@sage-rsc/talking-head-react 1.5.1 → 1.5.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 +7 -2
- package/dist/index.js +1289 -1005
- package/package.json +1 -1
- package/src/components/AnimationSelector.jsx +419 -0
- package/src/index.js +1 -0
package/dist/index.js
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
import { jsxs as
|
|
2
|
-
import { forwardRef as
|
|
1
|
+
import { jsxs as fe, jsx as q } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef as Fe, useRef as X, useState as ae, useEffect as me, useCallback as U, useImperativeHandle as Ee, useLayoutEffect as je } from "react";
|
|
3
3
|
import * as y from "three";
|
|
4
|
-
import { OrbitControls as
|
|
5
|
-
import { GLTFLoader as
|
|
6
|
-
import { DRACOLoader as
|
|
4
|
+
import { OrbitControls as Ye } from "three/addons/controls/OrbitControls.js";
|
|
5
|
+
import { GLTFLoader as Qe } from "three/addons/loaders/GLTFLoader.js";
|
|
6
|
+
import { DRACOLoader as qe } from "three/addons/loaders/DRACOLoader.js";
|
|
7
7
|
import { FBXLoader as De } from "three/addons/loaders/FBXLoader.js";
|
|
8
|
-
import { RoomEnvironment as
|
|
9
|
-
import
|
|
10
|
-
let m,
|
|
11
|
-
const z = [0, 0, 0, 0],
|
|
8
|
+
import { RoomEnvironment as _e } from "three/addons/environments/RoomEnvironment.js";
|
|
9
|
+
import Ke from "three/addons/libs/stats.module.js";
|
|
10
|
+
let m, de, pe;
|
|
11
|
+
const z = [0, 0, 0, 0], E = new y.Vector3(), ze = new y.Vector3(), ce = new y.Vector3(), He = new y.Vector3();
|
|
12
12
|
new y.Plane();
|
|
13
13
|
new y.Ray();
|
|
14
14
|
new y.Euler();
|
|
15
|
-
const
|
|
15
|
+
const he = new y.Quaternion(), Ne = new y.Quaternion(), xe = new y.Matrix4(), be = new y.Matrix4();
|
|
16
16
|
new y.Vector3();
|
|
17
|
-
const
|
|
18
|
-
class
|
|
17
|
+
const Te = new y.Vector3(0, 0, 1), Je = new y.Vector3(1, 0, 0), $e = new y.Vector3(0, 1, 0), et = new y.Vector3(0, 0, 1);
|
|
18
|
+
class tt {
|
|
19
19
|
constructor(t = null) {
|
|
20
20
|
this.opt = Object.assign({
|
|
21
21
|
warmupMs: 2e3,
|
|
@@ -192,7 +192,7 @@ class et {
|
|
|
192
192
|
const l = this.armature.getObjectByName(s.bone);
|
|
193
193
|
if (!l) throw new Error("Bone '" + s.bone + "' not found in #" + o + " exclude.");
|
|
194
194
|
if (Number.isNaN(s.radius) && s.radius >= 0) throw new Error("Radius must be a non-negative number in #" + o + " exclude.");
|
|
195
|
-
const
|
|
195
|
+
const c = {
|
|
196
196
|
bone: l,
|
|
197
197
|
// Bone object
|
|
198
198
|
radius: s.radius,
|
|
@@ -203,9 +203,9 @@ class et {
|
|
|
203
203
|
};
|
|
204
204
|
if (s.deltaLocal) {
|
|
205
205
|
if (!Array.isArray(s.deltaLocal) || s.deltaLocal.length !== 3 || s.deltaLocal.some((r) => Number.isNaN(r))) throw new Error("deltaLocal must be an array of three numbers in #" + o + " exclude.");
|
|
206
|
-
|
|
206
|
+
c.deltaLocal = [...s.deltaLocal];
|
|
207
207
|
}
|
|
208
|
-
i.excludes.push(
|
|
208
|
+
i.excludes.push(c);
|
|
209
209
|
});
|
|
210
210
|
}
|
|
211
211
|
this.showHelpers();
|
|
@@ -282,8 +282,8 @@ class et {
|
|
|
282
282
|
m = this.dict[o.boneParent.name], m && (m.children || (m.children = []), m.children.push(o));
|
|
283
283
|
}), this.objectsUpdate = [];
|
|
284
284
|
const n = /* @__PURE__ */ new WeakSet(), i = (o) => o.parent?.isBone ? [o, ...i(o.parent)] : [o], s = (o) => {
|
|
285
|
-
i(o).forEach((
|
|
286
|
-
n.has(
|
|
285
|
+
i(o).forEach((c) => {
|
|
286
|
+
n.has(c) || (this.objectsUpdate.push(c), n.add(c));
|
|
287
287
|
});
|
|
288
288
|
};
|
|
289
289
|
this.data.forEach((o) => {
|
|
@@ -308,12 +308,12 @@ class et {
|
|
|
308
308
|
i(t?.isScene, "First parameter must be Scene."), this.scene = t, i(e?.isObject3D, "Second parameter must be the armature Object3D."), this.armature = e, i(Array.isArray(n), "Third parameter must be an array of bone configs."), this.config = n, this.config.forEach((s, o) => {
|
|
309
309
|
const l = "Config item #" + o + ": ";
|
|
310
310
|
i(s.bone, l + "Bone not specified.");
|
|
311
|
-
const
|
|
312
|
-
i(typeof
|
|
313
|
-
const r = this.armature.getObjectByName(
|
|
314
|
-
i(r, l + "Bone '" +
|
|
311
|
+
const c = s.bone;
|
|
312
|
+
i(typeof c == "string" && c.length > 0, l + "Bone name must be a non-empty string.");
|
|
313
|
+
const r = this.armature.getObjectByName(c);
|
|
314
|
+
i(r, l + "Bone '" + c + "' not found."), i(r.parent?.isBone, l + "Bone must have a parent bone."), i(this.data.every((a) => a.bone !== r), l + "Bone '" + c + "' already exists."), r.updateMatrixWorld(!0);
|
|
315
315
|
const u = {
|
|
316
|
-
name:
|
|
316
|
+
name: c,
|
|
317
317
|
// Bone name
|
|
318
318
|
bone: r,
|
|
319
319
|
// Bone object
|
|
@@ -321,7 +321,7 @@ class et {
|
|
|
321
321
|
/// Bone's parent object
|
|
322
322
|
vBasis: r.position.clone(),
|
|
323
323
|
// Original local position
|
|
324
|
-
vWorld: r.parent.getWorldPosition(
|
|
324
|
+
vWorld: r.parent.getWorldPosition(E).clone(),
|
|
325
325
|
// World position, parent
|
|
326
326
|
qBasis: r.parent.quaternion.clone(),
|
|
327
327
|
// Original quaternion, parent
|
|
@@ -338,9 +338,9 @@ class et {
|
|
|
338
338
|
ea: [0, 0, 0, 0]
|
|
339
339
|
// External acceleration [m/s^2]
|
|
340
340
|
};
|
|
341
|
-
u.boneParent.matrixWorld.decompose(
|
|
341
|
+
u.boneParent.matrixWorld.decompose(E, he, ce), E.copy(Te).applyQuaternion(he).setY(0).normalize(), he.premultiply(Ne.setFromUnitVectors(Te, E).invert()).normalize(), u.qWorldInverseYaw = he.clone().normalize(), this.data.push(u), this.dict[c] = u;
|
|
342
342
|
try {
|
|
343
|
-
this.setValue(
|
|
343
|
+
this.setValue(c, "type", s.type), this.setValue(c, "stiffness", s.stiffness), this.setValue(c, "damping", s.damping), this.setValue(c, "external", s.external), this.setValue(c, "limits", s.limits), this.setValue(c, "excludes", s.excludes), this.setValue(c, "deltaLocal", s.deltaLocal), this.setValue(c, "deltaWorld", s.deltaWorld), this.setValue(c, "pivot", s.pivot), this.setValue(c, "helper", s.helper);
|
|
344
344
|
} catch (a) {
|
|
345
345
|
i(!1, l + a);
|
|
346
346
|
}
|
|
@@ -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],
|
|
359
|
+
if (o = this.data[e], E.copy(o.vWorld), xe.copy(o.boneParent.matrixWorld), be.copy(xe).invert(), o.vWorld.setFromMatrixPosition(xe), E.applyMatrix4(be), E.length() > 0.5 && (console.info("Info: Unrealistic jump of " + E.length().toFixed(2) + " meters."), E.setLength(0.5)), E.applyQuaternion(o.bone.quaternion), z[0] = E.x, z[1] = E.y, z[2] = -E.z, z[3] = E.length() / 3, o.children)
|
|
360
360
|
for (n = 0, s = o.children.length; n < s; n++)
|
|
361
361
|
m = o.children[n], z[0] -= m.v[0] * t / 3, z[1] -= m.v[1] * t / 3, z[2] += m.v[2] * t / 3, z[3] -= m.v[3] * t / 3;
|
|
362
|
-
if (m = this.opt.sensitivityFactor, z[0] *= o.ext * m, z[1] *= o.ext * m, z[2] *= o.ext * m, z[3] *= o.ext * m, o.isX && (m = z[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 + z[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 = z[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 + z[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 = z[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 + z[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 = z[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 + z[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), z[0] = o.p[0], z[1] = o.p[1], z[2] = o.p[2], z[3] = o.p[3], m = this.opt.movementFactor, z[0] *= m, z[1] *= m, z[2] *= m, z[3] *= m, o.dl && (m = o.dl, z[0] += m[0], z[1] += m[1], z[2] += m[2]), o.dw && (m = o.dw,
|
|
362
|
+
if (m = this.opt.sensitivityFactor, z[0] *= o.ext * m, z[1] *= o.ext * m, z[2] *= o.ext * m, z[3] *= o.ext * m, o.isX && (m = z[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 + z[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 = z[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 + z[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 = z[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 + z[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 = z[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 + z[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), z[0] = o.p[0], z[1] = o.p[1], z[2] = o.p[2], z[3] = o.p[3], m = this.opt.movementFactor, z[0] *= m, z[1] *= m, z[2] *= m, z[3] *= m, o.dl && (m = o.dl, z[0] += m[0], z[1] += m[1], z[2] += m[2]), o.dw && (m = o.dw, E.set(
|
|
363
363
|
o.vBasis.x + z[0],
|
|
364
364
|
o.vBasis.y + z[1],
|
|
365
365
|
o.vBasis.z + z[2]
|
|
366
|
-
),
|
|
366
|
+
), E.applyMatrix4(xe), E.x += m[0], E.y += m[1], E.z += m[2], E.applyMatrix4(be), z[0] += E.x - o.vBasis.x, z[1] += E.y - o.vBasis.y, z[2] += E.z - o.vBasis.z), o.limits && this.opt.isLimits && (m = o.limits, m[0] && (m[0][0] !== null && z[0] < m[0][0] && (z[0] = m[0][0]), m[0][1] !== null && z[0] > m[0][1] && (z[0] = m[0][1])), m[1] && (m[1][0] !== null && z[1] < m[1][0] && (z[1] = m[1][0]), m[1][1] !== null && z[1] > m[1][1] && (z[1] = m[1][1])), m[2] && (m[2][0] !== null && z[2] < m[2][0] && (z[2] = m[2][0]), m[2][1] !== null && z[2] > m[2][1] && (z[2] = m[2][1])), m[3] && (m[3][0] !== null && z[3] < m[3][0] && (z[3] = m[3][0]), m[3][1] !== null && z[3] > m[3][1] && (z[3] = m[3][1]))), o.isPoint)
|
|
367
367
|
o.bone.position.set(
|
|
368
368
|
o.vBasis.x + z[0],
|
|
369
369
|
o.vBasis.y + z[1],
|
|
370
370
|
o.vBasis.z - z[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(
|
|
372
|
+
else if (o.boneParent.quaternion.copy(o.qBasis), o.pivot && this.opt.isPivots && (o.boneParent.updateWorldMatrix(!1, !1), o.boneParent.matrixWorld.decompose(E, he, ce), E.copy(Te).applyQuaternion(he).setY(0).normalize(), he.premultiply(Ne.setFromUnitVectors(Te, E).invert()).normalize(), o.boneParent.quaternion.multiply(he.invert()), o.boneParent.quaternion.multiply(o.qWorldInverseYaw)), o.isZ && (m = Math.atan(z[0] / o.l), he.setFromAxisAngle(et, -m), o.boneParent.quaternion.multiply(he)), o.isY && (m = o.l / 3, m = m * Math.tanh(z[1] / m), o.bone.position.setLength(o.l + m)), o.isX && (m = Math.atan(z[2] / o.l), he.setFromAxisAngle(Je, -m), o.boneParent.quaternion.multiply(he)), o.isT && (m = 1.5 * Math.tanh(z[3] * 1.5), he.setFromAxisAngle($e, -m), o.boneParent.quaternion.multiply(he)), 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],
|
|
374
|
+
m = o.excludes[n], ce.set(0, 0, 0), m.deltaLocal && (ce.x += m.deltaLocal[0], ce.y += m.deltaLocal[1], ce.z += m.deltaLocal[2]), ce.applyMatrix4(m.bone.matrixWorld), be.copy(o.boneParent.matrixWorld).invert(), ce.applyMatrix4(be), E.copy(o.bone.position), !(E.distanceToSquared(ce) >= m.radiusSq) && (pe = E.length(), de = ce.length(), !(de > m.radius + pe) && (de < Math.abs(m.radius - pe) || (de = (de * de + pe * pe - m.radiusSq) / (2 * de), ce.normalize(), He.copy(ce).multiplyScalar(de), de = Math.sqrt(pe * pe - de * de), E.subVectors(E, He).projectOnPlane(ce).normalize().multiplyScalar(de), ze.subVectors(o.vBasis, He).projectOnPlane(ce).normalize(), pe = ze.dot(E), pe < 0 && (pe = Math.sqrt(de * de - pe * pe), ze.multiplyScalar(pe), E.add(ze)), E.add(He).normalize(), ce.copy(o.bone.position).normalize(), he.setFromUnitVectors(ce, E), o.boneParent.quaternion.premultiply(he), o.boneParent.updateWorldMatrix(!1, !0))));
|
|
375
375
|
}
|
|
376
376
|
this.helpers.isActive && this.updateHelpers();
|
|
377
377
|
}
|
|
@@ -408,9 +408,9 @@ class et {
|
|
|
408
408
|
);
|
|
409
409
|
}), m = this.helpers.points, m.bones.length) {
|
|
410
410
|
this.helpers.isActive = !0;
|
|
411
|
-
const e = new y.BufferGeometry(), n = m.bones.map((
|
|
411
|
+
const e = new y.BufferGeometry(), n = m.bones.map((c) => [0, 0, 0]).flat();
|
|
412
412
|
e.setAttribute("position", new y.Float32BufferAttribute(n, 3));
|
|
413
|
-
const i = new y.Color(this.opt.helperBoneColor1), s = new y.Color(this.opt.helperBoneColor2), o = m.pivots.map((
|
|
413
|
+
const i = new y.Color(this.opt.helperBoneColor1), s = new y.Color(this.opt.helperBoneColor2), o = m.pivots.map((c) => c && this.opt.isPivots ? [s.r, s.g, s.b] : [i.r, i.g, i.b]).flat();
|
|
414
414
|
e.setAttribute("color", new y.Float32BufferAttribute(o, 3));
|
|
415
415
|
const l = new y.PointsMaterial({
|
|
416
416
|
depthTest: !1,
|
|
@@ -423,9 +423,9 @@ class et {
|
|
|
423
423
|
m.object = new y.Points(e, l), m.object.renderOrder = 998, m.object.matrix = this.armature.matrixWorld, m.object.matrixAutoUpdate = !1, this.scene.add(m.object);
|
|
424
424
|
}
|
|
425
425
|
if (m = this.helpers.lines, m.bones.length) {
|
|
426
|
-
const e = new y.BufferGeometry(), n = m.bones.map((
|
|
426
|
+
const e = new y.BufferGeometry(), n = m.bones.map((c) => [0, 0, 0, 0, 0, 0]).flat();
|
|
427
427
|
e.setAttribute("position", new y.Float32BufferAttribute(n, 3));
|
|
428
|
-
const i = new y.Color(this.opt.helperLinkColor1), s = new y.Color(this.opt.helperLinkColor2), o = m.bones.map((
|
|
428
|
+
const i = new y.Color(this.opt.helperLinkColor1), s = new y.Color(this.opt.helperLinkColor2), o = m.bones.map((c) => [i.r, i.g, i.b, s.r, s.g, s.b]).flat();
|
|
429
429
|
e.setAttribute("color", new y.Float32BufferAttribute(o, 3));
|
|
430
430
|
const l = new y.LineBasicMaterial({
|
|
431
431
|
vertexColors: !0,
|
|
@@ -442,17 +442,17 @@ class et {
|
|
|
442
442
|
*/
|
|
443
443
|
updateHelpers() {
|
|
444
444
|
if (m = this.helpers.points, m.bones.length) {
|
|
445
|
-
|
|
445
|
+
be.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
|
+
xe.multiplyMatrices(be, m.bones[e].matrixWorld), E.setFromMatrixPosition(xe), t.setXYZ(e, E.x, E.y, E.z);
|
|
449
449
|
t.needsUpdate = !0, m.object.updateMatrixWorld();
|
|
450
450
|
}
|
|
451
451
|
if (m = this.helpers.lines, m.bones.length) {
|
|
452
|
-
|
|
452
|
+
be.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
|
+
xe.multiplyMatrices(be, m.bones[e].matrixWorld), E.setFromMatrixPosition(xe), t.setXYZ(n, E.x, E.y, E.z), xe.multiplyMatrices(be, m.bones[e].parent.matrixWorld), E.setFromMatrixPosition(xe), t.setXYZ(n + 1, E.x, E.y, E.z);
|
|
456
456
|
t.needsUpdate = !0, m.object.updateMatrixWorld();
|
|
457
457
|
}
|
|
458
458
|
}
|
|
@@ -489,7 +489,7 @@ class et {
|
|
|
489
489
|
this.stop(), this.scene = null, this.armature = null, this.config = [], this.data = [], this.dict = {}, this.objectsUpdate = [], this.timerMs = 0;
|
|
490
490
|
}
|
|
491
491
|
}
|
|
492
|
-
class
|
|
492
|
+
class nt {
|
|
493
493
|
constructor(t) {
|
|
494
494
|
this.audioContext = t, this.analyzer = null, this.dataArray = null, this.bufferLength = 0;
|
|
495
495
|
}
|
|
@@ -519,12 +519,12 @@ class tt {
|
|
|
519
519
|
phonemeBoundaries: []
|
|
520
520
|
}, i = 1024, s = 512, o = Math.floor((t.length - i) / s) + 1;
|
|
521
521
|
for (let l = 0; l < o; l++) {
|
|
522
|
-
const
|
|
522
|
+
const c = l * s, r = Math.min(c + i, t.length), u = t.slice(c, r), a = this.calculateEnergy(u);
|
|
523
523
|
n.energy.push(a);
|
|
524
524
|
const d = this.calculateSpectralCentroid(u);
|
|
525
525
|
n.spectralCentroid.push(d);
|
|
526
|
-
const
|
|
527
|
-
n.zeroCrossingRate.push(
|
|
526
|
+
const h = this.calculateZeroCrossingRate(u);
|
|
527
|
+
n.zeroCrossingRate.push(h);
|
|
528
528
|
const g = this.calculateMFCC(u);
|
|
529
529
|
n.mfcc.push(g);
|
|
530
530
|
}
|
|
@@ -597,19 +597,19 @@ class tt {
|
|
|
597
597
|
for (; s & o; )
|
|
598
598
|
s ^= o, o >>= 1;
|
|
599
599
|
if (s ^= o, i < s) {
|
|
600
|
-
const l = n[i * 2],
|
|
601
|
-
n[i * 2] = n[s * 2], n[i * 2 + 1] = n[s * 2 + 1], n[s * 2] = l, n[s * 2 + 1] =
|
|
600
|
+
const l = n[i * 2], c = n[i * 2 + 1];
|
|
601
|
+
n[i * 2] = n[s * 2], n[i * 2 + 1] = n[s * 2 + 1], n[s * 2] = l, n[s * 2 + 1] = c;
|
|
602
602
|
}
|
|
603
603
|
}
|
|
604
604
|
for (let i = 2; i <= e; i <<= 1) {
|
|
605
605
|
const s = -2 * Math.PI / i, o = Math.cos(s), l = Math.sin(s);
|
|
606
|
-
for (let
|
|
606
|
+
for (let c = 0; c < e; c += i) {
|
|
607
607
|
let r = 1, u = 0;
|
|
608
608
|
for (let a = 0; a < i / 2; a++) {
|
|
609
|
-
const d = n[(
|
|
610
|
-
n[(
|
|
611
|
-
const
|
|
612
|
-
r =
|
|
609
|
+
const d = n[(c + a) * 2], h = n[(c + a) * 2 + 1], g = n[(c + a + i / 2) * 2] * r - n[(c + a + i / 2) * 2 + 1] * u, b = n[(c + a + i / 2) * 2] * u + n[(c + a + i / 2) * 2 + 1] * r;
|
|
610
|
+
n[(c + a) * 2] = d + g, n[(c + a) * 2 + 1] = h + b, n[(c + a + i / 2) * 2] = d - g, n[(c + a + i / 2) * 2 + 1] = h - b;
|
|
611
|
+
const f = r * o - u * l, w = r * l + u * o;
|
|
612
|
+
r = f, u = w;
|
|
613
613
|
}
|
|
614
614
|
}
|
|
615
615
|
}
|
|
@@ -624,8 +624,8 @@ class tt {
|
|
|
624
624
|
const e = [];
|
|
625
625
|
let s = -0.1;
|
|
626
626
|
for (let o = 1; o < t.length; o++) {
|
|
627
|
-
const l = t[o] - t[o - 1],
|
|
628
|
-
l > 0.1 &&
|
|
627
|
+
const l = t[o] - t[o - 1], c = o * 0.023;
|
|
628
|
+
l > 0.1 && c - s > 0.1 && (e.push(c), s = c);
|
|
629
629
|
}
|
|
630
630
|
return e;
|
|
631
631
|
}
|
|
@@ -637,8 +637,8 @@ class tt {
|
|
|
637
637
|
detectPhonemeBoundaries(t) {
|
|
638
638
|
const e = [], { energy: n, spectralCentroid: i, zeroCrossingRate: s } = t;
|
|
639
639
|
for (let o = 1; o < n.length; o++) {
|
|
640
|
-
const l = o * 0.023,
|
|
641
|
-
|
|
640
|
+
const l = o * 0.023, c = Math.abs(n[o] - n[o - 1]), r = Math.abs(i[o] - i[o - 1]), u = Math.abs(s[o] - s[o - 1]);
|
|
641
|
+
c + r * 0.1 + u * 0.5 > 0.2 && e.push(l);
|
|
642
642
|
}
|
|
643
643
|
return e;
|
|
644
644
|
}
|
|
@@ -654,8 +654,8 @@ class tt {
|
|
|
654
654
|
t.phonemeBoundaries, t.onsets;
|
|
655
655
|
const s = [];
|
|
656
656
|
let o = 0;
|
|
657
|
-
for (let
|
|
658
|
-
const r = i[
|
|
657
|
+
for (let c = 0; c < i.length; c++) {
|
|
658
|
+
const r = i[c], u = this.estimateWordDuration(r, n / i.length);
|
|
659
659
|
s.push({
|
|
660
660
|
word: r,
|
|
661
661
|
startTime: o,
|
|
@@ -701,27 +701,27 @@ class tt {
|
|
|
701
701
|
const i = [], s = t.phonemeBoundaries;
|
|
702
702
|
t.onsets;
|
|
703
703
|
const o = this.textToVisemes(e);
|
|
704
|
-
let l = 0,
|
|
704
|
+
let l = 0, c = 0;
|
|
705
705
|
for (let r = 0; r < s.length && l < o.length; r++) {
|
|
706
|
-
const u = s[r], a = o[l], d = t.energy[Math.floor(u / 0.023)] || 0,
|
|
706
|
+
const u = s[r], a = o[l], d = t.energy[Math.floor(u / 0.023)] || 0, h = this.calculateVisemeDuration(a, d);
|
|
707
707
|
i.push({
|
|
708
708
|
viseme: a,
|
|
709
|
-
startTime:
|
|
710
|
-
endTime:
|
|
711
|
-
duration:
|
|
709
|
+
startTime: c,
|
|
710
|
+
endTime: c + h,
|
|
711
|
+
duration: h,
|
|
712
712
|
intensity: Math.min(1, d * 2)
|
|
713
713
|
// Map energy to viseme intensity
|
|
714
|
-
}),
|
|
714
|
+
}), c += h, l++;
|
|
715
715
|
}
|
|
716
716
|
for (; l < o.length; ) {
|
|
717
717
|
const r = o[l], u = this.calculateVisemeDuration(r, 0.5);
|
|
718
718
|
i.push({
|
|
719
719
|
viseme: r,
|
|
720
|
-
startTime:
|
|
721
|
-
endTime:
|
|
720
|
+
startTime: c,
|
|
721
|
+
endTime: c + u,
|
|
722
722
|
duration: u,
|
|
723
723
|
intensity: 0.6
|
|
724
|
-
}),
|
|
724
|
+
}), c += u, l++;
|
|
725
725
|
}
|
|
726
726
|
return i;
|
|
727
727
|
}
|
|
@@ -775,16 +775,16 @@ class tt {
|
|
|
775
775
|
let o = 0;
|
|
776
776
|
for (; o < s.length; ) {
|
|
777
777
|
let l = !1;
|
|
778
|
-
for (let
|
|
779
|
-
const r = s.substr(o,
|
|
778
|
+
for (let c = 3; c >= 2; c--) {
|
|
779
|
+
const r = s.substr(o, c);
|
|
780
780
|
if (e[r]) {
|
|
781
|
-
n.push(e[r]), o +=
|
|
781
|
+
n.push(e[r]), o += c, l = !0;
|
|
782
782
|
break;
|
|
783
783
|
}
|
|
784
784
|
}
|
|
785
785
|
if (!l) {
|
|
786
|
-
const
|
|
787
|
-
e[
|
|
786
|
+
const c = s[o];
|
|
787
|
+
e[c] && n.push(e[c]), o++;
|
|
788
788
|
}
|
|
789
789
|
}
|
|
790
790
|
}
|
|
@@ -814,7 +814,7 @@ class tt {
|
|
|
814
814
|
return i * s;
|
|
815
815
|
}
|
|
816
816
|
}
|
|
817
|
-
class
|
|
817
|
+
class it {
|
|
818
818
|
/**
|
|
819
819
|
* @constructor
|
|
820
820
|
*/
|
|
@@ -1206,11 +1206,11 @@ class nt {
|
|
|
1206
1206
|
};
|
|
1207
1207
|
Object.keys(this.rules).forEach((e) => {
|
|
1208
1208
|
this.rules[e] = this.rules[e].map((n) => {
|
|
1209
|
-
const i = n.indexOf("["), s = n.indexOf("]"), o = n.indexOf("="), l = n.substring(0, i),
|
|
1209
|
+
const i = n.indexOf("["), s = n.indexOf("]"), o = n.indexOf("="), l = n.substring(0, i), c = n.substring(i + 1, s), r = n.substring(s + 1, o), u = n.substring(o + 1), a = { regex: "", move: 0, visemes: [] };
|
|
1210
1210
|
let d = "";
|
|
1211
1211
|
d += [...l].map((g) => t[g] || g).join("");
|
|
1212
|
-
const
|
|
1213
|
-
return
|
|
1212
|
+
const h = [...c];
|
|
1213
|
+
return h[0] = h[0].toLowerCase(), d += h.join(""), a.move = h.length, d += [...r].map((g) => t[g] || g).join(""), a.regex = new RegExp(d), u.length && u.split(" ").forEach((g) => {
|
|
1214
1214
|
a.visemes.push(g);
|
|
1215
1215
|
}), a;
|
|
1216
1216
|
});
|
|
@@ -1324,8 +1324,8 @@ class nt {
|
|
|
1324
1324
|
*/
|
|
1325
1325
|
convertDecade(t) {
|
|
1326
1326
|
const e = parseInt(t), n = !isNaN(e) && t.length === 2, i = !isNaN(e) && t.length > 2 && e > 0 && e <= 3e3, s = i && e % 1e3 === 0 ? Math.floor(e / 1e3) : null, o = i && !s ? Math.floor(e / 100) : null, l = n || i ? Math.floor(e % 100 / 10) * 10 : null;
|
|
1327
|
-
let
|
|
1328
|
-
return s ?
|
|
1327
|
+
let c = [];
|
|
1328
|
+
return s ? c.push(this.convertNumberToWords(s).trim(), "thousands") : (o && c.push(this.convertNumberToWords(o).trim()), l ? c.push(this.decades[l] || this.convertNumberToWords(l).trim() + "s") : o ? c.push("hundreds") : c.push(t)), c.join(" ");
|
|
1329
1329
|
}
|
|
1330
1330
|
/**
|
|
1331
1331
|
* Convert ordinal number to text.
|
|
@@ -1376,9 +1376,9 @@ class nt {
|
|
|
1376
1376
|
const s = i[e.i], o = this.rules[s];
|
|
1377
1377
|
if (o)
|
|
1378
1378
|
for (let l = 0; l < o.length; l++) {
|
|
1379
|
-
const
|
|
1380
|
-
if ((e.words.substring(0, e.i) + s.toLowerCase() + e.words.substring(e.i + 1)).match(
|
|
1381
|
-
|
|
1379
|
+
const c = o[l];
|
|
1380
|
+
if ((e.words.substring(0, e.i) + s.toLowerCase() + e.words.substring(e.i + 1)).match(c.regex)) {
|
|
1381
|
+
c.visemes.forEach((a) => {
|
|
1382
1382
|
if (e.visemes.length && e.visemes[e.visemes.length - 1] === a) {
|
|
1383
1383
|
const d = 0.7 * (this.visemeDurations[a] || 1);
|
|
1384
1384
|
e.durations[e.durations.length - 1] += d, n += d;
|
|
@@ -1386,7 +1386,7 @@ class nt {
|
|
|
1386
1386
|
const d = this.visemeDurations[a] || 1;
|
|
1387
1387
|
e.visemes.push(a), e.times.push(n), e.durations.push(d), n += d;
|
|
1388
1388
|
}
|
|
1389
|
-
}), e.i +=
|
|
1389
|
+
}), e.i += c.move;
|
|
1390
1390
|
break;
|
|
1391
1391
|
}
|
|
1392
1392
|
}
|
|
@@ -1396,11 +1396,11 @@ class nt {
|
|
|
1396
1396
|
return e;
|
|
1397
1397
|
}
|
|
1398
1398
|
}
|
|
1399
|
-
const
|
|
1399
|
+
const ot = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
1400
1400
|
__proto__: null,
|
|
1401
|
-
LipsyncEn:
|
|
1401
|
+
LipsyncEn: it
|
|
1402
1402
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
1403
|
-
class
|
|
1403
|
+
class st {
|
|
1404
1404
|
/**
|
|
1405
1405
|
* @constructor
|
|
1406
1406
|
*/
|
|
@@ -1616,11 +1616,11 @@ class ot {
|
|
|
1616
1616
|
};
|
|
1617
1617
|
Object.keys(this.rules).forEach((e) => {
|
|
1618
1618
|
this.rules[e] = this.rules[e].map((n) => {
|
|
1619
|
-
const i = n.indexOf("["), s = n.indexOf("]"), o = n.indexOf("="), l = n.substring(0, i),
|
|
1619
|
+
const i = n.indexOf("["), s = n.indexOf("]"), o = n.indexOf("="), l = n.substring(0, i), c = n.substring(i + 1, s), r = n.substring(s + 1, o), u = n.substring(o + 1), a = { regex: "", move: 0, visemes: [] };
|
|
1620
1620
|
let d = "";
|
|
1621
1621
|
d += [...l].map((g) => t[g] || g).join("");
|
|
1622
|
-
const
|
|
1623
|
-
return
|
|
1622
|
+
const h = [...c];
|
|
1623
|
+
return h[0] = h[0].toLowerCase(), d += h.join(""), a.move = h.length, d += [...r].map((g) => t[g] || g).join(""), a.regex = new RegExp(d), u.length && u.split(" ").forEach((g) => {
|
|
1624
1624
|
a.visemes.push(g);
|
|
1625
1625
|
}), a;
|
|
1626
1626
|
});
|
|
@@ -1732,16 +1732,16 @@ class ot {
|
|
|
1732
1732
|
const s = i[e.i], o = this.rules[s];
|
|
1733
1733
|
if (o) {
|
|
1734
1734
|
let l = !1;
|
|
1735
|
-
for (let
|
|
1736
|
-
const r = o[
|
|
1735
|
+
for (let c = 0; c < o.length; c++) {
|
|
1736
|
+
const r = o[c];
|
|
1737
1737
|
if ((e.words.substring(0, e.i) + s.toLowerCase() + e.words.substring(e.i + 1)).match(r.regex)) {
|
|
1738
1738
|
r.visemes.forEach((d) => {
|
|
1739
1739
|
if (e.visemes.length && e.visemes[e.visemes.length - 1] === d) {
|
|
1740
|
-
const
|
|
1741
|
-
e.durations[e.durations.length - 1] +=
|
|
1740
|
+
const h = 0.7 * (this.visemeDurations[d] || 1);
|
|
1741
|
+
e.durations[e.durations.length - 1] += h, n += h;
|
|
1742
1742
|
} else {
|
|
1743
|
-
const
|
|
1744
|
-
e.visemes.push(d), e.times.push(n), e.durations.push(
|
|
1743
|
+
const h = this.visemeDurations[d] || 1;
|
|
1744
|
+
e.visemes.push(d), e.times.push(n), e.durations.push(h), n += h;
|
|
1745
1745
|
}
|
|
1746
1746
|
}), e.i += r.move, l = !0;
|
|
1747
1747
|
break;
|
|
@@ -1754,11 +1754,11 @@ class ot {
|
|
|
1754
1754
|
return e;
|
|
1755
1755
|
}
|
|
1756
1756
|
}
|
|
1757
|
-
const
|
|
1757
|
+
const at = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
1758
1758
|
__proto__: null,
|
|
1759
|
-
LipsyncDe:
|
|
1759
|
+
LipsyncDe: st
|
|
1760
1760
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
1761
|
-
class
|
|
1761
|
+
class rt {
|
|
1762
1762
|
/**
|
|
1763
1763
|
* @constructor
|
|
1764
1764
|
*/
|
|
@@ -2131,11 +2131,11 @@ class at {
|
|
|
2131
2131
|
};
|
|
2132
2132
|
Object.keys(this.rules).forEach((e) => {
|
|
2133
2133
|
this.rules[e] = this.rules[e].map((n) => {
|
|
2134
|
-
const i = n.indexOf("["), s = n.indexOf("]"), o = n.indexOf("="), l = n.substring(0, i),
|
|
2134
|
+
const i = n.indexOf("["), s = n.indexOf("]"), o = n.indexOf("="), l = n.substring(0, i), c = n.substring(i + 1, s), r = n.substring(s + 1, o), u = n.substring(o + 1), a = { regex: "", move: 0, visemes: [] };
|
|
2135
2135
|
let d = "";
|
|
2136
2136
|
d += [...l].map((g) => t[g] || g).join("");
|
|
2137
|
-
const
|
|
2138
|
-
return
|
|
2137
|
+
const h = [...c];
|
|
2138
|
+
return h[0] = h[0].toLowerCase(), d += h.join(""), a.move = h.length, d += [...r].map((g) => t[g] || g).join(""), a.regex = new RegExp(d, "i"), u.length && u.split(" ").forEach((g) => {
|
|
2139
2139
|
g && a.visemes.push(g);
|
|
2140
2140
|
}), a;
|
|
2141
2141
|
});
|
|
@@ -2267,16 +2267,16 @@ class at {
|
|
|
2267
2267
|
const s = i[e.i], o = this.rules[s];
|
|
2268
2268
|
if (o) {
|
|
2269
2269
|
let l = !1;
|
|
2270
|
-
for (let
|
|
2271
|
-
const r = o[
|
|
2270
|
+
for (let c = 0; c < o.length; c++) {
|
|
2271
|
+
const r = o[c];
|
|
2272
2272
|
if ((e.words.substring(0, e.i) + s.toLowerCase() + e.words.substring(e.i + 1)).match(r.regex)) {
|
|
2273
2273
|
r.visemes.forEach((d) => {
|
|
2274
2274
|
if (e.visemes.length && e.visemes[e.visemes.length - 1] === d) {
|
|
2275
|
-
const
|
|
2276
|
-
e.durations[e.durations.length - 1] +=
|
|
2275
|
+
const h = 0.7 * (this.visemeDurations[d] || 1);
|
|
2276
|
+
e.durations[e.durations.length - 1] += h, n += h;
|
|
2277
2277
|
} else {
|
|
2278
|
-
const
|
|
2279
|
-
e.visemes.push(d), e.times.push(n), e.durations.push(
|
|
2278
|
+
const h = this.visemeDurations[d] || 1;
|
|
2279
|
+
e.visemes.push(d), e.times.push(n), e.durations.push(h), n += h;
|
|
2280
2280
|
}
|
|
2281
2281
|
}), e.i += r.move, l = !0;
|
|
2282
2282
|
break;
|
|
@@ -2289,11 +2289,11 @@ class at {
|
|
|
2289
2289
|
return e;
|
|
2290
2290
|
}
|
|
2291
2291
|
}
|
|
2292
|
-
const
|
|
2292
|
+
const lt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
2293
2293
|
__proto__: null,
|
|
2294
|
-
LipsyncFr:
|
|
2294
|
+
LipsyncFr: rt
|
|
2295
2295
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
2296
|
-
class
|
|
2296
|
+
class ut {
|
|
2297
2297
|
/**
|
|
2298
2298
|
* @constructor
|
|
2299
2299
|
*/
|
|
@@ -2381,10 +2381,10 @@ class lt {
|
|
|
2381
2381
|
const e = [];
|
|
2382
2382
|
let n = parseFloat(t);
|
|
2383
2383
|
if (n === void 0) return t;
|
|
2384
|
-
let i = (s, o, l,
|
|
2384
|
+
let i = (s, o, l, c, r) => {
|
|
2385
2385
|
if (s < o) return s;
|
|
2386
2386
|
const u = Math.floor(s / o);
|
|
2387
|
-
return e.push(l + (u === 1 ?
|
|
2387
|
+
return e.push(l + (u === 1 ? c : this.numberToFinnishWords(u.toString()) + r)), s - u * o;
|
|
2388
2388
|
};
|
|
2389
2389
|
if (n < 0 && (e.push("miinus "), n = Math.abs(n)), n = i(n, 1e9, " ", "miljardi", " miljardia"), n = i(n, 1e6, " ", "miljoona", " miljoonaa"), n = i(n, 1e3, "", "tuhat", "tuhatta"), n = i(n, 100, " ", "sata", "sataa"), n > 20 && (n = i(n, 10, "", "", "kymmentä")), n >= 1) {
|
|
2390
2390
|
let s = Math.floor(n);
|
|
@@ -2436,9 +2436,9 @@ class lt {
|
|
|
2436
2436
|
return e;
|
|
2437
2437
|
}
|
|
2438
2438
|
}
|
|
2439
|
-
const
|
|
2439
|
+
const ct = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
2440
2440
|
__proto__: null,
|
|
2441
|
-
LipsyncFi:
|
|
2441
|
+
LipsyncFi: ut
|
|
2442
2442
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
2443
2443
|
class ht {
|
|
2444
2444
|
/**
|
|
@@ -2559,10 +2559,10 @@ class ht {
|
|
|
2559
2559
|
const e = [];
|
|
2560
2560
|
let n = parseFloat(t);
|
|
2561
2561
|
if (n === void 0) return t;
|
|
2562
|
-
let i = (s, o, l,
|
|
2562
|
+
let i = (s, o, l, c, r) => {
|
|
2563
2563
|
if (s < o) return s;
|
|
2564
2564
|
const u = Math.floor(s / o);
|
|
2565
|
-
return u === 1 ? e.push(this.numbers[1]) : e.push(this.numberToLithuanianWords(u.toString())), u % 10 === 1 ? e.push(l) : u % 10 === 0 || u % 100 > 10 && u % 100 < 20 ? e.push(r) : e.push(
|
|
2565
|
+
return u === 1 ? e.push(this.numbers[1]) : e.push(this.numberToLithuanianWords(u.toString())), u % 10 === 1 ? e.push(l) : u % 10 === 0 || u % 100 > 10 && u % 100 < 20 ? e.push(r) : e.push(c), s - u * o;
|
|
2566
2566
|
};
|
|
2567
2567
|
n < 0 && (e.push("minus"), n = Math.abs(n)), n = i(n, 1e9, "milijardas", "milijardai", "milijardų"), n = i(n, 1e6, "milijonas", "milijonai", "milijonų"), n = i(n, 1e3, "tūkstantis", "tūkstančiai", "tūkstančių"), n = i(n, 100, "šimtas", "šimtai", "šimtų");
|
|
2568
2568
|
for (let s = this.tens.length - 1; s >= 1; s--)
|
|
@@ -2608,11 +2608,11 @@ class ht {
|
|
|
2608
2608
|
const o = i[s].toLowerCase(), l = this.visemes[o];
|
|
2609
2609
|
if (l)
|
|
2610
2610
|
if (e.visemes.length && e.visemes[e.visemes.length - 1] === l) {
|
|
2611
|
-
const
|
|
2612
|
-
e.durations[e.durations.length - 1] +=
|
|
2611
|
+
const c = 0.7 * (this.durations[o] || 1);
|
|
2612
|
+
e.durations[e.durations.length - 1] += c, n += c;
|
|
2613
2613
|
} else {
|
|
2614
|
-
const
|
|
2615
|
-
e.visemes.push(l), e.times.push(n), e.durations.push(
|
|
2614
|
+
const c = this.durations[o] || 1;
|
|
2615
|
+
e.visemes.push(l), e.times.push(n), e.durations.push(c), n += c;
|
|
2616
2616
|
}
|
|
2617
2617
|
else
|
|
2618
2618
|
n += this.pauses[i[s]] || 0;
|
|
@@ -2620,21 +2620,21 @@ class ht {
|
|
|
2620
2620
|
return e;
|
|
2621
2621
|
}
|
|
2622
2622
|
}
|
|
2623
|
-
const
|
|
2623
|
+
const dt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
2624
2624
|
__proto__: null,
|
|
2625
2625
|
LipsyncLt: ht
|
|
2626
|
-
}, Symbol.toStringTag, { value: "Module" })), dt = new URL("data:text/javascript;base64,Y2xhc3MgUGxheWJhY2tXb3JrbGV0IGV4dGVuZHMgQXVkaW9Xb3JrbGV0UHJvY2Vzc29yIHsKICBzdGF0aWMgRlNNID0gewogICAgSURMRTogMCwKICAgIFBMQVlJTkc6IDEsCiAgfTsKCiAgY29uc3RydWN0b3Iob3B0aW9ucykgewogICAgc3VwZXIoKTsKICAgIHRoaXMucG9ydC5vbm1lc3NhZ2UgPSB0aGlzLmhhbmRsZU1lc3NhZ2UuYmluZCh0aGlzKTsKCiAgICB0aGlzLl9zYW1wbGVSYXRlID0gb3B0aW9ucz8ucHJvY2Vzc29yT3B0aW9ucz8uc2FtcGxlUmF0ZSB8fCBzYW1wbGVSYXRlOwogICAgdGhpcy5fc2NhbGUgPSAxIC8gMzI3Njg7IC8vIFBDTTE2IC0+IGZsb2F0CgogICAgLy8gU2lsZW5jZSBkZXRlY3Rpb24gdGhyZXNob2xkICgxIHNlY29uZCkgYXMgYSBmYWxsYmFjayBzYWZldHkgbmV0CiAgICBjb25zdCBzaWxlbmNlRHVyYXRpb25TZWNvbmRzID0gMS4wOwogICAgdGhpcy5fc2lsZW5jZVRocmVzaG9sZEJsb2NrcyA9IE1hdGguY2VpbCgodGhpcy5fc2FtcGxlUmF0ZSAqIHNpbGVuY2VEdXJhdGlvblNlY29uZHMpIC8gMTI4KTsKCiAgICAvLyBNZXRyaWNzIGNvbmZpZ3VyYXRpb24gdmlhIG9wdGlvbnMKICAgIGNvbnN0IG1ldHJpY3NDZmcgPSBvcHRpb25zPy5wcm9jZXNzb3JPcHRpb25zPy5tZXRyaWNzIHx8IHt9OwogICAgdGhpcy5fbWV0cmljc0VuYWJsZWQgPSBtZXRyaWNzQ2ZnLmVuYWJsZWQgIT09IGZhbHNlOwogICAgY29uc3QgaW50ZXJ2YWxIeiA9ICh0eXBlb2YgbWV0cmljc0NmZy5pbnRlcnZhbEh6ID09PSAibnVtYmVyIiAmJiBtZXRyaWNzQ2ZnLmludGVydmFsSHogPiAwKQogICAgICA/IG1ldHJpY3NDZmcuaW50ZXJ2YWxIeiA6IDI7CiAgICAvLyBNZXRyaWNzIHN0YXRlIChsb3ctb3ZlcmhlYWQpCiAgICB0aGlzLl9mcmFtZXNQcm9jZXNzZWQgPSAwOwogICAgdGhpcy5fdW5kZXJydW5CbG9ja3MgPSAwOwogICAgdGhpcy5fbWF4UXVldWVTYW1wbGVzID0gMDsKICAgIHRoaXMuX2xhc3RNZXRyaWNzU2VudEF0RnJhbWUgPSAwOwogICAgLy8gQ29udmVydCB0byBmcmFtZXMgYmV0d2VlbiByZXBvcnRzCiAgICB0aGlzLl9tZXRyaWNzSW50ZXJ2YWxGcmFtZXMgPSBNYXRoLm1heCgxMjgsIE1hdGgucm91bmQodGhpcy5fc2FtcGxlUmF0ZSAvIGludGVydmFsSHopKTsKCiAgICB0aGlzLnJlc2V0KCk7CiAgfQoKICAvKioKICAgKiBSZXNldHMgdGhlIHdvcmtsZXQgdG8gaXRzIGluaXRpYWwgSURMRSBzdGF0ZS4KICAgKi8KICByZXNldCgpIHsKICAgIHRoaXMuX2J1ZmZlclF1ZXVlID0gW107CiAgICB0aGlzLl9jdXJyZW50Q2h1bmsgPSBudWxsOwogICAgdGhpcy5fY3VycmVudENodW5rT2Zmc2V0ID0gMDsKICAgIHRoaXMuX3N0YXRlID0gUGxheWJhY2tXb3JrbGV0LkZTTS5JRExFOwoKICAgIHRoaXMuX25vTW9yZURhdGFSZWNlaXZlZCA9IGZhbHNlOwogICAgdGhpcy5fc2lsZW5jZUZyYW1lc0NvdW50ID0gMDsKICAgIHRoaXMuX2hhc1NlbnRFbmRlZCA9IGZhbHNlOwogICAgLy8gUmVzZXQgbWF4IHF1ZXVlIHRyYWNrZXIgb25seSB3aGVuIGdvaW5nIGlkbGUKICAgIHRoaXMuX21heFF1ZXVlU2FtcGxlcyA9IDA7CiAgfQoKICBoYW5kbGVNZXNzYWdlKGV2ZW50KSB7CiAgICBjb25zdCB7IHR5cGUsIGRhdGEgfSA9IGV2ZW50LmRhdGE7CgogICAgLy8gSU5URVJSVVBUOiBUaGUgbWFpbiB0aHJlYWQgd2FudHMgdG8gc3RvcCBpbW1lZGlhdGVseS4KICAgIGlmICh0eXBlID09PSAic3RvcCIpIHsKICAgICAgdGhpcy5yZXNldCgpOwogICAgICAvLyBTZW5kIGZpbmFsIG1ldHJpY3Mgc2hvd2luZyBjbGVhcmVkIHN0YXRlCiAgICAgIGlmICh0aGlzLl9tZXRyaWNzRW5hYmxlZCkgewogICAgICAgIHRyeSB7CiAgICAgICAgICB0aGlzLnBvcnQucG9zdE1lc3NhZ2UoewogICAgICAgICAgICB0eXBlOiAibWV0cmljcyIsCiAgICAgICAgICAgIGRhdGE6IHsKICAgICAgICAgICAgICBzdGF0ZTogUGxheWJhY2tXb3JrbGV0LkZTTS5JRExFLAogICAgICAgICAgICAgIHF1ZXVlZFNhbXBsZXM6IDAsCiAgICAgICAgICAgICAgcXVldWVkTXM6IDAsCiAgICAgICAgICAgICAgbWF4UXVldWVkTXM6IE1hdGgucm91bmQoKHRoaXMuX21heFF1ZXVlU2FtcGxlcyAvIHRoaXMuX3NhbXBsZVJhdGUpICogMTAwMCksCiAgICAgICAgICAgICAgdW5kZXJydW5CbG9ja3M6IHRoaXMuX3VuZGVycnVuQmxvY2tzLAogICAgICAgICAgICAgIGZyYW1lc1Byb2Nlc3NlZDogdGhpcy5fZnJhbWVzUHJvY2Vzc2VkCiAgICAgICAgICAgIH0KICAgICAgICAgIH0pOwogICAgICAgIH0gY2F0Y2ggKF8pIHsgfQogICAgICB9CiAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBNYWluIHRocmVhZCBoYXMgc2lnbmFsZWQgdGhhdCBubyBtb3JlIGF1ZGlvIGNodW5rcyB3aWxsIGJlIHNlbnQgZm9yIHRoaXMgdXR0ZXJhbmNlLgogICAgaWYgKHR5cGUgPT09ICJuby1tb3JlLWRhdGEiKSB7CiAgICAgIHRoaXMuX25vTW9yZURhdGFSZWNlaXZlZCA9IHRydWU7CiAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBVcGRhdGUgbWV0cmljcyBjb25maWd1cmF0aW9uIGF0IHJ1bnRpbWUKICAgIGlmICh0eXBlID09PSAiY29uZmlnLW1ldHJpY3MiICYmIGRhdGEgJiYgdHlwZW9mIGRhdGEgPT09ICJvYmplY3QiKSB7CiAgICAgIGlmICgiZW5hYmxlZCIgaW4gZGF0YSkgdGhpcy5fbWV0cmljc0VuYWJsZWQgPSAhIWRhdGEuZW5hYmxlZDsKICAgICAgaWYgKHR5cGVvZiBkYXRhLmludGVydmFsSHogPT09ICJudW1iZXIiICYmIGRhdGEuaW50ZXJ2YWxIeiA+IDApIHsKICAgICAgICBjb25zdCBpbnRlcnZhbEh6ID0gZGF0YS5pbnRlcnZhbEh6OwogICAgICAgIHRoaXMuX21ldHJpY3NJbnRlcnZhbEZyYW1lcyA9IE1hdGgubWF4KDEyOCwgTWF0aC5yb3VuZCh0aGlzLl9zYW1wbGVSYXRlIC8gaW50ZXJ2YWxIeikpOwogICAgICB9CiAgICAgIC8vIFJlc2V0IHBhY2luZyBzbyB0aGUgbmV4dCByZXBvcnQgYWxpZ25zIHdpdGggbmV3IGludGVydmFsCiAgICAgIHRoaXMuX2xhc3RNZXRyaWNzU2VudEF0RnJhbWUgPSB0aGlzLl9mcmFtZXNQcm9jZXNzZWQ7CiAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBOZXcgYXVkaW8gZGF0YSBoYXMgYXJyaXZlZC4KICAgIGlmICh0eXBlID09PSAiYXVkaW9EYXRhIiAmJiBkYXRhIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHsKICAgICAgdGhpcy5fbm9Nb3JlRGF0YVJlY2VpdmVkID0gZmFsc2U7CiAgICAgIC8vIElmIHdlIHdlcmUgaWRsZSwgdGhpcyBuZXcgZGF0YSBraWNrcyBvZmYgdGhlIHBsYXliYWNrLgogICAgICBpZiAodGhpcy5fc3RhdGUgPT09IFBsYXliYWNrV29ya2xldC5GU00uSURMRSkgewogICAgICAgIHRoaXMuX3N0YXRlID0gUGxheWJhY2tXb3JrbGV0LkZTTS5QTEFZSU5HOwogICAgICAgIHRoaXMucG9ydC5wb3N0TWVzc2FnZSh7IHR5cGU6ICJwbGF5YmFjay1zdGFydGVkIiB9KTsKICAgICAgfQoKICAgICAgLy8gV2Ugb25seSBxdWV1ZSBkYXRhIGlmIHdlIGFyZSBpbiB0aGUgUExBWUlORyBzdGF0ZS4gVGhpcyBwcmV2ZW50cwogICAgICAvLyBkYXRhIGZyb20gYSBwcmV2aW91cywgaW50ZXJydXB0ZWQgc3RyZWFtIGZyb20gbGluZ2VyaW5nLgogICAgICBpZiAodGhpcy5fc3RhdGUgPT09IFBsYXliYWNrV29ya2xldC5GU00uUExBWUlORykgewogICAgICAgIC8vIFN0b3JlIGFzIEludDE2QXJyYXkgdmlldyB0byBhdm9pZCBjb25zdHJ1Y3RpbmcgaXQgaW4gcHJvY2VzcygpCiAgICAgICAgdGhpcy5fYnVmZmVyUXVldWUucHVzaChuZXcgSW50MTZBcnJheShkYXRhKSk7CiAgICAgICAgdGhpcy5fc2lsZW5jZUZyYW1lc0NvdW50ID0gMDsgLy8gUmVzZXQgc2lsZW5jZSBjb3VudGVyIG9uIG5ldyBkYXRhCiAgICAgIH0KICAgIH0KICB9CgogIHByb2Nlc3MoaW5wdXRzLCBvdXRwdXRzLCBwYXJhbWV0ZXJzKSB7CiAgICBjb25zdCBvdXRwdXRDaGFubmVsID0gb3V0cHV0c1swXT8uWzBdOwogICAgaWYgKCFvdXRwdXRDaGFubmVsKSB7CiAgICAgIHJldHVybiB0cnVlOyAvLyBLZWVwIGFsaXZlIGV2ZW4gaWYgb3V0cHV0IGlzIHRlbXBvcmFyaWx5IGRpc2Nvbm5lY3RlZAogICAgfQoKICAgIC8vIElmIHdlIGFyZSBub3QgcGxheWluZywganVzdCBvdXRwdXQgc2lsZW5jZSBhbmQgd2FpdC4KICAgIGlmICh0aGlzLl9zdGF0ZSAhPT0gUGxheWJhY2tXb3JrbGV0LkZTTS5QTEFZSU5HKSB7CiAgICAgIG91dHB1dENoYW5uZWwuZmlsbCgwKTsKICAgICAgcmV0dXJuIHRydWU7IC8vIEFsd2F5cyByZXR1cm4gdHJ1ZSB0byBrZWVwIHRoZSBwcm9jZXNzb3IgYWxpdmUKICAgIH0KCiAgICAvLyBDb3JlIFBMQVlJTkcgTG9naWMKICAgIGNvbnN0IGJsb2NrU2l6ZSA9IG91dHB1dENoYW5uZWwubGVuZ3RoOwogICAgbGV0IHNhbXBsZXNDb3BpZWQgPSAwOwoKICAgIHdoaWxlIChzYW1wbGVzQ29waWVkIDwgYmxvY2tTaXplKSB7CiAgICAgIGlmICghdGhpcy5fY3VycmVudENodW5rIHx8IHRoaXMuX2N1cnJlbnRDaHVua09mZnNldCA+PSB0aGlzLl9jdXJyZW50Q2h1bmsubGVuZ3RoKSB7CiAgICAgICAgaWYgKHRoaXMuX2J1ZmZlclF1ZXVlLmxlbmd0aCA+IDApIHsKICAgICAgICAgIHRoaXMuX2N1cnJlbnRDaHVuayA9IHRoaXMuX2J1ZmZlclF1ZXVlLnNoaWZ0KCk7CiAgICAgICAgICB0aGlzLl9jdXJyZW50Q2h1bmtPZmZzZXQgPSAwOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAvLyBCdWZmZXIgaXMgZW1wdHkuIENoZWNrIGZvciBlbmQgY29uZGl0aW9ucy4KICAgICAgICAgIGNvbnN0IGlzVGltZWRPdXQgPSB0aGlzLl9zaWxlbmNlRnJhbWVzQ291bnQgPiB0aGlzLl9zaWxlbmNlVGhyZXNob2xkQmxvY2tzOwoKICAgICAgICAgIGlmICh0aGlzLl9ub01vcmVEYXRhUmVjZWl2ZWQgfHwgaXNUaW1lZE91dCkgewogICAgICAgICAgICAvLyBFTkQgT0YgUExBWUJBQ0s6IEVpdGhlciBleHBsaWNpdGx5IHNpZ25hbGVkIG9yIHRpbWVkIG91dC4KICAgICAgICAgICAgaWYgKCF0aGlzLl9oYXNTZW50RW5kZWQpIHsKICAgICAgICAgICAgICB0aGlzLnBvcnQucG9zdE1lc3NhZ2UoeyB0eXBlOiAicGxheWJhY2stZW5kZWQiIH0pOwogICAgICAgICAgICAgIHRoaXMuX2hhc1NlbnRFbmRlZCA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gU2VuZCBmaW5hbCBtZXRyaWNzIHNob3dpbmcgY2xlYXJlZCBzdGF0ZQogICAgICAgICAgICBpZiAodGhpcy5fbWV0cmljc0VuYWJsZWQpIHsKICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgdGhpcy5wb3J0LnBvc3RNZXNzYWdlKHsKICAgICAgICAgICAgICAgICAgdHlwZTogIm1ldHJpY3MiLAogICAgICAgICAgICAgICAgICBkYXRhOiB7CiAgICAgICAgICAgICAgICAgICAgc3RhdGU6IFBsYXliYWNrV29ya2xldC5GU00uSURMRSwKICAgICAgICAgICAgICAgICAgICBxdWV1ZWRTYW1wbGVzOiAwLAogICAgICAgICAgICAgICAgICAgIHF1ZXVlZE1zOiAwLAogICAgICAgICAgICAgICAgICAgIG1heFF1ZXVlZE1zOiBNYXRoLnJvdW5kKCh0aGlzLl9tYXhRdWV1ZVNhbXBsZXMgLyB0aGlzLl9zYW1wbGVSYXRlKSAqIDEwMDApLAogICAgICAgICAgICAgICAgICAgIHVuZGVycnVuQmxvY2tzOiB0aGlzLl91bmRlcnJ1bkJsb2NrcywKICAgICAgICAgICAgICAgICAgICBmcmFtZXNQcm9jZXNzZWQ6IHRoaXMuX2ZyYW1lc1Byb2Nlc3NlZAogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICB9IGNhdGNoIChfKSB7IH0KICAgICAgICAgICAgfQogICAgICAgICAgICB0aGlzLnJlc2V0KCk7IC8vIFJlc2V0IHRvIElETEUgc3RhdGUgZm9yIHJldXNlCiAgICAgICAgICAgIGJyZWFrOyAvLyBFeGl0IHdoaWxlIGxvb3AKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8vIEJVRkZFUiBVTkRFUlJVTiAoTEFHKTogUGxheSBzaWxlbmNlIGFuZCB3YWl0IGZvciBtb3JlIGRhdGEuCiAgICAgICAgICAgIHRoaXMuX3NpbGVuY2VGcmFtZXNDb3VudCsrOwogICAgICAgICAgICBpZiAodGhpcy5fbWV0cmljc0VuYWJsZWQpIHRoaXMuX3VuZGVycnVuQmxvY2tzKys7CiAgICAgICAgICAgIGJyZWFrOyAvLyBFeGl0IHdoaWxlIGxvb3AKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KCiAgICAgIC8vIElmIHdlIGhhdmUgYSBjaHVuayAoY291bGQgYmUgYSBuZXcgb25lIGZyb20gdGhlIGxvZ2ljIGFib3ZlKSwgcHJvY2VzcyBpdC4KICAgICAgaWYgKHRoaXMuX2N1cnJlbnRDaHVuaykgewogICAgICAgIGNvbnN0IHNhbXBsZXNUb0NvcHkgPSBNYXRoLm1pbigKICAgICAgICAgIGJsb2NrU2l6ZSAtIHNhbXBsZXNDb3BpZWQsCiAgICAgICAgICB0aGlzLl9jdXJyZW50Q2h1bmsubGVuZ3RoIC0gdGhpcy5fY3VycmVudENodW5rT2Zmc2V0CiAgICAgICAgKTsKICAgICAgICAvLyBEaXJlY3RseSB3cml0ZSB0byBvdXRwdXRDaGFubmVsIHRvIGF2b2lkIGV4dHJhIGNvcHkKICAgICAgICBjb25zdCBzcmMgPSB0aGlzLl9jdXJyZW50Q2h1bms7CiAgICAgICAgY29uc3QgYmFzZVNyYyA9IHRoaXMuX2N1cnJlbnRDaHVua09mZnNldDsKICAgICAgICBjb25zdCBiYXNlRHN0ID0gc2FtcGxlc0NvcGllZDsKICAgICAgICBjb25zdCBzY2FsZSA9IHRoaXMuX3NjYWxlOwogICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2FtcGxlc1RvQ29weTsgaSsrKSB7CiAgICAgICAgICBvdXRwdXRDaGFubmVsW2Jhc2VEc3QgKyBpXSA9IHNyY1tiYXNlU3JjICsgaV0gKiBzY2FsZTsKICAgICAgICB9CgogICAgICAgIHRoaXMuX2N1cnJlbnRDaHVua09mZnNldCArPSBzYW1wbGVzVG9Db3B5OwogICAgICAgIHNhbXBsZXNDb3BpZWQgKz0gc2FtcGxlc1RvQ29weTsKICAgICAgfQogICAgfQoKICAgIC8vIFplcm8tZmlsbCB0aGUgcmVtYWluZGVyLCBpZiBhbnksIG9uY2UgcGVyIGJsb2NrCiAgICBpZiAoc2FtcGxlc0NvcGllZCA8IGJsb2NrU2l6ZSkgewogICAgICBvdXRwdXRDaGFubmVsLmZpbGwoMCwgc2FtcGxlc0NvcGllZCk7CiAgICB9CgogICAgLy8gVXBkYXRlIG1ldHJpY3MgKG9wdGlvbmFsKQogICAgaWYgKHRoaXMuX21ldHJpY3NFbmFibGVkKSB7CiAgICAgIHRoaXMuX2ZyYW1lc1Byb2Nlc3NlZCArPSBibG9ja1NpemU7CgogICAgICAvLyBUcmFjayBxdWV1ZSBkZXB0aCBpbiBzYW1wbGVzIChhcHByb3hpbWF0ZSkKICAgICAgbGV0IHF1ZXVlZFNhbXBsZXMgPSAwOwogICAgICBpZiAodGhpcy5fY3VycmVudENodW5rKSBxdWV1ZWRTYW1wbGVzICs9IE1hdGgubWF4KDAsIHRoaXMuX2N1cnJlbnRDaHVuay5sZW5ndGggLSB0aGlzLl9jdXJyZW50Q2h1bmtPZmZzZXQpOwogICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX2J1ZmZlclF1ZXVlLmxlbmd0aDsgaSsrKSBxdWV1ZWRTYW1wbGVzICs9IHRoaXMuX2J1ZmZlclF1ZXVlW2ldLmxlbmd0aDsKICAgICAgaWYgKHF1ZXVlZFNhbXBsZXMgPiB0aGlzLl9tYXhRdWV1ZVNhbXBsZXMpIHRoaXMuX21heFF1ZXVlU2FtcGxlcyA9IHF1ZXVlZFNhbXBsZXM7CgogICAgICAvLyBQZXJpb2RpY2FsbHkgc2VuZCBtZXRyaWNzIHRvIG1haW4gdGhyZWFkCiAgICAgIGlmICh0aGlzLl9mcmFtZXNQcm9jZXNzZWQgLSB0aGlzLl9sYXN0TWV0cmljc1NlbnRBdEZyYW1lID49IHRoaXMuX21ldHJpY3NJbnRlcnZhbEZyYW1lcykgewogICAgICAgIHRoaXMuX2xhc3RNZXRyaWNzU2VudEF0RnJhbWUgPSB0aGlzLl9mcmFtZXNQcm9jZXNzZWQ7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIHRoaXMucG9ydC5wb3N0TWVzc2FnZSh7CiAgICAgICAgICAgIHR5cGU6ICJtZXRyaWNzIiwKICAgICAgICAgICAgZGF0YTogewogICAgICAgICAgICAgIHN0YXRlOiB0aGlzLl9zdGF0ZSwKICAgICAgICAgICAgICBxdWV1ZWRTYW1wbGVzLAogICAgICAgICAgICAgIHF1ZXVlZE1zOiBNYXRoLnJvdW5kKChxdWV1ZWRTYW1wbGVzIC8gdGhpcy5fc2FtcGxlUmF0ZSkgKiAxMDAwKSwKICAgICAgICAgICAgICBtYXhRdWV1ZWRNczogTWF0aC5yb3VuZCgodGhpcy5fbWF4UXVldWVTYW1wbGVzIC8gdGhpcy5fc2FtcGxlUmF0ZSkgKiAxMDAwKSwKICAgICAgICAgICAgICB1bmRlcnJ1bkJsb2NrczogdGhpcy5fdW5kZXJydW5CbG9ja3MsCiAgICAgICAgICAgICAgZnJhbWVzUHJvY2Vzc2VkOiB0aGlzLl9mcmFtZXNQcm9jZXNzZWQKICAgICAgICAgICAgfQogICAgICAgICAgfSk7CiAgICAgICAgfSBjYXRjaCAoXykgeyB9CiAgICAgICAgLy8gRG9uJ3QgcmVzZXQgbWF4IHRyYWNrZXIgLSBrZWVwIHNlc3Npb24gcGVhayB1bnRpbCBpZGxlCiAgICAgIH0KICAgIH0KCiAgICAvLyBBTFdBWVMgcmV0dXJuIHRydWUgdG8ga2VlcCB0aGUgcHJvY2Vzc29yIGFsaXZlIGZvciByZXVzZS4KICAgIHJldHVybiB0cnVlOwogIH0KfQoKcmVnaXN0ZXJQcm9jZXNzb3IoInBsYXliYWNrLXdvcmtsZXQiLCBQbGF5YmFja1dvcmtsZXQpOwo=", import.meta.url), Ue = {
|
|
2627
|
-
en:
|
|
2628
|
-
de:
|
|
2629
|
-
fr:
|
|
2630
|
-
fi:
|
|
2631
|
-
lt:
|
|
2632
|
-
},
|
|
2626
|
+
}, Symbol.toStringTag, { value: "Module" })), mt = new URL("data:text/javascript;base64,Y2xhc3MgUGxheWJhY2tXb3JrbGV0IGV4dGVuZHMgQXVkaW9Xb3JrbGV0UHJvY2Vzc29yIHsKICBzdGF0aWMgRlNNID0gewogICAgSURMRTogMCwKICAgIFBMQVlJTkc6IDEsCiAgfTsKCiAgY29uc3RydWN0b3Iob3B0aW9ucykgewogICAgc3VwZXIoKTsKICAgIHRoaXMucG9ydC5vbm1lc3NhZ2UgPSB0aGlzLmhhbmRsZU1lc3NhZ2UuYmluZCh0aGlzKTsKCiAgICB0aGlzLl9zYW1wbGVSYXRlID0gb3B0aW9ucz8ucHJvY2Vzc29yT3B0aW9ucz8uc2FtcGxlUmF0ZSB8fCBzYW1wbGVSYXRlOwogICAgdGhpcy5fc2NhbGUgPSAxIC8gMzI3Njg7IC8vIFBDTTE2IC0+IGZsb2F0CgogICAgLy8gU2lsZW5jZSBkZXRlY3Rpb24gdGhyZXNob2xkICgxIHNlY29uZCkgYXMgYSBmYWxsYmFjayBzYWZldHkgbmV0CiAgICBjb25zdCBzaWxlbmNlRHVyYXRpb25TZWNvbmRzID0gMS4wOwogICAgdGhpcy5fc2lsZW5jZVRocmVzaG9sZEJsb2NrcyA9IE1hdGguY2VpbCgodGhpcy5fc2FtcGxlUmF0ZSAqIHNpbGVuY2VEdXJhdGlvblNlY29uZHMpIC8gMTI4KTsKCiAgICAvLyBNZXRyaWNzIGNvbmZpZ3VyYXRpb24gdmlhIG9wdGlvbnMKICAgIGNvbnN0IG1ldHJpY3NDZmcgPSBvcHRpb25zPy5wcm9jZXNzb3JPcHRpb25zPy5tZXRyaWNzIHx8IHt9OwogICAgdGhpcy5fbWV0cmljc0VuYWJsZWQgPSBtZXRyaWNzQ2ZnLmVuYWJsZWQgIT09IGZhbHNlOwogICAgY29uc3QgaW50ZXJ2YWxIeiA9ICh0eXBlb2YgbWV0cmljc0NmZy5pbnRlcnZhbEh6ID09PSAibnVtYmVyIiAmJiBtZXRyaWNzQ2ZnLmludGVydmFsSHogPiAwKQogICAgICA/IG1ldHJpY3NDZmcuaW50ZXJ2YWxIeiA6IDI7CiAgICAvLyBNZXRyaWNzIHN0YXRlIChsb3ctb3ZlcmhlYWQpCiAgICB0aGlzLl9mcmFtZXNQcm9jZXNzZWQgPSAwOwogICAgdGhpcy5fdW5kZXJydW5CbG9ja3MgPSAwOwogICAgdGhpcy5fbWF4UXVldWVTYW1wbGVzID0gMDsKICAgIHRoaXMuX2xhc3RNZXRyaWNzU2VudEF0RnJhbWUgPSAwOwogICAgLy8gQ29udmVydCB0byBmcmFtZXMgYmV0d2VlbiByZXBvcnRzCiAgICB0aGlzLl9tZXRyaWNzSW50ZXJ2YWxGcmFtZXMgPSBNYXRoLm1heCgxMjgsIE1hdGgucm91bmQodGhpcy5fc2FtcGxlUmF0ZSAvIGludGVydmFsSHopKTsKCiAgICB0aGlzLnJlc2V0KCk7CiAgfQoKICAvKioKICAgKiBSZXNldHMgdGhlIHdvcmtsZXQgdG8gaXRzIGluaXRpYWwgSURMRSBzdGF0ZS4KICAgKi8KICByZXNldCgpIHsKICAgIHRoaXMuX2J1ZmZlclF1ZXVlID0gW107CiAgICB0aGlzLl9jdXJyZW50Q2h1bmsgPSBudWxsOwogICAgdGhpcy5fY3VycmVudENodW5rT2Zmc2V0ID0gMDsKICAgIHRoaXMuX3N0YXRlID0gUGxheWJhY2tXb3JrbGV0LkZTTS5JRExFOwoKICAgIHRoaXMuX25vTW9yZURhdGFSZWNlaXZlZCA9IGZhbHNlOwogICAgdGhpcy5fc2lsZW5jZUZyYW1lc0NvdW50ID0gMDsKICAgIHRoaXMuX2hhc1NlbnRFbmRlZCA9IGZhbHNlOwogICAgLy8gUmVzZXQgbWF4IHF1ZXVlIHRyYWNrZXIgb25seSB3aGVuIGdvaW5nIGlkbGUKICAgIHRoaXMuX21heFF1ZXVlU2FtcGxlcyA9IDA7CiAgfQoKICBoYW5kbGVNZXNzYWdlKGV2ZW50KSB7CiAgICBjb25zdCB7IHR5cGUsIGRhdGEgfSA9IGV2ZW50LmRhdGE7CgogICAgLy8gSU5URVJSVVBUOiBUaGUgbWFpbiB0aHJlYWQgd2FudHMgdG8gc3RvcCBpbW1lZGlhdGVseS4KICAgIGlmICh0eXBlID09PSAic3RvcCIpIHsKICAgICAgdGhpcy5yZXNldCgpOwogICAgICAvLyBTZW5kIGZpbmFsIG1ldHJpY3Mgc2hvd2luZyBjbGVhcmVkIHN0YXRlCiAgICAgIGlmICh0aGlzLl9tZXRyaWNzRW5hYmxlZCkgewogICAgICAgIHRyeSB7CiAgICAgICAgICB0aGlzLnBvcnQucG9zdE1lc3NhZ2UoewogICAgICAgICAgICB0eXBlOiAibWV0cmljcyIsCiAgICAgICAgICAgIGRhdGE6IHsKICAgICAgICAgICAgICBzdGF0ZTogUGxheWJhY2tXb3JrbGV0LkZTTS5JRExFLAogICAgICAgICAgICAgIHF1ZXVlZFNhbXBsZXM6IDAsCiAgICAgICAgICAgICAgcXVldWVkTXM6IDAsCiAgICAgICAgICAgICAgbWF4UXVldWVkTXM6IE1hdGgucm91bmQoKHRoaXMuX21heFF1ZXVlU2FtcGxlcyAvIHRoaXMuX3NhbXBsZVJhdGUpICogMTAwMCksCiAgICAgICAgICAgICAgdW5kZXJydW5CbG9ja3M6IHRoaXMuX3VuZGVycnVuQmxvY2tzLAogICAgICAgICAgICAgIGZyYW1lc1Byb2Nlc3NlZDogdGhpcy5fZnJhbWVzUHJvY2Vzc2VkCiAgICAgICAgICAgIH0KICAgICAgICAgIH0pOwogICAgICAgIH0gY2F0Y2ggKF8pIHsgfQogICAgICB9CiAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBNYWluIHRocmVhZCBoYXMgc2lnbmFsZWQgdGhhdCBubyBtb3JlIGF1ZGlvIGNodW5rcyB3aWxsIGJlIHNlbnQgZm9yIHRoaXMgdXR0ZXJhbmNlLgogICAgaWYgKHR5cGUgPT09ICJuby1tb3JlLWRhdGEiKSB7CiAgICAgIHRoaXMuX25vTW9yZURhdGFSZWNlaXZlZCA9IHRydWU7CiAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBVcGRhdGUgbWV0cmljcyBjb25maWd1cmF0aW9uIGF0IHJ1bnRpbWUKICAgIGlmICh0eXBlID09PSAiY29uZmlnLW1ldHJpY3MiICYmIGRhdGEgJiYgdHlwZW9mIGRhdGEgPT09ICJvYmplY3QiKSB7CiAgICAgIGlmICgiZW5hYmxlZCIgaW4gZGF0YSkgdGhpcy5fbWV0cmljc0VuYWJsZWQgPSAhIWRhdGEuZW5hYmxlZDsKICAgICAgaWYgKHR5cGVvZiBkYXRhLmludGVydmFsSHogPT09ICJudW1iZXIiICYmIGRhdGEuaW50ZXJ2YWxIeiA+IDApIHsKICAgICAgICBjb25zdCBpbnRlcnZhbEh6ID0gZGF0YS5pbnRlcnZhbEh6OwogICAgICAgIHRoaXMuX21ldHJpY3NJbnRlcnZhbEZyYW1lcyA9IE1hdGgubWF4KDEyOCwgTWF0aC5yb3VuZCh0aGlzLl9zYW1wbGVSYXRlIC8gaW50ZXJ2YWxIeikpOwogICAgICB9CiAgICAgIC8vIFJlc2V0IHBhY2luZyBzbyB0aGUgbmV4dCByZXBvcnQgYWxpZ25zIHdpdGggbmV3IGludGVydmFsCiAgICAgIHRoaXMuX2xhc3RNZXRyaWNzU2VudEF0RnJhbWUgPSB0aGlzLl9mcmFtZXNQcm9jZXNzZWQ7CiAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBOZXcgYXVkaW8gZGF0YSBoYXMgYXJyaXZlZC4KICAgIGlmICh0eXBlID09PSAiYXVkaW9EYXRhIiAmJiBkYXRhIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHsKICAgICAgdGhpcy5fbm9Nb3JlRGF0YVJlY2VpdmVkID0gZmFsc2U7CiAgICAgIC8vIElmIHdlIHdlcmUgaWRsZSwgdGhpcyBuZXcgZGF0YSBraWNrcyBvZmYgdGhlIHBsYXliYWNrLgogICAgICBpZiAodGhpcy5fc3RhdGUgPT09IFBsYXliYWNrV29ya2xldC5GU00uSURMRSkgewogICAgICAgIHRoaXMuX3N0YXRlID0gUGxheWJhY2tXb3JrbGV0LkZTTS5QTEFZSU5HOwogICAgICAgIHRoaXMucG9ydC5wb3N0TWVzc2FnZSh7IHR5cGU6ICJwbGF5YmFjay1zdGFydGVkIiB9KTsKICAgICAgfQoKICAgICAgLy8gV2Ugb25seSBxdWV1ZSBkYXRhIGlmIHdlIGFyZSBpbiB0aGUgUExBWUlORyBzdGF0ZS4gVGhpcyBwcmV2ZW50cwogICAgICAvLyBkYXRhIGZyb20gYSBwcmV2aW91cywgaW50ZXJydXB0ZWQgc3RyZWFtIGZyb20gbGluZ2VyaW5nLgogICAgICBpZiAodGhpcy5fc3RhdGUgPT09IFBsYXliYWNrV29ya2xldC5GU00uUExBWUlORykgewogICAgICAgIC8vIFN0b3JlIGFzIEludDE2QXJyYXkgdmlldyB0byBhdm9pZCBjb25zdHJ1Y3RpbmcgaXQgaW4gcHJvY2VzcygpCiAgICAgICAgdGhpcy5fYnVmZmVyUXVldWUucHVzaChuZXcgSW50MTZBcnJheShkYXRhKSk7CiAgICAgICAgdGhpcy5fc2lsZW5jZUZyYW1lc0NvdW50ID0gMDsgLy8gUmVzZXQgc2lsZW5jZSBjb3VudGVyIG9uIG5ldyBkYXRhCiAgICAgIH0KICAgIH0KICB9CgogIHByb2Nlc3MoaW5wdXRzLCBvdXRwdXRzLCBwYXJhbWV0ZXJzKSB7CiAgICBjb25zdCBvdXRwdXRDaGFubmVsID0gb3V0cHV0c1swXT8uWzBdOwogICAgaWYgKCFvdXRwdXRDaGFubmVsKSB7CiAgICAgIHJldHVybiB0cnVlOyAvLyBLZWVwIGFsaXZlIGV2ZW4gaWYgb3V0cHV0IGlzIHRlbXBvcmFyaWx5IGRpc2Nvbm5lY3RlZAogICAgfQoKICAgIC8vIElmIHdlIGFyZSBub3QgcGxheWluZywganVzdCBvdXRwdXQgc2lsZW5jZSBhbmQgd2FpdC4KICAgIGlmICh0aGlzLl9zdGF0ZSAhPT0gUGxheWJhY2tXb3JrbGV0LkZTTS5QTEFZSU5HKSB7CiAgICAgIG91dHB1dENoYW5uZWwuZmlsbCgwKTsKICAgICAgcmV0dXJuIHRydWU7IC8vIEFsd2F5cyByZXR1cm4gdHJ1ZSB0byBrZWVwIHRoZSBwcm9jZXNzb3IgYWxpdmUKICAgIH0KCiAgICAvLyBDb3JlIFBMQVlJTkcgTG9naWMKICAgIGNvbnN0IGJsb2NrU2l6ZSA9IG91dHB1dENoYW5uZWwubGVuZ3RoOwogICAgbGV0IHNhbXBsZXNDb3BpZWQgPSAwOwoKICAgIHdoaWxlIChzYW1wbGVzQ29waWVkIDwgYmxvY2tTaXplKSB7CiAgICAgIGlmICghdGhpcy5fY3VycmVudENodW5rIHx8IHRoaXMuX2N1cnJlbnRDaHVua09mZnNldCA+PSB0aGlzLl9jdXJyZW50Q2h1bmsubGVuZ3RoKSB7CiAgICAgICAgaWYgKHRoaXMuX2J1ZmZlclF1ZXVlLmxlbmd0aCA+IDApIHsKICAgICAgICAgIHRoaXMuX2N1cnJlbnRDaHVuayA9IHRoaXMuX2J1ZmZlclF1ZXVlLnNoaWZ0KCk7CiAgICAgICAgICB0aGlzLl9jdXJyZW50Q2h1bmtPZmZzZXQgPSAwOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAvLyBCdWZmZXIgaXMgZW1wdHkuIENoZWNrIGZvciBlbmQgY29uZGl0aW9ucy4KICAgICAgICAgIGNvbnN0IGlzVGltZWRPdXQgPSB0aGlzLl9zaWxlbmNlRnJhbWVzQ291bnQgPiB0aGlzLl9zaWxlbmNlVGhyZXNob2xkQmxvY2tzOwoKICAgICAgICAgIGlmICh0aGlzLl9ub01vcmVEYXRhUmVjZWl2ZWQgfHwgaXNUaW1lZE91dCkgewogICAgICAgICAgICAvLyBFTkQgT0YgUExBWUJBQ0s6IEVpdGhlciBleHBsaWNpdGx5IHNpZ25hbGVkIG9yIHRpbWVkIG91dC4KICAgICAgICAgICAgaWYgKCF0aGlzLl9oYXNTZW50RW5kZWQpIHsKICAgICAgICAgICAgICB0aGlzLnBvcnQucG9zdE1lc3NhZ2UoeyB0eXBlOiAicGxheWJhY2stZW5kZWQiIH0pOwogICAgICAgICAgICAgIHRoaXMuX2hhc1NlbnRFbmRlZCA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gU2VuZCBmaW5hbCBtZXRyaWNzIHNob3dpbmcgY2xlYXJlZCBzdGF0ZQogICAgICAgICAgICBpZiAodGhpcy5fbWV0cmljc0VuYWJsZWQpIHsKICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgdGhpcy5wb3J0LnBvc3RNZXNzYWdlKHsKICAgICAgICAgICAgICAgICAgdHlwZTogIm1ldHJpY3MiLAogICAgICAgICAgICAgICAgICBkYXRhOiB7CiAgICAgICAgICAgICAgICAgICAgc3RhdGU6IFBsYXliYWNrV29ya2xldC5GU00uSURMRSwKICAgICAgICAgICAgICAgICAgICBxdWV1ZWRTYW1wbGVzOiAwLAogICAgICAgICAgICAgICAgICAgIHF1ZXVlZE1zOiAwLAogICAgICAgICAgICAgICAgICAgIG1heFF1ZXVlZE1zOiBNYXRoLnJvdW5kKCh0aGlzLl9tYXhRdWV1ZVNhbXBsZXMgLyB0aGlzLl9zYW1wbGVSYXRlKSAqIDEwMDApLAogICAgICAgICAgICAgICAgICAgIHVuZGVycnVuQmxvY2tzOiB0aGlzLl91bmRlcnJ1bkJsb2NrcywKICAgICAgICAgICAgICAgICAgICBmcmFtZXNQcm9jZXNzZWQ6IHRoaXMuX2ZyYW1lc1Byb2Nlc3NlZAogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICB9IGNhdGNoIChfKSB7IH0KICAgICAgICAgICAgfQogICAgICAgICAgICB0aGlzLnJlc2V0KCk7IC8vIFJlc2V0IHRvIElETEUgc3RhdGUgZm9yIHJldXNlCiAgICAgICAgICAgIGJyZWFrOyAvLyBFeGl0IHdoaWxlIGxvb3AKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8vIEJVRkZFUiBVTkRFUlJVTiAoTEFHKTogUGxheSBzaWxlbmNlIGFuZCB3YWl0IGZvciBtb3JlIGRhdGEuCiAgICAgICAgICAgIHRoaXMuX3NpbGVuY2VGcmFtZXNDb3VudCsrOwogICAgICAgICAgICBpZiAodGhpcy5fbWV0cmljc0VuYWJsZWQpIHRoaXMuX3VuZGVycnVuQmxvY2tzKys7CiAgICAgICAgICAgIGJyZWFrOyAvLyBFeGl0IHdoaWxlIGxvb3AKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KCiAgICAgIC8vIElmIHdlIGhhdmUgYSBjaHVuayAoY291bGQgYmUgYSBuZXcgb25lIGZyb20gdGhlIGxvZ2ljIGFib3ZlKSwgcHJvY2VzcyBpdC4KICAgICAgaWYgKHRoaXMuX2N1cnJlbnRDaHVuaykgewogICAgICAgIGNvbnN0IHNhbXBsZXNUb0NvcHkgPSBNYXRoLm1pbigKICAgICAgICAgIGJsb2NrU2l6ZSAtIHNhbXBsZXNDb3BpZWQsCiAgICAgICAgICB0aGlzLl9jdXJyZW50Q2h1bmsubGVuZ3RoIC0gdGhpcy5fY3VycmVudENodW5rT2Zmc2V0CiAgICAgICAgKTsKICAgICAgICAvLyBEaXJlY3RseSB3cml0ZSB0byBvdXRwdXRDaGFubmVsIHRvIGF2b2lkIGV4dHJhIGNvcHkKICAgICAgICBjb25zdCBzcmMgPSB0aGlzLl9jdXJyZW50Q2h1bms7CiAgICAgICAgY29uc3QgYmFzZVNyYyA9IHRoaXMuX2N1cnJlbnRDaHVua09mZnNldDsKICAgICAgICBjb25zdCBiYXNlRHN0ID0gc2FtcGxlc0NvcGllZDsKICAgICAgICBjb25zdCBzY2FsZSA9IHRoaXMuX3NjYWxlOwogICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2FtcGxlc1RvQ29weTsgaSsrKSB7CiAgICAgICAgICBvdXRwdXRDaGFubmVsW2Jhc2VEc3QgKyBpXSA9IHNyY1tiYXNlU3JjICsgaV0gKiBzY2FsZTsKICAgICAgICB9CgogICAgICAgIHRoaXMuX2N1cnJlbnRDaHVua09mZnNldCArPSBzYW1wbGVzVG9Db3B5OwogICAgICAgIHNhbXBsZXNDb3BpZWQgKz0gc2FtcGxlc1RvQ29weTsKICAgICAgfQogICAgfQoKICAgIC8vIFplcm8tZmlsbCB0aGUgcmVtYWluZGVyLCBpZiBhbnksIG9uY2UgcGVyIGJsb2NrCiAgICBpZiAoc2FtcGxlc0NvcGllZCA8IGJsb2NrU2l6ZSkgewogICAgICBvdXRwdXRDaGFubmVsLmZpbGwoMCwgc2FtcGxlc0NvcGllZCk7CiAgICB9CgogICAgLy8gVXBkYXRlIG1ldHJpY3MgKG9wdGlvbmFsKQogICAgaWYgKHRoaXMuX21ldHJpY3NFbmFibGVkKSB7CiAgICAgIHRoaXMuX2ZyYW1lc1Byb2Nlc3NlZCArPSBibG9ja1NpemU7CgogICAgICAvLyBUcmFjayBxdWV1ZSBkZXB0aCBpbiBzYW1wbGVzIChhcHByb3hpbWF0ZSkKICAgICAgbGV0IHF1ZXVlZFNhbXBsZXMgPSAwOwogICAgICBpZiAodGhpcy5fY3VycmVudENodW5rKSBxdWV1ZWRTYW1wbGVzICs9IE1hdGgubWF4KDAsIHRoaXMuX2N1cnJlbnRDaHVuay5sZW5ndGggLSB0aGlzLl9jdXJyZW50Q2h1bmtPZmZzZXQpOwogICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX2J1ZmZlclF1ZXVlLmxlbmd0aDsgaSsrKSBxdWV1ZWRTYW1wbGVzICs9IHRoaXMuX2J1ZmZlclF1ZXVlW2ldLmxlbmd0aDsKICAgICAgaWYgKHF1ZXVlZFNhbXBsZXMgPiB0aGlzLl9tYXhRdWV1ZVNhbXBsZXMpIHRoaXMuX21heFF1ZXVlU2FtcGxlcyA9IHF1ZXVlZFNhbXBsZXM7CgogICAgICAvLyBQZXJpb2RpY2FsbHkgc2VuZCBtZXRyaWNzIHRvIG1haW4gdGhyZWFkCiAgICAgIGlmICh0aGlzLl9mcmFtZXNQcm9jZXNzZWQgLSB0aGlzLl9sYXN0TWV0cmljc1NlbnRBdEZyYW1lID49IHRoaXMuX21ldHJpY3NJbnRlcnZhbEZyYW1lcykgewogICAgICAgIHRoaXMuX2xhc3RNZXRyaWNzU2VudEF0RnJhbWUgPSB0aGlzLl9mcmFtZXNQcm9jZXNzZWQ7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIHRoaXMucG9ydC5wb3N0TWVzc2FnZSh7CiAgICAgICAgICAgIHR5cGU6ICJtZXRyaWNzIiwKICAgICAgICAgICAgZGF0YTogewogICAgICAgICAgICAgIHN0YXRlOiB0aGlzLl9zdGF0ZSwKICAgICAgICAgICAgICBxdWV1ZWRTYW1wbGVzLAogICAgICAgICAgICAgIHF1ZXVlZE1zOiBNYXRoLnJvdW5kKChxdWV1ZWRTYW1wbGVzIC8gdGhpcy5fc2FtcGxlUmF0ZSkgKiAxMDAwKSwKICAgICAgICAgICAgICBtYXhRdWV1ZWRNczogTWF0aC5yb3VuZCgodGhpcy5fbWF4UXVldWVTYW1wbGVzIC8gdGhpcy5fc2FtcGxlUmF0ZSkgKiAxMDAwKSwKICAgICAgICAgICAgICB1bmRlcnJ1bkJsb2NrczogdGhpcy5fdW5kZXJydW5CbG9ja3MsCiAgICAgICAgICAgICAgZnJhbWVzUHJvY2Vzc2VkOiB0aGlzLl9mcmFtZXNQcm9jZXNzZWQKICAgICAgICAgICAgfQogICAgICAgICAgfSk7CiAgICAgICAgfSBjYXRjaCAoXykgeyB9CiAgICAgICAgLy8gRG9uJ3QgcmVzZXQgbWF4IHRyYWNrZXIgLSBrZWVwIHNlc3Npb24gcGVhayB1bnRpbCBpZGxlCiAgICAgIH0KICAgIH0KCiAgICAvLyBBTFdBWVMgcmV0dXJuIHRydWUgdG8ga2VlcCB0aGUgcHJvY2Vzc29yIGFsaXZlIGZvciByZXVzZS4KICAgIHJldHVybiB0cnVlOwogIH0KfQoKcmVnaXN0ZXJQcm9jZXNzb3IoInBsYXliYWNrLXdvcmtsZXQiLCBQbGF5YmFja1dvcmtsZXQpOwo=", import.meta.url), Ue = {
|
|
2627
|
+
en: ot,
|
|
2628
|
+
de: at,
|
|
2629
|
+
fr: lt,
|
|
2630
|
+
fi: ct,
|
|
2631
|
+
lt: dt
|
|
2632
|
+
}, te = new y.Quaternion(), Q = new y.Euler(), Re = new y.Vector3(), Ie = new y.Vector3(), We = new y.Box3();
|
|
2633
2633
|
new y.Matrix4();
|
|
2634
2634
|
new y.Matrix4();
|
|
2635
2635
|
new y.Vector3();
|
|
2636
2636
|
new y.Vector3(0, 0, 1);
|
|
2637
|
-
const
|
|
2637
|
+
const pt = new y.Vector3(1, 0, 0);
|
|
2638
2638
|
new y.Vector3(0, 1, 0);
|
|
2639
2639
|
new y.Vector3(0, 0, 1);
|
|
2640
2640
|
class Be {
|
|
@@ -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: {
|
|
@@ -3569,15 +3569,15 @@ class Be {
|
|
|
3569
3569
|
"RightArm.scale": { x: 0, y: 0, z: 0 }
|
|
3570
3570
|
}
|
|
3571
3571
|
}, ["Left", "Right"].forEach((l) => {
|
|
3572
|
-
["Leg", "UpLeg", "Arm", "ForeArm", "Hand"].forEach((
|
|
3573
|
-
this.poseDelta.props[l +
|
|
3574
|
-
}), ["HandThumb", "HandIndex", "HandMiddle", "HandRing", "HandPinky"].forEach((
|
|
3575
|
-
this.poseDelta.props[l +
|
|
3572
|
+
["Leg", "UpLeg", "Arm", "ForeArm", "Hand"].forEach((c) => {
|
|
3573
|
+
this.poseDelta.props[l + c + ".quaternion"] = { x: 0, y: 0, z: 0 };
|
|
3574
|
+
}), ["HandThumb", "HandIndex", "HandMiddle", "HandRing", "HandPinky"].forEach((c) => {
|
|
3575
|
+
this.poseDelta.props[l + c + "1.quaternion"] = { x: 0, y: 0, z: 0 }, this.poseDelta.props[l + c + "2.quaternion"] = { x: 0, y: 0, z: 0 }, this.poseDelta.props[l + c + "3.quaternion"] = { x: 0, y: 0, z: 0 };
|
|
3576
3576
|
});
|
|
3577
3577
|
});
|
|
3578
3578
|
const n = /* @__PURE__ */ new Set();
|
|
3579
3579
|
Object.values(this.poseTemplates).forEach((l) => {
|
|
3580
|
-
Object.keys(this.propsToThreeObjects(l.props)).forEach((
|
|
3580
|
+
Object.keys(this.propsToThreeObjects(l.props)).forEach((c) => n.add(c));
|
|
3581
3581
|
}), Object.keys(this.poseDelta.props).forEach((l) => {
|
|
3582
3582
|
n.add(l);
|
|
3583
3583
|
}), this.posePropNames = [...n], this.poseName = "side", this.poseWeightOnLeft = !0, this.gesture = null, this.poseCurrentTemplate = this.poseTemplates[this.poseName], this.poseStraight = this.propsToThreeObjects(this.poseTemplates.straight.props), this.poseBase = this.poseFactory(this.poseCurrentTemplate), this.poseTarget = this.poseFactory(this.poseCurrentTemplate), this.poseAvatar = null, this.avatarHeight = 1.7, this.animTemplateEyes = {
|
|
@@ -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
|
|
4089
|
+
l.compileEquirectangularShader(), this.scene.environment = l.fromScene(new _e()).texture, this.resizeobserver = new ResizeObserver(this.onResize.bind(this)), this.resizeobserver.observe(this.nodeAvatar), this.controls = new Ye(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 = {
|
|
@@ -4101,17 +4101,17 @@ class Be {
|
|
|
4101
4101
|
RightHand: "RightForeArm",
|
|
4102
4102
|
RightHandMiddle1: "RightHand"
|
|
4103
4103
|
}, o = [];
|
|
4104
|
-
Object.entries(s).forEach((l,
|
|
4104
|
+
Object.entries(s).forEach((l, c) => {
|
|
4105
4105
|
const r = new y.Bone();
|
|
4106
4106
|
r.name = l[0], l[1] ? this.ikMesh.getObjectByName(l[1]).add(r) : this.ikMesh.add(r), o.push(r);
|
|
4107
|
-
}), this.ikMesh.bind(new y.Skeleton(o)), this.dynamicbones = new
|
|
4107
|
+
}), this.ikMesh.bind(new y.Skeleton(o)), this.dynamicbones = new tt(), this.isStreaming = !1, this.streamWorkletNode = null, this.streamAudioStartTime = null, this.streamWaitForAudioChunks = !0, this.streamLipsyncLang = null, this.streamLipsyncType = "visemes", this.streamLipsyncQueue = [];
|
|
4108
4108
|
}
|
|
4109
4109
|
/**
|
|
4110
4110
|
* Helper that re/creates the audio context and the other nodes.
|
|
4111
4111
|
* @param {number} sampleRate
|
|
4112
4112
|
*/
|
|
4113
4113
|
initAudioGraph(t = null) {
|
|
4114
|
-
if (this.audioCtx && this.audioCtx.state !== "closed" && this.audioCtx.close(), t ? this.audioCtx = new AudioContext({ sampleRate: t }) : this.audioCtx = new AudioContext(), this.audioSpeechSource = this.audioCtx.createBufferSource(), this.audioBackgroundSource = this.audioCtx.createBufferSource(), this.audioBackgroundGainNode = this.audioCtx.createGain(), this.audioSpeechGainNode = this.audioCtx.createGain(), this.audioStreamGainNode = this.audioCtx.createGain(), this.audioAnalyzerNode = this.audioCtx.createAnalyser(), this.audioAnalyzerNode.fftSize = 256, this.audioAnalyzerNode.smoothingTimeConstant = 0.1, this.audioAnalyzerNode.minDecibels = -70, this.audioAnalyzerNode.maxDecibels = -10, this.audioAnalyzer = new
|
|
4114
|
+
if (this.audioCtx && this.audioCtx.state !== "closed" && this.audioCtx.close(), t ? this.audioCtx = new AudioContext({ sampleRate: t }) : this.audioCtx = new AudioContext(), this.audioSpeechSource = this.audioCtx.createBufferSource(), this.audioBackgroundSource = this.audioCtx.createBufferSource(), this.audioBackgroundGainNode = this.audioCtx.createGain(), this.audioSpeechGainNode = this.audioCtx.createGain(), this.audioStreamGainNode = this.audioCtx.createGain(), this.audioAnalyzerNode = this.audioCtx.createAnalyser(), this.audioAnalyzerNode.fftSize = 256, this.audioAnalyzerNode.smoothingTimeConstant = 0.1, this.audioAnalyzerNode.minDecibels = -70, this.audioAnalyzerNode.maxDecibels = -10, this.audioAnalyzer = new nt(this.audioCtx), this.audioReverbNode = this.audioCtx.createConvolver(), this.audioBackgroundGainNode.connect(this.audioReverbNode), this.audioAnalyzerNode.connect(this.audioSpeechGainNode), this.audioSpeechGainNode.connect(this.audioReverbNode), this.audioStreamGainNode.connect(this.audioReverbNode), this.audioReverbNode.connect(this.audioCtx.destination), this.setReverb(this.currentReverb || null), this.setMixerGain(
|
|
4115
4115
|
this.opt.mixerGainSpeech,
|
|
4116
4116
|
this.opt.mixerGainBackground
|
|
4117
4117
|
), this.workletLoaded = !1, this.streamWorkletNode) {
|
|
@@ -4150,9 +4150,9 @@ class Be {
|
|
|
4150
4150
|
let e = 3 * t.length / 4;
|
|
4151
4151
|
t[t.length - 1] === "=" && (e--, t[t.length - 2] === "=" && e--);
|
|
4152
4152
|
const n = new ArrayBuffer(e), i = new Uint8Array(n);
|
|
4153
|
-
let s, o = 0, l,
|
|
4153
|
+
let s, o = 0, l, c, r, u;
|
|
4154
4154
|
for (s = 0; s < t.length; s += 4)
|
|
4155
|
-
l = this.b64Lookup[t.charCodeAt(s)],
|
|
4155
|
+
l = this.b64Lookup[t.charCodeAt(s)], c = this.b64Lookup[t.charCodeAt(s + 1)], r = this.b64Lookup[t.charCodeAt(s + 2)], u = this.b64Lookup[t.charCodeAt(s + 3)], i[o++] = l << 2 | c >> 4, i[o++] = (c & 15) << 4 | r >> 2, i[o++] = (r & 3) << 6 | u & 63;
|
|
4156
4156
|
return n;
|
|
4157
4157
|
}
|
|
4158
4158
|
/**
|
|
@@ -4193,8 +4193,8 @@ class Be {
|
|
|
4193
4193
|
const e = {};
|
|
4194
4194
|
for (let [n, i] of Object.entries(t)) {
|
|
4195
4195
|
const s = n.split(".");
|
|
4196
|
-
let o = Array.isArray(i.x) ? this.gaussianRandom(...i.x) : i.x, l = Array.isArray(i.y) ? this.gaussianRandom(...i.y) : i.y,
|
|
4197
|
-
s[1] === "position" || s[1] === "scale" ? e[n] = new y.Vector3(o, l,
|
|
4196
|
+
let o = Array.isArray(i.x) ? this.gaussianRandom(...i.x) : i.x, l = Array.isArray(i.y) ? this.gaussianRandom(...i.y) : i.y, c = Array.isArray(i.z) ? this.gaussianRandom(...i.z) : i.z;
|
|
4197
|
+
s[1] === "position" || s[1] === "scale" ? e[n] = new y.Vector3(o, l, c) : s[1] === "rotation" ? (n = s[0] + ".quaternion", e[n] = new y.Quaternion().setFromEuler(new y.Euler(o, l, c, "XYZ")).normalize()) : s[1] === "quaternion" && (e[n] = new y.Quaternion(o, l, c, i.w).normalize());
|
|
4198
4198
|
}
|
|
4199
4199
|
return e;
|
|
4200
4200
|
}
|
|
@@ -4222,23 +4222,23 @@ class Be {
|
|
|
4222
4222
|
t.forEach((s) => {
|
|
4223
4223
|
if (!i && s.morphTargetDictionary.hasOwnProperty(e)) return;
|
|
4224
4224
|
const o = s.geometry;
|
|
4225
|
-
let l = null,
|
|
4225
|
+
let l = null, c = null;
|
|
4226
4226
|
for (const [r, u] of Object.entries(n))
|
|
4227
4227
|
if (s.morphTargetDictionary.hasOwnProperty(r)) {
|
|
4228
|
-
const a = s.morphTargetDictionary[r], d = o.morphAttributes.position[a],
|
|
4229
|
-
l || (l = new y.Float32BufferAttribute(d.count * 3, 3),
|
|
4228
|
+
const a = s.morphTargetDictionary[r], d = o.morphAttributes.position[a], h = o.morphAttributes.normal?.[a];
|
|
4229
|
+
l || (l = new y.Float32BufferAttribute(d.count * 3, 3), h && (c = new y.Float32BufferAttribute(d.count * 3, 3)));
|
|
4230
4230
|
for (let g = 0; g < d.count; g++) {
|
|
4231
|
-
const b = l.getX(g) + d.getX(g) * u,
|
|
4232
|
-
l.setXYZ(g, b,
|
|
4231
|
+
const b = l.getX(g) + d.getX(g) * u, f = l.getY(g) + d.getY(g) * u, w = l.getZ(g) + d.getZ(g) * u;
|
|
4232
|
+
l.setXYZ(g, b, f, w);
|
|
4233
4233
|
}
|
|
4234
|
-
if (
|
|
4234
|
+
if (h)
|
|
4235
4235
|
for (let g = 0; g < d.count; g++) {
|
|
4236
|
-
const b =
|
|
4237
|
-
|
|
4236
|
+
const b = c.getX(g) + h.getX(g) * u, f = c.getY(g) + h.getY(g) * u, w = c.getZ(g) + h.getZ(g) * u;
|
|
4237
|
+
c.setXYZ(g, b, f, w);
|
|
4238
4238
|
}
|
|
4239
4239
|
}
|
|
4240
4240
|
if (l) {
|
|
4241
|
-
o.morphAttributes.position.push(l),
|
|
4241
|
+
o.morphAttributes.position.push(l), c && o.morphAttributes.normal.push(c);
|
|
4242
4242
|
const r = o.morphAttributes.position.length - 1;
|
|
4243
4243
|
s.morphTargetInfluences[r] = 0, s.morphTargetDictionary[e] = r;
|
|
4244
4244
|
}
|
|
@@ -4252,9 +4252,9 @@ 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 Qe();
|
|
4256
4256
|
if (this.dracoEnabled) {
|
|
4257
|
-
const r = new
|
|
4257
|
+
const r = new qe();
|
|
4258
4258
|
r.setDecoderPath(this.dracoDecoderPath), n.setDRACOLoader(r);
|
|
4259
4259
|
}
|
|
4260
4260
|
let i = await n.loadAsync(t.url, e);
|
|
@@ -4314,8 +4314,8 @@ class Be {
|
|
|
4314
4314
|
console.error("Dynamic bones setup failed: " + r);
|
|
4315
4315
|
}
|
|
4316
4316
|
this.objectLeftToeBase = this.armature.getObjectByName("LeftToeBase"), this.objectRightToeBase = this.armature.getObjectByName("RightToeBase"), this.objectLeftEye = this.armature.getObjectByName("LeftEye"), this.objectRightEye = this.armature.getObjectByName("RightEye"), this.objectLeftArm = this.armature.getObjectByName("LeftArm"), this.objectRightArm = this.armature.getObjectByName("RightArm"), this.objectHips = this.armature.getObjectByName("Hips"), this.objectHead = this.armature.getObjectByName("Head"), this.objectNeck = this.armature.getObjectByName("Neck");
|
|
4317
|
-
const
|
|
4318
|
-
this.objectLeftEye.getWorldPosition(
|
|
4317
|
+
const c = new y.Vector3();
|
|
4318
|
+
this.objectLeftEye.getWorldPosition(c), this.avatarHeight = c.y + 0.2, this.viewName || this.setView(this.opt.cameraView), this.setMood(this.avatar.avatarMood || this.moodName || this.opt.avatarMood), this.avatar.body === "M" && this.poseTemplates.wide && (this.poseName = "wide", this.setPoseFromTemplate(this.poseTemplates.wide, 0), console.log("Set initial male-appropriate pose: wide")), this.initializeFBXAnimationLoader(), this.bodyMovement && this.bodyMovement !== "idle" && this.applyBodyMovementAnimation(), this.start();
|
|
4319
4319
|
}
|
|
4320
4320
|
/**
|
|
4321
4321
|
* Get view names.
|
|
@@ -4343,8 +4343,8 @@ class Be {
|
|
|
4343
4343
|
return;
|
|
4344
4344
|
}
|
|
4345
4345
|
if (this.viewName = t || this.viewName, e = e || {}, this.isAvatarOnly) return;
|
|
4346
|
-
const n = e.hasOwnProperty("cameraX") ? e.cameraX : this.opt.cameraX, i = e.hasOwnProperty("cameraY") ? e.cameraY : this.opt.cameraY, s = e.hasOwnProperty("cameraDistance") ? e.cameraDistance : this.opt.cameraDistance, o = e.hasOwnProperty("cameraRotateX") ? e.cameraRotateX : this.opt.cameraRotateX, l = e.hasOwnProperty("cameraRotateY") ? e.cameraRotateY : this.opt.cameraRotateY,
|
|
4347
|
-
let r = -n * Math.tan(
|
|
4346
|
+
const n = e.hasOwnProperty("cameraX") ? e.cameraX : this.opt.cameraX, i = e.hasOwnProperty("cameraY") ? e.cameraY : this.opt.cameraY, s = e.hasOwnProperty("cameraDistance") ? e.cameraDistance : this.opt.cameraDistance, o = e.hasOwnProperty("cameraRotateX") ? e.cameraRotateX : this.opt.cameraRotateX, l = e.hasOwnProperty("cameraRotateY") ? e.cameraRotateY : this.opt.cameraRotateY, c = this.camera.fov * (Math.PI / 180);
|
|
4347
|
+
let r = -n * Math.tan(c / 2), u = (1 - i) * Math.tan(c / 2), a = s;
|
|
4348
4348
|
switch (this.viewName) {
|
|
4349
4349
|
case "head":
|
|
4350
4350
|
a += 2, u = u * a + 4 * this.avatarHeight / 5;
|
|
@@ -4436,9 +4436,9 @@ class Be {
|
|
|
4436
4436
|
updatePoseDelta() {
|
|
4437
4437
|
for (const [t, e] of Object.entries(this.poseDelta.props)) {
|
|
4438
4438
|
if (e.x === 0 && e.y === 0 && e.z === 0) continue;
|
|
4439
|
-
|
|
4439
|
+
Q.set(e.x, e.y, e.z);
|
|
4440
4440
|
const n = this.poseAvatar.props[t];
|
|
4441
|
-
n.isQuaternion ? (
|
|
4441
|
+
n.isQuaternion ? (te.setFromEuler(Q), n.multiply(te)) : n.isVector3 && n.add(Q);
|
|
4442
4442
|
}
|
|
4443
4443
|
}
|
|
4444
4444
|
/**
|
|
@@ -4498,8 +4498,8 @@ class Be {
|
|
|
4498
4498
|
});
|
|
4499
4499
|
break;
|
|
4500
4500
|
case "chestInhale":
|
|
4501
|
-
const l = n.applied / 20,
|
|
4502
|
-
this.poseDelta.props["Spine1.scale"] =
|
|
4501
|
+
const l = n.applied / 20, c = { x: l, y: l / 2, z: 3 * l }, r = { x: 1 / (1 + l) - 1, y: 1 / (1 + l / 2) - 1, z: 1 / (1 + 3 * l) - 1 };
|
|
4502
|
+
this.poseDelta.props["Spine1.scale"] = c, this.poseDelta.props["Neck.scale"] = r, this.poseDelta.props["LeftArm.scale"] = r, this.poseDelta.props["RightArm.scale"] = r;
|
|
4503
4503
|
break;
|
|
4504
4504
|
default:
|
|
4505
4505
|
for (let u = 0, a = n.ms.length; u < a; u++)
|
|
@@ -4518,8 +4518,8 @@ class Be {
|
|
|
4518
4518
|
return Object.entries(t).forEach((i, s) => {
|
|
4519
4519
|
const o = i[0].split(".");
|
|
4520
4520
|
if (o[1] === "position" || o[1] === "rotation" || o[1] === "quaternion") {
|
|
4521
|
-
const l = o[1] === "quaternion" ? o[0] + ".rotation" : i[0],
|
|
4522
|
-
n += (s ? ", " : "") + "'" + l + "':{", n += "x:" + Math.round(
|
|
4521
|
+
const l = o[1] === "quaternion" ? o[0] + ".rotation" : i[0], c = i[1].isQuaternion ? new y.Euler().setFromQuaternion(i[1]) : i[1];
|
|
4522
|
+
n += (s ? ", " : "") + "'" + l + "':{", n += "x:" + Math.round(c.x * e) / e, n += ", y:" + Math.round(c.y * e) / e, n += ", z:" + Math.round(c.z * e) / e, n += "}";
|
|
4523
4523
|
}
|
|
4524
4524
|
}), n += "}", n;
|
|
4525
4525
|
}
|
|
@@ -4589,8 +4589,8 @@ class Be {
|
|
|
4589
4589
|
if (n ? (this.poseCurrentTemplate = this.poseTemplates.oneknee, setTimeout(() => {
|
|
4590
4590
|
this.setPoseFromTemplate(t, e);
|
|
4591
4591
|
}, o)) : this.poseCurrentTemplate = t || this.poseCurrentTemplate, this.poseTarget = this.poseFactory(this.poseCurrentTemplate, o), this.poseWeightOnLeft = !0, (!i && !s || i && s) && (this.poseTarget.props = this.mirrorPose(this.poseTarget.props), this.poseWeightOnLeft = !this.poseWeightOnLeft), this.gesture)
|
|
4592
|
-
for (let [l,
|
|
4593
|
-
this.poseTarget.props.hasOwnProperty(l) && (this.poseTarget.props[l].copy(
|
|
4592
|
+
for (let [l, c] of Object.entries(this.gesture))
|
|
4593
|
+
this.poseTarget.props.hasOwnProperty(l) && (this.poseTarget.props[l].copy(c), this.poseTarget.props[l].t = c.t, this.poseTarget.props[l].d = c.d);
|
|
4594
4594
|
Object.keys(this.poseDelta.props).forEach((l) => {
|
|
4595
4595
|
this.poseTarget.props.hasOwnProperty(l) || (this.poseTarget.props[l] = this.poseBase.props[l].clone(), this.poseTarget.props[l].t = this.animClock, this.poseTarget.props[l].d = o);
|
|
4596
4596
|
});
|
|
@@ -5026,8 +5026,8 @@ class Be {
|
|
|
5026
5026
|
const u = Math.random();
|
|
5027
5027
|
let a = 0;
|
|
5028
5028
|
for (let d = 0; d < l.alt.length; d++) {
|
|
5029
|
-
let
|
|
5030
|
-
if (a +=
|
|
5029
|
+
let h = this.valueFn(l.alt[d].p);
|
|
5030
|
+
if (a += h === void 0 ? (1 - a) / (l.alt.length - 1 - d) : h, u < a) {
|
|
5031
5031
|
r = l.alt[d];
|
|
5032
5032
|
break;
|
|
5033
5033
|
}
|
|
@@ -5037,8 +5037,8 @@ class Be {
|
|
|
5037
5037
|
continue;
|
|
5038
5038
|
} else
|
|
5039
5039
|
break;
|
|
5040
|
-
let
|
|
5041
|
-
if (Array.isArray(
|
|
5040
|
+
let c = this.valueFn(l.delay) || 0;
|
|
5041
|
+
if (Array.isArray(c) && (c = this.gaussianRandom(...c)), l.hasOwnProperty("dt"))
|
|
5042
5042
|
l.dt.forEach((r, u) => {
|
|
5043
5043
|
let a = this.valueFn(r);
|
|
5044
5044
|
Array.isArray(a) && (a = this.gaussianRandom(...a)), o.ts[u + 1] = o.ts[u] + a;
|
|
@@ -5047,10 +5047,10 @@ class Be {
|
|
|
5047
5047
|
let r = Object.values(l.vs).reduce((u, a) => a.length > u ? a.length : u, 0);
|
|
5048
5048
|
o.ts = Array(r + 1).fill(0);
|
|
5049
5049
|
}
|
|
5050
|
-
s ? o.ts = o.ts.map((r) =>
|
|
5050
|
+
s ? o.ts = o.ts.map((r) => c + r * n) : o.ts = o.ts.map((r) => this.animClock + c + r * n), l.vs && l.vs.pose && console.log("Pose being selected from vs.pose:", l.vs.pose, "for avatar body:", this.avatar?.body);
|
|
5051
5051
|
for (let [r, u] of Object.entries(l.vs)) {
|
|
5052
|
-
const a = this.getBaselineValue(r), d = u.map((
|
|
5053
|
-
r === "eyesRotateY" ? (o.vs.eyeLookOutLeft = [null, ...d.map((
|
|
5052
|
+
const a = this.getBaselineValue(r), d = u.map((h) => (h = this.valueFn(h), h === null ? null : typeof h == "function" ? h : typeof h == "string" || h instanceof String ? r === "pose" && this.avatar && this.avatar.body === "M" && (h === "hip" || h === "side") ? (console.log("Intercepting pose", h, "in animation factory, overriding to wide for male avatar"), "wide") : h.slice() : Array.isArray(h) ? r === "gesture" ? h.slice() : (a === void 0 ? 0 : a) + i * this.gaussianRandom(...h) : typeof h == "boolean" ? h : h instanceof Object && h.constructor === Object ? Object.assign({}, h) : (a === void 0 ? 0 : a) + i * h));
|
|
5053
|
+
r === "eyesRotateY" ? (o.vs.eyeLookOutLeft = [null, ...d.map((h) => h > 0 ? h : 0)], o.vs.eyeLookInLeft = [null, ...d.map((h) => h > 0 ? 0 : -h)], o.vs.eyeLookOutRight = [null, ...d.map((h) => h > 0 ? 0 : -h)], o.vs.eyeLookInRight = [null, ...d.map((h) => h > 0 ? h : 0)]) : r === "eyesRotateX" ? (o.vs.eyesLookDown = [null, ...d.map((h) => h > 0 ? h : 0)], o.vs.eyesLookUp = [null, ...d.map((h) => h > 0 ? 0 : -h)]) : o.vs[r] = [null, ...d];
|
|
5054
5054
|
}
|
|
5055
5055
|
for (let r of Object.keys(o.vs))
|
|
5056
5056
|
for (; o.vs[r].length <= o.ts.length; ) o.vs[r].push(o.vs[r][o.vs[r].length - 1]);
|
|
@@ -5131,23 +5131,23 @@ class Be {
|
|
|
5131
5131
|
if (this.isSpeaking)
|
|
5132
5132
|
for (l = 0, this.audioAnalyzerNode.getByteFrequencyData(this.volumeFrequencyData), n = 2, s = 10; n < s; n++)
|
|
5133
5133
|
this.volumeFrequencyData[n] > l && (l = this.volumeFrequencyData[n]);
|
|
5134
|
-
let
|
|
5134
|
+
let c = null, r = null;
|
|
5135
5135
|
const u = [];
|
|
5136
5136
|
for (n = 0, s = this.animQueue.length; n < s; n++) {
|
|
5137
5137
|
const a = this.animQueue[n];
|
|
5138
5138
|
if (!(!a || !a.ts || !a.ts.length || this.animClock < a.ts[0])) {
|
|
5139
5139
|
for (i = a.ndx || 0, o = a.ts.length; i < o && !(this.animClock < a.ts[i]); i++)
|
|
5140
|
-
for (let [d,
|
|
5140
|
+
for (let [d, h] of Object.entries(a.vs))
|
|
5141
5141
|
if (this.mtAvatar.hasOwnProperty(d)) {
|
|
5142
|
-
if (
|
|
5142
|
+
if (h[i + 1] === null) continue;
|
|
5143
5143
|
const g = this.mtAvatar[d];
|
|
5144
|
-
if (
|
|
5145
|
-
g.newvalue =
|
|
5144
|
+
if (h[i] === null && (h[i] = g.value), i === o - 1)
|
|
5145
|
+
g.newvalue = h[i];
|
|
5146
5146
|
else {
|
|
5147
|
-
g.newvalue =
|
|
5147
|
+
g.newvalue = h[i + 1];
|
|
5148
5148
|
const b = a.ts[i + 1] - a.ts[i];
|
|
5149
|
-
let
|
|
5150
|
-
b > 1e-4 && (
|
|
5149
|
+
let f = 1;
|
|
5150
|
+
b > 1e-4 && (f = (this.animClock - a.ts[i]) / b), f < 1 && (g.easing && (f = g.easing(f)), g.newvalue = (1 - f) * h[i] + f * g.newvalue), g.ref && g.ref !== a.vs && g.ref.hasOwnProperty(d) && delete g.ref[d], g.ref = a.vs;
|
|
5151
5151
|
}
|
|
5152
5152
|
if (l)
|
|
5153
5153
|
switch (d) {
|
|
@@ -5159,7 +5159,7 @@ class Be {
|
|
|
5159
5159
|
g.newvalue *= 1 + l / 255 - 0.5;
|
|
5160
5160
|
}
|
|
5161
5161
|
g.needsUpdate = !0;
|
|
5162
|
-
} else d === "eyeContact" &&
|
|
5162
|
+
} else d === "eyeContact" && h[i] !== null && c !== !1 ? c = !!h[i] : d === "headMove" && h[i] !== null && r !== !1 ? h[i] === 0 ? r = !1 : (Math.random() < h[i] && (r = !0), h[i] = null) : h[i] !== null && (u.push({ mt: d, val: h[i] }), h[i] = null);
|
|
5163
5163
|
i === o ? (a.hasOwnProperty("mood") && this.setMood(a.mood), a.loop ? (o = this.isSpeaking && (a.template.name === "head" || a.template.name === "eyes") ? 4 : 1, this.animQueue[n] = this.animFactory(a.template, a.loop > 0 ? a.loop - 1 : a.loop, 1, 1 / o)) : (this.animQueue.splice(n--, 1), s--)) : a.ndx = i - 1;
|
|
5164
5164
|
}
|
|
5165
5165
|
}
|
|
@@ -5181,8 +5181,8 @@ class Be {
|
|
|
5181
5181
|
i && typeof i == "function" && i();
|
|
5182
5182
|
break;
|
|
5183
5183
|
case "moveto":
|
|
5184
|
-
Object.entries(i.props).forEach((
|
|
5185
|
-
|
|
5184
|
+
Object.entries(i.props).forEach((h) => {
|
|
5185
|
+
h[1] ? this.poseTarget.props[h[0]].copy(h[1]) : this.poseTarget.props[h[0]].copy(this.getPoseTemplateProp(h[0])), this.poseTarget.props[h[0]].t = this.animClock, this.poseTarget.props[h[0]].d = h[1] && h[1].d ? h[1].d : h.duration || 2e3;
|
|
5186
5186
|
});
|
|
5187
5187
|
break;
|
|
5188
5188
|
case "handLeft":
|
|
@@ -5210,7 +5210,7 @@ class Be {
|
|
|
5210
5210
|
}, i.x ? new y.Vector3(i.x, i.y, i.z) : null, !0, i.d);
|
|
5211
5211
|
break;
|
|
5212
5212
|
}
|
|
5213
|
-
if ((
|
|
5213
|
+
if ((c || r) && (Q.setFromQuaternion(this.poseAvatar.props["Head.quaternion"]), Q.x = Math.max(-0.9, Math.min(0.9, 2 * Q.x - 0.5)), Q.y = Math.max(-0.9, Math.min(0.9, -2.5 * Q.y)), c ? (Object.assign(this.mtAvatar.eyesLookDown, { system: Q.x < 0 ? -Q.x : 0, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyesLookUp, { system: Q.x < 0 ? 0 : Q.x, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookInLeft, { system: Q.y < 0 ? -Q.y : 0, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookOutLeft, { system: Q.y < 0 ? 0 : Q.y, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookInRight, { system: Q.y < 0 ? 0 : Q.y, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookOutRight, { system: Q.y < 0 ? -Q.y : 0, needsUpdate: !0 }), r && (n = -this.mtAvatar.bodyRotateY.value, i = this.gaussianRandom(-0.2, 0.2), this.animQueue.push(this.animFactory({
|
|
5214
5214
|
name: "headmove",
|
|
5215
5215
|
dt: [[1e3, 2e3], [1e3, 2e3, 1, 2], [1e3, 2e3], [1e3, 2e3, 1, 2]],
|
|
5216
5216
|
vs: {
|
|
@@ -5231,7 +5231,7 @@ class Be {
|
|
|
5231
5231
|
eyeLookOutRight: [null, 0],
|
|
5232
5232
|
eyeContact: [0]
|
|
5233
5233
|
}
|
|
5234
|
-
})))), 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.applyShoulderAdjustmentToBones(), (this.isSpeaking || this.isListening) &&
|
|
5234
|
+
})))), 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.applyShoulderAdjustmentToBones(), (this.isSpeaking || this.isListening) && c ? 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 && (te.setFromAxisAngle(pt, this.volumeHeadCurrent), this.objectNeck.quaternion.multiply(te)), We.setFromObject(this.armature), this.objectLeftToeBase.getWorldPosition(Re), Re.sub(this.armature.position), this.objectRightToeBase.getWorldPosition(Ie), Ie.sub(this.armature.position), this.objectHips.position.y -= We.min.y / 2, this.objectHips.position.x -= (Re.x + Ie.x) / 4, this.objectHips.position.z -= (Re.z + Ie.z) / 2, this.dynamicbones.update(e), this.fbxAnimationLoader && this.fbxAnimationLoader.update(), this.opt.update && this.opt.update(e), this.updateMorphTargets(e), this.isAvatarOnly)
|
|
5235
5235
|
this.stats && this.stats.end();
|
|
5236
5236
|
else {
|
|
5237
5237
|
if (this.cameraClock !== null && this.cameraClock < 1e3) {
|
|
@@ -5298,14 +5298,14 @@ class Be {
|
|
|
5298
5298
|
*/
|
|
5299
5299
|
speakText(t, e = null, n = null, i = null) {
|
|
5300
5300
|
e = e || {};
|
|
5301
|
-
const s = /[!\.\?\n\p{Extended_Pictographic}]/ug, o = /[ ]/ug, l = /[\p{L}\p{N},\.\p{Quotation_Mark}!€\$\+\p{Dash_Punctuation}%&\?]/ug,
|
|
5302
|
-
let u = "", a = "", d = 0,
|
|
5303
|
-
const b = Array.from(this.segmenter.segment(t), (
|
|
5304
|
-
for (let
|
|
5305
|
-
const
|
|
5306
|
-
let p = b[
|
|
5307
|
-
const
|
|
5308
|
-
if (p && !
|
|
5301
|
+
const s = /[!\.\?\n\p{Extended_Pictographic}]/ug, o = /[ ]/ug, l = /[\p{L}\p{N},\.\p{Quotation_Mark}!€\$\+\p{Dash_Punctuation}%&\?]/ug, c = /[\p{Extended_Pictographic}]/ug, r = e.lipsyncLang || this.avatar.lipsyncLang || this.opt.lipsyncLang;
|
|
5302
|
+
let u = "", a = "", d = 0, h = [], g = [];
|
|
5303
|
+
const b = Array.from(this.segmenter.segment(t), (f) => f.segment);
|
|
5304
|
+
for (let f = 0; f < b.length; f++) {
|
|
5305
|
+
const w = f === b.length - 1, N = b[f].match(l);
|
|
5306
|
+
let p = b[f].match(s);
|
|
5307
|
+
const B = b[f].match(c), F = b[f].match(o);
|
|
5308
|
+
if (p && !w && !B && b[f + 1].match(s) && (p = !1), n && (u += b[f]), N && (!i || i.every((I) => f < I[0] || f > I[1])) && (a += b[f]), (F || p || w) && (a.length && (a = this.lipsyncPreProcessText(a, r), a.length && h.push({
|
|
5309
5309
|
mark: d,
|
|
5310
5310
|
word: a
|
|
5311
5311
|
})), u.length && (g.push({
|
|
@@ -5318,28 +5318,28 @@ class Be {
|
|
|
5318
5318
|
}), u = ""), a.length)) {
|
|
5319
5319
|
const I = this.lipsyncWordsToVisemes(a, r);
|
|
5320
5320
|
if (I && I.visemes && I.visemes.length) {
|
|
5321
|
-
const
|
|
5322
|
-
for (let
|
|
5321
|
+
const D = I.times[I.visemes.length - 1] + I.durations[I.visemes.length - 1];
|
|
5322
|
+
for (let x = 0; x < I.visemes.length; x++)
|
|
5323
5323
|
g.push({
|
|
5324
5324
|
mark: d,
|
|
5325
5325
|
template: { name: "viseme" },
|
|
5326
|
-
ts: [(I.times[
|
|
5326
|
+
ts: [(I.times[x] - 0.6) / D, (I.times[x] + 0.5) / D, (I.times[x] + I.durations[x] + 0.5) / D],
|
|
5327
5327
|
vs: {
|
|
5328
|
-
["viseme_" + I.visemes[
|
|
5328
|
+
["viseme_" + I.visemes[x]]: [null, I.visemes[x] === "PP" || I.visemes[x] === "FF" ? 0.9 : 0.6, 0]
|
|
5329
5329
|
}
|
|
5330
5330
|
});
|
|
5331
5331
|
}
|
|
5332
5332
|
a = "", d++;
|
|
5333
5333
|
}
|
|
5334
|
-
if (p ||
|
|
5335
|
-
if (
|
|
5334
|
+
if (p || w) {
|
|
5335
|
+
if (h.length || w && g.length) {
|
|
5336
5336
|
const I = {
|
|
5337
5337
|
anim: g
|
|
5338
5338
|
};
|
|
5339
|
-
n && (I.onSubtitles = n),
|
|
5339
|
+
n && (I.onSubtitles = n), h.length && !e.avatarMute && (I.text = h, e.avatarMood && (I.mood = e.avatarMood), e.ttsLang && (I.lang = e.ttsLang), e.ttsVoice && (I.voice = e.ttsVoice), e.ttsRate && (I.rate = e.ttsRate), e.ttsVoice && (I.pitch = e.ttsPitch), e.ttsVolume && (I.volume = e.ttsVolume)), this.speechQueue.push(I), h = [], a = "", d = 0, g = [];
|
|
5340
5340
|
}
|
|
5341
|
-
if (
|
|
5342
|
-
let I = this.animEmojis[b[
|
|
5341
|
+
if (B) {
|
|
5342
|
+
let I = this.animEmojis[b[f]];
|
|
5343
5343
|
I && I.link && (I = this.animEmojis[I.link]), I && this.speechQueue.push({ emoji: I });
|
|
5344
5344
|
}
|
|
5345
5345
|
this.speechQueue.push({ break: 100 });
|
|
@@ -5421,27 +5421,27 @@ class Be {
|
|
|
5421
5421
|
if (t.words) {
|
|
5422
5422
|
let o = [];
|
|
5423
5423
|
for (let l = 0; l < t.words.length; l++) {
|
|
5424
|
-
const
|
|
5424
|
+
const c = t.words[l], r = t.wtimes[l];
|
|
5425
5425
|
let u = t.wdurations[l];
|
|
5426
|
-
if (
|
|
5426
|
+
if (c.length && (n && o.push({
|
|
5427
5427
|
template: { name: "subtitles" },
|
|
5428
5428
|
ts: [r],
|
|
5429
5429
|
vs: {
|
|
5430
|
-
subtitles: [" " +
|
|
5430
|
+
subtitles: [" " + c]
|
|
5431
5431
|
}
|
|
5432
5432
|
}), !t.visemes)) {
|
|
5433
|
-
const a = this.lipsyncPreProcessText(
|
|
5433
|
+
const a = this.lipsyncPreProcessText(c, i), d = this.lipsyncWordsToVisemes(a, i);
|
|
5434
5434
|
if (d && d.visemes && d.visemes.length) {
|
|
5435
|
-
const
|
|
5435
|
+
const h = d.times[d.visemes.length - 1] + d.durations[d.visemes.length - 1], g = Math.min(u, Math.max(0, u - d.visemes.length * 150));
|
|
5436
5436
|
let b = 0.6 + this.convertRange(g, [0, u], [0, 0.4]);
|
|
5437
|
-
if (u = Math.min(u, d.visemes.length * 200),
|
|
5438
|
-
for (let
|
|
5439
|
-
const
|
|
5437
|
+
if (u = Math.min(u, d.visemes.length * 200), h > 0)
|
|
5438
|
+
for (let f = 0; f < d.visemes.length; f++) {
|
|
5439
|
+
const w = r + d.times[f] / h * u, N = d.durations[f] / h * u;
|
|
5440
5440
|
o.push({
|
|
5441
5441
|
template: { name: "viseme" },
|
|
5442
|
-
ts: [
|
|
5442
|
+
ts: [w - Math.min(60, 2 * N / 3), w + Math.min(25, N / 2), w + N + Math.min(60, N / 2)],
|
|
5443
5443
|
vs: {
|
|
5444
|
-
["viseme_" + d.visemes[
|
|
5444
|
+
["viseme_" + d.visemes[f]]: [null, d.visemes[f] === "PP" || d.visemes[f] === "FF" ? 0.9 : b, 0]
|
|
5445
5445
|
}
|
|
5446
5446
|
});
|
|
5447
5447
|
}
|
|
@@ -5450,22 +5450,22 @@ class Be {
|
|
|
5450
5450
|
}
|
|
5451
5451
|
if (t.visemes)
|
|
5452
5452
|
for (let l = 0; l < t.visemes.length; l++) {
|
|
5453
|
-
const
|
|
5453
|
+
const c = t.visemes[l], r = t.vtimes[l], u = t.vdurations[l];
|
|
5454
5454
|
o.push({
|
|
5455
5455
|
template: { name: "viseme" },
|
|
5456
5456
|
ts: [r - 2 * u / 3, r + u / 2, r + u + u / 2],
|
|
5457
5457
|
vs: {
|
|
5458
|
-
["viseme_" +
|
|
5458
|
+
["viseme_" + c]: [null, c === "PP" || c === "FF" ? 0.9 : 0.6, 0]
|
|
5459
5459
|
}
|
|
5460
5460
|
});
|
|
5461
5461
|
}
|
|
5462
5462
|
if (t.markers)
|
|
5463
5463
|
for (let l = 0; l < t.markers.length; l++) {
|
|
5464
|
-
const
|
|
5464
|
+
const c = t.markers[l], r = t.mtimes[l];
|
|
5465
5465
|
o.push({
|
|
5466
5466
|
template: { name: "markers" },
|
|
5467
5467
|
ts: [r],
|
|
5468
|
-
vs: { function: [
|
|
5468
|
+
vs: { function: [c] }
|
|
5469
5469
|
});
|
|
5470
5470
|
}
|
|
5471
5471
|
o.length && (s.anim = o);
|
|
@@ -5485,7 +5485,7 @@ class Be {
|
|
|
5485
5485
|
if (this.isAudioPlaying = !0, this.audioPlaylist.length) {
|
|
5486
5486
|
const e = this.audioPlaylist.shift();
|
|
5487
5487
|
if (this.audioCtx.state === "suspended" || this.audioCtx.state === "interrupted") {
|
|
5488
|
-
const s = this.audioCtx.resume(), o = new Promise((l,
|
|
5488
|
+
const s = this.audioCtx.resume(), o = new Promise((l, c) => setTimeout(() => c("p2"), 1e3));
|
|
5489
5489
|
try {
|
|
5490
5490
|
await Promise.race([s, o]);
|
|
5491
5491
|
} catch {
|
|
@@ -5517,38 +5517,38 @@ class Be {
|
|
|
5517
5517
|
*/
|
|
5518
5518
|
async synthesizeWithBrowserTTS(t) {
|
|
5519
5519
|
return new Promise((e, n) => {
|
|
5520
|
-
const i = t.text.map((p) => p.word).join(" "), s = new SpeechSynthesisUtterance(i), o = t.lang || this.avatar.ttsLang || this.opt.ttsLang || "en-US", l = (t.rate || this.avatar.ttsRate || this.opt.ttsRate || 1) + this.mood.speech.deltaRate,
|
|
5521
|
-
s.lang = o, s.rate = Math.max(0.1, Math.min(10, l)), s.pitch = Math.max(0, Math.min(2,
|
|
5520
|
+
const i = t.text.map((p) => p.word).join(" "), s = new SpeechSynthesisUtterance(i), o = t.lang || this.avatar.ttsLang || this.opt.ttsLang || "en-US", l = (t.rate || this.avatar.ttsRate || this.opt.ttsRate || 1) + this.mood.speech.deltaRate, c = (t.pitch || this.avatar.ttsPitch || this.opt.ttsPitch || 1) + this.mood.speech.deltaPitch, r = (t.volume || this.avatar.ttsVolume || this.opt.ttsVolume || 1) + this.mood.speech.deltaVolume;
|
|
5521
|
+
s.lang = o, s.rate = Math.max(0.1, Math.min(10, l)), s.pitch = Math.max(0, Math.min(2, c)), s.volume = Math.max(0, Math.min(1, r));
|
|
5522
5522
|
const u = speechSynthesis.getVoices(), a = t.voice || this.avatar.ttsVoice || this.opt.ttsVoice;
|
|
5523
5523
|
if (a && u.length > 0) {
|
|
5524
|
-
const p = u.find((
|
|
5524
|
+
const p = u.find((B) => B.name.includes(a) || B.lang === o);
|
|
5525
5525
|
p && (s.voice = p);
|
|
5526
5526
|
}
|
|
5527
|
-
const d = i.length * 100 / s.rate,
|
|
5527
|
+
const d = i.length * 100 / s.rate, h = this.audioCtx.createBuffer(1, this.audioCtx.sampleRate * (d / 1e3), this.audioCtx.sampleRate), g = this.avatar.lipsyncLang || this.opt.lipsyncLang || "en", b = this.lipsyncPreProcessText(i, g), f = this.lipsyncWordsToVisemes(b, g);
|
|
5528
5528
|
console.log("Browser TTS Lip-sync Debug:", {
|
|
5529
5529
|
text: i,
|
|
5530
5530
|
lipsyncLang: g,
|
|
5531
5531
|
processedText: b,
|
|
5532
|
-
lipsyncData:
|
|
5533
|
-
hasVisemes:
|
|
5532
|
+
lipsyncData: f,
|
|
5533
|
+
hasVisemes: f && f.visemes && f.visemes.length > 0,
|
|
5534
5534
|
estimatedDuration: d
|
|
5535
5535
|
});
|
|
5536
|
-
const
|
|
5537
|
-
if (
|
|
5538
|
-
const p =
|
|
5539
|
-
for (let
|
|
5540
|
-
const
|
|
5541
|
-
|
|
5536
|
+
const w = [];
|
|
5537
|
+
if (f && f.visemes && f.visemes.length > 0) {
|
|
5538
|
+
const p = f.times[f.visemes.length - 1] + f.durations[f.visemes.length - 1];
|
|
5539
|
+
for (let B = 0; B < f.visemes.length; B++) {
|
|
5540
|
+
const F = f.visemes[B], I = f.times[B] / p, D = f.durations[B] / p, x = I * d, k = D * d;
|
|
5541
|
+
w.push({
|
|
5542
5542
|
template: { name: "viseme" },
|
|
5543
|
-
ts: [
|
|
5543
|
+
ts: [x - Math.min(60, 2 * k / 3), x + Math.min(25, k / 2), x + k + Math.min(60, k / 2)],
|
|
5544
5544
|
vs: {
|
|
5545
|
-
["viseme_" +
|
|
5545
|
+
["viseme_" + F]: [null, F === "PP" || F === "FF" ? 0.9 : 0.6, 0]
|
|
5546
5546
|
}
|
|
5547
5547
|
});
|
|
5548
5548
|
}
|
|
5549
5549
|
}
|
|
5550
|
-
const
|
|
5551
|
-
this.audioPlaylist.push({ anim:
|
|
5550
|
+
const N = [...t.anim, ...w];
|
|
5551
|
+
this.audioPlaylist.push({ anim: N, audio: h }), this.onSubtitles = t.onSubtitles || null, this.resetLips(), t.mood && this.setMood(t.mood), this.playAudio(), s.onend = () => {
|
|
5552
5552
|
e();
|
|
5553
5553
|
}, s.onerror = (p) => {
|
|
5554
5554
|
console.error("Speech synthesis error:", p.error), n(p.error);
|
|
@@ -5582,26 +5582,26 @@ class Be {
|
|
|
5582
5582
|
throw new Error(`ElevenLabs TTS error: ${s.status} ${s.statusText}`);
|
|
5583
5583
|
const o = await s.arrayBuffer(), l = await this.audioCtx.decodeAudioData(o);
|
|
5584
5584
|
console.log("Using text-based lip-sync for debugging...");
|
|
5585
|
-
const
|
|
5585
|
+
const c = this.avatar.lipsyncLang || this.opt.lipsyncLang || "en";
|
|
5586
5586
|
let r;
|
|
5587
5587
|
try {
|
|
5588
5588
|
console.log("Lip-sync modules available:", {
|
|
5589
5589
|
hasLipsync: !!this.lipsync,
|
|
5590
5590
|
lipsyncKeys: this.lipsync ? Object.keys(this.lipsync) : [],
|
|
5591
|
-
lipsyncLang:
|
|
5591
|
+
lipsyncLang: c
|
|
5592
5592
|
});
|
|
5593
|
-
const d = this.lipsyncPreProcessText(e,
|
|
5593
|
+
const d = this.lipsyncPreProcessText(e, c), h = this.lipsyncWordsToVisemes(d, c);
|
|
5594
5594
|
if (console.log("Lip-sync data:", {
|
|
5595
5595
|
processedText: d,
|
|
5596
|
-
lipsyncData:
|
|
5597
|
-
hasVisemes:
|
|
5598
|
-
}),
|
|
5596
|
+
lipsyncData: h,
|
|
5597
|
+
hasVisemes: h && h.visemes && h.visemes.length > 0
|
|
5598
|
+
}), h && h.visemes && h.visemes.length > 0)
|
|
5599
5599
|
r = {
|
|
5600
|
-
visemes:
|
|
5600
|
+
visemes: h.visemes.map((g, b) => ({
|
|
5601
5601
|
viseme: g,
|
|
5602
|
-
startTime: b * l.duration /
|
|
5603
|
-
endTime: (b + 1) * l.duration /
|
|
5604
|
-
duration: l.duration /
|
|
5602
|
+
startTime: b * l.duration / h.visemes.length,
|
|
5603
|
+
endTime: (b + 1) * l.duration / h.visemes.length,
|
|
5604
|
+
duration: l.duration / h.visemes.length,
|
|
5605
5605
|
intensity: 0.7
|
|
5606
5606
|
})),
|
|
5607
5607
|
words: [],
|
|
@@ -5612,17 +5612,17 @@ class Be {
|
|
|
5612
5612
|
throw new Error("No visemes generated from text");
|
|
5613
5613
|
} catch (d) {
|
|
5614
5614
|
console.error("Text-based lip-sync failed, using fallback:", d);
|
|
5615
|
-
const
|
|
5616
|
-
for (const b of
|
|
5617
|
-
for (const
|
|
5618
|
-
let
|
|
5619
|
-
"aeiou".includes(
|
|
5615
|
+
const h = e.toLowerCase().split(/\s+/), g = [];
|
|
5616
|
+
for (const b of h)
|
|
5617
|
+
for (const f of b) {
|
|
5618
|
+
let w = "aa";
|
|
5619
|
+
"aeiou".includes(f) ? w = "aa" : "bp".includes(f) ? w = "PP" : "fv".includes(f) ? w = "FF" : "st".includes(f) ? w = "SS" : "dln".includes(f) ? w = "DD" : "kg".includes(f) ? w = "kk" : "rw".includes(f) && (w = "RR"), g.push(w);
|
|
5620
5620
|
}
|
|
5621
5621
|
r = {
|
|
5622
|
-
visemes: g.map((b,
|
|
5622
|
+
visemes: g.map((b, f) => ({
|
|
5623
5623
|
viseme: b,
|
|
5624
|
-
startTime:
|
|
5625
|
-
endTime: (
|
|
5624
|
+
startTime: f * l.duration / g.length,
|
|
5625
|
+
endTime: (f + 1) * l.duration / g.length,
|
|
5626
5626
|
duration: l.duration / g.length,
|
|
5627
5627
|
intensity: 0.6
|
|
5628
5628
|
})),
|
|
@@ -5647,12 +5647,12 @@ class Be {
|
|
|
5647
5647
|
if (r.visemes && r.visemes.length > 0) {
|
|
5648
5648
|
console.log("ElevenLabs: Generating lip-sync animation from", r.visemes.length, "visemes");
|
|
5649
5649
|
for (let d = 0; d < r.visemes.length; d++) {
|
|
5650
|
-
const
|
|
5650
|
+
const h = r.visemes[d], g = h.startTime * 1e3, b = h.duration * 1e3, f = h.intensity;
|
|
5651
5651
|
u.push({
|
|
5652
5652
|
template: { name: "viseme" },
|
|
5653
5653
|
ts: [g - Math.min(60, 2 * b / 3), g + Math.min(25, b / 2), g + b + Math.min(60, b / 2)],
|
|
5654
5654
|
vs: {
|
|
5655
|
-
["viseme_" +
|
|
5655
|
+
["viseme_" + h.viseme]: [null, f, 0]
|
|
5656
5656
|
}
|
|
5657
5657
|
});
|
|
5658
5658
|
}
|
|
@@ -5680,26 +5680,26 @@ class Be {
|
|
|
5680
5680
|
throw new Error(`Deepgram TTS error: ${s.status} ${s.statusText}`);
|
|
5681
5681
|
const o = await s.arrayBuffer(), l = await this.audioCtx.decodeAudioData(o);
|
|
5682
5682
|
console.log("Using text-based lip-sync for Deepgram...");
|
|
5683
|
-
const
|
|
5683
|
+
const c = this.avatar.lipsyncLang || this.opt.lipsyncLang || "en";
|
|
5684
5684
|
let r;
|
|
5685
5685
|
try {
|
|
5686
5686
|
console.log("Lip-sync modules available:", {
|
|
5687
5687
|
hasLipsync: !!this.lipsync,
|
|
5688
5688
|
lipsyncKeys: this.lipsync ? Object.keys(this.lipsync) : [],
|
|
5689
|
-
lipsyncLang:
|
|
5689
|
+
lipsyncLang: c
|
|
5690
5690
|
});
|
|
5691
|
-
const d = this.lipsyncPreProcessText(e,
|
|
5691
|
+
const d = this.lipsyncPreProcessText(e, c), h = this.lipsyncWordsToVisemes(d, c);
|
|
5692
5692
|
if (console.log("Lip-sync data:", {
|
|
5693
5693
|
processedText: d,
|
|
5694
|
-
lipsyncData:
|
|
5695
|
-
hasVisemes:
|
|
5696
|
-
}),
|
|
5694
|
+
lipsyncData: h,
|
|
5695
|
+
hasVisemes: h && h.visemes && h.visemes.length > 0
|
|
5696
|
+
}), h && h.visemes && h.visemes.length > 0)
|
|
5697
5697
|
r = {
|
|
5698
|
-
visemes:
|
|
5698
|
+
visemes: h.visemes.map((g, b) => ({
|
|
5699
5699
|
viseme: g,
|
|
5700
|
-
startTime: b * l.duration /
|
|
5701
|
-
endTime: (b + 1) * l.duration /
|
|
5702
|
-
duration: l.duration /
|
|
5700
|
+
startTime: b * l.duration / h.visemes.length,
|
|
5701
|
+
endTime: (b + 1) * l.duration / h.visemes.length,
|
|
5702
|
+
duration: l.duration / h.visemes.length,
|
|
5703
5703
|
intensity: 0.7
|
|
5704
5704
|
})),
|
|
5705
5705
|
words: [],
|
|
@@ -5710,17 +5710,17 @@ class Be {
|
|
|
5710
5710
|
throw new Error("No visemes generated from text");
|
|
5711
5711
|
} catch (d) {
|
|
5712
5712
|
console.error("Text-based lip-sync failed, using fallback:", d);
|
|
5713
|
-
const
|
|
5714
|
-
for (const b of
|
|
5715
|
-
for (const
|
|
5716
|
-
let
|
|
5717
|
-
"aeiou".includes(
|
|
5713
|
+
const h = e.toLowerCase().split(/\s+/), g = [];
|
|
5714
|
+
for (const b of h)
|
|
5715
|
+
for (const f of b) {
|
|
5716
|
+
let w = "aa";
|
|
5717
|
+
"aeiou".includes(f) ? w = "aa" : "bp".includes(f) ? w = "PP" : "fv".includes(f) ? w = "FF" : "st".includes(f) ? w = "SS" : "dln".includes(f) ? w = "DD" : "kg".includes(f) ? w = "kk" : "rw".includes(f) && (w = "RR"), g.push(w);
|
|
5718
5718
|
}
|
|
5719
5719
|
r = {
|
|
5720
|
-
visemes: g.map((b,
|
|
5720
|
+
visemes: g.map((b, f) => ({
|
|
5721
5721
|
viseme: b,
|
|
5722
|
-
startTime:
|
|
5723
|
-
endTime: (
|
|
5722
|
+
startTime: f * l.duration / g.length,
|
|
5723
|
+
endTime: (f + 1) * l.duration / g.length,
|
|
5724
5724
|
duration: l.duration / g.length,
|
|
5725
5725
|
intensity: 0.6
|
|
5726
5726
|
})),
|
|
@@ -5745,12 +5745,12 @@ class Be {
|
|
|
5745
5745
|
if (r.visemes && r.visemes.length > 0) {
|
|
5746
5746
|
console.log("Deepgram: Generating lip-sync animation from", r.visemes.length, "visemes");
|
|
5747
5747
|
for (let d = 0; d < r.visemes.length; d++) {
|
|
5748
|
-
const
|
|
5748
|
+
const h = r.visemes[d], g = h.startTime * 1e3, b = h.duration * 1e3, f = h.intensity;
|
|
5749
5749
|
u.push({
|
|
5750
5750
|
template: { name: "viseme" },
|
|
5751
5751
|
ts: [g - Math.min(60, 2 * b / 3), g + Math.min(25, b / 2), g + b + Math.min(60, b / 2)],
|
|
5752
5752
|
vs: {
|
|
5753
|
-
["viseme_" +
|
|
5753
|
+
["viseme_" + h.viseme]: [null, f, 0]
|
|
5754
5754
|
}
|
|
5755
5755
|
});
|
|
5756
5756
|
}
|
|
@@ -5784,23 +5784,23 @@ class Be {
|
|
|
5784
5784
|
throw new Error(`Azure TTS error: ${s.status} ${s.statusText}`);
|
|
5785
5785
|
const o = await s.arrayBuffer(), l = await this.audioCtx.decodeAudioData(o);
|
|
5786
5786
|
console.log("Analyzing audio for precise lip-sync...");
|
|
5787
|
-
const
|
|
5787
|
+
const c = await this.audioAnalyzer.analyzeAudio(l, e);
|
|
5788
5788
|
console.log("Azure TTS Audio Analysis:", {
|
|
5789
5789
|
text: e,
|
|
5790
5790
|
audioDuration: l.duration,
|
|
5791
|
-
visemeCount:
|
|
5792
|
-
wordCount:
|
|
5791
|
+
visemeCount: c.visemes.length,
|
|
5792
|
+
wordCount: c.words.length,
|
|
5793
5793
|
features: {
|
|
5794
|
-
onsets:
|
|
5795
|
-
boundaries:
|
|
5794
|
+
onsets: c.features.onsets.length,
|
|
5795
|
+
boundaries: c.features.phonemeBoundaries.length
|
|
5796
5796
|
}
|
|
5797
5797
|
});
|
|
5798
5798
|
const r = [];
|
|
5799
|
-
for (let a = 0; a <
|
|
5800
|
-
const d =
|
|
5799
|
+
for (let a = 0; a < c.visemes.length; a++) {
|
|
5800
|
+
const d = c.visemes[a], h = d.startTime * 1e3, g = d.duration * 1e3, b = d.intensity;
|
|
5801
5801
|
r.push({
|
|
5802
5802
|
template: { name: "viseme" },
|
|
5803
|
-
ts: [
|
|
5803
|
+
ts: [h - Math.min(60, 2 * g / 3), h + Math.min(25, g / 2), h + g + Math.min(60, g / 2)],
|
|
5804
5804
|
vs: {
|
|
5805
5805
|
["viseme_" + d.viseme]: [null, b, 0]
|
|
5806
5806
|
}
|
|
@@ -5846,27 +5846,27 @@ class Be {
|
|
|
5846
5846
|
if (i.status === 200 && s && s.audioContent) {
|
|
5847
5847
|
const o = this.b64ToArrayBuffer(s.audioContent), l = await this.audioCtx.decodeAudioData(o);
|
|
5848
5848
|
this.speakWithHands();
|
|
5849
|
-
const
|
|
5849
|
+
const c = [0];
|
|
5850
5850
|
let r = 0;
|
|
5851
|
-
t.text.forEach((d,
|
|
5852
|
-
if (
|
|
5853
|
-
let g =
|
|
5854
|
-
s.timepoints[r] && (g = s.timepoints[r].timeSeconds * 1e3, s.timepoints[r].markName === "" + d.mark && r++),
|
|
5851
|
+
t.text.forEach((d, h) => {
|
|
5852
|
+
if (h > 0) {
|
|
5853
|
+
let g = c[c.length - 1];
|
|
5854
|
+
s.timepoints[r] && (g = s.timepoints[r].timeSeconds * 1e3, s.timepoints[r].markName === "" + d.mark && r++), c.push(g);
|
|
5855
5855
|
}
|
|
5856
5856
|
});
|
|
5857
5857
|
const u = [{ mark: 0, time: 0 }];
|
|
5858
|
-
|
|
5859
|
-
if (
|
|
5860
|
-
let g = d - h
|
|
5861
|
-
u[
|
|
5858
|
+
c.forEach((d, h) => {
|
|
5859
|
+
if (h > 0) {
|
|
5860
|
+
let g = d - c[h - 1];
|
|
5861
|
+
u[h - 1].duration = g, u.push({ mark: h, time: d });
|
|
5862
5862
|
}
|
|
5863
5863
|
});
|
|
5864
5864
|
let a = 1e3 * l.duration;
|
|
5865
5865
|
a > this.opt.ttsTrimEnd && (a = a - this.opt.ttsTrimEnd), u[u.length - 1].duration = a - u[u.length - 1].time, t.anim.forEach((d) => {
|
|
5866
|
-
const
|
|
5867
|
-
if (
|
|
5866
|
+
const h = u[d.mark];
|
|
5867
|
+
if (h)
|
|
5868
5868
|
for (let g = 0; g < d.ts.length; g++)
|
|
5869
|
-
d.ts[g] =
|
|
5869
|
+
d.ts[g] = h.time + d.ts[g] * h.duration + this.opt.ttsTrimStart;
|
|
5870
5870
|
}), this.audioPlaylist.push({ anim: t.anim, audio: l }), this.onSubtitles = t.onSubtitles || null, this.resetLips(), t.mood && this.setMood(t.mood), this.playAudio();
|
|
5871
5871
|
} else
|
|
5872
5872
|
this.startSpeaking(!0);
|
|
@@ -5946,10 +5946,10 @@ class Be {
|
|
|
5946
5946
|
}
|
|
5947
5947
|
if (!this.workletLoaded)
|
|
5948
5948
|
try {
|
|
5949
|
-
const l = this.audioCtx.audioWorklet.addModule(
|
|
5949
|
+
const l = this.audioCtx.audioWorklet.addModule(mt.href), c = new Promise(
|
|
5950
5950
|
(r, u) => setTimeout(() => u(new Error("Worklet loading timed out")), 5e3)
|
|
5951
5951
|
);
|
|
5952
|
-
await Promise.race([l,
|
|
5952
|
+
await Promise.race([l, c]), this.workletLoaded = !0;
|
|
5953
5953
|
} catch (l) {
|
|
5954
5954
|
throw console.error("Failed to load audio worklet:", l), new Error("Failed to initialize streaming speech");
|
|
5955
5955
|
}
|
|
@@ -5962,8 +5962,8 @@ class Be {
|
|
|
5962
5962
|
if (l.data.type === "playback-started" && (this.isSpeaking = !0, this.stateName = "speaking", this.streamWaitForAudioChunks && (this.streamAudioStartTime = this.animClock), this._processStreamLipsyncQueue(), this.speakWithHands(), this.onAudioStart))
|
|
5963
5963
|
try {
|
|
5964
5964
|
this.onAudioStart?.();
|
|
5965
|
-
} catch (
|
|
5966
|
-
console.error(
|
|
5965
|
+
} catch (c) {
|
|
5966
|
+
console.error(c);
|
|
5967
5967
|
}
|
|
5968
5968
|
if (l.data.type === "playback-ended" && (this._streamPause(), this.onAudioEnd))
|
|
5969
5969
|
try {
|
|
@@ -5983,9 +5983,9 @@ class Be {
|
|
|
5983
5983
|
} catch {
|
|
5984
5984
|
}
|
|
5985
5985
|
if (this.resetLips(), this.lookAtCamera(500), t.mood && this.setMood(t.mood), this.onSubtitles = i || null, this.audioCtx.state === "suspended" || this.audioCtx.state === "interrupted") {
|
|
5986
|
-
const l = this.audioCtx.resume(),
|
|
5986
|
+
const l = this.audioCtx.resume(), c = new Promise((r, u) => setTimeout(() => u("p2"), 1e3));
|
|
5987
5987
|
try {
|
|
5988
|
-
await Promise.race([l,
|
|
5988
|
+
await Promise.race([l, c]);
|
|
5989
5989
|
} catch {
|
|
5990
5990
|
console.warn("Can't play audio. Web Audio API suspended. This is often due to calling some speak method before the first user action, which is typically prevented by the browser.");
|
|
5991
5991
|
return;
|
|
@@ -6082,18 +6082,18 @@ class Be {
|
|
|
6082
6082
|
subtitles: [" " + i]
|
|
6083
6083
|
}
|
|
6084
6084
|
}), this.streamLipsyncType == "words")) {
|
|
6085
|
-
const l = this.streamLipsyncLang || this.avatar.lipsyncLang || this.opt.lipsyncLang,
|
|
6085
|
+
const l = this.streamLipsyncLang || this.avatar.lipsyncLang || this.opt.lipsyncLang, c = this.lipsyncPreProcessText(i, l), r = this.lipsyncWordsToVisemes(c, l);
|
|
6086
6086
|
if (r && r.visemes && r.visemes.length) {
|
|
6087
6087
|
const u = r.times[r.visemes.length - 1] + r.durations[r.visemes.length - 1], a = Math.min(o, Math.max(0, o - r.visemes.length * 150));
|
|
6088
6088
|
let d = 0.6 + this.convertRange(a, [0, o], [0, 0.4]);
|
|
6089
6089
|
if (o = Math.min(o, r.visemes.length * 200), u > 0)
|
|
6090
|
-
for (let
|
|
6091
|
-
const g = e + s + r.times[
|
|
6090
|
+
for (let h = 0; h < r.visemes.length; h++) {
|
|
6091
|
+
const g = e + s + r.times[h] / u * o, b = r.durations[h] / u * o;
|
|
6092
6092
|
this.animQueue.push({
|
|
6093
6093
|
template: { name: "viseme" },
|
|
6094
6094
|
ts: [g - Math.min(60, 2 * b / 3), g + Math.min(25, b / 2), g + b + Math.min(60, b / 2)],
|
|
6095
6095
|
vs: {
|
|
6096
|
-
["viseme_" + r.visemes[
|
|
6096
|
+
["viseme_" + r.visemes[h]]: [null, r.visemes[h] === "PP" || r.visemes[h] === "FF" ? 0.9 : d, 0]
|
|
6097
6097
|
}
|
|
6098
6098
|
});
|
|
6099
6099
|
}
|
|
@@ -6184,7 +6184,7 @@ class Be {
|
|
|
6184
6184
|
*/
|
|
6185
6185
|
lookAtCamera(t) {
|
|
6186
6186
|
let e;
|
|
6187
|
-
if (this.speakTo && (e = new y.Vector3(), this.speakTo.objectLeftEye?.isObject3D ? (this.speakTo.armature.objectHead, this.speakTo.objectLeftEye.updateMatrixWorld(!0), this.speakTo.objectRightEye.updateMatrixWorld(!0),
|
|
6187
|
+
if (this.speakTo && (e = new y.Vector3(), this.speakTo.objectLeftEye?.isObject3D ? (this.speakTo.armature.objectHead, this.speakTo.objectLeftEye.updateMatrixWorld(!0), this.speakTo.objectRightEye.updateMatrixWorld(!0), Re.setFromMatrixPosition(this.speakTo.objectLeftEye.matrixWorld), Ie.setFromMatrixPosition(this.speakTo.objectRightEye.matrixWorld), e.addVectors(Re, Ie).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) {
|
|
6188
6188
|
if (this.avatar.hasOwnProperty("avatarIgnoreCamera")) {
|
|
6189
6189
|
if (this.avatar.avatarIgnoreCamera) {
|
|
6190
6190
|
this.lookAhead(t);
|
|
@@ -6197,22 +6197,22 @@ class Be {
|
|
|
6197
6197
|
this.lookAt(null, null, t);
|
|
6198
6198
|
return;
|
|
6199
6199
|
}
|
|
6200
|
-
this.objectLeftEye.updateMatrixWorld(!0), this.objectRightEye.updateMatrixWorld(!0),
|
|
6201
|
-
const n = new y.Vector3().subVectors(e,
|
|
6202
|
-
|
|
6203
|
-
const l = new y.Quaternion().setFromEuler(
|
|
6204
|
-
|
|
6205
|
-
let r =
|
|
6200
|
+
this.objectLeftEye.updateMatrixWorld(!0), this.objectRightEye.updateMatrixWorld(!0), Re.setFromMatrixPosition(this.objectLeftEye.matrixWorld), Ie.setFromMatrixPosition(this.objectRightEye.matrixWorld), Re.add(Ie).divideScalar(2), te.copy(this.armature.quaternion), te.multiply(this.poseTarget.props["Hips.quaternion"]), te.multiply(this.poseTarget.props["Spine.quaternion"]), te.multiply(this.poseTarget.props["Spine1.quaternion"]), te.multiply(this.poseTarget.props["Spine2.quaternion"]), te.multiply(this.poseTarget.props["Neck.quaternion"]), te.multiply(this.poseTarget.props["Head.quaternion"]);
|
|
6201
|
+
const n = new y.Vector3().subVectors(e, Re).normalize(), i = Math.atan2(n.x, n.z), s = Math.asin(-n.y);
|
|
6202
|
+
Q.set(s, i, 0, "YXZ");
|
|
6203
|
+
const l = new y.Quaternion().setFromEuler(Q), c = new y.Quaternion().copy(l).multiply(te.clone().invert());
|
|
6204
|
+
Q.setFromQuaternion(c, "YXZ");
|
|
6205
|
+
let r = Q.x / (40 / 24) + 0.2, u = Q.y / (9 / 4), a = Math.min(0.6, Math.max(-0.3, r)), d = Math.min(0.8, Math.max(-0.8, u)), h = (Math.random() - 0.5) / 4, g = (Math.random() - 0.5) / 4;
|
|
6206
6206
|
if (t) {
|
|
6207
|
-
let b = this.animQueue.findIndex((
|
|
6207
|
+
let b = this.animQueue.findIndex((w) => w.template.name === "lookat");
|
|
6208
6208
|
b !== -1 && this.animQueue.splice(b, 1);
|
|
6209
|
-
const
|
|
6209
|
+
const f = {
|
|
6210
6210
|
name: "lookat",
|
|
6211
6211
|
dt: [750, t],
|
|
6212
6212
|
vs: {
|
|
6213
|
-
bodyRotateX: [a +
|
|
6213
|
+
bodyRotateX: [a + h],
|
|
6214
6214
|
bodyRotateY: [d + g],
|
|
6215
|
-
eyesRotateX: [-3 *
|
|
6215
|
+
eyesRotateX: [-3 * h + 0.1],
|
|
6216
6216
|
eyesRotateY: [-5 * g],
|
|
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(f));
|
|
6225
6225
|
}
|
|
6226
6226
|
}
|
|
6227
6227
|
/**
|
|
@@ -6236,21 +6236,21 @@ class Be {
|
|
|
6236
6236
|
this.objectLeftEye.updateMatrixWorld(!0), this.objectRightEye.updateMatrixWorld(!0);
|
|
6237
6237
|
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);
|
|
6238
6238
|
l.project(this.camera);
|
|
6239
|
-
let
|
|
6240
|
-
t === null && (t =
|
|
6241
|
-
let u =
|
|
6242
|
-
|
|
6243
|
-
let
|
|
6239
|
+
let c = (l.x + 1) / 2 * i.width + i.left, r = -(l.y - 1) / 2 * i.height + i.top;
|
|
6240
|
+
t === null && (t = c), e === null && (e = r), te.copy(this.armature.quaternion), te.multiply(this.poseTarget.props["Hips.quaternion"]), te.multiply(this.poseTarget.props["Spine.quaternion"]), te.multiply(this.poseTarget.props["Spine1.quaternion"]), te.multiply(this.poseTarget.props["Spine2.quaternion"]), te.multiply(this.poseTarget.props["Neck.quaternion"]), te.multiply(this.poseTarget.props["Head.quaternion"]), Q.setFromQuaternion(te);
|
|
6241
|
+
let u = Q.x / (40 / 24), a = Q.y / (9 / 4), d = Math.min(0.4, Math.max(-0.4, this.camera.rotation.x)), h = Math.min(0.4, Math.max(-0.4, this.camera.rotation.y)), g = Math.max(window.innerWidth - c, c), b = Math.max(window.innerHeight - r, r), f = this.convertRange(e, [r - b, r + b], [-0.3, 0.6]) - u + d, w = this.convertRange(t, [c - g, c + g], [-0.8, 0.8]) - a + h;
|
|
6242
|
+
f = Math.min(0.6, Math.max(-0.3, f)), w = Math.min(0.8, Math.max(-0.8, w));
|
|
6243
|
+
let N = (Math.random() - 0.5) / 4, p = (Math.random() - 0.5) / 4;
|
|
6244
6244
|
if (n) {
|
|
6245
|
-
let
|
|
6246
|
-
|
|
6247
|
-
const
|
|
6245
|
+
let B = this.animQueue.findIndex((I) => I.template.name === "lookat");
|
|
6246
|
+
B !== -1 && this.animQueue.splice(B, 1);
|
|
6247
|
+
const F = {
|
|
6248
6248
|
name: "lookat",
|
|
6249
6249
|
dt: [750, n],
|
|
6250
6250
|
vs: {
|
|
6251
|
-
bodyRotateX: [
|
|
6252
|
-
bodyRotateY: [
|
|
6253
|
-
eyesRotateX: [-3 *
|
|
6251
|
+
bodyRotateX: [f + N],
|
|
6252
|
+
bodyRotateY: [w + p],
|
|
6253
|
+
eyesRotateX: [-3 * N + 0.1],
|
|
6254
6254
|
eyesRotateY: [-5 * p],
|
|
6255
6255
|
browInnerUp: [[0, 0.7]],
|
|
6256
6256
|
mouthLeft: [[0, 0.7]],
|
|
@@ -6259,7 +6259,7 @@ class Be {
|
|
|
6259
6259
|
headMove: [0]
|
|
6260
6260
|
}
|
|
6261
6261
|
};
|
|
6262
|
-
this.animQueue.push(this.animFactory(
|
|
6262
|
+
this.animQueue.push(this.animFactory(F));
|
|
6263
6263
|
}
|
|
6264
6264
|
}
|
|
6265
6265
|
/**
|
|
@@ -6277,9 +6277,9 @@ class Be {
|
|
|
6277
6277
|
s.setFromCamera(i, this.camera);
|
|
6278
6278
|
const o = s.intersectObject(this.armature);
|
|
6279
6279
|
if (o.length > 0) {
|
|
6280
|
-
const l = o[0].point,
|
|
6281
|
-
this.objectLeftArm.getWorldPosition(
|
|
6282
|
-
const u =
|
|
6280
|
+
const l = o[0].point, c = new y.Vector3(), r = new y.Vector3();
|
|
6281
|
+
this.objectLeftArm.getWorldPosition(c), this.objectRightArm.getWorldPosition(r);
|
|
6282
|
+
const u = c.distanceToSquared(l), a = r.distanceToSquared(l);
|
|
6283
6283
|
u < a ? (this.ikSolve({
|
|
6284
6284
|
iterations: 20,
|
|
6285
6285
|
root: "LeftShoulder",
|
|
@@ -6301,8 +6301,8 @@ class Be {
|
|
|
6301
6301
|
}, l, !1, 1e3), this.setValue("handFistRight", 0));
|
|
6302
6302
|
} else
|
|
6303
6303
|
["LeftArm", "LeftForeArm", "LeftHand", "RightArm", "RightForeArm", "RightHand"].forEach((l) => {
|
|
6304
|
-
let
|
|
6305
|
-
this.poseTarget.props[
|
|
6304
|
+
let c = l + ".quaternion";
|
|
6305
|
+
this.poseTarget.props[c].copy(this.getPoseTemplateProp(c)), this.poseTarget.props[c].t = this.animClock, this.poseTarget.props[c].d = 1e3;
|
|
6306
6306
|
});
|
|
6307
6307
|
return o.length > 0;
|
|
6308
6308
|
}
|
|
@@ -6421,10 +6421,10 @@ class Be {
|
|
|
6421
6421
|
async playAnimation(t, e = null, n = 10, i = 0, s = 0.01, o = !1) {
|
|
6422
6422
|
if (!this.armature) return;
|
|
6423
6423
|
this.positionWasLocked = !o, o ? console.log("Position locking disabled for FBX animation:", t) : (this.lockAvatarPosition(), console.log("Position locked immediately before FBX animation:", t));
|
|
6424
|
-
let l = this.animClips.find((
|
|
6424
|
+
let l = this.animClips.find((c) => c.url === t + "-" + i);
|
|
6425
6425
|
if (l) {
|
|
6426
|
-
let
|
|
6427
|
-
|
|
6426
|
+
let c = this.animQueue.find((a) => a.template.name === "pose");
|
|
6427
|
+
c && (c.ts[0] = 1 / 0), Object.entries(l.pose.props).forEach((a) => {
|
|
6428
6428
|
this.poseBase.props[a[0]] = a[1].clone(), this.poseTarget.props[a[0]] = a[1].clone(), this.poseTarget.props[a[0]].t = 0, this.poseTarget.props[a[0]].d = 1e3;
|
|
6429
6429
|
}), this.mixer ? console.log("Using existing mixer for FBX animation, preserving morph targets") : (this.mixer = new y.AnimationMixer(this.armature), console.log("Created new mixer for FBX animation")), this.mixer.addEventListener("finished", this.stopAnimation.bind(this), { once: !0 });
|
|
6430
6430
|
const r = Math.ceil(n / l.clip.duration), u = this.mixer.clipAction(l.clip);
|
|
@@ -6465,52 +6465,52 @@ class Be {
|
|
|
6465
6465
|
suggestion: "Make sure the file is a valid FBX file and the path is correct"
|
|
6466
6466
|
}), d.message && d.message.includes("version number") && (console.error("FBX Loader Error: Cannot find version number"), console.error("This error usually means:"), console.error("1. The file is not a valid FBX file (might be GLB, corrupted, or wrong format)"), console.error("2. The file might be corrupted"), console.error("3. The file path might be incorrect"), console.error("4. The server returned an HTML error page instead of the FBX file"), console.error("5. The file might not exist at that path"), console.error(""), console.error("Solution: Please verify:"), console.error(` - File exists at: ${t}`), console.error(" - File is a valid FBX binary file"), console.error(" - File path matches your public folder structure"), console.error(" - File is not corrupted"));
|
|
6467
6467
|
try {
|
|
6468
|
-
const
|
|
6468
|
+
const h = await fetch(t), g = h.headers.get("content-type"), b = await h.text();
|
|
6469
6469
|
console.error("Response details:", {
|
|
6470
|
-
status:
|
|
6470
|
+
status: h.status,
|
|
6471
6471
|
contentType: g,
|
|
6472
6472
|
firstBytes: b.substring(0, 100),
|
|
6473
6473
|
isHTML: b.trim().startsWith("<!DOCTYPE") || b.trim().startsWith("<html")
|
|
6474
6474
|
}), (b.trim().startsWith("<!DOCTYPE") || b.trim().startsWith("<html")) && console.error("The server returned an HTML page instead of an FBX file. The file path is likely incorrect.");
|
|
6475
|
-
} catch (
|
|
6476
|
-
console.error("Could not fetch file for debugging:",
|
|
6475
|
+
} catch (h) {
|
|
6476
|
+
console.error("Could not fetch file for debugging:", h);
|
|
6477
6477
|
}
|
|
6478
6478
|
return;
|
|
6479
6479
|
}
|
|
6480
6480
|
if (a && a.animations && a.animations[i]) {
|
|
6481
6481
|
let d = a.animations[i];
|
|
6482
|
-
const
|
|
6483
|
-
this.armature && this.armature.traverse((
|
|
6484
|
-
(
|
|
6482
|
+
const h = /* @__PURE__ */ new Set();
|
|
6483
|
+
this.armature && this.armature.traverse((x) => {
|
|
6484
|
+
(x.isBone || x.type === "Bone") && h.add(x.name);
|
|
6485
6485
|
});
|
|
6486
|
-
const g = /* @__PURE__ */ new Map(), b = (
|
|
6487
|
-
if (
|
|
6488
|
-
return
|
|
6489
|
-
let
|
|
6490
|
-
if (
|
|
6491
|
-
return
|
|
6492
|
-
const
|
|
6493
|
-
if (
|
|
6494
|
-
if (
|
|
6495
|
-
if (
|
|
6496
|
-
if (
|
|
6497
|
-
} else if (!
|
|
6486
|
+
const g = /* @__PURE__ */ new Map(), b = (x) => {
|
|
6487
|
+
if (h.has(x))
|
|
6488
|
+
return x;
|
|
6489
|
+
let k = x.replace(/^mixamorig/i, "").replace(/^CC_Base_/i, "").replace(/^RPM_/i, "");
|
|
6490
|
+
if (h.has(k))
|
|
6491
|
+
return k;
|
|
6492
|
+
const A = k.toLowerCase();
|
|
6493
|
+
if (A.includes("left") && A.includes("arm")) {
|
|
6494
|
+
if (A.includes("fore") || A.includes("lower")) {
|
|
6495
|
+
if (h.has("LeftForeArm")) return "LeftForeArm";
|
|
6496
|
+
if (h.has("LeftForearm")) return "LeftForearm";
|
|
6497
|
+
} else if (!A.includes("fore") && !A.includes("hand") && h.has("LeftArm"))
|
|
6498
6498
|
return "LeftArm";
|
|
6499
6499
|
}
|
|
6500
|
-
if (
|
|
6501
|
-
if (
|
|
6502
|
-
if (
|
|
6503
|
-
if (
|
|
6504
|
-
} else if (!
|
|
6500
|
+
if (A.includes("right") && A.includes("arm")) {
|
|
6501
|
+
if (A.includes("fore") || A.includes("lower")) {
|
|
6502
|
+
if (h.has("RightForeArm")) return "RightForeArm";
|
|
6503
|
+
if (h.has("RightForearm")) return "RightForearm";
|
|
6504
|
+
} else if (!A.includes("fore") && !A.includes("hand") && h.has("RightArm"))
|
|
6505
6505
|
return "RightArm";
|
|
6506
6506
|
}
|
|
6507
|
-
if (
|
|
6507
|
+
if (A.includes("left") && A.includes("hand") && !A.includes("index") && !A.includes("thumb") && !A.includes("middle") && !A.includes("ring") && !A.includes("pinky") && h.has("LeftHand"))
|
|
6508
6508
|
return "LeftHand";
|
|
6509
|
-
if (
|
|
6509
|
+
if (A.includes("right") && A.includes("hand") && !A.includes("index") && !A.includes("thumb") && !A.includes("middle") && !A.includes("ring") && !A.includes("pinky") && h.has("RightHand"))
|
|
6510
6510
|
return "RightHand";
|
|
6511
|
-
if (
|
|
6511
|
+
if (A.includes("left") && (A.includes("shoulder") || A.includes("clavicle")) && h.has("LeftShoulder"))
|
|
6512
6512
|
return "LeftShoulder";
|
|
6513
|
-
if (
|
|
6513
|
+
if (A.includes("right") && (A.includes("shoulder") || A.includes("clavicle")) && h.has("RightShoulder"))
|
|
6514
6514
|
return "RightShoulder";
|
|
6515
6515
|
const L = {
|
|
6516
6516
|
// Arm bones - exact matches
|
|
@@ -6552,70 +6552,70 @@ class Be {
|
|
|
6552
6552
|
Root: "Hips",
|
|
6553
6553
|
root: "Hips"
|
|
6554
6554
|
};
|
|
6555
|
-
if (L[
|
|
6556
|
-
const
|
|
6557
|
-
if (
|
|
6558
|
-
return
|
|
6555
|
+
if (L[k]) {
|
|
6556
|
+
const T = L[k];
|
|
6557
|
+
if (h.has(T))
|
|
6558
|
+
return T;
|
|
6559
6559
|
}
|
|
6560
|
-
for (const
|
|
6561
|
-
if (
|
|
6562
|
-
return
|
|
6563
|
-
for (const
|
|
6564
|
-
const
|
|
6565
|
-
if ((
|
|
6566
|
-
return
|
|
6560
|
+
for (const T of h)
|
|
6561
|
+
if (T.toLowerCase() === A)
|
|
6562
|
+
return T;
|
|
6563
|
+
for (const T of h) {
|
|
6564
|
+
const M = T.toLowerCase();
|
|
6565
|
+
if ((A.includes("left") && M.includes("left") || A.includes("right") && M.includes("right")) && (A.includes("arm") && M.includes("arm") && !M.includes("fore") || A.includes("forearm") && M.includes("forearm") || A.includes("hand") && M.includes("hand") && !M.includes("index") && !M.includes("thumb") || A.includes("shoulder") && M.includes("shoulder")))
|
|
6566
|
+
return T;
|
|
6567
6567
|
}
|
|
6568
6568
|
return null;
|
|
6569
|
-
},
|
|
6570
|
-
d.tracks.forEach((
|
|
6571
|
-
const
|
|
6572
|
-
|
|
6573
|
-
}), console.log("=== Ready Player Me Animation Bone Analysis ==="), console.log("FBX bone names:", Array.from(
|
|
6574
|
-
const
|
|
6575
|
-
(
|
|
6576
|
-
),
|
|
6577
|
-
(
|
|
6569
|
+
}, f = /* @__PURE__ */ new Set();
|
|
6570
|
+
d.tracks.forEach((x) => {
|
|
6571
|
+
const k = x.name.split(".");
|
|
6572
|
+
f.add(k[0]);
|
|
6573
|
+
}), 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(h).sort().join(", "));
|
|
6574
|
+
const w = Array.from(f).filter(
|
|
6575
|
+
(x) => x.toLowerCase().includes("arm") || x.toLowerCase().includes("hand") || x.toLowerCase().includes("shoulder")
|
|
6576
|
+
), N = Array.from(h).filter(
|
|
6577
|
+
(x) => x.includes("Arm") || x.includes("Hand") || x.includes("Shoulder")
|
|
6578
6578
|
);
|
|
6579
|
-
console.log("FBX arm/hand/shoulder bones:",
|
|
6580
|
-
const p = [],
|
|
6581
|
-
let
|
|
6582
|
-
if (d.tracks.forEach((
|
|
6583
|
-
const
|
|
6584
|
-
if (
|
|
6585
|
-
|
|
6579
|
+
console.log("FBX arm/hand/shoulder bones:", w.sort().join(", ")), console.log("Avatar arm/hand/shoulder bones:", N.sort().join(", "));
|
|
6580
|
+
const p = [], B = /* @__PURE__ */ new Set();
|
|
6581
|
+
let F = 0;
|
|
6582
|
+
if (d.tracks.forEach((x) => {
|
|
6583
|
+
const A = x.name.replaceAll("mixamorig", "").split("."), L = A[0], T = A[1], M = b(L);
|
|
6584
|
+
if (M && (M === "LeftShoulder" || M === "RightShoulder") && (T === "quaternion" || T === "rotation")) {
|
|
6585
|
+
F++;
|
|
6586
6586
|
return;
|
|
6587
6587
|
}
|
|
6588
|
-
if (
|
|
6589
|
-
const
|
|
6590
|
-
|
|
6588
|
+
if (M && T) {
|
|
6589
|
+
const j = `${M}.${T}`, Z = x.clone();
|
|
6590
|
+
Z.name = j, p.push(Z), L !== M && g.set(L, M);
|
|
6591
6591
|
} else
|
|
6592
|
-
|
|
6593
|
-
}),
|
|
6592
|
+
B.add(L), (L.toLowerCase().includes("arm") || L.toLowerCase().includes("hand") || L.toLowerCase().includes("shoulder")) && console.warn(`⚠️ Arm bone "${L}" could not be mapped to avatar skeleton`);
|
|
6593
|
+
}), F > 0 && console.log(`✓ Filtered out ${F} shoulder rotation track(s) to prevent high shoulders`), B.size > 0 && console.warn(`⚠️ ${B.size} bone(s) could not be mapped:`, Array.from(B).sort().join(", ")), p.length > 0) {
|
|
6594
6594
|
d = new y.AnimationClip(d.name, d.duration, p), console.log(`✓ Created animation with ${p.length} mapped tracks (from ${d.tracks.length} original tracks)`), g.size > 0 && console.log(
|
|
6595
6595
|
`✓ Mapped ${g.size} bone(s):`,
|
|
6596
|
-
Array.from(g.entries()).map(([
|
|
6596
|
+
Array.from(g.entries()).map(([k, A]) => `${k}→${A}`).join(", ")
|
|
6597
6597
|
);
|
|
6598
|
-
const
|
|
6599
|
-
(
|
|
6598
|
+
const x = Array.from(g.values()).filter(
|
|
6599
|
+
(k) => k.includes("Arm") || k.includes("Hand") || k.includes("Shoulder")
|
|
6600
6600
|
);
|
|
6601
|
-
|
|
6601
|
+
x.length > 0 ? console.log(`✓ Arm bones mapped: ${x.join(", ")}`) : console.warn("⚠️ No arm bones were mapped! This may cause arm rigging issues.");
|
|
6602
6602
|
} else
|
|
6603
6603
|
console.error("❌ No tracks could be mapped! Animation may not work correctly.");
|
|
6604
6604
|
const I = {};
|
|
6605
|
-
d.tracks.forEach((
|
|
6606
|
-
|
|
6607
|
-
const
|
|
6608
|
-
if (
|
|
6609
|
-
for (let
|
|
6610
|
-
|
|
6611
|
-
I[
|
|
6612
|
-
} else
|
|
6605
|
+
d.tracks.forEach((x) => {
|
|
6606
|
+
x.name = x.name.replaceAll("mixamorig", "");
|
|
6607
|
+
const k = x.name.split(".");
|
|
6608
|
+
if (k[1] === "position") {
|
|
6609
|
+
for (let A = 0; A < x.values.length; A++)
|
|
6610
|
+
x.values[A] = x.values[A] * s;
|
|
6611
|
+
I[x.name] = new y.Vector3(x.values[0], x.values[1], x.values[2]);
|
|
6612
|
+
} else k[1] === "quaternion" ? I[x.name] = new y.Quaternion(x.values[0], x.values[1], x.values[2], x.values[3]) : k[1] === "rotation" && (I[k[0] + ".quaternion"] = new y.Quaternion().setFromEuler(new y.Euler(x.values[0], x.values[1], x.values[2], "XYZ")).normalize());
|
|
6613
6613
|
});
|
|
6614
|
-
const
|
|
6615
|
-
I["Hips.position"] && (I["Hips.position"].y < 0.5 ?
|
|
6614
|
+
const D = { props: I };
|
|
6615
|
+
I["Hips.position"] && (I["Hips.position"].y < 0.5 ? D.lying = !0 : D.standing = !0), this.animClips.push({
|
|
6616
6616
|
url: t + "-" + i,
|
|
6617
6617
|
clip: d,
|
|
6618
|
-
pose:
|
|
6618
|
+
pose: D
|
|
6619
6619
|
}), this.playAnimation(t, e, n, i, s);
|
|
6620
6620
|
} else {
|
|
6621
6621
|
const d = "Animation " + t + " (ndx=" + i + ") not found";
|
|
@@ -6645,22 +6645,22 @@ class Be {
|
|
|
6645
6645
|
if (!this.armature) return;
|
|
6646
6646
|
let o = this.poseTemplates[t];
|
|
6647
6647
|
if (!o) {
|
|
6648
|
-
const l = this.animPoses.find((
|
|
6648
|
+
const l = this.animPoses.find((c) => c.url === t + "-" + i);
|
|
6649
6649
|
l && (o = l.pose);
|
|
6650
6650
|
}
|
|
6651
6651
|
if (o) {
|
|
6652
6652
|
this.poseName = t, this.mixer = null;
|
|
6653
|
-
let l = this.animQueue.find((
|
|
6653
|
+
let l = this.animQueue.find((c) => c.template.name === "pose");
|
|
6654
6654
|
l && (l.ts[0] = this.animClock + n * 1e3 + 2e3), this.setPoseFromTemplate(o);
|
|
6655
6655
|
} else {
|
|
6656
|
-
let
|
|
6657
|
-
if (
|
|
6658
|
-
let r =
|
|
6656
|
+
let c = await new De().loadAsync(t, e);
|
|
6657
|
+
if (c && c.animations && c.animations[i]) {
|
|
6658
|
+
let r = c.animations[i];
|
|
6659
6659
|
const u = {};
|
|
6660
6660
|
r.tracks.forEach((d) => {
|
|
6661
6661
|
d.name = d.name.replaceAll("mixamorig", "");
|
|
6662
|
-
const
|
|
6663
|
-
|
|
6662
|
+
const h = d.name.split(".");
|
|
6663
|
+
h[1] === "position" ? u[d.name] = new y.Vector3(d.values[0] * s, d.values[1] * s, d.values[2] * s) : h[1] === "quaternion" ? u[d.name] = new y.Quaternion(d.values[0], d.values[1], d.values[2], d.values[3]) : h[1] === "rotation" && (u[h[0] + ".quaternion"] = new y.Quaternion().setFromEuler(new y.Euler(d.values[0], d.values[1], d.values[2], "XYZ")).normalize());
|
|
6664
6664
|
});
|
|
6665
6665
|
const a = { props: u };
|
|
6666
6666
|
u["Hips.position"] && (u["Hips.position"].y < 0.5 ? a.lying = !0 : a.standing = !0), this.animPoses.push({
|
|
@@ -6692,10 +6692,10 @@ class Be {
|
|
|
6692
6692
|
let s = this.gestureTemplates[t];
|
|
6693
6693
|
if (s) {
|
|
6694
6694
|
this.gestureTimeout && (clearTimeout(this.gestureTimeout), this.gestureTimeout = null);
|
|
6695
|
-
let l = this.animQueue.findIndex((
|
|
6696
|
-
l !== -1 && (this.animQueue[l].ts = this.animQueue[l].ts.map((
|
|
6697
|
-
for (let [
|
|
6698
|
-
r.t = this.animClock, r.d = i, this.poseTarget.props.hasOwnProperty(
|
|
6695
|
+
let l = this.animQueue.findIndex((c) => c.template.name === "talkinghands");
|
|
6696
|
+
l !== -1 && (this.animQueue[l].ts = this.animQueue[l].ts.map((c) => 0)), this.gesture = this.propsToThreeObjects(s), n && (this.gesture = this.mirrorPose(this.gesture)), t === "namaste" && this.avatar.body === "M" && (this.gesture["RightArm.quaternion"].rotateTowards(new y.Quaternion(0, 1, 0, 0), -0.25), this.gesture["LeftArm.quaternion"].rotateTowards(new y.Quaternion(0, 1, 0, 0), -0.25));
|
|
6697
|
+
for (let [c, r] of Object.entries(this.gesture))
|
|
6698
|
+
r.t = this.animClock, r.d = i, this.poseTarget.props.hasOwnProperty(c) && (this.poseTarget.props[c].copy(r), this.poseTarget.props[c].t = this.animClock, this.poseTarget.props[c].d = i);
|
|
6699
6699
|
e && Number.isFinite(e) && (this.gestureTimeout = setTimeout(this.stopGesture.bind(this, i), 1e3 * e));
|
|
6700
6700
|
}
|
|
6701
6701
|
let o = this.animEmojis[t];
|
|
@@ -6703,15 +6703,15 @@ class Be {
|
|
|
6703
6703
|
this.lookAtCamera(500);
|
|
6704
6704
|
const l = this.animFactory(o);
|
|
6705
6705
|
if (l.gesture = !0, e && Number.isFinite(e)) {
|
|
6706
|
-
const
|
|
6706
|
+
const c = l.ts[0], u = l.ts[l.ts.length - 1] - c;
|
|
6707
6707
|
if (e * 1e3 - u > 0) {
|
|
6708
6708
|
const d = [];
|
|
6709
6709
|
for (let b = 1; b < l.ts.length; b++) d.push(l.ts[b] - l.ts[b - 1]);
|
|
6710
|
-
const
|
|
6711
|
-
l.ts = l.ts.map((b,
|
|
6710
|
+
const h = o.template?.rescale || d.map((b) => b / u), g = e * 1e3 - u;
|
|
6711
|
+
l.ts = l.ts.map((b, f, w) => f === 0 ? c : w[f - 1] + d[f - 1] + h[f - 1] * g);
|
|
6712
6712
|
} else {
|
|
6713
6713
|
const d = e * 1e3 / u;
|
|
6714
|
-
l.ts = l.ts.map((
|
|
6714
|
+
l.ts = l.ts.map((h) => c + d * (h - c));
|
|
6715
6715
|
}
|
|
6716
6716
|
}
|
|
6717
6717
|
this.animQueue.push(l);
|
|
@@ -6741,21 +6741,21 @@ class Be {
|
|
|
6741
6741
|
* @param {numeric} [d=null] If set, apply in d milliseconds
|
|
6742
6742
|
*/
|
|
6743
6743
|
ikSolve(t, e = null, n = !1, i = null) {
|
|
6744
|
-
const s = new y.Vector3(), o = new y.Vector3(), l = new y.Vector3(),
|
|
6745
|
-
|
|
6744
|
+
const s = new y.Vector3(), o = new y.Vector3(), l = new y.Vector3(), c = new y.Vector3(), r = new y.Quaternion(), u = new y.Vector3(), a = new y.Vector3(), d = new y.Vector3(), h = this.ikMesh.getObjectByName(t.root);
|
|
6745
|
+
h.position.setFromMatrixPosition(this.armature.getObjectByName(t.root).matrixWorld), h.quaternion.setFromRotationMatrix(this.armature.getObjectByName(t.root).matrixWorld), e && n && e.applyQuaternion(this.armature.quaternion).add(h.position);
|
|
6746
6746
|
const g = this.ikMesh.getObjectByName(t.effector), b = t.links;
|
|
6747
|
-
b.forEach((
|
|
6748
|
-
|
|
6749
|
-
}),
|
|
6750
|
-
const
|
|
6747
|
+
b.forEach((w) => {
|
|
6748
|
+
w.bone = this.ikMesh.getObjectByName(w.link), w.bone.quaternion.copy(this.getPoseTemplateProp(w.link + ".quaternion"));
|
|
6749
|
+
}), h.updateMatrixWorld(!0);
|
|
6750
|
+
const f = t.iterations || 10;
|
|
6751
6751
|
if (e)
|
|
6752
|
-
for (let
|
|
6753
|
-
let
|
|
6754
|
-
for (let p = 0,
|
|
6755
|
-
const
|
|
6756
|
-
|
|
6752
|
+
for (let w = 0; w < f; w++) {
|
|
6753
|
+
let N = !1;
|
|
6754
|
+
for (let p = 0, B = b.length; p < B; p++) {
|
|
6755
|
+
const F = b[p].bone;
|
|
6756
|
+
F.matrixWorld.decompose(c, r, u), r.invert(), o.setFromMatrixPosition(g.matrixWorld), l.subVectors(o, c), l.applyQuaternion(r), l.normalize(), s.subVectors(e, c), s.applyQuaternion(r), s.normalize();
|
|
6757
6757
|
let I = s.dot(l);
|
|
6758
|
-
I > 1 ? I = 1 : I < -1 && (I = -1), I = Math.acos(I), !(I < 1e-5) && (b[p].minAngle !== void 0 && I < b[p].minAngle && (I = b[p].minAngle), b[p].maxAngle !== void 0 && I > b[p].maxAngle && (I = b[p].maxAngle), a.crossVectors(l, s), a.normalize(),
|
|
6758
|
+
I > 1 ? I = 1 : I < -1 && (I = -1), I = Math.acos(I), !(I < 1e-5) && (b[p].minAngle !== void 0 && I < b[p].minAngle && (I = b[p].minAngle), b[p].maxAngle !== void 0 && I > b[p].maxAngle && (I = b[p].maxAngle), a.crossVectors(l, s), a.normalize(), te.setFromAxisAngle(a, I), F.quaternion.multiply(te), F.rotation.setFromVector3(d.setFromEuler(F.rotation).clamp(new y.Vector3(
|
|
6759
6759
|
b[p].minx !== void 0 ? b[p].minx : -1 / 0,
|
|
6760
6760
|
b[p].miny !== void 0 ? b[p].miny : -1 / 0,
|
|
6761
6761
|
b[p].minz !== void 0 ? b[p].minz : -1 / 0
|
|
@@ -6763,12 +6763,12 @@ class Be {
|
|
|
6763
6763
|
b[p].maxx !== void 0 ? b[p].maxx : 1 / 0,
|
|
6764
6764
|
b[p].maxy !== void 0 ? b[p].maxy : 1 / 0,
|
|
6765
6765
|
b[p].maxz !== void 0 ? b[p].maxz : 1 / 0
|
|
6766
|
-
))),
|
|
6766
|
+
))), F.updateMatrixWorld(!0), N = !0);
|
|
6767
6767
|
}
|
|
6768
|
-
if (!
|
|
6768
|
+
if (!N) break;
|
|
6769
6769
|
}
|
|
6770
|
-
i && b.forEach((
|
|
6771
|
-
this.poseTarget.props[
|
|
6770
|
+
i && b.forEach((w) => {
|
|
6771
|
+
this.poseTarget.props[w.link + ".quaternion"].copy(w.bone.quaternion), this.poseTarget.props[w.link + ".quaternion"].t = this.animClock, this.poseTarget.props[w.link + ".quaternion"].d = i;
|
|
6772
6772
|
});
|
|
6773
6773
|
}
|
|
6774
6774
|
/**
|
|
@@ -6778,7 +6778,7 @@ class Be {
|
|
|
6778
6778
|
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();
|
|
6779
6779
|
}
|
|
6780
6780
|
}
|
|
6781
|
-
const
|
|
6781
|
+
const Ae = {
|
|
6782
6782
|
apiKey: "sk_ace57ef3ef65a92b9d3bee2a00183b78ca790bc3e10964f2",
|
|
6783
6783
|
// Replace with your actual API key (should start with sk_)
|
|
6784
6784
|
endpoint: "https://api.elevenlabs.io/v1/text-to-speech",
|
|
@@ -6798,7 +6798,7 @@ const Ie = {
|
|
|
6798
6798
|
josh: "VR6AewLTigWG4xSOukaG"
|
|
6799
6799
|
// Male, American
|
|
6800
6800
|
}
|
|
6801
|
-
},
|
|
6801
|
+
}, Me = {
|
|
6802
6802
|
defaultVoice: "aura-2-thalia-en",
|
|
6803
6803
|
// Thalia (Female, English)
|
|
6804
6804
|
voices: {
|
|
@@ -6818,26 +6818,26 @@ const Ie = {
|
|
|
6818
6818
|
// Male, English - Powerful
|
|
6819
6819
|
}
|
|
6820
6820
|
};
|
|
6821
|
-
function
|
|
6821
|
+
function Pe() {
|
|
6822
6822
|
return {
|
|
6823
6823
|
service: "elevenlabs",
|
|
6824
|
-
endpoint:
|
|
6825
|
-
apiKey:
|
|
6826
|
-
defaultVoice:
|
|
6827
|
-
voices:
|
|
6824
|
+
endpoint: Ae.endpoint,
|
|
6825
|
+
apiKey: Ae.apiKey,
|
|
6826
|
+
defaultVoice: Ae.defaultVoice,
|
|
6827
|
+
voices: Ae.voices
|
|
6828
6828
|
};
|
|
6829
6829
|
}
|
|
6830
6830
|
function wt() {
|
|
6831
|
-
const
|
|
6832
|
-
return Object.entries(
|
|
6831
|
+
const G = Pe(), t = [];
|
|
6832
|
+
return Object.entries(G.voices).forEach(([e, n]) => {
|
|
6833
6833
|
t.push({
|
|
6834
6834
|
value: n,
|
|
6835
|
-
label: `${e.charAt(0).toUpperCase() + e.slice(1)} (${
|
|
6835
|
+
label: `${e.charAt(0).toUpperCase() + e.slice(1)} (${G.service})`
|
|
6836
6836
|
});
|
|
6837
6837
|
}), t;
|
|
6838
6838
|
}
|
|
6839
|
-
const Ve =
|
|
6840
|
-
avatarUrl:
|
|
6839
|
+
const Ve = Fe(({
|
|
6840
|
+
avatarUrl: G = "/avatars/brunette.glb",
|
|
6841
6841
|
avatarBody: t = "F",
|
|
6842
6842
|
mood: e = "neutral",
|
|
6843
6843
|
ttsLang: n = "en",
|
|
@@ -6845,139 +6845,139 @@ const Ve = Me(({
|
|
|
6845
6845
|
ttsVoice: s = null,
|
|
6846
6846
|
ttsApiKey: o = null,
|
|
6847
6847
|
bodyMovement: l = "idle",
|
|
6848
|
-
movementIntensity:
|
|
6848
|
+
movementIntensity: c = 0.5,
|
|
6849
6849
|
showFullAvatar: r = !0,
|
|
6850
6850
|
cameraView: u = "upper",
|
|
6851
6851
|
onReady: a = () => {
|
|
6852
6852
|
},
|
|
6853
6853
|
onLoading: d = () => {
|
|
6854
6854
|
},
|
|
6855
|
-
onError:
|
|
6855
|
+
onError: h = () => {
|
|
6856
6856
|
},
|
|
6857
6857
|
className: g = "",
|
|
6858
6858
|
style: b = {},
|
|
6859
|
-
animations:
|
|
6860
|
-
},
|
|
6861
|
-
const
|
|
6862
|
-
|
|
6863
|
-
|
|
6864
|
-
}, [
|
|
6865
|
-
|
|
6859
|
+
animations: f = {}
|
|
6860
|
+
}, w) => {
|
|
6861
|
+
const N = X(null), p = X(null), B = X(r), F = X(null), I = X(null), D = X(!1), x = X({ remainingText: null, originalText: null, options: null }), k = X([]), A = X(0), [L, T] = ae(!0), [M, j] = ae(null), [Z, ue] = ae(!1), [re, ge] = ae(!1);
|
|
6862
|
+
me(() => {
|
|
6863
|
+
D.current = re;
|
|
6864
|
+
}, [re]), me(() => {
|
|
6865
|
+
B.current = r;
|
|
6866
6866
|
}, [r]);
|
|
6867
|
-
const
|
|
6868
|
-
let
|
|
6869
|
-
|
|
6867
|
+
const ne = Pe(), ve = i || ne.service;
|
|
6868
|
+
let _;
|
|
6869
|
+
ve === "browser" ? _ = {
|
|
6870
6870
|
service: "browser",
|
|
6871
6871
|
endpoint: "",
|
|
6872
6872
|
apiKey: null,
|
|
6873
6873
|
defaultVoice: "Google US English"
|
|
6874
|
-
} :
|
|
6874
|
+
} : ve === "elevenlabs" ? _ = {
|
|
6875
6875
|
service: "elevenlabs",
|
|
6876
6876
|
endpoint: "https://api.elevenlabs.io/v1/text-to-speech",
|
|
6877
|
-
apiKey: o ||
|
|
6878
|
-
defaultVoice: s ||
|
|
6879
|
-
voices:
|
|
6880
|
-
} :
|
|
6877
|
+
apiKey: o || ne.apiKey,
|
|
6878
|
+
defaultVoice: s || ne.defaultVoice || Ae.defaultVoice,
|
|
6879
|
+
voices: ne.voices || Ae.voices
|
|
6880
|
+
} : ve === "deepgram" ? _ = {
|
|
6881
6881
|
service: "deepgram",
|
|
6882
6882
|
endpoint: "https://api.deepgram.com/v1/speak",
|
|
6883
|
-
apiKey: o ||
|
|
6884
|
-
defaultVoice: s ||
|
|
6885
|
-
voices:
|
|
6886
|
-
} :
|
|
6887
|
-
...
|
|
6883
|
+
apiKey: o || ne.apiKey,
|
|
6884
|
+
defaultVoice: s || ne.defaultVoice || Me.defaultVoice,
|
|
6885
|
+
voices: ne.voices || Me.voices
|
|
6886
|
+
} : _ = {
|
|
6887
|
+
...ne,
|
|
6888
6888
|
// Override API key if provided via props
|
|
6889
|
-
apiKey: o !== null ? o :
|
|
6889
|
+
apiKey: o !== null ? o : ne.apiKey
|
|
6890
6890
|
};
|
|
6891
6891
|
const v = {
|
|
6892
|
-
url:
|
|
6892
|
+
url: G,
|
|
6893
6893
|
body: t,
|
|
6894
6894
|
avatarMood: e,
|
|
6895
|
-
ttsLang:
|
|
6896
|
-
ttsVoice: s ||
|
|
6895
|
+
ttsLang: ve === "browser" ? "en-US" : n,
|
|
6896
|
+
ttsVoice: s || _.defaultVoice,
|
|
6897
6897
|
lipsyncLang: "en",
|
|
6898
6898
|
showFullAvatar: r,
|
|
6899
6899
|
bodyMovement: l,
|
|
6900
|
-
movementIntensity:
|
|
6900
|
+
movementIntensity: c
|
|
6901
6901
|
}, R = {
|
|
6902
|
-
ttsEndpoint:
|
|
6903
|
-
ttsApikey:
|
|
6904
|
-
ttsService:
|
|
6902
|
+
ttsEndpoint: _.endpoint,
|
|
6903
|
+
ttsApikey: _.apiKey,
|
|
6904
|
+
ttsService: ve,
|
|
6905
6905
|
lipsyncModules: ["en"],
|
|
6906
6906
|
cameraView: u
|
|
6907
|
-
},
|
|
6908
|
-
if (!(!
|
|
6907
|
+
}, P = U(async () => {
|
|
6908
|
+
if (!(!N.current || p.current))
|
|
6909
6909
|
try {
|
|
6910
|
-
if (
|
|
6911
|
-
if (
|
|
6912
|
-
const
|
|
6913
|
-
d(
|
|
6910
|
+
if (T(!0), j(null), p.current = new Be(N.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), f && Object.keys(f).length > 0 && (p.current.customAnimations = f), await p.current.showAvatar(v, ($) => {
|
|
6911
|
+
if ($.lengthComputable) {
|
|
6912
|
+
const oe = Math.min(100, Math.round($.loaded / $.total * 100));
|
|
6913
|
+
d(oe);
|
|
6914
6914
|
}
|
|
6915
|
-
}), await new Promise((
|
|
6916
|
-
const
|
|
6917
|
-
p.current.lipsync && Object.keys(p.current.lipsync).length > 0 ?
|
|
6915
|
+
}), await new Promise(($) => {
|
|
6916
|
+
const oe = () => {
|
|
6917
|
+
p.current.lipsync && Object.keys(p.current.lipsync).length > 0 ? $() : setTimeout(oe, 100);
|
|
6918
6918
|
};
|
|
6919
|
-
|
|
6919
|
+
oe();
|
|
6920
6920
|
}), p.current && p.current.setShowFullAvatar)
|
|
6921
6921
|
try {
|
|
6922
6922
|
p.current.setShowFullAvatar(r);
|
|
6923
|
-
} catch (
|
|
6924
|
-
console.warn("Error setting full body mode on initialization:",
|
|
6923
|
+
} catch ($) {
|
|
6924
|
+
console.warn("Error setting full body mode on initialization:", $);
|
|
6925
6925
|
}
|
|
6926
|
-
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()),
|
|
6926
|
+
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()), T(!1), ue(!0), a(p.current);
|
|
6927
6927
|
const V = () => {
|
|
6928
6928
|
document.visibilityState === "visible" ? p.current?.start() : p.current?.stop();
|
|
6929
6929
|
};
|
|
6930
6930
|
return document.addEventListener("visibilitychange", V), () => {
|
|
6931
6931
|
document.removeEventListener("visibilitychange", V);
|
|
6932
6932
|
};
|
|
6933
|
-
} catch (
|
|
6934
|
-
console.error("Error initializing TalkingHead:",
|
|
6933
|
+
} catch (C) {
|
|
6934
|
+
console.error("Error initializing TalkingHead:", C), j(C.message || "Failed to initialize avatar"), T(!1), h(C);
|
|
6935
6935
|
}
|
|
6936
|
-
}, [
|
|
6937
|
-
|
|
6936
|
+
}, [G, t, e, n, i, s, o, r, l, c, u]);
|
|
6937
|
+
me(() => (P(), () => {
|
|
6938
6938
|
p.current && (p.current.stop(), p.current.dispose(), p.current = null);
|
|
6939
|
-
}), [
|
|
6940
|
-
if (!
|
|
6941
|
-
const
|
|
6942
|
-
for (const
|
|
6939
|
+
}), [P]), me(() => {
|
|
6940
|
+
if (!N.current || !p.current) return;
|
|
6941
|
+
const C = new ResizeObserver(($) => {
|
|
6942
|
+
for (const oe of $)
|
|
6943
6943
|
p.current && p.current.onResize && p.current.onResize();
|
|
6944
6944
|
});
|
|
6945
|
-
|
|
6945
|
+
C.observe(N.current);
|
|
6946
6946
|
const V = () => {
|
|
6947
6947
|
p.current && p.current.onResize && p.current.onResize();
|
|
6948
6948
|
};
|
|
6949
6949
|
return window.addEventListener("resize", V), () => {
|
|
6950
|
-
|
|
6950
|
+
C.disconnect(), window.removeEventListener("resize", V);
|
|
6951
6951
|
};
|
|
6952
|
-
}, [
|
|
6953
|
-
const
|
|
6952
|
+
}, [Z]);
|
|
6953
|
+
const O = U(async () => {
|
|
6954
6954
|
if (p.current && p.current.audioCtx)
|
|
6955
6955
|
try {
|
|
6956
6956
|
(p.current.audioCtx.state === "suspended" || p.current.audioCtx.state === "interrupted") && (await p.current.audioCtx.resume(), console.log("Audio context resumed"));
|
|
6957
|
-
} catch (
|
|
6958
|
-
console.warn("Failed to resume audio context:",
|
|
6957
|
+
} catch (C) {
|
|
6958
|
+
console.warn("Failed to resume audio context:", C);
|
|
6959
6959
|
}
|
|
6960
|
-
}, []), W =
|
|
6961
|
-
if (p.current &&
|
|
6960
|
+
}, []), W = U(async (C, V = {}) => {
|
|
6961
|
+
if (p.current && Z)
|
|
6962
6962
|
try {
|
|
6963
|
-
I.current && (clearInterval(I.current), I.current = null),
|
|
6964
|
-
const
|
|
6965
|
-
|
|
6966
|
-
const
|
|
6963
|
+
I.current && (clearInterval(I.current), I.current = null), F.current = { text: C, options: V }, x.current = { remainingText: null, originalText: null, options: null };
|
|
6964
|
+
const $ = /[!\.\?\n\p{Extended_Pictographic}]/ug, oe = C.split($).map((S) => S.trim()).filter((S) => S.length > 0);
|
|
6965
|
+
k.current = oe, A.current = 0, ge(!1), D.current = !1, await O();
|
|
6966
|
+
const ye = {
|
|
6967
6967
|
...V,
|
|
6968
6968
|
lipsyncLang: V.lipsyncLang || v.lipsyncLang || "en"
|
|
6969
6969
|
};
|
|
6970
6970
|
if (V.onSpeechEnd && p.current) {
|
|
6971
|
-
const
|
|
6972
|
-
let
|
|
6973
|
-
const
|
|
6974
|
-
let
|
|
6975
|
-
|
|
6976
|
-
if (
|
|
6971
|
+
const S = p.current;
|
|
6972
|
+
let H = null, Y = 0;
|
|
6973
|
+
const ee = 1200;
|
|
6974
|
+
let se = !1;
|
|
6975
|
+
H = setInterval(() => {
|
|
6976
|
+
if (Y++, D.current)
|
|
6977
6977
|
return;
|
|
6978
|
-
if (
|
|
6979
|
-
if (
|
|
6980
|
-
|
|
6978
|
+
if (Y > ee) {
|
|
6979
|
+
if (H && (clearInterval(H), H = null, I.current = null), !se && !D.current) {
|
|
6980
|
+
se = !0;
|
|
6981
6981
|
try {
|
|
6982
6982
|
V.onSpeechEnd();
|
|
6983
6983
|
} catch (Oe) {
|
|
@@ -6986,148 +6986,148 @@ const Ve = Me(({
|
|
|
6986
6986
|
}
|
|
6987
6987
|
return;
|
|
6988
6988
|
}
|
|
6989
|
-
const
|
|
6990
|
-
|
|
6991
|
-
if (
|
|
6992
|
-
|
|
6989
|
+
const le = !S.speechQueue || S.speechQueue.length === 0, Ce = !S.audioPlaylist || S.audioPlaylist.length === 0;
|
|
6990
|
+
S && S.isSpeaking === !1 && le && Ce && S.isAudioPlaying === !1 && !se && !D.current && setTimeout(() => {
|
|
6991
|
+
if (S && !D.current && S.isSpeaking === !1 && (!S.speechQueue || S.speechQueue.length === 0) && (!S.audioPlaylist || S.audioPlaylist.length === 0) && S.isAudioPlaying === !1 && !se && !D.current) {
|
|
6992
|
+
se = !0, H && (clearInterval(H), H = null, I.current = null);
|
|
6993
6993
|
try {
|
|
6994
6994
|
V.onSpeechEnd();
|
|
6995
|
-
} catch (
|
|
6996
|
-
console.error("Error in onSpeechEnd callback:",
|
|
6995
|
+
} catch (Xe) {
|
|
6996
|
+
console.error("Error in onSpeechEnd callback:", Xe);
|
|
6997
6997
|
}
|
|
6998
6998
|
}
|
|
6999
6999
|
}, 100);
|
|
7000
|
-
}, 100), I.current =
|
|
7000
|
+
}, 100), I.current = H;
|
|
7001
7001
|
}
|
|
7002
|
-
p.current.lipsync && Object.keys(p.current.lipsync).length > 0 ? (p.current.setSlowdownRate && p.current.setSlowdownRate(1.05), p.current.speakText(
|
|
7003
|
-
await
|
|
7002
|
+
p.current.lipsync && Object.keys(p.current.lipsync).length > 0 ? (p.current.setSlowdownRate && p.current.setSlowdownRate(1.05), p.current.speakText(C, ye)) : setTimeout(async () => {
|
|
7003
|
+
await O(), p.current && p.current.lipsync && (p.current.setSlowdownRate && p.current.setSlowdownRate(1.05), p.current.speakText(C, ye));
|
|
7004
7004
|
}, 100);
|
|
7005
|
-
} catch (
|
|
7006
|
-
console.error("Error speaking text:",
|
|
7005
|
+
} catch ($) {
|
|
7006
|
+
console.error("Error speaking text:", $), j($.message || "Failed to speak text");
|
|
7007
7007
|
}
|
|
7008
|
-
}, [
|
|
7009
|
-
p.current && (p.current.stopSpeaking(), p.current.setSlowdownRate && p.current.setSlowdownRate(1),
|
|
7010
|
-
}, []),
|
|
7008
|
+
}, [Z, O, v.lipsyncLang]), ie = U(() => {
|
|
7009
|
+
p.current && (p.current.stopSpeaking(), p.current.setSlowdownRate && p.current.setSlowdownRate(1), F.current = null, ge(!1));
|
|
7010
|
+
}, []), K = U(() => {
|
|
7011
7011
|
if (p.current && p.current.pauseSpeaking) {
|
|
7012
|
-
const
|
|
7013
|
-
if (
|
|
7012
|
+
const C = p.current;
|
|
7013
|
+
if (C.isSpeaking || C.audioPlaylist && C.audioPlaylist.length > 0 || C.speechQueue && C.speechQueue.length > 0) {
|
|
7014
7014
|
I.current && (clearInterval(I.current), I.current = null);
|
|
7015
|
-
let
|
|
7016
|
-
if (
|
|
7017
|
-
const
|
|
7018
|
-
if (
|
|
7019
|
-
const
|
|
7020
|
-
|
|
7015
|
+
let $ = "";
|
|
7016
|
+
if (F.current && k.current.length > 0) {
|
|
7017
|
+
const oe = k.current.length, ye = C.speechQueue ? C.speechQueue.filter((ee) => ee && ee.text && Array.isArray(ee.text) && ee.text.length > 0).length : 0, S = C.audioPlaylist && C.audioPlaylist.length > 0, H = ye + (S ? 1 : 0), Y = oe - H;
|
|
7018
|
+
if (H > 0 && Y < oe && ($ = k.current.slice(Y).join(". ").trim(), !$ && ye > 0 && C.speechQueue)) {
|
|
7019
|
+
const se = C.speechQueue.filter((le) => le && le.text && Array.isArray(le.text) && le.text.length > 0).map((le) => le.text.map((Ce) => Ce.word || "").filter((Ce) => Ce.length > 0).join(" ")).filter((le) => le.length > 0).join(" ");
|
|
7020
|
+
se && se.trim() && ($ = se.trim());
|
|
7021
7021
|
}
|
|
7022
7022
|
}
|
|
7023
|
-
|
|
7024
|
-
remainingText:
|
|
7025
|
-
originalText:
|
|
7026
|
-
options:
|
|
7027
|
-
}),
|
|
7023
|
+
F.current && (x.current = {
|
|
7024
|
+
remainingText: $ || null,
|
|
7025
|
+
originalText: F.current.text,
|
|
7026
|
+
options: F.current.options
|
|
7027
|
+
}), C.speechQueue && (C.speechQueue.length = 0), p.current.pauseSpeaking(), D.current = !0, ge(!0);
|
|
7028
7028
|
}
|
|
7029
7029
|
}
|
|
7030
|
-
}, []),
|
|
7031
|
-
if (!p.current || !
|
|
7030
|
+
}, []), J = U(async () => {
|
|
7031
|
+
if (!p.current || !re)
|
|
7032
7032
|
return;
|
|
7033
|
-
let
|
|
7034
|
-
if (
|
|
7035
|
-
|
|
7036
|
-
else if (
|
|
7037
|
-
|
|
7033
|
+
let C = "", V = {};
|
|
7034
|
+
if (x.current && x.current.remainingText)
|
|
7035
|
+
C = x.current.remainingText, V = x.current.options || {}, x.current = { remainingText: null, originalText: null, options: null };
|
|
7036
|
+
else if (F.current && F.current.text)
|
|
7037
|
+
C = F.current.text, V = F.current.options || {};
|
|
7038
7038
|
else {
|
|
7039
|
-
console.warn("Resume called but no paused speech found"),
|
|
7039
|
+
console.warn("Resume called but no paused speech found"), ge(!1), D.current = !1;
|
|
7040
7040
|
return;
|
|
7041
7041
|
}
|
|
7042
|
-
|
|
7043
|
-
const
|
|
7042
|
+
ge(!1), D.current = !1, await O();
|
|
7043
|
+
const $ = {
|
|
7044
7044
|
...V,
|
|
7045
7045
|
lipsyncLang: V.lipsyncLang || v.lipsyncLang || "en"
|
|
7046
7046
|
};
|
|
7047
7047
|
try {
|
|
7048
|
-
await W(
|
|
7049
|
-
} catch (
|
|
7050
|
-
console.error("Error resuming speech:",
|
|
7048
|
+
await W(C, $);
|
|
7049
|
+
} catch (oe) {
|
|
7050
|
+
console.error("Error resuming speech:", oe), ge(!1), D.current = !1;
|
|
7051
7051
|
}
|
|
7052
|
-
}, [
|
|
7053
|
-
p.current && p.current.setMood(
|
|
7054
|
-
}, []),
|
|
7055
|
-
p.current && p.current.setSlowdownRate && p.current.setSlowdownRate(
|
|
7056
|
-
}, []),
|
|
7052
|
+
}, [O, re, W, v]), Le = U((C) => {
|
|
7053
|
+
p.current && p.current.setMood(C);
|
|
7054
|
+
}, []), ke = U((C) => {
|
|
7055
|
+
p.current && p.current.setSlowdownRate && p.current.setSlowdownRate(C);
|
|
7056
|
+
}, []), Se = U((C, V = !1) => {
|
|
7057
7057
|
if (p.current && p.current.playAnimation) {
|
|
7058
|
-
if (
|
|
7058
|
+
if (f && f[C] && (C = f[C]), p.current.setShowFullAvatar)
|
|
7059
7059
|
try {
|
|
7060
|
-
p.current.setShowFullAvatar(
|
|
7061
|
-
} catch (
|
|
7062
|
-
console.warn("Error setting full body mode:",
|
|
7060
|
+
p.current.setShowFullAvatar(B.current);
|
|
7061
|
+
} catch (oe) {
|
|
7062
|
+
console.warn("Error setting full body mode:", oe);
|
|
7063
7063
|
}
|
|
7064
|
-
if (
|
|
7064
|
+
if (C.includes("."))
|
|
7065
7065
|
try {
|
|
7066
|
-
p.current.playAnimation(
|
|
7067
|
-
} catch (
|
|
7068
|
-
console.warn(`Failed to play ${
|
|
7066
|
+
p.current.playAnimation(C, null, 10, 0, 0.01, V);
|
|
7067
|
+
} catch (oe) {
|
|
7068
|
+
console.warn(`Failed to play ${C}:`, oe);
|
|
7069
7069
|
try {
|
|
7070
7070
|
p.current.setBodyMovement("idle");
|
|
7071
|
-
} catch (
|
|
7072
|
-
console.warn("Fallback animation also failed:",
|
|
7071
|
+
} catch (ye) {
|
|
7072
|
+
console.warn("Fallback animation also failed:", ye);
|
|
7073
7073
|
}
|
|
7074
7074
|
}
|
|
7075
7075
|
else {
|
|
7076
|
-
const
|
|
7077
|
-
let
|
|
7078
|
-
for (const
|
|
7076
|
+
const oe = [".fbx", ".glb", ".gltf"];
|
|
7077
|
+
let ye = !1;
|
|
7078
|
+
for (const S of oe)
|
|
7079
7079
|
try {
|
|
7080
|
-
p.current.playAnimation(
|
|
7080
|
+
p.current.playAnimation(C + S, null, 10, 0, 0.01, V), ye = !0;
|
|
7081
7081
|
break;
|
|
7082
7082
|
} catch {
|
|
7083
7083
|
}
|
|
7084
|
-
if (!
|
|
7085
|
-
console.warn("Animation not found:",
|
|
7084
|
+
if (!ye) {
|
|
7085
|
+
console.warn("Animation not found:", C);
|
|
7086
7086
|
try {
|
|
7087
7087
|
p.current.setBodyMovement("idle");
|
|
7088
|
-
} catch (
|
|
7089
|
-
console.warn("Fallback animation also failed:",
|
|
7088
|
+
} catch (S) {
|
|
7089
|
+
console.warn("Fallback animation also failed:", S);
|
|
7090
7090
|
}
|
|
7091
7091
|
}
|
|
7092
7092
|
}
|
|
7093
7093
|
}
|
|
7094
|
-
}, [
|
|
7094
|
+
}, [f]), we = U(() => {
|
|
7095
7095
|
p.current && p.current.onResize && p.current.onResize();
|
|
7096
7096
|
}, []);
|
|
7097
|
-
return
|
|
7097
|
+
return Ee(w, () => ({
|
|
7098
7098
|
speakText: W,
|
|
7099
|
-
stopSpeaking:
|
|
7100
|
-
pauseSpeaking:
|
|
7101
|
-
resumeSpeaking:
|
|
7102
|
-
resumeAudioContext:
|
|
7103
|
-
setMood:
|
|
7104
|
-
setTimingAdjustment:
|
|
7105
|
-
playAnimation:
|
|
7106
|
-
isReady:
|
|
7107
|
-
isPaused:
|
|
7099
|
+
stopSpeaking: ie,
|
|
7100
|
+
pauseSpeaking: K,
|
|
7101
|
+
resumeSpeaking: J,
|
|
7102
|
+
resumeAudioContext: O,
|
|
7103
|
+
setMood: Le,
|
|
7104
|
+
setTimingAdjustment: ke,
|
|
7105
|
+
playAnimation: Se,
|
|
7106
|
+
isReady: Z,
|
|
7107
|
+
isPaused: re,
|
|
7108
7108
|
talkingHead: p.current,
|
|
7109
|
-
handleResize:
|
|
7110
|
-
setBodyMovement: (
|
|
7109
|
+
handleResize: we,
|
|
7110
|
+
setBodyMovement: (C) => {
|
|
7111
7111
|
if (p.current && p.current.setShowFullAvatar && p.current.setBodyMovement)
|
|
7112
7112
|
try {
|
|
7113
|
-
p.current.setShowFullAvatar(
|
|
7113
|
+
p.current.setShowFullAvatar(B.current), p.current.setBodyMovement(C);
|
|
7114
7114
|
} catch (V) {
|
|
7115
7115
|
console.warn("Error setting body movement:", V);
|
|
7116
7116
|
}
|
|
7117
7117
|
},
|
|
7118
|
-
setMovementIntensity: (
|
|
7118
|
+
setMovementIntensity: (C) => p.current?.setMovementIntensity(C),
|
|
7119
7119
|
playRandomDance: () => {
|
|
7120
7120
|
if (p.current && p.current.setShowFullAvatar && p.current.playRandomDance)
|
|
7121
7121
|
try {
|
|
7122
|
-
p.current.setShowFullAvatar(
|
|
7123
|
-
} catch (
|
|
7124
|
-
console.warn("Error playing random dance:",
|
|
7122
|
+
p.current.setShowFullAvatar(B.current), p.current.playRandomDance();
|
|
7123
|
+
} catch (C) {
|
|
7124
|
+
console.warn("Error playing random dance:", C);
|
|
7125
7125
|
}
|
|
7126
7126
|
},
|
|
7127
|
-
playReaction: (
|
|
7127
|
+
playReaction: (C) => {
|
|
7128
7128
|
if (p.current && p.current.setShowFullAvatar && p.current.playReaction)
|
|
7129
7129
|
try {
|
|
7130
|
-
p.current.setShowFullAvatar(
|
|
7130
|
+
p.current.setShowFullAvatar(B.current), p.current.playReaction(C);
|
|
7131
7131
|
} catch (V) {
|
|
7132
7132
|
console.warn("Error playing reaction:", V);
|
|
7133
7133
|
}
|
|
@@ -7135,15 +7135,15 @@ const Ve = Me(({
|
|
|
7135
7135
|
playCelebration: () => {
|
|
7136
7136
|
if (p.current && p.current.setShowFullAvatar && p.current.playCelebration)
|
|
7137
7137
|
try {
|
|
7138
|
-
p.current.setShowFullAvatar(
|
|
7139
|
-
} catch (
|
|
7140
|
-
console.warn("Error playing celebration:",
|
|
7138
|
+
p.current.setShowFullAvatar(B.current), p.current.playCelebration();
|
|
7139
|
+
} catch (C) {
|
|
7140
|
+
console.warn("Error playing celebration:", C);
|
|
7141
7141
|
}
|
|
7142
7142
|
},
|
|
7143
|
-
setShowFullAvatar: (
|
|
7143
|
+
setShowFullAvatar: (C) => {
|
|
7144
7144
|
if (p.current && p.current.setShowFullAvatar)
|
|
7145
7145
|
try {
|
|
7146
|
-
|
|
7146
|
+
B.current = C, p.current.setShowFullAvatar(C);
|
|
7147
7147
|
} catch (V) {
|
|
7148
7148
|
console.warn("Error setting showFullAvatar:", V);
|
|
7149
7149
|
}
|
|
@@ -7152,19 +7152,19 @@ const Ve = Me(({
|
|
|
7152
7152
|
if (p.current && p.current.lockAvatarPosition)
|
|
7153
7153
|
try {
|
|
7154
7154
|
p.current.lockAvatarPosition();
|
|
7155
|
-
} catch (
|
|
7156
|
-
console.warn("Error locking avatar position:",
|
|
7155
|
+
} catch (C) {
|
|
7156
|
+
console.warn("Error locking avatar position:", C);
|
|
7157
7157
|
}
|
|
7158
7158
|
},
|
|
7159
7159
|
unlockAvatarPosition: () => {
|
|
7160
7160
|
if (p.current && p.current.unlockAvatarPosition)
|
|
7161
7161
|
try {
|
|
7162
7162
|
p.current.unlockAvatarPosition();
|
|
7163
|
-
} catch (
|
|
7164
|
-
console.warn("Error unlocking avatar position:",
|
|
7163
|
+
} catch (C) {
|
|
7164
|
+
console.warn("Error unlocking avatar position:", C);
|
|
7165
7165
|
}
|
|
7166
7166
|
}
|
|
7167
|
-
})), /* @__PURE__ */
|
|
7167
|
+
})), /* @__PURE__ */ fe(
|
|
7168
7168
|
"div",
|
|
7169
7169
|
{
|
|
7170
7170
|
className: `talking-head-avatar ${g}`,
|
|
@@ -7175,10 +7175,10 @@ const Ve = Me(({
|
|
|
7175
7175
|
...b
|
|
7176
7176
|
},
|
|
7177
7177
|
children: [
|
|
7178
|
-
/* @__PURE__ */
|
|
7178
|
+
/* @__PURE__ */ q(
|
|
7179
7179
|
"div",
|
|
7180
7180
|
{
|
|
7181
|
-
ref:
|
|
7181
|
+
ref: N,
|
|
7182
7182
|
className: "talking-head-viewer",
|
|
7183
7183
|
style: {
|
|
7184
7184
|
width: "100%",
|
|
@@ -7187,7 +7187,7 @@ const Ve = Me(({
|
|
|
7187
7187
|
}
|
|
7188
7188
|
}
|
|
7189
7189
|
),
|
|
7190
|
-
L && /* @__PURE__ */
|
|
7190
|
+
L && /* @__PURE__ */ q("div", { className: "loading-overlay", style: {
|
|
7191
7191
|
position: "absolute",
|
|
7192
7192
|
top: "50%",
|
|
7193
7193
|
left: "50%",
|
|
@@ -7196,7 +7196,7 @@ const Ve = Me(({
|
|
|
7196
7196
|
fontSize: "18px",
|
|
7197
7197
|
zIndex: 10
|
|
7198
7198
|
}, children: "Loading avatar..." }),
|
|
7199
|
-
|
|
7199
|
+
M && /* @__PURE__ */ q("div", { className: "error-overlay", style: {
|
|
7200
7200
|
position: "absolute",
|
|
7201
7201
|
top: "50%",
|
|
7202
7202
|
left: "50%",
|
|
@@ -7207,14 +7207,14 @@ const Ve = Me(({
|
|
|
7207
7207
|
zIndex: 10,
|
|
7208
7208
|
padding: "20px",
|
|
7209
7209
|
borderRadius: "8px"
|
|
7210
|
-
}, children:
|
|
7210
|
+
}, children: M })
|
|
7211
7211
|
]
|
|
7212
7212
|
}
|
|
7213
7213
|
);
|
|
7214
7214
|
});
|
|
7215
7215
|
Ve.displayName = "TalkingHeadAvatar";
|
|
7216
|
-
const
|
|
7217
|
-
text:
|
|
7216
|
+
const gt = Fe(({
|
|
7217
|
+
text: G = "Hello! I'm a talking avatar. How are you today?",
|
|
7218
7218
|
onLoading: t = () => {
|
|
7219
7219
|
},
|
|
7220
7220
|
onError: e = () => {
|
|
@@ -7225,23 +7225,23 @@ const pt = Me(({
|
|
|
7225
7225
|
style: s = {},
|
|
7226
7226
|
avatarConfig: o = {}
|
|
7227
7227
|
}, l) => {
|
|
7228
|
-
const
|
|
7228
|
+
const c = X(null), r = X(null), [u, a] = ae(!0), [d, h] = ae(null), [g, b] = ae(!1), f = Pe(), w = o.ttsService || f.service, N = w === "browser" ? {
|
|
7229
7229
|
endpoint: "",
|
|
7230
7230
|
apiKey: null,
|
|
7231
7231
|
defaultVoice: "Google US English"
|
|
7232
7232
|
} : {
|
|
7233
|
-
...
|
|
7233
|
+
...f,
|
|
7234
7234
|
// Override API key if provided via avatarConfig
|
|
7235
|
-
apiKey: o.ttsApiKey !== void 0 && o.ttsApiKey !== null ? o.ttsApiKey :
|
|
7235
|
+
apiKey: o.ttsApiKey !== void 0 && o.ttsApiKey !== null ? o.ttsApiKey : f.apiKey,
|
|
7236
7236
|
// Override endpoint for ElevenLabs if service is explicitly set
|
|
7237
|
-
endpoint:
|
|
7237
|
+
endpoint: w === "elevenlabs" && o.ttsApiKey ? "https://api.elevenlabs.io/v1/text-to-speech" : f.endpoint
|
|
7238
7238
|
}, p = {
|
|
7239
7239
|
url: "/avatars/brunette.glb",
|
|
7240
7240
|
// Use brunette avatar (working glTF file)
|
|
7241
7241
|
body: "F",
|
|
7242
7242
|
avatarMood: "neutral",
|
|
7243
|
-
ttsLang:
|
|
7244
|
-
ttsVoice: o.ttsVoice ||
|
|
7243
|
+
ttsLang: w === "browser" ? "en-US" : "en",
|
|
7244
|
+
ttsVoice: o.ttsVoice || N.defaultVoice,
|
|
7245
7245
|
lipsyncLang: "en",
|
|
7246
7246
|
// English lip-sync
|
|
7247
7247
|
showFullAvatar: !0,
|
|
@@ -7249,123 +7249,123 @@ const pt = Me(({
|
|
|
7249
7249
|
bodyMovement: "idle",
|
|
7250
7250
|
movementIntensity: 0.5,
|
|
7251
7251
|
...o
|
|
7252
|
-
},
|
|
7253
|
-
ttsEndpoint:
|
|
7254
|
-
ttsApikey:
|
|
7255
|
-
ttsService:
|
|
7252
|
+
}, B = {
|
|
7253
|
+
ttsEndpoint: N.endpoint,
|
|
7254
|
+
ttsApikey: N.apiKey,
|
|
7255
|
+
ttsService: w,
|
|
7256
7256
|
lipsyncModules: ["en"],
|
|
7257
7257
|
cameraView: "upper"
|
|
7258
|
-
},
|
|
7259
|
-
if (!(!
|
|
7258
|
+
}, F = U(async () => {
|
|
7259
|
+
if (!(!c.current || r.current))
|
|
7260
7260
|
try {
|
|
7261
|
-
if (a(!0),
|
|
7262
|
-
if (
|
|
7263
|
-
const
|
|
7264
|
-
t(
|
|
7261
|
+
if (a(!0), h(null), r.current = new Be(c.current, B), await r.current.showAvatar(p, (M) => {
|
|
7262
|
+
if (M.lengthComputable) {
|
|
7263
|
+
const j = Math.min(100, Math.round(M.loaded / M.total * 100));
|
|
7264
|
+
t(j);
|
|
7265
7265
|
}
|
|
7266
7266
|
}), r.current.morphs && r.current.morphs.length > 0) {
|
|
7267
|
-
const
|
|
7268
|
-
console.log("Available morph targets:", Object.keys(
|
|
7269
|
-
const
|
|
7270
|
-
console.log("Viseme morph targets found:",
|
|
7267
|
+
const M = r.current.morphs[0].morphTargetDictionary;
|
|
7268
|
+
console.log("Available morph targets:", Object.keys(M));
|
|
7269
|
+
const j = Object.keys(M).filter((Z) => Z.startsWith("viseme_"));
|
|
7270
|
+
console.log("Viseme morph targets found:", j), j.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"));
|
|
7271
7271
|
}
|
|
7272
|
-
if (await new Promise((
|
|
7273
|
-
const
|
|
7274
|
-
r.current.lipsync && Object.keys(r.current.lipsync).length > 0 ? (console.log("Lip-sync modules loaded:", Object.keys(r.current.lipsync)),
|
|
7272
|
+
if (await new Promise((M) => {
|
|
7273
|
+
const j = () => {
|
|
7274
|
+
r.current.lipsync && Object.keys(r.current.lipsync).length > 0 ? (console.log("Lip-sync modules loaded:", Object.keys(r.current.lipsync)), M()) : (console.log("Waiting for lip-sync modules to load..."), setTimeout(j, 100));
|
|
7275
7275
|
};
|
|
7276
|
-
|
|
7276
|
+
j();
|
|
7277
7277
|
}), r.current && r.current.setShowFullAvatar)
|
|
7278
7278
|
try {
|
|
7279
7279
|
r.current.setShowFullAvatar(!0), console.log("Avatar initialized in full body mode");
|
|
7280
|
-
} catch (
|
|
7281
|
-
console.warn("Error setting full body mode on initialization:",
|
|
7280
|
+
} catch (M) {
|
|
7281
|
+
console.warn("Error setting full body mode on initialization:", M);
|
|
7282
7282
|
}
|
|
7283
7283
|
a(!1), b(!0), n(r.current);
|
|
7284
|
-
const
|
|
7284
|
+
const T = () => {
|
|
7285
7285
|
document.visibilityState === "visible" ? r.current?.start() : r.current?.stop();
|
|
7286
7286
|
};
|
|
7287
|
-
return document.addEventListener("visibilitychange",
|
|
7288
|
-
document.removeEventListener("visibilitychange",
|
|
7287
|
+
return document.addEventListener("visibilitychange", T), () => {
|
|
7288
|
+
document.removeEventListener("visibilitychange", T);
|
|
7289
7289
|
};
|
|
7290
7290
|
} catch (L) {
|
|
7291
|
-
console.error("Error initializing TalkingHead:", L),
|
|
7291
|
+
console.error("Error initializing TalkingHead:", L), h(L.message || "Failed to initialize avatar"), a(!1), e(L);
|
|
7292
7292
|
}
|
|
7293
7293
|
}, []);
|
|
7294
|
-
|
|
7294
|
+
me(() => (F(), () => {
|
|
7295
7295
|
r.current && (r.current.stop(), r.current.dispose(), r.current = null);
|
|
7296
|
-
}), [
|
|
7297
|
-
const I =
|
|
7296
|
+
}), [F]);
|
|
7297
|
+
const I = U((L) => {
|
|
7298
7298
|
if (r.current && g)
|
|
7299
7299
|
try {
|
|
7300
7300
|
console.log("Speaking text:", L), 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(L)) : (console.warn("Lip-sync modules not ready, waiting..."), setTimeout(() => {
|
|
7301
7301
|
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(L)) : console.error("Lip-sync still not ready after waiting");
|
|
7302
7302
|
}, 500));
|
|
7303
|
-
} catch (
|
|
7304
|
-
console.error("Error speaking text:",
|
|
7303
|
+
} catch (T) {
|
|
7304
|
+
console.error("Error speaking text:", T), h(T.message || "Failed to speak text");
|
|
7305
7305
|
}
|
|
7306
7306
|
else
|
|
7307
7307
|
console.warn("Avatar not ready for speaking. isReady:", g, "talkingHeadRef:", !!r.current);
|
|
7308
|
-
}, [g, p]),
|
|
7308
|
+
}, [g, p]), D = U(() => {
|
|
7309
7309
|
r.current && (r.current.stopSpeaking(), r.current.setSlowdownRate && (r.current.setSlowdownRate(1), console.log("Reset timing to normal")));
|
|
7310
|
-
}, []),
|
|
7310
|
+
}, []), x = U((L) => {
|
|
7311
7311
|
r.current && r.current.setMood(L);
|
|
7312
|
-
}, []),
|
|
7312
|
+
}, []), k = U((L) => {
|
|
7313
7313
|
r.current && r.current.setSlowdownRate && (r.current.setSlowdownRate(L), console.log("Timing adjustment set to:", L));
|
|
7314
|
-
}, []),
|
|
7314
|
+
}, []), A = U((L, T = !1) => {
|
|
7315
7315
|
if (r.current && r.current.playAnimation) {
|
|
7316
7316
|
if (r.current.setShowFullAvatar)
|
|
7317
7317
|
try {
|
|
7318
7318
|
r.current.setShowFullAvatar(!0);
|
|
7319
|
-
} catch (
|
|
7320
|
-
console.warn("Error setting full body mode:",
|
|
7319
|
+
} catch (j) {
|
|
7320
|
+
console.warn("Error setting full body mode:", j);
|
|
7321
7321
|
}
|
|
7322
7322
|
if (L.includes("."))
|
|
7323
7323
|
try {
|
|
7324
|
-
r.current.playAnimation(L, null, 10, 0, 0.01,
|
|
7325
|
-
} catch (
|
|
7326
|
-
console.log(`Failed to play ${L}:`,
|
|
7324
|
+
r.current.playAnimation(L, null, 10, 0, 0.01, T), console.log("Playing animation:", L);
|
|
7325
|
+
} catch (j) {
|
|
7326
|
+
console.log(`Failed to play ${L}:`, j);
|
|
7327
7327
|
try {
|
|
7328
7328
|
r.current.setBodyMovement("idle"), console.log("Fallback to idle animation");
|
|
7329
|
-
} catch (
|
|
7330
|
-
console.warn("Fallback animation also failed:",
|
|
7329
|
+
} catch (Z) {
|
|
7330
|
+
console.warn("Fallback animation also failed:", Z);
|
|
7331
7331
|
}
|
|
7332
7332
|
}
|
|
7333
7333
|
else {
|
|
7334
|
-
const
|
|
7335
|
-
let
|
|
7336
|
-
for (const
|
|
7334
|
+
const j = [".fbx", ".glb", ".gltf"];
|
|
7335
|
+
let Z = !1;
|
|
7336
|
+
for (const ue of j)
|
|
7337
7337
|
try {
|
|
7338
|
-
r.current.playAnimation(L +
|
|
7338
|
+
r.current.playAnimation(L + ue, null, 10, 0, 0.01, T), console.log("Playing animation:", L + ue), Z = !0;
|
|
7339
7339
|
break;
|
|
7340
7340
|
} catch {
|
|
7341
|
-
console.log(`Failed to play ${L}${
|
|
7341
|
+
console.log(`Failed to play ${L}${ue}, trying next format...`);
|
|
7342
7342
|
}
|
|
7343
|
-
if (!
|
|
7343
|
+
if (!Z) {
|
|
7344
7344
|
console.warn("Animation system not available or animation not found:", L);
|
|
7345
7345
|
try {
|
|
7346
7346
|
r.current.setBodyMovement("idle"), console.log("Fallback to idle animation");
|
|
7347
|
-
} catch (
|
|
7348
|
-
console.warn("Fallback animation also failed:",
|
|
7347
|
+
} catch (ue) {
|
|
7348
|
+
console.warn("Fallback animation also failed:", ue);
|
|
7349
7349
|
}
|
|
7350
7350
|
}
|
|
7351
7351
|
}
|
|
7352
7352
|
} else
|
|
7353
7353
|
console.warn("Animation system not available or animation not found:", L);
|
|
7354
7354
|
}, []);
|
|
7355
|
-
return
|
|
7355
|
+
return Ee(l, () => ({
|
|
7356
7356
|
speakText: I,
|
|
7357
|
-
stopSpeaking:
|
|
7358
|
-
setMood:
|
|
7359
|
-
setTimingAdjustment:
|
|
7360
|
-
playAnimation:
|
|
7357
|
+
stopSpeaking: D,
|
|
7358
|
+
setMood: x,
|
|
7359
|
+
setTimingAdjustment: k,
|
|
7360
|
+
playAnimation: A,
|
|
7361
7361
|
isReady: g,
|
|
7362
7362
|
talkingHead: r.current,
|
|
7363
7363
|
setBodyMovement: (L) => {
|
|
7364
7364
|
if (r.current && r.current.setShowFullAvatar && r.current.setBodyMovement)
|
|
7365
7365
|
try {
|
|
7366
7366
|
r.current.setShowFullAvatar(!0), r.current.setBodyMovement(L), console.log("Body movement set with full body mode:", L);
|
|
7367
|
-
} catch (
|
|
7368
|
-
console.warn("Error setting body movement:",
|
|
7367
|
+
} catch (T) {
|
|
7368
|
+
console.warn("Error setting body movement:", T);
|
|
7369
7369
|
}
|
|
7370
7370
|
},
|
|
7371
7371
|
setMovementIntensity: (L) => r.current?.setMovementIntensity(L),
|
|
@@ -7381,8 +7381,8 @@ const pt = Me(({
|
|
|
7381
7381
|
if (r.current && r.current.setShowFullAvatar && r.current.playReaction)
|
|
7382
7382
|
try {
|
|
7383
7383
|
r.current.setShowFullAvatar(!0), r.current.playReaction(L), console.log("Reaction played with full body mode:", L);
|
|
7384
|
-
} catch (
|
|
7385
|
-
console.warn("Error playing reaction:",
|
|
7384
|
+
} catch (T) {
|
|
7385
|
+
console.warn("Error playing reaction:", T);
|
|
7386
7386
|
}
|
|
7387
7387
|
},
|
|
7388
7388
|
playCelebration: () => {
|
|
@@ -7397,8 +7397,8 @@ const pt = Me(({
|
|
|
7397
7397
|
if (r.current && r.current.setShowFullAvatar)
|
|
7398
7398
|
try {
|
|
7399
7399
|
r.current.setShowFullAvatar(L), console.log("Show full avatar set to:", L);
|
|
7400
|
-
} catch (
|
|
7401
|
-
console.warn("Error setting showFullAvatar:",
|
|
7400
|
+
} catch (T) {
|
|
7401
|
+
console.warn("Error setting showFullAvatar:", T);
|
|
7402
7402
|
}
|
|
7403
7403
|
},
|
|
7404
7404
|
lockAvatarPosition: () => {
|
|
@@ -7417,11 +7417,11 @@ const pt = Me(({
|
|
|
7417
7417
|
console.warn("Error unlocking avatar position:", L);
|
|
7418
7418
|
}
|
|
7419
7419
|
}
|
|
7420
|
-
})), /* @__PURE__ */
|
|
7421
|
-
/* @__PURE__ */
|
|
7420
|
+
})), /* @__PURE__ */ fe("div", { className: `talking-head-container ${i}`, style: s, children: [
|
|
7421
|
+
/* @__PURE__ */ q(
|
|
7422
7422
|
"div",
|
|
7423
7423
|
{
|
|
7424
|
-
ref:
|
|
7424
|
+
ref: c,
|
|
7425
7425
|
className: "talking-head-viewer",
|
|
7426
7426
|
style: {
|
|
7427
7427
|
width: "100%",
|
|
@@ -7430,7 +7430,7 @@ const pt = Me(({
|
|
|
7430
7430
|
}
|
|
7431
7431
|
}
|
|
7432
7432
|
),
|
|
7433
|
-
u && /* @__PURE__ */
|
|
7433
|
+
u && /* @__PURE__ */ q("div", { className: "loading-overlay", style: {
|
|
7434
7434
|
position: "absolute",
|
|
7435
7435
|
top: "50%",
|
|
7436
7436
|
left: "50%",
|
|
@@ -7439,7 +7439,7 @@ const pt = Me(({
|
|
|
7439
7439
|
fontSize: "18px",
|
|
7440
7440
|
zIndex: 10
|
|
7441
7441
|
}, children: "Loading avatar..." }),
|
|
7442
|
-
d && /* @__PURE__ */
|
|
7442
|
+
d && /* @__PURE__ */ q("div", { className: "error-overlay", style: {
|
|
7443
7443
|
position: "absolute",
|
|
7444
7444
|
top: "50%",
|
|
7445
7445
|
left: "50%",
|
|
@@ -7453,11 +7453,11 @@ const pt = Me(({
|
|
|
7453
7453
|
}, children: d })
|
|
7454
7454
|
] });
|
|
7455
7455
|
});
|
|
7456
|
-
|
|
7457
|
-
async function
|
|
7456
|
+
gt.displayName = "TalkingHeadComponent";
|
|
7457
|
+
async function Ge(G) {
|
|
7458
7458
|
try {
|
|
7459
|
-
console.log(`📥 Loading animation manifest from: ${
|
|
7460
|
-
const t = await fetch(
|
|
7459
|
+
console.log(`📥 Loading animation manifest from: ${G}`);
|
|
7460
|
+
const t = await fetch(G);
|
|
7461
7461
|
if (!t.ok)
|
|
7462
7462
|
throw new Error(`Failed to fetch manifest: ${t.status} ${t.statusText}`);
|
|
7463
7463
|
const e = await t.json();
|
|
@@ -7472,8 +7472,8 @@ async function gt(Z) {
|
|
|
7472
7472
|
return console.error("❌ Failed to load animation manifest:", t), {};
|
|
7473
7473
|
}
|
|
7474
7474
|
}
|
|
7475
|
-
const yt =
|
|
7476
|
-
text:
|
|
7475
|
+
const yt = Fe(({
|
|
7476
|
+
text: G = null,
|
|
7477
7477
|
avatarUrl: t = "/avatars/brunette.glb",
|
|
7478
7478
|
avatarBody: e = "F",
|
|
7479
7479
|
mood: n = "neutral",
|
|
@@ -7481,253 +7481,253 @@ const yt = Me(({
|
|
|
7481
7481
|
ttsService: s = null,
|
|
7482
7482
|
ttsVoice: o = null,
|
|
7483
7483
|
ttsApiKey: l = null,
|
|
7484
|
-
bodyMovement:
|
|
7484
|
+
bodyMovement: c = "idle",
|
|
7485
7485
|
movementIntensity: r = 0.5,
|
|
7486
7486
|
showFullAvatar: u = !1,
|
|
7487
7487
|
cameraView: a = "upper",
|
|
7488
7488
|
onReady: d = () => {
|
|
7489
7489
|
},
|
|
7490
|
-
onLoading:
|
|
7490
|
+
onLoading: h = () => {
|
|
7491
7491
|
},
|
|
7492
7492
|
onError: g = () => {
|
|
7493
7493
|
},
|
|
7494
7494
|
onSpeechEnd: b = () => {
|
|
7495
7495
|
},
|
|
7496
|
-
className:
|
|
7497
|
-
style:
|
|
7498
|
-
animations:
|
|
7496
|
+
className: f = "",
|
|
7497
|
+
style: w = {},
|
|
7498
|
+
animations: N = {},
|
|
7499
7499
|
autoAnimationGroup: p = null,
|
|
7500
7500
|
// e.g., "talking" - will randomly select from this group when speaking
|
|
7501
|
-
autoIdleGroup:
|
|
7501
|
+
autoIdleGroup: B = null,
|
|
7502
7502
|
// e.g., "idle" - will randomly select from this group when idle
|
|
7503
|
-
autoSpeak:
|
|
7503
|
+
autoSpeak: F = !1
|
|
7504
7504
|
}, I) => {
|
|
7505
|
-
const
|
|
7506
|
-
|
|
7507
|
-
|
|
7508
|
-
}, [
|
|
7505
|
+
const D = X(null), x = X(null), k = X(u), A = X(null), L = X(null), T = X(!1), M = X({ remainingText: null, originalText: null, options: null }), j = X([]), [Z, ue] = ae(!0), [re, ge] = ae(null), [ne, ve] = ae(!1), [_, v] = ae(!1), [R, P] = ae(N), O = X(null);
|
|
7506
|
+
me(() => {
|
|
7507
|
+
T.current = _;
|
|
7508
|
+
}, [_]), me(() => {
|
|
7509
7509
|
(async () => {
|
|
7510
|
-
if (
|
|
7510
|
+
if (N.manifest)
|
|
7511
7511
|
try {
|
|
7512
|
-
console.log("🔄 Loading animations from manifest:",
|
|
7513
|
-
const
|
|
7514
|
-
|
|
7515
|
-
male: Object.keys(
|
|
7516
|
-
female: Object.keys(
|
|
7517
|
-
shared: Object.keys(
|
|
7512
|
+
console.log("🔄 Loading animations from manifest:", N.manifest);
|
|
7513
|
+
const H = await Ge(N.manifest);
|
|
7514
|
+
P(H), console.log("✅ Animations loaded and set:", H), H._genderSpecific ? console.log("👥 Gender-specific animations detected:", {
|
|
7515
|
+
male: Object.keys(H._genderSpecific.male || {}),
|
|
7516
|
+
female: Object.keys(H._genderSpecific.female || {}),
|
|
7517
|
+
shared: Object.keys(H._genderSpecific.shared || {})
|
|
7518
7518
|
}) : console.log("⚠️ No gender-specific animations found in manifest");
|
|
7519
|
-
} catch (
|
|
7520
|
-
console.error("❌ Failed to load animation manifest:",
|
|
7519
|
+
} catch (H) {
|
|
7520
|
+
console.error("❌ Failed to load animation manifest:", H), P(N);
|
|
7521
7521
|
}
|
|
7522
7522
|
else
|
|
7523
|
-
console.log("📝 Using animations from props (no manifest):",
|
|
7523
|
+
console.log("📝 Using animations from props (no manifest):", N), P(N);
|
|
7524
7524
|
})();
|
|
7525
|
-
}, [
|
|
7526
|
-
|
|
7525
|
+
}, [N]), me(() => {
|
|
7526
|
+
k.current = u;
|
|
7527
7527
|
}, [u]);
|
|
7528
|
-
const W =
|
|
7529
|
-
let
|
|
7530
|
-
|
|
7528
|
+
const W = Pe(), ie = s || W.service;
|
|
7529
|
+
let K;
|
|
7530
|
+
ie === "browser" ? K = {
|
|
7531
7531
|
service: "browser",
|
|
7532
7532
|
endpoint: "",
|
|
7533
7533
|
apiKey: null,
|
|
7534
7534
|
defaultVoice: "Google US English"
|
|
7535
|
-
} :
|
|
7535
|
+
} : ie === "elevenlabs" ? K = {
|
|
7536
7536
|
service: "elevenlabs",
|
|
7537
7537
|
endpoint: "https://api.elevenlabs.io/v1/text-to-speech",
|
|
7538
7538
|
apiKey: l || W.apiKey,
|
|
7539
|
-
defaultVoice: o || W.defaultVoice ||
|
|
7540
|
-
voices: W.voices ||
|
|
7541
|
-
} :
|
|
7539
|
+
defaultVoice: o || W.defaultVoice || Ae.defaultVoice,
|
|
7540
|
+
voices: W.voices || Ae.voices
|
|
7541
|
+
} : ie === "deepgram" ? K = {
|
|
7542
7542
|
service: "deepgram",
|
|
7543
7543
|
endpoint: "https://api.deepgram.com/v1/speak",
|
|
7544
7544
|
apiKey: l || W.apiKey,
|
|
7545
|
-
defaultVoice: o || W.defaultVoice ||
|
|
7546
|
-
voices: W.voices ||
|
|
7547
|
-
} :
|
|
7545
|
+
defaultVoice: o || W.defaultVoice || Me.defaultVoice,
|
|
7546
|
+
voices: W.voices || Me.voices
|
|
7547
|
+
} : K = {
|
|
7548
7548
|
...W,
|
|
7549
7549
|
apiKey: l !== null ? l : W.apiKey
|
|
7550
7550
|
};
|
|
7551
|
-
const
|
|
7551
|
+
const J = {
|
|
7552
7552
|
url: t,
|
|
7553
7553
|
body: e,
|
|
7554
7554
|
avatarMood: n,
|
|
7555
|
-
ttsLang:
|
|
7556
|
-
ttsVoice: o ||
|
|
7555
|
+
ttsLang: ie === "browser" ? "en-US" : i,
|
|
7556
|
+
ttsVoice: o || K.defaultVoice,
|
|
7557
7557
|
lipsyncLang: "en",
|
|
7558
7558
|
showFullAvatar: u,
|
|
7559
|
-
bodyMovement:
|
|
7559
|
+
bodyMovement: c,
|
|
7560
7560
|
movementIntensity: r
|
|
7561
|
-
},
|
|
7562
|
-
ttsEndpoint:
|
|
7563
|
-
ttsApikey:
|
|
7564
|
-
ttsService:
|
|
7561
|
+
}, Le = {
|
|
7562
|
+
ttsEndpoint: K.endpoint,
|
|
7563
|
+
ttsApikey: K.apiKey,
|
|
7564
|
+
ttsService: ie,
|
|
7565
7565
|
lipsyncModules: ["en"],
|
|
7566
7566
|
cameraView: a
|
|
7567
|
-
},
|
|
7568
|
-
if (!(!
|
|
7567
|
+
}, ke = U(async () => {
|
|
7568
|
+
if (!(!D.current || x.current))
|
|
7569
7569
|
try {
|
|
7570
|
-
|
|
7571
|
-
url:
|
|
7572
|
-
body:
|
|
7573
|
-
avatarMood:
|
|
7574
|
-
}), await
|
|
7575
|
-
if (
|
|
7576
|
-
const
|
|
7577
|
-
|
|
7570
|
+
ue(!0), ge(null), x.current = new Be(D.current, Le), console.log("Avatar config being passed:", {
|
|
7571
|
+
url: J.url,
|
|
7572
|
+
body: J.body,
|
|
7573
|
+
avatarMood: J.avatarMood
|
|
7574
|
+
}), await x.current.showAvatar(J, (H) => {
|
|
7575
|
+
if (H.lengthComputable) {
|
|
7576
|
+
const Y = Math.min(100, Math.round(H.loaded / H.total * 100));
|
|
7577
|
+
h(Y);
|
|
7578
7578
|
}
|
|
7579
|
-
}),
|
|
7580
|
-
const
|
|
7581
|
-
document.visibilityState === "visible" ?
|
|
7579
|
+
}), x.current?.avatar && console.log("Avatar body after initialization:", x.current.avatar.body), ue(!1), ve(!0), d(x.current);
|
|
7580
|
+
const S = () => {
|
|
7581
|
+
document.visibilityState === "visible" ? x.current?.start() : x.current?.stop();
|
|
7582
7582
|
};
|
|
7583
|
-
return document.addEventListener("visibilitychange",
|
|
7584
|
-
document.removeEventListener("visibilitychange",
|
|
7583
|
+
return document.addEventListener("visibilitychange", S), () => {
|
|
7584
|
+
document.removeEventListener("visibilitychange", S);
|
|
7585
7585
|
};
|
|
7586
|
-
} catch (
|
|
7587
|
-
console.error("Error initializing TalkingHead:",
|
|
7586
|
+
} catch (S) {
|
|
7587
|
+
console.error("Error initializing TalkingHead:", S), ge(S.message || "Failed to initialize avatar"), ue(!1), g(S);
|
|
7588
7588
|
}
|
|
7589
7589
|
}, []);
|
|
7590
|
-
|
|
7591
|
-
|
|
7592
|
-
}), [
|
|
7593
|
-
const
|
|
7594
|
-
if (
|
|
7590
|
+
me(() => (ke(), () => {
|
|
7591
|
+
x.current && (x.current.stop(), x.current.dispose(), x.current = null);
|
|
7592
|
+
}), [ke]);
|
|
7593
|
+
const Se = U(async () => {
|
|
7594
|
+
if (x.current)
|
|
7595
7595
|
try {
|
|
7596
|
-
const
|
|
7597
|
-
|
|
7598
|
-
} catch (
|
|
7599
|
-
console.warn("Failed to resume audio context:",
|
|
7596
|
+
const S = x.current.audioCtx || x.current.audioContext;
|
|
7597
|
+
S && (S.state === "suspended" || S.state === "interrupted") && (await S.resume(), console.log("Audio context resumed"));
|
|
7598
|
+
} catch (S) {
|
|
7599
|
+
console.warn("Failed to resume audio context:", S);
|
|
7600
7600
|
}
|
|
7601
|
-
}, []),
|
|
7601
|
+
}, []), we = U((S) => {
|
|
7602
7602
|
if (!R)
|
|
7603
7603
|
return console.warn("No animations loaded"), null;
|
|
7604
|
-
let
|
|
7604
|
+
let H = null;
|
|
7605
7605
|
if (R._genderSpecific) {
|
|
7606
|
-
const
|
|
7607
|
-
|
|
7606
|
+
const ee = (e?.toUpperCase() || "F") === "M" ? "male" : "female", se = R._genderSpecific[ee];
|
|
7607
|
+
se && se[S] ? (H = se[S], console.log(`Using ${ee} animations for "${S}":`, H)) : R._genderSpecific.shared && R._genderSpecific.shared[S] && (H = R._genderSpecific.shared[S], console.log(`Using shared animations for "${S}":`, H));
|
|
7608
7608
|
}
|
|
7609
|
-
if (!
|
|
7610
|
-
if (console.warn(`Animation group "${
|
|
7611
|
-
const
|
|
7612
|
-
console.warn(`Gender-specific groups (${
|
|
7609
|
+
if (!H && R[S] && (H = R[S], console.log(`Using root-level animations for "${S}":`, H)), !H) {
|
|
7610
|
+
if (console.warn(`Animation group "${S}" not found. Available groups:`, Object.keys(R).filter((Y) => Y !== "_genderSpecific")), R._genderSpecific) {
|
|
7611
|
+
const ee = (e?.toUpperCase() || "F") === "M" ? "male" : "female";
|
|
7612
|
+
console.warn(`Gender-specific groups (${ee}):`, Object.keys(R._genderSpecific[ee] || {}));
|
|
7613
7613
|
}
|
|
7614
7614
|
return null;
|
|
7615
7615
|
}
|
|
7616
|
-
if (Array.isArray(
|
|
7617
|
-
const
|
|
7618
|
-
return
|
|
7616
|
+
if (Array.isArray(H) && H.length > 0) {
|
|
7617
|
+
const Y = Math.floor(Math.random() * H.length);
|
|
7618
|
+
return H[Y];
|
|
7619
7619
|
}
|
|
7620
|
-
return typeof
|
|
7621
|
-
}, [R, e]),
|
|
7622
|
-
if (!
|
|
7620
|
+
return typeof H == "string" ? H : (console.warn(`Animation group "${S}" is not a valid format (expected array or string):`, H), null);
|
|
7621
|
+
}, [R, e]), C = U((S, H = !1) => {
|
|
7622
|
+
if (!x.current)
|
|
7623
7623
|
return console.warn("TalkingHead not initialized yet"), null;
|
|
7624
|
-
const
|
|
7625
|
-
if (
|
|
7624
|
+
const Y = we(S);
|
|
7625
|
+
if (Y)
|
|
7626
7626
|
try {
|
|
7627
|
-
return
|
|
7628
|
-
} catch (
|
|
7629
|
-
return console.error(`❌ Failed to play random animation from "${
|
|
7627
|
+
return x.current.playAnimation(Y, null, 10, 0, 0.01, H), console.log(`✅ Playing random animation from "${S}" group:`, Y), Y;
|
|
7628
|
+
} catch (ee) {
|
|
7629
|
+
return console.error(`❌ Failed to play random animation from "${S}" group:`, ee), null;
|
|
7630
7630
|
}
|
|
7631
7631
|
else
|
|
7632
|
-
console.warn(`⚠️ No animation found for group "${
|
|
7632
|
+
console.warn(`⚠️ No animation found for group "${S}"`);
|
|
7633
7633
|
return null;
|
|
7634
|
-
}, [
|
|
7635
|
-
if (!
|
|
7634
|
+
}, [we]), V = U(async (S, H = {}) => {
|
|
7635
|
+
if (!x.current || !ne) {
|
|
7636
7636
|
console.warn("Avatar not ready for speaking");
|
|
7637
7637
|
return;
|
|
7638
7638
|
}
|
|
7639
|
-
if (!
|
|
7639
|
+
if (!S || S.trim() === "") {
|
|
7640
7640
|
console.warn("No text provided to speak");
|
|
7641
7641
|
return;
|
|
7642
7642
|
}
|
|
7643
|
-
await
|
|
7644
|
-
const
|
|
7645
|
-
|
|
7646
|
-
const
|
|
7647
|
-
|
|
7648
|
-
const
|
|
7649
|
-
lipsyncLang:
|
|
7643
|
+
await Se();
|
|
7644
|
+
const Y = H.animationGroup || p;
|
|
7645
|
+
Y && !H.skipAnimation ? (console.log(`🎬 Attempting to play animation from group: "${Y}"`), console.log(`📊 Current avatarBody: "${e}", loadedAnimations:`, R), C(Y)) : console.log(`⏭️ Skipping animation (group: ${Y}, skipAnimation: ${H.skipAnimation})`), M.current = { remainingText: null, originalText: null, options: null }, j.current = [], A.current = { text: S, options: H }, L.current && (clearInterval(L.current), L.current = null), v(!1), T.current = !1;
|
|
7646
|
+
const ee = S.split(/[.!?]+/).filter((le) => le.trim().length > 0);
|
|
7647
|
+
j.current = ee;
|
|
7648
|
+
const se = {
|
|
7649
|
+
lipsyncLang: H.lipsyncLang || "en",
|
|
7650
7650
|
onSpeechEnd: () => {
|
|
7651
|
-
L.current && (clearInterval(L.current), L.current = null),
|
|
7651
|
+
L.current && (clearInterval(L.current), L.current = null), H.onSpeechEnd && H.onSpeechEnd(), b();
|
|
7652
7652
|
}
|
|
7653
7653
|
};
|
|
7654
7654
|
try {
|
|
7655
|
-
|
|
7656
|
-
} catch (
|
|
7657
|
-
console.error("Error speaking text:",
|
|
7655
|
+
x.current.speakText(S, se);
|
|
7656
|
+
} catch (le) {
|
|
7657
|
+
console.error("Error speaking text:", le), ge(le.message || "Failed to speak text");
|
|
7658
7658
|
}
|
|
7659
|
-
}, [
|
|
7660
|
-
|
|
7661
|
-
if (!
|
|
7659
|
+
}, [ne, b, Se, p, C]);
|
|
7660
|
+
me(() => {
|
|
7661
|
+
if (!ne || !B || !x.current)
|
|
7662
7662
|
return;
|
|
7663
|
-
|
|
7664
|
-
const
|
|
7665
|
-
|
|
7663
|
+
O.current && clearInterval(O.current);
|
|
7664
|
+
const S = () => {
|
|
7665
|
+
x.current && !T.current && C(B);
|
|
7666
7666
|
};
|
|
7667
|
-
return
|
|
7668
|
-
|
|
7667
|
+
return S(), O.current = setInterval(() => {
|
|
7668
|
+
S();
|
|
7669
7669
|
}, 12e3 + Math.random() * 3e3), () => {
|
|
7670
|
-
|
|
7670
|
+
O.current && (clearInterval(O.current), O.current = null);
|
|
7671
7671
|
};
|
|
7672
|
-
}, [
|
|
7673
|
-
|
|
7674
|
-
}, [
|
|
7675
|
-
const
|
|
7676
|
-
if (
|
|
7672
|
+
}, [ne, B, C]), me(() => {
|
|
7673
|
+
ne && G && F && x.current && V(G);
|
|
7674
|
+
}, [ne, G, F, V]);
|
|
7675
|
+
const $ = U(() => {
|
|
7676
|
+
if (x.current)
|
|
7677
7677
|
try {
|
|
7678
|
-
const
|
|
7679
|
-
if (
|
|
7678
|
+
const S = x.current.isSpeaking || !1, H = x.current.audioPlaylist || [], Y = x.current.speechQueue || [];
|
|
7679
|
+
if (S || H.length > 0 || Y.length > 0) {
|
|
7680
7680
|
L.current && (clearInterval(L.current), L.current = null);
|
|
7681
|
-
let
|
|
7682
|
-
|
|
7683
|
-
remainingText:
|
|
7684
|
-
originalText:
|
|
7685
|
-
options:
|
|
7686
|
-
},
|
|
7681
|
+
let ee = "";
|
|
7682
|
+
Y.length > 0 && (ee = Y.map((se) => se.text && Array.isArray(se.text) ? se.text.map((le) => le.word).join(" ") : se.text || "").join(" ")), M.current = {
|
|
7683
|
+
remainingText: ee || null,
|
|
7684
|
+
originalText: A.current?.text || null,
|
|
7685
|
+
options: A.current?.options || null
|
|
7686
|
+
}, x.current.speechQueue.length = 0, x.current.pauseSpeaking(), v(!0), T.current = !0;
|
|
7687
7687
|
}
|
|
7688
|
-
} catch (
|
|
7689
|
-
console.warn("Error pausing speech:",
|
|
7688
|
+
} catch (S) {
|
|
7689
|
+
console.warn("Error pausing speech:", S);
|
|
7690
7690
|
}
|
|
7691
|
-
}, []),
|
|
7692
|
-
if (!(!
|
|
7691
|
+
}, []), oe = U(async () => {
|
|
7692
|
+
if (!(!x.current || !_))
|
|
7693
7693
|
try {
|
|
7694
|
-
await
|
|
7695
|
-
const
|
|
7696
|
-
|
|
7697
|
-
} catch (
|
|
7698
|
-
console.warn("Error resuming speech:",
|
|
7694
|
+
await Se(), v(!1), T.current = !1;
|
|
7695
|
+
const S = M.current?.remainingText, H = M.current?.originalText || A.current?.text, Y = M.current?.options || A.current?.options || {}, ee = S || H;
|
|
7696
|
+
ee && V(ee, Y);
|
|
7697
|
+
} catch (S) {
|
|
7698
|
+
console.warn("Error resuming speech:", S), v(!1), T.current = !1;
|
|
7699
7699
|
}
|
|
7700
|
-
}, [
|
|
7701
|
-
|
|
7700
|
+
}, [_, V, Se]), ye = U(() => {
|
|
7701
|
+
x.current && (x.current.stopSpeaking(), L.current && (clearInterval(L.current), L.current = null), v(!1), T.current = !1);
|
|
7702
7702
|
}, []);
|
|
7703
|
-
return
|
|
7703
|
+
return Ee(I, () => ({
|
|
7704
7704
|
speakText: V,
|
|
7705
|
-
pauseSpeaking:
|
|
7706
|
-
resumeSpeaking:
|
|
7707
|
-
stopSpeaking:
|
|
7708
|
-
resumeAudioContext:
|
|
7709
|
-
isPaused: () =>
|
|
7710
|
-
setMood: (
|
|
7711
|
-
setBodyMovement: (
|
|
7712
|
-
|
|
7705
|
+
pauseSpeaking: $,
|
|
7706
|
+
resumeSpeaking: oe,
|
|
7707
|
+
stopSpeaking: ye,
|
|
7708
|
+
resumeAudioContext: Se,
|
|
7709
|
+
isPaused: () => _,
|
|
7710
|
+
setMood: (S) => x.current?.setMood(S),
|
|
7711
|
+
setBodyMovement: (S) => {
|
|
7712
|
+
x.current && x.current.setBodyMovement(S);
|
|
7713
7713
|
},
|
|
7714
|
-
playAnimation: (
|
|
7715
|
-
|
|
7714
|
+
playAnimation: (S, H = !1) => {
|
|
7715
|
+
x.current && x.current.playAnimation && x.current.playAnimation(S, null, 10, 0, 0.01, H);
|
|
7716
7716
|
},
|
|
7717
|
-
playRandomAnimation: (
|
|
7718
|
-
getRandomAnimation: (
|
|
7719
|
-
playReaction: (
|
|
7720
|
-
playCelebration: () =>
|
|
7721
|
-
setShowFullAvatar: (
|
|
7722
|
-
|
|
7717
|
+
playRandomAnimation: (S, H = !1) => C(S, H),
|
|
7718
|
+
getRandomAnimation: (S) => we(S),
|
|
7719
|
+
playReaction: (S) => x.current?.playReaction(S),
|
|
7720
|
+
playCelebration: () => x.current?.playCelebration(),
|
|
7721
|
+
setShowFullAvatar: (S) => {
|
|
7722
|
+
x.current && (k.current = S, x.current.setShowFullAvatar(S));
|
|
7723
7723
|
},
|
|
7724
|
-
isReady:
|
|
7725
|
-
talkingHead:
|
|
7726
|
-
})), /* @__PURE__ */
|
|
7727
|
-
/* @__PURE__ */
|
|
7724
|
+
isReady: ne,
|
|
7725
|
+
talkingHead: x.current
|
|
7726
|
+
})), /* @__PURE__ */ fe("div", { className: `simple-talking-avatar-container ${f}`, style: w, children: [
|
|
7727
|
+
/* @__PURE__ */ q(
|
|
7728
7728
|
"div",
|
|
7729
7729
|
{
|
|
7730
|
-
ref:
|
|
7730
|
+
ref: D,
|
|
7731
7731
|
className: "talking-head-viewer",
|
|
7732
7732
|
style: {
|
|
7733
7733
|
width: "100%",
|
|
@@ -7736,7 +7736,7 @@ const yt = Me(({
|
|
|
7736
7736
|
}
|
|
7737
7737
|
}
|
|
7738
7738
|
),
|
|
7739
|
-
|
|
7739
|
+
Z && /* @__PURE__ */ q("div", { className: "loading-overlay", style: {
|
|
7740
7740
|
position: "absolute",
|
|
7741
7741
|
top: "50%",
|
|
7742
7742
|
left: "50%",
|
|
@@ -7745,7 +7745,7 @@ const yt = Me(({
|
|
|
7745
7745
|
fontSize: "18px",
|
|
7746
7746
|
zIndex: 10
|
|
7747
7747
|
}, children: "Loading avatar..." }),
|
|
7748
|
-
|
|
7748
|
+
re && /* @__PURE__ */ q("div", { className: "error-overlay", style: {
|
|
7749
7749
|
position: "absolute",
|
|
7750
7750
|
top: "50%",
|
|
7751
7751
|
left: "50%",
|
|
@@ -7756,12 +7756,12 @@ const yt = Me(({
|
|
|
7756
7756
|
zIndex: 10,
|
|
7757
7757
|
padding: "20px",
|
|
7758
7758
|
borderRadius: "8px"
|
|
7759
|
-
}, children:
|
|
7759
|
+
}, children: re })
|
|
7760
7760
|
] });
|
|
7761
7761
|
});
|
|
7762
7762
|
yt.displayName = "SimpleTalkingAvatar";
|
|
7763
|
-
const ft =
|
|
7764
|
-
curriculumData:
|
|
7763
|
+
const ft = Fe(({
|
|
7764
|
+
curriculumData: G = null,
|
|
7765
7765
|
avatarConfig: t = {},
|
|
7766
7766
|
animations: e = {},
|
|
7767
7767
|
onLessonStart: n = () => {
|
|
@@ -7774,9 +7774,9 @@ const ft = Me(({
|
|
|
7774
7774
|
},
|
|
7775
7775
|
onCustomAction: l = () => {
|
|
7776
7776
|
},
|
|
7777
|
-
autoStart:
|
|
7777
|
+
autoStart: c = !1
|
|
7778
7778
|
}, r) => {
|
|
7779
|
-
const u =
|
|
7779
|
+
const u = X(null), a = X({
|
|
7780
7780
|
currentModuleIndex: 0,
|
|
7781
7781
|
currentLessonIndex: 0,
|
|
7782
7782
|
currentQuestionIndex: 0,
|
|
@@ -7786,18 +7786,18 @@ const ft = Me(({
|
|
|
7786
7786
|
curriculumCompleted: !1,
|
|
7787
7787
|
score: 0,
|
|
7788
7788
|
totalQuestions: 0
|
|
7789
|
-
}), d =
|
|
7789
|
+
}), d = X({
|
|
7790
7790
|
onLessonStart: n,
|
|
7791
7791
|
onLessonComplete: i,
|
|
7792
7792
|
onQuestionAnswer: s,
|
|
7793
7793
|
onCurriculumComplete: o,
|
|
7794
7794
|
onCustomAction: l
|
|
7795
|
-
}),
|
|
7795
|
+
}), h = X(null), g = X(null), b = X(null), f = X(null), w = X(null), N = X(null), p = X(null), B = X(G?.curriculum || {
|
|
7796
7796
|
title: "Default Curriculum",
|
|
7797
7797
|
description: "No curriculum data provided",
|
|
7798
7798
|
language: "en",
|
|
7799
7799
|
modules: []
|
|
7800
|
-
}),
|
|
7800
|
+
}), F = X({
|
|
7801
7801
|
avatarUrl: t.avatarUrl || "/avatars/brunette.glb",
|
|
7802
7802
|
avatarBody: t.avatarBody || "F",
|
|
7803
7803
|
mood: t.mood || "happy",
|
|
@@ -7811,7 +7811,7 @@ const ft = Me(({
|
|
|
7811
7811
|
animations: e,
|
|
7812
7812
|
lipsyncLang: "en"
|
|
7813
7813
|
});
|
|
7814
|
-
|
|
7814
|
+
me(() => {
|
|
7815
7815
|
d.current = {
|
|
7816
7816
|
onLessonStart: n,
|
|
7817
7817
|
onLessonComplete: i,
|
|
@@ -7819,13 +7819,13 @@ const ft = Me(({
|
|
|
7819
7819
|
onCurriculumComplete: o,
|
|
7820
7820
|
onCustomAction: l
|
|
7821
7821
|
};
|
|
7822
|
-
}, [n, i, s, o, l]),
|
|
7823
|
-
|
|
7822
|
+
}, [n, i, s, o, l]), me(() => {
|
|
7823
|
+
B.current = G?.curriculum || {
|
|
7824
7824
|
title: "Default Curriculum",
|
|
7825
7825
|
description: "No curriculum data provided",
|
|
7826
7826
|
language: "en",
|
|
7827
7827
|
modules: []
|
|
7828
|
-
},
|
|
7828
|
+
}, F.current = {
|
|
7829
7829
|
avatarUrl: t.avatarUrl || "/avatars/brunette.glb",
|
|
7830
7830
|
avatarBody: t.avatarBody || "F",
|
|
7831
7831
|
mood: t.mood || "happy",
|
|
@@ -7839,8 +7839,8 @@ const ft = Me(({
|
|
|
7839
7839
|
animations: e,
|
|
7840
7840
|
lipsyncLang: "en"
|
|
7841
7841
|
};
|
|
7842
|
-
}, [
|
|
7843
|
-
const I =
|
|
7842
|
+
}, [G, t, e]);
|
|
7843
|
+
const I = U(() => (B.current || { modules: [] }).modules[a.current.currentModuleIndex]?.lessons[a.current.currentLessonIndex], []), D = U(() => I()?.questions[a.current.currentQuestionIndex], [I]), x = U((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, []), k = U(() => {
|
|
7844
7844
|
a.current.lessonCompleted = !0, a.current.isQuestionMode = !1;
|
|
7845
7845
|
const v = a.current.totalQuestions > 0 ? Math.round(a.current.score / a.current.totalQuestions * 100) : 100;
|
|
7846
7846
|
let R = "Congratulations! You've completed this lesson";
|
|
@@ -7864,9 +7864,9 @@ const ft = Me(({
|
|
|
7864
7864
|
} catch {
|
|
7865
7865
|
u.current.playCelebration();
|
|
7866
7866
|
}
|
|
7867
|
-
const
|
|
7867
|
+
const P = B.current || { modules: [] }, O = P.modules[a.current.currentModuleIndex], W = a.current.currentLessonIndex < (O?.lessons?.length || 0) - 1, ie = a.current.currentModuleIndex < (P.modules?.length || 0) - 1, K = W || ie, J = F.current || { lipsyncLang: "en" };
|
|
7868
7868
|
u.current.speakText(R, {
|
|
7869
|
-
lipsyncLang:
|
|
7869
|
+
lipsyncLang: J.lipsyncLang,
|
|
7870
7870
|
onSpeechEnd: () => {
|
|
7871
7871
|
d.current.onCustomAction({
|
|
7872
7872
|
type: "lessonCompleteFeedbackDone",
|
|
@@ -7875,17 +7875,17 @@ const ft = Me(({
|
|
|
7875
7875
|
score: a.current.score,
|
|
7876
7876
|
totalQuestions: a.current.totalQuestions,
|
|
7877
7877
|
percentage: v,
|
|
7878
|
-
hasNextLesson:
|
|
7878
|
+
hasNextLesson: K
|
|
7879
7879
|
});
|
|
7880
7880
|
}
|
|
7881
7881
|
});
|
|
7882
7882
|
}
|
|
7883
|
-
}, [e.lessonComplete]),
|
|
7883
|
+
}, [e.lessonComplete]), A = U(() => {
|
|
7884
7884
|
a.current.curriculumCompleted = !0;
|
|
7885
|
-
const v =
|
|
7885
|
+
const v = B.current || { modules: [] };
|
|
7886
7886
|
if (d.current.onCurriculumComplete({
|
|
7887
7887
|
modules: v.modules.length,
|
|
7888
|
-
totalLessons: v.modules.reduce((R,
|
|
7888
|
+
totalLessons: v.modules.reduce((R, P) => R + P.lessons.length, 0)
|
|
7889
7889
|
}), u.current) {
|
|
7890
7890
|
if (u.current.setMood("celebrating"), e.curriculumComplete)
|
|
7891
7891
|
try {
|
|
@@ -7893,13 +7893,13 @@ const ft = Me(({
|
|
|
7893
7893
|
} catch {
|
|
7894
7894
|
u.current.playCelebration();
|
|
7895
7895
|
}
|
|
7896
|
-
const R =
|
|
7896
|
+
const R = F.current || { lipsyncLang: "en" };
|
|
7897
7897
|
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 });
|
|
7898
7898
|
}
|
|
7899
|
-
}, [e.curriculumComplete]), L =
|
|
7899
|
+
}, [e.curriculumComplete]), L = U(() => {
|
|
7900
7900
|
const v = I();
|
|
7901
7901
|
a.current.isQuestionMode = !0, a.current.currentQuestionIndex = 0, a.current.totalQuestions = v?.questions?.length || 0, a.current.score = 0;
|
|
7902
|
-
const R =
|
|
7902
|
+
const R = D();
|
|
7903
7903
|
R && d.current.onCustomAction({
|
|
7904
7904
|
type: "questionStart",
|
|
7905
7905
|
moduleIndex: a.current.currentModuleIndex,
|
|
@@ -7909,7 +7909,7 @@ const ft = Me(({
|
|
|
7909
7909
|
question: R,
|
|
7910
7910
|
score: a.current.score
|
|
7911
7911
|
});
|
|
7912
|
-
const
|
|
7912
|
+
const P = () => {
|
|
7913
7913
|
if (!u.current || !R) return;
|
|
7914
7914
|
if (u.current.setMood("happy"), e.questionStart)
|
|
7915
7915
|
try {
|
|
@@ -7917,27 +7917,27 @@ const ft = Me(({
|
|
|
7917
7917
|
} catch (W) {
|
|
7918
7918
|
console.warn("Failed to play questionStart animation:", W);
|
|
7919
7919
|
}
|
|
7920
|
-
const
|
|
7921
|
-
R.type === "code_test" ? u.current.speakText(`Let's test your coding skills! Here's your first challenge: ${R.question}`, { lipsyncLang:
|
|
7920
|
+
const O = F.current || { lipsyncLang: "en" };
|
|
7921
|
+
R.type === "code_test" ? u.current.speakText(`Let's test your coding skills! Here's your first challenge: ${R.question}`, { lipsyncLang: O.lipsyncLang }) : R.type === "multiple_choice" ? u.current.speakText(`Now let me ask you some questions. Here's the first one: ${R.question}`, { lipsyncLang: O.lipsyncLang }) : R.type === "true_false" ? u.current.speakText(`Let's start with some true or false questions. First question: ${R.question}`, { lipsyncLang: O.lipsyncLang }) : u.current.speakText(`Now let me ask you some questions. Here's the first one: ${R.question}`, { lipsyncLang: O.lipsyncLang });
|
|
7922
7922
|
};
|
|
7923
7923
|
if (u.current && u.current.isReady && R)
|
|
7924
|
-
|
|
7924
|
+
P();
|
|
7925
7925
|
else if (u.current && u.current.isReady) {
|
|
7926
|
-
const
|
|
7927
|
-
u.current.speakText("Now let me ask you some questions to test your understanding.", { lipsyncLang:
|
|
7926
|
+
const O = F.current || { lipsyncLang: "en" };
|
|
7927
|
+
u.current.speakText("Now let me ask you some questions to test your understanding.", { lipsyncLang: O.lipsyncLang });
|
|
7928
7928
|
} else {
|
|
7929
|
-
const
|
|
7930
|
-
u.current && u.current.isReady && (clearInterval(
|
|
7929
|
+
const O = setInterval(() => {
|
|
7930
|
+
u.current && u.current.isReady && (clearInterval(O), R && P());
|
|
7931
7931
|
}, 100);
|
|
7932
7932
|
setTimeout(() => {
|
|
7933
|
-
clearInterval(
|
|
7933
|
+
clearInterval(O);
|
|
7934
7934
|
}, 5e3);
|
|
7935
7935
|
}
|
|
7936
|
-
}, [e.questionStart, I,
|
|
7936
|
+
}, [e.questionStart, I, D]), T = U(() => {
|
|
7937
7937
|
const v = I();
|
|
7938
7938
|
if (a.current.currentQuestionIndex < (v?.questions?.length || 0) - 1) {
|
|
7939
7939
|
u.current && u.current.stopSpeaking && u.current.stopSpeaking(), a.current.currentQuestionIndex += 1;
|
|
7940
|
-
const R =
|
|
7940
|
+
const R = D();
|
|
7941
7941
|
R && d.current.onCustomAction({
|
|
7942
7942
|
type: "nextQuestion",
|
|
7943
7943
|
moduleIndex: a.current.currentModuleIndex,
|
|
@@ -7947,45 +7947,45 @@ const ft = Me(({
|
|
|
7947
7947
|
question: R,
|
|
7948
7948
|
score: a.current.score
|
|
7949
7949
|
});
|
|
7950
|
-
const
|
|
7950
|
+
const P = () => {
|
|
7951
7951
|
if (!u.current || !R) return;
|
|
7952
7952
|
if (u.current.setMood("happy"), u.current.setBodyMovement("idle"), e.nextQuestion)
|
|
7953
7953
|
try {
|
|
7954
7954
|
u.current.playAnimation(e.nextQuestion, !0);
|
|
7955
|
-
} catch (
|
|
7956
|
-
console.warn("Failed to play nextQuestion animation:",
|
|
7955
|
+
} catch (J) {
|
|
7956
|
+
console.warn("Failed to play nextQuestion animation:", J);
|
|
7957
7957
|
}
|
|
7958
|
-
const
|
|
7958
|
+
const O = F.current || { lipsyncLang: "en" }, ie = I()?.questions?.length || 0, K = a.current.currentQuestionIndex >= ie - 1;
|
|
7959
7959
|
if (R.type === "code_test") {
|
|
7960
|
-
const
|
|
7961
|
-
u.current.speakText(
|
|
7962
|
-
lipsyncLang:
|
|
7960
|
+
const J = K ? `Great! Here's your final coding challenge: ${R.question}` : `Great! Now let's move on to your next coding challenge: ${R.question}`;
|
|
7961
|
+
u.current.speakText(J, {
|
|
7962
|
+
lipsyncLang: O.lipsyncLang
|
|
7963
7963
|
});
|
|
7964
7964
|
} else if (R.type === "multiple_choice") {
|
|
7965
|
-
const
|
|
7966
|
-
u.current.speakText(
|
|
7967
|
-
lipsyncLang:
|
|
7965
|
+
const J = K ? `Alright! Here's your final question: ${R.question}` : `Alright! Here's your next question: ${R.question}`;
|
|
7966
|
+
u.current.speakText(J, {
|
|
7967
|
+
lipsyncLang: O.lipsyncLang
|
|
7968
7968
|
});
|
|
7969
7969
|
} else if (R.type === "true_false") {
|
|
7970
|
-
const
|
|
7971
|
-
u.current.speakText(
|
|
7972
|
-
lipsyncLang:
|
|
7970
|
+
const J = K ? `Now let's try this final one: ${R.question}` : `Now let's try this one: ${R.question}`;
|
|
7971
|
+
u.current.speakText(J, {
|
|
7972
|
+
lipsyncLang: O.lipsyncLang
|
|
7973
7973
|
});
|
|
7974
7974
|
} else {
|
|
7975
|
-
const
|
|
7976
|
-
u.current.speakText(
|
|
7977
|
-
lipsyncLang:
|
|
7975
|
+
const J = K ? `Here's your final question: ${R.question}` : `Here's the next question: ${R.question}`;
|
|
7976
|
+
u.current.speakText(J, {
|
|
7977
|
+
lipsyncLang: O.lipsyncLang
|
|
7978
7978
|
});
|
|
7979
7979
|
}
|
|
7980
7980
|
};
|
|
7981
7981
|
if (u.current && u.current.isReady && R)
|
|
7982
|
-
|
|
7982
|
+
P();
|
|
7983
7983
|
else if (R) {
|
|
7984
|
-
const
|
|
7985
|
-
u.current && u.current.isReady && (clearInterval(
|
|
7984
|
+
const O = setInterval(() => {
|
|
7985
|
+
u.current && u.current.isReady && (clearInterval(O), P());
|
|
7986
7986
|
}, 100);
|
|
7987
7987
|
setTimeout(() => {
|
|
7988
|
-
clearInterval(
|
|
7988
|
+
clearInterval(O);
|
|
7989
7989
|
}, 5e3);
|
|
7990
7990
|
}
|
|
7991
7991
|
} else
|
|
@@ -7996,16 +7996,16 @@ const ft = Me(({
|
|
|
7996
7996
|
totalQuestions: a.current.totalQuestions,
|
|
7997
7997
|
score: a.current.score
|
|
7998
7998
|
});
|
|
7999
|
-
}, [e.nextQuestion, I,
|
|
8000
|
-
const v =
|
|
7999
|
+
}, [e.nextQuestion, I, D]), M = U(() => {
|
|
8000
|
+
const v = B.current || { modules: [] }, R = v.modules[a.current.currentModuleIndex];
|
|
8001
8001
|
if (a.current.currentLessonIndex < (R?.lessons?.length || 0) - 1) {
|
|
8002
8002
|
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;
|
|
8003
|
-
const
|
|
8003
|
+
const O = v.modules[a.current.currentModuleIndex], W = a.current.currentLessonIndex < (O?.lessons?.length || 0) - 1, ie = a.current.currentModuleIndex < (v.modules?.length || 0) - 1, K = W || ie;
|
|
8004
8004
|
d.current.onCustomAction({
|
|
8005
8005
|
type: "lessonStart",
|
|
8006
8006
|
moduleIndex: a.current.currentModuleIndex,
|
|
8007
8007
|
lessonIndex: a.current.currentLessonIndex,
|
|
8008
|
-
hasNextLesson:
|
|
8008
|
+
hasNextLesson: K
|
|
8009
8009
|
}), d.current.onLessonStart({
|
|
8010
8010
|
moduleIndex: a.current.currentModuleIndex,
|
|
8011
8011
|
lessonIndex: a.current.currentLessonIndex,
|
|
@@ -8013,38 +8013,38 @@ const ft = Me(({
|
|
|
8013
8013
|
}), u.current && (u.current.setMood("happy"), u.current.setBodyMovement("idle"));
|
|
8014
8014
|
} else if (a.current.currentModuleIndex < (v.modules?.length || 0) - 1) {
|
|
8015
8015
|
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;
|
|
8016
|
-
const W = v.modules[a.current.currentModuleIndex],
|
|
8016
|
+
const W = v.modules[a.current.currentModuleIndex], ie = a.current.currentLessonIndex < (W?.lessons?.length || 0) - 1, K = a.current.currentModuleIndex < (v.modules?.length || 0) - 1, J = ie || K;
|
|
8017
8017
|
d.current.onCustomAction({
|
|
8018
8018
|
type: "lessonStart",
|
|
8019
8019
|
moduleIndex: a.current.currentModuleIndex,
|
|
8020
8020
|
lessonIndex: a.current.currentLessonIndex,
|
|
8021
|
-
hasNextLesson:
|
|
8021
|
+
hasNextLesson: J
|
|
8022
8022
|
}), d.current.onLessonStart({
|
|
8023
8023
|
moduleIndex: a.current.currentModuleIndex,
|
|
8024
8024
|
lessonIndex: a.current.currentLessonIndex,
|
|
8025
8025
|
lesson: I()
|
|
8026
8026
|
}), u.current && (u.current.setMood("happy"), u.current.setBodyMovement("idle"));
|
|
8027
8027
|
} else
|
|
8028
|
-
|
|
8029
|
-
}, []),
|
|
8028
|
+
w.current && w.current();
|
|
8029
|
+
}, []), j = U(() => {
|
|
8030
8030
|
const v = I();
|
|
8031
8031
|
let R = null;
|
|
8032
8032
|
if (v?.avatar_script && v?.body) {
|
|
8033
|
-
const
|
|
8034
|
-
R = `${
|
|
8033
|
+
const P = v.avatar_script.trim(), O = v.body.trim(), W = P.match(/[.!?]$/) ? " " : ". ";
|
|
8034
|
+
R = `${P}${W}${O}`;
|
|
8035
8035
|
} else
|
|
8036
8036
|
R = v?.avatar_script || v?.body || null;
|
|
8037
8037
|
if (u.current && u.current.isReady && R) {
|
|
8038
8038
|
a.current.isTeaching = !0, a.current.isQuestionMode = !1, a.current.score = 0, a.current.totalQuestions = 0, u.current.setMood("happy");
|
|
8039
|
-
let
|
|
8039
|
+
let P = !1;
|
|
8040
8040
|
if (e.teaching)
|
|
8041
8041
|
try {
|
|
8042
|
-
u.current.playAnimation(e.teaching, !0),
|
|
8042
|
+
u.current.playAnimation(e.teaching, !0), P = !0;
|
|
8043
8043
|
} catch (W) {
|
|
8044
8044
|
console.warn("Failed to play teaching animation:", W);
|
|
8045
8045
|
}
|
|
8046
|
-
|
|
8047
|
-
const
|
|
8046
|
+
P || u.current.setBodyMovement("gesturing");
|
|
8047
|
+
const O = F.current || { lipsyncLang: "en" };
|
|
8048
8048
|
d.current.onLessonStart({
|
|
8049
8049
|
moduleIndex: a.current.currentModuleIndex,
|
|
8050
8050
|
lessonIndex: a.current.currentLessonIndex,
|
|
@@ -8055,7 +8055,7 @@ const ft = Me(({
|
|
|
8055
8055
|
lessonIndex: a.current.currentLessonIndex,
|
|
8056
8056
|
lesson: v
|
|
8057
8057
|
}), u.current.speakText(R, {
|
|
8058
|
-
lipsyncLang:
|
|
8058
|
+
lipsyncLang: O.lipsyncLang,
|
|
8059
8059
|
onSpeechEnd: () => {
|
|
8060
8060
|
a.current.isTeaching = !1, d.current.onCustomAction({
|
|
8061
8061
|
type: "teachingComplete",
|
|
@@ -8073,17 +8073,17 @@ const ft = Me(({
|
|
|
8073
8073
|
}
|
|
8074
8074
|
});
|
|
8075
8075
|
}
|
|
8076
|
-
}, [e.teaching, I]),
|
|
8077
|
-
const R =
|
|
8078
|
-
if (
|
|
8076
|
+
}, [e.teaching, I]), Z = U((v) => {
|
|
8077
|
+
const R = D(), P = x(v, R);
|
|
8078
|
+
if (P && (a.current.score += 1), d.current.onQuestionAnswer({
|
|
8079
8079
|
moduleIndex: a.current.currentModuleIndex,
|
|
8080
8080
|
lessonIndex: a.current.currentLessonIndex,
|
|
8081
8081
|
questionIndex: a.current.currentQuestionIndex,
|
|
8082
8082
|
answer: v,
|
|
8083
|
-
isCorrect:
|
|
8083
|
+
isCorrect: P,
|
|
8084
8084
|
question: R
|
|
8085
8085
|
}), u.current)
|
|
8086
|
-
if (
|
|
8086
|
+
if (P) {
|
|
8087
8087
|
if (u.current.setMood("happy"), e.correct)
|
|
8088
8088
|
try {
|
|
8089
8089
|
u.current.playReaction("happy");
|
|
@@ -8093,11 +8093,11 @@ const ft = Me(({
|
|
|
8093
8093
|
u.current.setBodyMovement("gesturing");
|
|
8094
8094
|
const W = I()?.questions?.length || 0;
|
|
8095
8095
|
a.current.currentQuestionIndex >= W - 1;
|
|
8096
|
-
const
|
|
8097
|
-
console.log("[CurriculumLearning] Answer feedback - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:", W, "hasNextQuestion:",
|
|
8098
|
-
const
|
|
8099
|
-
u.current.speakText(
|
|
8100
|
-
lipsyncLang:
|
|
8096
|
+
const ie = a.current.currentQuestionIndex < W - 1;
|
|
8097
|
+
console.log("[CurriculumLearning] Answer feedback - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:", W, "hasNextQuestion:", ie);
|
|
8098
|
+
const K = R.type === "code_test" ? `Great job! Your code passed all the tests! ${R.explanation || ""}` : `Excellent! That's correct! ${R.explanation || ""}`, J = F.current || { lipsyncLang: "en" };
|
|
8099
|
+
u.current.speakText(K, {
|
|
8100
|
+
lipsyncLang: J.lipsyncLang,
|
|
8101
8101
|
onSpeechEnd: () => {
|
|
8102
8102
|
d.current.onCustomAction({
|
|
8103
8103
|
type: "answerFeedbackComplete",
|
|
@@ -8105,7 +8105,7 @@ const ft = Me(({
|
|
|
8105
8105
|
lessonIndex: a.current.currentLessonIndex,
|
|
8106
8106
|
questionIndex: a.current.currentQuestionIndex,
|
|
8107
8107
|
isCorrect: !0,
|
|
8108
|
-
hasNextQuestion:
|
|
8108
|
+
hasNextQuestion: ie,
|
|
8109
8109
|
score: a.current.score,
|
|
8110
8110
|
totalQuestions: a.current.totalQuestions
|
|
8111
8111
|
});
|
|
@@ -8119,11 +8119,11 @@ const ft = Me(({
|
|
|
8119
8119
|
u.current.setBodyMovement("idle");
|
|
8120
8120
|
}
|
|
8121
8121
|
u.current.setBodyMovement("gesturing");
|
|
8122
|
-
const W = I()?.questions?.length || 0,
|
|
8123
|
-
console.log("[CurriculumLearning] Answer feedback (incorrect) - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:", W, "hasNextQuestion:",
|
|
8124
|
-
const
|
|
8125
|
-
u.current.speakText(
|
|
8126
|
-
lipsyncLang:
|
|
8122
|
+
const W = I()?.questions?.length || 0, ie = a.current.currentQuestionIndex >= W - 1, K = a.current.currentQuestionIndex < W - 1;
|
|
8123
|
+
console.log("[CurriculumLearning] Answer feedback (incorrect) - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:", W, "hasNextQuestion:", K);
|
|
8124
|
+
const J = 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 || ""}${ie ? "" : " Let's move on to the next question."}`, Le = F.current || { lipsyncLang: "en" };
|
|
8125
|
+
u.current.speakText(J, {
|
|
8126
|
+
lipsyncLang: Le.lipsyncLang,
|
|
8127
8127
|
onSpeechEnd: () => {
|
|
8128
8128
|
d.current.onCustomAction({
|
|
8129
8129
|
type: "answerFeedbackComplete",
|
|
@@ -8131,7 +8131,7 @@ const ft = Me(({
|
|
|
8131
8131
|
lessonIndex: a.current.currentLessonIndex,
|
|
8132
8132
|
questionIndex: a.current.currentQuestionIndex,
|
|
8133
8133
|
isCorrect: !1,
|
|
8134
|
-
hasNextQuestion:
|
|
8134
|
+
hasNextQuestion: K,
|
|
8135
8135
|
score: a.current.score,
|
|
8136
8136
|
totalQuestions: a.current.totalQuestions
|
|
8137
8137
|
});
|
|
@@ -8145,15 +8145,15 @@ const ft = Me(({
|
|
|
8145
8145
|
moduleIndex: a.current.currentModuleIndex,
|
|
8146
8146
|
lessonIndex: a.current.currentLessonIndex,
|
|
8147
8147
|
questionIndex: a.current.currentQuestionIndex,
|
|
8148
|
-
isCorrect:
|
|
8148
|
+
isCorrect: P,
|
|
8149
8149
|
hasNextQuestion: a.current.currentQuestionIndex < W - 1,
|
|
8150
8150
|
score: a.current.score,
|
|
8151
8151
|
totalQuestions: a.current.totalQuestions,
|
|
8152
8152
|
avatarNotReady: !0
|
|
8153
8153
|
});
|
|
8154
8154
|
}
|
|
8155
|
-
}, [e.correct, e.incorrect,
|
|
8156
|
-
const R =
|
|
8155
|
+
}, [e.correct, e.incorrect, D, I, x]), ue = U((v) => {
|
|
8156
|
+
const R = D();
|
|
8157
8157
|
if (!v || typeof v != "object") {
|
|
8158
8158
|
console.error("Invalid code test result format. Expected object with {passed: boolean, ...}");
|
|
8159
8159
|
return;
|
|
@@ -8162,7 +8162,7 @@ const ft = Me(({
|
|
|
8162
8162
|
console.warn("Current question is not a code test. Use handleAnswerSelect for other question types.");
|
|
8163
8163
|
return;
|
|
8164
8164
|
}
|
|
8165
|
-
const
|
|
8165
|
+
const P = {
|
|
8166
8166
|
passed: v.passed === !0,
|
|
8167
8167
|
results: v.results || [],
|
|
8168
8168
|
output: v.output || "",
|
|
@@ -8177,13 +8177,13 @@ const ft = Me(({
|
|
|
8177
8177
|
moduleIndex: a.current.currentModuleIndex,
|
|
8178
8178
|
lessonIndex: a.current.currentLessonIndex,
|
|
8179
8179
|
questionIndex: a.current.currentQuestionIndex,
|
|
8180
|
-
testResult:
|
|
8180
|
+
testResult: P,
|
|
8181
8181
|
question: R
|
|
8182
|
-
}), p.current && p.current(
|
|
8183
|
-
}, [
|
|
8182
|
+
}), p.current && p.current(P);
|
|
8183
|
+
}, [D, x]), re = U(() => {
|
|
8184
8184
|
if (a.current.currentQuestionIndex > 0) {
|
|
8185
8185
|
a.current.currentQuestionIndex -= 1;
|
|
8186
|
-
const v =
|
|
8186
|
+
const v = D();
|
|
8187
8187
|
v && d.current.onCustomAction({
|
|
8188
8188
|
type: "questionStart",
|
|
8189
8189
|
moduleIndex: a.current.currentModuleIndex,
|
|
@@ -8196,26 +8196,26 @@ const ft = Me(({
|
|
|
8196
8196
|
const R = () => {
|
|
8197
8197
|
if (!u.current || !v) return;
|
|
8198
8198
|
u.current.setMood("happy"), u.current.setBodyMovement("idle");
|
|
8199
|
-
const
|
|
8199
|
+
const P = F.current || { lipsyncLang: "en" };
|
|
8200
8200
|
v.type === "code_test" ? u.current.speakText(`Let's go back to this coding challenge: ${v.question}`, {
|
|
8201
|
-
lipsyncLang:
|
|
8201
|
+
lipsyncLang: P.lipsyncLang
|
|
8202
8202
|
}) : u.current.speakText(`Going back to: ${v.question}`, {
|
|
8203
|
-
lipsyncLang:
|
|
8203
|
+
lipsyncLang: P.lipsyncLang
|
|
8204
8204
|
});
|
|
8205
8205
|
};
|
|
8206
8206
|
if (u.current && u.current.isReady && v)
|
|
8207
8207
|
R();
|
|
8208
8208
|
else if (v) {
|
|
8209
|
-
const
|
|
8210
|
-
u.current && u.current.isReady && (clearInterval(
|
|
8209
|
+
const P = setInterval(() => {
|
|
8210
|
+
u.current && u.current.isReady && (clearInterval(P), R());
|
|
8211
8211
|
}, 100);
|
|
8212
8212
|
setTimeout(() => {
|
|
8213
|
-
clearInterval(
|
|
8213
|
+
clearInterval(P);
|
|
8214
8214
|
}, 5e3);
|
|
8215
8215
|
}
|
|
8216
8216
|
}
|
|
8217
|
-
}, [
|
|
8218
|
-
const v =
|
|
8217
|
+
}, [D]), ge = U(() => {
|
|
8218
|
+
const v = B.current || { modules: [] };
|
|
8219
8219
|
if (v.modules[a.current.currentModuleIndex], a.current.currentLessonIndex > 0)
|
|
8220
8220
|
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, d.current.onCustomAction({
|
|
8221
8221
|
type: "lessonStart",
|
|
@@ -8227,8 +8227,8 @@ const ft = Me(({
|
|
|
8227
8227
|
lesson: I()
|
|
8228
8228
|
}), u.current && (u.current.setMood("happy"), u.current.setBodyMovement("idle"));
|
|
8229
8229
|
else if (a.current.currentModuleIndex > 0) {
|
|
8230
|
-
const
|
|
8231
|
-
a.current.currentModuleIndex -= 1, a.current.currentLessonIndex = (
|
|
8230
|
+
const O = v.modules[a.current.currentModuleIndex - 1];
|
|
8231
|
+
a.current.currentModuleIndex -= 1, a.current.currentLessonIndex = (O?.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, d.current.onCustomAction({
|
|
8232
8232
|
type: "lessonStart",
|
|
8233
8233
|
moduleIndex: a.current.currentModuleIndex,
|
|
8234
8234
|
lessonIndex: a.current.currentLessonIndex
|
|
@@ -8238,40 +8238,40 @@ const ft = Me(({
|
|
|
8238
8238
|
lesson: I()
|
|
8239
8239
|
}), u.current && (u.current.setMood("happy"), u.current.setBodyMovement("idle"));
|
|
8240
8240
|
}
|
|
8241
|
-
}, [I]),
|
|
8241
|
+
}, [I]), ne = U(() => {
|
|
8242
8242
|
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;
|
|
8243
|
-
}, []),
|
|
8243
|
+
}, []), ve = U((v) => {
|
|
8244
8244
|
console.log("Avatar is ready!", v);
|
|
8245
|
-
const R = I(),
|
|
8246
|
-
|
|
8247
|
-
|
|
8245
|
+
const R = I(), P = R?.avatar_script || R?.body;
|
|
8246
|
+
c && P && setTimeout(() => {
|
|
8247
|
+
h.current && h.current();
|
|
8248
8248
|
}, 10);
|
|
8249
|
-
}, [
|
|
8250
|
-
|
|
8251
|
-
|
|
8252
|
-
}),
|
|
8249
|
+
}, [c, I]);
|
|
8250
|
+
je(() => {
|
|
8251
|
+
h.current = j, g.current = M, b.current = k, f.current = T, w.current = A, N.current = L, p.current = Z;
|
|
8252
|
+
}), Ee(r, () => ({
|
|
8253
8253
|
// Curriculum control methods
|
|
8254
|
-
startTeaching:
|
|
8254
|
+
startTeaching: j,
|
|
8255
8255
|
startQuestions: L,
|
|
8256
|
-
handleAnswerSelect:
|
|
8257
|
-
handleCodeTestResult:
|
|
8258
|
-
nextQuestion:
|
|
8259
|
-
previousQuestion:
|
|
8260
|
-
nextLesson:
|
|
8261
|
-
previousLesson:
|
|
8262
|
-
completeLesson:
|
|
8263
|
-
completeCurriculum:
|
|
8264
|
-
resetCurriculum:
|
|
8256
|
+
handleAnswerSelect: Z,
|
|
8257
|
+
handleCodeTestResult: ue,
|
|
8258
|
+
nextQuestion: T,
|
|
8259
|
+
previousQuestion: re,
|
|
8260
|
+
nextLesson: M,
|
|
8261
|
+
previousLesson: ge,
|
|
8262
|
+
completeLesson: k,
|
|
8263
|
+
completeCurriculum: A,
|
|
8264
|
+
resetCurriculum: ne,
|
|
8265
8265
|
getState: () => ({ ...a.current }),
|
|
8266
|
-
getCurrentQuestion: () =>
|
|
8266
|
+
getCurrentQuestion: () => D(),
|
|
8267
8267
|
getCurrentLesson: () => I(),
|
|
8268
8268
|
// Direct access to avatar ref (always returns current value)
|
|
8269
8269
|
getAvatarRef: () => u.current,
|
|
8270
8270
|
// Convenience methods that delegate to avatar (always check current ref)
|
|
8271
8271
|
speakText: async (v, R = {}) => {
|
|
8272
8272
|
await u.current?.resumeAudioContext?.();
|
|
8273
|
-
const
|
|
8274
|
-
u.current?.speakText(v, { ...R, lipsyncLang: R.lipsyncLang ||
|
|
8273
|
+
const P = F.current || { lipsyncLang: "en" };
|
|
8274
|
+
u.current?.speakText(v, { ...R, lipsyncLang: R.lipsyncLang || P.lipsyncLang });
|
|
8275
8275
|
},
|
|
8276
8276
|
resumeAudioContext: async () => {
|
|
8277
8277
|
if (u.current?.resumeAudioContext)
|
|
@@ -8282,8 +8282,8 @@ const ft = Me(({
|
|
|
8282
8282
|
if (R.state === "suspended" || R.state === "interrupted")
|
|
8283
8283
|
try {
|
|
8284
8284
|
await R.resume(), console.log("Audio context resumed via talkingHead");
|
|
8285
|
-
} catch (
|
|
8286
|
-
console.warn("Failed to resume audio context:",
|
|
8285
|
+
} catch (P) {
|
|
8286
|
+
console.warn("Failed to resume audio context:", P);
|
|
8287
8287
|
}
|
|
8288
8288
|
} else
|
|
8289
8289
|
console.warn("Audio context not available yet");
|
|
@@ -8315,8 +8315,8 @@ const ft = Me(({
|
|
|
8315
8315
|
handleResize: () => u.current?.handleResize(),
|
|
8316
8316
|
// Avatar readiness check (always returns current value)
|
|
8317
8317
|
isAvatarReady: () => u.current?.isReady || !1
|
|
8318
|
-
}), [
|
|
8319
|
-
const
|
|
8318
|
+
}), [j, L, Z, ue, T, M, k, A, ne, D, I]);
|
|
8319
|
+
const _ = F.current || {
|
|
8320
8320
|
avatarUrl: "/avatars/brunette.glb",
|
|
8321
8321
|
avatarBody: "F",
|
|
8322
8322
|
mood: "happy",
|
|
@@ -8329,23 +8329,23 @@ const ft = Me(({
|
|
|
8329
8329
|
showFullAvatar: !1,
|
|
8330
8330
|
animations: e
|
|
8331
8331
|
};
|
|
8332
|
-
return /* @__PURE__ */
|
|
8332
|
+
return /* @__PURE__ */ q("div", { style: { width: "100%", height: "100%" }, children: /* @__PURE__ */ q(
|
|
8333
8333
|
Ve,
|
|
8334
8334
|
{
|
|
8335
8335
|
ref: u,
|
|
8336
|
-
avatarUrl:
|
|
8337
|
-
avatarBody:
|
|
8338
|
-
mood:
|
|
8339
|
-
ttsLang:
|
|
8340
|
-
ttsService:
|
|
8341
|
-
ttsVoice:
|
|
8342
|
-
ttsApiKey:
|
|
8343
|
-
bodyMovement:
|
|
8344
|
-
movementIntensity:
|
|
8345
|
-
showFullAvatar:
|
|
8336
|
+
avatarUrl: _.avatarUrl,
|
|
8337
|
+
avatarBody: _.avatarBody,
|
|
8338
|
+
mood: _.mood,
|
|
8339
|
+
ttsLang: _.ttsLang,
|
|
8340
|
+
ttsService: _.ttsService,
|
|
8341
|
+
ttsVoice: _.ttsVoice,
|
|
8342
|
+
ttsApiKey: _.ttsApiKey,
|
|
8343
|
+
bodyMovement: _.bodyMovement,
|
|
8344
|
+
movementIntensity: _.movementIntensity,
|
|
8345
|
+
showFullAvatar: _.showFullAvatar,
|
|
8346
8346
|
cameraView: "upper",
|
|
8347
|
-
animations:
|
|
8348
|
-
onReady:
|
|
8347
|
+
animations: _.animations,
|
|
8348
|
+
onReady: ve,
|
|
8349
8349
|
onLoading: () => {
|
|
8350
8350
|
},
|
|
8351
8351
|
onError: (v) => {
|
|
@@ -8355,7 +8355,290 @@ const ft = Me(({
|
|
|
8355
8355
|
) });
|
|
8356
8356
|
});
|
|
8357
8357
|
ft.displayName = "CurriculumLearning";
|
|
8358
|
-
|
|
8358
|
+
function Ct({
|
|
8359
|
+
manifestPath: G = "/animations/manifest.json",
|
|
8360
|
+
avatarBody: t = "F",
|
|
8361
|
+
onAnimationPlay: e = null,
|
|
8362
|
+
onAnimationsSelected: n = null,
|
|
8363
|
+
onDeleteAnimations: i = null,
|
|
8364
|
+
style: s = {}
|
|
8365
|
+
}) {
|
|
8366
|
+
const [o, l] = ae([]), [c, r] = ae(/* @__PURE__ */ new Set()), [u, a] = ae(!0), [d, h] = ae(null), [g, b] = ae("all"), [f, w] = ae("");
|
|
8367
|
+
me(() => {
|
|
8368
|
+
(async () => {
|
|
8369
|
+
a(!0), h(null);
|
|
8370
|
+
try {
|
|
8371
|
+
const A = await Ge(G), L = [];
|
|
8372
|
+
if (A._genderSpecific) {
|
|
8373
|
+
const M = (t?.toUpperCase() || "F") === "M" ? "male" : "female";
|
|
8374
|
+
A._genderSpecific[M] && Object.entries(A._genderSpecific[M]).forEach(([j, Z]) => {
|
|
8375
|
+
(Array.isArray(Z) ? Z : [Z]).forEach((re) => {
|
|
8376
|
+
L.push({
|
|
8377
|
+
path: re,
|
|
8378
|
+
group: j,
|
|
8379
|
+
gender: M,
|
|
8380
|
+
name: re.split("/").pop().replace(".fbx", "")
|
|
8381
|
+
});
|
|
8382
|
+
});
|
|
8383
|
+
}), A._genderSpecific.shared && Object.entries(A._genderSpecific.shared).forEach(([j, Z]) => {
|
|
8384
|
+
(Array.isArray(Z) ? Z : [Z]).forEach((re) => {
|
|
8385
|
+
L.push({
|
|
8386
|
+
path: re,
|
|
8387
|
+
group: j,
|
|
8388
|
+
gender: "shared",
|
|
8389
|
+
name: re.split("/").pop().replace(".fbx", "")
|
|
8390
|
+
});
|
|
8391
|
+
});
|
|
8392
|
+
});
|
|
8393
|
+
}
|
|
8394
|
+
Object.entries(A).forEach(([T, M]) => {
|
|
8395
|
+
T !== "_genderSpecific" && (Array.isArray(M) ? M : [M]).forEach((Z) => {
|
|
8396
|
+
typeof Z == "string" && L.push({
|
|
8397
|
+
path: Z,
|
|
8398
|
+
group: T,
|
|
8399
|
+
gender: "root",
|
|
8400
|
+
name: Z.split("/").pop().replace(".fbx", "")
|
|
8401
|
+
});
|
|
8402
|
+
});
|
|
8403
|
+
}), l(L), a(!1);
|
|
8404
|
+
} catch (A) {
|
|
8405
|
+
console.error("Failed to load animations:", A), h(A.message), a(!1);
|
|
8406
|
+
}
|
|
8407
|
+
})();
|
|
8408
|
+
}, [G, t]);
|
|
8409
|
+
const N = ["all", ...new Set(o.map((k) => k.group))], p = o.filter((k) => {
|
|
8410
|
+
const A = g === "all" || k.group === g, L = f === "" || k.name.toLowerCase().includes(f.toLowerCase()) || k.path.toLowerCase().includes(f.toLowerCase());
|
|
8411
|
+
return A && L;
|
|
8412
|
+
}), B = (k) => {
|
|
8413
|
+
const A = new Set(c);
|
|
8414
|
+
A.has(k) ? A.delete(k) : A.add(k), r(A), n && n(Array.from(A));
|
|
8415
|
+
}, F = () => {
|
|
8416
|
+
const k = new Set(c);
|
|
8417
|
+
p.forEach((A) => {
|
|
8418
|
+
k.add(A.path);
|
|
8419
|
+
}), r(k), n && n(Array.from(k));
|
|
8420
|
+
}, I = () => {
|
|
8421
|
+
const k = new Set(c);
|
|
8422
|
+
p.forEach((A) => {
|
|
8423
|
+
k.delete(A.path);
|
|
8424
|
+
}), r(k), n && n(Array.from(k));
|
|
8425
|
+
}, D = () => {
|
|
8426
|
+
const A = o.filter((L) => !c.has(L.path)).map((L) => L.path);
|
|
8427
|
+
if (A.length === 0) {
|
|
8428
|
+
alert("No animations to delete. Select animations to keep, then delete will remove the unselected ones.");
|
|
8429
|
+
return;
|
|
8430
|
+
}
|
|
8431
|
+
window.confirm(`Are you sure you want to delete ${A.length} animation(s)?
|
|
8432
|
+
|
|
8433
|
+
This will delete:
|
|
8434
|
+
${A.slice(0, 5).join(`
|
|
8435
|
+
`)}${A.length > 5 ? `
|
|
8436
|
+
...` : ""}`) && (i && i(A), l(o.filter((L) => c.has(L.path))), r(/* @__PURE__ */ new Set()));
|
|
8437
|
+
}, x = (k) => {
|
|
8438
|
+
e && e(k);
|
|
8439
|
+
};
|
|
8440
|
+
return u ? /* @__PURE__ */ q("div", { style: { padding: "20px", textAlign: "center", ...s }, children: /* @__PURE__ */ q("p", { children: "Loading animations..." }) }) : d ? /* @__PURE__ */ q("div", { style: { padding: "20px", color: "red", ...s }, children: /* @__PURE__ */ fe("p", { children: [
|
|
8441
|
+
"Error loading animations: ",
|
|
8442
|
+
d
|
|
8443
|
+
] }) }) : /* @__PURE__ */ fe("div", { style: {
|
|
8444
|
+
padding: "20px",
|
|
8445
|
+
backgroundColor: "#2a2a2a",
|
|
8446
|
+
borderRadius: "8px",
|
|
8447
|
+
color: "#fff",
|
|
8448
|
+
...s
|
|
8449
|
+
}, children: [
|
|
8450
|
+
/* @__PURE__ */ q("h2", { style: { marginTop: 0 }, children: "Animation Selector" }),
|
|
8451
|
+
/* @__PURE__ */ q("p", { style: { color: "#aaa", fontSize: "14px" }, children: "Click buttons to play animations. Select animations to keep, then delete will remove the rest." }),
|
|
8452
|
+
/* @__PURE__ */ fe("div", { style: {
|
|
8453
|
+
display: "flex",
|
|
8454
|
+
gap: "10px",
|
|
8455
|
+
marginBottom: "20px",
|
|
8456
|
+
flexWrap: "wrap",
|
|
8457
|
+
alignItems: "center"
|
|
8458
|
+
}, children: [
|
|
8459
|
+
/* @__PURE__ */ q(
|
|
8460
|
+
"input",
|
|
8461
|
+
{
|
|
8462
|
+
type: "text",
|
|
8463
|
+
placeholder: "Search animations...",
|
|
8464
|
+
value: f,
|
|
8465
|
+
onChange: (k) => w(k.target.value),
|
|
8466
|
+
style: {
|
|
8467
|
+
padding: "8px 12px",
|
|
8468
|
+
borderRadius: "6px",
|
|
8469
|
+
border: "1px solid #555",
|
|
8470
|
+
backgroundColor: "#333",
|
|
8471
|
+
color: "#fff",
|
|
8472
|
+
fontSize: "14px",
|
|
8473
|
+
flex: "1",
|
|
8474
|
+
minWidth: "200px"
|
|
8475
|
+
}
|
|
8476
|
+
}
|
|
8477
|
+
),
|
|
8478
|
+
/* @__PURE__ */ q(
|
|
8479
|
+
"select",
|
|
8480
|
+
{
|
|
8481
|
+
value: g,
|
|
8482
|
+
onChange: (k) => b(k.target.value),
|
|
8483
|
+
style: {
|
|
8484
|
+
padding: "8px 12px",
|
|
8485
|
+
borderRadius: "6px",
|
|
8486
|
+
border: "1px solid #555",
|
|
8487
|
+
backgroundColor: "#333",
|
|
8488
|
+
color: "#fff",
|
|
8489
|
+
fontSize: "14px"
|
|
8490
|
+
},
|
|
8491
|
+
children: N.map((k) => /* @__PURE__ */ q("option", { value: k, children: k === "all" ? "All Groups" : k }, k))
|
|
8492
|
+
}
|
|
8493
|
+
),
|
|
8494
|
+
/* @__PURE__ */ q(
|
|
8495
|
+
"button",
|
|
8496
|
+
{
|
|
8497
|
+
onClick: F,
|
|
8498
|
+
style: {
|
|
8499
|
+
padding: "8px 16px",
|
|
8500
|
+
backgroundColor: "#4CAF50",
|
|
8501
|
+
color: "white",
|
|
8502
|
+
border: "none",
|
|
8503
|
+
borderRadius: "6px",
|
|
8504
|
+
cursor: "pointer",
|
|
8505
|
+
fontSize: "14px"
|
|
8506
|
+
},
|
|
8507
|
+
children: "Select All Visible"
|
|
8508
|
+
}
|
|
8509
|
+
),
|
|
8510
|
+
/* @__PURE__ */ q(
|
|
8511
|
+
"button",
|
|
8512
|
+
{
|
|
8513
|
+
onClick: I,
|
|
8514
|
+
style: {
|
|
8515
|
+
padding: "8px 16px",
|
|
8516
|
+
backgroundColor: "#666",
|
|
8517
|
+
color: "white",
|
|
8518
|
+
border: "none",
|
|
8519
|
+
borderRadius: "6px",
|
|
8520
|
+
cursor: "pointer",
|
|
8521
|
+
fontSize: "14px"
|
|
8522
|
+
},
|
|
8523
|
+
children: "Deselect All Visible"
|
|
8524
|
+
}
|
|
8525
|
+
),
|
|
8526
|
+
/* @__PURE__ */ fe(
|
|
8527
|
+
"button",
|
|
8528
|
+
{
|
|
8529
|
+
onClick: D,
|
|
8530
|
+
style: {
|
|
8531
|
+
padding: "8px 16px",
|
|
8532
|
+
backgroundColor: "#f44336",
|
|
8533
|
+
color: "white",
|
|
8534
|
+
border: "none",
|
|
8535
|
+
borderRadius: "6px",
|
|
8536
|
+
cursor: "pointer",
|
|
8537
|
+
fontSize: "14px",
|
|
8538
|
+
fontWeight: "bold"
|
|
8539
|
+
},
|
|
8540
|
+
children: [
|
|
8541
|
+
"Delete Unselected (",
|
|
8542
|
+
o.length - c.size,
|
|
8543
|
+
")"
|
|
8544
|
+
]
|
|
8545
|
+
}
|
|
8546
|
+
)
|
|
8547
|
+
] }),
|
|
8548
|
+
/* @__PURE__ */ fe("div", { style: {
|
|
8549
|
+
marginBottom: "15px",
|
|
8550
|
+
fontSize: "14px",
|
|
8551
|
+
color: "#aaa"
|
|
8552
|
+
}, children: [
|
|
8553
|
+
"Total: ",
|
|
8554
|
+
o.length,
|
|
8555
|
+
" | Selected: ",
|
|
8556
|
+
c.size,
|
|
8557
|
+
" | Showing: ",
|
|
8558
|
+
p.length
|
|
8559
|
+
] }),
|
|
8560
|
+
/* @__PURE__ */ q("div", { style: {
|
|
8561
|
+
display: "grid",
|
|
8562
|
+
gridTemplateColumns: "repeat(auto-fill, minmax(200px, 1fr))",
|
|
8563
|
+
gap: "10px",
|
|
8564
|
+
maxHeight: "500px",
|
|
8565
|
+
overflowY: "auto",
|
|
8566
|
+
padding: "10px",
|
|
8567
|
+
backgroundColor: "#1a1a1a",
|
|
8568
|
+
borderRadius: "6px"
|
|
8569
|
+
}, children: p.map((k, A) => {
|
|
8570
|
+
const L = c.has(k.path);
|
|
8571
|
+
return /* @__PURE__ */ fe(
|
|
8572
|
+
"div",
|
|
8573
|
+
{
|
|
8574
|
+
style: {
|
|
8575
|
+
border: `2px solid ${L ? "#4CAF50" : "#555"}`,
|
|
8576
|
+
borderRadius: "6px",
|
|
8577
|
+
padding: "10px",
|
|
8578
|
+
backgroundColor: L ? "#2a4a2a" : "#222",
|
|
8579
|
+
cursor: "pointer",
|
|
8580
|
+
transition: "all 0.2s"
|
|
8581
|
+
},
|
|
8582
|
+
onClick: () => B(k.path),
|
|
8583
|
+
children: [
|
|
8584
|
+
/* @__PURE__ */ fe("div", { style: { marginBottom: "8px" }, children: [
|
|
8585
|
+
/* @__PURE__ */ q(
|
|
8586
|
+
"input",
|
|
8587
|
+
{
|
|
8588
|
+
type: "checkbox",
|
|
8589
|
+
checked: L,
|
|
8590
|
+
onChange: () => B(k.path),
|
|
8591
|
+
onClick: (T) => T.stopPropagation(),
|
|
8592
|
+
style: {
|
|
8593
|
+
marginRight: "8px",
|
|
8594
|
+
cursor: "pointer"
|
|
8595
|
+
}
|
|
8596
|
+
}
|
|
8597
|
+
),
|
|
8598
|
+
/* @__PURE__ */ fe("span", { style: { fontSize: "12px", color: "#aaa" }, children: [
|
|
8599
|
+
k.group,
|
|
8600
|
+
" ",
|
|
8601
|
+
k.gender !== "root" && `(${k.gender})`
|
|
8602
|
+
] })
|
|
8603
|
+
] }),
|
|
8604
|
+
/* @__PURE__ */ q("div", { style: {
|
|
8605
|
+
fontSize: "13px",
|
|
8606
|
+
fontWeight: "bold",
|
|
8607
|
+
marginBottom: "8px",
|
|
8608
|
+
wordBreak: "break-word"
|
|
8609
|
+
}, children: k.name }),
|
|
8610
|
+
/* @__PURE__ */ q(
|
|
8611
|
+
"button",
|
|
8612
|
+
{
|
|
8613
|
+
onClick: (T) => {
|
|
8614
|
+
T.stopPropagation(), x(k.path);
|
|
8615
|
+
},
|
|
8616
|
+
style: {
|
|
8617
|
+
width: "100%",
|
|
8618
|
+
padding: "6px",
|
|
8619
|
+
backgroundColor: "#2196F3",
|
|
8620
|
+
color: "white",
|
|
8621
|
+
border: "none",
|
|
8622
|
+
borderRadius: "4px",
|
|
8623
|
+
cursor: "pointer",
|
|
8624
|
+
fontSize: "12px"
|
|
8625
|
+
},
|
|
8626
|
+
children: "▶ Play"
|
|
8627
|
+
}
|
|
8628
|
+
)
|
|
8629
|
+
]
|
|
8630
|
+
},
|
|
8631
|
+
`${k.path}-${A}`
|
|
8632
|
+
);
|
|
8633
|
+
}) }),
|
|
8634
|
+
p.length === 0 && /* @__PURE__ */ q("div", { style: {
|
|
8635
|
+
padding: "40px",
|
|
8636
|
+
textAlign: "center",
|
|
8637
|
+
color: "#aaa"
|
|
8638
|
+
}, children: "No animations found matching your filters." })
|
|
8639
|
+
] });
|
|
8640
|
+
}
|
|
8641
|
+
const Ze = {
|
|
8359
8642
|
// Code-based dance animations (no FBX required)
|
|
8360
8643
|
dance: {
|
|
8361
8644
|
name: "dance",
|
|
@@ -8458,15 +8741,16 @@ const Ge = {
|
|
|
8458
8741
|
duration: 5e3,
|
|
8459
8742
|
description: "Excited, energetic movement"
|
|
8460
8743
|
}
|
|
8461
|
-
}, zt = (
|
|
8744
|
+
}, zt = (G) => Ze[G] || null, Ht = (G) => Ze.hasOwnProperty(G);
|
|
8462
8745
|
export {
|
|
8746
|
+
Ct as AnimationSelector,
|
|
8463
8747
|
ft as CurriculumLearning,
|
|
8464
8748
|
yt as SimpleTalkingAvatar,
|
|
8465
8749
|
Ve as TalkingHeadAvatar,
|
|
8466
|
-
|
|
8467
|
-
|
|
8468
|
-
|
|
8750
|
+
gt as TalkingHeadComponent,
|
|
8751
|
+
Ze as animations,
|
|
8752
|
+
Pe as getActiveTTSConfig,
|
|
8469
8753
|
zt as getAnimation,
|
|
8470
8754
|
wt as getVoiceOptions,
|
|
8471
|
-
|
|
8755
|
+
Ht as hasAnimation
|
|
8472
8756
|
};
|