svedit 0.12.0 → 0.14.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.
Files changed (88) hide show
  1. package/README.md +35 -22
  2. package/dist/Command.svelte.d.ts +38 -30
  3. package/dist/Command.svelte.d.ts.map +1 -1
  4. package/dist/Command.svelte.js +271 -326
  5. package/dist/CustomProperty.svelte +3 -5
  6. package/dist/CustomProperty.svelte.d.ts +3 -6
  7. package/dist/CustomProperty.svelte.d.ts.map +1 -1
  8. package/dist/KeyMapper.svelte.d.ts +19 -6
  9. package/dist/KeyMapper.svelte.d.ts.map +1 -1
  10. package/dist/KeyMapper.svelte.js +95 -112
  11. package/dist/Node.svelte +16 -13
  12. package/dist/Node.svelte.d.ts +3 -5
  13. package/dist/Node.svelte.d.ts.map +1 -1
  14. package/dist/NodeArrayProperty.svelte +39 -22
  15. package/dist/NodeArrayProperty.svelte.d.ts +3 -5
  16. package/dist/NodeArrayProperty.svelte.d.ts.map +1 -1
  17. package/dist/NodeCaret.svelte +2 -2
  18. package/dist/NodeCaret.svelte.d.ts +6 -14
  19. package/dist/NodeCaret.svelte.d.ts.map +1 -1
  20. package/dist/NodeGap.svelte +12 -6
  21. package/dist/NodeGap.svelte.d.ts +7 -14
  22. package/dist/NodeGap.svelte.d.ts.map +1 -1
  23. package/dist/NodeGapMarkers.svelte +36 -14
  24. package/dist/NodeGapMarkers.svelte.d.ts +6 -11
  25. package/dist/NodeGapMarkers.svelte.d.ts.map +1 -1
  26. package/dist/NodeSelectionMarkers.svelte +21 -7
  27. package/dist/NodeSelectionMarkers.svelte.d.ts +2 -5
  28. package/dist/NodeSelectionMarkers.svelte.d.ts.map +1 -1
  29. package/dist/Session.svelte.d.ts +81 -129
  30. package/dist/Session.svelte.d.ts.map +1 -1
  31. package/dist/Session.svelte.js +542 -648
  32. package/dist/Svedit.svelte +146 -140
  33. package/dist/Svedit.svelte.d.ts +30 -10
  34. package/dist/Svedit.svelte.d.ts.map +1 -1
  35. package/dist/TextProperty.svelte +37 -23
  36. package/dist/TextProperty.svelte.d.ts +3 -5
  37. package/dist/TextProperty.svelte.d.ts.map +1 -1
  38. package/dist/Transaction.svelte.d.ts +64 -127
  39. package/dist/Transaction.svelte.d.ts.map +1 -1
  40. package/dist/Transaction.svelte.js +839 -1001
  41. package/dist/UnknownNode.svelte +4 -3
  42. package/dist/UnknownNode.svelte.d.ts +5 -9
  43. package/dist/UnknownNode.svelte.d.ts.map +1 -1
  44. package/dist/doc_utils.d.ts +67 -155
  45. package/dist/doc_utils.d.ts.map +1 -1
  46. package/dist/doc_utils.js +619 -863
  47. package/dist/index.d.ts +20 -17
  48. package/dist/index.d.ts.map +1 -1
  49. package/dist/index.js +1 -17
  50. package/dist/node_visibility.svelte.d.ts +110 -9
  51. package/dist/node_visibility.svelte.d.ts.map +1 -1
  52. package/dist/node_visibility.svelte.js +473 -544
  53. package/dist/paste_utils.d.ts +11 -44
  54. package/dist/paste_utils.d.ts.map +1 -1
  55. package/dist/paste_utils.js +111 -152
  56. package/dist/styles/svedit-colors.css +8 -5
  57. package/dist/transforms.svelte.d.ts +9 -7
  58. package/dist/transforms.svelte.d.ts.map +1 -1
  59. package/dist/transforms.svelte.js +125 -150
  60. package/dist/types.d.ts +294 -309
  61. package/dist/types.d.ts.map +1 -0
  62. package/dist/types.js +1 -0
  63. package/dist/utils.d.ts +40 -119
  64. package/dist/utils.d.ts.map +1 -1
  65. package/dist/utils.js +346 -473
  66. package/package.json +70 -70
  67. package/src/lib/{Command.svelte.js → Command.svelte.ts} +29 -17
  68. package/src/lib/CustomProperty.svelte +3 -5
  69. package/src/lib/{KeyMapper.svelte.js → KeyMapper.svelte.ts} +28 -11
  70. package/src/lib/Node.svelte +16 -13
  71. package/src/lib/NodeArrayProperty.svelte +39 -22
  72. package/src/lib/NodeCaret.svelte +2 -2
  73. package/src/lib/NodeGap.svelte +12 -6
  74. package/src/lib/NodeGapMarkers.svelte +36 -14
  75. package/src/lib/NodeSelectionMarkers.svelte +21 -7
  76. package/src/lib/{Session.svelte.js → Session.svelte.ts} +130 -127
  77. package/src/lib/Svedit.svelte +146 -140
  78. package/src/lib/TextProperty.svelte +37 -23
  79. package/src/lib/{Transaction.svelte.js → Transaction.svelte.ts} +139 -143
  80. package/src/lib/UnknownNode.svelte +4 -3
  81. package/src/lib/{doc_utils.js → doc_utils.ts} +247 -206
  82. package/src/lib/{index.js → index.ts} +48 -0
  83. package/src/lib/{node_visibility.svelte.js → node_visibility.svelte.ts} +68 -92
  84. package/src/lib/{paste_utils.js → paste_utils.ts} +47 -58
  85. package/src/lib/styles/svedit-colors.css +8 -5
  86. package/src/lib/{transforms.svelte.js → transforms.svelte.ts} +39 -21
  87. package/src/lib/{types.d.ts → types.ts} +161 -66
  88. package/src/lib/{utils.js → utils.ts} +110 -129
package/dist/index.d.ts CHANGED
@@ -1,18 +1,21 @@
1
- export { default as Svedit } from "./Svedit.svelte";
2
- export { default as TextProperty } from "./TextProperty.svelte";
3
- export { default as CustomProperty } from "./CustomProperty.svelte";
4
- export { default as Node } from "./Node.svelte";
5
- export { default as NodeArrayProperty } from "./NodeArrayProperty.svelte";
6
- export { default as NodeGap } from "./NodeGap.svelte";
7
- export { default as NodeGapMarkers } from "./NodeGapMarkers.svelte";
8
- export { default as NodeCaret } from "./NodeCaret.svelte";
9
- export { default as NodeSelectionMarkers } from "./NodeSelectionMarkers.svelte";
10
- export { default as Session } from "./Session.svelte.js";
11
- export { default as Transaction } from "./Transaction.svelte.js";
12
- export { default as Command } from "./Command.svelte.js";
13
- export * from "./Command.svelte.js";
14
- export * from "./transforms.svelte.js";
15
- export * from "./utils.js";
16
- export { define_document_schema, is_primitive_type, get_default_node_type, get_property_default, fill_node_defaults, fill_document_defaults, validate_document_schema, validate_document, validate_node, get_referencing_node_ids } from "./doc_utils.js";
17
- export { KeyMapper, define_keymap } from "./KeyMapper.svelte.js";
1
+ export { default as Svedit } from './Svedit.svelte';
2
+ export { default as TextProperty } from './TextProperty.svelte';
3
+ export { default as CustomProperty } from './CustomProperty.svelte';
4
+ export { default as Node } from './Node.svelte';
5
+ export { default as NodeArrayProperty } from './NodeArrayProperty.svelte';
6
+ export { default as NodeGap } from './NodeGap.svelte';
7
+ export { default as NodeGapMarkers } from './NodeGapMarkers.svelte';
8
+ export { default as NodeCaret } from './NodeCaret.svelte';
9
+ export { default as NodeSelectionMarkers } from './NodeSelectionMarkers.svelte';
10
+ export { default as Session } from './Session.svelte.js';
11
+ export { default as Transaction } from './Transaction.svelte.js';
12
+ export type { DocumentSchema, NodeSchema, NodeKind, PropertyDefinition, PropertyType, PropertyValue, NodeOfType, AnyNode, NodeMap, DynamicRecord, SessionConfig, CommandRegistry, DocumentOperation, Inspection, Document, DocumentNode, DocumentPath, NodeId, Text, NodeArray, Attachment, Mark, Annotation, Selection, TextSelection, NodeSelection, PropertySelection, SelectionRange, SveditProps, SveditContext, TextPropertyProps, CustomPropertyProps, NodeArrayPropertyProps, NodeGapToolsProps, NodeProps, NodeArrayAttachmentContext } from './types.js';
13
+ export type { SelectedAttachment } from './doc_utils.js';
14
+ export type { Keymap } from './KeyMapper.svelte.js';
15
+ export { define_document_schema, is_primitive_type, get_default_node_type, get_property_default, fill_node_defaults, fill_document_defaults, validate_document_schema, validate_document, validate_node, get_referencing_node_ids } from './doc_utils.js';
16
+ export { default as Command } from './Command.svelte.js';
17
+ export * from './Command.svelte.js';
18
+ export { KeyMapper, define_keymap } from './KeyMapper.svelte.js';
19
+ export * from './transforms.svelte.js';
20
+ export * from './utils.js';
18
21
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/lib/index.js"],"names":[],"mappings":""}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/lib/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACpE,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC1E,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACpE,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,OAAO,IAAI,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAGhF,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAGjE,YAAY,EAEX,cAAc,EACd,UAAU,EACV,QAAQ,EACR,kBAAkB,EAClB,YAAY,EAEZ,aAAa,EACb,UAAU,EACV,OAAO,EACP,OAAO,EACP,aAAa,EACb,aAAa,EACb,eAAe,EACf,iBAAiB,EACjB,UAAU,EAEV,QAAQ,EACR,YAAY,EACZ,YAAY,EACZ,MAAM,EAEN,IAAI,EACJ,SAAS,EACT,UAAU,EACV,IAAI,EACJ,UAAU,EAEV,SAAS,EACT,aAAa,EACb,aAAa,EACb,iBAAiB,EACjB,cAAc,EAEd,WAAW,EACX,aAAa,EACb,iBAAiB,EACjB,mBAAmB,EACnB,sBAAsB,EACtB,iBAAiB,EACjB,SAAS,EACT,0BAA0B,EAC1B,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACzD,YAAY,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAGpD,OAAO,EACN,sBAAsB,EACtB,iBAAiB,EACjB,qBAAqB,EACrB,oBAAoB,EACpB,kBAAkB,EAClB,sBAAsB,EACtB,wBAAwB,EACxB,iBAAiB,EACjB,aAAa,EACb,wBAAwB,EACxB,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,qBAAqB,CAAC;AACzD,cAAc,qBAAqB,CAAC;AAGpC,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAGjE,cAAc,wBAAwB,CAAC;AACvC,cAAc,YAAY,CAAC"}
package/dist/index.js CHANGED
@@ -8,32 +8,16 @@ export { default as NodeGap } from './NodeGap.svelte';
8
8
  export { default as NodeGapMarkers } from './NodeGapMarkers.svelte';
9
9
  export { default as NodeCaret } from './NodeCaret.svelte';
10
10
  export { default as NodeSelectionMarkers } from './NodeSelectionMarkers.svelte';
11
-
12
11
  // Core classes and utilities
13
12
  export { default as Session } from './Session.svelte.js';
14
13
  export { default as Transaction } from './Transaction.svelte.js';
15
-
16
14
  // Document utilities
17
- export {
18
- define_document_schema,
19
- is_primitive_type,
20
- get_default_node_type,
21
- get_property_default,
22
- fill_node_defaults,
23
- fill_document_defaults,
24
- validate_document_schema,
25
- validate_document,
26
- validate_node,
27
- get_referencing_node_ids
28
- } from './doc_utils.js';
29
-
15
+ export { define_document_schema, is_primitive_type, get_default_node_type, get_property_default, fill_node_defaults, fill_document_defaults, validate_document_schema, validate_document, validate_node, get_referencing_node_ids } from './doc_utils.js';
30
16
  // Command system
31
17
  export { default as Command } from './Command.svelte.js';
32
18
  export * from './Command.svelte.js';
33
-
34
19
  // Keyboard handling
35
20
  export { KeyMapper, define_keymap } from './KeyMapper.svelte.js';
36
-
37
21
  // Transforms and utilities
38
22
  export * from './transforms.svelte.js';
39
23
  export * from './utils.js';
@@ -1,3 +1,90 @@
1
+ /**
2
+ * Dual-observer viewport visibility tracking for node arrays.
3
+ *
4
+ * ## Why this exists
5
+ *
6
+ * CSS anchor positioning is O(N) — the browser must resolve anchor()
7
+ * functions for every positioned element on every layout pass. Gap
8
+ * markers (NodeGapMarkers) also grow at O(N). At ~200+ nodes this
9
+ * causes frame drops during scroll/resize; at 500+ it's unusable.
10
+ *
11
+ * ## Design principle: structurally stable DOM
12
+ *
13
+ * NodeGap elements are always present in the DOM when editable. The
14
+ * `.positioned` class (which activates anchor() resolution) is gated
15
+ * by viewport visibility. Off-screen NodeGaps remain as zero-size
16
+ * absolute elements with no anchor cost.
17
+ *
18
+ * ## Element registration via attachments
19
+ *
20
+ * Node elements (Node.svelte and the empty-array placeholder) register
21
+ * themselves with `{@attach registry.track_node(path)}`; node-array
22
+ * containers use `{@attach registry.track_array(path)}`. Attachments
23
+ * re-run whenever Svelte recreates the element or its path changes, so
24
+ * observation and per-path state follow the DOM's actual lifecycle —
25
+ * including DOM recreation without a document change (e.g. dev-mode
26
+ * HMR component swaps), which a document-driven reconciliation pass
27
+ * would miss.
28
+ *
29
+ * During keyed updates several elements can change paths at once
30
+ * (e.g. 0→1 while a new element claims 0), and Svelte doesn't
31
+ * guarantee attachment ordering across elements. Per-path ownership
32
+ * maps make unregistration collision-safe: a teardown only clears a
33
+ * path's state if that element still owns the path.
34
+ *
35
+ * ## Two observers
36
+ *
37
+ * **Overscan IO** (`rootMargin: 500px`, threshold `0`) — fills the
38
+ * per-array `array_indices` sets. NodeGap derives its `.positioned`
39
+ * class reactively from them. Registration seeds
40
+ * the state synchronously from one getBoundingClientRect (so there's
41
+ * no unpositioned flash on mount); the IO owns subsequent viewport
42
+ * transitions, including layout-shift-induced ones.
43
+ *
44
+ * **Viewport IO** (`rootMargin: 0`, threshold `[0, 1]`) — toggles
45
+ * view classes (`.in-view`, `.fully-in-view`, …) on node elements.
46
+ * OPT-IN via `session.config.view_classes`. A separate observer is
47
+ * required because the overscan IO fires its thresholds while nodes
48
+ * are still 500px outside the real viewport.
49
+ *
50
+ * **Document scroll listener** (capture, passive) — fills `edge_map`,
51
+ * a per-array `{first, last}` flag indicating whether the leading/
52
+ * trailing node has reached the matching container edge within
53
+ * EDGE_TOLERANCE_PX. IntersectionObserver doesn't re-fire on scrolls
54
+ * inside non-root scroll containers (the intersection ratio doesn't
55
+ * cross any threshold), so this is the only reliable way to track
56
+ * horizontal-overflow scroll position. The handler is hot but cheap:
57
+ * a single `.closest()` early-out (page scroll → null → returns
58
+ * immediately) and a RAF flush that reads only scrollLeft / scrollWidth /
59
+ * clientWidth on the dirty array.
60
+ *
61
+ * **Document changes** — content changes alter an array's scroll
62
+ * extent without recreating the array element, so after Svelte
63
+ * updates the DOM all registered arrays re-sync their edge state in
64
+ * one batch.
65
+ *
66
+ * **Array ResizeObserver** — box-size changes (window resize, sidebar
67
+ * toggle, responsive breakpoint) can flip an array between fitting
68
+ * and overflowing without a scroll event or document change; a shared
69
+ * ResizeObserver on registered arrays re-syncs their edge state.
70
+ *
71
+ * ## Reactivity
72
+ *
73
+ * State lives in per-array SvelteSets (array_indices, the single
74
+ * source of truth for node nearness) and a SvelteMap (edge_map).
75
+ * Consumers (NodeGap and NodeGapMarkers, both via
76
+ * $derived) read via .has()/.get() — Svelte's runtime tracks at
77
+ * per-key granularity, so only consumers whose specific dependencies
78
+ * changed re-evaluate. Because the `.positioned` class is applied
79
+ * declaratively by NodeGap, it survives DOM recreation that happens
80
+ * without a document change (e.g. dev-mode HMR component swaps).
81
+ *
82
+ * View classes are toggled imperatively (no Svelte consumers — they're
83
+ * pure CSS hooks for app code).
84
+ *
85
+ * @module
86
+ */
87
+ import { SvelteMap, SvelteSet } from 'svelte/reactivity';
1
88
  /**
2
89
  * Install the visibility registry on the svedit context.
3
90
  *
@@ -6,9 +93,28 @@
6
93
  * The IntersectionObservers own viewport changes; document changes
7
94
  * only trigger an edge-state re-sync over the registered arrays.
8
95
  *
9
- * @param {object} svedit - Svedit context (session, editable)
96
+ * @param svedit - Svedit context (session, editable)
10
97
  */
11
- export function create_node_visibility(svedit: object): void;
98
+ export declare function create_node_visibility(svedit: {
99
+ session: {
100
+ config?: {
101
+ view_classes?: boolean;
102
+ visibility_culling?: boolean;
103
+ };
104
+ doc: unknown;
105
+ };
106
+ editable: boolean;
107
+ visibility_registry?: VisibilityRegistryApi;
108
+ }): void;
109
+ export type VisibilityRegistryApi = {
110
+ edge_map: SvelteMap<string, {
111
+ first: boolean;
112
+ last: boolean;
113
+ }>;
114
+ get_array_indices(array_path_str: string): SvelteSet<number>;
115
+ track_node(path: string): (el: HTMLElement) => () => void;
116
+ track_array(path: string): (el: Element) => () => void;
117
+ };
12
118
  /**
13
119
  * Pure visibility check for a gap's `.positioned` class. NodeGap calls
14
120
  * this from a $derived, so the `near.has()` reads are tracked at
@@ -21,15 +127,10 @@ export function create_node_visibility(svedit: object): void;
21
127
  * $derived (see the note there): membership reads on a set created
22
128
  * within the same derived are not tracked by Svelte.
23
129
  *
24
- * @param {SvelteSet<number>} near - near child indices of the array
25
- * @param {{ first: boolean, last: boolean } | undefined} edge_state
26
- * @param {number} offset
27
- * @param {boolean} is_last
28
- * @param {boolean} empty
130
+ * @param near - near child indices of the array
29
131
  */
30
- export function should_position_gap(near: SvelteSet<number>, edge_state: {
132
+ export declare function should_position_gap(near: SvelteSet<number>, edge_state: {
31
133
  first: boolean;
32
134
  last: boolean;
33
135
  } | undefined, offset: number, is_last: boolean, empty: boolean): boolean;
34
- import { SvelteSet } from 'svelte/reactivity';
35
136
  //# sourceMappingURL=node_visibility.svelte.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"node_visibility.svelte.d.ts","sourceRoot":"","sources":["../src/lib/node_visibility.svelte.js"],"names":[],"mappings":"AA8iBA;;;;;;;;;GASG;AACH,+CAFW,MAAM,QAsEhB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,0CANW,SAAS,CAAC,MAAM,CAAC,cACjB;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,GAAG,SAAS,UAC7C,MAAM,WACN,OAAO,SACP,OAAO,WA2BjB;0BAllBoC,mBAAmB"}
1
+ {"version":3,"file":"node_visibility.svelte.d.ts","sourceRoot":"","sources":["../src/lib/node_visibility.svelte.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqFG;AAEH,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAibzD;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE;IAC9C,OAAO,EAAE;QACR,MAAM,CAAC,EAAE;YAAE,YAAY,CAAC,EAAE,OAAO,CAAC;YAAC,kBAAkB,CAAC,EAAE,OAAO,CAAA;SAAE,CAAC;QAClE,GAAG,EAAE,OAAO,CAAC;KACb,CAAC;IACF,QAAQ,EAAE,OAAO,CAAC;IAClB,mBAAmB,CAAC,EAAE,qBAAqB,CAAC;CAC5C,GAAG,IAAI,CAkEP;AAED,MAAM,MAAM,qBAAqB,GAAG;IACnC,QAAQ,EAAE,SAAS,CAAC,MAAM,EAAE;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,IAAI,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAC/D,iBAAiB,CAAC,cAAc,EAAE,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;IAC7D,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,CAAC,EAAE,EAAE,WAAW,KAAK,MAAM,IAAI,CAAC;IAC1D,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,CAAC,EAAE,EAAE,OAAO,KAAK,MAAM,IAAI,CAAC;CACvD,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,wBAAgB,mBAAmB,CAClC,IAAI,EAAE,SAAS,CAAC,MAAM,CAAC,EACvB,UAAU,EAAE;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,GAAG,SAAS,EACzD,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,OAAO,GACZ,OAAO,CAyBT"}