@vscode/markdown-editor 0.0.2-113 → 0.0.2-114
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +425 -0
- package/dist/commands.js +1 -1
- package/dist/commands.js.map +1 -1
- package/dist/index.d.ts +264 -30
- package/dist/index.js +2837 -2128
- package/dist/index.js.map +1 -1
- package/package.json +16 -7
- package/src/contrib/rename/rename.css +73 -0
- package/src/contrib/suggest/suggest.css +109 -0
- package/src/view/editor.css +279 -40
package/README.md
CHANGED
|
@@ -4,6 +4,397 @@
|
|
|
4
4
|
editor. It keeps Markdown source as the canonical document while presenting
|
|
5
5
|
inactive blocks in rendered form and active blocks in editable source form.
|
|
6
6
|
|
|
7
|
+
## Package releases
|
|
8
|
+
|
|
9
|
+
The npm release pipelines run `pnpm exec turbo build --filter=@vscode/markdown-editor`.
|
|
10
|
+
The package build depends on the workspace observables, HubRPC, and web-editors
|
|
11
|
+
builds. Fixture-only dependencies (Component Explorer and the cmark WASM compiler)
|
|
12
|
+
remain in the fixture/screenshot task graph, not the library release graph.
|
|
13
|
+
Both stable and nightly release jobs install Chromium before running the package
|
|
14
|
+
tests, which include real-browser clipboard and widget tests.
|
|
15
|
+
|
|
16
|
+
The Markdown test runner is temporarily pinned to Playwright 1.56.1, matching
|
|
17
|
+
Monaco's release tooling. Its Chromium download uses Microsoft's distribution
|
|
18
|
+
endpoint; newer Chrome-for-Testing downloads redirect to Google storage, which
|
|
19
|
+
failed with `EPERM` on the Azure release agent. Keep the exact pin until the newer
|
|
20
|
+
download route is approved and verified on that agent. This affects test tooling,
|
|
21
|
+
not the published editor's runtime dependencies or Component Explorer's renderer.
|
|
22
|
+
|
|
23
|
+
## Browser tests
|
|
24
|
+
|
|
25
|
+
`pnpm test:e2e` builds the fixture dependencies and runs the Playwright interaction
|
|
26
|
+
suite. Tests use isolated browser contexts and run in parallel, with four workers
|
|
27
|
+
in CI (override with Playwright's `--workers` option). This is separate from
|
|
28
|
+
Component Explorer's screenshot renderer, which already defaults to available
|
|
29
|
+
CPUs capped at eight workers. Screenshot computation remains Turbo-cached.
|
|
30
|
+
|
|
31
|
+
The Playwright `e2e/milestone-one.spec.ts` suite is temporarily skipped to unblock
|
|
32
|
+
CI while its debug-panel-based checks are replaced with fixture-native assertions.
|
|
33
|
+
The milestone fixtures remain in the screenshot pipeline; other E2E and unit
|
|
34
|
+
tests remain enabled.
|
|
35
|
+
|
|
36
|
+
In locked mode, submitting a comment or dismissing it with Escape keeps the input
|
|
37
|
+
hidden for the current selection, including across layout changes. Changing the
|
|
38
|
+
selection makes comment entry available again.
|
|
39
|
+
|
|
40
|
+
## Editing policies
|
|
41
|
+
|
|
42
|
+
The editor has three independent policies:
|
|
43
|
+
|
|
44
|
+
- `EditorModel.readonlyMode`: disables text editing. The lock/pencil button
|
|
45
|
+
changes only this permission, not parsing, layout, or syntax visibility.
|
|
46
|
+
- `EditorModel.presentation`: `reading` uses conventional Markdown whitespace;
|
|
47
|
+
`editing` preserves source line breaks, blank lines, repeated spaces and tabs
|
|
48
|
+
while keeping rich formatting. Both work while locked or editable.
|
|
49
|
+
- `EditorModel.renderMarkupText`: `none` hides syntax, `selection` uses the
|
|
50
|
+
existing active-block revelation rules, and `all` reveals syntax throughout
|
|
51
|
+
the document. Hidden inline syntax occupies no width in either presentation.
|
|
52
|
+
Find can temporarily reveal hidden source for the current match without
|
|
53
|
+
changing this policy or cursor-navigation rules; closing Find removes the reveal.
|
|
54
|
+
|
|
55
|
+
Non-obvious spaces (leading, trailing, and runs of two or more) show dot
|
|
56
|
+
indicators wherever markup is revealed; tabs show an arrow. Ordinary single
|
|
57
|
+
inter-word spaces remain unmarked. The view-data layer maps markup visibility
|
|
58
|
+
to per-leaf `showWhitespace` booleans, so whitespace rendering does not depend
|
|
59
|
+
on the public policy enum. In editing presentation these are overlays on real
|
|
60
|
+
source whitespace: line breaks, wrapping, source offsets, and clipboard text
|
|
61
|
+
remain unchanged.
|
|
62
|
+
|
|
63
|
+
The model defaults to editable, reading presentation, and selection markup.
|
|
64
|
+
Hosts can initialize presentation with `EditorView`'s `presentation` option.
|
|
65
|
+
Switching presentation reparses without changing source or selection. Locking
|
|
66
|
+
does not reparse the document.
|
|
67
|
+
|
|
68
|
+
The editing preset maps to explicit parser options rather than a parser UI mode:
|
|
69
|
+
`explicitBlankLineBlocks`, `explicitFinalEmptyLine`,
|
|
70
|
+
`preserveTrailingListContinuation`, and `allowEmptyListItemInterrupts`.
|
|
71
|
+
Blank source lines become empty blocks; the final unfinished line stays in its
|
|
72
|
+
list paragraph when it can continue that paragraph. A blank line ends this lazy
|
|
73
|
+
continuation. Empty nested list prefixes are structural before their first text
|
|
74
|
+
character is typed. These narrow recognition deviations avoid structural jumps
|
|
75
|
+
while typing or deleting, without depending on editing history. The reading
|
|
76
|
+
preset leaves these extensions off.
|
|
77
|
+
|
|
78
|
+
In editing presentation, Enter continues complete list items and exits/outdents
|
|
79
|
+
empty ones. Elsewhere it inserts a single newline without creating a virtual
|
|
80
|
+
paragraph. Arrow Down also stays within
|
|
81
|
+
the existing source instead of creating a virtual paragraph.
|
|
82
|
+
|
|
83
|
+
See [Editing property tests](docs/editing-properties.md) for the interactive
|
|
84
|
+
assertion fixtures, CI contracts, deterministic editing corpus, and the
|
|
85
|
+
red/green/visual evidence required for layout fixes.
|
|
86
|
+
|
|
87
|
+
### Automatic links
|
|
88
|
+
|
|
89
|
+
Bare HTTP(S) URLs, `www.` addresses, and email addresses are detected using GFM
|
|
90
|
+
autolink rules. Angle-bracket autolinks are supported too. They use the same link
|
|
91
|
+
nodes and host presentation provider as explicit Markdown links, so recognized
|
|
92
|
+
GitHub issue URLs can receive VS Code rich presentations without `[label](url)`
|
|
93
|
+
syntax. Active links retain their exact editable source. Code spans and fenced
|
|
94
|
+
code do not auto-link; trailing punctuation is excluded from link targets.
|
|
95
|
+
|
|
96
|
+
### Fixture reference rendering
|
|
97
|
+
|
|
98
|
+
The real-editor examples expose **Interactive mode** in the fixture toolbar.
|
|
99
|
+
This live input enables browser typing and cursor blinking without resetting the
|
|
100
|
+
editor, selection, or recording; it defaults off for deterministic screenshots.
|
|
101
|
+
|
|
102
|
+
In the sidebar, **showEditModeToggle** restores the editor's lock button.
|
|
103
|
+
**readonly**, **presentation** (`reading` / `editing`), and **renderMarkupText**
|
|
104
|
+
(`none` / `selection` / `all`) control the three independent policies. These controls are
|
|
105
|
+
live in the examples, main demos, content/selection fixtures, and Mermaid
|
|
106
|
+
fixtures: edits and selection survive changes. The dropdown follows the editor
|
|
107
|
+
button and replayed state. Legacy recordings with `sourceEditing` and
|
|
108
|
+
`activeEverywhere` are translated when loaded; new recordings store the explicit
|
|
109
|
+
policies. Existing fixture defaults are preserved, including
|
|
110
|
+
hidden buttons in the examples and selection fixtures. Browser input remains
|
|
111
|
+
controlled separately by **Interactive mode**.
|
|
112
|
+
|
|
113
|
+
The Compare diagnostics (injectivity, Arrow Down coverage, and active/inactive
|
|
114
|
+
comparison) also honor **showEditModeToggle**, defaulting to hidden. They retain
|
|
115
|
+
their diagnostic selection/presentation setup rather than synchronizing the
|
|
116
|
+
compared models through the interactive policy controls.
|
|
117
|
+
Injectivity activates each source character and compares its start and end in
|
|
118
|
+
that same layout. It does not compare coordinates across cell activations,
|
|
119
|
+
which can resize table columns when inline markers appear or collapse.
|
|
120
|
+
|
|
121
|
+
The **Reference** debug tab follows the editor's source and replay position.
|
|
122
|
+
Its renderer selector defaults to **GitHub (cmark-gfm)**, using the
|
|
123
|
+
[`@vscode/cmark-gfm-wasm`](../../../cmark-gfm-wasm/README.md) workspace package
|
|
124
|
+
with GFM tables, task lists, strikethrough, and autolinks. **markdown-it** retains
|
|
125
|
+
the previous reference engine for comparison (including its different task-list
|
|
126
|
+
behavior). Both use `github-markdown-css` in a script-disabled iframe.
|
|
127
|
+
Ordinary paragraphs and lists therefore usually look identical. For a visible
|
|
128
|
+
engine difference, try `- [x] Done`: cmark-gfm renders a checkbox, while the
|
|
129
|
+
markdown-it configuration leaves `[x]` as text.
|
|
130
|
+
This is GitHub's Markdown parser plus reference CSS, not GitHub's complete site
|
|
131
|
+
rendering/sanitization pipeline. cmark's safe HTML defaults remain enabled.
|
|
132
|
+
Initialization/rendering errors are displayed in the pane, not replaced by a
|
|
133
|
+
different engine.
|
|
134
|
+
|
|
135
|
+
The **Trees** pane groups **AST**, **Tokens**, **View data**, and **View** behind
|
|
136
|
+
a dropdown. **Split right** opens another copy with an independent tree
|
|
137
|
+
selection; both continue to follow live edits and replay. **Layout** remains a
|
|
138
|
+
separate pane.
|
|
139
|
+
|
|
140
|
+
Fixture dependency builds now require Emscripten 4.0.15 and CMake for cmark-gfm.
|
|
141
|
+
Alternatively, build that package with `pnpm --filter @vscode/cmark-gfm-wasm
|
|
142
|
+
build:docker`, then run `pnpm run build:fixtures` once the other fixture
|
|
143
|
+
dependencies have been built. Production editor bundles do not include this
|
|
144
|
+
fixture-only renderer.
|
|
145
|
+
|
|
146
|
+
### Language feature widgets
|
|
147
|
+
|
|
148
|
+
`RenameModel` / `RenameWidget` and `SuggestModel` / `SuggestWidget` are isolated,
|
|
149
|
+
observable-driven contributions exported from the package. Import
|
|
150
|
+
`@vscode/markdown-editor/rename.css` or `@vscode/markdown-editor/suggest.css`
|
|
151
|
+
alongside the corresponding widget. Hosts own provider requests, edit application,
|
|
152
|
+
command routing, and editor integration; importing a widget does not enable a
|
|
153
|
+
language feature automatically.
|
|
154
|
+
|
|
155
|
+
See the [rename integration guide](src/contrib/rename/README.md) and
|
|
156
|
+
[suggest integration guide](src/contrib/suggest/README.md) for their contracts,
|
|
157
|
+
focus handling, and lifecycle requirements.
|
|
158
|
+
|
|
159
|
+
### Milestone 1 editing coverage
|
|
160
|
+
|
|
161
|
+
The `editor/milestone-1` fixture group is generated from
|
|
162
|
+
`src/view/fixture/milestoneOneScenarios.ts`. Each unique source, directed
|
|
163
|
+
selection, and presentation state mounts the real editor directly. Screenshot
|
|
164
|
+
fixtures do not replay editing history: restored undo/redo states and other
|
|
165
|
+
identical states are deduplicated across the group. Behavioral tests cover
|
|
166
|
+
typing and history separately. The star has detailed prefix coverage; other
|
|
167
|
+
list markers each have a sanity state rather than a duplicate sequence.
|
|
168
|
+
Examples default to 360px wide and content-sized height. **Editor margin**,
|
|
169
|
+
width, markup policy, read-only toggle, and interactive input controls support
|
|
170
|
+
live visual review. Disabling editor margins retains a left rail for hanging
|
|
171
|
+
source markers. The source-selection status uses a fixed-height, ellipsized row.
|
|
172
|
+
|
|
173
|
+
| Family | Source-state coverage | Still to verify before milestone completion |
|
|
174
|
+
| --- | --- | --- |
|
|
175
|
+
| Text and whitespace | Spaces, tabs, soft line breaks, graphemes, empty/populated documents, directed selections | Empty-file VS Code integration, wrapping, clipboard and IME |
|
|
176
|
+
| Headings | ATX levels 1/2/6, setext creation, incomplete prefixes | Other levels, Enter/split/join and caret geometry across wrapping |
|
|
177
|
+
| Lists | Star prefixes, alternate-marker sanity checks, lazy continuation, stable blank-line carets, source/bullet alignment, list continuation/exit | Broader active-block ownership, indentation/outdent and nested combinations |
|
|
178
|
+
| Task lists | Checked/unchecked prefixes, nested task ownership, mixed sibling label alignment | Toggling/history and broader nested task transitions |
|
|
179
|
+
| Links | Inline destination completion, reference definition completion, formatted labels | Escapes/titles, selections at boundaries, mouse placement and wrapped labels |
|
|
180
|
+
| Inline formatting | Star/underscore italics, bold, strike, bold-italic and nested/adjacent emphasis | Delimiter boundary matrix, escaped punctuation, cross-line and cross-block selections |
|
|
181
|
+
|
|
182
|
+
These are coverage seeds, not a claim that every combination is complete.
|
|
183
|
+
Concrete feedback must receive a named fixture plus behavioral/geometry
|
|
184
|
+
assertions; screenshot review alone does not close a regression. Production
|
|
185
|
+
margin optimization and removal of alternative hit-testing remain separate
|
|
186
|
+
follow-ups after reviewing these fixtures.
|
|
187
|
+
|
|
188
|
+
The list-marker review deliberately distinguishes presentation policies.
|
|
189
|
+
Editing presentation treats a bare `*`, `-`, `+`, or ordered marker as paragraph
|
|
190
|
+
text until its separator space/tab exists. A standalone bare marker has no list
|
|
191
|
+
indentation; a bare continuation stays in its existing bullet paragraph. Inserting
|
|
192
|
+
the separator promotes it, and deleting the separator reverses that promotion.
|
|
193
|
+
Reading presentation retains CommonMark empty-list parsing, with the caret
|
|
194
|
+
immediately after the actual marker rather than its synthetic gutter separator.
|
|
195
|
+
The `lists/lazy-continuation` checkpoints, parser ownership tests, and browser
|
|
196
|
+
geometry/history regressions cover these differences.
|
|
197
|
+
|
|
198
|
+
The `lists/empty-line-0` and `lists/lazy-empty-line`
|
|
199
|
+
checkpoints compare the same caret at EOF and before an additional newline,
|
|
200
|
+
without duplicate restored-state screenshots. The first empty continuation line of a
|
|
201
|
+
populated list paragraph keeps its indentation even when another newline follows;
|
|
202
|
+
the final line after the list terminator remains outside the list. Empty
|
|
203
|
+
marker-only items retain their existing empty-line placement.
|
|
204
|
+
|
|
205
|
+
`lists/nested-indent-dots` spreads source indentation indicators over the reserved
|
|
206
|
+
gutter. `lists/indent-space-1`, `lists/indent-space-2`, and `lists/indent-space-3`
|
|
207
|
+
isolate individual space selections and caret movement before a list marker.
|
|
208
|
+
Parsed list depth determines the gutter width; the actual source whitespace
|
|
209
|
+
shares that width evenly, rather than assuming two spaces per nesting level.
|
|
210
|
+
Each space's source-mapped text and dot fill its allocated cell. At the final
|
|
211
|
+
indentation boundary the caret meets the actual source glyph, including its
|
|
212
|
+
normal font sidebearing; the selection spans those exact caret endpoints.
|
|
213
|
+
Source-only spaces that do not create a nested item extend
|
|
214
|
+
leftward into the gutter instead of moving the logical bullet or text column.
|
|
215
|
+
Their display width uses the parsed marker prefix, not a fixed two-space rule.
|
|
216
|
+
Reading layout is unchanged.
|
|
217
|
+
The `lists/indent-depth-2`, `lists/indent-depth-uneven`, and `lists/indent-prefix-3`
|
|
218
|
+
fixtures reconstruct the nested-spacing feedback with minimal sources.
|
|
219
|
+
Browser geometry assertions also cover wider ordered prefixes, tabs,
|
|
220
|
+
markup visibility, typing, and undo.
|
|
221
|
+
|
|
222
|
+
`task-lists/nested-task-ownership` prevents a child checkbox from turning its
|
|
223
|
+
parent into a task. `task-lists/mixed-task-labels` aligns labels of task and
|
|
224
|
+
ordinary sibling items while preserving nested indentation. The ordinary
|
|
225
|
+
item's real separator spaces expand to fill the extra label-column width.
|
|
226
|
+
`task-lists/nested-task-empty-sibling-*` and `task-lists/mixed-task-separated-lists-*`
|
|
227
|
+
isolate populated/empty nested tasks and mixed lists separated by a thematic break.
|
|
228
|
+
In editing presentation, checkboxes and ordinary bullets share a gutter column;
|
|
229
|
+
the task's extra source bullet hangs farther left. Labels keep their position
|
|
230
|
+
when markup visibility changes, except for extra source-only separator padding.
|
|
231
|
+
The expanded ordinary separator has a visible
|
|
232
|
+
whitespace dot. Browser tests click task-label characters with markup hidden,
|
|
233
|
+
selection-revealed, and fully revealed, then verify exact insertion offsets.
|
|
234
|
+
`task-lists/empty-task-label` keeps a completed checkbox plus separator structural
|
|
235
|
+
before label text is typed in editing presentation. Reading retains standard GFM
|
|
236
|
+
parsing. Typing or deleting the label must not change checkbox ownership or move
|
|
237
|
+
the empty caret's text column.
|
|
238
|
+
Editing also treats `- [] test` as unchecked, preserving task layout through
|
|
239
|
+
`[x]` -> `[]` -> `[ ]` edits without inserting a space into the source.
|
|
240
|
+
Reading keeps `[]` as literal text. The normal separator requirement remains;
|
|
241
|
+
`- []text` and a bare `- []` at EOF are not tasks. The reduced
|
|
242
|
+
`task-lists/checkbox-value-0`, `checkbox-value-1`, and `checkbox-value-2`
|
|
243
|
+
fixtures cover all three values in reading and editing presentation.
|
|
244
|
+
The paired `task-lists/checkbox-line-end-empty` and `task-lists/checkbox-line-end-filled`
|
|
245
|
+
states extend this guarantee to a checkbox followed directly by a newline:
|
|
246
|
+
typing on the continuation must neither create the checkbox nor move the caret
|
|
247
|
+
column. Bare `* [ ]` without a separator retains standard non-task parsing.
|
|
248
|
+
`lists/nested-parent-filled` and `lists/nested-parent-empty` preserve the parent's
|
|
249
|
+
marker separator and its own visual line when its last label character is
|
|
250
|
+
removed. The nested item's row and indentation must not move. Parser tests cover
|
|
251
|
+
LF, CRLF, CR, source tiling, and incremental edits; browser tests assert the
|
|
252
|
+
caret and nested-item coordinates through deletion and retyping.
|
|
253
|
+
`task-lists/continuation-enter` covers a blank task continuation: editing Enter
|
|
254
|
+
inserts only `\n`. List auto-continuation still applies on the item's own marker
|
|
255
|
+
line, not every later line owned by that item.
|
|
256
|
+
`task-lists/checkbox-newline` keeps the line ending after `[ ]` in paragraph
|
|
257
|
+
flow instead of the absolutely positioned checkbox source.
|
|
258
|
+
The paired `lists/marker-separator-1` and `lists/marker-separator-2` states keep
|
|
259
|
+
the marker fixed while additional separator characters move the content right.
|
|
260
|
+
Extra spaces occupy half-em source cells. Unordered source symbols use the
|
|
261
|
+
body font and baseline in a one-em gutter cell, followed by a half-em separator.
|
|
262
|
+
Native reading bullets retain their original size, font, and nested list style;
|
|
263
|
+
we do not require unrelated glyphs to have identical pixel ink bounds across
|
|
264
|
+
fallback fonts. Geometry tests cover multiple font families and sizes.
|
|
265
|
+
|
|
266
|
+
`lists/separator-activation-inactive` and `lists/separator-activation-active`
|
|
267
|
+
show that extra source-only separator padding collapses outside the active
|
|
268
|
+
item. Nested logical gutters do not move. The explicit `all` and `none` markup
|
|
269
|
+
policies still force revelation or hiding.
|
|
270
|
+
`formatting/table-cell-outside`, `formatting/table-cell-first`, and
|
|
271
|
+
`formatting/table-cell-second` keep inline formatting markers out of the
|
|
272
|
+
inactive cells' layout. Activating another cell may resize columns; source
|
|
273
|
+
offsets remain distinct within each resulting layout.
|
|
274
|
+
|
|
275
|
+
`lists/blank-between-items` keeps list-level blank separators at their
|
|
276
|
+
surrounding container's margin, including typing and undo/redo. These separators
|
|
277
|
+
are distinct from continuation lines within a list-item paragraph.
|
|
278
|
+
`lists/first-blank-between-items` covers the first empty line immediately after
|
|
279
|
+
populated item text: its caret stays at the item's text indent, even when later
|
|
280
|
+
blank lines and another item follow. Moving to the next blank line moves to the
|
|
281
|
+
document margin. Browser tests compare each empty-line caret with the position
|
|
282
|
+
of ordinary text inserted there, across nested, ordered, and quoted lists,
|
|
283
|
+
empty items, and LF and CRLF endings. Parser source-ownership and incremental
|
|
284
|
+
reconciliation tests also cover CR endings.
|
|
285
|
+
|
|
286
|
+
`listMarkerAlignment/Source versus rendered bullet` places the production
|
|
287
|
+
source star and rendered bullet side by side. Reading bullets retain native
|
|
288
|
+
browser typography; source symbols use the body font and baseline, centered
|
|
289
|
+
in a one-em gutter slot. Browser regressions check the source column and
|
|
290
|
+
baseline across font families and sizes, and ensure reading bullets are not
|
|
291
|
+
replaced or resized. They deliberately do not require optical ink centers to
|
|
292
|
+
match across different glyphs and fallback fonts.
|
|
293
|
+
|
|
294
|
+
### Screenshot CI
|
|
295
|
+
|
|
296
|
+
All fixtures use the package-local `fixtureUtils.ts` wrapper to disable CSS
|
|
297
|
+
animations and transitions within their own container, including the mode
|
|
298
|
+
toggle and cursor. Editor examples restore live motion when **Interactive mode**
|
|
299
|
+
is enabled. The custom cycling highlighter stays fixed by default; enable
|
|
300
|
+
**Cycle keyword colors** to exercise its live observable updates. Property
|
|
301
|
+
fixtures keep their complete diagnostic evidence in a **Replay log** disclosure,
|
|
302
|
+
collapsed by default so screenshots capture the editor rather than the JSON.
|
|
303
|
+
|
|
304
|
+
The `markdown-editor-screenshots` workflow captures every fixture discovered
|
|
305
|
+
by this package's Component Explorer configuration, including content,
|
|
306
|
+
diagnostic, property, and widget fixtures. There is no fixture-ID allowlist
|
|
307
|
+
or fixed fixture count; new fixtures are included automatically. The separate
|
|
308
|
+
screenshot job runs for every PR targeting main and every push to main, without
|
|
309
|
+
changed-path gates. Turbo decides which computations can be reused; commit
|
|
310
|
+
manifest publication always runs for authorized events, including cache hits.
|
|
311
|
+
This registers unchanged snapshots for new commit SHAs so unrelated main
|
|
312
|
+
changes do not leave holes in the baseline history. Pages reload
|
|
313
|
+
between fixtures to isolate their rendering. Capture uses `build:fixtures`
|
|
314
|
+
and `component-explorer.screenshots.json` to serve a static build on an
|
|
315
|
+
ephemeral local port, avoiding dev-server dependency optimization and module
|
|
316
|
+
reloads during a full run. Interactive exploration still uses the regular
|
|
317
|
+
`component-explorer.json` dev-server configuration. On the hosted Ubuntu runner,
|
|
318
|
+
CI removes the unused Android SDK before installing dependencies to leave
|
|
319
|
+
disk space for the full capture. The package-owned
|
|
320
|
+
`scripts/screenshots.mjs` and `screenshots` task store their
|
|
321
|
+
validated render JSON (without Git commit metadata or PNGs) in Turborepo's
|
|
322
|
+
cross-commit cache. The publish step attaches the *current* commit and the
|
|
323
|
+
`markdown-editor` service project ID, checks each content hash against
|
|
324
|
+
the screenshot service, and uploads only missing PNGs. If a cached hash is
|
|
325
|
+
missing remotely and its PNG is no longer local, it recaptures and verifies
|
|
326
|
+
the image before publishing; unchanged hashes already present remotely need
|
|
327
|
+
no browser run on a cache hit.
|
|
328
|
+
|
|
329
|
+
CI restores only the published-cache namespace and saves it after successful
|
|
330
|
+
image/manifest upload and validation. Fork and Dependabot runs do not populate
|
|
331
|
+
this cache. Thus a reusable CI snapshot's images have already been published;
|
|
332
|
+
PNGs remain in the service rather than in Turbo. The existing missing-image
|
|
333
|
+
recovery also supports local caches and older snapshots.
|
|
334
|
+
|
|
335
|
+
Before consulting the screenshot cache, CI builds the renderer and its
|
|
336
|
+
dependencies with `pnpm --filter @vscode/component-explorer-cli... run build`.
|
|
337
|
+
This deliberately bypasses Turbo's dependency-build cache: package builds can
|
|
338
|
+
also generate external dependency outputs (such as LinkRPC), which are not
|
|
339
|
+
restored by a cache entry containing only that package's `dist` directory.
|
|
340
|
+
Screenshot render results remain cached across commits.
|
|
341
|
+
Screenshot-script tests and fixture typechecking are explicit Turbo tasks.
|
|
342
|
+
Rendering depends on successful fixture typechecking, including on cache hits;
|
|
343
|
+
unchanged successful checks need not execute again. Commit metadata, service
|
|
344
|
+
publication, and PR reporting remain outside the cached tasks.
|
|
345
|
+
|
|
346
|
+
Image lookups run in batches of at most eight, use a 10-second timeout per attempt, and retry transient network
|
|
347
|
+
errors and HTTP 429/500/502/503/504 responses up to three total attempts, with
|
|
348
|
+
one- and two-second backoffs logged to CI. Only HTTP 404 means an image is
|
|
349
|
+
missing; persistent service errors fail preparation rather than being hidden.
|
|
350
|
+
The workflow archives the per-commit manifest and writes an advisory
|
|
351
|
+
base-commit comparison with before/after screenshots to the job summary.
|
|
352
|
+
Non-fork PRs also get a single updated comparison comment. Large comments
|
|
353
|
+
stop at a complete fixture boundary below GitHub's size limit; the complete
|
|
354
|
+
comparison remains in the job summary and `markdown-editor-screenshot-report`
|
|
355
|
+
artifact. Comparisons can
|
|
356
|
+
read the legacy `markdown-editor-pilot` baseline until main has published
|
|
357
|
+
under the new project ID; new uploads always use `markdown-editor`.
|
|
358
|
+
Diagnostic fixture errors remain in the published manifest and are listed
|
|
359
|
+
explicitly in the comparison report, including fixtures that could not produce
|
|
360
|
+
an image. Every fixture must pass diagnostics for required CI to be green,
|
|
361
|
+
including when its result is restored from the screenshot cache. The diagnostic
|
|
362
|
+
check runs after artifacts, uploads, reports, and PR comments so failures retain
|
|
363
|
+
their evidence. Run `node scripts/screenshots.mjs check` locally to check the
|
|
364
|
+
cached manifest, or pass a manifest path to check a specific capture.
|
|
365
|
+
Visual screenshot changes remain advisory, not merge gates.
|
|
366
|
+
Empty, duplicate, or malformed manifests, infrastructure failures, and
|
|
367
|
+
invalid image hashes still fail CI.
|
|
368
|
+
|
|
369
|
+
The service must support its existing `/images/<sha256>`,
|
|
370
|
+
`/commits/<owner>/<repo>/<sha>`, and authenticated `/upload` endpoints, with
|
|
371
|
+
project snapshots enabled. The upload step sends the manifest and
|
|
372
|
+
missing PNGs as a ZIP directly; no service-side GitHub token is needed to
|
|
373
|
+
download Actions artifacts. Main-branch pushes and non-fork PRs authenticate using GitHub
|
|
374
|
+
Actions OIDC (the same mechanism used by VS Code screenshot CI), not a new
|
|
375
|
+
repository secret. The service must authorize this repository's main pushes
|
|
376
|
+
and non-fork PR tokens for its OIDC audience. Fork and Dependabot PRs skip
|
|
377
|
+
OIDC upload and commenting; their job summary links to the workflow artifacts
|
|
378
|
+
instead of embedding unpublished images. Upload or unexpected baseline-service
|
|
379
|
+
errors fail CI explicitly, while artifacts are preserved for inspection.
|
|
380
|
+
The reusable `markdown-editor-screenshots` workflow handles rendering,
|
|
381
|
+
archiving, upload, and reporting for both callers. Both `required` and the
|
|
382
|
+
main-push-only `markdown-editor-screenshots-publish` caller explicitly grant
|
|
383
|
+
`contents: read`, `id-token: write`, and `pull-requests: write`; reusable
|
|
384
|
+
workflows cannot elevate their caller's permissions.
|
|
385
|
+
The workflow's
|
|
386
|
+
public service URL and runner/font configuration must be updated together
|
|
387
|
+
when changing service or rendering environment; renderer source, fixture
|
|
388
|
+
inputs, dependency lockfile, and the runner image version participate in
|
|
389
|
+
the Turbo cache key. Branch protection still requires the repository
|
|
390
|
+
administrator to mark the umbrella `Required / required` check as required.
|
|
391
|
+
|
|
392
|
+
Screenshot orchestration, contract tests (`pnpm run test:screenshots`), and
|
|
393
|
+
the Turbo task configuration live in this package. Component Explorer provides
|
|
394
|
+
the reusable renderer and screenshot service, with no Markdown-specific scripts.
|
|
395
|
+
The `markdown-editor-screenshots` artifact contains the upload manifest and new
|
|
396
|
+
PNGs; `markdown-editor-screenshot-render` preserves render diagnostics.
|
|
397
|
+
|
|
7
398
|
Start with the [current implementation specification](./docs/specification.md).
|
|
8
399
|
It explains the architecture, runtime data flow, public integration surface,
|
|
9
400
|
extension points, the VS Code custom text editor adapter, tests, and current
|
|
@@ -29,3 +420,37 @@ Playwright reuses test servers from the same worktree using a deterministic
|
|
|
29
420
|
worktree-specific port pair. Set `VSCODE_MARKDOWN_EDITOR_E2E_BASE_PORT` to the
|
|
30
421
|
first port of a different adjacent pair if the generated ports conflict with
|
|
31
422
|
another local service.
|
|
423
|
+
|
|
424
|
+
From the `vscode-packages` workspace root, run `tilt up` to supervise the editor
|
|
425
|
+
test page in Tilt's local web UI at http://localhost:10350. Tilt checks the
|
|
426
|
+
workspace installation with `pnpm install --frozen-lockfile` first; the `editor`
|
|
427
|
+
resource then serves the test page at its worktree-specific URL (shown in the
|
|
428
|
+
Tilt UI). Enable the optional `fixtures` resource in the UI to build and serve
|
|
429
|
+
the Component Explorer fixtures on the adjacent port. The servers run locally;
|
|
430
|
+
Docker and Kubernetes are not needed. Disable either server in the UI to stop
|
|
431
|
+
it, or run `tilt down` to stop Tilt's resources. To start only the fixtures
|
|
432
|
+
from the command line, use `tilt up fixtures`.
|
|
433
|
+
|
|
434
|
+
Install [Tilt](https://docs.tilt.dev/install.html) and use a Node installation
|
|
435
|
+
that supports TypeScript type stripping (Node 22.6+). Corepack runs the pnpm
|
|
436
|
+
version pinned in the workspace's `package.json`. The same
|
|
437
|
+
`VSCODE_MARKDOWN_EDITOR_E2E_BASE_PORT` override applies to both Tilt servers.
|
|
438
|
+
|
|
439
|
+
The multi-repository workspace also has a `Tiltfile` beside
|
|
440
|
+
`markdown-editor.code-workspace`. Run `tilt up` from that directory to see the
|
|
441
|
+
package resources and optional VS Code resources in one dashboard. From either
|
|
442
|
+
dashboard, enable `markdown-explorer` for the interactive Component Explorer
|
|
443
|
+
(port 5339), `explorer-demo` for its demo app (port 5174),
|
|
444
|
+
`markdown-package-watch`, or `team-tools-watch`. The `fixtures` resource above
|
|
445
|
+
is a built preview, not the interactive Component Explorer CLI server. Enabling
|
|
446
|
+
`markdown-explorer` requires stopping any separately launched Component
|
|
447
|
+
Explorer daemon for this same project first; Tilt will not terminate it.
|
|
448
|
+
|
|
449
|
+
In the multi-repository dashboard, `vscode-markdown-webview-watch` and
|
|
450
|
+
`vscode-client-watch` run watchers from the VS Code checkout, while
|
|
451
|
+
`vscode-explorer` serves its separate Component Explorer (port 5337).
|
|
452
|
+
`vscode-extension-host` builds Team Tools and launches Code - OSS with an
|
|
453
|
+
isolated profile, no built-in or installed extensions, and only the Team Tools
|
|
454
|
+
development extension. Disabling the resource closes that window, not other
|
|
455
|
+
VS Code instances. The VS Code checkout needs its own dependencies installed
|
|
456
|
+
before enabling its watchers or Component Explorer.
|
package/dist/commands.js
CHANGED
|
@@ -147,7 +147,7 @@ const r = ["macos"], n = ["windows", "linux"], o = (i, u = !1) => ({
|
|
|
147
147
|
e("markdown.editor.joinLines", "Join Lines", d("joinLines"), [
|
|
148
148
|
t("j", { ctrl: !0 }, r)
|
|
149
149
|
]),
|
|
150
|
-
e("markdown.editor.toggleLocked", "Toggle
|
|
150
|
+
e("markdown.editor.toggleLocked", "Toggle Markdown Read-only", { kind: "toggleReadonly" }, [
|
|
151
151
|
t("e", { meta: !0 }, r)
|
|
152
152
|
]),
|
|
153
153
|
e("markdown.editor.undo", "Undo", c("undo"), [
|
package/dist/commands.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commands.js","sources":["../src/editorCommands.ts"],"sourcesContent":["export type KeyboardPlatform = 'macos' | 'windows' | 'linux';\n\nexport type CursorKeyboardAction =\n\t| 'left'\n\t| 'right'\n\t| 'up'\n\t| 'down'\n\t| 'wordLeft'\n\t| 'wordRight'\n\t| 'visualLineStart'\n\t| 'visualLineEnd'\n\t| 'logicalLineStart'\n\t| 'logicalLineEnd'\n\t| 'documentStart'\n\t| 'documentEnd';\n\nexport type EditKeyboardAction =\n\t| 'deleteLeft'\n\t| 'deleteRight'\n\t| 'deleteWordLeft'\n\t| 'deleteWordRight'\n\t| 'deleteLineLeft'\n\t| 'deleteLineRight'\n\t| 'copyLinesUp'\n\t| 'copyLinesDown'\n\t| 'moveLinesUp'\n\t| 'moveLinesDown'\n\t| 'deleteLines'\n\t| 'joinLines';\n\nexport type HistoryKeyboardAction = 'undo' | 'redo';\nexport type TabKeyboardAction = 'insert' | 'outdent';\n\nexport type EditorKeyboardAction =\n\t| { readonly kind: 'cursor'; readonly command: CursorKeyboardAction; readonly extend: boolean }\n\t| { readonly kind: 'edit'; readonly command: EditKeyboardAction }\n\t| { readonly kind: 'history'; readonly command: HistoryKeyboardAction }\n\t| { readonly kind: 'tab'; readonly command: TabKeyboardAction }\n\t| { readonly kind: 'toggleTabFocus' }\n\t| { readonly kind: 'toggleReadonly' }\n\t| { readonly kind: 'selectAll' }\n\t| { readonly kind: 'enter'; readonly command: 'smartEnter' | 'insertParagraph' | 'insertHardLineBreak' };\n\nexport interface KeyboardModifiers {\n\treadonly shift?: boolean;\n\treadonly alt?: boolean;\n\treadonly ctrl?: boolean;\n\treadonly meta?: boolean;\n}\n\nexport interface EditorCommandKeybinding {\n\treadonly key: string;\n\treadonly modifiers?: KeyboardModifiers;\n\treadonly platforms?: readonly KeyboardPlatform[];\n}\n\nexport interface EditorCommandDefinition {\n\treadonly id: `markdown.editor.${string}`;\n\treadonly title: string;\n\treadonly action: EditorKeyboardAction;\n\treadonly keybindings: readonly EditorCommandKeybinding[];\n\t/**\n\t * Local commands must execute synchronously in the webview instead of being\n\t * forwarded through the VS Code keybinding service.\n\t */\n\treadonly routing?: 'host' | 'local';\n}\n\nconst MACOS = ['macos'] as const;\nconst NON_MACOS = ['windows', 'linux'] as const;\n\nconst cursor = (command: CursorKeyboardAction, extend = false): EditorKeyboardAction => ({\n\tkind: 'cursor',\n\tcommand,\n\textend,\n});\nconst edit = (command: EditKeyboardAction): EditorKeyboardAction => ({ kind: 'edit', command });\nconst history = (command: HistoryKeyboardAction): EditorKeyboardAction => ({ kind: 'history', command });\nconst tab = (command: TabKeyboardAction): EditorKeyboardAction => ({ kind: 'tab', command });\nconst enter = (command: 'smartEnter' | 'insertParagraph' | 'insertHardLineBreak'): EditorKeyboardAction => ({\n\tkind: 'enter',\n\tcommand,\n});\nconst binding = (\n\tkey: string,\n\tmodifiers?: KeyboardModifiers,\n\tplatforms?: readonly KeyboardPlatform[],\n): EditorCommandKeybinding => ({ key, modifiers, platforms });\nconst command = (\n\tid: EditorCommandDefinition['id'],\n\ttitle: string,\n\taction: EditorKeyboardAction,\n\tkeybindings: readonly EditorCommandKeybinding[],\n\trouting: EditorCommandDefinition['routing'] = 'host',\n): EditorCommandDefinition => ({ id, title, action, keybindings, routing });\n\n/**\n * Canonical editor command catalog. Standalone keyboard handling and host\n * integrations derive their command registration and default keybindings from\n * this list.\n */\nexport const commands: readonly EditorCommandDefinition[] = [\n\tcommand('markdown.editor.cursorLeft', 'Move Cursor Left', cursor('left'), [\n\t\tbinding('b', { ctrl: true }, MACOS),\n\t\tbinding('ArrowLeft'),\n\t]),\n\tcommand('markdown.editor.cursorRight', 'Move Cursor Right', cursor('right'), [\n\t\tbinding('f', { ctrl: true }, MACOS),\n\t\tbinding('ArrowRight'),\n\t]),\n\tcommand('markdown.editor.cursorUp', 'Move Cursor Up', cursor('up'), [\n\t\tbinding('p', { ctrl: true }, MACOS),\n\t\tbinding('ArrowUp'),\n\t]),\n\tcommand('markdown.editor.cursorDown', 'Move Cursor Down', cursor('down'), [\n\t\tbinding('n', { ctrl: true }, MACOS),\n\t\tbinding('ArrowDown'),\n\t]),\n\tcommand('markdown.editor.cursorLeftSelect', 'Select Left', cursor('left', true), [\n\t\tbinding('ArrowLeft', { shift: true }),\n\t]),\n\tcommand('markdown.editor.cursorRightSelect', 'Select Right', cursor('right', true), [\n\t\tbinding('ArrowRight', { shift: true }),\n\t]),\n\tcommand('markdown.editor.cursorUpSelect', 'Select Up', cursor('up', true), [\n\t\tbinding('ArrowUp', { shift: true }),\n\t]),\n\tcommand('markdown.editor.cursorDownSelect', 'Select Down', cursor('down', true), [\n\t\tbinding('ArrowDown', { shift: true }),\n\t]),\n\tcommand('markdown.editor.cursorWordLeft', 'Move Cursor Word Left', cursor('wordLeft'), [\n\t\tbinding('ArrowLeft', { alt: true }, MACOS),\n\t\tbinding('ArrowLeft', { ctrl: true }, NON_MACOS),\n\t]),\n\tcommand('markdown.editor.cursorWordRight', 'Move Cursor Word Right', cursor('wordRight'), [\n\t\tbinding('ArrowRight', { alt: true }, MACOS),\n\t\tbinding('ArrowRight', { ctrl: true }, NON_MACOS),\n\t]),\n\tcommand('markdown.editor.cursorWordLeftSelect', 'Select Word Left', cursor('wordLeft', true), [\n\t\tbinding('ArrowLeft', { alt: true, shift: true }, MACOS),\n\t\tbinding('ArrowLeft', { ctrl: true, shift: true }, NON_MACOS),\n\t]),\n\tcommand('markdown.editor.cursorWordRightSelect', 'Select Word Right', cursor('wordRight', true), [\n\t\tbinding('ArrowRight', { alt: true, shift: true }, MACOS),\n\t\tbinding('ArrowRight', { ctrl: true, shift: true }, NON_MACOS),\n\t]),\n\tcommand('markdown.editor.cursorVisualLineStart', 'Move Cursor to Visual Line Start', cursor('visualLineStart'), [\n\t\tbinding('ArrowLeft', { meta: true }, MACOS),\n\t\tbinding('Home'),\n\t]),\n\tcommand('markdown.editor.cursorVisualLineEnd', 'Move Cursor to Visual Line End', cursor('visualLineEnd'), [\n\t\tbinding('ArrowRight', { meta: true }, MACOS),\n\t\tbinding('End'),\n\t]),\n\tcommand('markdown.editor.cursorVisualLineStartSelect', 'Select to Visual Line Start', cursor('visualLineStart', true), [\n\t\tbinding('ArrowLeft', { meta: true, shift: true }, MACOS),\n\t\tbinding('Home', { shift: true }),\n\t]),\n\tcommand('markdown.editor.cursorVisualLineEndSelect', 'Select to Visual Line End', cursor('visualLineEnd', true), [\n\t\tbinding('ArrowRight', { meta: true, shift: true }, MACOS),\n\t\tbinding('End', { shift: true }),\n\t]),\n\tcommand('markdown.editor.cursorLogicalLineStart', 'Move Cursor to Logical Line Start', cursor('logicalLineStart'), [\n\t\tbinding('a', { ctrl: true }, MACOS),\n\t]),\n\tcommand('markdown.editor.cursorLogicalLineEnd', 'Move Cursor to Logical Line End', cursor('logicalLineEnd'), [\n\t\tbinding('e', { ctrl: true }, MACOS),\n\t]),\n\tcommand('markdown.editor.cursorLogicalLineStartSelect', 'Select to Logical Line Start', cursor('logicalLineStart', true), [\n\t\tbinding('a', { ctrl: true, shift: true }, MACOS),\n\t]),\n\tcommand('markdown.editor.cursorLogicalLineEndSelect', 'Select to Logical Line End', cursor('logicalLineEnd', true), [\n\t\tbinding('e', { ctrl: true, shift: true }, MACOS),\n\t]),\n\tcommand('markdown.editor.cursorDocumentStart', 'Move Cursor to Document Start', cursor('documentStart'), [\n\t\tbinding('ArrowUp', { meta: true }, MACOS),\n\t\tbinding('Home', { ctrl: true }, NON_MACOS),\n\t]),\n\tcommand('markdown.editor.cursorDocumentEnd', 'Move Cursor to Document End', cursor('documentEnd'), [\n\t\tbinding('ArrowDown', { meta: true }, MACOS),\n\t\tbinding('End', { ctrl: true }, NON_MACOS),\n\t]),\n\tcommand('markdown.editor.cursorDocumentStartSelect', 'Select to Document Start', cursor('documentStart', true), [\n\t\tbinding('ArrowUp', { meta: true, shift: true }, MACOS),\n\t\tbinding('Home', { ctrl: true, shift: true }, NON_MACOS),\n\t]),\n\tcommand('markdown.editor.cursorDocumentEndSelect', 'Select to Document End', cursor('documentEnd', true), [\n\t\tbinding('ArrowDown', { meta: true, shift: true }, MACOS),\n\t\tbinding('End', { ctrl: true, shift: true }, NON_MACOS),\n\t]),\n\tcommand('markdown.editor.selectAll', 'Select All', { kind: 'selectAll' }, [\n\t\tbinding('a', { meta: true }, MACOS),\n\t\tbinding('a', { ctrl: true }, NON_MACOS),\n\t]),\n\tcommand('markdown.editor.deleteLeft', 'Delete Left', edit('deleteLeft'), [\n\t\tbinding('h', { ctrl: true }, MACOS),\n\t\tbinding('Backspace', { ctrl: true }, MACOS),\n\t\tbinding('Backspace'),\n\t\tbinding('Backspace', { shift: true }),\n\t]),\n\tcommand('markdown.editor.deleteRight', 'Delete Right', edit('deleteRight'), [\n\t\tbinding('d', { ctrl: true }, MACOS),\n\t\tbinding('Delete', { ctrl: true }, MACOS),\n\t\tbinding('Delete'),\n\t]),\n\tcommand('markdown.editor.deleteWordLeft', 'Delete Word Left', edit('deleteWordLeft'), [\n\t\tbinding('Backspace', { alt: true }, MACOS),\n\t\tbinding('Backspace', { ctrl: true }, NON_MACOS),\n\t]),\n\tcommand('markdown.editor.deleteWordRight', 'Delete Word Right', edit('deleteWordRight'), [\n\t\tbinding('Delete', { alt: true }, MACOS),\n\t\tbinding('Delete', { ctrl: true }, NON_MACOS),\n\t]),\n\tcommand('markdown.editor.deleteLineLeft', 'Delete All Left', edit('deleteLineLeft'), [\n\t\tbinding('Backspace', { meta: true }, MACOS),\n\t]),\n\tcommand('markdown.editor.deleteLineRight', 'Delete All Right', edit('deleteLineRight'), [\n\t\tbinding('Delete', { meta: true }, MACOS),\n\t\tbinding('k', { ctrl: true }, MACOS),\n\t]),\n\tcommand('markdown.editor.copyLinesUp', 'Copy Line Up', edit('copyLinesUp'), [\n\t\tbinding('ArrowUp', { alt: true, shift: true }, MACOS),\n\t\tbinding('ArrowUp', { alt: true, shift: true }, ['windows']),\n\t\tbinding('ArrowUp', { ctrl: true, alt: true, shift: true }, ['linux']),\n\t]),\n\tcommand('markdown.editor.copyLinesDown', 'Copy Line Down', edit('copyLinesDown'), [\n\t\tbinding('ArrowDown', { alt: true, shift: true }, MACOS),\n\t\tbinding('ArrowDown', { alt: true, shift: true }, ['windows']),\n\t\tbinding('ArrowDown', { ctrl: true, alt: true, shift: true }, ['linux']),\n\t]),\n\tcommand('markdown.editor.moveLinesUp', 'Move Line Up', edit('moveLinesUp'), [\n\t\tbinding('ArrowUp', { alt: true }),\n\t]),\n\tcommand('markdown.editor.moveLinesDown', 'Move Line Down', edit('moveLinesDown'), [\n\t\tbinding('ArrowDown', { alt: true }),\n\t]),\n\tcommand('markdown.editor.deleteLines', 'Delete Line', edit('deleteLines'), [\n\t\tbinding('k', { meta: true, shift: true }, MACOS),\n\t\tbinding('k', { ctrl: true, shift: true }, NON_MACOS),\n\t]),\n\tcommand('markdown.editor.joinLines', 'Join Lines', edit('joinLines'), [\n\t\tbinding('j', { ctrl: true }, MACOS),\n\t]),\n\tcommand('markdown.editor.toggleLocked', 'Toggle Editing/Locked Mode', { kind: 'toggleReadonly' }, [\n\t\tbinding('e', { meta: true }, MACOS),\n\t]),\n\tcommand('markdown.editor.undo', 'Undo', history('undo'), [\n\t\tbinding('z', { meta: true }, MACOS),\n\t\tbinding('z', { ctrl: true }, NON_MACOS),\n\t]),\n\tcommand('markdown.editor.redo', 'Redo', history('redo'), [\n\t\tbinding('z', { meta: true, shift: true }, MACOS),\n\t\tbinding('z', { ctrl: true, shift: true }, NON_MACOS),\n\t\tbinding('y', { ctrl: true }, NON_MACOS),\n\t]),\n\tcommand('markdown.editor.insertTab', 'Insert Tab', tab('insert'), [\n\t\tbinding('Tab'),\n\t], 'local'),\n\tcommand('markdown.editor.outdent', 'Outdent', tab('outdent'), [\n\t\tbinding('Tab', { shift: true }),\n\t], 'local'),\n\tcommand('markdown.editor.toggleTabFocus', 'Toggle Tab Key Moves Focus', { kind: 'toggleTabFocus' }, [\n\t\tbinding('m', { ctrl: true }),\n\t], 'local'),\n\tcommand('markdown.editor.smartEnter', 'Insert Paragraph', enter('smartEnter'), [\n\t\tbinding('Enter'),\n\t]),\n\tcommand('markdown.editor.insertHardLineBreak', 'Insert Hard Line Break', enter('insertHardLineBreak'), [\n\t\tbinding('Enter', { shift: true }),\n\t]),\n\tcommand('markdown.editor.insertParagraph', 'Insert Paragraph Without Continuing Markup', enter('insertParagraph'), [\n\t\tbinding('Enter', { meta: true }, MACOS),\n\t\tbinding('Enter', { ctrl: true }),\n\t]),\n];\n"],"names":["MACOS","NON_MACOS","cursor","command","extend","edit","history","tab","enter","binding","key","modifiers","platforms","id","title","action","keybindings","routing","commands"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"commands.js","sources":["../src/editorCommands.ts"],"sourcesContent":["export type KeyboardPlatform = 'macos' | 'windows' | 'linux';\n\nexport type CursorKeyboardAction =\n\t| 'left'\n\t| 'right'\n\t| 'up'\n\t| 'down'\n\t| 'wordLeft'\n\t| 'wordRight'\n\t| 'visualLineStart'\n\t| 'visualLineEnd'\n\t| 'logicalLineStart'\n\t| 'logicalLineEnd'\n\t| 'documentStart'\n\t| 'documentEnd';\n\nexport type EditKeyboardAction =\n\t| 'deleteLeft'\n\t| 'deleteRight'\n\t| 'deleteWordLeft'\n\t| 'deleteWordRight'\n\t| 'deleteLineLeft'\n\t| 'deleteLineRight'\n\t| 'copyLinesUp'\n\t| 'copyLinesDown'\n\t| 'moveLinesUp'\n\t| 'moveLinesDown'\n\t| 'deleteLines'\n\t| 'joinLines';\n\nexport type HistoryKeyboardAction = 'undo' | 'redo';\nexport type TabKeyboardAction = 'insert' | 'outdent';\n\nexport type EditorKeyboardAction =\n\t| { readonly kind: 'cursor'; readonly command: CursorKeyboardAction; readonly extend: boolean }\n\t| { readonly kind: 'edit'; readonly command: EditKeyboardAction }\n\t| { readonly kind: 'history'; readonly command: HistoryKeyboardAction }\n\t| { readonly kind: 'tab'; readonly command: TabKeyboardAction }\n\t| { readonly kind: 'toggleTabFocus' }\n\t| { readonly kind: 'toggleReadonly' }\n\t| { readonly kind: 'selectAll' }\n\t| { readonly kind: 'enter'; readonly command: 'smartEnter' | 'insertParagraph' | 'insertHardLineBreak' };\n\nexport interface KeyboardModifiers {\n\treadonly shift?: boolean;\n\treadonly alt?: boolean;\n\treadonly ctrl?: boolean;\n\treadonly meta?: boolean;\n}\n\nexport interface EditorCommandKeybinding {\n\treadonly key: string;\n\treadonly modifiers?: KeyboardModifiers;\n\treadonly platforms?: readonly KeyboardPlatform[];\n}\n\nexport interface EditorCommandDefinition {\n\treadonly id: `markdown.editor.${string}`;\n\treadonly title: string;\n\treadonly action: EditorKeyboardAction;\n\treadonly keybindings: readonly EditorCommandKeybinding[];\n\t/**\n\t * Local commands must execute synchronously in the webview instead of being\n\t * forwarded through the VS Code keybinding service.\n\t */\n\treadonly routing?: 'host' | 'local';\n}\n\nconst MACOS = ['macos'] as const;\nconst NON_MACOS = ['windows', 'linux'] as const;\n\nconst cursor = (command: CursorKeyboardAction, extend = false): EditorKeyboardAction => ({\n\tkind: 'cursor',\n\tcommand,\n\textend,\n});\nconst edit = (command: EditKeyboardAction): EditorKeyboardAction => ({ kind: 'edit', command });\nconst history = (command: HistoryKeyboardAction): EditorKeyboardAction => ({ kind: 'history', command });\nconst tab = (command: TabKeyboardAction): EditorKeyboardAction => ({ kind: 'tab', command });\nconst enter = (command: 'smartEnter' | 'insertParagraph' | 'insertHardLineBreak'): EditorKeyboardAction => ({\n\tkind: 'enter',\n\tcommand,\n});\nconst binding = (\n\tkey: string,\n\tmodifiers?: KeyboardModifiers,\n\tplatforms?: readonly KeyboardPlatform[],\n): EditorCommandKeybinding => ({ key, modifiers, platforms });\nconst command = (\n\tid: EditorCommandDefinition['id'],\n\ttitle: string,\n\taction: EditorKeyboardAction,\n\tkeybindings: readonly EditorCommandKeybinding[],\n\trouting: EditorCommandDefinition['routing'] = 'host',\n): EditorCommandDefinition => ({ id, title, action, keybindings, routing });\n\n/**\n * Canonical editor command catalog. Standalone keyboard handling and host\n * integrations derive their command registration and default keybindings from\n * this list.\n */\nexport const commands: readonly EditorCommandDefinition[] = [\n\tcommand('markdown.editor.cursorLeft', 'Move Cursor Left', cursor('left'), [\n\t\tbinding('b', { ctrl: true }, MACOS),\n\t\tbinding('ArrowLeft'),\n\t]),\n\tcommand('markdown.editor.cursorRight', 'Move Cursor Right', cursor('right'), [\n\t\tbinding('f', { ctrl: true }, MACOS),\n\t\tbinding('ArrowRight'),\n\t]),\n\tcommand('markdown.editor.cursorUp', 'Move Cursor Up', cursor('up'), [\n\t\tbinding('p', { ctrl: true }, MACOS),\n\t\tbinding('ArrowUp'),\n\t]),\n\tcommand('markdown.editor.cursorDown', 'Move Cursor Down', cursor('down'), [\n\t\tbinding('n', { ctrl: true }, MACOS),\n\t\tbinding('ArrowDown'),\n\t]),\n\tcommand('markdown.editor.cursorLeftSelect', 'Select Left', cursor('left', true), [\n\t\tbinding('ArrowLeft', { shift: true }),\n\t]),\n\tcommand('markdown.editor.cursorRightSelect', 'Select Right', cursor('right', true), [\n\t\tbinding('ArrowRight', { shift: true }),\n\t]),\n\tcommand('markdown.editor.cursorUpSelect', 'Select Up', cursor('up', true), [\n\t\tbinding('ArrowUp', { shift: true }),\n\t]),\n\tcommand('markdown.editor.cursorDownSelect', 'Select Down', cursor('down', true), [\n\t\tbinding('ArrowDown', { shift: true }),\n\t]),\n\tcommand('markdown.editor.cursorWordLeft', 'Move Cursor Word Left', cursor('wordLeft'), [\n\t\tbinding('ArrowLeft', { alt: true }, MACOS),\n\t\tbinding('ArrowLeft', { ctrl: true }, NON_MACOS),\n\t]),\n\tcommand('markdown.editor.cursorWordRight', 'Move Cursor Word Right', cursor('wordRight'), [\n\t\tbinding('ArrowRight', { alt: true }, MACOS),\n\t\tbinding('ArrowRight', { ctrl: true }, NON_MACOS),\n\t]),\n\tcommand('markdown.editor.cursorWordLeftSelect', 'Select Word Left', cursor('wordLeft', true), [\n\t\tbinding('ArrowLeft', { alt: true, shift: true }, MACOS),\n\t\tbinding('ArrowLeft', { ctrl: true, shift: true }, NON_MACOS),\n\t]),\n\tcommand('markdown.editor.cursorWordRightSelect', 'Select Word Right', cursor('wordRight', true), [\n\t\tbinding('ArrowRight', { alt: true, shift: true }, MACOS),\n\t\tbinding('ArrowRight', { ctrl: true, shift: true }, NON_MACOS),\n\t]),\n\tcommand('markdown.editor.cursorVisualLineStart', 'Move Cursor to Visual Line Start', cursor('visualLineStart'), [\n\t\tbinding('ArrowLeft', { meta: true }, MACOS),\n\t\tbinding('Home'),\n\t]),\n\tcommand('markdown.editor.cursorVisualLineEnd', 'Move Cursor to Visual Line End', cursor('visualLineEnd'), [\n\t\tbinding('ArrowRight', { meta: true }, MACOS),\n\t\tbinding('End'),\n\t]),\n\tcommand('markdown.editor.cursorVisualLineStartSelect', 'Select to Visual Line Start', cursor('visualLineStart', true), [\n\t\tbinding('ArrowLeft', { meta: true, shift: true }, MACOS),\n\t\tbinding('Home', { shift: true }),\n\t]),\n\tcommand('markdown.editor.cursorVisualLineEndSelect', 'Select to Visual Line End', cursor('visualLineEnd', true), [\n\t\tbinding('ArrowRight', { meta: true, shift: true }, MACOS),\n\t\tbinding('End', { shift: true }),\n\t]),\n\tcommand('markdown.editor.cursorLogicalLineStart', 'Move Cursor to Logical Line Start', cursor('logicalLineStart'), [\n\t\tbinding('a', { ctrl: true }, MACOS),\n\t]),\n\tcommand('markdown.editor.cursorLogicalLineEnd', 'Move Cursor to Logical Line End', cursor('logicalLineEnd'), [\n\t\tbinding('e', { ctrl: true }, MACOS),\n\t]),\n\tcommand('markdown.editor.cursorLogicalLineStartSelect', 'Select to Logical Line Start', cursor('logicalLineStart', true), [\n\t\tbinding('a', { ctrl: true, shift: true }, MACOS),\n\t]),\n\tcommand('markdown.editor.cursorLogicalLineEndSelect', 'Select to Logical Line End', cursor('logicalLineEnd', true), [\n\t\tbinding('e', { ctrl: true, shift: true }, MACOS),\n\t]),\n\tcommand('markdown.editor.cursorDocumentStart', 'Move Cursor to Document Start', cursor('documentStart'), [\n\t\tbinding('ArrowUp', { meta: true }, MACOS),\n\t\tbinding('Home', { ctrl: true }, NON_MACOS),\n\t]),\n\tcommand('markdown.editor.cursorDocumentEnd', 'Move Cursor to Document End', cursor('documentEnd'), [\n\t\tbinding('ArrowDown', { meta: true }, MACOS),\n\t\tbinding('End', { ctrl: true }, NON_MACOS),\n\t]),\n\tcommand('markdown.editor.cursorDocumentStartSelect', 'Select to Document Start', cursor('documentStart', true), [\n\t\tbinding('ArrowUp', { meta: true, shift: true }, MACOS),\n\t\tbinding('Home', { ctrl: true, shift: true }, NON_MACOS),\n\t]),\n\tcommand('markdown.editor.cursorDocumentEndSelect', 'Select to Document End', cursor('documentEnd', true), [\n\t\tbinding('ArrowDown', { meta: true, shift: true }, MACOS),\n\t\tbinding('End', { ctrl: true, shift: true }, NON_MACOS),\n\t]),\n\tcommand('markdown.editor.selectAll', 'Select All', { kind: 'selectAll' }, [\n\t\tbinding('a', { meta: true }, MACOS),\n\t\tbinding('a', { ctrl: true }, NON_MACOS),\n\t]),\n\tcommand('markdown.editor.deleteLeft', 'Delete Left', edit('deleteLeft'), [\n\t\tbinding('h', { ctrl: true }, MACOS),\n\t\tbinding('Backspace', { ctrl: true }, MACOS),\n\t\tbinding('Backspace'),\n\t\tbinding('Backspace', { shift: true }),\n\t]),\n\tcommand('markdown.editor.deleteRight', 'Delete Right', edit('deleteRight'), [\n\t\tbinding('d', { ctrl: true }, MACOS),\n\t\tbinding('Delete', { ctrl: true }, MACOS),\n\t\tbinding('Delete'),\n\t]),\n\tcommand('markdown.editor.deleteWordLeft', 'Delete Word Left', edit('deleteWordLeft'), [\n\t\tbinding('Backspace', { alt: true }, MACOS),\n\t\tbinding('Backspace', { ctrl: true }, NON_MACOS),\n\t]),\n\tcommand('markdown.editor.deleteWordRight', 'Delete Word Right', edit('deleteWordRight'), [\n\t\tbinding('Delete', { alt: true }, MACOS),\n\t\tbinding('Delete', { ctrl: true }, NON_MACOS),\n\t]),\n\tcommand('markdown.editor.deleteLineLeft', 'Delete All Left', edit('deleteLineLeft'), [\n\t\tbinding('Backspace', { meta: true }, MACOS),\n\t]),\n\tcommand('markdown.editor.deleteLineRight', 'Delete All Right', edit('deleteLineRight'), [\n\t\tbinding('Delete', { meta: true }, MACOS),\n\t\tbinding('k', { ctrl: true }, MACOS),\n\t]),\n\tcommand('markdown.editor.copyLinesUp', 'Copy Line Up', edit('copyLinesUp'), [\n\t\tbinding('ArrowUp', { alt: true, shift: true }, MACOS),\n\t\tbinding('ArrowUp', { alt: true, shift: true }, ['windows']),\n\t\tbinding('ArrowUp', { ctrl: true, alt: true, shift: true }, ['linux']),\n\t]),\n\tcommand('markdown.editor.copyLinesDown', 'Copy Line Down', edit('copyLinesDown'), [\n\t\tbinding('ArrowDown', { alt: true, shift: true }, MACOS),\n\t\tbinding('ArrowDown', { alt: true, shift: true }, ['windows']),\n\t\tbinding('ArrowDown', { ctrl: true, alt: true, shift: true }, ['linux']),\n\t]),\n\tcommand('markdown.editor.moveLinesUp', 'Move Line Up', edit('moveLinesUp'), [\n\t\tbinding('ArrowUp', { alt: true }),\n\t]),\n\tcommand('markdown.editor.moveLinesDown', 'Move Line Down', edit('moveLinesDown'), [\n\t\tbinding('ArrowDown', { alt: true }),\n\t]),\n\tcommand('markdown.editor.deleteLines', 'Delete Line', edit('deleteLines'), [\n\t\tbinding('k', { meta: true, shift: true }, MACOS),\n\t\tbinding('k', { ctrl: true, shift: true }, NON_MACOS),\n\t]),\n\tcommand('markdown.editor.joinLines', 'Join Lines', edit('joinLines'), [\n\t\tbinding('j', { ctrl: true }, MACOS),\n\t]),\n\tcommand('markdown.editor.toggleLocked', 'Toggle Markdown Read-only', { kind: 'toggleReadonly' }, [\n\t\tbinding('e', { meta: true }, MACOS),\n\t]),\n\tcommand('markdown.editor.undo', 'Undo', history('undo'), [\n\t\tbinding('z', { meta: true }, MACOS),\n\t\tbinding('z', { ctrl: true }, NON_MACOS),\n\t]),\n\tcommand('markdown.editor.redo', 'Redo', history('redo'), [\n\t\tbinding('z', { meta: true, shift: true }, MACOS),\n\t\tbinding('z', { ctrl: true, shift: true }, NON_MACOS),\n\t\tbinding('y', { ctrl: true }, NON_MACOS),\n\t]),\n\tcommand('markdown.editor.insertTab', 'Insert Tab', tab('insert'), [\n\t\tbinding('Tab'),\n\t], 'local'),\n\tcommand('markdown.editor.outdent', 'Outdent', tab('outdent'), [\n\t\tbinding('Tab', { shift: true }),\n\t], 'local'),\n\tcommand('markdown.editor.toggleTabFocus', 'Toggle Tab Key Moves Focus', { kind: 'toggleTabFocus' }, [\n\t\tbinding('m', { ctrl: true }),\n\t], 'local'),\n\tcommand('markdown.editor.smartEnter', 'Insert Paragraph', enter('smartEnter'), [\n\t\tbinding('Enter'),\n\t]),\n\tcommand('markdown.editor.insertHardLineBreak', 'Insert Hard Line Break', enter('insertHardLineBreak'), [\n\t\tbinding('Enter', { shift: true }),\n\t]),\n\tcommand('markdown.editor.insertParagraph', 'Insert Paragraph Without Continuing Markup', enter('insertParagraph'), [\n\t\tbinding('Enter', { meta: true }, MACOS),\n\t\tbinding('Enter', { ctrl: true }),\n\t]),\n];\n"],"names":["MACOS","NON_MACOS","cursor","command","extend","edit","history","tab","enter","binding","key","modifiers","platforms","id","title","action","keybindings","routing","commands"],"mappings":"AAoEA,MAAMA,IAAQ,CAAC,OAAO,GAChBC,IAAY,CAAC,WAAW,OAAO,GAE/BC,IAAS,CAACC,GAA+BC,IAAS,QAAiC;AAAA,EACxF,MAAM;AAAA,EACN,SAAAD;AAAAA,EACA,QAAAC;AACD,IACMC,IAAO,CAACF,OAAuD,EAAE,MAAM,QAAQ,SAAAA,MAC/EG,IAAU,CAACH,OAA0D,EAAE,MAAM,WAAW,SAAAA,MACxFI,IAAM,CAACJ,OAAsD,EAAE,MAAM,OAAO,SAAAA,MAC5EK,IAAQ,CAACL,OAA6F;AAAA,EAC3G,MAAM;AAAA,EACN,SAAAA;AACD,IACMM,IAAU,CACfC,GACAC,GACAC,OAC8B,EAAE,KAAAF,GAAK,WAAAC,GAAW,WAAAC,MAC3CT,IAAU,CACfU,GACAC,GACAC,GACAC,GACAC,IAA8C,YAChB,EAAE,IAAAJ,GAAI,OAAAC,GAAO,QAAAC,GAAQ,aAAAC,GAAa,SAAAC,EAAA,IAOpDC,IAA+C;AAAA,EAC3Df,EAAQ,8BAA8B,oBAAoBD,EAAO,MAAM,GAAG;AAAA,IACzEO,EAAQ,KAAK,EAAE,MAAM,GAAA,GAAQT,CAAK;AAAA,IAClCS,EAAQ,WAAW;AAAA,EAAA,CACnB;AAAA,EACDN,EAAQ,+BAA+B,qBAAqBD,EAAO,OAAO,GAAG;AAAA,IAC5EO,EAAQ,KAAK,EAAE,MAAM,GAAA,GAAQT,CAAK;AAAA,IAClCS,EAAQ,YAAY;AAAA,EAAA,CACpB;AAAA,EACDN,EAAQ,4BAA4B,kBAAkBD,EAAO,IAAI,GAAG;AAAA,IACnEO,EAAQ,KAAK,EAAE,MAAM,GAAA,GAAQT,CAAK;AAAA,IAClCS,EAAQ,SAAS;AAAA,EAAA,CACjB;AAAA,EACDN,EAAQ,8BAA8B,oBAAoBD,EAAO,MAAM,GAAG;AAAA,IACzEO,EAAQ,KAAK,EAAE,MAAM,GAAA,GAAQT,CAAK;AAAA,IAClCS,EAAQ,WAAW;AAAA,EAAA,CACnB;AAAA,EACDN,EAAQ,oCAAoC,eAAeD,EAAO,QAAQ,EAAI,GAAG;AAAA,IAChFO,EAAQ,aAAa,EAAE,OAAO,IAAM;AAAA,EAAA,CACpC;AAAA,EACDN,EAAQ,qCAAqC,gBAAgBD,EAAO,SAAS,EAAI,GAAG;AAAA,IACnFO,EAAQ,cAAc,EAAE,OAAO,IAAM;AAAA,EAAA,CACrC;AAAA,EACDN,EAAQ,kCAAkC,aAAaD,EAAO,MAAM,EAAI,GAAG;AAAA,IAC1EO,EAAQ,WAAW,EAAE,OAAO,IAAM;AAAA,EAAA,CAClC;AAAA,EACDN,EAAQ,oCAAoC,eAAeD,EAAO,QAAQ,EAAI,GAAG;AAAA,IAChFO,EAAQ,aAAa,EAAE,OAAO,IAAM;AAAA,EAAA,CACpC;AAAA,EACDN,EAAQ,kCAAkC,yBAAyBD,EAAO,UAAU,GAAG;AAAA,IACtFO,EAAQ,aAAa,EAAE,KAAK,GAAA,GAAQT,CAAK;AAAA,IACzCS,EAAQ,aAAa,EAAE,MAAM,GAAA,GAAQR,CAAS;AAAA,EAAA,CAC9C;AAAA,EACDE,EAAQ,mCAAmC,0BAA0BD,EAAO,WAAW,GAAG;AAAA,IACzFO,EAAQ,cAAc,EAAE,KAAK,GAAA,GAAQT,CAAK;AAAA,IAC1CS,EAAQ,cAAc,EAAE,MAAM,GAAA,GAAQR,CAAS;AAAA,EAAA,CAC/C;AAAA,EACDE,EAAQ,wCAAwC,oBAAoBD,EAAO,YAAY,EAAI,GAAG;AAAA,IAC7FO,EAAQ,aAAa,EAAE,KAAK,IAAM,OAAO,GAAA,GAAQT,CAAK;AAAA,IACtDS,EAAQ,aAAa,EAAE,MAAM,IAAM,OAAO,GAAA,GAAQR,CAAS;AAAA,EAAA,CAC3D;AAAA,EACDE,EAAQ,yCAAyC,qBAAqBD,EAAO,aAAa,EAAI,GAAG;AAAA,IAChGO,EAAQ,cAAc,EAAE,KAAK,IAAM,OAAO,GAAA,GAAQT,CAAK;AAAA,IACvDS,EAAQ,cAAc,EAAE,MAAM,IAAM,OAAO,GAAA,GAAQR,CAAS;AAAA,EAAA,CAC5D;AAAA,EACDE,EAAQ,yCAAyC,oCAAoCD,EAAO,iBAAiB,GAAG;AAAA,IAC/GO,EAAQ,aAAa,EAAE,MAAM,GAAA,GAAQT,CAAK;AAAA,IAC1CS,EAAQ,MAAM;AAAA,EAAA,CACd;AAAA,EACDN,EAAQ,uCAAuC,kCAAkCD,EAAO,eAAe,GAAG;AAAA,IACzGO,EAAQ,cAAc,EAAE,MAAM,GAAA,GAAQT,CAAK;AAAA,IAC3CS,EAAQ,KAAK;AAAA,EAAA,CACb;AAAA,EACDN,EAAQ,+CAA+C,+BAA+BD,EAAO,mBAAmB,EAAI,GAAG;AAAA,IACtHO,EAAQ,aAAa,EAAE,MAAM,IAAM,OAAO,GAAA,GAAQT,CAAK;AAAA,IACvDS,EAAQ,QAAQ,EAAE,OAAO,IAAM;AAAA,EAAA,CAC/B;AAAA,EACDN,EAAQ,6CAA6C,6BAA6BD,EAAO,iBAAiB,EAAI,GAAG;AAAA,IAChHO,EAAQ,cAAc,EAAE,MAAM,IAAM,OAAO,GAAA,GAAQT,CAAK;AAAA,IACxDS,EAAQ,OAAO,EAAE,OAAO,IAAM;AAAA,EAAA,CAC9B;AAAA,EACDN,EAAQ,0CAA0C,qCAAqCD,EAAO,kBAAkB,GAAG;AAAA,IAClHO,EAAQ,KAAK,EAAE,MAAM,GAAA,GAAQT,CAAK;AAAA,EAAA,CAClC;AAAA,EACDG,EAAQ,wCAAwC,mCAAmCD,EAAO,gBAAgB,GAAG;AAAA,IAC5GO,EAAQ,KAAK,EAAE,MAAM,GAAA,GAAQT,CAAK;AAAA,EAAA,CAClC;AAAA,EACDG,EAAQ,gDAAgD,gCAAgCD,EAAO,oBAAoB,EAAI,GAAG;AAAA,IACzHO,EAAQ,KAAK,EAAE,MAAM,IAAM,OAAO,GAAA,GAAQT,CAAK;AAAA,EAAA,CAC/C;AAAA,EACDG,EAAQ,8CAA8C,8BAA8BD,EAAO,kBAAkB,EAAI,GAAG;AAAA,IACnHO,EAAQ,KAAK,EAAE,MAAM,IAAM,OAAO,GAAA,GAAQT,CAAK;AAAA,EAAA,CAC/C;AAAA,EACDG,EAAQ,uCAAuC,iCAAiCD,EAAO,eAAe,GAAG;AAAA,IACxGO,EAAQ,WAAW,EAAE,MAAM,GAAA,GAAQT,CAAK;AAAA,IACxCS,EAAQ,QAAQ,EAAE,MAAM,GAAA,GAAQR,CAAS;AAAA,EAAA,CACzC;AAAA,EACDE,EAAQ,qCAAqC,+BAA+BD,EAAO,aAAa,GAAG;AAAA,IAClGO,EAAQ,aAAa,EAAE,MAAM,GAAA,GAAQT,CAAK;AAAA,IAC1CS,EAAQ,OAAO,EAAE,MAAM,GAAA,GAAQR,CAAS;AAAA,EAAA,CACxC;AAAA,EACDE,EAAQ,6CAA6C,4BAA4BD,EAAO,iBAAiB,EAAI,GAAG;AAAA,IAC/GO,EAAQ,WAAW,EAAE,MAAM,IAAM,OAAO,GAAA,GAAQT,CAAK;AAAA,IACrDS,EAAQ,QAAQ,EAAE,MAAM,IAAM,OAAO,GAAA,GAAQR,CAAS;AAAA,EAAA,CACtD;AAAA,EACDE,EAAQ,2CAA2C,0BAA0BD,EAAO,eAAe,EAAI,GAAG;AAAA,IACzGO,EAAQ,aAAa,EAAE,MAAM,IAAM,OAAO,GAAA,GAAQT,CAAK;AAAA,IACvDS,EAAQ,OAAO,EAAE,MAAM,IAAM,OAAO,GAAA,GAAQR,CAAS;AAAA,EAAA,CACrD;AAAA,EACDE,EAAQ,6BAA6B,cAAc,EAAE,MAAM,eAAe;AAAA,IACzEM,EAAQ,KAAK,EAAE,MAAM,GAAA,GAAQT,CAAK;AAAA,IAClCS,EAAQ,KAAK,EAAE,MAAM,GAAA,GAAQR,CAAS;AAAA,EAAA,CACtC;AAAA,EACDE,EAAQ,8BAA8B,eAAeE,EAAK,YAAY,GAAG;AAAA,IACxEI,EAAQ,KAAK,EAAE,MAAM,GAAA,GAAQT,CAAK;AAAA,IAClCS,EAAQ,aAAa,EAAE,MAAM,GAAA,GAAQT,CAAK;AAAA,IAC1CS,EAAQ,WAAW;AAAA,IACnBA,EAAQ,aAAa,EAAE,OAAO,IAAM;AAAA,EAAA,CACpC;AAAA,EACDN,EAAQ,+BAA+B,gBAAgBE,EAAK,aAAa,GAAG;AAAA,IAC3EI,EAAQ,KAAK,EAAE,MAAM,GAAA,GAAQT,CAAK;AAAA,IAClCS,EAAQ,UAAU,EAAE,MAAM,GAAA,GAAQT,CAAK;AAAA,IACvCS,EAAQ,QAAQ;AAAA,EAAA,CAChB;AAAA,EACDN,EAAQ,kCAAkC,oBAAoBE,EAAK,gBAAgB,GAAG;AAAA,IACrFI,EAAQ,aAAa,EAAE,KAAK,GAAA,GAAQT,CAAK;AAAA,IACzCS,EAAQ,aAAa,EAAE,MAAM,GAAA,GAAQR,CAAS;AAAA,EAAA,CAC9C;AAAA,EACDE,EAAQ,mCAAmC,qBAAqBE,EAAK,iBAAiB,GAAG;AAAA,IACxFI,EAAQ,UAAU,EAAE,KAAK,GAAA,GAAQT,CAAK;AAAA,IACtCS,EAAQ,UAAU,EAAE,MAAM,GAAA,GAAQR,CAAS;AAAA,EAAA,CAC3C;AAAA,EACDE,EAAQ,kCAAkC,mBAAmBE,EAAK,gBAAgB,GAAG;AAAA,IACpFI,EAAQ,aAAa,EAAE,MAAM,GAAA,GAAQT,CAAK;AAAA,EAAA,CAC1C;AAAA,EACDG,EAAQ,mCAAmC,oBAAoBE,EAAK,iBAAiB,GAAG;AAAA,IACvFI,EAAQ,UAAU,EAAE,MAAM,GAAA,GAAQT,CAAK;AAAA,IACvCS,EAAQ,KAAK,EAAE,MAAM,GAAA,GAAQT,CAAK;AAAA,EAAA,CAClC;AAAA,EACDG,EAAQ,+BAA+B,gBAAgBE,EAAK,aAAa,GAAG;AAAA,IAC3EI,EAAQ,WAAW,EAAE,KAAK,IAAM,OAAO,GAAA,GAAQT,CAAK;AAAA,IACpDS,EAAQ,WAAW,EAAE,KAAK,IAAM,OAAO,GAAA,GAAQ,CAAC,SAAS,CAAC;AAAA,IAC1DA,EAAQ,WAAW,EAAE,MAAM,IAAM,KAAK,IAAM,OAAO,MAAQ,CAAC,OAAO,CAAC;AAAA,EAAA,CACpE;AAAA,EACDN,EAAQ,iCAAiC,kBAAkBE,EAAK,eAAe,GAAG;AAAA,IACjFI,EAAQ,aAAa,EAAE,KAAK,IAAM,OAAO,GAAA,GAAQT,CAAK;AAAA,IACtDS,EAAQ,aAAa,EAAE,KAAK,IAAM,OAAO,GAAA,GAAQ,CAAC,SAAS,CAAC;AAAA,IAC5DA,EAAQ,aAAa,EAAE,MAAM,IAAM,KAAK,IAAM,OAAO,MAAQ,CAAC,OAAO,CAAC;AAAA,EAAA,CACtE;AAAA,EACDN,EAAQ,+BAA+B,gBAAgBE,EAAK,aAAa,GAAG;AAAA,IAC3EI,EAAQ,WAAW,EAAE,KAAK,IAAM;AAAA,EAAA,CAChC;AAAA,EACDN,EAAQ,iCAAiC,kBAAkBE,EAAK,eAAe,GAAG;AAAA,IACjFI,EAAQ,aAAa,EAAE,KAAK,IAAM;AAAA,EAAA,CAClC;AAAA,EACDN,EAAQ,+BAA+B,eAAeE,EAAK,aAAa,GAAG;AAAA,IAC1EI,EAAQ,KAAK,EAAE,MAAM,IAAM,OAAO,GAAA,GAAQT,CAAK;AAAA,IAC/CS,EAAQ,KAAK,EAAE,MAAM,IAAM,OAAO,GAAA,GAAQR,CAAS;AAAA,EAAA,CACnD;AAAA,EACDE,EAAQ,6BAA6B,cAAcE,EAAK,WAAW,GAAG;AAAA,IACrEI,EAAQ,KAAK,EAAE,MAAM,GAAA,GAAQT,CAAK;AAAA,EAAA,CAClC;AAAA,EACDG,EAAQ,gCAAgC,6BAA6B,EAAE,MAAM,oBAAoB;AAAA,IAChGM,EAAQ,KAAK,EAAE,MAAM,GAAA,GAAQT,CAAK;AAAA,EAAA,CAClC;AAAA,EACDG,EAAQ,wBAAwB,QAAQG,EAAQ,MAAM,GAAG;AAAA,IACxDG,EAAQ,KAAK,EAAE,MAAM,GAAA,GAAQT,CAAK;AAAA,IAClCS,EAAQ,KAAK,EAAE,MAAM,GAAA,GAAQR,CAAS;AAAA,EAAA,CACtC;AAAA,EACDE,EAAQ,wBAAwB,QAAQG,EAAQ,MAAM,GAAG;AAAA,IACxDG,EAAQ,KAAK,EAAE,MAAM,IAAM,OAAO,GAAA,GAAQT,CAAK;AAAA,IAC/CS,EAAQ,KAAK,EAAE,MAAM,IAAM,OAAO,GAAA,GAAQR,CAAS;AAAA,IACnDQ,EAAQ,KAAK,EAAE,MAAM,GAAA,GAAQR,CAAS;AAAA,EAAA,CACtC;AAAA,EACDE,EAAQ,6BAA6B,cAAcI,EAAI,QAAQ,GAAG;AAAA,IACjEE,EAAQ,KAAK;AAAA,EAAA,GACX,OAAO;AAAA,EACVN,EAAQ,2BAA2B,WAAWI,EAAI,SAAS,GAAG;AAAA,IAC7DE,EAAQ,OAAO,EAAE,OAAO,IAAM;AAAA,EAAA,GAC5B,OAAO;AAAA,EACVN,EAAQ,kCAAkC,8BAA8B,EAAE,MAAM,oBAAoB;AAAA,IACnGM,EAAQ,KAAK,EAAE,MAAM,IAAM;AAAA,EAAA,GACzB,OAAO;AAAA,EACVN,EAAQ,8BAA8B,oBAAoBK,EAAM,YAAY,GAAG;AAAA,IAC9EC,EAAQ,OAAO;AAAA,EAAA,CACf;AAAA,EACDN,EAAQ,uCAAuC,0BAA0BK,EAAM,qBAAqB,GAAG;AAAA,IACtGC,EAAQ,SAAS,EAAE,OAAO,IAAM;AAAA,EAAA,CAChC;AAAA,EACDN,EAAQ,mCAAmC,8CAA8CK,EAAM,iBAAiB,GAAG;AAAA,IAClHC,EAAQ,SAAS,EAAE,MAAM,GAAA,GAAQT,CAAK;AAAA,IACtCS,EAAQ,SAAS,EAAE,MAAM,IAAM;AAAA,EAAA,CAC/B;AACF;"}
|