diff --git a/dist/basic-setup.d.ts b/dist/basic-setup.d.ts new file mode 100644 index 0000000..a7413c7 --- /dev/null +++ b/dist/basic-setup.d.ts @@ -0,0 +1,21 @@ +import { EditorState, EditorSelection, Compartment, SelectionRange, Facet, StateField, StateEffect, Transaction, Text, combineConfig, Annotation } from "@codemirror/state"; +import { julia as julia_andrey } from "@plutojl/lang-julia"; +import { keymap, EditorView, highlightSpecialChars, drawSelection, placeholder, Decoration, ViewUpdate, ViewPlugin, WidgetType, lineNumbers, rectangularSelection } from "@codemirror/view"; +import { defaultKeymap, indentMore, indentLess, historyKeymap, history } from "@codemirror/commands"; +import { indentOnInput, indentUnit, syntaxTree, syntaxTreeAvailable, bracketMatching, foldGutter, foldKeymap, HighlightStyle, defaultHighlightStyle, syntaxHighlighting } from "@codemirror/language"; +import { tags } from "@lezer/highlight"; +import { closeBrackets, closeBracketsKeymap } from "@codemirror/autocomplete"; +import * as autocomplete from "@codemirror/autocomplete"; +import { highlightSelectionMatches, searchKeymap, selectNextOccurrence } from "@codemirror/search"; +import { completionKeymap } from "@codemirror/autocomplete"; +import { TreeCursor, NodeProp, parseMixed } from "@lezer/common"; +import { markdown, markdownLanguage } from "@codemirror/lang-markdown"; +import { parseCode } from "@lezer/markdown"; +import { html, htmlLanguage } from "@codemirror/lang-html"; +import { javascript, javascriptLanguage } from "@codemirror/lang-javascript"; +import { css, cssLanguage } from "@codemirror/lang-css"; +import { sql, PostgreSQL } from "@codemirror/lang-sql"; +import { python, pythonLanguage } from "@codemirror/lang-python"; +import { collab } from "@codemirror/collab"; +export { css, cssLanguage }; +export { Facet, StateField, StateEffect, Transaction, indentUnit, EditorState, EditorSelection, Compartment, EditorView, SelectionRange, placeholder, julia_andrey, keymap, history, historyKeymap, defaultKeymap, indentMore, indentLess, tags, HighlightStyle, syntaxHighlighting, syntaxTree, syntaxTreeAvailable, autocomplete, lineNumbers, highlightSpecialChars, foldGutter, drawSelection, indentOnInput, defaultHighlightStyle, bracketMatching, closeBrackets, rectangularSelection, highlightSelectionMatches, closeBracketsKeymap, searchKeymap, selectNextOccurrence, foldKeymap, completionKeymap, Decoration, ViewUpdate, ViewPlugin, WidgetType, TreeCursor, Text, combineConfig, NodeProp, markdown, markdownLanguage, parseCode, parseMixed, html, htmlLanguage, javascript, javascriptLanguage, sql, PostgreSQL, python, pythonLanguage, collab, Annotation, }; diff --git a/dist/index.d.ts b/dist/index.d.ts index bbf0a00..fd3c2bd 100644 --- a/dist/index.d.ts +++ b/dist/index.d.ts @@ -263,6 +263,7 @@ stores the document length, and can only be applied to documents with exactly that length. */ declare class ChangeSet extends ChangeDesc { + private constructor(); /** Apply the changes to a document, returning the modified document. @@ -348,6 +349,7 @@ declare class SelectionRange { */ readonly to: number; private flags; + private constructor(); /** The anchor of the range—the side that doesn't move when you extend it. @@ -418,6 +420,7 @@ declare class EditorSelection { usually the range that was added last). */ readonly mainIndex: number; + private constructor(); /** Map a selection through a change. Used to adjust the selection position for changes. @@ -502,13 +505,14 @@ declare type FacetConfig = { */ static?: boolean; /** - If given, these extension(s) will be added to any state where - this facet is provided. (Note that, while a facet's default - value can be read from a state even if the facet wasn't present - in the state at all, these extensions won't be added in that + If given, these extension(s) (or the result of calling the given + function with the facet) will be added to any state where this + facet is provided. (Note that, while a facet's default value can + be read from a state even if the facet wasn't present in the + state at all, these extensions won't be added in that situation.) */ - enables?: Extension; + enables?: Extension | ((self: Facet) => Extension); }; /** A facet is a labeled value that is associated with an editor @@ -849,6 +853,7 @@ declare class Transaction { transaction is dispatched. */ readonly scrollIntoView: boolean; + private constructor(); /** The new document produced by the transaction. Contrary to [`.state`](https://codemirror.net/6/docs/ref/#state.Transaction.state)`.doc`, accessing this won't @@ -1006,6 +1011,7 @@ declare class EditorState { The current selection. */ readonly selection: EditorSelection; + private constructor(); /** Retrieve the value of a [state field](https://codemirror.net/6/docs/ref/#state.StateField). Throws an error when the state doesn't have that field, unless you pass @@ -1167,8 +1173,13 @@ declare class EditorState { 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(phrase: string): string; + phrase(phrase: string, ...insert: any[]): string; /** A facet used to register [language data](https://codemirror.net/6/docs/ref/#state.EditorState.languageDataAt) providers. @@ -1335,6 +1346,7 @@ declare class Range { The value associated with this range. */ readonly value: T; + private constructor(); } /** Collection of methods used when comparing range sets. @@ -1435,6 +1447,7 @@ way that makes them efficient to [map](https://codemirror.net/6/docs/ref/#state. structure. */ declare class RangeSet { + private constructor(); /** The number of ranges in the set. */ @@ -1688,6 +1701,7 @@ interface SyntaxNodeRef { readonly name: string; readonly tree: Tree | null; readonly node: SyntaxNode; + matchContext(context: readonly string[]): boolean; } interface SyntaxNode extends SyntaxNodeRef { parent: SyntaxNode | null; @@ -1766,7 +1780,6 @@ declare class InputStream { pos: number; private rangeIndex; private range; - resolveOffset(offset: number, assoc: -1 | 1): number; peek(offset: number): any; acceptToken(token: number, endOffset?: number): void; private getChunk; @@ -1774,14 +1787,12 @@ declare class InputStream { advance(n?: number): number; private setDone; } -interface Tokenizer { -} interface ExternalOptions { contextual?: boolean; fallback?: boolean; extend?: boolean; } -declare class ExternalTokenizer implements Tokenizer { +declare class ExternalTokenizer { constructor(token: (input: InputStream, stack: Stack) => void, options?: ExternalOptions); } @@ -1803,6 +1814,10 @@ interface ParserConfig { from: ExternalTokenizer; to: ExternalTokenizer; }[]; + specializers?: { + from: (value: string, stack: Stack) => number; + to: (value: string, stack: Stack) => number; + }[]; contextTracker?: ContextTracker; strict?: boolean; wrap?: ParseWrapper; @@ -1818,6 +1833,7 @@ declare class LRParser extends Parser { hasWrappers(): boolean; getName(term: number): string; get topNode(): NodeType; + static deserialize(spec: any): LRParser; } declare class StyleModule { @@ -2377,10 +2393,16 @@ declare class BidiSpan { get dir(): Direction; } -interface EditorConfig { +/** +The type of object given to the [`EditorView`](https://codemirror.net/6/docs/ref/#view.EditorView) +constructor. +*/ +interface EditorViewConfig extends EditorStateConfig { /** - The view's initial state. Defaults to an extension-less state - with an empty document. + The view's initial state. If not given, a new state is created + by passing this configuration object to + [`EditorState.create`](https://codemirror.net/6/docs/ref/#state.EditorState^create), using its + `doc`, `selection`, and `extensions` field (if provided). */ state?: EditorState; /** @@ -2459,10 +2481,11 @@ declare class EditorView { */ get compositionStarted(): boolean; private _dispatch; + private _root; /** The document or shadow root that the view lives in. */ - readonly root: DocumentOrShadowRoot; + get root(): DocumentOrShadowRoot; /** The DOM element that wraps the entire editor view. */ @@ -2494,11 +2517,7 @@ declare class EditorView { option, or put `view.dom` into your document after creating a view, so that the user can see the editor. */ - constructor( - /** - Initialization options. - */ - config?: EditorConfig); + constructor(config?: EditorViewConfig); /** All regular editor state updates should go through this. It takes a transaction or transaction spec and updates the view to @@ -2551,7 +2570,7 @@ declare class EditorView { know you registered a given plugin, it is recommended to check the return value of this method. */ - plugin(plugin: ViewPlugin): T | null; + plugin(plugin: ViewPlugin): T | null; /** The top position of the document, in screen coordinates. This may be negative when the editor is scrolled down. Points @@ -2568,13 +2587,14 @@ declare class EditorView { /** Find the text line or block widget at the given vertical position (which is interpreted as relative to the [top of the - document](https://codemirror.net/6/docs/ref/#view.EditorView.documentTop) + document](https://codemirror.net/6/docs/ref/#view.EditorView.documentTop)). */ elementAtHeight(height: number): BlockInfo; /** Find the line block (see [`lineBlockAt`](https://codemirror.net/6/docs/ref/#view.EditorView.lineBlockAt) at the given - height. + height, again interpreted relative to the [top of the + document](https://codemirror.net/6/docs/ref/#view.EditorView.documentTop). */ lineBlockAtHeight(height: number): BlockInfo; /** @@ -2737,6 +2757,11 @@ declare class EditorView { */ focus(): void; /** + Update the [root](https://codemirror.net/6/docs/ref/##view.EditorViewConfig.root) in which the editor lives. This is only + necessary when moving the editor's existing DOM to a new window or shadow root. + */ + setRoot(root: Document | ShadowRoot): void; + /** Clean up this editor view, removing its element from the document, unregistering event handlers, and notifying plugins. The view instance can no longer be used after @@ -2863,6 +2888,11 @@ declare class EditorView { functions are called _after_ the new viewport has been computed, and thus **must not** introduce block widgets or replacing decorations that cover line breaks. + + If you want decorated ranges to behave like atomic units for + cursor motion and deletion purposes, also provide the range set + containing the decorations to + [`EditorView.atomicRanges`](https://codemirror.net/6/docs/ref/#view.EditorView^atomicRanges). */ static decorations: Facet DecorationSet), readonly (DecorationSet | ((view: EditorView) => DecorationSet))[]>; /** @@ -2949,6 +2979,11 @@ declare class EditorView { search match). */ static announce: StateEffectType; + /** + Retrieve an editor view instance from the view's DOM + representation. + */ + static findFromDOM(dom: HTMLElement): EditorView | null; } /** Helper type that maps event names to event object types, or the @@ -3018,7 +3053,7 @@ interface KeyBinding { command function returns `false`, further bindings will be tried for the key. */ - run: Command; + run?: Command; /** When given, this defines a second binding, using the (possibly platform-specific) key name prefixed with `Shift-` to activate @@ -3026,6 +3061,11 @@ interface KeyBinding { */ shift?: Command; /** + When this property is present, the function is called for every + key that is not a multi-stroke prefix. + */ + any?: (view: EditorView, event: KeyboardEvent) => boolean; + /** By default, key bindings apply when focus is on the editor content (the `"editor"` scope). Some extensions, mostly those that define their own panels, might want to allow you to @@ -3278,6 +3318,10 @@ declare class Language { [name: string]: any; }>; /** + A language name. + */ + readonly name: string; + /** The extension value to install this as the document language. */ readonly extension: Extension; @@ -3300,7 +3344,11 @@ declare class Language { */ data: Facet<{ [name: string]: any; - }>, parser: Parser, extraExtensions?: Extension[]); + }>, parser: Parser, extraExtensions?: Extension[], + /** + A language name. + */ + name?: string); /** Query whether this language is active at the given position. */ @@ -3332,6 +3380,10 @@ declare class LRLanguage extends Language { Define a language from a parser. */ static define(spec: { + /** + The [name](https://codemirror.net/6/docs/ref/#Language.name) of the language. + */ + name?: string; /** The parser to use. Should already have added editor-relevant node props (and optionally things like dialect and top rule) @@ -3348,9 +3400,9 @@ declare class LRLanguage extends Language { }): LRLanguage; /** Create a new instance of this language with a reconfigured - version of its parser. + version of its parser and optionally a new name. */ - configure(options: ParserConfig): LRLanguage; + configure(options: ParserConfig, name?: string): LRLanguage; get allowsNesting(): boolean; } /** @@ -3549,6 +3601,11 @@ interface FoldGutterConfig { Supply event handlers for DOM events on this gutter. */ domEventHandlers?: Handlers; + /** + When given, if this returns true for a given view update, + recompute the fold markers. + */ + foldingChanged?: (update: ViewUpdate) => boolean; } /** Create an extension that registers a fold gutter, which shows a @@ -3562,6 +3619,10 @@ A highlight style associates CSS styles with higlighting [tags](https://lezer.codemirror.net/docs/ref#highlight.Tag). */ declare class HighlightStyle implements Highlighter { + /** + The tag styles used to create this highlight style. + */ + readonly specs: readonly TagStyle[]; /** A style module holding the CSS rules for this highlight style. When using @@ -3738,7 +3799,7 @@ declare function history(config?: HistoryConfig): Extension; Default key bindings for the undo history. - Mod-z: [`undo`](https://codemirror.net/6/docs/ref/#commands.undo). -- Mod-y (Mod-Shift-z on macOS): [`redo`](https://codemirror.net/6/docs/ref/#commands.redo). +- Mod-y (Mod-Shift-z on macOS) + Ctrl-Shift-z on Linux: [`redo`](https://codemirror.net/6/docs/ref/#commands.redo). - Mod-u: [`undoSelection`](https://codemirror.net/6/docs/ref/#commands.undoSelection). - Alt-u (Mod-Shift-u on macOS): [`redoSelection`](https://codemirror.net/6/docs/ref/#commands.redoSelection). */ @@ -3784,6 +3845,15 @@ interface CompletionConfig { */ activateOnTyping?: boolean; /** + By default, when completion opens, the first option is selected + and can be confirmed with + [`acceptCompletion`](https://codemirror.net/6/docs/ref/#autocomplete.acceptCompletion). When this + is set to false, the completion widget starts with no completion + selected, and the user has to explicitly move to a completion + before you can confirm one. + */ + selectOnOpen?: boolean; + /** Override the completion sources used. By default, they will be taken from the `"autocomplete"` [language data](https://codemirror.net/6/docs/ref/#state.EditorState.languageDataAt) (which should hold @@ -3831,12 +3901,26 @@ interface CompletionConfig { completion, and should produce a DOM node to show. `position` determines where in the DOM the result appears, relative to other added widgets and the standard content. The default icons - have position 20, the label position 50, and the detail position 70. + have position 20, the label position 50, and the detail position + 80. */ addToOptions?: { render: (completion: Completion, state: EditorState) => Node | null; position: number; }[]; + /** + The comparison function to use when sorting completions with the same + match score. Defaults to using + [`localeCompare`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare). + */ + compareCompletions?: (a: Completion, b: Completion) => number; + /** + By default, commands relating to an open completion only take + effect 75 milliseconds after the completion opened, so that key + presses made before the user is aware of the tooltip don't go to + the tooltip. This option can be used to configure that delay. + */ + interactionDelay?: number; } /** @@ -4044,6 +4128,12 @@ This annotation is added to transactions that are produced by picking a completion. */ declare const pickedCompletion: AnnotationType; +/** +Helper function that returns a transaction spec which inserts a +completion's text in the main selection range, and any other +selection range that has the same text in front of it. +*/ +declare function insertCompletionText(state: EditorState, text: string, from: number, to: number): TransactionSpec; /** Convert a snippet template to a function that can @@ -4070,6 +4160,11 @@ cursor out of the current field deactivates the fields. The order of fields defaults to textual order, but you can add numbers to placeholders (`${1}` or `${1:defaultText}`) to provide a custom order. + +To include a literal `${` or `#{` in your template, put a +backslash after the dollar or hash and before the brace (`$\\{`). +This will be removed and the sequence will not be interpreted as a +placeholder. */ declare function snippet(template: string): (editor: { state: EditorState; @@ -4145,6 +4240,11 @@ interface CloseBracketConfig { whitespace. Defaults to `")]}:;>"`. */ before?: string; + /** + When determining whether a given node may be a string, recognize + these prefixes before the opening quote. + */ + stringPrefixes?: string[]; } /** Extension to enable bracket-closing behavior. When a closeable @@ -4219,71 +4319,73 @@ the currently selected completion. */ declare function setSelectedCompletion(index: number): StateEffect; -type index_CloseBracketConfig = CloseBracketConfig; -type index_Completion = Completion; -type index_CompletionContext = CompletionContext; -declare const index_CompletionContext: typeof CompletionContext; -type index_CompletionResult = CompletionResult; -type index_CompletionSource = CompletionSource; -declare const index_acceptCompletion: typeof acceptCompletion; -declare const index_autocompletion: typeof autocompletion; -declare const index_clearSnippet: typeof clearSnippet; -declare const index_closeBrackets: typeof closeBrackets; -declare const index_closeBracketsKeymap: typeof closeBracketsKeymap; -declare const index_closeCompletion: typeof closeCompletion; -declare const index_completeAnyWord: typeof completeAnyWord; -declare const index_completeFromList: typeof completeFromList; -declare const index_completionKeymap: typeof completionKeymap; -declare const index_completionStatus: typeof completionStatus; -declare const index_currentCompletions: typeof currentCompletions; -declare const index_deleteBracketPair: typeof deleteBracketPair; -declare const index_ifIn: typeof ifIn; -declare const index_ifNotIn: typeof ifNotIn; -declare const index_insertBracket: typeof insertBracket; -declare const index_moveCompletionSelection: typeof moveCompletionSelection; -declare const index_nextSnippetField: typeof nextSnippetField; -declare const index_pickedCompletion: typeof pickedCompletion; -declare const index_prevSnippetField: typeof prevSnippetField; -declare const index_selectedCompletion: typeof selectedCompletion; -declare const index_selectedCompletionIndex: typeof selectedCompletionIndex; -declare const index_setSelectedCompletion: typeof setSelectedCompletion; -declare const index_snippet: typeof snippet; -declare const index_snippetCompletion: typeof snippetCompletion; -declare const index_snippetKeymap: typeof snippetKeymap; -declare const index_startCompletion: typeof startCompletion; -declare namespace index { +type index_d_CloseBracketConfig = CloseBracketConfig; +type index_d_Completion = Completion; +type index_d_CompletionContext = CompletionContext; +declare const index_d_CompletionContext: typeof CompletionContext; +type index_d_CompletionResult = CompletionResult; +type index_d_CompletionSource = CompletionSource; +declare const index_d_acceptCompletion: typeof acceptCompletion; +declare const index_d_autocompletion: typeof autocompletion; +declare const index_d_clearSnippet: typeof clearSnippet; +declare const index_d_closeBrackets: typeof closeBrackets; +declare const index_d_closeBracketsKeymap: typeof closeBracketsKeymap; +declare const index_d_closeCompletion: typeof closeCompletion; +declare const index_d_completeAnyWord: typeof completeAnyWord; +declare const index_d_completeFromList: typeof completeFromList; +declare const index_d_completionKeymap: typeof completionKeymap; +declare const index_d_completionStatus: typeof completionStatus; +declare const index_d_currentCompletions: typeof currentCompletions; +declare const index_d_deleteBracketPair: typeof deleteBracketPair; +declare const index_d_ifIn: typeof ifIn; +declare const index_d_ifNotIn: typeof ifNotIn; +declare const index_d_insertBracket: typeof insertBracket; +declare const index_d_insertCompletionText: typeof insertCompletionText; +declare const index_d_moveCompletionSelection: typeof moveCompletionSelection; +declare const index_d_nextSnippetField: typeof nextSnippetField; +declare const index_d_pickedCompletion: typeof pickedCompletion; +declare const index_d_prevSnippetField: typeof prevSnippetField; +declare const index_d_selectedCompletion: typeof selectedCompletion; +declare const index_d_selectedCompletionIndex: typeof selectedCompletionIndex; +declare const index_d_setSelectedCompletion: typeof setSelectedCompletion; +declare const index_d_snippet: typeof snippet; +declare const index_d_snippetCompletion: typeof snippetCompletion; +declare const index_d_snippetKeymap: typeof snippetKeymap; +declare const index_d_startCompletion: typeof startCompletion; +declare namespace index_d { export { - index_CloseBracketConfig as CloseBracketConfig, - index_Completion as Completion, - index_CompletionContext as CompletionContext, - index_CompletionResult as CompletionResult, - index_CompletionSource as CompletionSource, - index_acceptCompletion as acceptCompletion, - index_autocompletion as autocompletion, - index_clearSnippet as clearSnippet, - index_closeBrackets as closeBrackets, - index_closeBracketsKeymap as closeBracketsKeymap, - index_closeCompletion as closeCompletion, - index_completeAnyWord as completeAnyWord, - index_completeFromList as completeFromList, - index_completionKeymap as completionKeymap, - index_completionStatus as completionStatus, - index_currentCompletions as currentCompletions, - index_deleteBracketPair as deleteBracketPair, - index_ifIn as ifIn, - index_ifNotIn as ifNotIn, - index_insertBracket as insertBracket, - index_moveCompletionSelection as moveCompletionSelection, - index_nextSnippetField as nextSnippetField, - index_pickedCompletion as pickedCompletion, - index_prevSnippetField as prevSnippetField, - index_selectedCompletion as selectedCompletion, - index_selectedCompletionIndex as selectedCompletionIndex, - index_setSelectedCompletion as setSelectedCompletion, - index_snippet as snippet, - index_snippetCompletion as snippetCompletion, - index_snippetKeymap as snippetKeymap, - index_startCompletion as startCompletion, + index_d_CloseBracketConfig as CloseBracketConfig, + index_d_Completion as Completion, + index_d_CompletionContext as CompletionContext, + index_d_CompletionResult as CompletionResult, + index_d_CompletionSource as CompletionSource, + index_d_acceptCompletion as acceptCompletion, + index_d_autocompletion as autocompletion, + index_d_clearSnippet as clearSnippet, + index_d_closeBrackets as closeBrackets, + index_d_closeBracketsKeymap as closeBracketsKeymap, + index_d_closeCompletion as closeCompletion, + index_d_completeAnyWord as completeAnyWord, + index_d_completeFromList as completeFromList, + index_d_completionKeymap as completionKeymap, + index_d_completionStatus as completionStatus, + index_d_currentCompletions as currentCompletions, + index_d_deleteBracketPair as deleteBracketPair, + index_d_ifIn as ifIn, + index_d_ifNotIn as ifNotIn, + index_d_insertBracket as insertBracket, + index_d_insertCompletionText as insertCompletionText, + index_d_moveCompletionSelection as moveCompletionSelection, + index_d_nextSnippetField as nextSnippetField, + index_d_pickedCompletion as pickedCompletion, + index_d_prevSnippetField as prevSnippetField, + index_d_selectedCompletion as selectedCompletion, + index_d_selectedCompletionIndex as selectedCompletionIndex, + index_d_setSelectedCompletion as setSelectedCompletion, + index_d_snippet as snippet, + index_d_snippetCompletion as snippetCompletion, + index_d_snippetKeymap as snippetKeymap, + index_d_startCompletion as startCompletion, }; } @@ -4316,6 +4418,11 @@ itself will be highlighted with `"cm-selectionMatch-main"`. */ declare function highlightSelectionMatches(options?: HighlightOptions): Extension; /** +Select next occurrence of the current selection. Expand selection +to the surrounding word when the selection is empty. +*/ +declare const selectNextOccurrence: StateCommand; +/** Default search-related key bindings. - Mod-f: [`openSearchPanel`](https://codemirror.net/6/docs/ref/#search.openSearchPanel) @@ -4461,12 +4568,14 @@ declare function markdown(config?: { */ defaultCodeLanguage?: Language | LanguageSupport; /** - A collection of language descriptions to search through for a - matching language (with - [`LanguageDescription.matchLanguageName`](https://codemirror.net/6/docs/ref/#language.LanguageDescription^matchLanguageName)) - when a fenced code block has an info string. + A source of language support for highlighting fenced code + blocks. When it is an array, the parser will use + [`LanguageDescription.matchLanguageName`](https://codemirror.net/6/docs/ref/#language.LanguageDescription^matchLanguageName) + with the fenced code info to find a matching language. When it + is a function, will be called with the info string and may + return a language or `LanguageDescription` object. */ - codeLanguages?: readonly LanguageDescription[]; + codeLanguages?: readonly LanguageDescription[] | ((info: string) => Language | LanguageDescription | null); /** Set this to false to disable installation of the Markdown [keymap](https://codemirror.net/6/docs/ref/#lang-markdown.markdownKeymap). @@ -4485,6 +4594,23 @@ declare function markdown(config?: { base?: Language; }): LanguageSupport; +/** +Type used to specify tags to complete. +*/ +interface TagSpec { + /** + Define tag-specific attributes. Property names are attribute + names, and property values can be null to indicate free-form + attributes, or a list of strings for suggested attribute values. + */ + attrs?: Record; + /** + Can be used to specify a list of child tags that are valid + inside this tag. The default is to allow any tag. + */ + children?: readonly string[]; +} + /** A language provider based on the [Lezer HTML parser](https://github.com/lezer-parser/html), extended with the @@ -4510,6 +4636,14 @@ declare function html(config?: { is included in the support extensions. Defaults to true. */ autoCloseTags?: boolean; + /** + Add additional tags that can be completed. + */ + extraTags?: Record; + /** + Add additional completable attributes to all tags. + */ + extraGlobalAttributes?: Record; }): LanguageSupport; /** @@ -4569,6 +4703,11 @@ declare type SQLDialectSpec = { */ spaceAfterDashes?: boolean; /** + When enabled, things quoted with "$$" are treated as + strings, rather than identifiers. + */ + doubleDollarQuotedStrings?: boolean; + /** When enabled, things quoted with double quotes are treated as strings, rather than identifiers. */ @@ -4592,6 +4731,12 @@ declare type SQLDialectSpec = { to `"\""`. */ identifierQuotes?: string; + /** + Controls whether bit values can be defined as 0b1010. Defaults + to false. + */ + unquotedBitLiterals?: boolean; + treatBitsAsBytes?: boolean; }; /** Represents an SQL dialect. @@ -4601,6 +4746,7 @@ declare class SQLDialect { The language for this dialect. */ readonly language: LRLanguage; + private constructor(); /** Returns the language for this dialect as an extension. */ @@ -4620,8 +4766,9 @@ interface SQLConfig { */ dialect?: SQLDialect; /** - An object that maps table names to options (columns) that can - be completed for that table. Use lower-case names here. + An object that maps table names, optionally prefixed with a + schema name (`"schema.table"`) to options (columns) that can be + completed for that table. Use lower-case names here. */ schema?: { [table: string]: readonly (string | Completion)[]; @@ -4639,6 +4786,11 @@ interface SQLConfig { */ defaultTable?: string; /** + When given, tables prefixed with this schema name can be + completed directly at the top level. + */ + defaultSchema?: string; + /** When set to true, keyword completions will be upper-case. */ upperCaseKeywords?: boolean; @@ -4690,4 +4842,4 @@ Create an instance of the collaborative editing plugin. */ declare function collab(config?: CollabConfig): Extension; -export { Annotation, Compartment, Decoration, EditorSelection, EditorState, EditorView, Facet, HighlightStyle, NodeProp, PostgreSQL, SelectionRange, StateEffect, StateField, Text, Transaction, TreeCursor, ViewPlugin, ViewUpdate, WidgetType, index as autocomplete, bracketMatching, closeBrackets, closeBracketsKeymap, collab, combineConfig, completionKeymap, css, cssLanguage, defaultHighlightStyle, defaultKeymap, drawSelection, foldGutter, foldKeymap, highlightSelectionMatches, highlightSpecialChars, history, historyKeymap, html, htmlLanguage, indentLess, indentMore, indentOnInput, indentUnit, javascript, javascriptLanguage, julia as julia_andrey, keymap, lineNumbers, markdown, markdownLanguage, parseCode, parseMixed, placeholder, python, pythonLanguage, rectangularSelection, searchKeymap, sql, syntaxHighlighting, syntaxTree, syntaxTreeAvailable, tags }; +export { Annotation, Compartment, Decoration, EditorSelection, EditorState, EditorView, Facet, HighlightStyle, NodeProp, PostgreSQL, SelectionRange, StateEffect, StateField, Text, Transaction, TreeCursor, ViewPlugin, ViewUpdate, WidgetType, index_d as autocomplete, bracketMatching, closeBrackets, closeBracketsKeymap, collab, combineConfig, completionKeymap, css, cssLanguage, defaultHighlightStyle, defaultKeymap, drawSelection, foldGutter, foldKeymap, highlightSelectionMatches, highlightSpecialChars, history, historyKeymap, html, htmlLanguage, indentLess, indentMore, indentOnInput, indentUnit, javascript, javascriptLanguage, julia as julia_andrey, keymap, lineNumbers, markdown, markdownLanguage, parseCode, parseMixed, placeholder, python, pythonLanguage, rectangularSelection, searchKeymap, selectNextOccurrence, sql, syntaxHighlighting, syntaxTree, syntaxTreeAvailable, tags }; diff --git a/dist/index.es.js b/dist/index.es.js index 9354593..3fedab2 100644 --- a/dist/index.es.js +++ b/dist/index.es.js @@ -27,10 +27,10 @@ class Text { */ replace(from, to, text) { let parts = []; - this.decompose(0, from, parts, 2 /* To */); + this.decompose(0, from, parts, 2 /* Open.To */); if (text.length) - text.decompose(0, text.length, parts, 1 /* From */ | 2 /* To */); - this.decompose(to, this.length, parts, 1 /* From */); + text.decompose(0, text.length, parts, 1 /* Open.From */ | 2 /* Open.To */); + this.decompose(to, this.length, parts, 1 /* Open.From */); return TextNode.from(parts, this.length - (to - from) + text.length); } /** @@ -120,7 +120,7 @@ class Text { throw new RangeError("A document must have at least one line"); if (text.length == 1 && !text[0]) return Text.empty; - return text.length <= 32 /* Branch */ ? new TextLeaf(text) : TextNode.from(TextLeaf.split(text, [])); + return text.length <= 32 /* Tree.Branch */ ? new TextLeaf(text) : TextNode.from(TextLeaf.split(text, [])); } } // Leaves store an array of line strings. There are always line breaks @@ -146,10 +146,10 @@ class TextLeaf extends Text { 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 /* From */) { + if (open & 1 /* Open.From */) { let prev = target.pop(); let joined = appendText(text.text, prev.text.slice(), 0, text.length); - if (joined.length <= 32 /* Branch */) { + if (joined.length <= 32 /* Tree.Branch */) { target.push(new TextLeaf(joined, prev.length + text.length)); } else { @@ -166,7 +166,7 @@ class TextLeaf extends Text { return super.replace(from, to, text); 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 /* Branch */) + if (lines.length <= 32 /* Tree.Branch */) return new TextLeaf(lines, newLen); return TextNode.from(TextLeaf.split(lines, []), newLen); } @@ -192,7 +192,7 @@ class TextLeaf extends Text { for (let line of text) { part.push(line); len += line.length + 1; - if (part.length == 32 /* Branch */) { + if (part.length == 32 /* Tree.Branch */) { target.push(new TextLeaf(part, len)); part = []; len = -1; @@ -229,7 +229,7 @@ class TextNode extends Text { 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 /* From */ : 0) | (end >= to ? 2 /* To */ : 0)); + let childOpen = open & ((pos <= from ? 1 /* Open.From */ : 0) | (end >= to ? 2 /* Open.To */ : 0)); if (pos >= from && end <= to && !childOpen) target.push(child); else @@ -248,8 +248,8 @@ class TextNode extends Text { 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 /* BranchShift */ - 1)) && - updated.lines > (totalLines >> (5 /* BranchShift */ + 1))) { + if (updated.lines < (totalLines >> (5 /* Tree.BranchShift */ - 1)) && + updated.lines > (totalLines >> (5 /* Tree.BranchShift */ + 1))) { let copy = this.children.slice(); copy[i] = updated; return new TextNode(copy, this.length - (to - from) + text.length); @@ -295,13 +295,13 @@ class TextNode extends Text { let lines = 0; for (let ch of children) lines += ch.lines; - if (lines < 32 /* Branch */) { + if (lines < 32 /* Tree.Branch */) { let flat = []; for (let ch of children) ch.flatten(flat); return new TextLeaf(flat, length); } - let chunk = Math.max(32 /* Branch */, lines >> 5 /* BranchShift */), maxChunk = chunk << 1, minChunk = chunk >> 1; + let chunk = Math.max(32 /* Tree.Branch */, lines >> 5 /* Tree.BranchShift */), maxChunk = chunk << 1, minChunk = chunk >> 1; let chunked = [], currentLines = 0, currentLen = -1, currentChunk = []; function add(child) { let last; @@ -315,7 +315,7 @@ class TextNode extends Text { } else if (child instanceof TextLeaf && currentLines && (last = currentChunk[currentChunk.length - 1]) instanceof TextLeaf && - child.lines + last.lines <= 32 /* Branch */) { + child.lines + last.lines <= 32 /* Tree.Branch */) { currentLines += child.lines; currentLen += child.length + 1; currentChunk[currentChunk.length - 1] = new TextLeaf(last.text.concat(child.text), last.length + 1 + child.length); @@ -512,7 +512,7 @@ if (typeof Symbol != "undefined") { This type describes a line in the document. It is created on-demand when lines are [queried](https://codemirror.net/6/docs/ref/#state.Text.lineAt). */ -class Line$1 { +let Line$1 = class Line { /** @internal */ @@ -543,7 +543,7 @@ class Line$1 { The length of the line (not including any line break after it). */ get length() { return this.to - this.from; } -} +}; // Compressed representation of the Grapheme_Cluster_Break=Extend // information from @@ -644,10 +644,7 @@ function fromCodePoint(code) { return String.fromCharCode((code >> 10) + 0xd800, (code & 1023) + 0xdc00); } /** -The first character that takes up two positions in a JavaScript -string. It is often useful to compare with this after calling -`codePointAt`, to figure out whether your character takes up 1 or -2 index positions. +The amount of positions a character takes up a JavaScript string. */ function codePointSize(code) { return code < 0x10000 ? 1 : 2; } @@ -842,6 +839,10 @@ class ChangeDesc { throw new RangeError("Invalid JSON representation of ChangeDesc"); return new ChangeDesc(json); } + /** + @internal + */ + static create(sections) { return new ChangeDesc(sections); } } /** A change set represents a group of modifications to a document. It @@ -849,9 +850,6 @@ stores the document length, and can only be applied to documents with exactly that length. */ class ChangeSet extends ChangeDesc { - /** - @internal - */ constructor(sections, /** @internal @@ -930,7 +928,7 @@ class ChangeSet extends ChangeDesc { Get a [change description](https://codemirror.net/6/docs/ref/#state.ChangeDesc) for this change set. */ - get desc() { return new ChangeDesc(this.sections); } + get desc() { return ChangeDesc.create(this.sections); } /** @internal */ @@ -963,7 +961,7 @@ class ChangeSet extends ChangeDesc { } } return { changes: new ChangeSet(resultSections, resultInserted), - filtered: new ChangeDesc(filteredSections) }; + filtered: ChangeDesc.create(filteredSections) }; } /** Serialize this change set to a JSON-representable value. @@ -1065,6 +1063,12 @@ class ChangeSet extends ChangeDesc { } return new ChangeSet(sections, inserted); } + /** + @internal + */ + static createSet(sections, inserted) { + return new ChangeSet(sections, inserted); + } } function addSection(sections, len, ins, forceJoin = false) { if (len == 0 && ins <= 0) @@ -1121,54 +1125,68 @@ function iterChanges(desc, f, individual) { } } function mapSet(setA, setB, before, mkSet = false) { + // Produce a copy of setA that applies to the document after setB + // has been applied (assuming both start at the same document). let sections = [], insert = mkSet ? [] : null; let a = new SectionIter(setA), b = new SectionIter(setB); - for (let posA = 0, posB = 0;;) { - if (a.ins == -1) { - posA += a.len; - a.next(); - } - else if (b.ins == -1 && posB < posA) { - let skip = Math.min(b.len, posA - posB); - b.forward(skip); - addSection(sections, skip, -1); - posB += skip; + // Iterate over both sets in parallel. inserted tracks, for changes + // in A that have to be processed piece-by-piece, whether their + // content has been inserted already, and refers to the section + // index. + for (let inserted = -1;;) { + if (a.ins == -1 && b.ins == -1) { + // Move across ranges skipped by both sets. + let len = Math.min(a.len, b.len); + addSection(sections, len, -1); + a.forward(len); + b.forward(len); } - else if (b.ins >= 0 && (a.done || posB < posA || posB == posA && (b.len < a.len || b.len == a.len && !before))) { + else if (b.ins >= 0 && (a.ins < 0 || inserted == a.i || a.off == 0 && (b.len < a.len || b.len == a.len && !before))) { + // If there's a change in B that comes before the next change in + // A (ordered by start pos, then len, then before flag), skip + // that (and process any changes in A it covers). + let len = b.len; addSection(sections, b.ins, -1); - while (posA > posB && !a.done && posA + a.len < posB + b.len) { - posA += a.len; - a.next(); + 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 (insert) + addInsert(insert, sections, a.text); + inserted = a.i; + } + a.forward(piece); + len -= piece; } - posB += b.len; b.next(); } else if (a.ins >= 0) { - let len = 0, end = posA + a.len; - for (;;) { - if (b.ins >= 0 && posB > posA && posB + b.len < end) { - len += b.ins; - posB += b.len; + // Process the part of a change in A up to the start of the next + // non-deletion change in B (if overlapping). + 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 if (b.ins == -1 && posB < end) { - let skip = Math.min(b.len, end - posB); - len += skip; - b.forward(skip); - posB += skip; - } else { break; } } - addSection(sections, len, a.ins); - if (insert) + addSection(sections, len, inserted < a.i ? a.ins : 0); + if (insert && inserted < a.i) addInsert(insert, sections, a.text); - posA = end; - a.next(); + inserted = a.i; + a.forward(a.len - left); } else if (a.done && b.done) { - return insert ? new ChangeSet(sections, insert) : new ChangeDesc(sections); + return insert ? ChangeSet.createSet(sections, insert) : ChangeDesc.create(sections); } else { throw new Error("Mismatched change set lengths"); @@ -1181,7 +1199,7 @@ function composeSets(setA, setB, mkSet = false) { let a = new SectionIter(setA), b = new SectionIter(setB); for (let open = false;;) { if (a.done && b.done) { - return insert ? new ChangeSet(sections, insert) : new ChangeDesc(sections); + return insert ? ChangeSet.createSet(sections, insert) : ChangeDesc.create(sections); } else if (a.ins == 0) { // Deletion in A addSection(sections, a.len, 0, open); @@ -1276,9 +1294,6 @@ is enabled, a [selection](https://codemirror.net/6/docs/ref/#state.EditorSelecti multiple ranges. By default, selections hold exactly one range. */ class SelectionRange { - /** - @internal - */ constructor( /** The lower boundary of the range. @@ -1296,12 +1311,12 @@ class SelectionRange { The anchor of the range—the side that doesn't move when you extend it. */ - get anchor() { return this.flags & 16 /* Inverted */ ? this.to : this.from; } + get anchor() { return this.flags & 16 /* RangeFlag.Inverted */ ? 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 & 16 /* Inverted */ ? this.from : this.to; } + get head() { return this.flags & 16 /* RangeFlag.Inverted */ ? this.from : this.to; } /** True when `anchor` and `head` are at the same position. */ @@ -1312,13 +1327,13 @@ class SelectionRange { the character before its position, 1 the character after, and 0 means no association. */ - get assoc() { return this.flags & 4 /* AssocBefore */ ? -1 : this.flags & 8 /* AssocAfter */ ? 1 : 0; } + get assoc() { return this.flags & 4 /* RangeFlag.AssocBefore */ ? -1 : this.flags & 8 /* RangeFlag.AssocAfter */ ? 1 : 0; } /** The bidirectional text level associated with this cursor, if any. */ get bidiLevel() { - let level = this.flags & 3 /* BidiLevelMask */; + let level = this.flags & 3 /* RangeFlag.BidiLevelMask */; return level == 3 ? null : level; } /** @@ -1328,8 +1343,8 @@ class SelectionRange { lines of different length. */ get goalColumn() { - let value = this.flags >> 5 /* GoalColumnOffset */; - return value == 33554431 /* NoGoalColumn */ ? undefined : value; + let value = this.flags >> 5 /* RangeFlag.GoalColumnOffset */; + return value == 33554431 /* RangeFlag.NoGoalColumn */ ? undefined : value; } /** Map this range through a change, producing a valid range in the @@ -1374,14 +1389,17 @@ class SelectionRange { throw new RangeError("Invalid JSON representation for SelectionRange"); return EditorSelection.range(json.anchor, json.head); } + /** + @internal + */ + static create(from, to, flags) { + return new SelectionRange(from, to, flags); + } } /** An editor selection holds one or more selection ranges. */ class EditorSelection { - /** - @internal - */ constructor( /** The ranges in the selection, sorted by position. Ranges cannot @@ -1392,7 +1410,7 @@ class EditorSelection { The index of the _main_ range in the selection (which is usually the range that was added last). */ - mainIndex = 0) { + mainIndex) { this.ranges = ranges; this.mainIndex = mainIndex; } @@ -1428,7 +1446,7 @@ class EditorSelection { holding only the main range from this selection. */ asSingle() { - return this.ranges.length == 1 ? this : new EditorSelection([this.main]); + return this.ranges.length == 1 ? this : new EditorSelection([this.main], 0); } /** Extend this selection with an extra range. @@ -1476,7 +1494,7 @@ class EditorSelection { for (let pos = 0, i = 0; i < ranges.length; i++) { let range = ranges[i]; if (range.empty ? range.from <= pos : range.from < pos) - return normalized(ranges.slice(), mainIndex); + return EditorSelection.normalized(ranges.slice(), mainIndex); pos = range.to; } return new EditorSelection(ranges, mainIndex); @@ -1486,33 +1504,36 @@ class EditorSelection { safely ignore the optional arguments in most situations. */ static cursor(pos, assoc = 0, bidiLevel, goalColumn) { - return new SelectionRange(pos, pos, (assoc == 0 ? 0 : assoc < 0 ? 4 /* AssocBefore */ : 8 /* AssocAfter */) | + return SelectionRange.create(pos, pos, (assoc == 0 ? 0 : assoc < 0 ? 4 /* RangeFlag.AssocBefore */ : 8 /* RangeFlag.AssocAfter */) | (bidiLevel == null ? 3 : Math.min(2, bidiLevel)) | - ((goalColumn !== null && goalColumn !== void 0 ? goalColumn : 33554431 /* NoGoalColumn */) << 5 /* GoalColumnOffset */)); + ((goalColumn !== null && goalColumn !== void 0 ? goalColumn : 33554431 /* RangeFlag.NoGoalColumn */) << 5 /* RangeFlag.GoalColumnOffset */)); } /** Create a selection range. */ static range(anchor, head, goalColumn) { - let goal = (goalColumn !== null && goalColumn !== void 0 ? goalColumn : 33554431 /* NoGoalColumn */) << 5 /* GoalColumnOffset */; - return head < anchor ? new SelectionRange(head, anchor, 16 /* Inverted */ | goal | 8 /* AssocAfter */) - : new SelectionRange(anchor, head, goal | (head > anchor ? 4 /* AssocBefore */ : 0)); + let goal = (goalColumn !== null && goalColumn !== void 0 ? goalColumn : 33554431 /* RangeFlag.NoGoalColumn */) << 5 /* RangeFlag.GoalColumnOffset */; + return head < anchor ? SelectionRange.create(head, anchor, 16 /* RangeFlag.Inverted */ | goal | 8 /* RangeFlag.AssocAfter */) + : SelectionRange.create(anchor, head, goal | (head > anchor ? 4 /* RangeFlag.AssocBefore */ : 0)); } -} -function 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)); + /** + @internal + */ + 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); } - return new EditorSelection(ranges, mainIndex); } function checkSelection(selection, docLength) { for (let range of selection.ranges) @@ -1544,21 +1565,17 @@ class Facet { /** @internal */ - compare, isStatic, - /** - @internal - */ - extensions) { + compare, isStatic, enables) { this.combine = combine; this.compareInput = compareInput; this.compare = compare; this.isStatic = isStatic; - this.extensions = extensions; /** @internal */ this.id = nextID++; this.default = combine([]); + this.extensions = typeof enables == "function" ? enables(this) : enables; } /** Define a new facet. @@ -1570,7 +1587,7 @@ class Facet { Returns an extension that adds the given value to this facet. */ of(value) { - return new FacetProvider([], this, 0 /* Static */, value); + return new FacetProvider([], this, 0 /* Provider.Static */, value); } /** Create an extension that computes a value for the facet from a @@ -1584,7 +1601,7 @@ class Facet { compute(deps, get) { if (this.isStatic) throw new Error("Can't compute a static facet"); - return new FacetProvider(deps, this, 1 /* Single */, get); + return new FacetProvider(deps, this, 1 /* Provider.Single */, get); } /** Create an extension that computes zero or more values for this @@ -1593,7 +1610,7 @@ class Facet { computeN(deps, get) { if (this.isStatic) throw new Error("Can't compute a static facet"); - return new FacetProvider(deps, this, 2 /* Multi */, get); + return new FacetProvider(deps, this, 2 /* Provider.Multi */, get); } from(field, get) { if (!get) @@ -1616,7 +1633,7 @@ class FacetProvider { var _a; let getter = this.value; let compare = this.facet.compareInput; - let id = this.id, idx = addresses[id] >> 1, multi = this.type == 2 /* Multi */; + let id = this.id, idx = addresses[id] >> 1, multi = this.type == 2 /* Provider.Multi */; let depDoc = false, depSel = false, depAddrs = []; for (let dep of this.dependencies) { if (dep == "doc") @@ -1629,14 +1646,14 @@ class FacetProvider { return { create(state) { state.values[idx] = getter(state); - return 1 /* Changed */; + return 1 /* SlotStatus.Changed */; }, 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], compare) : !compare(newVal, state.values[idx])) { state.values[idx] = newVal; - return 1 /* Changed */; + return 1 /* SlotStatus.Changed */; } } return 0; @@ -1655,7 +1672,7 @@ class FacetProvider { } } state.values[idx] = newVal; - return 1 /* Changed */; + return 1 /* SlotStatus.Changed */; } }; } @@ -1671,7 +1688,7 @@ function compareArray(a, b, compare) { function ensureAll(state, addrs) { let changed = false; for (let addr of addrs) - if (ensureAddr(state, addr) & 1 /* Changed */) + if (ensureAddr(state, addr) & 1 /* SlotStatus.Changed */) changed = true; return changed; } @@ -1684,7 +1701,7 @@ function dynamicFacetSlot(addresses, facet, providers) { let values = []; for (let i = 0; i < providerAddrs.length; i++) { let value = getAddr(state, providerAddrs[i]); - if (providerTypes[i] == 2 /* Multi */) + if (providerTypes[i] == 2 /* Provider.Multi */) for (let val of value) values.push(val); else @@ -1697,7 +1714,7 @@ function dynamicFacetSlot(addresses, facet, providers) { for (let addr of providerAddrs) ensureAddr(state, addr); state.values[idx] = get(state); - return 1 /* Changed */; + return 1 /* SlotStatus.Changed */; }, update(state, tr) { if (!ensureAll(state, dynamic)) @@ -1706,7 +1723,7 @@ function dynamicFacetSlot(addresses, facet, providers) { if (facet.compare(value, state.values[idx])) return 0; state.values[idx] = value; - return 1 /* Changed */; + return 1 /* SlotStatus.Changed */; }, reconfigure(state, oldState) { let depChanged = ensureAll(state, providerAddrs); @@ -1721,7 +1738,7 @@ function dynamicFacetSlot(addresses, facet, providers) { return 0; } state.values[idx] = value; - return 1 /* Changed */; + return 1 /* SlotStatus.Changed */; } }; } @@ -1771,7 +1788,7 @@ class StateField { return { create: (state) => { state.values[idx] = this.create(state); - return 1 /* Changed */; + return 1 /* SlotStatus.Changed */; }, update: (state, tr) => { let oldVal = state.values[idx]; @@ -1779,7 +1796,7 @@ class StateField { if (this.compareF(oldVal, value)) return 0; state.values[idx] = value; - return 1 /* Changed */; + return 1 /* SlotStatus.Changed */; }, reconfigure: (state, oldState) => { if (oldState.config.address[this.id] != null) { @@ -1787,7 +1804,7 @@ class StateField { return 0; } state.values[idx] = this.create(state); - return 1 /* Changed */; + return 1 /* SlotStatus.Changed */; } }; } @@ -1896,7 +1913,7 @@ class Configuration { this.facets = facets; this.statusTemplate = []; while (this.statusTemplate.length < dynamicSlots.length) - this.statusTemplate.push(0 /* Unresolved */); + this.statusTemplate.push(0 /* SlotStatus.Unresolved */); } staticFacet(facet) { let addr = this.address[facet.id]; @@ -1923,7 +1940,7 @@ class Configuration { for (let id in facets) { let providers = facets[id], facet = providers[0].facet; let oldProviders = oldFacets && oldFacets[id] || []; - if (providers.every(p => p.type == 0 /* Static */)) { + if (providers.every(p => p.type == 0 /* Provider.Static */)) { address[facet.id] = (staticValues.length << 1) | 1; if (sameArray$1(oldProviders, providers)) { staticValues.push(oldState.facet(facet)); @@ -1935,7 +1952,7 @@ class Configuration { } else { for (let p of providers) { - if (p.type == 0 /* Static */) { + if (p.type == 0 /* Provider.Static */) { address[p.id] = (staticValues.length << 1) | 1; staticValues.push(p.value); } @@ -1989,7 +2006,7 @@ function flatten(extension, compartments, newCompartments) { else if (ext instanceof FacetProvider) { result[prec].push(ext); if (ext.facet.extensions) - inner(ext.facet.extensions, prec); + inner(ext.facet.extensions, Prec_.default); } else { let content = ext.extension; @@ -2003,16 +2020,16 @@ function flatten(extension, compartments, newCompartments) { } function ensureAddr(state, addr) { if (addr & 1) - return 2 /* Computed */; + return 2 /* SlotStatus.Computed */; let idx = addr >> 1; let status = state.status[idx]; - if (status == 4 /* Computing */) + if (status == 4 /* SlotStatus.Computing */) throw new Error("Cyclic dependency between fields and/or facets"); - if (status & 2 /* Computed */) + if (status & 2 /* SlotStatus.Computed */) return status; - state.status[idx] = 4 /* Computing */; + state.status[idx] = 4 /* SlotStatus.Computing */; let changed = state.computeSlot(state, state.config.dynamicSlots[idx]); - return state.status[idx] = 2 /* Computed */ | changed; + return state.status[idx] = 2 /* SlotStatus.Computed */ | changed; } function getAddr(state, addr) { return addr & 1 ? state.config.staticValues[addr >> 1] : state.values[addr >> 1]; @@ -2178,9 +2195,6 @@ dispatch one by calling [`EditorView.dispatch`](https://codemirror.net/6/docs/ref/#view.EditorView.dispatch). */ class Transaction { - /** - @internal - */ constructor( /** The state from which the transaction starts. @@ -2228,6 +2242,12 @@ class Transaction { this.annotations = annotations.concat(Transaction.time.of(Date.now())); } /** + @internal + */ + static create(startState, changes, selection, effects, annotations, scrollIntoView) { + return new Transaction(startState, changes, selection, effects, annotations, scrollIntoView); + } + /** 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 @@ -2398,7 +2418,7 @@ function resolveTransaction(state, specs, filter) { let seq = !!specs[i].sequential; s = mergeTransaction(s, resolveTransactionInner(state, specs[i], seq ? s.changes.newLength : state.doc.length), seq); } - let tr = new Transaction(state, s.changes, s.selection, s.effects, s.annotations, s.scrollIntoView); + let tr = Transaction.create(state, s.changes, s.selection, s.effects, s.annotations, s.scrollIntoView); return extendTransaction(filter ? filterTransaction(tr) : tr); } // Finish a transaction by applying filters if necessary. @@ -2424,9 +2444,9 @@ function filterTransaction(tr) { else { let filtered = tr.changes.filter(result); changes = filtered.changes; - back = filtered.filtered.invertedDesc; + back = filtered.filtered.mapDesc(filtered.changes).invertedDesc; } - tr = new Transaction(state, changes, tr.selection && tr.selection.map(back), StateEffect.mapEffects(tr.effects, back), tr.annotations, tr.scrollIntoView); + tr = Transaction.create(state, changes, tr.selection && tr.selection.map(back), StateEffect.mapEffects(tr.effects, back), tr.annotations, tr.scrollIntoView); } // Transaction filters let filters = state.facet(transactionFilter); @@ -2446,9 +2466,9 @@ function extendTransaction(tr) { for (let i = extenders.length - 1; i >= 0; i--) { let extension = extenders[i](tr); if (extension && Object.keys(extension).length) - spec = mergeTransaction(tr, resolveTransactionInner(state, extension, tr.changes.newLength), true); + spec = mergeTransaction(spec, resolveTransactionInner(state, extension, tr.changes.newLength), true); } - return spec == tr ? tr : new Transaction(state, tr.changes, tr.selection, spec.effects, spec.annotations, spec.scrollIntoView); + return spec == tr ? tr : Transaction.create(state, tr.changes, tr.selection, spec.effects, spec.annotations, spec.scrollIntoView); } const none$3 = []; function asArray$1(value) { @@ -2513,9 +2533,6 @@ As such, _never_ mutate properties of a state directly. That'll just break things. */ class EditorState { - /** - @internal - */ constructor( /** @internal @@ -2699,7 +2716,7 @@ class EditorState { if (fields) for (let prop in fields) { let value = fields[prop]; - if (value instanceof StateField) + if (value instanceof StateField && this.config.address[value.id] != null) result[prop] = value.spec.toJSON(this.field(fields[prop]), this); } return result; @@ -2716,8 +2733,10 @@ class EditorState { let fieldInit = []; if (fields) for (let prop in fields) { - let field = fields[prop], value = json[prop]; - fieldInit.push(field.init(state => field.spec.fromJSON(value, state))); + 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, @@ -2761,11 +2780,25 @@ class EditorState { 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(phrase) { + phrase(phrase, ...insert) { for (let map of this.facet(EditorState.phrases)) - if (Object.prototype.hasOwnProperty.call(map, phrase)) - return map[phrase]; + if (Object.prototype.hasOwnProperty.call(map, phrase)) { + phrase = map[phrase]; + break; + } + if (insert.length) + phrase = phrase.replace(/\$(\$|\d*)/g, (m, i) => { + if (i == "$") + return "$"; + let n = +(i || 1); + return !n || n > insert.length ? m : insert[n - 1]; + }); return phrase; } /** @@ -2975,7 +3008,7 @@ class RangeValue { /** Create a [range](https://codemirror.net/6/docs/ref/#state.Range) with this value. */ - range(from, to = from) { return new Range$1(from, to, this); } + range(from, to = from) { return Range$1.create(from, to, this); } } RangeValue.prototype.startSide = RangeValue.prototype.endSide = 0; RangeValue.prototype.point = false; @@ -2983,10 +3016,7 @@ RangeValue.prototype.mapMode = MapMode.TrackDel; /** A range associates a value with a range of positions. */ -class Range$1 { - /** - @internal - */ +let Range$1 = class Range { constructor( /** The range's start position. @@ -3004,7 +3034,13 @@ class Range$1 { this.to = to; this.value = value; } -} + /** + @internal + */ + static create(from, to, value) { + return new Range$1(from, to, value); + } +}; function cmpRange(a, b) { return a.from - b.from || a.value.startSide - b.value.startSide; } @@ -3039,7 +3075,7 @@ class Chunk { } } between(offset, from, to, f) { - for (let i = this.findIndex(from, -1000000000 /* Far */, true), e = this.findIndex(to, 1000000000 /* Far */, false, i); i < e; i++) + for (let i = this.findIndex(from, -1000000000 /* C.Far */, true), e = this.findIndex(to, 1000000000 /* C.Far */, false, i); i < e; i++) if (f(this.from[i] + offset, this.to[i] + offset, this.value[i]) === false) return false; } @@ -3084,9 +3120,6 @@ way that makes them efficient to [map](https://codemirror.net/6/docs/ref/#state. structure. */ class RangeSet { - /** - @internal - */ constructor( /** @internal @@ -3099,7 +3132,7 @@ class RangeSet { /** @internal */ - nextLayer = RangeSet.empty, + nextLayer, /** @internal */ @@ -3112,6 +3145,12 @@ class RangeSet { /** @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); @@ -3168,7 +3207,7 @@ class RangeSet { else { if (!filter || filterFrom > cur.to || filterTo < cur.from || filter(cur.from, cur.to, cur.value)) { if (!builder.addInner(cur.from, cur.to, cur.value)) - spill.push(new Range$1(cur.from, cur.to, cur.value)); + spill.push(Range$1.create(cur.from, cur.to, cur.value)); } cur.next(); } @@ -3201,7 +3240,7 @@ class RangeSet { } } let next = this.nextLayer.map(changes); - return chunks.length == 0 ? next : new RangeSet(chunkPos, chunks, next, maxPoint); + return chunks.length == 0 ? next : new RangeSet(chunkPos, chunks, next || RangeSet.empty, maxPoint); } /** Iterate over the ranges that touch the region `from` to `to`, @@ -3269,7 +3308,7 @@ class RangeSet { */ static eq(oldSets, newSets, from = 0, to) { if (to == null) - to = 1000000000 /* Far */; + to = 1000000000 /* C.Far */; 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) @@ -3364,8 +3403,8 @@ class RangeSetBuilder { this.chunkPos = []; this.chunkStart = -1; this.last = null; - this.lastFrom = -1000000000 /* Far */; - this.lastTo = -1000000000 /* Far */; + this.lastFrom = -1000000000 /* C.Far */; + this.lastTo = -1000000000 /* C.Far */; this.from = []; this.to = []; this.value = []; @@ -3402,7 +3441,7 @@ class RangeSetBuilder { throw new Error("Ranges must be added sorted by `from` position and `startSide`"); if (diff < 0) return false; - if (this.from.length == 250 /* ChunkSize */) + if (this.from.length == 250 /* C.ChunkSize */) this.finishChunk(true); if (this.chunkStart < 0) this.chunkStart = from; @@ -3446,7 +3485,7 @@ class RangeSetBuilder { this.finishChunk(false); if (this.chunks.length == 0) return next; - let result = new RangeSet(this.chunkPos, this.chunks, this.nextLayer ? this.nextLayer.finishInner(next) : next, this.setMaxPoint); + let result = RangeSet.create(this.chunkPos, this.chunks, this.nextLayer ? this.nextLayer.finishInner(next) : next, this.setMaxPoint); this.from = null; // Make sure further `add` calls produce errors return result; } @@ -3476,7 +3515,7 @@ class LayerCursor { } get startSide() { return this.value ? this.value.startSide : 0; } get endSide() { return this.value ? this.value.endSide : 0; } - goto(pos, side = -1000000000 /* Far */) { + goto(pos, side = -1000000000 /* C.Far */) { this.chunkIndex = this.rangeIndex = 0; this.gotoInner(pos, side, false); return this; @@ -3505,7 +3544,7 @@ class LayerCursor { next() { for (;;) { if (this.chunkIndex == this.layer.chunk.length) { - this.from = this.to = 1000000000 /* Far */; + this.from = this.to = 1000000000 /* C.Far */; this.value = null; break; } @@ -3559,7 +3598,7 @@ class HeapCursor { return heap.length == 1 ? heap[0] : new HeapCursor(heap); } get startSide() { return this.value ? this.value.startSide : 0; } - goto(pos, side = -1000000000 /* Far */) { + goto(pos, side = -1000000000 /* C.Far */) { for (let cur of this.heap) cur.goto(pos, side); for (let i = this.heap.length >> 1; i >= 0; i--) @@ -3577,7 +3616,7 @@ class HeapCursor { } next() { if (this.heap.length == 0) { - this.from = this.to = 1000000000 /* Far */; + this.from = this.to = 1000000000 /* C.Far */; this.value = null; this.rank = -1; } @@ -3621,12 +3660,12 @@ class SpanCursor { this.point = null; this.pointFrom = 0; this.pointRank = 0; - this.to = -1000000000 /* Far */; + this.to = -1000000000 /* C.Far */; this.endSide = 0; this.openStart = -1; this.cursor = HeapCursor.from(sets, skip, minPoint); } - goto(pos, side = -1000000000 /* Far */) { + goto(pos, side = -1000000000 /* C.Far */) { this.cursor.goto(pos, side); this.active.length = this.activeTo.length = this.activeRank.length = 0; this.minActive = -1; @@ -3677,7 +3716,7 @@ class SpanCursor { remove(trackOpen, a); } else if (!this.cursor.value) { - this.to = this.endSide = 1000000000 /* Far */; + this.to = this.endSide = 1000000000 /* C.Far */; break; } else if (this.cursor.from > from) { @@ -3689,6 +3728,8 @@ class SpanCursor { let nextVal = this.cursor.value; if (!nextVal.point) { // Opening a range this.addActive(trackOpen); + if (this.cursor.from < from && this.cursor.to > from) + trackExtra++; this.cursor.next(); } else if (wasPoint && this.cursor.to == this.to && this.cursor.from < this.cursor.to) { @@ -3780,7 +3821,7 @@ function insert(array, index, value) { array[index] = value; } function findMinIndex(value, array) { - let found = -1, foundPos = 1000000000 /* Far */; + let found = -1, foundPos = 1000000000 /* C.Far */; for (let i = 0; i < array.length; i++) if ((array[i] - foundPos || value[i].endSide - value[found].endSide) < 0) { found = i; @@ -3828,7 +3869,7 @@ function findColumn(string, col, tabSize, strict) { // FIXME profile adding a per-Tree TreeNode cache, validating it by // parent pointer -/// The default maximum length of a `TreeBuffer` node (1024). +/// The default maximum length of a `TreeBuffer` node. const DefaultBufferLength = 1024; let nextPropID = 0; class Range { @@ -3891,7 +3932,7 @@ NodeProp.contextHash = new NodeProp({ perNode: true }); NodeProp.lookAhead = new NodeProp({ perNode: true }); /// This per-node prop is used to replace a given node, or part of a /// node, with another tree. This is useful to include trees from -/// different languages. +/// different languages in mixed-language parsers. NodeProp.mounted = new NodeProp({ perNode: true }); /// A mounted tree, which can be [stored](#common.NodeProp^mounted) on /// a tree node to indicate that parts of its content are @@ -3937,6 +3978,7 @@ class NodeType { this.id = id; this.flags = flags; } + /// Define a node type. static define(spec) { let props = spec.props && spec.props.length ? Object.create(null) : noProps; let flags = (spec.top ? 1 /* Top */ : 0) | (spec.skipped ? 2 /* Skipped */ : 0) | @@ -4018,7 +4060,7 @@ class NodeSet { throw new RangeError("Node type ids should correspond to array positions when creating a node set"); } /// Create a copy of this set with some node properties added. The - /// arguments to this method should be created with + /// arguments to this method can be created with /// [`NodeProp.add`](#common.NodeProp.add). extend(...props) { let newTypes = []; @@ -4144,6 +4186,10 @@ class Tree { /// position. If 1, it'll move into nodes that start at the /// position. With 0, it'll only enter nodes that cover the position /// from both sides. + /// + /// Note that this will not enter + /// [overlays](#common.MountedTree.overlay), and you often want + /// [`resolveInner`](#common.Tree.resolveInner) instead. resolve(pos, side = 0) { let node = resolveNode(CachedNode.get(this) || this.topNode, pos, side, false); CachedNode.set(this, node); @@ -4228,7 +4274,7 @@ class FlatBufferCursor { /// Tree buffers contain (type, start, end, endIndex) quads for each /// node. In such a buffer, nodes are stored in prefix order (parents /// before children, with the endIndex of the parent indicating which -/// children belong to it) +/// children belong to it). class TreeBuffer { /// Create a tree buffer. constructor( @@ -5081,6 +5127,48 @@ mkTree) { divide(children, positions, from, to, 0); return (mkTop || mkTree)(localChildren, localPositions, length); } +/// Provides a way to associate values with pieces of trees. As long +/// as that part of the tree is reused, the associated values can be +/// retrieved from an updated tree. +class NodeWeakMap { + constructor() { + this.map = new WeakMap(); + } + setBuffer(buffer, index, value) { + let inner = this.map.get(buffer); + if (!inner) + this.map.set(buffer, inner = new Map); + inner.set(index, value); + } + getBuffer(buffer, index) { + let inner = this.map.get(buffer); + return inner && inner.get(index); + } + /// Set the value for this syntax node. + set(node, value) { + if (node instanceof BufferNode) + this.setBuffer(node.context.buffer, node.index, value); + else if (node instanceof TreeNode) + this.map.set(node.tree, value); + } + /// Retrieve value for this syntax node, if it exists in the map. + get(node) { + return node instanceof BufferNode ? this.getBuffer(node.context.buffer, node.index) + : node instanceof TreeNode ? this.map.get(node.tree) : undefined; + } + /// Set the value for the node that a cursor currently points to. + cursorSet(cursor, value) { + if (cursor.buffer) + this.setBuffer(cursor.buffer.buffer, cursor.index, value); + else + this.map.set(cursor.tree, value); + } + /// Retrieve the value for the node that a cursor currently points + /// to. + cursorGet(cursor) { + return cursor.buffer ? this.getBuffer(cursor.buffer.buffer, cursor.index) : this.map.get(cursor.tree); + } +} /// Tree fragments are used during [incremental /// parsing](#common.Parser.startParse) to track parts of old trees @@ -5090,7 +5178,10 @@ mkTree) { /// [`applyChanges`](#common.TreeFragment^applyChanges) method to /// update fragments for document changes. class TreeFragment { - /// Construct a tree fragment. + /// Construct a tree fragment. You'll usually want to use + /// [`addTree`](#common.TreeFragment^addTree) and + /// [`applyChanges`](#common.TreeFragment^applyChanges) instead of + /// calling this directly. constructor( /// The start of the unchanged range pointed to by this fragment. /// This refers to an offset in the _updated_ document (as opposed @@ -5205,11 +5296,6 @@ class StringInput { /// function, runs the resulting [inner parses](#common.NestedParse), /// and then [mounts](#common.NodeProp^mounted) their results onto the /// tree. -/// -/// The nesting function is passed a cursor to provide context for a -/// node, but _should not_ move that cursor, only inspect its -/// properties and optionally access its -/// [node object](#common.TreeCursor.node). function parseMixed(nest) { return (parse, input, fragments, ranges) => new MixedParse(parse, nest, input, fragments, ranges); } @@ -5298,7 +5384,7 @@ class MixedParse { this.inner[i].parse.stopAt(pos); } startInner() { - let fragmentCursor = new FragmentCursor$7(this.fragments); + let fragmentCursor = new FragmentCursor$2(this.fragments); let overlay = null; let covered = null; let cursor = new TreeCursor(new TreeNode(this.baseTree, this.ranges[0].from, 0, null), IterMode.IncludeAnonymous | IterMode.IgnoreMounts); @@ -5455,7 +5541,7 @@ class StructureCursor { return false; } } -class FragmentCursor$7 { +let FragmentCursor$2 = class FragmentCursor { constructor(fragments) { var _a; this.fragments = fragments; @@ -5511,7 +5597,7 @@ class FragmentCursor$7 { } return result; } -} +}; function punchRanges(outer, ranges) { let copy = null, current = ranges; for (let i = 1, j = 0; i < outer.length; i++) { @@ -5586,14 +5672,14 @@ function enterFragments(mounts, ranges) { for (let i = 0, pos = from;; i++) { let last = i == changes.length, end = last ? to : changes[i].from; if (end > pos) - result.push(new TreeFragment(pos, end, mount.tree, -startPos, frag.from >= pos, frag.to <= end)); + result.push(new TreeFragment(pos, end, mount.tree, -startPos, frag.from >= pos || frag.openStart, frag.to <= end || frag.openEnd)); if (last) break; pos = changes[i].to; } } else { - result.push(new TreeFragment(from, to, mount.tree, -startPos, frag.from >= startPos, frag.to <= endPos)); + result.push(new TreeFragment(from, to, mount.tree, -startPos, frag.from >= startPos || frag.openStart, frag.to <= endPos || frag.openEnd)); } } return result; @@ -5603,7 +5689,7 @@ function enterFragments(mounts, ranges) { /// parsing progress. They also provide some properties and methods /// that external code such as a tokenizer can use to get information /// about the parse state. -class Stack$5 { +class Stack { /// @internal constructor( /// The parse that this stack is part of @internal @@ -5667,7 +5753,7 @@ class Stack$5 { /// @internal static start(p, state, pos = 0) { let cx = p.parser.context; - return new Stack$5(p, [], state, pos, pos, 0, [], 0, cx ? new StackContext$5(cx, cx.start) : null, 0, null); + return new Stack(p, [], state, pos, pos, 0, [], 0, cx ? new StackContext(cx, cx.start) : null, 0, null); } /// The stack's current [context](#lr.ContextTracker) value, if /// any. Its type will depend on the context tracker's type @@ -5830,7 +5916,7 @@ class Stack$5 { // Make sure parent points to an actual parent with content, if there is such a parent. while (parent && base == parent.bufferBase) parent = parent.parent; - return new Stack$5(this.p, this.stack.slice(), this.state, this.reducePos, this.pos, this.score, buffer, base, this.curContext, this.lookAhead, parent); + return new Stack(this.p, this.stack.slice(), this.state, this.reducePos, this.pos, this.score, buffer, base, this.curContext, this.lookAhead, parent); } // Try to recover from an error by 'deleting' (ignoring) one token. /// @internal @@ -5847,7 +5933,7 @@ class Stack$5 { /// external tokenizers that want to make sure they only provide a /// given token when it applies. canShift(term) { - for (let sim = new SimulatedStack$5(this);;) { + for (let sim = new SimulatedStack(this);;) { let action = this.p.parser.stateSlot(sim.state, 4 /* DefaultReduce */) || this.p.parser.hasAction(sim.state, term); if ((action & 65536 /* ReduceFlag */) == 0) return true; @@ -5974,7 +6060,7 @@ class Stack$5 { } updateContext(context) { if (context != this.curContext.context) { - let newCx = new StackContext$5(this.curContext.tracker, context); + let newCx = new StackContext(this.curContext.tracker, context); if (newCx.hash != this.curContext.hash) this.emitContext(); this.curContext = newCx; @@ -5995,14 +6081,14 @@ class Stack$5 { this.emitLookAhead(); } } -class StackContext$5 { +class StackContext { constructor(tracker, context) { this.tracker = tracker; this.context = context; this.hash = tracker.strict ? tracker.hash(context) : 0; } } -var Recover$5; +var Recover; (function (Recover) { Recover[Recover["Insert"] = 200] = "Insert"; Recover[Recover["Delete"] = 190] = "Delete"; @@ -6010,10 +6096,10 @@ var Recover$5; Recover[Recover["MaxNext"] = 4] = "MaxNext"; Recover[Recover["MaxInsertStackDepth"] = 300] = "MaxInsertStackDepth"; Recover[Recover["DampenInsertStackDepth"] = 120] = "DampenInsertStackDepth"; -})(Recover$5 || (Recover$5 = {})); +})(Recover || (Recover = {})); // Used to cheaply run some reductions to scan ahead without mutating // an entire stack -class SimulatedStack$5 { +class SimulatedStack { constructor(start) { this.start = start; this.state = start.state; @@ -6037,7 +6123,7 @@ class SimulatedStack$5 { } // This is given to `Tree.build` to build a buffer, and encapsulates // the parent-stack-walking necessary to read the nodes. -class StackBufferCursor$5 { +class StackBufferCursor { constructor(stack, pos, index) { this.stack = stack; this.pos = pos; @@ -6047,7 +6133,7 @@ class StackBufferCursor$5 { this.maybeNext(); } static create(stack, pos = stack.bufferBase + stack.buffer.length) { - return new StackBufferCursor$5(stack, pos, pos - stack.bufferBase); + return new StackBufferCursor(stack, pos, pos - stack.bufferBase); } maybeNext() { let next = this.stack.parent; @@ -6068,11 +6154,11 @@ class StackBufferCursor$5 { this.maybeNext(); } fork() { - return new StackBufferCursor$5(this.stack, this.pos, this.index); + return new StackBufferCursor(this.stack, this.pos, this.index); } } -class CachedToken$5 { +class CachedToken { constructor() { this.start = -1; this.value = -1; @@ -6083,12 +6169,12 @@ class CachedToken$5 { this.context = 0; } } -const nullToken$5 = new CachedToken$5; +const nullToken = new CachedToken; /// [Tokenizers](#lr.ExternalTokenizer) interact with the input /// through this interface. It presents the input as a stream of /// characters, tracking lookahead and hiding the complexity of /// [ranges](#common.Parser.parse^ranges) from tokenizer code. -class InputStream$5 { +class InputStream { /// @internal constructor( /// @internal @@ -6108,13 +6194,14 @@ class InputStream$5 { /// when the stream is at the end of the input. this.next = -1; /// @internal - this.token = nullToken$5; + this.token = nullToken; this.rangeIndex = 0; this.pos = this.chunkPos = ranges[0].from; this.range = ranges[0]; this.end = ranges[ranges.length - 1].to; this.readNext(); } + /// @internal resolveOffset(offset, assoc) { let range = this.range, index = this.rangeIndex; let pos = this.pos + offset; @@ -6134,6 +6221,15 @@ class InputStream$5 { } return pos; } + /// @internal + clipPos(pos) { + if (pos >= this.range.from && pos < this.range.to) + return pos; + for (let range of this.ranges) + if (range.to > pos) + return Math.max(pos, range.from); + return this.end; + } /// Look at a code unit near the stream position. `.peek(0)` equals /// `.next`, `.peek(-1)` gives you the previous character, and so /// on. @@ -6239,7 +6335,7 @@ class InputStream$5 { token.value = token.extended = -1; } else { - this.token = nullToken$5; + this.token = nullToken; } if (this.pos != pos) { this.pos = pos; @@ -6281,17 +6377,17 @@ class InputStream$5 { } } /// @internal -class TokenGroup$5 { +class TokenGroup { constructor(data, id) { this.data = data; this.id = id; } - token(input, stack) { readToken$5(this.data, input, stack, this.id); } + token(input, stack) { readToken(this.data, input, stack, this.id); } } -TokenGroup$5.prototype.contextual = TokenGroup$5.prototype.fallback = TokenGroup$5.prototype.extend = false; +TokenGroup.prototype.contextual = TokenGroup.prototype.fallback = TokenGroup.prototype.extend = false; /// `@external tokens` declarations in the grammar should resolve to /// an instance of this class. -class ExternalTokenizer$5 { +class ExternalTokenizer { /// Create a tokenizer. The first argument is the function that, /// given an input stream, scans for the types of tokens it /// recognizes at the stream's position, and calls @@ -6325,8 +6421,8 @@ class ExternalTokenizer$5 { // // This function interprets that data, running through a stream as // long as new states with the a matching group mask can be reached, -// and updating `token` when it matches a token. -function readToken$5(data, input, stack, group) { +// and updating `input.token` when it matches a token. +function readToken(data, input, stack, group) { let state = 0, groupMask = 1 << group, { parser } = stack.p, { dialect } = parser; scan: for (;;) { if ((groupMask & data[state]) == 0) @@ -6344,11 +6440,17 @@ function readToken$5(data, input, stack, group) { break; } } + let next = input.next, low = 0, high = data[state + 2]; + // Special case for EOF + if (input.next < 0 && high > low && data[accEnd + high * 3 - 3] == 65535 /* End */ && data[accEnd + high * 3 - 3] == 65535 /* End */) { + state = data[accEnd + high * 3 - 1]; + continue scan; + } // Do a binary search on the state's edges - for (let next = input.next, low = 0, high = data[state + 2]; low < high;) { + for (; low < high;) { let mid = (low + high) >> 1; let index = accEnd + mid + (mid << 1); - let from = data[index], to = data[index + 1]; + let from = data[index], to = data[index + 1] || 0x10000; if (next < from) high = mid; else if (next >= to) @@ -6365,7 +6467,7 @@ function readToken$5(data, input, stack, group) { // See lezer-generator/src/encode.ts for comments about the encoding // used here -function decodeArray$5(input, Type = Uint16Array) { +function decodeArray(input, Type = Uint16Array) { if (typeof input != "string") return input; let array = null; @@ -6400,13 +6502,13 @@ function decodeArray$5(input, Type = Uint16Array) { } // Environment variable used to control console output -const verbose$5 = typeof process != "undefined" && process.env && /\bparse\b/.test(process.env.LOG); -let stackIDs$5 = null; -var Safety$5; +const verbose = typeof process != "undefined" && process.env && /\bparse\b/.test(process.env.LOG); +let stackIDs = null; +var Safety; (function (Safety) { Safety[Safety["Margin"] = 25] = "Margin"; -})(Safety$5 || (Safety$5 = {})); -function cutAt$5(tree, pos, side) { +})(Safety || (Safety = {})); +function cutAt(tree, pos, side) { let cursor = tree.cursor(IterMode.IncludeAnonymous); cursor.moveTo(pos); for (;;) { @@ -6422,7 +6524,7 @@ function cutAt$5(tree, pos, side) { } } } -class FragmentCursor$6 { +let FragmentCursor$1 = class FragmentCursor { constructor(fragments, nodeSet) { this.fragments = fragments; this.nodeSet = nodeSet; @@ -6438,8 +6540,8 @@ class FragmentCursor$6 { nextFragment() { let fr = this.fragment = this.i == this.fragments.length ? null : this.fragments[this.i++]; if (fr) { - this.safeFrom = fr.openStart ? cutAt$5(fr.tree, fr.from + fr.offset, 1) - fr.offset : fr.from; - this.safeTo = fr.openEnd ? cutAt$5(fr.tree, fr.to + fr.offset, -1) - fr.offset : fr.to; + this.safeFrom = fr.openStart ? cutAt(fr.tree, fr.from + fr.offset, 1) - fr.offset : fr.from; + this.safeTo = fr.openEnd ? cutAt(fr.tree, fr.to + fr.offset, -1) - fr.offset : fr.to; while (this.trees.length) { this.trees.pop(); this.start.pop(); @@ -6505,14 +6607,14 @@ class FragmentCursor$6 { } } } -} -class TokenCache$5 { +}; +class TokenCache { constructor(parser, stream) { this.stream = stream; this.tokens = []; this.mainToken = null; this.actions = []; - this.tokens = parser.tokenizers.map(_ => new CachedToken$5); + this.tokens = parser.tokenizers.map(_ => new CachedToken); } getActions(stack) { let actionIndex = 0; @@ -6551,7 +6653,7 @@ class TokenCache$5 { if (lookAhead) stack.setLookAhead(lookAhead); if (!main && stack.pos == this.stream.end) { - main = new CachedToken$5; + main = new CachedToken; main.value = stack.p.parser.eofTerm; main.start = main.end = stack.pos; actionIndex = this.addActions(stack, main.value, main.end, actionIndex); @@ -6562,14 +6664,15 @@ class TokenCache$5 { getMainToken(stack) { if (this.mainToken) return this.mainToken; - let main = new CachedToken$5, { pos, p } = stack; + let main = new CachedToken, { pos, p } = stack; main.start = pos; main.end = Math.min(pos + 1, p.stream.end); main.value = pos == p.stream.end ? p.parser.eofTerm : 0 /* Err */; return main; } updateCachedToken(token, tokenizer, stack) { - tokenizer.token(this.stream.reset(stack.pos, token), stack); + let start = this.stream.clipPos(stack.pos); + tokenizer.token(this.stream.reset(start, token), stack); if (token.value > -1) { let { parser } = stack.p; for (let i = 0; i < parser.specialized.length; i++) @@ -6586,7 +6689,7 @@ class TokenCache$5 { } else { token.value = 0 /* Err */; - token.end = Math.min(stack.p.stream.end, stack.pos + 1); + token.end = this.stream.clipPos(start + 1); } } putAction(action, token, end, index) { @@ -6605,22 +6708,22 @@ class TokenCache$5 { for (let i = parser.stateSlot(state, set ? 2 /* Skip */ : 1 /* Actions */);; i += 3) { if (data[i] == 65535 /* End */) { if (data[i + 1] == 1 /* Next */) { - i = pair$5(data, i + 2); + i = pair(data, i + 2); } else { if (index == 0 && data[i + 1] == 2 /* Other */) - index = this.putAction(pair$5(data, i + 2), token, end, index); + index = this.putAction(pair(data, i + 2), token, end, index); break; } } if (data[i] == token) - index = this.putAction(pair$5(data, i + 1), token, end, index); + index = this.putAction(pair(data, i + 1), token, end, index); } } return index; } } -var Rec$5; +var Rec; (function (Rec) { Rec[Rec["Distance"] = 5] = "Distance"; Rec[Rec["MaxRemainingPerStep"] = 3] = "MaxRemainingPerStep"; @@ -6633,8 +6736,8 @@ var Rec$5; // on recursive traversal. Rec[Rec["CutDepth"] = 15000] = "CutDepth"; Rec[Rec["CutTo"] = 9000] = "CutTo"; -})(Rec$5 || (Rec$5 = {})); -class Parse$5 { +})(Rec || (Rec = {})); +class Parse { constructor(parser, input, fragments, ranges) { this.parser = parser; this.input = input; @@ -6644,13 +6747,13 @@ class Parse$5 { this.minStackPos = 0; this.reused = []; this.stoppedAt = null; - this.stream = new InputStream$5(input, ranges); - this.tokens = new TokenCache$5(parser, this.stream); + this.stream = new InputStream(input, ranges); + this.tokens = new TokenCache(parser, this.stream); this.topTerm = parser.top[1]; let { from } = ranges[0]; - this.stacks = [Stack$5.start(this, parser.top[0], from)]; + this.stacks = [Stack.start(this, parser.top[0], from)]; this.fragments = fragments.length && this.stream.end - from > parser.bufferLength * 4 - ? new FragmentCursor$6(fragments, parser.nodeSet) : null; + ? new FragmentCursor$1(fragments, parser.nodeSet) : null; } get parsedPos() { return this.minStackPos; @@ -6692,11 +6795,11 @@ class Parse$5 { } } if (!newStacks.length) { - let finished = stopped && findFinished$5(stopped); + let finished = stopped && findFinished(stopped); if (finished) return this.stackToTree(finished); if (this.parser.strict) { - if (verbose$5 && stopped) + if (verbose && stopped) console.log("Stuck with token " + (this.tokens.mainToken ? this.parser.getName(this.tokens.mainToken.value) : "none")); throw new SyntaxError("No parse at " + pos); } @@ -6757,7 +6860,7 @@ class Parse$5 { // `split`, or added to `stacks` if they move `pos` forward. advanceStack(stack, stacks, split) { let start = stack.pos, { parser } = this; - let base = verbose$5 ? this.stackID(stack) + " -> " : ""; + let base = verbose ? this.stackID(stack) + " -> " : ""; if (this.stoppedAt != null && start > this.stoppedAt) return stack.forceReduce() ? stack : null; if (this.fragments) { @@ -6766,7 +6869,7 @@ class Parse$5 { let match = this.parser.nodeSet.types[cached.type.id] == cached.type ? parser.getGoto(stack.state, cached.type.id) : -1; if (match > -1 && cached.length && (!strictCx || (cached.prop(NodeProp.contextHash) || 0) == cxHash)) { stack.useNode(cached, match); - if (verbose$5) + if (verbose) console.log(base + this.stackID(stack) + ` (via reuse of ${parser.getName(cached.type.id)})`); return true; } @@ -6782,7 +6885,7 @@ class Parse$5 { let defaultReduce = parser.stateSlot(stack.state, 4 /* DefaultReduce */); if (defaultReduce > 0) { stack.reduce(defaultReduce); - if (verbose$5) + if (verbose) console.log(base + this.stackID(stack) + ` (via always-reduce ${parser.getName(defaultReduce & 65535 /* ValueMask */)})`); return true; } @@ -6795,7 +6898,7 @@ class Parse$5 { let last = i == actions.length || !split; let localStack = last ? stack : stack.split(); localStack.apply(action, term, end); - if (verbose$5) + if (verbose) console.log(base + this.stackID(localStack) + ` (via ${(action & 65536 /* ReduceFlag */) == 0 ? "shift" : `reduce of ${parser.getName(action & 65535 /* ValueMask */)}`} for ${parser.getName(term)} @ ${start}${localStack == stack ? "" : ", split"})`); if (last) @@ -6816,7 +6919,7 @@ class Parse$5 { if (!this.advanceStack(stack, null, null)) return false; if (stack.pos > pos) { - pushStackDedup$5(stack, newStacks); + pushStackDedup(stack, newStacks); return true; } } @@ -6825,13 +6928,13 @@ class Parse$5 { let finished = null, restarted = false; for (let i = 0; i < stacks.length; i++) { let stack = stacks[i], token = tokens[i << 1], tokenEnd = tokens[(i << 1) + 1]; - let base = verbose$5 ? this.stackID(stack) + " -> " : ""; + let base = verbose ? this.stackID(stack) + " -> " : ""; if (stack.deadEnd) { if (restarted) continue; restarted = true; stack.restart(); - if (verbose$5) + if (verbose) console.log(base + this.stackID(stack) + " (restarted)"); let done = this.advanceFully(stack, newStacks); if (done) @@ -6839,16 +6942,16 @@ class Parse$5 { } let force = stack.split(), forceBase = base; for (let j = 0; force.forceReduce() && j < 10 /* ForceReduceLimit */; j++) { - if (verbose$5) + if (verbose) console.log(forceBase + this.stackID(force) + " (via force-reduce)"); let done = this.advanceFully(force, newStacks); if (done) break; - if (verbose$5) + if (verbose) forceBase = this.stackID(force) + " -> "; } for (let insert of stack.recoverByInsert(token)) { - if (verbose$5) + if (verbose) console.log(base + this.stackID(insert) + " (via recover-insert)"); this.advanceFully(insert, newStacks); } @@ -6858,9 +6961,9 @@ class Parse$5 { token = 0 /* Err */; } stack.recoverByDelete(token, tokenEnd); - if (verbose$5) + if (verbose) console.log(base + this.stackID(stack) + ` (via recover-delete ${this.parser.getName(token)})`); - pushStackDedup$5(stack, newStacks); + pushStackDedup(stack, newStacks); } else if (!finished || finished.score < stack.score) { finished = stack; @@ -6871,7 +6974,7 @@ class Parse$5 { // Convert the stack's buffer to a syntax tree. stackToTree(stack) { stack.close(); - return Tree.build({ buffer: StackBufferCursor$5.create(stack), + return Tree.build({ buffer: StackBufferCursor.create(stack), nodeSet: this.parser.nodeSet, topID: this.topTerm, maxBufferLength: this.parser.bufferLength, @@ -6881,13 +6984,13 @@ class Parse$5 { minRepeatType: this.parser.minRepeatTerm }); } stackID(stack) { - let id = (stackIDs$5 || (stackIDs$5 = new WeakMap)).get(stack); + let id = (stackIDs || (stackIDs = new WeakMap)).get(stack); if (!id) - stackIDs$5.set(stack, id = String.fromCodePoint(this.nextStackID++)); + stackIDs.set(stack, id = String.fromCodePoint(this.nextStackID++)); return id + stack; } } -function pushStackDedup$5(stack, newStacks) { +function pushStackDedup(stack, newStacks) { for (let i = 0; i < newStacks.length; i++) { let other = newStacks[i]; if (other.pos == stack.pos && other.sameState(stack)) { @@ -6898,7 +7001,7 @@ function pushStackDedup$5(stack, newStacks) { } newStacks.push(stack); } -class Dialect$5 { +class Dialect { constructor(source, flags, disabled) { this.source = source; this.flags = flags; @@ -6906,9 +7009,32 @@ class Dialect$5 { } allows(term) { return !this.disabled || this.disabled[term] == 0; } } -/// A parser holds the parse tables for a given grammar, as generated -/// by `lezer-generator`. -class LRParser$5 extends Parser { +const id = x => x; +/// Context trackers are used to track stateful context (such as +/// indentation in the Python grammar, or parent elements in the XML +/// grammar) needed by external tokenizers. You declare them in a +/// grammar file as `@context exportName from "module"`. +/// +/// Context values should be immutable, and can be updated (replaced) +/// on shift or reduce actions. +/// +/// The export used in a `@context` declaration should be of this +/// type. +class ContextTracker { + /// Define a context tracker. + constructor(spec) { + this.start = spec.start; + this.shift = spec.shift || id; + this.reduce = spec.reduce || id; + this.reuse = spec.reuse || id; + this.hash = spec.hash || (() => 0); + this.strict = spec.strict !== false; + } +} +/// Holds the parse tables for a given grammar, as generated by +/// `lezer-generator`, and provides [methods](#common.Parser) to parse +/// content with. +class LRParser extends Parser { /// @internal constructor(spec) { super(); @@ -6957,20 +7083,18 @@ class LRParser$5 extends Parser { this.nodeSet = this.nodeSet.extend(...spec.propSources); this.strict = false; this.bufferLength = DefaultBufferLength; - let tokenArray = decodeArray$5(spec.tokenData); + let tokenArray = decodeArray(spec.tokenData); this.context = spec.context; - this.specialized = new Uint16Array(spec.specialized ? spec.specialized.length : 0); - this.specializers = []; - if (spec.specialized) - for (let i = 0; i < spec.specialized.length; i++) { - this.specialized[i] = spec.specialized[i].term; - this.specializers[i] = spec.specialized[i].get; - } - this.states = decodeArray$5(spec.states, Uint32Array); - this.data = decodeArray$5(spec.stateData); - this.goto = decodeArray$5(spec.goto); + this.specializerSpecs = spec.specialized || []; + this.specialized = new Uint16Array(this.specializerSpecs.length); + for (let i = 0; i < this.specializerSpecs.length; i++) + this.specialized[i] = this.specializerSpecs[i].term; + this.specializers = this.specializerSpecs.map(getSpecializer); + this.states = decodeArray(spec.states, Uint32Array); + this.data = decodeArray(spec.stateData); + this.goto = decodeArray(spec.goto); this.maxTerm = spec.maxTerm; - this.tokenizers = spec.tokenizers.map(value => typeof value == "number" ? new TokenGroup$5(tokenArray, value) : value); + this.tokenizers = spec.tokenizers.map(value => typeof value == "number" ? new TokenGroup(tokenArray, value) : value); this.topRules = spec.topRules; this.dialects = spec.dialects || {}; this.dynamicPrecedences = spec.dynamicPrecedences || null; @@ -6981,7 +7105,7 @@ class LRParser$5 extends Parser { this.top = this.topRules[Object.keys(this.topRules)[0]]; } createParse(input, fragments, ranges) { - let parse = new Parse$5(this, input, fragments, ranges); + let parse = new Parse(this, input, fragments, ranges); for (let w of this.wrappers) parse = w(parse, input, fragments, ranges); return parse; @@ -7010,14 +7134,14 @@ class LRParser$5 extends Parser { for (let i = this.stateSlot(state, set ? 2 /* Skip */ : 1 /* Actions */), next;; i += 3) { if ((next = data[i]) == 65535 /* End */) { if (data[i + 1] == 1 /* Next */) - next = data[i = pair$5(data, i + 2)]; + next = data[i = pair(data, i + 2)]; else if (data[i + 1] == 2 /* Other */) - return pair$5(data, i + 2); + return pair(data, i + 2); else break; } if (next == terminal || next == 0 /* Err */) - return pair$5(data, i + 1); + return pair(data, i + 1); } } return 0; @@ -7037,11 +7161,11 @@ class LRParser$5 extends Parser { for (let i = this.stateSlot(state, 1 /* Actions */);; i += 3) { if (this.data[i] == 65535 /* End */) { if (this.data[i + 1] == 1 /* Next */) - i = pair$5(this.data, i + 2); + i = pair(this.data, i + 2); else return false; } - if (action == pair$5(this.data, i + 1)) + if (action == pair(this.data, i + 1)) return true; } } @@ -7052,7 +7176,7 @@ class LRParser$5 extends Parser { for (let i = this.stateSlot(state, 1 /* Actions */);; i += 3) { if (this.data[i] == 65535 /* End */) { if (this.data[i + 1] == 1 /* Next */) - i = pair$5(this.data, i + 2); + i = pair(this.data, i + 2); else break; } @@ -7066,8 +7190,8 @@ class LRParser$5 extends Parser { } /// @internal overrides(token, prev) { - let iPrev = findOffset$5(this.data, this.tokenPrecTable, prev); - return iPrev < 0 || findOffset$5(this.data, this.tokenPrecTable, token) < iPrev; + let iPrev = findOffset(this.data, this.tokenPrecTable, prev); + return iPrev < 0 || findOffset(this.data, this.tokenPrecTable, token) < iPrev; } /// Configure the parser. Returns a new parser instance that has the /// given settings modified. Settings not provided in `config` are @@ -7075,7 +7199,7 @@ class LRParser$5 extends Parser { configure(config) { // Hideous reflection-based kludge to make it easy to create a // slightly modified copy of a parser. - let copy = Object.assign(Object.create(LRParser$5.prototype), this); + let copy = Object.assign(Object.create(LRParser.prototype), this); if (config.props) copy.nodeSet = this.nodeSet.extend(...config.props); if (config.top) { @@ -7089,6 +7213,17 @@ class LRParser$5 extends Parser { let found = config.tokenizers.find(r => r.from == t); return found ? found.to : t; }); + if (config.specializers) { + copy.specializers = this.specializers.slice(); + copy.specializerSpecs = this.specializerSpecs.map((s, i) => { + let found = config.specializers.find(r => r.from == s.external); + if (!found) + return s; + let spec = Object.assign(Object.assign({}, s), { external: found.to }); + copy.specializers[i] = getSpecializer(spec); + return spec; + }); + } if (config.contextTracker) copy.context = config.contextTracker; if (config.dialect) @@ -7138,21 +7273,22 @@ class LRParser$5 extends Parser { for (let j = this.dialects[values[i]], id; (id = this.data[j++]) != 65535 /* End */;) (disabled || (disabled = new Uint8Array(this.maxTerm + 1)))[id] = 1; } - return new Dialect$5(dialect, flags, disabled); + return new Dialect(dialect, flags, disabled); } - /// (used by the output of the parser generator) @internal + /// Used by the output of the parser generator. Not available to + /// user code. static deserialize(spec) { - return new LRParser$5(spec); + return new LRParser(spec); } } -function pair$5(data, off) { return data[off] | (data[off + 1] << 16); } -function findOffset$5(data, start, term) { +function pair(data, off) { return data[off] | (data[off + 1] << 16); } +function findOffset(data, start, term) { for (let i = start, next; (next = data[i]) != 65535 /* End */; i++) if (next == term) return i - start; return -1; } -function findFinished$5(stacks) { +function findFinished(stacks) { let best = null; for (let stack of stacks) { let stopped = stack.p.stoppedAt; @@ -7163,6 +7299,13 @@ function findFinished$5(stacks) { } return best; } +function getSpecializer(spec) { + if (spec.external) { + let mask = spec.extend ? 1 /* Extend */ : 0 /* Specialize */; + return (value, stack) => (spec.external(value, stack) << 1) | mask; + } + return spec.get; +} // This file was generated by lezer-generator. You probably shouldn't edit it. const immediateParen = 245, @@ -7176,7 +7319,7 @@ const immediateParen = 245, nowhitespace = 253, newline$1$1 = 254, word$1 = 255, - Identifier$1 = 1, + Identifier$1$1 = 1, BlockComment$1$1 = 2, tripleStringContent$1 = 256, stringContent$1 = 257, @@ -7230,7 +7373,7 @@ const CAT_Emoji = /^\p{Emoji}/u; // TERMINATOR -const newline$3 = new ExternalTokenizer$5((input, stack) => { +const newline$3 = new ExternalTokenizer((input, stack) => { let c = input.peek(0); if (c === CHAR_NEWLINE) { if (stack.canShift(newline$1$1)) { @@ -7347,7 +7490,7 @@ function combineSurrogates(input, offset) { } const makeIdentifierThing = (term) => { - return new ExternalTokenizer$5((input, stack) => { + return new ExternalTokenizer((input, stack) => { let start = true; let offset = 0; let eat = 1; @@ -7396,7 +7539,7 @@ const makeIdentifierThing = (term) => { } }); }; -const Identifier$2 = makeIdentifierThing(Identifier$1); +const Identifier$2 = makeIdentifierThing(Identifier$1$1); const word = makeIdentifierThing(word$1); // STRING TOKENIZERS @@ -7411,7 +7554,7 @@ const isStringInterpolation = (input, offset) => { }; const makeStringContent = ({ till, term }) => { - return new ExternalTokenizer$5((input, stack) => { + return new ExternalTokenizer((input, stack) => { let offset = 0; let eatNext = false; while (true) { @@ -7433,7 +7576,7 @@ const makeStringContent = ({ till, term }) => { }; const makeStringContentWithoutInterpolation = ({ till, term }) => { - return new ExternalTokenizer$5((input, stack) => { + return new ExternalTokenizer((input, stack) => { let offset = 0; let eatNext = false; while (true) { @@ -7513,7 +7656,7 @@ const isBlockCommentEnd = (input, offset) => { ); }; -const BlockComment$2 = new ExternalTokenizer$5((input, stack) => { +const BlockComment$2 = new ExternalTokenizer((input, stack) => { // BlockComment if (isBlockCommentStart(input, 0)) { let depth = 1; @@ -7555,7 +7698,7 @@ const isWhitespace = (input, offset) => { ); }; -const layoutExtra = new ExternalTokenizer$5( +const layoutExtra = new ExternalTokenizer( (input, stack) => { // immediateParen if ( @@ -7648,7 +7791,7 @@ const layoutExtra = new ExternalTokenizer$5( // This file was generated by lezer-generator. You probably shouldn't edit it. const spec_Identifier = {__proto__:null,if:14, elseif:20, else:24, end:26, try:30, catch:34, finally:40, for:44, primitive:74, type:76, abstract:84, mutable:90, struct:92, module:98, baremodule:104, macro:110, in:132, isa:134, function:152, do:164, where:170, true:204, false:204, begin:264, while:320, let:326, const:334, global:342, local:346, quote:350, break:354, continue:358, return:362, using:366, import:368, as:376, export:384}; -const parser$7 = LRParser$5.deserialize({ +const parser$7 = LRParser.deserialize({ version: 14, states: "%<^Q$tQNSOOOOQj'#IP'#IPOOQj'#Gt'#GtO${QNSO'#IOO*cQNTO'#DoO*mQNTO'#DoO/eQNTO'#IRO0OQMyO'#IlOOQk'#Il'#IlO0TQNTO'#IlOOQk'#Do'#DoO:sQNTO'#DoO>{QNQO'#DtOOQk'#Ib'#IbO@WQNUO'#EWO@bONzO'#EhO@mONYO'#ElO@xO!!^O'#EmOATQMyO'#EoODRQNTO'#EoODYQMyO'#EnOGsQNQO'#FiOOQk'#I['#I[OLwQNTO'#I[ONrQNTO'#IOO! tQNSO'#IOOOQk'#IS'#ISO!!OQNTO'#GfO!#hQNTO'#GfO!$}QNQO'#GjO!(`QMxO'#GnO!(eQNTO'#IROOQk'#IR'#IRO! YQNSO'#IOO! YQNSO'#IOQOQMxOOO!(oQNQO'#CbOOQk'#Is'#IsO!$}QNQO'#FxO!,QQNQO'#F|O!/cQNQO'#GOOOQk'#GS'#GSOOQk'#GU'#GUO!2tQNTO'#GWO!4TQNQO'#GYO!4]QNQO'#GcO!4eQNSO'#CaO!4rQNSO'#CjO!5PQNQO'#DQO!5UQNQO'#DVO!5ZQNQO'#DYO!6}QNQO'#DYO!7SQNQO'#D^O!7XQNQO'#DaO!8eQNQO'#DdO!:]QNQO'#DyO!:gQNQO'#CqO!(oQNQO'#FqO!:oQNSO'#FtO!4kQNSO'#GQO!4kQNSO'#GeO!>rQNSO-E:rO!>|QNTO,5>TO!@tQNSO,5>TO!?vQNSO,5>TO!AOQNSO,5>jO!5ZQNQO,59fO!AjQNUO,59iOOQh'#Cw'#CwOOQh'#Cx'#CxO!AqQMxO,59gO!AvQMxO,5:iO!A{QMyO,5:iO!BTQMxO,59jO!BYQMxO,5jO!$}QNQO'#HdO#2TQNSO,5yQMyO'#I[O$?TQNSO,5:eO$?_QNQO'#CtO$?oQ!LjO'#CsO$?zQNSO,59]O$@UQNTO'#FsO!4kQNSO,5<]O$BvQMyO'#CzO$COQMzO'#FwO$C^QMzO'#FvO!4kQNSO,5<`O$CiQMzO,5<`O$CqQNQO,5TO$DoQNSO,5>TOOQj,5>T,5>TO$EaQNSO1G4UO$EwQNSO1G4UO$KYQNTO1G/QO%!dQNTO1G/TOOQk'#E`'#E`OOQk1G0e1G0eO%#YQM}O1G/RO%#aQNQO'#DtOOQk'#Iv'#IvO%#hQNTO1G0TO!AvQMxO1G0TO%,VQNQO1G/UO%,aQNQO'#DlOOQk1G1u1G1uO%/xQNTO'#CyOOQk1G1t1G1tOOQk1G4r1G4rO%4kQNQO,59aO%7|QNQO'#IuOOQ`,5:a,5:aO%8_QNQO'#DvOOQk1G1s1G1sO%8gQNQO,5?`O%8wQMxO,5?`O%OOOQk-E;b-E;bO%NyQNTO1G2QOOQk1G2Q1G2QO&!XQNSO1G2QO&&|QNTO1G2rO&)aQNTO1G2rO&+tQNTO1G2rO&+{QNTO1G2rO&.YQNTO1G2rO&.gQNTO1G2rO&0wQNTO1G2rO&1RQNTO1G2rO&3iQNTO1G2rO&3pQNTO1G2rO&5XQNRO1G2sOOQk1G2w1G2wO&7cQNTO1G2rO&7sQM|O1G2mOOQk-E;f-E;fOOQk'#Je'#JeO&7xQNTO1G2lOOQk1G2l1G2lP]QNSO'#GtOOQk,5POOQk,5>P,5>POOQk-E;c-E;cO()^QNQO1G2gOOQk1G2e1G2eOOQk,5>R,5>ROOQk-E;e-E;eOOQh,59O,59OOOQh-E:s-E:sOOQk7+$R7+$RO()kQNQO7+$RO()pQNTO,59POOQh,59R,59RO(,hQNTO'#CnOOQh,59W,59WO(2SQNSO,59WOOQh,59Z,59ZOOQk7+$[7+$[O(2ZQNQO7+$[O(2`QNQO7+$rOOQk7+$w7+$wO%!wQM}O1G/RO(2eQNQO,5>pO(2oQMxO,5>pOOQk7+$z7+$zO(2zQNQO7+$zOOQk7+%O7+%OOOQk7+%R7+%RO(3PQM|O1G/mO(3[QNQO1G/nOOQa1G/q1G/qO$9rQNQO,5:YO(3fQNQO1G/sO(3yQMxO1G/sOOQa1G/s1G/sO!4kQNSO7+%UO(4RQNTO'#IvOOQj1G0Y1G0YOOQj1G0S1G0SOOQk7+%k7+%kOOQj'#EU'#EUO!4kQNSO7+%kO(9jQNTO1G.yOOQj,5=|,5=|OOQj-E;`-E;`O(<_QNQO7+$cOOQk7+$c7+$cOOQk7+'c7+'cO([AN>[OOQkAN>qAN>qOOQj,5=i,5=iOOQj-E:{-E:{OOQk7+%q7+%qOOQi7+%|7+%|OOQi7+%{7+%{O+3uQNRO7+%}OOQi7+%}7+%}O+4VQMxO7+%}O+4[QMxO7+%}O+4dQMxO7+%}O(JTQMxO,5:}OOQi,5:},5:}OOQi7+&R7+&RO+4lQNRO7+&RO+9`QNRO,5;oO+9jQMxO,5;oO+9rQNRO1G0jOOQ`,5=j,5=jO+:PQMxO1G5TO+:_QNQO1G5TOOQ`-E:|-E:|O+QOOQk,5>Q,5>QO,#QQNTO,5>QOOQk-E;d-E;dOOQk1G2h1G2hO,#XQNRO1G/oOOQaAN>`AN>`O,#cQNQOAN>`O,#jQNQO<OO/$hQNRO,5>OO/&fQNRO,5>OO/'PQNTO,5>OO/(qQNTO,5>OO/*lQNRO,5>OO/+YQNTO1G2QO//`QNRO1G2QO/0PQNTO1G2QO/1xQNRO1G2QO/2fQNTO1G2QO/8]QNRO1G2QO/8jQNRO1G2QO/:hQNRO1G2rO/:oQNTO1G2rO/:vQNRO1G2rO/{QNRO1G1cO4?`QNRO1G1cO4?pQNRO1G1cO4@QQNRO1G1cO4@bQNRO1G1cO4AyQNRO1G1cO'9yQNQO,5;zO1LOQNQO,5;zO)/`QNQO,5;zO(NjQNQO,5;zO'9yQNQO7+'OO1LOQNQO7+'OO*DSQNQO7+'OO)/`QNQO7+'OO)6|QNQO7+'OO(NjQNQO7+'OO)3cQNQO7+'OO4BZQNRO1G1fO4E[QNRO1G1fO4GSQNRO1G1fO4GpQNRO1G1fO4J_QNRO<XQNRO1G2rO7>cQNRO1G2rO7>mQNRO1G2rO7>wQNRO1G2rO7ByQNRO1G2rO7DtQNRO1G2rO7FiQNRO1G2rO7HTQNRO1G2rO7H[QNRO1G2rO7HcQNRO1G2rO7HjQNRO1G2rO7HqQNRO1G2rO7HxQNRO1G2rO7IYQNRO1G2rO7IjQNRO1G2rO7IzQNRO1G2rO7J[QNQO'#FZO68QQNQO'#FZO7MpQNQO'#FZO64lQNQO'#FZO#-XQNQO,5=ZO6<|QNQO,5=ZO#-XQNQO7+(_O6<|QNQO7+(_O'IZQNQO7+(_O'N^QNQO7+(_O7J[QNQO,5;yO7MpQNQO,5;yO7J[QNQO,5;wO68QQNQO,5;wO7MpQNQO,5;wO64lQNQO,5;wO7J[QNQO,5;wO68QQNQO,5;wO7MpQNQO,5;wO64lQNQO,5;wO7J[QNQO,5;wO68QQNQO,5;wO7MpQNQO,5;wO64lQNQO,5;wO7J[QNQO,5;wO68QQNQO,5;wO7MpQNQO,5;wO64lQNQO,5;wO7J[QNQO,5;wO68QQNQO,5;wO7MpQNQO,5;wO64lQNQO,5;wO7J[QNQO,5;wO68QQNQO,5;wO7MpQNQO,5;wO64lQNQO,5;wO7J[QNQO,5;wO68QQNQO,5;wO7MpQNQO,5;wO64lQNQO,5;wO7J[QNQO,5;wO68QQNQO,5;wO7MpQNQO,5;wO64lQNQO,5;wO7J[QNQO,5;wO68QQNQO,5;wO7MpQNQO,5;wO64lQNQO,5;wO7J[QNQO,5;wO68QQNQO,5;wO7MpQNQO,5;wO64lQNQO,5;wO7J[QNQO,5;wO68QQNQO,5;wO7MpQNQO,5;wO64lQNQO,5;wO8#UQNRO1G2uO8%pQNRO1G2uO8&WQNRO<QQNRO1G1cO8?uQNRO1G1cO8@VQNRO1G1cO8@^QNRO1G1cO8@eQNRO1G1cO8@lQNRO1G1cO8BdQNRO1G1cO8DXQNRO1G1cO8E|QNRO1G1cO8GhQNRO1G1cO8GrQNRO1G1cO8G|QNRO1G1cO8HWQNRO1G1cO8HbQNRO1G1cO8J`QNRO1G1cO8LTQNRO1G1cO8MxQNRO1G1cO9 dQNRO1G1cO9 kQNRO1G1cO9 rQNRO1G1cO9 yQNRO1G1cO9!QQNRO1G1cO9!XQNRO1G1cO9!iQNRO1G1cO9!yQNRO1G1cO9#gQNRO1G1cO7J[QNQO,5;zO7MpQNQO,5;zO7J[QNQO7+'OO68QQNQO7+'OO7MpQNQO7+'OO64lQNQO7+'OO9#wQNRO1G1fO9%iQNRO1G1fO9&SQNRO<hO!w([O]&rP~P]O&t!rO&|!fO&}!gO']'zO~P!$}O!d(bO&{(_O'y(`O~O'W(cO]&rP~P]OP$gXV$gX]$gX_$gXf$gXu$gXx$gXz$gX}$gX!O$gX!R$gX!U$gX!X$gX!n$gX#Y$gX#Z$gX#x$gX$f$gX$i$gX$m$gX$q$gX$s$gX$u$gX$w$gX$y$gX${$gX$}$gX%O$gX%W$gX&h$gX&t$gX&w$gX&z$gX&{$gX'S$gX'_$gX'n$gX's$gX'u$gX'v$gX~P#A{O&_=QO&g=QO~O&{(gO&h$kX&t$kX'W$kX~O'W(hO&h$jX&t$jX~O&hPO&tPO~O](lO~O](mO~O&z#hO&{#hO&^&]a&h&]a&t&]aY&]a[&]a]&]aa&]ad&]a~P#FTO&z#hO&{#hO&^&]a&h&]a&t&]aY&]a[&]a]&]aa&]ad&]a~O&^&riY&ri[&ri]&ria&rid&ri~P]O&hPO&tPO&^&riY&ri[&ri]&ria&rid&ri~O&a!lO&b!kO&f'vO!dni!eni!fni!gni&^ni&cni&hni&tni&zni&{ni'Pni'Qni'Rni'Wni'^ni'ani'bni'cni'dni'eni'fni'{ni'|ni'}ni(Oni(Tnifni']niPniVni_niunixnizni}ni!Oni!Rni!Uni!Xni!nni#Yni#Zni#xni$fni$ini$mni$qni$sni$uni$wni$yni${ni$}ni%Oni%Wni&wni'Sni'Xni'_ni'nni'sni'uni'vniYni[ni]nianidni(Pni'Zni~O&_ni&gni&|ni&}ni!wni~P$FcO&a!lO&b!kO&f'vO!dqi!eqi!fqi!gqi&^qi&cqi&hqi&tqi&zqi&{qi'Pqi'Qqi'Rqi'Wqi'^qi'aqi'bqi'cqi'dqi'eqi'fqi'{qi'|qi'}qi(Oqi(Tqifqi']qiPqiVqi_qiuqixqizqi}qi!Oqi!Rqi!Uqi!Xqi!nqi#Yqi#Zqi#xqi$fqi$iqi$mqi$qqi$sqi$uqi$wqi$yqi${qi$}qi%Oqi%Wqi&wqi'Sqi'Xqi'_qi'nqi'sqi'uqi'vqiYqi[qi]qiaqidqi(Pqi'Zqi~O&_qi&gqi&|qi&}qi!wqi~P$KmO&i(oO'P=jO'R(pO&_!ra&g!ra~O'n^O~P%!wO'](tO~P;aO!t(vO!d!qi!e!qi!f!qi!g!qi&^!qi&_!qi&a!qi&b!qi&c!qi&f!qi&g!qi&h!qi&t!qi&z!qi&{!qi&|!qi&}!qi'P!qi'Q!qi'R!qi'W!qi'^!qi'a!qi'b!qi'c!qi'd!qi'e!qi'f!qi'{!qi'|!qi'}!qi(O!qi(T!qif!qi']!qiP!qiV!qi_!qiu!qix!qiz!qi}!qi!O!qi!R!qi!U!qi!X!qi!n!qi#Y!qi#Z!qi#x!qi$f!qi$i!qi$m!qi$q!qi$s!qi$u!qi$w!qi$y!qi${!qi$}!qi%O!qi%W!qi&w!qi'S!qi'X!qi'_!qi'n!qi's!qi'u!qi'v!qiY!qi[!qi]!qia!qid!qi(P!qi'Z!qi!w!qi~OP(|OVtO])OO_!POf!YOu!QOx)POz!RO}!TO!O!SO!R!UO!U!VO!X!WO!duO!euO!fYO!gYO!n!XO#Y)OO#Z)OO#x)OO$f!ZO$i![O$mvO'c?OO'd>rO'e?[O'f?WO'{>zO'|?dO'}?hO(ODQOf&SX'X&SX~P#)VO'X*PO~P#-XO&t*QO'X*PO~O&_*SO&f*TO!d$VX!e$VX!f$VX!g$VX&^$VX&c$VX&d#cX&e#cX&h$VX&t$VX&z$VX&{$VX'P$VX'Q$VX'R$VX'W$VX'^$VX'a$VX'b$VX'c$VX'd$VX'e$VX'f$VX'{$VX'|$VX'}$VX(O$VX(T$VXf$VX']$VXP$VXV$VX_$VXu$VXx$VXz$VX}$VX!O$VX!R$VX!U$VX!X$VX!n$VX#Y$VX#Z$VX#x$VX$f$VX$i$VX$m$VX$q$VX$s$VX$u$VX$w$VX$y$VX${$VX$}$VX%O$VX%W$VX&w$VX'S$VX'X$VX'_$VX'n$VX's$VX'u$VX'v$VXY$VX[$VX]$VXa$VXd$VX(P$VX'Z$VX~O!duO!euO!f#oO!g#pO&c#tO'P#mO'QVO'R#vO'^#jO'aWO'bWO'c#lO'd#iO'e#oO'{#kO'|#qO'}#rO(O#sO(T#uO&^&Wa&h&Wa&t&Wa&z&Wa&{&Wa'W&WaY&Wa[&Wa]&Waa&Wad&Wa~O'f#nO~P%LrO&z#hO&{#hO&^$ni&h$ni&t$niY$ni[$ni]$nia$nid$ni~P#FTO&^$ni&h$ni&t$niY$ni[$ni]$nia$nid$ni~O&z#hO&{#hO~P& mO&c#tO(T#uO!d%`i!e%`i!f%`i!g%`i&^%`i&h%`i&t%`i&z%`i&{%`i'P%`i'Q%`i'R%`i'W%`i'^%`i'a%`i'b%`i'c%`i'e%`i'f%`i'{%`i'|%`i'}%`i(O%`if%`i']%`iP%`iV%`i_%`iu%`ix%`iz%`i}%`i!O%`i!R%`i!U%`i!X%`i!n%`i#Y%`i#Z%`i#x%`i$f%`i$i%`i$m%`i$q%`i$s%`i$u%`i$w%`i$y%`i${%`i$}%`i%O%`i%W%`i&w%`i'S%`i'X%`i'_%`i'n%`i's%`i'u%`i'v%`iY%`i[%`i]%`ia%`id%`i(P%`i'Z%`i~O'd%`i~P&!cO&c#tO'd#iO(T#uO!d%`i!e%`i!f%`i!g%`i&^%`i&h%`i&t%`i&z%`i&{%`i'P%`i'Q%`i'R%`i'W%`i'a%`i'b%`i'c%`i'e%`i'f%`i'{%`i'|%`i'}%`i(O%`iY%`i[%`i]%`ia%`id%`i']%`i'Z%`i'X%`i(P%`i~O'^%`i~P&'TO!duO!euO!f#oO!g#pO&c#tO'P#mO'QVO'R#vO'^#jO'aWO'bWO'c#lO'd#iO'e#oO'{#kO'|#qO'}#rO(O#sO(T#uO&^%`i&h%`i&t%`i&z%`i&{%`i'W%`iY%`i[%`i]%`ia%`id%`i']%`i'Z%`i'X%`i(P%`i~O'f%`i~P&)hO'^#jO~P&'TO&c#tO(T#uO!d%`i!e%`i!f%`i!g%`i&^%`i&h%`i&t%`i&z%`i&{%`i'P%`i'Q%`i'R%`i'W%`i'a%`i'b%`i'e%`i'f%`i'{%`i'|%`i'}%`i(O%`iY%`i[%`i]%`ia%`id%`i']%`i'Z%`i'X%`i(P%`i~O'^#jO'c#lO'd#iO~P&,SO'f#nO~P&)hO&c#tO'P#mO'QVO'R#vO'^#jO'aWO'bWO'c#lO'd#iO(T#uO!d%`i!e%`i&^%`i&h%`i&t%`i&z%`i&{%`i'W%`i'e%`i'f%`i'{%`i'|%`i'}%`i(O%`iY%`i[%`i]%`ia%`id%`i']%`i'Z%`i'X%`i(P%`i~O!f#oO!g#pO~P&.nO!f%`i!g%`i~P&.nO!duO!euO!f#oO!g#pO&c#tO'P#mO'QVO'R#vO'^#jO'aWO'bWO'c#lO'd#iO'e#oO'}#rO(T#uO&^%`i&h%`i&t%`i&z%`i&{%`i'W%`i'f%`i'{%`i(O%`iY%`i[%`i]%`ia%`id%`i']%`i'Z%`i'X%`i(P%`i~O'|#qO~P&1]O'|%`i~P&1]O!duO!euO!f4eO!g4lO&c#tO'P4VO'QVO'R5RO'^3pO'aWO'bWO'c4OO'd3iO'e4eO'f4^O'{3wO'|4sO'}4zO(OC`O(T#uO~O(P*UO~P&3wO&c#tO'QVO'aWO'bWO(T#uO!d%`i!e%`i!f%`i!g%`i&^%`i&h%`i&t%`i&z%`i&{%`i'R%`i'W%`i'e%`i'f%`i'{%`i'|%`i'}%`i(O%`iY%`i[%`i]%`ia%`id%`i']%`i'Z%`i'X%`i(P%`i~O'P#mO'^#jO'c#lO'd#iO~P&5`O&i*VO~O!t(vO!d%Yi!e%Yi!f%Yi!g%Yi&^%Yi&c%Yi&h%Yi&t%Yi&z%Yi&{%Yi'P%Yi'Q%Yi'R%Yi'W%Yi'^%Yi'a%Yi'b%Yi'c%Yi'd%Yi'e%Yi'f%Yi'{%Yi'|%Yi'}%Yi(O%Yi(T%Yif%Yi']%YiP%YiV%Yi_%Yiu%Yix%Yiz%Yi}%Yi!O%Yi!R%Yi!U%Yi!X%Yi!n%Yi#Y%Yi#Z%Yi#x%Yi$f%Yi$i%Yi$m%Yi$q%Yi$s%Yi$u%Yi$w%Yi$y%Yi${%Yi$}%Yi%O%Yi%W%Yi&w%Yi'S%Yi'X%Yi'_%Yi'n%Yi's%Yi'u%Yi'v%YiY%Yi[%Yi]%Yia%Yid%Yi(P%Yi'Z%Yi~OP*XO~OP*YO'Q$aO~O'W'`O!d%Pa!e%Pa!f%Pa!g%Pa&^%Pa&c%Pa&h%Pa&t%Pa&z%Pa&{%Pa'P%Pa'Q%Pa'R%Pa'^%Pa'a%Pa'b%Pa'c%Pa'd%Pa'e%Pa'f%Pa'{%Pa'|%Pa'}%Pa(O%Pa(T%Paf%Pa']%PaP%PaV%Pa_%Pau%Pax%Paz%Pa}%Pa!O%Pa!R%Pa!U%Pa!X%Pa!n%Pa#Y%Pa#Z%Pa#x%Pa$f%Pa$i%Pa$m%Pa$q%Pa$s%Pa$u%Pa$w%Pa$y%Pa${%Pa$}%Pa%O%Pa%W%Pa&w%Pa'S%Pa'X%Pa'_%Pa'n%Pa's%Pa'u%Pa'v%PaY%Pa[%Pa]%Paa%Pad%Pa(P%Pa'Z%Pa~O'R*]O~OP*^O~OP*_O'n^O~O'W'dO!d%Vi!e%Vi!f%Vi!g%Vi&^%Vi&c%Vi&h%Vi&t%Vi&z%Vi&{%Vi'P%Vi'Q%Vi'R%Vi'^%Vi'a%Vi'b%Vi'c%Vi'd%Vi'e%Vi'f%Vi'{%Vi'|%Vi'}%Vi(O%Vi(T%Vif%Vi']%ViP%ViV%Vi_%Viu%Vix%Viz%Vi}%Vi!O%Vi!R%Vi!U%Vi!X%Vi!n%Vi#Y%Vi#Z%Vi#x%Vi$f%Vi$i%Vi$m%Vi$q%Vi$s%Vi$u%Vi$w%Vi$y%Vi${%Vi$}%Vi%O%Vi%W%Vi&w%Vi'S%Vi'X%Vi'_%Vi'n%Vi's%Vi'u%Vi'v%ViY%Vi[%Vi]%Via%Vid%Vi(P%Vi'Z%Vi~OY'iO['jO]*cO~OVtO_!POf!YOu!QOxgOz!RO}!TO!O!SO!R!UO!U!VO!X!WO!duO!euO!fYO!gYO!n!XO#YfO#ZfO#x!^O$f!ZO$i![O$mvO$qwO$sxO$u!]O$wyO$yzO${{O$}|O%O|O%W}O&hPO&tPO&w[O&zYO&{YO'PSO'QVO'RTO'SeO'^YO'_ZO'aWO'bXO'cYO'dYO'eYO'fYO'n^O's_O'u`O'vaO]&rPd&rP~OP*gO~P&FoO]*kO~O]*kOd'nO~OxwX~P$4[Ox*mO~O]{X~P$4[O]*nO~O'Q*oO~O&t%xO'W*pO']%zO~O']%uO~O]*rO~O]*tO~O]*uO~O'Q*vO~O'S*wO~O&a(SO&b(RO&f>QO&z*yO&{*yO&t'[X']'[X~O&t*zO']*|O~O]+RO~OP+SO'Y%lO~O!duO!euO!f#oO!g#pO&c#tO'P#mO'QVO'R#vO'^#jO'aWO'bWO'c#lO'd#iO'e#oO'f#nO'{#kO'|#qO'}#rO(O#sO(T#uO~O&z%qO&{%qO'W&yX&t&yX']&yX~P&MVO'W*pO~O]+YO~O]+ZO~OP%UO'P%TO~O'W(hO&h$ja&t$ja~O]+_O~O&^&rqY&rq[&rq]&rqa&rqd&rq~P]O&_7lO&g7lO~O&hPO&tPO&|!fO&}!gO~PDbO!t(vO!d!qq!e!qq!f!qq!g!qq&^!qq&_!qq&a!qq&b!qq&c!qq&f!qq&g!qq&h!qq&t!qq&z!qq&{!qq&|!qq&}!qq'P!qq'Q!qq'R!qq'W!qq'^!qq'a!qq'b!qq'c!qq'd!qq'e!qq'f!qq'{!qq'|!qq'}!qq(O!qq(T!qqf!qq']!qqP!qqV!qq_!qqu!qqx!qqz!qq}!qq!O!qq!R!qq!U!qq!X!qq!n!qq#Y!qq#Z!qq#x!qq$f!qq$i!qq$m!qq$q!qq$s!qq$u!qq$w!qq$y!qq${!qq$}!qq%O!qq%W!qq&w!qq'S!qq'X!qq'_!qq'n!qq's!qq'u!qq'v!qqY!qq[!qq]!qqa!qqd!qq(P!qq'Z!qq!w!qq~OP$OXV$OX]$OX_$OXf$OXf'`Xu$OXx$OXz$OX}$OX!O$OX!R$OX!U$OX!X$OX!d$OX!d'`X!e$OX!e'`X!f$OX!f'`X!g$OX!g'`X!n$OX#Y$OX#Z$OX#x$OX$f$OX$i$OX$m$OX$q$OX$s$OX$u$OX$w$OX$y$OX${$OX$}$OX%O$OX%W$OX&_'`X&a'`X&b'`X&c'`X&f'`X&g'`X&w$OX&z$OX&z'`X&{$OX&{'`X&|'`X&}'`X'P$OX'P'`X'Q$OX'Q'`X'R$OX'R'`X'S$OX'W'`X'X'`X'^$OX'^'`X'_$OX'a$OX'a'`X'b$OX'b'`X'c$OX'c'`X'd$OX'd'`X'e$OX'e'`X'f$OX'f'`X'n$OX's$OX'u$OX'v$OX'{'`X'|'`X'}'`X(O'`X(T'`X&t'`X']'`X~OP$OXV$OX]$OX_$OXu$OXx$OXz$OX}$OX!O$OX!R$OX!U$OX!X$OX!d!cX!e!cX!f!cX!g!cX!n$OX#Y$OX#Z$OX#x$OX$f$OX$i$OX$m$OX$q$OX$s$OX$u$OX$w$OX$y$OX${$OX$}$OX%O$OX%W$OX&_!cX&a!cX&b!cX&c!cX&f!cX&g!cX&w$OX&z!cX&{!cX&|!cX&}!cX'P!cX'Q!cX'R!cX'S$OX'W!cX'X!cX'^!cX'_$OX'a!cX'b!cX'c!cX'd!cX'e!cX'f!cX'n$OX's$OX'u$OX'v$OX'{!cX'|!cX'}!cX(O!cX(T!cX&t!cX']!cX~Of!cX~P'-lOf'TX!d'TX!e'TX!f'TX!g'TX&c'TX&z'TX&{'TX'P'TX'Q'TX'R'TX'W'TX'X'TX'^'TX'a'TX'b'TX'c'TX'd'TX'e'TX'f'TX'{'TX'|'TX'}'TX(O'TX(T'TX&t'TX']'TXP'TXV'TX]'TX_'TXu'TXx'TXz'TX}'TX!O'TX!R'TX!U'TX!X'TX!n'TX#Y'TX#Z'TX#x'TX$f'TX$i'TX$m'TX$q'TX$s'TX$u'TX$w'TX$y'TX${'TX$}'TX%O'TX%W'TX&w'TX'S'TX'_'TX'n'TX's'TX'u'TX'v'TX(P'TX'Z'TX~O&_+hO&a+jO&b+gO&f+fO&g+hO&|!fO&}!gO~P'2ZO&t+pO&|!fO&}!gO']+sO~P%(qOf'oX!d'oX!e'oX!f'oX!g'oX&_'oX&a'oX&b'oX&c'oX&d#cX&e#cX&f'oX&g'oX&z'oX&{'oX&|'oX&}'oX'P'oX'Q'oX'R'oX'W'oX'X'oX'^'oX'a'oX'b'oX'c'oX'd'oX'e'oX'f'oX'{'oX'|'oX'}'oX(O'oX(T'oX&t'oX']'oX~O(Q+vO~P'7`OP>SOVtO])OO_!POf!YOu!QOx)POz!RO}!TO!O!SO!R!UO!U!VO!X!WO!duO!euO!fYO!gYO!n!XO#Y)OO#Z)OO#x)OO$f!ZO$i![O$mVOVtO])OO_!POf!YOu!QOx)POz!RO}!TO!O!SO!R!UO!U!VO!X!WO!duO!euO!fYO!gYO!n!XO#Y)OO#Z)OO#x)OO$f!ZO$i![O$mUOVtO])OO_!POf!YOu!QOx)POz!RO}!TO!O!SO!R!UO!U!VO!X!WO!duO!euO!fYO!gYO!n!XO#Y)OO#Z)OO#x)OO$f!ZO$i![O$mvO$qwO$sxO$u!]O$wyO$yzO${{O$}|O%O|O%W}O&w({O&zYO&{YO'PSO'QVO'RTO'S(}O'^YO'_7uO'aWO'b7sO'cYO'dYO'eYO'fYO'n^O's_O'u`O'vaO~O'X.}O~P)/`O'W/OO'X.}O~OV/SOf,jO'W'xX'X'xX~OPCxOVtO])OO_!POf!YOu!QOx)POz!RO}!TO!O!SO!R!UO!U!VO!X!WO!duO!euO!fYO!gYO!n!XO#Y)OO#Z)OO#x)OO$f!ZO$i![O$mvO$qUOVtO])OO_!POf!YOu!QOx)POz!RO}!TO!O!SO!R!UO!U!VO!X!WO!duO!euO!fYO!gYO!n!XO#Y)OO#Z)OO#x)OO$f!ZO$i![O$mvO$qxO'aWO'bWO'c?QO'd>tO'e?^O'f?YO'{>|O'|?fO'}?jO(ODSO(T#uO~OV!kaf!ka&t!ka']!ka'X!ka~P):yO'W,rOV!jif!ji&t!ji']!ji'X!ji~O&t&xq&t'hq']&xq']'hq~O&|!fO&}!gO~P!$}O&t'hi']'hi~P!D{O!duO!euO!f?_O!g?cO&c#tO'P?VO'QVO'R?oO'^>yO'aWO'bWO'c?RO'd>uO'e?_O'f?ZO'{>}O'|?gO'}?kO(ODTO(T#uO~O']/nO~P)=vO&^%ci&h%ci&t%ci'W%ci'f%ciY%ci[%ci]%cia%cid%ci'Z%ci']%ci'X%ci(P%ci~P%CRO&z#hO&{#hO&^%gy&h%gy&t%gyY%gy[%gy]%gya%gyd%gy~P#FTO&z/pO&{/pO~O&i(oO'P%TO'R7oO~O!duO!euO&c#tO'QVO'aWO'bWO(T#uO&^%ay&h%ay&t%ay&z%ay&{%ay'W%ay'f%ay'{%ayY%ay[%ay]%aya%ayd%ay']%ay'Z%ay'X%ay(P%ay~O!f#oO!g#pO'P#mO'R#vO'^#jO'c#lO'd#iO'e#oO'|#qO'}#rO(O#sO~P)AfOP'^O&g!nO'Q$aO~O%S/tO'W/rO!d(WX!e(WX!f(WX!g(WX&^(WX&c(WX&h(WX&t(WX&z(WX&{(WX'P(WX'R(WX'^(WX'a(WX'b(WX'c(WX'd(WX'e(WX'f(WX'{(WX'|(WX'}(WX(O(WX(T(WXf(WX'](WXP(WXV(WX_(WXu(WXx(WXz(WX}(WX!O(WX!R(WX!U(WX!X(WX!n(WX#Y(WX#Z(WX#x(WX$f(WX$i(WX$m(WX$q(WX$s(WX$u(WX$w(WX$y(WX${(WX$}(WX%O(WX%W(WX&w(WX'S(WX'X(WX'_(WX'n(WX's(WX'u(WX'v(WXY(WX[(WX](WXa(WXd(WX(P(WX'Z(WX~O'Q'_O~P)DUO%S/tO'Q'_O~O'W/rO!d(WX!e(WX!f(WX!g(WX&^(WX&c(WX&h(WX&t(WX&z(WX&{(WX'P(WX'Q(WX'R(WX'^(WX'a(WX'b(WX'c(WX'd(WX'e(WX'f(WX'{(WX'|(WX'}(WX(O(WX(T(WXf(WX'](WXP(WXV(WX_(WXu(WXx(WXz(WX}(WX!O(WX!R(WX!U(WX!X(WX!n(WX#Y(WX#Z(WX#x(WX$f(WX$i(WX$m(WX$q(WX$s(WX$u(WX$w(WX$y(WX${(WX$}(WX%O(WX%W(WX&w(WX'S(WX'X(WX'_(WX'n(WX's(WX'u(WX'v(WXY(WX[(WX](WXa(WXd(WX(P(WX'Z(WX~O'Q(WX~P)DUO&t&xi']&xi~P!D{O&z/vO&{/vO'W/wO'X/yO~P'D^O'X/yO~O'W/zO'X/yO~O'W/wO'X/yO~O&a(SO&b(RO&f>QO&t!bi']!bi~O&|!fO&}!gO'PCVO'R=hO']/{O~P!7^O]/}O~O]0OO~O'W-yOP!uaV!ua]!ua_!uaf!uau!uax!uaz!ua}!ua!O!ua!R!ua!U!ua!X!ua!d!ua!e!ua!f!ua!g!ua!n!ua#Y!ua#Z!ua#x!ua$f!ua$i!ua$m!ua$q!ua$s!ua$u!ua$w!ua$y!ua${!ua$}!ua%O!ua%W!ua&h!ua&t!ua&w!ua&z!ua&{!ua'P!ua'Q!ua'R!ua'S!ua'^!ua'_!ua'a!ua'b!ua'c!ua'd!ua'e!ua'f!ua'n!ua's!ua'u!ua'v!ua~O]0RO~O&i(oO'P=jO'R(pO'n^O&_#Ua&g#Ua~O'W0WO'X0VO~P%(qO&t+pO&|!fO&}!gO']0[O~P%(qO!t(vOf#Ti!d#Ti!e#Ti!f#Ti!g#Ti&_#Ti&a#Ti&b#Ti&c#Ti&f#Ti&g#Ti&z#Ti&{#Ti&|#Ti&}#Ti'P#Ti'Q#Ti'R#Ti'W#Ti'X#Ti'^#Ti'a#Ti'b#Ti'c#Ti'd#Ti'e#Ti'f#Ti'{#Ti'|#Ti'}#Ti(O#Ti(T#Ti&t#Ti']#TiP#TiV#Ti]#Ti_#Tiu#Tix#Tiz#Ti}#Ti!O#Ti!R#Ti!U#Ti!X#Ti!n#Ti#Y#Ti#Z#Ti#x#Ti$f#Ti$i#Ti$m#Ti$q#Ti$s#Ti$u#Ti$w#Ti$y#Ti${#Ti$}#Ti%O#Ti%W#Ti&w#Ti'S#Ti'_#Ti'n#Ti's#Ti'u#Ti'v#Ti(P#Ti'Z#Ti~O&|!fO&}!gO~P)6|O&|!fO&}!gO&t'qa&t'wa']'qa']'wa~P%(qO'W0dO&t'qa&t'wa']'qa']'wa~OPCxOVtO])OO_!POf!YOu!QOx)POz!RO}!TO!O!SO!R!UO!U!VO!X!WO!duO!euO!fYO!gYO!n!XO#Y)OO#Z)OO#x)OO$f!ZO$i![O$mvO$qTOVtO])OO_!POf!YOu!QOx)POz!RO}!TO!O!SO!R!UO!U!VO!X!WO!duO!euO!fYO!gYO!n!XO#Y)OO#Z)OO#x)OO$f!ZO$i![O$m`O&{>`O&t'rX']'rX~P+:uO']1vO~P*,bO&|!fO&}!gO&t'qa']'qa~P%(qO'W1yO&t'qa']'qa~O'W%xa'X%xa~P+)eO'X1|O~P)6|O'X2OO~P(NjO!duO!euO!f9_O!g9fO&c,eO'P9PO'QVO'R9{O'^8jO'aWO'bWO'c8xO'd8cO'e9_O'{8qO'|9mO'}9tO(OCdO(T,fO~OP&PaV&Pa]&Pa_&Paf&Pau&Pax&Paz&Pa}&Pa!O&Pa!R&Pa!U&Pa!X&Pa!n&Pa#Y&Pa#Z&Pa#x&Pa$f&Pa$i&Pa$m&Pa$q&Pa$s&Pa$u&Pa$w&Pa$y&Pa${&Pa$}&Pa%O&Pa%W&Pa&w&Pa&z&Pa&{&Pa'S&Pa'W&Pa'X&Pa'_&Pa'f&Pa'n&Pa's&Pa'u&Pa'v&Pa&t&Pa']&Pa(P&Pa'Z&Pa~P+=sO&z.vO&{.vO'W.tOP#{iV#{i]#{i_#{if#{iu#{ix#{iz#{i}#{i!O#{i!R#{i!U#{i!X#{i!n#{i#Y#{i#Z#{i#x#{i$f#{i$i#{i$m#{i$q#{i$s#{i$u#{i$w#{i$y#{i${#{i$}#{i%O#{i%W#{i&w#{i'S#{i'X#{i'_#{i'f#{i'n#{i's#{i'u#{i'v#{i&t#{i']#{i(P#{i'Z#{i~P+=sO&z.vO&{.vOP#{iV#{i]#{i_#{if#{iu#{ix#{iz#{i}#{i!O#{i!R#{i!U#{i!X#{i!d#{i!e#{i!f#{i!g#{i!n#{i#Y#{i#Z#{i#x#{i$f#{i$i#{i$m#{i$q#{i$s#{i$u#{i$w#{i$y#{i${#{i$}#{i%O#{i%W#{i&c#{i&w#{i'P#{i'Q#{i'R#{i'S#{i'W#{i'X#{i'^#{i'_#{i'a#{i'b#{i'c#{i'd#{i'e#{i'f#{i'n#{i's#{i'u#{i'v#{i'{#{i'|#{i'}#{i(O#{i(T#{i&t#{i']#{i(P#{i'Z#{i~O!duO!euO!f9aO!g9hO&c,eO'P9RO'QVO'R9}O'^8lO'aWO'bWO'c8zO'd8eO'e9aO'f9YO'{8sO'|9oO'}9vO(OCfO(T,fO~OV#qaf#qa'W#qa'X#qa~P+I^O'W2SO~O'W1]OV#lif#li'X#li&t#li']#li~O&z#hO&{#hO&^%g!Z&h%g!Z&t%g!ZY%g!Z[%g!Z]%g!Za%g!Zd%g!Z~P#FTO%S/tO!d&Ya!e&Ya!f&Ya!g&Ya&^&Ya&c&Ya&h&Ya&t&Ya&z&Ya&{&Ya'P&Ya'R&Ya'W&Ya'^&Ya'a&Ya'b&Ya'c&Ya'd&Ya'e&Ya'f&Ya'{&Ya'|&Ya'}&Ya(O&Ya(T&Yaf&Ya']&YaP&YaV&Ya_&Yau&Yax&Yaz&Ya}&Ya!O&Ya!R&Ya!U&Ya!X&Ya!n&Ya#Y&Ya#Z&Ya#x&Ya$f&Ya$i&Ya$m&Ya$q&Ya$s&Ya$u&Ya$w&Ya$y&Ya${&Ya$}&Ya%O&Ya%W&Ya&w&Ya'S&Ya'X&Ya'_&Ya'n&Ya's&Ya'u&Ya'v&YaY&Ya[&Ya]&Yaa&Yad&Ya(P&Ya'Z&Ya~O'Q'_O~P+L]O'Q&Ya~P+L]O'W!]i'X!]i~P+)eO'X2XO~P)/`O'X2YO~P)/`O'W2ZO'X2YO~O&|!fO&}!gO'Z2_O~P)6|O'W2`O'Z2_O~O&t'qq&t'wq']'qq']'wq~O&|!fO&}!gO~P)/`O&|!fO&}!gO&t'qi']'qi~P%(qOf$Si'W$Si'X$Si'f$Si&t$Si']$Si~P*5lO'W!^i'X!^i~P+)eO!duO!euO&c,eO'QVO'aWO'bWO(T,fOf$Qy&z$Qy&{$Qy'W$Qy'X$Qy'f$Qy'{$Qy&t$Qy']$Qy~O!f,`O!g,aO'P,^O'R,kO'^,ZO'c,]O'd,YO'e,`O'|,bO'},cO(O,dO~P,%zO&|!fO&}!gO&t'wa']'wa~P%(qO'W2dO&t'wa']'wa~OV#mif#mi'W#mi'X#mi&t#mi']#mi~P+I^O'X2eO~P)/`O'W#Qi'X#Qi~P+)eO'W%}a'Z%}a~P+)eO&|!fO&}!gO'Z2fO~P)6|O&|!fO&}!gO&t'wi']'wi~P%(qOP%_XV%_X_%_Xf%_Xf'`Xu%_Xx%_Xz%_X}%_X!O%_X!R%_X!U%_X!X%_X!d%_X!d'`X!e%_X!e'`X!f%_X!f'`X!g%_X!g'`X!n%_X#Y%_X#Z%_X#x%_X$f%_X$i%_X$m%_X$q%_X$s%_X$u%_X$w%_X$y%_X${%_X$}%_X%O%_X%W%_X&_'`X&a'`X&b'`X&c'`X&f'`X&g'`X&t'`X&w%_X&z%_X&z'`X&{%_X&{'`X&|'`X&}'`X'P%_X'P'`X'Q%_X'Q'`X'R%_X'R'`X'S%_X'W'`X']'`X'^%_X'^'`X'_%_X'a%_X'a'`X'b%_X'b'`X'c%_X'c'`X'd%_X'd'`X'e%_X'e'`X'f%_X'f'`X'n%_X's%_X'u%_X'v%_X'{'`X'|'`X'}'`X(O'`X(T'`X'X'`X~OP'`XV'`X_'`Xf'`Xu'`Xx'`Xz'`X}'`X!O'`X!R'`X!U'`X!X'`X!n'`X#Y'`X#Z'`X#x'`X$f'`X$i'`X$m'`X$q'`X$s'`X$u'`X$w'`X$y'`X${'`X$}'`X%O'`X%W'`X&w'`X'S'`X'_'`X'n'`X's'`X'u'`X'v'`X~P0TOV'`X~P,*SOP%_XV%_X_%_Xf%_Xu%_Xx%_Xz%_X}%_X!O%_X!R%_X!U%_X!X%_X!d%_X!d'`X!e%_X!e'`X!f%_X!f'`X!g%_X!g'`X!n%_X#Y%_X#Z%_X#x%_X$f%_X$i%_X$m%_X$q%_X$s%_X$u%_X$w%_X$y%_X${%_X$}%_X%O%_X%W%_X&_'`X&a'`X&b'`X&c'`X&f'`X&g'`X&t'`X&w%_X&z%_X&{%_X&|'`X&}'`X'P%_X'P'`X'Q%_X'Q'`X'R%_X'R'`X'S%_X']'`X'^%_X'^'`X'_%_X'a%_X'a'`X'b%_X'b'`X'c%_X'c'`X'd%_X'd'`X'e%_X'e'`X'f%_X'f'`X'n%_X's%_X'u%_X'v%_X'{'`X'|'`X'}'`X(O'`X(T'`X'X'`X'W'`X~OV'`Xf'`X~P,2XO(P'`X'Z'`X&h'`X~P,2XOP%_X_%_Xf!cXu%_Xx%_Xz%_X}%_X!O%_X!R%_X!U%_X!X%_X!d!cX!e!cX!f!cX!g!cX!n%_X#Y%_X#Z%_X#x%_X$f%_X$i%_X$m%_X$q%_X$s%_X$u%_X$w%_X$y%_X${%_X$}%_X%O%_X%W%_X&_!cX&a!cX&b!cX&c!cX&f!cX&g!cX&t!cX&w%_X&z!cX&{!cX&|!cX&}!cX'P!cX'Q!cX'R!cX'S%_X'W!cX']!cX'^!cX'_%_X'a!cX'b!cX'c!cX'd!cX'e!cX'f!cX'n%_X's%_X'u%_X'v%_X'{!cX'|!cX'}!cX(O!cX(T!cX'X!cX~OV%_X~P,8SOV!cX~P,8SOP%_X_%_Xu%_Xx%_Xz%_X}%_X!O%_X!R%_X!U%_X!X%_X!d!cX!e!cX!f!cX!g!cX!n%_X#Y%_X#Z%_X#x%_X$f%_X$i%_X$m%_X$q%_X$s%_X$u%_X$w%_X$y%_X${%_X$}%_X%O%_X%W%_X&_!cX&a!cX&b!cX&c!cX&f!cX&g!cX&t!cX&w%_X&z%_X&{%_X&|!cX&}!cX'P!cX'Q!cX'R!cX'S%_X']!cX'^!cX'_%_X'a!cX'b!cX'c!cX'd!cX'e!cX'f!cX'n%_X's%_X'u%_X'v%_X'{!cX'|!cX'}!cX(O!cX(T!cX'X!cX'W!cX~OV!cXf!cX~P,hO!d$pa!d'OX!e$pa!e'OX!f$pa!f'OX!g$pa!g'OX&c$pa&c'OX&z'OX&{'OX&|'OX&}'OX'P$pa'P'OX'Q$pa'Q'OX'R$pa'R'OX'W'OX'^$pa'^'OX'a$pa'a'OX'b$pa'b'OX'c$pa'c'OX'd$pa'd'OX'e$pa'e'OX'f$pa'f'OX'{$pa'{'OX'|$pa'|'OX'}$pa'}'OX(O$pa(O'OX(P$pa(T$pa(T'OXV$paf$pa&t$pa']$pa'X$pa~P$>hO!d$pa!d'OX!e$pa!e'OX!f$pa!f'OX!g$pa!g'OX&c$pa&c'OX&z'OX&{'OX&|'OX&}'OX'P$pa'P'OX'Q$pa'Q'OX'R$pa'R'OX'W$pa'W'OX'Z$pa'^$pa'^'OX'a$pa'a'OX'b$pa'b'OX'c$pa'c'OX'd$pa'd'OX'e$pa'e'OX'f$pa'f'OX'{$pa'{'OX'|$pa'|'OX'}$pa'}'OX(O$pa(O'OX(T$pa(T'OX&t$pa']$pa'X$pa(P$pa&h$paV$paf$pa~P$>hO(Q#[OP$raV$raY$ra[$ra]$ra_$raf$rau$rax$raz$ra}$ra!O$ra!R$ra!U$ra!X$ra!d$ra!d'OX!e$ra!e'OX!f$ra!f'OX!g$ra!g'OX!n$ra#Y$ra#Z$ra#x$ra$f$ra$i$ra$m$ra$q$ra$s$ra$u$ra$w$ra$y$ra${$ra$}$ra%O$ra%W$ra&c$ra&c'OX&h$ra&t$ra&w$ra&z$ra&z'OX&{$ra&{'OX'P$ra'P'OX'Q$ra'Q'OX'R$ra'R'OX'S$ra'W'OX'^$ra'^'OX'_$ra'a$ra'a'OX'b$ra'b'OX'c$ra'c'OX'd$ra'd'OX'e$ra'e'OX'f$ra'f'OX'n$ra's$ra'u$ra'v$ra'{$ra'{'OX'|$ra'|'OX'}$ra'}'OX(O$ra(O'OX(T$ra(T'OX'X$ra']$ra(P$ra~P$:YO(Q#[O!d$ra!d'OX!e$ra!e'OX!f$ra!f'OX!g$ra!g'OX&c$ra&c'OX&z'OX&{'OX'P$ra'P'OX'Q$ra'Q'OX'R$ra'R'OX'W'OX'^$ra'^'OX'a$ra'a'OX'b$ra'b'OX'c$ra'c'OX'd$ra'd'OX'e$ra'e'OX'f$ra'f'OX'{$ra'{'OX'|$ra'|'OX'}$ra'}'OX(O$ra(O'OX(P$ra(T$ra(T'OXV$raf$ra&t$ra']$ra'X$ra~P$:YO(Q#[O!d$ra!d'OX!e$ra!e'OX!f$ra!f'OX!g$ra!g'OX&c$ra&c'OX&z'OX&{'OX'P$ra'P'OX'Q$ra'Q'OX'R$ra'R'OX'W$ra'W'OX'Z$ra'^$ra'^'OX'a$ra'a'OX'b$ra'b'OX'c$ra'c'OX'd$ra'd'OX'e$ra'e'OX'f$ra'f'OX'{$ra'{'OX'|$ra'|'OX'}$ra'}'OX(O$ra(O'OX(T$ra(T'OX&t$ra']$ra'X$ra(P$ra&h$raV$raf$ra~P$:YOP$raV$raY$ra[$ra]$ra_$raf$rau$rax$raz$ra}$ra!O$ra!R$ra!U$ra!X$ra!d$ra!d'OX!e$ra!e'OX!f$ra!f'OX!g$ra!g'OX!n$ra#Y$ra#Z$ra#x$ra$f$ra$i$ra$m$ra$q$ra$s$ra$u$ra$w$ra$y$ra${$ra$}$ra%O$ra%W$ra&c$ra&c'OX&h$ra&t$ra&w$ra&z$ra&z'OX&{$ra&{'OX&|'OX&}'OX'P$ra'P'OX'Q$ra'Q'OX'R$ra'R'OX'S$ra'W'OX'^$ra'^'OX'_$ra'a$ra'a'OX'b$ra'b'OX'c$ra'c'OX'd$ra'd'OX'e$ra'e'OX'f$ra'f'OX'n$ra's$ra'u$ra'v$ra'{$ra'{'OX'|$ra'|'OX'}$ra'}'OX(O$ra(O'OX(T$ra(T'OX'X$ra']$ra(P$ra~P$>hO!d$ra!d'OX!e$ra!e'OX!f$ra!f'OX!g$ra!g'OX&c$ra&c'OX&z'OX&{'OX&|'OX&}'OX'P$ra'P'OX'Q$ra'Q'OX'R$ra'R'OX'W'OX'^$ra'^'OX'a$ra'a'OX'b$ra'b'OX'c$ra'c'OX'd$ra'd'OX'e$ra'e'OX'f$ra'f'OX'{$ra'{'OX'|$ra'|'OX'}$ra'}'OX(O$ra(O'OX(P$ra(T$ra(T'OXV$raf$ra&t$ra']$ra'X$ra~P$>hO!d$ra!d'OX!e$ra!e'OX!f$ra!f'OX!g$ra!g'OX&c$ra&c'OX&z'OX&{'OX&|'OX&}'OX'P$ra'P'OX'Q$ra'Q'OX'R$ra'R'OX'W$ra'W'OX'Z$ra'^$ra'^'OX'a$ra'a'OX'b$ra'b'OX'c$ra'c'OX'd$ra'd'OX'e$ra'e'OX'f$ra'f'OX'{$ra'{'OX'|$ra'|'OX'}$ra'}'OX(O$ra(O'OX(T$ra(T'OX&t$ra']$ra'X$ra(P$ra&h$raV$raf$ra~P$>hO'W3XOf$za&t$za&z$za&{$za']$za'X$za~P!BgO!f4`O!g4gO'P4QO'R4|O'W3UO'^3kO'c3yO'd3dO'e4`O'f4XO'{3rO'|4nO'}4uO(OCZOP$zaV$za_$zaf$zau$zax$zaz$za}$za!O$za!R$za!U$za!X$za!n$za#Y$za#Z$za#x$za$f$za$i$za$m$za$q$za$s$za$u$za$w$za$y$za${$za$}$za%O$za%W$za&w$za'S$za'_$za'n$za's$za'u$za'v$za~P$'lO!duO!euO!f4aO!g4hO&c#tO'P4RO'QVO'R4}O'^3lO'aWO'bWO'c3zO'd3eO'e4aO'f4YO'{3sO'|4oO'}4vO(OC[O(T#uO~O'W3VOV$zaf$za&t$za&z$za&{$za']$za'X$za~P.WO'W3YO(P$za'Z$za&t$za']$za'X$za&h$za~P'FwO&_ni~P$4_O&_!iO&g!iO&|!fO&}!gO~P$FcO&_qi~P$4_O&_!iO&g!iO&|!fO&}!gO~P$KmOP!hiV!hi]!hi_!hif!hiu!hix!hiz!hi}!hi!O!hi!R!hi!U!hi!X!hi!d!hi!e!hi!f!hi!g!hi!n!hi!w!hi#Y!hi#Z!hi#x!hi$f!hi$i!hi$m!hi$q!hi$s!hi$u!hi$w!hi$y!hi${!hi$}!hi%O!hi%W!hi&h!hi&t!hi&w!hi&z!hi&{!hi'P!hi'Q!hi'R!hi'S!hi'^!hi'_!hi'a!hi'b!hi'c!hi'd!hi'e!hi'f!hi'n!hi's!hi'u!hi'v!hi~P%=]O&z8QO&{8QOf%bi&t%bi'W%bi']%bi'X%bi~P!BgO&z8RO&{8ROP%biV%bi_%bif%biu%bix%biz%bi}%bi!O%bi!R%bi!U%bi!X%bi!n%bi#Y%bi#Z%bi#x%bi$f%bi$i%bi$m%bi$q%bi$s%bi$u%bi$w%bi$y%bi${%bi$}%bi%O%bi%W%bi&t%bi&w%bi'S%bi'W%bi'X%bi'_%bi'n%bi's%bi'u%bi'v%bi&^%bi&h%bi']%biY%bi[%bi]%bia%bid%bi(P%bi'Z%bi~P(8YO&z8SO&{8SOV%bif%bi&t%bi'W%bi']%bi'X%bi~P.WO'f4[O~P/J|O'W%`i'Z%`i&t%`i']%`i'X%`i(P%`i&h%`i~P'FwO(P%`i~P&3wO&c#tO'P4PO'QVO'R4{O'^3jO'aWO'bWO'c3xO'd3cO(T#uOf%`i!d%`i!e%`i&t%`i&z%`i&{%`i'W%`i']%`i'e%`i'f%`i'{%`i'|%`i'}%`i(O%`i'X%`i~O!f4_O!g4fO~P09VO&c#tO'P4QO'QVO'R4|O'^3kO'aWO'bWO'c3yO'd3dO(T#uOP%`iV%`i_%`if%`iu%`ix%`iz%`i}%`i!O%`i!R%`i!U%`i!X%`i!d%`i!e%`i!n%`i#Y%`i#Z%`i#x%`i$f%`i$i%`i$m%`i$q%`i$s%`i$u%`i$w%`i$y%`i${%`i$}%`i%O%`i%W%`i&t%`i&w%`i&z%`i&{%`i'S%`i'W%`i'X%`i'_%`i'e%`i'f%`i'n%`i's%`i'u%`i'v%`i'{%`i'|%`i'}%`i(O%`i&^%`i&h%`i']%`iY%`i[%`i]%`ia%`id%`i(P%`i'Z%`i~O!f4`O!g4gO~P0;QO&c#tO'P4RO'QVO'R4}O'^3lO'aWO'bWO'c3zO'd3eO(T#uOV%`if%`i!d%`i!e%`i&t%`i&z%`i&{%`i'W%`i']%`i'e%`i'f%`i'{%`i'|%`i'}%`i(O%`i'X%`i~O!f4aO!g4hO~P0?rO&c#tO'P4SO'QVO'R5OO'^3mO'aWO'bWO'c3{O'd3fO(T#uOV%`if%`i!d%`i!e%`i&t%`i'W%`i']%`i'e%`i'f%`i'{%`i'|%`i'}%`i(O%`i'X%`i~O!f4bO!g4iO~P0ApO&c#tO'P4TO'QVO'R5PO'^3nO'aWO'bWO'c3|O'd3gO(T#uOP%`iV%`iY%`i[%`i]%`i_%`if%`iu%`ix%`iz%`i}%`i!O%`i!R%`i!U%`i!X%`i!d%`i!e%`i!n%`i#Y%`i#Z%`i#x%`i$f%`i$i%`i$m%`i$q%`i$s%`i$u%`i$w%`i$y%`i${%`i$}%`i%O%`i%W%`i&h%`i&t%`i&w%`i&z%`i&{%`i'S%`i'_%`i'e%`i'f%`i'n%`i's%`i'u%`i'v%`i'{%`i'|%`i'}%`i(O%`i~O!f4cO!g4jO~P0ChO&c#tO'P4UO'QVO'R5QO'^3oO'aWO'bWO'c3}O'd3hO(T#uO!d%`i!e%`i'W%`i'Z%`i'e%`i'f%`i'{%`i'|%`i'}%`i(O%`i&t%`i']%`i'X%`i(P%`i&h%`i~O!f4dO!g4kO~P0GpO&c#tO'P4VO'QVO'R5RO'^3pO'aWO'bWO'c4OO'd3iO(T#uO!d%`i!e%`i'e%`i'f%`i'{%`i'|%`i'}%`i(O%`i(P%`i~O!f4eO!g4lO~P0IkO!f%`i!g%`i~P09VO!f%`i!g%`i~P0;QO!f%`i!g%`i~P0?rO!f%`i!g%`i~P0ApO!f%`i!g%`i~P0ChO!f%`i!g%`i~P0GpO!f%`i!g%`i~P0IkO!duO!euO!f4_O!g4fO&c#tO'P4PO'QVO'R4{O'^3jO'aWO'bWO'c3xO'd3cO'e4_O'}4tO(T#uOf%`i&t%`i&z%`i&{%`i'W%`i']%`i'f%`i'{%`i(O%`i'X%`i~O'|4mO~P0LlO!duO!euO!f4`O!g4gO&c#tO'P4QO'QVO'R4|O'^3kO'aWO'bWO'c3yO'd3dO'e4`O'}4uO(T#uOP%`iV%`i_%`if%`iu%`ix%`iz%`i}%`i!O%`i!R%`i!U%`i!X%`i!n%`i#Y%`i#Z%`i#x%`i$f%`i$i%`i$m%`i$q%`i$s%`i$u%`i$w%`i$y%`i${%`i$}%`i%O%`i%W%`i&t%`i&w%`i&z%`i&{%`i'S%`i'W%`i'X%`i'_%`i'f%`i'n%`i's%`i'u%`i'v%`i'{%`i(O%`i&^%`i&h%`i']%`iY%`i[%`i]%`ia%`id%`i(P%`i'Z%`i~O'|4nO~P0NgO!duO!euO!f4aO!g4hO&c#tO'P4RO'QVO'R4}O'^3lO'aWO'bWO'c3zO'd3eO'e4aO'}4vO(T#uOV%`if%`i&t%`i&z%`i&{%`i'W%`i']%`i'f%`i'{%`i(O%`i'X%`i~O'|4oO~P1%XO!duO!euO!f4bO!g4iO&c#tO'P4SO'QVO'R5OO'^3mO'aWO'bWO'c3{O'd3fO'e4bO'}4wO(T#uOV%`if%`i&t%`i'W%`i']%`i'f%`i'{%`i(O%`i'X%`i~O'|4pO~P1'VO!duO!euO!f4cO!g4jO&c#tO'P4TO'QVO'R5PO'^3nO'aWO'bWO'c3|O'd3gO'e4cO'}4xO(T#uOP%`iV%`iY%`i[%`i]%`i_%`if%`iu%`ix%`iz%`i}%`i!O%`i!R%`i!U%`i!X%`i!n%`i#Y%`i#Z%`i#x%`i$f%`i$i%`i$m%`i$q%`i$s%`i$u%`i$w%`i$y%`i${%`i$}%`i%O%`i%W%`i&h%`i&t%`i&w%`i&z%`i&{%`i'S%`i'_%`i'f%`i'n%`i's%`i'u%`i'v%`i'{%`i(O%`i~O'|4qO~P1(}O!duO!euO!f4dO!g4kO&c#tO'P4UO'QVO'R5QO'^3oO'aWO'bWO'c3}O'd3hO'e4dO'}4yO(T#uO'W%`i'Z%`i'f%`i'{%`i(O%`i&t%`i']%`i'X%`i(P%`i&h%`i~O'|4rO~P1-VO!duO!euO!f4eO!g4lO&c#tO'P4VO'QVO'R5RO'^3pO'aWO'bWO'c4OO'd3iO'e4eO'}4zO(T#uO'f%`i'{%`i(O%`i(P%`i~O'|4sO~P1/QO'|%`i~P0LlO'|%`i~P0NgO'|%`i~P1%XO'|%`i~P1'VO'|%`i~P1(}O'|%`i~P1-VO'|%`i~P1/QO&c#tO'QVO'aWO'bWO(T#uOf%`i!d%`i!e%`i!f%`i!g%`i&t%`i&z%`i&{%`i'R%`i'W%`i']%`i'e%`i'f%`i'{%`i'|%`i'}%`i(O%`i'X%`i~O'P4PO'^3jO'c3xO'd3cO~P11lO'P4QO'^3kO'c3yO'd3dOP%`iV%`i_%`if%`iu%`ix%`iz%`i}%`i!O%`i!R%`i!U%`i!X%`i!n%`i#Y%`i#Z%`i#x%`i$f%`i$i%`i$m%`i$q%`i$s%`i$u%`i$w%`i$y%`i${%`i$}%`i%O%`i%W%`i&w%`i'S%`i'_%`i'n%`i's%`i'u%`i'v%`i~P&5`O'P4RO'^3lO'c3zO'd3eOV%`i~P11lO'P4SO'QVO'aWO'bWO~P0-UO'P4TO'QVO'aWO'bWO~P0.|O'P4UO'QVO'aWO'bWO~P03UO&c#tO'QVO'aWO'bWO(T#uO!d%`i!e%`i!f%`i!g%`i'R%`i'e%`i'f%`i'{%`i'|%`i'}%`i(O%`i(P%`i~O'P4VO'^3pO'c4OO'd3iO~P17kO&_(PO&g(PO~O&_7kO&g7kO~OP'`XV'`X]'`X_'`Xu'`Xx'`Xz'`X}'`X!O'`X!R'`X!U'`X!X'`X!n'`X#Y'`X#Z'`X#x'`X$f'`X$i'`X$m'`X$q'`X$s'`X$u'`X$w'`X$y'`X${'`X$}'`X%O'`X%W'`X&w'`X'S'`X'_'`X'n'`X's'`X'u'`X'v'`X(P'`X'Z'`X~P''|OV'`X~P''|OP$OXV$OX]$OX_$OXf$OXu$OXx$OXz$OX}$OX!O$OX!R$OX!U$OX!X$OX!d$OX!d'`X!e$OX!e'`X!f$OX!f'`X!g$OX!g'`X!n$OX#Y$OX#Z$OX#x$OX$f$OX$i$OX$m$OX$q$OX$s$OX$u$OX$w$OX$y$OX${$OX$}$OX%O$OX%W$OX&_'`X&a'`X&b'`X&c'`X&f'`X&g'`X&w$OX&z$OX&{$OX&|'`X&}'`X'P$OX'P'`X'Q$OX'Q'`X'R$OX'R'`X'S$OX'W'`X'X'`X'^$OX'^'`X'_$OX'a$OX'a'`X'b$OX'b'`X'c$OX'c'`X'd$OX'd'`X'e$OX'e'`X'f$OX'f'`X'n$OX's$OX'u$OX'v$OX'{'`X'|'`X'}'`X(O'`X(T'`X&t'`X']'`X~OV'`Xf'`X~P1TOVtO])OO_!POf!YOu!QOx)POz!RO}!TO!O!SO!R!UO!U!VO!X!WO!duO!euO!fYO!gYO!n!XO#Y)OO#Z)OO#x)OO$f!ZO$i![O$mWO&z8QO&{8QOf%ci&t%ci'W%ci']%ci'f%ci'X%ci~P/)_O!duO!euO&c#tO'QVO'aWO'bWO(T#uOP%ciV%ci_%cif%ciu%cix%ciz%ci}%ci!O%ci!R%ci!U%ci!X%ci!n%ci#Y%ci#Z%ci#x%ci$f%ci$i%ci$m%ci$q%ci$s%ci$u%ci$w%ci$y%ci${%ci$}%ci%O%ci%W%ci&t%ci&w%ci'S%ci'_%ci'f%ci'n%ci's%ci'u%ci'v%ci&h%ciY%ci[%ci]%ci~O!f4`O!g4gO&z8RO&{8RO'P4QO'R4|O'^3kO'c3yO'd3dO'e4`O'{3rO'|4nO'}4uO(OCZO'W%ci'X%ci&^%ci']%cia%cid%ci(P%ci'Z%ci~P2!hO&z8SO&{8SOV%cif%ci&t%ci'W%ci']%ci'f%ci'X%ci~P/#ZO!f4cO!g4jO&z8TO&{8TO'P4TO'R5PO'^3nO'c3|O'd3gO'e4cO'{3uO'|4qO'}4xO(OC^O~P2!hO!duO!euO&c#tO'QVO'aWO'bWO(T#uOf%ay&t%ay&z%ay&{%ay'W%ay']%ay'f%ay'{%ay'X%ay~O!f4_O!g4fO'P4PO'R4{O'^3jO'c3xO'd3cO'e4_O'|4mO'}4tO(OCYO~P2(yO!f4`O!g4gO'P4QO'R4|O'^3kO'c3yO'd3dO'e4`O'|4nO'}4uO(OCZOP%ayV%ay_%ayf%ayu%ayx%ayz%ay}%ay!O%ay!R%ay!U%ay!X%ay!n%ay#Y%ay#Z%ay#x%ay$f%ay$i%ay$m%ay$q%ay$s%ay$u%ay$w%ay$y%ay${%ay$}%ay%O%ay%W%ay&w%ay'S%ay'_%ay'n%ay's%ay'u%ay'v%ay~P)AfO!f4aO!g4hO'P4RO'R4}O'^3lO'c3zO'd3eO'e4aO'|4oO'}4vO(OC[OV%ay~P2(yO!duO!euO&c#tO'QVO'aWO'bWO(T#uOV%ayf%ay&t%ay']%ay'f%ay'{%ay'X%ay~O!f4bO!g4iO'P4SO'R5OO'^3mO'c3{O'd3fO'e4bO'|4pO'}4wO(OC]O'W%ay~P2.rO!duO!euO&c#tO'QVO'aWO'bWO(T#uOP%ayV%ay_%ayf%ayu%ayx%ayz%ay}%ay!O%ay!R%ay!U%ay!X%ay!n%ay#Y%ay#Z%ay#x%ay$f%ay$i%ay$m%ay$q%ay$s%ay$u%ay$w%ay$y%ay${%ay$}%ay%O%ay%W%ay&t%ay&w%ay&z%ay&{%ay'S%ay'_%ay'f%ay'n%ay's%ay'u%ay'v%ay'{%ay~O!f4cO!g4jO'P4TO'R5PO'^3nO'c3|O'd3gO'e4cO'|4qO'}4xO(OC^OY%ay[%ay]%ay&h%ay~P20jO!duO!euO&c#tO'QVO'aWO'bWO(T#uO'f%ay'{%ay&t%ay']%ay(P%ay~O!f4dO!g4kO'P4UO'R5QO'^3oO'c3}O'd3hO'e4dO'|4rO'}4yO(OC_O'W%ay'Z%ay'X%ay&h%ay~P24rO!duO!euO!f4eO!g4lO&c#tO'P4VO'QVO'R5RO'^3pO'aWO'bWO'c4OO'd3iO'e4eO'|4sO'}4zO(OC`O(T#uO~O'f%ay'{%ay(P%ay~P26mO&z;{O&{;{O'f9WOP$RiV$Ri]$Ri_$Rif$Riu$Rix$Riz$Ri}$Ri!O$Ri!R$Ri!U$Ri!X$Ri!n$Ri#Y$Ri#Z$Ri#x$Ri$f$Ri$i$Ri$m$Ri$q$Ri$s$Ri$u$Ri$w$Ri$y$Ri${$Ri$}$Ri%O$Ri%W$Ri&t$Ri&w$Ri'S$Ri'W$Ri'X$Ri'_$Ri'n$Ri's$Ri'u$Ri'v$Ri']$Ri(P$Ri'Z$Ri~P+=sO!duO!euO!f9`O!g9gO&c,eO&z;|O&{;|O'P9QO'QVO'R9|O'^8kO'aWO'bWO'c8yO'd8dO'e9`O'{8rO'|9nO'}9uO(OCeO(T,fO~O'f9XOV$Rif$Ri'W$Ri'X$Ri&t$Ri']$Ri~P2;VO&z;}O&{;}O'W$Ri'X$Ri'Z$Ri&t$Ri']$Ri~P*A{O!duO!euO!f9dO!g9kO&c,eO&z[O&{>[O'P=`O'QVO'R=fO'^=]O'aWO'bWO'c=_O'd=[O'e=bO'{=^O'|=dO'}=eO(ODPO(T#uO~O'f=aO(P%bi&t%bi']%bi~P5JgO&z=ZO&{=ZO!d$ni!e$ni!f$ni!g$ni&c$ni'P$ni'Q$ni'R$ni'W$ni'^$ni'a$ni'b$ni'c$ni'd$ni'e$ni'f$ni'{$ni'|$ni'}$ni(O$ni(T$ni(P$ni'Z$ni']$ni'X$ni~P& mO'd=[O&t%`i&z%`i&{%`i']%`i'^%`i'c%`i~P05PO!duO!euO!f=bO!g=cO&c#tO'P=`O'QVO'R=fO'^=]O'aWO'bWO'c=_O'd=[O'e=bO'{=^O'|=dO'}=eO(ODPO(T#uO&t%`i&z%`i&{%`i']%`i(P%`i~O'f%`i~P5NnO'^=]O'd=[O&t%`i&z%`i&{%`i']%`i'c%`i~P05PO'^=]O'c=_O'd=[O&t%`i&z%`i&{%`i']%`i~P05PO'f=aO~P5NnO&c#tO'P=`O'QVO'R=fO'^=]O'aWO'bWO'c=_O'd=[O(T#uO!d%`i!e%`i&t%`i&z%`i&{%`i']%`i'e%`i'f%`i'{%`i'|%`i'}%`i(O%`i(P%`i~O!f=bO!g=cO~P6#nO!f%`i!g%`i~P6#nO!duO!euO!f=bO!g=cO&c#tO'P=`O'QVO'R=fO'^=]O'aWO'bWO'c=_O'd=[O'e=bO'}=eO(T#uO&t%`i&z%`i&{%`i']%`i'f%`i'{%`i(O%`i(P%`i~O'|=dO~P6%mO'|%`i~P6%mO(P8UO~P&3wO(P8VO~P&3wO(P8WO~P&3wO(P8XO~P&3wO(P8YO~P&3wO(P8ZO~P&3wO(P8[O~P&3wO'P=`O'^=]O'c=_O'd=[O&t%`i&z%`i&{%`i']%`i~P17kO'Q8]O~O!duO!euO!f=bO!g=cO&c#tO'P=`O'QVO'R=fO'^=]O'aWO'bWO'c=_O'd=[O'e=bO'{=^O'|=dO'}=eO(ODPO(T#uO~O&z=lO&{=lO'f=aO&t&yX']&yX~P6)_O(Q8_O&_'oX&d#cX&e#cX&g'oX~P'=fO(Q8`OV'oX~P'7`O!d'oX!e'oX!f'oX!g'oX&_'oX&a'oX&b'oX&c'oX&d#cX&e#cX&f'oX&g'oX&z'oX&{'oX&|'oX&}'oX'P'oX'Q'oX'R'oX'X'oX'^'oX'a'oX'b'oX'c'oX'd'oX'e'oX'f'oX'{'oX'|'oX'}'oX(O'oX(T'oX&t'oX']'oX~O(Q8aO'W'oX'Z'oX~P6+nOV'oXf'oX!d'oX!e'oX!f'oX!g'oX&_'oX&a'oX&b'oX&c'oX&d#cX&e#cX&f'oX&g'oX&t'oX&z'oX&{'oX&|'oX&}'oX'P'oX'Q'oX'R'oX'X'oX'^'oX'a'oX'b'oX'c'oX'd'oX'e'oX'f'oX'{'oX'|'oX'}'oX(O'oX(T'oX~O(Q8bOP'oX]'oX_'oXu'oXx'oXz'oX}'oX!O'oX!R'oX!U'oX!X'oX!n'oX#Y'oX#Z'oX#x'oX$f'oX$i'oX$m'oX$q'oX$s'oX$u'oX$w'oX$y'oX${'oX$}'oX%O'oX%W'oX&w'oX'S'oX'_'oX'n'oX's'oX'u'oX'v'oX~P6.XO(Q8_O~O(Q8`O~O(Q8aO~O(Q8bO~O'f%ci(P%ci&t%ci']%ci~P5JgO!f=bO!g=cO'P=`O'R=fO'^=]O'c=_O'd=[O'e=bO'|=dO'}=eO(ODPO&z%ay&{%ay~P24rOPCxOVtO])OO_!POf!YOu!QOx)POz!RO}!TO!O!SO!R!UO!U!VO!X!WO!duO!euO!fYO!gYO!n!XO#Y)OO#Z)OO#x)OO$f!ZO$i![O$mvO$qvO'aWO'bWO'c?OO'd>rO'e?[O'{>zO'|?dO'}?hO(ODQO(T#uO~O'f?WOP%biV%bi_%bif%biu%bix%biz%bi}%bi!O%bi!R%bi!U%bi!X%bi!n%bi#Y%bi#Z%bi#x%bi$f%bi$i%bi$m%bi$q%bi$s%bi$u%bi$w%bi$y%bi${%bi$}%bi%O%bi%W%bi&t%bi&w%bi'S%bi'X%bi'_%bi'n%bi's%bi'u%bi'v%bi~P6@_O!duO!euO!f?]O!g?aO&c#tO&z@qO&{@qO'P?TO'QVO'R?mO'^>wO'aWO'bWO'c?PO'd>sO'e?]O'{>{O'|?eO'}?iO(ODRO(T#uO~O'f?XOV%bif%bi&t%bi']%bi'X%bi~P6D^O&c#tO'd>rO(T#uOP%`iV%`i_%`if%`iu%`ix%`iz%`i}%`i!O%`i!R%`i!U%`i!X%`i!d%`i!e%`i!f%`i!g%`i!n%`i#Y%`i#Z%`i#x%`i$f%`i$i%`i$m%`i$q%`i$s%`i$u%`i$w%`i$y%`i${%`i$}%`i%O%`i%W%`i&t%`i&w%`i&z%`i&{%`i'P%`i'Q%`i'R%`i'S%`i'X%`i'_%`i'a%`i'b%`i'c%`i'e%`i'f%`i'n%`i's%`i'u%`i'v%`i'{%`i'|%`i'}%`i(O%`i~O'^%`i~P6FXO&c#tO'd>sO(T#uOV%`if%`i!d%`i!e%`i!f%`i!g%`i&t%`i&z%`i&{%`i'P%`i'Q%`i'R%`i']%`i'a%`i'b%`i'c%`i'e%`i'f%`i'{%`i'|%`i'}%`i(O%`i'X%`i~O'^%`i~P6JWO&c#tO'd>tO(T#uOV%`if%`i!d%`i!e%`i!f%`i!g%`i&t%`i'P%`i'Q%`i'R%`i']%`i'a%`i'b%`i'c%`i'e%`i'f%`i'{%`i'|%`i'}%`i(O%`i'X%`i~O'^%`i~P6LRO&c#tO'd>uO(T#uO!d%`i!e%`i!f%`i!g%`i'P%`i'Q%`i'R%`i']%`i'a%`i'b%`i'c%`i'e%`i'f%`i'{%`i'|%`i'}%`i(O%`i&t%`i~O'^%`i~P6MvO!duO!euO!f?[O!g?`O&c#tO'P?SO'QVO'R?lO'^>vO'aWO'bWO'c?OO'd>rO'e?[O'{>zO'|?dO'}?hO(ODQO(T#uOP%`iV%`i_%`if%`iu%`ix%`iz%`i}%`i!O%`i!R%`i!U%`i!X%`i!n%`i#Y%`i#Z%`i#x%`i$f%`i$i%`i$m%`i$q%`i$s%`i$u%`i$w%`i$y%`i${%`i$}%`i%O%`i%W%`i&t%`i&w%`i&z%`i&{%`i'S%`i'X%`i'_%`i'n%`i's%`i'u%`i'v%`i~O'f%`i~P7 bO!duO!euO!f?]O!g?aO&c#tO'P?TO'QVO'R?mO'^>wO'aWO'bWO'c?PO'd>sO'e?]O'{>{O'|?eO'}?iO(ODRO(T#uOV%`if%`i&t%`i&z%`i&{%`i']%`i'X%`i~O'f%`i~P7%aO!duO!euO!f?^O!g?bO&c#tO'P?UO'QVO'R?nO'^>xO'aWO'bWO'c?QO'd>tO'e?^O'{>|O'|?fO'}?jO(ODSO(T#uOV%`if%`i&t%`i']%`i'X%`i~O'f%`i~P7'[O!duO!euO!f?_O!g?cO&c#tO'P?VO'QVO'R?oO'^>yO'aWO'bWO'c?RO'd>uO'e?_O'{>}O'|?gO'}?kO(ODTO(T#uO']%`i&t%`i~O'f%`i~P7)PO'^>vO~P6FXO'^>wO~P6JWO'^>xO~P6LRO'^>yO~P6MvO&c#tO'^>vO'c?OO'd>rO(T#uOP%`iV%`i_%`if%`iu%`ix%`iz%`i}%`i!O%`i!R%`i!U%`i!X%`i!d%`i!e%`i!f%`i!g%`i!n%`i#Y%`i#Z%`i#x%`i$f%`i$i%`i$m%`i$q%`i$s%`i$u%`i$w%`i$y%`i${%`i$}%`i%O%`i%W%`i&t%`i&w%`i&z%`i&{%`i'R%`i'S%`i'X%`i'_%`i'e%`i'f%`i'n%`i's%`i'u%`i'v%`i'{%`i'|%`i'}%`i(O%`i~O'P%`i'Q%`i'a%`i'b%`i~P7+XO&c#tO'^>wO'c?PO'd>sO(T#uOV%`if%`i!d%`i!e%`i!f%`i!g%`i&t%`i&z%`i&{%`i'R%`i']%`i'e%`i'f%`i'{%`i'|%`i'}%`i(O%`i'X%`i~O'P%`i'Q%`i'a%`i'b%`i~P7/WO&c#tO'^>xO'c?QO'd>tO(T#uOV%`if%`i!d%`i!e%`i!f%`i!g%`i&t%`i'R%`i']%`i'e%`i'f%`i'{%`i'|%`i'}%`i(O%`i'X%`i~O'P%`i'Q%`i'a%`i'b%`i~P71RO&c#tO'^>yO'c?RO'd>uO(T#uO!d%`i!e%`i!f%`i!g%`i'R%`i']%`i'e%`i'f%`i'{%`i'|%`i'}%`i(O%`i&t%`i~O'P%`i'Q%`i'a%`i'b%`i~P72vO'f?WO~P7 bO'f?XO~P7%aO'f?YO~P7'[O'f?ZO~P7)PO&c#tO'P?SO'QVO'R?lO'^>vO'aWO'bWO'c?OO'd>rO(T#uOP%`iV%`i_%`if%`iu%`ix%`iz%`i}%`i!O%`i!R%`i!U%`i!X%`i!d%`i!e%`i!n%`i#Y%`i#Z%`i#x%`i$f%`i$i%`i$m%`i$q%`i$s%`i$u%`i$w%`i$y%`i${%`i$}%`i%O%`i%W%`i&t%`i&w%`i&z%`i&{%`i'S%`i'X%`i'_%`i'e%`i'f%`i'n%`i's%`i'u%`i'v%`i'{%`i'|%`i'}%`i(O%`i~O!f?[O!g?`O~P75OO&c#tO'P?TO'QVO'R?mO'^>wO'aWO'bWO'c?PO'd>sO(T#uOV%`if%`i!d%`i!e%`i&t%`i&z%`i&{%`i']%`i'e%`i'f%`i'{%`i'|%`i'}%`i(O%`i'X%`i~O!f?]O!g?aO~P78}O&c#tO'P?UO'QVO'R?nO'^>xO'aWO'bWO'c?QO'd>tO(T#uOV%`if%`i!d%`i!e%`i&t%`i']%`i'e%`i'f%`i'{%`i'|%`i'}%`i(O%`i'X%`i~O!f?^O!g?bO~P7:xO&c#tO'P?VO'QVO'R?oO'^>yO'aWO'bWO'c?RO'd>uO(T#uO!d%`i!e%`i']%`i'e%`i'f%`i'{%`i'|%`i'}%`i(O%`i&t%`i~O!f?_O!g?cO~P7vO'aWO'bWO'c?OO'd>rO'e?[O'}?hO(T#uOP%`iV%`i_%`if%`iu%`ix%`iz%`i}%`i!O%`i!R%`i!U%`i!X%`i!n%`i#Y%`i#Z%`i#x%`i$f%`i$i%`i$m%`i$q%`i$s%`i$u%`i$w%`i$y%`i${%`i$}%`i%O%`i%W%`i&t%`i&w%`i&z%`i&{%`i'S%`i'X%`i'_%`i'f%`i'n%`i's%`i'u%`i'v%`i'{%`i(O%`i~O'|?dO~P7?RO!duO!euO!f?]O!g?aO&c#tO'P?TO'QVO'R?mO'^>wO'aWO'bWO'c?PO'd>sO'e?]O'}?iO(T#uOV%`if%`i&t%`i&z%`i&{%`i']%`i'f%`i'{%`i(O%`i'X%`i~O'|?eO~P7CQO!duO!euO!f?^O!g?bO&c#tO'P?UO'QVO'R?nO'^>xO'aWO'bWO'c?QO'd>tO'e?^O'}?jO(T#uOV%`if%`i&t%`i']%`i'f%`i'{%`i(O%`i'X%`i~O'|?fO~P7D{O!duO!euO!f?_O!g?cO&c#tO'P?VO'QVO'R?oO'^>yO'aWO'bWO'c?RO'd>uO'e?_O'}?kO(T#uO']%`i'f%`i'{%`i(O%`i&t%`i~O'|?gO~P7FpO'|%`i~P7?RO'|%`i~P7CQO'|%`i~P7D{O'|%`i~P7FpO'P?SO'QVO'aWO'bWO~P7+XO'P?TO'QVO'aWO'bWO~P7/WO'P?UO'QVO'aWO'bWO~P71RO'P?VO'QVO'aWO'bWO~P72vOPCwOVtO])OO_!POf!YOu!QOx)POz!RO}!TO!O!SO!R!UO!U!VO!X!WO!duO!euO!fYO!gYO!n!XO#Y)OO#Z)OO#x)OO$f!ZO$i![O$mvO'c?OO'd>rO'e?[O'|?dO'}?hO(ODQO'X%ay~P20jO!f?]O!g?aO'P?TO'R?mO'^>wO'c?PO'd>sO'e?]O'|?eO'}?iO(ODRO&z%ay&{%ay~P2.rO!f?^O!g?bO'P?UO'R?nO'^>xO'c?QO'd>tO'e?^O'|?fO'}?jO(ODSO~P2.rO!duO!euO!f?_O!g?cO&c#tO'P?VO'QVO'R?oO'^>yO'aWO'bWO'c?RO'd>uO'e?_O'|?gO'}?kO(ODTO(T#uO~O']%ay'f%ay'{%ay&t%ay~P8(tO!duO!euO!fAbO!gAfO&c,eO&zBxO&{BxO'PAYO'QVO'RArO'^@|O'aWO'bWO'cAUO'd@xO'eAbO'{AQO'|AjO'}AnO(ODUO(T,fO~O'fA^OV$Rif$Ri&t$Ri']$Ri'X$Ri~P8*`O&zByO&{ByO(P$Ri&t$Ri']$Ri~P+:uO&c,eO'd@xO(T,fOV$Pif$Pi!d$Pi!e$Pi!f$Pi!g$Pi&t$Pi&z$Pi&{$Pi'P$Pi'Q$Pi'R$Pi']$Pi'a$Pi'b$Pi'c$Pi'e$Pi'f$Pi'{$Pi'|$Pi'}$Pi(O$Pi'X$Pi~O'^$Pi~P8,nO&c,eO'd@yO(T,fOV$Pif$Pi!d$Pi!e$Pi!f$Pi!g$Pi&t$Pi'P$Pi'Q$Pi'R$Pi']$Pi'a$Pi'b$Pi'c$Pi'e$Pi'f$Pi'{$Pi'|$Pi'}$Pi(O$Pi'X$Pi~O'^$Pi~P8.iO'd@zO&t$Pi&z$Pi&{$Pi']$Pi'^$Pi'c$Pi~P3?kO&c,eO'd@{O(T,fO!d$Pi!e$Pi!f$Pi!g$Pi&t$Pi'P$Pi'Q$Pi'R$Pi']$Pi'a$Pi'b$Pi'c$Pi'e$Pi'f$Pi'{$Pi'|$Pi'}$Pi(O$Pi~O'^$Pi~P80wO!duO!euO!fAbO!gAfO&c,eO'PAYO'QVO'RArO'^@|O'aWO'bWO'cAUO'd@xO'eAbO'{AQO'|AjO'}AnO(ODUO(T,fOV$Pif$Pi&t$Pi&z$Pi&{$Pi']$Pi'X$Pi~O'f$Pi~P82cO!duO!euO!fAcO!gAgO&c,eO'PAZO'QVO'RAsO'^@}O'aWO'bWO'cAVO'd@yO'eAcO'{ARO'|AkO'}AoO(ODVO(T,fOV$Pif$Pi&t$Pi']$Pi'X$Pi~O'f$Pi~P84^O!duO!euO!fAdO!gAhO&c,eO'PA[O'QVO'RAtO'^AOO'aWO'bWO'cAWO'd@zO'eAdO'{ASO'|AlO'}ApO(ODWO(T,fO&t$Pi&z$Pi&{$Pi']$Pi(P$Pi~O'f$Pi~P86RO!duO!euO!fAeO!gAiO&c,eO'PA]O'QVO'RAuO'^APO'aWO'bWO'cAXO'd@{O'eAeO'{ATO'|AmO'}AqO(ODXO(T,fO&t$Pi']$Pi~O'f$Pi~P87vO'^@|O~P8,nO'^@}O~P8.iO'^AOO'd@zO&t$Pi&z$Pi&{$Pi']$Pi'c$Pi~P3?kO'^APO~P80wO&c,eO'^@|O'cAUO'd@xO(T,fOV$Pif$Pi!d$Pi!e$Pi!f$Pi!g$Pi&t$Pi&z$Pi&{$Pi'R$Pi']$Pi'e$Pi'f$Pi'{$Pi'|$Pi'}$Pi(O$Pi'X$Pi~O'P$Pi'Q$Pi'a$Pi'b$Pi~P8:bO&c,eO'^@}O'cAVO'd@yO(T,fOV$Pif$Pi!d$Pi!e$Pi!f$Pi!g$Pi&t$Pi'R$Pi']$Pi'e$Pi'f$Pi'{$Pi'|$Pi'}$Pi(O$Pi'X$Pi~O'P$Pi'Q$Pi'a$Pi'b$Pi~P8<]O'^AOO'cAWO'd@zO&t$Pi&z$Pi&{$Pi']$Pi~P3?kO&c,eO'^APO'cAXO'd@{O(T,fO!d$Pi!e$Pi!f$Pi!g$Pi&t$Pi'R$Pi']$Pi'e$Pi'f$Pi'{$Pi'|$Pi'}$Pi(O$Pi~O'P$Pi'Q$Pi'a$Pi'b$Pi~P8>kO'fA^O~P82cO'fA_O~P84^O'fA`O~P86RO'fAaO~P87vO&c,eO'PAYO'QVO'RArO'^@|O'aWO'bWO'cAUO'd@xO(T,fOV$Pif$Pi!d$Pi!e$Pi&t$Pi&z$Pi&{$Pi']$Pi'e$Pi'f$Pi'{$Pi'|$Pi'}$Pi(O$Pi'X$Pi~O!fAbO!gAfO~P8@sO&c,eO'PAZO'QVO'RAsO'^@}O'aWO'bWO'cAVO'd@yO(T,fOV$Pif$Pi!d$Pi!e$Pi&t$Pi']$Pi'e$Pi'f$Pi'{$Pi'|$Pi'}$Pi(O$Pi'X$Pi~O!fAcO!gAgO~P8BnO&c,eO'PA[O'QVO'RAtO'^AOO'aWO'bWO'cAWO'd@zO(T,fO!d$Pi!e$Pi&t$Pi&z$Pi&{$Pi']$Pi'e$Pi'f$Pi'{$Pi'|$Pi'}$Pi(O$Pi(P$Pi~O!fAdO!gAhO~P8DcO&c,eO'PA]O'QVO'RAuO'^APO'aWO'bWO'cAXO'd@{O(T,fO!d$Pi!e$Pi&t$Pi']$Pi'e$Pi'f$Pi'{$Pi'|$Pi'}$Pi(O$Pi~O!fAeO!gAiO~P8FWO!f$Pi!g$Pi~P8@sO!f$Pi!g$Pi~P8BnO!f$Pi!g$Pi~P8DcO!f$Pi!g$Pi~P8FWO!duO!euO!fAbO!gAfO&c,eO'PAYO'QVO'RArO'^@|O'aWO'bWO'cAUO'd@xO'eAbO'}AnO(T,fOV$Pif$Pi&t$Pi&z$Pi&{$Pi']$Pi'f$Pi'{$Pi(O$Pi'X$Pi~O'|AjO~P8HlO!duO!euO!fAcO!gAgO&c,eO'PAZO'QVO'RAsO'^@}O'aWO'bWO'cAVO'd@yO'eAcO'}AoO(T,fOV$Pif$Pi&t$Pi']$Pi'f$Pi'{$Pi(O$Pi'X$Pi~O'|AkO~P8JgO!duO!euO!fAdO!gAhO&c,eO'PA[O'QVO'RAtO'^AOO'aWO'bWO'cAWO'd@zO'eAdO'}ApO(T,fO&t$Pi&z$Pi&{$Pi']$Pi'f$Pi'{$Pi(O$Pi(P$Pi~O'|AlO~P8L[O!duO!euO!fAeO!gAiO&c,eO'PA]O'QVO'RAuO'^APO'aWO'bWO'cAXO'd@{O'eAeO'}AqO(T,fO&t$Pi']$Pi'f$Pi'{$Pi(O$Pi~O'|AmO~P8NPO'|$Pi~P8HlO'|$Pi~P8JgO'|$Pi~P8L[O'|$Pi~P8NPO'PAYO'QVO'aWO'bWO~P8:bO'PAZO'QVO'aWO'bWO~P8<]O'PA[O'^AOO'cAWO'd@zO&t$Pi&z$Pi&{$Pi']$Pi~P4@rO'PA]O'QVO'aWO'bWO~P8>kOV$Sif$Si&t$Si']$Si'f$Si'X$Si~P8*`O!duO!euO!fAdO!gAhO&c,eO'PA[O'QVO'RAtO'^AOO'aWO'bWO'cAWO'd@zO'eAdO'|AlO'}ApO(ODWO(T,fO~O&zByO&{ByO'{ASO'f$Si(P$Si&t$Si']$Si~P9$_O!fAbO!gAfO'PAYO'RArO'^@|O'cAUO'd@xO'eAbO'|AjO'}AnO(ODUO']$Qy~P5%yO!fAcO!gAgO'PAZO'RAsO'^@}O'cAVO'd@yO'eAcO'|AkO'}AoO(ODVO~P4NcO&t$Qy&z$Qy&{$Qy']$Qy'f$Qy'{$Qy(P$Qy~P9$_O!duO!euO!fAeO!gAiO&c,eO'PA]O'QVO'RAuO'^APO'aWO'bWO'cAXO'd@{O'eAeO'|AmO'}AqO(ODXO(T,fO~O&t$Qy']$Qy'f$Qy'{$Qy~P9(^O&_=PO&g=PO&a!cX&b!cX&f!cX~O&_=QO&g=QO&z!cX&{!cX~P1GZO(Q=WO~O(P>]O~P&3wO&tii']ii~P)=vOV>aOf,jO&t'xX']'xX'X'xX~OV>aOf,jO&t'xa']'xa'X'xa~O'fAaO'{ATO&t#Wi']#Wi~P9(^O!duO!euO&c,eO'QVO'aWO'bWO(T,fO~O!fAcO!gAgO'PAZO'RAsO'^@}O'cAVO'd@yO'eAcO'fA_O'{ARO'|AkO'}AoO(ODVOV#qaf#qa&t#qa']#qa'X#qa~P9,VO(Q>pO~O(Q>qO~O(Q>pOP'OXV'OX_'OXf'OXu'OXx'OXz'OX}'OX!O'OX!R'OX!U'OX!X'OX!d'OX!e'OX!f'OX!g'OX!n'OX#Y'OX#Z'OX#x'OX$f'OX$i'OX$m'OX$q'OX$s'OX$u'OX$w'OX$y'OX${'OX$}'OX%O'OX%W'OX&c'OX&t'OX&w'OX&z'OX&{'OX'P'OX'Q'OX'R'OX'S'OX'X'OX'^'OX'_'OX'a'OX'b'OX'c'OX'd'OX'e'OX'f'OX'n'OX's'OX'u'OX'v'OX'{'OX'|'OX'}'OX(O'OX(T'OX~P$:YO(Q>qOV'OXf'OX!d'OX!e'OX!f'OX!g'OX&c'OX&t'OX'P'OX'Q'OX'R'OX']'OX'^'OX'a'OX'b'OX'c'OX'd'OX'e'OX'f'OX'{'OX'|'OX'}'OX(O'OX(T'OX'X'OX&z'OX&{'OX~P$:YO(Q=WO!d'OX!e'OX!f'OX!g'OX&c'OX'P'OX'Q'OX'R'OX'^'OX'a'OX'b'OX'c'OX'd'OX'e'OX'f'OX'{'OX'|'OX'}'OX(O'OX(P'OX(T'OX&t'OX&z'OX&{'OX']'OX~P$:YO(P@rO~P&3wO(P@sO~P&3wO(P@tO~P&3wO(P@uO~P&3wO(Q@vO']'oX~P6.XO(Q@wO!d'oX!e'oX!f'oX!g'oX&_'oX&a'oX&b'oX&c'oX&d#cX&e#cX&f'oX&g'oX&|'oX&}'oX'P'oX'Q'oX'R'oX'^'oX'a'oX'b'oX'c'oX'd'oX'e'oX'f'oX'{'oX'|'oX'}'oX(O'oX(P'oX(T'oX&t'oX&z'oX&{'oX']'oX~O(Q@vO~O(Q@wO~O(PBzO~P+'|O(PB{O~P+'|O(PB|O~P+'|O(PB}O~P+'|O'e~", @@ -7661,7 +7804,7 @@ const parser$7 = LRParser$5.deserialize({ ], skippedNodes: [0,2,3], repeatNodeCount: 36, - tokenData: "#$d~R.[XYHwYZHwpqHwqrJursK[stKotuKzuvLPvwL^wxLnxyMhyzMmz{LP{|Mr|}Mz}!ONP!O!PNo!P!Q!Gu!Q!R!Lu!R![!Mo![!]# s!]!^#!T!^!_#!Y!_!`#!r!`!a!JT!b!c##P!}#O##U#O#P!Js#P#Q##Z#Q#R!Jx#S#T##`#o#p##e#p#q##j#q#r#$W#r#s!LY$r$s!Jc$w$x!Ko%o%p!Js&a&bLP%!]%!^!Js%#t%#uNe%#u%#v!La%#v%#wNe%#w%#x!La%#x%#yNe%$O%$PNe%$P%$QNe%$Q%$RNe%$R%$SNe%$S%$TNe%$U%$VNe%$W%$XNe%$X%$YNe%$Y%$ZNe%$[%$]Ne%$_%$`Ne%$`%$aNe%$a%$bNe%$b%$cNe%$d%$eNe%$r%$sNe%$s%$tNe%$v%$wNe%$w%$xNe%$z%${Ne%$|%$}Ne%$}%%ONe%%P%%QNe%%R%%SNe%%S%%TNe%%T%%UNe%%U%%VNe%%V%%WNe%%W%%XNe%%Y%%ZNe%%[%%]Ne%%b%%cNe%%c%%dNe%%d%%eNe%%e%%fNe%%h%%iNe%%j%%kNe%%|%%}Ne%%}%&O!La%&O%&PNe%&P%&QNe%&Q%&RNe%&R%&SNe%&S%&TNe%&T%&UNe%&U%&VNe%&V%&WNe%&W%&XNe%&X%&YNe%&b%&c#$]%&c%&dKV%&d%&eKV%&e%&fKV%&f%&gKV%&g%&hKV%&m%&n!Ko%&n%&o!Ko%&q%&r!Js%&r%&s!Js%&s%&t!Js%&t%&u!Jc%&u%&v!Jc%&v%&w!Jc%&w%&xKV%'O%'P!Js%'P%'QKV%'Q%'RKV%'R%'S!Js%'S%'T!Ko%'T%'U!Js%'U%'V!Ko%'c%'dKV%'d%'e!Ko%'f%'gKV%'g%'hKV%'i%'jKV%'j%'kKV%'l%'m!Js%'m%'nKV%'n%'o!Lf%'o%'pKV%'p%'qKV%'q%'rKV%'r%'sKV%'s%'tKV%'t%'uKV%'u%'vKV%'v%'wKV%'w%'xKV%'x%'yKV%'y%'zKV%'z%'{KV%'{%'|!Ko%'|%'}KV%'}%(OKV%(O%(PKV%(P%(QKV%(Q%(RLX%(R%(SLX%(S%(TKV%(T%(UKV%(U%(VKV%(V%(WKV%(W%(XKV%(X%(YKV%(Y%(ZKV%(Z%([KV%([%(]KV%(]%(^KV%(^%(_KV%(_%(`KV%(`%(aKV%(a%(bKV%(b%(cKV%(c%(dKV%(d%(eKV%(e%(fKV%(f%(gKV%(g%(hKV%(h%(iKV%(i%(jKV%(j%(kKV%(k%(lKV%(l%(mKV%(m%(nKV%(n%(oKV%(o%(pKV%(p%(qKV%(q%(rKV%(r%(sKV%(s%(tKV%(t%(uKV%(u%(vKV%(v%(wKV%(w%(xKV%(x%(yKV%(y%(zKV%(z%({KV%({%(|KV%(|%(}KV%(}%)OKV%)O%)PKV%)P%)QKV%)Q%)RKV%)R%)SKV%)S%)TKV%)T%)UKV%)U%)VKV%)V%)WKV%)W%)XKV%)X%)YKV%)Y%)ZKV%)Z%)[KV%)]%)^!Js%)^%)_!Ko%)_%)`KV%)`%)aKV%)a%)bKV%)b%)cKV%)c%)d!Js%)d%)e!Ko%)e%)f!Ko%)f%)g!Ko%)g%)h!Js%)h%)i!Js%)i%)j!Js%)j%)k!Js%)k%)l!Js%)l%)mKV%)n%)o!Ko%)o%)p!Ko%)p%)q!Js%)q%)r!Js%)r%)sKV%)s%)tKV%)y%)zKV%)|%)}KV%*O%*PKV%*Q%*RKV%*R%*SKV%*S%*TKV%*T%*UKV%*U%*VKV%*V%*WKV%*W%*XKV%*X%*YKV%*]%*^!Lm%*^%*_!Js%*_%*`!Ko%*f%*g!Js%*g%*h!Js%*h%*i!Js%*i%*j!Js%*k%*l!Js%*l%*m!Js%*m%*n!Js%*n%*o!Js%*o%*pKV%*p%*q!Ko%*q%*r!Js%*r%*sKV%*s%*tKV%*t%*u!Js%*u%*v!Ko%*w%*xKV%*x%*yKV%*y%*zKV%*z%*{KV%*{%*|KV%*|%*}KV%*}%+OKV%+O%+PKV%+P%+QKV%+Q%+RKV%+R%+SKV%+S%+TKV%+T%+UKV%+U%+VKV%+V%+WKV%+W%+XKV%+X%+YKV%+Y%+ZKV%+Z%+[KV%+[%+]KV%+]%+^KV%+^%+_KV%+_%+`KV%+`%+aKV%+a%+bKV%+f%+gKV%+g%+hKV%+h%+iKV%+i%+jKV%+j%+kKV%+k%+lKV%+l%+mKV%+m%+nKV%+n%+oKV%+o%+pKV%+p%+qKV%+q%+rKV%+r%+sKV%+s%+tKV%:y%:z!Js%F[%F]KV%Fb%FcKV%Fc%FdKV%Fk%Fl!Js%Fl%FmKV%Fo%Fp!Js%Fp%Fq!Js%Fq%Fr!Js%G[%G]!La%G]%G^!La%Ga%GbNe%Gb%GcNe%Gc%GdNe%Ge%GfNe%Gf%GgNe%Gg%GhNe%Gh%GiNe%Gi%GjNe%Gj%GkNe%Gk%GlNe%MW%MXNe%MX%MYNe%MY%MZNe%MZ%M[Ne%M[%M]Ne%M]%M^Ne%M^%M_Ne%M_%M`Ne%M`%Ma!La%Ma%Mb!La%Mb%Mc!La%Mc%Md!La%Md%MeNe%Me%MfNe%Mf%MgNe%Mg%MhNe%Mh%MiNe%Mi%MjNe%Mj%Mk!La%Mk%Ml!La%Ml%MmNe%Mm%MnNe%Mn%MoNe%Mo%MpNe%Mp%MqNe%Mu%MvNe%Mv%MwNe%Mw%MxNe%Mx%MyNe%Nn%NoNe%No%NpNe%Np%NqNe%Nq%NrNe%Nr%NsNe%Ns%Nt!La%Nt%NuNe%Nu%NvNe%Nv%Nw!La%Nw%Nx!La%Nx%NyNe%Ny%Nz!La%Nz%N{Ne%N{%N|!La%N|%N}Ne%N}& ONe& O& P!La& P& Q!La& Q& RNe& R& SNe& S& T!La& T& U!La& U& VNe& V& WNe& W& X!La& X& Y!La& Y& ZNe& Z& [Ne& [& ]!La& ]& ^!La& ^& _Ne& _& `!La& `& aNe& a& b!La& b& cNe& c& dNe& d& eNe& e& fNe& f& gNe& g& hNe& h& iNe& i& jNe& j& k!La& k& l!La& l& mNe&#V&#WKV&#W&#X!Js&#[&#]!Js&#^&#_!Js&#_&#`!Js&#`&#aKV&#a&#bKV&$R&$SKV&$T&$UKV&$U&$VKV&$V&$WKV&$f&$gNe&$h&$i!Js&$i&$j!Js&$l&$m!Ko&$m&$n!Ko&$y&$z!Js&$z&${!Ko&%a&%b!Js&%f&%g!Ko&%g&%h!Ko&%h&%i!Ko&%i&%j!Ko&%j&%k!Ko&%k&%l!Ko&%l&%m!Ko&%m&%n!Ko&%n&%o!Ko&%o&%p!Ko&%p&%q!Ko&%q&%r!Ko&%r&%s!Ko&%t&%u!Js&%u&%v!Js&%v&%w!Js&%w&%x!Js&%x&%y!Js&%y&%z!Js&%z&%{!Js&%{&%|!Js&%|&%}!Js&%}&&O!Ko&&O&&P!Ko&&P&&Q!Js&&Q&&R!Js&&R&&S!Js&&U&&V!Js&&V&&W!Ko&&W&&X!Ko&&X&&Y!Js&&Y&&Z!Js&&Z&&[!Ko&&`&&a!Ko&&a&&b!Js&&b&&c!Ko&&c&&d!Js&&d&&e!Js&&e&&f!Ko&&f&&g!Ko&&g&&h!Js&&h&&i!Ko&&i&&j!Js&&j&&k!Ko&&k&&l!Js&&l&&m!Ko&&m&&n!Ko&&n&&o!Js&&p&&q!Js&&q&&r!Ko&&r&&s!Js&&s&&t!Ko&&t&&u!Js&&u&&v!Js&&v&&w!Js&&w&&x!Ko&&x&&y!Ko&&y&&z!Ko&&|&&}KV&&}&'OKV&'Q&'RKV&'R&'SKV&'S&'TKV&'T&'UKV&'U&'VKV&'V&'WKV&'W&'XKV&'X&'YKV&'Y&'ZKV&'Z&'[KV&'[&']LX&']&'^KV&'^&'_KV&'_&'`KV&'`&'aKV&'a&'bKV&'b&'cKV&'c&'dKV&'d&'eKV&'e&'fKV&'f&'gKV&'g&'hKV&'h&'iKV&'i&'jKV&'j&'kKV&'k&'lKV&'l&'mKV&'m&'nKV&'n&'oKV&'o&'pKV&'p&'qKV&'q&'rKV&'r&'sKV&'s&'tKV&'t&'uKV&'u&'vKV&'v&'wKV&'w&'xKV&'x&'yKV&'y&'zKV&'z&'{KV&'{&'|KV&'|&'}KV&'}&(OKV&(O&(PKV&(P&(QKV&(Q&(RKV&(R&(SKV&(S&(TKV&(T&(UKV&(U&(VKV&(V&(WKV&(W&(XKV&(X&(YKV&(Y&(ZKV&(Z&([KV&([&(]KV&(]&(^KV&(^&(_KV&(_&(`KV&(`&(aKV&(a&(bKV&(b&(cKV&(c&(dKV&(d&(eKV&(e&(fKV&(f&(gKV&(g&(hKV&(h&(iKV&(i&(jKV&(j&(kKV&(k&(lKV&(l&(mKV&(m&(nKV&(n&(oKV&(o&(pKV&(p&(qKV&(q&(rKV&(r&(sKV&(s&(tKV&(t&(uKV&(u&(vKV&(v&(wKV&(w&(xKV&(x&(yKV&(y&(zKV&(z&({KV&({&(|KV&(|&(}KV&(}&)OKV&)O&)PKV&)P&)QKV&)Q&)RKV&)R&)SKV&)S&)TKV&)T&)UKV&)U&)VKV&)V&)WKV&)W&)XKV&)X&)YKV&)Y&)ZKV&)Z&)[KV&)[&)]KV&)]&)^KV&)^&)_KV&)_&)`KV&)`&)aKV&)a&)bKV&)b&)cKV&)c&)dKV&)d&)eKV&)e&)fKV&)g&)h!Js&*T&*UKV&*U&*VKV&*V&*WKV&*W&*XKV&+`&+aNe&+a&+bNe&+b&+cNe&+c&+dNe&+d&+eNe&+e&+fNe&+f&+gNe&+g&+hNe&+h&+iNe&+i&+jNe&+j&+kNe&+k&+lNe&+l&+mNe&+m&+nNe&+n&+oNe&+o&+pNe&+p&+qNe&+q&+rNe&+r&+sNe&+s&+tNe&+t&+uNe&+w&+xNe&+x&+yNe&+y&+zNe&+z&+{Ne&+{&+|Ne&+|&+}Ne?MX?MYNe?MY?MZ!La?MZ?M[Ne?M[?M]!La~H|T&q~XYI]YZI]pqI]![!]Io!a!bJZ~I`TXYI]YZI]pqI]![!]Io!a!bJZ~IrRXYI{YZI{pqI{~JQR(P~XYI{YZI{pqI{~J^RXYJgYZJgpqJg~JlR(O~XYJgYZJgpqJg~JzP'_~!_!`J}PKSP'eP!_!`KVPK[O'eP~KaP's~rsKd~KgPrsKj~KoO'u~~KtQR~OYKoZ~Ko~LPO'P~~LUP'c~!_!`LX~L^O&z~~LcQ'c~vwLi!_!`LX~LnO'}~RLsS(RQOwMPx#OMP#O#PM[#P~MPPMSPwxMVPM[O#ZPPM_ROwMPwxMVx~MP~MmO&w~~MrO']~~MwP'b~!_!`LX~NPO'W~~NUR'b~}!ON_!_!`LX!`!aNj~NbP!`!aNe~NjO'f~~NoO(Q~~Nt-w'Q~qrJuuvLPvwLPz{LP{|Mr}!O!G_!O!P!Gj!P!Q!Gu!Q![!HW!^!_!IT!_!`!Is!`!a!JT#O#P!Js#Q#R!Jx#p#q!KQ#r#s!LY$r$s!Jc$w$x!Ko%o%p!Js&a&bLP%!]%!^!Js%#t%#uNe%#u%#v!La%#v%#wNe%#w%#x!La%#x%#yNe%$O%$PNe%$P%$QNe%$Q%$RNe%$R%$SNe%$S%$TNe%$U%$VNe%$W%$XNe%$X%$YNe%$Y%$ZNe%$[%$]Ne%$_%$`Ne%$`%$aNe%$a%$bNe%$b%$cNe%$d%$eNe%$r%$sNe%$s%$tNe%$v%$wNe%$w%$xNe%$z%${Ne%$|%$}Ne%$}%%ONe%%P%%QNe%%R%%SNe%%S%%TNe%%T%%UNe%%U%%VNe%%V%%WNe%%W%%XNe%%Y%%ZNe%%[%%]Ne%%b%%cNe%%c%%dNe%%d%%eNe%%e%%fNe%%h%%iNe%%j%%kNe%%|%%}Ne%%}%&O!La%&O%&PNe%&P%&QNe%&Q%&RNe%&R%&SNe%&S%&TNe%&T%&UNe%&U%&VNe%&V%&WNe%&W%&XNe%&X%&YNe%&b%&cKV%&c%&dKV%&d%&eKV%&e%&fKV%&f%&gKV%&g%&hKV%&m%&n!Ko%&n%&o!Ko%&q%&r!Js%&r%&s!Js%&s%&t!Js%&t%&u!Jc%&u%&v!Jc%&v%&w!Jc%&w%&xKV%'O%'P!Js%'P%'QKV%'Q%'RKV%'R%'S!Js%'S%'T!Ko%'T%'U!Js%'U%'V!Ko%'c%'dKV%'d%'e!Ko%'f%'gKV%'g%'hKV%'i%'jKV%'j%'kKV%'l%'m!Js%'m%'nKV%'n%'o!Lf%'o%'pKV%'p%'qKV%'q%'rKV%'r%'sKV%'s%'tKV%'t%'uKV%'u%'vKV%'v%'wKV%'w%'xKV%'x%'yKV%'y%'zKV%'z%'{KV%'{%'|!Ko%'|%'}KV%'}%(OKV%(O%(PKV%(P%(QKV%(Q%(RLX%(R%(SLX%(S%(TKV%(T%(UKV%(U%(VKV%(V%(WKV%(W%(XKV%(X%(YKV%(Y%(ZKV%(Z%([KV%([%(]KV%(]%(^KV%(^%(_KV%(_%(`KV%(`%(aKV%(a%(bKV%(b%(cKV%(c%(dKV%(d%(eKV%(e%(fKV%(f%(gKV%(g%(hKV%(h%(iKV%(i%(jKV%(j%(kKV%(k%(lKV%(l%(mKV%(m%(nKV%(n%(oKV%(o%(pKV%(p%(qKV%(q%(rKV%(r%(sKV%(s%(tKV%(t%(uKV%(u%(vKV%(v%(wKV%(w%(xKV%(x%(yKV%(y%(zKV%(z%({KV%({%(|KV%(|%(}KV%(}%)OKV%)O%)PKV%)P%)QKV%)Q%)RKV%)R%)SKV%)S%)TKV%)T%)UKV%)U%)VKV%)V%)WKV%)W%)XKV%)X%)YKV%)Y%)ZKV%)Z%)[KV%)]%)^!Js%)^%)_!Ko%)_%)`KV%)`%)aKV%)a%)bKV%)b%)cKV%)c%)d!Js%)d%)e!Ko%)e%)f!Ko%)f%)g!Ko%)g%)h!Js%)h%)i!Js%)i%)j!Js%)j%)k!Js%)k%)l!Js%)l%)mKV%)n%)o!Ko%)o%)p!Ko%)p%)q!Js%)q%)r!Js%)r%)sKV%)s%)tKV%)y%)zKV%)|%)}KV%*O%*PKV%*Q%*RKV%*R%*SKV%*S%*TKV%*T%*UKV%*U%*VKV%*V%*WKV%*W%*XKV%*X%*YKV%*]%*^!Lm%*^%*_!Js%*_%*`!Ko%*f%*g!Js%*g%*h!Js%*h%*i!Js%*i%*j!Js%*k%*l!Js%*l%*m!Js%*m%*n!Js%*n%*o!Js%*o%*pKV%*p%*q!Ko%*q%*r!Js%*r%*sKV%*s%*tKV%*t%*u!Js%*u%*v!Ko%*w%*xKV%*x%*yKV%*y%*zKV%*z%*{KV%*{%*|KV%*|%*}KV%*}%+OKV%+O%+PKV%+P%+QKV%+Q%+RKV%+R%+SKV%+S%+TKV%+T%+UKV%+U%+VKV%+V%+WKV%+W%+XKV%+X%+YKV%+Y%+ZKV%+Z%+[KV%+[%+]KV%+]%+^KV%+^%+_KV%+_%+`KV%+`%+aKV%+a%+bKV%+f%+gKV%+g%+hKV%+h%+iKV%+i%+jKV%+j%+kKV%+k%+lKV%+l%+mKV%+m%+nKV%+n%+oKV%+o%+pKV%+p%+qKV%+q%+rKV%+r%+sKV%+s%+tKV%:y%:z!Js%F[%F]KV%Fb%FcKV%Fc%FdKV%Fk%Fl!Js%Fl%FmKV%Fo%Fp!Js%Fp%Fq!Js%Fq%Fr!Js%G[%G]!La%G]%G^!La%Ga%GbNe%Gb%GcNe%Gc%GdNe%Ge%GfNe%Gf%GgNe%Gg%GhNe%Gh%GiNe%Gi%GjNe%Gj%GkNe%Gk%GlNe%MW%MXNe%MX%MYNe%MY%MZNe%MZ%M[Ne%M[%M]Ne%M]%M^Ne%M^%M_Ne%M_%M`Ne%M`%Ma!La%Ma%Mb!La%Mb%Mc!La%Mc%Md!La%Md%MeNe%Me%MfNe%Mf%MgNe%Mg%MhNe%Mh%MiNe%Mi%MjNe%Mj%Mk!La%Mk%Ml!La%Ml%MmNe%Mm%MnNe%Mn%MoNe%Mo%MpNe%Mp%MqNe%Mu%MvNe%Mv%MwNe%Mw%MxNe%Mx%MyNe%Nn%NoNe%No%NpNe%Np%NqNe%Nq%NrNe%Nr%NsNe%Ns%Nt!La%Nt%NuNe%Nu%NvNe%Nv%Nw!La%Nw%Nx!La%Nx%NyNe%Ny%Nz!La%Nz%N{Ne%N{%N|!La%N|%N}Ne%N}& ONe& O& P!La& P& Q!La& Q& RNe& R& SNe& S& T!La& T& U!La& U& VNe& V& WNe& W& X!La& X& Y!La& Y& ZNe& Z& [Ne& [& ]!La& ]& ^!La& ^& _Ne& _& `!La& `& aNe& a& b!La& b& cNe& c& dNe& d& eNe& e& fNe& f& gNe& g& hNe& h& iNe& i& jNe& j& k!La& k& l!La& l& mNe&#V&#WKV&#W&#X!Js&#[&#]!Js&#^&#_!Js&#_&#`!Js&#`&#aKV&#a&#bKV&$R&$SKV&$T&$UKV&$U&$VKV&$V&$WKV&$f&$gNe&$h&$i!Js&$i&$j!Js&$l&$m!Ko&$m&$n!Ko&$y&$z!Js&$z&${!Ko&%a&%b!Js&%f&%g!Ko&%g&%h!Ko&%h&%i!Ko&%i&%j!Ko&%j&%k!Ko&%k&%l!Ko&%l&%m!Ko&%m&%n!Ko&%n&%o!Ko&%o&%p!Ko&%p&%q!Ko&%q&%r!Ko&%r&%s!Ko&%t&%u!Js&%u&%v!Js&%v&%w!Js&%w&%x!Js&%x&%y!Js&%y&%z!Js&%z&%{!Js&%{&%|!Js&%|&%}!Js&%}&&O!Ko&&O&&P!Ko&&P&&Q!Js&&Q&&R!Js&&R&&S!Js&&U&&V!Js&&V&&W!Ko&&W&&X!Ko&&X&&Y!Js&&Y&&Z!Js&&Z&&[!Ko&&`&&a!Ko&&a&&b!Js&&b&&c!Ko&&c&&d!Js&&d&&e!Js&&e&&f!Ko&&f&&g!Ko&&g&&h!Js&&h&&i!Ko&&i&&j!Js&&j&&k!Ko&&k&&l!Js&&l&&m!Ko&&m&&n!Ko&&n&&o!Js&&p&&q!Js&&q&&r!Ko&&r&&s!Js&&s&&t!Ko&&t&&u!Js&&u&&v!Js&&v&&w!Js&&w&&x!Ko&&x&&y!Ko&&y&&z!Ko&&|&&}KV&&}&'OKV&'Q&'RKV&'R&'SKV&'S&'TKV&'T&'UKV&'U&'VKV&'V&'WKV&'W&'XKV&'X&'YKV&'Y&'ZKV&'Z&'[KV&'[&']LX&']&'^KV&'^&'_KV&'_&'`KV&'`&'aKV&'a&'bKV&'b&'cKV&'c&'dKV&'d&'eKV&'e&'fKV&'f&'gKV&'g&'hKV&'h&'iKV&'i&'jKV&'j&'kKV&'k&'lKV&'l&'mKV&'m&'nKV&'n&'oKV&'o&'pKV&'p&'qKV&'q&'rKV&'r&'sKV&'s&'tKV&'t&'uKV&'u&'vKV&'v&'wKV&'w&'xKV&'x&'yKV&'y&'zKV&'z&'{KV&'{&'|KV&'|&'}KV&'}&(OKV&(O&(PKV&(P&(QKV&(Q&(RKV&(R&(SKV&(S&(TKV&(T&(UKV&(U&(VKV&(V&(WKV&(W&(XKV&(X&(YKV&(Y&(ZKV&(Z&([KV&([&(]KV&(]&(^KV&(^&(_KV&(_&(`KV&(`&(aKV&(a&(bKV&(b&(cKV&(c&(dKV&(d&(eKV&(e&(fKV&(f&(gKV&(g&(hKV&(h&(iKV&(i&(jKV&(j&(kKV&(k&(lKV&(l&(mKV&(m&(nKV&(n&(oKV&(o&(pKV&(p&(qKV&(q&(rKV&(r&(sKV&(s&(tKV&(t&(uKV&(u&(vKV&(v&(wKV&(w&(xKV&(x&(yKV&(y&(zKV&(z&({KV&({&(|KV&(|&(}KV&(}&)OKV&)O&)PKV&)P&)QKV&)Q&)RKV&)R&)SKV&)S&)TKV&)T&)UKV&)U&)VKV&)V&)WKV&)W&)XKV&)X&)YKV&)Y&)ZKV&)Z&)[KV&)[&)]KV&)]&)^KV&)^&)_KV&)_&)`KV&)`&)aKV&)a&)bKV&)b&)cKV&)c&)dKV&)d&)eKV&)e&)fKV&)g&)h!Js&*T&*UKV&*U&*VKV&*V&*WKV&*W&*XKV&+`&+aNe&+a&+bNe&+b&+cNe&+c&+dNe&+d&+eNe&+e&+fNe&+f&+gNe&+g&+hNe&+h&+iNe&+i&+jNe&+j&+kNe&+k&+lNe&+l&+mNe&+m&+nNe&+n&+oNe&+o&+pNe&+p&+qNe&+q&+rNe&+r&+sNe&+s&+tNe&+t&+uNe&+w&+xNe&+x&+yNe&+y&+zNe&+z&+{Ne&+{&+|Ne&+|&+}Ne?MX?MYNe?MY?MZ!La?MZ?M[Ne?M[?M]!La~!GdQ'b~}!ON_!_!`LX~!GmP!O!P!Gp~!GuO(T~~!GzQ'c~!P!Q!HQ!_!`LX~!HTP!_!`LX~!H]Sx~!Q![!HW!g!h!Hi#R#S!HW#X#Y!Hi~!HlR{|!Hu}!O!Hu!Q![!H{~!HxP!Q![!H{~!IQPx~!Q![!H{~!IYS'eP![!]KV!^!_!If!_!`KV#p#q!In~!IkP'^~!_!`LX~!IsO!f~~!IxQ&z~!_!`J}!`!a!JO~!JTO'{~~!JYR'eP![!]!Jc!_!`KV!`!a!Jh~!JhO'_~~!JmQ'^~!_!`LX!`!a!If~!JxO'c~~!J}P'd~!_!`LX~!KVS'b~{|!Kc!_!`!Kt!`!a!Kz#p#q!LP~!KfP{|!Ki~!KlP#p#q!Ko~!KtO'a~~!KwP#p#qLX~!LPO!g~~!LSQ!_!`!Kt#p#q!Ko~!LaO&z~'_~~!LfO'd~~!LmO'eP'a~~!LrP'a~!_!`LX~!LzVx~!O!P!Ma!Q![!Mo!g!h!Hi!z!{!NT#R#S!Mo#X#Y!Hi#l#m!NT~!MfRx~!Q![!HW!g!h!Hi#X#Y!Hi~!MtTx~!O!P!Ma!Q![!Mo!g!h!Hi#R#S!Mo#X#Y!Hi~!NWR!Q![!Na!c!i!Na#T#Z!Na~!NfWx~!Q![!Na!c!g!Na!g!h# O!h!i!Na#R#S!Na#T#X!Na#X#Y# O#Y#Z!Na~# TYx~{|!Hu}!O!Hu!Q![!Na!c!g!Na!g!h# O!h!i!Na#R#S!Na#T#X!Na#X#Y# O#Y#Z!Na~# xQ'R~![!]#!O!_!`LX~#!TO&|~~#!YO&t~~#!_S'eP![!]#!k!^!_!If!_!`KV#p#q!In~#!rO&}~'eP~#!yQ&{~&z~!_!`J}!`!a!JO~##UO'n~~##ZO'S~~##`O'X~~##eO'v~~##jO'Y~~##oS'b~{|!Kc!_!`!Kt!`!a!Kz#p#q##{~#$QQ'|~!_!`!Kt#p#q!Ko~#$]O'Z~R#$dO'yQ'eP", + tokenData: "#%S~R.[XYHwYZHwpqHwqrJursK[stKotuLWuvL]vwLjwxLzxyNWyzN]z{L]{|Nb|}Nj}!ONo!O!P! _!P!Q!He!Q!R!Me!R![!N_![!]#!c!]!^#!s!^!_#!x!_!`##b!`!a!Js!b!c##o!}#O##t#O#P!Kc#P#Q##y#Q#R!Kh#S#T#$O#o#p#$T#p#q#$Y#q#r#$v#r#s!Lx$r$s!KR$w$x!L_%o%p!Kc&a&bL]%!]%!^!Kc%#t%#u! T%#u%#v!MP%#v%#w! T%#w%#x!MP%#x%#y! T%$O%$P! T%$P%$Q! T%$Q%$R! T%$R%$S! T%$S%$T! T%$U%$V! T%$W%$X! T%$X%$Y! T%$Y%$Z! T%$[%$]! T%$_%$`! T%$`%$a! T%$a%$b! T%$b%$c! T%$d%$e! T%$r%$s! T%$s%$t! T%$v%$w! T%$w%$x! T%$z%${! T%$|%$}! T%$}%%O! T%%P%%Q! T%%R%%S! T%%S%%T! T%%T%%U! T%%U%%V! T%%V%%W! T%%W%%X! T%%Y%%Z! T%%[%%]! T%%b%%c! T%%c%%d! T%%d%%e! T%%e%%f! T%%h%%i! T%%j%%k! T%%|%%}! T%%}%&O!MP%&O%&P! T%&P%&Q! T%&Q%&R! T%&R%&S! T%&S%&T! T%&T%&U! T%&U%&V! T%&V%&W! T%&W%&X! T%&X%&Y! T%&b%&c#${%&c%&dKV%&d%&eKV%&e%&fKV%&f%&gKV%&g%&hKV%&m%&n!L_%&n%&o!L_%&q%&r!Kc%&r%&s!Kc%&s%&t!Kc%&t%&u!KR%&u%&v!KR%&v%&w!KR%&w%&xKV%'O%'P!Kc%'P%'QKV%'Q%'RKV%'R%'S!Kc%'S%'T!L_%'T%'U!Kc%'U%'V!L_%'c%'dKV%'d%'e!L_%'f%'gKV%'g%'hKV%'i%'jKV%'j%'kKV%'l%'m!Kc%'m%'nKV%'n%'o!MU%'o%'pKV%'p%'qKV%'q%'rKV%'r%'sKV%'s%'tKV%'t%'uKV%'u%'vKV%'v%'wKV%'w%'xKV%'x%'yKV%'y%'zKV%'z%'{KV%'{%'|!L_%'|%'}KV%'}%(OKV%(O%(PKV%(P%(QKV%(Q%(RLe%(R%(SLe%(S%(TKV%(T%(UKV%(U%(VKV%(V%(WKV%(W%(XKV%(X%(YKV%(Y%(ZKV%(Z%([KV%([%(]KV%(]%(^KV%(^%(_KV%(_%(`KV%(`%(aKV%(a%(bKV%(b%(cKV%(c%(dKV%(d%(eKV%(e%(fKV%(f%(gKV%(g%(hKV%(h%(iKV%(i%(jKV%(j%(kKV%(k%(lKV%(l%(mKV%(m%(nKV%(n%(oKV%(o%(pKV%(p%(qKV%(q%(rKV%(r%(sKV%(s%(tKV%(t%(uKV%(u%(vKV%(v%(wKV%(w%(xKV%(x%(yKV%(y%(zKV%(z%({KV%({%(|KV%(|%(}KV%(}%)OKV%)O%)PKV%)P%)QKV%)Q%)RKV%)R%)SKV%)S%)TKV%)T%)UKV%)U%)VKV%)V%)WKV%)W%)XKV%)X%)YKV%)Y%)ZKV%)Z%)[KV%)]%)^!Kc%)^%)_!L_%)_%)`KV%)`%)aKV%)a%)bKV%)b%)cKV%)c%)d!Kc%)d%)e!L_%)e%)f!L_%)f%)g!L_%)g%)h!Kc%)h%)i!Kc%)i%)j!Kc%)j%)k!Kc%)k%)l!Kc%)l%)mKV%)n%)o!L_%)o%)p!L_%)p%)q!Kc%)q%)r!Kc%)r%)sKV%)s%)tKV%)y%)zKV%)|%)}KV%*O%*PKV%*Q%*RKV%*R%*SKV%*S%*TKV%*T%*UKV%*U%*VKV%*V%*WKV%*W%*XKV%*X%*YKV%*]%*^!M]%*^%*_!Kc%*_%*`!L_%*f%*g!Kc%*g%*h!Kc%*h%*i!Kc%*i%*j!Kc%*k%*l!Kc%*l%*m!Kc%*m%*n!Kc%*n%*o!Kc%*o%*pKV%*p%*q!L_%*q%*r!Kc%*r%*sKV%*s%*tKV%*t%*u!Kc%*u%*v!L_%*w%*xKV%*x%*yKV%*y%*zKV%*z%*{KV%*{%*|KV%*|%*}KV%*}%+OKV%+O%+PKV%+P%+QKV%+Q%+RKV%+R%+SKV%+S%+TKV%+T%+UKV%+U%+VKV%+V%+WKV%+W%+XKV%+X%+YKV%+Y%+ZKV%+Z%+[KV%+[%+]KV%+]%+^KV%+^%+_KV%+_%+`KV%+`%+aKV%+a%+bKV%+f%+gKV%+g%+hKV%+h%+iKV%+i%+jKV%+j%+kKV%+k%+lKV%+l%+mKV%+m%+nKV%+n%+oKV%+o%+pKV%+p%+qKV%+q%+rKV%+r%+sKV%+s%+tKV%:y%:z!Kc%F[%F]KV%Fb%FcKV%Fc%FdKV%Fk%Fl!Kc%Fl%FmKV%Fo%Fp!Kc%Fp%Fq!Kc%Fq%Fr!Kc%G[%G]!MP%G]%G^!MP%Ga%Gb! T%Gb%Gc! T%Gc%Gd! T%Ge%Gf! T%Gf%Gg! T%Gg%Gh! T%Gh%Gi! T%Gi%Gj! T%Gj%Gk! T%Gk%Gl! T%MW%MX! T%MX%MY! T%MY%MZ! T%MZ%M[! T%M[%M]! T%M]%M^! T%M^%M_! T%M_%M`! T%M`%Ma!MP%Ma%Mb!MP%Mb%Mc!MP%Mc%Md!MP%Md%Me! T%Me%Mf! T%Mf%Mg! T%Mg%Mh! T%Mh%Mi! T%Mi%Mj! T%Mj%Mk!MP%Mk%Ml!MP%Ml%Mm! T%Mm%Mn! T%Mn%Mo! T%Mo%Mp! T%Mp%Mq! T%Mu%Mv! T%Mv%Mw! T%Mw%Mx! T%Mx%My! T%Nn%No! T%No%Np! T%Np%Nq! T%Nq%Nr! T%Nr%Ns! T%Ns%Nt!MP%Nt%Nu! T%Nu%Nv! T%Nv%Nw!MP%Nw%Nx!MP%Nx%Ny! T%Ny%Nz!MP%Nz%N{! T%N{%N|!MP%N|%N}! T%N}& O! T& O& P!MP& P& Q!MP& Q& R! T& R& S! T& S& T!MP& T& U!MP& U& V! T& V& W! T& W& X!MP& X& Y!MP& Y& Z! T& Z& [! T& [& ]!MP& ]& ^!MP& ^& _! T& _& `!MP& `& a! T& a& b!MP& b& c! T& c& d! T& d& e! T& e& f! T& f& g! T& g& h! T& h& i! T& i& j! T& j& k!MP& k& l!MP& l& m! T&#V&#WKV&#W&#X!Kc&#[&#]!Kc&#^&#_!Kc&#_&#`!Kc&#`&#aKV&#a&#bKV&$R&$SKV&$T&$UKV&$U&$VKV&$V&$WKV&$f&$g! T&$h&$i!Kc&$i&$j!Kc&$l&$m!L_&$m&$n!L_&$y&$z!Kc&$z&${!L_&%a&%b!Kc&%f&%g!L_&%g&%h!L_&%h&%i!L_&%i&%j!L_&%j&%k!L_&%k&%l!L_&%l&%m!L_&%m&%n!L_&%n&%o!L_&%o&%p!L_&%p&%q!L_&%q&%r!L_&%r&%s!L_&%t&%u!Kc&%u&%v!Kc&%v&%w!Kc&%w&%x!Kc&%x&%y!Kc&%y&%z!Kc&%z&%{!Kc&%{&%|!Kc&%|&%}!Kc&%}&&O!L_&&O&&P!L_&&P&&Q!Kc&&Q&&R!Kc&&R&&S!Kc&&U&&V!Kc&&V&&W!L_&&W&&X!L_&&X&&Y!Kc&&Y&&Z!Kc&&Z&&[!L_&&`&&a!L_&&a&&b!Kc&&b&&c!L_&&c&&d!Kc&&d&&e!Kc&&e&&f!L_&&f&&g!L_&&g&&h!Kc&&h&&i!L_&&i&&j!Kc&&j&&k!L_&&k&&l!Kc&&l&&m!L_&&m&&n!L_&&n&&o!Kc&&p&&q!Kc&&q&&r!L_&&r&&s!Kc&&s&&t!L_&&t&&u!Kc&&u&&v!Kc&&v&&w!Kc&&w&&x!L_&&x&&y!L_&&y&&z!L_&&|&&}KV&&}&'OKV&'Q&'RKV&'R&'SKV&'S&'TKV&'T&'UKV&'U&'VKV&'V&'WKV&'W&'XKV&'X&'YKV&'Y&'ZKV&'Z&'[KV&'[&']Le&']&'^KV&'^&'_KV&'_&'`KV&'`&'aKV&'a&'bKV&'b&'cKV&'c&'dKV&'d&'eKV&'e&'fKV&'f&'gKV&'g&'hKV&'h&'iKV&'i&'jKV&'j&'kKV&'k&'lKV&'l&'mKV&'m&'nKV&'n&'oKV&'o&'pKV&'p&'qKV&'q&'rKV&'r&'sKV&'s&'tKV&'t&'uKV&'u&'vKV&'v&'wKV&'w&'xKV&'x&'yKV&'y&'zKV&'z&'{KV&'{&'|KV&'|&'}KV&'}&(OKV&(O&(PKV&(P&(QKV&(Q&(RKV&(R&(SKV&(S&(TKV&(T&(UKV&(U&(VKV&(V&(WKV&(W&(XKV&(X&(YKV&(Y&(ZKV&(Z&([KV&([&(]KV&(]&(^KV&(^&(_KV&(_&(`KV&(`&(aKV&(a&(bKV&(b&(cKV&(c&(dKV&(d&(eKV&(e&(fKV&(f&(gKV&(g&(hKV&(h&(iKV&(i&(jKV&(j&(kKV&(k&(lKV&(l&(mKV&(m&(nKV&(n&(oKV&(o&(pKV&(p&(qKV&(q&(rKV&(r&(sKV&(s&(tKV&(t&(uKV&(u&(vKV&(v&(wKV&(w&(xKV&(x&(yKV&(y&(zKV&(z&({KV&({&(|KV&(|&(}KV&(}&)OKV&)O&)PKV&)P&)QKV&)Q&)RKV&)R&)SKV&)S&)TKV&)T&)UKV&)U&)VKV&)V&)WKV&)W&)XKV&)X&)YKV&)Y&)ZKV&)Z&)[KV&)[&)]KV&)]&)^KV&)^&)_KV&)_&)`KV&)`&)aKV&)a&)bKV&)b&)cKV&)c&)dKV&)d&)eKV&)e&)fKV&)g&)h!Kc&*T&*UKV&*U&*VKV&*V&*WKV&*W&*XKV&+`&+a! T&+a&+b! T&+b&+c! T&+c&+d! T&+d&+e! T&+e&+f! T&+f&+g! T&+g&+h! T&+h&+i! T&+i&+j! T&+j&+k! T&+k&+l! T&+l&+m! T&+m&+n! T&+n&+o! T&+o&+p! T&+p&+q! T&+q&+r! T&+r&+s! T&+s&+t! T&+t&+u! T&+w&+x! T&+x&+y! T&+y&+z! T&+z&+{! T&+{&+|! T&+|&+}! T?MX?MY! T?MY?MZ!MP?MZ?M[! T?M[?M]!MP~H|T&q~XYI]YZI]pqI]![!]Io!a!bJZ~I`TXYI]YZI]pqI]![!]Io!a!bJZ~IrRXYI{YZI{pqI{~JQR(P~XYI{YZI{pqI{~J^RXYJgYZJgpqJg~JlR(O~XYJgYZJgpqJg~JzP'_~!_!`J}PKSP'eP!_!`KVPK[O'eP~KaP's~rsKd~KgPrsKj~KoO'u~~KtSR~OYKoZ;'SKo;'S;=`LQ<%lOKo~LTP;=`<%lKo~L]O'P~~LbP'c~!_!`Le~LjO&z~~LoQ'c~vwLu!_!`Le~LzO'}~RMPU(RQOwMcx#OMc#O#PMn#P;'SMc;'S;=`NQ<%lOMcPMfPwxMiPMnO#ZPPMqTOwMcwxMix;'SMc;'S;=`NQ<%lOMcPNTP;=`<%lMc~N]O&w~~NbO']~~NgP'b~!_!`Le~NoO'W~~NtR'b~}!ON}!_!`Le!`!a! Y~! QP!`!a! T~! YO'f~~! _O(Q~~! d-w'Q~qrJuuvL]vwL]z{L]{|Nb}!O!G}!O!P!HY!P!Q!He!Q![!Hv!^!_!Is!_!`!Jc!`!a!Js#O#P!Kc#Q#R!Kh#p#q!Kp#r#s!Lx$r$s!KR$w$x!L_%o%p!Kc&a&bL]%!]%!^!Kc%#t%#u! T%#u%#v!MP%#v%#w! T%#w%#x!MP%#x%#y! T%$O%$P! T%$P%$Q! T%$Q%$R! T%$R%$S! T%$S%$T! T%$U%$V! T%$W%$X! T%$X%$Y! T%$Y%$Z! T%$[%$]! T%$_%$`! T%$`%$a! T%$a%$b! T%$b%$c! T%$d%$e! T%$r%$s! T%$s%$t! T%$v%$w! T%$w%$x! T%$z%${! T%$|%$}! T%$}%%O! T%%P%%Q! T%%R%%S! T%%S%%T! T%%T%%U! T%%U%%V! T%%V%%W! T%%W%%X! T%%Y%%Z! T%%[%%]! T%%b%%c! T%%c%%d! T%%d%%e! T%%e%%f! T%%h%%i! T%%j%%k! T%%|%%}! T%%}%&O!MP%&O%&P! T%&P%&Q! T%&Q%&R! T%&R%&S! T%&S%&T! T%&T%&U! T%&U%&V! T%&V%&W! T%&W%&X! T%&X%&Y! T%&b%&cKV%&c%&dKV%&d%&eKV%&e%&fKV%&f%&gKV%&g%&hKV%&m%&n!L_%&n%&o!L_%&q%&r!Kc%&r%&s!Kc%&s%&t!Kc%&t%&u!KR%&u%&v!KR%&v%&w!KR%&w%&xKV%'O%'P!Kc%'P%'QKV%'Q%'RKV%'R%'S!Kc%'S%'T!L_%'T%'U!Kc%'U%'V!L_%'c%'dKV%'d%'e!L_%'f%'gKV%'g%'hKV%'i%'jKV%'j%'kKV%'l%'m!Kc%'m%'nKV%'n%'o!MU%'o%'pKV%'p%'qKV%'q%'rKV%'r%'sKV%'s%'tKV%'t%'uKV%'u%'vKV%'v%'wKV%'w%'xKV%'x%'yKV%'y%'zKV%'z%'{KV%'{%'|!L_%'|%'}KV%'}%(OKV%(O%(PKV%(P%(QKV%(Q%(RLe%(R%(SLe%(S%(TKV%(T%(UKV%(U%(VKV%(V%(WKV%(W%(XKV%(X%(YKV%(Y%(ZKV%(Z%([KV%([%(]KV%(]%(^KV%(^%(_KV%(_%(`KV%(`%(aKV%(a%(bKV%(b%(cKV%(c%(dKV%(d%(eKV%(e%(fKV%(f%(gKV%(g%(hKV%(h%(iKV%(i%(jKV%(j%(kKV%(k%(lKV%(l%(mKV%(m%(nKV%(n%(oKV%(o%(pKV%(p%(qKV%(q%(rKV%(r%(sKV%(s%(tKV%(t%(uKV%(u%(vKV%(v%(wKV%(w%(xKV%(x%(yKV%(y%(zKV%(z%({KV%({%(|KV%(|%(}KV%(}%)OKV%)O%)PKV%)P%)QKV%)Q%)RKV%)R%)SKV%)S%)TKV%)T%)UKV%)U%)VKV%)V%)WKV%)W%)XKV%)X%)YKV%)Y%)ZKV%)Z%)[KV%)]%)^!Kc%)^%)_!L_%)_%)`KV%)`%)aKV%)a%)bKV%)b%)cKV%)c%)d!Kc%)d%)e!L_%)e%)f!L_%)f%)g!L_%)g%)h!Kc%)h%)i!Kc%)i%)j!Kc%)j%)k!Kc%)k%)l!Kc%)l%)mKV%)n%)o!L_%)o%)p!L_%)p%)q!Kc%)q%)r!Kc%)r%)sKV%)s%)tKV%)y%)zKV%)|%)}KV%*O%*PKV%*Q%*RKV%*R%*SKV%*S%*TKV%*T%*UKV%*U%*VKV%*V%*WKV%*W%*XKV%*X%*YKV%*]%*^!M]%*^%*_!Kc%*_%*`!L_%*f%*g!Kc%*g%*h!Kc%*h%*i!Kc%*i%*j!Kc%*k%*l!Kc%*l%*m!Kc%*m%*n!Kc%*n%*o!Kc%*o%*pKV%*p%*q!L_%*q%*r!Kc%*r%*sKV%*s%*tKV%*t%*u!Kc%*u%*v!L_%*w%*xKV%*x%*yKV%*y%*zKV%*z%*{KV%*{%*|KV%*|%*}KV%*}%+OKV%+O%+PKV%+P%+QKV%+Q%+RKV%+R%+SKV%+S%+TKV%+T%+UKV%+U%+VKV%+V%+WKV%+W%+XKV%+X%+YKV%+Y%+ZKV%+Z%+[KV%+[%+]KV%+]%+^KV%+^%+_KV%+_%+`KV%+`%+aKV%+a%+bKV%+f%+gKV%+g%+hKV%+h%+iKV%+i%+jKV%+j%+kKV%+k%+lKV%+l%+mKV%+m%+nKV%+n%+oKV%+o%+pKV%+p%+qKV%+q%+rKV%+r%+sKV%+s%+tKV%:y%:z!Kc%F[%F]KV%Fb%FcKV%Fc%FdKV%Fk%Fl!Kc%Fl%FmKV%Fo%Fp!Kc%Fp%Fq!Kc%Fq%Fr!Kc%G[%G]!MP%G]%G^!MP%Ga%Gb! T%Gb%Gc! T%Gc%Gd! T%Ge%Gf! T%Gf%Gg! T%Gg%Gh! T%Gh%Gi! T%Gi%Gj! T%Gj%Gk! T%Gk%Gl! T%MW%MX! T%MX%MY! T%MY%MZ! T%MZ%M[! T%M[%M]! T%M]%M^! T%M^%M_! T%M_%M`! T%M`%Ma!MP%Ma%Mb!MP%Mb%Mc!MP%Mc%Md!MP%Md%Me! T%Me%Mf! T%Mf%Mg! T%Mg%Mh! T%Mh%Mi! T%Mi%Mj! T%Mj%Mk!MP%Mk%Ml!MP%Ml%Mm! T%Mm%Mn! T%Mn%Mo! T%Mo%Mp! T%Mp%Mq! T%Mu%Mv! T%Mv%Mw! T%Mw%Mx! T%Mx%My! T%Nn%No! T%No%Np! T%Np%Nq! T%Nq%Nr! T%Nr%Ns! T%Ns%Nt!MP%Nt%Nu! T%Nu%Nv! T%Nv%Nw!MP%Nw%Nx!MP%Nx%Ny! T%Ny%Nz!MP%Nz%N{! T%N{%N|!MP%N|%N}! T%N}& O! T& O& P!MP& P& Q!MP& Q& R! T& R& S! T& S& T!MP& T& U!MP& U& V! T& V& W! T& W& X!MP& X& Y!MP& Y& Z! T& Z& [! T& [& ]!MP& ]& ^!MP& ^& _! T& _& `!MP& `& a! T& a& b!MP& b& c! T& c& d! T& d& e! T& e& f! T& f& g! T& g& h! T& h& i! T& i& j! T& j& k!MP& k& l!MP& l& m! T&#V&#WKV&#W&#X!Kc&#[&#]!Kc&#^&#_!Kc&#_&#`!Kc&#`&#aKV&#a&#bKV&$R&$SKV&$T&$UKV&$U&$VKV&$V&$WKV&$f&$g! T&$h&$i!Kc&$i&$j!Kc&$l&$m!L_&$m&$n!L_&$y&$z!Kc&$z&${!L_&%a&%b!Kc&%f&%g!L_&%g&%h!L_&%h&%i!L_&%i&%j!L_&%j&%k!L_&%k&%l!L_&%l&%m!L_&%m&%n!L_&%n&%o!L_&%o&%p!L_&%p&%q!L_&%q&%r!L_&%r&%s!L_&%t&%u!Kc&%u&%v!Kc&%v&%w!Kc&%w&%x!Kc&%x&%y!Kc&%y&%z!Kc&%z&%{!Kc&%{&%|!Kc&%|&%}!Kc&%}&&O!L_&&O&&P!L_&&P&&Q!Kc&&Q&&R!Kc&&R&&S!Kc&&U&&V!Kc&&V&&W!L_&&W&&X!L_&&X&&Y!Kc&&Y&&Z!Kc&&Z&&[!L_&&`&&a!L_&&a&&b!Kc&&b&&c!L_&&c&&d!Kc&&d&&e!Kc&&e&&f!L_&&f&&g!L_&&g&&h!Kc&&h&&i!L_&&i&&j!Kc&&j&&k!L_&&k&&l!Kc&&l&&m!L_&&m&&n!L_&&n&&o!Kc&&p&&q!Kc&&q&&r!L_&&r&&s!Kc&&s&&t!L_&&t&&u!Kc&&u&&v!Kc&&v&&w!Kc&&w&&x!L_&&x&&y!L_&&y&&z!L_&&|&&}KV&&}&'OKV&'Q&'RKV&'R&'SKV&'S&'TKV&'T&'UKV&'U&'VKV&'V&'WKV&'W&'XKV&'X&'YKV&'Y&'ZKV&'Z&'[KV&'[&']Le&']&'^KV&'^&'_KV&'_&'`KV&'`&'aKV&'a&'bKV&'b&'cKV&'c&'dKV&'d&'eKV&'e&'fKV&'f&'gKV&'g&'hKV&'h&'iKV&'i&'jKV&'j&'kKV&'k&'lKV&'l&'mKV&'m&'nKV&'n&'oKV&'o&'pKV&'p&'qKV&'q&'rKV&'r&'sKV&'s&'tKV&'t&'uKV&'u&'vKV&'v&'wKV&'w&'xKV&'x&'yKV&'y&'zKV&'z&'{KV&'{&'|KV&'|&'}KV&'}&(OKV&(O&(PKV&(P&(QKV&(Q&(RKV&(R&(SKV&(S&(TKV&(T&(UKV&(U&(VKV&(V&(WKV&(W&(XKV&(X&(YKV&(Y&(ZKV&(Z&([KV&([&(]KV&(]&(^KV&(^&(_KV&(_&(`KV&(`&(aKV&(a&(bKV&(b&(cKV&(c&(dKV&(d&(eKV&(e&(fKV&(f&(gKV&(g&(hKV&(h&(iKV&(i&(jKV&(j&(kKV&(k&(lKV&(l&(mKV&(m&(nKV&(n&(oKV&(o&(pKV&(p&(qKV&(q&(rKV&(r&(sKV&(s&(tKV&(t&(uKV&(u&(vKV&(v&(wKV&(w&(xKV&(x&(yKV&(y&(zKV&(z&({KV&({&(|KV&(|&(}KV&(}&)OKV&)O&)PKV&)P&)QKV&)Q&)RKV&)R&)SKV&)S&)TKV&)T&)UKV&)U&)VKV&)V&)WKV&)W&)XKV&)X&)YKV&)Y&)ZKV&)Z&)[KV&)[&)]KV&)]&)^KV&)^&)_KV&)_&)`KV&)`&)aKV&)a&)bKV&)b&)cKV&)c&)dKV&)d&)eKV&)e&)fKV&)g&)h!Kc&*T&*UKV&*U&*VKV&*V&*WKV&*W&*XKV&+`&+a! T&+a&+b! T&+b&+c! T&+c&+d! T&+d&+e! T&+e&+f! T&+f&+g! T&+g&+h! T&+h&+i! T&+i&+j! T&+j&+k! T&+k&+l! T&+l&+m! T&+m&+n! T&+n&+o! T&+o&+p! T&+p&+q! T&+q&+r! T&+r&+s! T&+s&+t! T&+t&+u! T&+w&+x! T&+x&+y! T&+y&+z! T&+z&+{! T&+{&+|! T&+|&+}! T?MX?MY! T?MY?MZ!MP?MZ?M[! T?M[?M]!MP~!HSQ'b~}!ON}!_!`Le~!H]P!O!P!H`~!HeO(T~~!HjQ'c~!P!Q!Hp!_!`Le~!HsP!_!`Le~!H{Sx~!Q![!Hv!g!h!IX#R#S!Hv#X#Y!IX~!I[R{|!Ie}!O!Ie!Q![!Ik~!IhP!Q![!Ik~!IpPx~!Q![!Ik~!IxS'eP![!]KV!^!_!JU!_!`KV#p#q!J^~!JZP'^~!_!`Le~!JcO!f~~!JhQ&z~!_!`J}!`!a!Jn~!JsO'{~~!JxR'eP![!]!KR!_!`KV!`!a!KW~!KWO'_~~!K]Q'^~!_!`Le!`!a!JU~!KhO'c~~!KmP'd~!_!`Le~!KuS'b~{|!LR!_!`!Ld!`!a!Lj#p#q!Lo~!LUP{|!LX~!L[P#p#q!L_~!LdO'a~~!LgP#p#qLe~!LoO!g~~!LrQ!_!`!Ld#p#q!L_~!MPO&z~'_~~!MUO'd~~!M]O'eP'a~~!MbP'a~!_!`Le~!MjVx~!O!P!NP!Q![!N_!g!h!IX!z!{!Ns#R#S!N_#X#Y!IX#l#m!Ns~!NURx~!Q![!Hv!g!h!IX#X#Y!IX~!NdTx~!O!P!NP!Q![!N_!g!h!IX#R#S!N_#X#Y!IX~!NvR!Q![# P!c!i# P#T#Z# P~# UWx~!Q![# P!c!g# P!g!h# n!h!i# P#R#S# P#T#X# P#X#Y# n#Y#Z# P~# sYx~{|!Ie}!O!Ie!Q![# P!c!g# P!g!h# n!h!i# P#R#S# P#T#X# P#X#Y# n#Y#Z# P~#!hQ'R~![!]#!n!_!`Le~#!sO&|~~#!xO&t~~#!}S'eP![!]##Z!^!_!JU!_!`KV#p#q!J^~##bO&}~'eP~##iQ&{~&z~!_!`J}!`!a!Jn~##tO'n~~##yO'S~~#$OO'X~~#$TO'v~~#$YO'Y~~#$_S'b~{|!LR!_!`!Ld!`!a!Lj#p#q#$k~#$pQ'|~!_!`!Ld#p#q!L_~#${O'Z~R#%SO'yQ'eP", tokenizers: [layoutExtra, newline$3, word, Identifier$2, BlockComment$2, tripleStringContent, stringContent, commandStringContent, tripleStringContentWithoutInterpolation, stringContentWithoutInterpolation, commandStringContentWithoutInterpolation, 0, 1], topRules: {"SourceFile":[0,4]}, dynamicPrecedences: {"30":2,"33":2,"95":10,"143":5,"189":1,"204":5,"207":2,"302":1,"304":1,"305":10,"308":1,"318":1,"326":1,"328":10,"329":10,"331":1}, @@ -7880,8 +8023,7 @@ var base = { 219: "[", 220: "\\", 221: "]", - 222: "'", - 229: "q" + 222: "'" }; var shift = { @@ -7908,16 +8050,14 @@ var shift = { 219: "{", 220: "|", 221: "}", - 222: "\"", - 229: "Q" + 222: "\"" }; var chrome$1 = typeof navigator != "undefined" && /Chrome\/(\d+)/.exec(navigator.userAgent); -var safari$1 = typeof navigator != "undefined" && /Apple Computer/.test(navigator.vendor); -var gecko$1 = typeof navigator != "undefined" && /Gecko\/\d+/.test(navigator.userAgent); +typeof navigator != "undefined" && /Gecko\/\d+/.test(navigator.userAgent); var mac = typeof navigator != "undefined" && /Mac/.test(navigator.platform); var ie$1 = typeof navigator != "undefined" && /MSIE \d|Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(navigator.userAgent); -var brokenModifierNames = chrome$1 && (mac || +chrome$1[1] < 57) || gecko$1 && mac; +var brokenModifierNames = mac || chrome$1 && +chrome$1[1] < 57; // Fill in the digit keys for (var i = 0; i < 10; i++) base[48 + i] = base[96 + i] = String(i); @@ -7935,10 +8075,9 @@ for (var i = 65; i <= 90; i++) { for (var code in base) if (!shift.hasOwnProperty(code)) shift[code] = base[code]; function keyName(event) { - // Don't trust event.key in Chrome when there are modifiers until - // they fix https://bugs.chromium.org/p/chromium/issues/detail?id=633838 var ignoreKey = brokenModifierNames && (event.ctrlKey || event.altKey || event.metaKey) || - (safari$1 || ie$1) && event.shiftKey && event.key && event.key.length == 1; + ie$1 && event.shiftKey && event.key && event.key.length == 1 || + event.key == "Unidentified"; var name = (!ignoreKey && event.key) || (event.shiftKey ? shift : base)[event.keyCode] || event.key || "Unidentified"; @@ -7969,8 +8108,8 @@ function getSelection(root) { function contains(dom, node) { return node ? dom == node || dom.contains(node.nodeType != 1 ? node.parentNode : node) : false; } -function deepActiveElement() { - let elt = document.activeElement; +function deepActiveElement(doc) { + let elt = doc.activeElement; while (elt && elt.shadowRoot) elt = elt.shadowRoot.activeElement; return elt; @@ -8047,7 +8186,7 @@ function windowRect(win) { top: 0, bottom: win.innerHeight }; } function scrollRectIntoView(dom, rect, side, x, y, xMargin, yMargin, ltr) { - let doc = dom.ownerDocument, win = doc.defaultView; + let doc = dom.ownerDocument, win = doc.defaultView || window; for (let cur = dom; cur;) { if (cur.nodeType == 1) { // Element let bounding, top = cur == doc.body; @@ -8056,7 +8195,7 @@ function scrollRectIntoView(dom, rect, side, x, y, xMargin, yMargin, ltr) { } else { if (cur.scrollHeight <= cur.clientHeight && cur.scrollWidth <= cur.clientWidth) { - cur = cur.parentNode; + cur = cur.assignedSlot || cur.parentNode; continue; } let rect = cur.getBoundingClientRect(); @@ -8107,24 +8246,28 @@ function scrollRectIntoView(dom, rect, side, x, y, xMargin, yMargin, ltr) { win.scrollBy(moveX, moveY); } else { + let movedX = 0, movedY = 0; if (moveY) { let start = cur.scrollTop; cur.scrollTop += moveY; - moveY = cur.scrollTop - start; + movedY = cur.scrollTop - start; } if (moveX) { let start = cur.scrollLeft; cur.scrollLeft += moveX; - moveX = cur.scrollLeft - start; + movedX = cur.scrollLeft - start; } - rect = { left: rect.left - moveX, top: rect.top - moveY, - right: rect.right - moveX, bottom: rect.bottom - moveY }; + rect = { left: rect.left - movedX, top: rect.top - movedY, + right: rect.right - movedX, bottom: rect.bottom - movedY }; + if (movedX && Math.abs(movedX - moveX) < 1) + x = "nearest"; + if (movedY && Math.abs(movedY - moveY) < 1) + y = "nearest"; } } if (top) break; cur = cur.assignedSlot || cur.parentNode; - x = y = "nearest"; } else if (cur.nodeType == 11) { // A shadow root cur = cur.host; @@ -8215,6 +8358,31 @@ function clearAttributes(node) { while (node.attributes.length) node.removeAttributeNode(node.attributes[0]); } +function atElementStart(doc, selection) { + let node = selection.focusNode, offset = selection.focusOffset; + if (!node || selection.anchorNode != node || selection.anchorOffset != offset) + return false; + for (;;) { + if (offset) { + if (node.nodeType != 1) + return false; + let prev = node.childNodes[offset - 1]; + if (prev.contentEditable == "false") + offset--; + else { + node = prev; + offset = maxOffset(node); + } + } + else if (node == doc) { + return true; + } + else { + offset = domIndex(node); + node = node.parentNode; + } + } +} class DOMPos { constructor(node, offset, precise = true) { @@ -8230,7 +8398,7 @@ class ContentView { constructor() { this.parent = null; this.dom = null; - this.dirty = 2 /* Node */; + this.dirty = 2 /* Dirty.Node */; } get editorView() { if (!this.parent) @@ -8261,18 +8429,18 @@ class ContentView { // given position. coordsAt(_pos, _side) { return null; } sync(track) { - if (this.dirty & 2 /* Node */) { + if (this.dirty & 2 /* Dirty.Node */) { let parent = this.dom; let prev = null, next; for (let child of this.children) { if (child.dirty) { if (!child.dom && (next = prev ? prev.nextSibling : parent.firstChild)) { let contentView = ContentView.get(next); - if (!contentView || !contentView.parent && contentView.constructor == child.constructor) + if (!contentView || !contentView.parent && contentView.canReuseDOM(child)) child.reuseDOM(next); } child.sync(track); - child.dirty = 0 /* Not */; + child.dirty = 0 /* Dirty.Not */; } next = prev ? prev.nextSibling : parent.firstChild; if (track && !track.written && track.node == parent && next != child.dom) @@ -8292,11 +8460,11 @@ class ContentView { while (next) next = rm$1(next); } - else if (this.dirty & 1 /* Child */) { + else if (this.dirty & 1 /* Dirty.Child */) { for (let child of this.children) if (child.dirty) { child.sync(track); - child.dirty = 0 /* Not */; + child.dirty = 0 /* Dirty.Not */; } } } @@ -8361,16 +8529,16 @@ class ContentView { endDOM: toI < this.children.length && toI >= 0 ? this.children[toI].dom : null }; } markDirty(andParent = false) { - this.dirty |= 2 /* Node */; + this.dirty |= 2 /* Dirty.Node */; this.markParentsDirty(andParent); } markParentsDirty(childList) { for (let parent = this.parent; parent; parent = parent.parent) { if (childList) - parent.dirty |= 2 /* Node */; - if (parent.dirty & 1 /* Child */) + parent.dirty |= 2 /* Dirty.Node */; + if (parent.dirty & 1 /* Dirty.Child */) return; - parent.dirty |= 1 /* Child */; + parent.dirty |= 1 /* Dirty.Child */; childList = false; } } @@ -8426,6 +8594,7 @@ class ContentView { return false; } become(other) { return false; } + canReuseDOM(other) { return other.constructor == this.constructor; } // When this is a zero-length view with a side, this should return a // number <= 0 to indicate it is before its position, or a // number > 0 when after its position. @@ -8646,13 +8815,13 @@ class MarkView extends ContentView { reuseDOM(node) { if (node.nodeName == this.mark.tagName.toUpperCase()) { this.setDOM(node); - this.dirty |= 4 /* Attrs */ | 2 /* Node */; + this.dirty |= 4 /* Dirty.Attrs */ | 2 /* Dirty.Node */; } } sync(track) { if (!this.dom) this.setDOM(this.setAttrs(document.createElement(this.mark.tagName))); - else if (this.dirty & 4 /* Attrs */) + else if (this.dirty & 4 /* Dirty.Attrs */) this.setAttrs(this.dom); super.sync(track); } @@ -8684,7 +8853,7 @@ class MarkView extends ContentView { return new MarkView(this.mark, result, length); } domAtPos(pos) { - return inlineDOMAtPos(this.dom, this.children, pos); + return inlineDOMAtPos(this, pos); } coordsAt(pos, side) { return coordsInChildren(this, pos, side); @@ -8701,7 +8870,7 @@ function textCoords(text, pos, side) { from--; flatten = 1; } // FIXME this is wrong in RTL text - else { + else if (to < length) { to++; flatten = -1; } @@ -8710,7 +8879,7 @@ function textCoords(text, pos, side) { else { if (side < 0) from--; - else + else if (to < length) to++; } let rects = textRange(text, from, to).getClientRects(); @@ -8792,7 +8961,7 @@ class WidgetView extends ContentView { if (pos > 0 ? i == 0 : i == rects.length - 1 || rect.top < rect.bottom) break; } - return (pos == 0 && side > 0 || pos == this.length && side <= 0) ? rect : flattenRect(rect, pos == 0); + return this.length ? rect : flattenRect(rect, this.side > 0); } get isEditable() { return false; } destroy() { @@ -8829,17 +8998,21 @@ class CompositionView extends WidgetView { (_a = this.widget.topView) === null || _a === void 0 ? void 0 : _a.destroy(); } get isEditable() { return true; } + canReuseDOM() { return true; } } // Uses the old structure of a chunk of content view frozen for // composition to try and find a reasonable DOM location for the given // offset. function scanCompositionTree(pos, side, view, text, enterView, fromText) { if (view instanceof MarkView) { - for (let child of view.children) { - let hasComp = contains(child.dom, text); - let len = hasComp ? text.nodeValue.length : child.length; - if (pos < len || pos == len && child.getSide() <= 0) - return hasComp ? scanCompositionTree(pos, side, child, text, enterView, fromText) : enterView(child, pos, side); + for (let child = view.dom.firstChild; child; child = child.nextSibling) { + let desc = ContentView.get(child); + if (!desc) + return fromText(pos, side); + let hasComp = contains(child, text); + let len = desc.length + (hasComp ? text.nodeValue.length : 0); + if (pos < len || pos == len && desc.getSide() <= 0) + return hasComp ? scanCompositionTree(pos, side, desc, text, enterView, fromText) : enterView(desc, pos, side); pos -= len; } return enterView(view, view.length, -1); @@ -8929,8 +9102,8 @@ function inlineSiblingRect(view, side) { } return undefined; } -function inlineDOMAtPos(dom, children, pos) { - let i = 0; +function inlineDOMAtPos(parent, pos) { + let dom = parent.dom, { children } = parent, i = 0; for (let off = 0; i < children.length; i++) { let child = children[i], end = off + child.length; if (end == off && child.getSide() <= 0) @@ -8941,10 +9114,15 @@ function inlineDOMAtPos(dom, children, pos) { break; off = end; } - for (; i > 0; i--) { - let before = children[i - 1].dom; - if (before.parentNode == dom) - return DOMPos.after(before); + for (let j = i; j > 0; j--) { + let prev = children[j - 1]; + if (prev.dom.parentNode == dom) + return prev.domAtPos(prev.length); + } + for (let j = i; j < children.length; j++) { + let next = children[j]; + if (next.dom.parentNode == dom) + return next.domAtPos(0); } return new DOMPos(dom, 0); } @@ -8962,21 +9140,33 @@ function joinInlineInto(parent, view, open) { parent.length += view.length; } function coordsInChildren(view, pos, side) { - for (let off = 0, i = 0; i < view.children.length; i++) { - let child = view.children[i], end = off + child.length, next; - if ((side <= 0 || end == view.length || child.getSide() > 0 ? end >= pos : end > pos) && - (pos < end || i + 1 == view.children.length || (next = view.children[i + 1]).length || next.getSide() > 0)) { - let flatten = 0; - if (end == off) { - if (child.getSide() <= 0) - continue; - flatten = side = -child.getSide(); + let before = null, beforePos = -1, after = null, afterPos = -1; + function scan(view, pos) { + for (let i = 0, off = 0; i < view.children.length && off <= pos; i++) { + let child = view.children[i], end = off + child.length; + if (end >= pos) { + if (child.children.length) { + scan(child, pos - off); + } + else if (!after && (end > pos || off == end && child.getSide() > 0)) { + after = child; + afterPos = pos - off; + } + else if (off < pos || (off == end && child.getSide() < 0)) { + before = child; + beforePos = pos - off; + } } - let rect = child.coordsAt(Math.max(0, pos - off), side); - return flatten && rect ? flattenRect(rect, side < 0) : rect; + off = end; } - off = end; } + scan(view, pos); + let target = (side < 0 ? before : after) || before || after; + if (target) + return target.coordsAt(Math.max(0, target == before ? beforePos : afterPos), side); + return fallbackRect(view); +} +function fallbackRect(view) { let last = view.dom.lastChild; if (!last) return view.dom.getBoundingClientRect(); @@ -9010,14 +9200,16 @@ function attrsEq(a, b) { return true; } function updateAttrs(dom, prev, attrs) { + let changed = null; if (prev) for (let name in prev) if (!(attrs && name in attrs)) - dom.removeAttribute(name); + dom.removeAttribute(changed = name); if (attrs) for (let name in attrs) if (!(prev && prev[name] == attrs[name])) - dom.setAttribute(name, attrs[name]); + dom.setAttribute(changed = name, attrs[name]); + return !!changed; } /** @@ -9150,7 +9342,7 @@ class Decoration extends RangeValue { */ static widget(spec) { let side = spec.side || 0, block = !!spec.block; - side += block ? (side > 0 ? 300000000 /* BlockAfter */ : -400000000 /* BlockBefore */) : (side > 0 ? 100000000 /* InlineAfter */ : -100000000 /* InlineBefore */); + side += block ? (side > 0 ? 300000000 /* Side.BlockAfter */ : -400000000 /* Side.BlockBefore */) : (side > 0 ? 100000000 /* Side.InlineAfter */ : -100000000 /* Side.InlineBefore */); return new PointDecoration(spec, side, side, block, spec.widget || null, false); } /** @@ -9160,13 +9352,13 @@ class Decoration extends RangeValue { static replace(spec) { let block = !!spec.block, startSide, endSide; if (spec.isBlockGap) { - startSide = -500000000 /* GapStart */; - endSide = 400000000 /* GapEnd */; + startSide = -500000000 /* Side.GapStart */; + endSide = 400000000 /* Side.GapEnd */; } else { let { start, end } = getInclusive(spec, block); - startSide = (start ? (block ? -300000000 /* BlockIncStart */ : -1 /* InlineIncStart */) : 500000000 /* NonIncStart */) - 1; - endSide = (end ? (block ? 200000000 /* BlockIncEnd */ : 1 /* InlineIncEnd */) : -600000000 /* NonIncEnd */) + 1; + startSide = (start ? (block ? -300000000 /* Side.BlockIncStart */ : -1 /* Side.InlineIncStart */) : 500000000 /* Side.NonIncStart */) - 1; + endSide = (end ? (block ? 200000000 /* Side.BlockIncEnd */ : 1 /* Side.InlineIncEnd */) : -600000000 /* Side.NonIncEnd */) + 1; } return new PointDecoration(spec, startSide, endSide, block, spec.widget || null, true); } @@ -9197,7 +9389,7 @@ Decoration.none = RangeSet.empty; class MarkDecoration extends Decoration { constructor(spec) { let { start, end } = getInclusive(spec); - super(start ? -1 /* InlineIncStart */ : 500000000 /* NonIncStart */, end ? 1 /* InlineIncEnd */ : -600000000 /* NonIncEnd */, null, spec); + super(start ? -1 /* Side.InlineIncStart */ : 500000000 /* Side.NonIncStart */, end ? 1 /* Side.InlineIncEnd */ : -600000000 /* Side.NonIncEnd */, null, spec); this.tagName = spec.tagName || "span"; this.class = spec.class || ""; this.attrs = spec.attributes || null; @@ -9218,7 +9410,7 @@ class MarkDecoration extends Decoration { MarkDecoration.prototype.point = false; class LineDecoration extends Decoration { constructor(spec) { - super(-200000000 /* Line */, -200000000 /* Line */, null, spec); + super(-200000000 /* Side.Line */, -200000000 /* Side.Line */, null, spec); } eq(other) { return other instanceof LineDecoration && attrsEq(this.spec.attributes, other.spec.attributes); @@ -9323,6 +9515,7 @@ class LineView extends ContentView { transferDOM(other) { if (!this.dom) return; + this.markDirty(); other.setDOM(this.dom); other.prevAttrs = this.prevAttrs === undefined ? this.attrs : this.prevAttrs; this.prevAttrs = undefined; @@ -9349,12 +9542,12 @@ class LineView extends ContentView { this.attrs = combineAttrs({ class: cls }, this.attrs || {}); } domAtPos(pos) { - return inlineDOMAtPos(this.dom, this.children, pos); + return inlineDOMAtPos(this, pos); } reuseDOM(node) { if (node.nodeName == "DIV") { this.setDOM(node); - this.dirty |= 4 /* Attrs */ | 2 /* Node */; + this.dirty |= 4 /* Dirty.Attrs */ | 2 /* Dirty.Node */; } } sync(track) { @@ -9364,7 +9557,7 @@ class LineView extends ContentView { this.dom.className = "cm-line"; this.prevAttrs = this.attrs ? null : undefined; } - else if (this.dirty & 4 /* Attrs */) { + else if (this.dirty & 4 /* Dirty.Attrs */) { clearAttributes(this.dom); this.dom.className = "cm-line"; this.prevAttrs = this.attrs ? null : undefined; @@ -9391,15 +9584,17 @@ class LineView extends ContentView { return null; let totalWidth = 0; for (let child of this.children) { - if (!(child instanceof TextView)) + if (!(child instanceof TextView) || /[^ -~]/.test(child.text)) return null; let rects = clientRectsFor(child.dom); if (rects.length != 1) return null; totalWidth += rects[0].width; } - return { lineHeight: this.dom.getBoundingClientRect().height, - charWidth: totalWidth / this.length }; + return !totalWidth ? null : { + lineHeight: this.dom.getBoundingClientRect().height, + charWidth: totalWidth / this.length + }; } coordsAt(pos, side) { return coordsInChildren(this, pos, side); @@ -9492,7 +9687,7 @@ class ContentBuilder { this.content = []; this.curLine = null; this.breakAtStart = 0; - this.pendingBuffer = 0 /* No */; + this.pendingBuffer = 0 /* Buf.No */; // Set to false directly after a widget that covers the position after it this.atCursorPos = true; this.openStart = -1; @@ -9518,7 +9713,7 @@ class ContentBuilder { flushBuffer(active) { if (this.pendingBuffer) { this.curLine.append(wrapMarks(new WidgetBufferView(-1), active), active.length); - this.pendingBuffer = 0 /* No */; + this.pendingBuffer = 0 /* Buf.No */; } } addBlockWidget(view) { @@ -9530,7 +9725,7 @@ class ContentBuilder { if (!openEnd) this.flushBuffer([]); else - this.pendingBuffer = 0 /* No */; + this.pendingBuffer = 0 /* Buf.No */; if (!this.posCovered()) this.getLine(); } @@ -9558,7 +9753,7 @@ class ContentBuilder { this.textOff = 0; } } - let take = Math.min(this.text.length - this.textOff, length, 512 /* Chunk */); + let take = Math.min(this.text.length - this.textOff, length, 512 /* T.Chunk */); this.flushBuffer(active.slice(0, openStart)); this.getLine().append(wrapMarks(new TextView(this.text.slice(this.textOff, this.textOff + take)), active), openStart); this.atCursorPos = true; @@ -9589,12 +9784,12 @@ class ContentBuilder { this.addBlockWidget(new BlockWidgetView(deco.widget || new NullWidget("div"), len, type)); } else { - let view = WidgetView.create(deco.widget || new NullWidget("span"), len, deco.startSide); + let view = WidgetView.create(deco.widget || new NullWidget("span"), len, len ? 0 : deco.startSide); let cursorBefore = this.atCursorPos && !view.isEditable && openStart <= active.length && (from < to || deco.startSide > 0); let cursorAfter = !view.isEditable && (from < to || deco.startSide <= 0); let line = this.getLine(); - if (this.pendingBuffer == 2 /* IfCursor */ && !cursorBefore) - this.pendingBuffer = 0 /* No */; + if (this.pendingBuffer == 2 /* Buf.IfCursor */ && !cursorBefore) + this.pendingBuffer = 0 /* Buf.No */; this.flushBuffer(active); if (cursorBefore) { line.append(wrapMarks(new WidgetBufferView(1), active), openStart); @@ -9602,7 +9797,7 @@ class ContentBuilder { } line.append(wrapMarks(view, active), openStart); this.atCursorPos = cursorAfter; - this.pendingBuffer = !cursorAfter ? 0 /* No */ : from < to ? 1 /* Yes */ : 2 /* IfCursor */; + this.pendingBuffer = !cursorAfter ? 0 /* Buf.No */ : from < to ? 1 /* Buf.Yes */ : 2 /* Buf.IfCursor */; } } else if (this.doc.lineAt(this.pos).from == this.pos) { // Line decoration @@ -9656,6 +9851,9 @@ const inputHandler$1 = /*@__PURE__*/Facet.define(); const perLineTextDirection = /*@__PURE__*/Facet.define({ combine: values => values.some(x => x) }); +const nativeSelectionHidden = /*@__PURE__*/Facet.define({ + combine: values => values.some(x => x) +}); class ScrollTarget { constructor(range, y = "nearest", x = "nearest", yMargin = 5, xMargin = 5) { this.range = range; @@ -9895,7 +10093,7 @@ class ViewUpdate { let focus = view.hasFocus; if (focus != view.inputState.notifiedFocused) { view.inputState.notifiedFocused = focus; - this.flags |= 1 /* Focus */; + this.flags |= 1 /* UpdateFlag.Focus */; } } /** @@ -9910,27 +10108,27 @@ class ViewUpdate { update. */ get viewportChanged() { - return (this.flags & 4 /* Viewport */) > 0; + return (this.flags & 4 /* UpdateFlag.Viewport */) > 0; } /** Indicates whether the height of a block element in the editor changed in this update. */ get heightChanged() { - return (this.flags & 2 /* Height */) > 0; + return (this.flags & 2 /* UpdateFlag.Height */) > 0; } /** Returns true when the document was modified or the size of the editor, or elements within the editor, changed. */ get geometryChanged() { - return this.docChanged || (this.flags & (8 /* Geometry */ | 2 /* Height */)) > 0; + return this.docChanged || (this.flags & (8 /* UpdateFlag.Geometry */ | 2 /* UpdateFlag.Height */)) > 0; } /** True when this update indicates a focus change. */ get focusChanged() { - return (this.flags & 1 /* Focus */) > 0; + return (this.flags & 1 /* UpdateFlag.Focus */) > 0; } /** Whether the document changed in this update. @@ -9988,13 +10186,14 @@ for (let p of ["()", "[]", "{}"]) { } function charType(ch) { return ch <= 0xf7 ? LowTypes[ch] : - 0x590 <= ch && ch <= 0x5f4 ? 2 /* R */ : + 0x590 <= ch && ch <= 0x5f4 ? 2 /* T.R */ : 0x600 <= ch && ch <= 0x6f9 ? ArabicTypes[ch - 0x600] : - 0x6ee <= ch && ch <= 0x8ac ? 4 /* AL */ : - 0x2000 <= ch && ch <= 0x200b ? 256 /* NI */ : - ch == 0x200c ? 256 /* NI */ : 1 /* L */; + 0x6ee <= ch && ch <= 0x8ac ? 4 /* T.AL */ : + 0x2000 <= ch && ch <= 0x200b ? 256 /* T.NI */ : + 0xfb50 <= ch && ch <= 0xfdff ? 4 /* T.AL */ : + ch == 0x200c ? 256 /* T.NI */ : 1 /* T.L */; } -const BidiRE = /[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/; +const BidiRE = /[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac\ufb50-\ufdff]/; /** Represents a contiguous range of text that has a single direction (as in left-to-right or right-to-left). @@ -10057,8 +10256,8 @@ class BidiSpan { // Reused array of character types const types = []; function computeOrder(line, direction) { - let len = line.length, outerType = direction == LTR ? 1 /* L */ : 2 /* R */, oppositeType = direction == LTR ? 2 /* R */ : 1 /* L */; - if (!line || outerType == 1 /* L */ && !BidiRE.test(line)) + let len = line.length, outerType = direction == LTR ? 1 /* T.L */ : 2 /* T.R */, oppositeType = direction == LTR ? 2 /* T.R */ : 1 /* T.L */; + if (!line || outerType == 1 /* T.L */ && !BidiRE.test(line)) return trivialOrder(len); // W1. Examine each non-spacing mark (NSM) in the level run, and // change the type of the NSM to the type of the previous @@ -10072,12 +10271,12 @@ function computeOrder(line, direction) { // (Left after this: L, R, EN, AN, ET, CS, NI) for (let i = 0, prev = outerType, prevStrong = outerType; i < len; i++) { let type = charType(line.charCodeAt(i)); - if (type == 512 /* NSM */) + if (type == 512 /* T.NSM */) type = prev; - else if (type == 8 /* EN */ && prevStrong == 4 /* AL */) - type = 16 /* AN */; - types[i] = type == 4 /* AL */ ? 2 /* R */ : type; - if (type & 7 /* Strong */) + else if (type == 8 /* T.EN */ && prevStrong == 4 /* T.AL */) + type = 16 /* T.AN */; + types[i] = type == 4 /* T.AL */ ? 2 /* T.R */ : type; + if (type & 7 /* T.Strong */) prevStrong = type; prev = type; } @@ -10091,26 +10290,26 @@ function computeOrder(line, direction) { // (Left after this: L, R, EN+AN, NI) for (let i = 0, prev = outerType, prevStrong = outerType; i < len; i++) { let type = types[i]; - if (type == 128 /* CS */) { - if (i < len - 1 && prev == types[i + 1] && (prev & 24 /* Num */)) + if (type == 128 /* T.CS */) { + if (i < len - 1 && prev == types[i + 1] && (prev & 24 /* T.Num */)) type = types[i] = prev; else - types[i] = 256 /* NI */; + types[i] = 256 /* T.NI */; } - else if (type == 64 /* ET */) { + else if (type == 64 /* T.ET */) { let end = i + 1; - while (end < len && types[end] == 64 /* ET */) + while (end < len && types[end] == 64 /* T.ET */) end++; - let replace = (i && prev == 8 /* EN */) || (end < len && types[end] == 8 /* EN */) ? (prevStrong == 1 /* L */ ? 1 /* L */ : 8 /* EN */) : 256 /* NI */; + let replace = (i && prev == 8 /* T.EN */) || (end < len && types[end] == 8 /* T.EN */) ? (prevStrong == 1 /* T.L */ ? 1 /* T.L */ : 8 /* T.EN */) : 256 /* T.NI */; for (let j = i; j < end; j++) types[j] = replace; i = end - 1; } - else if (type == 8 /* EN */ && prevStrong == 1 /* L */) { - types[i] = 1 /* L */; + else if (type == 8 /* T.EN */ && prevStrong == 1 /* T.L */) { + types[i] = 1 /* T.L */; } prev = type; - if (type & 7 /* Strong */) + if (type & 7 /* T.Strong */) prevStrong = type; } // N0. Process bracket pairs in an isolating run sequence @@ -10125,9 +10324,9 @@ function computeOrder(line, direction) { for (let sJ = sI - 3; sJ >= 0; sJ -= 3) { if (BracketStack[sJ + 1] == -br) { let flags = BracketStack[sJ + 2]; - let type = (flags & 2 /* EmbedInside */) ? outerType : - !(flags & 4 /* OppositeInside */) ? 0 : - (flags & 1 /* OppositeBefore */) ? oppositeType : outerType; + let type = (flags & 2 /* Bracketed.EmbedInside */) ? outerType : + !(flags & 4 /* Bracketed.OppositeInside */) ? 0 : + (flags & 1 /* Bracketed.OppositeBefore */) ? oppositeType : outerType; if (type) types[i] = types[BracketStack[sJ]] = type; sI = sJ; @@ -10135,7 +10334,7 @@ function computeOrder(line, direction) { } } } - else if (BracketStack.length == 189 /* MaxDepth */) { + else if (BracketStack.length == 189 /* Bracketed.MaxDepth */) { break; } else { @@ -10144,20 +10343,20 @@ function computeOrder(line, direction) { BracketStack[sI++] = context; } } - else if ((type = types[i]) == 2 /* R */ || type == 1 /* L */) { + else if ((type = types[i]) == 2 /* T.R */ || type == 1 /* T.L */) { let embed = type == outerType; - context = embed ? 0 : 1 /* OppositeBefore */; + context = embed ? 0 : 1 /* Bracketed.OppositeBefore */; for (let sJ = sI - 3; sJ >= 0; sJ -= 3) { let cur = BracketStack[sJ + 2]; - if (cur & 2 /* EmbedInside */) + if (cur & 2 /* Bracketed.EmbedInside */) break; if (embed) { - BracketStack[sJ + 2] |= 2 /* EmbedInside */; + BracketStack[sJ + 2] |= 2 /* Bracketed.EmbedInside */; } else { - if (cur & 4 /* OppositeInside */) + if (cur & 4 /* Bracketed.OppositeInside */) break; - BracketStack[sJ + 2] |= 4 /* OppositeInside */; + BracketStack[sJ + 2] |= 4 /* Bracketed.OppositeInside */; } } } @@ -10170,13 +10369,13 @@ function computeOrder(line, direction) { // N2. Any remaining neutrals take the embedding direction. // (Left after this: L, R, EN+AN) for (let i = 0; i < len; i++) { - if (types[i] == 256 /* NI */) { + if (types[i] == 256 /* T.NI */) { let end = i + 1; - while (end < len && types[end] == 256 /* NI */) + while (end < len && types[end] == 256 /* T.NI */) end++; - let beforeL = (i ? types[i - 1] : outerType) == 1 /* L */; - let afterL = (end < len ? types[end] : outerType) == 1 /* L */; - let replace = beforeL == afterL ? (beforeL ? 1 /* L */ : 2 /* R */) : outerType; + let beforeL = (i ? types[i - 1] : outerType) == 1 /* T.L */; + let afterL = (end < len ? types[end] : outerType) == 1 /* T.L */; + let replace = beforeL == afterL ? (beforeL ? 1 /* T.L */ : 2 /* T.R */) : outerType; for (let j = i; j < end; j++) types[j] = replace; i = end - 1; @@ -10188,15 +10387,15 @@ function computeOrder(line, direction) { // explicit embedding into account, we can build up the order on // the fly, without following the level-based algorithm. let order = []; - if (outerType == 1 /* L */) { + if (outerType == 1 /* T.L */) { for (let i = 0; i < len;) { - let start = i, rtl = types[i++] != 1 /* L */; - while (i < len && rtl == (types[i] != 1 /* L */)) + let start = i, rtl = types[i++] != 1 /* T.L */; + while (i < len && rtl == (types[i] != 1 /* T.L */)) i++; if (rtl) { for (let j = i; j > start;) { - let end = j, l = types[--j] != 2 /* R */; - while (j > start && l == (types[j - 1] != 2 /* R */)) + let end = j, l = types[--j] != 2 /* T.R */; + while (j > start && l == (types[j - 1] != 2 /* T.R */)) j--; order.push(new BidiSpan(j, end, l ? 2 : 1)); } @@ -10208,8 +10407,8 @@ function computeOrder(line, direction) { } else { for (let i = 0; i < len;) { - let start = i, rtl = types[i++] == 2 /* R */; - while (i < len && rtl == (types[i] == 2 /* R */)) + let start = i, rtl = types[i++] == 2 /* T.R */; + while (i < len && rtl == (types[i] == 2 /* T.R */)) i++; order.push(new BidiSpan(start, i, rtl ? 1 : 2)); } @@ -10398,7 +10597,6 @@ class DocView extends ContentView { this.updateDeco(); this.updateInner([new ChangedRange(0, 0, 0, view.state.doc.length)], 0); } - get root() { return this.view.root; } get editorView() { return this.view; } get length() { return this.view.state.doc.length; } // Update the document view to a given state. scrollIntoView can be @@ -10431,7 +10629,7 @@ class DocView extends ContentView { let prevDeco = this.decorations, deco = this.updateDeco(); let decoDiff = findChangedDeco(prevDeco, deco, update.changes); changedRanges = ChangedRange.extendWithRanges(changedRanges, decoDiff); - if (this.dirty == 0 /* Not */ && changedRanges.length == 0) { + if (this.dirty == 0 /* Dirty.Not */ && changedRanges.length == 0) { return false; } else { @@ -10453,14 +10651,14 @@ class DocView extends ContentView { // no relayout is triggered and I cannot imagine how it can // recompute the scroll position without a layout) this.dom.style.height = this.view.viewState.contentHeight + "px"; - this.dom.style.minWidth = this.minWidth ? this.minWidth + "px" : ""; + this.dom.style.flexBasis = this.minWidth ? this.minWidth + "px" : ""; // Chrome will sometimes, when DOM mutations occur directly // around the selection, get confused and report a different // selection from the one it displays (issue #218). This tries // to detect that situation. let track = browser.chrome || browser.ios ? { node: observer.selectionRange.focusNode, written: false } : undefined; this.sync(track); - this.dirty = 0 /* Not */; + this.dirty = 0 /* Dirty.Not */; if (track && (track.written || observer.selectionRange.focusNode != track.node)) this.forceSelection = true; this.dom.style.height = ""; @@ -10487,10 +10685,9 @@ class DocView extends ContentView { } // Sync the DOM selection to this.state.selection updateSelection(mustRead = false, fromPointer = false) { - if (mustRead) + if (mustRead || !this.view.observer.selectionRange.focusNode) this.view.observer.readSelectionRange(); - if (!(fromPointer || this.mayControlSelection()) || - browser.ios && this.view.inputState.rapidCompositionStart) + if (!(fromPointer || this.mayControlSelection())) return; let force = this.forceSelection; this.forceSelection = false; @@ -10521,15 +10718,16 @@ class DocView extends ContentView { this.dom.blur(); this.dom.focus({ preventScroll: true }); } - let rawSel = getSelection(this.root); - if (main.empty) { + let rawSel = getSelection(this.view.root); + if (!rawSel) ; + else if (main.empty) { // Work around https://bugzilla.mozilla.org/show_bug.cgi?id=1612076 if (browser.gecko) { let nextTo = nextToUneditable(anchor.node, anchor.offset); - if (nextTo && nextTo != (1 /* Before */ | 2 /* After */)) { - let text = nearbyTextNode(anchor.node, anchor.offset, nextTo == 1 /* Before */ ? 1 : -1); + if (nextTo && nextTo != (1 /* NextTo.Before */ | 2 /* NextTo.After */)) { + let text = nearbyTextNode(anchor.node, anchor.offset, nextTo == 1 /* NextTo.Before */ ? 1 : -1); if (text) - anchor = new DOMPos(text, nextTo == 1 /* Before */ ? 0 : text.nodeValue.length); + anchor = new DOMPos(text, nextTo == 1 /* NextTo.Before */ ? 0 : text.nodeValue.length); } } rawSel.collapse(anchor.node, anchor.offset); @@ -10541,7 +10739,13 @@ class DocView extends ContentView { // (one where the focus is before the anchor), but not all // browsers support it yet. rawSel.collapse(anchor.node, anchor.offset); - rawSel.extend(head.node, head.offset); + // Safari will ignore the call above when the editor is + // hidden, and then raise an error on the call to extend + // (#940). + try { + rawSel.extend(head.node, head.offset); + } + catch (_) { } } else { // Primitive (IE) way @@ -10562,9 +10766,10 @@ class DocView extends ContentView { enforceCursorAssoc() { if (this.compositionDeco.size) return; - let cursor = this.view.state.selection.main; - let sel = getSelection(this.root); - if (!cursor.empty || !cursor.assoc || !sel.modify) + let { view } = this, cursor = view.state.selection.main; + let sel = getSelection(view.root); + let { anchorNode, anchorOffset } = view.observer.selectionRange; + if (!sel || !cursor.empty || !cursor.assoc || !sel.modify) return; let line = LineView.find(this, cursor.head); if (!line) @@ -10578,10 +10783,17 @@ class DocView extends ContentView { let dom = this.domAtPos(cursor.head + cursor.assoc); sel.collapse(dom.node, dom.offset); sel.modify("move", cursor.assoc < 0 ? "forward" : "backward", "lineboundary"); + // This can go wrong in corner cases like single-character lines, + // so check and reset if necessary. + view.observer.readSelectionRange(); + let newRange = view.observer.selectionRange; + if (view.docView.posFromDOM(newRange.anchorNode, newRange.anchorOffset) != cursor.from) + sel.collapse(anchorNode, anchorOffset); } mayControlSelection() { - return this.view.state.facet(editable) ? this.root.activeElement == this.dom - : hasSelection(this.dom, this.view.observer.selectionRange); + let active = this.view.root.activeElement; + return active == this.dom || + hasSelection(this.dom, this.view.observer.selectionRange) && !(active && this.dom.contains(active)); } nearest(dom) { for (let cur = dom; cur;) { @@ -10666,6 +10878,7 @@ class DocView extends ContentView { // If no workable line exists, force a layout of a measurable element let dummy = document.createElement("div"), lineHeight, charWidth; dummy.className = "cm-line"; + dummy.style.width = "99999px"; dummy.textContent = "abc def ghi jkl mno pqr stu"; this.view.observer.ignore(() => { this.dom.appendChild(dummy); @@ -10859,8 +11072,8 @@ function nearbyTextNode(node, offset, side) { function nextToUneditable(node, offset) { if (node.nodeType != 1) return 0; - return (offset && node.childNodes[offset - 1].contentEditable == "false" ? 1 /* Before */ : 0) | - (offset < node.childNodes.length && node.childNodes[offset].contentEditable == "false" ? 2 /* After */ : 0); + return (offset && node.childNodes[offset - 1].contentEditable == "false" ? 1 /* NextTo.Before */ : 0) | + (offset < node.childNodes.length && node.childNodes[offset].contentEditable == "false" ? 2 /* NextTo.After */ : 0); } class DecorationComparator$1 { constructor() { @@ -10931,7 +11144,7 @@ function upBot(rect, bottom) { return bottom > rect.bottom ? { top: rect.top, left: rect.left, right: rect.right, bottom } : rect; } function domPosAtCoords(parent, x, y) { - let closest, closestRect, closestX, closestY; + let closest, closestRect, closestX, closestY, closestOverlap = false; let above, below, aboveRect, belowRect; for (let child = parent.firstChild; child; child = child.nextSibling) { let rects = clientRectsFor(child); @@ -10947,6 +11160,7 @@ function domPosAtCoords(parent, x, y) { closestRect = rect; closestX = dx; closestY = dy; + closestOverlap = !dx || (dx > 0 ? i < rects.length - 1 : i > 0); } if (dx == 0) { if (y > rect.bottom && (!aboveRect || aboveRect.bottom < rect.bottom)) { @@ -10979,7 +11193,7 @@ function domPosAtCoords(parent, x, y) { let clipX = Math.max(closestRect.left, Math.min(closestRect.right, x)); if (closest.nodeType == 3) return domPosInText(closest, clipX, y); - if (!closestX && closest.contentEditable == "true") + if (closestOverlap && closest.contentEditable != "false") return domPosAtCoords(closest, clipX, y); let offset = Array.prototype.indexOf.call(parent.childNodes, closest) + (x >= (closestRect.left + closestRect.right) / 2 ? 1 : 0); @@ -11076,7 +11290,9 @@ function posAtCoords(view, { x, y }, precise, bias = -1) { let range = doc.caretRangeFromPoint(x, y); if (range) { ({ startContainer: node, startOffset: offset } = range); - if (browser.safari && isSuspiciousCaretResult(node, offset, x)) + if (!view.contentDOM.contains(node) || + browser.safari && isSuspiciousSafariCaretResult(node, offset, x) || + browser.chrome && isSuspiciousChromeCaretResult(node, offset, x)) node = undefined; } } @@ -11103,7 +11319,7 @@ function posAtCoordsImprecise(view, contentRect, block, x, y) { // the space between lines as belonging to the last character of the // line before. This is used to detect such a result so that it can be // ignored (issue #401). -function isSuspiciousCaretResult(node, offset, x) { +function isSuspiciousSafariCaretResult(node, offset, x) { let len; if (node.nodeType != 3 || offset != (len = node.nodeValue.length)) return false; @@ -11112,6 +11328,22 @@ function isSuspiciousCaretResult(node, offset, x) { return false; return textRange(node, len - 1, len).getBoundingClientRect().left > x; } +// Chrome will move positions between lines to the start of the next line +function isSuspiciousChromeCaretResult(node, offset, x) { + if (offset != 0) + return false; + for (let cur = node;;) { + let parent = cur.parentNode; + if (!parent || parent.nodeType != 1 || parent.firstChild != cur) + return false; + if (parent.classList.contains("cm-line")) + break; + cur = parent; + } + let rect = node.nodeType == 1 ? node.getBoundingClientRect() + : textRange(node, 0, Math.max(node.nodeValue.length, 1)).getBoundingClientRect(); + return x - rect.left > 5; +} function moveToLineBoundary(view, start, forward, includeWrap) { let line = view.state.doc.lineAt(start.head); let coords = !includeWrap || !view.lineWrapping ? null @@ -11196,7 +11428,7 @@ function skipAtoms(view, oldPos, pos) { for (let set of atoms) { set.between(pos.from - 1, pos.from + 1, (from, to, value) => { if (pos.from > from && pos.from < to) { - pos = oldPos.from > pos.from ? EditorSelection.cursor(from, 1) : EditorSelection.cursor(to, -1); + pos = oldPos.head > pos.from ? EditorSelection.cursor(from, 1) : EditorSelection.cursor(to, -1); moved = true; } }); @@ -11211,6 +11443,11 @@ class InputState { constructor(view) { this.lastKeyCode = 0; this.lastKeyTime = 0; + this.lastTouchTime = 0; + this.lastFocusTime = 0; + this.lastScrollTop = 0; + this.lastScrollLeft = 0; + this.chromeScrollHack = -1; // On iOS, some keys need to have their default behavior happen // (after which we retroactively handle them and reset the DOM) to // avoid messing up the virtual keyboard state. @@ -11233,7 +11470,6 @@ class InputState { // composition) this.compositionFirstChange = null; this.compositionEndedAt = 0; - this.rapidCompositionStart = false; this.mouseSelection = null; for (let type in handlers) { let handler = handlers[type]; @@ -11248,9 +11484,24 @@ class InputState { event.preventDefault(); else handler(view, event); - }); + }, handlerOptions[type]); this.registeredEvents.push(type); } + if (browser.chrome && browser.chrome_version == 102) { // FIXME remove at some point + // On Chrome 102, viewport updates somehow stop wheel-based + // scrolling. Turning off pointer events during the scroll seems + // to avoid the issue. + view.scrollDOM.addEventListener("wheel", () => { + if (this.chromeScrollHack < 0) + view.contentDOM.style.pointerEvents = "none"; + else + window.clearTimeout(this.chromeScrollHack); + this.chromeScrollHack = setTimeout(() => { + this.chromeScrollHack = -1; + view.contentDOM.style.pointerEvents = ""; + }, 100); + }, { passive: true }); + } this.notifiedFocused = view.hasFocus; // On Safari adding an input event handler somehow prevents an // issue where the composition vanishes when you press enter. @@ -11296,6 +11547,8 @@ class InputState { return false; } runScrollHandlers(view, event) { + this.lastScrollTop = view.scrollDOM.scrollTop; + this.lastScrollLeft = view.scrollDOM.scrollLeft; for (let set of this.customHandlers) { let handler = set.handlers.scroll; if (handler) { @@ -11330,9 +11583,10 @@ class InputState { // applyDOMChange, notify key handlers of it and reset to // the state they produce. let pending; - if (browser.ios && (pending = PendingKeys.find(key => key.keyCode == event.keyCode)) && - !(event.ctrlKey || event.altKey || event.metaKey) && !event.synthetic) { - this.pendingIOSKey = pending; + if (browser.ios && !event.synthetic && !event.altKey && !event.metaKey && + ((pending = PendingKeys.find(key => key.keyCode == event.keyCode)) && !event.ctrlKey || + EmacsyPendingKeys.indexOf(event.key) > -1 && event.ctrlKey && !event.shiftKey)) { + this.pendingIOSKey = pending || event; setTimeout(() => this.flushIOSKey(view), 250); return true; } @@ -11356,15 +11610,14 @@ class InputState { // compositionend and keydown events are sometimes emitted in the // wrong order. The key event should still be ignored, even when // it happens after the compositionend event. - if (browser.safari && Date.now() - this.compositionEndedAt < 100) { + if (browser.safari && !browser.ios && Date.now() - this.compositionEndedAt < 100) { this.compositionEndedAt = 0; return true; } return false; } mustFlushObserver(event) { - return (event.type == "keydown" && event.keyCode != 229) || - event.type == "compositionend" && !browser.ios; + return event.type == "keydown" && event.keyCode != 229; } startMouseSelection(mouseSelection) { if (this.mouseSelection) @@ -11387,6 +11640,7 @@ const PendingKeys = [ { key: "Enter", keyCode: 13, inputType: "insertParagraph" }, { key: "Delete", keyCode: 46, inputType: "deleteContentForward" } ]; +const EmacsyPendingKeys = "dthko"; // Key codes for modifier keys const modifierCodes = [16, 17, 18, 20, 91, 92, 224, 225]; class MouseSelection { @@ -11462,7 +11716,7 @@ function isInPrimarySelection(view, event) { // On boundary clicks, check whether the coordinates are inside the // selection's client rectangles let sel = getSelection(view.root); - if (sel.rangeCount == 0) + if (!sel || sel.rangeCount == 0) return true; let rects = sel.getRangeAt(0).getClientRects(); for (let i = 0; i < rects.length; i++) { @@ -11484,6 +11738,7 @@ function eventBelongsToEditor(view, event) { return true; } const handlers = /*@__PURE__*/Object.create(null); +const handlerOptions = /*@__PURE__*/Object.create(null); // This is very crude, but unfortunately both these browsers _pretend_ // that they have a clipboard API—all the objects and methods are // there, they just don't work, and they are hard to test. @@ -11540,17 +11795,17 @@ handlers.keydown = (view, event) => { else if (modifierCodes.indexOf(event.keyCode) < 0) view.inputState.lastEscPress = 0; }; -let lastTouch = 0; handlers.touchstart = (view, e) => { - lastTouch = Date.now(); + view.inputState.lastTouchTime = Date.now(); view.inputState.setSelectionOrigin("select.pointer"); }; handlers.touchmove = view => { view.inputState.setSelectionOrigin("select.pointer"); }; +handlerOptions.touchstart = handlerOptions.touchmove = { passive: true }; handlers.mousedown = (view, event) => { view.observer.flush(); - if (lastTouch > Date.now() - 2000 && getClickType(event) == 1) + if (view.inputState.lastTouchTime > Date.now() - 2000) return; // Ignore touch interaction let style = null; for (let makeStyle of view.state.facet(mouseSelectionStyle)) { @@ -11630,8 +11885,7 @@ function basicMouseSelection(view, event) { return { update(update) { if (update.docChanged) { - if (start) - start.pos = update.changes.mapPos(start.pos); + start.pos = update.changes.mapPos(start.pos); startSel = startSel.map(update.changes); lastEvent = null; } @@ -11644,8 +11898,6 @@ function basicMouseSelection(view, event) { cur = last = queryPos(view, event); lastEvent = event; } - if (!cur || !start) - return startSel; let range = rangeForClick(view, cur.pos, cur.bias, type); if (start.pos != cur.pos && !extend) { let startRange = rangeForClick(view, start.pos, start.bias, type); @@ -11654,6 +11906,8 @@ function basicMouseSelection(view, event) { } if (extend) return startSel.replaceRange(startSel.main.extend(range.from, range.to)); + else if (multiple && startSel.ranges.length > 1 && startSel.ranges.some(r => r.eq(range))) + return removeRange(startSel, range); else if (multiple) return startSel.addRange(range); else @@ -11661,6 +11915,12 @@ function basicMouseSelection(view, event) { } }; } +function removeRange(sel, range) { + for (let i = 0;; i++) { + if (sel.ranges[i].eq(range)) + return EditorSelection.create(sel.ranges.slice(0, i).concat(sel.ranges.slice(i + 1)), sel.mainIndex == i ? 0 : sel.mainIndex - (sel.mainIndex > i ? 1 : 0)); + } +} handlers.dragstart = (view, event) => { let { selection: { main } } = view.state; let { mouseSelection } = view.inputState; @@ -11796,41 +12056,37 @@ function updateForFocusChange(view) { view.update([]); }, 10); } -handlers.focus = updateForFocusChange; +handlers.focus = view => { + view.inputState.lastFocusTime = Date.now(); + // When focusing reset the scroll position, move it back to where it was + if (!view.scrollDOM.scrollTop && (view.inputState.lastScrollTop || view.inputState.lastScrollLeft)) { + view.scrollDOM.scrollTop = view.inputState.lastScrollTop; + view.scrollDOM.scrollLeft = view.inputState.lastScrollLeft; + } + updateForFocusChange(view); +}; handlers.blur = view => { view.observer.clearSelectionRange(); updateForFocusChange(view); }; -function forceClearComposition(view, rapid) { - if (view.docView.compositionDeco.size) { - view.inputState.rapidCompositionStart = rapid; - try { - view.update([]); - } - finally { - view.inputState.rapidCompositionStart = false; - } - } -} handlers.compositionstart = handlers.compositionupdate = view => { if (view.inputState.compositionFirstChange == null) view.inputState.compositionFirstChange = true; if (view.inputState.composing < 0) { // FIXME possibly set a timeout to clear it again on Android view.inputState.composing = 0; - if (view.docView.compositionDeco.size) { - view.observer.flush(); - forceClearComposition(view, true); - } } }; handlers.compositionend = view => { view.inputState.composing = -1; view.inputState.compositionEndedAt = Date.now(); view.inputState.compositionFirstChange = null; + if (browser.chrome && browser.android) + view.observer.flushSoon(); setTimeout(() => { - if (view.inputState.composing < 0) - forceClearComposition(view, false); + // Force the composition state to be cleared if it hasn't already been + if (view.inputState.composing < 0 && view.docView.compositionDeco.size) + view.update([]); }, 50); }; handlers.contextmenu = view => { @@ -12000,13 +12256,13 @@ const Epsilon = 1e-3; class HeightMap { constructor(length, // The number of characters covered height, // Height of this part of the document - flags = 2 /* Outdated */) { + flags = 2 /* Flag.Outdated */) { this.length = length; this.height = height; this.flags = flags; } - get outdated() { return (this.flags & 2 /* Outdated */) > 0; } - set outdated(value) { this.flags = (value ? 2 /* Outdated */ : 0) | (this.flags & ~2 /* Outdated */); } + get outdated() { return (this.flags & 2 /* Flag.Outdated */) > 0; } + set outdated(value) { this.flags = (value ? 2 /* Flag.Outdated */ : 0) | (this.flags & ~2 /* Flag.Outdated */); } setHeight(oracle, height) { if (this.height != height) { if (Math.abs(this.height - height) > Epsilon) @@ -12133,7 +12389,7 @@ class HeightMapText extends HeightMapBlock { } replace(_from, _to, nodes) { let node = nodes[0]; - if (nodes.length == 1 && (node instanceof HeightMapText || node instanceof HeightMapGap && (node.flags & 4 /* SingleLine */)) && + if (nodes.length == 1 && (node instanceof HeightMapText || node instanceof HeightMapGap && (node.flags & 4 /* Flag.SingleLine */)) && Math.abs(this.length - node.length) < 10) { if (node instanceof HeightMapGap) node = new HeightMapText(node.length, this.height); @@ -12259,12 +12515,12 @@ class HeightMapGap extends HeightMap { } class HeightMapBranch extends HeightMap { constructor(left, brk, right) { - super(left.length + brk + right.length, left.height + right.height, brk | (left.outdated || right.outdated ? 2 /* Outdated */ : 0)); + super(left.length + brk + right.length, left.height + right.height, brk | (left.outdated || right.outdated ? 2 /* Flag.Outdated */ : 0)); this.left = left; this.right = right; this.size = left.size + right.size; } - get break() { return this.flags & 1 /* Break */; } + get break() { return this.flags & 1 /* Flag.Break */; } blockAt(height, doc, top, offset) { let mid = top + this.left.height; return height < mid ? this.left.blockAt(height, doc, top, offset) @@ -12448,7 +12704,7 @@ class NodeBuilder { blankContent(from, to) { let gap = new HeightMapGap(to - from); if (this.oracle.doc.lineAt(from).to == to) - gap.flags |= 4 /* SingleLine */; + gap.flags |= 4 /* Flag.SingleLine */; return gap; } ensureLine() { @@ -12519,10 +12775,10 @@ class DecorationComparator { function visiblePixelRange(dom, paddingTop) { let rect = dom.getBoundingClientRect(); - let left = Math.max(0, rect.left), right = Math.min(innerWidth, rect.right); - let top = Math.max(0, rect.top), bottom = Math.min(innerHeight, rect.bottom); - let body = dom.ownerDocument.body; - for (let parent = dom.parentNode; parent && parent != body;) { + let doc = dom.ownerDocument, win = doc.defaultView || window; + let left = Math.max(0, rect.left), right = Math.min(win.innerWidth, rect.right); + let top = Math.max(0, rect.top), bottom = Math.min(win.innerHeight, rect.bottom); + for (let parent = dom.parentNode; parent && parent != doc.body;) { if (parent.nodeType == 1) { let elt = parent; let style = window.getComputedStyle(elt); @@ -12532,7 +12788,7 @@ function visiblePixelRange(dom, paddingTop) { left = Math.max(left, parentRect.left); right = Math.min(right, parentRect.right); top = Math.max(top, parentRect.top); - bottom = Math.min(bottom, parentRect.bottom); + bottom = parent == dom.parentNode ? parentRect.bottom : Math.min(bottom, parentRect.bottom); } parent = style.position == "absolute" || style.position == "fixed" ? elt.offsetParent : elt.parentNode; } @@ -12616,7 +12872,7 @@ class ViewState { // Flag set when editor content was redrawn, so that the next // measure stage knows it must read DOM layout this.mustMeasureContent = true; - this.defaultTextDirection = Direction.RTL; + this.defaultTextDirection = Direction.LTR; this.visibleRanges = []; // Cursor 'assoc' is only significant when the cursor is on a line // wrap point, where it must stick to the character that it is @@ -12646,7 +12902,7 @@ class ViewState { } } this.viewports = viewports.sort((a, b) => a.from - b.from); - this.scaler = this.heightMap.height <= 7000000 /* MaxDOMHeight */ ? IdScaler : + this.scaler = this.heightMap.height <= 7000000 /* VP.MaxDOMHeight */ ? IdScaler : new BigScaler(this.heightOracle.doc, this.heightMap, this.viewports); } updateViewportLines() { @@ -12664,24 +12920,25 @@ class ViewState { let prevHeight = this.heightMap.height; this.heightMap = this.heightMap.applyChanges(this.stateDeco, update.startState.doc, this.heightOracle.setDoc(this.state.doc), heightChanges); if (this.heightMap.height != prevHeight) - update.flags |= 2 /* Height */; + update.flags |= 2 /* UpdateFlag.Height */; let viewport = heightChanges.length ? this.mapViewport(this.viewport, update.changes) : this.viewport; if (scrollTarget && (scrollTarget.range.head < viewport.from || scrollTarget.range.head > viewport.to) || !this.viewportIsAppropriate(viewport)) viewport = this.getViewport(0, scrollTarget); - let updateLines = !update.changes.empty || (update.flags & 2 /* Height */) || + let updateLines = !update.changes.empty || (update.flags & 2 /* UpdateFlag.Height */) || viewport.from != this.viewport.from || viewport.to != this.viewport.to; this.viewport = viewport; this.updateForViewport(); if (updateLines) this.updateViewportLines(); - if (this.lineGaps.length || this.viewport.to - this.viewport.from > 4000 /* DoubleMargin */) + if (this.lineGaps.length || this.viewport.to - this.viewport.from > (2000 /* LG.Margin */ << 1)) this.updateLineGaps(this.ensureLineGaps(this.mapLineGaps(this.lineGaps, update.changes))); update.flags |= this.computeVisibleRanges(); if (scrollTarget) this.scrollTarget = scrollTarget; if (!this.mustEnforceCursorAssoc && update.selectionSet && update.view.lineWrapping && - update.state.selection.main.empty && update.state.selection.main.assoc) + update.state.selection.main.empty && update.state.selection.main.assoc && + !update.state.facet(nativeSelectionHidden)) this.mustEnforceCursorAssoc = true; } measure(view) { @@ -12691,23 +12948,21 @@ class ViewState { this.defaultTextDirection = style.direction == "rtl" ? Direction.RTL : Direction.LTR; let refresh = this.heightOracle.mustRefreshForWrapping(whiteSpace); let measureContent = refresh || this.mustMeasureContent || this.contentDOMHeight != dom.clientHeight; + this.contentDOMHeight = dom.clientHeight; + this.mustMeasureContent = false; let result = 0, bias = 0; + // Vertical padding + let paddingTop = parseInt(style.paddingTop) || 0, paddingBottom = parseInt(style.paddingBottom) || 0; + if (this.paddingTop != paddingTop || this.paddingBottom != paddingBottom) { + this.paddingTop = paddingTop; + this.paddingBottom = paddingBottom; + result |= 8 /* UpdateFlag.Geometry */ | 2 /* UpdateFlag.Height */; + } if (this.editorWidth != view.scrollDOM.clientWidth) { if (oracle.lineWrapping) measureContent = true; this.editorWidth = view.scrollDOM.clientWidth; - result |= 8 /* Geometry */; - } - if (measureContent) { - this.mustMeasureContent = false; - this.contentDOMHeight = dom.clientHeight; - // Vertical padding - let paddingTop = parseInt(style.paddingTop) || 0, paddingBottom = parseInt(style.paddingBottom) || 0; - if (this.paddingTop != paddingTop || this.paddingBottom != paddingBottom) { - result |= 8 /* Geometry */; - this.paddingTop = paddingTop; - this.paddingBottom = paddingBottom; - } + result |= 8 /* UpdateFlag.Geometry */; } // Pixel viewport let pixelViewport = (this.printing ? fullPixelRange : visiblePixelRange)(dom, this.paddingTop); @@ -12719,13 +12974,13 @@ class ViewState { if (inView) measureContent = true; } - if (!this.inView) + if (!this.inView && !this.scrollTarget) return 0; let contentWidth = dom.clientWidth; if (this.contentDOMWidth != contentWidth || this.editorHeight != view.scrollDOM.clientHeight) { this.contentDOMWidth = contentWidth; this.editorHeight = view.scrollDOM.clientHeight; - result |= 8 /* Geometry */; + result |= 8 /* UpdateFlag.Geometry */; } if (measureContent) { let lineHeights = view.docView.measureVisibleLineHeights(this.viewport); @@ -12733,10 +12988,10 @@ class ViewState { refresh = true; if (refresh || oracle.lineWrapping && Math.abs(contentWidth - this.contentDOMWidth) > oracle.charWidth) { let { lineHeight, charWidth } = view.docView.measureTextSize(); - refresh = oracle.refresh(whiteSpace, lineHeight, charWidth, contentWidth / charWidth, lineHeights); + refresh = lineHeight > 0 && oracle.refresh(whiteSpace, lineHeight, charWidth, contentWidth / charWidth, lineHeights); if (refresh) { view.docView.minWidth = 0; - result |= 8 /* Geometry */; + result |= 8 /* UpdateFlag.Geometry */; } } if (dTop > 0 && dBottom > 0) @@ -12746,20 +13001,22 @@ class ViewState { oracle.heightChanged = false; for (let vp of this.viewports) { let heights = vp.from == this.viewport.from ? lineHeights : view.docView.measureVisibleLineHeights(vp); - this.heightMap = this.heightMap.updateHeight(oracle, 0, refresh, new MeasuredHeights(vp.from, heights)); + this.heightMap = refresh + ? HeightMap.empty().applyChanges(this.stateDeco, Text.empty, this.heightOracle, [new ChangedRange(0, 0, 0, view.state.doc.length)]) + : this.heightMap.updateHeight(oracle, 0, refresh, new MeasuredHeights(vp.from, heights)); } if (oracle.heightChanged) - result |= 2 /* Height */; + result |= 2 /* UpdateFlag.Height */; } let viewportChange = !this.viewportIsAppropriate(this.viewport, bias) || this.scrollTarget && (this.scrollTarget.range.head < this.viewport.from || this.scrollTarget.range.head > this.viewport.to); if (viewportChange) this.viewport = this.getViewport(bias, this.scrollTarget); this.updateForViewport(); - if ((result & 2 /* Height */) || viewportChange) + if ((result & 2 /* UpdateFlag.Height */) || viewportChange) this.updateViewportLines(); - if (this.lineGaps.length || this.viewport.to - this.viewport.from > 4000 /* DoubleMargin */) - this.updateLineGaps(this.ensureLineGaps(refresh ? [] : this.lineGaps)); + if (this.lineGaps.length || this.viewport.to - this.viewport.from > (2000 /* LG.Margin */ << 1)) + this.updateLineGaps(this.ensureLineGaps(refresh ? [] : this.lineGaps, view)); result |= this.computeVisibleRanges(); if (this.mustEnforceCursorAssoc) { this.mustEnforceCursorAssoc = false; @@ -12777,9 +13034,9 @@ class ViewState { // This will divide VP.Margin between the top and the // bottom, depending on the bias (the change in viewport position // since the last update). It'll hold a number between 0 and 1 - let marginTop = 0.5 - Math.max(-0.5, Math.min(0.5, bias / 1000 /* Margin */ / 2)); + let marginTop = 0.5 - Math.max(-0.5, Math.min(0.5, bias / 1000 /* VP.Margin */ / 2)); let map = this.heightMap, doc = this.state.doc, { visibleTop, visibleBottom } = this; - let viewport = new Viewport(map.lineAt(visibleTop - marginTop * 1000 /* Margin */, QueryType$1.ByHeight, doc, 0, 0).from, map.lineAt(visibleBottom + (1 - marginTop) * 1000 /* Margin */, QueryType$1.ByHeight, doc, 0, 0).to); + let viewport = new Viewport(map.lineAt(visibleTop - marginTop * 1000 /* VP.Margin */, QueryType$1.ByHeight, doc, 0, 0).from, map.lineAt(visibleBottom + (1 - marginTop) * 1000 /* VP.Margin */, QueryType$1.ByHeight, doc, 0, 0).to); // If scrollTarget is given, make sure the viewport includes that position if (scrollTarget) { let { head } = scrollTarget.range; @@ -12792,7 +13049,7 @@ class ViewState { topPos = block.top; else topPos = block.bottom - viewHeight; - viewport = new Viewport(map.lineAt(topPos - 1000 /* Margin */ / 2, QueryType$1.ByHeight, doc, 0, 0).from, map.lineAt(topPos + viewHeight + 1000 /* Margin */ / 2, QueryType$1.ByHeight, doc, 0, 0).to); + viewport = new Viewport(map.lineAt(topPos - 1000 /* VP.Margin */ / 2, QueryType$1.ByHeight, doc, 0, 0).from, map.lineAt(topPos + viewHeight + 1000 /* VP.Margin */ / 2, QueryType$1.ByHeight, doc, 0, 0).to); } } return viewport; @@ -12809,10 +13066,10 @@ class ViewState { let { top } = this.heightMap.lineAt(from, QueryType$1.ByPos, this.state.doc, 0, 0); let { bottom } = this.heightMap.lineAt(to, QueryType$1.ByPos, this.state.doc, 0, 0); let { visibleTop, visibleBottom } = this; - return (from == 0 || top <= visibleTop - Math.max(10 /* MinCoverMargin */, Math.min(-bias, 250 /* MaxCoverMargin */))) && + return (from == 0 || top <= visibleTop - Math.max(10 /* VP.MinCoverMargin */, Math.min(-bias, 250 /* VP.MaxCoverMargin */))) && (to == this.state.doc.length || - bottom >= visibleBottom + Math.max(10 /* MinCoverMargin */, Math.min(bias, 250 /* MaxCoverMargin */))) && - (top > visibleTop - 2 * 1000 /* Margin */ && bottom < visibleBottom + 2 * 1000 /* Margin */); + bottom >= visibleBottom + Math.max(10 /* VP.MinCoverMargin */, Math.min(bias, 250 /* VP.MaxCoverMargin */))) && + (top > visibleTop - 2 * 1000 /* VP.Margin */ && bottom < visibleBottom + 2 * 1000 /* VP.Margin */); } mapLineGaps(gaps, changes) { if (!gaps.length || changes.empty) @@ -12830,46 +13087,86 @@ class ViewState { // since actual DOM coordinates aren't always available and // predictable. Relies on generous margins (see LG.Margin) to hide // the artifacts this might produce from the user. - ensureLineGaps(current) { + ensureLineGaps(current, mayMeasure) { + let wrapping = this.heightOracle.lineWrapping; + let margin = wrapping ? 10000 /* LG.MarginWrap */ : 2000 /* LG.Margin */, halfMargin = margin >> 1, doubleMargin = margin << 1; + // The non-wrapping logic won't work at all in predominantly right-to-left text. + if (this.defaultTextDirection != Direction.LTR && !wrapping) + return []; let gaps = []; - // This won't work at all in predominantly right-to-left text. - if (this.defaultTextDirection != Direction.LTR) - return gaps; + let addGap = (from, to, line, structure) => { + if (to - from < halfMargin) + return; + let sel = this.state.selection.main, avoid = [sel.from]; + if (!sel.empty) + avoid.push(sel.to); + for (let pos of avoid) { + if (pos > from && pos < to) { + addGap(from, pos - 10 /* LG.SelectionMargin */, line, structure); + addGap(pos + 10 /* LG.SelectionMargin */, to, line, structure); + return; + } + } + let gap = find(current, gap => gap.from >= line.from && gap.to <= line.to && + Math.abs(gap.from - from) < halfMargin && Math.abs(gap.to - to) < halfMargin && + !avoid.some(pos => gap.from < pos && gap.to > pos)); + if (!gap) { + // When scrolling down, snap gap ends to line starts to avoid shifts in wrapping + if (to < line.to && mayMeasure && wrapping && + mayMeasure.visibleRanges.some(r => r.from <= to && r.to >= to)) { + let lineStart = mayMeasure.moveToLineBoundary(EditorSelection.cursor(to), false, true).head; + if (lineStart > from) + to = lineStart; + } + gap = new LineGap(from, to, this.gapSize(line, from, to, structure)); + } + gaps.push(gap); + }; for (let line of this.viewportLines) { - if (line.length < 4000 /* DoubleMargin */) + if (line.length < doubleMargin) continue; let structure = lineStructure(line.from, line.to, this.stateDeco); - if (structure.total < 4000 /* DoubleMargin */) + if (structure.total < doubleMargin) continue; + let target = this.scrollTarget ? this.scrollTarget.range.head : null; let viewFrom, viewTo; - if (this.heightOracle.lineWrapping) { - let marginHeight = (2000 /* Margin */ / this.heightOracle.lineLength) * this.heightOracle.lineHeight; - viewFrom = findPosition(structure, (this.visibleTop - line.top - marginHeight) / line.height); - viewTo = findPosition(structure, (this.visibleBottom - line.top + marginHeight) / line.height); + if (wrapping) { + let marginHeight = (margin / this.heightOracle.lineLength) * this.heightOracle.lineHeight; + let top, bot; + if (target != null) { + let targetFrac = findFraction(structure, target); + let spaceFrac = ((this.visibleBottom - this.visibleTop) / 2 + marginHeight) / line.height; + top = targetFrac - spaceFrac; + bot = targetFrac + spaceFrac; + } + else { + top = (this.visibleTop - line.top - marginHeight) / line.height; + bot = (this.visibleBottom - line.top + marginHeight) / line.height; + } + viewFrom = findPosition(structure, top); + viewTo = findPosition(structure, bot); } else { let totalWidth = structure.total * this.heightOracle.charWidth; - let marginWidth = 2000 /* Margin */ * this.heightOracle.charWidth; - viewFrom = findPosition(structure, (this.pixelViewport.left - marginWidth) / totalWidth); - viewTo = findPosition(structure, (this.pixelViewport.right + marginWidth) / totalWidth); + let marginWidth = margin * this.heightOracle.charWidth; + let left, right; + if (target != null) { + let targetFrac = findFraction(structure, target); + let spaceFrac = ((this.pixelViewport.right - this.pixelViewport.left) / 2 + marginWidth) / totalWidth; + left = targetFrac - spaceFrac; + right = targetFrac + spaceFrac; + } + else { + left = (this.pixelViewport.left - marginWidth) / totalWidth; + right = (this.pixelViewport.right + marginWidth) / totalWidth; + } + viewFrom = findPosition(structure, left); + viewTo = findPosition(structure, right); } - let outside = []; if (viewFrom > line.from) - outside.push({ from: line.from, to: viewFrom }); + addGap(line.from, viewFrom, line, structure); if (viewTo < line.to) - outside.push({ from: viewTo, to: line.to }); - let sel = this.state.selection.main; - // Make sure the gaps don't cover a selection end - if (sel.from >= line.from && sel.from <= line.to) - cutRange(outside, sel.from - 10 /* SelectionMargin */, sel.from + 10 /* SelectionMargin */); - if (!sel.empty && sel.to >= line.from && sel.to <= line.to) - cutRange(outside, sel.to - 10 /* SelectionMargin */, sel.to + 10 /* SelectionMargin */); - for (let { from, to } of outside) - if (to - from > 1000 /* HalfMargin */) { - gaps.push(find(current, gap => gap.from >= line.from && gap.to <= line.to && - Math.abs(gap.from - from) < 1000 /* HalfMargin */ && Math.abs(gap.to - to) < 1000 /* HalfMargin */) || - new LineGap(from, to, this.gapSize(line, from, to, structure))); - } + addGap(viewTo, line.to, line, structure); } return gaps; } @@ -12900,7 +13197,7 @@ class ViewState { let changed = ranges.length != this.visibleRanges.length || this.visibleRanges.some((r, i) => r.from != ranges[i].from || r.to != ranges[i].to); this.visibleRanges = ranges; - return changed ? 4 /* Viewport */ : 0; + return changed ? 4 /* UpdateFlag.Viewport */ : 0; } lineBlockAt(pos) { return (pos >= this.viewport.from && pos <= this.viewport.to && this.viewportLines.find(b => b.from <= pos && b.to >= pos)) || @@ -12967,20 +13264,6 @@ function findFraction(structure, pos) { } return counted / structure.total; } -function cutRange(ranges, from, to) { - for (let i = 0; i < ranges.length; i++) { - let r = ranges[i]; - if (r.from < to && r.to > from) { - let pieces = []; - if (r.from < from) - pieces.push({ from: r.from, to: from }); - if (r.to > to) - pieces.push({ from: to, to: r.to }); - ranges.splice(i, 1, ...pieces); - i += pieces.length - 1; - } - } -} function find(array, f) { for (let val of array) if (f(val)) @@ -13006,7 +13289,7 @@ class BigScaler { vpHeight += bottom - top; return { from, to, top, bottom, domTop: 0, domBottom: 0 }; }); - this.scale = (7000000 /* MaxDOMHeight */ - vpHeight) / (heightMap.height - vpHeight); + this.scale = (7000000 /* VP.MaxDOMHeight */ - vpHeight) / (heightMap.height - vpHeight); for (let obj of this.viewports) { obj.domTop = domBase + (obj.top - base) * this.scale; domBase = obj.domBottom = obj.domTop + (obj.bottom - obj.top); @@ -13091,6 +13374,7 @@ const baseTheme$1$2 = /*@__PURE__*/buildTheme("." + baseThemeID, { ".cm-content": { margin: 0, flexGrow: 2, + flexShrink: 0, minHeight: "100%", display: "block", whiteSpace: "pre", @@ -13106,7 +13390,8 @@ const baseTheme$1$2 = /*@__PURE__*/buildTheme("." + baseThemeID, { whiteSpace_fallback: "pre-wrap", whiteSpace: "break-spaces", wordBreak: "break-word", - overflowWrap: "anywhere" + overflowWrap: "anywhere", + flexShrink: 1 }, "&light .cm-content": { caretColor: "black" }, "&dark .cm-content": { caretColor: "white" }, @@ -13144,8 +13429,8 @@ const baseTheme$1$2 = /*@__PURE__*/buildTheme("." + baseThemeID, { // Two animations defined so that we can switch between them to // restart the animation without forcing another style // recomputation. - "@keyframes cm-blink": { "0%": {}, "50%": { visibility: "hidden" }, "100%": {} }, - "@keyframes cm-blink2": { "0%": {}, "50%": { visibility: "hidden" }, "100%": {} }, + "@keyframes cm-blink": { "0%": {}, "50%": { opacity: 0 }, "100%": {} }, + "@keyframes cm-blink2": { "0%": {}, "50%": { opacity: 0 }, "100%": {} }, ".cm-cursor, .cm-dropCursor": { position: "absolute", borderLeft: "1.2px solid black", @@ -13161,11 +13446,12 @@ const baseTheme$1$2 = /*@__PURE__*/buildTheme("." + baseThemeID, { "&.cm-focused .cm-cursor": { display: "block" }, - "&light .cm-activeLine": { backgroundColor: "#f3f9ff" }, - "&dark .cm-activeLine": { backgroundColor: "#223039" }, + "&light .cm-activeLine": { backgroundColor: "#cceeff44" }, + "&dark .cm-activeLine": { backgroundColor: "#99eeff33" }, "&light .cm-specialChar": { color: "red" }, "&dark .cm-specialChar": { color: "#f78" }, ".cm-gutters": { + flexShrink: 0, display: "flex", height: "100%", boxSizing: "border-box", @@ -13232,6 +13518,7 @@ const baseTheme$1$2 = /*@__PURE__*/buildTheme("." + baseThemeID, { ".cm-widgetBuffer": { verticalAlign: "text-top", height: "1em", + width: 0, display: "inline" }, ".cm-placeholder": { @@ -13276,6 +13563,236 @@ const baseTheme$1$2 = /*@__PURE__*/buildTheme("." + baseThemeID, { } }, lightDarkIDs); +class DOMChange { + constructor(view, start, end, typeOver) { + this.typeOver = typeOver; + this.bounds = null; + this.text = ""; + let { impreciseHead: iHead, impreciseAnchor: iAnchor } = view.docView; + if (start > -1 && !view.state.readOnly && (this.bounds = view.docView.domBoundsAround(start, end, 0))) { + let selPoints = iHead || iAnchor ? [] : selectionPoints(view); + let reader = new DOMReader(selPoints, view.state); + reader.readRange(this.bounds.startDOM, this.bounds.endDOM); + this.text = reader.text; + this.newSel = selectionFromPoints(selPoints, this.bounds.from); + } + else { + let domSel = view.observer.selectionRange; + let head = iHead && iHead.node == domSel.focusNode && iHead.offset == domSel.focusOffset || + !contains(view.contentDOM, domSel.focusNode) + ? view.state.selection.main.head + : view.docView.posFromDOM(domSel.focusNode, domSel.focusOffset); + let anchor = iAnchor && iAnchor.node == domSel.anchorNode && iAnchor.offset == domSel.anchorOffset || + !contains(view.contentDOM, domSel.anchorNode) + ? view.state.selection.main.anchor + : view.docView.posFromDOM(domSel.anchorNode, domSel.anchorOffset); + this.newSel = EditorSelection.single(anchor, head); + } + } +} +function applyDOMChange(view, domChange) { + let change; + let { newSel } = domChange, sel = view.state.selection.main; + if (domChange.bounds) { + let { from, to } = domChange.bounds; + let preferredPos = sel.from, preferredSide = null; + // Prefer anchoring to end when Backspace is pressed (or, on + // Android, when something was deleted) + if (view.inputState.lastKeyCode === 8 && view.inputState.lastKeyTime > Date.now() - 100 || + browser.android && domChange.text.length < to - from) { + preferredPos = sel.to; + preferredSide = "end"; + } + let diff = findDiff(view.state.doc.sliceString(from, to, LineBreakPlaceholder), domChange.text, preferredPos - from, preferredSide); + if (diff) { + // Chrome inserts two newlines when pressing shift-enter at the + // end of a line. DomChange drops one of those. + if (browser.chrome && view.inputState.lastKeyCode == 13 && + diff.toB == diff.from + 2 && domChange.text.slice(diff.from, diff.toB) == LineBreakPlaceholder + LineBreakPlaceholder) + diff.toB--; + change = { from: from + diff.from, to: from + diff.toA, + insert: Text.of(domChange.text.slice(diff.from, diff.toB).split(LineBreakPlaceholder)) }; + } + } + else if (newSel && (!view.hasFocus || !view.state.facet(editable) || newSel.main.eq(sel))) { + newSel = null; + } + if (!change && !newSel) + return false; + if (!change && domChange.typeOver && !sel.empty && newSel && newSel.main.empty) { + // Heuristic to notice typing over a selected character + change = { from: sel.from, to: sel.to, insert: view.state.doc.slice(sel.from, sel.to) }; + } + else if (change && change.from >= sel.from && change.to <= sel.to && + (change.from != sel.from || change.to != sel.to) && + (sel.to - sel.from) - (change.to - change.from) <= 4) { + // If the change is inside the selection and covers most of it, + // assume it is a selection replace (with identical characters at + // the start/end not included in the diff) + change = { + from: sel.from, to: sel.to, + insert: view.state.doc.slice(sel.from, change.from).append(change.insert).append(view.state.doc.slice(change.to, sel.to)) + }; + } + else if ((browser.mac || browser.android) && change && change.from == change.to && change.from == sel.head - 1 && + /^\. ?$/.test(change.insert.toString())) { + // Detect insert-period-on-double-space Mac and Android behavior, + // and transform it into a regular space insert. + if (newSel && change.insert.length == 2) + newSel = EditorSelection.single(newSel.main.anchor - 1, newSel.main.head - 1); + change = { from: sel.from, to: sel.to, insert: Text.of([" "]) }; + } + else if (browser.chrome && change && change.from == change.to && change.from == sel.head && + change.insert.toString() == "\n " && view.lineWrapping) { + // In Chrome, if you insert a space at the start of a wrapped + // line, it will actually insert a newline and a space, causing a + // bogus new line to be created in CodeMirror (#968) + if (newSel) + newSel = EditorSelection.single(newSel.main.anchor - 1, newSel.main.head - 1); + change = { from: sel.from, to: sel.to, insert: Text.of([" "]) }; + } + if (change) { + let startState = view.state; + if (browser.ios && view.inputState.flushIOSKey(view)) + return true; + // Android browsers don't fire reasonable key events for enter, + // backspace, or delete. So this detects changes that look like + // they're caused by those keys, and reinterprets them as key + // events. (Some of these keys are also handled by beforeinput + // events and the pendingAndroidKey mechanism, but that's not + // reliable in all situations.) + if (browser.android && + ((change.from == sel.from && change.to == sel.to && + change.insert.length == 1 && change.insert.lines == 2 && + dispatchKey(view.contentDOM, "Enter", 13)) || + (change.from == sel.from - 1 && change.to == sel.to && change.insert.length == 0 && + dispatchKey(view.contentDOM, "Backspace", 8)) || + (change.from == sel.from && change.to == sel.to + 1 && change.insert.length == 0 && + dispatchKey(view.contentDOM, "Delete", 46)))) + return true; + let text = change.insert.toString(); + if (view.state.facet(inputHandler$1).some(h => h(view, change.from, change.to, text))) + return true; + if (view.inputState.composing >= 0) + view.inputState.composing++; + let tr; + if (change.from >= sel.from && change.to <= sel.to && change.to - change.from >= (sel.to - sel.from) / 3 && + (!newSel || newSel.main.empty && newSel.main.from == change.from + change.insert.length) && + view.inputState.composing < 0) { + let before = sel.from < change.from ? startState.sliceDoc(sel.from, change.from) : ""; + let after = sel.to > change.to ? startState.sliceDoc(change.to, sel.to) : ""; + tr = startState.replaceSelection(view.state.toText(before + change.insert.sliceString(0, undefined, view.state.lineBreak) + after)); + } + else { + let changes = startState.changes(change); + let mainSel = newSel && !startState.selection.main.eq(newSel.main) && newSel.main.to <= changes.newLength + ? newSel.main : undefined; + // Try to apply a composition change to all cursors + if (startState.selection.ranges.length > 1 && view.inputState.composing >= 0 && + change.to <= sel.to && change.to >= sel.to - 10) { + let replaced = view.state.sliceDoc(change.from, change.to); + let compositionRange = compositionSurroundingNode(view) || view.state.doc.lineAt(sel.head); + let offset = sel.to - change.to, size = sel.to - sel.from; + tr = startState.changeByRange(range => { + if (range.from == sel.from && range.to == sel.to) + return { changes, range: mainSel || range.map(changes) }; + let to = range.to - offset, from = to - replaced.length; + if (range.to - range.from != size || view.state.sliceDoc(from, to) != replaced || + // Unfortunately, there's no way to make multiple + // changes in the same node work without aborting + // composition, so cursors in the composition range are + // ignored. + compositionRange && range.to >= compositionRange.from && range.from <= compositionRange.to) + return { range }; + let rangeChanges = startState.changes({ from, to, insert: change.insert }), selOff = range.to - sel.to; + return { + changes: rangeChanges, + range: !mainSel ? range.map(rangeChanges) : + EditorSelection.range(Math.max(0, mainSel.anchor + selOff), Math.max(0, mainSel.head + selOff)) + }; + }); + } + else { + tr = { + changes, + selection: mainSel && startState.selection.replaceRange(mainSel) + }; + } + } + let userEvent = "input.type"; + if (view.composing) { + userEvent += ".compose"; + if (view.inputState.compositionFirstChange) { + userEvent += ".start"; + view.inputState.compositionFirstChange = false; + } + } + view.dispatch(tr, { scrollIntoView: true, userEvent }); + return true; + } + else if (newSel && !newSel.main.eq(sel)) { + let scrollIntoView = false, userEvent = "select"; + if (view.inputState.lastSelectionTime > Date.now() - 50) { + if (view.inputState.lastSelectionOrigin == "select") + scrollIntoView = true; + userEvent = view.inputState.lastSelectionOrigin; + } + view.dispatch({ selection: newSel, scrollIntoView, userEvent }); + return true; + } + else { + return false; + } +} +function findDiff(a, b, preferredPos, preferredSide) { + let minLen = Math.min(a.length, b.length); + let from = 0; + while (from < minLen && a.charCodeAt(from) == b.charCodeAt(from)) + from++; + if (from == minLen && a.length == b.length) + return null; + let toA = a.length, toB = b.length; + while (toA > 0 && toB > 0 && a.charCodeAt(toA - 1) == b.charCodeAt(toB - 1)) { + toA--; + toB--; + } + if (preferredSide == "end") { + let adjust = Math.max(0, from - Math.min(toA, toB)); + preferredPos -= toA + adjust - from; + } + if (toA < from && a.length < b.length) { + let move = preferredPos <= from && preferredPos >= toA ? from - preferredPos : 0; + from -= move; + toB = from + (toB - toA); + toA = from; + } + else if (toB < from) { + let move = preferredPos <= from && preferredPos >= toB ? from - preferredPos : 0; + from -= move; + toA = from + (toA - toB); + toB = from; + } + return { from, toA, toB }; +} +function selectionPoints(view) { + let result = []; + if (view.root.activeElement != view.contentDOM) + return result; + let { anchorNode, anchorOffset, focusNode, focusOffset } = view.observer.selectionRange; + if (anchorNode) { + result.push(new DOMPoint(anchorNode, anchorOffset)); + if (focusNode != anchorNode || focusOffset != anchorOffset) + result.push(new DOMPoint(focusNode, focusOffset)); + } + return result; +} +function selectionFromPoints(points, base) { + if (points.length == 0) + return null; + let anchor = points[0].pos, head = points.length == 2 ? points[1].pos : anchor; + return anchor > -1 && head > -1 ? EditorSelection.single(anchor + base, head + base) : null; +} + const observeOptions = { childList: true, characterData: true, @@ -13287,10 +13804,8 @@ const observeOptions = { // DOMCharacterDataModified there const useCharData = browser.ie && browser.ie_version <= 11; class DOMObserver { - constructor(view, onChange, onScrollChanged) { + constructor(view) { this.view = view; - this.onChange = onChange; - this.onScrollChanged = onScrollChanged; this.active = false; // The known selection. Kept in our own object, as opposed to just // directly accessing the selection because: @@ -13305,6 +13820,8 @@ class DOMObserver { this.resizeTimeout = -1; this.queue = []; this.delayedAndroidKey = null; + this.flushingAndroidKey = -1; + this.lastChange = 0; this.scrollTargets = []; this.intersection = null; this.resize = null; @@ -13341,17 +13858,19 @@ class DOMObserver { this.flushSoon(); }; this.onSelectionChange = this.onSelectionChange.bind(this); - window.addEventListener("resize", this.onResize = this.onResize.bind(this)); + this.onResize = this.onResize.bind(this); + this.onPrint = this.onPrint.bind(this); + this.onScroll = this.onScroll.bind(this); if (typeof ResizeObserver == "function") { this.resize = new ResizeObserver(() => { - if (this.view.docView.lastUpdate < Date.now() - 75) + var _a; + if (((_a = this.view.docView) === null || _a === void 0 ? void 0 : _a.lastUpdate) < Date.now() - 75) this.onResize(); }); this.resize.observe(view.scrollDOM); } - window.addEventListener("beforeprint", this.onPrint = this.onPrint.bind(this)); + this.addWindowListeners(this.win = view.win); this.start(); - window.addEventListener("scroll", this.onScroll = this.onScroll.bind(this)); if (typeof IntersectionObserver == "function") { this.intersection = new IntersectionObserver(entries => { if (this.parentCheck < 0) @@ -13370,7 +13889,11 @@ class DOMObserver { } this.listenForScroll(); this.readSelectionRange(); - this.dom.ownerDocument.addEventListener("selectionchange", this.onSelectionChange); + } + onScrollChanged(e) { + this.view.inputState.runScrollHandlers(this.view, e); + if (this.intersecting) + this.view.measure(); } onScroll(e) { if (this.intersecting) @@ -13401,14 +13924,18 @@ class DOMObserver { } } onSelectionChange(event) { + let wasChanged = this.selectionChanged; if (!this.readSelectionRange() || this.delayedAndroidKey) return; let { view } = this, sel = this.selectionRange; if (view.state.facet(editable) ? view.root.activeElement != this.dom : !hasSelection(view.dom, sel)) return; let context = sel.anchorNode && view.docView.nearest(sel.anchorNode); - if (context && context.ignoreEvent(event)) + if (context && context.ignoreEvent(event)) { + if (!wasChanged) + this.selectionChanged = false; return; + } // Deletions on IE11 fire their events in the wrong order, giving // us a selection change event before the DOM changes are // reported. @@ -13422,15 +13949,30 @@ class DOMObserver { this.flush(false); } readSelectionRange() { - let { root } = this.view, domSel = getSelection(root); + let { view } = this; // The Selection object is broken in shadow roots in Safari. See - // https://github.com/codemirror/codemirror.next/issues/414 - let range = browser.safari && root.nodeType == 11 && deepActiveElement() == this.view.contentDOM && - safariSelectionRangeHack(this.view) || domSel; - if (this.selectionRange.eq(range)) + // https://github.com/codemirror/dev/issues/414 + let range = browser.safari && view.root.nodeType == 11 && + deepActiveElement(this.dom.ownerDocument) == this.dom && + safariSelectionRangeHack(this.view) || getSelection(view.root); + if (!range || this.selectionRange.eq(range)) + return false; + let local = hasSelection(this.dom, range); + // Detect the situation where the browser has, on focus, moved the + // selection to the start of the content element. Reset it to the + // position from the editor state. + if (local && !this.selectionChanged && + view.inputState.lastFocusTime > Date.now() - 200 && + view.inputState.lastTouchTime < Date.now() - 300 && + atElementStart(this.dom, range)) { + this.view.inputState.lastFocusTime = 0; + view.docView.updateSelection(); return false; + } this.selectionRange.setRange(range); - return this.selectionChanged = true; + if (local) + this.selectionChanged = true; + return true; } setSelectionRange(anchor, head) { this.selectionRange.set(anchor.node, anchor.offset, head.node, head.offset); @@ -13508,37 +14050,48 @@ class DOMObserver { // composition events that, when interrupted, cause text duplication // or other kinds of corruption. This hack makes the editor back off // from handling DOM changes for a moment when such a key is - // detected (via beforeinput or keydown), and then dispatches the - // key event, throwing away the DOM changes if it gets handled. + // detected (via beforeinput or keydown), and then tries to flush + // them or, if that has no effect, dispatches the given key. delayAndroidKey(key, keyCode) { - if (!this.delayedAndroidKey) - requestAnimationFrame(() => { + var _a; + if (!this.delayedAndroidKey) { + let flush = () => { let key = this.delayedAndroidKey; - this.delayedAndroidKey = null; - let startState = this.view.state; - this.readSelectionRange(); - if (dispatchKey(this.view.contentDOM, key.key, key.keyCode)) - this.processRecords(); - else - this.flush(); - if (this.view.state == startState) - this.view.update([]); - }); + if (key) { + this.clearDelayedAndroidKey(); + if (!this.flush() && key.force) + dispatchKey(this.dom, key.key, key.keyCode); + } + }; + this.flushingAndroidKey = this.view.win.requestAnimationFrame(flush); + } // Since backspace beforeinput is sometimes signalled spuriously, // Enter always takes precedence. if (!this.delayedAndroidKey || key == "Enter") - this.delayedAndroidKey = { key, keyCode }; + this.delayedAndroidKey = { + key, keyCode, + // Only run the key handler when no changes are detected if + // this isn't coming right after another change, in which case + // it is probably part of a weird chain of updates, and should + // be ignored if it returns the DOM to its previous state. + force: this.lastChange < Date.now() - 50 || !!((_a = this.delayedAndroidKey) === null || _a === void 0 ? void 0 : _a.force) + }; + } + clearDelayedAndroidKey() { + this.win.cancelAnimationFrame(this.flushingAndroidKey); + this.delayedAndroidKey = null; + this.flushingAndroidKey = -1; } flushSoon() { if (this.delayedFlush < 0) - this.delayedFlush = window.setTimeout(() => { this.delayedFlush = -1; this.flush(); }, 20); + this.delayedFlush = this.view.win.requestAnimationFrame(() => { this.delayedFlush = -1; this.flush(); }); } forceFlush() { if (this.delayedFlush >= 0) { - window.clearTimeout(this.delayedFlush); + this.view.win.cancelAnimationFrame(this.delayedFlush); this.delayedFlush = -1; - this.flush(); } + this.flush(); } processRecords() { let records = this.queue; @@ -13563,25 +14116,35 @@ class DOMObserver { } return { from, to, typeOver }; } + readChange() { + let { from, to, typeOver } = this.processRecords(); + let newSel = this.selectionChanged && hasSelection(this.dom, this.selectionRange); + if (from < 0 && !newSel) + return null; + if (from > -1) + this.lastChange = Date.now(); + this.view.inputState.lastFocusTime = 0; + this.selectionChanged = false; + return new DOMChange(this.view, from, to, typeOver); + } // Apply pending changes, if any flush(readSelection = true) { // Completely hold off flushing when pending keys are set—the code // managing those will make sure processRecords is called and the // view is resynchronized after if (this.delayedFlush >= 0 || this.delayedAndroidKey) - return; + return false; if (readSelection) this.readSelectionRange(); - let { from, to, typeOver } = this.processRecords(); - let newSel = this.selectionChanged && hasSelection(this.dom, this.selectionRange); - if (from < 0 && !newSel) - return; - this.selectionChanged = false; + let domChange = this.readChange(); + if (!domChange) + return false; let startState = this.view.state; - this.onChange(from, to, typeOver); + let handled = applyDOMChange(this.view, domChange); // The view wasn't updated if (this.view.state == startState) this.view.update([]); + return handled; } readMutation(rec) { let cView = this.view.docView.nearest(rec.target); @@ -13589,7 +14152,7 @@ class DOMObserver { return null; cView.markDirty(rec.type == "attributes"); if (rec.type == "attributes") - cView.dirty |= 4 /* Attrs */; + cView.dirty |= 4 /* Dirty.Attrs */; if (rec.type == "childList") { let childBefore = findChild(cView, rec.previousSibling || rec.target.previousSibling, -1); let childAfter = findChild(cView, rec.nextSibling || rec.target.nextSibling, 1); @@ -13603,6 +14166,25 @@ class DOMObserver { return null; } } + setWindow(win) { + if (win != this.win) { + this.removeWindowListeners(this.win); + this.win = win; + this.addWindowListeners(this.win); + } + } + addWindowListeners(win) { + win.addEventListener("resize", this.onResize); + win.addEventListener("beforeprint", this.onPrint); + win.addEventListener("scroll", this.onScroll); + win.document.addEventListener("selectionchange", this.onSelectionChange); + } + removeWindowListeners(win) { + win.removeEventListener("scroll", this.onScroll); + win.removeEventListener("resize", this.onResize); + win.removeEventListener("beforeprint", this.onPrint); + win.document.removeEventListener("selectionchange", this.onSelectionChange); + } destroy() { var _a, _b, _c; this.stop(); @@ -13611,12 +14193,11 @@ class DOMObserver { (_c = this.resize) === null || _c === void 0 ? void 0 : _c.disconnect(); for (let dom of this.scrollTargets) dom.removeEventListener("scroll", this.onScroll); - window.removeEventListener("scroll", this.onScroll); - window.removeEventListener("resize", this.onResize); - window.removeEventListener("beforeprint", this.onPrint); - this.dom.ownerDocument.removeEventListener("selectionchange", this.onSelectionChange); + this.removeWindowListeners(this.win); clearTimeout(this.parentCheck); clearTimeout(this.resizeTimeout); + this.win.cancelAnimationFrame(this.delayedFlush); + this.win.cancelAnimationFrame(this.flushingAndroidKey); } } function findChild(cView, dom, dir) { @@ -13643,7 +14224,7 @@ function safariSelectionRangeHack(view) { found = event.getTargetRanges()[0]; } view.contentDOM.addEventListener("beforeinput", read, true); - document.execCommand("indent"); + view.dom.ownerDocument.execCommand("indent"); view.contentDOM.removeEventListener("beforeinput", read, true); if (!found) return null; @@ -13658,208 +14239,6 @@ function safariSelectionRangeHack(view) { return { anchorNode, anchorOffset, focusNode, focusOffset }; } -function applyDOMChange(view, start, end, typeOver) { - let change, newSel; - let sel = view.state.selection.main; - if (start > -1) { - let bounds = view.docView.domBoundsAround(start, end, 0); - if (!bounds || view.state.readOnly) - return; - let { from, to } = bounds; - let selPoints = view.docView.impreciseHead || view.docView.impreciseAnchor ? [] : selectionPoints(view); - let reader = new DOMReader(selPoints, view.state); - reader.readRange(bounds.startDOM, bounds.endDOM); - let preferredPos = sel.from, preferredSide = null; - // Prefer anchoring to end when Backspace is pressed (or, on - // Android, when something was deleted) - if (view.inputState.lastKeyCode === 8 && view.inputState.lastKeyTime > Date.now() - 100 || - browser.android && reader.text.length < to - from) { - preferredPos = sel.to; - preferredSide = "end"; - } - let diff = findDiff(view.state.doc.sliceString(from, to, LineBreakPlaceholder), reader.text, preferredPos - from, preferredSide); - if (diff) { - // Chrome inserts two newlines when pressing shift-enter at the - // end of a line. This drops one of those. - if (browser.chrome && view.inputState.lastKeyCode == 13 && - diff.toB == diff.from + 2 && reader.text.slice(diff.from, diff.toB) == LineBreakPlaceholder + LineBreakPlaceholder) - diff.toB--; - change = { from: from + diff.from, to: from + diff.toA, - insert: Text.of(reader.text.slice(diff.from, diff.toB).split(LineBreakPlaceholder)) }; - } - newSel = selectionFromPoints(selPoints, from); - } - else if (view.hasFocus || !view.state.facet(editable)) { - let domSel = view.observer.selectionRange; - let { impreciseHead: iHead, impreciseAnchor: iAnchor } = view.docView; - let head = iHead && iHead.node == domSel.focusNode && iHead.offset == domSel.focusOffset || - !contains(view.contentDOM, domSel.focusNode) - ? view.state.selection.main.head - : view.docView.posFromDOM(domSel.focusNode, domSel.focusOffset); - let anchor = iAnchor && iAnchor.node == domSel.anchorNode && iAnchor.offset == domSel.anchorOffset || - !contains(view.contentDOM, domSel.anchorNode) - ? view.state.selection.main.anchor - : view.docView.posFromDOM(domSel.anchorNode, domSel.anchorOffset); - if (head != sel.head || anchor != sel.anchor) - newSel = EditorSelection.single(anchor, head); - } - if (!change && !newSel) - return; - // Heuristic to notice typing over a selected character - if (!change && typeOver && !sel.empty && newSel && newSel.main.empty) - change = { from: sel.from, to: sel.to, insert: view.state.doc.slice(sel.from, sel.to) }; - // If the change is inside the selection and covers most of it, - // assume it is a selection replace (with identical characters at - // the start/end not included in the diff) - else if (change && change.from >= sel.from && change.to <= sel.to && - (change.from != sel.from || change.to != sel.to) && - (sel.to - sel.from) - (change.to - change.from) <= 4) - change = { - from: sel.from, to: sel.to, - insert: view.state.doc.slice(sel.from, change.from).append(change.insert).append(view.state.doc.slice(change.to, sel.to)) - }; - // Detect insert-period-on-double-space Mac behavior, and transform - // it into a regular space insert. - else if (browser.mac && change && change.from == change.to && change.from == sel.head - 1 && - change.insert.toString() == ".") - change = { from: sel.from, to: sel.to, insert: Text.of([" "]) }; - if (change) { - let startState = view.state; - if (browser.ios && view.inputState.flushIOSKey(view)) - return; - // Android browsers don't fire reasonable key events for enter, - // backspace, or delete. So this detects changes that look like - // they're caused by those keys, and reinterprets them as key - // events. (Some of these keys are also handled by beforeinput - // events and the pendingAndroidKey mechanism, but that's not - // reliable in all situations.) - if (browser.android && - ((change.from == sel.from && change.to == sel.to && - change.insert.length == 1 && change.insert.lines == 2 && - dispatchKey(view.contentDOM, "Enter", 13)) || - (change.from == sel.from - 1 && change.to == sel.to && change.insert.length == 0 && - dispatchKey(view.contentDOM, "Backspace", 8)) || - (change.from == sel.from && change.to == sel.to + 1 && change.insert.length == 0 && - dispatchKey(view.contentDOM, "Delete", 46)))) - return; - let text = change.insert.toString(); - if (view.state.facet(inputHandler$1).some(h => h(view, change.from, change.to, text))) - return; - if (view.inputState.composing >= 0) - view.inputState.composing++; - let tr; - if (change.from >= sel.from && change.to <= sel.to && change.to - change.from >= (sel.to - sel.from) / 3 && - (!newSel || newSel.main.empty && newSel.main.from == change.from + change.insert.length) && - view.inputState.composing < 0) { - let before = sel.from < change.from ? startState.sliceDoc(sel.from, change.from) : ""; - let after = sel.to > change.to ? startState.sliceDoc(change.to, sel.to) : ""; - tr = startState.replaceSelection(view.state.toText(before + change.insert.sliceString(0, undefined, view.state.lineBreak) + after)); - } - else { - let changes = startState.changes(change); - let mainSel = newSel && !startState.selection.main.eq(newSel.main) && newSel.main.to <= changes.newLength - ? newSel.main : undefined; - // Try to apply a composition change to all cursors - if (startState.selection.ranges.length > 1 && view.inputState.composing >= 0 && - change.to <= sel.to && change.to >= sel.to - 10) { - let replaced = view.state.sliceDoc(change.from, change.to); - let compositionRange = compositionSurroundingNode(view) || view.state.doc.lineAt(sel.head); - let offset = sel.to - change.to, size = sel.to - sel.from; - tr = startState.changeByRange(range => { - if (range.from == sel.from && range.to == sel.to) - return { changes, range: mainSel || range.map(changes) }; - let to = range.to - offset, from = to - replaced.length; - if (range.to - range.from != size || view.state.sliceDoc(from, to) != replaced || - // Unfortunately, there's no way to make multiple - // changes in the same node work without aborting - // composition, so cursors in the composition range are - // ignored. - compositionRange && range.to >= compositionRange.from && range.from <= compositionRange.to) - return { range }; - let rangeChanges = startState.changes({ from, to, insert: change.insert }), selOff = range.to - sel.to; - return { - changes: rangeChanges, - range: !mainSel ? range.map(rangeChanges) : - EditorSelection.range(Math.max(0, mainSel.anchor + selOff), Math.max(0, mainSel.head + selOff)) - }; - }); - } - else { - tr = { - changes, - selection: mainSel && startState.selection.replaceRange(mainSel) - }; - } - } - let userEvent = "input.type"; - if (view.composing) { - userEvent += ".compose"; - if (view.inputState.compositionFirstChange) { - userEvent += ".start"; - view.inputState.compositionFirstChange = false; - } - } - view.dispatch(tr, { scrollIntoView: true, userEvent }); - } - else if (newSel && !newSel.main.eq(sel)) { - let scrollIntoView = false, userEvent = "select"; - if (view.inputState.lastSelectionTime > Date.now() - 50) { - if (view.inputState.lastSelectionOrigin == "select") - scrollIntoView = true; - userEvent = view.inputState.lastSelectionOrigin; - } - view.dispatch({ selection: newSel, scrollIntoView, userEvent }); - } -} -function findDiff(a, b, preferredPos, preferredSide) { - let minLen = Math.min(a.length, b.length); - let from = 0; - while (from < minLen && a.charCodeAt(from) == b.charCodeAt(from)) - from++; - if (from == minLen && a.length == b.length) - return null; - let toA = a.length, toB = b.length; - while (toA > 0 && toB > 0 && a.charCodeAt(toA - 1) == b.charCodeAt(toB - 1)) { - toA--; - toB--; - } - if (preferredSide == "end") { - let adjust = Math.max(0, from - Math.min(toA, toB)); - preferredPos -= toA + adjust - from; - } - if (toA < from && a.length < b.length) { - let move = preferredPos <= from && preferredPos >= toA ? from - preferredPos : 0; - from -= move; - toB = from + (toB - toA); - toA = from; - } - else if (toB < from) { - let move = preferredPos <= from && preferredPos >= toB ? from - preferredPos : 0; - from -= move; - toA = from + (toA - toB); - toB = from; - } - return { from, toA, toB }; -} -function selectionPoints(view) { - let result = []; - if (view.root.activeElement != view.contentDOM) - return result; - let { anchorNode, anchorOffset, focusNode, focusOffset } = view.observer.selectionRange; - if (anchorNode) { - result.push(new DOMPoint(anchorNode, anchorOffset)); - if (focusNode != anchorNode || focusOffset != anchorOffset) - result.push(new DOMPoint(focusNode, focusOffset)); - } - return result; -} -function selectionFromPoints(points, base) { - if (points.length == 0) - return null; - let anchor = points[0].pos, head = points.length == 2 ? points[1].pos : anchor; - return anchor > -1 && head > -1 ? EditorSelection.single(anchor + base, head + base) : null; -} - // The editor's update state machine looks something like this: // // Idle → Updating ⇆ Idle (unchecked) → Measuring → Idle @@ -13885,11 +14264,7 @@ class EditorView { option, or put `view.dom` into your document after creating a view, so that the user can see the editor. */ - constructor( - /** - Initialization options. - */ - config = {}) { + constructor(config = {}) { this.plugins = []; this.pluginMap = new Map; this.editorAttrs = {}; @@ -13899,7 +14274,7 @@ class EditorView { /** @internal */ - this.updateState = 2 /* Updating */; + this.updateState = 2 /* UpdateState.Updating */; /** @internal */ @@ -13921,24 +14296,18 @@ class EditorView { this.dom.appendChild(this.scrollDOM); this._dispatch = config.dispatch || ((tr) => this.update([tr])); this.dispatch = this.dispatch.bind(this); - this.root = (config.root || getRoot(config.parent) || document); - this.viewState = new ViewState(config.state || EditorState.create()); + this._root = (config.root || getRoot(config.parent) || document); + this.viewState = new ViewState(config.state || EditorState.create(config)); this.plugins = this.state.facet(viewPlugin).map(spec => new PluginInstance(spec)); for (let plugin of this.plugins) plugin.update(this); - this.observer = new DOMObserver(this, (from, to, typeOver) => { - applyDOMChange(this, from, to, typeOver); - }, event => { - this.inputState.runScrollHandlers(this, event); - if (this.observer.intersecting) - this.measure(); - }); + this.observer = new DOMObserver(this); this.inputState = new InputState(this); this.inputState.ensureHandlers(this, this.plugins); this.docView = new DocView(this); this.mountStyles(); this.updateAttrs(); - this.updateState = 0 /* Idle */; + this.updateState = 0 /* UpdateState.Idle */; this.requestMeasure(); if (config.parent) config.parent.appendChild(this.dom); @@ -13982,6 +14351,14 @@ class EditorView { composition there. */ get compositionStarted() { return this.inputState.composing >= 0; } + /** + The document or shadow root that the view lives in. + */ + get root() { return this._root; } + /** + @internal + */ + get win() { return this.dom.ownerDocument.defaultView || window; } dispatch(...input) { this._dispatch(input.length == 1 && input[0] instanceof Transaction ? input[0] : this.state.update(...input)); @@ -13995,9 +14372,9 @@ class EditorView { as a primitive. */ update(transactions) { - if (this.updateState != 0 /* Idle */) + if (this.updateState != 0 /* UpdateState.Idle */) throw new Error("Calls to EditorView.update are not allowed while an update is in progress"); - let redrawn = false, update; + let redrawn = false, attrsChanged = false, update; let state = this.state; for (let tr of transactions) { if (tr.startState != state) @@ -14008,13 +14385,27 @@ class EditorView { this.viewState.state = state; return; } + // If there was a pending DOM change, eagerly read it and try to + // apply it after the given transactions. + let pendingKey = this.observer.delayedAndroidKey, domChange = null; + if (pendingKey) { + this.observer.clearDelayedAndroidKey(); + domChange = this.observer.readChange(); + // Only try to apply DOM changes if the transactions didn't + // change the doc or selection. + if (domChange && !this.state.doc.eq(state.doc) || !this.state.selection.eq(state.selection)) + domChange = null; + } + else { + this.observer.clear(); + } // When the phrases change, redraw the editor if (state.facet(EditorState.phrases) != this.state.facet(EditorState.phrases)) return this.setState(state); update = ViewUpdate.create(this, state, transactions); let scrollTarget = this.viewState.scrollTarget; try { - this.updateState = 2 /* Updating */; + this.updateState = 2 /* UpdateState.Updating */; for (let tr of transactions) { if (scrollTarget) scrollTarget = scrollTarget.map(tr.changes); @@ -14035,20 +14426,24 @@ class EditorView { redrawn = this.docView.update(update); if (this.state.facet(styleModule) != this.styleModules) this.mountStyles(); - this.updateAttrs(); + attrsChanged = this.updateAttrs(); this.showAnnouncements(transactions); this.docView.updateSelection(redrawn, transactions.some(tr => tr.isUserEvent("select.pointer"))); } finally { - this.updateState = 0 /* Idle */; + this.updateState = 0 /* UpdateState.Idle */; } if (update.startState.facet(theme) != update.state.facet(theme)) this.viewState.mustMeasureContent = true; - if (redrawn || scrollTarget || this.viewState.mustEnforceCursorAssoc || this.viewState.mustMeasureContent) + if (redrawn || attrsChanged || scrollTarget || this.viewState.mustEnforceCursorAssoc || this.viewState.mustMeasureContent) this.requestMeasure(); if (!update.empty) for (let listener of this.state.facet(updateListener)) listener(update); + if (domChange) { + if (!applyDOMChange(this, domChange) && pendingKey.force) + dispatchKey(this.contentDOM, pendingKey.key, pendingKey.keyCode); + } } /** Reset the view to the given state. (This will cause the entire @@ -14058,13 +14453,13 @@ class EditorView { [`dispatch`](https://codemirror.net/6/docs/ref/#view.EditorView.dispatch) instead.) */ setState(newState) { - if (this.updateState != 0 /* Idle */) + if (this.updateState != 0 /* UpdateState.Idle */) throw new Error("Calls to EditorView.setState are not allowed while an update is in progress"); if (this.destroyed) { this.viewState.state = newState; return; } - this.updateState = 2 /* Updating */; + this.updateState = 2 /* UpdateState.Updating */; let hadFocus = this.hasFocus; try { for (let plugin of this.plugins) @@ -14081,7 +14476,7 @@ class EditorView { this.bidiCache = []; } finally { - this.updateState = 0 /* Idle */; + this.updateState = 0 /* UpdateState.Idle */; } if (hadFocus) this.focus(); @@ -14126,12 +14521,15 @@ class EditorView { cancelAnimationFrame(this.measureScheduled); this.measureScheduled = 0; // Prevent requestMeasure calls from scheduling another animation frame if (flush) - this.observer.flush(); + this.observer.forceFlush(); let updated = null; + let { scrollHeight, scrollTop, clientHeight } = this.scrollDOM; + let refHeight = scrollTop > scrollHeight - clientHeight - 4 ? scrollHeight : scrollTop; try { for (let i = 0;; i++) { - this.updateState = 1 /* Measuring */; + this.updateState = 1 /* UpdateState.Measuring */; let oldViewport = this.viewport; + let refBlock = this.viewState.lineBlockAtHeight(refHeight); let changed = this.viewState.measure(this); if (!changed && !this.measureRequests.length && this.viewState.scrollTarget == null) break; @@ -14143,7 +14541,7 @@ class EditorView { } let measuring = []; // Only run measure requests in this cycle when the viewport didn't change - if (!(changed & 4 /* Viewport */)) + if (!(changed & 4 /* UpdateFlag.Viewport */)) [this.measureRequests, measuring] = [measuring, this.measureRequests]; let measured = measuring.map(m => { try { @@ -14160,7 +14558,7 @@ class EditorView { updated = update; else updated.flags |= changed; - this.updateState = 2 /* Updating */; + this.updateState = 2 /* UpdateState.Updating */; if (!update.empty) { this.updatePlugins(update); this.inputState.update(update); @@ -14178,10 +14576,19 @@ class EditorView { logException(this.state, e); } } - if (this.viewState.scrollTarget) { - this.docView.scrollIntoView(this.viewState.scrollTarget); - this.viewState.scrollTarget = null; - scrolled = true; + if (this.viewState.editorHeight) { + if (this.viewState.scrollTarget) { + this.docView.scrollIntoView(this.viewState.scrollTarget); + this.viewState.scrollTarget = null; + scrolled = true; + } + else { + let diff = this.viewState.lineBlockAt(refBlock.from).top - refBlock.top; + if (diff > 1 || diff < -1) { + this.scrollDOM.scrollTop += diff; + scrolled = true; + } + } } if (redrawn) this.docView.updateSelection(true); @@ -14191,7 +14598,7 @@ class EditorView { } } finally { - this.updateState = 0 /* Idle */; + this.updateState = 0 /* UpdateState.Idle */; this.measureScheduled = -1; } if (updated && !updated.empty) @@ -14224,12 +14631,14 @@ class EditorView { if (this.state.readOnly) contentAttrs["aria-readonly"] = "true"; attrsFromFacet(this, contentAttributes, contentAttrs); - this.observer.ignore(() => { - updateAttrs(this.contentDOM, this.contentAttrs, contentAttrs); - updateAttrs(this.dom, this.editorAttrs, editorAttrs); + let changed = this.observer.ignore(() => { + let changedContent = updateAttrs(this.contentDOM, this.contentAttrs, contentAttrs); + let changedEditor = updateAttrs(this.dom, this.editorAttrs, editorAttrs); + return changedContent || changedEditor; }); this.editorAttrs = editorAttrs; this.contentAttrs = contentAttrs; + return changed; } showAnnouncements(trs) { let first = true; @@ -14248,9 +14657,9 @@ class EditorView { StyleModule.mount(this.root, this.styleModules.concat(baseTheme$1$2).reverse()); } readMeasured() { - if (this.updateState == 2 /* Updating */) + if (this.updateState == 2 /* UpdateState.Updating */) throw new Error("Reading the editor layout isn't allowed during an update"); - if (this.updateState == 0 /* Idle */ && this.measureScheduled > -1) + if (this.updateState == 0 /* UpdateState.Idle */ && this.measureScheduled > -1) this.measure(false); } /** @@ -14263,7 +14672,7 @@ class EditorView { */ requestMeasure(request) { if (this.measureScheduled < 0) - this.measureScheduled = requestAnimationFrame(() => this.measure()); + this.measureScheduled = this.win.requestAnimationFrame(() => this.measure()); if (request) { if (request.key != null) for (let i = 0; i < this.measureRequests.length; i++) { @@ -14304,7 +14713,7 @@ class EditorView { /** Find the text line or block widget at the given vertical position (which is interpreted as relative to the [top of the - document](https://codemirror.net/6/docs/ref/#view.EditorView.documentTop) + document](https://codemirror.net/6/docs/ref/#view.EditorView.documentTop)). */ elementAtHeight(height) { this.readMeasured(); @@ -14313,7 +14722,8 @@ class EditorView { /** Find the line block (see [`lineBlockAt`](https://codemirror.net/6/docs/ref/#view.EditorView.lineBlockAt) at the given - height. + height, again interpreted relative to the [top of the + document](https://codemirror.net/6/docs/ref/#view.EditorView.documentTop). */ lineBlockAtHeight(height) { this.readMeasured(); @@ -14507,7 +14917,7 @@ class EditorView { // or closing, which leads us to ignore selection changes from the // context menu because it looks like the editor isn't focused. // This kludges around that. - return (document.hasFocus() || browser.safari && ((_a = this.inputState) === null || _a === void 0 ? void 0 : _a.lastContextMenu) > Date.now() - 3e4) && + return (this.dom.ownerDocument.hasFocus() || browser.safari && ((_a = this.inputState) === null || _a === void 0 ? void 0 : _a.lastContextMenu) > Date.now() - 3e4) && this.root.activeElement == this.contentDOM; } /** @@ -14520,6 +14930,17 @@ class EditorView { }); } /** + Update the [root](https://codemirror.net/6/docs/ref/##view.EditorViewConfig.root) in which the editor lives. This is only + necessary when moving the editor's existing DOM to a new window or shadow root. + */ + setRoot(root) { + if (this._root != root) { + this._root = root; + this.observer.setWindow((root.nodeType == 9 ? root : root.ownerDocument).defaultView || window); + this.mountStyles(); + } + } + /** Clean up this editor view, removing its element from the document, unregistering event handlers, and notifying plugins. The view instance can no longer be used after @@ -14594,6 +15015,16 @@ class EditorView { static baseTheme(spec) { return Prec.lowest(styleModule.of(buildTheme("." + baseThemeID, spec, lightDarkIDs))); } + /** + Retrieve an editor view instance from the view's DOM + representation. + */ + static findFromDOM(dom) { + var _a; + let content = dom.querySelector(".cm-content"); + let cView = content && ContentView.get(content) || ContentView.get(dom); + return ((_a = cView === null || cView === void 0 ? void 0 : cView.rootView) === null || _a === void 0 ? void 0 : _a.view) || null; + } } /** Facet to add a [style @@ -14671,6 +15102,11 @@ the editor's vertical layout structure. The ones provided as functions are called _after_ the new viewport has been computed, and thus **must not** introduce block widgets or replacing decorations that cover line breaks. + +If you want decorated ranges to behave like atomic units for +cursor motion and deletion purposes, also provide the range set +containing the decorations to +[`EditorView.atomicRanges`](https://codemirror.net/6/docs/ref/#view.EditorView^atomicRanges). */ EditorView.decorations = decorations; /** @@ -14802,11 +15238,11 @@ function modifiers(name, event, shift) { name = "Shift-" + name; return name; } -const handleKeyEvents = /*@__PURE__*/EditorView.domEventHandlers({ +const handleKeyEvents = /*@__PURE__*/Prec.default(/*@__PURE__*/EditorView.domEventHandlers({ keydown(event, view) { return runHandlers(getKeymap(view.state), event, view, "editor"); } -}); +})); /** Facet used for registering keymaps. @@ -14847,6 +15283,7 @@ function buildKeymap(bindings, platform = currentPlatform) { throw new Error("Key binding " + name + " is used both as a regular binding and as a multi-stroke prefix"); }; let add = (scope, key, command, preventDefault) => { + var _a, _b; let scopeObj = bound[scope] || (bound[scope] = Object.create(null)); let parts = key.split(/ (?!$)/).map(k => normalizeKeyName(k, platform)); for (let i = 1; i < parts.length; i++) { @@ -14855,7 +15292,7 @@ function buildKeymap(bindings, platform = currentPlatform) { if (!scopeObj[prefix]) scopeObj[prefix] = { preventDefault: true, - commands: [(view) => { + run: [(view) => { let ourObj = storedPrefix = { view, prefix, scope }; setTimeout(() => { if (storedPrefix == ourObj) storedPrefix = null; }, PrefixTimeout); @@ -14865,16 +15302,26 @@ function buildKeymap(bindings, platform = currentPlatform) { } let full = parts.join(" "); checkPrefix(full, false); - let binding = scopeObj[full] || (scopeObj[full] = { preventDefault: false, commands: [] }); - binding.commands.push(command); + let binding = scopeObj[full] || (scopeObj[full] = { preventDefault: false, run: ((_b = (_a = scopeObj._any) === null || _a === void 0 ? void 0 : _a.run) === null || _b === void 0 ? void 0 : _b.slice()) || [] }); + if (command) + binding.run.push(command); if (preventDefault) binding.preventDefault = true; }; for (let b of bindings) { + let scopes = b.scope ? b.scope.split(" ") : ["editor"]; + if (b.any) + for (let scope of scopes) { + let scopeObj = bound[scope] || (bound[scope] = Object.create(null)); + if (!scopeObj._any) + scopeObj._any = { preventDefault: false, run: [] }; + for (let key in scopeObj) + scopeObj[key].run.push(b.any); + } let name = b[platform] || b.key; if (!name) continue; - for (let scope of b.scope ? b.scope.split(" ") : ["editor"]) { + for (let scope of scopes) { add(scope, name, b.run, b.preventDefault); if (b.shift) add(scope, "Shift-" + name, b.shift, b.preventDefault); @@ -14883,36 +15330,46 @@ function buildKeymap(bindings, platform = currentPlatform) { return bound; } function runHandlers(map, event, view, scope) { - let name = keyName(event), isChar = name.length == 1 && name != " "; + let name = keyName(event); + let charCode = codePointAt(name, 0), isChar = codePointSize(charCode) == name.length && name != " "; let prefix = "", fallthrough = false; if (storedPrefix && storedPrefix.view == view && storedPrefix.scope == scope) { prefix = storedPrefix.prefix + " "; if (fallthrough = modifierCodes.indexOf(event.keyCode) < 0) storedPrefix = null; } + let ran = new Set; let runFor = (binding) => { if (binding) { - for (let cmd of binding.commands) - if (cmd(view)) - return true; + for (let cmd of binding.run) + if (!ran.has(cmd)) { + ran.add(cmd); + if (cmd(view, event)) + return true; + } if (binding.preventDefault) fallthrough = true; } return false; }; - let scopeObj = map[scope], baseName; + let scopeObj = map[scope], baseName, shiftName; if (scopeObj) { if (runFor(scopeObj[prefix + modifiers(name, event, !isChar)])) return true; - if (isChar && (event.shiftKey || event.altKey || event.metaKey) && + if (isChar && (event.shiftKey || event.altKey || event.metaKey || charCode > 127) && (baseName = base[event.keyCode]) && baseName != name) { if (runFor(scopeObj[prefix + modifiers(baseName, event, true)])) return true; + else if (event.shiftKey && (shiftName = shift[event.keyCode]) != name && shiftName != baseName && + runFor(scopeObj[prefix + modifiers(shiftName, event, false)])) + return true; } else if (isChar && event.shiftKey) { if (runFor(scopeObj[prefix + modifiers(name, event, true)])) return true; } + if (runFor(scopeObj._any)) + return true; } return fallthrough; } @@ -14951,7 +15408,8 @@ function drawSelection(config = {}) { return [ selectionConfig.of(config), drawSelectionPlugin, - hideNativeSelection + hideNativeSelection, + nativeSelectionHidden.of(true) ]; } class Piece { @@ -15107,7 +15565,7 @@ function measureRange(view, range) { return pieces(top).concat(between).concat(pieces(bottom)); } function piece(left, top, right, bottom) { - return new Piece(left - base.left, top - base.top - 0.01 /* Epsilon */, right - left, bottom - top + 0.01 /* Epsilon */, "cm-selectionBackground"); + return new Piece(left - base.left, top - base.top - 0.01 /* C.Epsilon */, right - left, bottom - top + 0.01 /* C.Epsilon */, "cm-selectionBackground"); } function pieces({ top, bottom, horizontal }) { let pieces = []; @@ -15172,7 +15630,7 @@ function iterMatches(doc, re, from, to, f) { for (let cursor = doc.iterRange(from, to), pos = from, m; !cursor.next().done; pos += cursor.value.length) { if (!cursor.lineBreak) while (m = re.exec(cursor.value)) - f(pos + m.index, pos + m.index + m[0].length, m); + f(pos + m.index, m); } } function matchRanges(view, maxLength) { @@ -15202,11 +15660,26 @@ class MatchDecorator { Create a decorator. */ constructor(config) { - let { regexp, decoration, boundary, maxLength = 1000 } = config; + const { regexp, decoration, decorate, boundary, maxLength = 1000 } = config; if (!regexp.global) throw new RangeError("The regular expression given to MatchDecorator should have its 'g' flag set"); this.regexp = regexp; - this.getDeco = typeof decoration == "function" ? decoration : () => decoration; + if (decorate) { + this.addMatch = (match, view, from, add) => decorate(add, from, from + match[0].length, match, view); + } + else if (typeof decoration == "function") { + this.addMatch = (match, view, from, add) => { + let deco = decoration(match, view, from); + if (deco) + add(from, from + match[0].length, deco); + }; + } + else if (decoration) { + this.addMatch = (match, _view, from, add) => add(from, from + match[0].length, decoration); + } + else { + throw new RangeError("Either 'decorate' or 'decoration' should be provided to MatchDecorator"); + } this.boundary = boundary; this.maxLength = maxLength; } @@ -15216,9 +15689,9 @@ class MatchDecorator { plugin. */ createDeco(view) { - let build = new RangeSetBuilder(); + let build = new RangeSetBuilder(), add = build.add.bind(build); for (let { from, to } of matchRanges(view, this.maxLength)) - iterMatches(view.state.doc, this.regexp, from, to, (a, b, m) => build.add(a, b, this.getDeco(m, view, a))); + iterMatches(view.state.doc, this.regexp, from, to, (from, m) => this.addMatch(m, view, from, add)); return build.finish(); } /** @@ -15260,15 +15733,14 @@ class MatchDecorator { } } let ranges = [], m; + let add = (from, to, deco) => ranges.push(deco.range(from, to)); if (fromLine == toLine) { this.regexp.lastIndex = start - fromLine.from; - while ((m = this.regexp.exec(fromLine.text)) && m.index < end - fromLine.from) { - let pos = m.index + fromLine.from; - ranges.push(this.getDeco(m, view, pos).range(pos, pos + m[0].length)); - } + while ((m = this.regexp.exec(fromLine.text)) && m.index < end - fromLine.from) + this.addMatch(m, view, m.index + fromLine.from, add); } else { - iterMatches(view.state.doc, this.regexp, start, end, (from, to, m) => ranges.push(this.getDeco(m, view, from).range(from, to))); + iterMatches(view.state.doc, this.regexp, start, end, (from, m) => this.addMatch(m, view, from, add)); } deco = deco.update({ filterFrom: start, filterTo: end, filter: (from, to) => from < start || to > end, add: ranges }); } @@ -15278,7 +15750,7 @@ class MatchDecorator { } const UnicodeRegexpSupport = /x/.unicode != null ? "gu" : "g"; -const Specials = /*@__PURE__*/new RegExp("[\u0000-\u0008\u000a-\u001f\u007f-\u009f\u00ad\u061c\u200b\u200e\u200f\u2028\u2029\u202d\u202e\ufeff\ufff9-\ufffc]", UnicodeRegexpSupport); +const Specials = /*@__PURE__*/new RegExp("[\u0000-\u0008\u000a-\u001f\u007f-\u009f\u00ad\u061c\u200b\u200e\u200f\u2028\u2029\u202d\u202e\u2066\u2067\u2069\ufeff\ufff9-\ufffc]", UnicodeRegexpSupport); const Names = { 0: "null", 7: "bell", @@ -15295,6 +15767,9 @@ const Names = { 8232: "line separator", 8237: "left-to-right override", 8238: "right-to-left override", + 8294: "left-to-right isolate", + 8295: "right-to-left isolate", + 8297: "pop directional isolate", 8233: "paragraph separator", 65279: "zero width no-break space", 65532: "object replacement" @@ -15473,7 +15948,10 @@ function rectangleFor(state, a, b) { for (let i = startLine; i <= endLine; i++) { let line = state.doc.line(i); let start = findColumn(line.text, startCol, state.tabSize, true); - if (start > -1) { + if (start < 0) { + ranges.push(EditorSelection.cursor(line.to)); + } + else { let end = findColumn(line.text, endCol, state.tabSize); ranges.push(EditorSelection.range(line.from + start, line.from + end)); } @@ -15542,6 +16020,7 @@ class TooltipViewManager { this.tooltipViews = this.tooltips.map(createTooltipView); } update(update) { + var _a; let input = update.state.facet(this.facet); let tooltips = input.filter(x => x); if (input === this.input) { @@ -15570,16 +16049,19 @@ class TooltipViewManager { } } for (let t of this.tooltipViews) - if (tooltipViews.indexOf(t) < 0) + if (tooltipViews.indexOf(t) < 0) { t.dom.remove(); + (_a = t.destroy) === null || _a === void 0 ? void 0 : _a.call(t); + } this.input = input; this.tooltips = tooltips; this.tooltipViews = tooltipViews; return true; } } -function windowSpace() { - return { top: 0, left: 0, bottom: innerHeight, right: innerWidth }; +function windowSpace(view) { + let { win } = view; + return { top: 0, left: 0, bottom: win.innerHeight, right: win.innerWidth }; } const tooltipConfig = /*@__PURE__*/Facet.define({ combine: values => { @@ -15593,7 +16075,6 @@ const tooltipConfig = /*@__PURE__*/Facet.define({ }); const tooltipPlugin = /*@__PURE__*/ViewPlugin.fromClass(class { constructor(view) { - var _a; this.view = view; this.inView = true; this.lastTransaction = 0; @@ -15611,7 +16092,7 @@ const tooltipPlugin = /*@__PURE__*/ViewPlugin.fromClass(class { this.measureSoon(); }, { threshold: [1] }) : null; this.observeIntersection(); - (_a = view.dom.ownerDocument.defaultView) === null || _a === void 0 ? void 0 : _a.addEventListener("resize", this.measureSoon = this.measureSoon.bind(this)); + view.win.addEventListener("resize", this.measureSoon = this.measureSoon.bind(this)); this.maybeMeasure(); } createContainer() { @@ -15685,9 +16166,11 @@ const tooltipPlugin = /*@__PURE__*/ViewPlugin.fromClass(class { } destroy() { var _a, _b; - (_a = this.view.dom.ownerDocument.defaultView) === null || _a === void 0 ? void 0 : _a.removeEventListener("resize", this.measureSoon); - for (let { dom } of this.manager.tooltipViews) - dom.remove(); + this.view.win.removeEventListener("resize", this.measureSoon); + for (let tooltipView of this.manager.tooltipViews) { + tooltipView.dom.remove(); + (_a = tooltipView.destroy) === null || _a === void 0 ? void 0 : _a.call(tooltipView); + } (_b = this.intersectionObserver) === null || _b === void 0 ? void 0 : _b.disconnect(); clearTimeout(this.measureTimeout); } @@ -15719,12 +16202,12 @@ const tooltipPlugin = /*@__PURE__*/ViewPlugin.fromClass(class { continue; } let arrow = tooltip.arrow ? tView.dom.querySelector(".cm-tooltip-arrow") : null; - let arrowHeight = arrow ? 7 /* Size */ : 0; + let arrowHeight = arrow ? 7 /* Arrow.Size */ : 0; let width = size.right - size.left, height = size.bottom - size.top; let offset = tView.offset || noOffset, ltr = this.view.textDirection == Direction.LTR; let left = size.width > space.right - space.left ? (ltr ? space.left : space.right - size.width) - : ltr ? Math.min(pos.left - (arrow ? 14 /* Offset */ : 0) + offset.x, space.right - width) - : Math.max(space.left, pos.left - width + (arrow ? 14 /* Offset */ : 0) - offset.x); + : ltr ? Math.min(pos.left - (arrow ? 14 /* Arrow.Offset */ : 0) + offset.x, space.right - width) + : Math.max(space.left, pos.left - width + (arrow ? 14 /* Arrow.Offset */ : 0) - offset.x); let above = !!tooltip.above; if (!tooltip.strictSide && (above ? pos.top - (size.bottom - size.top) - offset.y < space.top @@ -15746,7 +16229,7 @@ const tooltipPlugin = /*@__PURE__*/ViewPlugin.fromClass(class { dom.style.left = left + "px"; } if (arrow) - arrow.style.left = `${pos.left + (ltr ? offset.x : -offset.x) - (left + 14 /* Offset */ - 7 /* Size */)}px`; + arrow.style.left = `${pos.left + (ltr ? offset.x : -offset.x) - (left + 14 /* Arrow.Offset */ - 7 /* Arrow.Size */)}px`; if (tView.overlap !== true) others.push({ left, top, right, bottom: top + height }); dom.classList.toggle("cm-tooltip-above", above); @@ -15788,8 +16271,8 @@ const baseTheme$4 = /*@__PURE__*/EditorView.baseTheme({ color: "white" }, ".cm-tooltip-arrow": { - height: `${7 /* Size */}px`, - width: `${7 /* Size */ * 2}px`, + height: `${7 /* Arrow.Size */}px`, + width: `${7 /* Arrow.Size */ * 2}px`, position: "absolute", zIndex: -1, overflow: "hidden", @@ -15798,26 +16281,26 @@ const baseTheme$4 = /*@__PURE__*/EditorView.baseTheme({ position: "absolute", width: 0, height: 0, - borderLeft: `${7 /* Size */}px solid transparent`, - borderRight: `${7 /* Size */}px solid transparent`, + borderLeft: `${7 /* Arrow.Size */}px solid transparent`, + borderRight: `${7 /* Arrow.Size */}px solid transparent`, }, ".cm-tooltip-above &": { - bottom: `-${7 /* Size */}px`, + bottom: `-${7 /* Arrow.Size */}px`, "&:before": { - borderTop: `${7 /* Size */}px solid #bbb`, + borderTop: `${7 /* Arrow.Size */}px solid #bbb`, }, "&:after": { - borderTop: `${7 /* Size */}px solid #f5f5f5`, + borderTop: `${7 /* Arrow.Size */}px solid #f5f5f5`, bottom: "1px" } }, ".cm-tooltip-below &": { - top: `-${7 /* Size */}px`, + top: `-${7 /* Arrow.Size */}px`, "&:before": { - borderBottom: `${7 /* Size */}px solid #bbb`, + borderBottom: `${7 /* Arrow.Size */}px solid #bbb`, }, "&:after": { - borderBottom: `${7 /* Size */}px solid #f5f5f5`, + borderBottom: `${7 /* Arrow.Size */}px solid #f5f5f5`, top: "1px" } }, @@ -16517,23 +17000,25 @@ class Modifier { let set = [], tag = new Tag(set, base, mods); for (let m of mods) m.instances.push(tag); - let configs = permute(mods); + let configs = powerSet(mods); for (let parent of base.set) - for (let config of configs) - set.push(Modifier.get(parent, config)); + if (!parent.modified.length) + for (let config of configs) + set.push(Modifier.get(parent, config)); return tag; } } function sameArray(a, b) { return a.length == b.length && a.every((x, i) => x == b[i]); } -function permute(array) { - let result = [array]; +function powerSet(array) { + let sets = [[]]; for (let i = 0; i < array.length; i++) { - for (let a of permute(array.slice(0, i).concat(array.slice(i + 1)))) - result.push(a); + for (let j = 0, e = sets.length; j < e; j++) { + sets.push(sets[j].concat(array[i])); + } } - return result; + return sets.sort((a, b) => b.length - a.length); } /// This function is used to add a set of tags to a language syntax /// via [`NodeSet.extend`](#common.NodeSet.extend) or @@ -16631,6 +17116,8 @@ class Rule { this.context = context; this.next = next; } + get opaque() { return this.mode == 0 /* Opaque */; } + get inherit() { return this.mode == 1 /* Inherit */; } sort(other) { if (!other || other.depth < this.depth) { this.next = other; @@ -16641,6 +17128,7 @@ class Rule { } get depth() { return this.context ? this.context.length : 0; } } +Rule.empty = new Rule([], 2 /* Normal */, null); /// Define a [highlighter](#highlight.Highlighter) from an array of /// tag/class pairs. Classes associated with more specific tags will /// take precedence. @@ -16668,7 +17156,7 @@ function tagHighlighter(tags, options) { } return cls; }, - scope: scope + scope }; } function highlightTags(highlighters, tags) { @@ -16721,25 +17209,17 @@ class HighlightBuilder { if (type.isTop) highlighters = this.highlighters.filter(h => !h.scope || h.scope(type)); let cls = inheritedClass; - let rule = type.prop(ruleNodeProp), opaque = false; - while (rule) { - if (!rule.context || cursor.matchContext(rule.context)) { - let tagCls = highlightTags(highlighters, rule.tags); - if (tagCls) { - if (cls) - cls += " "; - cls += tagCls; - if (rule.mode == 1 /* Inherit */) - inheritedClass += (inheritedClass ? " " : "") + tagCls; - else if (rule.mode == 0 /* Opaque */) - opaque = true; - } - break; - } - rule = rule.next; + let rule = getStyleTags(cursor) || Rule.empty; + let tagCls = highlightTags(highlighters, rule.tags); + if (tagCls) { + if (cls) + cls += " "; + cls += tagCls; + if (rule.mode == 1 /* Inherit */) + inheritedClass += (inheritedClass ? " " : "") + tagCls; } this.startSpan(cursor.from, cls); - if (opaque) + if (rule.opaque) return; let mounted = cursor.tree && cursor.tree.prop(NodeProp.mounted); if (mounted && mounted.overlay) { @@ -16782,6 +17262,15 @@ class HighlightBuilder { } } } +/// Match a syntax node's [highlight rules](#highlight.styleTags). If +/// there's a match, return its set of tags, and whether it is +/// opaque (uses a `!`) or applies to all child nodes (`/...`). +function getStyleTags(node) { + let rule = node.type.prop(ruleNodeProp); + while (rule && rule.context && !node.matchContext(rule.context)) + rule = rule.next; + return rule || null; +} const t = Tag.define; const comment = t(), name = t(), typeName = t(name), propertyName = t(name), literal = t(), string = t(literal), number = t(literal), content = t(), heading = t(content), keyword = t(), operator = t(), punctuation = t(), bracket = t(punctuation), meta = t(); /// The default set of highlighting [tags](#highlight.Tag). @@ -16882,7 +17371,7 @@ const tags$1 = { moduleKeyword: t(keyword), /// An operator. operator, - /// An [operator](#highlight.tags.operator) that defines something. + /// An [operator](#highlight.tags.operator) that dereferences something. derefOperator: t(operator), /// Arithmetic-related [operator](#highlight.tags.operator). arithmeticOperator: t(operator), @@ -17011,7 +17500,8 @@ const tags$1 = { /// * [`emphasis`](#highlight.tags.emphasis) /// * [`strong`](#highlight.tags.strong) /// * [`keyword`](#highlight.tags.keyword) -/// * [`atom`](#highlight.tags.atom) [`bool`](#highlight.tags.bool) +/// * [`atom`](#highlight.tags.atom) +/// * [`bool`](#highlight.tags.bool) /// * [`url`](#highlight.tags.url) /// * [`labelName`](#highlight.tags.labelName) /// * [`inserted`](#highlight.tags.inserted) @@ -17119,8 +17609,13 @@ class Language { The [language data](https://codemirror.net/6/docs/ref/#state.EditorState.languageDataAt) facet used for this language. */ - data, parser, extraExtensions = []) { + data, parser, extraExtensions = [], + /** + A language name. + */ + name = "") { this.data = data; + this.name = name; // Kludge to define EditorState.tree as a debugging helper, // without the EditorState package actually knowing about // languages and lezer trees. @@ -17208,8 +17703,8 @@ A subclass of [`Language`](https://codemirror.net/6/docs/ref/#language.Language) parsers. */ class LRLanguage extends Language { - constructor(data, parser) { - super(data, parser); + constructor(data, parser, name) { + super(data, parser, [], name); this.parser = parser; } /** @@ -17219,14 +17714,14 @@ class LRLanguage extends Language { let data = defineLanguageFacet(spec.languageData); return new LRLanguage(data, spec.parser.configure({ props: [languageDataProp.add(type => type.isTop ? data : undefined)] - })); + }), spec.name); } /** Create a new instance of this language with a reconfigured - version of its parser. + version of its parser and optionally a new name. */ - configure(options) { - return new LRLanguage(this.data, this.parser.configure(options)); + configure(options, name) { + return new LRLanguage(this.data, this.parser.configure(options), name || this.name); } get allowsNesting() { return this.parser.hasWrappers(); } } @@ -17540,14 +18035,14 @@ class LanguageState { // state updates with parse work beyond the viewport. let upto = this.context.treeLen == tr.startState.doc.length ? undefined : Math.max(tr.changes.mapPos(this.context.treeLen), newCx.viewport.to); - if (!newCx.work(20 /* Apply */, upto)) + if (!newCx.work(20 /* Work.Apply */, upto)) newCx.takeTree(); return new LanguageState(newCx); } static init(state) { - let vpTo = Math.min(3000 /* InitViewport */, state.doc.length); + let vpTo = Math.min(3000 /* Work.InitViewport */, state.doc.length); let parseState = ParseContext.create(state.facet(language$1).parser, state, { from: 0, to: vpTo }); - if (!parseState.work(20 /* Apply */, vpTo)) + if (!parseState.work(20 /* Work.Apply */, vpTo)) parseState.takeTree(); return new LanguageState(parseState); } @@ -17564,14 +18059,14 @@ Language.state = /*@__PURE__*/StateField.define({ } }); let requestIdle = (callback) => { - let timeout = setTimeout(() => callback(), 500 /* MaxPause */); + let timeout = setTimeout(() => callback(), 500 /* Work.MaxPause */); return () => clearTimeout(timeout); }; if (typeof requestIdleCallback != "undefined") requestIdle = (callback) => { let idle = -1, timeout = setTimeout(() => { - idle = requestIdleCallback(callback, { timeout: 500 /* MaxPause */ - 100 /* MinPause */ }); - }, 100 /* MinPause */); + idle = requestIdleCallback(callback, { timeout: 500 /* Work.MaxPause */ - 100 /* Work.MinPause */ }); + }, 100 /* Work.MinPause */); return () => idle < 0 ? clearTimeout(timeout) : cancelIdleCallback(idle); }; const isInputPending = typeof navigator != "undefined" && ((_a = navigator.scheduling) === null || _a === void 0 ? void 0 : _a.isInputPending) @@ -17594,7 +18089,7 @@ const parseWorker = /*@__PURE__*/ViewPlugin.fromClass(class ParseWorker { this.scheduleWork(); if (update.docChanged) { if (this.view.hasFocus) - this.chunkBudget += 50 /* ChangeBonus */; + this.chunkBudget += 50 /* Work.ChangeBonus */; this.scheduleWork(); } this.checkAsyncSchedule(cx); @@ -17610,19 +18105,19 @@ const parseWorker = /*@__PURE__*/ViewPlugin.fromClass(class ParseWorker { this.working = null; let now = Date.now(); if (this.chunkEnd < now && (this.chunkEnd < 0 || this.view.hasFocus)) { // Start a new chunk - this.chunkEnd = now + 30000 /* ChunkTime */; - this.chunkBudget = 3000 /* ChunkBudget */; + this.chunkEnd = now + 30000 /* Work.ChunkTime */; + this.chunkBudget = 3000 /* Work.ChunkBudget */; } if (this.chunkBudget <= 0) return; // No more budget let { state, viewport: { to: vpTo } } = this.view, field = state.field(Language.state); - if (field.tree == field.context.tree && field.context.isDone(vpTo + 100000 /* MaxParseAhead */)) + if (field.tree == field.context.tree && field.context.isDone(vpTo + 100000 /* Work.MaxParseAhead */)) return; - let endTime = Date.now() + Math.min(this.chunkBudget, 100 /* Slice */, deadline && !isInputPending ? Math.max(25 /* MinSlice */, deadline.timeRemaining() - 5) : 1e9); + let endTime = Date.now() + Math.min(this.chunkBudget, 100 /* Work.Slice */, deadline && !isInputPending ? Math.max(25 /* Work.MinSlice */, deadline.timeRemaining() - 5) : 1e9); let viewportFirst = field.context.treeLen < vpTo && state.doc.length > vpTo + 1000; let done = field.context.work(() => { return isInputPending && isInputPending() || Date.now() > endTime; - }, vpTo + (viewportFirst ? 0 : 100000 /* MaxParseAhead */)); + }, vpTo + (viewportFirst ? 0 : 100000 /* Work.MaxParseAhead */)); this.chunkBudget -= Date.now() - now; if (done || this.chunkBudget <= 0) { field.context.takeTree(); @@ -17653,11 +18148,21 @@ const parseWorker = /*@__PURE__*/ViewPlugin.fromClass(class ParseWorker { eventHandlers: { focus() { this.scheduleWork(); } } }); /** -The facet used to associate a language with an editor state. +The facet used to associate a language with an editor state. Used +by `Language` object's `extension` property (so you don't need to +manually wrap your languages in this). Can be used to access the +current language on a state. */ const language$1 = /*@__PURE__*/Facet.define({ combine(languages) { return languages.length ? languages[0] : null; }, - enables: [Language.state, parseWorker] + enables: language => [ + Language.state, + parseWorker, + EditorView.contentAttributes.compute([language], state => { + let lang = state.facet(language); + return lang && lang.name ? { "data-language": lang.name } : {}; + }) + ] }); /** This class bundles a [language](https://codemirror.net/6/docs/ref/#language.Language) with an @@ -17787,8 +18292,10 @@ class LanguageDescription { /** Facet that defines a way to provide a function that computes the -appropriate indentation depth at the start of a given line, or -`null` to indicate no appropriate indentation could be determined. +appropriate indentation depth, as a column number (see +[`indentString`](https://codemirror.net/6/docs/ref/#language.indentString)), at the start of a given +line, or `null` to indicate no appropriate indentation could be +determined. */ const indentService = /*@__PURE__*/Facet.define(); /** @@ -17833,12 +18340,13 @@ function indentString(state, cols) { return result; } /** -Get the indentation at the given position. Will first consult any -[indent services](https://codemirror.net/6/docs/ref/#language.indentService) that are registered, -and if none of those return an indentation, this will check the -syntax tree for the [indent node prop](https://codemirror.net/6/docs/ref/#language.indentNodeProp) -and use that if found. Returns a number when an indentation could -be determined, and null otherwise. +Get the indentation, as a column number, at the given position. +Will first consult any [indent services](https://codemirror.net/6/docs/ref/#language.indentService) +that are registered, and if none of those return an indentation, +this will check the syntax tree for the [indent node +prop](https://codemirror.net/6/docs/ref/#language.indentNodeProp) and use that if found. Returns a +number when an indentation could be determined, and null +otherwise. */ function getIndentation(context, pos) { if (context instanceof EditorState) @@ -17948,8 +18456,9 @@ class IndentContext { /** A syntax tree node prop used to associate indentation strategies with node types. Such a strategy is a function from an indentation -context to a column number or null, where null indicates that no -definitive indentation can be determined. +context to a column number (see also +[`indentString`](https://codemirror.net/6/docs/ref/#language.indentString)) or null, where null +indicates that no definitive indentation can be determined. */ const indentNodeProp = /*@__PURE__*/new NodeProp(); // Compute the indentation for a given position from the syntax tree. @@ -18241,6 +18750,13 @@ function selectedLines(view) { } return lines; } +/** +The state field that stores the folded ranges (as a [decoration +set](https://codemirror.net/6/docs/ref/#view.DecorationSet)). Can be passed to +[`EditorState.toJSON`](https://codemirror.net/6/docs/ref/#state.EditorState.toJSON) and +[`fromJSON`](https://codemirror.net/6/docs/ref/#state.EditorState^fromJSON) to serialize the fold +state. +*/ const foldState = /*@__PURE__*/StateField.define({ create() { return Decoration.none; @@ -18268,7 +18784,24 @@ const foldState = /*@__PURE__*/StateField.define({ } return folded; }, - provide: f => EditorView.decorations.from(f) + provide: f => EditorView.decorations.from(f), + toJSON(folded, state) { + let ranges = []; + folded.between(0, state.doc.length, (from, to) => { ranges.push(from, to); }); + return ranges; + }, + fromJSON(value) { + if (!Array.isArray(value) || value.length % 2) + throw new RangeError("Invalid JSON for fold state"); + let ranges = []; + for (let i = 0; i < value.length;) { + let from = value[i++], to = value[i++]; + if (typeof from != "number" || typeof to != "number") + throw new RangeError("Invalid JSON for fold state"); + ranges.push(foldWidget.range(from, to)); + } + return Decoration.set(ranges, true); + } }); function findFold(state, from, to) { var _a; @@ -18410,6 +18943,7 @@ const foldGutterDefaults = { closedText: "›", markerDOM: null, domEventHandlers: {}, + foldingChanged: () => false }; class FoldMarker extends GutterMarker { constructor(config, open) { @@ -18444,7 +18978,8 @@ function foldGutter(config = {}) { if (update.docChanged || update.viewportChanged || update.startState.facet(language$1) != update.state.facet(language$1) || update.startState.field(foldState, false) != update.state.field(foldState, false) || - syntaxTree(update.startState) != syntaxTree(update.state)) + syntaxTree(update.startState) != syntaxTree(update.state) || + fullConfig.foldingChanged(update)) this.markers = this.buildMarkers(update.view); } buildMarkers(view) { @@ -18507,7 +19042,12 @@ A highlight style associates CSS styles with higlighting [tags](https://lezer.codemirror.net/docs/ref#highlight.Tag). */ class HighlightStyle { - constructor(spec, options) { + constructor( + /** + The tag styles used to create this highlight style. + */ + specs, options) { + this.specs = specs; let modSpec; function def(spec) { let cls = StyleModule.newName(); @@ -18518,7 +19058,7 @@ class HighlightStyle { const scopeOpt = options.scope; this.scope = scopeOpt instanceof Language ? (type) => type.prop(languageDataProp) == scopeOpt.data : scopeOpt ? (type) => type == scopeOpt : undefined; - this.style = tagHighlighter(spec.map(style => ({ + this.style = tagHighlighter(specs.map(style => ({ tag: style.tag, class: style.class || def(Object.assign({}, style, { tag: null })) })), { @@ -18754,13 +19294,13 @@ function matchMarkedBrackets(_state, _pos, dir, token, matching, brackets) { depth++; } else if (matchingNodes(cursor.type, -dir, brackets)) { - depth--; if (depth == 0) return { start: firstToken, end: cursor.from == cursor.to ? undefined : { from: cursor.from, to: cursor.to }, matched: false }; + depth--; } } } while (dir < 0 ? cursor.prevSibling() : cursor.nextSibling()); @@ -18780,7 +19320,7 @@ function matchPlainBrackets(state, pos, dir, tree, tokenType, maxScanDistance, b let basePos = pos + distance * dir; for (let pos = dir > 0 ? 0 : text.length - 1, end = dir > 0 ? text.length : -1; pos != end; pos += dir) { let found = brackets.indexOf(text[pos]); - if (found < 0 || tree.resolve(basePos + pos, 1).type != tokenType) + if (found < 0 || tree.resolveInner(basePos + pos, 1).type != tokenType) continue; if ((found % 2 == 0) == (dir > 0)) { depth++; @@ -18806,8 +19346,8 @@ for (let [legacyName, name] of [ ["variable-2", "variableName.special"], ["string-2", "string.special"], ["def", "variableName.definition"], - ["tag", "typeName"], - ["attribute", "propertyName"], + ["tag", "tagName"], + ["attribute", "attributeName"], ["type", "typeName"], ["builtin", "variableName.standard"], ["qualifier", "modifier"], @@ -19000,32 +19540,35 @@ This annotation is added to transactions that are produced by picking a completion. */ const pickedCompletion = /*@__PURE__*/Annotation.define(); +/** +Helper function that returns a transaction spec which inserts a +completion's text in the main selection range, and any other +selection range that has the same text in front of it. +*/ +function insertCompletionText(state, text, from, to) { + return Object.assign(Object.assign({}, state.changeByRange(range => { + if (range == state.selection.main) + return { + changes: { from: from, to: to, insert: text }, + range: EditorSelection.cursor(from + text.length) + }; + let len = to - from; + if (!range.empty || + len && state.sliceDoc(range.from - len, range.from) != state.sliceDoc(from, to)) + return { range }; + return { + changes: { from: range.from - len, to: range.from, insert: text }, + range: EditorSelection.cursor(range.from - len + text.length) + }; + })), { userEvent: "input.complete" }); +} function applyCompletion(view, option) { const apply = option.completion.apply || option.completion.label; let result = option.source; - if (typeof apply == "string") { - view.dispatch(view.state.changeByRange(range => { - if (range == view.state.selection.main) - return { - changes: { from: result.from, to: result.to, insert: apply }, - range: EditorSelection.cursor(result.from + apply.length) - }; - let len = result.to - result.from; - if (!range.empty || - len && view.state.sliceDoc(range.from - len, range.from) != view.state.sliceDoc(result.from, result.to)) - return { range }; - return { - changes: { from: range.from - len, to: range.from, insert: apply }, - range: EditorSelection.cursor(range.from - len + apply.length) - }; - }), { - userEvent: "input.complete", - annotations: pickedCompletion.of(option.completion) - }); - } - else { + if (typeof apply == "string") + view.dispatch(insertCompletionText(view.state, apply, result.from, result.to)); + else apply(view, option.completion, result.from, result.to); - } } const SourceCache = /*@__PURE__*/new WeakMap(); function asSource(source) { @@ -19077,7 +19620,7 @@ class FuzzyMatcher { if (chars.length == 1) { let first = codePointAt(word, 0); return first == chars[0] ? [0, 0, codePointSize(first)] - : first == folded[0] ? [-200 /* CaseFold */, 0, codePointSize(first)] : null; + : first == folded[0] ? [-200 /* Penalty.CaseFold */, 0, codePointSize(first)] : null; } let direct = word.indexOf(this.pattern); if (direct == 0) @@ -19105,7 +19648,7 @@ class FuzzyMatcher { let adjacentTo = 0, adjacentStart = -1, adjacentEnd = -1; let hasLower = /[a-z]/.test(word), wordAdjacent = true; // Go over the option's text, scanning for the various kinds of matches - for (let i = 0, e = Math.min(word.length, 200), prevType = 0 /* NonWord */; i < e && byWordTo < len;) { + for (let i = 0, e = Math.min(word.length, 200), prevType = 0 /* Tp.NonWord */; i < e && byWordTo < len;) { let next = codePointAt(word, i); if (direct < 0) { if (preciseTo < len && next == chars[preciseTo]) @@ -19123,9 +19666,9 @@ class FuzzyMatcher { } } let ch, type = next < 0xff - ? (next >= 48 && next <= 57 || next >= 97 && next <= 122 ? 2 /* Lower */ : next >= 65 && next <= 90 ? 1 /* Upper */ : 0 /* NonWord */) - : ((ch = fromCodePoint(next)) != ch.toLowerCase() ? 1 /* Upper */ : ch != ch.toUpperCase() ? 2 /* Lower */ : 0 /* NonWord */); - if (!i || type == 1 /* Upper */ && hasLower || prevType == 0 /* NonWord */ && type != 0 /* NonWord */) { + ? (next >= 48 && next <= 57 || next >= 97 && next <= 122 ? 2 /* Tp.Lower */ : next >= 65 && next <= 90 ? 1 /* Tp.Upper */ : 0 /* Tp.NonWord */) + : ((ch = fromCodePoint(next)) != ch.toLowerCase() ? 1 /* Tp.Upper */ : ch != ch.toUpperCase() ? 2 /* Tp.Lower */ : 0 /* Tp.NonWord */); + if (!i || type == 1 /* Tp.Upper */ && hasLower || prevType == 0 /* Tp.NonWord */ && type != 0 /* Tp.NonWord */) { if (chars[byWordTo] == next || (folded[byWordTo] == next && (byWordFolded = true))) byWord[byWordTo++] = i; else if (byWord.length) @@ -19135,17 +19678,17 @@ class FuzzyMatcher { i += codePointSize(next); } if (byWordTo == len && byWord[0] == 0 && wordAdjacent) - return this.result(-100 /* ByWord */ + (byWordFolded ? -200 /* CaseFold */ : 0), byWord, word); + return this.result(-100 /* Penalty.ByWord */ + (byWordFolded ? -200 /* Penalty.CaseFold */ : 0), byWord, word); if (adjacentTo == len && adjacentStart == 0) - return [-200 /* CaseFold */ - word.length, 0, adjacentEnd]; + return [-200 /* Penalty.CaseFold */ - word.length, 0, adjacentEnd]; if (direct > -1) - return [-700 /* NotStart */ - word.length, direct, direct + this.pattern.length]; + return [-700 /* Penalty.NotStart */ - word.length, direct, direct + this.pattern.length]; if (adjacentTo == len) - return [-200 /* CaseFold */ + -700 /* NotStart */ - word.length, adjacentStart, adjacentEnd]; + return [-200 /* Penalty.CaseFold */ + -700 /* Penalty.NotStart */ - word.length, adjacentStart, adjacentEnd]; if (byWordTo == len) - return this.result(-100 /* ByWord */ + (byWordFolded ? -200 /* CaseFold */ : 0) + -700 /* NotStart */ + - (wordAdjacent ? 0 : -1100 /* Gap */), byWord, word); - return chars.length == 2 ? null : this.result((any[0] ? -700 /* NotStart */ : 0) + -200 /* CaseFold */ + -1100 /* Gap */, any, word); + return this.result(-100 /* Penalty.ByWord */ + (byWordFolded ? -200 /* Penalty.CaseFold */ : 0) + -700 /* Penalty.NotStart */ + + (wordAdjacent ? 0 : -1100 /* Penalty.Gap */), byWord, word); + return chars.length == 2 ? null : this.result((any[0] ? -700 /* Penalty.NotStart */ : 0) + -200 /* Penalty.CaseFold */ + -1100 /* Penalty.Gap */, any, word); } result(score, positions, word) { let result = [score - word.length], i = 1; @@ -19166,6 +19709,7 @@ const completionConfig = /*@__PURE__*/Facet.define({ combine(configs) { return combineConfig(configs, { activateOnTyping: true, + selectOnOpen: true, override: null, closeOnBlur: true, maxRenderedOptions: 100, @@ -19173,7 +19717,9 @@ const completionConfig = /*@__PURE__*/Facet.define({ optionClass: () => "", aboveCursor: false, icons: true, - addToOptions: [] + addToOptions: [], + compareCompletions: (a, b) => a.label.localeCompare(b.label), + interactionDelay: 75 }, { defaultKeymap: (a, b) => a && b, closeOnBlur: (a, b) => a && b, @@ -19236,6 +19782,8 @@ function optionContent(config) { function rangeAroundSelected(total, selected, max) { if (total <= max) return { from: 0, to: total }; + if (selected < 0) + selected = 0; if (selected <= (total >> 1)) { let off = Math.floor(selected / max); return { from: off * max, to: (off + 1) * max }; @@ -19287,7 +19835,7 @@ class CompletionTooltip { } updateSel() { let cState = this.view.state.field(this.stateField), open = cState.open; - if (open.selected < this.range.from || open.selected >= this.range.to) { + if (open.selected > -1 && open.selected < this.range.from || open.selected >= this.range.to) { this.range = rangeAroundSelected(open.options.length, open.selected, this.view.state.facet(completionConfig).maxRenderedOptions); this.list.remove(); this.list = this.dom.appendChild(this.createListBox(open.options, cState.id, this.range)); @@ -19348,26 +19896,47 @@ class CompletionTooltip { let sel = this.dom.querySelector("[aria-selected]"); if (!sel || !this.info) return null; + let win = this.dom.ownerDocument.defaultView || window; let listRect = this.dom.getBoundingClientRect(); let infoRect = this.info.getBoundingClientRect(); let selRect = sel.getBoundingClientRect(); - if (selRect.top > Math.min(innerHeight, listRect.bottom) - 10 || selRect.bottom < Math.max(0, listRect.top) + 10) + if (selRect.top > Math.min(win.innerHeight, listRect.bottom) - 10 || selRect.bottom < Math.max(0, listRect.top) + 10) return null; - let top = Math.max(0, Math.min(selRect.top, innerHeight - infoRect.height)) - listRect.top; - let left = this.view.textDirection == Direction.RTL; - let spaceLeft = listRect.left, spaceRight = innerWidth - listRect.right; + let rtl = this.view.textDirection == Direction.RTL, left = rtl, narrow = false, maxWidth; + let top = "", bottom = ""; + let spaceLeft = listRect.left, spaceRight = win.innerWidth - listRect.right; if (left && spaceLeft < Math.min(infoRect.width, spaceRight)) left = false; else if (!left && spaceRight < Math.min(infoRect.width, spaceLeft)) left = true; - return { top, left }; + if (infoRect.width <= (left ? spaceLeft : spaceRight)) { + top = (Math.max(0, Math.min(selRect.top, win.innerHeight - infoRect.height)) - listRect.top) + "px"; + maxWidth = Math.min(400 /* Info.Width */, left ? spaceLeft : spaceRight) + "px"; + } + else { + narrow = true; + maxWidth = Math.min(400 /* Info.Width */, (rtl ? listRect.right : win.innerWidth - listRect.left) - 30 /* Info.Margin */) + "px"; + let spaceBelow = win.innerHeight - listRect.bottom; + if (spaceBelow >= infoRect.height || spaceBelow > listRect.top) // Below the completion + top = (selRect.bottom - listRect.top) + "px"; + else // Above it + bottom = (listRect.bottom - selRect.top) + "px"; + } + return { + top, bottom, maxWidth, + class: narrow ? (rtl ? "left-narrow" : "right-narrow") : left ? "left" : "right", + }; } positionInfo(pos) { if (this.info) { - this.info.style.top = (pos ? pos.top : -1e6) + "px"; if (pos) { - this.info.classList.toggle("cm-completionInfo-left", pos.left); - this.info.classList.toggle("cm-completionInfo-right", !pos.left); + this.info.style.top = pos.top; + this.info.style.bottom = pos.bottom; + this.info.style.maxWidth = pos.maxWidth; + this.info.className = "cm-tooltip cm-completionInfo cm-completionInfo-" + pos.class; + } + else { + this.info.style.top = "-1e6px"; } } } @@ -19376,6 +19945,7 @@ class CompletionTooltip { ul.id = id; ul.setAttribute("role", "listbox"); ul.setAttribute("aria-expanded", "true"); + ul.setAttribute("aria-label", this.view.state.phrase("Completions")); for (let i = range.from; i < range.to; i++) { let { completion, match } = options[i]; const li = ul.appendChild(document.createElement("li")); @@ -19442,7 +20012,8 @@ function sortOptions(active, state) { } } let result = [], prev = null; - for (let opt of options.sort(cmpOption)) { + let compare = state.facet(completionConfig).compareCompletions; + for (let opt of options.sort((a, b) => (b.match[0] - a.match[0]) || compare(a.completion, b.completion))) { if (!prev || prev.label != opt.completion.label || prev.detail != opt.completion.detail || (prev.type != null && opt.completion.type != null && prev.type != opt.completion.type) || prev.apply != opt.completion.apply) @@ -19469,8 +20040,8 @@ class CompletionDialog { let options = sortOptions(active, state); if (!options.length) return null; - let selected = 0; - if (prev && prev.selected) { + let selected = state.facet(completionConfig).selectOnOpen ? 0 : -1; + if (prev && prev.selected != selected && prev.selected != -1) { let selectedValue = prev.options[prev.selected].completion; for (let i = 0; i < options.length; i++) if (options[i].completion == selectedValue) { @@ -19503,7 +20074,7 @@ class CompletionState { state.languageDataAt("autocomplete", cur(state)).map(asSource); let active = sources.map(source => { let value = this.active.find(s => s.source == source) || - new ActiveSource(source, this.active.some(a => a.state != 0 /* Inactive */) ? 1 /* Pending */ : 0 /* Inactive */); + new ActiveSource(source, this.active.some(a => a.state != 0 /* State.Inactive */) ? 1 /* State.Pending */ : 0 /* State.Inactive */); return value.update(tr, conf); }); if (active.length == this.active.length && active.every((a, i) => a == this.active[i])) @@ -19511,8 +20082,8 @@ class CompletionState { let open = tr.selection || active.some(a => a.hasResult() && tr.changes.touchesRange(a.from, a.to)) || !sameResults(active, this.active) ? CompletionDialog.build(active, state, this.id, this.open, conf) : this.open && tr.docChanged ? this.open.map(tr.changes) : this.open; - if (!open && active.every(a => a.state != 1 /* Pending */) && active.some(a => a.hasResult())) - active = active.map(a => a.hasResult() ? new ActiveSource(a.source, 0 /* Inactive */) : a); + if (!open && active.every(a => a.state != 1 /* State.Pending */) && active.some(a => a.hasResult())) + active = active.map(a => a.hasResult() ? new ActiveSource(a.source, 0 /* State.Inactive */) : a); for (let effect of tr.effects) if (effect.is(setSelectedEffect)) open = open && open.setSelected(effect.value, this.id); @@ -19540,20 +20111,16 @@ const baseAttrs = { "aria-autocomplete": "list" }; function makeAttrs(id, selected) { - return { + let result = { "aria-autocomplete": "list", "aria-haspopup": "listbox", - "aria-activedescendant": id + "-" + selected, "aria-controls": id }; + if (selected > -1) + result["aria-activedescendant"] = id + "-" + selected; + return result; } const none$2 = []; -function cmpOption(a, b) { - let dScore = b.match[0] - a.match[0]; - if (dScore) - return dScore; - return a.completion.label.localeCompare(b.completion.label); -} function getUserEvent(tr) { return tr.isUserEvent("input.type") ? "input" : tr.isUserEvent("delete.backward") ? "delete" : null; } @@ -19570,13 +20137,13 @@ class ActiveSource { value = value.handleUserEvent(tr, event, conf); else if (tr.docChanged) value = value.handleChange(tr); - else if (tr.selection && value.state != 0 /* Inactive */) - value = new ActiveSource(value.source, 0 /* Inactive */); + else if (tr.selection && value.state != 0 /* State.Inactive */) + value = new ActiveSource(value.source, 0 /* State.Inactive */); for (let effect of tr.effects) { if (effect.is(startCompletionEffect)) - value = new ActiveSource(value.source, 1 /* Pending */, effect.value ? cur(tr.state) : -1); + value = new ActiveSource(value.source, 1 /* State.Pending */, effect.value ? cur(tr.state) : -1); else if (effect.is(closeCompletionEffect)) - value = new ActiveSource(value.source, 0 /* Inactive */); + value = new ActiveSource(value.source, 0 /* State.Inactive */); else if (effect.is(setActiveEffect)) for (let active of effect.value) if (active.source == value.source) @@ -19585,10 +20152,10 @@ class ActiveSource { return value; } handleUserEvent(tr, type, conf) { - return type == "delete" || !conf.activateOnTyping ? this.map(tr.changes) : new ActiveSource(this.source, 1 /* Pending */); + return type == "delete" || !conf.activateOnTyping ? this.map(tr.changes) : new ActiveSource(this.source, 1 /* State.Pending */); } handleChange(tr) { - return tr.changes.touchesRange(cur(tr.startState)) ? new ActiveSource(this.source, 0 /* Inactive */) : this.map(tr.changes); + return tr.changes.touchesRange(cur(tr.startState)) ? new ActiveSource(this.source, 0 /* State.Inactive */) : this.map(tr.changes); } map(changes) { return changes.empty || this.explicitPos < 0 ? this : new ActiveSource(this.source, this.state, changes.mapPos(this.explicitPos)); @@ -19596,7 +20163,7 @@ class ActiveSource { } class ActiveResult extends ActiveSource { constructor(source, explicitPos, result, from, to) { - super(source, 2 /* Result */, explicitPos); + super(source, 2 /* State.Result */, explicitPos); this.result = result; this.from = from; this.to = to; @@ -19609,17 +20176,17 @@ class ActiveResult extends ActiveSource { if ((this.explicitPos < 0 ? pos <= from : pos < this.from) || pos > to || type == "delete" && cur(tr.startState) == this.from) - return new ActiveSource(this.source, type == "input" && conf.activateOnTyping ? 1 /* Pending */ : 0 /* Inactive */); + return new ActiveSource(this.source, type == "input" && conf.activateOnTyping ? 1 /* State.Pending */ : 0 /* State.Inactive */); let explicitPos = this.explicitPos < 0 ? -1 : tr.changes.mapPos(this.explicitPos), updated; if (checkValid(this.result.validFor, tr.state, from, to)) return new ActiveResult(this.source, explicitPos, this.result, from, to); if (this.result.update && (updated = this.result.update(this.result, from, to, new CompletionContext(tr.state, pos, explicitPos >= 0)))) return new ActiveResult(this.source, explicitPos, updated, updated.from, (_a = updated.to) !== null && _a !== void 0 ? _a : cur(tr.state)); - return new ActiveSource(this.source, 1 /* Pending */, explicitPos); + return new ActiveSource(this.source, 1 /* State.Pending */, explicitPos); } handleChange(tr) { - return tr.changes.touchesRange(this.from, this.to) ? new ActiveSource(this.source, 0 /* Inactive */) : this.map(tr.changes); + return tr.changes.touchesRange(this.from, this.to) ? new ActiveSource(this.source, 0 /* State.Inactive */) : this.map(tr.changes); } map(mapping) { return mapping.empty ? this : @@ -19647,7 +20214,6 @@ const completionState = /*@__PURE__*/StateField.define({ ] }); -const CompletionInteractMargin = 75; /** Returns a command that moves the completion selection forward or backward by the given amount. @@ -19655,13 +20221,15 @@ backward by the given amount. function moveCompletionSelection(forward, by = "option") { return (view) => { let cState = view.state.field(completionState, false); - if (!cState || !cState.open || Date.now() - cState.open.timestamp < CompletionInteractMargin) + if (!cState || !cState.open || + Date.now() - cState.open.timestamp < view.state.facet(completionConfig).interactionDelay) return false; let step = 1, tooltip; if (by == "page" && (tooltip = getTooltip(view, cState.open.tooltip))) step = Math.max(2, Math.floor(tooltip.dom.offsetHeight / tooltip.dom.querySelector("li").offsetHeight) - 1); - let selected = cState.open.selected + step * (forward ? 1 : -1), { length } = cState.open.options; + let { length } = cState.open.options; + let selected = cState.open.selected > -1 ? cState.open.selected + step * (forward ? 1 : -1) : forward ? 0 : length - 1; if (selected < 0) selected = by == "page" ? 0 : length - 1; else if (selected >= length) @@ -19675,7 +20243,8 @@ Accept the current completion. */ const acceptCompletion = (view) => { let cState = view.state.field(completionState, false); - if (view.state.readOnly || !cState || !cState.open || Date.now() - cState.open.timestamp < CompletionInteractMargin) + if (view.state.readOnly || !cState || !cState.open || cState.open.selected < 0 || + Date.now() - cState.open.timestamp < view.state.facet(completionConfig).interactionDelay) return false; applyCompletion(view, cState.open.options[cState.open.selected]); return true; @@ -19695,7 +20264,7 @@ Close the currently active completion. */ const closeCompletion = (view) => { let cState = view.state.field(completionState, false); - if (!cState || !cState.active.some(a => a.state != 0 /* Inactive */)) + if (!cState || !cState.active.some(a => a.state != 0 /* State.Inactive */)) return false; view.dispatch({ effects: closeCompletionEffect.of(null) }); return true; @@ -19718,9 +20287,9 @@ const completionPlugin = /*@__PURE__*/ViewPlugin.fromClass(class { this.debounceUpdate = -1; this.running = []; this.debounceAccept = -1; - this.composing = 0 /* None */; + this.composing = 0 /* CompositionState.None */; for (let active of view.state.field(completionState).active) - if (active.state == 1 /* Pending */) + if (active.state == 1 /* State.Pending */) this.startQuery(active); } update(update) { @@ -19751,21 +20320,21 @@ const completionPlugin = /*@__PURE__*/ViewPlugin.fromClass(class { } if (this.debounceUpdate > -1) clearTimeout(this.debounceUpdate); - this.debounceUpdate = cState.active.some(a => a.state == 1 /* Pending */ && !this.running.some(q => q.active.source == a.source)) + this.debounceUpdate = cState.active.some(a => a.state == 1 /* State.Pending */ && !this.running.some(q => q.active.source == a.source)) ? setTimeout(() => this.startUpdate(), DebounceTime) : -1; - if (this.composing != 0 /* None */) + if (this.composing != 0 /* CompositionState.None */) for (let tr of update.transactions) { if (getUserEvent(tr) == "input") - this.composing = 2 /* Changed */; - else if (this.composing == 2 /* Changed */ && tr.selection) - this.composing = 3 /* ChangedAndMoved */; + this.composing = 2 /* CompositionState.Changed */; + else if (this.composing == 2 /* CompositionState.Changed */ && tr.selection) + this.composing = 3 /* CompositionState.ChangedAndMoved */; } } startUpdate() { this.debounceUpdate = -1; let { state } = this.view, cState = state.field(completionState); for (let active of cState.active) { - if (active.state == 1 /* Pending */ && !this.running.some(r => r.active.source == active.source)) + if (active.state == 1 /* State.Pending */ && !this.running.some(r => r.active.source == active.source)) this.startQuery(active); } } @@ -19816,14 +20385,14 @@ const completionPlugin = /*@__PURE__*/ViewPlugin.fromClass(class { } } let current = this.view.state.field(completionState).active.find(a => a.source == query.active.source); - if (current && current.state == 1 /* Pending */) { + if (current && current.state == 1 /* State.Pending */) { if (query.done == null) { // Explicitly failed. Should clear the pending status if it // hasn't been re-set in the meantime. - let active = new ActiveSource(query.active.source, 0 /* Inactive */); + let active = new ActiveSource(query.active.source, 0 /* State.Inactive */); for (let tr of query.updates) active = active.update(tr, conf); - if (active.state != 1 /* Pending */) + if (active.state != 1 /* State.Pending */) updated.push(active); } else { @@ -19843,15 +20412,15 @@ const completionPlugin = /*@__PURE__*/ViewPlugin.fromClass(class { this.view.dispatch({ effects: closeCompletionEffect.of(null) }); }, compositionstart() { - this.composing = 1 /* Started */; + this.composing = 1 /* CompositionState.Started */; }, compositionend() { - if (this.composing == 3 /* ChangedAndMoved */) { + if (this.composing == 3 /* CompositionState.ChangedAndMoved */) { // Safari fires compositionend events synchronously, possibly // from inside an update, so dispatch asynchronously to avoid reentrancy setTimeout(() => this.view.dispatch({ effects: startCompletionEffect.of(false) }), 20); } - this.composing = 0 /* None */; + this.composing = 0 /* CompositionState.None */; } } }); @@ -19896,16 +20465,20 @@ const baseTheme$2 = /*@__PURE__*/EditorView.baseTheme({ position: "absolute", padding: "3px 9px", width: "max-content", - maxWidth: "300px", + maxWidth: `${400 /* Info.Width */}px`, + boxSizing: "border-box" }, ".cm-completionInfo.cm-completionInfo-left": { right: "100%" }, ".cm-completionInfo.cm-completionInfo-right": { left: "100%" }, + ".cm-completionInfo.cm-completionInfo-left-narrow": { right: `${30 /* Info.Margin */}px` }, + ".cm-completionInfo.cm-completionInfo-right-narrow": { left: `${30 /* Info.Margin */}px` }, "&light .cm-snippetField": { backgroundColor: "#00000022" }, "&dark .cm-snippetField": { backgroundColor: "#ffffff22" }, ".cm-snippetFieldPosition": { verticalAlign: "text-top", width: 0, height: "1.15em", + display: "inline-block", margin: "0 -0.7px -.7em", borderLeft: "1.4px dotted #888" }, @@ -20024,6 +20597,14 @@ class Snippet { positions.push(new FieldPos(found, lines.length, m.index, m.index + name.length)); line = line.slice(0, m.index) + name + line.slice(m.index + m[0].length); } + for (let esc; esc = /([$#])\\{/.exec(line);) { + line = line.slice(0, esc.index) + esc[1] + "{" + line.slice(esc.index + esc[0].length); + for (let pos of positions) + if (pos.line == lines.length && pos.from > esc.index) { + pos.from--; + pos.to--; + } + } lines.push(line); } return new Snippet(lines, positions); @@ -20107,12 +20688,20 @@ cursor out of the current field deactivates the fields. The order of fields defaults to textual order, but you can add numbers to placeholders (`${1}` or `${1:defaultText}`) to provide a custom order. + +To include a literal `${` or `#{` in your template, put a +backslash after the dollar or hash and before the brace (`$\\{`). +This will be removed and the sequence will not be interpreted as a +placeholder. */ function snippet(template) { let snippet = Snippet.parse(template); return (editor, _completion, from, to) => { let { text, ranges } = snippet.instantiate(editor.state, from); - let spec = { changes: { from, to, insert: Text.of(text) } }; + let spec = { + changes: { from, to, insert: Text.of(text) }, + scrollIntoView: true + }; if (ranges.length) spec.selection = fieldSelection(ranges, 0); if (ranges.length > 1) { @@ -20218,7 +20807,7 @@ function storeWords(doc, wordRE, result, seen, ignoreAt) { if (!seen[m[0]] && pos + m.index != ignoreAt) { result.push({ type: "text", label: m[0] }); seen[m[0]] = true; - if (result.length >= 2000 /* MaxList */) + if (result.length >= 2000 /* C.MaxList */) return; } } @@ -20226,7 +20815,7 @@ function storeWords(doc, wordRE, result, seen, ignoreAt) { } } function collectWords(doc, cache, wordRE, to, ignoreAt) { - let big = doc.length >= 1000 /* MinCacheLen */; + let big = doc.length >= 1000 /* C.MinCacheLen */; let cached = big && cache.get(doc); if (cached) return cached; @@ -20234,7 +20823,7 @@ function collectWords(doc, cache, wordRE, to, ignoreAt) { if (doc.children) { let pos = 0; for (let ch of doc.children) { - if (ch.length >= 1000 /* MinCacheLen */) { + if (ch.length >= 1000 /* C.MinCacheLen */) { for (let c of collectWords(ch, cache, wordRE, to - pos, ignoreAt - pos)) { if (!seen[c.label]) { seen[c.label] = true; @@ -20251,7 +20840,7 @@ function collectWords(doc, cache, wordRE, to, ignoreAt) { else { storeWords(doc, wordRE, result, seen, ignoreAt); } - if (big && result.length < 2000 /* MaxList */) + if (big && result.length < 2000 /* C.MaxList */) cache.set(doc, result); return result; } @@ -20267,13 +20856,14 @@ const completeAnyWord = context => { if (!token && !context.explicit) return null; let from = token ? token.from : context.pos; - let options = collectWords(context.state.doc, wordCache(wordChars), re, 50000 /* Range */, from); + let options = collectWords(context.state.doc, wordCache(wordChars), re, 50000 /* C.Range */, from); return { from, options, validFor: mapRE(re, s => "^" + s) }; }; const defaults$1 = { brackets: ["(", "[", "{", "'", '"'], - before: ")]}:;>" + before: ")]}:;>", + stringPrefixes: [] }; const closeBracketEffect = /*@__PURE__*/StateEffect.define({ map(value, mapping) { @@ -20356,14 +20946,13 @@ const deleteBracketPair = ({ state, dispatch }) => { for (let token of tokens) { if (token == before && nextChar(state.doc, range.head) == closing(codePointAt(token, 0))) return { changes: { from: range.head - token.length, to: range.head + token.length }, - range: EditorSelection.cursor(range.head - token.length), - userEvent: "delete.backward" }; + range: EditorSelection.cursor(range.head - token.length) }; } } return { range: dont = range }; }); if (!dont) - dispatch(state.update(changes, { scrollIntoView: true })); + dispatch(state.update(changes, { scrollIntoView: true, userEvent: "delete.backward" })); return !dont; }; /** @@ -20390,7 +20979,7 @@ function insertBracket(state, bracket) { for (let tok of tokens) { let closed = closing(codePointAt(tok, 0)); if (bracket == tok) - return closed == tok ? handleSame(state, tok, tokens.indexOf(tok + tok + tok) > -1) + return closed == tok ? handleSame(state, tok, tokens.indexOf(tok + tok + tok) > -1, conf) : handleOpen(state, tok, closed, conf.before || defaults$1.before); if (bracket == closed && closedBracketAt(state, state.selection.main.from)) return handleClose(state, tok, closed); @@ -20445,15 +21034,16 @@ function handleClose(state, _open, close) { } // Handles cases where the open and close token are the same, and // possibly triple quotes (as in `"""abc"""`-style quoting). -function handleSame(state, token, allowTriple) { +function handleSame(state, token, allowTriple, config) { + let stringPrefixes = config.stringPrefixes || defaults$1.stringPrefixes; let dont = null, changes = state.changeByRange(range => { if (!range.empty) return { changes: [{ insert: token, from: range.from }, { insert: token, from: range.to }], effects: closeBracketEffect.of(range.to + token.length), range: EditorSelection.range(range.anchor + token.length, range.head + token.length) }; - let pos = range.head, next = nextChar(state.doc, pos); + let pos = range.head, next = nextChar(state.doc, pos), start; if (next == token) { - if (nodeStart$1(state, pos)) { + if (nodeStart(state, pos)) { return { changes: { insert: token + token, from: pos }, effects: closeBracketEffect.of(pos + token.length), range: EditorSelection.cursor(pos + token.length) }; @@ -20465,14 +21055,14 @@ function handleSame(state, token, allowTriple) { } } else if (allowTriple && state.sliceDoc(pos - 2 * token.length, pos) == token + token && - nodeStart$1(state, pos - 2 * token.length)) { + (start = canStartStringAt(state, pos - 2 * token.length, stringPrefixes)) > -1 && + nodeStart(state, start)) { return { changes: { insert: token + token + token + token, from: pos }, effects: closeBracketEffect.of(pos + token.length), range: EditorSelection.cursor(pos + token.length) }; } else if (state.charCategorizer(pos)(next) != CharCategory.Word) { - let prev = state.sliceDoc(pos - 1, pos); - if (prev != token && state.charCategorizer(pos)(prev) != CharCategory.Word && !probablyInString(state, pos, token)) + if (canStartStringAt(state, pos, stringPrefixes) > -1 && !probablyInString(state, pos, token, stringPrefixes)) return { changes: { insert: token + token, from: pos }, effects: closeBracketEffect.of(pos + token.length), range: EditorSelection.cursor(pos + token.length) }; @@ -20484,15 +21074,25 @@ function handleSame(state, token, allowTriple) { userEvent: "input.type" }); } -function nodeStart$1(state, pos) { +function nodeStart(state, pos) { let tree = syntaxTree(state).resolveInner(pos + 1); return tree.parent && tree.from == pos; } -function probablyInString(state, pos, quoteToken) { +function probablyInString(state, pos, quoteToken, prefixes) { let node = syntaxTree(state).resolveInner(pos, -1); + let maxPrefix = prefixes.reduce((m, p) => Math.max(m, p.length), 0); for (let i = 0; i < 5; i++) { - if (state.sliceDoc(node.from, node.from + quoteToken.length) == quoteToken) + let start = state.sliceDoc(node.from, Math.min(node.to, node.from + quoteToken.length + maxPrefix)); + let quotePos = start.indexOf(quoteToken); + if (!quotePos || quotePos > -1 && prefixes.indexOf(start.slice(0, quotePos)) > -1) { + let first = node.firstChild; + while (first && first.from == node.from && first.to - first.from > quoteToken.length + quotePos) { + if (state.sliceDoc(first.to - quoteToken.length, first.to) == quoteToken) + return false; + first = first.firstChild; + } return true; + } let parent = node.to == pos && node.parent; if (!parent) break; @@ -20500,6 +21100,17 @@ function probablyInString(state, pos, quoteToken) { } return false; } +function canStartStringAt(state, pos, prefixes) { + let charCat = state.charCategorizer(pos); + if (charCat(state.sliceDoc(pos - 1, pos)) != CharCategory.Word) + return pos; + for (let prefix of prefixes) { + let start = pos - prefix.length; + if (state.sliceDoc(start, pos) == prefix && charCat(state.sliceDoc(start - 1, start)) != CharCategory.Word) + return start; + } + return -1; +} /** Returns an extension that enables autocompletion. @@ -20542,8 +21153,8 @@ returns `null`. */ function completionStatus(state) { let cState = state.field(completionState, false); - return cState && cState.active.some(a => a.state == 1 /* Pending */) ? "pending" - : cState && cState.active.some(a => a.state != 0 /* Inactive */) ? "active" : null; + return cState && cState.active.some(a => a.state == 1 /* State.Pending */) ? "pending" + : cState && cState.active.some(a => a.state != 0 /* State.Inactive */) ? "active" : null; } const completionArrayCache = /*@__PURE__*/new WeakMap; /** @@ -20565,7 +21176,7 @@ Return the currently selected completion, if any. function selectedCompletion(state) { var _a; let open = (_a = state.field(completionState, false)) === null || _a === void 0 ? void 0 : _a.open; - return open ? open.options[open.selected].completion : null; + return open && open.selected >= 0 ? open.options[open.selected].completion : null; } /** Returns the currently selected position in the active completion @@ -20574,7 +21185,7 @@ list, or null if no completions are active. function selectedCompletionIndex(state) { var _a; let open = (_a = state.field(completionState, false)) === null || _a === void 0 ? void 0 : _a.open; - return open ? open.selected : null; + return open && open.selected >= 0 ? open.selected : null; } /** Create an effect that can be attached to a transaction to change @@ -20602,6 +21213,7 @@ var index = /*#__PURE__*/Object.freeze({ ifIn: ifIn, ifNotIn: ifNotIn, insertBracket: insertBracket, + insertCompletionText: insertCompletionText, moveCompletionSelection: moveCompletionSelection, nextSnippetField: nextSnippetField, pickedCompletion: pickedCompletion, @@ -20774,19 +21386,19 @@ The line comment syntax is taken from the [`commentTokens`](https://codemirror.net/6/docs/ref/#commands.CommentTokens) [language data](https://codemirror.net/6/docs/ref/#state.EditorState.languageDataAt). */ -const toggleLineComment = /*@__PURE__*/command(changeLineComment, 0 /* Toggle */); +const toggleLineComment = /*@__PURE__*/command(changeLineComment, 0 /* CommentOption.Toggle */); /** Comment or uncomment the current selection using block comments. The block comment syntax is taken from the [`commentTokens`](https://codemirror.net/6/docs/ref/#commands.CommentTokens) [language data](https://codemirror.net/6/docs/ref/#state.EditorState.languageDataAt). */ -const toggleBlockComment = /*@__PURE__*/command(changeBlockComment, 0 /* Toggle */); +const toggleBlockComment = /*@__PURE__*/command(changeBlockComment, 0 /* CommentOption.Toggle */); /** Comment or uncomment the lines around the current selection using block comments. */ -const toggleBlockCommentByLine = /*@__PURE__*/command((o, s) => changeBlockComment(o, s, selectedLineRanges(s)), 0 /* Toggle */); +const toggleBlockCommentByLine = /*@__PURE__*/command((o, s) => changeBlockComment(o, s, selectedLineRanges(s)), 0 /* CommentOption.Toggle */); function getConfig(state, pos = state.selection.main.head) { let data = state.languageDataAt("commentTokens", pos); return data.length ? data[0] : {}; @@ -20845,14 +21457,14 @@ function changeBlockComment(option, state, ranges = state.selection.ranges) { if (!tokens.every(c => c)) return null; let comments = ranges.map((r, i) => findBlockComment(state, tokens[i], r.from, r.to)); - if (option != 2 /* Uncomment */ && !comments.every(c => c)) { + if (option != 2 /* CommentOption.Uncomment */ && !comments.every(c => c)) { return { changes: state.changes(ranges.map((range, i) => { if (comments[i]) return []; return [{ from: range.from, insert: tokens[i].open + " " }, { from: range.to, insert: " " + tokens[i].close }]; })) }; } - else if (option != 1 /* Comment */ && comments.some(c => c)) { + else if (option != 1 /* CommentOption.Comment */ && comments.some(c => c)) { let changes = []; for (let i = 0, comment; i < comments.length; i++) if (comment = comments[i]) { @@ -20892,7 +21504,7 @@ function changeLineComment(option, state, ranges = state.selection.ranges) { if (lines.length == startI + 1) lines[startI].single = true; } - if (option != 2 /* Uncomment */ && lines.some(l => l.comment < 0 && (!l.empty || l.single))) { + if (option != 2 /* CommentOption.Uncomment */ && lines.some(l => l.comment < 0 && (!l.empty || l.single))) { let changes = []; for (let { line, token, indent, empty, single } of lines) if (single || !empty) @@ -20900,7 +21512,7 @@ function changeLineComment(option, state, ranges = state.selection.ranges) { let changeSet = state.changes(changes); return { changes: changeSet, selection: state.selection.map(changeSet, 1) }; } - else if (option != 1 /* Comment */ && lines.some(l => l.comment >= 0)) { + else if (option != 1 /* CommentOption.Comment */ && lines.some(l => l.comment >= 0)) { let changes = []; for (let { line, comment, token } of lines) if (comment >= 0) { @@ -20954,12 +21566,12 @@ const historyField_ = /*@__PURE__*/StateField.define({ if (fromHist) { let selection = tr.docChanged ? EditorSelection.single(changeEnd(tr.changes)) : undefined; let item = HistEvent.fromTransaction(tr, selection), from = fromHist.side; - let other = from == 0 /* Done */ ? state.undone : state.done; + let other = from == 0 /* BranchName.Done */ ? state.undone : state.done; if (item) other = updateBranch(other, other.length, config.minDepth, item); else other = addSelection(other, tr.startState.selection); - return new HistoryState(from == 0 /* Done */ ? fromHist.rest : other, from == 0 /* Done */ ? other : fromHist.rest); + return new HistoryState(from == 0 /* BranchName.Done */ ? fromHist.rest : other, from == 0 /* BranchName.Done */ ? other : fromHist.rest); } let isolate = tr.annotation(isolateHistory); if (isolate == "full" || isolate == "before") @@ -21019,20 +21631,20 @@ function cmd(side, selection) { Undo a single group of history events. Returns false if no group was available. */ -const undo = /*@__PURE__*/cmd(0 /* Done */, false); +const undo = /*@__PURE__*/cmd(0 /* BranchName.Done */, false); /** Redo a group of history events. Returns false if no group was available. */ -const redo = /*@__PURE__*/cmd(1 /* Undone */, false); +const redo = /*@__PURE__*/cmd(1 /* BranchName.Undone */, false); /** Undo a change or selection change. */ -const undoSelection = /*@__PURE__*/cmd(0 /* Done */, true); +const undoSelection = /*@__PURE__*/cmd(0 /* BranchName.Done */, true); /** Redo a change or selection change. */ -const redoSelection = /*@__PURE__*/cmd(1 /* Undone */, true); +const redoSelection = /*@__PURE__*/cmd(1 /* BranchName.Undone */, true); // History events store groups of changes or effects that need to be // undone/redone together. class HistEvent { @@ -21044,7 +21656,10 @@ class HistEvent { // changes == startSelection == undefined changes, // The effects associated with this event - effects, mapped, + effects, + // Accumulated mapping (from addToHistory==false) that should be + // applied to events below this one. + mapped, // The selection before this event startSelection, // Stores selection changes after this event, to be used for @@ -21207,7 +21822,7 @@ class HistoryState { return new HistoryState(addMappingToBranch(this.done, mapping), addMappingToBranch(this.undone, mapping), this.prevTime, this.prevUserEvent); } pop(side, state, selection) { - let branch = side == 0 /* Done */ ? this.done : this.undone; + let branch = side == 0 /* BranchName.Done */ ? this.done : this.undone; if (branch.length == 0) return null; let event = branch[branch.length - 1]; @@ -21215,7 +21830,7 @@ class HistoryState { return state.update({ selection: event.selectionsAfter[event.selectionsAfter.length - 1], annotations: fromHistory.of({ side, rest: popSelection(branch) }), - userEvent: side == 0 /* Done */ ? "select.undo" : "select.redo", + userEvent: side == 0 /* BranchName.Done */ ? "select.undo" : "select.redo", scrollIntoView: true }); } @@ -21232,7 +21847,7 @@ class HistoryState { effects: event.effects, annotations: fromHistory.of({ side, rest }), filter: false, - userEvent: side == 0 /* Done */ ? "undo" : "redo", + userEvent: side == 0 /* BranchName.Done */ ? "undo" : "redo", scrollIntoView: true }); } @@ -21243,13 +21858,14 @@ HistoryState.empty = /*@__PURE__*/new HistoryState(none$1, none$1); Default key bindings for the undo history. - Mod-z: [`undo`](https://codemirror.net/6/docs/ref/#commands.undo). -- Mod-y (Mod-Shift-z on macOS): [`redo`](https://codemirror.net/6/docs/ref/#commands.redo). +- Mod-y (Mod-Shift-z on macOS) + Ctrl-Shift-z on Linux: [`redo`](https://codemirror.net/6/docs/ref/#commands.redo). - Mod-u: [`undoSelection`](https://codemirror.net/6/docs/ref/#commands.undoSelection). - Alt-u (Mod-Shift-u on macOS): [`redoSelection`](https://codemirror.net/6/docs/ref/#commands.redoSelection). */ const historyKeymap = [ { key: "Mod-z", run: undo, preventDefault: true }, { key: "Mod-y", mac: "Mod-Shift-z", run: redo, preventDefault: true }, + { linux: "Ctrl-Shift-z", run: redo, preventDefault: true }, { key: "Mod-u", run: undoSelection, preventDefault: true }, { key: "Alt-u", mac: "Mod-Shift-u", run: redoSelection, preventDefault: true } ]; @@ -21348,10 +21964,12 @@ const cursorLineUp = view => cursorByLine(view, false); Move the selection one line down. */ const cursorLineDown = view => cursorByLine(view, true); +function pageHeight(view) { + return Math.max(view.defaultLineHeight, Math.min(view.dom.clientHeight, innerHeight) - 5); +} function cursorByPage(view, forward) { let { state } = view, selection = updateSel(state.selection, range => { - return range.empty ? view.moveVertically(range, forward, Math.min(view.dom.clientHeight, innerHeight)) - : rangeEnd(range, forward); + return range.empty ? view.moveVertically(range, forward, pageHeight(view)) : rangeEnd(range, forward); }); if (selection.eq(state.selection)) return false; @@ -21396,6 +22014,14 @@ end of the indentation instead of the start of the line. */ const cursorLineBoundaryBackward = view => moveSel(view, range => moveByLineBoundary(view, range, false)); /** +Move the selection one line wrap point to the left. +*/ +const cursorLineBoundaryLeft = view => moveSel(view, range => moveByLineBoundary(view, range, !ltrAtCursor(view))); +/** +Move the selection one line wrap point to the right. +*/ +const cursorLineBoundaryRight = view => moveSel(view, range => moveByLineBoundary(view, range, ltrAtCursor(view))); +/** Move the selection to the start of the line. */ const cursorLineStart = view => moveSel(view, range => EditorSelection.cursor(view.lineBlockAt(range.head).from, 1)); @@ -21479,7 +22105,7 @@ Move the selection head one line down. */ const selectLineDown = view => selectByLine(view, true); function selectByPage(view, forward) { - return extendSel(view, range => view.moveVertically(range, forward, Math.min(view.dom.clientHeight, innerHeight))); + return extendSel(view, range => view.moveVertically(range, forward, pageHeight(view))); } /** Move the selection head one page up. @@ -21498,6 +22124,14 @@ Move the selection head to the previous line boundary. */ const selectLineBoundaryBackward = view => extendSel(view, range => moveByLineBoundary(view, range, false)); /** +Move the selection head one line boundary to the left. +*/ +const selectLineBoundaryLeft = view => extendSel(view, range => moveByLineBoundary(view, range, !ltrAtCursor(view))); +/** +Move the selection head one line boundary to the right. +*/ +const selectLineBoundaryRight = view => extendSel(view, range => moveByLineBoundary(view, range, ltrAtCursor(view))); +/** Move the selection head to the start of the line. */ const selectLineStart = view => extendSel(view, range => EditorSelection.cursor(view.lineBlockAt(range.head).from)); @@ -21583,26 +22217,38 @@ const simplifySelection = ({ state, dispatch }) => { dispatch(setSel(state, selection)); return true; }; -function deleteBy({ state, dispatch }, by) { - if (state.readOnly) +function deleteBy(target, by) { + if (target.state.readOnly) return false; - let event = "delete.selection"; + let event = "delete.selection", { state } = target; let changes = state.changeByRange(range => { let { from, to } = range; if (from == to) { let towards = by(from); - if (towards < from) + if (towards < from) { event = "delete.backward"; - else if (towards > from) + towards = skipAtomic(target, towards, false); + } + else if (towards > from) { event = "delete.forward"; + towards = skipAtomic(target, towards, true); + } from = Math.min(from, towards); to = Math.max(to, towards); } + else { + from = skipAtomic(target, from, false); + to = skipAtomic(target, to, true); + } return from == to ? { range } : { changes: { from, to }, range: EditorSelection.cursor(from) }; }); if (changes.changes.empty) return false; - dispatch(state.update(changes, { scrollIntoView: true, userEvent: event })); + target.dispatch(state.update(changes, { + scrollIntoView: true, + userEvent: event, + effects: event == "delete.selection" ? EditorView.announce.of(state.phrase("Selection deleted")) : undefined + })); return true; } function skipAtomic(target, pos, forward) { @@ -21630,7 +22276,7 @@ const deleteByChar = (target, forward) => deleteBy(target, pos => { if (targetPos == pos && line.number != (forward ? state.doc.lines : 1)) targetPos += forward ? 1 : -1; } - return skipAtomic(target, targetPos, forward); + return targetPos; }); /** Delete the selection, or, for cursor selections, the character @@ -21659,7 +22305,7 @@ const deleteByGroup = (target, forward) => deleteBy(target, start => { cat = nextCat; pos = next; } - return skipAtomic(target, pos, forward); + return pos; }); /** Delete the selection or backward until the end of the next @@ -21678,7 +22324,7 @@ line, delete the line break after it. */ const deleteToLineEnd = view => deleteBy(view, pos => { let lineEnd = view.lineBlockAt(pos).to; - return skipAtomic(view, pos < lineEnd ? lineEnd : Math.min(view.state.doc.length, pos + 1), true); + return pos < lineEnd ? lineEnd : Math.min(view.state.doc.length, pos + 1); }); /** Delete the selection, or, if it is a cursor selection, delete to @@ -21687,7 +22333,7 @@ line, delete the line break before it. */ const deleteToLineStart = view => deleteBy(view, pos => { let lineStart = view.lineBlockAt(pos).from; - return skipAtomic(view, pos > lineStart ? lineStart : Math.max(0, pos - 1), false); + return pos > lineStart ? lineStart : Math.max(0, pos - 1); }); /** Replace each selection range with a line break, leaving the cursor @@ -22016,11 +22662,11 @@ property changed to `mac`.) */ const standardKeymap = /*@__PURE__*/[ { key: "ArrowLeft", run: cursorCharLeft, shift: selectCharLeft, preventDefault: true }, - { key: "Mod-ArrowLeft", mac: "Alt-ArrowLeft", run: cursorGroupLeft, shift: selectGroupLeft }, - { mac: "Cmd-ArrowLeft", run: cursorLineBoundaryBackward, shift: selectLineBoundaryBackward }, + { key: "Mod-ArrowLeft", mac: "Alt-ArrowLeft", run: cursorGroupLeft, shift: selectGroupLeft, preventDefault: true }, + { mac: "Cmd-ArrowLeft", run: cursorLineBoundaryLeft, shift: selectLineBoundaryLeft, preventDefault: true }, { key: "ArrowRight", run: cursorCharRight, shift: selectCharRight, preventDefault: true }, - { key: "Mod-ArrowRight", mac: "Alt-ArrowRight", run: cursorGroupRight, shift: selectGroupRight }, - { mac: "Cmd-ArrowRight", run: cursorLineBoundaryForward, shift: selectLineBoundaryForward }, + { key: "Mod-ArrowRight", mac: "Alt-ArrowRight", run: cursorGroupRight, shift: selectGroupRight, preventDefault: true }, + { mac: "Cmd-ArrowRight", run: cursorLineBoundaryRight, shift: selectLineBoundaryRight, preventDefault: true }, { key: "ArrowUp", run: cursorLineUp, shift: selectLineUp, preventDefault: true }, { mac: "Cmd-ArrowUp", run: cursorDocStart, shift: selectDocStart }, { mac: "Ctrl-ArrowUp", run: cursorPageUp, shift: selectPageUp }, @@ -22132,7 +22778,8 @@ class SearchCursor { [`.normalize("NFKD")`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize) (when supported). */ - constructor(text, query, from = 0, to = text.length, normalize) { + constructor(text, query, from = 0, to = text.length, normalize, test) { + this.test = test; /** The current match (only holds a meaningful value after [`next`](https://codemirror.net/6/docs/ref/#search.SearchCursor.next) has been called and when @@ -22226,6 +22873,8 @@ class SearchCursor { else this.matches.push(1, pos); } + if (match && this.test && !this.test(match.from, match.to, this.buffer, this.bufferPos)) + match = null; return match; } } @@ -22246,6 +22895,7 @@ class RegExpCursor { `new RegExp`). */ constructor(text, query, options, from = 0, to = text.length) { + this.text = text; this.to = to; this.curLine = ""; /** @@ -22262,10 +22912,11 @@ class RegExpCursor { if (/\\[sWDnr]|\n|\r|\[\^/.test(query)) return new MultilineRegExpCursor(text, query, options, from, to); this.re = new RegExp(query, baseFlags + ((options === null || options === void 0 ? void 0 : options.ignoreCase) ? "i" : "")); + this.test = options === null || options === void 0 ? void 0 : options.test; this.iter = text.iter(); let startLine = text.lineAt(from); this.curLineStart = startLine.from; - this.matchPos = from; + this.matchPos = toCharEnd(text, from); this.getLine(this.curLineStart); } getLine(skip) { @@ -22296,10 +22947,10 @@ class RegExpCursor { let match = this.matchPos <= this.to && this.re.exec(this.curLine); if (match) { let from = this.curLineStart + match.index, to = from + match[0].length; - this.matchPos = to + (from == to ? 1 : 0); - if (from == this.curLine.length) + this.matchPos = toCharEnd(this.text, to + (from == to ? 1 : 0)); + if (from == this.curLineStart + this.curLine.length) this.nextLine(); - if (from < to || from > this.value.to) { + if ((from < to || from > this.value.to) && (!this.test || this.test(from, to, match))) { this.value = { from, to, match }; return this; } @@ -22350,9 +23001,10 @@ class MultilineRegExpCursor { this.to = to; this.done = false; this.value = empty; - this.matchPos = from; + this.matchPos = toCharEnd(text, from); this.re = new RegExp(query, baseFlags + ((options === null || options === void 0 ? void 0 : options.ignoreCase) ? "i" : "")); - this.flat = FlattenedDoc.get(text, from, this.chunkEnd(from + 5000 /* Base */)); + this.test = options === null || options === void 0 ? void 0 : options.test; + this.flat = FlattenedDoc.get(text, from, this.chunkEnd(from + 5000 /* Chunk.Base */)); } chunkEnd(pos) { return pos >= this.to ? this.to : this.text.lineAt(pos).to; @@ -22366,24 +23018,23 @@ class MultilineRegExpCursor { this.re.lastIndex = off + 1; match = this.re.exec(this.flat.text); } - // If a match goes almost to the end of a noncomplete chunk, try - // again, since it'll likely be able to match more - if (match && this.flat.to < this.to && match.index + match[0].length > this.flat.text.length - 10) - match = null; if (match) { let from = this.flat.from + match.index, to = from + match[0].length; - this.value = { from, to, match }; - this.matchPos = to + (from == to ? 1 : 0); - return this; - } - else { - if (this.flat.to == this.to) { - this.done = true; + // If a match goes almost to the end of a noncomplete chunk, try + // again, since it'll likely be able to match more + if ((this.flat.to >= this.to || match.index + match[0].length <= this.flat.text.length - 10) && + (!this.test || this.test(from, to, match))) { + this.value = { from, to, match }; + this.matchPos = toCharEnd(this.text, to + (from == to ? 1 : 0)); return this; } - // Grow the flattened doc - this.flat = FlattenedDoc.get(this.text, this.flat.from, this.chunkEnd(this.flat.from + this.flat.text.length * 2)); } + if (this.flat.to == this.to) { + this.done = true; + return this; + } + // Grow the flattened doc + this.flat = FlattenedDoc.get(this.text, this.flat.from, this.chunkEnd(this.flat.from + this.flat.text.length * 2)); } } } @@ -22400,6 +23051,14 @@ function validRegExp(source) { return false; } } +function toCharEnd(text, pos) { + if (pos >= text.length) + return pos; + let line = text.lineAt(pos), next; + while (pos < line.to && (next = line.text.charCodeAt(pos - line.from)) >= 0xDC00 && next < 0xE000) + pos++; + return pos; +} function createLineDialog(view) { let input = crelt("input", { class: "cm-textfield", name: "line" }); @@ -22651,12 +23310,13 @@ const selectNextOccurrence = ({ state, dispatch }) => { const searchConfigFacet = /*@__PURE__*/Facet.define({ combine(configs) { - var _a; - return { - top: configs.reduce((val, conf) => val !== null && val !== void 0 ? val : conf.top, undefined) || false, - caseSensitive: configs.reduce((val, conf) => val !== null && val !== void 0 ? val : conf.caseSensitive, undefined) || false, - createPanel: ((_a = configs.find(c => c.createPanel)) === null || _a === void 0 ? void 0 : _a.createPanel) || (view => new SearchPanel(view)) - }; + return combineConfig(configs, { + top: false, + caseSensitive: false, + literal: false, + wholeWord: false, + createPanel: view => new SearchPanel(view) + }); } }); /** @@ -22669,17 +23329,27 @@ class SearchQuery { constructor(config) { this.search = config.search; this.caseSensitive = !!config.caseSensitive; + this.literal = !!config.literal; this.regexp = !!config.regexp; this.replace = config.replace || ""; this.valid = !!this.search && (!this.regexp || validRegExp(this.search)); - this.unquoted = config.literal ? this.search : this.search.replace(/\\([nrt\\])/g, (_, ch) => ch == "n" ? "\n" : ch == "r" ? "\r" : ch == "t" ? "\t" : "\\"); + this.unquoted = this.unquote(this.search); + this.wholeWord = !!config.wholeWord; + } + /** + @internal + */ + unquote(text) { + return this.literal ? text : + text.replace(/\\([nrt\\])/g, (_, ch) => ch == "n" ? "\n" : ch == "r" ? "\r" : ch == "t" ? "\t" : "\\"); } /** Compare this query to another query. */ eq(other) { return this.search == other.search && this.replace == other.replace && - this.caseSensitive == other.caseSensitive && this.regexp == other.regexp; + this.caseSensitive == other.caseSensitive && this.regexp == other.regexp && + this.wholeWord == other.wholeWord; } /** @internal @@ -22689,10 +23359,13 @@ class SearchQuery { } /** Get a search cursor for this query, searching through the given - range in the given document. + range in the given state. */ - getCursor(doc, from = 0, to = doc.length) { - return this.regexp ? regexpCursor(this, doc, from, to) : stringCursor(this, doc, from, to); + getCursor(state, from = 0, to) { + let st = state.doc ? state : EditorState.create({ doc: state }); + if (to == null) + to = st.doc.length; + return this.regexp ? regexpCursor(this, st, from, to) : stringCursor(this, st, from, to); } } class QueryType { @@ -22700,41 +23373,53 @@ class QueryType { this.spec = spec; } } -function stringCursor(spec, doc, from, to) { - return new SearchCursor(doc, spec.unquoted, from, to, spec.caseSensitive ? undefined : x => x.toLowerCase()); +function stringCursor(spec, state, from, to) { + return new SearchCursor(state.doc, spec.unquoted, from, to, spec.caseSensitive ? undefined : x => x.toLowerCase(), spec.wholeWord ? stringWordTest(state.doc, state.charCategorizer(state.selection.main.head)) : undefined); +} +function stringWordTest(doc, categorizer) { + return (from, to, buf, bufPos) => { + if (bufPos > from || bufPos + buf.length < to) { + bufPos = Math.max(0, from - 2); + buf = doc.sliceString(bufPos, Math.min(doc.length, to + 2)); + } + return (categorizer(charBefore(buf, from - bufPos)) != CharCategory.Word || + categorizer(charAfter(buf, from - bufPos)) != CharCategory.Word) && + (categorizer(charAfter(buf, to - bufPos)) != CharCategory.Word || + categorizer(charBefore(buf, to - bufPos)) != CharCategory.Word); + }; } class StringQuery extends QueryType { constructor(spec) { super(spec); } - nextMatch(doc, curFrom, curTo) { - let cursor = stringCursor(this.spec, doc, curTo, doc.length).nextOverlapping(); + nextMatch(state, curFrom, curTo) { + let cursor = stringCursor(this.spec, state, curTo, state.doc.length).nextOverlapping(); if (cursor.done) - cursor = stringCursor(this.spec, doc, 0, curFrom).nextOverlapping(); + cursor = stringCursor(this.spec, state, 0, curFrom).nextOverlapping(); return cursor.done ? null : cursor.value; } // Searching in reverse is, rather than implementing inverted search // cursor, done by scanning chunk after chunk forward. - prevMatchInRange(doc, from, to) { + prevMatchInRange(state, from, to) { for (let pos = to;;) { - let start = Math.max(from, pos - 10000 /* ChunkSize */ - this.spec.unquoted.length); - let cursor = stringCursor(this.spec, doc, start, pos), range = null; + let start = Math.max(from, pos - 10000 /* FindPrev.ChunkSize */ - this.spec.unquoted.length); + let cursor = stringCursor(this.spec, state, start, pos), range = null; while (!cursor.nextOverlapping().done) range = cursor.value; if (range) return range; if (start == from) return null; - pos -= 10000 /* ChunkSize */; + pos -= 10000 /* FindPrev.ChunkSize */; } } - prevMatch(doc, curFrom, curTo) { - return this.prevMatchInRange(doc, 0, curFrom) || - this.prevMatchInRange(doc, curTo, doc.length); + prevMatch(state, curFrom, curTo) { + return this.prevMatchInRange(state, 0, curFrom) || + this.prevMatchInRange(state, curTo, state.doc.length); } - getReplacement(_result) { return this.spec.replace; } - matchAll(doc, limit) { - let cursor = stringCursor(this.spec, doc, 0, doc.length), ranges = []; + getReplacement(_result) { return this.spec.unquote(this.spec.replace); } + matchAll(state, limit) { + let cursor = stringCursor(this.spec, state, 0, state.doc.length), ranges = []; while (!cursor.next().done) { if (ranges.length >= limit) return null; @@ -22742,26 +23427,42 @@ class StringQuery extends QueryType { } return ranges; } - highlight(doc, from, to, add) { - let cursor = stringCursor(this.spec, doc, Math.max(0, from - this.spec.unquoted.length), Math.min(to + this.spec.unquoted.length, doc.length)); + highlight(state, from, to, add) { + let cursor = stringCursor(this.spec, state, Math.max(0, from - this.spec.unquoted.length), Math.min(to + this.spec.unquoted.length, state.doc.length)); while (!cursor.next().done) add(cursor.value.from, cursor.value.to); } } -function regexpCursor(spec, doc, from, to) { - return new RegExpCursor(doc, spec.search, spec.caseSensitive ? undefined : { ignoreCase: true }, from, to); +function regexpCursor(spec, state, from, to) { + return new RegExpCursor(state.doc, spec.search, { + ignoreCase: !spec.caseSensitive, + test: spec.wholeWord ? regexpWordTest(state.charCategorizer(state.selection.main.head)) : undefined + }, from, to); +} +function charBefore(str, index) { + return str.slice(findClusterBreak(str, index, false), index); +} +function charAfter(str, index) { + return str.slice(index, findClusterBreak(str, index)); +} +function regexpWordTest(categorizer) { + return (_from, _to, match) => !match[0].length || + (categorizer(charBefore(match.input, match.index)) != CharCategory.Word || + categorizer(charAfter(match.input, match.index)) != CharCategory.Word) && + (categorizer(charAfter(match.input, match.index + match[0].length)) != CharCategory.Word || + categorizer(charBefore(match.input, match.index + match[0].length)) != CharCategory.Word); } class RegExpQuery extends QueryType { - nextMatch(doc, curFrom, curTo) { - let cursor = regexpCursor(this.spec, doc, curTo, doc.length).next(); + nextMatch(state, curFrom, curTo) { + let cursor = regexpCursor(this.spec, state, curTo, state.doc.length).next(); if (cursor.done) - cursor = regexpCursor(this.spec, doc, 0, curFrom).next(); + cursor = regexpCursor(this.spec, state, 0, curFrom).next(); return cursor.done ? null : cursor.value; } - prevMatchInRange(doc, from, to) { + prevMatchInRange(state, from, to) { for (let size = 1;; size++) { - let start = Math.max(from, to - size * 10000 /* ChunkSize */); - let cursor = regexpCursor(this.spec, doc, start, to), range = null; + let start = Math.max(from, to - size * 10000 /* FindPrev.ChunkSize */); + let cursor = regexpCursor(this.spec, state, start, to), range = null; while (!cursor.next().done) range = cursor.value; if (range && (start == from || range.from > start + 10)) @@ -22770,18 +23471,18 @@ class RegExpQuery extends QueryType { return null; } } - prevMatch(doc, curFrom, curTo) { - return this.prevMatchInRange(doc, 0, curFrom) || - this.prevMatchInRange(doc, curTo, doc.length); + prevMatch(state, curFrom, curTo) { + return this.prevMatchInRange(state, 0, curFrom) || + this.prevMatchInRange(state, curTo, state.doc.length); } getReplacement(result) { - return this.spec.replace.replace(/\$([$&\d+])/g, (m, i) => i == "$" ? "$" + return this.spec.unquote(this.spec.replace.replace(/\$([$&\d+])/g, (m, i) => i == "$" ? "$" : i == "&" ? result.match[0] : i != "0" && +i < result.match.length ? result.match[i] - : m); + : m)); } - matchAll(doc, limit) { - let cursor = regexpCursor(this.spec, doc, 0, doc.length), ranges = []; + matchAll(state, limit) { + let cursor = regexpCursor(this.spec, state, 0, state.doc.length), ranges = []; while (!cursor.next().done) { if (ranges.length >= limit) return null; @@ -22789,8 +23490,8 @@ class RegExpQuery extends QueryType { } return ranges; } - highlight(doc, from, to, add) { - let cursor = regexpCursor(this.spec, doc, Math.max(0, from - 250 /* HighlightMargin */), Math.min(to + 250 /* HighlightMargin */, doc.length)); + highlight(state, from, to, add) { + let cursor = regexpCursor(this.spec, state, Math.max(0, from - 250 /* RegExp.HighlightMargin */), Math.min(to + 250 /* RegExp.HighlightMargin */, state.doc.length)); while (!cursor.next().done) add(cursor.value.from, cursor.value.to); } @@ -22843,9 +23544,9 @@ const searchHighlighter = /*@__PURE__*/ViewPlugin.fromClass(class { let builder = new RangeSetBuilder(); for (let i = 0, ranges = view.visibleRanges, l = ranges.length; i < l; i++) { let { from, to } = ranges[i]; - while (i < l - 1 && to > ranges[i + 1].from - 2 * 250 /* HighlightMargin */) + while (i < l - 1 && to > ranges[i + 1].from - 2 * 250 /* RegExp.HighlightMargin */) to = ranges[++i].to; - query.highlight(view.state.doc, from, to, (from, to) => { + query.highlight(view.state, from, to, (from, to) => { let selected = view.state.selection.ranges.some(r => r.from == from && r.to == to); builder.add(from, to, selected ? selectedMatchMark : matchMark); }); @@ -22868,9 +23569,9 @@ Will wrap around to the start of the document when it reaches the end. */ const findNext = /*@__PURE__*/searchCommand((view, { query }) => { - let { from, to } = view.state.selection.main; - let next = query.nextMatch(view.state.doc, from, to); - if (!next || next.from == from && next.to == to) + let { to } = view.state.selection.main; + let next = query.nextMatch(view.state, to, to); + if (!next) return false; view.dispatch({ selection: { anchor: next.from, head: next.to }, @@ -22886,8 +23587,8 @@ before the current main selection. Will wrap past the start of the document to start searching at the end again. */ const findPrevious = /*@__PURE__*/searchCommand((view, { query }) => { - let { state } = view, { from, to } = state.selection.main; - let range = query.prevMatch(state.doc, from, to); + let { state } = view, { from } = state.selection.main; + let range = query.prevMatch(state, from, from); if (!range) return false; view.dispatch({ @@ -22902,7 +23603,7 @@ const findPrevious = /*@__PURE__*/searchCommand((view, { query }) => { Select all instances of the search query. */ const selectMatches = /*@__PURE__*/searchCommand((view, { query }) => { - let ranges = query.matchAll(view.state.doc, 1000); + let ranges = query.matchAll(view.state, 1000); if (!ranges || !ranges.length) return false; view.dispatch({ @@ -22940,23 +23641,26 @@ const replaceNext = /*@__PURE__*/searchCommand((view, { query }) => { let { state } = view, { from, to } = state.selection.main; if (state.readOnly) return false; - let next = query.nextMatch(state.doc, from, from); + let next = query.nextMatch(state, from, from); if (!next) return false; let changes = [], selection, replacement; + let announce = []; if (next.from == from && next.to == to) { replacement = state.toText(query.getReplacement(next)); changes.push({ from: next.from, to: next.to, insert: replacement }); - next = query.nextMatch(state.doc, next.from, next.to); + next = query.nextMatch(state, next.from, next.to); + announce.push(EditorView.announce.of(state.phrase("replaced match on line $", state.doc.lineAt(from).number) + ".")); } if (next) { let off = changes.length == 0 || changes[0].from >= next.to ? 0 : next.to - next.from - replacement.length; selection = { anchor: next.from - off, head: next.to - off }; + announce.push(announceMatch(view, next)); } view.dispatch({ changes, selection, scrollIntoView: !!selection, - effects: next ? announceMatch(view, next) : undefined, + effects: announce, userEvent: "input.replace" }); return true; @@ -22968,14 +23672,16 @@ replacement. const replaceAll = /*@__PURE__*/searchCommand((view, { query }) => { if (view.state.readOnly) return false; - let changes = query.matchAll(view.state.doc, 1e9).map(match => { + let changes = query.matchAll(view.state, 1e9).map(match => { let { from, to } = match; return { from, to, insert: query.getReplacement(match) }; }); if (!changes.length) return false; + let announceText = view.state.phrase("replaced $ matches", changes.length) + "."; view.dispatch({ changes, + effects: EditorView.announce.of(announceText), userEvent: "input.replace.all" }); return true; @@ -22984,11 +23690,18 @@ function createSearchPanel(view) { return view.state.facet(searchConfigFacet).createPanel(view); } function defaultQuery(state, fallback) { - var _a; + var _a, _b, _c, _d; let sel = state.selection.main; let selText = sel.empty || sel.to > sel.from + 100 ? "" : state.sliceDoc(sel.from, sel.to); - let caseSensitive = (_a = fallback === null || fallback === void 0 ? void 0 : fallback.caseSensitive) !== null && _a !== void 0 ? _a : state.facet(searchConfigFacet).caseSensitive; - return fallback && !selText ? fallback : new SearchQuery({ search: selText.replace(/\n/g, "\\n"), caseSensitive }); + if (fallback && !selText) + return fallback; + let config = state.facet(searchConfigFacet); + return new SearchQuery({ + search: ((_a = fallback === null || fallback === void 0 ? void 0 : fallback.literal) !== null && _a !== void 0 ? _a : config.literal) ? selText : selText.replace(/\n/g, "\\n"), + caseSensitive: (_b = fallback === null || fallback === void 0 ? void 0 : fallback.caseSensitive) !== null && _b !== void 0 ? _b : config.caseSensitive, + literal: (_c = fallback === null || fallback === void 0 ? void 0 : fallback.literal) !== null && _c !== void 0 ? _c : config.literal, + wholeWord: (_d = fallback === null || fallback === void 0 ? void 0 : fallback.wholeWord) !== null && _d !== void 0 ? _d : config.wholeWord + }); } /** Make sure the search panel is open and focused. @@ -22999,8 +23712,8 @@ const openSearchPanel = view => { let panel = getPanel(view, createSearchPanel); if (!panel) return false; - let searchInput = panel.dom.querySelector("[name=search]"); - if (searchInput != view.root.activeElement) { + let searchInput = panel.dom.querySelector("[main-field]"); + if (searchInput && searchInput != view.root.activeElement) { let query = defaultQuery(view.state, state.query.spec); if (query.valid) view.dispatch({ effects: setSearchQuery.of(query) }); @@ -23058,6 +23771,8 @@ class SearchPanel { "aria-label": phrase(view, "Find"), class: "cm-textfield", name: "search", + form: "", + "main-field": "true", onchange: this.commit, onkeyup: this.commit }); @@ -23067,21 +23782,31 @@ class SearchPanel { "aria-label": phrase(view, "Replace"), class: "cm-textfield", name: "replace", + form: "", onchange: this.commit, onkeyup: this.commit }); this.caseField = crelt("input", { type: "checkbox", name: "case", + form: "", checked: query.caseSensitive, onchange: this.commit }); this.reField = crelt("input", { type: "checkbox", name: "re", + form: "", checked: query.regexp, onchange: this.commit }); + this.wordField = crelt("input", { + type: "checkbox", + name: "word", + form: "", + checked: query.wholeWord, + onchange: this.commit + }); function button(name, onclick, content) { return crelt("button", { class: "cm-button", name, onclick, type: "button" }, content); } @@ -23092,6 +23817,7 @@ class SearchPanel { button("select", () => selectMatches(view), [phrase(view, "all")]), crelt("label", null, [this.caseField, phrase(view, "match case")]), crelt("label", null, [this.reField, phrase(view, "regexp")]), + crelt("label", null, [this.wordField, phrase(view, "by word")]), ...view.state.readOnly ? [] : [ crelt("br"), this.replaceField, @@ -23111,7 +23837,8 @@ class SearchPanel { search: this.searchField.value, caseSensitive: this.caseField.checked, regexp: this.reField.checked, - replace: this.replaceField.value + wholeWord: this.wordField.checked, + replace: this.replaceField.value, }); if (!query.eq(this.query)) { this.query = query; @@ -23144,6 +23871,7 @@ class SearchPanel { this.replaceField.value = query.replace; this.caseField.checked = query.caseSensitive; this.reField.checked = query.regexp; + this.wordField.checked = query.wholeWord; } mount() { this.searchField.select(); @@ -23155,10 +23883,10 @@ function phrase(view, phrase) { return view.state.phrase(phrase); } const AnnounceMargin = 30; const Break = /[\s\.,:;?!]/; function announceMatch(view, { from, to }) { - let lineStart = view.state.doc.lineAt(from).from, lineEnd = view.state.doc.lineAt(to).to; - let start = Math.max(lineStart, from - AnnounceMargin), end = Math.min(lineEnd, to + AnnounceMargin); + let line = view.state.doc.lineAt(from), lineEnd = view.state.doc.lineAt(to).to; + let start = Math.max(line.from, from - AnnounceMargin), end = Math.min(lineEnd, to + AnnounceMargin); let text = view.state.sliceDoc(start, end); - if (start != lineStart) { + if (start != line.from) { for (let i = 0; i < AnnounceMargin; i++) if (!Break.test(text[i + 1]) && Break.test(text[i])) { text = text.slice(i); @@ -23172,7 +23900,7 @@ function announceMatch(view, { from, to }) { break; } } - return EditorView.announce.of(`${view.state.phrase("current match")}. ${text} ${view.state.phrase("on line")} ${view.state.doc.lineAt(from).number}`); + return EditorView.announce.of(`${view.state.phrase("current match")}. ${text} ${view.state.phrase("on line")} ${line.number}.`); } const baseTheme = /*@__PURE__*/EditorView.baseTheme({ ".cm-panel.cm-search": { @@ -23871,7 +24599,7 @@ class BlockContext { this.lineStart = this.absoluteLineStart = this.absoluteLineEnd = ranges[0].from; this.block = CompositeBlock.create(Type$1.Document, 0, this.lineStart, 0, 0); this.stack = [this.block]; - this.fragments = fragments.length ? new FragmentCursor$5(fragments, input) : null; + this.fragments = fragments.length ? new FragmentCursor(fragments, input) : null; this.readLine(); } get parsedPos() { @@ -23995,8 +24723,10 @@ class BlockContext { } } moveRangeI() { - while (this.rangeI < this.ranges.length - 1 && this.absoluteLineStart >= this.ranges[this.rangeI].to) + while (this.rangeI < this.ranges.length - 1 && this.absoluteLineStart >= this.ranges[this.rangeI].to) { this.rangeI++; + this.absoluteLineStart = Math.max(this.absoluteLineStart, this.ranges[this.rangeI].from); + } } /// @internal scanLine(start) { @@ -24006,7 +24736,7 @@ class BlockContext { r.text = ""; } else { - r.text = this.lineChunkAt(r.end); + r.text = this.lineChunkAt(start); r.end += r.text.length; if (this.ranges.length > 1) { let textOffset = this.absoluteLineStart, rangeI = this.rangeI; @@ -24216,7 +24946,7 @@ class MarkdownParser extends Parser { if (Array.isArray(style) || style instanceof Tag) styles[name] = style; else - Object.assign(style, styles); + Object.assign(styles, style); } } nodeSet = new NodeSet(nodeTypes); @@ -24364,7 +25094,7 @@ class Buffer { } } /// Elements are used to compose syntax nodes during parsing. -class Element$1 { +let Element$1 = class Element { /// @internal constructor( /// The node's @@ -24391,7 +25121,7 @@ class Element$1 { toTree(nodeSet) { return new Buffer(nodeSet).writeElements(this.children, -this.from).finish(this.type, this.to - this.from); } -} +}; class TreeElement { constructor(tree, from) { this.tree = tree; @@ -24693,8 +25423,10 @@ class InlineContext { addElement(elt) { return this.append(elt); } - /// @internal + /// Resolve markers between this.parts.length and from, wrapping matched markers in the + /// appropriate node and updating the content of this.parts. @internal resolveMarkers(from) { + // Scan forward, looking for closing tokens for (let i = from; i < this.parts.length; i++) { let close = this.parts[i]; if (!(close instanceof InlineDelimiter && close.type.resolve && (close.side & 2 /* Close */))) @@ -24702,25 +25434,30 @@ class InlineContext { let emp = close.type == EmphasisUnderscore || close.type == EmphasisAsterisk; let closeSize = close.to - close.from; let open, j = i - 1; + // Continue scanning for a matching opening token for (; j >= from; j--) { let part = this.parts[j]; - if (!(part instanceof InlineDelimiter && (part.side & 1 /* Open */) && part.type == close.type) || - emp && ((close.side & 1 /* Open */) || (part.side & 2 /* Close */)) && - (part.to - part.from + closeSize) % 3 == 0 && ((part.to - part.from) % 3 || closeSize % 3)) - continue; - open = part; - break; + if (part instanceof InlineDelimiter && (part.side & 1 /* Open */) && part.type == close.type && + // Ignore emphasis delimiters where the character count doesn't match + !(emp && ((close.side & 1 /* Open */) || (part.side & 2 /* Close */)) && + (part.to - part.from + closeSize) % 3 == 0 && ((part.to - part.from) % 3 || closeSize % 3))) { + open = part; + break; + } } if (!open) continue; let type = close.type.resolve, content = []; let start = open.from, end = close.to; + // Emphasis marker effect depends on the character count. Size consumed is minimum of the two + // markers. if (emp) { let size = Math.min(2, open.to - open.from, closeSize); start = open.to - size; end = close.from + size; type = size == 1 ? "Emphasis" : "StrongEmphasis"; } + // Move the covered region into content, optionally adding marker nodes if (open.type.mark) content.push(this.elt(open.type.mark, start, open.to)); for (let k = j + 1; k < i; k++) { @@ -24731,13 +25468,16 @@ class InlineContext { if (close.type.mark) content.push(this.elt(close.type.mark, close.from, end)); let element = this.elt(type, start, end, content); + // If there are leftover emphasis marker characters, shrink the close/open markers. Otherwise, clear them. this.parts[j] = emp && open.from != start ? new InlineDelimiter(open.type, open.from, start, open.side) : null; let keep = this.parts[i] = emp && close.to != end ? new InlineDelimiter(close.type, end, close.to, close.side) : null; + // Insert the new element in this.parts if (keep) this.parts.splice(i, 0, element); else this.parts[i] = element; } + // Collect the elements remaining in this.parts into an array. let result = []; for (let i = from; i < this.parts.length; i++) { let part = this.parts[i]; @@ -24800,7 +25540,7 @@ function injectMarks(elements, marks) { // These are blocks that can span blank lines, and should thus only be // reused if their next sibling is also being reused. const NotLast = [Type$1.CodeBlock, Type$1.ListItem, Type$1.OrderedList, Type$1.BulletList]; -class FragmentCursor$5 { +class FragmentCursor { constructor(fragments, input) { this.fragments = fragments; this.input = input; @@ -24968,9 +25708,12 @@ const Strikethrough = { parseInline: [{ name: "Strikethrough", parse(cx, next, pos) { - if (next != 126 /* '~' */ || cx.char(pos + 1) != 126) + if (next != 126 /* '~' */ || cx.char(pos + 1) != 126 || cx.char(pos + 2) == 126) return -1; - return cx.addDelimiter(StrikethroughDelim, pos, pos + 2, true, true); + let before = cx.slice(pos - 1, pos), after = cx.slice(pos + 2, pos + 3); + let sBefore = /\s|^$/.test(before), sAfter = /\s|^$/.test(after); + let pBefore = Punctuation$1.test(before), pAfter = Punctuation$1.test(after); + return cx.addDelimiter(StrikethroughDelim, pos, pos + 2, !sAfter && (!pAfter || sBefore || pBefore), !sBefore && (!pBefore || sAfter || pAfter)); }, after: "Emphasis" }] @@ -25168,10203 +25911,2585 @@ const Emoji = { }] }; -/// A parse stack. These are used internally by the parser to track -/// parsing progress. They also provide some properties and methods -/// that external code such as a tokenizer can use to get information -/// about the parse state. -class Stack$4 { - /// @internal - constructor( - /// The parse that this stack is part of @internal - p, - /// Holds state, input pos, buffer index triplets for all but the - /// top state @internal - stack, - /// The current parse state @internal - state, - // The position at which the next reduce should take place. This - // can be less than `this.pos` when skipped expressions have been - // added to the stack (which should be moved outside of the next - // reduction) - /// @internal - reducePos, - /// The input position up to which this stack has parsed. - pos, - /// The dynamic score of the stack, including dynamic precedence - /// and error-recovery penalties - /// @internal - score, - // The output buffer. Holds (type, start, end, size) quads - // representing nodes created by the parser, where `size` is - // amount of buffer array entries covered by this node. - /// @internal - buffer, - // The base offset of the buffer. When stacks are split, the split - // instance shared the buffer history with its parent up to - // `bufferBase`, which is the absolute offset (including the - // offset of previous splits) into the buffer at which this stack - // starts writing. - /// @internal - bufferBase, - /// @internal - curContext, - /// @internal - lookAhead = 0, - // A parent stack from which this was split off, if any. This is - // set up so that it always points to a stack that has some - // additional buffer content, never to a stack with an equal - // `bufferBase`. - /// @internal - parent) { - this.p = p; - this.stack = stack; - this.state = state; - this.reducePos = reducePos; - this.pos = pos; - this.score = score; - this.buffer = buffer; - this.bufferBase = bufferBase; - this.curContext = curContext; - this.lookAhead = lookAhead; - this.parent = parent; - } - /// @internal - toString() { - return `[${this.stack.filter((_, i) => i % 3 == 0).concat(this.state)}]@${this.pos}${this.score ? "!" + this.score : ""}`; - } - // Start an empty stack - /// @internal - static start(p, state, pos = 0) { - let cx = p.parser.context; - return new Stack$4(p, [], state, pos, pos, 0, [], 0, cx ? new StackContext$4(cx, cx.start) : null, 0, null); - } - /// The stack's current [context](#lr.ContextTracker) value, if - /// any. Its type will depend on the context tracker's type - /// parameter, or it will be `null` if there is no context - /// tracker. - get context() { return this.curContext ? this.curContext.context : null; } - // Push a state onto the stack, tracking its start position as well - // as the buffer base at that point. - /// @internal - pushState(state, start) { - this.stack.push(this.state, start, this.bufferBase + this.buffer.length); - this.state = state; - } - // Apply a reduce action - /// @internal - reduce(action) { - let depth = action >> 19 /* ReduceDepthShift */, type = action & 65535 /* ValueMask */; - let { parser } = this.p; - let dPrec = parser.dynamicPrecedence(type); - if (dPrec) - this.score += dPrec; - if (depth == 0) { - this.pushState(parser.getGoto(this.state, type, true), this.reducePos); - // Zero-depth reductions are a special case—they add stuff to - // the stack without popping anything off. - if (type < parser.minRepeatTerm) - this.storeNode(type, this.reducePos, this.reducePos, 4, true); - this.reduceContext(type, this.reducePos); - return; - } - // Find the base index into `this.stack`, content after which will - // be dropped. Note that with `StayFlag` reductions we need to - // consume two extra frames (the dummy parent node for the skipped - // expression and the state that we'll be staying in, which should - // be moved to `this.state`). - let base = this.stack.length - ((depth - 1) * 3) - (action & 262144 /* StayFlag */ ? 6 : 0); - let start = this.stack[base - 2]; - let bufferBase = this.stack[base - 1], count = this.bufferBase + this.buffer.length - bufferBase; - // Store normal terms or `R -> R R` repeat reductions - if (type < parser.minRepeatTerm || (action & 131072 /* RepeatFlag */)) { - let pos = parser.stateFlag(this.state, 1 /* Skipped */) ? this.pos : this.reducePos; - this.storeNode(type, start, pos, count + 4, true); - } - if (action & 262144 /* StayFlag */) { - this.state = this.stack[base]; - } - else { - let baseStateID = this.stack[base - 3]; - this.state = parser.getGoto(baseStateID, type, true); - } - while (this.stack.length > base) - this.stack.pop(); - this.reduceContext(type, start); - } - // Shift a value into the buffer - /// @internal - storeNode(term, start, end, size = 4, isReduce = false) { - if (term == 0 /* Err */ && - (!this.stack.length || this.stack[this.stack.length - 1] < this.buffer.length + this.bufferBase)) { - // Try to omit/merge adjacent error nodes - let cur = this, top = this.buffer.length; - if (top == 0 && cur.parent) { - top = cur.bufferBase - cur.parent.bufferBase; - cur = cur.parent; - } - if (top > 0 && cur.buffer[top - 4] == 0 /* Err */ && cur.buffer[top - 1] > -1) { - if (start == end) - return; - if (cur.buffer[top - 2] >= start) { - cur.buffer[top - 2] = end; - return; - } - } - } - if (!isReduce || this.pos == end) { // Simple case, just append - this.buffer.push(term, start, end, size); - } - else { // There may be skipped nodes that have to be moved forward - let index = this.buffer.length; - if (index > 0 && this.buffer[index - 4] != 0 /* Err */) - while (index > 0 && this.buffer[index - 2] > end) { - // Move this record forward - this.buffer[index] = this.buffer[index - 4]; - this.buffer[index + 1] = this.buffer[index - 3]; - this.buffer[index + 2] = this.buffer[index - 2]; - this.buffer[index + 3] = this.buffer[index - 1]; - index -= 4; - if (size > 4) - size -= 4; - } - this.buffer[index] = term; - this.buffer[index + 1] = start; - this.buffer[index + 2] = end; - this.buffer[index + 3] = size; - } - } - // Apply a shift action - /// @internal - shift(action, next, nextEnd) { - let start = this.pos; - if (action & 131072 /* GotoFlag */) { - this.pushState(action & 65535 /* ValueMask */, this.pos); - } - else if ((action & 262144 /* StayFlag */) == 0) { // Regular shift - let nextState = action, { parser } = this.p; - if (nextEnd > this.pos || next <= parser.maxNode) { - this.pos = nextEnd; - if (!parser.stateFlag(nextState, 1 /* Skipped */)) - this.reducePos = nextEnd; - } - this.pushState(nextState, start); - this.shiftContext(next, start); - if (next <= parser.maxNode) - this.buffer.push(next, start, nextEnd, 4); - } - else { // Shift-and-stay, which means this is a skipped token - this.pos = nextEnd; - this.shiftContext(next, start); - if (next <= this.p.parser.maxNode) - this.buffer.push(next, start, nextEnd, 4); - } - } - // Apply an action - /// @internal - apply(action, next, nextEnd) { - if (action & 65536 /* ReduceFlag */) - this.reduce(action); - else - this.shift(action, next, nextEnd); - } - // Add a prebuilt (reused) node into the buffer. - /// @internal - useNode(value, next) { - let index = this.p.reused.length - 1; - if (index < 0 || this.p.reused[index] != value) { - this.p.reused.push(value); - index++; - } - let start = this.pos; - this.reducePos = this.pos = start + value.length; - this.pushState(next, start); - this.buffer.push(index, start, this.reducePos, -1 /* size == -1 means this is a reused value */); - if (this.curContext) - this.updateContext(this.curContext.tracker.reuse(this.curContext.context, value, this, this.p.stream.reset(this.pos - value.length))); - } - // Split the stack. Due to the buffer sharing and the fact - // that `this.stack` tends to stay quite shallow, this isn't very - // expensive. - /// @internal - split() { - let parent = this; - let off = parent.buffer.length; - // Because the top of the buffer (after this.pos) may be mutated - // to reorder reductions and skipped tokens, and shared buffers - // should be immutable, this copies any outstanding skipped tokens - // to the new buffer, and puts the base pointer before them. - while (off > 0 && parent.buffer[off - 2] > parent.reducePos) - off -= 4; - let buffer = parent.buffer.slice(off), base = parent.bufferBase + off; - // Make sure parent points to an actual parent with content, if there is such a parent. - while (parent && base == parent.bufferBase) - parent = parent.parent; - return new Stack$4(this.p, this.stack.slice(), this.state, this.reducePos, this.pos, this.score, buffer, base, this.curContext, this.lookAhead, parent); - } - // Try to recover from an error by 'deleting' (ignoring) one token. - /// @internal - recoverByDelete(next, nextEnd) { - let isNode = next <= this.p.parser.maxNode; - if (isNode) - this.storeNode(next, this.pos, nextEnd, 4); - this.storeNode(0 /* Err */, this.pos, nextEnd, isNode ? 8 : 4); - this.pos = this.reducePos = nextEnd; - this.score -= 190 /* Delete */; - } - /// Check if the given term would be able to be shifted (optionally - /// after some reductions) on this stack. This can be useful for - /// external tokenizers that want to make sure they only provide a - /// given token when it applies. - canShift(term) { - for (let sim = new SimulatedStack$4(this);;) { - let action = this.p.parser.stateSlot(sim.state, 4 /* DefaultReduce */) || this.p.parser.hasAction(sim.state, term); - if ((action & 65536 /* ReduceFlag */) == 0) - return true; - if (action == 0) - return false; - sim.reduce(action); - } - } - // Apply up to Recover.MaxNext recovery actions that conceptually - // inserts some missing token or rule. - /// @internal - recoverByInsert(next) { - if (this.stack.length >= 300 /* MaxInsertStackDepth */) - return []; - let nextStates = this.p.parser.nextStates(this.state); - if (nextStates.length > 4 /* MaxNext */ << 1 || this.stack.length >= 120 /* DampenInsertStackDepth */) { - let best = []; - for (let i = 0, s; i < nextStates.length; i += 2) { - if ((s = nextStates[i + 1]) != this.state && this.p.parser.hasAction(s, next)) - best.push(nextStates[i], s); - } - if (this.stack.length < 120 /* DampenInsertStackDepth */) - for (let i = 0; best.length < 4 /* MaxNext */ << 1 && i < nextStates.length; i += 2) { - let s = nextStates[i + 1]; - if (!best.some((v, i) => (i & 1) && v == s)) - best.push(nextStates[i], s); - } - nextStates = best; - } - let result = []; - for (let i = 0; i < nextStates.length && result.length < 4 /* MaxNext */; i += 2) { - let s = nextStates[i + 1]; - if (s == this.state) - continue; - let stack = this.split(); - stack.pushState(s, this.pos); - stack.storeNode(0 /* Err */, stack.pos, stack.pos, 4, true); - stack.shiftContext(nextStates[i], this.pos); - stack.score -= 200 /* Insert */; - result.push(stack); - } - return result; - } - // Force a reduce, if possible. Return false if that can't - // be done. - /// @internal - forceReduce() { - let reduce = this.p.parser.stateSlot(this.state, 5 /* ForcedReduce */); - if ((reduce & 65536 /* ReduceFlag */) == 0) - return false; - let { parser } = this.p; - if (!parser.validAction(this.state, reduce)) { - let depth = reduce >> 19 /* ReduceDepthShift */, term = reduce & 65535 /* ValueMask */; - let target = this.stack.length - depth * 3; - if (target < 0 || parser.getGoto(this.stack[target], term, false) < 0) - return false; - this.storeNode(0 /* Err */, this.reducePos, this.reducePos, 4, true); - this.score -= 100 /* Reduce */; - } - this.reducePos = this.pos; - this.reduce(reduce); - return true; - } - /// @internal - forceAll() { - while (!this.p.parser.stateFlag(this.state, 2 /* Accepting */)) { - if (!this.forceReduce()) { - this.storeNode(0 /* Err */, this.pos, this.pos, 4, true); - break; - } - } - return this; - } - /// Check whether this state has no further actions (assumed to be a direct descendant of the - /// top state, since any other states must be able to continue - /// somehow). @internal - get deadEnd() { - if (this.stack.length != 3) - return false; - let { parser } = this.p; - return parser.data[parser.stateSlot(this.state, 1 /* Actions */)] == 65535 /* End */ && - !parser.stateSlot(this.state, 4 /* DefaultReduce */); - } - /// Restart the stack (put it back in its start state). Only safe - /// when this.stack.length == 3 (state is directly below the top - /// state). @internal - restart() { - this.state = this.stack[0]; - this.stack.length = 0; - } - /// @internal - sameState(other) { - if (this.state != other.state || this.stack.length != other.stack.length) - return false; - for (let i = 0; i < this.stack.length; i += 3) - if (this.stack[i] != other.stack[i]) - return false; - return true; - } - /// Get the parser used by this stack. - get parser() { return this.p.parser; } - /// Test whether a given dialect (by numeric ID, as exported from - /// the terms file) is enabled. - dialectEnabled(dialectID) { return this.p.parser.dialect.flags[dialectID]; } - shiftContext(term, start) { - if (this.curContext) - this.updateContext(this.curContext.tracker.shift(this.curContext.context, term, this, this.p.stream.reset(start))); - } - reduceContext(term, start) { - if (this.curContext) - this.updateContext(this.curContext.tracker.reduce(this.curContext.context, term, this, this.p.stream.reset(start))); - } - /// @internal - emitContext() { - let last = this.buffer.length - 1; - if (last < 0 || this.buffer[last] != -3) - this.buffer.push(this.curContext.hash, this.reducePos, this.reducePos, -3); - } - /// @internal - emitLookAhead() { - let last = this.buffer.length - 1; - if (last < 0 || this.buffer[last] != -4) - this.buffer.push(this.lookAhead, this.reducePos, this.reducePos, -4); - } - updateContext(context) { - if (context != this.curContext.context) { - let newCx = new StackContext$4(this.curContext.tracker, context); - if (newCx.hash != this.curContext.hash) - this.emitContext(); - this.curContext = newCx; - } - } - /// @internal - setLookAhead(lookAhead) { - if (lookAhead > this.lookAhead) { - this.emitLookAhead(); - this.lookAhead = lookAhead; - } - } - /// @internal - close() { - if (this.curContext && this.curContext.tracker.strict) - this.emitContext(); - if (this.lookAhead > 0) - this.emitLookAhead(); - } -} -class StackContext$4 { - constructor(tracker, context) { - this.tracker = tracker; - this.context = context; - this.hash = tracker.strict ? tracker.hash(context) : 0; - } -} -var Recover$4; -(function (Recover) { - Recover[Recover["Insert"] = 200] = "Insert"; - Recover[Recover["Delete"] = 190] = "Delete"; - Recover[Recover["Reduce"] = 100] = "Reduce"; - Recover[Recover["MaxNext"] = 4] = "MaxNext"; - Recover[Recover["MaxInsertStackDepth"] = 300] = "MaxInsertStackDepth"; - Recover[Recover["DampenInsertStackDepth"] = 120] = "DampenInsertStackDepth"; -})(Recover$4 || (Recover$4 = {})); -// Used to cheaply run some reductions to scan ahead without mutating -// an entire stack -class SimulatedStack$4 { - constructor(start) { - this.start = start; - this.state = start.state; - this.stack = start.stack; - this.base = this.stack.length; - } - reduce(action) { - let term = action & 65535 /* ValueMask */, depth = action >> 19 /* ReduceDepthShift */; - if (depth == 0) { - if (this.stack == this.start.stack) - this.stack = this.stack.slice(); - this.stack.push(this.state, 0, 0); - this.base += 3; - } - else { - this.base -= (depth - 1) * 3; - } - let goto = this.start.p.parser.getGoto(this.stack[this.base - 3], term, true); - this.state = goto; - } -} -// This is given to `Tree.build` to build a buffer, and encapsulates -// the parent-stack-walking necessary to read the nodes. -class StackBufferCursor$4 { - constructor(stack, pos, index) { - this.stack = stack; - this.pos = pos; - this.index = index; - this.buffer = stack.buffer; - if (this.index == 0) - this.maybeNext(); - } - static create(stack, pos = stack.bufferBase + stack.buffer.length) { - return new StackBufferCursor$4(stack, pos, pos - stack.bufferBase); - } - maybeNext() { - let next = this.stack.parent; - if (next != null) { - this.index = this.stack.bufferBase - next.bufferBase; - this.stack = next; - this.buffer = next.buffer; - } - } - get id() { return this.buffer[this.index - 4]; } - get start() { return this.buffer[this.index - 3]; } - get end() { return this.buffer[this.index - 2]; } - get size() { return this.buffer[this.index - 1]; } - next() { - this.index -= 4; - this.pos -= 4; - if (this.index == 0) - this.maybeNext(); - } - fork() { - return new StackBufferCursor$4(this.stack, this.pos, this.index); - } -} - -class CachedToken$4 { - constructor() { - this.start = -1; - this.value = -1; - this.end = -1; - this.extended = -1; - this.lookAhead = 0; - this.mask = 0; - this.context = 0; - } -} -const nullToken$4 = new CachedToken$4; -/// [Tokenizers](#lr.ExternalTokenizer) interact with the input -/// through this interface. It presents the input as a stream of -/// characters, tracking lookahead and hiding the complexity of -/// [ranges](#common.Parser.parse^ranges) from tokenizer code. -class InputStream$4 { - /// @internal - constructor( - /// @internal - input, - /// @internal - ranges) { - this.input = input; - this.ranges = ranges; - /// @internal - this.chunk = ""; - /// @internal - this.chunkOff = 0; - /// Backup chunk - this.chunk2 = ""; - this.chunk2Pos = 0; - /// The character code of the next code unit in the input, or -1 - /// when the stream is at the end of the input. - this.next = -1; - /// @internal - this.token = nullToken$4; - this.rangeIndex = 0; - this.pos = this.chunkPos = ranges[0].from; - this.range = ranges[0]; - this.end = ranges[ranges.length - 1].to; - this.readNext(); - } - resolveOffset(offset, assoc) { - let range = this.range, index = this.rangeIndex; - let pos = this.pos + offset; - while (pos < range.from) { - if (!index) - return null; - let next = this.ranges[--index]; - pos -= range.from - next.to; - range = next; - } - while (assoc < 0 ? pos > range.to : pos >= range.to) { - if (index == this.ranges.length - 1) - return null; - let next = this.ranges[++index]; - pos += next.from - range.to; - range = next; - } - return pos; - } - /// Look at a code unit near the stream position. `.peek(0)` equals - /// `.next`, `.peek(-1)` gives you the previous character, and so - /// on. - /// - /// Note that looking around during tokenizing creates dependencies - /// on potentially far-away content, which may reduce the - /// effectiveness incremental parsing—when looking forward—or even - /// cause invalid reparses when looking backward more than 25 code - /// units, since the library does not track lookbehind. - peek(offset) { - let idx = this.chunkOff + offset, pos, result; - if (idx >= 0 && idx < this.chunk.length) { - pos = this.pos + offset; - result = this.chunk.charCodeAt(idx); - } - else { - let resolved = this.resolveOffset(offset, 1); - if (resolved == null) - return -1; - pos = resolved; - if (pos >= this.chunk2Pos && pos < this.chunk2Pos + this.chunk2.length) { - result = this.chunk2.charCodeAt(pos - this.chunk2Pos); - } - else { - let i = this.rangeIndex, range = this.range; - while (range.to <= pos) - range = this.ranges[++i]; - this.chunk2 = this.input.chunk(this.chunk2Pos = pos); - if (pos + this.chunk2.length > range.to) - this.chunk2 = this.chunk2.slice(0, range.to - pos); - result = this.chunk2.charCodeAt(0); - } - } - if (pos >= this.token.lookAhead) - this.token.lookAhead = pos + 1; - return result; - } - /// Accept a token. By default, the end of the token is set to the - /// current stream position, but you can pass an offset (relative to - /// the stream position) to change that. - acceptToken(token, endOffset = 0) { - let end = endOffset ? this.resolveOffset(endOffset, -1) : this.pos; - if (end == null || end < this.token.start) - throw new RangeError("Token end out of bounds"); - this.token.value = token; - this.token.end = end; - } - getChunk() { - if (this.pos >= this.chunk2Pos && this.pos < this.chunk2Pos + this.chunk2.length) { - let { chunk, chunkPos } = this; - this.chunk = this.chunk2; - this.chunkPos = this.chunk2Pos; - this.chunk2 = chunk; - this.chunk2Pos = chunkPos; - this.chunkOff = this.pos - this.chunkPos; - } - else { - this.chunk2 = this.chunk; - this.chunk2Pos = this.chunkPos; - let nextChunk = this.input.chunk(this.pos); - let end = this.pos + nextChunk.length; - this.chunk = end > this.range.to ? nextChunk.slice(0, this.range.to - this.pos) : nextChunk; - this.chunkPos = this.pos; - this.chunkOff = 0; - } - } - readNext() { - if (this.chunkOff >= this.chunk.length) { - this.getChunk(); - if (this.chunkOff == this.chunk.length) - return this.next = -1; - } - return this.next = this.chunk.charCodeAt(this.chunkOff); - } - /// Move the stream forward N (defaults to 1) code units. Returns - /// the new value of [`next`](#lr.InputStream.next). - advance(n = 1) { - this.chunkOff += n; - while (this.pos + n >= this.range.to) { - if (this.rangeIndex == this.ranges.length - 1) - return this.setDone(); - n -= this.range.to - this.pos; - this.range = this.ranges[++this.rangeIndex]; - this.pos = this.range.from; - } - this.pos += n; - if (this.pos >= this.token.lookAhead) - this.token.lookAhead = this.pos + 1; - return this.readNext(); - } - setDone() { - this.pos = this.chunkPos = this.end; - this.range = this.ranges[this.rangeIndex = this.ranges.length - 1]; - this.chunk = ""; - return this.next = -1; - } - /// @internal - reset(pos, token) { - if (token) { - this.token = token; - token.start = pos; - token.lookAhead = pos + 1; - token.value = token.extended = -1; - } - else { - this.token = nullToken$4; - } - if (this.pos != pos) { - this.pos = pos; - if (pos == this.end) { - this.setDone(); - return this; - } - while (pos < this.range.from) - this.range = this.ranges[--this.rangeIndex]; - while (pos >= this.range.to) - this.range = this.ranges[++this.rangeIndex]; - if (pos >= this.chunkPos && pos < this.chunkPos + this.chunk.length) { - this.chunkOff = pos - this.chunkPos; - } - else { - this.chunk = ""; - this.chunkOff = 0; - } - this.readNext(); - } - return this; - } - /// @internal - read(from, to) { - if (from >= this.chunkPos && to <= this.chunkPos + this.chunk.length) - return this.chunk.slice(from - this.chunkPos, to - this.chunkPos); - if (from >= this.chunk2Pos && to <= this.chunk2Pos + this.chunk2.length) - return this.chunk2.slice(from - this.chunk2Pos, to - this.chunk2Pos); - if (from >= this.range.from && to <= this.range.to) - return this.input.read(from, to); - let result = ""; - for (let r of this.ranges) { - if (r.from >= to) - break; - if (r.to > from) - result += this.input.read(Math.max(r.from, from), Math.min(r.to, to)); - } - return result; - } -} -/// @internal -class TokenGroup$4 { - constructor(data, id) { - this.data = data; - this.id = id; - } - token(input, stack) { readToken$4(this.data, input, stack, this.id); } -} -TokenGroup$4.prototype.contextual = TokenGroup$4.prototype.fallback = TokenGroup$4.prototype.extend = false; -/// `@external tokens` declarations in the grammar should resolve to -/// an instance of this class. -class ExternalTokenizer$4 { - /// Create a tokenizer. The first argument is the function that, - /// given an input stream, scans for the types of tokens it - /// recognizes at the stream's position, and calls - /// [`acceptToken`](#lr.InputStream.acceptToken) when it finds - /// one. - constructor( - /// @internal - token, options = {}) { - this.token = token; - this.contextual = !!options.contextual; - this.fallback = !!options.fallback; - this.extend = !!options.extend; - } -} -// Tokenizer data is stored a big uint16 array containing, for each -// state: -// -// - A group bitmask, indicating what token groups are reachable from -// this state, so that paths that can only lead to tokens not in -// any of the current groups can be cut off early. -// -// - The position of the end of the state's sequence of accepting -// tokens -// -// - The number of outgoing edges for the state -// -// - The accepting tokens, as (token id, group mask) pairs -// -// - The outgoing edges, as (start character, end character, state -// index) triples, with end character being exclusive -// -// This function interprets that data, running through a stream as -// long as new states with the a matching group mask can be reached, -// and updating `token` when it matches a token. -function readToken$4(data, input, stack, group) { - let state = 0, groupMask = 1 << group, { parser } = stack.p, { dialect } = parser; - scan: for (;;) { - if ((groupMask & data[state]) == 0) - break; - let accEnd = data[state + 1]; - // Check whether this state can lead to a token in the current group - // Accept tokens in this state, possibly overwriting - // lower-precedence / shorter tokens - for (let i = state + 3; i < accEnd; i += 2) - if ((data[i + 1] & groupMask) > 0) { - let term = data[i]; - if (dialect.allows(term) && - (input.token.value == -1 || input.token.value == term || parser.overrides(term, input.token.value))) { - input.acceptToken(term); - break; - } - } - // Do a binary search on the state's edges - for (let next = input.next, low = 0, high = data[state + 2]; low < high;) { - let mid = (low + high) >> 1; - let index = accEnd + mid + (mid << 1); - let from = data[index], to = data[index + 1]; - if (next < from) - high = mid; - else if (next >= to) - low = mid + 1; - else { - state = data[index + 2]; - input.advance(); - continue scan; - } - } - break; - } -} - -// See lezer-generator/src/encode.ts for comments about the encoding -// used here -function decodeArray$4(input, Type = Uint16Array) { - if (typeof input != "string") - return input; - let array = null; - for (let pos = 0, out = 0; pos < input.length;) { - let value = 0; - for (;;) { - let next = input.charCodeAt(pos++), stop = false; - if (next == 126 /* BigValCode */) { - value = 65535 /* BigVal */; - break; - } - if (next >= 92 /* Gap2 */) - next--; - if (next >= 34 /* Gap1 */) - next--; - let digit = next - 32 /* Start */; - if (digit >= 46 /* Base */) { - digit -= 46 /* Base */; - stop = true; - } - value += digit; - if (stop) - break; - value *= 46 /* Base */; - } - if (array) - array[out++] = value; - else - array = new Type(value); - } - return array; -} - -// Environment variable used to control console output -const verbose$4 = typeof process != "undefined" && process.env && /\bparse\b/.test(process.env.LOG); -let stackIDs$4 = null; -var Safety$4; -(function (Safety) { - Safety[Safety["Margin"] = 25] = "Margin"; -})(Safety$4 || (Safety$4 = {})); -function cutAt$4(tree, pos, side) { - let cursor = tree.cursor(IterMode.IncludeAnonymous); - cursor.moveTo(pos); - for (;;) { - if (!(side < 0 ? cursor.childBefore(pos) : cursor.childAfter(pos))) - for (;;) { - if ((side < 0 ? cursor.to < pos : cursor.from > pos) && !cursor.type.isError) - return side < 0 ? Math.max(0, Math.min(cursor.to - 1, pos - 25 /* Margin */)) - : Math.min(tree.length, Math.max(cursor.from + 1, pos + 25 /* Margin */)); - if (side < 0 ? cursor.prevSibling() : cursor.nextSibling()) - break; - if (!cursor.parent()) - return side < 0 ? 0 : tree.length; - } - } -} -class FragmentCursor$4 { - constructor(fragments, nodeSet) { - this.fragments = fragments; - this.nodeSet = nodeSet; - this.i = 0; - this.fragment = null; - this.safeFrom = -1; - this.safeTo = -1; - this.trees = []; - this.start = []; - this.index = []; - this.nextFragment(); - } - nextFragment() { - let fr = this.fragment = this.i == this.fragments.length ? null : this.fragments[this.i++]; - if (fr) { - this.safeFrom = fr.openStart ? cutAt$4(fr.tree, fr.from + fr.offset, 1) - fr.offset : fr.from; - this.safeTo = fr.openEnd ? cutAt$4(fr.tree, fr.to + fr.offset, -1) - fr.offset : fr.to; - while (this.trees.length) { - this.trees.pop(); - this.start.pop(); - this.index.pop(); - } - this.trees.push(fr.tree); - this.start.push(-fr.offset); - this.index.push(0); - this.nextStart = this.safeFrom; - } - else { - this.nextStart = 1e9; - } - } - // `pos` must be >= any previously given `pos` for this cursor - nodeAt(pos) { - if (pos < this.nextStart) - return null; - while (this.fragment && this.safeTo <= pos) - this.nextFragment(); - if (!this.fragment) - return null; - for (;;) { - let last = this.trees.length - 1; - if (last < 0) { // End of tree - this.nextFragment(); - return null; - } - let top = this.trees[last], index = this.index[last]; - if (index == top.children.length) { - this.trees.pop(); - this.start.pop(); - this.index.pop(); - continue; - } - let next = top.children[index]; - let start = this.start[last] + top.positions[index]; - if (start > pos) { - this.nextStart = start; - return null; - } - if (next instanceof Tree) { - if (start == pos) { - if (start < this.safeFrom) - return null; - let end = start + next.length; - if (end <= this.safeTo) { - let lookAhead = next.prop(NodeProp.lookAhead); - if (!lookAhead || end + lookAhead < this.fragment.to) - return next; - } - } - this.index[last]++; - if (start + next.length >= Math.max(this.safeFrom, pos)) { // Enter this node - this.trees.push(next); - this.start.push(start); - this.index.push(0); - } - } - else { - this.index[last]++; - this.nextStart = start + next.length; - } - } - } -} -class TokenCache$4 { - constructor(parser, stream) { - this.stream = stream; - this.tokens = []; - this.mainToken = null; - this.actions = []; - this.tokens = parser.tokenizers.map(_ => new CachedToken$4); - } - getActions(stack) { - let actionIndex = 0; - let main = null; - let { parser } = stack.p, { tokenizers } = parser; - let mask = parser.stateSlot(stack.state, 3 /* TokenizerMask */); - let context = stack.curContext ? stack.curContext.hash : 0; - let lookAhead = 0; - for (let i = 0; i < tokenizers.length; i++) { - if (((1 << i) & mask) == 0) - continue; - let tokenizer = tokenizers[i], token = this.tokens[i]; - if (main && !tokenizer.fallback) - continue; - if (tokenizer.contextual || token.start != stack.pos || token.mask != mask || token.context != context) { - this.updateCachedToken(token, tokenizer, stack); - token.mask = mask; - token.context = context; - } - if (token.lookAhead > token.end + 25 /* Margin */) - lookAhead = Math.max(token.lookAhead, lookAhead); - if (token.value != 0 /* Err */) { - let startIndex = actionIndex; - if (token.extended > -1) - actionIndex = this.addActions(stack, token.extended, token.end, actionIndex); - actionIndex = this.addActions(stack, token.value, token.end, actionIndex); - if (!tokenizer.extend) { - main = token; - if (actionIndex > startIndex) - break; - } - } - } - while (this.actions.length > actionIndex) - this.actions.pop(); - if (lookAhead) - stack.setLookAhead(lookAhead); - if (!main && stack.pos == this.stream.end) { - main = new CachedToken$4; - main.value = stack.p.parser.eofTerm; - main.start = main.end = stack.pos; - actionIndex = this.addActions(stack, main.value, main.end, actionIndex); - } - this.mainToken = main; - return this.actions; - } - getMainToken(stack) { - if (this.mainToken) - return this.mainToken; - let main = new CachedToken$4, { pos, p } = stack; - main.start = pos; - main.end = Math.min(pos + 1, p.stream.end); - main.value = pos == p.stream.end ? p.parser.eofTerm : 0 /* Err */; - return main; - } - updateCachedToken(token, tokenizer, stack) { - tokenizer.token(this.stream.reset(stack.pos, token), stack); - if (token.value > -1) { - let { parser } = stack.p; - for (let i = 0; i < parser.specialized.length; i++) - if (parser.specialized[i] == token.value) { - let result = parser.specializers[i](this.stream.read(token.start, token.end), stack); - if (result >= 0 && stack.p.parser.dialect.allows(result >> 1)) { - if ((result & 1) == 0 /* Specialize */) - token.value = result >> 1; - else - token.extended = result >> 1; - break; - } - } - } - else { - token.value = 0 /* Err */; - token.end = Math.min(stack.p.stream.end, stack.pos + 1); - } - } - putAction(action, token, end, index) { - // Don't add duplicate actions - for (let i = 0; i < index; i += 3) - if (this.actions[i] == action) - return index; - this.actions[index++] = action; - this.actions[index++] = token; - this.actions[index++] = end; - return index; - } - addActions(stack, token, end, index) { - let { state } = stack, { parser } = stack.p, { data } = parser; - for (let set = 0; set < 2; set++) { - for (let i = parser.stateSlot(state, set ? 2 /* Skip */ : 1 /* Actions */);; i += 3) { - if (data[i] == 65535 /* End */) { - if (data[i + 1] == 1 /* Next */) { - i = pair$4(data, i + 2); - } - else { - if (index == 0 && data[i + 1] == 2 /* Other */) - index = this.putAction(pair$4(data, i + 2), token, end, index); - break; - } - } - if (data[i] == token) - index = this.putAction(pair$4(data, i + 1), token, end, index); - } - } - return index; - } -} -var Rec$4; -(function (Rec) { - Rec[Rec["Distance"] = 5] = "Distance"; - Rec[Rec["MaxRemainingPerStep"] = 3] = "MaxRemainingPerStep"; - // When two stacks have been running independently long enough to - // add this many elements to their buffers, prune one. - Rec[Rec["MinBufferLengthPrune"] = 500] = "MinBufferLengthPrune"; - Rec[Rec["ForceReduceLimit"] = 10] = "ForceReduceLimit"; - // Once a stack reaches this depth (in .stack.length) force-reduce - // it back to CutTo to avoid creating trees that overflow the stack - // on recursive traversal. - Rec[Rec["CutDepth"] = 15000] = "CutDepth"; - Rec[Rec["CutTo"] = 9000] = "CutTo"; -})(Rec$4 || (Rec$4 = {})); -class Parse$4 { - constructor(parser, input, fragments, ranges) { - this.parser = parser; - this.input = input; - this.ranges = ranges; - this.recovering = 0; - this.nextStackID = 0x2654; // ♔, ♕, ♖, ♗, ♘, ♙, ♠, ♡, ♢, ♣, ♤, ♥, ♦, ♧ - this.minStackPos = 0; - this.reused = []; - this.stoppedAt = null; - this.stream = new InputStream$4(input, ranges); - this.tokens = new TokenCache$4(parser, this.stream); - this.topTerm = parser.top[1]; - let { from } = ranges[0]; - this.stacks = [Stack$4.start(this, parser.top[0], from)]; - this.fragments = fragments.length && this.stream.end - from > parser.bufferLength * 4 - ? new FragmentCursor$4(fragments, parser.nodeSet) : null; - } - get parsedPos() { - return this.minStackPos; - } - // Move the parser forward. This will process all parse stacks at - // `this.pos` and try to advance them to a further position. If no - // stack for such a position is found, it'll start error-recovery. - // - // When the parse is finished, this will return a syntax tree. When - // not, it returns `null`. - advance() { - let stacks = this.stacks, pos = this.minStackPos; - // This will hold stacks beyond `pos`. - let newStacks = this.stacks = []; - let stopped, stoppedTokens; - // Keep advancing any stacks at `pos` until they either move - // forward or can't be advanced. Gather stacks that can't be - // advanced further in `stopped`. - for (let i = 0; i < stacks.length; i++) { - let stack = stacks[i]; - for (;;) { - this.tokens.mainToken = null; - if (stack.pos > pos) { - newStacks.push(stack); - } - else if (this.advanceStack(stack, newStacks, stacks)) { - continue; - } - else { - if (!stopped) { - stopped = []; - stoppedTokens = []; - } - stopped.push(stack); - let tok = this.tokens.getMainToken(stack); - stoppedTokens.push(tok.value, tok.end); - } - break; - } - } - if (!newStacks.length) { - let finished = stopped && findFinished$4(stopped); - if (finished) - return this.stackToTree(finished); - if (this.parser.strict) { - if (verbose$4 && stopped) - console.log("Stuck with token " + (this.tokens.mainToken ? this.parser.getName(this.tokens.mainToken.value) : "none")); - throw new SyntaxError("No parse at " + pos); - } - if (!this.recovering) - this.recovering = 5 /* Distance */; - } - if (this.recovering && stopped) { - let finished = this.stoppedAt != null && stopped[0].pos > this.stoppedAt ? stopped[0] - : this.runRecovery(stopped, stoppedTokens, newStacks); - if (finished) - return this.stackToTree(finished.forceAll()); - } - if (this.recovering) { - let maxRemaining = this.recovering == 1 ? 1 : this.recovering * 3 /* MaxRemainingPerStep */; - if (newStacks.length > maxRemaining) { - newStacks.sort((a, b) => b.score - a.score); - while (newStacks.length > maxRemaining) - newStacks.pop(); - } - if (newStacks.some(s => s.reducePos > pos)) - this.recovering--; - } - else if (newStacks.length > 1) { - // Prune stacks that are in the same state, or that have been - // running without splitting for a while, to avoid getting stuck - // with multiple successful stacks running endlessly on. - outer: for (let i = 0; i < newStacks.length - 1; i++) { - let stack = newStacks[i]; - for (let j = i + 1; j < newStacks.length; j++) { - let other = newStacks[j]; - if (stack.sameState(other) || - stack.buffer.length > 500 /* MinBufferLengthPrune */ && other.buffer.length > 500 /* MinBufferLengthPrune */) { - if (((stack.score - other.score) || (stack.buffer.length - other.buffer.length)) > 0) { - newStacks.splice(j--, 1); - } - else { - newStacks.splice(i--, 1); - continue outer; - } - } - } - } - } - this.minStackPos = newStacks[0].pos; - for (let i = 1; i < newStacks.length; i++) - if (newStacks[i].pos < this.minStackPos) - this.minStackPos = newStacks[i].pos; - return null; - } - stopAt(pos) { - if (this.stoppedAt != null && this.stoppedAt < pos) - throw new RangeError("Can't move stoppedAt forward"); - this.stoppedAt = pos; - } - // Returns an updated version of the given stack, or null if the - // stack can't advance normally. When `split` and `stacks` are - // given, stacks split off by ambiguous operations will be pushed to - // `split`, or added to `stacks` if they move `pos` forward. - advanceStack(stack, stacks, split) { - let start = stack.pos, { parser } = this; - let base = verbose$4 ? this.stackID(stack) + " -> " : ""; - if (this.stoppedAt != null && start > this.stoppedAt) - return stack.forceReduce() ? stack : null; - if (this.fragments) { - let strictCx = stack.curContext && stack.curContext.tracker.strict, cxHash = strictCx ? stack.curContext.hash : 0; - for (let cached = this.fragments.nodeAt(start); cached;) { - let match = this.parser.nodeSet.types[cached.type.id] == cached.type ? parser.getGoto(stack.state, cached.type.id) : -1; - if (match > -1 && cached.length && (!strictCx || (cached.prop(NodeProp.contextHash) || 0) == cxHash)) { - stack.useNode(cached, match); - if (verbose$4) - console.log(base + this.stackID(stack) + ` (via reuse of ${parser.getName(cached.type.id)})`); - return true; - } - if (!(cached instanceof Tree) || cached.children.length == 0 || cached.positions[0] > 0) - break; - let inner = cached.children[0]; - if (inner instanceof Tree && cached.positions[0] == 0) - cached = inner; - else - break; - } - } - let defaultReduce = parser.stateSlot(stack.state, 4 /* DefaultReduce */); - if (defaultReduce > 0) { - stack.reduce(defaultReduce); - if (verbose$4) - console.log(base + this.stackID(stack) + ` (via always-reduce ${parser.getName(defaultReduce & 65535 /* ValueMask */)})`); - return true; - } - if (stack.stack.length >= 15000 /* CutDepth */) { - while (stack.stack.length > 9000 /* CutTo */ && stack.forceReduce()) { } - } - let actions = this.tokens.getActions(stack); - for (let i = 0; i < actions.length;) { - let action = actions[i++], term = actions[i++], end = actions[i++]; - let last = i == actions.length || !split; - let localStack = last ? stack : stack.split(); - localStack.apply(action, term, end); - if (verbose$4) - console.log(base + this.stackID(localStack) + ` (via ${(action & 65536 /* ReduceFlag */) == 0 ? "shift" - : `reduce of ${parser.getName(action & 65535 /* ValueMask */)}`} for ${parser.getName(term)} @ ${start}${localStack == stack ? "" : ", split"})`); - if (last) - return true; - else if (localStack.pos > start) - stacks.push(localStack); - else - split.push(localStack); - } - return false; - } - // Advance a given stack forward as far as it will go. Returns the - // (possibly updated) stack if it got stuck, or null if it moved - // forward and was given to `pushStackDedup`. - advanceFully(stack, newStacks) { - let pos = stack.pos; - for (;;) { - if (!this.advanceStack(stack, null, null)) - return false; - if (stack.pos > pos) { - pushStackDedup$4(stack, newStacks); - return true; - } - } - } - runRecovery(stacks, tokens, newStacks) { - let finished = null, restarted = false; - for (let i = 0; i < stacks.length; i++) { - let stack = stacks[i], token = tokens[i << 1], tokenEnd = tokens[(i << 1) + 1]; - let base = verbose$4 ? this.stackID(stack) + " -> " : ""; - if (stack.deadEnd) { - if (restarted) - continue; - restarted = true; - stack.restart(); - if (verbose$4) - console.log(base + this.stackID(stack) + " (restarted)"); - let done = this.advanceFully(stack, newStacks); - if (done) - continue; - } - let force = stack.split(), forceBase = base; - for (let j = 0; force.forceReduce() && j < 10 /* ForceReduceLimit */; j++) { - if (verbose$4) - console.log(forceBase + this.stackID(force) + " (via force-reduce)"); - let done = this.advanceFully(force, newStacks); - if (done) - break; - if (verbose$4) - forceBase = this.stackID(force) + " -> "; - } - for (let insert of stack.recoverByInsert(token)) { - if (verbose$4) - console.log(base + this.stackID(insert) + " (via recover-insert)"); - this.advanceFully(insert, newStacks); - } - if (this.stream.end > stack.pos) { - if (tokenEnd == stack.pos) { - tokenEnd++; - token = 0 /* Err */; - } - stack.recoverByDelete(token, tokenEnd); - if (verbose$4) - console.log(base + this.stackID(stack) + ` (via recover-delete ${this.parser.getName(token)})`); - pushStackDedup$4(stack, newStacks); - } - else if (!finished || finished.score < stack.score) { - finished = stack; - } - } - return finished; - } - // Convert the stack's buffer to a syntax tree. - stackToTree(stack) { - stack.close(); - return Tree.build({ buffer: StackBufferCursor$4.create(stack), - nodeSet: this.parser.nodeSet, - topID: this.topTerm, - maxBufferLength: this.parser.bufferLength, - reused: this.reused, - start: this.ranges[0].from, - length: stack.pos - this.ranges[0].from, - minRepeatType: this.parser.minRepeatTerm }); - } - stackID(stack) { - let id = (stackIDs$4 || (stackIDs$4 = new WeakMap)).get(stack); - if (!id) - stackIDs$4.set(stack, id = String.fromCodePoint(this.nextStackID++)); - return id + stack; - } -} -function pushStackDedup$4(stack, newStacks) { - for (let i = 0; i < newStacks.length; i++) { - let other = newStacks[i]; - if (other.pos == stack.pos && other.sameState(stack)) { - if (newStacks[i].score < stack.score) - newStacks[i] = stack; - return; - } - } - newStacks.push(stack); -} -class Dialect$4 { - constructor(source, flags, disabled) { - this.source = source; - this.flags = flags; - this.disabled = disabled; - } - allows(term) { return !this.disabled || this.disabled[term] == 0; } -} -const id$2 = x => x; -/// Context trackers are used to track stateful context (such as -/// indentation in the Python grammar, or parent elements in the XML -/// grammar) needed by external tokenizers. You declare them in a -/// grammar file as `@context exportName from "module"`. -/// -/// Context values should be immutable, and can be updated (replaced) -/// on shift or reduce actions. -/// -/// The export used in a `@context` declaration should be of this -/// type. -class ContextTracker$2 { - /// Define a context tracker. - constructor(spec) { - this.start = spec.start; - this.shift = spec.shift || id$2; - this.reduce = spec.reduce || id$2; - this.reuse = spec.reuse || id$2; - this.hash = spec.hash || (() => 0); - this.strict = spec.strict !== false; - } -} -/// A parser holds the parse tables for a given grammar, as generated -/// by `lezer-generator`. -class LRParser$4 extends Parser { - /// @internal - constructor(spec) { - super(); - /// @internal - this.wrappers = []; - if (spec.version != 14 /* Version */) - throw new RangeError(`Parser version (${spec.version}) doesn't match runtime version (${14 /* Version */})`); - let nodeNames = spec.nodeNames.split(" "); - this.minRepeatTerm = nodeNames.length; - for (let i = 0; i < spec.repeatNodeCount; i++) - nodeNames.push(""); - let topTerms = Object.keys(spec.topRules).map(r => spec.topRules[r][1]); - let nodeProps = []; - for (let i = 0; i < nodeNames.length; i++) - nodeProps.push([]); - function setProp(nodeID, prop, value) { - nodeProps[nodeID].push([prop, prop.deserialize(String(value))]); - } - if (spec.nodeProps) - for (let propSpec of spec.nodeProps) { - let prop = propSpec[0]; - if (typeof prop == "string") - prop = NodeProp[prop]; - for (let i = 1; i < propSpec.length;) { - let next = propSpec[i++]; - if (next >= 0) { - setProp(next, prop, propSpec[i++]); - } - else { - let value = propSpec[i + -next]; - for (let j = -next; j > 0; j--) - setProp(propSpec[i++], prop, value); - i++; - } - } - } - this.nodeSet = new NodeSet(nodeNames.map((name, i) => NodeType.define({ - name: i >= this.minRepeatTerm ? undefined : name, - id: i, - props: nodeProps[i], - top: topTerms.indexOf(i) > -1, - error: i == 0, - skipped: spec.skippedNodes && spec.skippedNodes.indexOf(i) > -1 - }))); - if (spec.propSources) - this.nodeSet = this.nodeSet.extend(...spec.propSources); - this.strict = false; - this.bufferLength = DefaultBufferLength; - let tokenArray = decodeArray$4(spec.tokenData); - this.context = spec.context; - this.specialized = new Uint16Array(spec.specialized ? spec.specialized.length : 0); - this.specializers = []; - if (spec.specialized) - for (let i = 0; i < spec.specialized.length; i++) { - this.specialized[i] = spec.specialized[i].term; - this.specializers[i] = spec.specialized[i].get; - } - this.states = decodeArray$4(spec.states, Uint32Array); - this.data = decodeArray$4(spec.stateData); - this.goto = decodeArray$4(spec.goto); - this.maxTerm = spec.maxTerm; - this.tokenizers = spec.tokenizers.map(value => typeof value == "number" ? new TokenGroup$4(tokenArray, value) : value); - this.topRules = spec.topRules; - this.dialects = spec.dialects || {}; - this.dynamicPrecedences = spec.dynamicPrecedences || null; - this.tokenPrecTable = spec.tokenPrec; - this.termNames = spec.termNames || null; - this.maxNode = this.nodeSet.types.length - 1; - this.dialect = this.parseDialect(); - this.top = this.topRules[Object.keys(this.topRules)[0]]; - } - createParse(input, fragments, ranges) { - let parse = new Parse$4(this, input, fragments, ranges); - for (let w of this.wrappers) - parse = w(parse, input, fragments, ranges); - return parse; - } - /// Get a goto table entry @internal - getGoto(state, term, loose = false) { - let table = this.goto; - if (term >= table[0]) - return -1; - for (let pos = table[term + 1];;) { - let groupTag = table[pos++], last = groupTag & 1; - let target = table[pos++]; - if (last && loose) - return target; - for (let end = pos + (groupTag >> 1); pos < end; pos++) - if (table[pos] == state) - return target; - if (last) - return -1; - } - } - /// Check if this state has an action for a given terminal @internal - hasAction(state, terminal) { - let data = this.data; - for (let set = 0; set < 2; set++) { - for (let i = this.stateSlot(state, set ? 2 /* Skip */ : 1 /* Actions */), next;; i += 3) { - if ((next = data[i]) == 65535 /* End */) { - if (data[i + 1] == 1 /* Next */) - next = data[i = pair$4(data, i + 2)]; - else if (data[i + 1] == 2 /* Other */) - return pair$4(data, i + 2); - else - break; - } - if (next == terminal || next == 0 /* Err */) - return pair$4(data, i + 1); - } - } - return 0; - } - /// @internal - stateSlot(state, slot) { - return this.states[(state * 6 /* Size */) + slot]; - } - /// @internal - stateFlag(state, flag) { - return (this.stateSlot(state, 0 /* Flags */) & flag) > 0; - } - /// @internal - validAction(state, action) { - if (action == this.stateSlot(state, 4 /* DefaultReduce */)) - return true; - for (let i = this.stateSlot(state, 1 /* Actions */);; i += 3) { - if (this.data[i] == 65535 /* End */) { - if (this.data[i + 1] == 1 /* Next */) - i = pair$4(this.data, i + 2); - else - return false; - } - if (action == pair$4(this.data, i + 1)) - return true; - } - } - /// Get the states that can follow this one through shift actions or - /// goto jumps. @internal - nextStates(state) { - let result = []; - for (let i = this.stateSlot(state, 1 /* Actions */);; i += 3) { - if (this.data[i] == 65535 /* End */) { - if (this.data[i + 1] == 1 /* Next */) - i = pair$4(this.data, i + 2); - else - break; - } - if ((this.data[i + 2] & (65536 /* ReduceFlag */ >> 16)) == 0) { - let value = this.data[i + 1]; - if (!result.some((v, i) => (i & 1) && v == value)) - result.push(this.data[i], value); - } - } - return result; - } - /// @internal - overrides(token, prev) { - let iPrev = findOffset$4(this.data, this.tokenPrecTable, prev); - return iPrev < 0 || findOffset$4(this.data, this.tokenPrecTable, token) < iPrev; - } - /// Configure the parser. Returns a new parser instance that has the - /// given settings modified. Settings not provided in `config` are - /// kept from the original parser. - configure(config) { - // Hideous reflection-based kludge to make it easy to create a - // slightly modified copy of a parser. - let copy = Object.assign(Object.create(LRParser$4.prototype), this); - if (config.props) - copy.nodeSet = this.nodeSet.extend(...config.props); - if (config.top) { - let info = this.topRules[config.top]; - if (!info) - throw new RangeError(`Invalid top rule name ${config.top}`); - copy.top = info; - } - if (config.tokenizers) - copy.tokenizers = this.tokenizers.map(t => { - let found = config.tokenizers.find(r => r.from == t); - return found ? found.to : t; - }); - if (config.contextTracker) - copy.context = config.contextTracker; - if (config.dialect) - copy.dialect = this.parseDialect(config.dialect); - if (config.strict != null) - copy.strict = config.strict; - if (config.wrap) - copy.wrappers = copy.wrappers.concat(config.wrap); - if (config.bufferLength != null) - copy.bufferLength = config.bufferLength; - return copy; - } - /// Tells you whether any [parse wrappers](#lr.ParserConfig.wrap) - /// are registered for this parser. - hasWrappers() { - return this.wrappers.length > 0; - } - /// Returns the name associated with a given term. This will only - /// work for all terms when the parser was generated with the - /// `--names` option. By default, only the names of tagged terms are - /// stored. - getName(term) { - return this.termNames ? this.termNames[term] : String(term <= this.maxNode && this.nodeSet.types[term].name || term); - } - /// The eof term id is always allocated directly after the node - /// types. @internal - get eofTerm() { return this.maxNode + 1; } - /// The type of top node produced by the parser. - get topNode() { return this.nodeSet.types[this.top[1]]; } - /// @internal - dynamicPrecedence(term) { - let prec = this.dynamicPrecedences; - return prec == null ? 0 : prec[term] || 0; - } - /// @internal - parseDialect(dialect) { - let values = Object.keys(this.dialects), flags = values.map(() => false); - if (dialect) - for (let part of dialect.split(" ")) { - let id = values.indexOf(part); - if (id >= 0) - flags[id] = true; - } - let disabled = null; - for (let i = 0; i < values.length; i++) - if (!flags[i]) { - for (let j = this.dialects[values[i]], id; (id = this.data[j++]) != 65535 /* End */;) - (disabled || (disabled = new Uint8Array(this.maxTerm + 1)))[id] = 1; - } - return new Dialect$4(dialect, flags, disabled); - } - /// (used by the output of the parser generator) @internal - static deserialize(spec) { - return new LRParser$4(spec); - } -} -function pair$4(data, off) { return data[off] | (data[off + 1] << 16); } -function findOffset$4(data, start, term) { - for (let i = start, next; (next = data[i]) != 65535 /* End */; i++) - if (next == term) - return i - start; - return -1; -} -function findFinished$4(stacks) { - let best = null; - for (let stack of stacks) { - let stopped = stack.p.stoppedAt; - if ((stack.pos == stack.p.stream.end || stopped != null && stack.pos > stopped) && - stack.p.parser.stateFlag(stack.state, 2 /* Accepting */) && - (!best || best.score < stack.score)) - best = stack; - } - return best; -} - -// This file was generated by lezer-generator. You probably shouldn't edit it. -const scriptText = 53, - StartCloseScriptTag = 1, - styleText = 54, - StartCloseStyleTag = 2, - textareaText = 55, - StartCloseTextareaTag = 3, - StartTag = 4, - StartScriptTag = 5, - StartStyleTag = 6, - StartTextareaTag = 7, - StartSelfClosingTag = 8, - StartCloseTag = 9, - NoMatchStartCloseTag = 10, - MismatchedStartCloseTag = 11, - missingCloseTag = 56, - IncompleteCloseTag = 12, - commentContent$1 = 57, - Element = 18, - ScriptText = 27, - StyleText = 30, - TextareaText = 33, - OpenTag = 35, - Dialect_noMatch = 0; - -/* Hand-written tokenizers for HTML. */ - -const selfClosers = { - area: true, base: true, br: true, col: true, command: true, - embed: true, frame: true, hr: true, img: true, input: true, - keygen: true, link: true, meta: true, param: true, source: true, - track: true, wbr: true, menuitem: true -}; - -const implicitlyClosed = { - dd: true, li: true, optgroup: true, option: true, p: true, - rp: true, rt: true, tbody: true, td: true, tfoot: true, - th: true, tr: true -}; - -const closeOnOpen = { - dd: {dd: true, dt: true}, - dt: {dd: true, dt: true}, - li: {li: true}, - option: {option: true, optgroup: true}, - optgroup: {optgroup: true}, - p: { - address: true, article: true, aside: true, blockquote: true, dir: true, - div: true, dl: true, fieldset: true, footer: true, form: true, - h1: true, h2: true, h3: true, h4: true, h5: true, h6: true, - header: true, hgroup: true, hr: true, menu: true, nav: true, ol: true, - p: true, pre: true, section: true, table: true, ul: true - }, - rp: {rp: true, rt: true}, - rt: {rp: true, rt: true}, - tbody: {tbody: true, tfoot: true}, - td: {td: true, th: true}, - tfoot: {tbody: true}, - th: {td: true, th: true}, - thead: {tbody: true, tfoot: true}, - tr: {tr: true} -}; - -function nameChar(ch) { - return ch == 45 || ch == 46 || ch == 58 || ch >= 65 && ch <= 90 || ch == 95 || ch >= 97 && ch <= 122 || ch >= 161 -} - -function isSpace(ch) { - return ch == 9 || ch == 10 || ch == 13 || ch == 32 -} - -let cachedName = null, cachedInput = null, cachedPos = 0; -function tagNameAfter(input, offset) { - let pos = input.pos + offset; - if (cachedPos == pos && cachedInput == input) return cachedName - let next = input.peek(offset); - while (isSpace(next)) next = input.peek(++offset); - let name = ""; - for (;;) { - if (!nameChar(next)) break - name += String.fromCharCode(next); - next = input.peek(++offset); - } - // Undefined to signal there's a -1 ? new ElementContext(tagNameAfter(input, 1) || "", context) : context - }, - reduce(context, term) { - return term == Element && context ? context.parent : context - }, - reuse(context, node, stack, input) { - let type = node.type.id; - return type == StartTag || type == OpenTag - ? new ElementContext(tagNameAfter(input, 1) || "", context) : context - }, - hash(context) { return context ? context.hash : 0 }, - strict: false -}); - -const tagStart = new ExternalTokenizer$4((input, stack) => { - if (input.next != lessThan) { - // End of file, close any open tags - if (input.next < 0 && stack.context) input.acceptToken(missingCloseTag); - return - } - input.advance(); - let close = input.next == slash$1; - if (close) input.advance(); - let name = tagNameAfter(input, 0); - if (name === undefined) return - if (!name) return input.acceptToken(close ? IncompleteCloseTag : StartTag) - - let parent = stack.context ? stack.context.name : null; - if (close) { - if (name == parent) return input.acceptToken(StartCloseTag) - if (parent && implicitlyClosed[parent]) return input.acceptToken(missingCloseTag, -2) - if (stack.dialectEnabled(Dialect_noMatch)) return input.acceptToken(NoMatchStartCloseTag) - for (let cx = stack.context; cx; cx = cx.parent) if (cx.name == name) return - input.acceptToken(MismatchedStartCloseTag); - } else { - if (name == "script") return input.acceptToken(StartScriptTag) - if (name == "style") return input.acceptToken(StartStyleTag) - if (name == "textarea") return input.acceptToken(StartTextareaTag) - if (selfClosers.hasOwnProperty(name)) return input.acceptToken(StartSelfClosingTag) - if (parent && closeOnOpen[parent] && closeOnOpen[parent][name]) input.acceptToken(missingCloseTag, -1); - else input.acceptToken(StartTag); - } -}, {contextual: true}); - -const commentContent = new ExternalTokenizer$4(input => { - for (let dashes = 0, i = 0;; i++) { - if (input.next < 0) { - if (i) input.acceptToken(commentContent$1); - break - } - if (input.next == dash$1) { - dashes++; - } else if (input.next == greaterThan && dashes >= 2) { - if (i > 3) input.acceptToken(commentContent$1, -2); - break - } else { - dashes = 0; - } - input.advance(); - } -}); - -function contentTokenizer(tag, textToken, endToken) { - let lastState = 2 + tag.length; - return new ExternalTokenizer$4(input => { - // state means: - // - 0 nothing matched - // - 1 '<' matched - // - 2 '= 2 && state < lastState && input.next == tag.charCodeAt(state - 2)) { - state++; - matchedLen++; - } else if ((state == 2 || state == lastState) && isSpace(input.next)) { - matchedLen++; - } else if (state == lastState && input.next == greaterThan) { - if (i > matchedLen) - input.acceptToken(textToken, -matchedLen); - else - input.acceptToken(endToken, -(matchedLen - 2)); - break - } else if ((input.next == 10 /* '\n' */ || input.next == 13 /* '\r' */) && i) { - input.acceptToken(textToken, 1); - break - } else { - state = matchedLen = 0; - } - input.advance(); - } - }) -} - -const scriptTokens = contentTokenizer("script", scriptText, StartCloseScriptTag); - -const styleTokens = contentTokenizer("style", styleText, StartCloseStyleTag); - -const textareaTokens = contentTokenizer("textarea", textareaText, StartCloseTextareaTag); - -const htmlHighlighting = styleTags({ - "Text RawText": tags$1.content, - "StartTag StartCloseTag SelfCloserEndTag EndTag SelfCloseEndTag": tags$1.angleBracket, - TagName: tags$1.tagName, - "MismatchedCloseTag/TagName": [tags$1.tagName, tags$1.invalid], - AttributeName: tags$1.attributeName, - "AttributeValue UnquotedAttributeValue": tags$1.attributeValue, - Is: tags$1.definitionOperator, - "EntityReference CharacterReference": tags$1.character, - Comment: tags$1.blockComment, - ProcessingInst: tags$1.processingInstruction, - DoctypeDecl: tags$1.documentMeta -}); - -// This file was generated by lezer-generator. You probably shouldn't edit it. -const parser$5 = LRParser$4.deserialize({ - version: 14, - states: ",xOVOxOOO!WQ!bO'#CoO!]Q!bO'#CyO!bQ!bO'#C|O!gQ!bO'#DPO!lQ!bO'#DRO!qOXO'#CnO!|OYO'#CnO#XO[O'#CnO$eOxO'#CnOOOW'#Cn'#CnO$lO!rO'#DSO$tQ!bO'#DUO$yQ!bO'#DVOOOW'#Dj'#DjOOOW'#DX'#DXQVOxOOO%OQ#tO,59ZO%WQ#tO,59eO%`Q#tO,59hO%hQ#tO,59kO%pQ#tO,59mOOOX'#D]'#D]O%xOXO'#CwO&TOXO,59YOOOY'#D^'#D^O&]OYO'#CzO&hOYO,59YOOO['#D_'#D_O&pO[O'#C}O&{O[O,59YOOOW'#D`'#D`O'TOxO,59YO'[Q!bO'#DQOOOW,59Y,59YOOO`'#Da'#DaO'aO!rO,59nOOOW,59n,59nO'iQ!bO,59pO'nQ!bO,59qOOOW-E7V-E7VO'sQ#tO'#CqOOQO'#DY'#DYO(OQ#tO1G.uOOOX1G.u1G.uO(WQ#tO1G/POOOY1G/P1G/PO(`Q#tO1G/SOOO[1G/S1G/SO(hQ#tO1G/VOOOW1G/V1G/VO(pQ#tO1G/XOOOW1G/X1G/XOOOX-E7Z-E7ZO(xQ!bO'#CxOOOW1G.t1G.tOOOY-E7[-E7[O(}Q!bO'#C{OOO[-E7]-E7]O)SQ!bO'#DOOOOW-E7^-E7^O)XQ!bO,59lOOO`-E7_-E7_OOOW1G/Y1G/YOOOW1G/[1G/[OOOW1G/]1G/]O)^Q&jO,59]OOQO-E7W-E7WOOOX7+$a7+$aOOOY7+$k7+$kOOO[7+$n7+$nOOOW7+$q7+$qOOOW7+$s7+$sO)iQ!bO,59dO)nQ!bO,59gO)sQ!bO,59jOOOW1G/W1G/WO)xO,UO'#CtO*WO7[O'#CtOOQO1G.w1G.wOOOW1G/O1G/OOOOW1G/R1G/ROOOW1G/U1G/UOOOO'#DZ'#DZO*fO,UO,59`OOQO,59`,59`OOOO'#D['#D[O*tO7[O,59`OOOO-E7X-E7XOOQO1G.z1G.zOOOO-E7Y-E7Y", - stateData: "+[~O!]OS~OSSOTPOUQOVROWTOY]OZ[O[^O^^O_^O`^Oa^Ow^Oz_O!cZO~OdaO~OdbO~OdcO~OddO~OdeO~O!VfOPkP!YkP~O!WiOQnP!YnP~O!XlORqP!YqP~OSSOTPOUQOVROWTOXqOY]OZ[O[^O^^O_^O`^Oa^Ow^O!cZO~O!YrO~P#dO!ZsO!duO~OdvO~OdwO~OfyOj|O~OfyOj!OO~OfyOj!QO~OfyOj!SO~OfyOj!UO~O!VfOPkX!YkX~OP!WO!Y!XO~O!WiOQnX!YnX~OQ!ZO!Y!XO~O!XlORqX!YqX~OR!]O!Y!XO~O!Y!XO~P#dOd!_O~O!ZsO!d!aO~Oj!bO~Oj!cO~Og!dOfeXjeX~OfyOj!fO~OfyOj!gO~OfyOj!hO~OfyOj!iO~OfyOj!jO~Od!kO~Od!lO~Od!mO~Oj!nO~Oi!qO!_!oO!a!pO~Oj!rO~Oj!sO~Oj!tO~O_!uO`!uO!_!wO!`!uO~O_!xO`!xO!a!wO!b!xO~O_!uO`!uO!_!{O!`!uO~O_!xO`!xO!a!{O!b!xO~O`_a!cwz!c~", - goto: "%o!_PPPPPPPPPPPPPPPPPP!`!fP!lPP!xPP!{#O#R#X#[#_#e#h#k#q#w!`P!`!`P#}$T$k$q$w$}%T%Z%aPPPPPPPP%gX^OX`pXUOX`pezabcde{}!P!R!TR!q!dRhUR!XhXVOX`pRkVR!XkXWOX`pRnWR!XnXXOX`pQrXR!XpXYOX`pQ`ORx`Q{aQ}bQ!PcQ!RdQ!TeZ!e{}!P!R!TQ!v!oR!z!vQ!y!pR!|!yQgUR!VgQjVR!YjQmWR![mQpXR!^pQtZR!`tS_O`ToXp", - nodeNames: "⚠ StartCloseTag StartCloseTag StartCloseTag StartTag StartTag StartTag StartTag StartTag StartCloseTag StartCloseTag StartCloseTag IncompleteCloseTag Document Text EntityReference CharacterReference InvalidEntity Element OpenTag TagName Attribute AttributeName Is AttributeValue UnquotedAttributeValue EndTag ScriptText CloseTag OpenTag StyleText CloseTag OpenTag TextareaText CloseTag OpenTag CloseTag SelfClosingTag Comment ProcessingInst MismatchedCloseTag CloseTag DoctypeDecl", - maxTerm: 66, - context: elementContext, - nodeProps: [ - ["closedBy", -11,1,2,3,4,5,6,7,8,9,10,11,"EndTag",-4,19,29,32,35,"CloseTag"], - ["group", -9,12,15,16,17,18,38,39,40,41,"Entity",14,"Entity TextContent",-3,27,30,33,"TextContent Entity"], - ["openedBy", 26,"StartTag StartCloseTag",-4,28,31,34,36,"OpenTag"] - ], - propSources: [htmlHighlighting], - skippedNodes: [0], - repeatNodeCount: 9, - tokenData: "!#b!aR!WOX$kXY)sYZ)sZ]$k]^)s^p$kpq)sqr$krs*zsv$kvw+dwx2yx}$k}!O3f!O!P$k!P!Q7_!Q![$k![!]8u!]!^$k!^!_>b!_!`!!p!`!a8T!a!c$k!c!}8u!}#R$k#R#S8u#S#T$k#T#o8u#o$f$k$f$g&R$g%W$k%W%o8u%o%p$k%p&a8u&a&b$k&b1p8u1p4U$k4U4d8u4d4e$k4e$IS8u$IS$I`$k$I`$Ib8u$Ib$Kh$k$Kh%#t8u%#t&/x$k&/x&Et8u&Et&FV$k&FV;'S8u;'S;:jiW!``!bpOq(kqr?Rrs'gsv(kwx(]x!a(k!a!bKj!b~(k!R?YZ!``!bpOr(krs'gsv(kwx(]x}(k}!O?{!O!f(k!f!gAR!g#W(k#W#XGz#X~(k!R@SV!``!bpOr(krs'gsv(kwx(]x}(k}!O@i!O~(k!R@rT!``!bp!cPOr(krs'gsv(kwx(]x~(k!RAYV!``!bpOr(krs'gsv(kwx(]x!q(k!q!rAo!r~(k!RAvV!``!bpOr(krs'gsv(kwx(]x!e(k!e!fB]!f~(k!RBdV!``!bpOr(krs'gsv(kwx(]x!v(k!v!wBy!w~(k!RCQV!``!bpOr(krs'gsv(kwx(]x!{(k!{!|Cg!|~(k!RCnV!``!bpOr(krs'gsv(kwx(]x!r(k!r!sDT!s~(k!RD[V!``!bpOr(krs'gsv(kwx(]x!g(k!g!hDq!h~(k!RDxW!``!bpOrDqrsEbsvDqvwEvwxFfx!`Dq!`!aGb!a~DqqEgT!bpOvEbvxEvx!`Eb!`!aFX!a~EbPEyRO!`Ev!`!aFS!a~EvPFXOzPqF`Q!bpzPOv'gx~'gaFkV!``OrFfrsEvsvFfvwEvw!`Ff!`!aGQ!a~FfaGXR!``zPOr(]sv(]w~(]!RGkT!``!bpzPOr(krs'gsv(kwx(]x~(k!RHRV!``!bpOr(krs'gsv(kwx(]x#c(k#c#dHh#d~(k!RHoV!``!bpOr(krs'gsv(kwx(]x#V(k#V#WIU#W~(k!RI]V!``!bpOr(krs'gsv(kwx(]x#h(k#h#iIr#i~(k!RIyV!``!bpOr(krs'gsv(kwx(]x#m(k#m#nJ`#n~(k!RJgV!``!bpOr(krs'gsv(kwx(]x#d(k#d#eJ|#e~(k!RKTV!``!bpOr(krs'gsv(kwx(]x#X(k#X#YDq#Y~(k!RKqW!``!bpOrKjrsLZsvKjvwLowxNPx!aKj!a!b! g!b~KjqL`T!bpOvLZvxLox!aLZ!a!bM^!b~LZPLrRO!aLo!a!bL{!b~LoPMORO!`Lo!`!aMX!a~LoPM^OwPqMcT!bpOvLZvxLox!`LZ!`!aMr!a~LZqMyQ!bpwPOv'gx~'gaNUV!``OrNPrsLosvNPvwLow!aNP!a!bNk!b~NPaNpV!``OrNPrsLosvNPvwLow!`NP!`!a! V!a~NPa! ^R!``wPOr(]sv(]w~(]!R! nW!``!bpOrKjrsLZsvKjvwLowxNPx!`Kj!`!a!!W!a~Kj!R!!aT!``!bpwPOr(krs'gsv(kwx(]x~(k!V!!{VgS^P!``!bpOr&Rrs&qsv&Rwx'rx!^&R!^!_(k!_~&R", - tokenizers: [scriptTokens, styleTokens, textareaTokens, tagStart, commentContent, 0, 1, 2, 3, 4, 5], - topRules: {"Document":[0,13]}, - dialects: {noMatch: 0}, - tokenPrec: 464 -}); - -function getAttrs(element, input) { - let attrs = Object.create(null); - for (let att of element.firstChild.getChildren("Attribute")) { - let name = att.getChild("AttributeName"), value = att.getChild("AttributeValue") || att.getChild("UnquotedAttributeValue"); - if (name) attrs[input.read(name.from, name.to)] = - !value ? "" : value.name == "AttributeValue" ? input.read(value.from + 1, value.to - 1) : input.read(value.from, value.to); - } - return attrs -} - -function maybeNest(node, input, tags) { - let attrs; - for (let tag of tags) { - if (!tag.attrs || tag.attrs(attrs || (attrs = getAttrs(node.node.parent, input)))) - return {parser: tag.parser} - } - return null -} - -// tags: { -// tag: "script" | "style" | "textarea", -// attrs?: ({[attr: string]: string}) => boolean, -// parser: Parser -// }[] - -function configureNesting(tags) { - let script = [], style = [], textarea = []; - for (let tag of tags) { - let array = tag.tag == "script" ? script : tag.tag == "style" ? style : tag.tag == "textarea" ? textarea : null; - if (!array) throw new RangeError("Only script, style, and textarea tags can host nested parsers") - array.push(tag); - } - return parseMixed((node, input) => { - let id = node.type.id; - if (id == ScriptText) return maybeNest(node, input, script) - if (id == StyleText) return maybeNest(node, input, style) - if (id == TextareaText) return maybeNest(node, input, textarea) - return null - }) -} - -/// A parse stack. These are used internally by the parser to track -/// parsing progress. They also provide some properties and methods -/// that external code such as a tokenizer can use to get information -/// about the parse state. -class Stack$3 { - /// @internal - constructor( - /// The parse that this stack is part of @internal - p, - /// Holds state, input pos, buffer index triplets for all but the - /// top state @internal - stack, - /// The current parse state @internal - state, - // The position at which the next reduce should take place. This - // can be less than `this.pos` when skipped expressions have been - // added to the stack (which should be moved outside of the next - // reduction) - /// @internal - reducePos, - /// The input position up to which this stack has parsed. - pos, - /// The dynamic score of the stack, including dynamic precedence - /// and error-recovery penalties - /// @internal - score, - // The output buffer. Holds (type, start, end, size) quads - // representing nodes created by the parser, where `size` is - // amount of buffer array entries covered by this node. - /// @internal - buffer, - // The base offset of the buffer. When stacks are split, the split - // instance shared the buffer history with its parent up to - // `bufferBase`, which is the absolute offset (including the - // offset of previous splits) into the buffer at which this stack - // starts writing. - /// @internal - bufferBase, - /// @internal - curContext, - /// @internal - lookAhead = 0, - // A parent stack from which this was split off, if any. This is - // set up so that it always points to a stack that has some - // additional buffer content, never to a stack with an equal - // `bufferBase`. - /// @internal - parent) { - this.p = p; - this.stack = stack; - this.state = state; - this.reducePos = reducePos; - this.pos = pos; - this.score = score; - this.buffer = buffer; - this.bufferBase = bufferBase; - this.curContext = curContext; - this.lookAhead = lookAhead; - this.parent = parent; - } - /// @internal - toString() { - return `[${this.stack.filter((_, i) => i % 3 == 0).concat(this.state)}]@${this.pos}${this.score ? "!" + this.score : ""}`; - } - // Start an empty stack - /// @internal - static start(p, state, pos = 0) { - let cx = p.parser.context; - return new Stack$3(p, [], state, pos, pos, 0, [], 0, cx ? new StackContext$3(cx, cx.start) : null, 0, null); - } - /// The stack's current [context](#lr.ContextTracker) value, if - /// any. Its type will depend on the context tracker's type - /// parameter, or it will be `null` if there is no context - /// tracker. - get context() { return this.curContext ? this.curContext.context : null; } - // Push a state onto the stack, tracking its start position as well - // as the buffer base at that point. - /// @internal - pushState(state, start) { - this.stack.push(this.state, start, this.bufferBase + this.buffer.length); - this.state = state; - } - // Apply a reduce action - /// @internal - reduce(action) { - let depth = action >> 19 /* ReduceDepthShift */, type = action & 65535 /* ValueMask */; - let { parser } = this.p; - let dPrec = parser.dynamicPrecedence(type); - if (dPrec) - this.score += dPrec; - if (depth == 0) { - this.pushState(parser.getGoto(this.state, type, true), this.reducePos); - // Zero-depth reductions are a special case—they add stuff to - // the stack without popping anything off. - if (type < parser.minRepeatTerm) - this.storeNode(type, this.reducePos, this.reducePos, 4, true); - this.reduceContext(type, this.reducePos); - return; - } - // Find the base index into `this.stack`, content after which will - // be dropped. Note that with `StayFlag` reductions we need to - // consume two extra frames (the dummy parent node for the skipped - // expression and the state that we'll be staying in, which should - // be moved to `this.state`). - let base = this.stack.length - ((depth - 1) * 3) - (action & 262144 /* StayFlag */ ? 6 : 0); - let start = this.stack[base - 2]; - let bufferBase = this.stack[base - 1], count = this.bufferBase + this.buffer.length - bufferBase; - // Store normal terms or `R -> R R` repeat reductions - if (type < parser.minRepeatTerm || (action & 131072 /* RepeatFlag */)) { - let pos = parser.stateFlag(this.state, 1 /* Skipped */) ? this.pos : this.reducePos; - this.storeNode(type, start, pos, count + 4, true); - } - if (action & 262144 /* StayFlag */) { - this.state = this.stack[base]; - } - else { - let baseStateID = this.stack[base - 3]; - this.state = parser.getGoto(baseStateID, type, true); - } - while (this.stack.length > base) - this.stack.pop(); - this.reduceContext(type, start); - } - // Shift a value into the buffer - /// @internal - storeNode(term, start, end, size = 4, isReduce = false) { - if (term == 0 /* Err */ && - (!this.stack.length || this.stack[this.stack.length - 1] < this.buffer.length + this.bufferBase)) { - // Try to omit/merge adjacent error nodes - let cur = this, top = this.buffer.length; - if (top == 0 && cur.parent) { - top = cur.bufferBase - cur.parent.bufferBase; - cur = cur.parent; - } - if (top > 0 && cur.buffer[top - 4] == 0 /* Err */ && cur.buffer[top - 1] > -1) { - if (start == end) - return; - if (cur.buffer[top - 2] >= start) { - cur.buffer[top - 2] = end; - return; - } - } - } - if (!isReduce || this.pos == end) { // Simple case, just append - this.buffer.push(term, start, end, size); - } - else { // There may be skipped nodes that have to be moved forward - let index = this.buffer.length; - if (index > 0 && this.buffer[index - 4] != 0 /* Err */) - while (index > 0 && this.buffer[index - 2] > end) { - // Move this record forward - this.buffer[index] = this.buffer[index - 4]; - this.buffer[index + 1] = this.buffer[index - 3]; - this.buffer[index + 2] = this.buffer[index - 2]; - this.buffer[index + 3] = this.buffer[index - 1]; - index -= 4; - if (size > 4) - size -= 4; - } - this.buffer[index] = term; - this.buffer[index + 1] = start; - this.buffer[index + 2] = end; - this.buffer[index + 3] = size; - } - } - // Apply a shift action - /// @internal - shift(action, next, nextEnd) { - let start = this.pos; - if (action & 131072 /* GotoFlag */) { - this.pushState(action & 65535 /* ValueMask */, this.pos); - } - else if ((action & 262144 /* StayFlag */) == 0) { // Regular shift - let nextState = action, { parser } = this.p; - if (nextEnd > this.pos || next <= parser.maxNode) { - this.pos = nextEnd; - if (!parser.stateFlag(nextState, 1 /* Skipped */)) - this.reducePos = nextEnd; - } - this.pushState(nextState, start); - this.shiftContext(next, start); - if (next <= parser.maxNode) - this.buffer.push(next, start, nextEnd, 4); - } - else { // Shift-and-stay, which means this is a skipped token - this.pos = nextEnd; - this.shiftContext(next, start); - if (next <= this.p.parser.maxNode) - this.buffer.push(next, start, nextEnd, 4); - } - } - // Apply an action - /// @internal - apply(action, next, nextEnd) { - if (action & 65536 /* ReduceFlag */) - this.reduce(action); - else - this.shift(action, next, nextEnd); - } - // Add a prebuilt (reused) node into the buffer. - /// @internal - useNode(value, next) { - let index = this.p.reused.length - 1; - if (index < 0 || this.p.reused[index] != value) { - this.p.reused.push(value); - index++; - } - let start = this.pos; - this.reducePos = this.pos = start + value.length; - this.pushState(next, start); - this.buffer.push(index, start, this.reducePos, -1 /* size == -1 means this is a reused value */); - if (this.curContext) - this.updateContext(this.curContext.tracker.reuse(this.curContext.context, value, this, this.p.stream.reset(this.pos - value.length))); - } - // Split the stack. Due to the buffer sharing and the fact - // that `this.stack` tends to stay quite shallow, this isn't very - // expensive. - /// @internal - split() { - let parent = this; - let off = parent.buffer.length; - // Because the top of the buffer (after this.pos) may be mutated - // to reorder reductions and skipped tokens, and shared buffers - // should be immutable, this copies any outstanding skipped tokens - // to the new buffer, and puts the base pointer before them. - while (off > 0 && parent.buffer[off - 2] > parent.reducePos) - off -= 4; - let buffer = parent.buffer.slice(off), base = parent.bufferBase + off; - // Make sure parent points to an actual parent with content, if there is such a parent. - while (parent && base == parent.bufferBase) - parent = parent.parent; - return new Stack$3(this.p, this.stack.slice(), this.state, this.reducePos, this.pos, this.score, buffer, base, this.curContext, this.lookAhead, parent); - } - // Try to recover from an error by 'deleting' (ignoring) one token. - /// @internal - recoverByDelete(next, nextEnd) { - let isNode = next <= this.p.parser.maxNode; - if (isNode) - this.storeNode(next, this.pos, nextEnd, 4); - this.storeNode(0 /* Err */, this.pos, nextEnd, isNode ? 8 : 4); - this.pos = this.reducePos = nextEnd; - this.score -= 190 /* Delete */; - } - /// Check if the given term would be able to be shifted (optionally - /// after some reductions) on this stack. This can be useful for - /// external tokenizers that want to make sure they only provide a - /// given token when it applies. - canShift(term) { - for (let sim = new SimulatedStack$3(this);;) { - let action = this.p.parser.stateSlot(sim.state, 4 /* DefaultReduce */) || this.p.parser.hasAction(sim.state, term); - if ((action & 65536 /* ReduceFlag */) == 0) - return true; - if (action == 0) - return false; - sim.reduce(action); - } - } - // Apply up to Recover.MaxNext recovery actions that conceptually - // inserts some missing token or rule. - /// @internal - recoverByInsert(next) { - if (this.stack.length >= 300 /* MaxInsertStackDepth */) - return []; - let nextStates = this.p.parser.nextStates(this.state); - if (nextStates.length > 4 /* MaxNext */ << 1 || this.stack.length >= 120 /* DampenInsertStackDepth */) { - let best = []; - for (let i = 0, s; i < nextStates.length; i += 2) { - if ((s = nextStates[i + 1]) != this.state && this.p.parser.hasAction(s, next)) - best.push(nextStates[i], s); - } - if (this.stack.length < 120 /* DampenInsertStackDepth */) - for (let i = 0; best.length < 4 /* MaxNext */ << 1 && i < nextStates.length; i += 2) { - let s = nextStates[i + 1]; - if (!best.some((v, i) => (i & 1) && v == s)) - best.push(nextStates[i], s); - } - nextStates = best; - } - let result = []; - for (let i = 0; i < nextStates.length && result.length < 4 /* MaxNext */; i += 2) { - let s = nextStates[i + 1]; - if (s == this.state) - continue; - let stack = this.split(); - stack.pushState(s, this.pos); - stack.storeNode(0 /* Err */, stack.pos, stack.pos, 4, true); - stack.shiftContext(nextStates[i], this.pos); - stack.score -= 200 /* Insert */; - result.push(stack); - } - return result; - } - // Force a reduce, if possible. Return false if that can't - // be done. - /// @internal - forceReduce() { - let reduce = this.p.parser.stateSlot(this.state, 5 /* ForcedReduce */); - if ((reduce & 65536 /* ReduceFlag */) == 0) - return false; - let { parser } = this.p; - if (!parser.validAction(this.state, reduce)) { - let depth = reduce >> 19 /* ReduceDepthShift */, term = reduce & 65535 /* ValueMask */; - let target = this.stack.length - depth * 3; - if (target < 0 || parser.getGoto(this.stack[target], term, false) < 0) - return false; - this.storeNode(0 /* Err */, this.reducePos, this.reducePos, 4, true); - this.score -= 100 /* Reduce */; - } - this.reducePos = this.pos; - this.reduce(reduce); - return true; - } - /// @internal - forceAll() { - while (!this.p.parser.stateFlag(this.state, 2 /* Accepting */)) { - if (!this.forceReduce()) { - this.storeNode(0 /* Err */, this.pos, this.pos, 4, true); - break; - } - } - return this; - } - /// Check whether this state has no further actions (assumed to be a direct descendant of the - /// top state, since any other states must be able to continue - /// somehow). @internal - get deadEnd() { - if (this.stack.length != 3) - return false; - let { parser } = this.p; - return parser.data[parser.stateSlot(this.state, 1 /* Actions */)] == 65535 /* End */ && - !parser.stateSlot(this.state, 4 /* DefaultReduce */); - } - /// Restart the stack (put it back in its start state). Only safe - /// when this.stack.length == 3 (state is directly below the top - /// state). @internal - restart() { - this.state = this.stack[0]; - this.stack.length = 0; - } - /// @internal - sameState(other) { - if (this.state != other.state || this.stack.length != other.stack.length) - return false; - for (let i = 0; i < this.stack.length; i += 3) - if (this.stack[i] != other.stack[i]) - return false; - return true; - } - /// Get the parser used by this stack. - get parser() { return this.p.parser; } - /// Test whether a given dialect (by numeric ID, as exported from - /// the terms file) is enabled. - dialectEnabled(dialectID) { return this.p.parser.dialect.flags[dialectID]; } - shiftContext(term, start) { - if (this.curContext) - this.updateContext(this.curContext.tracker.shift(this.curContext.context, term, this, this.p.stream.reset(start))); - } - reduceContext(term, start) { - if (this.curContext) - this.updateContext(this.curContext.tracker.reduce(this.curContext.context, term, this, this.p.stream.reset(start))); - } - /// @internal - emitContext() { - let last = this.buffer.length - 1; - if (last < 0 || this.buffer[last] != -3) - this.buffer.push(this.curContext.hash, this.reducePos, this.reducePos, -3); - } - /// @internal - emitLookAhead() { - let last = this.buffer.length - 1; - if (last < 0 || this.buffer[last] != -4) - this.buffer.push(this.lookAhead, this.reducePos, this.reducePos, -4); - } - updateContext(context) { - if (context != this.curContext.context) { - let newCx = new StackContext$3(this.curContext.tracker, context); - if (newCx.hash != this.curContext.hash) - this.emitContext(); - this.curContext = newCx; - } - } - /// @internal - setLookAhead(lookAhead) { - if (lookAhead > this.lookAhead) { - this.emitLookAhead(); - this.lookAhead = lookAhead; - } - } - /// @internal - close() { - if (this.curContext && this.curContext.tracker.strict) - this.emitContext(); - if (this.lookAhead > 0) - this.emitLookAhead(); - } -} -class StackContext$3 { - constructor(tracker, context) { - this.tracker = tracker; - this.context = context; - this.hash = tracker.strict ? tracker.hash(context) : 0; - } -} -var Recover$3; -(function (Recover) { - Recover[Recover["Insert"] = 200] = "Insert"; - Recover[Recover["Delete"] = 190] = "Delete"; - Recover[Recover["Reduce"] = 100] = "Reduce"; - Recover[Recover["MaxNext"] = 4] = "MaxNext"; - Recover[Recover["MaxInsertStackDepth"] = 300] = "MaxInsertStackDepth"; - Recover[Recover["DampenInsertStackDepth"] = 120] = "DampenInsertStackDepth"; -})(Recover$3 || (Recover$3 = {})); -// Used to cheaply run some reductions to scan ahead without mutating -// an entire stack -class SimulatedStack$3 { - constructor(start) { - this.start = start; - this.state = start.state; - this.stack = start.stack; - this.base = this.stack.length; - } - reduce(action) { - let term = action & 65535 /* ValueMask */, depth = action >> 19 /* ReduceDepthShift */; - if (depth == 0) { - if (this.stack == this.start.stack) - this.stack = this.stack.slice(); - this.stack.push(this.state, 0, 0); - this.base += 3; - } - else { - this.base -= (depth - 1) * 3; - } - let goto = this.start.p.parser.getGoto(this.stack[this.base - 3], term, true); - this.state = goto; - } -} -// This is given to `Tree.build` to build a buffer, and encapsulates -// the parent-stack-walking necessary to read the nodes. -class StackBufferCursor$3 { - constructor(stack, pos, index) { - this.stack = stack; - this.pos = pos; - this.index = index; - this.buffer = stack.buffer; - if (this.index == 0) - this.maybeNext(); - } - static create(stack, pos = stack.bufferBase + stack.buffer.length) { - return new StackBufferCursor$3(stack, pos, pos - stack.bufferBase); - } - maybeNext() { - let next = this.stack.parent; - if (next != null) { - this.index = this.stack.bufferBase - next.bufferBase; - this.stack = next; - this.buffer = next.buffer; - } - } - get id() { return this.buffer[this.index - 4]; } - get start() { return this.buffer[this.index - 3]; } - get end() { return this.buffer[this.index - 2]; } - get size() { return this.buffer[this.index - 1]; } - next() { - this.index -= 4; - this.pos -= 4; - if (this.index == 0) - this.maybeNext(); - } - fork() { - return new StackBufferCursor$3(this.stack, this.pos, this.index); - } -} - -class CachedToken$3 { - constructor() { - this.start = -1; - this.value = -1; - this.end = -1; - this.extended = -1; - this.lookAhead = 0; - this.mask = 0; - this.context = 0; - } -} -const nullToken$3 = new CachedToken$3; -/// [Tokenizers](#lr.ExternalTokenizer) interact with the input -/// through this interface. It presents the input as a stream of -/// characters, tracking lookahead and hiding the complexity of -/// [ranges](#common.Parser.parse^ranges) from tokenizer code. -class InputStream$3 { - /// @internal - constructor( - /// @internal - input, - /// @internal - ranges) { - this.input = input; - this.ranges = ranges; - /// @internal - this.chunk = ""; - /// @internal - this.chunkOff = 0; - /// Backup chunk - this.chunk2 = ""; - this.chunk2Pos = 0; - /// The character code of the next code unit in the input, or -1 - /// when the stream is at the end of the input. - this.next = -1; - /// @internal - this.token = nullToken$3; - this.rangeIndex = 0; - this.pos = this.chunkPos = ranges[0].from; - this.range = ranges[0]; - this.end = ranges[ranges.length - 1].to; - this.readNext(); - } - resolveOffset(offset, assoc) { - let range = this.range, index = this.rangeIndex; - let pos = this.pos + offset; - while (pos < range.from) { - if (!index) - return null; - let next = this.ranges[--index]; - pos -= range.from - next.to; - range = next; - } - while (assoc < 0 ? pos > range.to : pos >= range.to) { - if (index == this.ranges.length - 1) - return null; - let next = this.ranges[++index]; - pos += next.from - range.to; - range = next; - } - return pos; - } - /// Look at a code unit near the stream position. `.peek(0)` equals - /// `.next`, `.peek(-1)` gives you the previous character, and so - /// on. - /// - /// Note that looking around during tokenizing creates dependencies - /// on potentially far-away content, which may reduce the - /// effectiveness incremental parsing—when looking forward—or even - /// cause invalid reparses when looking backward more than 25 code - /// units, since the library does not track lookbehind. - peek(offset) { - let idx = this.chunkOff + offset, pos, result; - if (idx >= 0 && idx < this.chunk.length) { - pos = this.pos + offset; - result = this.chunk.charCodeAt(idx); - } - else { - let resolved = this.resolveOffset(offset, 1); - if (resolved == null) - return -1; - pos = resolved; - if (pos >= this.chunk2Pos && pos < this.chunk2Pos + this.chunk2.length) { - result = this.chunk2.charCodeAt(pos - this.chunk2Pos); - } - else { - let i = this.rangeIndex, range = this.range; - while (range.to <= pos) - range = this.ranges[++i]; - this.chunk2 = this.input.chunk(this.chunk2Pos = pos); - if (pos + this.chunk2.length > range.to) - this.chunk2 = this.chunk2.slice(0, range.to - pos); - result = this.chunk2.charCodeAt(0); - } - } - if (pos >= this.token.lookAhead) - this.token.lookAhead = pos + 1; - return result; - } - /// Accept a token. By default, the end of the token is set to the - /// current stream position, but you can pass an offset (relative to - /// the stream position) to change that. - acceptToken(token, endOffset = 0) { - let end = endOffset ? this.resolveOffset(endOffset, -1) : this.pos; - if (end == null || end < this.token.start) - throw new RangeError("Token end out of bounds"); - this.token.value = token; - this.token.end = end; - } - getChunk() { - if (this.pos >= this.chunk2Pos && this.pos < this.chunk2Pos + this.chunk2.length) { - let { chunk, chunkPos } = this; - this.chunk = this.chunk2; - this.chunkPos = this.chunk2Pos; - this.chunk2 = chunk; - this.chunk2Pos = chunkPos; - this.chunkOff = this.pos - this.chunkPos; - } - else { - this.chunk2 = this.chunk; - this.chunk2Pos = this.chunkPos; - let nextChunk = this.input.chunk(this.pos); - let end = this.pos + nextChunk.length; - this.chunk = end > this.range.to ? nextChunk.slice(0, this.range.to - this.pos) : nextChunk; - this.chunkPos = this.pos; - this.chunkOff = 0; - } - } - readNext() { - if (this.chunkOff >= this.chunk.length) { - this.getChunk(); - if (this.chunkOff == this.chunk.length) - return this.next = -1; - } - return this.next = this.chunk.charCodeAt(this.chunkOff); - } - /// Move the stream forward N (defaults to 1) code units. Returns - /// the new value of [`next`](#lr.InputStream.next). - advance(n = 1) { - this.chunkOff += n; - while (this.pos + n >= this.range.to) { - if (this.rangeIndex == this.ranges.length - 1) - return this.setDone(); - n -= this.range.to - this.pos; - this.range = this.ranges[++this.rangeIndex]; - this.pos = this.range.from; - } - this.pos += n; - if (this.pos >= this.token.lookAhead) - this.token.lookAhead = this.pos + 1; - return this.readNext(); - } - setDone() { - this.pos = this.chunkPos = this.end; - this.range = this.ranges[this.rangeIndex = this.ranges.length - 1]; - this.chunk = ""; - return this.next = -1; - } - /// @internal - reset(pos, token) { - if (token) { - this.token = token; - token.start = pos; - token.lookAhead = pos + 1; - token.value = token.extended = -1; - } - else { - this.token = nullToken$3; - } - if (this.pos != pos) { - this.pos = pos; - if (pos == this.end) { - this.setDone(); - return this; - } - while (pos < this.range.from) - this.range = this.ranges[--this.rangeIndex]; - while (pos >= this.range.to) - this.range = this.ranges[++this.rangeIndex]; - if (pos >= this.chunkPos && pos < this.chunkPos + this.chunk.length) { - this.chunkOff = pos - this.chunkPos; - } - else { - this.chunk = ""; - this.chunkOff = 0; - } - this.readNext(); - } - return this; - } - /// @internal - read(from, to) { - if (from >= this.chunkPos && to <= this.chunkPos + this.chunk.length) - return this.chunk.slice(from - this.chunkPos, to - this.chunkPos); - if (from >= this.chunk2Pos && to <= this.chunk2Pos + this.chunk2.length) - return this.chunk2.slice(from - this.chunk2Pos, to - this.chunk2Pos); - if (from >= this.range.from && to <= this.range.to) - return this.input.read(from, to); - let result = ""; - for (let r of this.ranges) { - if (r.from >= to) - break; - if (r.to > from) - result += this.input.read(Math.max(r.from, from), Math.min(r.to, to)); - } - return result; - } -} -/// @internal -class TokenGroup$3 { - constructor(data, id) { - this.data = data; - this.id = id; - } - token(input, stack) { readToken$3(this.data, input, stack, this.id); } -} -TokenGroup$3.prototype.contextual = TokenGroup$3.prototype.fallback = TokenGroup$3.prototype.extend = false; -/// `@external tokens` declarations in the grammar should resolve to -/// an instance of this class. -class ExternalTokenizer$3 { - /// Create a tokenizer. The first argument is the function that, - /// given an input stream, scans for the types of tokens it - /// recognizes at the stream's position, and calls - /// [`acceptToken`](#lr.InputStream.acceptToken) when it finds - /// one. - constructor( - /// @internal - token, options = {}) { - this.token = token; - this.contextual = !!options.contextual; - this.fallback = !!options.fallback; - this.extend = !!options.extend; - } -} -// Tokenizer data is stored a big uint16 array containing, for each -// state: -// -// - A group bitmask, indicating what token groups are reachable from -// this state, so that paths that can only lead to tokens not in -// any of the current groups can be cut off early. -// -// - The position of the end of the state's sequence of accepting -// tokens -// -// - The number of outgoing edges for the state -// -// - The accepting tokens, as (token id, group mask) pairs -// -// - The outgoing edges, as (start character, end character, state -// index) triples, with end character being exclusive -// -// This function interprets that data, running through a stream as -// long as new states with the a matching group mask can be reached, -// and updating `token` when it matches a token. -function readToken$3(data, input, stack, group) { - let state = 0, groupMask = 1 << group, { parser } = stack.p, { dialect } = parser; - scan: for (;;) { - if ((groupMask & data[state]) == 0) - break; - let accEnd = data[state + 1]; - // Check whether this state can lead to a token in the current group - // Accept tokens in this state, possibly overwriting - // lower-precedence / shorter tokens - for (let i = state + 3; i < accEnd; i += 2) - if ((data[i + 1] & groupMask) > 0) { - let term = data[i]; - if (dialect.allows(term) && - (input.token.value == -1 || input.token.value == term || parser.overrides(term, input.token.value))) { - input.acceptToken(term); - break; - } - } - // Do a binary search on the state's edges - for (let next = input.next, low = 0, high = data[state + 2]; low < high;) { - let mid = (low + high) >> 1; - let index = accEnd + mid + (mid << 1); - let from = data[index], to = data[index + 1]; - if (next < from) - high = mid; - else if (next >= to) - low = mid + 1; - else { - state = data[index + 2]; - input.advance(); - continue scan; - } - } - break; - } -} - -// See lezer-generator/src/encode.ts for comments about the encoding -// used here -function decodeArray$3(input, Type = Uint16Array) { - if (typeof input != "string") - return input; - let array = null; - for (let pos = 0, out = 0; pos < input.length;) { - let value = 0; - for (;;) { - let next = input.charCodeAt(pos++), stop = false; - if (next == 126 /* BigValCode */) { - value = 65535 /* BigVal */; - break; - } - if (next >= 92 /* Gap2 */) - next--; - if (next >= 34 /* Gap1 */) - next--; - let digit = next - 32 /* Start */; - if (digit >= 46 /* Base */) { - digit -= 46 /* Base */; - stop = true; - } - value += digit; - if (stop) - break; - value *= 46 /* Base */; - } - if (array) - array[out++] = value; - else - array = new Type(value); - } - return array; -} - -// Environment variable used to control console output -const verbose$3 = typeof process != "undefined" && process.env && /\bparse\b/.test(process.env.LOG); -let stackIDs$3 = null; -var Safety$3; -(function (Safety) { - Safety[Safety["Margin"] = 25] = "Margin"; -})(Safety$3 || (Safety$3 = {})); -function cutAt$3(tree, pos, side) { - let cursor = tree.cursor(IterMode.IncludeAnonymous); - cursor.moveTo(pos); - for (;;) { - if (!(side < 0 ? cursor.childBefore(pos) : cursor.childAfter(pos))) - for (;;) { - if ((side < 0 ? cursor.to < pos : cursor.from > pos) && !cursor.type.isError) - return side < 0 ? Math.max(0, Math.min(cursor.to - 1, pos - 25 /* Margin */)) - : Math.min(tree.length, Math.max(cursor.from + 1, pos + 25 /* Margin */)); - if (side < 0 ? cursor.prevSibling() : cursor.nextSibling()) - break; - if (!cursor.parent()) - return side < 0 ? 0 : tree.length; - } - } -} -class FragmentCursor$3 { - constructor(fragments, nodeSet) { - this.fragments = fragments; - this.nodeSet = nodeSet; - this.i = 0; - this.fragment = null; - this.safeFrom = -1; - this.safeTo = -1; - this.trees = []; - this.start = []; - this.index = []; - this.nextFragment(); - } - nextFragment() { - let fr = this.fragment = this.i == this.fragments.length ? null : this.fragments[this.i++]; - if (fr) { - this.safeFrom = fr.openStart ? cutAt$3(fr.tree, fr.from + fr.offset, 1) - fr.offset : fr.from; - this.safeTo = fr.openEnd ? cutAt$3(fr.tree, fr.to + fr.offset, -1) - fr.offset : fr.to; - while (this.trees.length) { - this.trees.pop(); - this.start.pop(); - this.index.pop(); - } - this.trees.push(fr.tree); - this.start.push(-fr.offset); - this.index.push(0); - this.nextStart = this.safeFrom; - } - else { - this.nextStart = 1e9; - } - } - // `pos` must be >= any previously given `pos` for this cursor - nodeAt(pos) { - if (pos < this.nextStart) - return null; - while (this.fragment && this.safeTo <= pos) - this.nextFragment(); - if (!this.fragment) - return null; - for (;;) { - let last = this.trees.length - 1; - if (last < 0) { // End of tree - this.nextFragment(); - return null; - } - let top = this.trees[last], index = this.index[last]; - if (index == top.children.length) { - this.trees.pop(); - this.start.pop(); - this.index.pop(); - continue; - } - let next = top.children[index]; - let start = this.start[last] + top.positions[index]; - if (start > pos) { - this.nextStart = start; - return null; - } - if (next instanceof Tree) { - if (start == pos) { - if (start < this.safeFrom) - return null; - let end = start + next.length; - if (end <= this.safeTo) { - let lookAhead = next.prop(NodeProp.lookAhead); - if (!lookAhead || end + lookAhead < this.fragment.to) - return next; - } - } - this.index[last]++; - if (start + next.length >= Math.max(this.safeFrom, pos)) { // Enter this node - this.trees.push(next); - this.start.push(start); - this.index.push(0); - } - } - else { - this.index[last]++; - this.nextStart = start + next.length; - } - } - } -} -class TokenCache$3 { - constructor(parser, stream) { - this.stream = stream; - this.tokens = []; - this.mainToken = null; - this.actions = []; - this.tokens = parser.tokenizers.map(_ => new CachedToken$3); - } - getActions(stack) { - let actionIndex = 0; - let main = null; - let { parser } = stack.p, { tokenizers } = parser; - let mask = parser.stateSlot(stack.state, 3 /* TokenizerMask */); - let context = stack.curContext ? stack.curContext.hash : 0; - let lookAhead = 0; - for (let i = 0; i < tokenizers.length; i++) { - if (((1 << i) & mask) == 0) - continue; - let tokenizer = tokenizers[i], token = this.tokens[i]; - if (main && !tokenizer.fallback) - continue; - if (tokenizer.contextual || token.start != stack.pos || token.mask != mask || token.context != context) { - this.updateCachedToken(token, tokenizer, stack); - token.mask = mask; - token.context = context; - } - if (token.lookAhead > token.end + 25 /* Margin */) - lookAhead = Math.max(token.lookAhead, lookAhead); - if (token.value != 0 /* Err */) { - let startIndex = actionIndex; - if (token.extended > -1) - actionIndex = this.addActions(stack, token.extended, token.end, actionIndex); - actionIndex = this.addActions(stack, token.value, token.end, actionIndex); - if (!tokenizer.extend) { - main = token; - if (actionIndex > startIndex) - break; - } - } - } - while (this.actions.length > actionIndex) - this.actions.pop(); - if (lookAhead) - stack.setLookAhead(lookAhead); - if (!main && stack.pos == this.stream.end) { - main = new CachedToken$3; - main.value = stack.p.parser.eofTerm; - main.start = main.end = stack.pos; - actionIndex = this.addActions(stack, main.value, main.end, actionIndex); - } - this.mainToken = main; - return this.actions; - } - getMainToken(stack) { - if (this.mainToken) - return this.mainToken; - let main = new CachedToken$3, { pos, p } = stack; - main.start = pos; - main.end = Math.min(pos + 1, p.stream.end); - main.value = pos == p.stream.end ? p.parser.eofTerm : 0 /* Err */; - return main; - } - updateCachedToken(token, tokenizer, stack) { - tokenizer.token(this.stream.reset(stack.pos, token), stack); - if (token.value > -1) { - let { parser } = stack.p; - for (let i = 0; i < parser.specialized.length; i++) - if (parser.specialized[i] == token.value) { - let result = parser.specializers[i](this.stream.read(token.start, token.end), stack); - if (result >= 0 && stack.p.parser.dialect.allows(result >> 1)) { - if ((result & 1) == 0 /* Specialize */) - token.value = result >> 1; - else - token.extended = result >> 1; - break; - } - } - } - else { - token.value = 0 /* Err */; - token.end = Math.min(stack.p.stream.end, stack.pos + 1); - } - } - putAction(action, token, end, index) { - // Don't add duplicate actions - for (let i = 0; i < index; i += 3) - if (this.actions[i] == action) - return index; - this.actions[index++] = action; - this.actions[index++] = token; - this.actions[index++] = end; - return index; - } - addActions(stack, token, end, index) { - let { state } = stack, { parser } = stack.p, { data } = parser; - for (let set = 0; set < 2; set++) { - for (let i = parser.stateSlot(state, set ? 2 /* Skip */ : 1 /* Actions */);; i += 3) { - if (data[i] == 65535 /* End */) { - if (data[i + 1] == 1 /* Next */) { - i = pair$3(data, i + 2); - } - else { - if (index == 0 && data[i + 1] == 2 /* Other */) - index = this.putAction(pair$3(data, i + 2), token, end, index); - break; - } - } - if (data[i] == token) - index = this.putAction(pair$3(data, i + 1), token, end, index); - } - } - return index; - } -} -var Rec$3; -(function (Rec) { - Rec[Rec["Distance"] = 5] = "Distance"; - Rec[Rec["MaxRemainingPerStep"] = 3] = "MaxRemainingPerStep"; - // When two stacks have been running independently long enough to - // add this many elements to their buffers, prune one. - Rec[Rec["MinBufferLengthPrune"] = 500] = "MinBufferLengthPrune"; - Rec[Rec["ForceReduceLimit"] = 10] = "ForceReduceLimit"; - // Once a stack reaches this depth (in .stack.length) force-reduce - // it back to CutTo to avoid creating trees that overflow the stack - // on recursive traversal. - Rec[Rec["CutDepth"] = 15000] = "CutDepth"; - Rec[Rec["CutTo"] = 9000] = "CutTo"; -})(Rec$3 || (Rec$3 = {})); -class Parse$3 { - constructor(parser, input, fragments, ranges) { - this.parser = parser; - this.input = input; - this.ranges = ranges; - this.recovering = 0; - this.nextStackID = 0x2654; // ♔, ♕, ♖, ♗, ♘, ♙, ♠, ♡, ♢, ♣, ♤, ♥, ♦, ♧ - this.minStackPos = 0; - this.reused = []; - this.stoppedAt = null; - this.stream = new InputStream$3(input, ranges); - this.tokens = new TokenCache$3(parser, this.stream); - this.topTerm = parser.top[1]; - let { from } = ranges[0]; - this.stacks = [Stack$3.start(this, parser.top[0], from)]; - this.fragments = fragments.length && this.stream.end - from > parser.bufferLength * 4 - ? new FragmentCursor$3(fragments, parser.nodeSet) : null; - } - get parsedPos() { - return this.minStackPos; - } - // Move the parser forward. This will process all parse stacks at - // `this.pos` and try to advance them to a further position. If no - // stack for such a position is found, it'll start error-recovery. - // - // When the parse is finished, this will return a syntax tree. When - // not, it returns `null`. - advance() { - let stacks = this.stacks, pos = this.minStackPos; - // This will hold stacks beyond `pos`. - let newStacks = this.stacks = []; - let stopped, stoppedTokens; - // Keep advancing any stacks at `pos` until they either move - // forward or can't be advanced. Gather stacks that can't be - // advanced further in `stopped`. - for (let i = 0; i < stacks.length; i++) { - let stack = stacks[i]; - for (;;) { - this.tokens.mainToken = null; - if (stack.pos > pos) { - newStacks.push(stack); - } - else if (this.advanceStack(stack, newStacks, stacks)) { - continue; - } - else { - if (!stopped) { - stopped = []; - stoppedTokens = []; - } - stopped.push(stack); - let tok = this.tokens.getMainToken(stack); - stoppedTokens.push(tok.value, tok.end); - } - break; - } - } - if (!newStacks.length) { - let finished = stopped && findFinished$3(stopped); - if (finished) - return this.stackToTree(finished); - if (this.parser.strict) { - if (verbose$3 && stopped) - console.log("Stuck with token " + (this.tokens.mainToken ? this.parser.getName(this.tokens.mainToken.value) : "none")); - throw new SyntaxError("No parse at " + pos); - } - if (!this.recovering) - this.recovering = 5 /* Distance */; - } - if (this.recovering && stopped) { - let finished = this.stoppedAt != null && stopped[0].pos > this.stoppedAt ? stopped[0] - : this.runRecovery(stopped, stoppedTokens, newStacks); - if (finished) - return this.stackToTree(finished.forceAll()); - } - if (this.recovering) { - let maxRemaining = this.recovering == 1 ? 1 : this.recovering * 3 /* MaxRemainingPerStep */; - if (newStacks.length > maxRemaining) { - newStacks.sort((a, b) => b.score - a.score); - while (newStacks.length > maxRemaining) - newStacks.pop(); - } - if (newStacks.some(s => s.reducePos > pos)) - this.recovering--; - } - else if (newStacks.length > 1) { - // Prune stacks that are in the same state, or that have been - // running without splitting for a while, to avoid getting stuck - // with multiple successful stacks running endlessly on. - outer: for (let i = 0; i < newStacks.length - 1; i++) { - let stack = newStacks[i]; - for (let j = i + 1; j < newStacks.length; j++) { - let other = newStacks[j]; - if (stack.sameState(other) || - stack.buffer.length > 500 /* MinBufferLengthPrune */ && other.buffer.length > 500 /* MinBufferLengthPrune */) { - if (((stack.score - other.score) || (stack.buffer.length - other.buffer.length)) > 0) { - newStacks.splice(j--, 1); - } - else { - newStacks.splice(i--, 1); - continue outer; - } - } - } - } - } - this.minStackPos = newStacks[0].pos; - for (let i = 1; i < newStacks.length; i++) - if (newStacks[i].pos < this.minStackPos) - this.minStackPos = newStacks[i].pos; - return null; - } - stopAt(pos) { - if (this.stoppedAt != null && this.stoppedAt < pos) - throw new RangeError("Can't move stoppedAt forward"); - this.stoppedAt = pos; - } - // Returns an updated version of the given stack, or null if the - // stack can't advance normally. When `split` and `stacks` are - // given, stacks split off by ambiguous operations will be pushed to - // `split`, or added to `stacks` if they move `pos` forward. - advanceStack(stack, stacks, split) { - let start = stack.pos, { parser } = this; - let base = verbose$3 ? this.stackID(stack) + " -> " : ""; - if (this.stoppedAt != null && start > this.stoppedAt) - return stack.forceReduce() ? stack : null; - if (this.fragments) { - let strictCx = stack.curContext && stack.curContext.tracker.strict, cxHash = strictCx ? stack.curContext.hash : 0; - for (let cached = this.fragments.nodeAt(start); cached;) { - let match = this.parser.nodeSet.types[cached.type.id] == cached.type ? parser.getGoto(stack.state, cached.type.id) : -1; - if (match > -1 && cached.length && (!strictCx || (cached.prop(NodeProp.contextHash) || 0) == cxHash)) { - stack.useNode(cached, match); - if (verbose$3) - console.log(base + this.stackID(stack) + ` (via reuse of ${parser.getName(cached.type.id)})`); - return true; - } - if (!(cached instanceof Tree) || cached.children.length == 0 || cached.positions[0] > 0) - break; - let inner = cached.children[0]; - if (inner instanceof Tree && cached.positions[0] == 0) - cached = inner; - else - break; - } - } - let defaultReduce = parser.stateSlot(stack.state, 4 /* DefaultReduce */); - if (defaultReduce > 0) { - stack.reduce(defaultReduce); - if (verbose$3) - console.log(base + this.stackID(stack) + ` (via always-reduce ${parser.getName(defaultReduce & 65535 /* ValueMask */)})`); - return true; - } - if (stack.stack.length >= 15000 /* CutDepth */) { - while (stack.stack.length > 9000 /* CutTo */ && stack.forceReduce()) { } - } - let actions = this.tokens.getActions(stack); - for (let i = 0; i < actions.length;) { - let action = actions[i++], term = actions[i++], end = actions[i++]; - let last = i == actions.length || !split; - let localStack = last ? stack : stack.split(); - localStack.apply(action, term, end); - if (verbose$3) - console.log(base + this.stackID(localStack) + ` (via ${(action & 65536 /* ReduceFlag */) == 0 ? "shift" - : `reduce of ${parser.getName(action & 65535 /* ValueMask */)}`} for ${parser.getName(term)} @ ${start}${localStack == stack ? "" : ", split"})`); - if (last) - return true; - else if (localStack.pos > start) - stacks.push(localStack); - else - split.push(localStack); - } - return false; - } - // Advance a given stack forward as far as it will go. Returns the - // (possibly updated) stack if it got stuck, or null if it moved - // forward and was given to `pushStackDedup`. - advanceFully(stack, newStacks) { - let pos = stack.pos; - for (;;) { - if (!this.advanceStack(stack, null, null)) - return false; - if (stack.pos > pos) { - pushStackDedup$3(stack, newStacks); - return true; - } - } - } - runRecovery(stacks, tokens, newStacks) { - let finished = null, restarted = false; - for (let i = 0; i < stacks.length; i++) { - let stack = stacks[i], token = tokens[i << 1], tokenEnd = tokens[(i << 1) + 1]; - let base = verbose$3 ? this.stackID(stack) + " -> " : ""; - if (stack.deadEnd) { - if (restarted) - continue; - restarted = true; - stack.restart(); - if (verbose$3) - console.log(base + this.stackID(stack) + " (restarted)"); - let done = this.advanceFully(stack, newStacks); - if (done) - continue; - } - let force = stack.split(), forceBase = base; - for (let j = 0; force.forceReduce() && j < 10 /* ForceReduceLimit */; j++) { - if (verbose$3) - console.log(forceBase + this.stackID(force) + " (via force-reduce)"); - let done = this.advanceFully(force, newStacks); - if (done) - break; - if (verbose$3) - forceBase = this.stackID(force) + " -> "; - } - for (let insert of stack.recoverByInsert(token)) { - if (verbose$3) - console.log(base + this.stackID(insert) + " (via recover-insert)"); - this.advanceFully(insert, newStacks); - } - if (this.stream.end > stack.pos) { - if (tokenEnd == stack.pos) { - tokenEnd++; - token = 0 /* Err */; - } - stack.recoverByDelete(token, tokenEnd); - if (verbose$3) - console.log(base + this.stackID(stack) + ` (via recover-delete ${this.parser.getName(token)})`); - pushStackDedup$3(stack, newStacks); - } - else if (!finished || finished.score < stack.score) { - finished = stack; - } - } - return finished; - } - // Convert the stack's buffer to a syntax tree. - stackToTree(stack) { - stack.close(); - return Tree.build({ buffer: StackBufferCursor$3.create(stack), - nodeSet: this.parser.nodeSet, - topID: this.topTerm, - maxBufferLength: this.parser.bufferLength, - reused: this.reused, - start: this.ranges[0].from, - length: stack.pos - this.ranges[0].from, - minRepeatType: this.parser.minRepeatTerm }); - } - stackID(stack) { - let id = (stackIDs$3 || (stackIDs$3 = new WeakMap)).get(stack); - if (!id) - stackIDs$3.set(stack, id = String.fromCodePoint(this.nextStackID++)); - return id + stack; - } -} -function pushStackDedup$3(stack, newStacks) { - for (let i = 0; i < newStacks.length; i++) { - let other = newStacks[i]; - if (other.pos == stack.pos && other.sameState(stack)) { - if (newStacks[i].score < stack.score) - newStacks[i] = stack; - return; - } - } - newStacks.push(stack); -} -class Dialect$3 { - constructor(source, flags, disabled) { - this.source = source; - this.flags = flags; - this.disabled = disabled; - } - allows(term) { return !this.disabled || this.disabled[term] == 0; } -} -/// A parser holds the parse tables for a given grammar, as generated -/// by `lezer-generator`. -class LRParser$3 extends Parser { - /// @internal - constructor(spec) { - super(); - /// @internal - this.wrappers = []; - if (spec.version != 14 /* Version */) - throw new RangeError(`Parser version (${spec.version}) doesn't match runtime version (${14 /* Version */})`); - let nodeNames = spec.nodeNames.split(" "); - this.minRepeatTerm = nodeNames.length; - for (let i = 0; i < spec.repeatNodeCount; i++) - nodeNames.push(""); - let topTerms = Object.keys(spec.topRules).map(r => spec.topRules[r][1]); - let nodeProps = []; - for (let i = 0; i < nodeNames.length; i++) - nodeProps.push([]); - function setProp(nodeID, prop, value) { - nodeProps[nodeID].push([prop, prop.deserialize(String(value))]); - } - if (spec.nodeProps) - for (let propSpec of spec.nodeProps) { - let prop = propSpec[0]; - if (typeof prop == "string") - prop = NodeProp[prop]; - for (let i = 1; i < propSpec.length;) { - let next = propSpec[i++]; - if (next >= 0) { - setProp(next, prop, propSpec[i++]); - } - else { - let value = propSpec[i + -next]; - for (let j = -next; j > 0; j--) - setProp(propSpec[i++], prop, value); - i++; - } - } - } - this.nodeSet = new NodeSet(nodeNames.map((name, i) => NodeType.define({ - name: i >= this.minRepeatTerm ? undefined : name, - id: i, - props: nodeProps[i], - top: topTerms.indexOf(i) > -1, - error: i == 0, - skipped: spec.skippedNodes && spec.skippedNodes.indexOf(i) > -1 - }))); - if (spec.propSources) - this.nodeSet = this.nodeSet.extend(...spec.propSources); - this.strict = false; - this.bufferLength = DefaultBufferLength; - let tokenArray = decodeArray$3(spec.tokenData); - this.context = spec.context; - this.specialized = new Uint16Array(spec.specialized ? spec.specialized.length : 0); - this.specializers = []; - if (spec.specialized) - for (let i = 0; i < spec.specialized.length; i++) { - this.specialized[i] = spec.specialized[i].term; - this.specializers[i] = spec.specialized[i].get; - } - this.states = decodeArray$3(spec.states, Uint32Array); - this.data = decodeArray$3(spec.stateData); - this.goto = decodeArray$3(spec.goto); - this.maxTerm = spec.maxTerm; - this.tokenizers = spec.tokenizers.map(value => typeof value == "number" ? new TokenGroup$3(tokenArray, value) : value); - this.topRules = spec.topRules; - this.dialects = spec.dialects || {}; - this.dynamicPrecedences = spec.dynamicPrecedences || null; - this.tokenPrecTable = spec.tokenPrec; - this.termNames = spec.termNames || null; - this.maxNode = this.nodeSet.types.length - 1; - this.dialect = this.parseDialect(); - this.top = this.topRules[Object.keys(this.topRules)[0]]; - } - createParse(input, fragments, ranges) { - let parse = new Parse$3(this, input, fragments, ranges); - for (let w of this.wrappers) - parse = w(parse, input, fragments, ranges); - return parse; - } - /// Get a goto table entry @internal - getGoto(state, term, loose = false) { - let table = this.goto; - if (term >= table[0]) - return -1; - for (let pos = table[term + 1];;) { - let groupTag = table[pos++], last = groupTag & 1; - let target = table[pos++]; - if (last && loose) - return target; - for (let end = pos + (groupTag >> 1); pos < end; pos++) - if (table[pos] == state) - return target; - if (last) - return -1; - } - } - /// Check if this state has an action for a given terminal @internal - hasAction(state, terminal) { - let data = this.data; - for (let set = 0; set < 2; set++) { - for (let i = this.stateSlot(state, set ? 2 /* Skip */ : 1 /* Actions */), next;; i += 3) { - if ((next = data[i]) == 65535 /* End */) { - if (data[i + 1] == 1 /* Next */) - next = data[i = pair$3(data, i + 2)]; - else if (data[i + 1] == 2 /* Other */) - return pair$3(data, i + 2); - else - break; - } - if (next == terminal || next == 0 /* Err */) - return pair$3(data, i + 1); - } - } - return 0; - } - /// @internal - stateSlot(state, slot) { - return this.states[(state * 6 /* Size */) + slot]; - } - /// @internal - stateFlag(state, flag) { - return (this.stateSlot(state, 0 /* Flags */) & flag) > 0; - } - /// @internal - validAction(state, action) { - if (action == this.stateSlot(state, 4 /* DefaultReduce */)) - return true; - for (let i = this.stateSlot(state, 1 /* Actions */);; i += 3) { - if (this.data[i] == 65535 /* End */) { - if (this.data[i + 1] == 1 /* Next */) - i = pair$3(this.data, i + 2); - else - return false; - } - if (action == pair$3(this.data, i + 1)) - return true; - } - } - /// Get the states that can follow this one through shift actions or - /// goto jumps. @internal - nextStates(state) { - let result = []; - for (let i = this.stateSlot(state, 1 /* Actions */);; i += 3) { - if (this.data[i] == 65535 /* End */) { - if (this.data[i + 1] == 1 /* Next */) - i = pair$3(this.data, i + 2); - else - break; - } - if ((this.data[i + 2] & (65536 /* ReduceFlag */ >> 16)) == 0) { - let value = this.data[i + 1]; - if (!result.some((v, i) => (i & 1) && v == value)) - result.push(this.data[i], value); - } - } - return result; - } - /// @internal - overrides(token, prev) { - let iPrev = findOffset$3(this.data, this.tokenPrecTable, prev); - return iPrev < 0 || findOffset$3(this.data, this.tokenPrecTable, token) < iPrev; - } - /// Configure the parser. Returns a new parser instance that has the - /// given settings modified. Settings not provided in `config` are - /// kept from the original parser. - configure(config) { - // Hideous reflection-based kludge to make it easy to create a - // slightly modified copy of a parser. - let copy = Object.assign(Object.create(LRParser$3.prototype), this); - if (config.props) - copy.nodeSet = this.nodeSet.extend(...config.props); - if (config.top) { - let info = this.topRules[config.top]; - if (!info) - throw new RangeError(`Invalid top rule name ${config.top}`); - copy.top = info; - } - if (config.tokenizers) - copy.tokenizers = this.tokenizers.map(t => { - let found = config.tokenizers.find(r => r.from == t); - return found ? found.to : t; - }); - if (config.contextTracker) - copy.context = config.contextTracker; - if (config.dialect) - copy.dialect = this.parseDialect(config.dialect); - if (config.strict != null) - copy.strict = config.strict; - if (config.wrap) - copy.wrappers = copy.wrappers.concat(config.wrap); - if (config.bufferLength != null) - copy.bufferLength = config.bufferLength; - return copy; - } - /// Tells you whether any [parse wrappers](#lr.ParserConfig.wrap) - /// are registered for this parser. - hasWrappers() { - return this.wrappers.length > 0; - } - /// Returns the name associated with a given term. This will only - /// work for all terms when the parser was generated with the - /// `--names` option. By default, only the names of tagged terms are - /// stored. - getName(term) { - return this.termNames ? this.termNames[term] : String(term <= this.maxNode && this.nodeSet.types[term].name || term); - } - /// The eof term id is always allocated directly after the node - /// types. @internal - get eofTerm() { return this.maxNode + 1; } - /// The type of top node produced by the parser. - get topNode() { return this.nodeSet.types[this.top[1]]; } - /// @internal - dynamicPrecedence(term) { - let prec = this.dynamicPrecedences; - return prec == null ? 0 : prec[term] || 0; - } - /// @internal - parseDialect(dialect) { - let values = Object.keys(this.dialects), flags = values.map(() => false); - if (dialect) - for (let part of dialect.split(" ")) { - let id = values.indexOf(part); - if (id >= 0) - flags[id] = true; - } - let disabled = null; - for (let i = 0; i < values.length; i++) - if (!flags[i]) { - for (let j = this.dialects[values[i]], id; (id = this.data[j++]) != 65535 /* End */;) - (disabled || (disabled = new Uint8Array(this.maxTerm + 1)))[id] = 1; - } - return new Dialect$3(dialect, flags, disabled); - } - /// (used by the output of the parser generator) @internal - static deserialize(spec) { - return new LRParser$3(spec); - } -} -function pair$3(data, off) { return data[off] | (data[off + 1] << 16); } -function findOffset$3(data, start, term) { - for (let i = start, next; (next = data[i]) != 65535 /* End */; i++) - if (next == term) - return i - start; - return -1; -} -function findFinished$3(stacks) { - let best = null; - for (let stack of stacks) { - let stopped = stack.p.stoppedAt; - if ((stack.pos == stack.p.stream.end || stopped != null && stack.pos > stopped) && - stack.p.parser.stateFlag(stack.state, 2 /* Accepting */) && - (!best || best.score < stack.score)) - best = stack; - } - return best; -} - -// This file was generated by lezer-generator. You probably shouldn't edit it. -const descendantOp = 93, - Unit = 1, - callee = 94, - identifier$2 = 95, - VariableName = 2; - -/* Hand-written tokenizers for CSS tokens that can't be - expressed by Lezer's built-in tokenizer. */ - -const space$2 = [9, 10, 11, 12, 13, 32, 133, 160, 5760, 8192, 8193, 8194, 8195, 8196, 8197, - 8198, 8199, 8200, 8201, 8202, 8232, 8233, 8239, 8287, 12288]; -const colon = 58, parenL = 40, underscore = 95, bracketL = 91, dash = 45, period = 46, - hash$1 = 35, percent = 37; - -function isAlpha$1(ch) { return ch >= 65 && ch <= 90 || ch >= 97 && ch <= 122 || ch >= 161 } - -function isDigit(ch) { return ch >= 48 && ch <= 57 } - -const identifiers = new ExternalTokenizer$3((input, stack) => { - for (let inside = false, dashes = 0, i = 0;; i++) { - let {next} = input; - if (isAlpha$1(next) || next == dash || next == underscore || (inside && isDigit(next))) { - if (!inside && (next != dash || i > 0)) inside = true; - if (dashes === i && next == dash) dashes++; - input.advance(); - } else { - if (inside) - input.acceptToken(next == parenL ? callee : dashes == 2 && stack.canShift(VariableName) ? VariableName : identifier$2); - break - } - } -}); - -const descendant = new ExternalTokenizer$3(input => { - if (space$2.includes(input.peek(-1))) { - let {next} = input; - if (isAlpha$1(next) || next == underscore || next == hash$1 || next == period || - next == bracketL || next == colon || next == dash) - input.acceptToken(descendantOp); - } -}); - -const unitToken = new ExternalTokenizer$3(input => { - if (!space$2.includes(input.peek(-1))) { - let {next} = input; - if (next == percent) { input.advance(); input.acceptToken(Unit); } - if (isAlpha$1(next)) { - do { input.advance(); } while (isAlpha$1(input.next)) - input.acceptToken(Unit); - } - } -}); - -const cssHighlighting = styleTags({ - "import charset namespace keyframes": tags$1.definitionKeyword, - "media supports": tags$1.controlKeyword, - "from to selector": tags$1.keyword, - NamespaceName: tags$1.namespace, - KeyframeName: tags$1.labelName, - TagName: tags$1.tagName, - ClassName: tags$1.className, - PseudoClassName: tags$1.constant(tags$1.className), - IdName: tags$1.labelName, - "FeatureName PropertyName": tags$1.propertyName, - AttributeName: tags$1.attributeName, - NumberLiteral: tags$1.number, - KeywordQuery: tags$1.keyword, - UnaryQueryOp: tags$1.operatorKeyword, - "CallTag ValueName": tags$1.atom, - VariableName: tags$1.variableName, - Callee: tags$1.operatorKeyword, - Unit: tags$1.unit, - "UniversalSelector NestingSelector": tags$1.definitionOperator, - AtKeyword: tags$1.keyword, - MatchOp: tags$1.compareOperator, - "ChildOp SiblingOp, LogicOp": tags$1.logicOperator, - BinOp: tags$1.arithmeticOperator, - Important: tags$1.modifier, - Comment: tags$1.blockComment, - ParenthesizedContent: tags$1.special(tags$1.name), - ColorLiteral: tags$1.color, - StringLiteral: tags$1.string, - ":": tags$1.punctuation, - "PseudoOp #": tags$1.derefOperator, - "; ,": tags$1.separator, - "( )": tags$1.paren, - "[ ]": tags$1.squareBracket, - "{ }": tags$1.brace -}); - -// This file was generated by lezer-generator. You probably shouldn't edit it. -const spec_callee = {__proto__:null,lang:32, "nth-child":32, "nth-last-child":32, "nth-of-type":32, dir:32, url:60, "url-prefix":60, domain:60, regexp:60, selector:134}; -const spec_AtKeyword = {__proto__:null,"@import":114, "@media":138, "@charset":142, "@namespace":146, "@keyframes":152, "@supports":164}; -const spec_identifier$2 = {__proto__:null,not:128, only:128, from:158, to:160}; -const parser$4 = LRParser$3.deserialize({ - version: 14, - states: "7WOYQ[OOOOQP'#Cd'#CdOOQP'#Cc'#CcO!ZQ[O'#CfO!}QXO'#CaO#UQ[O'#ChO#aQ[O'#DPO#fQ[O'#DTOOQP'#Ec'#EcO#kQdO'#DeO$VQ[O'#DrO#kQdO'#DtO$hQ[O'#DvO$sQ[O'#DyO$xQ[O'#EPO%WQ[O'#EROOQS'#Eb'#EbOOQS'#ES'#ESQYQ[OOOOQP'#Cg'#CgOOQP,59Q,59QO!ZQ[O,59QO%_Q[O'#EVO%yQWO,58{O&RQ[O,59SO#aQ[O,59kO#fQ[O,59oO%_Q[O,59sO%_Q[O,59uO%_Q[O,59vO'bQ[O'#D`OOQS,58{,58{OOQP'#Ck'#CkOOQO'#C}'#C}OOQP,59S,59SO'iQWO,59SO'nQWO,59SOOQP'#DR'#DROOQP,59k,59kOOQO'#DV'#DVO'sQ`O,59oOOQS'#Cp'#CpO#kQdO'#CqO'{QvO'#CsO)VQtO,5:POOQO'#Cx'#CxO'iQWO'#CwO)kQWO'#CyOOQS'#Ef'#EfOOQO'#Dh'#DhO)pQ[O'#DoO*OQWO'#EiO$xQ[O'#DmO*^QWO'#DpOOQO'#Ej'#EjO%|QWO,5:^O*cQpO,5:`OOQS'#Dx'#DxO*kQWO,5:bO*pQ[O,5:bOOQO'#D{'#D{O*xQWO,5:eO*}QWO,5:kO+VQWO,5:mOOQS-E8Q-E8QOOQP1G.l1G.lO+yQXO,5:qOOQO-E8T-E8TOOQS1G.g1G.gOOQP1G.n1G.nO'iQWO1G.nO'nQWO1G.nOOQP1G/V1G/VO,WQ`O1G/ZO,qQXO1G/_O-XQXO1G/aO-oQXO1G/bO.VQXO'#CdO.zQWO'#DaOOQS,59z,59zO/PQWO,59zO/XQ[O,59zO/`QdO'#CoO/gQ[O'#DOOOQP1G/Z1G/ZO#kQdO1G/ZO/nQpO,59]OOQS,59_,59_O#kQdO,59aO/vQWO1G/kOOQS,59c,59cO/{Q!bO,59eO0TQWO'#DhO0`QWO,5:TO0eQWO,5:ZO$xQ[O,5:VO$xQ[O'#EYO0mQWO,5;TO0xQWO,5:XO%_Q[O,5:[OOQS1G/x1G/xOOQS1G/z1G/zOOQS1G/|1G/|O1ZQWO1G/|O1`QdO'#D|OOQS1G0P1G0POOQS1G0V1G0VOOQS1G0X1G0XOOQP7+$Y7+$YOOQP7+$u7+$uO#kQdO7+$uO#kQdO,59{O1nQ[O'#EXO1xQWO1G/fOOQS1G/f1G/fO1xQWO1G/fO2QQtO'#ETO2uQdO'#EeO3PQWO,59ZO3UQXO'#EhO3]QWO,59jO3bQpO7+$uOOQS1G.w1G.wOOQS1G.{1G.{OOQS7+%V7+%VO3jQWO1G/PO#kQdO1G/oOOQO1G/u1G/uOOQO1G/q1G/qO3oQWO,5:tOOQO-E8W-E8WO3}QXO1G/vOOQS7+%h7+%hO4UQYO'#CsO%|QWO'#EZO4^QdO,5:hOOQS,5:h,5:hO4lQpO<O!c!}$w!}#O?[#O#P$w#P#Q?g#Q#R2U#R#T$w#T#U?r#U#c$w#c#d@q#d#o$w#o#pAQ#p#q2U#q#rA]#r#sAh#s#y$w#y#z%]#z$f$w$f$g%]$g#BY$w#BY#BZ%]#BZ$IS$w$IS$I_%]$I_$I|$w$I|$JO%]$JO$JT$w$JT$JU%]$JU$KV$w$KV$KW%]$KW&FU$w&FU&FV%]&FV~$wW$zQOy%Qz~%QW%VQoWOy%Qz~%Q~%bf#T~OX%QX^&v^p%Qpq&vqy%Qz#y%Q#y#z&v#z$f%Q$f$g&v$g#BY%Q#BY#BZ&v#BZ$IS%Q$IS$I_&v$I_$I|%Q$I|$JO&v$JO$JT%Q$JT$JU&v$JU$KV%Q$KV$KW&v$KW&FU%Q&FU&FV&v&FV~%Q~&}f#T~oWOX%QX^&v^p%Qpq&vqy%Qz#y%Q#y#z&v#z$f%Q$f$g&v$g#BY%Q#BY#BZ&v#BZ$IS%Q$IS$I_&v$I_$I|%Q$I|$JO&v$JO$JT%Q$JT$JU&v$JU$KV%Q$KV$KW&v$KW&FU%Q&FU&FV&v&FV~%Q^(fSOy%Qz#]%Q#]#^(r#^~%Q^(wSoWOy%Qz#a%Q#a#b)T#b~%Q^)YSoWOy%Qz#d%Q#d#e)f#e~%Q^)kSoWOy%Qz#c%Q#c#d)w#d~%Q^)|SoWOy%Qz#f%Q#f#g*Y#g~%Q^*_SoWOy%Qz#h%Q#h#i*k#i~%Q^*pSoWOy%Qz#T%Q#T#U*|#U~%Q^+RSoWOy%Qz#b%Q#b#c+_#c~%Q^+dSoWOy%Qz#h%Q#h#i+p#i~%Q^+wQ!VUoWOy%Qz~%Q~,QUOY+}Zr+}rs,ds#O+}#O#P,i#P~+}~,iOh~~,lPO~+}_,tWtPOy%Qz!Q%Q!Q![-^![!c%Q!c!i-^!i#T%Q#T#Z-^#Z~%Q^-cWoWOy%Qz!Q%Q!Q![-{![!c%Q!c!i-{!i#T%Q#T#Z-{#Z~%Q^.QWoWOy%Qz!Q%Q!Q![.j![!c%Q!c!i.j!i#T%Q#T#Z.j#Z~%Q^.qWfUoWOy%Qz!Q%Q!Q![/Z![!c%Q!c!i/Z!i#T%Q#T#Z/Z#Z~%Q^/bWfUoWOy%Qz!Q%Q!Q![/z![!c%Q!c!i/z!i#T%Q#T#Z/z#Z~%Q^0PWoWOy%Qz!Q%Q!Q![0i![!c%Q!c!i0i!i#T%Q#T#Z0i#Z~%Q^0pWfUoWOy%Qz!Q%Q!Q![1Y![!c%Q!c!i1Y!i#T%Q#T#Z1Y#Z~%Q^1_WoWOy%Qz!Q%Q!Q![1w![!c%Q!c!i1w!i#T%Q#T#Z1w#Z~%Q^2OQfUoWOy%Qz~%QY2XSOy%Qz!_%Q!_!`2e!`~%QY2lQzQoWOy%Qz~%QX2wQXPOy%Qz~%Q~3QUOY2}Zw2}wx,dx#O2}#O#P3d#P~2}~3gPO~2}_3oQbVOy%Qz~%Q~3zOa~_4RSUPjSOy%Qz!_%Q!_!`2e!`~%Q_4fUjS!PPOy%Qz!O%Q!O!P4x!P!Q%Q!Q![7_![~%Q^4}SoWOy%Qz!Q%Q!Q![5Z![~%Q^5bWoW#ZUOy%Qz!Q%Q!Q![5Z![!g%Q!g!h5z!h#X%Q#X#Y5z#Y~%Q^6PWoWOy%Qz{%Q{|6i|}%Q}!O6i!O!Q%Q!Q![6z![~%Q^6nSoWOy%Qz!Q%Q!Q![6z![~%Q^7RSoW#ZUOy%Qz!Q%Q!Q![6z![~%Q^7fYoW#ZUOy%Qz!O%Q!O!P5Z!P!Q%Q!Q![7_![!g%Q!g!h5z!h#X%Q#X#Y5z#Y~%Q_8ZQpVOy%Qz~%Q^8fUjSOy%Qz!O%Q!O!P4x!P!Q%Q!Q![7_![~%Q_8}S#WPOy%Qz!Q%Q!Q![5Z![~%Q~9`RjSOy%Qz{9i{~%Q~9nSoWOy9iyz9zz{:o{~9i~9}ROz9zz{:W{~9z~:ZTOz9zz{:W{!P9z!P!Q:j!Q~9z~:oOR~~:tUoWOy9iyz9zz{:o{!P9i!P!Q;W!Q~9i~;_QoWR~Oy%Qz~%Q^;jY#ZUOy%Qz!O%Q!O!P5Z!P!Q%Q!Q![7_![!g%Q!g!h5z!h#X%Q#X#Y5z#Y~%QX<_S]POy%Qz![%Q![!]RUOy%Qz!c%Q!c!}>e!}#T%Q#T#o>e#o~%QX>lY!YPoWOy%Qz}%Q}!O>e!O!Q%Q!Q![>e![!c%Q!c!}>e!}#T%Q#T#o>e#o~%QX?aQxPOy%Qz~%Q^?lQvUOy%Qz~%QX?uSOy%Qz#b%Q#b#c@R#c~%QX@WSoWOy%Qz#W%Q#W#X@d#X~%QX@kQ!`PoWOy%Qz~%QX@tSOy%Qz#f%Q#f#g@d#g~%QXAVQ!RPOy%Qz~%Q_AbQ!QVOy%Qz~%QZAmS!PPOy%Qz!_%Q!_!`2e!`~%Q", - tokenizers: [descendant, unitToken, identifiers, 0, 1, 2, 3], - topRules: {"StyleSheet":[0,4]}, - specialized: [{term: 94, get: value => spec_callee[value] || -1},{term: 56, get: value => spec_AtKeyword[value] || -1},{term: 95, get: value => spec_identifier$2[value] || -1}], - tokenPrec: 1078 -}); - -let _properties = null; -function properties() { - if (!_properties && typeof document == "object" && document.body) { - let names = []; - for (let prop in document.body.style) { - if (!/[A-Z]|^-|^(item|length)$/.test(prop)) - names.push(prop); - } - _properties = names.sort().map(name => ({ type: "property", label: name })); - } - return _properties || []; -} -const pseudoClasses = /*@__PURE__*/[ - "active", "after", "before", "checked", "default", - "disabled", "empty", "enabled", "first-child", "first-letter", - "first-line", "first-of-type", "focus", "hover", "in-range", - "indeterminate", "invalid", "lang", "last-child", "last-of-type", - "link", "not", "nth-child", "nth-last-child", "nth-last-of-type", - "nth-of-type", "only-of-type", "only-child", "optional", "out-of-range", - "placeholder", "read-only", "read-write", "required", "root", - "selection", "target", "valid", "visited" -].map(name => ({ type: "class", label: name })); -const values = /*@__PURE__*/[ - "above", "absolute", "activeborder", "additive", "activecaption", "after-white-space", - "ahead", "alias", "all", "all-scroll", "alphabetic", "alternate", "always", - "antialiased", "appworkspace", "asterisks", "attr", "auto", "auto-flow", "avoid", "avoid-column", - "avoid-page", "avoid-region", "axis-pan", "background", "backwards", "baseline", "below", - "bidi-override", "blink", "block", "block-axis", "bold", "bolder", "border", "border-box", - "both", "bottom", "break", "break-all", "break-word", "bullets", "button", "button-bevel", - "buttonface", "buttonhighlight", "buttonshadow", "buttontext", "calc", "capitalize", - "caps-lock-indicator", "caption", "captiontext", "caret", "cell", "center", "checkbox", "circle", - "cjk-decimal", "clear", "clip", "close-quote", "col-resize", "collapse", "color", "color-burn", - "color-dodge", "column", "column-reverse", "compact", "condensed", "contain", "content", - "contents", "content-box", "context-menu", "continuous", "copy", "counter", "counters", "cover", - "crop", "cross", "crosshair", "currentcolor", "cursive", "cyclic", "darken", "dashed", "decimal", - "decimal-leading-zero", "default", "default-button", "dense", "destination-atop", "destination-in", - "destination-out", "destination-over", "difference", "disc", "discard", "disclosure-closed", - "disclosure-open", "document", "dot-dash", "dot-dot-dash", "dotted", "double", "down", "e-resize", - "ease", "ease-in", "ease-in-out", "ease-out", "element", "ellipse", "ellipsis", "embed", "end", - "ethiopic-abegede-gez", "ethiopic-halehame-aa-er", "ethiopic-halehame-gez", "ew-resize", "exclusion", - "expanded", "extends", "extra-condensed", "extra-expanded", "fantasy", "fast", "fill", "fill-box", - "fixed", "flat", "flex", "flex-end", "flex-start", "footnotes", "forwards", "from", - "geometricPrecision", "graytext", "grid", "groove", "hand", "hard-light", "help", "hidden", "hide", - "higher", "highlight", "highlighttext", "horizontal", "hsl", "hsla", "hue", "icon", "ignore", - "inactiveborder", "inactivecaption", "inactivecaptiontext", "infinite", "infobackground", "infotext", - "inherit", "initial", "inline", "inline-axis", "inline-block", "inline-flex", "inline-grid", - "inline-table", "inset", "inside", "intrinsic", "invert", "italic", "justify", "keep-all", - "landscape", "large", "larger", "left", "level", "lighter", "lighten", "line-through", "linear", - "linear-gradient", "lines", "list-item", "listbox", "listitem", "local", "logical", "loud", "lower", - "lower-hexadecimal", "lower-latin", "lower-norwegian", "lowercase", "ltr", "luminosity", "manipulation", - "match", "matrix", "matrix3d", "medium", "menu", "menutext", "message-box", "middle", "min-intrinsic", - "mix", "monospace", "move", "multiple", "multiple_mask_images", "multiply", "n-resize", "narrower", - "ne-resize", "nesw-resize", "no-close-quote", "no-drop", "no-open-quote", "no-repeat", "none", - "normal", "not-allowed", "nowrap", "ns-resize", "numbers", "numeric", "nw-resize", "nwse-resize", - "oblique", "opacity", "open-quote", "optimizeLegibility", "optimizeSpeed", "outset", "outside", - "outside-shape", "overlay", "overline", "padding", "padding-box", "painted", "page", "paused", - "perspective", "pinch-zoom", "plus-darker", "plus-lighter", "pointer", "polygon", "portrait", - "pre", "pre-line", "pre-wrap", "preserve-3d", "progress", "push-button", "radial-gradient", "radio", - "read-only", "read-write", "read-write-plaintext-only", "rectangle", "region", "relative", "repeat", - "repeating-linear-gradient", "repeating-radial-gradient", "repeat-x", "repeat-y", "reset", "reverse", - "rgb", "rgba", "ridge", "right", "rotate", "rotate3d", "rotateX", "rotateY", "rotateZ", "round", - "row", "row-resize", "row-reverse", "rtl", "run-in", "running", "s-resize", "sans-serif", "saturation", - "scale", "scale3d", "scaleX", "scaleY", "scaleZ", "screen", "scroll", "scrollbar", "scroll-position", - "se-resize", "self-start", "self-end", "semi-condensed", "semi-expanded", "separate", "serif", "show", - "single", "skew", "skewX", "skewY", "skip-white-space", "slide", "slider-horizontal", - "slider-vertical", "sliderthumb-horizontal", "sliderthumb-vertical", "slow", "small", "small-caps", - "small-caption", "smaller", "soft-light", "solid", "source-atop", "source-in", "source-out", - "source-over", "space", "space-around", "space-between", "space-evenly", "spell-out", "square", "start", - "static", "status-bar", "stretch", "stroke", "stroke-box", "sub", "subpixel-antialiased", "svg_masks", - "super", "sw-resize", "symbolic", "symbols", "system-ui", "table", "table-caption", "table-cell", - "table-column", "table-column-group", "table-footer-group", "table-header-group", "table-row", - "table-row-group", "text", "text-bottom", "text-top", "textarea", "textfield", "thick", "thin", - "threeddarkshadow", "threedface", "threedhighlight", "threedlightshadow", "threedshadow", "to", "top", - "transform", "translate", "translate3d", "translateX", "translateY", "translateZ", "transparent", - "ultra-condensed", "ultra-expanded", "underline", "unidirectional-pan", "unset", "up", "upper-latin", - "uppercase", "url", "var", "vertical", "vertical-text", "view-box", "visible", "visibleFill", - "visiblePainted", "visibleStroke", "visual", "w-resize", "wait", "wave", "wider", "window", "windowframe", - "windowtext", "words", "wrap", "wrap-reverse", "x-large", "x-small", "xor", "xx-large", "xx-small" -].map(name => ({ type: "keyword", label: name })).concat(/*@__PURE__*/[ - "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", - "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", - "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue", - "cornsilk", "crimson", "cyan", "darkblue", "darkcyan", "darkgoldenrod", - "darkgray", "darkgreen", "darkkhaki", "darkmagenta", "darkolivegreen", - "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", - "darkslateblue", "darkslategray", "darkturquoise", "darkviolet", - "deeppink", "deepskyblue", "dimgray", "dodgerblue", "firebrick", - "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", - "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew", - "hotpink", "indianred", "indigo", "ivory", "khaki", "lavender", - "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", - "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightpink", - "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", - "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta", - "maroon", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", - "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise", - "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin", - "navajowhite", "navy", "oldlace", "olive", "olivedrab", "orange", "orangered", - "orchid", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred", - "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", - "purple", "rebeccapurple", "red", "rosybrown", "royalblue", "saddlebrown", - "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", - "slateblue", "slategray", "snow", "springgreen", "steelblue", "tan", - "teal", "thistle", "tomato", "turquoise", "violet", "wheat", "white", - "whitesmoke", "yellow", "yellowgreen" -].map(name => ({ type: "constant", label: name }))); -const tags = /*@__PURE__*/[ - "a", "abbr", "address", "article", "aside", "b", "bdi", "bdo", "blockquote", "body", - "br", "button", "canvas", "caption", "cite", "code", "col", "colgroup", "dd", "del", - "details", "dfn", "dialog", "div", "dl", "dt", "em", "figcaption", "figure", "footer", - "form", "header", "hgroup", "h1", "h2", "h3", "h4", "h5", "h6", "hr", "html", "i", "iframe", - "img", "input", "ins", "kbd", "label", "legend", "li", "main", "meter", "nav", "ol", "output", - "p", "pre", "ruby", "section", "select", "small", "source", "span", "strong", "sub", "summary", - "sup", "table", "tbody", "td", "template", "textarea", "tfoot", "th", "thead", "tr", "u", "ul" -].map(name => ({ type: "type", label: name })); -const identifier$1 = /^[\w-]*/; -/** -CSS property and value keyword completion source. -*/ -const cssCompletionSource = context => { - let { state, pos } = context, node = syntaxTree(state).resolveInner(pos, -1); - if (node.name == "PropertyName") - return { from: node.from, options: properties(), validFor: identifier$1 }; - if (node.name == "ValueName") - return { from: node.from, options: values, validFor: identifier$1 }; - if (node.name == "PseudoClassName") - return { from: node.from, options: pseudoClasses, validFor: identifier$1 }; - if (node.name == "TagName") { - for (let { parent } = node; parent; parent = parent.parent) - if (parent.name == "Block") - return { from: node.from, options: properties(), validFor: identifier$1 }; - return { from: node.from, options: tags, validFor: identifier$1 }; - } - if (!context.explicit) - return null; - let above = node.resolve(pos), before = above.childBefore(pos); - if (before && before.name == ":" && above.name == "PseudoClassSelector") - return { from: pos, options: pseudoClasses, validFor: identifier$1 }; - if (before && before.name == ":" && above.name == "Declaration" || above.name == "ArgList") - return { from: pos, options: values, validFor: identifier$1 }; - if (above.name == "Block") - return { from: pos, options: properties(), validFor: identifier$1 }; - return null; -}; - -/** -A language provider based on the [Lezer CSS -parser](https://github.com/lezer-parser/css), extended with -highlighting and indentation information. -*/ -const cssLanguage = /*@__PURE__*/LRLanguage.define({ - parser: /*@__PURE__*/parser$4.configure({ - props: [ - /*@__PURE__*/indentNodeProp.add({ - Declaration: /*@__PURE__*/continuedIndent() - }), - /*@__PURE__*/foldNodeProp.add({ - Block: foldInside - }) - ] - }), - languageData: { - commentTokens: { block: { open: "/*", close: "*/" } }, - indentOnInput: /^\s*\}$/, - wordChars: "-" - } -}); -/** -Language support for CSS. -*/ -function css() { - return new LanguageSupport(cssLanguage, cssLanguage.data.of({ autocomplete: cssCompletionSource })); -} - -/// A parse stack. These are used internally by the parser to track -/// parsing progress. They also provide some properties and methods -/// that external code such as a tokenizer can use to get information -/// about the parse state. -class Stack$2 { - /// @internal - constructor( - /// The parse that this stack is part of @internal - p, - /// Holds state, input pos, buffer index triplets for all but the - /// top state @internal - stack, - /// The current parse state @internal - state, - // The position at which the next reduce should take place. This - // can be less than `this.pos` when skipped expressions have been - // added to the stack (which should be moved outside of the next - // reduction) - /// @internal - reducePos, - /// The input position up to which this stack has parsed. - pos, - /// The dynamic score of the stack, including dynamic precedence - /// and error-recovery penalties - /// @internal - score, - // The output buffer. Holds (type, start, end, size) quads - // representing nodes created by the parser, where `size` is - // amount of buffer array entries covered by this node. - /// @internal - buffer, - // The base offset of the buffer. When stacks are split, the split - // instance shared the buffer history with its parent up to - // `bufferBase`, which is the absolute offset (including the - // offset of previous splits) into the buffer at which this stack - // starts writing. - /// @internal - bufferBase, - /// @internal - curContext, - /// @internal - lookAhead = 0, - // A parent stack from which this was split off, if any. This is - // set up so that it always points to a stack that has some - // additional buffer content, never to a stack with an equal - // `bufferBase`. - /// @internal - parent) { - this.p = p; - this.stack = stack; - this.state = state; - this.reducePos = reducePos; - this.pos = pos; - this.score = score; - this.buffer = buffer; - this.bufferBase = bufferBase; - this.curContext = curContext; - this.lookAhead = lookAhead; - this.parent = parent; - } - /// @internal - toString() { - return `[${this.stack.filter((_, i) => i % 3 == 0).concat(this.state)}]@${this.pos}${this.score ? "!" + this.score : ""}`; - } - // Start an empty stack - /// @internal - static start(p, state, pos = 0) { - let cx = p.parser.context; - return new Stack$2(p, [], state, pos, pos, 0, [], 0, cx ? new StackContext$2(cx, cx.start) : null, 0, null); - } - /// The stack's current [context](#lr.ContextTracker) value, if - /// any. Its type will depend on the context tracker's type - /// parameter, or it will be `null` if there is no context - /// tracker. - get context() { return this.curContext ? this.curContext.context : null; } - // Push a state onto the stack, tracking its start position as well - // as the buffer base at that point. - /// @internal - pushState(state, start) { - this.stack.push(this.state, start, this.bufferBase + this.buffer.length); - this.state = state; - } - // Apply a reduce action - /// @internal - reduce(action) { - let depth = action >> 19 /* ReduceDepthShift */, type = action & 65535 /* ValueMask */; - let { parser } = this.p; - let dPrec = parser.dynamicPrecedence(type); - if (dPrec) - this.score += dPrec; - if (depth == 0) { - this.pushState(parser.getGoto(this.state, type, true), this.reducePos); - // Zero-depth reductions are a special case—they add stuff to - // the stack without popping anything off. - if (type < parser.minRepeatTerm) - this.storeNode(type, this.reducePos, this.reducePos, 4, true); - this.reduceContext(type, this.reducePos); - return; - } - // Find the base index into `this.stack`, content after which will - // be dropped. Note that with `StayFlag` reductions we need to - // consume two extra frames (the dummy parent node for the skipped - // expression and the state that we'll be staying in, which should - // be moved to `this.state`). - let base = this.stack.length - ((depth - 1) * 3) - (action & 262144 /* StayFlag */ ? 6 : 0); - let start = this.stack[base - 2]; - let bufferBase = this.stack[base - 1], count = this.bufferBase + this.buffer.length - bufferBase; - // Store normal terms or `R -> R R` repeat reductions - if (type < parser.minRepeatTerm || (action & 131072 /* RepeatFlag */)) { - let pos = parser.stateFlag(this.state, 1 /* Skipped */) ? this.pos : this.reducePos; - this.storeNode(type, start, pos, count + 4, true); - } - if (action & 262144 /* StayFlag */) { - this.state = this.stack[base]; - } - else { - let baseStateID = this.stack[base - 3]; - this.state = parser.getGoto(baseStateID, type, true); - } - while (this.stack.length > base) - this.stack.pop(); - this.reduceContext(type, start); - } - // Shift a value into the buffer - /// @internal - storeNode(term, start, end, size = 4, isReduce = false) { - if (term == 0 /* Err */ && - (!this.stack.length || this.stack[this.stack.length - 1] < this.buffer.length + this.bufferBase)) { - // Try to omit/merge adjacent error nodes - let cur = this, top = this.buffer.length; - if (top == 0 && cur.parent) { - top = cur.bufferBase - cur.parent.bufferBase; - cur = cur.parent; - } - if (top > 0 && cur.buffer[top - 4] == 0 /* Err */ && cur.buffer[top - 1] > -1) { - if (start == end) - return; - if (cur.buffer[top - 2] >= start) { - cur.buffer[top - 2] = end; - return; - } - } - } - if (!isReduce || this.pos == end) { // Simple case, just append - this.buffer.push(term, start, end, size); - } - else { // There may be skipped nodes that have to be moved forward - let index = this.buffer.length; - if (index > 0 && this.buffer[index - 4] != 0 /* Err */) - while (index > 0 && this.buffer[index - 2] > end) { - // Move this record forward - this.buffer[index] = this.buffer[index - 4]; - this.buffer[index + 1] = this.buffer[index - 3]; - this.buffer[index + 2] = this.buffer[index - 2]; - this.buffer[index + 3] = this.buffer[index - 1]; - index -= 4; - if (size > 4) - size -= 4; - } - this.buffer[index] = term; - this.buffer[index + 1] = start; - this.buffer[index + 2] = end; - this.buffer[index + 3] = size; - } - } - // Apply a shift action - /// @internal - shift(action, next, nextEnd) { - let start = this.pos; - if (action & 131072 /* GotoFlag */) { - this.pushState(action & 65535 /* ValueMask */, this.pos); - } - else if ((action & 262144 /* StayFlag */) == 0) { // Regular shift - let nextState = action, { parser } = this.p; - if (nextEnd > this.pos || next <= parser.maxNode) { - this.pos = nextEnd; - if (!parser.stateFlag(nextState, 1 /* Skipped */)) - this.reducePos = nextEnd; - } - this.pushState(nextState, start); - this.shiftContext(next, start); - if (next <= parser.maxNode) - this.buffer.push(next, start, nextEnd, 4); - } - else { // Shift-and-stay, which means this is a skipped token - this.pos = nextEnd; - this.shiftContext(next, start); - if (next <= this.p.parser.maxNode) - this.buffer.push(next, start, nextEnd, 4); - } - } - // Apply an action - /// @internal - apply(action, next, nextEnd) { - if (action & 65536 /* ReduceFlag */) - this.reduce(action); - else - this.shift(action, next, nextEnd); - } - // Add a prebuilt (reused) node into the buffer. - /// @internal - useNode(value, next) { - let index = this.p.reused.length - 1; - if (index < 0 || this.p.reused[index] != value) { - this.p.reused.push(value); - index++; - } - let start = this.pos; - this.reducePos = this.pos = start + value.length; - this.pushState(next, start); - this.buffer.push(index, start, this.reducePos, -1 /* size == -1 means this is a reused value */); - if (this.curContext) - this.updateContext(this.curContext.tracker.reuse(this.curContext.context, value, this, this.p.stream.reset(this.pos - value.length))); - } - // Split the stack. Due to the buffer sharing and the fact - // that `this.stack` tends to stay quite shallow, this isn't very - // expensive. - /// @internal - split() { - let parent = this; - let off = parent.buffer.length; - // Because the top of the buffer (after this.pos) may be mutated - // to reorder reductions and skipped tokens, and shared buffers - // should be immutable, this copies any outstanding skipped tokens - // to the new buffer, and puts the base pointer before them. - while (off > 0 && parent.buffer[off - 2] > parent.reducePos) - off -= 4; - let buffer = parent.buffer.slice(off), base = parent.bufferBase + off; - // Make sure parent points to an actual parent with content, if there is such a parent. - while (parent && base == parent.bufferBase) - parent = parent.parent; - return new Stack$2(this.p, this.stack.slice(), this.state, this.reducePos, this.pos, this.score, buffer, base, this.curContext, this.lookAhead, parent); - } - // Try to recover from an error by 'deleting' (ignoring) one token. - /// @internal - recoverByDelete(next, nextEnd) { - let isNode = next <= this.p.parser.maxNode; - if (isNode) - this.storeNode(next, this.pos, nextEnd, 4); - this.storeNode(0 /* Err */, this.pos, nextEnd, isNode ? 8 : 4); - this.pos = this.reducePos = nextEnd; - this.score -= 190 /* Delete */; - } - /// Check if the given term would be able to be shifted (optionally - /// after some reductions) on this stack. This can be useful for - /// external tokenizers that want to make sure they only provide a - /// given token when it applies. - canShift(term) { - for (let sim = new SimulatedStack$2(this);;) { - let action = this.p.parser.stateSlot(sim.state, 4 /* DefaultReduce */) || this.p.parser.hasAction(sim.state, term); - if ((action & 65536 /* ReduceFlag */) == 0) - return true; - if (action == 0) - return false; - sim.reduce(action); - } - } - // Apply up to Recover.MaxNext recovery actions that conceptually - // inserts some missing token or rule. - /// @internal - recoverByInsert(next) { - if (this.stack.length >= 300 /* MaxInsertStackDepth */) - return []; - let nextStates = this.p.parser.nextStates(this.state); - if (nextStates.length > 4 /* MaxNext */ << 1 || this.stack.length >= 120 /* DampenInsertStackDepth */) { - let best = []; - for (let i = 0, s; i < nextStates.length; i += 2) { - if ((s = nextStates[i + 1]) != this.state && this.p.parser.hasAction(s, next)) - best.push(nextStates[i], s); - } - if (this.stack.length < 120 /* DampenInsertStackDepth */) - for (let i = 0; best.length < 4 /* MaxNext */ << 1 && i < nextStates.length; i += 2) { - let s = nextStates[i + 1]; - if (!best.some((v, i) => (i & 1) && v == s)) - best.push(nextStates[i], s); - } - nextStates = best; - } - let result = []; - for (let i = 0; i < nextStates.length && result.length < 4 /* MaxNext */; i += 2) { - let s = nextStates[i + 1]; - if (s == this.state) - continue; - let stack = this.split(); - stack.pushState(s, this.pos); - stack.storeNode(0 /* Err */, stack.pos, stack.pos, 4, true); - stack.shiftContext(nextStates[i], this.pos); - stack.score -= 200 /* Insert */; - result.push(stack); - } - return result; - } - // Force a reduce, if possible. Return false if that can't - // be done. - /// @internal - forceReduce() { - let reduce = this.p.parser.stateSlot(this.state, 5 /* ForcedReduce */); - if ((reduce & 65536 /* ReduceFlag */) == 0) - return false; - let { parser } = this.p; - if (!parser.validAction(this.state, reduce)) { - let depth = reduce >> 19 /* ReduceDepthShift */, term = reduce & 65535 /* ValueMask */; - let target = this.stack.length - depth * 3; - if (target < 0 || parser.getGoto(this.stack[target], term, false) < 0) - return false; - this.storeNode(0 /* Err */, this.reducePos, this.reducePos, 4, true); - this.score -= 100 /* Reduce */; - } - this.reducePos = this.pos; - this.reduce(reduce); - return true; - } - /// @internal - forceAll() { - while (!this.p.parser.stateFlag(this.state, 2 /* Accepting */)) { - if (!this.forceReduce()) { - this.storeNode(0 /* Err */, this.pos, this.pos, 4, true); - break; - } - } - return this; - } - /// Check whether this state has no further actions (assumed to be a direct descendant of the - /// top state, since any other states must be able to continue - /// somehow). @internal - get deadEnd() { - if (this.stack.length != 3) - return false; - let { parser } = this.p; - return parser.data[parser.stateSlot(this.state, 1 /* Actions */)] == 65535 /* End */ && - !parser.stateSlot(this.state, 4 /* DefaultReduce */); - } - /// Restart the stack (put it back in its start state). Only safe - /// when this.stack.length == 3 (state is directly below the top - /// state). @internal - restart() { - this.state = this.stack[0]; - this.stack.length = 0; - } - /// @internal - sameState(other) { - if (this.state != other.state || this.stack.length != other.stack.length) - return false; - for (let i = 0; i < this.stack.length; i += 3) - if (this.stack[i] != other.stack[i]) - return false; - return true; - } - /// Get the parser used by this stack. - get parser() { return this.p.parser; } - /// Test whether a given dialect (by numeric ID, as exported from - /// the terms file) is enabled. - dialectEnabled(dialectID) { return this.p.parser.dialect.flags[dialectID]; } - shiftContext(term, start) { - if (this.curContext) - this.updateContext(this.curContext.tracker.shift(this.curContext.context, term, this, this.p.stream.reset(start))); - } - reduceContext(term, start) { - if (this.curContext) - this.updateContext(this.curContext.tracker.reduce(this.curContext.context, term, this, this.p.stream.reset(start))); - } - /// @internal - emitContext() { - let last = this.buffer.length - 1; - if (last < 0 || this.buffer[last] != -3) - this.buffer.push(this.curContext.hash, this.reducePos, this.reducePos, -3); - } - /// @internal - emitLookAhead() { - let last = this.buffer.length - 1; - if (last < 0 || this.buffer[last] != -4) - this.buffer.push(this.lookAhead, this.reducePos, this.reducePos, -4); - } - updateContext(context) { - if (context != this.curContext.context) { - let newCx = new StackContext$2(this.curContext.tracker, context); - if (newCx.hash != this.curContext.hash) - this.emitContext(); - this.curContext = newCx; - } - } - /// @internal - setLookAhead(lookAhead) { - if (lookAhead > this.lookAhead) { - this.emitLookAhead(); - this.lookAhead = lookAhead; - } - } - /// @internal - close() { - if (this.curContext && this.curContext.tracker.strict) - this.emitContext(); - if (this.lookAhead > 0) - this.emitLookAhead(); - } -} -class StackContext$2 { - constructor(tracker, context) { - this.tracker = tracker; - this.context = context; - this.hash = tracker.strict ? tracker.hash(context) : 0; - } -} -var Recover$2; -(function (Recover) { - Recover[Recover["Insert"] = 200] = "Insert"; - Recover[Recover["Delete"] = 190] = "Delete"; - Recover[Recover["Reduce"] = 100] = "Reduce"; - Recover[Recover["MaxNext"] = 4] = "MaxNext"; - Recover[Recover["MaxInsertStackDepth"] = 300] = "MaxInsertStackDepth"; - Recover[Recover["DampenInsertStackDepth"] = 120] = "DampenInsertStackDepth"; -})(Recover$2 || (Recover$2 = {})); -// Used to cheaply run some reductions to scan ahead without mutating -// an entire stack -class SimulatedStack$2 { - constructor(start) { - this.start = start; - this.state = start.state; - this.stack = start.stack; - this.base = this.stack.length; - } - reduce(action) { - let term = action & 65535 /* ValueMask */, depth = action >> 19 /* ReduceDepthShift */; - if (depth == 0) { - if (this.stack == this.start.stack) - this.stack = this.stack.slice(); - this.stack.push(this.state, 0, 0); - this.base += 3; - } - else { - this.base -= (depth - 1) * 3; - } - let goto = this.start.p.parser.getGoto(this.stack[this.base - 3], term, true); - this.state = goto; - } -} -// This is given to `Tree.build` to build a buffer, and encapsulates -// the parent-stack-walking necessary to read the nodes. -class StackBufferCursor$2 { - constructor(stack, pos, index) { - this.stack = stack; - this.pos = pos; - this.index = index; - this.buffer = stack.buffer; - if (this.index == 0) - this.maybeNext(); - } - static create(stack, pos = stack.bufferBase + stack.buffer.length) { - return new StackBufferCursor$2(stack, pos, pos - stack.bufferBase); - } - maybeNext() { - let next = this.stack.parent; - if (next != null) { - this.index = this.stack.bufferBase - next.bufferBase; - this.stack = next; - this.buffer = next.buffer; - } - } - get id() { return this.buffer[this.index - 4]; } - get start() { return this.buffer[this.index - 3]; } - get end() { return this.buffer[this.index - 2]; } - get size() { return this.buffer[this.index - 1]; } - next() { - this.index -= 4; - this.pos -= 4; - if (this.index == 0) - this.maybeNext(); - } - fork() { - return new StackBufferCursor$2(this.stack, this.pos, this.index); - } -} - -class CachedToken$2 { - constructor() { - this.start = -1; - this.value = -1; - this.end = -1; - this.extended = -1; - this.lookAhead = 0; - this.mask = 0; - this.context = 0; - } -} -const nullToken$2 = new CachedToken$2; -/// [Tokenizers](#lr.ExternalTokenizer) interact with the input -/// through this interface. It presents the input as a stream of -/// characters, tracking lookahead and hiding the complexity of -/// [ranges](#common.Parser.parse^ranges) from tokenizer code. -class InputStream$2 { - /// @internal - constructor( - /// @internal - input, - /// @internal - ranges) { - this.input = input; - this.ranges = ranges; - /// @internal - this.chunk = ""; - /// @internal - this.chunkOff = 0; - /// Backup chunk - this.chunk2 = ""; - this.chunk2Pos = 0; - /// The character code of the next code unit in the input, or -1 - /// when the stream is at the end of the input. - this.next = -1; - /// @internal - this.token = nullToken$2; - this.rangeIndex = 0; - this.pos = this.chunkPos = ranges[0].from; - this.range = ranges[0]; - this.end = ranges[ranges.length - 1].to; - this.readNext(); - } - resolveOffset(offset, assoc) { - let range = this.range, index = this.rangeIndex; - let pos = this.pos + offset; - while (pos < range.from) { - if (!index) - return null; - let next = this.ranges[--index]; - pos -= range.from - next.to; - range = next; - } - while (assoc < 0 ? pos > range.to : pos >= range.to) { - if (index == this.ranges.length - 1) - return null; - let next = this.ranges[++index]; - pos += next.from - range.to; - range = next; - } - return pos; - } - /// Look at a code unit near the stream position. `.peek(0)` equals - /// `.next`, `.peek(-1)` gives you the previous character, and so - /// on. - /// - /// Note that looking around during tokenizing creates dependencies - /// on potentially far-away content, which may reduce the - /// effectiveness incremental parsing—when looking forward—or even - /// cause invalid reparses when looking backward more than 25 code - /// units, since the library does not track lookbehind. - peek(offset) { - let idx = this.chunkOff + offset, pos, result; - if (idx >= 0 && idx < this.chunk.length) { - pos = this.pos + offset; - result = this.chunk.charCodeAt(idx); - } - else { - let resolved = this.resolveOffset(offset, 1); - if (resolved == null) - return -1; - pos = resolved; - if (pos >= this.chunk2Pos && pos < this.chunk2Pos + this.chunk2.length) { - result = this.chunk2.charCodeAt(pos - this.chunk2Pos); - } - else { - let i = this.rangeIndex, range = this.range; - while (range.to <= pos) - range = this.ranges[++i]; - this.chunk2 = this.input.chunk(this.chunk2Pos = pos); - if (pos + this.chunk2.length > range.to) - this.chunk2 = this.chunk2.slice(0, range.to - pos); - result = this.chunk2.charCodeAt(0); - } - } - if (pos >= this.token.lookAhead) - this.token.lookAhead = pos + 1; - return result; - } - /// Accept a token. By default, the end of the token is set to the - /// current stream position, but you can pass an offset (relative to - /// the stream position) to change that. - acceptToken(token, endOffset = 0) { - let end = endOffset ? this.resolveOffset(endOffset, -1) : this.pos; - if (end == null || end < this.token.start) - throw new RangeError("Token end out of bounds"); - this.token.value = token; - this.token.end = end; - } - getChunk() { - if (this.pos >= this.chunk2Pos && this.pos < this.chunk2Pos + this.chunk2.length) { - let { chunk, chunkPos } = this; - this.chunk = this.chunk2; - this.chunkPos = this.chunk2Pos; - this.chunk2 = chunk; - this.chunk2Pos = chunkPos; - this.chunkOff = this.pos - this.chunkPos; - } - else { - this.chunk2 = this.chunk; - this.chunk2Pos = this.chunkPos; - let nextChunk = this.input.chunk(this.pos); - let end = this.pos + nextChunk.length; - this.chunk = end > this.range.to ? nextChunk.slice(0, this.range.to - this.pos) : nextChunk; - this.chunkPos = this.pos; - this.chunkOff = 0; - } - } - readNext() { - if (this.chunkOff >= this.chunk.length) { - this.getChunk(); - if (this.chunkOff == this.chunk.length) - return this.next = -1; - } - return this.next = this.chunk.charCodeAt(this.chunkOff); - } - /// Move the stream forward N (defaults to 1) code units. Returns - /// the new value of [`next`](#lr.InputStream.next). - advance(n = 1) { - this.chunkOff += n; - while (this.pos + n >= this.range.to) { - if (this.rangeIndex == this.ranges.length - 1) - return this.setDone(); - n -= this.range.to - this.pos; - this.range = this.ranges[++this.rangeIndex]; - this.pos = this.range.from; - } - this.pos += n; - if (this.pos >= this.token.lookAhead) - this.token.lookAhead = this.pos + 1; - return this.readNext(); - } - setDone() { - this.pos = this.chunkPos = this.end; - this.range = this.ranges[this.rangeIndex = this.ranges.length - 1]; - this.chunk = ""; - return this.next = -1; - } - /// @internal - reset(pos, token) { - if (token) { - this.token = token; - token.start = pos; - token.lookAhead = pos + 1; - token.value = token.extended = -1; - } - else { - this.token = nullToken$2; - } - if (this.pos != pos) { - this.pos = pos; - if (pos == this.end) { - this.setDone(); - return this; - } - while (pos < this.range.from) - this.range = this.ranges[--this.rangeIndex]; - while (pos >= this.range.to) - this.range = this.ranges[++this.rangeIndex]; - if (pos >= this.chunkPos && pos < this.chunkPos + this.chunk.length) { - this.chunkOff = pos - this.chunkPos; - } - else { - this.chunk = ""; - this.chunkOff = 0; - } - this.readNext(); - } - return this; - } - /// @internal - read(from, to) { - if (from >= this.chunkPos && to <= this.chunkPos + this.chunk.length) - return this.chunk.slice(from - this.chunkPos, to - this.chunkPos); - if (from >= this.chunk2Pos && to <= this.chunk2Pos + this.chunk2.length) - return this.chunk2.slice(from - this.chunk2Pos, to - this.chunk2Pos); - if (from >= this.range.from && to <= this.range.to) - return this.input.read(from, to); - let result = ""; - for (let r of this.ranges) { - if (r.from >= to) - break; - if (r.to > from) - result += this.input.read(Math.max(r.from, from), Math.min(r.to, to)); - } - return result; - } -} -/// @internal -class TokenGroup$2 { - constructor(data, id) { - this.data = data; - this.id = id; - } - token(input, stack) { readToken$2(this.data, input, stack, this.id); } -} -TokenGroup$2.prototype.contextual = TokenGroup$2.prototype.fallback = TokenGroup$2.prototype.extend = false; -/// `@external tokens` declarations in the grammar should resolve to -/// an instance of this class. -class ExternalTokenizer$2 { - /// Create a tokenizer. The first argument is the function that, - /// given an input stream, scans for the types of tokens it - /// recognizes at the stream's position, and calls - /// [`acceptToken`](#lr.InputStream.acceptToken) when it finds - /// one. - constructor( - /// @internal - token, options = {}) { - this.token = token; - this.contextual = !!options.contextual; - this.fallback = !!options.fallback; - this.extend = !!options.extend; - } -} -// Tokenizer data is stored a big uint16 array containing, for each -// state: -// -// - A group bitmask, indicating what token groups are reachable from -// this state, so that paths that can only lead to tokens not in -// any of the current groups can be cut off early. -// -// - The position of the end of the state's sequence of accepting -// tokens -// -// - The number of outgoing edges for the state -// -// - The accepting tokens, as (token id, group mask) pairs -// -// - The outgoing edges, as (start character, end character, state -// index) triples, with end character being exclusive -// -// This function interprets that data, running through a stream as -// long as new states with the a matching group mask can be reached, -// and updating `token` when it matches a token. -function readToken$2(data, input, stack, group) { - let state = 0, groupMask = 1 << group, { parser } = stack.p, { dialect } = parser; - scan: for (;;) { - if ((groupMask & data[state]) == 0) - break; - let accEnd = data[state + 1]; - // Check whether this state can lead to a token in the current group - // Accept tokens in this state, possibly overwriting - // lower-precedence / shorter tokens - for (let i = state + 3; i < accEnd; i += 2) - if ((data[i + 1] & groupMask) > 0) { - let term = data[i]; - if (dialect.allows(term) && - (input.token.value == -1 || input.token.value == term || parser.overrides(term, input.token.value))) { - input.acceptToken(term); - break; - } - } - // Do a binary search on the state's edges - for (let next = input.next, low = 0, high = data[state + 2]; low < high;) { - let mid = (low + high) >> 1; - let index = accEnd + mid + (mid << 1); - let from = data[index], to = data[index + 1]; - if (next < from) - high = mid; - else if (next >= to) - low = mid + 1; - else { - state = data[index + 2]; - input.advance(); - continue scan; - } - } - break; - } -} - -// See lezer-generator/src/encode.ts for comments about the encoding -// used here -function decodeArray$2(input, Type = Uint16Array) { - if (typeof input != "string") - return input; - let array = null; - for (let pos = 0, out = 0; pos < input.length;) { - let value = 0; - for (;;) { - let next = input.charCodeAt(pos++), stop = false; - if (next == 126 /* BigValCode */) { - value = 65535 /* BigVal */; - break; - } - if (next >= 92 /* Gap2 */) - next--; - if (next >= 34 /* Gap1 */) - next--; - let digit = next - 32 /* Start */; - if (digit >= 46 /* Base */) { - digit -= 46 /* Base */; - stop = true; - } - value += digit; - if (stop) - break; - value *= 46 /* Base */; - } - if (array) - array[out++] = value; - else - array = new Type(value); - } - return array; -} - -// Environment variable used to control console output -const verbose$2 = typeof process != "undefined" && process.env && /\bparse\b/.test(process.env.LOG); -let stackIDs$2 = null; -var Safety$2; -(function (Safety) { - Safety[Safety["Margin"] = 25] = "Margin"; -})(Safety$2 || (Safety$2 = {})); -function cutAt$2(tree, pos, side) { - let cursor = tree.cursor(IterMode.IncludeAnonymous); - cursor.moveTo(pos); - for (;;) { - if (!(side < 0 ? cursor.childBefore(pos) : cursor.childAfter(pos))) - for (;;) { - if ((side < 0 ? cursor.to < pos : cursor.from > pos) && !cursor.type.isError) - return side < 0 ? Math.max(0, Math.min(cursor.to - 1, pos - 25 /* Margin */)) - : Math.min(tree.length, Math.max(cursor.from + 1, pos + 25 /* Margin */)); - if (side < 0 ? cursor.prevSibling() : cursor.nextSibling()) - break; - if (!cursor.parent()) - return side < 0 ? 0 : tree.length; - } - } -} -class FragmentCursor$2 { - constructor(fragments, nodeSet) { - this.fragments = fragments; - this.nodeSet = nodeSet; - this.i = 0; - this.fragment = null; - this.safeFrom = -1; - this.safeTo = -1; - this.trees = []; - this.start = []; - this.index = []; - this.nextFragment(); - } - nextFragment() { - let fr = this.fragment = this.i == this.fragments.length ? null : this.fragments[this.i++]; - if (fr) { - this.safeFrom = fr.openStart ? cutAt$2(fr.tree, fr.from + fr.offset, 1) - fr.offset : fr.from; - this.safeTo = fr.openEnd ? cutAt$2(fr.tree, fr.to + fr.offset, -1) - fr.offset : fr.to; - while (this.trees.length) { - this.trees.pop(); - this.start.pop(); - this.index.pop(); - } - this.trees.push(fr.tree); - this.start.push(-fr.offset); - this.index.push(0); - this.nextStart = this.safeFrom; - } - else { - this.nextStart = 1e9; - } - } - // `pos` must be >= any previously given `pos` for this cursor - nodeAt(pos) { - if (pos < this.nextStart) - return null; - while (this.fragment && this.safeTo <= pos) - this.nextFragment(); - if (!this.fragment) - return null; - for (;;) { - let last = this.trees.length - 1; - if (last < 0) { // End of tree - this.nextFragment(); - return null; - } - let top = this.trees[last], index = this.index[last]; - if (index == top.children.length) { - this.trees.pop(); - this.start.pop(); - this.index.pop(); - continue; - } - let next = top.children[index]; - let start = this.start[last] + top.positions[index]; - if (start > pos) { - this.nextStart = start; - return null; - } - if (next instanceof Tree) { - if (start == pos) { - if (start < this.safeFrom) - return null; - let end = start + next.length; - if (end <= this.safeTo) { - let lookAhead = next.prop(NodeProp.lookAhead); - if (!lookAhead || end + lookAhead < this.fragment.to) - return next; - } - } - this.index[last]++; - if (start + next.length >= Math.max(this.safeFrom, pos)) { // Enter this node - this.trees.push(next); - this.start.push(start); - this.index.push(0); - } - } - else { - this.index[last]++; - this.nextStart = start + next.length; - } - } - } -} -class TokenCache$2 { - constructor(parser, stream) { - this.stream = stream; - this.tokens = []; - this.mainToken = null; - this.actions = []; - this.tokens = parser.tokenizers.map(_ => new CachedToken$2); - } - getActions(stack) { - let actionIndex = 0; - let main = null; - let { parser } = stack.p, { tokenizers } = parser; - let mask = parser.stateSlot(stack.state, 3 /* TokenizerMask */); - let context = stack.curContext ? stack.curContext.hash : 0; - let lookAhead = 0; - for (let i = 0; i < tokenizers.length; i++) { - if (((1 << i) & mask) == 0) - continue; - let tokenizer = tokenizers[i], token = this.tokens[i]; - if (main && !tokenizer.fallback) - continue; - if (tokenizer.contextual || token.start != stack.pos || token.mask != mask || token.context != context) { - this.updateCachedToken(token, tokenizer, stack); - token.mask = mask; - token.context = context; - } - if (token.lookAhead > token.end + 25 /* Margin */) - lookAhead = Math.max(token.lookAhead, lookAhead); - if (token.value != 0 /* Err */) { - let startIndex = actionIndex; - if (token.extended > -1) - actionIndex = this.addActions(stack, token.extended, token.end, actionIndex); - actionIndex = this.addActions(stack, token.value, token.end, actionIndex); - if (!tokenizer.extend) { - main = token; - if (actionIndex > startIndex) - break; - } - } - } - while (this.actions.length > actionIndex) - this.actions.pop(); - if (lookAhead) - stack.setLookAhead(lookAhead); - if (!main && stack.pos == this.stream.end) { - main = new CachedToken$2; - main.value = stack.p.parser.eofTerm; - main.start = main.end = stack.pos; - actionIndex = this.addActions(stack, main.value, main.end, actionIndex); - } - this.mainToken = main; - return this.actions; - } - getMainToken(stack) { - if (this.mainToken) - return this.mainToken; - let main = new CachedToken$2, { pos, p } = stack; - main.start = pos; - main.end = Math.min(pos + 1, p.stream.end); - main.value = pos == p.stream.end ? p.parser.eofTerm : 0 /* Err */; - return main; - } - updateCachedToken(token, tokenizer, stack) { - tokenizer.token(this.stream.reset(stack.pos, token), stack); - if (token.value > -1) { - let { parser } = stack.p; - for (let i = 0; i < parser.specialized.length; i++) - if (parser.specialized[i] == token.value) { - let result = parser.specializers[i](this.stream.read(token.start, token.end), stack); - if (result >= 0 && stack.p.parser.dialect.allows(result >> 1)) { - if ((result & 1) == 0 /* Specialize */) - token.value = result >> 1; - else - token.extended = result >> 1; - break; - } - } - } - else { - token.value = 0 /* Err */; - token.end = Math.min(stack.p.stream.end, stack.pos + 1); - } - } - putAction(action, token, end, index) { - // Don't add duplicate actions - for (let i = 0; i < index; i += 3) - if (this.actions[i] == action) - return index; - this.actions[index++] = action; - this.actions[index++] = token; - this.actions[index++] = end; - return index; - } - addActions(stack, token, end, index) { - let { state } = stack, { parser } = stack.p, { data } = parser; - for (let set = 0; set < 2; set++) { - for (let i = parser.stateSlot(state, set ? 2 /* Skip */ : 1 /* Actions */);; i += 3) { - if (data[i] == 65535 /* End */) { - if (data[i + 1] == 1 /* Next */) { - i = pair$2(data, i + 2); - } - else { - if (index == 0 && data[i + 1] == 2 /* Other */) - index = this.putAction(pair$2(data, i + 2), token, end, index); - break; - } - } - if (data[i] == token) - index = this.putAction(pair$2(data, i + 1), token, end, index); - } - } - return index; - } -} -var Rec$2; -(function (Rec) { - Rec[Rec["Distance"] = 5] = "Distance"; - Rec[Rec["MaxRemainingPerStep"] = 3] = "MaxRemainingPerStep"; - // When two stacks have been running independently long enough to - // add this many elements to their buffers, prune one. - Rec[Rec["MinBufferLengthPrune"] = 500] = "MinBufferLengthPrune"; - Rec[Rec["ForceReduceLimit"] = 10] = "ForceReduceLimit"; - // Once a stack reaches this depth (in .stack.length) force-reduce - // it back to CutTo to avoid creating trees that overflow the stack - // on recursive traversal. - Rec[Rec["CutDepth"] = 15000] = "CutDepth"; - Rec[Rec["CutTo"] = 9000] = "CutTo"; -})(Rec$2 || (Rec$2 = {})); -class Parse$2 { - constructor(parser, input, fragments, ranges) { - this.parser = parser; - this.input = input; - this.ranges = ranges; - this.recovering = 0; - this.nextStackID = 0x2654; // ♔, ♕, ♖, ♗, ♘, ♙, ♠, ♡, ♢, ♣, ♤, ♥, ♦, ♧ - this.minStackPos = 0; - this.reused = []; - this.stoppedAt = null; - this.stream = new InputStream$2(input, ranges); - this.tokens = new TokenCache$2(parser, this.stream); - this.topTerm = parser.top[1]; - let { from } = ranges[0]; - this.stacks = [Stack$2.start(this, parser.top[0], from)]; - this.fragments = fragments.length && this.stream.end - from > parser.bufferLength * 4 - ? new FragmentCursor$2(fragments, parser.nodeSet) : null; - } - get parsedPos() { - return this.minStackPos; - } - // Move the parser forward. This will process all parse stacks at - // `this.pos` and try to advance them to a further position. If no - // stack for such a position is found, it'll start error-recovery. - // - // When the parse is finished, this will return a syntax tree. When - // not, it returns `null`. - advance() { - let stacks = this.stacks, pos = this.minStackPos; - // This will hold stacks beyond `pos`. - let newStacks = this.stacks = []; - let stopped, stoppedTokens; - // Keep advancing any stacks at `pos` until they either move - // forward or can't be advanced. Gather stacks that can't be - // advanced further in `stopped`. - for (let i = 0; i < stacks.length; i++) { - let stack = stacks[i]; - for (;;) { - this.tokens.mainToken = null; - if (stack.pos > pos) { - newStacks.push(stack); - } - else if (this.advanceStack(stack, newStacks, stacks)) { - continue; - } - else { - if (!stopped) { - stopped = []; - stoppedTokens = []; - } - stopped.push(stack); - let tok = this.tokens.getMainToken(stack); - stoppedTokens.push(tok.value, tok.end); - } - break; - } - } - if (!newStacks.length) { - let finished = stopped && findFinished$2(stopped); - if (finished) - return this.stackToTree(finished); - if (this.parser.strict) { - if (verbose$2 && stopped) - console.log("Stuck with token " + (this.tokens.mainToken ? this.parser.getName(this.tokens.mainToken.value) : "none")); - throw new SyntaxError("No parse at " + pos); - } - if (!this.recovering) - this.recovering = 5 /* Distance */; - } - if (this.recovering && stopped) { - let finished = this.stoppedAt != null && stopped[0].pos > this.stoppedAt ? stopped[0] - : this.runRecovery(stopped, stoppedTokens, newStacks); - if (finished) - return this.stackToTree(finished.forceAll()); - } - if (this.recovering) { - let maxRemaining = this.recovering == 1 ? 1 : this.recovering * 3 /* MaxRemainingPerStep */; - if (newStacks.length > maxRemaining) { - newStacks.sort((a, b) => b.score - a.score); - while (newStacks.length > maxRemaining) - newStacks.pop(); - } - if (newStacks.some(s => s.reducePos > pos)) - this.recovering--; - } - else if (newStacks.length > 1) { - // Prune stacks that are in the same state, or that have been - // running without splitting for a while, to avoid getting stuck - // with multiple successful stacks running endlessly on. - outer: for (let i = 0; i < newStacks.length - 1; i++) { - let stack = newStacks[i]; - for (let j = i + 1; j < newStacks.length; j++) { - let other = newStacks[j]; - if (stack.sameState(other) || - stack.buffer.length > 500 /* MinBufferLengthPrune */ && other.buffer.length > 500 /* MinBufferLengthPrune */) { - if (((stack.score - other.score) || (stack.buffer.length - other.buffer.length)) > 0) { - newStacks.splice(j--, 1); - } - else { - newStacks.splice(i--, 1); - continue outer; - } - } - } - } - } - this.minStackPos = newStacks[0].pos; - for (let i = 1; i < newStacks.length; i++) - if (newStacks[i].pos < this.minStackPos) - this.minStackPos = newStacks[i].pos; - return null; - } - stopAt(pos) { - if (this.stoppedAt != null && this.stoppedAt < pos) - throw new RangeError("Can't move stoppedAt forward"); - this.stoppedAt = pos; - } - // Returns an updated version of the given stack, or null if the - // stack can't advance normally. When `split` and `stacks` are - // given, stacks split off by ambiguous operations will be pushed to - // `split`, or added to `stacks` if they move `pos` forward. - advanceStack(stack, stacks, split) { - let start = stack.pos, { parser } = this; - let base = verbose$2 ? this.stackID(stack) + " -> " : ""; - if (this.stoppedAt != null && start > this.stoppedAt) - return stack.forceReduce() ? stack : null; - if (this.fragments) { - let strictCx = stack.curContext && stack.curContext.tracker.strict, cxHash = strictCx ? stack.curContext.hash : 0; - for (let cached = this.fragments.nodeAt(start); cached;) { - let match = this.parser.nodeSet.types[cached.type.id] == cached.type ? parser.getGoto(stack.state, cached.type.id) : -1; - if (match > -1 && cached.length && (!strictCx || (cached.prop(NodeProp.contextHash) || 0) == cxHash)) { - stack.useNode(cached, match); - if (verbose$2) - console.log(base + this.stackID(stack) + ` (via reuse of ${parser.getName(cached.type.id)})`); - return true; - } - if (!(cached instanceof Tree) || cached.children.length == 0 || cached.positions[0] > 0) - break; - let inner = cached.children[0]; - if (inner instanceof Tree && cached.positions[0] == 0) - cached = inner; - else - break; - } - } - let defaultReduce = parser.stateSlot(stack.state, 4 /* DefaultReduce */); - if (defaultReduce > 0) { - stack.reduce(defaultReduce); - if (verbose$2) - console.log(base + this.stackID(stack) + ` (via always-reduce ${parser.getName(defaultReduce & 65535 /* ValueMask */)})`); - return true; - } - if (stack.stack.length >= 15000 /* CutDepth */) { - while (stack.stack.length > 9000 /* CutTo */ && stack.forceReduce()) { } - } - let actions = this.tokens.getActions(stack); - for (let i = 0; i < actions.length;) { - let action = actions[i++], term = actions[i++], end = actions[i++]; - let last = i == actions.length || !split; - let localStack = last ? stack : stack.split(); - localStack.apply(action, term, end); - if (verbose$2) - console.log(base + this.stackID(localStack) + ` (via ${(action & 65536 /* ReduceFlag */) == 0 ? "shift" - : `reduce of ${parser.getName(action & 65535 /* ValueMask */)}`} for ${parser.getName(term)} @ ${start}${localStack == stack ? "" : ", split"})`); - if (last) - return true; - else if (localStack.pos > start) - stacks.push(localStack); - else - split.push(localStack); - } - return false; - } - // Advance a given stack forward as far as it will go. Returns the - // (possibly updated) stack if it got stuck, or null if it moved - // forward and was given to `pushStackDedup`. - advanceFully(stack, newStacks) { - let pos = stack.pos; - for (;;) { - if (!this.advanceStack(stack, null, null)) - return false; - if (stack.pos > pos) { - pushStackDedup$2(stack, newStacks); - return true; - } - } - } - runRecovery(stacks, tokens, newStacks) { - let finished = null, restarted = false; - for (let i = 0; i < stacks.length; i++) { - let stack = stacks[i], token = tokens[i << 1], tokenEnd = tokens[(i << 1) + 1]; - let base = verbose$2 ? this.stackID(stack) + " -> " : ""; - if (stack.deadEnd) { - if (restarted) - continue; - restarted = true; - stack.restart(); - if (verbose$2) - console.log(base + this.stackID(stack) + " (restarted)"); - let done = this.advanceFully(stack, newStacks); - if (done) - continue; - } - let force = stack.split(), forceBase = base; - for (let j = 0; force.forceReduce() && j < 10 /* ForceReduceLimit */; j++) { - if (verbose$2) - console.log(forceBase + this.stackID(force) + " (via force-reduce)"); - let done = this.advanceFully(force, newStacks); - if (done) - break; - if (verbose$2) - forceBase = this.stackID(force) + " -> "; - } - for (let insert of stack.recoverByInsert(token)) { - if (verbose$2) - console.log(base + this.stackID(insert) + " (via recover-insert)"); - this.advanceFully(insert, newStacks); - } - if (this.stream.end > stack.pos) { - if (tokenEnd == stack.pos) { - tokenEnd++; - token = 0 /* Err */; - } - stack.recoverByDelete(token, tokenEnd); - if (verbose$2) - console.log(base + this.stackID(stack) + ` (via recover-delete ${this.parser.getName(token)})`); - pushStackDedup$2(stack, newStacks); - } - else if (!finished || finished.score < stack.score) { - finished = stack; - } - } - return finished; - } - // Convert the stack's buffer to a syntax tree. - stackToTree(stack) { - stack.close(); - return Tree.build({ buffer: StackBufferCursor$2.create(stack), - nodeSet: this.parser.nodeSet, - topID: this.topTerm, - maxBufferLength: this.parser.bufferLength, - reused: this.reused, - start: this.ranges[0].from, - length: stack.pos - this.ranges[0].from, - minRepeatType: this.parser.minRepeatTerm }); - } - stackID(stack) { - let id = (stackIDs$2 || (stackIDs$2 = new WeakMap)).get(stack); - if (!id) - stackIDs$2.set(stack, id = String.fromCodePoint(this.nextStackID++)); - return id + stack; - } -} -function pushStackDedup$2(stack, newStacks) { - for (let i = 0; i < newStacks.length; i++) { - let other = newStacks[i]; - if (other.pos == stack.pos && other.sameState(stack)) { - if (newStacks[i].score < stack.score) - newStacks[i] = stack; - return; - } - } - newStacks.push(stack); -} -class Dialect$2 { - constructor(source, flags, disabled) { - this.source = source; - this.flags = flags; - this.disabled = disabled; - } - allows(term) { return !this.disabled || this.disabled[term] == 0; } -} -const id$1 = x => x; -/// Context trackers are used to track stateful context (such as -/// indentation in the Python grammar, or parent elements in the XML -/// grammar) needed by external tokenizers. You declare them in a -/// grammar file as `@context exportName from "module"`. -/// -/// Context values should be immutable, and can be updated (replaced) -/// on shift or reduce actions. -/// -/// The export used in a `@context` declaration should be of this -/// type. -class ContextTracker$1 { - /// Define a context tracker. - constructor(spec) { - this.start = spec.start; - this.shift = spec.shift || id$1; - this.reduce = spec.reduce || id$1; - this.reuse = spec.reuse || id$1; - this.hash = spec.hash || (() => 0); - this.strict = spec.strict !== false; - } -} -/// A parser holds the parse tables for a given grammar, as generated -/// by `lezer-generator`. -class LRParser$2 extends Parser { - /// @internal - constructor(spec) { - super(); - /// @internal - this.wrappers = []; - if (spec.version != 14 /* Version */) - throw new RangeError(`Parser version (${spec.version}) doesn't match runtime version (${14 /* Version */})`); - let nodeNames = spec.nodeNames.split(" "); - this.minRepeatTerm = nodeNames.length; - for (let i = 0; i < spec.repeatNodeCount; i++) - nodeNames.push(""); - let topTerms = Object.keys(spec.topRules).map(r => spec.topRules[r][1]); - let nodeProps = []; - for (let i = 0; i < nodeNames.length; i++) - nodeProps.push([]); - function setProp(nodeID, prop, value) { - nodeProps[nodeID].push([prop, prop.deserialize(String(value))]); - } - if (spec.nodeProps) - for (let propSpec of spec.nodeProps) { - let prop = propSpec[0]; - if (typeof prop == "string") - prop = NodeProp[prop]; - for (let i = 1; i < propSpec.length;) { - let next = propSpec[i++]; - if (next >= 0) { - setProp(next, prop, propSpec[i++]); - } - else { - let value = propSpec[i + -next]; - for (let j = -next; j > 0; j--) - setProp(propSpec[i++], prop, value); - i++; - } - } - } - this.nodeSet = new NodeSet(nodeNames.map((name, i) => NodeType.define({ - name: i >= this.minRepeatTerm ? undefined : name, - id: i, - props: nodeProps[i], - top: topTerms.indexOf(i) > -1, - error: i == 0, - skipped: spec.skippedNodes && spec.skippedNodes.indexOf(i) > -1 - }))); - if (spec.propSources) - this.nodeSet = this.nodeSet.extend(...spec.propSources); - this.strict = false; - this.bufferLength = DefaultBufferLength; - let tokenArray = decodeArray$2(spec.tokenData); - this.context = spec.context; - this.specialized = new Uint16Array(spec.specialized ? spec.specialized.length : 0); - this.specializers = []; - if (spec.specialized) - for (let i = 0; i < spec.specialized.length; i++) { - this.specialized[i] = spec.specialized[i].term; - this.specializers[i] = spec.specialized[i].get; - } - this.states = decodeArray$2(spec.states, Uint32Array); - this.data = decodeArray$2(spec.stateData); - this.goto = decodeArray$2(spec.goto); - this.maxTerm = spec.maxTerm; - this.tokenizers = spec.tokenizers.map(value => typeof value == "number" ? new TokenGroup$2(tokenArray, value) : value); - this.topRules = spec.topRules; - this.dialects = spec.dialects || {}; - this.dynamicPrecedences = spec.dynamicPrecedences || null; - this.tokenPrecTable = spec.tokenPrec; - this.termNames = spec.termNames || null; - this.maxNode = this.nodeSet.types.length - 1; - this.dialect = this.parseDialect(); - this.top = this.topRules[Object.keys(this.topRules)[0]]; - } - createParse(input, fragments, ranges) { - let parse = new Parse$2(this, input, fragments, ranges); - for (let w of this.wrappers) - parse = w(parse, input, fragments, ranges); - return parse; - } - /// Get a goto table entry @internal - getGoto(state, term, loose = false) { - let table = this.goto; - if (term >= table[0]) - return -1; - for (let pos = table[term + 1];;) { - let groupTag = table[pos++], last = groupTag & 1; - let target = table[pos++]; - if (last && loose) - return target; - for (let end = pos + (groupTag >> 1); pos < end; pos++) - if (table[pos] == state) - return target; - if (last) - return -1; - } - } - /// Check if this state has an action for a given terminal @internal - hasAction(state, terminal) { - let data = this.data; - for (let set = 0; set < 2; set++) { - for (let i = this.stateSlot(state, set ? 2 /* Skip */ : 1 /* Actions */), next;; i += 3) { - if ((next = data[i]) == 65535 /* End */) { - if (data[i + 1] == 1 /* Next */) - next = data[i = pair$2(data, i + 2)]; - else if (data[i + 1] == 2 /* Other */) - return pair$2(data, i + 2); - else - break; - } - if (next == terminal || next == 0 /* Err */) - return pair$2(data, i + 1); - } - } - return 0; - } - /// @internal - stateSlot(state, slot) { - return this.states[(state * 6 /* Size */) + slot]; - } - /// @internal - stateFlag(state, flag) { - return (this.stateSlot(state, 0 /* Flags */) & flag) > 0; - } - /// @internal - validAction(state, action) { - if (action == this.stateSlot(state, 4 /* DefaultReduce */)) - return true; - for (let i = this.stateSlot(state, 1 /* Actions */);; i += 3) { - if (this.data[i] == 65535 /* End */) { - if (this.data[i + 1] == 1 /* Next */) - i = pair$2(this.data, i + 2); - else - return false; - } - if (action == pair$2(this.data, i + 1)) - return true; - } - } - /// Get the states that can follow this one through shift actions or - /// goto jumps. @internal - nextStates(state) { - let result = []; - for (let i = this.stateSlot(state, 1 /* Actions */);; i += 3) { - if (this.data[i] == 65535 /* End */) { - if (this.data[i + 1] == 1 /* Next */) - i = pair$2(this.data, i + 2); - else - break; - } - if ((this.data[i + 2] & (65536 /* ReduceFlag */ >> 16)) == 0) { - let value = this.data[i + 1]; - if (!result.some((v, i) => (i & 1) && v == value)) - result.push(this.data[i], value); - } - } - return result; - } - /// @internal - overrides(token, prev) { - let iPrev = findOffset$2(this.data, this.tokenPrecTable, prev); - return iPrev < 0 || findOffset$2(this.data, this.tokenPrecTable, token) < iPrev; - } - /// Configure the parser. Returns a new parser instance that has the - /// given settings modified. Settings not provided in `config` are - /// kept from the original parser. - configure(config) { - // Hideous reflection-based kludge to make it easy to create a - // slightly modified copy of a parser. - let copy = Object.assign(Object.create(LRParser$2.prototype), this); - if (config.props) - copy.nodeSet = this.nodeSet.extend(...config.props); - if (config.top) { - let info = this.topRules[config.top]; - if (!info) - throw new RangeError(`Invalid top rule name ${config.top}`); - copy.top = info; - } - if (config.tokenizers) - copy.tokenizers = this.tokenizers.map(t => { - let found = config.tokenizers.find(r => r.from == t); - return found ? found.to : t; - }); - if (config.contextTracker) - copy.context = config.contextTracker; - if (config.dialect) - copy.dialect = this.parseDialect(config.dialect); - if (config.strict != null) - copy.strict = config.strict; - if (config.wrap) - copy.wrappers = copy.wrappers.concat(config.wrap); - if (config.bufferLength != null) - copy.bufferLength = config.bufferLength; - return copy; - } - /// Tells you whether any [parse wrappers](#lr.ParserConfig.wrap) - /// are registered for this parser. - hasWrappers() { - return this.wrappers.length > 0; - } - /// Returns the name associated with a given term. This will only - /// work for all terms when the parser was generated with the - /// `--names` option. By default, only the names of tagged terms are - /// stored. - getName(term) { - return this.termNames ? this.termNames[term] : String(term <= this.maxNode && this.nodeSet.types[term].name || term); - } - /// The eof term id is always allocated directly after the node - /// types. @internal - get eofTerm() { return this.maxNode + 1; } - /// The type of top node produced by the parser. - get topNode() { return this.nodeSet.types[this.top[1]]; } - /// @internal - dynamicPrecedence(term) { - let prec = this.dynamicPrecedences; - return prec == null ? 0 : prec[term] || 0; - } - /// @internal - parseDialect(dialect) { - let values = Object.keys(this.dialects), flags = values.map(() => false); - if (dialect) - for (let part of dialect.split(" ")) { - let id = values.indexOf(part); - if (id >= 0) - flags[id] = true; - } - let disabled = null; - for (let i = 0; i < values.length; i++) - if (!flags[i]) { - for (let j = this.dialects[values[i]], id; (id = this.data[j++]) != 65535 /* End */;) - (disabled || (disabled = new Uint8Array(this.maxTerm + 1)))[id] = 1; - } - return new Dialect$2(dialect, flags, disabled); - } - /// (used by the output of the parser generator) @internal - static deserialize(spec) { - return new LRParser$2(spec); - } -} -function pair$2(data, off) { return data[off] | (data[off + 1] << 16); } -function findOffset$2(data, start, term) { - for (let i = start, next; (next = data[i]) != 65535 /* End */; i++) - if (next == term) - return i - start; - return -1; -} -function findFinished$2(stacks) { - let best = null; - for (let stack of stacks) { - let stopped = stack.p.stoppedAt; - if ((stack.pos == stack.p.stream.end || stopped != null && stack.pos > stopped) && - stack.p.parser.stateFlag(stack.state, 2 /* Accepting */) && - (!best || best.score < stack.score)) - best = stack; - } - return best; -} - -// This file was generated by lezer-generator. You probably shouldn't edit it. -const noSemi = 281, - incdec = 1, - incdecPrefix = 2, - templateContent = 282, - InterpolationStart = 3, - templateEnd = 283, - insertSemi = 284, - TSExtends = 4, - spaces = 286, - newline$2 = 287, - LineComment$1 = 5, - BlockComment$1 = 6, - Dialect_ts = 1; - -/* Hand-written tokenizers for JavaScript tokens that can't be - expressed by lezer's built-in tokenizer. */ - -const space$1 = [9, 10, 11, 12, 13, 32, 133, 160, 5760, 8192, 8193, 8194, 8195, 8196, 8197, 8198, 8199, 8200, - 8201, 8202, 8232, 8233, 8239, 8287, 12288]; - -const braceR = 125, braceL = 123, semicolon = 59, slash = 47, star = 42, - plus = 43, minus = 45, dollar = 36, backtick = 96, backslash = 92; - -const trackNewline = new ContextTracker$1({ - start: false, - shift(context, term) { - return term == LineComment$1 || term == BlockComment$1 || term == spaces ? context : term == newline$2 - }, - strict: false -}); - -const insertSemicolon = new ExternalTokenizer$2((input, stack) => { - let {next} = input; - if ((next == braceR || next == -1 || stack.context) && stack.canShift(insertSemi)) - input.acceptToken(insertSemi); -}, {contextual: true, fallback: true}); - -const noSemicolon = new ExternalTokenizer$2((input, stack) => { - let {next} = input, after; - if (space$1.indexOf(next) > -1) return - if (next == slash && ((after = input.peek(1)) == slash || after == star)) return - if (next != braceR && next != semicolon && next != -1 && !stack.context && stack.canShift(noSemi)) - input.acceptToken(noSemi); -}, {contextual: true}); - -const incdecToken = new ExternalTokenizer$2((input, stack) => { - let {next} = input; - if (next == plus || next == minus) { - input.advance(); - if (next == input.next) { - input.advance(); - let mayPostfix = !stack.context && stack.canShift(incdec); - input.acceptToken(mayPostfix ? incdec : incdecPrefix); - } - } -}, {contextual: true}); - -const template = new ExternalTokenizer$2(input => { - for (let afterDollar = false, i = 0;; i++) { - let {next} = input; - if (next < 0) { - if (i) input.acceptToken(templateContent); - break - } else if (next == backtick) { - if (i) input.acceptToken(templateContent); - else input.acceptToken(templateEnd, 1); - break - } else if (next == braceL && afterDollar) { - if (i == 1) input.acceptToken(InterpolationStart, 1); - else input.acceptToken(templateContent, -1); - break - } else if (next == 10 /* "\n" */ && i) { - // Break up template strings on lines, to avoid huge tokens - input.advance(); - input.acceptToken(templateContent); - break - } else if (next == backslash) { - input.advance(); - } - afterDollar = next == dollar; - input.advance(); - } -}); - -function tsExtends(value, stack) { - return value == "extends" && stack.dialectEnabled(Dialect_ts) ? TSExtends : -1 -} - -const jsHighlight = styleTags({ - "get set async static": tags$1.modifier, - "for while do if else switch try catch finally return throw break continue default case": tags$1.controlKeyword, - "in of await yield void typeof delete instanceof": tags$1.operatorKeyword, - "let var const function class extends": tags$1.definitionKeyword, - "import export from": tags$1.moduleKeyword, - "with debugger as new": tags$1.keyword, - TemplateString: tags$1.special(tags$1.string), - Super: tags$1.atom, - BooleanLiteral: tags$1.bool, - this: tags$1.self, - null: tags$1.null, - Star: tags$1.modifier, - VariableName: tags$1.variableName, - "CallExpression/VariableName TaggedTemplateExpression/VariableName": tags$1.function(tags$1.variableName), - VariableDefinition: tags$1.definition(tags$1.variableName), - Label: tags$1.labelName, - PropertyName: tags$1.propertyName, - PrivatePropertyName: tags$1.special(tags$1.propertyName), - "CallExpression/MemberExpression/PropertyName": tags$1.function(tags$1.propertyName), - "FunctionDeclaration/VariableDefinition": tags$1.function(tags$1.definition(tags$1.variableName)), - "ClassDeclaration/VariableDefinition": tags$1.definition(tags$1.className), - PropertyDefinition: tags$1.definition(tags$1.propertyName), - PrivatePropertyDefinition: tags$1.definition(tags$1.special(tags$1.propertyName)), - UpdateOp: tags$1.updateOperator, - LineComment: tags$1.lineComment, - BlockComment: tags$1.blockComment, - Number: tags$1.number, - String: tags$1.string, - ArithOp: tags$1.arithmeticOperator, - LogicOp: tags$1.logicOperator, - BitOp: tags$1.bitwiseOperator, - CompareOp: tags$1.compareOperator, - RegExp: tags$1.regexp, - Equals: tags$1.definitionOperator, - "Arrow : Spread": tags$1.punctuation, - "( )": tags$1.paren, - "[ ]": tags$1.squareBracket, - "{ }": tags$1.brace, - "InterpolationStart InterpolationEnd": tags$1.special(tags$1.brace), - ".": tags$1.derefOperator, - ", ;": tags$1.separator, - - TypeName: tags$1.typeName, - TypeDefinition: tags$1.definition(tags$1.typeName), - "type enum interface implements namespace module declare": tags$1.definitionKeyword, - "abstract global Privacy readonly override": tags$1.modifier, - "is keyof unique infer": tags$1.operatorKeyword, - - JSXAttributeValue: tags$1.attributeValue, - JSXText: tags$1.content, - "JSXStartTag JSXStartCloseTag JSXSelfCloseEndTag JSXEndTag": tags$1.angleBracket, - "JSXIdentifier JSXNameSpacedName": tags$1.tagName, - "JSXAttribute/JSXIdentifier JSXAttribute/JSXNameSpacedName": tags$1.attributeName -}); - -// This file was generated by lezer-generator. You probably shouldn't edit it. -const spec_identifier$1 = {__proto__:null,export:18, as:23, from:29, default:32, async:37, function:38, this:48, true:56, false:56, void:66, typeof:70, null:86, super:88, new:122, await:139, yield:141, delete:142, class:152, extends:154, public:197, private:197, protected:197, readonly:199, instanceof:220, in:222, const:224, import:256, keyof:307, unique:311, infer:317, is:351, abstract:371, implements:373, type:375, let:378, var:380, interface:387, enum:391, namespace:397, module:399, declare:403, global:407, for:428, of:437, while:440, with:444, do:448, if:452, else:454, switch:458, case:464, try:470, catch:474, finally:478, return:482, throw:486, break:490, continue:494, debugger:498}; -const spec_word = {__proto__:null,async:109, get:111, set:113, public:161, private:161, protected:161, static:163, abstract:165, override:167, readonly:173, new:355}; -const spec_LessThan = {__proto__:null,"<":129}; -const parser$3 = LRParser$2.deserialize({ - version: 14, - states: "$4|O`QYOOO'QQ$IfO'#ChO'XOSO'#DVO)dQYO'#D]O)tQYO'#DhO){QYO'#DrO-xQYO'#DxOOQO'#E]'#E]O.]QWO'#E[O.bQWO'#E[OOQ$IU'#Ef'#EfO0aQ$IfO'#ItO2wQ$IfO'#IuO3eQWO'#EzO3jQpO'#FaOOQ$IU'#FS'#FSO3rO!bO'#FSO4QQWO'#FhO5_QWO'#FgOOQ$IU'#Iu'#IuOOQ$IS'#It'#ItOOQQ'#J^'#J^O5dQWO'#HpO5iQ$I[O'#HqOOQQ'#Ih'#IhOOQQ'#Hr'#HrQ`QYOOO){QYO'#DjO5qQWO'#G[O5vQ#tO'#CmO6UQWO'#EZO6aQWO'#EgO6fQ#tO'#FRO7QQWO'#G[O7VQWO'#G`O7bQWO'#G`O7pQWO'#GcO7pQWO'#GdO7pQWO'#GfO5qQWO'#GiO8aQWO'#GlO9oQWO'#CdO:PQWO'#GyO:XQWO'#HPO:XQWO'#HRO`QYO'#HTO:XQWO'#HVO:XQWO'#HYO:^QWO'#H`O:cQ$I]O'#HfO){QYO'#HhO:nQ$I]O'#HjO:yQ$I]O'#HlO5iQ$I[O'#HnO){QYO'#DWOOOS'#Ht'#HtO;UOSO,59qOOQ$IU,59q,59qO=gQbO'#ChO=qQYO'#HuO>UQWO'#IvO@TQbO'#IvO'dQYO'#IvO@[QWO,59wO@rQ&jO'#DbOAkQWO'#E]OAxQWO'#JROBTQWO'#JQOBTQWO'#JQOB]QWO,5:yOBbQWO'#JPOBiQWO'#DyO5vQ#tO'#EZOBwQWO'#EZOCSQ`O'#FROOQ$IU,5:S,5:SOC[QYO,5:SOEYQ$IfO,5:^OEvQWO,5:dOFaQ$I[O'#JOO7VQWO'#I}OFhQWO'#I}OFpQWO,5:xOFuQWO'#I}OGTQYO,5:vOITQWO'#EWOJ_QWO,5:vOKnQWO'#DlOKuQYO'#DqOLPQ&jO,5;PO){QYO,5;POOQQ'#Er'#ErOOQQ'#Et'#EtO){QYO,5;RO){QYO,5;RO){QYO,5;RO){QYO,5;RO){QYO,5;RO){QYO,5;RO){QYO,5;RO){QYO,5;RO){QYO,5;RO){QYO,5;RO){QYO,5;ROOQQ'#Ex'#ExOLXQYO,5;cOOQ$IU,5;h,5;hOOQ$IU,5;i,5;iONXQWO,5;iOOQ$IU,5;j,5;jO){QYO'#IPON^Q$I[O,5[OOQQ'#Ik'#IkOOQQ,5>],5>]OOQQ-E;p-E;pO!+VQ$IfO,5:UOOQ$IS'#Cp'#CpO!+vQ#tO,5Q,5>QO){QYO,5>QO5iQ$I[O,5>SOOQQ,5>U,5>UO!8VQWO,5>UOOQQ,5>W,5>WO!8VQWO,5>WOOQQ,5>Y,5>YO!8[Q`O,59rOOOS-E;r-E;rOOQ$IU1G/]1G/]O!8aQbO,5>aO'dQYO,5>aOOQO,5>f,5>fO!8kQYO'#HuOOQO-E;s-E;sO!8xQWO,5?bO!9QQbO,5?bO!9XQWO,5?lOOQ$IU1G/c1G/cO!9aQpO'#DTOOQO'#Ix'#IxO){QYO'#IxO!:OQpO'#IxO!:mQpO'#DcO!;OQ&jO'#DcO!=ZQYO'#DcO!=bQWO'#IwO!=jQWO,59|O!=oQWO'#EaO!=}QWO'#JSO!>VQWO,5:zO!>mQ&jO'#DcO){QYO,5?mO!>wQWO'#HzOOQO-E;x-E;xO!9XQWO,5?lOOQ$IS1G0e1G0eO!@TQ&jO'#D|OOQ$IU,5:e,5:eO){QYO,5:eOITQWO,5:eO!@[QWO,5:eO:^QWO,5:uO!,rQpO,5:uO!,zQ#tO,5:uO5vQ#tO,5:uOOQ$IU1G/n1G/nOOQ$IU1G0O1G0OOOQ$IS'#EV'#EVO){QYO,5?jO!@gQ$I[O,5?jO!@xQ$I[O,5?jO!APQWO,5?iO!AXQWO'#H|O!APQWO,5?iOOQ$IS1G0d1G0dO7VQWO,5?iOOQ$IU1G0b1G0bO!AsQ$IfO1G0bO!BdQ$IdO,5:rOOQ$IU'#Fq'#FqO!CQQ$IfO'#IqOGTQYO1G0bO!EPQ#tO'#IyO!EZQWO,5:WO!E`QbO'#IzO){QYO'#IzO!EjQWO,5:]OOQ$IU'#DT'#DTOOQ$IU1G0k1G0kO!EoQWO1G0kO!HQQ$IfO1G0mO!HXQ$IfO1G0mO!JlQ$IfO1G0mO!JsQ$IfO1G0mO!LzQ$IfO1G0mO!M_Q$IfO1G0mO#!OQ$IfO1G0mO#!VQ$IfO1G0mO#$jQ$IfO1G0mO#$qQ$IfO1G0mO#&fQ$IfO1G0mO#)`Q7^O'#ChO#+ZQ7^O1G0}O#-UQ7^O'#IuOOQ$IU1G1T1G1TO#-iQ$IfO,5>kOOQ$IS-E;}-E;}O#.YQ$IfO1G0mOOQ$IU1G0m1G0mO#0[Q$IfO1G1QO#0{QpO,5;sO#1QQpO,5;tO#1VQpO'#F[O#1kQWO'#FZOOQO'#JW'#JWOOQO'#H}'#H}O#1pQpO1G1]OOQ$IU1G1]1G1]OOOO1G1f1G1fO#2OQ7^O'#ItO#2YQWO,5;}OLXQYO,5;}OOOO-E;|-E;|OOQ$IU1G1Y1G1YOOQ$IU,5WQWO1G2iOOQQ1G2j1G2jOITQWO1G2jO#>]QWO1G2jO#>eQ&jO'#GhOOQQ1G2l1G2lO!&tQ&jO'#IYO!0OQ`O1G2oOOQQ1G2o1G2oOOQQ,5=Y,5=YO#>mQ#tO,5=[O5qQWO,5=[O#5YQWO,5=_O5_QWO,5=_O!,rQpO,5=_O!,zQ#tO,5=_O5vQ#tO,5=_O#?OQWO'#JaO#?ZQWO,5=`OOQQ1G.j1G.jO#?`Q$I[O1G.jO#?kQWO1G.jO#?pQWO1G.jO5iQ$I[O1G.jO#?xQbO,5@OO#@SQWO,5@OO#@_QYO,5=gO#@fQWO,5=gO7VQWO,5@OOOQQ1G3P1G3PO`QYO1G3POOQQ1G3V1G3VOOQQ1G3X1G3XO:XQWO1G3ZO#@kQYO1G3]O#DfQYO'#H[OOQQ1G3`1G3`O#DsQWO'#HbO:^QWO'#HdOOQQ1G3f1G3fO#D{QYO1G3fO5iQ$I[O1G3lOOQQ1G3n1G3nOOQ$IS'#Fx'#FxO5iQ$I[O1G3pO5iQ$I[O1G3rOOOS1G/^1G/^O#HyQ`O,5aO#I]QWO1G4|O#IeQWO1G5WO#ImQWO,5?dOLXQYO,5:{O7VQWO,5:{O:^QWO,59}OLXQYO,59}O!,rQpO,59}O#IrQ7^O,59}OOQO,5:{,5:{O#I|Q&jO'#HvO#JdQWO,5?cOOQ$IU1G/h1G/hO#JlQ&jO'#H{O#KQQWO,5?nOOQ$IS1G0f1G0fO!;OQ&jO,59}O#KYQbO1G5XO7VQWO,5>fOOQ$IS'#ES'#ESO#KdQ$ItO'#ETO!?{Q&jO'#D}OOQO'#Hy'#HyO#LOQ&jO,5:hOOQ$IU,5:h,5:hO#LVQ&jO'#D}O#LhQ&jO'#D}O#LoQ&jO'#EYO#LrQ&jO'#ETO#MPQ&jO'#ETO!?{Q&jO'#ETO#MdQWO1G0PO#MiQ`O1G0POOQ$IU1G0P1G0PO){QYO1G0POITQWO1G0POOQ$IU1G0a1G0aO:^QWO1G0aO!,rQpO1G0aO!,zQ#tO1G0aO#MpQ$IfO1G5UO){QYO1G5UO#NQQ$I[O1G5UO#NcQWO1G5TO7VQWO,5>hOOQO,5>h,5>hO#NkQWO,5>hOOQO-E;z-E;zO#NcQWO1G5TO#NyQ$IfO,59jO$!xQ$IfO,5m,5>mO$,iQWO,5>mOOQ$IU1G2P1G2PP$,nQWO'#IRPOQ$IU-Eo,5>oOOQO-Ep,5>pOOQO-Ex,5>xOOQO-E<[-E<[OOQ$IU7+&q7+&qO$4uQWO7+(iO5iQ$I[O7+(iO5qQWO7+(iO$4zQWO7+(iO$5PQWO7+'|OOQ$IS,5>r,5>rOOQ$IS-Et,5>tOOQO-EO,5>OOOQQ7+)Q7+)QOOQQ7+)W7+)WOOQQ7+)[7+)[OOQQ7+)^7+)^OOQO1G5O1G5OO$9eQ7^O1G0gO$9oQWO1G0gOOQO1G/i1G/iO$9zQ7^O1G/iO:^QWO1G/iOLXQYO'#DcOOQO,5>b,5>bOOQO-E;t-E;tOOQO,5>g,5>gOOQO-E;y-E;yO!,rQpO1G/iO:^QWO,5:iOOQO,5:o,5:oO){QYO,5:oO$:UQ$I[O,5:oO$:aQ$I[O,5:oO!,rQpO,5:iOOQO-E;w-E;wOOQ$IU1G0S1G0SO!?{Q&jO,5:iO$:oQ&jO,5:iO$;QQ$ItO,5:oO$;lQ&jO,5:iO!?{Q&jO,5:oOOQO,5:t,5:tO$;sQ&jO,5:oO$cOOQO-E;u-E;uO$CfQbO,5>dO){QYO,5>dOOQO-E;v-E;vO$CpQWO1G5QO$CxQ7^O1G0bO$FPQ7^O1G0mO$FWQ7^O1G0mO$HXQ7^O1G0mO$H`Q7^O1G0mO$JTQ7^O1G0mO$JhQ7^O1G0mO$LuQ7^O1G0mO$L|Q7^O1G0mO$N}Q7^O1G0mO% UQ7^O1G0mO%!yQ7^O1G0mO%#^Q$IfO<kOOOO7+'T7+'TOOOS1G/R1G/ROOQ$IU1G4X1G4XOJdQWO7+'zO%([QWO,5>lO5qQWO,5>lOOQO-EnO%)XQWO,5>nOITQWO,5>nOOQO-Ew,5>wO%,kQWO,5>wO%,pQWO,5>wOOQO-EvOOQO-EWQ7^O7+'WO%>eQ7^O7+'XO%>rQWO,5;xOOQO7+&{7+&{O%>wQ#tO<qOOQO-EsOOQO-E{AN>{OOQOAN>uAN>uO%1gQ$IfOAN>{O:^QWOAN>uO){QYOAN>{O!,rQpOAN>uO&%SQ$I[OAN>{O&%_Q7^O<^O!O&OO~Ox&RO!W&]O!X&UO!Y&UO'^$bO~O]&SOk&SO!Q&VO'g&PO!S'kP!S'vP~P@aO!O'sX!R'sX!]'sX!c'sX'p'sX~O!{'sX#W#PX!S'sX~PAYO!{&^O!O'uX!R'uX~O!R&_O!O'tX~O!O&bO~O!{#eO~PAYOS&fO!T&cO!o&eO']$`O~Oc&kO!d$XO']$`O~Ou$nO!d$mO~O!S&lO~P`Ou!{Ov!{Ox!|O!b!yO!d!zO'fQOP!faZ!faj!fa!R!fa!a!fa!j!fa#[!fa#]!fa#^!fa#_!fa#`!fa#a!fa#b!fa#c!fa#e!fa#g!fa#i!fa#j!fa'p!fa'w!fa'x!fa~O_!fa'W!fa!O!fa!c!fan!fa!T!fa%Q!fa!]!fa~PCcO!c&mO~O!]!wO!{&oO'p&nO!R'rX_'rX'W'rX~O!c'rX~PE{O!R&sO!c'qX~O!c&uO~Ox$tO!T$uO#V&vO']$`O~OPTOQTO]cOb!kOc!jOhcOjTOkcOlcOqTOsTOxRO{cO|cO}cO!TSO!_kO!dUO!gTO!hTO!iTO!jTO!kTO!n!iO#t!lO#x^O']9WO'fQO'oYO'|aO~O]#qOh$OOj#rOk#qOl#qOq$POs9kOx#xO!T#yO!_;RO!d#vO#V9tO#t$TO$_9nO$a9qO$d$UO']&zO'f#sO~O#W&|O~O]#qOh$OOj#rOk#qOl#qOq$POs$QOx#xO!T#yO!_$VO!d#vO#V$WO#t$TO$_$RO$a$SO$d$UO']&zO'f#sO~O'a'mP~PJdO!Q'QO!c'nP~P){O'g'SO'oYO~OP9TOQ9TO]cOb;POc!jOhcOj9TOkcOlcOq9TOs9TOxRO{cO|cO}cO!T!bO!_9VO!dUO!g9TO!h9TO!i9TO!j9TO!k9TO!n!iO#t!lO#x^O']'bO'fQO'oYO'|:}O~O!d!zO~O!R#bO_$]a'W$]a!c$]a!O$]a!T$]a%Q$]a!]$]a~O#d'iO~PITO!]'kO!T'yX#w'yX#z'yX$R'yX~Ou'lO~P! POu'lO!T'yX#w'yX#z'yX$R'yX~O!T'nO#w'rO#z'mO$R'sO~O!Q'vO~PLXO#z#fO$R'yO~Ou$eXx$eX!b$eX'p$eX'w$eX'x$eX~OSfX!RfX!{fX'afX'a$eX~P!!iOk'{O~OR'|O'U'}O'V(PO~Ou(ROx(SO'p#[O'w(UO'x(WO~O'a(QO~P!#rO'a(ZO~O]#qOh$OOj#rOk#qOl#qOq$POs9kOx#xO!T#yO!_;RO!d#vO#V9tO#t$TO$_9nO$a9qO$d$UO'f#sO~O!Q(_O']([O!c'}P~P!$aO#W(aO~O!Q(eO'](bO!O(OP~P!$aOj(sOx(kO!W(qO!X(jO!Y(jO!d(hO!x(rO$w(mO'^$bO'g(gO~O!S(pO~P!&XO!b!yOu'eXx'eX'p'eX'w'eX'x'eX!R'eX!{'eX~O'a'eX#m'eX~P!'QOS(vO!{(uO!R'dX'a'dX~O!R(wO'a'cX~O'](yO~O!d)OO~O']&zO~O!d(hO~Ox$tO!Q!rO!T$uO#U!uO#V!rO']$`O!c'qP~O!]!wO#W)SO~OP#^OZ#dOj#ROu!{Ov!{Ox!|O!a#TO!b!yO!d!zO!j#^O#[#PO#]#QO#^#QO#_#QO#`#SO#a#TO#b#TO#c#TO#e#UO#g#WO#i#YO#j#ZO'fQO'p#[O'w!}O'x#OO~O_!^a!R!^a'W!^a!O!^a!c!^an!^a!T!^a%Q!^a!]!^a~P!)cOS)[O!T&cO!o)ZO%Q)YO'b$cO~O']$zO'a'cP~O!])_O!T'`X_'`X!R'`X'W'`X~O!d$XO'b$cO~O!d$XO']$`O'b$cO~O!]!wO#W&|O~O])jO%R)kO'])gO!S(VP~O!R)lO^(UX~O'g'SO~OZ)pO~O^)qO~O!T$kO']$`O'^$bO^(UP~Ox$tO!Q)vO!R&_O!T$uO']$`O!O'tP~O]&YOk&YO!Q)wO'g'SO!S'vP~O!R)xO_(RX'W(RX~O!{)|O'b$cO~OS*PO!T#yO'b$cO~O!T*RO~Ou*TO!TSO~O!n*YO~Oc*_O~O'](yO!S(TP~Oc$iO~O%RtO']$zO~P8tOZ*eO^*dO~OPTOQTO]cObnOcmOhcOjTOkcOlcOqTOsTOxRO{cO|cO}cO!_kO!dUO!gTO!hTO!iTO!jTO!kTO!nlO#x^O%PqO'fQO'oYO'|aO~O!T!bO#t!lO']9WO~P!1RO^*dO_$[O'W$[O~O_*iO#d*kO%T*kO%U*kO~P){O!d%_O~O%t*pO~O!T*rO~O&V*tO&X*uOP&SaQ&SaX&Sa]&Sa_&Sab&Sac&Sah&Saj&Sak&Sal&Saq&Sas&Sax&Sa{&Sa|&Sa}&Sa!T&Sa!_&Sa!d&Sa!g&Sa!h&Sa!i&Sa!j&Sa!k&Sa!n&Sa#d&Sa#t&Sa#x&Sa%P&Sa%R&Sa%T&Sa%U&Sa%X&Sa%Z&Sa%^&Sa%_&Sa%a&Sa%n&Sa%t&Sa%v&Sa%x&Sa%z&Sa%}&Sa&T&Sa&Z&Sa&]&Sa&_&Sa&a&Sa&c&Sa'S&Sa']&Sa'f&Sa'o&Sa'|&Sa!S&Sa%{&Sa`&Sa&Q&Sa~O']*zO~On*}O~O!O&ia!R&ia~P!)cO!Q+RO!O&iX!R&iX~P){O!R%yO!O'ja~O!O'ja~P>^O!R&_O!O'ta~O!RwX!R!ZX!SwX!S!ZX!]wX!]!ZX!d!ZX!{wX'b!ZX~O!]+WO!{+VO!R#TX!R'lX!S#TX!S'lX!]'lX!d'lX'b'lX~O!]+YO!d$XO'b$cO!R!VX!S!VX~O]&QOk&QOx&RO'g(gO~OP9TOQ9TO]cOb;POc!jOhcOj9TOkcOlcOq9TOs9TOxRO{cO|cO}cO!T!bO!_9VO!dUO!g9TO!h9TO!i9TO!j9TO!k9TO!n!iO#t!lO#x^O'fQO'oYO'|:}O~O']9yO~P!;^O!R+^O!S'kX~O!S+`O~O!]+WO!{+VO!R#TX!S#TX~O!R+aO!S'vX~O!S+cO~O]&QOk&QOx&RO'^$bO'g(gO~O!X+dO!Y+dO~P!>[Ox$tO!Q+fO!T$uO']$`O!O&nX!R&nX~O_+jO!W+mO!X+iO!Y+iO!r+qO!s+oO!t+pO!u+nO!x+rO'^$bO'g(gO'o+gO~O!S+lO~P!?]OS+wO!T&cO!o+vO~O!{+}O!R'ra!c'ra_'ra'W'ra~O!]!wO~P!@gO!R&sO!c'qa~Ox$tO!Q,QO!T$uO#U,SO#V,QO']$`O!R&pX!c&pX~O_#Oi!R#Oi'W#Oi!O#Oi!c#Oin#Oi!T#Oi%Q#Oi!]#Oi~P!)cO#W!za!R!za!c!za!{!za!T!za_!za'W!za!O!za~P!#rO#W'eXP'eXZ'eX_'eXj'eXv'eX!a'eX!d'eX!j'eX#['eX#]'eX#^'eX#_'eX#`'eX#a'eX#b'eX#c'eX#e'eX#g'eX#i'eX#j'eX'W'eX'f'eX!c'eX!O'eX!T'eXn'eX%Q'eX!]'eX~P!'QO!R,]O'a'mX~P!#rO'a,_O~O!R,`O!c'nX~P!)cO!c,cO~O!O,dO~OP#^Ou!{Ov!{Ox!|O!b!yO!d!zO!j#^O'fQOZ#Zi_#Zij#Zi!R#Zi!a#Zi#]#Zi#^#Zi#_#Zi#`#Zi#a#Zi#b#Zi#c#Zi#e#Zi#g#Zi#i#Zi#j#Zi'W#Zi'p#Zi'w#Zi'x#Zi!O#Zi!c#Zin#Zi!T#Zi%Q#Zi!]#Zi~O#[#Zi~P!EtO#[#PO~P!EtOP#^Ou!{Ov!{Ox!|O!b!yO!d!zO!j#^O#[#PO#]#QO#^#QO#_#QO'fQOZ#Zi_#Zi!R#Zi!a#Zi#`#Zi#a#Zi#b#Zi#c#Zi#e#Zi#g#Zi#i#Zi#j#Zi'W#Zi'p#Zi'w#Zi'x#Zi!O#Zi!c#Zin#Zi!T#Zi%Q#Zi!]#Zi~Oj#Zi~P!H`Oj#RO~P!H`OP#^Oj#ROu!{Ov!{Ox!|O!b!yO!d!zO!j#^O#[#PO#]#QO#^#QO#_#QO#`#SO'fQO_#Zi!R#Zi#e#Zi#g#Zi#i#Zi#j#Zi'W#Zi'p#Zi'w#Zi'x#Zi!O#Zi!c#Zin#Zi!T#Zi%Q#Zi!]#Zi~OZ#Zi!a#Zi#a#Zi#b#Zi#c#Zi~P!JzOZ#dO!a#TO#a#TO#b#TO#c#TO~P!JzOP#^OZ#dOj#ROu!{Ov!{Ox!|O!a#TO!b!yO!d!zO!j#^O#[#PO#]#QO#^#QO#_#QO#`#SO#a#TO#b#TO#c#TO#e#UO'fQO_#Zi!R#Zi#g#Zi#i#Zi#j#Zi'W#Zi'p#Zi'x#Zi!O#Zi!c#Zin#Zi!T#Zi%Q#Zi!]#Zi~O'w#Zi~P!MrO'w!}O~P!MrOP#^OZ#dOj#ROu!{Ov!{Ox!|O!a#TO!b!yO!d!zO!j#^O#[#PO#]#QO#^#QO#_#QO#`#SO#a#TO#b#TO#c#TO#e#UO#g#WO'fQO'w!}O_#Zi!R#Zi#i#Zi#j#Zi'W#Zi'p#Zi!O#Zi!c#Zin#Zi!T#Zi%Q#Zi!]#Zi~O'x#Zi~P#!^O'x#OO~P#!^OP#^OZ#dOj#ROu!{Ov!{Ox!|O!a#TO!b!yO!d!zO!j#^O#[#PO#]#QO#^#QO#_#QO#`#SO#a#TO#b#TO#c#TO#e#UO#g#WO#i#YO'fQO'w!}O'x#OO~O_#Zi!R#Zi#j#Zi'W#Zi'p#Zi!O#Zi!c#Zin#Zi!T#Zi%Q#Zi!]#Zi~P#$xOP[XZ[Xj[Xu[Xv[Xx[X!a[X!b[X!d[X!j[X!{[X#WdX#[[X#][X#^[X#_[X#`[X#a[X#b[X#c[X#e[X#g[X#i[X#j[X#o[X'f[X'p[X'w[X'x[X!R[X!S[X~O#m[X~P#']OP#^OZ9iOj9^Ou!{Ov!{Ox!|O!a9`O!b!yO!d!zO!j#^O#[9[O#]9]O#^9]O#_9]O#`9_O#a9`O#b9`O#c9`O#e9aO#g9cO#i9eO#j9fO'fQO'p#[O'w!}O'x#OO~O#m,fO~P#)gOP'iXZ'iXj'iXu'iXv'iXx'iX!a'iX!b'iX!d'iX!j'iX#['iX#]'iX#^'iX#_'iX#`'iX#a'iX#b'iX#e'iX#g'iX#i'iX#j'iX'f'iX'p'iX'w'iX'x'iX!R'iX~O!{9jO#o9jO#c'iX#m'iX!S'iX~P#+bO_&sa!R&sa'W&sa!c&san&sa!O&sa!T&sa%Q&sa!]&sa~P!)cOP#ZiZ#Zi_#Zij#Ziv#Zi!R#Zi!a#Zi!b#Zi!d#Zi!j#Zi#[#Zi#]#Zi#^#Zi#_#Zi#`#Zi#a#Zi#b#Zi#c#Zi#e#Zi#g#Zi#i#Zi#j#Zi'W#Zi'f#Zi!O#Zi!c#Zin#Zi!T#Zi%Q#Zi!]#Zi~P!#rO_#ni!R#ni'W#ni!O#ni!c#nin#ni!T#ni%Q#ni!]#ni~P!)cO#z,hO~O#z,iO~O!]'kO!{,jO!T$OX#w$OX#z$OX$R$OX~O!Q,kO~O!T'nO#w,mO#z'mO$R,nO~O!R9gO!S'hX~P#)gO!S,oO~O$R,qO~OR'|O'U'}O'V,tO~O],wOk,wO!O,xO~O!RdX!]dX!cdX!c$eX'pdX~P!!iO!c-OO~P!#rO!R-PO!]!wO'p&nO!c'}X~O!c-UO~O!O$eX!R$eX!]$lX~P!!iO!R-WO!O(OX~P!#rO!]-YO~O!O-[O~O!Q(_O']$`O!c'}P~Oj-`O!]!wO!d$XO'b$cO'p&nO~O!])_O~O_$[O!R-eO'W$[O~O!S-gO~P!&XO!X-hO!Y-hO'^$bO'g(gO~Ox-jO'g(gO~O!x-kO~O']$zO!R&xX'a&xX~O!R(wO'a'ca~Ou-pOv-pOx-qO'pra'wra'xra!Rra!{ra~O'ara#mra~P#6qOu(ROx(SO'p$^a'w$^a'x$^a!R$^a!{$^a~O'a$^a#m$^a~P#7gOu(ROx(SO'p$`a'w$`a'x$`a!R$`a!{$`a~O'a$`a#m$`a~P#8YO]-rO~O#W-sO~O'a$na!R$na#m$na!{$na~P!#rO#W-vO~OS.PO!T&cO!o.OO%Q-}O~O'a.QO~O]#qOj#rOk#qOl#qOq$POs9kOx#xO!T#yO!_;RO!d#vO#V9tO#t$TO$_9nO$a9qO$d$UO'f#sO~Oh.SO'].RO~P#:PO!])_O!T'`a_'`a!R'`a'W'`a~O#W.YO~OZ[X!RdX!SdX~O!R.ZO!S(VX~O!S.]O~OZ.^O~O].`O'])gO~O!T$kO']$`O^'QX!R'QX~O!R)lO^(Ua~O!c.cO~P!)cO].eO~OZ.fO~O^.gO~OS.PO!T&cO!o.OO%Q-}O'b$cO~O!R)xO_(Ra'W(Ra~O!{.mO~OS.pO!T#yO~O'g'SO!S(SP~OS.zO!T.vO!o.yO%Q.xO'b$cO~OZ/UO!R/SO!S(TX~O!S/VO~O^/XO_$[O'W$[O~O]/YO~O]/ZO'](yO~O#c/[O%r/]O~P0zO!{#eO#c/[O%r/]O~O_/^O~P){O_/`O~O%{/dOP%yiQ%yiX%yi]%yi_%yib%yic%yih%yij%yik%yil%yiq%yis%yix%yi{%yi|%yi}%yi!T%yi!_%yi!d%yi!g%yi!h%yi!i%yi!j%yi!k%yi!n%yi#d%yi#t%yi#x%yi%P%yi%R%yi%T%yi%U%yi%X%yi%Z%yi%^%yi%_%yi%a%yi%n%yi%t%yi%v%yi%x%yi%z%yi%}%yi&T%yi&Z%yi&]%yi&_%yi&a%yi&c%yi'S%yi']%yi'f%yi'o%yi'|%yi!S%yi`%yi&Q%yi~O`/jO!S/hO&Q/iO~P`O!TSO!d/lO~O&X*uOP&SiQ&SiX&Si]&Si_&Sib&Sic&Sih&Sij&Sik&Sil&Siq&Sis&Six&Si{&Si|&Si}&Si!T&Si!_&Si!d&Si!g&Si!h&Si!i&Si!j&Si!k&Si!n&Si#d&Si#t&Si#x&Si%P&Si%R&Si%T&Si%U&Si%X&Si%Z&Si%^&Si%_&Si%a&Si%n&Si%t&Si%v&Si%x&Si%z&Si%}&Si&T&Si&Z&Si&]&Si&_&Si&a&Si&c&Si'S&Si']&Si'f&Si'o&Si'|&Si!S&Si%{&Si`&Si&Q&Si~O!R#bOn$]a~O!O&ii!R&ii~P!)cO!R%yO!O'ji~O!R&_O!O'ti~O!O/rO~O!R!Va!S!Va~P#)gO]&QOk&QO!Q/xO'g(gO!R&jX!S&jX~P@aO!R+^O!S'ka~O]&YOk&YO!Q)wO'g'SO!R&oX!S&oX~O!R+aO!S'va~O!O'ui!R'ui~P!)cO_$[O!]!wO!d$XO!j0SO!{0QO'W$[O'b$cO'p&nO~O!S0VO~P!?]O!X0WO!Y0WO'^$bO'g(gO'o+gO~O!W0XO~P#LVO!TSO!W0XO!u0ZO!x0[O~P#LVO!W0XO!s0^O!t0^O!u0ZO!x0[O~P#LVO!T&cO~O!T&cO~P!#rO!R'ri!c'ri_'ri'W'ri~P!)cO!{0gO!R'ri!c'ri_'ri'W'ri~O!R&sO!c'qi~Ox$tO!T$uO#V0iO']$`O~O#WraPraZra_rajra!ara!bra!dra!jra#[ra#]ra#^ra#_ra#`ra#ara#bra#cra#era#gra#ira#jra'Wra'fra!cra!Ora!Tranra%Qra!]ra~P#6qO#W$^aP$^aZ$^a_$^aj$^av$^a!a$^a!b$^a!d$^a!j$^a#[$^a#]$^a#^$^a#_$^a#`$^a#a$^a#b$^a#c$^a#e$^a#g$^a#i$^a#j$^a'W$^a'f$^a!c$^a!O$^a!T$^an$^a%Q$^a!]$^a~P#7gO#W$`aP$`aZ$`a_$`aj$`av$`a!a$`a!b$`a!d$`a!j$`a#[$`a#]$`a#^$`a#_$`a#`$`a#a$`a#b$`a#c$`a#e$`a#g$`a#i$`a#j$`a'W$`a'f$`a!c$`a!O$`a!T$`an$`a%Q$`a!]$`a~P#8YO#W$naP$naZ$na_$naj$nav$na!R$na!a$na!b$na!d$na!j$na#[$na#]$na#^$na#_$na#`$na#a$na#b$na#c$na#e$na#g$na#i$na#j$na'W$na'f$na!c$na!O$na!T$na!{$nan$na%Q$na!]$na~P!#rO_#Oq!R#Oq'W#Oq!O#Oq!c#Oqn#Oq!T#Oq%Q#Oq!]#Oq~P!)cO!R&kX'a&kX~PJdO!R,]O'a'ma~O!Q0qO!R&lX!c&lX~P){O!R,`O!c'na~O!R,`O!c'na~P!)cO#m!fa!S!fa~PCcO#m!^a!R!^a!S!^a~P#)gO!T1UO#x^O$P1VO~O!S1ZO~On1[O~P!#rO_$Yq!R$Yq'W$Yq!O$Yq!c$Yqn$Yq!T$Yq%Q$Yq!]$Yq~P!)cO!O1]O~O],wOk,wO~Ou(ROx(SO'x(WO'p$xi'w$xi!R$xi!{$xi~O'a$xi#m$xi~P$,vOu(ROx(SO'p$zi'w$zi'x$zi!R$zi!{$zi~O'a$zi#m$zi~P$-iO#m1^O~P!#rO!Q1`O']$`O!R&tX!c&tX~O!R-PO!c'}a~O!R-PO!]!wO!c'}a~O!R-PO!]!wO'p&nO!c'}a~O'a$gi!R$gi#m$gi!{$gi~P!#rO!Q1gO'](bO!O&vX!R&vX~P!$aO!R-WO!O(Oa~O!R-WO!O(Oa~P!#rO!]!wO~O!]!wO#c1oO~Oj1rO!]!wO'p&nO~O!R'di'a'di~P!#rO!{1uO!R'di'a'di~P!#rO!c1xO~O_$Zq!R$Zq'W$Zq!O$Zq!c$Zqn$Zq!T$Zq%Q$Zq!]$Zq~P!)cO!R1|O!T(PX~P!#rO!T&cO%Q2PO~O!T&cO%Q2PO~P!#rO!T$eX$u[X_$eX!R$eX'W$eX~P!!iO$u2TOugXxgX!TgX'pgX'wgX'xgX_gX!RgX'WgX~O$u2TO~O]2ZO%R2[O'])gO!R'PX!S'PX~O!R.ZO!S(Va~OZ2`O~O^2aO~O]2dO~OS2fO!T&cO!o2eO%Q2PO~O_$[O'W$[O~P!#rO!T#yO~P!#rO!R2kO!{2mO!S(SX~O!S2nO~Ox;]O!W2wO!X2pO!Y2pO!r2vO!s2uO!t2uO!x2tO'^$bO'g(gO'o+gO~O!S2sO~P$6QOS3OO!T.vO!o2}O%Q2|O~OS3OO!T.vO!o2}O%Q2|O'b$cO~O'](yO!R'OX!S'OX~O!R/SO!S(Ta~O]3YO'g3XO~O]3ZO~O^3]O~O!c3`O~P){O_3bO~O_3bO~P){O#c3dO%r3eO~PE{O`/jO!S3iO&Q/iO~P`O!]3kO~O!R#Ti!S#Ti~P#)gO!{3mO!R#Ti!S#Ti~O!R!Vi!S!Vi~P#)gO_$[O!{3tO'W$[O~O_$[O!]!wO!{3tO'W$[O~O!X3xO!Y3xO'^$bO'g(gO'o+gO~O_$[O!]!wO!d$XO!j3yO!{3tO'W$[O'b$cO'p&nO~O!W3zO~P$:oO!W3zO!u3}O!x4OO~P$:oO_$[O!]!wO!j3yO!{3tO'W$[O'p&nO~O!R'rq!c'rq_'rq'W'rq~P!)cO!R&sO!c'qq~O#W$xiP$xiZ$xi_$xij$xiv$xi!a$xi!b$xi!d$xi!j$xi#[$xi#]$xi#^$xi#_$xi#`$xi#a$xi#b$xi#c$xi#e$xi#g$xi#i$xi#j$xi'W$xi'f$xi!c$xi!O$xi!T$xin$xi%Q$xi!]$xi~P$,vO#W$ziP$ziZ$zi_$zij$ziv$zi!a$zi!b$zi!d$zi!j$zi#[$zi#]$zi#^$zi#_$zi#`$zi#a$zi#b$zi#c$zi#e$zi#g$zi#i$zi#j$zi'W$zi'f$zi!c$zi!O$zi!T$zin$zi%Q$zi!]$zi~P$-iO#W$giP$giZ$gi_$gij$giv$gi!R$gi!a$gi!b$gi!d$gi!j$gi#[$gi#]$gi#^$gi#_$gi#`$gi#a$gi#b$gi#c$gi#e$gi#g$gi#i$gi#j$gi'W$gi'f$gi!c$gi!O$gi!T$gi!{$gin$gi%Q$gi!]$gi~P!#rO!R&ka'a&ka~P!#rO!R&la!c&la~P!)cO!R,`O!c'ni~O#m#Oi!R#Oi!S#Oi~P#)gOP#^Ou!{Ov!{Ox!|O!b!yO!d!zO!j#^O'fQOZ#Zij#Zi!a#Zi#]#Zi#^#Zi#_#Zi#`#Zi#a#Zi#b#Zi#c#Zi#e#Zi#g#Zi#i#Zi#j#Zi#m#Zi'p#Zi'w#Zi'x#Zi!R#Zi!S#Zi~O#[#Zi~P$DVO#[9[O~P$DVOP#^Ou!{Ov!{Ox!|O!b!yO!d!zO!j#^O#[9[O#]9]O#^9]O#_9]O'fQOZ#Zi!a#Zi#`#Zi#a#Zi#b#Zi#c#Zi#e#Zi#g#Zi#i#Zi#j#Zi#m#Zi'p#Zi'w#Zi'x#Zi!R#Zi!S#Zi~Oj#Zi~P$F_Oj9^O~P$F_OP#^Oj9^Ou!{Ov!{Ox!|O!b!yO!d!zO!j#^O#[9[O#]9]O#^9]O#_9]O#`9_O'fQO#e#Zi#g#Zi#i#Zi#j#Zi#m#Zi'p#Zi'w#Zi'x#Zi!R#Zi!S#Zi~OZ#Zi!a#Zi#a#Zi#b#Zi#c#Zi~P$HgOZ9iO!a9`O#a9`O#b9`O#c9`O~P$HgOP#^OZ9iOj9^Ou!{Ov!{Ox!|O!a9`O!b!yO!d!zO!j#^O#[9[O#]9]O#^9]O#_9]O#`9_O#a9`O#b9`O#c9`O#e9aO'fQO#g#Zi#i#Zi#j#Zi#m#Zi'p#Zi'x#Zi!R#Zi!S#Zi~O'w#Zi~P$J{O'w!}O~P$J{OP#^OZ9iOj9^Ou!{Ov!{Ox!|O!a9`O!b!yO!d!zO!j#^O#[9[O#]9]O#^9]O#_9]O#`9_O#a9`O#b9`O#c9`O#e9aO#g9cO'fQO'w!}O#i#Zi#j#Zi#m#Zi'p#Zi!R#Zi!S#Zi~O'x#Zi~P$MTO'x#OO~P$MTOP#^OZ9iOj9^Ou!{Ov!{Ox!|O!a9`O!b!yO!d!zO!j#^O#[9[O#]9]O#^9]O#_9]O#`9_O#a9`O#b9`O#c9`O#e9aO#g9cO#i9eO'fQO'w!}O'x#OO~O#j#Zi#m#Zi'p#Zi!R#Zi!S#Zi~P% ]O_#ky!R#ky'W#ky!O#ky!c#kyn#ky!T#ky%Q#ky!]#ky~P!)cOP#ZiZ#Zij#Ziv#Zi!a#Zi!b#Zi!d#Zi!j#Zi#[#Zi#]#Zi#^#Zi#_#Zi#`#Zi#a#Zi#b#Zi#c#Zi#e#Zi#g#Zi#i#Zi#j#Zi#m#Zi'f#Zi!R#Zi!S#Zi~P!#rO!b!yOu'eXx'eX'p'eX'w'eX'x'eX!S'eX~OP'eXZ'eXj'eXv'eX!a'eX!d'eX!j'eX#['eX#]'eX#^'eX#_'eX#`'eX#a'eX#b'eX#c'eX#e'eX#g'eX#i'eX#j'eX#m'eX'f'eX!R'eX~P%%mO#m#ni!R#ni!S#ni~P#)gO!S4`O~O!R&sa!S&sa~P#)gO!]!wO'p&nO!R&ta!c&ta~O!R-PO!c'}i~O!R-PO!]!wO!c'}i~O!O&va!R&va~P!#rO!]4gO~O!R-WO!O(Oi~P!#rO!R-WO!O(Oi~O!O4kO~O!]!wO#c4pO~Oj4qO!]!wO'p&nO~O!O4sO~O'a$iq!R$iq#m$iq!{$iq~P!#rO_$Zy!R$Zy'W$Zy!O$Zy!c$Zyn$Zy!T$Zy%Q$Zy!]$Zy~P!)cO!R1|O!T(Pa~O!T&cO%Q4xO~O!T&cO%Q4xO~P!#rO_#Oy!R#Oy'W#Oy!O#Oy!c#Oyn#Oy!T#Oy%Q#Oy!]#Oy~P!)cOZ4{O~O]4}O'])gO~O!R.ZO!S(Vi~O]5QO~O^5RO~O'g'SO!R&{X!S&{X~O!R2kO!S(Sa~O!S5`O~P$6QOx;^O'g(gO'o+gO~O!W5cO!X5bO!Y5bO!x0[O'^$bO'g(gO'o+gO~O!s5dO!t5dO~P%.RO!X5bO!Y5bO'^$bO'g(gO'o+gO~O!T.vO~O!T.vO%Q5fO~O!T.vO%Q5fO~P!#rOS5kO!T.vO!o5jO%Q5fO~OZ5pO!R'Oa!S'Oa~O!R/SO!S(Ti~O]5sO~O!c5tO~O!c5uO~O!c5vO~O!c5vO~P){O_5xO~O!]5{O~O!c5|O~O!R'ui!S'ui~P#)gO_$[O'W$[O~P!)cO_$[O!{6RO'W$[O~O_$[O!]!wO!{6RO'W$[O~O!X6WO!Y6WO'^$bO'g(gO'o+gO~O_$[O!]!wO!j6XO!{6RO'W$[O'p&nO~O!d$XO'b$cO~P%2mO!W6YO~P%2[O!R'ry!c'ry_'ry'W'ry~P!)cO#W$iqP$iqZ$iq_$iqj$iqv$iq!R$iq!a$iq!b$iq!d$iq!j$iq#[$iq#]$iq#^$iq#_$iq#`$iq#a$iq#b$iq#c$iq#e$iq#g$iq#i$iq#j$iq'W$iq'f$iq!c$iq!O$iq!T$iq!{$iqn$iq%Q$iq!]$iq~P!#rO!R&li!c&li~P!)cO#m#Oq!R#Oq!S#Oq~P#)gOu-pOv-pOx-qO'pra'wra'xra!Sra~OPraZrajra!ara!bra!dra!jra#[ra#]ra#^ra#_ra#`ra#ara#bra#cra#era#gra#ira#jra#mra'fra!Rra~P%6eOu(ROx(SO'p$^a'w$^a'x$^a!S$^a~OP$^aZ$^aj$^av$^a!a$^a!b$^a!d$^a!j$^a#[$^a#]$^a#^$^a#_$^a#`$^a#a$^a#b$^a#c$^a#e$^a#g$^a#i$^a#j$^a#m$^a'f$^a!R$^a~P%8fOu(ROx(SO'p$`a'w$`a'x$`a!S$`a~OP$`aZ$`aj$`av$`a!a$`a!b$`a!d$`a!j$`a#[$`a#]$`a#^$`a#_$`a#`$`a#a$`a#b$`a#c$`a#e$`a#g$`a#i$`a#j$`a#m$`a'f$`a!R$`a~P%:gOP$naZ$naj$nav$na!a$na!b$na!d$na!j$na#[$na#]$na#^$na#_$na#`$na#a$na#b$na#c$na#e$na#g$na#i$na#j$na#m$na'f$na!R$na!S$na~P!#rO#m$Yq!R$Yq!S$Yq~P#)gO#m$Zq!R$Zq!S$Zq~P#)gO!S6dO~O'a$|y!R$|y#m$|y!{$|y~P!#rO!]!wO!R&ti!c&ti~O!]!wO'p&nO!R&ti!c&ti~O!R-PO!c'}q~O!O&vi!R&vi~P!#rO!R-WO!O(Oq~O!O6jO~P!#rO!O6jO~O!R'dy'a'dy~P!#rO!R&ya!T&ya~P!#rO!T$tq_$tq!R$tq'W$tq~P!#rOZ6qO~O!R.ZO!S(Vq~O]6tO~O!T&cO%Q6uO~O!T&cO%Q6uO~P!#rO!{6vO!R&{a!S&{a~O!R2kO!S(Si~P#)gO!X6|O!Y6|O'^$bO'g(gO'o+gO~O!W7OO!x4OO~P%BkO!T.vO%Q7RO~O!T.vO%Q7RO~P!#rO]7YO'g7XO~O!R/SO!S(Tq~O!c7[O~O!c7[O~P){O!c7^O~O!c7_O~O!R#Ty!S#Ty~P#)gO_$[O!{7eO'W$[O~O_$[O!]!wO!{7eO'W$[O~O!X7hO!Y7hO'^$bO'g(gO'o+gO~O_$[O!]!wO!j7iO!{7eO'W$[O'p&nO~O#W$|yP$|yZ$|y_$|yj$|yv$|y!R$|y!a$|y!b$|y!d$|y!j$|y#[$|y#]$|y#^$|y#_$|y#`$|y#a$|y#b$|y#c$|y#e$|y#g$|y#i$|y#j$|y'W$|y'f$|y!c$|y!O$|y!T$|y!{$|yn$|y%Q$|y!]$|y~P!#rO#m#ky!R#ky!S#ky~P#)gOP$giZ$gij$giv$gi!a$gi!b$gi!d$gi!j$gi#[$gi#]$gi#^$gi#_$gi#`$gi#a$gi#b$gi#c$gi#e$gi#g$gi#i$gi#j$gi#m$gi'f$gi!R$gi!S$gi~P!#rOu(ROx(SO'x(WO'p$xi'w$xi!S$xi~OP$xiZ$xij$xiv$xi!a$xi!b$xi!d$xi!j$xi#[$xi#]$xi#^$xi#_$xi#`$xi#a$xi#b$xi#c$xi#e$xi#g$xi#i$xi#j$xi#m$xi'f$xi!R$xi~P%JROu(ROx(SO'p$zi'w$zi'x$zi!S$zi~OP$ziZ$zij$ziv$zi!a$zi!b$zi!d$zi!j$zi#[$zi#]$zi#^$zi#_$zi#`$zi#a$zi#b$zi#c$zi#e$zi#g$zi#i$zi#j$zi#m$zi'f$zi!R$zi~P%LSO#m$Zy!R$Zy!S$Zy~P#)gO#m#Oy!R#Oy!S#Oy~P#)gO!]!wO!R&tq!c&tq~O!R-PO!c'}y~O!O&vq!R&vq~P!#rO!O7mO~P!#rO!R.ZO!S(Vy~O!R2kO!S(Sq~O!X7yO!Y7yO'^$bO'g(gO'o+gO~O!T.vO%Q7|O~O!T.vO%Q7|O~P!#rO!c8PO~O_$[O!{8UO'W$[O~O_$[O!]!wO!{8UO'W$[O~OP$iqZ$iqj$iqv$iq!a$iq!b$iq!d$iq!j$iq#[$iq#]$iq#^$iq#_$iq#`$iq#a$iq#b$iq#c$iq#e$iq#g$iq#i$iq#j$iq#m$iq'f$iq!R$iq!S$iq~P!#rO!R&{q!S&{q~P#)gO_$[O!{8hO'W$[O~OP$|yZ$|yj$|yv$|y!a$|y!b$|y!d$|y!j$|y#[$|y#]$|y#^$|y#_$|y#`$|y#a$|y#b$|y#c$|y#e$|y#g$|y#i$|y#j$|y#m$|y'f$|y!R$|y!S$|y~P!#rO!S!za!W!za!X!za!Y!za!r!za!s!za!t!za!x!za'^!za'g!za'o!za~P!#rO!W'eX!X'eX!Y'eX!r'eX!s'eX!t'eX!x'eX'^'eX'g'eX'o'eX~P%%mO!Wra!Xra!Yra!rra!sra!tra!xra'^ra'gra'ora~P%6eO!W$^a!X$^a!Y$^a!r$^a!s$^a!t$^a!x$^a'^$^a'g$^a'o$^a~P%8fO!W$`a!X$`a!Y$`a!r$`a!s$`a!t$`a!x$`a'^$`a'g$`a'o$`a~P%:gO!S$na!W$na!X$na!Y$na!r$na!s$na!t$na!x$na'^$na'g$na'o$na~P!#rO!W$xi!X$xi!Y$xi!r$xi!s$xi!t$xi!x$xi'^$xi'g$xi'o$xi~P%JRO!W$zi!X$zi!Y$zi!r$zi!s$zi!t$zi!x$zi'^$zi'g$zi'o$zi~P%LSO!S$gi!W$gi!X$gi!Y$gi!r$gi!s$gi!t$gi!x$gi'^$gi'g$gi'o$gi~P!#rO!S$iq!W$iq!X$iq!Y$iq!r$iq!s$iq!t$iq!x$iq'^$iq'g$iq'o$iq~P!#rO!S$|y!W$|y!X$|y!Y$|y!r$|y!s$|y!t$|y!x$|y'^$|y'g$|y'o$|y~P!#rOn'hX~P.jOn[X!O[X!c[X%r[X!T[X%Q[X!][X~P$zO!]dX!c[X!cdX'pdX~P;aOP9TOQ9TO]cOb;POc!jOhcOj9TOkcOlcOq9TOs9TOxRO{cO|cO}cO!TSO!_9VO!dUO!g9TO!h9TO!i9TO!j9TO!k9TO!n!iO#t!lO#x^O']'bO'fQO'oYO'|:}O~O]#qOh$OOj#rOk#qOl#qOq$POs9lOx#xO!T#yO!_;SO!d#vO#V9uO#t$TO$_9oO$a9rO$d$UO']&zO'f#sO~O!R9gO!S$]a~O]#qOh$OOj#rOk#qOl#qOq$POs9mOx#xO!T#yO!_;TO!d#vO#V9vO#t$TO$_9pO$a9sO$d$UO']&zO'f#sO~O#d'iO~P&3xO!S[X!SdX~P;aO!]9ZO~O#W9YO~O!]!wO#W9YO~O!{9jO~O#c9`O~O!{9wO!R'uX!S'uX~O!{9jO!R'sX!S'sX~O#W9xO~O'a9zO~P!#rO#W:RO~O#W:SO~O#W:TO~O!]!wO#W:UO~O!]!wO#W9xO~O#m:VO~P#)gO#W:WO~O#W:XO~O#W:YO~O#W:ZO~O#W:[O~O#m:]O~P!#rO#m:^O~P!#rO#m:_O~P!#rO!O:`O~O!O:aO~P!#rO!O:aO~O!O:bO~P!#rO!]!wO#c;YO~O!]!wO#c;[O~O#x~!b!r!t!u#U#V'|$_$a$d$u%P%Q%R%X%Z%^%_%a%c~UT#x'|#]}'Y'Z#z'Y']'g~", - goto: "#Hc(ZPPPPPPPP([P(lP*`PPPP-zPP.a3s5g5zP5zPPP5zP7t5zP5zP7xPP8OP8dk|}?O}!O>k!O!P?`!P!QCl!Q!R!0[!R![!1q![!]!7s!]!^!8V!^!_!8g!_!`!9d!`!a!:[!a!b!U#R#S2`#S#T!>i#T#o2`#o#p!>y#p#q!?O#q#r!?f#r#s!?x#s$f%T$f$g%c$g#BY2`#BY#BZ!@Y#BZ$IS2`$IS$I_!@Y$I_$I|2`$I|$I}!Bq$I}$JO!Bq$JO$JT2`$JT$JU!@Y$JU$KV2`$KV$KW!@Y$KW&FU2`&FU&FV!@Y&FV?HT2`?HT?HU!@Y?HU~2`W%YR$UWO!^%T!_#o%T#p~%T7Z%jg$UW'Y7ROX%TXY%cYZ%TZ[%c[p%Tpq%cq!^%T!_#o%T#p$f%T$f$g%c$g#BY%T#BY#BZ%c#BZ$IS%T$IS$I_%c$I_$JT%T$JT$JU%c$JU$KV%T$KV$KW%c$KW&FU%T&FU&FV%c&FV?HT%T?HT?HU%c?HU~%T7Z'YR$UW'Z7RO!^%T!_#o%T#p~%T$T'jS$UW!j#{O!^%T!_!`'v!`#o%T#p~%T$O'}S#e#v$UWO!^%T!_!`(Z!`#o%T#p~%T$O(bR#e#v$UWO!^%T!_#o%T#p~%T'u(rZ$UW]!ROY(kYZ)eZr(krs*rs!^(k!^!_+U!_#O(k#O#P-b#P#o(k#o#p+U#p~(k&r)jV$UWOr)ers*Ps!^)e!^!_*a!_#o)e#o#p*a#p~)e&r*WR$P&j$UWO!^%T!_#o%T#p~%T&j*dROr*ars*ms~*a&j*rO$P&j'u*{R$P&j$UW]!RO!^%T!_#o%T#p~%T'm+ZV]!ROY+UYZ*aZr+Urs+ps#O+U#O#P+w#P~+U'm+wO$P&j]!R'm+zROr+Urs,Ts~+U'm,[U$P&j]!ROY,nZr,nrs-Vs#O,n#O#P-[#P~,n!R,sU]!ROY,nZr,nrs-Vs#O,n#O#P-[#P~,n!R-[O]!R!R-_PO~,n'u-gV$UWOr(krs-|s!^(k!^!_+U!_#o(k#o#p+U#p~(k'u.VZ$P&j$UW]!ROY.xYZ%TZr.xrs/rs!^.x!^!_,n!_#O.x#O#P0S#P#o.x#o#p,n#p~.x!Z/PZ$UW]!ROY.xYZ%TZr.xrs/rs!^.x!^!_,n!_#O.x#O#P0S#P#o.x#o#p,n#p~.x!Z/yR$UW]!RO!^%T!_#o%T#p~%T!Z0XT$UWO!^.x!^!_,n!_#o.x#o#p,n#p~.x2k0mZ$UWOt%Ttu1`u!^%T!_!c%T!c!}1`!}#R%T#R#S1`#S#T%T#T#o1`#p$g%T$g~1`2k1g]$UW'o2cOt%Ttu1`u!Q%T!Q![1`![!^%T!_!c%T!c!}1`!}#R%T#R#S1`#S#T%T#T#o1`#p$g%T$g~1`7Z2k_$UW#zS']%k'g2bOt%Ttu2`u}%T}!O3j!O!Q%T!Q![2`![!^%T!_!c%T!c!}2`!}#R%T#R#S2`#S#T%T#T#o2`#p$g%T$g~2`[3q_$UW#zSOt%Ttu3ju}%T}!O3j!O!Q%T!Q![3j![!^%T!_!c%T!c!}3j!}#R%T#R#S3j#S#T%T#T#o3j#p$g%T$g~3j$O4wS#^#v$UWO!^%T!_!`5T!`#o%T#p~%T$O5[R$UW#o#vO!^%T!_#o%T#p~%T6d5lU'x6[$UWOv%Tvw6Ow!^%T!_!`5T!`#o%T#p~%T$O6VS$UW#i#vO!^%T!_!`5T!`#o%T#p~%T'u6jZ$UW]!ROY6cYZ7]Zw6cwx*rx!^6c!^!_8T!_#O6c#O#P:T#P#o6c#o#p8T#p~6c&r7bV$UWOw7]wx*Px!^7]!^!_7w!_#o7]#o#p7w#p~7]&j7zROw7wwx*mx~7w'm8YV]!ROY8TYZ7wZw8Twx+px#O8T#O#P8o#P~8T'm8rROw8Twx8{x~8T'm9SU$P&j]!ROY9fZw9fwx-Vx#O9f#O#P9}#P~9f!R9kU]!ROY9fZw9fwx-Vx#O9f#O#P9}#P~9f!R:QPO~9f'u:YV$UWOw6cwx:ox!^6c!^!_8T!_#o6c#o#p8T#p~6c'u:xZ$P&j$UW]!ROY;kYZ%TZw;kwx/rx!^;k!^!_9f!_#O;k#O#PW{!^%T!_!`5T!`#o%T#p~%T$O>_S#[#v$UWO!^%T!_!`5T!`#o%T#p~%T$u>rSj$m$UWO!^%T!_!`5T!`#o%T#p~%T&i?VR!R&a$UWO!^%T!_#o%T#p~%T7Z?gVu6`$UWO!O%T!O!P?|!P!Q%T!Q![@r![!^%T!_#o%T#p~%Ty@RT$UWO!O%T!O!P@b!P!^%T!_#o%T#p~%Ty@iR!Qq$UWO!^%T!_#o%T#p~%Ty@yZ$UWkqO!Q%T!Q![@r![!^%T!_!g%T!g!hAl!h#R%T#R#S@r#S#X%T#X#YAl#Y#o%T#p~%TyAqZ$UWO{%T{|Bd|}%T}!OBd!O!Q%T!Q![CO![!^%T!_#R%T#R#SCO#S#o%T#p~%TyBiV$UWO!Q%T!Q![CO![!^%T!_#R%T#R#SCO#S#o%T#p~%TyCVV$UWkqO!Q%T!Q![CO![!^%T!_#R%T#R#SCO#S#o%T#p~%T7ZCs`$UW#]#vOYDuYZ%TZzDuz{Jl{!PDu!P!Q!-e!Q!^Du!^!_Fx!_!`!.^!`!a!/]!a!}Du!}#OHq#O#PJQ#P#oDu#o#pFx#p~DuXD|[$UW}POYDuYZ%TZ!PDu!P!QEr!Q!^Du!^!_Fx!_!}Du!}#OHq#O#PJQ#P#oDu#o#pFx#p~DuXEy_$UW}PO!^%T!_#Z%T#Z#[Er#[#]%T#]#^Er#^#a%T#a#bEr#b#g%T#g#hEr#h#i%T#i#jEr#j#m%T#m#nEr#n#o%T#p~%TPF}V}POYFxZ!PFx!P!QGd!Q!}Fx!}#OG{#O#PHh#P~FxPGiU}P#Z#[Gd#]#^Gd#a#bGd#g#hGd#i#jGd#m#nGdPHOTOYG{Z#OG{#O#PH_#P#QFx#Q~G{PHbQOYG{Z~G{PHkQOYFxZ~FxXHvY$UWOYHqYZ%TZ!^Hq!^!_G{!_#OHq#O#PIf#P#QDu#Q#oHq#o#pG{#p~HqXIkV$UWOYHqYZ%TZ!^Hq!^!_G{!_#oHq#o#pG{#p~HqXJVV$UWOYDuYZ%TZ!^Du!^!_Fx!_#oDu#o#pFx#p~Du7ZJs^$UW}POYJlYZKoZzJlz{NQ{!PJl!P!Q!,R!Q!^Jl!^!_!!]!_!}Jl!}#O!'|#O#P!+a#P#oJl#o#p!!]#p~Jl7ZKtV$UWOzKoz{LZ{!^Ko!^!_M]!_#oKo#o#pM]#p~Ko7ZL`X$UWOzKoz{LZ{!PKo!P!QL{!Q!^Ko!^!_M]!_#oKo#o#pM]#p~Ko7ZMSR$UWU7RO!^%T!_#o%T#p~%T7RM`ROzM]z{Mi{~M]7RMlTOzM]z{Mi{!PM]!P!QM{!Q~M]7RNQOU7R7ZNX^$UW}POYJlYZKoZzJlz{NQ{!PJl!P!Q! T!Q!^Jl!^!_!!]!_!}Jl!}#O!'|#O#P!+a#P#oJl#o#p!!]#p~Jl7Z! ^_$UWU7R}PO!^%T!_#Z%T#Z#[Er#[#]%T#]#^Er#^#a%T#a#bEr#b#g%T#g#hEr#h#i%T#i#jEr#j#m%T#m#nEr#n#o%T#p~%T7R!!bY}POY!!]YZM]Zz!!]z{!#Q{!P!!]!P!Q!&x!Q!}!!]!}#O!$`#O#P!&f#P~!!]7R!#VY}POY!!]YZM]Zz!!]z{!#Q{!P!!]!P!Q!#u!Q!}!!]!}#O!$`#O#P!&f#P~!!]7R!#|UU7R}P#Z#[Gd#]#^Gd#a#bGd#g#hGd#i#jGd#m#nGd7R!$cWOY!$`YZM]Zz!$`z{!${{#O!$`#O#P!&S#P#Q!!]#Q~!$`7R!%OYOY!$`YZM]Zz!$`z{!${{!P!$`!P!Q!%n!Q#O!$`#O#P!&S#P#Q!!]#Q~!$`7R!%sTU7ROYG{Z#OG{#O#PH_#P#QFx#Q~G{7R!&VTOY!$`YZM]Zz!$`z{!${{~!$`7R!&iTOY!!]YZM]Zz!!]z{!#Q{~!!]7R!&}_}POzM]z{Mi{#ZM]#Z#[!&x#[#]M]#]#^!&x#^#aM]#a#b!&x#b#gM]#g#h!&x#h#iM]#i#j!&x#j#mM]#m#n!&x#n~M]7Z!(R[$UWOY!'|YZKoZz!'|z{!(w{!^!'|!^!_!$`!_#O!'|#O#P!*o#P#QJl#Q#o!'|#o#p!$`#p~!'|7Z!(|^$UWOY!'|YZKoZz!'|z{!(w{!P!'|!P!Q!)x!Q!^!'|!^!_!$`!_#O!'|#O#P!*o#P#QJl#Q#o!'|#o#p!$`#p~!'|7Z!*PY$UWU7ROYHqYZ%TZ!^Hq!^!_G{!_#OHq#O#PIf#P#QDu#Q#oHq#o#pG{#p~Hq7Z!*tX$UWOY!'|YZKoZz!'|z{!(w{!^!'|!^!_!$`!_#o!'|#o#p!$`#p~!'|7Z!+fX$UWOYJlYZKoZzJlz{NQ{!^Jl!^!_!!]!_#oJl#o#p!!]#p~Jl7Z!,Yc$UW}POzKoz{LZ{!^Ko!^!_M]!_#ZKo#Z#[!,R#[#]Ko#]#^!,R#^#aKo#a#b!,R#b#gKo#g#h!,R#h#iKo#i#j!,R#j#mKo#m#n!,R#n#oKo#o#pM]#p~Ko7Z!-lV$UWT7ROY!-eYZ%TZ!^!-e!^!_!.R!_#o!-e#o#p!.R#p~!-e7R!.WQT7ROY!.RZ~!.R$P!.g[$UW#o#v}POYDuYZ%TZ!PDu!P!QEr!Q!^Du!^!_Fx!_!}Du!}#OHq#O#PJQ#P#oDu#o#pFx#p~Du]!/f[#wS$UW}POYDuYZ%TZ!PDu!P!QEr!Q!^Du!^!_Fx!_!}Du!}#OHq#O#PJQ#P#oDu#o#pFx#p~Duy!0cd$UWkqO!O%T!O!P@r!P!Q%T!Q![!1q![!^%T!_!g%T!g!hAl!h#R%T#R#S!1q#S#U%T#U#V!3X#V#X%T#X#YAl#Y#b%T#b#c!2w#c#d!4m#d#l%T#l#m!5{#m#o%T#p~%Ty!1x_$UWkqO!O%T!O!P@r!P!Q%T!Q![!1q![!^%T!_!g%T!g!hAl!h#R%T#R#S!1q#S#X%T#X#YAl#Y#b%T#b#c!2w#c#o%T#p~%Ty!3OR$UWkqO!^%T!_#o%T#p~%Ty!3^W$UWO!Q%T!Q!R!3v!R!S!3v!S!^%T!_#R%T#R#S!3v#S#o%T#p~%Ty!3}Y$UWkqO!Q%T!Q!R!3v!R!S!3v!S!^%T!_#R%T#R#S!3v#S#b%T#b#c!2w#c#o%T#p~%Ty!4rV$UWO!Q%T!Q!Y!5X!Y!^%T!_#R%T#R#S!5X#S#o%T#p~%Ty!5`X$UWkqO!Q%T!Q!Y!5X!Y!^%T!_#R%T#R#S!5X#S#b%T#b#c!2w#c#o%T#p~%Ty!6QZ$UWO!Q%T!Q![!6s![!^%T!_!c%T!c!i!6s!i#R%T#R#S!6s#S#T%T#T#Z!6s#Z#o%T#p~%Ty!6z]$UWkqO!Q%T!Q![!6s![!^%T!_!c%T!c!i!6s!i#R%T#R#S!6s#S#T%T#T#Z!6s#Z#b%T#b#c!2w#c#o%T#p~%T%w!7|R!]V$UW#m%hO!^%T!_#o%T#p~%T!P!8^R_w$UWO!^%T!_#o%T#p~%T6i!8rR'bd!a0`#x&s'|P!P!Q!8{!^!_!9Q!_!`!9_W!9QO$WW#v!9VP#`#v!_!`!9Y#v!9_O#o#v#v!9dO#a#v%w!9kT!{%o$UWO!^%T!_!`'v!`!a!9z!a#o%T#p~%T$P!:RR#W#w$UWO!^%T!_#o%T#p~%T%w!:gT'a!s#a#v$RS$UWO!^%T!_!`!:v!`!a!;W!a#o%T#p~%T$O!:}R#a#v$UWO!^%T!_#o%T#p~%T$O!;_T#`#v$UWO!^%T!_!`5T!`!a!;n!a#o%T#p~%T$O!;uS#`#v$UWO!^%T!_!`5T!`#o%T#p~%T6i!]S#g#v$UWO!^%T!_!`5T!`#o%T#p~%T$P!>pR$UW'f#wO!^%T!_#o%T#p~%T~!?OO!T~6d!?VT'w6[$UWO!^%T!_!`5T!`#o%T#p#q!=P#q~%T5g!?oR!S5]nQ$UWO!^%T!_#o%T#p~%TX!@PR!kP$UWO!^%T!_#o%T#p~%T7Z!@gr$UW'Y7R#zS']%k'g2bOX%TXY%cYZ%TZ[%c[p%Tpq%cqt%Ttu2`u}%T}!O3j!O!Q%T!Q![2`![!^%T!_!c%T!c!}2`!}#R%T#R#S2`#S#T%T#T#o2`#p$f%T$f$g%c$g#BY2`#BY#BZ!@Y#BZ$IS2`$IS$I_!@Y$I_$JT2`$JT$JU!@Y$JU$KV2`$KV$KW!@Y$KW&FU2`&FU&FV!@Y&FV?HT2`?HT?HU!@Y?HU~2`7Z!CO_$UW'Z7R#zS']%k'g2bOt%Ttu2`u}%T}!O3j!O!Q%T!Q![2`![!^%T!_!c%T!c!}2`!}#R%T#R#S2`#S#T%T#T#o2`#p$g%T$g~2`", - tokenizers: [noSemicolon, incdecToken, template, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, insertSemicolon], - topRules: {"Script":[0,7]}, - dialects: {jsx: 11707, ts: 11709}, - dynamicPrecedences: {"149":1,"176":1}, - specialized: [{term: 289, get: (value, stack) => (tsExtends(value, stack) << 1)},{term: 289, get: value => spec_identifier$1[value] || -1},{term: 299, get: value => spec_word[value] || -1},{term: 63, get: value => spec_LessThan[value] || -1}], - tokenPrec: 11730 -}); - -/** -A collection of JavaScript-related -[snippets](https://codemirror.net/6/docs/ref/#autocomplete.snippet). -*/ -const snippets = [ - /*@__PURE__*/snippetCompletion("function ${name}(${params}) {\n\t${}\n}", { - label: "function", - detail: "definition", - type: "keyword" - }), - /*@__PURE__*/snippetCompletion("for (let ${index} = 0; ${index} < ${bound}; ${index}++) {\n\t${}\n}", { - label: "for", - detail: "loop", - type: "keyword" - }), - /*@__PURE__*/snippetCompletion("for (let ${name} of ${collection}) {\n\t${}\n}", { - label: "for", - detail: "of loop", - type: "keyword" - }), - /*@__PURE__*/snippetCompletion("try {\n\t${}\n} catch (${error}) {\n\t${}\n}", { - label: "try", - detail: "block", - type: "keyword" - }), - /*@__PURE__*/snippetCompletion("class ${name} {\n\tconstructor(${params}) {\n\t\t${}\n\t}\n}", { - label: "class", - detail: "definition", - type: "keyword" - }), - /*@__PURE__*/snippetCompletion("import {${names}} from \"${module}\"\n${}", { - label: "import", - detail: "named", - type: "keyword" - }), - /*@__PURE__*/snippetCompletion("import ${name} from \"${module}\"\n${}", { - label: "import", - detail: "default", - type: "keyword" - }) -]; - -/** -A language provider based on the [Lezer JavaScript -parser](https://github.com/lezer-parser/javascript), extended with -highlighting and indentation information. -*/ -const javascriptLanguage = /*@__PURE__*/LRLanguage.define({ - parser: /*@__PURE__*/parser$3.configure({ - props: [ - /*@__PURE__*/indentNodeProp.add({ - IfStatement: /*@__PURE__*/continuedIndent({ except: /^\s*({|else\b)/ }), - TryStatement: /*@__PURE__*/continuedIndent({ except: /^\s*({|catch\b|finally\b)/ }), - LabeledStatement: flatIndent, - SwitchBody: context => { - let after = context.textAfter, closed = /^\s*\}/.test(after), isCase = /^\s*(case|default)\b/.test(after); - return context.baseIndent + (closed ? 0 : isCase ? 1 : 2) * context.unit; - }, - Block: /*@__PURE__*/delimitedIndent$1({ closing: "}" }), - ArrowFunction: cx => cx.baseIndent + cx.unit, - "TemplateString BlockComment": () => -1, - "Statement Property": /*@__PURE__*/continuedIndent({ except: /^{/ }), - JSXElement(context) { - let closed = /^\s*<\//.test(context.textAfter); - return context.lineIndent(context.node.from) + (closed ? 0 : context.unit); - }, - JSXEscape(context) { - let closed = /\s*\}/.test(context.textAfter); - return context.lineIndent(context.node.from) + (closed ? 0 : context.unit); - }, - "JSXOpenTag JSXSelfClosingTag"(context) { - return context.column(context.node.from) + context.unit; - } - }), - /*@__PURE__*/foldNodeProp.add({ - "Block ClassBody SwitchBody EnumBody ObjectExpression ArrayExpression": foldInside, - BlockComment(tree) { return { from: tree.from + 2, to: tree.to - 2 }; } - }) - ] - }), - languageData: { - closeBrackets: { brackets: ["(", "[", "{", "'", '"', "`"] }, - commentTokens: { line: "//", block: { open: "/*", close: "*/" } }, - indentOnInput: /^\s*(?:case |default:|\{|\}|<\/)$/, - wordChars: "$" - } -}); -/** -A language provider for TypeScript. -*/ -const typescriptLanguage = /*@__PURE__*/javascriptLanguage.configure({ dialect: "ts" }); -/** -Language provider for JSX. -*/ -const jsxLanguage = /*@__PURE__*/javascriptLanguage.configure({ dialect: "jsx" }); -/** -Language provider for JSX + TypeScript. -*/ -const tsxLanguage = /*@__PURE__*/javascriptLanguage.configure({ dialect: "jsx ts" }); -/** -JavaScript support. Includes [snippet](https://codemirror.net/6/docs/ref/#lang-javascript.snippets) -completion. -*/ -function javascript(config = {}) { - let lang = config.jsx ? (config.typescript ? tsxLanguage : jsxLanguage) - : config.typescript ? typescriptLanguage : javascriptLanguage; - return new LanguageSupport(lang, [ - javascriptLanguage.data.of({ - autocomplete: ifNotIn(["LineComment", "BlockComment", "String"], completeFromList(snippets)) - }), - config.jsx ? autoCloseTags$1 : [], - ]); -} -function elementName$1(doc, tree, max = doc.length) { - if (!tree) - return ""; - let name = tree.getChild("JSXIdentifier"); - return name ? doc.sliceString(name.from, Math.min(name.to, max)) : ""; -} -const android = typeof navigator == "object" && /*@__PURE__*//Android\b/.test(navigator.userAgent); -/** -Extension that will automatically insert JSX close tags when a `>` or -`/` is typed. -*/ -const autoCloseTags$1 = /*@__PURE__*/EditorView.inputHandler.of((view, from, to, text) => { - if ((android ? view.composing : view.compositionStarted) || view.state.readOnly || - from != to || (text != ">" && text != "/") || - !javascriptLanguage.isActiveAt(view.state, from, -1)) - return false; - let { state } = view; - let changes = state.changeByRange(range => { - var _a, _b, _c; - let { head } = range, around = syntaxTree(state).resolveInner(head, -1), name; - if (around.name == "JSXStartTag") - around = around.parent; - if (text == ">" && around.name == "JSXFragmentTag") { - return { range: EditorSelection.cursor(head + 1), changes: { from: head, insert: `><>` } }; - } - else if (text == ">" && around.name == "JSXIdentifier") { - if (((_b = (_a = around.parent) === null || _a === void 0 ? void 0 : _a.lastChild) === null || _b === void 0 ? void 0 : _b.name) != "JSXEndTag" && (name = elementName$1(state.doc, around.parent, head))) - return { range: EditorSelection.cursor(head + 1), changes: { from: head, insert: `>` } }; - } - else if (text == "/" && around.name == "JSXFragmentTag") { - let empty = around.parent, base = empty === null || empty === void 0 ? void 0 : empty.parent; - if (empty.from == head - 1 && ((_c = base.lastChild) === null || _c === void 0 ? void 0 : _c.name) != "JSXEndTag" && (name = elementName$1(state.doc, base === null || base === void 0 ? void 0 : base.firstChild, head))) { - let insert = `/${name}>`; - return { range: EditorSelection.cursor(head + insert.length), changes: { from: head, insert } }; - } - } - return { range }; - }); - if (changes.changes.empty) - return false; - view.dispatch(changes, { userEvent: "input.type", scrollIntoView: true }); - return true; -}); - -const Targets = ["_blank", "_self", "_top", "_parent"]; -const Charsets = ["ascii", "utf-8", "utf-16", "latin1", "latin1"]; -const Methods = ["get", "post", "put", "delete"]; -const Encs = ["application/x-www-form-urlencoded", "multipart/form-data", "text/plain"]; -const Bool$1 = ["true", "false"]; -const S = {}; // Empty tag spec -const Tags = { - a: { - attrs: { - href: null, ping: null, type: null, - media: null, - target: Targets, - hreflang: null - } - }, - abbr: S, - acronym: S, - address: S, - applet: S, - area: { - attrs: { - alt: null, coords: null, href: null, target: null, ping: null, - media: null, hreflang: null, type: null, - shape: ["default", "rect", "circle", "poly"] - } - }, - article: S, - aside: S, - audio: { - attrs: { - src: null, mediagroup: null, - crossorigin: ["anonymous", "use-credentials"], - preload: ["none", "metadata", "auto"], - autoplay: ["autoplay"], - loop: ["loop"], - controls: ["controls"] - } - }, - b: S, - base: { attrs: { href: null, target: Targets } }, - basefont: S, - bdi: S, - bdo: S, - big: S, - blockquote: { attrs: { cite: null } }, - body: S, - br: S, - button: { - attrs: { - form: null, formaction: null, name: null, value: null, - autofocus: ["autofocus"], - disabled: ["autofocus"], - formenctype: Encs, - formmethod: Methods, - formnovalidate: ["novalidate"], - formtarget: Targets, - type: ["submit", "reset", "button"] - } - }, - canvas: { attrs: { width: null, height: null } }, - caption: S, - center: S, - cite: S, - code: S, - col: { attrs: { span: null } }, - colgroup: { attrs: { span: null } }, - command: { - attrs: { - type: ["command", "checkbox", "radio"], - label: null, icon: null, radiogroup: null, command: null, title: null, - disabled: ["disabled"], - checked: ["checked"] - } - }, - data: { attrs: { value: null } }, - datagrid: { attrs: { disabled: ["disabled"], multiple: ["multiple"] } }, - datalist: { attrs: { data: null } }, - dd: S, - del: { attrs: { cite: null, datetime: null } }, - details: { attrs: { open: ["open"] } }, - dfn: S, - dir: S, - div: S, - dl: S, - dt: S, - em: S, - embed: { attrs: { src: null, type: null, width: null, height: null } }, - eventsource: { attrs: { src: null } }, - fieldset: { attrs: { disabled: ["disabled"], form: null, name: null } }, - figcaption: S, - figure: S, - font: S, - footer: S, - form: { - attrs: { - action: null, name: null, - "accept-charset": Charsets, - autocomplete: ["on", "off"], - enctype: Encs, - method: Methods, - novalidate: ["novalidate"], - target: Targets - } - }, - frame: S, - frameset: S, - h1: S, h2: S, h3: S, h4: S, h5: S, h6: S, - head: { - children: ["title", "base", "link", "style", "meta", "script", "noscript", "command"] - }, - header: S, - hgroup: S, - hr: S, - html: { - attrs: { manifest: null } - }, - i: S, - iframe: { - attrs: { - src: null, srcdoc: null, name: null, width: null, height: null, - sandbox: ["allow-top-navigation", "allow-same-origin", "allow-forms", "allow-scripts"], - seamless: ["seamless"] - } - }, - img: { - attrs: { - alt: null, src: null, ismap: null, usemap: null, width: null, height: null, - crossorigin: ["anonymous", "use-credentials"] - } - }, - input: { - attrs: { - alt: null, dirname: null, form: null, formaction: null, - height: null, list: null, max: null, maxlength: null, min: null, - name: null, pattern: null, placeholder: null, size: null, src: null, - step: null, value: null, width: null, - accept: ["audio/*", "video/*", "image/*"], - autocomplete: ["on", "off"], - autofocus: ["autofocus"], - checked: ["checked"], - disabled: ["disabled"], - formenctype: Encs, - formmethod: Methods, - formnovalidate: ["novalidate"], - formtarget: Targets, - multiple: ["multiple"], - readonly: ["readonly"], - required: ["required"], - type: ["hidden", "text", "search", "tel", "url", "email", "password", "datetime", "date", "month", - "week", "time", "datetime-local", "number", "range", "color", "checkbox", "radio", - "file", "submit", "image", "reset", "button"] - } - }, - ins: { attrs: { cite: null, datetime: null } }, - kbd: S, - keygen: { - attrs: { - challenge: null, form: null, name: null, - autofocus: ["autofocus"], - disabled: ["disabled"], - keytype: ["RSA"] - } - }, - label: { attrs: { for: null, form: null } }, - legend: S, - li: { attrs: { value: null } }, - link: { - attrs: { - href: null, type: null, - hreflang: null, - media: null, - sizes: ["all", "16x16", "16x16 32x32", "16x16 32x32 64x64"] - } - }, - map: { attrs: { name: null } }, - mark: S, - menu: { attrs: { label: null, type: ["list", "context", "toolbar"] } }, - meta: { - attrs: { - content: null, - charset: Charsets, - name: ["viewport", "application-name", "author", "description", "generator", "keywords"], - "http-equiv": ["content-language", "content-type", "default-style", "refresh"] - } - }, - meter: { attrs: { value: null, min: null, low: null, high: null, max: null, optimum: null } }, - nav: S, - noframes: S, - noscript: S, - object: { - attrs: { - data: null, type: null, name: null, usemap: null, form: null, width: null, height: null, - typemustmatch: ["typemustmatch"] - } - }, - ol: { attrs: { reversed: ["reversed"], start: null, type: ["1", "a", "A", "i", "I"] }, - children: ["li", "script", "template", "ul", "ol"] }, - optgroup: { attrs: { disabled: ["disabled"], label: null } }, - option: { attrs: { disabled: ["disabled"], label: null, selected: ["selected"], value: null } }, - output: { attrs: { for: null, form: null, name: null } }, - p: S, - param: { attrs: { name: null, value: null } }, - pre: S, - progress: { attrs: { value: null, max: null } }, - q: { attrs: { cite: null } }, - rp: S, - rt: S, - ruby: S, - s: S, - samp: S, - script: { - attrs: { - type: ["text/javascript"], - src: null, - async: ["async"], - defer: ["defer"], - charset: Charsets - } - }, - section: S, - select: { - attrs: { - form: null, name: null, size: null, - autofocus: ["autofocus"], - disabled: ["disabled"], - multiple: ["multiple"] - } - }, - slot: { attrs: { name: null } }, - small: S, - source: { attrs: { src: null, type: null, media: null } }, - span: S, - strike: S, - strong: S, - style: { - attrs: { - type: ["text/css"], - media: null, - scoped: null - } - }, - sub: S, - summary: S, - sup: S, - table: S, - tbody: S, - td: { attrs: { colspan: null, rowspan: null, headers: null } }, - template: S, - textarea: { - attrs: { - dirname: null, form: null, maxlength: null, name: null, placeholder: null, - rows: null, cols: null, - autofocus: ["autofocus"], - disabled: ["disabled"], - readonly: ["readonly"], - required: ["required"], - wrap: ["soft", "hard"] - } - }, - tfoot: S, - th: { attrs: { colspan: null, rowspan: null, headers: null, scope: ["row", "col", "rowgroup", "colgroup"] } }, - thead: S, - time: { attrs: { datetime: null } }, - title: S, - tr: S, - track: { - attrs: { - src: null, label: null, default: null, - kind: ["subtitles", "captions", "descriptions", "chapters", "metadata"], - srclang: null - } - }, - tt: S, - u: S, - ul: { children: ["li", "script", "template", "ul", "ol"] }, - var: S, - video: { - attrs: { - src: null, poster: null, width: null, height: null, - crossorigin: ["anonymous", "use-credentials"], - preload: ["auto", "metadata", "none"], - autoplay: ["autoplay"], - mediagroup: ["movie"], - muted: ["muted"], - controls: ["controls"] - } - }, - wbr: S -}; -const GlobalAttrs = { - accesskey: null, - class: null, - contenteditable: Bool$1, - contextmenu: null, - dir: ["ltr", "rtl", "auto"], - draggable: ["true", "false", "auto"], - dropzone: ["copy", "move", "link", "string:", "file:"], - hidden: ["hidden"], - id: null, - inert: ["inert"], - itemid: null, - itemprop: null, - itemref: null, - itemscope: ["itemscope"], - itemtype: null, - lang: ["ar", "bn", "de", "en-GB", "en-US", "es", "fr", "hi", "id", "ja", "pa", "pt", "ru", "tr", "zh"], - spellcheck: Bool$1, - autocorrect: Bool$1, - autocapitalize: Bool$1, - style: null, - tabindex: null, - title: null, - translate: ["yes", "no"], - onclick: null, - rel: ["stylesheet", "alternate", "author", "bookmark", "help", "license", "next", "nofollow", "noreferrer", "prefetch", "prev", "search", "tag"], - role: /*@__PURE__*/"alert application article banner button cell checkbox complementary contentinfo dialog document feed figure form grid gridcell heading img list listbox listitem main navigation region row rowgroup search switch tab table tabpanel textbox timer".split(" "), - "aria-activedescendant": null, - "aria-atomic": Bool$1, - "aria-autocomplete": ["inline", "list", "both", "none"], - "aria-busy": Bool$1, - "aria-checked": ["true", "false", "mixed", "undefined"], - "aria-controls": null, - "aria-describedby": null, - "aria-disabled": Bool$1, - "aria-dropeffect": null, - "aria-expanded": ["true", "false", "undefined"], - "aria-flowto": null, - "aria-grabbed": ["true", "false", "undefined"], - "aria-haspopup": Bool$1, - "aria-hidden": Bool$1, - "aria-invalid": ["true", "false", "grammar", "spelling"], - "aria-label": null, - "aria-labelledby": null, - "aria-level": null, - "aria-live": ["off", "polite", "assertive"], - "aria-multiline": Bool$1, - "aria-multiselectable": Bool$1, - "aria-owns": null, - "aria-posinset": null, - "aria-pressed": ["true", "false", "mixed", "undefined"], - "aria-readonly": Bool$1, - "aria-relevant": null, - "aria-required": Bool$1, - "aria-selected": ["true", "false", "undefined"], - "aria-setsize": null, - "aria-sort": ["ascending", "descending", "none", "other"], - "aria-valuemax": null, - "aria-valuemin": null, - "aria-valuenow": null, - "aria-valuetext": null -}; -const AllTags = /*@__PURE__*/Object.keys(Tags); -const GlobalAttrNames = /*@__PURE__*/Object.keys(GlobalAttrs); -function elementName(doc, tree, max = doc.length) { - if (!tree) - return ""; - let tag = tree.firstChild; - let name = tag && tag.getChild("TagName"); - return name ? doc.sliceString(name.from, Math.min(name.to, max)) : ""; -} -function findParentElement(tree, skip = false) { - for (let cur = tree.parent; cur; cur = cur.parent) - if (cur.name == "Element") { - if (skip) - skip = false; - else - return cur; - } - return null; -} -function allowedChildren(doc, tree) { - let parentInfo = Tags[elementName(doc, findParentElement(tree, true))]; - return (parentInfo === null || parentInfo === void 0 ? void 0 : parentInfo.children) || AllTags; -} -function openTags(doc, tree) { - let open = []; - for (let parent = tree; parent = findParentElement(parent);) { - let tagName = elementName(doc, parent); - if (tagName && parent.lastChild.name == "CloseTag") - break; - if (tagName && open.indexOf(tagName) < 0 && (tree.name == "EndTag" || tree.from >= parent.firstChild.to)) - open.push(tagName); - } - return open; -} -const identifier = /^[:\-\.\w\u00b7-\uffff]*$/; -function completeTag(state, tree, from, to) { - let end = /\s*>/.test(state.sliceDoc(to, to + 5)) ? "" : ">"; - return { from, to, - options: allowedChildren(state.doc, tree).map(tagName => ({ label: tagName, type: "type" })).concat(openTags(state.doc, tree).map((tag, i) => ({ label: "/" + tag, apply: "/" + tag + end, type: "type", boost: 99 - i }))), - validFor: /^\/?[:\-\.\w\u00b7-\uffff]*$/ }; -} -function completeCloseTag(state, tree, from, to) { - let end = /\s*>/.test(state.sliceDoc(to, to + 5)) ? "" : ">"; - return { from, to, - options: openTags(state.doc, tree).map((tag, i) => ({ label: tag, apply: tag + end, type: "type", boost: 99 - i })), - validFor: identifier }; -} -function completeStartTag(state, tree, pos) { - let options = [], level = 0; - for (let tagName of allowedChildren(state.doc, tree)) - options.push({ label: "<" + tagName, type: "type" }); - for (let open of openTags(state.doc, tree)) - options.push({ label: "", type: "type", boost: 99 - level++ }); - return { from: pos, to: pos, options, validFor: /^<\/?[:\-\.\w\u00b7-\uffff]*$/ }; -} -function completeAttrName(state, tree, from, to) { - let elt = findParentElement(tree), info = elt ? Tags[elementName(state.doc, elt)] : null; - let names = (info && info.attrs ? Object.keys(info.attrs).concat(GlobalAttrNames) : GlobalAttrNames); - return { from, to, - options: names.map(attrName => ({ label: attrName, type: "property" })), - validFor: identifier }; -} -function completeAttrValue(state, tree, from, to) { - var _a; - let nameNode = (_a = tree.parent) === null || _a === void 0 ? void 0 : _a.getChild("AttributeName"); - let options = [], token = undefined; - if (nameNode) { - let attrName = state.sliceDoc(nameNode.from, nameNode.to); - let attrs = GlobalAttrs[attrName]; - if (!attrs) { - let elt = findParentElement(tree), info = elt ? Tags[elementName(state.doc, elt)] : null; - attrs = (info === null || info === void 0 ? void 0 : info.attrs) && info.attrs[attrName]; - } - if (attrs) { - let base = state.sliceDoc(from, to).toLowerCase(), quoteStart = '"', quoteEnd = '"'; - if (/^['"]/.test(base)) { - token = base[0] == '"' ? /^[^"]*$/ : /^[^']*$/; - quoteStart = ""; - quoteEnd = state.sliceDoc(to, to + 1) == base[0] ? "" : base[0]; - base = base.slice(1); - from++; - } - else { - token = /^[^\s<>='"]*$/; - } - for (let value of attrs) - options.push({ label: value, apply: quoteStart + value + quoteEnd, type: "constant" }); - } - } - return { from, to, options, validFor: token }; -} -/** -HTML tag completion. Opens and closes tags and attributes in a -context-aware way. -*/ -function htmlCompletionSource(context) { - let { state, pos } = context, around = syntaxTree(state).resolveInner(pos), tree = around.resolve(pos, -1); - for (let scan = pos, before; around == tree && (before = tree.childBefore(scan));) { - let last = before.lastChild; - if (!last || !last.type.isError || last.from < last.to) - break; - around = tree = before; - scan = last.from; - } - if (tree.name == "TagName") { - return tree.parent && /CloseTag$/.test(tree.parent.name) ? completeCloseTag(state, tree, tree.from, pos) - : completeTag(state, tree, tree.from, pos); - } - else if (tree.name == "StartTag") { - return completeTag(state, tree, pos, pos); - } - else if (tree.name == "StartCloseTag" || tree.name == "IncompleteCloseTag") { - return completeCloseTag(state, tree, pos, pos); - } - else if (context.explicit && (tree.name == "OpenTag" || tree.name == "SelfClosingTag") || tree.name == "AttributeName") { - return completeAttrName(state, tree, tree.name == "AttributeName" ? tree.from : pos, pos); - } - else if (tree.name == "Is" || tree.name == "AttributeValue" || tree.name == "UnquotedAttributeValue") { - return completeAttrValue(state, tree, tree.name == "Is" ? pos : tree.from, pos); - } - else if (context.explicit && (around.name == "Element" || around.name == "Text" || around.name == "Document")) { - return completeStartTag(state, tree, pos); - } - else { - return null; - } -} - -/** -A language provider based on the [Lezer HTML -parser](https://github.com/lezer-parser/html), extended with the -JavaScript and CSS parsers to parse the content of `