@sage-rsc/talking-head-react 1.8.8 → 1.9.0
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 +1217 -1205
- package/package.json +1 -1
- package/src/components/SimpleTalkingAvatar.jsx +74 -20
- package/src/lib/talkinghead.mjs +19 -0
package/dist/index.js
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
import { jsxs as
|
|
2
|
-
import { forwardRef as Ke, useRef as V, useState as
|
|
1
|
+
import { jsxs as Ee, jsx as le } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef as Ke, useRef as V, useState as ge, useEffect as ze, useCallback as W, useImperativeHandle as $e, useLayoutEffect as ft } from "react";
|
|
3
3
|
import * as A from "three";
|
|
4
|
-
import { OrbitControls as
|
|
5
|
-
import { GLTFLoader as
|
|
6
|
-
import { DRACOLoader as
|
|
7
|
-
import { FBXLoader as
|
|
8
|
-
import { RoomEnvironment as
|
|
9
|
-
import
|
|
10
|
-
let
|
|
11
|
-
const
|
|
4
|
+
import { OrbitControls as xt } from "three/addons/controls/OrbitControls.js";
|
|
5
|
+
import { GLTFLoader as bt } from "three/addons/loaders/GLTFLoader.js";
|
|
6
|
+
import { DRACOLoader as At } from "three/addons/loaders/DRACOLoader.js";
|
|
7
|
+
import { FBXLoader as ot } from "three/addons/loaders/FBXLoader.js";
|
|
8
|
+
import { RoomEnvironment as Rt } from "three/addons/environments/RoomEnvironment.js";
|
|
9
|
+
import vt from "three/addons/libs/stats.module.js";
|
|
10
|
+
let m, Ce, He;
|
|
11
|
+
const T = [0, 0, 0, 0], U = new A.Vector3(), Qe = new A.Vector3(), ve = new A.Vector3(), Ye = new A.Vector3();
|
|
12
12
|
new A.Plane();
|
|
13
13
|
new A.Ray();
|
|
14
14
|
new A.Euler();
|
|
15
|
-
const
|
|
15
|
+
const Ie = new A.Quaternion(), st = new A.Quaternion(), Pe = new A.Matrix4(), Be = new A.Matrix4();
|
|
16
16
|
new A.Vector3();
|
|
17
|
-
const qe = new A.Vector3(0, 0, 1),
|
|
18
|
-
class
|
|
17
|
+
const qe = new A.Vector3(0, 0, 1), It = new A.Vector3(1, 0, 0), Lt = new A.Vector3(0, 1, 0), St = new A.Vector3(0, 0, 1);
|
|
18
|
+
class kt {
|
|
19
19
|
constructor(n = null) {
|
|
20
20
|
this.opt = Object.assign({
|
|
21
21
|
warmupMs: 2e3,
|
|
@@ -264,7 +264,7 @@ class St {
|
|
|
264
264
|
"pivot",
|
|
265
265
|
"helper"
|
|
266
266
|
].forEach((t) => {
|
|
267
|
-
|
|
267
|
+
m = this.getValue(n.name, t), m && (e[t] = m);
|
|
268
268
|
}), e;
|
|
269
269
|
});
|
|
270
270
|
}
|
|
@@ -279,7 +279,7 @@ class St {
|
|
|
279
279
|
this.armature.traverse((i) => {
|
|
280
280
|
e.has(i) || (e.set(i, n), n++);
|
|
281
281
|
}), this.data.sort((i, a) => e.get(i.bone) - e.get(a.bone)), this.data.forEach((i) => {
|
|
282
|
-
|
|
282
|
+
m = this.dict[i.boneParent.name], m && (m.children || (m.children = []), m.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
285
|
o(i).forEach((u) => {
|
|
@@ -321,7 +321,7 @@ class St {
|
|
|
321
321
|
/// Bone's parent object
|
|
322
322
|
vBasis: l.position.clone(),
|
|
323
323
|
// Original local position
|
|
324
|
-
vWorld: l.parent.getWorldPosition(
|
|
324
|
+
vWorld: l.parent.getWorldPosition(U).clone(),
|
|
325
325
|
// World position, parent
|
|
326
326
|
qBasis: l.parent.quaternion.clone(),
|
|
327
327
|
// Original quaternion, parent
|
|
@@ -338,7 +338,7 @@ class St {
|
|
|
338
338
|
ea: [0, 0, 0, 0]
|
|
339
339
|
// External acceleration [m/s^2]
|
|
340
340
|
};
|
|
341
|
-
c.boneParent.matrixWorld.decompose(
|
|
341
|
+
c.boneParent.matrixWorld.decompose(U, Ie, ve), U.copy(qe).applyQuaternion(Ie).setY(0).normalize(), Ie.premultiply(st.setFromUnitVectors(qe, U).invert()).normalize(), c.qWorldInverseYaw = Ie.clone().normalize(), this.data.push(c), this.dict[u] = c;
|
|
342
342
|
try {
|
|
343
343
|
this.setValue(u, "type", s.type), this.setValue(u, "stiffness", s.stiffness), this.setValue(u, "damping", s.damping), this.setValue(u, "external", s.external), this.setValue(u, "limits", s.limits), this.setValue(u, "excludes", s.excludes), this.setValue(u, "deltaLocal", s.deltaLocal), this.setValue(u, "deltaWorld", s.deltaWorld), this.setValue(u, "pivot", s.pivot), this.setValue(u, "helper", s.helper);
|
|
344
344
|
} catch (r) {
|
|
@@ -356,22 +356,22 @@ class St {
|
|
|
356
356
|
for (this.timerMs += n, n > 1e3 && (this.timerMs = 0), n /= 1e3, e = 0, o = this.objectsUpdate.length; e < o; e++)
|
|
357
357
|
i = this.objectsUpdate[e], i.updateMatrix(), i.parent === null ? i.matrixWorld.copy(i.matrix) : i.matrixWorld.multiplyMatrices(i.parent.matrixWorld, i.matrix), i.matrixWorldNeedsUpdate = !1;
|
|
358
358
|
for (e = 0, o = this.data.length; e < o; e++) {
|
|
359
|
-
if (i = this.data[e],
|
|
359
|
+
if (i = this.data[e], U.copy(i.vWorld), Pe.copy(i.boneParent.matrixWorld), Be.copy(Pe).invert(), i.vWorld.setFromMatrixPosition(Pe), U.applyMatrix4(Be), U.length() > 0.5 && (console.info("Info: Unrealistic jump of " + U.length().toFixed(2) + " meters."), U.setLength(0.5)), U.applyQuaternion(i.bone.quaternion), T[0] = U.x, T[1] = U.y, T[2] = -U.z, T[3] = U.length() / 3, i.children)
|
|
360
360
|
for (t = 0, s = i.children.length; t < s; t++)
|
|
361
|
-
|
|
362
|
-
if (
|
|
363
|
-
i.vBasis.x +
|
|
364
|
-
i.vBasis.y +
|
|
365
|
-
i.vBasis.z +
|
|
366
|
-
),
|
|
361
|
+
m = i.children[t], T[0] -= m.v[0] * n / 3, T[1] -= m.v[1] * n / 3, T[2] += m.v[2] * n / 3, T[3] -= m.v[3] * n / 3;
|
|
362
|
+
if (m = this.opt.sensitivityFactor, T[0] *= i.ext * m, T[1] *= i.ext * m, T[2] *= i.ext * m, T[3] *= i.ext * m, i.isX && (m = T[0] / n, i.ea[0] = (m - i.ev[0]) / n, i.ev[0] = m, i.a[0] = -i.k[0] * i.p[0] - i.c[0] * i.v[0] - i.ea[0], i.p[0] += i.v[0] * n + i.a[0] * n * n / 2 + T[0], m = i.v[0] + i.a[0] * n / 2, m = -i.k[0] * i.p[0] - i.c[0] * m - i.ea[0], i.v[0] = i.v[0] + (m + i.a[0]) * n / 2), i.isY && (m = T[1] / n, i.ea[1] = (m - i.ev[1]) / n, i.ev[1] = m, i.a[1] = -i.k[1] * i.p[1] - i.c[1] * i.v[1] - i.ea[1], i.p[1] += i.v[1] * n + i.a[1] * n * n / 2 + T[1], m = i.v[1] + i.a[1] * n / 2, m = -i.k[1] * i.p[1] - i.c[1] * m - i.ea[1], i.v[1] = i.v[1] + (m + i.a[1]) * n / 2), i.isZ && (m = T[2] / n, i.ea[2] = (m - i.ev[2]) / n, i.ev[2] = m, i.a[2] = -i.k[2] * i.p[2] - i.c[2] * i.v[2] - i.ea[2], i.p[2] += i.v[2] * n + i.a[2] * n * n / 2 + T[2], m = i.v[2] + i.a[2] * n / 2, m = -i.k[2] * i.p[2] - i.c[2] * m - i.ea[2], i.v[2] = i.v[2] + (m + i.a[2]) * n / 2), i.isT && (m = T[3] / n, i.ea[3] = (m - i.ev[3]) / n, i.ev[3] = m, i.a[3] = -i.k[3] * i.p[3] - i.c[3] * i.v[3] - i.ea[3], i.p[3] += i.v[3] * n + i.a[3] * n * n / 2 + T[3], m = i.v[3] + i.a[3] * n / 2, m = -i.k[3] * i.p[3] - i.c[3] * m - i.ea[3], i.v[3] = i.v[3] + (m + i.a[3]) * n / 2), this.timerMs < this.opt.warmupMs && (i.v[0] *= 1e-4, i.p[0] *= 1e-4, i.v[1] *= 1e-4, i.p[1] *= 1e-4, i.v[2] *= 1e-4, i.p[2] *= 1e-4, i.v[3] *= 1e-4, i.p[3] *= 1e-4), T[0] = i.p[0], T[1] = i.p[1], T[2] = i.p[2], T[3] = i.p[3], m = this.opt.movementFactor, T[0] *= m, T[1] *= m, T[2] *= m, T[3] *= m, i.dl && (m = i.dl, T[0] += m[0], T[1] += m[1], T[2] += m[2]), i.dw && (m = i.dw, U.set(
|
|
363
|
+
i.vBasis.x + T[0],
|
|
364
|
+
i.vBasis.y + T[1],
|
|
365
|
+
i.vBasis.z + T[2]
|
|
366
|
+
), U.applyMatrix4(Pe), U.x += m[0], U.y += m[1], U.z += m[2], U.applyMatrix4(Be), T[0] += U.x - i.vBasis.x, T[1] += U.y - i.vBasis.y, T[2] += U.z - i.vBasis.z), i.limits && this.opt.isLimits && (m = i.limits, m[0] && (m[0][0] !== null && T[0] < m[0][0] && (T[0] = m[0][0]), m[0][1] !== null && T[0] > m[0][1] && (T[0] = m[0][1])), m[1] && (m[1][0] !== null && T[1] < m[1][0] && (T[1] = m[1][0]), m[1][1] !== null && T[1] > m[1][1] && (T[1] = m[1][1])), m[2] && (m[2][0] !== null && T[2] < m[2][0] && (T[2] = m[2][0]), m[2][1] !== null && T[2] > m[2][1] && (T[2] = m[2][1])), m[3] && (m[3][0] !== null && T[3] < m[3][0] && (T[3] = m[3][0]), m[3][1] !== null && T[3] > m[3][1] && (T[3] = m[3][1]))), i.isPoint)
|
|
367
367
|
i.bone.position.set(
|
|
368
|
-
i.vBasis.x +
|
|
369
|
-
i.vBasis.y +
|
|
370
|
-
i.vBasis.z -
|
|
368
|
+
i.vBasis.x + T[0],
|
|
369
|
+
i.vBasis.y + T[1],
|
|
370
|
+
i.vBasis.z - T[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(
|
|
372
|
+
else if (i.boneParent.quaternion.copy(i.qBasis), i.pivot && this.opt.isPivots && (i.boneParent.updateWorldMatrix(!1, !1), i.boneParent.matrixWorld.decompose(U, Ie, ve), U.copy(qe).applyQuaternion(Ie).setY(0).normalize(), Ie.premultiply(st.setFromUnitVectors(qe, U).invert()).normalize(), i.boneParent.quaternion.multiply(Ie.invert()), i.boneParent.quaternion.multiply(i.qWorldInverseYaw)), i.isZ && (m = Math.atan(T[0] / i.l), Ie.setFromAxisAngle(St, -m), i.boneParent.quaternion.multiply(Ie)), i.isY && (m = i.l / 3, m = m * Math.tanh(T[1] / m), i.bone.position.setLength(i.l + m)), i.isX && (m = Math.atan(T[2] / i.l), Ie.setFromAxisAngle(It, -m), i.boneParent.quaternion.multiply(Ie)), i.isT && (m = 1.5 * Math.tanh(T[3] * 1.5), Ie.setFromAxisAngle(Lt, -m), i.boneParent.quaternion.multiply(Ie)), i.boneParent.updateWorldMatrix(!1, !0), i.excludes && this.opt.isExcludes)
|
|
373
373
|
for (t = 0, s = i.excludes.length; t < s; t++)
|
|
374
|
-
|
|
374
|
+
m = i.excludes[t], ve.set(0, 0, 0), m.deltaLocal && (ve.x += m.deltaLocal[0], ve.y += m.deltaLocal[1], ve.z += m.deltaLocal[2]), ve.applyMatrix4(m.bone.matrixWorld), Be.copy(i.boneParent.matrixWorld).invert(), ve.applyMatrix4(Be), U.copy(i.bone.position), !(U.distanceToSquared(ve) >= m.radiusSq) && (He = U.length(), Ce = ve.length(), !(Ce > m.radius + He) && (Ce < Math.abs(m.radius - He) || (Ce = (Ce * Ce + He * He - m.radiusSq) / (2 * Ce), ve.normalize(), Ye.copy(ve).multiplyScalar(Ce), Ce = Math.sqrt(He * He - Ce * Ce), U.subVectors(U, Ye).projectOnPlane(ve).normalize().multiplyScalar(Ce), Qe.subVectors(i.vBasis, Ye).projectOnPlane(ve).normalize(), He = Qe.dot(U), He < 0 && (He = Math.sqrt(Ce * Ce - He * He), Qe.multiplyScalar(He), U.add(Qe)), U.add(Ye).normalize(), ve.copy(i.bone.position).normalize(), Ie.setFromUnitVectors(ve, U), i.boneParent.quaternion.premultiply(Ie), i.boneParent.updateWorldMatrix(!1, !0))));
|
|
375
375
|
}
|
|
376
376
|
this.helpers.isActive && this.updateHelpers();
|
|
377
377
|
}
|
|
@@ -382,18 +382,18 @@ class St {
|
|
|
382
382
|
* @param {boolean} [keepSetting=false] If true, keep the previos all setting
|
|
383
383
|
*/
|
|
384
384
|
showHelpers(n) {
|
|
385
|
-
if (this.hideHelpers(), this.helpers.isShowAll = n === void 0 ? this.helpers.isShowAll : n === !0,
|
|
386
|
-
(this.helpers.isShowAll || e.helper === !0) && (
|
|
385
|
+
if (this.hideHelpers(), this.helpers.isShowAll = n === void 0 ? this.helpers.isShowAll : n === !0, m = this.helpers, this.data.forEach((e) => {
|
|
386
|
+
(this.helpers.isShowAll || e.helper === !0) && (m.points.bones.push(e.bone), m.points.pivots.push(e.pivot), e.type !== 0 && m.lines.bones.push(e.bone), e.excludes && e.excludes.forEach((t) => {
|
|
387
387
|
let o = !1;
|
|
388
|
-
for (let s = 0; s <
|
|
389
|
-
if (
|
|
388
|
+
for (let s = 0; s < m.excludes.bones.length; s++)
|
|
389
|
+
if (m.excludes.bones[s] === t.bone && m.excludes.radii[s] === t.radius && !(m.excludes.deltaLocals[s] === null && t.deltaLocal !== null) && !(m.excludes.deltaLocals[s] !== null && t.deltaLocal === null) && !(m.excludes.deltaLocals[s] !== null && m.excludes.deltaLocals[s].some((i, a) => i !== t.deltaLocal[a]))) {
|
|
390
390
|
o = !0;
|
|
391
391
|
break;
|
|
392
392
|
}
|
|
393
|
-
o || (
|
|
393
|
+
o || (m.excludes.bones.push(t.bone), m.excludes.radii.push(t.radius), m.excludes.deltaLocals.push(t.deltaLocal ? [...t.deltaLocal] : null), m.excludes.objects.push(null));
|
|
394
394
|
}));
|
|
395
|
-
}),
|
|
396
|
-
const o = new A.SphereGeometry(
|
|
395
|
+
}), m = this.helpers.excludes, this.opt.isExcludes && m.bones.length && m.bones.forEach((e, t) => {
|
|
396
|
+
const o = new A.SphereGeometry(m.radii[t], 6, 6), s = new A.MeshBasicMaterial({
|
|
397
397
|
depthTest: !1,
|
|
398
398
|
depthWrite: !1,
|
|
399
399
|
toneMapped: !1,
|
|
@@ -401,16 +401,16 @@ class St {
|
|
|
401
401
|
wireframe: !0,
|
|
402
402
|
color: this.opt.helperExcludesColor
|
|
403
403
|
});
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
404
|
+
m.objects[t] = new A.Mesh(o, s), m.objects[t].renderOrder = 997, e.add(m.objects[t]), m.deltaLocals[t] && m.objects[t].position.set(
|
|
405
|
+
m.deltaLocals[t][0],
|
|
406
|
+
m.deltaLocals[t][1],
|
|
407
|
+
m.deltaLocals[t][2]
|
|
408
408
|
);
|
|
409
|
-
}),
|
|
409
|
+
}), m = this.helpers.points, m.bones.length) {
|
|
410
410
|
this.helpers.isActive = !0;
|
|
411
|
-
const e = new A.BufferGeometry(), t =
|
|
411
|
+
const e = new A.BufferGeometry(), t = m.bones.map((u) => [0, 0, 0]).flat();
|
|
412
412
|
e.setAttribute("position", new A.Float32BufferAttribute(t, 3));
|
|
413
|
-
const o = new A.Color(this.opt.helperBoneColor1), s = new A.Color(this.opt.helperBoneColor2), i =
|
|
413
|
+
const o = new A.Color(this.opt.helperBoneColor1), s = new A.Color(this.opt.helperBoneColor2), i = m.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 A.Float32BufferAttribute(i, 3));
|
|
415
415
|
const a = new A.PointsMaterial({
|
|
416
416
|
depthTest: !1,
|
|
@@ -420,12 +420,12 @@ class St {
|
|
|
420
420
|
size: 0.2,
|
|
421
421
|
vertexColors: !0
|
|
422
422
|
});
|
|
423
|
-
|
|
423
|
+
m.object = new A.Points(e, a), m.object.renderOrder = 998, m.object.matrix = this.armature.matrixWorld, m.object.matrixAutoUpdate = !1, this.scene.add(m.object);
|
|
424
424
|
}
|
|
425
|
-
if (
|
|
426
|
-
const e = new A.BufferGeometry(), t =
|
|
425
|
+
if (m = this.helpers.lines, m.bones.length) {
|
|
426
|
+
const e = new A.BufferGeometry(), t = m.bones.map((u) => [0, 0, 0, 0, 0, 0]).flat();
|
|
427
427
|
e.setAttribute("position", new A.Float32BufferAttribute(t, 3));
|
|
428
|
-
const o = new A.Color(this.opt.helperLinkColor1), s = new A.Color(this.opt.helperLinkColor2), i =
|
|
428
|
+
const o = new A.Color(this.opt.helperLinkColor1), s = new A.Color(this.opt.helperLinkColor2), i = m.bones.map((u) => [o.r, o.g, o.b, s.r, s.g, s.b]).flat();
|
|
429
429
|
e.setAttribute("color", new A.Float32BufferAttribute(i, 3));
|
|
430
430
|
const a = new A.LineBasicMaterial({
|
|
431
431
|
vertexColors: !0,
|
|
@@ -434,26 +434,26 @@ class St {
|
|
|
434
434
|
toneMapped: !1,
|
|
435
435
|
transparent: !0
|
|
436
436
|
});
|
|
437
|
-
|
|
437
|
+
m.object = new A.LineSegments(e, a), m.object.renderOrder = 999, m.object.matrix = this.armature.matrixWorld, m.object.matrixAutoUpdate = !1, this.scene.add(m.object);
|
|
438
438
|
}
|
|
439
439
|
}
|
|
440
440
|
/**
|
|
441
441
|
* Update the positions of dynamic bone helpers.
|
|
442
442
|
*/
|
|
443
443
|
updateHelpers() {
|
|
444
|
-
if (
|
|
445
|
-
|
|
446
|
-
const n =
|
|
447
|
-
for (let e = 0, t =
|
|
448
|
-
|
|
449
|
-
n.needsUpdate = !0,
|
|
444
|
+
if (m = this.helpers.points, m.bones.length) {
|
|
445
|
+
Be.copy(this.armature.matrixWorld).invert();
|
|
446
|
+
const n = m.object.geometry.getAttribute("position");
|
|
447
|
+
for (let e = 0, t = m.bones.length; e < t; e++)
|
|
448
|
+
Pe.multiplyMatrices(Be, m.bones[e].matrixWorld), U.setFromMatrixPosition(Pe), n.setXYZ(e, U.x, U.y, U.z);
|
|
449
|
+
n.needsUpdate = !0, m.object.updateMatrixWorld();
|
|
450
450
|
}
|
|
451
|
-
if (
|
|
452
|
-
|
|
453
|
-
const n =
|
|
454
|
-
for (let e = 0, t = 0, o =
|
|
455
|
-
|
|
456
|
-
n.needsUpdate = !0,
|
|
451
|
+
if (m = this.helpers.lines, m.bones.length) {
|
|
452
|
+
Be.copy(this.armature.matrixWorld).invert();
|
|
453
|
+
const n = m.object.geometry.getAttribute("position");
|
|
454
|
+
for (let e = 0, t = 0, o = m.bones.length; e < o; e++, t += 2)
|
|
455
|
+
Pe.multiplyMatrices(Be, m.bones[e].matrixWorld), U.setFromMatrixPosition(Pe), n.setXYZ(t, U.x, U.y, U.z), Pe.multiplyMatrices(Be, m.bones[e].parent.matrixWorld), U.setFromMatrixPosition(Pe), n.setXYZ(t + 1, U.x, U.y, U.z);
|
|
456
|
+
n.needsUpdate = !0, m.object.updateMatrixWorld();
|
|
457
457
|
}
|
|
458
458
|
}
|
|
459
459
|
/**
|
|
@@ -462,9 +462,9 @@ class St {
|
|
|
462
462
|
hideHelpers() {
|
|
463
463
|
[this.helpers.points, this.helpers.lines].forEach((n) => {
|
|
464
464
|
n.bones = [], n.object && (this.scene.remove(n.object), n.object.geometry.dispose(), n.object.material.dispose(), n.object = null);
|
|
465
|
-
}),
|
|
466
|
-
n && (
|
|
467
|
-
}),
|
|
465
|
+
}), m = this.helpers.excludes, m.objects.forEach((n, e) => {
|
|
466
|
+
n && (m.bones[e].remove(n), n.geometry.dispose(), n.material.dispose());
|
|
467
|
+
}), m.bones = [], m.deltaLocals = [], m.radii = [], m.objects = [], this.helpers.isActive = !1;
|
|
468
468
|
}
|
|
469
469
|
/**
|
|
470
470
|
* Start dynamic bones.
|
|
@@ -489,7 +489,7 @@ class St {
|
|
|
489
489
|
this.stop(), this.scene = null, this.armature = null, this.config = [], this.data = [], this.dict = {}, this.objectsUpdate = [], this.timerMs = 0;
|
|
490
490
|
}
|
|
491
491
|
}
|
|
492
|
-
class
|
|
492
|
+
class wt {
|
|
493
493
|
constructor(n) {
|
|
494
494
|
this.audioContext = n, this.analyzer = null, this.dataArray = null, this.bufferLength = 0;
|
|
495
495
|
}
|
|
@@ -525,8 +525,8 @@ class kt {
|
|
|
525
525
|
t.spectralCentroid.push(h);
|
|
526
526
|
const d = this.calculateZeroCrossingRate(c);
|
|
527
527
|
t.zeroCrossingRate.push(d);
|
|
528
|
-
const
|
|
529
|
-
t.mfcc.push(
|
|
528
|
+
const p = this.calculateMFCC(c);
|
|
529
|
+
t.mfcc.push(p);
|
|
530
530
|
}
|
|
531
531
|
return t.onsets = this.detectOnsets(t.energy), t.phonemeBoundaries = this.detectPhonemeBoundaries(t), t;
|
|
532
532
|
}
|
|
@@ -606,10 +606,10 @@ class kt {
|
|
|
606
606
|
for (let u = 0; u < e; u += o) {
|
|
607
607
|
let l = 1, c = 0;
|
|
608
608
|
for (let r = 0; r < o / 2; r++) {
|
|
609
|
-
const h = t[(u + r) * 2], d = t[(u + r) * 2 + 1],
|
|
610
|
-
t[(u + r) * 2] = h +
|
|
611
|
-
const
|
|
612
|
-
l =
|
|
609
|
+
const h = t[(u + r) * 2], d = t[(u + r) * 2 + 1], p = t[(u + r + o / 2) * 2] * l - t[(u + r + o / 2) * 2 + 1] * c, b = t[(u + r + o / 2) * 2] * c + t[(u + r + o / 2) * 2 + 1] * l;
|
|
610
|
+
t[(u + r) * 2] = h + p, t[(u + r) * 2 + 1] = d + b, t[(u + r + o / 2) * 2] = h - p, t[(u + r + o / 2) * 2 + 1] = d - b;
|
|
611
|
+
const f = l * i - c * a, L = l * a + c * i;
|
|
612
|
+
l = f, c = L;
|
|
613
613
|
}
|
|
614
614
|
}
|
|
615
615
|
}
|
|
@@ -814,7 +814,7 @@ class kt {
|
|
|
814
814
|
return o * s;
|
|
815
815
|
}
|
|
816
816
|
}
|
|
817
|
-
class
|
|
817
|
+
class Ct {
|
|
818
818
|
/**
|
|
819
819
|
* @constructor
|
|
820
820
|
*/
|
|
@@ -1208,10 +1208,10 @@ class wt {
|
|
|
1208
1208
|
this.rules[e] = this.rules[e].map((t) => {
|
|
1209
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
|
-
h += [...a].map((
|
|
1211
|
+
h += [...a].map((p) => n[p] || p).join("");
|
|
1212
1212
|
const d = [...u];
|
|
1213
|
-
return d[0] = d[0].toLowerCase(), h += d.join(""), r.move = d.length, h += [...l].map((
|
|
1214
|
-
r.visemes.push(
|
|
1213
|
+
return d[0] = d[0].toLowerCase(), h += d.join(""), r.move = d.length, h += [...l].map((p) => n[p] || p).join(""), r.regex = new RegExp(h), c.length && c.split(" ").forEach((p) => {
|
|
1214
|
+
r.visemes.push(p);
|
|
1215
1215
|
}), r;
|
|
1216
1216
|
});
|
|
1217
1217
|
}), this.visemeDurations = {
|
|
@@ -1396,11 +1396,11 @@ class wt {
|
|
|
1396
1396
|
return e;
|
|
1397
1397
|
}
|
|
1398
1398
|
}
|
|
1399
|
-
const
|
|
1399
|
+
const zt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
1400
1400
|
__proto__: null,
|
|
1401
|
-
LipsyncEn:
|
|
1401
|
+
LipsyncEn: Ct
|
|
1402
1402
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
1403
|
-
class
|
|
1403
|
+
class Ht {
|
|
1404
1404
|
/**
|
|
1405
1405
|
* @constructor
|
|
1406
1406
|
*/
|
|
@@ -1618,10 +1618,10 @@ class zt {
|
|
|
1618
1618
|
this.rules[e] = this.rules[e].map((t) => {
|
|
1619
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
|
-
h += [...a].map((
|
|
1621
|
+
h += [...a].map((p) => n[p] || p).join("");
|
|
1622
1622
|
const d = [...u];
|
|
1623
|
-
return d[0] = d[0].toLowerCase(), h += d.join(""), r.move = d.length, h += [...l].map((
|
|
1624
|
-
r.visemes.push(
|
|
1623
|
+
return d[0] = d[0].toLowerCase(), h += d.join(""), r.move = d.length, h += [...l].map((p) => n[p] || p).join(""), r.regex = new RegExp(h), c.length && c.split(" ").forEach((p) => {
|
|
1624
|
+
r.visemes.push(p);
|
|
1625
1625
|
}), r;
|
|
1626
1626
|
});
|
|
1627
1627
|
}), this.visemeDurations = {
|
|
@@ -1754,11 +1754,11 @@ class zt {
|
|
|
1754
1754
|
return e;
|
|
1755
1755
|
}
|
|
1756
1756
|
}
|
|
1757
|
-
const
|
|
1757
|
+
const Tt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
1758
1758
|
__proto__: null,
|
|
1759
|
-
LipsyncDe:
|
|
1759
|
+
LipsyncDe: Ht
|
|
1760
1760
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
1761
|
-
class
|
|
1761
|
+
class Ft {
|
|
1762
1762
|
/**
|
|
1763
1763
|
* @constructor
|
|
1764
1764
|
*/
|
|
@@ -2133,10 +2133,10 @@ class Tt {
|
|
|
2133
2133
|
this.rules[e] = this.rules[e].map((t) => {
|
|
2134
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
|
-
h += [...a].map((
|
|
2136
|
+
h += [...a].map((p) => n[p] || p).join("");
|
|
2137
2137
|
const d = [...u];
|
|
2138
|
-
return d[0] = d[0].toLowerCase(), h += d.join(""), r.move = d.length, h += [...l].map((
|
|
2139
|
-
|
|
2138
|
+
return d[0] = d[0].toLowerCase(), h += d.join(""), r.move = d.length, h += [...l].map((p) => n[p] || p).join(""), r.regex = new RegExp(h, "i"), c.length && c.split(" ").forEach((p) => {
|
|
2139
|
+
p && r.visemes.push(p);
|
|
2140
2140
|
}), r;
|
|
2141
2141
|
});
|
|
2142
2142
|
}), this.visemeDurations = {
|
|
@@ -2289,11 +2289,11 @@ class Tt {
|
|
|
2289
2289
|
return e;
|
|
2290
2290
|
}
|
|
2291
2291
|
}
|
|
2292
|
-
const
|
|
2292
|
+
const Mt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
2293
2293
|
__proto__: null,
|
|
2294
|
-
LipsyncFr:
|
|
2294
|
+
LipsyncFr: Ft
|
|
2295
2295
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
2296
|
-
class
|
|
2296
|
+
class Et {
|
|
2297
2297
|
/**
|
|
2298
2298
|
* @constructor
|
|
2299
2299
|
*/
|
|
@@ -2436,11 +2436,11 @@ class Mt {
|
|
|
2436
2436
|
return e;
|
|
2437
2437
|
}
|
|
2438
2438
|
}
|
|
2439
|
-
const
|
|
2439
|
+
const Pt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
2440
2440
|
__proto__: null,
|
|
2441
|
-
LipsyncFi:
|
|
2441
|
+
LipsyncFi: Et
|
|
2442
2442
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
2443
|
-
class
|
|
2443
|
+
class Bt {
|
|
2444
2444
|
/**
|
|
2445
2445
|
* @constructor
|
|
2446
2446
|
*/
|
|
@@ -2620,21 +2620,21 @@ class Pt {
|
|
|
2620
2620
|
return e;
|
|
2621
2621
|
}
|
|
2622
2622
|
}
|
|
2623
|
-
const
|
|
2623
|
+
const Ot = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
2624
2624
|
__proto__: null,
|
|
2625
|
-
LipsyncLt:
|
|
2626
|
-
}, Symbol.toStringTag, { value: "Module" })), Ot = new URL("data:text/javascript;base64,Y2xhc3MgUGxheWJhY2tXb3JrbGV0IGV4dGVuZHMgQXVkaW9Xb3JrbGV0UHJvY2Vzc29yIHsKICBzdGF0aWMgRlNNID0gewogICAgSURMRTogMCwKICAgIFBMQVlJTkc6IDEsCiAgfTsKCiAgY29uc3RydWN0b3Iob3B0aW9ucykgewogICAgc3VwZXIoKTsKICAgIHRoaXMucG9ydC5vbm1lc3NhZ2UgPSB0aGlzLmhhbmRsZU1lc3NhZ2UuYmluZCh0aGlzKTsKCiAgICB0aGlzLl9zYW1wbGVSYXRlID0gb3B0aW9ucz8ucHJvY2Vzc29yT3B0aW9ucz8uc2FtcGxlUmF0ZSB8fCBzYW1wbGVSYXRlOwogICAgdGhpcy5fc2NhbGUgPSAxIC8gMzI3Njg7IC8vIFBDTTE2IC0+IGZsb2F0CgogICAgLy8gU2lsZW5jZSBkZXRlY3Rpb24gdGhyZXNob2xkICgxIHNlY29uZCkgYXMgYSBmYWxsYmFjayBzYWZldHkgbmV0CiAgICBjb25zdCBzaWxlbmNlRHVyYXRpb25TZWNvbmRzID0gMS4wOwogICAgdGhpcy5fc2lsZW5jZVRocmVzaG9sZEJsb2NrcyA9IE1hdGguY2VpbCgodGhpcy5fc2FtcGxlUmF0ZSAqIHNpbGVuY2VEdXJhdGlvblNlY29uZHMpIC8gMTI4KTsKCiAgICAvLyBNZXRyaWNzIGNvbmZpZ3VyYXRpb24gdmlhIG9wdGlvbnMKICAgIGNvbnN0IG1ldHJpY3NDZmcgPSBvcHRpb25zPy5wcm9jZXNzb3JPcHRpb25zPy5tZXRyaWNzIHx8IHt9OwogICAgdGhpcy5fbWV0cmljc0VuYWJsZWQgPSBtZXRyaWNzQ2ZnLmVuYWJsZWQgIT09IGZhbHNlOwogICAgY29uc3QgaW50ZXJ2YWxIeiA9ICh0eXBlb2YgbWV0cmljc0NmZy5pbnRlcnZhbEh6ID09PSAibnVtYmVyIiAmJiBtZXRyaWNzQ2ZnLmludGVydmFsSHogPiAwKQogICAgICA/IG1ldHJpY3NDZmcuaW50ZXJ2YWxIeiA6IDI7CiAgICAvLyBNZXRyaWNzIHN0YXRlIChsb3ctb3ZlcmhlYWQpCiAgICB0aGlzLl9mcmFtZXNQcm9jZXNzZWQgPSAwOwogICAgdGhpcy5fdW5kZXJydW5CbG9ja3MgPSAwOwogICAgdGhpcy5fbWF4UXVldWVTYW1wbGVzID0gMDsKICAgIHRoaXMuX2xhc3RNZXRyaWNzU2VudEF0RnJhbWUgPSAwOwogICAgLy8gQ29udmVydCB0byBmcmFtZXMgYmV0d2VlbiByZXBvcnRzCiAgICB0aGlzLl9tZXRyaWNzSW50ZXJ2YWxGcmFtZXMgPSBNYXRoLm1heCgxMjgsIE1hdGgucm91bmQodGhpcy5fc2FtcGxlUmF0ZSAvIGludGVydmFsSHopKTsKCiAgICB0aGlzLnJlc2V0KCk7CiAgfQoKICAvKioKICAgKiBSZXNldHMgdGhlIHdvcmtsZXQgdG8gaXRzIGluaXRpYWwgSURMRSBzdGF0ZS4KICAgKi8KICByZXNldCgpIHsKICAgIHRoaXMuX2J1ZmZlclF1ZXVlID0gW107CiAgICB0aGlzLl9jdXJyZW50Q2h1bmsgPSBudWxsOwogICAgdGhpcy5fY3VycmVudENodW5rT2Zmc2V0ID0gMDsKICAgIHRoaXMuX3N0YXRlID0gUGxheWJhY2tXb3JrbGV0LkZTTS5JRExFOwoKICAgIHRoaXMuX25vTW9yZURhdGFSZWNlaXZlZCA9IGZhbHNlOwogICAgdGhpcy5fc2lsZW5jZUZyYW1lc0NvdW50ID0gMDsKICAgIHRoaXMuX2hhc1NlbnRFbmRlZCA9IGZhbHNlOwogICAgLy8gUmVzZXQgbWF4IHF1ZXVlIHRyYWNrZXIgb25seSB3aGVuIGdvaW5nIGlkbGUKICAgIHRoaXMuX21heFF1ZXVlU2FtcGxlcyA9IDA7CiAgfQoKICBoYW5kbGVNZXNzYWdlKGV2ZW50KSB7CiAgICBjb25zdCB7IHR5cGUsIGRhdGEgfSA9IGV2ZW50LmRhdGE7CgogICAgLy8gSU5URVJSVVBUOiBUaGUgbWFpbiB0aHJlYWQgd2FudHMgdG8gc3RvcCBpbW1lZGlhdGVseS4KICAgIGlmICh0eXBlID09PSAic3RvcCIpIHsKICAgICAgdGhpcy5yZXNldCgpOwogICAgICAvLyBTZW5kIGZpbmFsIG1ldHJpY3Mgc2hvd2luZyBjbGVhcmVkIHN0YXRlCiAgICAgIGlmICh0aGlzLl9tZXRyaWNzRW5hYmxlZCkgewogICAgICAgIHRyeSB7CiAgICAgICAgICB0aGlzLnBvcnQucG9zdE1lc3NhZ2UoewogICAgICAgICAgICB0eXBlOiAibWV0cmljcyIsCiAgICAgICAgICAgIGRhdGE6IHsKICAgICAgICAgICAgICBzdGF0ZTogUGxheWJhY2tXb3JrbGV0LkZTTS5JRExFLAogICAgICAgICAgICAgIHF1ZXVlZFNhbXBsZXM6IDAsCiAgICAgICAgICAgICAgcXVldWVkTXM6IDAsCiAgICAgICAgICAgICAgbWF4UXVldWVkTXM6IE1hdGgucm91bmQoKHRoaXMuX21heFF1ZXVlU2FtcGxlcyAvIHRoaXMuX3NhbXBsZVJhdGUpICogMTAwMCksCiAgICAgICAgICAgICAgdW5kZXJydW5CbG9ja3M6IHRoaXMuX3VuZGVycnVuQmxvY2tzLAogICAgICAgICAgICAgIGZyYW1lc1Byb2Nlc3NlZDogdGhpcy5fZnJhbWVzUHJvY2Vzc2VkCiAgICAgICAgICAgIH0KICAgICAgICAgIH0pOwogICAgICAgIH0gY2F0Y2ggKF8pIHsgfQogICAgICB9CiAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBNYWluIHRocmVhZCBoYXMgc2lnbmFsZWQgdGhhdCBubyBtb3JlIGF1ZGlvIGNodW5rcyB3aWxsIGJlIHNlbnQgZm9yIHRoaXMgdXR0ZXJhbmNlLgogICAgaWYgKHR5cGUgPT09ICJuby1tb3JlLWRhdGEiKSB7CiAgICAgIHRoaXMuX25vTW9yZURhdGFSZWNlaXZlZCA9IHRydWU7CiAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBVcGRhdGUgbWV0cmljcyBjb25maWd1cmF0aW9uIGF0IHJ1bnRpbWUKICAgIGlmICh0eXBlID09PSAiY29uZmlnLW1ldHJpY3MiICYmIGRhdGEgJiYgdHlwZW9mIGRhdGEgPT09ICJvYmplY3QiKSB7CiAgICAgIGlmICgiZW5hYmxlZCIgaW4gZGF0YSkgdGhpcy5fbWV0cmljc0VuYWJsZWQgPSAhIWRhdGEuZW5hYmxlZDsKICAgICAgaWYgKHR5cGVvZiBkYXRhLmludGVydmFsSHogPT09ICJudW1iZXIiICYmIGRhdGEuaW50ZXJ2YWxIeiA+IDApIHsKICAgICAgICBjb25zdCBpbnRlcnZhbEh6ID0gZGF0YS5pbnRlcnZhbEh6OwogICAgICAgIHRoaXMuX21ldHJpY3NJbnRlcnZhbEZyYW1lcyA9IE1hdGgubWF4KDEyOCwgTWF0aC5yb3VuZCh0aGlzLl9zYW1wbGVSYXRlIC8gaW50ZXJ2YWxIeikpOwogICAgICB9CiAgICAgIC8vIFJlc2V0IHBhY2luZyBzbyB0aGUgbmV4dCByZXBvcnQgYWxpZ25zIHdpdGggbmV3IGludGVydmFsCiAgICAgIHRoaXMuX2xhc3RNZXRyaWNzU2VudEF0RnJhbWUgPSB0aGlzLl9mcmFtZXNQcm9jZXNzZWQ7CiAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBOZXcgYXVkaW8gZGF0YSBoYXMgYXJyaXZlZC4KICAgIGlmICh0eXBlID09PSAiYXVkaW9EYXRhIiAmJiBkYXRhIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHsKICAgICAgdGhpcy5fbm9Nb3JlRGF0YVJlY2VpdmVkID0gZmFsc2U7CiAgICAgIC8vIElmIHdlIHdlcmUgaWRsZSwgdGhpcyBuZXcgZGF0YSBraWNrcyBvZmYgdGhlIHBsYXliYWNrLgogICAgICBpZiAodGhpcy5fc3RhdGUgPT09IFBsYXliYWNrV29ya2xldC5GU00uSURMRSkgewogICAgICAgIHRoaXMuX3N0YXRlID0gUGxheWJhY2tXb3JrbGV0LkZTTS5QTEFZSU5HOwogICAgICAgIHRoaXMucG9ydC5wb3N0TWVzc2FnZSh7IHR5cGU6ICJwbGF5YmFjay1zdGFydGVkIiB9KTsKICAgICAgfQoKICAgICAgLy8gV2Ugb25seSBxdWV1ZSBkYXRhIGlmIHdlIGFyZSBpbiB0aGUgUExBWUlORyBzdGF0ZS4gVGhpcyBwcmV2ZW50cwogICAgICAvLyBkYXRhIGZyb20gYSBwcmV2aW91cywgaW50ZXJydXB0ZWQgc3RyZWFtIGZyb20gbGluZ2VyaW5nLgogICAgICBpZiAodGhpcy5fc3RhdGUgPT09IFBsYXliYWNrV29ya2xldC5GU00uUExBWUlORykgewogICAgICAgIC8vIFN0b3JlIGFzIEludDE2QXJyYXkgdmlldyB0byBhdm9pZCBjb25zdHJ1Y3RpbmcgaXQgaW4gcHJvY2VzcygpCiAgICAgICAgdGhpcy5fYnVmZmVyUXVldWUucHVzaChuZXcgSW50MTZBcnJheShkYXRhKSk7CiAgICAgICAgdGhpcy5fc2lsZW5jZUZyYW1lc0NvdW50ID0gMDsgLy8gUmVzZXQgc2lsZW5jZSBjb3VudGVyIG9uIG5ldyBkYXRhCiAgICAgIH0KICAgIH0KICB9CgogIHByb2Nlc3MoaW5wdXRzLCBvdXRwdXRzLCBwYXJhbWV0ZXJzKSB7CiAgICBjb25zdCBvdXRwdXRDaGFubmVsID0gb3V0cHV0c1swXT8uWzBdOwogICAgaWYgKCFvdXRwdXRDaGFubmVsKSB7CiAgICAgIHJldHVybiB0cnVlOyAvLyBLZWVwIGFsaXZlIGV2ZW4gaWYgb3V0cHV0IGlzIHRlbXBvcmFyaWx5IGRpc2Nvbm5lY3RlZAogICAgfQoKICAgIC8vIElmIHdlIGFyZSBub3QgcGxheWluZywganVzdCBvdXRwdXQgc2lsZW5jZSBhbmQgd2FpdC4KICAgIGlmICh0aGlzLl9zdGF0ZSAhPT0gUGxheWJhY2tXb3JrbGV0LkZTTS5QTEFZSU5HKSB7CiAgICAgIG91dHB1dENoYW5uZWwuZmlsbCgwKTsKICAgICAgcmV0dXJuIHRydWU7IC8vIEFsd2F5cyByZXR1cm4gdHJ1ZSB0byBrZWVwIHRoZSBwcm9jZXNzb3IgYWxpdmUKICAgIH0KCiAgICAvLyBDb3JlIFBMQVlJTkcgTG9naWMKICAgIGNvbnN0IGJsb2NrU2l6ZSA9IG91dHB1dENoYW5uZWwubGVuZ3RoOwogICAgbGV0IHNhbXBsZXNDb3BpZWQgPSAwOwoKICAgIHdoaWxlIChzYW1wbGVzQ29waWVkIDwgYmxvY2tTaXplKSB7CiAgICAgIGlmICghdGhpcy5fY3VycmVudENodW5rIHx8IHRoaXMuX2N1cnJlbnRDaHVua09mZnNldCA+PSB0aGlzLl9jdXJyZW50Q2h1bmsubGVuZ3RoKSB7CiAgICAgICAgaWYgKHRoaXMuX2J1ZmZlclF1ZXVlLmxlbmd0aCA+IDApIHsKICAgICAgICAgIHRoaXMuX2N1cnJlbnRDaHVuayA9IHRoaXMuX2J1ZmZlclF1ZXVlLnNoaWZ0KCk7CiAgICAgICAgICB0aGlzLl9jdXJyZW50Q2h1bmtPZmZzZXQgPSAwOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAvLyBCdWZmZXIgaXMgZW1wdHkuIENoZWNrIGZvciBlbmQgY29uZGl0aW9ucy4KICAgICAgICAgIGNvbnN0IGlzVGltZWRPdXQgPSB0aGlzLl9zaWxlbmNlRnJhbWVzQ291bnQgPiB0aGlzLl9zaWxlbmNlVGhyZXNob2xkQmxvY2tzOwoKICAgICAgICAgIGlmICh0aGlzLl9ub01vcmVEYXRhUmVjZWl2ZWQgfHwgaXNUaW1lZE91dCkgewogICAgICAgICAgICAvLyBFTkQgT0YgUExBWUJBQ0s6IEVpdGhlciBleHBsaWNpdGx5IHNpZ25hbGVkIG9yIHRpbWVkIG91dC4KICAgICAgICAgICAgaWYgKCF0aGlzLl9oYXNTZW50RW5kZWQpIHsKICAgICAgICAgICAgICB0aGlzLnBvcnQucG9zdE1lc3NhZ2UoeyB0eXBlOiAicGxheWJhY2stZW5kZWQiIH0pOwogICAgICAgICAgICAgIHRoaXMuX2hhc1NlbnRFbmRlZCA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gU2VuZCBmaW5hbCBtZXRyaWNzIHNob3dpbmcgY2xlYXJlZCBzdGF0ZQogICAgICAgICAgICBpZiAodGhpcy5fbWV0cmljc0VuYWJsZWQpIHsKICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgdGhpcy5wb3J0LnBvc3RNZXNzYWdlKHsKICAgICAgICAgICAgICAgICAgdHlwZTogIm1ldHJpY3MiLAogICAgICAgICAgICAgICAgICBkYXRhOiB7CiAgICAgICAgICAgICAgICAgICAgc3RhdGU6IFBsYXliYWNrV29ya2xldC5GU00uSURMRSwKICAgICAgICAgICAgICAgICAgICBxdWV1ZWRTYW1wbGVzOiAwLAogICAgICAgICAgICAgICAgICAgIHF1ZXVlZE1zOiAwLAogICAgICAgICAgICAgICAgICAgIG1heFF1ZXVlZE1zOiBNYXRoLnJvdW5kKCh0aGlzLl9tYXhRdWV1ZVNhbXBsZXMgLyB0aGlzLl9zYW1wbGVSYXRlKSAqIDEwMDApLAogICAgICAgICAgICAgICAgICAgIHVuZGVycnVuQmxvY2tzOiB0aGlzLl91bmRlcnJ1bkJsb2NrcywKICAgICAgICAgICAgICAgICAgICBmcmFtZXNQcm9jZXNzZWQ6IHRoaXMuX2ZyYW1lc1Byb2Nlc3NlZAogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICB9IGNhdGNoIChfKSB7IH0KICAgICAgICAgICAgfQogICAgICAgICAgICB0aGlzLnJlc2V0KCk7IC8vIFJlc2V0IHRvIElETEUgc3RhdGUgZm9yIHJldXNlCiAgICAgICAgICAgIGJyZWFrOyAvLyBFeGl0IHdoaWxlIGxvb3AKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8vIEJVRkZFUiBVTkRFUlJVTiAoTEFHKTogUGxheSBzaWxlbmNlIGFuZCB3YWl0IGZvciBtb3JlIGRhdGEuCiAgICAgICAgICAgIHRoaXMuX3NpbGVuY2VGcmFtZXNDb3VudCsrOwogICAgICAgICAgICBpZiAodGhpcy5fbWV0cmljc0VuYWJsZWQpIHRoaXMuX3VuZGVycnVuQmxvY2tzKys7CiAgICAgICAgICAgIGJyZWFrOyAvLyBFeGl0IHdoaWxlIGxvb3AKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KCiAgICAgIC8vIElmIHdlIGhhdmUgYSBjaHVuayAoY291bGQgYmUgYSBuZXcgb25lIGZyb20gdGhlIGxvZ2ljIGFib3ZlKSwgcHJvY2VzcyBpdC4KICAgICAgaWYgKHRoaXMuX2N1cnJlbnRDaHVuaykgewogICAgICAgIGNvbnN0IHNhbXBsZXNUb0NvcHkgPSBNYXRoLm1pbigKICAgICAgICAgIGJsb2NrU2l6ZSAtIHNhbXBsZXNDb3BpZWQsCiAgICAgICAgICB0aGlzLl9jdXJyZW50Q2h1bmsubGVuZ3RoIC0gdGhpcy5fY3VycmVudENodW5rT2Zmc2V0CiAgICAgICAgKTsKICAgICAgICAvLyBEaXJlY3RseSB3cml0ZSB0byBvdXRwdXRDaGFubmVsIHRvIGF2b2lkIGV4dHJhIGNvcHkKICAgICAgICBjb25zdCBzcmMgPSB0aGlzLl9jdXJyZW50Q2h1bms7CiAgICAgICAgY29uc3QgYmFzZVNyYyA9IHRoaXMuX2N1cnJlbnRDaHVua09mZnNldDsKICAgICAgICBjb25zdCBiYXNlRHN0ID0gc2FtcGxlc0NvcGllZDsKICAgICAgICBjb25zdCBzY2FsZSA9IHRoaXMuX3NjYWxlOwogICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2FtcGxlc1RvQ29weTsgaSsrKSB7CiAgICAgICAgICBvdXRwdXRDaGFubmVsW2Jhc2VEc3QgKyBpXSA9IHNyY1tiYXNlU3JjICsgaV0gKiBzY2FsZTsKICAgICAgICB9CgogICAgICAgIHRoaXMuX2N1cnJlbnRDaHVua09mZnNldCArPSBzYW1wbGVzVG9Db3B5OwogICAgICAgIHNhbXBsZXNDb3BpZWQgKz0gc2FtcGxlc1RvQ29weTsKICAgICAgfQogICAgfQoKICAgIC8vIFplcm8tZmlsbCB0aGUgcmVtYWluZGVyLCBpZiBhbnksIG9uY2UgcGVyIGJsb2NrCiAgICBpZiAoc2FtcGxlc0NvcGllZCA8IGJsb2NrU2l6ZSkgewogICAgICBvdXRwdXRDaGFubmVsLmZpbGwoMCwgc2FtcGxlc0NvcGllZCk7CiAgICB9CgogICAgLy8gVXBkYXRlIG1ldHJpY3MgKG9wdGlvbmFsKQogICAgaWYgKHRoaXMuX21ldHJpY3NFbmFibGVkKSB7CiAgICAgIHRoaXMuX2ZyYW1lc1Byb2Nlc3NlZCArPSBibG9ja1NpemU7CgogICAgICAvLyBUcmFjayBxdWV1ZSBkZXB0aCBpbiBzYW1wbGVzIChhcHByb3hpbWF0ZSkKICAgICAgbGV0IHF1ZXVlZFNhbXBsZXMgPSAwOwogICAgICBpZiAodGhpcy5fY3VycmVudENodW5rKSBxdWV1ZWRTYW1wbGVzICs9IE1hdGgubWF4KDAsIHRoaXMuX2N1cnJlbnRDaHVuay5sZW5ndGggLSB0aGlzLl9jdXJyZW50Q2h1bmtPZmZzZXQpOwogICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX2J1ZmZlclF1ZXVlLmxlbmd0aDsgaSsrKSBxdWV1ZWRTYW1wbGVzICs9IHRoaXMuX2J1ZmZlclF1ZXVlW2ldLmxlbmd0aDsKICAgICAgaWYgKHF1ZXVlZFNhbXBsZXMgPiB0aGlzLl9tYXhRdWV1ZVNhbXBsZXMpIHRoaXMuX21heFF1ZXVlU2FtcGxlcyA9IHF1ZXVlZFNhbXBsZXM7CgogICAgICAvLyBQZXJpb2RpY2FsbHkgc2VuZCBtZXRyaWNzIHRvIG1haW4gdGhyZWFkCiAgICAgIGlmICh0aGlzLl9mcmFtZXNQcm9jZXNzZWQgLSB0aGlzLl9sYXN0TWV0cmljc1NlbnRBdEZyYW1lID49IHRoaXMuX21ldHJpY3NJbnRlcnZhbEZyYW1lcykgewogICAgICAgIHRoaXMuX2xhc3RNZXRyaWNzU2VudEF0RnJhbWUgPSB0aGlzLl9mcmFtZXNQcm9jZXNzZWQ7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIHRoaXMucG9ydC5wb3N0TWVzc2FnZSh7CiAgICAgICAgICAgIHR5cGU6ICJtZXRyaWNzIiwKICAgICAgICAgICAgZGF0YTogewogICAgICAgICAgICAgIHN0YXRlOiB0aGlzLl9zdGF0ZSwKICAgICAgICAgICAgICBxdWV1ZWRTYW1wbGVzLAogICAgICAgICAgICAgIHF1ZXVlZE1zOiBNYXRoLnJvdW5kKChxdWV1ZWRTYW1wbGVzIC8gdGhpcy5fc2FtcGxlUmF0ZSkgKiAxMDAwKSwKICAgICAgICAgICAgICBtYXhRdWV1ZWRNczogTWF0aC5yb3VuZCgodGhpcy5fbWF4UXVldWVTYW1wbGVzIC8gdGhpcy5fc2FtcGxlUmF0ZSkgKiAxMDAwKSwKICAgICAgICAgICAgICB1bmRlcnJ1bkJsb2NrczogdGhpcy5fdW5kZXJydW5CbG9ja3MsCiAgICAgICAgICAgICAgZnJhbWVzUHJvY2Vzc2VkOiB0aGlzLl9mcmFtZXNQcm9jZXNzZWQKICAgICAgICAgICAgfQogICAgICAgICAgfSk7CiAgICAgICAgfSBjYXRjaCAoXykgeyB9CiAgICAgICAgLy8gRG9uJ3QgcmVzZXQgbWF4IHRyYWNrZXIgLSBrZWVwIHNlc3Npb24gcGVhayB1bnRpbCBpZGxlCiAgICAgIH0KICAgIH0KCiAgICAvLyBBTFdBWVMgcmV0dXJuIHRydWUgdG8ga2VlcCB0aGUgcHJvY2Vzc29yIGFsaXZlIGZvciByZXVzZS4KICAgIHJldHVybiB0cnVlOwogIH0KfQoKcmVnaXN0ZXJQcm9jZXNzb3IoInBsYXliYWNrLXdvcmtsZXQiLCBQbGF5YmFja1dvcmtsZXQpOwo=", import.meta.url), at = {
|
|
2627
|
-
en:
|
|
2628
|
-
de:
|
|
2629
|
-
fr:
|
|
2630
|
-
fi:
|
|
2631
|
-
lt:
|
|
2632
|
-
},
|
|
2625
|
+
LipsyncLt: Bt
|
|
2626
|
+
}, Symbol.toStringTag, { value: "Module" })), Dt = new URL("data:text/javascript;base64,Y2xhc3MgUGxheWJhY2tXb3JrbGV0IGV4dGVuZHMgQXVkaW9Xb3JrbGV0UHJvY2Vzc29yIHsKICBzdGF0aWMgRlNNID0gewogICAgSURMRTogMCwKICAgIFBMQVlJTkc6IDEsCiAgfTsKCiAgY29uc3RydWN0b3Iob3B0aW9ucykgewogICAgc3VwZXIoKTsKICAgIHRoaXMucG9ydC5vbm1lc3NhZ2UgPSB0aGlzLmhhbmRsZU1lc3NhZ2UuYmluZCh0aGlzKTsKCiAgICB0aGlzLl9zYW1wbGVSYXRlID0gb3B0aW9ucz8ucHJvY2Vzc29yT3B0aW9ucz8uc2FtcGxlUmF0ZSB8fCBzYW1wbGVSYXRlOwogICAgdGhpcy5fc2NhbGUgPSAxIC8gMzI3Njg7IC8vIFBDTTE2IC0+IGZsb2F0CgogICAgLy8gU2lsZW5jZSBkZXRlY3Rpb24gdGhyZXNob2xkICgxIHNlY29uZCkgYXMgYSBmYWxsYmFjayBzYWZldHkgbmV0CiAgICBjb25zdCBzaWxlbmNlRHVyYXRpb25TZWNvbmRzID0gMS4wOwogICAgdGhpcy5fc2lsZW5jZVRocmVzaG9sZEJsb2NrcyA9IE1hdGguY2VpbCgodGhpcy5fc2FtcGxlUmF0ZSAqIHNpbGVuY2VEdXJhdGlvblNlY29uZHMpIC8gMTI4KTsKCiAgICAvLyBNZXRyaWNzIGNvbmZpZ3VyYXRpb24gdmlhIG9wdGlvbnMKICAgIGNvbnN0IG1ldHJpY3NDZmcgPSBvcHRpb25zPy5wcm9jZXNzb3JPcHRpb25zPy5tZXRyaWNzIHx8IHt9OwogICAgdGhpcy5fbWV0cmljc0VuYWJsZWQgPSBtZXRyaWNzQ2ZnLmVuYWJsZWQgIT09IGZhbHNlOwogICAgY29uc3QgaW50ZXJ2YWxIeiA9ICh0eXBlb2YgbWV0cmljc0NmZy5pbnRlcnZhbEh6ID09PSAibnVtYmVyIiAmJiBtZXRyaWNzQ2ZnLmludGVydmFsSHogPiAwKQogICAgICA/IG1ldHJpY3NDZmcuaW50ZXJ2YWxIeiA6IDI7CiAgICAvLyBNZXRyaWNzIHN0YXRlIChsb3ctb3ZlcmhlYWQpCiAgICB0aGlzLl9mcmFtZXNQcm9jZXNzZWQgPSAwOwogICAgdGhpcy5fdW5kZXJydW5CbG9ja3MgPSAwOwogICAgdGhpcy5fbWF4UXVldWVTYW1wbGVzID0gMDsKICAgIHRoaXMuX2xhc3RNZXRyaWNzU2VudEF0RnJhbWUgPSAwOwogICAgLy8gQ29udmVydCB0byBmcmFtZXMgYmV0d2VlbiByZXBvcnRzCiAgICB0aGlzLl9tZXRyaWNzSW50ZXJ2YWxGcmFtZXMgPSBNYXRoLm1heCgxMjgsIE1hdGgucm91bmQodGhpcy5fc2FtcGxlUmF0ZSAvIGludGVydmFsSHopKTsKCiAgICB0aGlzLnJlc2V0KCk7CiAgfQoKICAvKioKICAgKiBSZXNldHMgdGhlIHdvcmtsZXQgdG8gaXRzIGluaXRpYWwgSURMRSBzdGF0ZS4KICAgKi8KICByZXNldCgpIHsKICAgIHRoaXMuX2J1ZmZlclF1ZXVlID0gW107CiAgICB0aGlzLl9jdXJyZW50Q2h1bmsgPSBudWxsOwogICAgdGhpcy5fY3VycmVudENodW5rT2Zmc2V0ID0gMDsKICAgIHRoaXMuX3N0YXRlID0gUGxheWJhY2tXb3JrbGV0LkZTTS5JRExFOwoKICAgIHRoaXMuX25vTW9yZURhdGFSZWNlaXZlZCA9IGZhbHNlOwogICAgdGhpcy5fc2lsZW5jZUZyYW1lc0NvdW50ID0gMDsKICAgIHRoaXMuX2hhc1NlbnRFbmRlZCA9IGZhbHNlOwogICAgLy8gUmVzZXQgbWF4IHF1ZXVlIHRyYWNrZXIgb25seSB3aGVuIGdvaW5nIGlkbGUKICAgIHRoaXMuX21heFF1ZXVlU2FtcGxlcyA9IDA7CiAgfQoKICBoYW5kbGVNZXNzYWdlKGV2ZW50KSB7CiAgICBjb25zdCB7IHR5cGUsIGRhdGEgfSA9IGV2ZW50LmRhdGE7CgogICAgLy8gSU5URVJSVVBUOiBUaGUgbWFpbiB0aHJlYWQgd2FudHMgdG8gc3RvcCBpbW1lZGlhdGVseS4KICAgIGlmICh0eXBlID09PSAic3RvcCIpIHsKICAgICAgdGhpcy5yZXNldCgpOwogICAgICAvLyBTZW5kIGZpbmFsIG1ldHJpY3Mgc2hvd2luZyBjbGVhcmVkIHN0YXRlCiAgICAgIGlmICh0aGlzLl9tZXRyaWNzRW5hYmxlZCkgewogICAgICAgIHRyeSB7CiAgICAgICAgICB0aGlzLnBvcnQucG9zdE1lc3NhZ2UoewogICAgICAgICAgICB0eXBlOiAibWV0cmljcyIsCiAgICAgICAgICAgIGRhdGE6IHsKICAgICAgICAgICAgICBzdGF0ZTogUGxheWJhY2tXb3JrbGV0LkZTTS5JRExFLAogICAgICAgICAgICAgIHF1ZXVlZFNhbXBsZXM6IDAsCiAgICAgICAgICAgICAgcXVldWVkTXM6IDAsCiAgICAgICAgICAgICAgbWF4UXVldWVkTXM6IE1hdGgucm91bmQoKHRoaXMuX21heFF1ZXVlU2FtcGxlcyAvIHRoaXMuX3NhbXBsZVJhdGUpICogMTAwMCksCiAgICAgICAgICAgICAgdW5kZXJydW5CbG9ja3M6IHRoaXMuX3VuZGVycnVuQmxvY2tzLAogICAgICAgICAgICAgIGZyYW1lc1Byb2Nlc3NlZDogdGhpcy5fZnJhbWVzUHJvY2Vzc2VkCiAgICAgICAgICAgIH0KICAgICAgICAgIH0pOwogICAgICAgIH0gY2F0Y2ggKF8pIHsgfQogICAgICB9CiAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBNYWluIHRocmVhZCBoYXMgc2lnbmFsZWQgdGhhdCBubyBtb3JlIGF1ZGlvIGNodW5rcyB3aWxsIGJlIHNlbnQgZm9yIHRoaXMgdXR0ZXJhbmNlLgogICAgaWYgKHR5cGUgPT09ICJuby1tb3JlLWRhdGEiKSB7CiAgICAgIHRoaXMuX25vTW9yZURhdGFSZWNlaXZlZCA9IHRydWU7CiAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBVcGRhdGUgbWV0cmljcyBjb25maWd1cmF0aW9uIGF0IHJ1bnRpbWUKICAgIGlmICh0eXBlID09PSAiY29uZmlnLW1ldHJpY3MiICYmIGRhdGEgJiYgdHlwZW9mIGRhdGEgPT09ICJvYmplY3QiKSB7CiAgICAgIGlmICgiZW5hYmxlZCIgaW4gZGF0YSkgdGhpcy5fbWV0cmljc0VuYWJsZWQgPSAhIWRhdGEuZW5hYmxlZDsKICAgICAgaWYgKHR5cGVvZiBkYXRhLmludGVydmFsSHogPT09ICJudW1iZXIiICYmIGRhdGEuaW50ZXJ2YWxIeiA+IDApIHsKICAgICAgICBjb25zdCBpbnRlcnZhbEh6ID0gZGF0YS5pbnRlcnZhbEh6OwogICAgICAgIHRoaXMuX21ldHJpY3NJbnRlcnZhbEZyYW1lcyA9IE1hdGgubWF4KDEyOCwgTWF0aC5yb3VuZCh0aGlzLl9zYW1wbGVSYXRlIC8gaW50ZXJ2YWxIeikpOwogICAgICB9CiAgICAgIC8vIFJlc2V0IHBhY2luZyBzbyB0aGUgbmV4dCByZXBvcnQgYWxpZ25zIHdpdGggbmV3IGludGVydmFsCiAgICAgIHRoaXMuX2xhc3RNZXRyaWNzU2VudEF0RnJhbWUgPSB0aGlzLl9mcmFtZXNQcm9jZXNzZWQ7CiAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBOZXcgYXVkaW8gZGF0YSBoYXMgYXJyaXZlZC4KICAgIGlmICh0eXBlID09PSAiYXVkaW9EYXRhIiAmJiBkYXRhIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHsKICAgICAgdGhpcy5fbm9Nb3JlRGF0YVJlY2VpdmVkID0gZmFsc2U7CiAgICAgIC8vIElmIHdlIHdlcmUgaWRsZSwgdGhpcyBuZXcgZGF0YSBraWNrcyBvZmYgdGhlIHBsYXliYWNrLgogICAgICBpZiAodGhpcy5fc3RhdGUgPT09IFBsYXliYWNrV29ya2xldC5GU00uSURMRSkgewogICAgICAgIHRoaXMuX3N0YXRlID0gUGxheWJhY2tXb3JrbGV0LkZTTS5QTEFZSU5HOwogICAgICAgIHRoaXMucG9ydC5wb3N0TWVzc2FnZSh7IHR5cGU6ICJwbGF5YmFjay1zdGFydGVkIiB9KTsKICAgICAgfQoKICAgICAgLy8gV2Ugb25seSBxdWV1ZSBkYXRhIGlmIHdlIGFyZSBpbiB0aGUgUExBWUlORyBzdGF0ZS4gVGhpcyBwcmV2ZW50cwogICAgICAvLyBkYXRhIGZyb20gYSBwcmV2aW91cywgaW50ZXJydXB0ZWQgc3RyZWFtIGZyb20gbGluZ2VyaW5nLgogICAgICBpZiAodGhpcy5fc3RhdGUgPT09IFBsYXliYWNrV29ya2xldC5GU00uUExBWUlORykgewogICAgICAgIC8vIFN0b3JlIGFzIEludDE2QXJyYXkgdmlldyB0byBhdm9pZCBjb25zdHJ1Y3RpbmcgaXQgaW4gcHJvY2VzcygpCiAgICAgICAgdGhpcy5fYnVmZmVyUXVldWUucHVzaChuZXcgSW50MTZBcnJheShkYXRhKSk7CiAgICAgICAgdGhpcy5fc2lsZW5jZUZyYW1lc0NvdW50ID0gMDsgLy8gUmVzZXQgc2lsZW5jZSBjb3VudGVyIG9uIG5ldyBkYXRhCiAgICAgIH0KICAgIH0KICB9CgogIHByb2Nlc3MoaW5wdXRzLCBvdXRwdXRzLCBwYXJhbWV0ZXJzKSB7CiAgICBjb25zdCBvdXRwdXRDaGFubmVsID0gb3V0cHV0c1swXT8uWzBdOwogICAgaWYgKCFvdXRwdXRDaGFubmVsKSB7CiAgICAgIHJldHVybiB0cnVlOyAvLyBLZWVwIGFsaXZlIGV2ZW4gaWYgb3V0cHV0IGlzIHRlbXBvcmFyaWx5IGRpc2Nvbm5lY3RlZAogICAgfQoKICAgIC8vIElmIHdlIGFyZSBub3QgcGxheWluZywganVzdCBvdXRwdXQgc2lsZW5jZSBhbmQgd2FpdC4KICAgIGlmICh0aGlzLl9zdGF0ZSAhPT0gUGxheWJhY2tXb3JrbGV0LkZTTS5QTEFZSU5HKSB7CiAgICAgIG91dHB1dENoYW5uZWwuZmlsbCgwKTsKICAgICAgcmV0dXJuIHRydWU7IC8vIEFsd2F5cyByZXR1cm4gdHJ1ZSB0byBrZWVwIHRoZSBwcm9jZXNzb3IgYWxpdmUKICAgIH0KCiAgICAvLyBDb3JlIFBMQVlJTkcgTG9naWMKICAgIGNvbnN0IGJsb2NrU2l6ZSA9IG91dHB1dENoYW5uZWwubGVuZ3RoOwogICAgbGV0IHNhbXBsZXNDb3BpZWQgPSAwOwoKICAgIHdoaWxlIChzYW1wbGVzQ29waWVkIDwgYmxvY2tTaXplKSB7CiAgICAgIGlmICghdGhpcy5fY3VycmVudENodW5rIHx8IHRoaXMuX2N1cnJlbnRDaHVua09mZnNldCA+PSB0aGlzLl9jdXJyZW50Q2h1bmsubGVuZ3RoKSB7CiAgICAgICAgaWYgKHRoaXMuX2J1ZmZlclF1ZXVlLmxlbmd0aCA+IDApIHsKICAgICAgICAgIHRoaXMuX2N1cnJlbnRDaHVuayA9IHRoaXMuX2J1ZmZlclF1ZXVlLnNoaWZ0KCk7CiAgICAgICAgICB0aGlzLl9jdXJyZW50Q2h1bmtPZmZzZXQgPSAwOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAvLyBCdWZmZXIgaXMgZW1wdHkuIENoZWNrIGZvciBlbmQgY29uZGl0aW9ucy4KICAgICAgICAgIGNvbnN0IGlzVGltZWRPdXQgPSB0aGlzLl9zaWxlbmNlRnJhbWVzQ291bnQgPiB0aGlzLl9zaWxlbmNlVGhyZXNob2xkQmxvY2tzOwoKICAgICAgICAgIGlmICh0aGlzLl9ub01vcmVEYXRhUmVjZWl2ZWQgfHwgaXNUaW1lZE91dCkgewogICAgICAgICAgICAvLyBFTkQgT0YgUExBWUJBQ0s6IEVpdGhlciBleHBsaWNpdGx5IHNpZ25hbGVkIG9yIHRpbWVkIG91dC4KICAgICAgICAgICAgaWYgKCF0aGlzLl9oYXNTZW50RW5kZWQpIHsKICAgICAgICAgICAgICB0aGlzLnBvcnQucG9zdE1lc3NhZ2UoeyB0eXBlOiAicGxheWJhY2stZW5kZWQiIH0pOwogICAgICAgICAgICAgIHRoaXMuX2hhc1NlbnRFbmRlZCA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gU2VuZCBmaW5hbCBtZXRyaWNzIHNob3dpbmcgY2xlYXJlZCBzdGF0ZQogICAgICAgICAgICBpZiAodGhpcy5fbWV0cmljc0VuYWJsZWQpIHsKICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgdGhpcy5wb3J0LnBvc3RNZXNzYWdlKHsKICAgICAgICAgICAgICAgICAgdHlwZTogIm1ldHJpY3MiLAogICAgICAgICAgICAgICAgICBkYXRhOiB7CiAgICAgICAgICAgICAgICAgICAgc3RhdGU6IFBsYXliYWNrV29ya2xldC5GU00uSURMRSwKICAgICAgICAgICAgICAgICAgICBxdWV1ZWRTYW1wbGVzOiAwLAogICAgICAgICAgICAgICAgICAgIHF1ZXVlZE1zOiAwLAogICAgICAgICAgICAgICAgICAgIG1heFF1ZXVlZE1zOiBNYXRoLnJvdW5kKCh0aGlzLl9tYXhRdWV1ZVNhbXBsZXMgLyB0aGlzLl9zYW1wbGVSYXRlKSAqIDEwMDApLAogICAgICAgICAgICAgICAgICAgIHVuZGVycnVuQmxvY2tzOiB0aGlzLl91bmRlcnJ1bkJsb2NrcywKICAgICAgICAgICAgICAgICAgICBmcmFtZXNQcm9jZXNzZWQ6IHRoaXMuX2ZyYW1lc1Byb2Nlc3NlZAogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICB9IGNhdGNoIChfKSB7IH0KICAgICAgICAgICAgfQogICAgICAgICAgICB0aGlzLnJlc2V0KCk7IC8vIFJlc2V0IHRvIElETEUgc3RhdGUgZm9yIHJldXNlCiAgICAgICAgICAgIGJyZWFrOyAvLyBFeGl0IHdoaWxlIGxvb3AKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8vIEJVRkZFUiBVTkRFUlJVTiAoTEFHKTogUGxheSBzaWxlbmNlIGFuZCB3YWl0IGZvciBtb3JlIGRhdGEuCiAgICAgICAgICAgIHRoaXMuX3NpbGVuY2VGcmFtZXNDb3VudCsrOwogICAgICAgICAgICBpZiAodGhpcy5fbWV0cmljc0VuYWJsZWQpIHRoaXMuX3VuZGVycnVuQmxvY2tzKys7CiAgICAgICAgICAgIGJyZWFrOyAvLyBFeGl0IHdoaWxlIGxvb3AKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KCiAgICAgIC8vIElmIHdlIGhhdmUgYSBjaHVuayAoY291bGQgYmUgYSBuZXcgb25lIGZyb20gdGhlIGxvZ2ljIGFib3ZlKSwgcHJvY2VzcyBpdC4KICAgICAgaWYgKHRoaXMuX2N1cnJlbnRDaHVuaykgewogICAgICAgIGNvbnN0IHNhbXBsZXNUb0NvcHkgPSBNYXRoLm1pbigKICAgICAgICAgIGJsb2NrU2l6ZSAtIHNhbXBsZXNDb3BpZWQsCiAgICAgICAgICB0aGlzLl9jdXJyZW50Q2h1bmsubGVuZ3RoIC0gdGhpcy5fY3VycmVudENodW5rT2Zmc2V0CiAgICAgICAgKTsKICAgICAgICAvLyBEaXJlY3RseSB3cml0ZSB0byBvdXRwdXRDaGFubmVsIHRvIGF2b2lkIGV4dHJhIGNvcHkKICAgICAgICBjb25zdCBzcmMgPSB0aGlzLl9jdXJyZW50Q2h1bms7CiAgICAgICAgY29uc3QgYmFzZVNyYyA9IHRoaXMuX2N1cnJlbnRDaHVua09mZnNldDsKICAgICAgICBjb25zdCBiYXNlRHN0ID0gc2FtcGxlc0NvcGllZDsKICAgICAgICBjb25zdCBzY2FsZSA9IHRoaXMuX3NjYWxlOwogICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2FtcGxlc1RvQ29weTsgaSsrKSB7CiAgICAgICAgICBvdXRwdXRDaGFubmVsW2Jhc2VEc3QgKyBpXSA9IHNyY1tiYXNlU3JjICsgaV0gKiBzY2FsZTsKICAgICAgICB9CgogICAgICAgIHRoaXMuX2N1cnJlbnRDaHVua09mZnNldCArPSBzYW1wbGVzVG9Db3B5OwogICAgICAgIHNhbXBsZXNDb3BpZWQgKz0gc2FtcGxlc1RvQ29weTsKICAgICAgfQogICAgfQoKICAgIC8vIFplcm8tZmlsbCB0aGUgcmVtYWluZGVyLCBpZiBhbnksIG9uY2UgcGVyIGJsb2NrCiAgICBpZiAoc2FtcGxlc0NvcGllZCA8IGJsb2NrU2l6ZSkgewogICAgICBvdXRwdXRDaGFubmVsLmZpbGwoMCwgc2FtcGxlc0NvcGllZCk7CiAgICB9CgogICAgLy8gVXBkYXRlIG1ldHJpY3MgKG9wdGlvbmFsKQogICAgaWYgKHRoaXMuX21ldHJpY3NFbmFibGVkKSB7CiAgICAgIHRoaXMuX2ZyYW1lc1Byb2Nlc3NlZCArPSBibG9ja1NpemU7CgogICAgICAvLyBUcmFjayBxdWV1ZSBkZXB0aCBpbiBzYW1wbGVzIChhcHByb3hpbWF0ZSkKICAgICAgbGV0IHF1ZXVlZFNhbXBsZXMgPSAwOwogICAgICBpZiAodGhpcy5fY3VycmVudENodW5rKSBxdWV1ZWRTYW1wbGVzICs9IE1hdGgubWF4KDAsIHRoaXMuX2N1cnJlbnRDaHVuay5sZW5ndGggLSB0aGlzLl9jdXJyZW50Q2h1bmtPZmZzZXQpOwogICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX2J1ZmZlclF1ZXVlLmxlbmd0aDsgaSsrKSBxdWV1ZWRTYW1wbGVzICs9IHRoaXMuX2J1ZmZlclF1ZXVlW2ldLmxlbmd0aDsKICAgICAgaWYgKHF1ZXVlZFNhbXBsZXMgPiB0aGlzLl9tYXhRdWV1ZVNhbXBsZXMpIHRoaXMuX21heFF1ZXVlU2FtcGxlcyA9IHF1ZXVlZFNhbXBsZXM7CgogICAgICAvLyBQZXJpb2RpY2FsbHkgc2VuZCBtZXRyaWNzIHRvIG1haW4gdGhyZWFkCiAgICAgIGlmICh0aGlzLl9mcmFtZXNQcm9jZXNzZWQgLSB0aGlzLl9sYXN0TWV0cmljc1NlbnRBdEZyYW1lID49IHRoaXMuX21ldHJpY3NJbnRlcnZhbEZyYW1lcykgewogICAgICAgIHRoaXMuX2xhc3RNZXRyaWNzU2VudEF0RnJhbWUgPSB0aGlzLl9mcmFtZXNQcm9jZXNzZWQ7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIHRoaXMucG9ydC5wb3N0TWVzc2FnZSh7CiAgICAgICAgICAgIHR5cGU6ICJtZXRyaWNzIiwKICAgICAgICAgICAgZGF0YTogewogICAgICAgICAgICAgIHN0YXRlOiB0aGlzLl9zdGF0ZSwKICAgICAgICAgICAgICBxdWV1ZWRTYW1wbGVzLAogICAgICAgICAgICAgIHF1ZXVlZE1zOiBNYXRoLnJvdW5kKChxdWV1ZWRTYW1wbGVzIC8gdGhpcy5fc2FtcGxlUmF0ZSkgKiAxMDAwKSwKICAgICAgICAgICAgICBtYXhRdWV1ZWRNczogTWF0aC5yb3VuZCgodGhpcy5fbWF4UXVldWVTYW1wbGVzIC8gdGhpcy5fc2FtcGxlUmF0ZSkgKiAxMDAwKSwKICAgICAgICAgICAgICB1bmRlcnJ1bkJsb2NrczogdGhpcy5fdW5kZXJydW5CbG9ja3MsCiAgICAgICAgICAgICAgZnJhbWVzUHJvY2Vzc2VkOiB0aGlzLl9mcmFtZXNQcm9jZXNzZWQKICAgICAgICAgICAgfQogICAgICAgICAgfSk7CiAgICAgICAgfSBjYXRjaCAoXykgeyB9CiAgICAgICAgLy8gRG9uJ3QgcmVzZXQgbWF4IHRyYWNrZXIgLSBrZWVwIHNlc3Npb24gcGVhayB1bnRpbCBpZGxlCiAgICAgIH0KICAgIH0KCiAgICAvLyBBTFdBWVMgcmV0dXJuIHRydWUgdG8ga2VlcCB0aGUgcHJvY2Vzc29yIGFsaXZlIGZvciByZXVzZS4KICAgIHJldHVybiB0cnVlOwogIH0KfQoKcmVnaXN0ZXJQcm9jZXNzb3IoInBsYXliYWNrLXdvcmtsZXQiLCBQbGF5YmFja1dvcmtsZXQpOwo=", import.meta.url), rt = {
|
|
2627
|
+
en: zt,
|
|
2628
|
+
de: Tt,
|
|
2629
|
+
fr: Mt,
|
|
2630
|
+
fi: Pt,
|
|
2631
|
+
lt: Ot
|
|
2632
|
+
}, he = new A.Quaternion(), re = new A.Euler(), Ne = new A.Vector3(), We = new A.Vector3(), at = new A.Box3();
|
|
2633
2633
|
new A.Matrix4();
|
|
2634
2634
|
new A.Matrix4();
|
|
2635
2635
|
new A.Vector3();
|
|
2636
2636
|
new A.Vector3(0, 0, 1);
|
|
2637
|
-
const
|
|
2637
|
+
const Nt = new A.Vector3(1, 0, 0);
|
|
2638
2638
|
new A.Vector3(0, 1, 0);
|
|
2639
2639
|
new A.Vector3(0, 0, 1);
|
|
2640
2640
|
class it {
|
|
@@ -2763,7 +2763,7 @@ class it {
|
|
|
2763
2763
|
avatarOnlyCamera: null,
|
|
2764
2764
|
statsNode: null,
|
|
2765
2765
|
statsStyle: null
|
|
2766
|
-
}, Object.assign(this.opt, e || {}), this.opt.statsNode && (this.stats = new
|
|
2766
|
+
}, Object.assign(this.opt, e || {}), this.opt.statsNode && (this.stats = new vt(), this.opt.statsStyle && (this.stats.dom.style.cssText = this.opt.statsStyle), this.opt.statsNode.appendChild(this.stats.dom)), this.poseTemplates = {
|
|
2767
2767
|
side: {
|
|
2768
2768
|
standing: !0,
|
|
2769
2769
|
props: {
|
|
@@ -4086,7 +4086,7 @@ class it {
|
|
|
4086
4086
|
this.opt.lightSpotDispersion
|
|
4087
4087
|
), this.setLighting(this.opt);
|
|
4088
4088
|
const a = new A.PMREMGenerator(this.renderer);
|
|
4089
|
-
a.compileEquirectangularShader(), this.scene.environment = a.fromScene(new
|
|
4089
|
+
a.compileEquirectangularShader(), this.scene.environment = a.fromScene(new Rt()).texture, this.resizeobserver = new ResizeObserver(this.onResize.bind(this)), this.resizeobserver.observe(this.nodeAvatar), this.controls = new xt(this.camera, this.renderer.domElement), this.controls.enableZoom = this.opt.cameraZoomEnable, this.controls.enableRotate = this.opt.cameraRotateEnable, this.controls.enablePan = this.opt.cameraPanEnable, this.controls.minDistance = 2, this.controls.maxDistance = 2e3, this.controls.autoRotateSpeed = 0, this.controls.autoRotate = !1, this.controls.update(), this.cameraClock = null;
|
|
4090
4090
|
}
|
|
4091
4091
|
this.ikMesh = new A.SkinnedMesh();
|
|
4092
4092
|
const s = {
|
|
@@ -4104,14 +4104,14 @@ class it {
|
|
|
4104
4104
|
Object.entries(s).forEach((a, u) => {
|
|
4105
4105
|
const l = new A.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 A.Skeleton(i)), this.dynamicbones = new
|
|
4107
|
+
}), this.ikMesh.bind(new A.Skeleton(i)), this.dynamicbones = new kt(), 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.
|
|
4111
4111
|
* @param {number} sampleRate
|
|
4112
4112
|
*/
|
|
4113
4113
|
initAudioGraph(n = null) {
|
|
4114
|
-
if (this.audioCtx && this.audioCtx.state !== "closed" && this.audioCtx.close(), n ? this.audioCtx = new AudioContext({ sampleRate: n }) : this.audioCtx = new AudioContext(), this.audioSpeechSource = this.audioCtx.createBufferSource(), this.audioBackgroundSource = this.audioCtx.createBufferSource(), this.audioBackgroundGainNode = this.audioCtx.createGain(), this.audioSpeechGainNode = this.audioCtx.createGain(), this.audioStreamGainNode = this.audioCtx.createGain(), this.audioAnalyzerNode = this.audioCtx.createAnalyser(), this.audioAnalyzerNode.fftSize = 256, this.audioAnalyzerNode.smoothingTimeConstant = 0.1, this.audioAnalyzerNode.minDecibels = -70, this.audioAnalyzerNode.maxDecibels = -10, this.audioAnalyzer = new
|
|
4114
|
+
if (this.audioCtx && this.audioCtx.state !== "closed" && this.audioCtx.close(), n ? this.audioCtx = new AudioContext({ sampleRate: n }) : this.audioCtx = new AudioContext(), this.audioSpeechSource = this.audioCtx.createBufferSource(), this.audioBackgroundSource = this.audioCtx.createBufferSource(), this.audioBackgroundGainNode = this.audioCtx.createGain(), this.audioSpeechGainNode = this.audioCtx.createGain(), this.audioStreamGainNode = this.audioCtx.createGain(), this.audioAnalyzerNode = this.audioCtx.createAnalyser(), this.audioAnalyzerNode.fftSize = 256, this.audioAnalyzerNode.smoothingTimeConstant = 0.1, this.audioAnalyzerNode.minDecibels = -70, this.audioAnalyzerNode.maxDecibels = -10, this.audioAnalyzer = new wt(this.audioCtx), this.audioReverbNode = this.audioCtx.createConvolver(), this.audioBackgroundGainNode.connect(this.audioReverbNode), this.audioAnalyzerNode.connect(this.audioSpeechGainNode), this.audioSpeechGainNode.connect(this.audioReverbNode), this.audioStreamGainNode.connect(this.audioReverbNode), this.audioReverbNode.connect(this.audioCtx.destination), this.setReverb(this.currentReverb || null), this.setMixerGain(
|
|
4115
4115
|
this.opt.mixerGainSpeech,
|
|
4116
4116
|
this.opt.mixerGainBackground
|
|
4117
4117
|
), this.workletLoaded = !1, this.streamWorkletNode) {
|
|
@@ -4227,14 +4227,14 @@ class it {
|
|
|
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
4229
|
a || (a = new A.Float32BufferAttribute(h.count * 3, 3), d && (u = new A.Float32BufferAttribute(h.count * 3, 3)));
|
|
4230
|
-
for (let
|
|
4231
|
-
const b = a.getX(
|
|
4232
|
-
a.setXYZ(
|
|
4230
|
+
for (let p = 0; p < h.count; p++) {
|
|
4231
|
+
const b = a.getX(p) + h.getX(p) * c, f = a.getY(p) + h.getY(p) * c, L = a.getZ(p) + h.getZ(p) * c;
|
|
4232
|
+
a.setXYZ(p, b, f, L);
|
|
4233
4233
|
}
|
|
4234
4234
|
if (d)
|
|
4235
|
-
for (let
|
|
4236
|
-
const b = u.getX(
|
|
4237
|
-
u.setXYZ(
|
|
4235
|
+
for (let p = 0; p < h.count; p++) {
|
|
4236
|
+
const b = u.getX(p) + d.getX(p) * c, f = u.getY(p) + d.getY(p) * c, L = u.getZ(p) + d.getZ(p) * c;
|
|
4237
|
+
u.setXYZ(p, b, f, L);
|
|
4238
4238
|
}
|
|
4239
4239
|
}
|
|
4240
4240
|
if (a) {
|
|
@@ -4252,9 +4252,9 @@ class it {
|
|
|
4252
4252
|
async showAvatar(n, e = null) {
|
|
4253
4253
|
if (!n || !n.hasOwnProperty("url"))
|
|
4254
4254
|
throw new Error("Invalid parameter. The avatar must have at least 'url' specified.");
|
|
4255
|
-
const t = new
|
|
4255
|
+
const t = new bt();
|
|
4256
4256
|
if (this.dracoEnabled) {
|
|
4257
|
-
const l = new
|
|
4257
|
+
const l = new At();
|
|
4258
4258
|
l.setDecoderPath(this.dracoDecoderPath), t.setDRACOLoader(l);
|
|
4259
4259
|
}
|
|
4260
4260
|
let o = await t.loadAsync(n.url, e);
|
|
@@ -4412,9 +4412,9 @@ class it {
|
|
|
4412
4412
|
updatePoseDelta() {
|
|
4413
4413
|
for (const [n, e] of Object.entries(this.poseDelta.props)) {
|
|
4414
4414
|
if (e.x === 0 && e.y === 0 && e.z === 0) continue;
|
|
4415
|
-
|
|
4415
|
+
re.set(e.x, e.y, e.z);
|
|
4416
4416
|
const t = this.poseAvatar.props[n];
|
|
4417
|
-
t.isQuaternion ? (
|
|
4417
|
+
t.isQuaternion ? (he.setFromEuler(re), t.multiply(he)) : t.isVector3 && t.add(re);
|
|
4418
4418
|
}
|
|
4419
4419
|
}
|
|
4420
4420
|
/**
|
|
@@ -5109,14 +5109,14 @@ class it {
|
|
|
5109
5109
|
for (let [h, d] of Object.entries(r.vs))
|
|
5110
5110
|
if (this.mtAvatar.hasOwnProperty(h)) {
|
|
5111
5111
|
if (d[o + 1] === null) continue;
|
|
5112
|
-
const
|
|
5113
|
-
if (d[o] === null && (d[o] =
|
|
5114
|
-
|
|
5112
|
+
const p = this.mtAvatar[h];
|
|
5113
|
+
if (d[o] === null && (d[o] = p.value), o === i - 1)
|
|
5114
|
+
p.newvalue = d[o];
|
|
5115
5115
|
else {
|
|
5116
|
-
|
|
5116
|
+
p.newvalue = d[o + 1];
|
|
5117
5117
|
const b = r.ts[o + 1] - r.ts[o];
|
|
5118
|
-
let
|
|
5119
|
-
b > 1e-4 && (
|
|
5118
|
+
let f = 1;
|
|
5119
|
+
b > 1e-4 && (f = (this.animClock - r.ts[o]) / b), f < 1 && (p.easing && (f = p.easing(f)), p.newvalue = (1 - f) * d[o] + f * p.newvalue), p.ref && p.ref !== r.vs && p.ref.hasOwnProperty(h) && delete p.ref[h], p.ref = r.vs;
|
|
5120
5120
|
}
|
|
5121
5121
|
if (a)
|
|
5122
5122
|
switch (h) {
|
|
@@ -5125,9 +5125,9 @@ class it {
|
|
|
5125
5125
|
case "viseme_I":
|
|
5126
5126
|
case "viseme_O":
|
|
5127
5127
|
case "viseme_U":
|
|
5128
|
-
|
|
5128
|
+
p.newvalue *= 1 + a / 255 - 0.5;
|
|
5129
5129
|
}
|
|
5130
|
-
|
|
5130
|
+
p.needsUpdate = !0;
|
|
5131
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
|
}
|
|
@@ -5179,7 +5179,7 @@ class it {
|
|
|
5179
5179
|
}, o.x ? new A.Vector3(o.x, o.y, o.z) : null, !0, o.d);
|
|
5180
5180
|
break;
|
|
5181
5181
|
}
|
|
5182
|
-
if ((u || l) && (
|
|
5182
|
+
if ((u || l) && (re.setFromQuaternion(this.poseAvatar.props["Head.quaternion"]), re.x = Math.max(-0.9, Math.min(0.9, 2 * re.x - 0.5)), re.y = Math.max(-0.9, Math.min(0.9, -2.5 * re.y)), u ? (Object.assign(this.mtAvatar.eyesLookDown, { system: re.x < 0 ? -re.x : 0, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyesLookUp, { system: re.x < 0 ? 0 : re.x, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookInLeft, { system: re.y < 0 ? -re.y : 0, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookOutLeft, { system: re.y < 0 ? 0 : re.y, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookInRight, { system: re.y < 0 ? 0 : re.y, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookOutRight, { system: re.y < 0 ? -re.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: {
|
|
@@ -5208,7 +5208,7 @@ class it {
|
|
|
5208
5208
|
this.animationFinishedCallback = null, this.currentFBXActionCallback = null, this.currentFBXActionForCallback = null, this.currentFBXActionStartTime = null, this.currentFBXActionClipDuration = null, b();
|
|
5209
5209
|
} else this.currentFBXActionCallback && (this.currentFBXActionCallback = null, this.currentFBXActionForCallback = null, this.currentFBXActionStartTime = null, this.currentFBXActionClipDuration = null);
|
|
5210
5210
|
}
|
|
5211
|
-
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 && (
|
|
5211
|
+
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 && (he.setFromAxisAngle(Nt, this.volumeHeadCurrent), this.objectNeck.quaternion.multiply(he)), at.setFromObject(this.armature), this.objectLeftToeBase.getWorldPosition(Ne), Ne.sub(this.armature.position), this.objectRightToeBase.getWorldPosition(We), We.sub(this.armature.position), this.objectHips.position.y -= at.min.y / 2, this.objectHips.position.x -= (Ne.x + We.x) / 4, this.objectHips.position.z -= (Ne.z + We.z) / 2, this.dynamicbones.update(e), this.fbxAnimationLoader && this.fbxAnimationLoader.update(), this.opt.update && this.opt.update(e), this.updateMorphTargets(e), this.isAvatarOnly)
|
|
5212
5212
|
this.stats && this.stats.end();
|
|
5213
5213
|
else {
|
|
5214
5214
|
if (this.cameraClock !== null && this.cameraClock < 1e3) {
|
|
@@ -5239,8 +5239,8 @@ class it {
|
|
|
5239
5239
|
if (!this.lipsync.hasOwnProperty(n)) {
|
|
5240
5240
|
const t = n.toLowerCase(), o = "Lipsync" + n.charAt(0).toUpperCase() + n.slice(1);
|
|
5241
5241
|
try {
|
|
5242
|
-
const s =
|
|
5243
|
-
s && s[o] ? this.lipsync[n] = new s[o]() : console.warn(`Lip-sync module for ${n} not found. Available modules:`, Object.keys(
|
|
5242
|
+
const s = rt[t];
|
|
5243
|
+
s && s[o] ? this.lipsync[n] = new s[o]() : console.warn(`Lip-sync module for ${n} not found. Available modules:`, Object.keys(rt));
|
|
5244
5244
|
} catch (s) {
|
|
5245
5245
|
console.warn(`Failed to load lip-sync module for ${n}:`, s);
|
|
5246
5246
|
}
|
|
@@ -5276,16 +5276,16 @@ class it {
|
|
|
5276
5276
|
speakText(n, e = null, t = null, o = null) {
|
|
5277
5277
|
e = e || {};
|
|
5278
5278
|
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;
|
|
5279
|
-
let c = "", r = "", h = 0, d = [],
|
|
5280
|
-
const b = Array.from(this.segmenter.segment(n), (
|
|
5281
|
-
for (let
|
|
5282
|
-
const
|
|
5283
|
-
let
|
|
5284
|
-
const
|
|
5285
|
-
if (
|
|
5279
|
+
let c = "", r = "", h = 0, d = [], p = [];
|
|
5280
|
+
const b = Array.from(this.segmenter.segment(n), (f) => f.segment);
|
|
5281
|
+
for (let f = 0; f < b.length; f++) {
|
|
5282
|
+
const L = f === b.length - 1, Q = b[f].match(a);
|
|
5283
|
+
let g = b[f].match(s);
|
|
5284
|
+
const H = b[f].match(u), M = b[f].match(i);
|
|
5285
|
+
if (g && !L && !H && b[f + 1].match(s) && (g = !1), t && (c += b[f]), Q && (!o || o.every((y) => f < y[0] || f > y[1])) && (r += b[f]), (M || g || L) && (r.length && (r = this.lipsyncPreProcessText(r, l), r.length && d.push({
|
|
5286
5286
|
mark: h,
|
|
5287
5287
|
word: r
|
|
5288
|
-
})), c.length && (
|
|
5288
|
+
})), c.length && (p.push({
|
|
5289
5289
|
mark: h,
|
|
5290
5290
|
template: { name: "subtitles" },
|
|
5291
5291
|
ts: [0],
|
|
@@ -5293,31 +5293,31 @@ class it {
|
|
|
5293
5293
|
subtitles: [c]
|
|
5294
5294
|
}
|
|
5295
5295
|
}), c = ""), r.length)) {
|
|
5296
|
-
const
|
|
5297
|
-
if (
|
|
5298
|
-
const
|
|
5299
|
-
for (let
|
|
5300
|
-
|
|
5296
|
+
const y = this.lipsyncWordsToVisemes(r, l);
|
|
5297
|
+
if (y && y.visemes && y.visemes.length) {
|
|
5298
|
+
const E = y.times[y.visemes.length - 1] + y.durations[y.visemes.length - 1];
|
|
5299
|
+
for (let S = 0; S < y.visemes.length; S++)
|
|
5300
|
+
p.push({
|
|
5301
5301
|
mark: h,
|
|
5302
5302
|
template: { name: "viseme" },
|
|
5303
|
-
ts: [(
|
|
5303
|
+
ts: [(y.times[S] - 0.6) / E, (y.times[S] + 0.5) / E, (y.times[S] + y.durations[S] + 0.5) / E],
|
|
5304
5304
|
vs: {
|
|
5305
|
-
["viseme_" +
|
|
5305
|
+
["viseme_" + y.visemes[S]]: [null, y.visemes[S] === "PP" || y.visemes[S] === "FF" ? 0.9 : 0.6, 0]
|
|
5306
5306
|
}
|
|
5307
5307
|
});
|
|
5308
5308
|
}
|
|
5309
5309
|
r = "", h++;
|
|
5310
5310
|
}
|
|
5311
|
-
if (
|
|
5312
|
-
if (d.length ||
|
|
5313
|
-
const
|
|
5314
|
-
anim:
|
|
5311
|
+
if (g || L) {
|
|
5312
|
+
if (d.length || L && p.length) {
|
|
5313
|
+
const y = {
|
|
5314
|
+
anim: p
|
|
5315
5315
|
};
|
|
5316
|
-
t && (
|
|
5316
|
+
t && (y.onSubtitles = t), d.length && !e.avatarMute && (y.text = d, e.avatarMood && (y.mood = e.avatarMood), e.ttsLang && (y.lang = e.ttsLang), e.ttsVoice && (y.voice = e.ttsVoice), e.ttsRate && (y.rate = e.ttsRate), e.ttsVoice && (y.pitch = e.ttsPitch), e.ttsVolume && (y.volume = e.ttsVolume)), this.speechQueue.push(y), d = [], r = "", h = 0, p = [];
|
|
5317
5317
|
}
|
|
5318
|
-
if (
|
|
5319
|
-
let
|
|
5320
|
-
|
|
5318
|
+
if (H) {
|
|
5319
|
+
let y = this.animEmojis[b[f]];
|
|
5320
|
+
y && y.link && (y = this.animEmojis[y.link]), y && this.speechQueue.push({ emoji: y });
|
|
5321
5321
|
}
|
|
5322
5322
|
this.speechQueue.push({ break: 100 });
|
|
5323
5323
|
}
|
|
@@ -5409,16 +5409,16 @@ class it {
|
|
|
5409
5409
|
}), !n.visemes)) {
|
|
5410
5410
|
const r = this.lipsyncPreProcessText(u, o), h = this.lipsyncWordsToVisemes(r, o);
|
|
5411
5411
|
if (h && h.visemes && h.visemes.length) {
|
|
5412
|
-
const d = h.times[h.visemes.length - 1] + h.durations[h.visemes.length - 1],
|
|
5413
|
-
let b = 0.6 + this.convertRange(
|
|
5412
|
+
const d = h.times[h.visemes.length - 1] + h.durations[h.visemes.length - 1], p = Math.min(c, Math.max(0, c - h.visemes.length * 150));
|
|
5413
|
+
let b = 0.6 + this.convertRange(p, [0, c], [0, 0.4]);
|
|
5414
5414
|
if (c = Math.min(c, h.visemes.length * 200), d > 0)
|
|
5415
|
-
for (let
|
|
5416
|
-
const
|
|
5415
|
+
for (let f = 0; f < h.visemes.length; f++) {
|
|
5416
|
+
const L = l + h.times[f] / d * c, Q = h.durations[f] / d * c;
|
|
5417
5417
|
i.push({
|
|
5418
5418
|
template: { name: "viseme" },
|
|
5419
|
-
ts: [
|
|
5419
|
+
ts: [L - Math.min(60, 2 * Q / 3), L + Math.min(25, Q / 2), L + Q + Math.min(60, Q / 2)],
|
|
5420
5420
|
vs: {
|
|
5421
|
-
["viseme_" + h.visemes[
|
|
5421
|
+
["viseme_" + h.visemes[f]]: [null, h.visemes[f] === "PP" || h.visemes[f] === "FF" ? 0.9 : b, 0]
|
|
5422
5422
|
}
|
|
5423
5423
|
});
|
|
5424
5424
|
}
|
|
@@ -5547,32 +5547,32 @@ class it {
|
|
|
5547
5547
|
*/
|
|
5548
5548
|
async synthesizeWithBrowserTTS(n) {
|
|
5549
5549
|
return new Promise((e, t) => {
|
|
5550
|
-
const o = Array.isArray(n.text) ? n.text.map((
|
|
5550
|
+
const o = Array.isArray(n.text) ? n.text.map((g) => g.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;
|
|
5551
5551
|
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));
|
|
5552
5552
|
const c = speechSynthesis.getVoices(), r = n.voice || this.avatar.ttsVoice || this.opt.ttsVoice;
|
|
5553
5553
|
if (r && c.length > 0) {
|
|
5554
|
-
const
|
|
5555
|
-
|
|
5554
|
+
const g = c.find((H) => H.name.includes(r) || H.lang === i);
|
|
5555
|
+
g && (s.voice = g);
|
|
5556
5556
|
}
|
|
5557
|
-
const h = o.length * 100 / s.rate, d = this.audioCtx.createBuffer(1, this.audioCtx.sampleRate * (h / 1e3), this.audioCtx.sampleRate),
|
|
5558
|
-
if (
|
|
5559
|
-
const
|
|
5560
|
-
for (let
|
|
5561
|
-
const
|
|
5562
|
-
|
|
5557
|
+
const h = o.length * 100 / s.rate, d = this.audioCtx.createBuffer(1, this.audioCtx.sampleRate * (h / 1e3), this.audioCtx.sampleRate), p = this.avatar.lipsyncLang || this.opt.lipsyncLang || "en", b = this.lipsyncPreProcessText(o, p), f = this.lipsyncWordsToVisemes(b, p), L = [];
|
|
5558
|
+
if (f && f.visemes && f.visemes.length > 0) {
|
|
5559
|
+
const g = f.times[f.visemes.length - 1] + f.durations[f.visemes.length - 1];
|
|
5560
|
+
for (let H = 0; H < f.visemes.length; H++) {
|
|
5561
|
+
const M = f.visemes[H], y = f.times[H] / g, E = f.durations[H] / g, S = y * h, C = E * h;
|
|
5562
|
+
L.push({
|
|
5563
5563
|
template: { name: "viseme" },
|
|
5564
|
-
ts: [
|
|
5564
|
+
ts: [S - Math.min(60, 2 * C / 3), S + Math.min(25, C / 2), S + C + Math.min(60, C / 2)],
|
|
5565
5565
|
vs: {
|
|
5566
|
-
["viseme_" +
|
|
5566
|
+
["viseme_" + M]: [null, M === "PP" || M === "FF" ? 0.9 : 0.6, 0]
|
|
5567
5567
|
}
|
|
5568
5568
|
});
|
|
5569
5569
|
}
|
|
5570
5570
|
}
|
|
5571
|
-
const
|
|
5572
|
-
this.audioPlaylist.push({ anim:
|
|
5571
|
+
const Q = [...n.anim, ...L];
|
|
5572
|
+
this.audioPlaylist.push({ anim: Q, audio: d }), this.onSubtitles = n.onSubtitles || null, this.resetLips(), n.mood && this.setMood(n.mood), this.playAudio(), s.onend = () => {
|
|
5573
5573
|
e();
|
|
5574
|
-
}, s.onerror = (
|
|
5575
|
-
console.error("Speech synthesis error:",
|
|
5574
|
+
}, s.onerror = (g) => {
|
|
5575
|
+
console.error("Speech synthesis error:", g.error), t(g.error);
|
|
5576
5576
|
}, speechSynthesis.speak(s);
|
|
5577
5577
|
});
|
|
5578
5578
|
}
|
|
@@ -5616,8 +5616,8 @@ class it {
|
|
|
5616
5616
|
hasVisemes: d && d.visemes && d.visemes.length > 0
|
|
5617
5617
|
}), d && d.visemes && d.visemes.length > 0)
|
|
5618
5618
|
l = {
|
|
5619
|
-
visemes: d.visemes.map((
|
|
5620
|
-
viseme:
|
|
5619
|
+
visemes: d.visemes.map((p, b) => ({
|
|
5620
|
+
viseme: p,
|
|
5621
5621
|
startTime: b * a.duration / d.visemes.length,
|
|
5622
5622
|
endTime: (b + 1) * a.duration / d.visemes.length,
|
|
5623
5623
|
duration: a.duration / d.visemes.length,
|
|
@@ -5631,18 +5631,18 @@ class it {
|
|
|
5631
5631
|
throw new Error("No visemes generated from text");
|
|
5632
5632
|
} catch (h) {
|
|
5633
5633
|
console.error("Text-based lip-sync failed, using fallback:", h);
|
|
5634
|
-
const d = e.toLowerCase().split(/\s+/),
|
|
5634
|
+
const d = e.toLowerCase().split(/\s+/), p = [];
|
|
5635
5635
|
for (const b of d)
|
|
5636
|
-
for (const
|
|
5637
|
-
let
|
|
5638
|
-
"aeiou".includes(
|
|
5636
|
+
for (const f of b) {
|
|
5637
|
+
let L = "aa";
|
|
5638
|
+
"aeiou".includes(f) ? L = "aa" : "bp".includes(f) ? L = "PP" : "fv".includes(f) ? L = "FF" : "st".includes(f) ? L = "SS" : "dln".includes(f) ? L = "DD" : "kg".includes(f) ? L = "kk" : "rw".includes(f) && (L = "RR"), p.push(L);
|
|
5639
5639
|
}
|
|
5640
5640
|
l = {
|
|
5641
|
-
visemes:
|
|
5641
|
+
visemes: p.map((b, f) => ({
|
|
5642
5642
|
viseme: b,
|
|
5643
|
-
startTime:
|
|
5644
|
-
endTime: (
|
|
5645
|
-
duration: a.duration /
|
|
5643
|
+
startTime: f * a.duration / p.length,
|
|
5644
|
+
endTime: (f + 1) * a.duration / p.length,
|
|
5645
|
+
duration: a.duration / p.length,
|
|
5646
5646
|
intensity: 0.6
|
|
5647
5647
|
})),
|
|
5648
5648
|
words: [],
|
|
@@ -5653,12 +5653,12 @@ class it {
|
|
|
5653
5653
|
const c = [];
|
|
5654
5654
|
if (l.visemes && l.visemes.length > 0)
|
|
5655
5655
|
for (let h = 0; h < l.visemes.length; h++) {
|
|
5656
|
-
const d = l.visemes[h],
|
|
5656
|
+
const d = l.visemes[h], p = d.startTime * 1e3, b = d.duration * 1e3, f = d.intensity;
|
|
5657
5657
|
c.push({
|
|
5658
5658
|
template: { name: "viseme" },
|
|
5659
|
-
ts: [
|
|
5659
|
+
ts: [p - Math.min(60, 2 * b / 3), p + Math.min(25, b / 2), p + b + Math.min(60, b / 2)],
|
|
5660
5660
|
vs: {
|
|
5661
|
-
["viseme_" + d.viseme]: [null,
|
|
5661
|
+
["viseme_" + d.viseme]: [null, f, 0]
|
|
5662
5662
|
}
|
|
5663
5663
|
});
|
|
5664
5664
|
}
|
|
@@ -5698,8 +5698,8 @@ class it {
|
|
|
5698
5698
|
hasVisemes: d && d.visemes && d.visemes.length > 0
|
|
5699
5699
|
}), d && d.visemes && d.visemes.length > 0)
|
|
5700
5700
|
l = {
|
|
5701
|
-
visemes: d.visemes.map((
|
|
5702
|
-
viseme:
|
|
5701
|
+
visemes: d.visemes.map((p, b) => ({
|
|
5702
|
+
viseme: p,
|
|
5703
5703
|
startTime: b * a.duration / d.visemes.length,
|
|
5704
5704
|
endTime: (b + 1) * a.duration / d.visemes.length,
|
|
5705
5705
|
duration: a.duration / d.visemes.length,
|
|
@@ -5713,18 +5713,18 @@ class it {
|
|
|
5713
5713
|
throw new Error("No visemes generated from text");
|
|
5714
5714
|
} catch (h) {
|
|
5715
5715
|
console.error("Text-based lip-sync failed, using fallback:", h);
|
|
5716
|
-
const d = e.toLowerCase().split(/\s+/),
|
|
5716
|
+
const d = e.toLowerCase().split(/\s+/), p = [];
|
|
5717
5717
|
for (const b of d)
|
|
5718
|
-
for (const
|
|
5719
|
-
let
|
|
5720
|
-
"aeiou".includes(
|
|
5718
|
+
for (const f of b) {
|
|
5719
|
+
let L = "aa";
|
|
5720
|
+
"aeiou".includes(f) ? L = "aa" : "bp".includes(f) ? L = "PP" : "fv".includes(f) ? L = "FF" : "st".includes(f) ? L = "SS" : "dln".includes(f) ? L = "DD" : "kg".includes(f) ? L = "kk" : "rw".includes(f) && (L = "RR"), p.push(L);
|
|
5721
5721
|
}
|
|
5722
5722
|
l = {
|
|
5723
|
-
visemes:
|
|
5723
|
+
visemes: p.map((b, f) => ({
|
|
5724
5724
|
viseme: b,
|
|
5725
|
-
startTime:
|
|
5726
|
-
endTime: (
|
|
5727
|
-
duration: a.duration /
|
|
5725
|
+
startTime: f * a.duration / p.length,
|
|
5726
|
+
endTime: (f + 1) * a.duration / p.length,
|
|
5727
|
+
duration: a.duration / p.length,
|
|
5728
5728
|
intensity: 0.6
|
|
5729
5729
|
})),
|
|
5730
5730
|
words: [],
|
|
@@ -5735,12 +5735,12 @@ class it {
|
|
|
5735
5735
|
const c = [];
|
|
5736
5736
|
if (l.visemes && l.visemes.length > 0)
|
|
5737
5737
|
for (let h = 0; h < l.visemes.length; h++) {
|
|
5738
|
-
const d = l.visemes[h],
|
|
5738
|
+
const d = l.visemes[h], p = d.startTime * 1e3, b = d.duration * 1e3, f = d.intensity;
|
|
5739
5739
|
c.push({
|
|
5740
5740
|
template: { name: "viseme" },
|
|
5741
|
-
ts: [
|
|
5741
|
+
ts: [p - Math.min(60, 2 * b / 3), p + Math.min(25, b / 2), p + b + Math.min(60, b / 2)],
|
|
5742
5742
|
vs: {
|
|
5743
|
-
["viseme_" + d.viseme]: [null,
|
|
5743
|
+
["viseme_" + d.viseme]: [null, f, 0]
|
|
5744
5744
|
}
|
|
5745
5745
|
});
|
|
5746
5746
|
}
|
|
@@ -5773,10 +5773,10 @@ class it {
|
|
|
5773
5773
|
throw new Error(`Azure TTS error: ${s.status} ${s.statusText}`);
|
|
5774
5774
|
const i = await s.arrayBuffer(), a = await this.audioCtx.decodeAudioData(i), u = await this.audioAnalyzer.analyzeAudio(a, e), l = [];
|
|
5775
5775
|
for (let r = 0; r < u.visemes.length; r++) {
|
|
5776
|
-
const h = u.visemes[r], d = h.startTime * 1e3,
|
|
5776
|
+
const h = u.visemes[r], d = h.startTime * 1e3, p = h.duration * 1e3, b = h.intensity;
|
|
5777
5777
|
l.push({
|
|
5778
5778
|
template: { name: "viseme" },
|
|
5779
|
-
ts: [d - Math.min(60, 2 *
|
|
5779
|
+
ts: [d - Math.min(60, 2 * p / 3), d + Math.min(25, p / 2), d + p + Math.min(60, p / 2)],
|
|
5780
5780
|
vs: {
|
|
5781
5781
|
["viseme_" + h.viseme]: [null, b, 0]
|
|
5782
5782
|
}
|
|
@@ -5826,23 +5826,23 @@ class it {
|
|
|
5826
5826
|
let l = 0;
|
|
5827
5827
|
n.text.forEach((h, d) => {
|
|
5828
5828
|
if (d > 0) {
|
|
5829
|
-
let
|
|
5830
|
-
s.timepoints[l] && (
|
|
5829
|
+
let p = u[u.length - 1];
|
|
5830
|
+
s.timepoints[l] && (p = s.timepoints[l].timeSeconds * 1e3, s.timepoints[l].markName === "" + h.mark && l++), u.push(p);
|
|
5831
5831
|
}
|
|
5832
5832
|
});
|
|
5833
5833
|
const c = [{ mark: 0, time: 0 }];
|
|
5834
5834
|
u.forEach((h, d) => {
|
|
5835
5835
|
if (d > 0) {
|
|
5836
|
-
let
|
|
5837
|
-
c[d - 1].duration =
|
|
5836
|
+
let p = h - u[d - 1];
|
|
5837
|
+
c[d - 1].duration = p, c.push({ mark: d, time: h });
|
|
5838
5838
|
}
|
|
5839
5839
|
});
|
|
5840
5840
|
let r = 1e3 * a.duration;
|
|
5841
5841
|
r > this.opt.ttsTrimEnd && (r = r - this.opt.ttsTrimEnd), c[c.length - 1].duration = r - c[c.length - 1].time, n.anim.forEach((h) => {
|
|
5842
5842
|
const d = c[h.mark];
|
|
5843
5843
|
if (d)
|
|
5844
|
-
for (let
|
|
5845
|
-
h.ts[
|
|
5844
|
+
for (let p = 0; p < h.ts.length; p++)
|
|
5845
|
+
h.ts[p] = d.time + h.ts[p] * d.duration + this.opt.ttsTrimStart;
|
|
5846
5846
|
}), this.audioPlaylist.push({ anim: n.anim, audio: a }), this.onSubtitles = n.onSubtitles || null, this.resetLips(), n.mood && this.setMood(n.mood), this.playAudio();
|
|
5847
5847
|
} else
|
|
5848
5848
|
this.startSpeaking(!0);
|
|
@@ -5866,10 +5866,17 @@ class it {
|
|
|
5866
5866
|
e.isRaw || (this.lookAtCamera(500), this.speakWithHands(), this.resetLips()), this.audioPlaylist.push({ anim: e.anim, audio: e.audio, isRaw: e.isRaw }), this.onSubtitles = e.onSubtitles || null, e.mood && this.setMood(e.mood), this.playAudio();
|
|
5867
5867
|
else if (e.text) {
|
|
5868
5868
|
this.lookAtCamera(500);
|
|
5869
|
+
let t = "";
|
|
5870
|
+
if (Array.isArray(e.text) ? t = e.text.map((o) => o.word).join(" ") : typeof e.text == "string" && (t = e.text), t && this.onSubtitles && typeof this.onSubtitles == "function")
|
|
5871
|
+
try {
|
|
5872
|
+
this.onSubtitles({ text: t, subtitles: [t] });
|
|
5873
|
+
} catch (o) {
|
|
5874
|
+
console.warn("Error in subtitle callback:", o);
|
|
5875
|
+
}
|
|
5869
5876
|
try {
|
|
5870
5877
|
!this.opt.ttsEndpoint || this.opt.ttsEndpoint === "" ? await this.synthesizeWithBrowserTTS(e) : this.opt.ttsService === "elevenlabs" ? await this.synthesizeWithElevenLabsTTS(e) : this.opt.ttsService === "deepgram" ? await this.synthesizeWithDeepgramTTS(e) : this.opt.ttsService === "azure" ? await this.synthesizeWithAzureTTS(e) : await this.synthesizeWithExternalTTS(e);
|
|
5871
|
-
} catch (
|
|
5872
|
-
console.error("Error:",
|
|
5878
|
+
} catch (o) {
|
|
5879
|
+
console.error("Error:", o), this.startSpeaking(!0);
|
|
5873
5880
|
}
|
|
5874
5881
|
} else e.anim ? (this.onSubtitles = e.onSubtitles || null, this.resetLips(), e.mood && this.setMood(e.mood), e.anim.forEach((t, o) => {
|
|
5875
5882
|
for (let s = 0; s < t.ts.length; s++)
|
|
@@ -5895,27 +5902,27 @@ class it {
|
|
|
5895
5902
|
a
|
|
5896
5903
|
);
|
|
5897
5904
|
for (let h = 0; h < i.numberOfChannels; h++) {
|
|
5898
|
-
const d = i.getChannelData(h),
|
|
5905
|
+
const d = i.getChannelData(h), p = c.getChannelData(h);
|
|
5899
5906
|
for (let b = 0; b < l; b++)
|
|
5900
|
-
|
|
5907
|
+
p[b] = d[u + b];
|
|
5901
5908
|
}
|
|
5902
5909
|
let r = null;
|
|
5903
5910
|
if (this.currentAudioItem.anim) {
|
|
5904
|
-
const h = this.animClock + this.currentAudioItem.delay, d = t * 1e3,
|
|
5911
|
+
const h = this.animClock + this.currentAudioItem.delay, d = t * 1e3, p = h + d;
|
|
5905
5912
|
r = this.currentAudioItem.anim.map((b) => {
|
|
5906
|
-
const
|
|
5913
|
+
const f = {
|
|
5907
5914
|
template: b.template,
|
|
5908
5915
|
ts: [],
|
|
5909
5916
|
vs: []
|
|
5910
5917
|
};
|
|
5911
|
-
for (let
|
|
5912
|
-
const
|
|
5913
|
-
if (
|
|
5914
|
-
const
|
|
5915
|
-
|
|
5918
|
+
for (let L = 0; L < b.ts.length; L++) {
|
|
5919
|
+
const Q = b.ts[L];
|
|
5920
|
+
if (Q > p) {
|
|
5921
|
+
const g = Q - p;
|
|
5922
|
+
f.ts.push(g), f.vs.push(b.vs[L]);
|
|
5916
5923
|
}
|
|
5917
5924
|
}
|
|
5918
|
-
return
|
|
5925
|
+
return f.ts.length > 0 ? f : null;
|
|
5919
5926
|
}).filter((b) => b !== null);
|
|
5920
5927
|
}
|
|
5921
5928
|
n = {
|
|
@@ -5974,7 +5981,7 @@ class it {
|
|
|
5974
5981
|
}
|
|
5975
5982
|
if (!this.workletLoaded)
|
|
5976
5983
|
try {
|
|
5977
|
-
const a = this.audioCtx.audioWorklet.addModule(
|
|
5984
|
+
const a = this.audioCtx.audioWorklet.addModule(Dt.href), u = new Promise(
|
|
5978
5985
|
(l, c) => setTimeout(() => c(new Error("Worklet loading timed out")), 5e3)
|
|
5979
5986
|
);
|
|
5980
5987
|
await Promise.race([a, u]), this.workletLoaded = !0;
|
|
@@ -6116,10 +6123,10 @@ class it {
|
|
|
6116
6123
|
let h = 0.6 + this.convertRange(r, [0, i], [0, 0.4]);
|
|
6117
6124
|
if (i = Math.min(i, l.visemes.length * 200), c > 0)
|
|
6118
6125
|
for (let d = 0; d < l.visemes.length; d++) {
|
|
6119
|
-
const
|
|
6126
|
+
const p = e + s + l.times[d] / c * i, b = l.durations[d] / c * i;
|
|
6120
6127
|
this.animQueue.push({
|
|
6121
6128
|
template: { name: "viseme" },
|
|
6122
|
-
ts: [
|
|
6129
|
+
ts: [p - Math.min(60, 2 * b / 3), p + Math.min(25, b / 2), p + b + Math.min(60, b / 2)],
|
|
6123
6130
|
vs: {
|
|
6124
6131
|
["viseme_" + l.visemes[d]]: [null, l.visemes[d] === "PP" || l.visemes[d] === "FF" ? 0.9 : h, 0]
|
|
6125
6132
|
}
|
|
@@ -6212,7 +6219,7 @@ class it {
|
|
|
6212
6219
|
*/
|
|
6213
6220
|
lookAtCamera(n) {
|
|
6214
6221
|
let e;
|
|
6215
|
-
if (this.speakTo && (e = new A.Vector3(), this.speakTo.objectLeftEye?.isObject3D ? (this.speakTo.armature.objectHead, this.speakTo.objectLeftEye.updateMatrixWorld(!0), this.speakTo.objectRightEye.updateMatrixWorld(!0), Ne.setFromMatrixPosition(this.speakTo.objectLeftEye.matrixWorld),
|
|
6222
|
+
if (this.speakTo && (e = new A.Vector3(), this.speakTo.objectLeftEye?.isObject3D ? (this.speakTo.armature.objectHead, this.speakTo.objectLeftEye.updateMatrixWorld(!0), this.speakTo.objectRightEye.updateMatrixWorld(!0), Ne.setFromMatrixPosition(this.speakTo.objectLeftEye.matrixWorld), We.setFromMatrixPosition(this.speakTo.objectRightEye.matrixWorld), e.addVectors(Ne, We).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) {
|
|
6216
6223
|
if (this.avatar.hasOwnProperty("avatarIgnoreCamera")) {
|
|
6217
6224
|
if (this.avatar.avatarIgnoreCamera) {
|
|
6218
6225
|
this.lookAhead(n);
|
|
@@ -6225,23 +6232,23 @@ class it {
|
|
|
6225
6232
|
this.lookAt(null, null, n);
|
|
6226
6233
|
return;
|
|
6227
6234
|
}
|
|
6228
|
-
this.objectLeftEye.updateMatrixWorld(!0), this.objectRightEye.updateMatrixWorld(!0), Ne.setFromMatrixPosition(this.objectLeftEye.matrixWorld),
|
|
6235
|
+
this.objectLeftEye.updateMatrixWorld(!0), this.objectRightEye.updateMatrixWorld(!0), Ne.setFromMatrixPosition(this.objectLeftEye.matrixWorld), We.setFromMatrixPosition(this.objectRightEye.matrixWorld), Ne.add(We).divideScalar(2), he.copy(this.armature.quaternion), he.multiply(this.poseTarget.props["Hips.quaternion"]), he.multiply(this.poseTarget.props["Spine.quaternion"]), he.multiply(this.poseTarget.props["Spine1.quaternion"]), he.multiply(this.poseTarget.props["Spine2.quaternion"]), he.multiply(this.poseTarget.props["Neck.quaternion"]), he.multiply(this.poseTarget.props["Head.quaternion"]);
|
|
6229
6236
|
const t = new A.Vector3().subVectors(e, Ne).normalize(), o = Math.atan2(t.x, t.z), s = Math.asin(-t.y);
|
|
6230
|
-
|
|
6231
|
-
const a = new A.Quaternion().setFromEuler(
|
|
6232
|
-
|
|
6233
|
-
let l =
|
|
6237
|
+
re.set(s, o, 0, "YXZ");
|
|
6238
|
+
const a = new A.Quaternion().setFromEuler(re), u = new A.Quaternion().copy(a).multiply(he.clone().invert());
|
|
6239
|
+
re.setFromQuaternion(u, "YXZ");
|
|
6240
|
+
let l = re.x / (40 / 24) + 0.2, c = re.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, p = (Math.random() - 0.5) / 4;
|
|
6234
6241
|
if (n) {
|
|
6235
|
-
let b = this.animQueue.findIndex((
|
|
6242
|
+
let b = this.animQueue.findIndex((L) => L.template.name === "lookat");
|
|
6236
6243
|
b !== -1 && this.animQueue.splice(b, 1);
|
|
6237
|
-
const
|
|
6244
|
+
const f = {
|
|
6238
6245
|
name: "lookat",
|
|
6239
6246
|
dt: [750, n],
|
|
6240
6247
|
vs: {
|
|
6241
6248
|
bodyRotateX: [r + d],
|
|
6242
|
-
bodyRotateY: [h +
|
|
6249
|
+
bodyRotateY: [h + p],
|
|
6243
6250
|
eyesRotateX: [-3 * d + 0.1],
|
|
6244
|
-
eyesRotateY: [-5 *
|
|
6251
|
+
eyesRotateY: [-5 * p],
|
|
6245
6252
|
browInnerUp: [[0, 0.7]],
|
|
6246
6253
|
mouthLeft: [[0, 0.7]],
|
|
6247
6254
|
mouthRight: [[0, 0.7]],
|
|
@@ -6249,7 +6256,7 @@ class it {
|
|
|
6249
6256
|
headMove: [0]
|
|
6250
6257
|
}
|
|
6251
6258
|
};
|
|
6252
|
-
this.animQueue.push(this.animFactory(
|
|
6259
|
+
this.animQueue.push(this.animFactory(f));
|
|
6253
6260
|
}
|
|
6254
6261
|
}
|
|
6255
6262
|
/**
|
|
@@ -6265,21 +6272,21 @@ class it {
|
|
|
6265
6272
|
const s = new A.Vector3().setFromMatrixPosition(this.objectLeftEye.matrixWorld), i = new A.Vector3().setFromMatrixPosition(this.objectRightEye.matrixWorld), a = new A.Vector3().addVectors(s, i).divideScalar(2);
|
|
6266
6273
|
a.project(this.camera);
|
|
6267
6274
|
let u = (a.x + 1) / 2 * o.width + o.left, l = -(a.y - 1) / 2 * o.height + o.top;
|
|
6268
|
-
n === null && (n = u), e === null && (e = l),
|
|
6269
|
-
let c =
|
|
6270
|
-
|
|
6271
|
-
let
|
|
6275
|
+
n === null && (n = u), e === null && (e = l), he.copy(this.armature.quaternion), he.multiply(this.poseTarget.props["Hips.quaternion"]), he.multiply(this.poseTarget.props["Spine.quaternion"]), he.multiply(this.poseTarget.props["Spine1.quaternion"]), he.multiply(this.poseTarget.props["Spine2.quaternion"]), he.multiply(this.poseTarget.props["Neck.quaternion"]), he.multiply(this.poseTarget.props["Head.quaternion"]), re.setFromQuaternion(he);
|
|
6276
|
+
let c = re.x / (40 / 24), r = re.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)), p = Math.max(window.innerWidth - u, u), b = Math.max(window.innerHeight - l, l), f = this.convertRange(e, [l - b, l + b], [-0.3, 0.6]) - c + h, L = this.convertRange(n, [u - p, u + p], [-0.8, 0.8]) - r + d;
|
|
6277
|
+
f = Math.min(0.6, Math.max(-0.3, f)), L = Math.min(0.8, Math.max(-0.8, L));
|
|
6278
|
+
let Q = (Math.random() - 0.5) / 4, g = (Math.random() - 0.5) / 4;
|
|
6272
6279
|
if (t) {
|
|
6273
|
-
let
|
|
6274
|
-
|
|
6275
|
-
const
|
|
6280
|
+
let H = this.animQueue.findIndex((y) => y.template.name === "lookat");
|
|
6281
|
+
H !== -1 && this.animQueue.splice(H, 1);
|
|
6282
|
+
const M = {
|
|
6276
6283
|
name: "lookat",
|
|
6277
6284
|
dt: [750, t],
|
|
6278
6285
|
vs: {
|
|
6279
|
-
bodyRotateX: [
|
|
6280
|
-
bodyRotateY: [
|
|
6281
|
-
eyesRotateX: [-3 *
|
|
6282
|
-
eyesRotateY: [-5 *
|
|
6286
|
+
bodyRotateX: [f + Q],
|
|
6287
|
+
bodyRotateY: [L + g],
|
|
6288
|
+
eyesRotateX: [-3 * Q + 0.1],
|
|
6289
|
+
eyesRotateY: [-5 * g],
|
|
6283
6290
|
browInnerUp: [[0, 0.7]],
|
|
6284
6291
|
mouthLeft: [[0, 0.7]],
|
|
6285
6292
|
mouthRight: [[0, 0.7]],
|
|
@@ -6287,7 +6294,7 @@ class it {
|
|
|
6287
6294
|
headMove: [0]
|
|
6288
6295
|
}
|
|
6289
6296
|
};
|
|
6290
|
-
this.animQueue.push(this.animFactory(
|
|
6297
|
+
this.animQueue.push(this.animFactory(M));
|
|
6291
6298
|
}
|
|
6292
6299
|
}
|
|
6293
6300
|
/**
|
|
@@ -6511,7 +6518,7 @@ class it {
|
|
|
6511
6518
|
} catch (d) {
|
|
6512
6519
|
console.warn(`Could not verify file existence for ${n}, attempting to load anyway:`, d);
|
|
6513
6520
|
}
|
|
6514
|
-
const r = new
|
|
6521
|
+
const r = new ot();
|
|
6515
6522
|
let h;
|
|
6516
6523
|
try {
|
|
6517
6524
|
h = await r.loadAsync(n, e);
|
|
@@ -6522,54 +6529,54 @@ class it {
|
|
|
6522
6529
|
suggestion: "Make sure the file is a valid FBX file and the path is correct"
|
|
6523
6530
|
}), d.message && d.message.includes("version number") && (console.error("FBX Loader Error: Cannot find version number"), console.error("This error usually means:"), console.error("1. The file is not a valid FBX file (might be GLB, corrupted, or wrong format)"), console.error("2. The file might be corrupted"), console.error("3. The file path might be incorrect"), console.error("4. The server returned an HTML error page instead of the FBX file"), console.error("5. The file might not exist at that path"), console.error(""), console.error("Solution: Please verify:"), console.error(` - File exists at: ${n}`), console.error(" - File is a valid FBX binary file"), console.error(" - File path matches your public folder structure"), console.error(" - File is not corrupted"));
|
|
6524
6531
|
try {
|
|
6525
|
-
const
|
|
6532
|
+
const p = await fetch(n), b = p.headers.get("content-type"), f = await p.text();
|
|
6526
6533
|
console.error("Response details:", {
|
|
6527
|
-
status:
|
|
6534
|
+
status: p.status,
|
|
6528
6535
|
contentType: b,
|
|
6529
|
-
firstBytes:
|
|
6530
|
-
isHTML:
|
|
6531
|
-
}), (
|
|
6532
|
-
} catch (
|
|
6533
|
-
console.error("Could not fetch file for debugging:",
|
|
6536
|
+
firstBytes: f.substring(0, 100),
|
|
6537
|
+
isHTML: f.trim().startsWith("<!DOCTYPE") || f.trim().startsWith("<html")
|
|
6538
|
+
}), (f.trim().startsWith("<!DOCTYPE") || f.trim().startsWith("<html")) && console.error("The server returned an HTML page instead of an FBX file. The file path is likely incorrect.");
|
|
6539
|
+
} catch (p) {
|
|
6540
|
+
console.error("Could not fetch file for debugging:", p);
|
|
6534
6541
|
}
|
|
6535
6542
|
return;
|
|
6536
6543
|
}
|
|
6537
6544
|
if (h && h.animations && h.animations[o]) {
|
|
6538
6545
|
let d = h.animations[o];
|
|
6539
|
-
const
|
|
6540
|
-
this.armature && this.armature.traverse((
|
|
6541
|
-
(
|
|
6546
|
+
const p = /* @__PURE__ */ new Set();
|
|
6547
|
+
this.armature && this.armature.traverse((y) => {
|
|
6548
|
+
(y.isBone || y.type === "Bone") && p.add(y.name);
|
|
6542
6549
|
});
|
|
6543
|
-
const b = /* @__PURE__ */ new Map(),
|
|
6544
|
-
if (
|
|
6545
|
-
return
|
|
6546
|
-
let
|
|
6547
|
-
if (
|
|
6548
|
-
return
|
|
6549
|
-
const
|
|
6550
|
-
if (
|
|
6551
|
-
if (
|
|
6552
|
-
if (
|
|
6553
|
-
if (
|
|
6554
|
-
} else if (!
|
|
6550
|
+
const b = /* @__PURE__ */ new Map(), f = (y) => {
|
|
6551
|
+
if (p.has(y))
|
|
6552
|
+
return y;
|
|
6553
|
+
let E = y.replace(/^mixamorig/i, "").replace(/^CC_Base_/i, "").replace(/^RPM_/i, "");
|
|
6554
|
+
if (p.has(E))
|
|
6555
|
+
return E;
|
|
6556
|
+
const S = E.toLowerCase();
|
|
6557
|
+
if (S.includes("left") && S.includes("arm")) {
|
|
6558
|
+
if (S.includes("fore") || S.includes("lower")) {
|
|
6559
|
+
if (p.has("LeftForeArm")) return "LeftForeArm";
|
|
6560
|
+
if (p.has("LeftForearm")) return "LeftForearm";
|
|
6561
|
+
} else if (!S.includes("fore") && !S.includes("hand") && p.has("LeftArm"))
|
|
6555
6562
|
return "LeftArm";
|
|
6556
6563
|
}
|
|
6557
|
-
if (
|
|
6558
|
-
if (
|
|
6559
|
-
if (
|
|
6560
|
-
if (
|
|
6561
|
-
} else if (!
|
|
6564
|
+
if (S.includes("right") && S.includes("arm")) {
|
|
6565
|
+
if (S.includes("fore") || S.includes("lower")) {
|
|
6566
|
+
if (p.has("RightForeArm")) return "RightForeArm";
|
|
6567
|
+
if (p.has("RightForearm")) return "RightForearm";
|
|
6568
|
+
} else if (!S.includes("fore") && !S.includes("hand") && p.has("RightArm"))
|
|
6562
6569
|
return "RightArm";
|
|
6563
6570
|
}
|
|
6564
|
-
if (
|
|
6571
|
+
if (S.includes("left") && S.includes("hand") && !S.includes("index") && !S.includes("thumb") && !S.includes("middle") && !S.includes("ring") && !S.includes("pinky") && p.has("LeftHand"))
|
|
6565
6572
|
return "LeftHand";
|
|
6566
|
-
if (
|
|
6573
|
+
if (S.includes("right") && S.includes("hand") && !S.includes("index") && !S.includes("thumb") && !S.includes("middle") && !S.includes("ring") && !S.includes("pinky") && p.has("RightHand"))
|
|
6567
6574
|
return "RightHand";
|
|
6568
|
-
if (
|
|
6575
|
+
if (S.includes("left") && (S.includes("shoulder") || S.includes("clavicle")) && p.has("LeftShoulder"))
|
|
6569
6576
|
return "LeftShoulder";
|
|
6570
|
-
if (
|
|
6577
|
+
if (S.includes("right") && (S.includes("shoulder") || S.includes("clavicle")) && p.has("RightShoulder"))
|
|
6571
6578
|
return "RightShoulder";
|
|
6572
|
-
const
|
|
6579
|
+
const C = {
|
|
6573
6580
|
// Arm bones - exact matches
|
|
6574
6581
|
LeftArm: "LeftArm",
|
|
6575
6582
|
leftArm: "LeftArm",
|
|
@@ -6609,54 +6616,54 @@ class it {
|
|
|
6609
6616
|
Root: "Hips",
|
|
6610
6617
|
root: "Hips"
|
|
6611
6618
|
};
|
|
6612
|
-
if (
|
|
6613
|
-
const
|
|
6614
|
-
if (
|
|
6615
|
-
return
|
|
6619
|
+
if (C[E]) {
|
|
6620
|
+
const x = C[E];
|
|
6621
|
+
if (p.has(x))
|
|
6622
|
+
return x;
|
|
6616
6623
|
}
|
|
6617
|
-
for (const
|
|
6618
|
-
if (
|
|
6619
|
-
return
|
|
6620
|
-
for (const
|
|
6621
|
-
const I =
|
|
6622
|
-
if ((
|
|
6623
|
-
return
|
|
6624
|
+
for (const x of p)
|
|
6625
|
+
if (x.toLowerCase() === S)
|
|
6626
|
+
return x;
|
|
6627
|
+
for (const x of p) {
|
|
6628
|
+
const I = x.toLowerCase();
|
|
6629
|
+
if ((S.includes("left") && I.includes("left") || S.includes("right") && I.includes("right")) && (S.includes("arm") && I.includes("arm") && !I.includes("fore") || S.includes("forearm") && I.includes("forearm") || S.includes("hand") && I.includes("hand") && !I.includes("index") && !I.includes("thumb") || S.includes("shoulder") && I.includes("shoulder")))
|
|
6630
|
+
return x;
|
|
6624
6631
|
}
|
|
6625
6632
|
return null;
|
|
6626
|
-
},
|
|
6627
|
-
d.tracks.forEach((
|
|
6628
|
-
const
|
|
6629
|
-
|
|
6630
|
-
}), Array.from(
|
|
6631
|
-
(
|
|
6632
|
-
), Array.from(
|
|
6633
|
-
(
|
|
6633
|
+
}, L = /* @__PURE__ */ new Set();
|
|
6634
|
+
d.tracks.forEach((y) => {
|
|
6635
|
+
const E = y.name.split(".");
|
|
6636
|
+
L.add(E[0]);
|
|
6637
|
+
}), Array.from(L).filter(
|
|
6638
|
+
(y) => y.toLowerCase().includes("arm") || y.toLowerCase().includes("hand") || y.toLowerCase().includes("shoulder")
|
|
6639
|
+
), Array.from(p).filter(
|
|
6640
|
+
(y) => y.includes("Arm") || y.includes("Hand") || y.includes("Shoulder")
|
|
6634
6641
|
);
|
|
6635
|
-
const
|
|
6636
|
-
d.tracks.forEach((
|
|
6637
|
-
const
|
|
6638
|
-
if (!(I && (I === "LeftShoulder" || I === "RightShoulder") && (
|
|
6639
|
-
if (I &&
|
|
6640
|
-
const
|
|
6641
|
-
P.name =
|
|
6642
|
+
const Q = [], g = /* @__PURE__ */ new Set();
|
|
6643
|
+
d.tracks.forEach((y) => {
|
|
6644
|
+
const S = y.name.replaceAll("mixamorig", "").split("."), C = S[0], x = S[1], I = f(C);
|
|
6645
|
+
if (!(I && (I === "LeftShoulder" || I === "RightShoulder") && (x === "quaternion" || x === "rotation")))
|
|
6646
|
+
if (I && x) {
|
|
6647
|
+
const G = `${I}.${x}`, P = y.clone();
|
|
6648
|
+
P.name = G, Q.push(P), C !== I && b.set(C, I);
|
|
6642
6649
|
} else
|
|
6643
|
-
|
|
6644
|
-
}),
|
|
6645
|
-
const
|
|
6646
|
-
d.tracks.forEach((
|
|
6647
|
-
|
|
6648
|
-
const
|
|
6649
|
-
if (
|
|
6650
|
-
for (let
|
|
6651
|
-
|
|
6652
|
-
|
|
6653
|
-
} else
|
|
6650
|
+
g.add(C), (C.toLowerCase().includes("arm") || C.toLowerCase().includes("hand") || C.toLowerCase().includes("shoulder")) && console.warn(`⚠️ Arm bone "${C}" could not be mapped to avatar skeleton`);
|
|
6651
|
+
}), Q.length > 0 ? d = new A.AnimationClip(d.name, d.duration, Q) : console.error("No tracks could be mapped! Animation may not work correctly.");
|
|
6652
|
+
const H = {};
|
|
6653
|
+
d.tracks.forEach((y) => {
|
|
6654
|
+
y.name = y.name.replaceAll("mixamorig", "");
|
|
6655
|
+
const E = y.name.split(".");
|
|
6656
|
+
if (E[1] === "position") {
|
|
6657
|
+
for (let S = 0; S < y.values.length; S++)
|
|
6658
|
+
y.values[S] = y.values[S] * s;
|
|
6659
|
+
H[y.name] = new A.Vector3(y.values[0], y.values[1], y.values[2]);
|
|
6660
|
+
} else E[1] === "quaternion" ? H[y.name] = new A.Quaternion(y.values[0], y.values[1], y.values[2], y.values[3]) : E[1] === "rotation" && (H[E[0] + ".quaternion"] = new A.Quaternion().setFromEuler(new A.Euler(y.values[0], y.values[1], y.values[2], "XYZ")).normalize());
|
|
6654
6661
|
});
|
|
6655
|
-
const
|
|
6656
|
-
|
|
6662
|
+
const M = { props: H };
|
|
6663
|
+
H["Hips.position"] && (H["Hips.position"].y < 0.5 ? M.lying = !0 : M.standing = !0), this.animClips.push({
|
|
6657
6664
|
url: n + "-" + o,
|
|
6658
6665
|
clip: d,
|
|
6659
|
-
pose:
|
|
6666
|
+
pose: M
|
|
6660
6667
|
}), this.playAnimation(n, e, t, o, s);
|
|
6661
6668
|
} else {
|
|
6662
6669
|
const d = "Animation " + n + " (ndx=" + o + ") not found";
|
|
@@ -6694,7 +6701,7 @@ class it {
|
|
|
6694
6701
|
let a = this.animQueue.find((u) => u.template.name === "pose");
|
|
6695
6702
|
a && (a.ts[0] = this.animClock + t * 1e3 + 2e3), this.setPoseFromTemplate(i);
|
|
6696
6703
|
} else {
|
|
6697
|
-
let u = await new
|
|
6704
|
+
let u = await new ot().loadAsync(n, e);
|
|
6698
6705
|
if (u && u.animations && u.animations[o]) {
|
|
6699
6706
|
let l = u.animations[o];
|
|
6700
6707
|
const c = {};
|
|
@@ -6748,8 +6755,8 @@ class it {
|
|
|
6748
6755
|
if (e * 1e3 - c > 0) {
|
|
6749
6756
|
const h = [];
|
|
6750
6757
|
for (let b = 1; b < a.ts.length; b++) h.push(a.ts[b] - a.ts[b - 1]);
|
|
6751
|
-
const d = i.template?.rescale || h.map((b) => b / c),
|
|
6752
|
-
a.ts = a.ts.map((b,
|
|
6758
|
+
const d = i.template?.rescale || h.map((b) => b / c), p = e * 1e3 - c;
|
|
6759
|
+
a.ts = a.ts.map((b, f, L) => f === 0 ? u : L[f - 1] + h[f - 1] + d[f - 1] * p);
|
|
6753
6760
|
} else {
|
|
6754
6761
|
const h = e * 1e3 / c;
|
|
6755
6762
|
a.ts = a.ts.map((d) => u + h * (d - u));
|
|
@@ -6784,32 +6791,32 @@ class it {
|
|
|
6784
6791
|
ikSolve(n, e = null, t = !1, o = null) {
|
|
6785
6792
|
const s = new A.Vector3(), i = new A.Vector3(), a = new A.Vector3(), u = new A.Vector3(), l = new A.Quaternion(), c = new A.Vector3(), r = new A.Vector3(), h = new A.Vector3(), d = this.ikMesh.getObjectByName(n.root);
|
|
6786
6793
|
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);
|
|
6787
|
-
const
|
|
6788
|
-
b.forEach((
|
|
6789
|
-
|
|
6794
|
+
const p = this.ikMesh.getObjectByName(n.effector), b = n.links;
|
|
6795
|
+
b.forEach((L) => {
|
|
6796
|
+
L.bone = this.ikMesh.getObjectByName(L.link), L.bone.quaternion.copy(this.getPoseTemplateProp(L.link + ".quaternion"));
|
|
6790
6797
|
}), d.updateMatrixWorld(!0);
|
|
6791
|
-
const
|
|
6798
|
+
const f = n.iterations || 10;
|
|
6792
6799
|
if (e)
|
|
6793
|
-
for (let
|
|
6794
|
-
let
|
|
6795
|
-
for (let
|
|
6796
|
-
const
|
|
6797
|
-
|
|
6798
|
-
let
|
|
6799
|
-
|
|
6800
|
-
b[
|
|
6801
|
-
b[
|
|
6802
|
-
b[
|
|
6800
|
+
for (let L = 0; L < f; L++) {
|
|
6801
|
+
let Q = !1;
|
|
6802
|
+
for (let g = 0, H = b.length; g < H; g++) {
|
|
6803
|
+
const M = b[g].bone;
|
|
6804
|
+
M.matrixWorld.decompose(u, l, c), l.invert(), i.setFromMatrixPosition(p.matrixWorld), a.subVectors(i, u), a.applyQuaternion(l), a.normalize(), s.subVectors(e, u), s.applyQuaternion(l), s.normalize();
|
|
6805
|
+
let y = s.dot(a);
|
|
6806
|
+
y > 1 ? y = 1 : y < -1 && (y = -1), y = Math.acos(y), !(y < 1e-5) && (b[g].minAngle !== void 0 && y < b[g].minAngle && (y = b[g].minAngle), b[g].maxAngle !== void 0 && y > b[g].maxAngle && (y = b[g].maxAngle), r.crossVectors(a, s), r.normalize(), he.setFromAxisAngle(r, y), M.quaternion.multiply(he), M.rotation.setFromVector3(h.setFromEuler(M.rotation).clamp(new A.Vector3(
|
|
6807
|
+
b[g].minx !== void 0 ? b[g].minx : -1 / 0,
|
|
6808
|
+
b[g].miny !== void 0 ? b[g].miny : -1 / 0,
|
|
6809
|
+
b[g].minz !== void 0 ? b[g].minz : -1 / 0
|
|
6803
6810
|
), new A.Vector3(
|
|
6804
|
-
b[
|
|
6805
|
-
b[
|
|
6806
|
-
b[
|
|
6807
|
-
))),
|
|
6811
|
+
b[g].maxx !== void 0 ? b[g].maxx : 1 / 0,
|
|
6812
|
+
b[g].maxy !== void 0 ? b[g].maxy : 1 / 0,
|
|
6813
|
+
b[g].maxz !== void 0 ? b[g].maxz : 1 / 0
|
|
6814
|
+
))), M.updateMatrixWorld(!0), Q = !0);
|
|
6808
6815
|
}
|
|
6809
|
-
if (!
|
|
6816
|
+
if (!Q) break;
|
|
6810
6817
|
}
|
|
6811
|
-
o && b.forEach((
|
|
6812
|
-
this.poseTarget.props[
|
|
6818
|
+
o && b.forEach((L) => {
|
|
6819
|
+
this.poseTarget.props[L.link + ".quaternion"].copy(L.bone.quaternion), this.poseTarget.props[L.link + ".quaternion"].t = this.animClock, this.poseTarget.props[L.link + ".quaternion"].d = o;
|
|
6813
6820
|
});
|
|
6814
6821
|
}
|
|
6815
6822
|
/**
|
|
@@ -6819,7 +6826,7 @@ class it {
|
|
|
6819
6826
|
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();
|
|
6820
6827
|
}
|
|
6821
6828
|
}
|
|
6822
|
-
const
|
|
6829
|
+
const Ve = {
|
|
6823
6830
|
apiKey: "sk_ace57ef3ef65a92b9d3bee2a00183b78ca790bc3e10964f2",
|
|
6824
6831
|
// Replace with your actual API key (should start with sk_)
|
|
6825
6832
|
endpoint: "https://api.elevenlabs.io/v1/text-to-speech",
|
|
@@ -6862,23 +6869,23 @@ const Ge = {
|
|
|
6862
6869
|
function Je() {
|
|
6863
6870
|
return {
|
|
6864
6871
|
service: "elevenlabs",
|
|
6865
|
-
endpoint:
|
|
6866
|
-
apiKey:
|
|
6867
|
-
defaultVoice:
|
|
6868
|
-
voices:
|
|
6872
|
+
endpoint: Ve.endpoint,
|
|
6873
|
+
apiKey: Ve.apiKey,
|
|
6874
|
+
defaultVoice: Ve.defaultVoice,
|
|
6875
|
+
voices: Ve.voices
|
|
6869
6876
|
};
|
|
6870
6877
|
}
|
|
6871
|
-
function
|
|
6872
|
-
const
|
|
6873
|
-
return Object.entries(
|
|
6878
|
+
function $t() {
|
|
6879
|
+
const Y = Je(), n = [];
|
|
6880
|
+
return Object.entries(Y.voices).forEach(([e, t]) => {
|
|
6874
6881
|
n.push({
|
|
6875
6882
|
value: t,
|
|
6876
|
-
label: `${e.charAt(0).toUpperCase() + e.slice(1)} (${
|
|
6883
|
+
label: `${e.charAt(0).toUpperCase() + e.slice(1)} (${Y.service})`
|
|
6877
6884
|
});
|
|
6878
6885
|
}), n;
|
|
6879
6886
|
}
|
|
6880
|
-
const
|
|
6881
|
-
avatarUrl:
|
|
6887
|
+
const ct = Ke(({
|
|
6888
|
+
avatarUrl: Y = "/avatars/brunette.glb",
|
|
6882
6889
|
avatarBody: n = "F",
|
|
6883
6890
|
mood: e = "neutral",
|
|
6884
6891
|
ttsLang: t = "en",
|
|
@@ -6895,320 +6902,320 @@ const ut = Ke(({
|
|
|
6895
6902
|
},
|
|
6896
6903
|
onError: d = () => {
|
|
6897
6904
|
},
|
|
6898
|
-
className:
|
|
6905
|
+
className: p = "",
|
|
6899
6906
|
style: b = {},
|
|
6900
|
-
animations:
|
|
6901
|
-
},
|
|
6902
|
-
const
|
|
6903
|
-
|
|
6904
|
-
|
|
6905
|
-
}, [
|
|
6906
|
-
|
|
6907
|
+
animations: f = {}
|
|
6908
|
+
}, L) => {
|
|
6909
|
+
const Q = V(null), g = V(null), H = V(l), M = V(null), y = V(null), E = V(!1), S = V({ remainingText: null, originalText: null, options: null }), C = V([]), x = V(0), [I, G] = ge(!0), [P, D] = ge(null), [K, fe] = ge(!1), [xe, Te] = ge(!1);
|
|
6910
|
+
ze(() => {
|
|
6911
|
+
E.current = xe;
|
|
6912
|
+
}, [xe]), ze(() => {
|
|
6913
|
+
H.current = l;
|
|
6907
6914
|
}, [l]);
|
|
6908
|
-
const
|
|
6909
|
-
let
|
|
6910
|
-
|
|
6915
|
+
const Le = Je(), Me = o || Le.service;
|
|
6916
|
+
let ae;
|
|
6917
|
+
Me === "browser" ? ae = {
|
|
6911
6918
|
service: "browser",
|
|
6912
6919
|
endpoint: "",
|
|
6913
6920
|
apiKey: null,
|
|
6914
6921
|
defaultVoice: "Google US English"
|
|
6915
|
-
} :
|
|
6922
|
+
} : Me === "elevenlabs" ? ae = {
|
|
6916
6923
|
service: "elevenlabs",
|
|
6917
6924
|
endpoint: "https://api.elevenlabs.io/v1/text-to-speech",
|
|
6918
|
-
apiKey: i ||
|
|
6919
|
-
defaultVoice: s ||
|
|
6920
|
-
voices:
|
|
6921
|
-
} :
|
|
6925
|
+
apiKey: i || Le.apiKey,
|
|
6926
|
+
defaultVoice: s || Le.defaultVoice || Ve.defaultVoice,
|
|
6927
|
+
voices: Le.voices || Ve.voices
|
|
6928
|
+
} : Me === "deepgram" ? ae = {
|
|
6922
6929
|
service: "deepgram",
|
|
6923
6930
|
endpoint: "https://api.deepgram.com/v1/speak",
|
|
6924
|
-
apiKey: i ||
|
|
6925
|
-
defaultVoice: s ||
|
|
6926
|
-
voices:
|
|
6927
|
-
} :
|
|
6928
|
-
...
|
|
6931
|
+
apiKey: i || Le.apiKey,
|
|
6932
|
+
defaultVoice: s || Le.defaultVoice || _e.defaultVoice,
|
|
6933
|
+
voices: Le.voices || _e.voices
|
|
6934
|
+
} : ae = {
|
|
6935
|
+
...Le,
|
|
6929
6936
|
// Override API key if provided via props
|
|
6930
|
-
apiKey: i !== null ? i :
|
|
6937
|
+
apiKey: i !== null ? i : Le.apiKey
|
|
6931
6938
|
};
|
|
6932
6939
|
const R = {
|
|
6933
|
-
url:
|
|
6940
|
+
url: Y,
|
|
6934
6941
|
body: n,
|
|
6935
6942
|
avatarMood: e,
|
|
6936
|
-
ttsLang:
|
|
6937
|
-
ttsVoice: s ||
|
|
6943
|
+
ttsLang: Me === "browser" ? "en-US" : t,
|
|
6944
|
+
ttsVoice: s || ae.defaultVoice,
|
|
6938
6945
|
lipsyncLang: "en",
|
|
6939
6946
|
showFullAvatar: l,
|
|
6940
6947
|
bodyMovement: a,
|
|
6941
6948
|
movementIntensity: u
|
|
6942
6949
|
}, v = {
|
|
6943
|
-
ttsEndpoint:
|
|
6944
|
-
ttsApikey:
|
|
6945
|
-
ttsService:
|
|
6950
|
+
ttsEndpoint: ae.endpoint,
|
|
6951
|
+
ttsApikey: ae.apiKey,
|
|
6952
|
+
ttsService: Me,
|
|
6946
6953
|
lipsyncModules: ["en"],
|
|
6947
6954
|
cameraView: c
|
|
6948
|
-
},
|
|
6949
|
-
if (!(!
|
|
6955
|
+
}, N = W(async () => {
|
|
6956
|
+
if (!(!Q.current || g.current))
|
|
6950
6957
|
try {
|
|
6951
|
-
if (
|
|
6952
|
-
if (
|
|
6953
|
-
const
|
|
6954
|
-
h(
|
|
6958
|
+
if (G(!0), D(null), g.current = new it(Q.current, v), g.current.controls && (g.current.controls.enableRotate = !1, g.current.controls.enableZoom = !1, g.current.controls.enablePan = !1, g.current.controls.enableDamping = !1), f && Object.keys(f).length > 0 && (g.current.customAnimations = f), await g.current.showAvatar(R, (te) => {
|
|
6959
|
+
if (te.lengthComputable) {
|
|
6960
|
+
const ue = Math.min(100, Math.round(te.loaded / te.total * 100));
|
|
6961
|
+
h(ue);
|
|
6955
6962
|
}
|
|
6956
|
-
}), await new Promise((
|
|
6957
|
-
const
|
|
6958
|
-
|
|
6963
|
+
}), await new Promise((te) => {
|
|
6964
|
+
const ue = () => {
|
|
6965
|
+
g.current.lipsync && Object.keys(g.current.lipsync).length > 0 ? te() : setTimeout(ue, 100);
|
|
6959
6966
|
};
|
|
6960
|
-
|
|
6961
|
-
}),
|
|
6967
|
+
ue();
|
|
6968
|
+
}), g.current && g.current.setShowFullAvatar)
|
|
6962
6969
|
try {
|
|
6963
|
-
|
|
6964
|
-
} catch (
|
|
6965
|
-
console.warn("Error setting full body mode on initialization:",
|
|
6970
|
+
g.current.setShowFullAvatar(l);
|
|
6971
|
+
} catch (te) {
|
|
6972
|
+
console.warn("Error setting full body mode on initialization:", te);
|
|
6966
6973
|
}
|
|
6967
|
-
|
|
6974
|
+
g.current && g.current.controls && (g.current.controls.enableRotate = !1, g.current.controls.enableZoom = !1, g.current.controls.enablePan = !1, g.current.controls.enableDamping = !1, g.current.controls.update()), G(!1), fe(!0), r(g.current);
|
|
6968
6975
|
const _ = () => {
|
|
6969
|
-
document.visibilityState === "visible" ?
|
|
6976
|
+
document.visibilityState === "visible" ? g.current?.start() : g.current?.stop();
|
|
6970
6977
|
};
|
|
6971
6978
|
return document.addEventListener("visibilitychange", _), () => {
|
|
6972
6979
|
document.removeEventListener("visibilitychange", _);
|
|
6973
6980
|
};
|
|
6974
|
-
} catch (
|
|
6975
|
-
console.error("Error initializing TalkingHead:",
|
|
6981
|
+
} catch (w) {
|
|
6982
|
+
console.error("Error initializing TalkingHead:", w), D(w.message || "Failed to initialize avatar"), G(!1), d(w);
|
|
6976
6983
|
}
|
|
6977
|
-
}, [
|
|
6978
|
-
|
|
6979
|
-
|
|
6980
|
-
}), [
|
|
6981
|
-
if (!
|
|
6982
|
-
const
|
|
6983
|
-
for (const
|
|
6984
|
-
|
|
6984
|
+
}, [Y, n, e, t, o, s, i, l, a, u, c]);
|
|
6985
|
+
ze(() => (N(), () => {
|
|
6986
|
+
g.current && (g.current.stop(), g.current.dispose(), g.current = null);
|
|
6987
|
+
}), [N]), ze(() => {
|
|
6988
|
+
if (!Q.current || !g.current) return;
|
|
6989
|
+
const w = new ResizeObserver((te) => {
|
|
6990
|
+
for (const ue of te)
|
|
6991
|
+
g.current && g.current.onResize && g.current.onResize();
|
|
6985
6992
|
});
|
|
6986
|
-
|
|
6993
|
+
w.observe(Q.current);
|
|
6987
6994
|
const _ = () => {
|
|
6988
|
-
|
|
6995
|
+
g.current && g.current.onResize && g.current.onResize();
|
|
6989
6996
|
};
|
|
6990
6997
|
return window.addEventListener("resize", _), () => {
|
|
6991
|
-
|
|
6998
|
+
w.disconnect(), window.removeEventListener("resize", _);
|
|
6992
6999
|
};
|
|
6993
|
-
}, [
|
|
6994
|
-
const
|
|
6995
|
-
if (
|
|
7000
|
+
}, [K]);
|
|
7001
|
+
const B = W(async () => {
|
|
7002
|
+
if (g.current && g.current.audioCtx)
|
|
6996
7003
|
try {
|
|
6997
|
-
(
|
|
6998
|
-
} catch (
|
|
6999
|
-
console.warn("Failed to resume audio context:",
|
|
7004
|
+
(g.current.audioCtx.state === "suspended" || g.current.audioCtx.state === "interrupted") && (await g.current.audioCtx.resume(), console.log("Audio context resumed"));
|
|
7005
|
+
} catch (w) {
|
|
7006
|
+
console.warn("Failed to resume audio context:", w);
|
|
7000
7007
|
}
|
|
7001
|
-
}, []),
|
|
7002
|
-
if (
|
|
7008
|
+
}, []), j = W(async (w, _ = {}) => {
|
|
7009
|
+
if (g.current && K)
|
|
7003
7010
|
try {
|
|
7004
|
-
|
|
7005
|
-
const
|
|
7006
|
-
|
|
7007
|
-
const
|
|
7011
|
+
y.current && (clearInterval(y.current), y.current = null), M.current = { text: w, options: _ }, S.current = { remainingText: null, originalText: null, options: null };
|
|
7012
|
+
const te = /[!\.\?\n\p{Extended_Pictographic}]/ug, ue = w.split(te).map((ne) => ne.trim()).filter((ne) => ne.length > 0);
|
|
7013
|
+
C.current = ue, x.current = 0, Te(!1), E.current = !1, await B();
|
|
7014
|
+
const de = {
|
|
7008
7015
|
..._,
|
|
7009
7016
|
lipsyncLang: _.lipsyncLang || R.lipsyncLang || "en"
|
|
7010
7017
|
};
|
|
7011
|
-
if (_.onSpeechEnd &&
|
|
7012
|
-
const
|
|
7013
|
-
let
|
|
7014
|
-
const
|
|
7015
|
-
let
|
|
7016
|
-
|
|
7017
|
-
if (
|
|
7018
|
+
if (_.onSpeechEnd && g.current) {
|
|
7019
|
+
const ne = g.current;
|
|
7020
|
+
let me = null, Xe = 0;
|
|
7021
|
+
const Oe = 1200;
|
|
7022
|
+
let Fe = !1;
|
|
7023
|
+
me = setInterval(() => {
|
|
7024
|
+
if (Xe++, E.current)
|
|
7018
7025
|
return;
|
|
7019
|
-
if (
|
|
7020
|
-
if (
|
|
7021
|
-
|
|
7026
|
+
if (Xe > Oe) {
|
|
7027
|
+
if (me && (clearInterval(me), me = null, y.current = null), !Fe && !E.current) {
|
|
7028
|
+
Fe = !0;
|
|
7022
7029
|
try {
|
|
7023
7030
|
_.onSpeechEnd();
|
|
7024
|
-
} catch (
|
|
7025
|
-
console.error("Error in onSpeechEnd callback (timeout):",
|
|
7031
|
+
} catch (Ge) {
|
|
7032
|
+
console.error("Error in onSpeechEnd callback (timeout):", Ge);
|
|
7026
7033
|
}
|
|
7027
7034
|
}
|
|
7028
7035
|
return;
|
|
7029
7036
|
}
|
|
7030
|
-
const
|
|
7031
|
-
|
|
7032
|
-
if (
|
|
7033
|
-
|
|
7037
|
+
const Re = !ne.speechQueue || ne.speechQueue.length === 0, Ue = !ne.audioPlaylist || ne.audioPlaylist.length === 0;
|
|
7038
|
+
ne && ne.isSpeaking === !1 && Re && Ue && ne.isAudioPlaying === !1 && !Fe && !E.current && setTimeout(() => {
|
|
7039
|
+
if (ne && !E.current && ne.isSpeaking === !1 && (!ne.speechQueue || ne.speechQueue.length === 0) && (!ne.audioPlaylist || ne.audioPlaylist.length === 0) && ne.isAudioPlaying === !1 && !Fe && !E.current) {
|
|
7040
|
+
Fe = !0, me && (clearInterval(me), me = null, y.current = null);
|
|
7034
7041
|
try {
|
|
7035
7042
|
_.onSpeechEnd();
|
|
7036
|
-
} catch (
|
|
7037
|
-
console.error("Error in onSpeechEnd callback:",
|
|
7043
|
+
} catch (we) {
|
|
7044
|
+
console.error("Error in onSpeechEnd callback:", we);
|
|
7038
7045
|
}
|
|
7039
7046
|
}
|
|
7040
7047
|
}, 100);
|
|
7041
|
-
}, 100),
|
|
7048
|
+
}, 100), y.current = me;
|
|
7042
7049
|
}
|
|
7043
|
-
|
|
7044
|
-
await
|
|
7050
|
+
g.current.lipsync && Object.keys(g.current.lipsync).length > 0 ? (g.current.setSlowdownRate && g.current.setSlowdownRate(1.05), g.current.speakText(w, de)) : setTimeout(async () => {
|
|
7051
|
+
await B(), g.current && g.current.lipsync && (g.current.setSlowdownRate && g.current.setSlowdownRate(1.05), g.current.speakText(w, de));
|
|
7045
7052
|
}, 100);
|
|
7046
|
-
} catch (
|
|
7047
|
-
console.error("Error speaking text:",
|
|
7053
|
+
} catch (te) {
|
|
7054
|
+
console.error("Error speaking text:", te), D(te.message || "Failed to speak text");
|
|
7048
7055
|
}
|
|
7049
|
-
}, [
|
|
7050
|
-
|
|
7051
|
-
}, []),
|
|
7052
|
-
if (
|
|
7053
|
-
const
|
|
7054
|
-
if (
|
|
7055
|
-
|
|
7056
|
-
let
|
|
7057
|
-
if (
|
|
7058
|
-
const
|
|
7059
|
-
if (
|
|
7060
|
-
const
|
|
7061
|
-
|
|
7056
|
+
}, [K, B, R.lipsyncLang]), oe = W(() => {
|
|
7057
|
+
g.current && (g.current.stopSpeaking(), g.current.setSlowdownRate && g.current.setSlowdownRate(1), M.current = null, Te(!1));
|
|
7058
|
+
}, []), X = W(() => {
|
|
7059
|
+
if (g.current && g.current.pauseSpeaking) {
|
|
7060
|
+
const w = g.current;
|
|
7061
|
+
if (w.isSpeaking || w.audioPlaylist && w.audioPlaylist.length > 0 || w.speechQueue && w.speechQueue.length > 0) {
|
|
7062
|
+
y.current && (clearInterval(y.current), y.current = null);
|
|
7063
|
+
let te = "";
|
|
7064
|
+
if (M.current && C.current.length > 0) {
|
|
7065
|
+
const ue = C.current.length, de = w.speechQueue ? w.speechQueue.filter((Oe) => Oe && Oe.text && Array.isArray(Oe.text) && Oe.text.length > 0).length : 0, ne = w.audioPlaylist && w.audioPlaylist.length > 0, me = de + (ne ? 1 : 0), Xe = ue - me;
|
|
7066
|
+
if (me > 0 && Xe < ue && (te = C.current.slice(Xe).join(". ").trim(), !te && de > 0 && w.speechQueue)) {
|
|
7067
|
+
const Fe = w.speechQueue.filter((Re) => Re && Re.text && Array.isArray(Re.text) && Re.text.length > 0).map((Re) => Re.text.map((Ue) => Ue.word || "").filter((Ue) => Ue.length > 0).join(" ")).filter((Re) => Re.length > 0).join(" ");
|
|
7068
|
+
Fe && Fe.trim() && (te = Fe.trim());
|
|
7062
7069
|
}
|
|
7063
7070
|
}
|
|
7064
|
-
|
|
7065
|
-
remainingText:
|
|
7066
|
-
originalText:
|
|
7067
|
-
options:
|
|
7068
|
-
}),
|
|
7071
|
+
M.current && (S.current = {
|
|
7072
|
+
remainingText: te || null,
|
|
7073
|
+
originalText: M.current.text,
|
|
7074
|
+
options: M.current.options
|
|
7075
|
+
}), w.speechQueue && (w.speechQueue.length = 0), g.current.pauseSpeaking(), E.current = !0, Te(!0);
|
|
7069
7076
|
}
|
|
7070
7077
|
}
|
|
7071
|
-
}, []),
|
|
7072
|
-
if (!
|
|
7078
|
+
}, []), q = W(async () => {
|
|
7079
|
+
if (!g.current || !xe)
|
|
7073
7080
|
return;
|
|
7074
|
-
let
|
|
7075
|
-
if (
|
|
7076
|
-
|
|
7077
|
-
else if (
|
|
7078
|
-
|
|
7081
|
+
let w = "", _ = {};
|
|
7082
|
+
if (S.current && S.current.remainingText)
|
|
7083
|
+
w = S.current.remainingText, _ = S.current.options || {}, S.current = { remainingText: null, originalText: null, options: null };
|
|
7084
|
+
else if (M.current && M.current.text)
|
|
7085
|
+
w = M.current.text, _ = M.current.options || {};
|
|
7079
7086
|
else {
|
|
7080
|
-
console.warn("Resume called but no paused speech found"),
|
|
7087
|
+
console.warn("Resume called but no paused speech found"), Te(!1), E.current = !1;
|
|
7081
7088
|
return;
|
|
7082
7089
|
}
|
|
7083
|
-
|
|
7084
|
-
const
|
|
7090
|
+
Te(!1), E.current = !1, await B();
|
|
7091
|
+
const te = {
|
|
7085
7092
|
..._,
|
|
7086
7093
|
lipsyncLang: _.lipsyncLang || R.lipsyncLang || "en"
|
|
7087
7094
|
};
|
|
7088
7095
|
try {
|
|
7089
|
-
await
|
|
7090
|
-
} catch (
|
|
7091
|
-
console.error("Error resuming speech:",
|
|
7096
|
+
await j(w, te);
|
|
7097
|
+
} catch (ue) {
|
|
7098
|
+
console.error("Error resuming speech:", ue), Te(!1), E.current = !1;
|
|
7092
7099
|
}
|
|
7093
|
-
}, [
|
|
7094
|
-
|
|
7095
|
-
}, []),
|
|
7096
|
-
|
|
7097
|
-
}, []),
|
|
7098
|
-
if (
|
|
7099
|
-
if (
|
|
7100
|
+
}, [B, xe, j, R]), Se = W((w) => {
|
|
7101
|
+
g.current && g.current.setMood(w);
|
|
7102
|
+
}, []), be = W((w) => {
|
|
7103
|
+
g.current && g.current.setSlowdownRate && g.current.setSlowdownRate(w);
|
|
7104
|
+
}, []), Ae = W((w, _ = !1) => {
|
|
7105
|
+
if (g.current && g.current.playAnimation) {
|
|
7106
|
+
if (f && f[w] && (w = f[w]), g.current.setShowFullAvatar)
|
|
7100
7107
|
try {
|
|
7101
|
-
|
|
7102
|
-
} catch (
|
|
7103
|
-
console.warn("Error setting full body mode:",
|
|
7108
|
+
g.current.setShowFullAvatar(H.current);
|
|
7109
|
+
} catch (ue) {
|
|
7110
|
+
console.warn("Error setting full body mode:", ue);
|
|
7104
7111
|
}
|
|
7105
|
-
if (
|
|
7112
|
+
if (w.includes("."))
|
|
7106
7113
|
try {
|
|
7107
|
-
|
|
7108
|
-
} catch (
|
|
7109
|
-
console.warn(`Failed to play ${
|
|
7114
|
+
g.current.playAnimation(w, null, 10, 0, 0.01, _);
|
|
7115
|
+
} catch (ue) {
|
|
7116
|
+
console.warn(`Failed to play ${w}:`, ue);
|
|
7110
7117
|
try {
|
|
7111
|
-
|
|
7112
|
-
} catch (
|
|
7113
|
-
console.warn("Fallback animation also failed:",
|
|
7118
|
+
g.current.setBodyMovement("idle");
|
|
7119
|
+
} catch (de) {
|
|
7120
|
+
console.warn("Fallback animation also failed:", de);
|
|
7114
7121
|
}
|
|
7115
7122
|
}
|
|
7116
7123
|
else {
|
|
7117
|
-
const
|
|
7118
|
-
let
|
|
7119
|
-
for (const
|
|
7124
|
+
const ue = [".fbx", ".glb", ".gltf"];
|
|
7125
|
+
let de = !1;
|
|
7126
|
+
for (const ne of ue)
|
|
7120
7127
|
try {
|
|
7121
|
-
|
|
7128
|
+
g.current.playAnimation(w + ne, null, 10, 0, 0.01, _), de = !0;
|
|
7122
7129
|
break;
|
|
7123
7130
|
} catch {
|
|
7124
7131
|
}
|
|
7125
|
-
if (!
|
|
7126
|
-
console.warn("Animation not found:",
|
|
7132
|
+
if (!de) {
|
|
7133
|
+
console.warn("Animation not found:", w);
|
|
7127
7134
|
try {
|
|
7128
|
-
|
|
7129
|
-
} catch (
|
|
7130
|
-
console.warn("Fallback animation also failed:",
|
|
7135
|
+
g.current.setBodyMovement("idle");
|
|
7136
|
+
} catch (ne) {
|
|
7137
|
+
console.warn("Fallback animation also failed:", ne);
|
|
7131
7138
|
}
|
|
7132
7139
|
}
|
|
7133
7140
|
}
|
|
7134
7141
|
}
|
|
7135
|
-
}, [
|
|
7136
|
-
|
|
7142
|
+
}, [f]), et = W(() => {
|
|
7143
|
+
g.current && g.current.onResize && g.current.onResize();
|
|
7137
7144
|
}, []);
|
|
7138
|
-
return $e(
|
|
7139
|
-
speakText:
|
|
7140
|
-
stopSpeaking:
|
|
7141
|
-
pauseSpeaking:
|
|
7142
|
-
resumeSpeaking:
|
|
7143
|
-
resumeAudioContext:
|
|
7144
|
-
setMood:
|
|
7145
|
-
setTimingAdjustment:
|
|
7146
|
-
playAnimation:
|
|
7147
|
-
isReady:
|
|
7148
|
-
isPaused:
|
|
7149
|
-
talkingHead:
|
|
7150
|
-
handleResize:
|
|
7151
|
-
setBodyMovement: (
|
|
7152
|
-
if (
|
|
7145
|
+
return $e(L, () => ({
|
|
7146
|
+
speakText: j,
|
|
7147
|
+
stopSpeaking: oe,
|
|
7148
|
+
pauseSpeaking: X,
|
|
7149
|
+
resumeSpeaking: q,
|
|
7150
|
+
resumeAudioContext: B,
|
|
7151
|
+
setMood: Se,
|
|
7152
|
+
setTimingAdjustment: be,
|
|
7153
|
+
playAnimation: Ae,
|
|
7154
|
+
isReady: K,
|
|
7155
|
+
isPaused: xe,
|
|
7156
|
+
talkingHead: g.current,
|
|
7157
|
+
handleResize: et,
|
|
7158
|
+
setBodyMovement: (w) => {
|
|
7159
|
+
if (g.current && g.current.setShowFullAvatar && g.current.setBodyMovement)
|
|
7153
7160
|
try {
|
|
7154
|
-
|
|
7161
|
+
g.current.setShowFullAvatar(H.current), g.current.setBodyMovement(w);
|
|
7155
7162
|
} catch (_) {
|
|
7156
7163
|
console.warn("Error setting body movement:", _);
|
|
7157
7164
|
}
|
|
7158
7165
|
},
|
|
7159
|
-
setMovementIntensity: (
|
|
7166
|
+
setMovementIntensity: (w) => g.current?.setMovementIntensity(w),
|
|
7160
7167
|
playRandomDance: () => {
|
|
7161
|
-
if (
|
|
7168
|
+
if (g.current && g.current.setShowFullAvatar && g.current.playRandomDance)
|
|
7162
7169
|
try {
|
|
7163
|
-
|
|
7164
|
-
} catch (
|
|
7165
|
-
console.warn("Error playing random dance:",
|
|
7170
|
+
g.current.setShowFullAvatar(H.current), g.current.playRandomDance();
|
|
7171
|
+
} catch (w) {
|
|
7172
|
+
console.warn("Error playing random dance:", w);
|
|
7166
7173
|
}
|
|
7167
7174
|
},
|
|
7168
|
-
playReaction: (
|
|
7169
|
-
if (
|
|
7175
|
+
playReaction: (w) => {
|
|
7176
|
+
if (g.current && g.current.setShowFullAvatar && g.current.playReaction)
|
|
7170
7177
|
try {
|
|
7171
|
-
|
|
7178
|
+
g.current.setShowFullAvatar(H.current), g.current.playReaction(w);
|
|
7172
7179
|
} catch (_) {
|
|
7173
7180
|
console.warn("Error playing reaction:", _);
|
|
7174
7181
|
}
|
|
7175
7182
|
},
|
|
7176
7183
|
playCelebration: () => {
|
|
7177
|
-
if (
|
|
7184
|
+
if (g.current && g.current.setShowFullAvatar && g.current.playCelebration)
|
|
7178
7185
|
try {
|
|
7179
|
-
|
|
7180
|
-
} catch (
|
|
7181
|
-
console.warn("Error playing celebration:",
|
|
7186
|
+
g.current.setShowFullAvatar(H.current), g.current.playCelebration();
|
|
7187
|
+
} catch (w) {
|
|
7188
|
+
console.warn("Error playing celebration:", w);
|
|
7182
7189
|
}
|
|
7183
7190
|
},
|
|
7184
|
-
setShowFullAvatar: (
|
|
7185
|
-
if (
|
|
7191
|
+
setShowFullAvatar: (w) => {
|
|
7192
|
+
if (g.current && g.current.setShowFullAvatar)
|
|
7186
7193
|
try {
|
|
7187
|
-
|
|
7194
|
+
H.current = w, g.current.setShowFullAvatar(w);
|
|
7188
7195
|
} catch (_) {
|
|
7189
7196
|
console.warn("Error setting showFullAvatar:", _);
|
|
7190
7197
|
}
|
|
7191
7198
|
},
|
|
7192
7199
|
lockAvatarPosition: () => {
|
|
7193
|
-
if (
|
|
7200
|
+
if (g.current && g.current.lockAvatarPosition)
|
|
7194
7201
|
try {
|
|
7195
|
-
|
|
7196
|
-
} catch (
|
|
7197
|
-
console.warn("Error locking avatar position:",
|
|
7202
|
+
g.current.lockAvatarPosition();
|
|
7203
|
+
} catch (w) {
|
|
7204
|
+
console.warn("Error locking avatar position:", w);
|
|
7198
7205
|
}
|
|
7199
7206
|
},
|
|
7200
7207
|
unlockAvatarPosition: () => {
|
|
7201
|
-
if (
|
|
7208
|
+
if (g.current && g.current.unlockAvatarPosition)
|
|
7202
7209
|
try {
|
|
7203
|
-
|
|
7204
|
-
} catch (
|
|
7205
|
-
console.warn("Error unlocking avatar position:",
|
|
7210
|
+
g.current.unlockAvatarPosition();
|
|
7211
|
+
} catch (w) {
|
|
7212
|
+
console.warn("Error unlocking avatar position:", w);
|
|
7206
7213
|
}
|
|
7207
7214
|
}
|
|
7208
|
-
})), /* @__PURE__ */
|
|
7215
|
+
})), /* @__PURE__ */ Ee(
|
|
7209
7216
|
"div",
|
|
7210
7217
|
{
|
|
7211
|
-
className: `talking-head-avatar ${
|
|
7218
|
+
className: `talking-head-avatar ${p}`,
|
|
7212
7219
|
style: {
|
|
7213
7220
|
width: "100%",
|
|
7214
7221
|
height: "100%",
|
|
@@ -7216,10 +7223,10 @@ const ut = Ke(({
|
|
|
7216
7223
|
...b
|
|
7217
7224
|
},
|
|
7218
7225
|
children: [
|
|
7219
|
-
/* @__PURE__ */
|
|
7226
|
+
/* @__PURE__ */ le(
|
|
7220
7227
|
"div",
|
|
7221
7228
|
{
|
|
7222
|
-
ref:
|
|
7229
|
+
ref: Q,
|
|
7223
7230
|
className: "talking-head-viewer",
|
|
7224
7231
|
style: {
|
|
7225
7232
|
width: "100%",
|
|
@@ -7228,7 +7235,7 @@ const ut = Ke(({
|
|
|
7228
7235
|
}
|
|
7229
7236
|
}
|
|
7230
7237
|
),
|
|
7231
|
-
I && /* @__PURE__ */
|
|
7238
|
+
I && /* @__PURE__ */ le("div", { className: "loading-overlay", style: {
|
|
7232
7239
|
position: "absolute",
|
|
7233
7240
|
top: "50%",
|
|
7234
7241
|
left: "50%",
|
|
@@ -7237,7 +7244,7 @@ const ut = Ke(({
|
|
|
7237
7244
|
fontSize: "18px",
|
|
7238
7245
|
zIndex: 10
|
|
7239
7246
|
}, children: "Loading avatar..." }),
|
|
7240
|
-
P && /* @__PURE__ */
|
|
7247
|
+
P && /* @__PURE__ */ le("div", { className: "error-overlay", style: {
|
|
7241
7248
|
position: "absolute",
|
|
7242
7249
|
top: "50%",
|
|
7243
7250
|
left: "50%",
|
|
@@ -7253,9 +7260,9 @@ const ut = Ke(({
|
|
|
7253
7260
|
}
|
|
7254
7261
|
);
|
|
7255
7262
|
});
|
|
7256
|
-
|
|
7257
|
-
const
|
|
7258
|
-
text:
|
|
7263
|
+
ct.displayName = "TalkingHeadAvatar";
|
|
7264
|
+
const Ut = Ke(({
|
|
7265
|
+
text: Y = "Hello! I'm a talking avatar. How are you today?",
|
|
7259
7266
|
onLoading: n = () => {
|
|
7260
7267
|
},
|
|
7261
7268
|
onError: e = () => {
|
|
@@ -7266,23 +7273,23 @@ const Nt = Ke(({
|
|
|
7266
7273
|
style: s = {},
|
|
7267
7274
|
avatarConfig: i = {}
|
|
7268
7275
|
}, a) => {
|
|
7269
|
-
const u = V(null), l = V(null), [c, r] =
|
|
7276
|
+
const u = V(null), l = V(null), [c, r] = ge(!0), [h, d] = ge(null), [p, b] = ge(!1), f = Je(), L = i.ttsService || f.service, Q = L === "browser" ? {
|
|
7270
7277
|
endpoint: "",
|
|
7271
7278
|
apiKey: null,
|
|
7272
7279
|
defaultVoice: "Google US English"
|
|
7273
7280
|
} : {
|
|
7274
|
-
...
|
|
7281
|
+
...f,
|
|
7275
7282
|
// Override API key if provided via avatarConfig
|
|
7276
|
-
apiKey: i.ttsApiKey !== void 0 && i.ttsApiKey !== null ? i.ttsApiKey :
|
|
7283
|
+
apiKey: i.ttsApiKey !== void 0 && i.ttsApiKey !== null ? i.ttsApiKey : f.apiKey,
|
|
7277
7284
|
// Override endpoint for ElevenLabs if service is explicitly set
|
|
7278
|
-
endpoint:
|
|
7279
|
-
},
|
|
7285
|
+
endpoint: L === "elevenlabs" && i.ttsApiKey ? "https://api.elevenlabs.io/v1/text-to-speech" : f.endpoint
|
|
7286
|
+
}, g = {
|
|
7280
7287
|
url: "/avatars/brunette.glb",
|
|
7281
7288
|
// Use brunette avatar (working glTF file)
|
|
7282
7289
|
body: "F",
|
|
7283
7290
|
avatarMood: "neutral",
|
|
7284
|
-
ttsLang:
|
|
7285
|
-
ttsVoice: i.ttsVoice ||
|
|
7291
|
+
ttsLang: L === "browser" ? "en-US" : "en",
|
|
7292
|
+
ttsVoice: i.ttsVoice || Q.defaultVoice,
|
|
7286
7293
|
lipsyncLang: "en",
|
|
7287
7294
|
// English lip-sync
|
|
7288
7295
|
showFullAvatar: !0,
|
|
@@ -7290,31 +7297,31 @@ const Nt = Ke(({
|
|
|
7290
7297
|
bodyMovement: "idle",
|
|
7291
7298
|
movementIntensity: 0.5,
|
|
7292
7299
|
...i
|
|
7293
|
-
},
|
|
7294
|
-
ttsEndpoint:
|
|
7295
|
-
ttsApikey:
|
|
7296
|
-
ttsService:
|
|
7300
|
+
}, H = {
|
|
7301
|
+
ttsEndpoint: Q.endpoint,
|
|
7302
|
+
ttsApikey: Q.apiKey,
|
|
7303
|
+
ttsService: L,
|
|
7297
7304
|
lipsyncModules: ["en"],
|
|
7298
7305
|
cameraView: "upper"
|
|
7299
|
-
},
|
|
7306
|
+
}, M = W(async () => {
|
|
7300
7307
|
if (!(!u.current || l.current))
|
|
7301
7308
|
try {
|
|
7302
|
-
if (r(!0), d(null), l.current = new it(u.current,
|
|
7309
|
+
if (r(!0), d(null), l.current = new it(u.current, H), await l.current.showAvatar(g, (P) => {
|
|
7303
7310
|
if (P.lengthComputable) {
|
|
7304
|
-
const
|
|
7305
|
-
n(
|
|
7311
|
+
const D = Math.min(100, Math.round(P.loaded / P.total * 100));
|
|
7312
|
+
n(D);
|
|
7306
7313
|
}
|
|
7307
7314
|
}), l.current.morphs && l.current.morphs.length > 0) {
|
|
7308
7315
|
const P = l.current.morphs[0].morphTargetDictionary;
|
|
7309
7316
|
console.log("Available morph targets:", Object.keys(P));
|
|
7310
|
-
const
|
|
7311
|
-
console.log("Viseme morph targets found:",
|
|
7317
|
+
const D = Object.keys(P).filter((K) => K.startsWith("viseme_"));
|
|
7318
|
+
console.log("Viseme morph targets found:", D), D.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"));
|
|
7312
7319
|
}
|
|
7313
7320
|
if (await new Promise((P) => {
|
|
7314
|
-
const
|
|
7315
|
-
l.current.lipsync && Object.keys(l.current.lipsync).length > 0 ? (console.log("Lip-sync modules loaded:", Object.keys(l.current.lipsync)), P()) : (console.log("Waiting for lip-sync modules to load..."), setTimeout(
|
|
7321
|
+
const D = () => {
|
|
7322
|
+
l.current.lipsync && Object.keys(l.current.lipsync).length > 0 ? (console.log("Lip-sync modules loaded:", Object.keys(l.current.lipsync)), P()) : (console.log("Waiting for lip-sync modules to load..."), setTimeout(D, 100));
|
|
7316
7323
|
};
|
|
7317
|
-
|
|
7324
|
+
D();
|
|
7318
7325
|
}), l.current && l.current.setShowFullAvatar)
|
|
7319
7326
|
try {
|
|
7320
7327
|
l.current.setShowFullAvatar(!0), console.log("Avatar initialized in full body mode");
|
|
@@ -7322,71 +7329,71 @@ const Nt = Ke(({
|
|
|
7322
7329
|
console.warn("Error setting full body mode on initialization:", P);
|
|
7323
7330
|
}
|
|
7324
7331
|
r(!1), b(!0), t(l.current);
|
|
7325
|
-
const
|
|
7332
|
+
const G = () => {
|
|
7326
7333
|
document.visibilityState === "visible" ? l.current?.start() : l.current?.stop();
|
|
7327
7334
|
};
|
|
7328
|
-
return document.addEventListener("visibilitychange",
|
|
7329
|
-
document.removeEventListener("visibilitychange",
|
|
7335
|
+
return document.addEventListener("visibilitychange", G), () => {
|
|
7336
|
+
document.removeEventListener("visibilitychange", G);
|
|
7330
7337
|
};
|
|
7331
7338
|
} catch (I) {
|
|
7332
7339
|
console.error("Error initializing TalkingHead:", I), d(I.message || "Failed to initialize avatar"), r(!1), e(I);
|
|
7333
7340
|
}
|
|
7334
7341
|
}, []);
|
|
7335
|
-
|
|
7342
|
+
ze(() => (M(), () => {
|
|
7336
7343
|
l.current && (l.current.stop(), l.current.dispose(), l.current = null);
|
|
7337
|
-
}), [
|
|
7338
|
-
const
|
|
7339
|
-
if (l.current &&
|
|
7344
|
+
}), [M]);
|
|
7345
|
+
const y = W((I) => {
|
|
7346
|
+
if (l.current && p)
|
|
7340
7347
|
try {
|
|
7341
|
-
console.log("Speaking text:", I), console.log("Avatar config:",
|
|
7348
|
+
console.log("Speaking text:", I), console.log("Avatar config:", g), 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(() => {
|
|
7342
7349
|
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");
|
|
7343
7350
|
}, 500));
|
|
7344
|
-
} catch (
|
|
7345
|
-
console.error("Error speaking text:",
|
|
7351
|
+
} catch (G) {
|
|
7352
|
+
console.error("Error speaking text:", G), d(G.message || "Failed to speak text");
|
|
7346
7353
|
}
|
|
7347
7354
|
else
|
|
7348
|
-
console.warn("Avatar not ready for speaking. isReady:",
|
|
7349
|
-
}, [
|
|
7355
|
+
console.warn("Avatar not ready for speaking. isReady:", p, "talkingHeadRef:", !!l.current);
|
|
7356
|
+
}, [p, g]), E = W(() => {
|
|
7350
7357
|
l.current && (l.current.stopSpeaking(), l.current.setSlowdownRate && (l.current.setSlowdownRate(1), console.log("Reset timing to normal")));
|
|
7351
|
-
}, []),
|
|
7358
|
+
}, []), S = W((I) => {
|
|
7352
7359
|
l.current && l.current.setMood(I);
|
|
7353
|
-
}, []),
|
|
7360
|
+
}, []), C = W((I) => {
|
|
7354
7361
|
l.current && l.current.setSlowdownRate && (l.current.setSlowdownRate(I), console.log("Timing adjustment set to:", I));
|
|
7355
|
-
}, []),
|
|
7362
|
+
}, []), x = W((I, G = !1) => {
|
|
7356
7363
|
if (l.current && l.current.playAnimation) {
|
|
7357
7364
|
if (l.current.setShowFullAvatar)
|
|
7358
7365
|
try {
|
|
7359
7366
|
l.current.setShowFullAvatar(!0);
|
|
7360
|
-
} catch (
|
|
7361
|
-
console.warn("Error setting full body mode:",
|
|
7367
|
+
} catch (D) {
|
|
7368
|
+
console.warn("Error setting full body mode:", D);
|
|
7362
7369
|
}
|
|
7363
7370
|
if (I.includes("."))
|
|
7364
7371
|
try {
|
|
7365
|
-
l.current.playAnimation(I, null, 10, 0, 0.01,
|
|
7366
|
-
} catch (
|
|
7367
|
-
console.log(`Failed to play ${I}:`,
|
|
7372
|
+
l.current.playAnimation(I, null, 10, 0, 0.01, G), console.log("Playing animation:", I);
|
|
7373
|
+
} catch (D) {
|
|
7374
|
+
console.log(`Failed to play ${I}:`, D);
|
|
7368
7375
|
try {
|
|
7369
7376
|
l.current.setBodyMovement("idle"), console.log("Fallback to idle animation");
|
|
7370
|
-
} catch (
|
|
7371
|
-
console.warn("Fallback animation also failed:",
|
|
7377
|
+
} catch (K) {
|
|
7378
|
+
console.warn("Fallback animation also failed:", K);
|
|
7372
7379
|
}
|
|
7373
7380
|
}
|
|
7374
7381
|
else {
|
|
7375
|
-
const
|
|
7376
|
-
let
|
|
7377
|
-
for (const
|
|
7382
|
+
const D = [".fbx", ".glb", ".gltf"];
|
|
7383
|
+
let K = !1;
|
|
7384
|
+
for (const fe of D)
|
|
7378
7385
|
try {
|
|
7379
|
-
l.current.playAnimation(I +
|
|
7386
|
+
l.current.playAnimation(I + fe, null, 10, 0, 0.01, G), console.log("Playing animation:", I + fe), K = !0;
|
|
7380
7387
|
break;
|
|
7381
7388
|
} catch {
|
|
7382
|
-
console.log(`Failed to play ${I}${
|
|
7389
|
+
console.log(`Failed to play ${I}${fe}, trying next format...`);
|
|
7383
7390
|
}
|
|
7384
|
-
if (
|
|
7391
|
+
if (!K) {
|
|
7385
7392
|
console.warn("Animation system not available or animation not found:", I);
|
|
7386
7393
|
try {
|
|
7387
7394
|
l.current.setBodyMovement("idle"), console.log("Fallback to idle animation");
|
|
7388
|
-
} catch (
|
|
7389
|
-
console.warn("Fallback animation also failed:",
|
|
7395
|
+
} catch (fe) {
|
|
7396
|
+
console.warn("Fallback animation also failed:", fe);
|
|
7390
7397
|
}
|
|
7391
7398
|
}
|
|
7392
7399
|
}
|
|
@@ -7394,19 +7401,19 @@ const Nt = Ke(({
|
|
|
7394
7401
|
console.warn("Animation system not available or animation not found:", I);
|
|
7395
7402
|
}, []);
|
|
7396
7403
|
return $e(a, () => ({
|
|
7397
|
-
speakText:
|
|
7398
|
-
stopSpeaking:
|
|
7399
|
-
setMood:
|
|
7400
|
-
setTimingAdjustment:
|
|
7401
|
-
playAnimation:
|
|
7402
|
-
isReady:
|
|
7404
|
+
speakText: y,
|
|
7405
|
+
stopSpeaking: E,
|
|
7406
|
+
setMood: S,
|
|
7407
|
+
setTimingAdjustment: C,
|
|
7408
|
+
playAnimation: x,
|
|
7409
|
+
isReady: p,
|
|
7403
7410
|
talkingHead: l.current,
|
|
7404
7411
|
setBodyMovement: (I) => {
|
|
7405
7412
|
if (l.current && l.current.setShowFullAvatar && l.current.setBodyMovement)
|
|
7406
7413
|
try {
|
|
7407
7414
|
l.current.setShowFullAvatar(!0), l.current.setBodyMovement(I), console.log("Body movement set with full body mode:", I);
|
|
7408
|
-
} catch (
|
|
7409
|
-
console.warn("Error setting body movement:",
|
|
7415
|
+
} catch (G) {
|
|
7416
|
+
console.warn("Error setting body movement:", G);
|
|
7410
7417
|
}
|
|
7411
7418
|
},
|
|
7412
7419
|
setMovementIntensity: (I) => l.current?.setMovementIntensity(I),
|
|
@@ -7422,8 +7429,8 @@ const Nt = Ke(({
|
|
|
7422
7429
|
if (l.current && l.current.setShowFullAvatar && l.current.playReaction)
|
|
7423
7430
|
try {
|
|
7424
7431
|
l.current.setShowFullAvatar(!0), l.current.playReaction(I), console.log("Reaction played with full body mode:", I);
|
|
7425
|
-
} catch (
|
|
7426
|
-
console.warn("Error playing reaction:",
|
|
7432
|
+
} catch (G) {
|
|
7433
|
+
console.warn("Error playing reaction:", G);
|
|
7427
7434
|
}
|
|
7428
7435
|
},
|
|
7429
7436
|
playCelebration: () => {
|
|
@@ -7438,8 +7445,8 @@ const Nt = Ke(({
|
|
|
7438
7445
|
if (l.current && l.current.setShowFullAvatar)
|
|
7439
7446
|
try {
|
|
7440
7447
|
l.current.setShowFullAvatar(I), console.log("Show full avatar set to:", I);
|
|
7441
|
-
} catch (
|
|
7442
|
-
console.warn("Error setting showFullAvatar:",
|
|
7448
|
+
} catch (G) {
|
|
7449
|
+
console.warn("Error setting showFullAvatar:", G);
|
|
7443
7450
|
}
|
|
7444
7451
|
},
|
|
7445
7452
|
lockAvatarPosition: () => {
|
|
@@ -7458,8 +7465,8 @@ const Nt = Ke(({
|
|
|
7458
7465
|
console.warn("Error unlocking avatar position:", I);
|
|
7459
7466
|
}
|
|
7460
7467
|
}
|
|
7461
|
-
})), /* @__PURE__ */
|
|
7462
|
-
/* @__PURE__ */
|
|
7468
|
+
})), /* @__PURE__ */ Ee("div", { className: `talking-head-container ${o}`, style: s, children: [
|
|
7469
|
+
/* @__PURE__ */ le(
|
|
7463
7470
|
"div",
|
|
7464
7471
|
{
|
|
7465
7472
|
ref: u,
|
|
@@ -7471,7 +7478,7 @@ const Nt = Ke(({
|
|
|
7471
7478
|
}
|
|
7472
7479
|
}
|
|
7473
7480
|
),
|
|
7474
|
-
c && /* @__PURE__ */
|
|
7481
|
+
c && /* @__PURE__ */ le("div", { className: "loading-overlay", style: {
|
|
7475
7482
|
position: "absolute",
|
|
7476
7483
|
top: "50%",
|
|
7477
7484
|
left: "50%",
|
|
@@ -7480,7 +7487,7 @@ const Nt = Ke(({
|
|
|
7480
7487
|
fontSize: "18px",
|
|
7481
7488
|
zIndex: 10
|
|
7482
7489
|
}, children: "Loading avatar..." }),
|
|
7483
|
-
h && /* @__PURE__ */
|
|
7490
|
+
h && /* @__PURE__ */ le("div", { className: "error-overlay", style: {
|
|
7484
7491
|
position: "absolute",
|
|
7485
7492
|
top: "50%",
|
|
7486
7493
|
left: "50%",
|
|
@@ -7494,10 +7501,10 @@ const Nt = Ke(({
|
|
|
7494
7501
|
}, children: h })
|
|
7495
7502
|
] });
|
|
7496
7503
|
});
|
|
7497
|
-
|
|
7498
|
-
async function je(
|
|
7504
|
+
Ut.displayName = "TalkingHeadComponent";
|
|
7505
|
+
async function je(Y) {
|
|
7499
7506
|
try {
|
|
7500
|
-
const n = await fetch(
|
|
7507
|
+
const n = await fetch(Y);
|
|
7501
7508
|
if (!n.ok) {
|
|
7502
7509
|
if (n.status === 404)
|
|
7503
7510
|
return {};
|
|
@@ -7509,11 +7516,11 @@ async function je(j) {
|
|
|
7509
7516
|
const t = await n.text();
|
|
7510
7517
|
return t.trim().startsWith("<!") ? {} : JSON.parse(t).animations || {};
|
|
7511
7518
|
} catch (n) {
|
|
7512
|
-
return n instanceof SyntaxError || console.warn("⚠️ Could not load animation manifest (this is optional):",
|
|
7519
|
+
return n instanceof SyntaxError || console.warn("⚠️ Could not load animation manifest (this is optional):", Y), {};
|
|
7513
7520
|
}
|
|
7514
7521
|
}
|
|
7515
|
-
async function
|
|
7516
|
-
const e = [], t =
|
|
7522
|
+
async function Wt(Y, n = "F") {
|
|
7523
|
+
const e = [], t = Y.replace(/\/$/, "");
|
|
7517
7524
|
try {
|
|
7518
7525
|
const i = [
|
|
7519
7526
|
`${t}/.list.json`,
|
|
@@ -7556,19 +7563,19 @@ async function Ut(j, n = "F") {
|
|
|
7556
7563
|
}
|
|
7557
7564
|
return e.length > 0, e;
|
|
7558
7565
|
}
|
|
7559
|
-
async function
|
|
7566
|
+
async function lt(Y, n = "F") {
|
|
7560
7567
|
const e = {};
|
|
7561
|
-
for (const [t, o] of Object.entries(
|
|
7568
|
+
for (const [t, o] of Object.entries(Y))
|
|
7562
7569
|
try {
|
|
7563
|
-
const s = await
|
|
7570
|
+
const s = await Wt(o, n);
|
|
7564
7571
|
s.length > 0 && (e[t] = s);
|
|
7565
7572
|
} catch (s) {
|
|
7566
7573
|
console.error(`❌ Failed to auto-load animations from ${o}:`, s);
|
|
7567
7574
|
}
|
|
7568
7575
|
return e;
|
|
7569
7576
|
}
|
|
7570
|
-
const
|
|
7571
|
-
text:
|
|
7577
|
+
const Vt = Ke(({
|
|
7578
|
+
text: Y = null,
|
|
7572
7579
|
avatarUrl: n = "/avatars/brunette.glb",
|
|
7573
7580
|
avatarBody: e = "F",
|
|
7574
7581
|
mood: t = "neutral",
|
|
@@ -7584,467 +7591,472 @@ const Wt = Ke(({
|
|
|
7584
7591
|
},
|
|
7585
7592
|
onLoading: d = () => {
|
|
7586
7593
|
},
|
|
7587
|
-
onError:
|
|
7594
|
+
onError: p = () => {
|
|
7588
7595
|
},
|
|
7589
7596
|
onSpeechStart: b = () => {
|
|
7590
7597
|
},
|
|
7591
|
-
onSpeechEnd:
|
|
7598
|
+
onSpeechEnd: f = () => {
|
|
7592
7599
|
},
|
|
7593
|
-
|
|
7594
|
-
|
|
7595
|
-
|
|
7596
|
-
|
|
7597
|
-
|
|
7598
|
-
|
|
7599
|
-
|
|
7600
|
-
|
|
7601
|
-
|
|
7602
|
-
|
|
7603
|
-
|
|
7604
|
-
|
|
7605
|
-
|
|
7606
|
-
|
|
7607
|
-
|
|
7608
|
-
|
|
7609
|
-
|
|
7610
|
-
|
|
7600
|
+
onSubtitle: L = null,
|
|
7601
|
+
className: Q = "",
|
|
7602
|
+
style: g = {},
|
|
7603
|
+
animations: H = {},
|
|
7604
|
+
autoAnimationGroup: M = null,
|
|
7605
|
+
// e.g., "talking" - will select from this group in order when speaking
|
|
7606
|
+
autoIdleGroup: y = null,
|
|
7607
|
+
// e.g., "idle" - will select from this group in order when idle
|
|
7608
|
+
autoSpeak: E = !1
|
|
7609
|
+
}, S) => {
|
|
7610
|
+
const C = V(null), x = V(null), I = V(c), G = V(null), P = V(null), D = V(!1), K = V({ remainingText: null, originalText: null, options: null }), fe = V([]), [xe, Te] = ge(!0), [Le, Me] = ge(null), [ae, R] = ge(!1), [v, N] = ge(!1), [B, j] = ge(H), oe = V(null), X = V(!1), q = V(null), Se = V(!1), be = V([]), Ae = V([]), et = V(0), w = V(null), _ = V(null), te = V("");
|
|
7611
|
+
ze(() => {
|
|
7612
|
+
D.current = v;
|
|
7613
|
+
}, [v]);
|
|
7614
|
+
const ue = W((k) => {
|
|
7615
|
+
let z = "F";
|
|
7616
|
+
if (k) {
|
|
7617
|
+
const F = k.toString().toUpperCase().trim();
|
|
7618
|
+
F === "M" || F === "MALE" ? z = "M" : (F === "F" || F === "FEMALE") && (z = "F");
|
|
7611
7619
|
}
|
|
7612
|
-
return
|
|
7620
|
+
return z === "M" ? "male" : "female";
|
|
7613
7621
|
}, []);
|
|
7614
|
-
|
|
7622
|
+
ze(() => {
|
|
7615
7623
|
(async () => {
|
|
7616
|
-
if (
|
|
7624
|
+
if (H.manifest && H.auto)
|
|
7617
7625
|
try {
|
|
7618
|
-
const
|
|
7619
|
-
|
|
7626
|
+
const z = await je(H.manifest);
|
|
7627
|
+
j(z);
|
|
7620
7628
|
return;
|
|
7621
7629
|
} catch {
|
|
7622
7630
|
}
|
|
7623
|
-
if (
|
|
7624
|
-
const
|
|
7625
|
-
|
|
7626
|
-
} else if (
|
|
7631
|
+
if (H.manifest && !H.auto) {
|
|
7632
|
+
const z = await je(H.manifest), F = Object.keys(z).length > 0;
|
|
7633
|
+
j(F ? z : H);
|
|
7634
|
+
} else if (H.auto)
|
|
7627
7635
|
try {
|
|
7628
|
-
let
|
|
7629
|
-
if (
|
|
7636
|
+
let z = null;
|
|
7637
|
+
if (H.manifest)
|
|
7630
7638
|
try {
|
|
7631
|
-
|
|
7639
|
+
z = await je(H.manifest);
|
|
7632
7640
|
} catch {
|
|
7633
7641
|
}
|
|
7634
|
-
if (typeof
|
|
7635
|
-
const
|
|
7636
|
-
talking: `${
|
|
7637
|
-
idle: `${
|
|
7638
|
-
},
|
|
7639
|
-
|
|
7640
|
-
const
|
|
7641
|
-
if (!Object.values(
|
|
7642
|
-
|
|
7642
|
+
if (typeof H.auto == "string") {
|
|
7643
|
+
const F = H.auto, se = {
|
|
7644
|
+
talking: `${F}/talking`,
|
|
7645
|
+
idle: `${F}/idle`
|
|
7646
|
+
}, Z = ue(e);
|
|
7647
|
+
se[`${Z}_talking`] = `${F}/${Z}/talking`, se[`${Z}_idle`] = `${F}/${Z}/idle`, se.shared_talking = `${F}/shared/talking`, se.shared_idle = `${F}/shared/idle`;
|
|
7648
|
+
const ke = await lt(se, e);
|
|
7649
|
+
if (!Object.values(ke).some(($) => Array.isArray($) && $.length > 0) && z) {
|
|
7650
|
+
j(z);
|
|
7643
7651
|
return;
|
|
7644
7652
|
}
|
|
7645
|
-
const
|
|
7653
|
+
const ee = {
|
|
7646
7654
|
_genderSpecific: {
|
|
7647
|
-
[
|
|
7655
|
+
[Z]: {},
|
|
7648
7656
|
shared: {}
|
|
7649
7657
|
}
|
|
7650
7658
|
};
|
|
7651
|
-
Object.entries(
|
|
7652
|
-
if (
|
|
7653
|
-
const [
|
|
7654
|
-
|
|
7659
|
+
Object.entries(ke).forEach(([$, ie]) => {
|
|
7660
|
+
if ($.includes("_")) {
|
|
7661
|
+
const [J, ...ye] = $.split("_"), pe = ye.join("_");
|
|
7662
|
+
J === "shared" ? (ee._genderSpecific.shared[pe] || (ee._genderSpecific.shared[pe] = []), ee._genderSpecific.shared[pe].push(...ie)) : J === Z && (ee._genderSpecific[Z][pe] || (ee._genderSpecific[Z][pe] = []), ee._genderSpecific[Z][pe].push(...ie));
|
|
7655
7663
|
} else
|
|
7656
|
-
|
|
7657
|
-
}),
|
|
7658
|
-
|
|
7659
|
-
|
|
7664
|
+
ee[$] = ie;
|
|
7665
|
+
}), z && (z._genderSpecific && Object.keys(z._genderSpecific).forEach(($) => {
|
|
7666
|
+
ee._genderSpecific[$] || (ee._genderSpecific[$] = {}), Object.entries(z._genderSpecific[$]).forEach(([ie, J]) => {
|
|
7667
|
+
ee._genderSpecific[$][ie] || (ee._genderSpecific[$][ie] = J);
|
|
7660
7668
|
});
|
|
7661
|
-
}), Object.entries(
|
|
7662
|
-
|
|
7663
|
-
})),
|
|
7664
|
-
} else if (typeof
|
|
7665
|
-
const
|
|
7666
|
-
|
|
7669
|
+
}), Object.entries(z).forEach(([$, ie]) => {
|
|
7670
|
+
$ !== "_genderSpecific" && !ee[$] && (ee[$] = ie);
|
|
7671
|
+
})), j(ee);
|
|
7672
|
+
} else if (typeof H.auto == "object") {
|
|
7673
|
+
const F = await lt(H.auto, e), se = Object.values(F).some((Z) => Array.isArray(Z) && Z.length > 0);
|
|
7674
|
+
j(!se && z ? z : F);
|
|
7667
7675
|
}
|
|
7668
|
-
} catch (
|
|
7669
|
-
if (console.error("Failed to auto-discover animations:",
|
|
7676
|
+
} catch (z) {
|
|
7677
|
+
if (console.error("Failed to auto-discover animations:", z), H.manifest)
|
|
7670
7678
|
try {
|
|
7671
|
-
const
|
|
7672
|
-
|
|
7679
|
+
const F = await je(H.manifest);
|
|
7680
|
+
j(F);
|
|
7673
7681
|
} catch {
|
|
7674
|
-
|
|
7682
|
+
j(H);
|
|
7675
7683
|
}
|
|
7676
7684
|
else
|
|
7677
|
-
|
|
7685
|
+
j(H);
|
|
7678
7686
|
}
|
|
7679
7687
|
else
|
|
7680
|
-
|
|
7688
|
+
j(H);
|
|
7681
7689
|
})();
|
|
7682
|
-
}, [
|
|
7683
|
-
|
|
7690
|
+
}, [H, e, ue]), ze(() => {
|
|
7691
|
+
I.current = c;
|
|
7684
7692
|
}, [c]);
|
|
7685
|
-
const
|
|
7686
|
-
let
|
|
7687
|
-
|
|
7693
|
+
const de = Je(), ne = s || de.service;
|
|
7694
|
+
let me;
|
|
7695
|
+
ne === "browser" ? me = {
|
|
7688
7696
|
service: "browser",
|
|
7689
7697
|
endpoint: "",
|
|
7690
7698
|
apiKey: null,
|
|
7691
7699
|
defaultVoice: "Google US English"
|
|
7692
|
-
} :
|
|
7700
|
+
} : ne === "elevenlabs" ? me = {
|
|
7693
7701
|
service: "elevenlabs",
|
|
7694
7702
|
endpoint: "https://api.elevenlabs.io/v1/text-to-speech",
|
|
7695
|
-
apiKey: a ||
|
|
7696
|
-
defaultVoice: i ||
|
|
7697
|
-
voices:
|
|
7698
|
-
} :
|
|
7703
|
+
apiKey: a || de.apiKey,
|
|
7704
|
+
defaultVoice: i || de.defaultVoice || Ve.defaultVoice,
|
|
7705
|
+
voices: de.voices || Ve.voices
|
|
7706
|
+
} : ne === "deepgram" ? me = {
|
|
7699
7707
|
service: "deepgram",
|
|
7700
7708
|
endpoint: "https://api.deepgram.com/v1/speak",
|
|
7701
|
-
apiKey: a ||
|
|
7702
|
-
defaultVoice: i ||
|
|
7703
|
-
voices:
|
|
7704
|
-
} :
|
|
7705
|
-
...
|
|
7706
|
-
apiKey: a !== null ? a :
|
|
7709
|
+
apiKey: a || de.apiKey,
|
|
7710
|
+
defaultVoice: i || de.defaultVoice || _e.defaultVoice,
|
|
7711
|
+
voices: de.voices || _e.voices
|
|
7712
|
+
} : me = {
|
|
7713
|
+
...de,
|
|
7714
|
+
apiKey: a !== null ? a : de.apiKey
|
|
7707
7715
|
};
|
|
7708
|
-
const
|
|
7716
|
+
const Xe = {
|
|
7709
7717
|
url: n,
|
|
7710
7718
|
body: e,
|
|
7711
7719
|
avatarMood: t,
|
|
7712
|
-
ttsLang:
|
|
7713
|
-
ttsVoice: i ||
|
|
7720
|
+
ttsLang: ne === "browser" ? "en-US" : o,
|
|
7721
|
+
ttsVoice: i || me.defaultVoice,
|
|
7714
7722
|
lipsyncLang: "en",
|
|
7715
7723
|
showFullAvatar: c,
|
|
7716
7724
|
bodyMovement: u,
|
|
7717
7725
|
movementIntensity: l
|
|
7718
|
-
},
|
|
7719
|
-
ttsEndpoint:
|
|
7720
|
-
ttsApikey:
|
|
7721
|
-
ttsService:
|
|
7726
|
+
}, Oe = {
|
|
7727
|
+
ttsEndpoint: me.endpoint,
|
|
7728
|
+
ttsApikey: me.apiKey,
|
|
7729
|
+
ttsService: ne,
|
|
7722
7730
|
lipsyncModules: ["en"],
|
|
7723
7731
|
cameraView: r
|
|
7724
|
-
},
|
|
7725
|
-
if (!(!
|
|
7732
|
+
}, Fe = W(async () => {
|
|
7733
|
+
if (!(!C.current || x.current))
|
|
7726
7734
|
try {
|
|
7727
|
-
|
|
7728
|
-
if (
|
|
7729
|
-
const
|
|
7730
|
-
d(
|
|
7735
|
+
Te(!0), Me(null), x.current = new it(C.current, Oe), await x.current.showAvatar(Xe, (z) => {
|
|
7736
|
+
if (z.lengthComputable) {
|
|
7737
|
+
const F = Math.min(100, Math.round(z.loaded / z.total * 100));
|
|
7738
|
+
d(F);
|
|
7731
7739
|
}
|
|
7732
|
-
}),
|
|
7733
|
-
const
|
|
7734
|
-
document.visibilityState === "visible" ?
|
|
7740
|
+
}), Te(!1), R(!0), h(x.current);
|
|
7741
|
+
const k = () => {
|
|
7742
|
+
document.visibilityState === "visible" ? x.current?.start() : x.current?.stop();
|
|
7735
7743
|
};
|
|
7736
|
-
return document.addEventListener("visibilitychange",
|
|
7737
|
-
document.removeEventListener("visibilitychange",
|
|
7744
|
+
return document.addEventListener("visibilitychange", k), () => {
|
|
7745
|
+
document.removeEventListener("visibilitychange", k);
|
|
7738
7746
|
};
|
|
7739
|
-
} catch (
|
|
7740
|
-
console.error("Error initializing TalkingHead:",
|
|
7747
|
+
} catch (k) {
|
|
7748
|
+
console.error("Error initializing TalkingHead:", k), Me(k.message || "Failed to initialize avatar"), Te(!1), p(k);
|
|
7741
7749
|
}
|
|
7742
7750
|
}, []);
|
|
7743
|
-
|
|
7744
|
-
|
|
7745
|
-
}), [
|
|
7746
|
-
const
|
|
7747
|
-
if (
|
|
7751
|
+
ze(() => (Fe(), () => {
|
|
7752
|
+
x.current && (x.current.stop(), x.current.dispose(), x.current = null);
|
|
7753
|
+
}), [Fe]);
|
|
7754
|
+
const Re = W(async () => {
|
|
7755
|
+
if (x.current)
|
|
7748
7756
|
try {
|
|
7749
|
-
const
|
|
7750
|
-
|
|
7751
|
-
} catch (
|
|
7752
|
-
console.warn("Failed to resume audio context:",
|
|
7757
|
+
const k = x.current.audioCtx || x.current.audioContext;
|
|
7758
|
+
k && (k.state === "suspended" || k.state === "interrupted") && await k.resume();
|
|
7759
|
+
} catch (k) {
|
|
7760
|
+
console.warn("Failed to resume audio context:", k);
|
|
7753
7761
|
}
|
|
7754
|
-
}, []),
|
|
7755
|
-
if (!
|
|
7762
|
+
}, []), Ue = W((k) => {
|
|
7763
|
+
if (!B)
|
|
7756
7764
|
return [];
|
|
7757
|
-
let
|
|
7758
|
-
if (
|
|
7759
|
-
const
|
|
7760
|
-
if (
|
|
7761
|
-
const
|
|
7762
|
-
Array.isArray(
|
|
7765
|
+
let z = null;
|
|
7766
|
+
if (B._genderSpecific) {
|
|
7767
|
+
const F = ue(e), se = B._genderSpecific[F];
|
|
7768
|
+
if (se && se[k] && Array.isArray(se[k]) && se[k].length > 0 && (z = se[k]), !z && B._genderSpecific.shared && B._genderSpecific.shared[k]) {
|
|
7769
|
+
const Z = B._genderSpecific.shared[k];
|
|
7770
|
+
Array.isArray(Z) && Z.length > 0 && (z = Z);
|
|
7763
7771
|
}
|
|
7764
7772
|
}
|
|
7765
|
-
if (!
|
|
7766
|
-
const
|
|
7767
|
-
Array.isArray(
|
|
7768
|
-
}
|
|
7769
|
-
return !w || Array.isArray(w) && w.length === 0 ? ((Object.keys(F).length > 0 || F._genderSpecific && Object.keys(F._genderSpecific).length > 0) && console.warn(`⚠️ No animations found for group "${S}" (gender: ${_(e)}). Make sure animations are configured correctly.`), []) : Array.isArray(w) ? [...w] : typeof w == "string" ? [w] : [];
|
|
7770
|
-
}, [F, e, _]), He = U((S) => {
|
|
7771
|
-
const w = [...S];
|
|
7772
|
-
for (let H = w.length - 1; H > 0; H--) {
|
|
7773
|
-
const J = Math.floor(Math.random() * (H + 1));
|
|
7774
|
-
[w[H], w[J]] = [w[J], w[H]];
|
|
7773
|
+
if (!z && B[k]) {
|
|
7774
|
+
const F = B[k];
|
|
7775
|
+
Array.isArray(F) && F.length > 0 ? z = F : typeof F == "string" && (z = [F]);
|
|
7775
7776
|
}
|
|
7776
|
-
return
|
|
7777
|
-
}, []),
|
|
7778
|
-
if (
|
|
7779
|
-
const
|
|
7780
|
-
if (
|
|
7777
|
+
return !z || Array.isArray(z) && z.length === 0 ? ((Object.keys(B).length > 0 || B._genderSpecific && Object.keys(B._genderSpecific).length > 0) && console.warn(`⚠️ No animations found for group "${k}" (gender: ${ue(e)}). Make sure animations are configured correctly.`), []) : Array.isArray(z) ? [...z] : typeof z == "string" ? [z] : [];
|
|
7778
|
+
}, [B, e, ue]), tt = W((k) => {
|
|
7779
|
+
if (Ae.current.length === 0) {
|
|
7780
|
+
const F = Ue(k);
|
|
7781
|
+
if (F.length === 0)
|
|
7781
7782
|
return null;
|
|
7782
|
-
|
|
7783
|
+
Ae.current = [...F], be.current = [];
|
|
7783
7784
|
}
|
|
7784
|
-
const
|
|
7785
|
-
return
|
|
7786
|
-
}, [
|
|
7787
|
-
if (!
|
|
7785
|
+
const z = Ae.current.shift();
|
|
7786
|
+
return z && be.current.push(z), z;
|
|
7787
|
+
}, [Ue]), Ge = W((k) => k ? k.split("/").pop().replace(".fbx", "").replace(/[-_]/g, " ") : "Unknown", []), we = W((k, z = !1, F = null) => {
|
|
7788
|
+
if (!x.current || !X.current || q.current !== k)
|
|
7788
7789
|
return null;
|
|
7789
|
-
const
|
|
7790
|
-
if (
|
|
7790
|
+
const se = tt(k);
|
|
7791
|
+
if (se)
|
|
7791
7792
|
try {
|
|
7792
|
-
const
|
|
7793
|
-
console.log(`🎬 Playing animation: "${
|
|
7794
|
-
const
|
|
7793
|
+
const Z = Ge(se);
|
|
7794
|
+
console.log(`🎬 Playing animation: "${Z}"`);
|
|
7795
|
+
const ke = () => {
|
|
7795
7796
|
console.log("🎬 Animation finished, checking if should continue...");
|
|
7796
|
-
const
|
|
7797
|
-
if (!
|
|
7797
|
+
const O = () => {
|
|
7798
|
+
if (!x.current)
|
|
7798
7799
|
return console.log("🎬 No talkingHeadRef, stopping animations"), !1;
|
|
7799
|
-
if (!
|
|
7800
|
+
if (!X.current)
|
|
7800
7801
|
return console.log("🎬 isSpeakingRef is false, stopping animations"), !1;
|
|
7801
|
-
if (q.current !==
|
|
7802
|
-
return console.log(`🎬 Animation group mismatch (${q.current} !== ${
|
|
7803
|
-
const
|
|
7802
|
+
if (q.current !== k)
|
|
7803
|
+
return console.log(`🎬 Animation group mismatch (${q.current} !== ${k}), stopping animations`), !1;
|
|
7804
|
+
const $ = x.current, ie = $.isAudioPlaying === !0, J = $.audioPlaylist && $.audioPlaylist.length > 0, ye = $.speechQueue && $.speechQueue.length > 0, pe = $.isSpeaking === !0, De = pe || ie || J || ye;
|
|
7804
7805
|
return console.log("🎬 Still speaking check:", {
|
|
7805
|
-
isSpeakingRef:
|
|
7806
|
-
isTalkingHeadSpeaking:
|
|
7807
|
-
hasAudioPlaying:
|
|
7808
|
-
hasAudioInPlaylist:
|
|
7809
|
-
hasItemsInQueue:
|
|
7810
|
-
shouldContinue:
|
|
7811
|
-
}),
|
|
7806
|
+
isSpeakingRef: X.current,
|
|
7807
|
+
isTalkingHeadSpeaking: pe,
|
|
7808
|
+
hasAudioPlaying: ie,
|
|
7809
|
+
hasAudioInPlaylist: J,
|
|
7810
|
+
hasItemsInQueue: ye,
|
|
7811
|
+
shouldContinue: De
|
|
7812
|
+
}), De;
|
|
7812
7813
|
};
|
|
7813
|
-
|
|
7814
|
-
|
|
7815
|
-
})) : (console.log("🎬 Speech has ended, stopping animations"),
|
|
7814
|
+
O() ? (console.log("🎬 Still speaking, continuing to next animation..."), requestAnimationFrame(() => {
|
|
7815
|
+
O() ? (console.log("🎬 Playing next animation..."), we(k, z, F)) : (console.log("🎬 Speech ended, stopping animations"), X.current = !1, q.current = null, x.current && x.current.stopAnimation(), F && F());
|
|
7816
|
+
})) : (console.log("🎬 Speech has ended, stopping animations"), X.current = !1, q.current = null, x.current && x.current.stopAnimation(), F && F());
|
|
7816
7817
|
};
|
|
7817
|
-
return
|
|
7818
|
-
} catch (
|
|
7819
|
-
return console.error("Failed to play animation:",
|
|
7818
|
+
return x.current.playAnimation(se, null, 0, 0, 0.01, z, ke), se;
|
|
7819
|
+
} catch (Z) {
|
|
7820
|
+
return console.error("Failed to play animation:", Z), null;
|
|
7820
7821
|
}
|
|
7821
7822
|
else {
|
|
7822
|
-
const
|
|
7823
|
-
if (!
|
|
7823
|
+
const Z = () => {
|
|
7824
|
+
if (!x.current || !X.current || q.current !== k)
|
|
7824
7825
|
return !1;
|
|
7825
|
-
const
|
|
7826
|
-
return
|
|
7826
|
+
const O = x.current, ee = O.isAudioPlaying === !0, $ = O.audioPlaylist && O.audioPlaylist.length > 0, ie = O.speechQueue && O.speechQueue.length > 0;
|
|
7827
|
+
return O.isSpeaking === !0 || ee || $ || ie;
|
|
7827
7828
|
};
|
|
7828
|
-
|
|
7829
|
+
Z() && (Ae.current = [], be.current = [], Z() ? we(k, z, F) : (X.current = !1, q.current = null, x.current && x.current.stopAnimation()));
|
|
7829
7830
|
}
|
|
7830
7831
|
return null;
|
|
7831
|
-
}, [
|
|
7832
|
-
|
|
7833
|
-
!
|
|
7832
|
+
}, [tt, Ge]), ht = W(() => {
|
|
7833
|
+
y && x.current && !X.current && (oe.current && (clearInterval(oe.current), oe.current = null), Ae.current = [], be.current = [], we(y, !1, null), oe.current = setInterval(() => {
|
|
7834
|
+
!X.current && !D.current && y && (Ae.current = [], be.current = [], we(y, !1, null));
|
|
7834
7835
|
}, 12e3 + Math.random() * 3e3));
|
|
7835
|
-
}, [
|
|
7836
|
-
|
|
7837
|
-
const Ze =
|
|
7838
|
-
if (!
|
|
7836
|
+
}, [y, we]);
|
|
7837
|
+
_.current = ht;
|
|
7838
|
+
const Ze = W(async (k, z = {}) => {
|
|
7839
|
+
if (!x.current || !ae || !k || k.trim() === "")
|
|
7839
7840
|
return;
|
|
7840
|
-
await
|
|
7841
|
-
const
|
|
7842
|
-
|
|
7841
|
+
await Re(), oe.current && (clearInterval(oe.current), oe.current = null);
|
|
7842
|
+
const F = z.animationGroup || M;
|
|
7843
|
+
F && !z.skipAnimation && (X.current = !0, q.current = F, Ae.current = [], be.current = [], we(F));
|
|
7843
7844
|
try {
|
|
7844
|
-
b(
|
|
7845
|
-
} catch (
|
|
7846
|
-
console.warn("Error in onSpeechStart callback:",
|
|
7845
|
+
b(k), z.onSpeechStart && z.onSpeechStart(k);
|
|
7846
|
+
} catch (O) {
|
|
7847
|
+
console.warn("Error in onSpeechStart callback:", O);
|
|
7847
7848
|
}
|
|
7848
|
-
|
|
7849
|
-
const
|
|
7850
|
-
|
|
7851
|
-
const
|
|
7852
|
-
|
|
7849
|
+
K.current = { remainingText: null, originalText: null, options: null }, fe.current = [], G.current = { text: k, options: z }, P.current && (clearInterval(P.current), P.current = null), N(!1), D.current = !1, Se.current = !1;
|
|
7850
|
+
const se = k.split(/[.!?]+/).filter((O) => O.trim().length > 0);
|
|
7851
|
+
fe.current = se, et.current = 0, te.current = "";
|
|
7852
|
+
const Z = (O) => {
|
|
7853
|
+
let ee = "";
|
|
7854
|
+
if (O && (O.text ? ee = O.text : O.vs && O.vs.subtitles ? Array.isArray(O.vs.subtitles) ? ee = O.vs.subtitles.join("") : typeof O.vs.subtitles == "string" && (ee = O.vs.subtitles) : O.subtitles && (Array.isArray(O.subtitles) ? ee = O.subtitles.join("") : typeof O.subtitles == "string" && (ee = O.subtitles))), ee.trim() && (te.current += ee, L && typeof L == "function"))
|
|
7855
|
+
try {
|
|
7856
|
+
L(te.current.trim());
|
|
7857
|
+
} catch ($) {
|
|
7858
|
+
console.warn("Error in onSubtitle callback:", $);
|
|
7859
|
+
}
|
|
7860
|
+
}, ke = {
|
|
7861
|
+
lipsyncLang: z.lipsyncLang || "en",
|
|
7862
|
+
onSubtitles: L ? Z : null
|
|
7853
7863
|
};
|
|
7854
|
-
if (
|
|
7855
|
-
const
|
|
7856
|
-
let
|
|
7857
|
-
const
|
|
7858
|
-
|
|
7859
|
-
const
|
|
7860
|
-
if (
|
|
7864
|
+
if (x.current) {
|
|
7865
|
+
const O = x.current;
|
|
7866
|
+
let ee = 0;
|
|
7867
|
+
const $ = 1200;
|
|
7868
|
+
P.current && (clearInterval(P.current), P.current = null);
|
|
7869
|
+
const ie = { current: !1 }, J = setInterval(() => {
|
|
7870
|
+
if (ee++, D.current)
|
|
7861
7871
|
return;
|
|
7862
|
-
if (
|
|
7863
|
-
if (
|
|
7864
|
-
|
|
7872
|
+
if (ee > $) {
|
|
7873
|
+
if (J && (clearInterval(J), P.current = null), !ie.current && !D.current) {
|
|
7874
|
+
ie.current = !0, X.current = !1, q.current = null, Ae.current = [], be.current = [], x.current && (x.current.stopAnimation(), x.current.isSpeaking = !1);
|
|
7865
7875
|
try {
|
|
7866
|
-
|
|
7867
|
-
} catch (
|
|
7868
|
-
console.error("Error in onSpeechEnd callback (timeout):",
|
|
7876
|
+
z.onSpeechEnd && z.onSpeechEnd(), f();
|
|
7877
|
+
} catch (ce) {
|
|
7878
|
+
console.error("Error in onSpeechEnd callback (timeout):", ce);
|
|
7869
7879
|
}
|
|
7870
7880
|
}
|
|
7871
7881
|
return;
|
|
7872
7882
|
}
|
|
7873
|
-
const
|
|
7874
|
-
|
|
7875
|
-
const
|
|
7876
|
-
if (!
|
|
7883
|
+
const ye = !O.speechQueue || O.speechQueue.length === 0, pe = !O.audioPlaylist || O.audioPlaylist.length === 0, De = O.isAudioPlaying === !1;
|
|
7884
|
+
O && !D.current && ye && pe && De && O.isSpeaking === !1 && !ie.current && !D.current && setTimeout(() => {
|
|
7885
|
+
const ce = x.current;
|
|
7886
|
+
if (!ce)
|
|
7877
7887
|
return;
|
|
7878
|
-
!
|
|
7879
|
-
|
|
7888
|
+
!D.current && (!ce.speechQueue || ce.speechQueue.length === 0) && (!ce.audioPlaylist || ce.audioPlaylist.length === 0) && ce.isAudioPlaying === !1 && ce.isSpeaking === !1 && !ie.current && !D.current && (ie.current = !0, J && (clearInterval(J), P.current = null), X.current = !1, q.current = null, Ae.current = [], be.current = [], te.current = "", ce && (ce.stopAnimation(), ce.isSpeaking = !1), Se.current = !0, setTimeout(() => {
|
|
7889
|
+
_.current && _.current();
|
|
7880
7890
|
}, 500), setTimeout(() => {
|
|
7881
7891
|
try {
|
|
7882
|
-
|
|
7883
|
-
|
|
7892
|
+
z.onSpeechEnd && z.onSpeechEnd(), f(), setTimeout(() => {
|
|
7893
|
+
Se.current = !1;
|
|
7884
7894
|
}, 500);
|
|
7885
|
-
} catch (
|
|
7886
|
-
console.error("Error in onSpeechEnd callback:",
|
|
7895
|
+
} catch (nt) {
|
|
7896
|
+
console.error("Error in onSpeechEnd callback:", nt), Se.current = !1;
|
|
7887
7897
|
}
|
|
7888
7898
|
}, 100));
|
|
7889
7899
|
}, 200);
|
|
7890
7900
|
}, 50);
|
|
7891
|
-
|
|
7901
|
+
P.current = J;
|
|
7892
7902
|
}
|
|
7893
7903
|
try {
|
|
7894
|
-
|
|
7895
|
-
} catch (
|
|
7896
|
-
console.error("Error speaking text:",
|
|
7904
|
+
x.current.speakText(k, ke);
|
|
7905
|
+
} catch (O) {
|
|
7906
|
+
console.error("Error speaking text:", O), Me(O.message || "Failed to speak text");
|
|
7897
7907
|
}
|
|
7898
|
-
}, [
|
|
7899
|
-
|
|
7900
|
-
if (!
|
|
7908
|
+
}, [ae, f, Re, M, we]);
|
|
7909
|
+
ze(() => {
|
|
7910
|
+
if (!ae || !y || !x.current)
|
|
7901
7911
|
return;
|
|
7902
|
-
|
|
7903
|
-
const
|
|
7904
|
-
|
|
7912
|
+
oe.current && (clearInterval(oe.current), oe.current = null);
|
|
7913
|
+
const k = () => {
|
|
7914
|
+
x.current && !D.current && !X.current && (Ae.current = [], be.current = [], we(y, !1, null));
|
|
7905
7915
|
};
|
|
7906
|
-
return
|
|
7907
|
-
|
|
7916
|
+
return X.current || k(), oe.current = setInterval(() => {
|
|
7917
|
+
X.current || k();
|
|
7908
7918
|
}, 12e3 + Math.random() * 3e3), () => {
|
|
7909
|
-
|
|
7919
|
+
oe.current && (clearInterval(oe.current), oe.current = null);
|
|
7910
7920
|
};
|
|
7911
|
-
}, [
|
|
7912
|
-
|
|
7913
|
-
}, [
|
|
7914
|
-
const dt =
|
|
7915
|
-
if (
|
|
7921
|
+
}, [ae, y, we, X]), ze(() => {
|
|
7922
|
+
ae && Y && E && x.current && !X.current && !D.current && !Se.current && Ze(Y);
|
|
7923
|
+
}, [ae, Y, E, Ze]);
|
|
7924
|
+
const dt = W(() => {
|
|
7925
|
+
if (x.current)
|
|
7916
7926
|
try {
|
|
7917
|
-
const
|
|
7918
|
-
if (
|
|
7919
|
-
|
|
7920
|
-
const
|
|
7921
|
-
let
|
|
7922
|
-
const
|
|
7923
|
-
if (
|
|
7924
|
-
const
|
|
7925
|
-
|
|
7927
|
+
const k = x.current.isSpeaking || !1, z = [...x.current.audioPlaylist || []], F = [...x.current.speechQueue || []];
|
|
7928
|
+
if (k || z.length > 0 || F.length > 0) {
|
|
7929
|
+
P.current && (clearInterval(P.current), P.current = null);
|
|
7930
|
+
const se = fe.current;
|
|
7931
|
+
let Z = [];
|
|
7932
|
+
const ke = x.current.isAudioPlaying || !1;
|
|
7933
|
+
if (se.length > 0) {
|
|
7934
|
+
const J = z.length + F.length, ye = ke ? 1 : 0, pe = se.length - J - ye, De = ke ? pe : pe + ye;
|
|
7935
|
+
De < se.length && (Z = se.slice(De));
|
|
7926
7936
|
} else
|
|
7927
|
-
|
|
7928
|
-
if (
|
|
7929
|
-
if (Array.isArray(
|
|
7930
|
-
const
|
|
7931
|
-
|
|
7932
|
-
} else
|
|
7933
|
-
}),
|
|
7934
|
-
if (
|
|
7935
|
-
if (Array.isArray(
|
|
7936
|
-
const
|
|
7937
|
-
|
|
7938
|
-
} else
|
|
7937
|
+
z.length > 0 && z.forEach((J) => {
|
|
7938
|
+
if (J.text)
|
|
7939
|
+
if (Array.isArray(J.text)) {
|
|
7940
|
+
const ye = J.text.map((pe) => pe.word).join(" ");
|
|
7941
|
+
ye.trim() && Z.push(ye);
|
|
7942
|
+
} else J.text.trim() && Z.push(J.text);
|
|
7943
|
+
}), F.length > 0 && F.forEach((J) => {
|
|
7944
|
+
if (J.text)
|
|
7945
|
+
if (Array.isArray(J.text)) {
|
|
7946
|
+
const ye = J.text.map((pe) => pe.word).join(" ");
|
|
7947
|
+
ye.trim() && Z.push(ye);
|
|
7948
|
+
} else J.text.trim() && Z.push(J.text);
|
|
7939
7949
|
});
|
|
7940
|
-
const
|
|
7941
|
-
|
|
7942
|
-
remainingText:
|
|
7943
|
-
originalText:
|
|
7944
|
-
options:
|
|
7950
|
+
const O = Z.join(" ");
|
|
7951
|
+
K.current = {
|
|
7952
|
+
remainingText: O || null,
|
|
7953
|
+
originalText: G.current?.text || null,
|
|
7954
|
+
options: G.current?.options || null,
|
|
7945
7955
|
// Track if we're pausing mid-sentence (has currently playing audio)
|
|
7946
|
-
isMidSentence:
|
|
7956
|
+
isMidSentence: z.length > 0
|
|
7947
7957
|
};
|
|
7948
|
-
const
|
|
7949
|
-
|
|
7950
|
-
const
|
|
7951
|
-
|
|
7958
|
+
const $ = x.current.isAudioPlaying || !1 ? [...x.current.speechQueue || []] : null;
|
|
7959
|
+
x.current.speechQueue.length = 0;
|
|
7960
|
+
const ie = x.current.pauseSpeaking();
|
|
7961
|
+
x.current.isSpeaking = !1, X.current = !1, q.current = null, ie && ie.audio && $ ? (w.current = ie, w.current.savedSpeechQueue = $) : w.current = ie, N(!0), D.current = !0;
|
|
7952
7962
|
}
|
|
7953
|
-
} catch (
|
|
7954
|
-
console.warn("Error pausing speech:",
|
|
7963
|
+
} catch (k) {
|
|
7964
|
+
console.warn("Error pausing speech:", k);
|
|
7955
7965
|
}
|
|
7956
|
-
}, []), mt =
|
|
7957
|
-
if (!(!
|
|
7966
|
+
}, []), mt = W(async () => {
|
|
7967
|
+
if (!(!x.current || !v))
|
|
7958
7968
|
try {
|
|
7959
|
-
if (await
|
|
7960
|
-
|
|
7961
|
-
const
|
|
7962
|
-
if (
|
|
7963
|
-
const
|
|
7964
|
-
let
|
|
7965
|
-
const
|
|
7966
|
-
|
|
7967
|
-
const
|
|
7968
|
-
if (
|
|
7969
|
+
if (await Re(), N(!1), D.current = !1, w.current && w.current.audio) {
|
|
7970
|
+
X.current = !0;
|
|
7971
|
+
const Z = K.current?.options || G.current?.options || {}, ke = Z.animationGroup || M;
|
|
7972
|
+
if (ke && (q.current = ke), w.current.savedSpeechQueue && (x.current.speechQueue.length = 0, x.current.speechQueue.push(...w.current.savedSpeechQueue)), x.current.isSpeaking = !0, x.current) {
|
|
7973
|
+
const O = x.current;
|
|
7974
|
+
let ee = 0;
|
|
7975
|
+
const $ = 1200, ie = { current: !1 };
|
|
7976
|
+
P.current && (clearInterval(P.current), P.current = null);
|
|
7977
|
+
const J = setInterval(() => {
|
|
7978
|
+
if (ee++, D.current)
|
|
7969
7979
|
return;
|
|
7970
|
-
if (
|
|
7971
|
-
if (
|
|
7972
|
-
|
|
7980
|
+
if (ee > $) {
|
|
7981
|
+
if (J && (clearInterval(J), P.current = null), !ie.current && !D.current) {
|
|
7982
|
+
ie.current = !0, X.current = !1, q.current = null, Ae.current = [], be.current = [], x.current && (x.current.stopAnimation(), x.current.isSpeaking = !1);
|
|
7973
7983
|
try {
|
|
7974
|
-
|
|
7975
|
-
} catch (
|
|
7976
|
-
console.error("Error in onSpeechEnd callback (timeout):",
|
|
7984
|
+
Z.onSpeechEnd && Z.onSpeechEnd(), f();
|
|
7985
|
+
} catch (ce) {
|
|
7986
|
+
console.error("Error in onSpeechEnd callback (timeout):", ce);
|
|
7977
7987
|
}
|
|
7978
7988
|
}
|
|
7979
7989
|
return;
|
|
7980
7990
|
}
|
|
7981
|
-
const
|
|
7982
|
-
|
|
7983
|
-
const
|
|
7984
|
-
if (!
|
|
7985
|
-
!
|
|
7986
|
-
|
|
7991
|
+
const ye = !O.speechQueue || O.speechQueue.length === 0, pe = !O.audioPlaylist || O.audioPlaylist.length === 0, De = O.isAudioPlaying === !1;
|
|
7992
|
+
O && !D.current && ye && pe && De && O.isSpeaking === !1 && !ie.current && !D.current && setTimeout(() => {
|
|
7993
|
+
const ce = x.current;
|
|
7994
|
+
if (!ce) return;
|
|
7995
|
+
!D.current && (!ce.speechQueue || ce.speechQueue.length === 0) && (!ce.audioPlaylist || ce.audioPlaylist.length === 0) && ce.isAudioPlaying === !1 && ce.isSpeaking === !1 && !ie.current && !D.current && (ie.current = !0, J && (clearInterval(J), P.current = null), X.current = !1, q.current = null, Ae.current = [], be.current = [], te.current = "", ce && (ce.stopAnimation(), ce.isSpeaking = !1), Se.current = !0, setTimeout(() => {
|
|
7996
|
+
_.current && _.current();
|
|
7987
7997
|
}, 500), setTimeout(() => {
|
|
7988
7998
|
try {
|
|
7989
|
-
|
|
7990
|
-
|
|
7999
|
+
Z.onSpeechEnd && Z.onSpeechEnd(), f(), setTimeout(() => {
|
|
8000
|
+
Se.current = !1;
|
|
7991
8001
|
}, 500);
|
|
7992
|
-
} catch (
|
|
7993
|
-
console.error("Error in onSpeechEnd callback:",
|
|
8002
|
+
} catch (nt) {
|
|
8003
|
+
console.error("Error in onSpeechEnd callback:", nt), Se.current = !1;
|
|
7994
8004
|
}
|
|
7995
8005
|
}, 100));
|
|
7996
8006
|
}, 200);
|
|
7997
8007
|
}, 50);
|
|
7998
|
-
|
|
8008
|
+
P.current = J;
|
|
7999
8009
|
}
|
|
8000
|
-
await
|
|
8010
|
+
await x.current.playAudio(!1, w.current), ke && !Z.skipAnimation && (Ae.current = [], be.current = [], we(ke)), w.current = null;
|
|
8001
8011
|
return;
|
|
8002
8012
|
}
|
|
8003
|
-
const
|
|
8004
|
-
|
|
8005
|
-
} catch (
|
|
8006
|
-
console.warn("Error resuming speech:",
|
|
8013
|
+
const k = K.current?.remainingText, z = K.current?.originalText || G.current?.text, F = K.current?.options || G.current?.options || {}, se = k || z;
|
|
8014
|
+
se && Ze(se, F), w.current = null;
|
|
8015
|
+
} catch (k) {
|
|
8016
|
+
console.warn("Error resuming speech:", k), N(!1), D.current = !1, w.current = null;
|
|
8007
8017
|
}
|
|
8008
|
-
}, [
|
|
8009
|
-
if (
|
|
8010
|
-
|
|
8011
|
-
|
|
8018
|
+
}, [v, Ze, Re, M, we]), pt = W(() => {
|
|
8019
|
+
if (x.current) {
|
|
8020
|
+
x.current.stopAnimation(), x.current.stopSpeaking(), P.current && (clearInterval(P.current), P.current = null), X.current = !1, q.current = null, Ae.current = [], be.current = [], te.current = "", N(!1), D.current = !1, w.current = null, Se.current = !1, setTimeout(() => {
|
|
8021
|
+
_.current && _.current();
|
|
8012
8022
|
}, 500);
|
|
8013
8023
|
try {
|
|
8014
|
-
|
|
8015
|
-
} catch (
|
|
8016
|
-
console.warn("Error in onSpeechEnd callback (stopSpeaking):",
|
|
8024
|
+
f();
|
|
8025
|
+
} catch (k) {
|
|
8026
|
+
console.warn("Error in onSpeechEnd callback (stopSpeaking):", k);
|
|
8017
8027
|
}
|
|
8018
8028
|
}
|
|
8019
|
-
}, [
|
|
8020
|
-
return $e(
|
|
8029
|
+
}, [f]);
|
|
8030
|
+
return $e(S, () => ({
|
|
8021
8031
|
speakText: Ze,
|
|
8022
8032
|
pauseSpeaking: dt,
|
|
8023
8033
|
resumeSpeaking: mt,
|
|
8024
8034
|
stopSpeaking: pt,
|
|
8025
|
-
resumeAudioContext:
|
|
8026
|
-
isPaused: () =>
|
|
8027
|
-
|
|
8028
|
-
|
|
8029
|
-
|
|
8035
|
+
resumeAudioContext: Re,
|
|
8036
|
+
isPaused: () => v,
|
|
8037
|
+
getCurrentSubtitle: () => te.current,
|
|
8038
|
+
// Get current subtitle text
|
|
8039
|
+
setMood: (k) => x.current?.setMood(k),
|
|
8040
|
+
setBodyMovement: (k) => {
|
|
8041
|
+
x.current && x.current.setBodyMovement(k);
|
|
8030
8042
|
},
|
|
8031
|
-
playAnimation: (
|
|
8032
|
-
|
|
8043
|
+
playAnimation: (k, z = !1) => {
|
|
8044
|
+
x.current && x.current.playAnimation && x.current.playAnimation(k, null, 10, 0, 0.01, z);
|
|
8033
8045
|
},
|
|
8034
|
-
playRandomAnimation: (
|
|
8035
|
-
getRandomAnimation: (
|
|
8036
|
-
playReaction: (
|
|
8037
|
-
playCelebration: () =>
|
|
8038
|
-
setShowFullAvatar: (
|
|
8039
|
-
|
|
8046
|
+
playRandomAnimation: (k, z = !1) => we(k, z),
|
|
8047
|
+
getRandomAnimation: (k) => getRandomAnimation(k),
|
|
8048
|
+
playReaction: (k) => x.current?.playReaction(k),
|
|
8049
|
+
playCelebration: () => x.current?.playCelebration(),
|
|
8050
|
+
setShowFullAvatar: (k) => {
|
|
8051
|
+
x.current && (I.current = k, x.current.setShowFullAvatar(k));
|
|
8040
8052
|
},
|
|
8041
|
-
isReady:
|
|
8042
|
-
talkingHead:
|
|
8043
|
-
})), /* @__PURE__ */
|
|
8044
|
-
/* @__PURE__ */
|
|
8053
|
+
isReady: ae,
|
|
8054
|
+
talkingHead: x.current
|
|
8055
|
+
})), /* @__PURE__ */ Ee("div", { className: `simple-talking-avatar-container ${Q}`, style: g, children: [
|
|
8056
|
+
/* @__PURE__ */ le(
|
|
8045
8057
|
"div",
|
|
8046
8058
|
{
|
|
8047
|
-
ref:
|
|
8059
|
+
ref: C,
|
|
8048
8060
|
className: "talking-head-viewer",
|
|
8049
8061
|
style: {
|
|
8050
8062
|
width: "100%",
|
|
@@ -8053,7 +8065,7 @@ const Wt = Ke(({
|
|
|
8053
8065
|
}
|
|
8054
8066
|
}
|
|
8055
8067
|
),
|
|
8056
|
-
|
|
8068
|
+
xe && /* @__PURE__ */ le("div", { className: "loading-overlay", style: {
|
|
8057
8069
|
position: "absolute",
|
|
8058
8070
|
top: "50%",
|
|
8059
8071
|
left: "50%",
|
|
@@ -8062,7 +8074,7 @@ const Wt = Ke(({
|
|
|
8062
8074
|
fontSize: "18px",
|
|
8063
8075
|
zIndex: 10
|
|
8064
8076
|
}, children: "Loading avatar..." }),
|
|
8065
|
-
|
|
8077
|
+
Le && /* @__PURE__ */ le("div", { className: "error-overlay", style: {
|
|
8066
8078
|
position: "absolute",
|
|
8067
8079
|
top: "50%",
|
|
8068
8080
|
left: "50%",
|
|
@@ -8073,12 +8085,12 @@ const Wt = Ke(({
|
|
|
8073
8085
|
zIndex: 10,
|
|
8074
8086
|
padding: "20px",
|
|
8075
8087
|
borderRadius: "8px"
|
|
8076
|
-
}, children:
|
|
8088
|
+
}, children: Le })
|
|
8077
8089
|
] });
|
|
8078
8090
|
});
|
|
8079
|
-
|
|
8080
|
-
const
|
|
8081
|
-
curriculumData:
|
|
8091
|
+
Vt.displayName = "SimpleTalkingAvatar";
|
|
8092
|
+
const Xt = Ke(({
|
|
8093
|
+
curriculumData: Y = null,
|
|
8082
8094
|
avatarConfig: n = {},
|
|
8083
8095
|
animations: e = {},
|
|
8084
8096
|
onLessonStart: t = () => {
|
|
@@ -8109,12 +8121,12 @@ const Vt = Ke(({
|
|
|
8109
8121
|
onQuestionAnswer: s,
|
|
8110
8122
|
onCurriculumComplete: i,
|
|
8111
8123
|
onCustomAction: a
|
|
8112
|
-
}), d = V(null),
|
|
8124
|
+
}), d = V(null), p = V(null), b = V(null), f = V(null), L = V(null), Q = V(null), g = V(null), H = V(Y?.curriculum || {
|
|
8113
8125
|
title: "Default Curriculum",
|
|
8114
8126
|
description: "No curriculum data provided",
|
|
8115
8127
|
language: "en",
|
|
8116
8128
|
modules: []
|
|
8117
|
-
}),
|
|
8129
|
+
}), M = V({
|
|
8118
8130
|
avatarUrl: n.avatarUrl || "/avatars/brunette.glb",
|
|
8119
8131
|
avatarBody: n.avatarBody || "F",
|
|
8120
8132
|
mood: n.mood || "happy",
|
|
@@ -8128,7 +8140,7 @@ const Vt = Ke(({
|
|
|
8128
8140
|
animations: e,
|
|
8129
8141
|
lipsyncLang: "en"
|
|
8130
8142
|
});
|
|
8131
|
-
|
|
8143
|
+
ze(() => {
|
|
8132
8144
|
h.current = {
|
|
8133
8145
|
onLessonStart: t,
|
|
8134
8146
|
onLessonComplete: o,
|
|
@@ -8136,13 +8148,13 @@ const Vt = Ke(({
|
|
|
8136
8148
|
onCurriculumComplete: i,
|
|
8137
8149
|
onCustomAction: a
|
|
8138
8150
|
};
|
|
8139
|
-
}, [t, o, s, i, a]),
|
|
8140
|
-
|
|
8151
|
+
}, [t, o, s, i, a]), ze(() => {
|
|
8152
|
+
H.current = Y?.curriculum || {
|
|
8141
8153
|
title: "Default Curriculum",
|
|
8142
8154
|
description: "No curriculum data provided",
|
|
8143
8155
|
language: "en",
|
|
8144
8156
|
modules: []
|
|
8145
|
-
},
|
|
8157
|
+
}, M.current = {
|
|
8146
8158
|
avatarUrl: n.avatarUrl || "/avatars/brunette.glb",
|
|
8147
8159
|
avatarBody: n.avatarBody || "F",
|
|
8148
8160
|
mood: n.mood || "happy",
|
|
@@ -8156,8 +8168,8 @@ const Vt = Ke(({
|
|
|
8156
8168
|
animations: e,
|
|
8157
8169
|
lipsyncLang: "en"
|
|
8158
8170
|
};
|
|
8159
|
-
}, [
|
|
8160
|
-
const
|
|
8171
|
+
}, [Y, n, e]);
|
|
8172
|
+
const y = W(() => (H.current || { modules: [] }).modules[r.current.currentModuleIndex]?.lessons[r.current.currentLessonIndex], []), E = W(() => y()?.questions[r.current.currentQuestionIndex], [y]), S = W((R, v) => v.type === "multiple_choice" || v.type === "true_false" ? R === v.answer : v.type === "code_test" && typeof R == "object" && R !== null ? R.passed === !0 : !1, []), C = W(() => {
|
|
8161
8173
|
r.current.lessonCompleted = !0, r.current.isQuestionMode = !1;
|
|
8162
8174
|
const R = r.current.totalQuestions > 0 ? Math.round(r.current.score / r.current.totalQuestions * 100) : 100;
|
|
8163
8175
|
let v = "Congratulations! You've completed this lesson";
|
|
@@ -8181,9 +8193,9 @@ const Vt = Ke(({
|
|
|
8181
8193
|
} catch {
|
|
8182
8194
|
c.current.playCelebration();
|
|
8183
8195
|
}
|
|
8184
|
-
const
|
|
8196
|
+
const N = H.current || { modules: [] }, B = N.modules[r.current.currentModuleIndex], j = r.current.currentLessonIndex < (B?.lessons?.length || 0) - 1, oe = r.current.currentModuleIndex < (N.modules?.length || 0) - 1, X = j || oe, q = M.current || { lipsyncLang: "en" };
|
|
8185
8197
|
c.current.speakText(v, {
|
|
8186
|
-
lipsyncLang:
|
|
8198
|
+
lipsyncLang: q.lipsyncLang,
|
|
8187
8199
|
onSpeechEnd: () => {
|
|
8188
8200
|
h.current.onCustomAction({
|
|
8189
8201
|
type: "lessonCompleteFeedbackDone",
|
|
@@ -8192,17 +8204,17 @@ const Vt = Ke(({
|
|
|
8192
8204
|
score: r.current.score,
|
|
8193
8205
|
totalQuestions: r.current.totalQuestions,
|
|
8194
8206
|
percentage: R,
|
|
8195
|
-
hasNextLesson:
|
|
8207
|
+
hasNextLesson: X
|
|
8196
8208
|
});
|
|
8197
8209
|
}
|
|
8198
8210
|
});
|
|
8199
8211
|
}
|
|
8200
|
-
}, [e.lessonComplete]),
|
|
8212
|
+
}, [e.lessonComplete]), x = W(() => {
|
|
8201
8213
|
r.current.curriculumCompleted = !0;
|
|
8202
|
-
const R =
|
|
8214
|
+
const R = H.current || { modules: [] };
|
|
8203
8215
|
if (h.current.onCurriculumComplete({
|
|
8204
8216
|
modules: R.modules.length,
|
|
8205
|
-
totalLessons: R.modules.reduce((v,
|
|
8217
|
+
totalLessons: R.modules.reduce((v, N) => v + N.lessons.length, 0)
|
|
8206
8218
|
}), c.current) {
|
|
8207
8219
|
if (c.current.setMood("celebrating"), e.curriculumComplete)
|
|
8208
8220
|
try {
|
|
@@ -8210,13 +8222,13 @@ const Vt = Ke(({
|
|
|
8210
8222
|
} catch {
|
|
8211
8223
|
c.current.playCelebration();
|
|
8212
8224
|
}
|
|
8213
|
-
const v =
|
|
8225
|
+
const v = M.current || { lipsyncLang: "en" };
|
|
8214
8226
|
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 });
|
|
8215
8227
|
}
|
|
8216
|
-
}, [e.curriculumComplete]), I =
|
|
8217
|
-
const R =
|
|
8228
|
+
}, [e.curriculumComplete]), I = W(() => {
|
|
8229
|
+
const R = y();
|
|
8218
8230
|
r.current.isQuestionMode = !0, r.current.currentQuestionIndex = 0, r.current.totalQuestions = R?.questions?.length || 0, r.current.score = 0;
|
|
8219
|
-
const v =
|
|
8231
|
+
const v = E();
|
|
8220
8232
|
v && h.current.onCustomAction({
|
|
8221
8233
|
type: "questionStart",
|
|
8222
8234
|
moduleIndex: r.current.currentModuleIndex,
|
|
@@ -8226,35 +8238,35 @@ const Vt = Ke(({
|
|
|
8226
8238
|
question: v,
|
|
8227
8239
|
score: r.current.score
|
|
8228
8240
|
});
|
|
8229
|
-
const
|
|
8241
|
+
const N = () => {
|
|
8230
8242
|
if (!c.current || !v) return;
|
|
8231
8243
|
if (c.current.setMood("happy"), e.questionStart)
|
|
8232
8244
|
try {
|
|
8233
8245
|
c.current.playAnimation(e.questionStart, !0);
|
|
8234
|
-
} catch (
|
|
8235
|
-
console.warn("Failed to play questionStart animation:",
|
|
8246
|
+
} catch (j) {
|
|
8247
|
+
console.warn("Failed to play questionStart animation:", j);
|
|
8236
8248
|
}
|
|
8237
|
-
const
|
|
8238
|
-
v.type === "code_test" ? c.current.speakText(`Let's test your coding skills! Here's your first challenge: ${v.question}`, { lipsyncLang:
|
|
8249
|
+
const B = M.current || { lipsyncLang: "en" };
|
|
8250
|
+
v.type === "code_test" ? c.current.speakText(`Let's test your coding skills! Here's your first challenge: ${v.question}`, { lipsyncLang: B.lipsyncLang }) : v.type === "multiple_choice" ? c.current.speakText(`Now let me ask you some questions. Here's the first one: ${v.question}`, { lipsyncLang: B.lipsyncLang }) : v.type === "true_false" ? c.current.speakText(`Let's start with some true or false questions. First question: ${v.question}`, { lipsyncLang: B.lipsyncLang }) : c.current.speakText(`Now let me ask you some questions. Here's the first one: ${v.question}`, { lipsyncLang: B.lipsyncLang });
|
|
8239
8251
|
};
|
|
8240
8252
|
if (c.current && c.current.isReady && v)
|
|
8241
|
-
|
|
8253
|
+
N();
|
|
8242
8254
|
else if (c.current && c.current.isReady) {
|
|
8243
|
-
const
|
|
8244
|
-
c.current.speakText("Now let me ask you some questions to test your understanding.", { lipsyncLang:
|
|
8255
|
+
const B = M.current || { lipsyncLang: "en" };
|
|
8256
|
+
c.current.speakText("Now let me ask you some questions to test your understanding.", { lipsyncLang: B.lipsyncLang });
|
|
8245
8257
|
} else {
|
|
8246
|
-
const
|
|
8247
|
-
c.current && c.current.isReady && (clearInterval(
|
|
8258
|
+
const B = setInterval(() => {
|
|
8259
|
+
c.current && c.current.isReady && (clearInterval(B), v && N());
|
|
8248
8260
|
}, 100);
|
|
8249
8261
|
setTimeout(() => {
|
|
8250
|
-
clearInterval(
|
|
8262
|
+
clearInterval(B);
|
|
8251
8263
|
}, 5e3);
|
|
8252
8264
|
}
|
|
8253
|
-
}, [e.questionStart,
|
|
8254
|
-
const R =
|
|
8265
|
+
}, [e.questionStart, y, E]), G = W(() => {
|
|
8266
|
+
const R = y();
|
|
8255
8267
|
if (r.current.currentQuestionIndex < (R?.questions?.length || 0) - 1) {
|
|
8256
8268
|
c.current && c.current.stopSpeaking && c.current.stopSpeaking(), r.current.currentQuestionIndex += 1;
|
|
8257
|
-
const v =
|
|
8269
|
+
const v = E();
|
|
8258
8270
|
v && h.current.onCustomAction({
|
|
8259
8271
|
type: "nextQuestion",
|
|
8260
8272
|
moduleIndex: r.current.currentModuleIndex,
|
|
@@ -8264,45 +8276,45 @@ const Vt = Ke(({
|
|
|
8264
8276
|
question: v,
|
|
8265
8277
|
score: r.current.score
|
|
8266
8278
|
});
|
|
8267
|
-
const
|
|
8279
|
+
const N = () => {
|
|
8268
8280
|
if (!c.current || !v) return;
|
|
8269
8281
|
if (c.current.setMood("happy"), c.current.setBodyMovement("idle"), e.nextQuestion)
|
|
8270
8282
|
try {
|
|
8271
8283
|
c.current.playAnimation(e.nextQuestion, !0);
|
|
8272
|
-
} catch (
|
|
8273
|
-
console.warn("Failed to play nextQuestion animation:",
|
|
8284
|
+
} catch (q) {
|
|
8285
|
+
console.warn("Failed to play nextQuestion animation:", q);
|
|
8274
8286
|
}
|
|
8275
|
-
const
|
|
8287
|
+
const B = M.current || { lipsyncLang: "en" }, oe = y()?.questions?.length || 0, X = r.current.currentQuestionIndex >= oe - 1;
|
|
8276
8288
|
if (v.type === "code_test") {
|
|
8277
|
-
const
|
|
8278
|
-
c.current.speakText(
|
|
8279
|
-
lipsyncLang:
|
|
8289
|
+
const q = X ? `Great! Here's your final coding challenge: ${v.question}` : `Great! Now let's move on to your next coding challenge: ${v.question}`;
|
|
8290
|
+
c.current.speakText(q, {
|
|
8291
|
+
lipsyncLang: B.lipsyncLang
|
|
8280
8292
|
});
|
|
8281
8293
|
} else if (v.type === "multiple_choice") {
|
|
8282
|
-
const
|
|
8283
|
-
c.current.speakText(
|
|
8284
|
-
lipsyncLang:
|
|
8294
|
+
const q = X ? `Alright! Here's your final question: ${v.question}` : `Alright! Here's your next question: ${v.question}`;
|
|
8295
|
+
c.current.speakText(q, {
|
|
8296
|
+
lipsyncLang: B.lipsyncLang
|
|
8285
8297
|
});
|
|
8286
8298
|
} else if (v.type === "true_false") {
|
|
8287
|
-
const
|
|
8288
|
-
c.current.speakText(
|
|
8289
|
-
lipsyncLang:
|
|
8299
|
+
const q = X ? `Now let's try this final one: ${v.question}` : `Now let's try this one: ${v.question}`;
|
|
8300
|
+
c.current.speakText(q, {
|
|
8301
|
+
lipsyncLang: B.lipsyncLang
|
|
8290
8302
|
});
|
|
8291
8303
|
} else {
|
|
8292
|
-
const
|
|
8293
|
-
c.current.speakText(
|
|
8294
|
-
lipsyncLang:
|
|
8304
|
+
const q = X ? `Here's your final question: ${v.question}` : `Here's the next question: ${v.question}`;
|
|
8305
|
+
c.current.speakText(q, {
|
|
8306
|
+
lipsyncLang: B.lipsyncLang
|
|
8295
8307
|
});
|
|
8296
8308
|
}
|
|
8297
8309
|
};
|
|
8298
8310
|
if (c.current && c.current.isReady && v)
|
|
8299
|
-
|
|
8311
|
+
N();
|
|
8300
8312
|
else if (v) {
|
|
8301
|
-
const
|
|
8302
|
-
c.current && c.current.isReady && (clearInterval(
|
|
8313
|
+
const B = setInterval(() => {
|
|
8314
|
+
c.current && c.current.isReady && (clearInterval(B), N());
|
|
8303
8315
|
}, 100);
|
|
8304
8316
|
setTimeout(() => {
|
|
8305
|
-
clearInterval(
|
|
8317
|
+
clearInterval(B);
|
|
8306
8318
|
}, 5e3);
|
|
8307
8319
|
}
|
|
8308
8320
|
} else
|
|
@@ -8313,55 +8325,55 @@ const Vt = Ke(({
|
|
|
8313
8325
|
totalQuestions: r.current.totalQuestions,
|
|
8314
8326
|
score: r.current.score
|
|
8315
8327
|
});
|
|
8316
|
-
}, [e.nextQuestion,
|
|
8317
|
-
const R =
|
|
8328
|
+
}, [e.nextQuestion, y, E]), P = W(() => {
|
|
8329
|
+
const R = H.current || { modules: [] }, v = R.modules[r.current.currentModuleIndex];
|
|
8318
8330
|
if (r.current.currentLessonIndex < (v?.lessons?.length || 0) - 1) {
|
|
8319
8331
|
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;
|
|
8320
|
-
const
|
|
8332
|
+
const B = R.modules[r.current.currentModuleIndex], j = r.current.currentLessonIndex < (B?.lessons?.length || 0) - 1, oe = r.current.currentModuleIndex < (R.modules?.length || 0) - 1, X = j || oe;
|
|
8321
8333
|
h.current.onCustomAction({
|
|
8322
8334
|
type: "lessonStart",
|
|
8323
8335
|
moduleIndex: r.current.currentModuleIndex,
|
|
8324
8336
|
lessonIndex: r.current.currentLessonIndex,
|
|
8325
|
-
hasNextLesson:
|
|
8337
|
+
hasNextLesson: X
|
|
8326
8338
|
}), h.current.onLessonStart({
|
|
8327
8339
|
moduleIndex: r.current.currentModuleIndex,
|
|
8328
8340
|
lessonIndex: r.current.currentLessonIndex,
|
|
8329
|
-
lesson:
|
|
8341
|
+
lesson: y()
|
|
8330
8342
|
}), c.current && (c.current.setMood("happy"), c.current.setBodyMovement("idle"));
|
|
8331
8343
|
} else if (r.current.currentModuleIndex < (R.modules?.length || 0) - 1) {
|
|
8332
8344
|
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;
|
|
8333
|
-
const
|
|
8345
|
+
const j = R.modules[r.current.currentModuleIndex], oe = r.current.currentLessonIndex < (j?.lessons?.length || 0) - 1, X = r.current.currentModuleIndex < (R.modules?.length || 0) - 1, q = oe || X;
|
|
8334
8346
|
h.current.onCustomAction({
|
|
8335
8347
|
type: "lessonStart",
|
|
8336
8348
|
moduleIndex: r.current.currentModuleIndex,
|
|
8337
8349
|
lessonIndex: r.current.currentLessonIndex,
|
|
8338
|
-
hasNextLesson:
|
|
8350
|
+
hasNextLesson: q
|
|
8339
8351
|
}), h.current.onLessonStart({
|
|
8340
8352
|
moduleIndex: r.current.currentModuleIndex,
|
|
8341
8353
|
lessonIndex: r.current.currentLessonIndex,
|
|
8342
|
-
lesson:
|
|
8354
|
+
lesson: y()
|
|
8343
8355
|
}), c.current && (c.current.setMood("happy"), c.current.setBodyMovement("idle"));
|
|
8344
8356
|
} else
|
|
8345
|
-
|
|
8346
|
-
}, []),
|
|
8347
|
-
const R =
|
|
8357
|
+
L.current && L.current();
|
|
8358
|
+
}, []), D = W(() => {
|
|
8359
|
+
const R = y();
|
|
8348
8360
|
let v = null;
|
|
8349
8361
|
if (R?.avatar_script && R?.body) {
|
|
8350
|
-
const
|
|
8351
|
-
v = `${
|
|
8362
|
+
const N = R.avatar_script.trim(), B = R.body.trim(), j = N.match(/[.!?]$/) ? " " : ". ";
|
|
8363
|
+
v = `${N}${j}${B}`;
|
|
8352
8364
|
} else
|
|
8353
8365
|
v = R?.avatar_script || R?.body || null;
|
|
8354
8366
|
if (c.current && c.current.isReady && v) {
|
|
8355
8367
|
r.current.isTeaching = !0, r.current.isQuestionMode = !1, r.current.score = 0, r.current.totalQuestions = 0, c.current.setMood("happy");
|
|
8356
|
-
let
|
|
8368
|
+
let N = !1;
|
|
8357
8369
|
if (e.teaching)
|
|
8358
8370
|
try {
|
|
8359
|
-
c.current.playAnimation(e.teaching, !0),
|
|
8360
|
-
} catch (
|
|
8361
|
-
console.warn("Failed to play teaching animation:",
|
|
8371
|
+
c.current.playAnimation(e.teaching, !0), N = !0;
|
|
8372
|
+
} catch (j) {
|
|
8373
|
+
console.warn("Failed to play teaching animation:", j);
|
|
8362
8374
|
}
|
|
8363
|
-
|
|
8364
|
-
const
|
|
8375
|
+
N || c.current.setBodyMovement("gesturing");
|
|
8376
|
+
const B = M.current || { lipsyncLang: "en" };
|
|
8365
8377
|
h.current.onLessonStart({
|
|
8366
8378
|
moduleIndex: r.current.currentModuleIndex,
|
|
8367
8379
|
lessonIndex: r.current.currentLessonIndex,
|
|
@@ -8372,7 +8384,7 @@ const Vt = Ke(({
|
|
|
8372
8384
|
lessonIndex: r.current.currentLessonIndex,
|
|
8373
8385
|
lesson: R
|
|
8374
8386
|
}), c.current.speakText(v, {
|
|
8375
|
-
lipsyncLang:
|
|
8387
|
+
lipsyncLang: B.lipsyncLang,
|
|
8376
8388
|
onSpeechEnd: () => {
|
|
8377
8389
|
r.current.isTeaching = !1, h.current.onCustomAction({
|
|
8378
8390
|
type: "teachingComplete",
|
|
@@ -8390,17 +8402,17 @@ const Vt = Ke(({
|
|
|
8390
8402
|
}
|
|
8391
8403
|
});
|
|
8392
8404
|
}
|
|
8393
|
-
}, [e.teaching,
|
|
8394
|
-
const v =
|
|
8395
|
-
if (
|
|
8405
|
+
}, [e.teaching, y]), K = W((R) => {
|
|
8406
|
+
const v = E(), N = S(R, v);
|
|
8407
|
+
if (N && (r.current.score += 1), h.current.onQuestionAnswer({
|
|
8396
8408
|
moduleIndex: r.current.currentModuleIndex,
|
|
8397
8409
|
lessonIndex: r.current.currentLessonIndex,
|
|
8398
8410
|
questionIndex: r.current.currentQuestionIndex,
|
|
8399
8411
|
answer: R,
|
|
8400
|
-
isCorrect:
|
|
8412
|
+
isCorrect: N,
|
|
8401
8413
|
question: v
|
|
8402
8414
|
}), c.current)
|
|
8403
|
-
if (
|
|
8415
|
+
if (N) {
|
|
8404
8416
|
if (c.current.setMood("happy"), e.correct)
|
|
8405
8417
|
try {
|
|
8406
8418
|
c.current.playReaction("happy");
|
|
@@ -8408,13 +8420,13 @@ const Vt = Ke(({
|
|
|
8408
8420
|
c.current.setBodyMovement("happy");
|
|
8409
8421
|
}
|
|
8410
8422
|
c.current.setBodyMovement("gesturing");
|
|
8411
|
-
const
|
|
8412
|
-
r.current.currentQuestionIndex >=
|
|
8413
|
-
const
|
|
8414
|
-
console.log("[CurriculumLearning] Answer feedback - questionIndex:", r.current.currentQuestionIndex, "totalQuestions:",
|
|
8415
|
-
const
|
|
8416
|
-
c.current.speakText(
|
|
8417
|
-
lipsyncLang:
|
|
8423
|
+
const j = y()?.questions?.length || 0;
|
|
8424
|
+
r.current.currentQuestionIndex >= j - 1;
|
|
8425
|
+
const oe = r.current.currentQuestionIndex < j - 1;
|
|
8426
|
+
console.log("[CurriculumLearning] Answer feedback - questionIndex:", r.current.currentQuestionIndex, "totalQuestions:", j, "hasNextQuestion:", oe);
|
|
8427
|
+
const X = v.type === "code_test" ? `Great job! Your code passed all the tests! ${v.explanation || ""}` : `Excellent! That's correct! ${v.explanation || ""}`, q = M.current || { lipsyncLang: "en" };
|
|
8428
|
+
c.current.speakText(X, {
|
|
8429
|
+
lipsyncLang: q.lipsyncLang,
|
|
8418
8430
|
onSpeechEnd: () => {
|
|
8419
8431
|
h.current.onCustomAction({
|
|
8420
8432
|
type: "answerFeedbackComplete",
|
|
@@ -8422,7 +8434,7 @@ const Vt = Ke(({
|
|
|
8422
8434
|
lessonIndex: r.current.currentLessonIndex,
|
|
8423
8435
|
questionIndex: r.current.currentQuestionIndex,
|
|
8424
8436
|
isCorrect: !0,
|
|
8425
|
-
hasNextQuestion:
|
|
8437
|
+
hasNextQuestion: oe,
|
|
8426
8438
|
score: r.current.score,
|
|
8427
8439
|
totalQuestions: r.current.totalQuestions
|
|
8428
8440
|
});
|
|
@@ -8436,11 +8448,11 @@ const Vt = Ke(({
|
|
|
8436
8448
|
c.current.setBodyMovement("idle");
|
|
8437
8449
|
}
|
|
8438
8450
|
c.current.setBodyMovement("gesturing");
|
|
8439
|
-
const
|
|
8440
|
-
console.log("[CurriculumLearning] Answer feedback (incorrect) - questionIndex:", r.current.currentQuestionIndex, "totalQuestions:",
|
|
8441
|
-
const
|
|
8442
|
-
c.current.speakText(
|
|
8443
|
-
lipsyncLang:
|
|
8451
|
+
const j = y()?.questions?.length || 0, oe = r.current.currentQuestionIndex >= j - 1, X = r.current.currentQuestionIndex < j - 1;
|
|
8452
|
+
console.log("[CurriculumLearning] Answer feedback (incorrect) - questionIndex:", r.current.currentQuestionIndex, "totalQuestions:", j, "hasNextQuestion:", X);
|
|
8453
|
+
const q = v.type === "code_test" ? `Your code didn't pass all the tests. ${v.explanation || "Try again!"}` : `Not quite right, but don't worry! ${v.explanation || ""}${oe ? "" : " Let's move on to the next question."}`, Se = M.current || { lipsyncLang: "en" };
|
|
8454
|
+
c.current.speakText(q, {
|
|
8455
|
+
lipsyncLang: Se.lipsyncLang,
|
|
8444
8456
|
onSpeechEnd: () => {
|
|
8445
8457
|
h.current.onCustomAction({
|
|
8446
8458
|
type: "answerFeedbackComplete",
|
|
@@ -8448,7 +8460,7 @@ const Vt = Ke(({
|
|
|
8448
8460
|
lessonIndex: r.current.currentLessonIndex,
|
|
8449
8461
|
questionIndex: r.current.currentQuestionIndex,
|
|
8450
8462
|
isCorrect: !1,
|
|
8451
|
-
hasNextQuestion:
|
|
8463
|
+
hasNextQuestion: X,
|
|
8452
8464
|
score: r.current.score,
|
|
8453
8465
|
totalQuestions: r.current.totalQuestions
|
|
8454
8466
|
});
|
|
@@ -8456,21 +8468,21 @@ const Vt = Ke(({
|
|
|
8456
8468
|
});
|
|
8457
8469
|
}
|
|
8458
8470
|
else {
|
|
8459
|
-
const
|
|
8471
|
+
const j = y()?.questions?.length || 0;
|
|
8460
8472
|
h.current.onCustomAction({
|
|
8461
8473
|
type: "answerFeedbackComplete",
|
|
8462
8474
|
moduleIndex: r.current.currentModuleIndex,
|
|
8463
8475
|
lessonIndex: r.current.currentLessonIndex,
|
|
8464
8476
|
questionIndex: r.current.currentQuestionIndex,
|
|
8465
|
-
isCorrect:
|
|
8466
|
-
hasNextQuestion: r.current.currentQuestionIndex <
|
|
8477
|
+
isCorrect: N,
|
|
8478
|
+
hasNextQuestion: r.current.currentQuestionIndex < j - 1,
|
|
8467
8479
|
score: r.current.score,
|
|
8468
8480
|
totalQuestions: r.current.totalQuestions,
|
|
8469
8481
|
avatarNotReady: !0
|
|
8470
8482
|
});
|
|
8471
8483
|
}
|
|
8472
|
-
}, [e.correct, e.incorrect,
|
|
8473
|
-
const v =
|
|
8484
|
+
}, [e.correct, e.incorrect, E, y, S]), fe = W((R) => {
|
|
8485
|
+
const v = E();
|
|
8474
8486
|
if (!R || typeof R != "object") {
|
|
8475
8487
|
console.error("Invalid code test result format. Expected object with {passed: boolean, ...}");
|
|
8476
8488
|
return;
|
|
@@ -8479,7 +8491,7 @@ const Vt = Ke(({
|
|
|
8479
8491
|
console.warn("Current question is not a code test. Use handleAnswerSelect for other question types.");
|
|
8480
8492
|
return;
|
|
8481
8493
|
}
|
|
8482
|
-
const
|
|
8494
|
+
const N = {
|
|
8483
8495
|
passed: R.passed === !0,
|
|
8484
8496
|
results: R.results || [],
|
|
8485
8497
|
output: R.output || "",
|
|
@@ -8494,13 +8506,13 @@ const Vt = Ke(({
|
|
|
8494
8506
|
moduleIndex: r.current.currentModuleIndex,
|
|
8495
8507
|
lessonIndex: r.current.currentLessonIndex,
|
|
8496
8508
|
questionIndex: r.current.currentQuestionIndex,
|
|
8497
|
-
testResult:
|
|
8509
|
+
testResult: N,
|
|
8498
8510
|
question: v
|
|
8499
|
-
}),
|
|
8500
|
-
}, [
|
|
8511
|
+
}), g.current && g.current(N);
|
|
8512
|
+
}, [E, S]), xe = W(() => {
|
|
8501
8513
|
if (r.current.currentQuestionIndex > 0) {
|
|
8502
8514
|
r.current.currentQuestionIndex -= 1;
|
|
8503
|
-
const R =
|
|
8515
|
+
const R = E();
|
|
8504
8516
|
R && h.current.onCustomAction({
|
|
8505
8517
|
type: "questionStart",
|
|
8506
8518
|
moduleIndex: r.current.currentModuleIndex,
|
|
@@ -8513,26 +8525,26 @@ const Vt = Ke(({
|
|
|
8513
8525
|
const v = () => {
|
|
8514
8526
|
if (!c.current || !R) return;
|
|
8515
8527
|
c.current.setMood("happy"), c.current.setBodyMovement("idle");
|
|
8516
|
-
const
|
|
8528
|
+
const N = M.current || { lipsyncLang: "en" };
|
|
8517
8529
|
R.type === "code_test" ? c.current.speakText(`Let's go back to this coding challenge: ${R.question}`, {
|
|
8518
|
-
lipsyncLang:
|
|
8530
|
+
lipsyncLang: N.lipsyncLang
|
|
8519
8531
|
}) : c.current.speakText(`Going back to: ${R.question}`, {
|
|
8520
|
-
lipsyncLang:
|
|
8532
|
+
lipsyncLang: N.lipsyncLang
|
|
8521
8533
|
});
|
|
8522
8534
|
};
|
|
8523
8535
|
if (c.current && c.current.isReady && R)
|
|
8524
8536
|
v();
|
|
8525
8537
|
else if (R) {
|
|
8526
|
-
const
|
|
8527
|
-
c.current && c.current.isReady && (clearInterval(
|
|
8538
|
+
const N = setInterval(() => {
|
|
8539
|
+
c.current && c.current.isReady && (clearInterval(N), v());
|
|
8528
8540
|
}, 100);
|
|
8529
8541
|
setTimeout(() => {
|
|
8530
|
-
clearInterval(
|
|
8542
|
+
clearInterval(N);
|
|
8531
8543
|
}, 5e3);
|
|
8532
8544
|
}
|
|
8533
8545
|
}
|
|
8534
|
-
}, [
|
|
8535
|
-
const R =
|
|
8546
|
+
}, [E]), Te = W(() => {
|
|
8547
|
+
const R = H.current || { modules: [] };
|
|
8536
8548
|
if (R.modules[r.current.currentModuleIndex], r.current.currentLessonIndex > 0)
|
|
8537
8549
|
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({
|
|
8538
8550
|
type: "lessonStart",
|
|
@@ -8541,54 +8553,54 @@ const Vt = Ke(({
|
|
|
8541
8553
|
}), h.current.onLessonStart({
|
|
8542
8554
|
moduleIndex: r.current.currentModuleIndex,
|
|
8543
8555
|
lessonIndex: r.current.currentLessonIndex,
|
|
8544
|
-
lesson:
|
|
8556
|
+
lesson: y()
|
|
8545
8557
|
}), c.current && (c.current.setMood("happy"), c.current.setBodyMovement("idle"));
|
|
8546
8558
|
else if (r.current.currentModuleIndex > 0) {
|
|
8547
|
-
const
|
|
8548
|
-
r.current.currentModuleIndex -= 1, r.current.currentLessonIndex = (
|
|
8559
|
+
const B = R.modules[r.current.currentModuleIndex - 1];
|
|
8560
|
+
r.current.currentModuleIndex -= 1, r.current.currentLessonIndex = (B?.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({
|
|
8549
8561
|
type: "lessonStart",
|
|
8550
8562
|
moduleIndex: r.current.currentModuleIndex,
|
|
8551
8563
|
lessonIndex: r.current.currentLessonIndex
|
|
8552
8564
|
}), h.current.onLessonStart({
|
|
8553
8565
|
moduleIndex: r.current.currentModuleIndex,
|
|
8554
8566
|
lessonIndex: r.current.currentLessonIndex,
|
|
8555
|
-
lesson:
|
|
8567
|
+
lesson: y()
|
|
8556
8568
|
}), c.current && (c.current.setMood("happy"), c.current.setBodyMovement("idle"));
|
|
8557
8569
|
}
|
|
8558
|
-
}, [
|
|
8570
|
+
}, [y]), Le = W(() => {
|
|
8559
8571
|
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;
|
|
8560
|
-
}, []),
|
|
8572
|
+
}, []), Me = W((R) => {
|
|
8561
8573
|
console.log("Avatar is ready!", R);
|
|
8562
|
-
const v =
|
|
8563
|
-
u &&
|
|
8574
|
+
const v = y(), N = v?.avatar_script || v?.body;
|
|
8575
|
+
u && N && setTimeout(() => {
|
|
8564
8576
|
d.current && d.current();
|
|
8565
8577
|
}, 10);
|
|
8566
|
-
}, [u,
|
|
8567
|
-
|
|
8568
|
-
d.current =
|
|
8578
|
+
}, [u, y]);
|
|
8579
|
+
ft(() => {
|
|
8580
|
+
d.current = D, p.current = P, b.current = C, f.current = G, L.current = x, Q.current = I, g.current = K;
|
|
8569
8581
|
}), $e(l, () => ({
|
|
8570
8582
|
// Curriculum control methods
|
|
8571
|
-
startTeaching:
|
|
8583
|
+
startTeaching: D,
|
|
8572
8584
|
startQuestions: I,
|
|
8573
|
-
handleAnswerSelect:
|
|
8574
|
-
handleCodeTestResult:
|
|
8575
|
-
nextQuestion:
|
|
8576
|
-
previousQuestion:
|
|
8585
|
+
handleAnswerSelect: K,
|
|
8586
|
+
handleCodeTestResult: fe,
|
|
8587
|
+
nextQuestion: G,
|
|
8588
|
+
previousQuestion: xe,
|
|
8577
8589
|
nextLesson: P,
|
|
8578
|
-
previousLesson:
|
|
8579
|
-
completeLesson:
|
|
8580
|
-
completeCurriculum:
|
|
8581
|
-
resetCurriculum:
|
|
8590
|
+
previousLesson: Te,
|
|
8591
|
+
completeLesson: C,
|
|
8592
|
+
completeCurriculum: x,
|
|
8593
|
+
resetCurriculum: Le,
|
|
8582
8594
|
getState: () => ({ ...r.current }),
|
|
8583
|
-
getCurrentQuestion: () =>
|
|
8584
|
-
getCurrentLesson: () =>
|
|
8595
|
+
getCurrentQuestion: () => E(),
|
|
8596
|
+
getCurrentLesson: () => y(),
|
|
8585
8597
|
// Direct access to avatar ref (always returns current value)
|
|
8586
8598
|
getAvatarRef: () => c.current,
|
|
8587
8599
|
// Convenience methods that delegate to avatar (always check current ref)
|
|
8588
8600
|
speakText: async (R, v = {}) => {
|
|
8589
8601
|
await c.current?.resumeAudioContext?.();
|
|
8590
|
-
const
|
|
8591
|
-
c.current?.speakText(R, { ...v, lipsyncLang: v.lipsyncLang ||
|
|
8602
|
+
const N = M.current || { lipsyncLang: "en" };
|
|
8603
|
+
c.current?.speakText(R, { ...v, lipsyncLang: v.lipsyncLang || N.lipsyncLang });
|
|
8592
8604
|
},
|
|
8593
8605
|
resumeAudioContext: async () => {
|
|
8594
8606
|
if (c.current?.resumeAudioContext)
|
|
@@ -8599,8 +8611,8 @@ const Vt = Ke(({
|
|
|
8599
8611
|
if (v.state === "suspended" || v.state === "interrupted")
|
|
8600
8612
|
try {
|
|
8601
8613
|
await v.resume(), console.log("Audio context resumed via talkingHead");
|
|
8602
|
-
} catch (
|
|
8603
|
-
console.warn("Failed to resume audio context:",
|
|
8614
|
+
} catch (N) {
|
|
8615
|
+
console.warn("Failed to resume audio context:", N);
|
|
8604
8616
|
}
|
|
8605
8617
|
} else
|
|
8606
8618
|
console.warn("Audio context not available yet");
|
|
@@ -8632,8 +8644,8 @@ const Vt = Ke(({
|
|
|
8632
8644
|
handleResize: () => c.current?.handleResize(),
|
|
8633
8645
|
// Avatar readiness check (always returns current value)
|
|
8634
8646
|
isAvatarReady: () => c.current?.isReady || !1
|
|
8635
|
-
}), [
|
|
8636
|
-
const
|
|
8647
|
+
}), [D, I, K, fe, G, P, C, x, Le, E, y]);
|
|
8648
|
+
const ae = M.current || {
|
|
8637
8649
|
avatarUrl: "/avatars/brunette.glb",
|
|
8638
8650
|
avatarBody: "F",
|
|
8639
8651
|
mood: "happy",
|
|
@@ -8646,23 +8658,23 @@ const Vt = Ke(({
|
|
|
8646
8658
|
showFullAvatar: !1,
|
|
8647
8659
|
animations: e
|
|
8648
8660
|
};
|
|
8649
|
-
return /* @__PURE__ */
|
|
8650
|
-
|
|
8661
|
+
return /* @__PURE__ */ le("div", { style: { width: "100%", height: "100%" }, children: /* @__PURE__ */ le(
|
|
8662
|
+
ct,
|
|
8651
8663
|
{
|
|
8652
8664
|
ref: c,
|
|
8653
|
-
avatarUrl:
|
|
8654
|
-
avatarBody:
|
|
8655
|
-
mood:
|
|
8656
|
-
ttsLang:
|
|
8657
|
-
ttsService:
|
|
8658
|
-
ttsVoice:
|
|
8659
|
-
ttsApiKey:
|
|
8660
|
-
bodyMovement:
|
|
8661
|
-
movementIntensity:
|
|
8662
|
-
showFullAvatar:
|
|
8665
|
+
avatarUrl: ae.avatarUrl,
|
|
8666
|
+
avatarBody: ae.avatarBody,
|
|
8667
|
+
mood: ae.mood,
|
|
8668
|
+
ttsLang: ae.ttsLang,
|
|
8669
|
+
ttsService: ae.ttsService,
|
|
8670
|
+
ttsVoice: ae.ttsVoice,
|
|
8671
|
+
ttsApiKey: ae.ttsApiKey,
|
|
8672
|
+
bodyMovement: ae.bodyMovement,
|
|
8673
|
+
movementIntensity: ae.movementIntensity,
|
|
8674
|
+
showFullAvatar: ae.showFullAvatar,
|
|
8663
8675
|
cameraView: "upper",
|
|
8664
|
-
animations:
|
|
8665
|
-
onReady:
|
|
8676
|
+
animations: ae.animations,
|
|
8677
|
+
onReady: Me,
|
|
8666
8678
|
onLoading: () => {
|
|
8667
8679
|
},
|
|
8668
8680
|
onError: (R) => {
|
|
@@ -8671,115 +8683,115 @@ const Vt = Ke(({
|
|
|
8671
8683
|
}
|
|
8672
8684
|
) });
|
|
8673
8685
|
});
|
|
8674
|
-
|
|
8675
|
-
function
|
|
8676
|
-
manifestPath:
|
|
8686
|
+
Xt.displayName = "CurriculumLearning";
|
|
8687
|
+
function Jt({
|
|
8688
|
+
manifestPath: Y = "/animations/manifest.json",
|
|
8677
8689
|
avatarBody: n = "F",
|
|
8678
8690
|
onAnimationPlay: e = null,
|
|
8679
8691
|
onAnimationsSelected: t = null,
|
|
8680
8692
|
onDeleteAnimations: o = null,
|
|
8681
8693
|
style: s = {}
|
|
8682
8694
|
}) {
|
|
8683
|
-
const [i, a] =
|
|
8684
|
-
|
|
8695
|
+
const [i, a] = ge([]), [u, l] = ge(/* @__PURE__ */ new Set()), [c, r] = ge(!0), [h, d] = ge(null), [p, b] = ge("all"), [f, L] = ge("");
|
|
8696
|
+
ze(() => {
|
|
8685
8697
|
(async () => {
|
|
8686
8698
|
r(!0), d(null);
|
|
8687
8699
|
try {
|
|
8688
|
-
const
|
|
8689
|
-
if (
|
|
8700
|
+
const x = await je(Y), I = [];
|
|
8701
|
+
if (x._genderSpecific) {
|
|
8690
8702
|
const P = (n?.toUpperCase() || "F") === "M" ? "male" : "female";
|
|
8691
|
-
|
|
8692
|
-
(Array.isArray(
|
|
8703
|
+
x._genderSpecific[P] && Object.entries(x._genderSpecific[P]).forEach(([D, K]) => {
|
|
8704
|
+
(Array.isArray(K) ? K : [K]).forEach((xe) => {
|
|
8693
8705
|
I.push({
|
|
8694
|
-
path:
|
|
8695
|
-
group:
|
|
8706
|
+
path: xe,
|
|
8707
|
+
group: D,
|
|
8696
8708
|
gender: P,
|
|
8697
|
-
name:
|
|
8709
|
+
name: xe.split("/").pop().replace(".fbx", "")
|
|
8698
8710
|
});
|
|
8699
8711
|
});
|
|
8700
|
-
}),
|
|
8701
|
-
(Array.isArray(
|
|
8712
|
+
}), x._genderSpecific.shared && Object.entries(x._genderSpecific.shared).forEach(([D, K]) => {
|
|
8713
|
+
(Array.isArray(K) ? K : [K]).forEach((xe) => {
|
|
8702
8714
|
I.push({
|
|
8703
|
-
path:
|
|
8704
|
-
group:
|
|
8715
|
+
path: xe,
|
|
8716
|
+
group: D,
|
|
8705
8717
|
gender: "shared",
|
|
8706
|
-
name:
|
|
8718
|
+
name: xe.split("/").pop().replace(".fbx", "")
|
|
8707
8719
|
});
|
|
8708
8720
|
});
|
|
8709
8721
|
});
|
|
8710
8722
|
}
|
|
8711
|
-
Object.entries(
|
|
8712
|
-
|
|
8713
|
-
typeof
|
|
8714
|
-
path:
|
|
8715
|
-
group:
|
|
8723
|
+
Object.entries(x).forEach(([G, P]) => {
|
|
8724
|
+
G !== "_genderSpecific" && (Array.isArray(P) ? P : [P]).forEach((K) => {
|
|
8725
|
+
typeof K == "string" && I.push({
|
|
8726
|
+
path: K,
|
|
8727
|
+
group: G,
|
|
8716
8728
|
gender: "root",
|
|
8717
|
-
name:
|
|
8729
|
+
name: K.split("/").pop().replace(".fbx", "")
|
|
8718
8730
|
});
|
|
8719
8731
|
});
|
|
8720
8732
|
}), a(I), r(!1);
|
|
8721
|
-
} catch (
|
|
8722
|
-
console.error("Failed to load animations:",
|
|
8733
|
+
} catch (x) {
|
|
8734
|
+
console.error("Failed to load animations:", x), d(x.message), r(!1);
|
|
8723
8735
|
}
|
|
8724
8736
|
})();
|
|
8725
|
-
}, [
|
|
8726
|
-
const
|
|
8727
|
-
const
|
|
8728
|
-
return
|
|
8729
|
-
}),
|
|
8730
|
-
const
|
|
8731
|
-
|
|
8732
|
-
},
|
|
8733
|
-
const
|
|
8734
|
-
|
|
8735
|
-
|
|
8736
|
-
}), l(
|
|
8737
|
-
},
|
|
8738
|
-
const
|
|
8739
|
-
|
|
8740
|
-
|
|
8741
|
-
}), l(
|
|
8742
|
-
},
|
|
8743
|
-
const
|
|
8744
|
-
if (
|
|
8737
|
+
}, [Y, n]);
|
|
8738
|
+
const Q = ["all", ...new Set(i.map((C) => C.group))], g = i.filter((C) => {
|
|
8739
|
+
const x = p === "all" || C.group === p, I = f === "" || C.name.toLowerCase().includes(f.toLowerCase()) || C.path.toLowerCase().includes(f.toLowerCase());
|
|
8740
|
+
return x && I;
|
|
8741
|
+
}), H = (C) => {
|
|
8742
|
+
const x = new Set(u);
|
|
8743
|
+
x.has(C) ? x.delete(C) : x.add(C), l(x), t && t(Array.from(x));
|
|
8744
|
+
}, M = () => {
|
|
8745
|
+
const C = new Set(u);
|
|
8746
|
+
g.forEach((x) => {
|
|
8747
|
+
C.add(x.path);
|
|
8748
|
+
}), l(C), t && t(Array.from(C));
|
|
8749
|
+
}, y = () => {
|
|
8750
|
+
const C = new Set(u);
|
|
8751
|
+
g.forEach((x) => {
|
|
8752
|
+
C.delete(x.path);
|
|
8753
|
+
}), l(C), t && t(Array.from(C));
|
|
8754
|
+
}, E = () => {
|
|
8755
|
+
const x = i.filter((I) => !u.has(I.path)).map((I) => I.path);
|
|
8756
|
+
if (x.length === 0) {
|
|
8745
8757
|
alert("No animations to delete. Select animations to keep, then delete will remove the unselected ones.");
|
|
8746
8758
|
return;
|
|
8747
8759
|
}
|
|
8748
|
-
window.confirm(`Are you sure you want to delete ${
|
|
8760
|
+
window.confirm(`Are you sure you want to delete ${x.length} animation(s)?
|
|
8749
8761
|
|
|
8750
8762
|
This will delete:
|
|
8751
|
-
${
|
|
8752
|
-
`)}${
|
|
8753
|
-
...` : ""}`) && (o && o(
|
|
8754
|
-
},
|
|
8755
|
-
e && e(
|
|
8763
|
+
${x.slice(0, 5).join(`
|
|
8764
|
+
`)}${x.length > 5 ? `
|
|
8765
|
+
...` : ""}`) && (o && o(x), a(i.filter((I) => u.has(I.path))), l(/* @__PURE__ */ new Set()));
|
|
8766
|
+
}, S = (C) => {
|
|
8767
|
+
e && e(C);
|
|
8756
8768
|
};
|
|
8757
|
-
return c ? /* @__PURE__ */
|
|
8769
|
+
return c ? /* @__PURE__ */ le("div", { style: { padding: "20px", textAlign: "center", ...s }, children: /* @__PURE__ */ le("p", { children: "Loading animations..." }) }) : h ? /* @__PURE__ */ le("div", { style: { padding: "20px", color: "red", ...s }, children: /* @__PURE__ */ Ee("p", { children: [
|
|
8758
8770
|
"Error loading animations: ",
|
|
8759
8771
|
h
|
|
8760
|
-
] }) }) : /* @__PURE__ */
|
|
8772
|
+
] }) }) : /* @__PURE__ */ Ee("div", { style: {
|
|
8761
8773
|
padding: "20px",
|
|
8762
8774
|
backgroundColor: "#2a2a2a",
|
|
8763
8775
|
borderRadius: "8px",
|
|
8764
8776
|
color: "#fff",
|
|
8765
8777
|
...s
|
|
8766
8778
|
}, children: [
|
|
8767
|
-
/* @__PURE__ */
|
|
8768
|
-
/* @__PURE__ */
|
|
8769
|
-
/* @__PURE__ */
|
|
8779
|
+
/* @__PURE__ */ le("h2", { style: { marginTop: 0 }, children: "Animation Selector" }),
|
|
8780
|
+
/* @__PURE__ */ le("p", { style: { color: "#aaa", fontSize: "14px" }, children: "Click buttons to play animations. Select animations to keep, then delete will remove the rest." }),
|
|
8781
|
+
/* @__PURE__ */ Ee("div", { style: {
|
|
8770
8782
|
display: "flex",
|
|
8771
8783
|
gap: "10px",
|
|
8772
8784
|
marginBottom: "20px",
|
|
8773
8785
|
flexWrap: "wrap",
|
|
8774
8786
|
alignItems: "center"
|
|
8775
8787
|
}, children: [
|
|
8776
|
-
/* @__PURE__ */
|
|
8788
|
+
/* @__PURE__ */ le(
|
|
8777
8789
|
"input",
|
|
8778
8790
|
{
|
|
8779
8791
|
type: "text",
|
|
8780
8792
|
placeholder: "Search animations...",
|
|
8781
|
-
value:
|
|
8782
|
-
onChange: (
|
|
8793
|
+
value: f,
|
|
8794
|
+
onChange: (C) => L(C.target.value),
|
|
8783
8795
|
style: {
|
|
8784
8796
|
padding: "8px 12px",
|
|
8785
8797
|
borderRadius: "6px",
|
|
@@ -8792,11 +8804,11 @@ ${M.slice(0, 5).join(`
|
|
|
8792
8804
|
}
|
|
8793
8805
|
}
|
|
8794
8806
|
),
|
|
8795
|
-
/* @__PURE__ */
|
|
8807
|
+
/* @__PURE__ */ le(
|
|
8796
8808
|
"select",
|
|
8797
8809
|
{
|
|
8798
|
-
value:
|
|
8799
|
-
onChange: (
|
|
8810
|
+
value: p,
|
|
8811
|
+
onChange: (C) => b(C.target.value),
|
|
8800
8812
|
style: {
|
|
8801
8813
|
padding: "8px 12px",
|
|
8802
8814
|
borderRadius: "6px",
|
|
@@ -8805,13 +8817,13 @@ ${M.slice(0, 5).join(`
|
|
|
8805
8817
|
color: "#fff",
|
|
8806
8818
|
fontSize: "14px"
|
|
8807
8819
|
},
|
|
8808
|
-
children:
|
|
8820
|
+
children: Q.map((C) => /* @__PURE__ */ le("option", { value: C, children: C === "all" ? "All Groups" : C }, C))
|
|
8809
8821
|
}
|
|
8810
8822
|
),
|
|
8811
|
-
/* @__PURE__ */
|
|
8823
|
+
/* @__PURE__ */ le(
|
|
8812
8824
|
"button",
|
|
8813
8825
|
{
|
|
8814
|
-
onClick:
|
|
8826
|
+
onClick: M,
|
|
8815
8827
|
style: {
|
|
8816
8828
|
padding: "8px 16px",
|
|
8817
8829
|
backgroundColor: "#4CAF50",
|
|
@@ -8824,10 +8836,10 @@ ${M.slice(0, 5).join(`
|
|
|
8824
8836
|
children: "Select All Visible"
|
|
8825
8837
|
}
|
|
8826
8838
|
),
|
|
8827
|
-
/* @__PURE__ */
|
|
8839
|
+
/* @__PURE__ */ le(
|
|
8828
8840
|
"button",
|
|
8829
8841
|
{
|
|
8830
|
-
onClick:
|
|
8842
|
+
onClick: y,
|
|
8831
8843
|
style: {
|
|
8832
8844
|
padding: "8px 16px",
|
|
8833
8845
|
backgroundColor: "#666",
|
|
@@ -8840,10 +8852,10 @@ ${M.slice(0, 5).join(`
|
|
|
8840
8852
|
children: "Deselect All Visible"
|
|
8841
8853
|
}
|
|
8842
8854
|
),
|
|
8843
|
-
/* @__PURE__ */
|
|
8855
|
+
/* @__PURE__ */ Ee(
|
|
8844
8856
|
"button",
|
|
8845
8857
|
{
|
|
8846
|
-
onClick:
|
|
8858
|
+
onClick: E,
|
|
8847
8859
|
style: {
|
|
8848
8860
|
padding: "8px 16px",
|
|
8849
8861
|
backgroundColor: "#f44336",
|
|
@@ -8862,7 +8874,7 @@ ${M.slice(0, 5).join(`
|
|
|
8862
8874
|
}
|
|
8863
8875
|
)
|
|
8864
8876
|
] }),
|
|
8865
|
-
/* @__PURE__ */
|
|
8877
|
+
/* @__PURE__ */ Ee("div", { style: {
|
|
8866
8878
|
marginBottom: "15px",
|
|
8867
8879
|
fontSize: "14px",
|
|
8868
8880
|
color: "#aaa"
|
|
@@ -8872,9 +8884,9 @@ ${M.slice(0, 5).join(`
|
|
|
8872
8884
|
" | Selected: ",
|
|
8873
8885
|
u.size,
|
|
8874
8886
|
" | Showing: ",
|
|
8875
|
-
|
|
8887
|
+
g.length
|
|
8876
8888
|
] }),
|
|
8877
|
-
/* @__PURE__ */
|
|
8889
|
+
/* @__PURE__ */ le("div", { style: {
|
|
8878
8890
|
display: "grid",
|
|
8879
8891
|
gridTemplateColumns: "repeat(auto-fill, minmax(200px, 1fr))",
|
|
8880
8892
|
gap: "10px",
|
|
@@ -8883,9 +8895,9 @@ ${M.slice(0, 5).join(`
|
|
|
8883
8895
|
padding: "10px",
|
|
8884
8896
|
backgroundColor: "#1a1a1a",
|
|
8885
8897
|
borderRadius: "6px"
|
|
8886
|
-
}, children:
|
|
8887
|
-
const I = u.has(
|
|
8888
|
-
return /* @__PURE__ */
|
|
8898
|
+
}, children: g.map((C, x) => {
|
|
8899
|
+
const I = u.has(C.path);
|
|
8900
|
+
return /* @__PURE__ */ Ee(
|
|
8889
8901
|
"div",
|
|
8890
8902
|
{
|
|
8891
8903
|
style: {
|
|
@@ -8896,39 +8908,39 @@ ${M.slice(0, 5).join(`
|
|
|
8896
8908
|
cursor: "pointer",
|
|
8897
8909
|
transition: "all 0.2s"
|
|
8898
8910
|
},
|
|
8899
|
-
onClick: () =>
|
|
8911
|
+
onClick: () => H(C.path),
|
|
8900
8912
|
children: [
|
|
8901
|
-
/* @__PURE__ */
|
|
8902
|
-
/* @__PURE__ */
|
|
8913
|
+
/* @__PURE__ */ Ee("div", { style: { marginBottom: "8px" }, children: [
|
|
8914
|
+
/* @__PURE__ */ le(
|
|
8903
8915
|
"input",
|
|
8904
8916
|
{
|
|
8905
8917
|
type: "checkbox",
|
|
8906
8918
|
checked: I,
|
|
8907
|
-
onChange: () =>
|
|
8908
|
-
onClick: (
|
|
8919
|
+
onChange: () => H(C.path),
|
|
8920
|
+
onClick: (G) => G.stopPropagation(),
|
|
8909
8921
|
style: {
|
|
8910
8922
|
marginRight: "8px",
|
|
8911
8923
|
cursor: "pointer"
|
|
8912
8924
|
}
|
|
8913
8925
|
}
|
|
8914
8926
|
),
|
|
8915
|
-
/* @__PURE__ */
|
|
8916
|
-
|
|
8927
|
+
/* @__PURE__ */ Ee("span", { style: { fontSize: "12px", color: "#aaa" }, children: [
|
|
8928
|
+
C.group,
|
|
8917
8929
|
" ",
|
|
8918
|
-
|
|
8930
|
+
C.gender !== "root" && `(${C.gender})`
|
|
8919
8931
|
] })
|
|
8920
8932
|
] }),
|
|
8921
|
-
/* @__PURE__ */
|
|
8933
|
+
/* @__PURE__ */ le("div", { style: {
|
|
8922
8934
|
fontSize: "13px",
|
|
8923
8935
|
fontWeight: "bold",
|
|
8924
8936
|
marginBottom: "8px",
|
|
8925
8937
|
wordBreak: "break-word"
|
|
8926
|
-
}, children:
|
|
8927
|
-
/* @__PURE__ */
|
|
8938
|
+
}, children: C.name }),
|
|
8939
|
+
/* @__PURE__ */ le(
|
|
8928
8940
|
"button",
|
|
8929
8941
|
{
|
|
8930
|
-
onClick: (
|
|
8931
|
-
|
|
8942
|
+
onClick: (G) => {
|
|
8943
|
+
G.stopPropagation(), S(C.path);
|
|
8932
8944
|
},
|
|
8933
8945
|
style: {
|
|
8934
8946
|
width: "100%",
|
|
@@ -8945,17 +8957,17 @@ ${M.slice(0, 5).join(`
|
|
|
8945
8957
|
)
|
|
8946
8958
|
]
|
|
8947
8959
|
},
|
|
8948
|
-
`${
|
|
8960
|
+
`${C.path}-${x}`
|
|
8949
8961
|
);
|
|
8950
8962
|
}) }),
|
|
8951
|
-
|
|
8963
|
+
g.length === 0 && /* @__PURE__ */ le("div", { style: {
|
|
8952
8964
|
padding: "40px",
|
|
8953
8965
|
textAlign: "center",
|
|
8954
8966
|
color: "#aaa"
|
|
8955
8967
|
}, children: "No animations found matching your filters." })
|
|
8956
8968
|
] });
|
|
8957
8969
|
}
|
|
8958
|
-
const
|
|
8970
|
+
const ut = {
|
|
8959
8971
|
// Code-based dance animations (no FBX required)
|
|
8960
8972
|
dance: {
|
|
8961
8973
|
name: "dance",
|
|
@@ -9058,16 +9070,16 @@ const ht = {
|
|
|
9058
9070
|
duration: 5e3,
|
|
9059
9071
|
description: "Excited, energetic movement"
|
|
9060
9072
|
}
|
|
9061
|
-
},
|
|
9073
|
+
}, en = (Y) => ut[Y] || null, tn = (Y) => ut.hasOwnProperty(Y);
|
|
9062
9074
|
export {
|
|
9063
|
-
|
|
9064
|
-
|
|
9065
|
-
|
|
9066
|
-
|
|
9067
|
-
|
|
9068
|
-
|
|
9075
|
+
Jt as AnimationSelector,
|
|
9076
|
+
Xt as CurriculumLearning,
|
|
9077
|
+
Vt as SimpleTalkingAvatar,
|
|
9078
|
+
ct as TalkingHeadAvatar,
|
|
9079
|
+
Ut as TalkingHeadComponent,
|
|
9080
|
+
ut as animations,
|
|
9069
9081
|
Je as getActiveTTSConfig,
|
|
9070
|
-
|
|
9071
|
-
|
|
9072
|
-
|
|
9082
|
+
en as getAnimation,
|
|
9083
|
+
$t as getVoiceOptions,
|
|
9084
|
+
tn as hasAnimation
|
|
9073
9085
|
};
|