@damiro/stylo 0.15.1 → 0.16.0
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/dist/{InPlaceView-BLlGJ9mh.js → InPlaceView-CC5hZCcI.js} +787 -750
- package/dist/InPlaceView-CC5hZCcI.js.map +1 -0
- package/dist/Preview-5lm2uUVj.js +319 -0
- package/dist/Preview-5lm2uUVj.js.map +1 -0
- package/dist/Stylo.d.ts.map +1 -1
- package/dist/editor/useCodeMirror.d.ts.map +1 -1
- package/dist/embed-DKKeCE1Y.js +109 -0
- package/dist/embed-DKKeCE1Y.js.map +1 -0
- package/dist/embed-cache-CcBfVrc9.js +176 -0
- package/dist/embed-cache-CcBfVrc9.js.map +1 -0
- package/dist/inplace/context-menu-helpers.d.ts +3 -4
- package/dist/inplace/context-menu-helpers.d.ts.map +1 -1
- package/dist/inplace/decorate.d.ts.map +1 -1
- package/dist/inplace/edit-line-prefix.d.ts.map +1 -1
- package/dist/inplace/embed.d.ts.map +1 -1
- package/dist/inplace/extension.d.ts.map +1 -1
- package/dist/inplace/inline-md.d.ts.map +1 -1
- package/dist/inplace/link-row.d.ts +14 -13
- package/dist/inplace/link-row.d.ts.map +1 -1
- package/dist/inplace/list-guides.d.ts.map +1 -1
- package/dist/inplace/math.d.ts +18 -3
- package/dist/inplace/math.d.ts.map +1 -1
- package/dist/inplace/table-widget-keys.d.ts +46 -0
- package/dist/inplace/table-widget-keys.d.ts.map +1 -0
- package/dist/inplace/table-widget.d.ts +1 -2
- package/dist/inplace/table-widget.d.ts.map +1 -1
- package/dist/inplace/tables.d.ts.map +1 -1
- package/dist/inplace/wikilinks.d.ts +1 -1
- package/dist/inplace/wikilinks.d.ts.map +1 -1
- package/dist/render/Embed.d.ts.map +1 -1
- package/dist/render/Preview.d.ts.map +1 -1
- package/dist/render/embed-cache.d.ts +13 -0
- package/dist/render/embed-cache.d.ts.map +1 -1
- package/dist/render/preview-components.d.ts +22 -0
- package/dist/render/preview-components.d.ts.map +1 -0
- package/dist/render/remark-wikilink.d.ts.map +1 -1
- package/dist/render/taskCheckbox.d.ts +30 -0
- package/dist/render/taskCheckbox.d.ts.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/stylo.js +208 -196
- package/dist/stylo.js.map +1 -1
- package/dist/toolbar/Toolbar.d.ts.map +1 -1
- package/dist/toolbar/command-helpers.d.ts +27 -0
- package/dist/toolbar/command-helpers.d.ts.map +1 -1
- package/dist/toolbar/heading.d.ts +3 -0
- package/dist/toolbar/heading.d.ts.map +1 -1
- package/dist/toolbar/inline-ops.d.ts +6 -0
- package/dist/toolbar/inline-ops.d.ts.map +1 -1
- package/dist/toolbar/table.d.ts.map +1 -1
- package/dist/types/core.d.ts +200 -0
- package/dist/types/core.d.ts.map +1 -0
- package/dist/types/inplace.d.ts +91 -0
- package/dist/types/inplace.d.ts.map +1 -0
- package/dist/types/sources.d.ts +66 -0
- package/dist/types/sources.d.ts.map +1 -0
- package/dist/types/toolbar.d.ts +72 -0
- package/dist/types/toolbar.d.ts.map +1 -0
- package/dist/types.d.ts +11 -406
- package/dist/types.d.ts.map +1 -1
- package/dist/{useCodeMirror-QmbR0rQM.js → useCodeMirror-TAWSJQiZ.js} +345 -304
- package/dist/useCodeMirror-TAWSJQiZ.js.map +1 -0
- package/package.json +1 -1
- package/dist/InPlaceView-BLlGJ9mh.js.map +0 -1
- package/dist/Preview-DKOoZ-vr.js +0 -295
- package/dist/Preview-DKOoZ-vr.js.map +0 -1
- package/dist/embed-Dsu6b-MV.js +0 -131
- package/dist/embed-Dsu6b-MV.js.map +0 -1
- package/dist/highlight-BLVSvron.js +0 -133
- package/dist/highlight-BLVSvron.js.map +0 -1
- package/dist/inplace/table-widget-caret.d.ts +0 -11
- package/dist/inplace/table-widget-caret.d.ts.map +0 -1
- package/dist/useCodeMirror-QmbR0rQM.js.map +0 -1
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
/** One `[[wikilink]]` autocomplete candidate returned by `wikiLinkSource`. */
|
|
3
|
+
export interface WikiLinkCompletion {
|
|
4
|
+
/** Written verbatim between `[[` and `]]`. */
|
|
5
|
+
target: string;
|
|
6
|
+
/**
|
|
7
|
+
* Shown in the dropdown in place of `target`. When it differs from `target`,
|
|
8
|
+
* the accepted link is written `[[target|label]]`.
|
|
9
|
+
*/
|
|
10
|
+
label?: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Supplies `[[wikilink]]` autocomplete candidates. Called with the text typed
|
|
14
|
+
* after `[[` (before any `|`) while the caret sits inside an unclosed `[[…`;
|
|
15
|
+
* return the matches your index finds, already ordered — Stylo does not re-rank
|
|
16
|
+
* or filter. May be async (e.g. a vault search endpoint). Pass it to enable the
|
|
17
|
+
* feature; omit it and there is no wikilink completion. Read once, at mount.
|
|
18
|
+
* Affects the CodeMirror surfaces only (`source`, `split`, `in-place`).
|
|
19
|
+
*/
|
|
20
|
+
export type WikiLinkSource = (query: string) => readonly WikiLinkCompletion[] | Promise<readonly WikiLinkCompletion[]>;
|
|
21
|
+
/** One `#tag` autocomplete candidate returned by `tagSource`. */
|
|
22
|
+
export interface TagCompletion {
|
|
23
|
+
/** Written verbatim after `#`. No alias — tags have no `#tag|label` syntax. */
|
|
24
|
+
tag: string;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Supplies `#tag` autocomplete candidates. Called with the text typed after `#`
|
|
28
|
+
* while the caret sits inside an unclosed `#…` word; return the matches your
|
|
29
|
+
* index finds, already ordered — Stylo does not re-rank or filter. May be async
|
|
30
|
+
* (e.g. a tag-index lookup). Pass it to enable the feature; omit it and there is
|
|
31
|
+
* no tag completion. Read once, at mount. Never fires on a `# Heading` marker
|
|
32
|
+
* (the space breaks the match) or mid-word (`word#word`, a URL fragment).
|
|
33
|
+
*/
|
|
34
|
+
export type TagSource = (query: string) => readonly TagCompletion[] | Promise<readonly TagCompletion[]>;
|
|
35
|
+
/**
|
|
36
|
+
* Resolves an `![[ref]]` embed (transclusion) to something to render. Called
|
|
37
|
+
* with the raw reference — everything between `![[` and `]]`, trimmed, with any
|
|
38
|
+
* `#heading` / `#^blockid` / `|size` suffix left intact for the host to parse.
|
|
39
|
+
* Stylo has no vault, so it cannot resolve the reference itself; it detects the
|
|
40
|
+
* `![[…]]` and renders whatever node you return in its place. May be async (a
|
|
41
|
+
* vault lookup, a fetch). Return `null` to leave the reference as literal text.
|
|
42
|
+
*
|
|
43
|
+
* Pass it to enable embeds; omit it and `![[…]]` stays literal. Works on
|
|
44
|
+
* `preview`, `split`, and the in-place canvas (ADR-009). A `![[…]]` alone on its
|
|
45
|
+
* line renders as a **block**; one mid-sentence renders **inline** — return
|
|
46
|
+
* phrasing content (not a block element) for the inline case. `![[…]]` inside
|
|
47
|
+
* code stays literal, and inside an **in-place table cell** it stays literal too
|
|
48
|
+
* (a table cell there is for editing tabular text; `preview` / `split` do
|
|
49
|
+
* transclude in cells). Give it a stable reference — the render pipeline
|
|
50
|
+
* rebuilds when its identity changes, and the in-place canvas reads it once at
|
|
51
|
+
* mount.
|
|
52
|
+
*
|
|
53
|
+
* Results are memoised by `ref` per function identity (so a scroll or a
|
|
54
|
+
* re-render does not re-resolve). If your source's output for a given `ref` can
|
|
55
|
+
* change over time, vary the `ref` or pass a new `embedSource` to invalidate.
|
|
56
|
+
* Rejections are not cached.
|
|
57
|
+
*/
|
|
58
|
+
export type EmbedSource = (ref: string) => ReactNode | Promise<ReactNode>;
|
|
59
|
+
/** Which host resolver rejected, and the argument it was called with. */
|
|
60
|
+
export interface ResolveErrorInfo {
|
|
61
|
+
/** The prop whose function threw or returned a rejected promise. */
|
|
62
|
+
source: "embedSource" | "wikiLinkSource" | "tagSource";
|
|
63
|
+
/** What it was asked to resolve — an `![[ref]]` reference, or the `[[` query. */
|
|
64
|
+
input: string;
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=sources.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sources.d.ts","sourceRoot":"","sources":["../../src/types/sources.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAEtC,8EAA8E;AAC9E,MAAM,WAAW,kBAAkB;IACjC,8CAA8C;IAC9C,MAAM,EAAE,MAAM,CAAA;IACd;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,cAAc,GAAG,CAC3B,KAAK,EAAE,MAAM,KACV,SAAS,kBAAkB,EAAE,GAAG,OAAO,CAAC,SAAS,kBAAkB,EAAE,CAAC,CAAA;AAE3E,iEAAiE;AACjE,MAAM,WAAW,aAAa;IAC5B,+EAA+E;IAC/E,GAAG,EAAE,MAAM,CAAA;CACZ;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,SAAS,GAAG,CACtB,KAAK,EAAE,MAAM,KACV,SAAS,aAAa,EAAE,GAAG,OAAO,CAAC,SAAS,aAAa,EAAE,CAAC,CAAA;AAEjE;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,CAAA;AAEzE,yEAAyE;AACzE,MAAM,WAAW,gBAAgB;IAC/B,oEAAoE;IACpE,MAAM,EAAE,aAAa,GAAG,gBAAgB,GAAG,WAAW,CAAA;IACtD,iFAAiF;IACjF,KAAK,EAAE,MAAM,CAAA;CACd"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
import type { EditorState } from "@codemirror/state";
|
|
3
|
+
import type { EditorView } from "@codemirror/view";
|
|
4
|
+
/**
|
|
5
|
+
* Built-in toolbar command identifiers. In a `ToolbarConfig["items"]` list,
|
|
6
|
+
* `"|"` inserts a visual separator. See ADR-002 §2.
|
|
7
|
+
*/
|
|
8
|
+
export type ToolbarCommandId = "undo" | "redo" | "save" | "search" | "h1" | "h2" | "h3" | "body" | "bold" | "italic" | "strike" | "underline" | "code" | "codeBlock" | "link" | "wikilink" | "quote" | "bulletList" | "orderedList" | "task" | "hr" | "frontmatter" | "table" | "math" | "mathBlock";
|
|
9
|
+
/**
|
|
10
|
+
* A consumer-supplied toolbar button. Mixed into `ToolbarConfig["items"]`
|
|
11
|
+
* alongside the built-in ids. It runs against the same live `EditorView` the
|
|
12
|
+
* built-ins do; `isActive` / `disabled` are read back from the state on every
|
|
13
|
+
* selection, key, and pointer change, exactly like a built-in.
|
|
14
|
+
*
|
|
15
|
+
* No `keys` field: built-in shortcuts are compiled into CodeMirror's keymap at
|
|
16
|
+
* editor construction, so a custom binding would need its own keymap. Bind it
|
|
17
|
+
* yourself against `getView()` for now.
|
|
18
|
+
*/
|
|
19
|
+
export interface ToolbarCustomItem {
|
|
20
|
+
/**
|
|
21
|
+
* Stable identity, also the React key. Must not collide with a built-in id
|
|
22
|
+
* (`bold`, `h1`, …) or another custom item.
|
|
23
|
+
*/
|
|
24
|
+
id: string;
|
|
25
|
+
/** Tooltip and accessible label. */
|
|
26
|
+
title: string;
|
|
27
|
+
/** Button content — an inline SVG, a glyph, a short label. */
|
|
28
|
+
icon: ReactNode;
|
|
29
|
+
/** Run against the live view. The return value is ignored. */
|
|
30
|
+
run: (view: EditorView) => void;
|
|
31
|
+
/** Reflected as the button's pressed state (`aria-pressed`, `data-active`). */
|
|
32
|
+
isActive?: (state: EditorState) => boolean;
|
|
33
|
+
/** When true, the button is rendered `disabled`. */
|
|
34
|
+
disabled?: (state: EditorState) => boolean;
|
|
35
|
+
}
|
|
36
|
+
/** One rendered slot: a built-in id, a `"|"` separator, or a custom button. */
|
|
37
|
+
export type ToolbarItem = ToolbarCommandId | "|" | ToolbarCustomItem;
|
|
38
|
+
export interface ToolbarConfig {
|
|
39
|
+
/**
|
|
40
|
+
* Ordered toolbar slots — built-in command ids, `"|"` separators, and
|
|
41
|
+
* {@link ToolbarCustomItem} objects, in any order. Omit for the full default
|
|
42
|
+
* bar.
|
|
43
|
+
*/
|
|
44
|
+
items?: ToolbarItem[];
|
|
45
|
+
/**
|
|
46
|
+
* Wrap or replace the rendered bar. `bar` is the built-in
|
|
47
|
+
* `<div role="toolbar">` element; return it wrapped, with extra chrome
|
|
48
|
+
* appended, or ignore it entirely and return your own. `view` is `null` until
|
|
49
|
+
* the surface has mounted.
|
|
50
|
+
*/
|
|
51
|
+
render?: (bar: ReactNode, ctx: {
|
|
52
|
+
view: EditorView | null;
|
|
53
|
+
}) => ReactNode;
|
|
54
|
+
/**
|
|
55
|
+
* Fix the bar to an edge of the **window** instead of wherever `<Stylo>`
|
|
56
|
+
* sits on the page. `"bottom"` (or `true`) rides above the on-screen
|
|
57
|
+
* keyboard, tracked via the `visualViewport` API; `"top"` pins to the top
|
|
58
|
+
* edge, which needs no keyboard tracking and can't be covered by it or by a
|
|
59
|
+
* platform's own input accessory bar. Off (`false`, the default) is right
|
|
60
|
+
* for a small embedded field; a host opts in deliberately for a
|
|
61
|
+
* full-screen editor. See the toolbar reference's "On touch" section.
|
|
62
|
+
*/
|
|
63
|
+
sticky?: boolean | "top" | "bottom";
|
|
64
|
+
/**
|
|
65
|
+
* When `sticky` is set, whether the bar stays on screen the whole time
|
|
66
|
+
* (`"consistent"`, the default) or only while the editing surface actually
|
|
67
|
+
* has focus (`"dynamic"`) — faded out otherwise, so it doesn't sit over the
|
|
68
|
+
* content while the caret is elsewhere. Ignored when `sticky` is off.
|
|
69
|
+
*/
|
|
70
|
+
stickyVisibility?: "consistent" | "dynamic";
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=toolbar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toolbar.d.ts","sourceRoot":"","sources":["../../src/types/toolbar.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AACtC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AACpD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAElD;;;GAGG;AACH,MAAM,MAAM,gBAAgB,GACxB,MAAM,GACN,MAAM,GACN,MAAM,GACN,QAAQ,GACR,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,MAAM,GACN,MAAM,GACN,QAAQ,GACR,QAAQ,GACR,WAAW,GACX,MAAM,GACN,WAAW,GACX,MAAM,GACN,UAAU,GACV,OAAO,GACP,YAAY,GACZ,aAAa,GACb,MAAM,GACN,IAAI,GACJ,aAAa,GACb,OAAO,GACP,MAAM,GACN,WAAW,CAAA;AAEf;;;;;;;;;GASG;AACH,MAAM,WAAW,iBAAiB;IAChC;;;OAGG;IACH,EAAE,EAAE,MAAM,CAAA;IACV,oCAAoC;IACpC,KAAK,EAAE,MAAM,CAAA;IACb,8DAA8D;IAC9D,IAAI,EAAE,SAAS,CAAA;IACf,8DAA8D;IAC9D,GAAG,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,IAAI,CAAA;IAC/B,+EAA+E;IAC/E,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,OAAO,CAAA;IAC1C,oDAAoD;IACpD,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,OAAO,CAAA;CAC3C;AAED,+EAA+E;AAC/E,MAAM,MAAM,WAAW,GAAG,gBAAgB,GAAG,GAAG,GAAG,iBAAiB,CAAA;AAEpE,MAAM,WAAW,aAAa;IAC5B;;;;OAIG;IACH,KAAK,CAAC,EAAE,WAAW,EAAE,CAAA;IACrB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE;QAAE,IAAI,EAAE,UAAU,GAAG,IAAI,CAAA;KAAE,KAAK,SAAS,CAAA;IACxE;;;;;;;;OAQG;IACH,MAAM,CAAC,EAAE,OAAO,GAAG,KAAK,GAAG,QAAQ,CAAA;IACnC;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,YAAY,GAAG,SAAS,CAAA;CAC5C"}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,408 +1,13 @@
|
|
|
1
|
-
import type { ReactNode } from "react";
|
|
2
|
-
import type { Language, LanguageDescription } from "@codemirror/language";
|
|
3
|
-
import type { EditorState } from "@codemirror/state";
|
|
4
|
-
import type { EditorView } from "@codemirror/view";
|
|
5
|
-
export type StyloMode = "in-place" | "source" | "preview" | "split";
|
|
6
1
|
/**
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
export type
|
|
18
|
-
/**
|
|
19
|
-
* A consumer-supplied toolbar button. Mixed into `ToolbarConfig["items"]`
|
|
20
|
-
* alongside the built-in ids. It runs against the same live `EditorView` the
|
|
21
|
-
* built-ins do; `isActive` / `disabled` are read back from the state on every
|
|
22
|
-
* selection, key, and pointer change, exactly like a built-in.
|
|
23
|
-
*
|
|
24
|
-
* No `keys` field: built-in shortcuts are compiled into CodeMirror's keymap at
|
|
25
|
-
* editor construction, so a custom binding would need its own keymap. Bind it
|
|
26
|
-
* yourself against `getView()` for now.
|
|
27
|
-
*/
|
|
28
|
-
export interface ToolbarCustomItem {
|
|
29
|
-
/**
|
|
30
|
-
* Stable identity, also the React key. Must not collide with a built-in id
|
|
31
|
-
* (`bold`, `h1`, …) or another custom item.
|
|
32
|
-
*/
|
|
33
|
-
id: string;
|
|
34
|
-
/** Tooltip and accessible label. */
|
|
35
|
-
title: string;
|
|
36
|
-
/** Button content — an inline SVG, a glyph, a short label. */
|
|
37
|
-
icon: ReactNode;
|
|
38
|
-
/** Run against the live view. The return value is ignored. */
|
|
39
|
-
run: (view: EditorView) => void;
|
|
40
|
-
/** Reflected as the button's pressed state (`aria-pressed`, `data-active`). */
|
|
41
|
-
isActive?: (state: EditorState) => boolean;
|
|
42
|
-
/** When true, the button is rendered `disabled`. */
|
|
43
|
-
disabled?: (state: EditorState) => boolean;
|
|
44
|
-
}
|
|
45
|
-
/** One rendered slot: a built-in id, a `"|"` separator, or a custom button. */
|
|
46
|
-
export type ToolbarItem = ToolbarCommandId | "|" | ToolbarCustomItem;
|
|
47
|
-
export interface ToolbarConfig {
|
|
48
|
-
/**
|
|
49
|
-
* Ordered toolbar slots — built-in command ids, `"|"` separators, and
|
|
50
|
-
* {@link ToolbarCustomItem} objects, in any order. Omit for the full default
|
|
51
|
-
* bar.
|
|
52
|
-
*/
|
|
53
|
-
items?: ToolbarItem[];
|
|
54
|
-
/**
|
|
55
|
-
* Wrap or replace the rendered bar. `bar` is the built-in
|
|
56
|
-
* `<div role="toolbar">` element; return it wrapped, with extra chrome
|
|
57
|
-
* appended, or ignore it entirely and return your own. `view` is `null` until
|
|
58
|
-
* the surface has mounted.
|
|
59
|
-
*/
|
|
60
|
-
render?: (bar: ReactNode, ctx: {
|
|
61
|
-
view: EditorView | null;
|
|
62
|
-
}) => ReactNode;
|
|
63
|
-
/**
|
|
64
|
-
* Fix the bar to an edge of the **window** instead of wherever `<Stylo>`
|
|
65
|
-
* sits on the page. `"bottom"` (or `true`) rides above the on-screen
|
|
66
|
-
* keyboard, tracked via the `visualViewport` API; `"top"` pins to the top
|
|
67
|
-
* edge, which needs no keyboard tracking and can't be covered by it or by a
|
|
68
|
-
* platform's own input accessory bar. Off (`false`, the default) is right
|
|
69
|
-
* for a small embedded field; a host opts in deliberately for a
|
|
70
|
-
* full-screen editor. See the toolbar reference's "On touch" section.
|
|
71
|
-
*/
|
|
72
|
-
sticky?: boolean | "top" | "bottom";
|
|
73
|
-
/**
|
|
74
|
-
* When `sticky` is set, whether the bar stays on screen the whole time
|
|
75
|
-
* (`"consistent"`, the default) or only while the editing surface actually
|
|
76
|
-
* has focus (`"dynamic"`) — faded out otherwise, so it doesn't sit over the
|
|
77
|
-
* content while the caret is elsewhere. Ignored when `sticky` is off.
|
|
78
|
-
*/
|
|
79
|
-
stickyVisibility?: "consistent" | "dynamic";
|
|
80
|
-
}
|
|
81
|
-
/**
|
|
82
|
-
* Grammars for fenced-code sub-highlighting. Stylo ships none by default — a
|
|
83
|
-
* consumer opts in with exactly the set they want (`codeLanguages={languages}`
|
|
84
|
-
* from `@codemirror/language-data`, or a hand-built list). Forwarded verbatim
|
|
85
|
-
* to `@codemirror/lang-markdown` for the CodeMirror surfaces (`source`,
|
|
86
|
-
* `split`, `in-place`); `preview` resolves a fence's language the same way
|
|
87
|
-
* (same fuzzy `LanguageDescription` match, or the function form called with
|
|
88
|
-
* the same name) and colours it with the same `--stylo-syntax-*` tokens, so a
|
|
89
|
-
* block reads identically whether it's being read or edited. See the ADR-001
|
|
90
|
-
* amendment and ADR-002 §3's 2026-09-13 amendment.
|
|
91
|
-
*/
|
|
92
|
-
export type CodeLanguages = readonly LanguageDescription[] | ((info: string) => Language | LanguageDescription | null);
|
|
93
|
-
/** One `[[wikilink]]` autocomplete candidate returned by `wikiLinkSource`. */
|
|
94
|
-
export interface WikiLinkCompletion {
|
|
95
|
-
/** Written verbatim between `[[` and `]]`. */
|
|
96
|
-
target: string;
|
|
97
|
-
/**
|
|
98
|
-
* Shown in the dropdown in place of `target`. When it differs from `target`,
|
|
99
|
-
* the accepted link is written `[[target|label]]`.
|
|
100
|
-
*/
|
|
101
|
-
label?: string;
|
|
102
|
-
}
|
|
103
|
-
/**
|
|
104
|
-
* Supplies `[[wikilink]]` autocomplete candidates. Called with the text typed
|
|
105
|
-
* after `[[` (before any `|`) while the caret sits inside an unclosed `[[…`;
|
|
106
|
-
* return the matches your index finds, already ordered — Stylo does not re-rank
|
|
107
|
-
* or filter. May be async (e.g. a vault search endpoint). Pass it to enable the
|
|
108
|
-
* feature; omit it and there is no wikilink completion. Read once, at mount.
|
|
109
|
-
* Affects the CodeMirror surfaces only (`source`, `split`, `in-place`).
|
|
110
|
-
*/
|
|
111
|
-
export type WikiLinkSource = (query: string) => readonly WikiLinkCompletion[] | Promise<readonly WikiLinkCompletion[]>;
|
|
112
|
-
/** One `#tag` autocomplete candidate returned by `tagSource`. */
|
|
113
|
-
export interface TagCompletion {
|
|
114
|
-
/** Written verbatim after `#`. No alias — tags have no `#tag|label` syntax. */
|
|
115
|
-
tag: string;
|
|
116
|
-
}
|
|
117
|
-
/**
|
|
118
|
-
* Supplies `#tag` autocomplete candidates. Called with the text typed after `#`
|
|
119
|
-
* while the caret sits inside an unclosed `#…` word; return the matches your
|
|
120
|
-
* index finds, already ordered — Stylo does not re-rank or filter. May be async
|
|
121
|
-
* (e.g. a tag-index lookup). Pass it to enable the feature; omit it and there is
|
|
122
|
-
* no tag completion. Read once, at mount. Never fires on a `# Heading` marker
|
|
123
|
-
* (the space breaks the match) or mid-word (`word#word`, a URL fragment).
|
|
124
|
-
*/
|
|
125
|
-
export type TagSource = (query: string) => readonly TagCompletion[] | Promise<readonly TagCompletion[]>;
|
|
126
|
-
/**
|
|
127
|
-
* Resolves an `![[ref]]` embed (transclusion) to something to render. Called
|
|
128
|
-
* with the raw reference — everything between `![[` and `]]`, trimmed, with any
|
|
129
|
-
* `#heading` / `#^blockid` / `|size` suffix left intact for the host to parse.
|
|
130
|
-
* Stylo has no vault, so it cannot resolve the reference itself; it detects the
|
|
131
|
-
* `![[…]]` and renders whatever node you return in its place. May be async (a
|
|
132
|
-
* vault lookup, a fetch). Return `null` to leave the reference as literal text.
|
|
133
|
-
*
|
|
134
|
-
* Pass it to enable embeds; omit it and `![[…]]` stays literal. Works on
|
|
135
|
-
* `preview`, `split`, and the in-place canvas (ADR-009). A `![[…]]` alone on its
|
|
136
|
-
* line renders as a **block**; one mid-sentence renders **inline** — return
|
|
137
|
-
* phrasing content (not a block element) for the inline case. `![[…]]` inside
|
|
138
|
-
* code stays literal, and inside an **in-place table cell** it stays literal too
|
|
139
|
-
* (a table cell there is for editing tabular text; `preview` / `split` do
|
|
140
|
-
* transclude in cells). Give it a stable reference — the render pipeline
|
|
141
|
-
* rebuilds when its identity changes, and the in-place canvas reads it once at
|
|
142
|
-
* mount.
|
|
143
|
-
*
|
|
144
|
-
* Results are memoised by `ref` per function identity (so a scroll or a
|
|
145
|
-
* re-render does not re-resolve). If your source's output for a given `ref` can
|
|
146
|
-
* change over time, vary the `ref` or pass a new `embedSource` to invalidate.
|
|
147
|
-
* Rejections are not cached.
|
|
148
|
-
*/
|
|
149
|
-
export type EmbedSource = (ref: string) => ReactNode | Promise<ReactNode>;
|
|
150
|
-
/** Which host resolver rejected, and the argument it was called with. */
|
|
151
|
-
export interface ResolveErrorInfo {
|
|
152
|
-
/** The prop whose function threw or returned a rejected promise. */
|
|
153
|
-
source: "embedSource" | "wikiLinkSource" | "tagSource";
|
|
154
|
-
/** What it was asked to resolve — an `![[ref]]` reference, or the `[[` query. */
|
|
155
|
-
input: string;
|
|
156
|
-
}
|
|
157
|
-
/**
|
|
158
|
-
* Reported by `onTaskToggle` when a `preview` task-list checkbox is clicked.
|
|
159
|
-
* `start`/`end` are raw offsets into `value` bracketing the `[ ]` / `[x]`
|
|
160
|
-
* marker itself (`end - start === 3`); splice in the new marker text to apply
|
|
161
|
-
* the toggle: `value.slice(0, start) + (checked ? "[x]" : "[ ]") +
|
|
162
|
-
* value.slice(end)`. `checked` is the box's new state, not its state before
|
|
163
|
-
* the click.
|
|
164
|
-
*/
|
|
165
|
-
export interface TaskToggleInfo {
|
|
166
|
-
/** Offset of the marker's opening `[` in `value`. */
|
|
167
|
-
start: number;
|
|
168
|
-
/** Offset just past the marker's closing `]` in `value`. */
|
|
169
|
-
end: number;
|
|
170
|
-
/** The checkbox's new state. */
|
|
171
|
-
checked: boolean;
|
|
172
|
-
}
|
|
173
|
-
/**
|
|
174
|
-
* Per-construct on/off switches for the in-place canvas. Each key defaults to
|
|
175
|
-
* `true`; setting one `false` leaves that construct as plain source — no
|
|
176
|
-
* decoration, no cursor-reveal behaviour. See ADR-005.
|
|
177
|
-
*/
|
|
178
|
-
export interface InPlaceDecorationToggles {
|
|
179
|
-
headings?: boolean;
|
|
180
|
-
emphasis?: boolean;
|
|
181
|
-
links?: boolean;
|
|
182
|
-
wikilinks?: boolean;
|
|
183
|
-
math?: boolean;
|
|
184
|
-
lists?: boolean;
|
|
185
|
-
tasks?: boolean;
|
|
186
|
-
blockquote?: boolean;
|
|
187
|
-
horizontalRule?: boolean;
|
|
188
|
-
code?: boolean;
|
|
189
|
-
frontmatter?: boolean;
|
|
190
|
-
tables?: boolean;
|
|
191
|
-
/** `![[ref]]` transclusion blocks. Needs `embedSource` set; see ADR-009. */
|
|
192
|
-
embeds?: boolean;
|
|
193
|
-
}
|
|
194
|
-
/**
|
|
195
|
-
* How the in-place canvas handles editing a table.
|
|
196
|
-
* `"source"` (default) reveals the aligned pipe source under the caret;
|
|
197
|
-
* `"cells"` keeps the rendered `<table>` and edits its cells in place.
|
|
198
|
-
*/
|
|
199
|
-
export type TableEditing = "source" | "cells";
|
|
200
|
-
/**
|
|
201
|
-
* Whether the in-place canvas shows a construct's Markdown markers when the
|
|
202
|
-
* caret is on its line. `"caret"` (default) reveals them for editing and
|
|
203
|
-
* re-hides them on the way out — Obsidian's Live Preview. `"never"` keeps every
|
|
204
|
-
* inline marker hidden at all times; formatting is changed through the toolbar,
|
|
205
|
-
* the right-click menu, shortcuts, and autoformat-on-type instead. See ADR-007;
|
|
206
|
-
* `"never"` is being rolled out in stages.
|
|
207
|
-
*/
|
|
208
|
-
export type RevealMode = "caret" | "never";
|
|
209
|
-
/**
|
|
210
|
-
* What appears when text is selected in the in-place canvas. `"menu"` (default)
|
|
211
|
-
* puts the inline-formatting group in the right-click menu and shows no floating
|
|
212
|
-
* bar; `"bar"` shows a floating bar above the selection and drops that group
|
|
213
|
-
* from the menu so nothing is doubled; `"none"` shows neither and leaves the
|
|
214
|
-
* main toolbar as the only formatting surface. The toolbar is independent of
|
|
215
|
-
* this setting — it is always available (unless hidden via `toolbar`) and always
|
|
216
|
-
* acts on the selection.
|
|
217
|
-
*/
|
|
218
|
-
export type SelectionUI = "menu" | "bar" | "none";
|
|
219
|
-
/**
|
|
220
|
-
* The right-click menu's top-level groups. `link` is the internal / external
|
|
221
|
-
* link field rows; `format` the inline-mark submenu; `paragraph` the block-type
|
|
222
|
-
* submenu; `insert` the new-block submenu; `clipboard` cut / copy / paste.
|
|
223
|
-
*/
|
|
224
|
-
export type MenuGroupId = "link" | "format" | "paragraph" | "insert" | "clipboard";
|
|
225
|
-
export interface ContextMenuConfig {
|
|
226
|
-
/**
|
|
227
|
-
* Which top-level groups the menu shows, in order. Omit for all five in their
|
|
228
|
-
* default order. `link` and `format` still yield to `selectionUI` when it is
|
|
229
|
-
* not `"menu"` (they move to the floating bar / toolbar).
|
|
230
|
-
*/
|
|
231
|
-
groups?: MenuGroupId[];
|
|
232
|
-
}
|
|
233
|
-
export interface InPlaceConfig {
|
|
234
|
-
/** Which decoration types the in-place canvas renders. Read once, at mount. */
|
|
235
|
-
decorations?: InPlaceDecorationToggles;
|
|
236
|
-
/** Table editing mode (see `TableEditing`). Read once, at mount. */
|
|
237
|
-
table?: TableEditing;
|
|
238
|
-
/**
|
|
239
|
-
* Marker reveal behaviour (see `RevealMode`). Optional, defaults to
|
|
240
|
-
* `"caret"`. Read once, at mount.
|
|
241
|
-
*/
|
|
242
|
-
reveal?: RevealMode;
|
|
243
|
-
/**
|
|
244
|
-
* Right-click a block for a context menu (inline actions on a selection,
|
|
245
|
-
* block + insert actions otherwise). `false` keeps the browser's own menu; an
|
|
246
|
-
* object picks and orders the menu's groups. Defaults to `true`. Read once,
|
|
247
|
-
* at mount.
|
|
248
|
-
*/
|
|
249
|
-
contextMenu?: boolean | ContextMenuConfig;
|
|
250
|
-
/**
|
|
251
|
-
* What a non-empty selection offers (see `SelectionUI`). Defaults to
|
|
252
|
-
* `"menu"`. Read once, at mount.
|
|
253
|
-
*/
|
|
254
|
-
selectionUI?: SelectionUI;
|
|
255
|
-
/**
|
|
256
|
-
* Which buttons the floating selection bar shows (`selectionUI: "bar"`), in
|
|
257
|
-
* order. Any of `bold` / `italic` / `strike` / `code` / `link` / `wikilink` /
|
|
258
|
-
* `math`. Omit for all seven. Read once, at mount.
|
|
259
|
-
*/
|
|
260
|
-
selectionBarItems?: ToolbarCommandId[];
|
|
261
|
-
}
|
|
262
|
-
export interface StyloProps {
|
|
263
|
-
/** The canonical Markdown document. Stylo never holds a parsed model of it. */
|
|
264
|
-
value: string;
|
|
265
|
-
/** Called with the complete Markdown string on every edit. */
|
|
266
|
-
onChange: (next: string) => void;
|
|
267
|
-
/**
|
|
268
|
-
* Interaction layout. Defaults to `"in-place"` — the live decoration canvas.
|
|
269
|
-
* `"source"` is the plain surface and avoids loading the render chunk.
|
|
270
|
-
*/
|
|
271
|
-
mode?: StyloMode;
|
|
272
|
-
/**
|
|
273
|
-
* Called with the full Markdown string when `Mod-s` is pressed on any editing
|
|
274
|
-
* surface; the browser's own save dialog is then suppressed. Omit it and
|
|
275
|
-
* `Mod-s` keeps its default browser behaviour. Stylo holds no dirty state —
|
|
276
|
-
* `value` is yours, so compare it against your last-saved copy.
|
|
277
|
-
*/
|
|
278
|
-
onSave?: (value: string) => void;
|
|
279
|
-
/**
|
|
280
|
-
* Called on mount and whenever the leading `---` YAML block changes, with its
|
|
281
|
-
* inner text (no fences), or `null` when there is no block. Stylo does not
|
|
282
|
-
* parse it — pass `raw` to your own YAML parser for a structured panel. The
|
|
283
|
-
* same split is available synchronously as the exported `splitFrontmatter`.
|
|
284
|
-
*/
|
|
285
|
-
onFrontmatter?: (raw: string | null) => void;
|
|
286
|
-
/** Invoked when a `[[wikilink]]` is activated in the preview or in-place canvas. */
|
|
287
|
-
onWikiLinkClick?: (target: string) => void;
|
|
288
|
-
/**
|
|
289
|
-
* Invoked by the in-place link editor's "Open link" action with the link's
|
|
290
|
-
* `href`. Stylo does not navigate on its own.
|
|
291
|
-
*/
|
|
292
|
-
onLinkClick?: (href: string) => void;
|
|
293
|
-
/** Configures the in-place canvas (ADR-005). Applied when it mounts. */
|
|
294
|
-
inPlace?: InPlaceConfig;
|
|
295
|
-
/**
|
|
296
|
-
* How `preview` (and `split`'s preview pane) shows the leading `---` YAML
|
|
297
|
-
* block. `"hidden"` (default) drops it; `"code"` renders it as a styled
|
|
298
|
-
* `<pre class="stylo-frontmatter">`.
|
|
299
|
-
*/
|
|
300
|
-
frontmatter?: FrontmatterDisplay;
|
|
301
|
-
/**
|
|
302
|
-
* Turn a single line ending into a real `<br>` in `preview` (and `split`'s
|
|
303
|
-
* preview pane), instead of CommonMark's default — a blank line required to
|
|
304
|
-
* start a new paragraph, so consecutive lines join into one run. Obsidian's
|
|
305
|
-
* Live Preview reads this way. Off by default: a real, visible change to
|
|
306
|
-
* every existing render, so a host opts in deliberately rather than
|
|
307
|
-
* inheriting it. No effect on `in-place` / `source` — CodeMirror already
|
|
308
|
-
* decorates each source line independently there.
|
|
309
|
-
*/
|
|
310
|
-
softBreaks?: boolean;
|
|
311
|
-
/**
|
|
312
|
-
* Makes `preview` (and `split`'s preview pane) task-list checkboxes
|
|
313
|
-
* clickable instead of `disabled`. Fired with a {@link TaskToggleInfo} — raw
|
|
314
|
-
* offsets into `value` bracketing the clicked `[ ]` / `[x]` marker, and its
|
|
315
|
-
* new state. Stylo never mutates `value` itself; splice the marker and pass
|
|
316
|
-
* the result to `onChange`, same division of labour as `onWikiLinkClick`.
|
|
317
|
-
* Off by default: every checkbox stays `disabled`, exactly like today,
|
|
318
|
-
* until a host opts in.
|
|
319
|
-
*/
|
|
320
|
-
onTaskToggle?: (info: TaskToggleInfo) => void;
|
|
321
|
-
/**
|
|
322
|
-
* Grammars for fenced-code sub-highlighting on the CodeMirror surfaces
|
|
323
|
-
* (`source`, `split`, `in-place`). None by default. Read once, at mount.
|
|
324
|
-
*/
|
|
325
|
-
codeLanguages?: CodeLanguages;
|
|
326
|
-
/**
|
|
327
|
-
* Enables `[[wikilink]]` autocomplete on the CodeMirror surfaces. Called with
|
|
328
|
-
* the target typed so far; return your index's matches, ordered. Off when
|
|
329
|
-
* omitted. Read once, at mount. See `WikiLinkSource`.
|
|
330
|
-
*/
|
|
331
|
-
wikiLinkSource?: WikiLinkSource;
|
|
332
|
-
/**
|
|
333
|
-
* Enables `#tag` autocomplete on the CodeMirror surfaces. Called with the tag
|
|
334
|
-
* typed so far; return your index's matches, ordered. Off when omitted. Read
|
|
335
|
-
* once, at mount. See `TagSource`.
|
|
336
|
-
*/
|
|
337
|
-
tagSource?: TagSource;
|
|
338
|
-
/**
|
|
339
|
-
* Resolves `![[ref]]` embeds (transclusion) for `preview` and `split`. Called
|
|
340
|
-
* with the raw reference; return a node to render in its place, or `null` to
|
|
341
|
-
* leave it as literal text. May be async. Off when omitted. See
|
|
342
|
-
* {@link EmbedSource}.
|
|
343
|
-
*/
|
|
344
|
-
embedSource?: EmbedSource;
|
|
345
|
-
/**
|
|
346
|
-
* Called when `embedSource`, `wikiLinkSource`, or `tagSource` throws or
|
|
347
|
-
* returns a rejected promise. Purely for observation — logging, a toast — the
|
|
348
|
-
* resolver still falls back (literal `![[ref]]` text, or no completions)
|
|
349
|
-
* either way. A `null` return is a valid result, not an error, and does not
|
|
350
|
-
* fire this. Reactive; see {@link ResolveErrorInfo}.
|
|
351
|
-
*/
|
|
352
|
-
onResolveError?: (error: unknown, info: ResolveErrorInfo) => void;
|
|
353
|
-
/**
|
|
354
|
-
* Formatting toolbar above the editing surface (`source`, `in-place`,
|
|
355
|
-
* `split`; never `preview`). Omit or `true` for the default bar, `false` to
|
|
356
|
-
* hide it, or an object to choose and order the buttons. See ADR-002 §2.
|
|
357
|
-
*/
|
|
358
|
-
toolbar?: boolean | ToolbarConfig;
|
|
359
|
-
/**
|
|
360
|
-
* Replace individual toolbar glyphs, keyed by command id. Any id left out
|
|
361
|
-
* keeps its built-in inline-SVG icon — Stylo ships no icon dependency.
|
|
362
|
-
*/
|
|
363
|
-
icons?: Partial<Record<ToolbarCommandId, ReactNode>>;
|
|
364
|
-
/** Render the source surface read-only. */
|
|
365
|
-
readOnly?: boolean;
|
|
366
|
-
/** Placeholder text shown when the document is empty (source surface). */
|
|
367
|
-
placeholder?: string;
|
|
368
|
-
/** Extra class on the root element, alongside the internal classes. */
|
|
369
|
-
className?: string;
|
|
370
|
-
/**
|
|
371
|
-
* Host content docked inside the editing surface (`source`, `in-place`,
|
|
372
|
-
* `split`'s source pane; never `preview`) — after the find/replace panel,
|
|
373
|
-
* before the document body. Unlike `toolbar.render`, which wraps content
|
|
374
|
-
* *before* the whole canvas, this reaches the seam between CodeMirror's own
|
|
375
|
-
* top panels and its scroller, so host chrome (e.g. a frontmatter card) can
|
|
376
|
-
* sit under find/replace instead of always above it. `view` is `null` until
|
|
377
|
-
* the surface has mounted. Read once, at mount.
|
|
378
|
-
*/
|
|
379
|
-
canvasHeader?: (ctx: {
|
|
380
|
-
view: EditorView | null;
|
|
381
|
-
}) => ReactNode;
|
|
382
|
-
}
|
|
383
|
-
/**
|
|
384
|
-
* Imperative handle exposed on a `ref` to `<Stylo>`. Every method is a no-op —
|
|
385
|
-
* returning `null` / `false` where it has a return value — in `preview` mode or
|
|
386
|
-
* before the editing surface has mounted, since there is no editor then.
|
|
387
|
-
*/
|
|
388
|
-
export interface StyloHandle {
|
|
389
|
-
/** Move keyboard focus into the editing surface. */
|
|
390
|
-
focus(): void;
|
|
391
|
-
/**
|
|
392
|
-
* Put the caret at the start of the first ATX heading (`#` … `######`) whose
|
|
393
|
-
* text matches `text` (trimmed, case-insensitive) and scroll it to the top of
|
|
394
|
-
* the viewport. Returns `true` when a heading matched.
|
|
395
|
-
*/
|
|
396
|
-
scrollToHeading(text: string): boolean;
|
|
397
|
-
/**
|
|
398
|
-
* Replace the current selection — or insert at the caret when the selection is
|
|
399
|
-
* empty — with `md`. No effect on a `readOnly` surface.
|
|
400
|
-
*/
|
|
401
|
-
insertAtCursor(md: string): void;
|
|
402
|
-
/**
|
|
403
|
-
* The underlying CodeMirror `EditorView`, or `null` in `preview` mode or
|
|
404
|
-
* before mount. An escape hatch: not covered by semver.
|
|
405
|
-
*/
|
|
406
|
-
getView(): EditorView | null;
|
|
407
|
-
}
|
|
2
|
+
* Re-export barrel over `types/`, split by domain: `core` (`StyloProps`,
|
|
3
|
+
* `StyloHandle`, and the top-level display/mode types), `toolbar` (toolbar
|
|
4
|
+
* config), `sources` (wikilink/tag/embed resolver types), and `inplace`
|
|
5
|
+
* (in-place canvas config). Kept so nothing importing from `./types` today
|
|
6
|
+
* has to change.
|
|
7
|
+
*/
|
|
8
|
+
export type { StyloMode, FrontmatterDisplay, CodeLanguages, TaskToggleInfo, StyloProps, StyloHandle, } from "./types/core";
|
|
9
|
+
export type { ToolbarCommandId, ToolbarCustomItem, ToolbarItem, ToolbarConfig, } from "./types/toolbar";
|
|
10
|
+
export type { WikiLinkCompletion, WikiLinkSource, TagCompletion, TagSource } from "./types/sources";
|
|
11
|
+
export type { EmbedSource, ResolveErrorInfo } from "./types/sources";
|
|
12
|
+
export type { InPlaceDecorationToggles, TableEditing, RevealMode, SelectionUI, MenuGroupId, ContextMenuConfig, InPlaceConfig, } from "./types/inplace";
|
|
408
13
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,YAAY,EACV,SAAS,EACT,kBAAkB,EAClB,aAAa,EACb,cAAc,EACd,UAAU,EACV,WAAW,GACZ,MAAM,cAAc,CAAA;AACrB,YAAY,EACV,gBAAgB,EAChB,iBAAiB,EACjB,WAAW,EACX,aAAa,GACd,MAAM,iBAAiB,CAAA;AACxB,YAAY,EAAE,kBAAkB,EAAE,cAAc,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AACnG,YAAY,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AACpE,YAAY,EACV,wBAAwB,EACxB,YAAY,EACZ,UAAU,EACV,WAAW,EACX,WAAW,EACX,iBAAiB,EACjB,aAAa,GACd,MAAM,iBAAiB,CAAA"}
|