diff --git a/Cargo.lock b/Cargo.lock index 5e7341a..1385259 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1240,6 +1240,15 @@ dependencies = [ "version_check", ] +[[package]] +name = "getopts" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5" +dependencies = [ + "unicode-width", +] + [[package]] name = "getrandom" version = "0.2.15" @@ -2257,6 +2266,7 @@ dependencies = [ "free-icons", "minijinja", "minijinja-autoreload", + "pulldown-cmark", "rand 0.8.5", "redb", "serde", @@ -2346,6 +2356,25 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "pulldown-cmark" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8746739f11d39ce5ad5c2520a9b75285310dbfe78c541ccf832d38615765aec0" +dependencies = [ + "bitflags 2.5.0", + "getopts", + "memchr", + "pulldown-cmark-escape", + "unicase", +] + +[[package]] +name = "pulldown-cmark-escape" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "007d8adb5ddab6f8e3f491ac63566a7d5002cc7ed73901f72057943fa71ae1ae" + [[package]] name = "quanta" version = "0.12.3" @@ -3686,6 +3715,12 @@ version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" +[[package]] +name = "unicode-width" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68f5e5f3158ecfd4b8ff6fe086db7c8467a2dfdac97fe420f2b7c4aa97af66d6" + [[package]] name = "unicode_categories" version = "0.1.1" diff --git a/Cargo.toml b/Cargo.toml index b5b484e..93a5012 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,6 +23,7 @@ env_logger = "0.11.3" free-icons = "0.7.0" minijinja = { version = "1.0.14", features = ["loader", "json", "builtins"] } minijinja-autoreload = "1.0.14" +pulldown-cmark = "0.11.0" rand = "0.8.5" redb = "2.1.0" serde = { version = "1.0.197", features = ["derive"] } diff --git a/frontend/editor.ts b/frontend/editor.ts new file mode 100644 index 0000000..8cd22e6 --- /dev/null +++ b/frontend/editor.ts @@ -0,0 +1,44 @@ +import {basicSetup} from "codemirror" +import {EditorView, keymap} from "@codemirror/view" +import {indentWithTab} from "@codemirror/commands" +import {markdown} from "@codemirror/lang-markdown" + +export function makeEditor(divSelector, value) { + let div = document.querySelector(divSelector); + div.classList.remove("hidden"); + div.classList.remove("h-0"); + + let documentTheme = EditorView.theme({ + "&": { + "background-color": "white", + }, + ".cm-editor": { + "height": "100%", + }, + ".cm-scroller": {overflow: "auto"} + }, {}) + + // add a hidden textarea inside the div for form submission + let textarea = document.createElement("textarea"); + textarea.setAttribute("name", "content"); + textarea.style.display = "none"; + div.appendChild(textarea); + + let extensions = [ + basicSetup, + keymap.of([indentWithTab]), + markdown(), + documentTheme, + EditorView.lineWrapping, + ]; + + let view = new EditorView({parent: div, doc: value, extensions}) + + textarea.form.addEventListener("submit", () => { + textarea.value = view.state.doc.toString() + }) + + // remove the "hidden" and "h-0" classes from the div + + return view +} diff --git a/frontend/main.css b/frontend/main.css index 6260af8..2cce384 100644 --- a/frontend/main.css +++ b/frontend/main.css @@ -2,59 +2,16 @@ @tailwind components; @tailwind utilities; - - - -/* Borrowed from https://github.com/Milkdown/milkdown/blob/main/e2e/src/list-item-block/style.css -which is licensed under MIT. */ - -.prose :where(li):not(:where([class~="not-prose"] *)) { - margin-top: 0.5em; - margin-bottom: 0; +.prose li { + margin-top: 0; + margin-bottom: 0; } -.prose :where(blockquote):not(:where([class~="not-prose"] *)) { - font-style: inherit; - font-weight: inherit; -} - -.prose :where(ul ul, ul ol, ol ul, ol ol):not(:where([class~="not-prose"] *)) { - margin-top: 0.5em; - margin-bottom: 0; -} - -.prose ol, .prose ul { - list-style: none !important; - padding: 0; + margin-top: 0; + margin-bottom: 0; } -.prose li p { - @apply !m-0 !leading-6; +.prose h1 { + margin-bottom: 0.25em; } - -.prose li p + p { - @apply !mt-2; -} - -.prose li.ProseMirror-selectednode { - outline: 2px solid #8cf; -} - -.prose li::after { - all: unset !important; -} - -milkdown-list-item-block .list-item { - gap: 8px; -} - -milkdown-list-item-block .label-wrapper { - height: 24px; - display: inline-flex; - justify-content: center; - align-items: center; - color: darkcyan; -} - -/* End borrowed block. */ diff --git a/frontend/main.ts b/frontend/main.ts index 83332f4..b873d11 100644 --- a/frontend/main.ts +++ b/frontend/main.ts @@ -1,52 +1,2 @@ -import { defaultValueCtx, Editor, rootCtx } from '@milkdown/core'; -import { html } from 'atomico'; -import { listItemBlockComponent, listItemBlockConfig, ListItemBlockConfig, listItemBlockView } from '@milkdown/components/list-item-block' -import { commonmark } from '@milkdown/preset-commonmark'; -import { gfm } from '@milkdown/preset-gfm'; -import { nord } from '@milkdown/theme-nord' -import { listener, listenerCtx } from '@milkdown/plugin-listener'; -import '@milkdown/theme-nord/style.css' - -function configureListItem(ctx: Ctx) { - ctx.set(listItemBlockConfig.key, { - renderLabel: (label: string, listType, checked?: boolean) => { - if (checked == null) { - if (listType === 'bullet') { - return html`` - } - - return html`${label}` - } else { - return html`` - } - }, - }) -} - -function createEditor(rootId, fieldId, content) { - Editor - .make() - .config(ctx => { - ctx.set(rootCtx, rootId) - ctx.set(defaultValueCtx, content) - - const listener = ctx.get(listenerCtx); - listener.markdownUpdated((ctx, markdown, prevMarkdown) => { - if (markdown !== prevMarkdown) { - console.log(markdown); - console.log(fieldId); - document.getElementById(fieldId).value = markdown; - console.log("updated"); - } - }) - }) - .config(configureListItem) - .use(commonmark) - .use(gfm) - .use(nord) - .use(listener) - .use(listItemBlockComponent) - .create(); -} - -window.createEditor = createEditor; +import { makeEditor } from './editor'; +window.makeEditor = makeEditor; diff --git a/package-lock.json b/package-lock.json index edc791f..2d8ba45 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,6 +5,7 @@ "packages": { "": { "dependencies": { + "@codemirror/lang-markdown": "^6.2.5", "@milkdown/components": "^7.3.6", "@milkdown/core": "^7.3.6", "@milkdown/plugin-listener": "^7.3.6", @@ -13,6 +14,7 @@ "@milkdown/theme-nord": "^7.3.6", "@prosemirror-adapter/lit": "^0.2.6", "clsx": "^2.1.1", + "codemirror": "^6.0.1", "tailwindcss": "^3.4.3" }, "devDependencies": { @@ -387,11 +389,94 @@ "atomico": "^1.75.1" } }, + "node_modules/@codemirror/autocomplete": { + "version": "6.16.2", + "resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.16.2.tgz", + "integrity": "sha512-MjfDrHy0gHKlPWsvSsikhO1+BOh+eBHNgfH1OXs1+DAf30IonQldgMM3kxLDTG9ktE7kDLaA1j/l7KMPA4KNfw==", + "dependencies": { + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.17.0", + "@lezer/common": "^1.0.0" + }, + "peerDependencies": { + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0", + "@lezer/common": "^1.0.0" + } + }, + "node_modules/@codemirror/commands": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.5.0.tgz", + "integrity": "sha512-rK+sj4fCAN/QfcY9BEzYMgp4wwL/q5aj/VfNSoH1RWPF9XS/dUwBkvlL3hpWgEjOqlpdN1uLC9UkjJ4tmyjJYg==", + "dependencies": { + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.4.0", + "@codemirror/view": "^6.0.0", + "@lezer/common": "^1.1.0" + } + }, + "node_modules/@codemirror/lang-css": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@codemirror/lang-css/-/lang-css-6.2.1.tgz", + "integrity": "sha512-/UNWDNV5Viwi/1lpr/dIXJNWiwDxpw13I4pTUAsNxZdg6E0mI2kTQb0P2iHczg1Tu+H4EBgJR+hYhKiHKko7qg==", + "dependencies": { + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@lezer/common": "^1.0.2", + "@lezer/css": "^1.0.0" + } + }, + "node_modules/@codemirror/lang-html": { + "version": "6.4.9", + "resolved": "https://registry.npmjs.org/@codemirror/lang-html/-/lang-html-6.4.9.tgz", + "integrity": "sha512-aQv37pIMSlueybId/2PVSP6NPnmurFDVmZwzc7jszd2KAF8qd4VBbvNYPXWQq90WIARjsdVkPbw29pszmHws3Q==", + "dependencies": { + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/lang-css": "^6.0.0", + "@codemirror/lang-javascript": "^6.0.0", + "@codemirror/language": "^6.4.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.17.0", + "@lezer/common": "^1.0.0", + "@lezer/css": "^1.1.0", + "@lezer/html": "^1.3.0" + } + }, + "node_modules/@codemirror/lang-javascript": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/@codemirror/lang-javascript/-/lang-javascript-6.2.2.tgz", + "integrity": "sha512-VGQfY+FCc285AhWuwjYxQyUQcYurWlxdKYT4bqwr3Twnd5wP5WSeu52t4tvvuWmljT4EmgEgZCqSieokhtY8hg==", + "dependencies": { + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/language": "^6.6.0", + "@codemirror/lint": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.17.0", + "@lezer/common": "^1.0.0", + "@lezer/javascript": "^1.0.0" + } + }, + "node_modules/@codemirror/lang-markdown": { + "version": "6.2.5", + "resolved": "https://registry.npmjs.org/@codemirror/lang-markdown/-/lang-markdown-6.2.5.tgz", + "integrity": "sha512-Hgke565YcO4fd9pe2uLYxnMufHO5rQwRr+AAhFq8ABuhkrjyX8R5p5s+hZUTdV60O0dMRjxKhBLxz8pu/MkUVA==", + "dependencies": { + "@codemirror/autocomplete": "^6.7.1", + "@codemirror/lang-html": "^6.0.0", + "@codemirror/language": "^6.3.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0", + "@lezer/common": "^1.2.1", + "@lezer/markdown": "^1.0.0" + } + }, "node_modules/@codemirror/language": { "version": "6.10.1", "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.10.1.tgz", "integrity": "sha512-5GrXzrhq6k+gL5fjkAwt90nYDmjlzTIJV8THnxNFtNKWotMIlzzN+CpqxqwXOECnUdOndmSeWntVrVcv5axWRQ==", - "peer": true, "dependencies": { "@codemirror/state": "^6.0.0", "@codemirror/view": "^6.23.0", @@ -401,17 +486,35 @@ "style-mod": "^4.0.0" } }, + "node_modules/@codemirror/lint": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/@codemirror/lint/-/lint-6.8.0.tgz", + "integrity": "sha512-lsFofvaw0lnPRJlQylNsC4IRt/1lI4OD/yYslrSGVndOJfStc58v+8p9dgGiD90ktOfL7OhBWns1ZETYgz0EJA==", + "dependencies": { + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0", + "crelt": "^1.0.5" + } + }, + "node_modules/@codemirror/search": { + "version": "6.5.6", + "resolved": "https://registry.npmjs.org/@codemirror/search/-/search-6.5.6.tgz", + "integrity": "sha512-rpMgcsh7o0GuCDUXKPvww+muLA1pDJaFrpq/CCHtpQJYz8xopu4D1hPcKRoDD0YlF8gZaqTNIRa4VRBWyhyy7Q==", + "dependencies": { + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0", + "crelt": "^1.0.5" + } + }, "node_modules/@codemirror/state": { "version": "6.4.1", "resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.4.1.tgz", - "integrity": "sha512-QkEyUiLhsJoZkbumGZlswmAhA7CBU02Wrz7zvH4SrcifbsqwlXShVXg65f3v/ts57W3dqyamEriMhij1Z3Zz4A==", - "peer": true + "integrity": "sha512-QkEyUiLhsJoZkbumGZlswmAhA7CBU02Wrz7zvH4SrcifbsqwlXShVXg65f3v/ts57W3dqyamEriMhij1Z3Zz4A==" }, "node_modules/@codemirror/view": { "version": "6.26.3", "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.26.3.tgz", "integrity": "sha512-gmqxkPALZjkgSxIeeweY/wGQXBfwTUaLs8h7OKtSwfbj9Ct3L11lD+u1sS7XHppxFQoMDiMDp07P9f3I2jWOHw==", - "peer": true, "dependencies": { "@codemirror/state": "^6.4.0", "style-mod": "^4.1.0", @@ -876,27 +979,63 @@ "node_modules/@lezer/common": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.2.1.tgz", - "integrity": "sha512-yemX0ZD2xS/73llMZIK6KplkjIjf2EvAHcinDi/TfJ9hS25G0388+ClHt6/3but0oOxinTcQHJLDXh6w1crzFQ==", - "peer": true + "integrity": "sha512-yemX0ZD2xS/73llMZIK6KplkjIjf2EvAHcinDi/TfJ9hS25G0388+ClHt6/3but0oOxinTcQHJLDXh6w1crzFQ==" + }, + "node_modules/@lezer/css": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/@lezer/css/-/css-1.1.8.tgz", + "integrity": "sha512-7JhxupKuMBaWQKjQoLtzhGj83DdnZY9MckEOG5+/iLKNK2ZJqKc6hf6uc0HjwCX7Qlok44jBNqZhHKDhEhZYLA==", + "dependencies": { + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" + } }, "node_modules/@lezer/highlight": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.2.0.tgz", "integrity": "sha512-WrS5Mw51sGrpqjlh3d4/fOwpEV2Hd3YOkp9DBt4k8XZQcoTHZFB7sx030A6OcahF4J1nDQAa3jXlTVVYH50IFA==", - "peer": true, "dependencies": { "@lezer/common": "^1.0.0" } }, + "node_modules/@lezer/html": { + "version": "1.3.10", + "resolved": "https://registry.npmjs.org/@lezer/html/-/html-1.3.10.tgz", + "integrity": "sha512-dqpT8nISx/p9Do3AchvYGV3qYc4/rKr3IBZxlHmpIKam56P47RSHkSF5f13Vu9hebS1jM0HmtJIwLbWz1VIY6w==", + "dependencies": { + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" + } + }, + "node_modules/@lezer/javascript": { + "version": "1.4.16", + "resolved": "https://registry.npmjs.org/@lezer/javascript/-/javascript-1.4.16.tgz", + "integrity": "sha512-84UXR3N7s11MPQHWgMnjb9571fr19MmXnr5zTv2XX0gHXXUvW3uPJ8GCjKrfTXmSdfktjRK0ayKklw+A13rk4g==", + "dependencies": { + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.1.3", + "@lezer/lr": "^1.3.0" + } + }, "node_modules/@lezer/lr": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.4.0.tgz", "integrity": "sha512-Wst46p51km8gH0ZUmeNrtpRYmdlRHUpN1DQd3GFAyKANi8WVz8c2jHYTf1CVScFaCjQw1iO3ZZdqGDxQPRErTg==", - "peer": true, "dependencies": { "@lezer/common": "^1.0.0" } }, + "node_modules/@lezer/markdown": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@lezer/markdown/-/markdown-1.3.0.tgz", + "integrity": "sha512-ErbEQ15eowmJUyT095e9NJc3BI9yZ894fjSDtHftD0InkfUBGgnKSU6dvan9jqsZuNHg2+ag/1oyDRxNsENupQ==", + "dependencies": { + "@lezer/common": "^1.0.0", + "@lezer/highlight": "^1.0.0" + } + }, "node_modules/@lit-labs/context": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/@lit-labs/context/-/context-0.3.3.tgz", @@ -1535,6 +1674,20 @@ "node": ">=6" } }, + "node_modules/codemirror": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-6.0.1.tgz", + "integrity": "sha512-J8j+nZ+CdWmIeFIGXEFbFPtpiYacFMDR8GlHK3IyHQJMCaVRfGx9NT+Hxivv1ckLWPvNdZqndbr/7lVhrf/Svg==", + "dependencies": { + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/commands": "^6.0.0", + "@codemirror/language": "^6.0.0", + "@codemirror/lint": "^6.0.0", + "@codemirror/search": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0" + } + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -1562,6 +1715,11 @@ "node": ">= 6" } }, + "node_modules/crelt": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.6.tgz", + "integrity": "sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==" + }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -3618,8 +3776,7 @@ "node_modules/style-mod": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.1.2.tgz", - "integrity": "sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw==", - "peer": true + "integrity": "sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw==" }, "node_modules/sucrase": { "version": "3.35.0", @@ -3859,8 +4016,7 @@ "node_modules/w3c-keyname": { "version": "2.2.8", "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz", - "integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==", - "peer": true + "integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==" }, "node_modules/which": { "version": "2.0.2", diff --git a/package.json b/package.json index d595706..0373cb9 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "css": "tailwindcss -i ./frontend/main.css -o ./static/style.css" }, "dependencies": { + "@codemirror/lang-markdown": "^6.2.5", "@milkdown/components": "^7.3.6", "@milkdown/core": "^7.3.6", "@milkdown/plugin-listener": "^7.3.6", @@ -21,6 +22,7 @@ "@milkdown/theme-nord": "^7.3.6", "@prosemirror-adapter/lit": "^0.2.6", "clsx": "^2.1.1", + "codemirror": "^6.0.1", "tailwindcss": "^3.4.3" } } diff --git a/src/handler/documents.rs b/src/handler/documents.rs index 449219f..5170155 100644 --- a/src/handler/documents.rs +++ b/src/handler/documents.rs @@ -104,6 +104,45 @@ pub async fn create_document_submit( Ok(Redirect::to("/documents").into_response()) } +pub async fn view_document_page( + State(provider): State, + auth_session: AuthSession, + Path((id,)): Path<(Uuid,)>, +) -> Result { + let user = match auth_session.user { + Some(user) => user, + None => return Ok(Redirect::to("/login").into_response()), + }; + + let mut db = provider.db_pool.get().map_err(internal_error)?; + + let document_allowed = + permissions::q::check_user_document(&mut db, &user.id, &id.to_string(), Permission::Write) + .map_err(internal_error)?; + + if !document_allowed { + return Err((StatusCode::FORBIDDEN, "permission denied".to_owned())); + } + + let document = match documents::q::by_id(&mut db, &id.to_string()).map_err(internal_error)? { + Some(doc) => doc, + None => return Err((StatusCode::NOT_FOUND, "document not found".to_owned())), + }; + let projects = + permissions::q::accessible_projects(&mut db, &user.id).map_err(internal_error)?; + + let rendered_document = document.render_html(); + + let values = context! { + user => user, + document => document, + projects => projects, + rendered_document => rendered_document, + }; + + provider.render_resp("documents/view_document.html", values) +} + pub async fn edit_document_page( State(provider): State, auth_session: AuthSession, @@ -176,5 +215,6 @@ pub async fn edit_document_submit( ) .map_err(internal_error)?; - Ok(Redirect::to("/documents").into_response()) + let view_url = format!("/documents/view/{}", document_id); + Ok(Redirect::to(&view_url).into_response()) } diff --git a/src/handler/login.rs b/src/handler/login.rs index 4dbfb25..1a7d94f 100644 --- a/src/handler/login.rs +++ b/src/handler/login.rs @@ -48,7 +48,7 @@ pub async fn login_submit( Form(creds): Form, ) -> Result { if let Some(user) = auth_session.authenticate(creds).await.map_err(internal_error)? { - let _ = auth_session.login(&user).await.map_err(internal_error)?; + auth_session.login(&user).await.map_err(internal_error)?; Ok(Redirect::to("/").into_response()) } else { render_login_page(&provider, "", "", Some(LOGIN_ERROR_MSG)) diff --git a/src/models/documents.rs b/src/models/documents.rs index 0067275..5674e8a 100644 --- a/src/models/documents.rs +++ b/src/models/documents.rs @@ -1,4 +1,5 @@ use diesel::prelude::*; +use pulldown_cmark as markdown; use serde::Serialize; use uuid::Uuid; @@ -16,6 +17,21 @@ pub struct Document { pub content: String, } +impl Document { + pub fn render_html(&self) -> String { + let mut options = markdown::Options::empty(); + options.insert(markdown::Options::ENABLE_TASKLISTS); + options.insert(markdown::Options::ENABLE_STRIKETHROUGH); + + let parser = markdown::Parser::new_ext(&self.content, options); + + let mut html_output = String::new(); + markdown::html::push_html(&mut html_output, parser); + + html_output + } +} + #[derive(Insertable)] #[diesel(table_name = crate::schema::documents)] pub struct NewDocument { diff --git a/src/server.rs b/src/server.rs index 873ecbd..490c518 100644 --- a/src/server.rs +++ b/src/server.rs @@ -17,7 +17,7 @@ use crate::config::CommandLineOptions; use crate::db; use crate::handler::documents::{ create_document_page, create_document_submit, documents_page, edit_document_page, - edit_document_submit, + edit_document_submit, view_document_page, }; use crate::handler::home::home_page; use crate::handler::login::logout; @@ -66,6 +66,7 @@ pub async fn run() -> Result<()> { .route("/documents", get(documents_page)) .route("/documents/new", get(create_document_page)) .route("/documents/new", post(create_document_submit)) + .route("/documents/view/:id", get(view_document_page)) .route("/documents/edit/:id", get(edit_document_page)) .route("/documents/edit/:id", post(edit_document_submit)) .layer(trace_layer) diff --git a/static/main.css b/static/main.css deleted file mode 100644 index 0456fee..0000000 --- a/static/main.css +++ /dev/null @@ -1,196 +0,0 @@ -/* node_modules/@milkdown/theme-nord/lib/style.css */ -.ProseMirror { - position: relative; - word-wrap: break-word; - white-space: pre-wrap; - white-space: break-spaces; - font-variant-ligatures: none; - font-feature-settings: "liga" 0; -} -.ProseMirror pre { - white-space: pre-wrap; -} -.ProseMirror li { - position: relative; -} -.ProseMirror-hideselection *::selection { - background: transparent; -} -.ProseMirror-hideselection *::-moz-selection { - background: transparent; -} -.ProseMirror-hideselection { - caret-color: transparent; -} -.ProseMirror [draggable][contenteditable=false] { - -webkit-user-select: text; - -moz-user-select: text; - user-select: text; -} -.ProseMirror-selectednode { - outline: 2px solid #8cf; -} -li.ProseMirror-selectednode { - outline: none; -} -li.ProseMirror-selectednode:after { - content: ""; - position: absolute; - left: -32px; - right: -2px; - top: -2px; - bottom: -2px; - border: 2px solid #8cf; - pointer-events: none; -} -img.ProseMirror-separator { - display: inline !important; - border: none !important; - margin: 0 !important; -} -.ProseMirror .tableWrapper { - overflow-x: auto; -} -.ProseMirror table { - border-collapse: collapse; - table-layout: fixed; - width: 100%; - overflow: hidden; -} -.ProseMirror td, -.ProseMirror th { - vertical-align: top; - box-sizing: border-box; - position: relative; -} -.ProseMirror .column-resize-handle { - position: absolute; - right: -2px; - top: 0; - bottom: 0; - width: 4px; - z-index: 20; - background-color: #adf; - pointer-events: none; -} -.ProseMirror.resize-cursor { - cursor: ew-resize; - cursor: col-resize; -} -.ProseMirror .selectedCell:after { - z-index: 2; - position: absolute; - content: ""; - left: 0; - right: 0; - top: 0; - bottom: 0; - background: #c8c8ff66; - pointer-events: none; -} -.milkdown-theme-nord blockquote { - border-left-width: 4px; - --tw-border-opacity: 1; - border-color: rgb(94 129 172 / var(--tw-border-opacity)); - padding-left: 1rem; - font-family: - ui-serif, - Georgia, - Cambria, - Times New Roman, - Times, - serif; - font-style: normal; -} -.milkdown-theme-nord code { - font-family: - ui-monospace, - SFMono-Regular, - Menlo, - Monaco, - Consolas, - Liberation Mono, - Courier New, - monospace; - font-weight: 400; - --tw-text-opacity: 1; - color: rgb(94 129 172 / var(--tw-text-opacity)); -} -.milkdown-theme-nord pre code { - color: inherit; -} -.milkdown-theme-nord img { - margin-top: 0 !important; - margin-bottom: 0 !important; - display: inline-block; - max-width: 100%; -} -.milkdown-theme-nord.prose :where(blockquote):not(:where([class~=not-prose] *)) { - font-weight: 400; -} -.milkdown-theme-nord.prose :where(ol > li):not(:where([class~=not-prose] *))::marker, -.milkdown-theme-nord.prose :where(ul > li):not(:where([class~=not-prose] *))::marker { - --tw-text-opacity: 1; - color: rgb(94 129 172 / var(--tw-text-opacity)); -} -.milkdown-theme-nord.prose :where(blockquote p:first-of-type):not(:where([class~=not-prose] *)):before, -.milkdown-theme-nord.prose :where(blockquote p:first-of-type):not(:where([class~=not-prose] *)):after { - content: ""; -} -.milkdown-theme-nord.prose :where(code):not(:where([class~=not-prose] *)):before, -.milkdown-theme-nord.prose :where(code):not(:where([class~=not-prose] *)):after { - content: ""; -} -.milkdown-theme-nord.prose .tableWrapper { - position: relative; - margin-bottom: .5rem; - overflow-x: auto; -} -.milkdown-theme-nord.prose table { - margin: 1rem !important; - overflow: visible !important; - font-size: .875rem; - line-height: 1.25rem; - --tw-shadow: 0 4px 6px -1px rgb(0 0 0 / .1), 0 2px 4px -2px rgb(0 0 0 / .1); - --tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color); - box-shadow: - var(--tw-ring-offset-shadow, 0 0 #0000), - var(--tw-ring-shadow, 0 0 #0000), - var(--tw-shadow); -} -@media (min-width: 640px) { - .milkdown-theme-nord.prose table { - border-radius: .5rem; - } -} -.milkdown-theme-nord.prose td, -.milkdown-theme-nord.prose th { - padding: .75rem 1.5rem !important; -} -.milkdown-theme-nord.prose tr { - border-bottom-width: 1px; - --tw-border-opacity: 1; - border-color: rgb(229 231 235 / var(--tw-border-opacity)); -} -:is(.dark .milkdown-theme-nord.prose tr) { - --tw-border-opacity: 1; - border-color: rgb(75 85 99 / var(--tw-border-opacity)); -} -.milkdown-theme-nord.prose :where(td, th) p { - margin: 0 !important; -} -.milkdown-theme-nord.prose :where(td, th):nth-child(odd) { - --tw-bg-opacity: 1; - background-color: rgb(249 250 251 / var(--tw-bg-opacity)); -} -:is(.dark .milkdown-theme-nord.prose :where(td, th):nth-child(odd)) { - --tw-bg-opacity: 1; - background-color: rgb(17 24 39 / var(--tw-bg-opacity)); -} -.milkdown-theme-nord.prose.ProseMirror .selectedCell:after { - background-color: #88c0d04d; -} -.milkdown-theme-nord.prose br[data-is-inline=true], -.milkdown-theme-nord.prose br[data-is-inline=true]:after { - content: " "; -} diff --git a/static/main.js b/static/main.js index a0e49f3..6d07f92 100644 --- a/static/main.js +++ b/static/main.js @@ -1,20584 +1,3517 @@ (() => { - var __create = Object.create; - var __defProp = Object.defineProperty; - var __defProps = Object.defineProperties; - var __getOwnPropDesc = Object.getOwnPropertyDescriptor; - var __getOwnPropDescs = Object.getOwnPropertyDescriptors; - var __getOwnPropNames = Object.getOwnPropertyNames; - var __getOwnPropSymbols = Object.getOwnPropertySymbols; - var __getProtoOf = Object.getPrototypeOf; - var __hasOwnProp = Object.prototype.hasOwnProperty; - var __propIsEnum = Object.prototype.propertyIsEnumerable; - var __typeError = (msg) => { - throw TypeError(msg); - }; - var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; - var __spreadValues = (a2, b4) => { - for (var prop in b4 || (b4 = {})) - if (__hasOwnProp.call(b4, prop)) - __defNormalProp(a2, prop, b4[prop]); - if (__getOwnPropSymbols) - for (var prop of __getOwnPropSymbols(b4)) { - if (__propIsEnum.call(b4, prop)) - __defNormalProp(a2, prop, b4[prop]); - } - return a2; - }; - var __spreadProps = (a2, b4) => __defProps(a2, __getOwnPropDescs(b4)); - var __objRest = (source, exclude) => { - var target = {}; - for (var prop in source) - if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0) - target[prop] = source[prop]; - if (source != null && __getOwnPropSymbols) - for (var prop of __getOwnPropSymbols(source)) { - if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop)) - target[prop] = source[prop]; - } - return target; - }; - var __commonJS = (cb, mod) => function __require() { - return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; - }; - var __export = (target, all2) => { - for (var name in all2) - __defProp(target, name, { get: all2[name], enumerable: true }); - }; - var __copyProps = (to, from, except, desc) => { - if (from && typeof from === "object" || typeof from === "function") { - for (let key of __getOwnPropNames(from)) - if (!__hasOwnProp.call(to, key) && key !== except) - __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); - } - return to; - }; - var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( - // If the importer is in node compatibility mode or this is not an ESM - // file that has been converted to a CommonJS file using a Babel- - // compatible transform (i.e. "__esModule" has not been set), then set - // "default" to the CommonJS "module.exports" for node compatibility. - isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, - mod - )); - var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg); - var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj)); - var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value); - var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value); - - // node_modules/extend/index.js - var require_extend = __commonJS({ - "node_modules/extend/index.js"(exports, module) { - "use strict"; - var hasOwn = Object.prototype.hasOwnProperty; - var toStr = Object.prototype.toString; - var defineProperty = Object.defineProperty; - var gOPD = Object.getOwnPropertyDescriptor; - var isArray2 = function isArray3(arr) { - if (typeof Array.isArray === "function") { - return Array.isArray(arr); - } - return toStr.call(arr) === "[object Array]"; - }; - var isPlainObject2 = function isPlainObject3(obj) { - if (!obj || toStr.call(obj) !== "[object Object]") { - return false; - } - var hasOwnConstructor = hasOwn.call(obj, "constructor"); - var hasIsPrototypeOf = obj.constructor && obj.constructor.prototype && hasOwn.call(obj.constructor.prototype, "isPrototypeOf"); - if (obj.constructor && !hasOwnConstructor && !hasIsPrototypeOf) { - return false; - } - var key; - for (key in obj) { - } - return typeof key === "undefined" || hasOwn.call(obj, key); - }; - var setProperty2 = function setProperty3(target, options2) { - if (defineProperty && options2.name === "__proto__") { - defineProperty(target, options2.name, { - enumerable: true, - configurable: true, - value: options2.newValue, - writable: true - }); - } else { - target[options2.name] = options2.newValue; - } - }; - var getProperty = function getProperty2(obj, name) { - if (name === "__proto__") { - if (!hasOwn.call(obj, name)) { - return void 0; - } else if (gOPD) { - return gOPD(obj, name).value; - } - } - return obj[name]; - }; - module.exports = function extend2() { - var options2, name, src, copy2, copyIsArray, clone; - var target = arguments[0]; - var i2 = 1; - var length = arguments.length; - var deep = false; - if (typeof target === "boolean") { - deep = target; - target = arguments[1] || {}; - i2 = 2; - } - if (target == null || typeof target !== "object" && typeof target !== "function") { - target = {}; - } - for (; i2 < length; ++i2) { - options2 = arguments[i2]; - if (options2 != null) { - for (name in options2) { - src = getProperty(target, name); - copy2 = getProperty(options2, name); - if (target !== copy2) { - if (deep && copy2 && (isPlainObject2(copy2) || (copyIsArray = isArray2(copy2)))) { - if (copyIsArray) { - copyIsArray = false; - clone = src && isArray2(src) ? src : []; - } else { - clone = src && isPlainObject2(src) ? src : {}; - } - setProperty2(target, { name, newValue: extend2(deep, clone, copy2) }); - } else if (typeof copy2 !== "undefined") { - setProperty2(target, { name, newValue: copy2 }); - } - } - } - } - } - return target; - }; - } - }); - - // node_modules/lodash.debounce/index.js - var require_lodash = __commonJS({ - "node_modules/lodash.debounce/index.js"(exports, module) { - var FUNC_ERROR_TEXT = "Expected a function"; - var NAN = 0 / 0; - var symbolTag = "[object Symbol]"; - var reTrim = /^\s+|\s+$/g; - var reIsBadHex = /^[-+]0x[0-9a-f]+$/i; - var reIsBinary = /^0b[01]+$/i; - var reIsOctal = /^0o[0-7]+$/i; - var freeParseInt = parseInt; - var freeGlobal = typeof global == "object" && global && global.Object === Object && global; - var freeSelf = typeof self == "object" && self && self.Object === Object && self; - var root2 = freeGlobal || freeSelf || Function("return this")(); - var objectProto = Object.prototype; - var objectToString = objectProto.toString; - var nativeMax = Math.max; - var nativeMin = Math.min; - var now = function() { - return root2.Date.now(); - }; - function debounce(func, wait, options2) { - var lastArgs, lastThis, maxWait, result, timerId, lastCallTime, lastInvokeTime = 0, leading = false, maxing = false, trailing = true; - if (typeof func != "function") { - throw new TypeError(FUNC_ERROR_TEXT); - } - wait = toNumber(wait) || 0; - if (isObject2(options2)) { - leading = !!options2.leading; - maxing = "maxWait" in options2; - maxWait = maxing ? nativeMax(toNumber(options2.maxWait) || 0, wait) : maxWait; - trailing = "trailing" in options2 ? !!options2.trailing : trailing; - } - function invokeFunc(time) { - var args = lastArgs, thisArg = lastThis; - lastArgs = lastThis = void 0; - lastInvokeTime = time; - result = func.apply(thisArg, args); - return result; - } - function leadingEdge(time) { - lastInvokeTime = time; - timerId = setTimeout(timerExpired, wait); - return leading ? invokeFunc(time) : result; - } - function remainingWait(time) { - var timeSinceLastCall = time - lastCallTime, timeSinceLastInvoke = time - lastInvokeTime, result2 = wait - timeSinceLastCall; - return maxing ? nativeMin(result2, maxWait - timeSinceLastInvoke) : result2; - } - function shouldInvoke(time) { - var timeSinceLastCall = time - lastCallTime, timeSinceLastInvoke = time - lastInvokeTime; - return lastCallTime === void 0 || timeSinceLastCall >= wait || timeSinceLastCall < 0 || maxing && timeSinceLastInvoke >= maxWait; - } - function timerExpired() { - var time = now(); - if (shouldInvoke(time)) { - return trailingEdge(time); - } - timerId = setTimeout(timerExpired, remainingWait(time)); - } - function trailingEdge(time) { - timerId = void 0; - if (trailing && lastArgs) { - return invokeFunc(time); - } - lastArgs = lastThis = void 0; - return result; - } - function cancel() { - if (timerId !== void 0) { - clearTimeout(timerId); - } - lastInvokeTime = 0; - lastArgs = lastCallTime = lastThis = timerId = void 0; - } - function flush() { - return timerId === void 0 ? result : trailingEdge(now()); - } - function debounced() { - var time = now(), isInvoking = shouldInvoke(time); - lastArgs = arguments; - lastThis = this; - lastCallTime = time; - if (isInvoking) { - if (timerId === void 0) { - return leadingEdge(lastCallTime); - } - if (maxing) { - timerId = setTimeout(timerExpired, wait); - return invokeFunc(lastCallTime); - } - } - if (timerId === void 0) { - timerId = setTimeout(timerExpired, wait); - } - return result; - } - debounced.cancel = cancel; - debounced.flush = flush; - return debounced; - } - function isObject2(value) { - var type = typeof value; - return !!value && (type == "object" || type == "function"); - } - function isObjectLike(value) { - return !!value && typeof value == "object"; - } - function isSymbol(value) { - return typeof value == "symbol" || isObjectLike(value) && objectToString.call(value) == symbolTag; - } - function toNumber(value) { - if (typeof value == "number") { - return value; - } - if (isSymbol(value)) { - return NAN; - } - if (isObject2(value)) { - var other = typeof value.valueOf == "function" ? value.valueOf() : value; - value = isObject2(other) ? other + "" : other; - } - if (typeof value != "string") { - return value === 0 ? value : +value; - } - value = value.replace(reTrim, ""); - var isBinary = reIsBinary.test(value); - return isBinary || reIsOctal.test(value) ? freeParseInt(value.slice(2), isBinary ? 2 : 8) : reIsBadHex.test(value) ? NAN : +value; - } - module.exports = debounce; - } - }); - - // node_modules/@milkdown/exception/lib/index.es.js - var n = /* @__PURE__ */ ((e2) => (e2.docTypeError = "docTypeError", e2.contextNotFound = "contextNotFound", e2.timerNotFound = "timerNotFound", e2.ctxCallOutOfScope = "ctxCallOutOfScope", e2.createNodeInParserFail = "createNodeInParserFail", e2.stackOverFlow = "stackOverFlow", e2.parserMatchError = "parserMatchError", e2.serializerMatchError = "serializerMatchError", e2.getAtomFromSchemaFail = "getAtomFromSchemaFail", e2.expectDomTypeError = "expectDomTypeError", e2.callCommandBeforeEditorView = "callCommandBeforeEditorView", e2.missingRootElement = "missingRootElement", e2.missingNodeInSchema = "missingNodeInSchema", e2.missingMarkInSchema = "missingMarkInSchema", e2.ctxNotBind = "ctxNotBind", e2.missingYjsDoc = "missingYjsDoc", e2))(n || {}); - var t = class extends Error { - constructor(o2, a2) { - super(a2), this.name = "MilkdownError", this.code = o2; - } - }; - var u = (e2, o2) => typeof o2 == "function" ? "[Function]" : o2; - var i = (e2) => JSON.stringify(e2, u); - function l(e2) { - return new t(n.docTypeError, `Doc type error, unsupported type: ${i(e2)}`); - } - function d(e2) { - return new t(n.contextNotFound, `Context "${e2}" not found, do you forget to inject it?`); - } - function f(e2) { - return new t(n.timerNotFound, `Timer "${e2}" not found, do you forget to record it?`); - } - function p() { - return new t(n.ctxCallOutOfScope, "Should not call a context out of the plugin."); - } - function g(...e2) { - const o2 = e2.reduce((a2, c6) => { - if (!c6) - return a2; - const s2 = (r3) => Array.isArray(r3) ? r3.map((m3) => s2(m3)).join(", ") : r3.toJSON ? i(r3.toJSON()) : r3.spec ? i(r3.spec) : r3.toString(); - return `${a2}, ${s2(c6)}`; - }, "Create prosemirror node from remark failed in parser"); - return new t(n.createNodeInParserFail, o2); - } - function h() { - return new t(n.stackOverFlow, "Stack over flow, cannot pop on an empty stack."); - } - function w(e2) { - return new t(n.parserMatchError, `Cannot match target parser for node: ${i(e2)}.`); - } - function F(e2) { - return new t(n.serializerMatchError, `Cannot match target serializer for node: ${i(e2)}.`); - } - function S(e2) { - return new t(n.expectDomTypeError, `Expect to be a dom, but get: ${i(e2)}.`); - } - function y() { - return new t( - n.callCommandBeforeEditorView, - "You're trying to call a command before editor view initialized, make sure to get commandManager from ctx after editor view has been initialized" - ); - } - function M(e2) { - return new t( - n.missingNodeInSchema, - `Missing node in schema, milkdown cannot find "${e2}" in schema.` - ); - } - function x(e2) { - return new t( - n.missingMarkInSchema, - `Missing mark in schema, milkdown cannot find "${e2}" in schema.` - ); - } - - // node_modules/@milkdown/ctx/lib/index.es.js - var P = (o2, s2, i2) => { - if (!s2.has(o2)) - throw TypeError("Cannot " + i2); - }; - var e = (o2, s2, i2) => (P(o2, s2, "read from private field"), i2 ? i2.call(o2) : s2.get(o2)); - var a = (o2, s2, i2) => { - if (s2.has(o2)) - throw TypeError("Cannot add the same private member more than once"); - s2 instanceof WeakSet ? s2.add(o2) : s2.set(o2, i2); - }; - var n2 = (o2, s2, i2, r3) => (P(o2, s2, "write to private field"), r3 ? r3.call(o2, i2) : s2.set(o2, i2), i2); - var G = class { - constructor() { - this.sliceMap = /* @__PURE__ */ new Map(), this.get = (s2) => { - const i2 = typeof s2 == "string" ? [...this.sliceMap.values()].find((r3) => r3.type.name === s2) : this.sliceMap.get(s2.id); - if (!i2) { - const r3 = typeof s2 == "string" ? s2 : s2.name; - throw d(r3); - } - return i2; - }, this.remove = (s2) => { - const i2 = typeof s2 == "string" ? [...this.sliceMap.values()].find((r3) => r3.type.name === s2) : this.sliceMap.get(s2.id); - i2 && this.sliceMap.delete(i2.type.id); - }, this.has = (s2) => typeof s2 == "string" ? [...this.sliceMap.values()].some((i2) => i2.type.name === s2) : this.sliceMap.has(s2.id); - } - }; - var u2; - var m; - var y2; - var V = class { - /// @internal - constructor(s2, i2, r3) { - a(this, u2, void 0); - a(this, m, void 0); - a(this, y2, void 0); - n2(this, u2, []), n2(this, y2, () => { - e(this, u2).forEach((t2) => t2(e(this, m))); - }), this.set = (t2) => { - n2(this, m, t2), e(this, y2).call(this); - }, this.get = () => e(this, m), this.update = (t2) => { - n2(this, m, t2(e(this, m))), e(this, y2).call(this); - }, this.type = r3, n2(this, m, i2), s2.set(r3.id, this); - } - /// Add a watcher for changes in the slice. - /// Returns a function to remove the watcher. - on(s2) { - return e(this, u2).push(s2), () => { - n2(this, u2, e(this, u2).filter((i2) => i2 !== s2)); - }; - } - /// Add a one-time watcher for changes in the slice. - /// The watcher will be removed after it is called. - /// Returns a function to remove the watcher. - once(s2) { - const i2 = this.on((r3) => { - s2(r3), i2(); - }); - return i2; - } - /// Remove a watcher. - off(s2) { - n2(this, u2, e(this, u2).filter((i2) => i2 !== s2)); - } - /// Remove all watchers. - offAll() { - n2(this, u2, []); - } - }; - u2 = /* @__PURE__ */ new WeakMap(), m = /* @__PURE__ */ new WeakMap(), y2 = /* @__PURE__ */ new WeakMap(); - var W = class { - /// Create a slice type with a default value and a name. - /// The name should be unique in the container. - constructor(s2, i2) { - this.id = Symbol(`Context-${i2}`), this.name = i2, this._defaultValue = s2, this._typeInfo = () => { - throw p(); - }; - } - /// Create a slice with a container. - /// You can also pass a value to override the default value. - create(s2, i2 = this._defaultValue) { - return new V(s2, i2, this); - } - }; - var H = (o2, s2) => new W(o2, s2); - var D; - var x2; - var R; - var w2; - var S2; - var f2; - var M2; - var T; - var j; - var _ = class { - /// Create an inspector with container, clock and metadata. - constructor(s2, i2, r3) { - a(this, D, void 0); - a(this, x2, void 0); - a(this, R, void 0); - a(this, w2, void 0); - a(this, S2, void 0); - a(this, f2, void 0); - a(this, M2, void 0); - a(this, T, void 0); - a(this, j, void 0); - n2(this, w2, /* @__PURE__ */ new Set()), n2(this, S2, /* @__PURE__ */ new Set()), n2(this, f2, /* @__PURE__ */ new Map()), n2(this, M2, /* @__PURE__ */ new Map()), this.read = () => ({ - metadata: e(this, D), - injectedSlices: [...e(this, w2)].map((t2) => ({ - name: typeof t2 == "string" ? t2 : t2.name, - value: e(this, T).call(this, t2) - })), - consumedSlices: [...e(this, S2)].map((t2) => ({ - name: typeof t2 == "string" ? t2 : t2.name, - value: e(this, T).call(this, t2) - })), - recordedTimers: [...e(this, f2)].map(([t2, { duration: h5 }]) => ({ - name: t2.name, - duration: h5, - status: e(this, j).call(this, t2) - })), - waitTimers: [...e(this, M2)].map(([t2, { duration: h5 }]) => ({ - name: t2.name, - duration: h5, - status: e(this, j).call(this, t2) - })) - }), this.onRecord = (t2) => { - e(this, f2).set(t2, { start: Date.now(), duration: 0 }); - }, this.onClear = (t2) => { - e(this, f2).delete(t2); - }, this.onDone = (t2) => { - const h5 = e(this, f2).get(t2); - h5 && (h5.duration = Date.now() - h5.start); - }, this.onWait = (t2, h5) => { - const v4 = Date.now(); - h5.finally(() => { - e(this, M2).set(t2, { duration: Date.now() - v4 }); - }); - }, this.onInject = (t2) => { - e(this, w2).add(t2); - }, this.onRemove = (t2) => { - e(this, w2).delete(t2); - }, this.onUse = (t2) => { - e(this, S2).add(t2); - }, n2(this, T, (t2) => e(this, x2).get(t2).get()), n2(this, j, (t2) => e(this, R).get(t2).status), n2(this, x2, s2), n2(this, R, i2), n2(this, D, r3); - } - }; - D = /* @__PURE__ */ new WeakMap(), x2 = /* @__PURE__ */ new WeakMap(), R = /* @__PURE__ */ new WeakMap(), w2 = /* @__PURE__ */ new WeakMap(), S2 = /* @__PURE__ */ new WeakMap(), f2 = /* @__PURE__ */ new WeakMap(), M2 = /* @__PURE__ */ new WeakMap(), T = /* @__PURE__ */ new WeakMap(), j = /* @__PURE__ */ new WeakMap(); - var d2; - var l2; - var b; - var c; - var L = class L2 { - /// Create a ctx object with container and clock. - constructor(s2, i2, r3) { - a(this, d2, void 0); - a(this, l2, void 0); - a(this, b, void 0); - a(this, c, void 0); - this.produce = (t2) => t2 && Object.keys(t2).length ? new L2(e(this, d2), e(this, l2), __spreadValues({}, t2)) : this, this.inject = (t2, h5) => { - var O4; - const v4 = t2.create(e(this, d2).sliceMap); - return h5 != null && v4.set(h5), (O4 = e(this, c)) == null || O4.onInject(t2), this; - }, this.remove = (t2) => { - var h5; - return e(this, d2).remove(t2), (h5 = e(this, c)) == null || h5.onRemove(t2), this; - }, this.record = (t2) => { - var h5; - return t2.create(e(this, l2).store), (h5 = e(this, c)) == null || h5.onRecord(t2), this; - }, this.clearTimer = (t2) => { - var h5; - return e(this, l2).remove(t2), (h5 = e(this, c)) == null || h5.onClear(t2), this; - }, this.isInjected = (t2) => e(this, d2).has(t2), this.isRecorded = (t2) => e(this, l2).has(t2), this.use = (t2) => { - var h5; - return (h5 = e(this, c)) == null || h5.onUse(t2), e(this, d2).get(t2); - }, this.get = (t2) => this.use(t2).get(), this.set = (t2, h5) => this.use(t2).set(h5), this.update = (t2, h5) => this.use(t2).update(h5), this.timer = (t2) => e(this, l2).get(t2), this.done = (t2) => { - var h5; - this.timer(t2).done(), (h5 = e(this, c)) == null || h5.onDone(t2); - }, this.wait = (t2) => { - var v4; - const h5 = this.timer(t2).start(); - return (v4 = e(this, c)) == null || v4.onWait(t2, h5), h5; - }, this.waitTimers = async (t2) => { - await Promise.all(this.get(t2).map((h5) => this.wait(h5))); - }, n2(this, d2, s2), n2(this, l2, i2), n2(this, b, r3), r3 && n2(this, c, new _(s2, i2, r3)); - } - /// Get metadata of the ctx. - get meta() { - return e(this, b); - } - /// Get the inspector of the ctx. - get inspector() { - return e(this, c); - } - }; - d2 = /* @__PURE__ */ new WeakMap(), l2 = /* @__PURE__ */ new WeakMap(), b = /* @__PURE__ */ new WeakMap(), c = /* @__PURE__ */ new WeakMap(); - var U = L; - var J = class { - constructor() { - this.store = /* @__PURE__ */ new Map(), this.get = (s2) => { - const i2 = this.store.get(s2.id); - if (!i2) - throw f(s2.name); - return i2; - }, this.remove = (s2) => { - this.store.delete(s2.id); - }, this.has = (s2) => this.store.has(s2.id); - } - }; - var C; - var g2; - var E; - var p2; - var I; - var k; - var q = class { - /// @internal - constructor(s2, i2) { - a(this, C, void 0); - a(this, g2, void 0); - a(this, E, void 0); - a(this, p2, void 0); - a(this, I, void 0); - a(this, k, void 0); - n2(this, C, null), n2(this, g2, null), n2(this, p2, "pending"), this.start = () => { - var _a; - return (_a = e(this, C)) != null ? _a : n2(this, C, new Promise((r3, t2) => { - n2(this, g2, (h5) => { - h5 instanceof CustomEvent && h5.detail.id === e(this, E) && (n2(this, p2, "resolved"), e(this, I).call(this), h5.stopImmediatePropagation(), r3()); - }), e(this, k).call(this, () => { - e(this, p2) === "pending" && n2(this, p2, "rejected"), e(this, I).call(this), t2(new Error(`Timing ${this.type.name} timeout.`)); - }), n2(this, p2, "pending"), addEventListener(this.type.name, e(this, g2)); - })), e(this, C); - }, this.done = () => { - const r3 = new CustomEvent(this.type.name, { detail: { id: e(this, E) } }); - dispatchEvent(r3); - }, n2(this, I, () => { - e(this, g2) && removeEventListener(this.type.name, e(this, g2)); - }), n2(this, k, (r3) => { - setTimeout(() => { - r3(); - }, this.type.timeout); - }), n2(this, E, Symbol(i2.name)), this.type = i2, s2.set(i2.id, this); - } - /// The status of the timer. - /// Can be `pending`, `resolved` or `rejected`. - get status() { - return e(this, p2); - } - }; - C = /* @__PURE__ */ new WeakMap(), g2 = /* @__PURE__ */ new WeakMap(), E = /* @__PURE__ */ new WeakMap(), p2 = /* @__PURE__ */ new WeakMap(), I = /* @__PURE__ */ new WeakMap(), k = /* @__PURE__ */ new WeakMap(); - var A = class { - /// Create a timer type with a name and a timeout. - /// The name should be unique in the clock. - constructor(s2, i2 = 3e3) { - this.create = (r3) => new q(r3, this), this.id = Symbol(`Timer-${s2}`), this.name = s2, this.timeout = i2; - } - }; - var K = (o2, s2 = 3e3) => new A(o2, s2); - - // node_modules/orderedmap/dist/index.js - function OrderedMap(content3) { - this.content = content3; - } - OrderedMap.prototype = { - constructor: OrderedMap, - find: function(key) { - for (var i2 = 0; i2 < this.content.length; i2 += 2) - if (this.content[i2] === key) return i2; - return -1; - }, - // :: (string) → ?any - // Retrieve the value stored under `key`, or return undefined when - // no such key exists. - get: function(key) { - var found2 = this.find(key); - return found2 == -1 ? void 0 : this.content[found2 + 1]; - }, - // :: (string, any, ?string) → OrderedMap - // Create a new map by replacing the value of `key` with a new - // value, or adding a binding to the end of the map. If `newKey` is - // given, the key of the binding will be replaced with that key. - update: function(key, value, newKey) { - var self2 = newKey && newKey != key ? this.remove(newKey) : this; - var found2 = self2.find(key), content3 = self2.content.slice(); - if (found2 == -1) { - content3.push(newKey || key, value); - } else { - content3[found2 + 1] = value; - if (newKey) content3[found2] = newKey; - } - return new OrderedMap(content3); - }, - // :: (string) → OrderedMap - // Return a map with the given key removed, if it existed. - remove: function(key) { - var found2 = this.find(key); - if (found2 == -1) return this; - var content3 = this.content.slice(); - content3.splice(found2, 2); - return new OrderedMap(content3); - }, - // :: (string, any) → OrderedMap - // Add a new key to the start of the map. - addToStart: function(key, value) { - return new OrderedMap([key, value].concat(this.remove(key).content)); - }, - // :: (string, any) → OrderedMap - // Add a new key to the end of the map. - addToEnd: function(key, value) { - var content3 = this.remove(key).content.slice(); - content3.push(key, value); - return new OrderedMap(content3); - }, - // :: (string, string, any) → OrderedMap - // Add a key after the given key. If `place` is not found, the new - // key is added to the end. - addBefore: function(place, key, value) { - var without = this.remove(key), content3 = without.content.slice(); - var found2 = without.find(place); - content3.splice(found2 == -1 ? content3.length : found2, 0, key, value); - return new OrderedMap(content3); - }, - // :: ((key: string, value: any)) - // Call the given function for each key/value pair in the map, in - // order. - forEach: function(f3) { - for (var i2 = 0; i2 < this.content.length; i2 += 2) - f3(this.content[i2], this.content[i2 + 1]); - }, - // :: (union) → OrderedMap - // Create a new map by prepending the keys in this map that don't - // appear in `map` before the keys in `map`. - prepend: function(map5) { - map5 = OrderedMap.from(map5); - if (!map5.size) return this; - return new OrderedMap(map5.content.concat(this.subtract(map5).content)); - }, - // :: (union) → OrderedMap - // Create a new map by appending the keys in this map that don't - // appear in `map` after the keys in `map`. - append: function(map5) { - map5 = OrderedMap.from(map5); - if (!map5.size) return this; - return new OrderedMap(this.subtract(map5).content.concat(map5.content)); - }, - // :: (union) → OrderedMap - // Create a map containing all the keys in this map that don't - // appear in `map`. - subtract: function(map5) { - var result = this; - map5 = OrderedMap.from(map5); - for (var i2 = 0; i2 < map5.content.length; i2 += 2) - result = result.remove(map5.content[i2]); - return result; - }, - // :: () → Object - // Turn ordered map into a plain object. - toObject: function() { - var result = {}; - this.forEach(function(key, value) { - result[key] = value; - }); - return result; - }, - // :: number - // The amount of keys in this map. - get size() { - return this.content.length >> 1; - } - }; - OrderedMap.from = function(value) { - if (value instanceof OrderedMap) return value; - var content3 = []; - if (value) for (var prop in value) content3.push(prop, value[prop]); - return new OrderedMap(content3); - }; - var dist_default = OrderedMap; - - // node_modules/prosemirror-model/dist/index.js - function findDiffStart(a2, b4, pos) { - for (let i2 = 0; ; i2++) { - if (i2 == a2.childCount || i2 == b4.childCount) - return a2.childCount == b4.childCount ? null : pos; - let childA = a2.child(i2), childB = b4.child(i2); - if (childA == childB) { - pos += childA.nodeSize; - continue; - } - if (!childA.sameMarkup(childB)) - return pos; - if (childA.isText && childA.text != childB.text) { - for (let j6 = 0; childA.text[j6] == childB.text[j6]; j6++) - pos++; - return pos; - } - if (childA.content.size || childB.content.size) { - let inner = findDiffStart(childA.content, childB.content, pos + 1); - if (inner != null) - return inner; - } - pos += childA.nodeSize; - } - } - function findDiffEnd(a2, b4, posA, posB) { - for (let iA = a2.childCount, iB = b4.childCount; ; ) { - if (iA == 0 || iB == 0) - return iA == iB ? null : { a: posA, b: posB }; - let childA = a2.child(--iA), childB = b4.child(--iB), size = childA.nodeSize; - if (childA == childB) { - posA -= size; - posB -= size; - continue; - } - if (!childA.sameMarkup(childB)) - return { a: posA, b: posB }; - if (childA.isText && childA.text != childB.text) { - let same = 0, minSize = Math.min(childA.text.length, childB.text.length); - while (same < minSize && childA.text[childA.text.length - same - 1] == childB.text[childB.text.length - same - 1]) { - same++; - posA--; - posB--; - } - return { a: posA, b: posB }; - } - if (childA.content.size || childB.content.size) { - let inner = findDiffEnd(childA.content, childB.content, posA - 1, posB - 1); - if (inner) - return inner; - } - posA -= size; - posB -= size; - } - } - var Fragment = class _Fragment { + // node_modules/@codemirror/state/dist/index.js + var Text = class _Text { /** - @internal + Get the line description around the given position. */ - constructor(content3, size) { - this.content = content3; - this.size = size || 0; - if (size == null) - for (let i2 = 0; i2 < content3.length; i2++) - this.size += content3[i2].nodeSize; + lineAt(pos) { + if (pos < 0 || pos > this.length) + throw new RangeError(`Invalid position ${pos} in document of length ${this.length}`); + return this.lineInner(pos, false, 1, 0); } /** - Invoke a callback for all descendant nodes between the given two - positions (relative to start of this fragment). Doesn't descend - into a node when the callback returns `false`. + Get the description for the given (1-based) line number. */ - nodesBetween(from, to, f3, nodeStart = 0, parent) { - for (let i2 = 0, pos = 0; pos < to; i2++) { - let child = this.content[i2], end = pos + child.nodeSize; - if (end > from && f3(child, nodeStart + pos, parent || null, i2) !== false && child.content.size) { - let start = pos + 1; - child.nodesBetween(Math.max(0, from - start), Math.min(child.content.size, to - start), f3, nodeStart + start); - } - pos = end; - } + line(n) { + if (n < 1 || n > this.lines) + throw new RangeError(`Invalid line number ${n} in ${this.lines}-line document`); + return this.lineInner(n, true, 1, 0); } /** - Call the given callback for every descendant node. `pos` will be - relative to the start of the fragment. The callback may return - `false` to prevent traversal of a given node's children. + Replace a range of the text with the given content. */ - descendants(f3) { - this.nodesBetween(0, this.size, f3); + replace(from, to, text) { + [from, to] = clip(this, from, to); + let parts = []; + this.decompose( + 0, + from, + parts, + 2 + /* Open.To */ + ); + if (text.length) + text.decompose( + 0, + text.length, + parts, + 1 | 2 + /* Open.To */ + ); + this.decompose( + to, + this.length, + parts, + 1 + /* Open.From */ + ); + return TextNode.from(parts, this.length - (to - from) + text.length); } /** - Extract the text between `from` and `to`. See the same method on - [`Node`](https://prosemirror.net/docs/ref/#model.Node.textBetween). - */ - textBetween(from, to, blockSeparator, leafText) { - let text5 = "", first = true; - this.nodesBetween(from, to, (node2, pos) => { - let nodeText = node2.isText ? node2.text.slice(Math.max(from, pos) - pos, to - pos) : !node2.isLeaf ? "" : leafText ? typeof leafText === "function" ? leafText(node2) : leafText : node2.type.spec.leafText ? node2.type.spec.leafText(node2) : ""; - if (node2.isBlock && (node2.isLeaf && nodeText || node2.isTextblock) && blockSeparator) { - if (first) - first = false; - else - text5 += blockSeparator; - } - text5 += nodeText; - }, 0); - return text5; - } - /** - Create a new fragment containing the combined content of this - fragment and the other. + Append another document to this one. */ append(other) { - if (!other.size) - return this; - if (!this.size) - return other; - let last = this.lastChild, first = other.firstChild, content3 = this.content.slice(), i2 = 0; - if (last.isText && last.sameMarkup(first)) { - content3[content3.length - 1] = last.withText(last.text + first.text); - i2 = 1; - } - for (; i2 < other.content.length; i2++) - content3.push(other.content[i2]); - return new _Fragment(content3, this.size + other.size); + return this.replace(this.length, this.length, other); } /** - Cut out the sub-fragment between the two given positions. + Retrieve the text between the given points. */ - cut(from, to = this.size) { - if (from == 0 && to == this.size) - return this; - let result = [], size = 0; - if (to > from) - for (let i2 = 0, pos = 0; pos < to; i2++) { - let child = this.content[i2], end = pos + child.nodeSize; - if (end > from) { - if (pos < from || end > to) { - if (child.isText) - child = child.cut(Math.max(0, from - pos), Math.min(child.text.length, to - pos)); - else - child = child.cut(Math.max(0, from - pos - 1), Math.min(child.content.size, to - pos - 1)); - } - result.push(child); - size += child.nodeSize; - } - pos = end; - } - return new _Fragment(result, size); + slice(from, to = this.length) { + [from, to] = clip(this, from, to); + let parts = []; + this.decompose(from, to, parts, 0); + return TextNode.from(parts, to - from); } /** - @internal - */ - cutByIndex(from, to) { - if (from == to) - return _Fragment.empty; - if (from == 0 && to == this.content.length) - return this; - return new _Fragment(this.content.slice(from, to)); - } - /** - Create a new fragment in which the node at the given index is - replaced by the given node. - */ - replaceChild(index2, node2) { - let current = this.content[index2]; - if (current == node2) - return this; - let copy2 = this.content.slice(); - let size = this.size + node2.nodeSize - current.nodeSize; - copy2[index2] = node2; - return new _Fragment(copy2, size); - } - /** - Create a new fragment by prepending the given node to this - fragment. - */ - addToStart(node2) { - return new _Fragment([node2].concat(this.content), this.size + node2.nodeSize); - } - /** - Create a new fragment by appending the given node to this - fragment. - */ - addToEnd(node2) { - return new _Fragment(this.content.concat(node2), this.size + node2.nodeSize); - } - /** - Compare this fragment to another one. + Test whether this text is equal to another instance. */ eq(other) { - if (this.content.length != other.content.length) - return false; - for (let i2 = 0; i2 < this.content.length; i2++) - if (!this.content[i2].eq(other.content[i2])) - return false; - return true; - } - /** - The first child of the fragment, or `null` if it is empty. - */ - get firstChild() { - return this.content.length ? this.content[0] : null; - } - /** - The last child of the fragment, or `null` if it is empty. - */ - get lastChild() { - return this.content.length ? this.content[this.content.length - 1] : null; - } - /** - The number of child nodes in this fragment. - */ - get childCount() { - return this.content.length; - } - /** - Get the child node at the given index. Raise an error when the - index is out of range. - */ - child(index2) { - let found2 = this.content[index2]; - if (!found2) - throw new RangeError("Index " + index2 + " out of range for " + this); - return found2; - } - /** - Get the child node at the given index, if it exists. - */ - maybeChild(index2) { - return this.content[index2] || null; - } - /** - Call `f` for every child node, passing the node, its offset - into this parent node, and its index. - */ - forEach(f3) { - for (let i2 = 0, p4 = 0; i2 < this.content.length; i2++) { - let child = this.content[i2]; - f3(child, p4, i2); - p4 += child.nodeSize; - } - } - /** - Find the first position at which this fragment and another - fragment differ, or `null` if they are the same. - */ - findDiffStart(other, pos = 0) { - return findDiffStart(this, other, pos); - } - /** - Find the first position, searching from the end, at which this - fragment and the given fragment differ, or `null` if they are - the same. Since this position will not be the same in both - nodes, an object with two separate positions is returned. - */ - findDiffEnd(other, pos = this.size, otherPos = other.size) { - return findDiffEnd(this, other, pos, otherPos); - } - /** - Find the index and inner offset corresponding to a given relative - position in this fragment. The result object will be reused - (overwritten) the next time the function is called. (Not public.) - */ - findIndex(pos, round = -1) { - if (pos == 0) - return retIndex(0, pos); - if (pos == this.size) - return retIndex(this.content.length, pos); - if (pos > this.size || pos < 0) - throw new RangeError(`Position ${pos} outside of fragment (${this})`); - for (let i2 = 0, curPos = 0; ; i2++) { - let cur = this.child(i2), end = curPos + cur.nodeSize; - if (end >= pos) { - if (end == pos || round > 0) - return retIndex(i2 + 1, end); - return retIndex(i2, curPos); - } - curPos = end; - } - } - /** - Return a debugging string that describes this fragment. - */ - toString() { - return "<" + this.toStringInner() + ">"; - } - /** - @internal - */ - toStringInner() { - return this.content.join(", "); - } - /** - Create a JSON-serializeable representation of this fragment. - */ - toJSON() { - return this.content.length ? this.content.map((n4) => n4.toJSON()) : null; - } - /** - Deserialize a fragment from its JSON representation. - */ - static fromJSON(schema, value) { - if (!value) - return _Fragment.empty; - if (!Array.isArray(value)) - throw new RangeError("Invalid input for Fragment.fromJSON"); - return new _Fragment(value.map(schema.nodeFromJSON)); - } - /** - Build a fragment from an array of nodes. Ensures that adjacent - text nodes with the same marks are joined together. - */ - static fromArray(array) { - if (!array.length) - return _Fragment.empty; - let joined, size = 0; - for (let i2 = 0; i2 < array.length; i2++) { - let node2 = array[i2]; - size += node2.nodeSize; - if (i2 && node2.isText && array[i2 - 1].sameMarkup(node2)) { - if (!joined) - joined = array.slice(0, i2); - joined[joined.length - 1] = node2.withText(joined[joined.length - 1].text + node2.text); - } else if (joined) { - joined.push(node2); - } - } - return new _Fragment(joined || array, size); - } - /** - Create a fragment from something that can be interpreted as a - set of nodes. For `null`, it returns the empty fragment. For a - fragment, the fragment itself. For a node or array of nodes, a - fragment containing those nodes. - */ - static from(nodes) { - if (!nodes) - return _Fragment.empty; - if (nodes instanceof _Fragment) - return nodes; - if (Array.isArray(nodes)) - return this.fromArray(nodes); - if (nodes.attrs) - return new _Fragment([nodes], nodes.nodeSize); - throw new RangeError("Can not convert " + nodes + " to a Fragment" + (nodes.nodesBetween ? " (looks like multiple versions of prosemirror-model were loaded)" : "")); - } - }; - Fragment.empty = new Fragment([], 0); - var found = { index: 0, offset: 0 }; - function retIndex(index2, offset) { - found.index = index2; - found.offset = offset; - return found; - } - function compareDeep(a2, b4) { - if (a2 === b4) - return true; - if (!(a2 && typeof a2 == "object") || !(b4 && typeof b4 == "object")) - return false; - let array = Array.isArray(a2); - if (Array.isArray(b4) != array) - return false; - if (array) { - if (a2.length != b4.length) - return false; - for (let i2 = 0; i2 < a2.length; i2++) - if (!compareDeep(a2[i2], b4[i2])) - return false; - } else { - for (let p4 in a2) - if (!(p4 in b4) || !compareDeep(a2[p4], b4[p4])) - return false; - for (let p4 in b4) - if (!(p4 in a2)) - return false; - } - return true; - } - var Mark = class _Mark { - /** - @internal - */ - constructor(type, attrs) { - this.type = type; - this.attrs = attrs; - } - /** - Given a set of marks, create a new set which contains this one as - well, in the right position. If this mark is already in the set, - the set itself is returned. If any marks that are set to be - [exclusive](https://prosemirror.net/docs/ref/#model.MarkSpec.excludes) with this mark are present, - those are replaced by this one. - */ - addToSet(set) { - let copy2, placed = false; - for (let i2 = 0; i2 < set.length; i2++) { - let other = set[i2]; - if (this.eq(other)) - return set; - if (this.type.excludes(other.type)) { - if (!copy2) - copy2 = set.slice(0, i2); - } else if (other.type.excludes(this.type)) { - return set; - } else { - if (!placed && other.type.rank > this.type.rank) { - if (!copy2) - copy2 = set.slice(0, i2); - copy2.push(this); - placed = true; - } - if (copy2) - copy2.push(other); - } - } - if (!copy2) - copy2 = set.slice(); - if (!placed) - copy2.push(this); - return copy2; - } - /** - Remove this mark from the given set, returning a new set. If this - mark is not in the set, the set itself is returned. - */ - removeFromSet(set) { - for (let i2 = 0; i2 < set.length; i2++) - if (this.eq(set[i2])) - return set.slice(0, i2).concat(set.slice(i2 + 1)); - return set; - } - /** - Test whether this mark is in the given set of marks. - */ - isInSet(set) { - for (let i2 = 0; i2 < set.length; i2++) - if (this.eq(set[i2])) - return true; - return false; - } - /** - Test whether this mark has the same type and attributes as - another mark. - */ - eq(other) { - return this == other || this.type == other.type && compareDeep(this.attrs, other.attrs); - } - /** - Convert this mark to a JSON-serializeable representation. - */ - toJSON() { - let obj = { type: this.type.name }; - for (let _3 in this.attrs) { - obj.attrs = this.attrs; - break; - } - return obj; - } - /** - Deserialize a mark from JSON. - */ - static fromJSON(schema, json) { - if (!json) - throw new RangeError("Invalid input for Mark.fromJSON"); - let type = schema.marks[json.type]; - if (!type) - throw new RangeError(`There is no mark type ${json.type} in this schema`); - return type.create(json.attrs); - } - /** - Test whether two sets of marks are identical. - */ - static sameSet(a2, b4) { - if (a2 == b4) + if (other == this) return true; - if (a2.length != b4.length) + if (other.length != this.length || other.lines != this.lines) return false; - for (let i2 = 0; i2 < a2.length; i2++) - if (!a2[i2].eq(b4[i2])) + let start = this.scanIdentical(other, 1), end = this.length - this.scanIdentical(other, -1); + let a = new RawTextCursor(this), b = new RawTextCursor(other); + for (let skip = start, pos = start; ; ) { + a.next(skip); + b.next(skip); + skip = 0; + if (a.lineBreak != b.lineBreak || a.done != b.done || a.value != b.value) return false; - return true; + pos += a.value.length; + if (a.done || pos >= end) + return true; + } } /** - Create a properly sorted mark set from null, a single mark, or an - unsorted array of marks. + Iterate over the text. When `dir` is `-1`, iteration happens + from end to start. This will return lines and the breaks between + them as separate strings. */ - static setFrom(marks) { - if (!marks || Array.isArray(marks) && marks.length == 0) - return _Mark.none; - if (marks instanceof _Mark) - return [marks]; - let copy2 = marks.slice(); - copy2.sort((a2, b4) => a2.type.rank - b4.type.rank); - return copy2; + iter(dir = 1) { + return new RawTextCursor(this, dir); } - }; - Mark.none = []; - var ReplaceError = class extends Error { - }; - var Slice = class _Slice { /** - Create a slice. When specifying a non-zero open depth, you must - make sure that there are nodes of at least that depth at the - appropriate side of the fragment—i.e. if the fragment is an - empty paragraph node, `openStart` and `openEnd` can't be greater - than 1. + Iterate over a range of the text. When `from` > `to`, the + iterator will run in reverse. + */ + iterRange(from, to = this.length) { + return new PartialTextCursor(this, from, to); + } + /** + Return a cursor that iterates over the given range of lines, + _without_ returning the line breaks between, and yielding empty + strings for empty lines. - It is not necessary for the content of open nodes to conform to - the schema's content constraints, though it should be a valid - start/end/middle for such a node, depending on which sides are - open. + When `from` and `to` are given, they should be 1-based line numbers. */ - constructor(content3, openStart, openEnd) { - this.content = content3; - this.openStart = openStart; - this.openEnd = openEnd; - } - /** - The size this slice would add when inserted into a document. - */ - get size() { - return this.content.size - this.openStart - this.openEnd; - } - /** - @internal - */ - insertAt(pos, fragment) { - let content3 = insertInto(this.content, pos + this.openStart, fragment); - return content3 && new _Slice(content3, this.openStart, this.openEnd); - } - /** - @internal - */ - removeBetween(from, to) { - return new _Slice(removeRange(this.content, from + this.openStart, to + this.openStart), this.openStart, this.openEnd); - } - /** - Tests whether this slice is equal to another slice. - */ - eq(other) { - return this.content.eq(other.content) && this.openStart == other.openStart && this.openEnd == other.openEnd; - } - /** - @internal - */ - toString() { - return this.content + "(" + this.openStart + "," + this.openEnd + ")"; - } - /** - Convert a slice to a JSON-serializable representation. - */ - toJSON() { - if (!this.content.size) - return null; - let json = { content: this.content.toJSON() }; - if (this.openStart > 0) - json.openStart = this.openStart; - if (this.openEnd > 0) - json.openEnd = this.openEnd; - return json; - } - /** - Deserialize a slice from its JSON representation. - */ - static fromJSON(schema, json) { - if (!json) - return _Slice.empty; - let openStart = json.openStart || 0, openEnd = json.openEnd || 0; - if (typeof openStart != "number" || typeof openEnd != "number") - throw new RangeError("Invalid input for Slice.fromJSON"); - return new _Slice(Fragment.fromJSON(schema, json.content), openStart, openEnd); - } - /** - Create a slice from a fragment by taking the maximum possible - open value on both side of the fragment. - */ - static maxOpen(fragment, openIsolating = true) { - let openStart = 0, openEnd = 0; - for (let n4 = fragment.firstChild; n4 && !n4.isLeaf && (openIsolating || !n4.type.spec.isolating); n4 = n4.firstChild) - openStart++; - for (let n4 = fragment.lastChild; n4 && !n4.isLeaf && (openIsolating || !n4.type.spec.isolating); n4 = n4.lastChild) - openEnd++; - return new _Slice(fragment, openStart, openEnd); - } - }; - Slice.empty = new Slice(Fragment.empty, 0, 0); - function removeRange(content3, from, to) { - let { index: index2, offset } = content3.findIndex(from), child = content3.maybeChild(index2); - let { index: indexTo, offset: offsetTo } = content3.findIndex(to); - if (offset == from || child.isText) { - if (offsetTo != to && !content3.child(indexTo).isText) - throw new RangeError("Removing non-flat range"); - return content3.cut(0, from).append(content3.cut(to)); - } - if (index2 != indexTo) - throw new RangeError("Removing non-flat range"); - return content3.replaceChild(index2, child.copy(removeRange(child.content, from - offset - 1, to - offset - 1))); - } - function insertInto(content3, dist, insert, parent) { - let { index: index2, offset } = content3.findIndex(dist), child = content3.maybeChild(index2); - if (offset == dist || child.isText) { - if (parent && !parent.canReplace(index2, index2, insert)) - return null; - return content3.cut(0, dist).append(insert).append(content3.cut(dist)); - } - let inner = insertInto(child.content, dist - offset - 1, insert); - return inner && content3.replaceChild(index2, child.copy(inner)); - } - function replace($from, $to, slice) { - if (slice.openStart > $from.depth) - throw new ReplaceError("Inserted content deeper than insertion position"); - if ($from.depth - slice.openStart != $to.depth - slice.openEnd) - throw new ReplaceError("Inconsistent open depths"); - return replaceOuter($from, $to, slice, 0); - } - function replaceOuter($from, $to, slice, depth) { - let index2 = $from.index(depth), node2 = $from.node(depth); - if (index2 == $to.index(depth) && depth < $from.depth - slice.openStart) { - let inner = replaceOuter($from, $to, slice, depth + 1); - return node2.copy(node2.content.replaceChild(index2, inner)); - } else if (!slice.content.size) { - return close(node2, replaceTwoWay($from, $to, depth)); - } else if (!slice.openStart && !slice.openEnd && $from.depth == depth && $to.depth == depth) { - let parent = $from.parent, content3 = parent.content; - return close(parent, content3.cut(0, $from.parentOffset).append(slice.content).append(content3.cut($to.parentOffset))); - } else { - let { start, end } = prepareSliceForReplace(slice, $from); - return close(node2, replaceThreeWay($from, start, end, $to, depth)); - } - } - function checkJoin(main, sub) { - if (!sub.type.compatibleContent(main.type)) - throw new ReplaceError("Cannot join " + sub.type.name + " onto " + main.type.name); - } - function joinable($before, $after, depth) { - let node2 = $before.node(depth); - checkJoin(node2, $after.node(depth)); - return node2; - } - function addNode(child, target) { - let last = target.length - 1; - if (last >= 0 && child.isText && child.sameMarkup(target[last])) - target[last] = child.withText(target[last].text + child.text); - else - target.push(child); - } - function addRange($start, $end, depth, target) { - let node2 = ($end || $start).node(depth); - let startIndex = 0, endIndex = $end ? $end.index(depth) : node2.childCount; - if ($start) { - startIndex = $start.index(depth); - if ($start.depth > depth) { - startIndex++; - } else if ($start.textOffset) { - addNode($start.nodeAfter, target); - startIndex++; - } - } - for (let i2 = startIndex; i2 < endIndex; i2++) - addNode(node2.child(i2), target); - if ($end && $end.depth == depth && $end.textOffset) - addNode($end.nodeBefore, target); - } - function close(node2, content3) { - node2.type.checkContent(content3); - return node2.copy(content3); - } - function replaceThreeWay($from, $start, $end, $to, depth) { - let openStart = $from.depth > depth && joinable($from, $start, depth + 1); - let openEnd = $to.depth > depth && joinable($end, $to, depth + 1); - let content3 = []; - addRange(null, $from, depth, content3); - if (openStart && openEnd && $start.index(depth) == $end.index(depth)) { - checkJoin(openStart, openEnd); - addNode(close(openStart, replaceThreeWay($from, $start, $end, $to, depth + 1)), content3); - } else { - if (openStart) - addNode(close(openStart, replaceTwoWay($from, $start, depth + 1)), content3); - addRange($start, $end, depth, content3); - if (openEnd) - addNode(close(openEnd, replaceTwoWay($end, $to, depth + 1)), content3); - } - addRange($to, null, depth, content3); - return new Fragment(content3); - } - function replaceTwoWay($from, $to, depth) { - let content3 = []; - addRange(null, $from, depth, content3); - if ($from.depth > depth) { - let type = joinable($from, $to, depth + 1); - addNode(close(type, replaceTwoWay($from, $to, depth + 1)), content3); - } - addRange($to, null, depth, content3); - return new Fragment(content3); - } - function prepareSliceForReplace(slice, $along) { - let extra = $along.depth - slice.openStart, parent = $along.node(extra); - let node2 = parent.copy(slice.content); - for (let i2 = extra - 1; i2 >= 0; i2--) - node2 = $along.node(i2).copy(Fragment.from(node2)); - return { - start: node2.resolveNoCache(slice.openStart + extra), - end: node2.resolveNoCache(node2.content.size - slice.openEnd - extra) - }; - } - var ResolvedPos = class _ResolvedPos { - /** - @internal - */ - constructor(pos, path3, parentOffset) { - this.pos = pos; - this.path = path3; - this.parentOffset = parentOffset; - this.depth = path3.length / 3 - 1; - } - /** - @internal - */ - resolveDepth(val) { - if (val == null) - return this.depth; - if (val < 0) - return this.depth + val; - return val; - } - /** - The parent node that the position points into. Note that even if - a position points into a text node, that node is not considered - the parent—text nodes are ‘flat’ in this model, and have no content. - */ - get parent() { - return this.node(this.depth); - } - /** - The root node in which the position was resolved. - */ - get doc() { - return this.node(0); - } - /** - The ancestor node at the given level. `p.node(p.depth)` is the - same as `p.parent`. - */ - node(depth) { - return this.path[this.resolveDepth(depth) * 3]; - } - /** - The index into the ancestor at the given level. If this points - at the 3rd node in the 2nd paragraph on the top level, for - example, `p.index(0)` is 1 and `p.index(1)` is 2. - */ - index(depth) { - return this.path[this.resolveDepth(depth) * 3 + 1]; - } - /** - The index pointing after this position into the ancestor at the - given level. - */ - indexAfter(depth) { - depth = this.resolveDepth(depth); - return this.index(depth) + (depth == this.depth && !this.textOffset ? 0 : 1); - } - /** - The (absolute) position at the start of the node at the given - level. - */ - start(depth) { - depth = this.resolveDepth(depth); - return depth == 0 ? 0 : this.path[depth * 3 - 1] + 1; - } - /** - The (absolute) position at the end of the node at the given - level. - */ - end(depth) { - depth = this.resolveDepth(depth); - return this.start(depth) + this.node(depth).content.size; - } - /** - The (absolute) position directly before the wrapping node at the - given level, or, when `depth` is `this.depth + 1`, the original - position. - */ - before(depth) { - depth = this.resolveDepth(depth); - if (!depth) - throw new RangeError("There is no position before the top-level node"); - return depth == this.depth + 1 ? this.pos : this.path[depth * 3 - 1]; - } - /** - The (absolute) position directly after the wrapping node at the - given level, or the original position when `depth` is `this.depth + 1`. - */ - after(depth) { - depth = this.resolveDepth(depth); - if (!depth) - throw new RangeError("There is no position after the top-level node"); - return depth == this.depth + 1 ? this.pos : this.path[depth * 3 - 1] + this.path[depth * 3].nodeSize; - } - /** - When this position points into a text node, this returns the - distance between the position and the start of the text node. - Will be zero for positions that point between nodes. - */ - get textOffset() { - return this.pos - this.path[this.path.length - 1]; - } - /** - Get the node directly after the position, if any. If the position - points into a text node, only the part of that node after the - position is returned. - */ - get nodeAfter() { - let parent = this.parent, index2 = this.index(this.depth); - if (index2 == parent.childCount) - return null; - let dOff = this.pos - this.path[this.path.length - 1], child = parent.child(index2); - return dOff ? parent.child(index2).cut(dOff) : child; - } - /** - Get the node directly before the position, if any. If the - position points into a text node, only the part of that node - before the position is returned. - */ - get nodeBefore() { - let index2 = this.index(this.depth); - let dOff = this.pos - this.path[this.path.length - 1]; - if (dOff) - return this.parent.child(index2).cut(0, dOff); - return index2 == 0 ? null : this.parent.child(index2 - 1); - } - /** - Get the position at the given index in the parent node at the - given depth (which defaults to `this.depth`). - */ - posAtIndex(index2, depth) { - depth = this.resolveDepth(depth); - let node2 = this.path[depth * 3], pos = depth == 0 ? 0 : this.path[depth * 3 - 1] + 1; - for (let i2 = 0; i2 < index2; i2++) - pos += node2.child(i2).nodeSize; - return pos; - } - /** - Get the marks at this position, factoring in the surrounding - marks' [`inclusive`](https://prosemirror.net/docs/ref/#model.MarkSpec.inclusive) property. If the - position is at the start of a non-empty node, the marks of the - node after it (if any) are returned. - */ - marks() { - let parent = this.parent, index2 = this.index(); - if (parent.content.size == 0) - return Mark.none; - if (this.textOffset) - return parent.child(index2).marks; - let main = parent.maybeChild(index2 - 1), other = parent.maybeChild(index2); - if (!main) { - let tmp = main; - main = other; - other = tmp; - } - let marks = main.marks; - for (var i2 = 0; i2 < marks.length; i2++) - if (marks[i2].type.spec.inclusive === false && (!other || !marks[i2].isInSet(other.marks))) - marks = marks[i2--].removeFromSet(marks); - return marks; - } - /** - Get the marks after the current position, if any, except those - that are non-inclusive and not present at position `$end`. This - is mostly useful for getting the set of marks to preserve after a - deletion. Will return `null` if this position is at the end of - its parent node or its parent node isn't a textblock (in which - case no marks should be preserved). - */ - marksAcross($end) { - let after = this.parent.maybeChild(this.index()); - if (!after || !after.isInline) - return null; - let marks = after.marks, next = $end.parent.maybeChild($end.index()); - for (var i2 = 0; i2 < marks.length; i2++) - if (marks[i2].type.spec.inclusive === false && (!next || !marks[i2].isInSet(next.marks))) - marks = marks[i2--].removeFromSet(marks); - return marks; - } - /** - The depth up to which this position and the given (non-resolved) - position share the same parent nodes. - */ - sharedDepth(pos) { - for (let depth = this.depth; depth > 0; depth--) - if (this.start(depth) <= pos && this.end(depth) >= pos) - return depth; - return 0; - } - /** - Returns a range based on the place where this position and the - given position diverge around block content. If both point into - the same textblock, for example, a range around that textblock - will be returned. If they point into different blocks, the range - around those blocks in their shared ancestor is returned. You can - pass in an optional predicate that will be called with a parent - node to see if a range into that parent is acceptable. - */ - blockRange(other = this, pred) { - if (other.pos < this.pos) - return other.blockRange(this); - for (let d6 = this.depth - (this.parent.inlineContent || this.pos == other.pos ? 1 : 0); d6 >= 0; d6--) - if (other.pos <= this.end(d6) && (!pred || pred(this.node(d6)))) - return new NodeRange(this, other, d6); - return null; - } - /** - Query whether the given position shares the same parent node. - */ - sameParent(other) { - return this.pos - this.parentOffset == other.pos - other.parentOffset; - } - /** - Return the greater of this and the given position. - */ - max(other) { - return other.pos > this.pos ? other : this; - } - /** - Return the smaller of this and the given position. - */ - min(other) { - return other.pos < this.pos ? other : this; - } - /** - @internal - */ - toString() { - let str = ""; - for (let i2 = 1; i2 <= this.depth; i2++) - str += (str ? "/" : "") + this.node(i2).type.name + "_" + this.index(i2 - 1); - return str + ":" + this.parentOffset; - } - /** - @internal - */ - static resolve(doc4, pos) { - if (!(pos >= 0 && pos <= doc4.content.size)) - throw new RangeError("Position " + pos + " out of range"); - let path3 = []; - let start = 0, parentOffset = pos; - for (let node2 = doc4; ; ) { - let { index: index2, offset } = node2.content.findIndex(parentOffset); - let rem = parentOffset - offset; - path3.push(node2, index2, start + offset); - if (!rem) - break; - node2 = node2.child(index2); - if (node2.isText) - break; - parentOffset = rem - 1; - start += offset + 1; - } - return new _ResolvedPos(pos, path3, parentOffset); - } - /** - @internal - */ - static resolveCached(doc4, pos) { - for (let i2 = 0; i2 < resolveCache.length; i2++) { - let cached = resolveCache[i2]; - if (cached.pos == pos && cached.doc == doc4) - return cached; - } - let result = resolveCache[resolveCachePos] = _ResolvedPos.resolve(doc4, pos); - resolveCachePos = (resolveCachePos + 1) % resolveCacheSize; - return result; - } - }; - var resolveCache = []; - var resolveCachePos = 0; - var resolveCacheSize = 12; - var NodeRange = class { - /** - Construct a node range. `$from` and `$to` should point into the - same node until at least the given `depth`, since a node range - denotes an adjacent set of nodes in a single parent node. - */ - constructor($from, $to, depth) { - this.$from = $from; - this.$to = $to; - this.depth = depth; - } - /** - The position at the start of the range. - */ - get start() { - return this.$from.before(this.depth + 1); - } - /** - The position at the end of the range. - */ - get end() { - return this.$to.after(this.depth + 1); - } - /** - The parent node that the range points into. - */ - get parent() { - return this.$from.node(this.depth); - } - /** - The start index of the range in the parent node. - */ - get startIndex() { - return this.$from.index(this.depth); - } - /** - The end index of the range in the parent node. - */ - get endIndex() { - return this.$to.indexAfter(this.depth); - } - }; - var emptyAttrs = /* @__PURE__ */ Object.create(null); - var Node2 = class _Node { - /** - @internal - */ - constructor(type, attrs, content3, marks = Mark.none) { - this.type = type; - this.attrs = attrs; - this.marks = marks; - this.content = content3 || Fragment.empty; - } - /** - The size of this node, as defined by the integer-based [indexing - scheme](/docs/guide/#doc.indexing). For text nodes, this is the - amount of characters. For other leaf nodes, it is one. For - non-leaf nodes, it is the size of the content plus two (the - start and end token). - */ - get nodeSize() { - return this.isLeaf ? 1 : 2 + this.content.size; - } - /** - The number of children that the node has. - */ - get childCount() { - return this.content.childCount; - } - /** - Get the child node at the given index. Raises an error when the - index is out of range. - */ - child(index2) { - return this.content.child(index2); - } - /** - Get the child node at the given index, if it exists. - */ - maybeChild(index2) { - return this.content.maybeChild(index2); - } - /** - Call `f` for every child node, passing the node, its offset - into this parent node, and its index. - */ - forEach(f3) { - this.content.forEach(f3); - } - /** - Invoke a callback for all descendant nodes recursively between - the given two positions that are relative to start of this - node's content. The callback is invoked with the node, its - position relative to the original node (method receiver), - its parent node, and its child index. When the callback returns - false for a given node, that node's children will not be - recursed over. The last parameter can be used to specify a - starting position to count from. - */ - nodesBetween(from, to, f3, startPos = 0) { - this.content.nodesBetween(from, to, f3, startPos, this); - } - /** - Call the given callback for every descendant node. Doesn't - descend into a node when the callback returns `false`. - */ - descendants(f3) { - this.nodesBetween(0, this.content.size, f3); - } - /** - Concatenates all the text nodes found in this fragment and its - children. - */ - get textContent() { - return this.isLeaf && this.type.spec.leafText ? this.type.spec.leafText(this) : this.textBetween(0, this.content.size, ""); - } - /** - Get all text between positions `from` and `to`. When - `blockSeparator` is given, it will be inserted to separate text - from different block nodes. If `leafText` is given, it'll be - inserted for every non-text leaf node encountered, otherwise - [`leafText`](https://prosemirror.net/docs/ref/#model.NodeSpec^leafText) will be used. - */ - textBetween(from, to, blockSeparator, leafText) { - return this.content.textBetween(from, to, blockSeparator, leafText); - } - /** - Returns this node's first child, or `null` if there are no - children. - */ - get firstChild() { - return this.content.firstChild; - } - /** - Returns this node's last child, or `null` if there are no - children. - */ - get lastChild() { - return this.content.lastChild; - } - /** - Test whether two nodes represent the same piece of document. - */ - eq(other) { - return this == other || this.sameMarkup(other) && this.content.eq(other.content); - } - /** - Compare the markup (type, attributes, and marks) of this node to - those of another. Returns `true` if both have the same markup. - */ - sameMarkup(other) { - return this.hasMarkup(other.type, other.attrs, other.marks); - } - /** - Check whether this node's markup correspond to the given type, - attributes, and marks. - */ - hasMarkup(type, attrs, marks) { - return this.type == type && compareDeep(this.attrs, attrs || type.defaultAttrs || emptyAttrs) && Mark.sameSet(this.marks, marks || Mark.none); - } - /** - Create a new node with the same markup as this node, containing - the given content (or empty, if no content is given). - */ - copy(content3 = null) { - if (content3 == this.content) - return this; - return new _Node(this.type, this.attrs, content3, this.marks); - } - /** - Create a copy of this node, with the given set of marks instead - of the node's own marks. - */ - mark(marks) { - return marks == this.marks ? this : new _Node(this.type, this.attrs, this.content, marks); - } - /** - Create a copy of this node with only the content between the - given positions. If `to` is not given, it defaults to the end of - the node. - */ - cut(from, to = this.content.size) { - if (from == 0 && to == this.content.size) - return this; - return this.copy(this.content.cut(from, to)); - } - /** - Cut out the part of the document between the given positions, and - return it as a `Slice` object. - */ - slice(from, to = this.content.size, includeParents = false) { - if (from == to) - return Slice.empty; - let $from = this.resolve(from), $to = this.resolve(to); - let depth = includeParents ? 0 : $from.sharedDepth(to); - let start = $from.start(depth), node2 = $from.node(depth); - let content3 = node2.content.cut($from.pos - start, $to.pos - start); - return new Slice(content3, $from.depth - depth, $to.depth - depth); - } - /** - Replace the part of the document between the given positions with - the given slice. The slice must 'fit', meaning its open sides - must be able to connect to the surrounding content, and its - content nodes must be valid children for the node they are placed - into. If any of this is violated, an error of type - [`ReplaceError`](https://prosemirror.net/docs/ref/#model.ReplaceError) is thrown. - */ - replace(from, to, slice) { - return replace(this.resolve(from), this.resolve(to), slice); - } - /** - Find the node directly after the given position. - */ - nodeAt(pos) { - for (let node2 = this; ; ) { - let { index: index2, offset } = node2.content.findIndex(pos); - node2 = node2.maybeChild(index2); - if (!node2) - return null; - if (offset == pos || node2.isText) - return node2; - pos -= offset + 1; - } - } - /** - Find the (direct) child node after the given offset, if any, - and return it along with its index and offset relative to this - node. - */ - childAfter(pos) { - let { index: index2, offset } = this.content.findIndex(pos); - return { node: this.content.maybeChild(index2), index: index2, offset }; - } - /** - Find the (direct) child node before the given offset, if any, - and return it along with its index and offset relative to this - node. - */ - childBefore(pos) { - if (pos == 0) - return { node: null, index: 0, offset: 0 }; - let { index: index2, offset } = this.content.findIndex(pos); - if (offset < pos) - return { node: this.content.child(index2), index: index2, offset }; - let node2 = this.content.child(index2 - 1); - return { node: node2, index: index2 - 1, offset: offset - node2.nodeSize }; - } - /** - Resolve the given position in the document, returning an - [object](https://prosemirror.net/docs/ref/#model.ResolvedPos) with information about its context. - */ - resolve(pos) { - return ResolvedPos.resolveCached(this, pos); - } - /** - @internal - */ - resolveNoCache(pos) { - return ResolvedPos.resolve(this, pos); - } - /** - Test whether a given mark or mark type occurs in this document - between the two given positions. - */ - rangeHasMark(from, to, type) { - let found2 = false; - if (to > from) - this.nodesBetween(from, to, (node2) => { - if (type.isInSet(node2.marks)) - found2 = true; - return !found2; - }); - return found2; - } - /** - True when this is a block (non-inline node) - */ - get isBlock() { - return this.type.isBlock; - } - /** - True when this is a textblock node, a block node with inline - content. - */ - get isTextblock() { - return this.type.isTextblock; - } - /** - True when this node allows inline content. - */ - get inlineContent() { - return this.type.inlineContent; - } - /** - True when this is an inline node (a text node or a node that can - appear among text). - */ - get isInline() { - return this.type.isInline; - } - /** - True when this is a text node. - */ - get isText() { - return this.type.isText; - } - /** - True when this is a leaf node. - */ - get isLeaf() { - return this.type.isLeaf; - } - /** - True when this is an atom, i.e. when it does not have directly - editable content. This is usually the same as `isLeaf`, but can - be configured with the [`atom` property](https://prosemirror.net/docs/ref/#model.NodeSpec.atom) - on a node's spec (typically used when the node is displayed as - an uneditable [node view](https://prosemirror.net/docs/ref/#view.NodeView)). - */ - get isAtom() { - return this.type.isAtom; - } - /** - Return a string representation of this node for debugging - purposes. - */ - toString() { - if (this.type.spec.toDebugString) - return this.type.spec.toDebugString(this); - let name = this.type.name; - if (this.content.size) - name += "(" + this.content.toStringInner() + ")"; - return wrapMarks(this.marks, name); - } - /** - Get the content match in this node at the given index. - */ - contentMatchAt(index2) { - let match = this.type.contentMatch.matchFragment(this.content, 0, index2); - if (!match) - throw new Error("Called contentMatchAt on a node with invalid content"); - return match; - } - /** - Test whether replacing the range between `from` and `to` (by - child index) with the given replacement fragment (which defaults - to the empty fragment) would leave the node's content valid. You - can optionally pass `start` and `end` indices into the - replacement fragment. - */ - canReplace(from, to, replacement = Fragment.empty, start = 0, end = replacement.childCount) { - let one2 = this.contentMatchAt(from).matchFragment(replacement, start, end); - let two = one2 && one2.matchFragment(this.content, to); - if (!two || !two.validEnd) - return false; - for (let i2 = start; i2 < end; i2++) - if (!this.type.allowsMarks(replacement.child(i2).marks)) - return false; - return true; - } - /** - Test whether replacing the range `from` to `to` (by index) with - a node of the given type would leave the node's content valid. - */ - canReplaceWith(from, to, type, marks) { - if (marks && !this.type.allowsMarks(marks)) - return false; - let start = this.contentMatchAt(from).matchType(type); - let end = start && start.matchFragment(this.content, to); - return end ? end.validEnd : false; - } - /** - Test whether the given node's content could be appended to this - node. If that node is empty, this will only return true if there - is at least one node type that can appear in both nodes (to avoid - merging completely incompatible nodes). - */ - canAppend(other) { - if (other.content.size) - return this.canReplace(this.childCount, this.childCount, other.content); - else - return this.type.compatibleContent(other.type); - } - /** - Check whether this node and its descendants conform to the - schema, and raise error when they do not. - */ - check() { - this.type.checkContent(this.content); - let copy2 = Mark.none; - for (let i2 = 0; i2 < this.marks.length; i2++) - copy2 = this.marks[i2].addToSet(copy2); - if (!Mark.sameSet(copy2, this.marks)) - throw new RangeError(`Invalid collection of marks for node ${this.type.name}: ${this.marks.map((m3) => m3.type.name)}`); - this.content.forEach((node2) => node2.check()); - } - /** - Return a JSON-serializeable representation of this node. - */ - toJSON() { - let obj = { type: this.type.name }; - for (let _3 in this.attrs) { - obj.attrs = this.attrs; - break; - } - if (this.content.size) - obj.content = this.content.toJSON(); - if (this.marks.length) - obj.marks = this.marks.map((n4) => n4.toJSON()); - return obj; - } - /** - Deserialize a node from its JSON representation. - */ - static fromJSON(schema, json) { - if (!json) - throw new RangeError("Invalid input for Node.fromJSON"); - let marks = null; - if (json.marks) { - if (!Array.isArray(json.marks)) - throw new RangeError("Invalid mark data for Node.fromJSON"); - marks = json.marks.map(schema.markFromJSON); - } - if (json.type == "text") { - if (typeof json.text != "string") - throw new RangeError("Invalid text node in JSON"); - return schema.text(json.text, marks); - } - let content3 = Fragment.fromJSON(schema, json.content); - return schema.nodeType(json.type).create(json.attrs, content3, marks); - } - }; - Node2.prototype.text = void 0; - var TextNode = class _TextNode extends Node2 { - /** - @internal - */ - constructor(type, attrs, content3, marks) { - super(type, attrs, null, marks); - if (!content3) - throw new RangeError("Empty text nodes are not allowed"); - this.text = content3; - } - toString() { - if (this.type.spec.toDebugString) - return this.type.spec.toDebugString(this); - return wrapMarks(this.marks, JSON.stringify(this.text)); - } - get textContent() { - return this.text; - } - textBetween(from, to) { - return this.text.slice(from, to); - } - get nodeSize() { - return this.text.length; - } - mark(marks) { - return marks == this.marks ? this : new _TextNode(this.type, this.attrs, this.text, marks); - } - withText(text5) { - if (text5 == this.text) - return this; - return new _TextNode(this.type, this.attrs, text5, this.marks); - } - cut(from = 0, to = this.text.length) { - if (from == 0 && to == this.text.length) - return this; - return this.withText(this.text.slice(from, to)); - } - eq(other) { - return this.sameMarkup(other) && this.text == other.text; - } - toJSON() { - let base2 = super.toJSON(); - base2.text = this.text; - return base2; - } - }; - function wrapMarks(marks, str) { - for (let i2 = marks.length - 1; i2 >= 0; i2--) - str = marks[i2].type.name + "(" + str + ")"; - return str; - } - var ContentMatch = class _ContentMatch { - /** - @internal - */ - constructor(validEnd) { - this.validEnd = validEnd; - this.next = []; - this.wrapCache = []; - } - /** - @internal - */ - static parse(string3, nodeTypes) { - let stream = new TokenStream(string3, nodeTypes); - if (stream.next == null) - return _ContentMatch.empty; - let expr = parseExpr(stream); - if (stream.next) - stream.err("Unexpected trailing text"); - let match = dfa(nfa(expr)); - checkForDeadEnds(match, stream); - return match; - } - /** - Match a node type, returning a match after that node if - successful. - */ - matchType(type) { - for (let i2 = 0; i2 < this.next.length; i2++) - if (this.next[i2].type == type) - return this.next[i2].next; - return null; - } - /** - Try to match a fragment. Returns the resulting match when - successful. - */ - matchFragment(frag, start = 0, end = frag.childCount) { - let cur = this; - for (let i2 = start; cur && i2 < end; i2++) - cur = cur.matchType(frag.child(i2).type); - return cur; - } - /** - @internal - */ - get inlineContent() { - return this.next.length != 0 && this.next[0].type.isInline; - } - /** - Get the first matching node type at this match position that can - be generated. - */ - get defaultType() { - for (let i2 = 0; i2 < this.next.length; i2++) { - let { type } = this.next[i2]; - if (!(type.isText || type.hasRequiredAttrs())) - return type; - } - return null; - } - /** - @internal - */ - compatible(other) { - for (let i2 = 0; i2 < this.next.length; i2++) - for (let j6 = 0; j6 < other.next.length; j6++) - if (this.next[i2].type == other.next[j6].type) - return true; - return false; - } - /** - Try to match the given fragment, and if that fails, see if it can - be made to match by inserting nodes in front of it. When - successful, return a fragment of inserted nodes (which may be - empty if nothing had to be inserted). When `toEnd` is true, only - return a fragment if the resulting match goes to the end of the - content expression. - */ - fillBefore(after, toEnd = false, startIndex = 0) { - let seen = [this]; - function search2(match, types) { - let finished = match.matchFragment(after, startIndex); - if (finished && (!toEnd || finished.validEnd)) - return Fragment.from(types.map((tp) => tp.createAndFill())); - for (let i2 = 0; i2 < match.next.length; i2++) { - let { type, next } = match.next[i2]; - if (!(type.isText || type.hasRequiredAttrs()) && seen.indexOf(next) == -1) { - seen.push(next); - let found2 = search2(next, types.concat(type)); - if (found2) - return found2; - } - } - return null; - } - return search2(this, []); - } - /** - Find a set of wrapping node types that would allow a node of the - given type to appear at this position. The result may be empty - (when it fits directly) and will be null when no such wrapping - exists. - */ - findWrapping(target) { - for (let i2 = 0; i2 < this.wrapCache.length; i2 += 2) - if (this.wrapCache[i2] == target) - return this.wrapCache[i2 + 1]; - let computed = this.computeWrapping(target); - this.wrapCache.push(target, computed); - return computed; - } - /** - @internal - */ - computeWrapping(target) { - let seen = /* @__PURE__ */ Object.create(null), active = [{ match: this, type: null, via: null }]; - while (active.length) { - let current = active.shift(), match = current.match; - if (match.matchType(target)) { - let result = []; - for (let obj = current; obj.type; obj = obj.via) - result.push(obj.type); - return result.reverse(); - } - for (let i2 = 0; i2 < match.next.length; i2++) { - let { type, next } = match.next[i2]; - if (!type.isLeaf && !type.hasRequiredAttrs() && !(type.name in seen) && (!current.type || next.validEnd)) { - active.push({ match: type.contentMatch, type, via: current }); - seen[type.name] = true; - } - } - } - return null; - } - /** - The number of outgoing edges this node has in the finite - automaton that describes the content expression. - */ - get edgeCount() { - return this.next.length; - } - /** - Get the _n_​th outgoing edge from this node in the finite - automaton that describes the content expression. - */ - edge(n4) { - if (n4 >= this.next.length) - throw new RangeError(`There's no ${n4}th edge in this content match`); - return this.next[n4]; - } - /** - @internal - */ - toString() { - let seen = []; - function scan(m3) { - seen.push(m3); - for (let i2 = 0; i2 < m3.next.length; i2++) - if (seen.indexOf(m3.next[i2].next) == -1) - scan(m3.next[i2].next); - } - scan(this); - return seen.map((m3, i2) => { - let out = i2 + (m3.validEnd ? "*" : " ") + " "; - for (let i3 = 0; i3 < m3.next.length; i3++) - out += (i3 ? ", " : "") + m3.next[i3].type.name + "->" + seen.indexOf(m3.next[i3].next); - return out; - }).join("\n"); - } - }; - ContentMatch.empty = new ContentMatch(true); - var TokenStream = class { - constructor(string3, nodeTypes) { - this.string = string3; - this.nodeTypes = nodeTypes; - this.inline = null; - this.pos = 0; - this.tokens = string3.split(/\s*(?=\b|\W|$)/); - if (this.tokens[this.tokens.length - 1] == "") - this.tokens.pop(); - if (this.tokens[0] == "") - this.tokens.shift(); - } - get next() { - return this.tokens[this.pos]; - } - eat(tok) { - return this.next == tok && (this.pos++ || true); - } - err(str) { - throw new SyntaxError(str + " (in content expression '" + this.string + "')"); - } - }; - function parseExpr(stream) { - let exprs = []; - do { - exprs.push(parseExprSeq(stream)); - } while (stream.eat("|")); - return exprs.length == 1 ? exprs[0] : { type: "choice", exprs }; - } - function parseExprSeq(stream) { - let exprs = []; - do { - exprs.push(parseExprSubscript(stream)); - } while (stream.next && stream.next != ")" && stream.next != "|"); - return exprs.length == 1 ? exprs[0] : { type: "seq", exprs }; - } - function parseExprSubscript(stream) { - let expr = parseExprAtom(stream); - for (; ; ) { - if (stream.eat("+")) - expr = { type: "plus", expr }; - else if (stream.eat("*")) - expr = { type: "star", expr }; - else if (stream.eat("?")) - expr = { type: "opt", expr }; - else if (stream.eat("{")) - expr = parseExprRange(stream, expr); - else - break; - } - return expr; - } - function parseNum(stream) { - if (/\D/.test(stream.next)) - stream.err("Expected number, got '" + stream.next + "'"); - let result = Number(stream.next); - stream.pos++; - return result; - } - function parseExprRange(stream, expr) { - let min = parseNum(stream), max = min; - if (stream.eat(",")) { - if (stream.next != "}") - max = parseNum(stream); - else - max = -1; - } - if (!stream.eat("}")) - stream.err("Unclosed braced range"); - return { type: "range", min, max, expr }; - } - function resolveName(stream, name) { - let types = stream.nodeTypes, type = types[name]; - if (type) - return [type]; - let result = []; - for (let typeName in types) { - let type2 = types[typeName]; - if (type2.groups.indexOf(name) > -1) - result.push(type2); - } - if (result.length == 0) - stream.err("No node type or group '" + name + "' found"); - return result; - } - function parseExprAtom(stream) { - if (stream.eat("(")) { - let expr = parseExpr(stream); - if (!stream.eat(")")) - stream.err("Missing closing paren"); - return expr; - } else if (!/\W/.test(stream.next)) { - let exprs = resolveName(stream, stream.next).map((type) => { - if (stream.inline == null) - stream.inline = type.isInline; - else if (stream.inline != type.isInline) - stream.err("Mixing inline and block content"); - return { type: "name", value: type }; - }); - stream.pos++; - return exprs.length == 1 ? exprs[0] : { type: "choice", exprs }; - } else { - stream.err("Unexpected token '" + stream.next + "'"); - } - } - function nfa(expr) { - let nfa2 = [[]]; - connect(compile(expr, 0), node2()); - return nfa2; - function node2() { - return nfa2.push([]) - 1; - } - function edge(from, to, term) { - let edge2 = { term, to }; - nfa2[from].push(edge2); - return edge2; - } - function connect(edges, to) { - edges.forEach((edge2) => edge2.to = to); - } - function compile(expr2, from) { - if (expr2.type == "choice") { - return expr2.exprs.reduce((out, expr3) => out.concat(compile(expr3, from)), []); - } else if (expr2.type == "seq") { - for (let i2 = 0; ; i2++) { - let next = compile(expr2.exprs[i2], from); - if (i2 == expr2.exprs.length - 1) - return next; - connect(next, from = node2()); - } - } else if (expr2.type == "star") { - let loop = node2(); - edge(from, loop); - connect(compile(expr2.expr, loop), loop); - return [edge(loop)]; - } else if (expr2.type == "plus") { - let loop = node2(); - connect(compile(expr2.expr, from), loop); - connect(compile(expr2.expr, loop), loop); - return [edge(loop)]; - } else if (expr2.type == "opt") { - return [edge(from)].concat(compile(expr2.expr, from)); - } else if (expr2.type == "range") { - let cur = from; - for (let i2 = 0; i2 < expr2.min; i2++) { - let next = node2(); - connect(compile(expr2.expr, cur), next); - cur = next; - } - if (expr2.max == -1) { - connect(compile(expr2.expr, cur), cur); - } else { - for (let i2 = expr2.min; i2 < expr2.max; i2++) { - let next = node2(); - edge(cur, next); - connect(compile(expr2.expr, cur), next); - cur = next; - } - } - return [edge(cur)]; - } else if (expr2.type == "name") { - return [edge(from, void 0, expr2.value)]; - } else { - throw new Error("Unknown expr type"); - } - } - } - function cmp(a2, b4) { - return b4 - a2; - } - function nullFrom(nfa2, node2) { - let result = []; - scan(node2); - return result.sort(cmp); - function scan(node3) { - let edges = nfa2[node3]; - if (edges.length == 1 && !edges[0].term) - return scan(edges[0].to); - result.push(node3); - for (let i2 = 0; i2 < edges.length; i2++) { - let { term, to } = edges[i2]; - if (!term && result.indexOf(to) == -1) - scan(to); - } - } - } - function dfa(nfa2) { - let labeled = /* @__PURE__ */ Object.create(null); - return explore(nullFrom(nfa2, 0)); - function explore(states) { - let out = []; - states.forEach((node2) => { - nfa2[node2].forEach(({ term, to }) => { - if (!term) - return; - let set; - for (let i2 = 0; i2 < out.length; i2++) - if (out[i2][0] == term) - set = out[i2][1]; - nullFrom(nfa2, to).forEach((node3) => { - if (!set) - out.push([term, set = []]); - if (set.indexOf(node3) == -1) - set.push(node3); - }); - }); - }); - let state = labeled[states.join(",")] = new ContentMatch(states.indexOf(nfa2.length - 1) > -1); - for (let i2 = 0; i2 < out.length; i2++) { - let states2 = out[i2][1].sort(cmp); - state.next.push({ type: out[i2][0], next: labeled[states2.join(",")] || explore(states2) }); - } - return state; - } - } - function checkForDeadEnds(match, stream) { - for (let i2 = 0, work = [match]; i2 < work.length; i2++) { - let state = work[i2], dead = !state.validEnd, nodes = []; - for (let j6 = 0; j6 < state.next.length; j6++) { - let { type, next } = state.next[j6]; - nodes.push(type.name); - if (dead && !(type.isText || type.hasRequiredAttrs())) - dead = false; - if (work.indexOf(next) == -1) - work.push(next); - } - if (dead) - stream.err("Only non-generatable nodes (" + nodes.join(", ") + ") in a required position (see https://prosemirror.net/docs/guide/#generatable)"); - } - } - function defaultAttrs(attrs) { - let defaults = /* @__PURE__ */ Object.create(null); - for (let attrName in attrs) { - let attr = attrs[attrName]; - if (!attr.hasDefault) - return null; - defaults[attrName] = attr.default; - } - return defaults; - } - function computeAttrs(attrs, value) { - let built = /* @__PURE__ */ Object.create(null); - for (let name in attrs) { - let given = value && value[name]; - if (given === void 0) { - let attr = attrs[name]; - if (attr.hasDefault) - given = attr.default; - else - throw new RangeError("No value supplied for attribute " + name); - } - built[name] = given; - } - return built; - } - function initAttrs(attrs) { - let result = /* @__PURE__ */ Object.create(null); - if (attrs) - for (let name in attrs) - result[name] = new Attribute(attrs[name]); - return result; - } - var NodeType = class _NodeType { - /** - @internal - */ - constructor(name, schema, spec) { - this.name = name; - this.schema = schema; - this.spec = spec; - this.markSet = null; - this.groups = spec.group ? spec.group.split(" ") : []; - this.attrs = initAttrs(spec.attrs); - this.defaultAttrs = defaultAttrs(this.attrs); - this.contentMatch = null; - this.inlineContent = null; - this.isBlock = !(spec.inline || name == "text"); - this.isText = name == "text"; - } - /** - True if this is an inline type. - */ - get isInline() { - return !this.isBlock; - } - /** - True if this is a textblock type, a block that contains inline - content. - */ - get isTextblock() { - return this.isBlock && this.inlineContent; - } - /** - True for node types that allow no content. - */ - get isLeaf() { - return this.contentMatch == ContentMatch.empty; - } - /** - True when this node is an atom, i.e. when it does not have - directly editable content. - */ - get isAtom() { - return this.isLeaf || !!this.spec.atom; - } - /** - The node type's [whitespace](https://prosemirror.net/docs/ref/#model.NodeSpec.whitespace) option. - */ - get whitespace() { - return this.spec.whitespace || (this.spec.code ? "pre" : "normal"); - } - /** - Tells you whether this node type has any required attributes. - */ - hasRequiredAttrs() { - for (let n4 in this.attrs) - if (this.attrs[n4].isRequired) - return true; - return false; - } - /** - Indicates whether this node allows some of the same content as - the given node type. - */ - compatibleContent(other) { - return this == other || this.contentMatch.compatible(other.contentMatch); - } - /** - @internal - */ - computeAttrs(attrs) { - if (!attrs && this.defaultAttrs) - return this.defaultAttrs; - else - return computeAttrs(this.attrs, attrs); - } - /** - Create a `Node` of this type. The given attributes are - checked and defaulted (you can pass `null` to use the type's - defaults entirely, if no required attributes exist). `content` - may be a `Fragment`, a node, an array of nodes, or - `null`. Similarly `marks` may be `null` to default to the empty - set of marks. - */ - create(attrs = null, content3, marks) { - if (this.isText) - throw new Error("NodeType.create can't construct text nodes"); - return new Node2(this, this.computeAttrs(attrs), Fragment.from(content3), Mark.setFrom(marks)); - } - /** - Like [`create`](https://prosemirror.net/docs/ref/#model.NodeType.create), but check the given content - against the node type's content restrictions, and throw an error - if it doesn't match. - */ - createChecked(attrs = null, content3, marks) { - content3 = Fragment.from(content3); - this.checkContent(content3); - return new Node2(this, this.computeAttrs(attrs), content3, Mark.setFrom(marks)); - } - /** - Like [`create`](https://prosemirror.net/docs/ref/#model.NodeType.create), but see if it is - necessary to add nodes to the start or end of the given fragment - to make it fit the node. If no fitting wrapping can be found, - return null. Note that, due to the fact that required nodes can - always be created, this will always succeed if you pass null or - `Fragment.empty` as content. - */ - createAndFill(attrs = null, content3, marks) { - attrs = this.computeAttrs(attrs); - content3 = Fragment.from(content3); - if (content3.size) { - let before = this.contentMatch.fillBefore(content3); - if (!before) - return null; - content3 = before.append(content3); - } - let matched = this.contentMatch.matchFragment(content3); - let after = matched && matched.fillBefore(Fragment.empty, true); - if (!after) - return null; - return new Node2(this, attrs, content3.append(after), Mark.setFrom(marks)); - } - /** - Returns true if the given fragment is valid content for this node - type with the given attributes. - */ - validContent(content3) { - let result = this.contentMatch.matchFragment(content3); - if (!result || !result.validEnd) - return false; - for (let i2 = 0; i2 < content3.childCount; i2++) - if (!this.allowsMarks(content3.child(i2).marks)) - return false; - return true; - } - /** - Throws a RangeError if the given fragment is not valid content for this - node type. - @internal - */ - checkContent(content3) { - if (!this.validContent(content3)) - throw new RangeError(`Invalid content for node ${this.name}: ${content3.toString().slice(0, 50)}`); - } - /** - Check whether the given mark type is allowed in this node. - */ - allowsMarkType(markType) { - return this.markSet == null || this.markSet.indexOf(markType) > -1; - } - /** - Test whether the given set of marks are allowed in this node. - */ - allowsMarks(marks) { - if (this.markSet == null) - return true; - for (let i2 = 0; i2 < marks.length; i2++) - if (!this.allowsMarkType(marks[i2].type)) - return false; - return true; - } - /** - Removes the marks that are not allowed in this node from the given set. - */ - allowedMarks(marks) { - if (this.markSet == null) - return marks; - let copy2; - for (let i2 = 0; i2 < marks.length; i2++) { - if (!this.allowsMarkType(marks[i2].type)) { - if (!copy2) - copy2 = marks.slice(0, i2); - } else if (copy2) { - copy2.push(marks[i2]); - } - } - return !copy2 ? marks : copy2.length ? copy2 : Mark.none; - } - /** - @internal - */ - static compile(nodes, schema) { - let result = /* @__PURE__ */ Object.create(null); - nodes.forEach((name, spec) => result[name] = new _NodeType(name, schema, spec)); - let topType = schema.spec.topNode || "doc"; - if (!result[topType]) - throw new RangeError("Schema is missing its top node type ('" + topType + "')"); - if (!result.text) - throw new RangeError("Every schema needs a 'text' type"); - for (let _3 in result.text.attrs) - throw new RangeError("The text node type should not have attributes"); - return result; - } - }; - var Attribute = class { - constructor(options2) { - this.hasDefault = Object.prototype.hasOwnProperty.call(options2, "default"); - this.default = options2.default; - } - get isRequired() { - return !this.hasDefault; - } - }; - var MarkType = class _MarkType { - /** - @internal - */ - constructor(name, rank, schema, spec) { - this.name = name; - this.rank = rank; - this.schema = schema; - this.spec = spec; - this.attrs = initAttrs(spec.attrs); - this.excluded = null; - let defaults = defaultAttrs(this.attrs); - this.instance = defaults ? new Mark(this, defaults) : null; - } - /** - Create a mark of this type. `attrs` may be `null` or an object - containing only some of the mark's attributes. The others, if - they have defaults, will be added. - */ - create(attrs = null) { - if (!attrs && this.instance) - return this.instance; - return new Mark(this, computeAttrs(this.attrs, attrs)); - } - /** - @internal - */ - static compile(marks, schema) { - let result = /* @__PURE__ */ Object.create(null), rank = 0; - marks.forEach((name, spec) => result[name] = new _MarkType(name, rank++, schema, spec)); - return result; - } - /** - When there is a mark of this type in the given set, a new set - without it is returned. Otherwise, the input set is returned. - */ - removeFromSet(set) { - for (var i2 = 0; i2 < set.length; i2++) - if (set[i2].type == this) { - set = set.slice(0, i2).concat(set.slice(i2 + 1)); - i2--; - } - return set; - } - /** - Tests whether there is a mark of this type in the given set. - */ - isInSet(set) { - for (let i2 = 0; i2 < set.length; i2++) - if (set[i2].type == this) - return set[i2]; - } - /** - Queries whether a given mark type is - [excluded](https://prosemirror.net/docs/ref/#model.MarkSpec.excludes) by this one. - */ - excludes(other) { - return this.excluded.indexOf(other) > -1; - } - }; - var Schema = class { - /** - Construct a schema from a schema [specification](https://prosemirror.net/docs/ref/#model.SchemaSpec). - */ - constructor(spec) { - this.linebreakReplacement = null; - this.cached = /* @__PURE__ */ Object.create(null); - let instanceSpec = this.spec = {}; - for (let prop in spec) - instanceSpec[prop] = spec[prop]; - instanceSpec.nodes = dist_default.from(spec.nodes), instanceSpec.marks = dist_default.from(spec.marks || {}), this.nodes = NodeType.compile(this.spec.nodes, this); - this.marks = MarkType.compile(this.spec.marks, this); - let contentExprCache = /* @__PURE__ */ Object.create(null); - for (let prop in this.nodes) { - if (prop in this.marks) - throw new RangeError(prop + " can not be both a node and a mark"); - let type = this.nodes[prop], contentExpr = type.spec.content || "", markExpr = type.spec.marks; - type.contentMatch = contentExprCache[contentExpr] || (contentExprCache[contentExpr] = ContentMatch.parse(contentExpr, this.nodes)); - type.inlineContent = type.contentMatch.inlineContent; - if (type.spec.linebreakReplacement) { - if (this.linebreakReplacement) - throw new RangeError("Multiple linebreak nodes defined"); - if (!type.isInline || !type.isLeaf) - throw new RangeError("Linebreak replacement nodes must be inline leaf nodes"); - this.linebreakReplacement = type; - } - type.markSet = markExpr == "_" ? null : markExpr ? gatherMarks(this, markExpr.split(" ")) : markExpr == "" || !type.inlineContent ? [] : null; - } - for (let prop in this.marks) { - let type = this.marks[prop], excl = type.spec.excludes; - type.excluded = excl == null ? [type] : excl == "" ? [] : gatherMarks(this, excl.split(" ")); - } - this.nodeFromJSON = this.nodeFromJSON.bind(this); - this.markFromJSON = this.markFromJSON.bind(this); - this.topNodeType = this.nodes[this.spec.topNode || "doc"]; - this.cached.wrappings = /* @__PURE__ */ Object.create(null); - } - /** - Create a node in this schema. The `type` may be a string or a - `NodeType` instance. Attributes will be extended with defaults, - `content` may be a `Fragment`, `null`, a `Node`, or an array of - nodes. - */ - node(type, attrs = null, content3, marks) { - if (typeof type == "string") - type = this.nodeType(type); - else if (!(type instanceof NodeType)) - throw new RangeError("Invalid node type: " + type); - else if (type.schema != this) - throw new RangeError("Node type from different schema used (" + type.name + ")"); - return type.createChecked(attrs, content3, marks); - } - /** - Create a text node in the schema. Empty text nodes are not - allowed. - */ - text(text5, marks) { - let type = this.nodes.text; - return new TextNode(type, type.defaultAttrs, text5, Mark.setFrom(marks)); - } - /** - Create a mark with the given type and attributes. - */ - mark(type, attrs) { - if (typeof type == "string") - type = this.marks[type]; - return type.create(attrs); - } - /** - Deserialize a node from its JSON representation. This method is - bound. - */ - nodeFromJSON(json) { - return Node2.fromJSON(this, json); - } - /** - Deserialize a mark from its JSON representation. This method is - bound. - */ - markFromJSON(json) { - return Mark.fromJSON(this, json); - } - /** - @internal - */ - nodeType(name) { - let found2 = this.nodes[name]; - if (!found2) - throw new RangeError("Unknown node type: " + name); - return found2; - } - }; - function gatherMarks(schema, marks) { - let found2 = []; - for (let i2 = 0; i2 < marks.length; i2++) { - let name = marks[i2], mark = schema.marks[name], ok3 = mark; - if (mark) { - found2.push(mark); - } else { - for (let prop in schema.marks) { - let mark2 = schema.marks[prop]; - if (name == "_" || mark2.spec.group && mark2.spec.group.split(" ").indexOf(name) > -1) - found2.push(ok3 = mark2); - } - } - if (!ok3) - throw new SyntaxError("Unknown mark type: '" + marks[i2] + "'"); - } - return found2; - } - function isTagRule(rule) { - return rule.tag != null; - } - function isStyleRule(rule) { - return rule.style != null; - } - var DOMParser = class _DOMParser { - /** - Create a parser that targets the given schema, using the given - parsing rules. - */ - constructor(schema, rules) { - this.schema = schema; - this.rules = rules; - this.tags = []; - this.styles = []; - rules.forEach((rule) => { - if (isTagRule(rule)) - this.tags.push(rule); - else if (isStyleRule(rule)) - this.styles.push(rule); - }); - this.normalizeLists = !this.tags.some((r3) => { - if (!/^(ul|ol)\b/.test(r3.tag) || !r3.node) - return false; - let node2 = schema.nodes[r3.node]; - return node2.contentMatch.matchType(node2); - }); - } - /** - Parse a document from the content of a DOM node. - */ - parse(dom, options2 = {}) { - let context = new ParseContext(this, options2, false); - context.addAll(dom, options2.from, options2.to); - return context.finish(); - } - /** - Parses the content of the given DOM node, like - [`parse`](https://prosemirror.net/docs/ref/#model.DOMParser.parse), and takes the same set of - options. But unlike that method, which produces a whole node, - this one returns a slice that is open at the sides, meaning that - the schema constraints aren't applied to the start of nodes to - the left of the input and the end of nodes at the end. - */ - parseSlice(dom, options2 = {}) { - let context = new ParseContext(this, options2, true); - context.addAll(dom, options2.from, options2.to); - return Slice.maxOpen(context.finish()); - } - /** - @internal - */ - matchTag(dom, context, after) { - for (let i2 = after ? this.tags.indexOf(after) + 1 : 0; i2 < this.tags.length; i2++) { - let rule = this.tags[i2]; - if (matches(dom, rule.tag) && (rule.namespace === void 0 || dom.namespaceURI == rule.namespace) && (!rule.context || context.matchesContext(rule.context))) { - if (rule.getAttrs) { - let result = rule.getAttrs(dom); - if (result === false) - continue; - rule.attrs = result || void 0; - } - return rule; - } - } - } - /** - @internal - */ - matchStyle(prop, value, context, after) { - for (let i2 = after ? this.styles.indexOf(after) + 1 : 0; i2 < this.styles.length; i2++) { - let rule = this.styles[i2], style2 = rule.style; - if (style2.indexOf(prop) != 0 || rule.context && !context.matchesContext(rule.context) || // Test that the style string either precisely matches the prop, - // or has an '=' sign after the prop, followed by the given - // value. - style2.length > prop.length && (style2.charCodeAt(prop.length) != 61 || style2.slice(prop.length + 1) != value)) - continue; - if (rule.getAttrs) { - let result = rule.getAttrs(value); - if (result === false) - continue; - rule.attrs = result || void 0; - } - return rule; - } - } - /** - @internal - */ - static schemaRules(schema) { - let result = []; - function insert(rule) { - let priority = rule.priority == null ? 50 : rule.priority, i2 = 0; - for (; i2 < result.length; i2++) { - let next = result[i2], nextPriority = next.priority == null ? 50 : next.priority; - if (nextPriority < priority) - break; - } - result.splice(i2, 0, rule); - } - for (let name in schema.marks) { - let rules = schema.marks[name].spec.parseDOM; - if (rules) - rules.forEach((rule) => { - insert(rule = copy(rule)); - if (!(rule.mark || rule.ignore || rule.clearMark)) - rule.mark = name; - }); - } - for (let name in schema.nodes) { - let rules = schema.nodes[name].spec.parseDOM; - if (rules) - rules.forEach((rule) => { - insert(rule = copy(rule)); - if (!(rule.node || rule.ignore || rule.mark)) - rule.node = name; - }); - } - return result; - } - /** - Construct a DOM parser using the parsing rules listed in a - schema's [node specs](https://prosemirror.net/docs/ref/#model.NodeSpec.parseDOM), reordered by - [priority](https://prosemirror.net/docs/ref/#model.ParseRule.priority). - */ - static fromSchema(schema) { - return schema.cached.domParser || (schema.cached.domParser = new _DOMParser(schema, _DOMParser.schemaRules(schema))); - } - }; - var blockTags = { - address: true, - article: true, - aside: true, - blockquote: true, - canvas: true, - dd: true, - div: true, - dl: true, - fieldset: true, - figcaption: true, - figure: true, - footer: true, - form: true, - h1: true, - h2: true, - h3: true, - h4: true, - h5: true, - h6: true, - header: true, - hgroup: true, - hr: true, - li: true, - noscript: true, - ol: true, - output: true, - p: true, - pre: true, - section: true, - table: true, - tfoot: true, - ul: true - }; - var ignoreTags = { - head: true, - noscript: true, - object: true, - script: true, - style: true, - title: true - }; - var listTags = { ol: true, ul: true }; - var OPT_PRESERVE_WS = 1; - var OPT_PRESERVE_WS_FULL = 2; - var OPT_OPEN_LEFT = 4; - function wsOptionsFor(type, preserveWhitespace, base2) { - if (preserveWhitespace != null) - return (preserveWhitespace ? OPT_PRESERVE_WS : 0) | (preserveWhitespace === "full" ? OPT_PRESERVE_WS_FULL : 0); - return type && type.whitespace == "pre" ? OPT_PRESERVE_WS | OPT_PRESERVE_WS_FULL : base2 & ~OPT_OPEN_LEFT; - } - var NodeContext = class { - constructor(type, attrs, marks, pendingMarks, solid, match, options2) { - this.type = type; - this.attrs = attrs; - this.marks = marks; - this.pendingMarks = pendingMarks; - this.solid = solid; - this.options = options2; - this.content = []; - this.activeMarks = Mark.none; - this.stashMarks = []; - this.match = match || (options2 & OPT_OPEN_LEFT ? null : type.contentMatch); - } - findWrapping(node2) { - if (!this.match) { - if (!this.type) - return []; - let fill = this.type.contentMatch.fillBefore(Fragment.from(node2)); - if (fill) { - this.match = this.type.contentMatch.matchFragment(fill); - } else { - let start = this.type.contentMatch, wrap3; - if (wrap3 = start.findWrapping(node2.type)) { - this.match = start; - return wrap3; - } else { - return null; - } - } - } - return this.match.findWrapping(node2.type); - } - finish(openEnd) { - if (!(this.options & OPT_PRESERVE_WS)) { - let last = this.content[this.content.length - 1], m3; - if (last && last.isText && (m3 = /[ \t\r\n\u000c]+$/.exec(last.text))) { - let text5 = last; - if (last.text.length == m3[0].length) - this.content.pop(); - else - this.content[this.content.length - 1] = text5.withText(text5.text.slice(0, text5.text.length - m3[0].length)); - } - } - let content3 = Fragment.from(this.content); - if (!openEnd && this.match) - content3 = content3.append(this.match.fillBefore(Fragment.empty, true)); - return this.type ? this.type.create(this.attrs, content3, this.marks) : content3; - } - popFromStashMark(mark) { - for (let i2 = this.stashMarks.length - 1; i2 >= 0; i2--) - if (mark.eq(this.stashMarks[i2])) - return this.stashMarks.splice(i2, 1)[0]; - } - applyPending(nextType) { - for (let i2 = 0, pending = this.pendingMarks; i2 < pending.length; i2++) { - let mark = pending[i2]; - if ((this.type ? this.type.allowsMarkType(mark.type) : markMayApply(mark.type, nextType)) && !mark.isInSet(this.activeMarks)) { - this.activeMarks = mark.addToSet(this.activeMarks); - this.pendingMarks = mark.removeFromSet(this.pendingMarks); - } - } - } - inlineContext(node2) { - if (this.type) - return this.type.inlineContent; - if (this.content.length) - return this.content[0].isInline; - return node2.parentNode && !blockTags.hasOwnProperty(node2.parentNode.nodeName.toLowerCase()); - } - }; - var ParseContext = class { - constructor(parser, options2, isOpen) { - this.parser = parser; - this.options = options2; - this.isOpen = isOpen; - this.open = 0; - let topNode = options2.topNode, topContext; - let topOptions = wsOptionsFor(null, options2.preserveWhitespace, 0) | (isOpen ? OPT_OPEN_LEFT : 0); - if (topNode) - topContext = new NodeContext(topNode.type, topNode.attrs, Mark.none, Mark.none, true, options2.topMatch || topNode.type.contentMatch, topOptions); - else if (isOpen) - topContext = new NodeContext(null, null, Mark.none, Mark.none, true, null, topOptions); - else - topContext = new NodeContext(parser.schema.topNodeType, null, Mark.none, Mark.none, true, null, topOptions); - this.nodes = [topContext]; - this.find = options2.findPositions; - this.needsBlock = false; - } - get top() { - return this.nodes[this.open]; - } - // Add a DOM node to the content. Text is inserted as text node, - // otherwise, the node is passed to `addElement` or, if it has a - // `style` attribute, `addElementWithStyles`. - addDOM(dom) { - if (dom.nodeType == 3) - this.addTextNode(dom); - else if (dom.nodeType == 1) - this.addElement(dom); - } - withStyleRules(dom, f3) { - let style2 = dom.getAttribute("style"); - if (!style2) - return f3(); - let marks = this.readStyles(parseStyles(style2)); - if (!marks) - return; - let [addMarks, removeMarks] = marks, top = this.top; - for (let i2 = 0; i2 < removeMarks.length; i2++) - this.removePendingMark(removeMarks[i2], top); - for (let i2 = 0; i2 < addMarks.length; i2++) - this.addPendingMark(addMarks[i2]); - f3(); - for (let i2 = 0; i2 < addMarks.length; i2++) - this.removePendingMark(addMarks[i2], top); - for (let i2 = 0; i2 < removeMarks.length; i2++) - this.addPendingMark(removeMarks[i2]); - } - addTextNode(dom) { - let value = dom.nodeValue; - let top = this.top; - if (top.options & OPT_PRESERVE_WS_FULL || top.inlineContext(dom) || /[^ \t\r\n\u000c]/.test(value)) { - if (!(top.options & OPT_PRESERVE_WS)) { - value = value.replace(/[ \t\r\n\u000c]+/g, " "); - if (/^[ \t\r\n\u000c]/.test(value) && this.open == this.nodes.length - 1) { - let nodeBefore = top.content[top.content.length - 1]; - let domNodeBefore = dom.previousSibling; - if (!nodeBefore || domNodeBefore && domNodeBefore.nodeName == "BR" || nodeBefore.isText && /[ \t\r\n\u000c]$/.test(nodeBefore.text)) - value = value.slice(1); - } - } else if (!(top.options & OPT_PRESERVE_WS_FULL)) { - value = value.replace(/\r?\n|\r/g, " "); - } else { - value = value.replace(/\r\n?/g, "\n"); - } - if (value) - this.insertNode(this.parser.schema.text(value)); - this.findInText(dom); - } else { - this.findInside(dom); - } - } - // Try to find a handler for the given tag and use that to parse. If - // none is found, the element's content nodes are added directly. - addElement(dom, matchAfter) { - let name = dom.nodeName.toLowerCase(), ruleID; - if (listTags.hasOwnProperty(name) && this.parser.normalizeLists) - normalizeList(dom); - let rule = this.options.ruleFromNode && this.options.ruleFromNode(dom) || (ruleID = this.parser.matchTag(dom, this, matchAfter)); - if (rule ? rule.ignore : ignoreTags.hasOwnProperty(name)) { - this.findInside(dom); - this.ignoreFallback(dom); - } else if (!rule || rule.skip || rule.closeParent) { - if (rule && rule.closeParent) - this.open = Math.max(0, this.open - 1); - else if (rule && rule.skip.nodeType) - dom = rule.skip; - let sync, top = this.top, oldNeedsBlock = this.needsBlock; - if (blockTags.hasOwnProperty(name)) { - if (top.content.length && top.content[0].isInline && this.open) { - this.open--; - top = this.top; - } - sync = true; - if (!top.type) - this.needsBlock = true; - } else if (!dom.firstChild) { - this.leafFallback(dom); - return; - } - if (rule && rule.skip) - this.addAll(dom); - else - this.withStyleRules(dom, () => this.addAll(dom)); - if (sync) - this.sync(top); - this.needsBlock = oldNeedsBlock; - } else { - this.withStyleRules(dom, () => { - this.addElementByRule(dom, rule, rule.consuming === false ? ruleID : void 0); - }); - } - } - // Called for leaf DOM nodes that would otherwise be ignored - leafFallback(dom) { - if (dom.nodeName == "BR" && this.top.type && this.top.type.inlineContent) - this.addTextNode(dom.ownerDocument.createTextNode("\n")); - } - // Called for ignored nodes - ignoreFallback(dom) { - if (dom.nodeName == "BR" && (!this.top.type || !this.top.type.inlineContent)) - this.findPlace(this.parser.schema.text("-")); - } - // Run any style parser associated with the node's styles. Either - // return an array of marks, or null to indicate some of the styles - // had a rule with `ignore` set. - readStyles(styles) { - let add = Mark.none, remove = Mark.none; - for (let i2 = 0; i2 < styles.length; i2 += 2) { - for (let after = void 0; ; ) { - let rule = this.parser.matchStyle(styles[i2], styles[i2 + 1], this, after); - if (!rule) - break; - if (rule.ignore) - return null; - if (rule.clearMark) { - this.top.pendingMarks.concat(this.top.activeMarks).forEach((m3) => { - if (rule.clearMark(m3)) - remove = m3.addToSet(remove); - }); - } else { - add = this.parser.schema.marks[rule.mark].create(rule.attrs).addToSet(add); - } - if (rule.consuming === false) - after = rule; - else - break; - } - } - return [add, remove]; - } - // Look up a handler for the given node. If none are found, return - // false. Otherwise, apply it, use its return value to drive the way - // the node's content is wrapped, and return true. - addElementByRule(dom, rule, continueAfter) { - let sync, nodeType, mark; - if (rule.node) { - nodeType = this.parser.schema.nodes[rule.node]; - if (!nodeType.isLeaf) { - sync = this.enter(nodeType, rule.attrs || null, rule.preserveWhitespace); - } else if (!this.insertNode(nodeType.create(rule.attrs))) { - this.leafFallback(dom); - } - } else { - let markType = this.parser.schema.marks[rule.mark]; - mark = markType.create(rule.attrs); - this.addPendingMark(mark); - } - let startIn = this.top; - if (nodeType && nodeType.isLeaf) { - this.findInside(dom); - } else if (continueAfter) { - this.addElement(dom, continueAfter); - } else if (rule.getContent) { - this.findInside(dom); - rule.getContent(dom, this.parser.schema).forEach((node2) => this.insertNode(node2)); - } else { - let contentDOM = dom; - if (typeof rule.contentElement == "string") - contentDOM = dom.querySelector(rule.contentElement); - else if (typeof rule.contentElement == "function") - contentDOM = rule.contentElement(dom); - else if (rule.contentElement) - contentDOM = rule.contentElement; - this.findAround(dom, contentDOM, true); - this.addAll(contentDOM); - } - if (sync && this.sync(startIn)) - this.open--; - if (mark) - this.removePendingMark(mark, startIn); - } - // Add all child nodes between `startIndex` and `endIndex` (or the - // whole node, if not given). If `sync` is passed, use it to - // synchronize after every block element. - addAll(parent, startIndex, endIndex) { - let index2 = startIndex || 0; - for (let dom = startIndex ? parent.childNodes[startIndex] : parent.firstChild, end = endIndex == null ? null : parent.childNodes[endIndex]; dom != end; dom = dom.nextSibling, ++index2) { - this.findAtPoint(parent, index2); - this.addDOM(dom); - } - this.findAtPoint(parent, index2); - } - // Try to find a way to fit the given node type into the current - // context. May add intermediate wrappers and/or leave non-solid - // nodes that we're in. - findPlace(node2) { - let route, sync; - for (let depth = this.open; depth >= 0; depth--) { - let cx = this.nodes[depth]; - let found2 = cx.findWrapping(node2); - if (found2 && (!route || route.length > found2.length)) { - route = found2; - sync = cx; - if (!found2.length) - break; - } - if (cx.solid) - break; - } - if (!route) - return false; - this.sync(sync); - for (let i2 = 0; i2 < route.length; i2++) - this.enterInner(route[i2], null, false); - return true; - } - // Try to insert the given node, adjusting the context when needed. - insertNode(node2) { - if (node2.isInline && this.needsBlock && !this.top.type) { - let block = this.textblockFromContext(); - if (block) - this.enterInner(block); - } - if (this.findPlace(node2)) { - this.closeExtra(); - let top = this.top; - top.applyPending(node2.type); - if (top.match) - top.match = top.match.matchType(node2.type); - let marks = top.activeMarks; - for (let i2 = 0; i2 < node2.marks.length; i2++) - if (!top.type || top.type.allowsMarkType(node2.marks[i2].type)) - marks = node2.marks[i2].addToSet(marks); - top.content.push(node2.mark(marks)); - return true; - } - return false; - } - // Try to start a node of the given type, adjusting the context when - // necessary. - enter(type, attrs, preserveWS) { - let ok3 = this.findPlace(type.create(attrs)); - if (ok3) - this.enterInner(type, attrs, true, preserveWS); - return ok3; - } - // Open a node of the given type - enterInner(type, attrs = null, solid = false, preserveWS) { - this.closeExtra(); - let top = this.top; - top.applyPending(type); - top.match = top.match && top.match.matchType(type); - let options2 = wsOptionsFor(type, preserveWS, top.options); - if (top.options & OPT_OPEN_LEFT && top.content.length == 0) - options2 |= OPT_OPEN_LEFT; - this.nodes.push(new NodeContext(type, attrs, top.activeMarks, top.pendingMarks, solid, null, options2)); - this.open++; - } - // Make sure all nodes above this.open are finished and added to - // their parents - closeExtra(openEnd = false) { - let i2 = this.nodes.length - 1; - if (i2 > this.open) { - for (; i2 > this.open; i2--) - this.nodes[i2 - 1].content.push(this.nodes[i2].finish(openEnd)); - this.nodes.length = this.open + 1; - } - } - finish() { - this.open = 0; - this.closeExtra(this.isOpen); - return this.nodes[0].finish(this.isOpen || this.options.topOpen); - } - sync(to) { - for (let i2 = this.open; i2 >= 0; i2--) - if (this.nodes[i2] == to) { - this.open = i2; - return true; - } - return false; - } - get currentPos() { - this.closeExtra(); - let pos = 0; - for (let i2 = this.open; i2 >= 0; i2--) { - let content3 = this.nodes[i2].content; - for (let j6 = content3.length - 1; j6 >= 0; j6--) - pos += content3[j6].nodeSize; - if (i2) - pos++; - } - return pos; - } - findAtPoint(parent, offset) { - if (this.find) - for (let i2 = 0; i2 < this.find.length; i2++) { - if (this.find[i2].node == parent && this.find[i2].offset == offset) - this.find[i2].pos = this.currentPos; - } - } - findInside(parent) { - if (this.find) - for (let i2 = 0; i2 < this.find.length; i2++) { - if (this.find[i2].pos == null && parent.nodeType == 1 && parent.contains(this.find[i2].node)) - this.find[i2].pos = this.currentPos; - } - } - findAround(parent, content3, before) { - if (parent != content3 && this.find) - for (let i2 = 0; i2 < this.find.length; i2++) { - if (this.find[i2].pos == null && parent.nodeType == 1 && parent.contains(this.find[i2].node)) { - let pos = content3.compareDocumentPosition(this.find[i2].node); - if (pos & (before ? 2 : 4)) - this.find[i2].pos = this.currentPos; - } - } - } - findInText(textNode) { - if (this.find) - for (let i2 = 0; i2 < this.find.length; i2++) { - if (this.find[i2].node == textNode) - this.find[i2].pos = this.currentPos - (textNode.nodeValue.length - this.find[i2].offset); - } - } - // Determines whether the given context string matches this context. - matchesContext(context) { - if (context.indexOf("|") > -1) - return context.split(/\s*\|\s*/).some(this.matchesContext, this); - let parts = context.split("/"); - let option = this.options.context; - let useRoot = !this.isOpen && (!option || option.parent.type == this.nodes[0].type); - let minDepth = -(option ? option.depth + 1 : 0) + (useRoot ? 0 : 1); - let match = (i2, depth) => { - for (; i2 >= 0; i2--) { - let part = parts[i2]; - if (part == "") { - if (i2 == parts.length - 1 || i2 == 0) - continue; - for (; depth >= minDepth; depth--) - if (match(i2 - 1, depth)) - return true; - return false; - } else { - let next = depth > 0 || depth == 0 && useRoot ? this.nodes[depth].type : option && depth >= minDepth ? option.node(depth - minDepth).type : null; - if (!next || next.name != part && next.groups.indexOf(part) == -1) - return false; - depth--; - } - } - return true; - }; - return match(parts.length - 1, this.open); - } - textblockFromContext() { - let $context = this.options.context; - if ($context) - for (let d6 = $context.depth; d6 >= 0; d6--) { - let deflt = $context.node(d6).contentMatchAt($context.indexAfter(d6)).defaultType; - if (deflt && deflt.isTextblock && deflt.defaultAttrs) - return deflt; - } - for (let name in this.parser.schema.nodes) { - let type = this.parser.schema.nodes[name]; - if (type.isTextblock && type.defaultAttrs) - return type; - } - } - addPendingMark(mark) { - let found2 = findSameMarkInSet(mark, this.top.pendingMarks); - if (found2) - this.top.stashMarks.push(found2); - this.top.pendingMarks = mark.addToSet(this.top.pendingMarks); - } - removePendingMark(mark, upto) { - for (let depth = this.open; depth >= 0; depth--) { - let level = this.nodes[depth]; - let found2 = level.pendingMarks.lastIndexOf(mark); - if (found2 > -1) { - level.pendingMarks = mark.removeFromSet(level.pendingMarks); - } else { - level.activeMarks = mark.removeFromSet(level.activeMarks); - let stashMark = level.popFromStashMark(mark); - if (stashMark && level.type && level.type.allowsMarkType(stashMark.type)) - level.activeMarks = stashMark.addToSet(level.activeMarks); - } - if (level == upto) - break; - } - } - }; - function normalizeList(dom) { - for (let child = dom.firstChild, prevItem = null; child; child = child.nextSibling) { - let name = child.nodeType == 1 ? child.nodeName.toLowerCase() : null; - if (name && listTags.hasOwnProperty(name) && prevItem) { - prevItem.appendChild(child); - child = prevItem; - } else if (name == "li") { - prevItem = child; - } else if (name) { - prevItem = null; - } - } - } - function matches(dom, selector) { - return (dom.matches || dom.msMatchesSelector || dom.webkitMatchesSelector || dom.mozMatchesSelector).call(dom, selector); - } - function parseStyles(style2) { - let re4 = /\s*([\w-]+)\s*:\s*([^;]+)/g, m3, result = []; - while (m3 = re4.exec(style2)) - result.push(m3[1], m3[2].trim()); - return result; - } - function copy(obj) { - let copy2 = {}; - for (let prop in obj) - copy2[prop] = obj[prop]; - return copy2; - } - function markMayApply(markType, nodeType) { - let nodes = nodeType.schema.nodes; - for (let name in nodes) { - let parent = nodes[name]; - if (!parent.allowsMarkType(markType)) - continue; - let seen = [], scan = (match) => { - seen.push(match); - for (let i2 = 0; i2 < match.edgeCount; i2++) { - let { type, next } = match.edge(i2); - if (type == nodeType) - return true; - if (seen.indexOf(next) < 0 && scan(next)) - return true; - } - }; - if (scan(parent.contentMatch)) - return true; - } - } - function findSameMarkInSet(mark, set) { - for (let i2 = 0; i2 < set.length; i2++) { - if (mark.eq(set[i2])) - return set[i2]; - } - } - var DOMSerializer = class _DOMSerializer { - /** - Create a serializer. `nodes` should map node names to functions - that take a node and return a description of the corresponding - DOM. `marks` does the same for mark names, but also gets an - argument that tells it whether the mark's content is block or - inline content (for typical use, it'll always be inline). A mark - serializer may be `null` to indicate that marks of that type - should not be serialized. - */ - constructor(nodes, marks) { - this.nodes = nodes; - this.marks = marks; - } - /** - Serialize the content of this fragment to a DOM fragment. When - not in the browser, the `document` option, containing a DOM - document, should be passed so that the serializer can create - nodes. - */ - serializeFragment(fragment, options2 = {}, target) { - if (!target) - target = doc(options2).createDocumentFragment(); - let top = target, active = []; - fragment.forEach((node2) => { - if (active.length || node2.marks.length) { - let keep = 0, rendered = 0; - while (keep < active.length && rendered < node2.marks.length) { - let next = node2.marks[rendered]; - if (!this.marks[next.type.name]) { - rendered++; - continue; - } - if (!next.eq(active[keep][0]) || next.type.spec.spanning === false) - break; - keep++; - rendered++; - } - while (keep < active.length) - top = active.pop()[1]; - while (rendered < node2.marks.length) { - let add = node2.marks[rendered++]; - let markDOM = this.serializeMark(add, node2.isInline, options2); - if (markDOM) { - active.push([add, top]); - top.appendChild(markDOM.dom); - top = markDOM.contentDOM || markDOM.dom; - } - } - } - top.appendChild(this.serializeNodeInner(node2, options2)); - }); - return target; - } - /** - @internal - */ - serializeNodeInner(node2, options2) { - let { dom, contentDOM } = _DOMSerializer.renderSpec(doc(options2), this.nodes[node2.type.name](node2)); - if (contentDOM) { - if (node2.isLeaf) - throw new RangeError("Content hole not allowed in a leaf node spec"); - this.serializeFragment(node2.content, options2, contentDOM); - } - return dom; - } - /** - Serialize this node to a DOM node. This can be useful when you - need to serialize a part of a document, as opposed to the whole - document. To serialize a whole document, use - [`serializeFragment`](https://prosemirror.net/docs/ref/#model.DOMSerializer.serializeFragment) on - its [content](https://prosemirror.net/docs/ref/#model.Node.content). - */ - serializeNode(node2, options2 = {}) { - let dom = this.serializeNodeInner(node2, options2); - for (let i2 = node2.marks.length - 1; i2 >= 0; i2--) { - let wrap3 = this.serializeMark(node2.marks[i2], node2.isInline, options2); - if (wrap3) { - (wrap3.contentDOM || wrap3.dom).appendChild(dom); - dom = wrap3.dom; - } - } - return dom; - } - /** - @internal - */ - serializeMark(mark, inline, options2 = {}) { - let toDOM = this.marks[mark.type.name]; - return toDOM && _DOMSerializer.renderSpec(doc(options2), toDOM(mark, inline)); - } - /** - Render an [output spec](https://prosemirror.net/docs/ref/#model.DOMOutputSpec) to a DOM node. If - the spec has a hole (zero) in it, `contentDOM` will point at the - node with the hole. - */ - static renderSpec(doc4, structure, xmlNS = null) { - if (typeof structure == "string") - return { dom: doc4.createTextNode(structure) }; - if (structure.nodeType != null) - return { dom: structure }; - if (structure.dom && structure.dom.nodeType != null) - return structure; - let tagName = structure[0], space = tagName.indexOf(" "); - if (space > 0) { - xmlNS = tagName.slice(0, space); - tagName = tagName.slice(space + 1); - } - let contentDOM; - let dom = xmlNS ? doc4.createElementNS(xmlNS, tagName) : doc4.createElement(tagName); - let attrs = structure[1], start = 1; - if (attrs && typeof attrs == "object" && attrs.nodeType == null && !Array.isArray(attrs)) { - start = 2; - for (let name in attrs) - if (attrs[name] != null) { - let space2 = name.indexOf(" "); - if (space2 > 0) - dom.setAttributeNS(name.slice(0, space2), name.slice(space2 + 1), attrs[name]); - else - dom.setAttribute(name, attrs[name]); - } - } - for (let i2 = start; i2 < structure.length; i2++) { - let child = structure[i2]; - if (child === 0) { - if (i2 < structure.length - 1 || i2 > start) - throw new RangeError("Content hole must be the only child of its parent node"); - return { dom, contentDOM: dom }; - } else { - let { dom: inner, contentDOM: innerContent } = _DOMSerializer.renderSpec(doc4, child, xmlNS); - dom.appendChild(inner); - if (innerContent) { - if (contentDOM) - throw new RangeError("Multiple content holes"); - contentDOM = innerContent; - } - } - } - return { dom, contentDOM }; - } - /** - Build a serializer using the [`toDOM`](https://prosemirror.net/docs/ref/#model.NodeSpec.toDOM) - properties in a schema's node and mark specs. - */ - static fromSchema(schema) { - return schema.cached.domSerializer || (schema.cached.domSerializer = new _DOMSerializer(this.nodesFromSchema(schema), this.marksFromSchema(schema))); - } - /** - Gather the serializers in a schema's node specs into an object. - This can be useful as a base to build a custom serializer from. - */ - static nodesFromSchema(schema) { - let result = gatherToDOM(schema.nodes); - if (!result.text) - result.text = (node2) => node2.text; - return result; - } - /** - Gather the serializers in a schema's mark specs into an object. - */ - static marksFromSchema(schema) { - return gatherToDOM(schema.marks); - } - }; - function gatherToDOM(obj) { - let result = {}; - for (let name in obj) { - let toDOM = obj[name].spec.toDOM; - if (toDOM) - result[name] = toDOM; - } - return result; - } - function doc(options2) { - return options2.document || window.document; - } - - // node_modules/mdast-util-to-string/lib/index.js - var emptyOptions = {}; - function toString(value, options2) { - const settings = options2 || emptyOptions; - const includeImageAlt = typeof settings.includeImageAlt === "boolean" ? settings.includeImageAlt : true; - const includeHtml = typeof settings.includeHtml === "boolean" ? settings.includeHtml : true; - return one(value, includeImageAlt, includeHtml); - } - function one(value, includeImageAlt, includeHtml) { - if (node(value)) { - if ("value" in value) { - return value.type === "html" && !includeHtml ? "" : value.value; - } - if (includeImageAlt && "alt" in value && value.alt) { - return value.alt; - } - if ("children" in value) { - return all(value.children, includeImageAlt, includeHtml); - } - } - if (Array.isArray(value)) { - return all(value, includeImageAlt, includeHtml); - } - return ""; - } - function all(values, includeImageAlt, includeHtml) { - const result = []; - let index2 = -1; - while (++index2 < values.length) { - result[index2] = one(values[index2], includeImageAlt, includeHtml); - } - return result.join(""); - } - function node(value) { - return Boolean(value && typeof value === "object"); - } - - // node_modules/decode-named-character-reference/index.dom.js - var element = document.createElement("i"); - function decodeNamedCharacterReference(value) { - const characterReference2 = "&" + value + ";"; - element.innerHTML = characterReference2; - const char = element.textContent; - if (char.charCodeAt(char.length - 1) === 59 && value !== "semi") { - return false; - } - return char === characterReference2 ? false : char; - } - - // node_modules/micromark-util-chunked/index.js - function splice(list4, start, remove, items) { - const end = list4.length; - let chunkStart = 0; - let parameters; - if (start < 0) { - start = -start > end ? 0 : end + start; - } else { - start = start > end ? end : start; - } - remove = remove > 0 ? remove : 0; - if (items.length < 1e4) { - parameters = Array.from(items); - parameters.unshift(start, remove); - list4.splice(...parameters); - } else { - if (remove) list4.splice(start, remove); - while (chunkStart < items.length) { - parameters = items.slice(chunkStart, chunkStart + 1e4); - parameters.unshift(start, 0); - list4.splice(...parameters); - chunkStart += 1e4; - start += 1e4; - } - } - } - function push(list4, items) { - if (list4.length > 0) { - splice(list4, list4.length, 0, items); - return list4; - } - return items; - } - - // node_modules/micromark-util-combine-extensions/index.js - var hasOwnProperty = {}.hasOwnProperty; - function combineExtensions(extensions) { - const all2 = {}; - let index2 = -1; - while (++index2 < extensions.length) { - syntaxExtension(all2, extensions[index2]); - } - return all2; - } - function syntaxExtension(all2, extension2) { - let hook; - for (hook in extension2) { - const maybe = hasOwnProperty.call(all2, hook) ? all2[hook] : void 0; - const left = maybe || (all2[hook] = {}); - const right = extension2[hook]; - let code3; - if (right) { - for (code3 in right) { - if (!hasOwnProperty.call(left, code3)) left[code3] = []; - const value = right[code3]; - constructs( - // @ts-expect-error Looks like a list. - left[code3], - Array.isArray(value) ? value : value ? [value] : [] - ); - } - } - } - } - function constructs(existing, list4) { - let index2 = -1; - const before = []; - while (++index2 < list4.length) { - ; - (list4[index2].add === "after" ? existing : before).push(list4[index2]); - } - splice(existing, 0, 0, before); - } - - // node_modules/micromark-util-decode-numeric-character-reference/index.js - function decodeNumericCharacterReference(value, base2) { - const code3 = Number.parseInt(value, base2); - if ( - // C0 except for HT, LF, FF, CR, space. - code3 < 9 || code3 === 11 || code3 > 13 && code3 < 32 || // Control character (DEL) of C0, and C1 controls. - code3 > 126 && code3 < 160 || // Lone high surrogates and low surrogates. - code3 > 55295 && code3 < 57344 || // Noncharacters. - code3 > 64975 && code3 < 65008 || /* eslint-disable no-bitwise */ - (code3 & 65535) === 65535 || (code3 & 65535) === 65534 || /* eslint-enable no-bitwise */ - // Out of range - code3 > 1114111 - ) { - return "\uFFFD"; - } - return String.fromCodePoint(code3); - } - - // node_modules/micromark-util-normalize-identifier/index.js - function normalizeIdentifier(value) { - return value.replace(/[\t\n\r ]+/g, " ").replace(/^ | $/g, "").toLowerCase().toUpperCase(); - } - - // node_modules/micromark-util-character/index.js - var asciiAlpha = regexCheck(/[A-Za-z]/); - var asciiAlphanumeric = regexCheck(/[\dA-Za-z]/); - var asciiAtext = regexCheck(/[#-'*+\--9=?A-Z^-~]/); - function asciiControl(code3) { - return ( - // Special whitespace codes (which have negative values), C0 and Control - // character DEL - code3 !== null && (code3 < 32 || code3 === 127) - ); - } - var asciiDigit = regexCheck(/\d/); - var asciiHexDigit = regexCheck(/[\dA-Fa-f]/); - var asciiPunctuation = regexCheck(/[!-/:-@[-`{-~]/); - function markdownLineEnding(code3) { - return code3 !== null && code3 < -2; - } - function markdownLineEndingOrSpace(code3) { - return code3 !== null && (code3 < 0 || code3 === 32); - } - function markdownSpace(code3) { - return code3 === -2 || code3 === -1 || code3 === 32; - } - var unicodePunctuation = regexCheck(new RegExp("\\p{P}|\\p{S}", "u")); - var unicodeWhitespace = regexCheck(/\s/); - function regexCheck(regex) { - return check; - function check(code3) { - return code3 !== null && code3 > -1 && regex.test(String.fromCharCode(code3)); - } - } - - // node_modules/micromark-factory-space/index.js - function factorySpace(effects, ok3, type, max) { - const limit = max ? max - 1 : Number.POSITIVE_INFINITY; - let size = 0; - return start; - function start(code3) { - if (markdownSpace(code3)) { - effects.enter(type); - return prefix(code3); - } - return ok3(code3); - } - function prefix(code3) { - if (markdownSpace(code3) && size++ < limit) { - effects.consume(code3); - return prefix; - } - effects.exit(type); - return ok3(code3); - } - } - - // node_modules/micromark/lib/initialize/content.js - var content = { - tokenize: initializeContent - }; - function initializeContent(effects) { - const contentStart = effects.attempt( - this.parser.constructs.contentInitial, - afterContentStartConstruct, - paragraphInitial - ); - let previous3; - return contentStart; - function afterContentStartConstruct(code3) { - if (code3 === null) { - effects.consume(code3); - return; - } - effects.enter("lineEnding"); - effects.consume(code3); - effects.exit("lineEnding"); - return factorySpace(effects, contentStart, "linePrefix"); - } - function paragraphInitial(code3) { - effects.enter("paragraph"); - return lineStart(code3); - } - function lineStart(code3) { - const token = effects.enter("chunkText", { - contentType: "text", - previous: previous3 - }); - if (previous3) { - previous3.next = token; - } - previous3 = token; - return data(code3); - } - function data(code3) { - if (code3 === null) { - effects.exit("chunkText"); - effects.exit("paragraph"); - effects.consume(code3); - return; - } - if (markdownLineEnding(code3)) { - effects.consume(code3); - effects.exit("chunkText"); - return lineStart; - } - effects.consume(code3); - return data; - } - } - - // node_modules/micromark/lib/initialize/document.js - var document2 = { - tokenize: initializeDocument - }; - var containerConstruct = { - tokenize: tokenizeContainer - }; - function initializeDocument(effects) { - const self2 = this; - const stack = []; - let continued = 0; - let childFlow; - let childToken; - let lineStartOffset; - return start; - function start(code3) { - if (continued < stack.length) { - const item = stack[continued]; - self2.containerState = item[1]; - return effects.attempt( - item[0].continuation, - documentContinue, - checkNewContainers - )(code3); - } - return checkNewContainers(code3); - } - function documentContinue(code3) { - continued++; - if (self2.containerState._closeFlow) { - self2.containerState._closeFlow = void 0; - if (childFlow) { - closeFlow(); - } - const indexBeforeExits = self2.events.length; - let indexBeforeFlow = indexBeforeExits; - let point3; - while (indexBeforeFlow--) { - if (self2.events[indexBeforeFlow][0] === "exit" && self2.events[indexBeforeFlow][1].type === "chunkFlow") { - point3 = self2.events[indexBeforeFlow][1].end; - break; - } - } - exitContainers(continued); - let index2 = indexBeforeExits; - while (index2 < self2.events.length) { - self2.events[index2][1].end = Object.assign({}, point3); - index2++; - } - splice( - self2.events, - indexBeforeFlow + 1, - 0, - self2.events.slice(indexBeforeExits) - ); - self2.events.length = index2; - return checkNewContainers(code3); - } - return start(code3); - } - function checkNewContainers(code3) { - if (continued === stack.length) { - if (!childFlow) { - return documentContinued(code3); - } - if (childFlow.currentConstruct && childFlow.currentConstruct.concrete) { - return flowStart(code3); - } - self2.interrupt = Boolean( - childFlow.currentConstruct && !childFlow._gfmTableDynamicInterruptHack - ); - } - self2.containerState = {}; - return effects.check( - containerConstruct, - thereIsANewContainer, - thereIsNoNewContainer - )(code3); - } - function thereIsANewContainer(code3) { - if (childFlow) closeFlow(); - exitContainers(continued); - return documentContinued(code3); - } - function thereIsNoNewContainer(code3) { - self2.parser.lazy[self2.now().line] = continued !== stack.length; - lineStartOffset = self2.now().offset; - return flowStart(code3); - } - function documentContinued(code3) { - self2.containerState = {}; - return effects.attempt( - containerConstruct, - containerContinue, - flowStart - )(code3); - } - function containerContinue(code3) { - continued++; - stack.push([self2.currentConstruct, self2.containerState]); - return documentContinued(code3); - } - function flowStart(code3) { - if (code3 === null) { - if (childFlow) closeFlow(); - exitContainers(0); - effects.consume(code3); - return; - } - childFlow = childFlow || self2.parser.flow(self2.now()); - effects.enter("chunkFlow", { - contentType: "flow", - previous: childToken, - _tokenizer: childFlow - }); - return flowContinue(code3); - } - function flowContinue(code3) { - if (code3 === null) { - writeToChild(effects.exit("chunkFlow"), true); - exitContainers(0); - effects.consume(code3); - return; - } - if (markdownLineEnding(code3)) { - effects.consume(code3); - writeToChild(effects.exit("chunkFlow")); - continued = 0; - self2.interrupt = void 0; - return start; - } - effects.consume(code3); - return flowContinue; - } - function writeToChild(token, eof) { - const stream = self2.sliceStream(token); - if (eof) stream.push(null); - token.previous = childToken; - if (childToken) childToken.next = token; - childToken = token; - childFlow.defineSkip(token.start); - childFlow.write(stream); - if (self2.parser.lazy[token.start.line]) { - let index2 = childFlow.events.length; - while (index2--) { - if ( - // The token starts before the line ending… - childFlow.events[index2][1].start.offset < lineStartOffset && // …and either is not ended yet… - (!childFlow.events[index2][1].end || // …or ends after it. - childFlow.events[index2][1].end.offset > lineStartOffset) - ) { - return; - } - } - const indexBeforeExits = self2.events.length; - let indexBeforeFlow = indexBeforeExits; - let seen; - let point3; - while (indexBeforeFlow--) { - if (self2.events[indexBeforeFlow][0] === "exit" && self2.events[indexBeforeFlow][1].type === "chunkFlow") { - if (seen) { - point3 = self2.events[indexBeforeFlow][1].end; - break; - } - seen = true; - } - } - exitContainers(continued); - index2 = indexBeforeExits; - while (index2 < self2.events.length) { - self2.events[index2][1].end = Object.assign({}, point3); - index2++; - } - splice( - self2.events, - indexBeforeFlow + 1, - 0, - self2.events.slice(indexBeforeExits) - ); - self2.events.length = index2; - } - } - function exitContainers(size) { - let index2 = stack.length; - while (index2-- > size) { - const entry = stack[index2]; - self2.containerState = entry[1]; - entry[0].exit.call(self2, effects); - } - stack.length = size; - } - function closeFlow() { - childFlow.write([null]); - childToken = void 0; - childFlow = void 0; - self2.containerState._closeFlow = void 0; - } - } - function tokenizeContainer(effects, ok3, nok) { - return factorySpace( - effects, - effects.attempt(this.parser.constructs.document, ok3, nok), - "linePrefix", - this.parser.constructs.disable.null.includes("codeIndented") ? void 0 : 4 - ); - } - - // node_modules/micromark-util-classify-character/index.js - function classifyCharacter(code3) { - if (code3 === null || markdownLineEndingOrSpace(code3) || unicodeWhitespace(code3)) { - return 1; - } - if (unicodePunctuation(code3)) { - return 2; - } - } - - // node_modules/micromark-util-resolve-all/index.js - function resolveAll(constructs2, events, context) { - const called = []; - let index2 = -1; - while (++index2 < constructs2.length) { - const resolve = constructs2[index2].resolveAll; - if (resolve && !called.includes(resolve)) { - events = resolve(events, context); - called.push(resolve); - } - } - return events; - } - - // node_modules/micromark-core-commonmark/lib/attention.js - var attention = { - name: "attention", - tokenize: tokenizeAttention, - resolveAll: resolveAllAttention - }; - function resolveAllAttention(events, context) { - let index2 = -1; - let open; - let group; - let text5; - let openingSequence; - let closingSequence; - let use; - let nextEvents; - let offset; - while (++index2 < events.length) { - if (events[index2][0] === "enter" && events[index2][1].type === "attentionSequence" && events[index2][1]._close) { - open = index2; - while (open--) { - if (events[open][0] === "exit" && events[open][1].type === "attentionSequence" && events[open][1]._open && // If the markers are the same: - context.sliceSerialize(events[open][1]).charCodeAt(0) === context.sliceSerialize(events[index2][1]).charCodeAt(0)) { - if ((events[open][1]._close || events[index2][1]._open) && (events[index2][1].end.offset - events[index2][1].start.offset) % 3 && !((events[open][1].end.offset - events[open][1].start.offset + events[index2][1].end.offset - events[index2][1].start.offset) % 3)) { - continue; - } - use = events[open][1].end.offset - events[open][1].start.offset > 1 && events[index2][1].end.offset - events[index2][1].start.offset > 1 ? 2 : 1; - const start = Object.assign({}, events[open][1].end); - const end = Object.assign({}, events[index2][1].start); - movePoint(start, -use); - movePoint(end, use); - openingSequence = { - type: use > 1 ? "strongSequence" : "emphasisSequence", - start, - end: Object.assign({}, events[open][1].end) - }; - closingSequence = { - type: use > 1 ? "strongSequence" : "emphasisSequence", - start: Object.assign({}, events[index2][1].start), - end - }; - text5 = { - type: use > 1 ? "strongText" : "emphasisText", - start: Object.assign({}, events[open][1].end), - end: Object.assign({}, events[index2][1].start) - }; - group = { - type: use > 1 ? "strong" : "emphasis", - start: Object.assign({}, openingSequence.start), - end: Object.assign({}, closingSequence.end) - }; - events[open][1].end = Object.assign({}, openingSequence.start); - events[index2][1].start = Object.assign({}, closingSequence.end); - nextEvents = []; - if (events[open][1].end.offset - events[open][1].start.offset) { - nextEvents = push(nextEvents, [["enter", events[open][1], context], ["exit", events[open][1], context]]); - } - nextEvents = push(nextEvents, [["enter", group, context], ["enter", openingSequence, context], ["exit", openingSequence, context], ["enter", text5, context]]); - nextEvents = push(nextEvents, resolveAll(context.parser.constructs.insideSpan.null, events.slice(open + 1, index2), context)); - nextEvents = push(nextEvents, [["exit", text5, context], ["enter", closingSequence, context], ["exit", closingSequence, context], ["exit", group, context]]); - if (events[index2][1].end.offset - events[index2][1].start.offset) { - offset = 2; - nextEvents = push(nextEvents, [["enter", events[index2][1], context], ["exit", events[index2][1], context]]); - } else { - offset = 0; - } - splice(events, open - 1, index2 - open + 3, nextEvents); - index2 = open + nextEvents.length - offset - 2; - break; - } - } - } - } - index2 = -1; - while (++index2 < events.length) { - if (events[index2][1].type === "attentionSequence") { - events[index2][1].type = "data"; - } - } - return events; - } - function tokenizeAttention(effects, ok3) { - const attentionMarkers2 = this.parser.constructs.attentionMarkers.null; - const previous3 = this.previous; - const before = classifyCharacter(previous3); - let marker; - return start; - function start(code3) { - marker = code3; - effects.enter("attentionSequence"); - return inside(code3); - } - function inside(code3) { - if (code3 === marker) { - effects.consume(code3); - return inside; - } - const token = effects.exit("attentionSequence"); - const after = classifyCharacter(code3); - const open = !after || after === 2 && before || attentionMarkers2.includes(code3); - const close2 = !before || before === 2 && after || attentionMarkers2.includes(previous3); - token._open = Boolean(marker === 42 ? open : open && (before || !close2)); - token._close = Boolean(marker === 42 ? close2 : close2 && (after || !open)); - return ok3(code3); - } - } - function movePoint(point3, offset) { - point3.column += offset; - point3.offset += offset; - point3._bufferIndex += offset; - } - - // node_modules/micromark-core-commonmark/lib/autolink.js - var autolink = { - name: "autolink", - tokenize: tokenizeAutolink - }; - function tokenizeAutolink(effects, ok3, nok) { - let size = 0; - return start; - function start(code3) { - effects.enter("autolink"); - effects.enter("autolinkMarker"); - effects.consume(code3); - effects.exit("autolinkMarker"); - effects.enter("autolinkProtocol"); - return open; - } - function open(code3) { - if (asciiAlpha(code3)) { - effects.consume(code3); - return schemeOrEmailAtext; - } - if (code3 === 64) { - return nok(code3); - } - return emailAtext(code3); - } - function schemeOrEmailAtext(code3) { - if (code3 === 43 || code3 === 45 || code3 === 46 || asciiAlphanumeric(code3)) { - size = 1; - return schemeInsideOrEmailAtext(code3); - } - return emailAtext(code3); - } - function schemeInsideOrEmailAtext(code3) { - if (code3 === 58) { - effects.consume(code3); - size = 0; - return urlInside; - } - if ((code3 === 43 || code3 === 45 || code3 === 46 || asciiAlphanumeric(code3)) && size++ < 32) { - effects.consume(code3); - return schemeInsideOrEmailAtext; - } - size = 0; - return emailAtext(code3); - } - function urlInside(code3) { - if (code3 === 62) { - effects.exit("autolinkProtocol"); - effects.enter("autolinkMarker"); - effects.consume(code3); - effects.exit("autolinkMarker"); - effects.exit("autolink"); - return ok3; - } - if (code3 === null || code3 === 32 || code3 === 60 || asciiControl(code3)) { - return nok(code3); - } - effects.consume(code3); - return urlInside; - } - function emailAtext(code3) { - if (code3 === 64) { - effects.consume(code3); - return emailAtSignOrDot; - } - if (asciiAtext(code3)) { - effects.consume(code3); - return emailAtext; - } - return nok(code3); - } - function emailAtSignOrDot(code3) { - return asciiAlphanumeric(code3) ? emailLabel(code3) : nok(code3); - } - function emailLabel(code3) { - if (code3 === 46) { - effects.consume(code3); - size = 0; - return emailAtSignOrDot; - } - if (code3 === 62) { - effects.exit("autolinkProtocol").type = "autolinkEmail"; - effects.enter("autolinkMarker"); - effects.consume(code3); - effects.exit("autolinkMarker"); - effects.exit("autolink"); - return ok3; - } - return emailValue(code3); - } - function emailValue(code3) { - if ((code3 === 45 || asciiAlphanumeric(code3)) && size++ < 63) { - const next = code3 === 45 ? emailValue : emailLabel; - effects.consume(code3); - return next; - } - return nok(code3); - } - } - - // node_modules/micromark-core-commonmark/lib/blank-line.js - var blankLine = { - tokenize: tokenizeBlankLine, - partial: true - }; - function tokenizeBlankLine(effects, ok3, nok) { - return start; - function start(code3) { - return markdownSpace(code3) ? factorySpace(effects, after, "linePrefix")(code3) : after(code3); - } - function after(code3) { - return code3 === null || markdownLineEnding(code3) ? ok3(code3) : nok(code3); - } - } - - // node_modules/micromark-core-commonmark/lib/block-quote.js - var blockQuote = { - name: "blockQuote", - tokenize: tokenizeBlockQuoteStart, - continuation: { - tokenize: tokenizeBlockQuoteContinuation - }, - exit - }; - function tokenizeBlockQuoteStart(effects, ok3, nok) { - const self2 = this; - return start; - function start(code3) { - if (code3 === 62) { - const state = self2.containerState; - if (!state.open) { - effects.enter("blockQuote", { - _container: true - }); - state.open = true; - } - effects.enter("blockQuotePrefix"); - effects.enter("blockQuoteMarker"); - effects.consume(code3); - effects.exit("blockQuoteMarker"); - return after; - } - return nok(code3); - } - function after(code3) { - if (markdownSpace(code3)) { - effects.enter("blockQuotePrefixWhitespace"); - effects.consume(code3); - effects.exit("blockQuotePrefixWhitespace"); - effects.exit("blockQuotePrefix"); - return ok3; - } - effects.exit("blockQuotePrefix"); - return ok3(code3); - } - } - function tokenizeBlockQuoteContinuation(effects, ok3, nok) { - const self2 = this; - return contStart; - function contStart(code3) { - if (markdownSpace(code3)) { - return factorySpace(effects, contBefore, "linePrefix", self2.parser.constructs.disable.null.includes("codeIndented") ? void 0 : 4)(code3); - } - return contBefore(code3); - } - function contBefore(code3) { - return effects.attempt(blockQuote, ok3, nok)(code3); - } - } - function exit(effects) { - effects.exit("blockQuote"); - } - - // node_modules/micromark-core-commonmark/lib/character-escape.js - var characterEscape = { - name: "characterEscape", - tokenize: tokenizeCharacterEscape - }; - function tokenizeCharacterEscape(effects, ok3, nok) { - return start; - function start(code3) { - effects.enter("characterEscape"); - effects.enter("escapeMarker"); - effects.consume(code3); - effects.exit("escapeMarker"); - return inside; - } - function inside(code3) { - if (asciiPunctuation(code3)) { - effects.enter("characterEscapeValue"); - effects.consume(code3); - effects.exit("characterEscapeValue"); - effects.exit("characterEscape"); - return ok3; - } - return nok(code3); - } - } - - // node_modules/micromark-core-commonmark/lib/character-reference.js - var characterReference = { - name: "characterReference", - tokenize: tokenizeCharacterReference - }; - function tokenizeCharacterReference(effects, ok3, nok) { - const self2 = this; - let size = 0; - let max; - let test; - return start; - function start(code3) { - effects.enter("characterReference"); - effects.enter("characterReferenceMarker"); - effects.consume(code3); - effects.exit("characterReferenceMarker"); - return open; - } - function open(code3) { - if (code3 === 35) { - effects.enter("characterReferenceMarkerNumeric"); - effects.consume(code3); - effects.exit("characterReferenceMarkerNumeric"); - return numeric; - } - effects.enter("characterReferenceValue"); - max = 31; - test = asciiAlphanumeric; - return value(code3); - } - function numeric(code3) { - if (code3 === 88 || code3 === 120) { - effects.enter("characterReferenceMarkerHexadecimal"); - effects.consume(code3); - effects.exit("characterReferenceMarkerHexadecimal"); - effects.enter("characterReferenceValue"); - max = 6; - test = asciiHexDigit; - return value; - } - effects.enter("characterReferenceValue"); - max = 7; - test = asciiDigit; - return value(code3); - } - function value(code3) { - if (code3 === 59 && size) { - const token = effects.exit("characterReferenceValue"); - if (test === asciiAlphanumeric && !decodeNamedCharacterReference(self2.sliceSerialize(token))) { - return nok(code3); - } - effects.enter("characterReferenceMarker"); - effects.consume(code3); - effects.exit("characterReferenceMarker"); - effects.exit("characterReference"); - return ok3; - } - if (test(code3) && size++ < max) { - effects.consume(code3); - return value; - } - return nok(code3); - } - } - - // node_modules/micromark-core-commonmark/lib/code-fenced.js - var nonLazyContinuation = { - tokenize: tokenizeNonLazyContinuation, - partial: true - }; - var codeFenced = { - name: "codeFenced", - tokenize: tokenizeCodeFenced, - concrete: true - }; - function tokenizeCodeFenced(effects, ok3, nok) { - const self2 = this; - const closeStart = { - tokenize: tokenizeCloseStart, - partial: true - }; - let initialPrefix = 0; - let sizeOpen = 0; - let marker; - return start; - function start(code3) { - return beforeSequenceOpen(code3); - } - function beforeSequenceOpen(code3) { - const tail = self2.events[self2.events.length - 1]; - initialPrefix = tail && tail[1].type === "linePrefix" ? tail[2].sliceSerialize(tail[1], true).length : 0; - marker = code3; - effects.enter("codeFenced"); - effects.enter("codeFencedFence"); - effects.enter("codeFencedFenceSequence"); - return sequenceOpen(code3); - } - function sequenceOpen(code3) { - if (code3 === marker) { - sizeOpen++; - effects.consume(code3); - return sequenceOpen; - } - if (sizeOpen < 3) { - return nok(code3); - } - effects.exit("codeFencedFenceSequence"); - return markdownSpace(code3) ? factorySpace(effects, infoBefore, "whitespace")(code3) : infoBefore(code3); - } - function infoBefore(code3) { - if (code3 === null || markdownLineEnding(code3)) { - effects.exit("codeFencedFence"); - return self2.interrupt ? ok3(code3) : effects.check(nonLazyContinuation, atNonLazyBreak, after)(code3); - } - effects.enter("codeFencedFenceInfo"); - effects.enter("chunkString", { - contentType: "string" - }); - return info(code3); - } - function info(code3) { - if (code3 === null || markdownLineEnding(code3)) { - effects.exit("chunkString"); - effects.exit("codeFencedFenceInfo"); - return infoBefore(code3); - } - if (markdownSpace(code3)) { - effects.exit("chunkString"); - effects.exit("codeFencedFenceInfo"); - return factorySpace(effects, metaBefore, "whitespace")(code3); - } - if (code3 === 96 && code3 === marker) { - return nok(code3); - } - effects.consume(code3); - return info; - } - function metaBefore(code3) { - if (code3 === null || markdownLineEnding(code3)) { - return infoBefore(code3); - } - effects.enter("codeFencedFenceMeta"); - effects.enter("chunkString", { - contentType: "string" - }); - return meta(code3); - } - function meta(code3) { - if (code3 === null || markdownLineEnding(code3)) { - effects.exit("chunkString"); - effects.exit("codeFencedFenceMeta"); - return infoBefore(code3); - } - if (code3 === 96 && code3 === marker) { - return nok(code3); - } - effects.consume(code3); - return meta; - } - function atNonLazyBreak(code3) { - return effects.attempt(closeStart, after, contentBefore)(code3); - } - function contentBefore(code3) { - effects.enter("lineEnding"); - effects.consume(code3); - effects.exit("lineEnding"); - return contentStart; - } - function contentStart(code3) { - return initialPrefix > 0 && markdownSpace(code3) ? factorySpace(effects, beforeContentChunk, "linePrefix", initialPrefix + 1)(code3) : beforeContentChunk(code3); - } - function beforeContentChunk(code3) { - if (code3 === null || markdownLineEnding(code3)) { - return effects.check(nonLazyContinuation, atNonLazyBreak, after)(code3); - } - effects.enter("codeFlowValue"); - return contentChunk(code3); - } - function contentChunk(code3) { - if (code3 === null || markdownLineEnding(code3)) { - effects.exit("codeFlowValue"); - return beforeContentChunk(code3); - } - effects.consume(code3); - return contentChunk; - } - function after(code3) { - effects.exit("codeFenced"); - return ok3(code3); - } - function tokenizeCloseStart(effects2, ok4, nok2) { - let size = 0; - return startBefore; - function startBefore(code3) { - effects2.enter("lineEnding"); - effects2.consume(code3); - effects2.exit("lineEnding"); - return start2; - } - function start2(code3) { - effects2.enter("codeFencedFence"); - return markdownSpace(code3) ? factorySpace(effects2, beforeSequenceClose, "linePrefix", self2.parser.constructs.disable.null.includes("codeIndented") ? void 0 : 4)(code3) : beforeSequenceClose(code3); - } - function beforeSequenceClose(code3) { - if (code3 === marker) { - effects2.enter("codeFencedFenceSequence"); - return sequenceClose(code3); - } - return nok2(code3); - } - function sequenceClose(code3) { - if (code3 === marker) { - size++; - effects2.consume(code3); - return sequenceClose; - } - if (size >= sizeOpen) { - effects2.exit("codeFencedFenceSequence"); - return markdownSpace(code3) ? factorySpace(effects2, sequenceCloseAfter, "whitespace")(code3) : sequenceCloseAfter(code3); - } - return nok2(code3); - } - function sequenceCloseAfter(code3) { - if (code3 === null || markdownLineEnding(code3)) { - effects2.exit("codeFencedFence"); - return ok4(code3); - } - return nok2(code3); - } - } - } - function tokenizeNonLazyContinuation(effects, ok3, nok) { - const self2 = this; - return start; - function start(code3) { - if (code3 === null) { - return nok(code3); - } - effects.enter("lineEnding"); - effects.consume(code3); - effects.exit("lineEnding"); - return lineStart; - } - function lineStart(code3) { - return self2.parser.lazy[self2.now().line] ? nok(code3) : ok3(code3); - } - } - - // node_modules/micromark-core-commonmark/lib/code-indented.js - var codeIndented = { - name: "codeIndented", - tokenize: tokenizeCodeIndented - }; - var furtherStart = { - tokenize: tokenizeFurtherStart, - partial: true - }; - function tokenizeCodeIndented(effects, ok3, nok) { - const self2 = this; - return start; - function start(code3) { - effects.enter("codeIndented"); - return factorySpace(effects, afterPrefix, "linePrefix", 4 + 1)(code3); - } - function afterPrefix(code3) { - const tail = self2.events[self2.events.length - 1]; - return tail && tail[1].type === "linePrefix" && tail[2].sliceSerialize(tail[1], true).length >= 4 ? atBreak(code3) : nok(code3); - } - function atBreak(code3) { - if (code3 === null) { - return after(code3); - } - if (markdownLineEnding(code3)) { - return effects.attempt(furtherStart, atBreak, after)(code3); - } - effects.enter("codeFlowValue"); - return inside(code3); - } - function inside(code3) { - if (code3 === null || markdownLineEnding(code3)) { - effects.exit("codeFlowValue"); - return atBreak(code3); - } - effects.consume(code3); - return inside; - } - function after(code3) { - effects.exit("codeIndented"); - return ok3(code3); - } - } - function tokenizeFurtherStart(effects, ok3, nok) { - const self2 = this; - return furtherStart2; - function furtherStart2(code3) { - if (self2.parser.lazy[self2.now().line]) { - return nok(code3); - } - if (markdownLineEnding(code3)) { - effects.enter("lineEnding"); - effects.consume(code3); - effects.exit("lineEnding"); - return furtherStart2; - } - return factorySpace(effects, afterPrefix, "linePrefix", 4 + 1)(code3); - } - function afterPrefix(code3) { - const tail = self2.events[self2.events.length - 1]; - return tail && tail[1].type === "linePrefix" && tail[2].sliceSerialize(tail[1], true).length >= 4 ? ok3(code3) : markdownLineEnding(code3) ? furtherStart2(code3) : nok(code3); - } - } - - // node_modules/micromark-core-commonmark/lib/code-text.js - var codeText = { - name: "codeText", - tokenize: tokenizeCodeText, - resolve: resolveCodeText, - previous - }; - function resolveCodeText(events) { - let tailExitIndex = events.length - 4; - let headEnterIndex = 3; - let index2; - let enter; - if ((events[headEnterIndex][1].type === "lineEnding" || events[headEnterIndex][1].type === "space") && (events[tailExitIndex][1].type === "lineEnding" || events[tailExitIndex][1].type === "space")) { - index2 = headEnterIndex; - while (++index2 < tailExitIndex) { - if (events[index2][1].type === "codeTextData") { - events[headEnterIndex][1].type = "codeTextPadding"; - events[tailExitIndex][1].type = "codeTextPadding"; - headEnterIndex += 2; - tailExitIndex -= 2; - break; - } - } - } - index2 = headEnterIndex - 1; - tailExitIndex++; - while (++index2 <= tailExitIndex) { - if (enter === void 0) { - if (index2 !== tailExitIndex && events[index2][1].type !== "lineEnding") { - enter = index2; - } - } else if (index2 === tailExitIndex || events[index2][1].type === "lineEnding") { - events[enter][1].type = "codeTextData"; - if (index2 !== enter + 2) { - events[enter][1].end = events[index2 - 1][1].end; - events.splice(enter + 2, index2 - enter - 2); - tailExitIndex -= index2 - enter - 2; - index2 = enter + 2; - } - enter = void 0; - } - } - return events; - } - function previous(code3) { - return code3 !== 96 || this.events[this.events.length - 1][1].type === "characterEscape"; - } - function tokenizeCodeText(effects, ok3, nok) { - const self2 = this; - let sizeOpen = 0; - let size; - let token; - return start; - function start(code3) { - effects.enter("codeText"); - effects.enter("codeTextSequence"); - return sequenceOpen(code3); - } - function sequenceOpen(code3) { - if (code3 === 96) { - effects.consume(code3); - sizeOpen++; - return sequenceOpen; - } - effects.exit("codeTextSequence"); - return between2(code3); - } - function between2(code3) { - if (code3 === null) { - return nok(code3); - } - if (code3 === 32) { - effects.enter("space"); - effects.consume(code3); - effects.exit("space"); - return between2; - } - if (code3 === 96) { - token = effects.enter("codeTextSequence"); - size = 0; - return sequenceClose(code3); - } - if (markdownLineEnding(code3)) { - effects.enter("lineEnding"); - effects.consume(code3); - effects.exit("lineEnding"); - return between2; - } - effects.enter("codeTextData"); - return data(code3); - } - function data(code3) { - if (code3 === null || code3 === 32 || code3 === 96 || markdownLineEnding(code3)) { - effects.exit("codeTextData"); - return between2(code3); - } - effects.consume(code3); - return data; - } - function sequenceClose(code3) { - if (code3 === 96) { - effects.consume(code3); - size++; - return sequenceClose; - } - if (size === sizeOpen) { - effects.exit("codeTextSequence"); - effects.exit("codeText"); - return ok3(code3); - } - token.type = "codeTextData"; - return data(code3); - } - } - - // node_modules/micromark-util-subtokenize/lib/splice-buffer.js - var SpliceBuffer = class { - /** - * @param {ReadonlyArray | null | undefined} [initial] - * Initial items (optional). - * @returns - * Splice buffer. - */ - constructor(initial) { - this.left = initial ? [...initial] : []; - this.right = []; - } - /** - * Array access; - * does not move the cursor. - * - * @param {number} index - * Index. - * @return {T} - * Item. - */ - get(index2) { - if (index2 < 0 || index2 >= this.left.length + this.right.length) { - throw new RangeError("Cannot access index `" + index2 + "` in a splice buffer of size `" + (this.left.length + this.right.length) + "`"); - } - if (index2 < this.left.length) return this.left[index2]; - return this.right[this.right.length - index2 + this.left.length - 1]; - } - /** - * The length of the splice buffer, one greater than the largest index in the - * array. - */ - get length() { - return this.left.length + this.right.length; - } - /** - * Remove and return `list[0]`; - * moves the cursor to `0`. - * - * @returns {T | undefined} - * Item, optional. - */ - shift() { - this.setCursor(0); - return this.right.pop(); - } - /** - * Slice the buffer to get an array; - * does not move the cursor. - * - * @param {number} start - * Start. - * @param {number | null | undefined} [end] - * End (optional). - * @returns {Array} - * Array of items. - */ - slice(start, end) { - const stop = end === null || end === void 0 ? Number.POSITIVE_INFINITY : end; - if (stop < this.left.length) { - return this.left.slice(start, stop); - } - if (start > this.left.length) { - return this.right.slice(this.right.length - stop + this.left.length, this.right.length - start + this.left.length).reverse(); - } - return this.left.slice(start).concat(this.right.slice(this.right.length - stop + this.left.length).reverse()); - } - /** - * Mimics the behavior of Array.prototype.splice() except for the change of - * interface necessary to avoid segfaults when patching in very large arrays. - * - * This operation moves cursor is moved to `start` and results in the cursor - * placed after any inserted items. - * - * @param {number} start - * Start; - * zero-based index at which to start changing the array; - * negative numbers count backwards from the end of the array and values - * that are out-of bounds are clamped to the appropriate end of the array. - * @param {number | null | undefined} [deleteCount=0] - * Delete count (default: `0`); - * maximum number of elements to delete, starting from start. - * @param {Array | null | undefined} [items=[]] - * Items to include in place of the deleted items (default: `[]`). - * @return {Array} - * Any removed items. - */ - splice(start, deleteCount, items) { - const count = deleteCount || 0; - this.setCursor(Math.trunc(start)); - const removed = this.right.splice(this.right.length - count, Number.POSITIVE_INFINITY); - if (items) chunkedPush(this.left, items); - return removed.reverse(); - } - /** - * Remove and return the highest-numbered item in the array, so - * `list[list.length - 1]`; - * Moves the cursor to `length`. - * - * @returns {T | undefined} - * Item, optional. - */ - pop() { - this.setCursor(Number.POSITIVE_INFINITY); - return this.left.pop(); - } - /** - * Inserts a single item to the high-numbered side of the array; - * moves the cursor to `length`. - * - * @param {T} item - * Item. - * @returns {undefined} - * Nothing. - */ - push(item) { - this.setCursor(Number.POSITIVE_INFINITY); - this.left.push(item); - } - /** - * Inserts many items to the high-numbered side of the array. - * Moves the cursor to `length`. - * - * @param {Array} items - * Items. - * @returns {undefined} - * Nothing. - */ - pushMany(items) { - this.setCursor(Number.POSITIVE_INFINITY); - chunkedPush(this.left, items); - } - /** - * Inserts a single item to the low-numbered side of the array; - * Moves the cursor to `0`. - * - * @param {T} item - * Item. - * @returns {undefined} - * Nothing. - */ - unshift(item) { - this.setCursor(0); - this.right.push(item); - } - /** - * Inserts many items to the low-numbered side of the array; - * moves the cursor to `0`. - * - * @param {Array} items - * Items. - * @returns {undefined} - * Nothing. - */ - unshiftMany(items) { - this.setCursor(0); - chunkedPush(this.right, items.reverse()); - } - /** - * Move the cursor to a specific position in the array. Requires - * time proportional to the distance moved. - * - * If `n < 0`, the cursor will end up at the beginning. - * If `n > length`, the cursor will end up at the end. - * - * @param {number} n - * Position. - * @return {undefined} - * Nothing. - */ - setCursor(n4) { - if (n4 === this.left.length || n4 > this.left.length && this.right.length === 0 || n4 < 0 && this.left.length === 0) return; - if (n4 < this.left.length) { - const removed = this.left.splice(n4, Number.POSITIVE_INFINITY); - chunkedPush(this.right, removed.reverse()); - } else { - const removed = this.right.splice(this.left.length + this.right.length - n4, Number.POSITIVE_INFINITY); - chunkedPush(this.left, removed.reverse()); - } - } - }; - function chunkedPush(list4, right) { - let chunkStart = 0; - if (right.length < 1e4) { - list4.push(...right); - } else { - while (chunkStart < right.length) { - list4.push(...right.slice(chunkStart, chunkStart + 1e4)); - chunkStart += 1e4; - } - } - } - - // node_modules/micromark-util-subtokenize/index.js - function subtokenize(eventsArray) { - const jumps = {}; - let index2 = -1; - let event; - let lineIndex; - let otherIndex; - let otherEvent; - let parameters; - let subevents; - let more; - const events = new SpliceBuffer(eventsArray); - while (++index2 < events.length) { - while (index2 in jumps) { - index2 = jumps[index2]; - } - event = events.get(index2); - if (index2 && event[1].type === "chunkFlow" && events.get(index2 - 1)[1].type === "listItemPrefix") { - subevents = event[1]._tokenizer.events; - otherIndex = 0; - if (otherIndex < subevents.length && subevents[otherIndex][1].type === "lineEndingBlank") { - otherIndex += 2; - } - if (otherIndex < subevents.length && subevents[otherIndex][1].type === "content") { - while (++otherIndex < subevents.length) { - if (subevents[otherIndex][1].type === "content") { - break; - } - if (subevents[otherIndex][1].type === "chunkText") { - subevents[otherIndex][1]._isInFirstContentOfListItem = true; - otherIndex++; - } - } - } - } - if (event[0] === "enter") { - if (event[1].contentType) { - Object.assign(jumps, subcontent(events, index2)); - index2 = jumps[index2]; - more = true; - } - } else if (event[1]._container) { - otherIndex = index2; - lineIndex = void 0; - while (otherIndex--) { - otherEvent = events.get(otherIndex); - if (otherEvent[1].type === "lineEnding" || otherEvent[1].type === "lineEndingBlank") { - if (otherEvent[0] === "enter") { - if (lineIndex) { - events.get(lineIndex)[1].type = "lineEndingBlank"; - } - otherEvent[1].type = "lineEnding"; - lineIndex = otherIndex; - } - } else { - break; - } - } - if (lineIndex) { - event[1].end = Object.assign({}, events.get(lineIndex)[1].start); - parameters = events.slice(lineIndex, index2); - parameters.unshift(event); - events.splice(lineIndex, index2 - lineIndex + 1, parameters); - } - } - } - splice(eventsArray, 0, Number.POSITIVE_INFINITY, events.slice(0)); - return !more; - } - function subcontent(events, eventIndex) { - const token = events.get(eventIndex)[1]; - const context = events.get(eventIndex)[2]; - let startPosition = eventIndex - 1; - const startPositions = []; - const tokenizer = token._tokenizer || context.parser[token.contentType](token.start); - const childEvents = tokenizer.events; - const jumps = []; - const gaps = {}; - let stream; - let previous3; - let index2 = -1; - let current = token; - let adjust = 0; - let start = 0; - const breaks = [start]; - while (current) { - while (events.get(++startPosition)[1] !== current) { - } - startPositions.push(startPosition); - if (!current._tokenizer) { - stream = context.sliceStream(current); - if (!current.next) { - stream.push(null); - } - if (previous3) { - tokenizer.defineSkip(current.start); - } - if (current._isInFirstContentOfListItem) { - tokenizer._gfmTasklistFirstContentOfListItem = true; - } - tokenizer.write(stream); - if (current._isInFirstContentOfListItem) { - tokenizer._gfmTasklistFirstContentOfListItem = void 0; - } - } - previous3 = current; - current = current.next; - } - current = token; - while (++index2 < childEvents.length) { - if ( - // Find a void token that includes a break. - childEvents[index2][0] === "exit" && childEvents[index2 - 1][0] === "enter" && childEvents[index2][1].type === childEvents[index2 - 1][1].type && childEvents[index2][1].start.line !== childEvents[index2][1].end.line - ) { - start = index2 + 1; - breaks.push(start); - current._tokenizer = void 0; - current.previous = void 0; - current = current.next; - } - } - tokenizer.events = []; - if (current) { - current._tokenizer = void 0; - current.previous = void 0; - } else { - breaks.pop(); - } - index2 = breaks.length; - while (index2--) { - const slice = childEvents.slice(breaks[index2], breaks[index2 + 1]); - const start2 = startPositions.pop(); - jumps.push([start2, start2 + slice.length - 1]); - events.splice(start2, 2, slice); - } - jumps.reverse(); - index2 = -1; - while (++index2 < jumps.length) { - gaps[adjust + jumps[index2][0]] = adjust + jumps[index2][1]; - adjust += jumps[index2][1] - jumps[index2][0] - 1; - } - return gaps; - } - - // node_modules/micromark-core-commonmark/lib/content.js - var content2 = { - tokenize: tokenizeContent, - resolve: resolveContent - }; - var continuationConstruct = { - tokenize: tokenizeContinuation, - partial: true - }; - function resolveContent(events) { - subtokenize(events); - return events; - } - function tokenizeContent(effects, ok3) { - let previous3; - return chunkStart; - function chunkStart(code3) { - effects.enter("content"); - previous3 = effects.enter("chunkContent", { - contentType: "content" - }); - return chunkInside(code3); - } - function chunkInside(code3) { - if (code3 === null) { - return contentEnd(code3); - } - if (markdownLineEnding(code3)) { - return effects.check(continuationConstruct, contentContinue, contentEnd)(code3); - } - effects.consume(code3); - return chunkInside; - } - function contentEnd(code3) { - effects.exit("chunkContent"); - effects.exit("content"); - return ok3(code3); - } - function contentContinue(code3) { - effects.consume(code3); - effects.exit("chunkContent"); - previous3.next = effects.enter("chunkContent", { - contentType: "content", - previous: previous3 - }); - previous3 = previous3.next; - return chunkInside; - } - } - function tokenizeContinuation(effects, ok3, nok) { - const self2 = this; - return startLookahead; - function startLookahead(code3) { - effects.exit("chunkContent"); - effects.enter("lineEnding"); - effects.consume(code3); - effects.exit("lineEnding"); - return factorySpace(effects, prefixed, "linePrefix"); - } - function prefixed(code3) { - if (code3 === null || markdownLineEnding(code3)) { - return nok(code3); - } - const tail = self2.events[self2.events.length - 1]; - if (!self2.parser.constructs.disable.null.includes("codeIndented") && tail && tail[1].type === "linePrefix" && tail[2].sliceSerialize(tail[1], true).length >= 4) { - return ok3(code3); - } - return effects.interrupt(self2.parser.constructs.flow, nok, ok3)(code3); - } - } - - // node_modules/micromark-factory-destination/index.js - function factoryDestination(effects, ok3, nok, type, literalType, literalMarkerType, rawType, stringType, max) { - const limit = max || Number.POSITIVE_INFINITY; - let balance = 0; - return start; - function start(code3) { - if (code3 === 60) { - effects.enter(type); - effects.enter(literalType); - effects.enter(literalMarkerType); - effects.consume(code3); - effects.exit(literalMarkerType); - return enclosedBefore; - } - if (code3 === null || code3 === 32 || code3 === 41 || asciiControl(code3)) { - return nok(code3); - } - effects.enter(type); - effects.enter(rawType); - effects.enter(stringType); - effects.enter("chunkString", { - contentType: "string" - }); - return raw(code3); - } - function enclosedBefore(code3) { - if (code3 === 62) { - effects.enter(literalMarkerType); - effects.consume(code3); - effects.exit(literalMarkerType); - effects.exit(literalType); - effects.exit(type); - return ok3; - } - effects.enter(stringType); - effects.enter("chunkString", { - contentType: "string" - }); - return enclosed(code3); - } - function enclosed(code3) { - if (code3 === 62) { - effects.exit("chunkString"); - effects.exit(stringType); - return enclosedBefore(code3); - } - if (code3 === null || code3 === 60 || markdownLineEnding(code3)) { - return nok(code3); - } - effects.consume(code3); - return code3 === 92 ? enclosedEscape : enclosed; - } - function enclosedEscape(code3) { - if (code3 === 60 || code3 === 62 || code3 === 92) { - effects.consume(code3); - return enclosed; - } - return enclosed(code3); - } - function raw(code3) { - if (!balance && (code3 === null || code3 === 41 || markdownLineEndingOrSpace(code3))) { - effects.exit("chunkString"); - effects.exit(stringType); - effects.exit(rawType); - effects.exit(type); - return ok3(code3); - } - if (balance < limit && code3 === 40) { - effects.consume(code3); - balance++; - return raw; - } - if (code3 === 41) { - effects.consume(code3); - balance--; - return raw; - } - if (code3 === null || code3 === 32 || code3 === 40 || asciiControl(code3)) { - return nok(code3); - } - effects.consume(code3); - return code3 === 92 ? rawEscape : raw; - } - function rawEscape(code3) { - if (code3 === 40 || code3 === 41 || code3 === 92) { - effects.consume(code3); - return raw; - } - return raw(code3); - } - } - - // node_modules/micromark-factory-label/index.js - function factoryLabel(effects, ok3, nok, type, markerType, stringType) { - const self2 = this; - let size = 0; - let seen; - return start; - function start(code3) { - effects.enter(type); - effects.enter(markerType); - effects.consume(code3); - effects.exit(markerType); - effects.enter(stringType); - return atBreak; - } - function atBreak(code3) { - if (size > 999 || code3 === null || code3 === 91 || code3 === 93 && !seen || // To do: remove in the future once we’ve switched from - // `micromark-extension-footnote` to `micromark-extension-gfm-footnote`, - // which doesn’t need this. - // Hidden footnotes hook. - /* c8 ignore next 3 */ - code3 === 94 && !size && "_hiddenFootnoteSupport" in self2.parser.constructs) { - return nok(code3); - } - if (code3 === 93) { - effects.exit(stringType); - effects.enter(markerType); - effects.consume(code3); - effects.exit(markerType); - effects.exit(type); - return ok3; - } - if (markdownLineEnding(code3)) { - effects.enter("lineEnding"); - effects.consume(code3); - effects.exit("lineEnding"); - return atBreak; - } - effects.enter("chunkString", { - contentType: "string" - }); - return labelInside(code3); - } - function labelInside(code3) { - if (code3 === null || code3 === 91 || code3 === 93 || markdownLineEnding(code3) || size++ > 999) { - effects.exit("chunkString"); - return atBreak(code3); - } - effects.consume(code3); - if (!seen) seen = !markdownSpace(code3); - return code3 === 92 ? labelEscape : labelInside; - } - function labelEscape(code3) { - if (code3 === 91 || code3 === 92 || code3 === 93) { - effects.consume(code3); - size++; - return labelInside; - } - return labelInside(code3); - } - } - - // node_modules/micromark-factory-title/index.js - function factoryTitle(effects, ok3, nok, type, markerType, stringType) { - let marker; - return start; - function start(code3) { - if (code3 === 34 || code3 === 39 || code3 === 40) { - effects.enter(type); - effects.enter(markerType); - effects.consume(code3); - effects.exit(markerType); - marker = code3 === 40 ? 41 : code3; - return begin; - } - return nok(code3); - } - function begin(code3) { - if (code3 === marker) { - effects.enter(markerType); - effects.consume(code3); - effects.exit(markerType); - effects.exit(type); - return ok3; - } - effects.enter(stringType); - return atBreak(code3); - } - function atBreak(code3) { - if (code3 === marker) { - effects.exit(stringType); - return begin(marker); - } - if (code3 === null) { - return nok(code3); - } - if (markdownLineEnding(code3)) { - effects.enter("lineEnding"); - effects.consume(code3); - effects.exit("lineEnding"); - return factorySpace(effects, atBreak, "linePrefix"); - } - effects.enter("chunkString", { - contentType: "string" - }); - return inside(code3); - } - function inside(code3) { - if (code3 === marker || code3 === null || markdownLineEnding(code3)) { - effects.exit("chunkString"); - return atBreak(code3); - } - effects.consume(code3); - return code3 === 92 ? escape : inside; - } - function escape(code3) { - if (code3 === marker || code3 === 92) { - effects.consume(code3); - return inside; - } - return inside(code3); - } - } - - // node_modules/micromark-factory-whitespace/index.js - function factoryWhitespace(effects, ok3) { - let seen; - return start; - function start(code3) { - if (markdownLineEnding(code3)) { - effects.enter("lineEnding"); - effects.consume(code3); - effects.exit("lineEnding"); - seen = true; - return start; - } - if (markdownSpace(code3)) { - return factorySpace( - effects, - start, - seen ? "linePrefix" : "lineSuffix" - )(code3); - } - return ok3(code3); - } - } - - // node_modules/micromark-core-commonmark/lib/definition.js - var definition = { - name: "definition", - tokenize: tokenizeDefinition - }; - var titleBefore = { - tokenize: tokenizeTitleBefore, - partial: true - }; - function tokenizeDefinition(effects, ok3, nok) { - const self2 = this; - let identifier; - return start; - function start(code3) { - effects.enter("definition"); - return before(code3); - } - function before(code3) { - return factoryLabel.call( - self2, - effects, - labelAfter, - // Note: we don’t need to reset the way `markdown-rs` does. - nok, - "definitionLabel", - "definitionLabelMarker", - "definitionLabelString" - )(code3); - } - function labelAfter(code3) { - identifier = normalizeIdentifier(self2.sliceSerialize(self2.events[self2.events.length - 1][1]).slice(1, -1)); - if (code3 === 58) { - effects.enter("definitionMarker"); - effects.consume(code3); - effects.exit("definitionMarker"); - return markerAfter; - } - return nok(code3); - } - function markerAfter(code3) { - return markdownLineEndingOrSpace(code3) ? factoryWhitespace(effects, destinationBefore)(code3) : destinationBefore(code3); - } - function destinationBefore(code3) { - return factoryDestination( - effects, - destinationAfter, - // Note: we don’t need to reset the way `markdown-rs` does. - nok, - "definitionDestination", - "definitionDestinationLiteral", - "definitionDestinationLiteralMarker", - "definitionDestinationRaw", - "definitionDestinationString" - )(code3); - } - function destinationAfter(code3) { - return effects.attempt(titleBefore, after, after)(code3); - } - function after(code3) { - return markdownSpace(code3) ? factorySpace(effects, afterWhitespace, "whitespace")(code3) : afterWhitespace(code3); - } - function afterWhitespace(code3) { - if (code3 === null || markdownLineEnding(code3)) { - effects.exit("definition"); - self2.parser.defined.push(identifier); - return ok3(code3); - } - return nok(code3); - } - } - function tokenizeTitleBefore(effects, ok3, nok) { - return titleBefore2; - function titleBefore2(code3) { - return markdownLineEndingOrSpace(code3) ? factoryWhitespace(effects, beforeMarker)(code3) : nok(code3); - } - function beforeMarker(code3) { - return factoryTitle(effects, titleAfter, nok, "definitionTitle", "definitionTitleMarker", "definitionTitleString")(code3); - } - function titleAfter(code3) { - return markdownSpace(code3) ? factorySpace(effects, titleAfterOptionalWhitespace, "whitespace")(code3) : titleAfterOptionalWhitespace(code3); - } - function titleAfterOptionalWhitespace(code3) { - return code3 === null || markdownLineEnding(code3) ? ok3(code3) : nok(code3); - } - } - - // node_modules/micromark-core-commonmark/lib/hard-break-escape.js - var hardBreakEscape = { - name: "hardBreakEscape", - tokenize: tokenizeHardBreakEscape - }; - function tokenizeHardBreakEscape(effects, ok3, nok) { - return start; - function start(code3) { - effects.enter("hardBreakEscape"); - effects.consume(code3); - return after; - } - function after(code3) { - if (markdownLineEnding(code3)) { - effects.exit("hardBreakEscape"); - return ok3(code3); - } - return nok(code3); - } - } - - // node_modules/micromark-core-commonmark/lib/heading-atx.js - var headingAtx = { - name: "headingAtx", - tokenize: tokenizeHeadingAtx, - resolve: resolveHeadingAtx - }; - function resolveHeadingAtx(events, context) { - let contentEnd = events.length - 2; - let contentStart = 3; - let content3; - let text5; - if (events[contentStart][1].type === "whitespace") { - contentStart += 2; - } - if (contentEnd - 2 > contentStart && events[contentEnd][1].type === "whitespace") { - contentEnd -= 2; - } - if (events[contentEnd][1].type === "atxHeadingSequence" && (contentStart === contentEnd - 1 || contentEnd - 4 > contentStart && events[contentEnd - 2][1].type === "whitespace")) { - contentEnd -= contentStart + 1 === contentEnd ? 2 : 4; - } - if (contentEnd > contentStart) { - content3 = { - type: "atxHeadingText", - start: events[contentStart][1].start, - end: events[contentEnd][1].end - }; - text5 = { - type: "chunkText", - start: events[contentStart][1].start, - end: events[contentEnd][1].end, - contentType: "text" - }; - splice(events, contentStart, contentEnd - contentStart + 1, [["enter", content3, context], ["enter", text5, context], ["exit", text5, context], ["exit", content3, context]]); - } - return events; - } - function tokenizeHeadingAtx(effects, ok3, nok) { - let size = 0; - return start; - function start(code3) { - effects.enter("atxHeading"); - return before(code3); - } - function before(code3) { - effects.enter("atxHeadingSequence"); - return sequenceOpen(code3); - } - function sequenceOpen(code3) { - if (code3 === 35 && size++ < 6) { - effects.consume(code3); - return sequenceOpen; - } - if (code3 === null || markdownLineEndingOrSpace(code3)) { - effects.exit("atxHeadingSequence"); - return atBreak(code3); - } - return nok(code3); - } - function atBreak(code3) { - if (code3 === 35) { - effects.enter("atxHeadingSequence"); - return sequenceFurther(code3); - } - if (code3 === null || markdownLineEnding(code3)) { - effects.exit("atxHeading"); - return ok3(code3); - } - if (markdownSpace(code3)) { - return factorySpace(effects, atBreak, "whitespace")(code3); - } - effects.enter("atxHeadingText"); - return data(code3); - } - function sequenceFurther(code3) { - if (code3 === 35) { - effects.consume(code3); - return sequenceFurther; - } - effects.exit("atxHeadingSequence"); - return atBreak(code3); - } - function data(code3) { - if (code3 === null || code3 === 35 || markdownLineEndingOrSpace(code3)) { - effects.exit("atxHeadingText"); - return atBreak(code3); - } - effects.consume(code3); - return data; - } - } - - // node_modules/micromark-util-html-tag-name/index.js - var htmlBlockNames = [ - "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", - "h1", - "h2", - "h3", - "h4", - "h5", - "h6", - "head", - "header", - "hr", - "html", - "iframe", - "legend", - "li", - "link", - "main", - "menu", - "menuitem", - "nav", - "noframes", - "ol", - "optgroup", - "option", - "p", - "param", - "search", - "section", - "summary", - "table", - "tbody", - "td", - "tfoot", - "th", - "thead", - "title", - "tr", - "track", - "ul" - ]; - var htmlRawNames = ["pre", "script", "style", "textarea"]; - - // node_modules/micromark-core-commonmark/lib/html-flow.js - var htmlFlow = { - name: "htmlFlow", - tokenize: tokenizeHtmlFlow, - resolveTo: resolveToHtmlFlow, - concrete: true - }; - var blankLineBefore = { - tokenize: tokenizeBlankLineBefore, - partial: true - }; - var nonLazyContinuationStart = { - tokenize: tokenizeNonLazyContinuationStart, - partial: true - }; - function resolveToHtmlFlow(events) { - let index2 = events.length; - while (index2--) { - if (events[index2][0] === "enter" && events[index2][1].type === "htmlFlow") { - break; - } - } - if (index2 > 1 && events[index2 - 2][1].type === "linePrefix") { - events[index2][1].start = events[index2 - 2][1].start; - events[index2 + 1][1].start = events[index2 - 2][1].start; - events.splice(index2 - 2, 2); - } - return events; - } - function tokenizeHtmlFlow(effects, ok3, nok) { - const self2 = this; - let marker; - let closingTag; - let buffer; - let index2; - let markerB; - return start; - function start(code3) { - return before(code3); - } - function before(code3) { - effects.enter("htmlFlow"); - effects.enter("htmlFlowData"); - effects.consume(code3); - return open; - } - function open(code3) { - if (code3 === 33) { - effects.consume(code3); - return declarationOpen; - } - if (code3 === 47) { - effects.consume(code3); - closingTag = true; - return tagCloseStart; - } - if (code3 === 63) { - effects.consume(code3); - marker = 3; - return self2.interrupt ? ok3 : continuationDeclarationInside; - } - if (asciiAlpha(code3)) { - effects.consume(code3); - buffer = String.fromCharCode(code3); - return tagName; - } - return nok(code3); - } - function declarationOpen(code3) { - if (code3 === 45) { - effects.consume(code3); - marker = 2; - return commentOpenInside; - } - if (code3 === 91) { - effects.consume(code3); - marker = 5; - index2 = 0; - return cdataOpenInside; - } - if (asciiAlpha(code3)) { - effects.consume(code3); - marker = 4; - return self2.interrupt ? ok3 : continuationDeclarationInside; - } - return nok(code3); - } - function commentOpenInside(code3) { - if (code3 === 45) { - effects.consume(code3); - return self2.interrupt ? ok3 : continuationDeclarationInside; - } - return nok(code3); - } - function cdataOpenInside(code3) { - const value = "CDATA["; - if (code3 === value.charCodeAt(index2++)) { - effects.consume(code3); - if (index2 === value.length) { - return self2.interrupt ? ok3 : continuation; - } - return cdataOpenInside; - } - return nok(code3); - } - function tagCloseStart(code3) { - if (asciiAlpha(code3)) { - effects.consume(code3); - buffer = String.fromCharCode(code3); - return tagName; - } - return nok(code3); - } - function tagName(code3) { - if (code3 === null || code3 === 47 || code3 === 62 || markdownLineEndingOrSpace(code3)) { - const slash = code3 === 47; - const name = buffer.toLowerCase(); - if (!slash && !closingTag && htmlRawNames.includes(name)) { - marker = 1; - return self2.interrupt ? ok3(code3) : continuation(code3); - } - if (htmlBlockNames.includes(buffer.toLowerCase())) { - marker = 6; - if (slash) { - effects.consume(code3); - return basicSelfClosing; - } - return self2.interrupt ? ok3(code3) : continuation(code3); - } - marker = 7; - return self2.interrupt && !self2.parser.lazy[self2.now().line] ? nok(code3) : closingTag ? completeClosingTagAfter(code3) : completeAttributeNameBefore(code3); - } - if (code3 === 45 || asciiAlphanumeric(code3)) { - effects.consume(code3); - buffer += String.fromCharCode(code3); - return tagName; - } - return nok(code3); - } - function basicSelfClosing(code3) { - if (code3 === 62) { - effects.consume(code3); - return self2.interrupt ? ok3 : continuation; - } - return nok(code3); - } - function completeClosingTagAfter(code3) { - if (markdownSpace(code3)) { - effects.consume(code3); - return completeClosingTagAfter; - } - return completeEnd(code3); - } - function completeAttributeNameBefore(code3) { - if (code3 === 47) { - effects.consume(code3); - return completeEnd; - } - if (code3 === 58 || code3 === 95 || asciiAlpha(code3)) { - effects.consume(code3); - return completeAttributeName; - } - if (markdownSpace(code3)) { - effects.consume(code3); - return completeAttributeNameBefore; - } - return completeEnd(code3); - } - function completeAttributeName(code3) { - if (code3 === 45 || code3 === 46 || code3 === 58 || code3 === 95 || asciiAlphanumeric(code3)) { - effects.consume(code3); - return completeAttributeName; - } - return completeAttributeNameAfter(code3); - } - function completeAttributeNameAfter(code3) { - if (code3 === 61) { - effects.consume(code3); - return completeAttributeValueBefore; - } - if (markdownSpace(code3)) { - effects.consume(code3); - return completeAttributeNameAfter; - } - return completeAttributeNameBefore(code3); - } - function completeAttributeValueBefore(code3) { - if (code3 === null || code3 === 60 || code3 === 61 || code3 === 62 || code3 === 96) { - return nok(code3); - } - if (code3 === 34 || code3 === 39) { - effects.consume(code3); - markerB = code3; - return completeAttributeValueQuoted; - } - if (markdownSpace(code3)) { - effects.consume(code3); - return completeAttributeValueBefore; - } - return completeAttributeValueUnquoted(code3); - } - function completeAttributeValueQuoted(code3) { - if (code3 === markerB) { - effects.consume(code3); - markerB = null; - return completeAttributeValueQuotedAfter; - } - if (code3 === null || markdownLineEnding(code3)) { - return nok(code3); - } - effects.consume(code3); - return completeAttributeValueQuoted; - } - function completeAttributeValueUnquoted(code3) { - if (code3 === null || code3 === 34 || code3 === 39 || code3 === 47 || code3 === 60 || code3 === 61 || code3 === 62 || code3 === 96 || markdownLineEndingOrSpace(code3)) { - return completeAttributeNameAfter(code3); - } - effects.consume(code3); - return completeAttributeValueUnquoted; - } - function completeAttributeValueQuotedAfter(code3) { - if (code3 === 47 || code3 === 62 || markdownSpace(code3)) { - return completeAttributeNameBefore(code3); - } - return nok(code3); - } - function completeEnd(code3) { - if (code3 === 62) { - effects.consume(code3); - return completeAfter; - } - return nok(code3); - } - function completeAfter(code3) { - if (code3 === null || markdownLineEnding(code3)) { - return continuation(code3); - } - if (markdownSpace(code3)) { - effects.consume(code3); - return completeAfter; - } - return nok(code3); - } - function continuation(code3) { - if (code3 === 45 && marker === 2) { - effects.consume(code3); - return continuationCommentInside; - } - if (code3 === 60 && marker === 1) { - effects.consume(code3); - return continuationRawTagOpen; - } - if (code3 === 62 && marker === 4) { - effects.consume(code3); - return continuationClose; - } - if (code3 === 63 && marker === 3) { - effects.consume(code3); - return continuationDeclarationInside; - } - if (code3 === 93 && marker === 5) { - effects.consume(code3); - return continuationCdataInside; - } - if (markdownLineEnding(code3) && (marker === 6 || marker === 7)) { - effects.exit("htmlFlowData"); - return effects.check(blankLineBefore, continuationAfter, continuationStart)(code3); - } - if (code3 === null || markdownLineEnding(code3)) { - effects.exit("htmlFlowData"); - return continuationStart(code3); - } - effects.consume(code3); - return continuation; - } - function continuationStart(code3) { - return effects.check(nonLazyContinuationStart, continuationStartNonLazy, continuationAfter)(code3); - } - function continuationStartNonLazy(code3) { - effects.enter("lineEnding"); - effects.consume(code3); - effects.exit("lineEnding"); - return continuationBefore; - } - function continuationBefore(code3) { - if (code3 === null || markdownLineEnding(code3)) { - return continuationStart(code3); - } - effects.enter("htmlFlowData"); - return continuation(code3); - } - function continuationCommentInside(code3) { - if (code3 === 45) { - effects.consume(code3); - return continuationDeclarationInside; - } - return continuation(code3); - } - function continuationRawTagOpen(code3) { - if (code3 === 47) { - effects.consume(code3); - buffer = ""; - return continuationRawEndTag; - } - return continuation(code3); - } - function continuationRawEndTag(code3) { - if (code3 === 62) { - const name = buffer.toLowerCase(); - if (htmlRawNames.includes(name)) { - effects.consume(code3); - return continuationClose; - } - return continuation(code3); - } - if (asciiAlpha(code3) && buffer.length < 8) { - effects.consume(code3); - buffer += String.fromCharCode(code3); - return continuationRawEndTag; - } - return continuation(code3); - } - function continuationCdataInside(code3) { - if (code3 === 93) { - effects.consume(code3); - return continuationDeclarationInside; - } - return continuation(code3); - } - function continuationDeclarationInside(code3) { - if (code3 === 62) { - effects.consume(code3); - return continuationClose; - } - if (code3 === 45 && marker === 2) { - effects.consume(code3); - return continuationDeclarationInside; - } - return continuation(code3); - } - function continuationClose(code3) { - if (code3 === null || markdownLineEnding(code3)) { - effects.exit("htmlFlowData"); - return continuationAfter(code3); - } - effects.consume(code3); - return continuationClose; - } - function continuationAfter(code3) { - effects.exit("htmlFlow"); - return ok3(code3); - } - } - function tokenizeNonLazyContinuationStart(effects, ok3, nok) { - const self2 = this; - return start; - function start(code3) { - if (markdownLineEnding(code3)) { - effects.enter("lineEnding"); - effects.consume(code3); - effects.exit("lineEnding"); - return after; - } - return nok(code3); - } - function after(code3) { - return self2.parser.lazy[self2.now().line] ? nok(code3) : ok3(code3); - } - } - function tokenizeBlankLineBefore(effects, ok3, nok) { - return start; - function start(code3) { - effects.enter("lineEnding"); - effects.consume(code3); - effects.exit("lineEnding"); - return effects.attempt(blankLine, ok3, nok); - } - } - - // node_modules/micromark-core-commonmark/lib/html-text.js - var htmlText = { - name: "htmlText", - tokenize: tokenizeHtmlText - }; - function tokenizeHtmlText(effects, ok3, nok) { - const self2 = this; - let marker; - let index2; - let returnState; - return start; - function start(code3) { - effects.enter("htmlText"); - effects.enter("htmlTextData"); - effects.consume(code3); - return open; - } - function open(code3) { - if (code3 === 33) { - effects.consume(code3); - return declarationOpen; - } - if (code3 === 47) { - effects.consume(code3); - return tagCloseStart; - } - if (code3 === 63) { - effects.consume(code3); - return instruction; - } - if (asciiAlpha(code3)) { - effects.consume(code3); - return tagOpen; - } - return nok(code3); - } - function declarationOpen(code3) { - if (code3 === 45) { - effects.consume(code3); - return commentOpenInside; - } - if (code3 === 91) { - effects.consume(code3); - index2 = 0; - return cdataOpenInside; - } - if (asciiAlpha(code3)) { - effects.consume(code3); - return declaration; - } - return nok(code3); - } - function commentOpenInside(code3) { - if (code3 === 45) { - effects.consume(code3); - return commentEnd; - } - return nok(code3); - } - function comment(code3) { - if (code3 === null) { - return nok(code3); - } - if (code3 === 45) { - effects.consume(code3); - return commentClose; - } - if (markdownLineEnding(code3)) { - returnState = comment; - return lineEndingBefore(code3); - } - effects.consume(code3); - return comment; - } - function commentClose(code3) { - if (code3 === 45) { - effects.consume(code3); - return commentEnd; - } - return comment(code3); - } - function commentEnd(code3) { - return code3 === 62 ? end(code3) : code3 === 45 ? commentClose(code3) : comment(code3); - } - function cdataOpenInside(code3) { - const value = "CDATA["; - if (code3 === value.charCodeAt(index2++)) { - effects.consume(code3); - return index2 === value.length ? cdata : cdataOpenInside; - } - return nok(code3); - } - function cdata(code3) { - if (code3 === null) { - return nok(code3); - } - if (code3 === 93) { - effects.consume(code3); - return cdataClose; - } - if (markdownLineEnding(code3)) { - returnState = cdata; - return lineEndingBefore(code3); - } - effects.consume(code3); - return cdata; - } - function cdataClose(code3) { - if (code3 === 93) { - effects.consume(code3); - return cdataEnd; - } - return cdata(code3); - } - function cdataEnd(code3) { - if (code3 === 62) { - return end(code3); - } - if (code3 === 93) { - effects.consume(code3); - return cdataEnd; - } - return cdata(code3); - } - function declaration(code3) { - if (code3 === null || code3 === 62) { - return end(code3); - } - if (markdownLineEnding(code3)) { - returnState = declaration; - return lineEndingBefore(code3); - } - effects.consume(code3); - return declaration; - } - function instruction(code3) { - if (code3 === null) { - return nok(code3); - } - if (code3 === 63) { - effects.consume(code3); - return instructionClose; - } - if (markdownLineEnding(code3)) { - returnState = instruction; - return lineEndingBefore(code3); - } - effects.consume(code3); - return instruction; - } - function instructionClose(code3) { - return code3 === 62 ? end(code3) : instruction(code3); - } - function tagCloseStart(code3) { - if (asciiAlpha(code3)) { - effects.consume(code3); - return tagClose; - } - return nok(code3); - } - function tagClose(code3) { - if (code3 === 45 || asciiAlphanumeric(code3)) { - effects.consume(code3); - return tagClose; - } - return tagCloseBetween(code3); - } - function tagCloseBetween(code3) { - if (markdownLineEnding(code3)) { - returnState = tagCloseBetween; - return lineEndingBefore(code3); - } - if (markdownSpace(code3)) { - effects.consume(code3); - return tagCloseBetween; - } - return end(code3); - } - function tagOpen(code3) { - if (code3 === 45 || asciiAlphanumeric(code3)) { - effects.consume(code3); - return tagOpen; - } - if (code3 === 47 || code3 === 62 || markdownLineEndingOrSpace(code3)) { - return tagOpenBetween(code3); - } - return nok(code3); - } - function tagOpenBetween(code3) { - if (code3 === 47) { - effects.consume(code3); - return end; - } - if (code3 === 58 || code3 === 95 || asciiAlpha(code3)) { - effects.consume(code3); - return tagOpenAttributeName; - } - if (markdownLineEnding(code3)) { - returnState = tagOpenBetween; - return lineEndingBefore(code3); - } - if (markdownSpace(code3)) { - effects.consume(code3); - return tagOpenBetween; - } - return end(code3); - } - function tagOpenAttributeName(code3) { - if (code3 === 45 || code3 === 46 || code3 === 58 || code3 === 95 || asciiAlphanumeric(code3)) { - effects.consume(code3); - return tagOpenAttributeName; - } - return tagOpenAttributeNameAfter(code3); - } - function tagOpenAttributeNameAfter(code3) { - if (code3 === 61) { - effects.consume(code3); - return tagOpenAttributeValueBefore; - } - if (markdownLineEnding(code3)) { - returnState = tagOpenAttributeNameAfter; - return lineEndingBefore(code3); - } - if (markdownSpace(code3)) { - effects.consume(code3); - return tagOpenAttributeNameAfter; - } - return tagOpenBetween(code3); - } - function tagOpenAttributeValueBefore(code3) { - if (code3 === null || code3 === 60 || code3 === 61 || code3 === 62 || code3 === 96) { - return nok(code3); - } - if (code3 === 34 || code3 === 39) { - effects.consume(code3); - marker = code3; - return tagOpenAttributeValueQuoted; - } - if (markdownLineEnding(code3)) { - returnState = tagOpenAttributeValueBefore; - return lineEndingBefore(code3); - } - if (markdownSpace(code3)) { - effects.consume(code3); - return tagOpenAttributeValueBefore; - } - effects.consume(code3); - return tagOpenAttributeValueUnquoted; - } - function tagOpenAttributeValueQuoted(code3) { - if (code3 === marker) { - effects.consume(code3); - marker = void 0; - return tagOpenAttributeValueQuotedAfter; - } - if (code3 === null) { - return nok(code3); - } - if (markdownLineEnding(code3)) { - returnState = tagOpenAttributeValueQuoted; - return lineEndingBefore(code3); - } - effects.consume(code3); - return tagOpenAttributeValueQuoted; - } - function tagOpenAttributeValueUnquoted(code3) { - if (code3 === null || code3 === 34 || code3 === 39 || code3 === 60 || code3 === 61 || code3 === 96) { - return nok(code3); - } - if (code3 === 47 || code3 === 62 || markdownLineEndingOrSpace(code3)) { - return tagOpenBetween(code3); - } - effects.consume(code3); - return tagOpenAttributeValueUnquoted; - } - function tagOpenAttributeValueQuotedAfter(code3) { - if (code3 === 47 || code3 === 62 || markdownLineEndingOrSpace(code3)) { - return tagOpenBetween(code3); - } - return nok(code3); - } - function end(code3) { - if (code3 === 62) { - effects.consume(code3); - effects.exit("htmlTextData"); - effects.exit("htmlText"); - return ok3; - } - return nok(code3); - } - function lineEndingBefore(code3) { - effects.exit("htmlTextData"); - effects.enter("lineEnding"); - effects.consume(code3); - effects.exit("lineEnding"); - return lineEndingAfter; - } - function lineEndingAfter(code3) { - return markdownSpace(code3) ? factorySpace(effects, lineEndingAfterPrefix, "linePrefix", self2.parser.constructs.disable.null.includes("codeIndented") ? void 0 : 4)(code3) : lineEndingAfterPrefix(code3); - } - function lineEndingAfterPrefix(code3) { - effects.enter("htmlTextData"); - return returnState(code3); - } - } - - // node_modules/micromark-core-commonmark/lib/label-end.js - var labelEnd = { - name: "labelEnd", - tokenize: tokenizeLabelEnd, - resolveTo: resolveToLabelEnd, - resolveAll: resolveAllLabelEnd - }; - var resourceConstruct = { - tokenize: tokenizeResource - }; - var referenceFullConstruct = { - tokenize: tokenizeReferenceFull - }; - var referenceCollapsedConstruct = { - tokenize: tokenizeReferenceCollapsed - }; - function resolveAllLabelEnd(events) { - let index2 = -1; - while (++index2 < events.length) { - const token = events[index2][1]; - if (token.type === "labelImage" || token.type === "labelLink" || token.type === "labelEnd") { - events.splice(index2 + 1, token.type === "labelImage" ? 4 : 2); - token.type = "data"; - index2++; - } - } - return events; - } - function resolveToLabelEnd(events, context) { - let index2 = events.length; - let offset = 0; - let token; - let open; - let close2; - let media; - while (index2--) { - token = events[index2][1]; - if (open) { - if (token.type === "link" || token.type === "labelLink" && token._inactive) { - break; - } - if (events[index2][0] === "enter" && token.type === "labelLink") { - token._inactive = true; - } - } else if (close2) { - if (events[index2][0] === "enter" && (token.type === "labelImage" || token.type === "labelLink") && !token._balanced) { - open = index2; - if (token.type !== "labelLink") { - offset = 2; - break; - } - } - } else if (token.type === "labelEnd") { - close2 = index2; - } - } - const group = { - type: events[open][1].type === "labelLink" ? "link" : "image", - start: Object.assign({}, events[open][1].start), - end: Object.assign({}, events[events.length - 1][1].end) - }; - const label = { - type: "label", - start: Object.assign({}, events[open][1].start), - end: Object.assign({}, events[close2][1].end) - }; - const text5 = { - type: "labelText", - start: Object.assign({}, events[open + offset + 2][1].end), - end: Object.assign({}, events[close2 - 2][1].start) - }; - media = [["enter", group, context], ["enter", label, context]]; - media = push(media, events.slice(open + 1, open + offset + 3)); - media = push(media, [["enter", text5, context]]); - media = push(media, resolveAll(context.parser.constructs.insideSpan.null, events.slice(open + offset + 4, close2 - 3), context)); - media = push(media, [["exit", text5, context], events[close2 - 2], events[close2 - 1], ["exit", label, context]]); - media = push(media, events.slice(close2 + 1)); - media = push(media, [["exit", group, context]]); - splice(events, open, events.length, media); - return events; - } - function tokenizeLabelEnd(effects, ok3, nok) { - const self2 = this; - let index2 = self2.events.length; - let labelStart; - let defined; - while (index2--) { - if ((self2.events[index2][1].type === "labelImage" || self2.events[index2][1].type === "labelLink") && !self2.events[index2][1]._balanced) { - labelStart = self2.events[index2][1]; - break; - } - } - return start; - function start(code3) { - if (!labelStart) { - return nok(code3); - } - if (labelStart._inactive) { - return labelEndNok(code3); - } - defined = self2.parser.defined.includes(normalizeIdentifier(self2.sliceSerialize({ - start: labelStart.end, - end: self2.now() - }))); - effects.enter("labelEnd"); - effects.enter("labelMarker"); - effects.consume(code3); - effects.exit("labelMarker"); - effects.exit("labelEnd"); - return after; - } - function after(code3) { - if (code3 === 40) { - return effects.attempt(resourceConstruct, labelEndOk, defined ? labelEndOk : labelEndNok)(code3); - } - if (code3 === 91) { - return effects.attempt(referenceFullConstruct, labelEndOk, defined ? referenceNotFull : labelEndNok)(code3); - } - return defined ? labelEndOk(code3) : labelEndNok(code3); - } - function referenceNotFull(code3) { - return effects.attempt(referenceCollapsedConstruct, labelEndOk, labelEndNok)(code3); - } - function labelEndOk(code3) { - return ok3(code3); - } - function labelEndNok(code3) { - labelStart._balanced = true; - return nok(code3); - } - } - function tokenizeResource(effects, ok3, nok) { - return resourceStart; - function resourceStart(code3) { - effects.enter("resource"); - effects.enter("resourceMarker"); - effects.consume(code3); - effects.exit("resourceMarker"); - return resourceBefore; - } - function resourceBefore(code3) { - return markdownLineEndingOrSpace(code3) ? factoryWhitespace(effects, resourceOpen)(code3) : resourceOpen(code3); - } - function resourceOpen(code3) { - if (code3 === 41) { - return resourceEnd(code3); - } - return factoryDestination(effects, resourceDestinationAfter, resourceDestinationMissing, "resourceDestination", "resourceDestinationLiteral", "resourceDestinationLiteralMarker", "resourceDestinationRaw", "resourceDestinationString", 32)(code3); - } - function resourceDestinationAfter(code3) { - return markdownLineEndingOrSpace(code3) ? factoryWhitespace(effects, resourceBetween)(code3) : resourceEnd(code3); - } - function resourceDestinationMissing(code3) { - return nok(code3); - } - function resourceBetween(code3) { - if (code3 === 34 || code3 === 39 || code3 === 40) { - return factoryTitle(effects, resourceTitleAfter, nok, "resourceTitle", "resourceTitleMarker", "resourceTitleString")(code3); - } - return resourceEnd(code3); - } - function resourceTitleAfter(code3) { - return markdownLineEndingOrSpace(code3) ? factoryWhitespace(effects, resourceEnd)(code3) : resourceEnd(code3); - } - function resourceEnd(code3) { - if (code3 === 41) { - effects.enter("resourceMarker"); - effects.consume(code3); - effects.exit("resourceMarker"); - effects.exit("resource"); - return ok3; - } - return nok(code3); - } - } - function tokenizeReferenceFull(effects, ok3, nok) { - const self2 = this; - return referenceFull; - function referenceFull(code3) { - return factoryLabel.call(self2, effects, referenceFullAfter, referenceFullMissing, "reference", "referenceMarker", "referenceString")(code3); - } - function referenceFullAfter(code3) { - return self2.parser.defined.includes(normalizeIdentifier(self2.sliceSerialize(self2.events[self2.events.length - 1][1]).slice(1, -1))) ? ok3(code3) : nok(code3); - } - function referenceFullMissing(code3) { - return nok(code3); - } - } - function tokenizeReferenceCollapsed(effects, ok3, nok) { - return referenceCollapsedStart; - function referenceCollapsedStart(code3) { - effects.enter("reference"); - effects.enter("referenceMarker"); - effects.consume(code3); - effects.exit("referenceMarker"); - return referenceCollapsedOpen; - } - function referenceCollapsedOpen(code3) { - if (code3 === 93) { - effects.enter("referenceMarker"); - effects.consume(code3); - effects.exit("referenceMarker"); - effects.exit("reference"); - return ok3; - } - return nok(code3); - } - } - - // node_modules/micromark-core-commonmark/lib/label-start-image.js - var labelStartImage = { - name: "labelStartImage", - tokenize: tokenizeLabelStartImage, - resolveAll: labelEnd.resolveAll - }; - function tokenizeLabelStartImage(effects, ok3, nok) { - const self2 = this; - return start; - function start(code3) { - effects.enter("labelImage"); - effects.enter("labelImageMarker"); - effects.consume(code3); - effects.exit("labelImageMarker"); - return open; - } - function open(code3) { - if (code3 === 91) { - effects.enter("labelMarker"); - effects.consume(code3); - effects.exit("labelMarker"); - effects.exit("labelImage"); - return after; - } - return nok(code3); - } - function after(code3) { - return code3 === 94 && "_hiddenFootnoteSupport" in self2.parser.constructs ? nok(code3) : ok3(code3); - } - } - - // node_modules/micromark-core-commonmark/lib/label-start-link.js - var labelStartLink = { - name: "labelStartLink", - tokenize: tokenizeLabelStartLink, - resolveAll: labelEnd.resolveAll - }; - function tokenizeLabelStartLink(effects, ok3, nok) { - const self2 = this; - return start; - function start(code3) { - effects.enter("labelLink"); - effects.enter("labelMarker"); - effects.consume(code3); - effects.exit("labelMarker"); - effects.exit("labelLink"); - return after; - } - function after(code3) { - return code3 === 94 && "_hiddenFootnoteSupport" in self2.parser.constructs ? nok(code3) : ok3(code3); - } - } - - // node_modules/micromark-core-commonmark/lib/line-ending.js - var lineEnding = { - name: "lineEnding", - tokenize: tokenizeLineEnding - }; - function tokenizeLineEnding(effects, ok3) { - return start; - function start(code3) { - effects.enter("lineEnding"); - effects.consume(code3); - effects.exit("lineEnding"); - return factorySpace(effects, ok3, "linePrefix"); - } - } - - // node_modules/micromark-core-commonmark/lib/thematic-break.js - var thematicBreak = { - name: "thematicBreak", - tokenize: tokenizeThematicBreak - }; - function tokenizeThematicBreak(effects, ok3, nok) { - let size = 0; - let marker; - return start; - function start(code3) { - effects.enter("thematicBreak"); - return before(code3); - } - function before(code3) { - marker = code3; - return atBreak(code3); - } - function atBreak(code3) { - if (code3 === marker) { - effects.enter("thematicBreakSequence"); - return sequence(code3); - } - if (size >= 3 && (code3 === null || markdownLineEnding(code3))) { - effects.exit("thematicBreak"); - return ok3(code3); - } - return nok(code3); - } - function sequence(code3) { - if (code3 === marker) { - effects.consume(code3); - size++; - return sequence; - } - effects.exit("thematicBreakSequence"); - return markdownSpace(code3) ? factorySpace(effects, atBreak, "whitespace")(code3) : atBreak(code3); - } - } - - // node_modules/micromark-core-commonmark/lib/list.js - var list = { - name: "list", - tokenize: tokenizeListStart, - continuation: { - tokenize: tokenizeListContinuation - }, - exit: tokenizeListEnd - }; - var listItemPrefixWhitespaceConstruct = { - tokenize: tokenizeListItemPrefixWhitespace, - partial: true - }; - var indentConstruct = { - tokenize: tokenizeIndent, - partial: true - }; - function tokenizeListStart(effects, ok3, nok) { - const self2 = this; - const tail = self2.events[self2.events.length - 1]; - let initialSize = tail && tail[1].type === "linePrefix" ? tail[2].sliceSerialize(tail[1], true).length : 0; - let size = 0; - return start; - function start(code3) { - const kind = self2.containerState.type || (code3 === 42 || code3 === 43 || code3 === 45 ? "listUnordered" : "listOrdered"); - if (kind === "listUnordered" ? !self2.containerState.marker || code3 === self2.containerState.marker : asciiDigit(code3)) { - if (!self2.containerState.type) { - self2.containerState.type = kind; - effects.enter(kind, { - _container: true - }); - } - if (kind === "listUnordered") { - effects.enter("listItemPrefix"); - return code3 === 42 || code3 === 45 ? effects.check(thematicBreak, nok, atMarker)(code3) : atMarker(code3); - } - if (!self2.interrupt || code3 === 49) { - effects.enter("listItemPrefix"); - effects.enter("listItemValue"); - return inside(code3); - } - } - return nok(code3); - } - function inside(code3) { - if (asciiDigit(code3) && ++size < 10) { - effects.consume(code3); - return inside; - } - if ((!self2.interrupt || size < 2) && (self2.containerState.marker ? code3 === self2.containerState.marker : code3 === 41 || code3 === 46)) { - effects.exit("listItemValue"); - return atMarker(code3); - } - return nok(code3); - } - function atMarker(code3) { - effects.enter("listItemMarker"); - effects.consume(code3); - effects.exit("listItemMarker"); - self2.containerState.marker = self2.containerState.marker || code3; - return effects.check( - blankLine, - // Can’t be empty when interrupting. - self2.interrupt ? nok : onBlank, - effects.attempt(listItemPrefixWhitespaceConstruct, endOfPrefix, otherPrefix) - ); - } - function onBlank(code3) { - self2.containerState.initialBlankLine = true; - initialSize++; - return endOfPrefix(code3); - } - function otherPrefix(code3) { - if (markdownSpace(code3)) { - effects.enter("listItemPrefixWhitespace"); - effects.consume(code3); - effects.exit("listItemPrefixWhitespace"); - return endOfPrefix; - } - return nok(code3); - } - function endOfPrefix(code3) { - self2.containerState.size = initialSize + self2.sliceSerialize(effects.exit("listItemPrefix"), true).length; - return ok3(code3); - } - } - function tokenizeListContinuation(effects, ok3, nok) { - const self2 = this; - self2.containerState._closeFlow = void 0; - return effects.check(blankLine, onBlank, notBlank); - function onBlank(code3) { - self2.containerState.furtherBlankLines = self2.containerState.furtherBlankLines || self2.containerState.initialBlankLine; - return factorySpace(effects, ok3, "listItemIndent", self2.containerState.size + 1)(code3); - } - function notBlank(code3) { - if (self2.containerState.furtherBlankLines || !markdownSpace(code3)) { - self2.containerState.furtherBlankLines = void 0; - self2.containerState.initialBlankLine = void 0; - return notInCurrentItem(code3); - } - self2.containerState.furtherBlankLines = void 0; - self2.containerState.initialBlankLine = void 0; - return effects.attempt(indentConstruct, ok3, notInCurrentItem)(code3); - } - function notInCurrentItem(code3) { - self2.containerState._closeFlow = true; - self2.interrupt = void 0; - return factorySpace(effects, effects.attempt(list, ok3, nok), "linePrefix", self2.parser.constructs.disable.null.includes("codeIndented") ? void 0 : 4)(code3); - } - } - function tokenizeIndent(effects, ok3, nok) { - const self2 = this; - return factorySpace(effects, afterPrefix, "listItemIndent", self2.containerState.size + 1); - function afterPrefix(code3) { - const tail = self2.events[self2.events.length - 1]; - return tail && tail[1].type === "listItemIndent" && tail[2].sliceSerialize(tail[1], true).length === self2.containerState.size ? ok3(code3) : nok(code3); - } - } - function tokenizeListEnd(effects) { - effects.exit(this.containerState.type); - } - function tokenizeListItemPrefixWhitespace(effects, ok3, nok) { - const self2 = this; - return factorySpace(effects, afterPrefix, "listItemPrefixWhitespace", self2.parser.constructs.disable.null.includes("codeIndented") ? void 0 : 4 + 1); - function afterPrefix(code3) { - const tail = self2.events[self2.events.length - 1]; - return !markdownSpace(code3) && tail && tail[1].type === "listItemPrefixWhitespace" ? ok3(code3) : nok(code3); - } - } - - // node_modules/micromark-core-commonmark/lib/setext-underline.js - var setextUnderline = { - name: "setextUnderline", - tokenize: tokenizeSetextUnderline, - resolveTo: resolveToSetextUnderline - }; - function resolveToSetextUnderline(events, context) { - let index2 = events.length; - let content3; - let text5; - let definition3; - while (index2--) { - if (events[index2][0] === "enter") { - if (events[index2][1].type === "content") { - content3 = index2; - break; - } - if (events[index2][1].type === "paragraph") { - text5 = index2; - } - } else { - if (events[index2][1].type === "content") { - events.splice(index2, 1); - } - if (!definition3 && events[index2][1].type === "definition") { - definition3 = index2; - } - } - } - const heading2 = { - type: "setextHeading", - start: Object.assign({}, events[text5][1].start), - end: Object.assign({}, events[events.length - 1][1].end) - }; - events[text5][1].type = "setextHeadingText"; - if (definition3) { - events.splice(text5, 0, ["enter", heading2, context]); - events.splice(definition3 + 1, 0, ["exit", events[content3][1], context]); - events[content3][1].end = Object.assign({}, events[definition3][1].end); - } else { - events[content3][1] = heading2; - } - events.push(["exit", heading2, context]); - return events; - } - function tokenizeSetextUnderline(effects, ok3, nok) { - const self2 = this; - let marker; - return start; - function start(code3) { - let index2 = self2.events.length; - let paragraph2; - while (index2--) { - if (self2.events[index2][1].type !== "lineEnding" && self2.events[index2][1].type !== "linePrefix" && self2.events[index2][1].type !== "content") { - paragraph2 = self2.events[index2][1].type === "paragraph"; - break; - } - } - if (!self2.parser.lazy[self2.now().line] && (self2.interrupt || paragraph2)) { - effects.enter("setextHeadingLine"); - marker = code3; - return before(code3); - } - return nok(code3); - } - function before(code3) { - effects.enter("setextHeadingLineSequence"); - return inside(code3); - } - function inside(code3) { - if (code3 === marker) { - effects.consume(code3); - return inside; - } - effects.exit("setextHeadingLineSequence"); - return markdownSpace(code3) ? factorySpace(effects, after, "lineSuffix")(code3) : after(code3); - } - function after(code3) { - if (code3 === null || markdownLineEnding(code3)) { - effects.exit("setextHeadingLine"); - return ok3(code3); - } - return nok(code3); - } - } - - // node_modules/micromark/lib/initialize/flow.js - var flow = { - tokenize: initializeFlow - }; - function initializeFlow(effects) { - const self2 = this; - const initial = effects.attempt( - // Try to parse a blank line. - blankLine, - atBlankEnding, - // Try to parse initial flow (essentially, only code). - effects.attempt( - this.parser.constructs.flowInitial, - afterConstruct, - factorySpace( - effects, - effects.attempt( - this.parser.constructs.flow, - afterConstruct, - effects.attempt(content2, afterConstruct) - ), - "linePrefix" - ) - ) - ); - return initial; - function atBlankEnding(code3) { - if (code3 === null) { - effects.consume(code3); - return; - } - effects.enter("lineEndingBlank"); - effects.consume(code3); - effects.exit("lineEndingBlank"); - self2.currentConstruct = void 0; - return initial; - } - function afterConstruct(code3) { - if (code3 === null) { - effects.consume(code3); - return; - } - effects.enter("lineEnding"); - effects.consume(code3); - effects.exit("lineEnding"); - self2.currentConstruct = void 0; - return initial; - } - } - - // node_modules/micromark/lib/initialize/text.js - var resolver = { - resolveAll: createResolver() - }; - var string = initializeFactory("string"); - var text = initializeFactory("text"); - function initializeFactory(field) { - return { - tokenize: initializeText, - resolveAll: createResolver( - field === "text" ? resolveAllLineSuffixes : void 0 - ) - }; - function initializeText(effects) { - const self2 = this; - const constructs2 = this.parser.constructs[field]; - const text5 = effects.attempt(constructs2, start, notText); - return start; - function start(code3) { - return atBreak(code3) ? text5(code3) : notText(code3); - } - function notText(code3) { - if (code3 === null) { - effects.consume(code3); - return; - } - effects.enter("data"); - effects.consume(code3); - return data; - } - function data(code3) { - if (atBreak(code3)) { - effects.exit("data"); - return text5(code3); - } - effects.consume(code3); - return data; - } - function atBreak(code3) { - if (code3 === null) { - return true; - } - const list4 = constructs2[code3]; - let index2 = -1; - if (list4) { - while (++index2 < list4.length) { - const item = list4[index2]; - if (!item.previous || item.previous.call(self2, self2.previous)) { - return true; - } - } - } - return false; - } - } - } - function createResolver(extraResolver) { - return resolveAllText; - function resolveAllText(events, context) { - let index2 = -1; - let enter; - while (++index2 <= events.length) { - if (enter === void 0) { - if (events[index2] && events[index2][1].type === "data") { - enter = index2; - index2++; - } - } else if (!events[index2] || events[index2][1].type !== "data") { - if (index2 !== enter + 2) { - events[enter][1].end = events[index2 - 1][1].end; - events.splice(enter + 2, index2 - enter - 2); - index2 = enter + 2; - } - enter = void 0; - } - } - return extraResolver ? extraResolver(events, context) : events; - } - } - function resolveAllLineSuffixes(events, context) { - let eventIndex = 0; - while (++eventIndex <= events.length) { - if ((eventIndex === events.length || events[eventIndex][1].type === "lineEnding") && events[eventIndex - 1][1].type === "data") { - const data = events[eventIndex - 1][1]; - const chunks = context.sliceStream(data); - let index2 = chunks.length; - let bufferIndex = -1; - let size = 0; - let tabs; - while (index2--) { - const chunk = chunks[index2]; - if (typeof chunk === "string") { - bufferIndex = chunk.length; - while (chunk.charCodeAt(bufferIndex - 1) === 32) { - size++; - bufferIndex--; - } - if (bufferIndex) break; - bufferIndex = -1; - } else if (chunk === -2) { - tabs = true; - size++; - } else if (chunk === -1) { - } else { - index2++; - break; - } - } - if (size) { - const token = { - type: eventIndex === events.length || tabs || size < 2 ? "lineSuffix" : "hardBreakTrailing", - start: { - line: data.end.line, - column: data.end.column - size, - offset: data.end.offset - size, - _index: data.start._index + index2, - _bufferIndex: index2 ? bufferIndex : data.start._bufferIndex + bufferIndex - }, - end: Object.assign({}, data.end) - }; - data.end = Object.assign({}, token.start); - if (data.start.offset === data.end.offset) { - Object.assign(data, token); - } else { - events.splice( - eventIndex, - 0, - ["enter", token, context], - ["exit", token, context] - ); - eventIndex += 2; - } - } - eventIndex++; - } - } - return events; - } - - // node_modules/micromark/lib/create-tokenizer.js - function createTokenizer(parser, initialize, from) { - let point3 = Object.assign( - from ? Object.assign({}, from) : { - line: 1, - column: 1, - offset: 0 - }, - { - _index: 0, - _bufferIndex: -1 - } - ); - const columnStart = {}; - const resolveAllConstructs = []; - let chunks = []; - let stack = []; - let consumed = true; - const effects = { - consume, - enter, - exit: exit3, - attempt: constructFactory(onsuccessfulconstruct), - check: constructFactory(onsuccessfulcheck), - interrupt: constructFactory(onsuccessfulcheck, { - interrupt: true - }) - }; - const context = { - previous: null, - code: null, - containerState: {}, - events: [], - parser, - sliceStream, - sliceSerialize, - now, - defineSkip, - write - }; - let state = initialize.tokenize.call(context, effects); - let expectedCode; - if (initialize.resolveAll) { - resolveAllConstructs.push(initialize); - } - return context; - function write(slice) { - chunks = push(chunks, slice); - main(); - if (chunks[chunks.length - 1] !== null) { - return []; - } - addResult(initialize, 0); - context.events = resolveAll(resolveAllConstructs, context.events, context); - return context.events; - } - function sliceSerialize(token, expandTabs) { - return serializeChunks(sliceStream(token), expandTabs); - } - function sliceStream(token) { - return sliceChunks(chunks, token); - } - function now() { - const { line, column, offset, _index, _bufferIndex } = point3; - return { - line, - column, - offset, - _index, - _bufferIndex - }; - } - function defineSkip(value) { - columnStart[value.line] = value.column; - accountForPotentialSkip(); - } - function main() { - let chunkIndex; - while (point3._index < chunks.length) { - const chunk = chunks[point3._index]; - if (typeof chunk === "string") { - chunkIndex = point3._index; - if (point3._bufferIndex < 0) { - point3._bufferIndex = 0; - } - while (point3._index === chunkIndex && point3._bufferIndex < chunk.length) { - go(chunk.charCodeAt(point3._bufferIndex)); - } - } else { - go(chunk); - } - } - } - function go(code3) { - consumed = void 0; - expectedCode = code3; - state = state(code3); - } - function consume(code3) { - if (markdownLineEnding(code3)) { - point3.line++; - point3.column = 1; - point3.offset += code3 === -3 ? 2 : 1; - accountForPotentialSkip(); - } else if (code3 !== -1) { - point3.column++; - point3.offset++; - } - if (point3._bufferIndex < 0) { - point3._index++; - } else { - point3._bufferIndex++; - if (point3._bufferIndex === chunks[point3._index].length) { - point3._bufferIndex = -1; - point3._index++; - } - } - context.previous = code3; - consumed = true; - } - function enter(type, fields) { - const token = fields || {}; - token.type = type; - token.start = now(); - context.events.push(["enter", token, context]); - stack.push(token); - return token; - } - function exit3(type) { - const token = stack.pop(); - token.end = now(); - context.events.push(["exit", token, context]); - return token; - } - function onsuccessfulconstruct(construct, info) { - addResult(construct, info.from); - } - function onsuccessfulcheck(_3, info) { - info.restore(); - } - function constructFactory(onreturn, fields) { - return hook; - function hook(constructs2, returnState, bogusState) { - let listOfConstructs; - let constructIndex; - let currentConstruct; - let info; - return Array.isArray(constructs2) ? handleListOfConstructs(constructs2) : "tokenize" in constructs2 ? ( - // @ts-expect-error Looks like a construct. - handleListOfConstructs([constructs2]) - ) : handleMapOfConstructs(constructs2); - function handleMapOfConstructs(map5) { - return start; - function start(code3) { - const def = code3 !== null && map5[code3]; - const all2 = code3 !== null && map5.null; - const list4 = [ - // To do: add more extension tests. - /* c8 ignore next 2 */ - ...Array.isArray(def) ? def : def ? [def] : [], - ...Array.isArray(all2) ? all2 : all2 ? [all2] : [] - ]; - return handleListOfConstructs(list4)(code3); - } - } - function handleListOfConstructs(list4) { - listOfConstructs = list4; - constructIndex = 0; - if (list4.length === 0) { - return bogusState; - } - return handleConstruct(list4[constructIndex]); - } - function handleConstruct(construct) { - return start; - function start(code3) { - info = store(); - currentConstruct = construct; - if (!construct.partial) { - context.currentConstruct = construct; - } - if (construct.name && context.parser.constructs.disable.null.includes(construct.name)) { - return nok(code3); - } - return construct.tokenize.call( - // If we do have fields, create an object w/ `context` as its - // prototype. - // This allows a “live binding”, which is needed for `interrupt`. - fields ? Object.assign(Object.create(context), fields) : context, - effects, - ok3, - nok - )(code3); - } - } - function ok3(code3) { - consumed = true; - onreturn(currentConstruct, info); - return returnState; - } - function nok(code3) { - consumed = true; - info.restore(); - if (++constructIndex < listOfConstructs.length) { - return handleConstruct(listOfConstructs[constructIndex]); - } - return bogusState; - } - } - } - function addResult(construct, from2) { - if (construct.resolveAll && !resolveAllConstructs.includes(construct)) { - resolveAllConstructs.push(construct); - } - if (construct.resolve) { - splice( - context.events, - from2, - context.events.length - from2, - construct.resolve(context.events.slice(from2), context) - ); - } - if (construct.resolveTo) { - context.events = construct.resolveTo(context.events, context); - } - } - function store() { - const startPoint = now(); - const startPrevious = context.previous; - const startCurrentConstruct = context.currentConstruct; - const startEventsIndex = context.events.length; - const startStack = Array.from(stack); - return { - restore, - from: startEventsIndex - }; - function restore() { - point3 = startPoint; - context.previous = startPrevious; - context.currentConstruct = startCurrentConstruct; - context.events.length = startEventsIndex; - stack = startStack; - accountForPotentialSkip(); - } - } - function accountForPotentialSkip() { - if (point3.line in columnStart && point3.column < 2) { - point3.column = columnStart[point3.line]; - point3.offset += columnStart[point3.line] - 1; - } - } - } - function sliceChunks(chunks, token) { - const startIndex = token.start._index; - const startBufferIndex = token.start._bufferIndex; - const endIndex = token.end._index; - const endBufferIndex = token.end._bufferIndex; - let view; - if (startIndex === endIndex) { - view = [chunks[startIndex].slice(startBufferIndex, endBufferIndex)]; - } else { - view = chunks.slice(startIndex, endIndex); - if (startBufferIndex > -1) { - const head = view[0]; - if (typeof head === "string") { - view[0] = head.slice(startBufferIndex); - } else { - view.shift(); - } - } - if (endBufferIndex > 0) { - view.push(chunks[endIndex].slice(0, endBufferIndex)); - } - } - return view; - } - function serializeChunks(chunks, expandTabs) { - let index2 = -1; - const result = []; - let atTab; - while (++index2 < chunks.length) { - const chunk = chunks[index2]; - let value; - if (typeof chunk === "string") { - value = chunk; - } else - switch (chunk) { - case -5: { - value = "\r"; - break; - } - case -4: { - value = "\n"; - break; - } - case -3: { - value = "\r\n"; - break; - } - case -2: { - value = expandTabs ? " " : " "; - break; - } - case -1: { - if (!expandTabs && atTab) continue; - value = " "; - break; - } - default: { - value = String.fromCharCode(chunk); - } - } - atTab = chunk === -2; - result.push(value); - } - return result.join(""); - } - - // node_modules/micromark/lib/constructs.js - var constructs_exports = {}; - __export(constructs_exports, { - attentionMarkers: () => attentionMarkers, - contentInitial: () => contentInitial, - disable: () => disable, - document: () => document3, - flow: () => flow2, - flowInitial: () => flowInitial, - insideSpan: () => insideSpan, - string: () => string2, - text: () => text2 - }); - var document3 = { - [42]: list, - [43]: list, - [45]: list, - [48]: list, - [49]: list, - [50]: list, - [51]: list, - [52]: list, - [53]: list, - [54]: list, - [55]: list, - [56]: list, - [57]: list, - [62]: blockQuote - }; - var contentInitial = { - [91]: definition - }; - var flowInitial = { - [-2]: codeIndented, - [-1]: codeIndented, - [32]: codeIndented - }; - var flow2 = { - [35]: headingAtx, - [42]: thematicBreak, - [45]: [setextUnderline, thematicBreak], - [60]: htmlFlow, - [61]: setextUnderline, - [95]: thematicBreak, - [96]: codeFenced, - [126]: codeFenced - }; - var string2 = { - [38]: characterReference, - [92]: characterEscape - }; - var text2 = { - [-5]: lineEnding, - [-4]: lineEnding, - [-3]: lineEnding, - [33]: labelStartImage, - [38]: characterReference, - [42]: attention, - [60]: [autolink, htmlText], - [91]: labelStartLink, - [92]: [hardBreakEscape, characterEscape], - [93]: labelEnd, - [95]: attention, - [96]: codeText - }; - var insideSpan = { - null: [attention, resolver] - }; - var attentionMarkers = { - null: [42, 95] - }; - var disable = { - null: [] - }; - - // node_modules/micromark/lib/parse.js - function parse(options2) { - const settings = options2 || {}; - const constructs2 = ( - /** @type {FullNormalizedExtension} */ - combineExtensions([constructs_exports, ...settings.extensions || []]) - ); - const parser = { - defined: [], - lazy: {}, - constructs: constructs2, - content: create(content), - document: create(document2), - flow: create(flow), - string: create(string), - text: create(text) - }; - return parser; - function create(initial) { - return creator; - function creator(from) { - return createTokenizer(parser, initial, from); - } - } - } - - // node_modules/micromark/lib/postprocess.js - function postprocess(events) { - while (!subtokenize(events)) { - } - return events; - } - - // node_modules/micromark/lib/preprocess.js - var search = /[\0\t\n\r]/g; - function preprocess() { - let column = 1; - let buffer = ""; - let start = true; - let atCarriageReturn; - return preprocessor; - function preprocessor(value, encoding, end) { - const chunks = []; - let match; - let next; - let startPosition; - let endPosition; - let code3; - value = buffer + (typeof value === "string" ? value.toString() : new TextDecoder(encoding || void 0).decode(value)); - startPosition = 0; - buffer = ""; - if (start) { - if (value.charCodeAt(0) === 65279) { - startPosition++; - } - start = void 0; - } - while (startPosition < value.length) { - search.lastIndex = startPosition; - match = search.exec(value); - endPosition = match && match.index !== void 0 ? match.index : value.length; - code3 = value.charCodeAt(endPosition); - if (!match) { - buffer = value.slice(startPosition); - break; - } - if (code3 === 10 && startPosition === endPosition && atCarriageReturn) { - chunks.push(-3); - atCarriageReturn = void 0; - } else { - if (atCarriageReturn) { - chunks.push(-5); - atCarriageReturn = void 0; - } - if (startPosition < endPosition) { - chunks.push(value.slice(startPosition, endPosition)); - column += endPosition - startPosition; - } - switch (code3) { - case 0: { - chunks.push(65533); - column++; - break; - } - case 9: { - next = Math.ceil(column / 4) * 4; - chunks.push(-2); - while (column++ < next) chunks.push(-1); - break; - } - case 10: { - chunks.push(-4); - column = 1; - break; - } - default: { - atCarriageReturn = true; - column = 1; - } - } - } - startPosition = endPosition + 1; - } - if (end) { - if (atCarriageReturn) chunks.push(-5); - if (buffer) chunks.push(buffer); - chunks.push(null); - } - return chunks; - } - } - - // node_modules/micromark-util-decode-string/index.js - var characterEscapeOrReference = /\\([!-/:-@[-`{-~])|&(#(?:\d{1,7}|x[\da-f]{1,6})|[\da-z]{1,31});/gi; - function decodeString(value) { - return value.replace(characterEscapeOrReference, decode); - } - function decode($0, $1, $22) { - if ($1) { - return $1; - } - const head = $22.charCodeAt(0); - if (head === 35) { - const head2 = $22.charCodeAt(1); - const hex = head2 === 120 || head2 === 88; - return decodeNumericCharacterReference($22.slice(hex ? 2 : 1), hex ? 16 : 10); - } - return decodeNamedCharacterReference($22) || $0; - } - - // node_modules/unist-util-stringify-position/lib/index.js - function stringifyPosition(value) { - if (!value || typeof value !== "object") { - return ""; - } - if ("position" in value || "type" in value) { - return position(value.position); - } - if ("start" in value || "end" in value) { - return position(value); - } - if ("line" in value || "column" in value) { - return point(value); - } - return ""; - } - function point(point3) { - return index(point3 && point3.line) + ":" + index(point3 && point3.column); - } - function position(pos) { - return point(pos && pos.start) + "-" + point(pos && pos.end); - } - function index(value) { - return value && typeof value === "number" ? value : 1; - } - - // node_modules/mdast-util-from-markdown/lib/index.js - var own = {}.hasOwnProperty; - function fromMarkdown(value, encoding, options2) { - if (typeof encoding !== "string") { - options2 = encoding; - encoding = void 0; - } - return compiler(options2)( - postprocess( - parse(options2).document().write(preprocess()(value, encoding, true)) - ) - ); - } - function compiler(options2) { - const config = { - transforms: [], - canContainEols: ["emphasis", "fragment", "heading", "paragraph", "strong"], - enter: { - autolink: opener(link2), - autolinkProtocol: onenterdata, - autolinkEmail: onenterdata, - atxHeading: opener(heading2), - blockQuote: opener(blockQuote2), - characterEscape: onenterdata, - characterReference: onenterdata, - codeFenced: opener(codeFlow), - codeFencedFenceInfo: buffer, - codeFencedFenceMeta: buffer, - codeIndented: opener(codeFlow, buffer), - codeText: opener(codeText2, buffer), - codeTextData: onenterdata, - data: onenterdata, - codeFlowValue: onenterdata, - definition: opener(definition3), - definitionDestinationString: buffer, - definitionLabelString: buffer, - definitionTitleString: buffer, - emphasis: opener(emphasis2), - hardBreakEscape: opener(hardBreak2), - hardBreakTrailing: opener(hardBreak2), - htmlFlow: opener(html3, buffer), - htmlFlowData: onenterdata, - htmlText: opener(html3, buffer), - htmlTextData: onenterdata, - image: opener(image2), - label: buffer, - link: opener(link2), - listItem: opener(listItem2), - listItemValue: onenterlistitemvalue, - listOrdered: opener(list4, onenterlistordered), - listUnordered: opener(list4), - paragraph: opener(paragraph2), - reference: onenterreference, - referenceString: buffer, - resourceDestinationString: buffer, - resourceTitleString: buffer, - setextHeading: opener(heading2), - strong: opener(strong2), - thematicBreak: opener(thematicBreak3) - }, - exit: { - atxHeading: closer(), - atxHeadingSequence: onexitatxheadingsequence, - autolink: closer(), - autolinkEmail: onexitautolinkemail, - autolinkProtocol: onexitautolinkprotocol, - blockQuote: closer(), - characterEscapeValue: onexitdata, - characterReferenceMarkerHexadecimal: onexitcharacterreferencemarker, - characterReferenceMarkerNumeric: onexitcharacterreferencemarker, - characterReferenceValue: onexitcharacterreferencevalue, - codeFenced: closer(onexitcodefenced), - codeFencedFence: onexitcodefencedfence, - codeFencedFenceInfo: onexitcodefencedfenceinfo, - codeFencedFenceMeta: onexitcodefencedfencemeta, - codeFlowValue: onexitdata, - codeIndented: closer(onexitcodeindented), - codeText: closer(onexitcodetext), - codeTextData: onexitdata, - data: onexitdata, - definition: closer(), - definitionDestinationString: onexitdefinitiondestinationstring, - definitionLabelString: onexitdefinitionlabelstring, - definitionTitleString: onexitdefinitiontitlestring, - emphasis: closer(), - hardBreakEscape: closer(onexithardbreak), - hardBreakTrailing: closer(onexithardbreak), - htmlFlow: closer(onexithtmlflow), - htmlFlowData: onexitdata, - htmlText: closer(onexithtmltext), - htmlTextData: onexitdata, - image: closer(onexitimage), - label: onexitlabel, - labelText: onexitlabeltext, - lineEnding: onexitlineending, - link: closer(onexitlink), - listItem: closer(), - listOrdered: closer(), - listUnordered: closer(), - paragraph: closer(), - referenceString: onexitreferencestring, - resourceDestinationString: onexitresourcedestinationstring, - resourceTitleString: onexitresourcetitlestring, - resource: onexitresource, - setextHeading: closer(onexitsetextheading), - setextHeadingLineSequence: onexitsetextheadinglinesequence, - setextHeadingText: onexitsetextheadingtext, - strong: closer(), - thematicBreak: closer() - } - }; - configure(config, (options2 || {}).mdastExtensions || []); - const data = {}; - return compile; - function compile(events) { - let tree = { - type: "root", - children: [] - }; - const context = { - stack: [tree], - tokenStack: [], - config, - enter, - exit: exit3, - buffer, - resume, - data - }; - const listStack = []; - let index2 = -1; - while (++index2 < events.length) { - if (events[index2][1].type === "listOrdered" || events[index2][1].type === "listUnordered") { - if (events[index2][0] === "enter") { - listStack.push(index2); - } else { - const tail = listStack.pop(); - index2 = prepareList(events, tail, index2); - } - } - } - index2 = -1; - while (++index2 < events.length) { - const handler = config[events[index2][0]]; - if (own.call(handler, events[index2][1].type)) { - handler[events[index2][1].type].call( - Object.assign( - { - sliceSerialize: events[index2][2].sliceSerialize - }, - context - ), - events[index2][1] - ); - } - } - if (context.tokenStack.length > 0) { - const tail = context.tokenStack[context.tokenStack.length - 1]; - const handler = tail[1] || defaultOnError; - handler.call(context, void 0, tail[0]); - } - tree.position = { - start: point2( - events.length > 0 ? events[0][1].start : { - line: 1, - column: 1, - offset: 0 - } - ), - end: point2( - events.length > 0 ? events[events.length - 2][1].end : { - line: 1, - column: 1, - offset: 0 - } - ) - }; - index2 = -1; - while (++index2 < config.transforms.length) { - tree = config.transforms[index2](tree) || tree; - } - return tree; - } - function prepareList(events, start, length) { - let index2 = start - 1; - let containerBalance = -1; - let listSpread = false; - let listItem3; - let lineIndex; - let firstBlankLineIndex; - let atMarker; - while (++index2 <= length) { - const event = events[index2]; - switch (event[1].type) { - case "listUnordered": - case "listOrdered": - case "blockQuote": { - if (event[0] === "enter") { - containerBalance++; - } else { - containerBalance--; - } - atMarker = void 0; - break; - } - case "lineEndingBlank": { - if (event[0] === "enter") { - if (listItem3 && !atMarker && !containerBalance && !firstBlankLineIndex) { - firstBlankLineIndex = index2; - } - atMarker = void 0; - } - break; - } - case "linePrefix": - case "listItemValue": - case "listItemMarker": - case "listItemPrefix": - case "listItemPrefixWhitespace": { - break; - } - default: { - atMarker = void 0; - } - } - if (!containerBalance && event[0] === "enter" && event[1].type === "listItemPrefix" || containerBalance === -1 && event[0] === "exit" && (event[1].type === "listUnordered" || event[1].type === "listOrdered")) { - if (listItem3) { - let tailIndex = index2; - lineIndex = void 0; - while (tailIndex--) { - const tailEvent = events[tailIndex]; - if (tailEvent[1].type === "lineEnding" || tailEvent[1].type === "lineEndingBlank") { - if (tailEvent[0] === "exit") continue; - if (lineIndex) { - events[lineIndex][1].type = "lineEndingBlank"; - listSpread = true; - } - tailEvent[1].type = "lineEnding"; - lineIndex = tailIndex; - } else if (tailEvent[1].type === "linePrefix" || tailEvent[1].type === "blockQuotePrefix" || tailEvent[1].type === "blockQuotePrefixWhitespace" || tailEvent[1].type === "blockQuoteMarker" || tailEvent[1].type === "listItemIndent") { - } else { - break; - } - } - if (firstBlankLineIndex && (!lineIndex || firstBlankLineIndex < lineIndex)) { - listItem3._spread = true; - } - listItem3.end = Object.assign( - {}, - lineIndex ? events[lineIndex][1].start : event[1].end - ); - events.splice(lineIndex || index2, 0, ["exit", listItem3, event[2]]); - index2++; - length++; - } - if (event[1].type === "listItemPrefix") { - const item = { - type: "listItem", - _spread: false, - start: Object.assign({}, event[1].start), - // @ts-expect-error: we’ll add `end` in a second. - end: void 0 - }; - listItem3 = item; - events.splice(index2, 0, ["enter", item, event[2]]); - index2++; - length++; - firstBlankLineIndex = void 0; - atMarker = true; - } - } - } - events[start][1]._spread = listSpread; - return length; - } - function opener(create, and) { - return open; - function open(token) { - enter.call(this, create(token), token); - if (and) and.call(this, token); - } - } - function buffer() { - this.stack.push({ - type: "fragment", - children: [] - }); - } - function enter(node2, token, errorHandler) { - const parent = this.stack[this.stack.length - 1]; - const siblings = parent.children; - siblings.push(node2); - this.stack.push(node2); - this.tokenStack.push([token, errorHandler]); - node2.position = { - start: point2(token.start), - // @ts-expect-error: `end` will be patched later. - end: void 0 - }; - } - function closer(and) { - return close2; - function close2(token) { - if (and) and.call(this, token); - exit3.call(this, token); - } - } - function exit3(token, onExitError) { - const node2 = this.stack.pop(); - const open = this.tokenStack.pop(); - if (!open) { - throw new Error( - "Cannot close `" + token.type + "` (" + stringifyPosition({ - start: token.start, - end: token.end - }) + "): it\u2019s not open" - ); - } else if (open[0].type !== token.type) { - if (onExitError) { - onExitError.call(this, token, open[0]); - } else { - const handler = open[1] || defaultOnError; - handler.call(this, token, open[0]); - } - } - node2.position.end = point2(token.end); - } - function resume() { - return toString(this.stack.pop()); - } - function onenterlistordered() { - this.data.expectingFirstListItemValue = true; - } - function onenterlistitemvalue(token) { - if (this.data.expectingFirstListItemValue) { - const ancestor = this.stack[this.stack.length - 2]; - ancestor.start = Number.parseInt(this.sliceSerialize(token), 10); - this.data.expectingFirstListItemValue = void 0; - } - } - function onexitcodefencedfenceinfo() { - const data2 = this.resume(); - const node2 = this.stack[this.stack.length - 1]; - node2.lang = data2; - } - function onexitcodefencedfencemeta() { - const data2 = this.resume(); - const node2 = this.stack[this.stack.length - 1]; - node2.meta = data2; - } - function onexitcodefencedfence() { - if (this.data.flowCodeInside) return; - this.buffer(); - this.data.flowCodeInside = true; - } - function onexitcodefenced() { - const data2 = this.resume(); - const node2 = this.stack[this.stack.length - 1]; - node2.value = data2.replace(/^(\r?\n|\r)|(\r?\n|\r)$/g, ""); - this.data.flowCodeInside = void 0; - } - function onexitcodeindented() { - const data2 = this.resume(); - const node2 = this.stack[this.stack.length - 1]; - node2.value = data2.replace(/(\r?\n|\r)$/g, ""); - } - function onexitdefinitionlabelstring(token) { - const label = this.resume(); - const node2 = this.stack[this.stack.length - 1]; - node2.label = label; - node2.identifier = normalizeIdentifier( - this.sliceSerialize(token) - ).toLowerCase(); - } - function onexitdefinitiontitlestring() { - const data2 = this.resume(); - const node2 = this.stack[this.stack.length - 1]; - node2.title = data2; - } - function onexitdefinitiondestinationstring() { - const data2 = this.resume(); - const node2 = this.stack[this.stack.length - 1]; - node2.url = data2; - } - function onexitatxheadingsequence(token) { - const node2 = this.stack[this.stack.length - 1]; - if (!node2.depth) { - const depth = this.sliceSerialize(token).length; - node2.depth = depth; - } - } - function onexitsetextheadingtext() { - this.data.setextHeadingSlurpLineEnding = true; - } - function onexitsetextheadinglinesequence(token) { - const node2 = this.stack[this.stack.length - 1]; - node2.depth = this.sliceSerialize(token).codePointAt(0) === 61 ? 1 : 2; - } - function onexitsetextheading() { - this.data.setextHeadingSlurpLineEnding = void 0; - } - function onenterdata(token) { - const node2 = this.stack[this.stack.length - 1]; - const siblings = node2.children; - let tail = siblings[siblings.length - 1]; - if (!tail || tail.type !== "text") { - tail = text5(); - tail.position = { - start: point2(token.start), - // @ts-expect-error: we’ll add `end` later. - end: void 0 - }; - siblings.push(tail); - } - this.stack.push(tail); - } - function onexitdata(token) { - const tail = this.stack.pop(); - tail.value += this.sliceSerialize(token); - tail.position.end = point2(token.end); - } - function onexitlineending(token) { - const context = this.stack[this.stack.length - 1]; - if (this.data.atHardBreak) { - const tail = context.children[context.children.length - 1]; - tail.position.end = point2(token.end); - this.data.atHardBreak = void 0; - return; - } - if (!this.data.setextHeadingSlurpLineEnding && config.canContainEols.includes(context.type)) { - onenterdata.call(this, token); - onexitdata.call(this, token); - } - } - function onexithardbreak() { - this.data.atHardBreak = true; - } - function onexithtmlflow() { - const data2 = this.resume(); - const node2 = this.stack[this.stack.length - 1]; - node2.value = data2; - } - function onexithtmltext() { - const data2 = this.resume(); - const node2 = this.stack[this.stack.length - 1]; - node2.value = data2; - } - function onexitcodetext() { - const data2 = this.resume(); - const node2 = this.stack[this.stack.length - 1]; - node2.value = data2; - } - function onexitlink() { - const node2 = this.stack[this.stack.length - 1]; - if (this.data.inReference) { - const referenceType = this.data.referenceType || "shortcut"; - node2.type += "Reference"; - node2.referenceType = referenceType; - delete node2.url; - delete node2.title; - } else { - delete node2.identifier; - delete node2.label; - } - this.data.referenceType = void 0; - } - function onexitimage() { - const node2 = this.stack[this.stack.length - 1]; - if (this.data.inReference) { - const referenceType = this.data.referenceType || "shortcut"; - node2.type += "Reference"; - node2.referenceType = referenceType; - delete node2.url; - delete node2.title; - } else { - delete node2.identifier; - delete node2.label; - } - this.data.referenceType = void 0; - } - function onexitlabeltext(token) { - const string3 = this.sliceSerialize(token); - const ancestor = this.stack[this.stack.length - 2]; - ancestor.label = decodeString(string3); - ancestor.identifier = normalizeIdentifier(string3).toLowerCase(); - } - function onexitlabel() { - const fragment = this.stack[this.stack.length - 1]; - const value = this.resume(); - const node2 = this.stack[this.stack.length - 1]; - this.data.inReference = true; - if (node2.type === "link") { - const children = fragment.children; - node2.children = children; - } else { - node2.alt = value; - } - } - function onexitresourcedestinationstring() { - const data2 = this.resume(); - const node2 = this.stack[this.stack.length - 1]; - node2.url = data2; - } - function onexitresourcetitlestring() { - const data2 = this.resume(); - const node2 = this.stack[this.stack.length - 1]; - node2.title = data2; - } - function onexitresource() { - this.data.inReference = void 0; - } - function onenterreference() { - this.data.referenceType = "collapsed"; - } - function onexitreferencestring(token) { - const label = this.resume(); - const node2 = this.stack[this.stack.length - 1]; - node2.label = label; - node2.identifier = normalizeIdentifier( - this.sliceSerialize(token) - ).toLowerCase(); - this.data.referenceType = "full"; - } - function onexitcharacterreferencemarker(token) { - this.data.characterReferenceType = token.type; - } - function onexitcharacterreferencevalue(token) { - const data2 = this.sliceSerialize(token); - const type = this.data.characterReferenceType; - let value; - if (type) { - value = decodeNumericCharacterReference( - data2, - type === "characterReferenceMarkerNumeric" ? 10 : 16 - ); - this.data.characterReferenceType = void 0; - } else { - const result = decodeNamedCharacterReference(data2); - value = result; - } - const tail = this.stack.pop(); - tail.value += value; - tail.position.end = point2(token.end); - } - function onexitautolinkprotocol(token) { - onexitdata.call(this, token); - const node2 = this.stack[this.stack.length - 1]; - node2.url = this.sliceSerialize(token); - } - function onexitautolinkemail(token) { - onexitdata.call(this, token); - const node2 = this.stack[this.stack.length - 1]; - node2.url = "mailto:" + this.sliceSerialize(token); - } - function blockQuote2() { - return { - type: "blockquote", - children: [] - }; - } - function codeFlow() { - return { - type: "code", - lang: null, - meta: null, - value: "" - }; - } - function codeText2() { - return { - type: "inlineCode", - value: "" - }; - } - function definition3() { - return { - type: "definition", - identifier: "", - label: null, - title: null, - url: "" - }; - } - function emphasis2() { - return { - type: "emphasis", - children: [] - }; - } - function heading2() { - return { - type: "heading", - // @ts-expect-error `depth` will be set later. - depth: 0, - children: [] - }; - } - function hardBreak2() { - return { - type: "break" - }; - } - function html3() { - return { - type: "html", - value: "" - }; - } - function image2() { - return { - type: "image", - title: null, - url: "", - alt: null - }; - } - function link2() { - return { - type: "link", - title: null, - url: "", - children: [] - }; - } - function list4(token) { - return { - type: "list", - ordered: token.type === "listOrdered", - start: null, - spread: token._spread, - children: [] - }; - } - function listItem2(token) { - return { - type: "listItem", - spread: token._spread, - checked: null, - children: [] - }; - } - function paragraph2() { - return { - type: "paragraph", - children: [] - }; - } - function strong2() { - return { - type: "strong", - children: [] - }; - } - function text5() { - return { - type: "text", - value: "" - }; - } - function thematicBreak3() { - return { - type: "thematicBreak" - }; - } - } - function point2(d6) { - return { - line: d6.line, - column: d6.column, - offset: d6.offset - }; - } - function configure(combined, extensions) { - let index2 = -1; - while (++index2 < extensions.length) { - const value = extensions[index2]; - if (Array.isArray(value)) { - configure(combined, value); - } else { - extension(combined, value); - } - } - } - function extension(combined, extension2) { - let key; - for (key in extension2) { - if (own.call(extension2, key)) { - switch (key) { - case "canContainEols": { - const right = extension2[key]; - if (right) { - combined[key].push(...right); - } - break; - } - case "transforms": { - const right = extension2[key]; - if (right) { - combined[key].push(...right); - } - break; - } - case "enter": - case "exit": { - const right = extension2[key]; - if (right) { - Object.assign(combined[key], right); - } - break; - } - } - } - } - } - function defaultOnError(left, right) { - if (left) { - throw new Error( - "Cannot close `" + left.type + "` (" + stringifyPosition({ - start: left.start, - end: left.end - }) + "): a different token (`" + right.type + "`, " + stringifyPosition({ - start: right.start, - end: right.end - }) + ") is open" - ); - } else { - throw new Error( - "Cannot close document, a token (`" + right.type + "`, " + stringifyPosition({ - start: right.start, - end: right.end - }) + ") is still open" - ); - } - } - - // node_modules/remark-parse/lib/index.js - function remarkParse(options2) { - const self2 = this; - self2.parser = parser; - function parser(doc4) { - return fromMarkdown(doc4, __spreadProps(__spreadValues(__spreadValues({}, self2.data("settings")), options2), { - // Note: these options are not in the readme. - // The goal is for them to be set by plugins on `data` instead of being - // passed by users. - extensions: self2.data("micromarkExtensions") || [], - mdastExtensions: self2.data("fromMarkdownExtensions") || [] - })); - } - } - - // node_modules/zwitch/index.js - var own2 = {}.hasOwnProperty; - function zwitch(key, options2) { - const settings = options2 || {}; - function one2(value, ...parameters) { - let fn = one2.invalid; - const handlers2 = one2.handlers; - if (value && own2.call(value, key)) { - const id = String(value[key]); - fn = own2.call(handlers2, id) ? handlers2[id] : one2.unknown; - } - if (fn) { - return fn.call(this, value, ...parameters); - } - } - one2.handlers = settings.handlers || {}; - one2.invalid = settings.invalid; - one2.unknown = settings.unknown; - return one2; - } - - // node_modules/mdast-util-to-markdown/lib/configure.js - var own3 = {}.hasOwnProperty; - function configure2(base2, extension2) { - let index2 = -1; - let key; - if (extension2.extensions) { - while (++index2 < extension2.extensions.length) { - configure2(base2, extension2.extensions[index2]); - } - } - for (key in extension2) { - if (own3.call(extension2, key)) { - switch (key) { - case "extensions": { - break; - } - case "unsafe": { - list2(base2[key], extension2[key]); - break; - } - case "join": { - list2(base2[key], extension2[key]); - break; - } - case "handlers": { - map(base2[key], extension2[key]); - break; - } - default: { - base2.options[key] = extension2[key]; - } - } - } - } - return base2; - } - function list2(left, right) { - if (right) { - left.push(...right); - } - } - function map(left, right) { - if (right) { - Object.assign(left, right); - } - } - - // node_modules/mdast-util-to-markdown/lib/handle/blockquote.js - function blockquote(node2, _3, state, info) { - const exit3 = state.enter("blockquote"); - const tracker = state.createTracker(info); - tracker.move("> "); - tracker.shift(2); - const value = state.indentLines( - state.containerFlow(node2, tracker.current()), - map2 - ); - exit3(); - return value; - } - function map2(line, _3, blank) { - return ">" + (blank ? "" : " ") + line; - } - - // node_modules/mdast-util-to-markdown/lib/util/pattern-in-scope.js - function patternInScope(stack, pattern) { - return listInScope(stack, pattern.inConstruct, true) && !listInScope(stack, pattern.notInConstruct, false); - } - function listInScope(stack, list4, none2) { - if (typeof list4 === "string") { - list4 = [list4]; - } - if (!list4 || list4.length === 0) { - return none2; - } - let index2 = -1; - while (++index2 < list4.length) { - if (stack.includes(list4[index2])) { - return true; - } - } - return false; - } - - // node_modules/mdast-util-to-markdown/lib/handle/break.js - function hardBreak(_3, _1, state, info) { - let index2 = -1; - while (++index2 < state.unsafe.length) { - if (state.unsafe[index2].character === "\n" && patternInScope(state.stack, state.unsafe[index2])) { - return /[ \t]/.test(info.before) ? "" : " "; - } - } - return "\\\n"; - } - - // node_modules/longest-streak/index.js - function longestStreak(value, substring) { - const source = String(value); - let index2 = source.indexOf(substring); - let expected = index2; - let count = 0; - let max = 0; - if (typeof substring !== "string") { - throw new TypeError("Expected substring"); - } - while (index2 !== -1) { - if (index2 === expected) { - if (++count > max) { - max = count; - } - } else { - count = 1; - } - expected = index2 + substring.length; - index2 = source.indexOf(substring, expected); - } - return max; - } - - // node_modules/mdast-util-to-markdown/lib/util/format-code-as-indented.js - function formatCodeAsIndented(node2, state) { - return Boolean( - state.options.fences === false && node2.value && // If there’s no info… - !node2.lang && // And there’s a non-whitespace character… - /[^ \r\n]/.test(node2.value) && // And the value doesn’t start or end in a blank… - !/^[\t ]*(?:[\r\n]|$)|(?:^|[\r\n])[\t ]*$/.test(node2.value) - ); - } - - // node_modules/mdast-util-to-markdown/lib/util/check-fence.js - function checkFence(state) { - const marker = state.options.fence || "`"; - if (marker !== "`" && marker !== "~") { - throw new Error( - "Cannot serialize code with `" + marker + "` for `options.fence`, expected `` ` `` or `~`" - ); - } - return marker; - } - - // node_modules/mdast-util-to-markdown/lib/handle/code.js - function code(node2, _3, state, info) { - const marker = checkFence(state); - const raw = node2.value || ""; - const suffix = marker === "`" ? "GraveAccent" : "Tilde"; - if (formatCodeAsIndented(node2, state)) { - const exit4 = state.enter("codeIndented"); - const value2 = state.indentLines(raw, map3); - exit4(); - return value2; - } - const tracker = state.createTracker(info); - const sequence = marker.repeat(Math.max(longestStreak(raw, marker) + 1, 3)); - const exit3 = state.enter("codeFenced"); - let value = tracker.move(sequence); - if (node2.lang) { - const subexit = state.enter(`codeFencedLang${suffix}`); - value += tracker.move( - state.safe(node2.lang, __spreadValues({ - before: value, - after: " ", - encode: ["`"] - }, tracker.current())) - ); - subexit(); - } - if (node2.lang && node2.meta) { - const subexit = state.enter(`codeFencedMeta${suffix}`); - value += tracker.move(" "); - value += tracker.move( - state.safe(node2.meta, __spreadValues({ - before: value, - after: "\n", - encode: ["`"] - }, tracker.current())) - ); - subexit(); - } - value += tracker.move("\n"); - if (raw) { - value += tracker.move(raw + "\n"); - } - value += tracker.move(sequence); - exit3(); - return value; - } - function map3(line, _3, blank) { - return (blank ? "" : " ") + line; - } - - // node_modules/mdast-util-to-markdown/lib/util/check-quote.js - function checkQuote(state) { - const marker = state.options.quote || '"'; - if (marker !== '"' && marker !== "'") { - throw new Error( - "Cannot serialize title with `" + marker + "` for `options.quote`, expected `\"`, or `'`" - ); - } - return marker; - } - - // node_modules/mdast-util-to-markdown/lib/handle/definition.js - function definition2(node2, _3, state, info) { - const quote = checkQuote(state); - const suffix = quote === '"' ? "Quote" : "Apostrophe"; - const exit3 = state.enter("definition"); - let subexit = state.enter("label"); - const tracker = state.createTracker(info); - let value = tracker.move("["); - value += tracker.move( - state.safe(state.associationId(node2), __spreadValues({ - before: value, - after: "]" - }, tracker.current())) - ); - value += tracker.move("]: "); - subexit(); - if ( - // If there’s no url, or… - !node2.url || // If there are control characters or whitespace. - /[\0- \u007F]/.test(node2.url) - ) { - subexit = state.enter("destinationLiteral"); - value += tracker.move("<"); - value += tracker.move( - state.safe(node2.url, __spreadValues({ before: value, after: ">" }, tracker.current())) - ); - value += tracker.move(">"); - } else { - subexit = state.enter("destinationRaw"); - value += tracker.move( - state.safe(node2.url, __spreadValues({ - before: value, - after: node2.title ? " " : "\n" - }, tracker.current())) - ); - } - subexit(); - if (node2.title) { - subexit = state.enter(`title${suffix}`); - value += tracker.move(" " + quote); - value += tracker.move( - state.safe(node2.title, __spreadValues({ - before: value, - after: quote - }, tracker.current())) - ); - value += tracker.move(quote); - subexit(); - } - exit3(); - return value; - } - - // node_modules/mdast-util-to-markdown/lib/util/check-emphasis.js - function checkEmphasis(state) { - const marker = state.options.emphasis || "*"; - if (marker !== "*" && marker !== "_") { - throw new Error( - "Cannot serialize emphasis with `" + marker + "` for `options.emphasis`, expected `*`, or `_`" - ); - } - return marker; - } - - // node_modules/mdast-util-to-markdown/lib/handle/emphasis.js - emphasis.peek = emphasisPeek; - function emphasis(node2, _3, state, info) { - const marker = checkEmphasis(state); - const exit3 = state.enter("emphasis"); - const tracker = state.createTracker(info); - let value = tracker.move(marker); - value += tracker.move( - state.containerPhrasing(node2, __spreadValues({ - before: value, - after: marker - }, tracker.current())) - ); - value += tracker.move(marker); - exit3(); - return value; - } - function emphasisPeek(_3, _1, state) { - return state.options.emphasis || "*"; - } - - // node_modules/unist-util-is/lib/index.js - var convert = ( - // Note: overloads in JSDoc can’t yet use different `@template`s. - /** - * @type {( - * ((test: Condition) => (node: unknown, index?: number | null | undefined, parent?: Parent | null | undefined, context?: unknown) => node is Node & {type: Condition}) & - * ((test: Condition) => (node: unknown, index?: number | null | undefined, parent?: Parent | null | undefined, context?: unknown) => node is Node & Condition) & - * ((test: Condition) => (node: unknown, index?: number | null | undefined, parent?: Parent | null | undefined, context?: unknown) => node is Node & Predicate) & - * ((test?: null | undefined) => (node?: unknown, index?: number | null | undefined, parent?: Parent | null | undefined, context?: unknown) => node is Node) & - * ((test?: Test) => Check) - * )} - */ - /** - * @param {Test} [test] - * @returns {Check} - */ - function(test) { - if (test === null || test === void 0) { - return ok; - } - if (typeof test === "function") { - return castFactory(test); - } - if (typeof test === "object") { - return Array.isArray(test) ? anyFactory(test) : propsFactory(test); - } - if (typeof test === "string") { - return typeFactory(test); - } - throw new Error("Expected function, string, or object as test"); - } - ); - function anyFactory(tests) { - const checks = []; - let index2 = -1; - while (++index2 < tests.length) { - checks[index2] = convert(tests[index2]); - } - return castFactory(any); - function any(...parameters) { - let index3 = -1; - while (++index3 < checks.length) { - if (checks[index3].apply(this, parameters)) return true; - } - return false; - } - } - function propsFactory(check) { - const checkAsRecord = ( - /** @type {Record} */ - check - ); - return castFactory(all2); - function all2(node2) { - const nodeAsRecord = ( - /** @type {Record} */ - /** @type {unknown} */ - node2 - ); - let key; - for (key in check) { - if (nodeAsRecord[key] !== checkAsRecord[key]) return false; - } - return true; - } - } - function typeFactory(check) { - return castFactory(type); - function type(node2) { - return node2 && node2.type === check; - } - } - function castFactory(testFunction) { - return check; - function check(value, index2, parent) { - return Boolean( - looksLikeANode(value) && testFunction.call( - this, - value, - typeof index2 === "number" ? index2 : void 0, - parent || void 0 - ) - ); - } - } - function ok() { - return true; - } - function looksLikeANode(value) { - return value !== null && typeof value === "object" && "type" in value; - } - - // node_modules/unist-util-visit-parents/lib/color.js - function color(d6) { - return d6; - } - - // node_modules/unist-util-visit-parents/lib/index.js - var empty = []; - var CONTINUE = true; - var EXIT = false; - var SKIP = "skip"; - function visitParents(tree, test, visitor, reverse) { - let check; - if (typeof test === "function" && typeof visitor !== "function") { - reverse = visitor; - visitor = test; - } else { - check = test; - } - const is2 = convert(check); - const step = reverse ? -1 : 1; - factory(tree, void 0, [])(); - function factory(node2, index2, parents) { - const value = ( - /** @type {Record} */ - node2 && typeof node2 === "object" ? node2 : {} - ); - if (typeof value.type === "string") { - const name = ( - // `hast` - typeof value.tagName === "string" ? value.tagName : ( - // `xast` - typeof value.name === "string" ? value.name : void 0 - ) - ); - Object.defineProperty(visit2, "name", { - value: "node (" + color(node2.type + (name ? "<" + name + ">" : "")) + ")" - }); - } - return visit2; - function visit2() { - let result = empty; - let subresult; - let offset; - let grandparents; - if (!test || is2(node2, index2, parents[parents.length - 1] || void 0)) { - result = toResult(visitor(node2, parents)); - if (result[0] === EXIT) { - return result; - } - } - if ("children" in node2 && node2.children) { - const nodeAsParent = ( - /** @type {UnistParent} */ - node2 - ); - if (nodeAsParent.children && result[0] !== SKIP) { - offset = (reverse ? nodeAsParent.children.length : -1) + step; - grandparents = parents.concat(nodeAsParent); - while (offset > -1 && offset < nodeAsParent.children.length) { - const child = nodeAsParent.children[offset]; - subresult = factory(child, offset, grandparents)(); - if (subresult[0] === EXIT) { - return subresult; - } - offset = typeof subresult[1] === "number" ? subresult[1] : offset + step; - } - } - } - return result; - } - } - } - function toResult(value) { - if (Array.isArray(value)) { - return value; - } - if (typeof value === "number") { - return [CONTINUE, value]; - } - return value === null || value === void 0 ? empty : [value]; - } - - // node_modules/unist-util-visit/lib/index.js - function visit(tree, testOrVisitor, visitorOrReverse, maybeReverse) { - let reverse; - let test; - let visitor; - if (typeof testOrVisitor === "function" && typeof visitorOrReverse !== "function") { - test = void 0; - visitor = testOrVisitor; - reverse = visitorOrReverse; - } else { - test = testOrVisitor; - visitor = visitorOrReverse; - reverse = maybeReverse; - } - visitParents(tree, test, overload, reverse); - function overload(node2, parents) { - const parent = parents[parents.length - 1]; - const index2 = parent ? parent.children.indexOf(node2) : void 0; - return visitor(node2, index2, parent); - } - } - - // node_modules/mdast-util-to-markdown/lib/util/format-heading-as-setext.js - function formatHeadingAsSetext(node2, state) { - let literalWithBreak = false; - visit(node2, function(node3) { - if ("value" in node3 && /\r?\n|\r/.test(node3.value) || node3.type === "break") { - literalWithBreak = true; - return EXIT; - } - }); - return Boolean( - (!node2.depth || node2.depth < 3) && toString(node2) && (state.options.setext || literalWithBreak) - ); - } - - // node_modules/mdast-util-to-markdown/lib/handle/heading.js - function heading(node2, _3, state, info) { - const rank = Math.max(Math.min(6, node2.depth || 1), 1); - const tracker = state.createTracker(info); - if (formatHeadingAsSetext(node2, state)) { - const exit4 = state.enter("headingSetext"); - const subexit2 = state.enter("phrasing"); - const value2 = state.containerPhrasing(node2, __spreadProps(__spreadValues({}, tracker.current()), { - before: "\n", - after: "\n" - })); - subexit2(); - exit4(); - return value2 + "\n" + (rank === 1 ? "=" : "-").repeat( - // The whole size… - value2.length - // Minus the position of the character after the last EOL (or - // 0 if there is none)… - (Math.max(value2.lastIndexOf("\r"), value2.lastIndexOf("\n")) + 1) - ); - } - const sequence = "#".repeat(rank); - const exit3 = state.enter("headingAtx"); - const subexit = state.enter("phrasing"); - tracker.move(sequence + " "); - let value = state.containerPhrasing(node2, __spreadValues({ - before: "# ", - after: "\n" - }, tracker.current())); - if (/^[\t ]/.test(value)) { - value = "&#x" + value.charCodeAt(0).toString(16).toUpperCase() + ";" + value.slice(1); - } - value = value ? sequence + " " + value : sequence; - if (state.options.closeAtx) { - value += " " + sequence; - } - subexit(); - exit3(); - return value; - } - - // node_modules/mdast-util-to-markdown/lib/handle/html.js - html.peek = htmlPeek; - function html(node2) { - return node2.value || ""; - } - function htmlPeek() { - return "<"; - } - - // node_modules/mdast-util-to-markdown/lib/handle/image.js - image.peek = imagePeek; - function image(node2, _3, state, info) { - const quote = checkQuote(state); - const suffix = quote === '"' ? "Quote" : "Apostrophe"; - const exit3 = state.enter("image"); - let subexit = state.enter("label"); - const tracker = state.createTracker(info); - let value = tracker.move("!["); - value += tracker.move( - state.safe(node2.alt, __spreadValues({ before: value, after: "]" }, tracker.current())) - ); - value += tracker.move("]("); - subexit(); - if ( - // If there’s no url but there is a title… - !node2.url && node2.title || // If there are control characters or whitespace. - /[\0- \u007F]/.test(node2.url) - ) { - subexit = state.enter("destinationLiteral"); - value += tracker.move("<"); - value += tracker.move( - state.safe(node2.url, __spreadValues({ before: value, after: ">" }, tracker.current())) - ); - value += tracker.move(">"); - } else { - subexit = state.enter("destinationRaw"); - value += tracker.move( - state.safe(node2.url, __spreadValues({ - before: value, - after: node2.title ? " " : ")" - }, tracker.current())) - ); - } - subexit(); - if (node2.title) { - subexit = state.enter(`title${suffix}`); - value += tracker.move(" " + quote); - value += tracker.move( - state.safe(node2.title, __spreadValues({ - before: value, - after: quote - }, tracker.current())) - ); - value += tracker.move(quote); - subexit(); - } - value += tracker.move(")"); - exit3(); - return value; - } - function imagePeek() { - return "!"; - } - - // node_modules/mdast-util-to-markdown/lib/handle/image-reference.js - imageReference.peek = imageReferencePeek; - function imageReference(node2, _3, state, info) { - const type = node2.referenceType; - const exit3 = state.enter("imageReference"); - let subexit = state.enter("label"); - const tracker = state.createTracker(info); - let value = tracker.move("!["); - const alt = state.safe(node2.alt, __spreadValues({ - before: value, - after: "]" - }, tracker.current())); - value += tracker.move(alt + "]["); - subexit(); - const stack = state.stack; - state.stack = []; - subexit = state.enter("reference"); - const reference = state.safe(state.associationId(node2), __spreadValues({ - before: value, - after: "]" - }, tracker.current())); - subexit(); - state.stack = stack; - exit3(); - if (type === "full" || !alt || alt !== reference) { - value += tracker.move(reference + "]"); - } else if (type === "shortcut") { - value = value.slice(0, -1); - } else { - value += tracker.move("]"); - } - return value; - } - function imageReferencePeek() { - return "!"; - } - - // node_modules/mdast-util-to-markdown/lib/handle/inline-code.js - inlineCode.peek = inlineCodePeek; - function inlineCode(node2, _3, state) { - let value = node2.value || ""; - let sequence = "`"; - let index2 = -1; - while (new RegExp("(^|[^`])" + sequence + "([^`]|$)").test(value)) { - sequence += "`"; - } - if (/[^ \r\n]/.test(value) && (/^[ \r\n]/.test(value) && /[ \r\n]$/.test(value) || /^`|`$/.test(value))) { - value = " " + value + " "; - } - while (++index2 < state.unsafe.length) { - const pattern = state.unsafe[index2]; - const expression = state.compilePattern(pattern); - let match; - if (!pattern.atBreak) continue; - while (match = expression.exec(value)) { - let position2 = match.index; - if (value.charCodeAt(position2) === 10 && value.charCodeAt(position2 - 1) === 13) { - position2--; - } - value = value.slice(0, position2) + " " + value.slice(match.index + 1); - } - } - return sequence + value + sequence; - } - function inlineCodePeek() { - return "`"; - } - - // node_modules/mdast-util-to-markdown/lib/util/format-link-as-autolink.js - function formatLinkAsAutolink(node2, state) { - const raw = toString(node2); - return Boolean( - !state.options.resourceLink && // If there’s a url… - node2.url && // And there’s a no title… - !node2.title && // And the content of `node` is a single text node… - node2.children && node2.children.length === 1 && node2.children[0].type === "text" && // And if the url is the same as the content… - (raw === node2.url || "mailto:" + raw === node2.url) && // And that starts w/ a protocol… - /^[a-z][a-z+.-]+:/i.test(node2.url) && // And that doesn’t contain ASCII control codes (character escapes and - // references don’t work), space, or angle brackets… - !/[\0- <>\u007F]/.test(node2.url) - ); - } - - // node_modules/mdast-util-to-markdown/lib/handle/link.js - link.peek = linkPeek; - function link(node2, _3, state, info) { - const quote = checkQuote(state); - const suffix = quote === '"' ? "Quote" : "Apostrophe"; - const tracker = state.createTracker(info); - let exit3; - let subexit; - if (formatLinkAsAutolink(node2, state)) { - const stack = state.stack; - state.stack = []; - exit3 = state.enter("autolink"); - let value2 = tracker.move("<"); - value2 += tracker.move( - state.containerPhrasing(node2, __spreadValues({ - before: value2, - after: ">" - }, tracker.current())) - ); - value2 += tracker.move(">"); - exit3(); - state.stack = stack; - return value2; - } - exit3 = state.enter("link"); - subexit = state.enter("label"); - let value = tracker.move("["); - value += tracker.move( - state.containerPhrasing(node2, __spreadValues({ - before: value, - after: "](" - }, tracker.current())) - ); - value += tracker.move("]("); - subexit(); - if ( - // If there’s no url but there is a title… - !node2.url && node2.title || // If there are control characters or whitespace. - /[\0- \u007F]/.test(node2.url) - ) { - subexit = state.enter("destinationLiteral"); - value += tracker.move("<"); - value += tracker.move( - state.safe(node2.url, __spreadValues({ before: value, after: ">" }, tracker.current())) - ); - value += tracker.move(">"); - } else { - subexit = state.enter("destinationRaw"); - value += tracker.move( - state.safe(node2.url, __spreadValues({ - before: value, - after: node2.title ? " " : ")" - }, tracker.current())) - ); - } - subexit(); - if (node2.title) { - subexit = state.enter(`title${suffix}`); - value += tracker.move(" " + quote); - value += tracker.move( - state.safe(node2.title, __spreadValues({ - before: value, - after: quote - }, tracker.current())) - ); - value += tracker.move(quote); - subexit(); - } - value += tracker.move(")"); - exit3(); - return value; - } - function linkPeek(node2, _3, state) { - return formatLinkAsAutolink(node2, state) ? "<" : "["; - } - - // node_modules/mdast-util-to-markdown/lib/handle/link-reference.js - linkReference.peek = linkReferencePeek; - function linkReference(node2, _3, state, info) { - const type = node2.referenceType; - const exit3 = state.enter("linkReference"); - let subexit = state.enter("label"); - const tracker = state.createTracker(info); - let value = tracker.move("["); - const text5 = state.containerPhrasing(node2, __spreadValues({ - before: value, - after: "]" - }, tracker.current())); - value += tracker.move(text5 + "]["); - subexit(); - const stack = state.stack; - state.stack = []; - subexit = state.enter("reference"); - const reference = state.safe(state.associationId(node2), __spreadValues({ - before: value, - after: "]" - }, tracker.current())); - subexit(); - state.stack = stack; - exit3(); - if (type === "full" || !text5 || text5 !== reference) { - value += tracker.move(reference + "]"); - } else if (type === "shortcut") { - value = value.slice(0, -1); - } else { - value += tracker.move("]"); - } - return value; - } - function linkReferencePeek() { - return "["; - } - - // node_modules/mdast-util-to-markdown/lib/util/check-bullet.js - function checkBullet(state) { - const marker = state.options.bullet || "*"; - if (marker !== "*" && marker !== "+" && marker !== "-") { - throw new Error( - "Cannot serialize items with `" + marker + "` for `options.bullet`, expected `*`, `+`, or `-`" - ); - } - return marker; - } - - // node_modules/mdast-util-to-markdown/lib/util/check-bullet-other.js - function checkBulletOther(state) { - const bullet = checkBullet(state); - const bulletOther = state.options.bulletOther; - if (!bulletOther) { - return bullet === "*" ? "-" : "*"; - } - if (bulletOther !== "*" && bulletOther !== "+" && bulletOther !== "-") { - throw new Error( - "Cannot serialize items with `" + bulletOther + "` for `options.bulletOther`, expected `*`, `+`, or `-`" - ); - } - if (bulletOther === bullet) { - throw new Error( - "Expected `bullet` (`" + bullet + "`) and `bulletOther` (`" + bulletOther + "`) to be different" - ); - } - return bulletOther; - } - - // node_modules/mdast-util-to-markdown/lib/util/check-bullet-ordered.js - function checkBulletOrdered(state) { - const marker = state.options.bulletOrdered || "."; - if (marker !== "." && marker !== ")") { - throw new Error( - "Cannot serialize items with `" + marker + "` for `options.bulletOrdered`, expected `.` or `)`" - ); - } - return marker; - } - - // node_modules/mdast-util-to-markdown/lib/util/check-rule.js - function checkRule(state) { - const marker = state.options.rule || "*"; - if (marker !== "*" && marker !== "-" && marker !== "_") { - throw new Error( - "Cannot serialize rules with `" + marker + "` for `options.rule`, expected `*`, `-`, or `_`" - ); - } - return marker; - } - - // node_modules/mdast-util-to-markdown/lib/handle/list.js - function list3(node2, parent, state, info) { - const exit3 = state.enter("list"); - const bulletCurrent = state.bulletCurrent; - let bullet = node2.ordered ? checkBulletOrdered(state) : checkBullet(state); - const bulletOther = node2.ordered ? bullet === "." ? ")" : "." : checkBulletOther(state); - let useDifferentMarker = parent && state.bulletLastUsed ? bullet === state.bulletLastUsed : false; - if (!node2.ordered) { - const firstListItem = node2.children ? node2.children[0] : void 0; - if ( - // Bullet could be used as a thematic break marker: - (bullet === "*" || bullet === "-") && // Empty first list item: - firstListItem && (!firstListItem.children || !firstListItem.children[0]) && // Directly in two other list items: - state.stack[state.stack.length - 1] === "list" && state.stack[state.stack.length - 2] === "listItem" && state.stack[state.stack.length - 3] === "list" && state.stack[state.stack.length - 4] === "listItem" && // That are each the first child. - state.indexStack[state.indexStack.length - 1] === 0 && state.indexStack[state.indexStack.length - 2] === 0 && state.indexStack[state.indexStack.length - 3] === 0 - ) { - useDifferentMarker = true; - } - if (checkRule(state) === bullet && firstListItem) { - let index2 = -1; - while (++index2 < node2.children.length) { - const item = node2.children[index2]; - if (item && item.type === "listItem" && item.children && item.children[0] && item.children[0].type === "thematicBreak") { - useDifferentMarker = true; - break; - } - } - } - } - if (useDifferentMarker) { - bullet = bulletOther; - } - state.bulletCurrent = bullet; - const value = state.containerFlow(node2, info); - state.bulletLastUsed = bullet; - state.bulletCurrent = bulletCurrent; - exit3(); - return value; - } - - // node_modules/mdast-util-to-markdown/lib/util/check-list-item-indent.js - function checkListItemIndent(state) { - const style2 = state.options.listItemIndent || "one"; - if (style2 !== "tab" && style2 !== "one" && style2 !== "mixed") { - throw new Error( - "Cannot serialize items with `" + style2 + "` for `options.listItemIndent`, expected `tab`, `one`, or `mixed`" - ); - } - return style2; - } - - // node_modules/mdast-util-to-markdown/lib/handle/list-item.js - function listItem(node2, parent, state, info) { - const listItemIndent = checkListItemIndent(state); - let bullet = state.bulletCurrent || checkBullet(state); - if (parent && parent.type === "list" && parent.ordered) { - bullet = (typeof parent.start === "number" && parent.start > -1 ? parent.start : 1) + (state.options.incrementListMarker === false ? 0 : parent.children.indexOf(node2)) + bullet; - } - let size = bullet.length + 1; - if (listItemIndent === "tab" || listItemIndent === "mixed" && (parent && parent.type === "list" && parent.spread || node2.spread)) { - size = Math.ceil(size / 4) * 4; - } - const tracker = state.createTracker(info); - tracker.move(bullet + " ".repeat(size - bullet.length)); - tracker.shift(size); - const exit3 = state.enter("listItem"); - const value = state.indentLines( - state.containerFlow(node2, tracker.current()), - map5 - ); - exit3(); - return value; - function map5(line, index2, blank) { - if (index2) { - return (blank ? "" : " ".repeat(size)) + line; - } - return (blank ? bullet : bullet + " ".repeat(size - bullet.length)) + line; - } - } - - // node_modules/mdast-util-to-markdown/lib/handle/paragraph.js - function paragraph(node2, _3, state, info) { - const exit3 = state.enter("paragraph"); - const subexit = state.enter("phrasing"); - const value = state.containerPhrasing(node2, info); - subexit(); - exit3(); - return value; - } - - // node_modules/mdast-util-phrasing/lib/index.js - var phrasing = ( - /** @type {(node?: unknown) => node is Exclude} */ - convert([ - "break", - "delete", - "emphasis", - // To do: next major: removed since footnotes were added to GFM. - "footnote", - "footnoteReference", - "image", - "imageReference", - "inlineCode", - // Enabled by `mdast-util-math`: - "inlineMath", - "link", - "linkReference", - // Enabled by `mdast-util-mdx`: - "mdxJsxTextElement", - // Enabled by `mdast-util-mdx`: - "mdxTextExpression", - "strong", - "text", - // Enabled by `mdast-util-directive`: - "textDirective" - ]) - ); - - // node_modules/mdast-util-to-markdown/lib/handle/root.js - function root(node2, _3, state, info) { - const hasPhrasing = node2.children.some(function(d6) { - return phrasing(d6); - }); - const fn = hasPhrasing ? state.containerPhrasing : state.containerFlow; - return fn.call(state, node2, info); - } - - // node_modules/mdast-util-to-markdown/lib/util/check-strong.js - function checkStrong(state) { - const marker = state.options.strong || "*"; - if (marker !== "*" && marker !== "_") { - throw new Error( - "Cannot serialize strong with `" + marker + "` for `options.strong`, expected `*`, or `_`" - ); - } - return marker; - } - - // node_modules/mdast-util-to-markdown/lib/handle/strong.js - strong.peek = strongPeek; - function strong(node2, _3, state, info) { - const marker = checkStrong(state); - const exit3 = state.enter("strong"); - const tracker = state.createTracker(info); - let value = tracker.move(marker + marker); - value += tracker.move( - state.containerPhrasing(node2, __spreadValues({ - before: value, - after: marker - }, tracker.current())) - ); - value += tracker.move(marker + marker); - exit3(); - return value; - } - function strongPeek(_3, _1, state) { - return state.options.strong || "*"; - } - - // node_modules/mdast-util-to-markdown/lib/handle/text.js - function text3(node2, _3, state, info) { - return state.safe(node2.value, info); - } - - // node_modules/mdast-util-to-markdown/lib/util/check-rule-repetition.js - function checkRuleRepetition(state) { - const repetition = state.options.ruleRepetition || 3; - if (repetition < 3) { - throw new Error( - "Cannot serialize rules with repetition `" + repetition + "` for `options.ruleRepetition`, expected `3` or more" - ); - } - return repetition; - } - - // node_modules/mdast-util-to-markdown/lib/handle/thematic-break.js - function thematicBreak2(_3, _1, state) { - const value = (checkRule(state) + (state.options.ruleSpaces ? " " : "")).repeat(checkRuleRepetition(state)); - return state.options.ruleSpaces ? value.slice(0, -1) : value; - } - - // node_modules/mdast-util-to-markdown/lib/handle/index.js - var handle = { - blockquote, - break: hardBreak, - code, - definition: definition2, - emphasis, - hardBreak, - heading, - html, - image, - imageReference, - inlineCode, - link, - linkReference, - list: list3, - listItem, - paragraph, - root, - strong, - text: text3, - thematicBreak: thematicBreak2 - }; - - // node_modules/mdast-util-to-markdown/lib/join.js - var join = [joinDefaults]; - function joinDefaults(left, right, parent, state) { - if (right.type === "code" && formatCodeAsIndented(right, state) && (left.type === "list" || left.type === right.type && formatCodeAsIndented(left, state))) { - return false; - } - if ("spread" in parent && typeof parent.spread === "boolean") { - if (left.type === "paragraph" && // Two paragraphs. - (left.type === right.type || right.type === "definition" || // Paragraph followed by a setext heading. - right.type === "heading" && formatHeadingAsSetext(right, state))) { - return; - } - return parent.spread ? 1 : 0; - } - } - - // node_modules/mdast-util-to-markdown/lib/unsafe.js - var fullPhrasingSpans = [ - "autolink", - "destinationLiteral", - "destinationRaw", - "reference", - "titleQuote", - "titleApostrophe" - ]; - var unsafe = [ - { character: " ", after: "[\\r\\n]", inConstruct: "phrasing" }, - { character: " ", before: "[\\r\\n]", inConstruct: "phrasing" }, - { - character: " ", - inConstruct: ["codeFencedLangGraveAccent", "codeFencedLangTilde"] - }, - { - character: "\r", - inConstruct: [ - "codeFencedLangGraveAccent", - "codeFencedLangTilde", - "codeFencedMetaGraveAccent", - "codeFencedMetaTilde", - "destinationLiteral", - "headingAtx" - ] - }, - { - character: "\n", - inConstruct: [ - "codeFencedLangGraveAccent", - "codeFencedLangTilde", - "codeFencedMetaGraveAccent", - "codeFencedMetaTilde", - "destinationLiteral", - "headingAtx" - ] - }, - { character: " ", after: "[\\r\\n]", inConstruct: "phrasing" }, - { character: " ", before: "[\\r\\n]", inConstruct: "phrasing" }, - { - character: " ", - inConstruct: ["codeFencedLangGraveAccent", "codeFencedLangTilde"] - }, - // An exclamation mark can start an image, if it is followed by a link or - // a link reference. - { - character: "!", - after: "\\[", - inConstruct: "phrasing", - notInConstruct: fullPhrasingSpans - }, - // A quote can break out of a title. - { character: '"', inConstruct: "titleQuote" }, - // A number sign could start an ATX heading if it starts a line. - { atBreak: true, character: "#" }, - { character: "#", inConstruct: "headingAtx", after: "(?:[\r\n]|$)" }, - // Dollar sign and percentage are not used in markdown. - // An ampersand could start a character reference. - { character: "&", after: "[#A-Za-z]", inConstruct: "phrasing" }, - // An apostrophe can break out of a title. - { character: "'", inConstruct: "titleApostrophe" }, - // A left paren could break out of a destination raw. - { character: "(", inConstruct: "destinationRaw" }, - // A left paren followed by `]` could make something into a link or image. - { - before: "\\]", - character: "(", - inConstruct: "phrasing", - notInConstruct: fullPhrasingSpans - }, - // A right paren could start a list item or break out of a destination - // raw. - { atBreak: true, before: "\\d+", character: ")" }, - { character: ")", inConstruct: "destinationRaw" }, - // An asterisk can start thematic breaks, list items, emphasis, strong. - { atBreak: true, character: "*", after: "(?:[ \r\n*])" }, - { character: "*", inConstruct: "phrasing", notInConstruct: fullPhrasingSpans }, - // A plus sign could start a list item. - { atBreak: true, character: "+", after: "(?:[ \r\n])" }, - // A dash can start thematic breaks, list items, and setext heading - // underlines. - { atBreak: true, character: "-", after: "(?:[ \r\n-])" }, - // A dot could start a list item. - { atBreak: true, before: "\\d+", character: ".", after: "(?:[ \r\n]|$)" }, - // Slash, colon, and semicolon are not used in markdown for constructs. - // A less than can start html (flow or text) or an autolink. - // HTML could start with an exclamation mark (declaration, cdata, comment), - // slash (closing tag), question mark (instruction), or a letter (tag). - // An autolink also starts with a letter. - // Finally, it could break out of a destination literal. - { atBreak: true, character: "<", after: "[!/?A-Za-z]" }, - { - character: "<", - after: "[!/?A-Za-z]", - inConstruct: "phrasing", - notInConstruct: fullPhrasingSpans - }, - { character: "<", inConstruct: "destinationLiteral" }, - // An equals to can start setext heading underlines. - { atBreak: true, character: "=" }, - // A greater than can start block quotes and it can break out of a - // destination literal. - { atBreak: true, character: ">" }, - { character: ">", inConstruct: "destinationLiteral" }, - // Question mark and at sign are not used in markdown for constructs. - // A left bracket can start definitions, references, labels, - { atBreak: true, character: "[" }, - { character: "[", inConstruct: "phrasing", notInConstruct: fullPhrasingSpans }, - { character: "[", inConstruct: ["label", "reference"] }, - // A backslash can start an escape (when followed by punctuation) or a - // hard break (when followed by an eol). - // Note: typical escapes are handled in `safe`! - { character: "\\", after: "[\\r\\n]", inConstruct: "phrasing" }, - // A right bracket can exit labels. - { character: "]", inConstruct: ["label", "reference"] }, - // Caret is not used in markdown for constructs. - // An underscore can start emphasis, strong, or a thematic break. - { atBreak: true, character: "_" }, - { character: "_", inConstruct: "phrasing", notInConstruct: fullPhrasingSpans }, - // A grave accent can start code (fenced or text), or it can break out of - // a grave accent code fence. - { atBreak: true, character: "`" }, - { - character: "`", - inConstruct: ["codeFencedLangGraveAccent", "codeFencedMetaGraveAccent"] - }, - { character: "`", inConstruct: "phrasing", notInConstruct: fullPhrasingSpans }, - // Left brace, vertical bar, right brace are not used in markdown for - // constructs. - // A tilde can start code (fenced). - { atBreak: true, character: "~" } - ]; - - // node_modules/mdast-util-to-markdown/lib/util/association.js - function association(node2) { - if (node2.label || !node2.identifier) { - return node2.label || ""; - } - return decodeString(node2.identifier); - } - - // node_modules/mdast-util-to-markdown/lib/util/compile-pattern.js - function compilePattern(pattern) { - if (!pattern._compiled) { - const before = (pattern.atBreak ? "[\\r\\n][\\t ]*" : "") + (pattern.before ? "(?:" + pattern.before + ")" : ""); - pattern._compiled = new RegExp( - (before ? "(" + before + ")" : "") + (/[|\\{}()[\]^$+*?.-]/.test(pattern.character) ? "\\" : "") + pattern.character + (pattern.after ? "(?:" + pattern.after + ")" : ""), - "g" - ); - } - return pattern._compiled; - } - - // node_modules/mdast-util-to-markdown/lib/util/container-phrasing.js - function containerPhrasing(parent, state, info) { - const indexStack = state.indexStack; - const children = parent.children || []; - const results = []; - let index2 = -1; - let before = info.before; - indexStack.push(-1); - let tracker = state.createTracker(info); - while (++index2 < children.length) { - const child = children[index2]; - let after; - indexStack[indexStack.length - 1] = index2; - if (index2 + 1 < children.length) { - let handle2 = state.handle.handlers[children[index2 + 1].type]; - if (handle2 && handle2.peek) handle2 = handle2.peek; - after = handle2 ? handle2(children[index2 + 1], parent, state, __spreadValues({ - before: "", - after: "" - }, tracker.current())).charAt(0) : ""; - } else { - after = info.after; - } - if (results.length > 0 && (before === "\r" || before === "\n") && child.type === "html") { - results[results.length - 1] = results[results.length - 1].replace( - /(\r?\n|\r)$/, - " " - ); - before = " "; - tracker = state.createTracker(info); - tracker.move(results.join("")); - } - results.push( - tracker.move( - state.handle(child, parent, state, __spreadProps(__spreadValues({}, tracker.current()), { - before, - after - })) - ) - ); - before = results[results.length - 1].slice(-1); - } - indexStack.pop(); - return results.join(""); - } - - // node_modules/mdast-util-to-markdown/lib/util/container-flow.js - function containerFlow(parent, state, info) { - const indexStack = state.indexStack; - const children = parent.children || []; - const tracker = state.createTracker(info); - const results = []; - let index2 = -1; - indexStack.push(-1); - while (++index2 < children.length) { - const child = children[index2]; - indexStack[indexStack.length - 1] = index2; - results.push( - tracker.move( - state.handle(child, parent, state, __spreadValues({ - before: "\n", - after: "\n" - }, tracker.current())) - ) - ); - if (child.type !== "list") { - state.bulletLastUsed = void 0; - } - if (index2 < children.length - 1) { - results.push( - tracker.move(between(child, children[index2 + 1], parent, state)) - ); - } - } - indexStack.pop(); - return results.join(""); - } - function between(left, right, parent, state) { - let index2 = state.join.length; - while (index2--) { - const result = state.join[index2](left, right, parent, state); - if (result === true || result === 1) { - break; - } - if (typeof result === "number") { - return "\n".repeat(1 + result); - } - if (result === false) { - return "\n\n\n\n"; - } - } - return "\n\n"; - } - - // node_modules/mdast-util-to-markdown/lib/util/indent-lines.js - var eol = /\r?\n|\r/g; - function indentLines(value, map5) { - const result = []; - let start = 0; - let line = 0; - let match; - while (match = eol.exec(value)) { - one2(value.slice(start, match.index)); - result.push(match[0]); - start = match.index + match[0].length; - line++; - } - one2(value.slice(start)); - return result.join(""); - function one2(value2) { - result.push(map5(value2, line, !value2)); - } - } - - // node_modules/mdast-util-to-markdown/lib/util/safe.js - function safe(state, input, config) { - const value = (config.before || "") + (input || "") + (config.after || ""); - const positions = []; - const result = []; - const infos = {}; - let index2 = -1; - while (++index2 < state.unsafe.length) { - const pattern = state.unsafe[index2]; - if (!patternInScope(state.stack, pattern)) { - continue; - } - const expression = state.compilePattern(pattern); - let match; - while (match = expression.exec(value)) { - const before = "before" in pattern || Boolean(pattern.atBreak); - const after = "after" in pattern; - const position2 = match.index + (before ? match[1].length : 0); - if (positions.includes(position2)) { - if (infos[position2].before && !before) { - infos[position2].before = false; - } - if (infos[position2].after && !after) { - infos[position2].after = false; - } - } else { - positions.push(position2); - infos[position2] = { before, after }; - } - } - } - positions.sort(numerical); - let start = config.before ? config.before.length : 0; - const end = value.length - (config.after ? config.after.length : 0); - index2 = -1; - while (++index2 < positions.length) { - const position2 = positions[index2]; - if (position2 < start || position2 >= end) { - continue; - } - if (position2 + 1 < end && positions[index2 + 1] === position2 + 1 && infos[position2].after && !infos[position2 + 1].before && !infos[position2 + 1].after || positions[index2 - 1] === position2 - 1 && infos[position2].before && !infos[position2 - 1].before && !infos[position2 - 1].after) { - continue; - } - if (start !== position2) { - result.push(escapeBackslashes(value.slice(start, position2), "\\")); - } - start = position2; - if (/[!-/:-@[-`{-~]/.test(value.charAt(position2)) && (!config.encode || !config.encode.includes(value.charAt(position2)))) { - result.push("\\"); - } else { - result.push( - "&#x" + value.charCodeAt(position2).toString(16).toUpperCase() + ";" - ); - start++; - } - } - result.push(escapeBackslashes(value.slice(start, end), config.after)); - return result.join(""); - } - function numerical(a2, b4) { - return a2 - b4; - } - function escapeBackslashes(value, after) { - const expression = /\\(?=[!-/:-@[-`{-~])/g; - const positions = []; - const results = []; - const whole = value + after; - let index2 = -1; - let start = 0; - let match; - while (match = expression.exec(whole)) { - positions.push(match.index); - } - while (++index2 < positions.length) { - if (start !== positions[index2]) { - results.push(value.slice(start, positions[index2])); - } - results.push("\\"); - start = positions[index2]; - } - results.push(value.slice(start)); - return results.join(""); - } - - // node_modules/mdast-util-to-markdown/lib/util/track.js - function track(config) { - const options2 = config || {}; - const now = options2.now || {}; - let lineShift = options2.lineShift || 0; - let line = now.line || 1; - let column = now.column || 1; - return { move, current, shift: shift2 }; - function current() { - return { now: { line, column }, lineShift }; - } - function shift2(value) { - lineShift += value; - } - function move(input) { - const value = input || ""; - const chunks = value.split(/\r?\n|\r/g); - const tail = chunks[chunks.length - 1]; - line += chunks.length - 1; - column = chunks.length === 1 ? column + tail.length : 1 + tail.length + lineShift; - return value; - } - } - - // node_modules/mdast-util-to-markdown/lib/index.js - function toMarkdown(tree, options2 = {}) { - const state = { - enter, - indentLines, - associationId: association, - containerPhrasing: containerPhrasingBound, - containerFlow: containerFlowBound, - createTracker: track, - compilePattern, - safe: safeBound, - stack: [], - unsafe: [...unsafe], - join: [...join], - // @ts-expect-error: GFM / frontmatter are typed in `mdast` but not defined - // here. - handlers: __spreadValues({}, handle), - options: {}, - indexStack: [], - // @ts-expect-error: add `handle` in a second. - handle: void 0 - }; - configure2(state, options2); - if (state.options.tightDefinitions) { - state.join.push(joinDefinition); - } - state.handle = zwitch("type", { - invalid, - unknown, - handlers: state.handlers - }); - let result = state.handle(tree, void 0, state, { - before: "\n", - after: "\n", - now: { line: 1, column: 1 }, - lineShift: 0 - }); - if (result && result.charCodeAt(result.length - 1) !== 10 && result.charCodeAt(result.length - 1) !== 13) { - result += "\n"; - } - return result; - function enter(name) { - state.stack.push(name); - return exit3; - function exit3() { - state.stack.pop(); - } - } - } - function invalid(value) { - throw new Error("Cannot handle value `" + value + "`, expected node"); - } - function unknown(value) { - const node2 = ( - /** @type {Nodes} */ - value - ); - throw new Error("Cannot handle unknown node `" + node2.type + "`"); - } - function joinDefinition(left, right) { - if (left.type === "definition" && left.type === right.type) { - return 0; - } - } - function containerPhrasingBound(parent, info) { - return containerPhrasing(parent, this, info); - } - function containerFlowBound(parent, info) { - return containerFlow(parent, this, info); - } - function safeBound(value, config) { - return safe(this, value, config); - } - - // node_modules/remark-stringify/lib/index.js - function remarkStringify(options2) { - const self2 = this; - self2.compiler = compiler2; - function compiler2(tree) { - return toMarkdown(tree, __spreadProps(__spreadValues(__spreadValues({}, self2.data("settings")), options2), { - // Note: this option is not in the readme. - // The goal is for it to be set by plugins on `data` instead of being - // passed by users. - extensions: self2.data("toMarkdownExtensions") || [] - })); - } - } - - // node_modules/bail/index.js - function bail(error) { - if (error) { - throw error; - } - } - - // node_modules/unified/lib/index.js - var import_extend = __toESM(require_extend(), 1); - - // node_modules/devlop/lib/default.js - function ok2() { - } - - // node_modules/is-plain-obj/index.js - function isPlainObject(value) { - if (typeof value !== "object" || value === null) { - return false; - } - const prototype = Object.getPrototypeOf(value); - return (prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null) && !(Symbol.toStringTag in value) && !(Symbol.iterator in value); - } - - // node_modules/trough/lib/index.js - function trough() { - const fns = []; - const pipeline = { run: run2, use }; - return pipeline; - function run2(...values) { - let middlewareIndex = -1; - const callback = values.pop(); - if (typeof callback !== "function") { - throw new TypeError("Expected function as last argument, not " + callback); - } - next(null, ...values); - function next(error, ...output) { - const fn = fns[++middlewareIndex]; - let index2 = -1; - if (error) { - callback(error); - return; - } - while (++index2 < values.length) { - if (output[index2] === null || output[index2] === void 0) { - output[index2] = values[index2]; - } - } - values = output; - if (fn) { - wrap(fn, next)(...output); - } else { - callback(null, ...output); - } - } - } - function use(middelware) { - if (typeof middelware !== "function") { - throw new TypeError( - "Expected `middelware` to be a function, not " + middelware - ); - } - fns.push(middelware); - return pipeline; - } - } - function wrap(middleware, callback) { - let called; - return wrapped; - function wrapped(...parameters) { - const fnExpectsCallback = middleware.length > parameters.length; - let result; - if (fnExpectsCallback) { - parameters.push(done); - } - try { - result = middleware.apply(this, parameters); - } catch (error) { - const exception = ( - /** @type {Error} */ - error - ); - if (fnExpectsCallback && called) { - throw exception; - } - return done(exception); - } - if (!fnExpectsCallback) { - if (result && result.then && typeof result.then === "function") { - result.then(then, done); - } else if (result instanceof Error) { - done(result); - } else { - then(result); - } - } - } - function done(error, ...output) { - if (!called) { - called = true; - callback(error, ...output); - } - } - function then(value) { - done(null, value); - } - } - - // node_modules/vfile-message/lib/index.js - var VFileMessage = class extends Error { - /** - * Create a message for `reason`. - * - * > 🪦 **Note**: also has obsolete signatures. - * - * @overload - * @param {string} reason - * @param {Options | null | undefined} [options] - * @returns - * - * @overload - * @param {string} reason - * @param {Node | NodeLike | null | undefined} parent - * @param {string | null | undefined} [origin] - * @returns - * - * @overload - * @param {string} reason - * @param {Point | Position | null | undefined} place - * @param {string | null | undefined} [origin] - * @returns - * - * @overload - * @param {string} reason - * @param {string | null | undefined} [origin] - * @returns - * - * @overload - * @param {Error | VFileMessage} cause - * @param {Node | NodeLike | null | undefined} parent - * @param {string | null | undefined} [origin] - * @returns - * - * @overload - * @param {Error | VFileMessage} cause - * @param {Point | Position | null | undefined} place - * @param {string | null | undefined} [origin] - * @returns - * - * @overload - * @param {Error | VFileMessage} cause - * @param {string | null | undefined} [origin] - * @returns - * - * @param {Error | VFileMessage | string} causeOrReason - * Reason for message, should use markdown. - * @param {Node | NodeLike | Options | Point | Position | string | null | undefined} [optionsOrParentOrPlace] - * Configuration (optional). - * @param {string | null | undefined} [origin] - * Place in code where the message originates (example: - * `'my-package:my-rule'` or `'my-rule'`). - * @returns - * Instance of `VFileMessage`. - */ - // eslint-disable-next-line complexity - constructor(causeOrReason, optionsOrParentOrPlace, origin) { - super(); - if (typeof optionsOrParentOrPlace === "string") { - origin = optionsOrParentOrPlace; - optionsOrParentOrPlace = void 0; - } - let reason = ""; - let options2 = {}; - let legacyCause = false; - if (optionsOrParentOrPlace) { - if ("line" in optionsOrParentOrPlace && "column" in optionsOrParentOrPlace) { - options2 = { place: optionsOrParentOrPlace }; - } else if ("start" in optionsOrParentOrPlace && "end" in optionsOrParentOrPlace) { - options2 = { place: optionsOrParentOrPlace }; - } else if ("type" in optionsOrParentOrPlace) { - options2 = { - ancestors: [optionsOrParentOrPlace], - place: optionsOrParentOrPlace.position - }; - } else { - options2 = __spreadValues({}, optionsOrParentOrPlace); - } - } - if (typeof causeOrReason === "string") { - reason = causeOrReason; - } else if (!options2.cause && causeOrReason) { - legacyCause = true; - reason = causeOrReason.message; - options2.cause = causeOrReason; - } - if (!options2.ruleId && !options2.source && typeof origin === "string") { - const index2 = origin.indexOf(":"); - if (index2 === -1) { - options2.ruleId = origin; - } else { - options2.source = origin.slice(0, index2); - options2.ruleId = origin.slice(index2 + 1); - } - } - if (!options2.place && options2.ancestors && options2.ancestors) { - const parent = options2.ancestors[options2.ancestors.length - 1]; - if (parent) { - options2.place = parent.position; - } - } - const start = options2.place && "start" in options2.place ? options2.place.start : options2.place; - this.ancestors = options2.ancestors || void 0; - this.cause = options2.cause || void 0; - this.column = start ? start.column : void 0; - this.fatal = void 0; - this.file; - this.message = reason; - this.line = start ? start.line : void 0; - this.name = stringifyPosition(options2.place) || "1:1"; - this.place = options2.place || void 0; - this.reason = this.message; - this.ruleId = options2.ruleId || void 0; - this.source = options2.source || void 0; - this.stack = legacyCause && options2.cause && typeof options2.cause.stack === "string" ? options2.cause.stack : ""; - this.actual; - this.expected; - this.note; - this.url; - } - }; - VFileMessage.prototype.file = ""; - VFileMessage.prototype.name = ""; - VFileMessage.prototype.reason = ""; - VFileMessage.prototype.message = ""; - VFileMessage.prototype.stack = ""; - VFileMessage.prototype.column = void 0; - VFileMessage.prototype.line = void 0; - VFileMessage.prototype.ancestors = void 0; - VFileMessage.prototype.cause = void 0; - VFileMessage.prototype.fatal = void 0; - VFileMessage.prototype.place = void 0; - VFileMessage.prototype.ruleId = void 0; - VFileMessage.prototype.source = void 0; - - // node_modules/vfile/lib/minpath.browser.js - var path = { basename, dirname, extname, join: join2, sep: "/" }; - function basename(path3, ext) { - if (ext !== void 0 && typeof ext !== "string") { - throw new TypeError('"ext" argument must be a string'); - } - assertPath(path3); - let start = 0; - let end = -1; - let index2 = path3.length; - let seenNonSlash; - if (ext === void 0 || ext.length === 0 || ext.length > path3.length) { - while (index2--) { - if (path3.codePointAt(index2) === 47) { - if (seenNonSlash) { - start = index2 + 1; - break; - } - } else if (end < 0) { - seenNonSlash = true; - end = index2 + 1; - } - } - return end < 0 ? "" : path3.slice(start, end); - } - if (ext === path3) { - return ""; - } - let firstNonSlashEnd = -1; - let extIndex = ext.length - 1; - while (index2--) { - if (path3.codePointAt(index2) === 47) { - if (seenNonSlash) { - start = index2 + 1; - break; - } - } else { - if (firstNonSlashEnd < 0) { - seenNonSlash = true; - firstNonSlashEnd = index2 + 1; - } - if (extIndex > -1) { - if (path3.codePointAt(index2) === ext.codePointAt(extIndex--)) { - if (extIndex < 0) { - end = index2; - } - } else { - extIndex = -1; - end = firstNonSlashEnd; - } - } - } - } - if (start === end) { - end = firstNonSlashEnd; - } else if (end < 0) { - end = path3.length; - } - return path3.slice(start, end); - } - function dirname(path3) { - assertPath(path3); - if (path3.length === 0) { - return "."; - } - let end = -1; - let index2 = path3.length; - let unmatchedSlash; - while (--index2) { - if (path3.codePointAt(index2) === 47) { - if (unmatchedSlash) { - end = index2; - break; - } - } else if (!unmatchedSlash) { - unmatchedSlash = true; - } - } - return end < 0 ? path3.codePointAt(0) === 47 ? "/" : "." : end === 1 && path3.codePointAt(0) === 47 ? "//" : path3.slice(0, end); - } - function extname(path3) { - assertPath(path3); - let index2 = path3.length; - let end = -1; - let startPart = 0; - let startDot = -1; - let preDotState = 0; - let unmatchedSlash; - while (index2--) { - const code3 = path3.codePointAt(index2); - if (code3 === 47) { - if (unmatchedSlash) { - startPart = index2 + 1; - break; - } - continue; - } - if (end < 0) { - unmatchedSlash = true; - end = index2 + 1; - } - if (code3 === 46) { - if (startDot < 0) { - startDot = index2; - } else if (preDotState !== 1) { - preDotState = 1; - } - } else if (startDot > -1) { - preDotState = -1; - } - } - if (startDot < 0 || end < 0 || // We saw a non-dot character immediately before the dot. - preDotState === 0 || // The (right-most) trimmed path component is exactly `..`. - preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) { - return ""; - } - return path3.slice(startDot, end); - } - function join2(...segments) { - let index2 = -1; - let joined; - while (++index2 < segments.length) { - assertPath(segments[index2]); - if (segments[index2]) { - joined = joined === void 0 ? segments[index2] : joined + "/" + segments[index2]; - } - } - return joined === void 0 ? "." : normalize(joined); - } - function normalize(path3) { - assertPath(path3); - const absolute = path3.codePointAt(0) === 47; - let value = normalizeString(path3, !absolute); - if (value.length === 0 && !absolute) { - value = "."; - } - if (value.length > 0 && path3.codePointAt(path3.length - 1) === 47) { - value += "/"; - } - return absolute ? "/" + value : value; - } - function normalizeString(path3, allowAboveRoot) { - let result = ""; - let lastSegmentLength = 0; - let lastSlash = -1; - let dots = 0; - let index2 = -1; - let code3; - let lastSlashIndex; - while (++index2 <= path3.length) { - if (index2 < path3.length) { - code3 = path3.codePointAt(index2); - } else if (code3 === 47) { - break; - } else { - code3 = 47; - } - if (code3 === 47) { - if (lastSlash === index2 - 1 || dots === 1) { - } else if (lastSlash !== index2 - 1 && dots === 2) { - if (result.length < 2 || lastSegmentLength !== 2 || result.codePointAt(result.length - 1) !== 46 || result.codePointAt(result.length - 2) !== 46) { - if (result.length > 2) { - lastSlashIndex = result.lastIndexOf("/"); - if (lastSlashIndex !== result.length - 1) { - if (lastSlashIndex < 0) { - result = ""; - lastSegmentLength = 0; - } else { - result = result.slice(0, lastSlashIndex); - lastSegmentLength = result.length - 1 - result.lastIndexOf("/"); - } - lastSlash = index2; - dots = 0; - continue; - } - } else if (result.length > 0) { - result = ""; - lastSegmentLength = 0; - lastSlash = index2; - dots = 0; - continue; - } - } - if (allowAboveRoot) { - result = result.length > 0 ? result + "/.." : ".."; - lastSegmentLength = 2; - } - } else { - if (result.length > 0) { - result += "/" + path3.slice(lastSlash + 1, index2); - } else { - result = path3.slice(lastSlash + 1, index2); - } - lastSegmentLength = index2 - lastSlash - 1; - } - lastSlash = index2; - dots = 0; - } else if (code3 === 46 && dots > -1) { - dots++; - } else { - dots = -1; - } - } - return result; - } - function assertPath(path3) { - if (typeof path3 !== "string") { - throw new TypeError( - "Path must be a string. Received " + JSON.stringify(path3) - ); - } - } - - // node_modules/vfile/lib/minproc.browser.js - var proc = { cwd }; - function cwd() { - return "/"; - } - - // node_modules/vfile/lib/minurl.shared.js - function isUrl(fileUrlOrPath) { - return Boolean( - fileUrlOrPath !== null && typeof fileUrlOrPath === "object" && "href" in fileUrlOrPath && fileUrlOrPath.href && "protocol" in fileUrlOrPath && fileUrlOrPath.protocol && // @ts-expect-error: indexing is fine. - fileUrlOrPath.auth === void 0 - ); - } - - // node_modules/vfile/lib/minurl.browser.js - function urlToPath(path3) { - if (typeof path3 === "string") { - path3 = new URL(path3); - } else if (!isUrl(path3)) { - const error = new TypeError( - 'The "path" argument must be of type string or an instance of URL. Received `' + path3 + "`" - ); - error.code = "ERR_INVALID_ARG_TYPE"; - throw error; - } - if (path3.protocol !== "file:") { - const error = new TypeError("The URL must be of scheme file"); - error.code = "ERR_INVALID_URL_SCHEME"; - throw error; - } - return getPathFromURLPosix(path3); - } - function getPathFromURLPosix(url) { - if (url.hostname !== "") { - const error = new TypeError( - 'File URL host must be "localhost" or empty on darwin' - ); - error.code = "ERR_INVALID_FILE_URL_HOST"; - throw error; - } - const pathname = url.pathname; - let index2 = -1; - while (++index2 < pathname.length) { - if (pathname.codePointAt(index2) === 37 && pathname.codePointAt(index2 + 1) === 50) { - const third = pathname.codePointAt(index2 + 2); - if (third === 70 || third === 102) { - const error = new TypeError( - "File URL path must not include encoded / characters" - ); - error.code = "ERR_INVALID_FILE_URL_PATH"; - throw error; - } - } - } - return decodeURIComponent(pathname); - } - - // node_modules/vfile/lib/index.js - var order = ( - /** @type {const} */ - [ - "history", - "path", - "basename", - "stem", - "extname", - "dirname" - ] - ); - var VFile = class { - /** - * Create a new virtual file. - * - * `options` is treated as: - * - * * `string` or `Uint8Array` — `{value: options}` - * * `URL` — `{path: options}` - * * `VFile` — shallow copies its data over to the new file - * * `object` — all fields are shallow copied over to the new file - * - * Path related fields are set in the following order (least specific to - * most specific): `history`, `path`, `basename`, `stem`, `extname`, - * `dirname`. - * - * You cannot set `dirname` or `extname` without setting either `history`, - * `path`, `basename`, or `stem` too. - * - * @param {Compatible | null | undefined} [value] - * File value. - * @returns - * New instance. - */ - constructor(value) { - let options2; - if (!value) { - options2 = {}; - } else if (isUrl(value)) { - options2 = { path: value }; - } else if (typeof value === "string" || isUint8Array(value)) { - options2 = { value }; - } else { - options2 = value; - } - this.cwd = proc.cwd(); - this.data = {}; - this.history = []; - this.messages = []; - this.value; - this.map; - this.result; - this.stored; - let index2 = -1; - while (++index2 < order.length) { - const prop2 = order[index2]; - if (prop2 in options2 && options2[prop2] !== void 0 && options2[prop2] !== null) { - this[prop2] = prop2 === "history" ? [...options2[prop2]] : options2[prop2]; - } - } - let prop; - for (prop in options2) { - if (!order.includes(prop)) { - this[prop] = options2[prop]; - } - } - } - /** - * Get the basename (including extname) (example: `'index.min.js'`). - * - * @returns {string | undefined} - * Basename. - */ - get basename() { - return typeof this.path === "string" ? path.basename(this.path) : void 0; - } - /** - * Set basename (including extname) (`'index.min.js'`). - * - * Cannot contain path separators (`'/'` on unix, macOS, and browsers, `'\'` - * on windows). - * Cannot be nullified (use `file.path = file.dirname` instead). - * - * @param {string} basename - * Basename. - * @returns {undefined} - * Nothing. - */ - set basename(basename2) { - assertNonEmpty(basename2, "basename"); - assertPart(basename2, "basename"); - this.path = path.join(this.dirname || "", basename2); - } - /** - * Get the parent path (example: `'~'`). - * - * @returns {string | undefined} - * Dirname. - */ - get dirname() { - return typeof this.path === "string" ? path.dirname(this.path) : void 0; - } - /** - * Set the parent path (example: `'~'`). - * - * Cannot be set if there’s no `path` yet. - * - * @param {string | undefined} dirname - * Dirname. - * @returns {undefined} - * Nothing. - */ - set dirname(dirname2) { - assertPath2(this.basename, "dirname"); - this.path = path.join(dirname2 || "", this.basename); - } - /** - * Get the extname (including dot) (example: `'.js'`). - * - * @returns {string | undefined} - * Extname. - */ - get extname() { - return typeof this.path === "string" ? path.extname(this.path) : void 0; - } - /** - * Set the extname (including dot) (example: `'.js'`). - * - * Cannot contain path separators (`'/'` on unix, macOS, and browsers, `'\'` - * on windows). - * Cannot be set if there’s no `path` yet. - * - * @param {string | undefined} extname - * Extname. - * @returns {undefined} - * Nothing. - */ - set extname(extname2) { - assertPart(extname2, "extname"); - assertPath2(this.dirname, "extname"); - if (extname2) { - if (extname2.codePointAt(0) !== 46) { - throw new Error("`extname` must start with `.`"); - } - if (extname2.includes(".", 1)) { - throw new Error("`extname` cannot contain multiple dots"); - } - } - this.path = path.join(this.dirname, this.stem + (extname2 || "")); - } - /** - * Get the full path (example: `'~/index.min.js'`). - * - * @returns {string} - * Path. - */ - get path() { - return this.history[this.history.length - 1]; - } - /** - * Set the full path (example: `'~/index.min.js'`). - * - * Cannot be nullified. - * You can set a file URL (a `URL` object with a `file:` protocol) which will - * be turned into a path with `url.fileURLToPath`. - * - * @param {URL | string} path - * Path. - * @returns {undefined} - * Nothing. - */ - set path(path3) { - if (isUrl(path3)) { - path3 = urlToPath(path3); - } - assertNonEmpty(path3, "path"); - if (this.path !== path3) { - this.history.push(path3); - } - } - /** - * Get the stem (basename w/o extname) (example: `'index.min'`). - * - * @returns {string | undefined} - * Stem. - */ - get stem() { - return typeof this.path === "string" ? path.basename(this.path, this.extname) : void 0; - } - /** - * Set the stem (basename w/o extname) (example: `'index.min'`). - * - * Cannot contain path separators (`'/'` on unix, macOS, and browsers, `'\'` - * on windows). - * Cannot be nullified (use `file.path = file.dirname` instead). - * - * @param {string} stem - * Stem. - * @returns {undefined} - * Nothing. - */ - set stem(stem) { - assertNonEmpty(stem, "stem"); - assertPart(stem, "stem"); - this.path = path.join(this.dirname || "", stem + (this.extname || "")); - } - // Normal prototypal methods. - /** - * Create a fatal message for `reason` associated with the file. - * - * The `fatal` field of the message is set to `true` (error; file not usable) - * and the `file` field is set to the current file path. - * The message is added to the `messages` field on `file`. - * - * > 🪦 **Note**: also has obsolete signatures. - * - * @overload - * @param {string} reason - * @param {MessageOptions | null | undefined} [options] - * @returns {never} - * - * @overload - * @param {string} reason - * @param {Node | NodeLike | null | undefined} parent - * @param {string | null | undefined} [origin] - * @returns {never} - * - * @overload - * @param {string} reason - * @param {Point | Position | null | undefined} place - * @param {string | null | undefined} [origin] - * @returns {never} - * - * @overload - * @param {string} reason - * @param {string | null | undefined} [origin] - * @returns {never} - * - * @overload - * @param {Error | VFileMessage} cause - * @param {Node | NodeLike | null | undefined} parent - * @param {string | null | undefined} [origin] - * @returns {never} - * - * @overload - * @param {Error | VFileMessage} cause - * @param {Point | Position | null | undefined} place - * @param {string | null | undefined} [origin] - * @returns {never} - * - * @overload - * @param {Error | VFileMessage} cause - * @param {string | null | undefined} [origin] - * @returns {never} - * - * @param {Error | VFileMessage | string} causeOrReason - * Reason for message, should use markdown. - * @param {Node | NodeLike | MessageOptions | Point | Position | string | null | undefined} [optionsOrParentOrPlace] - * Configuration (optional). - * @param {string | null | undefined} [origin] - * Place in code where the message originates (example: - * `'my-package:my-rule'` or `'my-rule'`). - * @returns {never} - * Never. - * @throws {VFileMessage} - * Message. - */ - fail(causeOrReason, optionsOrParentOrPlace, origin) { - const message = this.message(causeOrReason, optionsOrParentOrPlace, origin); - message.fatal = true; - throw message; - } - /** - * Create an info message for `reason` associated with the file. - * - * The `fatal` field of the message is set to `undefined` (info; change - * likely not needed) and the `file` field is set to the current file path. - * The message is added to the `messages` field on `file`. - * - * > 🪦 **Note**: also has obsolete signatures. - * - * @overload - * @param {string} reason - * @param {MessageOptions | null | undefined} [options] - * @returns {VFileMessage} - * - * @overload - * @param {string} reason - * @param {Node | NodeLike | null | undefined} parent - * @param {string | null | undefined} [origin] - * @returns {VFileMessage} - * - * @overload - * @param {string} reason - * @param {Point | Position | null | undefined} place - * @param {string | null | undefined} [origin] - * @returns {VFileMessage} - * - * @overload - * @param {string} reason - * @param {string | null | undefined} [origin] - * @returns {VFileMessage} - * - * @overload - * @param {Error | VFileMessage} cause - * @param {Node | NodeLike | null | undefined} parent - * @param {string | null | undefined} [origin] - * @returns {VFileMessage} - * - * @overload - * @param {Error | VFileMessage} cause - * @param {Point | Position | null | undefined} place - * @param {string | null | undefined} [origin] - * @returns {VFileMessage} - * - * @overload - * @param {Error | VFileMessage} cause - * @param {string | null | undefined} [origin] - * @returns {VFileMessage} - * - * @param {Error | VFileMessage | string} causeOrReason - * Reason for message, should use markdown. - * @param {Node | NodeLike | MessageOptions | Point | Position | string | null | undefined} [optionsOrParentOrPlace] - * Configuration (optional). - * @param {string | null | undefined} [origin] - * Place in code where the message originates (example: - * `'my-package:my-rule'` or `'my-rule'`). - * @returns {VFileMessage} - * Message. - */ - info(causeOrReason, optionsOrParentOrPlace, origin) { - const message = this.message(causeOrReason, optionsOrParentOrPlace, origin); - message.fatal = void 0; - return message; - } - /** - * Create a message for `reason` associated with the file. - * - * The `fatal` field of the message is set to `false` (warning; change may be - * needed) and the `file` field is set to the current file path. - * The message is added to the `messages` field on `file`. - * - * > 🪦 **Note**: also has obsolete signatures. - * - * @overload - * @param {string} reason - * @param {MessageOptions | null | undefined} [options] - * @returns {VFileMessage} - * - * @overload - * @param {string} reason - * @param {Node | NodeLike | null | undefined} parent - * @param {string | null | undefined} [origin] - * @returns {VFileMessage} - * - * @overload - * @param {string} reason - * @param {Point | Position | null | undefined} place - * @param {string | null | undefined} [origin] - * @returns {VFileMessage} - * - * @overload - * @param {string} reason - * @param {string | null | undefined} [origin] - * @returns {VFileMessage} - * - * @overload - * @param {Error | VFileMessage} cause - * @param {Node | NodeLike | null | undefined} parent - * @param {string | null | undefined} [origin] - * @returns {VFileMessage} - * - * @overload - * @param {Error | VFileMessage} cause - * @param {Point | Position | null | undefined} place - * @param {string | null | undefined} [origin] - * @returns {VFileMessage} - * - * @overload - * @param {Error | VFileMessage} cause - * @param {string | null | undefined} [origin] - * @returns {VFileMessage} - * - * @param {Error | VFileMessage | string} causeOrReason - * Reason for message, should use markdown. - * @param {Node | NodeLike | MessageOptions | Point | Position | string | null | undefined} [optionsOrParentOrPlace] - * Configuration (optional). - * @param {string | null | undefined} [origin] - * Place in code where the message originates (example: - * `'my-package:my-rule'` or `'my-rule'`). - * @returns {VFileMessage} - * Message. - */ - message(causeOrReason, optionsOrParentOrPlace, origin) { - const message = new VFileMessage( - // @ts-expect-error: the overloads are fine. - causeOrReason, - optionsOrParentOrPlace, - origin - ); - if (this.path) { - message.name = this.path + ":" + message.name; - message.file = this.path; - } - message.fatal = false; - this.messages.push(message); - return message; - } - /** - * Serialize the file. - * - * > **Note**: which encodings are supported depends on the engine. - * > For info on Node.js, see: - * > . - * - * @param {string | null | undefined} [encoding='utf8'] - * Character encoding to understand `value` as when it’s a `Uint8Array` - * (default: `'utf-8'`). - * @returns {string} - * Serialized file. - */ - toString(encoding) { - if (this.value === void 0) { - return ""; - } - if (typeof this.value === "string") { - return this.value; - } - const decoder = new TextDecoder(encoding || void 0); - return decoder.decode(this.value); - } - }; - function assertPart(part, name) { - if (part && part.includes(path.sep)) { - throw new Error( - "`" + name + "` cannot be a path: did not expect `" + path.sep + "`" - ); - } - } - function assertNonEmpty(part, name) { - if (!part) { - throw new Error("`" + name + "` cannot be empty"); - } - } - function assertPath2(path3, name) { - if (!path3) { - throw new Error("Setting `" + name + "` requires `path` to be set too"); - } - } - function isUint8Array(value) { - return Boolean( - value && typeof value === "object" && "byteLength" in value && "byteOffset" in value - ); - } - - // node_modules/unified/lib/callable-instance.js - var CallableInstance = ( - /** - * @type {new , Result>(property: string | symbol) => (...parameters: Parameters) => Result} - */ - /** @type {unknown} */ - /** - * @this {Function} - * @param {string | symbol} property - * @returns {(...parameters: Array) => unknown} - */ - function(property) { - const self2 = this; - const constr = self2.constructor; - const proto = ( - /** @type {Record} */ - // Prototypes do exist. - // type-coverage:ignore-next-line - constr.prototype - ); - const func = proto[property]; - const apply2 = function() { - return func.apply(apply2, arguments); - }; - Object.setPrototypeOf(apply2, proto); - const names = Object.getOwnPropertyNames(func); - for (const p4 of names) { - const descriptor = Object.getOwnPropertyDescriptor(func, p4); - if (descriptor) Object.defineProperty(apply2, p4, descriptor); - } - return apply2; - } - ); - - // node_modules/unified/lib/index.js - var own4 = {}.hasOwnProperty; - var Processor = class _Processor extends CallableInstance { - /** - * Create a processor. - */ - constructor() { - super("copy"); - this.Compiler = void 0; - this.Parser = void 0; - this.attachers = []; - this.compiler = void 0; - this.freezeIndex = -1; - this.frozen = void 0; - this.namespace = {}; - this.parser = void 0; - this.transformers = trough(); - } - /** - * Copy a processor. - * - * @deprecated - * This is a private internal method and should not be used. - * @returns {Processor} - * New *unfrozen* processor ({@link Processor `Processor`}) that is - * configured to work the same as its ancestor. - * When the descendant processor is configured in the future it does not - * affect the ancestral processor. - */ - copy() { - const destination = ( - /** @type {Processor} */ - new _Processor() - ); - let index2 = -1; - while (++index2 < this.attachers.length) { - const attacher = this.attachers[index2]; - destination.use(...attacher); - } - destination.data((0, import_extend.default)(true, {}, this.namespace)); - return destination; - } - /** - * Configure the processor with info available to all plugins. - * Information is stored in an object. - * - * Typically, options can be given to a specific plugin, but sometimes it - * makes sense to have information shared with several plugins. - * For example, a list of HTML elements that are self-closing, which is - * needed during all phases. - * - * > 👉 **Note**: setting information cannot occur on *frozen* processors. - * > Call the processor first to create a new unfrozen processor. - * - * > 👉 **Note**: to register custom data in TypeScript, augment the - * > {@link Data `Data`} interface. - * - * @example - * This example show how to get and set info: - * - * ```js - * import {unified} from 'unified' - * - * const processor = unified().data('alpha', 'bravo') - * - * processor.data('alpha') // => 'bravo' - * - * processor.data() // => {alpha: 'bravo'} - * - * processor.data({charlie: 'delta'}) - * - * processor.data() // => {charlie: 'delta'} - * ``` - * - * @template {keyof Data} Key - * - * @overload - * @returns {Data} - * - * @overload - * @param {Data} dataset - * @returns {Processor} - * - * @overload - * @param {Key} key - * @returns {Data[Key]} - * - * @overload - * @param {Key} key - * @param {Data[Key]} value - * @returns {Processor} - * - * @param {Data | Key} [key] - * Key to get or set, or entire dataset to set, or nothing to get the - * entire dataset (optional). - * @param {Data[Key]} [value] - * Value to set (optional). - * @returns {unknown} - * The current processor when setting, the value at `key` when getting, or - * the entire dataset when getting without key. - */ - data(key, value) { - if (typeof key === "string") { - if (arguments.length === 2) { - assertUnfrozen("data", this.frozen); - this.namespace[key] = value; - return this; - } - return own4.call(this.namespace, key) && this.namespace[key] || void 0; - } - if (key) { - assertUnfrozen("data", this.frozen); - this.namespace = key; - return this; - } - return this.namespace; - } - /** - * Freeze a processor. - * - * Frozen processors are meant to be extended and not to be configured - * directly. - * - * When a processor is frozen it cannot be unfrozen. - * New processors working the same way can be created by calling the - * processor. - * - * It’s possible to freeze processors explicitly by calling `.freeze()`. - * Processors freeze automatically when `.parse()`, `.run()`, `.runSync()`, - * `.stringify()`, `.process()`, or `.processSync()` are called. - * - * @returns {Processor} - * The current processor. - */ - freeze() { - if (this.frozen) { - return this; - } - const self2 = ( - /** @type {Processor} */ - /** @type {unknown} */ - this - ); - while (++this.freezeIndex < this.attachers.length) { - const [attacher, ...options2] = this.attachers[this.freezeIndex]; - if (options2[0] === false) { - continue; - } - if (options2[0] === true) { - options2[0] = void 0; - } - const transformer = attacher.call(self2, ...options2); - if (typeof transformer === "function") { - this.transformers.use(transformer); - } - } - this.frozen = true; - this.freezeIndex = Number.POSITIVE_INFINITY; - return this; - } - /** - * Parse text to a syntax tree. - * - * > 👉 **Note**: `parse` freezes the processor if not already *frozen*. - * - * > 👉 **Note**: `parse` performs the parse phase, not the run phase or other - * > phases. - * - * @param {Compatible | undefined} [file] - * file to parse (optional); typically `string` or `VFile`; any value - * accepted as `x` in `new VFile(x)`. - * @returns {ParseTree extends undefined ? Node : ParseTree} - * Syntax tree representing `file`. - */ - parse(file) { - this.freeze(); - const realFile = vfile(file); - const parser = this.parser || this.Parser; - assertParser("parse", parser); - return parser(String(realFile), realFile); - } - /** - * Process the given file as configured on the processor. - * - * > 👉 **Note**: `process` freezes the processor if not already *frozen*. - * - * > 👉 **Note**: `process` performs the parse, run, and stringify phases. - * - * @overload - * @param {Compatible | undefined} file - * @param {ProcessCallback>} done - * @returns {undefined} - * - * @overload - * @param {Compatible | undefined} [file] - * @returns {Promise>} - * - * @param {Compatible | undefined} [file] - * File (optional); typically `string` or `VFile`]; any value accepted as - * `x` in `new VFile(x)`. - * @param {ProcessCallback> | undefined} [done] - * Callback (optional). - * @returns {Promise | undefined} - * Nothing if `done` is given. - * Otherwise a promise, rejected with a fatal error or resolved with the - * processed file. - * - * The parsed, transformed, and compiled value is available at - * `file.value` (see note). - * - * > 👉 **Note**: unified typically compiles by serializing: most - * > compilers return `string` (or `Uint8Array`). - * > Some compilers, such as the one configured with - * > [`rehype-react`][rehype-react], return other values (in this case, a - * > React tree). - * > If you’re using a compiler that doesn’t serialize, expect different - * > result values. - * > - * > To register custom results in TypeScript, add them to - * > {@link CompileResultMap `CompileResultMap`}. - * - * [rehype-react]: https://github.com/rehypejs/rehype-react - */ - process(file, done) { - const self2 = this; - this.freeze(); - assertParser("process", this.parser || this.Parser); - assertCompiler("process", this.compiler || this.Compiler); - return done ? executor(void 0, done) : new Promise(executor); - function executor(resolve, reject) { - const realFile = vfile(file); - const parseTree = ( - /** @type {HeadTree extends undefined ? Node : HeadTree} */ - /** @type {unknown} */ - self2.parse(realFile) - ); - self2.run(parseTree, realFile, function(error, tree, file2) { - if (error || !tree || !file2) { - return realDone(error); - } - const compileTree = ( - /** @type {CompileTree extends undefined ? Node : CompileTree} */ - /** @type {unknown} */ - tree - ); - const compileResult = self2.stringify(compileTree, file2); - if (looksLikeAValue(compileResult)) { - file2.value = compileResult; - } else { - file2.result = compileResult; - } - realDone( - error, - /** @type {VFileWithOutput} */ - file2 - ); - }); - function realDone(error, file2) { - if (error || !file2) { - reject(error); - } else if (resolve) { - resolve(file2); - } else { - ok2(done, "`done` is defined if `resolve` is not"); - done(void 0, file2); - } - } - } - } - /** - * Process the given file as configured on the processor. - * - * An error is thrown if asynchronous transforms are configured. - * - * > 👉 **Note**: `processSync` freezes the processor if not already *frozen*. - * - * > 👉 **Note**: `processSync` performs the parse, run, and stringify phases. - * - * @param {Compatible | undefined} [file] - * File (optional); typically `string` or `VFile`; any value accepted as - * `x` in `new VFile(x)`. - * @returns {VFileWithOutput} - * The processed file. - * - * The parsed, transformed, and compiled value is available at - * `file.value` (see note). - * - * > 👉 **Note**: unified typically compiles by serializing: most - * > compilers return `string` (or `Uint8Array`). - * > Some compilers, such as the one configured with - * > [`rehype-react`][rehype-react], return other values (in this case, a - * > React tree). - * > If you’re using a compiler that doesn’t serialize, expect different - * > result values. - * > - * > To register custom results in TypeScript, add them to - * > {@link CompileResultMap `CompileResultMap`}. - * - * [rehype-react]: https://github.com/rehypejs/rehype-react - */ - processSync(file) { - let complete = false; - let result; - this.freeze(); - assertParser("processSync", this.parser || this.Parser); - assertCompiler("processSync", this.compiler || this.Compiler); - this.process(file, realDone); - assertDone("processSync", "process", complete); - ok2(result, "we either bailed on an error or have a tree"); - return result; - function realDone(error, file2) { - complete = true; - bail(error); - result = file2; - } - } - /** - * Run *transformers* on a syntax tree. - * - * > 👉 **Note**: `run` freezes the processor if not already *frozen*. - * - * > 👉 **Note**: `run` performs the run phase, not other phases. - * - * @overload - * @param {HeadTree extends undefined ? Node : HeadTree} tree - * @param {RunCallback} done - * @returns {undefined} - * - * @overload - * @param {HeadTree extends undefined ? Node : HeadTree} tree - * @param {Compatible | undefined} file - * @param {RunCallback} done - * @returns {undefined} - * - * @overload - * @param {HeadTree extends undefined ? Node : HeadTree} tree - * @param {Compatible | undefined} [file] - * @returns {Promise} - * - * @param {HeadTree extends undefined ? Node : HeadTree} tree - * Tree to transform and inspect. - * @param {( - * RunCallback | - * Compatible - * )} [file] - * File associated with `node` (optional); any value accepted as `x` in - * `new VFile(x)`. - * @param {RunCallback} [done] - * Callback (optional). - * @returns {Promise | undefined} - * Nothing if `done` is given. - * Otherwise, a promise rejected with a fatal error or resolved with the - * transformed tree. - */ - run(tree, file, done) { - assertNode(tree); - this.freeze(); - const transformers = this.transformers; - if (!done && typeof file === "function") { - done = file; - file = void 0; - } - return done ? executor(void 0, done) : new Promise(executor); - function executor(resolve, reject) { - ok2( - typeof file !== "function", - "`file` can\u2019t be a `done` anymore, we checked" - ); - const realFile = vfile(file); - transformers.run(tree, realFile, realDone); - function realDone(error, outputTree, file2) { - const resultingTree = ( - /** @type {TailTree extends undefined ? Node : TailTree} */ - outputTree || tree - ); - if (error) { - reject(error); - } else if (resolve) { - resolve(resultingTree); - } else { - ok2(done, "`done` is defined if `resolve` is not"); - done(void 0, resultingTree, file2); - } - } - } - } - /** - * Run *transformers* on a syntax tree. - * - * An error is thrown if asynchronous transforms are configured. - * - * > 👉 **Note**: `runSync` freezes the processor if not already *frozen*. - * - * > 👉 **Note**: `runSync` performs the run phase, not other phases. - * - * @param {HeadTree extends undefined ? Node : HeadTree} tree - * Tree to transform and inspect. - * @param {Compatible | undefined} [file] - * File associated with `node` (optional); any value accepted as `x` in - * `new VFile(x)`. - * @returns {TailTree extends undefined ? Node : TailTree} - * Transformed tree. - */ - runSync(tree, file) { - let complete = false; - let result; - this.run(tree, file, realDone); - assertDone("runSync", "run", complete); - ok2(result, "we either bailed on an error or have a tree"); - return result; - function realDone(error, tree2) { - bail(error); - result = tree2; - complete = true; - } - } - /** - * Compile a syntax tree. - * - * > 👉 **Note**: `stringify` freezes the processor if not already *frozen*. - * - * > 👉 **Note**: `stringify` performs the stringify phase, not the run phase - * > or other phases. - * - * @param {CompileTree extends undefined ? Node : CompileTree} tree - * Tree to compile. - * @param {Compatible | undefined} [file] - * File associated with `node` (optional); any value accepted as `x` in - * `new VFile(x)`. - * @returns {CompileResult extends undefined ? Value : CompileResult} - * Textual representation of the tree (see note). - * - * > 👉 **Note**: unified typically compiles by serializing: most compilers - * > return `string` (or `Uint8Array`). - * > Some compilers, such as the one configured with - * > [`rehype-react`][rehype-react], return other values (in this case, a - * > React tree). - * > If you’re using a compiler that doesn’t serialize, expect different - * > result values. - * > - * > To register custom results in TypeScript, add them to - * > {@link CompileResultMap `CompileResultMap`}. - * - * [rehype-react]: https://github.com/rehypejs/rehype-react - */ - stringify(tree, file) { - this.freeze(); - const realFile = vfile(file); - const compiler2 = this.compiler || this.Compiler; - assertCompiler("stringify", compiler2); - assertNode(tree); - return compiler2(tree, realFile); - } - /** - * Configure the processor to use a plugin, a list of usable values, or a - * preset. - * - * If the processor is already using a plugin, the previous plugin - * configuration is changed based on the options that are passed in. - * In other words, the plugin is not added a second time. - * - * > 👉 **Note**: `use` cannot be called on *frozen* processors. - * > Call the processor first to create a new unfrozen processor. - * - * @example - * There are many ways to pass plugins to `.use()`. - * This example gives an overview: - * - * ```js - * import {unified} from 'unified' - * - * unified() - * // Plugin with options: - * .use(pluginA, {x: true, y: true}) - * // Passing the same plugin again merges configuration (to `{x: true, y: false, z: true}`): - * .use(pluginA, {y: false, z: true}) - * // Plugins: - * .use([pluginB, pluginC]) - * // Two plugins, the second with options: - * .use([pluginD, [pluginE, {}]]) - * // Preset with plugins and settings: - * .use({plugins: [pluginF, [pluginG, {}]], settings: {position: false}}) - * // Settings only: - * .use({settings: {position: false}}) - * ``` - * - * @template {Array} [Parameters=[]] - * @template {Node | string | undefined} [Input=undefined] - * @template [Output=Input] - * - * @overload - * @param {Preset | null | undefined} [preset] - * @returns {Processor} - * - * @overload - * @param {PluggableList} list - * @returns {Processor} - * - * @overload - * @param {Plugin} plugin - * @param {...(Parameters | [boolean])} parameters - * @returns {UsePlugin} - * - * @param {PluggableList | Plugin | Preset | null | undefined} value - * Usable value. - * @param {...unknown} parameters - * Parameters, when a plugin is given as a usable value. - * @returns {Processor} - * Current processor. - */ - use(value, ...parameters) { - const attachers = this.attachers; - const namespace = this.namespace; - assertUnfrozen("use", this.frozen); - if (value === null || value === void 0) { - } else if (typeof value === "function") { - addPlugin(value, parameters); - } else if (typeof value === "object") { - if (Array.isArray(value)) { - addList(value); - } else { - addPreset(value); - } - } else { - throw new TypeError("Expected usable value, not `" + value + "`"); - } - return this; - function add(value2) { - if (typeof value2 === "function") { - addPlugin(value2, []); - } else if (typeof value2 === "object") { - if (Array.isArray(value2)) { - const [plugin, ...parameters2] = ( - /** @type {PluginTuple>} */ - value2 - ); - addPlugin(plugin, parameters2); - } else { - addPreset(value2); - } - } else { - throw new TypeError("Expected usable value, not `" + value2 + "`"); - } - } - function addPreset(result) { - if (!("plugins" in result) && !("settings" in result)) { - throw new Error( - "Expected usable value but received an empty preset, which is probably a mistake: presets typically come with `plugins` and sometimes with `settings`, but this has neither" - ); - } - addList(result.plugins); - if (result.settings) { - namespace.settings = (0, import_extend.default)(true, namespace.settings, result.settings); - } - } - function addList(plugins) { - let index2 = -1; - if (plugins === null || plugins === void 0) { - } else if (Array.isArray(plugins)) { - while (++index2 < plugins.length) { - const thing = plugins[index2]; - add(thing); - } - } else { - throw new TypeError("Expected a list of plugins, not `" + plugins + "`"); - } - } - function addPlugin(plugin, parameters2) { - let index2 = -1; - let entryIndex = -1; - while (++index2 < attachers.length) { - if (attachers[index2][0] === plugin) { - entryIndex = index2; - break; - } - } - if (entryIndex === -1) { - attachers.push([plugin, ...parameters2]); - } else if (parameters2.length > 0) { - let [primary, ...rest] = parameters2; - const currentPrimary = attachers[entryIndex][1]; - if (isPlainObject(currentPrimary) && isPlainObject(primary)) { - primary = (0, import_extend.default)(true, currentPrimary, primary); - } - attachers[entryIndex] = [plugin, primary, ...rest]; - } - } - } - }; - var unified = new Processor().freeze(); - function assertParser(name, value) { - if (typeof value !== "function") { - throw new TypeError("Cannot `" + name + "` without `parser`"); - } - } - function assertCompiler(name, value) { - if (typeof value !== "function") { - throw new TypeError("Cannot `" + name + "` without `compiler`"); - } - } - function assertUnfrozen(name, frozen) { - if (frozen) { - throw new Error( - "Cannot call `" + name + "` on a frozen processor.\nCreate a new processor first, by calling it: use `processor()` instead of `processor`." - ); - } - } - function assertNode(node2) { - if (!isPlainObject(node2) || typeof node2.type !== "string") { - throw new TypeError("Expected node, got `" + node2 + "`"); - } - } - function assertDone(name, asyncName, complete) { - if (!complete) { - throw new Error( - "`" + name + "` finished async. Use `" + asyncName + "` instead" - ); - } - } - function vfile(value) { - return looksLikeAVFile(value) ? value : new VFile(value); - } - function looksLikeAVFile(value) { - return Boolean( - value && typeof value === "object" && "message" in value && "messages" in value - ); - } - function looksLikeAValue(value) { - return typeof value === "string" || isUint8Array2(value); - } - function isUint8Array2(value) { - return Boolean( - value && typeof value === "object" && "byteLength" in value && "byteOffset" in value - ); - } - - // node_modules/@milkdown/transformer/lib/index.es.js - var G2 = (p4, h5, n4) => { - if (!h5.has(p4)) - throw TypeError("Cannot " + n4); - }; - var r = (p4, h5, n4) => (G2(p4, h5, "read from private field"), n4 ? n4.call(p4) : h5.get(p4)); - var c2 = (p4, h5, n4) => { - if (h5.has(p4)) - throw TypeError("Cannot add the same private member more than once"); - h5 instanceof WeakSet ? h5.add(p4) : h5.set(p4, n4); - }; - var o = (p4, h5, n4, t2) => (G2(p4, h5, "write to private field"), t2 ? t2.call(p4, n4) : h5.set(p4, n4), n4); - var Q = class { - }; - var U2 = class { - constructor() { - this.elements = [], this.size = () => this.elements.length, this.top = () => this.elements.at(-1), this.push = (h5) => { - var n4; - (n4 = this.top()) == null || n4.push(h5); - }, this.open = (h5) => { - this.elements.push(h5); - }, this.close = () => { - const h5 = this.elements.pop(); - if (!h5) - throw h(); - return h5; - }; - } - }; - var B = class _B extends Q { - constructor(h5, n4, t2) { - super(), this.type = h5, this.content = n4, this.attrs = t2; - } - push(h5, ...n4) { - this.content.push(h5, ...n4); - } - pop() { - return this.content.pop(); - } - static create(h5, n4, t2) { - return new _B(h5, n4, t2); - } - }; - var d3; - var N; - var O; - var T2; - var F2; - var k2; - var M3; - var S3 = class S4 extends U2 { - /// @internal - constructor(n4) { - super(); - c2(this, d3, void 0); - c2(this, N, void 0); - c2(this, O, void 0); - c2(this, T2, void 0); - c2(this, F2, void 0); - c2(this, k2, void 0); - c2(this, M3, void 0); - o(this, d3, Mark.none), o(this, N, (t2) => t2.isText), o(this, O, (t2, s2) => { - if (r(this, N).call(this, t2) && r(this, N).call(this, s2) && Mark.sameSet(t2.marks, s2.marks)) - return this.schema.text(t2.text + s2.text, t2.marks); - }), o(this, T2, (t2) => { - const s2 = Object.values(__spreadValues(__spreadValues({}, this.schema.nodes), this.schema.marks)).find((e2) => e2.spec.parseMarkdown.match(t2)); - if (!s2) - throw w(t2); - return s2; - }), o(this, F2, (t2) => { - const s2 = r(this, T2).call(this, t2); - s2.spec.parseMarkdown.runner(this, t2, s2); - }), this.injectRoot = (t2, s2, e2) => (this.openNode(s2, e2), this.next(t2.children), this), this.openNode = (t2, s2) => (this.open(B.create(t2, [], s2)), this), o(this, k2, () => { - o(this, d3, Mark.none); - const t2 = this.close(); - return r(this, M3).call(this, t2.type, t2.attrs, t2.content); - }), this.closeNode = () => (r(this, k2).call(this), this), o(this, M3, (t2, s2, e2) => { - const i2 = t2.createAndFill(s2, e2, r(this, d3)); - if (!i2) - throw g(t2, s2, e2); - return this.push(i2), i2; - }), this.addNode = (t2, s2, e2) => (r(this, M3).call(this, t2, s2, e2), this), this.openMark = (t2, s2) => { - const e2 = t2.create(s2); - return o(this, d3, e2.addToSet(r(this, d3))), this; - }, this.closeMark = (t2) => (o(this, d3, t2.removeFromSet(r(this, d3))), this), this.addText = (t2) => { - const s2 = this.top(); - if (!s2) - throw h(); - const e2 = s2.pop(), i2 = this.schema.text(t2, r(this, d3)); - if (!e2) - return s2.push(i2), this; - const a2 = r(this, O).call(this, e2, i2); - return a2 ? (s2.push(a2), this) : (s2.push(e2, i2), this); - }, this.build = () => { - let t2; - do - t2 = r(this, k2).call(this); - while (this.size()); - return t2; - }, this.next = (t2 = []) => ([t2].flat().forEach((s2) => r(this, F2).call(this, s2)), this), this.toDoc = () => this.build(), this.run = (t2, s2) => { - const e2 = t2.runSync(t2.parse(s2), s2); - return this.next(e2), this; - }, this.schema = n4; - } - }; - d3 = /* @__PURE__ */ new WeakMap(), N = /* @__PURE__ */ new WeakMap(), O = /* @__PURE__ */ new WeakMap(), T2 = /* @__PURE__ */ new WeakMap(), F2 = /* @__PURE__ */ new WeakMap(), k2 = /* @__PURE__ */ new WeakMap(), M3 = /* @__PURE__ */ new WeakMap(), S3.create = (n4, t2) => { - const s2 = new S3(n4); - return (e2) => (s2.run(t2, e2), s2.toDoc()); - }; - var H2 = S3; - var q2 = class q3 extends Q { - constructor(h5, n4, t2, s2 = {}) { - super(), this.type = h5, this.children = n4, this.value = t2, this.props = s2, this.push = (e2, ...i2) => { - this.children || (this.children = []), this.children.push(e2, ...i2); - }, this.pop = () => { - var e2; - return (e2 = this.children) == null ? void 0 : e2.pop(); - }; - } - }; - q2.create = (h5, n4, t2, s2 = {}) => new q2(h5, n4, t2, s2); - var J2 = q2; - var Z = (p4) => Object.prototype.hasOwnProperty.call(p4, "size"); - var l3; - var v; - var A2; - var E2; - var w3; - var j2; - var x3; - var R2; - var m2; - var g3; - var C2; - var P2; - var z = class z2 extends U2 { - /// @internal - constructor(n4) { - super(); - c2(this, l3, void 0); - c2(this, v, void 0); - c2(this, A2, void 0); - c2(this, E2, void 0); - c2(this, w3, void 0); - c2(this, j2, void 0); - c2(this, x3, void 0); - c2(this, R2, void 0); - c2(this, m2, void 0); - c2(this, g3, void 0); - c2(this, C2, void 0); - c2(this, P2, void 0); - o(this, l3, Mark.none), o(this, v, (t2) => { - const s2 = Object.values(__spreadValues(__spreadValues({}, this.schema.nodes), this.schema.marks)).find((e2) => e2.spec.toMarkdown.match(t2)); - if (!s2) - throw F(t2.type); - return s2; - }), o(this, A2, (t2) => r(this, v).call(this, t2).spec.toMarkdown.runner(this, t2)), o(this, E2, (t2, s2) => r(this, v).call(this, t2).spec.toMarkdown.runner(this, t2, s2)), o(this, w3, (t2) => { - const { marks: s2 } = t2, e2 = (u4) => { - var _a; - return (_a = u4.type.spec.priority) != null ? _a : 50; - }; - [...s2].sort((u4, f3) => e2(u4) - e2(f3)).every((u4) => !r(this, E2).call(this, u4, t2)) && r(this, A2).call(this, t2), s2.forEach((u4) => r(this, P2).call(this, u4)); - }), o(this, j2, (t2, s2) => { - var f3; - if (t2.type === s2 || ((f3 = t2.children) == null ? void 0 : f3.length) !== 1) - return t2; - const e2 = (y4) => { - var I4; - if (y4.type === s2) - return y4; - if (((I4 = y4.children) == null ? void 0 : I4.length) !== 1) - return null; - const [b4] = y4.children; - return b4 ? e2(b4) : null; - }, i2 = e2(t2); - if (!i2) - return t2; - const a2 = i2.children ? [...i2.children] : void 0, u4 = __spreadProps(__spreadValues({}, t2), { children: a2 }); - return u4.children = a2, i2.children = [u4], i2; - }), o(this, x3, (t2) => { - const { children: s2 } = t2; - return s2 && (t2.children = s2.reduce((e2, i2, a2) => { - if (a2 === 0) - return [i2]; - const u4 = e2.at(-1); - if (u4 && u4.isMark && i2.isMark) { - i2 = r(this, j2).call(this, i2, u4.type); - const _a = i2, { children: f3 } = _a, y4 = __objRest(_a, ["children"]), _b = u4, { children: b4 } = _b, I4 = __objRest(_b, ["children"]); - if (i2.type === u4.type && f3 && b4 && JSON.stringify(y4) === JSON.stringify(I4)) { - const V4 = __spreadProps(__spreadValues({}, I4), { - children: [...b4, ...f3] - }); - return e2.slice(0, -1).concat(r(this, x3).call(this, V4)); - } - } - return e2.concat(i2); - }, [])), t2; - }), o(this, R2, (t2) => { - const s2 = __spreadProps(__spreadValues({}, t2.props), { - type: t2.type - }); - return t2.children && (s2.children = t2.children), t2.value && (s2.value = t2.value), s2; - }), this.openNode = (t2, s2, e2) => (this.open(J2.create(t2, void 0, s2, e2)), this), o(this, m2, () => { - const t2 = this.close(); - return r(this, g3).call(this, t2.type, t2.children, t2.value, t2.props); - }), this.closeNode = () => (r(this, m2).call(this), this), o(this, g3, (t2, s2, e2, i2) => { - const a2 = J2.create(t2, s2, e2, i2), u4 = r(this, x3).call(this, r(this, R2).call(this, a2)); - return this.push(u4), u4; - }), this.addNode = (t2, s2, e2, i2) => (r(this, g3).call(this, t2, s2, e2, i2), this), o(this, C2, (t2, s2, e2, i2) => t2.isInSet(r(this, l3)) ? this : (o(this, l3, t2.addToSet(r(this, l3))), this.openNode(s2, e2, __spreadProps(__spreadValues({}, i2), { isMark: true })))), o(this, P2, (t2) => { - t2.isInSet(r(this, l3)) && (o(this, l3, t2.type.removeFromSet(r(this, l3))), r(this, m2).call(this)); - }), this.withMark = (t2, s2, e2, i2) => (r(this, C2).call(this, t2, s2, e2, i2), this), this.closeMark = (t2) => (r(this, P2).call(this, t2), this), this.build = () => { - let t2 = null; - do - t2 = r(this, m2).call(this); - while (this.size()); - return t2; - }, this.next = (t2) => Z(t2) ? (t2.forEach((s2) => { - r(this, w3).call(this, s2); - }), this) : (r(this, w3).call(this, t2), this), this.toString = (t2) => t2.stringify(this.build()), this.run = (t2) => (this.next(t2), this), this.schema = n4; - } - }; - l3 = /* @__PURE__ */ new WeakMap(), v = /* @__PURE__ */ new WeakMap(), A2 = /* @__PURE__ */ new WeakMap(), E2 = /* @__PURE__ */ new WeakMap(), w3 = /* @__PURE__ */ new WeakMap(), j2 = /* @__PURE__ */ new WeakMap(), x3 = /* @__PURE__ */ new WeakMap(), R2 = /* @__PURE__ */ new WeakMap(), m2 = /* @__PURE__ */ new WeakMap(), g3 = /* @__PURE__ */ new WeakMap(), C2 = /* @__PURE__ */ new WeakMap(), P2 = /* @__PURE__ */ new WeakMap(), z.create = (n4, t2) => { - const s2 = new z(n4); - return (e2) => (s2.run(e2), s2.toString(t2)); - }; - var K2 = z; - - // node_modules/prosemirror-transform/dist/index.js - var lower16 = 65535; - var factor16 = Math.pow(2, 16); - function makeRecover(index2, offset) { - return index2 + offset * factor16; - } - function recoverIndex(value) { - return value & lower16; - } - function recoverOffset(value) { - return (value - (value & lower16)) / factor16; - } - var DEL_BEFORE = 1; - var DEL_AFTER = 2; - var DEL_ACROSS = 4; - var DEL_SIDE = 8; - var MapResult = class { - /** - @internal - */ - constructor(pos, delInfo, recover) { - this.pos = pos; - this.delInfo = delInfo; - this.recover = recover; - } - /** - Tells you whether the position was deleted, that is, whether the - step removed the token on the side queried (via the `assoc`) - argument from the document. - */ - get deleted() { - return (this.delInfo & DEL_SIDE) > 0; - } - /** - Tells you whether the token before the mapped position was deleted. - */ - get deletedBefore() { - return (this.delInfo & (DEL_BEFORE | DEL_ACROSS)) > 0; - } - /** - True when the token after the mapped position was deleted. - */ - get deletedAfter() { - return (this.delInfo & (DEL_AFTER | DEL_ACROSS)) > 0; - } - /** - Tells whether any of the steps mapped through deletes across the - position (including both the token before and after the - position). - */ - get deletedAcross() { - return (this.delInfo & DEL_ACROSS) > 0; - } - }; - var StepMap = class _StepMap { - /** - Create a position map. The modifications to the document are - represented as an array of numbers, in which each group of three - represents a modified chunk as `[start, oldSize, newSize]`. - */ - constructor(ranges, inverted = false) { - this.ranges = ranges; - this.inverted = inverted; - if (!ranges.length && _StepMap.empty) - return _StepMap.empty; - } - /** - @internal - */ - recover(value) { - let diff2 = 0, index2 = recoverIndex(value); - if (!this.inverted) - for (let i2 = 0; i2 < index2; i2++) - diff2 += this.ranges[i2 * 3 + 2] - this.ranges[i2 * 3 + 1]; - return this.ranges[index2 * 3] + diff2 + recoverOffset(value); - } - mapResult(pos, assoc = 1) { - return this._map(pos, assoc, false); - } - map(pos, assoc = 1) { - return this._map(pos, assoc, true); - } - /** - @internal - */ - _map(pos, assoc, simple) { - let diff2 = 0, oldIndex = this.inverted ? 2 : 1, newIndex = this.inverted ? 1 : 2; - for (let i2 = 0; i2 < this.ranges.length; i2 += 3) { - let start = this.ranges[i2] - (this.inverted ? diff2 : 0); - if (start > pos) - break; - let oldSize = this.ranges[i2 + oldIndex], newSize = this.ranges[i2 + newIndex], end = start + oldSize; - if (pos <= end) { - let side = !oldSize ? assoc : pos == start ? -1 : pos == end ? 1 : assoc; - let result = start + diff2 + (side < 0 ? 0 : newSize); - if (simple) - return result; - let recover = pos == (assoc < 0 ? start : end) ? null : makeRecover(i2 / 3, pos - start); - let del2 = pos == start ? DEL_AFTER : pos == end ? DEL_BEFORE : DEL_ACROSS; - if (assoc < 0 ? pos != start : pos != end) - del2 |= DEL_SIDE; - return new MapResult(result, del2, recover); - } - diff2 += newSize - oldSize; - } - return simple ? pos + diff2 : new MapResult(pos + diff2, 0, null); - } - /** - @internal - */ - touches(pos, recover) { - let diff2 = 0, index2 = recoverIndex(recover); - let oldIndex = this.inverted ? 2 : 1, newIndex = this.inverted ? 1 : 2; - for (let i2 = 0; i2 < this.ranges.length; i2 += 3) { - let start = this.ranges[i2] - (this.inverted ? diff2 : 0); - if (start > pos) - break; - let oldSize = this.ranges[i2 + oldIndex], end = start + oldSize; - if (pos <= end && i2 == index2 * 3) - return true; - diff2 += this.ranges[i2 + newIndex] - oldSize; - } - return false; - } - /** - Calls the given function on each of the changed ranges included in - this map. - */ - forEach(f3) { - let oldIndex = this.inverted ? 2 : 1, newIndex = this.inverted ? 1 : 2; - for (let i2 = 0, diff2 = 0; i2 < this.ranges.length; i2 += 3) { - let start = this.ranges[i2], oldStart = start - (this.inverted ? diff2 : 0), newStart = start + (this.inverted ? 0 : diff2); - let oldSize = this.ranges[i2 + oldIndex], newSize = this.ranges[i2 + newIndex]; - f3(oldStart, oldStart + oldSize, newStart, newStart + newSize); - diff2 += newSize - oldSize; - } - } - /** - Create an inverted version of this map. The result can be used to - map positions in the post-step document to the pre-step document. - */ - invert() { - return new _StepMap(this.ranges, !this.inverted); - } - /** - @internal - */ - toString() { - return (this.inverted ? "-" : "") + JSON.stringify(this.ranges); - } - /** - Create a map that moves all positions by offset `n` (which may be - negative). This can be useful when applying steps meant for a - sub-document to a larger document, or vice-versa. - */ - static offset(n4) { - return n4 == 0 ? _StepMap.empty : new _StepMap(n4 < 0 ? [0, -n4, 0] : [0, 0, n4]); - } - }; - StepMap.empty = new StepMap([]); - var Mapping = class _Mapping { - /** - Create a new mapping with the given position maps. - */ - constructor(maps = [], mirror, from = 0, to = maps.length) { - this.maps = maps; - this.mirror = mirror; - this.from = from; - this.to = to; - } - /** - Create a mapping that maps only through a part of this one. - */ - slice(from = 0, to = this.maps.length) { - return new _Mapping(this.maps, this.mirror, from, to); - } - /** - @internal - */ - copy() { - return new _Mapping(this.maps.slice(), this.mirror && this.mirror.slice(), this.from, this.to); - } - /** - Add a step map to the end of this mapping. If `mirrors` is - given, it should be the index of the step map that is the mirror - image of this one. - */ - appendMap(map5, mirrors) { - this.to = this.maps.push(map5); - if (mirrors != null) - this.setMirror(this.maps.length - 1, mirrors); - } - /** - Add all the step maps in a given mapping to this one (preserving - mirroring information). - */ - appendMapping(mapping) { - for (let i2 = 0, startSize = this.maps.length; i2 < mapping.maps.length; i2++) { - let mirr = mapping.getMirror(i2); - this.appendMap(mapping.maps[i2], mirr != null && mirr < i2 ? startSize + mirr : void 0); - } - } - /** - Finds the offset of the step map that mirrors the map at the - given offset, in this mapping (as per the second argument to - `appendMap`). - */ - getMirror(n4) { - if (this.mirror) { - for (let i2 = 0; i2 < this.mirror.length; i2++) - if (this.mirror[i2] == n4) - return this.mirror[i2 + (i2 % 2 ? -1 : 1)]; - } - } - /** - @internal - */ - setMirror(n4, m3) { - if (!this.mirror) - this.mirror = []; - this.mirror.push(n4, m3); - } - /** - Append the inverse of the given mapping to this one. - */ - appendMappingInverted(mapping) { - for (let i2 = mapping.maps.length - 1, totalSize = this.maps.length + mapping.maps.length; i2 >= 0; i2--) { - let mirr = mapping.getMirror(i2); - this.appendMap(mapping.maps[i2].invert(), mirr != null && mirr > i2 ? totalSize - mirr - 1 : void 0); - } - } - /** - Create an inverted version of this mapping. - */ - invert() { - let inverse = new _Mapping(); - inverse.appendMappingInverted(this); - return inverse; - } - /** - Map a position through this mapping. - */ - map(pos, assoc = 1) { - if (this.mirror) - return this._map(pos, assoc, true); - for (let i2 = this.from; i2 < this.to; i2++) - pos = this.maps[i2].map(pos, assoc); - return pos; - } - /** - Map a position through this mapping, returning a mapping - result. - */ - mapResult(pos, assoc = 1) { - return this._map(pos, assoc, false); - } - /** - @internal - */ - _map(pos, assoc, simple) { - let delInfo = 0; - for (let i2 = this.from; i2 < this.to; i2++) { - let map5 = this.maps[i2], result = map5.mapResult(pos, assoc); - if (result.recover != null) { - let corr = this.getMirror(i2); - if (corr != null && corr > i2 && corr < this.to) { - i2 = corr; - pos = this.maps[corr].recover(result.recover); - continue; - } - } - delInfo |= result.delInfo; - pos = result.pos; - } - return simple ? pos : new MapResult(pos, delInfo, null); - } - }; - var stepsByID = /* @__PURE__ */ Object.create(null); - var Step = class { - /** - Get the step map that represents the changes made by this step, - and which can be used to transform between positions in the old - and the new document. - */ - getMap() { - return StepMap.empty; - } - /** - Try to merge this step with another one, to be applied directly - after it. Returns the merged step when possible, null if the - steps can't be merged. - */ - merge(other) { - return null; - } - /** - Deserialize a step from its JSON representation. Will call - through to the step class' own implementation of this method. - */ - static fromJSON(schema, json) { - if (!json || !json.stepType) - throw new RangeError("Invalid input for Step.fromJSON"); - let type = stepsByID[json.stepType]; - if (!type) - throw new RangeError(`No step type ${json.stepType} defined`); - return type.fromJSON(schema, json); - } - /** - To be able to serialize steps to JSON, each step needs a string - ID to attach to its JSON representation. Use this method to - register an ID for your step classes. Try to pick something - that's unlikely to clash with steps from other modules. - */ - static jsonID(id, stepClass) { - if (id in stepsByID) - throw new RangeError("Duplicate use of step JSON ID " + id); - stepsByID[id] = stepClass; - stepClass.prototype.jsonID = id; - return stepClass; - } - }; - var StepResult = class _StepResult { - /** - @internal - */ - constructor(doc4, failed) { - this.doc = doc4; - this.failed = failed; - } - /** - Create a successful step result. - */ - static ok(doc4) { - return new _StepResult(doc4, null); - } - /** - Create a failed step result. - */ - static fail(message) { - return new _StepResult(null, message); - } - /** - Call [`Node.replace`](https://prosemirror.net/docs/ref/#model.Node.replace) with the given - arguments. Create a successful result if it succeeds, and a - failed one if it throws a `ReplaceError`. - */ - static fromReplace(doc4, from, to, slice) { - try { - return _StepResult.ok(doc4.replace(from, to, slice)); - } catch (e2) { - if (e2 instanceof ReplaceError) - return _StepResult.fail(e2.message); - throw e2; - } - } - }; - function mapFragment(fragment, f3, parent) { - let mapped = []; - for (let i2 = 0; i2 < fragment.childCount; i2++) { - let child = fragment.child(i2); - if (child.content.size) - child = child.copy(mapFragment(child.content, f3, child)); - if (child.isInline) - child = f3(child, parent, i2); - mapped.push(child); - } - return Fragment.fromArray(mapped); - } - var AddMarkStep = class _AddMarkStep extends Step { - /** - Create a mark step. - */ - constructor(from, to, mark) { - super(); - this.from = from; - this.to = to; - this.mark = mark; - } - apply(doc4) { - let oldSlice = doc4.slice(this.from, this.to), $from = doc4.resolve(this.from); - let parent = $from.node($from.sharedDepth(this.to)); - let slice = new Slice(mapFragment(oldSlice.content, (node2, parent2) => { - if (!node2.isAtom || !parent2.type.allowsMarkType(this.mark.type)) - return node2; - return node2.mark(this.mark.addToSet(node2.marks)); - }, parent), oldSlice.openStart, oldSlice.openEnd); - return StepResult.fromReplace(doc4, this.from, this.to, slice); - } - invert() { - return new RemoveMarkStep(this.from, this.to, this.mark); - } - map(mapping) { - let from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1); - if (from.deleted && to.deleted || from.pos >= to.pos) - return null; - return new _AddMarkStep(from.pos, to.pos, this.mark); - } - merge(other) { - if (other instanceof _AddMarkStep && other.mark.eq(this.mark) && this.from <= other.to && this.to >= other.from) - return new _AddMarkStep(Math.min(this.from, other.from), Math.max(this.to, other.to), this.mark); - return null; - } - toJSON() { - return { - stepType: "addMark", - mark: this.mark.toJSON(), - from: this.from, - to: this.to - }; - } - /** - @internal - */ - static fromJSON(schema, json) { - if (typeof json.from != "number" || typeof json.to != "number") - throw new RangeError("Invalid input for AddMarkStep.fromJSON"); - return new _AddMarkStep(json.from, json.to, schema.markFromJSON(json.mark)); - } - }; - Step.jsonID("addMark", AddMarkStep); - var RemoveMarkStep = class _RemoveMarkStep extends Step { - /** - Create a mark-removing step. - */ - constructor(from, to, mark) { - super(); - this.from = from; - this.to = to; - this.mark = mark; - } - apply(doc4) { - let oldSlice = doc4.slice(this.from, this.to); - let slice = new Slice(mapFragment(oldSlice.content, (node2) => { - return node2.mark(this.mark.removeFromSet(node2.marks)); - }, doc4), oldSlice.openStart, oldSlice.openEnd); - return StepResult.fromReplace(doc4, this.from, this.to, slice); - } - invert() { - return new AddMarkStep(this.from, this.to, this.mark); - } - map(mapping) { - let from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1); - if (from.deleted && to.deleted || from.pos >= to.pos) - return null; - return new _RemoveMarkStep(from.pos, to.pos, this.mark); - } - merge(other) { - if (other instanceof _RemoveMarkStep && other.mark.eq(this.mark) && this.from <= other.to && this.to >= other.from) - return new _RemoveMarkStep(Math.min(this.from, other.from), Math.max(this.to, other.to), this.mark); - return null; - } - toJSON() { - return { - stepType: "removeMark", - mark: this.mark.toJSON(), - from: this.from, - to: this.to - }; - } - /** - @internal - */ - static fromJSON(schema, json) { - if (typeof json.from != "number" || typeof json.to != "number") - throw new RangeError("Invalid input for RemoveMarkStep.fromJSON"); - return new _RemoveMarkStep(json.from, json.to, schema.markFromJSON(json.mark)); - } - }; - Step.jsonID("removeMark", RemoveMarkStep); - var AddNodeMarkStep = class _AddNodeMarkStep extends Step { - /** - Create a node mark step. - */ - constructor(pos, mark) { - super(); - this.pos = pos; - this.mark = mark; - } - apply(doc4) { - let node2 = doc4.nodeAt(this.pos); - if (!node2) - return StepResult.fail("No node at mark step's position"); - let updated = node2.type.create(node2.attrs, null, this.mark.addToSet(node2.marks)); - return StepResult.fromReplace(doc4, this.pos, this.pos + 1, new Slice(Fragment.from(updated), 0, node2.isLeaf ? 0 : 1)); - } - invert(doc4) { - let node2 = doc4.nodeAt(this.pos); - if (node2) { - let newSet = this.mark.addToSet(node2.marks); - if (newSet.length == node2.marks.length) { - for (let i2 = 0; i2 < node2.marks.length; i2++) - if (!node2.marks[i2].isInSet(newSet)) - return new _AddNodeMarkStep(this.pos, node2.marks[i2]); - return new _AddNodeMarkStep(this.pos, this.mark); - } - } - return new RemoveNodeMarkStep(this.pos, this.mark); - } - map(mapping) { - let pos = mapping.mapResult(this.pos, 1); - return pos.deletedAfter ? null : new _AddNodeMarkStep(pos.pos, this.mark); - } - toJSON() { - return { stepType: "addNodeMark", pos: this.pos, mark: this.mark.toJSON() }; - } - /** - @internal - */ - static fromJSON(schema, json) { - if (typeof json.pos != "number") - throw new RangeError("Invalid input for AddNodeMarkStep.fromJSON"); - return new _AddNodeMarkStep(json.pos, schema.markFromJSON(json.mark)); - } - }; - Step.jsonID("addNodeMark", AddNodeMarkStep); - var RemoveNodeMarkStep = class _RemoveNodeMarkStep extends Step { - /** - Create a mark-removing step. - */ - constructor(pos, mark) { - super(); - this.pos = pos; - this.mark = mark; - } - apply(doc4) { - let node2 = doc4.nodeAt(this.pos); - if (!node2) - return StepResult.fail("No node at mark step's position"); - let updated = node2.type.create(node2.attrs, null, this.mark.removeFromSet(node2.marks)); - return StepResult.fromReplace(doc4, this.pos, this.pos + 1, new Slice(Fragment.from(updated), 0, node2.isLeaf ? 0 : 1)); - } - invert(doc4) { - let node2 = doc4.nodeAt(this.pos); - if (!node2 || !this.mark.isInSet(node2.marks)) - return this; - return new AddNodeMarkStep(this.pos, this.mark); - } - map(mapping) { - let pos = mapping.mapResult(this.pos, 1); - return pos.deletedAfter ? null : new _RemoveNodeMarkStep(pos.pos, this.mark); - } - toJSON() { - return { stepType: "removeNodeMark", pos: this.pos, mark: this.mark.toJSON() }; - } - /** - @internal - */ - static fromJSON(schema, json) { - if (typeof json.pos != "number") - throw new RangeError("Invalid input for RemoveNodeMarkStep.fromJSON"); - return new _RemoveNodeMarkStep(json.pos, schema.markFromJSON(json.mark)); - } - }; - Step.jsonID("removeNodeMark", RemoveNodeMarkStep); - var ReplaceStep = class _ReplaceStep extends Step { - /** - The given `slice` should fit the 'gap' between `from` and - `to`—the depths must line up, and the surrounding nodes must be - able to be joined with the open sides of the slice. When - `structure` is true, the step will fail if the content between - from and to is not just a sequence of closing and then opening - tokens (this is to guard against rebased replace steps - overwriting something they weren't supposed to). - */ - constructor(from, to, slice, structure = false) { - super(); - this.from = from; - this.to = to; - this.slice = slice; - this.structure = structure; - } - apply(doc4) { - if (this.structure && contentBetween(doc4, this.from, this.to)) - return StepResult.fail("Structure replace would overwrite content"); - return StepResult.fromReplace(doc4, this.from, this.to, this.slice); - } - getMap() { - return new StepMap([this.from, this.to - this.from, this.slice.size]); - } - invert(doc4) { - return new _ReplaceStep(this.from, this.from + this.slice.size, doc4.slice(this.from, this.to)); - } - map(mapping) { - let from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1); - if (from.deletedAcross && to.deletedAcross) - return null; - return new _ReplaceStep(from.pos, Math.max(from.pos, to.pos), this.slice); - } - merge(other) { - if (!(other instanceof _ReplaceStep) || other.structure || this.structure) - return null; - if (this.from + this.slice.size == other.from && !this.slice.openEnd && !other.slice.openStart) { - let slice = this.slice.size + other.slice.size == 0 ? Slice.empty : new Slice(this.slice.content.append(other.slice.content), this.slice.openStart, other.slice.openEnd); - return new _ReplaceStep(this.from, this.to + (other.to - other.from), slice, this.structure); - } else if (other.to == this.from && !this.slice.openStart && !other.slice.openEnd) { - let slice = this.slice.size + other.slice.size == 0 ? Slice.empty : new Slice(other.slice.content.append(this.slice.content), other.slice.openStart, this.slice.openEnd); - return new _ReplaceStep(other.from, this.to, slice, this.structure); - } else { - return null; - } - } - toJSON() { - let json = { stepType: "replace", from: this.from, to: this.to }; - if (this.slice.size) - json.slice = this.slice.toJSON(); - if (this.structure) - json.structure = true; - return json; - } - /** - @internal - */ - static fromJSON(schema, json) { - if (typeof json.from != "number" || typeof json.to != "number") - throw new RangeError("Invalid input for ReplaceStep.fromJSON"); - return new _ReplaceStep(json.from, json.to, Slice.fromJSON(schema, json.slice), !!json.structure); - } - }; - Step.jsonID("replace", ReplaceStep); - var ReplaceAroundStep = class _ReplaceAroundStep extends Step { - /** - Create a replace-around step with the given range and gap. - `insert` should be the point in the slice into which the content - of the gap should be moved. `structure` has the same meaning as - it has in the [`ReplaceStep`](https://prosemirror.net/docs/ref/#transform.ReplaceStep) class. - */ - constructor(from, to, gapFrom, gapTo, slice, insert, structure = false) { - super(); - this.from = from; - this.to = to; - this.gapFrom = gapFrom; - this.gapTo = gapTo; - this.slice = slice; - this.insert = insert; - this.structure = structure; - } - apply(doc4) { - if (this.structure && (contentBetween(doc4, this.from, this.gapFrom) || contentBetween(doc4, this.gapTo, this.to))) - return StepResult.fail("Structure gap-replace would overwrite content"); - let gap = doc4.slice(this.gapFrom, this.gapTo); - if (gap.openStart || gap.openEnd) - return StepResult.fail("Gap is not a flat range"); - let inserted = this.slice.insertAt(this.insert, gap.content); - if (!inserted) - return StepResult.fail("Content does not fit in gap"); - return StepResult.fromReplace(doc4, this.from, this.to, inserted); - } - getMap() { - return new StepMap([ - this.from, - this.gapFrom - this.from, - this.insert, - this.gapTo, - this.to - this.gapTo, - this.slice.size - this.insert - ]); - } - invert(doc4) { - let gap = this.gapTo - this.gapFrom; - return new _ReplaceAroundStep(this.from, this.from + this.slice.size + gap, this.from + this.insert, this.from + this.insert + gap, doc4.slice(this.from, this.to).removeBetween(this.gapFrom - this.from, this.gapTo - this.from), this.gapFrom - this.from, this.structure); - } - map(mapping) { - let from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1); - let gapFrom = this.from == this.gapFrom ? from.pos : mapping.map(this.gapFrom, -1); - let gapTo = this.to == this.gapTo ? to.pos : mapping.map(this.gapTo, 1); - if (from.deletedAcross && to.deletedAcross || gapFrom < from.pos || gapTo > to.pos) - return null; - return new _ReplaceAroundStep(from.pos, to.pos, gapFrom, gapTo, this.slice, this.insert, this.structure); - } - toJSON() { - let json = { - stepType: "replaceAround", - from: this.from, - to: this.to, - gapFrom: this.gapFrom, - gapTo: this.gapTo, - insert: this.insert - }; - if (this.slice.size) - json.slice = this.slice.toJSON(); - if (this.structure) - json.structure = true; - return json; - } - /** - @internal - */ - static fromJSON(schema, json) { - if (typeof json.from != "number" || typeof json.to != "number" || typeof json.gapFrom != "number" || typeof json.gapTo != "number" || typeof json.insert != "number") - throw new RangeError("Invalid input for ReplaceAroundStep.fromJSON"); - return new _ReplaceAroundStep(json.from, json.to, json.gapFrom, json.gapTo, Slice.fromJSON(schema, json.slice), json.insert, !!json.structure); - } - }; - Step.jsonID("replaceAround", ReplaceAroundStep); - function contentBetween(doc4, from, to) { - let $from = doc4.resolve(from), dist = to - from, depth = $from.depth; - while (dist > 0 && depth > 0 && $from.indexAfter(depth) == $from.node(depth).childCount) { - depth--; - dist--; - } - if (dist > 0) { - let next = $from.node(depth).maybeChild($from.indexAfter(depth)); - while (dist > 0) { - if (!next || next.isLeaf) - return true; - next = next.firstChild; - dist--; - } - } - return false; - } - function addMark(tr, from, to, mark) { - let removed = [], added = []; - let removing, adding; - tr.doc.nodesBetween(from, to, (node2, pos, parent) => { - if (!node2.isInline) - return; - let marks = node2.marks; - if (!mark.isInSet(marks) && parent.type.allowsMarkType(mark.type)) { - let start = Math.max(pos, from), end = Math.min(pos + node2.nodeSize, to); - let newSet = mark.addToSet(marks); - for (let i2 = 0; i2 < marks.length; i2++) { - if (!marks[i2].isInSet(newSet)) { - if (removing && removing.to == start && removing.mark.eq(marks[i2])) - removing.to = end; - else - removed.push(removing = new RemoveMarkStep(start, end, marks[i2])); - } - } - if (adding && adding.to == start) - adding.to = end; - else - added.push(adding = new AddMarkStep(start, end, mark)); - } - }); - removed.forEach((s2) => tr.step(s2)); - added.forEach((s2) => tr.step(s2)); - } - function removeMark(tr, from, to, mark) { - let matched = [], step = 0; - tr.doc.nodesBetween(from, to, (node2, pos) => { - if (!node2.isInline) - return; - step++; - let toRemove = null; - if (mark instanceof MarkType) { - let set = node2.marks, found2; - while (found2 = mark.isInSet(set)) { - (toRemove || (toRemove = [])).push(found2); - set = found2.removeFromSet(set); - } - } else if (mark) { - if (mark.isInSet(node2.marks)) - toRemove = [mark]; - } else { - toRemove = node2.marks; - } - if (toRemove && toRemove.length) { - let end = Math.min(pos + node2.nodeSize, to); - for (let i2 = 0; i2 < toRemove.length; i2++) { - let style2 = toRemove[i2], found2; - for (let j6 = 0; j6 < matched.length; j6++) { - let m3 = matched[j6]; - if (m3.step == step - 1 && style2.eq(matched[j6].style)) - found2 = m3; - } - if (found2) { - found2.to = end; - found2.step = step; - } else { - matched.push({ style: style2, from: Math.max(pos, from), to: end, step }); - } - } - } - }); - matched.forEach((m3) => tr.step(new RemoveMarkStep(m3.from, m3.to, m3.style))); - } - function clearIncompatible(tr, pos, parentType, match = parentType.contentMatch, clearNewlines = true) { - let node2 = tr.doc.nodeAt(pos); - let replSteps = [], cur = pos + 1; - for (let i2 = 0; i2 < node2.childCount; i2++) { - let child = node2.child(i2), end = cur + child.nodeSize; - let allowed = match.matchType(child.type); - if (!allowed) { - replSteps.push(new ReplaceStep(cur, end, Slice.empty)); - } else { - match = allowed; - for (let j6 = 0; j6 < child.marks.length; j6++) - if (!parentType.allowsMarkType(child.marks[j6].type)) - tr.step(new RemoveMarkStep(cur, end, child.marks[j6])); - if (clearNewlines && child.isText && parentType.whitespace != "pre") { - let m3, newline = /\r?\n|\r/g, slice; - while (m3 = newline.exec(child.text)) { - if (!slice) - slice = new Slice(Fragment.from(parentType.schema.text(" ", parentType.allowedMarks(child.marks))), 0, 0); - replSteps.push(new ReplaceStep(cur + m3.index, cur + m3.index + m3[0].length, slice)); - } - } - } - cur = end; - } - if (!match.validEnd) { - let fill = match.fillBefore(Fragment.empty, true); - tr.replace(cur, cur, new Slice(fill, 0, 0)); - } - for (let i2 = replSteps.length - 1; i2 >= 0; i2--) - tr.step(replSteps[i2]); - } - function canCut(node2, start, end) { - return (start == 0 || node2.canReplace(start, node2.childCount)) && (end == node2.childCount || node2.canReplace(0, end)); - } - function liftTarget(range) { - let parent = range.parent; - let content3 = parent.content.cutByIndex(range.startIndex, range.endIndex); - for (let depth = range.depth; ; --depth) { - let node2 = range.$from.node(depth); - let index2 = range.$from.index(depth), endIndex = range.$to.indexAfter(depth); - if (depth < range.depth && node2.canReplace(index2, endIndex, content3)) - return depth; - if (depth == 0 || node2.type.spec.isolating || !canCut(node2, index2, endIndex)) - break; - } - return null; - } - function lift(tr, range, target) { - let { $from, $to, depth } = range; - let gapStart = $from.before(depth + 1), gapEnd = $to.after(depth + 1); - let start = gapStart, end = gapEnd; - let before = Fragment.empty, openStart = 0; - for (let d6 = depth, splitting = false; d6 > target; d6--) - if (splitting || $from.index(d6) > 0) { - splitting = true; - before = Fragment.from($from.node(d6).copy(before)); - openStart++; - } else { - start--; - } - let after = Fragment.empty, openEnd = 0; - for (let d6 = depth, splitting = false; d6 > target; d6--) - if (splitting || $to.after(d6 + 1) < $to.end(d6)) { - splitting = true; - after = Fragment.from($to.node(d6).copy(after)); - openEnd++; - } else { - end++; - } - tr.step(new ReplaceAroundStep(start, end, gapStart, gapEnd, new Slice(before.append(after), openStart, openEnd), before.size - openStart, true)); - } - function findWrapping(range, nodeType, attrs = null, innerRange = range) { - let around = findWrappingOutside(range, nodeType); - let inner = around && findWrappingInside(innerRange, nodeType); - if (!inner) - return null; - return around.map(withAttrs).concat({ type: nodeType, attrs }).concat(inner.map(withAttrs)); - } - function withAttrs(type) { - return { type, attrs: null }; - } - function findWrappingOutside(range, type) { - let { parent, startIndex, endIndex } = range; - let around = parent.contentMatchAt(startIndex).findWrapping(type); - if (!around) - return null; - let outer = around.length ? around[0] : type; - return parent.canReplaceWith(startIndex, endIndex, outer) ? around : null; - } - function findWrappingInside(range, type) { - let { parent, startIndex, endIndex } = range; - let inner = parent.child(startIndex); - let inside = type.contentMatch.findWrapping(inner.type); - if (!inside) - return null; - let lastType = inside.length ? inside[inside.length - 1] : type; - let innerMatch = lastType.contentMatch; - for (let i2 = startIndex; innerMatch && i2 < endIndex; i2++) - innerMatch = innerMatch.matchType(parent.child(i2).type); - if (!innerMatch || !innerMatch.validEnd) - return null; - return inside; - } - function wrap2(tr, range, wrappers) { - let content3 = Fragment.empty; - for (let i2 = wrappers.length - 1; i2 >= 0; i2--) { - if (content3.size) { - let match = wrappers[i2].type.contentMatch.matchFragment(content3); - if (!match || !match.validEnd) - throw new RangeError("Wrapper type given to Transform.wrap does not form valid content of its parent wrapper"); - } - content3 = Fragment.from(wrappers[i2].type.create(wrappers[i2].attrs, content3)); - } - let start = range.start, end = range.end; - tr.step(new ReplaceAroundStep(start, end, start, end, new Slice(content3, 0, 0), wrappers.length, true)); - } - function setBlockType(tr, from, to, type, attrs) { - if (!type.isTextblock) - throw new RangeError("Type given to setBlockType should be a textblock"); - let mapFrom = tr.steps.length; - tr.doc.nodesBetween(from, to, (node2, pos) => { - if (node2.isTextblock && !node2.hasMarkup(type, attrs) && canChangeType(tr.doc, tr.mapping.slice(mapFrom).map(pos), type)) { - let convertNewlines = null; - if (type.schema.linebreakReplacement) { - let pre = type.whitespace == "pre", supportLinebreak = !!type.contentMatch.matchType(type.schema.linebreakReplacement); - if (pre && !supportLinebreak) - convertNewlines = false; - else if (!pre && supportLinebreak) - convertNewlines = true; - } - if (convertNewlines === false) - replaceLinebreaks(tr, node2, pos, mapFrom); - clearIncompatible(tr, tr.mapping.slice(mapFrom).map(pos, 1), type, void 0, convertNewlines === null); - let mapping = tr.mapping.slice(mapFrom); - let startM = mapping.map(pos, 1), endM = mapping.map(pos + node2.nodeSize, 1); - tr.step(new ReplaceAroundStep(startM, endM, startM + 1, endM - 1, new Slice(Fragment.from(type.create(attrs, null, node2.marks)), 0, 0), 1, true)); - if (convertNewlines === true) - replaceNewlines(tr, node2, pos, mapFrom); - return false; - } - }); - } - function replaceNewlines(tr, node2, pos, mapFrom) { - node2.forEach((child, offset) => { - if (child.isText) { - let m3, newline = /\r?\n|\r/g; - while (m3 = newline.exec(child.text)) { - let start = tr.mapping.slice(mapFrom).map(pos + 1 + offset + m3.index); - tr.replaceWith(start, start + 1, node2.type.schema.linebreakReplacement.create()); - } - } - }); - } - function replaceLinebreaks(tr, node2, pos, mapFrom) { - node2.forEach((child, offset) => { - if (child.type == child.type.schema.linebreakReplacement) { - let start = tr.mapping.slice(mapFrom).map(pos + 1 + offset); - tr.replaceWith(start, start + 1, node2.type.schema.text("\n")); - } - }); - } - function canChangeType(doc4, pos, type) { - let $pos = doc4.resolve(pos), index2 = $pos.index(); - return $pos.parent.canReplaceWith(index2, index2 + 1, type); - } - function setNodeMarkup(tr, pos, type, attrs, marks) { - let node2 = tr.doc.nodeAt(pos); - if (!node2) - throw new RangeError("No node at given position"); - if (!type) - type = node2.type; - let newNode = type.create(attrs, null, marks || node2.marks); - if (node2.isLeaf) - return tr.replaceWith(pos, pos + node2.nodeSize, newNode); - if (!type.validContent(node2.content)) - throw new RangeError("Invalid content for node type " + type.name); - tr.step(new ReplaceAroundStep(pos, pos + node2.nodeSize, pos + 1, pos + node2.nodeSize - 1, new Slice(Fragment.from(newNode), 0, 0), 1, true)); - } - function canSplit(doc4, pos, depth = 1, typesAfter) { - let $pos = doc4.resolve(pos), base2 = $pos.depth - depth; - let innerType = typesAfter && typesAfter[typesAfter.length - 1] || $pos.parent; - if (base2 < 0 || $pos.parent.type.spec.isolating || !$pos.parent.canReplace($pos.index(), $pos.parent.childCount) || !innerType.type.validContent($pos.parent.content.cutByIndex($pos.index(), $pos.parent.childCount))) - return false; - for (let d6 = $pos.depth - 1, i2 = depth - 2; d6 > base2; d6--, i2--) { - let node2 = $pos.node(d6), index3 = $pos.index(d6); - if (node2.type.spec.isolating) - return false; - let rest = node2.content.cutByIndex(index3, node2.childCount); - let overrideChild = typesAfter && typesAfter[i2 + 1]; - if (overrideChild) - rest = rest.replaceChild(0, overrideChild.type.create(overrideChild.attrs)); - let after = typesAfter && typesAfter[i2] || node2; - if (!node2.canReplace(index3 + 1, node2.childCount) || !after.type.validContent(rest)) - return false; - } - let index2 = $pos.indexAfter(base2); - let baseType = typesAfter && typesAfter[0]; - return $pos.node(base2).canReplaceWith(index2, index2, baseType ? baseType.type : $pos.node(base2 + 1).type); - } - function split(tr, pos, depth = 1, typesAfter) { - let $pos = tr.doc.resolve(pos), before = Fragment.empty, after = Fragment.empty; - for (let d6 = $pos.depth, e2 = $pos.depth - depth, i2 = depth - 1; d6 > e2; d6--, i2--) { - before = Fragment.from($pos.node(d6).copy(before)); - let typeAfter = typesAfter && typesAfter[i2]; - after = Fragment.from(typeAfter ? typeAfter.type.create(typeAfter.attrs, after) : $pos.node(d6).copy(after)); - } - tr.step(new ReplaceStep(pos, pos, new Slice(before.append(after), depth, depth), true)); - } - function canJoin(doc4, pos) { - let $pos = doc4.resolve(pos), index2 = $pos.index(); - return joinable2($pos.nodeBefore, $pos.nodeAfter) && $pos.parent.canReplace(index2, index2 + 1); - } - function joinable2(a2, b4) { - return !!(a2 && b4 && !a2.isLeaf && a2.canAppend(b4)); - } - function join3(tr, pos, depth) { - let step = new ReplaceStep(pos - depth, pos + depth, Slice.empty, true); - tr.step(step); - } - function insertPoint(doc4, pos, nodeType) { - let $pos = doc4.resolve(pos); - if ($pos.parent.canReplaceWith($pos.index(), $pos.index(), nodeType)) - return pos; - if ($pos.parentOffset == 0) - for (let d6 = $pos.depth - 1; d6 >= 0; d6--) { - let index2 = $pos.index(d6); - if ($pos.node(d6).canReplaceWith(index2, index2, nodeType)) - return $pos.before(d6 + 1); - if (index2 > 0) - return null; - } - if ($pos.parentOffset == $pos.parent.content.size) - for (let d6 = $pos.depth - 1; d6 >= 0; d6--) { - let index2 = $pos.indexAfter(d6); - if ($pos.node(d6).canReplaceWith(index2, index2, nodeType)) - return $pos.after(d6 + 1); - if (index2 < $pos.node(d6).childCount) - return null; - } - return null; - } - function dropPoint(doc4, pos, slice) { - let $pos = doc4.resolve(pos); - if (!slice.content.size) - return pos; - let content3 = slice.content; - for (let i2 = 0; i2 < slice.openStart; i2++) - content3 = content3.firstChild.content; - for (let pass = 1; pass <= (slice.openStart == 0 && slice.size ? 2 : 1); pass++) { - for (let d6 = $pos.depth; d6 >= 0; d6--) { - let bias = d6 == $pos.depth ? 0 : $pos.pos <= ($pos.start(d6 + 1) + $pos.end(d6 + 1)) / 2 ? -1 : 1; - let insertPos = $pos.index(d6) + (bias > 0 ? 1 : 0); - let parent = $pos.node(d6), fits = false; - if (pass == 1) { - fits = parent.canReplace(insertPos, insertPos, content3); - } else { - let wrapping = parent.contentMatchAt(insertPos).findWrapping(content3.firstChild.type); - fits = wrapping && parent.canReplaceWith(insertPos, insertPos, wrapping[0]); - } - if (fits) - return bias == 0 ? $pos.pos : bias < 0 ? $pos.before(d6 + 1) : $pos.after(d6 + 1); - } - } - return null; - } - function replaceStep(doc4, from, to = from, slice = Slice.empty) { - if (from == to && !slice.size) - return null; - let $from = doc4.resolve(from), $to = doc4.resolve(to); - if (fitsTrivially($from, $to, slice)) - return new ReplaceStep(from, to, slice); - return new Fitter($from, $to, slice).fit(); - } - function fitsTrivially($from, $to, slice) { - return !slice.openStart && !slice.openEnd && $from.start() == $to.start() && $from.parent.canReplace($from.index(), $to.index(), slice.content); - } - var Fitter = class { - constructor($from, $to, unplaced) { - this.$from = $from; - this.$to = $to; - this.unplaced = unplaced; - this.frontier = []; - this.placed = Fragment.empty; - for (let i2 = 0; i2 <= $from.depth; i2++) { - let node2 = $from.node(i2); - this.frontier.push({ - type: node2.type, - match: node2.contentMatchAt($from.indexAfter(i2)) - }); - } - for (let i2 = $from.depth; i2 > 0; i2--) - this.placed = Fragment.from($from.node(i2).copy(this.placed)); - } - get depth() { - return this.frontier.length - 1; - } - fit() { - while (this.unplaced.size) { - let fit = this.findFittable(); - if (fit) - this.placeNodes(fit); - else - this.openMore() || this.dropNode(); - } - let moveInline = this.mustMoveInline(), placedSize = this.placed.size - this.depth - this.$from.depth; - let $from = this.$from, $to = this.close(moveInline < 0 ? this.$to : $from.doc.resolve(moveInline)); - if (!$to) - return null; - let content3 = this.placed, openStart = $from.depth, openEnd = $to.depth; - while (openStart && openEnd && content3.childCount == 1) { - content3 = content3.firstChild.content; - openStart--; - openEnd--; - } - let slice = new Slice(content3, openStart, openEnd); - if (moveInline > -1) - return new ReplaceAroundStep($from.pos, moveInline, this.$to.pos, this.$to.end(), slice, placedSize); - if (slice.size || $from.pos != this.$to.pos) - return new ReplaceStep($from.pos, $to.pos, slice); - return null; - } - // Find a position on the start spine of `this.unplaced` that has - // content that can be moved somewhere on the frontier. Returns two - // depths, one for the slice and one for the frontier. - findFittable() { - let startDepth = this.unplaced.openStart; - for (let cur = this.unplaced.content, d6 = 0, openEnd = this.unplaced.openEnd; d6 < startDepth; d6++) { - let node2 = cur.firstChild; - if (cur.childCount > 1) - openEnd = 0; - if (node2.type.spec.isolating && openEnd <= d6) { - startDepth = d6; - break; - } - cur = node2.content; - } - for (let pass = 1; pass <= 2; pass++) { - for (let sliceDepth = pass == 1 ? startDepth : this.unplaced.openStart; sliceDepth >= 0; sliceDepth--) { - let fragment, parent = null; - if (sliceDepth) { - parent = contentAt(this.unplaced.content, sliceDepth - 1).firstChild; - fragment = parent.content; - } else { - fragment = this.unplaced.content; - } - let first = fragment.firstChild; - for (let frontierDepth = this.depth; frontierDepth >= 0; frontierDepth--) { - let { type, match } = this.frontier[frontierDepth], wrap3, inject = null; - if (pass == 1 && (first ? match.matchType(first.type) || (inject = match.fillBefore(Fragment.from(first), false)) : parent && type.compatibleContent(parent.type))) - return { sliceDepth, frontierDepth, parent, inject }; - else if (pass == 2 && first && (wrap3 = match.findWrapping(first.type))) - return { sliceDepth, frontierDepth, parent, wrap: wrap3 }; - if (parent && match.matchType(parent.type)) - break; - } - } - } - } - openMore() { - let { content: content3, openStart, openEnd } = this.unplaced; - let inner = contentAt(content3, openStart); - if (!inner.childCount || inner.firstChild.isLeaf) - return false; - this.unplaced = new Slice(content3, openStart + 1, Math.max(openEnd, inner.size + openStart >= content3.size - openEnd ? openStart + 1 : 0)); - return true; - } - dropNode() { - let { content: content3, openStart, openEnd } = this.unplaced; - let inner = contentAt(content3, openStart); - if (inner.childCount <= 1 && openStart > 0) { - let openAtEnd = content3.size - openStart <= openStart + inner.size; - this.unplaced = new Slice(dropFromFragment(content3, openStart - 1, 1), openStart - 1, openAtEnd ? openStart - 1 : openEnd); - } else { - this.unplaced = new Slice(dropFromFragment(content3, openStart, 1), openStart, openEnd); - } - } - // Move content from the unplaced slice at `sliceDepth` to the - // frontier node at `frontierDepth`. Close that frontier node when - // applicable. - placeNodes({ sliceDepth, frontierDepth, parent, inject, wrap: wrap3 }) { - while (this.depth > frontierDepth) - this.closeFrontierNode(); - if (wrap3) - for (let i2 = 0; i2 < wrap3.length; i2++) - this.openFrontierNode(wrap3[i2]); - let slice = this.unplaced, fragment = parent ? parent.content : slice.content; - let openStart = slice.openStart - sliceDepth; - let taken = 0, add = []; - let { match, type } = this.frontier[frontierDepth]; - if (inject) { - for (let i2 = 0; i2 < inject.childCount; i2++) - add.push(inject.child(i2)); - match = match.matchFragment(inject); - } - let openEndCount = fragment.size + sliceDepth - (slice.content.size - slice.openEnd); - while (taken < fragment.childCount) { - let next = fragment.child(taken), matches2 = match.matchType(next.type); - if (!matches2) - break; - taken++; - if (taken > 1 || openStart == 0 || next.content.size) { - match = matches2; - add.push(closeNodeStart(next.mark(type.allowedMarks(next.marks)), taken == 1 ? openStart : 0, taken == fragment.childCount ? openEndCount : -1)); - } - } - let toEnd = taken == fragment.childCount; - if (!toEnd) - openEndCount = -1; - this.placed = addToFragment(this.placed, frontierDepth, Fragment.from(add)); - this.frontier[frontierDepth].match = match; - if (toEnd && openEndCount < 0 && parent && parent.type == this.frontier[this.depth].type && this.frontier.length > 1) - this.closeFrontierNode(); - for (let i2 = 0, cur = fragment; i2 < openEndCount; i2++) { - let node2 = cur.lastChild; - this.frontier.push({ type: node2.type, match: node2.contentMatchAt(node2.childCount) }); - cur = node2.content; - } - this.unplaced = !toEnd ? new Slice(dropFromFragment(slice.content, sliceDepth, taken), slice.openStart, slice.openEnd) : sliceDepth == 0 ? Slice.empty : new Slice(dropFromFragment(slice.content, sliceDepth - 1, 1), sliceDepth - 1, openEndCount < 0 ? slice.openEnd : sliceDepth - 1); - } - mustMoveInline() { - if (!this.$to.parent.isTextblock) - return -1; - let top = this.frontier[this.depth], level; - if (!top.type.isTextblock || !contentAfterFits(this.$to, this.$to.depth, top.type, top.match, false) || this.$to.depth == this.depth && (level = this.findCloseLevel(this.$to)) && level.depth == this.depth) - return -1; - let { depth } = this.$to, after = this.$to.after(depth); - while (depth > 1 && after == this.$to.end(--depth)) - ++after; - return after; - } - findCloseLevel($to) { - scan: for (let i2 = Math.min(this.depth, $to.depth); i2 >= 0; i2--) { - let { match, type } = this.frontier[i2]; - let dropInner = i2 < $to.depth && $to.end(i2 + 1) == $to.pos + ($to.depth - (i2 + 1)); - let fit = contentAfterFits($to, i2, type, match, dropInner); - if (!fit) - continue; - for (let d6 = i2 - 1; d6 >= 0; d6--) { - let { match: match2, type: type2 } = this.frontier[d6]; - let matches2 = contentAfterFits($to, d6, type2, match2, true); - if (!matches2 || matches2.childCount) - continue scan; - } - return { depth: i2, fit, move: dropInner ? $to.doc.resolve($to.after(i2 + 1)) : $to }; - } - } - close($to) { - let close2 = this.findCloseLevel($to); - if (!close2) - return null; - while (this.depth > close2.depth) - this.closeFrontierNode(); - if (close2.fit.childCount) - this.placed = addToFragment(this.placed, close2.depth, close2.fit); - $to = close2.move; - for (let d6 = close2.depth + 1; d6 <= $to.depth; d6++) { - let node2 = $to.node(d6), add = node2.type.contentMatch.fillBefore(node2.content, true, $to.index(d6)); - this.openFrontierNode(node2.type, node2.attrs, add); - } - return $to; - } - openFrontierNode(type, attrs = null, content3) { - let top = this.frontier[this.depth]; - top.match = top.match.matchType(type); - this.placed = addToFragment(this.placed, this.depth, Fragment.from(type.create(attrs, content3))); - this.frontier.push({ type, match: type.contentMatch }); - } - closeFrontierNode() { - let open = this.frontier.pop(); - let add = open.match.fillBefore(Fragment.empty, true); - if (add.childCount) - this.placed = addToFragment(this.placed, this.frontier.length, add); - } - }; - function dropFromFragment(fragment, depth, count) { - if (depth == 0) - return fragment.cutByIndex(count, fragment.childCount); - return fragment.replaceChild(0, fragment.firstChild.copy(dropFromFragment(fragment.firstChild.content, depth - 1, count))); - } - function addToFragment(fragment, depth, content3) { - if (depth == 0) - return fragment.append(content3); - return fragment.replaceChild(fragment.childCount - 1, fragment.lastChild.copy(addToFragment(fragment.lastChild.content, depth - 1, content3))); - } - function contentAt(fragment, depth) { - for (let i2 = 0; i2 < depth; i2++) - fragment = fragment.firstChild.content; - return fragment; - } - function closeNodeStart(node2, openStart, openEnd) { - if (openStart <= 0) - return node2; - let frag = node2.content; - if (openStart > 1) - frag = frag.replaceChild(0, closeNodeStart(frag.firstChild, openStart - 1, frag.childCount == 1 ? openEnd - 1 : 0)); - if (openStart > 0) { - frag = node2.type.contentMatch.fillBefore(frag).append(frag); - if (openEnd <= 0) - frag = frag.append(node2.type.contentMatch.matchFragment(frag).fillBefore(Fragment.empty, true)); - } - return node2.copy(frag); - } - function contentAfterFits($to, depth, type, match, open) { - let node2 = $to.node(depth), index2 = open ? $to.indexAfter(depth) : $to.index(depth); - if (index2 == node2.childCount && !type.compatibleContent(node2.type)) - return null; - let fit = match.fillBefore(node2.content, true, index2); - return fit && !invalidMarks(type, node2.content, index2) ? fit : null; - } - function invalidMarks(type, fragment, start) { - for (let i2 = start; i2 < fragment.childCount; i2++) - if (!type.allowsMarks(fragment.child(i2).marks)) - return true; - return false; - } - function definesContent(type) { - return type.spec.defining || type.spec.definingForContent; - } - function replaceRange(tr, from, to, slice) { - if (!slice.size) - return tr.deleteRange(from, to); - let $from = tr.doc.resolve(from), $to = tr.doc.resolve(to); - if (fitsTrivially($from, $to, slice)) - return tr.step(new ReplaceStep(from, to, slice)); - let targetDepths = coveredDepths($from, tr.doc.resolve(to)); - if (targetDepths[targetDepths.length - 1] == 0) - targetDepths.pop(); - let preferredTarget = -($from.depth + 1); - targetDepths.unshift(preferredTarget); - for (let d6 = $from.depth, pos = $from.pos - 1; d6 > 0; d6--, pos--) { - let spec = $from.node(d6).type.spec; - if (spec.defining || spec.definingAsContext || spec.isolating) - break; - if (targetDepths.indexOf(d6) > -1) - preferredTarget = d6; - else if ($from.before(d6) == pos) - targetDepths.splice(1, 0, -d6); - } - let preferredTargetIndex = targetDepths.indexOf(preferredTarget); - let leftNodes = [], preferredDepth = slice.openStart; - for (let content3 = slice.content, i2 = 0; ; i2++) { - let node2 = content3.firstChild; - leftNodes.push(node2); - if (i2 == slice.openStart) - break; - content3 = node2.content; - } - for (let d6 = preferredDepth - 1; d6 >= 0; d6--) { - let leftNode = leftNodes[d6], def = definesContent(leftNode.type); - if (def && !leftNode.sameMarkup($from.node(Math.abs(preferredTarget) - 1))) - preferredDepth = d6; - else if (def || !leftNode.type.isTextblock) - break; - } - for (let j6 = slice.openStart; j6 >= 0; j6--) { - let openDepth = (j6 + preferredDepth + 1) % (slice.openStart + 1); - let insert = leftNodes[openDepth]; - if (!insert) - continue; - for (let i2 = 0; i2 < targetDepths.length; i2++) { - let targetDepth = targetDepths[(i2 + preferredTargetIndex) % targetDepths.length], expand = true; - if (targetDepth < 0) { - expand = false; - targetDepth = -targetDepth; - } - let parent = $from.node(targetDepth - 1), index2 = $from.index(targetDepth - 1); - if (parent.canReplaceWith(index2, index2, insert.type, insert.marks)) - return tr.replace($from.before(targetDepth), expand ? $to.after(targetDepth) : to, new Slice(closeFragment(slice.content, 0, slice.openStart, openDepth), openDepth, slice.openEnd)); - } - } - let startSteps = tr.steps.length; - for (let i2 = targetDepths.length - 1; i2 >= 0; i2--) { - tr.replace(from, to, slice); - if (tr.steps.length > startSteps) - break; - let depth = targetDepths[i2]; - if (depth < 0) - continue; - from = $from.before(depth); - to = $to.after(depth); - } - } - function closeFragment(fragment, depth, oldOpen, newOpen, parent) { - if (depth < oldOpen) { - let first = fragment.firstChild; - fragment = fragment.replaceChild(0, first.copy(closeFragment(first.content, depth + 1, oldOpen, newOpen, first))); - } - if (depth > newOpen) { - let match = parent.contentMatchAt(0); - let start = match.fillBefore(fragment).append(fragment); - fragment = start.append(match.matchFragment(start).fillBefore(Fragment.empty, true)); - } - return fragment; - } - function replaceRangeWith(tr, from, to, node2) { - if (!node2.isInline && from == to && tr.doc.resolve(from).parent.content.size) { - let point3 = insertPoint(tr.doc, from, node2.type); - if (point3 != null) - from = to = point3; - } - tr.replaceRange(from, to, new Slice(Fragment.from(node2), 0, 0)); - } - function deleteRange(tr, from, to) { - let $from = tr.doc.resolve(from), $to = tr.doc.resolve(to); - let covered = coveredDepths($from, $to); - for (let i2 = 0; i2 < covered.length; i2++) { - let depth = covered[i2], last = i2 == covered.length - 1; - if (last && depth == 0 || $from.node(depth).type.contentMatch.validEnd) - return tr.delete($from.start(depth), $to.end(depth)); - if (depth > 0 && (last || $from.node(depth - 1).canReplace($from.index(depth - 1), $to.indexAfter(depth - 1)))) - return tr.delete($from.before(depth), $to.after(depth)); - } - for (let d6 = 1; d6 <= $from.depth && d6 <= $to.depth; d6++) { - if (from - $from.start(d6) == $from.depth - d6 && to > $from.end(d6) && $to.end(d6) - to != $to.depth - d6) - return tr.delete($from.before(d6), to); - } - tr.delete(from, to); - } - function coveredDepths($from, $to) { - let result = [], minDepth = Math.min($from.depth, $to.depth); - for (let d6 = minDepth; d6 >= 0; d6--) { - let start = $from.start(d6); - if (start < $from.pos - ($from.depth - d6) || $to.end(d6) > $to.pos + ($to.depth - d6) || $from.node(d6).type.spec.isolating || $to.node(d6).type.spec.isolating) - break; - if (start == $to.start(d6) || d6 == $from.depth && d6 == $to.depth && $from.parent.inlineContent && $to.parent.inlineContent && d6 && $to.start(d6 - 1) == start - 1) - result.push(d6); - } - return result; - } - var AttrStep = class _AttrStep extends Step { - /** - Construct an attribute step. - */ - constructor(pos, attr, value) { - super(); - this.pos = pos; - this.attr = attr; - this.value = value; - } - apply(doc4) { - let node2 = doc4.nodeAt(this.pos); - if (!node2) - return StepResult.fail("No node at attribute step's position"); - let attrs = /* @__PURE__ */ Object.create(null); - for (let name in node2.attrs) - attrs[name] = node2.attrs[name]; - attrs[this.attr] = this.value; - let updated = node2.type.create(attrs, null, node2.marks); - return StepResult.fromReplace(doc4, this.pos, this.pos + 1, new Slice(Fragment.from(updated), 0, node2.isLeaf ? 0 : 1)); - } - getMap() { - return StepMap.empty; - } - invert(doc4) { - return new _AttrStep(this.pos, this.attr, doc4.nodeAt(this.pos).attrs[this.attr]); - } - map(mapping) { - let pos = mapping.mapResult(this.pos, 1); - return pos.deletedAfter ? null : new _AttrStep(pos.pos, this.attr, this.value); - } - toJSON() { - return { stepType: "attr", pos: this.pos, attr: this.attr, value: this.value }; - } - static fromJSON(schema, json) { - if (typeof json.pos != "number" || typeof json.attr != "string") - throw new RangeError("Invalid input for AttrStep.fromJSON"); - return new _AttrStep(json.pos, json.attr, json.value); - } - }; - Step.jsonID("attr", AttrStep); - var DocAttrStep = class _DocAttrStep extends Step { - /** - Construct an attribute step. - */ - constructor(attr, value) { - super(); - this.attr = attr; - this.value = value; - } - apply(doc4) { - let attrs = /* @__PURE__ */ Object.create(null); - for (let name in doc4.attrs) - attrs[name] = doc4.attrs[name]; - attrs[this.attr] = this.value; - let updated = doc4.type.create(attrs, doc4.content, doc4.marks); - return StepResult.ok(updated); - } - getMap() { - return StepMap.empty; - } - invert(doc4) { - return new _DocAttrStep(this.attr, doc4.attrs[this.attr]); - } - map(mapping) { - return this; - } - toJSON() { - return { stepType: "docAttr", attr: this.attr, value: this.value }; - } - static fromJSON(schema, json) { - if (typeof json.attr != "string") - throw new RangeError("Invalid input for DocAttrStep.fromJSON"); - return new _DocAttrStep(json.attr, json.value); - } - }; - Step.jsonID("docAttr", DocAttrStep); - var TransformError = class extends Error { - }; - TransformError = function TransformError2(message) { - let err = Error.call(this, message); - err.__proto__ = TransformError2.prototype; - return err; - }; - TransformError.prototype = Object.create(Error.prototype); - TransformError.prototype.constructor = TransformError; - TransformError.prototype.name = "TransformError"; - var Transform = class { - /** - Create a transform that starts with the given document. - */ - constructor(doc4) { - this.doc = doc4; - this.steps = []; - this.docs = []; - this.mapping = new Mapping(); - } - /** - The starting document. - */ - get before() { - return this.docs.length ? this.docs[0] : this.doc; - } - /** - Apply a new step in this transform, saving the result. Throws an - error when the step fails. - */ - step(step) { - let result = this.maybeStep(step); - if (result.failed) - throw new TransformError(result.failed); - return this; - } - /** - Try to apply a step in this transformation, ignoring it if it - fails. Returns the step result. - */ - maybeStep(step) { - let result = step.apply(this.doc); - if (!result.failed) - this.addStep(step, result.doc); - return result; - } - /** - True when the document has been changed (when there are any - steps). - */ - get docChanged() { - return this.steps.length > 0; - } - /** - @internal - */ - addStep(step, doc4) { - this.docs.push(this.doc); - this.steps.push(step); - this.mapping.appendMap(step.getMap()); - this.doc = doc4; - } - /** - Replace the part of the document between `from` and `to` with the - given `slice`. - */ - replace(from, to = from, slice = Slice.empty) { - let step = replaceStep(this.doc, from, to, slice); - if (step) - this.step(step); - return this; - } - /** - Replace the given range with the given content, which may be a - fragment, node, or array of nodes. - */ - replaceWith(from, to, content3) { - return this.replace(from, to, new Slice(Fragment.from(content3), 0, 0)); - } - /** - Delete the content between the given positions. - */ - delete(from, to) { - return this.replace(from, to, Slice.empty); - } - /** - Insert the given content at the given position. - */ - insert(pos, content3) { - return this.replaceWith(pos, pos, content3); - } - /** - Replace a range of the document with a given slice, using - `from`, `to`, and the slice's - [`openStart`](https://prosemirror.net/docs/ref/#model.Slice.openStart) property as hints, rather - than fixed start and end points. This method may grow the - replaced area or close open nodes in the slice in order to get a - fit that is more in line with WYSIWYG expectations, by dropping - fully covered parent nodes of the replaced region when they are - marked [non-defining as - context](https://prosemirror.net/docs/ref/#model.NodeSpec.definingAsContext), or including an - open parent node from the slice that _is_ marked as [defining - its content](https://prosemirror.net/docs/ref/#model.NodeSpec.definingForContent). - - This is the method, for example, to handle paste. The similar - [`replace`](https://prosemirror.net/docs/ref/#transform.Transform.replace) method is a more - primitive tool which will _not_ move the start and end of its given - range, and is useful in situations where you need more precise - control over what happens. - */ - replaceRange(from, to, slice) { - replaceRange(this, from, to, slice); - return this; - } - /** - Replace the given range with a node, but use `from` and `to` as - hints, rather than precise positions. When from and to are the same - and are at the start or end of a parent node in which the given - node doesn't fit, this method may _move_ them out towards a parent - that does allow the given node to be placed. When the given range - completely covers a parent node, this method may completely replace - that parent node. - */ - replaceRangeWith(from, to, node2) { - replaceRangeWith(this, from, to, node2); - return this; - } - /** - Delete the given range, expanding it to cover fully covered - parent nodes until a valid replace is found. - */ - deleteRange(from, to) { - deleteRange(this, from, to); - return this; - } - /** - Split the content in the given range off from its parent, if there - is sibling content before or after it, and move it up the tree to - the depth specified by `target`. You'll probably want to use - [`liftTarget`](https://prosemirror.net/docs/ref/#transform.liftTarget) to compute `target`, to make - sure the lift is valid. - */ - lift(range, target) { - lift(this, range, target); - return this; - } - /** - Join the blocks around the given position. If depth is 2, their - last and first siblings are also joined, and so on. - */ - join(pos, depth = 1) { - join3(this, pos, depth); - return this; - } - /** - Wrap the given [range](https://prosemirror.net/docs/ref/#model.NodeRange) in the given set of wrappers. - The wrappers are assumed to be valid in this position, and should - probably be computed with [`findWrapping`](https://prosemirror.net/docs/ref/#transform.findWrapping). - */ - wrap(range, wrappers) { - wrap2(this, range, wrappers); - return this; - } - /** - Set the type of all textblocks (partly) between `from` and `to` to - the given node type with the given attributes. - */ - setBlockType(from, to = from, type, attrs = null) { - setBlockType(this, from, to, type, attrs); - return this; - } - /** - Change the type, attributes, and/or marks of the node at `pos`. - When `type` isn't given, the existing node type is preserved, - */ - setNodeMarkup(pos, type, attrs = null, marks) { - setNodeMarkup(this, pos, type, attrs, marks); - return this; - } - /** - Set a single attribute on a given node to a new value. - The `pos` addresses the document content. Use `setDocAttribute` - to set attributes on the document itself. - */ - setNodeAttribute(pos, attr, value) { - this.step(new AttrStep(pos, attr, value)); - return this; - } - /** - Set a single attribute on the document to a new value. - */ - setDocAttribute(attr, value) { - this.step(new DocAttrStep(attr, value)); - return this; - } - /** - Add a mark to the node at position `pos`. - */ - addNodeMark(pos, mark) { - this.step(new AddNodeMarkStep(pos, mark)); - return this; - } - /** - Remove a mark (or a mark of the given type) from the node at - position `pos`. - */ - removeNodeMark(pos, mark) { - if (!(mark instanceof Mark)) { - let node2 = this.doc.nodeAt(pos); - if (!node2) - throw new RangeError("No node at position " + pos); - mark = mark.isInSet(node2.marks); - if (!mark) - return this; - } - this.step(new RemoveNodeMarkStep(pos, mark)); - return this; - } - /** - Split the node at the given position, and optionally, if `depth` is - greater than one, any number of nodes above that. By default, the - parts split off will inherit the node type of the original node. - This can be changed by passing an array of types and attributes to - use after the split. - */ - split(pos, depth = 1, typesAfter) { - split(this, pos, depth, typesAfter); - return this; - } - /** - Add the given mark to the inline content between `from` and `to`. - */ - addMark(from, to, mark) { - addMark(this, from, to, mark); - return this; - } - /** - Remove marks from inline nodes between `from` and `to`. When - `mark` is a single mark, remove precisely that mark. When it is - a mark type, remove all marks of that type. When it is null, - remove all marks of any type. - */ - removeMark(from, to, mark) { - removeMark(this, from, to, mark); - return this; - } - /** - Removes all marks and nodes from the content of the node at - `pos` that don't match the given new parent node type. Accepts - an optional starting [content match](https://prosemirror.net/docs/ref/#model.ContentMatch) as - third argument. - */ - clearIncompatible(pos, parentType, match) { - clearIncompatible(this, pos, parentType, match); - return this; - } - }; - - // node_modules/prosemirror-state/dist/index.js - var classesById = /* @__PURE__ */ Object.create(null); - var Selection = class { - /** - Initialize a selection with the head and anchor and ranges. If no - ranges are given, constructs a single range across `$anchor` and - `$head`. - */ - constructor($anchor, $head, ranges) { - this.$anchor = $anchor; - this.$head = $head; - this.ranges = ranges || [new SelectionRange($anchor.min($head), $anchor.max($head))]; - } - /** - The selection's anchor, as an unresolved position. - */ - get anchor() { - return this.$anchor.pos; - } - /** - The selection's head. - */ - get head() { - return this.$head.pos; - } - /** - The lower bound of the selection's main range. - */ - get from() { - return this.$from.pos; - } - /** - The upper bound of the selection's main range. - */ - get to() { - return this.$to.pos; - } - /** - The resolved lower bound of the selection's main range. - */ - get $from() { - return this.ranges[0].$from; - } - /** - The resolved upper bound of the selection's main range. - */ - get $to() { - return this.ranges[0].$to; - } - /** - Indicates whether the selection contains any content. - */ - get empty() { - let ranges = this.ranges; - for (let i2 = 0; i2 < ranges.length; i2++) - if (ranges[i2].$from.pos != ranges[i2].$to.pos) - return false; - return true; - } - /** - Get the content of this selection as a slice. - */ - content() { - return this.$from.doc.slice(this.from, this.to, true); - } - /** - Replace the selection with a slice or, if no slice is given, - delete the selection. Will append to the given transaction. - */ - replace(tr, content3 = Slice.empty) { - let lastNode = content3.content.lastChild, lastParent = null; - for (let i2 = 0; i2 < content3.openEnd; i2++) { - lastParent = lastNode; - lastNode = lastNode.lastChild; - } - let mapFrom = tr.steps.length, ranges = this.ranges; - for (let i2 = 0; i2 < ranges.length; i2++) { - let { $from, $to } = ranges[i2], mapping = tr.mapping.slice(mapFrom); - tr.replaceRange(mapping.map($from.pos), mapping.map($to.pos), i2 ? Slice.empty : content3); - if (i2 == 0) - selectionToInsertionEnd(tr, mapFrom, (lastNode ? lastNode.isInline : lastParent && lastParent.isTextblock) ? -1 : 1); - } - } - /** - Replace the selection with the given node, appending the changes - to the given transaction. - */ - replaceWith(tr, node2) { - let mapFrom = tr.steps.length, ranges = this.ranges; - for (let i2 = 0; i2 < ranges.length; i2++) { - let { $from, $to } = ranges[i2], mapping = tr.mapping.slice(mapFrom); - let from = mapping.map($from.pos), to = mapping.map($to.pos); - if (i2) { - tr.deleteRange(from, to); - } else { - tr.replaceRangeWith(from, to, node2); - selectionToInsertionEnd(tr, mapFrom, node2.isInline ? -1 : 1); - } - } - } - /** - Find a valid cursor or leaf node selection starting at the given - position and searching back if `dir` is negative, and forward if - positive. When `textOnly` is true, only consider cursor - selections. Will return null when no valid selection position is - found. - */ - static findFrom($pos, dir, textOnly = false) { - let inner = $pos.parent.inlineContent ? new TextSelection($pos) : findSelectionIn($pos.node(0), $pos.parent, $pos.pos, $pos.index(), dir, textOnly); - if (inner) - return inner; - for (let depth = $pos.depth - 1; depth >= 0; depth--) { - let found2 = dir < 0 ? findSelectionIn($pos.node(0), $pos.node(depth), $pos.before(depth + 1), $pos.index(depth), dir, textOnly) : findSelectionIn($pos.node(0), $pos.node(depth), $pos.after(depth + 1), $pos.index(depth) + 1, dir, textOnly); - if (found2) - return found2; - } - return null; - } - /** - Find a valid cursor or leaf node selection near the given - position. Searches forward first by default, but if `bias` is - negative, it will search backwards first. - */ - static near($pos, bias = 1) { - return this.findFrom($pos, bias) || this.findFrom($pos, -bias) || new AllSelection($pos.node(0)); - } - /** - Find the cursor or leaf node selection closest to the start of - the given document. Will return an - [`AllSelection`](https://prosemirror.net/docs/ref/#state.AllSelection) if no valid position - exists. - */ - static atStart(doc4) { - return findSelectionIn(doc4, doc4, 0, 0, 1) || new AllSelection(doc4); - } - /** - Find the cursor or leaf node selection closest to the end of the - given document. - */ - static atEnd(doc4) { - return findSelectionIn(doc4, doc4, doc4.content.size, doc4.childCount, -1) || new AllSelection(doc4); - } - /** - Deserialize the JSON representation of a selection. Must be - implemented for custom classes (as a static class method). - */ - static fromJSON(doc4, json) { - if (!json || !json.type) - throw new RangeError("Invalid input for Selection.fromJSON"); - let cls = classesById[json.type]; - if (!cls) - throw new RangeError(`No selection type ${json.type} defined`); - return cls.fromJSON(doc4, json); - } - /** - To be able to deserialize selections from JSON, custom selection - classes must register themselves with an ID string, so that they - can be disambiguated. Try to pick something that's unlikely to - clash with classes from other modules. - */ - static jsonID(id, selectionClass) { - if (id in classesById) - throw new RangeError("Duplicate use of selection JSON ID " + id); - classesById[id] = selectionClass; - selectionClass.prototype.jsonID = id; - return selectionClass; - } - /** - Get a [bookmark](https://prosemirror.net/docs/ref/#state.SelectionBookmark) for this selection, - which is a value that can be mapped without having access to a - current document, and later resolved to a real selection for a - given document again. (This is used mostly by the history to - track and restore old selections.) The default implementation of - this method just converts the selection to a text selection and - returns the bookmark for that. - */ - getBookmark() { - return TextSelection.between(this.$anchor, this.$head).getBookmark(); - } - }; - Selection.prototype.visible = true; - var SelectionRange = class { - /** - Create a range. - */ - constructor($from, $to) { - this.$from = $from; - this.$to = $to; - } - }; - var warnedAboutTextSelection = false; - function checkTextSelection($pos) { - if (!warnedAboutTextSelection && !$pos.parent.inlineContent) { - warnedAboutTextSelection = true; - console["warn"]("TextSelection endpoint not pointing into a node with inline content (" + $pos.parent.type.name + ")"); - } - } - var TextSelection = class _TextSelection extends Selection { - /** - Construct a text selection between the given points. - */ - constructor($anchor, $head = $anchor) { - checkTextSelection($anchor); - checkTextSelection($head); - super($anchor, $head); - } - /** - Returns a resolved position if this is a cursor selection (an - empty text selection), and null otherwise. - */ - get $cursor() { - return this.$anchor.pos == this.$head.pos ? this.$head : null; - } - map(doc4, mapping) { - let $head = doc4.resolve(mapping.map(this.head)); - if (!$head.parent.inlineContent) - return Selection.near($head); - let $anchor = doc4.resolve(mapping.map(this.anchor)); - return new _TextSelection($anchor.parent.inlineContent ? $anchor : $head, $head); - } - replace(tr, content3 = Slice.empty) { - super.replace(tr, content3); - if (content3 == Slice.empty) { - let marks = this.$from.marksAcross(this.$to); - if (marks) - tr.ensureMarks(marks); - } - } - eq(other) { - return other instanceof _TextSelection && other.anchor == this.anchor && other.head == this.head; - } - getBookmark() { - return new TextBookmark(this.anchor, this.head); - } - toJSON() { - return { type: "text", anchor: this.anchor, head: this.head }; - } - /** - @internal - */ - static fromJSON(doc4, json) { - if (typeof json.anchor != "number" || typeof json.head != "number") - throw new RangeError("Invalid input for TextSelection.fromJSON"); - return new _TextSelection(doc4.resolve(json.anchor), doc4.resolve(json.head)); - } - /** - Create a text selection from non-resolved positions. - */ - static create(doc4, anchor, head = anchor) { - let $anchor = doc4.resolve(anchor); - return new this($anchor, head == anchor ? $anchor : doc4.resolve(head)); - } - /** - Return a text selection that spans the given positions or, if - they aren't text positions, find a text selection near them. - `bias` determines whether the method searches forward (default) - or backwards (negative number) first. Will fall back to calling - [`Selection.near`](https://prosemirror.net/docs/ref/#state.Selection^near) when the document - doesn't contain a valid text position. - */ - static between($anchor, $head, bias) { - let dPos = $anchor.pos - $head.pos; - if (!bias || dPos) - bias = dPos >= 0 ? 1 : -1; - if (!$head.parent.inlineContent) { - let found2 = Selection.findFrom($head, bias, true) || Selection.findFrom($head, -bias, true); - if (found2) - $head = found2.$head; - else - return Selection.near($head, bias); - } - if (!$anchor.parent.inlineContent) { - if (dPos == 0) { - $anchor = $head; - } else { - $anchor = (Selection.findFrom($anchor, -bias, true) || Selection.findFrom($anchor, bias, true)).$anchor; - if ($anchor.pos < $head.pos != dPos < 0) - $anchor = $head; - } - } - return new _TextSelection($anchor, $head); - } - }; - Selection.jsonID("text", TextSelection); - var TextBookmark = class _TextBookmark { - constructor(anchor, head) { - this.anchor = anchor; - this.head = head; - } - map(mapping) { - return new _TextBookmark(mapping.map(this.anchor), mapping.map(this.head)); - } - resolve(doc4) { - return TextSelection.between(doc4.resolve(this.anchor), doc4.resolve(this.head)); - } - }; - var NodeSelection = class _NodeSelection extends Selection { - /** - Create a node selection. Does not verify the validity of its - argument. - */ - constructor($pos) { - let node2 = $pos.nodeAfter; - let $end = $pos.node(0).resolve($pos.pos + node2.nodeSize); - super($pos, $end); - this.node = node2; - } - map(doc4, mapping) { - let { deleted, pos } = mapping.mapResult(this.anchor); - let $pos = doc4.resolve(pos); - if (deleted) - return Selection.near($pos); - return new _NodeSelection($pos); - } - content() { - return new Slice(Fragment.from(this.node), 0, 0); - } - eq(other) { - return other instanceof _NodeSelection && other.anchor == this.anchor; - } - toJSON() { - return { type: "node", anchor: this.anchor }; - } - getBookmark() { - return new NodeBookmark(this.anchor); - } - /** - @internal - */ - static fromJSON(doc4, json) { - if (typeof json.anchor != "number") - throw new RangeError("Invalid input for NodeSelection.fromJSON"); - return new _NodeSelection(doc4.resolve(json.anchor)); - } - /** - Create a node selection from non-resolved positions. - */ - static create(doc4, from) { - return new _NodeSelection(doc4.resolve(from)); - } - /** - Determines whether the given node may be selected as a node - selection. - */ - static isSelectable(node2) { - return !node2.isText && node2.type.spec.selectable !== false; - } - }; - NodeSelection.prototype.visible = false; - Selection.jsonID("node", NodeSelection); - var NodeBookmark = class _NodeBookmark { - constructor(anchor) { - this.anchor = anchor; - } - map(mapping) { - let { deleted, pos } = mapping.mapResult(this.anchor); - return deleted ? new TextBookmark(pos, pos) : new _NodeBookmark(pos); - } - resolve(doc4) { - let $pos = doc4.resolve(this.anchor), node2 = $pos.nodeAfter; - if (node2 && NodeSelection.isSelectable(node2)) - return new NodeSelection($pos); - return Selection.near($pos); - } - }; - var AllSelection = class _AllSelection extends Selection { - /** - Create an all-selection over the given document. - */ - constructor(doc4) { - super(doc4.resolve(0), doc4.resolve(doc4.content.size)); - } - replace(tr, content3 = Slice.empty) { - if (content3 == Slice.empty) { - tr.delete(0, tr.doc.content.size); - let sel = Selection.atStart(tr.doc); - if (!sel.eq(tr.selection)) - tr.setSelection(sel); - } else { - super.replace(tr, content3); - } - } - toJSON() { - return { type: "all" }; - } - /** - @internal - */ - static fromJSON(doc4) { - return new _AllSelection(doc4); - } - map(doc4) { - return new _AllSelection(doc4); - } - eq(other) { - return other instanceof _AllSelection; - } - getBookmark() { - return AllBookmark; - } - }; - Selection.jsonID("all", AllSelection); - var AllBookmark = { - map() { - return this; - }, - resolve(doc4) { - return new AllSelection(doc4); - } - }; - function findSelectionIn(doc4, node2, pos, index2, dir, text5 = false) { - if (node2.inlineContent) - return TextSelection.create(doc4, pos); - for (let i2 = index2 - (dir > 0 ? 0 : 1); dir > 0 ? i2 < node2.childCount : i2 >= 0; i2 += dir) { - let child = node2.child(i2); - if (!child.isAtom) { - let inner = findSelectionIn(doc4, child, pos + dir, dir < 0 ? child.childCount : 0, dir, text5); - if (inner) - return inner; - } else if (!text5 && NodeSelection.isSelectable(child)) { - return NodeSelection.create(doc4, pos - (dir < 0 ? child.nodeSize : 0)); - } - pos += child.nodeSize * dir; - } - return null; - } - function selectionToInsertionEnd(tr, startLen, bias) { - let last = tr.steps.length - 1; - if (last < startLen) - return; - let step = tr.steps[last]; - if (!(step instanceof ReplaceStep || step instanceof ReplaceAroundStep)) - return; - let map5 = tr.mapping.maps[last], end; - map5.forEach((_from, _to, _newFrom, newTo) => { - if (end == null) - end = newTo; - }); - tr.setSelection(Selection.near(tr.doc.resolve(end), bias)); - } - var UPDATED_SEL = 1; - var UPDATED_MARKS = 2; - var UPDATED_SCROLL = 4; - var Transaction = class extends Transform { - /** - @internal - */ - constructor(state) { - super(state.doc); - this.curSelectionFor = 0; - this.updated = 0; - this.meta = /* @__PURE__ */ Object.create(null); - this.time = Date.now(); - this.curSelection = state.selection; - this.storedMarks = state.storedMarks; - } - /** - The transaction's current selection. This defaults to the editor - selection [mapped](https://prosemirror.net/docs/ref/#state.Selection.map) through the steps in the - transaction, but can be overwritten with - [`setSelection`](https://prosemirror.net/docs/ref/#state.Transaction.setSelection). - */ - get selection() { - if (this.curSelectionFor < this.steps.length) { - this.curSelection = this.curSelection.map(this.doc, this.mapping.slice(this.curSelectionFor)); - this.curSelectionFor = this.steps.length; - } - return this.curSelection; - } - /** - Update the transaction's current selection. Will determine the - selection that the editor gets when the transaction is applied. - */ - setSelection(selection) { - if (selection.$from.doc != this.doc) - throw new RangeError("Selection passed to setSelection must point at the current document"); - this.curSelection = selection; - this.curSelectionFor = this.steps.length; - this.updated = (this.updated | UPDATED_SEL) & ~UPDATED_MARKS; - this.storedMarks = null; - return this; - } - /** - Whether the selection was explicitly updated by this transaction. - */ - get selectionSet() { - return (this.updated & UPDATED_SEL) > 0; - } - /** - Set the current stored marks. - */ - setStoredMarks(marks) { - this.storedMarks = marks; - this.updated |= UPDATED_MARKS; - return this; - } - /** - Make sure the current stored marks or, if that is null, the marks - at the selection, match the given set of marks. Does nothing if - this is already the case. - */ - ensureMarks(marks) { - if (!Mark.sameSet(this.storedMarks || this.selection.$from.marks(), marks)) - this.setStoredMarks(marks); - return this; - } - /** - Add a mark to the set of stored marks. - */ - addStoredMark(mark) { - return this.ensureMarks(mark.addToSet(this.storedMarks || this.selection.$head.marks())); - } - /** - Remove a mark or mark type from the set of stored marks. - */ - removeStoredMark(mark) { - return this.ensureMarks(mark.removeFromSet(this.storedMarks || this.selection.$head.marks())); - } - /** - Whether the stored marks were explicitly set for this transaction. - */ - get storedMarksSet() { - return (this.updated & UPDATED_MARKS) > 0; - } - /** - @internal - */ - addStep(step, doc4) { - super.addStep(step, doc4); - this.updated = this.updated & ~UPDATED_MARKS; - this.storedMarks = null; - } - /** - Update the timestamp for the transaction. - */ - setTime(time) { - this.time = time; - return this; - } - /** - Replace the current selection with the given slice. - */ - replaceSelection(slice) { - this.selection.replace(this, slice); - return this; - } - /** - Replace the selection with the given node. When `inheritMarks` is - true and the content is inline, it inherits the marks from the - place where it is inserted. - */ - replaceSelectionWith(node2, inheritMarks = true) { - let selection = this.selection; - if (inheritMarks) - node2 = node2.mark(this.storedMarks || (selection.empty ? selection.$from.marks() : selection.$from.marksAcross(selection.$to) || Mark.none)); - selection.replaceWith(this, node2); - return this; - } - /** - Delete the selection. - */ - deleteSelection() { - this.selection.replace(this); - return this; - } - /** - Replace the given range, or the selection if no range is given, - with a text node containing the given string. - */ - insertText(text5, from, to) { - let schema = this.doc.type.schema; + iterLines(from, to) { + let inner; if (from == null) { - if (!text5) - return this.deleteSelection(); - return this.replaceSelectionWith(schema.text(text5), true); + inner = this.iter(); } else { if (to == null) - to = from; - to = to == null ? from : to; - if (!text5) - return this.deleteRange(from, to); - let marks = this.storedMarks; - if (!marks) { - let $from = this.doc.resolve(from); - marks = to == from ? $from.marks() : $from.marksAcross(this.doc.resolve(to)); - } - this.replaceRangeWith(from, to, schema.text(text5, marks)); - if (!this.selection.empty) - this.setSelection(Selection.near(this.selection.$to)); - return this; + to = this.lines + 1; + let start = this.line(from).from; + inner = this.iterRange(start, Math.max(start, to == this.lines + 1 ? this.length : to <= 1 ? 0 : this.line(to - 1).to)); } + return new LineCursor(inner); } /** - Store a metadata property in this transaction, keyed either by - name or by plugin. + Return the document as a string, using newline characters to + separate lines. */ - setMeta(key, value) { - this.meta[typeof key == "string" ? key : key.key] = value; - return this; + toString() { + return this.sliceString(0); } /** - Retrieve a metadata property for a given name or plugin. + Convert the document to an array of lines (which can be + deserialized again via [`Text.of`](https://codemirror.net/6/docs/ref/#state.Text^of)). */ - getMeta(key) { - return this.meta[typeof key == "string" ? key : key.key]; - } - /** - Returns true if this transaction doesn't contain any metadata, - and can thus safely be extended. - */ - get isGeneric() { - for (let _3 in this.meta) - return false; - return true; - } - /** - Indicate that the editor should scroll the selection into view - when updated to the state produced by this transaction. - */ - scrollIntoView() { - this.updated |= UPDATED_SCROLL; - return this; - } - /** - True when this transaction has had `scrollIntoView` called on it. - */ - get scrolledIntoView() { - return (this.updated & UPDATED_SCROLL) > 0; - } - }; - function bind(f3, self2) { - return !self2 || !f3 ? f3 : f3.bind(self2); - } - var FieldDesc = class { - constructor(name, desc, self2) { - this.name = name; - this.init = bind(desc.init, self2); - this.apply = bind(desc.apply, self2); - } - }; - var baseFields = [ - new FieldDesc("doc", { - init(config) { - return config.doc || config.schema.topNodeType.createAndFill(); - }, - apply(tr) { - return tr.doc; - } - }), - new FieldDesc("selection", { - init(config, instance) { - return config.selection || Selection.atStart(instance.doc); - }, - apply(tr) { - return tr.selection; - } - }), - new FieldDesc("storedMarks", { - init(config) { - return config.storedMarks || null; - }, - apply(tr, _marks, _old, state) { - return state.selection.$cursor ? tr.storedMarks : null; - } - }), - new FieldDesc("scrollToSelection", { - init() { - return 0; - }, - apply(tr, prev) { - return tr.scrolledIntoView ? prev + 1 : prev; - } - }) - ]; - var Configuration = class { - constructor(schema, plugins) { - this.schema = schema; - this.plugins = []; - this.pluginsByKey = /* @__PURE__ */ Object.create(null); - this.fields = baseFields.slice(); - if (plugins) - plugins.forEach((plugin) => { - if (this.pluginsByKey[plugin.key]) - throw new RangeError("Adding different instances of a keyed plugin (" + plugin.key + ")"); - this.plugins.push(plugin); - this.pluginsByKey[plugin.key] = plugin; - if (plugin.spec.state) - this.fields.push(new FieldDesc(plugin.key, plugin.spec.state, plugin)); - }); - } - }; - var EditorState = class _EditorState { - /** - @internal - */ - constructor(config) { - this.config = config; - } - /** - The schema of the state's document. - */ - get schema() { - return this.config.schema; - } - /** - The plugins that are active in this state. - */ - get plugins() { - return this.config.plugins; - } - /** - Apply the given transaction to produce a new state. - */ - apply(tr) { - return this.applyTransaction(tr).state; + toJSON() { + let lines = []; + this.flatten(lines); + return lines; } /** @internal */ - filterTransaction(tr, ignore = -1) { - for (let i2 = 0; i2 < this.config.plugins.length; i2++) - if (i2 != ignore) { - let plugin = this.config.plugins[i2]; - if (plugin.spec.filterTransaction && !plugin.spec.filterTransaction.call(plugin, tr, this)) - return false; - } - return true; + constructor() { } /** - Verbose variant of [`apply`](https://prosemirror.net/docs/ref/#state.EditorState.apply) that - returns the precise transactions that were applied (which might - be influenced by the [transaction - hooks](https://prosemirror.net/docs/ref/#state.PluginSpec.filterTransaction) of - plugins) along with the new state. + Create a `Text` instance for the given array of lines. */ - applyTransaction(rootTr) { - if (!this.filterTransaction(rootTr)) - return { state: this, transactions: [] }; - let trs = [rootTr], newState = this.applyInner(rootTr), seen = null; - for (; ; ) { - let haveNew = false; - for (let i2 = 0; i2 < this.config.plugins.length; i2++) { - let plugin = this.config.plugins[i2]; - if (plugin.spec.appendTransaction) { - let n4 = seen ? seen[i2].n : 0, oldState = seen ? seen[i2].state : this; - let tr = n4 < trs.length && plugin.spec.appendTransaction.call(plugin, n4 ? trs.slice(n4) : trs, oldState, newState); - if (tr && newState.filterTransaction(tr, i2)) { - tr.setMeta("appendedTransaction", rootTr); - if (!seen) { - seen = []; - for (let j6 = 0; j6 < this.config.plugins.length; j6++) - seen.push(j6 < i2 ? { state: newState, n: trs.length } : { state: this, n: 0 }); - } - trs.push(tr); - newState = newState.applyInner(tr); - haveNew = true; - } - if (seen) - seen[i2] = { state: newState, n: trs.length }; - } - } - if (!haveNew) - return { state: newState, transactions: trs }; + static of(text) { + if (text.length == 0) + throw new RangeError("A document must have at least one line"); + if (text.length == 1 && !text[0]) + return _Text.empty; + return text.length <= 32 ? new TextLeaf(text) : TextNode.from(TextLeaf.split(text, [])); + } + }; + var TextLeaf = class _TextLeaf extends Text { + constructor(text, length = textLength(text)) { + super(); + this.text = text; + this.length = length; + } + get lines() { + return this.text.length; + } + get children() { + return null; + } + lineInner(target, isLine, line, offset) { + for (let i = 0; ; i++) { + let string2 = this.text[i], end = offset + string2.length; + if ((isLine ? line : end) >= target) + return new Line(offset, end, line, string2); + offset = end + 1; + line++; } } - /** - @internal - */ - applyInner(tr) { - if (!tr.before.eq(this.doc)) - throw new RangeError("Applying a mismatched transaction"); - let newInstance = new _EditorState(this.config), fields = this.config.fields; - for (let i2 = 0; i2 < fields.length; i2++) { - let field = fields[i2]; - newInstance[field.name] = field.apply(tr, this[field.name], this, newInstance); - } - return newInstance; - } - /** - Start a [transaction](https://prosemirror.net/docs/ref/#state.Transaction) from this state. - */ - get tr() { - return new Transaction(this); - } - /** - Create a new state. - */ - static create(config) { - let $config = new Configuration(config.doc ? config.doc.type.schema : config.schema, config.plugins); - let instance = new _EditorState($config); - for (let i2 = 0; i2 < $config.fields.length; i2++) - instance[$config.fields[i2].name] = $config.fields[i2].init(config, instance); - return instance; - } - /** - Create a new state based on this one, but with an adjusted set - of active plugins. State fields that exist in both sets of - plugins are kept unchanged. Those that no longer exist are - dropped, and those that are new are initialized using their - [`init`](https://prosemirror.net/docs/ref/#state.StateField.init) method, passing in the new - configuration object.. - */ - reconfigure(config) { - let $config = new Configuration(this.schema, config.plugins); - let fields = $config.fields, instance = new _EditorState($config); - for (let i2 = 0; i2 < fields.length; i2++) { - let name = fields[i2].name; - instance[name] = this.hasOwnProperty(name) ? this[name] : fields[i2].init(config, instance); - } - return instance; - } - /** - Serialize this state to JSON. If you want to serialize the state - of plugins, pass an object mapping property names to use in the - resulting JSON object to plugin objects. The argument may also be - a string or number, in which case it is ignored, to support the - way `JSON.stringify` calls `toString` methods. - */ - toJSON(pluginFields) { - let result = { doc: this.doc.toJSON(), selection: this.selection.toJSON() }; - if (this.storedMarks) - result.storedMarks = this.storedMarks.map((m3) => m3.toJSON()); - if (pluginFields && typeof pluginFields == "object") - for (let prop in pluginFields) { - if (prop == "doc" || prop == "selection") - throw new RangeError("The JSON fields `doc` and `selection` are reserved"); - let plugin = pluginFields[prop], state = plugin.spec.state; - if (state && state.toJSON) - result[prop] = state.toJSON.call(plugin, this[plugin.key]); + decompose(from, to, target, open) { + let text = from <= 0 && to >= this.length ? this : new _TextLeaf(sliceText(this.text, from, to), Math.min(to, this.length) - Math.max(0, from)); + if (open & 1) { + let prev = target.pop(); + let joined = appendText(text.text, prev.text.slice(), 0, text.length); + if (joined.length <= 32) { + target.push(new _TextLeaf(joined, prev.length + text.length)); + } else { + let mid = joined.length >> 1; + target.push(new _TextLeaf(joined.slice(0, mid)), new _TextLeaf(joined.slice(mid))); } + } else { + target.push(text); + } + } + replace(from, to, text) { + if (!(text instanceof _TextLeaf)) + return super.replace(from, to, text); + [from, to] = clip(this, from, to); + let lines = appendText(this.text, appendText(text.text, sliceText(this.text, 0, from)), to); + let newLen = this.length + text.length - (to - from); + if (lines.length <= 32) + return new _TextLeaf(lines, newLen); + return TextNode.from(_TextLeaf.split(lines, []), newLen); + } + sliceString(from, to = this.length, lineSep = "\n") { + [from, to] = clip(this, from, to); + let result = ""; + for (let pos = 0, i = 0; pos <= to && i < this.text.length; i++) { + let line = this.text[i], end = pos + line.length; + if (pos > from && i) + result += lineSep; + if (from < end && to > pos) + result += line.slice(Math.max(0, from - pos), to - pos); + pos = end + 1; + } return result; } - /** - Deserialize a JSON representation of a state. `config` should - have at least a `schema` field, and should contain array of - plugins to initialize the state with. `pluginFields` can be used - to deserialize the state of plugins, by associating plugin - instances with the property names they use in the JSON object. - */ - static fromJSON(config, json, pluginFields) { - if (!json) - throw new RangeError("Invalid input for EditorState.fromJSON"); - if (!config.schema) - throw new RangeError("Required config field 'schema' missing"); - let $config = new Configuration(config.schema, config.plugins); - let instance = new _EditorState($config); - $config.fields.forEach((field) => { - if (field.name == "doc") { - instance.doc = Node2.fromJSON(config.schema, json.doc); - } else if (field.name == "selection") { - instance.selection = Selection.fromJSON(instance.doc, json.selection); - } else if (field.name == "storedMarks") { - if (json.storedMarks) - instance.storedMarks = json.storedMarks.map(config.schema.markFromJSON); - } else { - if (pluginFields) - for (let prop in pluginFields) { - let plugin = pluginFields[prop], state = plugin.spec.state; - if (plugin.key == field.name && state && state.fromJSON && Object.prototype.hasOwnProperty.call(json, prop)) { - instance[field.name] = state.fromJSON.call(plugin, config, json[prop], instance); - return; - } - } - instance[field.name] = field.init(config, instance); + flatten(target) { + for (let line of this.text) + target.push(line); + } + scanIdentical() { + return 0; + } + static split(text, target) { + let part = [], len = -1; + for (let line of text) { + part.push(line); + len += line.length + 1; + if (part.length == 32) { + target.push(new _TextLeaf(part, len)); + part = []; + len = -1; } - }); - return instance; + } + if (len > -1) + target.push(new _TextLeaf(part, len)); + return target; } }; - function bindProps(obj, self2, target) { - for (let prop in obj) { - let val = obj[prop]; - if (val instanceof Function) - val = val.bind(self2); - else if (prop == "handleDOMEvents") - val = bindProps(val, self2, {}); - target[prop] = val; + var TextNode = class _TextNode extends Text { + constructor(children, length) { + super(); + this.children = children; + this.length = length; + this.lines = 0; + for (let child of children) + this.lines += child.lines; + } + lineInner(target, isLine, line, offset) { + for (let i = 0; ; i++) { + let child = this.children[i], end = offset + child.length, endLine = line + child.lines - 1; + if ((isLine ? endLine : end) >= target) + return child.lineInner(target, isLine, line, offset); + offset = end + 1; + line = endLine + 1; + } + } + decompose(from, to, target, open) { + for (let i = 0, pos = 0; pos <= to && i < this.children.length; i++) { + let child = this.children[i], end = pos + child.length; + if (from <= end && to >= pos) { + let childOpen = open & ((pos <= from ? 1 : 0) | (end >= to ? 2 : 0)); + if (pos >= from && end <= to && !childOpen) + target.push(child); + else + child.decompose(from - pos, to - pos, target, childOpen); + } + pos = end + 1; + } + } + replace(from, to, text) { + [from, to] = clip(this, from, to); + if (text.lines < this.lines) + for (let i = 0, pos = 0; i < this.children.length; i++) { + let child = this.children[i], end = pos + child.length; + if (from >= pos && to <= end) { + let updated = child.replace(from - pos, to - pos, text); + let totalLines = this.lines - child.lines + updated.lines; + if (updated.lines < totalLines >> 5 - 1 && updated.lines > totalLines >> 5 + 1) { + let copy = this.children.slice(); + copy[i] = updated; + return new _TextNode(copy, this.length - (to - from) + text.length); + } + return super.replace(pos, end, updated); + } + pos = end + 1; + } + return super.replace(from, to, text); + } + sliceString(from, to = this.length, lineSep = "\n") { + [from, to] = clip(this, from, to); + let result = ""; + for (let i = 0, pos = 0; i < this.children.length && pos <= to; i++) { + let child = this.children[i], end = pos + child.length; + if (pos > from && i) + result += lineSep; + if (from < end && to > pos) + result += child.sliceString(from - pos, to - pos, lineSep); + pos = end + 1; + } + return result; + } + flatten(target) { + for (let child of this.children) + child.flatten(target); + } + scanIdentical(other, dir) { + if (!(other instanceof _TextNode)) + return 0; + let length = 0; + let [iA, iB, eA, eB] = dir > 0 ? [0, 0, this.children.length, other.children.length] : [this.children.length - 1, other.children.length - 1, -1, -1]; + for (; ; iA += dir, iB += dir) { + if (iA == eA || iB == eB) + return length; + let chA = this.children[iA], chB = other.children[iB]; + if (chA != chB) + return length + chA.scanIdentical(chB, dir); + length += chA.length + 1; + } + } + static from(children, length = children.reduce((l, ch) => l + ch.length + 1, -1)) { + let lines = 0; + for (let ch of children) + lines += ch.lines; + if (lines < 32) { + let flat = []; + for (let ch of children) + ch.flatten(flat); + return new TextLeaf(flat, length); + } + let chunk = Math.max( + 32, + lines >> 5 + /* Tree.BranchShift */ + ), maxChunk = chunk << 1, minChunk = chunk >> 1; + let chunked = [], currentLines = 0, currentLen = -1, currentChunk = []; + function add2(child) { + let last; + if (child.lines > maxChunk && child instanceof _TextNode) { + for (let node of child.children) + add2(node); + } else if (child.lines > minChunk && (currentLines > minChunk || !currentLines)) { + flush(); + chunked.push(child); + } else if (child instanceof TextLeaf && currentLines && (last = currentChunk[currentChunk.length - 1]) instanceof TextLeaf && child.lines + last.lines <= 32) { + currentLines += child.lines; + currentLen += child.length + 1; + currentChunk[currentChunk.length - 1] = new TextLeaf(last.text.concat(child.text), last.length + 1 + child.length); + } else { + if (currentLines + child.lines > chunk) + flush(); + currentLines += child.lines; + currentLen += child.length + 1; + currentChunk.push(child); + } + } + function flush() { + if (currentLines == 0) + return; + chunked.push(currentChunk.length == 1 ? currentChunk[0] : _TextNode.from(currentChunk, currentLen)); + currentLen = -1; + currentLines = currentChunk.length = 0; + } + for (let child of children) + add2(child); + flush(); + return chunked.length == 1 ? chunked[0] : new _TextNode(chunked, length); + } + }; + Text.empty = /* @__PURE__ */ new TextLeaf([""], 0); + function textLength(text) { + let length = -1; + for (let line of text) + length += line.length + 1; + return length; + } + function appendText(text, target, from = 0, to = 1e9) { + for (let pos = 0, i = 0, first = true; i < text.length && pos <= to; i++) { + let line = text[i], end = pos + line.length; + if (end >= from) { + if (end > to) + line = line.slice(0, to - pos); + if (pos < from) + line = line.slice(from - pos); + if (first) { + target[target.length - 1] += line; + first = false; + } else + target.push(line); + } + pos = end + 1; } return target; } - var Plugin = class { - /** - Create a plugin. - */ - constructor(spec) { - this.spec = spec; - this.props = {}; - if (spec.props) - bindProps(spec.props, this, this.props); - this.key = spec.key ? spec.key.key : createKey("plugin"); - } - /** - Extract the plugin's state field from an editor state. - */ - getState(state) { - return state[this.key]; - } - }; - var keys = /* @__PURE__ */ Object.create(null); - function createKey(name) { - if (name in keys) - return name + "$" + ++keys[name]; - keys[name] = 0; - return name + "$"; + function sliceText(text, from, to) { + return appendText(text, [""], from, to); } - var PluginKey = class { - /** - Create a plugin key. - */ - constructor(name = "key") { - this.key = createKey(name); + var RawTextCursor = class { + constructor(text, dir = 1) { + this.dir = dir; + this.done = false; + this.lineBreak = false; + this.value = ""; + this.nodes = [text]; + this.offsets = [dir > 0 ? 1 : (text instanceof TextLeaf ? text.text.length : text.children.length) << 1]; } - /** - Get the active plugin with this key, if any, from an editor - state. - */ - get(state) { - return state.config.pluginsByKey[this.key]; + nextInner(skip, dir) { + this.done = this.lineBreak = false; + for (; ; ) { + let last = this.nodes.length - 1; + let top2 = this.nodes[last], offsetValue = this.offsets[last], offset = offsetValue >> 1; + let size = top2 instanceof TextLeaf ? top2.text.length : top2.children.length; + if (offset == (dir > 0 ? size : 0)) { + if (last == 0) { + this.done = true; + this.value = ""; + return this; + } + if (dir > 0) + this.offsets[last - 1]++; + this.nodes.pop(); + this.offsets.pop(); + } else if ((offsetValue & 1) == (dir > 0 ? 0 : 1)) { + this.offsets[last] += dir; + if (skip == 0) { + this.lineBreak = true; + this.value = "\n"; + return this; + } + skip--; + } else if (top2 instanceof TextLeaf) { + let next = top2.text[offset + (dir < 0 ? -1 : 0)]; + this.offsets[last] += dir; + if (next.length > Math.max(0, skip)) { + this.value = skip == 0 ? next : dir > 0 ? next.slice(skip) : next.slice(0, next.length - skip); + return this; + } + skip -= next.length; + } else { + let next = top2.children[offset + (dir < 0 ? -1 : 0)]; + if (skip > next.length) { + skip -= next.length; + this.offsets[last] += dir; + } else { + if (dir < 0) + this.offsets[last]--; + this.nodes.push(next); + this.offsets.push(dir > 0 ? 1 : (next instanceof TextLeaf ? next.text.length : next.children.length) << 1); + } + } + } } - /** - Get the plugin's state from an editor state. - */ - getState(state) { - return state[this.key]; + next(skip = 0) { + if (skip < 0) { + this.nextInner(-skip, -this.dir); + skip = this.value.length; + } + return this.nextInner(skip, this.dir); } }; - - // node_modules/prosemirror-view/dist/index.js - var domIndex = function(node2) { - for (var index2 = 0; ; index2++) { - node2 = node2.previousSibling; - if (!node2) - return index2; + var PartialTextCursor = class { + constructor(text, start, end) { + this.value = ""; + this.done = false; + this.cursor = new RawTextCursor(text, start > end ? -1 : 1); + this.pos = start > end ? text.length : 0; + this.from = Math.min(start, end); + this.to = Math.max(start, end); + } + nextInner(skip, dir) { + if (dir < 0 ? this.pos <= this.from : this.pos >= this.to) { + this.value = ""; + this.done = true; + return this; + } + skip += Math.max(0, dir < 0 ? this.pos - this.to : this.from - this.pos); + let limit = dir < 0 ? this.pos - this.from : this.to - this.pos; + if (skip > limit) + skip = limit; + limit -= skip; + let { value } = this.cursor.next(skip); + this.pos += (value.length + skip) * dir; + this.value = value.length <= limit ? value : dir < 0 ? value.slice(value.length - limit) : value.slice(0, limit); + this.done = !this.value; + return this; + } + next(skip = 0) { + if (skip < 0) + skip = Math.max(skip, this.from - this.pos); + else if (skip > 0) + skip = Math.min(skip, this.to - this.pos); + return this.nextInner(skip, this.cursor.dir); + } + get lineBreak() { + return this.cursor.lineBreak && this.value != ""; } }; - var parentNode = function(node2) { - let parent = node2.assignedSlot || node2.parentNode; - return parent && parent.nodeType == 11 ? parent.host : parent; - }; - var reusedRange = null; - var textRange = function(node2, from, to) { - let range = reusedRange || (reusedRange = document.createRange()); - range.setEnd(node2, to == null ? node2.nodeValue.length : to); - range.setStart(node2, from || 0); - return range; - }; - var clearReusedRange = function() { - reusedRange = null; - }; - var isEquivalentPosition = function(node2, off, targetNode, targetOff) { - return targetNode && (scanFor(node2, off, targetNode, targetOff, -1) || scanFor(node2, off, targetNode, targetOff, 1)); - }; - var atomElements = /^(img|br|input|textarea|hr)$/i; - function scanFor(node2, off, targetNode, targetOff, dir) { - for (; ; ) { - if (node2 == targetNode && off == targetOff) - return true; - if (off == (dir < 0 ? 0 : nodeSize(node2))) { - let parent = node2.parentNode; - if (!parent || parent.nodeType != 1 || hasBlockDesc(node2) || atomElements.test(node2.nodeName) || node2.contentEditable == "false") - return false; - off = domIndex(node2) + (dir < 0 ? 0 : 1); - node2 = parent; - } else if (node2.nodeType == 1) { - node2 = node2.childNodes[off + (dir < 0 ? -1 : 0)]; - if (node2.contentEditable == "false") - return false; - off = dir < 0 ? nodeSize(node2) : 0; + var LineCursor = class { + constructor(inner) { + this.inner = inner; + this.afterBreak = true; + this.value = ""; + this.done = false; + } + next(skip = 0) { + let { done, lineBreak, value } = this.inner.next(skip); + if (done && this.afterBreak) { + this.value = ""; + this.afterBreak = false; + } else if (done) { + this.done = true; + this.value = ""; + } else if (lineBreak) { + if (this.afterBreak) { + this.value = ""; + } else { + this.afterBreak = true; + this.next(); + } } else { - return false; + this.value = value; + this.afterBreak = false; } + return this; } - } - function nodeSize(node2) { - return node2.nodeType == 3 ? node2.nodeValue.length : node2.childNodes.length; - } - function textNodeBefore$1(node2, offset) { - for (; ; ) { - if (node2.nodeType == 3 && offset) - return node2; - if (node2.nodeType == 1 && offset > 0) { - if (node2.contentEditable == "false") - return null; - node2 = node2.childNodes[offset - 1]; - offset = nodeSize(node2); - } else if (node2.parentNode && !hasBlockDesc(node2)) { - offset = domIndex(node2); - node2 = node2.parentNode; - } else { - return null; - } + get lineBreak() { + return false; } - } - function textNodeAfter$1(node2, offset) { - for (; ; ) { - if (node2.nodeType == 3 && offset < node2.nodeValue.length) - return node2; - if (node2.nodeType == 1 && offset < node2.childNodes.length) { - if (node2.contentEditable == "false") - return null; - node2 = node2.childNodes[offset]; - offset = 0; - } else if (node2.parentNode && !hasBlockDesc(node2)) { - offset = domIndex(node2) + 1; - node2 = node2.parentNode; - } else { - return null; - } - } - } - function isOnEdge(node2, offset, parent) { - for (let atStart = offset == 0, atEnd = offset == nodeSize(node2); atStart || atEnd; ) { - if (node2 == parent) - return true; - let index2 = domIndex(node2); - node2 = node2.parentNode; - if (!node2) - return false; - atStart = atStart && index2 == 0; - atEnd = atEnd && index2 == nodeSize(node2); - } - } - function hasBlockDesc(dom) { - let desc; - for (let cur = dom; cur; cur = cur.parentNode) - if (desc = cur.pmViewDesc) - break; - return desc && desc.node && desc.node.isBlock && (desc.dom == dom || desc.contentDOM == dom); - } - var selectionCollapsed = function(domSel) { - return domSel.focusNode && isEquivalentPosition(domSel.focusNode, domSel.focusOffset, domSel.anchorNode, domSel.anchorOffset); }; - function keyEvent(keyCode, key) { - let event = document.createEvent("Event"); - event.initEvent("keydown", true, true); - event.keyCode = keyCode; - event.key = event.code = key; - return event; - } - function deepActiveElement(doc4) { - let elt = doc4.activeElement; - while (elt && elt.shadowRoot) - elt = elt.shadowRoot.activeElement; - return elt; - } - function caretFromPoint(doc4, x6, y4) { - if (doc4.caretPositionFromPoint) { - try { - let pos = doc4.caretPositionFromPoint(x6, y4); - if (pos) - return { node: pos.offsetNode, offset: pos.offset }; - } catch (_3) { - } - } - if (doc4.caretRangeFromPoint) { - let range = doc4.caretRangeFromPoint(x6, y4); - if (range) - return { node: range.startContainer, offset: range.startOffset }; - } - } - var nav = typeof navigator != "undefined" ? navigator : null; - var doc2 = typeof document != "undefined" ? document : null; - var agent = nav && nav.userAgent || ""; - var ie_edge = /Edge\/(\d+)/.exec(agent); - var ie_upto10 = /MSIE \d/.exec(agent); - var ie_11up = /Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(agent); - var ie = !!(ie_upto10 || ie_11up || ie_edge); - var ie_version = ie_upto10 ? document.documentMode : ie_11up ? +ie_11up[1] : ie_edge ? +ie_edge[1] : 0; - var gecko = !ie && /gecko\/(\d+)/i.test(agent); - gecko && +(/Firefox\/(\d+)/.exec(agent) || [0, 0])[1]; - var _chrome = !ie && /Chrome\/(\d+)/.exec(agent); - var chrome = !!_chrome; - var chrome_version = _chrome ? +_chrome[1] : 0; - var safari = !ie && !!nav && /Apple Computer/.test(nav.vendor); - var ios = safari && (/Mobile\/\w+/.test(agent) || !!nav && nav.maxTouchPoints > 2); - var mac = ios || (nav ? /Mac/.test(nav.platform) : false); - var windows = nav ? /Win/.test(nav.platform) : false; - var android = /Android \d/.test(agent); - var webkit = !!doc2 && "webkitFontSmoothing" in doc2.documentElement.style; - var webkit_version = webkit ? +(/\bAppleWebKit\/(\d+)/.exec(navigator.userAgent) || [0, 0])[1] : 0; - function windowRect(doc4) { - let vp = doc4.defaultView && doc4.defaultView.visualViewport; - if (vp) - return { - left: 0, - right: vp.width, - top: 0, - bottom: vp.height - }; - return { - left: 0, - right: doc4.documentElement.clientWidth, - top: 0, - bottom: doc4.documentElement.clientHeight + if (typeof Symbol != "undefined") { + Text.prototype[Symbol.iterator] = function() { + return this.iter(); + }; + RawTextCursor.prototype[Symbol.iterator] = PartialTextCursor.prototype[Symbol.iterator] = LineCursor.prototype[Symbol.iterator] = function() { + return this; }; } - function getSide(value, side) { - return typeof value == "number" ? value : value[side]; - } - function clientRect(node2) { - let rect = node2.getBoundingClientRect(); - let scaleX = rect.width / node2.offsetWidth || 1; - let scaleY = rect.height / node2.offsetHeight || 1; - return { - left: rect.left, - right: rect.left + node2.clientWidth * scaleX, - top: rect.top, - bottom: rect.top + node2.clientHeight * scaleY - }; - } - function scrollRectIntoView(view, rect, startDOM) { - let scrollThreshold = view.someProp("scrollThreshold") || 0, scrollMargin = view.someProp("scrollMargin") || 5; - let doc4 = view.dom.ownerDocument; - for (let parent = startDOM || view.dom; ; parent = parentNode(parent)) { - if (!parent) - break; - if (parent.nodeType != 1) - continue; - let elt = parent; - let atTop = elt == doc4.body; - let bounding = atTop ? windowRect(doc4) : clientRect(elt); - let moveX = 0, moveY = 0; - if (rect.top < bounding.top + getSide(scrollThreshold, "top")) - moveY = -(bounding.top - rect.top + getSide(scrollMargin, "top")); - else if (rect.bottom > bounding.bottom - getSide(scrollThreshold, "bottom")) - moveY = rect.bottom - rect.top > bounding.bottom - bounding.top ? rect.top + getSide(scrollMargin, "top") - bounding.top : rect.bottom - bounding.bottom + getSide(scrollMargin, "bottom"); - if (rect.left < bounding.left + getSide(scrollThreshold, "left")) - moveX = -(bounding.left - rect.left + getSide(scrollMargin, "left")); - else if (rect.right > bounding.right - getSide(scrollThreshold, "right")) - moveX = rect.right - bounding.right + getSide(scrollMargin, "right"); - if (moveX || moveY) { - if (atTop) { - doc4.defaultView.scrollBy(moveX, moveY); - } else { - let startX = elt.scrollLeft, startY = elt.scrollTop; - if (moveY) - elt.scrollTop += moveY; - if (moveX) - elt.scrollLeft += moveX; - let dX = elt.scrollLeft - startX, dY = elt.scrollTop - startY; - rect = { left: rect.left - dX, top: rect.top - dY, right: rect.right - dX, bottom: rect.bottom - dY }; - } - } - if (atTop || /^(fixed|sticky)$/.test(getComputedStyle(parent).position)) - break; - } - } - function storeScrollPos(view) { - let rect = view.dom.getBoundingClientRect(), startY = Math.max(0, rect.top); - let refDOM, refTop; - for (let x6 = (rect.left + rect.right) / 2, y4 = startY + 1; y4 < Math.min(innerHeight, rect.bottom); y4 += 5) { - let dom = view.root.elementFromPoint(x6, y4); - if (!dom || dom == view.dom || !view.dom.contains(dom)) - continue; - let localRect = dom.getBoundingClientRect(); - if (localRect.top >= startY - 20) { - refDOM = dom; - refTop = localRect.top; - break; - } - } - return { refDOM, refTop, stack: scrollStack(view.dom) }; - } - function scrollStack(dom) { - let stack = [], doc4 = dom.ownerDocument; - for (let cur = dom; cur; cur = parentNode(cur)) { - stack.push({ dom: cur, top: cur.scrollTop, left: cur.scrollLeft }); - if (dom == doc4) - break; - } - return stack; - } - function resetScrollPos({ refDOM, refTop, stack }) { - let newRefTop = refDOM ? refDOM.getBoundingClientRect().top : 0; - restoreScrollStack(stack, newRefTop == 0 ? 0 : newRefTop - refTop); - } - function restoreScrollStack(stack, dTop) { - for (let i2 = 0; i2 < stack.length; i2++) { - let { dom, top, left } = stack[i2]; - if (dom.scrollTop != top + dTop) - dom.scrollTop = top + dTop; - if (dom.scrollLeft != left) - dom.scrollLeft = left; - } - } - var preventScrollSupported = null; - function focusPreventScroll(dom) { - if (dom.setActive) - return dom.setActive(); - if (preventScrollSupported) - return dom.focus(preventScrollSupported); - let stored = scrollStack(dom); - dom.focus(preventScrollSupported == null ? { - get preventScroll() { - preventScrollSupported = { preventScroll: true }; - return true; - } - } : void 0); - if (!preventScrollSupported) { - preventScrollSupported = false; - restoreScrollStack(stored, 0); - } - } - function findOffsetInNode(node2, coords) { - let closest, dxClosest = 2e8, coordsClosest, offset = 0; - let rowBot = coords.top, rowTop = coords.top; - let firstBelow, coordsBelow; - for (let child = node2.firstChild, childIndex = 0; child; child = child.nextSibling, childIndex++) { - let rects; - if (child.nodeType == 1) - rects = child.getClientRects(); - else if (child.nodeType == 3) - rects = textRange(child).getClientRects(); - else - continue; - for (let i2 = 0; i2 < rects.length; i2++) { - let rect = rects[i2]; - if (rect.top <= rowBot && rect.bottom >= rowTop) { - rowBot = Math.max(rect.bottom, rowBot); - rowTop = Math.min(rect.top, rowTop); - let dx = rect.left > coords.left ? rect.left - coords.left : rect.right < coords.left ? coords.left - rect.right : 0; - if (dx < dxClosest) { - closest = child; - dxClosest = dx; - coordsClosest = dx && closest.nodeType == 3 ? { - left: rect.right < coords.left ? rect.right : rect.left, - top: coords.top - } : coords; - if (child.nodeType == 1 && dx) - offset = childIndex + (coords.left >= (rect.left + rect.right) / 2 ? 1 : 0); - continue; - } - } else if (rect.top > coords.top && !firstBelow && rect.left <= coords.left && rect.right >= coords.left) { - firstBelow = child; - coordsBelow = { left: Math.max(rect.left, Math.min(rect.right, coords.left)), top: rect.top }; - } - if (!closest && (coords.left >= rect.right && coords.top >= rect.top || coords.left >= rect.left && coords.top >= rect.bottom)) - offset = childIndex + 1; - } - } - if (!closest && firstBelow) { - closest = firstBelow; - coordsClosest = coordsBelow; - dxClosest = 0; - } - if (closest && closest.nodeType == 3) - return findOffsetInText(closest, coordsClosest); - if (!closest || dxClosest && closest.nodeType == 1) - return { node: node2, offset }; - return findOffsetInNode(closest, coordsClosest); - } - function findOffsetInText(node2, coords) { - let len = node2.nodeValue.length; - let range = document.createRange(); - for (let i2 = 0; i2 < len; i2++) { - range.setEnd(node2, i2 + 1); - range.setStart(node2, i2); - let rect = singleRect(range, 1); - if (rect.top == rect.bottom) - continue; - if (inRect(coords, rect)) - return { node: node2, offset: i2 + (coords.left >= (rect.left + rect.right) / 2 ? 1 : 0) }; - } - return { node: node2, offset: 0 }; - } - function inRect(coords, rect) { - return coords.left >= rect.left - 1 && coords.left <= rect.right + 1 && coords.top >= rect.top - 1 && coords.top <= rect.bottom + 1; - } - function targetKludge(dom, coords) { - let parent = dom.parentNode; - if (parent && /^li$/i.test(parent.nodeName) && coords.left < dom.getBoundingClientRect().left) - return parent; - return dom; - } - function posFromElement(view, elt, coords) { - let { node: node2, offset } = findOffsetInNode(elt, coords), bias = -1; - if (node2.nodeType == 1 && !node2.firstChild) { - let rect = node2.getBoundingClientRect(); - bias = rect.left != rect.right && coords.left > (rect.left + rect.right) / 2 ? 1 : -1; - } - return view.docView.posFromDOM(node2, offset, bias); - } - function posFromCaret(view, node2, offset, coords) { - let outsideBlock = -1; - for (let cur = node2, sawBlock = false; ; ) { - if (cur == view.dom) - break; - let desc = view.docView.nearestDesc(cur, true); - if (!desc) - return null; - if (desc.dom.nodeType == 1 && (desc.node.isBlock && desc.parent && !sawBlock || !desc.contentDOM)) { - let rect = desc.dom.getBoundingClientRect(); - if (desc.node.isBlock && desc.parent && !sawBlock) { - sawBlock = true; - if (rect.left > coords.left || rect.top > coords.top) - outsideBlock = desc.posBefore; - else if (rect.right < coords.left || rect.bottom < coords.top) - outsideBlock = desc.posAfter; - } - if (!desc.contentDOM && outsideBlock < 0 && !desc.node.isText) { - let before = desc.node.isBlock ? coords.top < (rect.top + rect.bottom) / 2 : coords.left < (rect.left + rect.right) / 2; - return before ? desc.posBefore : desc.posAfter; - } - } - cur = desc.dom.parentNode; - } - return outsideBlock > -1 ? outsideBlock : view.docView.posFromDOM(node2, offset, -1); - } - function elementFromPoint(element2, coords, box) { - let len = element2.childNodes.length; - if (len && box.top < box.bottom) { - for (let startI = Math.max(0, Math.min(len - 1, Math.floor(len * (coords.top - box.top) / (box.bottom - box.top)) - 2)), i2 = startI; ; ) { - let child = element2.childNodes[i2]; - if (child.nodeType == 1) { - let rects = child.getClientRects(); - for (let j6 = 0; j6 < rects.length; j6++) { - let rect = rects[j6]; - if (inRect(coords, rect)) - return elementFromPoint(child, coords, rect); - } - } - if ((i2 = (i2 + 1) % len) == startI) - break; - } - } - return element2; - } - function posAtCoords(view, coords) { - let doc4 = view.dom.ownerDocument, node2, offset = 0; - let caret = caretFromPoint(doc4, coords.left, coords.top); - if (caret) - ({ node: node2, offset } = caret); - let elt = (view.root.elementFromPoint ? view.root : doc4).elementFromPoint(coords.left, coords.top); - let pos; - if (!elt || !view.dom.contains(elt.nodeType != 1 ? elt.parentNode : elt)) { - let box = view.dom.getBoundingClientRect(); - if (!inRect(coords, box)) - return null; - elt = elementFromPoint(view.dom, coords, box); - if (!elt) - return null; - } - if (safari) { - for (let p4 = elt; node2 && p4; p4 = parentNode(p4)) - if (p4.draggable) - node2 = void 0; - } - elt = targetKludge(elt, coords); - if (node2) { - if (gecko && node2.nodeType == 1) { - offset = Math.min(offset, node2.childNodes.length); - if (offset < node2.childNodes.length) { - let next = node2.childNodes[offset], box; - if (next.nodeName == "IMG" && (box = next.getBoundingClientRect()).right <= coords.left && box.bottom > coords.top) - offset++; - } - } - let prev; - if (webkit && offset && node2.nodeType == 1 && (prev = node2.childNodes[offset - 1]).nodeType == 1 && prev.contentEditable == "false" && prev.getBoundingClientRect().top >= coords.top) - offset--; - if (node2 == view.dom && offset == node2.childNodes.length - 1 && node2.lastChild.nodeType == 1 && coords.top > node2.lastChild.getBoundingClientRect().bottom) - pos = view.state.doc.content.size; - else if (offset == 0 || node2.nodeType != 1 || node2.childNodes[offset - 1].nodeName != "BR") - pos = posFromCaret(view, node2, offset, coords); - } - if (pos == null) - pos = posFromElement(view, elt, coords); - let desc = view.docView.nearestDesc(elt, true); - return { pos, inside: desc ? desc.posAtStart - desc.border : -1 }; - } - function nonZero(rect) { - return rect.top < rect.bottom || rect.left < rect.right; - } - function singleRect(target, bias) { - let rects = target.getClientRects(); - if (rects.length) { - let first = rects[bias < 0 ? 0 : rects.length - 1]; - if (nonZero(first)) - return first; - } - return Array.prototype.find.call(rects, nonZero) || target.getBoundingClientRect(); - } - var BIDI = /[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/; - function coordsAtPos(view, pos, side) { - let { node: node2, offset, atom } = view.docView.domFromPos(pos, side < 0 ? -1 : 1); - let supportEmptyRange = webkit || gecko; - if (node2.nodeType == 3) { - if (supportEmptyRange && (BIDI.test(node2.nodeValue) || (side < 0 ? !offset : offset == node2.nodeValue.length))) { - let rect = singleRect(textRange(node2, offset, offset), side); - if (gecko && offset && /\s/.test(node2.nodeValue[offset - 1]) && offset < node2.nodeValue.length) { - let rectBefore = singleRect(textRange(node2, offset - 1, offset - 1), -1); - if (rectBefore.top == rect.top) { - let rectAfter = singleRect(textRange(node2, offset, offset + 1), -1); - if (rectAfter.top != rect.top) - return flattenV(rectAfter, rectAfter.left < rectBefore.left); - } - } - return rect; - } else { - let from = offset, to = offset, takeSide = side < 0 ? 1 : -1; - if (side < 0 && !offset) { - to++; - takeSide = -1; - } else if (side >= 0 && offset == node2.nodeValue.length) { - from--; - takeSide = 1; - } else if (side < 0) { - from--; - } else { - to++; - } - return flattenV(singleRect(textRange(node2, from, to), takeSide), takeSide < 0); - } - } - let $dom = view.state.doc.resolve(pos - (atom || 0)); - if (!$dom.parent.inlineContent) { - if (atom == null && offset && (side < 0 || offset == nodeSize(node2))) { - let before = node2.childNodes[offset - 1]; - if (before.nodeType == 1) - return flattenH(before.getBoundingClientRect(), false); - } - if (atom == null && offset < nodeSize(node2)) { - let after = node2.childNodes[offset]; - if (after.nodeType == 1) - return flattenH(after.getBoundingClientRect(), true); - } - return flattenH(node2.getBoundingClientRect(), side >= 0); - } - if (atom == null && offset && (side < 0 || offset == nodeSize(node2))) { - let before = node2.childNodes[offset - 1]; - let target = before.nodeType == 3 ? textRange(before, nodeSize(before) - (supportEmptyRange ? 0 : 1)) : before.nodeType == 1 && (before.nodeName != "BR" || !before.nextSibling) ? before : null; - if (target) - return flattenV(singleRect(target, 1), false); - } - if (atom == null && offset < nodeSize(node2)) { - let after = node2.childNodes[offset]; - while (after.pmViewDesc && after.pmViewDesc.ignoreForCoords) - after = after.nextSibling; - let target = !after ? null : after.nodeType == 3 ? textRange(after, 0, supportEmptyRange ? 0 : 1) : after.nodeType == 1 ? after : null; - if (target) - return flattenV(singleRect(target, -1), true); - } - return flattenV(singleRect(node2.nodeType == 3 ? textRange(node2) : node2, -side), side >= 0); - } - function flattenV(rect, left) { - if (rect.width == 0) - return rect; - let x6 = left ? rect.left : rect.right; - return { top: rect.top, bottom: rect.bottom, left: x6, right: x6 }; - } - function flattenH(rect, top) { - if (rect.height == 0) - return rect; - let y4 = top ? rect.top : rect.bottom; - return { top: y4, bottom: y4, left: rect.left, right: rect.right }; - } - function withFlushedState(view, state, f3) { - let viewState = view.state, active = view.root.activeElement; - if (viewState != state) - view.updateState(state); - if (active != view.dom) - view.focus(); - try { - return f3(); - } finally { - if (viewState != state) - view.updateState(viewState); - if (active != view.dom && active) - active.focus(); - } - } - function endOfTextblockVertical(view, state, dir) { - let sel = state.selection; - let $pos = dir == "up" ? sel.$from : sel.$to; - return withFlushedState(view, state, () => { - let { node: dom } = view.docView.domFromPos($pos.pos, dir == "up" ? -1 : 1); - for (; ; ) { - let nearest = view.docView.nearestDesc(dom, true); - if (!nearest) - break; - if (nearest.node.isBlock) { - dom = nearest.contentDOM || nearest.dom; - break; - } - dom = nearest.dom.parentNode; - } - let coords = coordsAtPos(view, $pos.pos, 1); - for (let child = dom.firstChild; child; child = child.nextSibling) { - let boxes; - if (child.nodeType == 1) - boxes = child.getClientRects(); - else if (child.nodeType == 3) - boxes = textRange(child, 0, child.nodeValue.length).getClientRects(); - else - continue; - for (let i2 = 0; i2 < boxes.length; i2++) { - let box = boxes[i2]; - if (box.bottom > box.top + 1 && (dir == "up" ? coords.top - box.top > (box.bottom - coords.top) * 2 : box.bottom - coords.bottom > (coords.bottom - box.top) * 2)) - return false; - } - } - return true; - }); - } - var maybeRTL = /[\u0590-\u08ac]/; - function endOfTextblockHorizontal(view, state, dir) { - let { $head } = state.selection; - if (!$head.parent.isTextblock) - return false; - let offset = $head.parentOffset, atStart = !offset, atEnd = offset == $head.parent.content.size; - let sel = view.domSelection(); - if (!maybeRTL.test($head.parent.textContent) || !sel.modify) - return dir == "left" || dir == "backward" ? atStart : atEnd; - return withFlushedState(view, state, () => { - let { focusNode: oldNode, focusOffset: oldOff, anchorNode, anchorOffset } = view.domSelectionRange(); - let oldBidiLevel = sel.caretBidiLevel; - sel.modify("move", dir, "character"); - let parentDOM = $head.depth ? view.docView.domAfterPos($head.before()) : view.dom; - let { focusNode: newNode, focusOffset: newOff } = view.domSelectionRange(); - let result = newNode && !parentDOM.contains(newNode.nodeType == 1 ? newNode : newNode.parentNode) || oldNode == newNode && oldOff == newOff; - try { - sel.collapse(anchorNode, anchorOffset); - if (oldNode && (oldNode != anchorNode || oldOff != anchorOffset) && sel.extend) - sel.extend(oldNode, oldOff); - } catch (_3) { - } - if (oldBidiLevel != null) - sel.caretBidiLevel = oldBidiLevel; - return result; - }); - } - var cachedState = null; - var cachedDir = null; - var cachedResult = false; - function endOfTextblock(view, state, dir) { - if (cachedState == state && cachedDir == dir) - return cachedResult; - cachedState = state; - cachedDir = dir; - return cachedResult = dir == "up" || dir == "down" ? endOfTextblockVertical(view, state, dir) : endOfTextblockHorizontal(view, state, dir); - } - var NOT_DIRTY = 0; - var CHILD_DIRTY = 1; - var CONTENT_DIRTY = 2; - var NODE_DIRTY = 3; - var ViewDesc = class { - constructor(parent, children, dom, contentDOM) { - this.parent = parent; - this.children = children; - this.dom = dom; - this.contentDOM = contentDOM; - this.dirty = NOT_DIRTY; - dom.pmViewDesc = this; - } - // Used to check whether a given description corresponds to a - // widget/mark/node. - matchesWidget(widget) { - return false; - } - matchesMark(mark) { - return false; - } - matchesNode(node2, outerDeco, innerDeco) { - return false; - } - matchesHack(nodeName) { - return false; - } - // When parsing in-editor content (in domchange.js), we allow - // descriptions to determine the parse rules that should be used to - // parse them. - parseRule() { - return null; - } - // Used by the editor's event handler to ignore events that come - // from certain descs. - stopEvent(event) { - return false; - } - // The size of the content represented by this desc. - get size() { - let size = 0; - for (let i2 = 0; i2 < this.children.length; i2++) - size += this.children[i2].size; - return size; - } - // For block nodes, this represents the space taken up by their - // start/end tokens. - get border() { - return 0; - } - destroy() { - this.parent = void 0; - if (this.dom.pmViewDesc == this) - this.dom.pmViewDesc = void 0; - for (let i2 = 0; i2 < this.children.length; i2++) - this.children[i2].destroy(); - } - posBeforeChild(child) { - for (let i2 = 0, pos = this.posAtStart; ; i2++) { - let cur = this.children[i2]; - if (cur == child) - return pos; - pos += cur.size; - } - } - get posBefore() { - return this.parent.posBeforeChild(this); - } - get posAtStart() { - return this.parent ? this.parent.posBeforeChild(this) + this.border : 0; - } - get posAfter() { - return this.posBefore + this.size; - } - get posAtEnd() { - return this.posAtStart + this.size - 2 * this.border; - } - localPosFromDOM(dom, offset, bias) { - if (this.contentDOM && this.contentDOM.contains(dom.nodeType == 1 ? dom : dom.parentNode)) { - if (bias < 0) { - let domBefore, desc; - if (dom == this.contentDOM) { - domBefore = dom.childNodes[offset - 1]; - } else { - while (dom.parentNode != this.contentDOM) - dom = dom.parentNode; - domBefore = dom.previousSibling; - } - while (domBefore && !((desc = domBefore.pmViewDesc) && desc.parent == this)) - domBefore = domBefore.previousSibling; - return domBefore ? this.posBeforeChild(desc) + desc.size : this.posAtStart; - } else { - let domAfter, desc; - if (dom == this.contentDOM) { - domAfter = dom.childNodes[offset]; - } else { - while (dom.parentNode != this.contentDOM) - dom = dom.parentNode; - domAfter = dom.nextSibling; - } - while (domAfter && !((desc = domAfter.pmViewDesc) && desc.parent == this)) - domAfter = domAfter.nextSibling; - return domAfter ? this.posBeforeChild(desc) : this.posAtEnd; - } - } - let atEnd; - if (dom == this.dom && this.contentDOM) { - atEnd = offset > domIndex(this.contentDOM); - } else if (this.contentDOM && this.contentDOM != this.dom && this.dom.contains(this.contentDOM)) { - atEnd = dom.compareDocumentPosition(this.contentDOM) & 2; - } else if (this.dom.firstChild) { - if (offset == 0) - for (let search2 = dom; ; search2 = search2.parentNode) { - if (search2 == this.dom) { - atEnd = false; - break; - } - if (search2.previousSibling) - break; - } - if (atEnd == null && offset == dom.childNodes.length) - for (let search2 = dom; ; search2 = search2.parentNode) { - if (search2 == this.dom) { - atEnd = true; - break; - } - if (search2.nextSibling) - break; - } - } - return (atEnd == null ? bias > 0 : atEnd) ? this.posAtEnd : this.posAtStart; - } - nearestDesc(dom, onlyNodes = false) { - for (let first = true, cur = dom; cur; cur = cur.parentNode) { - let desc = this.getDesc(cur), nodeDOM; - if (desc && (!onlyNodes || desc.node)) { - if (first && (nodeDOM = desc.nodeDOM) && !(nodeDOM.nodeType == 1 ? nodeDOM.contains(dom.nodeType == 1 ? dom : dom.parentNode) : nodeDOM == dom)) - first = false; - else - return desc; - } - } - } - getDesc(dom) { - let desc = dom.pmViewDesc; - for (let cur = desc; cur; cur = cur.parent) - if (cur == this) - return desc; - } - posFromDOM(dom, offset, bias) { - for (let scan = dom; scan; scan = scan.parentNode) { - let desc = this.getDesc(scan); - if (desc) - return desc.localPosFromDOM(dom, offset, bias); - } - return -1; - } - // Find the desc for the node after the given pos, if any. (When a - // parent node overrode rendering, there might not be one.) - descAt(pos) { - for (let i2 = 0, offset = 0; i2 < this.children.length; i2++) { - let child = this.children[i2], end = offset + child.size; - if (offset == pos && end != offset) { - while (!child.border && child.children.length) - child = child.children[0]; - return child; - } - if (pos < end) - return child.descAt(pos - offset - child.border); - offset = end; - } - } - domFromPos(pos, side) { - if (!this.contentDOM) - return { node: this.dom, offset: 0, atom: pos + 1 }; - let i2 = 0, offset = 0; - for (let curPos = 0; i2 < this.children.length; i2++) { - let child = this.children[i2], end = curPos + child.size; - if (end > pos || child instanceof TrailingHackViewDesc) { - offset = pos - curPos; - break; - } - curPos = end; - } - if (offset) - return this.children[i2].domFromPos(offset - this.children[i2].border, side); - for (let prev; i2 && !(prev = this.children[i2 - 1]).size && prev instanceof WidgetViewDesc && prev.side >= 0; i2--) { - } - if (side <= 0) { - let prev, enter = true; - for (; ; i2--, enter = false) { - prev = i2 ? this.children[i2 - 1] : null; - if (!prev || prev.dom.parentNode == this.contentDOM) - break; - } - if (prev && side && enter && !prev.border && !prev.domAtom) - return prev.domFromPos(prev.size, side); - return { node: this.contentDOM, offset: prev ? domIndex(prev.dom) + 1 : 0 }; - } else { - let next, enter = true; - for (; ; i2++, enter = false) { - next = i2 < this.children.length ? this.children[i2] : null; - if (!next || next.dom.parentNode == this.contentDOM) - break; - } - if (next && enter && !next.border && !next.domAtom) - return next.domFromPos(0, side); - return { node: this.contentDOM, offset: next ? domIndex(next.dom) : this.contentDOM.childNodes.length }; - } - } - // Used to find a DOM range in a single parent for a given changed - // range. - parseRange(from, to, base2 = 0) { - if (this.children.length == 0) - return { node: this.contentDOM, from, to, fromOffset: 0, toOffset: this.contentDOM.childNodes.length }; - let fromOffset = -1, toOffset = -1; - for (let offset = base2, i2 = 0; ; i2++) { - let child = this.children[i2], end = offset + child.size; - if (fromOffset == -1 && from <= end) { - let childBase = offset + child.border; - if (from >= childBase && to <= end - child.border && child.node && child.contentDOM && this.contentDOM.contains(child.contentDOM)) - return child.parseRange(from, to, childBase); - from = offset; - for (let j6 = i2; j6 > 0; j6--) { - let prev = this.children[j6 - 1]; - if (prev.size && prev.dom.parentNode == this.contentDOM && !prev.emptyChildAt(1)) { - fromOffset = domIndex(prev.dom) + 1; - break; - } - from -= prev.size; - } - if (fromOffset == -1) - fromOffset = 0; - } - if (fromOffset > -1 && (end > to || i2 == this.children.length - 1)) { - to = end; - for (let j6 = i2 + 1; j6 < this.children.length; j6++) { - let next = this.children[j6]; - if (next.size && next.dom.parentNode == this.contentDOM && !next.emptyChildAt(-1)) { - toOffset = domIndex(next.dom); - break; - } - to += next.size; - } - if (toOffset == -1) - toOffset = this.contentDOM.childNodes.length; - break; - } - offset = end; - } - return { node: this.contentDOM, from, to, fromOffset, toOffset }; - } - emptyChildAt(side) { - if (this.border || !this.contentDOM || !this.children.length) - return false; - let child = this.children[side < 0 ? 0 : this.children.length - 1]; - return child.size == 0 || child.emptyChildAt(side); - } - domAfterPos(pos) { - let { node: node2, offset } = this.domFromPos(pos, 0); - if (node2.nodeType != 1 || offset == node2.childNodes.length) - throw new RangeError("No node after pos " + pos); - return node2.childNodes[offset]; - } - // View descs are responsible for setting any selection that falls - // entirely inside of them, so that custom implementations can do - // custom things with the selection. Note that this falls apart when - // a selection starts in such a node and ends in another, in which - // case we just use whatever domFromPos produces as a best effort. - setSelection(anchor, head, root2, force = false) { - let from = Math.min(anchor, head), to = Math.max(anchor, head); - for (let i2 = 0, offset = 0; i2 < this.children.length; i2++) { - let child = this.children[i2], end = offset + child.size; - if (from > offset && to < end) - return child.setSelection(anchor - offset - child.border, head - offset - child.border, root2, force); - offset = end; - } - let anchorDOM = this.domFromPos(anchor, anchor ? -1 : 1); - let headDOM = head == anchor ? anchorDOM : this.domFromPos(head, head ? -1 : 1); - let domSel = root2.getSelection(); - let brKludge = false; - if ((gecko || safari) && anchor == head) { - let { node: node2, offset } = anchorDOM; - if (node2.nodeType == 3) { - brKludge = !!(offset && node2.nodeValue[offset - 1] == "\n"); - if (brKludge && offset == node2.nodeValue.length) { - for (let scan = node2, after; scan; scan = scan.parentNode) { - if (after = scan.nextSibling) { - if (after.nodeName == "BR") - anchorDOM = headDOM = { node: after.parentNode, offset: domIndex(after) + 1 }; - break; - } - let desc = scan.pmViewDesc; - if (desc && desc.node && desc.node.isBlock) - break; - } - } - } else { - let prev = node2.childNodes[offset - 1]; - brKludge = prev && (prev.nodeName == "BR" || prev.contentEditable == "false"); - } - } - if (gecko && domSel.focusNode && domSel.focusNode != headDOM.node && domSel.focusNode.nodeType == 1) { - let after = domSel.focusNode.childNodes[domSel.focusOffset]; - if (after && after.contentEditable == "false") - force = true; - } - if (!(force || brKludge && safari) && isEquivalentPosition(anchorDOM.node, anchorDOM.offset, domSel.anchorNode, domSel.anchorOffset) && isEquivalentPosition(headDOM.node, headDOM.offset, domSel.focusNode, domSel.focusOffset)) - return; - let domSelExtended = false; - if ((domSel.extend || anchor == head) && !brKludge) { - domSel.collapse(anchorDOM.node, anchorDOM.offset); - try { - if (anchor != head) - domSel.extend(headDOM.node, headDOM.offset); - domSelExtended = true; - } catch (_3) { - } - } - if (!domSelExtended) { - if (anchor > head) { - let tmp = anchorDOM; - anchorDOM = headDOM; - headDOM = tmp; - } - let range = document.createRange(); - range.setEnd(headDOM.node, headDOM.offset); - range.setStart(anchorDOM.node, anchorDOM.offset); - domSel.removeAllRanges(); - domSel.addRange(range); - } - } - ignoreMutation(mutation) { - return !this.contentDOM && mutation.type != "selection"; - } - get contentLost() { - return this.contentDOM && this.contentDOM != this.dom && !this.dom.contains(this.contentDOM); - } - // Remove a subtree of the element tree that has been touched - // by a DOM change, so that the next update will redraw it. - markDirty(from, to) { - for (let offset = 0, i2 = 0; i2 < this.children.length; i2++) { - let child = this.children[i2], end = offset + child.size; - if (offset == end ? from <= end && to >= offset : from < end && to > offset) { - let startInside = offset + child.border, endInside = end - child.border; - if (from >= startInside && to <= endInside) { - this.dirty = from == offset || to == end ? CONTENT_DIRTY : CHILD_DIRTY; - if (from == startInside && to == endInside && (child.contentLost || child.dom.parentNode != this.contentDOM)) - child.dirty = NODE_DIRTY; - else - child.markDirty(from - startInside, to - startInside); - return; - } else { - child.dirty = child.dom == child.contentDOM && child.dom.parentNode == this.contentDOM && !child.children.length ? CONTENT_DIRTY : NODE_DIRTY; - } - } - offset = end; - } - this.dirty = CONTENT_DIRTY; - } - markParentsDirty() { - let level = 1; - for (let node2 = this.parent; node2; node2 = node2.parent, level++) { - let dirty = level == 1 ? CONTENT_DIRTY : CHILD_DIRTY; - if (node2.dirty < dirty) - node2.dirty = dirty; - } - } - get domAtom() { - return false; - } - get ignoreForCoords() { - return false; - } - isText(text5) { - return false; - } - }; - var WidgetViewDesc = class extends ViewDesc { - constructor(parent, widget, view, pos) { - let self2, dom = widget.type.toDOM; - if (typeof dom == "function") - dom = dom(view, () => { - if (!self2) - return pos; - if (self2.parent) - return self2.parent.posBeforeChild(self2); - }); - if (!widget.type.spec.raw) { - if (dom.nodeType != 1) { - let wrap3 = document.createElement("span"); - wrap3.appendChild(dom); - dom = wrap3; - } - dom.contentEditable = "false"; - dom.classList.add("ProseMirror-widget"); - } - super(parent, [], dom, null); - this.widget = widget; - this.widget = widget; - self2 = this; - } - matchesWidget(widget) { - return this.dirty == NOT_DIRTY && widget.type.eq(this.widget.type); - } - parseRule() { - return { ignore: true }; - } - stopEvent(event) { - let stop = this.widget.spec.stopEvent; - return stop ? stop(event) : false; - } - ignoreMutation(mutation) { - return mutation.type != "selection" || this.widget.spec.ignoreSelection; - } - destroy() { - this.widget.type.destroy(this.dom); - super.destroy(); - } - get domAtom() { - return true; - } - get side() { - return this.widget.type.side; - } - }; - var CompositionViewDesc = class extends ViewDesc { - constructor(parent, dom, textDOM, text5) { - super(parent, [], dom, null); - this.textDOM = textDOM; - this.text = text5; - } - get size() { - return this.text.length; - } - localPosFromDOM(dom, offset) { - if (dom != this.textDOM) - return this.posAtStart + (offset ? this.size : 0); - return this.posAtStart + offset; - } - domFromPos(pos) { - return { node: this.textDOM, offset: pos }; - } - ignoreMutation(mut) { - return mut.type === "characterData" && mut.target.nodeValue == mut.oldValue; - } - }; - var MarkViewDesc = class _MarkViewDesc extends ViewDesc { - constructor(parent, mark, dom, contentDOM) { - super(parent, [], dom, contentDOM); - this.mark = mark; - } - static create(parent, mark, inline, view) { - let custom = view.nodeViews[mark.type.name]; - let spec = custom && custom(mark, view, inline); - if (!spec || !spec.dom) - spec = DOMSerializer.renderSpec(document, mark.type.spec.toDOM(mark, inline)); - return new _MarkViewDesc(parent, mark, spec.dom, spec.contentDOM || spec.dom); - } - parseRule() { - if (this.dirty & NODE_DIRTY || this.mark.type.spec.reparseInView) - return null; - return { mark: this.mark.type.name, attrs: this.mark.attrs, contentElement: this.contentDOM }; - } - matchesMark(mark) { - return this.dirty != NODE_DIRTY && this.mark.eq(mark); - } - markDirty(from, to) { - super.markDirty(from, to); - if (this.dirty != NOT_DIRTY) { - let parent = this.parent; - while (!parent.node) - parent = parent.parent; - if (parent.dirty < this.dirty) - parent.dirty = this.dirty; - this.dirty = NOT_DIRTY; - } - } - slice(from, to, view) { - let copy2 = _MarkViewDesc.create(this.parent, this.mark, true, view); - let nodes = this.children, size = this.size; - if (to < size) - nodes = replaceNodes(nodes, to, size, view); - if (from > 0) - nodes = replaceNodes(nodes, 0, from, view); - for (let i2 = 0; i2 < nodes.length; i2++) - nodes[i2].parent = copy2; - copy2.children = nodes; - return copy2; - } - }; - var NodeViewDesc = class _NodeViewDesc extends ViewDesc { - constructor(parent, node2, outerDeco, innerDeco, dom, contentDOM, nodeDOM, view, pos) { - super(parent, [], dom, contentDOM); - this.node = node2; - this.outerDeco = outerDeco; - this.innerDeco = innerDeco; - this.nodeDOM = nodeDOM; - } - // By default, a node is rendered using the `toDOM` method from the - // node type spec. But client code can use the `nodeViews` spec to - // supply a custom node view, which can influence various aspects of - // the way the node works. - // - // (Using subclassing for this was intentionally decided against, - // since it'd require exposing a whole slew of finicky - // implementation details to the user code that they probably will - // never need.) - static create(parent, node2, outerDeco, innerDeco, view, pos) { - let custom = view.nodeViews[node2.type.name], descObj; - let spec = custom && custom(node2, view, () => { - if (!descObj) - return pos; - if (descObj.parent) - return descObj.parent.posBeforeChild(descObj); - }, outerDeco, innerDeco); - let dom = spec && spec.dom, contentDOM = spec && spec.contentDOM; - if (node2.isText) { - if (!dom) - dom = document.createTextNode(node2.text); - else if (dom.nodeType != 3) - throw new RangeError("Text must be rendered as a DOM text node"); - } else if (!dom) { - ({ dom, contentDOM } = DOMSerializer.renderSpec(document, node2.type.spec.toDOM(node2))); - } - if (!contentDOM && !node2.isText && dom.nodeName != "BR") { - if (!dom.hasAttribute("contenteditable")) - dom.contentEditable = "false"; - if (node2.type.spec.draggable) - dom.draggable = true; - } - let nodeDOM = dom; - dom = applyOuterDeco(dom, outerDeco, node2); - if (spec) - return descObj = new CustomNodeViewDesc(parent, node2, outerDeco, innerDeco, dom, contentDOM || null, nodeDOM, spec, view, pos + 1); - else if (node2.isText) - return new TextViewDesc(parent, node2, outerDeco, innerDeco, dom, nodeDOM, view); - else - return new _NodeViewDesc(parent, node2, outerDeco, innerDeco, dom, contentDOM || null, nodeDOM, view, pos + 1); - } - parseRule() { - if (this.node.type.spec.reparseInView) - return null; - let rule = { node: this.node.type.name, attrs: this.node.attrs }; - if (this.node.type.whitespace == "pre") - rule.preserveWhitespace = "full"; - if (!this.contentDOM) { - rule.getContent = () => this.node.content; - } else if (!this.contentLost) { - rule.contentElement = this.contentDOM; - } else { - for (let i2 = this.children.length - 1; i2 >= 0; i2--) { - let child = this.children[i2]; - if (this.dom.contains(child.dom.parentNode)) { - rule.contentElement = child.dom.parentNode; - break; - } - } - if (!rule.contentElement) - rule.getContent = () => Fragment.empty; - } - return rule; - } - matchesNode(node2, outerDeco, innerDeco) { - return this.dirty == NOT_DIRTY && node2.eq(this.node) && sameOuterDeco(outerDeco, this.outerDeco) && innerDeco.eq(this.innerDeco); - } - get size() { - return this.node.nodeSize; - } - get border() { - return this.node.isLeaf ? 0 : 1; - } - // Syncs `this.children` to match `this.node.content` and the local - // decorations, possibly introducing nesting for marks. Then, in a - // separate step, syncs the DOM inside `this.contentDOM` to - // `this.children`. - updateChildren(view, pos) { - let inline = this.node.inlineContent, off = pos; - let composition = view.composing ? this.localCompositionInfo(view, pos) : null; - let localComposition = composition && composition.pos > -1 ? composition : null; - let compositionInChild = composition && composition.pos < 0; - let updater = new ViewTreeUpdater(this, localComposition && localComposition.node, view); - iterDeco(this.node, this.innerDeco, (widget, i2, insideNode) => { - if (widget.spec.marks) - updater.syncToMarks(widget.spec.marks, inline, view); - else if (widget.type.side >= 0 && !insideNode) - updater.syncToMarks(i2 == this.node.childCount ? Mark.none : this.node.child(i2).marks, inline, view); - updater.placeWidget(widget, view, off); - }, (child, outerDeco, innerDeco, i2) => { - updater.syncToMarks(child.marks, inline, view); - let compIndex; - if (updater.findNodeMatch(child, outerDeco, innerDeco, i2)) ; - else if (compositionInChild && view.state.selection.from > off && view.state.selection.to < off + child.nodeSize && (compIndex = updater.findIndexWithChild(composition.node)) > -1 && updater.updateNodeAt(child, outerDeco, innerDeco, compIndex, view)) ; - else if (updater.updateNextNode(child, outerDeco, innerDeco, view, i2, off)) ; - else { - updater.addNode(child, outerDeco, innerDeco, view, off); - } - off += child.nodeSize; - }); - updater.syncToMarks([], inline, view); - if (this.node.isTextblock) - updater.addTextblockHacks(); - updater.destroyRest(); - if (updater.changed || this.dirty == CONTENT_DIRTY) { - if (localComposition) - this.protectLocalComposition(view, localComposition); - renderDescs(this.contentDOM, this.children, view); - if (ios) - iosHacks(this.dom); - } - } - localCompositionInfo(view, pos) { - let { from, to } = view.state.selection; - if (!(view.state.selection instanceof TextSelection) || from < pos || to > pos + this.node.content.size) - return null; - let textNode = view.input.compositionNode; - if (!textNode || !this.dom.contains(textNode.parentNode)) - return null; - if (this.node.inlineContent) { - let text5 = textNode.nodeValue; - let textPos = findTextInFragment(this.node.content, text5, from - pos, to - pos); - return textPos < 0 ? null : { node: textNode, pos: textPos, text: text5 }; - } else { - return { node: textNode, pos: -1, text: "" }; - } - } - protectLocalComposition(view, { node: node2, pos, text: text5 }) { - if (this.getDesc(node2)) - return; - let topNode = node2; - for (; ; topNode = topNode.parentNode) { - if (topNode.parentNode == this.contentDOM) - break; - while (topNode.previousSibling) - topNode.parentNode.removeChild(topNode.previousSibling); - while (topNode.nextSibling) - topNode.parentNode.removeChild(topNode.nextSibling); - if (topNode.pmViewDesc) - topNode.pmViewDesc = void 0; - } - let desc = new CompositionViewDesc(this, topNode, node2, text5); - view.input.compositionNodes.push(desc); - this.children = replaceNodes(this.children, pos, pos + text5.length, view, desc); - } - // If this desc must be updated to match the given node decoration, - // do so and return true. - update(node2, outerDeco, innerDeco, view) { - if (this.dirty == NODE_DIRTY || !node2.sameMarkup(this.node)) - return false; - this.updateInner(node2, outerDeco, innerDeco, view); - return true; - } - updateInner(node2, outerDeco, innerDeco, view) { - this.updateOuterDeco(outerDeco); - this.node = node2; - this.innerDeco = innerDeco; - if (this.contentDOM) - this.updateChildren(view, this.posAtStart); - this.dirty = NOT_DIRTY; - } - updateOuterDeco(outerDeco) { - if (sameOuterDeco(outerDeco, this.outerDeco)) - return; - let needsWrap = this.nodeDOM.nodeType != 1; - let oldDOM = this.dom; - this.dom = patchOuterDeco(this.dom, this.nodeDOM, computeOuterDeco(this.outerDeco, this.node, needsWrap), computeOuterDeco(outerDeco, this.node, needsWrap)); - if (this.dom != oldDOM) { - oldDOM.pmViewDesc = void 0; - this.dom.pmViewDesc = this; - } - this.outerDeco = outerDeco; - } - // Mark this node as being the selected node. - selectNode() { - if (this.nodeDOM.nodeType == 1) - this.nodeDOM.classList.add("ProseMirror-selectednode"); - if (this.contentDOM || !this.node.type.spec.draggable) - this.dom.draggable = true; - } - // Remove selected node marking from this node. - deselectNode() { - if (this.nodeDOM.nodeType == 1) - this.nodeDOM.classList.remove("ProseMirror-selectednode"); - if (this.contentDOM || !this.node.type.spec.draggable) - this.dom.removeAttribute("draggable"); - } - get domAtom() { - return this.node.isAtom; - } - }; - function docViewDesc(doc4, outerDeco, innerDeco, dom, view) { - applyOuterDeco(dom, outerDeco, doc4); - let docView = new NodeViewDesc(void 0, doc4, outerDeco, innerDeco, dom, dom, dom, view, 0); - if (docView.contentDOM) - docView.updateChildren(view, 0); - return docView; - } - var TextViewDesc = class _TextViewDesc extends NodeViewDesc { - constructor(parent, node2, outerDeco, innerDeco, dom, nodeDOM, view) { - super(parent, node2, outerDeco, innerDeco, dom, null, nodeDOM, view, 0); - } - parseRule() { - let skip = this.nodeDOM.parentNode; - while (skip && skip != this.dom && !skip.pmIsDeco) - skip = skip.parentNode; - return { skip: skip || true }; - } - update(node2, outerDeco, innerDeco, view) { - if (this.dirty == NODE_DIRTY || this.dirty != NOT_DIRTY && !this.inParent() || !node2.sameMarkup(this.node)) - return false; - this.updateOuterDeco(outerDeco); - if ((this.dirty != NOT_DIRTY || node2.text != this.node.text) && node2.text != this.nodeDOM.nodeValue) { - this.nodeDOM.nodeValue = node2.text; - if (view.trackWrites == this.nodeDOM) - view.trackWrites = null; - } - this.node = node2; - this.dirty = NOT_DIRTY; - return true; - } - inParent() { - let parentDOM = this.parent.contentDOM; - for (let n4 = this.nodeDOM; n4; n4 = n4.parentNode) - if (n4 == parentDOM) - return true; - return false; - } - domFromPos(pos) { - return { node: this.nodeDOM, offset: pos }; - } - localPosFromDOM(dom, offset, bias) { - if (dom == this.nodeDOM) - return this.posAtStart + Math.min(offset, this.node.text.length); - return super.localPosFromDOM(dom, offset, bias); - } - ignoreMutation(mutation) { - return mutation.type != "characterData" && mutation.type != "selection"; - } - slice(from, to, view) { - let node2 = this.node.cut(from, to), dom = document.createTextNode(node2.text); - return new _TextViewDesc(this.parent, node2, this.outerDeco, this.innerDeco, dom, dom, view); - } - markDirty(from, to) { - super.markDirty(from, to); - if (this.dom != this.nodeDOM && (from == 0 || to == this.nodeDOM.nodeValue.length)) - this.dirty = NODE_DIRTY; - } - get domAtom() { - return false; - } - isText(text5) { - return this.node.text == text5; - } - }; - var TrailingHackViewDesc = class extends ViewDesc { - parseRule() { - return { ignore: true }; - } - matchesHack(nodeName) { - return this.dirty == NOT_DIRTY && this.dom.nodeName == nodeName; - } - get domAtom() { - return true; - } - get ignoreForCoords() { - return this.dom.nodeName == "IMG"; - } - }; - var CustomNodeViewDesc = class extends NodeViewDesc { - constructor(parent, node2, outerDeco, innerDeco, dom, contentDOM, nodeDOM, spec, view, pos) { - super(parent, node2, outerDeco, innerDeco, dom, contentDOM, nodeDOM, view, pos); - this.spec = spec; - } - // A custom `update` method gets to decide whether the update goes - // through. If it does, and there's a `contentDOM` node, our logic - // updates the children. - update(node2, outerDeco, innerDeco, view) { - if (this.dirty == NODE_DIRTY) - return false; - if (this.spec.update) { - let result = this.spec.update(node2, outerDeco, innerDeco); - if (result) - this.updateInner(node2, outerDeco, innerDeco, view); - return result; - } else if (!this.contentDOM && !node2.isLeaf) { - return false; - } else { - return super.update(node2, outerDeco, innerDeco, view); - } - } - selectNode() { - this.spec.selectNode ? this.spec.selectNode() : super.selectNode(); - } - deselectNode() { - this.spec.deselectNode ? this.spec.deselectNode() : super.deselectNode(); - } - setSelection(anchor, head, root2, force) { - this.spec.setSelection ? this.spec.setSelection(anchor, head, root2) : super.setSelection(anchor, head, root2, force); - } - destroy() { - if (this.spec.destroy) - this.spec.destroy(); - super.destroy(); - } - stopEvent(event) { - return this.spec.stopEvent ? this.spec.stopEvent(event) : false; - } - ignoreMutation(mutation) { - return this.spec.ignoreMutation ? this.spec.ignoreMutation(mutation) : super.ignoreMutation(mutation); - } - }; - function renderDescs(parentDOM, descs, view) { - let dom = parentDOM.firstChild, written = false; - for (let i2 = 0; i2 < descs.length; i2++) { - let desc = descs[i2], childDOM = desc.dom; - if (childDOM.parentNode == parentDOM) { - while (childDOM != dom) { - dom = rm(dom); - written = true; - } - dom = dom.nextSibling; - } else { - written = true; - parentDOM.insertBefore(childDOM, dom); - } - if (desc instanceof MarkViewDesc) { - let pos = dom ? dom.previousSibling : parentDOM.lastChild; - renderDescs(desc.contentDOM, desc.children, view); - dom = pos ? pos.nextSibling : parentDOM.firstChild; - } - } - while (dom) { - dom = rm(dom); - written = true; - } - if (written && view.trackWrites == parentDOM) - view.trackWrites = null; - } - var OuterDecoLevel = function(nodeName) { - if (nodeName) - this.nodeName = nodeName; - }; - OuterDecoLevel.prototype = /* @__PURE__ */ Object.create(null); - var noDeco = [new OuterDecoLevel()]; - function computeOuterDeco(outerDeco, node2, needsWrap) { - if (outerDeco.length == 0) - return noDeco; - let top = needsWrap ? noDeco[0] : new OuterDecoLevel(), result = [top]; - for (let i2 = 0; i2 < outerDeco.length; i2++) { - let attrs = outerDeco[i2].type.attrs; - if (!attrs) - continue; - if (attrs.nodeName) - result.push(top = new OuterDecoLevel(attrs.nodeName)); - for (let name in attrs) { - let val = attrs[name]; - if (val == null) - continue; - if (needsWrap && result.length == 1) - result.push(top = new OuterDecoLevel(node2.isInline ? "span" : "div")); - if (name == "class") - top.class = (top.class ? top.class + " " : "") + val; - else if (name == "style") - top.style = (top.style ? top.style + ";" : "") + val; - else if (name != "nodeName") - top[name] = val; - } - } - return result; - } - function patchOuterDeco(outerDOM, nodeDOM, prevComputed, curComputed) { - if (prevComputed == noDeco && curComputed == noDeco) - return nodeDOM; - let curDOM = nodeDOM; - for (let i2 = 0; i2 < curComputed.length; i2++) { - let deco = curComputed[i2], prev = prevComputed[i2]; - if (i2) { - let parent; - if (prev && prev.nodeName == deco.nodeName && curDOM != outerDOM && (parent = curDOM.parentNode) && parent.nodeName.toLowerCase() == deco.nodeName) { - curDOM = parent; - } else { - parent = document.createElement(deco.nodeName); - parent.pmIsDeco = true; - parent.appendChild(curDOM); - prev = noDeco[0]; - curDOM = parent; - } - } - patchAttributes(curDOM, prev || noDeco[0], deco); - } - return curDOM; - } - function patchAttributes(dom, prev, cur) { - for (let name in prev) - if (name != "class" && name != "style" && name != "nodeName" && !(name in cur)) - dom.removeAttribute(name); - for (let name in cur) - if (name != "class" && name != "style" && name != "nodeName" && cur[name] != prev[name]) - dom.setAttribute(name, cur[name]); - if (prev.class != cur.class) { - let prevList = prev.class ? prev.class.split(" ").filter(Boolean) : []; - let curList = cur.class ? cur.class.split(" ").filter(Boolean) : []; - for (let i2 = 0; i2 < prevList.length; i2++) - if (curList.indexOf(prevList[i2]) == -1) - dom.classList.remove(prevList[i2]); - for (let i2 = 0; i2 < curList.length; i2++) - if (prevList.indexOf(curList[i2]) == -1) - dom.classList.add(curList[i2]); - if (dom.classList.length == 0) - dom.removeAttribute("class"); - } - if (prev.style != cur.style) { - if (prev.style) { - let prop = /\s*([\w\-\xa1-\uffff]+)\s*:(?:"(?:\\.|[^"])*"|'(?:\\.|[^'])*'|\(.*?\)|[^;])*/g, m3; - while (m3 = prop.exec(prev.style)) - dom.style.removeProperty(m3[1]); - } - if (cur.style) - dom.style.cssText += cur.style; - } - } - function applyOuterDeco(dom, deco, node2) { - return patchOuterDeco(dom, dom, noDeco, computeOuterDeco(deco, node2, dom.nodeType != 1)); - } - function sameOuterDeco(a2, b4) { - if (a2.length != b4.length) - return false; - for (let i2 = 0; i2 < a2.length; i2++) - if (!a2[i2].type.eq(b4[i2].type)) - return false; - return true; - } - function rm(dom) { - let next = dom.nextSibling; - dom.parentNode.removeChild(dom); - return next; - } - var ViewTreeUpdater = class { - constructor(top, lock, view) { - this.lock = lock; - this.view = view; - this.index = 0; - this.stack = []; - this.changed = false; - this.top = top; - this.preMatch = preMatch(top.node.content, top); - } - // Destroy and remove the children between the given indices in - // `this.top`. - destroyBetween(start, end) { - if (start == end) - return; - for (let i2 = start; i2 < end; i2++) - this.top.children[i2].destroy(); - this.top.children.splice(start, end - start); - this.changed = true; - } - // Destroy all remaining children in `this.top`. - destroyRest() { - this.destroyBetween(this.index, this.top.children.length); - } - // Sync the current stack of mark descs with the given array of - // marks, reusing existing mark descs when possible. - syncToMarks(marks, inline, view) { - let keep = 0, depth = this.stack.length >> 1; - let maxKeep = Math.min(depth, marks.length); - while (keep < maxKeep && (keep == depth - 1 ? this.top : this.stack[keep + 1 << 1]).matchesMark(marks[keep]) && marks[keep].type.spec.spanning !== false) - keep++; - while (keep < depth) { - this.destroyRest(); - this.top.dirty = NOT_DIRTY; - this.index = this.stack.pop(); - this.top = this.stack.pop(); - depth--; - } - while (depth < marks.length) { - this.stack.push(this.top, this.index + 1); - let found2 = -1; - for (let i2 = this.index; i2 < Math.min(this.index + 3, this.top.children.length); i2++) { - let next = this.top.children[i2]; - if (next.matchesMark(marks[depth]) && !this.isLocked(next.dom)) { - found2 = i2; - break; - } - } - if (found2 > -1) { - if (found2 > this.index) { - this.changed = true; - this.destroyBetween(this.index, found2); - } - this.top = this.top.children[this.index]; - } else { - let markDesc = MarkViewDesc.create(this.top, marks[depth], inline, view); - this.top.children.splice(this.index, 0, markDesc); - this.top = markDesc; - this.changed = true; - } - this.index = 0; - depth++; - } - } - // Try to find a node desc matching the given data. Skip over it and - // return true when successful. - findNodeMatch(node2, outerDeco, innerDeco, index2) { - let found2 = -1, targetDesc; - if (index2 >= this.preMatch.index && (targetDesc = this.preMatch.matches[index2 - this.preMatch.index]).parent == this.top && targetDesc.matchesNode(node2, outerDeco, innerDeco)) { - found2 = this.top.children.indexOf(targetDesc, this.index); - } else { - for (let i2 = this.index, e2 = Math.min(this.top.children.length, i2 + 5); i2 < e2; i2++) { - let child = this.top.children[i2]; - if (child.matchesNode(node2, outerDeco, innerDeco) && !this.preMatch.matched.has(child)) { - found2 = i2; - break; - } - } - } - if (found2 < 0) - return false; - this.destroyBetween(this.index, found2); - this.index++; - return true; - } - updateNodeAt(node2, outerDeco, innerDeco, index2, view) { - let child = this.top.children[index2]; - if (child.dirty == NODE_DIRTY && child.dom == child.contentDOM) - child.dirty = CONTENT_DIRTY; - if (!child.update(node2, outerDeco, innerDeco, view)) - return false; - this.destroyBetween(this.index, index2); - this.index++; - return true; - } - findIndexWithChild(domNode) { - for (; ; ) { - let parent = domNode.parentNode; - if (!parent) - return -1; - if (parent == this.top.contentDOM) { - let desc = domNode.pmViewDesc; - if (desc) - for (let i2 = this.index; i2 < this.top.children.length; i2++) { - if (this.top.children[i2] == desc) - return i2; - } - return -1; - } - domNode = parent; - } - } - // Try to update the next node, if any, to the given data. Checks - // pre-matches to avoid overwriting nodes that could still be used. - updateNextNode(node2, outerDeco, innerDeco, view, index2, pos) { - for (let i2 = this.index; i2 < this.top.children.length; i2++) { - let next = this.top.children[i2]; - if (next instanceof NodeViewDesc) { - let preMatch2 = this.preMatch.matched.get(next); - if (preMatch2 != null && preMatch2 != index2) - return false; - let nextDOM = next.dom, updated; - let locked = this.isLocked(nextDOM) && !(node2.isText && next.node && next.node.isText && next.nodeDOM.nodeValue == node2.text && next.dirty != NODE_DIRTY && sameOuterDeco(outerDeco, next.outerDeco)); - if (!locked && next.update(node2, outerDeco, innerDeco, view)) { - this.destroyBetween(this.index, i2); - if (next.dom != nextDOM) - this.changed = true; - this.index++; - return true; - } else if (!locked && (updated = this.recreateWrapper(next, node2, outerDeco, innerDeco, view, pos))) { - this.top.children[this.index] = updated; - if (updated.contentDOM) { - updated.dirty = CONTENT_DIRTY; - updated.updateChildren(view, pos + 1); - updated.dirty = NOT_DIRTY; - } - this.changed = true; - this.index++; - return true; - } - break; - } - } - return false; - } - // When a node with content is replaced by a different node with - // identical content, move over its children. - recreateWrapper(next, node2, outerDeco, innerDeco, view, pos) { - if (next.dirty || node2.isAtom || !next.children.length || !next.node.content.eq(node2.content)) - return null; - let wrapper = NodeViewDesc.create(this.top, node2, outerDeco, innerDeco, view, pos); - if (wrapper.contentDOM) { - wrapper.children = next.children; - next.children = []; - for (let ch of wrapper.children) - ch.parent = wrapper; - } - next.destroy(); - return wrapper; - } - // Insert the node as a newly created node desc. - addNode(node2, outerDeco, innerDeco, view, pos) { - let desc = NodeViewDesc.create(this.top, node2, outerDeco, innerDeco, view, pos); - if (desc.contentDOM) - desc.updateChildren(view, pos + 1); - this.top.children.splice(this.index++, 0, desc); - this.changed = true; - } - placeWidget(widget, view, pos) { - let next = this.index < this.top.children.length ? this.top.children[this.index] : null; - if (next && next.matchesWidget(widget) && (widget == next.widget || !next.widget.type.toDOM.parentNode)) { - this.index++; - } else { - let desc = new WidgetViewDesc(this.top, widget, view, pos); - this.top.children.splice(this.index++, 0, desc); - this.changed = true; - } - } - // Make sure a textblock looks and behaves correctly in - // contentEditable. - addTextblockHacks() { - let lastChild = this.top.children[this.index - 1], parent = this.top; - while (lastChild instanceof MarkViewDesc) { - parent = lastChild; - lastChild = parent.children[parent.children.length - 1]; - } - if (!lastChild || // Empty textblock - !(lastChild instanceof TextViewDesc) || /\n$/.test(lastChild.node.text) || this.view.requiresGeckoHackNode && /\s$/.test(lastChild.node.text)) { - if ((safari || chrome) && lastChild && lastChild.dom.contentEditable == "false") - this.addHackNode("IMG", parent); - this.addHackNode("BR", this.top); - } - } - addHackNode(nodeName, parent) { - if (parent == this.top && this.index < parent.children.length && parent.children[this.index].matchesHack(nodeName)) { - this.index++; - } else { - let dom = document.createElement(nodeName); - if (nodeName == "IMG") { - dom.className = "ProseMirror-separator"; - dom.alt = ""; - } - if (nodeName == "BR") - dom.className = "ProseMirror-trailingBreak"; - let hack = new TrailingHackViewDesc(this.top, [], dom, null); - if (parent != this.top) - parent.children.push(hack); - else - parent.children.splice(this.index++, 0, hack); - this.changed = true; - } - } - isLocked(node2) { - return this.lock && (node2 == this.lock || node2.nodeType == 1 && node2.contains(this.lock.parentNode)); - } - }; - function preMatch(frag, parentDesc) { - let curDesc = parentDesc, descI = curDesc.children.length; - let fI = frag.childCount, matched = /* @__PURE__ */ new Map(), matches2 = []; - outer: while (fI > 0) { - let desc; - for (; ; ) { - if (descI) { - let next = curDesc.children[descI - 1]; - if (next instanceof MarkViewDesc) { - curDesc = next; - descI = next.children.length; - } else { - desc = next; - descI--; - break; - } - } else if (curDesc == parentDesc) { - break outer; - } else { - descI = curDesc.parent.children.indexOf(curDesc); - curDesc = curDesc.parent; - } - } - let node2 = desc.node; - if (!node2) - continue; - if (node2 != frag.child(fI - 1)) - break; - --fI; - matched.set(desc, fI); - matches2.push(desc); - } - return { index: fI, matched, matches: matches2.reverse() }; - } - function compareSide(a2, b4) { - return a2.type.side - b4.type.side; - } - function iterDeco(parent, deco, onWidget, onNode) { - let locals = deco.locals(parent), offset = 0; - if (locals.length == 0) { - for (let i2 = 0; i2 < parent.childCount; i2++) { - let child = parent.child(i2); - onNode(child, locals, deco.forChild(offset, child), i2); - offset += child.nodeSize; - } - return; - } - let decoIndex = 0, active = [], restNode = null; - for (let parentIndex = 0; ; ) { - let widget, widgets; - while (decoIndex < locals.length && locals[decoIndex].to == offset) { - let next = locals[decoIndex++]; - if (next.widget) { - if (!widget) - widget = next; - else - (widgets || (widgets = [widget])).push(next); - } - } - if (widget) { - if (widgets) { - widgets.sort(compareSide); - for (let i2 = 0; i2 < widgets.length; i2++) - onWidget(widgets[i2], parentIndex, !!restNode); - } else { - onWidget(widget, parentIndex, !!restNode); - } - } - let child, index2; - if (restNode) { - index2 = -1; - child = restNode; - restNode = null; - } else if (parentIndex < parent.childCount) { - index2 = parentIndex; - child = parent.child(parentIndex++); - } else { - break; - } - for (let i2 = 0; i2 < active.length; i2++) - if (active[i2].to <= offset) - active.splice(i2--, 1); - while (decoIndex < locals.length && locals[decoIndex].from <= offset && locals[decoIndex].to > offset) - active.push(locals[decoIndex++]); - let end = offset + child.nodeSize; - if (child.isText) { - let cutAt = end; - if (decoIndex < locals.length && locals[decoIndex].from < cutAt) - cutAt = locals[decoIndex].from; - for (let i2 = 0; i2 < active.length; i2++) - if (active[i2].to < cutAt) - cutAt = active[i2].to; - if (cutAt < end) { - restNode = child.cut(cutAt - offset); - child = child.cut(0, cutAt - offset); - end = cutAt; - index2 = -1; - } - } else { - while (decoIndex < locals.length && locals[decoIndex].to < end) - decoIndex++; - } - let outerDeco = child.isInline && !child.isLeaf ? active.filter((d6) => !d6.inline) : active.slice(); - onNode(child, outerDeco, deco.forChild(offset, child), index2); - offset = end; - } - } - function iosHacks(dom) { - if (dom.nodeName == "UL" || dom.nodeName == "OL") { - let oldCSS = dom.style.cssText; - dom.style.cssText = oldCSS + "; list-style: square !important"; - window.getComputedStyle(dom).listStyle; - dom.style.cssText = oldCSS; - } - } - function findTextInFragment(frag, text5, from, to) { - for (let i2 = 0, pos = 0; i2 < frag.childCount && pos <= to; ) { - let child = frag.child(i2++), childStart = pos; - pos += child.nodeSize; - if (!child.isText) - continue; - let str = child.text; - while (i2 < frag.childCount) { - let next = frag.child(i2++); - pos += next.nodeSize; - if (!next.isText) - break; - str += next.text; - } - if (pos >= from) { - if (pos >= to && str.slice(to - text5.length - childStart, to - childStart) == text5) - return to - text5.length; - let found2 = childStart < to ? str.lastIndexOf(text5, to - childStart - 1) : -1; - if (found2 >= 0 && found2 + text5.length + childStart >= from) - return childStart + found2; - if (from == to && str.length >= to + text5.length - childStart && str.slice(to - childStart, to - childStart + text5.length) == text5) - return to; - } - } - return -1; - } - function replaceNodes(nodes, from, to, view, replacement) { - let result = []; - for (let i2 = 0, off = 0; i2 < nodes.length; i2++) { - let child = nodes[i2], start = off, end = off += child.size; - if (start >= to || end <= from) { - result.push(child); - } else { - if (start < from) - result.push(child.slice(0, from - start, view)); - if (replacement) { - result.push(replacement); - replacement = void 0; - } - if (end > to) - result.push(child.slice(to - start, child.size, view)); - } - } - return result; - } - function selectionFromDOM(view, origin = null) { - let domSel = view.domSelectionRange(), doc4 = view.state.doc; - if (!domSel.focusNode) - return null; - let nearestDesc = view.docView.nearestDesc(domSel.focusNode), inWidget = nearestDesc && nearestDesc.size == 0; - let head = view.docView.posFromDOM(domSel.focusNode, domSel.focusOffset, 1); - if (head < 0) - return null; - let $head = doc4.resolve(head), $anchor, selection; - if (selectionCollapsed(domSel)) { - $anchor = $head; - while (nearestDesc && !nearestDesc.node) - nearestDesc = nearestDesc.parent; - let nearestDescNode = nearestDesc.node; - if (nearestDesc && nearestDescNode.isAtom && NodeSelection.isSelectable(nearestDescNode) && nearestDesc.parent && !(nearestDescNode.isInline && isOnEdge(domSel.focusNode, domSel.focusOffset, nearestDesc.dom))) { - let pos = nearestDesc.posBefore; - selection = new NodeSelection(head == pos ? $head : doc4.resolve(pos)); - } - } else { - let anchor = view.docView.posFromDOM(domSel.anchorNode, domSel.anchorOffset, 1); - if (anchor < 0) - return null; - $anchor = doc4.resolve(anchor); - } - if (!selection) { - let bias = origin == "pointer" || view.state.selection.head < $head.pos && !inWidget ? 1 : -1; - selection = selectionBetween(view, $anchor, $head, bias); - } - return selection; - } - function editorOwnsSelection(view) { - return view.editable ? view.hasFocus() : hasSelection(view) && document.activeElement && document.activeElement.contains(view.dom); - } - function selectionToDOM(view, force = false) { - let sel = view.state.selection; - syncNodeSelection(view, sel); - if (!editorOwnsSelection(view)) - return; - if (!force && view.input.mouseDown && view.input.mouseDown.allowDefault && chrome) { - let domSel = view.domSelectionRange(), curSel = view.domObserver.currentSelection; - if (domSel.anchorNode && curSel.anchorNode && isEquivalentPosition(domSel.anchorNode, domSel.anchorOffset, curSel.anchorNode, curSel.anchorOffset)) { - view.input.mouseDown.delayedSelectionSync = true; - view.domObserver.setCurSelection(); - return; - } - } - view.domObserver.disconnectSelection(); - if (view.cursorWrapper) { - selectCursorWrapper(view); - } else { - let { anchor, head } = sel, resetEditableFrom, resetEditableTo; - if (brokenSelectBetweenUneditable && !(sel instanceof TextSelection)) { - if (!sel.$from.parent.inlineContent) - resetEditableFrom = temporarilyEditableNear(view, sel.from); - if (!sel.empty && !sel.$from.parent.inlineContent) - resetEditableTo = temporarilyEditableNear(view, sel.to); - } - view.docView.setSelection(anchor, head, view.root, force); - if (brokenSelectBetweenUneditable) { - if (resetEditableFrom) - resetEditable(resetEditableFrom); - if (resetEditableTo) - resetEditable(resetEditableTo); - } - if (sel.visible) { - view.dom.classList.remove("ProseMirror-hideselection"); - } else { - view.dom.classList.add("ProseMirror-hideselection"); - if ("onselectionchange" in document) - removeClassOnSelectionChange(view); - } - } - view.domObserver.setCurSelection(); - view.domObserver.connectSelection(); - } - var brokenSelectBetweenUneditable = safari || chrome && chrome_version < 63; - function temporarilyEditableNear(view, pos) { - let { node: node2, offset } = view.docView.domFromPos(pos, 0); - let after = offset < node2.childNodes.length ? node2.childNodes[offset] : null; - let before = offset ? node2.childNodes[offset - 1] : null; - if (safari && after && after.contentEditable == "false") - return setEditable(after); - if ((!after || after.contentEditable == "false") && (!before || before.contentEditable == "false")) { - if (after) - return setEditable(after); - else if (before) - return setEditable(before); - } - } - function setEditable(element2) { - element2.contentEditable = "true"; - if (safari && element2.draggable) { - element2.draggable = false; - element2.wasDraggable = true; - } - return element2; - } - function resetEditable(element2) { - element2.contentEditable = "false"; - if (element2.wasDraggable) { - element2.draggable = true; - element2.wasDraggable = null; - } - } - function removeClassOnSelectionChange(view) { - let doc4 = view.dom.ownerDocument; - doc4.removeEventListener("selectionchange", view.input.hideSelectionGuard); - let domSel = view.domSelectionRange(); - let node2 = domSel.anchorNode, offset = domSel.anchorOffset; - doc4.addEventListener("selectionchange", view.input.hideSelectionGuard = () => { - if (domSel.anchorNode != node2 || domSel.anchorOffset != offset) { - doc4.removeEventListener("selectionchange", view.input.hideSelectionGuard); - setTimeout(() => { - if (!editorOwnsSelection(view) || view.state.selection.visible) - view.dom.classList.remove("ProseMirror-hideselection"); - }, 20); - } - }); - } - function selectCursorWrapper(view) { - let domSel = view.domSelection(), range = document.createRange(); - let node2 = view.cursorWrapper.dom, img = node2.nodeName == "IMG"; - if (img) - range.setEnd(node2.parentNode, domIndex(node2) + 1); - else - range.setEnd(node2, 0); - range.collapse(false); - domSel.removeAllRanges(); - domSel.addRange(range); - if (!img && !view.state.selection.visible && ie && ie_version <= 11) { - node2.disabled = true; - node2.disabled = false; - } - } - function syncNodeSelection(view, sel) { - if (sel instanceof NodeSelection) { - let desc = view.docView.descAt(sel.from); - if (desc != view.lastSelectedViewDesc) { - clearNodeSelection(view); - if (desc) - desc.selectNode(); - view.lastSelectedViewDesc = desc; - } - } else { - clearNodeSelection(view); - } - } - function clearNodeSelection(view) { - if (view.lastSelectedViewDesc) { - if (view.lastSelectedViewDesc.parent) - view.lastSelectedViewDesc.deselectNode(); - view.lastSelectedViewDesc = void 0; - } - } - function selectionBetween(view, $anchor, $head, bias) { - return view.someProp("createSelectionBetween", (f3) => f3(view, $anchor, $head)) || TextSelection.between($anchor, $head, bias); - } - function hasFocusAndSelection(view) { - if (view.editable && !view.hasFocus()) - return false; - return hasSelection(view); - } - function hasSelection(view) { - let sel = view.domSelectionRange(); - if (!sel.anchorNode) - return false; - try { - return view.dom.contains(sel.anchorNode.nodeType == 3 ? sel.anchorNode.parentNode : sel.anchorNode) && (view.editable || view.dom.contains(sel.focusNode.nodeType == 3 ? sel.focusNode.parentNode : sel.focusNode)); - } catch (_3) { - return false; - } - } - function anchorInRightPlace(view) { - let anchorDOM = view.docView.domFromPos(view.state.selection.anchor, 0); - let domSel = view.domSelectionRange(); - return isEquivalentPosition(anchorDOM.node, anchorDOM.offset, domSel.anchorNode, domSel.anchorOffset); - } - function moveSelectionBlock(state, dir) { - let { $anchor, $head } = state.selection; - let $side = dir > 0 ? $anchor.max($head) : $anchor.min($head); - let $start = !$side.parent.inlineContent ? $side : $side.depth ? state.doc.resolve(dir > 0 ? $side.after() : $side.before()) : null; - return $start && Selection.findFrom($start, dir); - } - function apply(view, sel) { - view.dispatch(view.state.tr.setSelection(sel).scrollIntoView()); - return true; - } - function selectHorizontally(view, dir, mods) { - let sel = view.state.selection; - if (sel instanceof TextSelection) { - if (mods.indexOf("s") > -1) { - let { $head } = sel, node2 = $head.textOffset ? null : dir < 0 ? $head.nodeBefore : $head.nodeAfter; - if (!node2 || node2.isText || !node2.isLeaf) - return false; - let $newHead = view.state.doc.resolve($head.pos + node2.nodeSize * (dir < 0 ? -1 : 1)); - return apply(view, new TextSelection(sel.$anchor, $newHead)); - } else if (!sel.empty) { - return false; - } else if (view.endOfTextblock(dir > 0 ? "forward" : "backward")) { - let next = moveSelectionBlock(view.state, dir); - if (next && next instanceof NodeSelection) - return apply(view, next); - return false; - } else if (!(mac && mods.indexOf("m") > -1)) { - let $head = sel.$head, node2 = $head.textOffset ? null : dir < 0 ? $head.nodeBefore : $head.nodeAfter, desc; - if (!node2 || node2.isText) - return false; - let nodePos = dir < 0 ? $head.pos - node2.nodeSize : $head.pos; - if (!(node2.isAtom || (desc = view.docView.descAt(nodePos)) && !desc.contentDOM)) - return false; - if (NodeSelection.isSelectable(node2)) { - return apply(view, new NodeSelection(dir < 0 ? view.state.doc.resolve($head.pos - node2.nodeSize) : $head)); - } else if (webkit) { - return apply(view, new TextSelection(view.state.doc.resolve(dir < 0 ? nodePos : nodePos + node2.nodeSize))); - } else { - return false; - } - } - } else if (sel instanceof NodeSelection && sel.node.isInline) { - return apply(view, new TextSelection(dir > 0 ? sel.$to : sel.$from)); - } else { - let next = moveSelectionBlock(view.state, dir); - if (next) - return apply(view, next); - return false; - } - } - function nodeLen(node2) { - return node2.nodeType == 3 ? node2.nodeValue.length : node2.childNodes.length; - } - function isIgnorable(dom, dir) { - let desc = dom.pmViewDesc; - return desc && desc.size == 0 && (dir < 0 || dom.nextSibling || dom.nodeName != "BR"); - } - function skipIgnoredNodes(view, dir) { - return dir < 0 ? skipIgnoredNodesBefore(view) : skipIgnoredNodesAfter(view); - } - function skipIgnoredNodesBefore(view) { - let sel = view.domSelectionRange(); - let node2 = sel.focusNode, offset = sel.focusOffset; - if (!node2) - return; - let moveNode, moveOffset, force = false; - if (gecko && node2.nodeType == 1 && offset < nodeLen(node2) && isIgnorable(node2.childNodes[offset], -1)) - force = true; - for (; ; ) { - if (offset > 0) { - if (node2.nodeType != 1) { - break; - } else { - let before = node2.childNodes[offset - 1]; - if (isIgnorable(before, -1)) { - moveNode = node2; - moveOffset = --offset; - } else if (before.nodeType == 3) { - node2 = before; - offset = node2.nodeValue.length; - } else - break; - } - } else if (isBlockNode(node2)) { - break; - } else { - let prev = node2.previousSibling; - while (prev && isIgnorable(prev, -1)) { - moveNode = node2.parentNode; - moveOffset = domIndex(prev); - prev = prev.previousSibling; - } - if (!prev) { - node2 = node2.parentNode; - if (node2 == view.dom) - break; - offset = 0; - } else { - node2 = prev; - offset = nodeLen(node2); - } - } - } - if (force) - setSelFocus(view, node2, offset); - else if (moveNode) - setSelFocus(view, moveNode, moveOffset); - } - function skipIgnoredNodesAfter(view) { - let sel = view.domSelectionRange(); - let node2 = sel.focusNode, offset = sel.focusOffset; - if (!node2) - return; - let len = nodeLen(node2); - let moveNode, moveOffset; - for (; ; ) { - if (offset < len) { - if (node2.nodeType != 1) - break; - let after = node2.childNodes[offset]; - if (isIgnorable(after, 1)) { - moveNode = node2; - moveOffset = ++offset; - } else - break; - } else if (isBlockNode(node2)) { - break; - } else { - let next = node2.nextSibling; - while (next && isIgnorable(next, 1)) { - moveNode = next.parentNode; - moveOffset = domIndex(next) + 1; - next = next.nextSibling; - } - if (!next) { - node2 = node2.parentNode; - if (node2 == view.dom) - break; - offset = len = 0; - } else { - node2 = next; - offset = 0; - len = nodeLen(node2); - } - } - } - if (moveNode) - setSelFocus(view, moveNode, moveOffset); - } - function isBlockNode(dom) { - let desc = dom.pmViewDesc; - return desc && desc.node && desc.node.isBlock; - } - function textNodeAfter(node2, offset) { - while (node2 && offset == node2.childNodes.length && !hasBlockDesc(node2)) { - offset = domIndex(node2) + 1; - node2 = node2.parentNode; - } - while (node2 && offset < node2.childNodes.length) { - let next = node2.childNodes[offset]; - if (next.nodeType == 3) - return next; - if (next.nodeType == 1 && next.contentEditable == "false") - break; - node2 = next; - offset = 0; - } - } - function textNodeBefore(node2, offset) { - while (node2 && !offset && !hasBlockDesc(node2)) { - offset = domIndex(node2); - node2 = node2.parentNode; - } - while (node2 && offset) { - let next = node2.childNodes[offset - 1]; - if (next.nodeType == 3) - return next; - if (next.nodeType == 1 && next.contentEditable == "false") - break; - node2 = next; - offset = node2.childNodes.length; - } - } - function setSelFocus(view, node2, offset) { - if (node2.nodeType != 3) { - let before, after; - if (after = textNodeAfter(node2, offset)) { - node2 = after; - offset = 0; - } else if (before = textNodeBefore(node2, offset)) { - node2 = before; - offset = before.nodeValue.length; - } - } - let sel = view.domSelection(); - if (selectionCollapsed(sel)) { - let range = document.createRange(); - range.setEnd(node2, offset); - range.setStart(node2, offset); - sel.removeAllRanges(); - sel.addRange(range); - } else if (sel.extend) { - sel.extend(node2, offset); - } - view.domObserver.setCurSelection(); - let { state } = view; - setTimeout(() => { - if (view.state == state) - selectionToDOM(view); - }, 50); - } - function findDirection(view, pos) { - let $pos = view.state.doc.resolve(pos); - if (!(chrome || windows) && $pos.parent.inlineContent) { - let coords = view.coordsAtPos(pos); - if (pos > $pos.start()) { - let before = view.coordsAtPos(pos - 1); - let mid = (before.top + before.bottom) / 2; - if (mid > coords.top && mid < coords.bottom && Math.abs(before.left - coords.left) > 1) - return before.left < coords.left ? "ltr" : "rtl"; - } - if (pos < $pos.end()) { - let after = view.coordsAtPos(pos + 1); - let mid = (after.top + after.bottom) / 2; - if (mid > coords.top && mid < coords.bottom && Math.abs(after.left - coords.left) > 1) - return after.left > coords.left ? "ltr" : "rtl"; - } - } - let computed = getComputedStyle(view.dom).direction; - return computed == "rtl" ? "rtl" : "ltr"; - } - function selectVertically(view, dir, mods) { - let sel = view.state.selection; - if (sel instanceof TextSelection && !sel.empty || mods.indexOf("s") > -1) - return false; - if (mac && mods.indexOf("m") > -1) - return false; - let { $from, $to } = sel; - if (!$from.parent.inlineContent || view.endOfTextblock(dir < 0 ? "up" : "down")) { - let next = moveSelectionBlock(view.state, dir); - if (next && next instanceof NodeSelection) - return apply(view, next); - } - if (!$from.parent.inlineContent) { - let side = dir < 0 ? $from : $to; - let beyond = sel instanceof AllSelection ? Selection.near(side, dir) : Selection.findFrom(side, dir); - return beyond ? apply(view, beyond) : false; - } - return false; - } - function stopNativeHorizontalDelete(view, dir) { - if (!(view.state.selection instanceof TextSelection)) - return true; - let { $head, $anchor, empty: empty3 } = view.state.selection; - if (!$head.sameParent($anchor)) - return true; - if (!empty3) - return false; - if (view.endOfTextblock(dir > 0 ? "forward" : "backward")) - return true; - let nextNode = !$head.textOffset && (dir < 0 ? $head.nodeBefore : $head.nodeAfter); - if (nextNode && !nextNode.isText) { - let tr = view.state.tr; - if (dir < 0) - tr.delete($head.pos - nextNode.nodeSize, $head.pos); - else - tr.delete($head.pos, $head.pos + nextNode.nodeSize); - view.dispatch(tr); - return true; - } - return false; - } - function switchEditable(view, node2, state) { - view.domObserver.stop(); - node2.contentEditable = state; - view.domObserver.start(); - } - function safariDownArrowBug(view) { - if (!safari || view.state.selection.$head.parentOffset > 0) - return false; - let { focusNode, focusOffset } = view.domSelectionRange(); - if (focusNode && focusNode.nodeType == 1 && focusOffset == 0 && focusNode.firstChild && focusNode.firstChild.contentEditable == "false") { - let child = focusNode.firstChild; - switchEditable(view, child, "true"); - setTimeout(() => switchEditable(view, child, "false"), 20); - } - return false; - } - function getMods(event) { - let result = ""; - if (event.ctrlKey) - result += "c"; - if (event.metaKey) - result += "m"; - if (event.altKey) - result += "a"; - if (event.shiftKey) - result += "s"; - return result; - } - function captureKeyDown(view, event) { - let code3 = event.keyCode, mods = getMods(event); - if (code3 == 8 || mac && code3 == 72 && mods == "c") { - return stopNativeHorizontalDelete(view, -1) || skipIgnoredNodes(view, -1); - } else if (code3 == 46 && !event.shiftKey || mac && code3 == 68 && mods == "c") { - return stopNativeHorizontalDelete(view, 1) || skipIgnoredNodes(view, 1); - } else if (code3 == 13 || code3 == 27) { - return true; - } else if (code3 == 37 || mac && code3 == 66 && mods == "c") { - let dir = code3 == 37 ? findDirection(view, view.state.selection.from) == "ltr" ? -1 : 1 : -1; - return selectHorizontally(view, dir, mods) || skipIgnoredNodes(view, dir); - } else if (code3 == 39 || mac && code3 == 70 && mods == "c") { - let dir = code3 == 39 ? findDirection(view, view.state.selection.from) == "ltr" ? 1 : -1 : 1; - return selectHorizontally(view, dir, mods) || skipIgnoredNodes(view, dir); - } else if (code3 == 38 || mac && code3 == 80 && mods == "c") { - return selectVertically(view, -1, mods) || skipIgnoredNodes(view, -1); - } else if (code3 == 40 || mac && code3 == 78 && mods == "c") { - return safariDownArrowBug(view) || selectVertically(view, 1, mods) || skipIgnoredNodes(view, 1); - } else if (mods == (mac ? "m" : "c") && (code3 == 66 || code3 == 73 || code3 == 89 || code3 == 90)) { - return true; - } - return false; - } - function serializeForClipboard(view, slice) { - view.someProp("transformCopied", (f3) => { - slice = f3(slice, view); - }); - let context = [], { content: content3, openStart, openEnd } = slice; - while (openStart > 1 && openEnd > 1 && content3.childCount == 1 && content3.firstChild.childCount == 1) { - openStart--; - openEnd--; - let node2 = content3.firstChild; - context.push(node2.type.name, node2.attrs != node2.type.defaultAttrs ? node2.attrs : null); - content3 = node2.content; - } - let serializer = view.someProp("clipboardSerializer") || DOMSerializer.fromSchema(view.state.schema); - let doc4 = detachedDoc(), wrap3 = doc4.createElement("div"); - wrap3.appendChild(serializer.serializeFragment(content3, { document: doc4 })); - let firstChild = wrap3.firstChild, needsWrap, wrappers = 0; - while (firstChild && firstChild.nodeType == 1 && (needsWrap = wrapMap[firstChild.nodeName.toLowerCase()])) { - for (let i2 = needsWrap.length - 1; i2 >= 0; i2--) { - let wrapper = doc4.createElement(needsWrap[i2]); - while (wrap3.firstChild) - wrapper.appendChild(wrap3.firstChild); - wrap3.appendChild(wrapper); - wrappers++; - } - firstChild = wrap3.firstChild; - } - if (firstChild && firstChild.nodeType == 1) - firstChild.setAttribute("data-pm-slice", `${openStart} ${openEnd}${wrappers ? ` -${wrappers}` : ""} ${JSON.stringify(context)}`); - let text5 = view.someProp("clipboardTextSerializer", (f3) => f3(slice, view)) || slice.content.textBetween(0, slice.content.size, "\n\n"); - return { dom: wrap3, text: text5, slice }; - } - function parseFromClipboard(view, text5, html3, plainText, $context) { - let inCode = $context.parent.type.spec.code; - let dom, slice; - if (!html3 && !text5) - return null; - let asText = text5 && (plainText || inCode || !html3); - if (asText) { - view.someProp("transformPastedText", (f3) => { - text5 = f3(text5, inCode || plainText, view); - }); - if (inCode) - return text5 ? new Slice(Fragment.from(view.state.schema.text(text5.replace(/\r\n?/g, "\n"))), 0, 0) : Slice.empty; - let parsed = view.someProp("clipboardTextParser", (f3) => f3(text5, $context, plainText, view)); - if (parsed) { - slice = parsed; - } else { - let marks = $context.marks(); - let { schema } = view.state, serializer = DOMSerializer.fromSchema(schema); - dom = document.createElement("div"); - text5.split(/(?:\r\n?|\n)+/).forEach((block) => { - let p4 = dom.appendChild(document.createElement("p")); - if (block) - p4.appendChild(serializer.serializeNode(schema.text(block, marks))); - }); - } - } else { - view.someProp("transformPastedHTML", (f3) => { - html3 = f3(html3, view); - }); - dom = readHTML(html3); - if (webkit) - restoreReplacedSpaces(dom); - } - let contextNode = dom && dom.querySelector("[data-pm-slice]"); - let sliceData = contextNode && /^(\d+) (\d+)(?: -(\d+))? (.*)/.exec(contextNode.getAttribute("data-pm-slice") || ""); - if (sliceData && sliceData[3]) - for (let i2 = +sliceData[3]; i2 > 0; i2--) { - let child = dom.firstChild; - while (child && child.nodeType != 1) - child = child.nextSibling; - if (!child) - break; - dom = child; - } - if (!slice) { - let parser = view.someProp("clipboardParser") || view.someProp("domParser") || DOMParser.fromSchema(view.state.schema); - slice = parser.parseSlice(dom, { - preserveWhitespace: !!(asText || sliceData), - context: $context, - ruleFromNode(dom2) { - if (dom2.nodeName == "BR" && !dom2.nextSibling && dom2.parentNode && !inlineParents.test(dom2.parentNode.nodeName)) - return { ignore: true }; - return null; - } - }); - } - if (sliceData) { - slice = addContext(closeSlice(slice, +sliceData[1], +sliceData[2]), sliceData[4]); - } else { - slice = Slice.maxOpen(normalizeSiblings(slice.content, $context), true); - if (slice.openStart || slice.openEnd) { - let openStart = 0, openEnd = 0; - for (let node2 = slice.content.firstChild; openStart < slice.openStart && !node2.type.spec.isolating; openStart++, node2 = node2.firstChild) { - } - for (let node2 = slice.content.lastChild; openEnd < slice.openEnd && !node2.type.spec.isolating; openEnd++, node2 = node2.lastChild) { - } - slice = closeSlice(slice, openStart, openEnd); - } - } - view.someProp("transformPasted", (f3) => { - slice = f3(slice, view); - }); - return slice; - } - var inlineParents = /^(a|abbr|acronym|b|cite|code|del|em|i|ins|kbd|label|output|q|ruby|s|samp|span|strong|sub|sup|time|u|tt|var)$/i; - function normalizeSiblings(fragment, $context) { - if (fragment.childCount < 2) - return fragment; - for (let d6 = $context.depth; d6 >= 0; d6--) { - let parent = $context.node(d6); - let match = parent.contentMatchAt($context.index(d6)); - let lastWrap, result = []; - fragment.forEach((node2) => { - if (!result) - return; - let wrap3 = match.findWrapping(node2.type), inLast; - if (!wrap3) - return result = null; - if (inLast = result.length && lastWrap.length && addToSibling(wrap3, lastWrap, node2, result[result.length - 1], 0)) { - result[result.length - 1] = inLast; - } else { - if (result.length) - result[result.length - 1] = closeRight(result[result.length - 1], lastWrap.length); - let wrapped = withWrappers(node2, wrap3); - result.push(wrapped); - match = match.matchType(wrapped.type); - lastWrap = wrap3; - } - }); - if (result) - return Fragment.from(result); - } - return fragment; - } - function withWrappers(node2, wrap3, from = 0) { - for (let i2 = wrap3.length - 1; i2 >= from; i2--) - node2 = wrap3[i2].create(null, Fragment.from(node2)); - return node2; - } - function addToSibling(wrap3, lastWrap, node2, sibling, depth) { - if (depth < wrap3.length && depth < lastWrap.length && wrap3[depth] == lastWrap[depth]) { - let inner = addToSibling(wrap3, lastWrap, node2, sibling.lastChild, depth + 1); - if (inner) - return sibling.copy(sibling.content.replaceChild(sibling.childCount - 1, inner)); - let match = sibling.contentMatchAt(sibling.childCount); - if (match.matchType(depth == wrap3.length - 1 ? node2.type : wrap3[depth + 1])) - return sibling.copy(sibling.content.append(Fragment.from(withWrappers(node2, wrap3, depth + 1)))); - } - } - function closeRight(node2, depth) { - if (depth == 0) - return node2; - let fragment = node2.content.replaceChild(node2.childCount - 1, closeRight(node2.lastChild, depth - 1)); - let fill = node2.contentMatchAt(node2.childCount).fillBefore(Fragment.empty, true); - return node2.copy(fragment.append(fill)); - } - function closeRange(fragment, side, from, to, depth, openEnd) { - let node2 = side < 0 ? fragment.firstChild : fragment.lastChild, inner = node2.content; - if (fragment.childCount > 1) - openEnd = 0; - if (depth < to - 1) - inner = closeRange(inner, side, from, to, depth + 1, openEnd); - if (depth >= from) - inner = side < 0 ? node2.contentMatchAt(0).fillBefore(inner, openEnd <= depth).append(inner) : inner.append(node2.contentMatchAt(node2.childCount).fillBefore(Fragment.empty, true)); - return fragment.replaceChild(side < 0 ? 0 : fragment.childCount - 1, node2.copy(inner)); - } - function closeSlice(slice, openStart, openEnd) { - if (openStart < slice.openStart) - slice = new Slice(closeRange(slice.content, -1, openStart, slice.openStart, 0, slice.openEnd), openStart, slice.openEnd); - if (openEnd < slice.openEnd) - slice = new Slice(closeRange(slice.content, 1, openEnd, slice.openEnd, 0, 0), slice.openStart, openEnd); - return slice; - } - var wrapMap = { - thead: ["table"], - tbody: ["table"], - tfoot: ["table"], - caption: ["table"], - colgroup: ["table"], - col: ["table", "colgroup"], - tr: ["table", "tbody"], - td: ["table", "tbody", "tr"], - th: ["table", "tbody", "tr"] - }; - var _detachedDoc = null; - function detachedDoc() { - return _detachedDoc || (_detachedDoc = document.implementation.createHTMLDocument("title")); - } - function readHTML(html3) { - let metas = /^(\s*]*>)*/.exec(html3); - if (metas) - html3 = html3.slice(metas[0].length); - let elt = detachedDoc().createElement("div"); - let firstTag = /<([a-z][^>\s]+)/i.exec(html3), wrap3; - if (wrap3 = firstTag && wrapMap[firstTag[1].toLowerCase()]) - html3 = wrap3.map((n4) => "<" + n4 + ">").join("") + html3 + wrap3.map((n4) => "").reverse().join(""); - elt.innerHTML = html3; - if (wrap3) - for (let i2 = 0; i2 < wrap3.length; i2++) - elt = elt.querySelector(wrap3[i2]) || elt; - return elt; - } - function restoreReplacedSpaces(dom) { - let nodes = dom.querySelectorAll(chrome ? "span:not([class]):not([style])" : "span.Apple-converted-space"); - for (let i2 = 0; i2 < nodes.length; i2++) { - let node2 = nodes[i2]; - if (node2.childNodes.length == 1 && node2.textContent == "\xA0" && node2.parentNode) - node2.parentNode.replaceChild(dom.ownerDocument.createTextNode(" "), node2); - } - } - function addContext(slice, context) { - if (!slice.size) - return slice; - let schema = slice.content.firstChild.type.schema, array; - try { - array = JSON.parse(context); - } catch (e2) { - return slice; - } - let { content: content3, openStart, openEnd } = slice; - for (let i2 = array.length - 2; i2 >= 0; i2 -= 2) { - let type = schema.nodes[array[i2]]; - if (!type || type.hasRequiredAttrs()) - break; - content3 = Fragment.from(type.create(array[i2 + 1], content3)); - openStart++; - openEnd++; - } - return new Slice(content3, openStart, openEnd); - } - var handlers = {}; - var editHandlers = {}; - var passiveHandlers = { touchstart: true, touchmove: true }; - var InputState = class { - constructor() { - this.shiftKey = false; - this.mouseDown = null; - this.lastKeyCode = null; - this.lastKeyCodeTime = 0; - this.lastClick = { time: 0, x: 0, y: 0, type: "" }; - this.lastSelectionOrigin = null; - this.lastSelectionTime = 0; - this.lastIOSEnter = 0; - this.lastIOSEnterFallbackTimeout = -1; - this.lastFocus = 0; - this.lastTouch = 0; - this.lastAndroidDelete = 0; - this.composing = false; - this.compositionNode = null; - this.composingTimeout = -1; - this.compositionNodes = []; - this.compositionEndedAt = -2e8; - this.compositionID = 1; - this.compositionPendingChanges = 0; - this.domChangeCount = 0; - this.eventHandlers = /* @__PURE__ */ Object.create(null); - this.hideSelectionGuard = null; - } - }; - function initInput(view) { - for (let event in handlers) { - let handler = handlers[event]; - view.dom.addEventListener(event, view.input.eventHandlers[event] = (event2) => { - if (eventBelongsToView(view, event2) && !runCustomHandler(view, event2) && (view.editable || !(event2.type in editHandlers))) - handler(view, event2); - }, passiveHandlers[event] ? { passive: true } : void 0); - } - if (safari) - view.dom.addEventListener("input", () => null); - ensureListeners(view); - } - function setSelectionOrigin(view, origin) { - view.input.lastSelectionOrigin = origin; - view.input.lastSelectionTime = Date.now(); - } - function destroyInput(view) { - view.domObserver.stop(); - for (let type in view.input.eventHandlers) - view.dom.removeEventListener(type, view.input.eventHandlers[type]); - clearTimeout(view.input.composingTimeout); - clearTimeout(view.input.lastIOSEnterFallbackTimeout); - } - function ensureListeners(view) { - view.someProp("handleDOMEvents", (currentHandlers) => { - for (let type in currentHandlers) - if (!view.input.eventHandlers[type]) - view.dom.addEventListener(type, view.input.eventHandlers[type] = (event) => runCustomHandler(view, event)); - }); - } - function runCustomHandler(view, event) { - return view.someProp("handleDOMEvents", (handlers2) => { - let handler = handlers2[event.type]; - return handler ? handler(view, event) || event.defaultPrevented : false; - }); - } - function eventBelongsToView(view, event) { - if (!event.bubbles) - return true; - if (event.defaultPrevented) - return false; - for (let node2 = event.target; node2 != view.dom; node2 = node2.parentNode) - if (!node2 || node2.nodeType == 11 || node2.pmViewDesc && node2.pmViewDesc.stopEvent(event)) - return false; - return true; - } - function dispatchEvent2(view, event) { - if (!runCustomHandler(view, event) && handlers[event.type] && (view.editable || !(event.type in editHandlers))) - handlers[event.type](view, event); - } - editHandlers.keydown = (view, _event) => { - let event = _event; - view.input.shiftKey = event.keyCode == 16 || event.shiftKey; - if (inOrNearComposition(view, event)) - return; - view.input.lastKeyCode = event.keyCode; - view.input.lastKeyCodeTime = Date.now(); - if (android && chrome && event.keyCode == 13) - return; - if (event.keyCode != 229) - view.domObserver.forceFlush(); - if (ios && event.keyCode == 13 && !event.ctrlKey && !event.altKey && !event.metaKey) { - let now = Date.now(); - view.input.lastIOSEnter = now; - view.input.lastIOSEnterFallbackTimeout = setTimeout(() => { - if (view.input.lastIOSEnter == now) { - view.someProp("handleKeyDown", (f3) => f3(view, keyEvent(13, "Enter"))); - view.input.lastIOSEnter = 0; - } - }, 200); - } else if (view.someProp("handleKeyDown", (f3) => f3(view, event)) || captureKeyDown(view, event)) { - event.preventDefault(); - } else { - setSelectionOrigin(view, "key"); - } - }; - editHandlers.keyup = (view, event) => { - if (event.keyCode == 16) - view.input.shiftKey = false; - }; - editHandlers.keypress = (view, _event) => { - let event = _event; - if (inOrNearComposition(view, event) || !event.charCode || event.ctrlKey && !event.altKey || mac && event.metaKey) - return; - if (view.someProp("handleKeyPress", (f3) => f3(view, event))) { - event.preventDefault(); - return; - } - let sel = view.state.selection; - if (!(sel instanceof TextSelection) || !sel.$from.sameParent(sel.$to)) { - let text5 = String.fromCharCode(event.charCode); - if (!/[\r\n]/.test(text5) && !view.someProp("handleTextInput", (f3) => f3(view, sel.$from.pos, sel.$to.pos, text5))) - view.dispatch(view.state.tr.insertText(text5).scrollIntoView()); - event.preventDefault(); - } - }; - function eventCoords(event) { - return { left: event.clientX, top: event.clientY }; - } - function isNear(event, click) { - let dx = click.x - event.clientX, dy = click.y - event.clientY; - return dx * dx + dy * dy < 100; - } - function runHandlerOnContext(view, propName, pos, inside, event) { - if (inside == -1) - return false; - let $pos = view.state.doc.resolve(inside); - for (let i2 = $pos.depth + 1; i2 > 0; i2--) { - if (view.someProp(propName, (f3) => i2 > $pos.depth ? f3(view, pos, $pos.nodeAfter, $pos.before(i2), event, true) : f3(view, pos, $pos.node(i2), $pos.before(i2), event, false))) - return true; - } - return false; - } - function updateSelection(view, selection, origin) { - if (!view.focused) - view.focus(); - let tr = view.state.tr.setSelection(selection); - if (origin == "pointer") - tr.setMeta("pointer", true); - view.dispatch(tr); - } - function selectClickedLeaf(view, inside) { - if (inside == -1) - return false; - let $pos = view.state.doc.resolve(inside), node2 = $pos.nodeAfter; - if (node2 && node2.isAtom && NodeSelection.isSelectable(node2)) { - updateSelection(view, new NodeSelection($pos), "pointer"); - return true; - } - return false; - } - function selectClickedNode(view, inside) { - if (inside == -1) - return false; - let sel = view.state.selection, selectedNode, selectAt; - if (sel instanceof NodeSelection) - selectedNode = sel.node; - let $pos = view.state.doc.resolve(inside); - for (let i2 = $pos.depth + 1; i2 > 0; i2--) { - let node2 = i2 > $pos.depth ? $pos.nodeAfter : $pos.node(i2); - if (NodeSelection.isSelectable(node2)) { - if (selectedNode && sel.$from.depth > 0 && i2 >= sel.$from.depth && $pos.before(sel.$from.depth + 1) == sel.$from.pos) - selectAt = $pos.before(sel.$from.depth); - else - selectAt = $pos.before(i2); - break; - } - } - if (selectAt != null) { - updateSelection(view, NodeSelection.create(view.state.doc, selectAt), "pointer"); - return true; - } else { - return false; - } - } - function handleSingleClick(view, pos, inside, event, selectNode) { - return runHandlerOnContext(view, "handleClickOn", pos, inside, event) || view.someProp("handleClick", (f3) => f3(view, pos, event)) || (selectNode ? selectClickedNode(view, inside) : selectClickedLeaf(view, inside)); - } - function handleDoubleClick(view, pos, inside, event) { - return runHandlerOnContext(view, "handleDoubleClickOn", pos, inside, event) || view.someProp("handleDoubleClick", (f3) => f3(view, pos, event)); - } - function handleTripleClick(view, pos, inside, event) { - return runHandlerOnContext(view, "handleTripleClickOn", pos, inside, event) || view.someProp("handleTripleClick", (f3) => f3(view, pos, event)) || defaultTripleClick(view, inside, event); - } - function defaultTripleClick(view, inside, event) { - if (event.button != 0) - return false; - let doc4 = view.state.doc; - if (inside == -1) { - if (doc4.inlineContent) { - updateSelection(view, TextSelection.create(doc4, 0, doc4.content.size), "pointer"); - return true; - } - return false; - } - let $pos = doc4.resolve(inside); - for (let i2 = $pos.depth + 1; i2 > 0; i2--) { - let node2 = i2 > $pos.depth ? $pos.nodeAfter : $pos.node(i2); - let nodePos = $pos.before(i2); - if (node2.inlineContent) - updateSelection(view, TextSelection.create(doc4, nodePos + 1, nodePos + 1 + node2.content.size), "pointer"); - else if (NodeSelection.isSelectable(node2)) - updateSelection(view, NodeSelection.create(doc4, nodePos), "pointer"); - else - continue; - return true; - } - } - function forceDOMFlush(view) { - return endComposition(view); - } - var selectNodeModifier = mac ? "metaKey" : "ctrlKey"; - handlers.mousedown = (view, _event) => { - let event = _event; - view.input.shiftKey = event.shiftKey; - let flushed = forceDOMFlush(view); - let now = Date.now(), type = "singleClick"; - if (now - view.input.lastClick.time < 500 && isNear(event, view.input.lastClick) && !event[selectNodeModifier]) { - if (view.input.lastClick.type == "singleClick") - type = "doubleClick"; - else if (view.input.lastClick.type == "doubleClick") - type = "tripleClick"; - } - view.input.lastClick = { time: now, x: event.clientX, y: event.clientY, type }; - let pos = view.posAtCoords(eventCoords(event)); - if (!pos) - return; - if (type == "singleClick") { - if (view.input.mouseDown) - view.input.mouseDown.done(); - view.input.mouseDown = new MouseDown(view, pos, event, !!flushed); - } else if ((type == "doubleClick" ? handleDoubleClick : handleTripleClick)(view, pos.pos, pos.inside, event)) { - event.preventDefault(); - } else { - setSelectionOrigin(view, "pointer"); - } - }; - var MouseDown = class { - constructor(view, pos, event, flushed) { - this.view = view; - this.pos = pos; - this.event = event; - this.flushed = flushed; - this.delayedSelectionSync = false; - this.mightDrag = null; - this.startDoc = view.state.doc; - this.selectNode = !!event[selectNodeModifier]; - this.allowDefault = event.shiftKey; - let targetNode, targetPos; - if (pos.inside > -1) { - targetNode = view.state.doc.nodeAt(pos.inside); - targetPos = pos.inside; - } else { - let $pos = view.state.doc.resolve(pos.pos); - targetNode = $pos.parent; - targetPos = $pos.depth ? $pos.before() : 0; - } - const target = flushed ? null : event.target; - const targetDesc = target ? view.docView.nearestDesc(target, true) : null; - this.target = targetDesc ? targetDesc.dom : null; - let { selection } = view.state; - if (event.button == 0 && targetNode.type.spec.draggable && targetNode.type.spec.selectable !== false || selection instanceof NodeSelection && selection.from <= targetPos && selection.to > targetPos) - this.mightDrag = { - node: targetNode, - pos: targetPos, - addAttr: !!(this.target && !this.target.draggable), - setUneditable: !!(this.target && gecko && !this.target.hasAttribute("contentEditable")) - }; - if (this.target && this.mightDrag && (this.mightDrag.addAttr || this.mightDrag.setUneditable)) { - this.view.domObserver.stop(); - if (this.mightDrag.addAttr) - this.target.draggable = true; - if (this.mightDrag.setUneditable) - setTimeout(() => { - if (this.view.input.mouseDown == this) - this.target.setAttribute("contentEditable", "false"); - }, 20); - this.view.domObserver.start(); - } - view.root.addEventListener("mouseup", this.up = this.up.bind(this)); - view.root.addEventListener("mousemove", this.move = this.move.bind(this)); - setSelectionOrigin(view, "pointer"); - } - done() { - this.view.root.removeEventListener("mouseup", this.up); - this.view.root.removeEventListener("mousemove", this.move); - if (this.mightDrag && this.target) { - this.view.domObserver.stop(); - if (this.mightDrag.addAttr) - this.target.removeAttribute("draggable"); - if (this.mightDrag.setUneditable) - this.target.removeAttribute("contentEditable"); - this.view.domObserver.start(); - } - if (this.delayedSelectionSync) - setTimeout(() => selectionToDOM(this.view)); - this.view.input.mouseDown = null; - } - up(event) { - this.done(); - if (!this.view.dom.contains(event.target)) - return; - let pos = this.pos; - if (this.view.state.doc != this.startDoc) - pos = this.view.posAtCoords(eventCoords(event)); - this.updateAllowDefault(event); - if (this.allowDefault || !pos) { - setSelectionOrigin(this.view, "pointer"); - } else if (handleSingleClick(this.view, pos.pos, pos.inside, event, this.selectNode)) { - event.preventDefault(); - } else if (event.button == 0 && (this.flushed || // Safari ignores clicks on draggable elements - safari && this.mightDrag && !this.mightDrag.node.isAtom || // Chrome will sometimes treat a node selection as a - // cursor, but still report that the node is selected - // when asked through getSelection. You'll then get a - // situation where clicking at the point where that - // (hidden) cursor is doesn't change the selection, and - // thus doesn't get a reaction from ProseMirror. This - // works around that. - chrome && !this.view.state.selection.visible && Math.min(Math.abs(pos.pos - this.view.state.selection.from), Math.abs(pos.pos - this.view.state.selection.to)) <= 2)) { - updateSelection(this.view, Selection.near(this.view.state.doc.resolve(pos.pos)), "pointer"); - event.preventDefault(); - } else { - setSelectionOrigin(this.view, "pointer"); - } - } - move(event) { - this.updateAllowDefault(event); - setSelectionOrigin(this.view, "pointer"); - if (event.buttons == 0) - this.done(); - } - updateAllowDefault(event) { - if (!this.allowDefault && (Math.abs(this.event.x - event.clientX) > 4 || Math.abs(this.event.y - event.clientY) > 4)) - this.allowDefault = true; - } - }; - handlers.touchstart = (view) => { - view.input.lastTouch = Date.now(); - forceDOMFlush(view); - setSelectionOrigin(view, "pointer"); - }; - handlers.touchmove = (view) => { - view.input.lastTouch = Date.now(); - setSelectionOrigin(view, "pointer"); - }; - handlers.contextmenu = (view) => forceDOMFlush(view); - function inOrNearComposition(view, event) { - if (view.composing) - return true; - if (safari && Math.abs(event.timeStamp - view.input.compositionEndedAt) < 500) { - view.input.compositionEndedAt = -2e8; - return true; - } - return false; - } - var timeoutComposition = android ? 5e3 : -1; - editHandlers.compositionstart = editHandlers.compositionupdate = (view) => { - if (!view.composing) { - view.domObserver.flush(); - let { state } = view, $pos = state.selection.$from; - if (state.selection.empty && (state.storedMarks || !$pos.textOffset && $pos.parentOffset && $pos.nodeBefore.marks.some((m3) => m3.type.spec.inclusive === false))) { - view.markCursor = view.state.storedMarks || $pos.marks(); - endComposition(view, true); - view.markCursor = null; - } else { - endComposition(view); - if (gecko && state.selection.empty && $pos.parentOffset && !$pos.textOffset && $pos.nodeBefore.marks.length) { - let sel = view.domSelectionRange(); - for (let node2 = sel.focusNode, offset = sel.focusOffset; node2 && node2.nodeType == 1 && offset != 0; ) { - let before = offset < 0 ? node2.lastChild : node2.childNodes[offset - 1]; - if (!before) - break; - if (before.nodeType == 3) { - view.domSelection().collapse(before, before.nodeValue.length); - break; - } else { - node2 = before; - offset = -1; - } - } - } - } - view.input.composing = true; - } - scheduleComposeEnd(view, timeoutComposition); - }; - editHandlers.compositionend = (view, event) => { - if (view.composing) { - view.input.composing = false; - view.input.compositionEndedAt = event.timeStamp; - view.input.compositionPendingChanges = view.domObserver.pendingRecords().length ? view.input.compositionID : 0; - view.input.compositionNode = null; - if (view.input.compositionPendingChanges) - Promise.resolve().then(() => view.domObserver.flush()); - view.input.compositionID++; - scheduleComposeEnd(view, 20); - } - }; - function scheduleComposeEnd(view, delay) { - clearTimeout(view.input.composingTimeout); - if (delay > -1) - view.input.composingTimeout = setTimeout(() => endComposition(view), delay); - } - function clearComposition(view) { - if (view.composing) { - view.input.composing = false; - view.input.compositionEndedAt = timestampFromCustomEvent(); - } - while (view.input.compositionNodes.length > 0) - view.input.compositionNodes.pop().markParentsDirty(); - } - function findCompositionNode(view) { - let sel = view.domSelectionRange(); - if (!sel.focusNode) - return null; - let textBefore = textNodeBefore$1(sel.focusNode, sel.focusOffset); - let textAfter = textNodeAfter$1(sel.focusNode, sel.focusOffset); - if (textBefore && textAfter && textBefore != textAfter) { - let descAfter = textAfter.pmViewDesc; - if (!descAfter || !descAfter.isText(textAfter.nodeValue)) { - return textAfter; - } else if (view.input.compositionNode == textAfter) { - let descBefore = textBefore.pmViewDesc; - if (!(!descBefore || !descBefore.isText(textBefore.nodeValue))) - return textAfter; - } - } - return textBefore || textAfter; - } - function timestampFromCustomEvent() { - let event = document.createEvent("Event"); - event.initEvent("event", true, true); - return event.timeStamp; - } - function endComposition(view, forceUpdate = false) { - if (android && view.domObserver.flushingSoon >= 0) - return; - view.domObserver.forceFlush(); - clearComposition(view); - if (forceUpdate || view.docView && view.docView.dirty) { - let sel = selectionFromDOM(view); - if (sel && !sel.eq(view.state.selection)) - view.dispatch(view.state.tr.setSelection(sel)); - else - view.updateState(view.state); - return true; - } - return false; - } - function captureCopy(view, dom) { - if (!view.dom.parentNode) - return; - let wrap3 = view.dom.parentNode.appendChild(document.createElement("div")); - wrap3.appendChild(dom); - wrap3.style.cssText = "position: fixed; left: -10000px; top: 10px"; - let sel = getSelection(), range = document.createRange(); - range.selectNodeContents(dom); - view.dom.blur(); - sel.removeAllRanges(); - sel.addRange(range); - setTimeout(() => { - if (wrap3.parentNode) - wrap3.parentNode.removeChild(wrap3); - view.focus(); - }, 50); - } - var brokenClipboardAPI = ie && ie_version < 15 || ios && webkit_version < 604; - handlers.copy = editHandlers.cut = (view, _event) => { - let event = _event; - let sel = view.state.selection, cut = event.type == "cut"; - if (sel.empty) - return; - let data = brokenClipboardAPI ? null : event.clipboardData; - let slice = sel.content(), { dom, text: text5 } = serializeForClipboard(view, slice); - if (data) { - event.preventDefault(); - data.clearData(); - data.setData("text/html", dom.innerHTML); - data.setData("text/plain", text5); - } else { - captureCopy(view, dom); - } - if (cut) - view.dispatch(view.state.tr.deleteSelection().scrollIntoView().setMeta("uiEvent", "cut")); - }; - function sliceSingleNode(slice) { - return slice.openStart == 0 && slice.openEnd == 0 && slice.content.childCount == 1 ? slice.content.firstChild : null; - } - function capturePaste(view, event) { - if (!view.dom.parentNode) - return; - let plainText = view.input.shiftKey || view.state.selection.$from.parent.type.spec.code; - let target = view.dom.parentNode.appendChild(document.createElement(plainText ? "textarea" : "div")); - if (!plainText) - target.contentEditable = "true"; - target.style.cssText = "position: fixed; left: -10000px; top: 10px"; - target.focus(); - let plain = view.input.shiftKey && view.input.lastKeyCode != 45; - setTimeout(() => { - view.focus(); - if (target.parentNode) - target.parentNode.removeChild(target); - if (plainText) - doPaste(view, target.value, null, plain, event); - else - doPaste(view, target.textContent, target.innerHTML, plain, event); - }, 50); - } - function doPaste(view, text5, html3, preferPlain, event) { - let slice = parseFromClipboard(view, text5, html3, preferPlain, view.state.selection.$from); - if (view.someProp("handlePaste", (f3) => f3(view, event, slice || Slice.empty))) - return true; - if (!slice) - return false; - let singleNode = sliceSingleNode(slice); - let tr = singleNode ? view.state.tr.replaceSelectionWith(singleNode, preferPlain) : view.state.tr.replaceSelection(slice); - view.dispatch(tr.scrollIntoView().setMeta("paste", true).setMeta("uiEvent", "paste")); - return true; - } - function getText(clipboardData) { - let text5 = clipboardData.getData("text/plain") || clipboardData.getData("Text"); - if (text5) - return text5; - let uris = clipboardData.getData("text/uri-list"); - return uris ? uris.replace(/\r?\n/g, " ") : ""; - } - editHandlers.paste = (view, _event) => { - let event = _event; - if (view.composing && !android) - return; - let data = brokenClipboardAPI ? null : event.clipboardData; - let plain = view.input.shiftKey && view.input.lastKeyCode != 45; - if (data && doPaste(view, getText(data), data.getData("text/html"), plain, event)) - event.preventDefault(); - else - capturePaste(view, event); - }; - var Dragging = class { - constructor(slice, move, node2) { - this.slice = slice; - this.move = move; - this.node = node2; - } - }; - var dragCopyModifier = mac ? "altKey" : "ctrlKey"; - handlers.dragstart = (view, _event) => { - let event = _event; - let mouseDown = view.input.mouseDown; - if (mouseDown) - mouseDown.done(); - if (!event.dataTransfer) - return; - let sel = view.state.selection; - let pos = sel.empty ? null : view.posAtCoords(eventCoords(event)); - let node2; - if (pos && pos.pos >= sel.from && pos.pos <= (sel instanceof NodeSelection ? sel.to - 1 : sel.to)) ; - else if (mouseDown && mouseDown.mightDrag) { - node2 = NodeSelection.create(view.state.doc, mouseDown.mightDrag.pos); - } else if (event.target && event.target.nodeType == 1) { - let desc = view.docView.nearestDesc(event.target, true); - if (desc && desc.node.type.spec.draggable && desc != view.docView) - node2 = NodeSelection.create(view.state.doc, desc.posBefore); - } - let draggedSlice = (node2 || view.state.selection).content(); - let { dom, text: text5, slice } = serializeForClipboard(view, draggedSlice); - event.dataTransfer.clearData(); - event.dataTransfer.setData(brokenClipboardAPI ? "Text" : "text/html", dom.innerHTML); - event.dataTransfer.effectAllowed = "copyMove"; - if (!brokenClipboardAPI) - event.dataTransfer.setData("text/plain", text5); - view.dragging = new Dragging(slice, !event[dragCopyModifier], node2); - }; - handlers.dragend = (view) => { - let dragging = view.dragging; - window.setTimeout(() => { - if (view.dragging == dragging) - view.dragging = null; - }, 50); - }; - editHandlers.dragover = editHandlers.dragenter = (_3, e2) => e2.preventDefault(); - editHandlers.drop = (view, _event) => { - let event = _event; - let dragging = view.dragging; - view.dragging = null; - if (!event.dataTransfer) - return; - let eventPos = view.posAtCoords(eventCoords(event)); - if (!eventPos) - return; - let $mouse = view.state.doc.resolve(eventPos.pos); - let slice = dragging && dragging.slice; - if (slice) { - view.someProp("transformPasted", (f3) => { - slice = f3(slice, view); - }); - } else { - slice = parseFromClipboard(view, getText(event.dataTransfer), brokenClipboardAPI ? null : event.dataTransfer.getData("text/html"), false, $mouse); - } - let move = !!(dragging && !event[dragCopyModifier]); - if (view.someProp("handleDrop", (f3) => f3(view, event, slice || Slice.empty, move))) { - event.preventDefault(); - return; - } - if (!slice) - return; - event.preventDefault(); - let insertPos = slice ? dropPoint(view.state.doc, $mouse.pos, slice) : $mouse.pos; - if (insertPos == null) - insertPos = $mouse.pos; - let tr = view.state.tr; - if (move) { - let { node: node2 } = dragging; - if (node2) - node2.replace(tr); - else - tr.deleteSelection(); - } - let pos = tr.mapping.map(insertPos); - let isNode = slice.openStart == 0 && slice.openEnd == 0 && slice.content.childCount == 1; - let beforeInsert = tr.doc; - if (isNode) - tr.replaceRangeWith(pos, pos, slice.content.firstChild); - else - tr.replaceRange(pos, pos, slice); - if (tr.doc.eq(beforeInsert)) - return; - let $pos = tr.doc.resolve(pos); - if (isNode && NodeSelection.isSelectable(slice.content.firstChild) && $pos.nodeAfter && $pos.nodeAfter.sameMarkup(slice.content.firstChild)) { - tr.setSelection(new NodeSelection($pos)); - } else { - let end = tr.mapping.map(insertPos); - tr.mapping.maps[tr.mapping.maps.length - 1].forEach((_from, _to, _newFrom, newTo) => end = newTo); - tr.setSelection(selectionBetween(view, $pos, tr.doc.resolve(end))); - } - view.focus(); - view.dispatch(tr.setMeta("uiEvent", "drop")); - }; - handlers.focus = (view) => { - view.input.lastFocus = Date.now(); - if (!view.focused) { - view.domObserver.stop(); - view.dom.classList.add("ProseMirror-focused"); - view.domObserver.start(); - view.focused = true; - setTimeout(() => { - if (view.docView && view.hasFocus() && !view.domObserver.currentSelection.eq(view.domSelectionRange())) - selectionToDOM(view); - }, 20); - } - }; - handlers.blur = (view, _event) => { - let event = _event; - if (view.focused) { - view.domObserver.stop(); - view.dom.classList.remove("ProseMirror-focused"); - view.domObserver.start(); - if (event.relatedTarget && view.dom.contains(event.relatedTarget)) - view.domObserver.currentSelection.clear(); - view.focused = false; - } - }; - handlers.beforeinput = (view, _event) => { - let event = _event; - if (chrome && android && event.inputType == "deleteContentBackward") { - view.domObserver.flushSoon(); - let { domChangeCount } = view.input; - setTimeout(() => { - if (view.input.domChangeCount != domChangeCount) - return; - view.dom.blur(); - view.focus(); - if (view.someProp("handleKeyDown", (f3) => f3(view, keyEvent(8, "Backspace")))) - return; - let { $cursor } = view.state.selection; - if ($cursor && $cursor.pos > 0) - view.dispatch(view.state.tr.delete($cursor.pos - 1, $cursor.pos).scrollIntoView()); - }, 50); - } - }; - for (let prop in editHandlers) - handlers[prop] = editHandlers[prop]; - function compareObjs(a2, b4) { - if (a2 == b4) - return true; - for (let p4 in a2) - if (a2[p4] !== b4[p4]) - return false; - for (let p4 in b4) - if (!(p4 in a2)) - return false; - return true; - } - var WidgetType = class _WidgetType { - constructor(toDOM, spec) { - this.toDOM = toDOM; - this.spec = spec || noSpec; - this.side = this.spec.side || 0; - } - map(mapping, span, offset, oldOffset) { - let { pos, deleted } = mapping.mapResult(span.from + oldOffset, this.side < 0 ? -1 : 1); - return deleted ? null : new Decoration(pos - offset, pos - offset, this); - } - valid() { - return true; - } - eq(other) { - return this == other || other instanceof _WidgetType && (this.spec.key && this.spec.key == other.spec.key || this.toDOM == other.toDOM && compareObjs(this.spec, other.spec)); - } - destroy(node2) { - if (this.spec.destroy) - this.spec.destroy(node2); - } - }; - var InlineType = class _InlineType { - constructor(attrs, spec) { - this.attrs = attrs; - this.spec = spec || noSpec; - } - map(mapping, span, offset, oldOffset) { - let from = mapping.map(span.from + oldOffset, this.spec.inclusiveStart ? -1 : 1) - offset; - let to = mapping.map(span.to + oldOffset, this.spec.inclusiveEnd ? 1 : -1) - offset; - return from >= to ? null : new Decoration(from, to, this); - } - valid(_3, span) { - return span.from < span.to; - } - eq(other) { - return this == other || other instanceof _InlineType && compareObjs(this.attrs, other.attrs) && compareObjs(this.spec, other.spec); - } - static is(span) { - return span.type instanceof _InlineType; - } - destroy() { - } - }; - var NodeType2 = class _NodeType { - constructor(attrs, spec) { - this.attrs = attrs; - this.spec = spec || noSpec; - } - map(mapping, span, offset, oldOffset) { - let from = mapping.mapResult(span.from + oldOffset, 1); - if (from.deleted) - return null; - let to = mapping.mapResult(span.to + oldOffset, -1); - if (to.deleted || to.pos <= from.pos) - return null; - return new Decoration(from.pos - offset, to.pos - offset, this); - } - valid(node2, span) { - let { index: index2, offset } = node2.content.findIndex(span.from), child; - return offset == span.from && !(child = node2.child(index2)).isText && offset + child.nodeSize == span.to; - } - eq(other) { - return this == other || other instanceof _NodeType && compareObjs(this.attrs, other.attrs) && compareObjs(this.spec, other.spec); - } - destroy() { - } - }; - var Decoration = class _Decoration { + var Line = class { /** @internal */ - constructor(from, to, type) { + constructor(from, to, number2, text) { this.from = from; this.to = to; - this.type = type; + this.number = number2; + this.text = text; } /** - @internal + The length of the line (not including any line break after it). */ - copy(from, to) { - return new _Decoration(from, to, this.type); - } - /** - @internal - */ - eq(other, offset = 0) { - return this.type.eq(other.type) && this.from + offset == other.from && this.to + offset == other.to; - } - /** - @internal - */ - map(mapping, offset, oldOffset) { - return this.type.map(mapping, this, offset, oldOffset); - } - /** - Creates a widget decoration, which is a DOM node that's shown in - the document at the given position. It is recommended that you - delay rendering the widget by passing a function that will be - called when the widget is actually drawn in a view, but you can - also directly pass a DOM node. `getPos` can be used to find the - widget's current document position. - */ - static widget(pos, toDOM, spec) { - return new _Decoration(pos, pos, new WidgetType(toDOM, spec)); - } - /** - Creates an inline decoration, which adds the given attributes to - each inline node between `from` and `to`. - */ - static inline(from, to, attrs, spec) { - return new _Decoration(from, to, new InlineType(attrs, spec)); - } - /** - Creates a node decoration. `from` and `to` should point precisely - before and after a node in the document. That node, and only that - node, will receive the given attributes. - */ - static node(from, to, attrs, spec) { - return new _Decoration(from, to, new NodeType2(attrs, spec)); - } - /** - The spec provided when creating this decoration. Can be useful - if you've stored extra information in that object. - */ - get spec() { - return this.type.spec; - } - /** - @internal - */ - get inline() { - return this.type instanceof InlineType; - } - /** - @internal - */ - get widget() { - return this.type instanceof WidgetType; + get length() { + return this.to - this.from; } }; - var none = []; - var noSpec = {}; - var DecorationSet = class _DecorationSet { + function clip(text, from, to) { + from = Math.max(0, Math.min(text.length, from)); + return [from, Math.max(from, Math.min(text.length, to))]; + } + var extend = /* @__PURE__ */ "lc,34,7n,7,7b,19,,,,2,,2,,,20,b,1c,l,g,,2t,7,2,6,2,2,,4,z,,u,r,2j,b,1m,9,9,,o,4,,9,,3,,5,17,3,3b,f,,w,1j,,,,4,8,4,,3,7,a,2,t,,1m,,,,2,4,8,,9,,a,2,q,,2,2,1l,,4,2,4,2,2,3,3,,u,2,3,,b,2,1l,,4,5,,2,4,,k,2,m,6,,,1m,,,2,,4,8,,7,3,a,2,u,,1n,,,,c,,9,,14,,3,,1l,3,5,3,,4,7,2,b,2,t,,1m,,2,,2,,3,,5,2,7,2,b,2,s,2,1l,2,,,2,4,8,,9,,a,2,t,,20,,4,,2,3,,,8,,29,,2,7,c,8,2q,,2,9,b,6,22,2,r,,,,,,1j,e,,5,,2,5,b,,10,9,,2u,4,,6,,2,2,2,p,2,4,3,g,4,d,,2,2,6,,f,,jj,3,qa,3,t,3,t,2,u,2,1s,2,,7,8,,2,b,9,,19,3,3b,2,y,,3a,3,4,2,9,,6,3,63,2,2,,1m,,,7,,,,,2,8,6,a,2,,1c,h,1r,4,1c,7,,,5,,14,9,c,2,w,4,2,2,,3,1k,,,2,3,,,3,1m,8,2,2,48,3,,d,,7,4,,6,,3,2,5i,1m,,5,ek,,5f,x,2da,3,3x,,2o,w,fe,6,2x,2,n9w,4,,a,w,2,28,2,7k,,3,,4,,p,2,5,,47,2,q,i,d,,12,8,p,b,1a,3,1c,,2,4,2,2,13,,1v,6,2,2,2,2,c,,8,,1b,,1f,,,3,2,2,5,2,,,16,2,8,,6m,,2,,4,,fn4,,kh,g,g,g,a6,2,gt,,6a,,45,5,1ae,3,,2,5,4,14,3,4,,4l,2,fx,4,ar,2,49,b,4w,,1i,f,1k,3,1d,4,2,2,1x,3,10,5,,8,1q,,c,2,1g,9,a,4,2,,2n,3,2,,,2,6,,4g,,3,8,l,2,1l,2,,,,,m,,e,7,3,5,5f,8,2,3,,,n,,29,,2,6,,,2,,,2,,2,6j,,2,4,6,2,,2,r,2,2d,8,2,,,2,2y,,,,2,6,,,2t,3,2,4,,5,77,9,,2,6t,,a,2,,,4,,40,4,2,2,4,,w,a,14,6,2,4,8,,9,6,2,3,1a,d,,2,ba,7,,6,,,2a,m,2,7,,2,,2,3e,6,3,,,2,,7,,,20,2,3,,,,9n,2,f0b,5,1n,7,t4,,1r,4,29,,f5k,2,43q,,,3,4,5,8,8,2,7,u,4,44,3,1iz,1j,4,1e,8,,e,,m,5,,f,11s,7,,h,2,7,,2,,5,79,7,c5,4,15s,7,31,7,240,5,gx7k,2o,3k,6o".split(",").map((s) => s ? parseInt(s, 36) : 1); + for (let i = 1; i < extend.length; i++) + extend[i] += extend[i - 1]; + function isExtendingChar(code) { + for (let i = 1; i < extend.length; i += 2) + if (extend[i] > code) + return extend[i - 1] <= code; + return false; + } + function isRegionalIndicator(code) { + return code >= 127462 && code <= 127487; + } + var ZWJ = 8205; + function findClusterBreak(str, pos, forward = true, includeExtending = true) { + return (forward ? nextClusterBreak : prevClusterBreak)(str, pos, includeExtending); + } + function nextClusterBreak(str, pos, includeExtending) { + if (pos == str.length) + return pos; + if (pos && surrogateLow(str.charCodeAt(pos)) && surrogateHigh(str.charCodeAt(pos - 1))) + pos--; + let prev = codePointAt(str, pos); + pos += codePointSize(prev); + while (pos < str.length) { + let next = codePointAt(str, pos); + if (prev == ZWJ || next == ZWJ || includeExtending && isExtendingChar(next)) { + pos += codePointSize(next); + prev = next; + } else if (isRegionalIndicator(next)) { + let countBefore = 0, i = pos - 2; + while (i >= 0 && isRegionalIndicator(codePointAt(str, i))) { + countBefore++; + i -= 2; + } + if (countBefore % 2 == 0) + break; + else + pos += 2; + } else { + break; + } + } + return pos; + } + function prevClusterBreak(str, pos, includeExtending) { + while (pos > 0) { + let found = nextClusterBreak(str, pos - 2, includeExtending); + if (found < pos) + return found; + pos--; + } + return 0; + } + function surrogateLow(ch) { + return ch >= 56320 && ch < 57344; + } + function surrogateHigh(ch) { + return ch >= 55296 && ch < 56320; + } + function codePointAt(str, pos) { + let code0 = str.charCodeAt(pos); + if (!surrogateHigh(code0) || pos + 1 == str.length) + return code0; + let code1 = str.charCodeAt(pos + 1); + if (!surrogateLow(code1)) + return code0; + return (code0 - 55296 << 10) + (code1 - 56320) + 65536; + } + function fromCodePoint(code) { + if (code <= 65535) + return String.fromCharCode(code); + code -= 65536; + return String.fromCharCode((code >> 10) + 55296, (code & 1023) + 56320); + } + function codePointSize(code) { + return code < 65536 ? 1 : 2; + } + var DefaultSplit = /\r\n?|\n/; + var MapMode = /* @__PURE__ */ function(MapMode2) { + MapMode2[MapMode2["Simple"] = 0] = "Simple"; + MapMode2[MapMode2["TrackDel"] = 1] = "TrackDel"; + MapMode2[MapMode2["TrackBefore"] = 2] = "TrackBefore"; + MapMode2[MapMode2["TrackAfter"] = 3] = "TrackAfter"; + return MapMode2; + }(MapMode || (MapMode = {})); + var ChangeDesc = class _ChangeDesc { + // Sections are encoded as pairs of integers. The first is the + // length in the current document, and the second is -1 for + // unaffected sections, and the length of the replacement content + // otherwise. So an insertion would be (0, n>0), a deletion (n>0, + // 0), and a replacement two positive numbers. /** @internal */ - constructor(local, children) { - this.local = local.length ? local : none; - this.children = children.length ? children : none; + constructor(sections) { + this.sections = sections; } /** - Create a set of decorations, using the structure of the given - document. This will consume (modify) the `decorations` array, so - you must make a copy if you want need to preserve that. + The length of the document before the change. */ - static create(doc4, decorations) { - return decorations.length ? buildTree(decorations, doc4, 0, noSpec) : empty2; - } - /** - Find all decorations in this set which touch the given range - (including decorations that start or end directly at the - boundaries) and match the given predicate on their spec. When - `start` and `end` are omitted, all decorations in the set are - considered. When `predicate` isn't given, all decorations are - assumed to match. - */ - find(start, end, predicate) { - let result = []; - this.findInner(start == null ? 0 : start, end == null ? 1e9 : end, result, 0, predicate); + get length() { + let result = 0; + for (let i = 0; i < this.sections.length; i += 2) + result += this.sections[i]; return result; } - findInner(start, end, result, offset, predicate) { - for (let i2 = 0; i2 < this.local.length; i2++) { - let span = this.local[i2]; - if (span.from <= end && span.to >= start && (!predicate || predicate(span.spec))) - result.push(span.copy(span.from + offset, span.to + offset)); + /** + The length of the document after the change. + */ + get newLength() { + let result = 0; + for (let i = 0; i < this.sections.length; i += 2) { + let ins = this.sections[i + 1]; + result += ins < 0 ? this.sections[i] : ins; } - for (let i2 = 0; i2 < this.children.length; i2 += 3) { - if (this.children[i2] < end && this.children[i2 + 1] > start) { - let childOff = this.children[i2] + 1; - this.children[i2 + 2].findInner(start - childOff, end - childOff, result, offset + childOff, predicate); + return result; + } + /** + False when there are actual changes in this set. + */ + get empty() { + return this.sections.length == 0 || this.sections.length == 2 && this.sections[1] < 0; + } + /** + Iterate over the unchanged parts left by these changes. `posA` + provides the position of the range in the old document, `posB` + the new position in the changed document. + */ + iterGaps(f) { + for (let i = 0, posA = 0, posB = 0; i < this.sections.length; ) { + let len = this.sections[i++], ins = this.sections[i++]; + if (ins < 0) { + f(posA, posB, len); + posB += len; + } else { + posB += ins; } + posA += len; } } /** - Map the set of decorations in response to a change in the + Iterate over the ranges changed by these changes. (See + [`ChangeSet.iterChanges`](https://codemirror.net/6/docs/ref/#state.ChangeSet.iterChanges) for a + variant that also provides you with the inserted text.) + `fromA`/`toA` provides the extent of the change in the starting + document, `fromB`/`toB` the extent of the replacement in the + changed document. + + When `individual` is true, adjacent changes (which are kept + separate for [position mapping](https://codemirror.net/6/docs/ref/#state.ChangeDesc.mapPos)) are + reported separately. + */ + iterChangedRanges(f, individual = false) { + iterChanges(this, f, individual); + } + /** + Get a description of the inverted form of these changes. + */ + get invertedDesc() { + let sections = []; + for (let i = 0; i < this.sections.length; ) { + let len = this.sections[i++], ins = this.sections[i++]; + if (ins < 0) + sections.push(len, ins); + else + sections.push(ins, len); + } + return new _ChangeDesc(sections); + } + /** + Compute the combined effect of applying another set of changes + after this one. The length of the document after this set should + match the length before `other`. + */ + composeDesc(other) { + return this.empty ? other : other.empty ? this : composeSets(this, other); + } + /** + Map this description, which should start with the same document + as `other`, over another set of changes, so that it can be + applied after it. When `before` is true, map as if the changes + in `other` happened before the ones in `this`. + */ + mapDesc(other, before = false) { + return other.empty ? this : mapSet(this, other, before); + } + mapPos(pos, assoc = -1, mode = MapMode.Simple) { + let posA = 0, posB = 0; + for (let i = 0; i < this.sections.length; ) { + let len = this.sections[i++], ins = this.sections[i++], endA = posA + len; + if (ins < 0) { + if (endA > pos) + return posB + (pos - posA); + posB += len; + } else { + if (mode != MapMode.Simple && endA >= pos && (mode == MapMode.TrackDel && posA < pos && endA > pos || mode == MapMode.TrackBefore && posA < pos || mode == MapMode.TrackAfter && endA > pos)) + return null; + if (endA > pos || endA == pos && assoc < 0 && !len) + return pos == posA || assoc < 0 ? posB : posB + ins; + posB += ins; + } + posA = endA; + } + if (pos > posA) + throw new RangeError(`Position ${pos} is out of range for changeset of length ${posA}`); + return posB; + } + /** + Check whether these changes touch a given range. When one of the + changes entirely covers the range, the string `"cover"` is + returned. + */ + touchesRange(from, to = from) { + for (let i = 0, pos = 0; i < this.sections.length && pos <= to; ) { + let len = this.sections[i++], ins = this.sections[i++], end = pos + len; + if (ins >= 0 && pos <= to && end >= from) + return pos < from && end > to ? "cover" : true; + pos = end; + } + return false; + } + /** + @internal + */ + toString() { + let result = ""; + for (let i = 0; i < this.sections.length; ) { + let len = this.sections[i++], ins = this.sections[i++]; + result += (result ? " " : "") + len + (ins >= 0 ? ":" + ins : ""); + } + return result; + } + /** + Serialize this change desc to a JSON-representable value. + */ + toJSON() { + return this.sections; + } + /** + Create a change desc from its JSON representation (as produced + by [`toJSON`](https://codemirror.net/6/docs/ref/#state.ChangeDesc.toJSON). + */ + static fromJSON(json) { + if (!Array.isArray(json) || json.length % 2 || json.some((a) => typeof a != "number")) + throw new RangeError("Invalid JSON representation of ChangeDesc"); + return new _ChangeDesc(json); + } + /** + @internal + */ + static create(sections) { + return new _ChangeDesc(sections); + } + }; + var ChangeSet = class _ChangeSet extends ChangeDesc { + constructor(sections, inserted) { + super(sections); + this.inserted = inserted; + } + /** + Apply the changes to a document, returning the modified document. */ - map(mapping, doc4, options2) { - if (this == empty2 || mapping.maps.length == 0) - return this; - return this.mapInner(mapping, doc4, 0, 0, options2 || noSpec); + apply(doc2) { + if (this.length != doc2.length) + throw new RangeError("Applying change set to a document with the wrong length"); + iterChanges(this, (fromA, toA, fromB, _toB, text) => doc2 = doc2.replace(fromB, fromB + (toA - fromA), text), false); + return doc2; + } + mapDesc(other, before = false) { + return mapSet(this, other, before, true); + } + /** + Given the document as it existed _before_ the changes, return a + change set that represents the inverse of this set, which could + be used to go from the document created by the changes back to + the document as it existed before the changes. + */ + invert(doc2) { + let sections = this.sections.slice(), inserted = []; + for (let i = 0, pos = 0; i < sections.length; i += 2) { + let len = sections[i], ins = sections[i + 1]; + if (ins >= 0) { + sections[i] = ins; + sections[i + 1] = len; + let index = i >> 1; + while (inserted.length < index) + inserted.push(Text.empty); + inserted.push(len ? doc2.slice(pos, pos + len) : Text.empty); + } + pos += len; + } + return new _ChangeSet(sections, inserted); + } + /** + Combine two subsequent change sets into a single set. `other` + must start in the document produced by `this`. If `this` goes + `docA` → `docB` and `other` represents `docB` → `docC`, the + returned value will represent the change `docA` → `docC`. + */ + compose(other) { + return this.empty ? other : other.empty ? this : composeSets(this, other, true); + } + /** + Given another change set starting in the same document, maps this + change set over the other, producing a new change set that can be + applied to the document produced by applying `other`. When + `before` is `true`, order changes as if `this` comes before + `other`, otherwise (the default) treat `other` as coming first. + + Given two changes `A` and `B`, `A.compose(B.map(A))` and + `B.compose(A.map(B, true))` will produce the same document. This + provides a basic form of [operational + transformation](https://en.wikipedia.org/wiki/Operational_transformation), + and can be used for collaborative editing. + */ + map(other, before = false) { + return other.empty ? this : mapSet(this, other, before, true); + } + /** + Iterate over the changed ranges in the document, calling `f` for + each, with the range in the original document (`fromA`-`toA`) + and the range that replaces it in the new document + (`fromB`-`toB`). + + When `individual` is true, adjacent changes are reported + separately. + */ + iterChanges(f, individual = false) { + iterChanges(this, f, individual); + } + /** + Get a [change description](https://codemirror.net/6/docs/ref/#state.ChangeDesc) for this change + set. + */ + get desc() { + return ChangeDesc.create(this.sections); } /** @internal */ - mapInner(mapping, node2, offset, oldOffset, options2) { - let newLocal; - for (let i2 = 0; i2 < this.local.length; i2++) { - let mapped = this.local[i2].map(mapping, offset, oldOffset); - if (mapped && mapped.type.valid(node2, mapped)) - (newLocal || (newLocal = [])).push(mapped); - else if (options2.onRemove) - options2.onRemove(this.local[i2].spec); + filter(ranges) { + let resultSections = [], resultInserted = [], filteredSections = []; + let iter = new SectionIter(this); + done: for (let i = 0, pos = 0; ; ) { + let next = i == ranges.length ? 1e9 : ranges[i++]; + while (pos < next || pos == next && iter.len == 0) { + if (iter.done) + break done; + let len = Math.min(iter.len, next - pos); + addSection(filteredSections, len, -1); + let ins = iter.ins == -1 ? -1 : iter.off == 0 ? iter.ins : 0; + addSection(resultSections, len, ins); + if (ins > 0) + addInsert(resultInserted, resultSections, iter.text); + iter.forward(len); + pos += len; + } + let end = ranges[i++]; + while (pos < end) { + if (iter.done) + break done; + let len = Math.min(iter.len, end - pos); + addSection(resultSections, len, -1); + addSection(filteredSections, len, iter.ins == -1 ? -1 : iter.off == 0 ? iter.ins : 0); + iter.forward(len); + pos += len; + } } - if (this.children.length) - return mapChildren(this.children, newLocal || [], mapping, node2, offset, oldOffset, options2); - else - return newLocal ? new _DecorationSet(newLocal.sort(byPos), none) : empty2; + return { + changes: new _ChangeSet(resultSections, resultInserted), + filtered: ChangeDesc.create(filteredSections) + }; } /** - Add the given array of decorations to the ones in the set, - producing a new set. Consumes the `decorations` array. Needs - access to the current document to create the appropriate tree - structure. + Serialize this change set to a JSON-representable value. */ - add(doc4, decorations) { - if (!decorations.length) - return this; - if (this == empty2) - return _DecorationSet.create(doc4, decorations); - return this.addInner(doc4, decorations, 0); + toJSON() { + let parts = []; + for (let i = 0; i < this.sections.length; i += 2) { + let len = this.sections[i], ins = this.sections[i + 1]; + if (ins < 0) + parts.push(len); + else if (ins == 0) + parts.push([len]); + else + parts.push([len].concat(this.inserted[i >> 1].toJSON())); + } + return parts; } - addInner(doc4, decorations, offset) { - let children, childIndex = 0; - doc4.forEach((childNode, childOffset) => { - let baseOffset = childOffset + offset, found2; - if (!(found2 = takeSpansForNode(decorations, childNode, baseOffset))) + /** + Create a change set for the given changes, for a document of the + given length, using `lineSep` as line separator. + */ + static of(changes, length, lineSep) { + let sections = [], inserted = [], pos = 0; + let total = null; + function flush(force = false) { + if (!force && !sections.length) return; - if (!children) - children = this.children.slice(); - while (childIndex < children.length && children[childIndex] < childOffset) - childIndex += 3; - if (children[childIndex] == childOffset) - children[childIndex + 2] = children[childIndex + 2].addInner(childNode, found2, baseOffset + 1); - else - children.splice(childIndex, 0, childOffset, childOffset + childNode.nodeSize, buildTree(found2, childNode, baseOffset + 1, noSpec)); - childIndex += 3; - }); - let local = moveSpans(childIndex ? withoutNulls(decorations) : decorations, -offset); - for (let i2 = 0; i2 < local.length; i2++) - if (!local[i2].type.valid(doc4, local[i2])) - local.splice(i2--, 1); - return new _DecorationSet(local.length ? this.local.concat(local).sort(byPos) : this.local, children || this.children); - } - /** - Create a new set that contains the decorations in this set, minus - the ones in the given array. - */ - remove(decorations) { - if (decorations.length == 0 || this == empty2) - return this; - return this.removeInner(decorations, 0); - } - removeInner(decorations, offset) { - let children = this.children, local = this.local; - for (let i2 = 0; i2 < children.length; i2 += 3) { - let found2; - let from = children[i2] + offset, to = children[i2 + 1] + offset; - for (let j6 = 0, span; j6 < decorations.length; j6++) - if (span = decorations[j6]) { - if (span.from > from && span.to < to) { - decorations[j6] = null; - (found2 || (found2 = [])).push(span); - } - } - if (!found2) - continue; - if (children == this.children) - children = this.children.slice(); - let removed = children[i2 + 2].removeInner(found2, from + 1); - if (removed != empty2) { - children[i2 + 2] = removed; + if (pos < length) + addSection(sections, length - pos, -1); + let set = new _ChangeSet(sections, inserted); + total = total ? total.compose(set.map(total)) : set; + sections = []; + inserted = []; + pos = 0; + } + function process2(spec) { + if (Array.isArray(spec)) { + for (let sub of spec) + process2(sub); + } else if (spec instanceof _ChangeSet) { + if (spec.length != length) + throw new RangeError(`Mismatched change set length (got ${spec.length}, expected ${length})`); + flush(); + total = total ? total.compose(spec.map(total)) : spec; } else { - children.splice(i2, 3); - i2 -= 3; + let { from, to = from, insert: insert2 } = spec; + if (from > to || from < 0 || to > length) + throw new RangeError(`Invalid change range ${from} to ${to} (in doc of length ${length})`); + let insText = !insert2 ? Text.empty : typeof insert2 == "string" ? Text.of(insert2.split(lineSep || DefaultSplit)) : insert2; + let insLen = insText.length; + if (from == to && insLen == 0) + return; + if (from < pos) + flush(); + if (from > pos) + addSection(sections, from - pos, -1); + addSection(sections, to - from, insLen); + addInsert(inserted, sections, insText); + pos = to; } } - if (local.length) { - for (let i2 = 0, span; i2 < decorations.length; i2++) - if (span = decorations[i2]) { - for (let j6 = 0; j6 < local.length; j6++) - if (local[j6].eq(span, offset)) { - if (local == this.local) - local = this.local.slice(); - local.splice(j6--, 1); - } - } - } - if (children == this.children && local == this.local) - return this; - return local.length || children.length ? new _DecorationSet(local, children) : empty2; + process2(changes); + flush(!total); + return total; } - forChild(offset, node2) { - if (this == empty2) - return this; - if (node2.isLeaf) - return _DecorationSet.empty; - let child, local; - for (let i2 = 0; i2 < this.children.length; i2 += 3) - if (this.children[i2] >= offset) { - if (this.children[i2] == offset) - child = this.children[i2 + 2]; - break; - } - let start = offset + 1, end = start + node2.content.size; - for (let i2 = 0; i2 < this.local.length; i2++) { - let dec = this.local[i2]; - if (dec.from < end && dec.to > start && dec.type instanceof InlineType) { - let from = Math.max(start, dec.from) - start, to = Math.min(end, dec.to) - start; - if (from < to) - (local || (local = [])).push(dec.copy(from, to)); + /** + Create an empty changeset of the given length. + */ + static empty(length) { + return new _ChangeSet(length ? [length, -1] : [], []); + } + /** + Create a changeset from its JSON representation (as produced by + [`toJSON`](https://codemirror.net/6/docs/ref/#state.ChangeSet.toJSON). + */ + static fromJSON(json) { + if (!Array.isArray(json)) + throw new RangeError("Invalid JSON representation of ChangeSet"); + let sections = [], inserted = []; + for (let i = 0; i < json.length; i++) { + let part = json[i]; + if (typeof part == "number") { + sections.push(part, -1); + } else if (!Array.isArray(part) || typeof part[0] != "number" || part.some((e, i2) => i2 && typeof e != "string")) { + throw new RangeError("Invalid JSON representation of ChangeSet"); + } else if (part.length == 1) { + sections.push(part[0], 0); + } else { + while (inserted.length < i) + inserted.push(Text.empty); + inserted[i] = Text.of(part.slice(1)); + sections.push(part[0], inserted[i].length); } } - if (local) { - let localSet = new _DecorationSet(local.sort(byPos), none); - return child ? new DecorationGroup([localSet, child]) : localSet; - } - return child || empty2; + return new _ChangeSet(sections, inserted); } /** @internal */ - eq(other) { - if (this == other) - return true; - if (!(other instanceof _DecorationSet) || this.local.length != other.local.length || this.children.length != other.children.length) - return false; - for (let i2 = 0; i2 < this.local.length; i2++) - if (!this.local[i2].eq(other.local[i2])) - return false; - for (let i2 = 0; i2 < this.children.length; i2 += 3) - if (this.children[i2] != other.children[i2] || this.children[i2 + 1] != other.children[i2 + 1] || !this.children[i2 + 2].eq(other.children[i2 + 2])) - return false; - return true; - } - /** - @internal - */ - locals(node2) { - return removeOverlap(this.localsInner(node2)); - } - /** - @internal - */ - localsInner(node2) { - if (this == empty2) - return none; - if (node2.inlineContent || !this.local.some(InlineType.is)) - return this.local; - let result = []; - for (let i2 = 0; i2 < this.local.length; i2++) { - if (!(this.local[i2].type instanceof InlineType)) - result.push(this.local[i2]); - } - return result; + static createSet(sections, inserted) { + return new _ChangeSet(sections, inserted); } }; - DecorationSet.empty = new DecorationSet([], []); - DecorationSet.removeOverlap = removeOverlap; - var empty2 = DecorationSet.empty; - var DecorationGroup = class _DecorationGroup { - constructor(members) { - this.members = members; + function addSection(sections, len, ins, forceJoin = false) { + if (len == 0 && ins <= 0) + return; + let last = sections.length - 2; + if (last >= 0 && ins <= 0 && ins == sections[last + 1]) + sections[last] += len; + else if (len == 0 && sections[last] == 0) + sections[last + 1] += ins; + else if (forceJoin) { + sections[last] += len; + sections[last + 1] += ins; + } else + sections.push(len, ins); + } + function addInsert(values2, sections, value) { + if (value.length == 0) + return; + let index = sections.length - 2 >> 1; + if (index < values2.length) { + values2[values2.length - 1] = values2[values2.length - 1].append(value); + } else { + while (values2.length < index) + values2.push(Text.empty); + values2.push(value); } - map(mapping, doc4) { - const mappedDecos = this.members.map((member) => member.map(mapping, doc4, noSpec)); - return _DecorationGroup.from(mappedDecos); - } - forChild(offset, child) { - if (child.isLeaf) - return DecorationSet.empty; - let found2 = []; - for (let i2 = 0; i2 < this.members.length; i2++) { - let result = this.members[i2].forChild(offset, child); - if (result == empty2) - continue; - if (result instanceof _DecorationGroup) - found2 = found2.concat(result.members); - else - found2.push(result); + } + function iterChanges(desc, f, individual) { + let inserted = desc.inserted; + for (let posA = 0, posB = 0, i = 0; i < desc.sections.length; ) { + let len = desc.sections[i++], ins = desc.sections[i++]; + if (ins < 0) { + posA += len; + posB += len; + } else { + let endA = posA, endB = posB, text = Text.empty; + for (; ; ) { + endA += len; + endB += ins; + if (ins && inserted) + text = text.append(inserted[i - 2 >> 1]); + if (individual || i == desc.sections.length || desc.sections[i + 1] < 0) + break; + len = desc.sections[i++]; + ins = desc.sections[i++]; + } + f(posA, endA, posB, endB, text); + posA = endA; + posB = endB; } - return _DecorationGroup.from(found2); } - eq(other) { - if (!(other instanceof _DecorationGroup) || other.members.length != this.members.length) - return false; - for (let i2 = 0; i2 < this.members.length; i2++) - if (!this.members[i2].eq(other.members[i2])) - return false; - return true; - } - locals(node2) { - let result, sorted = true; - for (let i2 = 0; i2 < this.members.length; i2++) { - let locals = this.members[i2].localsInner(node2); - if (!locals.length) - continue; - if (!result) { - result = locals; - } else { - if (sorted) { - result = result.slice(); - sorted = false; + } + function mapSet(setA, setB, before, mkSet = false) { + let sections = [], insert2 = mkSet ? [] : null; + let a = new SectionIter(setA), b = new SectionIter(setB); + for (let inserted = -1; ; ) { + if (a.ins == -1 && b.ins == -1) { + let len = Math.min(a.len, b.len); + addSection(sections, len, -1); + a.forward(len); + b.forward(len); + } else if (b.ins >= 0 && (a.ins < 0 || inserted == a.i || a.off == 0 && (b.len < a.len || b.len == a.len && !before))) { + let len = b.len; + addSection(sections, b.ins, -1); + while (len) { + let piece = Math.min(a.len, len); + if (a.ins >= 0 && inserted < a.i && a.len <= piece) { + addSection(sections, 0, a.ins); + if (insert2) + addInsert(insert2, sections, a.text); + inserted = a.i; } - for (let j6 = 0; j6 < locals.length; j6++) - result.push(locals[j6]); + a.forward(piece); + len -= piece; } - } - return result ? removeOverlap(sorted ? result : result.sort(byPos)) : none; - } - // Create a group for the given array of decoration sets, or return - // a single set when possible. - static from(members) { - switch (members.length) { - case 0: - return empty2; - case 1: - return members[0]; - default: - return new _DecorationGroup(members.every((m3) => m3 instanceof DecorationSet) ? members : members.reduce((r3, m3) => r3.concat(m3 instanceof DecorationSet ? m3 : m3.members), [])); - } - } - }; - function mapChildren(oldChildren, newLocal, mapping, node2, offset, oldOffset, options2) { - let children = oldChildren.slice(); - for (let i2 = 0, baseOffset = oldOffset; i2 < mapping.maps.length; i2++) { - let moved = 0; - mapping.maps[i2].forEach((oldStart, oldEnd, newStart, newEnd) => { - let dSize = newEnd - newStart - (oldEnd - oldStart); - for (let i3 = 0; i3 < children.length; i3 += 3) { - let end = children[i3 + 1]; - if (end < 0 || oldStart > end + baseOffset - moved) - continue; - let start = children[i3] + baseOffset - moved; - if (oldEnd >= start) { - children[i3 + 1] = oldStart <= start ? -2 : -1; - } else if (oldStart >= baseOffset && dSize) { - children[i3] += dSize; - children[i3 + 1] += dSize; - } - } - moved += dSize; - }); - baseOffset = mapping.maps[i2].map(baseOffset, -1); - } - let mustRebuild = false; - for (let i2 = 0; i2 < children.length; i2 += 3) - if (children[i2 + 1] < 0) { - if (children[i2 + 1] == -2) { - mustRebuild = true; - children[i2 + 1] = -1; - continue; - } - let from = mapping.map(oldChildren[i2] + oldOffset), fromLocal = from - offset; - if (fromLocal < 0 || fromLocal >= node2.content.size) { - mustRebuild = true; - continue; - } - let to = mapping.map(oldChildren[i2 + 1] + oldOffset, -1), toLocal = to - offset; - let { index: index2, offset: childOffset } = node2.content.findIndex(fromLocal); - let childNode = node2.maybeChild(index2); - if (childNode && childOffset == fromLocal && childOffset + childNode.nodeSize == toLocal) { - let mapped = children[i2 + 2].mapInner(mapping, childNode, from + 1, oldChildren[i2] + oldOffset + 1, options2); - if (mapped != empty2) { - children[i2] = fromLocal; - children[i2 + 1] = toLocal; - children[i2 + 2] = mapped; + b.next(); + } else if (a.ins >= 0) { + let len = 0, left = a.len; + while (left) { + if (b.ins == -1) { + let piece = Math.min(left, b.len); + len += piece; + left -= piece; + b.forward(piece); + } else if (b.ins == 0 && b.len < left) { + left -= b.len; + b.next(); } else { - children[i2 + 1] = -2; - mustRebuild = true; - } - } else { - mustRebuild = true; - } - } - if (mustRebuild) { - let decorations = mapAndGatherRemainingDecorations(children, oldChildren, newLocal, mapping, offset, oldOffset, options2); - let built = buildTree(decorations, node2, 0, options2); - newLocal = built.local; - for (let i2 = 0; i2 < children.length; i2 += 3) - if (children[i2 + 1] < 0) { - children.splice(i2, 3); - i2 -= 3; - } - for (let i2 = 0, j6 = 0; i2 < built.children.length; i2 += 3) { - let from = built.children[i2]; - while (j6 < children.length && children[j6] < from) - j6 += 3; - children.splice(j6, 0, built.children[i2], built.children[i2 + 1], built.children[i2 + 2]); - } - } - return new DecorationSet(newLocal.sort(byPos), children); - } - function moveSpans(spans, offset) { - if (!offset || !spans.length) - return spans; - let result = []; - for (let i2 = 0; i2 < spans.length; i2++) { - let span = spans[i2]; - result.push(new Decoration(span.from + offset, span.to + offset, span.type)); - } - return result; - } - function mapAndGatherRemainingDecorations(children, oldChildren, decorations, mapping, offset, oldOffset, options2) { - function gather(set, oldOffset2) { - for (let i2 = 0; i2 < set.local.length; i2++) { - let mapped = set.local[i2].map(mapping, offset, oldOffset2); - if (mapped) - decorations.push(mapped); - else if (options2.onRemove) - options2.onRemove(set.local[i2].spec); - } - for (let i2 = 0; i2 < set.children.length; i2 += 3) - gather(set.children[i2 + 2], set.children[i2] + oldOffset2 + 1); - } - for (let i2 = 0; i2 < children.length; i2 += 3) - if (children[i2 + 1] == -1) - gather(children[i2 + 2], oldChildren[i2] + oldOffset + 1); - return decorations; - } - function takeSpansForNode(spans, node2, offset) { - if (node2.isLeaf) - return null; - let end = offset + node2.nodeSize, found2 = null; - for (let i2 = 0, span; i2 < spans.length; i2++) { - if ((span = spans[i2]) && span.from > offset && span.to < end) { - (found2 || (found2 = [])).push(span); - spans[i2] = null; - } - } - return found2; - } - function withoutNulls(array) { - let result = []; - for (let i2 = 0; i2 < array.length; i2++) - if (array[i2] != null) - result.push(array[i2]); - return result; - } - function buildTree(spans, node2, offset, options2) { - let children = [], hasNulls = false; - node2.forEach((childNode, localStart) => { - let found2 = takeSpansForNode(spans, childNode, localStart + offset); - if (found2) { - hasNulls = true; - let subtree = buildTree(found2, childNode, offset + localStart + 1, options2); - if (subtree != empty2) - children.push(localStart, localStart + childNode.nodeSize, subtree); - } - }); - let locals = moveSpans(hasNulls ? withoutNulls(spans) : spans, -offset).sort(byPos); - for (let i2 = 0; i2 < locals.length; i2++) - if (!locals[i2].type.valid(node2, locals[i2])) { - if (options2.onRemove) - options2.onRemove(locals[i2].spec); - locals.splice(i2--, 1); - } - return locals.length || children.length ? new DecorationSet(locals, children) : empty2; - } - function byPos(a2, b4) { - return a2.from - b4.from || a2.to - b4.to; - } - function removeOverlap(spans) { - let working = spans; - for (let i2 = 0; i2 < working.length - 1; i2++) { - let span = working[i2]; - if (span.from != span.to) - for (let j6 = i2 + 1; j6 < working.length; j6++) { - let next = working[j6]; - if (next.from == span.from) { - if (next.to != span.to) { - if (working == spans) - working = spans.slice(); - working[j6] = next.copy(next.from, span.to); - insertAhead(working, j6 + 1, next.copy(span.to, next.to)); - } - continue; - } else { - if (next.from < span.to) { - if (working == spans) - working = spans.slice(); - working[i2] = span.copy(span.from, next.from); - insertAhead(working, j6, span.copy(next.from, span.to)); - } break; } } - } - return working; - } - function insertAhead(array, i2, deco) { - while (i2 < array.length && byPos(deco, array[i2]) > 0) - i2++; - array.splice(i2, 0, deco); - } - function viewDecorations(view) { - let found2 = []; - view.someProp("decorations", (f3) => { - let result = f3(view.state); - if (result && result != empty2) - found2.push(result); - }); - if (view.cursorWrapper) - found2.push(DecorationSet.create(view.state.doc, [view.cursorWrapper.deco])); - return DecorationGroup.from(found2); - } - var observeOptions = { - childList: true, - characterData: true, - characterDataOldValue: true, - attributes: true, - attributeOldValue: true, - subtree: true - }; - var useCharData = ie && ie_version <= 11; - var SelectionState = class { - constructor() { - this.anchorNode = null; - this.anchorOffset = 0; - this.focusNode = null; - this.focusOffset = 0; - } - set(sel) { - this.anchorNode = sel.anchorNode; - this.anchorOffset = sel.anchorOffset; - this.focusNode = sel.focusNode; - this.focusOffset = sel.focusOffset; - } - clear() { - this.anchorNode = this.focusNode = null; - } - eq(sel) { - return sel.anchorNode == this.anchorNode && sel.anchorOffset == this.anchorOffset && sel.focusNode == this.focusNode && sel.focusOffset == this.focusOffset; - } - }; - var DOMObserver = class { - constructor(view, handleDOMChange) { - this.view = view; - this.handleDOMChange = handleDOMChange; - this.queue = []; - this.flushingSoon = -1; - this.observer = null; - this.currentSelection = new SelectionState(); - this.onCharData = null; - this.suppressingSelectionUpdates = false; - this.observer = window.MutationObserver && new window.MutationObserver((mutations) => { - for (let i2 = 0; i2 < mutations.length; i2++) - this.queue.push(mutations[i2]); - if (ie && ie_version <= 11 && mutations.some((m3) => m3.type == "childList" && m3.removedNodes.length || m3.type == "characterData" && m3.oldValue.length > m3.target.nodeValue.length)) - this.flushSoon(); - else - this.flush(); - }); - if (useCharData) { - this.onCharData = (e2) => { - this.queue.push({ target: e2.target, type: "characterData", oldValue: e2.prevValue }); - this.flushSoon(); - }; - } - this.onSelectionChange = this.onSelectionChange.bind(this); - } - flushSoon() { - if (this.flushingSoon < 0) - this.flushingSoon = window.setTimeout(() => { - this.flushingSoon = -1; - this.flush(); - }, 20); - } - forceFlush() { - if (this.flushingSoon > -1) { - window.clearTimeout(this.flushingSoon); - this.flushingSoon = -1; - this.flush(); - } - } - start() { - if (this.observer) { - this.observer.takeRecords(); - this.observer.observe(this.view.dom, observeOptions); - } - if (this.onCharData) - this.view.dom.addEventListener("DOMCharacterDataModified", this.onCharData); - this.connectSelection(); - } - stop() { - if (this.observer) { - let take = this.observer.takeRecords(); - if (take.length) { - for (let i2 = 0; i2 < take.length; i2++) - this.queue.push(take[i2]); - window.setTimeout(() => this.flush(), 20); - } - this.observer.disconnect(); - } - if (this.onCharData) - this.view.dom.removeEventListener("DOMCharacterDataModified", this.onCharData); - this.disconnectSelection(); - } - connectSelection() { - this.view.dom.ownerDocument.addEventListener("selectionchange", this.onSelectionChange); - } - disconnectSelection() { - this.view.dom.ownerDocument.removeEventListener("selectionchange", this.onSelectionChange); - } - suppressSelectionUpdates() { - this.suppressingSelectionUpdates = true; - setTimeout(() => this.suppressingSelectionUpdates = false, 50); - } - onSelectionChange() { - if (!hasFocusAndSelection(this.view)) - return; - if (this.suppressingSelectionUpdates) - return selectionToDOM(this.view); - if (ie && ie_version <= 11 && !this.view.state.selection.empty) { - let sel = this.view.domSelectionRange(); - if (sel.focusNode && isEquivalentPosition(sel.focusNode, sel.focusOffset, sel.anchorNode, sel.anchorOffset)) - return this.flushSoon(); - } - this.flush(); - } - setCurSelection() { - this.currentSelection.set(this.view.domSelectionRange()); - } - ignoreSelectionChange(sel) { - if (!sel.focusNode) - return true; - let ancestors = /* @__PURE__ */ new Set(), container; - for (let scan = sel.focusNode; scan; scan = parentNode(scan)) - ancestors.add(scan); - for (let scan = sel.anchorNode; scan; scan = parentNode(scan)) - if (ancestors.has(scan)) { - container = scan; - break; - } - let desc = container && this.view.docView.nearestDesc(container); - if (desc && desc.ignoreMutation({ - type: "selection", - target: container.nodeType == 3 ? container.parentNode : container - })) { - this.setCurSelection(); - return true; - } - } - pendingRecords() { - if (this.observer) - for (let mut of this.observer.takeRecords()) - this.queue.push(mut); - return this.queue; - } - flush() { - let { view } = this; - if (!view.docView || this.flushingSoon > -1) - return; - let mutations = this.pendingRecords(); - if (mutations.length) - this.queue = []; - let sel = view.domSelectionRange(); - let newSel = !this.suppressingSelectionUpdates && !this.currentSelection.eq(sel) && hasFocusAndSelection(view) && !this.ignoreSelectionChange(sel); - let from = -1, to = -1, typeOver = false, added = []; - if (view.editable) { - for (let i2 = 0; i2 < mutations.length; i2++) { - let result = this.registerMutation(mutations[i2], added); - if (result) { - from = from < 0 ? result.from : Math.min(result.from, from); - to = to < 0 ? result.to : Math.max(result.to, to); - if (result.typeOver) - typeOver = true; - } - } - } - if (gecko && added.length > 1) { - let brs = added.filter((n4) => n4.nodeName == "BR"); - if (brs.length == 2) { - let a2 = brs[0], b4 = brs[1]; - if (a2.parentNode && a2.parentNode.parentNode == b4.parentNode) - b4.remove(); - else - a2.remove(); - } - } - let readSel = null; - if (from < 0 && newSel && view.input.lastFocus > Date.now() - 200 && Math.max(view.input.lastTouch, view.input.lastClick.time) < Date.now() - 300 && selectionCollapsed(sel) && (readSel = selectionFromDOM(view)) && readSel.eq(Selection.near(view.state.doc.resolve(0), 1))) { - view.input.lastFocus = 0; - selectionToDOM(view); - this.currentSelection.set(sel); - view.scrollToSelection(); - } else if (from > -1 || newSel) { - if (from > -1) { - view.docView.markDirty(from, to); - checkCSS(view); - } - this.handleDOMChange(from, to, typeOver, added); - if (view.docView && view.docView.dirty) - view.updateState(view.state); - else if (!this.currentSelection.eq(sel)) - selectionToDOM(view); - this.currentSelection.set(sel); - } - } - registerMutation(mut, added) { - if (added.indexOf(mut.target) > -1) - return null; - let desc = this.view.docView.nearestDesc(mut.target); - if (mut.type == "attributes" && (desc == this.view.docView || mut.attributeName == "contenteditable" || // Firefox sometimes fires spurious events for null/empty styles - mut.attributeName == "style" && !mut.oldValue && !mut.target.getAttribute("style"))) - return null; - if (!desc || desc.ignoreMutation(mut)) - return null; - if (mut.type == "childList") { - for (let i2 = 0; i2 < mut.addedNodes.length; i2++) - added.push(mut.addedNodes[i2]); - if (desc.contentDOM && desc.contentDOM != desc.dom && !desc.contentDOM.contains(mut.target)) - return { from: desc.posBefore, to: desc.posAfter }; - let prev = mut.previousSibling, next = mut.nextSibling; - if (ie && ie_version <= 11 && mut.addedNodes.length) { - for (let i2 = 0; i2 < mut.addedNodes.length; i2++) { - let { previousSibling, nextSibling } = mut.addedNodes[i2]; - if (!previousSibling || Array.prototype.indexOf.call(mut.addedNodes, previousSibling) < 0) - prev = previousSibling; - if (!nextSibling || Array.prototype.indexOf.call(mut.addedNodes, nextSibling) < 0) - next = nextSibling; - } - } - let fromOffset = prev && prev.parentNode == mut.target ? domIndex(prev) + 1 : 0; - let from = desc.localPosFromDOM(mut.target, fromOffset, -1); - let toOffset = next && next.parentNode == mut.target ? domIndex(next) : mut.target.childNodes.length; - let to = desc.localPosFromDOM(mut.target, toOffset, 1); - return { from, to }; - } else if (mut.type == "attributes") { - return { from: desc.posAtStart - desc.border, to: desc.posAtEnd + desc.border }; + addSection(sections, len, inserted < a.i ? a.ins : 0); + if (insert2 && inserted < a.i) + addInsert(insert2, sections, a.text); + inserted = a.i; + a.forward(a.len - left); + } else if (a.done && b.done) { + return insert2 ? ChangeSet.createSet(sections, insert2) : ChangeDesc.create(sections); } else { - return { - from: desc.posAtStart, - to: desc.posAtEnd, - // An event was generated for a text change that didn't change - // any text. Mark the dom change to fall back to assuming the - // selection was typed over with an identical value if it can't - // find another change. - typeOver: mut.target.nodeValue == mut.oldValue - }; + throw new Error("Mismatched change set lengths"); } } - }; - var cssChecked = /* @__PURE__ */ new WeakMap(); - var cssCheckWarned = false; - function checkCSS(view) { - if (cssChecked.has(view)) - return; - cssChecked.set(view, null); - if (["normal", "nowrap", "pre-line"].indexOf(getComputedStyle(view.dom).whiteSpace) !== -1) { - view.requiresGeckoHackNode = gecko; - if (cssCheckWarned) - return; - console["warn"]("ProseMirror expects the CSS white-space property to be set, preferably to 'pre-wrap'. It is recommended to load style/prosemirror.css from the prosemirror-view package."); - cssCheckWarned = true; - } } - function rangeToSelectionRange(view, range) { - let anchorNode = range.startContainer, anchorOffset = range.startOffset; - let focusNode = range.endContainer, focusOffset = range.endOffset; - let currentAnchor = view.domAtPos(view.state.selection.anchor); - if (isEquivalentPosition(currentAnchor.node, currentAnchor.offset, focusNode, focusOffset)) - [anchorNode, anchorOffset, focusNode, focusOffset] = [focusNode, focusOffset, anchorNode, anchorOffset]; - return { anchorNode, anchorOffset, focusNode, focusOffset }; - } - function safariShadowSelectionRange(view, selection) { - if (selection.getComposedRanges) { - let range = selection.getComposedRanges(view.root)[0]; - if (range) - return rangeToSelectionRange(view, range); - } - let found2; - function read(event) { - event.preventDefault(); - event.stopImmediatePropagation(); - found2 = event.getTargetRanges()[0]; - } - view.dom.addEventListener("beforeinput", read, true); - document.execCommand("indent"); - view.dom.removeEventListener("beforeinput", read, true); - return found2 ? rangeToSelectionRange(view, found2) : null; - } - function parseBetween(view, from_, to_) { - let { node: parent, fromOffset, toOffset, from, to } = view.docView.parseRange(from_, to_); - let domSel = view.domSelectionRange(); - let find; - let anchor = domSel.anchorNode; - if (anchor && view.dom.contains(anchor.nodeType == 1 ? anchor : anchor.parentNode)) { - find = [{ node: anchor, offset: domSel.anchorOffset }]; - if (!selectionCollapsed(domSel)) - find.push({ node: domSel.focusNode, offset: domSel.focusOffset }); - } - if (chrome && view.input.lastKeyCode === 8) { - for (let off = toOffset; off > fromOffset; off--) { - let node2 = parent.childNodes[off - 1], desc = node2.pmViewDesc; - if (node2.nodeName == "BR" && !desc) { - toOffset = off; - break; - } - if (!desc || desc.size) - break; - } - } - let startDoc = view.state.doc; - let parser = view.someProp("domParser") || DOMParser.fromSchema(view.state.schema); - let $from = startDoc.resolve(from); - let sel = null, doc4 = parser.parse(parent, { - topNode: $from.parent, - topMatch: $from.parent.contentMatchAt($from.index()), - topOpen: true, - from: fromOffset, - to: toOffset, - preserveWhitespace: $from.parent.type.whitespace == "pre" ? "full" : true, - findPositions: find, - ruleFromNode, - context: $from - }); - if (find && find[0].pos != null) { - let anchor2 = find[0].pos, head = find[1] && find[1].pos; - if (head == null) - head = anchor2; - sel = { anchor: anchor2 + from, head: head + from }; - } - return { doc: doc4, sel, from, to }; - } - function ruleFromNode(dom) { - let desc = dom.pmViewDesc; - if (desc) { - return desc.parseRule(); - } else if (dom.nodeName == "BR" && dom.parentNode) { - if (safari && /^(ul|ol)$/i.test(dom.parentNode.nodeName)) { - let skip = document.createElement("div"); - skip.appendChild(document.createElement("li")); - return { skip }; - } else if (dom.parentNode.lastChild == dom || safari && /^(tr|table)$/i.test(dom.parentNode.nodeName)) { - return { ignore: true }; - } - } else if (dom.nodeName == "IMG" && dom.getAttribute("mark-placeholder")) { - return { ignore: true }; - } - return null; - } - var isInline = /^(a|abbr|acronym|b|bd[io]|big|br|button|cite|code|data(list)?|del|dfn|em|i|ins|kbd|label|map|mark|meter|output|q|ruby|s|samp|small|span|strong|su[bp]|time|u|tt|var)$/i; - function readDOMChange(view, from, to, typeOver, addedNodes) { - let compositionID = view.input.compositionPendingChanges || (view.composing ? view.input.compositionID : 0); - view.input.compositionPendingChanges = 0; - if (from < 0) { - let origin = view.input.lastSelectionTime > Date.now() - 50 ? view.input.lastSelectionOrigin : null; - let newSel = selectionFromDOM(view, origin); - if (newSel && !view.state.selection.eq(newSel)) { - if (chrome && android && view.input.lastKeyCode === 13 && Date.now() - 100 < view.input.lastKeyCodeTime && view.someProp("handleKeyDown", (f3) => f3(view, keyEvent(13, "Enter")))) - return; - let tr2 = view.state.tr.setSelection(newSel); - if (origin == "pointer") - tr2.setMeta("pointer", true); - else if (origin == "key") - tr2.scrollIntoView(); - if (compositionID) - tr2.setMeta("composition", compositionID); - view.dispatch(tr2); - } - return; - } - let $before = view.state.doc.resolve(from); - let shared = $before.sharedDepth(to); - from = $before.before(shared + 1); - to = view.state.doc.resolve(to).after(shared + 1); - let sel = view.state.selection; - let parse2 = parseBetween(view, from, to); - let doc4 = view.state.doc, compare = doc4.slice(parse2.from, parse2.to); - let preferredPos, preferredSide; - if (view.input.lastKeyCode === 8 && Date.now() - 100 < view.input.lastKeyCodeTime) { - preferredPos = view.state.selection.to; - preferredSide = "end"; - } else { - preferredPos = view.state.selection.from; - preferredSide = "start"; - } - view.input.lastKeyCode = null; - let change = findDiff(compare.content, parse2.doc.content, parse2.from, preferredPos, preferredSide); - if ((ios && view.input.lastIOSEnter > Date.now() - 225 || android) && addedNodes.some((n4) => n4.nodeType == 1 && !isInline.test(n4.nodeName)) && (!change || change.endA >= change.endB) && view.someProp("handleKeyDown", (f3) => f3(view, keyEvent(13, "Enter")))) { - view.input.lastIOSEnter = 0; - return; - } - if (!change) { - if (typeOver && sel instanceof TextSelection && !sel.empty && sel.$head.sameParent(sel.$anchor) && !view.composing && !(parse2.sel && parse2.sel.anchor != parse2.sel.head)) { - change = { start: sel.from, endA: sel.to, endB: sel.to }; + function composeSets(setA, setB, mkSet = false) { + let sections = []; + let insert2 = mkSet ? [] : null; + let a = new SectionIter(setA), b = new SectionIter(setB); + for (let open = false; ; ) { + if (a.done && b.done) { + return insert2 ? ChangeSet.createSet(sections, insert2) : ChangeDesc.create(sections); + } else if (a.ins == 0) { + addSection(sections, a.len, 0, open); + a.next(); + } else if (b.len == 0 && !b.done) { + addSection(sections, 0, b.ins, open); + if (insert2) + addInsert(insert2, sections, b.text); + b.next(); + } else if (a.done || b.done) { + throw new Error("Mismatched change set lengths"); } else { - if (parse2.sel) { - let sel2 = resolveSelection(view, view.state.doc, parse2.sel); - if (sel2 && !sel2.eq(view.state.selection)) { - let tr2 = view.state.tr.setSelection(sel2); - if (compositionID) - tr2.setMeta("composition", compositionID); - view.dispatch(tr2); - } - } - return; - } - } - view.input.domChangeCount++; - if (view.state.selection.from < view.state.selection.to && change.start == change.endB && view.state.selection instanceof TextSelection) { - if (change.start > view.state.selection.from && change.start <= view.state.selection.from + 2 && view.state.selection.from >= parse2.from) { - change.start = view.state.selection.from; - } else if (change.endA < view.state.selection.to && change.endA >= view.state.selection.to - 2 && view.state.selection.to <= parse2.to) { - change.endB += view.state.selection.to - change.endA; - change.endA = view.state.selection.to; - } - } - if (ie && ie_version <= 11 && change.endB == change.start + 1 && change.endA == change.start && change.start > parse2.from && parse2.doc.textBetween(change.start - parse2.from - 1, change.start - parse2.from + 1) == " \xA0") { - change.start--; - change.endA--; - change.endB--; - } - let $from = parse2.doc.resolveNoCache(change.start - parse2.from); - let $to = parse2.doc.resolveNoCache(change.endB - parse2.from); - let $fromA = doc4.resolve(change.start); - let inlineChange = $from.sameParent($to) && $from.parent.inlineContent && $fromA.end() >= change.endA; - let nextSel; - if ((ios && view.input.lastIOSEnter > Date.now() - 225 && (!inlineChange || addedNodes.some((n4) => n4.nodeName == "DIV" || n4.nodeName == "P")) || !inlineChange && $from.pos < parse2.doc.content.size && !$from.sameParent($to) && (nextSel = Selection.findFrom(parse2.doc.resolve($from.pos + 1), 1, true)) && nextSel.head == $to.pos) && view.someProp("handleKeyDown", (f3) => f3(view, keyEvent(13, "Enter")))) { - view.input.lastIOSEnter = 0; - return; - } - if (view.state.selection.anchor > change.start && looksLikeBackspace(doc4, change.start, change.endA, $from, $to) && view.someProp("handleKeyDown", (f3) => f3(view, keyEvent(8, "Backspace")))) { - if (android && chrome) - view.domObserver.suppressSelectionUpdates(); - return; - } - if (chrome && android && change.endB == change.start) - view.input.lastAndroidDelete = Date.now(); - if (android && !inlineChange && $from.start() != $to.start() && $to.parentOffset == 0 && $from.depth == $to.depth && parse2.sel && parse2.sel.anchor == parse2.sel.head && parse2.sel.head == change.endA) { - change.endB -= 2; - $to = parse2.doc.resolveNoCache(change.endB - parse2.from); - setTimeout(() => { - view.someProp("handleKeyDown", function(f3) { - return f3(view, keyEvent(13, "Enter")); - }); - }, 20); - } - let chFrom = change.start, chTo = change.endA; - let tr, storedMarks, markChange; - if (inlineChange) { - if ($from.pos == $to.pos) { - if (ie && ie_version <= 11 && $from.parentOffset == 0) { - view.domObserver.suppressSelectionUpdates(); - setTimeout(() => selectionToDOM(view), 20); - } - tr = view.state.tr.delete(chFrom, chTo); - storedMarks = doc4.resolve(change.start).marksAcross(doc4.resolve(change.endA)); - } else if ( - // Adding or removing a mark - change.endA == change.endB && (markChange = isMarkChange($from.parent.content.cut($from.parentOffset, $to.parentOffset), $fromA.parent.content.cut($fromA.parentOffset, change.endA - $fromA.start()))) - ) { - tr = view.state.tr; - if (markChange.type == "add") - tr.addMark(chFrom, chTo, markChange.mark); - else - tr.removeMark(chFrom, chTo, markChange.mark); - } else if ($from.parent.child($from.index()).isText && $from.index() == $to.index() - ($to.textOffset ? 0 : 1)) { - let text5 = $from.parent.textBetween($from.parentOffset, $to.parentOffset); - if (view.someProp("handleTextInput", (f3) => f3(view, chFrom, chTo, text5))) - return; - tr = view.state.tr.insertText(text5, chFrom, chTo); - } - } - if (!tr) - tr = view.state.tr.replace(chFrom, chTo, parse2.doc.slice(change.start - parse2.from, change.endB - parse2.from)); - if (parse2.sel) { - let sel2 = resolveSelection(view, tr.doc, parse2.sel); - if (sel2 && !(chrome && android && view.composing && sel2.empty && (change.start != change.endB || view.input.lastAndroidDelete < Date.now() - 100) && (sel2.head == chFrom || sel2.head == tr.mapping.map(chTo) - 1) || ie && sel2.empty && sel2.head == chFrom)) - tr.setSelection(sel2); - } - if (storedMarks) - tr.ensureMarks(storedMarks); - if (compositionID) - tr.setMeta("composition", compositionID); - view.dispatch(tr.scrollIntoView()); - } - function resolveSelection(view, doc4, parsedSel) { - if (Math.max(parsedSel.anchor, parsedSel.head) > doc4.content.size) - return null; - return selectionBetween(view, doc4.resolve(parsedSel.anchor), doc4.resolve(parsedSel.head)); - } - function isMarkChange(cur, prev) { - let curMarks = cur.firstChild.marks, prevMarks = prev.firstChild.marks; - let added = curMarks, removed = prevMarks, type, mark, update; - for (let i2 = 0; i2 < prevMarks.length; i2++) - added = prevMarks[i2].removeFromSet(added); - for (let i2 = 0; i2 < curMarks.length; i2++) - removed = curMarks[i2].removeFromSet(removed); - if (added.length == 1 && removed.length == 0) { - mark = added[0]; - type = "add"; - update = (node2) => node2.mark(mark.addToSet(node2.marks)); - } else if (added.length == 0 && removed.length == 1) { - mark = removed[0]; - type = "remove"; - update = (node2) => node2.mark(mark.removeFromSet(node2.marks)); - } else { - return null; - } - let updated = []; - for (let i2 = 0; i2 < prev.childCount; i2++) - updated.push(update(prev.child(i2))); - if (Fragment.from(updated).eq(cur)) - return { mark, type }; - } - function looksLikeBackspace(old, start, end, $newStart, $newEnd) { - if ( - // The content must have shrunk - end - start <= $newEnd.pos - $newStart.pos || // newEnd must point directly at or after the end of the block that newStart points into - skipClosingAndOpening($newStart, true, false) < $newEnd.pos - ) - return false; - let $start = old.resolve(start); - if (!$newStart.parent.isTextblock) { - let after = $start.nodeAfter; - return after != null && end == start + after.nodeSize; - } - if ($start.parentOffset < $start.parent.content.size || !$start.parent.isTextblock) - return false; - let $next = old.resolve(skipClosingAndOpening($start, true, true)); - if (!$next.parent.isTextblock || $next.pos > end || skipClosingAndOpening($next, true, false) < end) - return false; - return $newStart.parent.content.cut($newStart.parentOffset).eq($next.parent.content); - } - function skipClosingAndOpening($pos, fromEnd, mayOpen) { - let depth = $pos.depth, end = fromEnd ? $pos.end() : $pos.pos; - while (depth > 0 && (fromEnd || $pos.indexAfter(depth) == $pos.node(depth).childCount)) { - depth--; - end++; - fromEnd = false; - } - if (mayOpen) { - let next = $pos.node(depth).maybeChild($pos.indexAfter(depth)); - while (next && !next.isLeaf) { - next = next.firstChild; - end++; - } - } - return end; - } - function findDiff(a2, b4, pos, preferredPos, preferredSide) { - let start = a2.findDiffStart(b4, pos); - if (start == null) - return null; - let { a: endA, b: endB } = a2.findDiffEnd(b4, pos + a2.size, pos + b4.size); - if (preferredSide == "end") { - let adjust = Math.max(0, start - Math.min(endA, endB)); - preferredPos -= endA + adjust - start; - } - if (endA < start && a2.size < b4.size) { - let move = preferredPos <= start && preferredPos >= endA ? start - preferredPos : 0; - start -= move; - if (start && start < b4.size && isSurrogatePair(b4.textBetween(start - 1, start + 1))) - start += move ? 1 : -1; - endB = start + (endB - endA); - endA = start; - } else if (endB < start) { - let move = preferredPos <= start && preferredPos >= endB ? start - preferredPos : 0; - start -= move; - if (start && start < a2.size && isSurrogatePair(a2.textBetween(start - 1, start + 1))) - start += move ? 1 : -1; - endA = start + (endA - endB); - endB = start; - } - return { start, endA, endB }; - } - function isSurrogatePair(str) { - if (str.length != 2) - return false; - let a2 = str.charCodeAt(0), b4 = str.charCodeAt(1); - return a2 >= 56320 && a2 <= 57343 && b4 >= 55296 && b4 <= 56319; - } - var EditorView = class { - /** - Create a view. `place` may be a DOM node that the editor should - be appended to, a function that will place it into the document, - or an object whose `mount` property holds the node to use as the - document container. If it is `null`, the editor will not be - added to the document. - */ - constructor(place, props) { - this._root = null; - this.focused = false; - this.trackWrites = null; - this.mounted = false; - this.markCursor = null; - this.cursorWrapper = null; - this.lastSelectedViewDesc = void 0; - this.input = new InputState(); - this.prevDirectPlugins = []; - this.pluginViews = []; - this.requiresGeckoHackNode = false; - this.dragging = null; - this._props = props; - this.state = props.state; - this.directPlugins = props.plugins || []; - this.directPlugins.forEach(checkStateComponent); - this.dispatch = this.dispatch.bind(this); - this.dom = place && place.mount || document.createElement("div"); - if (place) { - if (place.appendChild) - place.appendChild(this.dom); - else if (typeof place == "function") - place(this.dom); - else if (place.mount) - this.mounted = true; - } - this.editable = getEditable(this); - updateCursorWrapper(this); - this.nodeViews = buildNodeViews(this); - this.docView = docViewDesc(this.state.doc, computeDocDeco(this), viewDecorations(this), this.dom, this); - this.domObserver = new DOMObserver(this, (from, to, typeOver, added) => readDOMChange(this, from, to, typeOver, added)); - this.domObserver.start(); - initInput(this); - this.updatePluginViews(); - } - /** - Holds `true` when a - [composition](https://w3c.github.io/uievents/#events-compositionevents) - is active. - */ - get composing() { - return this.input.composing; - } - /** - The view's current [props](https://prosemirror.net/docs/ref/#view.EditorProps). - */ - get props() { - if (this._props.state != this.state) { - let prev = this._props; - this._props = {}; - for (let name in prev) - this._props[name] = prev[name]; - this._props.state = this.state; - } - return this._props; - } - /** - Update the view's props. Will immediately cause an update to - the DOM. - */ - update(props) { - if (props.handleDOMEvents != this._props.handleDOMEvents) - ensureListeners(this); - let prevProps = this._props; - this._props = props; - if (props.plugins) { - props.plugins.forEach(checkStateComponent); - this.directPlugins = props.plugins; - } - this.updateStateInner(props.state, prevProps); - } - /** - Update the view by updating existing props object with the object - given as argument. Equivalent to `view.update(Object.assign({}, - view.props, props))`. - */ - setProps(props) { - let updated = {}; - for (let name in this._props) - updated[name] = this._props[name]; - updated.state = this.state; - for (let name in props) - updated[name] = props[name]; - this.update(updated); - } - /** - Update the editor's `state` prop, without touching any of the - other props. - */ - updateState(state) { - this.updateStateInner(state, this._props); - } - updateStateInner(state, prevProps) { - var _a; - let prev = this.state, redraw = false, updateSel = false; - if (state.storedMarks && this.composing) { - clearComposition(this); - updateSel = true; - } - this.state = state; - let pluginsChanged = prev.plugins != state.plugins || this._props.plugins != prevProps.plugins; - if (pluginsChanged || this._props.plugins != prevProps.plugins || this._props.nodeViews != prevProps.nodeViews) { - let nodeViews = buildNodeViews(this); - if (changedNodeViews(nodeViews, this.nodeViews)) { - this.nodeViews = nodeViews; - redraw = true; - } - } - if (pluginsChanged || prevProps.handleDOMEvents != this._props.handleDOMEvents) { - ensureListeners(this); - } - this.editable = getEditable(this); - updateCursorWrapper(this); - let innerDeco = viewDecorations(this), outerDeco = computeDocDeco(this); - let scroll = prev.plugins != state.plugins && !prev.doc.eq(state.doc) ? "reset" : state.scrollToSelection > prev.scrollToSelection ? "to selection" : "preserve"; - let updateDoc = redraw || !this.docView.matchesNode(state.doc, outerDeco, innerDeco); - if (updateDoc || !state.selection.eq(prev.selection)) - updateSel = true; - let oldScrollPos = scroll == "preserve" && updateSel && this.dom.style.overflowAnchor == null && storeScrollPos(this); - if (updateSel) { - this.domObserver.stop(); - let forceSelUpdate = updateDoc && (ie || chrome) && !this.composing && !prev.selection.empty && !state.selection.empty && selectionContextChanged(prev.selection, state.selection); - if (updateDoc) { - let chromeKludge = chrome ? this.trackWrites = this.domSelectionRange().focusNode : null; - if (this.composing) - this.input.compositionNode = findCompositionNode(this); - if (redraw || !this.docView.update(state.doc, outerDeco, innerDeco, this)) { - this.docView.updateOuterDeco(outerDeco); - this.docView.destroy(); - this.docView = docViewDesc(state.doc, outerDeco, innerDeco, this.dom, this); - } - if (chromeKludge && !this.trackWrites) - forceSelUpdate = true; - } - if (forceSelUpdate || !(this.input.mouseDown && this.domObserver.currentSelection.eq(this.domSelectionRange()) && anchorInRightPlace(this))) { - selectionToDOM(this, forceSelUpdate); + let len = Math.min(a.len2, b.len), sectionLen = sections.length; + if (a.ins == -1) { + let insB = b.ins == -1 ? -1 : b.off ? 0 : b.ins; + addSection(sections, len, insB, open); + if (insert2 && insB) + addInsert(insert2, sections, b.text); + } else if (b.ins == -1) { + addSection(sections, a.off ? 0 : a.len, len, open); + if (insert2) + addInsert(insert2, sections, a.textBit(len)); } else { - syncNodeSelection(this, state.selection); - this.domObserver.setCurSelection(); + addSection(sections, a.off ? 0 : a.len, b.off ? 0 : b.ins, open); + if (insert2 && !b.off) + addInsert(insert2, sections, b.text); } - this.domObserver.start(); + open = (a.ins > len || b.ins >= 0 && b.len > len) && (open || sections.length > sectionLen); + a.forward2(len); + b.forward(len); } - this.updatePluginViews(prev); - if (((_a = this.dragging) === null || _a === void 0 ? void 0 : _a.node) && !prev.doc.eq(state.doc)) - this.updateDraggedNode(this.dragging, prev); - if (scroll == "reset") { - this.dom.scrollTop = 0; - } else if (scroll == "to selection") { - this.scrollToSelection(); - } else if (oldScrollPos) { - resetScrollPos(oldScrollPos); + } + } + var SectionIter = class { + constructor(set) { + this.set = set; + this.i = 0; + this.next(); + } + next() { + let { sections } = this.set; + if (this.i < sections.length) { + this.len = sections[this.i++]; + this.ins = sections[this.i++]; + } else { + this.len = 0; + this.ins = -2; } + this.off = 0; + } + get done() { + return this.ins == -2; + } + get len2() { + return this.ins < 0 ? this.len : this.ins; + } + get text() { + let { inserted } = this.set, index = this.i - 2 >> 1; + return index >= inserted.length ? Text.empty : inserted[index]; + } + textBit(len) { + let { inserted } = this.set, index = this.i - 2 >> 1; + return index >= inserted.length && !len ? Text.empty : inserted[index].slice(this.off, len == null ? void 0 : this.off + len); + } + forward(len) { + if (len == this.len) + this.next(); + else { + this.len -= len; + this.off += len; + } + } + forward2(len) { + if (this.ins == -1) + this.forward(len); + else if (len == this.ins) + this.next(); + else { + this.ins -= len; + this.off += len; + } + } + }; + var SelectionRange = class _SelectionRange { + constructor(from, to, flags) { + this.from = from; + this.to = to; + this.flags = flags; + } + /** + The anchor of the range—the side that doesn't move when you + extend it. + */ + get anchor() { + return this.flags & 32 ? this.to : this.from; + } + /** + The head of the range, which is moved when the range is + [extended](https://codemirror.net/6/docs/ref/#state.SelectionRange.extend). + */ + get head() { + return this.flags & 32 ? this.from : this.to; + } + /** + True when `anchor` and `head` are at the same position. + */ + get empty() { + return this.from == this.to; + } + /** + If this is a cursor that is explicitly associated with the + character on one of its sides, this returns the side. -1 means + the character before its position, 1 the character after, and 0 + means no association. + */ + get assoc() { + return this.flags & 8 ? -1 : this.flags & 16 ? 1 : 0; + } + /** + The bidirectional text level associated with this cursor, if + any. + */ + get bidiLevel() { + let level = this.flags & 7; + return level == 7 ? null : level; + } + /** + The goal column (stored vertical offset) associated with a + cursor. This is used to preserve the vertical position when + [moving](https://codemirror.net/6/docs/ref/#view.EditorView.moveVertically) across + lines of different length. + */ + get goalColumn() { + let value = this.flags >> 6; + return value == 16777215 ? void 0 : value; + } + /** + Map this range through a change, producing a valid range in the + updated document. + */ + map(change, assoc = -1) { + let from, to; + if (this.empty) { + from = to = change.mapPos(this.from, assoc); + } else { + from = change.mapPos(this.from, 1); + to = change.mapPos(this.to, -1); + } + return from == this.from && to == this.to ? this : new _SelectionRange(from, to, this.flags); + } + /** + Extend this range to cover at least `from` to `to`. + */ + extend(from, to = from) { + if (from <= this.anchor && to >= this.anchor) + return EditorSelection.range(from, to); + let head = Math.abs(from - this.anchor) > Math.abs(to - this.anchor) ? from : to; + return EditorSelection.range(this.anchor, head); + } + /** + Compare this range to another range. + */ + eq(other, includeAssoc = false) { + return this.anchor == other.anchor && this.head == other.head && (!includeAssoc || !this.empty || this.assoc == other.assoc); + } + /** + Return a JSON-serializable object representing the range. + */ + toJSON() { + return { anchor: this.anchor, head: this.head }; + } + /** + Convert a JSON representation of a range to a `SelectionRange` + instance. + */ + static fromJSON(json) { + if (!json || typeof json.anchor != "number" || typeof json.head != "number") + throw new RangeError("Invalid JSON representation for SelectionRange"); + return EditorSelection.range(json.anchor, json.head); } /** @internal */ - scrollToSelection() { - let startDOM = this.domSelectionRange().focusNode; - if (this.someProp("handleScrollToSelection", (f3) => f3(this))) ; - else if (this.state.selection instanceof NodeSelection) { - let target = this.docView.domAfterPos(this.state.selection.from); - if (target.nodeType == 1) - scrollRectIntoView(this, target.getBoundingClientRect(), startDOM); - } else { - scrollRectIntoView(this, this.coordsAtPos(this.state.selection.head, 1), startDOM); - } + static create(from, to, flags) { + return new _SelectionRange(from, to, flags); } - destroyPluginViews() { - let view; - while (view = this.pluginViews.pop()) - if (view.destroy) - view.destroy(); - } - updatePluginViews(prevState) { - if (!prevState || prevState.plugins != this.state.plugins || this.directPlugins != this.prevDirectPlugins) { - this.prevDirectPlugins = this.directPlugins; - this.destroyPluginViews(); - for (let i2 = 0; i2 < this.directPlugins.length; i2++) { - let plugin = this.directPlugins[i2]; - if (plugin.spec.view) - this.pluginViews.push(plugin.spec.view(this)); - } - for (let i2 = 0; i2 < this.state.plugins.length; i2++) { - let plugin = this.state.plugins[i2]; - if (plugin.spec.view) - this.pluginViews.push(plugin.spec.view(this)); - } - } else { - for (let i2 = 0; i2 < this.pluginViews.length; i2++) { - let pluginView = this.pluginViews[i2]; - if (pluginView.update) - pluginView.update(this, prevState); - } - } - } - updateDraggedNode(dragging, prev) { - let sel = dragging.node, found2 = -1; - if (this.state.doc.nodeAt(sel.from) == sel.node) { - found2 = sel.from; - } else { - let movedPos = sel.from + (this.state.doc.content.size - prev.doc.content.size); - let moved = movedPos > 0 && this.state.doc.nodeAt(movedPos); - if (moved == sel.node) - found2 = movedPos; - } - this.dragging = new Dragging(dragging.slice, dragging.move, found2 < 0 ? void 0 : NodeSelection.create(this.state.doc, found2)); - } - someProp(propName, f3) { - let prop = this._props && this._props[propName], value; - if (prop != null && (value = f3 ? f3(prop) : prop)) - return value; - for (let i2 = 0; i2 < this.directPlugins.length; i2++) { - let prop2 = this.directPlugins[i2].props[propName]; - if (prop2 != null && (value = f3 ? f3(prop2) : prop2)) - return value; - } - let plugins = this.state.plugins; - if (plugins) - for (let i2 = 0; i2 < plugins.length; i2++) { - let prop2 = plugins[i2].props[propName]; - if (prop2 != null && (value = f3 ? f3(prop2) : prop2)) - return value; - } + }; + var EditorSelection = class _EditorSelection { + constructor(ranges, mainIndex) { + this.ranges = ranges; + this.mainIndex = mainIndex; } /** - Query whether the view has focus. + Map a selection through a change. Used to adjust the selection + position for changes. */ - hasFocus() { - if (ie) { - let node2 = this.root.activeElement; - if (node2 == this.dom) - return true; - if (!node2 || !this.dom.contains(node2)) + map(change, assoc = -1) { + if (change.empty) + return this; + return _EditorSelection.create(this.ranges.map((r) => r.map(change, assoc)), this.mainIndex); + } + /** + Compare this selection to another selection. By default, ranges + are compared only by position. When `includeAssoc` is true, + cursor ranges must also have the same + [`assoc`](https://codemirror.net/6/docs/ref/#state.SelectionRange.assoc) value. + */ + eq(other, includeAssoc = false) { + if (this.ranges.length != other.ranges.length || this.mainIndex != other.mainIndex) + return false; + for (let i = 0; i < this.ranges.length; i++) + if (!this.ranges[i].eq(other.ranges[i], includeAssoc)) return false; - while (node2 && this.dom != node2 && this.dom.contains(node2)) { - if (node2.contentEditable == "false") - return false; - node2 = node2.parentElement; - } - return true; + return true; + } + /** + Get the primary selection range. Usually, you should make sure + your code applies to _all_ ranges, by using methods like + [`changeByRange`](https://codemirror.net/6/docs/ref/#state.EditorState.changeByRange). + */ + get main() { + return this.ranges[this.mainIndex]; + } + /** + Make sure the selection only has one range. Returns a selection + holding only the main range from this selection. + */ + asSingle() { + return this.ranges.length == 1 ? this : new _EditorSelection([this.main], 0); + } + /** + Extend this selection with an extra range. + */ + addRange(range, main = true) { + return _EditorSelection.create([range].concat(this.ranges), main ? 0 : this.mainIndex + 1); + } + /** + Replace a given range with another range, and then normalize the + selection to merge and sort ranges if necessary. + */ + replaceRange(range, which = this.mainIndex) { + let ranges = this.ranges.slice(); + ranges[which] = range; + return _EditorSelection.create(ranges, this.mainIndex); + } + /** + Convert this selection to an object that can be serialized to + JSON. + */ + toJSON() { + return { ranges: this.ranges.map((r) => r.toJSON()), main: this.mainIndex }; + } + /** + Create a selection from a JSON representation. + */ + static fromJSON(json) { + if (!json || !Array.isArray(json.ranges) || typeof json.main != "number" || json.main >= json.ranges.length) + throw new RangeError("Invalid JSON representation for EditorSelection"); + return new _EditorSelection(json.ranges.map((r) => SelectionRange.fromJSON(r)), json.main); + } + /** + Create a selection holding a single range. + */ + static single(anchor, head = anchor) { + return new _EditorSelection([_EditorSelection.range(anchor, head)], 0); + } + /** + Sort and merge the given set of ranges, creating a valid + selection. + */ + static create(ranges, mainIndex = 0) { + if (ranges.length == 0) + throw new RangeError("A selection needs at least one range"); + for (let pos = 0, i = 0; i < ranges.length; i++) { + let range = ranges[i]; + if (range.empty ? range.from <= pos : range.from < pos) + return _EditorSelection.normalized(ranges.slice(), mainIndex); + pos = range.to; } - return this.root.activeElement == this.dom; + return new _EditorSelection(ranges, mainIndex); } /** - Focus the editor. + Create a cursor selection range at the given position. You can + safely ignore the optional arguments in most situations. */ - focus() { - this.domObserver.stop(); - if (this.editable) - focusPreventScroll(this.dom); - selectionToDOM(this); - this.domObserver.start(); + static cursor(pos, assoc = 0, bidiLevel, goalColumn) { + return SelectionRange.create(pos, pos, (assoc == 0 ? 0 : assoc < 0 ? 8 : 16) | (bidiLevel == null ? 7 : Math.min(6, bidiLevel)) | (goalColumn !== null && goalColumn !== void 0 ? goalColumn : 16777215) << 6); } /** - Get the document root in which the editor exists. This will - usually be the top-level `document`, but might be a [shadow - DOM](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Shadow_DOM) - root if the editor is inside one. + Create a selection range. */ - get root() { - let cached = this._root; - if (cached == null) - for (let search2 = this.dom.parentNode; search2; search2 = search2.parentNode) { - if (search2.nodeType == 9 || search2.nodeType == 11 && search2.host) { - if (!search2.getSelection) - Object.getPrototypeOf(search2).getSelection = () => search2.ownerDocument.getSelection(); - return this._root = search2; - } - } - return cached || document; - } - /** - When an existing editor view is moved to a new document or - shadow tree, call this to make it recompute its root. - */ - updateRoot() { - this._root = null; - } - /** - Given a pair of viewport coordinates, return the document - position that corresponds to them. May return null if the given - coordinates aren't inside of the editor. When an object is - returned, its `pos` property is the position nearest to the - coordinates, and its `inside` property holds the position of the - inner node that the position falls inside of, or -1 if it is at - the top level, not in any node. - */ - posAtCoords(coords) { - return posAtCoords(this, coords); - } - /** - Returns the viewport rectangle at a given document position. - `left` and `right` will be the same number, as this returns a - flat cursor-ish rectangle. If the position is between two things - that aren't directly adjacent, `side` determines which element - is used. When < 0, the element before the position is used, - otherwise the element after. - */ - coordsAtPos(pos, side = 1) { - return coordsAtPos(this, pos, side); - } - /** - Find the DOM position that corresponds to the given document - position. When `side` is negative, find the position as close as - possible to the content before the position. When positive, - prefer positions close to the content after the position. When - zero, prefer as shallow a position as possible. - - Note that you should **not** mutate the editor's internal DOM, - only inspect it (and even that is usually not necessary). - */ - domAtPos(pos, side = 0) { - return this.docView.domFromPos(pos, side); - } - /** - Find the DOM node that represents the document node after the - given position. May return `null` when the position doesn't point - in front of a node or if the node is inside an opaque node view. - - This is intended to be able to call things like - `getBoundingClientRect` on that DOM node. Do **not** mutate the - editor DOM directly, or add styling this way, since that will be - immediately overriden by the editor as it redraws the node. - */ - nodeDOM(pos) { - let desc = this.docView.descAt(pos); - return desc ? desc.nodeDOM : null; - } - /** - Find the document position that corresponds to a given DOM - position. (Whenever possible, it is preferable to inspect the - document structure directly, rather than poking around in the - DOM, but sometimes—for example when interpreting an event - target—you don't have a choice.) - - The `bias` parameter can be used to influence which side of a DOM - node to use when the position is inside a leaf node. - */ - posAtDOM(node2, offset, bias = -1) { - let pos = this.docView.posFromDOM(node2, offset, bias); - if (pos == null) - throw new RangeError("DOM position not inside the editor"); - return pos; - } - /** - Find out whether the selection is at the end of a textblock when - moving in a given direction. When, for example, given `"left"`, - it will return true if moving left from the current cursor - position would leave that position's parent textblock. Will apply - to the view's current state by default, but it is possible to - pass a different state. - */ - endOfTextblock(dir, state) { - return endOfTextblock(this, state || this.state, dir); - } - /** - Run the editor's paste logic with the given HTML string. The - `event`, if given, will be passed to the - [`handlePaste`](https://prosemirror.net/docs/ref/#view.EditorProps.handlePaste) hook. - */ - pasteHTML(html3, event) { - return doPaste(this, "", html3, false, event || new ClipboardEvent("paste")); - } - /** - Run the editor's paste logic with the given plain-text input. - */ - pasteText(text5, event) { - return doPaste(this, text5, null, true, event || new ClipboardEvent("paste")); - } - /** - Removes the editor from the DOM and destroys all [node - views](https://prosemirror.net/docs/ref/#view.NodeView). - */ - destroy() { - if (!this.docView) - return; - destroyInput(this); - this.destroyPluginViews(); - if (this.mounted) { - this.docView.update(this.state.doc, [], viewDecorations(this), this); - this.dom.textContent = ""; - } else if (this.dom.parentNode) { - this.dom.parentNode.removeChild(this.dom); - } - this.docView.destroy(); - this.docView = null; - clearReusedRange(); - } - /** - This is true when the view has been - [destroyed](https://prosemirror.net/docs/ref/#view.EditorView.destroy) (and thus should not be - used anymore). - */ - get isDestroyed() { - return this.docView == null; - } - /** - Used for testing. - */ - dispatchEvent(event) { - return dispatchEvent2(this, event); - } - /** - Dispatch a transaction. Will call - [`dispatchTransaction`](https://prosemirror.net/docs/ref/#view.DirectEditorProps.dispatchTransaction) - when given, and otherwise defaults to applying the transaction to - the current state and calling - [`updateState`](https://prosemirror.net/docs/ref/#view.EditorView.updateState) with the result. - This method is bound to the view instance, so that it can be - easily passed around. - */ - dispatch(tr) { - let dispatchTransaction = this._props.dispatchTransaction; - if (dispatchTransaction) - dispatchTransaction.call(this, tr); - else - this.updateState(this.state.apply(tr)); + static range(anchor, head, goalColumn, bidiLevel) { + let flags = (goalColumn !== null && goalColumn !== void 0 ? goalColumn : 16777215) << 6 | (bidiLevel == null ? 7 : Math.min(6, bidiLevel)); + return head < anchor ? SelectionRange.create(head, anchor, 32 | 16 | flags) : SelectionRange.create(anchor, head, (head > anchor ? 8 : 0) | flags); } /** @internal */ - domSelectionRange() { - let sel = this.domSelection(); - return safari && this.root.nodeType === 11 && deepActiveElement(this.dom.ownerDocument) == this.dom && safariShadowSelectionRange(this, sel) || sel; + static normalized(ranges, mainIndex = 0) { + let main = ranges[mainIndex]; + ranges.sort((a, b) => a.from - b.from); + mainIndex = ranges.indexOf(main); + for (let i = 1; i < ranges.length; i++) { + let range = ranges[i], prev = ranges[i - 1]; + if (range.empty ? range.from <= prev.to : range.from < prev.to) { + let from = prev.from, to = Math.max(range.to, prev.to); + if (i <= mainIndex) + mainIndex--; + ranges.splice(--i, 2, range.anchor > range.head ? _EditorSelection.range(to, from) : _EditorSelection.range(from, to)); + } + } + return new _EditorSelection(ranges, mainIndex); + } + }; + function checkSelection(selection, docLength) { + for (let range of selection.ranges) + if (range.to > docLength) + throw new RangeError("Selection points outside of document"); + } + var nextID = 0; + var Facet = class _Facet { + constructor(combine, compareInput, compare2, isStatic, enables) { + this.combine = combine; + this.compareInput = compareInput; + this.compare = compare2; + this.isStatic = isStatic; + this.id = nextID++; + this.default = combine([]); + this.extensions = typeof enables == "function" ? enables(this) : enables; } /** - @internal + Returns a facet reader for this facet, which can be used to + [read](https://codemirror.net/6/docs/ref/#state.EditorState.facet) it but not to define values for it. */ - domSelection() { - return this.root.getSelection(); + get reader() { + return this; } - }; - function computeDocDeco(view) { - let attrs = /* @__PURE__ */ Object.create(null); - attrs.class = "ProseMirror"; - attrs.contenteditable = String(view.editable); - view.someProp("attributes", (value) => { - if (typeof value == "function") - value = value(view.state); - if (value) - for (let attr in value) { - if (attr == "class") - attrs.class += " " + value[attr]; - else if (attr == "style") - attrs.style = (attrs.style ? attrs.style + ";" : "") + value[attr]; - else if (!attrs[attr] && attr != "contenteditable" && attr != "nodeName") - attrs[attr] = String(value[attr]); - } - }); - if (!attrs.translate) - attrs.translate = "no"; - return [Decoration.node(0, view.state.doc.content.size, attrs)]; - } - function updateCursorWrapper(view) { - if (view.markCursor) { - let dom = document.createElement("img"); - dom.className = "ProseMirror-separator"; - dom.setAttribute("mark-placeholder", "true"); - dom.setAttribute("alt", ""); - view.cursorWrapper = { dom, deco: Decoration.widget(view.state.selection.head, dom, { raw: true, marks: view.markCursor }) }; - } else { - view.cursorWrapper = null; - } - } - function getEditable(view) { - return !view.someProp("editable", (value) => value(view.state) === false); - } - function selectionContextChanged(sel1, sel2) { - let depth = Math.min(sel1.$anchor.sharedDepth(sel1.head), sel2.$anchor.sharedDepth(sel2.head)); - return sel1.$anchor.start(depth) != sel2.$anchor.start(depth); - } - function buildNodeViews(view) { - let result = /* @__PURE__ */ Object.create(null); - function add(obj) { - for (let prop in obj) - if (!Object.prototype.hasOwnProperty.call(result, prop)) - result[prop] = obj[prop]; - } - view.someProp("nodeViews", add); - view.someProp("markViews", add); - return result; - } - function changedNodeViews(a2, b4) { - let nA = 0, nB = 0; - for (let prop in a2) { - if (a2[prop] != b4[prop]) - return true; - nA++; - } - for (let _3 in b4) - nB++; - return nA != nB; - } - function checkStateComponent(plugin) { - if (plugin.spec.state || plugin.spec.filterTransaction || plugin.spec.appendTransaction) - throw new RangeError("Plugins passed directly to the view must not have a state component"); - } - - // node_modules/prosemirror-inputrules/dist/index.js - var InputRule = class { - // :: (RegExp, union) /** - Create an input rule. The rule applies when the user typed - something and the text directly in front of the cursor matches - `match`, which should end with `$`. - - The `handler` can be a string, in which case the matched text, or - the first matched group in the regexp, is replaced by that - string. - - Or a it can be a function, which will be called with the match - array produced by - [`RegExp.exec`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/exec), - as well as the start and end of the matched range, and which can - return a [transaction](https://prosemirror.net/docs/ref/#state.Transaction) that describes the - rule's effect, or null to indicate the input was not handled. + Define a new facet. */ - constructor(match, handler, options2 = {}) { - this.match = match; - this.match = match; - this.handler = typeof handler == "string" ? stringHandler(handler) : handler; - this.undoable = options2.undoable !== false; - this.inCode = options2.inCode || false; + static define(config2 = {}) { + return new _Facet(config2.combine || ((a) => a), config2.compareInput || ((a, b) => a === b), config2.compare || (!config2.combine ? sameArray : (a, b) => a === b), !!config2.static, config2.enables); + } + /** + Returns an extension that adds the given value to this facet. + */ + of(value) { + return new FacetProvider([], this, 0, value); + } + /** + Create an extension that computes a value for the facet from a + state. You must take care to declare the parts of the state that + this value depends on, since your function is only called again + for a new state when one of those parts changed. + + In cases where your value depends only on a single field, you'll + want to use the [`from`](https://codemirror.net/6/docs/ref/#state.Facet.from) method instead. + */ + compute(deps, get) { + if (this.isStatic) + throw new Error("Can't compute a static facet"); + return new FacetProvider(deps, this, 1, get); + } + /** + Create an extension that computes zero or more values for this + facet from a state. + */ + computeN(deps, get) { + if (this.isStatic) + throw new Error("Can't compute a static facet"); + return new FacetProvider(deps, this, 2, get); + } + from(field, get) { + if (!get) + get = (x) => x; + return this.compute([field], (state) => get(state.field(field))); } }; - function stringHandler(string3) { - return function(state, match, start, end) { - let insert = string3; - if (match[1]) { - let offset = match[0].lastIndexOf(match[1]); - insert += match[0].slice(offset + match[1].length); - start += offset; - let cutOff = start - end; - if (cutOff > 0) { - insert = match[0].slice(offset - cutOff, offset) + insert; - start = end; - } - } - return state.tr.insertText(insert, start, end); - }; + function sameArray(a, b) { + return a == b || a.length == b.length && a.every((e, i) => e === b[i]); } - var undoInputRule = (state, dispatch) => { - let plugins = state.plugins; - for (let i2 = 0; i2 < plugins.length; i2++) { - let plugin = plugins[i2], undoable; - if (plugin.spec.isInputRules && (undoable = plugin.getState(state))) { - if (dispatch) { - let tr = state.tr, toUndo = undoable.transform; - for (let j6 = toUndo.steps.length - 1; j6 >= 0; j6--) - tr.step(toUndo.steps[j6].invert(toUndo.docs[j6])); - if (undoable.text) { - let marks = tr.doc.resolve(undoable.from).marks(); - tr.replaceWith(undoable.from, undoable.to, state.schema.text(undoable.text, marks)); - } else { - tr.delete(undoable.from, undoable.to); - } - dispatch(tr); - } - return true; - } + var FacetProvider = class { + constructor(dependencies, facet, type, value) { + this.dependencies = dependencies; + this.facet = facet; + this.type = type; + this.value = value; + this.id = nextID++; } - return false; - }; - var emDash = new InputRule(/--$/, "\u2014"); - var ellipsis = new InputRule(/\.\.\.$/, "\u2026"); - var openDoubleQuote = new InputRule(/(?:^|[\s\{\[\(\<'"\u2018\u201C])(")$/, "\u201C"); - var closeDoubleQuote = new InputRule(/"$/, "\u201D"); - var openSingleQuote = new InputRule(/(?:^|[\s\{\[\(\<'"\u2018\u201C])(')$/, "\u2018"); - var closeSingleQuote = new InputRule(/'$/, "\u2019"); - function wrappingInputRule(regexp, nodeType, getAttrs = null, joinPredicate) { - return new InputRule(regexp, (state, match, start, end) => { - let attrs = getAttrs instanceof Function ? getAttrs(match) : getAttrs; - let tr = state.tr.delete(start, end); - let $start = tr.doc.resolve(start), range = $start.blockRange(), wrapping = range && findWrapping(range, nodeType, attrs); - if (!wrapping) - return null; - tr.wrap(range, wrapping); - let before = tr.doc.resolve(start - 1).nodeBefore; - if (before && before.type == nodeType && canJoin(tr.doc, start - 1) && (!joinPredicate || joinPredicate(match, before))) - tr.join(start - 1); - return tr; - }); - } - function textblockTypeInputRule(regexp, nodeType, getAttrs = null) { - return new InputRule(regexp, (state, match, start, end) => { - let $start = state.doc.resolve(start); - let attrs = getAttrs instanceof Function ? getAttrs(match) : getAttrs; - if (!$start.node(-1).canReplaceWith($start.index(-1), $start.indexAfter(-1), nodeType)) - return null; - return state.tr.delete(start, end).setBlockType(start, start, nodeType, attrs); - }); - } - - // node_modules/@milkdown/prose/lib/index.js - var nav2 = typeof navigator != "undefined" ? navigator : null; - var doc3 = typeof document != "undefined" ? document : null; - var agent2 = nav2 && nav2.userAgent || ""; - var ie_edge2 = /Edge\/(\d+)/.exec(agent2); - var ie_upto102 = /MSIE \d/.exec(agent2); - var ie_11up2 = /Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(agent2); - var ie2 = !!(ie_upto102 || ie_11up2 || ie_edge2); - var ie_version2 = ie_upto102 ? document.documentMode : ie_11up2 ? +ie_11up2[1] : ie_edge2 ? +ie_edge2[1] : 0; - var gecko2 = !ie2 && /gecko\/(\d+)/i.test(agent2); - var gecko_version = gecko2 && +(/Firefox\/(\d+)/.exec(agent2) || [0, 0])[1]; - var _chrome2 = !ie2 && /Chrome\/(\d+)/.exec(agent2); - var chrome2 = !!_chrome2; - var chrome_version2 = _chrome2 ? +_chrome2[1] : 0; - var safari2 = !ie2 && !!nav2 && /Apple Computer/.test(nav2.vendor); - var ios2 = safari2 && (/Mobile\/\w+/.test(agent2) || !!nav2 && nav2.maxTouchPoints > 2); - var mac2 = ios2 || (nav2 ? /Mac/.test(nav2.platform) : false); - var android2 = /Android \d/.test(agent2); - var webkit2 = !!doc3 && "webkitFontSmoothing" in doc3.documentElement.style; - var webkit_version2 = webkit2 ? +(/\bAppleWebKit\/(\d+)/.exec(navigator.userAgent) || [0, 0])[1] : 0; - var browser = /* @__PURE__ */ Object.freeze({ - __proto__: null, - android: android2, - chrome: chrome2, - chrome_version: chrome_version2, - gecko: gecko2, - gecko_version, - ie: ie2, - ie_version: ie_version2, - ios: ios2, - mac: mac2, - safari: safari2, - webkit: webkit2, - webkit_version: webkit_version2 - }); - function run(view, from, to, text5, rules, plugin) { - if (view.composing) - return false; - const state = view.state; - const $from = state.doc.resolve(from); - if ($from.parent.type.spec.code) - return false; - const textBefore = $from.parent.textBetween(Math.max(0, $from.parentOffset - 500), $from.parentOffset, void 0, "\uFFFC") + text5; - for (let i2 = 0; i2 < rules.length; i2++) { - const match = rules[i2].match.exec(textBefore); - const tr = match && match[0] && rules[i2].handler(state, match, from - (match[0].length - text5.length), to); - if (!tr) - continue; - view.dispatch(tr.setMeta(plugin, { transform: tr, from, to, text: text5 })); - return true; - } - return false; - } - var customInputRulesKey = new PluginKey("MILKDOWN_CUSTOM_INPUTRULES"); - function customInputRules({ rules }) { - const plugin = new Plugin({ - key: customInputRulesKey, - isInputRules: true, - state: { - init() { - return null; + dynamicSlot(addresses) { + var _a2; + let getter = this.value; + let compare2 = this.facet.compareInput; + let id2 = this.id, idx = addresses[id2] >> 1, multi = this.type == 2; + let depDoc = false, depSel = false, depAddrs = []; + for (let dep of this.dependencies) { + if (dep == "doc") + depDoc = true; + else if (dep == "selection") + depSel = true; + else if ((((_a2 = addresses[dep.id]) !== null && _a2 !== void 0 ? _a2 : 1) & 1) == 0) + depAddrs.push(addresses[dep.id]); + } + return { + create(state) { + state.values[idx] = getter(state); + return 1; }, - apply(tr, prev) { - const stored = tr.getMeta(this); - if (stored) - return stored; - return tr.selectionSet || tr.docChanged ? null : prev; - } - }, - props: { - handleTextInput(view, from, to, text5) { - return run(view, from, to, text5, rules, plugin); - }, - handleDOMEvents: { - compositionend: (view) => { - setTimeout(() => { - const { $cursor } = view.state.selection; - if ($cursor) - run(view, $cursor.pos, $cursor.pos, "", rules, plugin); - }); - return false; - } - }, - handleKeyDown(view, event) { - if (event.key !== "Enter") - return false; - const { $cursor } = view.state.selection; - if ($cursor) - return run(view, $cursor.pos, $cursor.pos, "\n", rules, plugin); - return false; - } - } - }); - return plugin; - } - function markRule(regexp, markType, options2 = {}) { - return new InputRule(regexp, (state, match, start, end) => { - var _a, _b, _c, _d; - const { tr } = state; - const matchLength = match.length; - let group = match[matchLength - 1]; - let fullMatch = match[0]; - let initialStoredMarks = []; - let markEnd = end; - const captured = { - group, - fullMatch, - start, - end - }; - const result = (_a = options2.updateCaptured) == null ? void 0 : _a.call(options2, captured); - Object.assign(captured, result); - ({ group, fullMatch, start, end } = captured); - if (fullMatch === null) - return null; - if ((group == null ? void 0 : group.trim()) === "") - return null; - if (group) { - const startSpaces = fullMatch.search(/\S/); - const textStart = start + fullMatch.indexOf(group); - const textEnd = textStart + group.length; - initialStoredMarks = (_b = tr.storedMarks) != null ? _b : []; - if (textEnd < end) - tr.delete(textEnd, end); - if (textStart > start) - tr.delete(start + startSpaces, textStart); - markEnd = start + startSpaces + group.length; - const attrs = (_c = options2.getAttr) == null ? void 0 : _c.call(options2, match); - tr.addMark(start, markEnd, markType.create(attrs)); - tr.setStoredMarks(initialStoredMarks); - (_d = options2.beforeDispatch) == null ? void 0 : _d.call(options2, { match, start, end, tr }); - } - return tr; - }); - } - function cloneTr(tr) { - return Object.assign(Object.create(tr), tr).setTime(Date.now()); - } - function equalNodeType(nodeType, node2) { - return Array.isArray(nodeType) && nodeType.includes(node2.type) || node2.type === nodeType; - } - function findParentNodeClosestToPos(predicate) { - return ($pos) => { - for (let i2 = $pos.depth; i2 > 0; i2--) { - const node2 = $pos.node(i2); - if (predicate(node2)) { - return { - pos: i2 > 0 ? $pos.before(i2) : 0, - start: $pos.start(i2), - depth: i2, - node: node2 - }; - } - } - return void 0; - }; - } - function findParentNode(predicate) { - return (selection) => { - return findParentNodeClosestToPos(predicate)(selection.$from); - }; - } - function findSelectedNodeOfType(selection, nodeType) { - if (!(selection instanceof NodeSelection)) - return; - const { node: node2, $from } = selection; - if (equalNodeType(nodeType, node2)) - return { node: node2, pos: $from.pos, start: $from.start($from.depth), depth: $from.depth }; - return void 0; - } - - // node_modules/prosemirror-commands/dist/index.js - var deleteSelection = (state, dispatch) => { - if (state.selection.empty) - return false; - if (dispatch) - dispatch(state.tr.deleteSelection().scrollIntoView()); - return true; - }; - function atBlockStart(state, view) { - let { $cursor } = state.selection; - if (!$cursor || (view ? !view.endOfTextblock("backward", state) : $cursor.parentOffset > 0)) - return null; - return $cursor; - } - var joinBackward = (state, dispatch, view) => { - let $cursor = atBlockStart(state, view); - if (!$cursor) - return false; - let $cut = findCutBefore($cursor); - if (!$cut) { - let range = $cursor.blockRange(), target = range && liftTarget(range); - if (target == null) - return false; - if (dispatch) - dispatch(state.tr.lift(range, target).scrollIntoView()); - return true; - } - let before = $cut.nodeBefore; - if (!before.type.spec.isolating && deleteBarrier(state, $cut, dispatch)) - return true; - if ($cursor.parent.content.size == 0 && (textblockAt(before, "end") || NodeSelection.isSelectable(before))) { - let delStep = replaceStep(state.doc, $cursor.before(), $cursor.after(), Slice.empty); - if (delStep && delStep.slice.size < delStep.to - delStep.from) { - if (dispatch) { - let tr = state.tr.step(delStep); - tr.setSelection(textblockAt(before, "end") ? Selection.findFrom(tr.doc.resolve(tr.mapping.map($cut.pos, -1)), -1) : NodeSelection.create(tr.doc, $cut.pos - before.nodeSize)); - dispatch(tr.scrollIntoView()); - } - return true; - } - } - if (before.isAtom && $cut.depth == $cursor.depth - 1) { - if (dispatch) - dispatch(state.tr.delete($cut.pos - before.nodeSize, $cut.pos).scrollIntoView()); - return true; - } - return false; - }; - function textblockAt(node2, side, only = false) { - for (let scan = node2; scan; scan = side == "start" ? scan.firstChild : scan.lastChild) { - if (scan.isTextblock) - return true; - if (only && scan.childCount != 1) - return false; - } - return false; - } - var selectNodeBackward = (state, dispatch, view) => { - let { $head, empty: empty3 } = state.selection, $cut = $head; - if (!empty3) - return false; - if ($head.parent.isTextblock) { - if (view ? !view.endOfTextblock("backward", state) : $head.parentOffset > 0) - return false; - $cut = findCutBefore($head); - } - let node2 = $cut && $cut.nodeBefore; - if (!node2 || !NodeSelection.isSelectable(node2)) - return false; - if (dispatch) - dispatch(state.tr.setSelection(NodeSelection.create(state.doc, $cut.pos - node2.nodeSize)).scrollIntoView()); - return true; - }; - function findCutBefore($pos) { - if (!$pos.parent.type.spec.isolating) - for (let i2 = $pos.depth - 1; i2 >= 0; i2--) { - if ($pos.index(i2) > 0) - return $pos.doc.resolve($pos.before(i2 + 1)); - if ($pos.node(i2).type.spec.isolating) - break; - } - return null; - } - function atBlockEnd(state, view) { - let { $cursor } = state.selection; - if (!$cursor || (view ? !view.endOfTextblock("forward", state) : $cursor.parentOffset < $cursor.parent.content.size)) - return null; - return $cursor; - } - var joinForward = (state, dispatch, view) => { - let $cursor = atBlockEnd(state, view); - if (!$cursor) - return false; - let $cut = findCutAfter($cursor); - if (!$cut) - return false; - let after = $cut.nodeAfter; - if (deleteBarrier(state, $cut, dispatch)) - return true; - if ($cursor.parent.content.size == 0 && (textblockAt(after, "start") || NodeSelection.isSelectable(after))) { - let delStep = replaceStep(state.doc, $cursor.before(), $cursor.after(), Slice.empty); - if (delStep && delStep.slice.size < delStep.to - delStep.from) { - if (dispatch) { - let tr = state.tr.step(delStep); - tr.setSelection(textblockAt(after, "start") ? Selection.findFrom(tr.doc.resolve(tr.mapping.map($cut.pos)), 1) : NodeSelection.create(tr.doc, tr.mapping.map($cut.pos))); - dispatch(tr.scrollIntoView()); - } - return true; - } - } - if (after.isAtom && $cut.depth == $cursor.depth - 1) { - if (dispatch) - dispatch(state.tr.delete($cut.pos, $cut.pos + after.nodeSize).scrollIntoView()); - return true; - } - return false; - }; - var selectNodeForward = (state, dispatch, view) => { - let { $head, empty: empty3 } = state.selection, $cut = $head; - if (!empty3) - return false; - if ($head.parent.isTextblock) { - if (view ? !view.endOfTextblock("forward", state) : $head.parentOffset < $head.parent.content.size) - return false; - $cut = findCutAfter($head); - } - let node2 = $cut && $cut.nodeAfter; - if (!node2 || !NodeSelection.isSelectable(node2)) - return false; - if (dispatch) - dispatch(state.tr.setSelection(NodeSelection.create(state.doc, $cut.pos)).scrollIntoView()); - return true; - }; - function findCutAfter($pos) { - if (!$pos.parent.type.spec.isolating) - for (let i2 = $pos.depth - 1; i2 >= 0; i2--) { - let parent = $pos.node(i2); - if ($pos.index(i2) + 1 < parent.childCount) - return $pos.doc.resolve($pos.after(i2 + 1)); - if (parent.type.spec.isolating) - break; - } - return null; - } - var newlineInCode = (state, dispatch) => { - let { $head, $anchor } = state.selection; - if (!$head.parent.type.spec.code || !$head.sameParent($anchor)) - return false; - if (dispatch) - dispatch(state.tr.insertText("\n").scrollIntoView()); - return true; - }; - function defaultBlockAt(match) { - for (let i2 = 0; i2 < match.edgeCount; i2++) { - let { type } = match.edge(i2); - if (type.isTextblock && !type.hasRequiredAttrs()) - return type; - } - return null; - } - var exitCode = (state, dispatch) => { - let { $head, $anchor } = state.selection; - if (!$head.parent.type.spec.code || !$head.sameParent($anchor)) - return false; - let above = $head.node(-1), after = $head.indexAfter(-1), type = defaultBlockAt(above.contentMatchAt(after)); - if (!type || !above.canReplaceWith(after, after, type)) - return false; - if (dispatch) { - let pos = $head.after(), tr = state.tr.replaceWith(pos, pos, type.createAndFill()); - tr.setSelection(Selection.near(tr.doc.resolve(pos), 1)); - dispatch(tr.scrollIntoView()); - } - return true; - }; - var createParagraphNear = (state, dispatch) => { - let sel = state.selection, { $from, $to } = sel; - if (sel instanceof AllSelection || $from.parent.inlineContent || $to.parent.inlineContent) - return false; - let type = defaultBlockAt($to.parent.contentMatchAt($to.indexAfter())); - if (!type || !type.isTextblock) - return false; - if (dispatch) { - let side = (!$from.parentOffset && $to.index() < $to.parent.childCount ? $from : $to).pos; - let tr = state.tr.insert(side, type.createAndFill()); - tr.setSelection(TextSelection.create(tr.doc, side + 1)); - dispatch(tr.scrollIntoView()); - } - return true; - }; - var liftEmptyBlock = (state, dispatch) => { - let { $cursor } = state.selection; - if (!$cursor || $cursor.parent.content.size) - return false; - if ($cursor.depth > 1 && $cursor.after() != $cursor.end(-1)) { - let before = $cursor.before(); - if (canSplit(state.doc, before)) { - if (dispatch) - dispatch(state.tr.split(before).scrollIntoView()); - return true; - } - } - let range = $cursor.blockRange(), target = range && liftTarget(range); - if (target == null) - return false; - if (dispatch) - dispatch(state.tr.lift(range, target).scrollIntoView()); - return true; - }; - function splitBlockAs(splitNode) { - return (state, dispatch) => { - let { $from, $to } = state.selection; - if (state.selection instanceof NodeSelection && state.selection.node.isBlock) { - if (!$from.parentOffset || !canSplit(state.doc, $from.pos)) - return false; - if (dispatch) - dispatch(state.tr.split($from.pos).scrollIntoView()); - return true; - } - if (!$from.parent.isBlock) - return false; - if (dispatch) { - let atEnd = $to.parentOffset == $to.parent.content.size; - let tr = state.tr; - if (state.selection instanceof TextSelection || state.selection instanceof AllSelection) - tr.deleteSelection(); - let deflt = $from.depth == 0 ? null : defaultBlockAt($from.node(-1).contentMatchAt($from.indexAfter(-1))); - let splitType = splitNode && splitNode($to.parent, atEnd); - let types = splitType ? [splitType] : atEnd && deflt ? [{ type: deflt }] : void 0; - let can = canSplit(tr.doc, tr.mapping.map($from.pos), 1, types); - if (!types && !can && canSplit(tr.doc, tr.mapping.map($from.pos), 1, deflt ? [{ type: deflt }] : void 0)) { - if (deflt) - types = [{ type: deflt }]; - can = true; - } - if (can) { - tr.split(tr.mapping.map($from.pos), 1, types); - if (!atEnd && !$from.parentOffset && $from.parent.type != deflt) { - let first = tr.mapping.map($from.before()), $first = tr.doc.resolve(first); - if (deflt && $from.node(-1).canReplaceWith($first.index(), $first.index() + 1, deflt)) - tr.setNodeMarkup(tr.mapping.map($from.before()), deflt); - } - } - dispatch(tr.scrollIntoView()); - } - return true; - }; - } - var splitBlock = splitBlockAs(); - var selectAll = (state, dispatch) => { - if (dispatch) - dispatch(state.tr.setSelection(new AllSelection(state.doc))); - return true; - }; - function joinMaybeClear(state, $pos, dispatch) { - let before = $pos.nodeBefore, after = $pos.nodeAfter, index2 = $pos.index(); - if (!before || !after || !before.type.compatibleContent(after.type)) - return false; - if (!before.content.size && $pos.parent.canReplace(index2 - 1, index2)) { - if (dispatch) - dispatch(state.tr.delete($pos.pos - before.nodeSize, $pos.pos).scrollIntoView()); - return true; - } - if (!$pos.parent.canReplace(index2, index2 + 1) || !(after.isTextblock || canJoin(state.doc, $pos.pos))) - return false; - if (dispatch) - dispatch(state.tr.clearIncompatible($pos.pos, before.type, before.contentMatchAt(before.childCount)).join($pos.pos).scrollIntoView()); - return true; - } - function deleteBarrier(state, $cut, dispatch) { - let before = $cut.nodeBefore, after = $cut.nodeAfter, conn, match; - if (before.type.spec.isolating || after.type.spec.isolating) - return false; - if (joinMaybeClear(state, $cut, dispatch)) - return true; - let canDelAfter = $cut.parent.canReplace($cut.index(), $cut.index() + 1); - if (canDelAfter && (conn = (match = before.contentMatchAt(before.childCount)).findWrapping(after.type)) && match.matchType(conn[0] || after.type).validEnd) { - if (dispatch) { - let end = $cut.pos + after.nodeSize, wrap3 = Fragment.empty; - for (let i2 = conn.length - 1; i2 >= 0; i2--) - wrap3 = Fragment.from(conn[i2].create(null, wrap3)); - wrap3 = Fragment.from(before.copy(wrap3)); - let tr = state.tr.step(new ReplaceAroundStep($cut.pos - 1, end, $cut.pos, end, new Slice(wrap3, 1, 0), conn.length, true)); - let joinAt = end + 2 * conn.length; - if (canJoin(tr.doc, joinAt)) - tr.join(joinAt); - dispatch(tr.scrollIntoView()); - } - return true; - } - let selAfter = Selection.findFrom($cut, 1); - let range = selAfter && selAfter.$from.blockRange(selAfter.$to), target = range && liftTarget(range); - if (target != null && target >= $cut.depth) { - if (dispatch) - dispatch(state.tr.lift(range, target).scrollIntoView()); - return true; - } - if (canDelAfter && textblockAt(after, "start", true) && textblockAt(before, "end")) { - let at4 = before, wrap3 = []; - for (; ; ) { - wrap3.push(at4); - if (at4.isTextblock) - break; - at4 = at4.lastChild; - } - let afterText = after, afterDepth = 1; - for (; !afterText.isTextblock; afterText = afterText.firstChild) - afterDepth++; - if (at4.canReplace(at4.childCount, at4.childCount, afterText.content)) { - if (dispatch) { - let end = Fragment.empty; - for (let i2 = wrap3.length - 1; i2 >= 0; i2--) - end = Fragment.from(wrap3[i2].copy(end)); - let tr = state.tr.step(new ReplaceAroundStep($cut.pos - wrap3.length, $cut.pos + after.nodeSize, $cut.pos + afterDepth, $cut.pos + after.nodeSize - afterDepth, new Slice(end, wrap3.length, 0), 0, true)); - dispatch(tr.scrollIntoView()); - } - return true; - } - } - return false; - } - function selectTextblockSide(side) { - return function(state, dispatch) { - let sel = state.selection, $pos = side < 0 ? sel.$from : sel.$to; - let depth = $pos.depth; - while ($pos.node(depth).isInline) { - if (!depth) - return false; - depth--; - } - if (!$pos.node(depth).isTextblock) - return false; - if (dispatch) - dispatch(state.tr.setSelection(TextSelection.create(state.doc, side < 0 ? $pos.start(depth) : $pos.end(depth)))); - return true; - }; - } - var selectTextblockStart = selectTextblockSide(-1); - var selectTextblockEnd = selectTextblockSide(1); - function wrapIn(nodeType, attrs = null) { - return function(state, dispatch) { - let { $from, $to } = state.selection; - let range = $from.blockRange($to), wrapping = range && findWrapping(range, nodeType, attrs); - if (!wrapping) - return false; - if (dispatch) - dispatch(state.tr.wrap(range, wrapping).scrollIntoView()); - return true; - }; - } - function setBlockType2(nodeType, attrs = null) { - return function(state, dispatch) { - let applicable = false; - for (let i2 = 0; i2 < state.selection.ranges.length && !applicable; i2++) { - let { $from: { pos: from }, $to: { pos: to } } = state.selection.ranges[i2]; - state.doc.nodesBetween(from, to, (node2, pos) => { - if (applicable) - return false; - if (!node2.isTextblock || node2.hasMarkup(nodeType, attrs)) - return; - if (node2.type == nodeType) { - applicable = true; - } else { - let $pos = state.doc.resolve(pos), index2 = $pos.index(); - applicable = $pos.parent.canReplaceWith(index2, index2 + 1, nodeType); - } - }); - } - if (!applicable) - return false; - if (dispatch) { - let tr = state.tr; - for (let i2 = 0; i2 < state.selection.ranges.length; i2++) { - let { $from: { pos: from }, $to: { pos: to } } = state.selection.ranges[i2]; - tr.setBlockType(from, to, nodeType, attrs); - } - dispatch(tr.scrollIntoView()); - } - return true; - }; - } - function markApplies(doc4, ranges, type) { - for (let i2 = 0; i2 < ranges.length; i2++) { - let { $from, $to } = ranges[i2]; - let can = $from.depth == 0 ? doc4.inlineContent && doc4.type.allowsMarkType(type) : false; - doc4.nodesBetween($from.pos, $to.pos, (node2) => { - if (can) - return false; - can = node2.inlineContent && node2.type.allowsMarkType(type); - }); - if (can) - return true; - } - return false; - } - function toggleMark(markType, attrs = null) { - return function(state, dispatch) { - let { empty: empty3, $cursor, ranges } = state.selection; - if (empty3 && !$cursor || !markApplies(state.doc, ranges, markType)) - return false; - if (dispatch) { - if ($cursor) { - if (markType.isInSet(state.storedMarks || $cursor.marks())) - dispatch(state.tr.removeStoredMark(markType)); - else - dispatch(state.tr.addStoredMark(markType.create(attrs))); - } else { - let has = false, tr = state.tr; - for (let i2 = 0; !has && i2 < ranges.length; i2++) { - let { $from, $to } = ranges[i2]; - has = state.doc.rangeHasMark($from.pos, $to.pos, markType); - } - for (let i2 = 0; i2 < ranges.length; i2++) { - let { $from, $to } = ranges[i2]; - if (has) { - tr.removeMark($from.pos, $to.pos, markType); - } else { - let from = $from.pos, to = $to.pos, start = $from.nodeAfter, end = $to.nodeBefore; - let spaceStart = start && start.isText ? /^\s*/.exec(start.text)[0].length : 0; - let spaceEnd = end && end.isText ? /\s*$/.exec(end.text)[0].length : 0; - if (from + spaceStart < to) { - from += spaceStart; - to -= spaceEnd; - } - tr.addMark(from, to, markType.create(attrs)); + update(state, tr) { + if (depDoc && tr.docChanged || depSel && (tr.docChanged || tr.selection) || ensureAll(state, depAddrs)) { + let newVal = getter(state); + if (multi ? !compareArray(newVal, state.values[idx], compare2) : !compare2(newVal, state.values[idx])) { + state.values[idx] = newVal; + return 1; } } - dispatch(tr.scrollIntoView()); + return 0; + }, + reconfigure: (state, oldState) => { + let newVal, oldAddr = oldState.config.address[id2]; + if (oldAddr != null) { + let oldVal = getAddr(oldState, oldAddr); + if (this.dependencies.every((dep) => { + return dep instanceof Facet ? oldState.facet(dep) === state.facet(dep) : dep instanceof StateField ? oldState.field(dep, false) == state.field(dep, false) : true; + }) || (multi ? compareArray(newVal = getter(state), oldVal, compare2) : compare2(newVal = getter(state), oldVal))) { + state.values[idx] = oldVal; + return 0; + } + } else { + newVal = getter(state); + } + state.values[idx] = newVal; + return 1; + } + }; + } + }; + function compareArray(a, b, compare2) { + if (a.length != b.length) + return false; + for (let i = 0; i < a.length; i++) + if (!compare2(a[i], b[i])) + return false; + return true; + } + function ensureAll(state, addrs) { + let changed = false; + for (let addr of addrs) + if (ensureAddr(state, addr) & 1) + changed = true; + return changed; + } + function dynamicFacetSlot(addresses, facet, providers) { + let providerAddrs = providers.map((p) => addresses[p.id]); + let providerTypes = providers.map((p) => p.type); + let dynamic = providerAddrs.filter((p) => !(p & 1)); + let idx = addresses[facet.id] >> 1; + function get(state) { + let values2 = []; + for (let i = 0; i < providerAddrs.length; i++) { + let value = getAddr(state, providerAddrs[i]); + if (providerTypes[i] == 2) + for (let val of value) + values2.push(val); + else + values2.push(value); + } + return facet.combine(values2); + } + return { + create(state) { + for (let addr of providerAddrs) + ensureAddr(state, addr); + state.values[idx] = get(state); + return 1; + }, + update(state, tr) { + if (!ensureAll(state, dynamic)) + return 0; + let value = get(state); + if (facet.compare(value, state.values[idx])) + return 0; + state.values[idx] = value; + return 1; + }, + reconfigure(state, oldState) { + let depChanged = ensureAll(state, providerAddrs); + let oldProviders = oldState.config.facets[facet.id], oldValue = oldState.facet(facet); + if (oldProviders && !depChanged && sameArray(providers, oldProviders)) { + state.values[idx] = oldValue; + return 0; + } + let value = get(state); + if (facet.compare(value, oldValue)) { + state.values[idx] = oldValue; + return 0; + } + state.values[idx] = value; + return 1; + } + }; + } + var initField = /* @__PURE__ */ Facet.define({ static: true }); + var StateField = class _StateField { + constructor(id2, createF, updateF, compareF, spec) { + this.id = id2; + this.createF = createF; + this.updateF = updateF; + this.compareF = compareF; + this.spec = spec; + this.provides = void 0; + } + /** + Define a state field. + */ + static define(config2) { + let field = new _StateField(nextID++, config2.create, config2.update, config2.compare || ((a, b) => a === b), config2); + if (config2.provide) + field.provides = config2.provide(field); + return field; + } + create(state) { + let init = state.facet(initField).find((i) => i.field == this); + return ((init === null || init === void 0 ? void 0 : init.create) || this.createF)(state); + } + /** + @internal + */ + slot(addresses) { + let idx = addresses[this.id] >> 1; + return { + create: (state) => { + state.values[idx] = this.create(state); + return 1; + }, + update: (state, tr) => { + let oldVal = state.values[idx]; + let value = this.updateF(oldVal, tr); + if (this.compareF(oldVal, value)) + return 0; + state.values[idx] = value; + return 1; + }, + reconfigure: (state, oldState) => { + if (oldState.config.address[this.id] != null) { + state.values[idx] = oldState.field(this); + return 0; + } + state.values[idx] = this.create(state); + return 1; + } + }; + } + /** + Returns an extension that enables this field and overrides the + way it is initialized. Can be useful when you need to provide a + non-default starting value for the field. + */ + init(create) { + return [this, initField.of({ field: this, create })]; + } + /** + State field instances can be used as + [`Extension`](https://codemirror.net/6/docs/ref/#state.Extension) values to enable the field in a + given state. + */ + get extension() { + return this; + } + }; + var Prec_ = { lowest: 4, low: 3, default: 2, high: 1, highest: 0 }; + function prec(value) { + return (ext) => new PrecExtension(ext, value); + } + var Prec = { + /** + The highest precedence level, for extensions that should end up + near the start of the precedence ordering. + */ + highest: /* @__PURE__ */ prec(Prec_.highest), + /** + A higher-than-default precedence, for extensions that should + come before those with default precedence. + */ + high: /* @__PURE__ */ prec(Prec_.high), + /** + The default precedence, which is also used for extensions + without an explicit precedence. + */ + default: /* @__PURE__ */ prec(Prec_.default), + /** + A lower-than-default precedence. + */ + low: /* @__PURE__ */ prec(Prec_.low), + /** + The lowest precedence level. Meant for things that should end up + near the end of the extension order. + */ + lowest: /* @__PURE__ */ prec(Prec_.lowest) + }; + var PrecExtension = class { + constructor(inner, prec2) { + this.inner = inner; + this.prec = prec2; + } + }; + var Compartment = class _Compartment { + /** + Create an instance of this compartment to add to your [state + configuration](https://codemirror.net/6/docs/ref/#state.EditorStateConfig.extensions). + */ + of(ext) { + return new CompartmentInstance(this, ext); + } + /** + Create an [effect](https://codemirror.net/6/docs/ref/#state.TransactionSpec.effects) that + reconfigures this compartment. + */ + reconfigure(content2) { + return _Compartment.reconfigure.of({ compartment: this, extension: content2 }); + } + /** + Get the current content of the compartment in the state, or + `undefined` if it isn't present. + */ + get(state) { + return state.config.compartments.get(this); + } + }; + var CompartmentInstance = class { + constructor(compartment, inner) { + this.compartment = compartment; + this.inner = inner; + } + }; + var Configuration = class _Configuration { + constructor(base2, compartments, dynamicSlots, address, staticValues, facets) { + this.base = base2; + this.compartments = compartments; + this.dynamicSlots = dynamicSlots; + this.address = address; + this.staticValues = staticValues; + this.facets = facets; + this.statusTemplate = []; + while (this.statusTemplate.length < dynamicSlots.length) + this.statusTemplate.push( + 0 + /* SlotStatus.Unresolved */ + ); + } + staticFacet(facet) { + let addr = this.address[facet.id]; + return addr == null ? facet.default : this.staticValues[addr >> 1]; + } + static resolve(base2, compartments, oldState) { + let fields = []; + let facets = /* @__PURE__ */ Object.create(null); + let newCompartments = /* @__PURE__ */ new Map(); + for (let ext of flatten(base2, compartments, newCompartments)) { + if (ext instanceof StateField) + fields.push(ext); + else + (facets[ext.facet.id] || (facets[ext.facet.id] = [])).push(ext); + } + let address = /* @__PURE__ */ Object.create(null); + let staticValues = []; + let dynamicSlots = []; + for (let field of fields) { + address[field.id] = dynamicSlots.length << 1; + dynamicSlots.push((a) => field.slot(a)); + } + let oldFacets = oldState === null || oldState === void 0 ? void 0 : oldState.config.facets; + for (let id2 in facets) { + let providers = facets[id2], facet = providers[0].facet; + let oldProviders = oldFacets && oldFacets[id2] || []; + if (providers.every( + (p) => p.type == 0 + /* Provider.Static */ + )) { + address[facet.id] = staticValues.length << 1 | 1; + if (sameArray(oldProviders, providers)) { + staticValues.push(oldState.facet(facet)); + } else { + let value = facet.combine(providers.map((p) => p.value)); + staticValues.push(oldState && facet.compare(value, oldState.facet(facet)) ? oldState.facet(facet) : value); + } + } else { + for (let p of providers) { + if (p.type == 0) { + address[p.id] = staticValues.length << 1 | 1; + staticValues.push(p.value); + } else { + address[p.id] = dynamicSlots.length << 1; + dynamicSlots.push((a) => p.dynamicSlot(a)); + } + } + address[facet.id] = dynamicSlots.length << 1; + dynamicSlots.push((a) => dynamicFacetSlot(a, facet, providers)); } } - return true; + let dynamic = dynamicSlots.map((f) => f(address)); + return new _Configuration(base2, newCompartments, dynamic, address, staticValues, facets); + } + }; + function flatten(extension, compartments, newCompartments) { + let result = [[], [], [], [], []]; + let seen = /* @__PURE__ */ new Map(); + function inner(ext, prec2) { + let known = seen.get(ext); + if (known != null) { + if (known <= prec2) + return; + let found = result[known].indexOf(ext); + if (found > -1) + result[known].splice(found, 1); + if (ext instanceof CompartmentInstance) + newCompartments.delete(ext.compartment); + } + seen.set(ext, prec2); + if (Array.isArray(ext)) { + for (let e of ext) + inner(e, prec2); + } else if (ext instanceof CompartmentInstance) { + if (newCompartments.has(ext.compartment)) + throw new RangeError(`Duplicate use of compartment in extensions`); + let content2 = compartments.get(ext.compartment) || ext.inner; + newCompartments.set(ext.compartment, content2); + inner(content2, prec2); + } else if (ext instanceof PrecExtension) { + inner(ext.inner, ext.prec); + } else if (ext instanceof StateField) { + result[prec2].push(ext); + if (ext.provides) + inner(ext.provides, prec2); + } else if (ext instanceof FacetProvider) { + result[prec2].push(ext); + if (ext.facet.extensions) + inner(ext.facet.extensions, Prec_.default); + } else { + let content2 = ext.extension; + if (!content2) + throw new Error(`Unrecognized extension value in extension set (${ext}). This sometimes happens because multiple instances of @codemirror/state are loaded, breaking instanceof checks.`); + inner(content2, prec2); + } + } + inner(extension, Prec_.default); + return result.reduce((a, b) => a.concat(b)); + } + function ensureAddr(state, addr) { + if (addr & 1) + return 2; + let idx = addr >> 1; + let status = state.status[idx]; + if (status == 4) + throw new Error("Cyclic dependency between fields and/or facets"); + if (status & 2) + return status; + state.status[idx] = 4; + let changed = state.computeSlot(state, state.config.dynamicSlots[idx]); + return state.status[idx] = 2 | changed; + } + function getAddr(state, addr) { + return addr & 1 ? state.config.staticValues[addr >> 1] : state.values[addr >> 1]; + } + var languageData = /* @__PURE__ */ Facet.define(); + var allowMultipleSelections = /* @__PURE__ */ Facet.define({ + combine: (values2) => values2.some((v) => v), + static: true + }); + var lineSeparator = /* @__PURE__ */ Facet.define({ + combine: (values2) => values2.length ? values2[0] : void 0, + static: true + }); + var changeFilter = /* @__PURE__ */ Facet.define(); + var transactionFilter = /* @__PURE__ */ Facet.define(); + var transactionExtender = /* @__PURE__ */ Facet.define(); + var readOnly = /* @__PURE__ */ Facet.define({ + combine: (values2) => values2.length ? values2[0] : false + }); + var Annotation = class { + /** + @internal + */ + constructor(type, value) { + this.type = type; + this.value = value; + } + /** + Define a new type of annotation. + */ + static define() { + return new AnnotationType(); + } + }; + var AnnotationType = class { + /** + Create an instance of this annotation. + */ + of(value) { + return new Annotation(this, value); + } + }; + var StateEffectType = class { + /** + @internal + */ + constructor(map) { + this.map = map; + } + /** + Create a [state effect](https://codemirror.net/6/docs/ref/#state.StateEffect) instance of this + type. + */ + of(value) { + return new StateEffect(this, value); + } + }; + var StateEffect = class _StateEffect { + /** + @internal + */ + constructor(type, value) { + this.type = type; + this.value = value; + } + /** + Map this effect through a position mapping. Will return + `undefined` when that ends up deleting the effect. + */ + map(mapping) { + let mapped = this.type.map(this.value, mapping); + return mapped === void 0 ? void 0 : mapped == this.value ? this : new _StateEffect(this.type, mapped); + } + /** + Tells you whether this effect object is of a given + [type](https://codemirror.net/6/docs/ref/#state.StateEffectType). + */ + is(type) { + return this.type == type; + } + /** + Define a new effect type. The type parameter indicates the type + of values that his effect holds. It should be a type that + doesn't include `undefined`, since that is used in + [mapping](https://codemirror.net/6/docs/ref/#state.StateEffect.map) to indicate that an effect is + removed. + */ + static define(spec = {}) { + return new StateEffectType(spec.map || ((v) => v)); + } + /** + Map an array of effects through a change set. + */ + static mapEffects(effects, mapping) { + if (!effects.length) + return effects; + let result = []; + for (let effect of effects) { + let mapped = effect.map(mapping); + if (mapped) + result.push(mapped); + } + return result; + } + }; + StateEffect.reconfigure = /* @__PURE__ */ StateEffect.define(); + StateEffect.appendConfig = /* @__PURE__ */ StateEffect.define(); + var Transaction = class _Transaction { + constructor(startState, changes, selection, effects, annotations, scrollIntoView3) { + this.startState = startState; + this.changes = changes; + this.selection = selection; + this.effects = effects; + this.annotations = annotations; + this.scrollIntoView = scrollIntoView3; + this._doc = null; + this._state = null; + if (selection) + checkSelection(selection, changes.newLength); + if (!annotations.some((a) => a.type == _Transaction.time)) + this.annotations = annotations.concat(_Transaction.time.of(Date.now())); + } + /** + @internal + */ + static create(startState, changes, selection, effects, annotations, scrollIntoView3) { + return new _Transaction(startState, changes, selection, effects, annotations, scrollIntoView3); + } + /** + The new document produced by the transaction. Contrary to + [`.state`](https://codemirror.net/6/docs/ref/#state.Transaction.state)`.doc`, accessing this won't + force the entire new state to be computed right away, so it is + recommended that [transaction + filters](https://codemirror.net/6/docs/ref/#state.EditorState^transactionFilter) use this getter + when they need to look at the new document. + */ + get newDoc() { + return this._doc || (this._doc = this.changes.apply(this.startState.doc)); + } + /** + The new selection produced by the transaction. If + [`this.selection`](https://codemirror.net/6/docs/ref/#state.Transaction.selection) is undefined, + this will [map](https://codemirror.net/6/docs/ref/#state.EditorSelection.map) the start state's + current selection through the changes made by the transaction. + */ + get newSelection() { + return this.selection || this.startState.selection.map(this.changes); + } + /** + The new state created by the transaction. Computed on demand + (but retained for subsequent access), so it is recommended not to + access it in [transaction + filters](https://codemirror.net/6/docs/ref/#state.EditorState^transactionFilter) when possible. + */ + get state() { + if (!this._state) + this.startState.applyTransaction(this); + return this._state; + } + /** + Get the value of the given annotation type, if any. + */ + annotation(type) { + for (let ann of this.annotations) + if (ann.type == type) + return ann.value; + return void 0; + } + /** + Indicates whether the transaction changed the document. + */ + get docChanged() { + return !this.changes.empty; + } + /** + Indicates whether this transaction reconfigures the state + (through a [configuration compartment](https://codemirror.net/6/docs/ref/#state.Compartment) or + with a top-level configuration + [effect](https://codemirror.net/6/docs/ref/#state.StateEffect^reconfigure). + */ + get reconfigured() { + return this.startState.config != this.state.config; + } + /** + Returns true if the transaction has a [user + event](https://codemirror.net/6/docs/ref/#state.Transaction^userEvent) annotation that is equal to + or more specific than `event`. For example, if the transaction + has `"select.pointer"` as user event, `"select"` and + `"select.pointer"` will match it. + */ + isUserEvent(event) { + let e = this.annotation(_Transaction.userEvent); + return !!(e && (e == event || e.length > event.length && e.slice(0, event.length) == event && e[event.length] == ".")); + } + }; + Transaction.time = /* @__PURE__ */ Annotation.define(); + Transaction.userEvent = /* @__PURE__ */ Annotation.define(); + Transaction.addToHistory = /* @__PURE__ */ Annotation.define(); + Transaction.remote = /* @__PURE__ */ Annotation.define(); + function joinRanges(a, b) { + let result = []; + for (let iA = 0, iB = 0; ; ) { + let from, to; + if (iA < a.length && (iB == b.length || b[iB] >= a[iA])) { + from = a[iA++]; + to = a[iA++]; + } else if (iB < b.length) { + from = b[iB++]; + to = b[iB++]; + } else + return result; + if (!result.length || result[result.length - 1] < from) + result.push(from, to); + else if (result[result.length - 1] < to) + result[result.length - 1] = to; + } + } + function mergeTransaction(a, b, sequential) { + var _a2; + let mapForA, mapForB, changes; + if (sequential) { + mapForA = b.changes; + mapForB = ChangeSet.empty(b.changes.length); + changes = a.changes.compose(b.changes); + } else { + mapForA = b.changes.map(a.changes); + mapForB = a.changes.mapDesc(b.changes, true); + changes = a.changes.compose(mapForA); + } + return { + changes, + selection: b.selection ? b.selection.map(mapForB) : (_a2 = a.selection) === null || _a2 === void 0 ? void 0 : _a2.map(mapForA), + effects: StateEffect.mapEffects(a.effects, mapForA).concat(StateEffect.mapEffects(b.effects, mapForB)), + annotations: a.annotations.length ? a.annotations.concat(b.annotations) : b.annotations, + scrollIntoView: a.scrollIntoView || b.scrollIntoView }; } - function chainCommands(...commands) { - return function(state, dispatch, view) { - for (let i2 = 0; i2 < commands.length; i2++) - if (commands[i2](state, dispatch, view)) + function resolveTransactionInner(state, spec, docSize) { + let sel = spec.selection, annotations = asArray(spec.annotations); + if (spec.userEvent) + annotations = annotations.concat(Transaction.userEvent.of(spec.userEvent)); + return { + changes: spec.changes instanceof ChangeSet ? spec.changes : ChangeSet.of(spec.changes || [], docSize, state.facet(lineSeparator)), + selection: sel && (sel instanceof EditorSelection ? sel : EditorSelection.single(sel.anchor, sel.head)), + effects: asArray(spec.effects), + annotations, + scrollIntoView: !!spec.scrollIntoView + }; + } + function resolveTransaction(state, specs, filter) { + let s = resolveTransactionInner(state, specs.length ? specs[0] : {}, state.doc.length); + if (specs.length && specs[0].filter === false) + filter = false; + for (let i = 1; i < specs.length; i++) { + if (specs[i].filter === false) + filter = false; + let seq = !!specs[i].sequential; + s = mergeTransaction(s, resolveTransactionInner(state, specs[i], seq ? s.changes.newLength : state.doc.length), seq); + } + let tr = Transaction.create(state, s.changes, s.selection, s.effects, s.annotations, s.scrollIntoView); + return extendTransaction(filter ? filterTransaction(tr) : tr); + } + function filterTransaction(tr) { + let state = tr.startState; + let result = true; + for (let filter of state.facet(changeFilter)) { + let value = filter(tr); + if (value === false) { + result = false; + break; + } + if (Array.isArray(value)) + result = result === true ? value : joinRanges(result, value); + } + if (result !== true) { + let changes, back; + if (result === false) { + back = tr.changes.invertedDesc; + changes = ChangeSet.empty(state.doc.length); + } else { + let filtered = tr.changes.filter(result); + changes = filtered.changes; + back = filtered.filtered.mapDesc(filtered.changes).invertedDesc; + } + tr = Transaction.create(state, changes, tr.selection && tr.selection.map(back), StateEffect.mapEffects(tr.effects, back), tr.annotations, tr.scrollIntoView); + } + let filters = state.facet(transactionFilter); + for (let i = filters.length - 1; i >= 0; i--) { + let filtered = filters[i](tr); + if (filtered instanceof Transaction) + tr = filtered; + else if (Array.isArray(filtered) && filtered.length == 1 && filtered[0] instanceof Transaction) + tr = filtered[0]; + else + tr = resolveTransaction(state, asArray(filtered), false); + } + return tr; + } + function extendTransaction(tr) { + let state = tr.startState, extenders = state.facet(transactionExtender), spec = tr; + for (let i = extenders.length - 1; i >= 0; i--) { + let extension = extenders[i](tr); + if (extension && Object.keys(extension).length) + spec = mergeTransaction(spec, resolveTransactionInner(state, extension, tr.changes.newLength), true); + } + return spec == tr ? tr : Transaction.create(state, tr.changes, tr.selection, spec.effects, spec.annotations, spec.scrollIntoView); + } + var none = []; + function asArray(value) { + return value == null ? none : Array.isArray(value) ? value : [value]; + } + var CharCategory = /* @__PURE__ */ function(CharCategory2) { + CharCategory2[CharCategory2["Word"] = 0] = "Word"; + CharCategory2[CharCategory2["Space"] = 1] = "Space"; + CharCategory2[CharCategory2["Other"] = 2] = "Other"; + return CharCategory2; + }(CharCategory || (CharCategory = {})); + var nonASCIISingleCaseWordChar = /[\u00df\u0587\u0590-\u05f4\u0600-\u06ff\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/; + var wordChar; + try { + wordChar = /* @__PURE__ */ new RegExp("[\\p{Alphabetic}\\p{Number}_]", "u"); + } catch (_) { + } + function hasWordChar(str) { + if (wordChar) + return wordChar.test(str); + for (let i = 0; i < str.length; i++) { + let ch = str[i]; + if (/\w/.test(ch) || ch > "\x80" && (ch.toUpperCase() != ch.toLowerCase() || nonASCIISingleCaseWordChar.test(ch))) + return true; + } + return false; + } + function makeCategorizer(wordChars) { + return (char) => { + if (!/\S/.test(char)) + return CharCategory.Space; + if (hasWordChar(char)) + return CharCategory.Word; + for (let i = 0; i < wordChars.length; i++) + if (char.indexOf(wordChars[i]) > -1) + return CharCategory.Word; + return CharCategory.Other; + }; + } + var EditorState = class _EditorState { + constructor(config2, doc2, selection, values2, computeSlot, tr) { + this.config = config2; + this.doc = doc2; + this.selection = selection; + this.values = values2; + this.status = config2.statusTemplate.slice(); + this.computeSlot = computeSlot; + if (tr) + tr._state = this; + for (let i = 0; i < this.config.dynamicSlots.length; i++) + ensureAddr(this, i << 1); + this.computeSlot = null; + } + field(field, require2 = true) { + let addr = this.config.address[field.id]; + if (addr == null) { + if (require2) + throw new RangeError("Field is not present in this state"); + return void 0; + } + ensureAddr(this, addr); + return getAddr(this, addr); + } + /** + Create a [transaction](https://codemirror.net/6/docs/ref/#state.Transaction) that updates this + state. Any number of [transaction specs](https://codemirror.net/6/docs/ref/#state.TransactionSpec) + can be passed. Unless + [`sequential`](https://codemirror.net/6/docs/ref/#state.TransactionSpec.sequential) is set, the + [changes](https://codemirror.net/6/docs/ref/#state.TransactionSpec.changes) (if any) of each spec + are assumed to start in the _current_ document (not the document + produced by previous specs), and its + [selection](https://codemirror.net/6/docs/ref/#state.TransactionSpec.selection) and + [effects](https://codemirror.net/6/docs/ref/#state.TransactionSpec.effects) are assumed to refer + to the document created by its _own_ changes. The resulting + transaction contains the combined effect of all the different + specs. For [selection](https://codemirror.net/6/docs/ref/#state.TransactionSpec.selection), later + specs take precedence over earlier ones. + */ + update(...specs) { + return resolveTransaction(this, specs, true); + } + /** + @internal + */ + applyTransaction(tr) { + let conf = this.config, { base: base2, compartments } = conf; + for (let effect of tr.effects) { + if (effect.is(Compartment.reconfigure)) { + if (conf) { + compartments = /* @__PURE__ */ new Map(); + conf.compartments.forEach((val, key) => compartments.set(key, val)); + conf = null; + } + compartments.set(effect.value.compartment, effect.value.extension); + } else if (effect.is(StateEffect.reconfigure)) { + conf = null; + base2 = effect.value; + } else if (effect.is(StateEffect.appendConfig)) { + conf = null; + base2 = asArray(base2).concat(effect.value); + } + } + let startValues; + if (!conf) { + conf = Configuration.resolve(base2, compartments, this); + let intermediateState = new _EditorState(conf, this.doc, this.selection, conf.dynamicSlots.map(() => null), (state, slot) => slot.reconfigure(state, this), null); + startValues = intermediateState.values; + } else { + startValues = tr.startState.values.slice(); + } + let selection = tr.startState.facet(allowMultipleSelections) ? tr.newSelection : tr.newSelection.asSingle(); + new _EditorState(conf, tr.newDoc, selection, startValues, (state, slot) => slot.update(state, tr), tr); + } + /** + Create a [transaction spec](https://codemirror.net/6/docs/ref/#state.TransactionSpec) that + replaces every selection range with the given content. + */ + replaceSelection(text) { + if (typeof text == "string") + text = this.toText(text); + return this.changeByRange((range) => ({ + changes: { from: range.from, to: range.to, insert: text }, + range: EditorSelection.cursor(range.from + text.length) + })); + } + /** + Create a set of changes and a new selection by running the given + function for each range in the active selection. The function + can return an optional set of changes (in the coordinate space + of the start document), plus an updated range (in the coordinate + space of the document produced by the call's own changes). This + method will merge all the changes and ranges into a single + changeset and selection, and return it as a [transaction + spec](https://codemirror.net/6/docs/ref/#state.TransactionSpec), which can be passed to + [`update`](https://codemirror.net/6/docs/ref/#state.EditorState.update). + */ + changeByRange(f) { + let sel = this.selection; + let result1 = f(sel.ranges[0]); + let changes = this.changes(result1.changes), ranges = [result1.range]; + let effects = asArray(result1.effects); + for (let i = 1; i < sel.ranges.length; i++) { + let result = f(sel.ranges[i]); + let newChanges = this.changes(result.changes), newMapped = newChanges.map(changes); + for (let j = 0; j < i; j++) + ranges[j] = ranges[j].map(newMapped); + let mapBy = changes.mapDesc(newChanges, true); + ranges.push(result.range.map(mapBy)); + changes = changes.compose(newMapped); + effects = StateEffect.mapEffects(effects, newMapped).concat(StateEffect.mapEffects(asArray(result.effects), mapBy)); + } + return { + changes, + selection: EditorSelection.create(ranges, sel.mainIndex), + effects + }; + } + /** + Create a [change set](https://codemirror.net/6/docs/ref/#state.ChangeSet) from the given change + description, taking the state's document length and line + separator into account. + */ + changes(spec = []) { + if (spec instanceof ChangeSet) + return spec; + return ChangeSet.of(spec, this.doc.length, this.facet(_EditorState.lineSeparator)); + } + /** + Using the state's [line + separator](https://codemirror.net/6/docs/ref/#state.EditorState^lineSeparator), create a + [`Text`](https://codemirror.net/6/docs/ref/#state.Text) instance from the given string. + */ + toText(string2) { + return Text.of(string2.split(this.facet(_EditorState.lineSeparator) || DefaultSplit)); + } + /** + Return the given range of the document as a string. + */ + sliceDoc(from = 0, to = this.doc.length) { + return this.doc.sliceString(from, to, this.lineBreak); + } + /** + Get the value of a state [facet](https://codemirror.net/6/docs/ref/#state.Facet). + */ + facet(facet) { + let addr = this.config.address[facet.id]; + if (addr == null) + return facet.default; + ensureAddr(this, addr); + return getAddr(this, addr); + } + /** + Convert this state to a JSON-serializable object. When custom + fields should be serialized, you can pass them in as an object + mapping property names (in the resulting object, which should + not use `doc` or `selection`) to fields. + */ + toJSON(fields) { + let result = { + doc: this.sliceDoc(), + selection: this.selection.toJSON() + }; + if (fields) + for (let prop in fields) { + let value = fields[prop]; + if (value instanceof StateField && this.config.address[value.id] != null) + result[prop] = value.spec.toJSON(this.field(fields[prop]), this); + } + return result; + } + /** + Deserialize a state from its JSON representation. When custom + fields should be deserialized, pass the same object you passed + to [`toJSON`](https://codemirror.net/6/docs/ref/#state.EditorState.toJSON) when serializing as + third argument. + */ + static fromJSON(json, config2 = {}, fields) { + if (!json || typeof json.doc != "string") + throw new RangeError("Invalid JSON representation for EditorState"); + let fieldInit = []; + if (fields) + for (let prop in fields) { + if (Object.prototype.hasOwnProperty.call(json, prop)) { + let field = fields[prop], value = json[prop]; + fieldInit.push(field.init((state) => field.spec.fromJSON(value, state))); + } + } + return _EditorState.create({ + doc: json.doc, + selection: EditorSelection.fromJSON(json.selection), + extensions: config2.extensions ? fieldInit.concat([config2.extensions]) : fieldInit + }); + } + /** + Create a new state. You'll usually only need this when + initializing an editor—updated states are created by applying + transactions. + */ + static create(config2 = {}) { + let configuration = Configuration.resolve(config2.extensions || [], /* @__PURE__ */ new Map()); + let doc2 = config2.doc instanceof Text ? config2.doc : Text.of((config2.doc || "").split(configuration.staticFacet(_EditorState.lineSeparator) || DefaultSplit)); + let selection = !config2.selection ? EditorSelection.single(0) : config2.selection instanceof EditorSelection ? config2.selection : EditorSelection.single(config2.selection.anchor, config2.selection.head); + checkSelection(selection, doc2.length); + if (!configuration.staticFacet(allowMultipleSelections)) + selection = selection.asSingle(); + return new _EditorState(configuration, doc2, selection, configuration.dynamicSlots.map(() => null), (state, slot) => slot.create(state), null); + } + /** + The size (in columns) of a tab in the document, determined by + the [`tabSize`](https://codemirror.net/6/docs/ref/#state.EditorState^tabSize) facet. + */ + get tabSize() { + return this.facet(_EditorState.tabSize); + } + /** + Get the proper [line-break](https://codemirror.net/6/docs/ref/#state.EditorState^lineSeparator) + string for this state. + */ + get lineBreak() { + return this.facet(_EditorState.lineSeparator) || "\n"; + } + /** + Returns true when the editor is + [configured](https://codemirror.net/6/docs/ref/#state.EditorState^readOnly) to be read-only. + */ + get readOnly() { + return this.facet(readOnly); + } + /** + Look up a translation for the given phrase (via the + [`phrases`](https://codemirror.net/6/docs/ref/#state.EditorState^phrases) facet), or return the + original string if no translation is found. + + If additional arguments are passed, they will be inserted in + place of markers like `$1` (for the first value) and `$2`, etc. + A single `$` is equivalent to `$1`, and `$$` will produce a + literal dollar sign. + */ + phrase(phrase2, ...insert2) { + for (let map of this.facet(_EditorState.phrases)) + if (Object.prototype.hasOwnProperty.call(map, phrase2)) { + phrase2 = map[phrase2]; + break; + } + if (insert2.length) + phrase2 = phrase2.replace(/\$(\$|\d*)/g, (m, i) => { + if (i == "$") + return "$"; + let n = +(i || 1); + return !n || n > insert2.length ? m : insert2[n - 1]; + }); + return phrase2; + } + /** + Find the values for a given language data field, provided by the + the [`languageData`](https://codemirror.net/6/docs/ref/#state.EditorState^languageData) facet. + + Examples of language data fields are... + + - [`"commentTokens"`](https://codemirror.net/6/docs/ref/#commands.CommentTokens) for specifying + comment syntax. + - [`"autocomplete"`](https://codemirror.net/6/docs/ref/#autocomplete.autocompletion^config.override) + for providing language-specific completion sources. + - [`"wordChars"`](https://codemirror.net/6/docs/ref/#state.EditorState.charCategorizer) for adding + characters that should be considered part of words in this + language. + - [`"closeBrackets"`](https://codemirror.net/6/docs/ref/#autocomplete.CloseBracketConfig) controls + bracket closing behavior. + */ + languageDataAt(name2, pos, side = -1) { + let values2 = []; + for (let provider of this.facet(languageData)) { + for (let result of provider(this, pos, side)) { + if (Object.prototype.hasOwnProperty.call(result, name2)) + values2.push(result[name2]); + } + } + return values2; + } + /** + Return a function that can categorize strings (expected to + represent a single [grapheme cluster](https://codemirror.net/6/docs/ref/#state.findClusterBreak)) + into one of: + + - Word (contains an alphanumeric character or a character + explicitly listed in the local language's `"wordChars"` + language data, which should be a string) + - Space (contains only whitespace) + - Other (anything else) + */ + charCategorizer(at) { + return makeCategorizer(this.languageDataAt("wordChars", at).join("")); + } + /** + Find the word at the given position, meaning the range + containing all [word](https://codemirror.net/6/docs/ref/#state.CharCategory.Word) characters + around it. If no word characters are adjacent to the position, + this returns null. + */ + wordAt(pos) { + let { text, from, length } = this.doc.lineAt(pos); + let cat = this.charCategorizer(pos); + let start = pos - from, end = pos - from; + while (start > 0) { + let prev = findClusterBreak(text, start, false); + if (cat(text.slice(prev, start)) != CharCategory.Word) + break; + start = prev; + } + while (end < length) { + let next = findClusterBreak(text, end); + if (cat(text.slice(end, next)) != CharCategory.Word) + break; + end = next; + } + return start == end ? null : EditorSelection.range(start + from, end + from); + } + }; + EditorState.allowMultipleSelections = allowMultipleSelections; + EditorState.tabSize = /* @__PURE__ */ Facet.define({ + combine: (values2) => values2.length ? values2[0] : 4 + }); + EditorState.lineSeparator = lineSeparator; + EditorState.readOnly = readOnly; + EditorState.phrases = /* @__PURE__ */ Facet.define({ + compare(a, b) { + let kA = Object.keys(a), kB = Object.keys(b); + return kA.length == kB.length && kA.every((k) => a[k] == b[k]); + } + }); + EditorState.languageData = languageData; + EditorState.changeFilter = changeFilter; + EditorState.transactionFilter = transactionFilter; + EditorState.transactionExtender = transactionExtender; + Compartment.reconfigure = /* @__PURE__ */ StateEffect.define(); + function combineConfig(configs, defaults3, combine = {}) { + let result = {}; + for (let config2 of configs) + for (let key of Object.keys(config2)) { + let value = config2[key], current = result[key]; + if (current === void 0) + result[key] = value; + else if (current === value || value === void 0) ; + else if (Object.hasOwnProperty.call(combine, key)) + result[key] = combine[key](current, value); + else + throw new Error("Config merge conflict for field " + key); + } + for (let key in defaults3) + if (result[key] === void 0) + result[key] = defaults3[key]; + return result; + } + var RangeValue = class { + /** + Compare this value with another value. Used when comparing + rangesets. The default implementation compares by identity. + Unless you are only creating a fixed number of unique instances + of your value type, it is a good idea to implement this + properly. + */ + eq(other) { + return this == other; + } + /** + Create a [range](https://codemirror.net/6/docs/ref/#state.Range) with this value. + */ + range(from, to = from) { + return Range.create(from, to, this); + } + }; + RangeValue.prototype.startSide = RangeValue.prototype.endSide = 0; + RangeValue.prototype.point = false; + RangeValue.prototype.mapMode = MapMode.TrackDel; + var Range = class _Range { + constructor(from, to, value) { + this.from = from; + this.to = to; + this.value = value; + } + /** + @internal + */ + static create(from, to, value) { + return new _Range(from, to, value); + } + }; + function cmpRange(a, b) { + return a.from - b.from || a.value.startSide - b.value.startSide; + } + var Chunk = class _Chunk { + constructor(from, to, value, maxPoint) { + this.from = from; + this.to = to; + this.value = value; + this.maxPoint = maxPoint; + } + get length() { + return this.to[this.to.length - 1]; + } + // Find the index of the given position and side. Use the ranges' + // `from` pos when `end == false`, `to` when `end == true`. + findIndex(pos, side, end, startAt = 0) { + let arr = end ? this.to : this.from; + for (let lo = startAt, hi = arr.length; ; ) { + if (lo == hi) + return lo; + let mid = lo + hi >> 1; + let diff = arr[mid] - pos || (end ? this.value[mid].endSide : this.value[mid].startSide) - side; + if (mid == lo) + return diff >= 0 ? lo : hi; + if (diff >= 0) + hi = mid; + else + lo = mid + 1; + } + } + between(offset, from, to, f) { + for (let i = this.findIndex(from, -1e9, true), e = this.findIndex(to, 1e9, false, i); i < e; i++) + if (f(this.from[i] + offset, this.to[i] + offset, this.value[i]) === false) + return false; + } + map(offset, changes) { + let value = [], from = [], to = [], newPos = -1, maxPoint = -1; + for (let i = 0; i < this.value.length; i++) { + let val = this.value[i], curFrom = this.from[i] + offset, curTo = this.to[i] + offset, newFrom, newTo; + if (curFrom == curTo) { + let mapped = changes.mapPos(curFrom, val.startSide, val.mapMode); + if (mapped == null) + continue; + newFrom = newTo = mapped; + if (val.startSide != val.endSide) { + newTo = changes.mapPos(curFrom, val.endSide); + if (newTo < newFrom) + continue; + } + } else { + newFrom = changes.mapPos(curFrom, val.startSide); + newTo = changes.mapPos(curTo, val.endSide); + if (newFrom > newTo || newFrom == newTo && val.startSide > 0 && val.endSide <= 0) + continue; + } + if ((newTo - newFrom || val.endSide - val.startSide) < 0) + continue; + if (newPos < 0) + newPos = newFrom; + if (val.point) + maxPoint = Math.max(maxPoint, newTo - newFrom); + value.push(val); + from.push(newFrom - newPos); + to.push(newTo - newPos); + } + return { mapped: value.length ? new _Chunk(from, to, value, maxPoint) : null, pos: newPos }; + } + }; + var RangeSet = class _RangeSet { + constructor(chunkPos, chunk, nextLayer, maxPoint) { + this.chunkPos = chunkPos; + this.chunk = chunk; + this.nextLayer = nextLayer; + this.maxPoint = maxPoint; + } + /** + @internal + */ + static create(chunkPos, chunk, nextLayer, maxPoint) { + return new _RangeSet(chunkPos, chunk, nextLayer, maxPoint); + } + /** + @internal + */ + get length() { + let last = this.chunk.length - 1; + return last < 0 ? 0 : Math.max(this.chunkEnd(last), this.nextLayer.length); + } + /** + The number of ranges in the set. + */ + get size() { + if (this.isEmpty) + return 0; + let size = this.nextLayer.size; + for (let chunk of this.chunk) + size += chunk.value.length; + return size; + } + /** + @internal + */ + chunkEnd(index) { + return this.chunkPos[index] + this.chunk[index].length; + } + /** + Update the range set, optionally adding new ranges or filtering + out existing ones. + + (Note: The type parameter is just there as a kludge to work + around TypeScript variance issues that prevented `RangeSet` + from being a subtype of `RangeSet` when `X` is a subtype of + `Y`.) + */ + update(updateSpec) { + let { add: add2 = [], sort = false, filterFrom = 0, filterTo = this.length } = updateSpec; + let filter = updateSpec.filter; + if (add2.length == 0 && !filter) + return this; + if (sort) + add2 = add2.slice().sort(cmpRange); + if (this.isEmpty) + return add2.length ? _RangeSet.of(add2) : this; + let cur2 = new LayerCursor(this, null, -1).goto(0), i = 0, spill = []; + let builder = new RangeSetBuilder(); + while (cur2.value || i < add2.length) { + if (i < add2.length && (cur2.from - add2[i].from || cur2.startSide - add2[i].value.startSide) >= 0) { + let range = add2[i++]; + if (!builder.addInner(range.from, range.to, range.value)) + spill.push(range); + } else if (cur2.rangeIndex == 1 && cur2.chunkIndex < this.chunk.length && (i == add2.length || this.chunkEnd(cur2.chunkIndex) < add2[i].from) && (!filter || filterFrom > this.chunkEnd(cur2.chunkIndex) || filterTo < this.chunkPos[cur2.chunkIndex]) && builder.addChunk(this.chunkPos[cur2.chunkIndex], this.chunk[cur2.chunkIndex])) { + cur2.nextChunk(); + } else { + if (!filter || filterFrom > cur2.to || filterTo < cur2.from || filter(cur2.from, cur2.to, cur2.value)) { + if (!builder.addInner(cur2.from, cur2.to, cur2.value)) + spill.push(Range.create(cur2.from, cur2.to, cur2.value)); + } + cur2.next(); + } + } + return builder.finishInner(this.nextLayer.isEmpty && !spill.length ? _RangeSet.empty : this.nextLayer.update({ add: spill, filter, filterFrom, filterTo })); + } + /** + Map this range set through a set of changes, return the new set. + */ + map(changes) { + if (changes.empty || this.isEmpty) + return this; + let chunks = [], chunkPos = [], maxPoint = -1; + for (let i = 0; i < this.chunk.length; i++) { + let start = this.chunkPos[i], chunk = this.chunk[i]; + let touch = changes.touchesRange(start, start + chunk.length); + if (touch === false) { + maxPoint = Math.max(maxPoint, chunk.maxPoint); + chunks.push(chunk); + chunkPos.push(changes.mapPos(start)); + } else if (touch === true) { + let { mapped, pos } = chunk.map(start, changes); + if (mapped) { + maxPoint = Math.max(maxPoint, mapped.maxPoint); + chunks.push(mapped); + chunkPos.push(pos); + } + } + } + let next = this.nextLayer.map(changes); + return chunks.length == 0 ? next : new _RangeSet(chunkPos, chunks, next || _RangeSet.empty, maxPoint); + } + /** + Iterate over the ranges that touch the region `from` to `to`, + calling `f` for each. There is no guarantee that the ranges will + be reported in any specific order. When the callback returns + `false`, iteration stops. + */ + between(from, to, f) { + if (this.isEmpty) + return; + for (let i = 0; i < this.chunk.length; i++) { + let start = this.chunkPos[i], chunk = this.chunk[i]; + if (to >= start && from <= start + chunk.length && chunk.between(start, from - start, to - start, f) === false) + return; + } + this.nextLayer.between(from, to, f); + } + /** + Iterate over the ranges in this set, in order, including all + ranges that end at or after `from`. + */ + iter(from = 0) { + return HeapCursor.from([this]).goto(from); + } + /** + @internal + */ + get isEmpty() { + return this.nextLayer == this; + } + /** + Iterate over the ranges in a collection of sets, in order, + starting from `from`. + */ + static iter(sets, from = 0) { + return HeapCursor.from(sets).goto(from); + } + /** + Iterate over two groups of sets, calling methods on `comparator` + to notify it of possible differences. + */ + static compare(oldSets, newSets, textDiff, comparator, minPointSize = -1) { + let a = oldSets.filter((set) => set.maxPoint > 0 || !set.isEmpty && set.maxPoint >= minPointSize); + let b = newSets.filter((set) => set.maxPoint > 0 || !set.isEmpty && set.maxPoint >= minPointSize); + let sharedChunks = findSharedChunks(a, b, textDiff); + let sideA = new SpanCursor(a, sharedChunks, minPointSize); + let sideB = new SpanCursor(b, sharedChunks, minPointSize); + textDiff.iterGaps((fromA, fromB, length) => compare(sideA, fromA, sideB, fromB, length, comparator)); + if (textDiff.empty && textDiff.length == 0) + compare(sideA, 0, sideB, 0, 0, comparator); + } + /** + Compare the contents of two groups of range sets, returning true + if they are equivalent in the given range. + */ + static eq(oldSets, newSets, from = 0, to) { + if (to == null) + to = 1e9 - 1; + let a = oldSets.filter((set) => !set.isEmpty && newSets.indexOf(set) < 0); + let b = newSets.filter((set) => !set.isEmpty && oldSets.indexOf(set) < 0); + if (a.length != b.length) + return false; + if (!a.length) + return true; + let sharedChunks = findSharedChunks(a, b); + let sideA = new SpanCursor(a, sharedChunks, 0).goto(from), sideB = new SpanCursor(b, sharedChunks, 0).goto(from); + for (; ; ) { + if (sideA.to != sideB.to || !sameValues(sideA.active, sideB.active) || sideA.point && (!sideB.point || !sideA.point.eq(sideB.point))) + return false; + if (sideA.to > to) return true; - return false; - }; + sideA.next(); + sideB.next(); + } + } + /** + Iterate over a group of range sets at the same time, notifying + the iterator about the ranges covering every given piece of + content. Returns the open count (see + [`SpanIterator.span`](https://codemirror.net/6/docs/ref/#state.SpanIterator.span)) at the end + of the iteration. + */ + static spans(sets, from, to, iterator, minPointSize = -1) { + let cursor = new SpanCursor(sets, null, minPointSize).goto(from), pos = from; + let openRanges = cursor.openStart; + for (; ; ) { + let curTo = Math.min(cursor.to, to); + if (cursor.point) { + let active = cursor.activeForPoint(cursor.to); + let openCount = cursor.pointFrom < from ? active.length + 1 : cursor.point.startSide < 0 ? active.length : Math.min(active.length, openRanges); + iterator.point(pos, curTo, cursor.point, active, openCount, cursor.pointRank); + openRanges = Math.min(cursor.openEnd(curTo), active.length); + } else if (curTo > pos) { + iterator.span(pos, curTo, cursor.active, openRanges); + openRanges = cursor.openEnd(curTo); + } + if (cursor.to > to) + return openRanges + (cursor.point && cursor.to > to ? 1 : 0); + pos = cursor.to; + cursor.next(); + } + } + /** + Create a range set for the given range or array of ranges. By + default, this expects the ranges to be _sorted_ (by start + position and, if two start at the same position, + `value.startSide`). You can pass `true` as second argument to + cause the method to sort them. + */ + static of(ranges, sort = false) { + let build = new RangeSetBuilder(); + for (let range of ranges instanceof Range ? [ranges] : sort ? lazySort(ranges) : ranges) + build.add(range.from, range.to, range.value); + return build.finish(); + } + /** + Join an array of range sets into a single set. + */ + static join(sets) { + if (!sets.length) + return _RangeSet.empty; + let result = sets[sets.length - 1]; + for (let i = sets.length - 2; i >= 0; i--) { + for (let layer2 = sets[i]; layer2 != _RangeSet.empty; layer2 = layer2.nextLayer) + result = new _RangeSet(layer2.chunkPos, layer2.chunk, result, Math.max(layer2.maxPoint, result.maxPoint)); + } + return result; + } + }; + RangeSet.empty = /* @__PURE__ */ new RangeSet([], [], null, -1); + function lazySort(ranges) { + if (ranges.length > 1) + for (let prev = ranges[0], i = 1; i < ranges.length; i++) { + let cur2 = ranges[i]; + if (cmpRange(prev, cur2) > 0) + return ranges.slice().sort(cmpRange); + prev = cur2; + } + return ranges; } - var backspace = chainCommands(deleteSelection, joinBackward, selectNodeBackward); - var del = chainCommands(deleteSelection, joinForward, selectNodeForward); - var pcBaseKeymap = { - "Enter": chainCommands(newlineInCode, createParagraphNear, liftEmptyBlock, splitBlock), - "Mod-Enter": exitCode, - "Backspace": backspace, - "Mod-Backspace": backspace, - "Shift-Backspace": backspace, - "Delete": del, - "Mod-Delete": del, - "Mod-a": selectAll + RangeSet.empty.nextLayer = RangeSet.empty; + var RangeSetBuilder = class _RangeSetBuilder { + finishChunk(newArrays) { + this.chunks.push(new Chunk(this.from, this.to, this.value, this.maxPoint)); + this.chunkPos.push(this.chunkStart); + this.chunkStart = -1; + this.setMaxPoint = Math.max(this.setMaxPoint, this.maxPoint); + this.maxPoint = -1; + if (newArrays) { + this.from = []; + this.to = []; + this.value = []; + } + } + /** + Create an empty builder. + */ + constructor() { + this.chunks = []; + this.chunkPos = []; + this.chunkStart = -1; + this.last = null; + this.lastFrom = -1e9; + this.lastTo = -1e9; + this.from = []; + this.to = []; + this.value = []; + this.maxPoint = -1; + this.setMaxPoint = -1; + this.nextLayer = null; + } + /** + Add a range. Ranges should be added in sorted (by `from` and + `value.startSide`) order. + */ + add(from, to, value) { + if (!this.addInner(from, to, value)) + (this.nextLayer || (this.nextLayer = new _RangeSetBuilder())).add(from, to, value); + } + /** + @internal + */ + addInner(from, to, value) { + let diff = from - this.lastTo || value.startSide - this.last.endSide; + if (diff <= 0 && (from - this.lastFrom || value.startSide - this.last.startSide) < 0) + throw new Error("Ranges must be added sorted by `from` position and `startSide`"); + if (diff < 0) + return false; + if (this.from.length == 250) + this.finishChunk(true); + if (this.chunkStart < 0) + this.chunkStart = from; + this.from.push(from - this.chunkStart); + this.to.push(to - this.chunkStart); + this.last = value; + this.lastFrom = from; + this.lastTo = to; + this.value.push(value); + if (value.point) + this.maxPoint = Math.max(this.maxPoint, to - from); + return true; + } + /** + @internal + */ + addChunk(from, chunk) { + if ((from - this.lastTo || chunk.value[0].startSide - this.last.endSide) < 0) + return false; + if (this.from.length) + this.finishChunk(true); + this.setMaxPoint = Math.max(this.setMaxPoint, chunk.maxPoint); + this.chunks.push(chunk); + this.chunkPos.push(from); + let last = chunk.value.length - 1; + this.last = chunk.value[last]; + this.lastFrom = chunk.from[last] + from; + this.lastTo = chunk.to[last] + from; + return true; + } + /** + Finish the range set. Returns the new set. The builder can't be + used anymore after this has been called. + */ + finish() { + return this.finishInner(RangeSet.empty); + } + /** + @internal + */ + finishInner(next) { + if (this.from.length) + this.finishChunk(false); + if (this.chunks.length == 0) + return next; + let result = RangeSet.create(this.chunkPos, this.chunks, this.nextLayer ? this.nextLayer.finishInner(next) : next, this.setMaxPoint); + this.from = null; + return result; + } }; - var macBaseKeymap = { - "Ctrl-h": pcBaseKeymap["Backspace"], - "Alt-Backspace": pcBaseKeymap["Mod-Backspace"], - "Ctrl-d": pcBaseKeymap["Delete"], - "Ctrl-Alt-Backspace": pcBaseKeymap["Mod-Delete"], - "Alt-Delete": pcBaseKeymap["Mod-Delete"], - "Alt-d": pcBaseKeymap["Mod-Delete"], - "Ctrl-a": selectTextblockStart, - "Ctrl-e": selectTextblockEnd + function findSharedChunks(a, b, textDiff) { + let inA = /* @__PURE__ */ new Map(); + for (let set of a) + for (let i = 0; i < set.chunk.length; i++) + if (set.chunk[i].maxPoint <= 0) + inA.set(set.chunk[i], set.chunkPos[i]); + let shared = /* @__PURE__ */ new Set(); + for (let set of b) + for (let i = 0; i < set.chunk.length; i++) { + let known = inA.get(set.chunk[i]); + if (known != null && (textDiff ? textDiff.mapPos(known) : known) == set.chunkPos[i] && !(textDiff === null || textDiff === void 0 ? void 0 : textDiff.touchesRange(known, known + set.chunk[i].length))) + shared.add(set.chunk[i]); + } + return shared; + } + var LayerCursor = class { + constructor(layer2, skip, minPoint, rank = 0) { + this.layer = layer2; + this.skip = skip; + this.minPoint = minPoint; + this.rank = rank; + } + get startSide() { + return this.value ? this.value.startSide : 0; + } + get endSide() { + return this.value ? this.value.endSide : 0; + } + goto(pos, side = -1e9) { + this.chunkIndex = this.rangeIndex = 0; + this.gotoInner(pos, side, false); + return this; + } + gotoInner(pos, side, forward) { + while (this.chunkIndex < this.layer.chunk.length) { + let next = this.layer.chunk[this.chunkIndex]; + if (!(this.skip && this.skip.has(next) || this.layer.chunkEnd(this.chunkIndex) < pos || next.maxPoint < this.minPoint)) + break; + this.chunkIndex++; + forward = false; + } + if (this.chunkIndex < this.layer.chunk.length) { + let rangeIndex = this.layer.chunk[this.chunkIndex].findIndex(pos - this.layer.chunkPos[this.chunkIndex], side, true); + if (!forward || this.rangeIndex < rangeIndex) + this.setRangeIndex(rangeIndex); + } + this.next(); + } + forward(pos, side) { + if ((this.to - pos || this.endSide - side) < 0) + this.gotoInner(pos, side, true); + } + next() { + for (; ; ) { + if (this.chunkIndex == this.layer.chunk.length) { + this.from = this.to = 1e9; + this.value = null; + break; + } else { + let chunkPos = this.layer.chunkPos[this.chunkIndex], chunk = this.layer.chunk[this.chunkIndex]; + let from = chunkPos + chunk.from[this.rangeIndex]; + this.from = from; + this.to = chunkPos + chunk.to[this.rangeIndex]; + this.value = chunk.value[this.rangeIndex]; + this.setRangeIndex(this.rangeIndex + 1); + if (this.minPoint < 0 || this.value.point && this.to - this.from >= this.minPoint) + break; + } + } + } + setRangeIndex(index) { + if (index == this.layer.chunk[this.chunkIndex].value.length) { + this.chunkIndex++; + if (this.skip) { + while (this.chunkIndex < this.layer.chunk.length && this.skip.has(this.layer.chunk[this.chunkIndex])) + this.chunkIndex++; + } + this.rangeIndex = 0; + } else { + this.rangeIndex = index; + } + } + nextChunk() { + this.chunkIndex++; + this.rangeIndex = 0; + this.next(); + } + compare(other) { + return this.from - other.from || this.startSide - other.startSide || this.rank - other.rank || this.to - other.to || this.endSide - other.endSide; + } + }; + var HeapCursor = class _HeapCursor { + constructor(heap) { + this.heap = heap; + } + static from(sets, skip = null, minPoint = -1) { + let heap = []; + for (let i = 0; i < sets.length; i++) { + for (let cur2 = sets[i]; !cur2.isEmpty; cur2 = cur2.nextLayer) { + if (cur2.maxPoint >= minPoint) + heap.push(new LayerCursor(cur2, skip, minPoint, i)); + } + } + return heap.length == 1 ? heap[0] : new _HeapCursor(heap); + } + get startSide() { + return this.value ? this.value.startSide : 0; + } + goto(pos, side = -1e9) { + for (let cur2 of this.heap) + cur2.goto(pos, side); + for (let i = this.heap.length >> 1; i >= 0; i--) + heapBubble(this.heap, i); + this.next(); + return this; + } + forward(pos, side) { + for (let cur2 of this.heap) + cur2.forward(pos, side); + for (let i = this.heap.length >> 1; i >= 0; i--) + heapBubble(this.heap, i); + if ((this.to - pos || this.value.endSide - side) < 0) + this.next(); + } + next() { + if (this.heap.length == 0) { + this.from = this.to = 1e9; + this.value = null; + this.rank = -1; + } else { + let top2 = this.heap[0]; + this.from = top2.from; + this.to = top2.to; + this.value = top2.value; + this.rank = top2.rank; + if (top2.value) + top2.next(); + heapBubble(this.heap, 0); + } + } + }; + function heapBubble(heap, index) { + for (let cur2 = heap[index]; ; ) { + let childIndex = (index << 1) + 1; + if (childIndex >= heap.length) + break; + let child = heap[childIndex]; + if (childIndex + 1 < heap.length && child.compare(heap[childIndex + 1]) >= 0) { + child = heap[childIndex + 1]; + childIndex++; + } + if (cur2.compare(child) < 0) + break; + heap[childIndex] = cur2; + heap[index] = child; + index = childIndex; + } + } + var SpanCursor = class { + constructor(sets, skip, minPoint) { + this.minPoint = minPoint; + this.active = []; + this.activeTo = []; + this.activeRank = []; + this.minActive = -1; + this.point = null; + this.pointFrom = 0; + this.pointRank = 0; + this.to = -1e9; + this.endSide = 0; + this.openStart = -1; + this.cursor = HeapCursor.from(sets, skip, minPoint); + } + goto(pos, side = -1e9) { + this.cursor.goto(pos, side); + this.active.length = this.activeTo.length = this.activeRank.length = 0; + this.minActive = -1; + this.to = pos; + this.endSide = side; + this.openStart = -1; + this.next(); + return this; + } + forward(pos, side) { + while (this.minActive > -1 && (this.activeTo[this.minActive] - pos || this.active[this.minActive].endSide - side) < 0) + this.removeActive(this.minActive); + this.cursor.forward(pos, side); + } + removeActive(index) { + remove(this.active, index); + remove(this.activeTo, index); + remove(this.activeRank, index); + this.minActive = findMinIndex(this.active, this.activeTo); + } + addActive(trackOpen) { + let i = 0, { value, to, rank } = this.cursor; + while (i < this.activeRank.length && (rank - this.activeRank[i] || to - this.activeTo[i]) > 0) + i++; + insert(this.active, i, value); + insert(this.activeTo, i, to); + insert(this.activeRank, i, rank); + if (trackOpen) + insert(trackOpen, i, this.cursor.from); + this.minActive = findMinIndex(this.active, this.activeTo); + } + // After calling this, if `this.point` != null, the next range is a + // point. Otherwise, it's a regular range, covered by `this.active`. + next() { + let from = this.to, wasPoint = this.point; + this.point = null; + let trackOpen = this.openStart < 0 ? [] : null; + for (; ; ) { + let a = this.minActive; + if (a > -1 && (this.activeTo[a] - this.cursor.from || this.active[a].endSide - this.cursor.startSide) < 0) { + if (this.activeTo[a] > from) { + this.to = this.activeTo[a]; + this.endSide = this.active[a].endSide; + break; + } + this.removeActive(a); + if (trackOpen) + remove(trackOpen, a); + } else if (!this.cursor.value) { + this.to = this.endSide = 1e9; + break; + } else if (this.cursor.from > from) { + this.to = this.cursor.from; + this.endSide = this.cursor.startSide; + break; + } else { + let nextVal = this.cursor.value; + if (!nextVal.point) { + this.addActive(trackOpen); + this.cursor.next(); + } else if (wasPoint && this.cursor.to == this.to && this.cursor.from < this.cursor.to) { + this.cursor.next(); + } else { + this.point = nextVal; + this.pointFrom = this.cursor.from; + this.pointRank = this.cursor.rank; + this.to = this.cursor.to; + this.endSide = nextVal.endSide; + this.cursor.next(); + this.forward(this.to, this.endSide); + break; + } + } + } + if (trackOpen) { + this.openStart = 0; + for (let i = trackOpen.length - 1; i >= 0 && trackOpen[i] < from; i--) + this.openStart++; + } + } + activeForPoint(to) { + if (!this.active.length) + return this.active; + let active = []; + for (let i = this.active.length - 1; i >= 0; i--) { + if (this.activeRank[i] < this.pointRank) + break; + if (this.activeTo[i] > to || this.activeTo[i] == to && this.active[i].endSide >= this.point.endSide) + active.push(this.active[i]); + } + return active.reverse(); + } + openEnd(to) { + let open = 0; + for (let i = this.activeTo.length - 1; i >= 0 && this.activeTo[i] > to; i--) + open++; + return open; + } + }; + function compare(a, startA, b, startB, length, comparator) { + a.goto(startA); + b.goto(startB); + let endB = startB + length; + let pos = startB, dPos = startB - startA; + for (; ; ) { + let diff = a.to + dPos - b.to || a.endSide - b.endSide; + let end = diff < 0 ? a.to + dPos : b.to, clipEnd = Math.min(end, endB); + if (a.point || b.point) { + if (!(a.point && b.point && (a.point == b.point || a.point.eq(b.point)) && sameValues(a.activeForPoint(a.to), b.activeForPoint(b.to)))) + comparator.comparePoint(pos, clipEnd, a.point, b.point); + } else { + if (clipEnd > pos && !sameValues(a.active, b.active)) + comparator.compareRange(pos, clipEnd, a.active, b.active); + } + if (end > endB) + break; + pos = end; + if (diff <= 0) + a.next(); + if (diff >= 0) + b.next(); + } + } + function sameValues(a, b) { + if (a.length != b.length) + return false; + for (let i = 0; i < a.length; i++) + if (a[i] != b[i] && !a[i].eq(b[i])) + return false; + return true; + } + function remove(array, index) { + for (let i = index, e = array.length - 1; i < e; i++) + array[i] = array[i + 1]; + array.pop(); + } + function insert(array, index, value) { + for (let i = array.length - 1; i >= index; i--) + array[i + 1] = array[i]; + array[index] = value; + } + function findMinIndex(value, array) { + let found = -1, foundPos = 1e9; + for (let i = 0; i < array.length; i++) + if ((array[i] - foundPos || value[i].endSide - value[found].endSide) < 0) { + found = i; + foundPos = array[i]; + } + return found; + } + function countColumn(string2, tabSize, to = string2.length) { + let n = 0; + for (let i = 0; i < to; ) { + if (string2.charCodeAt(i) == 9) { + n += tabSize - n % tabSize; + i++; + } else { + n++; + i = findClusterBreak(string2, i); + } + } + return n; + } + function findColumn(string2, col, tabSize, strict) { + for (let i = 0, n = 0; ; ) { + if (n >= col) + return i; + if (i == string2.length) + break; + n += string2.charCodeAt(i) == 9 ? tabSize - n % tabSize : 1; + i = findClusterBreak(string2, i); + } + return strict === true ? -1 : string2.length; + } + + // node_modules/style-mod/src/style-mod.js + var C = "\u037C"; + var COUNT = typeof Symbol == "undefined" ? "__" + C : Symbol.for(C); + var SET = typeof Symbol == "undefined" ? "__styleSet" + Math.floor(Math.random() * 1e8) : Symbol("styleSet"); + var top = typeof globalThis != "undefined" ? globalThis : typeof window != "undefined" ? window : {}; + var StyleModule = class { + // :: (Object