@framers/agentos-ext-streaming-tts-elevenlabs 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,65 @@
1
+ ---
2
+ name: streaming-tts-elevenlabs
3
+ description: Streaming text-to-speech via ElevenLabs WebSocket API with real-time audio generation
4
+ category: voice
5
+ ---
6
+
7
+ # ElevenLabs Streaming TTS
8
+
9
+ Low-latency streaming text-to-speech using the ElevenLabs WebSocket Streaming API. Maintains a
10
+ persistent WebSocket connection per session and streams audio chunks as MP3 data as soon as each
11
+ sentence boundary is reached, enabling near-instant audio playback.
12
+
13
+ ## Setup
14
+
15
+ Set `ELEVENLABS_API_KEY` in your environment or agent secrets store.
16
+
17
+ ## Features
18
+
19
+ - Persistent WebSocket connection per session (no per-request HTTP overhead)
20
+ - Real-time audio streaming: ElevenLabs generates and sends audio as tokens arrive
21
+ - Automatic sentence-boundary flushing (`.`, `?`, `!`) for low-latency output
22
+ - Configurable voice via ElevenLabs voice ID
23
+ - Configurable model (eleven_turbo_v2 for low latency, eleven_multilingual_v2 for quality)
24
+ - Voice settings: stability, similarity boost, style, speaker boost
25
+ - MP3 output at 44.1 kHz / 128 kbps
26
+
27
+ ## Configuration
28
+
29
+ In `agent.config.json`:
30
+
31
+ ```json
32
+ {
33
+ "voice": {
34
+ "tts": "elevenlabs"
35
+ }
36
+ }
37
+ ```
38
+
39
+ Provider-specific options via `providerOptions`:
40
+
41
+ ```json
42
+ {
43
+ "voice": {
44
+ "tts": "elevenlabs",
45
+ "providerOptions": {
46
+ "voiceId": "21m00Tcm4TlvDq8ikWAM",
47
+ "modelId": "eleven_turbo_v2",
48
+ "stability": 0.5,
49
+ "similarityBoost": 0.75,
50
+ "style": 0.0,
51
+ "useSpeakerBoost": true
52
+ }
53
+ }
54
+ }
55
+ ```
56
+
57
+ ## Events
58
+
59
+ | Event | Payload | Description |
60
+ |----------------------|-------------------------|----------------------------------------------------|
61
+ | `audio_chunk` | `EncodedAudioChunk` | MP3 audio buffer ready for playback |
62
+ | `utterance_complete` | `{ text, durationMs }` | ElevenLabs signalled final audio generation done |
63
+ | `cancelled` | `{ remaining: string }` | Session was cancelled; remaining text not rendered |
64
+ | `error` | `Error` | WebSocket or synthesis error |
65
+ | `close` | — | Session fully terminated |
@@ -0,0 +1,64 @@
1
+ /**
2
+ * @file ElevenLabsStreamingTTS.ts
3
+ * @description {@link IStreamingTTS}-compatible factory for ElevenLabs TTS sessions.
4
+ *
5
+ * {@link ElevenLabsStreamingTTS} is a thin factory that creates
6
+ * {@link ElevenLabsTTSSession} instances on demand. It holds no mutable state
7
+ * other than an active-session reference count used to implement {@link isStreaming}.
8
+ *
9
+ * @module streaming-tts-elevenlabs/ElevenLabsStreamingTTS
10
+ */
11
+ import { ElevenLabsTTSSession } from './ElevenLabsTTSSession.js';
12
+ import type { ElevenLabsStreamingTTSConfig, StreamingTTSConfig } from './types.js';
13
+ /**
14
+ * Factory for ElevenLabs-backed streaming TTS sessions.
15
+ *
16
+ * Instantiate once per agent and reuse across voice turns. Each call to
17
+ * {@link startSession} creates an independent {@link ElevenLabsTTSSession} that
18
+ * owns its own WebSocket connection lifecycle.
19
+ *
20
+ * @example
21
+ * ```ts
22
+ * const tts = new ElevenLabsStreamingTTS({ apiKey: process.env.ELEVENLABS_API_KEY! });
23
+ * const session = await tts.startSession();
24
+ *
25
+ * session.on('audio_chunk', (chunk) => audioPlayer.enqueue(chunk.audio));
26
+ *
27
+ * llm.on('token', (tok) => session.pushTokens(tok));
28
+ * llm.on('end', () => session.flush());
29
+ * ```
30
+ */
31
+ export declare class ElevenLabsStreamingTTS {
32
+ private readonly config;
33
+ /**
34
+ * Stable provider identifier used by the voice pipeline to select between
35
+ * registered TTS implementations.
36
+ */
37
+ readonly providerId = "elevenlabs-streaming-tts";
38
+ /** `true` while at least one session is open and not yet closed. */
39
+ get isStreaming(): boolean;
40
+ /** Count of sessions opened but not yet closed or cancelled. */
41
+ private _activeSessions;
42
+ /**
43
+ * @param config - ElevenLabs provider configuration. `apiKey` is required;
44
+ * all other fields have sensible defaults.
45
+ */
46
+ constructor(config: ElevenLabsStreamingTTSConfig);
47
+ /**
48
+ * Open a new streaming TTS session backed by a fresh WebSocket connection.
49
+ *
50
+ * Provider-specific options can be forwarded via `config.providerOptions`
51
+ * under the following keys:
52
+ * - `voiceId` — ElevenLabs voice ID (default Rachel).
53
+ * - `modelId` — Model ID (default `'eleven_turbo_v2'`).
54
+ * - `stability` — Voice stability 0.0–1.0 (default `0.5`).
55
+ * - `similarityBoost`— Similarity boost 0.0–1.0 (default `0.75`).
56
+ * - `style` — Style exaggeration 0.0–1.0 (default `0.0`).
57
+ * - `useSpeakerBoost`— Speaker boost enabled (default `true`).
58
+ *
59
+ * @param config - Generic session config merged with provider defaults.
60
+ * @returns A ready-to-use {@link ElevenLabsTTSSession}.
61
+ */
62
+ startSession(config?: StreamingTTSConfig): Promise<ElevenLabsTTSSession>;
63
+ }
64
+ //# sourceMappingURL=ElevenLabsStreamingTTS.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ElevenLabsStreamingTTS.d.ts","sourceRoot":"","sources":["../src/ElevenLabsStreamingTTS.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,KAAK,EAAE,4BAA4B,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAMnF;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,sBAAsB;IAmBrB,OAAO,CAAC,QAAQ,CAAC,MAAM;IAlBnC;;;OAGG;IACH,QAAQ,CAAC,UAAU,8BAA8B;IAEjD,oEAAoE;IACpE,IAAI,WAAW,IAAI,OAAO,CAEzB;IAED,gEAAgE;IAChE,OAAO,CAAC,eAAe,CAAK;IAE5B;;;OAGG;gBAC0B,MAAM,EAAE,4BAA4B;IAEjE;;;;;;;;;;;;;;OAcG;IACG,YAAY,CAAC,MAAM,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,oBAAoB,CAAC;CA2B/E"}
@@ -0,0 +1,91 @@
1
+ /**
2
+ * @file ElevenLabsStreamingTTS.ts
3
+ * @description {@link IStreamingTTS}-compatible factory for ElevenLabs TTS sessions.
4
+ *
5
+ * {@link ElevenLabsStreamingTTS} is a thin factory that creates
6
+ * {@link ElevenLabsTTSSession} instances on demand. It holds no mutable state
7
+ * other than an active-session reference count used to implement {@link isStreaming}.
8
+ *
9
+ * @module streaming-tts-elevenlabs/ElevenLabsStreamingTTS
10
+ */
11
+ import { ElevenLabsTTSSession } from './ElevenLabsTTSSession.js';
12
+ // ---------------------------------------------------------------------------
13
+ // Main class
14
+ // ---------------------------------------------------------------------------
15
+ /**
16
+ * Factory for ElevenLabs-backed streaming TTS sessions.
17
+ *
18
+ * Instantiate once per agent and reuse across voice turns. Each call to
19
+ * {@link startSession} creates an independent {@link ElevenLabsTTSSession} that
20
+ * owns its own WebSocket connection lifecycle.
21
+ *
22
+ * @example
23
+ * ```ts
24
+ * const tts = new ElevenLabsStreamingTTS({ apiKey: process.env.ELEVENLABS_API_KEY! });
25
+ * const session = await tts.startSession();
26
+ *
27
+ * session.on('audio_chunk', (chunk) => audioPlayer.enqueue(chunk.audio));
28
+ *
29
+ * llm.on('token', (tok) => session.pushTokens(tok));
30
+ * llm.on('end', () => session.flush());
31
+ * ```
32
+ */
33
+ export class ElevenLabsStreamingTTS {
34
+ config;
35
+ /**
36
+ * Stable provider identifier used by the voice pipeline to select between
37
+ * registered TTS implementations.
38
+ */
39
+ providerId = 'elevenlabs-streaming-tts';
40
+ /** `true` while at least one session is open and not yet closed. */
41
+ get isStreaming() {
42
+ return this._activeSessions > 0;
43
+ }
44
+ /** Count of sessions opened but not yet closed or cancelled. */
45
+ _activeSessions = 0;
46
+ /**
47
+ * @param config - ElevenLabs provider configuration. `apiKey` is required;
48
+ * all other fields have sensible defaults.
49
+ */
50
+ constructor(config) {
51
+ this.config = config;
52
+ }
53
+ /**
54
+ * Open a new streaming TTS session backed by a fresh WebSocket connection.
55
+ *
56
+ * Provider-specific options can be forwarded via `config.providerOptions`
57
+ * under the following keys:
58
+ * - `voiceId` — ElevenLabs voice ID (default Rachel).
59
+ * - `modelId` — Model ID (default `'eleven_turbo_v2'`).
60
+ * - `stability` — Voice stability 0.0–1.0 (default `0.5`).
61
+ * - `similarityBoost`— Similarity boost 0.0–1.0 (default `0.75`).
62
+ * - `style` — Style exaggeration 0.0–1.0 (default `0.0`).
63
+ * - `useSpeakerBoost`— Speaker boost enabled (default `true`).
64
+ *
65
+ * @param config - Generic session config merged with provider defaults.
66
+ * @returns A ready-to-use {@link ElevenLabsTTSSession}.
67
+ */
68
+ async startSession(config) {
69
+ const provOpts = (config?.providerOptions ?? {});
70
+ // Session-level overrides take precedence over factory-level config.
71
+ const sessionProviderConfig = {
72
+ ...this.config,
73
+ voiceId: provOpts.voiceId ?? this.config.voiceId,
74
+ modelId: provOpts.modelId ?? this.config.modelId,
75
+ stability: provOpts.stability ?? this.config.stability,
76
+ similarityBoost: provOpts.similarityBoost ?? this.config.similarityBoost,
77
+ style: provOpts.style ?? this.config.style,
78
+ useSpeakerBoost: provOpts.useSpeakerBoost ?? this.config.useSpeakerBoost,
79
+ };
80
+ const session = new ElevenLabsTTSSession(sessionProviderConfig, config ?? {});
81
+ this._activeSessions++;
82
+ // Decrement the counter when the session terminates for any reason.
83
+ const onDone = () => {
84
+ this._activeSessions = Math.max(0, this._activeSessions - 1);
85
+ };
86
+ session.once('close', onDone);
87
+ session.once('cancelled', onDone);
88
+ return session;
89
+ }
90
+ }
91
+ //# sourceMappingURL=ElevenLabsStreamingTTS.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ElevenLabsStreamingTTS.js","sourceRoot":"","sources":["../src/ElevenLabsStreamingTTS.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAGjE,8EAA8E;AAC9E,aAAa;AACb,8EAA8E;AAE9E;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,OAAO,sBAAsB;IAmBJ;IAlB7B;;;OAGG;IACM,UAAU,GAAG,0BAA0B,CAAC;IAEjD,oEAAoE;IACpE,IAAI,WAAW;QACb,OAAO,IAAI,CAAC,eAAe,GAAG,CAAC,CAAC;IAClC,CAAC;IAED,gEAAgE;IACxD,eAAe,GAAG,CAAC,CAAC;IAE5B;;;OAGG;IACH,YAA6B,MAAoC;QAApC,WAAM,GAAN,MAAM,CAA8B;IAAG,CAAC;IAErE;;;;;;;;;;;;;;OAcG;IACH,KAAK,CAAC,YAAY,CAAC,MAA2B;QAC5C,MAAM,QAAQ,GAAG,CAAC,MAAM,EAAE,eAAe,IAAI,EAAE,CAA0C,CAAC;QAE1F,qEAAqE;QACrE,MAAM,qBAAqB,GAAiC;YAC1D,GAAG,IAAI,CAAC,MAAM;YACd,OAAO,EAAS,QAAQ,CAAC,OAAO,IAAY,IAAI,CAAC,MAAM,CAAC,OAAO;YAC/D,OAAO,EAAS,QAAQ,CAAC,OAAO,IAAY,IAAI,CAAC,MAAM,CAAC,OAAO;YAC/D,SAAS,EAAO,QAAQ,CAAC,SAAS,IAAU,IAAI,CAAC,MAAM,CAAC,SAAS;YACjE,eAAe,EAAC,QAAQ,CAAC,eAAe,IAAI,IAAI,CAAC,MAAM,CAAC,eAAe;YACvE,KAAK,EAAW,QAAQ,CAAC,KAAK,IAAc,IAAI,CAAC,MAAM,CAAC,KAAK;YAC7D,eAAe,EAAC,QAAQ,CAAC,eAAe,IAAI,IAAI,CAAC,MAAM,CAAC,eAAe;SACxE,CAAC;QAEF,MAAM,OAAO,GAAG,IAAI,oBAAoB,CAAC,qBAAqB,EAAE,MAAM,IAAI,EAAE,CAAC,CAAC;QAE9E,IAAI,CAAC,eAAe,EAAE,CAAC;QAEvB,oEAAoE;QACpE,MAAM,MAAM,GAAG,GAAS,EAAE;YACxB,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,eAAe,GAAG,CAAC,CAAC,CAAC;QAC/D,CAAC,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,OAAO,EAAM,MAAM,CAAC,CAAC;QAClC,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;QAElC,OAAO,OAAO,CAAC;IACjB,CAAC;CACF"}
@@ -0,0 +1,147 @@
1
+ /**
2
+ * @file ElevenLabsTTSSession.ts
3
+ * @description Active TTS session backed by the ElevenLabs WebSocket Streaming API.
4
+ *
5
+ * {@link ElevenLabsTTSSession} implements the `StreamingTTSSession` interface
6
+ * (EventEmitter) and provides the following events:
7
+ *
8
+ * | Event | Payload | Description |
9
+ * |----------------------|----------------------------|------------------------------------------------------|
10
+ * | `'audio_chunk'` | `EncodedAudioChunk` | MP3 audio buffer from ElevenLabs, ready for playback |
11
+ * | `'utterance_complete'`| `{ text, durationMs }` | ElevenLabs signalled end of audio generation |
12
+ * | `'cancelled'` | `{ remaining: string }` | Session cancelled; remaining text not rendered |
13
+ * | `'error'` | `Error` | WebSocket or protocol error |
14
+ * | `'close'` | — | Session fully terminated |
15
+ *
16
+ * ### Protocol Overview
17
+ *
18
+ * The ElevenLabs WebSocket streaming protocol works as follows:
19
+ *
20
+ * 1. Open WSS connection to the voice/model endpoint.
21
+ * 2. Send a BOS (Beginning-Of-Stream) message: `{ text: " ", voice_settings: {...}, xi_api_key }`.
22
+ * 3. Stream text tokens as `{ text: "..." }` JSON messages.
23
+ * 4. To generate audio for accumulated text, include `flush: true` in the text message.
24
+ * 5. To end the stream, send an EOS (End-Of-Stream) message: `{ text: "" }`.
25
+ * 6. The server returns binary messages (MP3 audio chunks) and JSON status messages.
26
+ * 7. When all audio has been generated the server sends `{ isFinal: true }`.
27
+ *
28
+ * @module streaming-tts-elevenlabs/ElevenLabsTTSSession
29
+ */
30
+ import { EventEmitter } from 'node:events';
31
+ import type { ElevenLabsStreamingTTSConfig, StreamingTTSConfig } from './types.js';
32
+ /**
33
+ * Active streaming TTS session backed by the ElevenLabs WebSocket Streaming API.
34
+ *
35
+ * Construct via {@link ElevenLabsStreamingTTS.startSession} rather than directly.
36
+ *
37
+ * @example
38
+ * ```ts
39
+ * const session = new ElevenLabsTTSSession(
40
+ * { apiKey: process.env.ELEVENLABS_API_KEY! },
41
+ * {},
42
+ * );
43
+ *
44
+ * session.on('audio_chunk', (chunk) => audioPlayer.enqueue(chunk.audio));
45
+ * session.on('utterance_complete', ({ text, durationMs }) => {
46
+ * console.log(`Synthesis complete ~${durationMs} ms`);
47
+ * });
48
+ *
49
+ * llm.on('token', (tok) => session.pushTokens(tok));
50
+ * llm.on('end', () => session.flush());
51
+ * ```
52
+ */
53
+ export declare class ElevenLabsTTSSession extends EventEmitter {
54
+ private readonly providerConfig;
55
+ /** ElevenLabs voice ID. */
56
+ private readonly voiceId;
57
+ /** ElevenLabs model ID. */
58
+ private readonly modelId;
59
+ /** Voice stability (0.0 – 1.0). */
60
+ private readonly stability;
61
+ /** Similarity boost (0.0 – 1.0). */
62
+ private readonly similarityBoost;
63
+ /** Style exaggeration (0.0 – 1.0). */
64
+ private readonly style;
65
+ /** Whether to enable speaker boost. */
66
+ private readonly useSpeakerBoost;
67
+ /** Live WebSocket connection to the ElevenLabs streaming endpoint. */
68
+ private readonly ws;
69
+ /**
70
+ * Text that has been pushed since the last sentence-boundary flush.
71
+ *
72
+ * Accumulated so that `cancel()` can report the remaining un-synthesised text.
73
+ */
74
+ private pendingText;
75
+ /** `true` after {@link close} or {@link cancel} is called. */
76
+ private closed;
77
+ /**
78
+ * Whether the BOS (beginning-of-stream) message has been sent.
79
+ *
80
+ * The BOS is sent once on `ws.open`; subsequent messages are plain text sends.
81
+ */
82
+ private bosAcknowledged;
83
+ /**
84
+ * Queue of text segments that need to be sent once the WebSocket opens.
85
+ *
86
+ * If `pushTokens` or `flush` is called before the socket is open, messages
87
+ * are queued here and drained on `ws.open`.
88
+ */
89
+ private readonly sendQueue;
90
+ /**
91
+ * @param providerConfig - ElevenLabs-specific configuration (apiKey required).
92
+ * @param _sessionConfig - Generic voice-pipeline session config (reserved for
93
+ * future `language` forwarding).
94
+ */
95
+ constructor(providerConfig: ElevenLabsStreamingTTSConfig, _sessionConfig: StreamingTTSConfig);
96
+ /**
97
+ * Push LLM output token(s) into the stream.
98
+ *
99
+ * Text is accumulated in an internal buffer. When a sentence boundary
100
+ * (`.`, `?`, `!`) is detected the accumulated segment is sent to ElevenLabs
101
+ * with `flush: true` so the server generates audio immediately. Mid-sentence
102
+ * tokens are sent with a trailing space continuation to avoid falling intonation
103
+ * on partial phrases.
104
+ *
105
+ * @param text - One or more LLM token characters to append.
106
+ */
107
+ pushTokens(text: string): void;
108
+ /**
109
+ * Flush any remaining buffered text and signal EOS to ElevenLabs.
110
+ *
111
+ * Call this when the LLM stream has ended. Sends an EOS (end-of-stream)
112
+ * message (`{ text: "" }`) which instructs ElevenLabs to finalise audio
113
+ * generation for all remaining buffered text and close the stream.
114
+ *
115
+ * @returns Promise that resolves when the EOS message is queued for sending.
116
+ */
117
+ flush(): Promise<void>;
118
+ /**
119
+ * Cancel the session immediately.
120
+ *
121
+ * Closes the WebSocket, discards any unsent text, and emits a `'cancelled'`
122
+ * event carrying the remaining un-synthesised text.
123
+ */
124
+ cancel(): void;
125
+ /**
126
+ * Close the session cleanly.
127
+ *
128
+ * Sends a WebSocket close frame and emits a `'close'` event.
129
+ * Idempotent — safe to call multiple times.
130
+ */
131
+ close(): void;
132
+ /**
133
+ * Attach event listeners to the WebSocket instance and handle the full
134
+ * message lifecycle.
135
+ */
136
+ private _wireWebSocket;
137
+ /**
138
+ * Send a JSON message over the WebSocket.
139
+ *
140
+ * If the socket is not yet open, the message is queued and will be sent once
141
+ * the `open` event fires (after the BOS message is dispatched).
142
+ *
143
+ * @param msg - The message object to serialise and send.
144
+ */
145
+ private _send;
146
+ }
147
+ //# sourceMappingURL=ElevenLabsTTSSession.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ElevenLabsTTSSession.d.ts","sourceRoot":"","sources":["../src/ElevenLabsTTSSession.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,KAAK,EAAE,4BAA4B,EAAE,kBAAkB,EAAqB,MAAM,YAAY,CAAC;AAoDtG;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,qBAAa,oBAAqB,SAAQ,YAAY;IAiElD,OAAO,CAAC,QAAQ,CAAC,cAAc;IA5DjC,2BAA2B;IAC3B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IAEjC,2BAA2B;IAC3B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IAEjC,mCAAmC;IACnC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IAEnC,oCAAoC;IACpC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IAEzC,sCAAsC;IACtC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAE/B,uCAAuC;IACvC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAU;IAM1C,sEAAsE;IACtE,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAY;IAE/B;;;;OAIG;IACH,OAAO,CAAC,WAAW,CAAM;IAEzB,8DAA8D;IAC9D,OAAO,CAAC,MAAM,CAAS;IAEvB;;;;OAIG;IACH,OAAO,CAAC,eAAe,CAAS;IAEhC;;;;;OAKG;IACH,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAqB;IAM/C;;;;OAIG;gBAEgB,cAAc,EAAE,4BAA4B,EAC7D,cAAc,EAAE,kBAAkB;IA0BpC;;;;;;;;;;OAUG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAoB9B;;;;;;;;OAQG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAc5B;;;;;OAKG;IACH,MAAM,IAAI,IAAI;IAWd;;;;;OAKG;IACH,KAAK,IAAI,IAAI;IAYb;;;OAGG;IACH,OAAO,CAAC,cAAc;IA8EtB;;;;;;;OAOG;IACH,OAAO,CAAC,KAAK;CAQd"}