@sage-rsc/talking-head-react 1.8.0 → 1.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +5 -5
- package/dist/index.js +1000 -991
- package/package.json +1 -1
- package/src/components/SimpleTalkingAvatar.jsx +31 -12
- package/src/lib/talkinghead.mjs +45 -2
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsxs as Pe, jsx as ae } from "react/jsx-runtime";
|
|
2
|
-
import { forwardRef as Ke, useRef as
|
|
2
|
+
import { forwardRef as Ke, useRef as V, useState as pe, useEffect as Se, useCallback as U, useImperativeHandle as Je, useLayoutEffect as pt } from "react";
|
|
3
3
|
import * as b from "three";
|
|
4
4
|
import { OrbitControls as gt } from "three/addons/controls/OrbitControls.js";
|
|
5
5
|
import { GLTFLoader as yt } from "three/addons/loaders/GLTFLoader.js";
|
|
@@ -14,8 +14,8 @@ new b.Ray();
|
|
|
14
14
|
new b.Euler();
|
|
15
15
|
const be = new b.Quaternion(), st = new b.Quaternion(), De = new b.Matrix4(), Ne = new b.Matrix4();
|
|
16
16
|
new b.Vector3();
|
|
17
|
-
const qe = new b.Vector3(0, 0, 1), Rt = new b.Vector3(1, 0, 0),
|
|
18
|
-
class
|
|
17
|
+
const qe = new b.Vector3(0, 0, 1), Rt = new b.Vector3(1, 0, 0), At = new b.Vector3(0, 1, 0), vt = new b.Vector3(0, 0, 1);
|
|
18
|
+
class It {
|
|
19
19
|
constructor(n = null) {
|
|
20
20
|
this.opt = Object.assign({
|
|
21
21
|
warmupMs: 2e3,
|
|
@@ -192,7 +192,7 @@ class At {
|
|
|
192
192
|
const a = this.armature.getObjectByName(s.bone);
|
|
193
193
|
if (!a) throw new Error("Bone '" + s.bone + "' not found in #" + i + " exclude.");
|
|
194
194
|
if (Number.isNaN(s.radius) && s.radius >= 0) throw new Error("Radius must be a non-negative number in #" + i + " exclude.");
|
|
195
|
-
const
|
|
195
|
+
const u = {
|
|
196
196
|
bone: a,
|
|
197
197
|
// Bone object
|
|
198
198
|
radius: s.radius,
|
|
@@ -203,9 +203,9 @@ class At {
|
|
|
203
203
|
};
|
|
204
204
|
if (s.deltaLocal) {
|
|
205
205
|
if (!Array.isArray(s.deltaLocal) || s.deltaLocal.length !== 3 || s.deltaLocal.some((l) => Number.isNaN(l))) throw new Error("deltaLocal must be an array of three numbers in #" + i + " exclude.");
|
|
206
|
-
|
|
206
|
+
u.deltaLocal = [...s.deltaLocal];
|
|
207
207
|
}
|
|
208
|
-
o.excludes.push(
|
|
208
|
+
o.excludes.push(u);
|
|
209
209
|
});
|
|
210
210
|
}
|
|
211
211
|
this.showHelpers();
|
|
@@ -282,8 +282,8 @@ class At {
|
|
|
282
282
|
p = this.dict[i.boneParent.name], p && (p.children || (p.children = []), p.children.push(i));
|
|
283
283
|
}), this.objectsUpdate = [];
|
|
284
284
|
const t = /* @__PURE__ */ new WeakSet(), o = (i) => i.parent?.isBone ? [i, ...o(i.parent)] : [i], s = (i) => {
|
|
285
|
-
o(i).forEach((
|
|
286
|
-
t.has(
|
|
285
|
+
o(i).forEach((u) => {
|
|
286
|
+
t.has(u) || (this.objectsUpdate.push(u), t.add(u));
|
|
287
287
|
});
|
|
288
288
|
};
|
|
289
289
|
this.data.forEach((i) => {
|
|
@@ -308,12 +308,12 @@ class At {
|
|
|
308
308
|
o(n?.isScene, "First parameter must be Scene."), this.scene = n, o(e?.isObject3D, "Second parameter must be the armature Object3D."), this.armature = e, o(Array.isArray(t), "Third parameter must be an array of bone configs."), this.config = t, this.config.forEach((s, i) => {
|
|
309
309
|
const a = "Config item #" + i + ": ";
|
|
310
310
|
o(s.bone, a + "Bone not specified.");
|
|
311
|
-
const
|
|
312
|
-
o(typeof
|
|
313
|
-
const l = this.armature.getObjectByName(
|
|
314
|
-
o(l, a + "Bone '" +
|
|
315
|
-
const
|
|
316
|
-
name:
|
|
311
|
+
const u = s.bone;
|
|
312
|
+
o(typeof u == "string" && u.length > 0, a + "Bone name must be a non-empty string.");
|
|
313
|
+
const l = this.armature.getObjectByName(u);
|
|
314
|
+
o(l, a + "Bone '" + u + "' not found."), o(l.parent?.isBone, a + "Bone must have a parent bone."), o(this.data.every((r) => r.bone !== l), a + "Bone '" + u + "' already exists."), l.updateMatrixWorld(!0);
|
|
315
|
+
const c = {
|
|
316
|
+
name: u,
|
|
317
317
|
// Bone name
|
|
318
318
|
bone: l,
|
|
319
319
|
// Bone object
|
|
@@ -338,9 +338,9 @@ class At {
|
|
|
338
338
|
ea: [0, 0, 0, 0]
|
|
339
339
|
// External acceleration [m/s^2]
|
|
340
340
|
};
|
|
341
|
-
|
|
341
|
+
c.boneParent.matrixWorld.decompose(N, be, xe), N.copy(qe).applyQuaternion(be).setY(0).normalize(), be.premultiply(st.setFromUnitVectors(qe, N).invert()).normalize(), c.qWorldInverseYaw = be.clone().normalize(), this.data.push(c), this.dict[u] = c;
|
|
342
342
|
try {
|
|
343
|
-
this.setValue(
|
|
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
344
|
} catch (r) {
|
|
345
345
|
o(!1, a + r);
|
|
346
346
|
}
|
|
@@ -369,7 +369,7 @@ class At {
|
|
|
369
369
|
i.vBasis.y + z[1],
|
|
370
370
|
i.vBasis.z - z[2]
|
|
371
371
|
);
|
|
372
|
-
else if (i.boneParent.quaternion.copy(i.qBasis), i.pivot && this.opt.isPivots && (i.boneParent.updateWorldMatrix(!1, !1), i.boneParent.matrixWorld.decompose(N, be, xe), N.copy(qe).applyQuaternion(be).setY(0).normalize(), be.premultiply(st.setFromUnitVectors(qe, N).invert()).normalize(), i.boneParent.quaternion.multiply(be.invert()), i.boneParent.quaternion.multiply(i.qWorldInverseYaw)), i.isZ && (p = Math.atan(z[0] / i.l), be.setFromAxisAngle(
|
|
372
|
+
else if (i.boneParent.quaternion.copy(i.qBasis), i.pivot && this.opt.isPivots && (i.boneParent.updateWorldMatrix(!1, !1), i.boneParent.matrixWorld.decompose(N, be, xe), N.copy(qe).applyQuaternion(be).setY(0).normalize(), be.premultiply(st.setFromUnitVectors(qe, N).invert()).normalize(), i.boneParent.quaternion.multiply(be.invert()), i.boneParent.quaternion.multiply(i.qWorldInverseYaw)), i.isZ && (p = Math.atan(z[0] / i.l), be.setFromAxisAngle(vt, -p), i.boneParent.quaternion.multiply(be)), i.isY && (p = i.l / 3, p = p * Math.tanh(z[1] / p), i.bone.position.setLength(i.l + p)), i.isX && (p = Math.atan(z[2] / i.l), be.setFromAxisAngle(Rt, -p), i.boneParent.quaternion.multiply(be)), i.isT && (p = 1.5 * Math.tanh(z[3] * 1.5), be.setFromAxisAngle(At, -p), i.boneParent.quaternion.multiply(be)), i.boneParent.updateWorldMatrix(!1, !0), i.excludes && this.opt.isExcludes)
|
|
373
373
|
for (t = 0, s = i.excludes.length; t < s; t++)
|
|
374
374
|
p = i.excludes[t], xe.set(0, 0, 0), p.deltaLocal && (xe.x += p.deltaLocal[0], xe.y += p.deltaLocal[1], xe.z += p.deltaLocal[2]), xe.applyMatrix4(p.bone.matrixWorld), Ne.copy(i.boneParent.matrixWorld).invert(), xe.applyMatrix4(Ne), N.copy(i.bone.position), !(N.distanceToSquared(xe) >= p.radiusSq) && (Ce = N.length(), Le = xe.length(), !(Le > p.radius + Ce) && (Le < Math.abs(p.radius - Ce) || (Le = (Le * Le + Ce * Ce - p.radiusSq) / (2 * Le), xe.normalize(), Ye.copy(xe).multiplyScalar(Le), Le = Math.sqrt(Ce * Ce - Le * Le), N.subVectors(N, Ye).projectOnPlane(xe).normalize().multiplyScalar(Le), Qe.subVectors(i.vBasis, Ye).projectOnPlane(xe).normalize(), Ce = Qe.dot(N), Ce < 0 && (Ce = Math.sqrt(Le * Le - Ce * Ce), Qe.multiplyScalar(Ce), N.add(Qe)), N.add(Ye).normalize(), xe.copy(i.bone.position).normalize(), be.setFromUnitVectors(xe, N), i.boneParent.quaternion.premultiply(be), i.boneParent.updateWorldMatrix(!1, !0))));
|
|
375
375
|
}
|
|
@@ -408,9 +408,9 @@ class At {
|
|
|
408
408
|
);
|
|
409
409
|
}), p = this.helpers.points, p.bones.length) {
|
|
410
410
|
this.helpers.isActive = !0;
|
|
411
|
-
const e = new b.BufferGeometry(), t = p.bones.map((
|
|
411
|
+
const e = new b.BufferGeometry(), t = p.bones.map((u) => [0, 0, 0]).flat();
|
|
412
412
|
e.setAttribute("position", new b.Float32BufferAttribute(t, 3));
|
|
413
|
-
const o = new b.Color(this.opt.helperBoneColor1), s = new b.Color(this.opt.helperBoneColor2), i = p.pivots.map((
|
|
413
|
+
const o = new b.Color(this.opt.helperBoneColor1), s = new b.Color(this.opt.helperBoneColor2), i = p.pivots.map((u) => u && this.opt.isPivots ? [s.r, s.g, s.b] : [o.r, o.g, o.b]).flat();
|
|
414
414
|
e.setAttribute("color", new b.Float32BufferAttribute(i, 3));
|
|
415
415
|
const a = new b.PointsMaterial({
|
|
416
416
|
depthTest: !1,
|
|
@@ -423,9 +423,9 @@ class At {
|
|
|
423
423
|
p.object = new b.Points(e, a), p.object.renderOrder = 998, p.object.matrix = this.armature.matrixWorld, p.object.matrixAutoUpdate = !1, this.scene.add(p.object);
|
|
424
424
|
}
|
|
425
425
|
if (p = this.helpers.lines, p.bones.length) {
|
|
426
|
-
const e = new b.BufferGeometry(), t = p.bones.map((
|
|
426
|
+
const e = new b.BufferGeometry(), t = p.bones.map((u) => [0, 0, 0, 0, 0, 0]).flat();
|
|
427
427
|
e.setAttribute("position", new b.Float32BufferAttribute(t, 3));
|
|
428
|
-
const o = new b.Color(this.opt.helperLinkColor1), s = new b.Color(this.opt.helperLinkColor2), i = p.bones.map((
|
|
428
|
+
const o = new b.Color(this.opt.helperLinkColor1), s = new b.Color(this.opt.helperLinkColor2), i = p.bones.map((u) => [o.r, o.g, o.b, s.r, s.g, s.b]).flat();
|
|
429
429
|
e.setAttribute("color", new b.Float32BufferAttribute(i, 3));
|
|
430
430
|
const a = new b.LineBasicMaterial({
|
|
431
431
|
vertexColors: !0,
|
|
@@ -519,13 +519,13 @@ class Lt {
|
|
|
519
519
|
phonemeBoundaries: []
|
|
520
520
|
}, o = 1024, s = 512, i = Math.floor((n.length - o) / s) + 1;
|
|
521
521
|
for (let a = 0; a < i; a++) {
|
|
522
|
-
const
|
|
522
|
+
const u = a * s, l = Math.min(u + o, n.length), c = n.slice(u, l), r = this.calculateEnergy(c);
|
|
523
523
|
t.energy.push(r);
|
|
524
|
-
const h = this.calculateSpectralCentroid(
|
|
524
|
+
const h = this.calculateSpectralCentroid(c);
|
|
525
525
|
t.spectralCentroid.push(h);
|
|
526
|
-
const d = this.calculateZeroCrossingRate(
|
|
526
|
+
const d = this.calculateZeroCrossingRate(c);
|
|
527
527
|
t.zeroCrossingRate.push(d);
|
|
528
|
-
const g = this.calculateMFCC(
|
|
528
|
+
const g = this.calculateMFCC(c);
|
|
529
529
|
t.mfcc.push(g);
|
|
530
530
|
}
|
|
531
531
|
return t.onsets = this.detectOnsets(t.energy), t.phonemeBoundaries = this.detectPhonemeBoundaries(t), t;
|
|
@@ -597,19 +597,19 @@ class Lt {
|
|
|
597
597
|
for (; s & i; )
|
|
598
598
|
s ^= i, i >>= 1;
|
|
599
599
|
if (s ^= i, o < s) {
|
|
600
|
-
const a = t[o * 2],
|
|
601
|
-
t[o * 2] = t[s * 2], t[o * 2 + 1] = t[s * 2 + 1], t[s * 2] = a, t[s * 2 + 1] =
|
|
600
|
+
const a = t[o * 2], u = t[o * 2 + 1];
|
|
601
|
+
t[o * 2] = t[s * 2], t[o * 2 + 1] = t[s * 2 + 1], t[s * 2] = a, t[s * 2 + 1] = u;
|
|
602
602
|
}
|
|
603
603
|
}
|
|
604
604
|
for (let o = 2; o <= e; o <<= 1) {
|
|
605
605
|
const s = -2 * Math.PI / o, i = Math.cos(s), a = Math.sin(s);
|
|
606
|
-
for (let
|
|
607
|
-
let l = 1,
|
|
606
|
+
for (let u = 0; u < e; u += o) {
|
|
607
|
+
let l = 1, c = 0;
|
|
608
608
|
for (let r = 0; r < o / 2; r++) {
|
|
609
|
-
const h = t[(
|
|
610
|
-
t[(
|
|
611
|
-
const x = l * i -
|
|
612
|
-
l = x,
|
|
609
|
+
const h = t[(u + r) * 2], d = t[(u + r) * 2 + 1], g = t[(u + r + o / 2) * 2] * l - t[(u + r + o / 2) * 2 + 1] * c, R = t[(u + r + o / 2) * 2] * c + t[(u + r + o / 2) * 2 + 1] * l;
|
|
610
|
+
t[(u + r) * 2] = h + g, t[(u + r) * 2 + 1] = d + R, t[(u + r + o / 2) * 2] = h - g, t[(u + r + o / 2) * 2 + 1] = d - R;
|
|
611
|
+
const x = l * i - c * a, k = l * a + c * i;
|
|
612
|
+
l = x, c = k;
|
|
613
613
|
}
|
|
614
614
|
}
|
|
615
615
|
}
|
|
@@ -624,8 +624,8 @@ class Lt {
|
|
|
624
624
|
const e = [];
|
|
625
625
|
let s = -0.1;
|
|
626
626
|
for (let i = 1; i < n.length; i++) {
|
|
627
|
-
const a = n[i] - n[i - 1],
|
|
628
|
-
a > 0.1 &&
|
|
627
|
+
const a = n[i] - n[i - 1], u = i * 0.023;
|
|
628
|
+
a > 0.1 && u - s > 0.1 && (e.push(u), s = u);
|
|
629
629
|
}
|
|
630
630
|
return e;
|
|
631
631
|
}
|
|
@@ -637,8 +637,8 @@ class Lt {
|
|
|
637
637
|
detectPhonemeBoundaries(n) {
|
|
638
638
|
const e = [], { energy: t, spectralCentroid: o, zeroCrossingRate: s } = n;
|
|
639
639
|
for (let i = 1; i < t.length; i++) {
|
|
640
|
-
const a = i * 0.023,
|
|
641
|
-
|
|
640
|
+
const a = i * 0.023, u = Math.abs(t[i] - t[i - 1]), l = Math.abs(o[i] - o[i - 1]), c = Math.abs(s[i] - s[i - 1]);
|
|
641
|
+
u + l * 0.1 + c * 0.5 > 0.2 && e.push(a);
|
|
642
642
|
}
|
|
643
643
|
return e;
|
|
644
644
|
}
|
|
@@ -654,14 +654,14 @@ class Lt {
|
|
|
654
654
|
n.phonemeBoundaries, n.onsets;
|
|
655
655
|
const s = [];
|
|
656
656
|
let i = 0;
|
|
657
|
-
for (let
|
|
658
|
-
const l = o[
|
|
657
|
+
for (let u = 0; u < o.length; u++) {
|
|
658
|
+
const l = o[u], c = this.estimateWordDuration(l, t / o.length);
|
|
659
659
|
s.push({
|
|
660
660
|
word: l,
|
|
661
661
|
startTime: i,
|
|
662
|
-
endTime: i +
|
|
663
|
-
duration:
|
|
664
|
-
}), i +=
|
|
662
|
+
endTime: i + c,
|
|
663
|
+
duration: c
|
|
664
|
+
}), i += c;
|
|
665
665
|
}
|
|
666
666
|
const a = this.generateVisemeTimings(n, e, t);
|
|
667
667
|
return {
|
|
@@ -701,27 +701,27 @@ class Lt {
|
|
|
701
701
|
const o = [], s = n.phonemeBoundaries;
|
|
702
702
|
n.onsets;
|
|
703
703
|
const i = this.textToVisemes(e);
|
|
704
|
-
let a = 0,
|
|
704
|
+
let a = 0, u = 0;
|
|
705
705
|
for (let l = 0; l < s.length && a < i.length; l++) {
|
|
706
|
-
const
|
|
706
|
+
const c = s[l], r = i[a], h = n.energy[Math.floor(c / 0.023)] || 0, d = this.calculateVisemeDuration(r, h);
|
|
707
707
|
o.push({
|
|
708
708
|
viseme: r,
|
|
709
|
-
startTime:
|
|
710
|
-
endTime:
|
|
709
|
+
startTime: u,
|
|
710
|
+
endTime: u + d,
|
|
711
711
|
duration: d,
|
|
712
712
|
intensity: Math.min(1, h * 2)
|
|
713
713
|
// Map energy to viseme intensity
|
|
714
|
-
}),
|
|
714
|
+
}), u += d, a++;
|
|
715
715
|
}
|
|
716
716
|
for (; a < i.length; ) {
|
|
717
|
-
const l = i[a],
|
|
717
|
+
const l = i[a], c = this.calculateVisemeDuration(l, 0.5);
|
|
718
718
|
o.push({
|
|
719
719
|
viseme: l,
|
|
720
|
-
startTime:
|
|
721
|
-
endTime:
|
|
722
|
-
duration:
|
|
720
|
+
startTime: u,
|
|
721
|
+
endTime: u + c,
|
|
722
|
+
duration: c,
|
|
723
723
|
intensity: 0.6
|
|
724
|
-
}),
|
|
724
|
+
}), u += c, a++;
|
|
725
725
|
}
|
|
726
726
|
return o;
|
|
727
727
|
}
|
|
@@ -775,16 +775,16 @@ class Lt {
|
|
|
775
775
|
let i = 0;
|
|
776
776
|
for (; i < s.length; ) {
|
|
777
777
|
let a = !1;
|
|
778
|
-
for (let
|
|
779
|
-
const l = s.substr(i,
|
|
778
|
+
for (let u = 3; u >= 2; u--) {
|
|
779
|
+
const l = s.substr(i, u);
|
|
780
780
|
if (e[l]) {
|
|
781
|
-
t.push(e[l]), i +=
|
|
781
|
+
t.push(e[l]), i += u, a = !0;
|
|
782
782
|
break;
|
|
783
783
|
}
|
|
784
784
|
}
|
|
785
785
|
if (!a) {
|
|
786
|
-
const
|
|
787
|
-
e[
|
|
786
|
+
const u = s[i];
|
|
787
|
+
e[u] && t.push(e[u]), i++;
|
|
788
788
|
}
|
|
789
789
|
}
|
|
790
790
|
}
|
|
@@ -1206,11 +1206,11 @@ class St {
|
|
|
1206
1206
|
};
|
|
1207
1207
|
Object.keys(this.rules).forEach((e) => {
|
|
1208
1208
|
this.rules[e] = this.rules[e].map((t) => {
|
|
1209
|
-
const o = t.indexOf("["), s = t.indexOf("]"), i = t.indexOf("="), a = t.substring(0, o),
|
|
1209
|
+
const o = t.indexOf("["), s = t.indexOf("]"), i = t.indexOf("="), a = t.substring(0, o), u = t.substring(o + 1, s), l = t.substring(s + 1, i), c = t.substring(i + 1), r = { regex: "", move: 0, visemes: [] };
|
|
1210
1210
|
let h = "";
|
|
1211
1211
|
h += [...a].map((g) => n[g] || g).join("");
|
|
1212
|
-
const d = [...
|
|
1213
|
-
return d[0] = d[0].toLowerCase(), h += d.join(""), r.move = d.length, h += [...l].map((g) => n[g] || g).join(""), r.regex = new RegExp(h),
|
|
1212
|
+
const d = [...u];
|
|
1213
|
+
return d[0] = d[0].toLowerCase(), h += d.join(""), r.move = d.length, h += [...l].map((g) => n[g] || g).join(""), r.regex = new RegExp(h), c.length && c.split(" ").forEach((g) => {
|
|
1214
1214
|
r.visemes.push(g);
|
|
1215
1215
|
}), r;
|
|
1216
1216
|
});
|
|
@@ -1324,8 +1324,8 @@ class St {
|
|
|
1324
1324
|
*/
|
|
1325
1325
|
convertDecade(n) {
|
|
1326
1326
|
const e = parseInt(n), t = !isNaN(e) && n.length === 2, o = !isNaN(e) && n.length > 2 && e > 0 && e <= 3e3, s = o && e % 1e3 === 0 ? Math.floor(e / 1e3) : null, i = o && !s ? Math.floor(e / 100) : null, a = t || o ? Math.floor(e % 100 / 10) * 10 : null;
|
|
1327
|
-
let
|
|
1328
|
-
return s ?
|
|
1327
|
+
let u = [];
|
|
1328
|
+
return s ? u.push(this.convertNumberToWords(s).trim(), "thousands") : (i && u.push(this.convertNumberToWords(i).trim()), a ? u.push(this.decades[a] || this.convertNumberToWords(a).trim() + "s") : i ? u.push("hundreds") : u.push(n)), u.join(" ");
|
|
1329
1329
|
}
|
|
1330
1330
|
/**
|
|
1331
1331
|
* Convert ordinal number to text.
|
|
@@ -1376,9 +1376,9 @@ class St {
|
|
|
1376
1376
|
const s = o[e.i], i = this.rules[s];
|
|
1377
1377
|
if (i)
|
|
1378
1378
|
for (let a = 0; a < i.length; a++) {
|
|
1379
|
-
const
|
|
1380
|
-
if ((e.words.substring(0, e.i) + s.toLowerCase() + e.words.substring(e.i + 1)).match(
|
|
1381
|
-
|
|
1379
|
+
const u = i[a];
|
|
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
1382
|
if (e.visemes.length && e.visemes[e.visemes.length - 1] === r) {
|
|
1383
1383
|
const h = 0.7 * (this.visemeDurations[r] || 1);
|
|
1384
1384
|
e.durations[e.durations.length - 1] += h, t += h;
|
|
@@ -1386,7 +1386,7 @@ class St {
|
|
|
1386
1386
|
const h = this.visemeDurations[r] || 1;
|
|
1387
1387
|
e.visemes.push(r), e.times.push(t), e.durations.push(h), t += h;
|
|
1388
1388
|
}
|
|
1389
|
-
}), e.i +=
|
|
1389
|
+
}), e.i += u.move;
|
|
1390
1390
|
break;
|
|
1391
1391
|
}
|
|
1392
1392
|
}
|
|
@@ -1616,11 +1616,11 @@ class wt {
|
|
|
1616
1616
|
};
|
|
1617
1617
|
Object.keys(this.rules).forEach((e) => {
|
|
1618
1618
|
this.rules[e] = this.rules[e].map((t) => {
|
|
1619
|
-
const o = t.indexOf("["), s = t.indexOf("]"), i = t.indexOf("="), a = t.substring(0, o),
|
|
1619
|
+
const o = t.indexOf("["), s = t.indexOf("]"), i = t.indexOf("="), a = t.substring(0, o), u = t.substring(o + 1, s), l = t.substring(s + 1, i), c = t.substring(i + 1), r = { regex: "", move: 0, visemes: [] };
|
|
1620
1620
|
let h = "";
|
|
1621
1621
|
h += [...a].map((g) => n[g] || g).join("");
|
|
1622
|
-
const d = [...
|
|
1623
|
-
return d[0] = d[0].toLowerCase(), h += d.join(""), r.move = d.length, h += [...l].map((g) => n[g] || g).join(""), r.regex = new RegExp(h),
|
|
1622
|
+
const d = [...u];
|
|
1623
|
+
return d[0] = d[0].toLowerCase(), h += d.join(""), r.move = d.length, h += [...l].map((g) => n[g] || g).join(""), r.regex = new RegExp(h), c.length && c.split(" ").forEach((g) => {
|
|
1624
1624
|
r.visemes.push(g);
|
|
1625
1625
|
}), r;
|
|
1626
1626
|
});
|
|
@@ -1732,8 +1732,8 @@ class wt {
|
|
|
1732
1732
|
const s = o[e.i], i = this.rules[s];
|
|
1733
1733
|
if (i) {
|
|
1734
1734
|
let a = !1;
|
|
1735
|
-
for (let
|
|
1736
|
-
const l = i[
|
|
1735
|
+
for (let u = 0; u < i.length; u++) {
|
|
1736
|
+
const l = i[u];
|
|
1737
1737
|
if ((e.words.substring(0, e.i) + s.toLowerCase() + e.words.substring(e.i + 1)).match(l.regex)) {
|
|
1738
1738
|
l.visemes.forEach((h) => {
|
|
1739
1739
|
if (e.visemes.length && e.visemes[e.visemes.length - 1] === h) {
|
|
@@ -2131,11 +2131,11 @@ class zt {
|
|
|
2131
2131
|
};
|
|
2132
2132
|
Object.keys(this.rules).forEach((e) => {
|
|
2133
2133
|
this.rules[e] = this.rules[e].map((t) => {
|
|
2134
|
-
const o = t.indexOf("["), s = t.indexOf("]"), i = t.indexOf("="), a = t.substring(0, o),
|
|
2134
|
+
const o = t.indexOf("["), s = t.indexOf("]"), i = t.indexOf("="), a = t.substring(0, o), u = t.substring(o + 1, s), l = t.substring(s + 1, i), c = t.substring(i + 1), r = { regex: "", move: 0, visemes: [] };
|
|
2135
2135
|
let h = "";
|
|
2136
2136
|
h += [...a].map((g) => n[g] || g).join("");
|
|
2137
|
-
const d = [...
|
|
2138
|
-
return d[0] = d[0].toLowerCase(), h += d.join(""), r.move = d.length, h += [...l].map((g) => n[g] || g).join(""), r.regex = new RegExp(h, "i"),
|
|
2137
|
+
const d = [...u];
|
|
2138
|
+
return d[0] = d[0].toLowerCase(), h += d.join(""), r.move = d.length, h += [...l].map((g) => n[g] || g).join(""), r.regex = new RegExp(h, "i"), c.length && c.split(" ").forEach((g) => {
|
|
2139
2139
|
g && r.visemes.push(g);
|
|
2140
2140
|
}), r;
|
|
2141
2141
|
});
|
|
@@ -2267,8 +2267,8 @@ class zt {
|
|
|
2267
2267
|
const s = o[e.i], i = this.rules[s];
|
|
2268
2268
|
if (i) {
|
|
2269
2269
|
let a = !1;
|
|
2270
|
-
for (let
|
|
2271
|
-
const l = i[
|
|
2270
|
+
for (let u = 0; u < i.length; u++) {
|
|
2271
|
+
const l = i[u];
|
|
2272
2272
|
if ((e.words.substring(0, e.i) + s.toLowerCase() + e.words.substring(e.i + 1)).match(l.regex)) {
|
|
2273
2273
|
l.visemes.forEach((h) => {
|
|
2274
2274
|
if (e.visemes.length && e.visemes[e.visemes.length - 1] === h) {
|
|
@@ -2381,10 +2381,10 @@ class Tt {
|
|
|
2381
2381
|
const e = [];
|
|
2382
2382
|
let t = parseFloat(n);
|
|
2383
2383
|
if (t === void 0) return n;
|
|
2384
|
-
let o = (s, i, a,
|
|
2384
|
+
let o = (s, i, a, u, l) => {
|
|
2385
2385
|
if (s < i) return s;
|
|
2386
|
-
const
|
|
2387
|
-
return e.push(a + (
|
|
2386
|
+
const c = Math.floor(s / i);
|
|
2387
|
+
return e.push(a + (c === 1 ? u : this.numberToFinnishWords(c.toString()) + l)), s - c * i;
|
|
2388
2388
|
};
|
|
2389
2389
|
if (t < 0 && (e.push("miinus "), t = Math.abs(t)), t = o(t, 1e9, " ", "miljardi", " miljardia"), t = o(t, 1e6, " ", "miljoona", " miljoonaa"), t = o(t, 1e3, "", "tuhat", "tuhatta"), t = o(t, 100, " ", "sata", "sataa"), t > 20 && (t = o(t, 10, "", "", "kymmentä")), t >= 1) {
|
|
2390
2390
|
let s = Math.floor(t);
|
|
@@ -2440,7 +2440,7 @@ const Mt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
|
2440
2440
|
__proto__: null,
|
|
2441
2441
|
LipsyncFi: Tt
|
|
2442
2442
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
2443
|
-
class
|
|
2443
|
+
class Ft {
|
|
2444
2444
|
/**
|
|
2445
2445
|
* @constructor
|
|
2446
2446
|
*/
|
|
@@ -2559,10 +2559,10 @@ class Et {
|
|
|
2559
2559
|
const e = [];
|
|
2560
2560
|
let t = parseFloat(n);
|
|
2561
2561
|
if (t === void 0) return n;
|
|
2562
|
-
let o = (s, i, a,
|
|
2562
|
+
let o = (s, i, a, u, l) => {
|
|
2563
2563
|
if (s < i) return s;
|
|
2564
|
-
const
|
|
2565
|
-
return
|
|
2564
|
+
const c = Math.floor(s / i);
|
|
2565
|
+
return c === 1 ? e.push(this.numbers[1]) : e.push(this.numberToLithuanianWords(c.toString())), c % 10 === 1 ? e.push(a) : c % 10 === 0 || c % 100 > 10 && c % 100 < 20 ? e.push(l) : e.push(u), s - c * i;
|
|
2566
2566
|
};
|
|
2567
2567
|
t < 0 && (e.push("minus"), t = Math.abs(t)), t = o(t, 1e9, "milijardas", "milijardai", "milijardų"), t = o(t, 1e6, "milijonas", "milijonai", "milijonų"), t = o(t, 1e3, "tūkstantis", "tūkstančiai", "tūkstančių"), t = o(t, 100, "šimtas", "šimtai", "šimtų");
|
|
2568
2568
|
for (let s = this.tens.length - 1; s >= 1; s--)
|
|
@@ -2608,11 +2608,11 @@ class Et {
|
|
|
2608
2608
|
const i = o[s].toLowerCase(), a = this.visemes[i];
|
|
2609
2609
|
if (a)
|
|
2610
2610
|
if (e.visemes.length && e.visemes[e.visemes.length - 1] === a) {
|
|
2611
|
-
const
|
|
2612
|
-
e.durations[e.durations.length - 1] +=
|
|
2611
|
+
const u = 0.7 * (this.durations[i] || 1);
|
|
2612
|
+
e.durations[e.durations.length - 1] += u, t += u;
|
|
2613
2613
|
} else {
|
|
2614
|
-
const
|
|
2615
|
-
e.visemes.push(a), e.times.push(t), e.durations.push(
|
|
2614
|
+
const u = this.durations[i] || 1;
|
|
2615
|
+
e.visemes.push(a), e.times.push(t), e.durations.push(u), t += u;
|
|
2616
2616
|
}
|
|
2617
2617
|
else
|
|
2618
2618
|
t += this.pauses[o[s]] || 0;
|
|
@@ -2620,21 +2620,21 @@ class Et {
|
|
|
2620
2620
|
return e;
|
|
2621
2621
|
}
|
|
2622
2622
|
}
|
|
2623
|
-
const
|
|
2623
|
+
const Et = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
2624
2624
|
__proto__: null,
|
|
2625
|
-
LipsyncLt:
|
|
2625
|
+
LipsyncLt: Ft
|
|
2626
2626
|
}, Symbol.toStringTag, { value: "Module" })), Pt = new URL("data:text/javascript;base64,Y2xhc3MgUGxheWJhY2tXb3JrbGV0IGV4dGVuZHMgQXVkaW9Xb3JrbGV0UHJvY2Vzc29yIHsKICBzdGF0aWMgRlNNID0gewogICAgSURMRTogMCwKICAgIFBMQVlJTkc6IDEsCiAgfTsKCiAgY29uc3RydWN0b3Iob3B0aW9ucykgewogICAgc3VwZXIoKTsKICAgIHRoaXMucG9ydC5vbm1lc3NhZ2UgPSB0aGlzLmhhbmRsZU1lc3NhZ2UuYmluZCh0aGlzKTsKCiAgICB0aGlzLl9zYW1wbGVSYXRlID0gb3B0aW9ucz8ucHJvY2Vzc29yT3B0aW9ucz8uc2FtcGxlUmF0ZSB8fCBzYW1wbGVSYXRlOwogICAgdGhpcy5fc2NhbGUgPSAxIC8gMzI3Njg7IC8vIFBDTTE2IC0+IGZsb2F0CgogICAgLy8gU2lsZW5jZSBkZXRlY3Rpb24gdGhyZXNob2xkICgxIHNlY29uZCkgYXMgYSBmYWxsYmFjayBzYWZldHkgbmV0CiAgICBjb25zdCBzaWxlbmNlRHVyYXRpb25TZWNvbmRzID0gMS4wOwogICAgdGhpcy5fc2lsZW5jZVRocmVzaG9sZEJsb2NrcyA9IE1hdGguY2VpbCgodGhpcy5fc2FtcGxlUmF0ZSAqIHNpbGVuY2VEdXJhdGlvblNlY29uZHMpIC8gMTI4KTsKCiAgICAvLyBNZXRyaWNzIGNvbmZpZ3VyYXRpb24gdmlhIG9wdGlvbnMKICAgIGNvbnN0IG1ldHJpY3NDZmcgPSBvcHRpb25zPy5wcm9jZXNzb3JPcHRpb25zPy5tZXRyaWNzIHx8IHt9OwogICAgdGhpcy5fbWV0cmljc0VuYWJsZWQgPSBtZXRyaWNzQ2ZnLmVuYWJsZWQgIT09IGZhbHNlOwogICAgY29uc3QgaW50ZXJ2YWxIeiA9ICh0eXBlb2YgbWV0cmljc0NmZy5pbnRlcnZhbEh6ID09PSAibnVtYmVyIiAmJiBtZXRyaWNzQ2ZnLmludGVydmFsSHogPiAwKQogICAgICA/IG1ldHJpY3NDZmcuaW50ZXJ2YWxIeiA6IDI7CiAgICAvLyBNZXRyaWNzIHN0YXRlIChsb3ctb3ZlcmhlYWQpCiAgICB0aGlzLl9mcmFtZXNQcm9jZXNzZWQgPSAwOwogICAgdGhpcy5fdW5kZXJydW5CbG9ja3MgPSAwOwogICAgdGhpcy5fbWF4UXVldWVTYW1wbGVzID0gMDsKICAgIHRoaXMuX2xhc3RNZXRyaWNzU2VudEF0RnJhbWUgPSAwOwogICAgLy8gQ29udmVydCB0byBmcmFtZXMgYmV0d2VlbiByZXBvcnRzCiAgICB0aGlzLl9tZXRyaWNzSW50ZXJ2YWxGcmFtZXMgPSBNYXRoLm1heCgxMjgsIE1hdGgucm91bmQodGhpcy5fc2FtcGxlUmF0ZSAvIGludGVydmFsSHopKTsKCiAgICB0aGlzLnJlc2V0KCk7CiAgfQoKICAvKioKICAgKiBSZXNldHMgdGhlIHdvcmtsZXQgdG8gaXRzIGluaXRpYWwgSURMRSBzdGF0ZS4KICAgKi8KICByZXNldCgpIHsKICAgIHRoaXMuX2J1ZmZlclF1ZXVlID0gW107CiAgICB0aGlzLl9jdXJyZW50Q2h1bmsgPSBudWxsOwogICAgdGhpcy5fY3VycmVudENodW5rT2Zmc2V0ID0gMDsKICAgIHRoaXMuX3N0YXRlID0gUGxheWJhY2tXb3JrbGV0LkZTTS5JRExFOwoKICAgIHRoaXMuX25vTW9yZURhdGFSZWNlaXZlZCA9IGZhbHNlOwogICAgdGhpcy5fc2lsZW5jZUZyYW1lc0NvdW50ID0gMDsKICAgIHRoaXMuX2hhc1NlbnRFbmRlZCA9IGZhbHNlOwogICAgLy8gUmVzZXQgbWF4IHF1ZXVlIHRyYWNrZXIgb25seSB3aGVuIGdvaW5nIGlkbGUKICAgIHRoaXMuX21heFF1ZXVlU2FtcGxlcyA9IDA7CiAgfQoKICBoYW5kbGVNZXNzYWdlKGV2ZW50KSB7CiAgICBjb25zdCB7IHR5cGUsIGRhdGEgfSA9IGV2ZW50LmRhdGE7CgogICAgLy8gSU5URVJSVVBUOiBUaGUgbWFpbiB0aHJlYWQgd2FudHMgdG8gc3RvcCBpbW1lZGlhdGVseS4KICAgIGlmICh0eXBlID09PSAic3RvcCIpIHsKICAgICAgdGhpcy5yZXNldCgpOwogICAgICAvLyBTZW5kIGZpbmFsIG1ldHJpY3Mgc2hvd2luZyBjbGVhcmVkIHN0YXRlCiAgICAgIGlmICh0aGlzLl9tZXRyaWNzRW5hYmxlZCkgewogICAgICAgIHRyeSB7CiAgICAgICAgICB0aGlzLnBvcnQucG9zdE1lc3NhZ2UoewogICAgICAgICAgICB0eXBlOiAibWV0cmljcyIsCiAgICAgICAgICAgIGRhdGE6IHsKICAgICAgICAgICAgICBzdGF0ZTogUGxheWJhY2tXb3JrbGV0LkZTTS5JRExFLAogICAgICAgICAgICAgIHF1ZXVlZFNhbXBsZXM6IDAsCiAgICAgICAgICAgICAgcXVldWVkTXM6IDAsCiAgICAgICAgICAgICAgbWF4UXVldWVkTXM6IE1hdGgucm91bmQoKHRoaXMuX21heFF1ZXVlU2FtcGxlcyAvIHRoaXMuX3NhbXBsZVJhdGUpICogMTAwMCksCiAgICAgICAgICAgICAgdW5kZXJydW5CbG9ja3M6IHRoaXMuX3VuZGVycnVuQmxvY2tzLAogICAgICAgICAgICAgIGZyYW1lc1Byb2Nlc3NlZDogdGhpcy5fZnJhbWVzUHJvY2Vzc2VkCiAgICAgICAgICAgIH0KICAgICAgICAgIH0pOwogICAgICAgIH0gY2F0Y2ggKF8pIHsgfQogICAgICB9CiAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBNYWluIHRocmVhZCBoYXMgc2lnbmFsZWQgdGhhdCBubyBtb3JlIGF1ZGlvIGNodW5rcyB3aWxsIGJlIHNlbnQgZm9yIHRoaXMgdXR0ZXJhbmNlLgogICAgaWYgKHR5cGUgPT09ICJuby1tb3JlLWRhdGEiKSB7CiAgICAgIHRoaXMuX25vTW9yZURhdGFSZWNlaXZlZCA9IHRydWU7CiAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBVcGRhdGUgbWV0cmljcyBjb25maWd1cmF0aW9uIGF0IHJ1bnRpbWUKICAgIGlmICh0eXBlID09PSAiY29uZmlnLW1ldHJpY3MiICYmIGRhdGEgJiYgdHlwZW9mIGRhdGEgPT09ICJvYmplY3QiKSB7CiAgICAgIGlmICgiZW5hYmxlZCIgaW4gZGF0YSkgdGhpcy5fbWV0cmljc0VuYWJsZWQgPSAhIWRhdGEuZW5hYmxlZDsKICAgICAgaWYgKHR5cGVvZiBkYXRhLmludGVydmFsSHogPT09ICJudW1iZXIiICYmIGRhdGEuaW50ZXJ2YWxIeiA+IDApIHsKICAgICAgICBjb25zdCBpbnRlcnZhbEh6ID0gZGF0YS5pbnRlcnZhbEh6OwogICAgICAgIHRoaXMuX21ldHJpY3NJbnRlcnZhbEZyYW1lcyA9IE1hdGgubWF4KDEyOCwgTWF0aC5yb3VuZCh0aGlzLl9zYW1wbGVSYXRlIC8gaW50ZXJ2YWxIeikpOwogICAgICB9CiAgICAgIC8vIFJlc2V0IHBhY2luZyBzbyB0aGUgbmV4dCByZXBvcnQgYWxpZ25zIHdpdGggbmV3IGludGVydmFsCiAgICAgIHRoaXMuX2xhc3RNZXRyaWNzU2VudEF0RnJhbWUgPSB0aGlzLl9mcmFtZXNQcm9jZXNzZWQ7CiAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBOZXcgYXVkaW8gZGF0YSBoYXMgYXJyaXZlZC4KICAgIGlmICh0eXBlID09PSAiYXVkaW9EYXRhIiAmJiBkYXRhIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHsKICAgICAgdGhpcy5fbm9Nb3JlRGF0YVJlY2VpdmVkID0gZmFsc2U7CiAgICAgIC8vIElmIHdlIHdlcmUgaWRsZSwgdGhpcyBuZXcgZGF0YSBraWNrcyBvZmYgdGhlIHBsYXliYWNrLgogICAgICBpZiAodGhpcy5fc3RhdGUgPT09IFBsYXliYWNrV29ya2xldC5GU00uSURMRSkgewogICAgICAgIHRoaXMuX3N0YXRlID0gUGxheWJhY2tXb3JrbGV0LkZTTS5QTEFZSU5HOwogICAgICAgIHRoaXMucG9ydC5wb3N0TWVzc2FnZSh7IHR5cGU6ICJwbGF5YmFjay1zdGFydGVkIiB9KTsKICAgICAgfQoKICAgICAgLy8gV2Ugb25seSBxdWV1ZSBkYXRhIGlmIHdlIGFyZSBpbiB0aGUgUExBWUlORyBzdGF0ZS4gVGhpcyBwcmV2ZW50cwogICAgICAvLyBkYXRhIGZyb20gYSBwcmV2aW91cywgaW50ZXJydXB0ZWQgc3RyZWFtIGZyb20gbGluZ2VyaW5nLgogICAgICBpZiAodGhpcy5fc3RhdGUgPT09IFBsYXliYWNrV29ya2xldC5GU00uUExBWUlORykgewogICAgICAgIC8vIFN0b3JlIGFzIEludDE2QXJyYXkgdmlldyB0byBhdm9pZCBjb25zdHJ1Y3RpbmcgaXQgaW4gcHJvY2VzcygpCiAgICAgICAgdGhpcy5fYnVmZmVyUXVldWUucHVzaChuZXcgSW50MTZBcnJheShkYXRhKSk7CiAgICAgICAgdGhpcy5fc2lsZW5jZUZyYW1lc0NvdW50ID0gMDsgLy8gUmVzZXQgc2lsZW5jZSBjb3VudGVyIG9uIG5ldyBkYXRhCiAgICAgIH0KICAgIH0KICB9CgogIHByb2Nlc3MoaW5wdXRzLCBvdXRwdXRzLCBwYXJhbWV0ZXJzKSB7CiAgICBjb25zdCBvdXRwdXRDaGFubmVsID0gb3V0cHV0c1swXT8uWzBdOwogICAgaWYgKCFvdXRwdXRDaGFubmVsKSB7CiAgICAgIHJldHVybiB0cnVlOyAvLyBLZWVwIGFsaXZlIGV2ZW4gaWYgb3V0cHV0IGlzIHRlbXBvcmFyaWx5IGRpc2Nvbm5lY3RlZAogICAgfQoKICAgIC8vIElmIHdlIGFyZSBub3QgcGxheWluZywganVzdCBvdXRwdXQgc2lsZW5jZSBhbmQgd2FpdC4KICAgIGlmICh0aGlzLl9zdGF0ZSAhPT0gUGxheWJhY2tXb3JrbGV0LkZTTS5QTEFZSU5HKSB7CiAgICAgIG91dHB1dENoYW5uZWwuZmlsbCgwKTsKICAgICAgcmV0dXJuIHRydWU7IC8vIEFsd2F5cyByZXR1cm4gdHJ1ZSB0byBrZWVwIHRoZSBwcm9jZXNzb3IgYWxpdmUKICAgIH0KCiAgICAvLyBDb3JlIFBMQVlJTkcgTG9naWMKICAgIGNvbnN0IGJsb2NrU2l6ZSA9IG91dHB1dENoYW5uZWwubGVuZ3RoOwogICAgbGV0IHNhbXBsZXNDb3BpZWQgPSAwOwoKICAgIHdoaWxlIChzYW1wbGVzQ29waWVkIDwgYmxvY2tTaXplKSB7CiAgICAgIGlmICghdGhpcy5fY3VycmVudENodW5rIHx8IHRoaXMuX2N1cnJlbnRDaHVua09mZnNldCA+PSB0aGlzLl9jdXJyZW50Q2h1bmsubGVuZ3RoKSB7CiAgICAgICAgaWYgKHRoaXMuX2J1ZmZlclF1ZXVlLmxlbmd0aCA+IDApIHsKICAgICAgICAgIHRoaXMuX2N1cnJlbnRDaHVuayA9IHRoaXMuX2J1ZmZlclF1ZXVlLnNoaWZ0KCk7CiAgICAgICAgICB0aGlzLl9jdXJyZW50Q2h1bmtPZmZzZXQgPSAwOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAvLyBCdWZmZXIgaXMgZW1wdHkuIENoZWNrIGZvciBlbmQgY29uZGl0aW9ucy4KICAgICAgICAgIGNvbnN0IGlzVGltZWRPdXQgPSB0aGlzLl9zaWxlbmNlRnJhbWVzQ291bnQgPiB0aGlzLl9zaWxlbmNlVGhyZXNob2xkQmxvY2tzOwoKICAgICAgICAgIGlmICh0aGlzLl9ub01vcmVEYXRhUmVjZWl2ZWQgfHwgaXNUaW1lZE91dCkgewogICAgICAgICAgICAvLyBFTkQgT0YgUExBWUJBQ0s6IEVpdGhlciBleHBsaWNpdGx5IHNpZ25hbGVkIG9yIHRpbWVkIG91dC4KICAgICAgICAgICAgaWYgKCF0aGlzLl9oYXNTZW50RW5kZWQpIHsKICAgICAgICAgICAgICB0aGlzLnBvcnQucG9zdE1lc3NhZ2UoeyB0eXBlOiAicGxheWJhY2stZW5kZWQiIH0pOwogICAgICAgICAgICAgIHRoaXMuX2hhc1NlbnRFbmRlZCA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gU2VuZCBmaW5hbCBtZXRyaWNzIHNob3dpbmcgY2xlYXJlZCBzdGF0ZQogICAgICAgICAgICBpZiAodGhpcy5fbWV0cmljc0VuYWJsZWQpIHsKICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgdGhpcy5wb3J0LnBvc3RNZXNzYWdlKHsKICAgICAgICAgICAgICAgICAgdHlwZTogIm1ldHJpY3MiLAogICAgICAgICAgICAgICAgICBkYXRhOiB7CiAgICAgICAgICAgICAgICAgICAgc3RhdGU6IFBsYXliYWNrV29ya2xldC5GU00uSURMRSwKICAgICAgICAgICAgICAgICAgICBxdWV1ZWRTYW1wbGVzOiAwLAogICAgICAgICAgICAgICAgICAgIHF1ZXVlZE1zOiAwLAogICAgICAgICAgICAgICAgICAgIG1heFF1ZXVlZE1zOiBNYXRoLnJvdW5kKCh0aGlzLl9tYXhRdWV1ZVNhbXBsZXMgLyB0aGlzLl9zYW1wbGVSYXRlKSAqIDEwMDApLAogICAgICAgICAgICAgICAgICAgIHVuZGVycnVuQmxvY2tzOiB0aGlzLl91bmRlcnJ1bkJsb2NrcywKICAgICAgICAgICAgICAgICAgICBmcmFtZXNQcm9jZXNzZWQ6IHRoaXMuX2ZyYW1lc1Byb2Nlc3NlZAogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICB9IGNhdGNoIChfKSB7IH0KICAgICAgICAgICAgfQogICAgICAgICAgICB0aGlzLnJlc2V0KCk7IC8vIFJlc2V0IHRvIElETEUgc3RhdGUgZm9yIHJldXNlCiAgICAgICAgICAgIGJyZWFrOyAvLyBFeGl0IHdoaWxlIGxvb3AKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8vIEJVRkZFUiBVTkRFUlJVTiAoTEFHKTogUGxheSBzaWxlbmNlIGFuZCB3YWl0IGZvciBtb3JlIGRhdGEuCiAgICAgICAgICAgIHRoaXMuX3NpbGVuY2VGcmFtZXNDb3VudCsrOwogICAgICAgICAgICBpZiAodGhpcy5fbWV0cmljc0VuYWJsZWQpIHRoaXMuX3VuZGVycnVuQmxvY2tzKys7CiAgICAgICAgICAgIGJyZWFrOyAvLyBFeGl0IHdoaWxlIGxvb3AKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KCiAgICAgIC8vIElmIHdlIGhhdmUgYSBjaHVuayAoY291bGQgYmUgYSBuZXcgb25lIGZyb20gdGhlIGxvZ2ljIGFib3ZlKSwgcHJvY2VzcyBpdC4KICAgICAgaWYgKHRoaXMuX2N1cnJlbnRDaHVuaykgewogICAgICAgIGNvbnN0IHNhbXBsZXNUb0NvcHkgPSBNYXRoLm1pbigKICAgICAgICAgIGJsb2NrU2l6ZSAtIHNhbXBsZXNDb3BpZWQsCiAgICAgICAgICB0aGlzLl9jdXJyZW50Q2h1bmsubGVuZ3RoIC0gdGhpcy5fY3VycmVudENodW5rT2Zmc2V0CiAgICAgICAgKTsKICAgICAgICAvLyBEaXJlY3RseSB3cml0ZSB0byBvdXRwdXRDaGFubmVsIHRvIGF2b2lkIGV4dHJhIGNvcHkKICAgICAgICBjb25zdCBzcmMgPSB0aGlzLl9jdXJyZW50Q2h1bms7CiAgICAgICAgY29uc3QgYmFzZVNyYyA9IHRoaXMuX2N1cnJlbnRDaHVua09mZnNldDsKICAgICAgICBjb25zdCBiYXNlRHN0ID0gc2FtcGxlc0NvcGllZDsKICAgICAgICBjb25zdCBzY2FsZSA9IHRoaXMuX3NjYWxlOwogICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2FtcGxlc1RvQ29weTsgaSsrKSB7CiAgICAgICAgICBvdXRwdXRDaGFubmVsW2Jhc2VEc3QgKyBpXSA9IHNyY1tiYXNlU3JjICsgaV0gKiBzY2FsZTsKICAgICAgICB9CgogICAgICAgIHRoaXMuX2N1cnJlbnRDaHVua09mZnNldCArPSBzYW1wbGVzVG9Db3B5OwogICAgICAgIHNhbXBsZXNDb3BpZWQgKz0gc2FtcGxlc1RvQ29weTsKICAgICAgfQogICAgfQoKICAgIC8vIFplcm8tZmlsbCB0aGUgcmVtYWluZGVyLCBpZiBhbnksIG9uY2UgcGVyIGJsb2NrCiAgICBpZiAoc2FtcGxlc0NvcGllZCA8IGJsb2NrU2l6ZSkgewogICAgICBvdXRwdXRDaGFubmVsLmZpbGwoMCwgc2FtcGxlc0NvcGllZCk7CiAgICB9CgogICAgLy8gVXBkYXRlIG1ldHJpY3MgKG9wdGlvbmFsKQogICAgaWYgKHRoaXMuX21ldHJpY3NFbmFibGVkKSB7CiAgICAgIHRoaXMuX2ZyYW1lc1Byb2Nlc3NlZCArPSBibG9ja1NpemU7CgogICAgICAvLyBUcmFjayBxdWV1ZSBkZXB0aCBpbiBzYW1wbGVzIChhcHByb3hpbWF0ZSkKICAgICAgbGV0IHF1ZXVlZFNhbXBsZXMgPSAwOwogICAgICBpZiAodGhpcy5fY3VycmVudENodW5rKSBxdWV1ZWRTYW1wbGVzICs9IE1hdGgubWF4KDAsIHRoaXMuX2N1cnJlbnRDaHVuay5sZW5ndGggLSB0aGlzLl9jdXJyZW50Q2h1bmtPZmZzZXQpOwogICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX2J1ZmZlclF1ZXVlLmxlbmd0aDsgaSsrKSBxdWV1ZWRTYW1wbGVzICs9IHRoaXMuX2J1ZmZlclF1ZXVlW2ldLmxlbmd0aDsKICAgICAgaWYgKHF1ZXVlZFNhbXBsZXMgPiB0aGlzLl9tYXhRdWV1ZVNhbXBsZXMpIHRoaXMuX21heFF1ZXVlU2FtcGxlcyA9IHF1ZXVlZFNhbXBsZXM7CgogICAgICAvLyBQZXJpb2RpY2FsbHkgc2VuZCBtZXRyaWNzIHRvIG1haW4gdGhyZWFkCiAgICAgIGlmICh0aGlzLl9mcmFtZXNQcm9jZXNzZWQgLSB0aGlzLl9sYXN0TWV0cmljc1NlbnRBdEZyYW1lID49IHRoaXMuX21ldHJpY3NJbnRlcnZhbEZyYW1lcykgewogICAgICAgIHRoaXMuX2xhc3RNZXRyaWNzU2VudEF0RnJhbWUgPSB0aGlzLl9mcmFtZXNQcm9jZXNzZWQ7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIHRoaXMucG9ydC5wb3N0TWVzc2FnZSh7CiAgICAgICAgICAgIHR5cGU6ICJtZXRyaWNzIiwKICAgICAgICAgICAgZGF0YTogewogICAgICAgICAgICAgIHN0YXRlOiB0aGlzLl9zdGF0ZSwKICAgICAgICAgICAgICBxdWV1ZWRTYW1wbGVzLAogICAgICAgICAgICAgIHF1ZXVlZE1zOiBNYXRoLnJvdW5kKChxdWV1ZWRTYW1wbGVzIC8gdGhpcy5fc2FtcGxlUmF0ZSkgKiAxMDAwKSwKICAgICAgICAgICAgICBtYXhRdWV1ZWRNczogTWF0aC5yb3VuZCgodGhpcy5fbWF4UXVldWVTYW1wbGVzIC8gdGhpcy5fc2FtcGxlUmF0ZSkgKiAxMDAwKSwKICAgICAgICAgICAgICB1bmRlcnJ1bkJsb2NrczogdGhpcy5fdW5kZXJydW5CbG9ja3MsCiAgICAgICAgICAgICAgZnJhbWVzUHJvY2Vzc2VkOiB0aGlzLl9mcmFtZXNQcm9jZXNzZWQKICAgICAgICAgICAgfQogICAgICAgICAgfSk7CiAgICAgICAgfSBjYXRjaCAoXykgeyB9CiAgICAgICAgLy8gRG9uJ3QgcmVzZXQgbWF4IHRyYWNrZXIgLSBrZWVwIHNlc3Npb24gcGVhayB1bnRpbCBpZGxlCiAgICAgIH0KICAgIH0KCiAgICAvLyBBTFdBWVMgcmV0dXJuIHRydWUgdG8ga2VlcCB0aGUgcHJvY2Vzc29yIGFsaXZlIGZvciByZXVzZS4KICAgIHJldHVybiB0cnVlOwogIH0KfQoKcmVnaXN0ZXJQcm9jZXNzb3IoInBsYXliYWNrLXdvcmtsZXQiLCBQbGF5YmFja1dvcmtsZXQpOwo=", import.meta.url), rt = {
|
|
2627
2627
|
en: kt,
|
|
2628
2628
|
de: Ct,
|
|
2629
2629
|
fr: Ht,
|
|
2630
2630
|
fi: Mt,
|
|
2631
|
-
lt:
|
|
2632
|
-
},
|
|
2631
|
+
lt: Et
|
|
2632
|
+
}, ue = new b.Quaternion(), oe = new b.Euler(), Ue = new b.Vector3(), Xe = new b.Vector3(), at = new b.Box3();
|
|
2633
2633
|
new b.Matrix4();
|
|
2634
2634
|
new b.Matrix4();
|
|
2635
2635
|
new b.Vector3();
|
|
2636
2636
|
new b.Vector3(0, 0, 1);
|
|
2637
|
-
const
|
|
2637
|
+
const Bt = new b.Vector3(1, 0, 0);
|
|
2638
2638
|
new b.Vector3(0, 1, 0);
|
|
2639
2639
|
new b.Vector3(0, 0, 1);
|
|
2640
2640
|
class nt {
|
|
@@ -3569,15 +3569,15 @@ class nt {
|
|
|
3569
3569
|
"RightArm.scale": { x: 0, y: 0, z: 0 }
|
|
3570
3570
|
}
|
|
3571
3571
|
}, ["Left", "Right"].forEach((a) => {
|
|
3572
|
-
["Leg", "UpLeg", "Arm", "ForeArm", "Hand"].forEach((
|
|
3573
|
-
this.poseDelta.props[a +
|
|
3574
|
-
}), ["HandThumb", "HandIndex", "HandMiddle", "HandRing", "HandPinky"].forEach((
|
|
3575
|
-
this.poseDelta.props[a +
|
|
3572
|
+
["Leg", "UpLeg", "Arm", "ForeArm", "Hand"].forEach((u) => {
|
|
3573
|
+
this.poseDelta.props[a + u + ".quaternion"] = { x: 0, y: 0, z: 0 };
|
|
3574
|
+
}), ["HandThumb", "HandIndex", "HandMiddle", "HandRing", "HandPinky"].forEach((u) => {
|
|
3575
|
+
this.poseDelta.props[a + u + "1.quaternion"] = { x: 0, y: 0, z: 0 }, this.poseDelta.props[a + u + "2.quaternion"] = { x: 0, y: 0, z: 0 }, this.poseDelta.props[a + u + "3.quaternion"] = { x: 0, y: 0, z: 0 };
|
|
3576
3576
|
});
|
|
3577
3577
|
});
|
|
3578
3578
|
const t = /* @__PURE__ */ new Set();
|
|
3579
3579
|
Object.values(this.poseTemplates).forEach((a) => {
|
|
3580
|
-
Object.keys(this.propsToThreeObjects(a.props)).forEach((
|
|
3580
|
+
Object.keys(this.propsToThreeObjects(a.props)).forEach((u) => t.add(u));
|
|
3581
3581
|
}), Object.keys(this.poseDelta.props).forEach((a) => {
|
|
3582
3582
|
t.add(a);
|
|
3583
3583
|
}), this.posePropNames = [...t], this.poseName = "side", this.poseWeightOnLeft = !0, this.gesture = null, this.poseCurrentTemplate = this.poseTemplates[this.poseName], this.poseStraight = this.propsToThreeObjects(this.poseTemplates.straight.props), this.poseBase = this.poseFactory(this.poseCurrentTemplate), this.poseTarget = this.poseFactory(this.poseCurrentTemplate), this.poseAvatar = null, this.avatarHeight = 1.7, this.animTemplateEyes = {
|
|
@@ -4101,10 +4101,10 @@ class nt {
|
|
|
4101
4101
|
RightHand: "RightForeArm",
|
|
4102
4102
|
RightHandMiddle1: "RightHand"
|
|
4103
4103
|
}, i = [];
|
|
4104
|
-
Object.entries(s).forEach((a,
|
|
4104
|
+
Object.entries(s).forEach((a, u) => {
|
|
4105
4105
|
const l = new b.Bone();
|
|
4106
4106
|
l.name = a[0], a[1] ? this.ikMesh.getObjectByName(a[1]).add(l) : this.ikMesh.add(l), i.push(l);
|
|
4107
|
-
}), this.ikMesh.bind(new b.Skeleton(i)), this.dynamicbones = new
|
|
4107
|
+
}), this.ikMesh.bind(new b.Skeleton(i)), this.dynamicbones = new It(), this.isStreaming = !1, this.streamWorkletNode = null, this.streamAudioStartTime = null, this.streamWaitForAudioChunks = !0, this.streamLipsyncLang = null, this.streamLipsyncType = "visemes", this.streamLipsyncQueue = [];
|
|
4108
4108
|
}
|
|
4109
4109
|
/**
|
|
4110
4110
|
* Helper that re/creates the audio context and the other nodes.
|
|
@@ -4150,9 +4150,9 @@ class nt {
|
|
|
4150
4150
|
let e = 3 * n.length / 4;
|
|
4151
4151
|
n[n.length - 1] === "=" && (e--, n[n.length - 2] === "=" && e--);
|
|
4152
4152
|
const t = new ArrayBuffer(e), o = new Uint8Array(t);
|
|
4153
|
-
let s, i = 0, a,
|
|
4153
|
+
let s, i = 0, a, u, l, c;
|
|
4154
4154
|
for (s = 0; s < n.length; s += 4)
|
|
4155
|
-
a = this.b64Lookup[n.charCodeAt(s)],
|
|
4155
|
+
a = this.b64Lookup[n.charCodeAt(s)], u = this.b64Lookup[n.charCodeAt(s + 1)], l = this.b64Lookup[n.charCodeAt(s + 2)], c = this.b64Lookup[n.charCodeAt(s + 3)], o[i++] = a << 2 | u >> 4, o[i++] = (u & 15) << 4 | l >> 2, o[i++] = (l & 3) << 6 | c & 63;
|
|
4156
4156
|
return t;
|
|
4157
4157
|
}
|
|
4158
4158
|
/**
|
|
@@ -4193,8 +4193,8 @@ class nt {
|
|
|
4193
4193
|
const e = {};
|
|
4194
4194
|
for (let [t, o] of Object.entries(n)) {
|
|
4195
4195
|
const s = t.split(".");
|
|
4196
|
-
let i = Array.isArray(o.x) ? this.gaussianRandom(...o.x) : o.x, a = Array.isArray(o.y) ? this.gaussianRandom(...o.y) : o.y,
|
|
4197
|
-
s[1] === "position" || s[1] === "scale" ? e[t] = new b.Vector3(i, a,
|
|
4196
|
+
let i = Array.isArray(o.x) ? this.gaussianRandom(...o.x) : o.x, a = Array.isArray(o.y) ? this.gaussianRandom(...o.y) : o.y, u = Array.isArray(o.z) ? this.gaussianRandom(...o.z) : o.z;
|
|
4197
|
+
s[1] === "position" || s[1] === "scale" ? e[t] = new b.Vector3(i, a, u) : s[1] === "rotation" ? (t = s[0] + ".quaternion", e[t] = new b.Quaternion().setFromEuler(new b.Euler(i, a, u, "XYZ")).normalize()) : s[1] === "quaternion" && (e[t] = new b.Quaternion(i, a, u, o.w).normalize());
|
|
4198
4198
|
}
|
|
4199
4199
|
return e;
|
|
4200
4200
|
}
|
|
@@ -4222,23 +4222,23 @@ class nt {
|
|
|
4222
4222
|
n.forEach((s) => {
|
|
4223
4223
|
if (!o && s.morphTargetDictionary.hasOwnProperty(e)) return;
|
|
4224
4224
|
const i = s.geometry;
|
|
4225
|
-
let a = null,
|
|
4226
|
-
for (const [l,
|
|
4225
|
+
let a = null, u = null;
|
|
4226
|
+
for (const [l, c] of Object.entries(t))
|
|
4227
4227
|
if (s.morphTargetDictionary.hasOwnProperty(l)) {
|
|
4228
4228
|
const r = s.morphTargetDictionary[l], h = i.morphAttributes.position[r], d = i.morphAttributes.normal?.[r];
|
|
4229
|
-
a || (a = new b.Float32BufferAttribute(h.count * 3, 3), d && (
|
|
4229
|
+
a || (a = new b.Float32BufferAttribute(h.count * 3, 3), d && (u = new b.Float32BufferAttribute(h.count * 3, 3)));
|
|
4230
4230
|
for (let g = 0; g < h.count; g++) {
|
|
4231
|
-
const R = a.getX(g) + h.getX(g) *
|
|
4232
|
-
a.setXYZ(g, R, x,
|
|
4231
|
+
const R = a.getX(g) + h.getX(g) * c, x = a.getY(g) + h.getY(g) * c, k = a.getZ(g) + h.getZ(g) * c;
|
|
4232
|
+
a.setXYZ(g, R, x, k);
|
|
4233
4233
|
}
|
|
4234
4234
|
if (d)
|
|
4235
4235
|
for (let g = 0; g < h.count; g++) {
|
|
4236
|
-
const R =
|
|
4237
|
-
|
|
4236
|
+
const R = u.getX(g) + d.getX(g) * c, x = u.getY(g) + d.getY(g) * c, k = u.getZ(g) + d.getZ(g) * c;
|
|
4237
|
+
u.setXYZ(g, R, x, k);
|
|
4238
4238
|
}
|
|
4239
4239
|
}
|
|
4240
4240
|
if (a) {
|
|
4241
|
-
i.morphAttributes.position.push(a),
|
|
4241
|
+
i.morphAttributes.position.push(a), u && i.morphAttributes.normal.push(u);
|
|
4242
4242
|
const l = i.morphAttributes.position.length - 1;
|
|
4243
4243
|
s.morphTargetInfluences[l] = 0, s.morphTargetDictionary[e] = l;
|
|
4244
4244
|
}
|
|
@@ -4268,7 +4268,7 @@ class nt {
|
|
|
4268
4268
|
throw new Error("Blend shapes not found");
|
|
4269
4269
|
const i = new Set(this.mtCustoms);
|
|
4270
4270
|
this.morphs.forEach((l) => {
|
|
4271
|
-
Object.keys(l.morphTargetDictionary).forEach((
|
|
4271
|
+
Object.keys(l.morphTargetDictionary).forEach((c) => i.add(c));
|
|
4272
4272
|
}), this.mtExtras.forEach((l) => {
|
|
4273
4273
|
i.has(l.key) || (this.addMixedMorphTarget(this.morphs, l.key, l.mix), i.add(l.key));
|
|
4274
4274
|
});
|
|
@@ -4295,16 +4295,16 @@ class nt {
|
|
|
4295
4295
|
ms: [],
|
|
4296
4296
|
is: []
|
|
4297
4297
|
}, a[l].value = a[l].baseline, a[l].applied = a[l].baseline;
|
|
4298
|
-
const
|
|
4299
|
-
|
|
4300
|
-
a[l][r] =
|
|
4298
|
+
const c = this.mtAvatar[l];
|
|
4299
|
+
c && ["fixed", "system", "systemd", "realtime", "base", "v", "value", "applied"].forEach((r) => {
|
|
4300
|
+
a[l][r] = c[r];
|
|
4301
4301
|
}), this.morphs.forEach((r) => {
|
|
4302
4302
|
const h = r.morphTargetDictionary[l];
|
|
4303
4303
|
h !== void 0 && (a[l].ms.push(r.morphTargetInfluences), a[l].is.push(h), r.morphTargetInfluences[h] = a[l].applied);
|
|
4304
4304
|
});
|
|
4305
4305
|
}), this.mtAvatar = a, this.poseAvatar = { props: {} }, this.posePropNames.forEach((l) => {
|
|
4306
|
-
const
|
|
4307
|
-
this.poseAvatar.props[l] = r[
|
|
4306
|
+
const c = l.split("."), r = this.armature.getObjectByName(c[0]);
|
|
4307
|
+
this.poseAvatar.props[l] = r[c[1]], this.poseBase.props.hasOwnProperty(l) ? this.poseAvatar.props[l].copy(this.poseBase.props[l]) : this.poseBase.props[l] = this.poseAvatar.props[l].clone(), this.poseDelta.props.hasOwnProperty(l) && !this.poseTarget.props.hasOwnProperty(l) && (this.poseTarget.props[l] = this.poseAvatar.props[l].clone()), this.poseTarget.props[l].t = this.animClock, this.poseTarget.props[l].d = 2e3;
|
|
4308
4308
|
}), this.ikMesh.traverse((l) => {
|
|
4309
4309
|
l.isBone && l.position.copy(this.armature.getObjectByName(l.name).position);
|
|
4310
4310
|
}), this.isAvatarOnly ? this.scene && this.scene.add(this.armature) : (this.scene.add(o.scene), this.scene.add(this.lightAmbient), this.scene.add(this.lightDirect), this.scene.add(this.lightSpot), this.lightSpot.target = this.armature.getObjectByName("Head")), n.hasOwnProperty("modelDynamicBones"))
|
|
@@ -4314,8 +4314,8 @@ class nt {
|
|
|
4314
4314
|
console.error("Dynamic bones setup failed: " + l);
|
|
4315
4315
|
}
|
|
4316
4316
|
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");
|
|
4317
|
-
const
|
|
4318
|
-
this.objectLeftEye.getWorldPosition(
|
|
4317
|
+
const u = new b.Vector3();
|
|
4318
|
+
this.objectLeftEye.getWorldPosition(u), this.avatarHeight = u.y + 0.2, this.viewName || this.setView(this.opt.cameraView), this.setMood(this.avatar.avatarMood || this.moodName || this.opt.avatarMood), this.avatar.body === "M" && this.poseTemplates.wide && (this.poseName = "wide", this.setPoseFromTemplate(this.poseTemplates.wide, 0)), this.initializeFBXAnimationLoader(), this.bodyMovement && this.bodyMovement !== "idle" && this.applyBodyMovementAnimation(), this.start();
|
|
4319
4319
|
}
|
|
4320
4320
|
/**
|
|
4321
4321
|
* Get view names.
|
|
@@ -4343,22 +4343,22 @@ class nt {
|
|
|
4343
4343
|
return;
|
|
4344
4344
|
}
|
|
4345
4345
|
if (this.viewName = n || this.viewName, e = e || {}, this.isAvatarOnly) return;
|
|
4346
|
-
const t = e.hasOwnProperty("cameraX") ? e.cameraX : this.opt.cameraX, o = e.hasOwnProperty("cameraY") ? e.cameraY : this.opt.cameraY, s = e.hasOwnProperty("cameraDistance") ? e.cameraDistance : this.opt.cameraDistance, i = e.hasOwnProperty("cameraRotateX") ? e.cameraRotateX : this.opt.cameraRotateX, a = e.hasOwnProperty("cameraRotateY") ? e.cameraRotateY : this.opt.cameraRotateY,
|
|
4347
|
-
let l = -t * Math.tan(
|
|
4346
|
+
const t = e.hasOwnProperty("cameraX") ? e.cameraX : this.opt.cameraX, o = e.hasOwnProperty("cameraY") ? e.cameraY : this.opt.cameraY, s = e.hasOwnProperty("cameraDistance") ? e.cameraDistance : this.opt.cameraDistance, i = e.hasOwnProperty("cameraRotateX") ? e.cameraRotateX : this.opt.cameraRotateX, a = e.hasOwnProperty("cameraRotateY") ? e.cameraRotateY : this.opt.cameraRotateY, u = this.camera.fov * (Math.PI / 180);
|
|
4347
|
+
let l = -t * Math.tan(u / 2), c = (1 - o) * Math.tan(u / 2), r = s;
|
|
4348
4348
|
switch (this.viewName) {
|
|
4349
4349
|
case "head":
|
|
4350
|
-
r += 2,
|
|
4350
|
+
r += 2, c = c * r + 4 * this.avatarHeight / 5;
|
|
4351
4351
|
break;
|
|
4352
4352
|
case "upper":
|
|
4353
|
-
r += 4.5,
|
|
4353
|
+
r += 4.5, c = c * r + 2 * this.avatarHeight / 3;
|
|
4354
4354
|
break;
|
|
4355
4355
|
case "mid":
|
|
4356
|
-
r += 8,
|
|
4356
|
+
r += 8, c = c * r + this.avatarHeight / 3;
|
|
4357
4357
|
break;
|
|
4358
4358
|
default:
|
|
4359
|
-
r += 12,
|
|
4359
|
+
r += 12, c = c * r;
|
|
4360
4360
|
}
|
|
4361
|
-
l = l * r, this.controlsEnd = new b.Vector3(l,
|
|
4361
|
+
l = l * r, this.controlsEnd = new b.Vector3(l, c, 0), this.cameraEnd = new b.Vector3(l, c, r).applyEuler(new b.Euler(i, a, 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;
|
|
4362
4362
|
}
|
|
4363
4363
|
/**
|
|
4364
4364
|
* Change light colors and intensities.
|
|
@@ -4414,7 +4414,7 @@ class nt {
|
|
|
4414
4414
|
if (e.x === 0 && e.y === 0 && e.z === 0) continue;
|
|
4415
4415
|
oe.set(e.x, e.y, e.z);
|
|
4416
4416
|
const t = this.poseAvatar.props[n];
|
|
4417
|
-
t.isQuaternion ? (
|
|
4417
|
+
t.isQuaternion ? (ue.setFromEuler(oe), t.multiply(ue)) : t.isVector3 && t.add(oe);
|
|
4418
4418
|
}
|
|
4419
4419
|
}
|
|
4420
4420
|
/**
|
|
@@ -4469,17 +4469,17 @@ class nt {
|
|
|
4469
4469
|
"HandMiddle",
|
|
4470
4470
|
"HandRing",
|
|
4471
4471
|
"HandPinky"
|
|
4472
|
-
].forEach((
|
|
4473
|
-
r === 0 ? (this.poseDelta.props[i +
|
|
4472
|
+
].forEach((c, r) => {
|
|
4473
|
+
r === 0 ? (this.poseDelta.props[i + c + "1.quaternion"].x = 0, this.poseDelta.props[i + c + "2.quaternion"].z = (i === "Left" ? -1 : 1) * t.applied, this.poseDelta.props[i + c + "3.quaternion"].z = (i === "Left" ? -1 : 1) * t.applied) : (this.poseDelta.props[i + c + "1.quaternion"].x = t.applied, this.poseDelta.props[i + c + "2.quaternion"].x = 1.5 * t.applied, this.poseDelta.props[i + c + "3.quaternion"].x = 1.5 * t.applied);
|
|
4474
4474
|
});
|
|
4475
4475
|
break;
|
|
4476
4476
|
case "chestInhale":
|
|
4477
|
-
const a = t.applied / 20,
|
|
4478
|
-
this.poseDelta.props["Spine1.scale"] =
|
|
4477
|
+
const a = t.applied / 20, u = { x: a, y: a / 2, z: 3 * a }, l = { x: 1 / (1 + a) - 1, y: 1 / (1 + a / 2) - 1, z: 1 / (1 + 3 * a) - 1 };
|
|
4478
|
+
this.poseDelta.props["Spine1.scale"] = u, this.poseDelta.props["Neck.scale"] = l, this.poseDelta.props["LeftArm.scale"] = l, this.poseDelta.props["RightArm.scale"] = l;
|
|
4479
4479
|
break;
|
|
4480
4480
|
default:
|
|
4481
|
-
for (let
|
|
4482
|
-
t.ms[
|
|
4481
|
+
for (let c = 0, r = t.ms.length; c < r; c++)
|
|
4482
|
+
t.ms[c][t.is[c]] = t.applied;
|
|
4483
4483
|
}
|
|
4484
4484
|
}
|
|
4485
4485
|
}
|
|
@@ -4494,8 +4494,8 @@ class nt {
|
|
|
4494
4494
|
return Object.entries(n).forEach((o, s) => {
|
|
4495
4495
|
const i = o[0].split(".");
|
|
4496
4496
|
if (i[1] === "position" || i[1] === "rotation" || i[1] === "quaternion") {
|
|
4497
|
-
const a = i[1] === "quaternion" ? i[0] + ".rotation" : o[0],
|
|
4498
|
-
t += (s ? ", " : "") + "'" + a + "':{", t += "x:" + Math.round(
|
|
4497
|
+
const a = i[1] === "quaternion" ? i[0] + ".rotation" : o[0], u = o[1].isQuaternion ? new b.Euler().setFromQuaternion(o[1]) : o[1];
|
|
4498
|
+
t += (s ? ", " : "") + "'" + a + "':{", t += "x:" + Math.round(u.x * e) / e, t += ", y:" + Math.round(u.y * e) / e, t += ", z:" + Math.round(u.z * e) / e, t += "}";
|
|
4499
4499
|
}
|
|
4500
4500
|
}), t += "}", t;
|
|
4501
4501
|
}
|
|
@@ -4565,8 +4565,8 @@ class nt {
|
|
|
4565
4565
|
if (t ? (this.poseCurrentTemplate = this.poseTemplates.oneknee, setTimeout(() => {
|
|
4566
4566
|
this.setPoseFromTemplate(n, e);
|
|
4567
4567
|
}, i)) : this.poseCurrentTemplate = n || this.poseCurrentTemplate, this.poseTarget = this.poseFactory(this.poseCurrentTemplate, i), this.poseWeightOnLeft = !0, (!o && !s || o && s) && (this.poseTarget.props = this.mirrorPose(this.poseTarget.props), this.poseWeightOnLeft = !this.poseWeightOnLeft), this.gesture)
|
|
4568
|
-
for (let [a,
|
|
4569
|
-
this.poseTarget.props.hasOwnProperty(a) && (this.poseTarget.props[a].copy(
|
|
4568
|
+
for (let [a, u] of Object.entries(this.gesture))
|
|
4569
|
+
this.poseTarget.props.hasOwnProperty(a) && (this.poseTarget.props[a].copy(u), this.poseTarget.props[a].t = u.t, this.poseTarget.props[a].d = u.d);
|
|
4570
4570
|
Object.keys(this.poseDelta.props).forEach((a) => {
|
|
4571
4571
|
this.poseTarget.props.hasOwnProperty(a) || (this.poseTarget.props[a] = this.poseBase.props[a].clone(), this.poseTarget.props[a].t = this.animClock, this.poseTarget.props[a].d = i);
|
|
4572
4572
|
});
|
|
@@ -4992,11 +4992,11 @@ class nt {
|
|
|
4992
4992
|
else if (a.hasOwnProperty("alt")) {
|
|
4993
4993
|
let l = a.alt[0];
|
|
4994
4994
|
if (a.alt.length > 1) {
|
|
4995
|
-
const
|
|
4995
|
+
const c = Math.random();
|
|
4996
4996
|
let r = 0;
|
|
4997
4997
|
for (let h = 0; h < a.alt.length; h++) {
|
|
4998
4998
|
let d = this.valueFn(a.alt[h].p);
|
|
4999
|
-
if (r += d === void 0 ? (1 - r) / (a.alt.length - 1 - h) : d,
|
|
4999
|
+
if (r += d === void 0 ? (1 - r) / (a.alt.length - 1 - h) : d, c < r) {
|
|
5000
5000
|
l = a.alt[h];
|
|
5001
5001
|
break;
|
|
5002
5002
|
}
|
|
@@ -5006,19 +5006,19 @@ class nt {
|
|
|
5006
5006
|
continue;
|
|
5007
5007
|
} else
|
|
5008
5008
|
break;
|
|
5009
|
-
let
|
|
5010
|
-
if (Array.isArray(
|
|
5011
|
-
a.dt.forEach((l,
|
|
5009
|
+
let u = this.valueFn(a.delay) || 0;
|
|
5010
|
+
if (Array.isArray(u) && (u = this.gaussianRandom(...u)), a.hasOwnProperty("dt"))
|
|
5011
|
+
a.dt.forEach((l, c) => {
|
|
5012
5012
|
let r = this.valueFn(l);
|
|
5013
|
-
Array.isArray(r) && (r = this.gaussianRandom(...r)), i.ts[
|
|
5013
|
+
Array.isArray(r) && (r = this.gaussianRandom(...r)), i.ts[c + 1] = i.ts[c] + r;
|
|
5014
5014
|
});
|
|
5015
5015
|
else {
|
|
5016
|
-
let l = Object.values(a.vs).reduce((
|
|
5016
|
+
let l = Object.values(a.vs).reduce((c, r) => r.length > c ? r.length : c, 0);
|
|
5017
5017
|
i.ts = Array(l + 1).fill(0);
|
|
5018
5018
|
}
|
|
5019
|
-
s ? i.ts = i.ts.map((l) =>
|
|
5020
|
-
for (let [l,
|
|
5021
|
-
const r = this.getBaselineValue(l), h =
|
|
5019
|
+
s ? i.ts = i.ts.map((l) => u + l * t) : i.ts = i.ts.map((l) => this.animClock + u + l * t), a.vs && a.vs.pose;
|
|
5020
|
+
for (let [l, c] of Object.entries(a.vs)) {
|
|
5021
|
+
const r = this.getBaselineValue(l), h = c.map((d) => (d = this.valueFn(d), d === null ? null : typeof d == "function" ? d : typeof d == "string" || d instanceof String ? l === "pose" && this.avatar && this.avatar.body === "M" && (d === "hip" || d === "side") ? "wide" : d.slice() : Array.isArray(d) ? l === "gesture" ? d.slice() : (r === void 0 ? 0 : r) + o * this.gaussianRandom(...d) : typeof d == "boolean" ? d : d instanceof Object && d.constructor === Object ? Object.assign({}, d) : (r === void 0 ? 0 : r) + o * d));
|
|
5022
5022
|
l === "eyesRotateY" ? (i.vs.eyeLookOutLeft = [null, ...h.map((d) => d > 0 ? d : 0)], i.vs.eyeLookInLeft = [null, ...h.map((d) => d > 0 ? 0 : -d)], i.vs.eyeLookOutRight = [null, ...h.map((d) => d > 0 ? 0 : -d)], i.vs.eyeLookInRight = [null, ...h.map((d) => d > 0 ? d : 0)]) : l === "eyesRotateX" ? (i.vs.eyesLookDown = [null, ...h.map((d) => d > 0 ? d : 0)], i.vs.eyesLookUp = [null, ...h.map((d) => d > 0 ? 0 : -d)]) : i.vs[l] = [null, ...h];
|
|
5023
5023
|
}
|
|
5024
5024
|
for (let l of Object.keys(i.vs))
|
|
@@ -5100,8 +5100,8 @@ class nt {
|
|
|
5100
5100
|
if (this.isSpeaking)
|
|
5101
5101
|
for (a = 0, this.audioAnalyzerNode.getByteFrequencyData(this.volumeFrequencyData), t = 2, s = 10; t < s; t++)
|
|
5102
5102
|
this.volumeFrequencyData[t] > a && (a = this.volumeFrequencyData[t]);
|
|
5103
|
-
let
|
|
5104
|
-
const
|
|
5103
|
+
let u = null, l = null;
|
|
5104
|
+
const c = [];
|
|
5105
5105
|
for (t = 0, s = this.animQueue.length; t < s; t++) {
|
|
5106
5106
|
const r = this.animQueue[t];
|
|
5107
5107
|
if (!(!r || !r.ts || !r.ts.length || this.animClock < r.ts[0])) {
|
|
@@ -5128,12 +5128,12 @@ class nt {
|
|
|
5128
5128
|
g.newvalue *= 1 + a / 255 - 0.5;
|
|
5129
5129
|
}
|
|
5130
5130
|
g.needsUpdate = !0;
|
|
5131
|
-
} else h === "eyeContact" && d[o] !== null &&
|
|
5131
|
+
} else h === "eyeContact" && d[o] !== null && u !== !1 ? u = !!d[o] : h === "headMove" && d[o] !== null && l !== !1 ? d[o] === 0 ? l = !1 : (Math.random() < d[o] && (l = !0), d[o] = null) : d[o] !== null && (c.push({ mt: h, val: d[o] }), d[o] = null);
|
|
5132
5132
|
o === i ? (r.hasOwnProperty("mood") && this.setMood(r.mood), r.loop ? (i = this.isSpeaking && (r.template.name === "head" || r.template.name === "eyes") ? 4 : 1, this.animQueue[t] = this.animFactory(r.template, r.loop > 0 ? r.loop - 1 : r.loop, 1, 1 / i)) : (this.animQueue.splice(t--, 1), s--)) : r.ndx = o - 1;
|
|
5133
5133
|
}
|
|
5134
5134
|
}
|
|
5135
|
-
for (let r = 0, h =
|
|
5136
|
-
switch (o =
|
|
5135
|
+
for (let r = 0, h = c.length; r < h; r++)
|
|
5136
|
+
switch (o = c[r].val, c[r].mt) {
|
|
5137
5137
|
case "speak":
|
|
5138
5138
|
this.speakText(o);
|
|
5139
5139
|
break;
|
|
@@ -5179,7 +5179,7 @@ class nt {
|
|
|
5179
5179
|
}, o.x ? new b.Vector3(o.x, o.y, o.z) : null, !0, o.d);
|
|
5180
5180
|
break;
|
|
5181
5181
|
}
|
|
5182
|
-
if ((
|
|
5182
|
+
if ((u || l) && (oe.setFromQuaternion(this.poseAvatar.props["Head.quaternion"]), oe.x = Math.max(-0.9, Math.min(0.9, 2 * oe.x - 0.5)), oe.y = Math.max(-0.9, Math.min(0.9, -2.5 * oe.y)), u ? (Object.assign(this.mtAvatar.eyesLookDown, { system: oe.x < 0 ? -oe.x : 0, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyesLookUp, { system: oe.x < 0 ? 0 : oe.x, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookInLeft, { system: oe.y < 0 ? -oe.y : 0, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookOutLeft, { system: oe.y < 0 ? 0 : oe.y, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookInRight, { system: oe.y < 0 ? 0 : oe.y, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookOutRight, { system: oe.y < 0 ? -oe.y : 0, needsUpdate: !0 }), l && (t = -this.mtAvatar.bodyRotateY.value, o = this.gaussianRandom(-0.2, 0.2), this.animQueue.push(this.animFactory({
|
|
5183
5183
|
name: "headmove",
|
|
5184
5184
|
dt: [[1e3, 2e3], [1e3, 2e3, 1, 2], [1e3, 2e3], [1e3, 2e3, 1, 2]],
|
|
5185
5185
|
vs: {
|
|
@@ -5200,7 +5200,11 @@ class nt {
|
|
|
5200
5200
|
eyeLookOutRight: [null, 0],
|
|
5201
5201
|
eyeContact: [0]
|
|
5202
5202
|
}
|
|
5203
|
-
})))), e > 2 * this.animFrameDur && (e = 2 * this.animFrameDur), (this.viewName !== "full" || this.isAvatarOnly) && (t = this.mtRandomized[Math.floor(Math.random() * this.mtRandomized.length)], o = this.mtAvatar[t], o.needsUpdate || Object.assign(o, { base: (this.mood.baseline[t] || 0) + (1 + a / 255) * Math.random() / 5, needsUpdate: !0 })), this.updatePoseBase(this.animClock), this.mixer && this.mixer.update(e / 1e3 * this.mixer.timeScale), this.
|
|
5203
|
+
})))), e > 2 * this.animFrameDur && (e = 2 * this.animFrameDur), (this.viewName !== "full" || this.isAvatarOnly) && (t = this.mtRandomized[Math.floor(Math.random() * this.mtRandomized.length)], o = this.mtAvatar[t], o.needsUpdate || Object.assign(o, { base: (this.mood.baseline[t] || 0) + (1 + a / 255) * Math.random() / 5, needsUpdate: !0 })), this.updatePoseBase(this.animClock), this.mixer && (this.mixer.update(e / 1e3 * this.mixer.timeScale), this.currentFBXActionForCallback && this.currentFBXActionForCallback.isRunning() && this.currentFBXActionClipDuration)) {
|
|
5204
|
+
const r = this.currentFBXActionForCallback.time, h = this.currentFBXActionClipDuration;
|
|
5205
|
+
(r >= h - 0.05 || r > 0 && !this.currentFBXActionForCallback.paused && r >= h - 0.1) && (this.currentFBXActionCallback && (this.currentFBXActionCallback(), this.currentFBXActionCallback = null), this.currentFBXActionForCallback = null, this.currentFBXActionStartTime = null, this.currentFBXActionClipDuration = null);
|
|
5206
|
+
}
|
|
5207
|
+
if (this.updatePoseDelta(), (this.isSpeaking || this.isListening) && u ? a > this.volumeMax ? (this.volumeHeadBase = 0.05, Math.random() > 0.6 && (this.volumeHeadTarget = -0.05 - Math.random() / 15), this.volumeMax = a) : (this.volumeMax *= 0.92, this.volumeHeadTarget = this.volumeHeadBase - 0.9 * (this.volumeHeadBase - this.volumeHeadTarget)) : (this.volumeHeadTarget = 0, this.volumeMax = 0), t = this.volumeHeadTarget - this.volumeHeadCurrent, o = Math.abs(t), o > 1e-4 && (i = o * (this.volumeHeadEasing(Math.min(1, this.volumeHeadVelocity * e / 1e3 / o) / 2 + 0.5) - 0.5), this.volumeHeadCurrent += Math.sign(t) * Math.min(o, i)), Math.abs(this.volumeHeadCurrent) > 1e-4 && (ue.setFromAxisAngle(Bt, this.volumeHeadCurrent), this.objectNeck.quaternion.multiply(ue)), at.setFromObject(this.armature), this.objectLeftToeBase.getWorldPosition(Ue), Ue.sub(this.armature.position), this.objectRightToeBase.getWorldPosition(Xe), Xe.sub(this.armature.position), this.objectHips.position.y -= at.min.y / 2, this.objectHips.position.x -= (Ue.x + Xe.x) / 4, this.objectHips.position.z -= (Ue.z + Xe.z) / 2, this.dynamicbones.update(e), this.fbxAnimationLoader && this.fbxAnimationLoader.update(), this.opt.update && this.opt.update(e), this.updateMorphTargets(e), this.isAvatarOnly)
|
|
5204
5208
|
this.stats && this.stats.end();
|
|
5205
5209
|
else {
|
|
5206
5210
|
if (this.cameraClock !== null && this.cameraClock < 1e3) {
|
|
@@ -5267,24 +5271,24 @@ class nt {
|
|
|
5267
5271
|
*/
|
|
5268
5272
|
speakText(n, e = null, t = null, o = null) {
|
|
5269
5273
|
e = e || {};
|
|
5270
|
-
const s = /[!\.\?\n\p{Extended_Pictographic}]/ug, i = /[ ]/ug, a = /[\p{L}\p{N},\.\p{Quotation_Mark}!€\$\+\p{Dash_Punctuation}%&\?]/ug,
|
|
5271
|
-
let
|
|
5274
|
+
const s = /[!\.\?\n\p{Extended_Pictographic}]/ug, i = /[ ]/ug, a = /[\p{L}\p{N},\.\p{Quotation_Mark}!€\$\+\p{Dash_Punctuation}%&\?]/ug, u = /[\p{Extended_Pictographic}]/ug, l = e.lipsyncLang || this.avatar.lipsyncLang || this.opt.lipsyncLang;
|
|
5275
|
+
let c = "", r = "", h = 0, d = [], g = [];
|
|
5272
5276
|
const R = Array.from(this.segmenter.segment(n), (x) => x.segment);
|
|
5273
5277
|
for (let x = 0; x < R.length; x++) {
|
|
5274
|
-
const
|
|
5278
|
+
const k = x === R.length - 1, G = R[x].match(a);
|
|
5275
5279
|
let m = R[x].match(s);
|
|
5276
|
-
const D = R[x].match(
|
|
5277
|
-
if (m && !
|
|
5280
|
+
const D = R[x].match(u), E = R[x].match(i);
|
|
5281
|
+
if (m && !k && !D && R[x + 1].match(s) && (m = !1), t && (c += R[x]), G && (!o || o.every((y) => x < y[0] || x > y[1])) && (r += R[x]), (E || m || k) && (r.length && (r = this.lipsyncPreProcessText(r, l), r.length && d.push({
|
|
5278
5282
|
mark: h,
|
|
5279
5283
|
word: r
|
|
5280
|
-
})),
|
|
5284
|
+
})), c.length && (g.push({
|
|
5281
5285
|
mark: h,
|
|
5282
5286
|
template: { name: "subtitles" },
|
|
5283
5287
|
ts: [0],
|
|
5284
5288
|
vs: {
|
|
5285
|
-
subtitles: [
|
|
5289
|
+
subtitles: [c]
|
|
5286
5290
|
}
|
|
5287
|
-
}),
|
|
5291
|
+
}), c = ""), r.length)) {
|
|
5288
5292
|
const y = this.lipsyncWordsToVisemes(r, l);
|
|
5289
5293
|
if (y && y.visemes && y.visemes.length) {
|
|
5290
5294
|
const P = y.times[y.visemes.length - 1] + y.durations[y.visemes.length - 1];
|
|
@@ -5300,8 +5304,8 @@ class nt {
|
|
|
5300
5304
|
}
|
|
5301
5305
|
r = "", h++;
|
|
5302
5306
|
}
|
|
5303
|
-
if (m ||
|
|
5304
|
-
if (d.length ||
|
|
5307
|
+
if (m || k) {
|
|
5308
|
+
if (d.length || k && g.length) {
|
|
5305
5309
|
const y = {
|
|
5306
5310
|
anim: g
|
|
5307
5311
|
};
|
|
@@ -5390,25 +5394,25 @@ class nt {
|
|
|
5390
5394
|
if (n.words) {
|
|
5391
5395
|
let i = [];
|
|
5392
5396
|
for (let a = 0; a < n.words.length; a++) {
|
|
5393
|
-
const
|
|
5394
|
-
let
|
|
5395
|
-
if (
|
|
5397
|
+
const u = n.words[a], l = n.wtimes[a];
|
|
5398
|
+
let c = n.wdurations[a];
|
|
5399
|
+
if (u.length && (t && i.push({
|
|
5396
5400
|
template: { name: "subtitles" },
|
|
5397
5401
|
ts: [l],
|
|
5398
5402
|
vs: {
|
|
5399
|
-
subtitles: [" " +
|
|
5403
|
+
subtitles: [" " + u]
|
|
5400
5404
|
}
|
|
5401
5405
|
}), !n.visemes)) {
|
|
5402
|
-
const r = this.lipsyncPreProcessText(
|
|
5406
|
+
const r = this.lipsyncPreProcessText(u, o), h = this.lipsyncWordsToVisemes(r, o);
|
|
5403
5407
|
if (h && h.visemes && h.visemes.length) {
|
|
5404
|
-
const d = h.times[h.visemes.length - 1] + h.durations[h.visemes.length - 1], g = Math.min(
|
|
5405
|
-
let R = 0.6 + this.convertRange(g, [0,
|
|
5406
|
-
if (
|
|
5408
|
+
const d = h.times[h.visemes.length - 1] + h.durations[h.visemes.length - 1], g = Math.min(c, Math.max(0, c - h.visemes.length * 150));
|
|
5409
|
+
let R = 0.6 + this.convertRange(g, [0, c], [0, 0.4]);
|
|
5410
|
+
if (c = Math.min(c, h.visemes.length * 200), d > 0)
|
|
5407
5411
|
for (let x = 0; x < h.visemes.length; x++) {
|
|
5408
|
-
const
|
|
5412
|
+
const k = l + h.times[x] / d * c, G = h.durations[x] / d * c;
|
|
5409
5413
|
i.push({
|
|
5410
5414
|
template: { name: "viseme" },
|
|
5411
|
-
ts: [
|
|
5415
|
+
ts: [k - Math.min(60, 2 * G / 3), k + Math.min(25, G / 2), k + G + Math.min(60, G / 2)],
|
|
5412
5416
|
vs: {
|
|
5413
5417
|
["viseme_" + h.visemes[x]]: [null, h.visemes[x] === "PP" || h.visemes[x] === "FF" ? 0.9 : R, 0]
|
|
5414
5418
|
}
|
|
@@ -5419,22 +5423,22 @@ class nt {
|
|
|
5419
5423
|
}
|
|
5420
5424
|
if (n.visemes)
|
|
5421
5425
|
for (let a = 0; a < n.visemes.length; a++) {
|
|
5422
|
-
const
|
|
5426
|
+
const u = n.visemes[a], l = n.vtimes[a], c = n.vdurations[a];
|
|
5423
5427
|
i.push({
|
|
5424
5428
|
template: { name: "viseme" },
|
|
5425
|
-
ts: [l - 2 *
|
|
5429
|
+
ts: [l - 2 * c / 3, l + c / 2, l + c + c / 2],
|
|
5426
5430
|
vs: {
|
|
5427
|
-
["viseme_" +
|
|
5431
|
+
["viseme_" + u]: [null, u === "PP" || u === "FF" ? 0.9 : 0.6, 0]
|
|
5428
5432
|
}
|
|
5429
5433
|
});
|
|
5430
5434
|
}
|
|
5431
5435
|
if (n.markers)
|
|
5432
5436
|
for (let a = 0; a < n.markers.length; a++) {
|
|
5433
|
-
const
|
|
5437
|
+
const u = n.markers[a], l = n.mtimes[a];
|
|
5434
5438
|
i.push({
|
|
5435
5439
|
template: { name: "markers" },
|
|
5436
5440
|
ts: [l],
|
|
5437
|
-
vs: { function: [
|
|
5441
|
+
vs: { function: [u] }
|
|
5438
5442
|
});
|
|
5439
5443
|
}
|
|
5440
5444
|
i.length && (s.anim = i);
|
|
@@ -5460,7 +5464,7 @@ class nt {
|
|
|
5460
5464
|
delay: e.delay || 0
|
|
5461
5465
|
};
|
|
5462
5466
|
if (this.audioCtx.state === "suspended" || this.audioCtx.state === "interrupted") {
|
|
5463
|
-
const s = this.audioCtx.resume(), i = new Promise((a,
|
|
5467
|
+
const s = this.audioCtx.resume(), i = new Promise((a, u) => setTimeout(() => u("p2"), 1e3));
|
|
5464
5468
|
try {
|
|
5465
5469
|
await Promise.race([s, i]);
|
|
5466
5470
|
} catch {
|
|
@@ -5485,7 +5489,7 @@ class nt {
|
|
|
5485
5489
|
template: i.template,
|
|
5486
5490
|
// Trimmed timestamps are relative (ms), add base clock to make absolute
|
|
5487
5491
|
// This ensures lip-sync continues from the exact resume point
|
|
5488
|
-
ts: i.ts.map((
|
|
5492
|
+
ts: i.ts.map((u) => s + u),
|
|
5489
5493
|
vs: i.vs
|
|
5490
5494
|
};
|
|
5491
5495
|
this.animQueue.push(a);
|
|
@@ -5498,9 +5502,9 @@ class nt {
|
|
|
5498
5502
|
if (this.audioPlaylist.length) {
|
|
5499
5503
|
const t = this.audioPlaylist.shift();
|
|
5500
5504
|
if (this.audioCtx.state === "suspended" || this.audioCtx.state === "interrupted") {
|
|
5501
|
-
const a = this.audioCtx.resume(),
|
|
5505
|
+
const a = this.audioCtx.resume(), u = new Promise((l, c) => setTimeout(() => c("p2"), 1e3));
|
|
5502
5506
|
try {
|
|
5503
|
-
await Promise.race([a,
|
|
5507
|
+
await Promise.race([a, u]);
|
|
5504
5508
|
} catch {
|
|
5505
5509
|
console.log("Can't play audio. Web Audio API suspended. This is often due to calling some speak method before the first user action, which is typically prevented by the browser."), this.playAudio(!0);
|
|
5506
5510
|
return;
|
|
@@ -5525,8 +5529,8 @@ class nt {
|
|
|
5525
5529
|
this.audioStartTime = this.audioCtx.currentTime + i, this.audioSpeechSource.addEventListener("ended", () => {
|
|
5526
5530
|
this.audioSpeechSource.disconnect(), this.audioStartTime = null, this.currentAudioItem = null, this.isSpeaking = !0, this.playAudio(!0);
|
|
5527
5531
|
}, { once: !0 }), t.anim && t.anim.forEach((a) => {
|
|
5528
|
-
for (let
|
|
5529
|
-
a.ts[
|
|
5532
|
+
for (let u = 0; u < a.ts.length; u++)
|
|
5533
|
+
a.ts[u] = this.animClock + a.ts[u] + s;
|
|
5530
5534
|
this.animQueue.push(a);
|
|
5531
5535
|
}), this.audioSpeechSource.start(i);
|
|
5532
5536
|
} else
|
|
@@ -5539,29 +5543,29 @@ class nt {
|
|
|
5539
5543
|
*/
|
|
5540
5544
|
async synthesizeWithBrowserTTS(n) {
|
|
5541
5545
|
return new Promise((e, t) => {
|
|
5542
|
-
const o = Array.isArray(n.text) ? n.text.map((m) => m.word).join(" ") : typeof n.text == "string" ? n.text : "", s = new SpeechSynthesisUtterance(o), i = n.lang || this.avatar.ttsLang || this.opt.ttsLang || "en-US", a = (n.rate || this.avatar.ttsRate || this.opt.ttsRate || 1) + this.mood.speech.deltaRate,
|
|
5543
|
-
s.lang = i, s.rate = Math.max(0.1, Math.min(10, a)), s.pitch = Math.max(0, Math.min(2,
|
|
5544
|
-
const
|
|
5545
|
-
if (r &&
|
|
5546
|
-
const m =
|
|
5546
|
+
const o = Array.isArray(n.text) ? n.text.map((m) => m.word).join(" ") : typeof n.text == "string" ? n.text : "", s = new SpeechSynthesisUtterance(o), i = n.lang || this.avatar.ttsLang || this.opt.ttsLang || "en-US", a = (n.rate || this.avatar.ttsRate || this.opt.ttsRate || 1) + this.mood.speech.deltaRate, u = (n.pitch || this.avatar.ttsPitch || this.opt.ttsPitch || 1) + this.mood.speech.deltaPitch, l = (n.volume || this.avatar.ttsVolume || this.opt.ttsVolume || 1) + this.mood.speech.deltaVolume;
|
|
5547
|
+
s.lang = i, s.rate = Math.max(0.1, Math.min(10, a)), s.pitch = Math.max(0, Math.min(2, u)), s.volume = Math.max(0, Math.min(1, l));
|
|
5548
|
+
const c = speechSynthesis.getVoices(), r = n.voice || this.avatar.ttsVoice || this.opt.ttsVoice;
|
|
5549
|
+
if (r && c.length > 0) {
|
|
5550
|
+
const m = c.find((D) => D.name.includes(r) || D.lang === i);
|
|
5547
5551
|
m && (s.voice = m);
|
|
5548
5552
|
}
|
|
5549
|
-
const h = o.length * 100 / s.rate, d = this.audioCtx.createBuffer(1, this.audioCtx.sampleRate * (h / 1e3), this.audioCtx.sampleRate), g = this.avatar.lipsyncLang || this.opt.lipsyncLang || "en", R = this.lipsyncPreProcessText(o, g), x = this.lipsyncWordsToVisemes(R, g),
|
|
5553
|
+
const h = o.length * 100 / s.rate, d = this.audioCtx.createBuffer(1, this.audioCtx.sampleRate * (h / 1e3), this.audioCtx.sampleRate), g = this.avatar.lipsyncLang || this.opt.lipsyncLang || "en", R = this.lipsyncPreProcessText(o, g), x = this.lipsyncWordsToVisemes(R, g), k = [];
|
|
5550
5554
|
if (x && x.visemes && x.visemes.length > 0) {
|
|
5551
5555
|
const m = x.times[x.visemes.length - 1] + x.durations[x.visemes.length - 1];
|
|
5552
5556
|
for (let D = 0; D < x.visemes.length; D++) {
|
|
5553
|
-
const
|
|
5554
|
-
|
|
5557
|
+
const E = x.visemes[D], y = x.times[D] / m, P = x.durations[D] / m, L = y * h, f = P * h;
|
|
5558
|
+
k.push({
|
|
5555
5559
|
template: { name: "viseme" },
|
|
5556
5560
|
ts: [L - Math.min(60, 2 * f / 3), L + Math.min(25, f / 2), L + f + Math.min(60, f / 2)],
|
|
5557
5561
|
vs: {
|
|
5558
|
-
["viseme_" +
|
|
5562
|
+
["viseme_" + E]: [null, E === "PP" || E === "FF" ? 0.9 : 0.6, 0]
|
|
5559
5563
|
}
|
|
5560
5564
|
});
|
|
5561
5565
|
}
|
|
5562
5566
|
}
|
|
5563
|
-
const
|
|
5564
|
-
this.audioPlaylist.push({ anim:
|
|
5567
|
+
const G = [...n.anim, ...k];
|
|
5568
|
+
this.audioPlaylist.push({ anim: G, audio: d }), this.onSubtitles = n.onSubtitles || null, this.resetLips(), n.mood && this.setMood(n.mood), this.playAudio(), s.onend = () => {
|
|
5565
5569
|
e();
|
|
5566
5570
|
}, s.onerror = (m) => {
|
|
5567
5571
|
console.error("Speech synthesis error:", m.error), t(m.error);
|
|
@@ -5593,15 +5597,15 @@ class nt {
|
|
|
5593
5597
|
});
|
|
5594
5598
|
if (!s.ok)
|
|
5595
5599
|
throw new Error(`ElevenLabs TTS error: ${s.status} ${s.statusText}`);
|
|
5596
|
-
const i = await s.arrayBuffer(), a = await this.audioCtx.decodeAudioData(i),
|
|
5600
|
+
const i = await s.arrayBuffer(), a = await this.audioCtx.decodeAudioData(i), u = this.avatar.lipsyncLang || this.opt.lipsyncLang || "en";
|
|
5597
5601
|
let l;
|
|
5598
5602
|
try {
|
|
5599
5603
|
console.log("Lip-sync modules available:", {
|
|
5600
5604
|
hasLipsync: !!this.lipsync,
|
|
5601
5605
|
lipsyncKeys: this.lipsync ? Object.keys(this.lipsync) : [],
|
|
5602
|
-
lipsyncLang:
|
|
5606
|
+
lipsyncLang: u
|
|
5603
5607
|
});
|
|
5604
|
-
const h = this.lipsyncPreProcessText(e,
|
|
5608
|
+
const h = this.lipsyncPreProcessText(e, u), d = this.lipsyncWordsToVisemes(h, u);
|
|
5605
5609
|
if (console.log("Lip-sync data:", {
|
|
5606
5610
|
processedText: h,
|
|
5607
5611
|
lipsyncData: d,
|
|
@@ -5626,8 +5630,8 @@ class nt {
|
|
|
5626
5630
|
const d = e.toLowerCase().split(/\s+/), g = [];
|
|
5627
5631
|
for (const R of d)
|
|
5628
5632
|
for (const x of R) {
|
|
5629
|
-
let
|
|
5630
|
-
"aeiou".includes(x) ?
|
|
5633
|
+
let k = "aa";
|
|
5634
|
+
"aeiou".includes(x) ? k = "aa" : "bp".includes(x) ? k = "PP" : "fv".includes(x) ? k = "FF" : "st".includes(x) ? k = "SS" : "dln".includes(x) ? k = "DD" : "kg".includes(x) ? k = "kk" : "rw".includes(x) && (k = "RR"), g.push(k);
|
|
5631
5635
|
}
|
|
5632
5636
|
l = {
|
|
5633
5637
|
visemes: g.map((R, x) => ({
|
|
@@ -5642,11 +5646,11 @@ class nt {
|
|
|
5642
5646
|
features: { onsets: [], boundaries: [] }
|
|
5643
5647
|
};
|
|
5644
5648
|
}
|
|
5645
|
-
const
|
|
5649
|
+
const c = [];
|
|
5646
5650
|
if (l.visemes && l.visemes.length > 0)
|
|
5647
5651
|
for (let h = 0; h < l.visemes.length; h++) {
|
|
5648
5652
|
const d = l.visemes[h], g = d.startTime * 1e3, R = d.duration * 1e3, x = d.intensity;
|
|
5649
|
-
|
|
5653
|
+
c.push({
|
|
5650
5654
|
template: { name: "viseme" },
|
|
5651
5655
|
ts: [g - Math.min(60, 2 * R / 3), g + Math.min(25, R / 2), g + R + Math.min(60, R / 2)],
|
|
5652
5656
|
vs: {
|
|
@@ -5656,7 +5660,7 @@ class nt {
|
|
|
5656
5660
|
}
|
|
5657
5661
|
else
|
|
5658
5662
|
console.warn("ElevenLabs: No visemes available for lip-sync animation");
|
|
5659
|
-
const r = [...n.anim, ...
|
|
5663
|
+
const r = [...n.anim, ...c];
|
|
5660
5664
|
this.audioPlaylist.push({ anim: r, audio: a }), this.onSubtitles = n.onSubtitles || null, this.resetLips(), n.mood && this.setMood(n.mood), this.playAudio();
|
|
5661
5665
|
}
|
|
5662
5666
|
/**
|
|
@@ -5675,15 +5679,15 @@ class nt {
|
|
|
5675
5679
|
});
|
|
5676
5680
|
if (!s.ok)
|
|
5677
5681
|
throw new Error(`Deepgram TTS error: ${s.status} ${s.statusText}`);
|
|
5678
|
-
const i = await s.arrayBuffer(), a = await this.audioCtx.decodeAudioData(i),
|
|
5682
|
+
const i = await s.arrayBuffer(), a = await this.audioCtx.decodeAudioData(i), u = this.avatar.lipsyncLang || this.opt.lipsyncLang || "en";
|
|
5679
5683
|
let l;
|
|
5680
5684
|
try {
|
|
5681
5685
|
console.log("Lip-sync modules available:", {
|
|
5682
5686
|
hasLipsync: !!this.lipsync,
|
|
5683
5687
|
lipsyncKeys: this.lipsync ? Object.keys(this.lipsync) : [],
|
|
5684
|
-
lipsyncLang:
|
|
5688
|
+
lipsyncLang: u
|
|
5685
5689
|
});
|
|
5686
|
-
const h = this.lipsyncPreProcessText(e,
|
|
5690
|
+
const h = this.lipsyncPreProcessText(e, u), d = this.lipsyncWordsToVisemes(h, u);
|
|
5687
5691
|
if (console.log("Lip-sync data:", {
|
|
5688
5692
|
processedText: h,
|
|
5689
5693
|
lipsyncData: d,
|
|
@@ -5708,8 +5712,8 @@ class nt {
|
|
|
5708
5712
|
const d = e.toLowerCase().split(/\s+/), g = [];
|
|
5709
5713
|
for (const R of d)
|
|
5710
5714
|
for (const x of R) {
|
|
5711
|
-
let
|
|
5712
|
-
"aeiou".includes(x) ?
|
|
5715
|
+
let k = "aa";
|
|
5716
|
+
"aeiou".includes(x) ? k = "aa" : "bp".includes(x) ? k = "PP" : "fv".includes(x) ? k = "FF" : "st".includes(x) ? k = "SS" : "dln".includes(x) ? k = "DD" : "kg".includes(x) ? k = "kk" : "rw".includes(x) && (k = "RR"), g.push(k);
|
|
5713
5717
|
}
|
|
5714
5718
|
l = {
|
|
5715
5719
|
visemes: g.map((R, x) => ({
|
|
@@ -5724,11 +5728,11 @@ class nt {
|
|
|
5724
5728
|
features: { onsets: [], boundaries: [] }
|
|
5725
5729
|
};
|
|
5726
5730
|
}
|
|
5727
|
-
const
|
|
5731
|
+
const c = [];
|
|
5728
5732
|
if (l.visemes && l.visemes.length > 0)
|
|
5729
5733
|
for (let h = 0; h < l.visemes.length; h++) {
|
|
5730
5734
|
const d = l.visemes[h], g = d.startTime * 1e3, R = d.duration * 1e3, x = d.intensity;
|
|
5731
|
-
|
|
5735
|
+
c.push({
|
|
5732
5736
|
template: { name: "viseme" },
|
|
5733
5737
|
ts: [g - Math.min(60, 2 * R / 3), g + Math.min(25, R / 2), g + R + Math.min(60, R / 2)],
|
|
5734
5738
|
vs: {
|
|
@@ -5738,7 +5742,7 @@ class nt {
|
|
|
5738
5742
|
}
|
|
5739
5743
|
else
|
|
5740
5744
|
console.warn("Deepgram: No visemes available for lip-sync animation");
|
|
5741
|
-
const r = [...n.anim, ...
|
|
5745
|
+
const r = [...n.anim, ...c];
|
|
5742
5746
|
this.audioPlaylist.push({ anim: r, audio: a }), this.onSubtitles = n.onSubtitles || null, this.resetLips(), n.mood && this.setMood(n.mood), this.playAudio();
|
|
5743
5747
|
}
|
|
5744
5748
|
/**
|
|
@@ -5763,9 +5767,9 @@ class nt {
|
|
|
5763
5767
|
});
|
|
5764
5768
|
if (!s.ok)
|
|
5765
5769
|
throw new Error(`Azure TTS error: ${s.status} ${s.statusText}`);
|
|
5766
|
-
const i = await s.arrayBuffer(), a = await this.audioCtx.decodeAudioData(i),
|
|
5767
|
-
for (let r = 0; r <
|
|
5768
|
-
const h =
|
|
5770
|
+
const i = await s.arrayBuffer(), a = await this.audioCtx.decodeAudioData(i), u = await this.audioAnalyzer.analyzeAudio(a, e), l = [];
|
|
5771
|
+
for (let r = 0; r < u.visemes.length; r++) {
|
|
5772
|
+
const h = u.visemes[r], d = h.startTime * 1e3, g = h.duration * 1e3, R = h.intensity;
|
|
5769
5773
|
l.push({
|
|
5770
5774
|
template: { name: "viseme" },
|
|
5771
5775
|
ts: [d - Math.min(60, 2 * g / 3), d + Math.min(25, g / 2), d + g + Math.min(60, g / 2)],
|
|
@@ -5774,8 +5778,8 @@ class nt {
|
|
|
5774
5778
|
}
|
|
5775
5779
|
});
|
|
5776
5780
|
}
|
|
5777
|
-
const
|
|
5778
|
-
this.audioPlaylist.push({ anim:
|
|
5781
|
+
const c = [...n.anim, ...l];
|
|
5782
|
+
this.audioPlaylist.push({ anim: c, audio: a }), this.onSubtitles = n.onSubtitles || null, this.resetLips(), n.mood && this.setMood(n.mood), this.playAudio();
|
|
5779
5783
|
}
|
|
5780
5784
|
/**
|
|
5781
5785
|
* Synthesize speech using external TTS service (Google Cloud, etc.)
|
|
@@ -5814,24 +5818,24 @@ class nt {
|
|
|
5814
5818
|
if (o.status === 200 && s && s.audioContent) {
|
|
5815
5819
|
const i = this.b64ToArrayBuffer(s.audioContent), a = await this.audioCtx.decodeAudioData(i);
|
|
5816
5820
|
this.speakWithHands();
|
|
5817
|
-
const
|
|
5821
|
+
const u = [0];
|
|
5818
5822
|
let l = 0;
|
|
5819
5823
|
n.text.forEach((h, d) => {
|
|
5820
5824
|
if (d > 0) {
|
|
5821
|
-
let g =
|
|
5822
|
-
s.timepoints[l] && (g = s.timepoints[l].timeSeconds * 1e3, s.timepoints[l].markName === "" + h.mark && l++),
|
|
5825
|
+
let g = u[u.length - 1];
|
|
5826
|
+
s.timepoints[l] && (g = s.timepoints[l].timeSeconds * 1e3, s.timepoints[l].markName === "" + h.mark && l++), u.push(g);
|
|
5823
5827
|
}
|
|
5824
5828
|
});
|
|
5825
|
-
const
|
|
5826
|
-
|
|
5829
|
+
const c = [{ mark: 0, time: 0 }];
|
|
5830
|
+
u.forEach((h, d) => {
|
|
5827
5831
|
if (d > 0) {
|
|
5828
|
-
let g = h -
|
|
5829
|
-
|
|
5832
|
+
let g = h - u[d - 1];
|
|
5833
|
+
c[d - 1].duration = g, c.push({ mark: d, time: h });
|
|
5830
5834
|
}
|
|
5831
5835
|
});
|
|
5832
5836
|
let r = 1e3 * a.duration;
|
|
5833
|
-
r > this.opt.ttsTrimEnd && (r = r - this.opt.ttsTrimEnd),
|
|
5834
|
-
const d =
|
|
5837
|
+
r > this.opt.ttsTrimEnd && (r = r - this.opt.ttsTrimEnd), c[c.length - 1].duration = r - c[c.length - 1].time, n.anim.forEach((h) => {
|
|
5838
|
+
const d = c[h.mark];
|
|
5835
5839
|
if (d)
|
|
5836
5840
|
for (let g = 0; g < h.ts.length; g++)
|
|
5837
5841
|
h.ts[g] = d.time + h.ts[g] * d.duration + this.opt.ttsTrimStart;
|
|
@@ -5879,17 +5883,17 @@ class nt {
|
|
|
5879
5883
|
let n = null;
|
|
5880
5884
|
if (this.audioSpeechSource && this.currentAudioItem && this.audioStartTime !== null)
|
|
5881
5885
|
try {
|
|
5882
|
-
const e = this.audioCtx.currentTime, t = Math.max(0, e - this.audioStartTime), o = this.audioSpeechSource.playbackRate.value, s = t * o, i = this.currentAudioItem.audio, a = i.sampleRate,
|
|
5883
|
-
if (
|
|
5884
|
-
const l = i.length -
|
|
5886
|
+
const e = this.audioCtx.currentTime, t = Math.max(0, e - this.audioStartTime), o = this.audioSpeechSource.playbackRate.value, s = t * o, i = this.currentAudioItem.audio, a = i.sampleRate, u = Math.floor(s * a);
|
|
5887
|
+
if (u < i.length) {
|
|
5888
|
+
const l = i.length - u, c = this.audioCtx.createBuffer(
|
|
5885
5889
|
i.numberOfChannels,
|
|
5886
5890
|
l,
|
|
5887
5891
|
a
|
|
5888
5892
|
);
|
|
5889
5893
|
for (let h = 0; h < i.numberOfChannels; h++) {
|
|
5890
|
-
const d = i.getChannelData(h), g =
|
|
5894
|
+
const d = i.getChannelData(h), g = c.getChannelData(h);
|
|
5891
5895
|
for (let R = 0; R < l; R++)
|
|
5892
|
-
g[R] = d[
|
|
5896
|
+
g[R] = d[u + R];
|
|
5893
5897
|
}
|
|
5894
5898
|
let r = null;
|
|
5895
5899
|
if (this.currentAudioItem.anim) {
|
|
@@ -5900,18 +5904,18 @@ class nt {
|
|
|
5900
5904
|
ts: [],
|
|
5901
5905
|
vs: []
|
|
5902
5906
|
};
|
|
5903
|
-
for (let
|
|
5904
|
-
const
|
|
5905
|
-
if (
|
|
5906
|
-
const m =
|
|
5907
|
-
x.ts.push(m), x.vs.push(R.vs[
|
|
5907
|
+
for (let k = 0; k < R.ts.length; k++) {
|
|
5908
|
+
const G = R.ts[k];
|
|
5909
|
+
if (G > g) {
|
|
5910
|
+
const m = G - g;
|
|
5911
|
+
x.ts.push(m), x.vs.push(R.vs[k]);
|
|
5908
5912
|
}
|
|
5909
5913
|
}
|
|
5910
5914
|
return x.ts.length > 0 ? x : null;
|
|
5911
5915
|
}).filter((R) => R !== null);
|
|
5912
5916
|
}
|
|
5913
5917
|
n = {
|
|
5914
|
-
audio:
|
|
5918
|
+
audio: c,
|
|
5915
5919
|
anim: r,
|
|
5916
5920
|
text: this.currentAudioItem.text,
|
|
5917
5921
|
delay: 0,
|
|
@@ -5963,10 +5967,10 @@ class nt {
|
|
|
5963
5967
|
}
|
|
5964
5968
|
if (!this.workletLoaded)
|
|
5965
5969
|
try {
|
|
5966
|
-
const a = this.audioCtx.audioWorklet.addModule(Pt.href),
|
|
5967
|
-
(l,
|
|
5970
|
+
const a = this.audioCtx.audioWorklet.addModule(Pt.href), u = new Promise(
|
|
5971
|
+
(l, c) => setTimeout(() => c(new Error("Worklet loading timed out")), 5e3)
|
|
5968
5972
|
);
|
|
5969
|
-
await Promise.race([a,
|
|
5973
|
+
await Promise.race([a, u]), this.workletLoaded = !0;
|
|
5970
5974
|
} catch (a) {
|
|
5971
5975
|
throw console.error("Failed to load audio worklet:", a), new Error("Failed to initialize streaming speech");
|
|
5972
5976
|
}
|
|
@@ -5979,8 +5983,8 @@ class nt {
|
|
|
5979
5983
|
if (a.data.type === "playback-started" && (this.isSpeaking = !0, this.stateName = "speaking", this.streamWaitForAudioChunks && (this.streamAudioStartTime = this.animClock), this._processStreamLipsyncQueue(), this.speakWithHands(), this.onAudioStart))
|
|
5980
5984
|
try {
|
|
5981
5985
|
this.onAudioStart?.();
|
|
5982
|
-
} catch (
|
|
5983
|
-
console.error(
|
|
5986
|
+
} catch (u) {
|
|
5987
|
+
console.error(u);
|
|
5984
5988
|
}
|
|
5985
5989
|
if (a.data.type === "playback-ended" && (this._streamPause(), this.onAudioEnd))
|
|
5986
5990
|
try {
|
|
@@ -6000,9 +6004,9 @@ class nt {
|
|
|
6000
6004
|
} catch {
|
|
6001
6005
|
}
|
|
6002
6006
|
if (this.resetLips(), this.lookAtCamera(500), n.mood && this.setMood(n.mood), this.onSubtitles = o || null, this.audioCtx.state === "suspended" || this.audioCtx.state === "interrupted") {
|
|
6003
|
-
const a = this.audioCtx.resume(),
|
|
6007
|
+
const a = this.audioCtx.resume(), u = new Promise((l, c) => setTimeout(() => c("p2"), 1e3));
|
|
6004
6008
|
try {
|
|
6005
|
-
await Promise.race([a,
|
|
6009
|
+
await Promise.race([a, u]);
|
|
6006
6010
|
} catch {
|
|
6007
6011
|
console.warn("Can't play audio. Web Audio API suspended. This is often due to calling some speak method before the first user action, which is typically prevented by the browser.");
|
|
6008
6012
|
return;
|
|
@@ -6099,13 +6103,13 @@ class nt {
|
|
|
6099
6103
|
subtitles: [" " + o]
|
|
6100
6104
|
}
|
|
6101
6105
|
}), this.streamLipsyncType == "words")) {
|
|
6102
|
-
const a = this.streamLipsyncLang || this.avatar.lipsyncLang || this.opt.lipsyncLang,
|
|
6106
|
+
const a = this.streamLipsyncLang || this.avatar.lipsyncLang || this.opt.lipsyncLang, u = this.lipsyncPreProcessText(o, a), l = this.lipsyncWordsToVisemes(u, a);
|
|
6103
6107
|
if (l && l.visemes && l.visemes.length) {
|
|
6104
|
-
const
|
|
6108
|
+
const c = l.times[l.visemes.length - 1] + l.durations[l.visemes.length - 1], r = Math.min(i, Math.max(0, i - l.visemes.length * 150));
|
|
6105
6109
|
let h = 0.6 + this.convertRange(r, [0, i], [0, 0.4]);
|
|
6106
|
-
if (i = Math.min(i, l.visemes.length * 200),
|
|
6110
|
+
if (i = Math.min(i, l.visemes.length * 200), c > 0)
|
|
6107
6111
|
for (let d = 0; d < l.visemes.length; d++) {
|
|
6108
|
-
const g = e + s + l.times[d] /
|
|
6112
|
+
const g = e + s + l.times[d] / c * i, R = l.durations[d] / c * i;
|
|
6109
6113
|
this.animQueue.push({
|
|
6110
6114
|
template: { name: "viseme" },
|
|
6111
6115
|
ts: [g - Math.min(60, 2 * R / 3), g + Math.min(25, R / 2), g + R + Math.min(60, R / 2)],
|
|
@@ -6201,7 +6205,7 @@ class nt {
|
|
|
6201
6205
|
*/
|
|
6202
6206
|
lookAtCamera(n) {
|
|
6203
6207
|
let e;
|
|
6204
|
-
if (this.speakTo && (e = new b.Vector3(), this.speakTo.objectLeftEye?.isObject3D ? (this.speakTo.armature.objectHead, this.speakTo.objectLeftEye.updateMatrixWorld(!0), this.speakTo.objectRightEye.updateMatrixWorld(!0), Ue.setFromMatrixPosition(this.speakTo.objectLeftEye.matrixWorld),
|
|
6208
|
+
if (this.speakTo && (e = new b.Vector3(), this.speakTo.objectLeftEye?.isObject3D ? (this.speakTo.armature.objectHead, this.speakTo.objectLeftEye.updateMatrixWorld(!0), this.speakTo.objectRightEye.updateMatrixWorld(!0), Ue.setFromMatrixPosition(this.speakTo.objectLeftEye.matrixWorld), Xe.setFromMatrixPosition(this.speakTo.objectRightEye.matrixWorld), e.addVectors(Ue, Xe).divideScalar(2)) : this.speakTo.isObject3D ? this.speakTo.getWorldPosition(e) : this.speakTo.isVector3 ? e.set(this.speakTo) : this.speakTo.x && this.speakTo.y && this.speakTo.z && e.set(this.speakTo.x, this.speakTo.y, this.speakTo.z)), !e) {
|
|
6205
6209
|
if (this.avatar.hasOwnProperty("avatarIgnoreCamera")) {
|
|
6206
6210
|
if (this.avatar.avatarIgnoreCamera) {
|
|
6207
6211
|
this.lookAhead(n);
|
|
@@ -6214,14 +6218,14 @@ class nt {
|
|
|
6214
6218
|
this.lookAt(null, null, n);
|
|
6215
6219
|
return;
|
|
6216
6220
|
}
|
|
6217
|
-
this.objectLeftEye.updateMatrixWorld(!0), this.objectRightEye.updateMatrixWorld(!0), Ue.setFromMatrixPosition(this.objectLeftEye.matrixWorld),
|
|
6221
|
+
this.objectLeftEye.updateMatrixWorld(!0), this.objectRightEye.updateMatrixWorld(!0), Ue.setFromMatrixPosition(this.objectLeftEye.matrixWorld), Xe.setFromMatrixPosition(this.objectRightEye.matrixWorld), Ue.add(Xe).divideScalar(2), ue.copy(this.armature.quaternion), ue.multiply(this.poseTarget.props["Hips.quaternion"]), ue.multiply(this.poseTarget.props["Spine.quaternion"]), ue.multiply(this.poseTarget.props["Spine1.quaternion"]), ue.multiply(this.poseTarget.props["Spine2.quaternion"]), ue.multiply(this.poseTarget.props["Neck.quaternion"]), ue.multiply(this.poseTarget.props["Head.quaternion"]);
|
|
6218
6222
|
const t = new b.Vector3().subVectors(e, Ue).normalize(), o = Math.atan2(t.x, t.z), s = Math.asin(-t.y);
|
|
6219
6223
|
oe.set(s, o, 0, "YXZ");
|
|
6220
|
-
const a = new b.Quaternion().setFromEuler(oe),
|
|
6221
|
-
oe.setFromQuaternion(
|
|
6222
|
-
let l = oe.x / (40 / 24) + 0.2,
|
|
6224
|
+
const a = new b.Quaternion().setFromEuler(oe), u = new b.Quaternion().copy(a).multiply(ue.clone().invert());
|
|
6225
|
+
oe.setFromQuaternion(u, "YXZ");
|
|
6226
|
+
let l = oe.x / (40 / 24) + 0.2, c = oe.y / (9 / 4), r = Math.min(0.6, Math.max(-0.3, l)), h = Math.min(0.8, Math.max(-0.8, c)), d = (Math.random() - 0.5) / 4, g = (Math.random() - 0.5) / 4;
|
|
6223
6227
|
if (n) {
|
|
6224
|
-
let R = this.animQueue.findIndex((
|
|
6228
|
+
let R = this.animQueue.findIndex((k) => k.template.name === "lookat");
|
|
6225
6229
|
R !== -1 && this.animQueue.splice(R, 1);
|
|
6226
6230
|
const x = {
|
|
6227
6231
|
name: "lookat",
|
|
@@ -6253,21 +6257,21 @@ class nt {
|
|
|
6253
6257
|
this.objectLeftEye.updateMatrixWorld(!0), this.objectRightEye.updateMatrixWorld(!0);
|
|
6254
6258
|
const s = new b.Vector3().setFromMatrixPosition(this.objectLeftEye.matrixWorld), i = new b.Vector3().setFromMatrixPosition(this.objectRightEye.matrixWorld), a = new b.Vector3().addVectors(s, i).divideScalar(2);
|
|
6255
6259
|
a.project(this.camera);
|
|
6256
|
-
let
|
|
6257
|
-
n === null && (n =
|
|
6258
|
-
let
|
|
6259
|
-
x = Math.min(0.6, Math.max(-0.3, x)),
|
|
6260
|
-
let
|
|
6260
|
+
let u = (a.x + 1) / 2 * o.width + o.left, l = -(a.y - 1) / 2 * o.height + o.top;
|
|
6261
|
+
n === null && (n = u), e === null && (e = l), ue.copy(this.armature.quaternion), ue.multiply(this.poseTarget.props["Hips.quaternion"]), ue.multiply(this.poseTarget.props["Spine.quaternion"]), ue.multiply(this.poseTarget.props["Spine1.quaternion"]), ue.multiply(this.poseTarget.props["Spine2.quaternion"]), ue.multiply(this.poseTarget.props["Neck.quaternion"]), ue.multiply(this.poseTarget.props["Head.quaternion"]), oe.setFromQuaternion(ue);
|
|
6262
|
+
let c = oe.x / (40 / 24), r = oe.y / (9 / 4), h = 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), R = Math.max(window.innerHeight - l, l), x = this.convertRange(e, [l - R, l + R], [-0.3, 0.6]) - c + h, k = this.convertRange(n, [u - g, u + g], [-0.8, 0.8]) - r + d;
|
|
6263
|
+
x = Math.min(0.6, Math.max(-0.3, x)), k = Math.min(0.8, Math.max(-0.8, k));
|
|
6264
|
+
let G = (Math.random() - 0.5) / 4, m = (Math.random() - 0.5) / 4;
|
|
6261
6265
|
if (t) {
|
|
6262
6266
|
let D = this.animQueue.findIndex((y) => y.template.name === "lookat");
|
|
6263
6267
|
D !== -1 && this.animQueue.splice(D, 1);
|
|
6264
|
-
const
|
|
6268
|
+
const E = {
|
|
6265
6269
|
name: "lookat",
|
|
6266
6270
|
dt: [750, t],
|
|
6267
6271
|
vs: {
|
|
6268
|
-
bodyRotateX: [x +
|
|
6269
|
-
bodyRotateY: [
|
|
6270
|
-
eyesRotateX: [-3 *
|
|
6272
|
+
bodyRotateX: [x + G],
|
|
6273
|
+
bodyRotateY: [k + m],
|
|
6274
|
+
eyesRotateX: [-3 * G + 0.1],
|
|
6271
6275
|
eyesRotateY: [-5 * m],
|
|
6272
6276
|
browInnerUp: [[0, 0.7]],
|
|
6273
6277
|
mouthLeft: [[0, 0.7]],
|
|
@@ -6276,7 +6280,7 @@ class nt {
|
|
|
6276
6280
|
headMove: [0]
|
|
6277
6281
|
}
|
|
6278
6282
|
};
|
|
6279
|
-
this.animQueue.push(this.animFactory(
|
|
6283
|
+
this.animQueue.push(this.animFactory(E));
|
|
6280
6284
|
}
|
|
6281
6285
|
}
|
|
6282
6286
|
/**
|
|
@@ -6294,10 +6298,10 @@ class nt {
|
|
|
6294
6298
|
s.setFromCamera(o, this.camera);
|
|
6295
6299
|
const i = s.intersectObject(this.armature);
|
|
6296
6300
|
if (i.length > 0) {
|
|
6297
|
-
const a = i[0].point,
|
|
6298
|
-
this.objectLeftArm.getWorldPosition(
|
|
6299
|
-
const
|
|
6300
|
-
|
|
6301
|
+
const a = i[0].point, u = new b.Vector3(), l = new b.Vector3();
|
|
6302
|
+
this.objectLeftArm.getWorldPosition(u), this.objectRightArm.getWorldPosition(l);
|
|
6303
|
+
const c = u.distanceToSquared(a), r = l.distanceToSquared(a);
|
|
6304
|
+
c < r ? (this.ikSolve({
|
|
6301
6305
|
iterations: 20,
|
|
6302
6306
|
root: "LeftShoulder",
|
|
6303
6307
|
effector: "LeftHandMiddle1",
|
|
@@ -6318,8 +6322,8 @@ class nt {
|
|
|
6318
6322
|
}, a, !1, 1e3), this.setValue("handFistRight", 0));
|
|
6319
6323
|
} else
|
|
6320
6324
|
["LeftArm", "LeftForeArm", "LeftHand", "RightArm", "RightForeArm", "RightHand"].forEach((a) => {
|
|
6321
|
-
let
|
|
6322
|
-
this.poseTarget.props[
|
|
6325
|
+
let u = a + ".quaternion";
|
|
6326
|
+
this.poseTarget.props[u].copy(this.getPoseTemplateProp(u)), this.poseTarget.props[u].t = this.animClock, this.poseTarget.props[u].d = 1e3;
|
|
6323
6327
|
});
|
|
6324
6328
|
return i.length > 0;
|
|
6325
6329
|
}
|
|
@@ -6438,26 +6442,24 @@ class nt {
|
|
|
6438
6442
|
async playAnimation(n, e = null, t = 10, o = 0, s = 0.01, i = !1, a = null) {
|
|
6439
6443
|
if (!this.armature) return;
|
|
6440
6444
|
this.positionWasLocked = !i, i || this.lockAvatarPosition();
|
|
6441
|
-
let
|
|
6442
|
-
if (
|
|
6445
|
+
let u = this.animClips.find((l) => l.url === n + "-" + o);
|
|
6446
|
+
if (u) {
|
|
6443
6447
|
let l = this.animQueue.find((h) => h.template.name === "pose");
|
|
6444
|
-
l && (l.ts[0] = 1 / 0), Object.entries(
|
|
6448
|
+
l && (l.ts[0] = 1 / 0), Object.entries(u.pose.props).forEach((h) => {
|
|
6445
6449
|
this.poseBase.props[h[0]] = h[1].clone(), this.poseTarget.props[h[0]] = h[1].clone(), this.poseTarget.props[h[0]].t = 0, this.poseTarget.props[h[0]].d = 1e3;
|
|
6446
6450
|
}), this.mixer || (this.mixer = new b.AnimationMixer(this.armature)), this.animationFinishedCallback = a;
|
|
6447
|
-
const
|
|
6451
|
+
const c = () => {
|
|
6448
6452
|
this.animationFinishedCallback && (this.animationFinishedCallback(), this.animationFinishedCallback = null), this.stopAnimation();
|
|
6449
|
-
};
|
|
6450
|
-
this.mixer.addEventListener("finished", u, { once: !0 });
|
|
6451
|
-
const r = this.mixer.clipAction(c.clip);
|
|
6453
|
+
}, r = this.mixer.clipAction(u.clip);
|
|
6452
6454
|
if (t <= 0)
|
|
6453
6455
|
r.setLoop(b.LoopOnce, 1);
|
|
6454
6456
|
else {
|
|
6455
|
-
const h = Math.ceil(t /
|
|
6457
|
+
const h = Math.ceil(t / u.clip.duration);
|
|
6456
6458
|
r.setLoop(b.LoopRepeat, h);
|
|
6457
6459
|
}
|
|
6458
|
-
if (r.clampWhenFinished = !0, this.currentFBXAction && this.currentFBXAction.isRunning()) {
|
|
6460
|
+
if (r.clampWhenFinished = !0, this.mixer.addEventListener("finished", c, { once: !0 }), this.currentFBXActionForCallback = r, this.currentFBXActionCallback = c, this.currentFBXActionClipDuration = u.clip.duration, this.currentFBXActionStartTime = null, this.currentFBXAction && this.currentFBXAction.isRunning()) {
|
|
6459
6461
|
this.currentFBXAction.fadeOut(0.3), setTimeout(() => {
|
|
6460
|
-
this.currentFBXAction = r;
|
|
6462
|
+
this.currentFBXAction = r, this.currentFBXActionForCallback = r, this.currentFBXActionCallback = c, this.currentFBXActionClipDuration = u.clip.duration, this.currentFBXActionStartTime = this.mixer.time;
|
|
6461
6463
|
try {
|
|
6462
6464
|
r.fadeIn(0.5).play(), console.log("FBX animation started successfully (with fade transition):", n);
|
|
6463
6465
|
} catch (h) {
|
|
@@ -6466,7 +6468,7 @@ class nt {
|
|
|
6466
6468
|
}, 300);
|
|
6467
6469
|
return;
|
|
6468
6470
|
}
|
|
6469
|
-
this.currentFBXAction = r;
|
|
6471
|
+
this.currentFBXAction = r, this.currentFBXActionStartTime = this.mixer.time;
|
|
6470
6472
|
try {
|
|
6471
6473
|
r.fadeIn(0.5).play(), console.log("FBX animation started successfully:", n);
|
|
6472
6474
|
} catch (h) {
|
|
@@ -6482,10 +6484,10 @@ class nt {
|
|
|
6482
6484
|
console.error(`Invalid file type for FBX animation: ${n}. Expected .fbx file.`);
|
|
6483
6485
|
return;
|
|
6484
6486
|
}
|
|
6485
|
-
let
|
|
6487
|
+
let c = !1;
|
|
6486
6488
|
try {
|
|
6487
6489
|
const d = await fetch(n, { method: "HEAD" });
|
|
6488
|
-
if (
|
|
6490
|
+
if (c = d.ok, !c) {
|
|
6489
6491
|
console.error(`FBX file not found at ${n}. Status: ${d.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)");
|
|
6490
6492
|
return;
|
|
6491
6493
|
}
|
|
@@ -6591,38 +6593,38 @@ class nt {
|
|
|
6591
6593
|
root: "Hips"
|
|
6592
6594
|
};
|
|
6593
6595
|
if (f[P]) {
|
|
6594
|
-
const
|
|
6595
|
-
if (g.has(
|
|
6596
|
-
return
|
|
6596
|
+
const M = f[P];
|
|
6597
|
+
if (g.has(M))
|
|
6598
|
+
return M;
|
|
6597
6599
|
}
|
|
6598
|
-
for (const
|
|
6599
|
-
if (
|
|
6600
|
-
return
|
|
6601
|
-
for (const
|
|
6602
|
-
const
|
|
6603
|
-
if ((L.includes("left") &&
|
|
6604
|
-
return
|
|
6600
|
+
for (const M of g)
|
|
6601
|
+
if (M.toLowerCase() === L)
|
|
6602
|
+
return M;
|
|
6603
|
+
for (const M of g) {
|
|
6604
|
+
const I = M.toLowerCase();
|
|
6605
|
+
if ((L.includes("left") && I.includes("left") || L.includes("right") && I.includes("right")) && (L.includes("arm") && I.includes("arm") && !I.includes("fore") || L.includes("forearm") && I.includes("forearm") || L.includes("hand") && I.includes("hand") && !I.includes("index") && !I.includes("thumb") || L.includes("shoulder") && I.includes("shoulder")))
|
|
6606
|
+
return M;
|
|
6605
6607
|
}
|
|
6606
6608
|
return null;
|
|
6607
|
-
},
|
|
6609
|
+
}, k = /* @__PURE__ */ new Set();
|
|
6608
6610
|
d.tracks.forEach((y) => {
|
|
6609
6611
|
const P = y.name.split(".");
|
|
6610
|
-
|
|
6611
|
-
}), Array.from(
|
|
6612
|
+
k.add(P[0]);
|
|
6613
|
+
}), Array.from(k).filter(
|
|
6612
6614
|
(y) => y.toLowerCase().includes("arm") || y.toLowerCase().includes("hand") || y.toLowerCase().includes("shoulder")
|
|
6613
6615
|
), Array.from(g).filter(
|
|
6614
6616
|
(y) => y.includes("Arm") || y.includes("Hand") || y.includes("Shoulder")
|
|
6615
6617
|
);
|
|
6616
|
-
const
|
|
6618
|
+
const G = [], m = /* @__PURE__ */ new Set();
|
|
6617
6619
|
d.tracks.forEach((y) => {
|
|
6618
|
-
const L = y.name.replaceAll("mixamorig", "").split("."), f = L[0],
|
|
6619
|
-
if (!(
|
|
6620
|
-
if (
|
|
6621
|
-
const
|
|
6622
|
-
|
|
6620
|
+
const L = y.name.replaceAll("mixamorig", "").split("."), f = L[0], M = L[1], I = x(f);
|
|
6621
|
+
if (!(I && (I === "LeftShoulder" || I === "RightShoulder") && (M === "quaternion" || M === "rotation")))
|
|
6622
|
+
if (I && M) {
|
|
6623
|
+
const F = `${I}.${M}`, B = y.clone();
|
|
6624
|
+
B.name = F, G.push(B), f !== I && R.set(f, I);
|
|
6623
6625
|
} else
|
|
6624
6626
|
m.add(f), (f.toLowerCase().includes("arm") || f.toLowerCase().includes("hand") || f.toLowerCase().includes("shoulder")) && console.warn(`⚠️ Arm bone "${f}" could not be mapped to avatar skeleton`);
|
|
6625
|
-
}),
|
|
6627
|
+
}), G.length > 0 ? d = new b.AnimationClip(d.name, d.duration, G) : console.error("No tracks could be mapped! Animation may not work correctly.");
|
|
6626
6628
|
const D = {};
|
|
6627
6629
|
d.tracks.forEach((y) => {
|
|
6628
6630
|
y.name = y.name.replaceAll("mixamorig", "");
|
|
@@ -6633,11 +6635,11 @@ class nt {
|
|
|
6633
6635
|
D[y.name] = new b.Vector3(y.values[0], y.values[1], y.values[2]);
|
|
6634
6636
|
} else P[1] === "quaternion" ? D[y.name] = new b.Quaternion(y.values[0], y.values[1], y.values[2], y.values[3]) : P[1] === "rotation" && (D[P[0] + ".quaternion"] = new b.Quaternion().setFromEuler(new b.Euler(y.values[0], y.values[1], y.values[2], "XYZ")).normalize());
|
|
6635
6637
|
});
|
|
6636
|
-
const
|
|
6637
|
-
D["Hips.position"] && (D["Hips.position"].y < 0.5 ?
|
|
6638
|
+
const E = { props: D };
|
|
6639
|
+
D["Hips.position"] && (D["Hips.position"].y < 0.5 ? E.lying = !0 : E.standing = !0), this.animClips.push({
|
|
6638
6640
|
url: n + "-" + o,
|
|
6639
6641
|
clip: d,
|
|
6640
|
-
pose:
|
|
6642
|
+
pose: E
|
|
6641
6643
|
}), this.playAnimation(n, e, t, o, s);
|
|
6642
6644
|
} else {
|
|
6643
6645
|
const d = "Animation " + n + " (ndx=" + o + ") not found";
|
|
@@ -6649,7 +6651,7 @@ class nt {
|
|
|
6649
6651
|
* Stop running animations.
|
|
6650
6652
|
*/
|
|
6651
6653
|
stopAnimation() {
|
|
6652
|
-
if (this.currentFBXAction && (this.currentFBXAction.stop(), this.currentFBXAction = null), this.mixer && this.mixer._actions.length === 0 && (this.mixer = null), this.positionWasLocked && this.unlockAvatarPosition(), this.gesture)
|
|
6654
|
+
if (this.currentFBXAction && (this.currentFBXAction.stop(), this.currentFBXAction = null), this.currentFBXActionForCallback = null, this.currentFBXActionCallback = null, this.currentFBXActionStartTime = null, this.currentFBXActionClipDuration = null, this.mixer && this.mixer._actions.length === 0 && (this.mixer = null), this.positionWasLocked && this.unlockAvatarPosition(), this.gesture)
|
|
6653
6655
|
for (let [e, t] of Object.entries(this.gesture))
|
|
6654
6656
|
t.t = this.animClock, t.d = 1e3, this.poseTarget.props.hasOwnProperty(e) && (this.poseTarget.props[e].copy(t), this.poseTarget.props[e].t = this.animClock, this.poseTarget.props[e].d = 1e3);
|
|
6655
6657
|
let n = this.animQueue.find((e) => e.template.name === "pose");
|
|
@@ -6667,25 +6669,25 @@ class nt {
|
|
|
6667
6669
|
if (!this.armature) return;
|
|
6668
6670
|
let i = this.poseTemplates[n];
|
|
6669
6671
|
if (!i) {
|
|
6670
|
-
const a = this.animPoses.find((
|
|
6672
|
+
const a = this.animPoses.find((u) => u.url === n + "-" + o);
|
|
6671
6673
|
a && (i = a.pose);
|
|
6672
6674
|
}
|
|
6673
6675
|
if (i) {
|
|
6674
6676
|
this.poseName = n, this.mixer = null;
|
|
6675
|
-
let a = this.animQueue.find((
|
|
6677
|
+
let a = this.animQueue.find((u) => u.template.name === "pose");
|
|
6676
6678
|
a && (a.ts[0] = this.animClock + t * 1e3 + 2e3), this.setPoseFromTemplate(i);
|
|
6677
6679
|
} else {
|
|
6678
|
-
let
|
|
6679
|
-
if (
|
|
6680
|
-
let l =
|
|
6681
|
-
const
|
|
6680
|
+
let u = await new ot().loadAsync(n, e);
|
|
6681
|
+
if (u && u.animations && u.animations[o]) {
|
|
6682
|
+
let l = u.animations[o];
|
|
6683
|
+
const c = {};
|
|
6682
6684
|
l.tracks.forEach((h) => {
|
|
6683
6685
|
h.name = h.name.replaceAll("mixamorig", "");
|
|
6684
6686
|
const d = h.name.split(".");
|
|
6685
|
-
d[1] === "position" ?
|
|
6687
|
+
d[1] === "position" ? c[h.name] = new b.Vector3(h.values[0] * s, h.values[1] * s, h.values[2] * s) : d[1] === "quaternion" ? c[h.name] = new b.Quaternion(h.values[0], h.values[1], h.values[2], h.values[3]) : d[1] === "rotation" && (c[d[0] + ".quaternion"] = new b.Quaternion().setFromEuler(new b.Euler(h.values[0], h.values[1], h.values[2], "XYZ")).normalize());
|
|
6686
6688
|
});
|
|
6687
|
-
const r = { props:
|
|
6688
|
-
|
|
6689
|
+
const r = { props: c };
|
|
6690
|
+
c["Hips.position"] && (c["Hips.position"].y < 0.5 ? r.lying = !0 : r.standing = !0), this.animPoses.push({
|
|
6689
6691
|
url: n + "-" + o,
|
|
6690
6692
|
pose: r
|
|
6691
6693
|
}), this.playPose(n, e, t, o, s);
|
|
@@ -6714,10 +6716,10 @@ class nt {
|
|
|
6714
6716
|
let s = this.gestureTemplates[n];
|
|
6715
6717
|
if (s) {
|
|
6716
6718
|
this.gestureTimeout && (clearTimeout(this.gestureTimeout), this.gestureTimeout = null);
|
|
6717
|
-
let a = this.animQueue.findIndex((
|
|
6718
|
-
a !== -1 && (this.animQueue[a].ts = this.animQueue[a].ts.map((
|
|
6719
|
-
for (let [
|
|
6720
|
-
l.t = this.animClock, l.d = o, this.poseTarget.props.hasOwnProperty(
|
|
6719
|
+
let a = this.animQueue.findIndex((u) => u.template.name === "talkinghands");
|
|
6720
|
+
a !== -1 && (this.animQueue[a].ts = this.animQueue[a].ts.map((u) => 0)), this.gesture = this.propsToThreeObjects(s), t && (this.gesture = this.mirrorPose(this.gesture)), n === "namaste" && this.avatar.body === "M" && (this.gesture["RightArm.quaternion"].rotateTowards(new b.Quaternion(0, 1, 0, 0), -0.25), this.gesture["LeftArm.quaternion"].rotateTowards(new b.Quaternion(0, 1, 0, 0), -0.25));
|
|
6721
|
+
for (let [u, l] of Object.entries(this.gesture))
|
|
6722
|
+
l.t = this.animClock, l.d = o, this.poseTarget.props.hasOwnProperty(u) && (this.poseTarget.props[u].copy(l), this.poseTarget.props[u].t = this.animClock, this.poseTarget.props[u].d = o);
|
|
6721
6723
|
e && Number.isFinite(e) && (this.gestureTimeout = setTimeout(this.stopGesture.bind(this, o), 1e3 * e));
|
|
6722
6724
|
}
|
|
6723
6725
|
let i = this.animEmojis[n];
|
|
@@ -6725,15 +6727,15 @@ class nt {
|
|
|
6725
6727
|
this.lookAtCamera(500);
|
|
6726
6728
|
const a = this.animFactory(i);
|
|
6727
6729
|
if (a.gesture = !0, e && Number.isFinite(e)) {
|
|
6728
|
-
const
|
|
6729
|
-
if (e * 1e3 -
|
|
6730
|
+
const u = a.ts[0], c = a.ts[a.ts.length - 1] - u;
|
|
6731
|
+
if (e * 1e3 - c > 0) {
|
|
6730
6732
|
const h = [];
|
|
6731
6733
|
for (let R = 1; R < a.ts.length; R++) h.push(a.ts[R] - a.ts[R - 1]);
|
|
6732
|
-
const d = i.template?.rescale || h.map((R) => R /
|
|
6733
|
-
a.ts = a.ts.map((R, x,
|
|
6734
|
+
const d = i.template?.rescale || h.map((R) => R / c), g = e * 1e3 - c;
|
|
6735
|
+
a.ts = a.ts.map((R, x, k) => x === 0 ? u : k[x - 1] + h[x - 1] + d[x - 1] * g);
|
|
6734
6736
|
} else {
|
|
6735
|
-
const h = e * 1e3 /
|
|
6736
|
-
a.ts = a.ts.map((d) =>
|
|
6737
|
+
const h = e * 1e3 / c;
|
|
6738
|
+
a.ts = a.ts.map((d) => u + h * (d - u));
|
|
6737
6739
|
}
|
|
6738
6740
|
}
|
|
6739
6741
|
this.animQueue.push(a);
|
|
@@ -6763,21 +6765,21 @@ class nt {
|
|
|
6763
6765
|
* @param {numeric} [d=null] If set, apply in d milliseconds
|
|
6764
6766
|
*/
|
|
6765
6767
|
ikSolve(n, e = null, t = !1, o = null) {
|
|
6766
|
-
const s = new b.Vector3(), i = new b.Vector3(), a = new b.Vector3(),
|
|
6768
|
+
const s = new b.Vector3(), i = new b.Vector3(), a = new b.Vector3(), u = new b.Vector3(), l = new b.Quaternion(), c = new b.Vector3(), r = new b.Vector3(), h = new b.Vector3(), d = this.ikMesh.getObjectByName(n.root);
|
|
6767
6769
|
d.position.setFromMatrixPosition(this.armature.getObjectByName(n.root).matrixWorld), d.quaternion.setFromRotationMatrix(this.armature.getObjectByName(n.root).matrixWorld), e && t && e.applyQuaternion(this.armature.quaternion).add(d.position);
|
|
6768
6770
|
const g = this.ikMesh.getObjectByName(n.effector), R = n.links;
|
|
6769
|
-
R.forEach((
|
|
6770
|
-
|
|
6771
|
+
R.forEach((k) => {
|
|
6772
|
+
k.bone = this.ikMesh.getObjectByName(k.link), k.bone.quaternion.copy(this.getPoseTemplateProp(k.link + ".quaternion"));
|
|
6771
6773
|
}), d.updateMatrixWorld(!0);
|
|
6772
6774
|
const x = n.iterations || 10;
|
|
6773
6775
|
if (e)
|
|
6774
|
-
for (let
|
|
6775
|
-
let
|
|
6776
|
+
for (let k = 0; k < x; k++) {
|
|
6777
|
+
let G = !1;
|
|
6776
6778
|
for (let m = 0, D = R.length; m < D; m++) {
|
|
6777
|
-
const
|
|
6778
|
-
|
|
6779
|
+
const E = R[m].bone;
|
|
6780
|
+
E.matrixWorld.decompose(u, l, c), l.invert(), i.setFromMatrixPosition(g.matrixWorld), a.subVectors(i, u), a.applyQuaternion(l), a.normalize(), s.subVectors(e, u), s.applyQuaternion(l), s.normalize();
|
|
6779
6781
|
let y = s.dot(a);
|
|
6780
|
-
y > 1 ? y = 1 : y < -1 && (y = -1), y = Math.acos(y), !(y < 1e-5) && (R[m].minAngle !== void 0 && y < R[m].minAngle && (y = R[m].minAngle), R[m].maxAngle !== void 0 && y > R[m].maxAngle && (y = R[m].maxAngle), r.crossVectors(a, s), r.normalize(),
|
|
6782
|
+
y > 1 ? y = 1 : y < -1 && (y = -1), y = Math.acos(y), !(y < 1e-5) && (R[m].minAngle !== void 0 && y < R[m].minAngle && (y = R[m].minAngle), R[m].maxAngle !== void 0 && y > R[m].maxAngle && (y = R[m].maxAngle), r.crossVectors(a, s), r.normalize(), ue.setFromAxisAngle(r, y), E.quaternion.multiply(ue), E.rotation.setFromVector3(h.setFromEuler(E.rotation).clamp(new b.Vector3(
|
|
6781
6783
|
R[m].minx !== void 0 ? R[m].minx : -1 / 0,
|
|
6782
6784
|
R[m].miny !== void 0 ? R[m].miny : -1 / 0,
|
|
6783
6785
|
R[m].minz !== void 0 ? R[m].minz : -1 / 0
|
|
@@ -6785,12 +6787,12 @@ class nt {
|
|
|
6785
6787
|
R[m].maxx !== void 0 ? R[m].maxx : 1 / 0,
|
|
6786
6788
|
R[m].maxy !== void 0 ? R[m].maxy : 1 / 0,
|
|
6787
6789
|
R[m].maxz !== void 0 ? R[m].maxz : 1 / 0
|
|
6788
|
-
))),
|
|
6790
|
+
))), E.updateMatrixWorld(!0), G = !0);
|
|
6789
6791
|
}
|
|
6790
|
-
if (!
|
|
6792
|
+
if (!G) break;
|
|
6791
6793
|
}
|
|
6792
|
-
o && R.forEach((
|
|
6793
|
-
this.poseTarget.props[
|
|
6794
|
+
o && R.forEach((k) => {
|
|
6795
|
+
this.poseTarget.props[k.link + ".quaternion"].copy(k.bone.quaternion), this.poseTarget.props[k.link + ".quaternion"].t = this.animClock, this.poseTarget.props[k.link + ".quaternion"].d = o;
|
|
6794
6796
|
});
|
|
6795
6797
|
}
|
|
6796
6798
|
/**
|
|
@@ -6800,7 +6802,7 @@ class nt {
|
|
|
6800
6802
|
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();
|
|
6801
6803
|
}
|
|
6802
6804
|
}
|
|
6803
|
-
const
|
|
6805
|
+
const Ze = {
|
|
6804
6806
|
apiKey: "sk_ace57ef3ef65a92b9d3bee2a00183b78ca790bc3e10964f2",
|
|
6805
6807
|
// Replace with your actual API key (should start with sk_)
|
|
6806
6808
|
endpoint: "https://api.elevenlabs.io/v1/text-to-speech",
|
|
@@ -6843,10 +6845,10 @@ const Xe = {
|
|
|
6843
6845
|
function $e() {
|
|
6844
6846
|
return {
|
|
6845
6847
|
service: "elevenlabs",
|
|
6846
|
-
endpoint:
|
|
6847
|
-
apiKey:
|
|
6848
|
-
defaultVoice:
|
|
6849
|
-
voices:
|
|
6848
|
+
endpoint: Ze.endpoint,
|
|
6849
|
+
apiKey: Ze.apiKey,
|
|
6850
|
+
defaultVoice: Ze.defaultVoice,
|
|
6851
|
+
voices: Ze.voices
|
|
6850
6852
|
};
|
|
6851
6853
|
}
|
|
6852
6854
|
function qt() {
|
|
@@ -6858,7 +6860,7 @@ function qt() {
|
|
|
6858
6860
|
});
|
|
6859
6861
|
}), n;
|
|
6860
6862
|
}
|
|
6861
|
-
const
|
|
6863
|
+
const ct = Ke(({
|
|
6862
6864
|
avatarUrl: Z = "/avatars/brunette.glb",
|
|
6863
6865
|
avatarBody: n = "F",
|
|
6864
6866
|
mood: e = "neutral",
|
|
@@ -6867,9 +6869,9 @@ const ut = Ke(({
|
|
|
6867
6869
|
ttsVoice: s = null,
|
|
6868
6870
|
ttsApiKey: i = null,
|
|
6869
6871
|
bodyMovement: a = "idle",
|
|
6870
|
-
movementIntensity:
|
|
6872
|
+
movementIntensity: u = 0.5,
|
|
6871
6873
|
showFullAvatar: l = !0,
|
|
6872
|
-
cameraView:
|
|
6874
|
+
cameraView: c = "upper",
|
|
6873
6875
|
onReady: r = () => {
|
|
6874
6876
|
},
|
|
6875
6877
|
onLoading: h = () => {
|
|
@@ -6879,8 +6881,8 @@ const ut = Ke(({
|
|
|
6879
6881
|
className: g = "",
|
|
6880
6882
|
style: R = {},
|
|
6881
6883
|
animations: x = {}
|
|
6882
|
-
},
|
|
6883
|
-
const
|
|
6884
|
+
}, k) => {
|
|
6885
|
+
const G = V(null), m = V(null), D = V(l), E = V(null), y = V(null), P = V(!1), L = V({ remainingText: null, originalText: null, options: null }), f = V([]), M = V(0), [I, F] = pe(!0), [B, Q] = pe(null), [_, ve] = pe(!1), [me, Fe] = pe(!1);
|
|
6884
6886
|
Se(() => {
|
|
6885
6887
|
P.current = me;
|
|
6886
6888
|
}, [me]), Se(() => {
|
|
@@ -6897,8 +6899,8 @@ const ut = Ke(({
|
|
|
6897
6899
|
service: "elevenlabs",
|
|
6898
6900
|
endpoint: "https://api.elevenlabs.io/v1/text-to-speech",
|
|
6899
6901
|
apiKey: i || ye.apiKey,
|
|
6900
|
-
defaultVoice: s || ye.defaultVoice ||
|
|
6901
|
-
voices: ye.voices ||
|
|
6902
|
+
defaultVoice: s || ye.defaultVoice || Ze.defaultVoice,
|
|
6903
|
+
voices: ye.voices || Ze.voices
|
|
6902
6904
|
} : Re === "deepgram" ? he = {
|
|
6903
6905
|
service: "deepgram",
|
|
6904
6906
|
endpoint: "https://api.deepgram.com/v1/speak",
|
|
@@ -6910,7 +6912,7 @@ const ut = Ke(({
|
|
|
6910
6912
|
// Override API key if provided via props
|
|
6911
6913
|
apiKey: i !== null ? i : ye.apiKey
|
|
6912
6914
|
};
|
|
6913
|
-
const
|
|
6915
|
+
const A = {
|
|
6914
6916
|
url: Z,
|
|
6915
6917
|
body: n,
|
|
6916
6918
|
avatarMood: e,
|
|
@@ -6919,17 +6921,17 @@ const ut = Ke(({
|
|
|
6919
6921
|
lipsyncLang: "en",
|
|
6920
6922
|
showFullAvatar: l,
|
|
6921
6923
|
bodyMovement: a,
|
|
6922
|
-
movementIntensity:
|
|
6923
|
-
},
|
|
6924
|
+
movementIntensity: u
|
|
6925
|
+
}, v = {
|
|
6924
6926
|
ttsEndpoint: he.endpoint,
|
|
6925
6927
|
ttsApikey: he.apiKey,
|
|
6926
6928
|
ttsService: Re,
|
|
6927
6929
|
lipsyncModules: ["en"],
|
|
6928
|
-
cameraView:
|
|
6929
|
-
},
|
|
6930
|
-
if (!(!
|
|
6930
|
+
cameraView: c
|
|
6931
|
+
}, T = U(async () => {
|
|
6932
|
+
if (!(!G.current || m.current))
|
|
6931
6933
|
try {
|
|
6932
|
-
if (
|
|
6934
|
+
if (F(!0), Q(null), m.current = new nt(G.current, v), m.current.controls && (m.current.controls.enableRotate = !1, m.current.controls.enableZoom = !1, m.current.controls.enablePan = !1, m.current.controls.enableDamping = !1), x && Object.keys(x).length > 0 && (m.current.customAnimations = x), await m.current.showAvatar(A, (ne) => {
|
|
6933
6935
|
if (ne.lengthComputable) {
|
|
6934
6936
|
const se = Math.min(100, Math.round(ne.loaded / ne.total * 100));
|
|
6935
6937
|
h(se);
|
|
@@ -6945,63 +6947,63 @@ const ut = Ke(({
|
|
|
6945
6947
|
} catch (ne) {
|
|
6946
6948
|
console.warn("Error setting full body mode on initialization:", ne);
|
|
6947
6949
|
}
|
|
6948
|
-
m.current && m.current.controls && (m.current.controls.enableRotate = !1, m.current.controls.enableZoom = !1, m.current.controls.enablePan = !1, m.current.controls.enableDamping = !1, m.current.controls.update()),
|
|
6949
|
-
const
|
|
6950
|
+
m.current && m.current.controls && (m.current.controls.enableRotate = !1, m.current.controls.enableZoom = !1, m.current.controls.enablePan = !1, m.current.controls.enableDamping = !1, m.current.controls.update()), F(!1), ve(!0), r(m.current);
|
|
6951
|
+
const X = () => {
|
|
6950
6952
|
document.visibilityState === "visible" ? m.current?.start() : m.current?.stop();
|
|
6951
6953
|
};
|
|
6952
|
-
return document.addEventListener("visibilitychange",
|
|
6953
|
-
document.removeEventListener("visibilitychange",
|
|
6954
|
+
return document.addEventListener("visibilitychange", X), () => {
|
|
6955
|
+
document.removeEventListener("visibilitychange", X);
|
|
6954
6956
|
};
|
|
6955
6957
|
} catch (C) {
|
|
6956
|
-
console.error("Error initializing TalkingHead:", C), Q(C.message || "Failed to initialize avatar"),
|
|
6958
|
+
console.error("Error initializing TalkingHead:", C), Q(C.message || "Failed to initialize avatar"), F(!1), d(C);
|
|
6957
6959
|
}
|
|
6958
|
-
}, [Z, n, e, t, o, s, i, l, a,
|
|
6959
|
-
Se(() => (
|
|
6960
|
+
}, [Z, n, e, t, o, s, i, l, a, u, c]);
|
|
6961
|
+
Se(() => (T(), () => {
|
|
6960
6962
|
m.current && (m.current.stop(), m.current.dispose(), m.current = null);
|
|
6961
|
-
}), [
|
|
6962
|
-
if (!
|
|
6963
|
+
}), [T]), Se(() => {
|
|
6964
|
+
if (!G.current || !m.current) return;
|
|
6963
6965
|
const C = new ResizeObserver((ne) => {
|
|
6964
6966
|
for (const se of ne)
|
|
6965
6967
|
m.current && m.current.onResize && m.current.onResize();
|
|
6966
6968
|
});
|
|
6967
|
-
C.observe(
|
|
6968
|
-
const
|
|
6969
|
+
C.observe(G.current);
|
|
6970
|
+
const X = () => {
|
|
6969
6971
|
m.current && m.current.onResize && m.current.onResize();
|
|
6970
6972
|
};
|
|
6971
|
-
return window.addEventListener("resize",
|
|
6972
|
-
C.disconnect(), window.removeEventListener("resize",
|
|
6973
|
+
return window.addEventListener("resize", X), () => {
|
|
6974
|
+
C.disconnect(), window.removeEventListener("resize", X);
|
|
6973
6975
|
};
|
|
6974
6976
|
}, [_]);
|
|
6975
|
-
const
|
|
6977
|
+
const O = U(async () => {
|
|
6976
6978
|
if (m.current && m.current.audioCtx)
|
|
6977
6979
|
try {
|
|
6978
6980
|
(m.current.audioCtx.state === "suspended" || m.current.audioCtx.state === "interrupted") && (await m.current.audioCtx.resume(), console.log("Audio context resumed"));
|
|
6979
6981
|
} catch (C) {
|
|
6980
6982
|
console.warn("Failed to resume audio context:", C);
|
|
6981
6983
|
}
|
|
6982
|
-
}, []), Y = U(async (C,
|
|
6984
|
+
}, []), Y = U(async (C, X = {}) => {
|
|
6983
6985
|
if (m.current && _)
|
|
6984
6986
|
try {
|
|
6985
|
-
y.current && (clearInterval(y.current), y.current = null),
|
|
6987
|
+
y.current && (clearInterval(y.current), y.current = null), E.current = { text: C, options: X }, L.current = { remainingText: null, originalText: null, options: null };
|
|
6986
6988
|
const ne = /[!\.\?\n\p{Extended_Pictographic}]/ug, se = C.split(ne).map((re) => re.trim()).filter((re) => re.length > 0);
|
|
6987
|
-
f.current = se,
|
|
6989
|
+
f.current = se, M.current = 0, Fe(!1), P.current = !1, await O();
|
|
6988
6990
|
const ze = {
|
|
6989
|
-
...
|
|
6990
|
-
lipsyncLang:
|
|
6991
|
+
...X,
|
|
6992
|
+
lipsyncLang: X.lipsyncLang || A.lipsyncLang || "en"
|
|
6991
6993
|
};
|
|
6992
|
-
if (
|
|
6994
|
+
if (X.onSpeechEnd && m.current) {
|
|
6993
6995
|
const re = m.current;
|
|
6994
|
-
let
|
|
6995
|
-
const
|
|
6996
|
+
let Ae = null, Ee = 0;
|
|
6997
|
+
const Be = 1200;
|
|
6996
6998
|
let He = !1;
|
|
6997
|
-
|
|
6998
|
-
if (
|
|
6999
|
+
Ae = setInterval(() => {
|
|
7000
|
+
if (Ee++, P.current)
|
|
6999
7001
|
return;
|
|
7000
|
-
if (
|
|
7001
|
-
if (
|
|
7002
|
+
if (Ee > Be) {
|
|
7003
|
+
if (Ae && (clearInterval(Ae), Ae = null, y.current = null), !He && !P.current) {
|
|
7002
7004
|
He = !0;
|
|
7003
7005
|
try {
|
|
7004
|
-
|
|
7006
|
+
X.onSpeechEnd();
|
|
7005
7007
|
} catch (Ve) {
|
|
7006
7008
|
console.error("Error in onSpeechEnd callback (timeout):", Ve);
|
|
7007
7009
|
}
|
|
@@ -7011,71 +7013,71 @@ const ut = Ke(({
|
|
|
7011
7013
|
const we = !re.speechQueue || re.speechQueue.length === 0, We = !re.audioPlaylist || re.audioPlaylist.length === 0;
|
|
7012
7014
|
re && re.isSpeaking === !1 && we && We && re.isAudioPlaying === !1 && !He && !P.current && setTimeout(() => {
|
|
7013
7015
|
if (re && !P.current && re.isSpeaking === !1 && (!re.speechQueue || re.speechQueue.length === 0) && (!re.audioPlaylist || re.audioPlaylist.length === 0) && re.isAudioPlaying === !1 && !He && !P.current) {
|
|
7014
|
-
He = !0,
|
|
7016
|
+
He = !0, Ae && (clearInterval(Ae), Ae = null, y.current = null);
|
|
7015
7017
|
try {
|
|
7016
|
-
|
|
7018
|
+
X.onSpeechEnd();
|
|
7017
7019
|
} catch (tt) {
|
|
7018
7020
|
console.error("Error in onSpeechEnd callback:", tt);
|
|
7019
7021
|
}
|
|
7020
7022
|
}
|
|
7021
7023
|
}, 100);
|
|
7022
|
-
}, 100), y.current =
|
|
7024
|
+
}, 100), y.current = Ae;
|
|
7023
7025
|
}
|
|
7024
7026
|
m.current.lipsync && Object.keys(m.current.lipsync).length > 0 ? (m.current.setSlowdownRate && m.current.setSlowdownRate(1.05), m.current.speakText(C, ze)) : setTimeout(async () => {
|
|
7025
|
-
await
|
|
7027
|
+
await O(), m.current && m.current.lipsync && (m.current.setSlowdownRate && m.current.setSlowdownRate(1.05), m.current.speakText(C, ze));
|
|
7026
7028
|
}, 100);
|
|
7027
7029
|
} catch (ne) {
|
|
7028
7030
|
console.error("Error speaking text:", ne), Q(ne.message || "Failed to speak text");
|
|
7029
7031
|
}
|
|
7030
|
-
}, [_,
|
|
7031
|
-
m.current && (m.current.stopSpeaking(), m.current.setSlowdownRate && m.current.setSlowdownRate(1),
|
|
7032
|
+
}, [_, O, A.lipsyncLang]), K = U(() => {
|
|
7033
|
+
m.current && (m.current.stopSpeaking(), m.current.setSlowdownRate && m.current.setSlowdownRate(1), E.current = null, Fe(!1));
|
|
7032
7034
|
}, []), q = U(() => {
|
|
7033
7035
|
if (m.current && m.current.pauseSpeaking) {
|
|
7034
7036
|
const C = m.current;
|
|
7035
7037
|
if (C.isSpeaking || C.audioPlaylist && C.audioPlaylist.length > 0 || C.speechQueue && C.speechQueue.length > 0) {
|
|
7036
7038
|
y.current && (clearInterval(y.current), y.current = null);
|
|
7037
7039
|
let ne = "";
|
|
7038
|
-
if (
|
|
7039
|
-
const se = f.current.length, ze = C.speechQueue ? C.speechQueue.filter((
|
|
7040
|
-
if (
|
|
7040
|
+
if (E.current && f.current.length > 0) {
|
|
7041
|
+
const se = f.current.length, ze = C.speechQueue ? C.speechQueue.filter((Be) => Be && Be.text && Array.isArray(Be.text) && Be.text.length > 0).length : 0, re = C.audioPlaylist && C.audioPlaylist.length > 0, Ae = ze + (re ? 1 : 0), Ee = se - Ae;
|
|
7042
|
+
if (Ae > 0 && Ee < se && (ne = f.current.slice(Ee).join(". ").trim(), !ne && ze > 0 && C.speechQueue)) {
|
|
7041
7043
|
const He = C.speechQueue.filter((we) => we && we.text && Array.isArray(we.text) && we.text.length > 0).map((we) => we.text.map((We) => We.word || "").filter((We) => We.length > 0).join(" ")).filter((we) => we.length > 0).join(" ");
|
|
7042
7044
|
He && He.trim() && (ne = He.trim());
|
|
7043
7045
|
}
|
|
7044
7046
|
}
|
|
7045
|
-
|
|
7047
|
+
E.current && (L.current = {
|
|
7046
7048
|
remainingText: ne || null,
|
|
7047
|
-
originalText:
|
|
7048
|
-
options:
|
|
7049
|
-
}), C.speechQueue && (C.speechQueue.length = 0), m.current.pauseSpeaking(), P.current = !0,
|
|
7049
|
+
originalText: E.current.text,
|
|
7050
|
+
options: E.current.options
|
|
7051
|
+
}), C.speechQueue && (C.speechQueue.length = 0), m.current.pauseSpeaking(), P.current = !0, Fe(!0);
|
|
7050
7052
|
}
|
|
7051
7053
|
}
|
|
7052
7054
|
}, []), te = U(async () => {
|
|
7053
7055
|
if (!m.current || !me)
|
|
7054
7056
|
return;
|
|
7055
|
-
let C = "",
|
|
7057
|
+
let C = "", X = {};
|
|
7056
7058
|
if (L.current && L.current.remainingText)
|
|
7057
|
-
C = L.current.remainingText,
|
|
7058
|
-
else if (
|
|
7059
|
-
C =
|
|
7059
|
+
C = L.current.remainingText, X = L.current.options || {}, L.current = { remainingText: null, originalText: null, options: null };
|
|
7060
|
+
else if (E.current && E.current.text)
|
|
7061
|
+
C = E.current.text, X = E.current.options || {};
|
|
7060
7062
|
else {
|
|
7061
|
-
console.warn("Resume called but no paused speech found"),
|
|
7063
|
+
console.warn("Resume called but no paused speech found"), Fe(!1), P.current = !1;
|
|
7062
7064
|
return;
|
|
7063
7065
|
}
|
|
7064
|
-
|
|
7066
|
+
Fe(!1), P.current = !1, await O();
|
|
7065
7067
|
const ne = {
|
|
7066
|
-
...
|
|
7067
|
-
lipsyncLang:
|
|
7068
|
+
...X,
|
|
7069
|
+
lipsyncLang: X.lipsyncLang || A.lipsyncLang || "en"
|
|
7068
7070
|
};
|
|
7069
7071
|
try {
|
|
7070
7072
|
await Y(C, ne);
|
|
7071
7073
|
} catch (se) {
|
|
7072
|
-
console.error("Error resuming speech:", se),
|
|
7074
|
+
console.error("Error resuming speech:", se), Fe(!1), P.current = !1;
|
|
7073
7075
|
}
|
|
7074
|
-
}, [
|
|
7076
|
+
}, [O, me, Y, A]), fe = U((C) => {
|
|
7075
7077
|
m.current && m.current.setMood(C);
|
|
7076
|
-
}, []),
|
|
7078
|
+
}, []), Ie = U((C) => {
|
|
7077
7079
|
m.current && m.current.setSlowdownRate && m.current.setSlowdownRate(C);
|
|
7078
|
-
}, []), et = U((C,
|
|
7080
|
+
}, []), et = U((C, X = !1) => {
|
|
7079
7081
|
if (m.current && m.current.playAnimation) {
|
|
7080
7082
|
if (x && x[C] && (C = x[C]), m.current.setShowFullAvatar)
|
|
7081
7083
|
try {
|
|
@@ -7085,7 +7087,7 @@ const ut = Ke(({
|
|
|
7085
7087
|
}
|
|
7086
7088
|
if (C.includes("."))
|
|
7087
7089
|
try {
|
|
7088
|
-
m.current.playAnimation(C, null, 10, 0, 0.01,
|
|
7090
|
+
m.current.playAnimation(C, null, 10, 0, 0.01, X);
|
|
7089
7091
|
} catch (se) {
|
|
7090
7092
|
console.warn(`Failed to play ${C}:`, se);
|
|
7091
7093
|
try {
|
|
@@ -7099,7 +7101,7 @@ const ut = Ke(({
|
|
|
7099
7101
|
let ze = !1;
|
|
7100
7102
|
for (const re of se)
|
|
7101
7103
|
try {
|
|
7102
|
-
m.current.playAnimation(C + re, null, 10, 0, 0.01,
|
|
7104
|
+
m.current.playAnimation(C + re, null, 10, 0, 0.01, X), ze = !0;
|
|
7103
7105
|
break;
|
|
7104
7106
|
} catch {
|
|
7105
7107
|
}
|
|
@@ -7116,14 +7118,14 @@ const ut = Ke(({
|
|
|
7116
7118
|
}, [x]), ke = U(() => {
|
|
7117
7119
|
m.current && m.current.onResize && m.current.onResize();
|
|
7118
7120
|
}, []);
|
|
7119
|
-
return Je(
|
|
7121
|
+
return Je(k, () => ({
|
|
7120
7122
|
speakText: Y,
|
|
7121
7123
|
stopSpeaking: K,
|
|
7122
7124
|
pauseSpeaking: q,
|
|
7123
7125
|
resumeSpeaking: te,
|
|
7124
|
-
resumeAudioContext:
|
|
7126
|
+
resumeAudioContext: O,
|
|
7125
7127
|
setMood: fe,
|
|
7126
|
-
setTimingAdjustment:
|
|
7128
|
+
setTimingAdjustment: Ie,
|
|
7127
7129
|
playAnimation: et,
|
|
7128
7130
|
isReady: _,
|
|
7129
7131
|
isPaused: me,
|
|
@@ -7133,8 +7135,8 @@ const ut = Ke(({
|
|
|
7133
7135
|
if (m.current && m.current.setShowFullAvatar && m.current.setBodyMovement)
|
|
7134
7136
|
try {
|
|
7135
7137
|
m.current.setShowFullAvatar(D.current), m.current.setBodyMovement(C);
|
|
7136
|
-
} catch (
|
|
7137
|
-
console.warn("Error setting body movement:",
|
|
7138
|
+
} catch (X) {
|
|
7139
|
+
console.warn("Error setting body movement:", X);
|
|
7138
7140
|
}
|
|
7139
7141
|
},
|
|
7140
7142
|
setMovementIntensity: (C) => m.current?.setMovementIntensity(C),
|
|
@@ -7150,8 +7152,8 @@ const ut = Ke(({
|
|
|
7150
7152
|
if (m.current && m.current.setShowFullAvatar && m.current.playReaction)
|
|
7151
7153
|
try {
|
|
7152
7154
|
m.current.setShowFullAvatar(D.current), m.current.playReaction(C);
|
|
7153
|
-
} catch (
|
|
7154
|
-
console.warn("Error playing reaction:",
|
|
7155
|
+
} catch (X) {
|
|
7156
|
+
console.warn("Error playing reaction:", X);
|
|
7155
7157
|
}
|
|
7156
7158
|
},
|
|
7157
7159
|
playCelebration: () => {
|
|
@@ -7166,8 +7168,8 @@ const ut = Ke(({
|
|
|
7166
7168
|
if (m.current && m.current.setShowFullAvatar)
|
|
7167
7169
|
try {
|
|
7168
7170
|
D.current = C, m.current.setShowFullAvatar(C);
|
|
7169
|
-
} catch (
|
|
7170
|
-
console.warn("Error setting showFullAvatar:",
|
|
7171
|
+
} catch (X) {
|
|
7172
|
+
console.warn("Error setting showFullAvatar:", X);
|
|
7171
7173
|
}
|
|
7172
7174
|
},
|
|
7173
7175
|
lockAvatarPosition: () => {
|
|
@@ -7200,7 +7202,7 @@ const ut = Ke(({
|
|
|
7200
7202
|
/* @__PURE__ */ ae(
|
|
7201
7203
|
"div",
|
|
7202
7204
|
{
|
|
7203
|
-
ref:
|
|
7205
|
+
ref: G,
|
|
7204
7206
|
className: "talking-head-viewer",
|
|
7205
7207
|
style: {
|
|
7206
7208
|
width: "100%",
|
|
@@ -7209,7 +7211,7 @@ const ut = Ke(({
|
|
|
7209
7211
|
}
|
|
7210
7212
|
}
|
|
7211
7213
|
),
|
|
7212
|
-
|
|
7214
|
+
I && /* @__PURE__ */ ae("div", { className: "loading-overlay", style: {
|
|
7213
7215
|
position: "absolute",
|
|
7214
7216
|
top: "50%",
|
|
7215
7217
|
left: "50%",
|
|
@@ -7218,7 +7220,7 @@ const ut = Ke(({
|
|
|
7218
7220
|
fontSize: "18px",
|
|
7219
7221
|
zIndex: 10
|
|
7220
7222
|
}, children: "Loading avatar..." }),
|
|
7221
|
-
|
|
7223
|
+
B && /* @__PURE__ */ ae("div", { className: "error-overlay", style: {
|
|
7222
7224
|
position: "absolute",
|
|
7223
7225
|
top: "50%",
|
|
7224
7226
|
left: "50%",
|
|
@@ -7229,13 +7231,13 @@ const ut = Ke(({
|
|
|
7229
7231
|
zIndex: 10,
|
|
7230
7232
|
padding: "20px",
|
|
7231
7233
|
borderRadius: "8px"
|
|
7232
|
-
}, children:
|
|
7234
|
+
}, children: B })
|
|
7233
7235
|
]
|
|
7234
7236
|
}
|
|
7235
7237
|
);
|
|
7236
7238
|
});
|
|
7237
|
-
|
|
7238
|
-
const
|
|
7239
|
+
ct.displayName = "TalkingHeadAvatar";
|
|
7240
|
+
const Ot = Ke(({
|
|
7239
7241
|
text: Z = "Hello! I'm a talking avatar. How are you today?",
|
|
7240
7242
|
onLoading: n = () => {
|
|
7241
7243
|
},
|
|
@@ -7247,7 +7249,7 @@ const Bt = Ke(({
|
|
|
7247
7249
|
style: s = {},
|
|
7248
7250
|
avatarConfig: i = {}
|
|
7249
7251
|
}, a) => {
|
|
7250
|
-
const
|
|
7252
|
+
const u = V(null), l = V(null), [c, r] = pe(!0), [h, d] = pe(null), [g, R] = pe(!1), x = $e(), k = i.ttsService || x.service, G = k === "browser" ? {
|
|
7251
7253
|
endpoint: "",
|
|
7252
7254
|
apiKey: null,
|
|
7253
7255
|
defaultVoice: "Google US English"
|
|
@@ -7256,14 +7258,14 @@ const Bt = Ke(({
|
|
|
7256
7258
|
// Override API key if provided via avatarConfig
|
|
7257
7259
|
apiKey: i.ttsApiKey !== void 0 && i.ttsApiKey !== null ? i.ttsApiKey : x.apiKey,
|
|
7258
7260
|
// Override endpoint for ElevenLabs if service is explicitly set
|
|
7259
|
-
endpoint:
|
|
7261
|
+
endpoint: k === "elevenlabs" && i.ttsApiKey ? "https://api.elevenlabs.io/v1/text-to-speech" : x.endpoint
|
|
7260
7262
|
}, m = {
|
|
7261
7263
|
url: "/avatars/brunette.glb",
|
|
7262
7264
|
// Use brunette avatar (working glTF file)
|
|
7263
7265
|
body: "F",
|
|
7264
7266
|
avatarMood: "neutral",
|
|
7265
|
-
ttsLang:
|
|
7266
|
-
ttsVoice: i.ttsVoice ||
|
|
7267
|
+
ttsLang: k === "browser" ? "en-US" : "en",
|
|
7268
|
+
ttsVoice: i.ttsVoice || G.defaultVoice,
|
|
7267
7269
|
lipsyncLang: "en",
|
|
7268
7270
|
// English lip-sync
|
|
7269
7271
|
showFullAvatar: !0,
|
|
@@ -7272,68 +7274,68 @@ const Bt = Ke(({
|
|
|
7272
7274
|
movementIntensity: 0.5,
|
|
7273
7275
|
...i
|
|
7274
7276
|
}, D = {
|
|
7275
|
-
ttsEndpoint:
|
|
7276
|
-
ttsApikey:
|
|
7277
|
-
ttsService:
|
|
7277
|
+
ttsEndpoint: G.endpoint,
|
|
7278
|
+
ttsApikey: G.apiKey,
|
|
7279
|
+
ttsService: k,
|
|
7278
7280
|
lipsyncModules: ["en"],
|
|
7279
7281
|
cameraView: "upper"
|
|
7280
|
-
},
|
|
7281
|
-
if (!(!
|
|
7282
|
+
}, E = U(async () => {
|
|
7283
|
+
if (!(!u.current || l.current))
|
|
7282
7284
|
try {
|
|
7283
|
-
if (r(!0), d(null), l.current = new nt(
|
|
7284
|
-
if (
|
|
7285
|
-
const Q = Math.min(100, Math.round(
|
|
7285
|
+
if (r(!0), d(null), l.current = new nt(u.current, D), await l.current.showAvatar(m, (B) => {
|
|
7286
|
+
if (B.lengthComputable) {
|
|
7287
|
+
const Q = Math.min(100, Math.round(B.loaded / B.total * 100));
|
|
7286
7288
|
n(Q);
|
|
7287
7289
|
}
|
|
7288
7290
|
}), l.current.morphs && l.current.morphs.length > 0) {
|
|
7289
|
-
const
|
|
7290
|
-
console.log("Available morph targets:", Object.keys(
|
|
7291
|
-
const Q = Object.keys(
|
|
7291
|
+
const B = l.current.morphs[0].morphTargetDictionary;
|
|
7292
|
+
console.log("Available morph targets:", Object.keys(B));
|
|
7293
|
+
const Q = Object.keys(B).filter((_) => _.startsWith("viseme_"));
|
|
7292
7294
|
console.log("Viseme morph targets found:", Q), Q.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"));
|
|
7293
7295
|
}
|
|
7294
|
-
if (await new Promise((
|
|
7296
|
+
if (await new Promise((B) => {
|
|
7295
7297
|
const Q = () => {
|
|
7296
|
-
l.current.lipsync && Object.keys(l.current.lipsync).length > 0 ? (console.log("Lip-sync modules loaded:", Object.keys(l.current.lipsync)),
|
|
7298
|
+
l.current.lipsync && Object.keys(l.current.lipsync).length > 0 ? (console.log("Lip-sync modules loaded:", Object.keys(l.current.lipsync)), B()) : (console.log("Waiting for lip-sync modules to load..."), setTimeout(Q, 100));
|
|
7297
7299
|
};
|
|
7298
7300
|
Q();
|
|
7299
7301
|
}), l.current && l.current.setShowFullAvatar)
|
|
7300
7302
|
try {
|
|
7301
7303
|
l.current.setShowFullAvatar(!0), console.log("Avatar initialized in full body mode");
|
|
7302
|
-
} catch (
|
|
7303
|
-
console.warn("Error setting full body mode on initialization:",
|
|
7304
|
+
} catch (B) {
|
|
7305
|
+
console.warn("Error setting full body mode on initialization:", B);
|
|
7304
7306
|
}
|
|
7305
7307
|
r(!1), R(!0), t(l.current);
|
|
7306
|
-
const
|
|
7308
|
+
const F = () => {
|
|
7307
7309
|
document.visibilityState === "visible" ? l.current?.start() : l.current?.stop();
|
|
7308
7310
|
};
|
|
7309
|
-
return document.addEventListener("visibilitychange",
|
|
7310
|
-
document.removeEventListener("visibilitychange",
|
|
7311
|
+
return document.addEventListener("visibilitychange", F), () => {
|
|
7312
|
+
document.removeEventListener("visibilitychange", F);
|
|
7311
7313
|
};
|
|
7312
|
-
} catch (
|
|
7313
|
-
console.error("Error initializing TalkingHead:",
|
|
7314
|
+
} catch (I) {
|
|
7315
|
+
console.error("Error initializing TalkingHead:", I), d(I.message || "Failed to initialize avatar"), r(!1), e(I);
|
|
7314
7316
|
}
|
|
7315
7317
|
}, []);
|
|
7316
|
-
Se(() => (
|
|
7318
|
+
Se(() => (E(), () => {
|
|
7317
7319
|
l.current && (l.current.stop(), l.current.dispose(), l.current = null);
|
|
7318
|
-
}), [
|
|
7319
|
-
const y = U((
|
|
7320
|
+
}), [E]);
|
|
7321
|
+
const y = U((I) => {
|
|
7320
7322
|
if (l.current && g)
|
|
7321
7323
|
try {
|
|
7322
|
-
console.log("Speaking text:",
|
|
7323
|
-
l.current && l.current.lipsync ? (console.log("Lip-sync now ready, speaking..."), l.current.setSlowdownRate && (l.current.setSlowdownRate(1.05), console.log("Applied timing adjustment for better lip-sync")), l.current.speakText(
|
|
7324
|
+
console.log("Speaking text:", I), console.log("Avatar config:", m), console.log("TalkingHead instance:", l.current), l.current.lipsync && Object.keys(l.current.lipsync).length > 0 ? (console.log("Lip-sync modules loaded:", Object.keys(l.current.lipsync)), l.current.setSlowdownRate && (l.current.setSlowdownRate(1.05), console.log("Applied timing adjustment for better lip-sync")), l.current.speakText(I)) : (console.warn("Lip-sync modules not ready, waiting..."), setTimeout(() => {
|
|
7325
|
+
l.current && l.current.lipsync ? (console.log("Lip-sync now ready, speaking..."), l.current.setSlowdownRate && (l.current.setSlowdownRate(1.05), console.log("Applied timing adjustment for better lip-sync")), l.current.speakText(I)) : console.error("Lip-sync still not ready after waiting");
|
|
7324
7326
|
}, 500));
|
|
7325
|
-
} catch (
|
|
7326
|
-
console.error("Error speaking text:",
|
|
7327
|
+
} catch (F) {
|
|
7328
|
+
console.error("Error speaking text:", F), d(F.message || "Failed to speak text");
|
|
7327
7329
|
}
|
|
7328
7330
|
else
|
|
7329
7331
|
console.warn("Avatar not ready for speaking. isReady:", g, "talkingHeadRef:", !!l.current);
|
|
7330
7332
|
}, [g, m]), P = U(() => {
|
|
7331
7333
|
l.current && (l.current.stopSpeaking(), l.current.setSlowdownRate && (l.current.setSlowdownRate(1), console.log("Reset timing to normal")));
|
|
7332
|
-
}, []), L = U((
|
|
7333
|
-
l.current && l.current.setMood(
|
|
7334
|
-
}, []), f = U((
|
|
7335
|
-
l.current && l.current.setSlowdownRate && (l.current.setSlowdownRate(
|
|
7336
|
-
}, []),
|
|
7334
|
+
}, []), L = U((I) => {
|
|
7335
|
+
l.current && l.current.setMood(I);
|
|
7336
|
+
}, []), f = U((I) => {
|
|
7337
|
+
l.current && l.current.setSlowdownRate && (l.current.setSlowdownRate(I), console.log("Timing adjustment set to:", I));
|
|
7338
|
+
}, []), M = U((I, F = !1) => {
|
|
7337
7339
|
if (l.current && l.current.playAnimation) {
|
|
7338
7340
|
if (l.current.setShowFullAvatar)
|
|
7339
7341
|
try {
|
|
@@ -7341,11 +7343,11 @@ const Bt = Ke(({
|
|
|
7341
7343
|
} catch (Q) {
|
|
7342
7344
|
console.warn("Error setting full body mode:", Q);
|
|
7343
7345
|
}
|
|
7344
|
-
if (
|
|
7346
|
+
if (I.includes("."))
|
|
7345
7347
|
try {
|
|
7346
|
-
l.current.playAnimation(
|
|
7348
|
+
l.current.playAnimation(I, null, 10, 0, 0.01, F), console.log("Playing animation:", I);
|
|
7347
7349
|
} catch (Q) {
|
|
7348
|
-
console.log(`Failed to play ${
|
|
7350
|
+
console.log(`Failed to play ${I}:`, Q);
|
|
7349
7351
|
try {
|
|
7350
7352
|
l.current.setBodyMovement("idle"), console.log("Fallback to idle animation");
|
|
7351
7353
|
} catch (_) {
|
|
@@ -7355,95 +7357,95 @@ const Bt = Ke(({
|
|
|
7355
7357
|
else {
|
|
7356
7358
|
const Q = [".fbx", ".glb", ".gltf"];
|
|
7357
7359
|
let _ = !1;
|
|
7358
|
-
for (const
|
|
7360
|
+
for (const ve of Q)
|
|
7359
7361
|
try {
|
|
7360
|
-
l.current.playAnimation(
|
|
7362
|
+
l.current.playAnimation(I + ve, null, 10, 0, 0.01, F), console.log("Playing animation:", I + ve), _ = !0;
|
|
7361
7363
|
break;
|
|
7362
7364
|
} catch {
|
|
7363
|
-
console.log(`Failed to play ${
|
|
7365
|
+
console.log(`Failed to play ${I}${ve}, trying next format...`);
|
|
7364
7366
|
}
|
|
7365
7367
|
if (!_) {
|
|
7366
|
-
console.warn("Animation system not available or animation not found:",
|
|
7368
|
+
console.warn("Animation system not available or animation not found:", I);
|
|
7367
7369
|
try {
|
|
7368
7370
|
l.current.setBodyMovement("idle"), console.log("Fallback to idle animation");
|
|
7369
|
-
} catch (
|
|
7370
|
-
console.warn("Fallback animation also failed:",
|
|
7371
|
+
} catch (ve) {
|
|
7372
|
+
console.warn("Fallback animation also failed:", ve);
|
|
7371
7373
|
}
|
|
7372
7374
|
}
|
|
7373
7375
|
}
|
|
7374
7376
|
} else
|
|
7375
|
-
console.warn("Animation system not available or animation not found:",
|
|
7377
|
+
console.warn("Animation system not available or animation not found:", I);
|
|
7376
7378
|
}, []);
|
|
7377
7379
|
return Je(a, () => ({
|
|
7378
7380
|
speakText: y,
|
|
7379
7381
|
stopSpeaking: P,
|
|
7380
7382
|
setMood: L,
|
|
7381
7383
|
setTimingAdjustment: f,
|
|
7382
|
-
playAnimation:
|
|
7384
|
+
playAnimation: M,
|
|
7383
7385
|
isReady: g,
|
|
7384
7386
|
talkingHead: l.current,
|
|
7385
|
-
setBodyMovement: (
|
|
7387
|
+
setBodyMovement: (I) => {
|
|
7386
7388
|
if (l.current && l.current.setShowFullAvatar && l.current.setBodyMovement)
|
|
7387
7389
|
try {
|
|
7388
|
-
l.current.setShowFullAvatar(!0), l.current.setBodyMovement(
|
|
7389
|
-
} catch (
|
|
7390
|
-
console.warn("Error setting body movement:",
|
|
7390
|
+
l.current.setShowFullAvatar(!0), l.current.setBodyMovement(I), console.log("Body movement set with full body mode:", I);
|
|
7391
|
+
} catch (F) {
|
|
7392
|
+
console.warn("Error setting body movement:", F);
|
|
7391
7393
|
}
|
|
7392
7394
|
},
|
|
7393
|
-
setMovementIntensity: (
|
|
7395
|
+
setMovementIntensity: (I) => l.current?.setMovementIntensity(I),
|
|
7394
7396
|
playRandomDance: () => {
|
|
7395
7397
|
if (l.current && l.current.setShowFullAvatar && l.current.playRandomDance)
|
|
7396
7398
|
try {
|
|
7397
7399
|
l.current.setShowFullAvatar(!0), l.current.playRandomDance(), console.log("Random dance played with full body mode");
|
|
7398
|
-
} catch (
|
|
7399
|
-
console.warn("Error playing random dance:",
|
|
7400
|
+
} catch (I) {
|
|
7401
|
+
console.warn("Error playing random dance:", I);
|
|
7400
7402
|
}
|
|
7401
7403
|
},
|
|
7402
|
-
playReaction: (
|
|
7404
|
+
playReaction: (I) => {
|
|
7403
7405
|
if (l.current && l.current.setShowFullAvatar && l.current.playReaction)
|
|
7404
7406
|
try {
|
|
7405
|
-
l.current.setShowFullAvatar(!0), l.current.playReaction(
|
|
7406
|
-
} catch (
|
|
7407
|
-
console.warn("Error playing reaction:",
|
|
7407
|
+
l.current.setShowFullAvatar(!0), l.current.playReaction(I), console.log("Reaction played with full body mode:", I);
|
|
7408
|
+
} catch (F) {
|
|
7409
|
+
console.warn("Error playing reaction:", F);
|
|
7408
7410
|
}
|
|
7409
7411
|
},
|
|
7410
7412
|
playCelebration: () => {
|
|
7411
7413
|
if (l.current && l.current.setShowFullAvatar && l.current.playCelebration)
|
|
7412
7414
|
try {
|
|
7413
7415
|
l.current.setShowFullAvatar(!0), l.current.playCelebration(), console.log("Celebration played with full body mode");
|
|
7414
|
-
} catch (
|
|
7415
|
-
console.warn("Error playing celebration:",
|
|
7416
|
+
} catch (I) {
|
|
7417
|
+
console.warn("Error playing celebration:", I);
|
|
7416
7418
|
}
|
|
7417
7419
|
},
|
|
7418
|
-
setShowFullAvatar: (
|
|
7420
|
+
setShowFullAvatar: (I) => {
|
|
7419
7421
|
if (l.current && l.current.setShowFullAvatar)
|
|
7420
7422
|
try {
|
|
7421
|
-
l.current.setShowFullAvatar(
|
|
7422
|
-
} catch (
|
|
7423
|
-
console.warn("Error setting showFullAvatar:",
|
|
7423
|
+
l.current.setShowFullAvatar(I), console.log("Show full avatar set to:", I);
|
|
7424
|
+
} catch (F) {
|
|
7425
|
+
console.warn("Error setting showFullAvatar:", F);
|
|
7424
7426
|
}
|
|
7425
7427
|
},
|
|
7426
7428
|
lockAvatarPosition: () => {
|
|
7427
7429
|
if (l.current && l.current.lockAvatarPosition)
|
|
7428
7430
|
try {
|
|
7429
7431
|
l.current.lockAvatarPosition();
|
|
7430
|
-
} catch (
|
|
7431
|
-
console.warn("Error locking avatar position:",
|
|
7432
|
+
} catch (I) {
|
|
7433
|
+
console.warn("Error locking avatar position:", I);
|
|
7432
7434
|
}
|
|
7433
7435
|
},
|
|
7434
7436
|
unlockAvatarPosition: () => {
|
|
7435
7437
|
if (l.current && l.current.unlockAvatarPosition)
|
|
7436
7438
|
try {
|
|
7437
7439
|
l.current.unlockAvatarPosition();
|
|
7438
|
-
} catch (
|
|
7439
|
-
console.warn("Error unlocking avatar position:",
|
|
7440
|
+
} catch (I) {
|
|
7441
|
+
console.warn("Error unlocking avatar position:", I);
|
|
7440
7442
|
}
|
|
7441
7443
|
}
|
|
7442
7444
|
})), /* @__PURE__ */ Pe("div", { className: `talking-head-container ${o}`, style: s, children: [
|
|
7443
7445
|
/* @__PURE__ */ ae(
|
|
7444
7446
|
"div",
|
|
7445
7447
|
{
|
|
7446
|
-
ref:
|
|
7448
|
+
ref: u,
|
|
7447
7449
|
className: "talking-head-viewer",
|
|
7448
7450
|
style: {
|
|
7449
7451
|
width: "100%",
|
|
@@ -7452,7 +7454,7 @@ const Bt = Ke(({
|
|
|
7452
7454
|
}
|
|
7453
7455
|
}
|
|
7454
7456
|
),
|
|
7455
|
-
|
|
7457
|
+
c && /* @__PURE__ */ ae("div", { className: "loading-overlay", style: {
|
|
7456
7458
|
position: "absolute",
|
|
7457
7459
|
top: "50%",
|
|
7458
7460
|
left: "50%",
|
|
@@ -7475,7 +7477,7 @@ const Bt = Ke(({
|
|
|
7475
7477
|
}, children: h })
|
|
7476
7478
|
] });
|
|
7477
7479
|
});
|
|
7478
|
-
|
|
7480
|
+
Ot.displayName = "TalkingHeadComponent";
|
|
7479
7481
|
async function je(Z) {
|
|
7480
7482
|
try {
|
|
7481
7483
|
const n = await fetch(Z);
|
|
@@ -7506,9 +7508,9 @@ async function Dt(Z, n = "F") {
|
|
|
7506
7508
|
];
|
|
7507
7509
|
for (const a of i)
|
|
7508
7510
|
try {
|
|
7509
|
-
const
|
|
7510
|
-
if (
|
|
7511
|
-
const l = await
|
|
7511
|
+
const u = await fetch(a);
|
|
7512
|
+
if (u.ok) {
|
|
7513
|
+
const l = await u.json(), r = (Array.isArray(l) ? l : l.files || []).filter((h) => typeof h == "string" && h.toLowerCase().endsWith(".fbx")).map((h) => h.startsWith("/") ? h : `${t}/${h}`);
|
|
7512
7514
|
if (r.length > 0)
|
|
7513
7515
|
return r;
|
|
7514
7516
|
}
|
|
@@ -7527,10 +7529,10 @@ async function Dt(Z, n = "F") {
|
|
|
7527
7529
|
o === "M" ? s.push(`${t}/male`, `${t}/m`) : s.push(`${t}/female`, `${t}/f`), s.push(`${t}/shared`);
|
|
7528
7530
|
for (const i of s)
|
|
7529
7531
|
try {
|
|
7530
|
-
const a = `${i}/.list.json`,
|
|
7531
|
-
if (
|
|
7532
|
-
const l = await
|
|
7533
|
-
|
|
7532
|
+
const a = `${i}/.list.json`, u = await fetch(a);
|
|
7533
|
+
if (u.ok) {
|
|
7534
|
+
const l = await u.json(), c = (Array.isArray(l) ? l : l.files || []).filter((r) => typeof r == "string" && r.toLowerCase().endsWith(".fbx")).map((r) => r.startsWith("/") ? r : `${i}/${r}`);
|
|
7535
|
+
c.length > 0 && e.push(...c);
|
|
7534
7536
|
}
|
|
7535
7537
|
} catch {
|
|
7536
7538
|
continue;
|
|
@@ -7557,9 +7559,9 @@ const Nt = Ke(({
|
|
|
7557
7559
|
ttsService: s = null,
|
|
7558
7560
|
ttsVoice: i = null,
|
|
7559
7561
|
ttsApiKey: a = null,
|
|
7560
|
-
bodyMovement:
|
|
7562
|
+
bodyMovement: u = "idle",
|
|
7561
7563
|
movementIntensity: l = 0.5,
|
|
7562
|
-
showFullAvatar:
|
|
7564
|
+
showFullAvatar: c = !1,
|
|
7563
7565
|
cameraView: r = "upper",
|
|
7564
7566
|
onReady: h = () => {
|
|
7565
7567
|
},
|
|
@@ -7571,24 +7573,24 @@ const Nt = Ke(({
|
|
|
7571
7573
|
},
|
|
7572
7574
|
onSpeechEnd: x = () => {
|
|
7573
7575
|
},
|
|
7574
|
-
className:
|
|
7575
|
-
style:
|
|
7576
|
+
className: k = "",
|
|
7577
|
+
style: G = {},
|
|
7576
7578
|
animations: m = {},
|
|
7577
7579
|
autoAnimationGroup: D = null,
|
|
7578
7580
|
// e.g., "talking" - will randomly select from this group when speaking
|
|
7579
|
-
autoIdleGroup:
|
|
7581
|
+
autoIdleGroup: E = null,
|
|
7580
7582
|
// e.g., "idle" - will randomly select from this group when idle
|
|
7581
7583
|
autoSpeak: y = !1
|
|
7582
7584
|
}, P) => {
|
|
7583
|
-
const L =
|
|
7585
|
+
const L = V(null), f = V(null), M = V(c), I = V(null), F = V(null), B = V(!1), Q = V({ remainingText: null, originalText: null, options: null }), _ = V([]), [ve, me] = pe(!0), [Fe, ye] = pe(null), [Re, he] = pe(!1), [A, v] = pe(!1), [T, O] = pe(m), Y = V(null), K = V(!1), q = V(null), te = V(!1), fe = V([]), Ie = V([]), et = V(0), ke = V(null);
|
|
7584
7586
|
Se(() => {
|
|
7585
|
-
|
|
7586
|
-
}, [
|
|
7587
|
-
const C = U((
|
|
7587
|
+
B.current = A;
|
|
7588
|
+
}, [A]);
|
|
7589
|
+
const C = U((S) => {
|
|
7588
7590
|
let w = "F";
|
|
7589
|
-
if (
|
|
7590
|
-
const
|
|
7591
|
-
|
|
7591
|
+
if (S) {
|
|
7592
|
+
const H = S.toString().toUpperCase().trim();
|
|
7593
|
+
H === "M" || H === "MALE" ? w = "M" : (H === "F" || H === "FEMALE") && (w = "F");
|
|
7592
7594
|
}
|
|
7593
7595
|
return w === "M" ? "male" : "female";
|
|
7594
7596
|
}, []);
|
|
@@ -7597,13 +7599,13 @@ const Nt = Ke(({
|
|
|
7597
7599
|
if (m.manifest && m.auto)
|
|
7598
7600
|
try {
|
|
7599
7601
|
const w = await je(m.manifest);
|
|
7600
|
-
|
|
7602
|
+
O(w);
|
|
7601
7603
|
return;
|
|
7602
7604
|
} catch {
|
|
7603
7605
|
}
|
|
7604
7606
|
if (m.manifest && !m.auto) {
|
|
7605
|
-
const w = await je(m.manifest),
|
|
7606
|
-
|
|
7607
|
+
const w = await je(m.manifest), H = Object.keys(w).length > 0;
|
|
7608
|
+
O(H ? w : m);
|
|
7607
7609
|
} else if (m.auto)
|
|
7608
7610
|
try {
|
|
7609
7611
|
let w = null;
|
|
@@ -7613,57 +7615,57 @@ const Nt = Ke(({
|
|
|
7613
7615
|
} catch {
|
|
7614
7616
|
}
|
|
7615
7617
|
if (typeof m.auto == "string") {
|
|
7616
|
-
const
|
|
7617
|
-
talking: `${
|
|
7618
|
-
idle: `${
|
|
7619
|
-
},
|
|
7620
|
-
|
|
7621
|
-
const ie = await lt(
|
|
7622
|
-
if (!Object.values(ie).some((
|
|
7623
|
-
|
|
7618
|
+
const H = m.auto, J = {
|
|
7619
|
+
talking: `${H}/talking`,
|
|
7620
|
+
idle: `${H}/idle`
|
|
7621
|
+
}, W = C(e);
|
|
7622
|
+
J[`${W}_talking`] = `${H}/${W}/talking`, J[`${W}_idle`] = `${H}/${W}/idle`, J.shared_talking = `${H}/shared/talking`, J.shared_idle = `${H}/shared/idle`;
|
|
7623
|
+
const ie = await lt(J, e);
|
|
7624
|
+
if (!Object.values(ie).some((j) => Array.isArray(j) && j.length > 0) && w) {
|
|
7625
|
+
O(w);
|
|
7624
7626
|
return;
|
|
7625
7627
|
}
|
|
7626
|
-
const
|
|
7628
|
+
const ce = {
|
|
7627
7629
|
_genderSpecific: {
|
|
7628
|
-
[
|
|
7630
|
+
[W]: {},
|
|
7629
7631
|
shared: {}
|
|
7630
7632
|
}
|
|
7631
7633
|
};
|
|
7632
|
-
Object.entries(ie).forEach(([
|
|
7633
|
-
if (
|
|
7634
|
-
const [
|
|
7635
|
-
|
|
7634
|
+
Object.entries(ie).forEach(([j, $]) => {
|
|
7635
|
+
if (j.includes("_")) {
|
|
7636
|
+
const [ee, ...ge] = j.split("_"), de = ge.join("_");
|
|
7637
|
+
ee === "shared" ? (ce._genderSpecific.shared[de] || (ce._genderSpecific.shared[de] = []), ce._genderSpecific.shared[de].push(...$)) : ee === W && (ce._genderSpecific[W][de] || (ce._genderSpecific[W][de] = []), ce._genderSpecific[W][de].push(...$));
|
|
7636
7638
|
} else
|
|
7637
|
-
|
|
7638
|
-
}), w && (w._genderSpecific && Object.keys(w._genderSpecific).forEach((
|
|
7639
|
-
|
|
7640
|
-
|
|
7639
|
+
ce[j] = $;
|
|
7640
|
+
}), w && (w._genderSpecific && Object.keys(w._genderSpecific).forEach((j) => {
|
|
7641
|
+
ce._genderSpecific[j] || (ce._genderSpecific[j] = {}), Object.entries(w._genderSpecific[j]).forEach(([$, ee]) => {
|
|
7642
|
+
ce._genderSpecific[j][$] || (ce._genderSpecific[j][$] = ee);
|
|
7641
7643
|
});
|
|
7642
|
-
}), Object.entries(w).forEach(([
|
|
7643
|
-
|
|
7644
|
-
})),
|
|
7644
|
+
}), Object.entries(w).forEach(([j, $]) => {
|
|
7645
|
+
j !== "_genderSpecific" && !ce[j] && (ce[j] = $);
|
|
7646
|
+
})), O(ce);
|
|
7645
7647
|
} else if (typeof m.auto == "object") {
|
|
7646
|
-
const
|
|
7647
|
-
|
|
7648
|
+
const H = await lt(m.auto, e), J = Object.values(H).some((W) => Array.isArray(W) && W.length > 0);
|
|
7649
|
+
O(!J && w ? w : H);
|
|
7648
7650
|
}
|
|
7649
7651
|
} catch (w) {
|
|
7650
7652
|
if (console.error("Failed to auto-discover animations:", w), m.manifest)
|
|
7651
7653
|
try {
|
|
7652
|
-
const
|
|
7653
|
-
|
|
7654
|
+
const H = await je(m.manifest);
|
|
7655
|
+
O(H);
|
|
7654
7656
|
} catch {
|
|
7655
|
-
|
|
7657
|
+
O(m);
|
|
7656
7658
|
}
|
|
7657
7659
|
else
|
|
7658
|
-
|
|
7660
|
+
O(m);
|
|
7659
7661
|
}
|
|
7660
7662
|
else
|
|
7661
|
-
|
|
7663
|
+
O(m);
|
|
7662
7664
|
})();
|
|
7663
7665
|
}, [m, e, C]), Se(() => {
|
|
7664
|
-
|
|
7665
|
-
}, [
|
|
7666
|
-
const
|
|
7666
|
+
M.current = c;
|
|
7667
|
+
}, [c]);
|
|
7668
|
+
const X = $e(), ne = s || X.service;
|
|
7667
7669
|
let se;
|
|
7668
7670
|
ne === "browser" ? se = {
|
|
7669
7671
|
service: "browser",
|
|
@@ -7673,18 +7675,18 @@ const Nt = Ke(({
|
|
|
7673
7675
|
} : ne === "elevenlabs" ? se = {
|
|
7674
7676
|
service: "elevenlabs",
|
|
7675
7677
|
endpoint: "https://api.elevenlabs.io/v1/text-to-speech",
|
|
7676
|
-
apiKey: a ||
|
|
7677
|
-
defaultVoice: i ||
|
|
7678
|
-
voices:
|
|
7678
|
+
apiKey: a || X.apiKey,
|
|
7679
|
+
defaultVoice: i || X.defaultVoice || Ze.defaultVoice,
|
|
7680
|
+
voices: X.voices || Ze.voices
|
|
7679
7681
|
} : ne === "deepgram" ? se = {
|
|
7680
7682
|
service: "deepgram",
|
|
7681
7683
|
endpoint: "https://api.deepgram.com/v1/speak",
|
|
7682
|
-
apiKey: a ||
|
|
7683
|
-
defaultVoice: i ||
|
|
7684
|
-
voices:
|
|
7684
|
+
apiKey: a || X.apiKey,
|
|
7685
|
+
defaultVoice: i || X.defaultVoice || _e.defaultVoice,
|
|
7686
|
+
voices: X.voices || _e.voices
|
|
7685
7687
|
} : se = {
|
|
7686
|
-
...
|
|
7687
|
-
apiKey: a !== null ? a :
|
|
7688
|
+
...X,
|
|
7689
|
+
apiKey: a !== null ? a : X.apiKey
|
|
7688
7690
|
};
|
|
7689
7691
|
const ze = {
|
|
7690
7692
|
url: n,
|
|
@@ -7693,8 +7695,8 @@ const Nt = Ke(({
|
|
|
7693
7695
|
ttsLang: ne === "browser" ? "en-US" : o,
|
|
7694
7696
|
ttsVoice: i || se.defaultVoice,
|
|
7695
7697
|
lipsyncLang: "en",
|
|
7696
|
-
showFullAvatar:
|
|
7697
|
-
bodyMovement:
|
|
7698
|
+
showFullAvatar: c,
|
|
7699
|
+
bodyMovement: u,
|
|
7698
7700
|
movementIntensity: l
|
|
7699
7701
|
}, re = {
|
|
7700
7702
|
ttsEndpoint: se.endpoint,
|
|
@@ -7702,69 +7704,76 @@ const Nt = Ke(({
|
|
|
7702
7704
|
ttsService: ne,
|
|
7703
7705
|
lipsyncModules: ["en"],
|
|
7704
7706
|
cameraView: r
|
|
7705
|
-
},
|
|
7707
|
+
}, Ae = U(async () => {
|
|
7706
7708
|
if (!(!L.current || f.current))
|
|
7707
7709
|
try {
|
|
7708
7710
|
me(!0), ye(null), f.current = new nt(L.current, re), await f.current.showAvatar(ze, (w) => {
|
|
7709
7711
|
if (w.lengthComputable) {
|
|
7710
|
-
const
|
|
7711
|
-
d(
|
|
7712
|
+
const H = Math.min(100, Math.round(w.loaded / w.total * 100));
|
|
7713
|
+
d(H);
|
|
7712
7714
|
}
|
|
7713
7715
|
}), me(!1), he(!0), h(f.current);
|
|
7714
|
-
const
|
|
7716
|
+
const S = () => {
|
|
7715
7717
|
document.visibilityState === "visible" ? f.current?.start() : f.current?.stop();
|
|
7716
7718
|
};
|
|
7717
|
-
return document.addEventListener("visibilitychange",
|
|
7718
|
-
document.removeEventListener("visibilitychange",
|
|
7719
|
+
return document.addEventListener("visibilitychange", S), () => {
|
|
7720
|
+
document.removeEventListener("visibilitychange", S);
|
|
7719
7721
|
};
|
|
7720
|
-
} catch (
|
|
7721
|
-
console.error("Error initializing TalkingHead:",
|
|
7722
|
+
} catch (S) {
|
|
7723
|
+
console.error("Error initializing TalkingHead:", S), ye(S.message || "Failed to initialize avatar"), me(!1), g(S);
|
|
7722
7724
|
}
|
|
7723
7725
|
}, []);
|
|
7724
|
-
Se(() => (
|
|
7726
|
+
Se(() => (Ae(), () => {
|
|
7725
7727
|
f.current && (f.current.stop(), f.current.dispose(), f.current = null);
|
|
7726
|
-
}), [
|
|
7727
|
-
const
|
|
7728
|
+
}), [Ae]);
|
|
7729
|
+
const Ee = U(async () => {
|
|
7728
7730
|
if (f.current)
|
|
7729
7731
|
try {
|
|
7730
|
-
const
|
|
7731
|
-
|
|
7732
|
-
} catch (
|
|
7733
|
-
console.warn("Failed to resume audio context:",
|
|
7732
|
+
const S = f.current.audioCtx || f.current.audioContext;
|
|
7733
|
+
S && (S.state === "suspended" || S.state === "interrupted") && await S.resume();
|
|
7734
|
+
} catch (S) {
|
|
7735
|
+
console.warn("Failed to resume audio context:", S);
|
|
7734
7736
|
}
|
|
7735
|
-
}, []),
|
|
7736
|
-
if (!
|
|
7737
|
+
}, []), Be = U((S) => {
|
|
7738
|
+
if (!T)
|
|
7737
7739
|
return [];
|
|
7738
7740
|
let w = null;
|
|
7739
|
-
if (
|
|
7740
|
-
const
|
|
7741
|
-
|
|
7741
|
+
if (T._genderSpecific) {
|
|
7742
|
+
const H = C(e), J = T._genderSpecific[H];
|
|
7743
|
+
if (J && J[S] && Array.isArray(J[S]) && J[S].length > 0 && (w = J[S]), !w && T._genderSpecific.shared && T._genderSpecific.shared[S]) {
|
|
7744
|
+
const W = T._genderSpecific.shared[S];
|
|
7745
|
+
Array.isArray(W) && W.length > 0 && (w = W);
|
|
7746
|
+
}
|
|
7742
7747
|
}
|
|
7743
|
-
|
|
7744
|
-
|
|
7745
|
-
|
|
7746
|
-
|
|
7747
|
-
|
|
7748
|
-
|
|
7748
|
+
if (!w && T[S]) {
|
|
7749
|
+
const H = T[S];
|
|
7750
|
+
Array.isArray(H) && H.length > 0 ? w = H : typeof H == "string" && (w = [H]);
|
|
7751
|
+
}
|
|
7752
|
+
return !w || Array.isArray(w) && w.length === 0 ? ((Object.keys(T).length > 0 || T._genderSpecific && Object.keys(T._genderSpecific).length > 0) && console.warn(`⚠️ No animations found for group "${S}" (gender: ${C(e)}). Make sure animations are configured correctly.`), []) : Array.isArray(w) ? [...w] : typeof w == "string" ? [w] : [];
|
|
7753
|
+
}, [T, e, C]), He = U((S) => {
|
|
7754
|
+
const w = [...S];
|
|
7755
|
+
for (let H = w.length - 1; H > 0; H--) {
|
|
7756
|
+
const J = Math.floor(Math.random() * (H + 1));
|
|
7757
|
+
[w[H], w[J]] = [w[J], w[H]];
|
|
7749
7758
|
}
|
|
7750
7759
|
return w;
|
|
7751
|
-
}, []), we = U((
|
|
7752
|
-
if (
|
|
7753
|
-
const
|
|
7754
|
-
if (
|
|
7760
|
+
}, []), we = U((S) => {
|
|
7761
|
+
if (Ie.current.length === 0) {
|
|
7762
|
+
const H = Be(S);
|
|
7763
|
+
if (H.length === 0)
|
|
7755
7764
|
return null;
|
|
7756
|
-
|
|
7765
|
+
Ie.current = He(H), fe.current = [];
|
|
7757
7766
|
}
|
|
7758
|
-
const w =
|
|
7767
|
+
const w = Ie.current.shift();
|
|
7759
7768
|
return w && fe.current.push(w), w;
|
|
7760
|
-
}, [
|
|
7761
|
-
if (!f.current || !K.current || q.current !==
|
|
7769
|
+
}, [Be, He]), We = U((S) => S ? S.split("/").pop().replace(".fbx", "").replace(/[-_]/g, " ") : "Unknown", []), Oe = U((S, w = !1, H = null) => {
|
|
7770
|
+
if (!f.current || !K.current || q.current !== S)
|
|
7762
7771
|
return null;
|
|
7763
|
-
const
|
|
7764
|
-
if (
|
|
7772
|
+
const J = we(S);
|
|
7773
|
+
if (J)
|
|
7765
7774
|
try {
|
|
7766
|
-
const
|
|
7767
|
-
console.log(`🎬 Playing animation: "${
|
|
7775
|
+
const W = We(J);
|
|
7776
|
+
console.log(`🎬 Playing animation: "${W}"`);
|
|
7768
7777
|
const ie = () => {
|
|
7769
7778
|
console.log("🎬 Animation finished, checking if should continue...");
|
|
7770
7779
|
const le = () => {
|
|
@@ -7772,64 +7781,64 @@ const Nt = Ke(({
|
|
|
7772
7781
|
return console.log("🎬 No talkingHeadRef, stopping animations"), !1;
|
|
7773
7782
|
if (!K.current)
|
|
7774
7783
|
return console.log("🎬 isSpeakingRef is false, stopping animations"), !1;
|
|
7775
|
-
if (q.current !==
|
|
7776
|
-
return console.log(`🎬 Animation group mismatch (${q.current} !== ${
|
|
7777
|
-
const
|
|
7784
|
+
if (q.current !== S)
|
|
7785
|
+
return console.log(`🎬 Animation group mismatch (${q.current} !== ${S}), stopping animations`), !1;
|
|
7786
|
+
const j = f.current, $ = j.isAudioPlaying === !0, ee = j.audioPlaylist && j.audioPlaylist.length > 0, ge = j.speechQueue && j.speechQueue.length > 0, de = j.isSpeaking === !0, Ge = de || $ || ee || ge;
|
|
7778
7787
|
return console.log("🎬 Still speaking check:", {
|
|
7779
7788
|
isSpeakingRef: K.current,
|
|
7780
7789
|
isTalkingHeadSpeaking: de,
|
|
7781
|
-
hasAudioPlaying:
|
|
7782
|
-
hasAudioInPlaylist:
|
|
7790
|
+
hasAudioPlaying: $,
|
|
7791
|
+
hasAudioInPlaylist: ee,
|
|
7783
7792
|
hasItemsInQueue: ge,
|
|
7784
7793
|
shouldContinue: Ge
|
|
7785
7794
|
}), Ge;
|
|
7786
7795
|
};
|
|
7787
7796
|
le() ? (console.log("🎬 Still speaking, continuing to next animation..."), requestAnimationFrame(() => {
|
|
7788
|
-
le() ? (console.log("🎬 Playing next animation..."),
|
|
7789
|
-
})) : (console.log("🎬 Speech has ended, stopping animations"), K.current = !1, q.current = null,
|
|
7797
|
+
le() ? (console.log("🎬 Playing next animation..."), Oe(S, w, H)) : (console.log("🎬 Speech ended, stopping animations"), K.current = !1, q.current = null, H && H());
|
|
7798
|
+
})) : (console.log("🎬 Speech has ended, stopping animations"), K.current = !1, q.current = null, H && H());
|
|
7790
7799
|
};
|
|
7791
|
-
return f.current.playAnimation(
|
|
7792
|
-
} catch (
|
|
7793
|
-
return console.error("Failed to play animation:",
|
|
7800
|
+
return f.current.playAnimation(J, null, 0, 0, 0.01, w, ie), J;
|
|
7801
|
+
} catch (W) {
|
|
7802
|
+
return console.error("Failed to play animation:", W), null;
|
|
7794
7803
|
}
|
|
7795
7804
|
else {
|
|
7796
|
-
const
|
|
7797
|
-
if (!f.current || !K.current || q.current !==
|
|
7805
|
+
const W = () => {
|
|
7806
|
+
if (!f.current || !K.current || q.current !== S)
|
|
7798
7807
|
return !1;
|
|
7799
|
-
const le = f.current,
|
|
7800
|
-
return le.isSpeaking === !0 ||
|
|
7808
|
+
const le = f.current, ce = le.isAudioPlaying === !0, j = le.audioPlaylist && le.audioPlaylist.length > 0, $ = le.speechQueue && le.speechQueue.length > 0;
|
|
7809
|
+
return le.isSpeaking === !0 || ce || j || $;
|
|
7801
7810
|
};
|
|
7802
|
-
|
|
7811
|
+
W() && (Ie.current = [], fe.current = [], W() ? Oe(S, w, H) : (K.current = !1, q.current = null));
|
|
7803
7812
|
}
|
|
7804
7813
|
return null;
|
|
7805
|
-
}, [we, We]), Ve = U(async (
|
|
7806
|
-
if (!f.current || !Re || !
|
|
7814
|
+
}, [we, We]), Ve = U(async (S, w = {}) => {
|
|
7815
|
+
if (!f.current || !Re || !S || S.trim() === "")
|
|
7807
7816
|
return;
|
|
7808
|
-
await
|
|
7809
|
-
const
|
|
7810
|
-
|
|
7817
|
+
await Ee();
|
|
7818
|
+
const H = w.animationGroup || D;
|
|
7819
|
+
H && !w.skipAnimation && (K.current = !0, q.current = H, Ie.current = [], fe.current = [], Oe(H));
|
|
7811
7820
|
try {
|
|
7812
|
-
R(
|
|
7821
|
+
R(S), w.onSpeechStart && w.onSpeechStart(S);
|
|
7813
7822
|
} catch (ie) {
|
|
7814
7823
|
console.warn("Error in onSpeechStart callback:", ie);
|
|
7815
7824
|
}
|
|
7816
|
-
Q.current = { remainingText: null, originalText: null, options: null }, _.current = [],
|
|
7817
|
-
const
|
|
7818
|
-
_.current =
|
|
7819
|
-
const
|
|
7825
|
+
Q.current = { remainingText: null, originalText: null, options: null }, _.current = [], I.current = { text: S, options: w }, F.current && (clearInterval(F.current), F.current = null), v(!1), B.current = !1, te.current = !1;
|
|
7826
|
+
const J = S.split(/[.!?]+/).filter((ie) => ie.trim().length > 0);
|
|
7827
|
+
_.current = J, et.current = 0;
|
|
7828
|
+
const W = {
|
|
7820
7829
|
lipsyncLang: w.lipsyncLang || "en"
|
|
7821
7830
|
};
|
|
7822
7831
|
if (f.current) {
|
|
7823
7832
|
const ie = f.current;
|
|
7824
7833
|
let le = 0;
|
|
7825
|
-
const
|
|
7826
|
-
|
|
7827
|
-
const
|
|
7828
|
-
if (le++,
|
|
7834
|
+
const ce = 1200;
|
|
7835
|
+
F.current && (clearInterval(F.current), F.current = null);
|
|
7836
|
+
const j = { current: !1 }, $ = setInterval(() => {
|
|
7837
|
+
if (le++, B.current)
|
|
7829
7838
|
return;
|
|
7830
|
-
if (le >
|
|
7831
|
-
if (
|
|
7832
|
-
|
|
7839
|
+
if (le > ce) {
|
|
7840
|
+
if ($ && (clearInterval($), F.current = null), !j.current && !B.current) {
|
|
7841
|
+
j.current = !0, K.current = !1, q.current = null, Ie.current = [], fe.current = [], f.current && (f.current.isSpeaking = !1);
|
|
7833
7842
|
try {
|
|
7834
7843
|
w.onSpeechEnd && w.onSpeechEnd(), x();
|
|
7835
7844
|
} catch (Te) {
|
|
@@ -7838,12 +7847,12 @@ const Nt = Ke(({
|
|
|
7838
7847
|
}
|
|
7839
7848
|
return;
|
|
7840
7849
|
}
|
|
7841
|
-
const
|
|
7842
|
-
ie && !
|
|
7850
|
+
const ee = !ie.speechQueue || ie.speechQueue.length === 0, ge = !ie.audioPlaylist || ie.audioPlaylist.length === 0, de = ie.isAudioPlaying === !1;
|
|
7851
|
+
ie && !B.current && ee && ge && de && ie.isSpeaking === !1 && !j.current && !B.current && setTimeout(() => {
|
|
7843
7852
|
const Te = f.current;
|
|
7844
7853
|
if (!Te)
|
|
7845
7854
|
return;
|
|
7846
|
-
!
|
|
7855
|
+
!B.current && (!Te.speechQueue || Te.speechQueue.length === 0) && (!Te.audioPlaylist || Te.audioPlaylist.length === 0) && Te.isAudioPlaying === !1 && Te.isSpeaking === !1 && !j.current && !B.current && (j.current = !0, $ && (clearInterval($), F.current = null), K.current = !1, q.current = null, Ie.current = [], fe.current = [], te.current = !0, Te && (Te.isSpeaking = !1), setTimeout(() => {
|
|
7847
7856
|
try {
|
|
7848
7857
|
w.onSpeechEnd && w.onSpeechEnd(), x(), setTimeout(() => {
|
|
7849
7858
|
te.current = !1;
|
|
@@ -7854,90 +7863,90 @@ const Nt = Ke(({
|
|
|
7854
7863
|
}, 100));
|
|
7855
7864
|
}, 200);
|
|
7856
7865
|
}, 50);
|
|
7857
|
-
|
|
7866
|
+
F.current = $;
|
|
7858
7867
|
}
|
|
7859
7868
|
try {
|
|
7860
|
-
f.current.speakText(
|
|
7869
|
+
f.current.speakText(S, W);
|
|
7861
7870
|
} catch (ie) {
|
|
7862
7871
|
console.error("Error speaking text:", ie), ye(ie.message || "Failed to speak text");
|
|
7863
7872
|
}
|
|
7864
|
-
}, [Re, x,
|
|
7873
|
+
}, [Re, x, Ee, D, Oe]);
|
|
7865
7874
|
Se(() => {
|
|
7866
|
-
if (!Re || !
|
|
7875
|
+
if (!Re || !E || !f.current)
|
|
7867
7876
|
return;
|
|
7868
7877
|
Y.current && clearInterval(Y.current);
|
|
7869
|
-
const
|
|
7870
|
-
f.current && !
|
|
7878
|
+
const S = () => {
|
|
7879
|
+
f.current && !B.current && Oe(E);
|
|
7871
7880
|
};
|
|
7872
|
-
return
|
|
7873
|
-
|
|
7881
|
+
return S(), Y.current = setInterval(() => {
|
|
7882
|
+
S();
|
|
7874
7883
|
}, 12e3 + Math.random() * 3e3), () => {
|
|
7875
7884
|
Y.current && (clearInterval(Y.current), Y.current = null);
|
|
7876
7885
|
};
|
|
7877
|
-
}, [Re,
|
|
7878
|
-
Re && Z && y && f.current && !K.current && !
|
|
7886
|
+
}, [Re, E, Oe]), Se(() => {
|
|
7887
|
+
Re && Z && y && f.current && !K.current && !B.current && !te.current && Ve(Z);
|
|
7879
7888
|
}, [Re, Z, y, Ve]);
|
|
7880
7889
|
const tt = U(() => {
|
|
7881
7890
|
if (f.current)
|
|
7882
7891
|
try {
|
|
7883
|
-
const
|
|
7884
|
-
if (
|
|
7885
|
-
|
|
7886
|
-
const
|
|
7887
|
-
let
|
|
7892
|
+
const S = f.current.isSpeaking || !1, w = [...f.current.audioPlaylist || []], H = [...f.current.speechQueue || []];
|
|
7893
|
+
if (S || w.length > 0 || H.length > 0) {
|
|
7894
|
+
F.current && (clearInterval(F.current), F.current = null);
|
|
7895
|
+
const J = _.current;
|
|
7896
|
+
let W = [];
|
|
7888
7897
|
const ie = f.current.isAudioPlaying || !1;
|
|
7889
|
-
if (
|
|
7890
|
-
const
|
|
7891
|
-
Ge <
|
|
7898
|
+
if (J.length > 0) {
|
|
7899
|
+
const ee = w.length + H.length, ge = ie ? 1 : 0, de = J.length - ee - ge, Ge = ie ? de : de + ge;
|
|
7900
|
+
Ge < J.length && (W = J.slice(Ge));
|
|
7892
7901
|
} else
|
|
7893
|
-
w.length > 0 && w.forEach((
|
|
7894
|
-
if (
|
|
7895
|
-
if (Array.isArray(
|
|
7896
|
-
const ge =
|
|
7897
|
-
ge.trim() &&
|
|
7898
|
-
} else
|
|
7899
|
-
}),
|
|
7900
|
-
if (
|
|
7901
|
-
if (Array.isArray(
|
|
7902
|
-
const ge =
|
|
7903
|
-
ge.trim() &&
|
|
7904
|
-
} else
|
|
7902
|
+
w.length > 0 && w.forEach((ee) => {
|
|
7903
|
+
if (ee.text)
|
|
7904
|
+
if (Array.isArray(ee.text)) {
|
|
7905
|
+
const ge = ee.text.map((de) => de.word).join(" ");
|
|
7906
|
+
ge.trim() && W.push(ge);
|
|
7907
|
+
} else ee.text.trim() && W.push(ee.text);
|
|
7908
|
+
}), H.length > 0 && H.forEach((ee) => {
|
|
7909
|
+
if (ee.text)
|
|
7910
|
+
if (Array.isArray(ee.text)) {
|
|
7911
|
+
const ge = ee.text.map((de) => de.word).join(" ");
|
|
7912
|
+
ge.trim() && W.push(ge);
|
|
7913
|
+
} else ee.text.trim() && W.push(ee.text);
|
|
7905
7914
|
});
|
|
7906
|
-
const le =
|
|
7915
|
+
const le = W.join(" ");
|
|
7907
7916
|
Q.current = {
|
|
7908
7917
|
remainingText: le || null,
|
|
7909
|
-
originalText:
|
|
7910
|
-
options:
|
|
7918
|
+
originalText: I.current?.text || null,
|
|
7919
|
+
options: I.current?.options || null,
|
|
7911
7920
|
// Track if we're pausing mid-sentence (has currently playing audio)
|
|
7912
7921
|
isMidSentence: w.length > 0
|
|
7913
7922
|
};
|
|
7914
|
-
const
|
|
7923
|
+
const j = f.current.isAudioPlaying || !1 ? [...f.current.speechQueue || []] : null;
|
|
7915
7924
|
f.current.speechQueue.length = 0;
|
|
7916
|
-
const
|
|
7917
|
-
f.current.isSpeaking = !1,
|
|
7925
|
+
const $ = f.current.pauseSpeaking();
|
|
7926
|
+
f.current.isSpeaking = !1, K.current = !1, q.current = null, $ && $.audio && j ? (ke.current = $, ke.current.savedSpeechQueue = j) : ke.current = $, v(!0), B.current = !0;
|
|
7918
7927
|
}
|
|
7919
|
-
} catch (
|
|
7920
|
-
console.warn("Error pausing speech:",
|
|
7928
|
+
} catch (S) {
|
|
7929
|
+
console.warn("Error pausing speech:", S);
|
|
7921
7930
|
}
|
|
7922
7931
|
}, []), ht = U(async () => {
|
|
7923
|
-
if (!(!f.current || !
|
|
7932
|
+
if (!(!f.current || !A))
|
|
7924
7933
|
try {
|
|
7925
|
-
if (await
|
|
7934
|
+
if (await Ee(), v(!1), B.current = !1, ke.current && ke.current.audio) {
|
|
7926
7935
|
K.current = !0;
|
|
7927
|
-
const
|
|
7936
|
+
const W = Q.current?.options || I.current?.options || {}, ie = W.animationGroup || D;
|
|
7928
7937
|
if (ie && (q.current = ie), ke.current.savedSpeechQueue && (f.current.speechQueue.length = 0, f.current.speechQueue.push(...ke.current.savedSpeechQueue)), f.current.isSpeaking = !0, f.current) {
|
|
7929
7938
|
const le = f.current;
|
|
7930
|
-
let
|
|
7931
|
-
const
|
|
7932
|
-
|
|
7933
|
-
const
|
|
7934
|
-
if (
|
|
7939
|
+
let ce = 0;
|
|
7940
|
+
const j = 1200, $ = { current: !1 };
|
|
7941
|
+
F.current && (clearInterval(F.current), F.current = null);
|
|
7942
|
+
const ee = setInterval(() => {
|
|
7943
|
+
if (ce++, B.current)
|
|
7935
7944
|
return;
|
|
7936
|
-
if (
|
|
7937
|
-
if (
|
|
7938
|
-
|
|
7945
|
+
if (ce > j) {
|
|
7946
|
+
if (ee && (clearInterval(ee), F.current = null), !$.current && !B.current) {
|
|
7947
|
+
$.current = !0, K.current = !1, q.current = null, Ie.current = [], fe.current = [], f.current && (f.current.isSpeaking = !1);
|
|
7939
7948
|
try {
|
|
7940
|
-
|
|
7949
|
+
W.onSpeechEnd && W.onSpeechEnd(), x();
|
|
7941
7950
|
} catch (Me) {
|
|
7942
7951
|
console.error("Error in onSpeechEnd callback (timeout):", Me);
|
|
7943
7952
|
}
|
|
@@ -7945,12 +7954,12 @@ const Nt = Ke(({
|
|
|
7945
7954
|
return;
|
|
7946
7955
|
}
|
|
7947
7956
|
const ge = !le.speechQueue || le.speechQueue.length === 0, de = !le.audioPlaylist || le.audioPlaylist.length === 0, Ge = le.isAudioPlaying === !1;
|
|
7948
|
-
le && !
|
|
7957
|
+
le && !B.current && ge && de && Ge && le.isSpeaking === !1 && !$.current && !B.current && setTimeout(() => {
|
|
7949
7958
|
const Me = f.current;
|
|
7950
7959
|
if (!Me) return;
|
|
7951
|
-
!
|
|
7960
|
+
!B.current && (!Me.speechQueue || Me.speechQueue.length === 0) && (!Me.audioPlaylist || Me.audioPlaylist.length === 0) && Me.isAudioPlaying === !1 && Me.isSpeaking === !1 && !$.current && !B.current && ($.current = !0, ee && (clearInterval(ee), F.current = null), K.current = !1, q.current = null, Ie.current = [], fe.current = [], te.current = !0, Me && (Me.isSpeaking = !1), setTimeout(() => {
|
|
7952
7961
|
try {
|
|
7953
|
-
|
|
7962
|
+
W.onSpeechEnd && W.onSpeechEnd(), x(), setTimeout(() => {
|
|
7954
7963
|
te.current = !1;
|
|
7955
7964
|
}, 500);
|
|
7956
7965
|
} catch (mt) {
|
|
@@ -7959,23 +7968,23 @@ const Nt = Ke(({
|
|
|
7959
7968
|
}, 100));
|
|
7960
7969
|
}, 200);
|
|
7961
7970
|
}, 50);
|
|
7962
|
-
|
|
7971
|
+
F.current = ee;
|
|
7963
7972
|
}
|
|
7964
|
-
await f.current.playAudio(!1, ke.current), ie && !
|
|
7973
|
+
await f.current.playAudio(!1, ke.current), ie && !W.skipAnimation && (Ie.current = [], fe.current = [], Oe(ie)), ke.current = null;
|
|
7965
7974
|
return;
|
|
7966
7975
|
}
|
|
7967
|
-
const
|
|
7968
|
-
|
|
7969
|
-
} catch (
|
|
7970
|
-
console.warn("Error resuming speech:",
|
|
7976
|
+
const S = Q.current?.remainingText, w = Q.current?.originalText || I.current?.text, H = Q.current?.options || I.current?.options || {}, J = S || w;
|
|
7977
|
+
J && Ve(J, H), ke.current = null;
|
|
7978
|
+
} catch (S) {
|
|
7979
|
+
console.warn("Error resuming speech:", S), v(!1), B.current = !1, ke.current = null;
|
|
7971
7980
|
}
|
|
7972
|
-
}, [
|
|
7981
|
+
}, [A, Ve, Ee, D, Oe]), dt = U(() => {
|
|
7973
7982
|
if (f.current) {
|
|
7974
|
-
f.current.stopSpeaking(),
|
|
7983
|
+
f.current.stopSpeaking(), F.current && (clearInterval(F.current), F.current = null), K.current = !1, q.current = null, Ie.current = [], fe.current = [], v(!1), B.current = !1;
|
|
7975
7984
|
try {
|
|
7976
7985
|
x();
|
|
7977
|
-
} catch (
|
|
7978
|
-
console.warn("Error in onSpeechEnd callback (stopSpeaking):",
|
|
7986
|
+
} catch (S) {
|
|
7987
|
+
console.warn("Error in onSpeechEnd callback (stopSpeaking):", S);
|
|
7979
7988
|
}
|
|
7980
7989
|
}
|
|
7981
7990
|
}, [x]);
|
|
@@ -7984,25 +7993,25 @@ const Nt = Ke(({
|
|
|
7984
7993
|
pauseSpeaking: tt,
|
|
7985
7994
|
resumeSpeaking: ht,
|
|
7986
7995
|
stopSpeaking: dt,
|
|
7987
|
-
resumeAudioContext:
|
|
7988
|
-
isPaused: () =>
|
|
7989
|
-
setMood: (
|
|
7990
|
-
setBodyMovement: (
|
|
7991
|
-
f.current && f.current.setBodyMovement(
|
|
7996
|
+
resumeAudioContext: Ee,
|
|
7997
|
+
isPaused: () => A,
|
|
7998
|
+
setMood: (S) => f.current?.setMood(S),
|
|
7999
|
+
setBodyMovement: (S) => {
|
|
8000
|
+
f.current && f.current.setBodyMovement(S);
|
|
7992
8001
|
},
|
|
7993
|
-
playAnimation: (
|
|
7994
|
-
f.current && f.current.playAnimation && f.current.playAnimation(
|
|
8002
|
+
playAnimation: (S, w = !1) => {
|
|
8003
|
+
f.current && f.current.playAnimation && f.current.playAnimation(S, null, 10, 0, 0.01, w);
|
|
7995
8004
|
},
|
|
7996
|
-
playRandomAnimation: (
|
|
7997
|
-
getRandomAnimation: (
|
|
7998
|
-
playReaction: (
|
|
8005
|
+
playRandomAnimation: (S, w = !1) => Oe(S, w),
|
|
8006
|
+
getRandomAnimation: (S) => getRandomAnimation(S),
|
|
8007
|
+
playReaction: (S) => f.current?.playReaction(S),
|
|
7999
8008
|
playCelebration: () => f.current?.playCelebration(),
|
|
8000
|
-
setShowFullAvatar: (
|
|
8001
|
-
f.current && (
|
|
8009
|
+
setShowFullAvatar: (S) => {
|
|
8010
|
+
f.current && (M.current = S, f.current.setShowFullAvatar(S));
|
|
8002
8011
|
},
|
|
8003
8012
|
isReady: Re,
|
|
8004
8013
|
talkingHead: f.current
|
|
8005
|
-
})), /* @__PURE__ */ Pe("div", { className: `simple-talking-avatar-container ${
|
|
8014
|
+
})), /* @__PURE__ */ Pe("div", { className: `simple-talking-avatar-container ${k}`, style: G, children: [
|
|
8006
8015
|
/* @__PURE__ */ ae(
|
|
8007
8016
|
"div",
|
|
8008
8017
|
{
|
|
@@ -8015,7 +8024,7 @@ const Nt = Ke(({
|
|
|
8015
8024
|
}
|
|
8016
8025
|
}
|
|
8017
8026
|
),
|
|
8018
|
-
|
|
8027
|
+
ve && /* @__PURE__ */ ae("div", { className: "loading-overlay", style: {
|
|
8019
8028
|
position: "absolute",
|
|
8020
8029
|
top: "50%",
|
|
8021
8030
|
left: "50%",
|
|
@@ -8024,7 +8033,7 @@ const Nt = Ke(({
|
|
|
8024
8033
|
fontSize: "18px",
|
|
8025
8034
|
zIndex: 10
|
|
8026
8035
|
}, children: "Loading avatar..." }),
|
|
8027
|
-
|
|
8036
|
+
Fe && /* @__PURE__ */ ae("div", { className: "error-overlay", style: {
|
|
8028
8037
|
position: "absolute",
|
|
8029
8038
|
top: "50%",
|
|
8030
8039
|
left: "50%",
|
|
@@ -8035,7 +8044,7 @@ const Nt = Ke(({
|
|
|
8035
8044
|
zIndex: 10,
|
|
8036
8045
|
padding: "20px",
|
|
8037
8046
|
borderRadius: "8px"
|
|
8038
|
-
}, children:
|
|
8047
|
+
}, children: Fe })
|
|
8039
8048
|
] });
|
|
8040
8049
|
});
|
|
8041
8050
|
Nt.displayName = "SimpleTalkingAvatar";
|
|
@@ -8053,9 +8062,9 @@ const Ut = Ke(({
|
|
|
8053
8062
|
},
|
|
8054
8063
|
onCustomAction: a = () => {
|
|
8055
8064
|
},
|
|
8056
|
-
autoStart:
|
|
8065
|
+
autoStart: u = !1
|
|
8057
8066
|
}, l) => {
|
|
8058
|
-
const
|
|
8067
|
+
const c = V(null), r = V({
|
|
8059
8068
|
currentModuleIndex: 0,
|
|
8060
8069
|
currentLessonIndex: 0,
|
|
8061
8070
|
currentQuestionIndex: 0,
|
|
@@ -8065,18 +8074,18 @@ const Ut = Ke(({
|
|
|
8065
8074
|
curriculumCompleted: !1,
|
|
8066
8075
|
score: 0,
|
|
8067
8076
|
totalQuestions: 0
|
|
8068
|
-
}), h =
|
|
8077
|
+
}), h = V({
|
|
8069
8078
|
onLessonStart: t,
|
|
8070
8079
|
onLessonComplete: o,
|
|
8071
8080
|
onQuestionAnswer: s,
|
|
8072
8081
|
onCurriculumComplete: i,
|
|
8073
8082
|
onCustomAction: a
|
|
8074
|
-
}), d =
|
|
8083
|
+
}), d = V(null), g = V(null), R = V(null), x = V(null), k = V(null), G = V(null), m = V(null), D = V(Z?.curriculum || {
|
|
8075
8084
|
title: "Default Curriculum",
|
|
8076
8085
|
description: "No curriculum data provided",
|
|
8077
8086
|
language: "en",
|
|
8078
8087
|
modules: []
|
|
8079
|
-
}),
|
|
8088
|
+
}), E = V({
|
|
8080
8089
|
avatarUrl: n.avatarUrl || "/avatars/brunette.glb",
|
|
8081
8090
|
avatarBody: n.avatarBody || "F",
|
|
8082
8091
|
mood: n.mood || "happy",
|
|
@@ -8104,7 +8113,7 @@ const Ut = Ke(({
|
|
|
8104
8113
|
description: "No curriculum data provided",
|
|
8105
8114
|
language: "en",
|
|
8106
8115
|
modules: []
|
|
8107
|
-
},
|
|
8116
|
+
}, E.current = {
|
|
8108
8117
|
avatarUrl: n.avatarUrl || "/avatars/brunette.glb",
|
|
8109
8118
|
avatarBody: n.avatarBody || "F",
|
|
8110
8119
|
mood: n.mood || "happy",
|
|
@@ -8119,32 +8128,32 @@ const Ut = Ke(({
|
|
|
8119
8128
|
lipsyncLang: "en"
|
|
8120
8129
|
};
|
|
8121
8130
|
}, [Z, n, e]);
|
|
8122
|
-
const y = U(() => (D.current || { modules: [] }).modules[r.current.currentModuleIndex]?.lessons[r.current.currentLessonIndex], []), P = U(() => y()?.questions[r.current.currentQuestionIndex], [y]), L = U((
|
|
8131
|
+
const y = U(() => (D.current || { modules: [] }).modules[r.current.currentModuleIndex]?.lessons[r.current.currentLessonIndex], []), P = U(() => y()?.questions[r.current.currentQuestionIndex], [y]), L = U((A, v) => v.type === "multiple_choice" || v.type === "true_false" ? A === v.answer : v.type === "code_test" && typeof A == "object" && A !== null ? A.passed === !0 : !1, []), f = U(() => {
|
|
8123
8132
|
r.current.lessonCompleted = !0, r.current.isQuestionMode = !1;
|
|
8124
|
-
const
|
|
8125
|
-
let
|
|
8126
|
-
if (r.current.totalQuestions > 0 ?
|
|
8133
|
+
const A = r.current.totalQuestions > 0 ? Math.round(r.current.score / r.current.totalQuestions * 100) : 100;
|
|
8134
|
+
let v = "Congratulations! You've completed this lesson";
|
|
8135
|
+
if (r.current.totalQuestions > 0 ? v += ` You got ${r.current.score} correct out of ${r.current.totalQuestions} question${r.current.totalQuestions === 1 ? "" : "s"}, achieving a score of ${A} percent. ` : v += "! ", A >= 80 ? v += "Excellent work! You have a great understanding of this topic." : A >= 60 ? v += "Good job! You understand most of the concepts." : v += "Keep practicing! You're making progress.", h.current.onLessonComplete({
|
|
8127
8136
|
moduleIndex: r.current.currentModuleIndex,
|
|
8128
8137
|
lessonIndex: r.current.currentLessonIndex,
|
|
8129
8138
|
score: r.current.score,
|
|
8130
8139
|
totalQuestions: r.current.totalQuestions,
|
|
8131
|
-
percentage:
|
|
8140
|
+
percentage: A
|
|
8132
8141
|
}), h.current.onCustomAction({
|
|
8133
8142
|
type: "lessonComplete",
|
|
8134
8143
|
moduleIndex: r.current.currentModuleIndex,
|
|
8135
8144
|
lessonIndex: r.current.currentLessonIndex,
|
|
8136
8145
|
score: r.current.score,
|
|
8137
8146
|
totalQuestions: r.current.totalQuestions,
|
|
8138
|
-
percentage:
|
|
8139
|
-
}),
|
|
8140
|
-
if (
|
|
8147
|
+
percentage: A
|
|
8148
|
+
}), c.current) {
|
|
8149
|
+
if (c.current.setMood("happy"), e.lessonComplete)
|
|
8141
8150
|
try {
|
|
8142
|
-
|
|
8151
|
+
c.current.playAnimation(e.lessonComplete, !0);
|
|
8143
8152
|
} catch {
|
|
8144
|
-
|
|
8153
|
+
c.current.playCelebration();
|
|
8145
8154
|
}
|
|
8146
|
-
const
|
|
8147
|
-
|
|
8155
|
+
const T = D.current || { modules: [] }, O = T.modules[r.current.currentModuleIndex], Y = r.current.currentLessonIndex < (O?.lessons?.length || 0) - 1, K = r.current.currentModuleIndex < (T.modules?.length || 0) - 1, q = Y || K, te = E.current || { lipsyncLang: "en" };
|
|
8156
|
+
c.current.speakText(v, {
|
|
8148
8157
|
lipsyncLang: te.lipsyncLang,
|
|
8149
8158
|
onSpeechEnd: () => {
|
|
8150
8159
|
h.current.onCustomAction({
|
|
@@ -8153,118 +8162,118 @@ const Ut = Ke(({
|
|
|
8153
8162
|
lessonIndex: r.current.currentLessonIndex,
|
|
8154
8163
|
score: r.current.score,
|
|
8155
8164
|
totalQuestions: r.current.totalQuestions,
|
|
8156
|
-
percentage:
|
|
8165
|
+
percentage: A,
|
|
8157
8166
|
hasNextLesson: q
|
|
8158
8167
|
});
|
|
8159
8168
|
}
|
|
8160
8169
|
});
|
|
8161
8170
|
}
|
|
8162
|
-
}, [e.lessonComplete]),
|
|
8171
|
+
}, [e.lessonComplete]), M = U(() => {
|
|
8163
8172
|
r.current.curriculumCompleted = !0;
|
|
8164
|
-
const
|
|
8173
|
+
const A = D.current || { modules: [] };
|
|
8165
8174
|
if (h.current.onCurriculumComplete({
|
|
8166
|
-
modules:
|
|
8167
|
-
totalLessons:
|
|
8168
|
-
}),
|
|
8169
|
-
if (
|
|
8175
|
+
modules: A.modules.length,
|
|
8176
|
+
totalLessons: A.modules.reduce((v, T) => v + T.lessons.length, 0)
|
|
8177
|
+
}), c.current) {
|
|
8178
|
+
if (c.current.setMood("celebrating"), e.curriculumComplete)
|
|
8170
8179
|
try {
|
|
8171
|
-
|
|
8180
|
+
c.current.playAnimation(e.curriculumComplete, !0);
|
|
8172
8181
|
} catch {
|
|
8173
|
-
|
|
8182
|
+
c.current.playCelebration();
|
|
8174
8183
|
}
|
|
8175
|
-
const
|
|
8176
|
-
|
|
8184
|
+
const v = E.current || { lipsyncLang: "en" };
|
|
8185
|
+
c.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 });
|
|
8177
8186
|
}
|
|
8178
|
-
}, [e.curriculumComplete]),
|
|
8179
|
-
const
|
|
8180
|
-
r.current.isQuestionMode = !0, r.current.currentQuestionIndex = 0, r.current.totalQuestions =
|
|
8181
|
-
const
|
|
8182
|
-
|
|
8187
|
+
}, [e.curriculumComplete]), I = U(() => {
|
|
8188
|
+
const A = y();
|
|
8189
|
+
r.current.isQuestionMode = !0, r.current.currentQuestionIndex = 0, r.current.totalQuestions = A?.questions?.length || 0, r.current.score = 0;
|
|
8190
|
+
const v = P();
|
|
8191
|
+
v && h.current.onCustomAction({
|
|
8183
8192
|
type: "questionStart",
|
|
8184
8193
|
moduleIndex: r.current.currentModuleIndex,
|
|
8185
8194
|
lessonIndex: r.current.currentLessonIndex,
|
|
8186
8195
|
questionIndex: r.current.currentQuestionIndex,
|
|
8187
8196
|
totalQuestions: r.current.totalQuestions,
|
|
8188
|
-
question:
|
|
8197
|
+
question: v,
|
|
8189
8198
|
score: r.current.score
|
|
8190
8199
|
});
|
|
8191
|
-
const
|
|
8192
|
-
if (!
|
|
8193
|
-
if (
|
|
8200
|
+
const T = () => {
|
|
8201
|
+
if (!c.current || !v) return;
|
|
8202
|
+
if (c.current.setMood("happy"), e.questionStart)
|
|
8194
8203
|
try {
|
|
8195
|
-
|
|
8204
|
+
c.current.playAnimation(e.questionStart, !0);
|
|
8196
8205
|
} catch (Y) {
|
|
8197
8206
|
console.warn("Failed to play questionStart animation:", Y);
|
|
8198
8207
|
}
|
|
8199
|
-
const
|
|
8200
|
-
|
|
8208
|
+
const O = E.current || { lipsyncLang: "en" };
|
|
8209
|
+
v.type === "code_test" ? c.current.speakText(`Let's test your coding skills! Here's your first challenge: ${v.question}`, { lipsyncLang: O.lipsyncLang }) : v.type === "multiple_choice" ? c.current.speakText(`Now let me ask you some questions. Here's the first one: ${v.question}`, { lipsyncLang: O.lipsyncLang }) : v.type === "true_false" ? c.current.speakText(`Let's start with some true or false questions. First question: ${v.question}`, { lipsyncLang: O.lipsyncLang }) : c.current.speakText(`Now let me ask you some questions. Here's the first one: ${v.question}`, { lipsyncLang: O.lipsyncLang });
|
|
8201
8210
|
};
|
|
8202
|
-
if (
|
|
8203
|
-
|
|
8204
|
-
else if (
|
|
8205
|
-
const
|
|
8206
|
-
|
|
8211
|
+
if (c.current && c.current.isReady && v)
|
|
8212
|
+
T();
|
|
8213
|
+
else if (c.current && c.current.isReady) {
|
|
8214
|
+
const O = E.current || { lipsyncLang: "en" };
|
|
8215
|
+
c.current.speakText("Now let me ask you some questions to test your understanding.", { lipsyncLang: O.lipsyncLang });
|
|
8207
8216
|
} else {
|
|
8208
|
-
const
|
|
8209
|
-
|
|
8217
|
+
const O = setInterval(() => {
|
|
8218
|
+
c.current && c.current.isReady && (clearInterval(O), v && T());
|
|
8210
8219
|
}, 100);
|
|
8211
8220
|
setTimeout(() => {
|
|
8212
|
-
clearInterval(
|
|
8221
|
+
clearInterval(O);
|
|
8213
8222
|
}, 5e3);
|
|
8214
8223
|
}
|
|
8215
|
-
}, [e.questionStart, y, P]),
|
|
8216
|
-
const
|
|
8217
|
-
if (r.current.currentQuestionIndex < (
|
|
8218
|
-
|
|
8219
|
-
const
|
|
8220
|
-
|
|
8224
|
+
}, [e.questionStart, y, P]), F = U(() => {
|
|
8225
|
+
const A = y();
|
|
8226
|
+
if (r.current.currentQuestionIndex < (A?.questions?.length || 0) - 1) {
|
|
8227
|
+
c.current && c.current.stopSpeaking && c.current.stopSpeaking(), r.current.currentQuestionIndex += 1;
|
|
8228
|
+
const v = P();
|
|
8229
|
+
v && h.current.onCustomAction({
|
|
8221
8230
|
type: "nextQuestion",
|
|
8222
8231
|
moduleIndex: r.current.currentModuleIndex,
|
|
8223
8232
|
lessonIndex: r.current.currentLessonIndex,
|
|
8224
8233
|
questionIndex: r.current.currentQuestionIndex,
|
|
8225
8234
|
totalQuestions: r.current.totalQuestions,
|
|
8226
|
-
question:
|
|
8235
|
+
question: v,
|
|
8227
8236
|
score: r.current.score
|
|
8228
8237
|
});
|
|
8229
|
-
const
|
|
8230
|
-
if (!
|
|
8231
|
-
if (
|
|
8238
|
+
const T = () => {
|
|
8239
|
+
if (!c.current || !v) return;
|
|
8240
|
+
if (c.current.setMood("happy"), c.current.setBodyMovement("idle"), e.nextQuestion)
|
|
8232
8241
|
try {
|
|
8233
|
-
|
|
8242
|
+
c.current.playAnimation(e.nextQuestion, !0);
|
|
8234
8243
|
} catch (te) {
|
|
8235
8244
|
console.warn("Failed to play nextQuestion animation:", te);
|
|
8236
8245
|
}
|
|
8237
|
-
const
|
|
8238
|
-
if (
|
|
8239
|
-
const te = q ? `Great! Here's your final coding challenge: ${
|
|
8240
|
-
|
|
8241
|
-
lipsyncLang:
|
|
8246
|
+
const O = E.current || { lipsyncLang: "en" }, K = y()?.questions?.length || 0, q = r.current.currentQuestionIndex >= K - 1;
|
|
8247
|
+
if (v.type === "code_test") {
|
|
8248
|
+
const te = q ? `Great! Here's your final coding challenge: ${v.question}` : `Great! Now let's move on to your next coding challenge: ${v.question}`;
|
|
8249
|
+
c.current.speakText(te, {
|
|
8250
|
+
lipsyncLang: O.lipsyncLang
|
|
8242
8251
|
});
|
|
8243
|
-
} else if (
|
|
8244
|
-
const te = q ? `Alright! Here's your final question: ${
|
|
8245
|
-
|
|
8246
|
-
lipsyncLang:
|
|
8252
|
+
} else if (v.type === "multiple_choice") {
|
|
8253
|
+
const te = q ? `Alright! Here's your final question: ${v.question}` : `Alright! Here's your next question: ${v.question}`;
|
|
8254
|
+
c.current.speakText(te, {
|
|
8255
|
+
lipsyncLang: O.lipsyncLang
|
|
8247
8256
|
});
|
|
8248
|
-
} else if (
|
|
8249
|
-
const te = q ? `Now let's try this final one: ${
|
|
8250
|
-
|
|
8251
|
-
lipsyncLang:
|
|
8257
|
+
} else if (v.type === "true_false") {
|
|
8258
|
+
const te = q ? `Now let's try this final one: ${v.question}` : `Now let's try this one: ${v.question}`;
|
|
8259
|
+
c.current.speakText(te, {
|
|
8260
|
+
lipsyncLang: O.lipsyncLang
|
|
8252
8261
|
});
|
|
8253
8262
|
} else {
|
|
8254
|
-
const te = q ? `Here's your final question: ${
|
|
8255
|
-
|
|
8256
|
-
lipsyncLang:
|
|
8263
|
+
const te = q ? `Here's your final question: ${v.question}` : `Here's the next question: ${v.question}`;
|
|
8264
|
+
c.current.speakText(te, {
|
|
8265
|
+
lipsyncLang: O.lipsyncLang
|
|
8257
8266
|
});
|
|
8258
8267
|
}
|
|
8259
8268
|
};
|
|
8260
|
-
if (
|
|
8261
|
-
|
|
8262
|
-
else if (
|
|
8263
|
-
const
|
|
8264
|
-
|
|
8269
|
+
if (c.current && c.current.isReady && v)
|
|
8270
|
+
T();
|
|
8271
|
+
else if (v) {
|
|
8272
|
+
const O = setInterval(() => {
|
|
8273
|
+
c.current && c.current.isReady && (clearInterval(O), T());
|
|
8265
8274
|
}, 100);
|
|
8266
8275
|
setTimeout(() => {
|
|
8267
|
-
clearInterval(
|
|
8276
|
+
clearInterval(O);
|
|
8268
8277
|
}, 5e3);
|
|
8269
8278
|
}
|
|
8270
8279
|
} else
|
|
@@ -8275,11 +8284,11 @@ const Ut = Ke(({
|
|
|
8275
8284
|
totalQuestions: r.current.totalQuestions,
|
|
8276
8285
|
score: r.current.score
|
|
8277
8286
|
});
|
|
8278
|
-
}, [e.nextQuestion, y, P]),
|
|
8279
|
-
const
|
|
8280
|
-
if (r.current.currentLessonIndex < (
|
|
8287
|
+
}, [e.nextQuestion, y, P]), B = U(() => {
|
|
8288
|
+
const A = D.current || { modules: [] }, v = A.modules[r.current.currentModuleIndex];
|
|
8289
|
+
if (r.current.currentLessonIndex < (v?.lessons?.length || 0) - 1) {
|
|
8281
8290
|
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;
|
|
8282
|
-
const
|
|
8291
|
+
const O = A.modules[r.current.currentModuleIndex], Y = r.current.currentLessonIndex < (O?.lessons?.length || 0) - 1, K = r.current.currentModuleIndex < (A.modules?.length || 0) - 1, q = Y || K;
|
|
8283
8292
|
h.current.onCustomAction({
|
|
8284
8293
|
type: "lessonStart",
|
|
8285
8294
|
moduleIndex: r.current.currentModuleIndex,
|
|
@@ -8289,10 +8298,10 @@ const Ut = Ke(({
|
|
|
8289
8298
|
moduleIndex: r.current.currentModuleIndex,
|
|
8290
8299
|
lessonIndex: r.current.currentLessonIndex,
|
|
8291
8300
|
lesson: y()
|
|
8292
|
-
}),
|
|
8293
|
-
} else if (r.current.currentModuleIndex < (
|
|
8301
|
+
}), c.current && (c.current.setMood("happy"), c.current.setBodyMovement("idle"));
|
|
8302
|
+
} else if (r.current.currentModuleIndex < (A.modules?.length || 0) - 1) {
|
|
8294
8303
|
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;
|
|
8295
|
-
const Y =
|
|
8304
|
+
const Y = A.modules[r.current.currentModuleIndex], K = r.current.currentLessonIndex < (Y?.lessons?.length || 0) - 1, q = r.current.currentModuleIndex < (A.modules?.length || 0) - 1, te = K || q;
|
|
8296
8305
|
h.current.onCustomAction({
|
|
8297
8306
|
type: "lessonStart",
|
|
8298
8307
|
moduleIndex: r.current.currentModuleIndex,
|
|
@@ -8302,80 +8311,80 @@ const Ut = Ke(({
|
|
|
8302
8311
|
moduleIndex: r.current.currentModuleIndex,
|
|
8303
8312
|
lessonIndex: r.current.currentLessonIndex,
|
|
8304
8313
|
lesson: y()
|
|
8305
|
-
}),
|
|
8314
|
+
}), c.current && (c.current.setMood("happy"), c.current.setBodyMovement("idle"));
|
|
8306
8315
|
} else
|
|
8307
|
-
|
|
8316
|
+
k.current && k.current();
|
|
8308
8317
|
}, []), Q = U(() => {
|
|
8309
|
-
const
|
|
8310
|
-
let
|
|
8311
|
-
if (
|
|
8312
|
-
const
|
|
8313
|
-
|
|
8318
|
+
const A = y();
|
|
8319
|
+
let v = null;
|
|
8320
|
+
if (A?.avatar_script && A?.body) {
|
|
8321
|
+
const T = A.avatar_script.trim(), O = A.body.trim(), Y = T.match(/[.!?]$/) ? " " : ". ";
|
|
8322
|
+
v = `${T}${Y}${O}`;
|
|
8314
8323
|
} else
|
|
8315
|
-
|
|
8316
|
-
if (
|
|
8317
|
-
r.current.isTeaching = !0, r.current.isQuestionMode = !1, r.current.score = 0, r.current.totalQuestions = 0,
|
|
8318
|
-
let
|
|
8324
|
+
v = A?.avatar_script || A?.body || null;
|
|
8325
|
+
if (c.current && c.current.isReady && v) {
|
|
8326
|
+
r.current.isTeaching = !0, r.current.isQuestionMode = !1, r.current.score = 0, r.current.totalQuestions = 0, c.current.setMood("happy");
|
|
8327
|
+
let T = !1;
|
|
8319
8328
|
if (e.teaching)
|
|
8320
8329
|
try {
|
|
8321
|
-
|
|
8330
|
+
c.current.playAnimation(e.teaching, !0), T = !0;
|
|
8322
8331
|
} catch (Y) {
|
|
8323
8332
|
console.warn("Failed to play teaching animation:", Y);
|
|
8324
8333
|
}
|
|
8325
|
-
|
|
8326
|
-
const
|
|
8334
|
+
T || c.current.setBodyMovement("gesturing");
|
|
8335
|
+
const O = E.current || { lipsyncLang: "en" };
|
|
8327
8336
|
h.current.onLessonStart({
|
|
8328
8337
|
moduleIndex: r.current.currentModuleIndex,
|
|
8329
8338
|
lessonIndex: r.current.currentLessonIndex,
|
|
8330
|
-
lesson:
|
|
8339
|
+
lesson: A
|
|
8331
8340
|
}), h.current.onCustomAction({
|
|
8332
8341
|
type: "teachingStart",
|
|
8333
8342
|
moduleIndex: r.current.currentModuleIndex,
|
|
8334
8343
|
lessonIndex: r.current.currentLessonIndex,
|
|
8335
|
-
lesson:
|
|
8336
|
-
}),
|
|
8337
|
-
lipsyncLang:
|
|
8344
|
+
lesson: A
|
|
8345
|
+
}), c.current.speakText(v, {
|
|
8346
|
+
lipsyncLang: O.lipsyncLang,
|
|
8338
8347
|
onSpeechEnd: () => {
|
|
8339
8348
|
r.current.isTeaching = !1, h.current.onCustomAction({
|
|
8340
8349
|
type: "teachingComplete",
|
|
8341
8350
|
moduleIndex: r.current.currentModuleIndex,
|
|
8342
8351
|
lessonIndex: r.current.currentLessonIndex,
|
|
8343
|
-
lesson:
|
|
8344
|
-
hasQuestions:
|
|
8345
|
-
}),
|
|
8352
|
+
lesson: A,
|
|
8353
|
+
hasQuestions: A.questions && A.questions.length > 0
|
|
8354
|
+
}), A?.code_example && h.current.onCustomAction({
|
|
8346
8355
|
type: "codeExampleReady",
|
|
8347
8356
|
moduleIndex: r.current.currentModuleIndex,
|
|
8348
8357
|
lessonIndex: r.current.currentLessonIndex,
|
|
8349
|
-
lesson:
|
|
8350
|
-
codeExample:
|
|
8358
|
+
lesson: A,
|
|
8359
|
+
codeExample: A.code_example
|
|
8351
8360
|
});
|
|
8352
8361
|
}
|
|
8353
8362
|
});
|
|
8354
8363
|
}
|
|
8355
|
-
}, [e.teaching, y]), _ = U((
|
|
8356
|
-
const
|
|
8357
|
-
if (
|
|
8364
|
+
}, [e.teaching, y]), _ = U((A) => {
|
|
8365
|
+
const v = P(), T = L(A, v);
|
|
8366
|
+
if (T && (r.current.score += 1), h.current.onQuestionAnswer({
|
|
8358
8367
|
moduleIndex: r.current.currentModuleIndex,
|
|
8359
8368
|
lessonIndex: r.current.currentLessonIndex,
|
|
8360
8369
|
questionIndex: r.current.currentQuestionIndex,
|
|
8361
|
-
answer:
|
|
8362
|
-
isCorrect:
|
|
8363
|
-
question:
|
|
8364
|
-
}),
|
|
8365
|
-
if (
|
|
8366
|
-
if (
|
|
8370
|
+
answer: A,
|
|
8371
|
+
isCorrect: T,
|
|
8372
|
+
question: v
|
|
8373
|
+
}), c.current)
|
|
8374
|
+
if (T) {
|
|
8375
|
+
if (c.current.setMood("happy"), e.correct)
|
|
8367
8376
|
try {
|
|
8368
|
-
|
|
8377
|
+
c.current.playReaction("happy");
|
|
8369
8378
|
} catch {
|
|
8370
|
-
|
|
8379
|
+
c.current.setBodyMovement("happy");
|
|
8371
8380
|
}
|
|
8372
|
-
|
|
8381
|
+
c.current.setBodyMovement("gesturing");
|
|
8373
8382
|
const Y = y()?.questions?.length || 0;
|
|
8374
8383
|
r.current.currentQuestionIndex >= Y - 1;
|
|
8375
8384
|
const K = r.current.currentQuestionIndex < Y - 1;
|
|
8376
8385
|
console.log("[CurriculumLearning] Answer feedback - questionIndex:", r.current.currentQuestionIndex, "totalQuestions:", Y, "hasNextQuestion:", K);
|
|
8377
|
-
const q =
|
|
8378
|
-
|
|
8386
|
+
const q = v.type === "code_test" ? `Great job! Your code passed all the tests! ${v.explanation || ""}` : `Excellent! That's correct! ${v.explanation || ""}`, te = E.current || { lipsyncLang: "en" };
|
|
8387
|
+
c.current.speakText(q, {
|
|
8379
8388
|
lipsyncLang: te.lipsyncLang,
|
|
8380
8389
|
onSpeechEnd: () => {
|
|
8381
8390
|
h.current.onCustomAction({
|
|
@@ -8391,17 +8400,17 @@ const Ut = Ke(({
|
|
|
8391
8400
|
}
|
|
8392
8401
|
});
|
|
8393
8402
|
} else {
|
|
8394
|
-
if (
|
|
8403
|
+
if (c.current.setMood("sad"), e.incorrect)
|
|
8395
8404
|
try {
|
|
8396
|
-
|
|
8405
|
+
c.current.playAnimation(e.incorrect, !0);
|
|
8397
8406
|
} catch {
|
|
8398
|
-
|
|
8407
|
+
c.current.setBodyMovement("idle");
|
|
8399
8408
|
}
|
|
8400
|
-
|
|
8409
|
+
c.current.setBodyMovement("gesturing");
|
|
8401
8410
|
const Y = y()?.questions?.length || 0, K = r.current.currentQuestionIndex >= Y - 1, q = r.current.currentQuestionIndex < Y - 1;
|
|
8402
8411
|
console.log("[CurriculumLearning] Answer feedback (incorrect) - questionIndex:", r.current.currentQuestionIndex, "totalQuestions:", Y, "hasNextQuestion:", q);
|
|
8403
|
-
const te =
|
|
8404
|
-
|
|
8412
|
+
const te = 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 || ""}${K ? "" : " Let's move on to the next question."}`, fe = E.current || { lipsyncLang: "en" };
|
|
8413
|
+
c.current.speakText(te, {
|
|
8405
8414
|
lipsyncLang: fe.lipsyncLang,
|
|
8406
8415
|
onSpeechEnd: () => {
|
|
8407
8416
|
h.current.onCustomAction({
|
|
@@ -8424,78 +8433,78 @@ const Ut = Ke(({
|
|
|
8424
8433
|
moduleIndex: r.current.currentModuleIndex,
|
|
8425
8434
|
lessonIndex: r.current.currentLessonIndex,
|
|
8426
8435
|
questionIndex: r.current.currentQuestionIndex,
|
|
8427
|
-
isCorrect:
|
|
8436
|
+
isCorrect: T,
|
|
8428
8437
|
hasNextQuestion: r.current.currentQuestionIndex < Y - 1,
|
|
8429
8438
|
score: r.current.score,
|
|
8430
8439
|
totalQuestions: r.current.totalQuestions,
|
|
8431
8440
|
avatarNotReady: !0
|
|
8432
8441
|
});
|
|
8433
8442
|
}
|
|
8434
|
-
}, [e.correct, e.incorrect, P, y, L]),
|
|
8435
|
-
const
|
|
8436
|
-
if (!
|
|
8443
|
+
}, [e.correct, e.incorrect, P, y, L]), ve = U((A) => {
|
|
8444
|
+
const v = P();
|
|
8445
|
+
if (!A || typeof A != "object") {
|
|
8437
8446
|
console.error("Invalid code test result format. Expected object with {passed: boolean, ...}");
|
|
8438
8447
|
return;
|
|
8439
8448
|
}
|
|
8440
|
-
if (
|
|
8449
|
+
if (v?.type !== "code_test") {
|
|
8441
8450
|
console.warn("Current question is not a code test. Use handleAnswerSelect for other question types.");
|
|
8442
8451
|
return;
|
|
8443
8452
|
}
|
|
8444
|
-
const
|
|
8445
|
-
passed:
|
|
8446
|
-
results:
|
|
8447
|
-
output:
|
|
8448
|
-
error:
|
|
8449
|
-
executionTime:
|
|
8450
|
-
testCount:
|
|
8451
|
-
passedCount:
|
|
8452
|
-
failedCount:
|
|
8453
|
+
const T = {
|
|
8454
|
+
passed: A.passed === !0,
|
|
8455
|
+
results: A.results || [],
|
|
8456
|
+
output: A.output || "",
|
|
8457
|
+
error: A.error || null,
|
|
8458
|
+
executionTime: A.executionTime || null,
|
|
8459
|
+
testCount: A.testCount || 0,
|
|
8460
|
+
passedCount: A.passedCount || 0,
|
|
8461
|
+
failedCount: A.failedCount || 0
|
|
8453
8462
|
};
|
|
8454
8463
|
h.current.onCustomAction({
|
|
8455
8464
|
type: "codeTestSubmitted",
|
|
8456
8465
|
moduleIndex: r.current.currentModuleIndex,
|
|
8457
8466
|
lessonIndex: r.current.currentLessonIndex,
|
|
8458
8467
|
questionIndex: r.current.currentQuestionIndex,
|
|
8459
|
-
testResult:
|
|
8460
|
-
question:
|
|
8461
|
-
}), m.current && m.current(
|
|
8468
|
+
testResult: T,
|
|
8469
|
+
question: v
|
|
8470
|
+
}), m.current && m.current(T);
|
|
8462
8471
|
}, [P, L]), me = U(() => {
|
|
8463
8472
|
if (r.current.currentQuestionIndex > 0) {
|
|
8464
8473
|
r.current.currentQuestionIndex -= 1;
|
|
8465
|
-
const
|
|
8466
|
-
|
|
8474
|
+
const A = P();
|
|
8475
|
+
A && h.current.onCustomAction({
|
|
8467
8476
|
type: "questionStart",
|
|
8468
8477
|
moduleIndex: r.current.currentModuleIndex,
|
|
8469
8478
|
lessonIndex: r.current.currentLessonIndex,
|
|
8470
8479
|
questionIndex: r.current.currentQuestionIndex,
|
|
8471
8480
|
totalQuestions: r.current.totalQuestions,
|
|
8472
|
-
question:
|
|
8481
|
+
question: A,
|
|
8473
8482
|
score: r.current.score
|
|
8474
8483
|
});
|
|
8475
|
-
const
|
|
8476
|
-
if (!
|
|
8477
|
-
|
|
8478
|
-
const
|
|
8479
|
-
|
|
8480
|
-
lipsyncLang:
|
|
8481
|
-
}) :
|
|
8482
|
-
lipsyncLang:
|
|
8484
|
+
const v = () => {
|
|
8485
|
+
if (!c.current || !A) return;
|
|
8486
|
+
c.current.setMood("happy"), c.current.setBodyMovement("idle");
|
|
8487
|
+
const T = E.current || { lipsyncLang: "en" };
|
|
8488
|
+
A.type === "code_test" ? c.current.speakText(`Let's go back to this coding challenge: ${A.question}`, {
|
|
8489
|
+
lipsyncLang: T.lipsyncLang
|
|
8490
|
+
}) : c.current.speakText(`Going back to: ${A.question}`, {
|
|
8491
|
+
lipsyncLang: T.lipsyncLang
|
|
8483
8492
|
});
|
|
8484
8493
|
};
|
|
8485
|
-
if (
|
|
8486
|
-
|
|
8487
|
-
else if (
|
|
8488
|
-
const
|
|
8489
|
-
|
|
8494
|
+
if (c.current && c.current.isReady && A)
|
|
8495
|
+
v();
|
|
8496
|
+
else if (A) {
|
|
8497
|
+
const T = setInterval(() => {
|
|
8498
|
+
c.current && c.current.isReady && (clearInterval(T), v());
|
|
8490
8499
|
}, 100);
|
|
8491
8500
|
setTimeout(() => {
|
|
8492
|
-
clearInterval(
|
|
8501
|
+
clearInterval(T);
|
|
8493
8502
|
}, 5e3);
|
|
8494
8503
|
}
|
|
8495
8504
|
}
|
|
8496
|
-
}, [P]),
|
|
8497
|
-
const
|
|
8498
|
-
if (
|
|
8505
|
+
}, [P]), Fe = U(() => {
|
|
8506
|
+
const A = D.current || { modules: [] };
|
|
8507
|
+
if (A.modules[r.current.currentModuleIndex], r.current.currentLessonIndex > 0)
|
|
8499
8508
|
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, h.current.onCustomAction({
|
|
8500
8509
|
type: "lessonStart",
|
|
8501
8510
|
moduleIndex: r.current.currentModuleIndex,
|
|
@@ -8504,10 +8513,10 @@ const Ut = Ke(({
|
|
|
8504
8513
|
moduleIndex: r.current.currentModuleIndex,
|
|
8505
8514
|
lessonIndex: r.current.currentLessonIndex,
|
|
8506
8515
|
lesson: y()
|
|
8507
|
-
}),
|
|
8516
|
+
}), c.current && (c.current.setMood("happy"), c.current.setBodyMovement("idle"));
|
|
8508
8517
|
else if (r.current.currentModuleIndex > 0) {
|
|
8509
|
-
const
|
|
8510
|
-
r.current.currentModuleIndex -= 1, r.current.currentLessonIndex = (
|
|
8518
|
+
const O = A.modules[r.current.currentModuleIndex - 1];
|
|
8519
|
+
r.current.currentModuleIndex -= 1, r.current.currentLessonIndex = (O?.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, h.current.onCustomAction({
|
|
8511
8520
|
type: "lessonStart",
|
|
8512
8521
|
moduleIndex: r.current.currentModuleIndex,
|
|
8513
8522
|
lessonIndex: r.current.currentLessonIndex
|
|
@@ -8515,87 +8524,87 @@ const Ut = Ke(({
|
|
|
8515
8524
|
moduleIndex: r.current.currentModuleIndex,
|
|
8516
8525
|
lessonIndex: r.current.currentLessonIndex,
|
|
8517
8526
|
lesson: y()
|
|
8518
|
-
}),
|
|
8527
|
+
}), c.current && (c.current.setMood("happy"), c.current.setBodyMovement("idle"));
|
|
8519
8528
|
}
|
|
8520
8529
|
}, [y]), ye = U(() => {
|
|
8521
8530
|
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;
|
|
8522
|
-
}, []), Re = U((
|
|
8523
|
-
console.log("Avatar is ready!",
|
|
8524
|
-
const
|
|
8525
|
-
|
|
8531
|
+
}, []), Re = U((A) => {
|
|
8532
|
+
console.log("Avatar is ready!", A);
|
|
8533
|
+
const v = y(), T = v?.avatar_script || v?.body;
|
|
8534
|
+
u && T && setTimeout(() => {
|
|
8526
8535
|
d.current && d.current();
|
|
8527
8536
|
}, 10);
|
|
8528
|
-
}, [
|
|
8537
|
+
}, [u, y]);
|
|
8529
8538
|
pt(() => {
|
|
8530
|
-
d.current = Q, g.current =
|
|
8539
|
+
d.current = Q, g.current = B, R.current = f, x.current = F, k.current = M, G.current = I, m.current = _;
|
|
8531
8540
|
}), Je(l, () => ({
|
|
8532
8541
|
// Curriculum control methods
|
|
8533
8542
|
startTeaching: Q,
|
|
8534
|
-
startQuestions:
|
|
8543
|
+
startQuestions: I,
|
|
8535
8544
|
handleAnswerSelect: _,
|
|
8536
|
-
handleCodeTestResult:
|
|
8537
|
-
nextQuestion:
|
|
8545
|
+
handleCodeTestResult: ve,
|
|
8546
|
+
nextQuestion: F,
|
|
8538
8547
|
previousQuestion: me,
|
|
8539
|
-
nextLesson:
|
|
8540
|
-
previousLesson:
|
|
8548
|
+
nextLesson: B,
|
|
8549
|
+
previousLesson: Fe,
|
|
8541
8550
|
completeLesson: f,
|
|
8542
|
-
completeCurriculum:
|
|
8551
|
+
completeCurriculum: M,
|
|
8543
8552
|
resetCurriculum: ye,
|
|
8544
8553
|
getState: () => ({ ...r.current }),
|
|
8545
8554
|
getCurrentQuestion: () => P(),
|
|
8546
8555
|
getCurrentLesson: () => y(),
|
|
8547
8556
|
// Direct access to avatar ref (always returns current value)
|
|
8548
|
-
getAvatarRef: () =>
|
|
8557
|
+
getAvatarRef: () => c.current,
|
|
8549
8558
|
// Convenience methods that delegate to avatar (always check current ref)
|
|
8550
|
-
speakText: async (
|
|
8551
|
-
await
|
|
8552
|
-
const
|
|
8553
|
-
|
|
8559
|
+
speakText: async (A, v = {}) => {
|
|
8560
|
+
await c.current?.resumeAudioContext?.();
|
|
8561
|
+
const T = E.current || { lipsyncLang: "en" };
|
|
8562
|
+
c.current?.speakText(A, { ...v, lipsyncLang: v.lipsyncLang || T.lipsyncLang });
|
|
8554
8563
|
},
|
|
8555
8564
|
resumeAudioContext: async () => {
|
|
8556
|
-
if (
|
|
8557
|
-
return await
|
|
8558
|
-
const
|
|
8559
|
-
if (
|
|
8560
|
-
const
|
|
8561
|
-
if (
|
|
8565
|
+
if (c.current?.resumeAudioContext)
|
|
8566
|
+
return await c.current.resumeAudioContext();
|
|
8567
|
+
const A = c.current?.talkingHead;
|
|
8568
|
+
if (A?.audioCtx) {
|
|
8569
|
+
const v = A.audioCtx;
|
|
8570
|
+
if (v.state === "suspended" || v.state === "interrupted")
|
|
8562
8571
|
try {
|
|
8563
|
-
await
|
|
8564
|
-
} catch (
|
|
8565
|
-
console.warn("Failed to resume audio context:",
|
|
8572
|
+
await v.resume(), console.log("Audio context resumed via talkingHead");
|
|
8573
|
+
} catch (T) {
|
|
8574
|
+
console.warn("Failed to resume audio context:", T);
|
|
8566
8575
|
}
|
|
8567
8576
|
} else
|
|
8568
8577
|
console.warn("Audio context not available yet");
|
|
8569
8578
|
},
|
|
8570
|
-
stopSpeaking: () =>
|
|
8571
|
-
pauseSpeaking: () =>
|
|
8572
|
-
resumeSpeaking: async () => await
|
|
8573
|
-
isPaused: () =>
|
|
8574
|
-
setMood: (
|
|
8575
|
-
playAnimation: (
|
|
8576
|
-
setBodyMovement: (
|
|
8577
|
-
setMovementIntensity: (
|
|
8578
|
-
playRandomDance: () =>
|
|
8579
|
-
playReaction: (
|
|
8580
|
-
playCelebration: () =>
|
|
8581
|
-
setShowFullAvatar: (
|
|
8582
|
-
setTimingAdjustment: (
|
|
8583
|
-
lockAvatarPosition: () =>
|
|
8584
|
-
unlockAvatarPosition: () =>
|
|
8579
|
+
stopSpeaking: () => c.current?.stopSpeaking(),
|
|
8580
|
+
pauseSpeaking: () => c.current?.pauseSpeaking(),
|
|
8581
|
+
resumeSpeaking: async () => await c.current?.resumeSpeaking(),
|
|
8582
|
+
isPaused: () => c.current && typeof c.current.isPaused < "u" ? c.current.isPaused : !1,
|
|
8583
|
+
setMood: (A) => c.current?.setMood(A),
|
|
8584
|
+
playAnimation: (A, v) => c.current?.playAnimation(A, v),
|
|
8585
|
+
setBodyMovement: (A) => c.current?.setBodyMovement(A),
|
|
8586
|
+
setMovementIntensity: (A) => c.current?.setMovementIntensity(A),
|
|
8587
|
+
playRandomDance: () => c.current?.playRandomDance(),
|
|
8588
|
+
playReaction: (A) => c.current?.playReaction(A),
|
|
8589
|
+
playCelebration: () => c.current?.playCelebration(),
|
|
8590
|
+
setShowFullAvatar: (A) => c.current?.setShowFullAvatar(A),
|
|
8591
|
+
setTimingAdjustment: (A) => c.current?.setTimingAdjustment(A),
|
|
8592
|
+
lockAvatarPosition: () => c.current?.lockAvatarPosition(),
|
|
8593
|
+
unlockAvatarPosition: () => c.current?.unlockAvatarPosition(),
|
|
8585
8594
|
// Custom action trigger
|
|
8586
|
-
triggerCustomAction: (
|
|
8595
|
+
triggerCustomAction: (A, v) => {
|
|
8587
8596
|
h.current.onCustomAction({
|
|
8588
|
-
type:
|
|
8589
|
-
...
|
|
8597
|
+
type: A,
|
|
8598
|
+
...v,
|
|
8590
8599
|
state: { ...r.current }
|
|
8591
8600
|
});
|
|
8592
8601
|
},
|
|
8593
8602
|
// Responsive resize handler
|
|
8594
|
-
handleResize: () =>
|
|
8603
|
+
handleResize: () => c.current?.handleResize(),
|
|
8595
8604
|
// Avatar readiness check (always returns current value)
|
|
8596
|
-
isAvatarReady: () =>
|
|
8597
|
-
}), [Q,
|
|
8598
|
-
const he =
|
|
8605
|
+
isAvatarReady: () => c.current?.isReady || !1
|
|
8606
|
+
}), [Q, I, _, ve, F, B, f, M, ye, P, y]);
|
|
8607
|
+
const he = E.current || {
|
|
8599
8608
|
avatarUrl: "/avatars/brunette.glb",
|
|
8600
8609
|
avatarBody: "F",
|
|
8601
8610
|
mood: "happy",
|
|
@@ -8609,9 +8618,9 @@ const Ut = Ke(({
|
|
|
8609
8618
|
animations: e
|
|
8610
8619
|
};
|
|
8611
8620
|
return /* @__PURE__ */ ae("div", { style: { width: "100%", height: "100%" }, children: /* @__PURE__ */ ae(
|
|
8612
|
-
|
|
8621
|
+
ct,
|
|
8613
8622
|
{
|
|
8614
|
-
ref:
|
|
8623
|
+
ref: c,
|
|
8615
8624
|
avatarUrl: he.avatarUrl,
|
|
8616
8625
|
avatarBody: he.avatarBody,
|
|
8617
8626
|
mood: he.mood,
|
|
@@ -8627,8 +8636,8 @@ const Ut = Ke(({
|
|
|
8627
8636
|
onReady: Re,
|
|
8628
8637
|
onLoading: () => {
|
|
8629
8638
|
},
|
|
8630
|
-
onError: (
|
|
8631
|
-
console.error("Avatar error:",
|
|
8639
|
+
onError: (A) => {
|
|
8640
|
+
console.error("Avatar error:", A);
|
|
8632
8641
|
}
|
|
8633
8642
|
}
|
|
8634
8643
|
) });
|
|
@@ -8642,26 +8651,26 @@ function _t({
|
|
|
8642
8651
|
onDeleteAnimations: o = null,
|
|
8643
8652
|
style: s = {}
|
|
8644
8653
|
}) {
|
|
8645
|
-
const [i, a] = pe([]), [
|
|
8654
|
+
const [i, a] = pe([]), [u, l] = pe(/* @__PURE__ */ new Set()), [c, r] = pe(!0), [h, d] = pe(null), [g, R] = pe("all"), [x, k] = pe("");
|
|
8646
8655
|
Se(() => {
|
|
8647
8656
|
(async () => {
|
|
8648
8657
|
r(!0), d(null);
|
|
8649
8658
|
try {
|
|
8650
|
-
const
|
|
8651
|
-
if (
|
|
8652
|
-
const
|
|
8653
|
-
|
|
8659
|
+
const M = await je(Z), I = [];
|
|
8660
|
+
if (M._genderSpecific) {
|
|
8661
|
+
const B = (n?.toUpperCase() || "F") === "M" ? "male" : "female";
|
|
8662
|
+
M._genderSpecific[B] && Object.entries(M._genderSpecific[B]).forEach(([Q, _]) => {
|
|
8654
8663
|
(Array.isArray(_) ? _ : [_]).forEach((me) => {
|
|
8655
|
-
|
|
8664
|
+
I.push({
|
|
8656
8665
|
path: me,
|
|
8657
8666
|
group: Q,
|
|
8658
|
-
gender:
|
|
8667
|
+
gender: B,
|
|
8659
8668
|
name: me.split("/").pop().replace(".fbx", "")
|
|
8660
8669
|
});
|
|
8661
8670
|
});
|
|
8662
|
-
}),
|
|
8671
|
+
}), M._genderSpecific.shared && Object.entries(M._genderSpecific.shared).forEach(([Q, _]) => {
|
|
8663
8672
|
(Array.isArray(_) ? _ : [_]).forEach((me) => {
|
|
8664
|
-
|
|
8673
|
+
I.push({
|
|
8665
8674
|
path: me,
|
|
8666
8675
|
group: Q,
|
|
8667
8676
|
gender: "shared",
|
|
@@ -8670,53 +8679,53 @@ function _t({
|
|
|
8670
8679
|
});
|
|
8671
8680
|
});
|
|
8672
8681
|
}
|
|
8673
|
-
Object.entries(
|
|
8674
|
-
|
|
8675
|
-
typeof _ == "string" &&
|
|
8682
|
+
Object.entries(M).forEach(([F, B]) => {
|
|
8683
|
+
F !== "_genderSpecific" && (Array.isArray(B) ? B : [B]).forEach((_) => {
|
|
8684
|
+
typeof _ == "string" && I.push({
|
|
8676
8685
|
path: _,
|
|
8677
|
-
group:
|
|
8686
|
+
group: F,
|
|
8678
8687
|
gender: "root",
|
|
8679
8688
|
name: _.split("/").pop().replace(".fbx", "")
|
|
8680
8689
|
});
|
|
8681
8690
|
});
|
|
8682
|
-
}), a(
|
|
8683
|
-
} catch (
|
|
8684
|
-
console.error("Failed to load animations:",
|
|
8691
|
+
}), a(I), r(!1);
|
|
8692
|
+
} catch (M) {
|
|
8693
|
+
console.error("Failed to load animations:", M), d(M.message), r(!1);
|
|
8685
8694
|
}
|
|
8686
8695
|
})();
|
|
8687
8696
|
}, [Z, n]);
|
|
8688
|
-
const
|
|
8689
|
-
const
|
|
8690
|
-
return
|
|
8697
|
+
const G = ["all", ...new Set(i.map((f) => f.group))], m = i.filter((f) => {
|
|
8698
|
+
const M = g === "all" || f.group === g, I = x === "" || f.name.toLowerCase().includes(x.toLowerCase()) || f.path.toLowerCase().includes(x.toLowerCase());
|
|
8699
|
+
return M && I;
|
|
8691
8700
|
}), D = (f) => {
|
|
8692
|
-
const
|
|
8693
|
-
|
|
8694
|
-
},
|
|
8695
|
-
const f = new Set(
|
|
8696
|
-
m.forEach((
|
|
8697
|
-
f.add(
|
|
8701
|
+
const M = new Set(u);
|
|
8702
|
+
M.has(f) ? M.delete(f) : M.add(f), l(M), t && t(Array.from(M));
|
|
8703
|
+
}, E = () => {
|
|
8704
|
+
const f = new Set(u);
|
|
8705
|
+
m.forEach((M) => {
|
|
8706
|
+
f.add(M.path);
|
|
8698
8707
|
}), l(f), t && t(Array.from(f));
|
|
8699
8708
|
}, y = () => {
|
|
8700
|
-
const f = new Set(
|
|
8701
|
-
m.forEach((
|
|
8702
|
-
f.delete(
|
|
8709
|
+
const f = new Set(u);
|
|
8710
|
+
m.forEach((M) => {
|
|
8711
|
+
f.delete(M.path);
|
|
8703
8712
|
}), l(f), t && t(Array.from(f));
|
|
8704
8713
|
}, P = () => {
|
|
8705
|
-
const
|
|
8706
|
-
if (
|
|
8714
|
+
const M = i.filter((I) => !u.has(I.path)).map((I) => I.path);
|
|
8715
|
+
if (M.length === 0) {
|
|
8707
8716
|
alert("No animations to delete. Select animations to keep, then delete will remove the unselected ones.");
|
|
8708
8717
|
return;
|
|
8709
8718
|
}
|
|
8710
|
-
window.confirm(`Are you sure you want to delete ${
|
|
8719
|
+
window.confirm(`Are you sure you want to delete ${M.length} animation(s)?
|
|
8711
8720
|
|
|
8712
8721
|
This will delete:
|
|
8713
|
-
${
|
|
8714
|
-
`)}${
|
|
8715
|
-
...` : ""}`) && (o && o(
|
|
8722
|
+
${M.slice(0, 5).join(`
|
|
8723
|
+
`)}${M.length > 5 ? `
|
|
8724
|
+
...` : ""}`) && (o && o(M), a(i.filter((I) => u.has(I.path))), l(/* @__PURE__ */ new Set()));
|
|
8716
8725
|
}, L = (f) => {
|
|
8717
8726
|
e && e(f);
|
|
8718
8727
|
};
|
|
8719
|
-
return
|
|
8728
|
+
return c ? /* @__PURE__ */ ae("div", { style: { padding: "20px", textAlign: "center", ...s }, children: /* @__PURE__ */ ae("p", { children: "Loading animations..." }) }) : h ? /* @__PURE__ */ ae("div", { style: { padding: "20px", color: "red", ...s }, children: /* @__PURE__ */ Pe("p", { children: [
|
|
8720
8729
|
"Error loading animations: ",
|
|
8721
8730
|
h
|
|
8722
8731
|
] }) }) : /* @__PURE__ */ Pe("div", { style: {
|
|
@@ -8741,7 +8750,7 @@ ${T.slice(0, 5).join(`
|
|
|
8741
8750
|
type: "text",
|
|
8742
8751
|
placeholder: "Search animations...",
|
|
8743
8752
|
value: x,
|
|
8744
|
-
onChange: (f) =>
|
|
8753
|
+
onChange: (f) => k(f.target.value),
|
|
8745
8754
|
style: {
|
|
8746
8755
|
padding: "8px 12px",
|
|
8747
8756
|
borderRadius: "6px",
|
|
@@ -8767,13 +8776,13 @@ ${T.slice(0, 5).join(`
|
|
|
8767
8776
|
color: "#fff",
|
|
8768
8777
|
fontSize: "14px"
|
|
8769
8778
|
},
|
|
8770
|
-
children:
|
|
8779
|
+
children: G.map((f) => /* @__PURE__ */ ae("option", { value: f, children: f === "all" ? "All Groups" : f }, f))
|
|
8771
8780
|
}
|
|
8772
8781
|
),
|
|
8773
8782
|
/* @__PURE__ */ ae(
|
|
8774
8783
|
"button",
|
|
8775
8784
|
{
|
|
8776
|
-
onClick:
|
|
8785
|
+
onClick: E,
|
|
8777
8786
|
style: {
|
|
8778
8787
|
padding: "8px 16px",
|
|
8779
8788
|
backgroundColor: "#4CAF50",
|
|
@@ -8818,7 +8827,7 @@ ${T.slice(0, 5).join(`
|
|
|
8818
8827
|
},
|
|
8819
8828
|
children: [
|
|
8820
8829
|
"Delete Unselected (",
|
|
8821
|
-
i.length -
|
|
8830
|
+
i.length - u.size,
|
|
8822
8831
|
")"
|
|
8823
8832
|
]
|
|
8824
8833
|
}
|
|
@@ -8832,7 +8841,7 @@ ${T.slice(0, 5).join(`
|
|
|
8832
8841
|
"Total: ",
|
|
8833
8842
|
i.length,
|
|
8834
8843
|
" | Selected: ",
|
|
8835
|
-
|
|
8844
|
+
u.size,
|
|
8836
8845
|
" | Showing: ",
|
|
8837
8846
|
m.length
|
|
8838
8847
|
] }),
|
|
@@ -8845,16 +8854,16 @@ ${T.slice(0, 5).join(`
|
|
|
8845
8854
|
padding: "10px",
|
|
8846
8855
|
backgroundColor: "#1a1a1a",
|
|
8847
8856
|
borderRadius: "6px"
|
|
8848
|
-
}, children: m.map((f,
|
|
8849
|
-
const
|
|
8857
|
+
}, children: m.map((f, M) => {
|
|
8858
|
+
const I = u.has(f.path);
|
|
8850
8859
|
return /* @__PURE__ */ Pe(
|
|
8851
8860
|
"div",
|
|
8852
8861
|
{
|
|
8853
8862
|
style: {
|
|
8854
|
-
border: `2px solid ${
|
|
8863
|
+
border: `2px solid ${I ? "#4CAF50" : "#555"}`,
|
|
8855
8864
|
borderRadius: "6px",
|
|
8856
8865
|
padding: "10px",
|
|
8857
|
-
backgroundColor:
|
|
8866
|
+
backgroundColor: I ? "#2a4a2a" : "#222",
|
|
8858
8867
|
cursor: "pointer",
|
|
8859
8868
|
transition: "all 0.2s"
|
|
8860
8869
|
},
|
|
@@ -8865,9 +8874,9 @@ ${T.slice(0, 5).join(`
|
|
|
8865
8874
|
"input",
|
|
8866
8875
|
{
|
|
8867
8876
|
type: "checkbox",
|
|
8868
|
-
checked:
|
|
8877
|
+
checked: I,
|
|
8869
8878
|
onChange: () => D(f.path),
|
|
8870
|
-
onClick: (
|
|
8879
|
+
onClick: (F) => F.stopPropagation(),
|
|
8871
8880
|
style: {
|
|
8872
8881
|
marginRight: "8px",
|
|
8873
8882
|
cursor: "pointer"
|
|
@@ -8889,8 +8898,8 @@ ${T.slice(0, 5).join(`
|
|
|
8889
8898
|
/* @__PURE__ */ ae(
|
|
8890
8899
|
"button",
|
|
8891
8900
|
{
|
|
8892
|
-
onClick: (
|
|
8893
|
-
|
|
8901
|
+
onClick: (F) => {
|
|
8902
|
+
F.stopPropagation(), L(f.path);
|
|
8894
8903
|
},
|
|
8895
8904
|
style: {
|
|
8896
8905
|
width: "100%",
|
|
@@ -8907,7 +8916,7 @@ ${T.slice(0, 5).join(`
|
|
|
8907
8916
|
)
|
|
8908
8917
|
]
|
|
8909
8918
|
},
|
|
8910
|
-
`${f.path}-${
|
|
8919
|
+
`${f.path}-${M}`
|
|
8911
8920
|
);
|
|
8912
8921
|
}) }),
|
|
8913
8922
|
m.length === 0 && /* @__PURE__ */ ae("div", { style: {
|
|
@@ -8917,7 +8926,7 @@ ${T.slice(0, 5).join(`
|
|
|
8917
8926
|
}, children: "No animations found matching your filters." })
|
|
8918
8927
|
] });
|
|
8919
8928
|
}
|
|
8920
|
-
const
|
|
8929
|
+
const ut = {
|
|
8921
8930
|
// Code-based dance animations (no FBX required)
|
|
8922
8931
|
dance: {
|
|
8923
8932
|
name: "dance",
|
|
@@ -9020,14 +9029,14 @@ const ct = {
|
|
|
9020
9029
|
duration: 5e3,
|
|
9021
9030
|
description: "Excited, energetic movement"
|
|
9022
9031
|
}
|
|
9023
|
-
}, Kt = (Z) =>
|
|
9032
|
+
}, Kt = (Z) => ut[Z] || null, Jt = (Z) => ut.hasOwnProperty(Z);
|
|
9024
9033
|
export {
|
|
9025
9034
|
_t as AnimationSelector,
|
|
9026
9035
|
Ut as CurriculumLearning,
|
|
9027
9036
|
Nt as SimpleTalkingAvatar,
|
|
9028
|
-
|
|
9029
|
-
|
|
9030
|
-
|
|
9037
|
+
ct as TalkingHeadAvatar,
|
|
9038
|
+
Ot as TalkingHeadComponent,
|
|
9039
|
+
ut as animations,
|
|
9031
9040
|
$e as getActiveTTSConfig,
|
|
9032
9041
|
Kt as getAnimation,
|
|
9033
9042
|
qt as getVoiceOptions,
|