@ai-composer/core 0.1.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/LICENSE +21 -0
- package/README.md +6 -0
- package/dist/commands/builtins.d.ts +41 -0
- package/dist/commands/builtins.d.ts.map +1 -0
- package/dist/commands/builtins.js +116 -0
- package/dist/commands/builtins.js.map +1 -0
- package/dist/commands/registry.d.ts +27 -0
- package/dist/commands/registry.d.ts.map +1 -0
- package/dist/commands/registry.js +29 -0
- package/dist/commands/registry.js.map +1 -0
- package/dist/editor.d.ts +185 -0
- package/dist/editor.d.ts.map +1 -0
- package/dist/editor.js +558 -0
- package/dist/editor.js.map +1 -0
- package/dist/errors.d.ts +15 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +22 -0
- package/dist/errors.js.map +1 -0
- package/dist/events/event-bus.d.ts +19 -0
- package/dist/events/event-bus.d.ts.map +1 -0
- package/dist/events/event-bus.js +51 -0
- package/dist/events/event-bus.js.map +1 -0
- package/dist/events/events.d.ts +94 -0
- package/dist/events/events.d.ts.map +1 -0
- package/dist/events/events.js +6 -0
- package/dist/events/events.js.map +1 -0
- package/dist/factory.d.ts +17 -0
- package/dist/factory.d.ts.map +1 -0
- package/dist/factory.js +18 -0
- package/dist/factory.js.map +1 -0
- package/dist/history/history.d.ts +48 -0
- package/dist/history/history.d.ts.map +1 -0
- package/dist/history/history.js +71 -0
- package/dist/history/history.js.map +1 -0
- package/dist/index.d.ts +43 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +30 -0
- package/dist/index.js.map +1 -0
- package/dist/model/document.d.ts +54 -0
- package/dist/model/document.d.ts.map +1 -0
- package/dist/model/document.js +177 -0
- package/dist/model/document.js.map +1 -0
- package/dist/model/nodes.d.ts +80 -0
- package/dist/model/nodes.d.ts.map +1 -0
- package/dist/model/nodes.js +64 -0
- package/dist/model/nodes.js.map +1 -0
- package/dist/model/selection.d.ts +40 -0
- package/dist/model/selection.d.ts.map +1 -0
- package/dist/model/selection.js +79 -0
- package/dist/model/selection.js.map +1 -0
- package/dist/nodes/registry.d.ts +39 -0
- package/dist/nodes/registry.d.ts.map +1 -0
- package/dist/nodes/registry.js +93 -0
- package/dist/nodes/registry.js.map +1 -0
- package/dist/package.json +21 -0
- package/dist/plugins/registry.d.ts +53 -0
- package/dist/plugins/registry.d.ts.map +1 -0
- package/dist/plugins/registry.js +102 -0
- package/dist/plugins/registry.js.map +1 -0
- package/dist/serialization/builtins.d.ts +30 -0
- package/dist/serialization/builtins.d.ts.map +1 -0
- package/dist/serialization/builtins.js +102 -0
- package/dist/serialization/builtins.js.map +1 -0
- package/dist/serialization/index.d.ts +4 -0
- package/dist/serialization/index.d.ts.map +1 -0
- package/dist/serialization/index.js +3 -0
- package/dist/serialization/index.js.map +1 -0
- package/dist/serialization/registry.d.ts +17 -0
- package/dist/serialization/registry.d.ts.map +1 -0
- package/dist/serialization/registry.js +35 -0
- package/dist/serialization/registry.js.map +1 -0
- package/dist/serialization/serializers.d.ts +12 -0
- package/dist/serialization/serializers.d.ts.map +1 -0
- package/dist/serialization/serializers.js +3 -0
- package/dist/serialization/serializers.js.map +1 -0
- package/dist/state/state.d.ts +54 -0
- package/dist/state/state.d.ts.map +1 -0
- package/dist/state/state.js +6 -0
- package/dist/state/state.js.map +1 -0
- package/dist/triggers/engine.d.ts +102 -0
- package/dist/triggers/engine.d.ts.map +1 -0
- package/dist/triggers/engine.js +235 -0
- package/dist/triggers/engine.js.map +1 -0
- package/dist/types.d.ts +37 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/html.d.ts +3 -0
- package/dist/utils/html.d.ts.map +1 -0
- package/dist/utils/html.js +10 -0
- package/dist/utils/html.js.map +1 -0
- package/package.json +20 -0
- package/project.json +56 -0
- package/src/commands/builtins.ts +142 -0
- package/src/commands/registry.ts +53 -0
- package/src/commands.test.ts +118 -0
- package/src/editor.test.ts +311 -0
- package/src/editor.ts +826 -0
- package/src/errors.ts +25 -0
- package/src/events/event-bus.test.ts +62 -0
- package/src/events/event-bus.ts +72 -0
- package/src/events/events.ts +120 -0
- package/src/factory.ts +21 -0
- package/src/history/history.ts +108 -0
- package/src/index.ts +201 -0
- package/src/model/document.test.ts +130 -0
- package/src/model/document.ts +207 -0
- package/src/model/nodes.ts +151 -0
- package/src/model/selection.ts +107 -0
- package/src/nodes/registry.ts +142 -0
- package/src/plugins/registry.ts +163 -0
- package/src/serialization/builtins.ts +123 -0
- package/src/serialization/index.ts +20 -0
- package/src/serialization/registry.ts +49 -0
- package/src/serialization/serializers.ts +15 -0
- package/src/state/state.ts +57 -0
- package/src/triggers/engine.ts +317 -0
- package/src/triggers.test.ts +138 -0
- package/src/types.ts +42 -0
- package/src/utils/html.ts +9 -0
- package/tsconfig.json +15 -0
- package/tsconfig.lib.json +15 -0
- package/tsconfig.spec.json +16 -0
- package/vitest.config.ts +11 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal typed event bus. No framework emitters in core — adapters map this
|
|
3
|
+
* to synthetic events, RxJS, component events, etc.
|
|
4
|
+
*/
|
|
5
|
+
export function createEventBus() {
|
|
6
|
+
const handlers = new Map();
|
|
7
|
+
const bus = {
|
|
8
|
+
on(type, handler) {
|
|
9
|
+
let set = handlers.get(type);
|
|
10
|
+
if (!set) {
|
|
11
|
+
set = new Set();
|
|
12
|
+
handlers.set(type, set);
|
|
13
|
+
}
|
|
14
|
+
set.add(handler);
|
|
15
|
+
return () => bus.off(type, handler);
|
|
16
|
+
},
|
|
17
|
+
once(type, handler) {
|
|
18
|
+
const wrapped = (payload) => {
|
|
19
|
+
off();
|
|
20
|
+
handler(payload);
|
|
21
|
+
};
|
|
22
|
+
const off = bus.on(type, wrapped);
|
|
23
|
+
return off;
|
|
24
|
+
},
|
|
25
|
+
off(type, handler) {
|
|
26
|
+
handlers.get(type)?.delete(handler);
|
|
27
|
+
},
|
|
28
|
+
emit(type, payload) {
|
|
29
|
+
const set = handlers.get(type);
|
|
30
|
+
if (!set || set.size === 0)
|
|
31
|
+
return;
|
|
32
|
+
for (const handler of [...set]) {
|
|
33
|
+
try {
|
|
34
|
+
handler(payload);
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
// A broken listener must never break the editor loop.
|
|
38
|
+
console.error(`[ai-composer] unhandled error in "${type}" listener`, error);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
listenerCount(type) {
|
|
43
|
+
return handlers.get(type)?.size ?? 0;
|
|
44
|
+
},
|
|
45
|
+
clear() {
|
|
46
|
+
handlers.clear();
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
return bus;
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=event-bus.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-bus.js","sourceRoot":"","sources":["../../src/events/event-bus.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAkBH,MAAM,UAAU,cAAc;IAC5B,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAsC,CAAC;IAE/D,MAAM,GAAG,GAAsB;QAC7B,EAAE,CAAC,IAAI,EAAE,OAAO;YACd,IAAI,GAAG,GAAG,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAC7B,IAAI,CAAC,GAAG,EAAE,CAAC;gBACT,GAAG,GAAG,IAAI,GAAG,EAAE,CAAC;gBAChB,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;YAC1B,CAAC;YACD,GAAG,CAAC,GAAG,CAAC,OAAgC,CAAC,CAAC;YAC1C,OAAO,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACtC,CAAC;QAED,IAAI,CAAC,IAAI,EAAE,OAAO;YAChB,MAAM,OAAO,GAA0B,CAAC,OAAO,EAAE,EAAE;gBACjD,GAAG,EAAE,CAAC;gBACL,OAAiC,CAAC,OAAO,CAAC,CAAC;YAC9C,CAAC,CAAC;YACF,MAAM,GAAG,GAAG,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,OAAgB,CAAC,CAAC;YAC3C,OAAO,GAAG,CAAC;QACb,CAAC;QAED,GAAG,CAAC,IAAI,EAAE,OAAO;YACf,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,OAAgC,CAAC,CAAC;QAC/D,CAAC;QAED,IAAI,CAAC,IAAI,EAAE,OAAO;YAChB,MAAM,GAAG,GAAG,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAC/B,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,KAAK,CAAC;gBAAE,OAAO;YACnC,KAAK,MAAM,OAAO,IAAI,CAAC,GAAG,GAAG,CAAC,EAAE,CAAC;gBAC/B,IAAI,CAAC;oBACH,OAAO,CAAC,OAAO,CAAC,CAAC;gBACnB,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,sDAAsD;oBACtD,OAAO,CAAC,KAAK,CAAC,qCAAqC,IAAI,YAAY,EAAE,KAAK,CAAC,CAAC;gBAC9E,CAAC;YACH,CAAC;QACH,CAAC;QAED,aAAa,CAAC,IAAI;YAChB,OAAO,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,CAAC;QACvC,CAAC;QAED,KAAK;YACH,QAAQ,CAAC,KAAK,EAAE,CAAC;QACnB,CAAC;KACF,CAAC;IAEF,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The editor event contract. Every adapter emits exactly these semantics, so
|
|
3
|
+
* behavior can be contract-tested across frameworks.
|
|
4
|
+
*/
|
|
5
|
+
import type { EventBus } from './event-bus';
|
|
6
|
+
import type { AIComposerDocument } from '../model/document';
|
|
7
|
+
import type { AttachmentNode, AIComposerNode } from '../model/nodes';
|
|
8
|
+
import type { SelectionState } from '../model/selection';
|
|
9
|
+
import type { SuggestionItem } from '../state/state';
|
|
10
|
+
/** What caused a document change. */
|
|
11
|
+
export type ChangeSource = 'init' | 'user' | 'api' | 'plugin' | 'undo' | 'redo';
|
|
12
|
+
export interface ChangeEvent {
|
|
13
|
+
value: AIComposerDocument;
|
|
14
|
+
source: ChangeSource;
|
|
15
|
+
}
|
|
16
|
+
export interface FocusChangeEvent {
|
|
17
|
+
focused: boolean;
|
|
18
|
+
}
|
|
19
|
+
export interface BeforeSubmitEvent {
|
|
20
|
+
value: AIComposerDocument;
|
|
21
|
+
defaultPrevented: boolean;
|
|
22
|
+
preventDefault(): void;
|
|
23
|
+
}
|
|
24
|
+
export interface SubmitEvent {
|
|
25
|
+
value: AIComposerDocument;
|
|
26
|
+
}
|
|
27
|
+
export interface SelectionChangeEvent {
|
|
28
|
+
selection: SelectionState;
|
|
29
|
+
}
|
|
30
|
+
export interface TriggerOpenEvent {
|
|
31
|
+
triggerId: string;
|
|
32
|
+
query: string;
|
|
33
|
+
}
|
|
34
|
+
export type TriggerCloseReason = 'select' | 'escape' | 'blur' | 'input' | 'manual' | 'editor-destroy';
|
|
35
|
+
export interface TriggerCloseEvent {
|
|
36
|
+
triggerId: string;
|
|
37
|
+
reason: TriggerCloseReason;
|
|
38
|
+
}
|
|
39
|
+
export interface SuggestionsChangeEvent {
|
|
40
|
+
triggerId: string | null;
|
|
41
|
+
suggestions: SuggestionItem[];
|
|
42
|
+
activeIndex: number;
|
|
43
|
+
}
|
|
44
|
+
export interface NodeInsertEvent {
|
|
45
|
+
node: AIComposerNode;
|
|
46
|
+
index: number;
|
|
47
|
+
}
|
|
48
|
+
export interface NodeRemoveEvent {
|
|
49
|
+
node: AIComposerNode;
|
|
50
|
+
index: number;
|
|
51
|
+
}
|
|
52
|
+
export interface AttachmentEvent {
|
|
53
|
+
attachment: AttachmentNode;
|
|
54
|
+
}
|
|
55
|
+
export interface CommandExecuteEvent {
|
|
56
|
+
id: string;
|
|
57
|
+
payload?: unknown;
|
|
58
|
+
}
|
|
59
|
+
export interface ModeChangeEvent {
|
|
60
|
+
mode: string;
|
|
61
|
+
}
|
|
62
|
+
export interface ErrorEvent {
|
|
63
|
+
error: Error;
|
|
64
|
+
/** Where it happened, e.g. `trigger:mention:search`, `submit`. */
|
|
65
|
+
phase?: string;
|
|
66
|
+
}
|
|
67
|
+
export interface DestroyEvent {
|
|
68
|
+
target: 'editor';
|
|
69
|
+
}
|
|
70
|
+
export type AIComposerEventMap = {
|
|
71
|
+
/** Any value change, from any source. */
|
|
72
|
+
change: ChangeEvent;
|
|
73
|
+
/** Value change caused by user input (typing, paste, chip insert). */
|
|
74
|
+
input: ChangeEvent;
|
|
75
|
+
focus: FocusChangeEvent;
|
|
76
|
+
blur: FocusChangeEvent;
|
|
77
|
+
beforeSubmit: BeforeSubmitEvent;
|
|
78
|
+
submit: SubmitEvent;
|
|
79
|
+
selectionChange: SelectionChangeEvent;
|
|
80
|
+
triggerOpen: TriggerOpenEvent;
|
|
81
|
+
triggerClose: TriggerCloseEvent;
|
|
82
|
+
suggestionsChange: SuggestionsChangeEvent;
|
|
83
|
+
nodeInsert: NodeInsertEvent;
|
|
84
|
+
nodeRemove: NodeRemoveEvent;
|
|
85
|
+
attachmentAdd: AttachmentEvent;
|
|
86
|
+
attachmentRemove: AttachmentEvent;
|
|
87
|
+
commandExecute: CommandExecuteEvent;
|
|
88
|
+
modeChange: ModeChangeEvent;
|
|
89
|
+
error: ErrorEvent;
|
|
90
|
+
destroy: DestroyEvent;
|
|
91
|
+
};
|
|
92
|
+
export type AIComposerEventType = keyof AIComposerEventMap & string;
|
|
93
|
+
export type AIComposerBus = EventBus<AIComposerEventMap>;
|
|
94
|
+
//# sourceMappingURL=events.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/events/events.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/events/events.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/** Factory + version. */
|
|
2
|
+
import { type AIComposer } from './editor';
|
|
3
|
+
import type { AIComposerOptions } from './types';
|
|
4
|
+
/**
|
|
5
|
+
* Create a framework-independent AI Composer editor instance.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```ts
|
|
9
|
+
* const editor = createAIComposer({
|
|
10
|
+
* placeholder: 'Ask anything…',
|
|
11
|
+
* plugins: [mentionPlugin({ trigger: '@', items })],
|
|
12
|
+
* });
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
15
|
+
export declare function createAIComposer(options?: AIComposerOptions): AIComposer;
|
|
16
|
+
export declare const CORE_VERSION = "0.1.0";
|
|
17
|
+
//# sourceMappingURL=factory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"AAAA,yBAAyB;AAEzB,OAAO,EAAkB,KAAK,UAAU,EAAE,MAAM,UAAU,CAAC;AAC3D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAEjD;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,GAAE,iBAAsB,GAAG,UAAU,CAE5E;AAED,eAAO,MAAM,YAAY,UAAU,CAAC"}
|
package/dist/factory.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/** Factory + version. */
|
|
2
|
+
import { AIComposerImpl } from './editor';
|
|
3
|
+
/**
|
|
4
|
+
* Create a framework-independent AI Composer editor instance.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```ts
|
|
8
|
+
* const editor = createAIComposer({
|
|
9
|
+
* placeholder: 'Ask anything…',
|
|
10
|
+
* plugins: [mentionPlugin({ trigger: '@', items })],
|
|
11
|
+
* });
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
export function createAIComposer(options = {}) {
|
|
15
|
+
return new AIComposerImpl(options);
|
|
16
|
+
}
|
|
17
|
+
export const CORE_VERSION = '0.1.0';
|
|
18
|
+
//# sourceMappingURL=factory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"factory.js","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"AAAA,yBAAyB;AAEzB,OAAO,EAAE,cAAc,EAAmB,MAAM,UAAU,CAAC;AAG3D;;;;;;;;;;GAUG;AACH,MAAM,UAAU,gBAAgB,CAAC,UAA6B,EAAE;IAC9D,OAAO,IAAI,cAAc,CAAC,OAAO,CAAC,CAAC;AACrC,CAAC;AAED,MAAM,CAAC,MAAM,YAAY,GAAG,OAAO,CAAC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Undo/redo — snapshot-based history (ADR-0003). Composer documents are small,
|
|
3
|
+
* so storing immutable document references beats operational transforms in
|
|
4
|
+
* simplicity and debuggability. Rapid consecutive user edits (typing) within
|
|
5
|
+
* `mergeWindowMs` collapse into a single undo step.
|
|
6
|
+
*/
|
|
7
|
+
import type { AIComposerDocument } from '../model/document';
|
|
8
|
+
import type { SelectionState } from '../model/selection';
|
|
9
|
+
export interface HistorySnapshot {
|
|
10
|
+
document: AIComposerDocument;
|
|
11
|
+
selection: SelectionState;
|
|
12
|
+
}
|
|
13
|
+
export interface HistoryOptions {
|
|
14
|
+
/** Max undo steps kept (default 200). */
|
|
15
|
+
limit?: number;
|
|
16
|
+
/** Window in ms within which same-label user edits merge (default 500). */
|
|
17
|
+
mergeWindowMs?: number;
|
|
18
|
+
}
|
|
19
|
+
export declare const DEFAULT_HISTORY_OPTIONS: Required<HistoryOptions>;
|
|
20
|
+
export interface RecordOptions {
|
|
21
|
+
/** Change label — merges only happen between identical labels. */
|
|
22
|
+
label?: string;
|
|
23
|
+
/** Only same-label merges; requires the caller to opt in (user typing). */
|
|
24
|
+
merge?: boolean;
|
|
25
|
+
}
|
|
26
|
+
export declare class EditorHistory {
|
|
27
|
+
private options;
|
|
28
|
+
/** States we can go back TO. */
|
|
29
|
+
private undoStack;
|
|
30
|
+
/** States we can go forward TO. */
|
|
31
|
+
private redoStack;
|
|
32
|
+
constructor(options?: HistoryOptions);
|
|
33
|
+
get canUndo(): boolean;
|
|
34
|
+
get canRedo(): boolean;
|
|
35
|
+
/**
|
|
36
|
+
* Record a change. `previous` is the state BEFORE the change; documents are
|
|
37
|
+
* immutable so no cloning is needed.
|
|
38
|
+
*/
|
|
39
|
+
record(previous: HistorySnapshot, options?: RecordOptions): void;
|
|
40
|
+
/** Return the state to restore, or null when nothing to undo. */
|
|
41
|
+
undo(current: HistorySnapshot): HistorySnapshot | null;
|
|
42
|
+
/** Return the state to restore, or null when nothing to redo. */
|
|
43
|
+
redo(current: HistorySnapshot): HistorySnapshot | null;
|
|
44
|
+
setOptions(options: HistoryOptions): void;
|
|
45
|
+
getOptions(): Required<HistoryOptions>;
|
|
46
|
+
reset(): void;
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=history.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"history.d.ts","sourceRoot":"","sources":["../../src/history/history.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEzD,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,SAAS,EAAE,cAAc,CAAC;CAC3B;AAOD,MAAM,WAAW,cAAc;IAC7B,yCAAyC;IACzC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2EAA2E;IAC3E,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,eAAO,MAAM,uBAAuB,EAAE,QAAQ,CAAC,cAAc,CAG5D,CAAC;AAEF,MAAM,WAAW,aAAa;IAC5B,kEAAkE;IAClE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2EAA2E;IAC3E,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,OAAO,CAA2B;IAC1C,gCAAgC;IAChC,OAAO,CAAC,SAAS,CAAsB;IACvC,mCAAmC;IACnC,OAAO,CAAC,SAAS,CAAsB;gBAE3B,OAAO,GAAE,cAAmB;IAIxC,IAAI,OAAO,IAAI,OAAO,CAErB;IAED,IAAI,OAAO,IAAI,OAAO,CAErB;IAED;;;OAGG;IACH,MAAM,CAAC,QAAQ,EAAE,eAAe,EAAE,OAAO,GAAE,aAAkB,GAAG,IAAI;IAiBpE,iEAAiE;IACjE,IAAI,CAAC,OAAO,EAAE,eAAe,GAAG,eAAe,GAAG,IAAI;IAOtD,iEAAiE;IACjE,IAAI,CAAC,OAAO,EAAE,eAAe,GAAG,eAAe,GAAG,IAAI;IAOtD,UAAU,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;IAIzC,UAAU,IAAI,QAAQ,CAAC,cAAc,CAAC;IAItC,KAAK,IAAI,IAAI;CAId"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Undo/redo — snapshot-based history (ADR-0003). Composer documents are small,
|
|
3
|
+
* so storing immutable document references beats operational transforms in
|
|
4
|
+
* simplicity and debuggability. Rapid consecutive user edits (typing) within
|
|
5
|
+
* `mergeWindowMs` collapse into a single undo step.
|
|
6
|
+
*/
|
|
7
|
+
export const DEFAULT_HISTORY_OPTIONS = {
|
|
8
|
+
limit: 200,
|
|
9
|
+
mergeWindowMs: 500,
|
|
10
|
+
};
|
|
11
|
+
export class EditorHistory {
|
|
12
|
+
options;
|
|
13
|
+
/** States we can go back TO. */
|
|
14
|
+
undoStack = [];
|
|
15
|
+
/** States we can go forward TO. */
|
|
16
|
+
redoStack = [];
|
|
17
|
+
constructor(options = {}) {
|
|
18
|
+
this.options = { ...DEFAULT_HISTORY_OPTIONS, ...options };
|
|
19
|
+
}
|
|
20
|
+
get canUndo() {
|
|
21
|
+
return this.undoStack.length > 0;
|
|
22
|
+
}
|
|
23
|
+
get canRedo() {
|
|
24
|
+
return this.redoStack.length > 0;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Record a change. `previous` is the state BEFORE the change; documents are
|
|
28
|
+
* immutable so no cloning is needed.
|
|
29
|
+
*/
|
|
30
|
+
record(previous, options = {}) {
|
|
31
|
+
const label = options.label ?? 'edit';
|
|
32
|
+
this.redoStack = [];
|
|
33
|
+
const top = this.undoStack[this.undoStack.length - 1];
|
|
34
|
+
const shouldMerge = options.merge === true &&
|
|
35
|
+
top !== undefined &&
|
|
36
|
+
top.label === label &&
|
|
37
|
+
Date.now() - top.timestamp <= this.options.mergeWindowMs;
|
|
38
|
+
if (!shouldMerge) {
|
|
39
|
+
this.undoStack.push({ ...previous, label, timestamp: Date.now() });
|
|
40
|
+
if (this.undoStack.length > this.options.limit)
|
|
41
|
+
this.undoStack.shift();
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/** Return the state to restore, or null when nothing to undo. */
|
|
45
|
+
undo(current) {
|
|
46
|
+
const entry = this.undoStack.pop();
|
|
47
|
+
if (!entry)
|
|
48
|
+
return null;
|
|
49
|
+
this.redoStack.push({ ...current, label: entry.label, timestamp: Date.now() });
|
|
50
|
+
return { document: entry.document, selection: entry.selection };
|
|
51
|
+
}
|
|
52
|
+
/** Return the state to restore, or null when nothing to redo. */
|
|
53
|
+
redo(current) {
|
|
54
|
+
const entry = this.redoStack.pop();
|
|
55
|
+
if (!entry)
|
|
56
|
+
return null;
|
|
57
|
+
this.undoStack.push({ ...current, label: entry.label, timestamp: Date.now() });
|
|
58
|
+
return { document: entry.document, selection: entry.selection };
|
|
59
|
+
}
|
|
60
|
+
setOptions(options) {
|
|
61
|
+
this.options = { ...this.options, ...options };
|
|
62
|
+
}
|
|
63
|
+
getOptions() {
|
|
64
|
+
return { ...this.options };
|
|
65
|
+
}
|
|
66
|
+
reset() {
|
|
67
|
+
this.undoStack = [];
|
|
68
|
+
this.redoStack = [];
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=history.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"history.js","sourceRoot":"","sources":["../../src/history/history.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @ai-composer/core — the framework-independent AI composer engine.
|
|
3
|
+
*
|
|
4
|
+
* Layers:
|
|
5
|
+
* model/ document, nodes, selection (pure data + edit primitives)
|
|
6
|
+
* state/ observable editor state
|
|
7
|
+
* events/ typed event bus + editor event map
|
|
8
|
+
* commands/ command registry + built-ins
|
|
9
|
+
* triggers/ trigger registry + suggestion engine
|
|
10
|
+
* history/ snapshot undo/redo with merge window
|
|
11
|
+
* plugins/ plugin contract + registry
|
|
12
|
+
* serialization/ json / text / markdown / html / ai serializers
|
|
13
|
+
*/
|
|
14
|
+
export type { AIComposerDocument } from './model/document';
|
|
15
|
+
export { coerceDocument, createDocument, deleteDocumentRange, documentLength, documentsEqual, findNode, findNodeIndex, getNodesOfType, insertNodesAt, isEmptyDocument, nodeLength, normalizeNodes, sanitizeDocument, } from './model/document';
|
|
16
|
+
export type { AttachmentNode, AtomicNode, BaseNode, CommandNode, CustomNode, MentionNode, NodeKey, AIComposerNode, AIComposerNodeType, TextNode, VariableNode, } from './model/nodes';
|
|
17
|
+
export { createAttachmentNode, createCommandNode, createCustomNode, createMentionNode, createNodeKey, createTextNode, createVariableNode, ensureNodeKey, getNodeType, isAtomicNode, isAIComposerNode, isTextNode, } from './model/nodes';
|
|
18
|
+
export type { DocumentRange, Position, SelectionState } from './model/selection';
|
|
19
|
+
export { clampPosition, clampSelection, comparePositions, createPosition, createSelection, equalsPosition, equalsSelection, fromGlobalOffset, getEnd, getRange, getStart, globalRange, isCollapsed, toGlobalOffset, } from './model/selection';
|
|
20
|
+
export type { AIComposerState, SuggestionItem, TriggerState } from './state/state';
|
|
21
|
+
export type { AttachmentEvent, BeforeSubmitEvent, ChangeEvent, ChangeSource, CommandExecuteEvent, DestroyEvent, ErrorEvent, FocusChangeEvent, ModeChangeEvent, NodeInsertEvent, NodeRemoveEvent, AIComposerBus, AIComposerEventMap, AIComposerEventType, SelectionChangeEvent, SubmitEvent, SuggestionsChangeEvent, TriggerCloseEvent, TriggerCloseReason, TriggerOpenEvent, } from './events/events';
|
|
22
|
+
export type { EventBus, EventHandler, EventMapBase, Unsubscribe, } from './events/event-bus';
|
|
23
|
+
export { createEventBus } from './events/event-bus';
|
|
24
|
+
export type { CommandContext, CommandRegistry, AIComposerCommand } from './commands/registry';
|
|
25
|
+
export { createCommandRegistry } from './commands/registry';
|
|
26
|
+
export { BUILTIN_COMMANDS, createBuiltinCommands, type AcceptSuggestionPayload, type InsertNodePayload, type InsertTextPayload, type OpenTriggerPayload, type RemoveNodePayload, } from './commands/builtins';
|
|
27
|
+
export type { AIComposerTrigger, TriggerHost, TriggerRegistry, TriggerSearchContext, TriggerSelectContext, } from './triggers/engine';
|
|
28
|
+
export { TriggerEngine, createNodeFromSuggestion, createTriggerRegistry, defineTrigger, } from './triggers/engine';
|
|
29
|
+
export type { HistoryOptions, HistorySnapshot, RecordOptions } from './history/history';
|
|
30
|
+
export { DEFAULT_HISTORY_OPTIONS, EditorHistory } from './history/history';
|
|
31
|
+
export type { PluginContext, AIComposerPlugin, PluginRegistry } from './plugins/registry';
|
|
32
|
+
export { createPluginRegistry } from './plugins/registry';
|
|
33
|
+
export type { AIComposerPayload, SerializationFormat, Serializer, SerializerContext, SerializerRegistry, } from './serialization';
|
|
34
|
+
export { createAiSerializer, createDefaultSerializers, createHtmlSerializer, createJsonSerializer, createMarkdownSerializer, createSerializerRegistry, createTextSerializer, documentToText, nodeToText, } from './serialization';
|
|
35
|
+
export type { NodeDefinition, NodeRegistry } from './nodes/registry';
|
|
36
|
+
export { ATTACHMENT_NODE_DEFINITION, COMMAND_NODE_DEFINITION, CUSTOM_NODE_DEFINITION, MENTION_NODE_DEFINITION, TEXT_NODE_DEFINITION, VARIABLE_NODE_DEFINITION, createDefaultNodeRegistry, createNodeRegistry, } from './nodes/registry';
|
|
37
|
+
export type { AIComposer, EditorView, InsertNodeOptions, SetValueOptions, StateListener, TransactionOptions, } from './editor';
|
|
38
|
+
export { AIComposerImpl, isAIComposer } from './editor';
|
|
39
|
+
export { createAIComposer, CORE_VERSION } from './factory';
|
|
40
|
+
export type { AIComposerConfig, AIComposerOptions, SubmitConfig, SubmitKey, } from './types';
|
|
41
|
+
export { ErrorCode, AIComposerError, toError, type AIComposerErrorCode } from './errors';
|
|
42
|
+
export { escapeHtml } from './utils/html';
|
|
43
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @ai-composer/core — the framework-independent AI composer engine.
|
|
3
|
+
*
|
|
4
|
+
* Layers:
|
|
5
|
+
* model/ document, nodes, selection (pure data + edit primitives)
|
|
6
|
+
* state/ observable editor state
|
|
7
|
+
* events/ typed event bus + editor event map
|
|
8
|
+
* commands/ command registry + built-ins
|
|
9
|
+
* triggers/ trigger registry + suggestion engine
|
|
10
|
+
* history/ snapshot undo/redo with merge window
|
|
11
|
+
* plugins/ plugin contract + registry
|
|
12
|
+
* serialization/ json / text / markdown / html / ai serializers
|
|
13
|
+
*/
|
|
14
|
+
export { coerceDocument, createDocument, deleteDocumentRange, documentLength, documentsEqual, findNode, findNodeIndex, getNodesOfType, insertNodesAt, isEmptyDocument, nodeLength, normalizeNodes, sanitizeDocument, } from './model/document';
|
|
15
|
+
export { createAttachmentNode, createCommandNode, createCustomNode, createMentionNode, createNodeKey, createTextNode, createVariableNode, ensureNodeKey, getNodeType, isAtomicNode, isAIComposerNode, isTextNode, } from './model/nodes';
|
|
16
|
+
export { clampPosition, clampSelection, comparePositions, createPosition, createSelection, equalsPosition, equalsSelection, fromGlobalOffset, getEnd, getRange, getStart, globalRange, isCollapsed, toGlobalOffset, } from './model/selection';
|
|
17
|
+
export { createEventBus } from './events/event-bus';
|
|
18
|
+
export { createCommandRegistry } from './commands/registry';
|
|
19
|
+
export { BUILTIN_COMMANDS, createBuiltinCommands, } from './commands/builtins';
|
|
20
|
+
export { TriggerEngine, createNodeFromSuggestion, createTriggerRegistry, defineTrigger, } from './triggers/engine';
|
|
21
|
+
export { DEFAULT_HISTORY_OPTIONS, EditorHistory } from './history/history';
|
|
22
|
+
export { createPluginRegistry } from './plugins/registry';
|
|
23
|
+
export { createAiSerializer, createDefaultSerializers, createHtmlSerializer, createJsonSerializer, createMarkdownSerializer, createSerializerRegistry, createTextSerializer, documentToText, nodeToText, } from './serialization';
|
|
24
|
+
export { ATTACHMENT_NODE_DEFINITION, COMMAND_NODE_DEFINITION, CUSTOM_NODE_DEFINITION, MENTION_NODE_DEFINITION, TEXT_NODE_DEFINITION, VARIABLE_NODE_DEFINITION, createDefaultNodeRegistry, createNodeRegistry, } from './nodes/registry';
|
|
25
|
+
export { AIComposerImpl, isAIComposer } from './editor';
|
|
26
|
+
export { createAIComposer, CORE_VERSION } from './factory';
|
|
27
|
+
// errors
|
|
28
|
+
export { ErrorCode, AIComposerError, toError } from './errors';
|
|
29
|
+
export { escapeHtml } from './utils/html';
|
|
30
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAIH,OAAO,EACL,cAAc,EACd,cAAc,EACd,mBAAmB,EACnB,cAAc,EACd,cAAc,EACd,QAAQ,EACR,aAAa,EACb,cAAc,EACd,aAAa,EACb,eAAe,EACf,UAAU,EACV,cAAc,EACd,gBAAgB,GACjB,MAAM,kBAAkB,CAAC;AAc1B,OAAO,EACL,oBAAoB,EACpB,iBAAiB,EACjB,gBAAgB,EAChB,iBAAiB,EACjB,aAAa,EACb,cAAc,EACd,kBAAkB,EAClB,aAAa,EACb,WAAW,EACX,YAAY,EACZ,gBAAgB,EAChB,UAAU,GACX,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,aAAa,EACb,cAAc,EACd,gBAAgB,EAChB,cAAc,EACd,eAAe,EACf,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,MAAM,EACN,QAAQ,EACR,QAAQ,EACR,WAAW,EACX,WAAW,EACX,cAAc,GACf,MAAM,mBAAmB,CAAC;AAkC3B,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAIpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EACL,gBAAgB,EAChB,qBAAqB,GAMtB,MAAM,qBAAqB,CAAC;AAU7B,OAAO,EACL,aAAa,EACb,wBAAwB,EACxB,qBAAqB,EACrB,aAAa,GACd,MAAM,mBAAmB,CAAC;AAI3B,OAAO,EAAE,uBAAuB,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAI3E,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAU1D,OAAO,EACL,kBAAkB,EAClB,wBAAwB,EACxB,oBAAoB,EACpB,oBAAoB,EACpB,wBAAwB,EACxB,wBAAwB,EACxB,oBAAoB,EACpB,cAAc,EACd,UAAU,GACX,MAAM,iBAAiB,CAAC;AAIzB,OAAO,EACL,0BAA0B,EAC1B,uBAAuB,EACvB,sBAAsB,EACtB,uBAAuB,EACvB,oBAAoB,EACpB,wBAAwB,EACxB,yBAAyB,EACzB,kBAAkB,GACnB,MAAM,kBAAkB,CAAC;AAW1B,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAQ3D,SAAS;AACT,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,OAAO,EAA4B,MAAM,UAAU,CAAC;AAEzF,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Composer document — the authoritative, framework-neutral value of an editor
|
|
3
|
+
* (model-first architecture, ADR-0001). Documents are treated as immutable:
|
|
4
|
+
* edit helpers return new documents and never mutate node objects.
|
|
5
|
+
*/
|
|
6
|
+
import { type AIComposerNode } from './nodes';
|
|
7
|
+
import { type Position, type DocumentRange } from './selection';
|
|
8
|
+
export interface AIComposerDocument {
|
|
9
|
+
nodes: AIComposerNode[];
|
|
10
|
+
metadata?: Record<string, unknown>;
|
|
11
|
+
}
|
|
12
|
+
export declare function createDocument(nodes?: AIComposerNode[], metadata?: Record<string, unknown>): AIComposerDocument;
|
|
13
|
+
/** Coerce common inputs into a document. */
|
|
14
|
+
export declare function coerceDocument(value: AIComposerDocument | AIComposerNode[] | string | null | undefined): AIComposerDocument;
|
|
15
|
+
/**
|
|
16
|
+
* Merge adjacent text nodes and drop empty text runs. Returns a new array;
|
|
17
|
+
* input nodes are never mutated.
|
|
18
|
+
*/
|
|
19
|
+
export declare function normalizeNodes(nodes: AIComposerNode[]): AIComposerNode[];
|
|
20
|
+
export declare function nodeLength(node: AIComposerNode): number;
|
|
21
|
+
export declare function totalLength(nodes: AIComposerNode[]): number;
|
|
22
|
+
export declare function documentLength(document: AIComposerDocument): number;
|
|
23
|
+
/**
|
|
24
|
+
* True when there is nothing meaningful to show or submit: no chips and no
|
|
25
|
+
* text beyond whitespace. ContentEditable hosts keep a layout `<br>` after
|
|
26
|
+
* the user deletes everything — that artifact must read as empty or the
|
|
27
|
+
* placeholder never comes back.
|
|
28
|
+
*/
|
|
29
|
+
export declare function isEmptyDocument(document: AIComposerDocument): boolean;
|
|
30
|
+
export declare function findNodeIndex(document: AIComposerDocument, key: string): number;
|
|
31
|
+
export declare function findNode(document: AIComposerDocument, key: string): {
|
|
32
|
+
node: AIComposerNode;
|
|
33
|
+
index: number;
|
|
34
|
+
} | null;
|
|
35
|
+
export declare function getNodesOfType<T extends AIComposerNode>(document: AIComposerDocument, type: T['type']): T[];
|
|
36
|
+
export declare function cloneDocument(document: AIComposerDocument): AIComposerDocument;
|
|
37
|
+
export declare function documentsEqual(a: AIComposerDocument, b: AIComposerDocument): boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Replace unknown/unregistered node types with a readable text node so that
|
|
40
|
+
* documents from external sources (paste, storage, setValue) can never inject
|
|
41
|
+
* unrenderable nodes.
|
|
42
|
+
*/
|
|
43
|
+
export declare function sanitizeDocument(document: AIComposerDocument, isKnownType: (type: string) => boolean): AIComposerDocument;
|
|
44
|
+
/** Delete `range` (inclusive) and report the caret position after deletion. */
|
|
45
|
+
export declare function deleteDocumentRange(document: AIComposerDocument, range: DocumentRange): {
|
|
46
|
+
document: AIComposerDocument;
|
|
47
|
+
caret: Position;
|
|
48
|
+
};
|
|
49
|
+
/** Insert `inserted` at `position` (splitting a text node when needed). */
|
|
50
|
+
export declare function insertNodesAt(document: AIComposerDocument, position: Position, inserted: AIComposerNode[]): {
|
|
51
|
+
document: AIComposerDocument;
|
|
52
|
+
caret: Position;
|
|
53
|
+
};
|
|
54
|
+
//# sourceMappingURL=document.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"document.d.ts","sourceRoot":"","sources":["../../src/model/document.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAIL,KAAK,cAAc,EACpB,MAAM,SAAS,CAAC;AACjB,OAAO,EAAoC,KAAK,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAElG,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,wBAAgB,cAAc,CAAC,KAAK,GAAE,cAAc,EAAO,EAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,kBAAkB,CAInH;AAED,4CAA4C;AAC5C,wBAAgB,cAAc,CAAC,KAAK,EAAE,kBAAkB,GAAG,cAAc,EAAE,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,kBAAkB,CAK3H;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,cAAc,EAAE,GAAG,cAAc,EAAE,CAcxE;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM,CAEvD;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,cAAc,EAAE,GAAG,MAAM,CAE3D;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,kBAAkB,GAAG,MAAM,CAEnE;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,kBAAkB,GAAG,OAAO,CAQrE;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,kBAAkB,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAE/E;AAED,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,kBAAkB,EAAE,GAAG,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAGlH;AAED,wBAAgB,cAAc,CAAC,CAAC,SAAS,cAAc,EAAE,QAAQ,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAE3G;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,kBAAkB,GAAG,kBAAkB,CAK9E;AAED,wBAAgB,cAAc,CAAC,CAAC,EAAE,kBAAkB,EAAE,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAGpF;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,kBAAkB,EAC5B,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,GACrC,kBAAkB,CASpB;AAMD,+EAA+E;AAC/E,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,kBAAkB,EAC5B,KAAK,EAAE,aAAa,GACnB;IAAE,QAAQ,EAAE,kBAAkB,CAAC;IAAC,KAAK,EAAE,QAAQ,CAAA;CAAE,CAgCnD;AAED,2EAA2E;AAC3E,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,kBAAkB,EAC5B,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,cAAc,EAAE,GACzB;IAAE,QAAQ,EAAE,kBAAkB,CAAC;IAAC,KAAK,EAAE,QAAQ,CAAA;CAAE,CAkCnD"}
|