@szjy/ai-coms 0.1.16 → 0.1.17
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/dist/images/sikao.svg +20 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.mjs +2418 -1235
- package/dist/index.umd.js +7 -3
- package/dist/packages/common/voice/EqualizerBars.vue.d.ts +17 -0
- package/dist/packages/common/voice/VoiceCaptionBar.vue.d.ts +2 -0
- package/dist/packages/common/voice/VoiceMicButton.vue.d.ts +2 -0
- package/dist/packages/common/voice/VoiceOverlay.vue.d.ts +29 -0
- package/dist/packages/common/voice/aec.d.ts +52 -0
- package/dist/packages/common/voice/aec.test.d.ts +1 -0
- package/dist/packages/common/voice/api.d.ts +31 -0
- package/dist/packages/common/voice/api.test.d.ts +1 -0
- package/dist/packages/common/voice/asr.d.ts +20 -0
- package/dist/packages/common/voice/asr.test.d.ts +1 -0
- package/dist/packages/common/voice/constants.d.ts +37 -0
- package/dist/packages/common/voice/index.d.ts +11 -0
- package/dist/packages/common/voice/playback.d.ts +14 -0
- package/dist/packages/common/voice/types.d.ts +86 -0
- package/dist/packages/common/voice/useVoice.d.ts +29 -0
- package/dist/packages/common/voice/useVoice.test.d.ts +1 -0
- package/dist/packages/components/AiChat/src/index.vue.d.ts +37 -0
- package/dist/packages/components/AiChatPlain/src/index.vue.d.ts +37 -0
- package/dist/style.css +2 -2
- package/package.json +6 -2
package/dist/index.mjs
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var
|
|
4
|
-
import { computed as
|
|
5
|
-
const
|
|
6
|
-
function
|
|
1
|
+
var Yt = Object.defineProperty;
|
|
2
|
+
var Xt = (e, t, n) => t in e ? Yt(e, t, { enumerable: !0, configurable: !0, writable: !0, value: n }) : e[t] = n;
|
|
3
|
+
var N = (e, t, n) => Xt(e, typeof t != "symbol" ? t + "" : t, n);
|
|
4
|
+
import { computed as q, openBlock as T, createElementBlock as L, normalizeStyle as ce, createElementVNode as p, normalizeClass as le, getCurrentInstance as bt, ref as R, watch as ye, onUnmounted as De, createBlock as Se, Transition as Le, withCtx as ie, toDisplayString as Q, withDirectives as kt, vShow as St, createCommentVNode as H, createVNode as ne, nextTick as Ct, inject as Zt, shallowRef as it, provide as Qt, toValue as lt, defineComponent as Ue, Fragment as he, renderList as Fe, createTextVNode as fe, onMounted as en, unref as Re, reactive as tn, onBeforeUnmount as nn, resolveComponent as Je, withKeys as sn, withModifiers as on } from "vue";
|
|
5
|
+
const rn = "/images/ai-round.png", an = "/images/ai-sqrt.png", ln = "/images/sikao.svg", cn = "/images/bars-loading.svg";
|
|
6
|
+
function At(e) {
|
|
7
7
|
return e.startsWith("http://") || e.startsWith("https://") ? e : `${location.protocol}//${location.host}${e}`;
|
|
8
8
|
}
|
|
9
|
-
async function
|
|
10
|
-
const { projectId:
|
|
11
|
-
|
|
9
|
+
async function un(e, t, n, s = "", r = {}) {
|
|
10
|
+
const { projectId: o } = r, a = At(s), i = new URL(`${a}/v1/chat/completions`), l = (r == null ? void 0 : r.authToken) || "app-oLZVFFdYyJX2QK3rdOLWsC2u";
|
|
11
|
+
r != null && r.authToken || console.error("缺少 authToken!现在默认使用内网的 authToken");
|
|
12
12
|
const c = new Request(i, {
|
|
13
13
|
method: "post",
|
|
14
14
|
headers: {
|
|
@@ -20,8 +20,8 @@ async function Tt(e, t, s, r = "", o = {}) {
|
|
|
20
20
|
stream: !0,
|
|
21
21
|
inputs: {
|
|
22
22
|
token: t,
|
|
23
|
-
projectCode:
|
|
24
|
-
...
|
|
23
|
+
projectCode: n,
|
|
24
|
+
...o ? { projectId: o } : {}
|
|
25
25
|
},
|
|
26
26
|
messages: [
|
|
27
27
|
{
|
|
@@ -37,12 +37,12 @@ async function Tt(e, t, s, r = "", o = {}) {
|
|
|
37
37
|
});
|
|
38
38
|
return fetch(c);
|
|
39
39
|
}
|
|
40
|
-
async function
|
|
41
|
-
const
|
|
40
|
+
async function dn(e, t, n, s = "", r = {}) {
|
|
41
|
+
const o = new URL("http://localhost:11434/api/chat"), a = {};
|
|
42
42
|
Object.keys(a).forEach((l) => {
|
|
43
|
-
|
|
43
|
+
o.searchParams.append(l, a[l]);
|
|
44
44
|
});
|
|
45
|
-
const i = new Request(
|
|
45
|
+
const i = new Request(o, {
|
|
46
46
|
mode: "cors",
|
|
47
47
|
method: "post",
|
|
48
48
|
headers: {
|
|
@@ -65,12 +65,12 @@ async function Rt(e, t, s, r = "", o = {}) {
|
|
|
65
65
|
});
|
|
66
66
|
return fetch(i);
|
|
67
67
|
}
|
|
68
|
-
async function
|
|
69
|
-
const
|
|
68
|
+
async function fn(e, t, n, s = "", r = {}) {
|
|
69
|
+
const o = new URL(`${location.origin}/spark/v1/chat/completions`), a = {};
|
|
70
70
|
Object.keys(a).forEach((l) => {
|
|
71
|
-
|
|
71
|
+
o.searchParams.append(l, a[l]);
|
|
72
72
|
});
|
|
73
|
-
const i = new Request(
|
|
73
|
+
const i = new Request(o, {
|
|
74
74
|
method: "post",
|
|
75
75
|
headers: {
|
|
76
76
|
"Content-Type": "application/json",
|
|
@@ -89,12 +89,12 @@ async function Ut(e, t, s, r = "", o = {}) {
|
|
|
89
89
|
});
|
|
90
90
|
return fetch(i);
|
|
91
91
|
}
|
|
92
|
-
async function
|
|
93
|
-
const
|
|
92
|
+
async function hn(e, t, n, s = "", r = {}) {
|
|
93
|
+
const o = new URL(`${location.origin}/siliconflow/v1/chat/completions`), a = {};
|
|
94
94
|
Object.keys(a).forEach((l) => {
|
|
95
|
-
|
|
95
|
+
o.searchParams.append(l, a[l]);
|
|
96
96
|
});
|
|
97
|
-
const i = new Request(
|
|
97
|
+
const i = new Request(o, {
|
|
98
98
|
method: "post",
|
|
99
99
|
headers: {
|
|
100
100
|
"Content-Type": "application/json",
|
|
@@ -114,12 +114,12 @@ async function _t(e, t, s, r = "", o = {}) {
|
|
|
114
114
|
});
|
|
115
115
|
return fetch(i);
|
|
116
116
|
}
|
|
117
|
-
async function
|
|
118
|
-
const
|
|
117
|
+
async function pn(e, t, n, s = "", r = {}) {
|
|
118
|
+
const o = new URL(`${location.origin}/moonshot/v1/chat/completions`), a = {};
|
|
119
119
|
Object.keys(a).forEach((l) => {
|
|
120
|
-
|
|
120
|
+
o.searchParams.append(l, a[l]);
|
|
121
121
|
});
|
|
122
|
-
const i = new Request(
|
|
122
|
+
const i = new Request(o, {
|
|
123
123
|
method: "post",
|
|
124
124
|
headers: {
|
|
125
125
|
"Content-Type": "application/json",
|
|
@@ -142,12 +142,12 @@ async function Pt(e, t, s, r = "", o = {}) {
|
|
|
142
142
|
});
|
|
143
143
|
return fetch(i);
|
|
144
144
|
}
|
|
145
|
-
async function
|
|
146
|
-
const
|
|
145
|
+
async function mn(e, t, n, s = "", r = {}) {
|
|
146
|
+
const o = new URL(`${location.origin}/dashscope/compatible-mode/v1/chat/completions`), a = {};
|
|
147
147
|
Object.keys(a).forEach((l) => {
|
|
148
|
-
|
|
148
|
+
o.searchParams.append(l, a[l]);
|
|
149
149
|
});
|
|
150
|
-
const i = new Request(
|
|
150
|
+
const i = new Request(o, {
|
|
151
151
|
method: "post",
|
|
152
152
|
headers: {
|
|
153
153
|
"Content-Type": "application/json",
|
|
@@ -170,8 +170,8 @@ async function Mt(e, t, s, r = "", o = {}) {
|
|
|
170
170
|
});
|
|
171
171
|
return fetch(i);
|
|
172
172
|
}
|
|
173
|
-
async function
|
|
174
|
-
const
|
|
173
|
+
async function vn(e, t, n, s = "", r = {}) {
|
|
174
|
+
const o = At(s), a = new URL(`${o}/support/${n}/a`), i = {};
|
|
175
175
|
Object.keys(i).forEach((c) => {
|
|
176
176
|
a.searchParams.append(c, i[c]);
|
|
177
177
|
});
|
|
@@ -187,7 +187,7 @@ async function It(e, t, s, r = "", o = {}) {
|
|
|
187
187
|
});
|
|
188
188
|
return fetch(l);
|
|
189
189
|
}
|
|
190
|
-
const
|
|
190
|
+
const gn = [
|
|
191
191
|
"根据您的问题,我为您整理了以下构件:",
|
|
192
192
|
"",
|
|
193
193
|
"```szjy-ui",
|
|
@@ -236,18 +236,18 @@ const Et = [
|
|
|
236
236
|
"",
|
|
237
237
|
"点击上方按钮即可在 BIM 沙盘中定位对应构件。"
|
|
238
238
|
].join(`
|
|
239
|
-
`),
|
|
240
|
-
function
|
|
241
|
-
const
|
|
242
|
-
for (let
|
|
243
|
-
|
|
244
|
-
return
|
|
245
|
-
}
|
|
246
|
-
async function
|
|
247
|
-
const a = (
|
|
239
|
+
`), yn = 8, wn = 80, bn = (e) => new Promise((t) => setTimeout(t, e));
|
|
240
|
+
function kn(e, t) {
|
|
241
|
+
const n = Math.ceil(e.length / t), s = [];
|
|
242
|
+
for (let r = 0; r < e.length; r += n)
|
|
243
|
+
s.push(e.slice(r, r + n));
|
|
244
|
+
return s.length ? s : [""];
|
|
245
|
+
}
|
|
246
|
+
async function Sn(e, t, n, s = "", r = {}) {
|
|
247
|
+
const a = (r && typeof r.mockResponse == "string" ? r.mockResponse.trim() : "") || gn, i = new TextEncoder(), l = new ReadableStream({
|
|
248
248
|
async start(c) {
|
|
249
|
-
for (const
|
|
250
|
-
c.enqueue(i.encode(
|
|
249
|
+
for (const d of kn(a, yn))
|
|
250
|
+
c.enqueue(i.encode(d)), await bn(wn);
|
|
251
251
|
c.close();
|
|
252
252
|
}
|
|
253
253
|
});
|
|
@@ -256,7 +256,7 @@ async function Ot(e, t, s, r = "", o = {}) {
|
|
|
256
256
|
headers: { "Content-Type": "text/plain; charset=utf-8" }
|
|
257
257
|
});
|
|
258
258
|
}
|
|
259
|
-
const
|
|
259
|
+
const Cn = (e) => {
|
|
260
260
|
if (e.startsWith("data:")) {
|
|
261
261
|
const t = e.substring(5).trim();
|
|
262
262
|
if (t === "[DONE]")
|
|
@@ -265,103 +265,103 @@ const Nt = (e) => {
|
|
|
265
265
|
};
|
|
266
266
|
try {
|
|
267
267
|
return JSON.parse(t);
|
|
268
|
-
} catch (
|
|
269
|
-
console.error("JSON parsing error:",
|
|
268
|
+
} catch (n) {
|
|
269
|
+
console.error("JSON parsing error:", n);
|
|
270
270
|
}
|
|
271
271
|
}
|
|
272
272
|
return null;
|
|
273
|
-
},
|
|
274
|
-
const
|
|
275
|
-
for (let
|
|
276
|
-
if (t.startsWith(e.slice(
|
|
277
|
-
return e.length -
|
|
273
|
+
}, Ke = "<think>", Ne = "</think>", Ye = (e, t) => {
|
|
274
|
+
const n = Math.max(0, e.length - (t.length - 1));
|
|
275
|
+
for (let s = n; s < e.length; s++)
|
|
276
|
+
if (t.startsWith(e.slice(s)))
|
|
277
|
+
return e.length - s;
|
|
278
278
|
return 0;
|
|
279
|
-
},
|
|
280
|
-
let t = "",
|
|
281
|
-
for (;
|
|
282
|
-
const
|
|
283
|
-
if (
|
|
284
|
-
|
|
285
|
-
else if (a >= 0 && (
|
|
286
|
-
t +=
|
|
287
|
-
else if (
|
|
288
|
-
const i =
|
|
289
|
-
t +=
|
|
279
|
+
}, An = (e) => {
|
|
280
|
+
let t = "", n = "", s = e || "", r = !1;
|
|
281
|
+
for (; s; ) {
|
|
282
|
+
const o = s.indexOf(Ke), a = s.indexOf(Ne);
|
|
283
|
+
if (o >= 0 && (a < 0 || o < a))
|
|
284
|
+
n += s.slice(0, o), s = s.slice(o + Ke.length), r = !0;
|
|
285
|
+
else if (a >= 0 && (o < 0 || a < o))
|
|
286
|
+
t += s.slice(0, a), s = s.slice(a + Ne.length), r = !1;
|
|
287
|
+
else if (r) {
|
|
288
|
+
const i = Ye(s, Ne);
|
|
289
|
+
t += s.slice(0, s.length - i), s = "";
|
|
290
290
|
} else {
|
|
291
291
|
const i = Math.max(
|
|
292
|
-
|
|
293
|
-
|
|
292
|
+
Ye(s, Ke),
|
|
293
|
+
Ye(s, Ne)
|
|
294
294
|
);
|
|
295
|
-
|
|
295
|
+
n += s.slice(0, s.length - i), s = "";
|
|
296
296
|
}
|
|
297
297
|
}
|
|
298
298
|
return {
|
|
299
299
|
thinking: t.trim(),
|
|
300
|
-
content:
|
|
301
|
-
isThinkingStreaming:
|
|
300
|
+
content: n.trim(),
|
|
301
|
+
isThinkingStreaming: r
|
|
302
302
|
};
|
|
303
|
-
},
|
|
303
|
+
}, ct = [
|
|
304
304
|
{
|
|
305
305
|
label: "模拟数据模型",
|
|
306
306
|
modelName: "standard",
|
|
307
307
|
// 不请求真实后端:流式输出 extraConfig.mockResponse(或内置样例),
|
|
308
308
|
// 配合 sz-ai-chat 的 mockResponse prop 用于本地联调
|
|
309
|
-
api:
|
|
309
|
+
api: Sn
|
|
310
310
|
},
|
|
311
311
|
{
|
|
312
312
|
label: "Spark 星火大模型",
|
|
313
313
|
modelName: "spark",
|
|
314
|
-
api:
|
|
314
|
+
api: fn
|
|
315
315
|
},
|
|
316
316
|
{
|
|
317
317
|
label: "Ollama 3 大模型",
|
|
318
318
|
modelName: "ollama3",
|
|
319
|
-
api:
|
|
319
|
+
api: dn
|
|
320
320
|
},
|
|
321
321
|
{
|
|
322
322
|
label: "SiliconFlow 硅基流动大模型",
|
|
323
323
|
modelName: "siliconflow",
|
|
324
|
-
api:
|
|
324
|
+
api: hn
|
|
325
325
|
},
|
|
326
326
|
{
|
|
327
327
|
label: "Kimi Moonshot 月之暗面大模型",
|
|
328
328
|
modelName: "moonshot",
|
|
329
|
-
api:
|
|
329
|
+
api: pn
|
|
330
330
|
},
|
|
331
331
|
{
|
|
332
332
|
label: "通义千问大模型",
|
|
333
333
|
modelName: "dashscope",
|
|
334
|
-
api:
|
|
334
|
+
api: mn
|
|
335
335
|
},
|
|
336
336
|
{
|
|
337
337
|
label: "数智建管大模型",
|
|
338
338
|
modelName: "szjy",
|
|
339
|
-
api:
|
|
339
|
+
api: vn
|
|
340
340
|
},
|
|
341
341
|
{
|
|
342
342
|
label: "Dify (OpenAI 兼容)",
|
|
343
343
|
modelName: "dify-openai",
|
|
344
|
-
api:
|
|
344
|
+
api: un
|
|
345
345
|
}
|
|
346
|
-
],
|
|
346
|
+
], ut = {
|
|
347
347
|
standard(e, t) {
|
|
348
|
-
let
|
|
349
|
-
return e instanceof Uint8Array ?
|
|
348
|
+
let n = "";
|
|
349
|
+
return e instanceof Uint8Array ? n = t.decode(e, {
|
|
350
350
|
stream: !0
|
|
351
|
-
}) :
|
|
352
|
-
content:
|
|
351
|
+
}) : n = e, {
|
|
352
|
+
content: n
|
|
353
353
|
};
|
|
354
354
|
},
|
|
355
355
|
spark(e) {
|
|
356
|
-
const t =
|
|
356
|
+
const t = Cn(e);
|
|
357
357
|
if (t.done)
|
|
358
358
|
return {
|
|
359
359
|
done: !0
|
|
360
360
|
};
|
|
361
|
-
const
|
|
362
|
-
let
|
|
363
|
-
return
|
|
364
|
-
content:
|
|
361
|
+
const n = t.choices[0].delta, s = n.reasoning_content || n.reasoning;
|
|
362
|
+
let r = n.content || "";
|
|
363
|
+
return s && (r = `<think>${s}</think>${r}`), {
|
|
364
|
+
content: r
|
|
365
365
|
};
|
|
366
366
|
},
|
|
367
367
|
siliconflow(e) {
|
|
@@ -384,47 +384,47 @@ const Nt = (e) => {
|
|
|
384
384
|
content: JSON.parse(e).message.content
|
|
385
385
|
};
|
|
386
386
|
}
|
|
387
|
-
},
|
|
388
|
-
const
|
|
389
|
-
return
|
|
390
|
-
|
|
391
|
-
}),
|
|
392
|
-
},
|
|
387
|
+
}, dt = (e, t, n) => {
|
|
388
|
+
const s = e.split(n);
|
|
389
|
+
return s.slice(0, -1).forEach((r) => {
|
|
390
|
+
r.trim() !== "" && t.enqueue(r);
|
|
391
|
+
}), s[s.length - 1];
|
|
392
|
+
}, Tn = (e) => {
|
|
393
393
|
let t = "";
|
|
394
394
|
return new TransformStream({
|
|
395
|
-
transform(
|
|
396
|
-
if (t +=
|
|
397
|
-
t =
|
|
395
|
+
transform(n, s) {
|
|
396
|
+
if (t += n, t.trim().startsWith("data:"))
|
|
397
|
+
t = dt(t, s, e);
|
|
398
398
|
else
|
|
399
399
|
try {
|
|
400
|
-
JSON.parse(t), t =
|
|
400
|
+
JSON.parse(t), t = dt(t, s, e);
|
|
401
401
|
} catch {
|
|
402
|
-
|
|
402
|
+
s.enqueue(n), t = "";
|
|
403
403
|
}
|
|
404
404
|
},
|
|
405
|
-
flush(
|
|
406
|
-
t.trim() !== "" &&
|
|
405
|
+
flush(n) {
|
|
406
|
+
t.trim() !== "" && n.enqueue(t);
|
|
407
407
|
}
|
|
408
408
|
});
|
|
409
409
|
};
|
|
410
|
-
async function
|
|
411
|
-
const
|
|
412
|
-
return
|
|
413
|
-
|
|
414
|
-
if (
|
|
415
|
-
const
|
|
410
|
+
async function xn(e, t) {
|
|
411
|
+
const n = e.api;
|
|
412
|
+
return n ? new Promise((s) => {
|
|
413
|
+
n(t.text, t.token, t.identifier, t.baseUrl, t.extraConfig).then((r) => {
|
|
414
|
+
if (r.body) {
|
|
415
|
+
const o = r.body.pipeThrough(new TextDecoderStream()).pipeThrough(Tn(`
|
|
416
416
|
`)).getReader();
|
|
417
|
-
console.log("reader from response:",
|
|
417
|
+
console.log("reader from response:", o), s({
|
|
418
418
|
error: 0,
|
|
419
|
-
reader:
|
|
419
|
+
reader: o
|
|
420
420
|
});
|
|
421
421
|
} else
|
|
422
|
-
|
|
422
|
+
s({
|
|
423
423
|
error: 1,
|
|
424
424
|
reader: null
|
|
425
425
|
});
|
|
426
426
|
}).catch(() => {
|
|
427
|
-
|
|
427
|
+
s({
|
|
428
428
|
error: 1,
|
|
429
429
|
reader: null
|
|
430
430
|
});
|
|
@@ -434,98 +434,98 @@ async function Vt(e, t) {
|
|
|
434
434
|
reader: null
|
|
435
435
|
};
|
|
436
436
|
}
|
|
437
|
-
const
|
|
438
|
-
function
|
|
439
|
-
|
|
437
|
+
const et = /* @__PURE__ */ new Map(), tt = /* @__PURE__ */ new Map();
|
|
438
|
+
function Tt(e, t) {
|
|
439
|
+
et.set(e, t);
|
|
440
440
|
}
|
|
441
|
-
function
|
|
442
|
-
|
|
441
|
+
function Rn(e, t) {
|
|
442
|
+
tt.set(e, t);
|
|
443
443
|
}
|
|
444
|
-
function
|
|
445
|
-
return
|
|
444
|
+
function En(e) {
|
|
445
|
+
return et.get(e);
|
|
446
446
|
}
|
|
447
|
-
function
|
|
448
|
-
return
|
|
447
|
+
function Ln(e) {
|
|
448
|
+
return et.has(e);
|
|
449
449
|
}
|
|
450
|
-
function
|
|
451
|
-
return
|
|
450
|
+
function Pn(e) {
|
|
451
|
+
return tt.get(e);
|
|
452
452
|
}
|
|
453
|
-
function
|
|
454
|
-
return
|
|
453
|
+
function Un(e) {
|
|
454
|
+
return tt.has(e);
|
|
455
455
|
}
|
|
456
|
-
const
|
|
456
|
+
const Mn = {
|
|
457
457
|
"&": "&",
|
|
458
458
|
"<": "<",
|
|
459
459
|
">": ">",
|
|
460
460
|
'"': """,
|
|
461
461
|
"'": "'"
|
|
462
462
|
};
|
|
463
|
-
function
|
|
464
|
-
return String(e ?? "").replace(/[&<>"']/g, (t) =>
|
|
463
|
+
function Ie(e) {
|
|
464
|
+
return String(e ?? "").replace(/[&<>"']/g, (t) => Mn[t]);
|
|
465
465
|
}
|
|
466
|
-
function
|
|
467
|
-
const
|
|
468
|
-
return
|
|
466
|
+
function _n(e) {
|
|
467
|
+
const n = xt(e, { block: e });
|
|
468
|
+
return n ? `<div class="szjy-ui" data-szjy-ui="1">${n}</div>` : "";
|
|
469
469
|
}
|
|
470
|
-
function
|
|
470
|
+
function xt(e, t) {
|
|
471
471
|
if (!e || typeof e != "object" || typeof e.type != "string") return "";
|
|
472
|
-
const
|
|
473
|
-
return
|
|
472
|
+
const n = En(e.type);
|
|
473
|
+
return n ? n(e, t) : "";
|
|
474
474
|
}
|
|
475
|
-
function
|
|
475
|
+
function jn(e) {
|
|
476
476
|
const t = e.action;
|
|
477
477
|
if (!t || typeof t != "string") return "";
|
|
478
|
-
if (!
|
|
479
|
-
return ` disabled title="未知动作:${
|
|
480
|
-
const
|
|
481
|
-
return ` data-szjy-ui-action="${
|
|
478
|
+
if (!Un(t))
|
|
479
|
+
return ` disabled title="未知动作:${Ie(t)}"`;
|
|
480
|
+
const n = e.actionParams === void 0 ? "" : encodeURIComponent(JSON.stringify(e.actionParams ?? null));
|
|
481
|
+
return ` data-szjy-ui-action="${Ie(t)}" data-szjy-ui-params="${n}"`;
|
|
482
482
|
}
|
|
483
|
-
function
|
|
483
|
+
function In(e) {
|
|
484
484
|
return typeof e == "number" && Number.isFinite(e) && e >= 0 ? `${e}px` : typeof e == "string" && /^\d+(\.\d+)?(px|rem|em|%)?$/.test(e.trim()) ? /^\d+(\.\d+)?$/.test(e.trim()) ? `${e.trim()}px` : e.trim() : "12px";
|
|
485
485
|
}
|
|
486
|
-
function
|
|
487
|
-
const
|
|
488
|
-
return '<div class="szjy-ui-list">' +
|
|
486
|
+
function zn(e, t) {
|
|
487
|
+
const n = typeof e.title == "string" && e.title ? `<div class="szjy-ui-list__title">${Ie(e.title)}</div>` : "", r = (Array.isArray(e.items) ? e.items : []).map((a) => xt(a, t)).filter(Boolean).map((a) => `<div class="szjy-ui-list__item">${a}</div>`).join(""), o = Ie(In(e.gap));
|
|
488
|
+
return '<div class="szjy-ui-list">' + n + `<div class="szjy-ui-list__items" style="gap:${o}">${r}</div></div>`;
|
|
489
489
|
}
|
|
490
|
-
|
|
491
|
-
const
|
|
492
|
-
function
|
|
493
|
-
const
|
|
494
|
-
return `<button type="button" class="${["szjy-ui-btn", `szjy-ui-btn--${
|
|
490
|
+
Tt("list", zn);
|
|
491
|
+
const $n = ["default", "primary", "success", "warning", "danger", "info", "text"], On = ["small", "default", "large"];
|
|
492
|
+
function Bn(e, t) {
|
|
493
|
+
const n = e.props, s = n && typeof n == "object" ? n : {}, r = $n.includes(s.type) ? s.type : "default", o = On.includes(s.size) ? s.size : "default", a = Ie(s.content ?? s.text ?? "按钮"), i = jn(e);
|
|
494
|
+
return `<button type="button" class="${["szjy-ui-btn", `szjy-ui-btn--${r}`, `szjy-ui-btn--${o}`].join(" ")}"${i}><span class="szjy-ui-btn__text">${a}</span><span class="szjy-ui-btn__status" aria-live="polite"></span></button>`;
|
|
495
495
|
}
|
|
496
|
-
|
|
497
|
-
const
|
|
496
|
+
Tt("button", Bn);
|
|
497
|
+
const Nn = 15e3, Rt = /未就绪|未加载/, Vn = "BIM_SANDBOX", Fn = {
|
|
498
498
|
locateComponent: (e) => [e == null ? void 0 : e.wbsCode],
|
|
499
499
|
openPDFSearch: () => []
|
|
500
500
|
};
|
|
501
|
-
let
|
|
502
|
-
function
|
|
503
|
-
let
|
|
501
|
+
let Dn = 0;
|
|
502
|
+
function Hn(e, t) {
|
|
503
|
+
let n;
|
|
504
504
|
if (!e || e === "self")
|
|
505
|
-
|
|
505
|
+
n = [window];
|
|
506
506
|
else if (e === "parent")
|
|
507
|
-
|
|
507
|
+
n = [window.parent];
|
|
508
508
|
else if (e === "top")
|
|
509
|
-
|
|
509
|
+
n = [window.top];
|
|
510
510
|
else if (typeof e == "function")
|
|
511
511
|
try {
|
|
512
|
-
|
|
513
|
-
} catch (
|
|
514
|
-
console.error("[szjy-ui] 解析 postMessage 目标窗口失败:",
|
|
512
|
+
n = e(t);
|
|
513
|
+
} catch (o) {
|
|
514
|
+
console.error("[szjy-ui] 解析 postMessage 目标窗口失败:", o), n = [];
|
|
515
515
|
}
|
|
516
|
-
else Array.isArray(e) ?
|
|
517
|
-
const
|
|
518
|
-
if (
|
|
519
|
-
if (Array.isArray(
|
|
520
|
-
|
|
516
|
+
else Array.isArray(e) ? n = e : n = [e];
|
|
517
|
+
const s = [], r = (o) => {
|
|
518
|
+
if (o) {
|
|
519
|
+
if (Array.isArray(o)) {
|
|
520
|
+
o.forEach(r);
|
|
521
521
|
return;
|
|
522
522
|
}
|
|
523
|
-
typeof
|
|
523
|
+
typeof o.postMessage == "function" && !s.includes(o) && s.push(o);
|
|
524
524
|
}
|
|
525
525
|
};
|
|
526
|
-
return
|
|
526
|
+
return r(n), s;
|
|
527
527
|
}
|
|
528
|
-
function
|
|
528
|
+
function Pe(e) {
|
|
529
529
|
if (e === window) return `self (${location.origin})`;
|
|
530
530
|
if (e === window.parent) return "parent";
|
|
531
531
|
if (e === window.top) return "top";
|
|
@@ -535,7 +535,7 @@ function de(e) {
|
|
|
535
535
|
return "window (cross-origin)";
|
|
536
536
|
}
|
|
537
537
|
}
|
|
538
|
-
function
|
|
538
|
+
function qn(e) {
|
|
539
539
|
try {
|
|
540
540
|
const t = e.$bimSandbox;
|
|
541
541
|
return t && typeof t == "object" ? t : null;
|
|
@@ -543,52 +543,52 @@ function ln(e) {
|
|
|
543
543
|
return null;
|
|
544
544
|
}
|
|
545
545
|
}
|
|
546
|
-
function
|
|
547
|
-
if (t.type !==
|
|
548
|
-
const
|
|
549
|
-
if (!
|
|
550
|
-
const
|
|
551
|
-
if (!
|
|
552
|
-
const
|
|
546
|
+
function Wn(e, t, n) {
|
|
547
|
+
if (t.type !== Vn) return { handled: !1 };
|
|
548
|
+
const s = Fn[t.action];
|
|
549
|
+
if (!s) return { handled: !1 };
|
|
550
|
+
const r = qn(e);
|
|
551
|
+
if (!r || typeof r[t.action] != "function") return { handled: !1 };
|
|
552
|
+
const o = s(t.payload);
|
|
553
553
|
let a;
|
|
554
554
|
try {
|
|
555
|
-
a =
|
|
555
|
+
a = r[t.action](...o);
|
|
556
556
|
} catch (i) {
|
|
557
557
|
return console.error("[szjy-ui] $bimSandbox 方法调用异常,回退 postMessage:", i), { handled: !1 };
|
|
558
558
|
}
|
|
559
|
-
return
|
|
559
|
+
return n && console.log("[szjy-ui] $bimSandbox 直调", {
|
|
560
560
|
method: t.action,
|
|
561
|
-
args:
|
|
561
|
+
args: o,
|
|
562
562
|
result: a,
|
|
563
|
-
target:
|
|
563
|
+
target: Pe(e)
|
|
564
564
|
}), { handled: !0, result: a };
|
|
565
565
|
}
|
|
566
|
-
function
|
|
566
|
+
function Et(e, t, n, s, r, o, a) {
|
|
567
567
|
return (() => {
|
|
568
|
-
const { handled: l, result: c } =
|
|
569
|
-
return l ? (c && c.success ?
|
|
570
|
-
`[szjy-ui] $bimSandbox 直调失败(${c.message}),${
|
|
571
|
-
),
|
|
572
|
-
|
|
573
|
-
},
|
|
568
|
+
const { handled: l, result: c } = Wn(e, t, a);
|
|
569
|
+
return l ? (c && c.success ? o && pe(n, "success", c.message || "执行成功") : c && Rt.test(String(c.message || "")) && s > 0 ? (a && console.warn(
|
|
570
|
+
`[szjy-ui] $bimSandbox 直调失败(${c.message}),${r}ms 后自动重试,剩余 ${s - 1} 次`
|
|
571
|
+
), o && pe(n, "retrying", `${c.message},${Math.round(r / 1e3)}s 后自动重试`), setTimeout(() => {
|
|
572
|
+
Et(e, t, n, s - 1, r, o, a);
|
|
573
|
+
}, r)) : o && pe(n, "error", c && c.message || "执行失败"), !0) : !1;
|
|
574
574
|
})();
|
|
575
575
|
}
|
|
576
|
-
function
|
|
577
|
-
const t =
|
|
576
|
+
function Gn(e) {
|
|
577
|
+
const t = Jn(e.config), n = !e.config || e.config.debug !== !1, s = t.feedback !== !1, r = t.retry === !1 ? { retries: 0, delay: 2e3 } : { retries: 2, delay: 2e3, ...t.retry || {} };
|
|
578
578
|
if (!e.params || typeof e.params != "object" || Array.isArray(e.params)) {
|
|
579
|
-
console.warn("[szjy-ui] postMessage 动作的 actionParams 必须是对象:", e.params),
|
|
579
|
+
console.warn("[szjy-ui] postMessage 动作的 actionParams 必须是对象:", e.params), pe(e.triggerEl, "error", "参数无效");
|
|
580
580
|
return;
|
|
581
581
|
}
|
|
582
|
-
const
|
|
582
|
+
const o = { ...e.params }, a = Hn(t.target, o);
|
|
583
583
|
if (!a.length) {
|
|
584
|
-
console.warn("[szjy-ui] postMessage 无可用目标窗口,target 配置:", t.target),
|
|
584
|
+
console.warn("[szjy-ui] postMessage 无可用目标窗口,target 配置:", t.target), pe(e.triggerEl, "error", "无目标窗口");
|
|
585
585
|
return;
|
|
586
586
|
}
|
|
587
587
|
const i = t.targetOrigin || "*", l = t.transport || "auto";
|
|
588
588
|
if (l !== "postMessage") {
|
|
589
589
|
let c = !1;
|
|
590
|
-
for (const
|
|
591
|
-
if (
|
|
590
|
+
for (const d of a)
|
|
591
|
+
if (Et(d, o, e.triggerEl, r.retries, r.delay, s, n)) {
|
|
592
592
|
c = !0;
|
|
593
593
|
break;
|
|
594
594
|
}
|
|
@@ -596,153 +596,153 @@ function un(e) {
|
|
|
596
596
|
return;
|
|
597
597
|
if (l === "global") {
|
|
598
598
|
console.warn("[szjy-ui] transport=global 但 $bimSandbox 全局方法不可用:", {
|
|
599
|
-
targets: a.map(
|
|
600
|
-
message:
|
|
601
|
-
}),
|
|
599
|
+
targets: a.map(Pe),
|
|
600
|
+
message: o
|
|
601
|
+
}), pe(e.triggerEl, "error", "全局方法不可用");
|
|
602
602
|
return;
|
|
603
603
|
}
|
|
604
|
-
|
|
604
|
+
n && console.log("[szjy-ui] $bimSandbox 不可用,回退 postMessage 通道");
|
|
605
605
|
}
|
|
606
|
-
|
|
607
|
-
message:
|
|
608
|
-
targets: a.map(
|
|
606
|
+
o.requestId === void 0 && (o.requestId = `szjy-ui-${Date.now()}-${++Dn}`), Lt(a, o, i), n && console.log("[szjy-ui] postMessage 已发送", {
|
|
607
|
+
message: o,
|
|
608
|
+
targets: a.map(Pe),
|
|
609
609
|
targetOrigin: i,
|
|
610
|
-
feedback:
|
|
611
|
-
}),
|
|
610
|
+
feedback: s
|
|
611
|
+
}), s && (pe(e.triggerEl, "loading", "已发送"), Kn(o, a, e.triggerEl, i, r, n));
|
|
612
612
|
}
|
|
613
|
-
function
|
|
613
|
+
function Jn(e) {
|
|
614
614
|
return e && e.postMessage || {};
|
|
615
615
|
}
|
|
616
|
-
function
|
|
617
|
-
e.forEach((
|
|
616
|
+
function Lt(e, t, n) {
|
|
617
|
+
e.forEach((s) => {
|
|
618
618
|
try {
|
|
619
|
-
|
|
620
|
-
} catch (
|
|
621
|
-
console.error("[szjy-ui] postMessage 发送失败:",
|
|
619
|
+
s.postMessage(t, n);
|
|
620
|
+
} catch (r) {
|
|
621
|
+
console.error("[szjy-ui] postMessage 发送失败:", r);
|
|
622
622
|
}
|
|
623
623
|
});
|
|
624
624
|
}
|
|
625
|
-
function
|
|
626
|
-
let a =
|
|
627
|
-
const i =
|
|
625
|
+
function Kn(e, t, n, s, r, o) {
|
|
626
|
+
let a = r.retries;
|
|
627
|
+
const i = r.delay;
|
|
628
628
|
let l = null;
|
|
629
629
|
const c = () => {
|
|
630
630
|
window.removeEventListener("message", P), l && (clearTimeout(l), l = null);
|
|
631
|
-
},
|
|
631
|
+
}, d = () => {
|
|
632
632
|
l && clearTimeout(l), l = setTimeout(() => {
|
|
633
|
-
c(),
|
|
634
|
-
},
|
|
633
|
+
c(), o && console.warn("[szjy-ui] postMessage 超时未收到回执", { message: e, targets: t.map(Pe), targetOrigin: s }), pe(n, "none", "未收到回执");
|
|
634
|
+
}, Nn);
|
|
635
635
|
}, P = (A) => {
|
|
636
|
-
const
|
|
637
|
-
!
|
|
638
|
-
requestId:
|
|
639
|
-
success:
|
|
640
|
-
message:
|
|
641
|
-
data:
|
|
642
|
-
from:
|
|
643
|
-
}),
|
|
644
|
-
|
|
645
|
-
}, i)) : (c(),
|
|
636
|
+
const m = A.data;
|
|
637
|
+
!m || typeof m != "object" || e.type !== void 0 && m.type !== e.type || m.success !== void 0 && (e.requestId !== void 0 && m.requestId !== void 0 && String(m.requestId) !== String(e.requestId) || A.source && !t.includes(A.source) || (o && console.log("[szjy-ui] postMessage 收到回执", {
|
|
638
|
+
requestId: m.requestId,
|
|
639
|
+
success: m.success,
|
|
640
|
+
message: m.message,
|
|
641
|
+
data: m.data,
|
|
642
|
+
from: Pe(A.source)
|
|
643
|
+
}), m.success ? (c(), pe(n, "success", m.message || "执行成功")) : Rt.test(String(m.message || "")) && a > 0 ? (a -= 1, o && console.warn(`[szjy-ui] postMessage 回执失败(${m.message}),${i}ms 后自动重试,剩余 ${a} 次`), pe(n, "retrying", `${m.message},${Math.round(i / 1e3)}s 后自动重试`), l && clearTimeout(l), setTimeout(() => {
|
|
644
|
+
Lt(t, e, s), o && console.log("[szjy-ui] postMessage 重试已发送", { message: e, targets: t.map(Pe), targetOrigin: s }), pe(n, "loading", "已发送"), d();
|
|
645
|
+
}, i)) : (c(), pe(n, "error", m.message || "执行失败"))));
|
|
646
646
|
};
|
|
647
|
-
window.addEventListener("message", P),
|
|
647
|
+
window.addEventListener("message", P), d();
|
|
648
648
|
}
|
|
649
|
-
function
|
|
649
|
+
function pe(e, t, n) {
|
|
650
650
|
if (!e || !e.isConnected) return;
|
|
651
|
-
const
|
|
652
|
-
e.classList.remove("is-loading", "is-success", "is-error", "is-retrying"), t && t !== "none" && e.classList.add(`is-${t}`),
|
|
651
|
+
const s = e.querySelector(":scope > .szjy-ui-btn__status");
|
|
652
|
+
e.classList.remove("is-loading", "is-success", "is-error", "is-retrying"), t && t !== "none" && e.classList.add(`is-${t}`), s && (s.textContent = n || "");
|
|
653
653
|
}
|
|
654
|
-
|
|
655
|
-
const
|
|
656
|
-
function
|
|
654
|
+
Rn("postMessage", Gn);
|
|
655
|
+
const Yn = "szjy-ui";
|
|
656
|
+
function Xn(e) {
|
|
657
657
|
if (!e || typeof e != "string") return null;
|
|
658
658
|
const t = e.trim();
|
|
659
659
|
if (!t.startsWith("{")) return null;
|
|
660
|
-
let
|
|
660
|
+
let n;
|
|
661
661
|
try {
|
|
662
|
-
|
|
662
|
+
n = JSON.parse(t);
|
|
663
663
|
} catch {
|
|
664
664
|
return null;
|
|
665
665
|
}
|
|
666
|
-
return
|
|
666
|
+
return Zn(n);
|
|
667
667
|
}
|
|
668
|
-
function
|
|
669
|
-
return !e || typeof e != "object" || Array.isArray(e) || typeof e.type != "string" || !
|
|
668
|
+
function Zn(e) {
|
|
669
|
+
return !e || typeof e != "object" || Array.isArray(e) || typeof e.type != "string" || !Ln(e.type) || e.items !== void 0 && !Array.isArray(e.items) ? null : e;
|
|
670
670
|
}
|
|
671
|
-
function
|
|
671
|
+
function Qn(e, t = {}) {
|
|
672
672
|
if (!e) return () => {
|
|
673
673
|
};
|
|
674
|
-
const
|
|
674
|
+
const n = (s) => {
|
|
675
675
|
var A;
|
|
676
|
-
const
|
|
677
|
-
if (!
|
|
678
|
-
const a =
|
|
676
|
+
const r = s.target, o = r && typeof r.closest == "function" ? r.closest("[data-szjy-ui-action]") : null;
|
|
677
|
+
if (!o || !e.contains(o)) return;
|
|
678
|
+
const a = o.getAttribute("data-szjy-ui-action") || "", i = Pn(a);
|
|
679
679
|
if (!i) {
|
|
680
680
|
console.warn(`[szjy-ui] 未注册的动作: ${a}`);
|
|
681
681
|
return;
|
|
682
682
|
}
|
|
683
|
-
const l =
|
|
683
|
+
const l = o.getAttribute("data-szjy-ui-params");
|
|
684
684
|
let c = null;
|
|
685
685
|
if (l)
|
|
686
686
|
try {
|
|
687
687
|
c = JSON.parse(decodeURIComponent(l));
|
|
688
|
-
} catch (
|
|
689
|
-
console.error("[szjy-ui] actionParams 解析失败:",
|
|
688
|
+
} catch (m) {
|
|
689
|
+
console.error("[szjy-ui] actionParams 解析失败:", m);
|
|
690
690
|
return;
|
|
691
691
|
}
|
|
692
|
-
const
|
|
693
|
-
if (!
|
|
694
|
-
const
|
|
692
|
+
const d = t.getConfig ? t.getConfig() : null;
|
|
693
|
+
if (!d || d.debug !== !1) {
|
|
694
|
+
const m = (A = o.querySelector(":scope > .szjy-ui-btn__text")) == null ? void 0 : A.textContent;
|
|
695
695
|
console.log("[szjy-ui] 动作触发", {
|
|
696
696
|
action: a,
|
|
697
697
|
params: c,
|
|
698
|
-
text: (
|
|
699
|
-
trigger:
|
|
698
|
+
text: (m || o.textContent || "").trim().slice(0, 40),
|
|
699
|
+
trigger: o
|
|
700
700
|
});
|
|
701
701
|
}
|
|
702
702
|
const P = t.getInterceptor ? t.getInterceptor() : null;
|
|
703
|
-
if (!(P && P(a, c,
|
|
703
|
+
if (!(P && P(a, c, o) === !1)) {
|
|
704
704
|
if (t.onAction)
|
|
705
705
|
try {
|
|
706
|
-
t.onAction({ action: a, params: c, triggerEl:
|
|
707
|
-
} catch (
|
|
708
|
-
console.error("[szjy-ui] onAction 回调执行失败:",
|
|
706
|
+
t.onAction({ action: a, params: c, triggerEl: o });
|
|
707
|
+
} catch (m) {
|
|
708
|
+
console.error("[szjy-ui] onAction 回调执行失败:", m);
|
|
709
709
|
}
|
|
710
|
-
i({ params: c, config:
|
|
710
|
+
i({ params: c, config: d, triggerEl: o });
|
|
711
711
|
}
|
|
712
712
|
};
|
|
713
|
-
return e.addEventListener("click",
|
|
714
|
-
e.removeEventListener("click",
|
|
713
|
+
return e.addEventListener("click", n), () => {
|
|
714
|
+
e.removeEventListener("click", n);
|
|
715
715
|
};
|
|
716
716
|
}
|
|
717
|
-
let
|
|
718
|
-
function
|
|
719
|
-
return
|
|
717
|
+
let Ce = null;
|
|
718
|
+
function es() {
|
|
719
|
+
return Ce || (window.markdownit ? (Ce = new window.markdownit({
|
|
720
720
|
html: !0,
|
|
721
721
|
linkify: !0,
|
|
722
722
|
typographer: !0
|
|
723
|
-
}),
|
|
724
|
-
const
|
|
725
|
-
if (
|
|
726
|
-
const
|
|
723
|
+
}), Ce.renderer.rules.fence = (e, t) => {
|
|
724
|
+
const n = e[t], s = (n.info || "").trim().split(/\s+/)[0];
|
|
725
|
+
if (s === Yn) {
|
|
726
|
+
const o = Xn(n.content), a = o ? _n(o) : "";
|
|
727
727
|
if (a)
|
|
728
728
|
return a;
|
|
729
729
|
}
|
|
730
|
-
let
|
|
731
|
-
if (
|
|
730
|
+
let r = "";
|
|
731
|
+
if (s && window.hljs && window.hljs.getLanguage(s))
|
|
732
732
|
try {
|
|
733
|
-
|
|
733
|
+
r = window.hljs.highlight(n.content, { language: s }).value;
|
|
734
734
|
} catch {
|
|
735
|
-
|
|
735
|
+
r = "";
|
|
736
736
|
}
|
|
737
|
-
return
|
|
738
|
-
}) : console.log("markdownit is not loaded"),
|
|
739
|
-
}
|
|
740
|
-
const
|
|
741
|
-
const
|
|
742
|
-
for (const [
|
|
743
|
-
s
|
|
744
|
-
return
|
|
745
|
-
},
|
|
737
|
+
return r || (r = Ce.utils.escapeHtml(n.content)), `<pre class="md-code-block"><code class="hljs${s ? " language-" + s : ""}">${r}</code></pre>`;
|
|
738
|
+
}) : console.log("markdownit is not loaded"), Ce);
|
|
739
|
+
}
|
|
740
|
+
const ts = (e, t) => {
|
|
741
|
+
const n = e.__vccOpts || e;
|
|
742
|
+
for (const [s, r] of t)
|
|
743
|
+
n[s] = r;
|
|
744
|
+
return n;
|
|
745
|
+
}, ns = ["src", "alt"], ss = {
|
|
746
746
|
__name: "SvgIcon",
|
|
747
747
|
props: {
|
|
748
748
|
// 图标名称或完整URL
|
|
@@ -772,47 +772,47 @@ const vn = (e, t) => {
|
|
|
772
772
|
}
|
|
773
773
|
},
|
|
774
774
|
setup(e) {
|
|
775
|
-
const t = e,
|
|
775
|
+
const t = e, n = q(() => {
|
|
776
776
|
if (t.name.startsWith("http://") || t.name.startsWith("https://") || t.name.startsWith("/"))
|
|
777
777
|
return t.name;
|
|
778
|
-
const
|
|
779
|
-
return `${t.basePath}${
|
|
780
|
-
}),
|
|
781
|
-
const
|
|
778
|
+
const o = t.name.endsWith(".svg") ? t.name : `${t.name}.svg`;
|
|
779
|
+
return `${t.basePath}${o}`;
|
|
780
|
+
}), s = q(() => {
|
|
781
|
+
const o = typeof t.size == "number" ? `${t.size}px` : t.size;
|
|
782
782
|
return {
|
|
783
|
-
width:
|
|
784
|
-
height:
|
|
783
|
+
width: o,
|
|
784
|
+
height: o,
|
|
785
785
|
display: "inline-flex",
|
|
786
786
|
justifyContent: "center",
|
|
787
787
|
alignItems: "center"
|
|
788
788
|
};
|
|
789
|
-
}),
|
|
790
|
-
const
|
|
789
|
+
}), r = q(() => {
|
|
790
|
+
const o = {
|
|
791
791
|
width: "100%",
|
|
792
792
|
height: "100%"
|
|
793
793
|
};
|
|
794
|
-
return t.color && (
|
|
794
|
+
return t.color && (o.filter = `drop-shadow(0 0 0 ${t.color})`), o;
|
|
795
795
|
});
|
|
796
|
-
return (
|
|
796
|
+
return (o, a) => (T(), L("div", {
|
|
797
797
|
class: "svg-icon-wrapper",
|
|
798
|
-
style:
|
|
798
|
+
style: ce(s.value)
|
|
799
799
|
}, [
|
|
800
|
-
|
|
801
|
-
src:
|
|
800
|
+
p("img", {
|
|
801
|
+
src: n.value,
|
|
802
802
|
alt: e.name,
|
|
803
|
-
class:
|
|
804
|
-
style:
|
|
805
|
-
}, null, 14,
|
|
803
|
+
class: le(["svg-icon", e.className]),
|
|
804
|
+
style: ce(r.value)
|
|
805
|
+
}, null, 14, ns)
|
|
806
806
|
], 4));
|
|
807
807
|
}
|
|
808
|
-
},
|
|
808
|
+
}, Ve = /* @__PURE__ */ ts(ss, [["__scopeId", "data-v-490b11c1"]]), os = async (e) => {
|
|
809
809
|
if (navigator.clipboard && navigator.permissions)
|
|
810
810
|
await navigator.clipboard.writeText(e);
|
|
811
811
|
else {
|
|
812
812
|
const t = document.createElement("textArea");
|
|
813
813
|
t.value = e, t.style.width = 0, t.style.position = "fixed", t.style.left = "-999px", t.style.top = "10px", t.setAttribute("readonly", "readonly"), document.body.appendChild(t), t.select(), document.execCommand("copy"), document.body.removeChild(t);
|
|
814
814
|
}
|
|
815
|
-
},
|
|
815
|
+
}, rs = { class: "thinking-title" }, as = { class: "thinking-toggle-hint" }, is = ["innerHTML"], ls = ["innerHTML"], cs = 10, us = {
|
|
816
816
|
__name: "Previewer",
|
|
817
817
|
props: {
|
|
818
818
|
reader: null,
|
|
@@ -841,128 +841,132 @@ const vn = (e, t) => {
|
|
|
841
841
|
},
|
|
842
842
|
emits: [
|
|
843
843
|
"failed",
|
|
844
|
+
"started",
|
|
844
845
|
"completed",
|
|
845
846
|
"updating",
|
|
846
847
|
"ui-action"
|
|
847
848
|
],
|
|
848
|
-
setup(e, { expose: t, emit:
|
|
849
|
-
const { appContext:
|
|
849
|
+
setup(e, { expose: t, emit: n }) {
|
|
850
|
+
const { appContext: s } = bt(), { $message: r } = s.config.globalProperties, o = e, a = R(o.displayText || ""), i = R(!0), l = R(!1), c = R(!!o.displayText), d = n, P = R(null);
|
|
850
851
|
let A = null;
|
|
851
|
-
|
|
852
|
-
A && (A(), A = null),
|
|
852
|
+
ye(P, (W) => {
|
|
853
|
+
A && (A(), A = null), W && (A = Qn(W, {
|
|
853
854
|
// 点击时才读取最新 props,宿主更新 customUi/uiActionHandler 后立即生效
|
|
854
|
-
getConfig: () =>
|
|
855
|
-
getInterceptor: () =>
|
|
856
|
-
onAction: (
|
|
855
|
+
getConfig: () => o.customUi,
|
|
856
|
+
getInterceptor: () => o.uiActionHandler,
|
|
857
|
+
onAction: (h) => d("ui-action", h)
|
|
857
858
|
}));
|
|
858
859
|
});
|
|
859
|
-
let
|
|
860
|
-
const
|
|
861
|
-
|
|
860
|
+
let m = null;
|
|
861
|
+
const S = q(() => An(a.value)), x = q(() => S.value.thinking.length > 0), _ = R(o.displayText ? S.value.content.length : 0), w = q(() => S.value.isThinkingStreaming && !c.value), u = R(!1), k = () => {
|
|
862
|
+
u.value = !u.value;
|
|
862
863
|
};
|
|
863
|
-
let
|
|
864
|
-
const
|
|
865
|
-
|
|
866
|
-
!
|
|
864
|
+
let v = null, f = null;
|
|
865
|
+
const U = R(0);
|
|
866
|
+
ye(() => S.value.thinking, (W) => {
|
|
867
|
+
!W || U.value > 0 || (f === null && (f = v ?? Date.now()), S.value.content && M());
|
|
867
868
|
});
|
|
868
|
-
const
|
|
869
|
-
if (
|
|
870
|
-
const
|
|
871
|
-
|
|
872
|
-
},
|
|
873
|
-
|
|
874
|
-
},
|
|
875
|
-
|
|
876
|
-
},
|
|
877
|
-
|
|
878
|
-
},
|
|
879
|
-
if (!
|
|
880
|
-
const
|
|
869
|
+
const M = () => {
|
|
870
|
+
if (U.value > 0 || !x.value) return;
|
|
871
|
+
const W = f ?? v;
|
|
872
|
+
W && (U.value = Math.max(1, Math.round((Date.now() - W) / 1e3)));
|
|
873
|
+
}, F = q(() => w.value ? "正在思考..." : U.value > 0 ? `已深度思考(用时 ${U.value} 秒)` : "思考过程"), I = q(() => x.value ? Ce ? Ce.render(S.value.thinking) : S.value.thinking : ""), O = q(() => S.value.content.slice(0, _.value)), E = q(() => Ce ? Ce.render(O.value) : O.value), D = () => {
|
|
874
|
+
o.reader && o.reader.cancel(), l.value = !0, X.value = !1, ae(), c.value = !0, M(), d("completed", a.value), i.value = !1, m && (cancelAnimationFrame(m), m = null);
|
|
875
|
+
}, se = q(() => `${E.value}`), K = R(!1), oe = () => {
|
|
876
|
+
K.value = !0;
|
|
877
|
+
}, ae = () => {
|
|
878
|
+
K.value = !1;
|
|
879
|
+
}, X = R(!1), ue = async () => {
|
|
880
|
+
if (!o.reader) return;
|
|
881
|
+
const W = new TextDecoder("utf-8");
|
|
881
882
|
for (i.value = !0; !l.value; )
|
|
882
883
|
try {
|
|
883
|
-
if (!
|
|
884
|
-
|
|
884
|
+
if (!o.reader) {
|
|
885
|
+
X.value = !0;
|
|
885
886
|
break;
|
|
886
887
|
}
|
|
887
|
-
const { value:
|
|
888
|
-
if (!
|
|
889
|
-
|
|
888
|
+
const { value: h, done: j } = await o.reader.read();
|
|
889
|
+
if (!o.reader) {
|
|
890
|
+
X.value = !0;
|
|
890
891
|
break;
|
|
891
892
|
}
|
|
892
|
-
if (
|
|
893
|
-
|
|
893
|
+
if (j) {
|
|
894
|
+
X.value = !0;
|
|
894
895
|
break;
|
|
895
896
|
}
|
|
896
|
-
const
|
|
897
|
-
if (!
|
|
897
|
+
const V = ut[o.model];
|
|
898
|
+
if (!V)
|
|
898
899
|
break;
|
|
899
|
-
const
|
|
900
|
-
if (
|
|
901
|
-
|
|
900
|
+
const B = V.call(ut, h, W);
|
|
901
|
+
if (B.done) {
|
|
902
|
+
X.value = !0;
|
|
902
903
|
break;
|
|
903
904
|
}
|
|
904
|
-
!
|
|
905
|
-
} catch (
|
|
906
|
-
|
|
905
|
+
!v && B.content && (v = Date.now(), d("started")), a.value += B.content, m === null && de();
|
|
906
|
+
} catch (h) {
|
|
907
|
+
X.value = !0, console.log(3333, h), d("failed", h), D();
|
|
907
908
|
break;
|
|
908
909
|
} finally {
|
|
909
|
-
|
|
910
|
+
ae();
|
|
910
911
|
}
|
|
911
|
-
},
|
|
912
|
-
|
|
913
|
-
},
|
|
914
|
-
},
|
|
912
|
+
}, me = async () => {
|
|
913
|
+
o.scrollToBottomFn && o.scrollToBottomFn();
|
|
914
|
+
}, ve = (W = () => {
|
|
915
|
+
}, h = () => {
|
|
915
916
|
}) => {
|
|
916
|
-
const
|
|
917
|
-
|
|
918
|
-
},
|
|
919
|
-
if (l.value &&
|
|
920
|
-
cancelAnimationFrame(
|
|
917
|
+
const j = S.value.content.length;
|
|
918
|
+
_.value > j && (_.value = j), _.value < j ? (_.value = Math.min(j, _.value + cs), W()) : h();
|
|
919
|
+
}, de = () => {
|
|
920
|
+
if (l.value && m) {
|
|
921
|
+
cancelAnimationFrame(m), m = null, i.value = !1;
|
|
921
922
|
return;
|
|
922
923
|
}
|
|
923
|
-
|
|
924
|
+
X.value ? ve(
|
|
924
925
|
() => {
|
|
925
|
-
|
|
926
|
+
m = requestAnimationFrame(de), d("updating", null);
|
|
926
927
|
},
|
|
927
928
|
() => {
|
|
928
|
-
|
|
929
|
-
if (
|
|
929
|
+
M(), d("completed", a.value), i.value = !1, c.value = !0, Ct(() => {
|
|
930
|
+
if (X.value = !1, o.messagePostRender && P.value)
|
|
930
931
|
try {
|
|
931
|
-
|
|
932
|
-
} catch (
|
|
933
|
-
console.error("messagePostRender 执行失败:",
|
|
932
|
+
o.messagePostRender(P.value, S.value.content);
|
|
933
|
+
} catch (W) {
|
|
934
|
+
console.error("messagePostRender 执行失败:", W);
|
|
934
935
|
}
|
|
935
|
-
}),
|
|
936
|
+
}), m = null;
|
|
936
937
|
}
|
|
937
|
-
) : (
|
|
938
|
+
) : (ve(), m = requestAnimationFrame(de)), me();
|
|
938
939
|
};
|
|
939
|
-
|
|
940
|
-
() =>
|
|
940
|
+
ye(
|
|
941
|
+
() => o.reader,
|
|
941
942
|
() => {
|
|
942
|
-
|
|
943
|
+
o.reader && ue();
|
|
943
944
|
},
|
|
944
945
|
{
|
|
945
946
|
immediate: !0,
|
|
946
947
|
deep: !0
|
|
947
948
|
}
|
|
948
|
-
),
|
|
949
|
-
A && (A(), A = null),
|
|
949
|
+
), De(() => {
|
|
950
|
+
A && (A(), A = null), D();
|
|
950
951
|
}), t({
|
|
951
|
-
abortReader:
|
|
952
|
-
initializeStart:
|
|
953
|
-
initializeEnd:
|
|
954
|
-
|
|
955
|
-
|
|
952
|
+
abortReader: D,
|
|
953
|
+
initializeStart: oe,
|
|
954
|
+
initializeEnd: ae,
|
|
955
|
+
// 全双工语音集成(ChatPanel 喂 TTS 用):流式原文与中止状态
|
|
956
|
+
getRawText: () => a.value,
|
|
957
|
+
isAborted: () => l.value
|
|
958
|
+
}), q(() => K.value ? !0 : (!o.reader || !i || a.value, !1));
|
|
959
|
+
const Ae = async () => {
|
|
956
960
|
try {
|
|
957
|
-
const
|
|
958
|
-
await
|
|
959
|
-
} catch (
|
|
960
|
-
console.error("复制失败:",
|
|
961
|
+
const W = S.value.content || a.value;
|
|
962
|
+
await os(W), r.success("复制成功");
|
|
963
|
+
} catch (W) {
|
|
964
|
+
console.error("复制失败:", W), r.error("复制失败");
|
|
961
965
|
}
|
|
962
966
|
};
|
|
963
|
-
return (
|
|
964
|
-
default:
|
|
965
|
-
|
|
967
|
+
return (W, h) => (T(), Se(Le, { name: "fade" }, {
|
|
968
|
+
default: ie(() => [
|
|
969
|
+
se.value || x.value ? (T(), L("div", {
|
|
966
970
|
key: 0,
|
|
967
971
|
ref_key: "refWrapperContent",
|
|
968
972
|
ref: P,
|
|
@@ -970,65 +974,65 @@ const vn = (e, t) => {
|
|
|
970
974
|
class: "w-full h-full overflow-y-auto relative",
|
|
971
975
|
"p-24px": ""
|
|
972
976
|
}, [
|
|
973
|
-
|
|
977
|
+
x.value ? (T(), L("div", {
|
|
974
978
|
key: 0,
|
|
975
|
-
class:
|
|
976
|
-
"is-expanded":
|
|
977
|
-
"is-streaming":
|
|
979
|
+
class: le(["ai-thinking-block", {
|
|
980
|
+
"is-expanded": u.value || w.value,
|
|
981
|
+
"is-streaming": w.value
|
|
978
982
|
}])
|
|
979
983
|
}, [
|
|
980
|
-
|
|
984
|
+
p("div", {
|
|
981
985
|
class: "thinking-header",
|
|
982
|
-
onClick:
|
|
986
|
+
onClick: k
|
|
983
987
|
}, [
|
|
984
|
-
|
|
988
|
+
h[0] || (h[0] = p("svg", {
|
|
985
989
|
class: "thinking-arrow",
|
|
986
990
|
viewBox: "0 0 1024 1024",
|
|
987
991
|
width: "10",
|
|
988
992
|
height: "10"
|
|
989
993
|
}, [
|
|
990
|
-
|
|
994
|
+
p("path", {
|
|
991
995
|
d: "M704 512 320 256v512z",
|
|
992
996
|
fill: "currentColor"
|
|
993
997
|
})
|
|
994
998
|
], -1)),
|
|
995
|
-
|
|
996
|
-
|
|
999
|
+
p("span", rs, Q(F.value), 1),
|
|
1000
|
+
p("span", as, Q(u.value || w.value ? "收起" : "展开"), 1)
|
|
997
1001
|
]),
|
|
998
|
-
|
|
1002
|
+
kt(p("div", {
|
|
999
1003
|
class: "thinking-body",
|
|
1000
|
-
innerHTML:
|
|
1001
|
-
}, null, 8,
|
|
1002
|
-
[
|
|
1004
|
+
innerHTML: I.value
|
|
1005
|
+
}, null, 8, is), [
|
|
1006
|
+
[St, u.value || w.value]
|
|
1003
1007
|
])
|
|
1004
|
-
], 2)) :
|
|
1005
|
-
|
|
1008
|
+
], 2)) : H("", !0),
|
|
1009
|
+
p("div", {
|
|
1006
1010
|
class: "markdown-wrapper",
|
|
1007
|
-
innerHTML:
|
|
1008
|
-
}, null, 8,
|
|
1009
|
-
c.value ? (
|
|
1011
|
+
innerHTML: se.value
|
|
1012
|
+
}, null, 8, ls),
|
|
1013
|
+
c.value ? (T(), L("div", {
|
|
1010
1014
|
key: 1,
|
|
1011
1015
|
class: "ai-copy-btn-wrapper",
|
|
1012
|
-
onClick:
|
|
1016
|
+
onClick: Ae
|
|
1013
1017
|
}, [
|
|
1014
|
-
|
|
1018
|
+
ne(Ve, {
|
|
1015
1019
|
name: "/images/svg/copy.svg",
|
|
1016
1020
|
color: "#666666"
|
|
1017
1021
|
}),
|
|
1018
|
-
|
|
1019
|
-
])) :
|
|
1020
|
-
], 512)) :
|
|
1022
|
+
h[1] || (h[1] = p("span", { class: "copy-text" }, "复制", -1))
|
|
1023
|
+
])) : H("", !0)
|
|
1024
|
+
], 512)) : H("", !0)
|
|
1021
1025
|
]),
|
|
1022
1026
|
_: 1
|
|
1023
1027
|
}));
|
|
1024
1028
|
}
|
|
1025
1029
|
};
|
|
1026
|
-
class
|
|
1027
|
-
constructor(t,
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
this.ratio = t /
|
|
1030
|
+
class ds {
|
|
1031
|
+
constructor(t, n) {
|
|
1032
|
+
N(this, "ratio");
|
|
1033
|
+
N(this, "leftover", new Float32Array(0));
|
|
1034
|
+
N(this, "fracOffset", 0);
|
|
1035
|
+
this.ratio = t / n;
|
|
1032
1036
|
}
|
|
1033
1037
|
reset() {
|
|
1034
1038
|
this.leftover = new Float32Array(0), this.fracOffset = 0;
|
|
@@ -1036,32 +1040,32 @@ class Un {
|
|
|
1036
1040
|
process(t) {
|
|
1037
1041
|
if (this.ratio === 1)
|
|
1038
1042
|
return new Float32Array(t);
|
|
1039
|
-
const
|
|
1040
|
-
if (
|
|
1041
|
-
return this.leftover =
|
|
1042
|
-
const
|
|
1043
|
-
let
|
|
1044
|
-
for (;
|
|
1045
|
-
const a = Math.floor(
|
|
1046
|
-
|
|
1043
|
+
const n = new Float32Array(this.leftover.length + t.length);
|
|
1044
|
+
if (n.set(this.leftover), n.set(t, this.leftover.length), n.length < 2)
|
|
1045
|
+
return this.leftover = n, new Float32Array(0);
|
|
1046
|
+
const s = [];
|
|
1047
|
+
let r = this.fracOffset;
|
|
1048
|
+
for (; r < n.length - 1; ) {
|
|
1049
|
+
const a = Math.floor(r), i = r - a, l = n[a], c = n[a + 1];
|
|
1050
|
+
s.push(l + i * (c - l)), r += this.ratio;
|
|
1047
1051
|
}
|
|
1048
|
-
const
|
|
1049
|
-
return this.leftover =
|
|
1052
|
+
const o = Math.min(n.length, Math.floor(r));
|
|
1053
|
+
return this.leftover = n.slice(o), this.fracOffset = r - o, Float32Array.from(s);
|
|
1050
1054
|
}
|
|
1051
1055
|
}
|
|
1052
|
-
class
|
|
1056
|
+
class fs {
|
|
1053
1057
|
constructor(t = {}) {
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1058
|
+
N(this, "targetSampleRate");
|
|
1059
|
+
N(this, "audioContext", null);
|
|
1060
|
+
N(this, "mediaStream", null);
|
|
1061
|
+
N(this, "sourceNode", null);
|
|
1062
|
+
N(this, "processorNode", null);
|
|
1063
|
+
N(this, "muteGain", null);
|
|
1064
|
+
N(this, "resampler", null);
|
|
1065
|
+
N(this, "audioChunks", []);
|
|
1066
|
+
N(this, "onVolumeChange");
|
|
1067
|
+
N(this, "onAudioChunk");
|
|
1068
|
+
N(this, "_isRecording", !1);
|
|
1065
1069
|
this.targetSampleRate = t.sampleRate || 16e3, this.onVolumeChange = t.onVolumeChange, this.onAudioChunk = t.onAudioChunk;
|
|
1066
1070
|
}
|
|
1067
1071
|
get isRecording() {
|
|
@@ -1084,8 +1088,8 @@ class _n {
|
|
|
1084
1088
|
autoGainControl: !0
|
|
1085
1089
|
}
|
|
1086
1090
|
});
|
|
1087
|
-
} catch (
|
|
1088
|
-
throw
|
|
1091
|
+
} catch (s) {
|
|
1092
|
+
throw s.name === "NotAllowedError" || s.name === "PermissionDeniedError" ? new Error("麦克风权限被拒绝,请在浏览器地址栏允许麦克风访问权限。") : s.name === "NotFoundError" || s.name === "DevicesNotFoundError" ? new Error("未检测到可用的麦克风输入设备。") : new Error(`无法启动麦克风: ${s.message || s}`);
|
|
1089
1093
|
}
|
|
1090
1094
|
const t = window.AudioContext || window.webkitAudioContext;
|
|
1091
1095
|
try {
|
|
@@ -1093,21 +1097,21 @@ class _n {
|
|
|
1093
1097
|
} catch {
|
|
1094
1098
|
this.audioContext = new t();
|
|
1095
1099
|
}
|
|
1096
|
-
this.audioContext.state === "suspended" && await this.audioContext.resume(), this.audioChunks = [], this.resampler = this.audioContext.sampleRate === this.targetSampleRate ? null : new
|
|
1097
|
-
const
|
|
1098
|
-
this.processorNode = this.audioContext.createScriptProcessor(
|
|
1100
|
+
this.audioContext.state === "suspended" && await this.audioContext.resume(), this.audioChunks = [], this.resampler = this.audioContext.sampleRate === this.targetSampleRate ? null : new ds(this.audioContext.sampleRate, this.targetSampleRate), this.sourceNode = this.audioContext.createMediaStreamSource(this.mediaStream);
|
|
1101
|
+
const n = 4096;
|
|
1102
|
+
this.processorNode = this.audioContext.createScriptProcessor(n, 1, 1), this.processorNode.onaudioprocess = (s) => {
|
|
1099
1103
|
var a;
|
|
1100
1104
|
if (!this._isRecording) return;
|
|
1101
|
-
const
|
|
1105
|
+
const r = new Float32Array(s.inputBuffer.getChannelData(0));
|
|
1102
1106
|
if (this.onVolumeChange) {
|
|
1103
1107
|
let i = 0;
|
|
1104
|
-
for (let
|
|
1105
|
-
i +=
|
|
1106
|
-
const l = Math.sqrt(i /
|
|
1108
|
+
for (let d = 0; d < r.length; d++)
|
|
1109
|
+
i += r[d] * r[d];
|
|
1110
|
+
const l = Math.sqrt(i / r.length), c = Math.min(100, Math.round(l * 100 * 5));
|
|
1107
1111
|
this.onVolumeChange(c);
|
|
1108
1112
|
}
|
|
1109
|
-
const
|
|
1110
|
-
|
|
1113
|
+
const o = this.resampler ? this.resampler.process(r) : r;
|
|
1114
|
+
o.length && (this.audioChunks.push(o), (a = this.onAudioChunk) == null || a.call(this, o));
|
|
1111
1115
|
}, this.muteGain = this.audioContext.createGain(), this.muteGain.gain.value = 0, this.sourceNode.connect(this.processorNode), this.processorNode.connect(this.muteGain), this.muteGain.connect(this.audioContext.destination), this._isRecording = !0;
|
|
1112
1116
|
}
|
|
1113
1117
|
/**
|
|
@@ -1117,11 +1121,11 @@ class _n {
|
|
|
1117
1121
|
if (!this._isRecording)
|
|
1118
1122
|
return new Float32Array(0);
|
|
1119
1123
|
this._isRecording = !1, this.cleanup();
|
|
1120
|
-
const t = this.audioChunks.reduce((
|
|
1121
|
-
let
|
|
1122
|
-
for (const
|
|
1123
|
-
|
|
1124
|
-
return this.audioChunks = [],
|
|
1124
|
+
const t = this.audioChunks.reduce((r, o) => r + o.length, 0), n = new Float32Array(t);
|
|
1125
|
+
let s = 0;
|
|
1126
|
+
for (const r of this.audioChunks)
|
|
1127
|
+
n.set(r, s), s += r.length;
|
|
1128
|
+
return this.audioChunks = [], n;
|
|
1125
1129
|
}
|
|
1126
1130
|
/**
|
|
1127
1131
|
* 取消录音并丢弃采集的数据
|
|
@@ -1134,99 +1138,99 @@ class _n {
|
|
|
1134
1138
|
}), this.audioContext = null);
|
|
1135
1139
|
}
|
|
1136
1140
|
}
|
|
1137
|
-
function
|
|
1138
|
-
if (t ===
|
|
1141
|
+
function hs(e, t, n) {
|
|
1142
|
+
if (t === n)
|
|
1139
1143
|
return new Float32Array(e);
|
|
1140
|
-
const
|
|
1141
|
-
for (let a = 0; a <
|
|
1142
|
-
const i = a *
|
|
1143
|
-
|
|
1144
|
+
const s = t / n, r = Math.round(e.length / s), o = new Float32Array(r);
|
|
1145
|
+
for (let a = 0; a < r; a++) {
|
|
1146
|
+
const i = a * s, l = Math.floor(i), c = i - l, d = e[l] ?? 0, P = e[l + 1] ?? d;
|
|
1147
|
+
o[a] = d + c * (P - d);
|
|
1144
1148
|
}
|
|
1145
|
-
return
|
|
1149
|
+
return o;
|
|
1146
1150
|
}
|
|
1147
|
-
async function
|
|
1148
|
-
const
|
|
1151
|
+
async function ps(e, t = 16e3) {
|
|
1152
|
+
const n = await e.arrayBuffer(), s = window.AudioContext || window.webkitAudioContext, r = new s();
|
|
1149
1153
|
try {
|
|
1150
|
-
const
|
|
1154
|
+
const o = await r.decodeAudioData(n);
|
|
1151
1155
|
let a;
|
|
1152
|
-
if (
|
|
1153
|
-
a = new Float32Array(
|
|
1154
|
-
for (let i = 0; i <
|
|
1155
|
-
const l =
|
|
1156
|
-
for (let c = 0; c <
|
|
1157
|
-
a[c] += l[c] /
|
|
1156
|
+
if (o.numberOfChannels > 1) {
|
|
1157
|
+
a = new Float32Array(o.length);
|
|
1158
|
+
for (let i = 0; i < o.numberOfChannels; i++) {
|
|
1159
|
+
const l = o.getChannelData(i);
|
|
1160
|
+
for (let c = 0; c < o.length; c++)
|
|
1161
|
+
a[c] += l[c] / o.numberOfChannels;
|
|
1158
1162
|
}
|
|
1159
1163
|
} else
|
|
1160
|
-
a =
|
|
1161
|
-
return
|
|
1164
|
+
a = o.getChannelData(0);
|
|
1165
|
+
return hs(a, o.sampleRate, t);
|
|
1162
1166
|
} finally {
|
|
1163
|
-
|
|
1167
|
+
r.state !== "closed" && await r.close().catch(() => {
|
|
1164
1168
|
});
|
|
1165
1169
|
}
|
|
1166
1170
|
}
|
|
1167
|
-
function
|
|
1168
|
-
const
|
|
1171
|
+
function ft(e, t = 16e3) {
|
|
1172
|
+
const n = new ArrayBuffer(44 + e.length * 2), s = new DataView(n), r = (a, i) => {
|
|
1169
1173
|
for (let l = 0; l < i.length; l++)
|
|
1170
|
-
|
|
1174
|
+
s.setUint8(a + l, i.charCodeAt(l));
|
|
1171
1175
|
};
|
|
1172
|
-
|
|
1173
|
-
let
|
|
1174
|
-
for (let a = 0; a < e.length; a++,
|
|
1176
|
+
r(0, "RIFF"), s.setUint32(4, 36 + e.length * 2, !0), r(8, "WAVE"), r(12, "fmt "), s.setUint32(16, 16, !0), s.setUint16(20, 1, !0), s.setUint16(22, 1, !0), s.setUint32(24, t, !0), s.setUint32(28, t * 2, !0), s.setUint16(32, 2, !0), s.setUint16(34, 16, !0), r(36, "data"), s.setUint32(40, e.length * 2, !0);
|
|
1177
|
+
let o = 44;
|
|
1178
|
+
for (let a = 0; a < e.length; a++, o += 2) {
|
|
1175
1179
|
const i = Math.max(-1, Math.min(1, e[a]));
|
|
1176
|
-
|
|
1180
|
+
s.setInt16(o, i < 0 ? i * 32768 : i * 32767, !0);
|
|
1177
1181
|
}
|
|
1178
|
-
return new Blob([
|
|
1182
|
+
return new Blob([s], { type: "audio/wav" });
|
|
1179
1183
|
}
|
|
1180
|
-
const
|
|
1181
|
-
function
|
|
1182
|
-
return new Worker(
|
|
1184
|
+
const Pt = 16e3, ms = Math.round(Pt * 0.35), Ut = "/scripts/ai/whisper.worker.js";
|
|
1185
|
+
function vs() {
|
|
1186
|
+
return new Worker(Ze(Ut), { type: "module" });
|
|
1183
1187
|
}
|
|
1184
|
-
function
|
|
1188
|
+
function Ze(e) {
|
|
1185
1189
|
return /^https?:\/\//i.test(e) ? e : typeof location < "u" ? new URL(e, location.origin).href : e;
|
|
1186
1190
|
}
|
|
1187
|
-
function
|
|
1191
|
+
function ht(e) {
|
|
1188
1192
|
if (!e.ok) return !1;
|
|
1189
1193
|
const t = (e.headers.get("content-type") || "").toLowerCase();
|
|
1190
1194
|
return !(t.includes("text/html") || t.includes("application/xhtml+xml"));
|
|
1191
1195
|
}
|
|
1192
|
-
async function
|
|
1196
|
+
async function gs(e) {
|
|
1193
1197
|
try {
|
|
1194
1198
|
const t = await fetch(e, { method: "HEAD" });
|
|
1195
|
-
if (
|
|
1199
|
+
if (ht(t)) return !0;
|
|
1196
1200
|
} catch {
|
|
1197
1201
|
}
|
|
1198
1202
|
try {
|
|
1199
1203
|
const t = await fetch(e, { headers: { Range: "bytes=0-64" } });
|
|
1200
|
-
if (
|
|
1204
|
+
if (ht(t)) return !0;
|
|
1201
1205
|
} catch {
|
|
1202
1206
|
}
|
|
1203
1207
|
return !1;
|
|
1204
1208
|
}
|
|
1205
|
-
async function
|
|
1209
|
+
async function ys(e) {
|
|
1206
1210
|
const t = [];
|
|
1207
|
-
e && t.push(
|
|
1208
|
-
const
|
|
1209
|
-
for (const
|
|
1210
|
-
if (await
|
|
1211
|
-
return console.log("[VoiceInputManager] 使用语音 Worker:",
|
|
1211
|
+
e && t.push(Ze(e)), t.push(Ze(Ut));
|
|
1212
|
+
const n = [...new Set(t.filter(Boolean))];
|
|
1213
|
+
for (const s of n)
|
|
1214
|
+
if (await gs(s))
|
|
1215
|
+
return console.log("[VoiceInputManager] 使用语音 Worker:", s), s;
|
|
1212
1216
|
return console.warn(
|
|
1213
1217
|
"[VoiceInputManager] 未探测到可访问的 Worker 脚本,将回退到 Vite 打包注入地址。已尝试:",
|
|
1214
|
-
|
|
1218
|
+
n.join(" , ")
|
|
1215
1219
|
), null;
|
|
1216
1220
|
}
|
|
1217
|
-
class
|
|
1221
|
+
class ws {
|
|
1218
1222
|
constructor(t = {}) {
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1223
|
+
N(this, "recorder", null);
|
|
1224
|
+
N(this, "worker", null);
|
|
1225
|
+
N(this, "status", "idle");
|
|
1226
|
+
N(this, "options");
|
|
1227
|
+
N(this, "isReady", !1);
|
|
1228
|
+
N(this, "initPromise", null);
|
|
1229
|
+
N(this, "currentTaskId", 0);
|
|
1230
|
+
N(this, "pcmParts", []);
|
|
1231
|
+
N(this, "pcmLength", 0);
|
|
1232
|
+
N(this, "streamChunkIndex", 0);
|
|
1233
|
+
N(this, "committedText", "");
|
|
1230
1234
|
this.options = {
|
|
1231
1235
|
soundBaseUrl: "/sounds/",
|
|
1232
1236
|
remoteHost: "https://hf-mirror.com",
|
|
@@ -1246,17 +1250,17 @@ class Ln {
|
|
|
1246
1250
|
*/
|
|
1247
1251
|
async init(t) {
|
|
1248
1252
|
if (!this.isReady)
|
|
1249
|
-
return this.initPromise ? this.initPromise : (t && (this.options.soundBaseUrl = t), this.initPromise = new Promise((
|
|
1253
|
+
return this.initPromise ? this.initPromise : (t && (this.options.soundBaseUrl = t), this.initPromise = new Promise((n, s) => {
|
|
1250
1254
|
this.setStatus("loading", "正在准备语音识别引擎..."), (async () => {
|
|
1251
|
-
var
|
|
1255
|
+
var o, a;
|
|
1252
1256
|
try {
|
|
1253
|
-
const i = await
|
|
1254
|
-
this.worker = i ? new Worker(i, { type: "module" }) :
|
|
1255
|
-
this.handleWorkerMessage(l,
|
|
1257
|
+
const i = await ys(this.options.workerUrl);
|
|
1258
|
+
this.worker = i ? new Worker(i, { type: "module" }) : vs(), this.worker.onmessage = (l) => {
|
|
1259
|
+
this.handleWorkerMessage(l, n, s);
|
|
1256
1260
|
}, this.worker.onerror = (l) => {
|
|
1257
1261
|
var P, A;
|
|
1258
|
-
const
|
|
1259
|
-
this.initPromise = null, this.setStatus("error",
|
|
1262
|
+
const d = `语音后台线程异常: ${l.message || l.filename || i || "未知错误"}`;
|
|
1263
|
+
this.initPromise = null, this.setStatus("error", d), (A = (P = this.options).onError) == null || A.call(P, d), s(l);
|
|
1260
1264
|
}, this.worker.postMessage({
|
|
1261
1265
|
type: "INIT",
|
|
1262
1266
|
data: {
|
|
@@ -1267,7 +1271,7 @@ class Ln {
|
|
|
1267
1271
|
});
|
|
1268
1272
|
} catch (i) {
|
|
1269
1273
|
const l = `创建语音 Worker 失败: ${i.message || i}`;
|
|
1270
|
-
this.initPromise = null, this.setStatus("error", l), (a = (
|
|
1274
|
+
this.initPromise = null, this.setStatus("error", l), (a = (o = this.options).onError) == null || a.call(o, l), s(i);
|
|
1271
1275
|
}
|
|
1272
1276
|
})();
|
|
1273
1277
|
}), this.initPromise);
|
|
@@ -1276,94 +1280,94 @@ class Ln {
|
|
|
1276
1280
|
* 开始语音录入(只采集,点「完成」后再转写)
|
|
1277
1281
|
*/
|
|
1278
1282
|
async startRecording() {
|
|
1279
|
-
var t, s, r
|
|
1283
|
+
var t, n, s, r;
|
|
1280
1284
|
if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
|
|
1281
|
-
const
|
|
1282
|
-
throw this.setStatus("error",
|
|
1285
|
+
const o = window.isSecureContext ? "当前浏览器环境不支持获取麦克风音频,请使用现代浏览器。" : "当前页面不是安全上下文,浏览器禁止调用麦克风。请使用 https:// 或 http://localhost / http://127.0.0.1 访问(通过局域网 IP 的 http 地址无法录音)。";
|
|
1286
|
+
throw this.setStatus("error", o), (n = (t = this.options).onError) == null || n.call(t, o), new Error(o);
|
|
1283
1287
|
}
|
|
1284
|
-
this.isReady || await this.init(), this.recorder || (this.recorder = new
|
|
1285
|
-
onVolumeChange: (
|
|
1288
|
+
this.isReady || await this.init(), this.recorder || (this.recorder = new fs({
|
|
1289
|
+
onVolumeChange: (o) => {
|
|
1286
1290
|
var a, i;
|
|
1287
|
-
(i = (a = this.options).onVolumeChange) == null || i.call(a,
|
|
1291
|
+
(i = (a = this.options).onVolumeChange) == null || i.call(a, o);
|
|
1288
1292
|
},
|
|
1289
|
-
onAudioChunk: (
|
|
1290
|
-
this.appendPcm(
|
|
1293
|
+
onAudioChunk: (o) => {
|
|
1294
|
+
this.appendPcm(o);
|
|
1291
1295
|
}
|
|
1292
1296
|
}));
|
|
1293
1297
|
try {
|
|
1294
1298
|
this.currentTaskId++, this.resetStreamState(), await this.recorder.start(), this.setStatus("recording", "正在录音...");
|
|
1295
|
-
} catch (
|
|
1296
|
-
throw this.setStatus("error",
|
|
1299
|
+
} catch (o) {
|
|
1300
|
+
throw this.setStatus("error", o.message || "启动录音失败"), (r = (s = this.options).onError) == null || r.call(s, o.message || "启动录音失败"), o;
|
|
1297
1301
|
}
|
|
1298
1302
|
}
|
|
1299
1303
|
/**
|
|
1300
1304
|
* 停止录音并触发模型端侧推理
|
|
1301
1305
|
*/
|
|
1302
1306
|
async stopAndTranscribe() {
|
|
1303
|
-
var t, s, r
|
|
1307
|
+
var t, n, s, r;
|
|
1304
1308
|
if (!(!this.recorder || !this.recorder.isRecording))
|
|
1305
1309
|
try {
|
|
1306
1310
|
await this.recorder.stop();
|
|
1307
|
-
const
|
|
1308
|
-
if (
|
|
1311
|
+
const o = this.mergePcm();
|
|
1312
|
+
if (o.length === 0) {
|
|
1309
1313
|
this.resetStreamState(), this.setStatus("idle");
|
|
1310
1314
|
return;
|
|
1311
1315
|
}
|
|
1312
1316
|
this.setStatus("transcribing", "正在识别语音...");
|
|
1313
1317
|
try {
|
|
1314
|
-
const a =
|
|
1315
|
-
(
|
|
1318
|
+
const a = ft(o), i = URL.createObjectURL(a);
|
|
1319
|
+
(n = (t = this.options).onAudioRecorded) == null || n.call(t, i, a);
|
|
1316
1320
|
} catch (a) {
|
|
1317
1321
|
console.warn("生成录音回放音频失败:", a);
|
|
1318
1322
|
}
|
|
1319
|
-
await this.transcribeAudioData(
|
|
1320
|
-
} catch (
|
|
1321
|
-
this.setStatus("error",
|
|
1323
|
+
await this.transcribeAudioData(o);
|
|
1324
|
+
} catch (o) {
|
|
1325
|
+
this.setStatus("error", o.message || "音频处理失败"), (r = (s = this.options).onError) == null || r.call(s, o.message || "音频处理失败");
|
|
1322
1326
|
}
|
|
1323
1327
|
}
|
|
1324
1328
|
/**
|
|
1325
1329
|
* 直接对外部传入的 16kHz Float32Array 音频进行端侧推理(例如文件上传)
|
|
1326
1330
|
*/
|
|
1327
|
-
async transcribeAudioData(t,
|
|
1328
|
-
var r, o,
|
|
1331
|
+
async transcribeAudioData(t, n) {
|
|
1332
|
+
var s, r, o, a;
|
|
1329
1333
|
this.isReady || await this.init(), this.setStatus("transcribing", "正在流式识别音频...");
|
|
1330
1334
|
try {
|
|
1331
|
-
|
|
1335
|
+
n && ((r = (s = this.options).onAudioRecorded) == null || r.call(s, n, ft(t))), this.currentTaskId++, this.resetStreamState(), this.appendPcm(t), this.dispatchFullAudio();
|
|
1332
1336
|
} catch (i) {
|
|
1333
|
-
this.setStatus("error", i.message || "音频处理失败"), (a = (
|
|
1337
|
+
this.setStatus("error", i.message || "音频处理失败"), (a = (o = this.options).onError) == null || a.call(o, i.message || "音频处理失败");
|
|
1334
1338
|
}
|
|
1335
1339
|
}
|
|
1336
1340
|
/**
|
|
1337
1341
|
* 上传音频/视频文件(支持 mp4, wav, mp3, m4a 等)并在浏览器端解析识别
|
|
1338
1342
|
*/
|
|
1339
1343
|
async transcribeFile(t) {
|
|
1340
|
-
var
|
|
1344
|
+
var n, s;
|
|
1341
1345
|
this.isReady || await this.init(), this.setStatus("loading", "正在解析音频文件...");
|
|
1342
1346
|
try {
|
|
1343
|
-
const
|
|
1344
|
-
if (
|
|
1347
|
+
const r = await ps(t);
|
|
1348
|
+
if (r.length === 0)
|
|
1345
1349
|
throw new Error("未能从该文件中提取出有效音频");
|
|
1346
|
-
const
|
|
1347
|
-
await this.transcribeAudioData(
|
|
1348
|
-
} catch (
|
|
1349
|
-
this.setStatus("error",
|
|
1350
|
+
const o = URL.createObjectURL(t);
|
|
1351
|
+
await this.transcribeAudioData(r, o);
|
|
1352
|
+
} catch (r) {
|
|
1353
|
+
this.setStatus("error", r.message || "音频文件解析失败"), (s = (n = this.options).onError) == null || s.call(n, r.message || "音频文件解析失败");
|
|
1350
1354
|
}
|
|
1351
1355
|
}
|
|
1352
1356
|
/**
|
|
1353
1357
|
* 取消当前录音并丢弃
|
|
1354
1358
|
*/
|
|
1355
1359
|
cancelRecording() {
|
|
1356
|
-
var
|
|
1360
|
+
var n;
|
|
1357
1361
|
const t = this.currentTaskId;
|
|
1358
|
-
this.currentTaskId++, (
|
|
1362
|
+
this.currentTaskId++, (n = this.worker) == null || n.postMessage({ type: "CANCEL", taskId: t }), this.resetStreamState(), this.recorder && this.recorder.cancel(), this.setStatus("idle");
|
|
1359
1363
|
}
|
|
1360
1364
|
/**
|
|
1361
1365
|
* 取消当前的语音识别推理任务
|
|
1362
1366
|
*/
|
|
1363
1367
|
cancelTranscribe() {
|
|
1364
|
-
var
|
|
1368
|
+
var n;
|
|
1365
1369
|
const t = this.currentTaskId;
|
|
1366
|
-
this.currentTaskId++, (
|
|
1370
|
+
this.currentTaskId++, (n = this.worker) == null || n.postMessage({ type: "CANCEL", taskId: t }), this.resetStreamState(), (this.status === "transcribing" || this.status === "recording") && this.setStatus("idle");
|
|
1367
1371
|
}
|
|
1368
1372
|
/**
|
|
1369
1373
|
* 清除本地模型缓存
|
|
@@ -1375,9 +1379,9 @@ class Ln {
|
|
|
1375
1379
|
* 销毁并释放所有资源
|
|
1376
1380
|
*/
|
|
1377
1381
|
destroy() {
|
|
1378
|
-
var
|
|
1382
|
+
var n;
|
|
1379
1383
|
const t = this.currentTaskId;
|
|
1380
|
-
this.currentTaskId++, (
|
|
1384
|
+
this.currentTaskId++, (n = this.worker) == null || n.postMessage({ type: "CANCEL", taskId: t }), this.resetStreamState(), this.recorder && (this.recorder.cancel(), this.recorder = null), this.worker && (this.worker.terminate(), this.worker = null), this.isReady = !1, this.initPromise = null, this.setStatus("idle");
|
|
1381
1385
|
}
|
|
1382
1386
|
resetStreamState() {
|
|
1383
1387
|
this.pcmParts = [], this.pcmLength = 0, this.streamChunkIndex = 0, this.committedText = "";
|
|
@@ -1387,19 +1391,19 @@ class Ln {
|
|
|
1387
1391
|
}
|
|
1388
1392
|
mergePcm() {
|
|
1389
1393
|
const t = new Float32Array(this.pcmLength);
|
|
1390
|
-
let
|
|
1391
|
-
for (const
|
|
1392
|
-
t.set(
|
|
1394
|
+
let n = 0;
|
|
1395
|
+
for (const s of this.pcmParts)
|
|
1396
|
+
t.set(s, n), n += s.length;
|
|
1393
1397
|
return t;
|
|
1394
1398
|
}
|
|
1395
1399
|
emitPartial(t) {
|
|
1396
|
-
var
|
|
1397
|
-
(
|
|
1400
|
+
var n, s;
|
|
1401
|
+
(s = (n = this.options).onPartial) == null || s.call(n, (t || "").trim());
|
|
1398
1402
|
}
|
|
1399
1403
|
finishStream(t) {
|
|
1400
|
-
var
|
|
1401
|
-
const
|
|
1402
|
-
this.setStatus("idle"), (
|
|
1404
|
+
var s, r;
|
|
1405
|
+
const n = (t ?? this.committedText).trim();
|
|
1406
|
+
this.setStatus("idle"), (r = (s = this.options).onResult) == null || r.call(s, n);
|
|
1403
1407
|
}
|
|
1404
1408
|
/**
|
|
1405
1409
|
* 录音结束或上传:整段一次送入 Worker。超过 30s 由 Worker 按重叠窗口切分。
|
|
@@ -1409,11 +1413,11 @@ class Ln {
|
|
|
1409
1413
|
this.finishStream();
|
|
1410
1414
|
return;
|
|
1411
1415
|
}
|
|
1412
|
-
if (this.pcmLength <
|
|
1416
|
+
if (this.pcmLength < ms) {
|
|
1413
1417
|
this.finishStream();
|
|
1414
1418
|
return;
|
|
1415
1419
|
}
|
|
1416
|
-
const t = this.mergePcm(),
|
|
1420
|
+
const t = this.mergePcm(), n = t.length > Pt * 30;
|
|
1417
1421
|
this.committedText = "", this.worker.postMessage(
|
|
1418
1422
|
{
|
|
1419
1423
|
type: "TRANSCRIBE",
|
|
@@ -1425,28 +1429,28 @@ class Ln {
|
|
|
1425
1429
|
chunkIndex: this.streamChunkIndex++,
|
|
1426
1430
|
isFinal: !0,
|
|
1427
1431
|
mode: "append",
|
|
1428
|
-
nativeChunking:
|
|
1432
|
+
nativeChunking: n
|
|
1429
1433
|
}
|
|
1430
1434
|
},
|
|
1431
1435
|
[t.buffer]
|
|
1432
1436
|
);
|
|
1433
1437
|
}
|
|
1434
|
-
handleWorkerMessage(t,
|
|
1435
|
-
var c,
|
|
1436
|
-
const { type:
|
|
1437
|
-
switch (
|
|
1438
|
+
handleWorkerMessage(t, n, s) {
|
|
1439
|
+
var c, d, P, A;
|
|
1440
|
+
const { type: r, data: o, taskId: a, text: i, error: l } = t.data;
|
|
1441
|
+
switch (r) {
|
|
1438
1442
|
case "READY":
|
|
1439
|
-
this.isReady = !0, this.setStatus("ready", "语音引擎就绪"),
|
|
1443
|
+
this.isReady = !0, this.setStatus("ready", "语音引擎就绪"), n == null || n();
|
|
1440
1444
|
break;
|
|
1441
1445
|
case "PROGRESS":
|
|
1442
|
-
if (
|
|
1443
|
-
const
|
|
1444
|
-
this.setStatus("downloading", `正在下载语音模型... ${
|
|
1445
|
-
status:
|
|
1446
|
-
progress:
|
|
1447
|
-
file:
|
|
1448
|
-
loaded:
|
|
1449
|
-
total:
|
|
1446
|
+
if (o) {
|
|
1447
|
+
const m = typeof o.progress == "number" ? Math.round(o.progress) : 0;
|
|
1448
|
+
this.setStatus("downloading", `正在下载语音模型... ${m}%`), (d = (c = this.options).onProgress) == null || d.call(c, {
|
|
1449
|
+
status: o.status || "progress",
|
|
1450
|
+
progress: m,
|
|
1451
|
+
file: o.file,
|
|
1452
|
+
loaded: o.loaded,
|
|
1453
|
+
total: o.total
|
|
1450
1454
|
});
|
|
1451
1455
|
}
|
|
1452
1456
|
break;
|
|
@@ -1468,63 +1472,1056 @@ class Ln {
|
|
|
1468
1472
|
break;
|
|
1469
1473
|
case "ERROR":
|
|
1470
1474
|
if (a && a !== this.currentTaskId) return;
|
|
1471
|
-
this.setStatus("error", l || "语音服务异常"), (A = (P = this.options).onError) == null || A.call(P, l || "语音服务异常"),
|
|
1475
|
+
this.setStatus("error", l || "语音服务异常"), (A = (P = this.options).onError) == null || A.call(P, l || "语音服务异常"), s == null || s(new Error(l));
|
|
1472
1476
|
break;
|
|
1473
1477
|
}
|
|
1474
1478
|
}
|
|
1475
|
-
setStatus(t,
|
|
1476
|
-
var
|
|
1477
|
-
this.status = t, (
|
|
1479
|
+
setStatus(t, n) {
|
|
1480
|
+
var s, r;
|
|
1481
|
+
this.status = t, (r = (s = this.options).onStatusChange) == null || r.call(s, t, n);
|
|
1482
|
+
}
|
|
1483
|
+
}
|
|
1484
|
+
const xe = 16e3, pt = 0.015, bs = 0.25, ks = 2e3, mt = 3e4, Ss = 250, vt = 350, Cs = 0.25, As = 900, Ts = 0.5, xs = 12, gt = 1024, Rs = 260, Es = 600, Ls = 80, Mt = 28, nt = "/api/voice", sr = {
|
|
1485
|
+
filterLength: 256,
|
|
1486
|
+
delay: 64,
|
|
1487
|
+
step: 0.1,
|
|
1488
|
+
epsilon: 1e-6
|
|
1489
|
+
}, Ps = 256, Us = 64, Ms = 0.1, _s = 1e-6;
|
|
1490
|
+
class js {
|
|
1491
|
+
constructor(t = {}) {
|
|
1492
|
+
N(this, "w");
|
|
1493
|
+
N(this, "xBuf");
|
|
1494
|
+
N(this, "filterLength");
|
|
1495
|
+
N(this, "delay");
|
|
1496
|
+
N(this, "mu");
|
|
1497
|
+
N(this, "eps");
|
|
1498
|
+
/** Ring cursor into xBuf (reference history). */
|
|
1499
|
+
N(this, "cursor", 0);
|
|
1500
|
+
/** How many reference samples we have buffered so far (for warm-up). */
|
|
1501
|
+
N(this, "filled", 0);
|
|
1502
|
+
this.filterLength = t.filterLength ?? Ps, this.delay = t.delay ?? Us, this.mu = t.step ?? Ms, this.eps = t.epsilon ?? _s, this.w = new Float32Array(this.filterLength), this.xBuf = new Float32Array(this.delay + this.filterLength);
|
|
1503
|
+
}
|
|
1504
|
+
/**
|
|
1505
|
+
* Push the next mic/reference block; returns the echo-removed mic samples
|
|
1506
|
+
* (same length as the input). Reference may be shorter than the mic block
|
|
1507
|
+
* (e.g. silence pad) — it is zero-filled to the block length.
|
|
1508
|
+
*/
|
|
1509
|
+
process(t, n) {
|
|
1510
|
+
const s = t.length, r = new Float32Array(s);
|
|
1511
|
+
if (s === 0) return r;
|
|
1512
|
+
const o = this.xBuf, a = o.length;
|
|
1513
|
+
let i = this.cursor;
|
|
1514
|
+
for (let l = 0; l < s; l++) {
|
|
1515
|
+
o[i] = l < n.length ? n[l] : 0, i = (i + 1) % a, this.filled = Math.min(this.filled + 1, a);
|
|
1516
|
+
const c = t[l];
|
|
1517
|
+
if (this.filled >= this.delay + this.filterLength) {
|
|
1518
|
+
let d = 0, P = 0, A = (i - this.delay + a) % a;
|
|
1519
|
+
for (let _ = 0; _ < this.filterLength; _++) {
|
|
1520
|
+
const w = o[A];
|
|
1521
|
+
d += this.w[_] * w, P += w * w, A = (A - 1 + a) % a;
|
|
1522
|
+
}
|
|
1523
|
+
const m = c - d;
|
|
1524
|
+
r[l] = m;
|
|
1525
|
+
const S = P + this.eps, x = this.mu * m / S;
|
|
1526
|
+
A = (i - this.delay + a) % a;
|
|
1527
|
+
for (let _ = 0; _ < this.filterLength; _++)
|
|
1528
|
+
this.w[_] += x * o[A], A = (A - 1 + a) % a;
|
|
1529
|
+
} else
|
|
1530
|
+
r[l] = c;
|
|
1531
|
+
}
|
|
1532
|
+
return this.cursor = i, r;
|
|
1533
|
+
}
|
|
1534
|
+
/** Reset adaptation (call on start/stop to avoid stale speaker->mic path). */
|
|
1535
|
+
reset() {
|
|
1536
|
+
this.w.fill(0), this.xBuf.fill(0), this.cursor = 0, this.filled = 0;
|
|
1537
|
+
}
|
|
1538
|
+
}
|
|
1539
|
+
const ze = (e, t) => `${e.replace(/\/+$/, "")}${t}`;
|
|
1540
|
+
function Is(e = nt, t = {}) {
|
|
1541
|
+
return fetch(ze(e, "/ready"), { headers: t }).then((n) => n.json());
|
|
1542
|
+
}
|
|
1543
|
+
function zs(e = nt, t = {}) {
|
|
1544
|
+
return fetch(ze(e, "/config"), { headers: t }).then((n) => n.json());
|
|
1545
|
+
}
|
|
1546
|
+
function or(e, t = {}, n, s) {
|
|
1547
|
+
const r = {
|
|
1548
|
+
"content-type": "application/octet-stream",
|
|
1549
|
+
...t
|
|
1550
|
+
};
|
|
1551
|
+
return s !== void 0 && (r["x-voice-session"] = s), fetch(ze(e, "/asr"), {
|
|
1552
|
+
method: "POST",
|
|
1553
|
+
headers: r,
|
|
1554
|
+
// slice() copies so the body is exactly this view's span.
|
|
1555
|
+
body: n.slice().buffer
|
|
1556
|
+
}).then(async (o) => {
|
|
1557
|
+
if (!o.ok) throw new Error(`asr http ${o.status}`);
|
|
1558
|
+
return await o.json();
|
|
1559
|
+
});
|
|
1560
|
+
}
|
|
1561
|
+
function yt(e, t = {}, n) {
|
|
1562
|
+
return fetch(ze(e, "/cancel"), {
|
|
1563
|
+
method: "POST",
|
|
1564
|
+
headers: { "content-type": "application/json", ...t },
|
|
1565
|
+
body: JSON.stringify({ sessionId: n })
|
|
1566
|
+
}).then(async (s) => {
|
|
1567
|
+
if (!s.ok) throw new Error(`cancel http ${s.status}`);
|
|
1568
|
+
return await s.json();
|
|
1569
|
+
});
|
|
1570
|
+
}
|
|
1571
|
+
function $s(e, t = {}, n, s) {
|
|
1572
|
+
const r = ze(e, "/stream");
|
|
1573
|
+
if (!(Object.keys(t).length > 0)) {
|
|
1574
|
+
const S = new EventSource(r);
|
|
1575
|
+
return S.onopen = () => s({ connected: !0 }), S.onerror = () => s({ connected: !1 }), S.addEventListener("audio", (x) => {
|
|
1576
|
+
try {
|
|
1577
|
+
n(JSON.parse(x.data));
|
|
1578
|
+
} catch {
|
|
1579
|
+
}
|
|
1580
|
+
}), { close: () => S.close() };
|
|
1581
|
+
}
|
|
1582
|
+
let a = !1, i = null, l = null, c = "";
|
|
1583
|
+
const d = () => {
|
|
1584
|
+
a || l !== null || (l = setTimeout(() => {
|
|
1585
|
+
l = null, m();
|
|
1586
|
+
}, 3e3));
|
|
1587
|
+
}, P = (S, x) => {
|
|
1588
|
+
if (S === "audio")
|
|
1589
|
+
try {
|
|
1590
|
+
n(JSON.parse(x));
|
|
1591
|
+
} catch {
|
|
1592
|
+
}
|
|
1593
|
+
}, A = () => {
|
|
1594
|
+
let S;
|
|
1595
|
+
for (; (S = c.indexOf(`
|
|
1596
|
+
|
|
1597
|
+
`)) !== -1; ) {
|
|
1598
|
+
const x = c.slice(0, S);
|
|
1599
|
+
c = c.slice(S + 2);
|
|
1600
|
+
let _ = "message";
|
|
1601
|
+
const w = [];
|
|
1602
|
+
for (const u of x.split(`
|
|
1603
|
+
`))
|
|
1604
|
+
u.startsWith(":") || (u.startsWith("event:") ? _ = u.slice(6).trim() : u.startsWith("data:") && w.push(u.slice(5).trimStart()));
|
|
1605
|
+
w.length > 0 && P(_, w.join(`
|
|
1606
|
+
`));
|
|
1607
|
+
}
|
|
1608
|
+
}, m = async () => {
|
|
1609
|
+
if (!a) {
|
|
1610
|
+
i = new AbortController();
|
|
1611
|
+
try {
|
|
1612
|
+
const S = await fetch(r, { headers: t, signal: i.signal });
|
|
1613
|
+
if (!S.ok || !S.body) throw new Error(`stream http ${S.status}`);
|
|
1614
|
+
s({ connected: !0 });
|
|
1615
|
+
const x = S.body.getReader(), _ = new TextDecoder();
|
|
1616
|
+
for (; ; ) {
|
|
1617
|
+
const { done: w, value: u } = await x.read();
|
|
1618
|
+
if (w) break;
|
|
1619
|
+
c += _.decode(u, { stream: !0 }), A();
|
|
1620
|
+
}
|
|
1621
|
+
} catch {
|
|
1622
|
+
}
|
|
1623
|
+
a || (s({ connected: !1 }), d());
|
|
1624
|
+
}
|
|
1625
|
+
};
|
|
1626
|
+
return m(), {
|
|
1627
|
+
close: () => {
|
|
1628
|
+
a = !0, l !== null && clearTimeout(l);
|
|
1629
|
+
try {
|
|
1630
|
+
i == null || i.abort();
|
|
1631
|
+
} catch {
|
|
1632
|
+
}
|
|
1633
|
+
}
|
|
1634
|
+
};
|
|
1635
|
+
}
|
|
1636
|
+
function Os(e, t) {
|
|
1637
|
+
const { asrUrl: n, getHeaders: s, getEchoReference: r } = t;
|
|
1638
|
+
let o = "idle";
|
|
1639
|
+
const a = /* @__PURE__ */ new Set(), i = /* @__PURE__ */ new Set(), l = /* @__PURE__ */ new Set(), c = /* @__PURE__ */ new Set(), d = /* @__PURE__ */ new Set();
|
|
1640
|
+
let P = !1, A = null, m = null, S = null, x = !1, _ = !1, w = !1, u = [], k = [], v = 0, f = 0, U = !1, M = 0, F = !1, I = 0, O = null, E = 0, D = "";
|
|
1641
|
+
const se = () => typeof crypto < "u" && typeof crypto.randomUUID == "function" ? crypto.randomUUID() : `p-${Date.now()}-${Math.random().toString(36).slice(2)}`, K = (h) => {
|
|
1642
|
+
o = h;
|
|
1643
|
+
for (const j of a)
|
|
1644
|
+
try {
|
|
1645
|
+
j(h);
|
|
1646
|
+
} catch {
|
|
1647
|
+
}
|
|
1648
|
+
}, oe = (h) => {
|
|
1649
|
+
const j = h.trim();
|
|
1650
|
+
if (j)
|
|
1651
|
+
for (const V of i)
|
|
1652
|
+
try {
|
|
1653
|
+
V(j);
|
|
1654
|
+
} catch {
|
|
1655
|
+
}
|
|
1656
|
+
}, ae = () => {
|
|
1657
|
+
const h = new Float32Array(u.reduce((V, B) => V + B.length, 0));
|
|
1658
|
+
let j = 0;
|
|
1659
|
+
for (const V of u)
|
|
1660
|
+
h.set(V, j), j += V.length;
|
|
1661
|
+
return h;
|
|
1662
|
+
}, X = async () => {
|
|
1663
|
+
if (F || d.size === 0 || u.length === 0) return;
|
|
1664
|
+
const h = u.reduce(($, Z) => $ + Z.length, 0) / xe;
|
|
1665
|
+
if (h < Ts || h > xs) return;
|
|
1666
|
+
const j = ae();
|
|
1667
|
+
if (j.length <= E) return;
|
|
1668
|
+
const V = j.subarray(E);
|
|
1669
|
+
E = j.length;
|
|
1670
|
+
const B = I;
|
|
1671
|
+
F = !0;
|
|
1672
|
+
const Y = new AbortController();
|
|
1673
|
+
O = Y;
|
|
1674
|
+
try {
|
|
1675
|
+
const $ = await fetch(n, {
|
|
1676
|
+
method: "POST",
|
|
1677
|
+
headers: {
|
|
1678
|
+
"content-type": "application/octet-stream",
|
|
1679
|
+
...(s == null ? void 0 : s()) ?? {},
|
|
1680
|
+
// 协议字段为 x-voice-session(PRD 4.3);dsh 后端读取的是
|
|
1681
|
+
// x-dsh-session,测试后端期间两个都发,后端各取所需。
|
|
1682
|
+
"x-voice-session": D,
|
|
1683
|
+
"x-dsh-session": D
|
|
1684
|
+
},
|
|
1685
|
+
// .slice() copies so the body is exactly the delta: subarray() is a
|
|
1686
|
+
// view whose .buffer still spans the whole capture.
|
|
1687
|
+
body: V.slice().buffer,
|
|
1688
|
+
signal: Y.signal
|
|
1689
|
+
});
|
|
1690
|
+
if (!$.ok) return;
|
|
1691
|
+
const Z = await $.json();
|
|
1692
|
+
if (B !== I) return;
|
|
1693
|
+
const g = (Z.text ?? "").trim();
|
|
1694
|
+
if (!g) return;
|
|
1695
|
+
for (const C of d)
|
|
1696
|
+
try {
|
|
1697
|
+
C(g);
|
|
1698
|
+
} catch {
|
|
1699
|
+
}
|
|
1700
|
+
} catch {
|
|
1701
|
+
} finally {
|
|
1702
|
+
F = !1, O === Y && (O = null);
|
|
1703
|
+
}
|
|
1704
|
+
}, ue = async (h) => {
|
|
1705
|
+
if (!P) {
|
|
1706
|
+
P = !0, K("transcribing");
|
|
1707
|
+
try {
|
|
1708
|
+
const j = h.slice().buffer, V = await fetch(n, {
|
|
1709
|
+
method: "POST",
|
|
1710
|
+
headers: {
|
|
1711
|
+
"content-type": "application/octet-stream",
|
|
1712
|
+
...(s == null ? void 0 : s()) ?? {}
|
|
1713
|
+
},
|
|
1714
|
+
body: j
|
|
1715
|
+
});
|
|
1716
|
+
if (!V.ok) throw new Error(`asr http ${V.status}`);
|
|
1717
|
+
const B = await V.json();
|
|
1718
|
+
B.text && oe(B.text);
|
|
1719
|
+
} catch (j) {
|
|
1720
|
+
console.warn(`[voice] transcription failed: ${String(j)}`);
|
|
1721
|
+
} finally {
|
|
1722
|
+
P = !1, K(x ? w ? "speech" : "recording" : "idle");
|
|
1723
|
+
}
|
|
1724
|
+
}
|
|
1725
|
+
}, me = () => {
|
|
1726
|
+
if (u.length === 0) return;
|
|
1727
|
+
const h = ae();
|
|
1728
|
+
u = [], w = !1, v = 0, f = 0, ue(h);
|
|
1729
|
+
}, ve = () => {
|
|
1730
|
+
const h = Math.floor(vt / 1e3 * xe);
|
|
1731
|
+
h > 0 && u.push(new Float32Array(h)), me();
|
|
1732
|
+
}, de = (h) => {
|
|
1733
|
+
if (!x || U) return;
|
|
1734
|
+
let j = 0;
|
|
1735
|
+
for (let $ = 0; $ < h.length; $++) j += h[$] * h[$];
|
|
1736
|
+
const V = Math.sqrt(j / h.length), B = h.length / xe * 1e3, Y = Math.min(1, V / bs);
|
|
1737
|
+
for (const $ of c)
|
|
1738
|
+
try {
|
|
1739
|
+
$(Y);
|
|
1740
|
+
} catch {
|
|
1741
|
+
}
|
|
1742
|
+
if (_) {
|
|
1743
|
+
if (!w && V > pt) {
|
|
1744
|
+
w = !0, K("speech");
|
|
1745
|
+
for (const $ of l)
|
|
1746
|
+
try {
|
|
1747
|
+
$();
|
|
1748
|
+
} catch {
|
|
1749
|
+
}
|
|
1750
|
+
}
|
|
1751
|
+
if (f += B, u.push(h), f > mt) {
|
|
1752
|
+
ve();
|
|
1753
|
+
return;
|
|
1754
|
+
}
|
|
1755
|
+
M += B, M >= As && (M = 0, X());
|
|
1756
|
+
return;
|
|
1757
|
+
}
|
|
1758
|
+
if (V > pt) {
|
|
1759
|
+
if (!w) {
|
|
1760
|
+
w = !0, K("speech");
|
|
1761
|
+
for (const $ of l)
|
|
1762
|
+
try {
|
|
1763
|
+
$();
|
|
1764
|
+
} catch {
|
|
1765
|
+
}
|
|
1766
|
+
for (const $ of k) u.push($);
|
|
1767
|
+
k = [];
|
|
1768
|
+
}
|
|
1769
|
+
f += B, v = 0, u.push(h), f > mt && ve();
|
|
1770
|
+
} else if (w)
|
|
1771
|
+
f += B, v += B, u.push(h), v > ks && ve();
|
|
1772
|
+
else {
|
|
1773
|
+
k.push(h);
|
|
1774
|
+
const $ = Ss;
|
|
1775
|
+
let Z = 0, g = 0;
|
|
1776
|
+
for (let C = k.length - 1; C >= 0; C--)
|
|
1777
|
+
if (Z += k[C].length / xe * 1e3, Z > $) {
|
|
1778
|
+
g = C + 1;
|
|
1779
|
+
break;
|
|
1780
|
+
}
|
|
1781
|
+
g > 0 && (k = k.slice(g));
|
|
1782
|
+
}
|
|
1783
|
+
}, Ae = async () => {
|
|
1784
|
+
var V;
|
|
1785
|
+
if (x) return;
|
|
1786
|
+
const h = ((V = r == null ? void 0 : r()) == null ? void 0 : V.node) ?? null;
|
|
1787
|
+
m = await navigator.mediaDevices.getUserMedia({
|
|
1788
|
+
audio: {
|
|
1789
|
+
channelCount: 1,
|
|
1790
|
+
echoCancellation: h === null,
|
|
1791
|
+
noiseSuppression: !0,
|
|
1792
|
+
autoGainControl: !0
|
|
1793
|
+
}
|
|
1794
|
+
}), A = new AudioContext({ sampleRate: xe }), await A.resume().catch(() => {
|
|
1795
|
+
});
|
|
1796
|
+
const j = A.createMediaStreamSource(m);
|
|
1797
|
+
if (h === null)
|
|
1798
|
+
S = A.createScriptProcessor(gt, 1, 1), S.onaudioprocess = (B) => {
|
|
1799
|
+
const Y = B.inputBuffer.getChannelData(0);
|
|
1800
|
+
de(new Float32Array(Y));
|
|
1801
|
+
}, j.connect(S);
|
|
1802
|
+
else {
|
|
1803
|
+
const B = new js({});
|
|
1804
|
+
S = A.createScriptProcessor(gt, 2, 1), S.onaudioprocess = (Y) => {
|
|
1805
|
+
const $ = Y.inputBuffer.getChannelData(0), Z = Y.inputBuffer.getChannelData(1);
|
|
1806
|
+
de(B.process($, Z));
|
|
1807
|
+
}, j.connect(S, 0, 0), h.connect(S, 0, 1);
|
|
1808
|
+
}
|
|
1809
|
+
S.connect(A.destination), x = !0;
|
|
1810
|
+
}, W = async (h = !1) => {
|
|
1811
|
+
if (!x) return;
|
|
1812
|
+
x = !1, U = !0, I++, M = 0;
|
|
1813
|
+
try {
|
|
1814
|
+
O == null || O.abort();
|
|
1815
|
+
} catch {
|
|
1816
|
+
}
|
|
1817
|
+
O = null;
|
|
1818
|
+
const j = _;
|
|
1819
|
+
_ = !1;
|
|
1820
|
+
try {
|
|
1821
|
+
if (h ? !1 : j ? u.length > 0 : w) {
|
|
1822
|
+
const B = u.reduce((Y, $) => Y + $.length, 0) / xe;
|
|
1823
|
+
if (!j || B >= Cs) {
|
|
1824
|
+
const Y = Math.floor(vt / 1e3 * xe);
|
|
1825
|
+
u.push(new Float32Array(Y)), me();
|
|
1826
|
+
} else
|
|
1827
|
+
u = [];
|
|
1828
|
+
} else
|
|
1829
|
+
u = [];
|
|
1830
|
+
w = !1, v = 0, f = 0, k = [];
|
|
1831
|
+
} finally {
|
|
1832
|
+
U = !1;
|
|
1833
|
+
}
|
|
1834
|
+
try {
|
|
1835
|
+
S == null || S.disconnect();
|
|
1836
|
+
} catch {
|
|
1837
|
+
}
|
|
1838
|
+
S = null, E = 0, D = "";
|
|
1839
|
+
try {
|
|
1840
|
+
m == null || m.getTracks().forEach((V) => V.stop());
|
|
1841
|
+
} catch {
|
|
1842
|
+
}
|
|
1843
|
+
m = null;
|
|
1844
|
+
try {
|
|
1845
|
+
await (A == null ? void 0 : A.close());
|
|
1846
|
+
} catch {
|
|
1847
|
+
}
|
|
1848
|
+
A = null;
|
|
1849
|
+
};
|
|
1850
|
+
return {
|
|
1851
|
+
get state() {
|
|
1852
|
+
return o;
|
|
1853
|
+
},
|
|
1854
|
+
async start(h) {
|
|
1855
|
+
if (!x) {
|
|
1856
|
+
_ = (h == null ? void 0 : h.hold) === !0, I++, M = 0, E = 0, D = se(), K("recording");
|
|
1857
|
+
try {
|
|
1858
|
+
await Ae();
|
|
1859
|
+
} catch (j) {
|
|
1860
|
+
throw _ = !1, K("idle"), j;
|
|
1861
|
+
}
|
|
1862
|
+
}
|
|
1863
|
+
},
|
|
1864
|
+
async stop() {
|
|
1865
|
+
if (!x) {
|
|
1866
|
+
K("idle");
|
|
1867
|
+
return;
|
|
1868
|
+
}
|
|
1869
|
+
await W(), P || K("idle");
|
|
1870
|
+
},
|
|
1871
|
+
async cancel() {
|
|
1872
|
+
await W(!0), K("idle");
|
|
1873
|
+
},
|
|
1874
|
+
onSegment(h) {
|
|
1875
|
+
return i.add(h), () => {
|
|
1876
|
+
i.delete(h);
|
|
1877
|
+
};
|
|
1878
|
+
},
|
|
1879
|
+
onState(h) {
|
|
1880
|
+
return a.add(h), h(o), () => {
|
|
1881
|
+
a.delete(h);
|
|
1882
|
+
};
|
|
1883
|
+
},
|
|
1884
|
+
onSpeechStart(h) {
|
|
1885
|
+
return l.add(h), () => {
|
|
1886
|
+
l.delete(h);
|
|
1887
|
+
};
|
|
1888
|
+
},
|
|
1889
|
+
onLevel(h) {
|
|
1890
|
+
return c.add(h), () => {
|
|
1891
|
+
c.delete(h);
|
|
1892
|
+
};
|
|
1893
|
+
},
|
|
1894
|
+
onPartial(h) {
|
|
1895
|
+
return d.add(h), () => {
|
|
1896
|
+
d.delete(h);
|
|
1897
|
+
};
|
|
1898
|
+
}
|
|
1899
|
+
};
|
|
1900
|
+
}
|
|
1901
|
+
function Bs(e) {
|
|
1902
|
+
const t = e instanceof DOMException ? e.name : "", n = e instanceof Error ? e.message : String(e);
|
|
1903
|
+
switch (t) {
|
|
1904
|
+
case "NotAllowedError":
|
|
1905
|
+
case "SecurityError":
|
|
1906
|
+
return "麦克风被拒绝:请在浏览器地址栏的权限设置里允许麦克风";
|
|
1907
|
+
case "NotFoundError":
|
|
1908
|
+
case "OverconstrainedError":
|
|
1909
|
+
return "找不到麦克风设备:请检查系统输入设备";
|
|
1910
|
+
case "NotReadableError":
|
|
1911
|
+
return "麦克风被其他程序占用";
|
|
1912
|
+
default:
|
|
1913
|
+
return n ? `麦克风不可用:${n}` : "麦克风不可用";
|
|
1914
|
+
}
|
|
1915
|
+
}
|
|
1916
|
+
function Ns(e) {
|
|
1917
|
+
const t = atob(e), n = new Uint8Array(t.length);
|
|
1918
|
+
for (let r = 0; r < t.length; r++) n[r] = t.charCodeAt(r);
|
|
1919
|
+
const s = n[0] === 82 && n[1] === 73 && n[2] === 70 && n[3] === 70;
|
|
1920
|
+
return URL.createObjectURL(new Blob([n], { type: s ? "audio/wav" : "audio/mpeg" }));
|
|
1921
|
+
}
|
|
1922
|
+
function Vs(e) {
|
|
1923
|
+
const t = /* @__PURE__ */ new Set();
|
|
1924
|
+
let n = { connected: !1, playing: !1, caption: null };
|
|
1925
|
+
const s = [], r = _t();
|
|
1926
|
+
let o = null;
|
|
1927
|
+
const a = () => {
|
|
1928
|
+
for (const d of t) d(n);
|
|
1929
|
+
}, i = (d) => {
|
|
1930
|
+
n = { ...n, ...d }, a();
|
|
1931
|
+
}, l = () => {
|
|
1932
|
+
const d = s.shift();
|
|
1933
|
+
if (!d) {
|
|
1934
|
+
i({ playing: !1, caption: null });
|
|
1935
|
+
return;
|
|
1936
|
+
}
|
|
1937
|
+
Fs();
|
|
1938
|
+
const P = Ns(d.audio);
|
|
1939
|
+
r.src = P, r.onended = () => {
|
|
1940
|
+
URL.revokeObjectURL(P), l();
|
|
1941
|
+
}, r.onerror = () => {
|
|
1942
|
+
URL.revokeObjectURL(P), l();
|
|
1943
|
+
}, i({ playing: !0, caption: d.text }), r.play().catch(() => {
|
|
1944
|
+
i({ playing: !1 });
|
|
1945
|
+
});
|
|
1946
|
+
}, c = (d) => {
|
|
1947
|
+
d.sessionId === e.getSessionId() && d.audio && (s.push(d), r.paused && l());
|
|
1948
|
+
};
|
|
1949
|
+
return {
|
|
1950
|
+
connect() {
|
|
1951
|
+
var d;
|
|
1952
|
+
o === null && (o = $s(
|
|
1953
|
+
e.streamUrl,
|
|
1954
|
+
((d = e.getHeaders) == null ? void 0 : d.call(e)) ?? {},
|
|
1955
|
+
c,
|
|
1956
|
+
(P) => i({ connected: P.connected })
|
|
1957
|
+
));
|
|
1958
|
+
},
|
|
1959
|
+
skip() {
|
|
1960
|
+
s.length = 0, r.pause(), r.onended = null, r.onerror = null, i({ playing: !1, caption: null });
|
|
1961
|
+
},
|
|
1962
|
+
subscribe(d) {
|
|
1963
|
+
return t.add(d), d(n), () => {
|
|
1964
|
+
t.delete(d);
|
|
1965
|
+
};
|
|
1966
|
+
},
|
|
1967
|
+
getEchoReference() {
|
|
1968
|
+
return je ? { node: je } : null;
|
|
1969
|
+
}
|
|
1970
|
+
};
|
|
1971
|
+
}
|
|
1972
|
+
let Xe = null;
|
|
1973
|
+
function _t() {
|
|
1974
|
+
return Xe === null && (Xe = typeof Audio < "u" ? new Audio() : {}), Xe;
|
|
1975
|
+
}
|
|
1976
|
+
let _e = null, je = null;
|
|
1977
|
+
function Fs() {
|
|
1978
|
+
if (_e === null) {
|
|
1979
|
+
_e = new AudioContext();
|
|
1980
|
+
const e = _t();
|
|
1981
|
+
je === null && (je = _e.createMediaElementSource(e), je.connect(_e.destination));
|
|
1478
1982
|
}
|
|
1983
|
+
return _e;
|
|
1984
|
+
}
|
|
1985
|
+
const jt = Symbol("szjy-voice");
|
|
1986
|
+
function It() {
|
|
1987
|
+
const e = Zt(jt);
|
|
1988
|
+
if (!e)
|
|
1989
|
+
throw new Error("useVoiceContext() 必须在 useVoice() 所在组件的子树中调用");
|
|
1990
|
+
return e;
|
|
1991
|
+
}
|
|
1992
|
+
function Ds(e) {
|
|
1993
|
+
const t = R("idle"), n = R(null), s = it(null), r = it(null), o = R(null), a = () => {
|
|
1994
|
+
var u;
|
|
1995
|
+
return ((u = e.getAuthHeaders) == null ? void 0 : u.call(e)) ?? {};
|
|
1996
|
+
}, i = () => lt(e.sessionId), l = () => lt(e.running) === !0;
|
|
1997
|
+
let c = !1;
|
|
1998
|
+
const d = () => {
|
|
1999
|
+
c = !0;
|
|
2000
|
+
}, P = () => {
|
|
2001
|
+
var u;
|
|
2002
|
+
(u = r.value) == null || u.skip(), yt(m(), a(), i()).catch(() => {
|
|
2003
|
+
});
|
|
2004
|
+
};
|
|
2005
|
+
let A = e.apiBase ?? nt;
|
|
2006
|
+
const m = () => A;
|
|
2007
|
+
let S = !1;
|
|
2008
|
+
(async () => {
|
|
2009
|
+
try {
|
|
2010
|
+
const u = await Is(m(), a());
|
|
2011
|
+
if (S) return;
|
|
2012
|
+
if (u.protocolVersion !== void 0 && u.protocolVersion !== 1) {
|
|
2013
|
+
n.value = "语音协议不兼容";
|
|
2014
|
+
return;
|
|
2015
|
+
}
|
|
2016
|
+
if (u.modelReady !== void 0 && u.modelReady === !1) {
|
|
2017
|
+
n.value = "语音模型未就绪";
|
|
2018
|
+
return;
|
|
2019
|
+
}
|
|
2020
|
+
const k = await zs(m(), a());
|
|
2021
|
+
if (S) return;
|
|
2022
|
+
A = e.apiBase ?? k.basePath ?? A, o.value = k.asr;
|
|
2023
|
+
const v = Vs({
|
|
2024
|
+
// openAudioStream(base) 内部会追加 /stream(api.ts 契约),此处传 base
|
|
2025
|
+
streamUrl: m(),
|
|
2026
|
+
getHeaders: a,
|
|
2027
|
+
getSessionId: i
|
|
2028
|
+
});
|
|
2029
|
+
r.value = v, v.connect();
|
|
2030
|
+
const f = Os(k.asr, {
|
|
2031
|
+
asrUrl: `${m()}/asr`,
|
|
2032
|
+
getHeaders: a,
|
|
2033
|
+
getEchoReference: () => v.getEchoReference()
|
|
2034
|
+
});
|
|
2035
|
+
f.onState((U) => {
|
|
2036
|
+
t.value = U;
|
|
2037
|
+
}), f.onSpeechStart(() => {
|
|
2038
|
+
v.skip(), yt(m(), a(), i()).catch(() => {
|
|
2039
|
+
}), l() && e.onCancelTurn();
|
|
2040
|
+
}), f.onSegment((U) => {
|
|
2041
|
+
const M = U.trim();
|
|
2042
|
+
if (!M) return;
|
|
2043
|
+
e.onTranscript(M);
|
|
2044
|
+
const F = c || k.asr.autoSend;
|
|
2045
|
+
c = !1, F && setTimeout(() => {
|
|
2046
|
+
try {
|
|
2047
|
+
e.onSubmit();
|
|
2048
|
+
} catch {
|
|
2049
|
+
}
|
|
2050
|
+
}, 60);
|
|
2051
|
+
}), s.value = f;
|
|
2052
|
+
} catch (u) {
|
|
2053
|
+
S || (n.value = `语音服务不可用:${u instanceof Error ? u.message : String(u)}`);
|
|
2054
|
+
}
|
|
2055
|
+
})();
|
|
2056
|
+
const x = () => {
|
|
2057
|
+
var u, k;
|
|
2058
|
+
S = !0, (u = s.value) == null || u.stop(), s.value = null, (k = r.value) == null || k.skip(), r.value = null;
|
|
2059
|
+
};
|
|
2060
|
+
De(x);
|
|
2061
|
+
const _ = (u, k = !1) => {
|
|
2062
|
+
!u && !k || fetch(`${m()}/speak`, {
|
|
2063
|
+
method: "POST",
|
|
2064
|
+
headers: { "content-type": "application/json", ...a() },
|
|
2065
|
+
body: JSON.stringify({ sessionId: i(), text: u, final: k })
|
|
2066
|
+
}).catch(() => {
|
|
2067
|
+
});
|
|
2068
|
+
};
|
|
2069
|
+
return Qt(jt, {
|
|
2070
|
+
engine: s,
|
|
2071
|
+
playback: r,
|
|
2072
|
+
config: o,
|
|
2073
|
+
asrState: t,
|
|
2074
|
+
error: n,
|
|
2075
|
+
requestSubmitOnNextSegment: d,
|
|
2076
|
+
skipPlayback: P,
|
|
2077
|
+
speak: _
|
|
2078
|
+
}), { asrState: t, error: n, dispose: x, speak: _ };
|
|
1479
2079
|
}
|
|
1480
|
-
const
|
|
2080
|
+
const Hs = { class: "szjyv-ptt-backdrop" }, qs = {
|
|
2081
|
+
key: 0,
|
|
2082
|
+
class: "szjyv-ptt-caret"
|
|
2083
|
+
}, Ws = { class: "szjyv-kbd" }, Gs = /* @__PURE__ */ Ue({
|
|
2084
|
+
__name: "VoiceOverlay",
|
|
2085
|
+
props: {
|
|
2086
|
+
levels: {},
|
|
2087
|
+
armedCancel: { type: Boolean },
|
|
2088
|
+
pending: { type: Boolean },
|
|
2089
|
+
partial: {},
|
|
2090
|
+
source: {},
|
|
2091
|
+
hotkey: {}
|
|
2092
|
+
},
|
|
2093
|
+
setup(e) {
|
|
2094
|
+
const t = e, n = q(() => t.armedCancel ? "#f85149" : "#2ea043"), s = q(
|
|
2095
|
+
() => Array.from({ length: Mt }, (o, a) => t.levels[a] ?? 0)
|
|
2096
|
+
), r = q(() => {
|
|
2097
|
+
const o = t.hotkey, a = typeof navigator < "u" && /Mac|iP(hone|ad|od)/.test(navigator.platform ?? "");
|
|
2098
|
+
switch (o) {
|
|
2099
|
+
case "Control":
|
|
2100
|
+
return a ? "⌃" : "Ctrl";
|
|
2101
|
+
case "Alt":
|
|
2102
|
+
return a ? "⌥" : "Alt";
|
|
2103
|
+
case "Meta":
|
|
2104
|
+
return a ? "⌘" : "Win";
|
|
2105
|
+
case "Shift":
|
|
2106
|
+
return "Shift";
|
|
2107
|
+
case " ":
|
|
2108
|
+
return "Space";
|
|
2109
|
+
default:
|
|
2110
|
+
return o;
|
|
2111
|
+
}
|
|
2112
|
+
});
|
|
2113
|
+
return (o, a) => (T(), L("div", Hs, [
|
|
2114
|
+
p("div", {
|
|
2115
|
+
class: le(["szjyv-ptt-card", { cancel: e.armedCancel }])
|
|
2116
|
+
}, [
|
|
2117
|
+
p("div", {
|
|
2118
|
+
class: le(["szjyv-ptt-wave", { frozen: e.pending }])
|
|
2119
|
+
}, [
|
|
2120
|
+
(T(!0), L(he, null, Fe(s.value, (i, l) => (T(), L("span", {
|
|
2121
|
+
key: l,
|
|
2122
|
+
class: "szjyv-ptt-bar",
|
|
2123
|
+
style: ce({
|
|
2124
|
+
height: `${3 + i * 37}px`,
|
|
2125
|
+
background: n.value,
|
|
2126
|
+
opacity: 0.45 + i * 0.55
|
|
2127
|
+
})
|
|
2128
|
+
}, null, 4))), 128))
|
|
2129
|
+
], 2),
|
|
2130
|
+
e.partial && !e.armedCancel ? (T(), L("div", {
|
|
2131
|
+
key: 0,
|
|
2132
|
+
class: le(["szjyv-ptt-live", { stale: e.pending }])
|
|
2133
|
+
}, [
|
|
2134
|
+
fe(Q(e.partial) + " ", 1),
|
|
2135
|
+
e.pending ? H("", !0) : (T(), L("span", qs))
|
|
2136
|
+
], 2)) : H("", !0),
|
|
2137
|
+
p("div", {
|
|
2138
|
+
class: "szjyv-ptt-hint",
|
|
2139
|
+
style: ce({ color: e.armedCancel ? "#f85149" : "#8b949e" })
|
|
2140
|
+
}, [
|
|
2141
|
+
e.pending ? (T(), L(he, { key: 0 }, [
|
|
2142
|
+
a[0] || (a[0] = p("span", { class: "szjyv-spin szjyv-ptt-spinner" }, null, -1)),
|
|
2143
|
+
a[1] || (a[1] = fe(" 识别中… ", -1))
|
|
2144
|
+
], 64)) : e.armedCancel ? (T(), L(he, { key: 1 }, [
|
|
2145
|
+
fe("松开手指 取消发送")
|
|
2146
|
+
], 64)) : e.source === "key" ? (T(), L(he, { key: 2 }, [
|
|
2147
|
+
a[2] || (a[2] = fe(" 松开 ", -1)),
|
|
2148
|
+
p("span", Ws, Q(r.value), 1),
|
|
2149
|
+
a[3] || (a[3] = fe(" 发送 · ", -1)),
|
|
2150
|
+
a[4] || (a[4] = p("span", { class: "szjyv-kbd" }, "Esc", -1)),
|
|
2151
|
+
a[5] || (a[5] = fe(" 取消 ", -1))
|
|
2152
|
+
], 64)) : (T(), L(he, { key: 3 }, [
|
|
2153
|
+
fe("松开发送 · 上滑取消")
|
|
2154
|
+
], 64))
|
|
2155
|
+
], 4)
|
|
2156
|
+
], 2)
|
|
2157
|
+
]));
|
|
2158
|
+
}
|
|
2159
|
+
}), zt = /* @__PURE__ */ Ue({
|
|
2160
|
+
__name: "EqualizerBars",
|
|
2161
|
+
props: {
|
|
2162
|
+
color: {},
|
|
2163
|
+
height: {}
|
|
2164
|
+
},
|
|
2165
|
+
setup(e) {
|
|
2166
|
+
return (t, n) => (T(), L("span", {
|
|
2167
|
+
class: "szjyv-eq",
|
|
2168
|
+
style: ce({ height: `${e.height}px` })
|
|
2169
|
+
}, [
|
|
2170
|
+
(T(), L(he, null, Fe(3, (s) => p("span", {
|
|
2171
|
+
key: s,
|
|
2172
|
+
style: ce({
|
|
2173
|
+
background: e.color,
|
|
2174
|
+
animationDelay: `${(s - 1) * 0.18}s`
|
|
2175
|
+
})
|
|
2176
|
+
}, null, 4)), 64))
|
|
2177
|
+
], 4));
|
|
2178
|
+
}
|
|
2179
|
+
}), Js = {
|
|
2180
|
+
key: 1,
|
|
2181
|
+
class: "szjyv-toast"
|
|
2182
|
+
}, Ks = ["title"], Ys = {
|
|
2183
|
+
key: 2,
|
|
2184
|
+
class: "szjyv-mic-icon",
|
|
2185
|
+
viewBox: "0 0 24 24",
|
|
2186
|
+
width: "17",
|
|
2187
|
+
height: "17",
|
|
2188
|
+
fill: "none",
|
|
2189
|
+
stroke: "currentColor",
|
|
2190
|
+
"stroke-width": "2",
|
|
2191
|
+
"stroke-linecap": "round",
|
|
2192
|
+
"stroke-linejoin": "round",
|
|
2193
|
+
"aria-hidden": "true"
|
|
2194
|
+
}, Xs = ["stroke"], Zs = {
|
|
2195
|
+
key: 4,
|
|
2196
|
+
class: "szjyv-mic-label"
|
|
2197
|
+
}, Qs = /* @__PURE__ */ Ue({
|
|
2198
|
+
__name: "VoiceMicButton",
|
|
2199
|
+
setup(e) {
|
|
2200
|
+
const t = It(), n = t.asrState, s = R(null), r = {
|
|
2201
|
+
idle: "voice: 待识别(点按说话)",
|
|
2202
|
+
recording: "voice: 录音中…",
|
|
2203
|
+
speech: "voice: 说话中…",
|
|
2204
|
+
transcribing: "voice: 识别中…",
|
|
2205
|
+
"loading-model": "voice: 模型加载中…"
|
|
2206
|
+
}, o = {
|
|
2207
|
+
idle: "#8b949e",
|
|
2208
|
+
recording: "#f85149",
|
|
2209
|
+
speech: "#2ea043",
|
|
2210
|
+
transcribing: "#58a6ff",
|
|
2211
|
+
"loading-model": "#bc8cff"
|
|
2212
|
+
}, a = R(!1), i = R(!1), l = R([]), c = R(""), d = R(!1), P = R("pointer"), A = R(""), m = R(null), S = R(null), x = R(null), _ = R(0), w = R(!1), u = R(!1), k = R(!1);
|
|
2213
|
+
ye(
|
|
2214
|
+
() => t.config.value,
|
|
2215
|
+
(g) => {
|
|
2216
|
+
A.value = (g == null ? void 0 : g.hotkey) ?? "";
|
|
2217
|
+
},
|
|
2218
|
+
{ immediate: !0 }
|
|
2219
|
+
);
|
|
2220
|
+
const v = q(() => n.value === "transcribing" || n.value === "loading-model"), f = q(() => {
|
|
2221
|
+
var g;
|
|
2222
|
+
return s.value ? "voice error" : n.value === "idle" ? "mic" : ((g = r[n.value]) == null ? void 0 : g.replace("voice: ", "")) ?? "mic";
|
|
2223
|
+
}), U = q(() => {
|
|
2224
|
+
if (s.value) return s.value;
|
|
2225
|
+
const g = A.value ? `;也可长按 ${M(A.value)}` : "";
|
|
2226
|
+
return `${r[n.value] ?? ""}(长按说话,松开发送${g})`;
|
|
2227
|
+
});
|
|
2228
|
+
function M(g) {
|
|
2229
|
+
const C = typeof navigator < "u" && /Mac|iP(hone|ad|od)/.test(navigator.platform ?? "");
|
|
2230
|
+
switch (g) {
|
|
2231
|
+
case "Control":
|
|
2232
|
+
return C ? "⌃" : "Ctrl";
|
|
2233
|
+
case "Alt":
|
|
2234
|
+
return C ? "⌥" : "Alt";
|
|
2235
|
+
case "Meta":
|
|
2236
|
+
return C ? "⌘" : "Win";
|
|
2237
|
+
case "Shift":
|
|
2238
|
+
return "Shift";
|
|
2239
|
+
case " ":
|
|
2240
|
+
return "Space";
|
|
2241
|
+
default:
|
|
2242
|
+
return g;
|
|
2243
|
+
}
|
|
2244
|
+
}
|
|
2245
|
+
ye(
|
|
2246
|
+
() => t.error.value,
|
|
2247
|
+
(g) => {
|
|
2248
|
+
g !== null && s.value === null && (s.value = g);
|
|
2249
|
+
},
|
|
2250
|
+
{ immediate: !0 }
|
|
2251
|
+
), ye(s, (g) => {
|
|
2252
|
+
g !== null && setTimeout(() => {
|
|
2253
|
+
s.value === g && (s.value = null);
|
|
2254
|
+
}, 4e3);
|
|
2255
|
+
});
|
|
2256
|
+
const F = async () => {
|
|
2257
|
+
const g = t.engine.value;
|
|
2258
|
+
if (g) {
|
|
2259
|
+
if (k.value) {
|
|
2260
|
+
k.value = !1;
|
|
2261
|
+
return;
|
|
2262
|
+
}
|
|
2263
|
+
s.value = null;
|
|
2264
|
+
try {
|
|
2265
|
+
g.state === "idle" ? await g.start() : await g.stop();
|
|
2266
|
+
} catch (C) {
|
|
2267
|
+
s.value = C instanceof Error ? C.message : String(C);
|
|
2268
|
+
}
|
|
2269
|
+
}
|
|
2270
|
+
};
|
|
2271
|
+
ye(a, (g) => {
|
|
2272
|
+
const C = t.engine.value;
|
|
2273
|
+
if (!g || !C) return;
|
|
2274
|
+
l.value = [];
|
|
2275
|
+
const G = C.onLevel((we) => {
|
|
2276
|
+
l.value = l.value.length < Mt ? [...l.value, we] : [...l.value.slice(1), we];
|
|
2277
|
+
});
|
|
2278
|
+
c.value = "";
|
|
2279
|
+
const ee = C.onPartial((we) => {
|
|
2280
|
+
c.value = we;
|
|
2281
|
+
}), re = C.onSegment(() => {
|
|
2282
|
+
d.value = !1, c.value = "";
|
|
2283
|
+
});
|
|
2284
|
+
I = () => {
|
|
2285
|
+
G(), ee(), re();
|
|
2286
|
+
};
|
|
2287
|
+
});
|
|
2288
|
+
let I = null;
|
|
2289
|
+
ye(a, (g, C) => {
|
|
2290
|
+
!g && C && I && (I(), I = null);
|
|
2291
|
+
}), ye([d, n], ([g, C]) => {
|
|
2292
|
+
if (!g || C === "transcribing" || C === "loading-model") return;
|
|
2293
|
+
setTimeout(() => {
|
|
2294
|
+
d.value = !1, c.value = "";
|
|
2295
|
+
}, C === "idle" ? 220 : 12e3);
|
|
2296
|
+
});
|
|
2297
|
+
const O = (g) => {
|
|
2298
|
+
if (x.value && (clearTimeout(x.value), x.value = null), !u.value) {
|
|
2299
|
+
S.value = null;
|
|
2300
|
+
return;
|
|
2301
|
+
}
|
|
2302
|
+
u.value = !1, S.value = null, k.value = !0, a.value = !1, i.value = !1, w.value = !1;
|
|
2303
|
+
const C = t.engine.value;
|
|
2304
|
+
if (g) {
|
|
2305
|
+
c.value = "", d.value = !1, C == null || C.cancel();
|
|
2306
|
+
return;
|
|
2307
|
+
}
|
|
2308
|
+
d.value = !0, t.requestSubmitOnNextSegment(), C == null || C.stop();
|
|
2309
|
+
}, E = (g, C, G = "pointer", ee = Rs) => {
|
|
2310
|
+
t.engine.value !== null && (x.value && clearTimeout(x.value), _.value = g, S.value = G, C == null || C(), x.value = setTimeout(() => {
|
|
2311
|
+
var re;
|
|
2312
|
+
x.value = null, u.value = !0, P.value = G, a.value = !0, d.value = !1, c.value = "", s.value = null, (re = t.engine.value) == null || re.start({ hold: !0 }).catch((we) => {
|
|
2313
|
+
s.value = Bs(we), u.value = !1, S.value = null, a.value = !1;
|
|
2314
|
+
});
|
|
2315
|
+
}, ee));
|
|
2316
|
+
}, D = (g) => {
|
|
2317
|
+
if (!u.value || S.value === "key") return;
|
|
2318
|
+
const C = _.value - g > Ls;
|
|
2319
|
+
C !== w.value && (w.value = C, i.value = C);
|
|
2320
|
+
}, se = (g) => {
|
|
2321
|
+
E(g.clientY, () => {
|
|
2322
|
+
try {
|
|
2323
|
+
g.currentTarget.setPointerCapture(g.pointerId);
|
|
2324
|
+
} catch {
|
|
2325
|
+
}
|
|
2326
|
+
});
|
|
2327
|
+
}, K = (g) => D(g.clientY), oe = () => {
|
|
2328
|
+
S.value !== "key" && O(w.value);
|
|
2329
|
+
}, ae = () => {
|
|
2330
|
+
S.value !== "key" && O(!0);
|
|
2331
|
+
}, X = () => {
|
|
2332
|
+
const g = m.value;
|
|
2333
|
+
if (!g) return null;
|
|
2334
|
+
let C = g.parentElement;
|
|
2335
|
+
for (let G = 0; C && G < 4; G++) {
|
|
2336
|
+
const ee = Array.from(C.querySelectorAll("button")).filter(
|
|
2337
|
+
(re) => re !== g && !g.contains(re)
|
|
2338
|
+
);
|
|
2339
|
+
if (ee.length > 0) return ee[ee.length - 1];
|
|
2340
|
+
C = C.parentElement;
|
|
2341
|
+
}
|
|
2342
|
+
return null;
|
|
2343
|
+
}, ue = R(X);
|
|
2344
|
+
ue.value = X;
|
|
2345
|
+
let me = !1;
|
|
2346
|
+
const ve = (g) => {
|
|
2347
|
+
const C = ue.value();
|
|
2348
|
+
if (!C) return;
|
|
2349
|
+
const G = C.getBoundingClientRect();
|
|
2350
|
+
g.clientX >= G.left && g.clientX <= G.right && g.clientY >= G.top && g.clientY <= G.bottom && Y.value(g.clientY);
|
|
2351
|
+
}, de = (g) => Z.value(g.clientY), Ae = () => {
|
|
2352
|
+
S.value !== "key" && $.value(w.value);
|
|
2353
|
+
}, W = () => {
|
|
2354
|
+
S.value !== "key" && $.value(!0);
|
|
2355
|
+
}, h = (g) => {
|
|
2356
|
+
if (!k.value) return;
|
|
2357
|
+
const C = ue.value(), G = g.target;
|
|
2358
|
+
!C || !G || !(C === G || C.contains(G)) || (k.value = !1, g.preventDefault(), g.stopImmediatePropagation());
|
|
2359
|
+
}, j = (g) => {
|
|
2360
|
+
const C = A.value;
|
|
2361
|
+
if (C) {
|
|
2362
|
+
if (S.value !== null) {
|
|
2363
|
+
if (g.key === C || S.value === "pointer" && g.key !== "Escape") return;
|
|
2364
|
+
$.value(!0);
|
|
2365
|
+
return;
|
|
2366
|
+
}
|
|
2367
|
+
g.key !== C || g.repeat || g.isComposing || Y.value(0, void 0, "key", Es);
|
|
2368
|
+
}
|
|
2369
|
+
}, V = (g) => {
|
|
2370
|
+
S.value === "key" && g.key === A.value && $.value(!1);
|
|
2371
|
+
}, B = () => {
|
|
2372
|
+
S.value === "key" && $.value(!0);
|
|
2373
|
+
}, Y = R(E);
|
|
2374
|
+
Y.value = E;
|
|
2375
|
+
const $ = R(O);
|
|
2376
|
+
$.value = O;
|
|
2377
|
+
const Z = R(D);
|
|
2378
|
+
return Z.value = D, en(() => {
|
|
2379
|
+
me || (window.addEventListener("pointerdown", ve), window.addEventListener("pointermove", de), window.addEventListener("pointerup", Ae), window.addEventListener("pointercancel", W), window.addEventListener("click", h, !0), window.addEventListener("keydown", j), window.addEventListener("keyup", V), window.addEventListener("blur", B));
|
|
2380
|
+
}), De(() => {
|
|
2381
|
+
me = !0, window.removeEventListener("pointerdown", ve), window.removeEventListener("pointermove", de), window.removeEventListener("pointerup", Ae), window.removeEventListener("pointercancel", W), window.removeEventListener("click", h, !0), window.removeEventListener("keydown", j), window.removeEventListener("keyup", V), window.removeEventListener("blur", B), x.value && clearTimeout(x.value), I == null || I();
|
|
2382
|
+
}), (g, C) => (T(), L(he, null, [
|
|
2383
|
+
a.value || d.value ? (T(), Se(Gs, {
|
|
2384
|
+
key: 0,
|
|
2385
|
+
levels: l.value,
|
|
2386
|
+
"armed-cancel": i.value,
|
|
2387
|
+
pending: d.value,
|
|
2388
|
+
partial: c.value,
|
|
2389
|
+
source: P.value,
|
|
2390
|
+
hotkey: A.value
|
|
2391
|
+
}, null, 8, ["levels", "armed-cancel", "pending", "partial", "source", "hotkey"])) : H("", !0),
|
|
2392
|
+
s.value ? (T(), L("div", Js, Q(s.value), 1)) : H("", !0),
|
|
2393
|
+
p("button", {
|
|
2394
|
+
ref_key: "anchorRef",
|
|
2395
|
+
ref: m,
|
|
2396
|
+
class: "szjyv-mic",
|
|
2397
|
+
title: U.value,
|
|
2398
|
+
onClick: F,
|
|
2399
|
+
onPointerdown: se,
|
|
2400
|
+
onPointermove: C[0] || (C[0] = (G) => K(G)),
|
|
2401
|
+
onPointerup: oe,
|
|
2402
|
+
onPointercancel: ae
|
|
2403
|
+
}, [
|
|
2404
|
+
v.value ? (T(), L("span", {
|
|
2405
|
+
key: 0,
|
|
2406
|
+
class: "szjyv-spin szjyv-mic-spinner",
|
|
2407
|
+
style: ce({ borderTopColor: o[Re(n)] })
|
|
2408
|
+
}, null, 4)) : Re(n) === "speech" ? (T(), Se(zt, {
|
|
2409
|
+
key: 1,
|
|
2410
|
+
color: "#2ea043",
|
|
2411
|
+
height: 11
|
|
2412
|
+
})) : Re(n) === "idle" && !a.value ? (T(), L("svg", Ys, [
|
|
2413
|
+
p("path", {
|
|
2414
|
+
d: "M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3Z",
|
|
2415
|
+
stroke: s.value ? "#f85149" : "#57606a",
|
|
2416
|
+
fill: "currentColor",
|
|
2417
|
+
"fill-opacity": "0.15"
|
|
2418
|
+
}, null, 8, Xs),
|
|
2419
|
+
C[1] || (C[1] = p("path", { d: "M19 10v2a7 7 0 0 1-14 0v-2" }, null, -1)),
|
|
2420
|
+
C[2] || (C[2] = p("line", {
|
|
2421
|
+
x1: "12",
|
|
2422
|
+
y1: "19",
|
|
2423
|
+
x2: "12",
|
|
2424
|
+
y2: "22"
|
|
2425
|
+
}, null, -1))
|
|
2426
|
+
])) : (T(), L("span", {
|
|
2427
|
+
key: 3,
|
|
2428
|
+
class: le(["szjyv-mic-dot", { pulse: Re(n) === "recording" && !s.value }]),
|
|
2429
|
+
style: ce({ background: s.value ? "#f85149" : o[Re(n)] })
|
|
2430
|
+
}, null, 6)),
|
|
2431
|
+
a.value || f.value !== "mic" ? (T(), L("span", Zs, Q(a.value ? i.value ? "松开取消" : "松开发送" : f.value), 1)) : H("", !0)
|
|
2432
|
+
], 40, Ks)
|
|
2433
|
+
], 64));
|
|
2434
|
+
}
|
|
2435
|
+
}), eo = { class: "szjyv-captionbar" }, to = /* @__PURE__ */ Ue({
|
|
2436
|
+
__name: "VoiceCaptionBar",
|
|
2437
|
+
setup(e) {
|
|
2438
|
+
const t = It(), n = tn({ connected: !1, playing: !1, caption: null });
|
|
2439
|
+
let s = null;
|
|
2440
|
+
const r = ye(
|
|
2441
|
+
() => t.playback.value,
|
|
2442
|
+
(l) => {
|
|
2443
|
+
!l || s || (s = l.subscribe((c) => Object.assign(n, c)));
|
|
2444
|
+
},
|
|
2445
|
+
{ immediate: !0 }
|
|
2446
|
+
);
|
|
2447
|
+
De(() => {
|
|
2448
|
+
r(), s == null || s();
|
|
2449
|
+
});
|
|
2450
|
+
const o = q(() => n.connected && n.playing), a = q(
|
|
2451
|
+
() => o.value ? "#2ea043" : n.connected ? "#8b949e" : "#f85149"
|
|
2452
|
+
), i = () => {
|
|
2453
|
+
t.skipPlayback();
|
|
2454
|
+
};
|
|
2455
|
+
return (l, c) => (T(), L("div", eo, [
|
|
2456
|
+
o.value ? (T(), Se(zt, {
|
|
2457
|
+
key: 0,
|
|
2458
|
+
color: "#2ea043",
|
|
2459
|
+
height: 13
|
|
2460
|
+
})) : (T(), L("span", {
|
|
2461
|
+
key: 1,
|
|
2462
|
+
class: le(["szjyv-caption-dot", { offline: !n.connected }]),
|
|
2463
|
+
style: ce({ background: a.value })
|
|
2464
|
+
}, null, 6)),
|
|
2465
|
+
(T(), L("span", {
|
|
2466
|
+
key: n.caption ?? "idle",
|
|
2467
|
+
class: "szjyv-caption-text"
|
|
2468
|
+
}, Q(n.caption ?? (n.connected ? "voice ready" : "voice offline")), 1)),
|
|
2469
|
+
n.playing ? (T(), L("button", {
|
|
2470
|
+
key: 2,
|
|
2471
|
+
class: "szjyv-skip",
|
|
2472
|
+
onClick: i
|
|
2473
|
+
}, "skip")) : H("", !0)
|
|
2474
|
+
]));
|
|
2475
|
+
}
|
|
2476
|
+
}), no = { class: "panel-header" }, so = { class: "header-actions" }, oo = { class: "header-title" }, ro = { class: "action-icons" }, ao = { class: "body-content" }, io = {
|
|
1481
2477
|
key: 0,
|
|
1482
2478
|
class: "welcome-content"
|
|
1483
|
-
},
|
|
2479
|
+
}, lo = { class: "subtitle" }, co = { class: "highlight" }, uo = { class: "quick-questions" }, fo = ["onClick"], ho = {
|
|
1484
2480
|
key: 1,
|
|
1485
2481
|
class: "message-content user-content"
|
|
1486
|
-
},
|
|
2482
|
+
}, po = {
|
|
1487
2483
|
key: 0,
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
2484
|
+
class: "ai-thinking-indicator"
|
|
2485
|
+
}, mo = {
|
|
2486
|
+
key: 1,
|
|
2487
|
+
class: "ai-failed-tip"
|
|
2488
|
+
}, vo = { class: "panel-footer" }, go = {
|
|
1492
2489
|
key: 0,
|
|
1493
2490
|
class: "voice-progress-banner"
|
|
1494
|
-
},
|
|
2491
|
+
}, yo = { class: "progress-info" }, wo = { class: "progress-text" }, bo = {
|
|
1495
2492
|
key: 0,
|
|
1496
2493
|
class: "progress-percent"
|
|
1497
|
-
},
|
|
2494
|
+
}, ko = {
|
|
1498
2495
|
key: 0,
|
|
1499
2496
|
class: "progress-track"
|
|
1500
|
-
},
|
|
2497
|
+
}, So = { class: "recording-main" }, Co = { class: "recording-status" }, Ao = {
|
|
1501
2498
|
key: 0,
|
|
1502
2499
|
class: "recording-time"
|
|
1503
|
-
},
|
|
2500
|
+
}, To = { class: "recording-hint" }, xo = {
|
|
1504
2501
|
key: 1,
|
|
1505
2502
|
class: "volume-waves"
|
|
1506
|
-
},
|
|
2503
|
+
}, Ro = { class: "recording-actions" }, Eo = ["title"], Lo = {
|
|
1507
2504
|
key: 0,
|
|
1508
2505
|
class: "voice-playback-bar"
|
|
1509
|
-
},
|
|
2506
|
+
}, Po = ["title"], Uo = { class: "playback-play-icon" }, Mo = {
|
|
1510
2507
|
key: 0,
|
|
1511
2508
|
viewBox: "0 0 24 24",
|
|
1512
2509
|
width: "14",
|
|
1513
2510
|
height: "14",
|
|
1514
2511
|
fill: "currentColor"
|
|
1515
|
-
},
|
|
2512
|
+
}, _o = {
|
|
1516
2513
|
key: 1,
|
|
1517
2514
|
viewBox: "0 0 24 24",
|
|
1518
2515
|
width: "14",
|
|
1519
2516
|
height: "14",
|
|
1520
2517
|
fill: "currentColor"
|
|
1521
|
-
},
|
|
2518
|
+
}, jo = { class: "playback-title" }, Io = {
|
|
1522
2519
|
key: 0,
|
|
1523
2520
|
class: "playback-time"
|
|
1524
|
-
},
|
|
2521
|
+
}, zo = {
|
|
1525
2522
|
key: 1,
|
|
1526
2523
|
class: "playback-waves"
|
|
1527
|
-
},
|
|
2524
|
+
}, $o = { class: "input-box" }, Oo = { class: "input-actions-box" }, Bo = ["src"], $t = {
|
|
1528
2525
|
__name: "ChatPanel",
|
|
1529
2526
|
props: {
|
|
1530
2527
|
modelValue: {
|
|
@@ -1591,6 +2588,27 @@ const $n = { class: "panel-header" }, On = { class: "header-actions" }, Nn = { c
|
|
|
1591
2588
|
/**
|
|
1592
2589
|
* 是否显示上传音频/视频识别入口,默认关闭
|
|
1593
2590
|
*/
|
|
2591
|
+
/**
|
|
2592
|
+
* 全双工语音(gateway-openai /api/voice):识别 → 填入输入框,助手回复经 SSE 朗读。
|
|
2593
|
+
* 默认关闭以向后兼容;开启后挂载全双工麦克风与字幕栏。
|
|
2594
|
+
*/
|
|
2595
|
+
enableDuplexVoice: {
|
|
2596
|
+
type: Boolean,
|
|
2597
|
+
default: !1
|
|
2598
|
+
},
|
|
2599
|
+
/** 全双工语音后端地址;留空则用默认 /api/voice(同源代理或 /config basePath 纠正) */
|
|
2600
|
+
voiceApiBase: {
|
|
2601
|
+
type: String,
|
|
2602
|
+
default: ""
|
|
2603
|
+
},
|
|
2604
|
+
/**
|
|
2605
|
+
* 朗读助手回复(TTS)。默认关闭——识别填入输入框不依赖此项;
|
|
2606
|
+
* 运行时切换即时生效(无需重挂载组件)。
|
|
2607
|
+
*/
|
|
2608
|
+
enableVoiceTts: {
|
|
2609
|
+
type: Boolean,
|
|
2610
|
+
default: !1
|
|
2611
|
+
},
|
|
1594
2612
|
enableVoiceUpload: {
|
|
1595
2613
|
type: Boolean,
|
|
1596
2614
|
default: !1
|
|
@@ -1629,210 +2647,275 @@ const $n = { class: "panel-header" }, On = { class: "header-actions" }, Nn = { c
|
|
|
1629
2647
|
},
|
|
1630
2648
|
emits: ["update:modelValue", "submit", "ui-action"],
|
|
1631
2649
|
setup(e, { emit: t }) {
|
|
1632
|
-
const { appContext:
|
|
1633
|
-
let
|
|
1634
|
-
const a =
|
|
2650
|
+
const { appContext: n } = bt(), { $message: s } = n.config.globalProperties, r = e;
|
|
2651
|
+
let o = null;
|
|
2652
|
+
const a = R("idle"), i = R(""), l = R(0), c = R(0), d = R(0);
|
|
1635
2653
|
let P = null;
|
|
1636
|
-
const A =
|
|
1637
|
-
let
|
|
1638
|
-
const
|
|
1639
|
-
const
|
|
1640
|
-
return
|
|
1641
|
-
},
|
|
1642
|
-
const
|
|
1643
|
-
return `${
|
|
1644
|
-
},
|
|
1645
|
-
soundBaseUrl:
|
|
1646
|
-
workerUrl:
|
|
1647
|
-
onStatusChange: (
|
|
1648
|
-
a.value =
|
|
2654
|
+
const A = R(""), m = R(!1), S = R(0);
|
|
2655
|
+
let x = null;
|
|
2656
|
+
const _ = R(""), w = R(""), u = q(() => a.value === "downloading"), k = q(() => a.value === "loading"), v = q(() => a.value === "recording"), f = q(() => a.value === "transcribing"), U = q(() => v.value ? "正在录音,点击完成后开始识别" : _.value ? "正在流式转写..." : "正在识别语音中..."), M = q(() => r.enableVoiceInput ? "请输入您的问题或点击麦克风语音输入" : r.enableVoiceUpload ? "请输入您的问题或上传音频识别" : "请输入您的问题"), F = (y, b) => {
|
|
2657
|
+
const z = (y || "").trim(), J = (b || "").trim();
|
|
2658
|
+
return J ? z ? /[A-Za-z0-9]$/.test(z) && /[A-Za-z0-9]/.test(J.charAt(0)) ? `${z} ${J}` : `${z}${J}` : J : z;
|
|
2659
|
+
}, I = (y) => {
|
|
2660
|
+
const b = Math.floor(y / 60), z = y % 60;
|
|
2661
|
+
return `${b.toString().padStart(2, "0")}:${z.toString().padStart(2, "0")}`;
|
|
2662
|
+
}, O = () => (o || (o = new ws({
|
|
2663
|
+
soundBaseUrl: r.soundBaseUrl || "/sounds/",
|
|
2664
|
+
workerUrl: r.workerUrl || void 0,
|
|
2665
|
+
onStatusChange: (y, b) => {
|
|
2666
|
+
a.value = y, b && (i.value = b);
|
|
1649
2667
|
},
|
|
1650
|
-
onProgress: (
|
|
1651
|
-
typeof
|
|
2668
|
+
onProgress: (y) => {
|
|
2669
|
+
typeof y.progress == "number" && (l.value = y.progress);
|
|
1652
2670
|
},
|
|
1653
|
-
onVolumeChange: (
|
|
1654
|
-
c.value =
|
|
2671
|
+
onVolumeChange: (y) => {
|
|
2672
|
+
c.value = y;
|
|
1655
2673
|
},
|
|
1656
|
-
onAudioRecorded: (
|
|
1657
|
-
A.value && URL.revokeObjectURL(A.value), A.value =
|
|
2674
|
+
onAudioRecorded: (y) => {
|
|
2675
|
+
A.value && URL.revokeObjectURL(A.value), A.value = y, S.value = d.value;
|
|
1658
2676
|
},
|
|
1659
|
-
onPartial: (
|
|
1660
|
-
|
|
2677
|
+
onPartial: (y) => {
|
|
2678
|
+
_.value = y || "", h.value = F(w.value, y);
|
|
1661
2679
|
},
|
|
1662
|
-
onResult: (
|
|
1663
|
-
|
|
1664
|
-
|
|
2680
|
+
onResult: (y) => {
|
|
2681
|
+
_.value = y || "", h.value = F(w.value, y), y ? s.success("语音识别完成") : s.warning("未能识别出有效语音,请重试"), setTimeout(() => {
|
|
2682
|
+
_.value = "", j.value && j.value.focus();
|
|
1665
2683
|
}, 100);
|
|
1666
2684
|
},
|
|
1667
|
-
onError: (
|
|
1668
|
-
|
|
2685
|
+
onError: (y) => {
|
|
2686
|
+
s.error(y || "语音输入服务出错"), D();
|
|
1669
2687
|
}
|
|
1670
|
-
})),
|
|
1671
|
-
|
|
1672
|
-
|
|
2688
|
+
})), o), E = () => {
|
|
2689
|
+
D(), d.value = 0, P = setInterval(() => {
|
|
2690
|
+
d.value += 1;
|
|
1673
2691
|
}, 1e3);
|
|
1674
|
-
},
|
|
2692
|
+
}, D = () => {
|
|
1675
2693
|
P && (clearInterval(P), P = null);
|
|
1676
|
-
},
|
|
1677
|
-
if (!
|
|
1678
|
-
if (
|
|
1679
|
-
await
|
|
2694
|
+
}, se = async () => {
|
|
2695
|
+
if (!r.enableVoiceInput) return;
|
|
2696
|
+
if (v.value) {
|
|
2697
|
+
await K();
|
|
1680
2698
|
return;
|
|
1681
2699
|
}
|
|
1682
|
-
|
|
1683
|
-
const
|
|
2700
|
+
m.value && x && (x.pause(), m.value = !1);
|
|
2701
|
+
const y = O();
|
|
1684
2702
|
try {
|
|
1685
|
-
|
|
1686
|
-
} catch (
|
|
1687
|
-
|
|
2703
|
+
w.value = h.value, _.value = "", E(), await y.startRecording();
|
|
2704
|
+
} catch (b) {
|
|
2705
|
+
D(), console.error("启动录音失败:", b);
|
|
1688
2706
|
}
|
|
1689
|
-
},
|
|
1690
|
-
|
|
1691
|
-
},
|
|
1692
|
-
|
|
1693
|
-
},
|
|
1694
|
-
var
|
|
1695
|
-
if (!
|
|
1696
|
-
const
|
|
1697
|
-
if (!
|
|
1698
|
-
|
|
1699
|
-
const
|
|
2707
|
+
}, K = async () => {
|
|
2708
|
+
D(), o && await o.stopAndTranscribe();
|
|
2709
|
+
}, oe = R(null), ae = () => {
|
|
2710
|
+
r.enableVoiceUpload && oe.value && (oe.value.value = "", oe.value.click());
|
|
2711
|
+
}, X = async (y) => {
|
|
2712
|
+
var ge;
|
|
2713
|
+
if (!r.enableVoiceUpload) return;
|
|
2714
|
+
const b = y.target, z = (ge = b == null ? void 0 : b.files) == null ? void 0 : ge[0];
|
|
2715
|
+
if (!z) return;
|
|
2716
|
+
m.value && x && (x.pause(), m.value = !1);
|
|
2717
|
+
const J = O();
|
|
1700
2718
|
try {
|
|
1701
|
-
|
|
1702
|
-
} catch (
|
|
1703
|
-
|
|
2719
|
+
w.value = h.value, _.value = "", s.info(`正在流式识别文件: ${z.name}`), await J.transcribeFile(z);
|
|
2720
|
+
} catch (te) {
|
|
2721
|
+
s.error(`文件识别失败: ${te.message || te}`);
|
|
1704
2722
|
}
|
|
1705
|
-
},
|
|
1706
|
-
|
|
1707
|
-
},
|
|
1708
|
-
|
|
1709
|
-
},
|
|
2723
|
+
}, ue = () => {
|
|
2724
|
+
D(), _.value = "", h.value = w.value, o && o.cancelRecording();
|
|
2725
|
+
}, me = () => {
|
|
2726
|
+
_.value = "", h.value = w.value, o && o.cancelTranscribe(), s.info("已取消本次语音识别");
|
|
2727
|
+
}, ve = () => {
|
|
1710
2728
|
if (A.value) {
|
|
1711
|
-
if (
|
|
1712
|
-
|
|
2729
|
+
if (m.value && x) {
|
|
2730
|
+
x.pause(), m.value = !1;
|
|
1713
2731
|
return;
|
|
1714
2732
|
}
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
},
|
|
1718
|
-
|
|
1719
|
-
},
|
|
1720
|
-
|
|
1721
|
-
},
|
|
1722
|
-
|
|
1723
|
-
}).catch((
|
|
1724
|
-
console.error("音频播放出错:",
|
|
2733
|
+
x && (x.pause(), x = null), x = new Audio(A.value), x.onloadedmetadata = () => {
|
|
2734
|
+
x && !isNaN(x.duration) && (S.value = Math.round(x.duration));
|
|
2735
|
+
}, x.onended = () => {
|
|
2736
|
+
m.value = !1;
|
|
2737
|
+
}, x.onerror = () => {
|
|
2738
|
+
m.value = !1, s.error("音频试听播放失败");
|
|
2739
|
+
}, x.play().then(() => {
|
|
2740
|
+
m.value = !0;
|
|
2741
|
+
}).catch((y) => {
|
|
2742
|
+
console.error("音频播放出错:", y), m.value = !1;
|
|
1725
2743
|
});
|
|
1726
2744
|
}
|
|
1727
|
-
},
|
|
1728
|
-
|
|
2745
|
+
}, de = () => {
|
|
2746
|
+
x && (x.pause(), x = null), m.value = !1, A.value && (URL.revokeObjectURL(A.value), A.value = "");
|
|
1729
2747
|
};
|
|
1730
|
-
|
|
1731
|
-
|
|
2748
|
+
nn(() => {
|
|
2749
|
+
D(), de(), o && (o.destroy(), o = null);
|
|
1732
2750
|
});
|
|
1733
|
-
const
|
|
2751
|
+
const Ae = q(() => ct.find((y) => y.modelName === r.llmName) ?? ct.find((y) => y.modelName === "szjy")), W = t, h = R(""), j = R(null), V = R(!1), B = R([]), Y = R([
|
|
1734
2752
|
"什么是AI助理,能做什么?",
|
|
1735
2753
|
"当前项目的基本情况?",
|
|
1736
2754
|
"当前项目的进度情况?",
|
|
1737
2755
|
"当前项目的参建方有哪些?",
|
|
1738
2756
|
"数智建管平台有哪些功能?能做什么?"
|
|
1739
|
-
]),
|
|
1740
|
-
|
|
1741
|
-
if (
|
|
1742
|
-
const
|
|
1743
|
-
|
|
1744
|
-
top:
|
|
2757
|
+
]), $ = R([]), Z = R(!1), g = R(null), C = () => {
|
|
2758
|
+
Ct(() => {
|
|
2759
|
+
if (g.value) {
|
|
2760
|
+
const y = g.value, b = y.scrollHeight, z = y.scrollTop, J = y.clientHeight;
|
|
2761
|
+
b - z - J < 100 ? y.scrollTop = b : y.scrollTo({
|
|
2762
|
+
top: b
|
|
1745
2763
|
});
|
|
1746
2764
|
}
|
|
1747
2765
|
});
|
|
1748
|
-
},
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
2766
|
+
}, G = R(!1), ee = R(!1), re = R("");
|
|
2767
|
+
let we = "";
|
|
2768
|
+
const Nt = q(() => G.value ? "/images/ai-stop.png" : "/images/ai-send.png"), ot = (y, b) => {
|
|
2769
|
+
var be;
|
|
2770
|
+
console.log("onFailedReader", y, b), Me(), Z.value = !1, ee.value = !1;
|
|
2771
|
+
const z = We();
|
|
2772
|
+
z && z.initializeEnd();
|
|
2773
|
+
const J = B.value[y], ge = $.value[y], te = ((be = ge == null ? void 0 : ge.getRawText) == null ? void 0 : be.call(ge)) || "";
|
|
2774
|
+
J && J.type === "ai" && !J.displayText && !te && B.value.splice(y, 1), re.value = we, G.value = !1, C(), setTimeout(() => {
|
|
2775
|
+
j.value && j.value.focus();
|
|
1753
2776
|
});
|
|
1754
|
-
},
|
|
1755
|
-
|
|
1756
|
-
|
|
2777
|
+
}, Vt = (y) => {
|
|
2778
|
+
ee.value = !1;
|
|
2779
|
+
}, Ft = (y, b) => {
|
|
2780
|
+
Z.value = !1, G.value = !1, ee.value = !1, C(), Kt(y, b), b && B.value[y] && (B.value[y].displayText = b), setTimeout(() => {
|
|
2781
|
+
j.value && j.value.focus();
|
|
1757
2782
|
});
|
|
1758
|
-
},
|
|
1759
|
-
|
|
1760
|
-
},
|
|
1761
|
-
|
|
1762
|
-
},
|
|
1763
|
-
|
|
1764
|
-
},
|
|
1765
|
-
|
|
1766
|
-
},
|
|
1767
|
-
for (let
|
|
1768
|
-
if (
|
|
1769
|
-
return
|
|
2783
|
+
}, Dt = (y) => {
|
|
2784
|
+
G.value = !0, Jt(y);
|
|
2785
|
+
}, Ht = () => {
|
|
2786
|
+
G.value = !1, ee.value = !1, re.value = "", W("update:modelValue", !1), V.value = !1, B.value = [];
|
|
2787
|
+
}, qe = R(!1), qt = () => {
|
|
2788
|
+
qe.value = !qe.value;
|
|
2789
|
+
}, Wt = (y) => {
|
|
2790
|
+
h.value = y, Be();
|
|
2791
|
+
}, We = () => {
|
|
2792
|
+
for (let y = $.value.length - 1; y >= 0; y--)
|
|
2793
|
+
if ($.value[y])
|
|
2794
|
+
return $.value[y];
|
|
1770
2795
|
return null;
|
|
1771
|
-
},
|
|
1772
|
-
if (console.log("stylizingLoading:",
|
|
1773
|
-
|
|
1774
|
-
|
|
2796
|
+
}, Be = async () => {
|
|
2797
|
+
if (console.log("stylizingLoading:", Z.value), Z.value) {
|
|
2798
|
+
ee.value = !1;
|
|
2799
|
+
const b = We();
|
|
2800
|
+
console.log("lastPreviewer:", b), b && (console.log("abortReader"), b.abortReader());
|
|
1775
2801
|
return;
|
|
1776
2802
|
}
|
|
1777
|
-
if (!
|
|
1778
|
-
console.log("no input, return"),
|
|
2803
|
+
if (!h.value.trim()) {
|
|
2804
|
+
console.log("no input, return"), j.value.focus();
|
|
1779
2805
|
return;
|
|
1780
2806
|
}
|
|
1781
|
-
|
|
2807
|
+
B.value.push({
|
|
1782
2808
|
type: "user",
|
|
1783
|
-
content:
|
|
1784
|
-
}),
|
|
1785
|
-
const
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
2809
|
+
content: h.value
|
|
2810
|
+
}), G.value = !0, V.value = !0, re.value = "", W("submit", h.value), C();
|
|
2811
|
+
const y = h.value;
|
|
2812
|
+
we = y, h.value = "", await rt(y);
|
|
2813
|
+
}, Gt = async () => {
|
|
2814
|
+
const y = re.value;
|
|
2815
|
+
!y || Z.value || (re.value = "", we = y, G.value = !0, C(), await rt(y));
|
|
2816
|
+
}, rt = async (y) => {
|
|
2817
|
+
const b = B.value.length;
|
|
2818
|
+
$.value[b] && $.value[b].initializeStart(), Z.value = !0, ee.value = !0, B.value.push({
|
|
1789
2819
|
type: "ai"
|
|
1790
2820
|
});
|
|
1791
|
-
const { error:
|
|
1792
|
-
text:
|
|
1793
|
-
token:
|
|
1794
|
-
identifier:
|
|
1795
|
-
baseUrl:
|
|
2821
|
+
const { error: z, reader: J } = await xn(Ae.value, {
|
|
2822
|
+
text: y,
|
|
2823
|
+
token: r.token,
|
|
2824
|
+
identifier: r.identifier,
|
|
2825
|
+
baseUrl: r.baseUrl,
|
|
1796
2826
|
// mock 模式(llmName=standard)经 extraConfig 读取 mockResponse,不侵入 API 签名
|
|
1797
|
-
extraConfig:
|
|
2827
|
+
extraConfig: r.mockResponse ? Object.assign({}, r.extraConfig, { mockResponse: r.mockResponse }) : r.extraConfig
|
|
1798
2828
|
});
|
|
1799
|
-
if (
|
|
1800
|
-
console.log(45455,
|
|
2829
|
+
if (z) {
|
|
2830
|
+
console.log(45455, z), ot(b, z);
|
|
1801
2831
|
return;
|
|
1802
2832
|
}
|
|
1803
|
-
|
|
2833
|
+
J && (B.value[b].reader = J);
|
|
1804
2834
|
};
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
2835
|
+
let Ee = null, Te = 0, at = 0;
|
|
2836
|
+
const Ge = R(r.enableVoiceTts);
|
|
2837
|
+
ye(
|
|
2838
|
+
() => r.enableVoiceTts,
|
|
2839
|
+
(y) => {
|
|
2840
|
+
Ge.value = y, y || Me();
|
|
2841
|
+
}
|
|
2842
|
+
);
|
|
2843
|
+
const Me = () => {
|
|
2844
|
+
Te = 0;
|
|
2845
|
+
}, Jt = (y) => {
|
|
2846
|
+
if (!Ee) return;
|
|
2847
|
+
const b = $.value[y];
|
|
2848
|
+
if (!b || !b.getRawText) return;
|
|
2849
|
+
const z = b.getRawText() || "";
|
|
2850
|
+
if (!Ge.value) {
|
|
2851
|
+
z.length > Te && (Te = z.length);
|
|
2852
|
+
return;
|
|
2853
|
+
}
|
|
2854
|
+
const J = Date.now();
|
|
2855
|
+
z.length > Te && J - at > 250 && (Ee(z.slice(Te), !1), Te = z.length, at = J);
|
|
2856
|
+
}, Kt = (y, b) => {
|
|
2857
|
+
if (!Ee) return;
|
|
2858
|
+
if (!Ge.value) {
|
|
2859
|
+
Me();
|
|
2860
|
+
return;
|
|
2861
|
+
}
|
|
2862
|
+
const z = $.value[y];
|
|
2863
|
+
if (z && z.isAborted && z.isAborted()) {
|
|
2864
|
+
Me();
|
|
2865
|
+
return;
|
|
2866
|
+
}
|
|
2867
|
+
const J = b || (z && z.getRawText ? z.getRawText() : "") || "";
|
|
2868
|
+
J.length > Te && Ee(J.slice(Te), !1), Ee("", !0), Me();
|
|
2869
|
+
};
|
|
2870
|
+
if (r.enableDuplexVoice) {
|
|
2871
|
+
const y = "chat-voice-" + Date.now().toString(36) + Math.random().toString(36).slice(2, 8), { speak: b } = Ds({
|
|
2872
|
+
apiBase: r.voiceApiBase || void 0,
|
|
2873
|
+
sessionId: y,
|
|
2874
|
+
running: q(() => G.value),
|
|
2875
|
+
onTranscript: (z) => {
|
|
2876
|
+
h.value = F(h.value, z);
|
|
2877
|
+
},
|
|
2878
|
+
onSubmit: () => {
|
|
2879
|
+
Be();
|
|
2880
|
+
},
|
|
2881
|
+
onCancelTurn: () => {
|
|
2882
|
+
const z = We();
|
|
2883
|
+
z && z.abortReader();
|
|
2884
|
+
}
|
|
2885
|
+
});
|
|
2886
|
+
Ee = b;
|
|
2887
|
+
}
|
|
2888
|
+
return (y, b) => {
|
|
2889
|
+
const z = Je("el-icon"), J = Je("el-button"), ge = Je("el-input");
|
|
2890
|
+
return T(), Se(Le, { name: "slide" }, {
|
|
2891
|
+
default: ie(() => [
|
|
2892
|
+
e.modelValue ? (T(), L("div", {
|
|
1810
2893
|
key: 0,
|
|
1811
|
-
class:
|
|
2894
|
+
class: le(["ai-panel", { "drawer-mode": qe.value, "embedded-mode": e.embedded }])
|
|
1812
2895
|
}, [
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
e.embedded ?
|
|
2896
|
+
p("div", no, [
|
|
2897
|
+
p("div", so, [
|
|
2898
|
+
p("div", oo, Q(e.title), 1),
|
|
2899
|
+
p("div", ro, [
|
|
2900
|
+
e.embedded ? H("", !0) : (T(), Se(z, {
|
|
1818
2901
|
key: 0,
|
|
1819
2902
|
class: "action-icon",
|
|
1820
|
-
onClick:
|
|
2903
|
+
onClick: qt
|
|
1821
2904
|
}, {
|
|
1822
|
-
default:
|
|
1823
|
-
|
|
2905
|
+
default: ie(() => [
|
|
2906
|
+
ne(Ve, {
|
|
1824
2907
|
name: "/images/svg/drawer-layout.svg",
|
|
1825
2908
|
color: "#999999"
|
|
1826
2909
|
})
|
|
1827
2910
|
]),
|
|
1828
2911
|
_: 1
|
|
1829
2912
|
})),
|
|
1830
|
-
|
|
2913
|
+
ne(z, {
|
|
1831
2914
|
class: "action-icon",
|
|
1832
|
-
onClick:
|
|
2915
|
+
onClick: Ht
|
|
1833
2916
|
}, {
|
|
1834
|
-
default:
|
|
1835
|
-
|
|
2917
|
+
default: ie(() => [
|
|
2918
|
+
ne(Ve, {
|
|
1836
2919
|
name: "/images/svg/close.svg",
|
|
1837
2920
|
color: "#999999"
|
|
1838
2921
|
})
|
|
@@ -1842,132 +2925,156 @@ const $n = { class: "panel-header" }, On = { class: "header-actions" }, Nn = { c
|
|
|
1842
2925
|
])
|
|
1843
2926
|
])
|
|
1844
2927
|
]),
|
|
1845
|
-
|
|
1846
|
-
|
|
2928
|
+
p("div", ao, [
|
|
2929
|
+
V.value ? (T(), L("div", {
|
|
1847
2930
|
key: 1,
|
|
1848
2931
|
class: "chat-messages",
|
|
1849
2932
|
ref_key: "messageContainerRef",
|
|
1850
|
-
ref:
|
|
2933
|
+
ref: g
|
|
1851
2934
|
}, [
|
|
1852
|
-
(
|
|
1853
|
-
key:
|
|
1854
|
-
class:
|
|
2935
|
+
(T(!0), L(he, null, Fe(B.value, (te, be) => (T(), L("div", {
|
|
2936
|
+
key: be,
|
|
2937
|
+
class: le(["message-item", te.type === "user" ? "user-message" : "ai-message"])
|
|
1855
2938
|
}, [
|
|
1856
|
-
|
|
2939
|
+
te.type === "ai" ? (T(), Se(us, {
|
|
1857
2940
|
key: 0,
|
|
1858
2941
|
ref_for: !0,
|
|
1859
|
-
ref: (
|
|
1860
|
-
reader:
|
|
1861
|
-
"onUpdate:reader": (
|
|
1862
|
-
model:
|
|
1863
|
-
displayText:
|
|
1864
|
-
scrollToBottomFn:
|
|
2942
|
+
ref: (ke) => $.value[be] = ke,
|
|
2943
|
+
reader: te.reader,
|
|
2944
|
+
"onUpdate:reader": (ke) => te.reader = ke,
|
|
2945
|
+
model: r.llmName,
|
|
2946
|
+
displayText: te.displayText,
|
|
2947
|
+
scrollToBottomFn: C,
|
|
1865
2948
|
messagePostRender: e.messagePostRender,
|
|
1866
2949
|
customUi: e.customUi,
|
|
1867
2950
|
uiActionHandler: e.uiActionHandler,
|
|
1868
|
-
onFailed: (
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
2951
|
+
onFailed: (ke) => ot(be, ke),
|
|
2952
|
+
onStarted: () => Vt(),
|
|
2953
|
+
onCompleted: (ke) => Ft(be, ke),
|
|
2954
|
+
onUpdating: () => Dt(be),
|
|
2955
|
+
onUiAction: b[0] || (b[0] = (ke) => W("ui-action", ke))
|
|
2956
|
+
}, null, 8, ["reader", "onUpdate:reader", "model", "displayText", "messagePostRender", "customUi", "uiActionHandler", "onFailed", "onStarted", "onCompleted", "onUpdating"])) : (T(), L("div", ho, Q(te.content), 1))
|
|
2957
|
+
], 2))), 128)),
|
|
2958
|
+
ne(Le, { name: "ai-status-fade" }, {
|
|
2959
|
+
default: ie(() => [
|
|
2960
|
+
ee.value ? (T(), L("div", po, [...b[4] || (b[4] = [
|
|
2961
|
+
p("img", {
|
|
2962
|
+
src: ln,
|
|
2963
|
+
alt: "AI思考中",
|
|
2964
|
+
class: "thinking-icon"
|
|
2965
|
+
}, null, -1),
|
|
2966
|
+
p("img", {
|
|
2967
|
+
src: cn,
|
|
2968
|
+
alt: "",
|
|
2969
|
+
class: "thinking-loading-icon"
|
|
2970
|
+
}, null, -1),
|
|
2971
|
+
p("span", { class: "thinking-text" }, "正在努力思考中~", -1)
|
|
2972
|
+
])])) : re.value ? (T(), L("div", mo, [
|
|
2973
|
+
b[5] || (b[5] = p("span", { class: "failed-text" }, "网络问题请重试", -1)),
|
|
2974
|
+
p("button", {
|
|
2975
|
+
class: "retry-btn",
|
|
2976
|
+
onClick: Gt
|
|
2977
|
+
}, "重试")
|
|
2978
|
+
])) : H("", !0)
|
|
2979
|
+
]),
|
|
2980
|
+
_: 1
|
|
2981
|
+
})
|
|
2982
|
+
], 512)) : (T(), L("div", io, [
|
|
2983
|
+
b[3] || (b[3] = p("div", { class: "title" }, [
|
|
2984
|
+
p("img", {
|
|
2985
|
+
src: an,
|
|
1878
2986
|
alt: "AI助手",
|
|
1879
2987
|
class: "panel-icon"
|
|
1880
2988
|
}),
|
|
1881
|
-
|
|
2989
|
+
p("h3", { class: "title-text" }, "Hi, 您好")
|
|
1882
2990
|
], -1)),
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
2991
|
+
p("div", lo, [
|
|
2992
|
+
b[2] || (b[2] = fe(" 我是", -1)),
|
|
2993
|
+
p("span", co, Q(e.title), 1)
|
|
1886
2994
|
]),
|
|
1887
|
-
|
|
1888
|
-
(
|
|
1889
|
-
key:
|
|
2995
|
+
p("div", uo, [
|
|
2996
|
+
(T(!0), L(he, null, Fe(Y.value, (te, be) => (T(), L("div", {
|
|
2997
|
+
key: be,
|
|
1890
2998
|
class: "question-item",
|
|
1891
|
-
onClick: (
|
|
2999
|
+
onClick: (ke) => Wt(te)
|
|
1892
3000
|
}, [
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
default:
|
|
1896
|
-
|
|
3001
|
+
p("span", null, Q(te), 1),
|
|
3002
|
+
ne(z, null, {
|
|
3003
|
+
default: ie(() => [
|
|
3004
|
+
ne(Ve, {
|
|
1897
3005
|
name: "/images/svg/arrow-right.svg",
|
|
1898
3006
|
color: "#999999"
|
|
1899
3007
|
})
|
|
1900
3008
|
]),
|
|
1901
3009
|
_: 1
|
|
1902
3010
|
})
|
|
1903
|
-
], 8,
|
|
3011
|
+
], 8, fo))), 128))
|
|
1904
3012
|
])
|
|
1905
3013
|
]))
|
|
1906
3014
|
]),
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
l.value > 0 ? (S(), x("span", Qn, W(l.value) + "%", 1)) : $("", !0)
|
|
3015
|
+
p("div", vo, [
|
|
3016
|
+
ne(Le, { name: "fade" }, {
|
|
3017
|
+
default: ie(() => [
|
|
3018
|
+
u.value || k.value ? (T(), L("div", go, [
|
|
3019
|
+
p("div", yo, [
|
|
3020
|
+
b[6] || (b[6] = p("span", { class: "progress-icon" }, "⏳", -1)),
|
|
3021
|
+
p("span", wo, Q(i.value), 1),
|
|
3022
|
+
l.value > 0 ? (T(), L("span", bo, Q(l.value) + "%", 1)) : H("", !0)
|
|
1916
3023
|
]),
|
|
1917
|
-
l.value > 0 ? (
|
|
1918
|
-
|
|
3024
|
+
l.value > 0 ? (T(), L("div", ko, [
|
|
3025
|
+
p("div", {
|
|
1919
3026
|
class: "progress-bar",
|
|
1920
|
-
style:
|
|
3027
|
+
style: ce({ width: l.value + "%" })
|
|
1921
3028
|
}, null, 4)
|
|
1922
|
-
])) :
|
|
1923
|
-
])) :
|
|
3029
|
+
])) : H("", !0)
|
|
3030
|
+
])) : H("", !0)
|
|
1924
3031
|
]),
|
|
1925
3032
|
_: 1
|
|
1926
3033
|
}),
|
|
1927
|
-
|
|
1928
|
-
default:
|
|
1929
|
-
|
|
3034
|
+
ne(Le, { name: "fade" }, {
|
|
3035
|
+
default: ie(() => [
|
|
3036
|
+
v.value || f.value ? (T(), L("div", {
|
|
1930
3037
|
key: 0,
|
|
1931
|
-
class:
|
|
3038
|
+
class: le(["voice-recording-panel", { "has-transcript": f.value }])
|
|
1932
3039
|
}, [
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
class:
|
|
3040
|
+
p("div", So, [
|
|
3041
|
+
p("div", Co, [
|
|
3042
|
+
p("span", {
|
|
3043
|
+
class: le(["recording-pulse", { transcribing: f.value }])
|
|
1937
3044
|
}, null, 2),
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
3045
|
+
v.value ? (T(), L("span", Ao, Q(I(d.value)), 1)) : H("", !0),
|
|
3046
|
+
p("span", To, Q(U.value), 1),
|
|
3047
|
+
v.value ? (T(), L("div", xo, [
|
|
3048
|
+
p("span", {
|
|
1942
3049
|
class: "wave",
|
|
1943
|
-
style:
|
|
3050
|
+
style: ce({ height: Math.max(4, Math.min(22, c.value * 0.3)) + "px" })
|
|
1944
3051
|
}, null, 4),
|
|
1945
|
-
|
|
3052
|
+
p("span", {
|
|
1946
3053
|
class: "wave",
|
|
1947
|
-
style:
|
|
3054
|
+
style: ce({ height: Math.max(4, Math.min(30, c.value * 0.5)) + "px" })
|
|
1948
3055
|
}, null, 4),
|
|
1949
|
-
|
|
3056
|
+
p("span", {
|
|
1950
3057
|
class: "wave",
|
|
1951
|
-
style:
|
|
3058
|
+
style: ce({ height: Math.max(4, Math.min(18, c.value * 0.25)) + "px" })
|
|
1952
3059
|
}, null, 4)
|
|
1953
|
-
])) :
|
|
3060
|
+
])) : H("", !0)
|
|
1954
3061
|
]),
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
3062
|
+
p("div", Ro, [
|
|
3063
|
+
v.value ? (T(), L(he, { key: 0 }, [
|
|
3064
|
+
ne(J, {
|
|
1958
3065
|
size: "small",
|
|
1959
3066
|
circle: "",
|
|
1960
|
-
onClick:
|
|
3067
|
+
onClick: ue,
|
|
1961
3068
|
title: "取消录音",
|
|
1962
3069
|
class: "voice-cancel-btn"
|
|
1963
3070
|
}, {
|
|
1964
|
-
default:
|
|
1965
|
-
|
|
3071
|
+
default: ie(() => [...b[7] || (b[7] = [
|
|
3072
|
+
p("svg", {
|
|
1966
3073
|
viewBox: "0 0 1024 1024",
|
|
1967
3074
|
width: "12",
|
|
1968
3075
|
height: "12"
|
|
1969
3076
|
}, [
|
|
1970
|
-
|
|
3077
|
+
p("path", {
|
|
1971
3078
|
d: "M512 456.310154L94.247385 38.557538a39.384615 39.384615 0 0 0-55.689847 55.689847L456.310154 512 38.557538 929.752615a39.384615 39.384615 0 0 0 55.689847 55.689847L512 567.689846l417.752615 417.752616c15.163077 15.163077 40.526769 15.163077 55.689847 0s15.163077-40.526769 0-55.689847L567.689846 512l417.752616-417.752615a39.384615 39.384615 0 0 0-55.689847-55.689847L512 456.310154z",
|
|
1972
3079
|
fill: "currentColor"
|
|
1973
3080
|
})
|
|
@@ -1975,111 +3082,111 @@ const $n = { class: "panel-header" }, On = { class: "header-actions" }, Nn = { c
|
|
|
1975
3082
|
])]),
|
|
1976
3083
|
_: 1
|
|
1977
3084
|
}),
|
|
1978
|
-
|
|
3085
|
+
ne(J, {
|
|
1979
3086
|
type: "primary",
|
|
1980
3087
|
size: "small",
|
|
1981
3088
|
round: "",
|
|
1982
|
-
onClick:
|
|
3089
|
+
onClick: K,
|
|
1983
3090
|
class: "voice-finish-btn"
|
|
1984
3091
|
}, {
|
|
1985
|
-
default:
|
|
1986
|
-
|
|
3092
|
+
default: ie(() => [...b[8] || (b[8] = [
|
|
3093
|
+
fe(" 完成 ", -1)
|
|
1987
3094
|
])]),
|
|
1988
3095
|
_: 1
|
|
1989
3096
|
})
|
|
1990
|
-
], 64)) :
|
|
3097
|
+
], 64)) : f.value ? (T(), Se(J, {
|
|
1991
3098
|
key: 1,
|
|
1992
3099
|
size: "small",
|
|
1993
3100
|
round: "",
|
|
1994
|
-
onClick:
|
|
3101
|
+
onClick: me,
|
|
1995
3102
|
class: "voice-cancel-transcribe-btn"
|
|
1996
3103
|
}, {
|
|
1997
|
-
default:
|
|
1998
|
-
|
|
3104
|
+
default: ie(() => [...b[9] || (b[9] = [
|
|
3105
|
+
fe(" 取消识别 ", -1)
|
|
1999
3106
|
])]),
|
|
2000
3107
|
_: 1
|
|
2001
|
-
})) :
|
|
3108
|
+
})) : H("", !0)
|
|
2002
3109
|
])
|
|
2003
3110
|
]),
|
|
2004
|
-
|
|
3111
|
+
f.value ? (T(), L("div", {
|
|
2005
3112
|
key: 0,
|
|
2006
|
-
class:
|
|
2007
|
-
title:
|
|
3113
|
+
class: le(["live-transcript", { empty: !_.value }]),
|
|
3114
|
+
title: _.value
|
|
2008
3115
|
}, [
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
], 64)) : (
|
|
2013
|
-
|
|
3116
|
+
_.value ? (T(), L(he, { key: 0 }, [
|
|
3117
|
+
fe(Q(_.value), 1),
|
|
3118
|
+
b[10] || (b[10] = p("span", { class: "caret" }, "|", -1))
|
|
3119
|
+
], 64)) : (T(), L(he, { key: 1 }, [
|
|
3120
|
+
fe("正在识别,文字将实时显示...")
|
|
2014
3121
|
], 64))
|
|
2015
|
-
], 10,
|
|
2016
|
-
], 2)) :
|
|
3122
|
+
], 10, Eo)) : H("", !0)
|
|
3123
|
+
], 2)) : H("", !0)
|
|
2017
3124
|
]),
|
|
2018
3125
|
_: 1
|
|
2019
3126
|
}),
|
|
2020
|
-
|
|
2021
|
-
default:
|
|
2022
|
-
A.value && !
|
|
2023
|
-
|
|
3127
|
+
ne(Le, { name: "fade" }, {
|
|
3128
|
+
default: ie(() => [
|
|
3129
|
+
A.value && !v.value && !f.value ? (T(), L("div", Lo, [
|
|
3130
|
+
p("div", {
|
|
2024
3131
|
class: "playback-main",
|
|
2025
|
-
onClick:
|
|
2026
|
-
title:
|
|
3132
|
+
onClick: ve,
|
|
3133
|
+
title: m.value ? "点击暂停" : "点击播放录音"
|
|
2027
3134
|
}, [
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
])])) : (
|
|
2032
|
-
|
|
3135
|
+
p("div", Uo, [
|
|
3136
|
+
m.value ? (T(), L("svg", _o, [...b[12] || (b[12] = [
|
|
3137
|
+
p("path", { d: "M6 19h4V5H6v14zm8-14v14h4V5h-4z" }, null, -1)
|
|
3138
|
+
])])) : (T(), L("svg", Mo, [...b[11] || (b[11] = [
|
|
3139
|
+
p("path", { d: "M8 5v14l11-7z" }, null, -1)
|
|
2033
3140
|
])]))
|
|
2034
3141
|
]),
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
])])) :
|
|
2043
|
-
], 8,
|
|
2044
|
-
|
|
3142
|
+
p("span", jo, Q(m.value ? "正在播放录音..." : "点击试听本次录音"), 1),
|
|
3143
|
+
S.value > 0 ? (T(), L("span", Io, Q(I(S.value)), 1)) : H("", !0),
|
|
3144
|
+
m.value ? (T(), L("div", zo, [...b[13] || (b[13] = [
|
|
3145
|
+
p("span", { class: "wave-bar" }, null, -1),
|
|
3146
|
+
p("span", { class: "wave-bar" }, null, -1),
|
|
3147
|
+
p("span", { class: "wave-bar" }, null, -1),
|
|
3148
|
+
p("span", { class: "wave-bar" }, null, -1)
|
|
3149
|
+
])])) : H("", !0)
|
|
3150
|
+
], 8, Po),
|
|
3151
|
+
p("div", {
|
|
2045
3152
|
class: "playback-close",
|
|
2046
|
-
onClick:
|
|
3153
|
+
onClick: de,
|
|
2047
3154
|
title: "清除试听"
|
|
2048
|
-
}, [...
|
|
2049
|
-
|
|
3155
|
+
}, [...b[14] || (b[14] = [
|
|
3156
|
+
p("svg", {
|
|
2050
3157
|
viewBox: "0 0 1024 1024",
|
|
2051
3158
|
width: "12",
|
|
2052
3159
|
height: "12"
|
|
2053
3160
|
}, [
|
|
2054
|
-
|
|
3161
|
+
p("path", {
|
|
2055
3162
|
d: "M512 456.310154L94.247385 38.557538a39.384615 39.384615 0 0 0-55.689847 55.689847L456.310154 512 38.557538 929.752615a39.384615 39.384615 0 0 0 55.689847 55.689847L512 567.689846l417.752615 417.752616c15.163077 15.163077 40.526769 15.163077 55.689847 0s15.163077-40.526769 0-55.689847L567.689846 512l417.752616-417.752615a39.384615 39.384615 0 0 0-55.689847-55.689847L512 456.310154z",
|
|
2056
3163
|
fill: "currentColor"
|
|
2057
3164
|
})
|
|
2058
3165
|
], -1)
|
|
2059
3166
|
])])
|
|
2060
|
-
])) :
|
|
3167
|
+
])) : H("", !0)
|
|
2061
3168
|
]),
|
|
2062
3169
|
_: 1
|
|
2063
3170
|
}),
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
modelValue:
|
|
2067
|
-
"onUpdate:modelValue":
|
|
3171
|
+
kt(p("div", $o, [
|
|
3172
|
+
ne(ge, {
|
|
3173
|
+
modelValue: h.value,
|
|
3174
|
+
"onUpdate:modelValue": b[1] || (b[1] = (te) => h.value = te),
|
|
2068
3175
|
ref_key: "refInputTextString",
|
|
2069
|
-
ref:
|
|
2070
|
-
placeholder:
|
|
3176
|
+
ref: j,
|
|
3177
|
+
placeholder: M.value,
|
|
2071
3178
|
autofocus: "",
|
|
2072
|
-
onKeyup:
|
|
3179
|
+
onKeyup: sn(Be, ["enter"])
|
|
2073
3180
|
}, {
|
|
2074
|
-
append:
|
|
2075
|
-
|
|
2076
|
-
e.enableVoiceUpload ? (
|
|
3181
|
+
append: ie(() => [
|
|
3182
|
+
p("div", Oo, [
|
|
3183
|
+
e.enableVoiceUpload ? (T(), L("div", {
|
|
2077
3184
|
key: 0,
|
|
2078
3185
|
class: "voice-upload-btn",
|
|
2079
|
-
onClick:
|
|
3186
|
+
onClick: ae,
|
|
2080
3187
|
title: "上传音频/视频文件识别 (支持 .wav, .mp4, .mp3, .m4a)"
|
|
2081
|
-
}, [...
|
|
2082
|
-
|
|
3188
|
+
}, [...b[15] || (b[15] = [
|
|
3189
|
+
p("svg", {
|
|
2083
3190
|
viewBox: "0 0 24 24",
|
|
2084
3191
|
width: "17",
|
|
2085
3192
|
height: "17",
|
|
@@ -2089,32 +3196,32 @@ const $n = { class: "panel-header" }, On = { class: "header-actions" }, Nn = { c
|
|
|
2089
3196
|
"stroke-linecap": "round",
|
|
2090
3197
|
"stroke-linejoin": "round"
|
|
2091
3198
|
}, [
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
3199
|
+
p("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }),
|
|
3200
|
+
p("polyline", { points: "17 8 12 3 7 8" }),
|
|
3201
|
+
p("line", {
|
|
2095
3202
|
x1: "12",
|
|
2096
3203
|
y1: "3",
|
|
2097
3204
|
x2: "12",
|
|
2098
3205
|
y2: "15"
|
|
2099
3206
|
})
|
|
2100
3207
|
], -1)
|
|
2101
|
-
])])) :
|
|
2102
|
-
e.enableVoiceUpload ? (
|
|
3208
|
+
])])) : H("", !0),
|
|
3209
|
+
e.enableVoiceUpload ? (T(), L("input", {
|
|
2103
3210
|
key: 1,
|
|
2104
3211
|
type: "file",
|
|
2105
3212
|
ref_key: "refAudioFileInput",
|
|
2106
|
-
ref:
|
|
3213
|
+
ref: oe,
|
|
2107
3214
|
accept: "audio/*,video/mp4,.wav,.mp4,.mp3,.m4a",
|
|
2108
3215
|
style: { display: "none" },
|
|
2109
|
-
onChange:
|
|
2110
|
-
}, null, 544)) :
|
|
2111
|
-
e.enableVoiceInput ? (
|
|
3216
|
+
onChange: X
|
|
3217
|
+
}, null, 544)) : H("", !0),
|
|
3218
|
+
e.enableVoiceInput ? (T(), L("div", {
|
|
2112
3219
|
key: 2,
|
|
2113
|
-
class:
|
|
2114
|
-
onClick:
|
|
3220
|
+
class: le(["voice-mic-btn", { "loading-anim": u.value || k.value }]),
|
|
3221
|
+
onClick: se,
|
|
2115
3222
|
title: "语音输入"
|
|
2116
|
-
}, [...
|
|
2117
|
-
|
|
3223
|
+
}, [...b[16] || (b[16] = [
|
|
3224
|
+
p("svg", {
|
|
2118
3225
|
viewBox: "0 0 24 24",
|
|
2119
3226
|
width: "18",
|
|
2120
3227
|
height: "18",
|
|
@@ -2124,328 +3231,330 @@ const $n = { class: "panel-header" }, On = { class: "header-actions" }, Nn = { c
|
|
|
2124
3231
|
"stroke-linecap": "round",
|
|
2125
3232
|
"stroke-linejoin": "round"
|
|
2126
3233
|
}, [
|
|
2127
|
-
|
|
3234
|
+
p("path", {
|
|
2128
3235
|
d: "M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3Z",
|
|
2129
3236
|
fill: "currentColor",
|
|
2130
3237
|
opacity: "0.2"
|
|
2131
3238
|
}),
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
3239
|
+
p("path", { d: "M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3Z" }),
|
|
3240
|
+
p("path", { d: "M19 10v2a7 7 0 0 1-14 0v-2" }),
|
|
3241
|
+
p("line", {
|
|
2135
3242
|
x1: "12",
|
|
2136
3243
|
y1: "19",
|
|
2137
3244
|
x2: "12",
|
|
2138
3245
|
y2: "22"
|
|
2139
3246
|
})
|
|
2140
3247
|
], -1)
|
|
2141
|
-
])], 2)) :
|
|
2142
|
-
|
|
3248
|
+
])], 2)) : H("", !0),
|
|
3249
|
+
e.enableDuplexVoice ? (T(), Se(Re(Qs), { key: 3 })) : H("", !0),
|
|
3250
|
+
p("div", {
|
|
2143
3251
|
class: "send-icon-box",
|
|
2144
|
-
onClick:
|
|
3252
|
+
onClick: Be
|
|
2145
3253
|
}, [
|
|
2146
|
-
|
|
2147
|
-
src:
|
|
3254
|
+
p("img", {
|
|
3255
|
+
src: Nt.value,
|
|
2148
3256
|
alt: "发送",
|
|
2149
3257
|
class: "send-icon"
|
|
2150
|
-
}, null, 8,
|
|
3258
|
+
}, null, 8, Bo)
|
|
2151
3259
|
])
|
|
2152
3260
|
])
|
|
2153
3261
|
]),
|
|
2154
3262
|
_: 1
|
|
2155
3263
|
}, 8, ["modelValue", "placeholder"])
|
|
2156
3264
|
], 512), [
|
|
2157
|
-
[
|
|
2158
|
-
])
|
|
3265
|
+
[St, !v.value && !f.value]
|
|
3266
|
+
]),
|
|
3267
|
+
e.enableDuplexVoice ? (T(), Se(Re(to), { key: 0 })) : H("", !0)
|
|
2159
3268
|
])
|
|
2160
|
-
], 2)) :
|
|
3269
|
+
], 2)) : H("", !0)
|
|
2161
3270
|
]),
|
|
2162
3271
|
_: 1
|
|
2163
3272
|
});
|
|
2164
3273
|
};
|
|
2165
3274
|
}
|
|
2166
3275
|
};
|
|
2167
|
-
var
|
|
3276
|
+
var Ot = { exports: {} };
|
|
2168
3277
|
(function(e, t) {
|
|
2169
|
-
(function(
|
|
2170
|
-
e.exports =
|
|
3278
|
+
(function(n, s) {
|
|
3279
|
+
e.exports = s();
|
|
2171
3280
|
})(window, function() {
|
|
2172
|
-
return function(
|
|
2173
|
-
var
|
|
2174
|
-
function o
|
|
2175
|
-
if (
|
|
2176
|
-
var a =
|
|
2177
|
-
return
|
|
3281
|
+
return function(n) {
|
|
3282
|
+
var s = {};
|
|
3283
|
+
function r(o) {
|
|
3284
|
+
if (s[o]) return s[o].exports;
|
|
3285
|
+
var a = s[o] = { i: o, l: !1, exports: {} };
|
|
3286
|
+
return n[o].call(a.exports, a, a.exports, r), a.l = !0, a.exports;
|
|
2178
3287
|
}
|
|
2179
|
-
return
|
|
2180
|
-
|
|
2181
|
-
},
|
|
2182
|
-
typeof Symbol < "u" && Symbol.toStringTag && Object.defineProperty(
|
|
2183
|
-
},
|
|
2184
|
-
if (1 & a && (
|
|
3288
|
+
return r.m = n, r.c = s, r.d = function(o, a, i) {
|
|
3289
|
+
r.o(o, a) || Object.defineProperty(o, a, { enumerable: !0, get: i });
|
|
3290
|
+
}, r.r = function(o) {
|
|
3291
|
+
typeof Symbol < "u" && Symbol.toStringTag && Object.defineProperty(o, Symbol.toStringTag, { value: "Module" }), Object.defineProperty(o, "__esModule", { value: !0 });
|
|
3292
|
+
}, r.t = function(o, a) {
|
|
3293
|
+
if (1 & a && (o = r(o)), 8 & a || 4 & a && typeof o == "object" && o && o.__esModule) return o;
|
|
2185
3294
|
var i = /* @__PURE__ */ Object.create(null);
|
|
2186
|
-
if (
|
|
2187
|
-
return
|
|
3295
|
+
if (r.r(i), Object.defineProperty(i, "default", { enumerable: !0, value: o }), 2 & a && typeof o != "string") for (var l in o) r.d(i, l, (function(c) {
|
|
3296
|
+
return o[c];
|
|
2188
3297
|
}).bind(null, l));
|
|
2189
3298
|
return i;
|
|
2190
|
-
},
|
|
2191
|
-
var a =
|
|
2192
|
-
return
|
|
3299
|
+
}, r.n = function(o) {
|
|
3300
|
+
var a = o && o.__esModule ? function() {
|
|
3301
|
+
return o.default;
|
|
2193
3302
|
} : function() {
|
|
2194
|
-
return
|
|
3303
|
+
return o;
|
|
2195
3304
|
};
|
|
2196
|
-
return
|
|
2197
|
-
},
|
|
2198
|
-
return Object.prototype.hasOwnProperty.call(
|
|
2199
|
-
},
|
|
2200
|
-
}([function(s, r
|
|
2201
|
-
function
|
|
2202
|
-
|
|
3305
|
+
return r.d(a, "a", a), a;
|
|
3306
|
+
}, r.o = function(o, a) {
|
|
3307
|
+
return Object.prototype.hasOwnProperty.call(o, a);
|
|
3308
|
+
}, r.p = "", r(r.s = 0);
|
|
3309
|
+
}([function(n, s, r) {
|
|
3310
|
+
function o(w, u, k, v) {
|
|
3311
|
+
k.push(w), v.push([].concat(u[w] || []));
|
|
2203
3312
|
}
|
|
2204
|
-
function a(
|
|
2205
|
-
if (!
|
|
2206
|
-
var
|
|
2207
|
-
for (
|
|
2208
|
-
var
|
|
2209
|
-
if (
|
|
2210
|
-
var
|
|
2211
|
-
if (
|
|
2212
|
-
|
|
2213
|
-
} else
|
|
3313
|
+
function a(w, u) {
|
|
3314
|
+
if (!w) throw new Error("[getMaxDepsChain] dep 参数不能为空");
|
|
3315
|
+
var k = [], v = [], f = [];
|
|
3316
|
+
for (o(w, u, v, f); v.length; ) {
|
|
3317
|
+
var U = f.pop();
|
|
3318
|
+
if (U && U.length) {
|
|
3319
|
+
var M = U.shift();
|
|
3320
|
+
if (f.push(U), ~v.indexOf(M)) throw new Error("[getMaxDepsChain][loop] 存在循环依赖,请检查依赖关系; nextName: " + M + ", mainStack: " + v);
|
|
3321
|
+
o(M, u, v, f);
|
|
3322
|
+
} else k.push([].concat(v)), v.pop();
|
|
2214
3323
|
}
|
|
2215
|
-
return
|
|
2216
|
-
return
|
|
3324
|
+
return k.reduce(function(F, I) {
|
|
3325
|
+
return I.length > F.length ? I : F;
|
|
2217
3326
|
}, []);
|
|
2218
3327
|
}
|
|
2219
|
-
function i(
|
|
2220
|
-
if (!
|
|
2221
|
-
var
|
|
2222
|
-
|
|
2223
|
-
|
|
3328
|
+
function i(w) {
|
|
3329
|
+
if (!w) throw new Error("[depsParser] 入参不能为空");
|
|
3330
|
+
var u = {};
|
|
3331
|
+
w.forEach(function(v) {
|
|
3332
|
+
u[v.name] = v.deps || [];
|
|
2224
3333
|
});
|
|
2225
|
-
var
|
|
2226
|
-
return
|
|
2227
|
-
var
|
|
2228
|
-
|
|
2229
|
-
}),
|
|
3334
|
+
var k = [];
|
|
3335
|
+
return w.forEach(function(v) {
|
|
3336
|
+
var f = a(v.name, u).length - 1;
|
|
3337
|
+
v.priority = f, k[f] = (k[f] || []).concat(v);
|
|
3338
|
+
}), k;
|
|
2230
3339
|
}
|
|
2231
|
-
|
|
3340
|
+
r.r(s), r.d(s, "loadScript", function() {
|
|
2232
3341
|
return A;
|
|
2233
|
-
}),
|
|
2234
|
-
return
|
|
2235
|
-
}),
|
|
2236
|
-
return
|
|
2237
|
-
}),
|
|
2238
|
-
return
|
|
2239
|
-
}),
|
|
2240
|
-
return
|
|
2241
|
-
}),
|
|
3342
|
+
}), r.d(s, "loadScripts", function() {
|
|
3343
|
+
return m;
|
|
3344
|
+
}), r.d(s, "dynamicLoadScripts", function() {
|
|
3345
|
+
return S;
|
|
3346
|
+
}), r.d(s, "createScriptsLoadIterator", function() {
|
|
3347
|
+
return x;
|
|
3348
|
+
}), r.d(s, "loadScriptsQueue", function() {
|
|
3349
|
+
return _;
|
|
3350
|
+
}), r.d(s, "getMaxDepsChain", function() {
|
|
2242
3351
|
return a;
|
|
2243
|
-
}),
|
|
3352
|
+
}), r.d(s, "depsParser", function() {
|
|
2244
3353
|
return i;
|
|
2245
3354
|
});
|
|
2246
3355
|
var l = function() {
|
|
2247
|
-
return (l = Object.assign || function(
|
|
2248
|
-
for (var
|
|
2249
|
-
return
|
|
3356
|
+
return (l = Object.assign || function(w) {
|
|
3357
|
+
for (var u, k = 1, v = arguments.length; k < v; k++) for (var f in u = arguments[k]) Object.prototype.hasOwnProperty.call(u, f) && (w[f] = u[f]);
|
|
3358
|
+
return w;
|
|
2250
3359
|
}).apply(this, arguments);
|
|
2251
|
-
}, c = function(
|
|
2252
|
-
return new (
|
|
2253
|
-
function
|
|
3360
|
+
}, c = function(w, u, k, v) {
|
|
3361
|
+
return new (k || (k = Promise))(function(f, U) {
|
|
3362
|
+
function M(O) {
|
|
2254
3363
|
try {
|
|
2255
|
-
|
|
2256
|
-
} catch (
|
|
2257
|
-
|
|
3364
|
+
I(v.next(O));
|
|
3365
|
+
} catch (E) {
|
|
3366
|
+
U(E);
|
|
2258
3367
|
}
|
|
2259
3368
|
}
|
|
2260
|
-
function
|
|
3369
|
+
function F(O) {
|
|
2261
3370
|
try {
|
|
2262
|
-
|
|
2263
|
-
} catch (
|
|
2264
|
-
|
|
3371
|
+
I(v.throw(O));
|
|
3372
|
+
} catch (E) {
|
|
3373
|
+
U(E);
|
|
2265
3374
|
}
|
|
2266
3375
|
}
|
|
2267
|
-
function
|
|
2268
|
-
var
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
})).then(
|
|
3376
|
+
function I(O) {
|
|
3377
|
+
var E;
|
|
3378
|
+
O.done ? f(O.value) : (E = O.value, E instanceof k ? E : new k(function(D) {
|
|
3379
|
+
D(E);
|
|
3380
|
+
})).then(M, F);
|
|
2272
3381
|
}
|
|
2273
|
-
|
|
3382
|
+
I((v = v.apply(w, [])).next());
|
|
2274
3383
|
});
|
|
2275
|
-
},
|
|
2276
|
-
var v, f,
|
|
2277
|
-
if (1 &
|
|
2278
|
-
return
|
|
3384
|
+
}, d = function(w, u) {
|
|
3385
|
+
var k, v, f, U, M = { label: 0, sent: function() {
|
|
3386
|
+
if (1 & f[0]) throw f[1];
|
|
3387
|
+
return f[1];
|
|
2279
3388
|
}, trys: [], ops: [] };
|
|
2280
|
-
return
|
|
3389
|
+
return U = { next: F(0), throw: F(1), return: F(2) }, typeof Symbol == "function" && (U[Symbol.iterator] = function() {
|
|
2281
3390
|
return this;
|
|
2282
|
-
}),
|
|
2283
|
-
function
|
|
2284
|
-
return function(
|
|
2285
|
-
return function(
|
|
2286
|
-
if (
|
|
2287
|
-
for (;
|
|
2288
|
-
if (
|
|
2289
|
-
switch (
|
|
3391
|
+
}), U;
|
|
3392
|
+
function F(I) {
|
|
3393
|
+
return function(O) {
|
|
3394
|
+
return function(E) {
|
|
3395
|
+
if (k) throw new TypeError("Generator is already executing.");
|
|
3396
|
+
for (; M; ) try {
|
|
3397
|
+
if (k = 1, v && (f = 2 & E[0] ? v.return : E[0] ? v.throw || ((f = v.return) && f.call(v), 0) : v.next) && !(f = f.call(v, E[1])).done) return f;
|
|
3398
|
+
switch (v = 0, f && (E = [2 & E[0], f.value]), E[0]) {
|
|
2290
3399
|
case 0:
|
|
2291
3400
|
case 1:
|
|
2292
|
-
|
|
3401
|
+
f = E;
|
|
2293
3402
|
break;
|
|
2294
3403
|
case 4:
|
|
2295
|
-
return
|
|
3404
|
+
return M.label++, { value: E[1], done: !1 };
|
|
2296
3405
|
case 5:
|
|
2297
|
-
|
|
3406
|
+
M.label++, v = E[1], E = [0];
|
|
2298
3407
|
continue;
|
|
2299
3408
|
case 7:
|
|
2300
|
-
|
|
3409
|
+
E = M.ops.pop(), M.trys.pop();
|
|
2301
3410
|
continue;
|
|
2302
3411
|
default:
|
|
2303
|
-
if (
|
|
2304
|
-
|
|
3412
|
+
if (f = M.trys, !((f = f.length > 0 && f[f.length - 1]) || E[0] !== 6 && E[0] !== 2)) {
|
|
3413
|
+
M = 0;
|
|
2305
3414
|
continue;
|
|
2306
3415
|
}
|
|
2307
|
-
if (
|
|
2308
|
-
|
|
3416
|
+
if (E[0] === 3 && (!f || E[1] > f[0] && E[1] < f[3])) {
|
|
3417
|
+
M.label = E[1];
|
|
2309
3418
|
break;
|
|
2310
3419
|
}
|
|
2311
|
-
if (
|
|
2312
|
-
|
|
3420
|
+
if (E[0] === 6 && M.label < f[1]) {
|
|
3421
|
+
M.label = f[1], f = E;
|
|
2313
3422
|
break;
|
|
2314
3423
|
}
|
|
2315
|
-
if (
|
|
2316
|
-
|
|
3424
|
+
if (f && M.label < f[2]) {
|
|
3425
|
+
M.label = f[2], M.ops.push(E);
|
|
2317
3426
|
break;
|
|
2318
3427
|
}
|
|
2319
|
-
|
|
3428
|
+
f[2] && M.ops.pop(), M.trys.pop();
|
|
2320
3429
|
continue;
|
|
2321
3430
|
}
|
|
2322
|
-
|
|
2323
|
-
} catch (
|
|
2324
|
-
|
|
3431
|
+
E = u.call(w, M);
|
|
3432
|
+
} catch (D) {
|
|
3433
|
+
E = [6, D], v = 0;
|
|
2325
3434
|
} finally {
|
|
2326
|
-
|
|
3435
|
+
k = f = 0;
|
|
2327
3436
|
}
|
|
2328
|
-
if (5 &
|
|
2329
|
-
return { value:
|
|
2330
|
-
}([
|
|
3437
|
+
if (5 & E[0]) throw E[1];
|
|
3438
|
+
return { value: E[0] ? E[1] : void 0, done: !0 };
|
|
3439
|
+
}([I, O]);
|
|
2331
3440
|
};
|
|
2332
3441
|
}
|
|
2333
|
-
}, P = function(
|
|
3442
|
+
}, P = function(w) {
|
|
2334
3443
|
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
|
2335
|
-
var
|
|
2336
|
-
return
|
|
3444
|
+
var u, k = w[Symbol.asyncIterator];
|
|
3445
|
+
return k ? k.call(w) : (w = typeof __values == "function" ? __values(w) : w[Symbol.iterator](), u = {}, v("next"), v("throw"), v("return"), u[Symbol.asyncIterator] = function() {
|
|
2337
3446
|
return this;
|
|
2338
|
-
},
|
|
2339
|
-
function f
|
|
2340
|
-
|
|
2341
|
-
return new Promise(function(
|
|
2342
|
-
(function(
|
|
2343
|
-
Promise.resolve(
|
|
2344
|
-
|
|
2345
|
-
},
|
|
2346
|
-
})(
|
|
3447
|
+
}, u);
|
|
3448
|
+
function v(f) {
|
|
3449
|
+
u[f] = w[f] && function(U) {
|
|
3450
|
+
return new Promise(function(M, F) {
|
|
3451
|
+
(function(I, O, E, D) {
|
|
3452
|
+
Promise.resolve(D).then(function(se) {
|
|
3453
|
+
I({ value: se, done: E });
|
|
3454
|
+
}, O);
|
|
3455
|
+
})(M, F, (U = w[f](U)).done, U.value);
|
|
2347
3456
|
});
|
|
2348
3457
|
};
|
|
2349
3458
|
}
|
|
2350
3459
|
};
|
|
2351
|
-
function A(
|
|
2352
|
-
return
|
|
2353
|
-
var
|
|
2354
|
-
|
|
3460
|
+
function A(w, u) {
|
|
3461
|
+
return u === void 0 && (u = !1), new Promise(function(k, v) {
|
|
3462
|
+
var f = u ? document.head : document.body, U = document.createElement("script");
|
|
3463
|
+
U.type = "text/javascript", U.src = w, U.crossOrigin = "anonymous", U.onreadystatechange = k, U.onload = k, U.onerror = v, f.appendChild(U);
|
|
2355
3464
|
});
|
|
2356
3465
|
}
|
|
2357
|
-
var
|
|
2358
|
-
return
|
|
2359
|
-
var v, f,
|
|
2360
|
-
return
|
|
2361
|
-
switch (
|
|
3466
|
+
var m = function(w, u) {
|
|
3467
|
+
return u === void 0 && (u = {}), c(void 0, void 0, void 0, function() {
|
|
3468
|
+
var k, v, f, U, M;
|
|
3469
|
+
return d(this, function(F) {
|
|
3470
|
+
switch (F.label) {
|
|
2362
3471
|
case 0:
|
|
2363
|
-
return
|
|
3472
|
+
return k = u.baseUrl, v = k === void 0 ? "" : k, f = u.lastLoadResult, U = u.inHead, M = U !== void 0 && U, [4, Promise.all(w.map(function(I) {
|
|
2364
3473
|
return c(void 0, void 0, void 0, function() {
|
|
2365
|
-
var
|
|
2366
|
-
return
|
|
2367
|
-
switch (
|
|
3474
|
+
var O, E, D, se, K, oe, ae, X;
|
|
3475
|
+
return d(this, function(ue) {
|
|
3476
|
+
switch (ue.label) {
|
|
2368
3477
|
case 0:
|
|
2369
|
-
return
|
|
3478
|
+
return O = I.name, E = I.path, D = I.deps, (ae = {})[O] = !0, se = ae, (X = {})[O] = !1, K = X, window[O] ? [2, se] : [3, 1];
|
|
2370
3479
|
case 1:
|
|
2371
|
-
return
|
|
2372
|
-
|
|
2373
|
-
}),
|
|
2374
|
-
return
|
|
3480
|
+
return oe = !0, D && f && [].concat(D).forEach(function(me) {
|
|
3481
|
+
f[me] !== !1 && (oe = !0);
|
|
3482
|
+
}), oe ? [4, A(E.indexOf("http") === 0 || E.indexOf("//:") === 0 ? E : v + E, M).then(function() {
|
|
3483
|
+
return se;
|
|
2375
3484
|
}).catch(function() {
|
|
2376
|
-
return
|
|
3485
|
+
return K;
|
|
2377
3486
|
})] : [3, 3];
|
|
2378
3487
|
case 2:
|
|
2379
|
-
return [2,
|
|
3488
|
+
return [2, ue.sent()];
|
|
2380
3489
|
case 3:
|
|
2381
|
-
return [2,
|
|
3490
|
+
return [2, K];
|
|
2382
3491
|
}
|
|
2383
3492
|
});
|
|
2384
3493
|
});
|
|
2385
3494
|
}))];
|
|
2386
3495
|
case 1:
|
|
2387
|
-
return [2,
|
|
3496
|
+
return [2, F.sent()];
|
|
2388
3497
|
}
|
|
2389
3498
|
});
|
|
2390
3499
|
});
|
|
2391
|
-
},
|
|
2392
|
-
return
|
|
2393
|
-
var
|
|
3500
|
+
}, S = function(w, u) {
|
|
3501
|
+
return u === void 0 && (u = {}), function() {
|
|
3502
|
+
var k = [].concat(i(w));
|
|
2394
3503
|
return { next: function() {
|
|
2395
|
-
if (
|
|
2396
|
-
var
|
|
2397
|
-
return
|
|
2398
|
-
return { value:
|
|
3504
|
+
if (k.length) {
|
|
3505
|
+
var v = k.shift();
|
|
3506
|
+
return m(v, u).then(function(f) {
|
|
3507
|
+
return { value: f, done: !1 };
|
|
2399
3508
|
});
|
|
2400
3509
|
}
|
|
2401
3510
|
return Promise.resolve({ done: !0 });
|
|
2402
3511
|
} };
|
|
2403
3512
|
};
|
|
2404
|
-
},
|
|
2405
|
-
var
|
|
2406
|
-
return
|
|
2407
|
-
},
|
|
2408
|
-
return
|
|
2409
|
-
var v, f,
|
|
2410
|
-
return
|
|
2411
|
-
switch (
|
|
3513
|
+
}, x = function(w, u) {
|
|
3514
|
+
var k;
|
|
3515
|
+
return u === void 0 && (u = {}), (k = {})[Symbol.asyncIterator] = S(w, u), k;
|
|
3516
|
+
}, _ = function(w, u) {
|
|
3517
|
+
return u === void 0 && (u = {}), c(void 0, void 0, void 0, function() {
|
|
3518
|
+
var k, v, f, U, M, F;
|
|
3519
|
+
return d(this, function(I) {
|
|
3520
|
+
switch (I.label) {
|
|
2412
3521
|
case 0:
|
|
2413
|
-
|
|
3522
|
+
I.trys.push([0, 5, 6, 11]), k = P(x(w, u)), I.label = 1;
|
|
2414
3523
|
case 1:
|
|
2415
|
-
return [4,
|
|
3524
|
+
return [4, k.next()];
|
|
2416
3525
|
case 2:
|
|
2417
|
-
if ((
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
}),
|
|
3526
|
+
if ((v = I.sent()).done) return [3, 4];
|
|
3527
|
+
f = v.value, u.lastLoadResult = u.lastLoadResult || {}, console.log("current load: ", f), f.forEach(function(O) {
|
|
3528
|
+
u.lastLoadResult = l(l({}, u.lastLoadResult), O);
|
|
3529
|
+
}), I.label = 3;
|
|
2421
3530
|
case 3:
|
|
2422
3531
|
return [3, 1];
|
|
2423
3532
|
case 4:
|
|
2424
3533
|
return [3, 11];
|
|
2425
3534
|
case 5:
|
|
2426
|
-
return
|
|
3535
|
+
return U = I.sent(), M = { error: U }, [3, 11];
|
|
2427
3536
|
case 6:
|
|
2428
|
-
return
|
|
3537
|
+
return I.trys.push([6, , 9, 10]), v && !v.done && (F = k.return) ? [4, F.call(k)] : [3, 8];
|
|
2429
3538
|
case 7:
|
|
2430
|
-
|
|
3539
|
+
I.sent(), I.label = 8;
|
|
2431
3540
|
case 8:
|
|
2432
3541
|
return [3, 10];
|
|
2433
3542
|
case 9:
|
|
2434
|
-
if (
|
|
3543
|
+
if (M) throw M.error;
|
|
2435
3544
|
return [7];
|
|
2436
3545
|
case 10:
|
|
2437
3546
|
return [7];
|
|
2438
3547
|
case 11:
|
|
2439
|
-
return [2,
|
|
3548
|
+
return [2, u.lastLoadResult];
|
|
2440
3549
|
}
|
|
2441
3550
|
});
|
|
2442
3551
|
});
|
|
2443
3552
|
};
|
|
2444
3553
|
}]);
|
|
2445
3554
|
});
|
|
2446
|
-
})(
|
|
2447
|
-
var
|
|
2448
|
-
function
|
|
3555
|
+
})(Ot);
|
|
3556
|
+
var No = Ot.exports;
|
|
3557
|
+
function Bt() {
|
|
2449
3558
|
const e = [
|
|
2450
3559
|
{
|
|
2451
3560
|
name: "markdownit",
|
|
@@ -2457,25 +3566,25 @@ function ct() {
|
|
|
2457
3566
|
}
|
|
2458
3567
|
];
|
|
2459
3568
|
let t = {};
|
|
2460
|
-
|
|
3569
|
+
No.loadScriptsQueue(e, {
|
|
2461
3570
|
baseUrl: "/scripts/ai/",
|
|
2462
3571
|
lastLoadResult: t,
|
|
2463
3572
|
inHead: !1
|
|
2464
|
-
}).then((
|
|
2465
|
-
if (console.log("load ai deps: ",
|
|
2466
|
-
const
|
|
2467
|
-
console.log("markdownit: ",
|
|
3573
|
+
}).then((n) => {
|
|
3574
|
+
if (console.log("load ai deps: ", n), window.markdownit) {
|
|
3575
|
+
const s = window.markdownit();
|
|
3576
|
+
console.log("markdownit: ", s), es();
|
|
2468
3577
|
}
|
|
2469
3578
|
});
|
|
2470
3579
|
}
|
|
2471
|
-
const
|
|
3580
|
+
const Vo = {
|
|
2472
3581
|
key: 0,
|
|
2473
3582
|
class: "ai-assistant"
|
|
2474
|
-
},
|
|
3583
|
+
}, Fo = {
|
|
2475
3584
|
name: "AiChat"
|
|
2476
3585
|
//这个⾮常重要,就是未来你放到其他项⽬中,组件标签的名字,⽐如:<sz-workflow></sz-workflow>
|
|
2477
|
-
},
|
|
2478
|
-
...
|
|
3586
|
+
}, Do = /* @__PURE__ */ Ue({
|
|
3587
|
+
...Fo,
|
|
2479
3588
|
props: {
|
|
2480
3589
|
token: {
|
|
2481
3590
|
type: String,
|
|
@@ -2544,6 +3653,23 @@ const br = {
|
|
|
2544
3653
|
/**
|
|
2545
3654
|
* 是否显示上传音频/视频识别入口,默认关闭
|
|
2546
3655
|
*/
|
|
3656
|
+
/**
|
|
3657
|
+
* 全双工语音(gateway-openai /api/voice):识别填入输入框,助手回复朗读。
|
|
3658
|
+
* 默认关闭以向后兼容;voiceApiBase 留空用默认 /api/voice。
|
|
3659
|
+
*/
|
|
3660
|
+
enableDuplexVoice: {
|
|
3661
|
+
type: Boolean,
|
|
3662
|
+
default: !1
|
|
3663
|
+
},
|
|
3664
|
+
voiceApiBase: {
|
|
3665
|
+
type: String,
|
|
3666
|
+
default: ""
|
|
3667
|
+
},
|
|
3668
|
+
/** 朗读助手回复(TTS),默认关闭;运行时切换即时生效 */
|
|
3669
|
+
enableVoiceTts: {
|
|
3670
|
+
type: Boolean,
|
|
3671
|
+
default: !1
|
|
3672
|
+
},
|
|
2547
3673
|
enableVoiceUpload: {
|
|
2548
3674
|
type: Boolean,
|
|
2549
3675
|
default: !1
|
|
@@ -2574,19 +3700,19 @@ const br = {
|
|
|
2574
3700
|
},
|
|
2575
3701
|
emits: ["ui-action"],
|
|
2576
3702
|
setup(e, { emit: t }) {
|
|
2577
|
-
const
|
|
2578
|
-
|
|
3703
|
+
const n = R(!1), s = R(!1), r = t, o = () => {
|
|
3704
|
+
n.value = !n.value;
|
|
2579
3705
|
}, a = () => {
|
|
2580
|
-
|
|
3706
|
+
s.value = !0, n.value = !1;
|
|
2581
3707
|
}, i = (l) => {
|
|
2582
3708
|
console.log("用户输入:", l);
|
|
2583
3709
|
};
|
|
2584
|
-
return
|
|
2585
|
-
|
|
2586
|
-
modelValue:
|
|
2587
|
-
"onUpdate:modelValue": c[0] || (c[0] = (
|
|
3710
|
+
return Bt(), (l, c) => s.value ? H("", !0) : (T(), L("div", Vo, [
|
|
3711
|
+
ne($t, {
|
|
3712
|
+
modelValue: n.value,
|
|
3713
|
+
"onUpdate:modelValue": c[0] || (c[0] = (d) => n.value = d),
|
|
2588
3714
|
onSubmit: i,
|
|
2589
|
-
onUiAction: c[1] || (c[1] = (
|
|
3715
|
+
onUiAction: c[1] || (c[1] = (d) => r("ui-action", d)),
|
|
2590
3716
|
token: e.token,
|
|
2591
3717
|
identifier: e.identifier,
|
|
2592
3718
|
baseUrl: e.baseUrl,
|
|
@@ -2600,40 +3726,43 @@ const br = {
|
|
|
2600
3726
|
soundBaseUrl: e.soundBaseUrl,
|
|
2601
3727
|
workerUrl: e.workerUrl,
|
|
2602
3728
|
enableVoiceInput: e.enableVoiceInput,
|
|
3729
|
+
enableDuplexVoice: e.enableDuplexVoice,
|
|
3730
|
+
voiceApiBase: e.voiceApiBase,
|
|
3731
|
+
enableVoiceTts: e.enableVoiceTts,
|
|
2603
3732
|
enableVoiceUpload: e.enableVoiceUpload
|
|
2604
|
-
}, null, 8, ["modelValue", "token", "identifier", "baseUrl", "title", "llmName", "messagePostRender", "extraConfig", "customUi", "uiActionHandler", "mockResponse", "soundBaseUrl", "workerUrl", "enableVoiceInput", "enableVoiceUpload"]),
|
|
2605
|
-
|
|
3733
|
+
}, null, 8, ["modelValue", "token", "identifier", "baseUrl", "title", "llmName", "messagePostRender", "extraConfig", "customUi", "uiActionHandler", "mockResponse", "soundBaseUrl", "workerUrl", "enableVoiceInput", "enableDuplexVoice", "voiceApiBase", "enableVoiceTts", "enableVoiceUpload"]),
|
|
3734
|
+
p("div", {
|
|
2606
3735
|
class: "ai-icon",
|
|
2607
|
-
onClick:
|
|
3736
|
+
onClick: o
|
|
2608
3737
|
}, [
|
|
2609
|
-
|
|
3738
|
+
p("div", {
|
|
2610
3739
|
class: "close-icon",
|
|
2611
|
-
onClick:
|
|
3740
|
+
onClick: on(a, ["stop"])
|
|
2612
3741
|
}, [...c[2] || (c[2] = [
|
|
2613
|
-
|
|
3742
|
+
p("svg", {
|
|
2614
3743
|
viewBox: "0 0 1024 1024",
|
|
2615
3744
|
width: "8",
|
|
2616
3745
|
height: "8"
|
|
2617
3746
|
}, [
|
|
2618
|
-
|
|
3747
|
+
p("path", {
|
|
2619
3748
|
d: "M512 456.310154L94.247385 38.557538a39.384615 39.384615 0 0 0-55.689847 55.689847L456.310154 512 38.557538 929.752615a39.384615 39.384615 0 0 0 55.689847 55.689847L512 567.689846l417.752615 417.752616c15.163077 15.163077 40.526769 15.163077 55.689847 0s15.163077-40.526769 0-55.689847L567.689846 512l417.752616-417.752615a39.384615 39.384615 0 0 0-55.689847-55.689847L512 456.310154z",
|
|
2620
3749
|
fill: "currentColor"
|
|
2621
3750
|
})
|
|
2622
3751
|
], -1)
|
|
2623
3752
|
])]),
|
|
2624
|
-
c[3] || (c[3] =
|
|
2625
|
-
src:
|
|
3753
|
+
c[3] || (c[3] = p("img", {
|
|
3754
|
+
src: rn,
|
|
2626
3755
|
alt: "AI助手"
|
|
2627
3756
|
}, null, -1)),
|
|
2628
|
-
c[4] || (c[4] =
|
|
3757
|
+
c[4] || (c[4] = p("span", { class: "ai-icon-text" }, "AI助手", -1))
|
|
2629
3758
|
])
|
|
2630
3759
|
]));
|
|
2631
3760
|
}
|
|
2632
|
-
}),
|
|
3761
|
+
}), Ho = { class: "ai-chat-plain" }, qo = {
|
|
2633
3762
|
name: "AiChatPlain"
|
|
2634
3763
|
// 注册后的组件标签名:<sz-ai-chat-plain>
|
|
2635
|
-
},
|
|
2636
|
-
...
|
|
3764
|
+
}, Wo = /* @__PURE__ */ Ue({
|
|
3765
|
+
...qo,
|
|
2637
3766
|
props: {
|
|
2638
3767
|
token: {
|
|
2639
3768
|
type: String,
|
|
@@ -2702,6 +3831,23 @@ const br = {
|
|
|
2702
3831
|
/**
|
|
2703
3832
|
* 是否显示上传音频/视频识别入口,默认关闭
|
|
2704
3833
|
*/
|
|
3834
|
+
/**
|
|
3835
|
+
* 全双工语音(gateway-openai /api/voice):识别填入输入框,助手回复朗读。
|
|
3836
|
+
* 默认关闭以向后兼容;voiceApiBase 留空用默认 /api/voice。
|
|
3837
|
+
*/
|
|
3838
|
+
enableDuplexVoice: {
|
|
3839
|
+
type: Boolean,
|
|
3840
|
+
default: !1
|
|
3841
|
+
},
|
|
3842
|
+
voiceApiBase: {
|
|
3843
|
+
type: String,
|
|
3844
|
+
default: ""
|
|
3845
|
+
},
|
|
3846
|
+
/** 朗读助手回复(TTS),默认关闭;运行时切换即时生效 */
|
|
3847
|
+
enableVoiceTts: {
|
|
3848
|
+
type: Boolean,
|
|
3849
|
+
default: !1
|
|
3850
|
+
},
|
|
2705
3851
|
enableVoiceUpload: {
|
|
2706
3852
|
type: Boolean,
|
|
2707
3853
|
default: !1
|
|
@@ -2732,9 +3878,9 @@ const br = {
|
|
|
2732
3878
|
},
|
|
2733
3879
|
emits: ["submit", "ui-action"],
|
|
2734
3880
|
setup(e, { emit: t }) {
|
|
2735
|
-
const
|
|
2736
|
-
return
|
|
2737
|
-
|
|
3881
|
+
const n = t;
|
|
3882
|
+
return Bt(), (s, r) => (T(), L("div", Ho, [
|
|
3883
|
+
ne($t, {
|
|
2738
3884
|
"model-value": !0,
|
|
2739
3885
|
token: e.token,
|
|
2740
3886
|
identifier: e.identifier,
|
|
@@ -2749,242 +3895,279 @@ const br = {
|
|
|
2749
3895
|
soundBaseUrl: e.soundBaseUrl,
|
|
2750
3896
|
workerUrl: e.workerUrl,
|
|
2751
3897
|
enableVoiceInput: e.enableVoiceInput,
|
|
3898
|
+
enableDuplexVoice: e.enableDuplexVoice,
|
|
3899
|
+
voiceApiBase: e.voiceApiBase,
|
|
3900
|
+
enableVoiceTts: e.enableVoiceTts,
|
|
2752
3901
|
enableVoiceUpload: e.enableVoiceUpload,
|
|
2753
3902
|
embedded: !0,
|
|
2754
|
-
onSubmit:
|
|
2755
|
-
onUiAction:
|
|
2756
|
-
}, null, 8, ["token", "identifier", "baseUrl", "title", "llmName", "messagePostRender", "extraConfig", "customUi", "uiActionHandler", "mockResponse", "soundBaseUrl", "workerUrl", "enableVoiceInput", "enableVoiceUpload"])
|
|
3903
|
+
onSubmit: r[0] || (r[0] = (o) => n("submit", o)),
|
|
3904
|
+
onUiAction: r[1] || (r[1] = (o) => n("ui-action", o))
|
|
3905
|
+
}, null, 8, ["token", "identifier", "baseUrl", "title", "llmName", "messagePostRender", "extraConfig", "customUi", "uiActionHandler", "mockResponse", "soundBaseUrl", "workerUrl", "enableVoiceInput", "enableDuplexVoice", "voiceApiBase", "enableVoiceTts", "enableVoiceUpload"])
|
|
2757
3906
|
]));
|
|
2758
3907
|
}
|
|
2759
|
-
}),
|
|
3908
|
+
}), wt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
2760
3909
|
__proto__: null,
|
|
2761
|
-
SzAiChat:
|
|
2762
|
-
SzAiChatPlain:
|
|
2763
|
-
}, Symbol.toStringTag, { value: "Module" })),
|
|
2764
|
-
if (!
|
|
2765
|
-
|
|
2766
|
-
for (let t in
|
|
2767
|
-
const
|
|
2768
|
-
e.component(
|
|
3910
|
+
SzAiChat: Do,
|
|
3911
|
+
SzAiChatPlain: Wo
|
|
3912
|
+
}, Symbol.toStringTag, { value: "Module" })), Qe = function(e) {
|
|
3913
|
+
if (!Qe.installed) {
|
|
3914
|
+
Qe.installed = !0;
|
|
3915
|
+
for (let t in wt) {
|
|
3916
|
+
const n = Reflect.get(wt, t);
|
|
3917
|
+
e.component(n.name, n);
|
|
2769
3918
|
}
|
|
2770
3919
|
}
|
|
2771
|
-
},
|
|
2772
|
-
const
|
|
2773
|
-
console.log(`点击了路由链接: ${e}${
|
|
2774
|
-
},
|
|
3920
|
+
}, Go = (e, t) => {
|
|
3921
|
+
const n = t ? `?${new URLSearchParams(t).toString()}` : "";
|
|
3922
|
+
console.log(`点击了路由链接: ${e}${n}`);
|
|
3923
|
+
}, Jo = (e) => {
|
|
2775
3924
|
const t = e.indexOf("?");
|
|
2776
3925
|
if (t === -1)
|
|
2777
3926
|
return { routeName: e };
|
|
2778
|
-
const
|
|
2779
|
-
return new URLSearchParams(
|
|
2780
|
-
|
|
2781
|
-
}), { routeName:
|
|
2782
|
-
},
|
|
3927
|
+
const n = e.substring(0, t), s = e.substring(t + 1), r = {};
|
|
3928
|
+
return new URLSearchParams(s).forEach((a, i) => {
|
|
3929
|
+
r[i] = a;
|
|
3930
|
+
}), { routeName: n, queryParams: Object.keys(r).length > 0 ? r : void 0 };
|
|
3931
|
+
}, Ko = {
|
|
2783
3932
|
color: "#536fec",
|
|
2784
3933
|
fontWeight: "bold",
|
|
2785
3934
|
textDecoration: "underline",
|
|
2786
3935
|
cursor: "pointer",
|
|
2787
3936
|
padding: "0 3px"
|
|
2788
|
-
},
|
|
2789
|
-
const t = /#router:([^#]+)#/g,
|
|
2790
|
-
let
|
|
2791
|
-
for (; (
|
|
2792
|
-
|
|
2793
|
-
const
|
|
2794
|
-
|
|
2795
|
-
}
|
|
2796
|
-
return
|
|
2797
|
-
},
|
|
2798
|
-
const { onRouteClick:
|
|
3937
|
+
}, Yo = (e) => {
|
|
3938
|
+
const t = /#router:([^#]+)#/g, n = [];
|
|
3939
|
+
let s = 0, r;
|
|
3940
|
+
for (; (r = t.exec(e)) !== null; ) {
|
|
3941
|
+
r.index > s && n.push({ text: e.substring(s, r.index) });
|
|
3942
|
+
const o = r[1], { routeName: a, queryParams: i } = Jo(o);
|
|
3943
|
+
n.push({ text: a, routeName: a, queryParams: i }), s = t.lastIndex;
|
|
3944
|
+
}
|
|
3945
|
+
return s < e.length && n.push({ text: e.substring(s) }), n;
|
|
3946
|
+
}, Xo = (e, t, n = {}, s) => {
|
|
3947
|
+
const { onRouteClick: r = Go, linkStyle: o = {} } = n, a = document.createElement("a");
|
|
2799
3948
|
a.href = "#", a.textContent = e;
|
|
2800
|
-
const i = { ...
|
|
3949
|
+
const i = { ...Ko, ...o };
|
|
2801
3950
|
return Object.assign(a.style, i), a.addEventListener("click", (l) => {
|
|
2802
|
-
l.preventDefault(),
|
|
3951
|
+
l.preventDefault(), r(t, s);
|
|
2803
3952
|
}), a;
|
|
2804
|
-
},
|
|
2805
|
-
const t = /#router:([^#]+)#/g,
|
|
3953
|
+
}, Zo = (e) => {
|
|
3954
|
+
const t = /#router:([^#]+)#/g, n = [], s = document.createTreeWalker(
|
|
2806
3955
|
e,
|
|
2807
3956
|
NodeFilter.SHOW_TEXT,
|
|
2808
3957
|
null
|
|
2809
3958
|
);
|
|
2810
|
-
let
|
|
2811
|
-
for (;
|
|
2812
|
-
const
|
|
3959
|
+
let r = s.nextNode();
|
|
3960
|
+
for (; r; ) {
|
|
3961
|
+
const o = r, a = o.textContent || "";
|
|
2813
3962
|
if (t.test(a)) {
|
|
2814
3963
|
t.lastIndex = 0;
|
|
2815
|
-
const i =
|
|
2816
|
-
i.length > 0 &&
|
|
3964
|
+
const i = Yo(a);
|
|
3965
|
+
i.length > 0 && n.push({ node: o, replacements: i });
|
|
2817
3966
|
}
|
|
2818
|
-
|
|
3967
|
+
r = s.nextNode();
|
|
2819
3968
|
}
|
|
2820
|
-
return
|
|
2821
|
-
},
|
|
2822
|
-
const
|
|
2823
|
-
|
|
3969
|
+
return n;
|
|
3970
|
+
}, rr = (e, t, n = {}) => {
|
|
3971
|
+
const s = Zo(e);
|
|
3972
|
+
s.forEach(({ node: r, replacements: o }) => {
|
|
2824
3973
|
var i;
|
|
2825
3974
|
const a = document.createDocumentFragment();
|
|
2826
|
-
|
|
3975
|
+
o.forEach(({ text: l, routeName: c, queryParams: d }) => {
|
|
2827
3976
|
if (c) {
|
|
2828
|
-
const P =
|
|
3977
|
+
const P = Xo(l, c, n, d);
|
|
2829
3978
|
a.appendChild(P);
|
|
2830
3979
|
} else
|
|
2831
3980
|
a.appendChild(document.createTextNode(l));
|
|
2832
|
-
}), (i =
|
|
2833
|
-
}),
|
|
3981
|
+
}), (i = r.parentNode) == null || i.replaceChild(a, r);
|
|
3982
|
+
}), n != null && n.nodeCallback && s.forEach(({ node: r, replacements: o }) => {
|
|
2834
3983
|
var a;
|
|
2835
|
-
(a =
|
|
3984
|
+
(a = n.nodeCallback) == null || a.call(n, r, o);
|
|
2836
3985
|
});
|
|
2837
|
-
},
|
|
2838
|
-
function
|
|
3986
|
+
}, $e = "szjy-voice-models", He = "szjy-voice-cache-v1";
|
|
3987
|
+
function Oe() {
|
|
2839
3988
|
return typeof navigator < "u" && !!navigator.storage && typeof navigator.storage.getDirectory == "function";
|
|
2840
3989
|
}
|
|
2841
|
-
async function
|
|
2842
|
-
if (!
|
|
3990
|
+
async function st(e = $e) {
|
|
3991
|
+
if (!Oe()) return null;
|
|
2843
3992
|
try {
|
|
2844
3993
|
return await (await navigator.storage.getDirectory()).getDirectoryHandle(e, { create: !0 });
|
|
2845
3994
|
} catch (t) {
|
|
2846
3995
|
return console.warn("[OPFS] 获取目录失败,将使用降级缓存:", t), null;
|
|
2847
3996
|
}
|
|
2848
3997
|
}
|
|
2849
|
-
async function
|
|
2850
|
-
if (
|
|
3998
|
+
async function ar(e, t, n = $e) {
|
|
3999
|
+
if (Oe())
|
|
2851
4000
|
try {
|
|
2852
|
-
const
|
|
2853
|
-
if (
|
|
2854
|
-
const
|
|
2855
|
-
return await
|
|
4001
|
+
const s = await st(n);
|
|
4002
|
+
if (s) {
|
|
4003
|
+
const o = await (await s.getFileHandle(e, { create: !0 })).createWritable();
|
|
4004
|
+
return await o.write(t), await o.close(), !0;
|
|
2856
4005
|
}
|
|
2857
|
-
} catch (
|
|
2858
|
-
console.warn(`[OPFS] 写入文件 ${e} 失败:`,
|
|
4006
|
+
} catch (s) {
|
|
4007
|
+
console.warn(`[OPFS] 写入文件 ${e} 失败:`, s);
|
|
2859
4008
|
}
|
|
2860
4009
|
if (typeof caches < "u")
|
|
2861
4010
|
try {
|
|
2862
|
-
const
|
|
4011
|
+
const s = await caches.open(He), r = new Response(t, {
|
|
2863
4012
|
headers: { "Content-Type": "application/octet-stream" }
|
|
2864
4013
|
});
|
|
2865
|
-
return await
|
|
2866
|
-
} catch (
|
|
2867
|
-
console.warn(`[CacheStorage] 缓存写入 ${e} 失败:`,
|
|
4014
|
+
return await s.put(`/${n}/${e}`, r), !0;
|
|
4015
|
+
} catch (s) {
|
|
4016
|
+
console.warn(`[CacheStorage] 缓存写入 ${e} 失败:`, s);
|
|
2868
4017
|
}
|
|
2869
4018
|
return !1;
|
|
2870
4019
|
}
|
|
2871
|
-
async function
|
|
2872
|
-
if (
|
|
4020
|
+
async function ir(e, t = $e) {
|
|
4021
|
+
if (Oe())
|
|
2873
4022
|
try {
|
|
2874
|
-
const
|
|
2875
|
-
if (
|
|
2876
|
-
return await (await (await
|
|
4023
|
+
const n = await st(t);
|
|
4024
|
+
if (n)
|
|
4025
|
+
return await (await (await n.getFileHandle(e, { create: !1 })).getFile()).arrayBuffer();
|
|
2877
4026
|
} catch {
|
|
2878
4027
|
}
|
|
2879
4028
|
if (typeof caches < "u")
|
|
2880
4029
|
try {
|
|
2881
|
-
const
|
|
2882
|
-
if (
|
|
2883
|
-
return await
|
|
4030
|
+
const s = await (await caches.open(He)).match(`/${t}/${e}`);
|
|
4031
|
+
if (s)
|
|
4032
|
+
return await s.arrayBuffer();
|
|
2884
4033
|
} catch {
|
|
2885
4034
|
}
|
|
2886
4035
|
return null;
|
|
2887
4036
|
}
|
|
2888
|
-
async function
|
|
2889
|
-
if (
|
|
4037
|
+
async function lr(e, t = $e) {
|
|
4038
|
+
if (Oe())
|
|
2890
4039
|
try {
|
|
2891
|
-
const
|
|
2892
|
-
if (
|
|
2893
|
-
return (await (await
|
|
4040
|
+
const n = await st(t);
|
|
4041
|
+
if (n)
|
|
4042
|
+
return (await (await n.getFileHandle(e, { create: !1 })).getFile()).size > 0;
|
|
2894
4043
|
} catch {
|
|
2895
4044
|
}
|
|
2896
4045
|
if (typeof caches < "u")
|
|
2897
4046
|
try {
|
|
2898
|
-
return !!await (await caches.open(
|
|
4047
|
+
return !!await (await caches.open(He)).match(`/${t}/${e}`);
|
|
2899
4048
|
} catch {
|
|
2900
4049
|
}
|
|
2901
4050
|
return !1;
|
|
2902
4051
|
}
|
|
2903
|
-
async function
|
|
4052
|
+
async function cr(e = $e) {
|
|
2904
4053
|
let t = !1;
|
|
2905
|
-
if (
|
|
4054
|
+
if (Oe())
|
|
2906
4055
|
try {
|
|
2907
4056
|
await (await navigator.storage.getDirectory()).removeEntry(e, { recursive: !0 }), t = !0, console.log(`[OPFS] 成功清空语音模型缓存目录: ${e}`);
|
|
2908
|
-
} catch (
|
|
2909
|
-
|
|
4057
|
+
} catch (n) {
|
|
4058
|
+
n.name === "NotFoundError" ? t = !0 : console.warn(`[OPFS] 清理目录 ${e} 异常:`, n);
|
|
2910
4059
|
}
|
|
2911
4060
|
if (typeof caches < "u")
|
|
2912
4061
|
try {
|
|
2913
|
-
const
|
|
2914
|
-
for (const
|
|
2915
|
-
(
|
|
2916
|
-
} catch (
|
|
2917
|
-
console.warn("[CacheStorage] 清除缓存异常:",
|
|
4062
|
+
const n = await caches.keys();
|
|
4063
|
+
for (const s of n)
|
|
4064
|
+
(s.includes("transformers") || s.includes("szjy-voice") || s === He) && (await caches.delete(s), t = !0);
|
|
4065
|
+
} catch (n) {
|
|
4066
|
+
console.warn("[CacheStorage] 清除缓存异常:", n);
|
|
2918
4067
|
}
|
|
2919
4068
|
return t;
|
|
2920
4069
|
}
|
|
2921
|
-
const
|
|
2922
|
-
function
|
|
2923
|
-
componentPrefix: e =
|
|
4070
|
+
const Qo = "0.1.17", er = "Sz";
|
|
4071
|
+
function ur({
|
|
4072
|
+
componentPrefix: e = er,
|
|
2924
4073
|
components: t = []
|
|
2925
4074
|
} = {}) {
|
|
2926
|
-
const
|
|
2927
|
-
function
|
|
2928
|
-
|
|
4075
|
+
const n = [];
|
|
4076
|
+
function s(o, a, i) {
|
|
4077
|
+
o.component(e + a) || o.component(
|
|
2929
4078
|
e + a,
|
|
2930
4079
|
i
|
|
2931
4080
|
);
|
|
2932
4081
|
}
|
|
2933
|
-
function o
|
|
2934
|
-
|
|
4082
|
+
function r(o) {
|
|
4083
|
+
n.includes(o) || (n.push(o), t.forEach((a) => {
|
|
2935
4084
|
const { name: i, alias: l } = a;
|
|
2936
|
-
|
|
2937
|
-
|
|
4085
|
+
s(o, i, a), l && l.forEach((c) => {
|
|
4086
|
+
s(o, c, a);
|
|
2938
4087
|
});
|
|
2939
4088
|
}));
|
|
2940
4089
|
}
|
|
2941
4090
|
return {
|
|
2942
|
-
version:
|
|
4091
|
+
version: Qo,
|
|
2943
4092
|
componentPrefix: e,
|
|
2944
|
-
install:
|
|
4093
|
+
install: r
|
|
2945
4094
|
};
|
|
2946
4095
|
}
|
|
2947
|
-
const
|
|
4096
|
+
const dr = {
|
|
2948
4097
|
install(e) {
|
|
2949
|
-
|
|
4098
|
+
Qe(e);
|
|
2950
4099
|
}
|
|
2951
4100
|
};
|
|
2952
4101
|
export {
|
|
2953
|
-
|
|
2954
|
-
|
|
2955
|
-
|
|
2956
|
-
|
|
2957
|
-
|
|
2958
|
-
|
|
2959
|
-
|
|
2960
|
-
|
|
2961
|
-
|
|
2962
|
-
|
|
2963
|
-
|
|
2964
|
-
|
|
2965
|
-
|
|
2966
|
-
|
|
2967
|
-
|
|
2968
|
-
|
|
2969
|
-
|
|
2970
|
-
|
|
2971
|
-
|
|
2972
|
-
|
|
2973
|
-
|
|
2974
|
-
|
|
2975
|
-
|
|
2976
|
-
|
|
2977
|
-
|
|
2978
|
-
|
|
2979
|
-
|
|
2980
|
-
|
|
2981
|
-
|
|
2982
|
-
|
|
2983
|
-
|
|
2984
|
-
|
|
2985
|
-
|
|
2986
|
-
|
|
2987
|
-
|
|
2988
|
-
|
|
2989
|
-
|
|
4102
|
+
sr as AEC_DEFAULTS,
|
|
4103
|
+
fs as AudioRecorder,
|
|
4104
|
+
gt as BUFFER_SIZE,
|
|
4105
|
+
Ls as CANCEL_DRAG_PX,
|
|
4106
|
+
nt as DEFAULT_BASE_PATH,
|
|
4107
|
+
gn as DEFAULT_MOCK_RESPONSE,
|
|
4108
|
+
Ut as DEFAULT_WHISPER_WORKER_URL,
|
|
4109
|
+
pt as ENERGY_THRESHOLD,
|
|
4110
|
+
zt as EqualizerBars,
|
|
4111
|
+
Rs as HOLD_THRESHOLD_MS,
|
|
4112
|
+
Es as KEY_HOLD_THRESHOLD_MS,
|
|
4113
|
+
bs as LEVEL_CEILING,
|
|
4114
|
+
mt as MAX_SEGMENT_MS,
|
|
4115
|
+
Cs as MIN_HOLD_SEGMENT_S,
|
|
4116
|
+
js as NlmsAec,
|
|
4117
|
+
As as PARTIAL_INTERVAL_MS,
|
|
4118
|
+
xs as PARTIAL_MAX_S,
|
|
4119
|
+
Ts as PARTIAL_MIN_S,
|
|
4120
|
+
vt as POST_PAD_MS,
|
|
4121
|
+
Ss as PRE_PAD_MS,
|
|
4122
|
+
xe as SAMPLE_RATE,
|
|
4123
|
+
ks as SILENCE_TIMEOUT_MS,
|
|
4124
|
+
Yn as SZJY_UI_FENCE_LANG,
|
|
4125
|
+
ds as StreamResampler,
|
|
4126
|
+
Do as SzAiChat,
|
|
4127
|
+
Wo as SzAiChatPlain,
|
|
4128
|
+
jt as VOICE_CONTEXT_KEY,
|
|
4129
|
+
to as VoiceCaptionBar,
|
|
4130
|
+
ws as VoiceInputManager,
|
|
4131
|
+
Qs as VoiceMicButton,
|
|
4132
|
+
Gs as VoiceOverlay,
|
|
4133
|
+
Mt as WAVE_BARS,
|
|
4134
|
+
Qn as bindSzjyUiEvents,
|
|
4135
|
+
cr as clearVoiceModelCache,
|
|
4136
|
+
ur as create,
|
|
4137
|
+
Os as createAsrEngine,
|
|
4138
|
+
Sn as createMockStylized,
|
|
4139
|
+
Vs as createPlaybackEngine,
|
|
4140
|
+
Xo as createRouteLink,
|
|
4141
|
+
ps as decodeAudioFile,
|
|
4142
|
+
dr as default,
|
|
4143
|
+
Ie as escapeHtml,
|
|
4144
|
+
Zo as findRouteTextNodes,
|
|
4145
|
+
ft as float32ToWav,
|
|
4146
|
+
zs as getConfig,
|
|
4147
|
+
ir as getFileFromCache,
|
|
4148
|
+
st as getOPFSDirectory,
|
|
4149
|
+
Is as getReady,
|
|
4150
|
+
Pn as getSzjyUiAction,
|
|
4151
|
+
En as getSzjyUiComponent,
|
|
4152
|
+
lr as hasFileInCache,
|
|
4153
|
+
Un as hasSzjyUiAction,
|
|
4154
|
+
Ln as hasSzjyUiComponent,
|
|
4155
|
+
Oe as isOPFSSupported,
|
|
4156
|
+
Bs as micErrorMessage,
|
|
4157
|
+
$s as openAudioStream,
|
|
4158
|
+
Jo as parseRouteMarkerContent,
|
|
4159
|
+
Yo as parseRouteMarkers,
|
|
4160
|
+
Xn as parseSzjyUiFence,
|
|
4161
|
+
or as postAsr,
|
|
4162
|
+
yt as postCancel,
|
|
4163
|
+
Rn as registerSzjyUiAction,
|
|
4164
|
+
Tt as registerSzjyUiComponent,
|
|
4165
|
+
jn as renderActionAttrs,
|
|
4166
|
+
_n as renderSzjyUiBlock,
|
|
4167
|
+
xt as renderSzjyUiNode,
|
|
4168
|
+
hs as resampleAudioData,
|
|
4169
|
+
rr as routeLinkRender,
|
|
4170
|
+
ar as saveFileToCache,
|
|
4171
|
+
Ds as useVoice,
|
|
4172
|
+
It as useVoiceContext
|
|
2990
4173
|
};
|