@streamoji/avatar-widget 0.2.6 → 0.2.8
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/avatar-widget.cjs +5 -5
- package/dist/avatar-widget.cjs.map +1 -1
- package/dist/avatar-widget.css +1 -1
- package/dist/avatar-widget.js +637 -621
- package/dist/avatar-widget.js.map +1 -1
- package/dist/avatar-widget.umd.js +41 -41
- package/dist/avatar-widget.umd.js.map +1 -1
- package/package.json +1 -1
package/dist/avatar-widget.js
CHANGED
|
@@ -1,100 +1,100 @@
|
|
|
1
|
-
import { jsx as l, jsxs as
|
|
2
|
-
import { useGLTF as
|
|
3
|
-
import { useFrame as
|
|
4
|
-
import { memo as
|
|
1
|
+
import { jsx as l, jsxs as ae } from "react/jsx-runtime";
|
|
2
|
+
import { useGLTF as lt, Environment as Yt } from "@react-three/drei";
|
|
3
|
+
import { useFrame as Qt, Canvas as Xt, useThree as Kt } from "@react-three/fiber";
|
|
4
|
+
import { memo as Zt, useMemo as ft, useRef as a, useState as g, useEffect as $, useCallback as Ye, useLayoutEffect as en, Suspense as tn } from "react";
|
|
5
5
|
import * as Ve from "three";
|
|
6
|
-
import { GLTFLoader as
|
|
7
|
-
const
|
|
8
|
-
},
|
|
9
|
-
},
|
|
10
|
-
const
|
|
11
|
-
return
|
|
12
|
-
const
|
|
13
|
-
if (!
|
|
14
|
-
const
|
|
15
|
-
if (!
|
|
16
|
-
let
|
|
17
|
-
f && (f.fftSize = 128,
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
const
|
|
21
|
-
if (
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
const
|
|
25
|
-
(!w.current || w.current.length !==
|
|
26
|
-
const
|
|
27
|
-
f &&
|
|
28
|
-
const
|
|
29
|
-
for (let
|
|
30
|
-
let
|
|
31
|
-
if (
|
|
32
|
-
const
|
|
33
|
-
for (let
|
|
34
|
-
const
|
|
35
|
-
|
|
6
|
+
import { GLTFLoader as nn } from "three/examples/jsm/loaders/GLTFLoader.js";
|
|
7
|
+
const ut = "https://ai.streamoji.com", V = (...f) => {
|
|
8
|
+
}, rn = (...f) => {
|
|
9
|
+
}, Et = ({ analyser: f }) => {
|
|
10
|
+
const T = a(null), w = a(null);
|
|
11
|
+
return $(() => {
|
|
12
|
+
const p = T.current;
|
|
13
|
+
if (!p) return;
|
|
14
|
+
const b = p.getContext("2d", { alpha: !0 });
|
|
15
|
+
if (!b) return;
|
|
16
|
+
let O, H = null;
|
|
17
|
+
f && (f.fftSize = 128, H = new Uint8Array(f.frequencyBinCount));
|
|
18
|
+
const he = () => {
|
|
19
|
+
O = requestAnimationFrame(he), (p.width !== p.offsetWidth || p.height !== p.offsetHeight) && (p.width = p.offsetWidth, p.height = p.offsetHeight);
|
|
20
|
+
const X = p.width, D = p.height;
|
|
21
|
+
if (X === 0 || D === 0) return;
|
|
22
|
+
const me = D / 2;
|
|
23
|
+
b.clearRect(0, 0, X, D), b.fillStyle = "#1e293b";
|
|
24
|
+
const I = 2, k = I + 2, E = X * 0.95, U = Math.floor(E / k);
|
|
25
|
+
(!w.current || w.current.length !== U) && (w.current = new Float32Array(U).fill(2));
|
|
26
|
+
const be = U * k, y = (X - be) / 2;
|
|
27
|
+
f && H && f.getByteFrequencyData(H);
|
|
28
|
+
const Ie = H ? H.length : 0, G = Math.floor(Ie * 0.7) / U, ce = new Float32Array(U);
|
|
29
|
+
for (let M = 0; M < U; M++) {
|
|
30
|
+
let B = 0;
|
|
31
|
+
if (H && G > 0) {
|
|
32
|
+
const ne = Math.floor(M * G), P = Math.floor((M + 1) * G);
|
|
33
|
+
for (let S = ne; S < P; S++) {
|
|
34
|
+
const x = H[S] || 0;
|
|
35
|
+
x > B && (B = x);
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
|
-
|
|
39
|
-
const
|
|
40
|
-
|
|
38
|
+
B < 10 && (B = 0);
|
|
39
|
+
const j = B / 255, N = B > 0 ? Math.max(2, Math.pow(j, 1.4) * D * 0.25) : 2;
|
|
40
|
+
ce[M] = N;
|
|
41
41
|
}
|
|
42
|
-
for (let
|
|
43
|
-
const
|
|
44
|
-
w.current[
|
|
45
|
-
const
|
|
46
|
-
|
|
42
|
+
for (let M = 0; M < U; M++) {
|
|
43
|
+
const B = U - 1 - M, j = Math.max(ce[M], ce[B]), N = w.current[M] + (j - w.current[M]) * 0.3;
|
|
44
|
+
w.current[M] = N;
|
|
45
|
+
const ne = y + M * k, P = me - N / 2;
|
|
46
|
+
b.beginPath(), b.roundRect ? b.roundRect(ne, P, I, N, 4) : b.fillRect(ne, P, I, N), b.fill();
|
|
47
47
|
}
|
|
48
48
|
};
|
|
49
|
-
return
|
|
50
|
-
cancelAnimationFrame(
|
|
49
|
+
return he(), () => {
|
|
50
|
+
cancelAnimationFrame(O);
|
|
51
51
|
};
|
|
52
52
|
}, [f]), /* @__PURE__ */ l(
|
|
53
53
|
"canvas",
|
|
54
54
|
{
|
|
55
|
-
ref:
|
|
55
|
+
ref: T,
|
|
56
56
|
style: { width: "100%", height: "100%", display: "block" }
|
|
57
57
|
}
|
|
58
58
|
);
|
|
59
|
-
},
|
|
60
|
-
async function
|
|
61
|
-
const
|
|
59
|
+
}, sn = "https://pub-48df6f7d60d6440bbd01676ea5d90e55.r2.dev", It = "https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/default-models/fullbodyavatarmale.glb";
|
|
60
|
+
async function on(f) {
|
|
61
|
+
const T = await crypto.subtle.digest(
|
|
62
62
|
"SHA-256",
|
|
63
63
|
new TextEncoder().encode(f)
|
|
64
64
|
);
|
|
65
|
-
return Array.from(new Uint8Array(
|
|
65
|
+
return Array.from(new Uint8Array(T)).map((w) => w.toString(16).padStart(2, "0")).join("");
|
|
66
66
|
}
|
|
67
|
-
function
|
|
68
|
-
const [
|
|
69
|
-
return
|
|
67
|
+
function an(f) {
|
|
68
|
+
const [T, w] = g(null);
|
|
69
|
+
return $(() => {
|
|
70
70
|
if (!f) {
|
|
71
71
|
w(null);
|
|
72
72
|
return;
|
|
73
73
|
}
|
|
74
|
-
let
|
|
75
|
-
return
|
|
76
|
-
if (
|
|
77
|
-
const
|
|
78
|
-
fetch(
|
|
79
|
-
|
|
74
|
+
let p = !1;
|
|
75
|
+
return on(f).then((b) => {
|
|
76
|
+
if (p) return;
|
|
77
|
+
const O = `${sn}/${b}.glb`;
|
|
78
|
+
fetch(O, { method: "HEAD" }).then((H) => {
|
|
79
|
+
p || w(H.ok ? O : It);
|
|
80
80
|
}).catch(() => {
|
|
81
|
-
|
|
81
|
+
p || w(It);
|
|
82
82
|
});
|
|
83
83
|
}), () => {
|
|
84
|
-
|
|
84
|
+
p = !0;
|
|
85
85
|
};
|
|
86
|
-
}, [f]),
|
|
86
|
+
}, [f]), T;
|
|
87
87
|
}
|
|
88
|
-
const
|
|
88
|
+
const cn = [
|
|
89
89
|
"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/idle/M_Standing_Idle_Variations_001.glb",
|
|
90
90
|
"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/idle/M_Standing_Idle_Variations_002.glb",
|
|
91
91
|
"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/idle/M_Standing_Idle_002.glb",
|
|
92
92
|
"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/idle/M_Standing_Idle_Variations_005.glb"
|
|
93
|
-
],
|
|
93
|
+
], ln = [
|
|
94
94
|
"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/idle/F_Standing_Idle_Variations_001.glb",
|
|
95
95
|
"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/idle/F_Standing_Idle_Variations_003.glb",
|
|
96
96
|
"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/idle/F_Standing_Idle_Variations_003.glb"
|
|
97
|
-
],
|
|
97
|
+
], un = [
|
|
98
98
|
{
|
|
99
99
|
id: "m_expr_01",
|
|
100
100
|
name: "Friendly Wave",
|
|
@@ -260,17 +260,17 @@ const an = [
|
|
|
260
260
|
name: "Take It Easy",
|
|
261
261
|
url: "https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/F_Talking_Variations_006.glb"
|
|
262
262
|
}
|
|
263
|
-
],
|
|
263
|
+
], dn = [
|
|
264
264
|
"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Talking_Variations_005.glb",
|
|
265
265
|
"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Talking_Variations_007.glb"
|
|
266
|
-
],
|
|
266
|
+
], fn = {
|
|
267
267
|
zoom: 0.85,
|
|
268
268
|
position: [0.15, -0.8, 0],
|
|
269
269
|
scale: 1.5,
|
|
270
270
|
rotation: [0.15, 0.02, 0]
|
|
271
|
-
},
|
|
271
|
+
}, hn = [-0.45, 1.9, 0.1], mn = {
|
|
272
272
|
browInnerUp: 0.2
|
|
273
|
-
},
|
|
273
|
+
}, dt = 0.18, pn = 1, Mt = "__branding__", Qe = {
|
|
274
274
|
neutral: { eyeLookDownLeft: 0.1, eyeLookDownRight: 0.1 },
|
|
275
275
|
happy: {
|
|
276
276
|
mouthSmileLeft: 0.2,
|
|
@@ -352,7 +352,7 @@ const an = [
|
|
|
352
352
|
mouthUpperUpLeft: 0.1,
|
|
353
353
|
mouthUpperUpRight: 0.1
|
|
354
354
|
}
|
|
355
|
-
},
|
|
355
|
+
}, gn = [
|
|
356
356
|
{ key: "viseme_aa", mix: { jawOpen: 0.6 } },
|
|
357
357
|
{
|
|
358
358
|
key: "viseme_E",
|
|
@@ -448,7 +448,7 @@ const an = [
|
|
|
448
448
|
}
|
|
449
449
|
},
|
|
450
450
|
{ key: "viseme_sil", mix: {} }
|
|
451
|
-
],
|
|
451
|
+
], bn = {
|
|
452
452
|
aei: [
|
|
453
453
|
{ v: "E", w: 0.8 },
|
|
454
454
|
{ v: "I", w: 0.2 }
|
|
@@ -477,331 +477,336 @@ const an = [
|
|
|
477
477
|
],
|
|
478
478
|
sil: [{ v: "sil", w: 1 }]
|
|
479
479
|
};
|
|
480
|
-
function
|
|
480
|
+
function _n(f) {
|
|
481
481
|
if (!f) return [{ v: "sil", w: 1 }];
|
|
482
|
-
const
|
|
483
|
-
return
|
|
482
|
+
const T = f.toLowerCase();
|
|
483
|
+
return bn[T] ?? [{ v: "sil", w: 1 }];
|
|
484
484
|
}
|
|
485
|
-
function
|
|
486
|
-
const { camera:
|
|
487
|
-
return
|
|
488
|
-
|
|
489
|
-
}, [
|
|
485
|
+
function wn({ target: f }) {
|
|
486
|
+
const { camera: T } = Kt();
|
|
487
|
+
return $(() => {
|
|
488
|
+
T.lookAt(...f);
|
|
489
|
+
}, [T, f]), null;
|
|
490
490
|
}
|
|
491
|
-
function
|
|
491
|
+
function Q(f, T, w) {
|
|
492
492
|
if (!f || !f.morphTargetDictionary)
|
|
493
493
|
return;
|
|
494
|
-
const
|
|
495
|
-
if (
|
|
496
|
-
for (const
|
|
497
|
-
|
|
494
|
+
const p = f, b = p.morphTargetDictionary, O = p.morphTargetInfluences;
|
|
495
|
+
if (O)
|
|
496
|
+
for (const H in b)
|
|
497
|
+
H.toLowerCase() === T.toLowerCase() && (O[b[H]] = w);
|
|
498
498
|
}
|
|
499
|
-
function
|
|
499
|
+
function Ct(f, T = 0.97) {
|
|
500
500
|
if (!f) return;
|
|
501
501
|
const w = f;
|
|
502
502
|
if (w.morphTargetInfluences)
|
|
503
|
-
for (let
|
|
504
|
-
w.morphTargetInfluences[
|
|
503
|
+
for (let p = 0; p < w.morphTargetInfluences.length; p++)
|
|
504
|
+
w.morphTargetInfluences[p] *= T;
|
|
505
505
|
}
|
|
506
|
-
const
|
|
506
|
+
const vn = Zt(
|
|
507
507
|
({
|
|
508
508
|
avatarUrl: f,
|
|
509
|
-
isPlayingRef:
|
|
509
|
+
isPlayingRef: T,
|
|
510
510
|
visemeQueueRef: w,
|
|
511
|
-
audioContextRef:
|
|
512
|
-
responseAudioStartTimeRef:
|
|
513
|
-
adjustments:
|
|
514
|
-
mood:
|
|
515
|
-
expression:
|
|
516
|
-
agentResponse:
|
|
517
|
-
isSpeaking:
|
|
518
|
-
nextStartTimeRef:
|
|
519
|
-
stopPlayback:
|
|
520
|
-
setIsSpeaking:
|
|
521
|
-
expressionUrl:
|
|
522
|
-
onExpressionFinished:
|
|
523
|
-
isNudgeResponse:
|
|
524
|
-
avatarGender:
|
|
511
|
+
audioContextRef: p,
|
|
512
|
+
responseAudioStartTimeRef: b,
|
|
513
|
+
adjustments: O,
|
|
514
|
+
mood: H,
|
|
515
|
+
expression: he,
|
|
516
|
+
agentResponse: X,
|
|
517
|
+
isSpeaking: D,
|
|
518
|
+
nextStartTimeRef: me,
|
|
519
|
+
stopPlayback: I,
|
|
520
|
+
setIsSpeaking: v,
|
|
521
|
+
expressionUrl: k,
|
|
522
|
+
onExpressionFinished: E,
|
|
523
|
+
isNudgeResponse: U,
|
|
524
|
+
avatarGender: be
|
|
525
525
|
}) => {
|
|
526
|
-
const { scene:
|
|
527
|
-
() =>
|
|
528
|
-
[
|
|
529
|
-
),
|
|
530
|
-
() =>
|
|
531
|
-
[
|
|
532
|
-
),
|
|
533
|
-
|
|
534
|
-
if (!(!
|
|
535
|
-
if (
|
|
536
|
-
const
|
|
537
|
-
if (!
|
|
538
|
-
const r =
|
|
539
|
-
r.name =
|
|
526
|
+
const { scene: y } = lt(f), Ne = lt(be === "female" ? ln : cn), G = ft(
|
|
527
|
+
() => Ne.flatMap((u) => u.animations),
|
|
528
|
+
[Ne]
|
|
529
|
+
), ce = lt(dn), M = ft(
|
|
530
|
+
() => ce.flatMap((u) => u.animations),
|
|
531
|
+
[ce]
|
|
532
|
+
), B = a(null), j = a(null), N = a(null), ne = a([]), [P] = g(() => new Ve.AnimationMixer(y)), S = a({}), x = a(null), ye = a(0), le = a(!1), $e = a(0), re = a(null);
|
|
533
|
+
$(() => {
|
|
534
|
+
if (!(!G || !y)) {
|
|
535
|
+
if (G.forEach((u, d) => {
|
|
536
|
+
const s = `idle_${d}`;
|
|
537
|
+
if (!S.current[s]) {
|
|
538
|
+
const r = P.clipAction(u, y);
|
|
539
|
+
r.name = s, r.setLoop(Ve.LoopOnce, 1), r.clampWhenFinished = !0, S.current[s] = r;
|
|
540
540
|
}
|
|
541
|
-
}),
|
|
542
|
-
const
|
|
543
|
-
if (!
|
|
544
|
-
const r =
|
|
545
|
-
r.name =
|
|
541
|
+
}), M.forEach((u, d) => {
|
|
542
|
+
const s = `talk_${d}`;
|
|
543
|
+
if (!S.current[s]) {
|
|
544
|
+
const r = P.clipAction(u, y);
|
|
545
|
+
r.name = s, r.setLoop(Ve.LoopOnce, 1), r.clampWhenFinished = !0, S.current[s] = r;
|
|
546
546
|
}
|
|
547
|
-
}),
|
|
548
|
-
const
|
|
549
|
-
|
|
547
|
+
}), G.length > 0) {
|
|
548
|
+
const u = S.current.idle_0, d = x.current && P.existingAction(x.current.getClip());
|
|
549
|
+
u && !d && (u.reset().fadeIn(0.5).play(), x.current = u);
|
|
550
550
|
}
|
|
551
551
|
return () => {
|
|
552
|
-
|
|
552
|
+
P.stopAllAction(), S.current = {}, x.current = null;
|
|
553
553
|
};
|
|
554
554
|
}
|
|
555
|
-
}, [
|
|
556
|
-
const
|
|
557
|
-
|
|
558
|
-
if (!
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
(
|
|
562
|
-
if (
|
|
563
|
-
const
|
|
564
|
-
if (r.name = `EXPR_${
|
|
565
|
-
const
|
|
566
|
-
r.reset().fadeIn(0.3).play(),
|
|
555
|
+
}, [G, M, y, P]);
|
|
556
|
+
const Se = a("");
|
|
557
|
+
$(() => {
|
|
558
|
+
if (!k || !y || k === Se.current) return;
|
|
559
|
+
Se.current = k, re.current = k, new nn().load(
|
|
560
|
+
k,
|
|
561
|
+
(d) => {
|
|
562
|
+
if (d.animations && d.animations.length > 0) {
|
|
563
|
+
const s = d.animations[0], r = P.clipAction(s, y);
|
|
564
|
+
if (r.name = `EXPR_${k}`, r.setLoop(Ve.LoopOnce, 1), r.clampWhenFinished = !0, S.current[`EXPR_${k}`] = r, D && re.current === k) {
|
|
565
|
+
const m = x.current;
|
|
566
|
+
r.reset().fadeIn(0.3).play(), m && m !== r && m.crossFadeTo(r, 0.3, !0), x.current = r, re.current = null;
|
|
567
567
|
}
|
|
568
568
|
}
|
|
569
569
|
},
|
|
570
570
|
void 0,
|
|
571
|
-
(
|
|
572
|
-
console.error(`[ANIMATION] Failed to load ${
|
|
571
|
+
(d) => {
|
|
572
|
+
console.error(`[ANIMATION] Failed to load ${k}`, d);
|
|
573
573
|
}
|
|
574
574
|
);
|
|
575
|
-
}, [
|
|
576
|
-
const
|
|
577
|
-
const
|
|
575
|
+
}, [k, y, P, D]), $(() => {
|
|
576
|
+
const u = (d) => {
|
|
577
|
+
const s = d.action, r = s.name || "";
|
|
578
578
|
if (r.startsWith("idle_")) {
|
|
579
|
-
const
|
|
580
|
-
|
|
579
|
+
const z = (parseInt(r.split("_")[1]) + 1) % G.length, K = S.current[`idle_${z}`];
|
|
580
|
+
K && (K.reset().fadeIn(0.5).play(), s.crossFadeTo(K, 0.5, !0), x.current = K);
|
|
581
581
|
} else if (r.startsWith("EXPR_")) {
|
|
582
|
-
if (
|
|
583
|
-
const
|
|
584
|
-
|
|
582
|
+
if (D) {
|
|
583
|
+
const m = S.current.talk_0;
|
|
584
|
+
m && (m.reset().fadeIn(0.5).play(), s.crossFadeTo(m, 0.5, !0), x.current = m);
|
|
585
585
|
} else {
|
|
586
|
-
const
|
|
587
|
-
|
|
586
|
+
const m = S.current.idle_0;
|
|
587
|
+
m && (m.reset().fadeIn(0.5).play(), s.crossFadeTo(m, 0.5, !0), x.current = m);
|
|
588
588
|
}
|
|
589
|
-
|
|
589
|
+
E && E();
|
|
590
590
|
} else if (r.startsWith("talk_"))
|
|
591
|
-
if (
|
|
592
|
-
const
|
|
593
|
-
|
|
591
|
+
if (D && !U) {
|
|
592
|
+
const z = (parseInt(r.split("_")[1]) + 1) % M.length, K = S.current[`talk_${z}`];
|
|
593
|
+
K && (K.reset().fadeIn(0.3).play(), s.crossFadeTo(K, 0.3, !0), x.current = K);
|
|
594
594
|
} else {
|
|
595
|
-
const
|
|
596
|
-
|
|
595
|
+
const m = S.current.idle_0;
|
|
596
|
+
m && (m.reset().fadeIn(0.5).play(), s.crossFadeTo(m, 0.5, !0), x.current = m);
|
|
597
597
|
}
|
|
598
598
|
};
|
|
599
|
-
return
|
|
599
|
+
return P.addEventListener("finished", u), () => P.removeEventListener("finished", u);
|
|
600
600
|
}, [
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
]),
|
|
608
|
-
if (
|
|
609
|
-
const
|
|
610
|
-
if (
|
|
611
|
-
const
|
|
612
|
-
if (
|
|
613
|
-
const r =
|
|
601
|
+
P,
|
|
602
|
+
G,
|
|
603
|
+
M,
|
|
604
|
+
D,
|
|
605
|
+
U,
|
|
606
|
+
E
|
|
607
|
+
]), $(() => {
|
|
608
|
+
if (D && y) {
|
|
609
|
+
const u = x.current, d = u?.name || "";
|
|
610
|
+
if (d.startsWith("idle_") || d.startsWith("talk_") || d === "") {
|
|
611
|
+
const s = re.current;
|
|
612
|
+
if (s) {
|
|
613
|
+
const r = S.current[`EXPR_${s}`];
|
|
614
614
|
if (r) {
|
|
615
|
-
r.reset().fadeIn(0.3).play(),
|
|
615
|
+
r.reset().fadeIn(0.3).play(), u && u !== r && u.crossFadeTo(r, 0.3, !0), x.current = r, re.current = null;
|
|
616
616
|
return;
|
|
617
617
|
}
|
|
618
618
|
}
|
|
619
|
-
if (
|
|
620
|
-
const r =
|
|
621
|
-
r && (r.reset().fadeIn(0.5).play(),
|
|
619
|
+
if (d.startsWith("idle_") || d === "") {
|
|
620
|
+
const r = S.current.talk_0;
|
|
621
|
+
r && (r.reset().fadeIn(0.5).play(), u && u.crossFadeTo(r, 0.5, !0), x.current = r);
|
|
622
622
|
}
|
|
623
623
|
}
|
|
624
|
-
} else if (!
|
|
625
|
-
const
|
|
626
|
-
if (
|
|
627
|
-
const
|
|
628
|
-
|
|
624
|
+
} else if (!D && y) {
|
|
625
|
+
const u = x.current, d = u?.name || "";
|
|
626
|
+
if (d.startsWith("talk_") || d.startsWith("EXPR_")) {
|
|
627
|
+
const s = S.current.idle_0;
|
|
628
|
+
s && (s.reset().fadeIn(0.5).play(), u && u.crossFadeTo(s, 0.5, !0), x.current = s);
|
|
629
629
|
}
|
|
630
630
|
}
|
|
631
|
-
}, [
|
|
632
|
-
if (!
|
|
633
|
-
|
|
634
|
-
if (
|
|
635
|
-
const r =
|
|
636
|
-
(r.includes("head") || r.includes("avatar")) && (
|
|
631
|
+
}, [D, y, k]), $(() => {
|
|
632
|
+
if (!y) return;
|
|
633
|
+
y.traverse((s) => {
|
|
634
|
+
if (s.isMesh && s.morphTargetDictionary) {
|
|
635
|
+
const r = s.name.toLowerCase();
|
|
636
|
+
(r.includes("head") || r.includes("avatar")) && (j.current = s, V(`[ANIMATION] Found head mesh: ${s.name}`)), r.includes("teeth") && (N.current = s, V(`[ANIMATION] Found teeth mesh: ${s.name}`));
|
|
637
637
|
}
|
|
638
638
|
});
|
|
639
|
-
const
|
|
640
|
-
|
|
641
|
-
(
|
|
639
|
+
const u = j.current?.morphTargetDictionary;
|
|
640
|
+
u && Object.keys(u).filter(
|
|
641
|
+
(s) => s.toLowerCase().includes("brow")
|
|
642
642
|
);
|
|
643
|
-
const
|
|
644
|
-
|
|
645
|
-
if (
|
|
646
|
-
const
|
|
647
|
-
|
|
643
|
+
const d = [];
|
|
644
|
+
y.traverse((s) => {
|
|
645
|
+
if (s.isMesh) {
|
|
646
|
+
const m = s.morphTargetDictionary;
|
|
647
|
+
m && Object.keys(m).some((z) => z.toLowerCase().includes("brow")) && d.push(s);
|
|
648
648
|
}
|
|
649
|
-
}),
|
|
650
|
-
}, [
|
|
651
|
-
const
|
|
652
|
-
const
|
|
649
|
+
}), ne.current = d, d.length > 0 && V("[ANIMATION] Meshes with brow morphs:", d.length);
|
|
650
|
+
}, [y]);
|
|
651
|
+
const xe = (u, d = 1) => {
|
|
652
|
+
const s = `viseme_${u}`.toLowerCase(), r = gn.find((m) => m.key.toLowerCase() === s);
|
|
653
653
|
if (r)
|
|
654
|
-
for (const
|
|
655
|
-
const
|
|
656
|
-
|
|
654
|
+
for (const m in r.mix) {
|
|
655
|
+
const z = r.mix[m] * d;
|
|
656
|
+
Q(j.current, m, z), Q(N.current, m, z);
|
|
657
657
|
}
|
|
658
|
-
},
|
|
659
|
-
const
|
|
660
|
-
for (const
|
|
661
|
-
|
|
658
|
+
}, Fe = (u) => {
|
|
659
|
+
const d = Qe[u] ?? Qe.neutral;
|
|
660
|
+
for (const s in d)
|
|
661
|
+
Q(j.current, s, d[s]), Q(N.current, s, d[s]);
|
|
662
662
|
};
|
|
663
|
-
return
|
|
664
|
-
const
|
|
665
|
-
|
|
666
|
-
const r =
|
|
667
|
-
let
|
|
668
|
-
if (Math.floor(r) % 5 === 0 && Math.floor((r -
|
|
663
|
+
return Qt((u, d) => {
|
|
664
|
+
const s = Math.pow(0.88, 60 * d);
|
|
665
|
+
Ct(j.current, s), Ct(N.current, s), Fe(H);
|
|
666
|
+
const r = u.clock.elapsedTime;
|
|
667
|
+
let m = 0;
|
|
668
|
+
if (Math.floor(r) % 5 === 0 && Math.floor((r - d) % 5) !== 0) {
|
|
669
669
|
let J = null;
|
|
670
|
-
|
|
671
|
-
|
|
670
|
+
y.traverse((te) => {
|
|
671
|
+
te.name.toLowerCase().includes("hips") && (J = te);
|
|
672
672
|
});
|
|
673
|
-
const
|
|
674
|
-
|
|
673
|
+
const ie = J ? `Hips Y: ${J.position.y.toFixed(4)}` : "Hips not found";
|
|
674
|
+
V(`[ANIMATION] Mixer Time: ${P.time.toFixed(2)}, ${ie}`);
|
|
675
675
|
}
|
|
676
|
-
if (
|
|
677
|
-
const
|
|
678
|
-
if (
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
676
|
+
if (P.update(d), r > ye.current && !le.current && (le.current = !0, $e.current = r), le.current) {
|
|
677
|
+
const J = D ? 0.2 : 0.3, ie = (r - $e.current) / J;
|
|
678
|
+
if (ie >= 1) {
|
|
679
|
+
le.current = !1;
|
|
680
|
+
const te = D ? 1 : 2.5;
|
|
681
|
+
ye.current = r + te;
|
|
682
|
+
} else {
|
|
683
|
+
const te = ie < 0.5 ? ie * 2 : (1 - ie) * 2;
|
|
684
|
+
Q(j.current, "eyeBlinkLeft", te), Q(j.current, "eyeBlinkRight", te), Q(N.current, "eyeBlinkLeft", te), Q(N.current, "eyeBlinkRight", te), m = te * mn.browInnerUp;
|
|
683
685
|
}
|
|
684
686
|
}
|
|
685
|
-
const
|
|
686
|
-
if (
|
|
687
|
-
const J =
|
|
688
|
-
|
|
689
|
-
|
|
687
|
+
const z = Qe[H] ?? Qe.neutral, K = z.browInnerUp ?? 0, Xe = z.browOuterUpLeft ?? 0, Ke = z.browOuterUpRight ?? 0, Me = r * pn, Ze = dt * Math.sin(Me), ke = dt * 0.7 * Math.sin(Me + 0.7), ee = dt * 0.7 * Math.sin(Me + 1.3), Ae = (J) => Math.max(0, Math.min(1, J)), _e = Ae(K + Ze), we = Ae(Xe + ke), Re = Ae(Ke + ee), Ue = Ae(_e + m);
|
|
688
|
+
if (Q(j.current, "browInnerUp", Ue), Q(N.current, "browInnerUp", Ue), Q(j.current, "browOuterUpLeft", we), Q(N.current, "browOuterUpLeft", we), Q(j.current, "browOuterUpRight", Re), Q(N.current, "browOuterUpRight", Re), B.current) {
|
|
689
|
+
const J = T.current ? 0 : O.rotation[1];
|
|
690
|
+
B.current.rotation.y = Ve.MathUtils.lerp(
|
|
691
|
+
B.current.rotation.y,
|
|
690
692
|
J,
|
|
691
693
|
0.1
|
|
692
|
-
),
|
|
694
|
+
), B.current.position.set(...O.position), B.current.scale.setScalar(O.scale), B.current.rotation.x = O.rotation[0], B.current.rotation.z = O.rotation[2];
|
|
693
695
|
}
|
|
694
|
-
if (
|
|
695
|
-
const J =
|
|
696
|
-
for (let
|
|
697
|
-
const
|
|
698
|
-
|
|
696
|
+
if (T.current && p.current) {
|
|
697
|
+
const J = p.current.currentTime, He = (J - b.current) * 1e3 - -150;
|
|
698
|
+
for (let Le = 0; Le < w.current.length; Le++) {
|
|
699
|
+
const Y = w.current[Le];
|
|
700
|
+
He >= Y.vtime && He < Y.vtime + Y.vduration && xe(Y.viseme, Y.weight ?? 1);
|
|
699
701
|
}
|
|
700
|
-
J >
|
|
702
|
+
J > me.current + 0.5 && (I(), v(!1));
|
|
701
703
|
}
|
|
702
|
-
}), /* @__PURE__ */ l("group", { ref:
|
|
704
|
+
}), /* @__PURE__ */ l("group", { ref: B, children: /* @__PURE__ */ l("primitive", { object: y }) });
|
|
703
705
|
}
|
|
704
706
|
);
|
|
705
|
-
function
|
|
707
|
+
function yn(f) {
|
|
706
708
|
return f ? f.charAt(0).toUpperCase() + f.slice(1).toLowerCase() : "";
|
|
707
709
|
}
|
|
708
|
-
const
|
|
710
|
+
const Sn = ({
|
|
709
711
|
token: f,
|
|
710
|
-
agentToken:
|
|
712
|
+
agentToken: T,
|
|
711
713
|
onNavigationRequested: w,
|
|
712
|
-
avatarGender:
|
|
714
|
+
avatarGender: p,
|
|
715
|
+
presetUserDetails: b
|
|
713
716
|
} = {}) => {
|
|
714
|
-
const
|
|
717
|
+
const O = f ?? T ?? "", H = an(O || void 0), [he, X] = g(""), [D, me] = g(""), [I, v] = g("Ready"), [k, E] = g(!1), [U, be] = g(!1), [y, Ie] = g([]), [Ne, G] = g(""), ce = a(null), [M, B] = g(
|
|
715
718
|
() => typeof window < "u" ? window.matchMedia("(max-width: 480px)").matches : !1
|
|
716
719
|
);
|
|
717
|
-
|
|
718
|
-
const e = window.matchMedia("(max-width: 480px)"), t = () =>
|
|
720
|
+
$(() => {
|
|
721
|
+
const e = window.matchMedia("(max-width: 480px)"), t = () => B(e.matches);
|
|
719
722
|
return e.addEventListener("change", t), () => e.removeEventListener("change", t);
|
|
720
723
|
}, []);
|
|
721
|
-
const
|
|
722
|
-
|
|
723
|
-
const
|
|
724
|
+
const j = M ? 80 : 600, N = a(!1), ne = a([]), P = a(0), S = a(!1), x = a([]), ye = a(null), le = a([]);
|
|
725
|
+
a([]);
|
|
726
|
+
const $e = a([]), re = a(0), Se = a(0), xe = a(0), Fe = a(0), u = a(!1), [d, s] = g(
|
|
724
727
|
null
|
|
725
|
-
),
|
|
728
|
+
), r = a(null), [m, z] = g("neutral"), [K, Xe] = g(""), [Ke, Me] = g(""), [Ze, ke] = g("Chat with us"), [ee, Ae] = g(
|
|
726
729
|
null
|
|
727
|
-
), [
|
|
728
|
-
|
|
729
|
-
const [
|
|
730
|
-
|
|
731
|
-
const
|
|
732
|
-
|
|
733
|
-
if (ue !== "hidden" || !
|
|
734
|
-
|
|
730
|
+
), [_e, we] = g("hidden"), [Re, Ue] = g(""), J = a(null), ie = a(_e);
|
|
731
|
+
ie.current = _e;
|
|
732
|
+
const [te, He] = g(null), Le = a(null), Y = a(null), [Be, ht] = g(!1), mt = a(null), [ue, je] = g("hidden"), [pt, Ot] = g(""), et = a(ue);
|
|
733
|
+
et.current = ue;
|
|
734
|
+
const pe = a(""), Ce = a(!1), Oe = a(""), gt = a(Date.now()), tt = a([]), Pe = a(!1), [nt, We] = g(!1), [bt, _t] = g(!1), ve = a(null), De = ft(() => Be ? "Try again" : I === "Busy" ? "Busy" : I === "Thinking..." || I === "Processing Voice..." ? I : ee != null && ee !== "" && ee !== "none" && ee !== "<none>" ? `Enter ${yn(ee)}` : ue !== "hidden" || !bt ? null : Mt, [I, ee, Be, ue, bt]), wt = !Be && I !== "Busy" && I !== "Thinking..." && I !== "Processing Voice..." && (ee == null || ee === "" || ee === "none" || ee === "<none>");
|
|
735
|
+
$(() => {
|
|
736
|
+
if (ue !== "hidden" || !wt) {
|
|
737
|
+
_t(!1), ve.current != null && (clearTimeout(ve.current), ve.current = null);
|
|
735
738
|
return;
|
|
736
739
|
}
|
|
737
|
-
return
|
|
738
|
-
|
|
740
|
+
return ve.current = setTimeout(() => {
|
|
741
|
+
ve.current = null, _t(!0);
|
|
739
742
|
}, 400), () => {
|
|
740
|
-
|
|
743
|
+
ve.current != null && (clearTimeout(ve.current), ve.current = null);
|
|
741
744
|
};
|
|
742
|
-
}, [ue,
|
|
743
|
-
const
|
|
744
|
-
|
|
745
|
-
const e =
|
|
745
|
+
}, [ue, wt]);
|
|
746
|
+
const Je = De != null && De !== "";
|
|
747
|
+
$(() => {
|
|
748
|
+
const e = ie.current;
|
|
746
749
|
if (!(e === "exiting" || e === "entering")) {
|
|
747
750
|
if (e === "hidden") {
|
|
748
|
-
|
|
751
|
+
Je && (Ue(De ?? ""), we("entering"));
|
|
749
752
|
return;
|
|
750
753
|
}
|
|
751
|
-
e === "visible" && (!
|
|
754
|
+
e === "visible" && (!Je || De !== Re) && (J.current = Je ? De : null, we("exiting"));
|
|
752
755
|
}
|
|
753
756
|
}, [
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
]),
|
|
759
|
-
if (
|
|
760
|
-
|
|
757
|
+
Je,
|
|
758
|
+
De,
|
|
759
|
+
_e,
|
|
760
|
+
Re
|
|
761
|
+
]), $(() => {
|
|
762
|
+
if (I !== "Busy") {
|
|
763
|
+
Y.current != null && (clearTimeout(Y.current), Y.current = null);
|
|
761
764
|
return;
|
|
762
765
|
}
|
|
763
|
-
return
|
|
764
|
-
|
|
766
|
+
return Y.current = setTimeout(() => {
|
|
767
|
+
Y.current = null, v("Ready"), ht(!0);
|
|
765
768
|
}, 12e3), () => {
|
|
766
|
-
|
|
769
|
+
Y.current != null && (clearTimeout(Y.current), Y.current = null);
|
|
767
770
|
};
|
|
768
|
-
}, [
|
|
769
|
-
if (!
|
|
770
|
-
const e = setTimeout(() =>
|
|
771
|
+
}, [I]), $(() => {
|
|
772
|
+
if (!Be) return;
|
|
773
|
+
const e = setTimeout(() => ht(!1), 2500);
|
|
771
774
|
return () => clearTimeout(e);
|
|
772
|
-
}, [
|
|
773
|
-
const
|
|
774
|
-
const e =
|
|
775
|
+
}, [Be]);
|
|
776
|
+
const Dt = Ye(() => {
|
|
777
|
+
const e = ie.current;
|
|
775
778
|
if (e === "exiting") {
|
|
776
|
-
|
|
777
|
-
const t =
|
|
778
|
-
|
|
779
|
-
} else e === "entering" &&
|
|
780
|
-
}, []),
|
|
779
|
+
we("hidden");
|
|
780
|
+
const t = J.current;
|
|
781
|
+
J.current = null, t != null && t !== "" && (Ue(t), we("entering"));
|
|
782
|
+
} else e === "entering" && we("visible");
|
|
783
|
+
}, []), Nt = (e) => {
|
|
781
784
|
if (!e) return;
|
|
782
785
|
if (e.mood != null) {
|
|
783
786
|
const n = String(e.mood).toLowerCase();
|
|
784
|
-
|
|
787
|
+
z(n);
|
|
785
788
|
}
|
|
786
789
|
if (e.expression != null) {
|
|
787
790
|
const n = String(e.expression).trim();
|
|
788
|
-
|
|
789
|
-
const
|
|
790
|
-
(
|
|
791
|
+
Xe(n);
|
|
792
|
+
const c = un.find(
|
|
793
|
+
(h) => h.name.toLowerCase() === n.toLowerCase()
|
|
791
794
|
);
|
|
792
|
-
|
|
793
|
-
`[STREAM] Animation match for "${n}": ${
|
|
794
|
-
),
|
|
795
|
+
V(
|
|
796
|
+
`[STREAM] Animation match for "${n}": ${c ? c.name : "NONE"}`
|
|
797
|
+
), Me(c?.url ?? "");
|
|
795
798
|
}
|
|
796
799
|
if (e.navigation != null) {
|
|
797
800
|
const n = String(e.navigation).trim();
|
|
798
801
|
n !== "" && (w ? w(n) : window.open(n, "_blank"));
|
|
799
802
|
}
|
|
800
|
-
const t = e.ask_for || e.lead_capture?.ask_for,
|
|
803
|
+
const t = e.ask_for || e.lead_capture?.ask_for, i = t ? String(t).trim().toLowerCase() : "", o = i === "none" || i === "<none>";
|
|
801
804
|
if (t && !o) {
|
|
802
|
-
const n =
|
|
803
|
-
|
|
804
|
-
|
|
805
|
+
const n = i;
|
|
806
|
+
if (b && (n === "email" && b.email || n === "name" && b.name || n === "phone" && b.phone))
|
|
807
|
+
return;
|
|
808
|
+
Ae(n || null), ke(n === "email" ? "Enter your email" : n === "name" ? "Enter your name" : n === "phone" ? "Enter your phone number" : "Chat with us");
|
|
809
|
+
} else (o || e.ask_for === null || e.lead_capture && e.lead_capture.ask_for === null || e.ask_for === "none") && (Ae(null), Ze !== "Chat with us" && ke("Chat with us"));
|
|
805
810
|
e.collected, e.valid;
|
|
806
811
|
}, Ft = (e) => {
|
|
807
812
|
const t = e.trim();
|
|
@@ -813,81 +818,92 @@ const yn = ({
|
|
|
813
818
|
return null;
|
|
814
819
|
}
|
|
815
820
|
if (t.includes(":")) {
|
|
816
|
-
const
|
|
821
|
+
const i = t.split(":"), o = i[0].trim().toLowerCase(), n = i.slice(1).join(":").trim();
|
|
817
822
|
return { [o]: n };
|
|
818
823
|
}
|
|
819
824
|
return null;
|
|
820
|
-
},
|
|
821
|
-
}, []),
|
|
825
|
+
}, Ut = Ye(() => {
|
|
826
|
+
}, []), vt = (e) => {
|
|
822
827
|
if (Ce.current)
|
|
823
|
-
e === "§" ? Ce.current = !1 : (Oe.current += e,
|
|
828
|
+
e === "§" ? Ce.current = !1 : (Oe.current += e, me((t) => t + e));
|
|
824
829
|
else if (e === "§") {
|
|
825
830
|
Ce.current = !0;
|
|
826
831
|
return;
|
|
827
832
|
} else
|
|
828
|
-
for (
|
|
833
|
+
for (pe.current += e; pe.current.includes(`
|
|
829
834
|
`); ) {
|
|
830
|
-
const t =
|
|
831
|
-
`),
|
|
832
|
-
|
|
833
|
-
const o = Ft(
|
|
834
|
-
o &&
|
|
835
|
+
const t = pe.current.indexOf(`
|
|
836
|
+
`), i = pe.current.slice(0, t).trim();
|
|
837
|
+
pe.current = pe.current.slice(t + 1);
|
|
838
|
+
const o = Ft(i);
|
|
839
|
+
o && Nt(o);
|
|
835
840
|
}
|
|
836
841
|
};
|
|
837
|
-
|
|
842
|
+
$(() => {
|
|
838
843
|
(async () => {
|
|
839
844
|
if (!sessionStorage.getItem(
|
|
840
845
|
"STREAMOJI_LEADS_SESSION_LEAD_ID"
|
|
841
846
|
)) {
|
|
842
|
-
const
|
|
847
|
+
const n = "secret", c = Math.floor(Date.now() / 1e3).toString();
|
|
843
848
|
try {
|
|
844
|
-
const
|
|
849
|
+
const h = new TextEncoder(), _ = await crypto.subtle.importKey(
|
|
845
850
|
"raw",
|
|
846
|
-
|
|
851
|
+
h.encode(n),
|
|
847
852
|
{ name: "HMAC", hash: "SHA-256" },
|
|
848
853
|
!1,
|
|
849
854
|
["sign"]
|
|
850
|
-
),
|
|
855
|
+
), A = await crypto.subtle.sign(
|
|
851
856
|
"HMAC",
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
),
|
|
855
|
-
sessionStorage.setItem("STREAMOJI_LEADS_SESSION_LEAD_ID",
|
|
856
|
-
} catch (
|
|
857
|
-
console.error("[SESSION] HMAC generation failed:",
|
|
858
|
-
const
|
|
859
|
-
sessionStorage.setItem("STREAMOJI_LEADS_SESSION_LEAD_ID",
|
|
857
|
+
_,
|
|
858
|
+
h.encode(c)
|
|
859
|
+
), L = Array.from(new Uint8Array(A)).map((W) => W.toString(16).padStart(2, "0")).join("");
|
|
860
|
+
sessionStorage.setItem("STREAMOJI_LEADS_SESSION_LEAD_ID", L), V("[SESSION] New HMAC UID generated and saved:", L);
|
|
861
|
+
} catch (h) {
|
|
862
|
+
console.error("[SESSION] HMAC generation failed:", h);
|
|
863
|
+
const _ = Math.random().toString(36) + Date.now().toString();
|
|
864
|
+
sessionStorage.setItem("STREAMOJI_LEADS_SESSION_LEAD_ID", _);
|
|
860
865
|
}
|
|
861
866
|
}
|
|
862
|
-
sessionStorage.getItem("STREAMOJI_LEADS_SESSION_MESSAGES")
|
|
867
|
+
const i = sessionStorage.getItem("STREAMOJI_LEADS_SESSION_MESSAGES");
|
|
868
|
+
let o = [];
|
|
869
|
+
if (i)
|
|
870
|
+
try {
|
|
871
|
+
o = JSON.parse(i);
|
|
872
|
+
} catch {
|
|
873
|
+
o = [];
|
|
874
|
+
}
|
|
875
|
+
o.length === 0 && b && (b.name || b.email) ? (o = [{ role: "user", content: `PRESET_USER_DETAILS: Name is "${b.name || ""}" , Email is "${b.email || ""}"` }], sessionStorage.setItem(
|
|
876
|
+
"STREAMOJI_LEADS_SESSION_MESSAGES",
|
|
877
|
+
JSON.stringify(o)
|
|
878
|
+
)) : i || sessionStorage.setItem(
|
|
863
879
|
"STREAMOJI_LEADS_SESSION_MESSAGES",
|
|
864
880
|
JSON.stringify([])
|
|
865
881
|
);
|
|
866
882
|
})();
|
|
867
|
-
}, []),
|
|
883
|
+
}, [b]), $(() => {
|
|
868
884
|
const e = () => {
|
|
869
|
-
|
|
885
|
+
gt.current = Date.now(), Pe.current && (Pe.current = !1, We(!1), Ie([]), G(""), me(""), be(!1));
|
|
870
886
|
};
|
|
871
887
|
window.addEventListener("mousemove", e), window.addEventListener("keydown", e), window.addEventListener("mousedown", e), window.addEventListener("touchstart", e);
|
|
872
888
|
const t = setInterval(async () => {
|
|
873
|
-
if (Date.now() -
|
|
874
|
-
if (Pe.current = !0,
|
|
875
|
-
We(!0),
|
|
889
|
+
if (Date.now() - gt.current >= 3e4 && !U && !k && I === "Ready" && !Pe.current)
|
|
890
|
+
if (Pe.current = !0, tt.current.length > 0)
|
|
891
|
+
We(!0), Ie(tt.current);
|
|
876
892
|
else
|
|
877
893
|
try {
|
|
878
|
-
const n = `${
|
|
894
|
+
const n = `${ut}/nudgeUser`, c = {
|
|
879
895
|
navigationUrl: window.location.href,
|
|
880
|
-
token:
|
|
881
|
-
},
|
|
896
|
+
token: O
|
|
897
|
+
}, h = await fetch(n, {
|
|
882
898
|
method: "POST",
|
|
883
899
|
headers: {
|
|
884
900
|
"Content-Type": "application/json"
|
|
885
901
|
},
|
|
886
|
-
body: JSON.stringify(
|
|
902
|
+
body: JSON.stringify(c)
|
|
887
903
|
});
|
|
888
|
-
if (
|
|
889
|
-
const
|
|
890
|
-
|
|
904
|
+
if (h.ok) {
|
|
905
|
+
const A = (await h.json()).nudge_questions;
|
|
906
|
+
A && A.length > 0 && (V("[NUDGE] Received nudge questions from API:", A), tt.current = A, We(!0), Ie(A));
|
|
891
907
|
}
|
|
892
908
|
} catch (n) {
|
|
893
909
|
console.error("[NUDGE] Error calling /nudgeUser:", n), Pe.current = !1;
|
|
@@ -896,25 +912,25 @@ const yn = ({
|
|
|
896
912
|
return () => {
|
|
897
913
|
window.removeEventListener("mousemove", e), window.removeEventListener("keydown", e), window.removeEventListener("mousedown", e), window.removeEventListener("touchstart", e), clearInterval(t);
|
|
898
914
|
};
|
|
899
|
-
}, [
|
|
900
|
-
if (
|
|
901
|
-
let e = 0, t = 0,
|
|
915
|
+
}, [O, U, k, I]), $(() => {
|
|
916
|
+
if (y.length === 0) return;
|
|
917
|
+
let e = 0, t = 0, i = !1, o = 100;
|
|
902
918
|
const n = () => {
|
|
903
|
-
const
|
|
904
|
-
if (
|
|
905
|
-
const
|
|
906
|
-
|
|
919
|
+
const c = y[e];
|
|
920
|
+
if (i) {
|
|
921
|
+
const h = c.substring(0, t - 1);
|
|
922
|
+
G(h), t--, o = 50;
|
|
907
923
|
} else {
|
|
908
|
-
const
|
|
909
|
-
|
|
924
|
+
const h = c.substring(0, t + 1);
|
|
925
|
+
G(h), t++, o = 100;
|
|
910
926
|
}
|
|
911
|
-
!
|
|
927
|
+
!i && t === c.length ? (i = !0, o = 3e3) : i && t === 0 && (i = !1, e = (e + 1) % y.length, o = 500), ce.current = setTimeout(n, o);
|
|
912
928
|
};
|
|
913
929
|
return n(), () => {
|
|
914
|
-
|
|
930
|
+
ce.current && clearTimeout(ce.current);
|
|
915
931
|
};
|
|
916
|
-
}, [
|
|
917
|
-
const
|
|
932
|
+
}, [y]);
|
|
933
|
+
const yt = () => {
|
|
918
934
|
try {
|
|
919
935
|
return JSON.parse(
|
|
920
936
|
sessionStorage.getItem("STREAMOJI_LEADS_SESSION_MESSAGES") || "[]"
|
|
@@ -922,232 +938,232 @@ const yn = ({
|
|
|
922
938
|
} catch {
|
|
923
939
|
return [];
|
|
924
940
|
}
|
|
925
|
-
},
|
|
941
|
+
}, Bt = (e) => {
|
|
926
942
|
sessionStorage.setItem(
|
|
927
943
|
"STREAMOJI_LEADS_SESSION_MESSAGES",
|
|
928
944
|
JSON.stringify(e)
|
|
929
945
|
);
|
|
930
|
-
}, [
|
|
946
|
+
}, [rt, it] = g(!1), [St, st] = g(0), de = a(null), qe = a([]), xt = a(0), [kt, Pt] = g(
|
|
931
947
|
null
|
|
932
|
-
), [
|
|
948
|
+
), [Wt, ot] = g(
|
|
933
949
|
null
|
|
934
|
-
),
|
|
950
|
+
), ge = a(null), Te = a(
|
|
935
951
|
null
|
|
936
|
-
),
|
|
937
|
-
e && (
|
|
952
|
+
), Ge = Ye((e = !1) => {
|
|
953
|
+
e && (u.current = !0, E(!1), v("Ready")), x.current = [], ne.current = [], S.current = !1, be(!1), re.current = 0, Se.current = 0, xe.current = 0, le.current.forEach((t) => {
|
|
938
954
|
try {
|
|
939
955
|
t.stop();
|
|
940
956
|
} catch {
|
|
941
957
|
}
|
|
942
|
-
}),
|
|
943
|
-
}, []),
|
|
958
|
+
}), Le.current && (clearTimeout(Le.current), Le.current = null), He(null), Me(""), le.current = [];
|
|
959
|
+
}, []), Vt = async () => {
|
|
944
960
|
try {
|
|
945
|
-
const e = await navigator.mediaDevices.getUserMedia({ audio: !0 }), t = window.AudioContext || window.webkitAudioContext,
|
|
946
|
-
n.fftSize = 64, o.connect(n),
|
|
947
|
-
const
|
|
948
|
-
de.current =
|
|
949
|
-
|
|
950
|
-
},
|
|
951
|
-
const
|
|
952
|
-
if (
|
|
953
|
-
|
|
961
|
+
const e = await navigator.mediaDevices.getUserMedia({ audio: !0 }), t = window.AudioContext || window.webkitAudioContext, i = new t(), o = i.createMediaStreamSource(e), n = i.createAnalyser();
|
|
962
|
+
n.fftSize = 64, o.connect(n), ge.current = i, Te.current = o, ot(n);
|
|
963
|
+
const c = new MediaRecorder(e);
|
|
964
|
+
de.current = c, qe.current = [], c.ondataavailable = (h) => {
|
|
965
|
+
h.data.size > 0 && qe.current.push(h.data);
|
|
966
|
+
}, c.onstop = async () => {
|
|
967
|
+
const h = Date.now() - xt.current;
|
|
968
|
+
if (ot(null), Te.current && (Te.current.disconnect(), Te.current = null), ge.current && ge.current.state !== "closed" && (ge.current.close(), ge.current = null), h < 1e3) {
|
|
969
|
+
v("Recording too short. Hold or click longer."), E(!1);
|
|
954
970
|
return;
|
|
955
971
|
}
|
|
956
|
-
const
|
|
972
|
+
const _ = new Blob(qe.current, {
|
|
957
973
|
type: "audio/wav"
|
|
958
974
|
});
|
|
959
|
-
await
|
|
960
|
-
},
|
|
975
|
+
await Jt(_);
|
|
976
|
+
}, xt.current = Date.now(), c.start(100), it(!0), v("Listening...");
|
|
961
977
|
} catch (e) {
|
|
962
|
-
console.error("Error accessing microphone:", e),
|
|
978
|
+
console.error("Error accessing microphone:", e), v("Mic Access Error");
|
|
963
979
|
}
|
|
964
|
-
},
|
|
965
|
-
de.current && de.current.state !== "inactive" && (de.current.stop(), de.current.stream.getTracks().forEach((e) => e.stop()),
|
|
980
|
+
}, $t = () => {
|
|
981
|
+
de.current && de.current.state !== "inactive" && (de.current.stop(), de.current.stream.getTracks().forEach((e) => e.stop()), it(!1));
|
|
966
982
|
}, Ht = () => {
|
|
967
|
-
de.current && de.current.state !== "inactive" && (de.current.onstop = null, de.current.stop(), de.current.stream.getTracks().forEach((e) => e.stop()),
|
|
983
|
+
de.current && de.current.state !== "inactive" && (de.current.onstop = null, de.current.stop(), de.current.stream.getTracks().forEach((e) => e.stop()), ot(null), Te.current && (Te.current.disconnect(), Te.current = null), ge.current && ge.current.state !== "closed" && (ge.current.close(), ge.current = null), it(!1), qe.current = [], v("Ready"));
|
|
968
984
|
};
|
|
969
|
-
|
|
970
|
-
if (!
|
|
985
|
+
$(() => {
|
|
986
|
+
if (!U) return;
|
|
971
987
|
const e = () => {
|
|
972
|
-
const t =
|
|
988
|
+
const t = xe.current;
|
|
973
989
|
if (t <= 0) return;
|
|
974
|
-
const
|
|
975
|
-
if (!
|
|
976
|
-
const n =
|
|
977
|
-
if (
|
|
978
|
-
const
|
|
979
|
-
Math.round(
|
|
980
|
-
|
|
990
|
+
const i = ye.current, o = re.current;
|
|
991
|
+
if (!i) return;
|
|
992
|
+
const n = i.currentTime - o, c = Math.min(Math.max(0, n), t), h = D.trim().length;
|
|
993
|
+
if (h <= 0) return;
|
|
994
|
+
const _ = Math.min(
|
|
995
|
+
Math.round(c / t * h),
|
|
996
|
+
h
|
|
981
997
|
);
|
|
982
|
-
|
|
998
|
+
s(_);
|
|
983
999
|
};
|
|
984
|
-
return clearInterval(
|
|
985
|
-
}, [
|
|
1000
|
+
return clearInterval(r.current ?? void 0), r.current = setInterval(e, 90), () => clearInterval(r.current ?? void 0);
|
|
1001
|
+
}, [U, D, xe.current]), $(() => {
|
|
986
1002
|
let e;
|
|
987
|
-
return
|
|
1003
|
+
return rt ? (st(0), e = window.setInterval(() => {
|
|
988
1004
|
st((t) => t + 1);
|
|
989
1005
|
}, 1e3)) : st(0), () => clearInterval(e);
|
|
990
|
-
}, [
|
|
991
|
-
const
|
|
992
|
-
const t = e.numberOfChannels,
|
|
993
|
-
let
|
|
994
|
-
const
|
|
995
|
-
n.setUint16(
|
|
996
|
-
},
|
|
997
|
-
n.setUint32(
|
|
1006
|
+
}, [rt]);
|
|
1007
|
+
const jt = (e) => {
|
|
1008
|
+
const t = e.numberOfChannels, i = e.length * t * 2 + 44, o = new ArrayBuffer(i), n = new DataView(o);
|
|
1009
|
+
let c = 0;
|
|
1010
|
+
const h = (L) => {
|
|
1011
|
+
n.setUint16(c, L, !0), c += 2;
|
|
1012
|
+
}, _ = (L) => {
|
|
1013
|
+
n.setUint32(c, L, !0), c += 4;
|
|
998
1014
|
};
|
|
999
|
-
|
|
1000
|
-
const
|
|
1001
|
-
for (let
|
|
1002
|
-
let
|
|
1003
|
-
for (;
|
|
1004
|
-
for (let
|
|
1005
|
-
let
|
|
1006
|
-
|
|
1015
|
+
_(1179011410), _(i - 8), _(1163280727), _(544501094), _(16), h(1), h(t), _(e.sampleRate), _(e.sampleRate * 2 * t), h(t * 2), h(16), _(1635017060), _(i - c - 4);
|
|
1016
|
+
const A = [];
|
|
1017
|
+
for (let L = 0; L < t; L++) A.push(e.getChannelData(L));
|
|
1018
|
+
let R = 0;
|
|
1019
|
+
for (; c < i; ) {
|
|
1020
|
+
for (let L = 0; L < t; L++) {
|
|
1021
|
+
let W = Math.max(-1, Math.min(1, A[L][R]));
|
|
1022
|
+
W = W < 0 ? W * 32768 : W * 32767, n.setInt16(c, W, !0), c += 2;
|
|
1007
1023
|
}
|
|
1008
|
-
|
|
1024
|
+
R++;
|
|
1009
1025
|
}
|
|
1010
1026
|
return new Blob([o], { type: "audio/wav" });
|
|
1011
|
-
},
|
|
1012
|
-
if (!
|
|
1013
|
-
if (
|
|
1014
|
-
|
|
1027
|
+
}, at = async (e, t, i = !1) => {
|
|
1028
|
+
if (!u.current) {
|
|
1029
|
+
if (N.current) {
|
|
1030
|
+
ne.current.push({
|
|
1015
1031
|
audio: e,
|
|
1016
1032
|
visemes: t,
|
|
1017
|
-
isNewSegment:
|
|
1033
|
+
isNewSegment: i
|
|
1018
1034
|
});
|
|
1019
1035
|
return;
|
|
1020
1036
|
}
|
|
1021
|
-
|
|
1037
|
+
N.current = !0;
|
|
1022
1038
|
try {
|
|
1023
|
-
const o = window.AudioContext || window.webkitAudioContext, n =
|
|
1024
|
-
n.state === "suspended" && await n.resume(),
|
|
1025
|
-
const
|
|
1026
|
-
for (let F = 0; F <
|
|
1027
|
-
|
|
1028
|
-
const
|
|
1029
|
-
|
|
1030
|
-
const
|
|
1031
|
-
let
|
|
1032
|
-
const
|
|
1033
|
-
|
|
1034
|
-
const
|
|
1035
|
-
|
|
1036
|
-
let
|
|
1037
|
-
if ((!
|
|
1038
|
-
|
|
1039
|
+
const o = window.AudioContext || window.webkitAudioContext, n = ye.current ?? new o();
|
|
1040
|
+
n.state === "suspended" && await n.resume(), ye.current = n;
|
|
1041
|
+
const c = window.atob(e), h = new Uint8Array(c.length);
|
|
1042
|
+
for (let F = 0; F < c.length; F++)
|
|
1043
|
+
h[F] = c.charCodeAt(F);
|
|
1044
|
+
const _ = await n.decodeAudioData(h.buffer.slice(0));
|
|
1045
|
+
xe.current += _.duration;
|
|
1046
|
+
const A = n.currentTime;
|
|
1047
|
+
let R = Se.current;
|
|
1048
|
+
const L = !S.current;
|
|
1049
|
+
R < A && (R = A + 0.1), Se.current = R + _.duration;
|
|
1050
|
+
const W = n.createBufferSource();
|
|
1051
|
+
W.buffer = _;
|
|
1052
|
+
let q = kt;
|
|
1053
|
+
if ((!q || q.context !== n) && (q = n.createAnalyser(), q.fftSize = 64, q.connect(n.destination), Pt(q)), W.connect(q), le.current.push(W), u.current) {
|
|
1054
|
+
le.current = le.current.filter((F) => F !== W);
|
|
1039
1055
|
return;
|
|
1040
1056
|
}
|
|
1041
|
-
if (
|
|
1042
|
-
|
|
1043
|
-
`[AUDIO] setIsSpeaking(true) - First chunk starting at ${
|
|
1057
|
+
if (L) {
|
|
1058
|
+
S.current = !0, be(!0), V(
|
|
1059
|
+
`[AUDIO] setIsSpeaking(true) - First chunk starting at ${R.toFixed(
|
|
1044
1060
|
3
|
|
1045
1061
|
)}`
|
|
1046
|
-
),
|
|
1047
|
-
const F = (
|
|
1048
|
-
|
|
1049
|
-
`[AUDIO] Response started. Initial startTime: ${
|
|
1062
|
+
), re.current = R;
|
|
1063
|
+
const F = (R - A) * 1e3;
|
|
1064
|
+
P.current = performance.now() + F, V(
|
|
1065
|
+
`[AUDIO] Response started. Initial startTime: ${R.toFixed(
|
|
1050
1066
|
3
|
|
1051
|
-
)}, CT: ${
|
|
1067
|
+
)}, CT: ${A.toFixed(3)}`
|
|
1052
1068
|
);
|
|
1053
1069
|
}
|
|
1054
|
-
|
|
1055
|
-
const
|
|
1056
|
-
|
|
1057
|
-
`[AUDIO] New segment detected at +${
|
|
1070
|
+
W.start(R);
|
|
1071
|
+
const Z = (R - re.current) * 1e3;
|
|
1072
|
+
i && (Fe.current = Z, V(
|
|
1073
|
+
`[AUDIO] New segment detected at +${Z.toFixed(
|
|
1058
1074
|
0
|
|
1059
1075
|
)}ms. Resetting segment offset.`
|
|
1060
1076
|
)), t.forEach((F, se) => {
|
|
1061
|
-
const
|
|
1062
|
-
if (
|
|
1063
|
-
const
|
|
1064
|
-
se < 3 &&
|
|
1065
|
-
`[AUDIO] Viseme "${
|
|
1077
|
+
const C = F.symbol ?? "";
|
|
1078
|
+
if (C) {
|
|
1079
|
+
const oe = _n(C), fe = Math.round(F.start * 1e3), Ee = Math.round((F.duration ?? 0) * 1e3), Lt = Fe.current + fe;
|
|
1080
|
+
se < 3 && V(
|
|
1081
|
+
`[AUDIO] Viseme "${C}": segment_relative=${fe}ms, segment_offset=${Fe.current.toFixed(
|
|
1066
1082
|
0
|
|
1067
|
-
)}ms => vtime=${
|
|
1068
|
-
),
|
|
1069
|
-
|
|
1070
|
-
viseme:
|
|
1071
|
-
weight:
|
|
1072
|
-
vtime:
|
|
1083
|
+
)}ms => vtime=${Lt}ms`
|
|
1084
|
+
), oe.forEach((Tt) => {
|
|
1085
|
+
x.current.push({
|
|
1086
|
+
viseme: Tt.v,
|
|
1087
|
+
weight: Tt.w,
|
|
1088
|
+
vtime: Lt,
|
|
1073
1089
|
vduration: Ee
|
|
1074
1090
|
});
|
|
1075
1091
|
});
|
|
1076
1092
|
}
|
|
1077
|
-
}),
|
|
1093
|
+
}), v("Speaking...");
|
|
1078
1094
|
} finally {
|
|
1079
|
-
if (
|
|
1080
|
-
const o =
|
|
1081
|
-
o &&
|
|
1095
|
+
if (N.current = !1, ne.current.length > 0) {
|
|
1096
|
+
const o = ne.current.shift();
|
|
1097
|
+
o && at(o.audio, o.visemes, o.isNewSegment);
|
|
1082
1098
|
}
|
|
1083
1099
|
}
|
|
1084
1100
|
}
|
|
1085
|
-
},
|
|
1101
|
+
}, Jt = async (e) => {
|
|
1086
1102
|
try {
|
|
1087
|
-
|
|
1088
|
-
const t = await e.arrayBuffer(), o = await new (window.AudioContext || window.webkitAudioContext)().decodeAudioData(t), n =
|
|
1089
|
-
|
|
1090
|
-
const
|
|
1091
|
-
|
|
1092
|
-
const
|
|
1093
|
-
|
|
1094
|
-
)}`,
|
|
1103
|
+
E(!0), We(!1), Oe.current = "", me(""), v("Processing Voice...");
|
|
1104
|
+
const t = await e.arrayBuffer(), o = await new (window.AudioContext || window.webkitAudioContext)().decodeAudioData(t), n = jt(o), c = new FileReader();
|
|
1105
|
+
c.readAsDataURL(n), c.onloadend = async () => {
|
|
1106
|
+
const h = c.result.split(",")[1];
|
|
1107
|
+
Ge(), X(""), pe.current = "", Ce.current = !1;
|
|
1108
|
+
const _ = `${ut}/stt?token=${encodeURIComponent(
|
|
1109
|
+
O
|
|
1110
|
+
)}`, A = await fetch(_, {
|
|
1095
1111
|
method: "POST",
|
|
1096
1112
|
headers: { "Content-Type": "application/json" },
|
|
1097
1113
|
body: JSON.stringify({
|
|
1098
|
-
audio_base64:
|
|
1114
|
+
audio_base64: h,
|
|
1099
1115
|
audio_format: "wav"
|
|
1100
1116
|
})
|
|
1101
1117
|
});
|
|
1102
|
-
if (
|
|
1118
|
+
if (A.status === 429) {
|
|
1103
1119
|
try {
|
|
1104
|
-
const se = await
|
|
1105
|
-
|
|
1120
|
+
const se = await A.text(), C = JSON.parse(se);
|
|
1121
|
+
V("[STT] 429 agent at capacity:", C?.detail);
|
|
1106
1122
|
} catch {
|
|
1107
1123
|
}
|
|
1108
|
-
|
|
1124
|
+
X(""), v("Busy"), E(!1);
|
|
1109
1125
|
return;
|
|
1110
1126
|
}
|
|
1111
|
-
if (!
|
|
1112
|
-
const se = await
|
|
1113
|
-
let
|
|
1127
|
+
if (!A.ok) {
|
|
1128
|
+
const se = await A.text();
|
|
1129
|
+
let C = "STT Failed";
|
|
1114
1130
|
try {
|
|
1115
|
-
|
|
1131
|
+
C = JSON.parse(se).error || C;
|
|
1116
1132
|
} catch {
|
|
1117
|
-
se && (
|
|
1133
|
+
se && (C = se.slice(0, 200));
|
|
1118
1134
|
}
|
|
1119
|
-
throw new Error(
|
|
1135
|
+
throw new Error(C);
|
|
1120
1136
|
}
|
|
1121
|
-
const
|
|
1122
|
-
if (
|
|
1123
|
-
|
|
1137
|
+
const R = A.body;
|
|
1138
|
+
if (V("this is body" + R), !R) {
|
|
1139
|
+
v("STT Failed"), E(!1);
|
|
1124
1140
|
return;
|
|
1125
1141
|
}
|
|
1126
|
-
const
|
|
1127
|
-
|
|
1128
|
-
const
|
|
1129
|
-
let
|
|
1130
|
-
const F = async (se,
|
|
1142
|
+
const L = R.getReader();
|
|
1143
|
+
u.current = !1;
|
|
1144
|
+
const W = new TextDecoder();
|
|
1145
|
+
let q = "", Z = !1;
|
|
1146
|
+
const F = async (se, C) => {
|
|
1131
1147
|
switch (se) {
|
|
1132
1148
|
case "transcript":
|
|
1133
|
-
|
|
1149
|
+
C.transcript != null && X(String(C.transcript));
|
|
1134
1150
|
break;
|
|
1135
1151
|
case "text": {
|
|
1136
|
-
const
|
|
1137
|
-
|
|
1152
|
+
const oe = C.delta ?? C.text ?? "";
|
|
1153
|
+
oe && vt(oe);
|
|
1138
1154
|
break;
|
|
1139
1155
|
}
|
|
1140
1156
|
case "audio": {
|
|
1141
|
-
const
|
|
1142
|
-
|
|
1157
|
+
const oe = C.chunk, fe = C.visemes ?? [], Ee = !!C.is_new_segment;
|
|
1158
|
+
oe && await at(oe, fe, Ee);
|
|
1143
1159
|
break;
|
|
1144
1160
|
}
|
|
1145
1161
|
case "done": {
|
|
1146
|
-
|
|
1162
|
+
Z = !0, v("Ready"), E(!1);
|
|
1147
1163
|
break;
|
|
1148
1164
|
}
|
|
1149
1165
|
case "error": {
|
|
1150
|
-
|
|
1166
|
+
Z = !0, v("STT Failed"), E(!1);
|
|
1151
1167
|
break;
|
|
1152
1168
|
}
|
|
1153
1169
|
default:
|
|
@@ -1155,37 +1171,37 @@ const yn = ({
|
|
|
1155
1171
|
}
|
|
1156
1172
|
};
|
|
1157
1173
|
for (; ; ) {
|
|
1158
|
-
const { done: se, value:
|
|
1159
|
-
|
|
1160
|
-
const
|
|
1174
|
+
const { done: se, value: C } = await L.read();
|
|
1175
|
+
C && (q += W.decode(C, { stream: !0 }));
|
|
1176
|
+
const oe = q.split(`
|
|
1161
1177
|
|
|
1162
1178
|
`);
|
|
1163
|
-
|
|
1164
|
-
for (const fe of
|
|
1165
|
-
const Ee =
|
|
1179
|
+
q = oe.pop() ?? "";
|
|
1180
|
+
for (const fe of oe) {
|
|
1181
|
+
const Ee = ze(fe);
|
|
1166
1182
|
Ee && await F(Ee.event, Ee.data);
|
|
1167
1183
|
}
|
|
1168
1184
|
if (se) {
|
|
1169
|
-
if (
|
|
1170
|
-
const fe =
|
|
1185
|
+
if (q.trim()) {
|
|
1186
|
+
const fe = ze(q.trim());
|
|
1171
1187
|
fe && await F(fe.event, fe.data);
|
|
1172
1188
|
}
|
|
1173
|
-
|
|
1189
|
+
Z || (v("Ready"), E(!1));
|
|
1174
1190
|
break;
|
|
1175
1191
|
}
|
|
1176
1192
|
}
|
|
1177
1193
|
};
|
|
1178
1194
|
} catch (t) {
|
|
1179
|
-
console.error("Audio Submission Error:", t),
|
|
1195
|
+
console.error("Audio Submission Error:", t), v("STT Failed"), E(!1);
|
|
1180
1196
|
}
|
|
1181
|
-
},
|
|
1182
|
-
e && e.preventDefault(), We(!1), Oe.current = "",
|
|
1183
|
-
},
|
|
1197
|
+
}, qt = async (e) => {
|
|
1198
|
+
e && e.preventDefault(), We(!1), Oe.current = "", me(""), !(!he || k) && await Gt(he);
|
|
1199
|
+
}, ze = (e) => {
|
|
1184
1200
|
const t = e.split(/\r?\n/);
|
|
1185
|
-
let
|
|
1186
|
-
for (const
|
|
1187
|
-
|
|
1188
|
-
if (!
|
|
1201
|
+
let i = "", o = "";
|
|
1202
|
+
for (const c of t)
|
|
1203
|
+
c.startsWith("event:") ? i = c.slice(6).trim() : c.startsWith("data:") && (o = c.slice(5).trim());
|
|
1204
|
+
if (!i) return null;
|
|
1189
1205
|
let n = {};
|
|
1190
1206
|
if (o)
|
|
1191
1207
|
try {
|
|
@@ -1193,55 +1209,55 @@ const yn = ({
|
|
|
1193
1209
|
} catch {
|
|
1194
1210
|
n = { raw: o };
|
|
1195
1211
|
}
|
|
1196
|
-
return { event:
|
|
1197
|
-
},
|
|
1212
|
+
return { event: i, data: n };
|
|
1213
|
+
}, At = (e, t) => {
|
|
1198
1214
|
switch (e) {
|
|
1199
1215
|
case "connected":
|
|
1200
|
-
|
|
1216
|
+
pe.current = "", Ce.current = !1;
|
|
1201
1217
|
break;
|
|
1202
1218
|
case "text": {
|
|
1203
|
-
const
|
|
1204
|
-
|
|
1219
|
+
const i = t.delta ?? "";
|
|
1220
|
+
i && vt(i);
|
|
1205
1221
|
break;
|
|
1206
1222
|
}
|
|
1207
1223
|
case "audio": {
|
|
1208
|
-
const
|
|
1209
|
-
|
|
1224
|
+
const i = t.chunk, o = t.visemes ?? [];
|
|
1225
|
+
i && at(i, o);
|
|
1210
1226
|
break;
|
|
1211
1227
|
}
|
|
1212
1228
|
case "done": {
|
|
1213
|
-
const
|
|
1214
|
-
...
|
|
1215
|
-
{ role: "user", content:
|
|
1229
|
+
const i = yt(), o = Oe.current.trim(), n = [
|
|
1230
|
+
...i,
|
|
1231
|
+
{ role: "user", content: he || "..." },
|
|
1216
1232
|
{ role: "assistant", content: o }
|
|
1217
1233
|
];
|
|
1218
|
-
|
|
1234
|
+
Bt(n), $e.current = [...x.current], v("Ready"), E(!1), X("");
|
|
1219
1235
|
break;
|
|
1220
1236
|
}
|
|
1221
1237
|
case "error": {
|
|
1222
|
-
const
|
|
1223
|
-
Oe.current =
|
|
1238
|
+
const i = t.message ?? "Unknown error";
|
|
1239
|
+
Oe.current = i, me(i), v("Agent Failed"), E(!1);
|
|
1224
1240
|
break;
|
|
1225
1241
|
}
|
|
1226
1242
|
}
|
|
1227
|
-
},
|
|
1228
|
-
|
|
1229
|
-
const t = `${
|
|
1230
|
-
|
|
1243
|
+
}, Gt = async (e) => {
|
|
1244
|
+
E(!0), v("Thinking..."), Oe.current = "", pe.current = "", Ce.current = !1, Ge(), xe.current = 0, s(0);
|
|
1245
|
+
const t = `${ut}/agent/chat?token=${encodeURIComponent(
|
|
1246
|
+
O
|
|
1231
1247
|
)}`;
|
|
1232
1248
|
try {
|
|
1233
|
-
const
|
|
1249
|
+
const i = yt();
|
|
1234
1250
|
let o = sessionStorage.getItem("STREAMOJI_LEADS_SESSION_LEAD_ID");
|
|
1235
|
-
o || (
|
|
1251
|
+
o || (rn(
|
|
1236
1252
|
"[CHAT] Session UID missing at send time! Generating emergency backup."
|
|
1237
1253
|
), o = "emergency-" + Math.random().toString(36).substring(7), sessionStorage.setItem("STREAMOJI_LEADS_SESSION_LEAD_ID", o));
|
|
1238
1254
|
const n = {
|
|
1239
|
-
history:
|
|
1255
|
+
history: i,
|
|
1240
1256
|
question: e,
|
|
1241
1257
|
lead_id: o
|
|
1242
1258
|
};
|
|
1243
|
-
|
|
1244
|
-
const
|
|
1259
|
+
V("[CHAT] Sending payload:", n);
|
|
1260
|
+
const c = await fetch(t, {
|
|
1245
1261
|
method: "POST",
|
|
1246
1262
|
headers: {
|
|
1247
1263
|
"Content-Type": "application/json"
|
|
@@ -1249,75 +1265,75 @@ const yn = ({
|
|
|
1249
1265
|
body: JSON.stringify(n),
|
|
1250
1266
|
cache: "default"
|
|
1251
1267
|
});
|
|
1252
|
-
if (
|
|
1268
|
+
if (c.status === 429) {
|
|
1253
1269
|
try {
|
|
1254
|
-
const
|
|
1255
|
-
|
|
1270
|
+
const L = await c.json();
|
|
1271
|
+
V("[CHAT] 429 agent at capacity:", L?.detail);
|
|
1256
1272
|
} catch {
|
|
1257
1273
|
}
|
|
1258
|
-
|
|
1274
|
+
X(""), v("Busy"), E(!1);
|
|
1259
1275
|
return;
|
|
1260
1276
|
}
|
|
1261
|
-
if (!
|
|
1277
|
+
if (!c.ok)
|
|
1262
1278
|
throw new Error("Agent request failed");
|
|
1263
|
-
const
|
|
1264
|
-
if (!
|
|
1265
|
-
|
|
1279
|
+
const h = c.body;
|
|
1280
|
+
if (!h) {
|
|
1281
|
+
v("Agent Failed"), E(!1);
|
|
1266
1282
|
return;
|
|
1267
1283
|
}
|
|
1268
|
-
const
|
|
1269
|
-
|
|
1270
|
-
const
|
|
1271
|
-
let
|
|
1284
|
+
const _ = h.getReader();
|
|
1285
|
+
u.current = !1;
|
|
1286
|
+
const A = new TextDecoder();
|
|
1287
|
+
let R = "";
|
|
1272
1288
|
for (; ; ) {
|
|
1273
|
-
const { done:
|
|
1274
|
-
|
|
1275
|
-
`[SSE] Chunk received. done=${
|
|
1276
|
-
),
|
|
1277
|
-
const
|
|
1289
|
+
const { done: L, value: W } = await _.read();
|
|
1290
|
+
V(
|
|
1291
|
+
`[SSE] Chunk received. done=${L}, length=${W?.length || 0}`
|
|
1292
|
+
), W && (R += A.decode(W, { stream: !0 }));
|
|
1293
|
+
const q = R.split(`
|
|
1278
1294
|
|
|
1279
1295
|
`);
|
|
1280
|
-
|
|
1281
|
-
for (const
|
|
1282
|
-
|
|
1283
|
-
const F =
|
|
1284
|
-
F && (
|
|
1296
|
+
R = q.pop() ?? "";
|
|
1297
|
+
for (const Z of q) {
|
|
1298
|
+
V(`[SSE] Processing block: ${Z.slice(0, 50)}...`);
|
|
1299
|
+
const F = ze(Z);
|
|
1300
|
+
F && (V(`[SSE] Event: ${F.event}`), At(F.event, F.data));
|
|
1285
1301
|
}
|
|
1286
|
-
if (
|
|
1287
|
-
if (
|
|
1288
|
-
const
|
|
1289
|
-
|
|
1302
|
+
if (L) {
|
|
1303
|
+
if (V("[SSE] Stream finished"), R.trim()) {
|
|
1304
|
+
const Z = ze(R.trim());
|
|
1305
|
+
Z && At(Z.event, Z.data);
|
|
1290
1306
|
}
|
|
1291
|
-
|
|
1307
|
+
v("Ready"), E(!1), X("");
|
|
1292
1308
|
break;
|
|
1293
1309
|
}
|
|
1294
1310
|
}
|
|
1295
|
-
} catch (
|
|
1296
|
-
console.error("Chat Error:",
|
|
1311
|
+
} catch (i) {
|
|
1312
|
+
console.error("Chat Error:", i), v("Agent Failed"), E(!1);
|
|
1297
1313
|
}
|
|
1298
|
-
}, Rt =
|
|
1314
|
+
}, Rt = D.trim(), ct = Rt && U ? Rt.slice(
|
|
1299
1315
|
0,
|
|
1300
1316
|
d != null && d > 0 ? d : 0
|
|
1301
1317
|
) : "";
|
|
1302
|
-
|
|
1303
|
-
const e =
|
|
1304
|
-
e !== "exiting" && (
|
|
1305
|
-
}, [
|
|
1306
|
-
const
|
|
1307
|
-
const e =
|
|
1308
|
-
e === "entering" ?
|
|
1318
|
+
$(() => {
|
|
1319
|
+
const e = et.current;
|
|
1320
|
+
e !== "exiting" && (ct ? (Ot(ct), e === "hidden" && je("entering")) : (e === "visible" || e === "entering") && je("exiting"));
|
|
1321
|
+
}, [ct, ue]);
|
|
1322
|
+
const zt = Ye(() => {
|
|
1323
|
+
const e = et.current;
|
|
1324
|
+
e === "entering" ? je("visible") : e === "exiting" && je("hidden");
|
|
1309
1325
|
}, []);
|
|
1310
|
-
return
|
|
1311
|
-
const e =
|
|
1326
|
+
return en(() => {
|
|
1327
|
+
const e = mt.current;
|
|
1312
1328
|
e && (e.scrollTop = e.scrollHeight);
|
|
1313
|
-
}, [
|
|
1314
|
-
/* @__PURE__ */
|
|
1315
|
-
|
|
1329
|
+
}, [pt]), /* @__PURE__ */ ae("div", { className: "avatar-widget-container", children: [
|
|
1330
|
+
/* @__PURE__ */ ae("div", { className: "avatar-input-area", children: [
|
|
1331
|
+
_e !== "hidden" ? /* @__PURE__ */ l(
|
|
1316
1332
|
"div",
|
|
1317
1333
|
{
|
|
1318
|
-
className: `avatar-thinking-tab${
|
|
1319
|
-
onAnimationEnd:
|
|
1320
|
-
children:
|
|
1334
|
+
className: `avatar-thinking-tab${_e === "exiting" ? " avatar-thinking-tab--exiting" : _e === "entering" ? " avatar-thinking-tab--entering" : ""}`,
|
|
1335
|
+
onAnimationEnd: Dt,
|
|
1336
|
+
children: Re === Mt ? /* @__PURE__ */ l(
|
|
1321
1337
|
"a",
|
|
1322
1338
|
{
|
|
1323
1339
|
href: "https://leads.streamoji.com",
|
|
@@ -1325,7 +1341,7 @@ const yn = ({
|
|
|
1325
1341
|
rel: "noopener noreferrer",
|
|
1326
1342
|
children: "Made by Streamoji Leads"
|
|
1327
1343
|
}
|
|
1328
|
-
) :
|
|
1344
|
+
) : Re
|
|
1329
1345
|
}
|
|
1330
1346
|
) : null,
|
|
1331
1347
|
/* @__PURE__ */ l("div", { className: "avatar-input-container", children: /* @__PURE__ */ l(
|
|
@@ -1337,7 +1353,7 @@ const yn = ({
|
|
|
1337
1353
|
width: "100%",
|
|
1338
1354
|
height: "100%"
|
|
1339
1355
|
},
|
|
1340
|
-
children:
|
|
1356
|
+
children: rt ? /* @__PURE__ */ ae("div", { className: "avatar-input-recording", children: [
|
|
1341
1357
|
/* @__PURE__ */ l(
|
|
1342
1358
|
"button",
|
|
1343
1359
|
{
|
|
@@ -1345,7 +1361,7 @@ const yn = ({
|
|
|
1345
1361
|
className: "avatar-recording-cancel",
|
|
1346
1362
|
onClick: Ht,
|
|
1347
1363
|
title: "Cancel",
|
|
1348
|
-
children: /* @__PURE__ */
|
|
1364
|
+
children: /* @__PURE__ */ ae(
|
|
1349
1365
|
"svg",
|
|
1350
1366
|
{
|
|
1351
1367
|
width: "18",
|
|
@@ -1365,7 +1381,7 @@ const yn = ({
|
|
|
1365
1381
|
)
|
|
1366
1382
|
}
|
|
1367
1383
|
),
|
|
1368
|
-
/* @__PURE__ */
|
|
1384
|
+
/* @__PURE__ */ ae(
|
|
1369
1385
|
"div",
|
|
1370
1386
|
{
|
|
1371
1387
|
style: {
|
|
@@ -1377,8 +1393,8 @@ const yn = ({
|
|
|
1377
1393
|
minWidth: 0
|
|
1378
1394
|
},
|
|
1379
1395
|
children: [
|
|
1380
|
-
/* @__PURE__ */ l("div", { style: { flex: 1, height: "100%" }, children: /* @__PURE__ */ l(
|
|
1381
|
-
/* @__PURE__ */
|
|
1396
|
+
/* @__PURE__ */ l("div", { style: { flex: 1, height: "100%" }, children: /* @__PURE__ */ l(Et, { analyser: Wt }) }),
|
|
1397
|
+
/* @__PURE__ */ ae(
|
|
1382
1398
|
"span",
|
|
1383
1399
|
{
|
|
1384
1400
|
style: {
|
|
@@ -1391,9 +1407,9 @@ const yn = ({
|
|
|
1391
1407
|
fontVariantNumeric: "tabular-nums"
|
|
1392
1408
|
},
|
|
1393
1409
|
children: [
|
|
1394
|
-
Math.floor(
|
|
1410
|
+
Math.floor(St / 60),
|
|
1395
1411
|
":",
|
|
1396
|
-
String(
|
|
1412
|
+
String(St % 60).padStart(2, "0")
|
|
1397
1413
|
]
|
|
1398
1414
|
}
|
|
1399
1415
|
)
|
|
@@ -1405,7 +1421,7 @@ const yn = ({
|
|
|
1405
1421
|
{
|
|
1406
1422
|
type: "button",
|
|
1407
1423
|
className: "avatar-recording-confirm",
|
|
1408
|
-
onClick:
|
|
1424
|
+
onClick: $t,
|
|
1409
1425
|
title: "Send",
|
|
1410
1426
|
children: /* @__PURE__ */ l(
|
|
1411
1427
|
"svg",
|
|
@@ -1424,7 +1440,7 @@ const yn = ({
|
|
|
1424
1440
|
)
|
|
1425
1441
|
}
|
|
1426
1442
|
)
|
|
1427
|
-
] }) :
|
|
1443
|
+
] }) : U && !nt ? /* @__PURE__ */ ae("div", { className: "avatar-input-speaking", children: [
|
|
1428
1444
|
/* @__PURE__ */ l(
|
|
1429
1445
|
"div",
|
|
1430
1446
|
{
|
|
@@ -1435,7 +1451,7 @@ const yn = ({
|
|
|
1435
1451
|
alignItems: "center",
|
|
1436
1452
|
paddingRight: "8px"
|
|
1437
1453
|
},
|
|
1438
|
-
children: /* @__PURE__ */ l(
|
|
1454
|
+
children: /* @__PURE__ */ l(Et, { analyser: kt })
|
|
1439
1455
|
}
|
|
1440
1456
|
),
|
|
1441
1457
|
/* @__PURE__ */ l(
|
|
@@ -1443,12 +1459,12 @@ const yn = ({
|
|
|
1443
1459
|
{
|
|
1444
1460
|
type: "button",
|
|
1445
1461
|
className: "avatar-speaking-stop",
|
|
1446
|
-
onClick: () =>
|
|
1462
|
+
onClick: () => Ge(!0),
|
|
1447
1463
|
title: "Stop",
|
|
1448
1464
|
children: /* @__PURE__ */ l("span", { className: "avatar-speaking-stop__icon", "aria-hidden": !0 })
|
|
1449
1465
|
}
|
|
1450
1466
|
)
|
|
1451
|
-
] }) :
|
|
1467
|
+
] }) : k ? /* @__PURE__ */ l(
|
|
1452
1468
|
"div",
|
|
1453
1469
|
{
|
|
1454
1470
|
style: {
|
|
@@ -1460,10 +1476,10 @@ const yn = ({
|
|
|
1460
1476
|
},
|
|
1461
1477
|
children: /* @__PURE__ */ l("div", { className: "avatar-input-loader" })
|
|
1462
1478
|
}
|
|
1463
|
-
) : /* @__PURE__ */
|
|
1479
|
+
) : /* @__PURE__ */ ae(
|
|
1464
1480
|
"form",
|
|
1465
1481
|
{
|
|
1466
|
-
onSubmit:
|
|
1482
|
+
onSubmit: qt,
|
|
1467
1483
|
style: {
|
|
1468
1484
|
flex: 1,
|
|
1469
1485
|
display: "flex",
|
|
@@ -1476,15 +1492,15 @@ const yn = ({
|
|
|
1476
1492
|
{
|
|
1477
1493
|
id: "avatar-text-input",
|
|
1478
1494
|
type: "text",
|
|
1479
|
-
value:
|
|
1480
|
-
onChange: (e) =>
|
|
1481
|
-
placeholder:
|
|
1482
|
-
disabled:
|
|
1495
|
+
value: he,
|
|
1496
|
+
onChange: (e) => X(e.target.value),
|
|
1497
|
+
placeholder: I === "Busy" ? "Assisting another user" : Ne || "Ask me anything",
|
|
1498
|
+
disabled: k || I === "Busy",
|
|
1483
1499
|
autoComplete: "off",
|
|
1484
1500
|
style: { width: "100%", height: "100%" }
|
|
1485
1501
|
}
|
|
1486
1502
|
),
|
|
1487
|
-
|
|
1503
|
+
I === "Busy" ? /* @__PURE__ */ l(
|
|
1488
1504
|
"button",
|
|
1489
1505
|
{
|
|
1490
1506
|
type: "button",
|
|
@@ -1511,15 +1527,15 @@ const yn = ({
|
|
|
1511
1527
|
}
|
|
1512
1528
|
)
|
|
1513
1529
|
}
|
|
1514
|
-
) :
|
|
1530
|
+
) : he.trim() === "" ? /* @__PURE__ */ l(
|
|
1515
1531
|
"button",
|
|
1516
1532
|
{
|
|
1517
1533
|
type: "button",
|
|
1518
1534
|
className: "mic-button",
|
|
1519
|
-
onClick:
|
|
1520
|
-
disabled:
|
|
1535
|
+
onClick: Vt,
|
|
1536
|
+
disabled: k,
|
|
1521
1537
|
style: { backgroundColor: "#1e4a5e" },
|
|
1522
|
-
children: /* @__PURE__ */
|
|
1538
|
+
children: /* @__PURE__ */ ae(
|
|
1523
1539
|
"svg",
|
|
1524
1540
|
{
|
|
1525
1541
|
width: "28",
|
|
@@ -1551,7 +1567,7 @@ const yn = ({
|
|
|
1551
1567
|
{
|
|
1552
1568
|
type: "submit",
|
|
1553
1569
|
className: "mic-button",
|
|
1554
|
-
disabled:
|
|
1570
|
+
disabled: k,
|
|
1555
1571
|
style: { backgroundColor: "#1e4a5e" },
|
|
1556
1572
|
title: "Send",
|
|
1557
1573
|
children: /* @__PURE__ */ l(
|
|
@@ -1582,22 +1598,22 @@ const yn = ({
|
|
|
1582
1598
|
}
|
|
1583
1599
|
) })
|
|
1584
1600
|
] }),
|
|
1585
|
-
/* @__PURE__ */ l("div", { className: "avatar-wrapper", children: /* @__PURE__ */
|
|
1601
|
+
/* @__PURE__ */ l("div", { className: "avatar-wrapper", children: /* @__PURE__ */ ae("div", { className: "avatar-scene-wrapper", children: [
|
|
1586
1602
|
ue !== "hidden" && /* @__PURE__ */ l(
|
|
1587
1603
|
"div",
|
|
1588
1604
|
{
|
|
1589
1605
|
className: `avatar-bubble${ue === "entering" ? " avatar-bubble--entering" : ue === "exiting" ? " avatar-bubble--exiting" : ""}`,
|
|
1590
|
-
onAnimationEnd:
|
|
1591
|
-
children: /* @__PURE__ */ l("div", { ref:
|
|
1606
|
+
onAnimationEnd: zt,
|
|
1607
|
+
children: /* @__PURE__ */ l("div", { ref: mt, className: `avatar-bubble__content${nt ? " avatar-bubble__content--nudge" : ""}`, children: pt })
|
|
1592
1608
|
}
|
|
1593
1609
|
),
|
|
1594
1610
|
/* @__PURE__ */ l(
|
|
1595
1611
|
"div",
|
|
1596
1612
|
{
|
|
1597
1613
|
className: "avatar-canvas-layer",
|
|
1598
|
-
style: { width:
|
|
1599
|
-
children: /* @__PURE__ */
|
|
1600
|
-
|
|
1614
|
+
style: { width: j, height: j },
|
|
1615
|
+
children: /* @__PURE__ */ ae(
|
|
1616
|
+
Xt,
|
|
1601
1617
|
{
|
|
1602
1618
|
shadows: !0,
|
|
1603
1619
|
camera: { position: [0.2, 1.4, 3], fov: 42 },
|
|
@@ -1605,30 +1621,30 @@ const yn = ({
|
|
|
1605
1621
|
dpr: 1.8,
|
|
1606
1622
|
style: { pointerEvents: "none", width: "100%", height: "100%" },
|
|
1607
1623
|
children: [
|
|
1608
|
-
/* @__PURE__ */ l(
|
|
1624
|
+
/* @__PURE__ */ l(wn, { target: hn }),
|
|
1609
1625
|
/* @__PURE__ */ l("ambientLight", { intensity: 0.7 }),
|
|
1610
1626
|
/* @__PURE__ */ l("directionalLight", { position: [0, 2, 2], intensity: 1 }),
|
|
1611
|
-
/* @__PURE__ */ l(
|
|
1612
|
-
/* @__PURE__ */ l(
|
|
1613
|
-
|
|
1627
|
+
/* @__PURE__ */ l(Yt, { preset: "city" }),
|
|
1628
|
+
/* @__PURE__ */ l(tn, { fallback: null, children: H !== null && /* @__PURE__ */ l(
|
|
1629
|
+
vn,
|
|
1614
1630
|
{
|
|
1615
|
-
avatarUrl:
|
|
1616
|
-
isPlayingRef:
|
|
1617
|
-
visemeQueueRef:
|
|
1618
|
-
audioContextRef:
|
|
1619
|
-
responseAudioStartTimeRef:
|
|
1620
|
-
adjustments:
|
|
1621
|
-
mood:
|
|
1622
|
-
expression:
|
|
1623
|
-
agentResponse:
|
|
1624
|
-
isSpeaking:
|
|
1625
|
-
nextStartTimeRef:
|
|
1626
|
-
stopPlayback:
|
|
1627
|
-
setIsSpeaking:
|
|
1631
|
+
avatarUrl: H,
|
|
1632
|
+
isPlayingRef: S,
|
|
1633
|
+
visemeQueueRef: x,
|
|
1634
|
+
audioContextRef: ye,
|
|
1635
|
+
responseAudioStartTimeRef: re,
|
|
1636
|
+
adjustments: fn,
|
|
1637
|
+
mood: m,
|
|
1638
|
+
expression: K,
|
|
1639
|
+
agentResponse: D,
|
|
1640
|
+
isSpeaking: U,
|
|
1641
|
+
nextStartTimeRef: Se,
|
|
1642
|
+
stopPlayback: Ge,
|
|
1643
|
+
setIsSpeaking: be,
|
|
1628
1644
|
expressionUrl: Ke,
|
|
1629
|
-
onExpressionFinished:
|
|
1630
|
-
isNudgeResponse:
|
|
1631
|
-
avatarGender:
|
|
1645
|
+
onExpressionFinished: Ut,
|
|
1646
|
+
isNudgeResponse: nt,
|
|
1647
|
+
avatarGender: p
|
|
1632
1648
|
}
|
|
1633
1649
|
) })
|
|
1634
1650
|
]
|
|
@@ -1638,17 +1654,17 @@ const yn = ({
|
|
|
1638
1654
|
)
|
|
1639
1655
|
] }) })
|
|
1640
1656
|
] });
|
|
1641
|
-
},
|
|
1657
|
+
}, Tn = ({
|
|
1642
1658
|
token: f,
|
|
1643
|
-
onNavigationRequested:
|
|
1659
|
+
onNavigationRequested: T
|
|
1644
1660
|
}) => /* @__PURE__ */ l(
|
|
1645
|
-
|
|
1661
|
+
Sn,
|
|
1646
1662
|
{
|
|
1647
1663
|
token: f,
|
|
1648
|
-
onNavigationRequested:
|
|
1664
|
+
onNavigationRequested: T
|
|
1649
1665
|
}
|
|
1650
1666
|
);
|
|
1651
1667
|
export {
|
|
1652
|
-
|
|
1668
|
+
Tn as AvatarWidget
|
|
1653
1669
|
};
|
|
1654
1670
|
//# sourceMappingURL=avatar-widget.js.map
|