@sage-rsc/talking-head-react 1.0.67 → 1.0.68

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/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { jsxs as De, jsx as ge } from "react/jsx-runtime";
2
- import { forwardRef as ze, useRef as N, useState as be, useEffect as ve, useCallback as M, useImperativeHandle as Ce, useLayoutEffect as Xe } from "react";
2
+ import { forwardRef as ze, useRef as N, useState as be, useEffect as Re, useCallback as M, useImperativeHandle as Ce, useLayoutEffect as Xe } from "react";
3
3
  import * as f from "three";
4
4
  import { OrbitControls as Ye } from "three/addons/controls/OrbitControls.js";
5
5
  import { GLTFLoader as je } from "three/addons/loaders/GLTFLoader.js";
@@ -202,7 +202,7 @@ class et {
202
202
  deltaLocal: null
203
203
  };
204
204
  if (s.deltaLocal) {
205
- if (!Array.isArray(s.deltaLocal) || s.deltaLocal.length !== 3 || s.deltaLocal.some((a) => Number.isNaN(a))) throw new Error("deltaLocal must be an array of three numbers in #" + o + " exclude.");
205
+ if (!Array.isArray(s.deltaLocal) || s.deltaLocal.length !== 3 || s.deltaLocal.some((r) => Number.isNaN(r))) throw new Error("deltaLocal must be an array of three numbers in #" + o + " exclude.");
206
206
  u.deltaLocal = [...s.deltaLocal];
207
207
  }
208
208
  i.excludes.push(u);
@@ -310,22 +310,22 @@ class et {
310
310
  i(s.bone, l + "Bone not specified.");
311
311
  const u = s.bone;
312
312
  i(typeof u == "string" && u.length > 0, l + "Bone name must be a non-empty string.");
313
- const a = this.armature.getObjectByName(u);
314
- i(a, l + "Bone '" + u + "' not found."), i(a.parent?.isBone, l + "Bone must have a parent bone."), i(this.data.every((r) => r.bone !== a), l + "Bone '" + u + "' already exists."), a.updateMatrixWorld(!0);
313
+ const r = this.armature.getObjectByName(u);
314
+ i(r, l + "Bone '" + u + "' not found."), i(r.parent?.isBone, l + "Bone must have a parent bone."), i(this.data.every((a) => a.bone !== r), l + "Bone '" + u + "' already exists."), r.updateMatrixWorld(!0);
315
315
  const h = {
316
316
  name: u,
317
317
  // Bone name
318
- bone: a,
318
+ bone: r,
319
319
  // Bone object
320
- boneParent: a.parent,
320
+ boneParent: r.parent,
321
321
  /// Bone's parent object
322
- vBasis: a.position.clone(),
322
+ vBasis: r.position.clone(),
323
323
  // Original local position
324
- vWorld: a.parent.getWorldPosition(k).clone(),
324
+ vWorld: r.parent.getWorldPosition(k).clone(),
325
325
  // World position, parent
326
- qBasis: a.parent.quaternion.clone(),
326
+ qBasis: r.parent.quaternion.clone(),
327
327
  // Original quaternion, parent
328
- l: a.position.length(),
328
+ l: r.position.length(),
329
329
  // Bone length
330
330
  p: [0, 0, 0, 0],
331
331
  // Relative position [m]
@@ -341,8 +341,8 @@ class et {
341
341
  h.boneParent.matrixWorld.decompose(k, K, _), k.copy(ke).applyQuaternion(K).setY(0).normalize(), K.premultiply(Ee.setFromUnitVectors(ke, k).invert()).normalize(), h.qWorldInverseYaw = K.clone().normalize(), this.data.push(h), this.dict[u] = h;
342
342
  try {
343
343
  this.setValue(u, "type", s.type), this.setValue(u, "stiffness", s.stiffness), this.setValue(u, "damping", s.damping), this.setValue(u, "external", s.external), this.setValue(u, "limits", s.limits), this.setValue(u, "excludes", s.excludes), this.setValue(u, "deltaLocal", s.deltaLocal), this.setValue(u, "deltaWorld", s.deltaWorld), this.setValue(u, "pivot", s.pivot), this.setValue(u, "helper", s.helper);
344
- } catch (r) {
345
- i(!1, l + r);
344
+ } catch (a) {
345
+ i(!1, l + a);
346
346
  }
347
347
  }), this.sortBones(), this.start();
348
348
  }
@@ -519,8 +519,8 @@ class tt {
519
519
  phonemeBoundaries: []
520
520
  }, i = 1024, s = 512, o = Math.floor((t.length - i) / s) + 1;
521
521
  for (let l = 0; l < o; l++) {
522
- const u = l * s, a = Math.min(u + i, t.length), h = t.slice(u, a), r = this.calculateEnergy(h);
523
- n.energy.push(r);
522
+ const u = l * s, r = Math.min(u + i, t.length), h = t.slice(u, r), a = this.calculateEnergy(h);
523
+ n.energy.push(a);
524
524
  const c = this.calculateSpectralCentroid(h);
525
525
  n.spectralCentroid.push(c);
526
526
  const d = this.calculateZeroCrossingRate(h);
@@ -604,12 +604,12 @@ class tt {
604
604
  for (let i = 2; i <= e; i <<= 1) {
605
605
  const s = -2 * Math.PI / i, o = Math.cos(s), l = Math.sin(s);
606
606
  for (let u = 0; u < e; u += i) {
607
- let a = 1, h = 0;
608
- for (let r = 0; r < i / 2; r++) {
609
- const c = n[(u + r) * 2], d = n[(u + r) * 2 + 1], g = n[(u + r + i / 2) * 2] * a - n[(u + r + i / 2) * 2 + 1] * h, y = n[(u + r + i / 2) * 2] * h + n[(u + r + i / 2) * 2 + 1] * a;
610
- n[(u + r) * 2] = c + g, n[(u + r) * 2 + 1] = d + y, n[(u + r + i / 2) * 2] = c - g, n[(u + r + i / 2) * 2 + 1] = d - y;
611
- const x = a * o - h * l, I = a * l + h * o;
612
- a = x, h = I;
607
+ let r = 1, h = 0;
608
+ for (let a = 0; a < i / 2; a++) {
609
+ const c = n[(u + a) * 2], d = n[(u + a) * 2 + 1], g = n[(u + a + i / 2) * 2] * r - n[(u + a + i / 2) * 2 + 1] * h, y = n[(u + a + i / 2) * 2] * h + n[(u + a + i / 2) * 2 + 1] * r;
610
+ n[(u + a) * 2] = c + g, n[(u + a) * 2 + 1] = d + y, n[(u + a + i / 2) * 2] = c - g, n[(u + a + i / 2) * 2 + 1] = d - y;
611
+ const x = r * o - h * l, I = r * l + h * o;
612
+ r = x, h = I;
613
613
  }
614
614
  }
615
615
  }
@@ -637,8 +637,8 @@ class tt {
637
637
  detectPhonemeBoundaries(t) {
638
638
  const e = [], { energy: n, spectralCentroid: i, zeroCrossingRate: s } = t;
639
639
  for (let o = 1; o < n.length; o++) {
640
- const l = o * 0.023, u = Math.abs(n[o] - n[o - 1]), a = Math.abs(i[o] - i[o - 1]), h = Math.abs(s[o] - s[o - 1]);
641
- u + a * 0.1 + h * 0.5 > 0.2 && e.push(l);
640
+ const l = o * 0.023, u = Math.abs(n[o] - n[o - 1]), r = Math.abs(i[o] - i[o - 1]), h = Math.abs(s[o] - s[o - 1]);
641
+ u + r * 0.1 + h * 0.5 > 0.2 && e.push(l);
642
642
  }
643
643
  return e;
644
644
  }
@@ -655,9 +655,9 @@ class tt {
655
655
  const s = [];
656
656
  let o = 0;
657
657
  for (let u = 0; u < i.length; u++) {
658
- const a = i[u], h = this.estimateWordDuration(a, n / i.length);
658
+ const r = i[u], h = this.estimateWordDuration(r, n / i.length);
659
659
  s.push({
660
- word: a,
660
+ word: r,
661
661
  startTime: o,
662
662
  endTime: o + h,
663
663
  duration: h
@@ -702,10 +702,10 @@ class tt {
702
702
  t.onsets;
703
703
  const o = this.textToVisemes(e);
704
704
  let l = 0, u = 0;
705
- for (let a = 0; a < s.length && l < o.length; a++) {
706
- const h = s[a], r = o[l], c = t.energy[Math.floor(h / 0.023)] || 0, d = this.calculateVisemeDuration(r, c);
705
+ for (let r = 0; r < s.length && l < o.length; r++) {
706
+ const h = s[r], a = o[l], c = t.energy[Math.floor(h / 0.023)] || 0, d = this.calculateVisemeDuration(a, c);
707
707
  i.push({
708
- viseme: r,
708
+ viseme: a,
709
709
  startTime: u,
710
710
  endTime: u + d,
711
711
  duration: d,
@@ -714,9 +714,9 @@ class tt {
714
714
  }), u += d, l++;
715
715
  }
716
716
  for (; l < o.length; ) {
717
- const a = o[l], h = this.calculateVisemeDuration(a, 0.5);
717
+ const r = o[l], h = this.calculateVisemeDuration(r, 0.5);
718
718
  i.push({
719
- viseme: a,
719
+ viseme: r,
720
720
  startTime: u,
721
721
  endTime: u + h,
722
722
  duration: h,
@@ -776,9 +776,9 @@ class tt {
776
776
  for (; o < s.length; ) {
777
777
  let l = !1;
778
778
  for (let u = 3; u >= 2; u--) {
779
- const a = s.substr(o, u);
780
- if (e[a]) {
781
- n.push(e[a]), o += u, l = !0;
779
+ const r = s.substr(o, u);
780
+ if (e[r]) {
781
+ n.push(e[r]), o += u, l = !0;
782
782
  break;
783
783
  }
784
784
  }
@@ -1206,13 +1206,13 @@ class nt {
1206
1206
  };
1207
1207
  Object.keys(this.rules).forEach((e) => {
1208
1208
  this.rules[e] = this.rules[e].map((n) => {
1209
- const i = n.indexOf("["), s = n.indexOf("]"), o = n.indexOf("="), l = n.substring(0, i), u = n.substring(i + 1, s), a = n.substring(s + 1, o), h = n.substring(o + 1), r = { regex: "", move: 0, visemes: [] };
1209
+ const i = n.indexOf("["), s = n.indexOf("]"), o = n.indexOf("="), l = n.substring(0, i), u = n.substring(i + 1, s), r = n.substring(s + 1, o), h = n.substring(o + 1), a = { regex: "", move: 0, visemes: [] };
1210
1210
  let c = "";
1211
1211
  c += [...l].map((g) => t[g] || g).join("");
1212
1212
  const d = [...u];
1213
- return d[0] = d[0].toLowerCase(), c += d.join(""), r.move = d.length, c += [...a].map((g) => t[g] || g).join(""), r.regex = new RegExp(c), h.length && h.split(" ").forEach((g) => {
1214
- r.visemes.push(g);
1215
- }), r;
1213
+ return d[0] = d[0].toLowerCase(), c += d.join(""), a.move = d.length, c += [...r].map((g) => t[g] || g).join(""), a.regex = new RegExp(c), h.length && h.split(" ").forEach((g) => {
1214
+ a.visemes.push(g);
1215
+ }), a;
1216
1216
  });
1217
1217
  }), this.visemeDurations = {
1218
1218
  aa: 0.95,
@@ -1378,13 +1378,13 @@ class nt {
1378
1378
  for (let l = 0; l < o.length; l++) {
1379
1379
  const u = o[l];
1380
1380
  if ((e.words.substring(0, e.i) + s.toLowerCase() + e.words.substring(e.i + 1)).match(u.regex)) {
1381
- u.visemes.forEach((r) => {
1382
- if (e.visemes.length && e.visemes[e.visemes.length - 1] === r) {
1383
- const c = 0.7 * (this.visemeDurations[r] || 1);
1381
+ u.visemes.forEach((a) => {
1382
+ if (e.visemes.length && e.visemes[e.visemes.length - 1] === a) {
1383
+ const c = 0.7 * (this.visemeDurations[a] || 1);
1384
1384
  e.durations[e.durations.length - 1] += c, n += c;
1385
1385
  } else {
1386
- const c = this.visemeDurations[r] || 1;
1387
- e.visemes.push(r), e.times.push(n), e.durations.push(c), n += c;
1386
+ const c = this.visemeDurations[a] || 1;
1387
+ e.visemes.push(a), e.times.push(n), e.durations.push(c), n += c;
1388
1388
  }
1389
1389
  }), e.i += u.move;
1390
1390
  break;
@@ -1616,13 +1616,13 @@ class ot {
1616
1616
  };
1617
1617
  Object.keys(this.rules).forEach((e) => {
1618
1618
  this.rules[e] = this.rules[e].map((n) => {
1619
- const i = n.indexOf("["), s = n.indexOf("]"), o = n.indexOf("="), l = n.substring(0, i), u = n.substring(i + 1, s), a = n.substring(s + 1, o), h = n.substring(o + 1), r = { regex: "", move: 0, visemes: [] };
1619
+ const i = n.indexOf("["), s = n.indexOf("]"), o = n.indexOf("="), l = n.substring(0, i), u = n.substring(i + 1, s), r = n.substring(s + 1, o), h = n.substring(o + 1), a = { regex: "", move: 0, visemes: [] };
1620
1620
  let c = "";
1621
1621
  c += [...l].map((g) => t[g] || g).join("");
1622
1622
  const d = [...u];
1623
- return d[0] = d[0].toLowerCase(), c += d.join(""), r.move = d.length, c += [...a].map((g) => t[g] || g).join(""), r.regex = new RegExp(c), h.length && h.split(" ").forEach((g) => {
1624
- r.visemes.push(g);
1625
- }), r;
1623
+ return d[0] = d[0].toLowerCase(), c += d.join(""), a.move = d.length, c += [...r].map((g) => t[g] || g).join(""), a.regex = new RegExp(c), h.length && h.split(" ").forEach((g) => {
1624
+ a.visemes.push(g);
1625
+ }), a;
1626
1626
  });
1627
1627
  }), this.visemeDurations = {
1628
1628
  aa: 1,
@@ -1733,9 +1733,9 @@ class ot {
1733
1733
  if (o) {
1734
1734
  let l = !1;
1735
1735
  for (let u = 0; u < o.length; u++) {
1736
- const a = o[u];
1737
- if ((e.words.substring(0, e.i) + s.toLowerCase() + e.words.substring(e.i + 1)).match(a.regex)) {
1738
- a.visemes.forEach((c) => {
1736
+ const r = o[u];
1737
+ if ((e.words.substring(0, e.i) + s.toLowerCase() + e.words.substring(e.i + 1)).match(r.regex)) {
1738
+ r.visemes.forEach((c) => {
1739
1739
  if (e.visemes.length && e.visemes[e.visemes.length - 1] === c) {
1740
1740
  const d = 0.7 * (this.visemeDurations[c] || 1);
1741
1741
  e.durations[e.durations.length - 1] += d, n += d;
@@ -1743,7 +1743,7 @@ class ot {
1743
1743
  const d = this.visemeDurations[c] || 1;
1744
1744
  e.visemes.push(c), e.times.push(n), e.durations.push(d), n += d;
1745
1745
  }
1746
- }), e.i += a.move, l = !0;
1746
+ }), e.i += r.move, l = !0;
1747
1747
  break;
1748
1748
  }
1749
1749
  }
@@ -2131,13 +2131,13 @@ class at {
2131
2131
  };
2132
2132
  Object.keys(this.rules).forEach((e) => {
2133
2133
  this.rules[e] = this.rules[e].map((n) => {
2134
- const i = n.indexOf("["), s = n.indexOf("]"), o = n.indexOf("="), l = n.substring(0, i), u = n.substring(i + 1, s), a = n.substring(s + 1, o), h = n.substring(o + 1), r = { regex: "", move: 0, visemes: [] };
2134
+ const i = n.indexOf("["), s = n.indexOf("]"), o = n.indexOf("="), l = n.substring(0, i), u = n.substring(i + 1, s), r = n.substring(s + 1, o), h = n.substring(o + 1), a = { regex: "", move: 0, visemes: [] };
2135
2135
  let c = "";
2136
2136
  c += [...l].map((g) => t[g] || g).join("");
2137
2137
  const d = [...u];
2138
- return d[0] = d[0].toLowerCase(), c += d.join(""), r.move = d.length, c += [...a].map((g) => t[g] || g).join(""), r.regex = new RegExp(c, "i"), h.length && h.split(" ").forEach((g) => {
2139
- g && r.visemes.push(g);
2140
- }), r;
2138
+ return d[0] = d[0].toLowerCase(), c += d.join(""), a.move = d.length, c += [...r].map((g) => t[g] || g).join(""), a.regex = new RegExp(c, "i"), h.length && h.split(" ").forEach((g) => {
2139
+ g && a.visemes.push(g);
2140
+ }), a;
2141
2141
  });
2142
2142
  }), this.visemeDurations = {
2143
2143
  aa: 1,
@@ -2268,9 +2268,9 @@ class at {
2268
2268
  if (o) {
2269
2269
  let l = !1;
2270
2270
  for (let u = 0; u < o.length; u++) {
2271
- const a = o[u];
2272
- if ((e.words.substring(0, e.i) + s.toLowerCase() + e.words.substring(e.i + 1)).match(a.regex)) {
2273
- a.visemes.forEach((c) => {
2271
+ const r = o[u];
2272
+ if ((e.words.substring(0, e.i) + s.toLowerCase() + e.words.substring(e.i + 1)).match(r.regex)) {
2273
+ r.visemes.forEach((c) => {
2274
2274
  if (e.visemes.length && e.visemes[e.visemes.length - 1] === c) {
2275
2275
  const d = 0.7 * (this.visemeDurations[c] || 1);
2276
2276
  e.durations[e.durations.length - 1] += d, n += d;
@@ -2278,7 +2278,7 @@ class at {
2278
2278
  const d = this.visemeDurations[c] || 1;
2279
2279
  e.visemes.push(c), e.times.push(n), e.durations.push(d), n += d;
2280
2280
  }
2281
- }), e.i += a.move, l = !0;
2281
+ }), e.i += r.move, l = !0;
2282
2282
  break;
2283
2283
  }
2284
2284
  }
@@ -2381,10 +2381,10 @@ class lt {
2381
2381
  const e = [];
2382
2382
  let n = parseFloat(t);
2383
2383
  if (n === void 0) return t;
2384
- let i = (s, o, l, u, a) => {
2384
+ let i = (s, o, l, u, r) => {
2385
2385
  if (s < o) return s;
2386
2386
  const h = Math.floor(s / o);
2387
- return e.push(l + (h === 1 ? u : this.numberToFinnishWords(h.toString()) + a)), s - h * o;
2387
+ return e.push(l + (h === 1 ? u : this.numberToFinnishWords(h.toString()) + r)), s - h * o;
2388
2388
  };
2389
2389
  if (n < 0 && (e.push("miinus "), n = Math.abs(n)), n = i(n, 1e9, " ", "miljardi", " miljardia"), n = i(n, 1e6, " ", "miljoona", " miljoonaa"), n = i(n, 1e3, "", "tuhat", "tuhatta"), n = i(n, 100, " ", "sata", "sataa"), n > 20 && (n = i(n, 10, "", "", "kymmentä")), n >= 1) {
2390
2390
  let s = Math.floor(n);
@@ -2559,10 +2559,10 @@ class ut {
2559
2559
  const e = [];
2560
2560
  let n = parseFloat(t);
2561
2561
  if (n === void 0) return t;
2562
- let i = (s, o, l, u, a) => {
2562
+ let i = (s, o, l, u, r) => {
2563
2563
  if (s < o) return s;
2564
2564
  const h = Math.floor(s / o);
2565
- return h === 1 ? e.push(this.numbers[1]) : e.push(this.numberToLithuanianWords(h.toString())), h % 10 === 1 ? e.push(l) : h % 10 === 0 || h % 100 > 10 && h % 100 < 20 ? e.push(a) : e.push(u), s - h * o;
2565
+ return h === 1 ? e.push(this.numbers[1]) : e.push(this.numberToLithuanianWords(h.toString())), h % 10 === 1 ? e.push(l) : h % 10 === 0 || h % 100 > 10 && h % 100 < 20 ? e.push(r) : e.push(u), s - h * o;
2566
2566
  };
2567
2567
  n < 0 && (e.push("minus"), n = Math.abs(n)), n = i(n, 1e9, "milijardas", "milijardai", "milijardų"), n = i(n, 1e6, "milijonas", "milijonai", "milijonų"), n = i(n, 1e3, "tūkstantis", "tūkstančiai", "tūkstančių"), n = i(n, 100, "šimtas", "šimtai", "šimtų");
2568
2568
  for (let s = this.tens.length - 1; s >= 1; s--)
@@ -4078,8 +4078,8 @@ class Oe {
4078
4078
  RightHandMiddle1: "RightHand"
4079
4079
  }, o = [];
4080
4080
  Object.entries(s).forEach((l, u) => {
4081
- const a = new f.Bone();
4082
- a.name = l[0], l[1] ? this.ikMesh.getObjectByName(l[1]).add(a) : this.ikMesh.add(a), o.push(a);
4081
+ const r = new f.Bone();
4082
+ r.name = l[0], l[1] ? this.ikMesh.getObjectByName(l[1]).add(r) : this.ikMesh.add(r), o.push(r);
4083
4083
  }), this.ikMesh.bind(new f.Skeleton(o)), this.dynamicbones = new et(), this.isStreaming = !1, this.streamWorkletNode = null, this.streamAudioStartTime = null, this.streamWaitForAudioChunks = !0, this.streamLipsyncLang = null, this.streamLipsyncType = "visemes", this.streamLipsyncQueue = [];
4084
4084
  }
4085
4085
  /**
@@ -4126,9 +4126,9 @@ class Oe {
4126
4126
  let e = 3 * t.length / 4;
4127
4127
  t[t.length - 1] === "=" && (e--, t[t.length - 2] === "=" && e--);
4128
4128
  const n = new ArrayBuffer(e), i = new Uint8Array(n);
4129
- let s, o = 0, l, u, a, h;
4129
+ let s, o = 0, l, u, r, h;
4130
4130
  for (s = 0; s < t.length; s += 4)
4131
- l = this.b64Lookup[t.charCodeAt(s)], u = this.b64Lookup[t.charCodeAt(s + 1)], a = this.b64Lookup[t.charCodeAt(s + 2)], h = this.b64Lookup[t.charCodeAt(s + 3)], i[o++] = l << 2 | u >> 4, i[o++] = (u & 15) << 4 | a >> 2, i[o++] = (a & 3) << 6 | h & 63;
4131
+ l = this.b64Lookup[t.charCodeAt(s)], u = this.b64Lookup[t.charCodeAt(s + 1)], r = this.b64Lookup[t.charCodeAt(s + 2)], h = this.b64Lookup[t.charCodeAt(s + 3)], i[o++] = l << 2 | u >> 4, i[o++] = (u & 15) << 4 | r >> 2, i[o++] = (r & 3) << 6 | h & 63;
4132
4132
  return n;
4133
4133
  }
4134
4134
  /**
@@ -4199,9 +4199,9 @@ class Oe {
4199
4199
  if (!i && s.morphTargetDictionary.hasOwnProperty(e)) return;
4200
4200
  const o = s.geometry;
4201
4201
  let l = null, u = null;
4202
- for (const [a, h] of Object.entries(n))
4203
- if (s.morphTargetDictionary.hasOwnProperty(a)) {
4204
- const r = s.morphTargetDictionary[a], c = o.morphAttributes.position[r], d = o.morphAttributes.normal?.[r];
4202
+ for (const [r, h] of Object.entries(n))
4203
+ if (s.morphTargetDictionary.hasOwnProperty(r)) {
4204
+ const a = s.morphTargetDictionary[r], c = o.morphAttributes.position[a], d = o.morphAttributes.normal?.[a];
4205
4205
  l || (l = new f.Float32BufferAttribute(c.count * 3, 3), d && (u = new f.Float32BufferAttribute(c.count * 3, 3)));
4206
4206
  for (let g = 0; g < c.count; g++) {
4207
4207
  const y = l.getX(g) + c.getX(g) * h, x = l.getY(g) + c.getY(g) * h, I = l.getZ(g) + c.getZ(g) * h;
@@ -4215,8 +4215,8 @@ class Oe {
4215
4215
  }
4216
4216
  if (l) {
4217
4217
  o.morphAttributes.position.push(l), u && o.morphAttributes.normal.push(u);
4218
- const a = o.morphAttributes.position.length - 1;
4219
- s.morphTargetInfluences[a] = 0, s.morphTargetDictionary[e] = a;
4218
+ const r = o.morphAttributes.position.length - 1;
4219
+ s.morphTargetInfluences[r] = 0, s.morphTargetDictionary[e] = r;
4220
4220
  }
4221
4221
  });
4222
4222
  }
@@ -4230,64 +4230,64 @@ class Oe {
4230
4230
  throw new Error("Invalid parameter. The avatar must have at least 'url' specified.");
4231
4231
  const n = new je();
4232
4232
  if (this.dracoEnabled) {
4233
- const a = new Qe();
4234
- a.setDecoderPath(this.dracoDecoderPath), n.setDRACOLoader(a);
4233
+ const r = new Qe();
4234
+ r.setDecoderPath(this.dracoDecoderPath), n.setDRACOLoader(r);
4235
4235
  }
4236
4236
  let i = await n.loadAsync(t.url, e);
4237
4237
  const s = [this.opt.modelRoot];
4238
- if (this.posePropNames.forEach((a) => s.push(a.split(".")[0])), s.forEach((a) => {
4239
- if (!i.scene.getObjectByName(a))
4240
- throw new Error("Avatar object " + a + " not found");
4241
- }), this.stop(), this.avatar = t, this.bodyMovement = t.bodyMovement || "idle", this.movementIntensity = t.movementIntensity || 0.5, this.showFullAvatar = t.showFullAvatar || !1, this.fbxAnimationLoader = null, this.dynamicbones.dispose(), this.mixer = null, this.isAvatarOnly ? this.armature && this.clearThree(this.armature) : this.armature && this.clearThree(this.scene), this.armature = i.scene.getObjectByName(this.opt.modelRoot), this.armature.scale.setScalar(1), this.animations = i.animations, this.userData = i.userData, this.morphs = [], this.armature.traverse((a) => {
4242
- a.morphTargetInfluences && a.morphTargetInfluences.length && a.morphTargetDictionary && this.morphs.push(a), a.frustumCulled = !1;
4238
+ if (this.posePropNames.forEach((r) => s.push(r.split(".")[0])), s.forEach((r) => {
4239
+ if (!i.scene.getObjectByName(r))
4240
+ throw new Error("Avatar object " + r + " not found");
4241
+ }), this.stop(), this.avatar = t, this.bodyMovement = t.bodyMovement || "idle", this.movementIntensity = t.movementIntensity || 0.5, this.showFullAvatar = t.showFullAvatar || !1, this.fbxAnimationLoader = null, this.dynamicbones.dispose(), this.mixer = null, this.isAvatarOnly ? this.armature && this.clearThree(this.armature) : this.armature && this.clearThree(this.scene), this.armature = i.scene.getObjectByName(this.opt.modelRoot), this.armature.scale.setScalar(1), this.animations = i.animations, this.userData = i.userData, this.morphs = [], this.armature.traverse((r) => {
4242
+ r.morphTargetInfluences && r.morphTargetInfluences.length && r.morphTargetDictionary && this.morphs.push(r), r.frustumCulled = !1;
4243
4243
  }), this.morphs.length === 0)
4244
4244
  throw new Error("Blend shapes not found");
4245
4245
  const o = new Set(this.mtCustoms);
4246
- this.morphs.forEach((a) => {
4247
- Object.keys(a.morphTargetDictionary).forEach((h) => o.add(h));
4248
- }), this.mtExtras.forEach((a) => {
4249
- o.has(a.key) || (this.addMixedMorphTarget(this.morphs, a.key, a.mix), o.add(a.key));
4246
+ this.morphs.forEach((r) => {
4247
+ Object.keys(r.morphTargetDictionary).forEach((h) => o.add(h));
4248
+ }), this.mtExtras.forEach((r) => {
4249
+ o.has(r.key) || (this.addMixedMorphTarget(this.morphs, r.key, r.mix), o.add(r.key));
4250
4250
  });
4251
4251
  const l = {};
4252
- if (o.forEach((a) => {
4253
- l[a] = {
4252
+ if (o.forEach((r) => {
4253
+ l[r] = {
4254
4254
  fixed: null,
4255
4255
  realtime: null,
4256
4256
  system: null,
4257
4257
  systemd: null,
4258
4258
  newvalue: null,
4259
4259
  ref: null,
4260
- min: this.mtMinExceptions.hasOwnProperty(a) ? this.mtMinExceptions[a] : this.mtMinDefault,
4261
- max: this.mtMaxExceptions.hasOwnProperty(a) ? this.mtMaxExceptions[a] : this.mtMaxDefault,
4260
+ min: this.mtMinExceptions.hasOwnProperty(r) ? this.mtMinExceptions[r] : this.mtMinDefault,
4261
+ max: this.mtMaxExceptions.hasOwnProperty(r) ? this.mtMaxExceptions[r] : this.mtMaxDefault,
4262
4262
  easing: this.mtEasingDefault,
4263
4263
  base: null,
4264
4264
  v: 0,
4265
4265
  needsUpdate: !0,
4266
- acc: (this.mtAccExceptions.hasOwnProperty(a) ? this.mtAccExceptions[a] : this.mtAccDefault) / 1e3,
4267
- maxv: (this.mtMaxVExceptions.hasOwnProperty(a) ? this.mtMaxVExceptions[a] : this.mtMaxVDefault) / 1e3,
4268
- limit: this.mtLimits.hasOwnProperty(a) ? this.mtLimits[a] : null,
4269
- onchange: this.mtOnchange.hasOwnProperty(a) ? this.mtOnchange[a] : null,
4270
- baseline: this.avatar.baseline?.hasOwnProperty(a) ? this.avatar.baseline[a] : this.mtBaselineExceptions.hasOwnProperty(a) ? this.mtBaselineExceptions[a] : this.mtBaselineDefault,
4266
+ acc: (this.mtAccExceptions.hasOwnProperty(r) ? this.mtAccExceptions[r] : this.mtAccDefault) / 1e3,
4267
+ maxv: (this.mtMaxVExceptions.hasOwnProperty(r) ? this.mtMaxVExceptions[r] : this.mtMaxVDefault) / 1e3,
4268
+ limit: this.mtLimits.hasOwnProperty(r) ? this.mtLimits[r] : null,
4269
+ onchange: this.mtOnchange.hasOwnProperty(r) ? this.mtOnchange[r] : null,
4270
+ baseline: this.avatar.baseline?.hasOwnProperty(r) ? this.avatar.baseline[r] : this.mtBaselineExceptions.hasOwnProperty(r) ? this.mtBaselineExceptions[r] : this.mtBaselineDefault,
4271
4271
  ms: [],
4272
4272
  is: []
4273
- }, l[a].value = l[a].baseline, l[a].applied = l[a].baseline;
4274
- const h = this.mtAvatar[a];
4275
- h && ["fixed", "system", "systemd", "realtime", "base", "v", "value", "applied"].forEach((r) => {
4276
- l[a][r] = h[r];
4277
- }), this.morphs.forEach((r) => {
4278
- const c = r.morphTargetDictionary[a];
4279
- c !== void 0 && (l[a].ms.push(r.morphTargetInfluences), l[a].is.push(c), r.morphTargetInfluences[c] = l[a].applied);
4273
+ }, l[r].value = l[r].baseline, l[r].applied = l[r].baseline;
4274
+ const h = this.mtAvatar[r];
4275
+ h && ["fixed", "system", "systemd", "realtime", "base", "v", "value", "applied"].forEach((a) => {
4276
+ l[r][a] = h[a];
4277
+ }), this.morphs.forEach((a) => {
4278
+ const c = a.morphTargetDictionary[r];
4279
+ c !== void 0 && (l[r].ms.push(a.morphTargetInfluences), l[r].is.push(c), a.morphTargetInfluences[c] = l[r].applied);
4280
4280
  });
4281
- }), this.mtAvatar = l, this.poseAvatar = { props: {} }, this.posePropNames.forEach((a) => {
4282
- const h = a.split("."), r = this.armature.getObjectByName(h[0]);
4283
- this.poseAvatar.props[a] = r[h[1]], this.poseBase.props.hasOwnProperty(a) ? this.poseAvatar.props[a].copy(this.poseBase.props[a]) : this.poseBase.props[a] = this.poseAvatar.props[a].clone(), this.poseDelta.props.hasOwnProperty(a) && !this.poseTarget.props.hasOwnProperty(a) && (this.poseTarget.props[a] = this.poseAvatar.props[a].clone()), this.poseTarget.props[a].t = this.animClock, this.poseTarget.props[a].d = 2e3;
4284
- }), this.ikMesh.traverse((a) => {
4285
- a.isBone && a.position.copy(this.armature.getObjectByName(a.name).position);
4281
+ }), this.mtAvatar = l, this.poseAvatar = { props: {} }, this.posePropNames.forEach((r) => {
4282
+ const h = r.split("."), a = this.armature.getObjectByName(h[0]);
4283
+ this.poseAvatar.props[r] = a[h[1]], this.poseBase.props.hasOwnProperty(r) ? this.poseAvatar.props[r].copy(this.poseBase.props[r]) : this.poseBase.props[r] = this.poseAvatar.props[r].clone(), this.poseDelta.props.hasOwnProperty(r) && !this.poseTarget.props.hasOwnProperty(r) && (this.poseTarget.props[r] = this.poseAvatar.props[r].clone()), this.poseTarget.props[r].t = this.animClock, this.poseTarget.props[r].d = 2e3;
4284
+ }), this.ikMesh.traverse((r) => {
4285
+ r.isBone && r.position.copy(this.armature.getObjectByName(r.name).position);
4286
4286
  }), this.isAvatarOnly ? this.scene && this.scene.add(this.armature) : (this.scene.add(i.scene), this.scene.add(this.lightAmbient), this.scene.add(this.lightDirect), this.scene.add(this.lightSpot), this.lightSpot.target = this.armature.getObjectByName("Head")), t.hasOwnProperty("modelDynamicBones"))
4287
4287
  try {
4288
4288
  this.dynamicbones.setup(this.scene, this.armature, t.modelDynamicBones);
4289
- } catch (a) {
4290
- console.error("Dynamic bones setup failed: " + a);
4289
+ } catch (r) {
4290
+ console.error("Dynamic bones setup failed: " + r);
4291
4291
  }
4292
4292
  this.objectLeftToeBase = this.armature.getObjectByName("LeftToeBase"), this.objectRightToeBase = this.armature.getObjectByName("RightToeBase"), this.objectLeftEye = this.armature.getObjectByName("LeftEye"), this.objectRightEye = this.armature.getObjectByName("RightEye"), this.objectLeftArm = this.armature.getObjectByName("LeftArm"), this.objectRightArm = this.armature.getObjectByName("RightArm"), this.objectHips = this.armature.getObjectByName("Hips"), this.objectHead = this.armature.getObjectByName("Head"), this.objectNeck = this.armature.getObjectByName("Neck");
4293
4293
  const u = new f.Vector3();
@@ -4320,21 +4320,21 @@ class Oe {
4320
4320
  }
4321
4321
  if (this.viewName = t || this.viewName, e = e || {}, this.isAvatarOnly) return;
4322
4322
  const n = e.hasOwnProperty("cameraX") ? e.cameraX : this.opt.cameraX, i = e.hasOwnProperty("cameraY") ? e.cameraY : this.opt.cameraY, s = e.hasOwnProperty("cameraDistance") ? e.cameraDistance : this.opt.cameraDistance, o = e.hasOwnProperty("cameraRotateX") ? e.cameraRotateX : this.opt.cameraRotateX, l = e.hasOwnProperty("cameraRotateY") ? e.cameraRotateY : this.opt.cameraRotateY, u = this.camera.fov * (Math.PI / 180);
4323
- let a = -n * Math.tan(u / 2), h = (1 - i) * Math.tan(u / 2), r = s;
4323
+ let r = -n * Math.tan(u / 2), h = (1 - i) * Math.tan(u / 2), a = s;
4324
4324
  switch (this.viewName) {
4325
4325
  case "head":
4326
- r += 2, h = h * r + 4 * this.avatarHeight / 5;
4326
+ a += 2, h = h * a + 4 * this.avatarHeight / 5;
4327
4327
  break;
4328
4328
  case "upper":
4329
- r += 4.5, h = h * r + 2 * this.avatarHeight / 3;
4329
+ a += 4.5, h = h * a + 2 * this.avatarHeight / 3;
4330
4330
  break;
4331
4331
  case "mid":
4332
- r += 8, h = h * r + this.avatarHeight / 3;
4332
+ a += 8, h = h * a + this.avatarHeight / 3;
4333
4333
  break;
4334
4334
  default:
4335
- r += 12, h = h * r;
4335
+ a += 12, h = h * a;
4336
4336
  }
4337
- a = a * r, this.controlsEnd = new f.Vector3(a, h, 0), this.cameraEnd = new f.Vector3(a, h, r).applyEuler(new f.Euler(o, l, 0)), this.cameraClock === null && (this.controls.target.copy(this.controlsEnd), this.camera.position.copy(this.cameraEnd)), this.controlsStart = this.controls.target.clone(), this.cameraStart = this.camera.position.clone(), this.cameraClock = 0;
4337
+ r = r * a, this.controlsEnd = new f.Vector3(r, h, 0), this.cameraEnd = new f.Vector3(r, h, a).applyEuler(new f.Euler(o, l, 0)), this.cameraClock === null && (this.controls.target.copy(this.controlsEnd), this.camera.position.copy(this.cameraEnd)), this.controlsStart = this.controls.target.clone(), this.cameraStart = this.camera.position.clone(), this.cameraClock = 0;
4338
4338
  }
4339
4339
  /**
4340
4340
  * Change light colors and intensities.
@@ -4431,16 +4431,16 @@ class Oe {
4431
4431
  "HandMiddle",
4432
4432
  "HandRing",
4433
4433
  "HandPinky"
4434
- ].forEach((h, r) => {
4435
- r === 0 ? (this.poseDelta.props[o + h + "1.quaternion"].x = 0, this.poseDelta.props[o + h + "2.quaternion"].z = (o === "Left" ? -1 : 1) * n.applied, this.poseDelta.props[o + h + "3.quaternion"].z = (o === "Left" ? -1 : 1) * n.applied) : (this.poseDelta.props[o + h + "1.quaternion"].x = n.applied, this.poseDelta.props[o + h + "2.quaternion"].x = 1.5 * n.applied, this.poseDelta.props[o + h + "3.quaternion"].x = 1.5 * n.applied);
4434
+ ].forEach((h, a) => {
4435
+ a === 0 ? (this.poseDelta.props[o + h + "1.quaternion"].x = 0, this.poseDelta.props[o + h + "2.quaternion"].z = (o === "Left" ? -1 : 1) * n.applied, this.poseDelta.props[o + h + "3.quaternion"].z = (o === "Left" ? -1 : 1) * n.applied) : (this.poseDelta.props[o + h + "1.quaternion"].x = n.applied, this.poseDelta.props[o + h + "2.quaternion"].x = 1.5 * n.applied, this.poseDelta.props[o + h + "3.quaternion"].x = 1.5 * n.applied);
4436
4436
  });
4437
4437
  break;
4438
4438
  case "chestInhale":
4439
- const l = n.applied / 20, u = { x: l, y: l / 2, z: 3 * l }, a = { x: 1 / (1 + l) - 1, y: 1 / (1 + l / 2) - 1, z: 1 / (1 + 3 * l) - 1 };
4440
- this.poseDelta.props["Spine1.scale"] = u, this.poseDelta.props["Neck.scale"] = a, this.poseDelta.props["LeftArm.scale"] = a, this.poseDelta.props["RightArm.scale"] = a;
4439
+ const l = n.applied / 20, u = { x: l, y: l / 2, z: 3 * l }, r = { x: 1 / (1 + l) - 1, y: 1 / (1 + l / 2) - 1, z: 1 / (1 + 3 * l) - 1 };
4440
+ this.poseDelta.props["Spine1.scale"] = u, this.poseDelta.props["Neck.scale"] = r, this.poseDelta.props["LeftArm.scale"] = r, this.poseDelta.props["RightArm.scale"] = r;
4441
4441
  break;
4442
4442
  default:
4443
- for (let h = 0, r = n.ms.length; h < r; h++)
4443
+ for (let h = 0, a = n.ms.length; h < a; h++)
4444
4444
  n.ms[h][n.is[h]] = n.applied;
4445
4445
  }
4446
4446
  }
@@ -4971,38 +4971,38 @@ class Oe {
4971
4971
  else if (this.avatar.body && l.hasOwnProperty(this.avatar.body))
4972
4972
  l = l[this.avatar.body];
4973
4973
  else if (l.hasOwnProperty("alt")) {
4974
- let a = l.alt[0];
4974
+ let r = l.alt[0];
4975
4975
  if (l.alt.length > 1) {
4976
4976
  const h = Math.random();
4977
- let r = 0;
4977
+ let a = 0;
4978
4978
  for (let c = 0; c < l.alt.length; c++) {
4979
4979
  let d = this.valueFn(l.alt[c].p);
4980
- if (r += d === void 0 ? (1 - r) / (l.alt.length - 1 - c) : d, h < r) {
4981
- a = l.alt[c];
4980
+ if (a += d === void 0 ? (1 - a) / (l.alt.length - 1 - c) : d, h < a) {
4981
+ r = l.alt[c];
4982
4982
  break;
4983
4983
  }
4984
4984
  }
4985
4985
  }
4986
- l = a;
4986
+ l = r;
4987
4987
  } else
4988
4988
  break;
4989
4989
  let u = this.valueFn(l.delay) || 0;
4990
4990
  if (Array.isArray(u) && (u = this.gaussianRandom(...u)), l.hasOwnProperty("dt"))
4991
- l.dt.forEach((a, h) => {
4992
- let r = this.valueFn(a);
4993
- Array.isArray(r) && (r = this.gaussianRandom(...r)), o.ts[h + 1] = o.ts[h] + r;
4991
+ l.dt.forEach((r, h) => {
4992
+ let a = this.valueFn(r);
4993
+ Array.isArray(a) && (a = this.gaussianRandom(...a)), o.ts[h + 1] = o.ts[h] + a;
4994
4994
  });
4995
4995
  else {
4996
- let a = Object.values(l.vs).reduce((h, r) => r.length > h ? r.length : h, 0);
4997
- o.ts = Array(a + 1).fill(0);
4996
+ let r = Object.values(l.vs).reduce((h, a) => a.length > h ? a.length : h, 0);
4997
+ o.ts = Array(r + 1).fill(0);
4998
4998
  }
4999
- s ? o.ts = o.ts.map((a) => u + a * n) : o.ts = o.ts.map((a) => this.animClock + u + a * n);
5000
- for (let [a, h] of Object.entries(l.vs)) {
5001
- const r = this.getBaselineValue(a), c = h.map((d) => (d = this.valueFn(d), d === null ? null : typeof d == "function" ? d : typeof d == "string" || d instanceof String ? d.slice() : Array.isArray(d) ? a === "gesture" ? d.slice() : (r === void 0 ? 0 : r) + i * this.gaussianRandom(...d) : typeof d == "boolean" ? d : d instanceof Object && d.constructor === Object ? Object.assign({}, d) : (r === void 0 ? 0 : r) + i * d));
5002
- a === "eyesRotateY" ? (o.vs.eyeLookOutLeft = [null, ...c.map((d) => d > 0 ? d : 0)], o.vs.eyeLookInLeft = [null, ...c.map((d) => d > 0 ? 0 : -d)], o.vs.eyeLookOutRight = [null, ...c.map((d) => d > 0 ? 0 : -d)], o.vs.eyeLookInRight = [null, ...c.map((d) => d > 0 ? d : 0)]) : a === "eyesRotateX" ? (o.vs.eyesLookDown = [null, ...c.map((d) => d > 0 ? d : 0)], o.vs.eyesLookUp = [null, ...c.map((d) => d > 0 ? 0 : -d)]) : o.vs[a] = [null, ...c];
4999
+ s ? o.ts = o.ts.map((r) => u + r * n) : o.ts = o.ts.map((r) => this.animClock + u + r * n);
5000
+ for (let [r, h] of Object.entries(l.vs)) {
5001
+ const a = this.getBaselineValue(r), c = h.map((d) => (d = this.valueFn(d), d === null ? null : typeof d == "function" ? d : typeof d == "string" || d instanceof String ? d.slice() : Array.isArray(d) ? r === "gesture" ? d.slice() : (a === void 0 ? 0 : a) + i * this.gaussianRandom(...d) : typeof d == "boolean" ? d : d instanceof Object && d.constructor === Object ? Object.assign({}, d) : (a === void 0 ? 0 : a) + i * d));
5002
+ r === "eyesRotateY" ? (o.vs.eyeLookOutLeft = [null, ...c.map((d) => d > 0 ? d : 0)], o.vs.eyeLookInLeft = [null, ...c.map((d) => d > 0 ? 0 : -d)], o.vs.eyeLookOutRight = [null, ...c.map((d) => d > 0 ? 0 : -d)], o.vs.eyeLookInRight = [null, ...c.map((d) => d > 0 ? d : 0)]) : r === "eyesRotateX" ? (o.vs.eyesLookDown = [null, ...c.map((d) => d > 0 ? d : 0)], o.vs.eyesLookUp = [null, ...c.map((d) => d > 0 ? 0 : -d)]) : o.vs[r] = [null, ...c];
5003
5003
  }
5004
- for (let a of Object.keys(o.vs))
5005
- for (; o.vs[a].length <= o.ts.length; ) o.vs[a].push(o.vs[a][o.vs[a].length - 1]);
5004
+ for (let r of Object.keys(o.vs))
5005
+ for (; o.vs[r].length <= o.ts.length; ) o.vs[r].push(o.vs[r][o.vs[r].length - 1]);
5006
5006
  return t.hasOwnProperty("mood") && (o.mood = this.valueFn(t.mood).slice()), e && (o.loop = e), o;
5007
5007
  }
5008
5008
  /**
@@ -5080,13 +5080,13 @@ class Oe {
5080
5080
  if (this.isSpeaking)
5081
5081
  for (l = 0, this.audioAnalyzerNode.getByteFrequencyData(this.volumeFrequencyData), n = 2, s = 10; n < s; n++)
5082
5082
  this.volumeFrequencyData[n] > l && (l = this.volumeFrequencyData[n]);
5083
- let u = null, a = null;
5083
+ let u = null, r = null;
5084
5084
  const h = [];
5085
5085
  for (n = 0, s = this.animQueue.length; n < s; n++) {
5086
- const r = this.animQueue[n];
5087
- if (!(!r || !r.ts || !r.ts.length || this.animClock < r.ts[0])) {
5088
- for (i = r.ndx || 0, o = r.ts.length; i < o && !(this.animClock < r.ts[i]); i++)
5089
- for (let [c, d] of Object.entries(r.vs))
5086
+ const a = this.animQueue[n];
5087
+ if (!(!a || !a.ts || !a.ts.length || this.animClock < a.ts[0])) {
5088
+ for (i = a.ndx || 0, o = a.ts.length; i < o && !(this.animClock < a.ts[i]); i++)
5089
+ for (let [c, d] of Object.entries(a.vs))
5090
5090
  if (this.mtAvatar.hasOwnProperty(c)) {
5091
5091
  if (d[i + 1] === null) continue;
5092
5092
  const g = this.mtAvatar[c];
@@ -5094,9 +5094,9 @@ class Oe {
5094
5094
  g.newvalue = d[i];
5095
5095
  else {
5096
5096
  g.newvalue = d[i + 1];
5097
- const y = r.ts[i + 1] - r.ts[i];
5097
+ const y = a.ts[i + 1] - a.ts[i];
5098
5098
  let x = 1;
5099
- y > 1e-4 && (x = (this.animClock - r.ts[i]) / y), x < 1 && (g.easing && (x = g.easing(x)), g.newvalue = (1 - x) * d[i] + x * g.newvalue), g.ref && g.ref !== r.vs && g.ref.hasOwnProperty(c) && delete g.ref[c], g.ref = r.vs;
5099
+ y > 1e-4 && (x = (this.animClock - a.ts[i]) / y), x < 1 && (g.easing && (x = g.easing(x)), g.newvalue = (1 - x) * d[i] + x * g.newvalue), g.ref && g.ref !== a.vs && g.ref.hasOwnProperty(c) && delete g.ref[c], g.ref = a.vs;
5100
5100
  }
5101
5101
  if (l)
5102
5102
  switch (c) {
@@ -5108,12 +5108,12 @@ class Oe {
5108
5108
  g.newvalue *= 1 + l / 255 - 0.5;
5109
5109
  }
5110
5110
  g.needsUpdate = !0;
5111
- } else c === "eyeContact" && d[i] !== null && u !== !1 ? u = !!d[i] : c === "headMove" && d[i] !== null && a !== !1 ? d[i] === 0 ? a = !1 : (Math.random() < d[i] && (a = !0), d[i] = null) : d[i] !== null && (h.push({ mt: c, val: d[i] }), d[i] = null);
5112
- i === o ? (r.hasOwnProperty("mood") && this.setMood(r.mood), r.loop ? (o = this.isSpeaking && (r.template.name === "head" || r.template.name === "eyes") ? 4 : 1, this.animQueue[n] = this.animFactory(r.template, r.loop > 0 ? r.loop - 1 : r.loop, 1, 1 / o)) : (this.animQueue.splice(n--, 1), s--)) : r.ndx = i - 1;
5111
+ } else c === "eyeContact" && d[i] !== null && u !== !1 ? u = !!d[i] : c === "headMove" && d[i] !== null && r !== !1 ? d[i] === 0 ? r = !1 : (Math.random() < d[i] && (r = !0), d[i] = null) : d[i] !== null && (h.push({ mt: c, val: d[i] }), d[i] = null);
5112
+ i === o ? (a.hasOwnProperty("mood") && this.setMood(a.mood), a.loop ? (o = this.isSpeaking && (a.template.name === "head" || a.template.name === "eyes") ? 4 : 1, this.animQueue[n] = this.animFactory(a.template, a.loop > 0 ? a.loop - 1 : a.loop, 1, 1 / o)) : (this.animQueue.splice(n--, 1), s--)) : a.ndx = i - 1;
5113
5113
  }
5114
5114
  }
5115
- for (let r = 0, c = h.length; r < c; r++)
5116
- switch (i = h[r].val, h[r].mt) {
5115
+ for (let a = 0, c = h.length; a < c; a++)
5116
+ switch (i = h[a].val, h[a].mt) {
5117
5117
  case "speak":
5118
5118
  this.speakText(i);
5119
5119
  break;
@@ -5159,7 +5159,7 @@ class Oe {
5159
5159
  }, i.x ? new f.Vector3(i.x, i.y, i.z) : null, !0, i.d);
5160
5160
  break;
5161
5161
  }
5162
- if ((u || a) && (E.setFromQuaternion(this.poseAvatar.props["Head.quaternion"]), E.x = Math.max(-0.9, Math.min(0.9, 2 * E.x - 0.5)), E.y = Math.max(-0.9, Math.min(0.9, -2.5 * E.y)), u ? (Object.assign(this.mtAvatar.eyesLookDown, { system: E.x < 0 ? -E.x : 0, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyesLookUp, { system: E.x < 0 ? 0 : E.x, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookInLeft, { system: E.y < 0 ? -E.y : 0, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookOutLeft, { system: E.y < 0 ? 0 : E.y, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookInRight, { system: E.y < 0 ? 0 : E.y, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookOutRight, { system: E.y < 0 ? -E.y : 0, needsUpdate: !0 }), a && (n = -this.mtAvatar.bodyRotateY.value, i = this.gaussianRandom(-0.2, 0.2), this.animQueue.push(this.animFactory({
5162
+ if ((u || r) && (E.setFromQuaternion(this.poseAvatar.props["Head.quaternion"]), E.x = Math.max(-0.9, Math.min(0.9, 2 * E.x - 0.5)), E.y = Math.max(-0.9, Math.min(0.9, -2.5 * E.y)), u ? (Object.assign(this.mtAvatar.eyesLookDown, { system: E.x < 0 ? -E.x : 0, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyesLookUp, { system: E.x < 0 ? 0 : E.x, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookInLeft, { system: E.y < 0 ? -E.y : 0, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookOutLeft, { system: E.y < 0 ? 0 : E.y, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookInRight, { system: E.y < 0 ? 0 : E.y, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookOutRight, { system: E.y < 0 ? -E.y : 0, needsUpdate: !0 }), r && (n = -this.mtAvatar.bodyRotateY.value, i = this.gaussianRandom(-0.2, 0.2), this.animQueue.push(this.animFactory({
5163
5163
  name: "headmove",
5164
5164
  dt: [[1e3, 2e3], [1e3, 2e3, 1, 2], [1e3, 2e3], [1e3, 2e3, 1, 2]],
5165
5165
  vs: {
@@ -5185,8 +5185,8 @@ class Oe {
5185
5185
  else {
5186
5186
  if (this.cameraClock !== null && this.cameraClock < 1e3) {
5187
5187
  this.cameraClock += e, this.cameraClock > 1e3 && (this.cameraClock = 1e3);
5188
- let r = new f.Spherical().setFromVector3(this.cameraStart), c = new f.Spherical().setFromVector3(this.cameraEnd);
5189
- r.phi += this.easing(this.cameraClock / 1e3) * (c.phi - r.phi), r.theta += this.easing(this.cameraClock / 1e3) * (c.theta - r.theta), r.radius += this.easing(this.cameraClock / 1e3) * (c.radius - r.radius), r.makeSafe(), this.camera.position.setFromSpherical(r), this.controlsStart.x !== this.controlsEnd.x ? this.controls.target.copy(this.controlsStart.lerp(this.controlsEnd, this.easing(this.cameraClock / 1e3))) : (r.setFromVector3(this.controlsStart), c.setFromVector3(this.controlsEnd), r.phi += this.easing(this.cameraClock / 1e3) * (c.phi - r.phi), r.theta += this.easing(this.cameraClock / 1e3) * (c.theta - r.theta), r.radius += this.easing(this.cameraClock / 1e3) * (c.radius - r.radius), r.makeSafe(), this.controls.target.setFromSpherical(r)), this.controls.update();
5188
+ let a = new f.Spherical().setFromVector3(this.cameraStart), c = new f.Spherical().setFromVector3(this.cameraEnd);
5189
+ a.phi += this.easing(this.cameraClock / 1e3) * (c.phi - a.phi), a.theta += this.easing(this.cameraClock / 1e3) * (c.theta - a.theta), a.radius += this.easing(this.cameraClock / 1e3) * (c.radius - a.radius), a.makeSafe(), this.camera.position.setFromSpherical(a), this.controlsStart.x !== this.controlsEnd.x ? this.controls.target.copy(this.controlsStart.lerp(this.controlsEnd, this.easing(this.cameraClock / 1e3))) : (a.setFromVector3(this.controlsStart), c.setFromVector3(this.controlsEnd), a.phi += this.easing(this.cameraClock / 1e3) * (c.phi - a.phi), a.theta += this.easing(this.cameraClock / 1e3) * (c.theta - a.theta), a.radius += this.easing(this.cameraClock / 1e3) * (c.radius - a.radius), a.makeSafe(), this.controls.target.setFromSpherical(a)), this.controls.update();
5190
5190
  }
5191
5191
  this.controls.autoRotate && this.controls.update(), this.stats && this.stats.end(), this.render();
5192
5192
  }
@@ -5247,16 +5247,16 @@ class Oe {
5247
5247
  */
5248
5248
  speakText(t, e = null, n = null, i = null) {
5249
5249
  e = e || {};
5250
- const s = /[!\.\?\n\p{Extended_Pictographic}]/ug, o = /[ ]/ug, l = /[\p{L}\p{N},\.\p{Quotation_Mark}!€\$\+\p{Dash_Punctuation}%&\?]/ug, u = /[\p{Extended_Pictographic}]/ug, a = e.lipsyncLang || this.avatar.lipsyncLang || this.opt.lipsyncLang;
5251
- let h = "", r = "", c = 0, d = [], g = [];
5250
+ const s = /[!\.\?\n\p{Extended_Pictographic}]/ug, o = /[ ]/ug, l = /[\p{L}\p{N},\.\p{Quotation_Mark}!€\$\+\p{Dash_Punctuation}%&\?]/ug, u = /[\p{Extended_Pictographic}]/ug, r = e.lipsyncLang || this.avatar.lipsyncLang || this.opt.lipsyncLang;
5251
+ let h = "", a = "", c = 0, d = [], g = [];
5252
5252
  const y = Array.from(this.segmenter.segment(t), (x) => x.segment);
5253
5253
  for (let x = 0; x < y.length; x++) {
5254
5254
  const I = x === y.length - 1, B = y[x].match(l);
5255
5255
  let p = y[x].match(s);
5256
5256
  const H = y[x].match(u), z = y[x].match(o);
5257
- if (p && !I && !H && y[x + 1].match(s) && (p = !1), n && (h += y[x]), B && (!i || i.every((v) => x < v[0] || x > v[1])) && (r += y[x]), (z || p || I) && (r.length && (r = this.lipsyncPreProcessText(r, a), r.length && d.push({
5257
+ if (p && !I && !H && y[x + 1].match(s) && (p = !1), n && (h += y[x]), B && (!i || i.every((R) => x < R[0] || x > R[1])) && (a += y[x]), (z || p || I) && (a.length && (a = this.lipsyncPreProcessText(a, r), a.length && d.push({
5258
5258
  mark: c,
5259
- word: r
5259
+ word: a
5260
5260
  })), h.length && (g.push({
5261
5261
  mark: c,
5262
5262
  template: { name: "subtitles" },
@@ -5264,32 +5264,32 @@ class Oe {
5264
5264
  vs: {
5265
5265
  subtitles: [h]
5266
5266
  }
5267
- }), h = ""), r.length)) {
5268
- const v = this.lipsyncWordsToVisemes(r, a);
5269
- if (v && v.visemes && v.visemes.length) {
5270
- const T = v.times[v.visemes.length - 1] + v.durations[v.visemes.length - 1];
5271
- for (let F = 0; F < v.visemes.length; F++)
5267
+ }), h = ""), a.length)) {
5268
+ const R = this.lipsyncWordsToVisemes(a, r);
5269
+ if (R && R.visemes && R.visemes.length) {
5270
+ const T = R.times[R.visemes.length - 1] + R.durations[R.visemes.length - 1];
5271
+ for (let F = 0; F < R.visemes.length; F++)
5272
5272
  g.push({
5273
5273
  mark: c,
5274
5274
  template: { name: "viseme" },
5275
- ts: [(v.times[F] - 0.6) / T, (v.times[F] + 0.5) / T, (v.times[F] + v.durations[F] + 0.5) / T],
5275
+ ts: [(R.times[F] - 0.6) / T, (R.times[F] + 0.5) / T, (R.times[F] + R.durations[F] + 0.5) / T],
5276
5276
  vs: {
5277
- ["viseme_" + v.visemes[F]]: [null, v.visemes[F] === "PP" || v.visemes[F] === "FF" ? 0.9 : 0.6, 0]
5277
+ ["viseme_" + R.visemes[F]]: [null, R.visemes[F] === "PP" || R.visemes[F] === "FF" ? 0.9 : 0.6, 0]
5278
5278
  }
5279
5279
  });
5280
5280
  }
5281
- r = "", c++;
5281
+ a = "", c++;
5282
5282
  }
5283
5283
  if (p || I) {
5284
5284
  if (d.length || I && g.length) {
5285
- const v = {
5285
+ const R = {
5286
5286
  anim: g
5287
5287
  };
5288
- n && (v.onSubtitles = n), d.length && !e.avatarMute && (v.text = d, e.avatarMood && (v.mood = e.avatarMood), e.ttsLang && (v.lang = e.ttsLang), e.ttsVoice && (v.voice = e.ttsVoice), e.ttsRate && (v.rate = e.ttsRate), e.ttsVoice && (v.pitch = e.ttsPitch), e.ttsVolume && (v.volume = e.ttsVolume)), this.speechQueue.push(v), d = [], r = "", c = 0, g = [];
5288
+ n && (R.onSubtitles = n), d.length && !e.avatarMute && (R.text = d, e.avatarMood && (R.mood = e.avatarMood), e.ttsLang && (R.lang = e.ttsLang), e.ttsVoice && (R.voice = e.ttsVoice), e.ttsRate && (R.rate = e.ttsRate), e.ttsVoice && (R.pitch = e.ttsPitch), e.ttsVolume && (R.volume = e.ttsVolume)), this.speechQueue.push(R), d = [], a = "", c = 0, g = [];
5289
5289
  }
5290
5290
  if (H) {
5291
- let v = this.animEmojis[y[x]];
5292
- v && v.link && (v = this.animEmojis[v.link]), v && this.speechQueue.push({ emoji: v });
5291
+ let R = this.animEmojis[y[x]];
5292
+ R && R.link && (R = this.animEmojis[R.link]), R && this.speechQueue.push({ emoji: R });
5293
5293
  }
5294
5294
  this.speechQueue.push({ break: 100 });
5295
5295
  }
@@ -5370,22 +5370,22 @@ class Oe {
5370
5370
  if (t.words) {
5371
5371
  let o = [];
5372
5372
  for (let l = 0; l < t.words.length; l++) {
5373
- const u = t.words[l], a = t.wtimes[l];
5373
+ const u = t.words[l], r = t.wtimes[l];
5374
5374
  let h = t.wdurations[l];
5375
5375
  if (u.length && (n && o.push({
5376
5376
  template: { name: "subtitles" },
5377
- ts: [a],
5377
+ ts: [r],
5378
5378
  vs: {
5379
5379
  subtitles: [" " + u]
5380
5380
  }
5381
5381
  }), !t.visemes)) {
5382
- const r = this.lipsyncPreProcessText(u, i), c = this.lipsyncWordsToVisemes(r, i);
5382
+ const a = this.lipsyncPreProcessText(u, i), c = this.lipsyncWordsToVisemes(a, i);
5383
5383
  if (c && c.visemes && c.visemes.length) {
5384
5384
  const d = c.times[c.visemes.length - 1] + c.durations[c.visemes.length - 1], g = Math.min(h, Math.max(0, h - c.visemes.length * 150));
5385
5385
  let y = 0.6 + this.convertRange(g, [0, h], [0, 0.4]);
5386
5386
  if (h = Math.min(h, c.visemes.length * 200), d > 0)
5387
5387
  for (let x = 0; x < c.visemes.length; x++) {
5388
- const I = a + c.times[x] / d * h, B = c.durations[x] / d * h;
5388
+ const I = r + c.times[x] / d * h, B = c.durations[x] / d * h;
5389
5389
  o.push({
5390
5390
  template: { name: "viseme" },
5391
5391
  ts: [I - Math.min(60, 2 * B / 3), I + Math.min(25, B / 2), I + B + Math.min(60, B / 2)],
@@ -5399,10 +5399,10 @@ class Oe {
5399
5399
  }
5400
5400
  if (t.visemes)
5401
5401
  for (let l = 0; l < t.visemes.length; l++) {
5402
- const u = t.visemes[l], a = t.vtimes[l], h = t.vdurations[l];
5402
+ const u = t.visemes[l], r = t.vtimes[l], h = t.vdurations[l];
5403
5403
  o.push({
5404
5404
  template: { name: "viseme" },
5405
- ts: [a - 2 * h / 3, a + h / 2, a + h + h / 2],
5405
+ ts: [r - 2 * h / 3, r + h / 2, r + h + h / 2],
5406
5406
  vs: {
5407
5407
  ["viseme_" + u]: [null, u === "PP" || u === "FF" ? 0.9 : 0.6, 0]
5408
5408
  }
@@ -5410,10 +5410,10 @@ class Oe {
5410
5410
  }
5411
5411
  if (t.markers)
5412
5412
  for (let l = 0; l < t.markers.length; l++) {
5413
- const u = t.markers[l], a = t.mtimes[l];
5413
+ const u = t.markers[l], r = t.mtimes[l];
5414
5414
  o.push({
5415
5415
  template: { name: "markers" },
5416
- ts: [a],
5416
+ ts: [r],
5417
5417
  vs: { function: [u] }
5418
5418
  });
5419
5419
  }
@@ -5466,11 +5466,11 @@ class Oe {
5466
5466
  */
5467
5467
  async synthesizeWithBrowserTTS(t) {
5468
5468
  return new Promise((e, n) => {
5469
- const i = t.text.map((p) => p.word).join(" "), s = new SpeechSynthesisUtterance(i), o = t.lang || this.avatar.ttsLang || this.opt.ttsLang || "en-US", l = (t.rate || this.avatar.ttsRate || this.opt.ttsRate || 1) + this.mood.speech.deltaRate, u = (t.pitch || this.avatar.ttsPitch || this.opt.ttsPitch || 1) + this.mood.speech.deltaPitch, a = (t.volume || this.avatar.ttsVolume || this.opt.ttsVolume || 1) + this.mood.speech.deltaVolume;
5470
- s.lang = o, s.rate = Math.max(0.1, Math.min(10, l)), s.pitch = Math.max(0, Math.min(2, u)), s.volume = Math.max(0, Math.min(1, a));
5471
- const h = speechSynthesis.getVoices(), r = t.voice || this.avatar.ttsVoice || this.opt.ttsVoice;
5472
- if (r && h.length > 0) {
5473
- const p = h.find((H) => H.name.includes(r) || H.lang === o);
5469
+ const i = t.text.map((p) => p.word).join(" "), s = new SpeechSynthesisUtterance(i), o = t.lang || this.avatar.ttsLang || this.opt.ttsLang || "en-US", l = (t.rate || this.avatar.ttsRate || this.opt.ttsRate || 1) + this.mood.speech.deltaRate, u = (t.pitch || this.avatar.ttsPitch || this.opt.ttsPitch || 1) + this.mood.speech.deltaPitch, r = (t.volume || this.avatar.ttsVolume || this.opt.ttsVolume || 1) + this.mood.speech.deltaVolume;
5470
+ s.lang = o, s.rate = Math.max(0.1, Math.min(10, l)), s.pitch = Math.max(0, Math.min(2, u)), s.volume = Math.max(0, Math.min(1, r));
5471
+ const h = speechSynthesis.getVoices(), a = t.voice || this.avatar.ttsVoice || this.opt.ttsVoice;
5472
+ if (a && h.length > 0) {
5473
+ const p = h.find((H) => H.name.includes(a) || H.lang === o);
5474
5474
  p && (s.voice = p);
5475
5475
  }
5476
5476
  const c = i.length * 100 / s.rate, d = this.audioCtx.createBuffer(1, this.audioCtx.sampleRate * (c / 1e3), this.audioCtx.sampleRate), g = this.avatar.lipsyncLang || this.opt.lipsyncLang || "en", y = this.lipsyncPreProcessText(i, g), x = this.lipsyncWordsToVisemes(y, g);
@@ -5486,7 +5486,7 @@ class Oe {
5486
5486
  if (x && x.visemes && x.visemes.length > 0) {
5487
5487
  const p = x.times[x.visemes.length - 1] + x.durations[x.visemes.length - 1];
5488
5488
  for (let H = 0; H < x.visemes.length; H++) {
5489
- const z = x.visemes[H], v = x.times[H] / p, T = x.durations[H] / p, F = v * c, J = T * c;
5489
+ const z = x.visemes[H], R = x.times[H] / p, T = x.durations[H] / p, F = R * c, J = T * c;
5490
5490
  I.push({
5491
5491
  template: { name: "viseme" },
5492
5492
  ts: [F - Math.min(60, 2 * J / 3), F + Math.min(25, J / 2), F + J + Math.min(60, J / 2)],
@@ -5532,7 +5532,7 @@ class Oe {
5532
5532
  const o = await s.arrayBuffer(), l = await this.audioCtx.decodeAudioData(o);
5533
5533
  console.log("Using text-based lip-sync for debugging...");
5534
5534
  const u = this.avatar.lipsyncLang || this.opt.lipsyncLang || "en";
5535
- let a;
5535
+ let r;
5536
5536
  try {
5537
5537
  console.log("Lip-sync modules available:", {
5538
5538
  hasLipsync: !!this.lipsync,
@@ -5545,7 +5545,7 @@ class Oe {
5545
5545
  lipsyncData: d,
5546
5546
  hasVisemes: d && d.visemes && d.visemes.length > 0
5547
5547
  }), d && d.visemes && d.visemes.length > 0)
5548
- a = {
5548
+ r = {
5549
5549
  visemes: d.visemes.map((g, y) => ({
5550
5550
  viseme: g,
5551
5551
  startTime: y * l.duration / d.visemes.length,
@@ -5567,7 +5567,7 @@ class Oe {
5567
5567
  let I = "aa";
5568
5568
  "aeiou".includes(x) ? I = "aa" : "bp".includes(x) ? I = "PP" : "fv".includes(x) ? I = "FF" : "st".includes(x) ? I = "SS" : "dln".includes(x) ? I = "DD" : "kg".includes(x) ? I = "kk" : "rw".includes(x) && (I = "RR"), g.push(I);
5569
5569
  }
5570
- a = {
5570
+ r = {
5571
5571
  visemes: g.map((y, x) => ({
5572
5572
  viseme: y,
5573
5573
  startTime: x * l.duration / g.length,
@@ -5583,20 +5583,20 @@ class Oe {
5583
5583
  console.log("ElevenLabs TTS Audio Analysis:", {
5584
5584
  text: e,
5585
5585
  audioDuration: l.duration,
5586
- visemeCount: a.visemes ? a.visemes.length : 0,
5587
- wordCount: a.words ? a.words.length : 0,
5586
+ visemeCount: r.visemes ? r.visemes.length : 0,
5587
+ wordCount: r.words ? r.words.length : 0,
5588
5588
  features: {
5589
- onsets: a.features && a.features.onsets ? a.features.onsets.length : 0,
5590
- boundaries: a.features && a.features.phonemeBoundaries ? a.features.phonemeBoundaries.length : 0
5589
+ onsets: r.features && r.features.onsets ? r.features.onsets.length : 0,
5590
+ boundaries: r.features && r.features.phonemeBoundaries ? r.features.phonemeBoundaries.length : 0
5591
5591
  },
5592
- visemes: a.visemes ? a.visemes.slice(0, 3) : []
5592
+ visemes: r.visemes ? r.visemes.slice(0, 3) : []
5593
5593
  // Show first 3 visemes for debugging
5594
5594
  });
5595
5595
  const h = [];
5596
- if (a.visemes && a.visemes.length > 0) {
5597
- console.log("ElevenLabs: Generating lip-sync animation from", a.visemes.length, "visemes");
5598
- for (let c = 0; c < a.visemes.length; c++) {
5599
- const d = a.visemes[c], g = d.startTime * 1e3, y = d.duration * 1e3, x = d.intensity;
5596
+ if (r.visemes && r.visemes.length > 0) {
5597
+ console.log("ElevenLabs: Generating lip-sync animation from", r.visemes.length, "visemes");
5598
+ for (let c = 0; c < r.visemes.length; c++) {
5599
+ const d = r.visemes[c], g = d.startTime * 1e3, y = d.duration * 1e3, x = d.intensity;
5600
5600
  h.push({
5601
5601
  template: { name: "viseme" },
5602
5602
  ts: [g - Math.min(60, 2 * y / 3), g + Math.min(25, y / 2), g + y + Math.min(60, y / 2)],
@@ -5608,8 +5608,8 @@ class Oe {
5608
5608
  console.log("ElevenLabs: Generated", h.length, "lip-sync animation frames");
5609
5609
  } else
5610
5610
  console.warn("ElevenLabs: No visemes available for lip-sync animation");
5611
- const r = [...t.anim, ...h];
5612
- console.log("ElevenLabs: Combined animation frames:", r.length, "(original:", t.anim.length, "+ lipsync:", h.length, ")"), this.audioPlaylist.push({ anim: r, audio: l }), this.onSubtitles = t.onSubtitles || null, this.resetLips(), t.mood && this.setMood(t.mood), this.playAudio();
5611
+ const a = [...t.anim, ...h];
5612
+ console.log("ElevenLabs: Combined animation frames:", a.length, "(original:", t.anim.length, "+ lipsync:", h.length, ")"), this.audioPlaylist.push({ anim: a, audio: l }), this.onSubtitles = t.onSubtitles || null, this.resetLips(), t.mood && this.setMood(t.mood), this.playAudio();
5613
5613
  }
5614
5614
  /**
5615
5615
  * Synthesize speech using Deepgram Aura-2 TTS
@@ -5630,7 +5630,7 @@ class Oe {
5630
5630
  const o = await s.arrayBuffer(), l = await this.audioCtx.decodeAudioData(o);
5631
5631
  console.log("Using text-based lip-sync for Deepgram...");
5632
5632
  const u = this.avatar.lipsyncLang || this.opt.lipsyncLang || "en";
5633
- let a;
5633
+ let r;
5634
5634
  try {
5635
5635
  console.log("Lip-sync modules available:", {
5636
5636
  hasLipsync: !!this.lipsync,
@@ -5643,7 +5643,7 @@ class Oe {
5643
5643
  lipsyncData: d,
5644
5644
  hasVisemes: d && d.visemes && d.visemes.length > 0
5645
5645
  }), d && d.visemes && d.visemes.length > 0)
5646
- a = {
5646
+ r = {
5647
5647
  visemes: d.visemes.map((g, y) => ({
5648
5648
  viseme: g,
5649
5649
  startTime: y * l.duration / d.visemes.length,
@@ -5665,7 +5665,7 @@ class Oe {
5665
5665
  let I = "aa";
5666
5666
  "aeiou".includes(x) ? I = "aa" : "bp".includes(x) ? I = "PP" : "fv".includes(x) ? I = "FF" : "st".includes(x) ? I = "SS" : "dln".includes(x) ? I = "DD" : "kg".includes(x) ? I = "kk" : "rw".includes(x) && (I = "RR"), g.push(I);
5667
5667
  }
5668
- a = {
5668
+ r = {
5669
5669
  visemes: g.map((y, x) => ({
5670
5670
  viseme: y,
5671
5671
  startTime: x * l.duration / g.length,
@@ -5681,20 +5681,20 @@ class Oe {
5681
5681
  console.log("Deepgram TTS Audio Analysis:", {
5682
5682
  text: e,
5683
5683
  audioDuration: l.duration,
5684
- visemeCount: a.visemes ? a.visemes.length : 0,
5685
- wordCount: a.words ? a.words.length : 0,
5684
+ visemeCount: r.visemes ? r.visemes.length : 0,
5685
+ wordCount: r.words ? r.words.length : 0,
5686
5686
  features: {
5687
- onsets: a.features && a.features.onsets ? a.features.onsets.length : 0,
5688
- boundaries: a.features && a.features.phonemeBoundaries ? a.features.phonemeBoundaries.length : 0
5687
+ onsets: r.features && r.features.onsets ? r.features.onsets.length : 0,
5688
+ boundaries: r.features && r.features.phonemeBoundaries ? r.features.phonemeBoundaries.length : 0
5689
5689
  },
5690
- visemes: a.visemes ? a.visemes.slice(0, 3) : []
5690
+ visemes: r.visemes ? r.visemes.slice(0, 3) : []
5691
5691
  // Show first 3 visemes for debugging
5692
5692
  });
5693
5693
  const h = [];
5694
- if (a.visemes && a.visemes.length > 0) {
5695
- console.log("Deepgram: Generating lip-sync animation from", a.visemes.length, "visemes");
5696
- for (let c = 0; c < a.visemes.length; c++) {
5697
- const d = a.visemes[c], g = d.startTime * 1e3, y = d.duration * 1e3, x = d.intensity;
5694
+ if (r.visemes && r.visemes.length > 0) {
5695
+ console.log("Deepgram: Generating lip-sync animation from", r.visemes.length, "visemes");
5696
+ for (let c = 0; c < r.visemes.length; c++) {
5697
+ const d = r.visemes[c], g = d.startTime * 1e3, y = d.duration * 1e3, x = d.intensity;
5698
5698
  h.push({
5699
5699
  template: { name: "viseme" },
5700
5700
  ts: [g - Math.min(60, 2 * y / 3), g + Math.min(25, y / 2), g + y + Math.min(60, y / 2)],
@@ -5706,15 +5706,15 @@ class Oe {
5706
5706
  console.log("Deepgram: Generated", h.length, "lip-sync animation frames");
5707
5707
  } else
5708
5708
  console.warn("Deepgram: No visemes available for lip-sync animation");
5709
- const r = [...t.anim, ...h];
5710
- console.log("Deepgram: Combined animation frames:", r.length, "(original:", t.anim.length, "+ lipsync:", h.length, ")"), this.audioPlaylist.push({ anim: r, audio: l }), this.onSubtitles = t.onSubtitles || null, this.resetLips(), t.mood && this.setMood(t.mood), this.playAudio();
5709
+ const a = [...t.anim, ...h];
5710
+ console.log("Deepgram: Combined animation frames:", a.length, "(original:", t.anim.length, "+ lipsync:", h.length, ")"), this.audioPlaylist.push({ anim: a, audio: l }), this.onSubtitles = t.onSubtitles || null, this.resetLips(), t.mood && this.setMood(t.mood), this.playAudio();
5711
5711
  }
5712
5712
  /**
5713
5713
  * Synthesize speech using Azure TTS
5714
5714
  * @param {Object} line Speech line object
5715
5715
  */
5716
5716
  async synthesizeWithAzureTTS(t) {
5717
- const e = t.text.map((r) => r.word).join(" "), i = `
5717
+ const e = t.text.map((a) => a.word).join(" "), i = `
5718
5718
  <speak version="1.0" xmlns="http://www.w3.org/2001/10/synthesis" xml:lang="en-US">
5719
5719
  <voice name="${t.voice || this.avatar.ttsVoice || this.opt.ttsVoice || "en-US-AriaNeural"}">
5720
5720
  ${e}
@@ -5744,10 +5744,10 @@ class Oe {
5744
5744
  boundaries: u.features.phonemeBoundaries.length
5745
5745
  }
5746
5746
  });
5747
- const a = [];
5748
- for (let r = 0; r < u.visemes.length; r++) {
5749
- const c = u.visemes[r], d = c.startTime * 1e3, g = c.duration * 1e3, y = c.intensity;
5750
- a.push({
5747
+ const r = [];
5748
+ for (let a = 0; a < u.visemes.length; a++) {
5749
+ const c = u.visemes[a], d = c.startTime * 1e3, g = c.duration * 1e3, y = c.intensity;
5750
+ r.push({
5751
5751
  template: { name: "viseme" },
5752
5752
  ts: [d - Math.min(60, 2 * g / 3), d + Math.min(25, g / 2), d + g + Math.min(60, g / 2)],
5753
5753
  vs: {
@@ -5755,7 +5755,7 @@ class Oe {
5755
5755
  }
5756
5756
  });
5757
5757
  }
5758
- const h = [...t.anim, ...a];
5758
+ const h = [...t.anim, ...r];
5759
5759
  this.audioPlaylist.push({ anim: h, audio: l }), this.onSubtitles = t.onSubtitles || null, this.resetLips(), t.mood && this.setMood(t.mood), this.playAudio();
5760
5760
  }
5761
5761
  /**
@@ -5796,11 +5796,11 @@ class Oe {
5796
5796
  const o = this.b64ToArrayBuffer(s.audioContent), l = await this.audioCtx.decodeAudioData(o);
5797
5797
  this.speakWithHands();
5798
5798
  const u = [0];
5799
- let a = 0;
5799
+ let r = 0;
5800
5800
  t.text.forEach((c, d) => {
5801
5801
  if (d > 0) {
5802
5802
  let g = u[u.length - 1];
5803
- s.timepoints[a] && (g = s.timepoints[a].timeSeconds * 1e3, s.timepoints[a].markName === "" + c.mark && a++), u.push(g);
5803
+ s.timepoints[r] && (g = s.timepoints[r].timeSeconds * 1e3, s.timepoints[r].markName === "" + c.mark && r++), u.push(g);
5804
5804
  }
5805
5805
  });
5806
5806
  const h = [{ mark: 0, time: 0 }];
@@ -5810,8 +5810,8 @@ class Oe {
5810
5810
  h[d - 1].duration = g, h.push({ mark: d, time: c });
5811
5811
  }
5812
5812
  });
5813
- let r = 1e3 * l.duration;
5814
- r > this.opt.ttsTrimEnd && (r = r - this.opt.ttsTrimEnd), h[h.length - 1].duration = r - h[h.length - 1].time, t.anim.forEach((c) => {
5813
+ let a = 1e3 * l.duration;
5814
+ a > this.opt.ttsTrimEnd && (a = a - this.opt.ttsTrimEnd), h[h.length - 1].duration = a - h[h.length - 1].time, t.anim.forEach((c) => {
5815
5815
  const d = h[c.mark];
5816
5816
  if (d)
5817
5817
  for (let g = 0; g < c.ts.length; g++)
@@ -5896,7 +5896,7 @@ class Oe {
5896
5896
  if (!this.workletLoaded)
5897
5897
  try {
5898
5898
  const l = this.audioCtx.audioWorklet.addModule(dt.href), u = new Promise(
5899
- (a, h) => setTimeout(() => h(new Error("Worklet loading timed out")), 5e3)
5899
+ (r, h) => setTimeout(() => h(new Error("Worklet loading timed out")), 5e3)
5900
5900
  );
5901
5901
  await Promise.race([l, u]), this.workletLoaded = !0;
5902
5902
  } catch (l) {
@@ -5932,7 +5932,7 @@ class Oe {
5932
5932
  } catch {
5933
5933
  }
5934
5934
  if (this.resetLips(), this.lookAtCamera(500), t.mood && this.setMood(t.mood), this.onSubtitles = i || null, this.audioCtx.state === "suspended" || this.audioCtx.state === "interrupted") {
5935
- const l = this.audioCtx.resume(), u = new Promise((a, h) => setTimeout(() => h("p2"), 1e3));
5935
+ const l = this.audioCtx.resume(), u = new Promise((r, h) => setTimeout(() => h("p2"), 1e3));
5936
5936
  try {
5937
5937
  await Promise.race([l, u]);
5938
5938
  } catch {
@@ -6031,18 +6031,18 @@ class Oe {
6031
6031
  subtitles: [" " + i]
6032
6032
  }
6033
6033
  }), this.streamLipsyncType == "words")) {
6034
- const l = this.streamLipsyncLang || this.avatar.lipsyncLang || this.opt.lipsyncLang, u = this.lipsyncPreProcessText(i, l), a = this.lipsyncWordsToVisemes(u, l);
6035
- if (a && a.visemes && a.visemes.length) {
6036
- const h = a.times[a.visemes.length - 1] + a.durations[a.visemes.length - 1], r = Math.min(o, Math.max(0, o - a.visemes.length * 150));
6037
- let c = 0.6 + this.convertRange(r, [0, o], [0, 0.4]);
6038
- if (o = Math.min(o, a.visemes.length * 200), h > 0)
6039
- for (let d = 0; d < a.visemes.length; d++) {
6040
- const g = e + s + a.times[d] / h * o, y = a.durations[d] / h * o;
6034
+ const l = this.streamLipsyncLang || this.avatar.lipsyncLang || this.opt.lipsyncLang, u = this.lipsyncPreProcessText(i, l), r = this.lipsyncWordsToVisemes(u, l);
6035
+ if (r && r.visemes && r.visemes.length) {
6036
+ const h = r.times[r.visemes.length - 1] + r.durations[r.visemes.length - 1], a = Math.min(o, Math.max(0, o - r.visemes.length * 150));
6037
+ let c = 0.6 + this.convertRange(a, [0, o], [0, 0.4]);
6038
+ if (o = Math.min(o, r.visemes.length * 200), h > 0)
6039
+ for (let d = 0; d < r.visemes.length; d++) {
6040
+ const g = e + s + r.times[d] / h * o, y = r.durations[d] / h * o;
6041
6041
  this.animQueue.push({
6042
6042
  template: { name: "viseme" },
6043
6043
  ts: [g - Math.min(60, 2 * y / 3), g + Math.min(25, y / 2), g + y + Math.min(60, y / 2)],
6044
6044
  vs: {
6045
- ["viseme_" + a.visemes[d]]: [null, a.visemes[d] === "PP" || a.visemes[d] === "FF" ? 0.9 : c, 0]
6045
+ ["viseme_" + r.visemes[d]]: [null, r.visemes[d] === "PP" || r.visemes[d] === "FF" ? 0.9 : c, 0]
6046
6046
  }
6047
6047
  });
6048
6048
  }
@@ -6151,7 +6151,7 @@ class Oe {
6151
6151
  E.set(s, i, 0, "YXZ");
6152
6152
  const l = new f.Quaternion().setFromEuler(E), u = new f.Quaternion().copy(l).multiply(G.clone().invert());
6153
6153
  E.setFromQuaternion(u, "YXZ");
6154
- let a = E.x / (40 / 24) + 0.2, h = E.y / (9 / 4), r = Math.min(0.6, Math.max(-0.3, a)), c = Math.min(0.8, Math.max(-0.8, h)), d = (Math.random() - 0.5) / 4, g = (Math.random() - 0.5) / 4;
6154
+ let r = E.x / (40 / 24) + 0.2, h = E.y / (9 / 4), a = Math.min(0.6, Math.max(-0.3, r)), c = Math.min(0.8, Math.max(-0.8, h)), d = (Math.random() - 0.5) / 4, g = (Math.random() - 0.5) / 4;
6155
6155
  if (t) {
6156
6156
  let y = this.animQueue.findIndex((I) => I.template.name === "lookat");
6157
6157
  y !== -1 && this.animQueue.splice(y, 1);
@@ -6159,7 +6159,7 @@ class Oe {
6159
6159
  name: "lookat",
6160
6160
  dt: [750, t],
6161
6161
  vs: {
6162
- bodyRotateX: [r + d],
6162
+ bodyRotateX: [a + d],
6163
6163
  bodyRotateY: [c + g],
6164
6164
  eyesRotateX: [-3 * d + 0.1],
6165
6165
  eyesRotateY: [-5 * g],
@@ -6185,13 +6185,13 @@ class Oe {
6185
6185
  this.objectLeftEye.updateMatrixWorld(!0), this.objectRightEye.updateMatrixWorld(!0);
6186
6186
  const s = new f.Vector3().setFromMatrixPosition(this.objectLeftEye.matrixWorld), o = new f.Vector3().setFromMatrixPosition(this.objectRightEye.matrixWorld), l = new f.Vector3().addVectors(s, o).divideScalar(2);
6187
6187
  l.project(this.camera);
6188
- let u = (l.x + 1) / 2 * i.width + i.left, a = -(l.y - 1) / 2 * i.height + i.top;
6189
- t === null && (t = u), e === null && (e = a), G.copy(this.armature.quaternion), G.multiply(this.poseTarget.props["Hips.quaternion"]), G.multiply(this.poseTarget.props["Spine.quaternion"]), G.multiply(this.poseTarget.props["Spine1.quaternion"]), G.multiply(this.poseTarget.props["Spine2.quaternion"]), G.multiply(this.poseTarget.props["Neck.quaternion"]), G.multiply(this.poseTarget.props["Head.quaternion"]), E.setFromQuaternion(G);
6190
- let h = E.x / (40 / 24), r = E.y / (9 / 4), c = Math.min(0.4, Math.max(-0.4, this.camera.rotation.x)), d = Math.min(0.4, Math.max(-0.4, this.camera.rotation.y)), g = Math.max(window.innerWidth - u, u), y = Math.max(window.innerHeight - a, a), x = this.convertRange(e, [a - y, a + y], [-0.3, 0.6]) - h + c, I = this.convertRange(t, [u - g, u + g], [-0.8, 0.8]) - r + d;
6188
+ let u = (l.x + 1) / 2 * i.width + i.left, r = -(l.y - 1) / 2 * i.height + i.top;
6189
+ t === null && (t = u), e === null && (e = r), G.copy(this.armature.quaternion), G.multiply(this.poseTarget.props["Hips.quaternion"]), G.multiply(this.poseTarget.props["Spine.quaternion"]), G.multiply(this.poseTarget.props["Spine1.quaternion"]), G.multiply(this.poseTarget.props["Spine2.quaternion"]), G.multiply(this.poseTarget.props["Neck.quaternion"]), G.multiply(this.poseTarget.props["Head.quaternion"]), E.setFromQuaternion(G);
6190
+ let h = E.x / (40 / 24), a = E.y / (9 / 4), c = Math.min(0.4, Math.max(-0.4, this.camera.rotation.x)), d = Math.min(0.4, Math.max(-0.4, this.camera.rotation.y)), g = Math.max(window.innerWidth - u, u), y = Math.max(window.innerHeight - r, r), x = this.convertRange(e, [r - y, r + y], [-0.3, 0.6]) - h + c, I = this.convertRange(t, [u - g, u + g], [-0.8, 0.8]) - a + d;
6191
6191
  x = Math.min(0.6, Math.max(-0.3, x)), I = Math.min(0.8, Math.max(-0.8, I));
6192
6192
  let B = (Math.random() - 0.5) / 4, p = (Math.random() - 0.5) / 4;
6193
6193
  if (n) {
6194
- let H = this.animQueue.findIndex((v) => v.template.name === "lookat");
6194
+ let H = this.animQueue.findIndex((R) => R.template.name === "lookat");
6195
6195
  H !== -1 && this.animQueue.splice(H, 1);
6196
6196
  const z = {
6197
6197
  name: "lookat",
@@ -6226,10 +6226,10 @@ class Oe {
6226
6226
  s.setFromCamera(i, this.camera);
6227
6227
  const o = s.intersectObject(this.armature);
6228
6228
  if (o.length > 0) {
6229
- const l = o[0].point, u = new f.Vector3(), a = new f.Vector3();
6230
- this.objectLeftArm.getWorldPosition(u), this.objectRightArm.getWorldPosition(a);
6231
- const h = u.distanceToSquared(l), r = a.distanceToSquared(l);
6232
- h < r ? (this.ikSolve({
6229
+ const l = o[0].point, u = new f.Vector3(), r = new f.Vector3();
6230
+ this.objectLeftArm.getWorldPosition(u), this.objectRightArm.getWorldPosition(r);
6231
+ const h = u.distanceToSquared(l), a = r.distanceToSquared(l);
6232
+ h < a ? (this.ikSolve({
6233
6233
  iterations: 20,
6234
6234
  root: "LeftShoulder",
6235
6235
  effector: "LeftHandMiddle1",
@@ -6372,16 +6372,16 @@ class Oe {
6372
6372
  this.positionWasLocked = !o, o ? console.log("Position locking disabled for FBX animation:", t) : (this.lockAvatarPosition(), console.log("Position locked immediately before FBX animation:", t));
6373
6373
  let l = this.animClips.find((u) => u.url === t + "-" + i);
6374
6374
  if (l) {
6375
- let u = this.animQueue.find((r) => r.template.name === "pose");
6376
- u && (u.ts[0] = 1 / 0), Object.entries(l.pose.props).forEach((r) => {
6377
- this.poseBase.props[r[0]] = r[1].clone(), this.poseTarget.props[r[0]] = r[1].clone(), this.poseTarget.props[r[0]].t = 0, this.poseTarget.props[r[0]].d = 1e3;
6375
+ let u = this.animQueue.find((a) => a.template.name === "pose");
6376
+ u && (u.ts[0] = 1 / 0), Object.entries(l.pose.props).forEach((a) => {
6377
+ this.poseBase.props[a[0]] = a[1].clone(), this.poseTarget.props[a[0]] = a[1].clone(), this.poseTarget.props[a[0]].t = 0, this.poseTarget.props[a[0]].d = 1e3;
6378
6378
  }), this.mixer ? console.log("Using existing mixer for FBX animation, preserving morph targets") : (this.mixer = new f.AnimationMixer(this.armature), console.log("Created new mixer for FBX animation")), this.mixer.addEventListener("finished", this.stopAnimation.bind(this), { once: !0 });
6379
- const a = Math.ceil(n / l.clip.duration), h = this.mixer.clipAction(l.clip);
6380
- h.setLoop(f.LoopRepeat, a), h.clampWhenFinished = !0, this.currentFBXAction = h;
6379
+ const r = Math.ceil(n / l.clip.duration), h = this.mixer.clipAction(l.clip);
6380
+ h.setLoop(f.LoopRepeat, r), h.clampWhenFinished = !0, this.currentFBXAction = h;
6381
6381
  try {
6382
6382
  h.fadeIn(0.5).play(), console.log("FBX animation started successfully:", t);
6383
- } catch (r) {
6384
- console.warn("FBX animation failed to start:", r), this.stopAnimation();
6383
+ } catch (a) {
6384
+ console.warn("FBX animation failed to start:", a), this.stopAnimation();
6385
6385
  return;
6386
6386
  }
6387
6387
  if (h.getClip().tracks.length === 0) {
@@ -6393,10 +6393,10 @@ class Oe {
6393
6393
  console.error(`Invalid file type for FBX animation: ${t}. Expected .fbx file.`);
6394
6394
  return;
6395
6395
  }
6396
- let a = !1;
6396
+ let r = !1;
6397
6397
  try {
6398
6398
  const c = await fetch(t, { method: "HEAD" });
6399
- if (a = c.ok, !a) {
6399
+ if (r = c.ok, !r) {
6400
6400
  console.error(`FBX file not found at ${t}. Status: ${c.status}`), console.error("Please check:"), console.error("1. File path is correct (note: path is case-sensitive)"), console.error("2. File exists in your public folder"), console.error("3. File is accessible (not blocked by server)");
6401
6401
  return;
6402
6402
  }
@@ -6404,9 +6404,9 @@ class Oe {
6404
6404
  console.warn(`Could not verify file existence for ${t}, attempting to load anyway:`, c);
6405
6405
  }
6406
6406
  const h = new Me();
6407
- let r;
6407
+ let a;
6408
6408
  try {
6409
- r = await h.loadAsync(t, e);
6409
+ a = await h.loadAsync(t, e);
6410
6410
  } catch (c) {
6411
6411
  console.error(`Failed to load FBX animation from ${t}:`, c), console.error("Error details:", {
6412
6412
  message: c.message,
@@ -6426,8 +6426,8 @@ class Oe {
6426
6426
  }
6427
6427
  return;
6428
6428
  }
6429
- if (r && r.animations && r.animations[i]) {
6430
- let c = r.animations[i];
6429
+ if (a && a.animations && a.animations[i]) {
6430
+ let c = a.animations[i];
6431
6431
  const d = {};
6432
6432
  c.tracks.forEach((y) => {
6433
6433
  y.name = y.name.replaceAll("mixamorig", "");
@@ -6446,7 +6446,7 @@ class Oe {
6446
6446
  }), this.playAnimation(t, e, n, i, s);
6447
6447
  } else {
6448
6448
  const c = "Animation " + t + " (ndx=" + i + ") not found";
6449
- console.error(c), r && r.animations ? console.error(`FBX file loaded but has ${r.animations.length} animation(s), requested index ${i}`) : console.error(r ? "FBX file loaded but contains no animations" : "FBX file failed to load or is invalid");
6449
+ console.error(c), a && a.animations ? console.error(`FBX file loaded but has ${a.animations.length} animation(s), requested index ${i}`) : console.error(a ? "FBX file loaded but contains no animations" : "FBX file failed to load or is invalid");
6450
6450
  }
6451
6451
  }
6452
6452
  }
@@ -6482,21 +6482,21 @@ class Oe {
6482
6482
  } else {
6483
6483
  let u = await new Me().loadAsync(t, e);
6484
6484
  if (u && u.animations && u.animations[i]) {
6485
- let a = u.animations[i];
6485
+ let r = u.animations[i];
6486
6486
  const h = {};
6487
- a.tracks.forEach((c) => {
6487
+ r.tracks.forEach((c) => {
6488
6488
  c.name = c.name.replaceAll("mixamorig", "");
6489
6489
  const d = c.name.split(".");
6490
6490
  d[1] === "position" ? h[c.name] = new f.Vector3(c.values[0] * s, c.values[1] * s, c.values[2] * s) : d[1] === "quaternion" ? h[c.name] = new f.Quaternion(c.values[0], c.values[1], c.values[2], c.values[3]) : d[1] === "rotation" && (h[d[0] + ".quaternion"] = new f.Quaternion().setFromEuler(new f.Euler(c.values[0], c.values[1], c.values[2], "XYZ")).normalize());
6491
6491
  });
6492
- const r = { props: h };
6493
- h["Hips.position"] && (h["Hips.position"].y < 0.5 ? r.lying = !0 : r.standing = !0), this.animPoses.push({
6492
+ const a = { props: h };
6493
+ h["Hips.position"] && (h["Hips.position"].y < 0.5 ? a.lying = !0 : a.standing = !0), this.animPoses.push({
6494
6494
  url: t + "-" + i,
6495
- pose: r
6495
+ pose: a
6496
6496
  }), this.playPose(t, e, n, i, s);
6497
6497
  } else {
6498
- const a = "Pose " + t + " (ndx=" + i + ") not found";
6499
- console.error(a);
6498
+ const r = "Pose " + t + " (ndx=" + i + ") not found";
6499
+ console.error(r);
6500
6500
  }
6501
6501
  }
6502
6502
  }
@@ -6521,8 +6521,8 @@ class Oe {
6521
6521
  this.gestureTimeout && (clearTimeout(this.gestureTimeout), this.gestureTimeout = null);
6522
6522
  let l = this.animQueue.findIndex((u) => u.template.name === "talkinghands");
6523
6523
  l !== -1 && (this.animQueue[l].ts = this.animQueue[l].ts.map((u) => 0)), this.gesture = this.propsToThreeObjects(s), n && (this.gesture = this.mirrorPose(this.gesture)), t === "namaste" && this.avatar.body === "M" && (this.gesture["RightArm.quaternion"].rotateTowards(new f.Quaternion(0, 1, 0, 0), -0.25), this.gesture["LeftArm.quaternion"].rotateTowards(new f.Quaternion(0, 1, 0, 0), -0.25));
6524
- for (let [u, a] of Object.entries(this.gesture))
6525
- a.t = this.animClock, a.d = i, this.poseTarget.props.hasOwnProperty(u) && (this.poseTarget.props[u].copy(a), this.poseTarget.props[u].t = this.animClock, this.poseTarget.props[u].d = i);
6524
+ for (let [u, r] of Object.entries(this.gesture))
6525
+ r.t = this.animClock, r.d = i, this.poseTarget.props.hasOwnProperty(u) && (this.poseTarget.props[u].copy(r), this.poseTarget.props[u].t = this.animClock, this.poseTarget.props[u].d = i);
6526
6526
  e && Number.isFinite(e) && (this.gestureTimeout = setTimeout(this.stopGesture.bind(this, i), 1e3 * e));
6527
6527
  }
6528
6528
  let o = this.animEmojis[t];
@@ -6568,7 +6568,7 @@ class Oe {
6568
6568
  * @param {numeric} [d=null] If set, apply in d milliseconds
6569
6569
  */
6570
6570
  ikSolve(t, e = null, n = !1, i = null) {
6571
- const s = new f.Vector3(), o = new f.Vector3(), l = new f.Vector3(), u = new f.Vector3(), a = new f.Quaternion(), h = new f.Vector3(), r = new f.Vector3(), c = new f.Vector3(), d = this.ikMesh.getObjectByName(t.root);
6571
+ const s = new f.Vector3(), o = new f.Vector3(), l = new f.Vector3(), u = new f.Vector3(), r = new f.Quaternion(), h = new f.Vector3(), a = new f.Vector3(), c = new f.Vector3(), d = this.ikMesh.getObjectByName(t.root);
6572
6572
  d.position.setFromMatrixPosition(this.armature.getObjectByName(t.root).matrixWorld), d.quaternion.setFromRotationMatrix(this.armature.getObjectByName(t.root).matrixWorld), e && n && e.applyQuaternion(this.armature.quaternion).add(d.position);
6573
6573
  const g = this.ikMesh.getObjectByName(t.effector), y = t.links;
6574
6574
  y.forEach((I) => {
@@ -6580,9 +6580,9 @@ class Oe {
6580
6580
  let B = !1;
6581
6581
  for (let p = 0, H = y.length; p < H; p++) {
6582
6582
  const z = y[p].bone;
6583
- z.matrixWorld.decompose(u, a, h), a.invert(), o.setFromMatrixPosition(g.matrixWorld), l.subVectors(o, u), l.applyQuaternion(a), l.normalize(), s.subVectors(e, u), s.applyQuaternion(a), s.normalize();
6584
- let v = s.dot(l);
6585
- v > 1 ? v = 1 : v < -1 && (v = -1), v = Math.acos(v), !(v < 1e-5) && (y[p].minAngle !== void 0 && v < y[p].minAngle && (v = y[p].minAngle), y[p].maxAngle !== void 0 && v > y[p].maxAngle && (v = y[p].maxAngle), r.crossVectors(l, s), r.normalize(), G.setFromAxisAngle(r, v), z.quaternion.multiply(G), z.rotation.setFromVector3(c.setFromEuler(z.rotation).clamp(new f.Vector3(
6583
+ z.matrixWorld.decompose(u, r, h), r.invert(), o.setFromMatrixPosition(g.matrixWorld), l.subVectors(o, u), l.applyQuaternion(r), l.normalize(), s.subVectors(e, u), s.applyQuaternion(r), s.normalize();
6584
+ let R = s.dot(l);
6585
+ R > 1 ? R = 1 : R < -1 && (R = -1), R = Math.acos(R), !(R < 1e-5) && (y[p].minAngle !== void 0 && R < y[p].minAngle && (R = y[p].minAngle), y[p].maxAngle !== void 0 && R > y[p].maxAngle && (R = y[p].maxAngle), a.crossVectors(l, s), a.normalize(), G.setFromAxisAngle(a, R), z.quaternion.multiply(G), z.rotation.setFromVector3(c.setFromEuler(z.rotation).clamp(new f.Vector3(
6586
6586
  y[p].minx !== void 0 ? y[p].minx : -1 / 0,
6587
6587
  y[p].miny !== void 0 ? y[p].miny : -1 / 0,
6588
6588
  y[p].minz !== void 0 ? y[p].minz : -1 / 0
@@ -6605,7 +6605,7 @@ class Oe {
6605
6605
  this.isRunning = !1, this.stop(), this.stopSpeaking(), this.streamStop(), this.isAvatarOnly ? this.armature && (this.armature.parent && this.armature.parent.remove(this.armature), this.clearThree(this.armature)) : (this.clearThree(this.scene), this.resizeobserver.disconnect(), this.renderer && (this.renderer.dispose(), this.renderer.domElement && this.renderer.domElement.parentNode && this.renderer.domElement.parentNode.removeChild(this.renderer.domElement), this.renderer = null)), this.clearThree(this.ikMesh), this.dynamicbones.dispose();
6606
6606
  }
6607
6607
  }
6608
- const Re = {
6608
+ const ve = {
6609
6609
  apiKey: "sk_ace57ef3ef65a92b9d3bee2a00183b78ca790bc3e10964f2",
6610
6610
  // Replace with your actual API key (should start with sk_)
6611
6611
  endpoint: "https://api.elevenlabs.io/v1/text-to-speech",
@@ -6648,10 +6648,10 @@ const Re = {
6648
6648
  function He() {
6649
6649
  return {
6650
6650
  service: "elevenlabs",
6651
- endpoint: Re.endpoint,
6652
- apiKey: Re.apiKey,
6653
- defaultVoice: Re.defaultVoice,
6654
- voices: Re.voices
6651
+ endpoint: ve.endpoint,
6652
+ apiKey: ve.apiKey,
6653
+ defaultVoice: ve.defaultVoice,
6654
+ voices: ve.voices
6655
6655
  };
6656
6656
  }
6657
6657
  function St() {
@@ -6673,9 +6673,9 @@ const Ne = ze(({
6673
6673
  ttsApiKey: o = null,
6674
6674
  bodyMovement: l = "idle",
6675
6675
  movementIntensity: u = 0.5,
6676
- showFullAvatar: a = !0,
6676
+ showFullAvatar: r = !0,
6677
6677
  cameraView: h = "upper",
6678
- onReady: r = () => {
6678
+ onReady: a = () => {
6679
6679
  },
6680
6680
  onLoading: c = () => {
6681
6681
  },
@@ -6685,12 +6685,12 @@ const Ne = ze(({
6685
6685
  style: y = {},
6686
6686
  animations: x = {}
6687
6687
  }, I) => {
6688
- const B = N(null), p = N(null), H = N(a), z = N(null), v = N(null), T = N(!1), F = N({ remainingText: null, originalText: null, options: null }), J = N([]), ye = N(0), [S, W] = be(!0), [Y, Z] = be(null), [$, se] = be(!1), [de, me] = be(!1);
6689
- ve(() => {
6688
+ const B = N(null), p = N(null), H = N(r), z = N(null), R = N(null), T = N(!1), F = N({ remainingText: null, originalText: null, options: null }), J = N([]), ye = N(0), [S, W] = be(!0), [Y, Z] = be(null), [$, se] = be(!1), [de, me] = be(!1);
6689
+ Re(() => {
6690
6690
  T.current = de;
6691
- }, [de]), ve(() => {
6692
- H.current = a;
6693
- }, [a]);
6691
+ }, [de]), Re(() => {
6692
+ H.current = r;
6693
+ }, [r]);
6694
6694
  const ie = He(), fe = i || ie.service;
6695
6695
  let X;
6696
6696
  fe === "browser" ? X = {
@@ -6702,8 +6702,8 @@ const Ne = ze(({
6702
6702
  service: "elevenlabs",
6703
6703
  endpoint: "https://api.elevenlabs.io/v1/text-to-speech",
6704
6704
  apiKey: o || ie.apiKey,
6705
- defaultVoice: s || ie.defaultVoice || Re.defaultVoice,
6706
- voices: ie.voices || Re.voices
6705
+ defaultVoice: s || ie.defaultVoice || ve.defaultVoice,
6706
+ voices: ie.voices || ve.voices
6707
6707
  } : fe === "deepgram" ? X = {
6708
6708
  service: "deepgram",
6709
6709
  endpoint: "https://api.deepgram.com/v1/speak",
@@ -6722,10 +6722,10 @@ const Ne = ze(({
6722
6722
  ttsLang: fe === "browser" ? "en-US" : n,
6723
6723
  ttsVoice: s || X.defaultVoice,
6724
6724
  lipsyncLang: "en",
6725
- showFullAvatar: a,
6725
+ showFullAvatar: r,
6726
6726
  bodyMovement: l,
6727
6727
  movementIntensity: u
6728
- }, R = {
6728
+ }, v = {
6729
6729
  ttsEndpoint: X.endpoint,
6730
6730
  ttsApikey: X.apiKey,
6731
6731
  ttsService: fe,
@@ -6734,7 +6734,7 @@ const Ne = ze(({
6734
6734
  }, w = M(async () => {
6735
6735
  if (!(!B.current || p.current))
6736
6736
  try {
6737
- if (W(!0), Z(null), p.current = new Oe(B.current, R), p.current.controls && (p.current.controls.enableRotate = !1, p.current.controls.enableZoom = !1, p.current.controls.enablePan = !1, p.current.controls.enableDamping = !1), x && Object.keys(x).length > 0 && (p.current.customAnimations = x), await p.current.showAvatar(b, (V) => {
6737
+ if (W(!0), Z(null), p.current = new Oe(B.current, v), p.current.controls && (p.current.controls.enableRotate = !1, p.current.controls.enableZoom = !1, p.current.controls.enablePan = !1, p.current.controls.enableDamping = !1), x && Object.keys(x).length > 0 && (p.current.customAnimations = x), await p.current.showAvatar(b, (V) => {
6738
6738
  if (V.lengthComputable) {
6739
6739
  const Q = Math.min(100, Math.round(V.loaded / V.total * 100));
6740
6740
  c(Q);
@@ -6746,11 +6746,11 @@ const Ne = ze(({
6746
6746
  Q();
6747
6747
  }), p.current && p.current.setShowFullAvatar)
6748
6748
  try {
6749
- p.current.setShowFullAvatar(a);
6749
+ p.current.setShowFullAvatar(r);
6750
6750
  } catch (V) {
6751
6751
  console.warn("Error setting full body mode on initialization:", V);
6752
6752
  }
6753
- p.current && p.current.controls && (p.current.controls.enableRotate = !1, p.current.controls.enableZoom = !1, p.current.controls.enablePan = !1, p.current.controls.enableDamping = !1, p.current.controls.update()), W(!1), se(!0), r(p.current);
6753
+ p.current && p.current.controls && (p.current.controls.enableRotate = !1, p.current.controls.enableZoom = !1, p.current.controls.enablePan = !1, p.current.controls.enableDamping = !1, p.current.controls.update()), W(!1), se(!0), a(p.current);
6754
6754
  const P = () => {
6755
6755
  document.visibilityState === "visible" ? p.current?.start() : p.current?.stop();
6756
6756
  };
@@ -6760,10 +6760,10 @@ const Ne = ze(({
6760
6760
  } catch (L) {
6761
6761
  console.error("Error initializing TalkingHead:", L), Z(L.message || "Failed to initialize avatar"), W(!1), d(L);
6762
6762
  }
6763
- }, [U, t, e, n, i, s, o, a, l, u, h]);
6764
- ve(() => (w(), () => {
6763
+ }, [U, t, e, n, i, s, o, r, l, u, h]);
6764
+ Re(() => (w(), () => {
6765
6765
  p.current && (p.current.stop(), p.current.dispose(), p.current = null);
6766
- }), [w]), ve(() => {
6766
+ }), [w]), Re(() => {
6767
6767
  if (!B.current || !p.current) return;
6768
6768
  const L = new ResizeObserver((V) => {
6769
6769
  for (const Q of V)
@@ -6787,7 +6787,7 @@ const Ne = ze(({
6787
6787
  }, []), D = M(async (L, P = {}) => {
6788
6788
  if (p.current && $)
6789
6789
  try {
6790
- v.current && (clearInterval(v.current), v.current = null), z.current = { text: L, options: P }, F.current = { remainingText: null, originalText: null, options: null };
6790
+ R.current && (clearInterval(R.current), R.current = null), z.current = { text: L, options: P }, F.current = { remainingText: null, originalText: null, options: null };
6791
6791
  const V = /[!\.\?\n\p{Extended_Pictographic}]/ug, Q = L.split(V).map((O) => O.trim()).filter((O) => O.length > 0);
6792
6792
  J.current = Q, ye.current = 0, me(!1), T.current = !1, await C();
6793
6793
  const ae = {
@@ -6803,7 +6803,7 @@ const Ne = ze(({
6803
6803
  if (Ie++, T.current)
6804
6804
  return;
6805
6805
  if (Ie > xe) {
6806
- if (oe && (clearInterval(oe), oe = null, v.current = null), !ue && !T.current) {
6806
+ if (oe && (clearInterval(oe), oe = null, R.current = null), !ue && !T.current) {
6807
6807
  ue = !0;
6808
6808
  try {
6809
6809
  P.onSpeechEnd();
@@ -6816,7 +6816,7 @@ const Ne = ze(({
6816
6816
  const re = !O.speechQueue || O.speechQueue.length === 0, Le = !O.audioPlaylist || O.audioPlaylist.length === 0;
6817
6817
  O && O.isSpeaking === !1 && re && Le && O.isAudioPlaying === !1 && !ue && !T.current && setTimeout(() => {
6818
6818
  if (O && !T.current && O.isSpeaking === !1 && (!O.speechQueue || O.speechQueue.length === 0) && (!O.audioPlaylist || O.audioPlaylist.length === 0) && O.isAudioPlaying === !1 && !ue && !T.current) {
6819
- ue = !0, oe && (clearInterval(oe), oe = null, v.current = null);
6819
+ ue = !0, oe && (clearInterval(oe), oe = null, R.current = null);
6820
6820
  try {
6821
6821
  P.onSpeechEnd();
6822
6822
  } catch (Ze) {
@@ -6824,7 +6824,7 @@ const Ne = ze(({
6824
6824
  }
6825
6825
  }
6826
6826
  }, 100);
6827
- }, 100), v.current = oe;
6827
+ }, 100), R.current = oe;
6828
6828
  }
6829
6829
  p.current.lipsync && Object.keys(p.current.lipsync).length > 0 ? (p.current.setSlowdownRate && p.current.setSlowdownRate(1.05), p.current.speakText(L, ae)) : setTimeout(async () => {
6830
6830
  await C(), p.current && p.current.lipsync && (p.current.setSlowdownRate && p.current.setSlowdownRate(1.05), p.current.speakText(L, ae));
@@ -6838,7 +6838,7 @@ const Ne = ze(({
6838
6838
  if (p.current && p.current.pauseSpeaking) {
6839
6839
  const L = p.current;
6840
6840
  if (L.isSpeaking || L.audioPlaylist && L.audioPlaylist.length > 0 || L.speechQueue && L.speechQueue.length > 0) {
6841
- v.current && (clearInterval(v.current), v.current = null);
6841
+ R.current && (clearInterval(R.current), R.current = null);
6842
6842
  let V = "";
6843
6843
  if (z.current && J.current.length > 0) {
6844
6844
  const Q = J.current.length, ae = L.speechQueue ? L.speechQueue.filter((xe) => xe && xe.text && Array.isArray(xe.text) && xe.text.length > 0).length : 0, O = L.audioPlaylist && L.audioPlaylist.length > 0, oe = ae + (O ? 1 : 0), Ie = Q - oe;
@@ -7052,7 +7052,7 @@ const pt = ze(({
7052
7052
  style: s = {},
7053
7053
  avatarConfig: o = {}
7054
7054
  }, l) => {
7055
- const u = N(null), a = N(null), [h, r] = be(!0), [c, d] = be(null), [g, y] = be(!1), x = He(), I = o.ttsService || x.service, B = I === "browser" ? {
7055
+ const u = N(null), r = N(null), [h, a] = be(!0), [c, d] = be(null), [g, y] = be(!1), x = He(), I = o.ttsService || x.service, B = I === "browser" ? {
7056
7056
  endpoint: "",
7057
7057
  apiKey: null,
7058
7058
  defaultVoice: "Google US English"
@@ -7083,76 +7083,76 @@ const pt = ze(({
7083
7083
  lipsyncModules: ["en"],
7084
7084
  cameraView: "upper"
7085
7085
  }, z = M(async () => {
7086
- if (!(!u.current || a.current))
7086
+ if (!(!u.current || r.current))
7087
7087
  try {
7088
- if (r(!0), d(null), a.current = new Oe(u.current, H), await a.current.showAvatar(p, (Y) => {
7088
+ if (a(!0), d(null), r.current = new Oe(u.current, H), await r.current.showAvatar(p, (Y) => {
7089
7089
  if (Y.lengthComputable) {
7090
7090
  const Z = Math.min(100, Math.round(Y.loaded / Y.total * 100));
7091
7091
  t(Z);
7092
7092
  }
7093
- }), a.current.morphs && a.current.morphs.length > 0) {
7094
- const Y = a.current.morphs[0].morphTargetDictionary;
7093
+ }), r.current.morphs && r.current.morphs.length > 0) {
7094
+ const Y = r.current.morphs[0].morphTargetDictionary;
7095
7095
  console.log("Available morph targets:", Object.keys(Y));
7096
7096
  const Z = Object.keys(Y).filter(($) => $.startsWith("viseme_"));
7097
7097
  console.log("Viseme morph targets found:", Z), Z.length === 0 && (console.warn("No viseme morph targets found! Lip-sync will not work properly."), console.log("Expected viseme targets: viseme_aa, viseme_E, viseme_I, viseme_O, viseme_U, viseme_PP, viseme_SS, viseme_TH, viseme_DD, viseme_FF, viseme_kk, viseme_nn, viseme_RR, viseme_CH, viseme_sil"));
7098
7098
  }
7099
7099
  if (await new Promise((Y) => {
7100
7100
  const Z = () => {
7101
- a.current.lipsync && Object.keys(a.current.lipsync).length > 0 ? (console.log("Lip-sync modules loaded:", Object.keys(a.current.lipsync)), Y()) : (console.log("Waiting for lip-sync modules to load..."), setTimeout(Z, 100));
7101
+ r.current.lipsync && Object.keys(r.current.lipsync).length > 0 ? (console.log("Lip-sync modules loaded:", Object.keys(r.current.lipsync)), Y()) : (console.log("Waiting for lip-sync modules to load..."), setTimeout(Z, 100));
7102
7102
  };
7103
7103
  Z();
7104
- }), a.current && a.current.setShowFullAvatar)
7104
+ }), r.current && r.current.setShowFullAvatar)
7105
7105
  try {
7106
- a.current.setShowFullAvatar(!0), console.log("Avatar initialized in full body mode");
7106
+ r.current.setShowFullAvatar(!0), console.log("Avatar initialized in full body mode");
7107
7107
  } catch (Y) {
7108
7108
  console.warn("Error setting full body mode on initialization:", Y);
7109
7109
  }
7110
- r(!1), y(!0), n(a.current);
7110
+ a(!1), y(!0), n(r.current);
7111
7111
  const W = () => {
7112
- document.visibilityState === "visible" ? a.current?.start() : a.current?.stop();
7112
+ document.visibilityState === "visible" ? r.current?.start() : r.current?.stop();
7113
7113
  };
7114
7114
  return document.addEventListener("visibilitychange", W), () => {
7115
7115
  document.removeEventListener("visibilitychange", W);
7116
7116
  };
7117
7117
  } catch (S) {
7118
- console.error("Error initializing TalkingHead:", S), d(S.message || "Failed to initialize avatar"), r(!1), e(S);
7118
+ console.error("Error initializing TalkingHead:", S), d(S.message || "Failed to initialize avatar"), a(!1), e(S);
7119
7119
  }
7120
7120
  }, []);
7121
- ve(() => (z(), () => {
7122
- a.current && (a.current.stop(), a.current.dispose(), a.current = null);
7121
+ Re(() => (z(), () => {
7122
+ r.current && (r.current.stop(), r.current.dispose(), r.current = null);
7123
7123
  }), [z]);
7124
- const v = M((S) => {
7125
- if (a.current && g)
7124
+ const R = M((S) => {
7125
+ if (r.current && g)
7126
7126
  try {
7127
- console.log("Speaking text:", S), console.log("Avatar config:", p), console.log("TalkingHead instance:", a.current), a.current.lipsync && Object.keys(a.current.lipsync).length > 0 ? (console.log("Lip-sync modules loaded:", Object.keys(a.current.lipsync)), a.current.setSlowdownRate && (a.current.setSlowdownRate(1.05), console.log("Applied timing adjustment for better lip-sync")), a.current.speakText(S)) : (console.warn("Lip-sync modules not ready, waiting..."), setTimeout(() => {
7128
- a.current && a.current.lipsync ? (console.log("Lip-sync now ready, speaking..."), a.current.setSlowdownRate && (a.current.setSlowdownRate(1.05), console.log("Applied timing adjustment for better lip-sync")), a.current.speakText(S)) : console.error("Lip-sync still not ready after waiting");
7127
+ console.log("Speaking text:", S), console.log("Avatar config:", p), console.log("TalkingHead instance:", r.current), r.current.lipsync && Object.keys(r.current.lipsync).length > 0 ? (console.log("Lip-sync modules loaded:", Object.keys(r.current.lipsync)), r.current.setSlowdownRate && (r.current.setSlowdownRate(1.05), console.log("Applied timing adjustment for better lip-sync")), r.current.speakText(S)) : (console.warn("Lip-sync modules not ready, waiting..."), setTimeout(() => {
7128
+ r.current && r.current.lipsync ? (console.log("Lip-sync now ready, speaking..."), r.current.setSlowdownRate && (r.current.setSlowdownRate(1.05), console.log("Applied timing adjustment for better lip-sync")), r.current.speakText(S)) : console.error("Lip-sync still not ready after waiting");
7129
7129
  }, 500));
7130
7130
  } catch (W) {
7131
7131
  console.error("Error speaking text:", W), d(W.message || "Failed to speak text");
7132
7132
  }
7133
7133
  else
7134
- console.warn("Avatar not ready for speaking. isReady:", g, "talkingHeadRef:", !!a.current);
7134
+ console.warn("Avatar not ready for speaking. isReady:", g, "talkingHeadRef:", !!r.current);
7135
7135
  }, [g, p]), T = M(() => {
7136
- a.current && (a.current.stopSpeaking(), a.current.setSlowdownRate && (a.current.setSlowdownRate(1), console.log("Reset timing to normal")));
7136
+ r.current && (r.current.stopSpeaking(), r.current.setSlowdownRate && (r.current.setSlowdownRate(1), console.log("Reset timing to normal")));
7137
7137
  }, []), F = M((S) => {
7138
- a.current && a.current.setMood(S);
7138
+ r.current && r.current.setMood(S);
7139
7139
  }, []), J = M((S) => {
7140
- a.current && a.current.setSlowdownRate && (a.current.setSlowdownRate(S), console.log("Timing adjustment set to:", S));
7140
+ r.current && r.current.setSlowdownRate && (r.current.setSlowdownRate(S), console.log("Timing adjustment set to:", S));
7141
7141
  }, []), ye = M((S, W = !1) => {
7142
- if (a.current && a.current.playAnimation) {
7143
- if (a.current.setShowFullAvatar)
7142
+ if (r.current && r.current.playAnimation) {
7143
+ if (r.current.setShowFullAvatar)
7144
7144
  try {
7145
- a.current.setShowFullAvatar(!0);
7145
+ r.current.setShowFullAvatar(!0);
7146
7146
  } catch (Z) {
7147
7147
  console.warn("Error setting full body mode:", Z);
7148
7148
  }
7149
7149
  if (S.includes("."))
7150
7150
  try {
7151
- a.current.playAnimation(S, null, 10, 0, 0.01, W), console.log("Playing animation:", S);
7151
+ r.current.playAnimation(S, null, 10, 0, 0.01, W), console.log("Playing animation:", S);
7152
7152
  } catch (Z) {
7153
7153
  console.log(`Failed to play ${S}:`, Z);
7154
7154
  try {
7155
- a.current.setBodyMovement("idle"), console.log("Fallback to idle animation");
7155
+ r.current.setBodyMovement("idle"), console.log("Fallback to idle animation");
7156
7156
  } catch ($) {
7157
7157
  console.warn("Fallback animation also failed:", $);
7158
7158
  }
@@ -7162,7 +7162,7 @@ const pt = ze(({
7162
7162
  let $ = !1;
7163
7163
  for (const se of Z)
7164
7164
  try {
7165
- a.current.playAnimation(S + se, null, 10, 0, 0.01, W), console.log("Playing animation:", S + se), $ = !0;
7165
+ r.current.playAnimation(S + se, null, 10, 0, 0.01, W), console.log("Playing animation:", S + se), $ = !0;
7166
7166
  break;
7167
7167
  } catch {
7168
7168
  console.log(`Failed to play ${S}${se}, trying next format...`);
@@ -7170,7 +7170,7 @@ const pt = ze(({
7170
7170
  if (!$) {
7171
7171
  console.warn("Animation system not available or animation not found:", S);
7172
7172
  try {
7173
- a.current.setBodyMovement("idle"), console.log("Fallback to idle animation");
7173
+ r.current.setBodyMovement("idle"), console.log("Fallback to idle animation");
7174
7174
  } catch (se) {
7175
7175
  console.warn("Fallback animation also failed:", se);
7176
7176
  }
@@ -7180,66 +7180,66 @@ const pt = ze(({
7180
7180
  console.warn("Animation system not available or animation not found:", S);
7181
7181
  }, []);
7182
7182
  return Ce(l, () => ({
7183
- speakText: v,
7183
+ speakText: R,
7184
7184
  stopSpeaking: T,
7185
7185
  setMood: F,
7186
7186
  setTimingAdjustment: J,
7187
7187
  playAnimation: ye,
7188
7188
  isReady: g,
7189
- talkingHead: a.current,
7189
+ talkingHead: r.current,
7190
7190
  setBodyMovement: (S) => {
7191
- if (a.current && a.current.setShowFullAvatar && a.current.setBodyMovement)
7191
+ if (r.current && r.current.setShowFullAvatar && r.current.setBodyMovement)
7192
7192
  try {
7193
- a.current.setShowFullAvatar(!0), a.current.setBodyMovement(S), console.log("Body movement set with full body mode:", S);
7193
+ r.current.setShowFullAvatar(!0), r.current.setBodyMovement(S), console.log("Body movement set with full body mode:", S);
7194
7194
  } catch (W) {
7195
7195
  console.warn("Error setting body movement:", W);
7196
7196
  }
7197
7197
  },
7198
- setMovementIntensity: (S) => a.current?.setMovementIntensity(S),
7198
+ setMovementIntensity: (S) => r.current?.setMovementIntensity(S),
7199
7199
  playRandomDance: () => {
7200
- if (a.current && a.current.setShowFullAvatar && a.current.playRandomDance)
7200
+ if (r.current && r.current.setShowFullAvatar && r.current.playRandomDance)
7201
7201
  try {
7202
- a.current.setShowFullAvatar(!0), a.current.playRandomDance(), console.log("Random dance played with full body mode");
7202
+ r.current.setShowFullAvatar(!0), r.current.playRandomDance(), console.log("Random dance played with full body mode");
7203
7203
  } catch (S) {
7204
7204
  console.warn("Error playing random dance:", S);
7205
7205
  }
7206
7206
  },
7207
7207
  playReaction: (S) => {
7208
- if (a.current && a.current.setShowFullAvatar && a.current.playReaction)
7208
+ if (r.current && r.current.setShowFullAvatar && r.current.playReaction)
7209
7209
  try {
7210
- a.current.setShowFullAvatar(!0), a.current.playReaction(S), console.log("Reaction played with full body mode:", S);
7210
+ r.current.setShowFullAvatar(!0), r.current.playReaction(S), console.log("Reaction played with full body mode:", S);
7211
7211
  } catch (W) {
7212
7212
  console.warn("Error playing reaction:", W);
7213
7213
  }
7214
7214
  },
7215
7215
  playCelebration: () => {
7216
- if (a.current && a.current.setShowFullAvatar && a.current.playCelebration)
7216
+ if (r.current && r.current.setShowFullAvatar && r.current.playCelebration)
7217
7217
  try {
7218
- a.current.setShowFullAvatar(!0), a.current.playCelebration(), console.log("Celebration played with full body mode");
7218
+ r.current.setShowFullAvatar(!0), r.current.playCelebration(), console.log("Celebration played with full body mode");
7219
7219
  } catch (S) {
7220
7220
  console.warn("Error playing celebration:", S);
7221
7221
  }
7222
7222
  },
7223
7223
  setShowFullAvatar: (S) => {
7224
- if (a.current && a.current.setShowFullAvatar)
7224
+ if (r.current && r.current.setShowFullAvatar)
7225
7225
  try {
7226
- a.current.setShowFullAvatar(S), console.log("Show full avatar set to:", S);
7226
+ r.current.setShowFullAvatar(S), console.log("Show full avatar set to:", S);
7227
7227
  } catch (W) {
7228
7228
  console.warn("Error setting showFullAvatar:", W);
7229
7229
  }
7230
7230
  },
7231
7231
  lockAvatarPosition: () => {
7232
- if (a.current && a.current.lockAvatarPosition)
7232
+ if (r.current && r.current.lockAvatarPosition)
7233
7233
  try {
7234
- a.current.lockAvatarPosition();
7234
+ r.current.lockAvatarPosition();
7235
7235
  } catch (S) {
7236
7236
  console.warn("Error locking avatar position:", S);
7237
7237
  }
7238
7238
  },
7239
7239
  unlockAvatarPosition: () => {
7240
- if (a.current && a.current.unlockAvatarPosition)
7240
+ if (r.current && r.current.unlockAvatarPosition)
7241
7241
  try {
7242
- a.current.unlockAvatarPosition();
7242
+ r.current.unlockAvatarPosition();
7243
7243
  } catch (S) {
7244
7244
  console.warn("Error unlocking avatar position:", S);
7245
7245
  }
@@ -7296,8 +7296,8 @@ const gt = ze(({
7296
7296
  onCustomAction: l = () => {
7297
7297
  },
7298
7298
  autoStart: u = !1
7299
- }, a) => {
7300
- const h = N(null), r = N({
7299
+ }, r) => {
7300
+ const h = N(null), a = N({
7301
7301
  currentModuleIndex: 0,
7302
7302
  currentLessonIndex: 0,
7303
7303
  currentQuestionIndex: 0,
@@ -7332,7 +7332,7 @@ const gt = ze(({
7332
7332
  animations: e,
7333
7333
  lipsyncLang: "en"
7334
7334
  });
7335
- ve(() => {
7335
+ Re(() => {
7336
7336
  c.current = {
7337
7337
  onLessonStart: n,
7338
7338
  onLessonComplete: i,
@@ -7340,7 +7340,7 @@ const gt = ze(({
7340
7340
  onCurriculumComplete: o,
7341
7341
  onCustomAction: l
7342
7342
  };
7343
- }, [n, i, s, o, l]), ve(() => {
7343
+ }, [n, i, s, o, l]), Re(() => {
7344
7344
  H.current = U?.curriculum || {
7345
7345
  title: "Default Curriculum",
7346
7346
  description: "No curriculum data provided",
@@ -7361,22 +7361,22 @@ const gt = ze(({
7361
7361
  lipsyncLang: "en"
7362
7362
  };
7363
7363
  }, [U, t, e]);
7364
- const v = M(() => (H.current || { modules: [] }).modules[r.current.currentModuleIndex]?.lessons[r.current.currentLessonIndex], []), T = M(() => v()?.questions[r.current.currentQuestionIndex], [v]), F = M((b, R) => R.type === "multiple_choice" || R.type === "true_false" ? b === R.answer : R.type === "code_test" && typeof b == "object" && b !== null ? b.passed === !0 : !1, []), J = M(() => {
7365
- r.current.lessonCompleted = !0, r.current.isQuestionMode = !1;
7366
- const b = r.current.totalQuestions > 0 ? Math.round(r.current.score / r.current.totalQuestions * 100) : 100;
7367
- let R = "Congratulations! You've completed this lesson";
7368
- if (r.current.totalQuestions > 0 ? R += ` You got ${r.current.score} correct out of ${r.current.totalQuestions} question${r.current.totalQuestions === 1 ? "" : "s"}, achieving a score of ${b} percent. ` : R += "! ", b >= 80 ? R += "Excellent work! You have a great understanding of this topic." : b >= 60 ? R += "Good job! You understand most of the concepts." : R += "Keep practicing! You're making progress.", c.current.onLessonComplete({
7369
- moduleIndex: r.current.currentModuleIndex,
7370
- lessonIndex: r.current.currentLessonIndex,
7371
- score: r.current.score,
7372
- totalQuestions: r.current.totalQuestions,
7364
+ const R = M(() => (H.current || { modules: [] }).modules[a.current.currentModuleIndex]?.lessons[a.current.currentLessonIndex], []), T = M(() => R()?.questions[a.current.currentQuestionIndex], [R]), F = M((b, v) => v.type === "multiple_choice" || v.type === "true_false" ? b === v.answer : v.type === "code_test" && typeof b == "object" && b !== null ? b.passed === !0 : !1, []), J = M(() => {
7365
+ a.current.lessonCompleted = !0, a.current.isQuestionMode = !1;
7366
+ const b = a.current.totalQuestions > 0 ? Math.round(a.current.score / a.current.totalQuestions * 100) : 100;
7367
+ let v = "Congratulations! You've completed this lesson";
7368
+ if (a.current.totalQuestions > 0 ? v += ` You got ${a.current.score} correct out of ${a.current.totalQuestions} question${a.current.totalQuestions === 1 ? "" : "s"}, achieving a score of ${b} percent. ` : v += "! ", b >= 80 ? v += "Excellent work! You have a great understanding of this topic." : b >= 60 ? v += "Good job! You understand most of the concepts." : v += "Keep practicing! You're making progress.", c.current.onLessonComplete({
7369
+ moduleIndex: a.current.currentModuleIndex,
7370
+ lessonIndex: a.current.currentLessonIndex,
7371
+ score: a.current.score,
7372
+ totalQuestions: a.current.totalQuestions,
7373
7373
  percentage: b
7374
7374
  }), c.current.onCustomAction({
7375
7375
  type: "lessonComplete",
7376
- moduleIndex: r.current.currentModuleIndex,
7377
- lessonIndex: r.current.currentLessonIndex,
7378
- score: r.current.score,
7379
- totalQuestions: r.current.totalQuestions,
7376
+ moduleIndex: a.current.currentModuleIndex,
7377
+ lessonIndex: a.current.currentLessonIndex,
7378
+ score: a.current.score,
7379
+ totalQuestions: a.current.totalQuestions,
7380
7380
  percentage: b
7381
7381
  }), h.current) {
7382
7382
  if (h.current.setMood("happy"), e.lessonComplete)
@@ -7385,16 +7385,16 @@ const gt = ze(({
7385
7385
  } catch {
7386
7386
  h.current.playCelebration();
7387
7387
  }
7388
- const w = H.current || { modules: [] }, C = w.modules[r.current.currentModuleIndex], D = r.current.currentLessonIndex < (C?.lessons?.length || 0) - 1, te = r.current.currentModuleIndex < (w.modules?.length || 0) - 1, q = D || te, j = z.current || { lipsyncLang: "en" };
7389
- h.current.speakText(R, {
7388
+ const w = H.current || { modules: [] }, C = w.modules[a.current.currentModuleIndex], D = a.current.currentLessonIndex < (C?.lessons?.length || 0) - 1, te = a.current.currentModuleIndex < (w.modules?.length || 0) - 1, q = D || te, j = z.current || { lipsyncLang: "en" };
7389
+ h.current.speakText(v, {
7390
7390
  lipsyncLang: j.lipsyncLang,
7391
7391
  onSpeechEnd: () => {
7392
7392
  c.current.onCustomAction({
7393
7393
  type: "lessonCompleteFeedbackDone",
7394
- moduleIndex: r.current.currentModuleIndex,
7395
- lessonIndex: r.current.currentLessonIndex,
7396
- score: r.current.score,
7397
- totalQuestions: r.current.totalQuestions,
7394
+ moduleIndex: a.current.currentModuleIndex,
7395
+ lessonIndex: a.current.currentLessonIndex,
7396
+ score: a.current.score,
7397
+ totalQuestions: a.current.totalQuestions,
7398
7398
  percentage: b,
7399
7399
  hasNextLesson: q
7400
7400
  });
@@ -7402,11 +7402,11 @@ const gt = ze(({
7402
7402
  });
7403
7403
  }
7404
7404
  }, [e.lessonComplete]), ye = M(() => {
7405
- r.current.curriculumCompleted = !0;
7405
+ a.current.curriculumCompleted = !0;
7406
7406
  const b = H.current || { modules: [] };
7407
7407
  if (c.current.onCurriculumComplete({
7408
7408
  modules: b.modules.length,
7409
- totalLessons: b.modules.reduce((R, w) => R + w.lessons.length, 0)
7409
+ totalLessons: b.modules.reduce((v, w) => v + w.lessons.length, 0)
7410
7410
  }), h.current) {
7411
7411
  if (h.current.setMood("celebrating"), e.curriculumComplete)
7412
7412
  try {
@@ -7414,24 +7414,24 @@ const gt = ze(({
7414
7414
  } catch {
7415
7415
  h.current.playCelebration();
7416
7416
  }
7417
- const R = z.current || { lipsyncLang: "en" };
7418
- h.current.speakText("Amazing! You've completed the entire curriculum! You're now ready to move on to more advanced topics. Well done!", { lipsyncLang: R.lipsyncLang });
7417
+ const v = z.current || { lipsyncLang: "en" };
7418
+ h.current.speakText("Amazing! You've completed the entire curriculum! You're now ready to move on to more advanced topics. Well done!", { lipsyncLang: v.lipsyncLang });
7419
7419
  }
7420
7420
  }, [e.curriculumComplete]), S = M(() => {
7421
- const b = v();
7422
- r.current.isQuestionMode = !0, r.current.currentQuestionIndex = 0, r.current.totalQuestions = b?.questions?.length || 0, r.current.score = 0;
7423
- const R = T();
7424
- R && c.current.onCustomAction({
7421
+ const b = R();
7422
+ a.current.isQuestionMode = !0, a.current.currentQuestionIndex = 0, a.current.totalQuestions = b?.questions?.length || 0, a.current.score = 0;
7423
+ const v = T();
7424
+ v && c.current.onCustomAction({
7425
7425
  type: "questionStart",
7426
- moduleIndex: r.current.currentModuleIndex,
7427
- lessonIndex: r.current.currentLessonIndex,
7428
- questionIndex: r.current.currentQuestionIndex,
7429
- totalQuestions: r.current.totalQuestions,
7430
- question: R,
7431
- score: r.current.score
7426
+ moduleIndex: a.current.currentModuleIndex,
7427
+ lessonIndex: a.current.currentLessonIndex,
7428
+ questionIndex: a.current.currentQuestionIndex,
7429
+ totalQuestions: a.current.totalQuestions,
7430
+ question: v,
7431
+ score: a.current.score
7432
7432
  });
7433
7433
  const w = () => {
7434
- if (!h.current || !R) return;
7434
+ if (!h.current || !v) return;
7435
7435
  if (h.current.setMood("happy"), e.questionStart)
7436
7436
  try {
7437
7437
  h.current.playAnimation(e.questionStart, !0);
@@ -7439,69 +7439,69 @@ const gt = ze(({
7439
7439
  console.warn("Failed to play questionStart animation:", D);
7440
7440
  }
7441
7441
  const C = z.current || { lipsyncLang: "en" };
7442
- R.type === "code_test" ? h.current.speakText(`Let's test your coding skills! Here's your first challenge: ${R.question}`, { lipsyncLang: C.lipsyncLang }) : R.type === "multiple_choice" ? h.current.speakText(`Now let me ask you some questions. Here's the first one: ${R.question}`, { lipsyncLang: C.lipsyncLang }) : R.type === "true_false" ? h.current.speakText(`Let's start with some true or false questions. First question: ${R.question}`, { lipsyncLang: C.lipsyncLang }) : h.current.speakText(`Now let me ask you some questions. Here's the first one: ${R.question}`, { lipsyncLang: C.lipsyncLang });
7442
+ v.type === "code_test" ? h.current.speakText(`Let's test your coding skills! Here's your first challenge: ${v.question}`, { lipsyncLang: C.lipsyncLang }) : v.type === "multiple_choice" ? h.current.speakText(`Now let me ask you some questions. Here's the first one: ${v.question}`, { lipsyncLang: C.lipsyncLang }) : v.type === "true_false" ? h.current.speakText(`Let's start with some true or false questions. First question: ${v.question}`, { lipsyncLang: C.lipsyncLang }) : h.current.speakText(`Now let me ask you some questions. Here's the first one: ${v.question}`, { lipsyncLang: C.lipsyncLang });
7443
7443
  };
7444
- if (h.current && h.current.isReady && R)
7444
+ if (h.current && h.current.isReady && v)
7445
7445
  w();
7446
7446
  else if (h.current && h.current.isReady) {
7447
7447
  const C = z.current || { lipsyncLang: "en" };
7448
7448
  h.current.speakText("Now let me ask you some questions to test your understanding.", { lipsyncLang: C.lipsyncLang });
7449
7449
  } else {
7450
7450
  const C = setInterval(() => {
7451
- h.current && h.current.isReady && (clearInterval(C), R && w());
7451
+ h.current && h.current.isReady && (clearInterval(C), v && w());
7452
7452
  }, 100);
7453
7453
  setTimeout(() => {
7454
7454
  clearInterval(C);
7455
7455
  }, 5e3);
7456
7456
  }
7457
- }, [e.questionStart, v, T]), W = M(() => {
7458
- const b = v();
7459
- if (r.current.currentQuestionIndex < (b?.questions?.length || 0) - 1) {
7460
- h.current && h.current.stopSpeaking && h.current.stopSpeaking(), r.current.currentQuestionIndex += 1;
7461
- const R = T();
7462
- R && c.current.onCustomAction({
7457
+ }, [e.questionStart, R, T]), W = M(() => {
7458
+ const b = R();
7459
+ if (a.current.currentQuestionIndex < (b?.questions?.length || 0) - 1) {
7460
+ h.current && h.current.stopSpeaking && h.current.stopSpeaking(), a.current.currentQuestionIndex += 1;
7461
+ const v = T();
7462
+ v && c.current.onCustomAction({
7463
7463
  type: "nextQuestion",
7464
- moduleIndex: r.current.currentModuleIndex,
7465
- lessonIndex: r.current.currentLessonIndex,
7466
- questionIndex: r.current.currentQuestionIndex,
7467
- totalQuestions: r.current.totalQuestions,
7468
- question: R,
7469
- score: r.current.score
7464
+ moduleIndex: a.current.currentModuleIndex,
7465
+ lessonIndex: a.current.currentLessonIndex,
7466
+ questionIndex: a.current.currentQuestionIndex,
7467
+ totalQuestions: a.current.totalQuestions,
7468
+ question: v,
7469
+ score: a.current.score
7470
7470
  });
7471
7471
  const w = () => {
7472
- if (!h.current || !R) return;
7472
+ if (!h.current || !v) return;
7473
7473
  if (h.current.setMood("happy"), h.current.setBodyMovement("idle"), e.nextQuestion)
7474
7474
  try {
7475
7475
  h.current.playAnimation(e.nextQuestion, !0);
7476
7476
  } catch (j) {
7477
7477
  console.warn("Failed to play nextQuestion animation:", j);
7478
7478
  }
7479
- const C = z.current || { lipsyncLang: "en" }, te = v()?.questions?.length || 0, q = r.current.currentQuestionIndex >= te - 1;
7480
- if (R.type === "code_test") {
7481
- const j = q ? `Great! Here's your final coding challenge: ${R.question}` : `Great! Now let's move on to your next coding challenge: ${R.question}`;
7479
+ const C = z.current || { lipsyncLang: "en" }, te = R()?.questions?.length || 0, q = a.current.currentQuestionIndex >= te - 1;
7480
+ if (v.type === "code_test") {
7481
+ const j = q ? `Great! Here's your final coding challenge: ${v.question}` : `Great! Now let's move on to your next coding challenge: ${v.question}`;
7482
7482
  h.current.speakText(j, {
7483
7483
  lipsyncLang: C.lipsyncLang
7484
7484
  });
7485
- } else if (R.type === "multiple_choice") {
7486
- const j = q ? `Alright! Here's your final question: ${R.question}` : `Alright! Here's your next question: ${R.question}`;
7485
+ } else if (v.type === "multiple_choice") {
7486
+ const j = q ? `Alright! Here's your final question: ${v.question}` : `Alright! Here's your next question: ${v.question}`;
7487
7487
  h.current.speakText(j, {
7488
7488
  lipsyncLang: C.lipsyncLang
7489
7489
  });
7490
- } else if (R.type === "true_false") {
7491
- const j = q ? `Now let's try this final one: ${R.question}` : `Now let's try this one: ${R.question}`;
7490
+ } else if (v.type === "true_false") {
7491
+ const j = q ? `Now let's try this final one: ${v.question}` : `Now let's try this one: ${v.question}`;
7492
7492
  h.current.speakText(j, {
7493
7493
  lipsyncLang: C.lipsyncLang
7494
7494
  });
7495
7495
  } else {
7496
- const j = q ? `Here's your final question: ${R.question}` : `Here's the next question: ${R.question}`;
7496
+ const j = q ? `Here's your final question: ${v.question}` : `Here's the next question: ${v.question}`;
7497
7497
  h.current.speakText(j, {
7498
7498
  lipsyncLang: C.lipsyncLang
7499
7499
  });
7500
7500
  }
7501
7501
  };
7502
- if (h.current && h.current.isReady && R)
7502
+ if (h.current && h.current.isReady && v)
7503
7503
  w();
7504
- else if (R) {
7504
+ else if (v) {
7505
7505
  const C = setInterval(() => {
7506
7506
  h.current && h.current.isReady && (clearInterval(C), w());
7507
7507
  }, 100);
@@ -7512,51 +7512,51 @@ const gt = ze(({
7512
7512
  } else
7513
7513
  c.current.onCustomAction({
7514
7514
  type: "allQuestionsComplete",
7515
- moduleIndex: r.current.currentModuleIndex,
7516
- lessonIndex: r.current.currentLessonIndex,
7517
- totalQuestions: r.current.totalQuestions,
7518
- score: r.current.score
7515
+ moduleIndex: a.current.currentModuleIndex,
7516
+ lessonIndex: a.current.currentLessonIndex,
7517
+ totalQuestions: a.current.totalQuestions,
7518
+ score: a.current.score
7519
7519
  });
7520
- }, [e.nextQuestion, v, T]), Y = M(() => {
7521
- const b = H.current || { modules: [] }, R = b.modules[r.current.currentModuleIndex];
7522
- if (r.current.currentLessonIndex < (R?.lessons?.length || 0) - 1) {
7523
- r.current.currentLessonIndex += 1, r.current.currentQuestionIndex = 0, r.current.lessonCompleted = !1, r.current.isQuestionMode = !1, r.current.isTeaching = !1, r.current.score = 0, r.current.totalQuestions = 0;
7524
- const C = b.modules[r.current.currentModuleIndex], D = r.current.currentLessonIndex < (C?.lessons?.length || 0) - 1, te = r.current.currentModuleIndex < (b.modules?.length || 0) - 1, q = D || te;
7520
+ }, [e.nextQuestion, R, T]), Y = M(() => {
7521
+ const b = H.current || { modules: [] }, v = b.modules[a.current.currentModuleIndex];
7522
+ if (a.current.currentLessonIndex < (v?.lessons?.length || 0) - 1) {
7523
+ a.current.currentLessonIndex += 1, a.current.currentQuestionIndex = 0, a.current.lessonCompleted = !1, a.current.isQuestionMode = !1, a.current.isTeaching = !1, a.current.score = 0, a.current.totalQuestions = 0;
7524
+ const C = b.modules[a.current.currentModuleIndex], D = a.current.currentLessonIndex < (C?.lessons?.length || 0) - 1, te = a.current.currentModuleIndex < (b.modules?.length || 0) - 1, q = D || te;
7525
7525
  c.current.onCustomAction({
7526
7526
  type: "lessonStart",
7527
- moduleIndex: r.current.currentModuleIndex,
7528
- lessonIndex: r.current.currentLessonIndex,
7527
+ moduleIndex: a.current.currentModuleIndex,
7528
+ lessonIndex: a.current.currentLessonIndex,
7529
7529
  hasNextLesson: q
7530
7530
  }), c.current.onLessonStart({
7531
- moduleIndex: r.current.currentModuleIndex,
7532
- lessonIndex: r.current.currentLessonIndex,
7533
- lesson: v()
7531
+ moduleIndex: a.current.currentModuleIndex,
7532
+ lessonIndex: a.current.currentLessonIndex,
7533
+ lesson: R()
7534
7534
  }), h.current && (h.current.setMood("happy"), h.current.setBodyMovement("idle"));
7535
- } else if (r.current.currentModuleIndex < (b.modules?.length || 0) - 1) {
7536
- r.current.currentModuleIndex += 1, r.current.currentLessonIndex = 0, r.current.currentQuestionIndex = 0, r.current.lessonCompleted = !1, r.current.isQuestionMode = !1, r.current.isTeaching = !1, r.current.score = 0, r.current.totalQuestions = 0;
7537
- const D = b.modules[r.current.currentModuleIndex], te = r.current.currentLessonIndex < (D?.lessons?.length || 0) - 1, q = r.current.currentModuleIndex < (b.modules?.length || 0) - 1, j = te || q;
7535
+ } else if (a.current.currentModuleIndex < (b.modules?.length || 0) - 1) {
7536
+ a.current.currentModuleIndex += 1, a.current.currentLessonIndex = 0, a.current.currentQuestionIndex = 0, a.current.lessonCompleted = !1, a.current.isQuestionMode = !1, a.current.isTeaching = !1, a.current.score = 0, a.current.totalQuestions = 0;
7537
+ const D = b.modules[a.current.currentModuleIndex], te = a.current.currentLessonIndex < (D?.lessons?.length || 0) - 1, q = a.current.currentModuleIndex < (b.modules?.length || 0) - 1, j = te || q;
7538
7538
  c.current.onCustomAction({
7539
7539
  type: "lessonStart",
7540
- moduleIndex: r.current.currentModuleIndex,
7541
- lessonIndex: r.current.currentLessonIndex,
7540
+ moduleIndex: a.current.currentModuleIndex,
7541
+ lessonIndex: a.current.currentLessonIndex,
7542
7542
  hasNextLesson: j
7543
7543
  }), c.current.onLessonStart({
7544
- moduleIndex: r.current.currentModuleIndex,
7545
- lessonIndex: r.current.currentLessonIndex,
7546
- lesson: v()
7544
+ moduleIndex: a.current.currentModuleIndex,
7545
+ lessonIndex: a.current.currentLessonIndex,
7546
+ lesson: R()
7547
7547
  }), h.current && (h.current.setMood("happy"), h.current.setBodyMovement("idle"));
7548
7548
  } else
7549
7549
  I.current && I.current();
7550
7550
  }, []), Z = M(() => {
7551
- const b = v();
7552
- let R = null;
7551
+ const b = R();
7552
+ let v = null;
7553
7553
  if (b?.avatar_script && b?.body) {
7554
7554
  const w = b.avatar_script.trim(), C = b.body.trim(), D = w.match(/[.!?]$/) ? " " : ". ";
7555
- R = `${w}${D}${C}`;
7555
+ v = `${w}${D}${C}`;
7556
7556
  } else
7557
- R = b?.avatar_script || b?.body || null;
7558
- if (h.current && h.current.isReady && R) {
7559
- r.current.isTeaching = !0, r.current.isQuestionMode = !1, r.current.score = 0, r.current.totalQuestions = 0, h.current.setMood("happy");
7557
+ v = b?.avatar_script || b?.body || null;
7558
+ if (h.current && h.current.isReady && v) {
7559
+ a.current.isTeaching = !0, a.current.isQuestionMode = !1, a.current.score = 0, a.current.totalQuestions = 0, h.current.setMood("happy");
7560
7560
  let w = !1;
7561
7561
  if (e.teaching)
7562
7562
  try {
@@ -7567,36 +7567,42 @@ const gt = ze(({
7567
7567
  w || h.current.setBodyMovement("gesturing");
7568
7568
  const C = z.current || { lipsyncLang: "en" };
7569
7569
  c.current.onLessonStart({
7570
- moduleIndex: r.current.currentModuleIndex,
7571
- lessonIndex: r.current.currentLessonIndex,
7570
+ moduleIndex: a.current.currentModuleIndex,
7571
+ lessonIndex: a.current.currentLessonIndex,
7572
7572
  lesson: b
7573
7573
  }), c.current.onCustomAction({
7574
7574
  type: "teachingStart",
7575
- moduleIndex: r.current.currentModuleIndex,
7576
- lessonIndex: r.current.currentLessonIndex,
7575
+ moduleIndex: a.current.currentModuleIndex,
7576
+ lessonIndex: a.current.currentLessonIndex,
7577
7577
  lesson: b
7578
- }), h.current.speakText(R, {
7578
+ }), h.current.speakText(v, {
7579
7579
  lipsyncLang: C.lipsyncLang,
7580
7580
  onSpeechEnd: () => {
7581
- r.current.isTeaching = !1, c.current.onCustomAction({
7581
+ a.current.isTeaching = !1, c.current.onCustomAction({
7582
7582
  type: "teachingComplete",
7583
- moduleIndex: r.current.currentModuleIndex,
7584
- lessonIndex: r.current.currentLessonIndex,
7583
+ moduleIndex: a.current.currentModuleIndex,
7584
+ lessonIndex: a.current.currentLessonIndex,
7585
7585
  lesson: b,
7586
7586
  hasQuestions: b.questions && b.questions.length > 0
7587
+ }), b?.code_example && c.current.onCustomAction({
7588
+ type: "codeExampleReady",
7589
+ moduleIndex: a.current.currentModuleIndex,
7590
+ lessonIndex: a.current.currentLessonIndex,
7591
+ lesson: b,
7592
+ codeExample: b.code_example
7587
7593
  });
7588
7594
  }
7589
7595
  });
7590
7596
  }
7591
- }, [e.teaching, v]), $ = M((b) => {
7592
- const R = T(), w = F(b, R);
7593
- if (w && (r.current.score += 1), c.current.onQuestionAnswer({
7594
- moduleIndex: r.current.currentModuleIndex,
7595
- lessonIndex: r.current.currentLessonIndex,
7596
- questionIndex: r.current.currentQuestionIndex,
7597
+ }, [e.teaching, R]), $ = M((b) => {
7598
+ const v = T(), w = F(b, v);
7599
+ if (w && (a.current.score += 1), c.current.onQuestionAnswer({
7600
+ moduleIndex: a.current.currentModuleIndex,
7601
+ lessonIndex: a.current.currentLessonIndex,
7602
+ questionIndex: a.current.currentQuestionIndex,
7597
7603
  answer: b,
7598
7604
  isCorrect: w,
7599
- question: R
7605
+ question: v
7600
7606
  }), h.current)
7601
7607
  if (w) {
7602
7608
  if (h.current.setMood("happy"), e.correct)
@@ -7606,21 +7612,21 @@ const gt = ze(({
7606
7612
  h.current.setBodyMovement("happy");
7607
7613
  }
7608
7614
  h.current.setBodyMovement("gesturing");
7609
- const D = v()?.questions?.length || 0;
7610
- r.current.currentQuestionIndex >= D - 1;
7611
- const te = R.type === "code_test" ? `Great job! Your code passed all the tests! ${R.explanation || ""}` : `Excellent! That's correct! ${R.explanation || ""}`, q = z.current || { lipsyncLang: "en" };
7615
+ const D = R()?.questions?.length || 0;
7616
+ a.current.currentQuestionIndex >= D - 1;
7617
+ const te = v.type === "code_test" ? `Great job! Your code passed all the tests! ${v.explanation || ""}` : `Excellent! That's correct! ${v.explanation || ""}`, q = z.current || { lipsyncLang: "en" };
7612
7618
  h.current.speakText(te, {
7613
7619
  lipsyncLang: q.lipsyncLang,
7614
7620
  onSpeechEnd: () => {
7615
7621
  c.current.onCustomAction({
7616
7622
  type: "answerFeedbackComplete",
7617
- moduleIndex: r.current.currentModuleIndex,
7618
- lessonIndex: r.current.currentLessonIndex,
7619
- questionIndex: r.current.currentQuestionIndex,
7623
+ moduleIndex: a.current.currentModuleIndex,
7624
+ lessonIndex: a.current.currentLessonIndex,
7625
+ questionIndex: a.current.currentQuestionIndex,
7620
7626
  isCorrect: !0,
7621
- hasNextQuestion: r.current.currentQuestionIndex < D - 1,
7622
- score: r.current.score,
7623
- totalQuestions: r.current.totalQuestions
7627
+ hasNextQuestion: a.current.currentQuestionIndex < D - 1,
7628
+ score: a.current.score,
7629
+ totalQuestions: a.current.totalQuestions
7624
7630
  });
7625
7631
  }
7626
7632
  });
@@ -7632,44 +7638,44 @@ const gt = ze(({
7632
7638
  h.current.setBodyMovement("idle");
7633
7639
  }
7634
7640
  h.current.setBodyMovement("gesturing");
7635
- const D = v()?.questions?.length || 0, te = r.current.currentQuestionIndex >= D - 1, q = R.type === "code_test" ? `Your code didn't pass all the tests. ${R.explanation || "Try again!"}` : `Not quite right, but don't worry! ${R.explanation || ""}${te ? "" : " Let's move on to the next question."}`, j = z.current || { lipsyncLang: "en" };
7641
+ const D = R()?.questions?.length || 0, te = a.current.currentQuestionIndex >= D - 1, q = v.type === "code_test" ? `Your code didn't pass all the tests. ${v.explanation || "Try again!"}` : `Not quite right, but don't worry! ${v.explanation || ""}${te ? "" : " Let's move on to the next question."}`, j = z.current || { lipsyncLang: "en" };
7636
7642
  h.current.speakText(q, {
7637
7643
  lipsyncLang: j.lipsyncLang,
7638
7644
  onSpeechEnd: () => {
7639
7645
  c.current.onCustomAction({
7640
7646
  type: "answerFeedbackComplete",
7641
- moduleIndex: r.current.currentModuleIndex,
7642
- lessonIndex: r.current.currentLessonIndex,
7643
- questionIndex: r.current.currentQuestionIndex,
7647
+ moduleIndex: a.current.currentModuleIndex,
7648
+ lessonIndex: a.current.currentLessonIndex,
7649
+ questionIndex: a.current.currentQuestionIndex,
7644
7650
  isCorrect: !1,
7645
- hasNextQuestion: r.current.currentQuestionIndex < D - 1,
7646
- score: r.current.score,
7647
- totalQuestions: r.current.totalQuestions
7651
+ hasNextQuestion: a.current.currentQuestionIndex < D - 1,
7652
+ score: a.current.score,
7653
+ totalQuestions: a.current.totalQuestions
7648
7654
  });
7649
7655
  }
7650
7656
  });
7651
7657
  }
7652
7658
  else {
7653
- const D = v()?.questions?.length || 0;
7659
+ const D = R()?.questions?.length || 0;
7654
7660
  c.current.onCustomAction({
7655
7661
  type: "answerFeedbackComplete",
7656
- moduleIndex: r.current.currentModuleIndex,
7657
- lessonIndex: r.current.currentLessonIndex,
7658
- questionIndex: r.current.currentQuestionIndex,
7662
+ moduleIndex: a.current.currentModuleIndex,
7663
+ lessonIndex: a.current.currentLessonIndex,
7664
+ questionIndex: a.current.currentQuestionIndex,
7659
7665
  isCorrect: w,
7660
- hasNextQuestion: r.current.currentQuestionIndex < D - 1,
7661
- score: r.current.score,
7662
- totalQuestions: r.current.totalQuestions,
7666
+ hasNextQuestion: a.current.currentQuestionIndex < D - 1,
7667
+ score: a.current.score,
7668
+ totalQuestions: a.current.totalQuestions,
7663
7669
  avatarNotReady: !0
7664
7670
  });
7665
7671
  }
7666
- }, [e.correct, e.incorrect, T, v, F]), se = M((b) => {
7667
- const R = T();
7672
+ }, [e.correct, e.incorrect, T, R, F]), se = M((b) => {
7673
+ const v = T();
7668
7674
  if (!b || typeof b != "object") {
7669
7675
  console.error("Invalid code test result format. Expected object with {passed: boolean, ...}");
7670
7676
  return;
7671
7677
  }
7672
- if (R?.type !== "code_test") {
7678
+ if (v?.type !== "code_test") {
7673
7679
  console.warn("Current question is not a code test. Use handleAnswerSelect for other question types.");
7674
7680
  return;
7675
7681
  }
@@ -7685,26 +7691,26 @@ const gt = ze(({
7685
7691
  };
7686
7692
  c.current.onCustomAction({
7687
7693
  type: "codeTestSubmitted",
7688
- moduleIndex: r.current.currentModuleIndex,
7689
- lessonIndex: r.current.currentLessonIndex,
7690
- questionIndex: r.current.currentQuestionIndex,
7694
+ moduleIndex: a.current.currentModuleIndex,
7695
+ lessonIndex: a.current.currentLessonIndex,
7696
+ questionIndex: a.current.currentQuestionIndex,
7691
7697
  testResult: w,
7692
- question: R
7698
+ question: v
7693
7699
  }), p.current && p.current(w);
7694
7700
  }, [T, F]), de = M(() => {
7695
- if (r.current.currentQuestionIndex > 0) {
7696
- r.current.currentQuestionIndex -= 1;
7701
+ if (a.current.currentQuestionIndex > 0) {
7702
+ a.current.currentQuestionIndex -= 1;
7697
7703
  const b = T();
7698
7704
  b && c.current.onCustomAction({
7699
7705
  type: "questionStart",
7700
- moduleIndex: r.current.currentModuleIndex,
7701
- lessonIndex: r.current.currentLessonIndex,
7702
- questionIndex: r.current.currentQuestionIndex,
7703
- totalQuestions: r.current.totalQuestions,
7706
+ moduleIndex: a.current.currentModuleIndex,
7707
+ lessonIndex: a.current.currentLessonIndex,
7708
+ questionIndex: a.current.currentQuestionIndex,
7709
+ totalQuestions: a.current.totalQuestions,
7704
7710
  question: b,
7705
- score: r.current.score
7711
+ score: a.current.score
7706
7712
  });
7707
- const R = () => {
7713
+ const v = () => {
7708
7714
  if (!h.current || !b) return;
7709
7715
  h.current.setMood("happy"), h.current.setBodyMovement("idle");
7710
7716
  const w = z.current || { lipsyncLang: "en" };
@@ -7715,10 +7721,10 @@ const gt = ze(({
7715
7721
  });
7716
7722
  };
7717
7723
  if (h.current && h.current.isReady && b)
7718
- R();
7724
+ v();
7719
7725
  else if (b) {
7720
7726
  const w = setInterval(() => {
7721
- h.current && h.current.isReady && (clearInterval(w), R());
7727
+ h.current && h.current.isReady && (clearInterval(w), v());
7722
7728
  }, 100);
7723
7729
  setTimeout(() => {
7724
7730
  clearInterval(w);
@@ -7727,40 +7733,40 @@ const gt = ze(({
7727
7733
  }
7728
7734
  }, [T]), me = M(() => {
7729
7735
  const b = H.current || { modules: [] };
7730
- if (b.modules[r.current.currentModuleIndex], r.current.currentLessonIndex > 0)
7731
- r.current.currentLessonIndex -= 1, r.current.currentQuestionIndex = 0, r.current.lessonCompleted = !1, r.current.isQuestionMode = !1, r.current.isTeaching = !1, r.current.score = 0, r.current.totalQuestions = 0, c.current.onCustomAction({
7736
+ if (b.modules[a.current.currentModuleIndex], a.current.currentLessonIndex > 0)
7737
+ a.current.currentLessonIndex -= 1, a.current.currentQuestionIndex = 0, a.current.lessonCompleted = !1, a.current.isQuestionMode = !1, a.current.isTeaching = !1, a.current.score = 0, a.current.totalQuestions = 0, c.current.onCustomAction({
7732
7738
  type: "lessonStart",
7733
- moduleIndex: r.current.currentModuleIndex,
7734
- lessonIndex: r.current.currentLessonIndex
7739
+ moduleIndex: a.current.currentModuleIndex,
7740
+ lessonIndex: a.current.currentLessonIndex
7735
7741
  }), c.current.onLessonStart({
7736
- moduleIndex: r.current.currentModuleIndex,
7737
- lessonIndex: r.current.currentLessonIndex,
7738
- lesson: v()
7742
+ moduleIndex: a.current.currentModuleIndex,
7743
+ lessonIndex: a.current.currentLessonIndex,
7744
+ lesson: R()
7739
7745
  }), h.current && (h.current.setMood("happy"), h.current.setBodyMovement("idle"));
7740
- else if (r.current.currentModuleIndex > 0) {
7741
- const C = b.modules[r.current.currentModuleIndex - 1];
7742
- r.current.currentModuleIndex -= 1, r.current.currentLessonIndex = (C?.lessons?.length || 1) - 1, r.current.currentQuestionIndex = 0, r.current.lessonCompleted = !1, r.current.isQuestionMode = !1, r.current.isTeaching = !1, r.current.score = 0, r.current.totalQuestions = 0, c.current.onCustomAction({
7746
+ else if (a.current.currentModuleIndex > 0) {
7747
+ const C = b.modules[a.current.currentModuleIndex - 1];
7748
+ a.current.currentModuleIndex -= 1, a.current.currentLessonIndex = (C?.lessons?.length || 1) - 1, a.current.currentQuestionIndex = 0, a.current.lessonCompleted = !1, a.current.isQuestionMode = !1, a.current.isTeaching = !1, a.current.score = 0, a.current.totalQuestions = 0, c.current.onCustomAction({
7743
7749
  type: "lessonStart",
7744
- moduleIndex: r.current.currentModuleIndex,
7745
- lessonIndex: r.current.currentLessonIndex
7750
+ moduleIndex: a.current.currentModuleIndex,
7751
+ lessonIndex: a.current.currentLessonIndex
7746
7752
  }), c.current.onLessonStart({
7747
- moduleIndex: r.current.currentModuleIndex,
7748
- lessonIndex: r.current.currentLessonIndex,
7749
- lesson: v()
7753
+ moduleIndex: a.current.currentModuleIndex,
7754
+ lessonIndex: a.current.currentLessonIndex,
7755
+ lesson: R()
7750
7756
  }), h.current && (h.current.setMood("happy"), h.current.setBodyMovement("idle"));
7751
7757
  }
7752
- }, [v]), ie = M(() => {
7753
- r.current.currentModuleIndex = 0, r.current.currentLessonIndex = 0, r.current.currentQuestionIndex = 0, r.current.isTeaching = !1, r.current.isQuestionMode = !1, r.current.lessonCompleted = !1, r.current.curriculumCompleted = !1, r.current.score = 0, r.current.totalQuestions = 0;
7758
+ }, [R]), ie = M(() => {
7759
+ a.current.currentModuleIndex = 0, a.current.currentLessonIndex = 0, a.current.currentQuestionIndex = 0, a.current.isTeaching = !1, a.current.isQuestionMode = !1, a.current.lessonCompleted = !1, a.current.curriculumCompleted = !1, a.current.score = 0, a.current.totalQuestions = 0;
7754
7760
  }, []), fe = M((b) => {
7755
7761
  console.log("Avatar is ready!", b);
7756
- const R = v(), w = R?.avatar_script || R?.body;
7762
+ const v = R(), w = v?.avatar_script || v?.body;
7757
7763
  u && w && setTimeout(() => {
7758
7764
  d.current && d.current();
7759
7765
  }, 10);
7760
- }, [u, v]);
7766
+ }, [u, R]);
7761
7767
  Xe(() => {
7762
7768
  d.current = Z, g.current = Y, y.current = J, x.current = W, I.current = ye, B.current = S, p.current = $;
7763
- }), Ce(a, () => ({
7769
+ }), Ce(r, () => ({
7764
7770
  // Curriculum control methods
7765
7771
  startTeaching: Z,
7766
7772
  startQuestions: S,
@@ -7773,26 +7779,26 @@ const gt = ze(({
7773
7779
  completeLesson: J,
7774
7780
  completeCurriculum: ye,
7775
7781
  resetCurriculum: ie,
7776
- getState: () => ({ ...r.current }),
7782
+ getState: () => ({ ...a.current }),
7777
7783
  getCurrentQuestion: () => T(),
7778
- getCurrentLesson: () => v(),
7784
+ getCurrentLesson: () => R(),
7779
7785
  // Direct access to avatar ref (always returns current value)
7780
7786
  getAvatarRef: () => h.current,
7781
7787
  // Convenience methods that delegate to avatar (always check current ref)
7782
- speakText: async (b, R = {}) => {
7788
+ speakText: async (b, v = {}) => {
7783
7789
  await h.current?.resumeAudioContext?.();
7784
7790
  const w = z.current || { lipsyncLang: "en" };
7785
- h.current?.speakText(b, { ...R, lipsyncLang: R.lipsyncLang || w.lipsyncLang });
7791
+ h.current?.speakText(b, { ...v, lipsyncLang: v.lipsyncLang || w.lipsyncLang });
7786
7792
  },
7787
7793
  resumeAudioContext: async () => {
7788
7794
  if (h.current?.resumeAudioContext)
7789
7795
  return await h.current.resumeAudioContext();
7790
7796
  const b = h.current?.talkingHead;
7791
7797
  if (b?.audioCtx) {
7792
- const R = b.audioCtx;
7793
- if (R.state === "suspended" || R.state === "interrupted")
7798
+ const v = b.audioCtx;
7799
+ if (v.state === "suspended" || v.state === "interrupted")
7794
7800
  try {
7795
- await R.resume(), console.log("Audio context resumed via talkingHead");
7801
+ await v.resume(), console.log("Audio context resumed via talkingHead");
7796
7802
  } catch (w) {
7797
7803
  console.warn("Failed to resume audio context:", w);
7798
7804
  }
@@ -7804,7 +7810,7 @@ const gt = ze(({
7804
7810
  resumeSpeaking: async () => await h.current?.resumeSpeaking(),
7805
7811
  isPaused: () => h.current && typeof h.current.isPaused < "u" ? h.current.isPaused : !1,
7806
7812
  setMood: (b) => h.current?.setMood(b),
7807
- playAnimation: (b, R) => h.current?.playAnimation(b, R),
7813
+ playAnimation: (b, v) => h.current?.playAnimation(b, v),
7808
7814
  setBodyMovement: (b) => h.current?.setBodyMovement(b),
7809
7815
  setMovementIntensity: (b) => h.current?.setMovementIntensity(b),
7810
7816
  playRandomDance: () => h.current?.playRandomDance(),
@@ -7815,18 +7821,18 @@ const gt = ze(({
7815
7821
  lockAvatarPosition: () => h.current?.lockAvatarPosition(),
7816
7822
  unlockAvatarPosition: () => h.current?.unlockAvatarPosition(),
7817
7823
  // Custom action trigger
7818
- triggerCustomAction: (b, R) => {
7824
+ triggerCustomAction: (b, v) => {
7819
7825
  c.current.onCustomAction({
7820
7826
  type: b,
7821
- ...R,
7822
- state: { ...r.current }
7827
+ ...v,
7828
+ state: { ...a.current }
7823
7829
  });
7824
7830
  },
7825
7831
  // Responsive resize handler
7826
7832
  handleResize: () => h.current?.handleResize(),
7827
7833
  // Avatar readiness check (always returns current value)
7828
7834
  isAvatarReady: () => h.current?.isReady || !1
7829
- }), [Z, S, $, se, W, Y, J, ye, ie, T, v]);
7835
+ }), [Z, S, $, se, W, Y, J, ye, ie, T, R]);
7830
7836
  const X = z.current || {
7831
7837
  avatarUrl: "/avatars/brunette.glb",
7832
7838
  avatarBody: "F",