retiam 2.0.0 → 2.0.2
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/THIRD_PARTY_NOTICES.md +3 -3
- package/agent/AGENTS.md +67 -0
- package/agent/CLAUDE.md +2 -0
- package/agent/skill/SKILL.md +111 -0
- package/agent/skill/examples/AreaLesson.ts +48 -0
- package/agent/skill/examples/ExplainMotion.ts +32 -0
- package/agent/skill/examples/NarratedMotion.ts +42 -0
- package/agent/skill/examples/SecantToTangent.ts +142 -0
- package/agent/skill/references/api.md +109 -0
- package/agent/skill/references/explainers.md +121 -0
- package/agent/skill/references/quality.md +148 -0
- package/agent/skill/references/styles.md +58 -0
- package/agent/skill/references/tts.md +72 -0
- package/agent/templates/explainer/lesson.json +25 -0
- package/agent/templates/explainer/review.json +6 -0
- package/agent/templates/explainer/styles.json +92 -0
- package/bin/agent-kit.js +26 -0
- package/bin/cli.js +24 -4
- package/bin/context.js +57 -0
- package/bin/init.js +71 -12
- package/bin/lesson-project.js +30 -0
- package/bin/lesson.js +168 -0
- package/bin/lint.js +6 -6
- package/bin/snapshot-runtime.js +185 -0
- package/bin/snapshot.js +32 -225
- package/dist/THIRD_PARTY_NOTICES.md +3 -3
- package/dist/UTIF-BrQ3Ng5l.min.js +1 -0
- package/dist/{UTIF-2Ear_0Uo.js → UTIF-CN0-pEnd.js} +1 -1
- package/dist/decompress-D7LzbvPD.min.js +15 -0
- package/dist/index-3sAseSJQ.min.js +10472 -0
- package/dist/{index-B2sJBy4c.js → index-yQIdejOj.js} +15 -13
- package/dist/libs/explainer/example.d.ts +3 -0
- package/dist/libs/explainer/index.d.ts +5 -0
- package/dist/libs/explainer/index.js +134 -0
- package/dist/libs/explainer/plan.d.ts +12 -0
- package/dist/libs/explainer/plan.js +197 -0
- package/dist/libs/explainer/runtime.d.ts +24 -0
- package/dist/libs/explainer/styles.d.ts +3 -0
- package/dist/libs/explainer/types.d.ts +119 -0
- package/dist/libs/explainer/visuals.d.ts +18 -0
- package/dist/libs/tts/index.js +386 -1009
- package/dist/libs/vite/index.d.ts +28 -0
- package/dist/libs/vite/index.js +158 -0
- package/dist/{main-D_G4uIju.js → main-BTk_9jtl.js} +1 -1
- package/dist/main-lQwYAed8.min.js +5939 -0
- package/dist/msEdgeV2-BLEnvPJa.js +641 -0
- package/dist/opentype.module-B-1cYAb-.min.js +1 -0
- package/dist/retiam.es.js +1 -1
- package/dist/retiam.es.min.js +1 -0
- package/dist/src/engine/animation/Animation.d.ts +1 -0
- package/package.json +12 -6
- package/readme.md +14 -7
package/dist/libs/tts/index.js
CHANGED
|
@@ -1,20 +1,22 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { D as M, c as D, p as F, g as L, s as V, f as P, a as N } from "../../msEdgeV2-BLEnvPJa.js";
|
|
2
|
+
import { M as rt, b as ot } from "../../msEdgeV2-BLEnvPJa.js";
|
|
3
|
+
import { Component as j, Color as y, hex as l, VGroup as H, SDFText as I, CENTER as $, Rect as X, Animation as K } from "retiam";
|
|
2
4
|
/*! Retiam: noncommercial use only unless separately licensed. See ../../LICENSE and ../../COMMERCIAL_LICENSE.md. Third-party notices: ../../THIRD_PARTY_NOTICES.md and ../../THIRD_PARTY_LICENSES.txt. */
|
|
3
|
-
function
|
|
4
|
-
const
|
|
5
|
-
|
|
5
|
+
function Y(c, t = 24e3) {
|
|
6
|
+
const a = t * 2, r = c.length * 2, n = new ArrayBuffer(44 + r), o = new DataView(n);
|
|
7
|
+
B(o, 0, "RIFF"), o.setUint32(4, 36 + r, !0), B(o, 8, "WAVE"), B(o, 12, "fmt "), o.setUint32(16, 16, !0), o.setUint16(20, 1, !0), o.setUint16(22, 1, !0), o.setUint32(24, t, !0), o.setUint32(28, a, !0), o.setUint16(32, 2, !0), o.setUint16(34, 16, !0), B(o, 36, "data"), o.setUint32(40, r, !0);
|
|
6
8
|
let u = 44;
|
|
7
|
-
for (let
|
|
8
|
-
const
|
|
9
|
-
o.setInt16(u,
|
|
9
|
+
for (let h = 0; h < c.length; h++) {
|
|
10
|
+
const d = Math.max(-1, Math.min(1, c[h])), p = d < 0 ? d * 32768 : d * 32767;
|
|
11
|
+
o.setInt16(u, p, !0), u += 2;
|
|
10
12
|
}
|
|
11
|
-
return
|
|
13
|
+
return n;
|
|
12
14
|
}
|
|
13
|
-
function
|
|
14
|
-
for (let i = 0; i <
|
|
15
|
-
|
|
15
|
+
function B(c, t, e) {
|
|
16
|
+
for (let i = 0; i < e.length; i++)
|
|
17
|
+
c.setUint8(t + i, e.charCodeAt(i));
|
|
16
18
|
}
|
|
17
|
-
class
|
|
19
|
+
class R {
|
|
18
20
|
text;
|
|
19
21
|
phonemes;
|
|
20
22
|
samples;
|
|
@@ -30,37 +32,37 @@ class G {
|
|
|
30
32
|
_blob = null;
|
|
31
33
|
_objectUrl = null;
|
|
32
34
|
_dataUrl = null;
|
|
33
|
-
constructor(
|
|
34
|
-
this.text =
|
|
35
|
+
constructor(t) {
|
|
36
|
+
this.text = t.text, this.phonemes = t.phonemes || "", this.samples = t.samples ?? new Float32Array(0), this.sampleRate = t.sampleRate ?? 24e3, this.voice = t.voice ?? "af_heart", this.speed = t.speed ?? 1, this.wordBoundaries = t.wordBoundaries, this.rawBuffer = t.rawBuffer, this.mimeType = t.mimeType || (t.rawBuffer ? "audio/mpeg" : "audio/wav"), t.durationMs !== void 0 ? (this.durationMs = t.durationMs, this.duration = t.duration ?? t.durationMs / 1e3) : t.duration !== void 0 ? (this.duration = t.duration, this.durationMs = t.duration * 1e3) : (this.duration = this.samples.length > 0 ? this.samples.length / this.sampleRate : 0, this.durationMs = this.duration * 1e3);
|
|
35
37
|
}
|
|
36
38
|
/**
|
|
37
39
|
* Converts raw PCM samples or decodes underlying rawBuffer into a Web Audio [[AudioBuffer]].
|
|
38
40
|
*/
|
|
39
|
-
async getOrDecodeAudioBuffer(
|
|
41
|
+
async getOrDecodeAudioBuffer(t) {
|
|
40
42
|
if (this.samples && this.samples.length > 0)
|
|
41
|
-
return this.toAudioBuffer(
|
|
43
|
+
return this.toAudioBuffer(t);
|
|
42
44
|
if (this.rawBuffer)
|
|
43
45
|
try {
|
|
44
|
-
const
|
|
45
|
-
return this.samples =
|
|
46
|
-
} catch (
|
|
47
|
-
console.warn("[TTSAudio] Failed to decode rawBuffer via context.decodeAudioData:",
|
|
46
|
+
const e = await t.decodeAudioData(this.rawBuffer.slice(0));
|
|
47
|
+
return this.samples = e.getChannelData(0), this.sampleRate = e.sampleRate, e;
|
|
48
|
+
} catch (e) {
|
|
49
|
+
console.warn("[TTSAudio] Failed to decode rawBuffer via context.decodeAudioData:", e);
|
|
48
50
|
}
|
|
49
|
-
return this.toAudioBuffer(
|
|
51
|
+
return this.toAudioBuffer(t);
|
|
50
52
|
}
|
|
51
53
|
/**
|
|
52
54
|
* Converts raw PCM samples to a Web Audio [[AudioBuffer]].
|
|
53
55
|
*/
|
|
54
|
-
toAudioBuffer(
|
|
55
|
-
const
|
|
56
|
-
if (
|
|
57
|
-
const
|
|
58
|
-
return
|
|
56
|
+
toAudioBuffer(t) {
|
|
57
|
+
const e = t || (typeof window < "u" ? window.__retiam_audio_context : null);
|
|
58
|
+
if (e) {
|
|
59
|
+
const s = e.createBuffer(1, Math.max(1, this.samples.length), this.sampleRate);
|
|
60
|
+
return s.getChannelData(0).set(this.samples), s;
|
|
59
61
|
}
|
|
60
62
|
const i = typeof window < "u" ? window.AudioContext || window.webkitAudioContext : null;
|
|
61
63
|
if (i) {
|
|
62
|
-
const
|
|
63
|
-
return
|
|
64
|
+
const a = new i().createBuffer(1, Math.max(1, this.samples.length), this.sampleRate);
|
|
65
|
+
return a.getChannelData(0).set(this.samples), a;
|
|
64
66
|
}
|
|
65
67
|
throw new Error("[TTSAudio] Cannot create AudioBuffer: No AudioContext available in this environment.");
|
|
66
68
|
}
|
|
@@ -68,7 +70,7 @@ class G {
|
|
|
68
70
|
* Returns an ArrayBuffer containing encoded 16-bit PCM WAV audio.
|
|
69
71
|
*/
|
|
70
72
|
toWav() {
|
|
71
|
-
return this._wavBuffer || (this.rawBuffer && this.mimeType.includes("wav") ? this._wavBuffer = this.rawBuffer : this._wavBuffer =
|
|
73
|
+
return this._wavBuffer || (this.rawBuffer && this.mimeType.includes("wav") ? this._wavBuffer = this.rawBuffer : this._wavBuffer = Y(this.samples, this.sampleRate)), this._wavBuffer;
|
|
72
74
|
}
|
|
73
75
|
/**
|
|
74
76
|
* Returns a standard WAV or MP3 [[Blob]].
|
|
@@ -81,13 +83,13 @@ class G {
|
|
|
81
83
|
*/
|
|
82
84
|
toDataUrl() {
|
|
83
85
|
if (!this._dataUrl) {
|
|
84
|
-
const
|
|
85
|
-
let
|
|
86
|
-
const i =
|
|
87
|
-
for (let
|
|
88
|
-
|
|
89
|
-
const
|
|
90
|
-
this._dataUrl = `data:${this.mimeType};base64,${
|
|
86
|
+
const t = this.rawBuffer ? new Uint8Array(this.rawBuffer) : new Uint8Array(this.toWav());
|
|
87
|
+
let e = "";
|
|
88
|
+
const i = t.byteLength;
|
|
89
|
+
for (let a = 0; a < i; a++)
|
|
90
|
+
e += String.fromCharCode(t[a]);
|
|
91
|
+
const s = typeof btoa < "u" ? btoa(e) : Buffer.from(e, "binary").toString("base64");
|
|
92
|
+
this._dataUrl = `data:${this.mimeType};base64,${s}`;
|
|
91
93
|
}
|
|
92
94
|
return this._dataUrl;
|
|
93
95
|
}
|
|
@@ -111,731 +113,102 @@ class G {
|
|
|
111
113
|
/**
|
|
112
114
|
* Triggers a browser download or writes out the audio file.
|
|
113
115
|
*/
|
|
114
|
-
save(
|
|
115
|
-
const
|
|
116
|
+
save(t) {
|
|
117
|
+
const e = this.mimeType.includes("mpeg") || this.mimeType.includes("mp3") ? ".mp3" : ".wav", i = `speech${e}`, s = t ? t.includes(".") ? t : `${t}${e}` : i;
|
|
116
118
|
if (typeof document < "u") {
|
|
117
|
-
const
|
|
118
|
-
|
|
119
|
-
document.body.removeChild(
|
|
119
|
+
const a = this.toObjectUrl(), r = document.createElement("a");
|
|
120
|
+
r.style.display = "none", r.href = a, r.download = s, document.body.appendChild(r), r.click(), setTimeout(() => {
|
|
121
|
+
document.body.removeChild(r);
|
|
120
122
|
}, 100);
|
|
121
123
|
return;
|
|
122
124
|
}
|
|
123
125
|
try {
|
|
124
|
-
const
|
|
125
|
-
if (
|
|
126
|
-
const
|
|
127
|
-
|
|
126
|
+
const a = globalThis.require ? globalThis.require("fs") : null;
|
|
127
|
+
if (a) {
|
|
128
|
+
const r = this.rawBuffer ? Buffer.from(this.rawBuffer) : Buffer.from(this.toWav());
|
|
129
|
+
a.writeFileSync(s, r);
|
|
128
130
|
}
|
|
129
|
-
} catch (
|
|
130
|
-
console.warn(`[TTSAudio] Unable to save file ${
|
|
131
|
+
} catch (a) {
|
|
132
|
+
console.warn(`[TTSAudio] Unable to save file ${s}:`, a);
|
|
131
133
|
}
|
|
132
134
|
}
|
|
133
135
|
/**
|
|
134
136
|
* Plays the audio through Retiam's [[AudioManager]] on the dedicated voiceover bus
|
|
135
137
|
* with automatic BGM ducking and timeline synchronization.
|
|
136
138
|
*/
|
|
137
|
-
async play(
|
|
139
|
+
async play(t, e = {}) {
|
|
138
140
|
let i;
|
|
139
|
-
return
|
|
141
|
+
return t && (typeof t.playVoiceover == "function" ? i = t : t.audio && typeof t.audio.playVoiceover == "function" && (i = t.audio)), i ? i.playVoiceover(this, e) : (console.warn("[TTSAudio] No active AudioManager provided to play(). Creating standalone audio playback."), this._playStandalone(e));
|
|
140
142
|
}
|
|
141
143
|
/**
|
|
142
144
|
* Standalone playback fallback if no Retiam scene/AudioManager is provided.
|
|
143
145
|
*/
|
|
144
|
-
_playStandalone(
|
|
145
|
-
return new Promise((
|
|
146
|
+
_playStandalone(t) {
|
|
147
|
+
return new Promise((e) => {
|
|
146
148
|
if (typeof Audio > "u") {
|
|
147
|
-
|
|
149
|
+
e(this.durationMs);
|
|
148
150
|
return;
|
|
149
151
|
}
|
|
150
152
|
const i = new Audio(this.toObjectUrl());
|
|
151
|
-
i.volume = Math.max(0, Math.min(1,
|
|
152
|
-
const
|
|
153
|
-
setTimeout(() =>
|
|
153
|
+
i.volume = Math.max(0, Math.min(1, t.volume ?? 1)), i.onended = () => {
|
|
154
|
+
const s = t.padEndMs ?? 100;
|
|
155
|
+
setTimeout(() => e(this.durationMs + s), s);
|
|
154
156
|
}, i.onerror = () => {
|
|
155
|
-
|
|
157
|
+
e(this.durationMs);
|
|
156
158
|
}, i.play().catch(() => {
|
|
157
|
-
|
|
159
|
+
e(this.durationMs);
|
|
158
160
|
});
|
|
159
161
|
});
|
|
160
162
|
}
|
|
161
163
|
}
|
|
162
|
-
|
|
163
|
-
1: [44100, 48e3, 32e3],
|
|
164
|
-
2: [22050, 24e3, 16e3],
|
|
165
|
-
"2.5": [11025, 12e3, 8e3]
|
|
166
|
-
}, de = {
|
|
167
|
-
V1L3: [0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320],
|
|
168
|
-
V2L3: [0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160]
|
|
169
|
-
};
|
|
170
|
-
function H(a) {
|
|
171
|
-
const e = a instanceof Uint8Array ? a : new Uint8Array(a), t = e.length;
|
|
172
|
-
let i = 0, r = 0, s = 0, n = 24e3, l = 96, o = 1;
|
|
173
|
-
for (t >= 10 && e[0] === 73 && e[1] === 68 && e[2] === 51 && (i = 10 + ((e[6] & 127) << 21 | (e[7] & 127) << 14 | (e[8] & 127) << 7 | e[9] & 127)); i < t - 4; ) {
|
|
174
|
-
if (e[i] === 255 && (e[i + 1] & 224) === 224) {
|
|
175
|
-
const d = e[i + 1], c = e[i + 2], f = e[i + 3], h = d >> 3 & 3, p = h === 3 ? "1" : h === 2 ? "2" : h === 0 ? "2.5" : null, b = d >> 1 & 3, m = c >> 4 & 15, _ = c >> 2 & 3, A = c >> 1 & 1, U = f >> 6 & 3;
|
|
176
|
-
if (p && b === 1 && _ < 3 && m > 0 && m < 15) {
|
|
177
|
-
const x = le[p][_], F = de[p === "1" ? "V1L3" : "V2L3"][m], z = F * 1e3, R = p === "1" ? 1152 : 576, ee = Math.floor(R * (z / 8) / x) + A;
|
|
178
|
-
n = x, l = F, o = U === 3 ? 1 : 2, s += R, r++, i += ee;
|
|
179
|
-
continue;
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
i++;
|
|
183
|
-
}
|
|
184
|
-
if (r === 0 || n === 0) {
|
|
185
|
-
const d = Math.max(0.1, t / 12e3);
|
|
186
|
-
return {
|
|
187
|
-
sampleRate: 24e3,
|
|
188
|
-
frameCount: 1,
|
|
189
|
-
totalSamples: Math.floor(d * 24e3),
|
|
190
|
-
durationSec: d,
|
|
191
|
-
durationMs: d * 1e3,
|
|
192
|
-
bitrateKbps: 96,
|
|
193
|
-
channels: 1
|
|
194
|
-
};
|
|
195
|
-
}
|
|
196
|
-
const u = s / n;
|
|
197
|
-
return {
|
|
198
|
-
sampleRate: n,
|
|
199
|
-
frameCount: r,
|
|
200
|
-
totalSamples: s,
|
|
201
|
-
durationSec: u,
|
|
202
|
-
durationMs: u * 1e3,
|
|
203
|
-
bitrateKbps: l,
|
|
204
|
-
channels: o
|
|
205
|
-
};
|
|
206
|
-
}
|
|
207
|
-
const K = {
|
|
208
|
-
// --- American English (US) ---
|
|
209
|
-
"en-US-JennyNeural": {
|
|
210
|
-
id: "en-US-JennyNeural",
|
|
211
|
-
name: "Jenny",
|
|
212
|
-
language: "en-us",
|
|
213
|
-
gender: "Female",
|
|
214
|
-
traits: "Warm, Conversational, Natural, Clear",
|
|
215
|
-
targetQuality: "A+",
|
|
216
|
-
overallGrade: "A+",
|
|
217
|
-
provider: "msedge"
|
|
218
|
-
},
|
|
219
|
-
"en-US-GuyNeural": {
|
|
220
|
-
id: "en-US-GuyNeural",
|
|
221
|
-
name: "Guy",
|
|
222
|
-
language: "en-us",
|
|
223
|
-
gender: "Male",
|
|
224
|
-
traits: "Confident, Broadcast, Documentary, Instructional",
|
|
225
|
-
targetQuality: "A+",
|
|
226
|
-
overallGrade: "A+",
|
|
227
|
-
provider: "msedge"
|
|
228
|
-
},
|
|
229
|
-
"en-US-AriaNeural": {
|
|
230
|
-
id: "en-US-AriaNeural",
|
|
231
|
-
name: "Aria",
|
|
232
|
-
language: "en-us",
|
|
233
|
-
gender: "Female",
|
|
234
|
-
traits: "Dynamic, Highly Expressive, Conversational",
|
|
235
|
-
targetQuality: "A+",
|
|
236
|
-
overallGrade: "A",
|
|
237
|
-
provider: "msedge"
|
|
238
|
-
},
|
|
239
|
-
"en-US-AndrewNeural": {
|
|
240
|
-
id: "en-US-AndrewNeural",
|
|
241
|
-
name: "Andrew",
|
|
242
|
-
language: "en-us",
|
|
243
|
-
gender: "Male",
|
|
244
|
-
traits: "Warm, Confident, Authentic, Honest",
|
|
245
|
-
targetQuality: "A+",
|
|
246
|
-
overallGrade: "A+",
|
|
247
|
-
provider: "msedge"
|
|
248
|
-
},
|
|
249
|
-
"en-US-AvaNeural": {
|
|
250
|
-
id: "en-US-AvaNeural",
|
|
251
|
-
name: "Ava",
|
|
252
|
-
language: "en-us",
|
|
253
|
-
gender: "Female",
|
|
254
|
-
traits: "Expressive, Natural, Pleasant",
|
|
255
|
-
targetQuality: "A+",
|
|
256
|
-
overallGrade: "A+",
|
|
257
|
-
provider: "msedge"
|
|
258
|
-
},
|
|
259
|
-
"en-US-EmmaNeural": {
|
|
260
|
-
id: "en-US-EmmaNeural",
|
|
261
|
-
name: "Emma",
|
|
262
|
-
language: "en-us",
|
|
263
|
-
gender: "Female",
|
|
264
|
-
traits: "Clear, Friendly, Conversational",
|
|
265
|
-
targetQuality: "A",
|
|
266
|
-
overallGrade: "A",
|
|
267
|
-
provider: "msedge"
|
|
268
|
-
},
|
|
269
|
-
"en-US-BrianNeural": {
|
|
270
|
-
id: "en-US-BrianNeural",
|
|
271
|
-
name: "Brian",
|
|
272
|
-
language: "en-us",
|
|
273
|
-
gender: "Male",
|
|
274
|
-
traits: "Approachable, Articulate, Natural",
|
|
275
|
-
targetQuality: "A",
|
|
276
|
-
overallGrade: "A",
|
|
277
|
-
provider: "msedge"
|
|
278
|
-
},
|
|
279
|
-
"en-US-ChristopherNeural": {
|
|
280
|
-
id: "en-US-ChristopherNeural",
|
|
281
|
-
name: "Christopher",
|
|
282
|
-
language: "en-us",
|
|
283
|
-
gender: "Male",
|
|
284
|
-
traits: "Deep, Authoritative, Cinematic",
|
|
285
|
-
targetQuality: "A",
|
|
286
|
-
overallGrade: "A",
|
|
287
|
-
provider: "msedge"
|
|
288
|
-
},
|
|
289
|
-
"en-US-EricNeural": {
|
|
290
|
-
id: "en-US-EricNeural",
|
|
291
|
-
name: "Eric",
|
|
292
|
-
language: "en-us",
|
|
293
|
-
gender: "Male",
|
|
294
|
-
traits: "Friendly, Casual, Natural",
|
|
295
|
-
targetQuality: "A-",
|
|
296
|
-
overallGrade: "A-",
|
|
297
|
-
provider: "msedge"
|
|
298
|
-
},
|
|
299
|
-
"en-US-MichelleNeural": {
|
|
300
|
-
id: "en-US-MichelleNeural",
|
|
301
|
-
name: "Michelle",
|
|
302
|
-
language: "en-us",
|
|
303
|
-
gender: "Female",
|
|
304
|
-
traits: "Professional, Engaging, Clear",
|
|
305
|
-
targetQuality: "A-",
|
|
306
|
-
overallGrade: "A-",
|
|
307
|
-
provider: "msedge"
|
|
308
|
-
},
|
|
309
|
-
"en-US-AnaNeural": {
|
|
310
|
-
id: "en-US-AnaNeural",
|
|
311
|
-
name: "Ana",
|
|
312
|
-
language: "en-us",
|
|
313
|
-
gender: "Female",
|
|
314
|
-
traits: "Childlike, Cheerful, Animated",
|
|
315
|
-
targetQuality: "B+",
|
|
316
|
-
overallGrade: "B+",
|
|
317
|
-
provider: "msedge"
|
|
318
|
-
},
|
|
319
|
-
"en-US-SteffanNeural": {
|
|
320
|
-
id: "en-US-SteffanNeural",
|
|
321
|
-
name: "Steffan",
|
|
322
|
-
language: "en-us",
|
|
323
|
-
gender: "Male",
|
|
324
|
-
traits: "Warm, Calming, Soft",
|
|
325
|
-
targetQuality: "A-",
|
|
326
|
-
overallGrade: "A-",
|
|
327
|
-
provider: "msedge"
|
|
328
|
-
},
|
|
329
|
-
// --- British English (UK) ---
|
|
330
|
-
"en-GB-SoniaNeural": {
|
|
331
|
-
id: "en-GB-SoniaNeural",
|
|
332
|
-
name: "Sonia",
|
|
333
|
-
language: "en-gb",
|
|
334
|
-
gender: "Female",
|
|
335
|
-
traits: "RP British, Polished, Professional, Clear",
|
|
336
|
-
targetQuality: "A+",
|
|
337
|
-
overallGrade: "A+",
|
|
338
|
-
provider: "msedge"
|
|
339
|
-
},
|
|
340
|
-
"en-GB-RyanNeural": {
|
|
341
|
-
id: "en-GB-RyanNeural",
|
|
342
|
-
name: "Ryan",
|
|
343
|
-
language: "en-gb",
|
|
344
|
-
gender: "Male",
|
|
345
|
-
traits: "Modern British, Natural, Confident",
|
|
346
|
-
targetQuality: "A",
|
|
347
|
-
overallGrade: "A",
|
|
348
|
-
provider: "msedge"
|
|
349
|
-
},
|
|
350
|
-
"en-GB-LibbyNeural": {
|
|
351
|
-
id: "en-GB-LibbyNeural",
|
|
352
|
-
name: "Libby",
|
|
353
|
-
language: "en-gb",
|
|
354
|
-
gender: "Female",
|
|
355
|
-
traits: "Storyteller, Warm British, Engaging",
|
|
356
|
-
targetQuality: "A-",
|
|
357
|
-
overallGrade: "A-",
|
|
358
|
-
provider: "msedge"
|
|
359
|
-
},
|
|
360
|
-
"en-GB-ThomasNeural": {
|
|
361
|
-
id: "en-GB-ThomasNeural",
|
|
362
|
-
name: "Thomas",
|
|
363
|
-
language: "en-gb",
|
|
364
|
-
gender: "Male",
|
|
365
|
-
traits: "Refined RP British, Documentary, Calm",
|
|
366
|
-
targetQuality: "A",
|
|
367
|
-
overallGrade: "A",
|
|
368
|
-
provider: "msedge"
|
|
369
|
-
},
|
|
370
|
-
// --- Australian & Canadian English ---
|
|
371
|
-
"en-AU-NatashaNeural": {
|
|
372
|
-
id: "en-AU-NatashaNeural",
|
|
373
|
-
name: "Natasha",
|
|
374
|
-
language: "en-au",
|
|
375
|
-
gender: "Female",
|
|
376
|
-
traits: "Australian, Friendly, Energetic",
|
|
377
|
-
targetQuality: "A",
|
|
378
|
-
overallGrade: "A",
|
|
379
|
-
provider: "msedge"
|
|
380
|
-
},
|
|
381
|
-
"en-AU-WilliamMultilingualNeural": {
|
|
382
|
-
id: "en-AU-WilliamMultilingualNeural",
|
|
383
|
-
name: "William",
|
|
384
|
-
language: "en-au",
|
|
385
|
-
gender: "Male",
|
|
386
|
-
traits: "Australian Multilingual, Articulate",
|
|
387
|
-
targetQuality: "A-",
|
|
388
|
-
overallGrade: "A-",
|
|
389
|
-
provider: "msedge"
|
|
390
|
-
},
|
|
391
|
-
"en-CA-ClaraNeural": {
|
|
392
|
-
id: "en-CA-ClaraNeural",
|
|
393
|
-
name: "Clara",
|
|
394
|
-
language: "en-ca",
|
|
395
|
-
gender: "Female",
|
|
396
|
-
traits: "Canadian, Clear, Crisp",
|
|
397
|
-
targetQuality: "A-",
|
|
398
|
-
overallGrade: "A-",
|
|
399
|
-
provider: "msedge"
|
|
400
|
-
},
|
|
401
|
-
"en-CA-LiamNeural": {
|
|
402
|
-
id: "en-CA-LiamNeural",
|
|
403
|
-
name: "Liam",
|
|
404
|
-
language: "en-ca",
|
|
405
|
-
gender: "Male",
|
|
406
|
-
traits: "Canadian, Natural, Conversational",
|
|
407
|
-
targetQuality: "A-",
|
|
408
|
-
overallGrade: "A-",
|
|
409
|
-
provider: "msedge"
|
|
410
|
-
},
|
|
411
|
-
// --- Indian English ---
|
|
412
|
-
"en-IN-NeerjaNeural": {
|
|
413
|
-
id: "en-IN-NeerjaNeural",
|
|
414
|
-
name: "Neerja",
|
|
415
|
-
language: "en-in",
|
|
416
|
-
gender: "Female",
|
|
417
|
-
traits: "Indian English, Professional, High Clarity",
|
|
418
|
-
targetQuality: "A",
|
|
419
|
-
overallGrade: "A",
|
|
420
|
-
provider: "msedge"
|
|
421
|
-
},
|
|
422
|
-
"en-IN-PrabhatNeural": {
|
|
423
|
-
id: "en-IN-PrabhatNeural",
|
|
424
|
-
name: "Prabhat",
|
|
425
|
-
language: "en-in",
|
|
426
|
-
gender: "Male",
|
|
427
|
-
traits: "Indian English, Confident, Instructional",
|
|
428
|
-
targetQuality: "A",
|
|
429
|
-
overallGrade: "A",
|
|
430
|
-
provider: "msedge"
|
|
431
|
-
},
|
|
432
|
-
// --- Global Languages ---
|
|
433
|
-
"es-ES-ElviraNeural": {
|
|
434
|
-
id: "es-ES-ElviraNeural",
|
|
435
|
-
name: "Elvira",
|
|
436
|
-
language: "es-es",
|
|
437
|
-
gender: "Female",
|
|
438
|
-
traits: "Spanish (Spain), Natural, Clear",
|
|
439
|
-
targetQuality: "A",
|
|
440
|
-
overallGrade: "A",
|
|
441
|
-
provider: "msedge"
|
|
442
|
-
},
|
|
443
|
-
"fr-FR-DeniseNeural": {
|
|
444
|
-
id: "fr-FR-DeniseNeural",
|
|
445
|
-
name: "Denise",
|
|
446
|
-
language: "fr-fr",
|
|
447
|
-
gender: "Female",
|
|
448
|
-
traits: "French (France), Refined, Elegant",
|
|
449
|
-
targetQuality: "A",
|
|
450
|
-
overallGrade: "A",
|
|
451
|
-
provider: "msedge"
|
|
452
|
-
},
|
|
453
|
-
"fr-FR-HenriNeural": {
|
|
454
|
-
id: "fr-FR-HenriNeural",
|
|
455
|
-
name: "Henri",
|
|
456
|
-
language: "fr-fr",
|
|
457
|
-
gender: "Male",
|
|
458
|
-
traits: "French (France), Documentary, Authoritative",
|
|
459
|
-
targetQuality: "A",
|
|
460
|
-
overallGrade: "A",
|
|
461
|
-
provider: "msedge"
|
|
462
|
-
},
|
|
463
|
-
"de-DE-KatjaNeural": {
|
|
464
|
-
id: "de-DE-KatjaNeural",
|
|
465
|
-
name: "Katja",
|
|
466
|
-
language: "de-de",
|
|
467
|
-
gender: "Female",
|
|
468
|
-
traits: "German (Germany), Precise, Professional",
|
|
469
|
-
targetQuality: "A",
|
|
470
|
-
overallGrade: "A",
|
|
471
|
-
provider: "msedge"
|
|
472
|
-
},
|
|
473
|
-
"de-DE-KillianNeural": {
|
|
474
|
-
id: "de-DE-KillianNeural",
|
|
475
|
-
name: "Killian",
|
|
476
|
-
language: "de-de",
|
|
477
|
-
gender: "Male",
|
|
478
|
-
traits: "German (Germany), Clear, Calm",
|
|
479
|
-
targetQuality: "A",
|
|
480
|
-
overallGrade: "A",
|
|
481
|
-
provider: "msedge"
|
|
482
|
-
},
|
|
483
|
-
"it-IT-ElsaNeural": {
|
|
484
|
-
id: "it-IT-ElsaNeural",
|
|
485
|
-
name: "Elsa",
|
|
486
|
-
language: "it-it",
|
|
487
|
-
gender: "Female",
|
|
488
|
-
traits: "Italian, Melodic, Expressive",
|
|
489
|
-
targetQuality: "A",
|
|
490
|
-
overallGrade: "A",
|
|
491
|
-
provider: "msedge"
|
|
492
|
-
},
|
|
493
|
-
"ja-JP-NanamiNeural": {
|
|
494
|
-
id: "ja-JP-NanamiNeural",
|
|
495
|
-
name: "Nanami",
|
|
496
|
-
language: "ja-jp",
|
|
497
|
-
gender: "Female",
|
|
498
|
-
traits: "Japanese, Crisp, Anime/Modern",
|
|
499
|
-
targetQuality: "A+",
|
|
500
|
-
overallGrade: "A+",
|
|
501
|
-
provider: "msedge"
|
|
502
|
-
},
|
|
503
|
-
"ja-JP-KeitaNeural": {
|
|
504
|
-
id: "ja-JP-KeitaNeural",
|
|
505
|
-
name: "Keita",
|
|
506
|
-
language: "ja-jp",
|
|
507
|
-
gender: "Male",
|
|
508
|
-
traits: "Japanese, Natural, Instructional",
|
|
509
|
-
targetQuality: "A",
|
|
510
|
-
overallGrade: "A",
|
|
511
|
-
provider: "msedge"
|
|
512
|
-
},
|
|
513
|
-
"zh-CN-XiaoxiaoNeural": {
|
|
514
|
-
id: "zh-CN-XiaoxiaoNeural",
|
|
515
|
-
name: "Xiaoxiao",
|
|
516
|
-
language: "zh-cn",
|
|
517
|
-
gender: "Female",
|
|
518
|
-
traits: "Chinese Mandarin, Natural, Expressive, Smooth",
|
|
519
|
-
targetQuality: "A+",
|
|
520
|
-
overallGrade: "A+",
|
|
521
|
-
provider: "msedge"
|
|
522
|
-
},
|
|
523
|
-
"zh-CN-YunxiNeural": {
|
|
524
|
-
id: "zh-CN-YunxiNeural",
|
|
525
|
-
name: "Yunxi",
|
|
526
|
-
language: "zh-cn",
|
|
527
|
-
gender: "Male",
|
|
528
|
-
traits: "Chinese Mandarin, Energetic, Storytelling",
|
|
529
|
-
targetQuality: "A",
|
|
530
|
-
overallGrade: "A",
|
|
531
|
-
provider: "msedge"
|
|
532
|
-
}
|
|
533
|
-
}, L = "en-US-JennyNeural";
|
|
534
|
-
let B = null;
|
|
535
|
-
function W() {
|
|
536
|
-
return B && B.length > 0 ? B : Object.values(K);
|
|
537
|
-
}
|
|
538
|
-
function ce(a) {
|
|
539
|
-
const e = a.toLowerCase().trim();
|
|
540
|
-
return W().find(
|
|
541
|
-
(i) => i.id.toLowerCase() === e || i.name.toLowerCase() === e || i.id.toLowerCase().includes(e) || i.name.toLowerCase().includes(e)
|
|
542
|
-
);
|
|
543
|
-
}
|
|
544
|
-
function Te(a) {
|
|
545
|
-
const e = a.toLowerCase().replace(/_/g, "-");
|
|
546
|
-
return W().filter(
|
|
547
|
-
(t) => t.language.toLowerCase() === e || t.language.toLowerCase().startsWith(e)
|
|
548
|
-
);
|
|
549
|
-
}
|
|
550
|
-
function he(a) {
|
|
551
|
-
B = a;
|
|
552
|
-
}
|
|
553
|
-
async function ue() {
|
|
554
|
-
if (B)
|
|
555
|
-
return B;
|
|
556
|
-
const e = "https://speech.platform.bing.com/consumer/speech/synthesize/readaloud/voices/list?trustedclienttoken=6A5AA1D4EAFF4E9FB37E23D68491D6F4";
|
|
557
|
-
try {
|
|
558
|
-
const t = await fetch(e);
|
|
559
|
-
if (!t.ok)
|
|
560
|
-
throw new Error(`HTTP ${t.status} ${t.statusText}`);
|
|
561
|
-
const i = await t.json();
|
|
562
|
-
if (Array.isArray(i)) {
|
|
563
|
-
const r = i.map((s) => ({
|
|
564
|
-
id: s.ShortName || s.Name,
|
|
565
|
-
name: (s.FriendlyName || s.ShortName || "").replace(/^Microsoft\s+/, "").replace(/\s+Online\s+\(Natural\)/, ""),
|
|
566
|
-
language: (s.Locale || "en-US").toLowerCase(),
|
|
567
|
-
gender: s.Gender === "Male" ? "Male" : "Female",
|
|
568
|
-
traits: s.VoiceTag?.VoicePersonalities ? s.VoiceTag.VoicePersonalities.join(", ") : void 0,
|
|
569
|
-
targetQuality: "A",
|
|
570
|
-
overallGrade: "A",
|
|
571
|
-
provider: "msedge"
|
|
572
|
-
}));
|
|
573
|
-
return B = r, r;
|
|
574
|
-
}
|
|
575
|
-
} catch (t) {
|
|
576
|
-
console.warn("[MsEdgeVoices] Unable to fetch remote voices list. Falling back to built-in curated catalog:", t);
|
|
577
|
-
}
|
|
578
|
-
return Object.values(K);
|
|
579
|
-
}
|
|
580
|
-
class T {
|
|
164
|
+
class C {
|
|
581
165
|
maxSize;
|
|
582
166
|
cache = /* @__PURE__ */ new Map();
|
|
583
|
-
constructor(
|
|
584
|
-
this.maxSize = Math.max(1,
|
|
167
|
+
constructor(t = 128) {
|
|
168
|
+
this.maxSize = Math.max(1, t);
|
|
585
169
|
}
|
|
586
|
-
static createKey(
|
|
587
|
-
return `${
|
|
170
|
+
static createKey(t, e, i) {
|
|
171
|
+
return `${e}:${i.toFixed(2)}:${t.trim().toLowerCase()}`;
|
|
588
172
|
}
|
|
589
|
-
get(
|
|
590
|
-
const
|
|
591
|
-
if (
|
|
592
|
-
return this.cache.delete(
|
|
173
|
+
get(t, e, i) {
|
|
174
|
+
const s = C.createKey(t, e, i), a = this.cache.get(s);
|
|
175
|
+
if (a)
|
|
176
|
+
return this.cache.delete(s), this.cache.set(s, a), a;
|
|
593
177
|
}
|
|
594
|
-
set(
|
|
595
|
-
const
|
|
596
|
-
if (this.cache.has(
|
|
597
|
-
this.cache.delete(
|
|
178
|
+
set(t, e, i, s) {
|
|
179
|
+
const a = C.createKey(t, e, i);
|
|
180
|
+
if (this.cache.has(a))
|
|
181
|
+
this.cache.delete(a);
|
|
598
182
|
else if (this.cache.size >= this.maxSize) {
|
|
599
|
-
const
|
|
600
|
-
|
|
183
|
+
const r = this.cache.keys().next().value;
|
|
184
|
+
r && (this.cache.get(r)?.revokeObjectUrl(), this.cache.delete(r));
|
|
601
185
|
}
|
|
602
|
-
this.cache.set(
|
|
186
|
+
this.cache.set(a, s);
|
|
603
187
|
}
|
|
604
|
-
has(
|
|
605
|
-
return this.cache.has(
|
|
188
|
+
has(t, e, i) {
|
|
189
|
+
return this.cache.has(C.createKey(t, e, i));
|
|
606
190
|
}
|
|
607
191
|
clear() {
|
|
608
|
-
for (const
|
|
609
|
-
|
|
192
|
+
for (const t of this.cache.values())
|
|
193
|
+
t.revokeObjectUrl();
|
|
610
194
|
this.cache.clear();
|
|
611
195
|
}
|
|
612
196
|
get size() {
|
|
613
197
|
return this.cache.size;
|
|
614
198
|
}
|
|
615
199
|
}
|
|
616
|
-
|
|
617
|
-
1779033703,
|
|
618
|
-
3144134277,
|
|
619
|
-
1013904242,
|
|
620
|
-
2773480762,
|
|
621
|
-
1359893119,
|
|
622
|
-
2600822924,
|
|
623
|
-
528734635,
|
|
624
|
-
1541459225
|
|
625
|
-
], ye = [
|
|
626
|
-
4255104674,
|
|
627
|
-
2435071207,
|
|
628
|
-
3192492180,
|
|
629
|
-
3442351626,
|
|
630
|
-
1811967817,
|
|
631
|
-
79508907,
|
|
632
|
-
4272990180,
|
|
633
|
-
66059218
|
|
634
|
-
], _e = [
|
|
635
|
-
3945054110,
|
|
636
|
-
358115615,
|
|
637
|
-
2696978146,
|
|
638
|
-
217723578,
|
|
639
|
-
2787307148,
|
|
640
|
-
3520959633,
|
|
641
|
-
3235718560,
|
|
642
|
-
4192668342,
|
|
643
|
-
4039316851,
|
|
644
|
-
1884868174,
|
|
645
|
-
1904797190,
|
|
646
|
-
15051571,
|
|
647
|
-
3529027680,
|
|
648
|
-
1920361828
|
|
649
|
-
], I = [
|
|
650
|
-
1116352408,
|
|
651
|
-
1899447441,
|
|
652
|
-
3049323471,
|
|
653
|
-
3921009573,
|
|
654
|
-
961987163,
|
|
655
|
-
1508970993,
|
|
656
|
-
2453635748,
|
|
657
|
-
2870763221,
|
|
658
|
-
3624381080,
|
|
659
|
-
310598401,
|
|
660
|
-
607225278,
|
|
661
|
-
1426881987,
|
|
662
|
-
1925078388,
|
|
663
|
-
2162078206,
|
|
664
|
-
2614888103,
|
|
665
|
-
3248222580,
|
|
666
|
-
3835390401,
|
|
667
|
-
4022224774,
|
|
668
|
-
264347078,
|
|
669
|
-
604807628,
|
|
670
|
-
770255983,
|
|
671
|
-
1249150122,
|
|
672
|
-
1555081692,
|
|
673
|
-
1996064986,
|
|
674
|
-
2554220882,
|
|
675
|
-
2821834349,
|
|
676
|
-
2952996808,
|
|
677
|
-
3210313671,
|
|
678
|
-
3336571891,
|
|
679
|
-
3584528711,
|
|
680
|
-
113926993,
|
|
681
|
-
338241895,
|
|
682
|
-
666307205,
|
|
683
|
-
773529912,
|
|
684
|
-
1294757372,
|
|
685
|
-
1396182291,
|
|
686
|
-
1695183700,
|
|
687
|
-
1986661051,
|
|
688
|
-
2177026350,
|
|
689
|
-
2456956037,
|
|
690
|
-
2730485921,
|
|
691
|
-
2820302411,
|
|
692
|
-
3259730800,
|
|
693
|
-
3345764771,
|
|
694
|
-
3516065817,
|
|
695
|
-
3600352804,
|
|
696
|
-
4094571909,
|
|
697
|
-
275423344,
|
|
698
|
-
430227734,
|
|
699
|
-
506948616,
|
|
700
|
-
659060556,
|
|
701
|
-
883997877,
|
|
702
|
-
958139571,
|
|
703
|
-
1322822218,
|
|
704
|
-
1537002063,
|
|
705
|
-
1747873779,
|
|
706
|
-
1955562222,
|
|
707
|
-
2024104815,
|
|
708
|
-
2227730452,
|
|
709
|
-
2361852424,
|
|
710
|
-
2428436474,
|
|
711
|
-
2756734187,
|
|
712
|
-
3204031479,
|
|
713
|
-
3329325298
|
|
714
|
-
], X = [...I];
|
|
715
|
-
X[14] = 3386640039;
|
|
716
|
-
const Q = [
|
|
717
|
-
[3895366065, 3005677776],
|
|
718
|
-
[1155409094, 2296378653],
|
|
719
|
-
[1005282748, 693190712],
|
|
720
|
-
[3365689651, 3005795295],
|
|
721
|
-
[2367603217, 3557143765],
|
|
722
|
-
[827258325, 652566332],
|
|
723
|
-
[3911487921, 1618477510],
|
|
724
|
-
[4037392853, 2192753147],
|
|
725
|
-
[101076211, 4199654362],
|
|
726
|
-
[3665427040, 545047652],
|
|
727
|
-
[3201434976, 1010595059],
|
|
728
|
-
[2314848760, 3536931681],
|
|
729
|
-
[905590982, 3137643201],
|
|
730
|
-
[3410617286, 3311559015]
|
|
731
|
-
], S = (a) => a >>> 0, g = (...a) => S(a.reduce((e, t) => e + t, 0)), y = (a, e) => S(Math.imul(a, e)), v = (a) => S(a << 16 | a >>> 16), N = (a, e) => S(a >>> e | a << 32 - e), P = (a) => S(a >>> 7 ^ a << 25 ^ a >>> 18 ^ a << 14 ^ a >>> 3), V = (a) => S(a >>> 17 ^ a << 15 ^ a >>> 19 ^ a << 13 ^ a >>> 10), Se = (a, e, t) => S(t ^ a & (e ^ t)), be = (a, e, t) => S(a & e | t & (a | e)), we = (a) => S(N(a, 6) ^ N(a, 11) ^ N(a, 25)), ve = (a) => S(N(a, 2) ^ N(a, 13) ^ N(a, 22));
|
|
732
|
-
function Y(a, e, t) {
|
|
733
|
-
let [i, r, s, n, l, o, u, d] = a;
|
|
734
|
-
const c = t === 14 ? X : I;
|
|
735
|
-
for (let f = t; f < 64; f++) {
|
|
736
|
-
const h = g(d, we(l), Se(l, o, u), c[f], e[f]), p = g(ve(i), be(i, r, s));
|
|
737
|
-
[i, r, s, n, l, o, u, d] = [g(h, p), i, r, s, g(n, h), l, o, u];
|
|
738
|
-
}
|
|
739
|
-
return [i, r, s, n, l, o, u, d];
|
|
740
|
-
}
|
|
741
|
-
function q(a, e) {
|
|
742
|
-
for (let t = e; t < 64; t++)
|
|
743
|
-
a.push(g(
|
|
744
|
-
V(a[t - 2]),
|
|
745
|
-
a[t - 7],
|
|
746
|
-
P(a[t - 15]),
|
|
747
|
-
a[t - 16]
|
|
748
|
-
));
|
|
749
|
-
}
|
|
750
|
-
function Ae(a) {
|
|
751
|
-
const e = new Array(16).fill(0);
|
|
752
|
-
e[14] = S(a[0] << 16 | a[1] << 8 | a[2]), e[15] = S(a[3] << 24 | a[4] << 16 | a[5] << 8 | a[6]);
|
|
753
|
-
for (let i = 16; i < 30; i++) {
|
|
754
|
-
let r = _e[i - 16];
|
|
755
|
-
if (i - 2 >= 14) {
|
|
756
|
-
const s = V(e[i - 2]);
|
|
757
|
-
r = g(r, i === 16 ? S(s ^ 758464) : s);
|
|
758
|
-
}
|
|
759
|
-
if (i - 7 >= 14 && (r = g(r, e[i - 7])), i - 15 >= 14) {
|
|
760
|
-
const s = P(e[i - 15]);
|
|
761
|
-
r = g(r, i === 29 ? S(s ^ 94112640) : s);
|
|
762
|
-
}
|
|
763
|
-
e.push(r);
|
|
764
|
-
}
|
|
765
|
-
e.push(g(
|
|
766
|
-
V(e[28]),
|
|
767
|
-
e[23],
|
|
768
|
-
P(e[15]),
|
|
769
|
-
e[14],
|
|
770
|
-
3386640039,
|
|
771
|
-
-I[14]
|
|
772
|
-
)), q(e, 31);
|
|
773
|
-
const t = Y(ye, e, 14);
|
|
774
|
-
return ge.map((i, r) => g(i, t[r]));
|
|
775
|
-
}
|
|
776
|
-
function ke(a) {
|
|
777
|
-
const e = 57 + a.length, t = ((55 - e) % 64 + 64) % 64, i = new Uint8Array(a.length - 7 + 1 + t + 8);
|
|
778
|
-
i.set(a.subarray(7)), i[a.length - 7] = 128;
|
|
779
|
-
const r = e * 8, s = new DataView(i.buffer);
|
|
780
|
-
s.setUint32(i.length - 8, Math.floor(r / 4294967296), !1), s.setUint32(i.length - 4, S(r), !1);
|
|
781
|
-
let n = Ae(a.subarray(0, 7));
|
|
782
|
-
for (let u = 0; u < i.length; u += 64) {
|
|
783
|
-
const d = new DataView(i.buffer, i.byteOffset + u, 64), c = Array.from({ length: 16 }, (h, p) => d.getUint32(p * 4, !1));
|
|
784
|
-
q(c, 16);
|
|
785
|
-
const f = Y(n, c, 0);
|
|
786
|
-
n = n.map((h, p) => g(h, f[p]));
|
|
787
|
-
}
|
|
788
|
-
const l = new Uint8Array(32), o = new DataView(l.buffer);
|
|
789
|
-
return n.forEach((u, d) => o.setUint32(d * 4, u, !1)), l;
|
|
790
|
-
}
|
|
791
|
-
function Ce(a) {
|
|
792
|
-
const e = new Uint8Array(Math.ceil(a.length / 4) * 4);
|
|
793
|
-
e.set(a);
|
|
794
|
-
const t = new DataView(e.buffer), i = Array.from({ length: e.length / 4 }, (r, s) => t.getUint32(s * 4, !0));
|
|
795
|
-
return i.length % 2 !== 0 && i.push(0), i;
|
|
796
|
-
}
|
|
797
|
-
function xe(a, e) {
|
|
798
|
-
const t = new DataView(e.buffer, e.byteOffset, e.byteLength), i = S(t.getUint32(0, !0) | 1), r = S(t.getUint32(4, !0) | 1), s = [y(i, 2190031155), y(r, 2190031155)], n = Q.map(([h], p) => y(h, s[p % 2])), l = Q.map(([, h]) => h), o = new Uint8Array(a.length + 1);
|
|
799
|
-
o.set(a, 1), Ce(o).forEach((h, p) => {
|
|
800
|
-
let b = y(h, p % 2 === 0 ? i : r), m = y(v(h), p % 2 === 0 ? 4010109435 : 3273069531);
|
|
801
|
-
p === 0 && (b = g(b, y(4076407578, s[0])), m = g(m, 186253312)), n.push(b), l.push(m);
|
|
802
|
-
});
|
|
803
|
-
let u = 0, d = 0, c = 0, f = 0;
|
|
804
|
-
for (let h = 0; h < n.length; h += 2) {
|
|
805
|
-
const p = n[h], b = n[h + 1];
|
|
806
|
-
let m = v(g(l[h], p)), _ = y(m, 1995771700);
|
|
807
|
-
u = g(u, y(v(_), 3287280279), _), m = v(g(l[h + 1], b)), _ = y(m, 411160124), d = g(y(v(_), 901586633), _), u = g(u, d), c = g(y(c, i), p), c = y(v(c), 3482890513), c = y(v(c), 2265471903), c = y(v(c), 315537773), c = y(v(c), 629022083), f = g(f, c), m = g(y(c, r), b), m = y(v(m), 2725517045), m = y(v(m), 3548616447), c = y(v(y(v(m), 2090019721)), 3215236969), f = g(f, c);
|
|
808
|
-
}
|
|
809
|
-
return [S(d ^ c), S(u ^ f)];
|
|
810
|
-
}
|
|
811
|
-
function $(a) {
|
|
812
|
-
return Array.from(a, (e) => e.toString(16).padStart(2, "0")).join("").toUpperCase();
|
|
813
|
-
}
|
|
814
|
-
function Ee(a = Date.now() / 1e3) {
|
|
815
|
-
let e = a + me;
|
|
816
|
-
e -= e % 300, e *= 1e7;
|
|
817
|
-
const t = new TextEncoder().encode(`${e.toFixed(0)}${J}`), i = ke(t), r = xe(t, i), s = new Uint8Array(8), n = new DataView(s.buffer);
|
|
818
|
-
return n.setUint32(0, r[0], !0), n.setUint32(4, r[1], !0), `${$(s)}-${$(i)}`;
|
|
819
|
-
}
|
|
820
|
-
function Be(a) {
|
|
821
|
-
const e = a;
|
|
822
|
-
e.__retiamV2Patched || (e.getSynthUrl = async () => {
|
|
823
|
-
const t = Array.from({ length: 32 }, () => Math.floor(Math.random() * 16).toString(16)).join(""), i = Ee();
|
|
824
|
-
return `${pe}?TrustedClientToken=${J}&Sec-MS-GEC=${i}&Sec-MS-GEC-Version=${fe}&ConnectionId=${t}`;
|
|
825
|
-
}, e.__retiamV2Patched = !0);
|
|
826
|
-
}
|
|
827
|
-
class Me {
|
|
200
|
+
class Z {
|
|
828
201
|
name = "msedge-tts";
|
|
829
202
|
_config;
|
|
830
203
|
_cache;
|
|
831
204
|
_isBrowser;
|
|
832
205
|
_nodeClients = [];
|
|
833
|
-
constructor(
|
|
206
|
+
constructor(t = {}) {
|
|
834
207
|
this._isBrowser = typeof window < "u" && typeof window.document < "u", this._config = {
|
|
835
|
-
cacheAudio:
|
|
836
|
-
maxCacheSize:
|
|
837
|
-
msedgeEndpoint:
|
|
838
|
-
}, this._cache = new
|
|
208
|
+
cacheAudio: t.cacheAudio !== !1,
|
|
209
|
+
maxCacheSize: t.maxCacheSize ?? 128,
|
|
210
|
+
msedgeEndpoint: t.msedgeEndpoint || "/api/tts/msedge"
|
|
211
|
+
}, this._cache = new C(this._config.maxCacheSize);
|
|
839
212
|
}
|
|
840
213
|
/**
|
|
841
214
|
* Microsoft Edge TTS is cloud-hosted and always ready immediately without local weight loading.
|
|
@@ -846,63 +219,63 @@ class Me {
|
|
|
846
219
|
/**
|
|
847
220
|
* Initializes provider configuration. No weight downloading required.
|
|
848
221
|
*/
|
|
849
|
-
async init(
|
|
850
|
-
|
|
222
|
+
async init(t) {
|
|
223
|
+
t?.msedgeEndpoint && (this._config.msedgeEndpoint = t.msedgeEndpoint), t?.cacheAudio !== void 0 && (this._config.cacheAudio = t.cacheAudio);
|
|
851
224
|
}
|
|
852
225
|
/**
|
|
853
226
|
* Synthesizes text into high-fidelity speech audio using Microsoft Edge neural voices.
|
|
854
227
|
*/
|
|
855
|
-
async synthesize(
|
|
856
|
-
const i =
|
|
228
|
+
async synthesize(t, e = {}) {
|
|
229
|
+
const i = t.trim(), s = e.voice || M, a = Math.max(0.25, Math.min(4, e.speed ?? 1));
|
|
857
230
|
if (!i)
|
|
858
|
-
return new
|
|
231
|
+
return new R({
|
|
859
232
|
text: "",
|
|
860
233
|
samples: new Float32Array(0),
|
|
861
234
|
sampleRate: 24e3,
|
|
862
|
-
voice:
|
|
863
|
-
speed:
|
|
235
|
+
voice: s,
|
|
236
|
+
speed: a
|
|
864
237
|
});
|
|
865
238
|
if (this._config.cacheAudio) {
|
|
866
|
-
const
|
|
867
|
-
if (
|
|
868
|
-
return
|
|
239
|
+
const n = this._cache.get(i, s, a);
|
|
240
|
+
if (n)
|
|
241
|
+
return n;
|
|
869
242
|
}
|
|
870
|
-
const
|
|
871
|
-
return this._config.cacheAudio && this._cache.set(i,
|
|
243
|
+
const r = this._isBrowser ? await this._synthesizeBrowser(i, s, a, e) : await this._synthesizeNode(i, s, a, e);
|
|
244
|
+
return this._config.cacheAudio && this._cache.set(i, s, a, r), r;
|
|
872
245
|
}
|
|
873
246
|
/**
|
|
874
247
|
* Node.js execution: directly calls the msedge-tts package in-process.
|
|
875
248
|
*/
|
|
876
|
-
async _synthesizeNode(
|
|
877
|
-
const { MsEdgeTTS:
|
|
878
|
-
|
|
879
|
-
const
|
|
880
|
-
await
|
|
249
|
+
async _synthesizeNode(t, e, i, s) {
|
|
250
|
+
const { MsEdgeTTS: a, OUTPUT_FORMAT: r } = await import("msedge-tts");
|
|
251
|
+
D(a);
|
|
252
|
+
const n = new a(), o = Math.round((i - 1) * 100), u = o >= 0 ? `+${o}%` : `${o}%`;
|
|
253
|
+
await n.setMetadata(e, r.AUDIO_24KHZ_96KBITRATE_MONO_MP3, {
|
|
881
254
|
wordBoundaryEnabled: !0,
|
|
882
255
|
sentenceBoundaryEnabled: !0
|
|
883
256
|
});
|
|
884
|
-
const
|
|
257
|
+
const h = {
|
|
885
258
|
rate: u
|
|
886
259
|
};
|
|
887
|
-
if (
|
|
888
|
-
if (typeof
|
|
889
|
-
|
|
890
|
-
else if (typeof
|
|
891
|
-
const
|
|
892
|
-
!isNaN(
|
|
260
|
+
if (s.pitch !== void 0 && (h.pitch = s.pitch), s.volume !== void 0 && s.volume !== null) {
|
|
261
|
+
if (typeof s.volume == "number")
|
|
262
|
+
h.volume = s.volume <= 1 && s.volume > 0 ? Math.round(s.volume * 100) : Math.round(s.volume);
|
|
263
|
+
else if (typeof s.volume == "string") {
|
|
264
|
+
const b = parseFloat(s.volume);
|
|
265
|
+
!isNaN(b) && !s.volume.includes("%") && !s.volume.startsWith("+") && !s.volume.startsWith("-") ? h.volume = b <= 1 && b > 0 ? Math.round(b * 100) : Math.round(b) : h.volume = s.volume;
|
|
893
266
|
}
|
|
894
267
|
}
|
|
895
|
-
const { audioStream:
|
|
896
|
-
|
|
268
|
+
const { audioStream: d, metadataStream: p } = n.toStream(t, h), f = [], x = [];
|
|
269
|
+
p && p.on("data", (b) => {
|
|
897
270
|
try {
|
|
898
|
-
const
|
|
899
|
-
if (Array.isArray(
|
|
900
|
-
for (const
|
|
901
|
-
if (
|
|
902
|
-
const
|
|
903
|
-
|
|
904
|
-
text:
|
|
905
|
-
offsetMs:
|
|
271
|
+
const A = b.toString(), S = JSON.parse(A);
|
|
272
|
+
if (Array.isArray(S?.Metadata)) {
|
|
273
|
+
for (const v of S.Metadata)
|
|
274
|
+
if (v.Type === "WordBoundary" && v.Data) {
|
|
275
|
+
const U = (v.Data.Offset || 0) / 1e4, z = (v.Data.Duration || 0) / 1e4, W = v.Data.text?.Text || "";
|
|
276
|
+
x.push({
|
|
277
|
+
text: W,
|
|
278
|
+
offsetMs: U,
|
|
906
279
|
durationMs: z,
|
|
907
280
|
boundaryType: "WordBoundary"
|
|
908
281
|
});
|
|
@@ -910,86 +283,86 @@ class Me {
|
|
|
910
283
|
}
|
|
911
284
|
} catch {
|
|
912
285
|
}
|
|
913
|
-
}), await new Promise((
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
}),
|
|
917
|
-
|
|
918
|
-
}),
|
|
919
|
-
|
|
286
|
+
}), await new Promise((b, A) => {
|
|
287
|
+
d.on("data", (S) => {
|
|
288
|
+
f.push(S);
|
|
289
|
+
}), d.on("end", () => {
|
|
290
|
+
b();
|
|
291
|
+
}), d.on("error", (S) => {
|
|
292
|
+
A(S);
|
|
920
293
|
});
|
|
921
294
|
});
|
|
922
|
-
const
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
),
|
|
926
|
-
return new
|
|
927
|
-
text:
|
|
928
|
-
rawBuffer:
|
|
295
|
+
const k = Buffer.concat(f), g = k.buffer.slice(
|
|
296
|
+
k.byteOffset,
|
|
297
|
+
k.byteOffset + k.byteLength
|
|
298
|
+
), m = F(new Uint8Array(g));
|
|
299
|
+
return new R({
|
|
300
|
+
text: t,
|
|
301
|
+
rawBuffer: g,
|
|
929
302
|
mimeType: "audio/mpeg",
|
|
930
|
-
samples: new Float32Array(
|
|
931
|
-
sampleRate:
|
|
932
|
-
duration:
|
|
933
|
-
durationMs:
|
|
934
|
-
voice:
|
|
303
|
+
samples: new Float32Array(m.totalSamples),
|
|
304
|
+
sampleRate: m.sampleRate,
|
|
305
|
+
duration: m.durationSec,
|
|
306
|
+
durationMs: m.durationMs,
|
|
307
|
+
voice: e,
|
|
935
308
|
speed: i,
|
|
936
|
-
wordBoundaries:
|
|
309
|
+
wordBoundaries: x.length > 0 ? x : void 0
|
|
937
310
|
});
|
|
938
311
|
}
|
|
939
312
|
/**
|
|
940
313
|
* Browser execution: invokes the Vite development server proxy endpoint.
|
|
941
314
|
*/
|
|
942
|
-
async _synthesizeBrowser(
|
|
943
|
-
const
|
|
315
|
+
async _synthesizeBrowser(t, e, i, s) {
|
|
316
|
+
const a = `${this._config.msedgeEndpoint}/synthesize`, r = await fetch(a, {
|
|
944
317
|
method: "POST",
|
|
945
318
|
headers: {
|
|
946
319
|
"Content-Type": "application/json"
|
|
947
320
|
},
|
|
948
321
|
body: JSON.stringify({
|
|
949
|
-
text:
|
|
950
|
-
voice:
|
|
322
|
+
text: t,
|
|
323
|
+
voice: e,
|
|
951
324
|
speed: i,
|
|
952
|
-
pitch:
|
|
953
|
-
volume:
|
|
325
|
+
pitch: s.pitch,
|
|
326
|
+
volume: s.volume
|
|
954
327
|
})
|
|
955
328
|
});
|
|
956
|
-
if (!
|
|
957
|
-
throw new Error(`[MsEdgeTTSProvider] Synthesis failed: HTTP ${
|
|
958
|
-
const
|
|
329
|
+
if (!r.ok)
|
|
330
|
+
throw new Error(`[MsEdgeTTSProvider] Synthesis failed: HTTP ${r.status} ${r.statusText}`);
|
|
331
|
+
const n = r.headers.get("X-Audio-Duration-Ms"), o = r.headers.get("X-Word-Boundaries");
|
|
959
332
|
let u;
|
|
960
333
|
if (o)
|
|
961
334
|
try {
|
|
962
335
|
u = JSON.parse(decodeURIComponent(o));
|
|
963
336
|
} catch {
|
|
964
337
|
}
|
|
965
|
-
const
|
|
966
|
-
let
|
|
967
|
-
const
|
|
968
|
-
if (
|
|
969
|
-
const
|
|
338
|
+
const h = await r.arrayBuffer();
|
|
339
|
+
let d = new Float32Array(0), p = 24e3, f = n ? parseFloat(n) : 0;
|
|
340
|
+
const x = window.AudioContext || window.webkitAudioContext;
|
|
341
|
+
if (x) {
|
|
342
|
+
const k = !!window.__retiam_audio_context, g = window.__retiam_audio_context || new x();
|
|
970
343
|
try {
|
|
971
|
-
const
|
|
972
|
-
|
|
973
|
-
} catch (
|
|
974
|
-
console.warn("[MsEdgeTTSProvider] AudioContext decode deferred, using raw MP3 buffer:",
|
|
344
|
+
const m = await g.decodeAudioData(h.slice(0));
|
|
345
|
+
d = m.getChannelData(0), p = m.sampleRate, f || (f = m.duration * 1e3);
|
|
346
|
+
} catch (m) {
|
|
347
|
+
console.warn("[MsEdgeTTSProvider] AudioContext decode deferred, using raw MP3 buffer:", m);
|
|
975
348
|
} finally {
|
|
976
|
-
!
|
|
349
|
+
!k && g && typeof g.close == "function" && g.close().catch(() => {
|
|
977
350
|
});
|
|
978
351
|
}
|
|
979
352
|
}
|
|
980
|
-
if (
|
|
981
|
-
const
|
|
982
|
-
|
|
353
|
+
if (d.length === 0 || !f) {
|
|
354
|
+
const k = F(new Uint8Array(h));
|
|
355
|
+
p = k.sampleRate, f || (f = k.durationMs);
|
|
983
356
|
}
|
|
984
|
-
return new
|
|
985
|
-
text:
|
|
986
|
-
rawBuffer:
|
|
357
|
+
return new R({
|
|
358
|
+
text: t,
|
|
359
|
+
rawBuffer: h,
|
|
987
360
|
mimeType: "audio/mpeg",
|
|
988
|
-
samples:
|
|
989
|
-
sampleRate:
|
|
990
|
-
duration:
|
|
991
|
-
durationMs:
|
|
992
|
-
voice:
|
|
361
|
+
samples: d,
|
|
362
|
+
sampleRate: p,
|
|
363
|
+
duration: f / 1e3,
|
|
364
|
+
durationMs: f,
|
|
365
|
+
voice: e,
|
|
993
366
|
speed: i,
|
|
994
367
|
wordBoundaries: u
|
|
995
368
|
});
|
|
@@ -997,34 +370,34 @@ class Me {
|
|
|
997
370
|
/**
|
|
998
371
|
* Progressively streams synthesized speech sentence by sentence.
|
|
999
372
|
*/
|
|
1000
|
-
async *stream(
|
|
1001
|
-
const i =
|
|
1002
|
-
for (let
|
|
1003
|
-
const
|
|
1004
|
-
|
|
373
|
+
async *stream(t, e = {}) {
|
|
374
|
+
const i = e.voice || M, s = Math.max(0.25, Math.min(4, e.speed ?? 1)), a = e.splitPattern || /([.!?;]+(?:\s+|$))/g, r = [], n = t.split(a);
|
|
375
|
+
for (let h = 0; h < n.length; h += 2) {
|
|
376
|
+
const d = (n[h] + (n[h + 1] || "")).trim();
|
|
377
|
+
d.length > 0 && r.push(d);
|
|
1005
378
|
}
|
|
1006
|
-
|
|
379
|
+
r.length === 0 && r.push(t.trim());
|
|
1007
380
|
let o = 0, u = 0;
|
|
1008
|
-
for (const
|
|
1009
|
-
const
|
|
1010
|
-
...
|
|
381
|
+
for (const h of r) {
|
|
382
|
+
const d = await this.synthesize(h, {
|
|
383
|
+
...e,
|
|
1011
384
|
voice: i,
|
|
1012
|
-
speed:
|
|
385
|
+
speed: s
|
|
1013
386
|
});
|
|
1014
387
|
yield {
|
|
1015
|
-
text:
|
|
388
|
+
text: h,
|
|
1016
389
|
phonemes: "",
|
|
1017
|
-
audio:
|
|
390
|
+
audio: d,
|
|
1018
391
|
chunkIndex: o++,
|
|
1019
392
|
startTimeMs: u
|
|
1020
|
-
}, u +=
|
|
393
|
+
}, u += d.durationMs;
|
|
1021
394
|
}
|
|
1022
395
|
}
|
|
1023
396
|
/**
|
|
1024
397
|
* Returns curated Microsoft Edge neural voices immediately.
|
|
1025
398
|
*/
|
|
1026
399
|
getVoices() {
|
|
1027
|
-
return
|
|
400
|
+
return L();
|
|
1028
401
|
}
|
|
1029
402
|
/**
|
|
1030
403
|
* Fetches the complete live catalog of all 320+ Microsoft Edge neural voices.
|
|
@@ -1032,15 +405,15 @@ class Me {
|
|
|
1032
405
|
async fetchVoices() {
|
|
1033
406
|
if (this._isBrowser)
|
|
1034
407
|
try {
|
|
1035
|
-
const
|
|
1036
|
-
if (
|
|
1037
|
-
const
|
|
1038
|
-
if (Array.isArray(
|
|
1039
|
-
return
|
|
408
|
+
const t = await fetch(`${this._config.msedgeEndpoint}/voices`);
|
|
409
|
+
if (t.ok) {
|
|
410
|
+
const e = await t.json();
|
|
411
|
+
if (Array.isArray(e))
|
|
412
|
+
return V(e), e;
|
|
1040
413
|
}
|
|
1041
414
|
} catch {
|
|
1042
415
|
}
|
|
1043
|
-
return
|
|
416
|
+
return P();
|
|
1044
417
|
}
|
|
1045
418
|
/**
|
|
1046
419
|
* Clears cached utterances.
|
|
@@ -1053,19 +426,19 @@ class Me {
|
|
|
1053
426
|
*/
|
|
1054
427
|
async dispose() {
|
|
1055
428
|
this.clearCache();
|
|
1056
|
-
for (const
|
|
429
|
+
for (const t of this._nodeClients)
|
|
1057
430
|
try {
|
|
1058
|
-
|
|
431
|
+
t.close();
|
|
1059
432
|
} catch {
|
|
1060
433
|
}
|
|
1061
434
|
this._nodeClients = [];
|
|
1062
435
|
}
|
|
1063
436
|
}
|
|
1064
|
-
class
|
|
437
|
+
class O {
|
|
1065
438
|
_provider;
|
|
1066
439
|
_config;
|
|
1067
|
-
constructor(
|
|
1068
|
-
this._config =
|
|
440
|
+
constructor(t = {}, e) {
|
|
441
|
+
this._config = t, this._provider = e ?? new Z(t);
|
|
1069
442
|
}
|
|
1070
443
|
/** The active speech provider. */
|
|
1071
444
|
get provider() {
|
|
@@ -1076,93 +449,93 @@ class Z {
|
|
|
1076
449
|
return this._provider.isReady;
|
|
1077
450
|
}
|
|
1078
451
|
/** Replaces the active provider instance. */
|
|
1079
|
-
setProvider(
|
|
1080
|
-
this._provider =
|
|
452
|
+
setProvider(t) {
|
|
453
|
+
this._provider = t;
|
|
1081
454
|
}
|
|
1082
455
|
/** Initializes the active provider. */
|
|
1083
|
-
async init(
|
|
1084
|
-
|
|
456
|
+
async init(t) {
|
|
457
|
+
t && (this._config = t), await this._provider.init(t ?? this._config);
|
|
1085
458
|
}
|
|
1086
459
|
/** Synthesizes text with the active provider. */
|
|
1087
|
-
async synthesize(
|
|
1088
|
-
return this._provider.synthesize(
|
|
460
|
+
async synthesize(t, e = {}) {
|
|
461
|
+
return this._provider.synthesize(t, e);
|
|
1089
462
|
}
|
|
1090
463
|
/** Streams synthesized audio sentence by sentence. */
|
|
1091
|
-
async *stream(
|
|
1092
|
-
yield* this._provider.stream(
|
|
464
|
+
async *stream(t, e = {}) {
|
|
465
|
+
yield* this._provider.stream(t, e);
|
|
1093
466
|
}
|
|
1094
467
|
/** Synthesizes and plays speech through a Scene or AudioManager. */
|
|
1095
|
-
async speak(
|
|
1096
|
-
const
|
|
1097
|
-
return { audio:
|
|
468
|
+
async speak(t, e, i = {}) {
|
|
469
|
+
const s = await this.synthesize(e, i), a = await s.play(t, i);
|
|
470
|
+
return { audio: s, durationMs: a };
|
|
1098
471
|
}
|
|
1099
472
|
/** Returns voices exposed by the active provider. */
|
|
1100
473
|
getVoices() {
|
|
1101
474
|
return this._provider.getVoices();
|
|
1102
475
|
}
|
|
1103
476
|
/** Finds a voice by ID, display name, or partial match. */
|
|
1104
|
-
findVoice(
|
|
1105
|
-
const
|
|
477
|
+
findVoice(t) {
|
|
478
|
+
const e = t.toLowerCase();
|
|
1106
479
|
return this._provider.getVoices().find(
|
|
1107
|
-
(i) => i.id.toLowerCase() ===
|
|
1108
|
-
) ??
|
|
480
|
+
(i) => i.id.toLowerCase() === e || i.name.toLowerCase() === e || i.id.toLowerCase().includes(e) || i.name.toLowerCase().includes(e)
|
|
481
|
+
) ?? N(t);
|
|
1109
482
|
}
|
|
1110
483
|
/** Releases provider resources and cached audio. */
|
|
1111
484
|
async dispose() {
|
|
1112
485
|
await this._provider.dispose();
|
|
1113
486
|
}
|
|
1114
487
|
}
|
|
1115
|
-
let
|
|
1116
|
-
function
|
|
1117
|
-
return
|
|
488
|
+
let E = null;
|
|
489
|
+
function w() {
|
|
490
|
+
return E || (E = new O()), E;
|
|
1118
491
|
}
|
|
1119
|
-
class
|
|
492
|
+
class T {
|
|
1120
493
|
/** Replaces the global client configuration and restores the built-in provider. */
|
|
1121
|
-
static configure(
|
|
1122
|
-
|
|
494
|
+
static configure(t) {
|
|
495
|
+
E = new O(t);
|
|
1123
496
|
}
|
|
1124
497
|
/** Initializes the global speech provider. */
|
|
1125
|
-
static async init(
|
|
1126
|
-
|
|
498
|
+
static async init(t) {
|
|
499
|
+
t && this.configure(t), await w().init(t);
|
|
1127
500
|
}
|
|
1128
501
|
/** Replaces the global provider instance. */
|
|
1129
|
-
static setProvider(
|
|
1130
|
-
|
|
502
|
+
static setProvider(t) {
|
|
503
|
+
w().setProvider(t);
|
|
1131
504
|
}
|
|
1132
505
|
/** Active global provider. */
|
|
1133
506
|
static get provider() {
|
|
1134
|
-
return
|
|
507
|
+
return w().provider;
|
|
1135
508
|
}
|
|
1136
509
|
/** Synthesizes text to speech. */
|
|
1137
|
-
static async synthesize(
|
|
1138
|
-
return
|
|
510
|
+
static async synthesize(t, e) {
|
|
511
|
+
return w().synthesize(t, e);
|
|
1139
512
|
}
|
|
1140
513
|
/** Explicit alias for Microsoft Edge neural synthesis. */
|
|
1141
|
-
static async msedge(
|
|
1142
|
-
return
|
|
514
|
+
static async msedge(t, e) {
|
|
515
|
+
return w().synthesize(t, e);
|
|
1143
516
|
}
|
|
1144
517
|
/** Streams synthesized speech sentence by sentence. */
|
|
1145
|
-
static async *stream(
|
|
1146
|
-
yield*
|
|
518
|
+
static async *stream(t, e) {
|
|
519
|
+
yield* w().stream(t, e);
|
|
1147
520
|
}
|
|
1148
521
|
/** Synthesizes and plays speech through a Scene or AudioManager. */
|
|
1149
|
-
static async speak(
|
|
1150
|
-
return
|
|
522
|
+
static async speak(t, e, i) {
|
|
523
|
+
return w().speak(t, e, i);
|
|
1151
524
|
}
|
|
1152
525
|
/** Returns the active provider's voices. */
|
|
1153
526
|
static getVoices() {
|
|
1154
|
-
return
|
|
527
|
+
return w().getVoices();
|
|
1155
528
|
}
|
|
1156
529
|
/** Finds a Microsoft Edge neural voice. */
|
|
1157
|
-
static findVoice(
|
|
1158
|
-
return
|
|
530
|
+
static findVoice(t) {
|
|
531
|
+
return w().findVoice(t);
|
|
1159
532
|
}
|
|
1160
533
|
/** Recommended default voice. */
|
|
1161
|
-
static DEFAULT_VOICE =
|
|
534
|
+
static DEFAULT_VOICE = M;
|
|
1162
535
|
/** Explicit provider-specific alias for the recommended default voice. */
|
|
1163
|
-
static DEFAULT_MSEDGE_VOICE =
|
|
536
|
+
static DEFAULT_MSEDGE_VOICE = M;
|
|
1164
537
|
}
|
|
1165
|
-
class
|
|
538
|
+
class Q extends j {
|
|
1166
539
|
voice;
|
|
1167
540
|
speed;
|
|
1168
541
|
animateSpeaking;
|
|
@@ -1174,13 +547,13 @@ class Fe extends te {
|
|
|
1174
547
|
_baseScaleX = 1;
|
|
1175
548
|
_baseScaleY = 1;
|
|
1176
549
|
_baseScaleZ = 1;
|
|
1177
|
-
constructor(
|
|
1178
|
-
super(), this.voice =
|
|
550
|
+
constructor(t = {}) {
|
|
551
|
+
super(), this.voice = t.voice ?? "en-US-JennyNeural", this.speed = t.speed ?? 1, this.animateSpeaking = t.animateSpeaking !== !1, this.pulseAmplitude = t.pulseAmplitude ?? 0.05, this.pulseFrequency = t.pulseFrequency ?? 4, this.onSpeechStart = t.onSpeechStart, this.onSpeechEnd = t.onSpeechEnd;
|
|
1179
552
|
}
|
|
1180
553
|
onInit() {
|
|
1181
554
|
if (this.entity?.transform) {
|
|
1182
|
-
const
|
|
1183
|
-
this._baseScaleX =
|
|
555
|
+
const t = this.entity.transform.getScale();
|
|
556
|
+
this._baseScaleX = t.x, this._baseScaleY = t.y, this._baseScaleZ = t.z;
|
|
1184
557
|
}
|
|
1185
558
|
}
|
|
1186
559
|
/**
|
|
@@ -1196,23 +569,23 @@ class Fe extends te {
|
|
|
1196
569
|
* @param overrides Voice and playback option overrides.
|
|
1197
570
|
* @returns Synthesized [[TTSAudioResult]] and total speech duration in milliseconds.
|
|
1198
571
|
*/
|
|
1199
|
-
async speak(
|
|
1200
|
-
const i = this.entity?.scene,
|
|
572
|
+
async speak(t, e = {}) {
|
|
573
|
+
const i = this.entity?.scene, s = e.voice ?? this.voice, a = e.speed ?? this.speed;
|
|
1201
574
|
if (this.entity?.transform) {
|
|
1202
575
|
const o = this.entity.transform.getScale();
|
|
1203
576
|
this._baseScaleX = o.x, this._baseScaleY = o.y, this._baseScaleZ = o.z;
|
|
1204
577
|
}
|
|
1205
|
-
const
|
|
1206
|
-
this._isSpeaking = !0, this.onSpeechStart?.(
|
|
1207
|
-
const
|
|
1208
|
-
return this._isSpeaking = !1, this._restoreBaseScale(), this.onSpeechEnd?.(
|
|
578
|
+
const r = await T.synthesize(t, { voice: s, speed: a, ...e });
|
|
579
|
+
this._isSpeaking = !0, this.onSpeechStart?.(t, r);
|
|
580
|
+
const n = await r.play(i, e);
|
|
581
|
+
return this._isSpeaking = !1, this._restoreBaseScale(), this.onSpeechEnd?.(t), { audio: r, durationMs: n };
|
|
1209
582
|
}
|
|
1210
|
-
update(
|
|
583
|
+
update(t, e) {
|
|
1211
584
|
if (!(!this.enabled || !this.entity?.transform) && this._isSpeaking && this.animateSpeaking) {
|
|
1212
|
-
const i =
|
|
585
|
+
const i = t / 1e3 * this.pulseFrequency * Math.PI * 2, s = 1 + Math.sin(i) * this.pulseAmplitude;
|
|
1213
586
|
this.entity.transform.setScale([
|
|
1214
|
-
this._baseScaleX *
|
|
1215
|
-
this._baseScaleY *
|
|
587
|
+
this._baseScaleX * s,
|
|
588
|
+
this._baseScaleY * s,
|
|
1216
589
|
this._baseScaleZ
|
|
1217
590
|
]), this.entity.version++;
|
|
1218
591
|
}
|
|
@@ -1228,14 +601,14 @@ class Fe extends te {
|
|
|
1228
601
|
this._isSpeaking = !1, this._restoreBaseScale();
|
|
1229
602
|
}
|
|
1230
603
|
}
|
|
1231
|
-
const
|
|
604
|
+
const q = {
|
|
1232
605
|
obsidian: {
|
|
1233
606
|
fontSize: 0.38,
|
|
1234
|
-
textColor:
|
|
607
|
+
textColor: l("#F8FAFC"),
|
|
1235
608
|
textOpacity: 1,
|
|
1236
|
-
backdropColor:
|
|
609
|
+
backdropColor: l("#060913"),
|
|
1237
610
|
backdropOpacity: 0.85,
|
|
1238
|
-
strokeColor: new
|
|
611
|
+
strokeColor: new y(0.22, 0.74, 0.97, 0.35),
|
|
1239
612
|
strokeWidth: 0.02,
|
|
1240
613
|
cornerRadius: 0.22,
|
|
1241
614
|
pillShape: !1,
|
|
@@ -1246,11 +619,11 @@ const Ne = {
|
|
|
1246
619
|
},
|
|
1247
620
|
pill: {
|
|
1248
621
|
fontSize: 0.38,
|
|
1249
|
-
textColor:
|
|
622
|
+
textColor: l("#FFFFFF"),
|
|
1250
623
|
textOpacity: 1,
|
|
1251
|
-
backdropColor:
|
|
624
|
+
backdropColor: l("#080D1A"),
|
|
1252
625
|
backdropOpacity: 0.88,
|
|
1253
|
-
strokeColor: new
|
|
626
|
+
strokeColor: new y(0.38, 0.52, 0.75, 0.4),
|
|
1254
627
|
strokeWidth: 0.02,
|
|
1255
628
|
pillShape: !0,
|
|
1256
629
|
padding: [0.7, 0.28],
|
|
@@ -1260,11 +633,11 @@ const Ne = {
|
|
|
1260
633
|
},
|
|
1261
634
|
minimal: {
|
|
1262
635
|
fontSize: 0.38,
|
|
1263
|
-
textColor:
|
|
636
|
+
textColor: l("#F1F5F9"),
|
|
1264
637
|
textOpacity: 1,
|
|
1265
|
-
backdropColor:
|
|
638
|
+
backdropColor: l("#090D16"),
|
|
1266
639
|
backdropOpacity: 0.8,
|
|
1267
|
-
strokeColor:
|
|
640
|
+
strokeColor: y.NONE,
|
|
1268
641
|
strokeWidth: 0,
|
|
1269
642
|
cornerRadius: 0.16,
|
|
1270
643
|
pillShape: !1,
|
|
@@ -1275,11 +648,11 @@ const Ne = {
|
|
|
1275
648
|
},
|
|
1276
649
|
broadcast: {
|
|
1277
650
|
fontSize: 0.38,
|
|
1278
|
-
textColor:
|
|
651
|
+
textColor: l("#FFFFFF"),
|
|
1279
652
|
textOpacity: 1,
|
|
1280
|
-
backdropColor:
|
|
653
|
+
backdropColor: l("#000000"),
|
|
1281
654
|
backdropOpacity: 0.92,
|
|
1282
|
-
strokeColor:
|
|
655
|
+
strokeColor: y.NONE,
|
|
1283
656
|
strokeWidth: 0,
|
|
1284
657
|
cornerRadius: 0.08,
|
|
1285
658
|
pillShape: !1,
|
|
@@ -1290,11 +663,11 @@ const Ne = {
|
|
|
1290
663
|
},
|
|
1291
664
|
neon: {
|
|
1292
665
|
fontSize: 0.38,
|
|
1293
|
-
textColor:
|
|
666
|
+
textColor: l("#E0F2FE"),
|
|
1294
667
|
textOpacity: 1,
|
|
1295
|
-
backdropColor:
|
|
668
|
+
backdropColor: l("#030712"),
|
|
1296
669
|
backdropOpacity: 0.92,
|
|
1297
|
-
strokeColor:
|
|
670
|
+
strokeColor: l("#00F0FF"),
|
|
1298
671
|
strokeWidth: 0.025,
|
|
1299
672
|
cornerRadius: 0.24,
|
|
1300
673
|
pillShape: !1,
|
|
@@ -1305,11 +678,11 @@ const Ne = {
|
|
|
1305
678
|
},
|
|
1306
679
|
glass: {
|
|
1307
680
|
fontSize: 0.38,
|
|
1308
|
-
textColor:
|
|
681
|
+
textColor: l("#FFFFFF"),
|
|
1309
682
|
textOpacity: 1,
|
|
1310
|
-
backdropColor: new
|
|
683
|
+
backdropColor: new y(0.05, 0.09, 0.15, 0.65),
|
|
1311
684
|
backdropOpacity: 0.65,
|
|
1312
|
-
strokeColor: new
|
|
685
|
+
strokeColor: new y(1, 1, 1, 0.25),
|
|
1313
686
|
strokeWidth: 0.015,
|
|
1314
687
|
cornerRadius: 0.25,
|
|
1315
688
|
pillShape: !1,
|
|
@@ -1320,11 +693,11 @@ const Ne = {
|
|
|
1320
693
|
},
|
|
1321
694
|
light: {
|
|
1322
695
|
fontSize: 0.38,
|
|
1323
|
-
textColor:
|
|
696
|
+
textColor: l("#0F172A"),
|
|
1324
697
|
textOpacity: 1,
|
|
1325
|
-
backdropColor:
|
|
698
|
+
backdropColor: l("#F8FAFC"),
|
|
1326
699
|
backdropOpacity: 0.92,
|
|
1327
|
-
strokeColor: new
|
|
700
|
+
strokeColor: new y(0.39, 0.45, 0.55, 0.25),
|
|
1328
701
|
strokeWidth: 0.015,
|
|
1329
702
|
cornerRadius: 0.2,
|
|
1330
703
|
pillShape: !1,
|
|
@@ -1334,18 +707,18 @@ const Ne = {
|
|
|
1334
707
|
showBackdrop: !0
|
|
1335
708
|
}
|
|
1336
709
|
};
|
|
1337
|
-
function
|
|
1338
|
-
return
|
|
710
|
+
function _(c, t) {
|
|
711
|
+
return c ? typeof c == "string" ? l(c) : c : t;
|
|
1339
712
|
}
|
|
1340
|
-
class
|
|
713
|
+
class tt extends H {
|
|
1341
714
|
_textEntity;
|
|
1342
715
|
_backdrop = null;
|
|
1343
716
|
_fontSize = 0.38;
|
|
1344
|
-
_textColor =
|
|
717
|
+
_textColor = l("#F8FAFC");
|
|
1345
718
|
_textOpacity = 1;
|
|
1346
|
-
_backdropColor =
|
|
719
|
+
_backdropColor = l("#060913");
|
|
1347
720
|
_backdropOpacity = 0.85;
|
|
1348
|
-
_strokeColor = new
|
|
721
|
+
_strokeColor = new y(0.22, 0.74, 0.97, 0.35);
|
|
1349
722
|
_strokeWidth = 0.02;
|
|
1350
723
|
_showBorder = !0;
|
|
1351
724
|
_cornerRadius = 0.22;
|
|
@@ -1356,15 +729,15 @@ class Re extends ie {
|
|
|
1356
729
|
_maxLineChars = 65;
|
|
1357
730
|
_lineHeight = 1.35;
|
|
1358
731
|
_clearTimeout = null;
|
|
1359
|
-
constructor(
|
|
732
|
+
constructor(t = {}) {
|
|
1360
733
|
super();
|
|
1361
|
-
const
|
|
1362
|
-
this._textEntity = new
|
|
734
|
+
const e = t.zIndex ?? 999;
|
|
735
|
+
this._textEntity = new I("", {
|
|
1363
736
|
fontSize: this._fontSize,
|
|
1364
737
|
fill: this._textColor,
|
|
1365
|
-
anchor:
|
|
1366
|
-
}), this._textEntity.paint.z_index =
|
|
1367
|
-
const i =
|
|
738
|
+
anchor: $
|
|
739
|
+
}), this._textEntity.paint.z_index = e + 1, this._backdrop = new X(2, 1, { cornerRadius: this._cornerRadius }), this._backdrop.paint.fill = this._backdropColor, this._backdrop.paint.stroke = this._strokeColor, this._backdrop.paint.strokeWidth = this._strokeWidth, this._backdrop.paint.z_index = e, this._backdrop.paint.opacity = 0, this.add(this._backdrop), this.add(this._textEntity), this.paint.z_index = e, this.applyOptions(t);
|
|
740
|
+
const i = t.bottomOffset ?? -5;
|
|
1368
741
|
this.transform.position.set([0, i, 0]);
|
|
1369
742
|
}
|
|
1370
743
|
/** Access the underlying SDFText entity for advanced low-level styling */
|
|
@@ -1378,75 +751,75 @@ class Re extends ie {
|
|
|
1378
751
|
/**
|
|
1379
752
|
* Applies a complete configuration options object or partial updates.
|
|
1380
753
|
*/
|
|
1381
|
-
applyOptions(
|
|
1382
|
-
const i = { ...
|
|
1383
|
-
return i.fontSize !== void 0 && (this._fontSize = i.fontSize, this._textEntity.fontSize = i.fontSize), i.textColor !== void 0 && (this._textColor =
|
|
754
|
+
applyOptions(t = {}) {
|
|
755
|
+
const i = { ...t.preset ? q[t.preset] : {}, ...t };
|
|
756
|
+
return i.fontSize !== void 0 && (this._fontSize = i.fontSize, this._textEntity.fontSize = i.fontSize), i.textColor !== void 0 && (this._textColor = _(i.textColor, this._textColor), this._textEntity.paint.fill = this._textColor), i.textOpacity !== void 0 && (this._textOpacity = i.textOpacity), i.backdropColor !== void 0 && (this._backdropColor = _(i.backdropColor, this._backdropColor)), i.backdropOpacity !== void 0 && (this._backdropOpacity = i.backdropOpacity), i.strokeColor !== void 0 && (this._strokeColor = _(i.strokeColor, this._strokeColor)), i.strokeWidth !== void 0 && (this._strokeWidth = i.strokeWidth), i.showBorder !== void 0 && (this._showBorder = i.showBorder), i.cornerRadius !== void 0 && (this._cornerRadius = i.cornerRadius), i.pillShape !== void 0 && (this._pillShape = i.pillShape), i.showBackdrop !== void 0 && (this._showBackdrop = i.showBackdrop), i.padding !== void 0 && (typeof i.padding == "number" ? this._padding = [i.padding, i.padding] : Array.isArray(i.padding) && (this._padding = [i.padding[0], i.padding[1]])), i.maxWidth !== void 0 && (this._maxWidth = i.maxWidth), i.maxLineChars !== void 0 && (this._maxLineChars = Math.max(15, i.maxLineChars)), i.lineHeight !== void 0 && (this._lineHeight = i.lineHeight), i.bottomOffset !== void 0 && this.setBottomOffset(i.bottomOffset), this._textEntity.text && this._updateBackdropDimensions(this._textEntity.text), this.version++, this;
|
|
1384
757
|
}
|
|
1385
758
|
/** Set an aesthetic preset theme */
|
|
1386
|
-
setPreset(
|
|
1387
|
-
return this.applyOptions({ preset:
|
|
759
|
+
setPreset(t) {
|
|
760
|
+
return this.applyOptions({ preset: t });
|
|
1388
761
|
}
|
|
1389
762
|
/** Set the corner radius of the backdrop pill without distortion */
|
|
1390
|
-
setCornerRadius(
|
|
1391
|
-
return this._cornerRadius =
|
|
763
|
+
setCornerRadius(t) {
|
|
764
|
+
return this._cornerRadius = t, this._pillShape = !1, this._textEntity.text && this._updateBackdropDimensions(this._textEntity.text), this;
|
|
1392
765
|
}
|
|
1393
766
|
/** Enable or disable stadium pill shape (semicircular ends where cornerRadius = height / 2) */
|
|
1394
|
-
setPillShape(
|
|
1395
|
-
return this._pillShape =
|
|
767
|
+
setPillShape(t = !0) {
|
|
768
|
+
return this._pillShape = t, this._textEntity.text && this._updateBackdropDimensions(this._textEntity.text), this;
|
|
1396
769
|
}
|
|
1397
770
|
/** Set the inner horizontal and vertical padding around the subtitle text */
|
|
1398
|
-
setPadding(
|
|
1399
|
-
return this._padding = [
|
|
771
|
+
setPadding(t, e = t) {
|
|
772
|
+
return this._padding = [t, e], this._textEntity.text && this._updateBackdropDimensions(this._textEntity.text), this;
|
|
1400
773
|
}
|
|
1401
774
|
/** Configure backdrop fill color and opacity */
|
|
1402
|
-
setBackdropColor(
|
|
1403
|
-
return this._backdropColor =
|
|
775
|
+
setBackdropColor(t, e) {
|
|
776
|
+
return this._backdropColor = _(t, this._backdropColor), e !== void 0 && (this._backdropOpacity = Math.max(0, Math.min(1, e))), this._backdrop && (this._backdrop.paint.fill = this._backdropColor, this._textEntity.text && (this._backdrop.paint.opacity = this._backdropOpacity), this._backdrop.invalidate()), this;
|
|
1404
777
|
}
|
|
1405
|
-
setStroke(
|
|
1406
|
-
return typeof
|
|
778
|
+
setStroke(t, e) {
|
|
779
|
+
return typeof t == "number" ? (this._strokeWidth = t, this._showBorder = t > 0, e !== void 0 && (typeof e == "string" || e instanceof y) && (this._strokeColor = _(e, this._strokeColor))) : (this._strokeColor = _(t, this._strokeColor), typeof e == "number" && (this._strokeWidth = e, this._showBorder = e > 0)), this._backdrop && (this._backdrop.paint.stroke = this._strokeColor, this._backdrop.paint.strokeWidth = this._strokeWidth, this._backdrop.invalidate()), this;
|
|
1407
780
|
}
|
|
1408
781
|
/** Set backdrop border stroke color */
|
|
1409
|
-
setStrokeColor(
|
|
1410
|
-
return this._strokeColor =
|
|
782
|
+
setStrokeColor(t) {
|
|
783
|
+
return this._strokeColor = _(t, this._strokeColor), this._backdrop && (this._backdrop.paint.stroke = this._strokeColor, this._backdrop.invalidate()), this;
|
|
1411
784
|
}
|
|
1412
785
|
/** Set backdrop border stroke width */
|
|
1413
|
-
setStrokeWidth(
|
|
1414
|
-
return this._strokeWidth =
|
|
786
|
+
setStrokeWidth(t) {
|
|
787
|
+
return this._strokeWidth = t, this._showBorder = t > 0, this._backdrop && (this._backdrop.paint.strokeWidth = this._strokeWidth, this._backdrop.invalidate()), this;
|
|
1415
788
|
}
|
|
1416
789
|
/** Configure subtitle typography (font color and world unit font size) */
|
|
1417
|
-
setTextColor(
|
|
1418
|
-
return this._textColor =
|
|
790
|
+
setTextColor(t, e = 1) {
|
|
791
|
+
return this._textColor = _(t, this._textColor), this._textOpacity = e, this._textEntity.paint.fill = this._textColor, this._textEntity.paint.opacity = e, this.version++, this;
|
|
1419
792
|
}
|
|
1420
793
|
/** Set subtitle font size in world units */
|
|
1421
|
-
setFontSize(
|
|
1422
|
-
return
|
|
794
|
+
setFontSize(t) {
|
|
795
|
+
return t > 0 && (this._fontSize = t, this._textEntity.fontSize = t, this._textEntity.text && this._updateBackdropDimensions(this._textEntity.text)), this;
|
|
1423
796
|
}
|
|
1424
797
|
/** Configure backdrop visual styling (colors, stroke border, corner radius) */
|
|
1425
|
-
setBackdropStyle(
|
|
1426
|
-
return this._backdropColor =
|
|
798
|
+
setBackdropStyle(t, e, i, s) {
|
|
799
|
+
return this._backdropColor = _(t, this._backdropColor), e !== void 0 && (this._strokeColor = _(e, this._strokeColor), this._showBorder = !0), i !== void 0 && (this._strokeWidth = i, this._showBorder = i > 0), s !== void 0 && (this._cornerRadius = s, this._pillShape = !1), this._textEntity.text && this._updateBackdropDimensions(this._textEntity.text), this.version++, this;
|
|
1427
800
|
}
|
|
1428
801
|
/** Configure subtitle typography */
|
|
1429
|
-
setTextStyle(
|
|
1430
|
-
return this._textColor =
|
|
802
|
+
setTextStyle(t, e) {
|
|
803
|
+
return this._textColor = _(t, this._textColor), this._textEntity.paint.fill = this._textColor, e !== void 0 && e > 0 && (this._fontSize = e, this._textEntity.fontSize = e), this._textEntity.text && this._updateBackdropDimensions(this._textEntity.text), this.version++, this;
|
|
1431
804
|
}
|
|
1432
805
|
/** Set maximum characters per line before word-wrapping occurs */
|
|
1433
|
-
setMaxLineChars(
|
|
1434
|
-
return this._maxLineChars = Math.max(15,
|
|
806
|
+
setMaxLineChars(t) {
|
|
807
|
+
return this._maxLineChars = Math.max(15, t), this;
|
|
1435
808
|
}
|
|
1436
809
|
/** Set maximum bounding box width in world units */
|
|
1437
|
-
setMaxWidth(
|
|
1438
|
-
return this._maxWidth =
|
|
810
|
+
setMaxWidth(t) {
|
|
811
|
+
return this._maxWidth = t, this;
|
|
1439
812
|
}
|
|
1440
813
|
/** Positions the subtitles at the bottom center with a custom Y world coordinate */
|
|
1441
|
-
setBottomOffset(
|
|
1442
|
-
return this.transform.position.set([0,
|
|
814
|
+
setBottomOffset(t) {
|
|
815
|
+
return this.transform.position.set([0, t, 0]), this;
|
|
1443
816
|
}
|
|
1444
817
|
/**
|
|
1445
818
|
* Computes safe corner radius: clamped so circular arcs never self-intersect,
|
|
1446
819
|
* or computes stadium capsule radius when pillShape is enabled.
|
|
1447
820
|
*/
|
|
1448
|
-
_getEffectiveCornerRadius(
|
|
1449
|
-
const i = Math.min(
|
|
821
|
+
_getEffectiveCornerRadius(t, e) {
|
|
822
|
+
const i = Math.min(t, e) / 2;
|
|
1450
823
|
return this._pillShape ? i : typeof this._cornerRadius == "number" ? Math.max(0, Math.min(this._cornerRadius, i)) : Array.isArray(this._cornerRadius) ? [
|
|
1451
824
|
Math.max(0, Math.min(this._cornerRadius[0], i)),
|
|
1452
825
|
Math.max(0, Math.min(this._cornerRadius[1], i)),
|
|
@@ -1458,48 +831,48 @@ class Re extends ie {
|
|
|
1458
831
|
* Internal geometry reflow: updates backdrop width & height using genuine Rect
|
|
1459
832
|
* geometry regeneration (Rect.sync()) to preserve pristine, circular corner arcs.
|
|
1460
833
|
*/
|
|
1461
|
-
_updateBackdropDimensions(
|
|
834
|
+
_updateBackdropDimensions(t) {
|
|
1462
835
|
if (!this._backdrop) return;
|
|
1463
|
-
if (!this._showBackdrop || !
|
|
836
|
+
if (!this._showBackdrop || !t || t.trim().length === 0) {
|
|
1464
837
|
this._backdrop.paint.opacity = 0, this._backdrop.invalidate();
|
|
1465
838
|
return;
|
|
1466
839
|
}
|
|
1467
|
-
const
|
|
1468
|
-
let
|
|
1469
|
-
if (
|
|
1470
|
-
const
|
|
840
|
+
const e = this._textEntity.getGroupLocalAABB(), i = e.isEmpty() ? 0 : e.size.x, s = e.isEmpty() ? 0 : e.size.y, [a, r] = this._padding;
|
|
841
|
+
let n = i, o = s;
|
|
842
|
+
if (n <= 0.1 || o <= 0.1) {
|
|
843
|
+
const p = t.split(`
|
|
1471
844
|
`);
|
|
1472
|
-
|
|
845
|
+
n = Math.max(...p.map((x) => x.length)) * (this._fontSize * 0.44), o = p.length * (this._fontSize * this._lineHeight);
|
|
1473
846
|
}
|
|
1474
|
-
const u = Math.max(2.4, Math.min(this._maxWidth,
|
|
1475
|
-
this._backdrop.transform.setScale([1, 1, 1]), this._backdrop.width = u, this._backdrop.height =
|
|
847
|
+
const u = Math.max(2.4, Math.min(this._maxWidth, n + a * 2)), h = o + r * 2, d = this._getEffectiveCornerRadius(u, h);
|
|
848
|
+
this._backdrop.transform.setScale([1, 1, 1]), this._backdrop.width = u, this._backdrop.height = h, this._backdrop.cornerRadius = d, this._backdrop.paint.fill = this._backdropColor, this._backdrop.paint.stroke = this._showBorder ? this._strokeColor : y.NONE, this._backdrop.paint.strokeWidth = this._showBorder ? this._strokeWidth : 0, this._backdrop.paint.opacity = this._backdropOpacity, this._backdrop.invalidate();
|
|
1476
849
|
}
|
|
1477
850
|
/**
|
|
1478
851
|
* Displays a subtitle sentence, formatting lines with word-wrapping and
|
|
1479
852
|
* reflowing the backdrop pill with true circular corner arcs.
|
|
1480
853
|
*/
|
|
1481
|
-
showText(
|
|
854
|
+
showText(t, e) {
|
|
1482
855
|
this._clearTimeout && (clearTimeout(this._clearTimeout), this._clearTimeout = null);
|
|
1483
|
-
const i =
|
|
1484
|
-
let
|
|
856
|
+
const i = t.trim();
|
|
857
|
+
let s = i;
|
|
1485
858
|
if (i.length > this._maxLineChars) {
|
|
1486
|
-
const
|
|
1487
|
-
let
|
|
1488
|
-
for (const o of
|
|
1489
|
-
(
|
|
1490
|
-
|
|
859
|
+
const a = i.split(" "), r = [];
|
|
860
|
+
let n = "";
|
|
861
|
+
for (const o of a)
|
|
862
|
+
(n + " " + o).trim().length > this._maxLineChars ? (n && r.push(n), n = o) : n = n ? n + " " + o : o;
|
|
863
|
+
n && r.push(n), s = r.join(`
|
|
1491
864
|
`);
|
|
1492
865
|
}
|
|
1493
|
-
return this._textEntity.text =
|
|
866
|
+
return this._textEntity.text = s, this._textEntity.paint.opacity = this._textOpacity, this._updateBackdropDimensions(s), this.version++, e && e > 0 && (this._clearTimeout = setTimeout(() => {
|
|
1494
867
|
this.clear();
|
|
1495
|
-
},
|
|
868
|
+
}, e)), this;
|
|
1496
869
|
}
|
|
1497
870
|
/**
|
|
1498
871
|
* Synchronizes this subtitle banner with a [[TTSAudioResult]], displaying the spoken text
|
|
1499
872
|
* for the duration of the utterance and clearing on finish.
|
|
1500
873
|
*/
|
|
1501
|
-
syncWithAudio(
|
|
1502
|
-
return this.showText(
|
|
874
|
+
syncWithAudio(t) {
|
|
875
|
+
return this.showText(t.text, t.durationMs);
|
|
1503
876
|
}
|
|
1504
877
|
/**
|
|
1505
878
|
* Immediately clears and hides the subtitle banner.
|
|
@@ -1508,7 +881,7 @@ class Re extends ie {
|
|
|
1508
881
|
return this._clearTimeout && (clearTimeout(this._clearTimeout), this._clearTimeout = null), this._textEntity.text = "", this._textEntity.paint.opacity = 0, this._backdrop && (this._backdrop.paint.opacity = 0, this._backdrop.invalidate()), this.version++, this;
|
|
1509
882
|
}
|
|
1510
883
|
}
|
|
1511
|
-
class
|
|
884
|
+
class et extends K {
|
|
1512
885
|
text;
|
|
1513
886
|
voice;
|
|
1514
887
|
speed;
|
|
@@ -1521,9 +894,9 @@ class De extends ne {
|
|
|
1521
894
|
_audioResult = null;
|
|
1522
895
|
_isStarted = !1;
|
|
1523
896
|
_baseScale = [1, 1, 1];
|
|
1524
|
-
constructor(
|
|
1525
|
-
super(
|
|
1526
|
-
const i =
|
|
897
|
+
constructor(t, e = {}) {
|
|
898
|
+
super(e), this.text = t, this.voice = e.voice ?? "en-US-JennyNeural", this.speed = e.speed ?? 1, this.pitch = e.pitch, this.subtitles = e.subtitles, this.targetEntity = e.entity, this.pulseAmplitude = e.pulseAmplitude ?? 0.05, this.duckingRatio = e.duckingRatio ?? 0.25, this.volume = e.volume ?? 1;
|
|
899
|
+
const i = t.trim().split(/\s+/).length;
|
|
1527
900
|
this.duration = Math.max(1e3, i * 420 * (1 / this.speed));
|
|
1528
901
|
}
|
|
1529
902
|
/**
|
|
@@ -1531,25 +904,29 @@ class De extends ne {
|
|
|
1531
904
|
*/
|
|
1532
905
|
prepare() {
|
|
1533
906
|
if (this.targetEntity?.transform) {
|
|
1534
|
-
const
|
|
1535
|
-
this._baseScale = [
|
|
907
|
+
const t = this.targetEntity.transform.getScale();
|
|
908
|
+
this._baseScale = [t.x, t.y, t.z];
|
|
1536
909
|
}
|
|
1537
910
|
}
|
|
1538
911
|
/**
|
|
1539
912
|
* Synthesizes audio ahead of time and locks exact duration.
|
|
1540
913
|
*/
|
|
1541
914
|
async prepareAudio() {
|
|
1542
|
-
return this._audioResult || (this._audioResult = await
|
|
915
|
+
return this._audioResult || (this._audioResult = await T.synthesize(this.text, {
|
|
1543
916
|
voice: this.voice,
|
|
1544
917
|
speed: this.speed,
|
|
1545
918
|
pitch: this.pitch,
|
|
1546
919
|
volume: this.volume
|
|
1547
920
|
}), this.duration = this._audioResult.durationMs), this._audioResult;
|
|
1548
921
|
}
|
|
1549
|
-
update(
|
|
922
|
+
update(t) {
|
|
1550
923
|
if (this.paused) return !1;
|
|
1551
|
-
if (this.
|
|
1552
|
-
|
|
924
|
+
if (this.delay > 0) {
|
|
925
|
+
if (this.delay -= t, this.delay > 0) return !1;
|
|
926
|
+
t = -this.delay, this.delay = 0;
|
|
927
|
+
}
|
|
928
|
+
if (this._isStarted || (this._isStarted = !0, this._beginPlayback()), this.elapsed += t, this.targetEntity?.transform) {
|
|
929
|
+
const e = this.elapsed / 1e3 * 4 * Math.PI * 2, i = 1 + Math.sin(e) * this.pulseAmplitude;
|
|
1553
930
|
this.targetEntity.transform.setScale([
|
|
1554
931
|
this._baseScale[0] * i,
|
|
1555
932
|
this._baseScale[1] * i,
|
|
@@ -1563,10 +940,10 @@ class De extends ne {
|
|
|
1563
940
|
const i = this.targetEntity.transform.getScale();
|
|
1564
941
|
this._baseScale = [i.x, i.y, i.z];
|
|
1565
942
|
}
|
|
1566
|
-
const
|
|
1567
|
-
this.subtitles && this.subtitles.syncWithAudio(
|
|
1568
|
-
const
|
|
1569
|
-
await
|
|
943
|
+
const t = await this.prepareAudio();
|
|
944
|
+
this.subtitles && this.subtitles.syncWithAudio(t);
|
|
945
|
+
const e = this.targetEntity?.scene;
|
|
946
|
+
await t.play(e, {
|
|
1570
947
|
duckingRatio: this.duckingRatio,
|
|
1571
948
|
volume: this.volume
|
|
1572
949
|
});
|
|
@@ -1575,38 +952,38 @@ class De extends ne {
|
|
|
1575
952
|
this.targetEntity?.transform && (this.targetEntity.transform.setScale(this._baseScale), this.targetEntity.version++);
|
|
1576
953
|
}
|
|
1577
954
|
}
|
|
1578
|
-
async function
|
|
1579
|
-
const i =
|
|
955
|
+
async function it(c, t, e = {}) {
|
|
956
|
+
const i = c?.audio || c;
|
|
1580
957
|
i && typeof i.awaitUnlock == "function" && await i.awaitUnlock();
|
|
1581
|
-
const
|
|
1582
|
-
voice:
|
|
1583
|
-
speed:
|
|
1584
|
-
pitch:
|
|
1585
|
-
volume:
|
|
958
|
+
const s = await T.synthesize(t, {
|
|
959
|
+
voice: e.voice,
|
|
960
|
+
speed: e.speed ?? 1,
|
|
961
|
+
pitch: e.pitch,
|
|
962
|
+
volume: e.volume
|
|
1586
963
|
});
|
|
1587
|
-
return
|
|
1588
|
-
duckingRatio:
|
|
1589
|
-
volume:
|
|
1590
|
-
}),
|
|
964
|
+
return e.subtitles && e.subtitles.syncWithAudio(s), s.play(i, {
|
|
965
|
+
duckingRatio: e.duckingRatio ?? 0.25,
|
|
966
|
+
volume: e.volume ?? 1
|
|
967
|
+
}), c && typeof c.wait == "function" && await c.wait(s.durationMs), s;
|
|
1591
968
|
}
|
|
1592
969
|
export {
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
970
|
+
M as DEFAULT_MSEDGE_VOICE,
|
|
971
|
+
rt as MSEDGE_VOICES,
|
|
972
|
+
Z as MsEdgeTTSProvider,
|
|
973
|
+
q as SUBTITLE_PRESETS,
|
|
974
|
+
et as Speak,
|
|
975
|
+
tt as Subtitles,
|
|
976
|
+
T as TTS,
|
|
977
|
+
R as TTSAudio,
|
|
978
|
+
C as TTSCache,
|
|
979
|
+
O as TTSClient,
|
|
980
|
+
Q as TTSNarrationComponent,
|
|
981
|
+
Y as encodeWAV,
|
|
982
|
+
P as fetchRemoteMsEdgeVoices,
|
|
983
|
+
N as findMsEdgeVoice,
|
|
984
|
+
L as getAvailableMsEdgeVoices,
|
|
985
|
+
ot as getMsEdgeVoicesByLanguage,
|
|
986
|
+
F as parseMp3Metadata,
|
|
987
|
+
V as setDynamicMsEdgeVoices,
|
|
988
|
+
it as speak
|
|
1612
989
|
};
|