@sage-rsc/talking-head-react 1.0.70 → 1.0.71
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 +2 -2
- package/dist/index.js +459 -448
- package/package.json +1 -1
- package/src/components/SimpleTalkingAvatar.jsx +27 -9
package/dist/index.js
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
import { jsxs as Pe, jsx as
|
|
2
|
-
import { forwardRef as Me, useRef as
|
|
1
|
+
import { jsxs as Pe, jsx as me } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef as Me, useRef as D, useState as ce, useEffect as de, useCallback as T, useImperativeHandle as Ee, useLayoutEffect as Xe } from "react";
|
|
3
3
|
import * as x from "three";
|
|
4
4
|
import { OrbitControls as Ye } from "three/addons/controls/OrbitControls.js";
|
|
5
5
|
import { GLTFLoader as je } from "three/addons/loaders/GLTFLoader.js";
|
|
6
6
|
import { DRACOLoader as Qe } from "three/addons/loaders/DRACOLoader.js";
|
|
7
7
|
import { FBXLoader as Oe } from "three/addons/loaders/FBXLoader.js";
|
|
8
8
|
import { RoomEnvironment as qe } from "three/addons/environments/RoomEnvironment.js";
|
|
9
|
-
import
|
|
9
|
+
import Ke from "three/addons/libs/stats.module.js";
|
|
10
10
|
let m, re, ue;
|
|
11
11
|
const A = [0, 0, 0, 0], k = new x.Vector3(), ze = new x.Vector3(), ne = new x.Vector3(), Ce = new x.Vector3();
|
|
12
12
|
new x.Plane();
|
|
13
13
|
new x.Ray();
|
|
14
14
|
new x.Euler();
|
|
15
|
-
const ie = new x.Quaternion(), Ne = new x.Quaternion(),
|
|
15
|
+
const ie = new x.Quaternion(), Ne = new x.Quaternion(), fe = new x.Matrix4(), xe = new x.Matrix4();
|
|
16
16
|
new x.Vector3();
|
|
17
|
-
const He = new x.Vector3(0, 0, 1),
|
|
17
|
+
const He = new x.Vector3(0, 0, 1), _e = new x.Vector3(1, 0, 0), Je = new x.Vector3(0, 1, 0), $e = new x.Vector3(0, 0, 1);
|
|
18
18
|
class et {
|
|
19
19
|
constructor(t = null) {
|
|
20
20
|
this.opt = Object.assign({
|
|
@@ -356,22 +356,22 @@ class et {
|
|
|
356
356
|
for (this.timerMs += t, t > 1e3 && (this.timerMs = 0), t /= 1e3, e = 0, i = this.objectsUpdate.length; e < i; e++)
|
|
357
357
|
o = this.objectsUpdate[e], o.updateMatrix(), o.parent === null ? o.matrixWorld.copy(o.matrix) : o.matrixWorld.multiplyMatrices(o.parent.matrixWorld, o.matrix), o.matrixWorldNeedsUpdate = !1;
|
|
358
358
|
for (e = 0, i = this.data.length; e < i; e++) {
|
|
359
|
-
if (o = this.data[e], k.copy(o.vWorld),
|
|
359
|
+
if (o = this.data[e], k.copy(o.vWorld), fe.copy(o.boneParent.matrixWorld), xe.copy(fe).invert(), o.vWorld.setFromMatrixPosition(fe), k.applyMatrix4(xe), k.length() > 0.5 && (console.info("Info: Unrealistic jump of " + k.length().toFixed(2) + " meters."), k.setLength(0.5)), k.applyQuaternion(o.bone.quaternion), A[0] = k.x, A[1] = k.y, A[2] = -k.z, A[3] = k.length() / 3, o.children)
|
|
360
360
|
for (n = 0, s = o.children.length; n < s; n++)
|
|
361
361
|
m = o.children[n], A[0] -= m.v[0] * t / 3, A[1] -= m.v[1] * t / 3, A[2] += m.v[2] * t / 3, A[3] -= m.v[3] * t / 3;
|
|
362
362
|
if (m = this.opt.sensitivityFactor, A[0] *= o.ext * m, A[1] *= o.ext * m, A[2] *= o.ext * m, A[3] *= o.ext * m, o.isX && (m = A[0] / t, o.ea[0] = (m - o.ev[0]) / t, o.ev[0] = m, o.a[0] = -o.k[0] * o.p[0] - o.c[0] * o.v[0] - o.ea[0], o.p[0] += o.v[0] * t + o.a[0] * t * t / 2 + A[0], m = o.v[0] + o.a[0] * t / 2, m = -o.k[0] * o.p[0] - o.c[0] * m - o.ea[0], o.v[0] = o.v[0] + (m + o.a[0]) * t / 2), o.isY && (m = A[1] / t, o.ea[1] = (m - o.ev[1]) / t, o.ev[1] = m, o.a[1] = -o.k[1] * o.p[1] - o.c[1] * o.v[1] - o.ea[1], o.p[1] += o.v[1] * t + o.a[1] * t * t / 2 + A[1], m = o.v[1] + o.a[1] * t / 2, m = -o.k[1] * o.p[1] - o.c[1] * m - o.ea[1], o.v[1] = o.v[1] + (m + o.a[1]) * t / 2), o.isZ && (m = A[2] / t, o.ea[2] = (m - o.ev[2]) / t, o.ev[2] = m, o.a[2] = -o.k[2] * o.p[2] - o.c[2] * o.v[2] - o.ea[2], o.p[2] += o.v[2] * t + o.a[2] * t * t / 2 + A[2], m = o.v[2] + o.a[2] * t / 2, m = -o.k[2] * o.p[2] - o.c[2] * m - o.ea[2], o.v[2] = o.v[2] + (m + o.a[2]) * t / 2), o.isT && (m = A[3] / t, o.ea[3] = (m - o.ev[3]) / t, o.ev[3] = m, o.a[3] = -o.k[3] * o.p[3] - o.c[3] * o.v[3] - o.ea[3], o.p[3] += o.v[3] * t + o.a[3] * t * t / 2 + A[3], m = o.v[3] + o.a[3] * t / 2, m = -o.k[3] * o.p[3] - o.c[3] * m - o.ea[3], o.v[3] = o.v[3] + (m + o.a[3]) * t / 2), this.timerMs < this.opt.warmupMs && (o.v[0] *= 1e-4, o.p[0] *= 1e-4, o.v[1] *= 1e-4, o.p[1] *= 1e-4, o.v[2] *= 1e-4, o.p[2] *= 1e-4, o.v[3] *= 1e-4, o.p[3] *= 1e-4), A[0] = o.p[0], A[1] = o.p[1], A[2] = o.p[2], A[3] = o.p[3], m = this.opt.movementFactor, A[0] *= m, A[1] *= m, A[2] *= m, A[3] *= m, o.dl && (m = o.dl, A[0] += m[0], A[1] += m[1], A[2] += m[2]), o.dw && (m = o.dw, k.set(
|
|
363
363
|
o.vBasis.x + A[0],
|
|
364
364
|
o.vBasis.y + A[1],
|
|
365
365
|
o.vBasis.z + A[2]
|
|
366
|
-
), k.applyMatrix4(
|
|
366
|
+
), k.applyMatrix4(fe), k.x += m[0], k.y += m[1], k.z += m[2], k.applyMatrix4(xe), A[0] += k.x - o.vBasis.x, A[1] += k.y - o.vBasis.y, A[2] += k.z - o.vBasis.z), o.limits && this.opt.isLimits && (m = o.limits, m[0] && (m[0][0] !== null && A[0] < m[0][0] && (A[0] = m[0][0]), m[0][1] !== null && A[0] > m[0][1] && (A[0] = m[0][1])), m[1] && (m[1][0] !== null && A[1] < m[1][0] && (A[1] = m[1][0]), m[1][1] !== null && A[1] > m[1][1] && (A[1] = m[1][1])), m[2] && (m[2][0] !== null && A[2] < m[2][0] && (A[2] = m[2][0]), m[2][1] !== null && A[2] > m[2][1] && (A[2] = m[2][1])), m[3] && (m[3][0] !== null && A[3] < m[3][0] && (A[3] = m[3][0]), m[3][1] !== null && A[3] > m[3][1] && (A[3] = m[3][1]))), o.isPoint)
|
|
367
367
|
o.bone.position.set(
|
|
368
368
|
o.vBasis.x + A[0],
|
|
369
369
|
o.vBasis.y + A[1],
|
|
370
370
|
o.vBasis.z - A[2]
|
|
371
371
|
);
|
|
372
|
-
else if (o.boneParent.quaternion.copy(o.qBasis), o.pivot && this.opt.isPivots && (o.boneParent.updateWorldMatrix(!1, !1), o.boneParent.matrixWorld.decompose(k, ie, ne), k.copy(He).applyQuaternion(ie).setY(0).normalize(), ie.premultiply(Ne.setFromUnitVectors(He, k).invert()).normalize(), o.boneParent.quaternion.multiply(ie.invert()), o.boneParent.quaternion.multiply(o.qWorldInverseYaw)), o.isZ && (m = Math.atan(A[0] / o.l), ie.setFromAxisAngle($e, -m), o.boneParent.quaternion.multiply(ie)), o.isY && (m = o.l / 3, m = m * Math.tanh(A[1] / m), o.bone.position.setLength(o.l + m)), o.isX && (m = Math.atan(A[2] / o.l), ie.setFromAxisAngle(
|
|
372
|
+
else if (o.boneParent.quaternion.copy(o.qBasis), o.pivot && this.opt.isPivots && (o.boneParent.updateWorldMatrix(!1, !1), o.boneParent.matrixWorld.decompose(k, ie, ne), k.copy(He).applyQuaternion(ie).setY(0).normalize(), ie.premultiply(Ne.setFromUnitVectors(He, k).invert()).normalize(), o.boneParent.quaternion.multiply(ie.invert()), o.boneParent.quaternion.multiply(o.qWorldInverseYaw)), o.isZ && (m = Math.atan(A[0] / o.l), ie.setFromAxisAngle($e, -m), o.boneParent.quaternion.multiply(ie)), o.isY && (m = o.l / 3, m = m * Math.tanh(A[1] / m), o.bone.position.setLength(o.l + m)), o.isX && (m = Math.atan(A[2] / o.l), ie.setFromAxisAngle(_e, -m), o.boneParent.quaternion.multiply(ie)), o.isT && (m = 1.5 * Math.tanh(A[3] * 1.5), ie.setFromAxisAngle(Je, -m), o.boneParent.quaternion.multiply(ie)), o.boneParent.updateWorldMatrix(!1, !0), o.excludes && this.opt.isExcludes)
|
|
373
373
|
for (n = 0, s = o.excludes.length; n < s; n++)
|
|
374
|
-
m = o.excludes[n], ne.set(0, 0, 0), m.deltaLocal && (ne.x += m.deltaLocal[0], ne.y += m.deltaLocal[1], ne.z += m.deltaLocal[2]), ne.applyMatrix4(m.bone.matrixWorld),
|
|
374
|
+
m = o.excludes[n], ne.set(0, 0, 0), m.deltaLocal && (ne.x += m.deltaLocal[0], ne.y += m.deltaLocal[1], ne.z += m.deltaLocal[2]), ne.applyMatrix4(m.bone.matrixWorld), xe.copy(o.boneParent.matrixWorld).invert(), ne.applyMatrix4(xe), k.copy(o.bone.position), !(k.distanceToSquared(ne) >= m.radiusSq) && (ue = k.length(), re = ne.length(), !(re > m.radius + ue) && (re < Math.abs(m.radius - ue) || (re = (re * re + ue * ue - m.radiusSq) / (2 * re), ne.normalize(), Ce.copy(ne).multiplyScalar(re), re = Math.sqrt(ue * ue - re * re), k.subVectors(k, Ce).projectOnPlane(ne).normalize().multiplyScalar(re), ze.subVectors(o.vBasis, Ce).projectOnPlane(ne).normalize(), ue = ze.dot(k), ue < 0 && (ue = Math.sqrt(re * re - ue * ue), ze.multiplyScalar(ue), k.add(ze)), k.add(Ce).normalize(), ne.copy(o.bone.position).normalize(), ie.setFromUnitVectors(ne, k), o.boneParent.quaternion.premultiply(ie), o.boneParent.updateWorldMatrix(!1, !0))));
|
|
375
375
|
}
|
|
376
376
|
this.helpers.isActive && this.updateHelpers();
|
|
377
377
|
}
|
|
@@ -442,17 +442,17 @@ class et {
|
|
|
442
442
|
*/
|
|
443
443
|
updateHelpers() {
|
|
444
444
|
if (m = this.helpers.points, m.bones.length) {
|
|
445
|
-
|
|
445
|
+
xe.copy(this.armature.matrixWorld).invert();
|
|
446
446
|
const t = m.object.geometry.getAttribute("position");
|
|
447
447
|
for (let e = 0, n = m.bones.length; e < n; e++)
|
|
448
|
-
|
|
448
|
+
fe.multiplyMatrices(xe, m.bones[e].matrixWorld), k.setFromMatrixPosition(fe), t.setXYZ(e, k.x, k.y, k.z);
|
|
449
449
|
t.needsUpdate = !0, m.object.updateMatrixWorld();
|
|
450
450
|
}
|
|
451
451
|
if (m = this.helpers.lines, m.bones.length) {
|
|
452
|
-
|
|
452
|
+
xe.copy(this.armature.matrixWorld).invert();
|
|
453
453
|
const t = m.object.geometry.getAttribute("position");
|
|
454
454
|
for (let e = 0, n = 0, i = m.bones.length; e < i; e++, n += 2)
|
|
455
|
-
|
|
455
|
+
fe.multiplyMatrices(xe, m.bones[e].matrixWorld), k.setFromMatrixPosition(fe), t.setXYZ(n, k.x, k.y, k.z), fe.multiplyMatrices(xe, m.bones[e].parent.matrixWorld), k.setFromMatrixPosition(fe), t.setXYZ(n + 1, k.x, k.y, k.z);
|
|
456
456
|
t.needsUpdate = !0, m.object.updateMatrixWorld();
|
|
457
457
|
}
|
|
458
458
|
}
|
|
@@ -2629,7 +2629,7 @@ const ct = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
|
2629
2629
|
fr: rt,
|
|
2630
2630
|
fi: ut,
|
|
2631
2631
|
lt: ct
|
|
2632
|
-
},
|
|
2632
|
+
}, Q = new x.Quaternion(), W = new x.Euler(), ve = new x.Vector3(), Re = new x.Vector3(), We = new x.Box3();
|
|
2633
2633
|
new x.Matrix4();
|
|
2634
2634
|
new x.Matrix4();
|
|
2635
2635
|
new x.Vector3();
|
|
@@ -2763,7 +2763,7 @@ class Be {
|
|
|
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 Ke(), 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: {
|
|
@@ -4374,9 +4374,9 @@ class Be {
|
|
|
4374
4374
|
updatePoseDelta() {
|
|
4375
4375
|
for (const [t, e] of Object.entries(this.poseDelta.props)) {
|
|
4376
4376
|
if (e.x === 0 && e.y === 0 && e.z === 0) continue;
|
|
4377
|
-
|
|
4377
|
+
W.set(e.x, e.y, e.z);
|
|
4378
4378
|
const n = this.poseAvatar.props[t];
|
|
4379
|
-
n.isQuaternion ? (
|
|
4379
|
+
n.isQuaternion ? (Q.setFromEuler(W), n.multiply(Q)) : n.isVector3 && n.add(W);
|
|
4380
4380
|
}
|
|
4381
4381
|
}
|
|
4382
4382
|
/**
|
|
@@ -5159,7 +5159,7 @@ class Be {
|
|
|
5159
5159
|
}, i.x ? new x.Vector3(i.x, i.y, i.z) : null, !0, i.d);
|
|
5160
5160
|
break;
|
|
5161
5161
|
}
|
|
5162
|
-
if ((h || r) && (
|
|
5162
|
+
if ((h || r) && (W.setFromQuaternion(this.poseAvatar.props["Head.quaternion"]), W.x = Math.max(-0.9, Math.min(0.9, 2 * W.x - 0.5)), W.y = Math.max(-0.9, Math.min(0.9, -2.5 * W.y)), h ? (Object.assign(this.mtAvatar.eyesLookDown, { system: W.x < 0 ? -W.x : 0, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyesLookUp, { system: W.x < 0 ? 0 : W.x, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookInLeft, { system: W.y < 0 ? -W.y : 0, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookOutLeft, { system: W.y < 0 ? 0 : W.y, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookInRight, { system: W.y < 0 ? 0 : W.y, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookOutRight, { system: W.y < 0 ? -W.y : 0, needsUpdate: !0 }), r && (n = -this.mtAvatar.bodyRotateY.value, i = this.gaussianRandom(-0.2, 0.2), this.animQueue.push(this.animFactory({
|
|
5163
5163
|
name: "headmove",
|
|
5164
5164
|
dt: [[1e3, 2e3], [1e3, 2e3, 1, 2], [1e3, 2e3], [1e3, 2e3, 1, 2]],
|
|
5165
5165
|
vs: {
|
|
@@ -5180,7 +5180,7 @@ class Be {
|
|
|
5180
5180
|
eyeLookOutRight: [null, 0],
|
|
5181
5181
|
eyeContact: [0]
|
|
5182
5182
|
}
|
|
5183
|
-
})))), e > 2 * this.animFrameDur && (e = 2 * this.animFrameDur), (this.viewName !== "full" || this.isAvatarOnly) && (n = this.mtRandomized[Math.floor(Math.random() * this.mtRandomized.length)], i = this.mtAvatar[n], i.needsUpdate || Object.assign(i, { base: (this.mood.baseline[n] || 0) + (1 + l / 255) * Math.random() / 5, needsUpdate: !0 })), this.updatePoseBase(this.animClock), this.mixer && this.mixer.update(e / 1e3 * this.mixer.timeScale), this.updatePoseDelta(), (this.isSpeaking || this.isListening) && h ? l > this.volumeMax ? (this.volumeHeadBase = 0.05, Math.random() > 0.6 && (this.volumeHeadTarget = -0.05 - Math.random() / 15), this.volumeMax = l) : (this.volumeMax *= 0.92, this.volumeHeadTarget = this.volumeHeadBase - 0.9 * (this.volumeHeadBase - this.volumeHeadTarget)) : (this.volumeHeadTarget = 0, this.volumeMax = 0), n = this.volumeHeadTarget - this.volumeHeadCurrent, i = Math.abs(n), i > 1e-4 && (o = i * (this.volumeHeadEasing(Math.min(1, this.volumeHeadVelocity * e / 1e3 / i) / 2 + 0.5) - 0.5), this.volumeHeadCurrent += Math.sign(n) * Math.min(i, o)), Math.abs(this.volumeHeadCurrent) > 1e-4 && (
|
|
5183
|
+
})))), e > 2 * this.animFrameDur && (e = 2 * this.animFrameDur), (this.viewName !== "full" || this.isAvatarOnly) && (n = this.mtRandomized[Math.floor(Math.random() * this.mtRandomized.length)], i = this.mtAvatar[n], i.needsUpdate || Object.assign(i, { base: (this.mood.baseline[n] || 0) + (1 + l / 255) * Math.random() / 5, needsUpdate: !0 })), this.updatePoseBase(this.animClock), this.mixer && this.mixer.update(e / 1e3 * this.mixer.timeScale), this.updatePoseDelta(), (this.isSpeaking || this.isListening) && h ? l > this.volumeMax ? (this.volumeHeadBase = 0.05, Math.random() > 0.6 && (this.volumeHeadTarget = -0.05 - Math.random() / 15), this.volumeMax = l) : (this.volumeMax *= 0.92, this.volumeHeadTarget = this.volumeHeadBase - 0.9 * (this.volumeHeadBase - this.volumeHeadTarget)) : (this.volumeHeadTarget = 0, this.volumeMax = 0), n = this.volumeHeadTarget - this.volumeHeadCurrent, i = Math.abs(n), i > 1e-4 && (o = i * (this.volumeHeadEasing(Math.min(1, this.volumeHeadVelocity * e / 1e3 / i) / 2 + 0.5) - 0.5), this.volumeHeadCurrent += Math.sign(n) * Math.min(i, o)), Math.abs(this.volumeHeadCurrent) > 1e-4 && (Q.setFromAxisAngle(mt, this.volumeHeadCurrent), this.objectNeck.quaternion.multiply(Q)), We.setFromObject(this.armature), this.objectLeftToeBase.getWorldPosition(ve), ve.sub(this.armature.position), this.objectRightToeBase.getWorldPosition(Re), Re.sub(this.armature.position), this.objectHips.position.y -= We.min.y / 2, this.objectHips.position.x -= (ve.x + Re.x) / 4, this.objectHips.position.z -= (ve.z + Re.z) / 2, this.dynamicbones.update(e), this.fbxAnimationLoader && this.fbxAnimationLoader.update(), this.opt.update && this.opt.update(e), this.updateMorphTargets(e), this.isAvatarOnly)
|
|
5184
5184
|
this.stats && this.stats.end();
|
|
5185
5185
|
else {
|
|
5186
5186
|
if (this.cameraClock !== null && this.cameraClock < 1e3) {
|
|
@@ -5251,10 +5251,10 @@ class Be {
|
|
|
5251
5251
|
let u = "", a = "", c = 0, d = [], g = [];
|
|
5252
5252
|
const y = Array.from(this.segmenter.segment(t), (b) => b.segment);
|
|
5253
5253
|
for (let b = 0; b < y.length; b++) {
|
|
5254
|
-
const I = b === y.length - 1,
|
|
5254
|
+
const I = b === y.length - 1, V = y[b].match(l);
|
|
5255
5255
|
let p = y[b].match(s);
|
|
5256
|
-
const
|
|
5257
|
-
if (p && !I && !
|
|
5256
|
+
const M = y[b].match(h), w = y[b].match(o);
|
|
5257
|
+
if (p && !I && !M && y[b + 1].match(s) && (p = !1), n && (u += y[b]), V && (!i || i.every((f) => b < f[0] || b > f[1])) && (a += y[b]), (w || p || I) && (a.length && (a = this.lipsyncPreProcessText(a, r), a.length && d.push({
|
|
5258
5258
|
mark: c,
|
|
5259
5259
|
word: a
|
|
5260
5260
|
})), u.length && (g.push({
|
|
@@ -5267,12 +5267,12 @@ class Be {
|
|
|
5267
5267
|
}), u = ""), a.length)) {
|
|
5268
5268
|
const f = this.lipsyncWordsToVisemes(a, r);
|
|
5269
5269
|
if (f && f.visemes && f.visemes.length) {
|
|
5270
|
-
const
|
|
5270
|
+
const E = f.times[f.visemes.length - 1] + f.durations[f.visemes.length - 1];
|
|
5271
5271
|
for (let P = 0; P < f.visemes.length; P++)
|
|
5272
5272
|
g.push({
|
|
5273
5273
|
mark: c,
|
|
5274
5274
|
template: { name: "viseme" },
|
|
5275
|
-
ts: [(f.times[P] - 0.6) /
|
|
5275
|
+
ts: [(f.times[P] - 0.6) / E, (f.times[P] + 0.5) / E, (f.times[P] + f.durations[P] + 0.5) / E],
|
|
5276
5276
|
vs: {
|
|
5277
5277
|
["viseme_" + f.visemes[P]]: [null, f.visemes[P] === "PP" || f.visemes[P] === "FF" ? 0.9 : 0.6, 0]
|
|
5278
5278
|
}
|
|
@@ -5287,7 +5287,7 @@ class Be {
|
|
|
5287
5287
|
};
|
|
5288
5288
|
n && (f.onSubtitles = n), d.length && !e.avatarMute && (f.text = d, e.avatarMood && (f.mood = e.avatarMood), e.ttsLang && (f.lang = e.ttsLang), e.ttsVoice && (f.voice = e.ttsVoice), e.ttsRate && (f.rate = e.ttsRate), e.ttsVoice && (f.pitch = e.ttsPitch), e.ttsVolume && (f.volume = e.ttsVolume)), this.speechQueue.push(f), d = [], a = "", c = 0, g = [];
|
|
5289
5289
|
}
|
|
5290
|
-
if (
|
|
5290
|
+
if (M) {
|
|
5291
5291
|
let f = this.animEmojis[y[b]];
|
|
5292
5292
|
f && f.link && (f = this.animEmojis[f.link]), f && this.speechQueue.push({ emoji: f });
|
|
5293
5293
|
}
|
|
@@ -5385,10 +5385,10 @@ class Be {
|
|
|
5385
5385
|
let y = 0.6 + this.convertRange(g, [0, u], [0, 0.4]);
|
|
5386
5386
|
if (u = Math.min(u, c.visemes.length * 200), d > 0)
|
|
5387
5387
|
for (let b = 0; b < c.visemes.length; b++) {
|
|
5388
|
-
const I = r + c.times[b] / d * u,
|
|
5388
|
+
const I = r + c.times[b] / d * u, V = c.durations[b] / d * u;
|
|
5389
5389
|
o.push({
|
|
5390
5390
|
template: { name: "viseme" },
|
|
5391
|
-
ts: [I - Math.min(60, 2 *
|
|
5391
|
+
ts: [I - Math.min(60, 2 * V / 3), I + Math.min(25, V / 2), I + V + Math.min(60, V / 2)],
|
|
5392
5392
|
vs: {
|
|
5393
5393
|
["viseme_" + c.visemes[b]]: [null, c.visemes[b] === "PP" || c.visemes[b] === "FF" ? 0.9 : y, 0]
|
|
5394
5394
|
}
|
|
@@ -5470,7 +5470,7 @@ class Be {
|
|
|
5470
5470
|
s.lang = o, s.rate = Math.max(0.1, Math.min(10, l)), s.pitch = Math.max(0, Math.min(2, h)), s.volume = Math.max(0, Math.min(1, r));
|
|
5471
5471
|
const u = speechSynthesis.getVoices(), a = t.voice || this.avatar.ttsVoice || this.opt.ttsVoice;
|
|
5472
5472
|
if (a && u.length > 0) {
|
|
5473
|
-
const p = u.find((
|
|
5473
|
+
const p = u.find((M) => M.name.includes(a) || M.lang === o);
|
|
5474
5474
|
p && (s.voice = p);
|
|
5475
5475
|
}
|
|
5476
5476
|
const c = i.length * 100 / s.rate, d = this.audioCtx.createBuffer(1, this.audioCtx.sampleRate * (c / 1e3), this.audioCtx.sampleRate), g = this.avatar.lipsyncLang || this.opt.lipsyncLang || "en", y = this.lipsyncPreProcessText(i, g), b = this.lipsyncWordsToVisemes(y, g);
|
|
@@ -5485,19 +5485,19 @@ class Be {
|
|
|
5485
5485
|
const I = [];
|
|
5486
5486
|
if (b && b.visemes && b.visemes.length > 0) {
|
|
5487
5487
|
const p = b.times[b.visemes.length - 1] + b.durations[b.visemes.length - 1];
|
|
5488
|
-
for (let
|
|
5489
|
-
const w = b.visemes[
|
|
5488
|
+
for (let M = 0; M < b.visemes.length; M++) {
|
|
5489
|
+
const w = b.visemes[M], f = b.times[M] / p, E = b.durations[M] / p, P = f * c, U = E * c;
|
|
5490
5490
|
I.push({
|
|
5491
5491
|
template: { name: "viseme" },
|
|
5492
|
-
ts: [P - Math.min(60, 2 *
|
|
5492
|
+
ts: [P - Math.min(60, 2 * U / 3), P + Math.min(25, U / 2), P + U + Math.min(60, U / 2)],
|
|
5493
5493
|
vs: {
|
|
5494
5494
|
["viseme_" + w]: [null, w === "PP" || w === "FF" ? 0.9 : 0.6, 0]
|
|
5495
5495
|
}
|
|
5496
5496
|
});
|
|
5497
5497
|
}
|
|
5498
5498
|
}
|
|
5499
|
-
const
|
|
5500
|
-
this.audioPlaylist.push({ anim:
|
|
5499
|
+
const V = [...t.anim, ...I];
|
|
5500
|
+
this.audioPlaylist.push({ anim: V, audio: d }), this.onSubtitles = t.onSubtitles || null, this.resetLips(), t.mood && this.setMood(t.mood), this.playAudio(), s.onend = () => {
|
|
5501
5501
|
e();
|
|
5502
5502
|
}, s.onerror = (p) => {
|
|
5503
5503
|
console.error("Speech synthesis error:", p.error), n(p.error);
|
|
@@ -6133,7 +6133,7 @@ class Be {
|
|
|
6133
6133
|
*/
|
|
6134
6134
|
lookAtCamera(t) {
|
|
6135
6135
|
let e;
|
|
6136
|
-
if (this.speakTo && (e = new x.Vector3(), this.speakTo.objectLeftEye?.isObject3D ? (this.speakTo.armature.objectHead, this.speakTo.objectLeftEye.updateMatrixWorld(!0), this.speakTo.objectRightEye.updateMatrixWorld(!0),
|
|
6136
|
+
if (this.speakTo && (e = new x.Vector3(), this.speakTo.objectLeftEye?.isObject3D ? (this.speakTo.armature.objectHead, this.speakTo.objectLeftEye.updateMatrixWorld(!0), this.speakTo.objectRightEye.updateMatrixWorld(!0), ve.setFromMatrixPosition(this.speakTo.objectLeftEye.matrixWorld), Re.setFromMatrixPosition(this.speakTo.objectRightEye.matrixWorld), e.addVectors(ve, Re).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) {
|
|
6137
6137
|
if (this.avatar.hasOwnProperty("avatarIgnoreCamera")) {
|
|
6138
6138
|
if (this.avatar.avatarIgnoreCamera) {
|
|
6139
6139
|
this.lookAhead(t);
|
|
@@ -6146,12 +6146,12 @@ class Be {
|
|
|
6146
6146
|
this.lookAt(null, null, t);
|
|
6147
6147
|
return;
|
|
6148
6148
|
}
|
|
6149
|
-
this.objectLeftEye.updateMatrixWorld(!0), this.objectRightEye.updateMatrixWorld(!0),
|
|
6150
|
-
const n = new x.Vector3().subVectors(e,
|
|
6151
|
-
|
|
6152
|
-
const l = new x.Quaternion().setFromEuler(
|
|
6153
|
-
|
|
6154
|
-
let r =
|
|
6149
|
+
this.objectLeftEye.updateMatrixWorld(!0), this.objectRightEye.updateMatrixWorld(!0), ve.setFromMatrixPosition(this.objectLeftEye.matrixWorld), Re.setFromMatrixPosition(this.objectRightEye.matrixWorld), ve.add(Re).divideScalar(2), Q.copy(this.armature.quaternion), Q.multiply(this.poseTarget.props["Hips.quaternion"]), Q.multiply(this.poseTarget.props["Spine.quaternion"]), Q.multiply(this.poseTarget.props["Spine1.quaternion"]), Q.multiply(this.poseTarget.props["Spine2.quaternion"]), Q.multiply(this.poseTarget.props["Neck.quaternion"]), Q.multiply(this.poseTarget.props["Head.quaternion"]);
|
|
6150
|
+
const n = new x.Vector3().subVectors(e, ve).normalize(), i = Math.atan2(n.x, n.z), s = Math.asin(-n.y);
|
|
6151
|
+
W.set(s, i, 0, "YXZ");
|
|
6152
|
+
const l = new x.Quaternion().setFromEuler(W), h = new x.Quaternion().copy(l).multiply(Q.clone().invert());
|
|
6153
|
+
W.setFromQuaternion(h, "YXZ");
|
|
6154
|
+
let r = W.x / (40 / 24) + 0.2, u = W.y / (9 / 4), a = Math.min(0.6, Math.max(-0.3, r)), c = Math.min(0.8, Math.max(-0.8, u)), d = (Math.random() - 0.5) / 4, g = (Math.random() - 0.5) / 4;
|
|
6155
6155
|
if (t) {
|
|
6156
6156
|
let y = this.animQueue.findIndex((I) => I.template.name === "lookat");
|
|
6157
6157
|
y !== -1 && this.animQueue.splice(y, 1);
|
|
@@ -6186,20 +6186,20 @@ class Be {
|
|
|
6186
6186
|
const s = new x.Vector3().setFromMatrixPosition(this.objectLeftEye.matrixWorld), o = new x.Vector3().setFromMatrixPosition(this.objectRightEye.matrixWorld), l = new x.Vector3().addVectors(s, o).divideScalar(2);
|
|
6187
6187
|
l.project(this.camera);
|
|
6188
6188
|
let h = (l.x + 1) / 2 * i.width + i.left, r = -(l.y - 1) / 2 * i.height + i.top;
|
|
6189
|
-
t === null && (t = h), e === null && (e = r),
|
|
6190
|
-
let u =
|
|
6189
|
+
t === null && (t = h), e === null && (e = r), Q.copy(this.armature.quaternion), Q.multiply(this.poseTarget.props["Hips.quaternion"]), Q.multiply(this.poseTarget.props["Spine.quaternion"]), Q.multiply(this.poseTarget.props["Spine1.quaternion"]), Q.multiply(this.poseTarget.props["Spine2.quaternion"]), Q.multiply(this.poseTarget.props["Neck.quaternion"]), Q.multiply(this.poseTarget.props["Head.quaternion"]), W.setFromQuaternion(Q);
|
|
6190
|
+
let u = W.x / (40 / 24), a = W.y / (9 / 4), c = Math.min(0.4, Math.max(-0.4, this.camera.rotation.x)), d = Math.min(0.4, Math.max(-0.4, this.camera.rotation.y)), g = Math.max(window.innerWidth - h, h), y = Math.max(window.innerHeight - r, r), b = this.convertRange(e, [r - y, r + y], [-0.3, 0.6]) - u + c, I = this.convertRange(t, [h - g, h + g], [-0.8, 0.8]) - a + d;
|
|
6191
6191
|
b = Math.min(0.6, Math.max(-0.3, b)), I = Math.min(0.8, Math.max(-0.8, I));
|
|
6192
|
-
let
|
|
6192
|
+
let V = (Math.random() - 0.5) / 4, p = (Math.random() - 0.5) / 4;
|
|
6193
6193
|
if (n) {
|
|
6194
|
-
let
|
|
6195
|
-
|
|
6194
|
+
let M = this.animQueue.findIndex((f) => f.template.name === "lookat");
|
|
6195
|
+
M !== -1 && this.animQueue.splice(M, 1);
|
|
6196
6196
|
const w = {
|
|
6197
6197
|
name: "lookat",
|
|
6198
6198
|
dt: [750, n],
|
|
6199
6199
|
vs: {
|
|
6200
|
-
bodyRotateX: [b +
|
|
6200
|
+
bodyRotateX: [b + V],
|
|
6201
6201
|
bodyRotateY: [I + p],
|
|
6202
|
-
eyesRotateX: [-3 *
|
|
6202
|
+
eyesRotateX: [-3 * V + 0.1],
|
|
6203
6203
|
eyesRotateY: [-5 * p],
|
|
6204
6204
|
browInnerUp: [[0, 0.7]],
|
|
6205
6205
|
mouthLeft: [[0, 0.7]],
|
|
@@ -6577,12 +6577,12 @@ class Be {
|
|
|
6577
6577
|
const b = t.iterations || 10;
|
|
6578
6578
|
if (e)
|
|
6579
6579
|
for (let I = 0; I < b; I++) {
|
|
6580
|
-
let
|
|
6581
|
-
for (let p = 0,
|
|
6580
|
+
let V = !1;
|
|
6581
|
+
for (let p = 0, M = y.length; p < M; p++) {
|
|
6582
6582
|
const w = y[p].bone;
|
|
6583
6583
|
w.matrixWorld.decompose(h, r, u), r.invert(), o.setFromMatrixPosition(g.matrixWorld), l.subVectors(o, h), l.applyQuaternion(r), l.normalize(), s.subVectors(e, h), s.applyQuaternion(r), s.normalize();
|
|
6584
6584
|
let f = s.dot(l);
|
|
6585
|
-
f > 1 ? f = 1 : f < -1 && (f = -1), f = Math.acos(f), !(f < 1e-5) && (y[p].minAngle !== void 0 && f < y[p].minAngle && (f = y[p].minAngle), y[p].maxAngle !== void 0 && f > y[p].maxAngle && (f = y[p].maxAngle), a.crossVectors(l, s), a.normalize(),
|
|
6585
|
+
f > 1 ? f = 1 : f < -1 && (f = -1), f = Math.acos(f), !(f < 1e-5) && (y[p].minAngle !== void 0 && f < y[p].minAngle && (f = y[p].minAngle), y[p].maxAngle !== void 0 && f > y[p].maxAngle && (f = y[p].maxAngle), a.crossVectors(l, s), a.normalize(), Q.setFromAxisAngle(a, f), w.quaternion.multiply(Q), w.rotation.setFromVector3(c.setFromEuler(w.rotation).clamp(new x.Vector3(
|
|
6586
6586
|
y[p].minx !== void 0 ? y[p].minx : -1 / 0,
|
|
6587
6587
|
y[p].miny !== void 0 ? y[p].miny : -1 / 0,
|
|
6588
6588
|
y[p].minz !== void 0 ? y[p].minz : -1 / 0
|
|
@@ -6590,9 +6590,9 @@ class Be {
|
|
|
6590
6590
|
y[p].maxx !== void 0 ? y[p].maxx : 1 / 0,
|
|
6591
6591
|
y[p].maxy !== void 0 ? y[p].maxy : 1 / 0,
|
|
6592
6592
|
y[p].maxz !== void 0 ? y[p].maxz : 1 / 0
|
|
6593
|
-
))), w.updateMatrixWorld(!0),
|
|
6593
|
+
))), w.updateMatrixWorld(!0), V = !0);
|
|
6594
6594
|
}
|
|
6595
|
-
if (!
|
|
6595
|
+
if (!V) break;
|
|
6596
6596
|
}
|
|
6597
6597
|
i && y.forEach((I) => {
|
|
6598
6598
|
this.poseTarget.props[I.link + ".quaternion"].copy(I.bone.quaternion), this.poseTarget.props[I.link + ".quaternion"].t = this.animClock, this.poseTarget.props[I.link + ".quaternion"].d = i;
|
|
@@ -6605,7 +6605,7 @@ class Be {
|
|
|
6605
6605
|
this.isRunning = !1, this.stop(), this.stopSpeaking(), this.streamStop(), this.isAvatarOnly ? this.armature && (this.armature.parent && this.armature.parent.remove(this.armature), this.clearThree(this.armature)) : (this.clearThree(this.scene), this.resizeobserver.disconnect(), this.renderer && (this.renderer.dispose(), this.renderer.domElement && this.renderer.domElement.parentNode && this.renderer.domElement.parentNode.removeChild(this.renderer.domElement), this.renderer = null)), this.clearThree(this.ikMesh), this.dynamicbones.dispose();
|
|
6606
6606
|
}
|
|
6607
6607
|
}
|
|
6608
|
-
const
|
|
6608
|
+
const Ie = {
|
|
6609
6609
|
apiKey: "sk_ace57ef3ef65a92b9d3bee2a00183b78ca790bc3e10964f2",
|
|
6610
6610
|
// Replace with your actual API key (should start with sk_)
|
|
6611
6611
|
endpoint: "https://api.elevenlabs.io/v1/text-to-speech",
|
|
@@ -6648,23 +6648,23 @@ const Le = {
|
|
|
6648
6648
|
function Fe() {
|
|
6649
6649
|
return {
|
|
6650
6650
|
service: "elevenlabs",
|
|
6651
|
-
endpoint:
|
|
6652
|
-
apiKey:
|
|
6653
|
-
defaultVoice:
|
|
6654
|
-
voices:
|
|
6651
|
+
endpoint: Ie.endpoint,
|
|
6652
|
+
apiKey: Ie.apiKey,
|
|
6653
|
+
defaultVoice: Ie.defaultVoice,
|
|
6654
|
+
voices: Ie.voices
|
|
6655
6655
|
};
|
|
6656
6656
|
}
|
|
6657
6657
|
function kt() {
|
|
6658
|
-
const
|
|
6659
|
-
return Object.entries(
|
|
6658
|
+
const G = Fe(), t = [];
|
|
6659
|
+
return Object.entries(G.voices).forEach(([e, n]) => {
|
|
6660
6660
|
t.push({
|
|
6661
6661
|
value: n,
|
|
6662
|
-
label: `${e.charAt(0).toUpperCase() + e.slice(1)} (${
|
|
6662
|
+
label: `${e.charAt(0).toUpperCase() + e.slice(1)} (${G.service})`
|
|
6663
6663
|
});
|
|
6664
6664
|
}), t;
|
|
6665
6665
|
}
|
|
6666
6666
|
const Ve = Me(({
|
|
6667
|
-
avatarUrl:
|
|
6667
|
+
avatarUrl: G = "/avatars/brunette.glb",
|
|
6668
6668
|
avatarBody: t = "F",
|
|
6669
6669
|
mood: e = "neutral",
|
|
6670
6670
|
ttsLang: n = "en",
|
|
@@ -6685,140 +6685,140 @@ const Ve = Me(({
|
|
|
6685
6685
|
style: y = {},
|
|
6686
6686
|
animations: b = {}
|
|
6687
6687
|
}, I) => {
|
|
6688
|
-
const
|
|
6689
|
-
|
|
6690
|
-
|
|
6691
|
-
}, [ae]),
|
|
6692
|
-
|
|
6688
|
+
const V = D(null), p = D(null), M = D(r), w = D(null), f = D(null), E = D(!1), P = D({ remainingText: null, originalText: null, options: null }), U = D([]), oe = D(0), [S, Z] = ce(!0), [K, X] = ce(null), [$, se] = ce(!1), [ae, pe] = ce(!1);
|
|
6689
|
+
de(() => {
|
|
6690
|
+
E.current = ae;
|
|
6691
|
+
}, [ae]), de(() => {
|
|
6692
|
+
M.current = r;
|
|
6693
6693
|
}, [r]);
|
|
6694
|
-
const
|
|
6695
|
-
let
|
|
6696
|
-
le === "browser" ?
|
|
6694
|
+
const ee = Fe(), le = i || ee.service;
|
|
6695
|
+
let O;
|
|
6696
|
+
le === "browser" ? O = {
|
|
6697
6697
|
service: "browser",
|
|
6698
6698
|
endpoint: "",
|
|
6699
6699
|
apiKey: null,
|
|
6700
6700
|
defaultVoice: "Google US English"
|
|
6701
|
-
} : le === "elevenlabs" ?
|
|
6701
|
+
} : le === "elevenlabs" ? O = {
|
|
6702
6702
|
service: "elevenlabs",
|
|
6703
6703
|
endpoint: "https://api.elevenlabs.io/v1/text-to-speech",
|
|
6704
|
-
apiKey: o ||
|
|
6705
|
-
defaultVoice: s ||
|
|
6706
|
-
voices:
|
|
6707
|
-
} : le === "deepgram" ?
|
|
6704
|
+
apiKey: o || ee.apiKey,
|
|
6705
|
+
defaultVoice: s || ee.defaultVoice || Ie.defaultVoice,
|
|
6706
|
+
voices: ee.voices || Ie.voices
|
|
6707
|
+
} : le === "deepgram" ? O = {
|
|
6708
6708
|
service: "deepgram",
|
|
6709
6709
|
endpoint: "https://api.deepgram.com/v1/speak",
|
|
6710
|
-
apiKey: o ||
|
|
6711
|
-
defaultVoice: s ||
|
|
6712
|
-
voices:
|
|
6713
|
-
} :
|
|
6714
|
-
|
|
6710
|
+
apiKey: o || ee.apiKey,
|
|
6711
|
+
defaultVoice: s || ee.defaultVoice || Te.defaultVoice,
|
|
6712
|
+
voices: ee.voices || Te.voices
|
|
6713
|
+
} : O = {
|
|
6714
|
+
...ee,
|
|
6715
6715
|
// Override API key if provided via props
|
|
6716
|
-
apiKey: o !== null ? o :
|
|
6716
|
+
apiKey: o !== null ? o : ee.apiKey
|
|
6717
6717
|
};
|
|
6718
6718
|
const v = {
|
|
6719
|
-
url:
|
|
6719
|
+
url: G,
|
|
6720
6720
|
body: t,
|
|
6721
6721
|
avatarMood: e,
|
|
6722
6722
|
ttsLang: le === "browser" ? "en-US" : n,
|
|
6723
|
-
ttsVoice: s ||
|
|
6723
|
+
ttsVoice: s || O.defaultVoice,
|
|
6724
6724
|
lipsyncLang: "en",
|
|
6725
6725
|
showFullAvatar: r,
|
|
6726
6726
|
bodyMovement: l,
|
|
6727
6727
|
movementIntensity: h
|
|
6728
6728
|
}, R = {
|
|
6729
|
-
ttsEndpoint:
|
|
6730
|
-
ttsApikey:
|
|
6729
|
+
ttsEndpoint: O.endpoint,
|
|
6730
|
+
ttsApikey: O.apiKey,
|
|
6731
6731
|
ttsService: le,
|
|
6732
6732
|
lipsyncModules: ["en"],
|
|
6733
6733
|
cameraView: u
|
|
6734
|
-
}, z =
|
|
6735
|
-
if (!(!
|
|
6734
|
+
}, z = T(async () => {
|
|
6735
|
+
if (!(!V.current || p.current))
|
|
6736
6736
|
try {
|
|
6737
|
-
if (
|
|
6738
|
-
if (
|
|
6739
|
-
const
|
|
6740
|
-
c(
|
|
6737
|
+
if (Z(!0), X(null), p.current = new Be(V.current, R), p.current.controls && (p.current.controls.enableRotate = !1, p.current.controls.enableZoom = !1, p.current.controls.enablePan = !1, p.current.controls.enableDamping = !1), b && Object.keys(b).length > 0 && (p.current.customAnimations = b), await p.current.showAvatar(v, (B) => {
|
|
6738
|
+
if (B.lengthComputable) {
|
|
6739
|
+
const J = Math.min(100, Math.round(B.loaded / B.total * 100));
|
|
6740
|
+
c(J);
|
|
6741
6741
|
}
|
|
6742
|
-
}), await new Promise((
|
|
6743
|
-
const
|
|
6744
|
-
p.current.lipsync && Object.keys(p.current.lipsync).length > 0 ?
|
|
6742
|
+
}), await new Promise((B) => {
|
|
6743
|
+
const J = () => {
|
|
6744
|
+
p.current.lipsync && Object.keys(p.current.lipsync).length > 0 ? B() : setTimeout(J, 100);
|
|
6745
6745
|
};
|
|
6746
|
-
|
|
6746
|
+
J();
|
|
6747
6747
|
}), p.current && p.current.setShowFullAvatar)
|
|
6748
6748
|
try {
|
|
6749
6749
|
p.current.setShowFullAvatar(r);
|
|
6750
|
-
} catch (
|
|
6751
|
-
console.warn("Error setting full body mode on initialization:",
|
|
6750
|
+
} catch (B) {
|
|
6751
|
+
console.warn("Error setting full body mode on initialization:", B);
|
|
6752
6752
|
}
|
|
6753
|
-
p.current && p.current.controls && (p.current.controls.enableRotate = !1, p.current.controls.enableZoom = !1, p.current.controls.enablePan = !1, p.current.controls.enableDamping = !1, p.current.controls.update()),
|
|
6754
|
-
const
|
|
6753
|
+
p.current && p.current.controls && (p.current.controls.enableRotate = !1, p.current.controls.enableZoom = !1, p.current.controls.enablePan = !1, p.current.controls.enableDamping = !1, p.current.controls.update()), Z(!1), se(!0), a(p.current);
|
|
6754
|
+
const F = () => {
|
|
6755
6755
|
document.visibilityState === "visible" ? p.current?.start() : p.current?.stop();
|
|
6756
6756
|
};
|
|
6757
|
-
return document.addEventListener("visibilitychange",
|
|
6758
|
-
document.removeEventListener("visibilitychange",
|
|
6757
|
+
return document.addEventListener("visibilitychange", F), () => {
|
|
6758
|
+
document.removeEventListener("visibilitychange", F);
|
|
6759
6759
|
};
|
|
6760
6760
|
} catch (L) {
|
|
6761
|
-
console.error("Error initializing TalkingHead:", L),
|
|
6761
|
+
console.error("Error initializing TalkingHead:", L), X(L.message || "Failed to initialize avatar"), Z(!1), d(L);
|
|
6762
6762
|
}
|
|
6763
|
-
}, [
|
|
6764
|
-
|
|
6763
|
+
}, [G, t, e, n, i, s, o, r, l, h, u]);
|
|
6764
|
+
de(() => (z(), () => {
|
|
6765
6765
|
p.current && (p.current.stop(), p.current.dispose(), p.current = null);
|
|
6766
|
-
}), [z]),
|
|
6767
|
-
if (!
|
|
6768
|
-
const L = new ResizeObserver((
|
|
6769
|
-
for (const
|
|
6766
|
+
}), [z]), de(() => {
|
|
6767
|
+
if (!V.current || !p.current) return;
|
|
6768
|
+
const L = new ResizeObserver((B) => {
|
|
6769
|
+
for (const J of B)
|
|
6770
6770
|
p.current && p.current.onResize && p.current.onResize();
|
|
6771
6771
|
});
|
|
6772
|
-
L.observe(
|
|
6773
|
-
const
|
|
6772
|
+
L.observe(V.current);
|
|
6773
|
+
const F = () => {
|
|
6774
6774
|
p.current && p.current.onResize && p.current.onResize();
|
|
6775
6775
|
};
|
|
6776
|
-
return window.addEventListener("resize",
|
|
6777
|
-
L.disconnect(), window.removeEventListener("resize",
|
|
6776
|
+
return window.addEventListener("resize", F), () => {
|
|
6777
|
+
L.disconnect(), window.removeEventListener("resize", F);
|
|
6778
6778
|
};
|
|
6779
|
-
}, [
|
|
6780
|
-
const
|
|
6779
|
+
}, [$]);
|
|
6780
|
+
const H = T(async () => {
|
|
6781
6781
|
if (p.current && p.current.audioCtx)
|
|
6782
6782
|
try {
|
|
6783
6783
|
(p.current.audioCtx.state === "suspended" || p.current.audioCtx.state === "interrupted") && (await p.current.audioCtx.resume(), console.log("Audio context resumed"));
|
|
6784
6784
|
} catch (L) {
|
|
6785
6785
|
console.warn("Failed to resume audio context:", L);
|
|
6786
6786
|
}
|
|
6787
|
-
}, []),
|
|
6788
|
-
if (p.current &&
|
|
6787
|
+
}, []), N = T(async (L, F = {}) => {
|
|
6788
|
+
if (p.current && $)
|
|
6789
6789
|
try {
|
|
6790
|
-
f.current && (clearInterval(f.current), f.current = null), w.current = { text: L, options:
|
|
6791
|
-
const
|
|
6792
|
-
|
|
6793
|
-
const
|
|
6794
|
-
...
|
|
6795
|
-
lipsyncLang:
|
|
6790
|
+
f.current && (clearInterval(f.current), f.current = null), w.current = { text: L, options: F }, P.current = { remainingText: null, originalText: null, options: null };
|
|
6791
|
+
const B = /[!\.\?\n\p{Extended_Pictographic}]/ug, J = L.split(B).map((Y) => Y.trim()).filter((Y) => Y.length > 0);
|
|
6792
|
+
U.current = J, oe.current = 0, pe(!1), E.current = !1, await H();
|
|
6793
|
+
const ge = {
|
|
6794
|
+
...F,
|
|
6795
|
+
lipsyncLang: F.lipsyncLang || v.lipsyncLang || "en"
|
|
6796
6796
|
};
|
|
6797
|
-
if (
|
|
6797
|
+
if (F.onSpeechEnd && p.current) {
|
|
6798
6798
|
const Y = p.current;
|
|
6799
|
-
let he = null,
|
|
6800
|
-
const
|
|
6801
|
-
let
|
|
6799
|
+
let he = null, Se = 0;
|
|
6800
|
+
const Ae = 1200;
|
|
6801
|
+
let be = !1;
|
|
6802
6802
|
he = setInterval(() => {
|
|
6803
|
-
if (
|
|
6803
|
+
if (Se++, E.current)
|
|
6804
6804
|
return;
|
|
6805
|
-
if (
|
|
6806
|
-
if (he && (clearInterval(he), he = null, f.current = null), !
|
|
6807
|
-
|
|
6805
|
+
if (Se > Ae) {
|
|
6806
|
+
if (he && (clearInterval(he), he = null, f.current = null), !be && !E.current) {
|
|
6807
|
+
be = !0;
|
|
6808
6808
|
try {
|
|
6809
|
-
|
|
6809
|
+
F.onSpeechEnd();
|
|
6810
6810
|
} catch (De) {
|
|
6811
6811
|
console.error("Error in onSpeechEnd callback (timeout):", De);
|
|
6812
6812
|
}
|
|
6813
6813
|
}
|
|
6814
6814
|
return;
|
|
6815
6815
|
}
|
|
6816
|
-
const
|
|
6817
|
-
Y && Y.isSpeaking === !1 &&
|
|
6818
|
-
if (Y && !
|
|
6819
|
-
|
|
6816
|
+
const ye = !Y.speechQueue || Y.speechQueue.length === 0, ke = !Y.audioPlaylist || Y.audioPlaylist.length === 0;
|
|
6817
|
+
Y && Y.isSpeaking === !1 && ye && ke && Y.isAudioPlaying === !1 && !be && !E.current && setTimeout(() => {
|
|
6818
|
+
if (Y && !E.current && Y.isSpeaking === !1 && (!Y.speechQueue || Y.speechQueue.length === 0) && (!Y.audioPlaylist || Y.audioPlaylist.length === 0) && Y.isAudioPlaying === !1 && !be && !E.current) {
|
|
6819
|
+
be = !0, he && (clearInterval(he), he = null, f.current = null);
|
|
6820
6820
|
try {
|
|
6821
|
-
|
|
6821
|
+
F.onSpeechEnd();
|
|
6822
6822
|
} catch (Ze) {
|
|
6823
6823
|
console.error("Error in onSpeechEnd callback:", Ze);
|
|
6824
6824
|
}
|
|
@@ -6826,89 +6826,89 @@ const Ve = Me(({
|
|
|
6826
6826
|
}, 100);
|
|
6827
6827
|
}, 100), f.current = he;
|
|
6828
6828
|
}
|
|
6829
|
-
p.current.lipsync && Object.keys(p.current.lipsync).length > 0 ? (p.current.setSlowdownRate && p.current.setSlowdownRate(1.05), p.current.speakText(L,
|
|
6830
|
-
await
|
|
6829
|
+
p.current.lipsync && Object.keys(p.current.lipsync).length > 0 ? (p.current.setSlowdownRate && p.current.setSlowdownRate(1.05), p.current.speakText(L, ge)) : setTimeout(async () => {
|
|
6830
|
+
await H(), p.current && p.current.lipsync && (p.current.setSlowdownRate && p.current.setSlowdownRate(1.05), p.current.speakText(L, ge));
|
|
6831
6831
|
}, 100);
|
|
6832
|
-
} catch (
|
|
6833
|
-
console.error("Error speaking text:",
|
|
6832
|
+
} catch (B) {
|
|
6833
|
+
console.error("Error speaking text:", B), X(B.message || "Failed to speak text");
|
|
6834
6834
|
}
|
|
6835
|
-
}, [
|
|
6836
|
-
p.current && (p.current.stopSpeaking(), p.current.setSlowdownRate && p.current.setSlowdownRate(1), w.current = null,
|
|
6837
|
-
}, []),
|
|
6835
|
+
}, [$, H, v.lipsyncLang]), _ = T(() => {
|
|
6836
|
+
p.current && (p.current.stopSpeaking(), p.current.setSlowdownRate && p.current.setSlowdownRate(1), w.current = null, pe(!1));
|
|
6837
|
+
}, []), j = T(() => {
|
|
6838
6838
|
if (p.current && p.current.pauseSpeaking) {
|
|
6839
6839
|
const L = p.current;
|
|
6840
6840
|
if (L.isSpeaking || L.audioPlaylist && L.audioPlaylist.length > 0 || L.speechQueue && L.speechQueue.length > 0) {
|
|
6841
6841
|
f.current && (clearInterval(f.current), f.current = null);
|
|
6842
|
-
let
|
|
6843
|
-
if (w.current &&
|
|
6844
|
-
const
|
|
6845
|
-
if (he > 0 &&
|
|
6846
|
-
const
|
|
6847
|
-
|
|
6842
|
+
let B = "";
|
|
6843
|
+
if (w.current && U.current.length > 0) {
|
|
6844
|
+
const J = U.current.length, ge = L.speechQueue ? L.speechQueue.filter((Ae) => Ae && Ae.text && Array.isArray(Ae.text) && Ae.text.length > 0).length : 0, Y = L.audioPlaylist && L.audioPlaylist.length > 0, he = ge + (Y ? 1 : 0), Se = J - he;
|
|
6845
|
+
if (he > 0 && Se < J && (B = U.current.slice(Se).join(". ").trim(), !B && ge > 0 && L.speechQueue)) {
|
|
6846
|
+
const be = L.speechQueue.filter((ye) => ye && ye.text && Array.isArray(ye.text) && ye.text.length > 0).map((ye) => ye.text.map((ke) => ke.word || "").filter((ke) => ke.length > 0).join(" ")).filter((ye) => ye.length > 0).join(" ");
|
|
6847
|
+
be && be.trim() && (B = be.trim());
|
|
6848
6848
|
}
|
|
6849
6849
|
}
|
|
6850
6850
|
w.current && (P.current = {
|
|
6851
|
-
remainingText:
|
|
6851
|
+
remainingText: B || null,
|
|
6852
6852
|
originalText: w.current.text,
|
|
6853
6853
|
options: w.current.options
|
|
6854
|
-
}), L.speechQueue && (L.speechQueue.length = 0), p.current.pauseSpeaking(),
|
|
6854
|
+
}), L.speechQueue && (L.speechQueue.length = 0), p.current.pauseSpeaking(), E.current = !0, pe(!0);
|
|
6855
6855
|
}
|
|
6856
6856
|
}
|
|
6857
|
-
}, []),
|
|
6857
|
+
}, []), q = T(async () => {
|
|
6858
6858
|
if (!p.current || !ae)
|
|
6859
6859
|
return;
|
|
6860
|
-
let L = "",
|
|
6860
|
+
let L = "", F = {};
|
|
6861
6861
|
if (P.current && P.current.remainingText)
|
|
6862
|
-
L = P.current.remainingText,
|
|
6862
|
+
L = P.current.remainingText, F = P.current.options || {}, P.current = { remainingText: null, originalText: null, options: null };
|
|
6863
6863
|
else if (w.current && w.current.text)
|
|
6864
|
-
L = w.current.text,
|
|
6864
|
+
L = w.current.text, F = w.current.options || {};
|
|
6865
6865
|
else {
|
|
6866
|
-
console.warn("Resume called but no paused speech found"),
|
|
6866
|
+
console.warn("Resume called but no paused speech found"), pe(!1), E.current = !1;
|
|
6867
6867
|
return;
|
|
6868
6868
|
}
|
|
6869
|
-
|
|
6870
|
-
const
|
|
6871
|
-
...
|
|
6872
|
-
lipsyncLang:
|
|
6869
|
+
pe(!1), E.current = !1, await H();
|
|
6870
|
+
const B = {
|
|
6871
|
+
...F,
|
|
6872
|
+
lipsyncLang: F.lipsyncLang || v.lipsyncLang || "en"
|
|
6873
6873
|
};
|
|
6874
6874
|
try {
|
|
6875
|
-
await
|
|
6876
|
-
} catch (
|
|
6877
|
-
console.error("Error resuming speech:",
|
|
6875
|
+
await N(L, B);
|
|
6876
|
+
} catch (J) {
|
|
6877
|
+
console.error("Error resuming speech:", J), pe(!1), E.current = !1;
|
|
6878
6878
|
}
|
|
6879
|
-
}, [
|
|
6879
|
+
}, [H, ae, N, v]), Le = T((L) => {
|
|
6880
6880
|
p.current && p.current.setMood(L);
|
|
6881
|
-
}, []),
|
|
6881
|
+
}, []), we = T((L) => {
|
|
6882
6882
|
p.current && p.current.setSlowdownRate && p.current.setSlowdownRate(L);
|
|
6883
|
-
}, []),
|
|
6883
|
+
}, []), C = T((L, F = !1) => {
|
|
6884
6884
|
if (p.current && p.current.playAnimation) {
|
|
6885
6885
|
if (b && b[L] && (L = b[L]), p.current.setShowFullAvatar)
|
|
6886
6886
|
try {
|
|
6887
|
-
p.current.setShowFullAvatar(
|
|
6888
|
-
} catch (
|
|
6889
|
-
console.warn("Error setting full body mode:",
|
|
6887
|
+
p.current.setShowFullAvatar(M.current);
|
|
6888
|
+
} catch (J) {
|
|
6889
|
+
console.warn("Error setting full body mode:", J);
|
|
6890
6890
|
}
|
|
6891
6891
|
if (L.includes("."))
|
|
6892
6892
|
try {
|
|
6893
|
-
p.current.playAnimation(L, null, 10, 0, 0.01,
|
|
6894
|
-
} catch (
|
|
6895
|
-
console.warn(`Failed to play ${L}:`,
|
|
6893
|
+
p.current.playAnimation(L, null, 10, 0, 0.01, F);
|
|
6894
|
+
} catch (J) {
|
|
6895
|
+
console.warn(`Failed to play ${L}:`, J);
|
|
6896
6896
|
try {
|
|
6897
6897
|
p.current.setBodyMovement("idle");
|
|
6898
|
-
} catch (
|
|
6899
|
-
console.warn("Fallback animation also failed:",
|
|
6898
|
+
} catch (ge) {
|
|
6899
|
+
console.warn("Fallback animation also failed:", ge);
|
|
6900
6900
|
}
|
|
6901
6901
|
}
|
|
6902
6902
|
else {
|
|
6903
|
-
const
|
|
6904
|
-
let
|
|
6905
|
-
for (const Y of
|
|
6903
|
+
const J = [".fbx", ".glb", ".gltf"];
|
|
6904
|
+
let ge = !1;
|
|
6905
|
+
for (const Y of J)
|
|
6906
6906
|
try {
|
|
6907
|
-
p.current.playAnimation(L + Y, null, 10, 0, 0.01,
|
|
6907
|
+
p.current.playAnimation(L + Y, null, 10, 0, 0.01, F), ge = !0;
|
|
6908
6908
|
break;
|
|
6909
6909
|
} catch {
|
|
6910
6910
|
}
|
|
6911
|
-
if (!
|
|
6911
|
+
if (!ge) {
|
|
6912
6912
|
console.warn("Animation not found:", L);
|
|
6913
6913
|
try {
|
|
6914
6914
|
p.current.setBodyMovement("idle");
|
|
@@ -6918,35 +6918,35 @@ const Ve = Me(({
|
|
|
6918
6918
|
}
|
|
6919
6919
|
}
|
|
6920
6920
|
}
|
|
6921
|
-
}, [b]),
|
|
6921
|
+
}, [b]), te = T(() => {
|
|
6922
6922
|
p.current && p.current.onResize && p.current.onResize();
|
|
6923
6923
|
}, []);
|
|
6924
6924
|
return Ee(I, () => ({
|
|
6925
|
-
speakText:
|
|
6925
|
+
speakText: N,
|
|
6926
6926
|
stopSpeaking: _,
|
|
6927
|
-
pauseSpeaking:
|
|
6928
|
-
resumeSpeaking:
|
|
6929
|
-
resumeAudioContext:
|
|
6930
|
-
setMood:
|
|
6931
|
-
setTimingAdjustment:
|
|
6932
|
-
playAnimation:
|
|
6933
|
-
isReady:
|
|
6927
|
+
pauseSpeaking: j,
|
|
6928
|
+
resumeSpeaking: q,
|
|
6929
|
+
resumeAudioContext: H,
|
|
6930
|
+
setMood: Le,
|
|
6931
|
+
setTimingAdjustment: we,
|
|
6932
|
+
playAnimation: C,
|
|
6933
|
+
isReady: $,
|
|
6934
6934
|
isPaused: ae,
|
|
6935
6935
|
talkingHead: p.current,
|
|
6936
|
-
handleResize:
|
|
6936
|
+
handleResize: te,
|
|
6937
6937
|
setBodyMovement: (L) => {
|
|
6938
6938
|
if (p.current && p.current.setShowFullAvatar && p.current.setBodyMovement)
|
|
6939
6939
|
try {
|
|
6940
|
-
p.current.setShowFullAvatar(
|
|
6941
|
-
} catch (
|
|
6942
|
-
console.warn("Error setting body movement:",
|
|
6940
|
+
p.current.setShowFullAvatar(M.current), p.current.setBodyMovement(L);
|
|
6941
|
+
} catch (F) {
|
|
6942
|
+
console.warn("Error setting body movement:", F);
|
|
6943
6943
|
}
|
|
6944
6944
|
},
|
|
6945
6945
|
setMovementIntensity: (L) => p.current?.setMovementIntensity(L),
|
|
6946
6946
|
playRandomDance: () => {
|
|
6947
6947
|
if (p.current && p.current.setShowFullAvatar && p.current.playRandomDance)
|
|
6948
6948
|
try {
|
|
6949
|
-
p.current.setShowFullAvatar(
|
|
6949
|
+
p.current.setShowFullAvatar(M.current), p.current.playRandomDance();
|
|
6950
6950
|
} catch (L) {
|
|
6951
6951
|
console.warn("Error playing random dance:", L);
|
|
6952
6952
|
}
|
|
@@ -6954,15 +6954,15 @@ const Ve = Me(({
|
|
|
6954
6954
|
playReaction: (L) => {
|
|
6955
6955
|
if (p.current && p.current.setShowFullAvatar && p.current.playReaction)
|
|
6956
6956
|
try {
|
|
6957
|
-
p.current.setShowFullAvatar(
|
|
6958
|
-
} catch (
|
|
6959
|
-
console.warn("Error playing reaction:",
|
|
6957
|
+
p.current.setShowFullAvatar(M.current), p.current.playReaction(L);
|
|
6958
|
+
} catch (F) {
|
|
6959
|
+
console.warn("Error playing reaction:", F);
|
|
6960
6960
|
}
|
|
6961
6961
|
},
|
|
6962
6962
|
playCelebration: () => {
|
|
6963
6963
|
if (p.current && p.current.setShowFullAvatar && p.current.playCelebration)
|
|
6964
6964
|
try {
|
|
6965
|
-
p.current.setShowFullAvatar(
|
|
6965
|
+
p.current.setShowFullAvatar(M.current), p.current.playCelebration();
|
|
6966
6966
|
} catch (L) {
|
|
6967
6967
|
console.warn("Error playing celebration:", L);
|
|
6968
6968
|
}
|
|
@@ -6970,9 +6970,9 @@ const Ve = Me(({
|
|
|
6970
6970
|
setShowFullAvatar: (L) => {
|
|
6971
6971
|
if (p.current && p.current.setShowFullAvatar)
|
|
6972
6972
|
try {
|
|
6973
|
-
|
|
6974
|
-
} catch (
|
|
6975
|
-
console.warn("Error setting showFullAvatar:",
|
|
6973
|
+
M.current = L, p.current.setShowFullAvatar(L);
|
|
6974
|
+
} catch (F) {
|
|
6975
|
+
console.warn("Error setting showFullAvatar:", F);
|
|
6976
6976
|
}
|
|
6977
6977
|
},
|
|
6978
6978
|
lockAvatarPosition: () => {
|
|
@@ -7002,10 +7002,10 @@ const Ve = Me(({
|
|
|
7002
7002
|
...y
|
|
7003
7003
|
},
|
|
7004
7004
|
children: [
|
|
7005
|
-
/* @__PURE__ */
|
|
7005
|
+
/* @__PURE__ */ me(
|
|
7006
7006
|
"div",
|
|
7007
7007
|
{
|
|
7008
|
-
ref:
|
|
7008
|
+
ref: V,
|
|
7009
7009
|
className: "talking-head-viewer",
|
|
7010
7010
|
style: {
|
|
7011
7011
|
width: "100%",
|
|
@@ -7014,7 +7014,7 @@ const Ve = Me(({
|
|
|
7014
7014
|
}
|
|
7015
7015
|
}
|
|
7016
7016
|
),
|
|
7017
|
-
S && /* @__PURE__ */
|
|
7017
|
+
S && /* @__PURE__ */ me("div", { className: "loading-overlay", style: {
|
|
7018
7018
|
position: "absolute",
|
|
7019
7019
|
top: "50%",
|
|
7020
7020
|
left: "50%",
|
|
@@ -7023,7 +7023,7 @@ const Ve = Me(({
|
|
|
7023
7023
|
fontSize: "18px",
|
|
7024
7024
|
zIndex: 10
|
|
7025
7025
|
}, children: "Loading avatar..." }),
|
|
7026
|
-
|
|
7026
|
+
K && /* @__PURE__ */ me("div", { className: "error-overlay", style: {
|
|
7027
7027
|
position: "absolute",
|
|
7028
7028
|
top: "50%",
|
|
7029
7029
|
left: "50%",
|
|
@@ -7034,14 +7034,14 @@ const Ve = Me(({
|
|
|
7034
7034
|
zIndex: 10,
|
|
7035
7035
|
padding: "20px",
|
|
7036
7036
|
borderRadius: "8px"
|
|
7037
|
-
}, children:
|
|
7037
|
+
}, children: K })
|
|
7038
7038
|
]
|
|
7039
7039
|
}
|
|
7040
7040
|
);
|
|
7041
7041
|
});
|
|
7042
7042
|
Ve.displayName = "TalkingHeadAvatar";
|
|
7043
7043
|
const pt = Me(({
|
|
7044
|
-
text:
|
|
7044
|
+
text: G = "Hello! I'm a talking avatar. How are you today?",
|
|
7045
7045
|
onLoading: t = () => {
|
|
7046
7046
|
},
|
|
7047
7047
|
onError: e = () => {
|
|
@@ -7052,7 +7052,7 @@ const pt = Me(({
|
|
|
7052
7052
|
style: s = {},
|
|
7053
7053
|
avatarConfig: o = {}
|
|
7054
7054
|
}, l) => {
|
|
7055
|
-
const h =
|
|
7055
|
+
const h = D(null), r = D(null), [u, a] = ce(!0), [c, d] = ce(null), [g, y] = ce(!1), b = Fe(), I = o.ttsService || b.service, V = I === "browser" ? {
|
|
7056
7056
|
endpoint: "",
|
|
7057
7057
|
apiKey: null,
|
|
7058
7058
|
defaultVoice: "Google US English"
|
|
@@ -7068,7 +7068,7 @@ const pt = Me(({
|
|
|
7068
7068
|
body: "F",
|
|
7069
7069
|
avatarMood: "neutral",
|
|
7070
7070
|
ttsLang: I === "browser" ? "en-US" : "en",
|
|
7071
|
-
ttsVoice: o.ttsVoice ||
|
|
7071
|
+
ttsVoice: o.ttsVoice || V.defaultVoice,
|
|
7072
7072
|
lipsyncLang: "en",
|
|
7073
7073
|
// English lip-sync
|
|
7074
7074
|
showFullAvatar: !0,
|
|
@@ -7076,98 +7076,98 @@ const pt = Me(({
|
|
|
7076
7076
|
bodyMovement: "idle",
|
|
7077
7077
|
movementIntensity: 0.5,
|
|
7078
7078
|
...o
|
|
7079
|
-
},
|
|
7080
|
-
ttsEndpoint:
|
|
7081
|
-
ttsApikey:
|
|
7079
|
+
}, M = {
|
|
7080
|
+
ttsEndpoint: V.endpoint,
|
|
7081
|
+
ttsApikey: V.apiKey,
|
|
7082
7082
|
ttsService: I,
|
|
7083
7083
|
lipsyncModules: ["en"],
|
|
7084
7084
|
cameraView: "upper"
|
|
7085
|
-
}, w =
|
|
7085
|
+
}, w = T(async () => {
|
|
7086
7086
|
if (!(!h.current || r.current))
|
|
7087
7087
|
try {
|
|
7088
|
-
if (a(!0), d(null), r.current = new Be(h.current,
|
|
7089
|
-
if (
|
|
7090
|
-
const
|
|
7091
|
-
t(
|
|
7088
|
+
if (a(!0), d(null), r.current = new Be(h.current, M), await r.current.showAvatar(p, (K) => {
|
|
7089
|
+
if (K.lengthComputable) {
|
|
7090
|
+
const X = Math.min(100, Math.round(K.loaded / K.total * 100));
|
|
7091
|
+
t(X);
|
|
7092
7092
|
}
|
|
7093
7093
|
}), r.current.morphs && r.current.morphs.length > 0) {
|
|
7094
|
-
const
|
|
7095
|
-
console.log("Available morph targets:", Object.keys(
|
|
7096
|
-
const
|
|
7097
|
-
console.log("Viseme morph targets found:",
|
|
7094
|
+
const K = r.current.morphs[0].morphTargetDictionary;
|
|
7095
|
+
console.log("Available morph targets:", Object.keys(K));
|
|
7096
|
+
const X = Object.keys(K).filter(($) => $.startsWith("viseme_"));
|
|
7097
|
+
console.log("Viseme morph targets found:", X), X.length === 0 && (console.warn("No viseme morph targets found! Lip-sync will not work properly."), console.log("Expected viseme targets: viseme_aa, viseme_E, viseme_I, viseme_O, viseme_U, viseme_PP, viseme_SS, viseme_TH, viseme_DD, viseme_FF, viseme_kk, viseme_nn, viseme_RR, viseme_CH, viseme_sil"));
|
|
7098
7098
|
}
|
|
7099
|
-
if (await new Promise((
|
|
7100
|
-
const
|
|
7101
|
-
r.current.lipsync && Object.keys(r.current.lipsync).length > 0 ? (console.log("Lip-sync modules loaded:", Object.keys(r.current.lipsync)),
|
|
7099
|
+
if (await new Promise((K) => {
|
|
7100
|
+
const X = () => {
|
|
7101
|
+
r.current.lipsync && Object.keys(r.current.lipsync).length > 0 ? (console.log("Lip-sync modules loaded:", Object.keys(r.current.lipsync)), K()) : (console.log("Waiting for lip-sync modules to load..."), setTimeout(X, 100));
|
|
7102
7102
|
};
|
|
7103
|
-
|
|
7103
|
+
X();
|
|
7104
7104
|
}), r.current && r.current.setShowFullAvatar)
|
|
7105
7105
|
try {
|
|
7106
7106
|
r.current.setShowFullAvatar(!0), console.log("Avatar initialized in full body mode");
|
|
7107
|
-
} catch (
|
|
7108
|
-
console.warn("Error setting full body mode on initialization:",
|
|
7107
|
+
} catch (K) {
|
|
7108
|
+
console.warn("Error setting full body mode on initialization:", K);
|
|
7109
7109
|
}
|
|
7110
7110
|
a(!1), y(!0), n(r.current);
|
|
7111
|
-
const
|
|
7111
|
+
const Z = () => {
|
|
7112
7112
|
document.visibilityState === "visible" ? r.current?.start() : r.current?.stop();
|
|
7113
7113
|
};
|
|
7114
|
-
return document.addEventListener("visibilitychange",
|
|
7115
|
-
document.removeEventListener("visibilitychange",
|
|
7114
|
+
return document.addEventListener("visibilitychange", Z), () => {
|
|
7115
|
+
document.removeEventListener("visibilitychange", Z);
|
|
7116
7116
|
};
|
|
7117
7117
|
} catch (S) {
|
|
7118
7118
|
console.error("Error initializing TalkingHead:", S), d(S.message || "Failed to initialize avatar"), a(!1), e(S);
|
|
7119
7119
|
}
|
|
7120
7120
|
}, []);
|
|
7121
|
-
|
|
7121
|
+
de(() => (w(), () => {
|
|
7122
7122
|
r.current && (r.current.stop(), r.current.dispose(), r.current = null);
|
|
7123
7123
|
}), [w]);
|
|
7124
|
-
const f =
|
|
7124
|
+
const f = T((S) => {
|
|
7125
7125
|
if (r.current && g)
|
|
7126
7126
|
try {
|
|
7127
7127
|
console.log("Speaking text:", S), console.log("Avatar config:", p), console.log("TalkingHead instance:", r.current), r.current.lipsync && Object.keys(r.current.lipsync).length > 0 ? (console.log("Lip-sync modules loaded:", Object.keys(r.current.lipsync)), r.current.setSlowdownRate && (r.current.setSlowdownRate(1.05), console.log("Applied timing adjustment for better lip-sync")), r.current.speakText(S)) : (console.warn("Lip-sync modules not ready, waiting..."), setTimeout(() => {
|
|
7128
7128
|
r.current && r.current.lipsync ? (console.log("Lip-sync now ready, speaking..."), r.current.setSlowdownRate && (r.current.setSlowdownRate(1.05), console.log("Applied timing adjustment for better lip-sync")), r.current.speakText(S)) : console.error("Lip-sync still not ready after waiting");
|
|
7129
7129
|
}, 500));
|
|
7130
|
-
} catch (
|
|
7131
|
-
console.error("Error speaking text:",
|
|
7130
|
+
} catch (Z) {
|
|
7131
|
+
console.error("Error speaking text:", Z), d(Z.message || "Failed to speak text");
|
|
7132
7132
|
}
|
|
7133
7133
|
else
|
|
7134
7134
|
console.warn("Avatar not ready for speaking. isReady:", g, "talkingHeadRef:", !!r.current);
|
|
7135
|
-
}, [g, p]),
|
|
7135
|
+
}, [g, p]), E = T(() => {
|
|
7136
7136
|
r.current && (r.current.stopSpeaking(), r.current.setSlowdownRate && (r.current.setSlowdownRate(1), console.log("Reset timing to normal")));
|
|
7137
|
-
}, []), P =
|
|
7137
|
+
}, []), P = T((S) => {
|
|
7138
7138
|
r.current && r.current.setMood(S);
|
|
7139
|
-
}, []),
|
|
7139
|
+
}, []), U = T((S) => {
|
|
7140
7140
|
r.current && r.current.setSlowdownRate && (r.current.setSlowdownRate(S), console.log("Timing adjustment set to:", S));
|
|
7141
|
-
}, []), oe =
|
|
7141
|
+
}, []), oe = T((S, Z = !1) => {
|
|
7142
7142
|
if (r.current && r.current.playAnimation) {
|
|
7143
7143
|
if (r.current.setShowFullAvatar)
|
|
7144
7144
|
try {
|
|
7145
7145
|
r.current.setShowFullAvatar(!0);
|
|
7146
|
-
} catch (
|
|
7147
|
-
console.warn("Error setting full body mode:",
|
|
7146
|
+
} catch (X) {
|
|
7147
|
+
console.warn("Error setting full body mode:", X);
|
|
7148
7148
|
}
|
|
7149
7149
|
if (S.includes("."))
|
|
7150
7150
|
try {
|
|
7151
|
-
r.current.playAnimation(S, null, 10, 0, 0.01,
|
|
7152
|
-
} catch (
|
|
7153
|
-
console.log(`Failed to play ${S}:`,
|
|
7151
|
+
r.current.playAnimation(S, null, 10, 0, 0.01, Z), console.log("Playing animation:", S);
|
|
7152
|
+
} catch (X) {
|
|
7153
|
+
console.log(`Failed to play ${S}:`, X);
|
|
7154
7154
|
try {
|
|
7155
7155
|
r.current.setBodyMovement("idle"), console.log("Fallback to idle animation");
|
|
7156
|
-
} catch (
|
|
7157
|
-
console.warn("Fallback animation also failed:",
|
|
7156
|
+
} catch ($) {
|
|
7157
|
+
console.warn("Fallback animation also failed:", $);
|
|
7158
7158
|
}
|
|
7159
7159
|
}
|
|
7160
7160
|
else {
|
|
7161
|
-
const
|
|
7162
|
-
let
|
|
7163
|
-
for (const se of
|
|
7161
|
+
const X = [".fbx", ".glb", ".gltf"];
|
|
7162
|
+
let $ = !1;
|
|
7163
|
+
for (const se of X)
|
|
7164
7164
|
try {
|
|
7165
|
-
r.current.playAnimation(S + se, null, 10, 0, 0.01,
|
|
7165
|
+
r.current.playAnimation(S + se, null, 10, 0, 0.01, Z), console.log("Playing animation:", S + se), $ = !0;
|
|
7166
7166
|
break;
|
|
7167
7167
|
} catch {
|
|
7168
7168
|
console.log(`Failed to play ${S}${se}, trying next format...`);
|
|
7169
7169
|
}
|
|
7170
|
-
if (
|
|
7170
|
+
if (!$) {
|
|
7171
7171
|
console.warn("Animation system not available or animation not found:", S);
|
|
7172
7172
|
try {
|
|
7173
7173
|
r.current.setBodyMovement("idle"), console.log("Fallback to idle animation");
|
|
@@ -7181,9 +7181,9 @@ const pt = Me(({
|
|
|
7181
7181
|
}, []);
|
|
7182
7182
|
return Ee(l, () => ({
|
|
7183
7183
|
speakText: f,
|
|
7184
|
-
stopSpeaking:
|
|
7184
|
+
stopSpeaking: E,
|
|
7185
7185
|
setMood: P,
|
|
7186
|
-
setTimingAdjustment:
|
|
7186
|
+
setTimingAdjustment: U,
|
|
7187
7187
|
playAnimation: oe,
|
|
7188
7188
|
isReady: g,
|
|
7189
7189
|
talkingHead: r.current,
|
|
@@ -7191,8 +7191,8 @@ const pt = Me(({
|
|
|
7191
7191
|
if (r.current && r.current.setShowFullAvatar && r.current.setBodyMovement)
|
|
7192
7192
|
try {
|
|
7193
7193
|
r.current.setShowFullAvatar(!0), r.current.setBodyMovement(S), console.log("Body movement set with full body mode:", S);
|
|
7194
|
-
} catch (
|
|
7195
|
-
console.warn("Error setting body movement:",
|
|
7194
|
+
} catch (Z) {
|
|
7195
|
+
console.warn("Error setting body movement:", Z);
|
|
7196
7196
|
}
|
|
7197
7197
|
},
|
|
7198
7198
|
setMovementIntensity: (S) => r.current?.setMovementIntensity(S),
|
|
@@ -7208,8 +7208,8 @@ const pt = Me(({
|
|
|
7208
7208
|
if (r.current && r.current.setShowFullAvatar && r.current.playReaction)
|
|
7209
7209
|
try {
|
|
7210
7210
|
r.current.setShowFullAvatar(!0), r.current.playReaction(S), console.log("Reaction played with full body mode:", S);
|
|
7211
|
-
} catch (
|
|
7212
|
-
console.warn("Error playing reaction:",
|
|
7211
|
+
} catch (Z) {
|
|
7212
|
+
console.warn("Error playing reaction:", Z);
|
|
7213
7213
|
}
|
|
7214
7214
|
},
|
|
7215
7215
|
playCelebration: () => {
|
|
@@ -7224,8 +7224,8 @@ const pt = Me(({
|
|
|
7224
7224
|
if (r.current && r.current.setShowFullAvatar)
|
|
7225
7225
|
try {
|
|
7226
7226
|
r.current.setShowFullAvatar(S), console.log("Show full avatar set to:", S);
|
|
7227
|
-
} catch (
|
|
7228
|
-
console.warn("Error setting showFullAvatar:",
|
|
7227
|
+
} catch (Z) {
|
|
7228
|
+
console.warn("Error setting showFullAvatar:", Z);
|
|
7229
7229
|
}
|
|
7230
7230
|
},
|
|
7231
7231
|
lockAvatarPosition: () => {
|
|
@@ -7245,7 +7245,7 @@ const pt = Me(({
|
|
|
7245
7245
|
}
|
|
7246
7246
|
}
|
|
7247
7247
|
})), /* @__PURE__ */ Pe("div", { className: `talking-head-container ${i}`, style: s, children: [
|
|
7248
|
-
/* @__PURE__ */
|
|
7248
|
+
/* @__PURE__ */ me(
|
|
7249
7249
|
"div",
|
|
7250
7250
|
{
|
|
7251
7251
|
ref: h,
|
|
@@ -7257,7 +7257,7 @@ const pt = Me(({
|
|
|
7257
7257
|
}
|
|
7258
7258
|
}
|
|
7259
7259
|
),
|
|
7260
|
-
u && /* @__PURE__ */
|
|
7260
|
+
u && /* @__PURE__ */ me("div", { className: "loading-overlay", style: {
|
|
7261
7261
|
position: "absolute",
|
|
7262
7262
|
top: "50%",
|
|
7263
7263
|
left: "50%",
|
|
@@ -7266,7 +7266,7 @@ const pt = Me(({
|
|
|
7266
7266
|
fontSize: "18px",
|
|
7267
7267
|
zIndex: 10
|
|
7268
7268
|
}, children: "Loading avatar..." }),
|
|
7269
|
-
c && /* @__PURE__ */
|
|
7269
|
+
c && /* @__PURE__ */ me("div", { className: "error-overlay", style: {
|
|
7270
7270
|
position: "absolute",
|
|
7271
7271
|
top: "50%",
|
|
7272
7272
|
left: "50%",
|
|
@@ -7282,7 +7282,7 @@ const pt = Me(({
|
|
|
7282
7282
|
});
|
|
7283
7283
|
pt.displayName = "TalkingHeadComponent";
|
|
7284
7284
|
const gt = Me(({
|
|
7285
|
-
text:
|
|
7285
|
+
text: G = null,
|
|
7286
7286
|
avatarUrl: t = "/avatars/brunette.glb",
|
|
7287
7287
|
avatarBody: e = "F",
|
|
7288
7288
|
mood: n = "neutral",
|
|
@@ -7304,16 +7304,16 @@ const gt = Me(({
|
|
|
7304
7304
|
},
|
|
7305
7305
|
className: b = "",
|
|
7306
7306
|
style: I = {},
|
|
7307
|
-
animations:
|
|
7307
|
+
animations: V = {},
|
|
7308
7308
|
autoSpeak: p = !1
|
|
7309
|
-
},
|
|
7310
|
-
const w =
|
|
7311
|
-
|
|
7312
|
-
oe.current =
|
|
7313
|
-
}, [
|
|
7314
|
-
|
|
7309
|
+
}, M) => {
|
|
7310
|
+
const w = D(null), f = D(null), E = D(u), P = D(null), U = D(null), oe = D(!1), S = D({ remainingText: null, originalText: null, options: null }), Z = D([]), [K, X] = ce(!0), [$, se] = ce(null), [ae, pe] = ce(!1), [ee, le] = ce(!1);
|
|
7311
|
+
de(() => {
|
|
7312
|
+
oe.current = ee;
|
|
7313
|
+
}, [ee]), de(() => {
|
|
7314
|
+
E.current = u;
|
|
7315
7315
|
}, [u]);
|
|
7316
|
-
const
|
|
7316
|
+
const O = Fe(), v = s || O.service;
|
|
7317
7317
|
let R;
|
|
7318
7318
|
v === "browser" ? R = {
|
|
7319
7319
|
service: "browser",
|
|
@@ -7323,18 +7323,18 @@ const gt = Me(({
|
|
|
7323
7323
|
} : v === "elevenlabs" ? R = {
|
|
7324
7324
|
service: "elevenlabs",
|
|
7325
7325
|
endpoint: "https://api.elevenlabs.io/v1/text-to-speech",
|
|
7326
|
-
apiKey: l ||
|
|
7327
|
-
defaultVoice: o ||
|
|
7328
|
-
voices:
|
|
7326
|
+
apiKey: l || O.apiKey,
|
|
7327
|
+
defaultVoice: o || O.defaultVoice || Ie.defaultVoice,
|
|
7328
|
+
voices: O.voices || Ie.voices
|
|
7329
7329
|
} : v === "deepgram" ? R = {
|
|
7330
7330
|
service: "deepgram",
|
|
7331
7331
|
endpoint: "https://api.deepgram.com/v1/speak",
|
|
7332
|
-
apiKey: l ||
|
|
7333
|
-
defaultVoice: o ||
|
|
7334
|
-
voices:
|
|
7332
|
+
apiKey: l || O.apiKey,
|
|
7333
|
+
defaultVoice: o || O.defaultVoice || Te.defaultVoice,
|
|
7334
|
+
voices: O.voices || Te.voices
|
|
7335
7335
|
} : R = {
|
|
7336
|
-
...
|
|
7337
|
-
apiKey: l !== null ? l :
|
|
7336
|
+
...O,
|
|
7337
|
+
apiKey: l !== null ? l : O.apiKey
|
|
7338
7338
|
};
|
|
7339
7339
|
const z = {
|
|
7340
7340
|
url: t,
|
|
@@ -7346,109 +7346,120 @@ const gt = Me(({
|
|
|
7346
7346
|
showFullAvatar: u,
|
|
7347
7347
|
bodyMovement: h,
|
|
7348
7348
|
movementIntensity: r
|
|
7349
|
-
},
|
|
7349
|
+
}, H = {
|
|
7350
7350
|
ttsEndpoint: R.endpoint,
|
|
7351
7351
|
ttsApikey: R.apiKey,
|
|
7352
7352
|
ttsService: v,
|
|
7353
7353
|
lipsyncModules: ["en"],
|
|
7354
7354
|
cameraView: a
|
|
7355
|
-
},
|
|
7355
|
+
}, N = T(async () => {
|
|
7356
7356
|
if (!(!w.current || f.current))
|
|
7357
7357
|
try {
|
|
7358
|
-
|
|
7358
|
+
X(!0), se(null), f.current = new Be(w.current, H), await f.current.showAvatar(z, (te) => {
|
|
7359
7359
|
if (te.lengthComputable) {
|
|
7360
|
-
const
|
|
7361
|
-
d(
|
|
7360
|
+
const L = Math.min(100, Math.round(te.loaded / te.total * 100));
|
|
7361
|
+
d(L);
|
|
7362
7362
|
}
|
|
7363
|
-
}),
|
|
7364
|
-
const
|
|
7363
|
+
}), X(!1), pe(!0), c(f.current);
|
|
7364
|
+
const C = () => {
|
|
7365
7365
|
document.visibilityState === "visible" ? f.current?.start() : f.current?.stop();
|
|
7366
7366
|
};
|
|
7367
|
-
return document.addEventListener("visibilitychange",
|
|
7368
|
-
document.removeEventListener("visibilitychange",
|
|
7367
|
+
return document.addEventListener("visibilitychange", C), () => {
|
|
7368
|
+
document.removeEventListener("visibilitychange", C);
|
|
7369
7369
|
};
|
|
7370
|
-
} catch (
|
|
7371
|
-
console.error("Error initializing TalkingHead:",
|
|
7370
|
+
} catch (C) {
|
|
7371
|
+
console.error("Error initializing TalkingHead:", C), se(C.message || "Failed to initialize avatar"), X(!1), g(C);
|
|
7372
7372
|
}
|
|
7373
|
-
}, [
|
|
7374
|
-
|
|
7373
|
+
}, []);
|
|
7374
|
+
de(() => (N(), () => {
|
|
7375
7375
|
f.current && (f.current.stop(), f.current.dispose(), f.current = null);
|
|
7376
|
-
}), [
|
|
7377
|
-
|
|
7378
|
-
|
|
7379
|
-
|
|
7376
|
+
}), [N]);
|
|
7377
|
+
const _ = T(async () => {
|
|
7378
|
+
if (f.current)
|
|
7379
|
+
try {
|
|
7380
|
+
const C = f.current.audioCtx || f.current.audioContext;
|
|
7381
|
+
C && (C.state === "suspended" || C.state === "interrupted") && (await C.resume(), console.log("Audio context resumed"));
|
|
7382
|
+
} catch (C) {
|
|
7383
|
+
console.warn("Failed to resume audio context:", C);
|
|
7384
|
+
}
|
|
7385
|
+
}, []);
|
|
7386
|
+
de(() => {
|
|
7387
|
+
ae && G && p && f.current && j(G);
|
|
7388
|
+
}, [ae, G, p, j]);
|
|
7389
|
+
const j = T(async (C, te = {}) => {
|
|
7380
7390
|
if (!f.current || !ae) {
|
|
7381
7391
|
console.warn("Avatar not ready for speaking");
|
|
7382
7392
|
return;
|
|
7383
7393
|
}
|
|
7384
|
-
if (!
|
|
7394
|
+
if (!C || C.trim() === "") {
|
|
7385
7395
|
console.warn("No text provided to speak");
|
|
7386
7396
|
return;
|
|
7387
7397
|
}
|
|
7388
|
-
S.current = { remainingText: null, originalText: null, options: null },
|
|
7389
|
-
const
|
|
7390
|
-
|
|
7391
|
-
const
|
|
7398
|
+
await _(), S.current = { remainingText: null, originalText: null, options: null }, Z.current = [], P.current = { text: C, options: te }, U.current && (clearInterval(U.current), U.current = null), le(!1), oe.current = !1;
|
|
7399
|
+
const L = C.split(/[.!?]+/).filter((B) => B.trim().length > 0);
|
|
7400
|
+
Z.current = L;
|
|
7401
|
+
const F = {
|
|
7392
7402
|
lipsyncLang: te.lipsyncLang || "en",
|
|
7393
7403
|
onSpeechEnd: () => {
|
|
7394
|
-
|
|
7404
|
+
U.current && (clearInterval(U.current), U.current = null), te.onSpeechEnd && te.onSpeechEnd(), y();
|
|
7395
7405
|
}
|
|
7396
7406
|
};
|
|
7397
7407
|
try {
|
|
7398
|
-
f.current.speakText(
|
|
7399
|
-
} catch (
|
|
7400
|
-
console.error("Error speaking text:",
|
|
7408
|
+
f.current.speakText(C, F);
|
|
7409
|
+
} catch (B) {
|
|
7410
|
+
console.error("Error speaking text:", B), se(B.message || "Failed to speak text");
|
|
7401
7411
|
}
|
|
7402
|
-
}, [ae, y]),
|
|
7412
|
+
}, [ae, y, _]), q = T(() => {
|
|
7403
7413
|
if (f.current)
|
|
7404
7414
|
try {
|
|
7405
|
-
const
|
|
7406
|
-
if (
|
|
7407
|
-
|
|
7408
|
-
let
|
|
7409
|
-
|
|
7410
|
-
remainingText:
|
|
7415
|
+
const C = f.current.isSpeaking || !1, te = f.current.audioPlaylist || [], L = f.current.speechQueue || [];
|
|
7416
|
+
if (C || te.length > 0 || L.length > 0) {
|
|
7417
|
+
U.current && (clearInterval(U.current), U.current = null);
|
|
7418
|
+
let F = "";
|
|
7419
|
+
L.length > 0 && (F = L.map((B) => B.text && Array.isArray(B.text) ? B.text.map((J) => J.word).join(" ") : B.text || "").join(" ")), S.current = {
|
|
7420
|
+
remainingText: F || null,
|
|
7411
7421
|
originalText: P.current?.text || null,
|
|
7412
7422
|
options: P.current?.options || null
|
|
7413
7423
|
}, f.current.speechQueue.length = 0, f.current.pauseSpeaking(), le(!0), oe.current = !0;
|
|
7414
7424
|
}
|
|
7415
|
-
} catch (
|
|
7416
|
-
console.warn("Error pausing speech:",
|
|
7425
|
+
} catch (C) {
|
|
7426
|
+
console.warn("Error pausing speech:", C);
|
|
7417
7427
|
}
|
|
7418
|
-
}, []),
|
|
7419
|
-
if (!(!f.current ||
|
|
7428
|
+
}, []), Le = T(async () => {
|
|
7429
|
+
if (!(!f.current || !ee))
|
|
7420
7430
|
try {
|
|
7421
|
-
|
|
7422
|
-
const
|
|
7423
|
-
|
|
7424
|
-
} catch (
|
|
7425
|
-
console.warn("Error resuming speech:",
|
|
7431
|
+
await _(), le(!1), oe.current = !1;
|
|
7432
|
+
const C = S.current?.remainingText, te = S.current?.originalText || P.current?.text, L = S.current?.options || P.current?.options || {}, F = C || te;
|
|
7433
|
+
F && j(F, L);
|
|
7434
|
+
} catch (C) {
|
|
7435
|
+
console.warn("Error resuming speech:", C), le(!1), oe.current = !1;
|
|
7426
7436
|
}
|
|
7427
|
-
}, [
|
|
7428
|
-
f.current && (f.current.stopSpeaking(),
|
|
7437
|
+
}, [ee, j, _]), we = T(() => {
|
|
7438
|
+
f.current && (f.current.stopSpeaking(), U.current && (clearInterval(U.current), U.current = null), le(!1), oe.current = !1);
|
|
7429
7439
|
}, []);
|
|
7430
|
-
return Ee(
|
|
7431
|
-
speakText:
|
|
7432
|
-
pauseSpeaking:
|
|
7433
|
-
resumeSpeaking:
|
|
7434
|
-
stopSpeaking:
|
|
7435
|
-
|
|
7436
|
-
|
|
7437
|
-
|
|
7438
|
-
|
|
7440
|
+
return Ee(M, () => ({
|
|
7441
|
+
speakText: j,
|
|
7442
|
+
pauseSpeaking: q,
|
|
7443
|
+
resumeSpeaking: Le,
|
|
7444
|
+
stopSpeaking: we,
|
|
7445
|
+
resumeAudioContext: _,
|
|
7446
|
+
isPaused: () => ee,
|
|
7447
|
+
setMood: (C) => f.current?.setMood(C),
|
|
7448
|
+
setBodyMovement: (C) => {
|
|
7449
|
+
f.current && f.current.setBodyMovement(C);
|
|
7439
7450
|
},
|
|
7440
|
-
playAnimation: (
|
|
7441
|
-
f.current && f.current.playAnimation && f.current.playAnimation(
|
|
7451
|
+
playAnimation: (C, te = !1) => {
|
|
7452
|
+
f.current && f.current.playAnimation && f.current.playAnimation(C, null, 10, 0, 0.01, te);
|
|
7442
7453
|
},
|
|
7443
|
-
playReaction: (
|
|
7454
|
+
playReaction: (C) => f.current?.playReaction(C),
|
|
7444
7455
|
playCelebration: () => f.current?.playCelebration(),
|
|
7445
|
-
setShowFullAvatar: (
|
|
7446
|
-
f.current && (
|
|
7456
|
+
setShowFullAvatar: (C) => {
|
|
7457
|
+
f.current && (E.current = C, f.current.setShowFullAvatar(C));
|
|
7447
7458
|
},
|
|
7448
7459
|
isReady: ae,
|
|
7449
7460
|
talkingHead: f.current
|
|
7450
7461
|
})), /* @__PURE__ */ Pe("div", { className: `simple-talking-avatar-container ${b}`, style: I, children: [
|
|
7451
|
-
/* @__PURE__ */
|
|
7462
|
+
/* @__PURE__ */ me(
|
|
7452
7463
|
"div",
|
|
7453
7464
|
{
|
|
7454
7465
|
ref: w,
|
|
@@ -7460,7 +7471,7 @@ const gt = Me(({
|
|
|
7460
7471
|
}
|
|
7461
7472
|
}
|
|
7462
7473
|
),
|
|
7463
|
-
|
|
7474
|
+
K && /* @__PURE__ */ me("div", { className: "loading-overlay", style: {
|
|
7464
7475
|
position: "absolute",
|
|
7465
7476
|
top: "50%",
|
|
7466
7477
|
left: "50%",
|
|
@@ -7469,7 +7480,7 @@ const gt = Me(({
|
|
|
7469
7480
|
fontSize: "18px",
|
|
7470
7481
|
zIndex: 10
|
|
7471
7482
|
}, children: "Loading avatar..." }),
|
|
7472
|
-
|
|
7483
|
+
$ && /* @__PURE__ */ me("div", { className: "error-overlay", style: {
|
|
7473
7484
|
position: "absolute",
|
|
7474
7485
|
top: "50%",
|
|
7475
7486
|
left: "50%",
|
|
@@ -7480,12 +7491,12 @@ const gt = Me(({
|
|
|
7480
7491
|
zIndex: 10,
|
|
7481
7492
|
padding: "20px",
|
|
7482
7493
|
borderRadius: "8px"
|
|
7483
|
-
}, children:
|
|
7494
|
+
}, children: $ })
|
|
7484
7495
|
] });
|
|
7485
7496
|
});
|
|
7486
7497
|
gt.displayName = "SimpleTalkingAvatar";
|
|
7487
7498
|
const yt = Me(({
|
|
7488
|
-
curriculumData:
|
|
7499
|
+
curriculumData: G = null,
|
|
7489
7500
|
avatarConfig: t = {},
|
|
7490
7501
|
animations: e = {},
|
|
7491
7502
|
onLessonStart: n = () => {
|
|
@@ -7500,7 +7511,7 @@ const yt = Me(({
|
|
|
7500
7511
|
},
|
|
7501
7512
|
autoStart: h = !1
|
|
7502
7513
|
}, r) => {
|
|
7503
|
-
const u =
|
|
7514
|
+
const u = D(null), a = D({
|
|
7504
7515
|
currentModuleIndex: 0,
|
|
7505
7516
|
currentLessonIndex: 0,
|
|
7506
7517
|
currentQuestionIndex: 0,
|
|
@@ -7510,18 +7521,18 @@ const yt = Me(({
|
|
|
7510
7521
|
curriculumCompleted: !1,
|
|
7511
7522
|
score: 0,
|
|
7512
7523
|
totalQuestions: 0
|
|
7513
|
-
}), c =
|
|
7524
|
+
}), c = D({
|
|
7514
7525
|
onLessonStart: n,
|
|
7515
7526
|
onLessonComplete: i,
|
|
7516
7527
|
onQuestionAnswer: s,
|
|
7517
7528
|
onCurriculumComplete: o,
|
|
7518
7529
|
onCustomAction: l
|
|
7519
|
-
}), d =
|
|
7530
|
+
}), d = D(null), g = D(null), y = D(null), b = D(null), I = D(null), V = D(null), p = D(null), M = D(G?.curriculum || {
|
|
7520
7531
|
title: "Default Curriculum",
|
|
7521
7532
|
description: "No curriculum data provided",
|
|
7522
7533
|
language: "en",
|
|
7523
7534
|
modules: []
|
|
7524
|
-
}), w =
|
|
7535
|
+
}), w = D({
|
|
7525
7536
|
avatarUrl: t.avatarUrl || "/avatars/brunette.glb",
|
|
7526
7537
|
avatarBody: t.avatarBody || "F",
|
|
7527
7538
|
mood: t.mood || "happy",
|
|
@@ -7535,7 +7546,7 @@ const yt = Me(({
|
|
|
7535
7546
|
animations: e,
|
|
7536
7547
|
lipsyncLang: "en"
|
|
7537
7548
|
});
|
|
7538
|
-
|
|
7549
|
+
de(() => {
|
|
7539
7550
|
c.current = {
|
|
7540
7551
|
onLessonStart: n,
|
|
7541
7552
|
onLessonComplete: i,
|
|
@@ -7543,8 +7554,8 @@ const yt = Me(({
|
|
|
7543
7554
|
onCurriculumComplete: o,
|
|
7544
7555
|
onCustomAction: l
|
|
7545
7556
|
};
|
|
7546
|
-
}, [n, i, s, o, l]),
|
|
7547
|
-
|
|
7557
|
+
}, [n, i, s, o, l]), de(() => {
|
|
7558
|
+
M.current = G?.curriculum || {
|
|
7548
7559
|
title: "Default Curriculum",
|
|
7549
7560
|
description: "No curriculum data provided",
|
|
7550
7561
|
language: "en",
|
|
@@ -7563,8 +7574,8 @@ const yt = Me(({
|
|
|
7563
7574
|
animations: e,
|
|
7564
7575
|
lipsyncLang: "en"
|
|
7565
7576
|
};
|
|
7566
|
-
}, [
|
|
7567
|
-
const f =
|
|
7577
|
+
}, [G, t, e]);
|
|
7578
|
+
const f = T(() => (M.current || { modules: [] }).modules[a.current.currentModuleIndex]?.lessons[a.current.currentLessonIndex], []), E = T(() => f()?.questions[a.current.currentQuestionIndex], [f]), P = T((v, R) => R.type === "multiple_choice" || R.type === "true_false" ? v === R.answer : R.type === "code_test" && typeof v == "object" && v !== null ? v.passed === !0 : !1, []), U = T(() => {
|
|
7568
7579
|
a.current.lessonCompleted = !0, a.current.isQuestionMode = !1;
|
|
7569
7580
|
const v = a.current.totalQuestions > 0 ? Math.round(a.current.score / a.current.totalQuestions * 100) : 100;
|
|
7570
7581
|
let R = "Congratulations! You've completed this lesson";
|
|
@@ -7588,9 +7599,9 @@ const yt = Me(({
|
|
|
7588
7599
|
} catch {
|
|
7589
7600
|
u.current.playCelebration();
|
|
7590
7601
|
}
|
|
7591
|
-
const z =
|
|
7602
|
+
const z = M.current || { modules: [] }, H = z.modules[a.current.currentModuleIndex], N = a.current.currentLessonIndex < (H?.lessons?.length || 0) - 1, _ = a.current.currentModuleIndex < (z.modules?.length || 0) - 1, j = N || _, q = w.current || { lipsyncLang: "en" };
|
|
7592
7603
|
u.current.speakText(R, {
|
|
7593
|
-
lipsyncLang:
|
|
7604
|
+
lipsyncLang: q.lipsyncLang,
|
|
7594
7605
|
onSpeechEnd: () => {
|
|
7595
7606
|
c.current.onCustomAction({
|
|
7596
7607
|
type: "lessonCompleteFeedbackDone",
|
|
@@ -7599,14 +7610,14 @@ const yt = Me(({
|
|
|
7599
7610
|
score: a.current.score,
|
|
7600
7611
|
totalQuestions: a.current.totalQuestions,
|
|
7601
7612
|
percentage: v,
|
|
7602
|
-
hasNextLesson:
|
|
7613
|
+
hasNextLesson: j
|
|
7603
7614
|
});
|
|
7604
7615
|
}
|
|
7605
7616
|
});
|
|
7606
7617
|
}
|
|
7607
|
-
}, [e.lessonComplete]), oe =
|
|
7618
|
+
}, [e.lessonComplete]), oe = T(() => {
|
|
7608
7619
|
a.current.curriculumCompleted = !0;
|
|
7609
|
-
const v =
|
|
7620
|
+
const v = M.current || { modules: [] };
|
|
7610
7621
|
if (c.current.onCurriculumComplete({
|
|
7611
7622
|
modules: v.modules.length,
|
|
7612
7623
|
totalLessons: v.modules.reduce((R, z) => R + z.lessons.length, 0)
|
|
@@ -7620,10 +7631,10 @@ const yt = Me(({
|
|
|
7620
7631
|
const R = w.current || { lipsyncLang: "en" };
|
|
7621
7632
|
u.current.speakText("Amazing! You've completed the entire curriculum! You're now ready to move on to more advanced topics. Well done!", { lipsyncLang: R.lipsyncLang });
|
|
7622
7633
|
}
|
|
7623
|
-
}, [e.curriculumComplete]), S =
|
|
7634
|
+
}, [e.curriculumComplete]), S = T(() => {
|
|
7624
7635
|
const v = f();
|
|
7625
7636
|
a.current.isQuestionMode = !0, a.current.currentQuestionIndex = 0, a.current.totalQuestions = v?.questions?.length || 0, a.current.score = 0;
|
|
7626
|
-
const R =
|
|
7637
|
+
const R = E();
|
|
7627
7638
|
R && c.current.onCustomAction({
|
|
7628
7639
|
type: "questionStart",
|
|
7629
7640
|
moduleIndex: a.current.currentModuleIndex,
|
|
@@ -7638,30 +7649,30 @@ const yt = Me(({
|
|
|
7638
7649
|
if (u.current.setMood("happy"), e.questionStart)
|
|
7639
7650
|
try {
|
|
7640
7651
|
u.current.playAnimation(e.questionStart, !0);
|
|
7641
|
-
} catch (
|
|
7642
|
-
console.warn("Failed to play questionStart animation:",
|
|
7652
|
+
} catch (N) {
|
|
7653
|
+
console.warn("Failed to play questionStart animation:", N);
|
|
7643
7654
|
}
|
|
7644
|
-
const
|
|
7645
|
-
R.type === "code_test" ? u.current.speakText(`Let's test your coding skills! Here's your first challenge: ${R.question}`, { lipsyncLang:
|
|
7655
|
+
const H = w.current || { lipsyncLang: "en" };
|
|
7656
|
+
R.type === "code_test" ? u.current.speakText(`Let's test your coding skills! Here's your first challenge: ${R.question}`, { lipsyncLang: H.lipsyncLang }) : R.type === "multiple_choice" ? u.current.speakText(`Now let me ask you some questions. Here's the first one: ${R.question}`, { lipsyncLang: H.lipsyncLang }) : R.type === "true_false" ? u.current.speakText(`Let's start with some true or false questions. First question: ${R.question}`, { lipsyncLang: H.lipsyncLang }) : u.current.speakText(`Now let me ask you some questions. Here's the first one: ${R.question}`, { lipsyncLang: H.lipsyncLang });
|
|
7646
7657
|
};
|
|
7647
7658
|
if (u.current && u.current.isReady && R)
|
|
7648
7659
|
z();
|
|
7649
7660
|
else if (u.current && u.current.isReady) {
|
|
7650
|
-
const
|
|
7651
|
-
u.current.speakText("Now let me ask you some questions to test your understanding.", { lipsyncLang:
|
|
7661
|
+
const H = w.current || { lipsyncLang: "en" };
|
|
7662
|
+
u.current.speakText("Now let me ask you some questions to test your understanding.", { lipsyncLang: H.lipsyncLang });
|
|
7652
7663
|
} else {
|
|
7653
|
-
const
|
|
7654
|
-
u.current && u.current.isReady && (clearInterval(
|
|
7664
|
+
const H = setInterval(() => {
|
|
7665
|
+
u.current && u.current.isReady && (clearInterval(H), R && z());
|
|
7655
7666
|
}, 100);
|
|
7656
7667
|
setTimeout(() => {
|
|
7657
|
-
clearInterval(
|
|
7668
|
+
clearInterval(H);
|
|
7658
7669
|
}, 5e3);
|
|
7659
7670
|
}
|
|
7660
|
-
}, [e.questionStart, f,
|
|
7671
|
+
}, [e.questionStart, f, E]), Z = T(() => {
|
|
7661
7672
|
const v = f();
|
|
7662
7673
|
if (a.current.currentQuestionIndex < (v?.questions?.length || 0) - 1) {
|
|
7663
7674
|
u.current && u.current.stopSpeaking && u.current.stopSpeaking(), a.current.currentQuestionIndex += 1;
|
|
7664
|
-
const R =
|
|
7675
|
+
const R = E();
|
|
7665
7676
|
R && c.current.onCustomAction({
|
|
7666
7677
|
type: "nextQuestion",
|
|
7667
7678
|
moduleIndex: a.current.currentModuleIndex,
|
|
@@ -7676,40 +7687,40 @@ const yt = Me(({
|
|
|
7676
7687
|
if (u.current.setMood("happy"), u.current.setBodyMovement("idle"), e.nextQuestion)
|
|
7677
7688
|
try {
|
|
7678
7689
|
u.current.playAnimation(e.nextQuestion, !0);
|
|
7679
|
-
} catch (
|
|
7680
|
-
console.warn("Failed to play nextQuestion animation:",
|
|
7690
|
+
} catch (q) {
|
|
7691
|
+
console.warn("Failed to play nextQuestion animation:", q);
|
|
7681
7692
|
}
|
|
7682
|
-
const
|
|
7693
|
+
const H = w.current || { lipsyncLang: "en" }, _ = f()?.questions?.length || 0, j = a.current.currentQuestionIndex >= _ - 1;
|
|
7683
7694
|
if (R.type === "code_test") {
|
|
7684
|
-
const
|
|
7685
|
-
u.current.speakText(
|
|
7686
|
-
lipsyncLang:
|
|
7695
|
+
const q = j ? `Great! Here's your final coding challenge: ${R.question}` : `Great! Now let's move on to your next coding challenge: ${R.question}`;
|
|
7696
|
+
u.current.speakText(q, {
|
|
7697
|
+
lipsyncLang: H.lipsyncLang
|
|
7687
7698
|
});
|
|
7688
7699
|
} else if (R.type === "multiple_choice") {
|
|
7689
|
-
const
|
|
7690
|
-
u.current.speakText(
|
|
7691
|
-
lipsyncLang:
|
|
7700
|
+
const q = j ? `Alright! Here's your final question: ${R.question}` : `Alright! Here's your next question: ${R.question}`;
|
|
7701
|
+
u.current.speakText(q, {
|
|
7702
|
+
lipsyncLang: H.lipsyncLang
|
|
7692
7703
|
});
|
|
7693
7704
|
} else if (R.type === "true_false") {
|
|
7694
|
-
const
|
|
7695
|
-
u.current.speakText(
|
|
7696
|
-
lipsyncLang:
|
|
7705
|
+
const q = j ? `Now let's try this final one: ${R.question}` : `Now let's try this one: ${R.question}`;
|
|
7706
|
+
u.current.speakText(q, {
|
|
7707
|
+
lipsyncLang: H.lipsyncLang
|
|
7697
7708
|
});
|
|
7698
7709
|
} else {
|
|
7699
|
-
const
|
|
7700
|
-
u.current.speakText(
|
|
7701
|
-
lipsyncLang:
|
|
7710
|
+
const q = j ? `Here's your final question: ${R.question}` : `Here's the next question: ${R.question}`;
|
|
7711
|
+
u.current.speakText(q, {
|
|
7712
|
+
lipsyncLang: H.lipsyncLang
|
|
7702
7713
|
});
|
|
7703
7714
|
}
|
|
7704
7715
|
};
|
|
7705
7716
|
if (u.current && u.current.isReady && R)
|
|
7706
7717
|
z();
|
|
7707
7718
|
else if (R) {
|
|
7708
|
-
const
|
|
7709
|
-
u.current && u.current.isReady && (clearInterval(
|
|
7719
|
+
const H = setInterval(() => {
|
|
7720
|
+
u.current && u.current.isReady && (clearInterval(H), z());
|
|
7710
7721
|
}, 100);
|
|
7711
7722
|
setTimeout(() => {
|
|
7712
|
-
clearInterval(
|
|
7723
|
+
clearInterval(H);
|
|
7713
7724
|
}, 5e3);
|
|
7714
7725
|
}
|
|
7715
7726
|
} else
|
|
@@ -7720,16 +7731,16 @@ const yt = Me(({
|
|
|
7720
7731
|
totalQuestions: a.current.totalQuestions,
|
|
7721
7732
|
score: a.current.score
|
|
7722
7733
|
});
|
|
7723
|
-
}, [e.nextQuestion, f,
|
|
7724
|
-
const v =
|
|
7734
|
+
}, [e.nextQuestion, f, E]), K = T(() => {
|
|
7735
|
+
const v = M.current || { modules: [] }, R = v.modules[a.current.currentModuleIndex];
|
|
7725
7736
|
if (a.current.currentLessonIndex < (R?.lessons?.length || 0) - 1) {
|
|
7726
7737
|
a.current.currentLessonIndex += 1, a.current.currentQuestionIndex = 0, a.current.lessonCompleted = !1, a.current.isQuestionMode = !1, a.current.isTeaching = !1, a.current.score = 0, a.current.totalQuestions = 0;
|
|
7727
|
-
const
|
|
7738
|
+
const H = v.modules[a.current.currentModuleIndex], N = a.current.currentLessonIndex < (H?.lessons?.length || 0) - 1, _ = a.current.currentModuleIndex < (v.modules?.length || 0) - 1, j = N || _;
|
|
7728
7739
|
c.current.onCustomAction({
|
|
7729
7740
|
type: "lessonStart",
|
|
7730
7741
|
moduleIndex: a.current.currentModuleIndex,
|
|
7731
7742
|
lessonIndex: a.current.currentLessonIndex,
|
|
7732
|
-
hasNextLesson:
|
|
7743
|
+
hasNextLesson: j
|
|
7733
7744
|
}), c.current.onLessonStart({
|
|
7734
7745
|
moduleIndex: a.current.currentModuleIndex,
|
|
7735
7746
|
lessonIndex: a.current.currentLessonIndex,
|
|
@@ -7737,12 +7748,12 @@ const yt = Me(({
|
|
|
7737
7748
|
}), u.current && (u.current.setMood("happy"), u.current.setBodyMovement("idle"));
|
|
7738
7749
|
} else if (a.current.currentModuleIndex < (v.modules?.length || 0) - 1) {
|
|
7739
7750
|
a.current.currentModuleIndex += 1, a.current.currentLessonIndex = 0, a.current.currentQuestionIndex = 0, a.current.lessonCompleted = !1, a.current.isQuestionMode = !1, a.current.isTeaching = !1, a.current.score = 0, a.current.totalQuestions = 0;
|
|
7740
|
-
const
|
|
7751
|
+
const N = v.modules[a.current.currentModuleIndex], _ = a.current.currentLessonIndex < (N?.lessons?.length || 0) - 1, j = a.current.currentModuleIndex < (v.modules?.length || 0) - 1, q = _ || j;
|
|
7741
7752
|
c.current.onCustomAction({
|
|
7742
7753
|
type: "lessonStart",
|
|
7743
7754
|
moduleIndex: a.current.currentModuleIndex,
|
|
7744
7755
|
lessonIndex: a.current.currentLessonIndex,
|
|
7745
|
-
hasNextLesson:
|
|
7756
|
+
hasNextLesson: q
|
|
7746
7757
|
}), c.current.onLessonStart({
|
|
7747
7758
|
moduleIndex: a.current.currentModuleIndex,
|
|
7748
7759
|
lessonIndex: a.current.currentLessonIndex,
|
|
@@ -7750,12 +7761,12 @@ const yt = Me(({
|
|
|
7750
7761
|
}), u.current && (u.current.setMood("happy"), u.current.setBodyMovement("idle"));
|
|
7751
7762
|
} else
|
|
7752
7763
|
I.current && I.current();
|
|
7753
|
-
}, []),
|
|
7764
|
+
}, []), X = T(() => {
|
|
7754
7765
|
const v = f();
|
|
7755
7766
|
let R = null;
|
|
7756
7767
|
if (v?.avatar_script && v?.body) {
|
|
7757
|
-
const z = v.avatar_script.trim(),
|
|
7758
|
-
R = `${z}${
|
|
7768
|
+
const z = v.avatar_script.trim(), H = v.body.trim(), N = z.match(/[.!?]$/) ? " " : ". ";
|
|
7769
|
+
R = `${z}${N}${H}`;
|
|
7759
7770
|
} else
|
|
7760
7771
|
R = v?.avatar_script || v?.body || null;
|
|
7761
7772
|
if (u.current && u.current.isReady && R) {
|
|
@@ -7764,11 +7775,11 @@ const yt = Me(({
|
|
|
7764
7775
|
if (e.teaching)
|
|
7765
7776
|
try {
|
|
7766
7777
|
u.current.playAnimation(e.teaching, !0), z = !0;
|
|
7767
|
-
} catch (
|
|
7768
|
-
console.warn("Failed to play teaching animation:",
|
|
7778
|
+
} catch (N) {
|
|
7779
|
+
console.warn("Failed to play teaching animation:", N);
|
|
7769
7780
|
}
|
|
7770
7781
|
z || u.current.setBodyMovement("gesturing");
|
|
7771
|
-
const
|
|
7782
|
+
const H = w.current || { lipsyncLang: "en" };
|
|
7772
7783
|
c.current.onLessonStart({
|
|
7773
7784
|
moduleIndex: a.current.currentModuleIndex,
|
|
7774
7785
|
lessonIndex: a.current.currentLessonIndex,
|
|
@@ -7779,7 +7790,7 @@ const yt = Me(({
|
|
|
7779
7790
|
lessonIndex: a.current.currentLessonIndex,
|
|
7780
7791
|
lesson: v
|
|
7781
7792
|
}), u.current.speakText(R, {
|
|
7782
|
-
lipsyncLang:
|
|
7793
|
+
lipsyncLang: H.lipsyncLang,
|
|
7783
7794
|
onSpeechEnd: () => {
|
|
7784
7795
|
a.current.isTeaching = !1, c.current.onCustomAction({
|
|
7785
7796
|
type: "teachingComplete",
|
|
@@ -7797,8 +7808,8 @@ const yt = Me(({
|
|
|
7797
7808
|
}
|
|
7798
7809
|
});
|
|
7799
7810
|
}
|
|
7800
|
-
}, [e.teaching, f]),
|
|
7801
|
-
const R =
|
|
7811
|
+
}, [e.teaching, f]), $ = T((v) => {
|
|
7812
|
+
const R = E(), z = P(v, R);
|
|
7802
7813
|
if (z && (a.current.score += 1), c.current.onQuestionAnswer({
|
|
7803
7814
|
moduleIndex: a.current.currentModuleIndex,
|
|
7804
7815
|
lessonIndex: a.current.currentLessonIndex,
|
|
@@ -7815,13 +7826,13 @@ const yt = Me(({
|
|
|
7815
7826
|
u.current.setBodyMovement("happy");
|
|
7816
7827
|
}
|
|
7817
7828
|
u.current.setBodyMovement("gesturing");
|
|
7818
|
-
const
|
|
7819
|
-
a.current.currentQuestionIndex >=
|
|
7820
|
-
const _ = a.current.currentQuestionIndex <
|
|
7821
|
-
console.log("[CurriculumLearning] Answer feedback - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:",
|
|
7822
|
-
const
|
|
7823
|
-
u.current.speakText(
|
|
7824
|
-
lipsyncLang:
|
|
7829
|
+
const N = f()?.questions?.length || 0;
|
|
7830
|
+
a.current.currentQuestionIndex >= N - 1;
|
|
7831
|
+
const _ = a.current.currentQuestionIndex < N - 1;
|
|
7832
|
+
console.log("[CurriculumLearning] Answer feedback - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:", N, "hasNextQuestion:", _);
|
|
7833
|
+
const j = R.type === "code_test" ? `Great job! Your code passed all the tests! ${R.explanation || ""}` : `Excellent! That's correct! ${R.explanation || ""}`, q = w.current || { lipsyncLang: "en" };
|
|
7834
|
+
u.current.speakText(j, {
|
|
7835
|
+
lipsyncLang: q.lipsyncLang,
|
|
7825
7836
|
onSpeechEnd: () => {
|
|
7826
7837
|
c.current.onCustomAction({
|
|
7827
7838
|
type: "answerFeedbackComplete",
|
|
@@ -7843,11 +7854,11 @@ const yt = Me(({
|
|
|
7843
7854
|
u.current.setBodyMovement("idle");
|
|
7844
7855
|
}
|
|
7845
7856
|
u.current.setBodyMovement("gesturing");
|
|
7846
|
-
const
|
|
7847
|
-
console.log("[CurriculumLearning] Answer feedback (incorrect) - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:",
|
|
7848
|
-
const
|
|
7849
|
-
u.current.speakText(
|
|
7850
|
-
lipsyncLang:
|
|
7857
|
+
const N = f()?.questions?.length || 0, _ = a.current.currentQuestionIndex >= N - 1, j = a.current.currentQuestionIndex < N - 1;
|
|
7858
|
+
console.log("[CurriculumLearning] Answer feedback (incorrect) - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:", N, "hasNextQuestion:", j);
|
|
7859
|
+
const q = R.type === "code_test" ? `Your code didn't pass all the tests. ${R.explanation || "Try again!"}` : `Not quite right, but don't worry! ${R.explanation || ""}${_ ? "" : " Let's move on to the next question."}`, Le = w.current || { lipsyncLang: "en" };
|
|
7860
|
+
u.current.speakText(q, {
|
|
7861
|
+
lipsyncLang: Le.lipsyncLang,
|
|
7851
7862
|
onSpeechEnd: () => {
|
|
7852
7863
|
c.current.onCustomAction({
|
|
7853
7864
|
type: "answerFeedbackComplete",
|
|
@@ -7855,7 +7866,7 @@ const yt = Me(({
|
|
|
7855
7866
|
lessonIndex: a.current.currentLessonIndex,
|
|
7856
7867
|
questionIndex: a.current.currentQuestionIndex,
|
|
7857
7868
|
isCorrect: !1,
|
|
7858
|
-
hasNextQuestion:
|
|
7869
|
+
hasNextQuestion: j,
|
|
7859
7870
|
score: a.current.score,
|
|
7860
7871
|
totalQuestions: a.current.totalQuestions
|
|
7861
7872
|
});
|
|
@@ -7863,21 +7874,21 @@ const yt = Me(({
|
|
|
7863
7874
|
});
|
|
7864
7875
|
}
|
|
7865
7876
|
else {
|
|
7866
|
-
const
|
|
7877
|
+
const N = f()?.questions?.length || 0;
|
|
7867
7878
|
c.current.onCustomAction({
|
|
7868
7879
|
type: "answerFeedbackComplete",
|
|
7869
7880
|
moduleIndex: a.current.currentModuleIndex,
|
|
7870
7881
|
lessonIndex: a.current.currentLessonIndex,
|
|
7871
7882
|
questionIndex: a.current.currentQuestionIndex,
|
|
7872
7883
|
isCorrect: z,
|
|
7873
|
-
hasNextQuestion: a.current.currentQuestionIndex <
|
|
7884
|
+
hasNextQuestion: a.current.currentQuestionIndex < N - 1,
|
|
7874
7885
|
score: a.current.score,
|
|
7875
7886
|
totalQuestions: a.current.totalQuestions,
|
|
7876
7887
|
avatarNotReady: !0
|
|
7877
7888
|
});
|
|
7878
7889
|
}
|
|
7879
|
-
}, [e.correct, e.incorrect,
|
|
7880
|
-
const R =
|
|
7890
|
+
}, [e.correct, e.incorrect, E, f, P]), se = T((v) => {
|
|
7891
|
+
const R = E();
|
|
7881
7892
|
if (!v || typeof v != "object") {
|
|
7882
7893
|
console.error("Invalid code test result format. Expected object with {passed: boolean, ...}");
|
|
7883
7894
|
return;
|
|
@@ -7904,10 +7915,10 @@ const yt = Me(({
|
|
|
7904
7915
|
testResult: z,
|
|
7905
7916
|
question: R
|
|
7906
7917
|
}), p.current && p.current(z);
|
|
7907
|
-
}, [
|
|
7918
|
+
}, [E, P]), ae = T(() => {
|
|
7908
7919
|
if (a.current.currentQuestionIndex > 0) {
|
|
7909
7920
|
a.current.currentQuestionIndex -= 1;
|
|
7910
|
-
const v =
|
|
7921
|
+
const v = E();
|
|
7911
7922
|
v && c.current.onCustomAction({
|
|
7912
7923
|
type: "questionStart",
|
|
7913
7924
|
moduleIndex: a.current.currentModuleIndex,
|
|
@@ -7938,8 +7949,8 @@ const yt = Me(({
|
|
|
7938
7949
|
}, 5e3);
|
|
7939
7950
|
}
|
|
7940
7951
|
}
|
|
7941
|
-
}, [
|
|
7942
|
-
const v =
|
|
7952
|
+
}, [E]), pe = T(() => {
|
|
7953
|
+
const v = M.current || { modules: [] };
|
|
7943
7954
|
if (v.modules[a.current.currentModuleIndex], a.current.currentLessonIndex > 0)
|
|
7944
7955
|
a.current.currentLessonIndex -= 1, a.current.currentQuestionIndex = 0, a.current.lessonCompleted = !1, a.current.isQuestionMode = !1, a.current.isTeaching = !1, a.current.score = 0, a.current.totalQuestions = 0, c.current.onCustomAction({
|
|
7945
7956
|
type: "lessonStart",
|
|
@@ -7951,8 +7962,8 @@ const yt = Me(({
|
|
|
7951
7962
|
lesson: f()
|
|
7952
7963
|
}), u.current && (u.current.setMood("happy"), u.current.setBodyMovement("idle"));
|
|
7953
7964
|
else if (a.current.currentModuleIndex > 0) {
|
|
7954
|
-
const
|
|
7955
|
-
a.current.currentModuleIndex -= 1, a.current.currentLessonIndex = (
|
|
7965
|
+
const H = v.modules[a.current.currentModuleIndex - 1];
|
|
7966
|
+
a.current.currentModuleIndex -= 1, a.current.currentLessonIndex = (H?.lessons?.length || 1) - 1, a.current.currentQuestionIndex = 0, a.current.lessonCompleted = !1, a.current.isQuestionMode = !1, a.current.isTeaching = !1, a.current.score = 0, a.current.totalQuestions = 0, c.current.onCustomAction({
|
|
7956
7967
|
type: "lessonStart",
|
|
7957
7968
|
moduleIndex: a.current.currentModuleIndex,
|
|
7958
7969
|
lessonIndex: a.current.currentLessonIndex
|
|
@@ -7962,9 +7973,9 @@ const yt = Me(({
|
|
|
7962
7973
|
lesson: f()
|
|
7963
7974
|
}), u.current && (u.current.setMood("happy"), u.current.setBodyMovement("idle"));
|
|
7964
7975
|
}
|
|
7965
|
-
}, [f]),
|
|
7976
|
+
}, [f]), ee = T(() => {
|
|
7966
7977
|
a.current.currentModuleIndex = 0, a.current.currentLessonIndex = 0, a.current.currentQuestionIndex = 0, a.current.isTeaching = !1, a.current.isQuestionMode = !1, a.current.lessonCompleted = !1, a.current.curriculumCompleted = !1, a.current.score = 0, a.current.totalQuestions = 0;
|
|
7967
|
-
}, []), le =
|
|
7978
|
+
}, []), le = T((v) => {
|
|
7968
7979
|
console.log("Avatar is ready!", v);
|
|
7969
7980
|
const R = f(), z = R?.avatar_script || R?.body;
|
|
7970
7981
|
h && z && setTimeout(() => {
|
|
@@ -7972,22 +7983,22 @@ const yt = Me(({
|
|
|
7972
7983
|
}, 10);
|
|
7973
7984
|
}, [h, f]);
|
|
7974
7985
|
Xe(() => {
|
|
7975
|
-
d.current =
|
|
7986
|
+
d.current = X, g.current = K, y.current = U, b.current = Z, I.current = oe, V.current = S, p.current = $;
|
|
7976
7987
|
}), Ee(r, () => ({
|
|
7977
7988
|
// Curriculum control methods
|
|
7978
|
-
startTeaching:
|
|
7989
|
+
startTeaching: X,
|
|
7979
7990
|
startQuestions: S,
|
|
7980
|
-
handleAnswerSelect:
|
|
7991
|
+
handleAnswerSelect: $,
|
|
7981
7992
|
handleCodeTestResult: se,
|
|
7982
|
-
nextQuestion:
|
|
7993
|
+
nextQuestion: Z,
|
|
7983
7994
|
previousQuestion: ae,
|
|
7984
|
-
nextLesson:
|
|
7985
|
-
previousLesson:
|
|
7986
|
-
completeLesson:
|
|
7995
|
+
nextLesson: K,
|
|
7996
|
+
previousLesson: pe,
|
|
7997
|
+
completeLesson: U,
|
|
7987
7998
|
completeCurriculum: oe,
|
|
7988
|
-
resetCurriculum:
|
|
7999
|
+
resetCurriculum: ee,
|
|
7989
8000
|
getState: () => ({ ...a.current }),
|
|
7990
|
-
getCurrentQuestion: () =>
|
|
8001
|
+
getCurrentQuestion: () => E(),
|
|
7991
8002
|
getCurrentLesson: () => f(),
|
|
7992
8003
|
// Direct access to avatar ref (always returns current value)
|
|
7993
8004
|
getAvatarRef: () => u.current,
|
|
@@ -8039,8 +8050,8 @@ const yt = Me(({
|
|
|
8039
8050
|
handleResize: () => u.current?.handleResize(),
|
|
8040
8051
|
// Avatar readiness check (always returns current value)
|
|
8041
8052
|
isAvatarReady: () => u.current?.isReady || !1
|
|
8042
|
-
}), [
|
|
8043
|
-
const
|
|
8053
|
+
}), [X, S, $, se, Z, K, U, oe, ee, E, f]);
|
|
8054
|
+
const O = w.current || {
|
|
8044
8055
|
avatarUrl: "/avatars/brunette.glb",
|
|
8045
8056
|
avatarBody: "F",
|
|
8046
8057
|
mood: "happy",
|
|
@@ -8053,22 +8064,22 @@ const yt = Me(({
|
|
|
8053
8064
|
showFullAvatar: !1,
|
|
8054
8065
|
animations: e
|
|
8055
8066
|
};
|
|
8056
|
-
return /* @__PURE__ */
|
|
8067
|
+
return /* @__PURE__ */ me("div", { style: { width: "100%", height: "100%" }, children: /* @__PURE__ */ me(
|
|
8057
8068
|
Ve,
|
|
8058
8069
|
{
|
|
8059
8070
|
ref: u,
|
|
8060
|
-
avatarUrl:
|
|
8061
|
-
avatarBody:
|
|
8062
|
-
mood:
|
|
8063
|
-
ttsLang:
|
|
8064
|
-
ttsService:
|
|
8065
|
-
ttsVoice:
|
|
8066
|
-
ttsApiKey:
|
|
8067
|
-
bodyMovement:
|
|
8068
|
-
movementIntensity:
|
|
8069
|
-
showFullAvatar:
|
|
8071
|
+
avatarUrl: O.avatarUrl,
|
|
8072
|
+
avatarBody: O.avatarBody,
|
|
8073
|
+
mood: O.mood,
|
|
8074
|
+
ttsLang: O.ttsLang,
|
|
8075
|
+
ttsService: O.ttsService,
|
|
8076
|
+
ttsVoice: O.ttsVoice,
|
|
8077
|
+
ttsApiKey: O.ttsApiKey,
|
|
8078
|
+
bodyMovement: O.bodyMovement,
|
|
8079
|
+
movementIntensity: O.movementIntensity,
|
|
8080
|
+
showFullAvatar: O.showFullAvatar,
|
|
8070
8081
|
cameraView: "upper",
|
|
8071
|
-
animations:
|
|
8082
|
+
animations: O.animations,
|
|
8072
8083
|
onReady: le,
|
|
8073
8084
|
onLoading: () => {
|
|
8074
8085
|
},
|
|
@@ -8182,7 +8193,7 @@ const Ge = {
|
|
|
8182
8193
|
duration: 5e3,
|
|
8183
8194
|
description: "Excited, energetic movement"
|
|
8184
8195
|
}
|
|
8185
|
-
}, wt = (
|
|
8196
|
+
}, wt = (G) => Ge[G] || null, zt = (G) => Ge.hasOwnProperty(G);
|
|
8186
8197
|
export {
|
|
8187
8198
|
yt as CurriculumLearning,
|
|
8188
8199
|
gt as SimpleTalkingAvatar,
|