@sage-rsc/talking-head-react 1.3.4 → 1.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +2 -2
- package/dist/index.js +335 -311
- package/package.json +1 -1
- package/src/components/SimpleTalkingAvatar.jsx +49 -13
- package/src/utils/animationLoader.js +19 -2
package/dist/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { jsxs as Pe, jsx as ye } from "react/jsx-runtime";
|
|
2
2
|
import { forwardRef as Me, useRef as W, useState as pe, useEffect as ce, useCallback as O, useImperativeHandle as Fe, useLayoutEffect as Xe } from "react";
|
|
3
3
|
import * as y from "three";
|
|
4
|
-
import { OrbitControls as
|
|
5
|
-
import { GLTFLoader as
|
|
4
|
+
import { OrbitControls as je } from "three/addons/controls/OrbitControls.js";
|
|
5
|
+
import { GLTFLoader as Ye } from "three/addons/loaders/GLTFLoader.js";
|
|
6
6
|
import { DRACOLoader as Qe } from "three/addons/loaders/DRACOLoader.js";
|
|
7
7
|
import { FBXLoader as De } from "three/addons/loaders/FBXLoader.js";
|
|
8
8
|
import { RoomEnvironment as qe } from "three/addons/environments/RoomEnvironment.js";
|
|
@@ -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
|
+
}, $ = new y.Quaternion(), Z = new y.Euler(), ve = new y.Vector3(), Re = new y.Vector3(), We = new y.Box3();
|
|
2633
2633
|
new y.Matrix4();
|
|
2634
2634
|
new y.Matrix4();
|
|
2635
2635
|
new y.Vector3();
|
|
@@ -4086,7 +4086,7 @@ class Be {
|
|
|
4086
4086
|
this.opt.lightSpotDispersion
|
|
4087
4087
|
), this.setLighting(this.opt);
|
|
4088
4088
|
const l = new y.PMREMGenerator(this.renderer);
|
|
4089
|
-
l.compileEquirectangularShader(), this.scene.environment = l.fromScene(new qe()).texture, this.resizeobserver = new ResizeObserver(this.onResize.bind(this)), this.resizeobserver.observe(this.nodeAvatar), this.controls = new
|
|
4089
|
+
l.compileEquirectangularShader(), this.scene.environment = l.fromScene(new qe()).texture, this.resizeobserver = new ResizeObserver(this.onResize.bind(this)), this.resizeobserver.observe(this.nodeAvatar), this.controls = new je(this.camera, this.renderer.domElement), this.controls.enableZoom = this.opt.cameraZoomEnable, this.controls.enableRotate = this.opt.cameraRotateEnable, this.controls.enablePan = this.opt.cameraPanEnable, this.controls.minDistance = 2, this.controls.maxDistance = 2e3, this.controls.autoRotateSpeed = 0, this.controls.autoRotate = !1, this.controls.update(), this.cameraClock = null;
|
|
4090
4090
|
}
|
|
4091
4091
|
this.ikMesh = new y.SkinnedMesh();
|
|
4092
4092
|
const s = {
|
|
@@ -4252,7 +4252,7 @@ class Be {
|
|
|
4252
4252
|
async showAvatar(t, e = null) {
|
|
4253
4253
|
if (!t || !t.hasOwnProperty("url"))
|
|
4254
4254
|
throw new Error("Invalid parameter. The avatar must have at least 'url' specified.");
|
|
4255
|
-
const n = new
|
|
4255
|
+
const n = new Ye();
|
|
4256
4256
|
if (this.dracoEnabled) {
|
|
4257
4257
|
const r = new Qe();
|
|
4258
4258
|
r.setDecoderPath(this.dracoDecoderPath), n.setDRACOLoader(r);
|
|
@@ -4398,9 +4398,9 @@ class Be {
|
|
|
4398
4398
|
updatePoseDelta() {
|
|
4399
4399
|
for (const [t, e] of Object.entries(this.poseDelta.props)) {
|
|
4400
4400
|
if (e.x === 0 && e.y === 0 && e.z === 0) continue;
|
|
4401
|
-
|
|
4401
|
+
Z.set(e.x, e.y, e.z);
|
|
4402
4402
|
const n = this.poseAvatar.props[t];
|
|
4403
|
-
n.isQuaternion ? (
|
|
4403
|
+
n.isQuaternion ? ($.setFromEuler(Z), n.multiply($)) : n.isVector3 && n.add(Z);
|
|
4404
4404
|
}
|
|
4405
4405
|
}
|
|
4406
4406
|
/**
|
|
@@ -5172,7 +5172,7 @@ class Be {
|
|
|
5172
5172
|
}, i.x ? new y.Vector3(i.x, i.y, i.z) : null, !0, i.d);
|
|
5173
5173
|
break;
|
|
5174
5174
|
}
|
|
5175
|
-
if ((h || r) && (
|
|
5175
|
+
if ((h || r) && (Z.setFromQuaternion(this.poseAvatar.props["Head.quaternion"]), Z.x = Math.max(-0.9, Math.min(0.9, 2 * Z.x - 0.5)), Z.y = Math.max(-0.9, Math.min(0.9, -2.5 * Z.y)), h ? (Object.assign(this.mtAvatar.eyesLookDown, { system: Z.x < 0 ? -Z.x : 0, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyesLookUp, { system: Z.x < 0 ? 0 : Z.x, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookInLeft, { system: Z.y < 0 ? -Z.y : 0, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookOutLeft, { system: Z.y < 0 ? 0 : Z.y, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookInRight, { system: Z.y < 0 ? 0 : Z.y, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookOutRight, { system: Z.y < 0 ? -Z.y : 0, needsUpdate: !0 }), r && (n = -this.mtAvatar.bodyRotateY.value, i = this.gaussianRandom(-0.2, 0.2), this.animQueue.push(this.animFactory({
|
|
5176
5176
|
name: "headmove",
|
|
5177
5177
|
dt: [[1e3, 2e3], [1e3, 2e3, 1, 2], [1e3, 2e3], [1e3, 2e3, 1, 2]],
|
|
5178
5178
|
vs: {
|
|
@@ -5193,7 +5193,7 @@ class Be {
|
|
|
5193
5193
|
eyeLookOutRight: [null, 0],
|
|
5194
5194
|
eyeContact: [0]
|
|
5195
5195
|
}
|
|
5196
|
-
})))), 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 && (
|
|
5196
|
+
})))), 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 && ($.setFromAxisAngle(mt, this.volumeHeadCurrent), this.objectNeck.quaternion.multiply($)), 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)
|
|
5197
5197
|
this.stats && this.stats.end();
|
|
5198
5198
|
else {
|
|
5199
5199
|
if (this.cameraClock !== null && this.cameraClock < 1e3) {
|
|
@@ -5264,10 +5264,10 @@ class Be {
|
|
|
5264
5264
|
let u = "", a = "", d = 0, c = [], g = [];
|
|
5265
5265
|
const x = Array.from(this.segmenter.segment(t), (f) => f.segment);
|
|
5266
5266
|
for (let f = 0; f < x.length; f++) {
|
|
5267
|
-
const k = f === x.length - 1,
|
|
5267
|
+
const k = f === x.length - 1, D = x[f].match(l);
|
|
5268
5268
|
let p = x[f].match(s);
|
|
5269
|
-
const B = x[f].match(h),
|
|
5270
|
-
if (p && !k && !B && x[f + 1].match(s) && (p = !1), n && (u += x[f]),
|
|
5269
|
+
const B = x[f].match(h), T = x[f].match(o);
|
|
5270
|
+
if (p && !k && !B && x[f + 1].match(s) && (p = !1), n && (u += x[f]), D && (!i || i.every((R) => f < R[0] || f > R[1])) && (a += x[f]), (T || p || k) && (a.length && (a = this.lipsyncPreProcessText(a, r), a.length && c.push({
|
|
5271
5271
|
mark: d,
|
|
5272
5272
|
word: a
|
|
5273
5273
|
})), u.length && (g.push({
|
|
@@ -5398,10 +5398,10 @@ class Be {
|
|
|
5398
5398
|
let x = 0.6 + this.convertRange(g, [0, u], [0, 0.4]);
|
|
5399
5399
|
if (u = Math.min(u, d.visemes.length * 200), c > 0)
|
|
5400
5400
|
for (let f = 0; f < d.visemes.length; f++) {
|
|
5401
|
-
const k = r + d.times[f] / c * u,
|
|
5401
|
+
const k = r + d.times[f] / c * u, D = d.durations[f] / c * u;
|
|
5402
5402
|
o.push({
|
|
5403
5403
|
template: { name: "viseme" },
|
|
5404
|
-
ts: [k - Math.min(60, 2 *
|
|
5404
|
+
ts: [k - Math.min(60, 2 * D / 3), k + Math.min(25, D / 2), k + D + Math.min(60, D / 2)],
|
|
5405
5405
|
vs: {
|
|
5406
5406
|
["viseme_" + d.visemes[f]]: [null, d.visemes[f] === "PP" || d.visemes[f] === "FF" ? 0.9 : x, 0]
|
|
5407
5407
|
}
|
|
@@ -5499,18 +5499,18 @@ class Be {
|
|
|
5499
5499
|
if (f && f.visemes && f.visemes.length > 0) {
|
|
5500
5500
|
const p = f.times[f.visemes.length - 1] + f.durations[f.visemes.length - 1];
|
|
5501
5501
|
for (let B = 0; B < f.visemes.length; B++) {
|
|
5502
|
-
const
|
|
5502
|
+
const T = f.visemes[B], R = f.times[B] / p, L = f.durations[B] / p, I = R * d, z = L * d;
|
|
5503
5503
|
k.push({
|
|
5504
5504
|
template: { name: "viseme" },
|
|
5505
5505
|
ts: [I - Math.min(60, 2 * z / 3), I + Math.min(25, z / 2), I + z + Math.min(60, z / 2)],
|
|
5506
5506
|
vs: {
|
|
5507
|
-
["viseme_" +
|
|
5507
|
+
["viseme_" + T]: [null, T === "PP" || T === "FF" ? 0.9 : 0.6, 0]
|
|
5508
5508
|
}
|
|
5509
5509
|
});
|
|
5510
5510
|
}
|
|
5511
5511
|
}
|
|
5512
|
-
const
|
|
5513
|
-
this.audioPlaylist.push({ anim:
|
|
5512
|
+
const D = [...t.anim, ...k];
|
|
5513
|
+
this.audioPlaylist.push({ anim: D, audio: c }), this.onSubtitles = t.onSubtitles || null, this.resetLips(), t.mood && this.setMood(t.mood), this.playAudio(), s.onend = () => {
|
|
5514
5514
|
e();
|
|
5515
5515
|
}, s.onerror = (p) => {
|
|
5516
5516
|
console.error("Speech synthesis error:", p.error), n(p.error);
|
|
@@ -6159,12 +6159,12 @@ class Be {
|
|
|
6159
6159
|
this.lookAt(null, null, t);
|
|
6160
6160
|
return;
|
|
6161
6161
|
}
|
|
6162
|
-
this.objectLeftEye.updateMatrixWorld(!0), this.objectRightEye.updateMatrixWorld(!0), ve.setFromMatrixPosition(this.objectLeftEye.matrixWorld), Re.setFromMatrixPosition(this.objectRightEye.matrixWorld), ve.add(Re).divideScalar(2),
|
|
6162
|
+
this.objectLeftEye.updateMatrixWorld(!0), this.objectRightEye.updateMatrixWorld(!0), ve.setFromMatrixPosition(this.objectLeftEye.matrixWorld), Re.setFromMatrixPosition(this.objectRightEye.matrixWorld), ve.add(Re).divideScalar(2), $.copy(this.armature.quaternion), $.multiply(this.poseTarget.props["Hips.quaternion"]), $.multiply(this.poseTarget.props["Spine.quaternion"]), $.multiply(this.poseTarget.props["Spine1.quaternion"]), $.multiply(this.poseTarget.props["Spine2.quaternion"]), $.multiply(this.poseTarget.props["Neck.quaternion"]), $.multiply(this.poseTarget.props["Head.quaternion"]);
|
|
6163
6163
|
const n = new y.Vector3().subVectors(e, ve).normalize(), i = Math.atan2(n.x, n.z), s = Math.asin(-n.y);
|
|
6164
|
-
|
|
6165
|
-
const l = new y.Quaternion().setFromEuler(
|
|
6166
|
-
|
|
6167
|
-
let r =
|
|
6164
|
+
Z.set(s, i, 0, "YXZ");
|
|
6165
|
+
const l = new y.Quaternion().setFromEuler(Z), h = new y.Quaternion().copy(l).multiply($.clone().invert());
|
|
6166
|
+
Z.setFromQuaternion(h, "YXZ");
|
|
6167
|
+
let r = Z.x / (40 / 24) + 0.2, u = Z.y / (9 / 4), a = Math.min(0.6, Math.max(-0.3, r)), d = Math.min(0.8, Math.max(-0.8, u)), c = (Math.random() - 0.5) / 4, g = (Math.random() - 0.5) / 4;
|
|
6168
6168
|
if (t) {
|
|
6169
6169
|
let x = this.animQueue.findIndex((k) => k.template.name === "lookat");
|
|
6170
6170
|
x !== -1 && this.animQueue.splice(x, 1);
|
|
@@ -6199,20 +6199,20 @@ class Be {
|
|
|
6199
6199
|
const s = new y.Vector3().setFromMatrixPosition(this.objectLeftEye.matrixWorld), o = new y.Vector3().setFromMatrixPosition(this.objectRightEye.matrixWorld), l = new y.Vector3().addVectors(s, o).divideScalar(2);
|
|
6200
6200
|
l.project(this.camera);
|
|
6201
6201
|
let h = (l.x + 1) / 2 * i.width + i.left, r = -(l.y - 1) / 2 * i.height + i.top;
|
|
6202
|
-
t === null && (t = h), e === null && (e = r),
|
|
6203
|
-
let u =
|
|
6202
|
+
t === null && (t = h), e === null && (e = r), $.copy(this.armature.quaternion), $.multiply(this.poseTarget.props["Hips.quaternion"]), $.multiply(this.poseTarget.props["Spine.quaternion"]), $.multiply(this.poseTarget.props["Spine1.quaternion"]), $.multiply(this.poseTarget.props["Spine2.quaternion"]), $.multiply(this.poseTarget.props["Neck.quaternion"]), $.multiply(this.poseTarget.props["Head.quaternion"]), Z.setFromQuaternion($);
|
|
6203
|
+
let u = Z.x / (40 / 24), a = Z.y / (9 / 4), d = Math.min(0.4, Math.max(-0.4, this.camera.rotation.x)), c = Math.min(0.4, Math.max(-0.4, this.camera.rotation.y)), g = Math.max(window.innerWidth - h, h), x = Math.max(window.innerHeight - r, r), f = this.convertRange(e, [r - x, r + x], [-0.3, 0.6]) - u + d, k = this.convertRange(t, [h - g, h + g], [-0.8, 0.8]) - a + c;
|
|
6204
6204
|
f = Math.min(0.6, Math.max(-0.3, f)), k = Math.min(0.8, Math.max(-0.8, k));
|
|
6205
|
-
let
|
|
6205
|
+
let D = (Math.random() - 0.5) / 4, p = (Math.random() - 0.5) / 4;
|
|
6206
6206
|
if (n) {
|
|
6207
6207
|
let B = this.animQueue.findIndex((R) => R.template.name === "lookat");
|
|
6208
6208
|
B !== -1 && this.animQueue.splice(B, 1);
|
|
6209
|
-
const
|
|
6209
|
+
const T = {
|
|
6210
6210
|
name: "lookat",
|
|
6211
6211
|
dt: [750, n],
|
|
6212
6212
|
vs: {
|
|
6213
|
-
bodyRotateX: [f +
|
|
6213
|
+
bodyRotateX: [f + D],
|
|
6214
6214
|
bodyRotateY: [k + p],
|
|
6215
|
-
eyesRotateX: [-3 *
|
|
6215
|
+
eyesRotateX: [-3 * D + 0.1],
|
|
6216
6216
|
eyesRotateY: [-5 * p],
|
|
6217
6217
|
browInnerUp: [[0, 0.7]],
|
|
6218
6218
|
mouthLeft: [[0, 0.7]],
|
|
@@ -6221,7 +6221,7 @@ class Be {
|
|
|
6221
6221
|
headMove: [0]
|
|
6222
6222
|
}
|
|
6223
6223
|
};
|
|
6224
|
-
this.animQueue.push(this.animFactory(
|
|
6224
|
+
this.animQueue.push(this.animFactory(T));
|
|
6225
6225
|
}
|
|
6226
6226
|
}
|
|
6227
6227
|
/**
|
|
@@ -6535,16 +6535,16 @@ class Be {
|
|
|
6535
6535
|
}), console.log("=== Ready Player Me Animation Bone Analysis ==="), console.log("FBX bone names:", Array.from(f).sort().join(", ")), console.log("Avatar skeleton bone names:", Array.from(c).sort().join(", "));
|
|
6536
6536
|
const k = Array.from(f).filter(
|
|
6537
6537
|
(L) => L.toLowerCase().includes("arm") || L.toLowerCase().includes("hand") || L.toLowerCase().includes("shoulder")
|
|
6538
|
-
),
|
|
6538
|
+
), D = Array.from(c).filter(
|
|
6539
6539
|
(L) => L.includes("Arm") || L.includes("Hand") || L.includes("Shoulder")
|
|
6540
6540
|
);
|
|
6541
|
-
console.log("FBX arm/hand/shoulder bones:", k.sort().join(", ")), console.log("Avatar arm/hand/shoulder bones:",
|
|
6541
|
+
console.log("FBX arm/hand/shoulder bones:", k.sort().join(", ")), console.log("Avatar arm/hand/shoulder bones:", D.sort().join(", "));
|
|
6542
6542
|
const p = [], B = /* @__PURE__ */ new Set();
|
|
6543
6543
|
if (d.tracks.forEach((L) => {
|
|
6544
6544
|
const z = L.name.replaceAll("mixamorig", "").split("."), Y = z[0], S = z[1], E = x(Y);
|
|
6545
6545
|
if (E && S) {
|
|
6546
|
-
const
|
|
6547
|
-
|
|
6546
|
+
const j = `${E}.${S}`, X = L.clone();
|
|
6547
|
+
X.name = j, p.push(X), Y !== E && g.set(Y, E);
|
|
6548
6548
|
} else
|
|
6549
6549
|
B.add(Y), (Y.toLowerCase().includes("arm") || Y.toLowerCase().includes("hand") || Y.toLowerCase().includes("shoulder")) && console.warn(`⚠️ Arm bone "${Y}" could not be mapped to avatar skeleton`);
|
|
6550
6550
|
}), B.size > 0 && console.warn(`⚠️ ${B.size} bone(s) could not be mapped:`, Array.from(B).sort().join(", ")), p.length > 0) {
|
|
@@ -6558,18 +6558,18 @@ class Be {
|
|
|
6558
6558
|
L.length > 0 ? console.log(`✓ Arm bones mapped: ${L.join(", ")}`) : console.warn("⚠️ No arm bones were mapped! This may cause arm rigging issues.");
|
|
6559
6559
|
} else
|
|
6560
6560
|
console.error("❌ No tracks could be mapped! Animation may not work correctly.");
|
|
6561
|
-
const
|
|
6561
|
+
const T = {};
|
|
6562
6562
|
d.tracks.forEach((L) => {
|
|
6563
6563
|
L.name = L.name.replaceAll("mixamorig", "");
|
|
6564
6564
|
const I = L.name.split(".");
|
|
6565
6565
|
if (I[1] === "position") {
|
|
6566
6566
|
for (let z = 0; z < L.values.length; z++)
|
|
6567
6567
|
L.values[z] = L.values[z] * s;
|
|
6568
|
-
|
|
6569
|
-
} else I[1] === "quaternion" ?
|
|
6568
|
+
T[L.name] = new y.Vector3(L.values[0], L.values[1], L.values[2]);
|
|
6569
|
+
} else I[1] === "quaternion" ? T[L.name] = new y.Quaternion(L.values[0], L.values[1], L.values[2], L.values[3]) : I[1] === "rotation" && (T[I[0] + ".quaternion"] = new y.Quaternion().setFromEuler(new y.Euler(L.values[0], L.values[1], L.values[2], "XYZ")).normalize());
|
|
6570
6570
|
});
|
|
6571
|
-
const R = { props:
|
|
6572
|
-
|
|
6571
|
+
const R = { props: T };
|
|
6572
|
+
T["Hips.position"] && (T["Hips.position"].y < 0.5 ? R.lying = !0 : R.standing = !0), this.animClips.push({
|
|
6573
6573
|
url: t + "-" + i,
|
|
6574
6574
|
clip: d,
|
|
6575
6575
|
pose: R
|
|
@@ -6707,12 +6707,12 @@ class Be {
|
|
|
6707
6707
|
const f = t.iterations || 10;
|
|
6708
6708
|
if (e)
|
|
6709
6709
|
for (let k = 0; k < f; k++) {
|
|
6710
|
-
let
|
|
6710
|
+
let D = !1;
|
|
6711
6711
|
for (let p = 0, B = x.length; p < B; p++) {
|
|
6712
|
-
const
|
|
6713
|
-
|
|
6712
|
+
const T = x[p].bone;
|
|
6713
|
+
T.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();
|
|
6714
6714
|
let R = s.dot(l);
|
|
6715
|
-
R > 1 ? R = 1 : R < -1 && (R = -1), R = Math.acos(R), !(R < 1e-5) && (x[p].minAngle !== void 0 && R < x[p].minAngle && (R = x[p].minAngle), x[p].maxAngle !== void 0 && R > x[p].maxAngle && (R = x[p].maxAngle), a.crossVectors(l, s), a.normalize(),
|
|
6715
|
+
R > 1 ? R = 1 : R < -1 && (R = -1), R = Math.acos(R), !(R < 1e-5) && (x[p].minAngle !== void 0 && R < x[p].minAngle && (R = x[p].minAngle), x[p].maxAngle !== void 0 && R > x[p].maxAngle && (R = x[p].maxAngle), a.crossVectors(l, s), a.normalize(), $.setFromAxisAngle(a, R), T.quaternion.multiply($), T.rotation.setFromVector3(d.setFromEuler(T.rotation).clamp(new y.Vector3(
|
|
6716
6716
|
x[p].minx !== void 0 ? x[p].minx : -1 / 0,
|
|
6717
6717
|
x[p].miny !== void 0 ? x[p].miny : -1 / 0,
|
|
6718
6718
|
x[p].minz !== void 0 ? x[p].minz : -1 / 0
|
|
@@ -6720,9 +6720,9 @@ class Be {
|
|
|
6720
6720
|
x[p].maxx !== void 0 ? x[p].maxx : 1 / 0,
|
|
6721
6721
|
x[p].maxy !== void 0 ? x[p].maxy : 1 / 0,
|
|
6722
6722
|
x[p].maxz !== void 0 ? x[p].maxz : 1 / 0
|
|
6723
|
-
))),
|
|
6723
|
+
))), T.updateMatrixWorld(!0), D = !0);
|
|
6724
6724
|
}
|
|
6725
|
-
if (!
|
|
6725
|
+
if (!D) break;
|
|
6726
6726
|
}
|
|
6727
6727
|
i && x.forEach((k) => {
|
|
6728
6728
|
this.poseTarget.props[k.link + ".quaternion"].copy(k.bone.quaternion), this.poseTarget.props[k.link + ".quaternion"].t = this.animClock, this.poseTarget.props[k.link + ".quaternion"].d = i;
|
|
@@ -6815,70 +6815,70 @@ const Ve = Me(({
|
|
|
6815
6815
|
style: x = {},
|
|
6816
6816
|
animations: f = {}
|
|
6817
6817
|
}, k) => {
|
|
6818
|
-
const
|
|
6818
|
+
const D = W(null), p = W(null), B = W(r), T = W(null), R = W(null), L = W(!1), I = W({ remainingText: null, originalText: null, options: null }), z = W([]), Y = W(0), [S, E] = pe(!0), [j, X] = pe(null), [oe, le] = pe(!1), [ge, de] = pe(!1);
|
|
6819
6819
|
ce(() => {
|
|
6820
6820
|
L.current = ge;
|
|
6821
6821
|
}, [ge]), ce(() => {
|
|
6822
6822
|
B.current = r;
|
|
6823
6823
|
}, [r]);
|
|
6824
|
-
const
|
|
6825
|
-
let
|
|
6826
|
-
be === "browser" ?
|
|
6824
|
+
const ee = Ee(), be = i || ee.service;
|
|
6825
|
+
let Q;
|
|
6826
|
+
be === "browser" ? Q = {
|
|
6827
6827
|
service: "browser",
|
|
6828
6828
|
endpoint: "",
|
|
6829
6829
|
apiKey: null,
|
|
6830
6830
|
defaultVoice: "Google US English"
|
|
6831
|
-
} : be === "elevenlabs" ?
|
|
6831
|
+
} : be === "elevenlabs" ? Q = {
|
|
6832
6832
|
service: "elevenlabs",
|
|
6833
6833
|
endpoint: "https://api.elevenlabs.io/v1/text-to-speech",
|
|
6834
|
-
apiKey: o ||
|
|
6835
|
-
defaultVoice: s ||
|
|
6836
|
-
voices:
|
|
6837
|
-
} : be === "deepgram" ?
|
|
6834
|
+
apiKey: o || ee.apiKey,
|
|
6835
|
+
defaultVoice: s || ee.defaultVoice || Ie.defaultVoice,
|
|
6836
|
+
voices: ee.voices || Ie.voices
|
|
6837
|
+
} : be === "deepgram" ? Q = {
|
|
6838
6838
|
service: "deepgram",
|
|
6839
6839
|
endpoint: "https://api.deepgram.com/v1/speak",
|
|
6840
|
-
apiKey: o ||
|
|
6841
|
-
defaultVoice: s ||
|
|
6842
|
-
voices:
|
|
6843
|
-
} :
|
|
6844
|
-
|
|
6840
|
+
apiKey: o || ee.apiKey,
|
|
6841
|
+
defaultVoice: s || ee.defaultVoice || Te.defaultVoice,
|
|
6842
|
+
voices: ee.voices || Te.voices
|
|
6843
|
+
} : Q = {
|
|
6844
|
+
...ee,
|
|
6845
6845
|
// Override API key if provided via props
|
|
6846
|
-
apiKey: o !== null ? o :
|
|
6846
|
+
apiKey: o !== null ? o : ee.apiKey
|
|
6847
6847
|
};
|
|
6848
6848
|
const b = {
|
|
6849
6849
|
url: V,
|
|
6850
6850
|
body: t,
|
|
6851
6851
|
avatarMood: e,
|
|
6852
6852
|
ttsLang: be === "browser" ? "en-US" : n,
|
|
6853
|
-
ttsVoice: s ||
|
|
6853
|
+
ttsVoice: s || Q.defaultVoice,
|
|
6854
6854
|
lipsyncLang: "en",
|
|
6855
6855
|
showFullAvatar: r,
|
|
6856
6856
|
bodyMovement: l,
|
|
6857
6857
|
movementIntensity: h
|
|
6858
6858
|
}, v = {
|
|
6859
|
-
ttsEndpoint:
|
|
6860
|
-
ttsApikey:
|
|
6859
|
+
ttsEndpoint: Q.endpoint,
|
|
6860
|
+
ttsApikey: Q.apiKey,
|
|
6861
6861
|
ttsService: be,
|
|
6862
6862
|
lipsyncModules: ["en"],
|
|
6863
6863
|
cameraView: u
|
|
6864
6864
|
}, F = O(async () => {
|
|
6865
|
-
if (!(!
|
|
6865
|
+
if (!(!D.current || p.current))
|
|
6866
6866
|
try {
|
|
6867
|
-
if (E(!0),
|
|
6868
|
-
if (
|
|
6869
|
-
const
|
|
6870
|
-
d(
|
|
6867
|
+
if (E(!0), X(null), p.current = new Be(D.current, v), p.current.controls && (p.current.controls.enableRotate = !1, p.current.controls.enableZoom = !1, p.current.controls.enablePan = !1, p.current.controls.enableDamping = !1), f && Object.keys(f).length > 0 && (p.current.customAnimations = f), await p.current.showAvatar(b, (K) => {
|
|
6868
|
+
if (K.lengthComputable) {
|
|
6869
|
+
const ne = Math.min(100, Math.round(K.loaded / K.total * 100));
|
|
6870
|
+
d(ne);
|
|
6871
6871
|
}
|
|
6872
|
-
}), await new Promise((
|
|
6873
|
-
const
|
|
6874
|
-
p.current.lipsync && Object.keys(p.current.lipsync).length > 0 ?
|
|
6872
|
+
}), await new Promise((K) => {
|
|
6873
|
+
const ne = () => {
|
|
6874
|
+
p.current.lipsync && Object.keys(p.current.lipsync).length > 0 ? K() : setTimeout(ne, 100);
|
|
6875
6875
|
};
|
|
6876
|
-
|
|
6876
|
+
ne();
|
|
6877
6877
|
}), p.current && p.current.setShowFullAvatar)
|
|
6878
6878
|
try {
|
|
6879
6879
|
p.current.setShowFullAvatar(r);
|
|
6880
|
-
} catch (
|
|
6881
|
-
console.warn("Error setting full body mode on initialization:",
|
|
6880
|
+
} catch (K) {
|
|
6881
|
+
console.warn("Error setting full body mode on initialization:", K);
|
|
6882
6882
|
}
|
|
6883
6883
|
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()), E(!1), le(!0), a(p.current);
|
|
6884
6884
|
const U = () => {
|
|
@@ -6888,18 +6888,18 @@ const Ve = Me(({
|
|
|
6888
6888
|
document.removeEventListener("visibilitychange", U);
|
|
6889
6889
|
};
|
|
6890
6890
|
} catch (w) {
|
|
6891
|
-
console.error("Error initializing TalkingHead:", w),
|
|
6891
|
+
console.error("Error initializing TalkingHead:", w), X(w.message || "Failed to initialize avatar"), E(!1), c(w);
|
|
6892
6892
|
}
|
|
6893
6893
|
}, [V, t, e, n, i, s, o, r, l, h, u]);
|
|
6894
6894
|
ce(() => (F(), () => {
|
|
6895
6895
|
p.current && (p.current.stop(), p.current.dispose(), p.current = null);
|
|
6896
6896
|
}), [F]), ce(() => {
|
|
6897
|
-
if (!
|
|
6898
|
-
const w = new ResizeObserver((
|
|
6899
|
-
for (const
|
|
6897
|
+
if (!D.current || !p.current) return;
|
|
6898
|
+
const w = new ResizeObserver((K) => {
|
|
6899
|
+
for (const ne of K)
|
|
6900
6900
|
p.current && p.current.onResize && p.current.onResize();
|
|
6901
6901
|
});
|
|
6902
|
-
w.observe(
|
|
6902
|
+
w.observe(D.current);
|
|
6903
6903
|
const U = () => {
|
|
6904
6904
|
p.current && p.current.onResize && p.current.onResize();
|
|
6905
6905
|
};
|
|
@@ -6914,26 +6914,26 @@ const Ve = Me(({
|
|
|
6914
6914
|
} catch (w) {
|
|
6915
6915
|
console.warn("Failed to resume audio context:", w);
|
|
6916
6916
|
}
|
|
6917
|
-
}, []),
|
|
6917
|
+
}, []), N = O(async (w, U = {}) => {
|
|
6918
6918
|
if (p.current && oe)
|
|
6919
6919
|
try {
|
|
6920
|
-
R.current && (clearInterval(R.current), R.current = null),
|
|
6921
|
-
const
|
|
6922
|
-
z.current =
|
|
6920
|
+
R.current && (clearInterval(R.current), R.current = null), T.current = { text: w, options: U }, I.current = { remainingText: null, originalText: null, options: null };
|
|
6921
|
+
const K = /[!\.\?\n\p{Extended_Pictographic}]/ug, ne = w.split(K).map((A) => A.trim()).filter((A) => A.length > 0);
|
|
6922
|
+
z.current = ne, Y.current = 0, de(!1), L.current = !1, await P();
|
|
6923
6923
|
const me = {
|
|
6924
6924
|
...U,
|
|
6925
6925
|
lipsyncLang: U.lipsyncLang || b.lipsyncLang || "en"
|
|
6926
6926
|
};
|
|
6927
6927
|
if (U.onSpeechEnd && p.current) {
|
|
6928
6928
|
const A = p.current;
|
|
6929
|
-
let
|
|
6930
|
-
const
|
|
6929
|
+
let H = null, G = 0;
|
|
6930
|
+
const J = 1200;
|
|
6931
6931
|
let ie = !1;
|
|
6932
|
-
|
|
6933
|
-
if (
|
|
6932
|
+
H = setInterval(() => {
|
|
6933
|
+
if (G++, L.current)
|
|
6934
6934
|
return;
|
|
6935
|
-
if (
|
|
6936
|
-
if (
|
|
6935
|
+
if (G > J) {
|
|
6936
|
+
if (H && (clearInterval(H), H = null, R.current = null), !ie && !L.current) {
|
|
6937
6937
|
ie = !0;
|
|
6938
6938
|
try {
|
|
6939
6939
|
U.onSpeechEnd();
|
|
@@ -6946,7 +6946,7 @@ const Ve = Me(({
|
|
|
6946
6946
|
const se = !A.speechQueue || A.speechQueue.length === 0, we = !A.audioPlaylist || A.audioPlaylist.length === 0;
|
|
6947
6947
|
A && A.isSpeaking === !1 && se && we && A.isAudioPlaying === !1 && !ie && !L.current && setTimeout(() => {
|
|
6948
6948
|
if (A && !L.current && A.isSpeaking === !1 && (!A.speechQueue || A.speechQueue.length === 0) && (!A.audioPlaylist || A.audioPlaylist.length === 0) && A.isAudioPlaying === !1 && !ie && !L.current) {
|
|
6949
|
-
ie = !0,
|
|
6949
|
+
ie = !0, H && (clearInterval(H), H = null, R.current = null);
|
|
6950
6950
|
try {
|
|
6951
6951
|
U.onSpeechEnd();
|
|
6952
6952
|
} catch (Ze) {
|
|
@@ -6954,59 +6954,59 @@ const Ve = Me(({
|
|
|
6954
6954
|
}
|
|
6955
6955
|
}
|
|
6956
6956
|
}, 100);
|
|
6957
|
-
}, 100), R.current =
|
|
6957
|
+
}, 100), R.current = H;
|
|
6958
6958
|
}
|
|
6959
6959
|
p.current.lipsync && Object.keys(p.current.lipsync).length > 0 ? (p.current.setSlowdownRate && p.current.setSlowdownRate(1.05), p.current.speakText(w, me)) : setTimeout(async () => {
|
|
6960
6960
|
await P(), p.current && p.current.lipsync && (p.current.setSlowdownRate && p.current.setSlowdownRate(1.05), p.current.speakText(w, me));
|
|
6961
6961
|
}, 100);
|
|
6962
|
-
} catch (
|
|
6963
|
-
console.error("Error speaking text:",
|
|
6962
|
+
} catch (K) {
|
|
6963
|
+
console.error("Error speaking text:", K), X(K.message || "Failed to speak text");
|
|
6964
6964
|
}
|
|
6965
|
-
}, [oe, P, b.lipsyncLang]),
|
|
6966
|
-
p.current && (p.current.stopSpeaking(), p.current.setSlowdownRate && p.current.setSlowdownRate(1),
|
|
6967
|
-
}, []),
|
|
6965
|
+
}, [oe, P, b.lipsyncLang]), te = O(() => {
|
|
6966
|
+
p.current && (p.current.stopSpeaking(), p.current.setSlowdownRate && p.current.setSlowdownRate(1), T.current = null, de(!1));
|
|
6967
|
+
}, []), q = O(() => {
|
|
6968
6968
|
if (p.current && p.current.pauseSpeaking) {
|
|
6969
6969
|
const w = p.current;
|
|
6970
6970
|
if (w.isSpeaking || w.audioPlaylist && w.audioPlaylist.length > 0 || w.speechQueue && w.speechQueue.length > 0) {
|
|
6971
6971
|
R.current && (clearInterval(R.current), R.current = null);
|
|
6972
|
-
let
|
|
6973
|
-
if (
|
|
6974
|
-
const
|
|
6975
|
-
if (
|
|
6972
|
+
let K = "";
|
|
6973
|
+
if (T.current && z.current.length > 0) {
|
|
6974
|
+
const ne = z.current.length, me = w.speechQueue ? w.speechQueue.filter((J) => J && J.text && Array.isArray(J.text) && J.text.length > 0).length : 0, A = w.audioPlaylist && w.audioPlaylist.length > 0, H = me + (A ? 1 : 0), G = ne - H;
|
|
6975
|
+
if (H > 0 && G < ne && (K = z.current.slice(G).join(". ").trim(), !K && me > 0 && w.speechQueue)) {
|
|
6976
6976
|
const ie = w.speechQueue.filter((se) => se && se.text && Array.isArray(se.text) && se.text.length > 0).map((se) => se.text.map((we) => we.word || "").filter((we) => we.length > 0).join(" ")).filter((se) => se.length > 0).join(" ");
|
|
6977
|
-
ie && ie.trim() && (
|
|
6977
|
+
ie && ie.trim() && (K = ie.trim());
|
|
6978
6978
|
}
|
|
6979
6979
|
}
|
|
6980
|
-
|
|
6981
|
-
remainingText:
|
|
6982
|
-
originalText:
|
|
6983
|
-
options:
|
|
6980
|
+
T.current && (I.current = {
|
|
6981
|
+
remainingText: K || null,
|
|
6982
|
+
originalText: T.current.text,
|
|
6983
|
+
options: T.current.options
|
|
6984
6984
|
}), w.speechQueue && (w.speechQueue.length = 0), p.current.pauseSpeaking(), L.current = !0, de(!0);
|
|
6985
6985
|
}
|
|
6986
6986
|
}
|
|
6987
|
-
}, []),
|
|
6987
|
+
}, []), _ = O(async () => {
|
|
6988
6988
|
if (!p.current || !ge)
|
|
6989
6989
|
return;
|
|
6990
6990
|
let w = "", U = {};
|
|
6991
6991
|
if (I.current && I.current.remainingText)
|
|
6992
6992
|
w = I.current.remainingText, U = I.current.options || {}, I.current = { remainingText: null, originalText: null, options: null };
|
|
6993
|
-
else if (
|
|
6994
|
-
w =
|
|
6993
|
+
else if (T.current && T.current.text)
|
|
6994
|
+
w = T.current.text, U = T.current.options || {};
|
|
6995
6995
|
else {
|
|
6996
6996
|
console.warn("Resume called but no paused speech found"), de(!1), L.current = !1;
|
|
6997
6997
|
return;
|
|
6998
6998
|
}
|
|
6999
6999
|
de(!1), L.current = !1, await P();
|
|
7000
|
-
const
|
|
7000
|
+
const K = {
|
|
7001
7001
|
...U,
|
|
7002
7002
|
lipsyncLang: U.lipsyncLang || b.lipsyncLang || "en"
|
|
7003
7003
|
};
|
|
7004
7004
|
try {
|
|
7005
|
-
await
|
|
7006
|
-
} catch (
|
|
7007
|
-
console.error("Error resuming speech:",
|
|
7005
|
+
await N(w, K);
|
|
7006
|
+
} catch (ne) {
|
|
7007
|
+
console.error("Error resuming speech:", ne), de(!1), L.current = !1;
|
|
7008
7008
|
}
|
|
7009
|
-
}, [P, ge,
|
|
7009
|
+
}, [P, ge, N, b]), Ae = O((w) => {
|
|
7010
7010
|
p.current && p.current.setMood(w);
|
|
7011
7011
|
}, []), Se = O((w) => {
|
|
7012
7012
|
p.current && p.current.setSlowdownRate && p.current.setSlowdownRate(w);
|
|
@@ -7015,14 +7015,14 @@ const Ve = Me(({
|
|
|
7015
7015
|
if (f && f[w] && (w = f[w]), p.current.setShowFullAvatar)
|
|
7016
7016
|
try {
|
|
7017
7017
|
p.current.setShowFullAvatar(B.current);
|
|
7018
|
-
} catch (
|
|
7019
|
-
console.warn("Error setting full body mode:",
|
|
7018
|
+
} catch (ne) {
|
|
7019
|
+
console.warn("Error setting full body mode:", ne);
|
|
7020
7020
|
}
|
|
7021
7021
|
if (w.includes("."))
|
|
7022
7022
|
try {
|
|
7023
7023
|
p.current.playAnimation(w, null, 10, 0, 0.01, U);
|
|
7024
|
-
} catch (
|
|
7025
|
-
console.warn(`Failed to play ${w}:`,
|
|
7024
|
+
} catch (ne) {
|
|
7025
|
+
console.warn(`Failed to play ${w}:`, ne);
|
|
7026
7026
|
try {
|
|
7027
7027
|
p.current.setBodyMovement("idle");
|
|
7028
7028
|
} catch (me) {
|
|
@@ -7030,9 +7030,9 @@ const Ve = Me(({
|
|
|
7030
7030
|
}
|
|
7031
7031
|
}
|
|
7032
7032
|
else {
|
|
7033
|
-
const
|
|
7033
|
+
const ne = [".fbx", ".glb", ".gltf"];
|
|
7034
7034
|
let me = !1;
|
|
7035
|
-
for (const A of
|
|
7035
|
+
for (const A of ne)
|
|
7036
7036
|
try {
|
|
7037
7037
|
p.current.playAnimation(w + A, null, 10, 0, 0.01, U), me = !0;
|
|
7038
7038
|
break;
|
|
@@ -7052,10 +7052,10 @@ const Ve = Me(({
|
|
|
7052
7052
|
p.current && p.current.onResize && p.current.onResize();
|
|
7053
7053
|
}, []);
|
|
7054
7054
|
return Fe(k, () => ({
|
|
7055
|
-
speakText:
|
|
7056
|
-
stopSpeaking:
|
|
7057
|
-
pauseSpeaking:
|
|
7058
|
-
resumeSpeaking:
|
|
7055
|
+
speakText: N,
|
|
7056
|
+
stopSpeaking: te,
|
|
7057
|
+
pauseSpeaking: q,
|
|
7058
|
+
resumeSpeaking: _,
|
|
7059
7059
|
resumeAudioContext: P,
|
|
7060
7060
|
setMood: Ae,
|
|
7061
7061
|
setTimingAdjustment: Se,
|
|
@@ -7135,7 +7135,7 @@ const Ve = Me(({
|
|
|
7135
7135
|
/* @__PURE__ */ ye(
|
|
7136
7136
|
"div",
|
|
7137
7137
|
{
|
|
7138
|
-
ref:
|
|
7138
|
+
ref: D,
|
|
7139
7139
|
className: "talking-head-viewer",
|
|
7140
7140
|
style: {
|
|
7141
7141
|
width: "100%",
|
|
@@ -7153,7 +7153,7 @@ const Ve = Me(({
|
|
|
7153
7153
|
fontSize: "18px",
|
|
7154
7154
|
zIndex: 10
|
|
7155
7155
|
}, children: "Loading avatar..." }),
|
|
7156
|
-
|
|
7156
|
+
j && /* @__PURE__ */ ye("div", { className: "error-overlay", style: {
|
|
7157
7157
|
position: "absolute",
|
|
7158
7158
|
top: "50%",
|
|
7159
7159
|
left: "50%",
|
|
@@ -7164,7 +7164,7 @@ const Ve = Me(({
|
|
|
7164
7164
|
zIndex: 10,
|
|
7165
7165
|
padding: "20px",
|
|
7166
7166
|
borderRadius: "8px"
|
|
7167
|
-
}, children:
|
|
7167
|
+
}, children: j })
|
|
7168
7168
|
]
|
|
7169
7169
|
}
|
|
7170
7170
|
);
|
|
@@ -7182,7 +7182,7 @@ const pt = Me(({
|
|
|
7182
7182
|
style: s = {},
|
|
7183
7183
|
avatarConfig: o = {}
|
|
7184
7184
|
}, l) => {
|
|
7185
|
-
const h = W(null), r = W(null), [u, a] = pe(!0), [d, c] = pe(null), [g, x] = pe(!1), f = Ee(), k = o.ttsService || f.service,
|
|
7185
|
+
const h = W(null), r = W(null), [u, a] = pe(!0), [d, c] = pe(null), [g, x] = pe(!1), f = Ee(), k = o.ttsService || f.service, D = k === "browser" ? {
|
|
7186
7186
|
endpoint: "",
|
|
7187
7187
|
apiKey: null,
|
|
7188
7188
|
defaultVoice: "Google US English"
|
|
@@ -7198,7 +7198,7 @@ const pt = Me(({
|
|
|
7198
7198
|
body: "F",
|
|
7199
7199
|
avatarMood: "neutral",
|
|
7200
7200
|
ttsLang: k === "browser" ? "en-US" : "en",
|
|
7201
|
-
ttsVoice: o.ttsVoice ||
|
|
7201
|
+
ttsVoice: o.ttsVoice || D.defaultVoice,
|
|
7202
7202
|
lipsyncLang: "en",
|
|
7203
7203
|
// English lip-sync
|
|
7204
7204
|
showFullAvatar: !0,
|
|
@@ -7207,35 +7207,35 @@ const pt = Me(({
|
|
|
7207
7207
|
movementIntensity: 0.5,
|
|
7208
7208
|
...o
|
|
7209
7209
|
}, B = {
|
|
7210
|
-
ttsEndpoint:
|
|
7211
|
-
ttsApikey:
|
|
7210
|
+
ttsEndpoint: D.endpoint,
|
|
7211
|
+
ttsApikey: D.apiKey,
|
|
7212
7212
|
ttsService: k,
|
|
7213
7213
|
lipsyncModules: ["en"],
|
|
7214
7214
|
cameraView: "upper"
|
|
7215
|
-
},
|
|
7215
|
+
}, T = O(async () => {
|
|
7216
7216
|
if (!(!h.current || r.current))
|
|
7217
7217
|
try {
|
|
7218
|
-
if (a(!0), c(null), r.current = new Be(h.current, B), await r.current.showAvatar(p, (
|
|
7219
|
-
if (
|
|
7220
|
-
const
|
|
7221
|
-
t(
|
|
7218
|
+
if (a(!0), c(null), r.current = new Be(h.current, B), await r.current.showAvatar(p, (j) => {
|
|
7219
|
+
if (j.lengthComputable) {
|
|
7220
|
+
const X = Math.min(100, Math.round(j.loaded / j.total * 100));
|
|
7221
|
+
t(X);
|
|
7222
7222
|
}
|
|
7223
7223
|
}), r.current.morphs && r.current.morphs.length > 0) {
|
|
7224
|
-
const
|
|
7225
|
-
console.log("Available morph targets:", Object.keys(
|
|
7226
|
-
const
|
|
7227
|
-
console.log("Viseme morph targets found:",
|
|
7224
|
+
const j = r.current.morphs[0].morphTargetDictionary;
|
|
7225
|
+
console.log("Available morph targets:", Object.keys(j));
|
|
7226
|
+
const X = Object.keys(j).filter((oe) => oe.startsWith("viseme_"));
|
|
7227
|
+
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"));
|
|
7228
7228
|
}
|
|
7229
|
-
if (await new Promise((
|
|
7230
|
-
const
|
|
7231
|
-
r.current.lipsync && Object.keys(r.current.lipsync).length > 0 ? (console.log("Lip-sync modules loaded:", Object.keys(r.current.lipsync)),
|
|
7229
|
+
if (await new Promise((j) => {
|
|
7230
|
+
const X = () => {
|
|
7231
|
+
r.current.lipsync && Object.keys(r.current.lipsync).length > 0 ? (console.log("Lip-sync modules loaded:", Object.keys(r.current.lipsync)), j()) : (console.log("Waiting for lip-sync modules to load..."), setTimeout(X, 100));
|
|
7232
7232
|
};
|
|
7233
|
-
|
|
7233
|
+
X();
|
|
7234
7234
|
}), r.current && r.current.setShowFullAvatar)
|
|
7235
7235
|
try {
|
|
7236
7236
|
r.current.setShowFullAvatar(!0), console.log("Avatar initialized in full body mode");
|
|
7237
|
-
} catch (
|
|
7238
|
-
console.warn("Error setting full body mode on initialization:",
|
|
7237
|
+
} catch (j) {
|
|
7238
|
+
console.warn("Error setting full body mode on initialization:", j);
|
|
7239
7239
|
}
|
|
7240
7240
|
a(!1), x(!0), n(r.current);
|
|
7241
7241
|
const E = () => {
|
|
@@ -7248,9 +7248,9 @@ const pt = Me(({
|
|
|
7248
7248
|
console.error("Error initializing TalkingHead:", S), c(S.message || "Failed to initialize avatar"), a(!1), e(S);
|
|
7249
7249
|
}
|
|
7250
7250
|
}, []);
|
|
7251
|
-
ce(() => (
|
|
7251
|
+
ce(() => (T(), () => {
|
|
7252
7252
|
r.current && (r.current.stop(), r.current.dispose(), r.current = null);
|
|
7253
|
-
}), [
|
|
7253
|
+
}), [T]);
|
|
7254
7254
|
const R = O((S) => {
|
|
7255
7255
|
if (r.current && g)
|
|
7256
7256
|
try {
|
|
@@ -7273,14 +7273,14 @@ const pt = Me(({
|
|
|
7273
7273
|
if (r.current.setShowFullAvatar)
|
|
7274
7274
|
try {
|
|
7275
7275
|
r.current.setShowFullAvatar(!0);
|
|
7276
|
-
} catch (
|
|
7277
|
-
console.warn("Error setting full body mode:",
|
|
7276
|
+
} catch (X) {
|
|
7277
|
+
console.warn("Error setting full body mode:", X);
|
|
7278
7278
|
}
|
|
7279
7279
|
if (S.includes("."))
|
|
7280
7280
|
try {
|
|
7281
7281
|
r.current.playAnimation(S, null, 10, 0, 0.01, E), console.log("Playing animation:", S);
|
|
7282
|
-
} catch (
|
|
7283
|
-
console.log(`Failed to play ${S}:`,
|
|
7282
|
+
} catch (X) {
|
|
7283
|
+
console.log(`Failed to play ${S}:`, X);
|
|
7284
7284
|
try {
|
|
7285
7285
|
r.current.setBodyMovement("idle"), console.log("Fallback to idle animation");
|
|
7286
7286
|
} catch (oe) {
|
|
@@ -7288,9 +7288,9 @@ const pt = Me(({
|
|
|
7288
7288
|
}
|
|
7289
7289
|
}
|
|
7290
7290
|
else {
|
|
7291
|
-
const
|
|
7291
|
+
const X = [".fbx", ".glb", ".gltf"];
|
|
7292
7292
|
let oe = !1;
|
|
7293
|
-
for (const le of
|
|
7293
|
+
for (const le of X)
|
|
7294
7294
|
try {
|
|
7295
7295
|
r.current.playAnimation(S + le, null, 10, 0, 0.01, E), console.log("Playing animation:", S + le), oe = !0;
|
|
7296
7296
|
break;
|
|
@@ -7413,9 +7413,20 @@ const pt = Me(({
|
|
|
7413
7413
|
pt.displayName = "TalkingHeadComponent";
|
|
7414
7414
|
async function gt(V) {
|
|
7415
7415
|
try {
|
|
7416
|
-
|
|
7416
|
+
console.log(`📥 Loading animation manifest from: ${V}`);
|
|
7417
|
+
const t = await fetch(V);
|
|
7418
|
+
if (!t.ok)
|
|
7419
|
+
throw new Error(`Failed to fetch manifest: ${t.status} ${t.statusText}`);
|
|
7420
|
+
const e = await t.json();
|
|
7421
|
+
console.log("📦 Raw manifest loaded:", e);
|
|
7422
|
+
const n = e.animations || {};
|
|
7423
|
+
return console.log("✅ Processed animations object:", n), n._genderSpecific && console.log("👥 Gender-specific structure detected:", {
|
|
7424
|
+
male: Object.keys(n._genderSpecific.male || {}),
|
|
7425
|
+
female: Object.keys(n._genderSpecific.female || {}),
|
|
7426
|
+
shared: Object.keys(n._genderSpecific.shared || {})
|
|
7427
|
+
}), n;
|
|
7417
7428
|
} catch (t) {
|
|
7418
|
-
return console.error("Failed to load animation manifest:", t), {};
|
|
7429
|
+
return console.error("❌ Failed to load animation manifest:", t), {};
|
|
7419
7430
|
}
|
|
7420
7431
|
}
|
|
7421
7432
|
const yt = Me(({
|
|
@@ -7441,84 +7452,86 @@ const yt = Me(({
|
|
|
7441
7452
|
},
|
|
7442
7453
|
className: f = "",
|
|
7443
7454
|
style: k = {},
|
|
7444
|
-
animations:
|
|
7455
|
+
animations: D = {},
|
|
7445
7456
|
autoAnimationGroup: p = null,
|
|
7446
7457
|
// e.g., "talking" - will randomly select from this group when speaking
|
|
7447
7458
|
autoIdleGroup: B = null,
|
|
7448
7459
|
// e.g., "idle" - will randomly select from this group when idle
|
|
7449
|
-
autoSpeak:
|
|
7460
|
+
autoSpeak: T = !1
|
|
7450
7461
|
}, R) => {
|
|
7451
|
-
const L = W(null), I = W(null), z = W(u), Y = W(null), S = W(null), E = W(!1),
|
|
7462
|
+
const L = W(null), I = W(null), z = W(u), Y = W(null), S = W(null), E = W(!1), j = W({ remainingText: null, originalText: null, options: null }), X = W([]), [oe, le] = pe(!0), [ge, de] = pe(null), [ee, be] = pe(!1), [Q, b] = pe(!1), [v, F] = pe(D), P = W(null);
|
|
7452
7463
|
ce(() => {
|
|
7453
|
-
E.current =
|
|
7454
|
-
}, [
|
|
7464
|
+
E.current = Q;
|
|
7465
|
+
}, [Q]), ce(() => {
|
|
7455
7466
|
(async () => {
|
|
7456
|
-
if (
|
|
7467
|
+
if (D.manifest)
|
|
7457
7468
|
try {
|
|
7458
|
-
|
|
7459
|
-
|
|
7460
|
-
|
|
7461
|
-
|
|
7462
|
-
|
|
7463
|
-
|
|
7464
|
-
console.
|
|
7469
|
+
console.log("🔄 Loading animations from manifest:", D.manifest);
|
|
7470
|
+
const H = await gt(D.manifest);
|
|
7471
|
+
F(H), console.log("✅ Animations loaded and set:", H), H._genderSpecific ? console.log("👥 Gender-specific animations detected:", {
|
|
7472
|
+
male: Object.keys(H._genderSpecific.male || {}),
|
|
7473
|
+
female: Object.keys(H._genderSpecific.female || {}),
|
|
7474
|
+
shared: Object.keys(H._genderSpecific.shared || {})
|
|
7475
|
+
}) : console.log("⚠️ No gender-specific animations found in manifest");
|
|
7476
|
+
} catch (H) {
|
|
7477
|
+
console.error("❌ Failed to load animation manifest:", H), F(D);
|
|
7465
7478
|
}
|
|
7466
7479
|
else
|
|
7467
|
-
F(
|
|
7480
|
+
console.log("📝 Using animations from props (no manifest):", D), F(D);
|
|
7468
7481
|
})();
|
|
7469
|
-
}, [
|
|
7482
|
+
}, [D]), ce(() => {
|
|
7470
7483
|
z.current = u;
|
|
7471
7484
|
}, [u]);
|
|
7472
|
-
const
|
|
7473
|
-
let
|
|
7474
|
-
|
|
7485
|
+
const N = Ee(), te = s || N.service;
|
|
7486
|
+
let q;
|
|
7487
|
+
te === "browser" ? q = {
|
|
7475
7488
|
service: "browser",
|
|
7476
7489
|
endpoint: "",
|
|
7477
7490
|
apiKey: null,
|
|
7478
7491
|
defaultVoice: "Google US English"
|
|
7479
|
-
} :
|
|
7492
|
+
} : te === "elevenlabs" ? q = {
|
|
7480
7493
|
service: "elevenlabs",
|
|
7481
7494
|
endpoint: "https://api.elevenlabs.io/v1/text-to-speech",
|
|
7482
|
-
apiKey: l ||
|
|
7483
|
-
defaultVoice: o ||
|
|
7484
|
-
voices:
|
|
7485
|
-
} :
|
|
7495
|
+
apiKey: l || N.apiKey,
|
|
7496
|
+
defaultVoice: o || N.defaultVoice || Ie.defaultVoice,
|
|
7497
|
+
voices: N.voices || Ie.voices
|
|
7498
|
+
} : te === "deepgram" ? q = {
|
|
7486
7499
|
service: "deepgram",
|
|
7487
7500
|
endpoint: "https://api.deepgram.com/v1/speak",
|
|
7488
|
-
apiKey: l ||
|
|
7489
|
-
defaultVoice: o ||
|
|
7490
|
-
voices:
|
|
7491
|
-
} :
|
|
7492
|
-
...
|
|
7493
|
-
apiKey: l !== null ? l :
|
|
7501
|
+
apiKey: l || N.apiKey,
|
|
7502
|
+
defaultVoice: o || N.defaultVoice || Te.defaultVoice,
|
|
7503
|
+
voices: N.voices || Te.voices
|
|
7504
|
+
} : q = {
|
|
7505
|
+
...N,
|
|
7506
|
+
apiKey: l !== null ? l : N.apiKey
|
|
7494
7507
|
};
|
|
7495
|
-
const
|
|
7508
|
+
const _ = {
|
|
7496
7509
|
url: t,
|
|
7497
7510
|
body: e,
|
|
7498
7511
|
avatarMood: n,
|
|
7499
|
-
ttsLang:
|
|
7500
|
-
ttsVoice: o ||
|
|
7512
|
+
ttsLang: te === "browser" ? "en-US" : i,
|
|
7513
|
+
ttsVoice: o || q.defaultVoice,
|
|
7501
7514
|
lipsyncLang: "en",
|
|
7502
7515
|
showFullAvatar: u,
|
|
7503
7516
|
bodyMovement: h,
|
|
7504
7517
|
movementIntensity: r
|
|
7505
7518
|
}, Ae = {
|
|
7506
|
-
ttsEndpoint:
|
|
7507
|
-
ttsApikey:
|
|
7508
|
-
ttsService:
|
|
7519
|
+
ttsEndpoint: q.endpoint,
|
|
7520
|
+
ttsApikey: q.apiKey,
|
|
7521
|
+
ttsService: te,
|
|
7509
7522
|
lipsyncModules: ["en"],
|
|
7510
7523
|
cameraView: a
|
|
7511
7524
|
}, Se = O(async () => {
|
|
7512
7525
|
if (!(!L.current || I.current))
|
|
7513
7526
|
try {
|
|
7514
7527
|
le(!0), de(null), I.current = new Be(L.current, Ae), console.log("Avatar config being passed:", {
|
|
7515
|
-
url:
|
|
7516
|
-
body:
|
|
7517
|
-
avatarMood:
|
|
7518
|
-
}), await I.current.showAvatar(
|
|
7519
|
-
if (
|
|
7520
|
-
const
|
|
7521
|
-
c(
|
|
7528
|
+
url: _.url,
|
|
7529
|
+
body: _.body,
|
|
7530
|
+
avatarMood: _.avatarMood
|
|
7531
|
+
}), await I.current.showAvatar(_, (H) => {
|
|
7532
|
+
if (H.lengthComputable) {
|
|
7533
|
+
const G = Math.min(100, Math.round(H.loaded / H.total * 100));
|
|
7534
|
+
c(G);
|
|
7522
7535
|
}
|
|
7523
7536
|
}), I.current?.avatar && console.log("Avatar body after initialization:", I.current.avatar.body), le(!1), be(!0), d(I.current);
|
|
7524
7537
|
const A = () => {
|
|
@@ -7543,29 +7556,40 @@ const yt = Me(({
|
|
|
7543
7556
|
console.warn("Failed to resume audio context:", A);
|
|
7544
7557
|
}
|
|
7545
7558
|
}, []), ke = O((A) => {
|
|
7546
|
-
if (!v
|
|
7547
|
-
return null;
|
|
7548
|
-
let
|
|
7559
|
+
if (!v)
|
|
7560
|
+
return console.warn("No animations loaded"), null;
|
|
7561
|
+
let H = null;
|
|
7549
7562
|
if (v._genderSpecific) {
|
|
7550
|
-
const
|
|
7551
|
-
ie && ie[A] ? (
|
|
7563
|
+
const J = (e?.toUpperCase() || "F") === "M" ? "male" : "female", ie = v._genderSpecific[J];
|
|
7564
|
+
ie && ie[A] ? (H = ie[A], console.log(`Using ${J} animations for "${A}":`, H)) : v._genderSpecific.shared && v._genderSpecific.shared[A] && (H = v._genderSpecific.shared[A], console.log(`Using shared animations for "${A}":`, H));
|
|
7552
7565
|
}
|
|
7553
|
-
if (
|
|
7554
|
-
|
|
7555
|
-
|
|
7566
|
+
if (!H && v[A] && (H = v[A], console.log(`Using root-level animations for "${A}":`, H)), !H) {
|
|
7567
|
+
if (console.warn(`Animation group "${A}" not found. Available groups:`, Object.keys(v).filter((G) => G !== "_genderSpecific")), v._genderSpecific) {
|
|
7568
|
+
const J = (e?.toUpperCase() || "F") === "M" ? "male" : "female";
|
|
7569
|
+
console.warn(`Gender-specific groups (${J}):`, Object.keys(v._genderSpecific[J] || {}));
|
|
7570
|
+
}
|
|
7571
|
+
return null;
|
|
7556
7572
|
}
|
|
7557
|
-
|
|
7558
|
-
|
|
7559
|
-
|
|
7560
|
-
|
|
7573
|
+
if (Array.isArray(H) && H.length > 0) {
|
|
7574
|
+
const G = Math.floor(Math.random() * H.length);
|
|
7575
|
+
return H[G];
|
|
7576
|
+
}
|
|
7577
|
+
return typeof H == "string" ? H : (console.warn(`Animation group "${A}" is not a valid format (expected array or string):`, H), null);
|
|
7578
|
+
}, [v, e]), w = O((A, H = !1) => {
|
|
7579
|
+
if (!I.current)
|
|
7580
|
+
return console.warn("TalkingHead not initialized yet"), null;
|
|
7581
|
+
const G = ke(A);
|
|
7582
|
+
if (G)
|
|
7561
7583
|
try {
|
|
7562
|
-
return I.current.playAnimation(
|
|
7563
|
-
} catch (
|
|
7564
|
-
return console.
|
|
7584
|
+
return I.current.playAnimation(G, null, 10, 0, 0.01, H), console.log(`✅ Playing random animation from "${A}" group:`, G), G;
|
|
7585
|
+
} catch (J) {
|
|
7586
|
+
return console.error(`❌ Failed to play random animation from "${A}" group:`, J), null;
|
|
7565
7587
|
}
|
|
7588
|
+
else
|
|
7589
|
+
console.warn(`⚠️ No animation found for group "${A}"`);
|
|
7566
7590
|
return null;
|
|
7567
|
-
}, [ke]), U = O(async (A,
|
|
7568
|
-
if (!I.current ||
|
|
7591
|
+
}, [ke]), U = O(async (A, H = {}) => {
|
|
7592
|
+
if (!I.current || !ee) {
|
|
7569
7593
|
console.warn("Avatar not ready for speaking");
|
|
7570
7594
|
return;
|
|
7571
7595
|
}
|
|
@@ -7574,14 +7598,14 @@ const yt = Me(({
|
|
|
7574
7598
|
return;
|
|
7575
7599
|
}
|
|
7576
7600
|
await Le();
|
|
7577
|
-
const
|
|
7578
|
-
|
|
7579
|
-
const
|
|
7580
|
-
|
|
7601
|
+
const G = H.animationGroup || p;
|
|
7602
|
+
G && !H.skipAnimation ? (console.log(`🎬 Attempting to play animation from group: "${G}"`), console.log(`📊 Current avatarBody: "${e}", loadedAnimations:`, v), w(G)) : console.log(`⏭️ Skipping animation (group: ${G}, skipAnimation: ${H.skipAnimation})`), j.current = { remainingText: null, originalText: null, options: null }, X.current = [], Y.current = { text: A, options: H }, S.current && (clearInterval(S.current), S.current = null), b(!1), E.current = !1;
|
|
7603
|
+
const J = A.split(/[.!?]+/).filter((se) => se.trim().length > 0);
|
|
7604
|
+
X.current = J;
|
|
7581
7605
|
const ie = {
|
|
7582
|
-
lipsyncLang:
|
|
7606
|
+
lipsyncLang: H.lipsyncLang || "en",
|
|
7583
7607
|
onSpeechEnd: () => {
|
|
7584
|
-
S.current && (clearInterval(S.current), S.current = null),
|
|
7608
|
+
S.current && (clearInterval(S.current), S.current = null), H.onSpeechEnd && H.onSpeechEnd(), x();
|
|
7585
7609
|
}
|
|
7586
7610
|
};
|
|
7587
7611
|
try {
|
|
@@ -7589,9 +7613,9 @@ const yt = Me(({
|
|
|
7589
7613
|
} catch (se) {
|
|
7590
7614
|
console.error("Error speaking text:", se), de(se.message || "Failed to speak text");
|
|
7591
7615
|
}
|
|
7592
|
-
}, [
|
|
7616
|
+
}, [ee, x, Le, p, w]);
|
|
7593
7617
|
ce(() => {
|
|
7594
|
-
if (
|
|
7618
|
+
if (!ee || !B || !I.current)
|
|
7595
7619
|
return;
|
|
7596
7620
|
P.current && clearInterval(P.current);
|
|
7597
7621
|
const A = () => {
|
|
@@ -7602,18 +7626,18 @@ const yt = Me(({
|
|
|
7602
7626
|
}, 12e3 + Math.random() * 3e3), () => {
|
|
7603
7627
|
P.current && (clearInterval(P.current), P.current = null);
|
|
7604
7628
|
};
|
|
7605
|
-
}, [
|
|
7606
|
-
|
|
7607
|
-
}, [
|
|
7608
|
-
const
|
|
7629
|
+
}, [ee, B, w]), ce(() => {
|
|
7630
|
+
ee && V && T && I.current && U(V);
|
|
7631
|
+
}, [ee, V, T, U]);
|
|
7632
|
+
const K = O(() => {
|
|
7609
7633
|
if (I.current)
|
|
7610
7634
|
try {
|
|
7611
|
-
const A = I.current.isSpeaking || !1,
|
|
7612
|
-
if (A ||
|
|
7635
|
+
const A = I.current.isSpeaking || !1, H = I.current.audioPlaylist || [], G = I.current.speechQueue || [];
|
|
7636
|
+
if (A || H.length > 0 || G.length > 0) {
|
|
7613
7637
|
S.current && (clearInterval(S.current), S.current = null);
|
|
7614
|
-
let
|
|
7615
|
-
|
|
7616
|
-
remainingText:
|
|
7638
|
+
let J = "";
|
|
7639
|
+
G.length > 0 && (J = G.map((ie) => ie.text && Array.isArray(ie.text) ? ie.text.map((se) => se.word).join(" ") : ie.text || "").join(" ")), j.current = {
|
|
7640
|
+
remainingText: J || null,
|
|
7617
7641
|
originalText: Y.current?.text || null,
|
|
7618
7642
|
options: Y.current?.options || null
|
|
7619
7643
|
}, I.current.speechQueue.length = 0, I.current.pauseSpeaking(), b(!0), E.current = !0;
|
|
@@ -7621,40 +7645,40 @@ const yt = Me(({
|
|
|
7621
7645
|
} catch (A) {
|
|
7622
7646
|
console.warn("Error pausing speech:", A);
|
|
7623
7647
|
}
|
|
7624
|
-
}, []),
|
|
7625
|
-
if (!(!I.current || !
|
|
7648
|
+
}, []), ne = O(async () => {
|
|
7649
|
+
if (!(!I.current || !Q))
|
|
7626
7650
|
try {
|
|
7627
7651
|
await Le(), b(!1), E.current = !1;
|
|
7628
|
-
const A =
|
|
7629
|
-
|
|
7652
|
+
const A = j.current?.remainingText, H = j.current?.originalText || Y.current?.text, G = j.current?.options || Y.current?.options || {}, J = A || H;
|
|
7653
|
+
J && U(J, G);
|
|
7630
7654
|
} catch (A) {
|
|
7631
7655
|
console.warn("Error resuming speech:", A), b(!1), E.current = !1;
|
|
7632
7656
|
}
|
|
7633
|
-
}, [
|
|
7657
|
+
}, [Q, U, Le]), me = O(() => {
|
|
7634
7658
|
I.current && (I.current.stopSpeaking(), S.current && (clearInterval(S.current), S.current = null), b(!1), E.current = !1);
|
|
7635
7659
|
}, []);
|
|
7636
7660
|
return Fe(R, () => ({
|
|
7637
7661
|
speakText: U,
|
|
7638
|
-
pauseSpeaking:
|
|
7639
|
-
resumeSpeaking:
|
|
7662
|
+
pauseSpeaking: K,
|
|
7663
|
+
resumeSpeaking: ne,
|
|
7640
7664
|
stopSpeaking: me,
|
|
7641
7665
|
resumeAudioContext: Le,
|
|
7642
|
-
isPaused: () =>
|
|
7666
|
+
isPaused: () => Q,
|
|
7643
7667
|
setMood: (A) => I.current?.setMood(A),
|
|
7644
7668
|
setBodyMovement: (A) => {
|
|
7645
7669
|
I.current && I.current.setBodyMovement(A);
|
|
7646
7670
|
},
|
|
7647
|
-
playAnimation: (A,
|
|
7648
|
-
I.current && I.current.playAnimation && I.current.playAnimation(A, null, 10, 0, 0.01,
|
|
7671
|
+
playAnimation: (A, H = !1) => {
|
|
7672
|
+
I.current && I.current.playAnimation && I.current.playAnimation(A, null, 10, 0, 0.01, H);
|
|
7649
7673
|
},
|
|
7650
|
-
playRandomAnimation: (A,
|
|
7674
|
+
playRandomAnimation: (A, H = !1) => w(A, H),
|
|
7651
7675
|
getRandomAnimation: (A) => ke(A),
|
|
7652
7676
|
playReaction: (A) => I.current?.playReaction(A),
|
|
7653
7677
|
playCelebration: () => I.current?.playCelebration(),
|
|
7654
7678
|
setShowFullAvatar: (A) => {
|
|
7655
7679
|
I.current && (z.current = A, I.current.setShowFullAvatar(A));
|
|
7656
7680
|
},
|
|
7657
|
-
isReady:
|
|
7681
|
+
isReady: ee,
|
|
7658
7682
|
talkingHead: I.current
|
|
7659
7683
|
})), /* @__PURE__ */ Pe("div", { className: `simple-talking-avatar-container ${f}`, style: k, children: [
|
|
7660
7684
|
/* @__PURE__ */ ye(
|
|
@@ -7725,12 +7749,12 @@ const ft = Me(({
|
|
|
7725
7749
|
onQuestionAnswer: s,
|
|
7726
7750
|
onCurriculumComplete: o,
|
|
7727
7751
|
onCustomAction: l
|
|
7728
|
-
}), c = W(null), g = W(null), x = W(null), f = W(null), k = W(null),
|
|
7752
|
+
}), c = W(null), g = W(null), x = W(null), f = W(null), k = W(null), D = W(null), p = W(null), B = W(V?.curriculum || {
|
|
7729
7753
|
title: "Default Curriculum",
|
|
7730
7754
|
description: "No curriculum data provided",
|
|
7731
7755
|
language: "en",
|
|
7732
7756
|
modules: []
|
|
7733
|
-
}),
|
|
7757
|
+
}), T = W({
|
|
7734
7758
|
avatarUrl: t.avatarUrl || "/avatars/brunette.glb",
|
|
7735
7759
|
avatarBody: t.avatarBody || "F",
|
|
7736
7760
|
mood: t.mood || "happy",
|
|
@@ -7758,7 +7782,7 @@ const ft = Me(({
|
|
|
7758
7782
|
description: "No curriculum data provided",
|
|
7759
7783
|
language: "en",
|
|
7760
7784
|
modules: []
|
|
7761
|
-
},
|
|
7785
|
+
}, T.current = {
|
|
7762
7786
|
avatarUrl: t.avatarUrl || "/avatars/brunette.glb",
|
|
7763
7787
|
avatarBody: t.avatarBody || "F",
|
|
7764
7788
|
mood: t.mood || "happy",
|
|
@@ -7797,9 +7821,9 @@ const ft = Me(({
|
|
|
7797
7821
|
} catch {
|
|
7798
7822
|
u.current.playCelebration();
|
|
7799
7823
|
}
|
|
7800
|
-
const F = B.current || { modules: [] }, P = F.modules[a.current.currentModuleIndex],
|
|
7824
|
+
const F = B.current || { modules: [] }, P = F.modules[a.current.currentModuleIndex], N = a.current.currentLessonIndex < (P?.lessons?.length || 0) - 1, te = a.current.currentModuleIndex < (F.modules?.length || 0) - 1, q = N || te, _ = T.current || { lipsyncLang: "en" };
|
|
7801
7825
|
u.current.speakText(v, {
|
|
7802
|
-
lipsyncLang:
|
|
7826
|
+
lipsyncLang: _.lipsyncLang,
|
|
7803
7827
|
onSpeechEnd: () => {
|
|
7804
7828
|
d.current.onCustomAction({
|
|
7805
7829
|
type: "lessonCompleteFeedbackDone",
|
|
@@ -7808,7 +7832,7 @@ const ft = Me(({
|
|
|
7808
7832
|
score: a.current.score,
|
|
7809
7833
|
totalQuestions: a.current.totalQuestions,
|
|
7810
7834
|
percentage: b,
|
|
7811
|
-
hasNextLesson:
|
|
7835
|
+
hasNextLesson: q
|
|
7812
7836
|
});
|
|
7813
7837
|
}
|
|
7814
7838
|
});
|
|
@@ -7826,7 +7850,7 @@ const ft = Me(({
|
|
|
7826
7850
|
} catch {
|
|
7827
7851
|
u.current.playCelebration();
|
|
7828
7852
|
}
|
|
7829
|
-
const v =
|
|
7853
|
+
const v = T.current || { lipsyncLang: "en" };
|
|
7830
7854
|
u.current.speakText("Amazing! You've completed the entire curriculum! You're now ready to move on to more advanced topics. Well done!", { lipsyncLang: v.lipsyncLang });
|
|
7831
7855
|
}
|
|
7832
7856
|
}, [e.curriculumComplete]), S = O(() => {
|
|
@@ -7847,16 +7871,16 @@ const ft = Me(({
|
|
|
7847
7871
|
if (u.current.setMood("happy"), e.questionStart)
|
|
7848
7872
|
try {
|
|
7849
7873
|
u.current.playAnimation(e.questionStart, !0);
|
|
7850
|
-
} catch (
|
|
7851
|
-
console.warn("Failed to play questionStart animation:",
|
|
7874
|
+
} catch (N) {
|
|
7875
|
+
console.warn("Failed to play questionStart animation:", N);
|
|
7852
7876
|
}
|
|
7853
|
-
const P =
|
|
7877
|
+
const P = T.current || { lipsyncLang: "en" };
|
|
7854
7878
|
v.type === "code_test" ? u.current.speakText(`Let's test your coding skills! Here's your first challenge: ${v.question}`, { lipsyncLang: P.lipsyncLang }) : v.type === "multiple_choice" ? u.current.speakText(`Now let me ask you some questions. Here's the first one: ${v.question}`, { lipsyncLang: P.lipsyncLang }) : v.type === "true_false" ? u.current.speakText(`Let's start with some true or false questions. First question: ${v.question}`, { lipsyncLang: P.lipsyncLang }) : u.current.speakText(`Now let me ask you some questions. Here's the first one: ${v.question}`, { lipsyncLang: P.lipsyncLang });
|
|
7855
7879
|
};
|
|
7856
7880
|
if (u.current && u.current.isReady && v)
|
|
7857
7881
|
F();
|
|
7858
7882
|
else if (u.current && u.current.isReady) {
|
|
7859
|
-
const P =
|
|
7883
|
+
const P = T.current || { lipsyncLang: "en" };
|
|
7860
7884
|
u.current.speakText("Now let me ask you some questions to test your understanding.", { lipsyncLang: P.lipsyncLang });
|
|
7861
7885
|
} else {
|
|
7862
7886
|
const P = setInterval(() => {
|
|
@@ -7885,28 +7909,28 @@ const ft = Me(({
|
|
|
7885
7909
|
if (u.current.setMood("happy"), u.current.setBodyMovement("idle"), e.nextQuestion)
|
|
7886
7910
|
try {
|
|
7887
7911
|
u.current.playAnimation(e.nextQuestion, !0);
|
|
7888
|
-
} catch (
|
|
7889
|
-
console.warn("Failed to play nextQuestion animation:",
|
|
7912
|
+
} catch (_) {
|
|
7913
|
+
console.warn("Failed to play nextQuestion animation:", _);
|
|
7890
7914
|
}
|
|
7891
|
-
const P =
|
|
7915
|
+
const P = T.current || { lipsyncLang: "en" }, te = R()?.questions?.length || 0, q = a.current.currentQuestionIndex >= te - 1;
|
|
7892
7916
|
if (v.type === "code_test") {
|
|
7893
|
-
const
|
|
7894
|
-
u.current.speakText(
|
|
7917
|
+
const _ = q ? `Great! Here's your final coding challenge: ${v.question}` : `Great! Now let's move on to your next coding challenge: ${v.question}`;
|
|
7918
|
+
u.current.speakText(_, {
|
|
7895
7919
|
lipsyncLang: P.lipsyncLang
|
|
7896
7920
|
});
|
|
7897
7921
|
} else if (v.type === "multiple_choice") {
|
|
7898
|
-
const
|
|
7899
|
-
u.current.speakText(
|
|
7922
|
+
const _ = q ? `Alright! Here's your final question: ${v.question}` : `Alright! Here's your next question: ${v.question}`;
|
|
7923
|
+
u.current.speakText(_, {
|
|
7900
7924
|
lipsyncLang: P.lipsyncLang
|
|
7901
7925
|
});
|
|
7902
7926
|
} else if (v.type === "true_false") {
|
|
7903
|
-
const
|
|
7904
|
-
u.current.speakText(
|
|
7927
|
+
const _ = q ? `Now let's try this final one: ${v.question}` : `Now let's try this one: ${v.question}`;
|
|
7928
|
+
u.current.speakText(_, {
|
|
7905
7929
|
lipsyncLang: P.lipsyncLang
|
|
7906
7930
|
});
|
|
7907
7931
|
} else {
|
|
7908
|
-
const
|
|
7909
|
-
u.current.speakText(
|
|
7932
|
+
const _ = q ? `Here's your final question: ${v.question}` : `Here's the next question: ${v.question}`;
|
|
7933
|
+
u.current.speakText(_, {
|
|
7910
7934
|
lipsyncLang: P.lipsyncLang
|
|
7911
7935
|
});
|
|
7912
7936
|
}
|
|
@@ -7929,16 +7953,16 @@ const ft = Me(({
|
|
|
7929
7953
|
totalQuestions: a.current.totalQuestions,
|
|
7930
7954
|
score: a.current.score
|
|
7931
7955
|
});
|
|
7932
|
-
}, [e.nextQuestion, R, L]),
|
|
7956
|
+
}, [e.nextQuestion, R, L]), j = O(() => {
|
|
7933
7957
|
const b = B.current || { modules: [] }, v = b.modules[a.current.currentModuleIndex];
|
|
7934
7958
|
if (a.current.currentLessonIndex < (v?.lessons?.length || 0) - 1) {
|
|
7935
7959
|
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;
|
|
7936
|
-
const P = b.modules[a.current.currentModuleIndex],
|
|
7960
|
+
const P = b.modules[a.current.currentModuleIndex], N = a.current.currentLessonIndex < (P?.lessons?.length || 0) - 1, te = a.current.currentModuleIndex < (b.modules?.length || 0) - 1, q = N || te;
|
|
7937
7961
|
d.current.onCustomAction({
|
|
7938
7962
|
type: "lessonStart",
|
|
7939
7963
|
moduleIndex: a.current.currentModuleIndex,
|
|
7940
7964
|
lessonIndex: a.current.currentLessonIndex,
|
|
7941
|
-
hasNextLesson:
|
|
7965
|
+
hasNextLesson: q
|
|
7942
7966
|
}), d.current.onLessonStart({
|
|
7943
7967
|
moduleIndex: a.current.currentModuleIndex,
|
|
7944
7968
|
lessonIndex: a.current.currentLessonIndex,
|
|
@@ -7946,12 +7970,12 @@ const ft = Me(({
|
|
|
7946
7970
|
}), u.current && (u.current.setMood("happy"), u.current.setBodyMovement("idle"));
|
|
7947
7971
|
} else if (a.current.currentModuleIndex < (b.modules?.length || 0) - 1) {
|
|
7948
7972
|
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;
|
|
7949
|
-
const
|
|
7973
|
+
const N = b.modules[a.current.currentModuleIndex], te = a.current.currentLessonIndex < (N?.lessons?.length || 0) - 1, q = a.current.currentModuleIndex < (b.modules?.length || 0) - 1, _ = te || q;
|
|
7950
7974
|
d.current.onCustomAction({
|
|
7951
7975
|
type: "lessonStart",
|
|
7952
7976
|
moduleIndex: a.current.currentModuleIndex,
|
|
7953
7977
|
lessonIndex: a.current.currentLessonIndex,
|
|
7954
|
-
hasNextLesson:
|
|
7978
|
+
hasNextLesson: _
|
|
7955
7979
|
}), d.current.onLessonStart({
|
|
7956
7980
|
moduleIndex: a.current.currentModuleIndex,
|
|
7957
7981
|
lessonIndex: a.current.currentLessonIndex,
|
|
@@ -7959,12 +7983,12 @@ const ft = Me(({
|
|
|
7959
7983
|
}), u.current && (u.current.setMood("happy"), u.current.setBodyMovement("idle"));
|
|
7960
7984
|
} else
|
|
7961
7985
|
k.current && k.current();
|
|
7962
|
-
}, []),
|
|
7986
|
+
}, []), X = O(() => {
|
|
7963
7987
|
const b = R();
|
|
7964
7988
|
let v = null;
|
|
7965
7989
|
if (b?.avatar_script && b?.body) {
|
|
7966
|
-
const F = b.avatar_script.trim(), P = b.body.trim(),
|
|
7967
|
-
v = `${F}${
|
|
7990
|
+
const F = b.avatar_script.trim(), P = b.body.trim(), N = F.match(/[.!?]$/) ? " " : ". ";
|
|
7991
|
+
v = `${F}${N}${P}`;
|
|
7968
7992
|
} else
|
|
7969
7993
|
v = b?.avatar_script || b?.body || null;
|
|
7970
7994
|
if (u.current && u.current.isReady && v) {
|
|
@@ -7973,11 +7997,11 @@ const ft = Me(({
|
|
|
7973
7997
|
if (e.teaching)
|
|
7974
7998
|
try {
|
|
7975
7999
|
u.current.playAnimation(e.teaching, !0), F = !0;
|
|
7976
|
-
} catch (
|
|
7977
|
-
console.warn("Failed to play teaching animation:",
|
|
8000
|
+
} catch (N) {
|
|
8001
|
+
console.warn("Failed to play teaching animation:", N);
|
|
7978
8002
|
}
|
|
7979
8003
|
F || u.current.setBodyMovement("gesturing");
|
|
7980
|
-
const P =
|
|
8004
|
+
const P = T.current || { lipsyncLang: "en" };
|
|
7981
8005
|
d.current.onLessonStart({
|
|
7982
8006
|
moduleIndex: a.current.currentModuleIndex,
|
|
7983
8007
|
lessonIndex: a.current.currentLessonIndex,
|
|
@@ -8024,13 +8048,13 @@ const ft = Me(({
|
|
|
8024
8048
|
u.current.setBodyMovement("happy");
|
|
8025
8049
|
}
|
|
8026
8050
|
u.current.setBodyMovement("gesturing");
|
|
8027
|
-
const
|
|
8028
|
-
a.current.currentQuestionIndex >=
|
|
8029
|
-
const
|
|
8030
|
-
console.log("[CurriculumLearning] Answer feedback - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:",
|
|
8031
|
-
const
|
|
8032
|
-
u.current.speakText(
|
|
8033
|
-
lipsyncLang:
|
|
8051
|
+
const N = R()?.questions?.length || 0;
|
|
8052
|
+
a.current.currentQuestionIndex >= N - 1;
|
|
8053
|
+
const te = a.current.currentQuestionIndex < N - 1;
|
|
8054
|
+
console.log("[CurriculumLearning] Answer feedback - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:", N, "hasNextQuestion:", te);
|
|
8055
|
+
const q = v.type === "code_test" ? `Great job! Your code passed all the tests! ${v.explanation || ""}` : `Excellent! That's correct! ${v.explanation || ""}`, _ = T.current || { lipsyncLang: "en" };
|
|
8056
|
+
u.current.speakText(q, {
|
|
8057
|
+
lipsyncLang: _.lipsyncLang,
|
|
8034
8058
|
onSpeechEnd: () => {
|
|
8035
8059
|
d.current.onCustomAction({
|
|
8036
8060
|
type: "answerFeedbackComplete",
|
|
@@ -8038,7 +8062,7 @@ const ft = Me(({
|
|
|
8038
8062
|
lessonIndex: a.current.currentLessonIndex,
|
|
8039
8063
|
questionIndex: a.current.currentQuestionIndex,
|
|
8040
8064
|
isCorrect: !0,
|
|
8041
|
-
hasNextQuestion:
|
|
8065
|
+
hasNextQuestion: te,
|
|
8042
8066
|
score: a.current.score,
|
|
8043
8067
|
totalQuestions: a.current.totalQuestions
|
|
8044
8068
|
});
|
|
@@ -8052,10 +8076,10 @@ const ft = Me(({
|
|
|
8052
8076
|
u.current.setBodyMovement("idle");
|
|
8053
8077
|
}
|
|
8054
8078
|
u.current.setBodyMovement("gesturing");
|
|
8055
|
-
const
|
|
8056
|
-
console.log("[CurriculumLearning] Answer feedback (incorrect) - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:",
|
|
8057
|
-
const
|
|
8058
|
-
u.current.speakText(
|
|
8079
|
+
const N = R()?.questions?.length || 0, te = a.current.currentQuestionIndex >= N - 1, q = a.current.currentQuestionIndex < N - 1;
|
|
8080
|
+
console.log("[CurriculumLearning] Answer feedback (incorrect) - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:", N, "hasNextQuestion:", q);
|
|
8081
|
+
const _ = v.type === "code_test" ? `Your code didn't pass all the tests. ${v.explanation || "Try again!"}` : `Not quite right, but don't worry! ${v.explanation || ""}${te ? "" : " Let's move on to the next question."}`, Ae = T.current || { lipsyncLang: "en" };
|
|
8082
|
+
u.current.speakText(_, {
|
|
8059
8083
|
lipsyncLang: Ae.lipsyncLang,
|
|
8060
8084
|
onSpeechEnd: () => {
|
|
8061
8085
|
d.current.onCustomAction({
|
|
@@ -8064,7 +8088,7 @@ const ft = Me(({
|
|
|
8064
8088
|
lessonIndex: a.current.currentLessonIndex,
|
|
8065
8089
|
questionIndex: a.current.currentQuestionIndex,
|
|
8066
8090
|
isCorrect: !1,
|
|
8067
|
-
hasNextQuestion:
|
|
8091
|
+
hasNextQuestion: q,
|
|
8068
8092
|
score: a.current.score,
|
|
8069
8093
|
totalQuestions: a.current.totalQuestions
|
|
8070
8094
|
});
|
|
@@ -8072,14 +8096,14 @@ const ft = Me(({
|
|
|
8072
8096
|
});
|
|
8073
8097
|
}
|
|
8074
8098
|
else {
|
|
8075
|
-
const
|
|
8099
|
+
const N = R()?.questions?.length || 0;
|
|
8076
8100
|
d.current.onCustomAction({
|
|
8077
8101
|
type: "answerFeedbackComplete",
|
|
8078
8102
|
moduleIndex: a.current.currentModuleIndex,
|
|
8079
8103
|
lessonIndex: a.current.currentLessonIndex,
|
|
8080
8104
|
questionIndex: a.current.currentQuestionIndex,
|
|
8081
8105
|
isCorrect: F,
|
|
8082
|
-
hasNextQuestion: a.current.currentQuestionIndex <
|
|
8106
|
+
hasNextQuestion: a.current.currentQuestionIndex < N - 1,
|
|
8083
8107
|
score: a.current.score,
|
|
8084
8108
|
totalQuestions: a.current.totalQuestions,
|
|
8085
8109
|
avatarNotReady: !0
|
|
@@ -8129,7 +8153,7 @@ const ft = Me(({
|
|
|
8129
8153
|
const v = () => {
|
|
8130
8154
|
if (!u.current || !b) return;
|
|
8131
8155
|
u.current.setMood("happy"), u.current.setBodyMovement("idle");
|
|
8132
|
-
const F =
|
|
8156
|
+
const F = T.current || { lipsyncLang: "en" };
|
|
8133
8157
|
b.type === "code_test" ? u.current.speakText(`Let's go back to this coding challenge: ${b.question}`, {
|
|
8134
8158
|
lipsyncLang: F.lipsyncLang
|
|
8135
8159
|
}) : u.current.speakText(`Going back to: ${b.question}`, {
|
|
@@ -8171,7 +8195,7 @@ const ft = Me(({
|
|
|
8171
8195
|
lesson: R()
|
|
8172
8196
|
}), u.current && (u.current.setMood("happy"), u.current.setBodyMovement("idle"));
|
|
8173
8197
|
}
|
|
8174
|
-
}, [R]),
|
|
8198
|
+
}, [R]), ee = O(() => {
|
|
8175
8199
|
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;
|
|
8176
8200
|
}, []), be = O((b) => {
|
|
8177
8201
|
console.log("Avatar is ready!", b);
|
|
@@ -8181,20 +8205,20 @@ const ft = Me(({
|
|
|
8181
8205
|
}, 10);
|
|
8182
8206
|
}, [h, R]);
|
|
8183
8207
|
Xe(() => {
|
|
8184
|
-
c.current =
|
|
8208
|
+
c.current = X, g.current = j, x.current = z, f.current = E, k.current = Y, D.current = S, p.current = oe;
|
|
8185
8209
|
}), Fe(r, () => ({
|
|
8186
8210
|
// Curriculum control methods
|
|
8187
|
-
startTeaching:
|
|
8211
|
+
startTeaching: X,
|
|
8188
8212
|
startQuestions: S,
|
|
8189
8213
|
handleAnswerSelect: oe,
|
|
8190
8214
|
handleCodeTestResult: le,
|
|
8191
8215
|
nextQuestion: E,
|
|
8192
8216
|
previousQuestion: ge,
|
|
8193
|
-
nextLesson:
|
|
8217
|
+
nextLesson: j,
|
|
8194
8218
|
previousLesson: de,
|
|
8195
8219
|
completeLesson: z,
|
|
8196
8220
|
completeCurriculum: Y,
|
|
8197
|
-
resetCurriculum:
|
|
8221
|
+
resetCurriculum: ee,
|
|
8198
8222
|
getState: () => ({ ...a.current }),
|
|
8199
8223
|
getCurrentQuestion: () => L(),
|
|
8200
8224
|
getCurrentLesson: () => R(),
|
|
@@ -8203,7 +8227,7 @@ const ft = Me(({
|
|
|
8203
8227
|
// Convenience methods that delegate to avatar (always check current ref)
|
|
8204
8228
|
speakText: async (b, v = {}) => {
|
|
8205
8229
|
await u.current?.resumeAudioContext?.();
|
|
8206
|
-
const F =
|
|
8230
|
+
const F = T.current || { lipsyncLang: "en" };
|
|
8207
8231
|
u.current?.speakText(b, { ...v, lipsyncLang: v.lipsyncLang || F.lipsyncLang });
|
|
8208
8232
|
},
|
|
8209
8233
|
resumeAudioContext: async () => {
|
|
@@ -8248,8 +8272,8 @@ const ft = Me(({
|
|
|
8248
8272
|
handleResize: () => u.current?.handleResize(),
|
|
8249
8273
|
// Avatar readiness check (always returns current value)
|
|
8250
8274
|
isAvatarReady: () => u.current?.isReady || !1
|
|
8251
|
-
}), [
|
|
8252
|
-
const
|
|
8275
|
+
}), [X, S, oe, le, E, j, z, Y, ee, L, R]);
|
|
8276
|
+
const Q = T.current || {
|
|
8253
8277
|
avatarUrl: "/avatars/brunette.glb",
|
|
8254
8278
|
avatarBody: "F",
|
|
8255
8279
|
mood: "happy",
|
|
@@ -8266,18 +8290,18 @@ const ft = Me(({
|
|
|
8266
8290
|
Ve,
|
|
8267
8291
|
{
|
|
8268
8292
|
ref: u,
|
|
8269
|
-
avatarUrl:
|
|
8270
|
-
avatarBody:
|
|
8271
|
-
mood:
|
|
8272
|
-
ttsLang:
|
|
8273
|
-
ttsService:
|
|
8274
|
-
ttsVoice:
|
|
8275
|
-
ttsApiKey:
|
|
8276
|
-
bodyMovement:
|
|
8277
|
-
movementIntensity:
|
|
8278
|
-
showFullAvatar:
|
|
8293
|
+
avatarUrl: Q.avatarUrl,
|
|
8294
|
+
avatarBody: Q.avatarBody,
|
|
8295
|
+
mood: Q.mood,
|
|
8296
|
+
ttsLang: Q.ttsLang,
|
|
8297
|
+
ttsService: Q.ttsService,
|
|
8298
|
+
ttsVoice: Q.ttsVoice,
|
|
8299
|
+
ttsApiKey: Q.ttsApiKey,
|
|
8300
|
+
bodyMovement: Q.bodyMovement,
|
|
8301
|
+
movementIntensity: Q.movementIntensity,
|
|
8302
|
+
showFullAvatar: Q.showFullAvatar,
|
|
8279
8303
|
cameraView: "upper",
|
|
8280
|
-
animations:
|
|
8304
|
+
animations: Q.animations,
|
|
8281
8305
|
onReady: be,
|
|
8282
8306
|
onLoading: () => {
|
|
8283
8307
|
},
|