@framers/agentos-ext-streaming-stt-deepgram 0.2.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 ADDED
@@ -0,0 +1,23 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Framers
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
23
+
package/SKILL.md ADDED
@@ -0,0 +1,62 @@
1
+ ---
2
+ name: streaming-stt-deepgram
3
+ description: Real-time streaming speech-to-text via Deepgram WebSocket API
4
+ category: voice
5
+ ---
6
+
7
+ # Deepgram Streaming STT
8
+
9
+ Real-time streaming speech-to-text using Deepgram's Nova-2 model via WebSocket.
10
+
11
+ ## Setup
12
+
13
+ Set `DEEPGRAM_API_KEY` in your environment or agent secrets store.
14
+
15
+ ## Features
16
+
17
+ - Sub-300 ms latency interim transcripts
18
+ - Native speaker diarization (word-level `speaker` labels)
19
+ - Automatic punctuation insertion
20
+ - Word-level timestamps and per-word confidence scores
21
+ - Auto-reconnect on connection drops (exponential back-off 100 ms → 5 s)
22
+ - Keyword boosting via `providerOptions.keywords`
23
+
24
+ ## Configuration
25
+
26
+ In `agent.config.json`:
27
+
28
+ ```json
29
+ {
30
+ "voice": {
31
+ "stt": "deepgram"
32
+ }
33
+ }
34
+ ```
35
+
36
+ Provider-specific options via `providerOptions`:
37
+
38
+ ```json
39
+ {
40
+ "voice": {
41
+ "stt": "deepgram",
42
+ "providerOptions": {
43
+ "model": "nova-2",
44
+ "diarize": true,
45
+ "keywords": ["AgentOS:2", "Deepgram:1.5"],
46
+ "endpointing": 300
47
+ }
48
+ }
49
+ }
50
+ ```
51
+
52
+ ## Events
53
+
54
+ | Event | Payload | Description |
55
+ |------------------------|-------------------|-------------------------------------------------|
56
+ | `transcript` | `TranscriptEvent` | Every hypothesis (interim + final) |
57
+ | `interim_transcript` | `TranscriptEvent` | Non-final hypothesis |
58
+ | `final_transcript` | `TranscriptEvent` | Stable, final hypothesis |
59
+ | `speech_start` | — | First non-empty word in an utterance |
60
+ | `speech_end` | — | Deepgram `speech_final` flag raised |
61
+ | `error` | `Error` | Unrecoverable provider error |
62
+ | `close` | — | Session fully terminated |
@@ -0,0 +1,78 @@
1
+ /**
2
+ * @file DeepgramDiarizationAdapter.ts
3
+ * @description Utilities for extracting speaker labels from Deepgram word-level
4
+ * diarization results.
5
+ *
6
+ * Deepgram's `diarize: true` option annotates each word in the transcript with
7
+ * a zero-indexed integer `speaker` field. This module converts that raw
8
+ * numeric label into the string format expected by {@link TranscriptWord.speaker}
9
+ * (`'Speaker_0'`, `'Speaker_1'`, …) and determines the majority speaker for
10
+ * an utterance.
11
+ *
12
+ * @module streaming-stt-deepgram/DeepgramDiarizationAdapter
13
+ */
14
+ /**
15
+ * A single Deepgram word object as returned by the WebSocket API when
16
+ * `diarize: true` is passed in the connection query string.
17
+ *
18
+ * Only the fields used by this adapter are declared; the raw JSON may contain
19
+ * additional fields that are ignored.
20
+ */
21
+ export interface DeepgramWord {
22
+ /** Recognised word token. */
23
+ word: string;
24
+ /** Start time relative to the stream start in seconds. */
25
+ start: number;
26
+ /** End time relative to the stream start in seconds. */
27
+ end: number;
28
+ /** Recognition confidence in [0, 1]. */
29
+ confidence: number;
30
+ /**
31
+ * Zero-indexed speaker index assigned by Deepgram's diarization model.
32
+ * Present only when the session was opened with `diarize=true`.
33
+ */
34
+ speaker?: number;
35
+ /** Punctuated variant of {@link word} when `punctuate=true`. */
36
+ punctuated_word?: string;
37
+ }
38
+ /**
39
+ * Extract the majority speaker label from an array of Deepgram word objects.
40
+ *
41
+ * The function tallies votes by `speaker` index and returns the label for the
42
+ * speaker with the most words. Ties are broken by lowest index (i.e. the
43
+ * earliest-assigned speaker wins).
44
+ *
45
+ * Returns `undefined` when the array is empty or no word carries a `speaker`
46
+ * field (i.e. diarization was not requested for this session).
47
+ *
48
+ * @param words - Raw Deepgram word objects from `channel.alternatives[0].words`.
49
+ * @returns A string label such as `'Speaker_0'`, or `undefined`.
50
+ *
51
+ * @example
52
+ * ```ts
53
+ * const words = [
54
+ * { word: 'Hello', speaker: 0, start: 0, end: 0.3, confidence: 0.99 },
55
+ * { word: 'world', speaker: 1, start: 0.4, end: 0.7, confidence: 0.97 },
56
+ * { word: 'today', speaker: 0, start: 0.8, end: 1.1, confidence: 0.95 },
57
+ * ];
58
+ * extractSpeakerFromWords(words); // → 'Speaker_0'
59
+ * ```
60
+ */
61
+ export declare function extractSpeakerFromWords(words: DeepgramWord[]): string | undefined;
62
+ /**
63
+ * Map a Deepgram word object to the canonical `TranscriptWord`-compatible shape.
64
+ *
65
+ * Seconds are converted to milliseconds to match the voice pipeline convention.
66
+ * The `word` field prefers the punctuated variant when available.
67
+ *
68
+ * @param dw - Raw Deepgram word object.
69
+ * @returns A plain object matching the {@link TranscriptWord} interface.
70
+ */
71
+ export declare function mapDeepgramWord(dw: DeepgramWord): {
72
+ word: string;
73
+ start: number;
74
+ end: number;
75
+ confidence: number;
76
+ speaker?: string;
77
+ };
78
+ //# sourceMappingURL=DeepgramDiarizationAdapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DeepgramDiarizationAdapter.d.ts","sourceRoot":"","sources":["../src/DeepgramDiarizationAdapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH;;;;;;GAMG;AACH,MAAM,WAAW,YAAY;IAC3B,6BAA6B;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,0DAA0D;IAC1D,KAAK,EAAE,MAAM,CAAC;IACd,wDAAwD;IACxD,GAAG,EAAE,MAAM,CAAC;IACZ,wCAAwC;IACxC,UAAU,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gEAAgE;IAChE,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,YAAY,EAAE,GAAG,MAAM,GAAG,SAAS,CAyBjF;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,EAAE,EAAE,YAAY,GAAG;IACjD,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAQA"}
@@ -0,0 +1,78 @@
1
+ /**
2
+ * @file DeepgramDiarizationAdapter.ts
3
+ * @description Utilities for extracting speaker labels from Deepgram word-level
4
+ * diarization results.
5
+ *
6
+ * Deepgram's `diarize: true` option annotates each word in the transcript with
7
+ * a zero-indexed integer `speaker` field. This module converts that raw
8
+ * numeric label into the string format expected by {@link TranscriptWord.speaker}
9
+ * (`'Speaker_0'`, `'Speaker_1'`, …) and determines the majority speaker for
10
+ * an utterance.
11
+ *
12
+ * @module streaming-stt-deepgram/DeepgramDiarizationAdapter
13
+ */
14
+ /**
15
+ * Extract the majority speaker label from an array of Deepgram word objects.
16
+ *
17
+ * The function tallies votes by `speaker` index and returns the label for the
18
+ * speaker with the most words. Ties are broken by lowest index (i.e. the
19
+ * earliest-assigned speaker wins).
20
+ *
21
+ * Returns `undefined` when the array is empty or no word carries a `speaker`
22
+ * field (i.e. diarization was not requested for this session).
23
+ *
24
+ * @param words - Raw Deepgram word objects from `channel.alternatives[0].words`.
25
+ * @returns A string label such as `'Speaker_0'`, or `undefined`.
26
+ *
27
+ * @example
28
+ * ```ts
29
+ * const words = [
30
+ * { word: 'Hello', speaker: 0, start: 0, end: 0.3, confidence: 0.99 },
31
+ * { word: 'world', speaker: 1, start: 0.4, end: 0.7, confidence: 0.97 },
32
+ * { word: 'today', speaker: 0, start: 0.8, end: 1.1, confidence: 0.95 },
33
+ * ];
34
+ * extractSpeakerFromWords(words); // → 'Speaker_0'
35
+ * ```
36
+ */
37
+ export function extractSpeakerFromWords(words) {
38
+ if (words.length === 0)
39
+ return undefined;
40
+ /** Vote counts keyed by speaker index. */
41
+ const votes = new Map();
42
+ for (const w of words) {
43
+ if (w.speaker === undefined)
44
+ continue;
45
+ votes.set(w.speaker, (votes.get(w.speaker) ?? 0) + 1);
46
+ }
47
+ if (votes.size === 0)
48
+ return undefined;
49
+ // Find the speaker index with the highest vote count; ties broken by lowest index.
50
+ let majorityIndex = -1;
51
+ let majorityCount = -1;
52
+ for (const [index, count] of votes) {
53
+ if (count > majorityCount || (count === majorityCount && index < majorityIndex)) {
54
+ majorityCount = count;
55
+ majorityIndex = index;
56
+ }
57
+ }
58
+ return majorityIndex >= 0 ? `Speaker_${majorityIndex}` : undefined;
59
+ }
60
+ /**
61
+ * Map a Deepgram word object to the canonical `TranscriptWord`-compatible shape.
62
+ *
63
+ * Seconds are converted to milliseconds to match the voice pipeline convention.
64
+ * The `word` field prefers the punctuated variant when available.
65
+ *
66
+ * @param dw - Raw Deepgram word object.
67
+ * @returns A plain object matching the {@link TranscriptWord} interface.
68
+ */
69
+ export function mapDeepgramWord(dw) {
70
+ return {
71
+ word: dw.punctuated_word ?? dw.word,
72
+ start: Math.round(dw.start * 1000),
73
+ end: Math.round(dw.end * 1000),
74
+ confidence: dw.confidence,
75
+ speaker: dw.speaker !== undefined ? `Speaker_${dw.speaker}` : undefined,
76
+ };
77
+ }
78
+ //# sourceMappingURL=DeepgramDiarizationAdapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DeepgramDiarizationAdapter.js","sourceRoot":"","sources":["../src/DeepgramDiarizationAdapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AA2BH;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,UAAU,uBAAuB,CAAC,KAAqB;IAC3D,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IAEzC,0CAA0C;IAC1C,MAAM,KAAK,GAAG,IAAI,GAAG,EAAkB,CAAC;IAExC,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,IAAI,CAAC,CAAC,OAAO,KAAK,SAAS;YAAE,SAAS;QACtC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACxD,CAAC;IAED,IAAI,KAAK,CAAC,IAAI,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IAEvC,mFAAmF;IACnF,IAAI,aAAa,GAAG,CAAC,CAAC,CAAC;IACvB,IAAI,aAAa,GAAG,CAAC,CAAC,CAAC;IAEvB,KAAK,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,KAAK,EAAE,CAAC;QACnC,IAAI,KAAK,GAAG,aAAa,IAAI,CAAC,KAAK,KAAK,aAAa,IAAI,KAAK,GAAG,aAAa,CAAC,EAAE,CAAC;YAChF,aAAa,GAAG,KAAK,CAAC;YACtB,aAAa,GAAG,KAAK,CAAC;QACxB,CAAC;IACH,CAAC;IAED,OAAO,aAAa,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,aAAa,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AACrE,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,eAAe,CAAC,EAAgB;IAO9C,OAAO;QACL,IAAI,EAAE,EAAE,CAAC,eAAe,IAAI,EAAE,CAAC,IAAI;QACnC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,GAAG,IAAI,CAAC;QAClC,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,GAAG,IAAI,CAAC;QAC9B,UAAU,EAAE,EAAE,CAAC,UAAU;QACzB,OAAO,EAAE,EAAE,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,SAAS;KACxE,CAAC;AACJ,CAAC"}
@@ -0,0 +1,150 @@
1
+ /**
2
+ * @file DeepgramStreamSession.ts
3
+ * @description Active streaming STT session backed by the Deepgram WebSocket API.
4
+ *
5
+ * {@link DeepgramStreamSession} implements the {@link StreamingSTTSession} interface
6
+ * (which extends `EventEmitter`) and adds Deepgram-specific convenience events:
7
+ *
8
+ * | Event | Payload | Description |
9
+ * |-----------------------|----------------------|-------------------------------------------------------|
10
+ * | `'transcript'` | `TranscriptEvent` | Every hypothesis (interim + final, per base interface)|
11
+ * | `'interim_transcript'`| `TranscriptEvent` | Non-final hypothesis only |
12
+ * | `'final_transcript'` | `TranscriptEvent` | Final (stable) hypothesis |
13
+ * | `'speech_start'` | — | First non-empty word received in this utterance |
14
+ * | `'speech_end'` | — | Deepgram `speech_final` flag fired |
15
+ * | `'error'` | `Error` | Unrecoverable provider error |
16
+ * | `'close'` | — | Session fully terminated |
17
+ *
18
+ * ### Auto-reconnect
19
+ * On an unexpected WebSocket close (code ≠ 1000/1001), the session buffers
20
+ * incoming audio frames (up to 5 s worth at 16 kHz / 512 samples per frame)
21
+ * and reattempts the connection with exponential back-off starting at 100 ms,
22
+ * doubling each attempt up to a cap of 5 000 ms.
23
+ *
24
+ * @module streaming-stt-deepgram/DeepgramStreamSession
25
+ */
26
+ import { EventEmitter } from 'node:events';
27
+ import type { DeepgramStreamingConfig } from './types.js';
28
+ /** Minimal AudioFrame shape — mirrors packages/agentos/src/voice-pipeline/types.ts */
29
+ export interface AudioFrame {
30
+ samples: Float32Array;
31
+ sampleRate: number;
32
+ timestamp: number;
33
+ speakerHint?: string;
34
+ }
35
+ /** Minimal TranscriptWord shape. */
36
+ export interface TranscriptWord {
37
+ word: string;
38
+ start: number;
39
+ end: number;
40
+ confidence: number;
41
+ speaker?: string;
42
+ }
43
+ /** Minimal TranscriptEvent shape. */
44
+ export interface TranscriptEvent {
45
+ text: string;
46
+ confidence: number;
47
+ words: TranscriptWord[];
48
+ isFinal: boolean;
49
+ durationMs?: number;
50
+ }
51
+ /**
52
+ * Active streaming STT session backed by a Deepgram WebSocket connection.
53
+ *
54
+ * Construct via {@link DeepgramStreamingSTT.startSession} rather than directly.
55
+ *
56
+ * @example
57
+ * ```ts
58
+ * const session = new DeepgramStreamSession({ apiKey: process.env.DEEPGRAM_API_KEY! });
59
+ *
60
+ * session.on('interim_transcript', (evt) => process.stdout.write(`\r${evt.text}`));
61
+ * session.on('final_transcript', (evt) => console.log(`FINAL: ${evt.text}`));
62
+ * session.on('speech_end', () => console.log('utterance ended'));
63
+ *
64
+ * // Push audio frames from a microphone source:
65
+ * microphone.on('frame', (frame) => session.pushAudio(frame));
66
+ *
67
+ * // Signal end of utterance:
68
+ * await session.flush();
69
+ * session.close();
70
+ * ```
71
+ */
72
+ export declare class DeepgramStreamSession extends EventEmitter {
73
+ /** Resolved configuration with all defaults applied. */
74
+ private readonly cfg;
75
+ /** Current WebSocket connection (replaced on reconnect). */
76
+ private ws;
77
+ /** `true` once the first non-empty transcript arrives in this utterance. */
78
+ private speechStarted;
79
+ /** `true` after {@link close} is called — prevents reconnect attempts. */
80
+ private closed;
81
+ /**
82
+ * Ring buffer of audio frames accumulated while the WebSocket is
83
+ * reconnecting. Capped at {@link MAX_BUFFER_FRAMES} to bound memory.
84
+ */
85
+ private reconnectBuffer;
86
+ /** Current reconnect back-off delay in milliseconds. */
87
+ private backoffMs;
88
+ /** Active reconnect timer handle. */
89
+ private reconnectTimer;
90
+ /** `true` while the WebSocket is open and ready to accept binary data. */
91
+ private wsReady;
92
+ /**
93
+ * @param config - Deepgram streaming configuration. `apiKey` is required;
94
+ * all other fields have sensible defaults.
95
+ */
96
+ constructor(config: DeepgramStreamingConfig);
97
+ /**
98
+ * Push a raw PCM audio frame into the recognition stream.
99
+ *
100
+ * Converts Float32 samples to Int16 linear PCM and transmits them as binary
101
+ * over the WebSocket. Frames received while the socket is reconnecting are
102
+ * queued in {@link reconnectBuffer} (up to {@link MAX_BUFFER_FRAMES}).
103
+ *
104
+ * @param frame - Audio frame with normalised Float32 samples at any sample rate.
105
+ * Frames are sent as-is; resample to 16 kHz before calling if
106
+ * the source differs from the Deepgram session's `sample_rate`.
107
+ */
108
+ pushAudio(frame: AudioFrame): void;
109
+ /**
110
+ * Signal end-of-utterance to Deepgram.
111
+ *
112
+ * Sends the JSON `{"type":"CloseStream"}` control message, instructing
113
+ * Deepgram to flush any buffered audio and emit a final transcript before
114
+ * closing the connection from their side.
115
+ *
116
+ * @returns A promise that resolves immediately after the message is enqueued.
117
+ */
118
+ flush(): Promise<void>;
119
+ /**
120
+ * Immediately terminate the session without waiting for a final result.
121
+ *
122
+ * Cancels any pending reconnect timer, marks the session as closed, and
123
+ * terminates the underlying WebSocket. After `close()` no further events
124
+ * are emitted.
125
+ */
126
+ close(): void;
127
+ /**
128
+ * Open (or reopen) the Deepgram WebSocket connection.
129
+ *
130
+ * Attaches `open`, `message`, `error`, and `close` handlers. On successful
131
+ * open the reconnect buffer is drained in order.
132
+ */
133
+ private connect;
134
+ /**
135
+ * Schedule a reconnect attempt after the current {@link backoffMs} delay,
136
+ * then double the delay for the next attempt (capped at {@link BACKOFF_MAX_MS}).
137
+ */
138
+ private scheduleReconnect;
139
+ /**
140
+ * Process a parsed Deepgram WebSocket message and emit the appropriate events.
141
+ *
142
+ * Deepgram sends two primary result types:
143
+ * - `Results` — transcript hypotheses with `is_final` and `speech_final` flags.
144
+ * - `Metadata` — session-level metadata (ignored here).
145
+ *
146
+ * @param msg - Parsed Deepgram JSON message.
147
+ */
148
+ private handleMessage;
149
+ }
150
+ //# sourceMappingURL=DeepgramStreamSession.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DeepgramStreamSession.d.ts","sourceRoot":"","sources":["../src/DeepgramStreamSession.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAQ1D,sFAAsF;AACtF,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,YAAY,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,oCAAoC;AACpC,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,qCAAqC;AACrC,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AA6ED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,qBAAa,qBAAsB,SAAQ,YAAY;IAKrD,wDAAwD;IACxD,OAAO,CAAC,QAAQ,CAAC,GAAG,CAMlB;IAEF,4DAA4D;IAC5D,OAAO,CAAC,EAAE,CAA0B;IAEpC,4EAA4E;IAC5E,OAAO,CAAC,aAAa,CAAS;IAE9B,0EAA0E;IAC1E,OAAO,CAAC,MAAM,CAAS;IAEvB;;;OAGG;IACH,OAAO,CAAC,eAAe,CAAoB;IAE3C,wDAAwD;IACxD,OAAO,CAAC,SAAS,CAAsB;IAEvC,qCAAqC;IACrC,OAAO,CAAC,cAAc,CAA8C;IAEpE,0EAA0E;IAC1E,OAAO,CAAC,OAAO,CAAS;IAMxB;;;OAGG;gBACS,MAAM,EAAE,uBAAuB;IAoB3C;;;;;;;;;;OAUG;IACH,SAAS,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAgBlC;;;;;;;;OAQG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAM5B;;;;;;OAMG;IACH,KAAK,IAAI,IAAI;IAqBb;;;;;OAKG;IACH,OAAO,CAAC,OAAO;IA0Df;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IAgBzB;;;;;;;;OAQG;IACH,OAAO,CAAC,aAAa;CAuDtB"}