@streamoji/avatar-widget 0.2.4 → 0.2.5

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