@speech-sdk/core 0.6.1 → 0.7.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 +202 -21
- package/README.md +215 -269
- package/dist/__tests__/e2e/_save-audio.d.ts +51 -2
- package/dist/__tests__/e2e/_save-audio.d.ts.map +1 -1
- package/dist/__tests__/e2e/_save-audio.js +139 -11
- package/dist/__tests__/e2e/_save-audio.js.map +1 -1
- package/dist/audio-utils.d.ts +2 -0
- package/dist/audio-utils.d.ts.map +1 -1
- package/dist/audio-utils.js +9 -0
- package/dist/audio-utils.js.map +1 -1
- package/dist/captions.d.ts +137 -0
- package/dist/captions.d.ts.map +1 -0
- package/dist/captions.js +283 -0
- package/dist/captions.js.map +1 -0
- package/dist/conversation/stitch.d.ts +5 -0
- package/dist/conversation/stitch.d.ts.map +1 -1
- package/dist/conversation/stitch.js +37 -0
- package/dist/conversation/stitch.js.map +1 -1
- package/dist/conversation/types.d.ts +16 -0
- package/dist/conversation/types.d.ts.map +1 -1
- package/dist/conversation/validate.d.ts.map +1 -1
- package/dist/conversation/validate.js +0 -6
- package/dist/conversation/validate.js.map +1 -1
- package/dist/derive-timestamps.d.ts +14 -0
- package/dist/derive-timestamps.d.ts.map +1 -0
- package/dist/derive-timestamps.js +38 -0
- package/dist/derive-timestamps.js.map +1 -0
- package/dist/errors.d.ts +25 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +28 -0
- package/dist/errors.js.map +1 -1
- package/dist/generate-conversation.d.ts +2 -1
- package/dist/generate-conversation.d.ts.map +1 -1
- package/dist/generate-conversation.js +72 -0
- package/dist/generate-conversation.js.map +1 -1
- package/dist/generate-speech.d.ts +18 -1
- package/dist/generate-speech.d.ts.map +1 -1
- package/dist/generate-speech.js +73 -16
- package/dist/generate-speech.js.map +1 -1
- package/dist/index.d.ts +6 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/logger.d.ts +2 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +40 -0
- package/dist/logger.js.map +1 -0
- package/dist/provider-utils.d.ts +8 -0
- package/dist/provider-utils.d.ts.map +1 -1
- package/dist/provider-utils.js +16 -2
- package/dist/provider-utils.js.map +1 -1
- package/dist/providers/cartesia/alignment.d.ts +24 -0
- package/dist/providers/cartesia/alignment.d.ts.map +1 -0
- package/dist/providers/cartesia/alignment.js +23 -0
- package/dist/providers/cartesia/alignment.js.map +1 -0
- package/dist/providers/cartesia/index.d.ts +12 -2
- package/dist/providers/cartesia/index.d.ts.map +1 -1
- package/dist/providers/cartesia/index.js +137 -2
- package/dist/providers/cartesia/index.js.map +1 -1
- package/dist/providers/elevenlabs/alignment.d.ts +24 -0
- package/dist/providers/elevenlabs/alignment.d.ts.map +1 -0
- package/dist/providers/elevenlabs/alignment.js +48 -0
- package/dist/providers/elevenlabs/alignment.js.map +1 -0
- package/dist/providers/elevenlabs/index.d.ts +19 -4
- package/dist/providers/elevenlabs/index.d.ts.map +1 -1
- package/dist/providers/elevenlabs/index.js +83 -13
- package/dist/providers/elevenlabs/index.js.map +1 -1
- package/dist/providers/fal/index.d.ts +0 -25
- package/dist/providers/fal/index.d.ts.map +1 -1
- package/dist/providers/fal/index.js +3 -58
- package/dist/providers/fal/index.js.map +1 -1
- package/dist/providers/hume/alignment.d.ts +38 -0
- package/dist/providers/hume/alignment.d.ts.map +1 -0
- package/dist/providers/hume/alignment.js +31 -0
- package/dist/providers/hume/alignment.js.map +1 -0
- package/dist/providers/hume/index.d.ts +8 -1
- package/dist/providers/hume/index.d.ts.map +1 -1
- package/dist/providers/hume/index.js +75 -1
- package/dist/providers/hume/index.js.map +1 -1
- package/dist/providers/inworld/alignment.d.ts +25 -0
- package/dist/providers/inworld/alignment.d.ts.map +1 -0
- package/dist/providers/inworld/alignment.js +23 -0
- package/dist/providers/inworld/alignment.js.map +1 -0
- package/dist/providers/inworld/index.d.ts +11 -2
- package/dist/providers/inworld/index.d.ts.map +1 -1
- package/dist/providers/inworld/index.js +11 -2
- package/dist/providers/inworld/index.js.map +1 -1
- package/dist/providers/murf/alignment.d.ts +22 -0
- package/dist/providers/murf/alignment.d.ts.map +1 -0
- package/dist/providers/murf/alignment.js +17 -0
- package/dist/providers/murf/alignment.js.map +1 -0
- package/dist/providers/murf/index.d.ts +8 -1
- package/dist/providers/murf/index.d.ts.map +1 -1
- package/dist/providers/murf/index.js +10 -1
- package/dist/providers/murf/index.js.map +1 -1
- package/dist/providers/openai/index.d.ts +12 -3
- package/dist/providers/openai/index.d.ts.map +1 -1
- package/dist/providers/openai/index.js +7 -3
- package/dist/providers/openai/index.js.map +1 -1
- package/dist/providers/resemble/alignment.d.ts +32 -0
- package/dist/providers/resemble/alignment.d.ts.map +1 -0
- package/dist/providers/resemble/alignment.js +57 -0
- package/dist/providers/resemble/alignment.js.map +1 -0
- package/dist/providers/resemble/index.d.ts +7 -1
- package/dist/providers/resemble/index.d.ts.map +1 -1
- package/dist/providers/resemble/index.js +13 -1
- package/dist/providers/resemble/index.js.map +1 -1
- package/dist/resolve-provider.d.ts.map +1 -1
- package/dist/resolve-provider.js +3 -12
- package/dist/resolve-provider.js.map +1 -1
- package/dist/speech-provider.d.ts +48 -4
- package/dist/speech-provider.d.ts.map +1 -1
- package/dist/speech-provider.js +16 -0
- package/dist/speech-provider.js.map +1 -1
- package/dist/speech-result.d.ts +10 -0
- package/dist/speech-result.d.ts.map +1 -1
- package/dist/speech-result.js.map +1 -1
- package/dist/speech-to-text-provider.d.ts +40 -0
- package/dist/speech-to-text-provider.d.ts.map +1 -0
- package/dist/speech-to-text-provider.js +2 -0
- package/dist/speech-to-text-provider.js.map +1 -0
- package/dist/stt-providers/openai/index.d.ts +42 -0
- package/dist/stt-providers/openai/index.d.ts.map +1 -0
- package/dist/stt-providers/openai/index.js +184 -0
- package/dist/stt-providers/openai/index.js.map +1 -0
- package/dist/timestamps.d.ts +23 -0
- package/dist/timestamps.d.ts.map +1 -0
- package/dist/timestamps.js +2 -0
- package/dist/timestamps.js.map +1 -0
- package/package.json +6 -2
|
@@ -1,11 +1,60 @@
|
|
|
1
|
+
import { generateConversation as _generateConversation } from "../../generate-conversation.js";
|
|
2
|
+
import { generateSpeech as _generateSpeech } from "../../generate-speech.js";
|
|
3
|
+
import type { WordTimestamp } from "../../timestamps.js";
|
|
1
4
|
/**
|
|
2
5
|
* Write a test-generated audio file to `SPEECH_SDK_E2E_OUTPUT_DIR` if the env
|
|
3
6
|
* var is set. No-op otherwise, so normal CI runs don't produce artifacts.
|
|
4
|
-
*
|
|
5
|
-
*
|
|
7
|
+
* Usually you don't need to call this directly — use the `generateSpeech`,
|
|
8
|
+
* `generateConversation`, and `collectStreamAndSave` helpers exported from
|
|
9
|
+
* this module, which autosave using the current test name.
|
|
10
|
+
*
|
|
11
|
+
* Output layout: `$SPEECH_SDK_E2E_OUTPUT_DIR/<provider-file>/<test-slug>.<ext>`.
|
|
12
|
+
* If the same test saves multiple times, subsequent files are suffixed `-2`,
|
|
13
|
+
* `-3`, etc.
|
|
6
14
|
*/
|
|
7
15
|
export declare function maybeSaveAudio(name: string, audio: {
|
|
8
16
|
uint8Array: Uint8Array;
|
|
9
17
|
mediaType: string;
|
|
10
18
|
}): Promise<void>;
|
|
19
|
+
/**
|
|
20
|
+
* Like {@link maybeSaveAudio}, plus — when `timestamps` is non-empty — also
|
|
21
|
+
* writes the raw alignment JSON and rendered SRT/VTT caption files alongside
|
|
22
|
+
* the audio. All four files share the same stem so they stay paired across
|
|
23
|
+
* multi-call tests. Still a no-op when `SPEECH_SDK_E2E_OUTPUT_DIR` is unset.
|
|
24
|
+
*
|
|
25
|
+
* Output layout (when timestamps present):
|
|
26
|
+
* ```
|
|
27
|
+
* <dir>/<bucket>/<slug>.<audio-ext>
|
|
28
|
+
* <dir>/<bucket>/<slug>.timestamps.json
|
|
29
|
+
* <dir>/<bucket>/<slug>.srt
|
|
30
|
+
* <dir>/<bucket>/<slug>.vtt
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export declare function maybeSaveResult(name: string, audio: {
|
|
34
|
+
uint8Array: Uint8Array;
|
|
35
|
+
mediaType: string;
|
|
36
|
+
}, timestamps?: readonly WordTimestamp[]): Promise<void>;
|
|
37
|
+
/**
|
|
38
|
+
* Drop-in replacement for `generateSpeech` that autosaves to
|
|
39
|
+
* `SPEECH_SDK_E2E_OUTPUT_DIR` using the current vitest test name. When the
|
|
40
|
+
* result includes word timestamps, also writes paired `.timestamps.json`,
|
|
41
|
+
* `.srt`, and `.vtt` files.
|
|
42
|
+
*/
|
|
43
|
+
export declare const generateSpeech: typeof _generateSpeech;
|
|
44
|
+
/**
|
|
45
|
+
* Drop-in replacement for `generateConversation` that autosaves to
|
|
46
|
+
* `SPEECH_SDK_E2E_OUTPUT_DIR` using the current vitest test name. When the
|
|
47
|
+
* result includes word timestamps, also writes paired `.timestamps.json`,
|
|
48
|
+
* `.srt`, and `.vtt` files.
|
|
49
|
+
*/
|
|
50
|
+
export declare const generateConversation: typeof _generateConversation;
|
|
51
|
+
/**
|
|
52
|
+
* Collects a streamed `streamSpeech` result into bytes AND autosaves them to
|
|
53
|
+
* `SPEECH_SDK_E2E_OUTPUT_DIR` using the current vitest test name. Use in place
|
|
54
|
+
* of `collectStream(result.audio)` in e2e tests.
|
|
55
|
+
*/
|
|
56
|
+
export declare function collectStreamAndSave(result: {
|
|
57
|
+
audio: ReadableStream<Uint8Array>;
|
|
58
|
+
mediaType: string;
|
|
59
|
+
}): Promise<Uint8Array>;
|
|
11
60
|
//# sourceMappingURL=_save-audio.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"_save-audio.d.ts","sourceRoot":"","sources":["../../../src/__tests__/e2e/_save-audio.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"_save-audio.d.ts","sourceRoot":"","sources":["../../../src/__tests__/e2e/_save-audio.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,oBAAoB,IAAI,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AAC/F,OAAO,EAAE,cAAc,IAAI,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC7E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AA8FzD;;;;;;;;;;GAUG;AACH,wBAAsB,cAAc,CAClC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE;IAAE,UAAU,EAAE,UAAU,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GACnD,OAAO,CAAC,IAAI,CAAC,CAEf;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE;IAAE,UAAU,EAAE,UAAU,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,EACpD,UAAU,CAAC,EAAE,SAAS,aAAa,EAAE,GACpC,OAAO,CAAC,IAAI,CAAC,CA8Bf;AAOD;;;;;GAKG;AACH,eAAO,MAAM,cAAc,EAAE,OAAO,eAMR,CAAC;AAE7B;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,EAAE,OAAO,qBAMR,CAAC;AAEnC;;;;GAIG;AACH,wBAAsB,oBAAoB,CAAC,MAAM,EAAE;IACjD,KAAK,EAAE,cAAc,CAAC,UAAU,CAAC,CAAC;IAClC,SAAS,EAAE,MAAM,CAAC;CACnB,GAAG,OAAO,CAAC,UAAU,CAAC,CAOtB"}
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import { mkdir, writeFile } from "node:fs/promises";
|
|
2
|
-
import { join } from "node:path";
|
|
2
|
+
import { basename, join } from "node:path";
|
|
3
|
+
import { expect } from "vitest";
|
|
4
|
+
import { timestampsToCaptions } from "../../captions.js";
|
|
5
|
+
import { generateConversation as _generateConversation } from "../../generate-conversation.js";
|
|
6
|
+
import { generateSpeech as _generateSpeech } from "../../generate-speech.js";
|
|
7
|
+
import { collectStream } from "./_collect-stream.js";
|
|
3
8
|
function extFor(mediaType) {
|
|
4
9
|
if (mediaType.includes("wav")) {
|
|
5
10
|
return "wav";
|
|
@@ -21,23 +26,146 @@ function extFor(mediaType) {
|
|
|
21
26
|
}
|
|
22
27
|
return "bin";
|
|
23
28
|
}
|
|
29
|
+
const NON_SLUG_CHARS = /[^a-zA-Z0-9._-]+/g;
|
|
30
|
+
const LEADING_OR_TRAILING_UNDERSCORES = /^_+|_+$/g;
|
|
31
|
+
const E2E_TEST_SUFFIX = /\.e2e\.test\.(ts|tsx|js|mjs)$/;
|
|
32
|
+
function slugify(name) {
|
|
33
|
+
return name
|
|
34
|
+
.replace(NON_SLUG_CHARS, "_")
|
|
35
|
+
.replace(LEADING_OR_TRAILING_UNDERSCORES, "");
|
|
36
|
+
}
|
|
37
|
+
function resolveOutputDir() {
|
|
38
|
+
const dir = process.env.SPEECH_SDK_E2E_OUTPUT_DIR;
|
|
39
|
+
if (!dir) {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
return dir.startsWith("~") ? join(process.env.HOME ?? "", dir.slice(1)) : dir;
|
|
43
|
+
}
|
|
44
|
+
function currentTestContext() {
|
|
45
|
+
// biome-ignore lint/suspicious/noMisplacedAssertion: reading vitest state, not asserting
|
|
46
|
+
const state = expect.getState();
|
|
47
|
+
return {
|
|
48
|
+
currentTestName: state.currentTestName,
|
|
49
|
+
testPath: state.testPath,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Derives the subdirectory for a given test file. e2e tests are named like
|
|
54
|
+
* `openai.e2e.test.ts` / `conversation-google.e2e.test.ts`; we strip the
|
|
55
|
+
* `.e2e.test.ts` suffix and use that as the per-provider bucket so a full run
|
|
56
|
+
* doesn't dump 100+ files into a single flat directory.
|
|
57
|
+
*/
|
|
58
|
+
function providerBucket(testPath) {
|
|
59
|
+
if (!testPath) {
|
|
60
|
+
return "unknown";
|
|
61
|
+
}
|
|
62
|
+
const base = basename(testPath).replace(E2E_TEST_SUFFIX, "");
|
|
63
|
+
return slugify(base) || "unknown";
|
|
64
|
+
}
|
|
65
|
+
// Counter keyed by `${bucket}/${slug}` so multiple generate/stream calls
|
|
66
|
+
// within a single test don't overwrite each other. Vitest isolates modules
|
|
67
|
+
// per file, so this resets per test file — collisions are only meaningful
|
|
68
|
+
// within the same `it`.
|
|
69
|
+
const callCounts = new Map();
|
|
70
|
+
/**
|
|
71
|
+
* Reserves a filename stem (without extension) for the next save call.
|
|
72
|
+
* First call returns `slug`; subsequent calls return `slug-2`, `slug-3`, etc.
|
|
73
|
+
* A single stem is shared across all sibling outputs from one logical save
|
|
74
|
+
* (audio + timestamps + captions), so they remain paired even across
|
|
75
|
+
* multiple saves within the same test.
|
|
76
|
+
*/
|
|
77
|
+
function nextStem(bucket, slug) {
|
|
78
|
+
const key = `${bucket}/${slug}`;
|
|
79
|
+
const n = (callCounts.get(key) ?? 0) + 1;
|
|
80
|
+
callCounts.set(key, n);
|
|
81
|
+
return n === 1 ? slug : `${slug}-${n}`;
|
|
82
|
+
}
|
|
83
|
+
async function writeAndLog(file, data) {
|
|
84
|
+
await writeFile(file, data);
|
|
85
|
+
console.log(`[e2e-save] wrote ${file}`);
|
|
86
|
+
}
|
|
24
87
|
/**
|
|
25
88
|
* Write a test-generated audio file to `SPEECH_SDK_E2E_OUTPUT_DIR` if the env
|
|
26
89
|
* var is set. No-op otherwise, so normal CI runs don't produce artifacts.
|
|
27
|
-
*
|
|
28
|
-
*
|
|
90
|
+
* Usually you don't need to call this directly — use the `generateSpeech`,
|
|
91
|
+
* `generateConversation`, and `collectStreamAndSave` helpers exported from
|
|
92
|
+
* this module, which autosave using the current test name.
|
|
93
|
+
*
|
|
94
|
+
* Output layout: `$SPEECH_SDK_E2E_OUTPUT_DIR/<provider-file>/<test-slug>.<ext>`.
|
|
95
|
+
* If the same test saves multiple times, subsequent files are suffixed `-2`,
|
|
96
|
+
* `-3`, etc.
|
|
29
97
|
*/
|
|
30
98
|
export async function maybeSaveAudio(name, audio) {
|
|
31
|
-
|
|
99
|
+
await maybeSaveResult(name, audio);
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Like {@link maybeSaveAudio}, plus — when `timestamps` is non-empty — also
|
|
103
|
+
* writes the raw alignment JSON and rendered SRT/VTT caption files alongside
|
|
104
|
+
* the audio. All four files share the same stem so they stay paired across
|
|
105
|
+
* multi-call tests. Still a no-op when `SPEECH_SDK_E2E_OUTPUT_DIR` is unset.
|
|
106
|
+
*
|
|
107
|
+
* Output layout (when timestamps present):
|
|
108
|
+
* ```
|
|
109
|
+
* <dir>/<bucket>/<slug>.<audio-ext>
|
|
110
|
+
* <dir>/<bucket>/<slug>.timestamps.json
|
|
111
|
+
* <dir>/<bucket>/<slug>.srt
|
|
112
|
+
* <dir>/<bucket>/<slug>.vtt
|
|
113
|
+
* ```
|
|
114
|
+
*/
|
|
115
|
+
export async function maybeSaveResult(name, audio, timestamps) {
|
|
116
|
+
const dir = resolveOutputDir();
|
|
32
117
|
if (!dir) {
|
|
33
118
|
return;
|
|
34
119
|
}
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
await mkdir(
|
|
39
|
-
const
|
|
40
|
-
await
|
|
41
|
-
|
|
120
|
+
const { testPath } = currentTestContext();
|
|
121
|
+
const bucket = providerBucket(testPath);
|
|
122
|
+
const bucketDir = join(dir, bucket);
|
|
123
|
+
await mkdir(bucketDir, { recursive: true });
|
|
124
|
+
const stem = nextStem(bucket, slugify(name));
|
|
125
|
+
await writeAndLog(join(bucketDir, `${stem}.${extFor(audio.mediaType)}`), audio.uint8Array);
|
|
126
|
+
if (timestamps && timestamps.length > 0) {
|
|
127
|
+
await writeAndLog(join(bucketDir, `${stem}.timestamps.json`), `${JSON.stringify(timestamps, null, 2)}\n`);
|
|
128
|
+
await writeAndLog(join(bucketDir, `${stem}.srt`), timestampsToCaptions(timestamps));
|
|
129
|
+
await writeAndLog(join(bucketDir, `${stem}.vtt`), timestampsToCaptions(timestamps, { format: "vtt" }));
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
function currentTestSlug() {
|
|
133
|
+
const { currentTestName } = currentTestContext();
|
|
134
|
+
return slugify(currentTestName ?? "unnamed") || "unnamed";
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Drop-in replacement for `generateSpeech` that autosaves to
|
|
138
|
+
* `SPEECH_SDK_E2E_OUTPUT_DIR` using the current vitest test name. When the
|
|
139
|
+
* result includes word timestamps, also writes paired `.timestamps.json`,
|
|
140
|
+
* `.srt`, and `.vtt` files.
|
|
141
|
+
*/
|
|
142
|
+
export const generateSpeech = (async (options) => {
|
|
143
|
+
const result = await _generateSpeech(options);
|
|
144
|
+
await maybeSaveResult(currentTestSlug(), result.audio, result.timestamps);
|
|
145
|
+
return result;
|
|
146
|
+
});
|
|
147
|
+
/**
|
|
148
|
+
* Drop-in replacement for `generateConversation` that autosaves to
|
|
149
|
+
* `SPEECH_SDK_E2E_OUTPUT_DIR` using the current vitest test name. When the
|
|
150
|
+
* result includes word timestamps, also writes paired `.timestamps.json`,
|
|
151
|
+
* `.srt`, and `.vtt` files.
|
|
152
|
+
*/
|
|
153
|
+
export const generateConversation = (async (options) => {
|
|
154
|
+
const result = await _generateConversation(options);
|
|
155
|
+
await maybeSaveResult(currentTestSlug(), result.audio, result.timestamps);
|
|
156
|
+
return result;
|
|
157
|
+
});
|
|
158
|
+
/**
|
|
159
|
+
* Collects a streamed `streamSpeech` result into bytes AND autosaves them to
|
|
160
|
+
* `SPEECH_SDK_E2E_OUTPUT_DIR` using the current vitest test name. Use in place
|
|
161
|
+
* of `collectStream(result.audio)` in e2e tests.
|
|
162
|
+
*/
|
|
163
|
+
export async function collectStreamAndSave(result) {
|
|
164
|
+
const bytes = await collectStream(result.audio);
|
|
165
|
+
await maybeSaveAudio(currentTestSlug(), {
|
|
166
|
+
uint8Array: bytes,
|
|
167
|
+
mediaType: result.mediaType,
|
|
168
|
+
});
|
|
169
|
+
return bytes;
|
|
42
170
|
}
|
|
43
171
|
//# sourceMappingURL=_save-audio.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"_save-audio.js","sourceRoot":"","sources":["../../../src/__tests__/e2e/_save-audio.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"_save-audio.js","sourceRoot":"","sources":["../../../src/__tests__/e2e/_save-audio.ts"],"names":[],"mappings":"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"}
|
package/dist/audio-utils.d.ts
CHANGED
|
@@ -9,4 +9,6 @@ export declare function parseMediaTypeParam(mediaType: string, name: string): nu
|
|
|
9
9
|
* does not require the WebCodecs encoder.
|
|
10
10
|
*/
|
|
11
11
|
export declare function wrapPcm16Mono(pcm: Uint8Array, sampleRate: number): Promise<Uint8Array>;
|
|
12
|
+
/** Decode a base64 string into raw bytes. */
|
|
13
|
+
export declare function base64ToUint8Array(b64: string): Uint8Array;
|
|
12
14
|
//# sourceMappingURL=audio-utils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audio-utils.d.ts","sourceRoot":"","sources":["../src/audio-utils.ts"],"names":[],"mappings":"AAUA;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,GACX,MAAM,GAAG,SAAS,CAcpB;AAED;;;;GAIG;AACH,wBAAsB,aAAa,CACjC,GAAG,EAAE,UAAU,EACf,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,UAAU,CAAC,CA2BrB"}
|
|
1
|
+
{"version":3,"file":"audio-utils.d.ts","sourceRoot":"","sources":["../src/audio-utils.ts"],"names":[],"mappings":"AAUA;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,GACX,MAAM,GAAG,SAAS,CAcpB;AAED;;;;GAIG;AACH,wBAAsB,aAAa,CACjC,GAAG,EAAE,UAAU,EACf,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,UAAU,CAAC,CA2BrB;AAED,6CAA6C;AAC7C,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAO1D"}
|
package/dist/audio-utils.js
CHANGED
|
@@ -50,4 +50,13 @@ export async function wrapPcm16Mono(pcm, sampleRate) {
|
|
|
50
50
|
}
|
|
51
51
|
return new Uint8Array(buffer);
|
|
52
52
|
}
|
|
53
|
+
/** Decode a base64 string into raw bytes. */
|
|
54
|
+
export function base64ToUint8Array(b64) {
|
|
55
|
+
const binary = atob(b64);
|
|
56
|
+
const bytes = new Uint8Array(binary.length);
|
|
57
|
+
for (let i = 0; i < binary.length; i++) {
|
|
58
|
+
bytes[i] = binary.charCodeAt(i);
|
|
59
|
+
}
|
|
60
|
+
return bytes;
|
|
61
|
+
}
|
|
53
62
|
//# sourceMappingURL=audio-utils.js.map
|
package/dist/audio-utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audio-utils.js","sourceRoot":"","sources":["../src/audio-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,wBAAwB,EACxB,aAAa,EACb,MAAM,EACN,eAAe,GAChB,MAAM,YAAY,CAAC;AAEpB,MAAM,iBAAiB,GAAG,IAAI,GAAG,EAAkB,CAAC;AAEpD;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CACjC,SAAiB,EACjB,IAAY;IAEZ,IAAI,EAAE,GAAG,iBAAiB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACrC,IAAI,CAAC,EAAE,EAAE,CAAC;QACR,sEAAsE;QACtE,oDAAoD;QACpD,EAAE,GAAG,IAAI,MAAM,CAAC,cAAc,IAAI,oBAAoB,EAAE,GAAG,CAAC,CAAC;QAC7D,iBAAiB,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IAClC,CAAC;IACD,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAClC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/B,OAAO,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;AACjE,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,GAAe,EACf,UAAkB;IAElB,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC;QACxB,MAAM,EAAE,IAAI,eAAe,EAAE;QAC7B,MAAM,EAAE,IAAI,YAAY,EAAE;KAC3B,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,IAAI,wBAAwB,CAAC,SAAS,CAAC,CAAC;IACvD,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;IAC7B,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;IAErB,4BAA4B;IAC5B,MAAM,UAAU,GAAG,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC;IAClC,MAAM,eAAe,GAAG,UAAU,GAAG,UAAU,CAAC;IAChD,MAAM,MAAM,GAAG,IAAI,aAAa,CAAC,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,eAAe,EAAE,CAAC,CAAC,CAAC;IACpE,MAAM,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE;QACvB,aAAa,EAAE;YACb,KAAK,EAAE,SAAS;YAChB,gBAAgB,EAAE,CAAC;YACnB,UAAU;SACX;KACF,CAAC,CAAC;IAEH,MAAM,MAAM,CAAC,QAAQ,EAAE,CAAC;IACxB,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC;IACpC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;IACrE,CAAC;IACD,OAAO,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC;AAChC,CAAC"}
|
|
1
|
+
{"version":3,"file":"audio-utils.js","sourceRoot":"","sources":["../src/audio-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,wBAAwB,EACxB,aAAa,EACb,MAAM,EACN,eAAe,GAChB,MAAM,YAAY,CAAC;AAEpB,MAAM,iBAAiB,GAAG,IAAI,GAAG,EAAkB,CAAC;AAEpD;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CACjC,SAAiB,EACjB,IAAY;IAEZ,IAAI,EAAE,GAAG,iBAAiB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACrC,IAAI,CAAC,EAAE,EAAE,CAAC;QACR,sEAAsE;QACtE,oDAAoD;QACpD,EAAE,GAAG,IAAI,MAAM,CAAC,cAAc,IAAI,oBAAoB,EAAE,GAAG,CAAC,CAAC;QAC7D,iBAAiB,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IAClC,CAAC;IACD,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAClC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/B,OAAO,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;AACjE,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,GAAe,EACf,UAAkB;IAElB,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC;QACxB,MAAM,EAAE,IAAI,eAAe,EAAE;QAC7B,MAAM,EAAE,IAAI,YAAY,EAAE;KAC3B,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,IAAI,wBAAwB,CAAC,SAAS,CAAC,CAAC;IACvD,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;IAC7B,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;IAErB,4BAA4B;IAC5B,MAAM,UAAU,GAAG,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC;IAClC,MAAM,eAAe,GAAG,UAAU,GAAG,UAAU,CAAC;IAChD,MAAM,MAAM,GAAG,IAAI,aAAa,CAAC,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,eAAe,EAAE,CAAC,CAAC,CAAC;IACpE,MAAM,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE;QACvB,aAAa,EAAE;YACb,KAAK,EAAE,SAAS;YAChB,gBAAgB,EAAE,CAAC;YACnB,UAAU;SACX;KACF,CAAC,CAAC;IAEH,MAAM,MAAM,CAAC,QAAQ,EAAE,CAAC;IACxB,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC;IACpC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;IACrE,CAAC;IACD,OAAO,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC;AAChC,CAAC;AAED,6CAA6C;AAC7C,MAAM,UAAU,kBAAkB,CAAC,GAAW;IAC5C,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;IACzB,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC5C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACvC,KAAK,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;IAClC,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import type { WordTimestamp } from "./timestamps.js";
|
|
2
|
+
/**
|
|
3
|
+
* Sanitizes caption-body text: strips C0 control characters (U+0000–U+001F
|
|
4
|
+
* minus whitespace, plus U+007F DEL), folds non-ASCII typography (curly
|
|
5
|
+
* quotes, en/em dashes, ellipsis) to ASCII equivalents, and collapses
|
|
6
|
+
* whitespace runs to a single space. Exported for testing.
|
|
7
|
+
*/
|
|
8
|
+
export declare function normalizeTypography(text: string): string;
|
|
9
|
+
/**
|
|
10
|
+
* Escapes characters that would otherwise be interpreted as inline WebVTT
|
|
11
|
+
* markup. Applied only to the VTT render path; SRT passes raw text through.
|
|
12
|
+
* Exported for testing; not part of the public API.
|
|
13
|
+
*/
|
|
14
|
+
export declare function escapeVttText(text: string): string;
|
|
15
|
+
/**
|
|
16
|
+
* Formats a number of seconds as an SRT timestamp: `HH:MM:SS,mmm`.
|
|
17
|
+
* Negative inputs are clamped to zero. Milliseconds are rounded.
|
|
18
|
+
* Exported for testing; not part of the public API.
|
|
19
|
+
*/
|
|
20
|
+
export declare function formatSrtTime(seconds: number): string;
|
|
21
|
+
/**
|
|
22
|
+
* Formats a number of seconds as a WebVTT timestamp: `HH:MM:SS.mmm`.
|
|
23
|
+
* Negative inputs are clamped to zero. Milliseconds are rounded.
|
|
24
|
+
* Exported for testing; not part of the public API.
|
|
25
|
+
*/
|
|
26
|
+
export declare function formatVttTime(seconds: number): string;
|
|
27
|
+
/**
|
|
28
|
+
* Groups a flat list of word timestamps into sentences using terminator
|
|
29
|
+
* punctuation attached to the trailing word. Supported terminators:
|
|
30
|
+
*
|
|
31
|
+
* - ASCII: `.`, `!`, `?`
|
|
32
|
+
* - CJK: `。`, `!`, `?`
|
|
33
|
+
* - Devanagari (Hindi, Sanskrit, Marathi): `।`, `॥`
|
|
34
|
+
* - Arabic: `؟`, `۔`
|
|
35
|
+
*
|
|
36
|
+
* A trailing closing quote (`"`, `'`, curly variants, or CJK corner
|
|
37
|
+
* bracket `」` / `』`) attached to the terminator is tolerated.
|
|
38
|
+
*
|
|
39
|
+
* Known limitations:
|
|
40
|
+
* - Abbreviations like "Dr." or "e.g." are treated as sentence ends.
|
|
41
|
+
* - Thai and other scripts without word-level whitespace or inline
|
|
42
|
+
* terminators fall through to char/duration-based hard breaks.
|
|
43
|
+
*
|
|
44
|
+
* Exported for testing; not part of the public API.
|
|
45
|
+
*/
|
|
46
|
+
export declare function groupIntoSentences(words: readonly WordTimestamp[]): WordTimestamp[][];
|
|
47
|
+
interface CueSplitOptions {
|
|
48
|
+
readonly longPhraseCommaBreakChars: number;
|
|
49
|
+
readonly maxCharsPerCue: number;
|
|
50
|
+
readonly maxCueDurationMs: number;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Subdivides a sentence (an ordered list of words) into one or more cues.
|
|
54
|
+
* Breaks are chosen in this priority order:
|
|
55
|
+
* 1. Hard: character budget exceeded → break before the offending word.
|
|
56
|
+
* 2. Hard: duration exceeded → break before the offending word.
|
|
57
|
+
* 3. Soft: comma in a word that leaves the current cue above
|
|
58
|
+
* `longPhraseCommaBreakChars` → break after that word.
|
|
59
|
+
*
|
|
60
|
+
* Exported for testing; not part of the public API.
|
|
61
|
+
*/
|
|
62
|
+
export declare function splitSentenceIntoCues(sentence: readonly WordTimestamp[], options: CueSplitOptions): WordTimestamp[][];
|
|
63
|
+
interface WrapOptions {
|
|
64
|
+
readonly maxLineLength: number;
|
|
65
|
+
readonly maxLines: number;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Wraps a sequence of words into up to `maxLines` lines, trying to keep
|
|
69
|
+
* each line at or below `maxLineLength` characters. A word longer than
|
|
70
|
+
* `maxLineLength` is placed on its own line rather than split. If words
|
|
71
|
+
* remain after the final line is full, they are appended to that final
|
|
72
|
+
* line (accept overflow; cue splitter is expected to have prevented this
|
|
73
|
+
* in normal flow).
|
|
74
|
+
*
|
|
75
|
+
* Exported for testing; not part of the public API.
|
|
76
|
+
*/
|
|
77
|
+
export declare function wrapCueText(words: readonly string[], options: WrapOptions): string;
|
|
78
|
+
/**
|
|
79
|
+
* Supported caption output formats.
|
|
80
|
+
*
|
|
81
|
+
* - `"srt"` — SubRip (`.srt`). Comma-decimal timestamps, numeric cue IDs,
|
|
82
|
+
* plain text bodies. Widely supported by media players and upload tools.
|
|
83
|
+
* - `"vtt"` — WebVTT (`.vtt`). Period-decimal timestamps, `WEBVTT` header,
|
|
84
|
+
* HTML-escaped bodies (`&`, `<`, `>`). Required for HTML `<track>`.
|
|
85
|
+
*/
|
|
86
|
+
export type CaptionFormat = "srt" | "vtt";
|
|
87
|
+
/**
|
|
88
|
+
* Options for {@link timestampsToCaptions}.
|
|
89
|
+
*/
|
|
90
|
+
export interface CaptionsOptions {
|
|
91
|
+
/** Output format. Default `"srt"`. */
|
|
92
|
+
readonly format?: CaptionFormat;
|
|
93
|
+
/**
|
|
94
|
+
* Minimum cue-char-count at which a trailing comma triggers a soft cue
|
|
95
|
+
* break. Prevents tiny fragments after every comma. Default `60`.
|
|
96
|
+
*/
|
|
97
|
+
readonly longPhraseCommaBreakChars?: number;
|
|
98
|
+
/** Max total chars per cue. Default `maxLineLength * maxLinesPerCue`. */
|
|
99
|
+
readonly maxCharsPerCue?: number;
|
|
100
|
+
/** Max cue duration in milliseconds. Default `7000`. */
|
|
101
|
+
readonly maxCueDurationMs?: number;
|
|
102
|
+
/**
|
|
103
|
+
* Max chars per line (word-boundary wrap). Default `42` — the common
|
|
104
|
+
* broadcast convention for Latin-alphabet subtitles.
|
|
105
|
+
*
|
|
106
|
+
* Character counts use JavaScript `string.length` (UTF-16 code units).
|
|
107
|
+
* For CJK (Japanese, Chinese, Korean) content, each character is roughly
|
|
108
|
+
* twice the visual width of an ASCII character in monospaced players;
|
|
109
|
+
* pass a smaller value (e.g. `16`) to match Japanese broadcast norms.
|
|
110
|
+
*/
|
|
111
|
+
readonly maxLineLength?: number;
|
|
112
|
+
/** Max lines per cue. Default `2`. */
|
|
113
|
+
readonly maxLinesPerCue?: number;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Converts word-level timestamps into a caption string in SRT or WebVTT
|
|
117
|
+
* format.
|
|
118
|
+
*
|
|
119
|
+
* Sentence boundaries (`.`, `!`, `?` in word text, optionally followed
|
|
120
|
+
* by a closing quote) create cue breaks; long sentences are subdivided
|
|
121
|
+
* by character count, duration, and soft comma breaks. Each cue is
|
|
122
|
+
* greedily wrapped into up to `maxLinesPerCue` lines of `maxLineLength`
|
|
123
|
+
* characters.
|
|
124
|
+
*
|
|
125
|
+
* Returns the empty string for empty input.
|
|
126
|
+
*
|
|
127
|
+
* @example
|
|
128
|
+
* ```ts
|
|
129
|
+
* const { timestamps } = await generateSpeech({ ... });
|
|
130
|
+
*
|
|
131
|
+
* const srt = timestampsToCaptions(timestamps ?? []);
|
|
132
|
+
* const vtt = timestampsToCaptions(timestamps ?? [], { format: "vtt" });
|
|
133
|
+
* ```
|
|
134
|
+
*/
|
|
135
|
+
export declare function timestampsToCaptions(timestamps: readonly WordTimestamp[], options?: CaptionsOptions): string;
|
|
136
|
+
export {};
|
|
137
|
+
//# sourceMappingURL=captions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"captions.d.ts","sourceRoot":"","sources":["../src/captions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAwBrD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAMxD;AAQD;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAMlD;AAeD;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAErD;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAErD;AAWD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,SAAS,aAAa,EAAE,GAC9B,aAAa,EAAE,EAAE,CAcnB;AAOD,UAAU,eAAe;IACvB,QAAQ,CAAC,yBAAyB,EAAE,MAAM,CAAC;IAC3C,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;CACnC;AA0BD;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,SAAS,aAAa,EAAE,EAClC,OAAO,EAAE,eAAe,GACvB,aAAa,EAAE,EAAE,CAgCnB;AAED,UAAU,WAAW;IACnB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CACzB,KAAK,EAAE,SAAS,MAAM,EAAE,EACxB,OAAO,EAAE,WAAW,GACnB,MAAM,CAmBR;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,KAAK,CAAC;AAE1C;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,sCAAsC;IACtC,QAAQ,CAAC,MAAM,CAAC,EAAE,aAAa,CAAC;IAChC;;;OAGG;IACH,QAAQ,CAAC,yBAAyB,CAAC,EAAE,MAAM,CAAC;IAC5C,yEAAyE;IACzE,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,wDAAwD;IACxD,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC;;;;;;;;OAQG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,sCAAsC;IACtC,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;CAClC;AAWD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,oBAAoB,CAClC,UAAU,EAAE,SAAS,aAAa,EAAE,EACpC,OAAO,GAAE,eAAoB,GAC5B,MAAM,CAkER"}
|