@sage-rsc/talking-head-react 1.0.69 → 1.0.71
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +2 -2
- package/dist/index.js +1146 -931
- package/package.json +1 -1
- package/src/components/SimpleTalkingAvatar.jsx +444 -0
- package/src/index.js +1 -0
package/dist/index.js
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
import { jsxs as
|
|
2
|
-
import { forwardRef as
|
|
3
|
-
import * as
|
|
1
|
+
import { jsxs as Pe, jsx as me } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef as Me, useRef as D, useState as ce, useEffect as de, useCallback as T, useImperativeHandle as Ee, useLayoutEffect as Xe } from "react";
|
|
3
|
+
import * as x from "three";
|
|
4
4
|
import { OrbitControls as Ye } from "three/addons/controls/OrbitControls.js";
|
|
5
5
|
import { GLTFLoader as je } from "three/addons/loaders/GLTFLoader.js";
|
|
6
6
|
import { DRACOLoader as Qe } from "three/addons/loaders/DRACOLoader.js";
|
|
7
|
-
import { FBXLoader as
|
|
7
|
+
import { FBXLoader as Oe } from "three/addons/loaders/FBXLoader.js";
|
|
8
8
|
import { RoomEnvironment as qe } from "three/addons/environments/RoomEnvironment.js";
|
|
9
|
-
import
|
|
10
|
-
let m,
|
|
11
|
-
const A = [0, 0, 0, 0], k = new
|
|
12
|
-
new
|
|
13
|
-
new
|
|
14
|
-
new
|
|
15
|
-
const
|
|
16
|
-
new
|
|
17
|
-
const
|
|
9
|
+
import Ke from "three/addons/libs/stats.module.js";
|
|
10
|
+
let m, re, ue;
|
|
11
|
+
const A = [0, 0, 0, 0], k = new x.Vector3(), ze = new x.Vector3(), ne = new x.Vector3(), Ce = new x.Vector3();
|
|
12
|
+
new x.Plane();
|
|
13
|
+
new x.Ray();
|
|
14
|
+
new x.Euler();
|
|
15
|
+
const ie = new x.Quaternion(), Ne = new x.Quaternion(), fe = new x.Matrix4(), xe = new x.Matrix4();
|
|
16
|
+
new x.Vector3();
|
|
17
|
+
const He = new x.Vector3(0, 0, 1), _e = new x.Vector3(1, 0, 0), Je = new x.Vector3(0, 1, 0), $e = new x.Vector3(0, 0, 1);
|
|
18
18
|
class et {
|
|
19
19
|
constructor(t = null) {
|
|
20
20
|
this.opt = Object.assign({
|
|
@@ -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 h = {
|
|
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
|
+
h.deltaLocal = [...s.deltaLocal];
|
|
207
207
|
}
|
|
208
|
-
i.excludes.push(
|
|
208
|
+
i.excludes.push(h);
|
|
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((h) => {
|
|
286
|
+
n.has(h) || (this.objectsUpdate.push(h), n.add(h));
|
|
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 '" +
|
|
315
|
-
const
|
|
316
|
-
name:
|
|
311
|
+
const h = s.bone;
|
|
312
|
+
i(typeof h == "string" && h.length > 0, l + "Bone name must be a non-empty string.");
|
|
313
|
+
const r = this.armature.getObjectByName(h);
|
|
314
|
+
i(r, l + "Bone '" + h + "' not found."), i(r.parent?.isBone, l + "Bone must have a parent bone."), i(this.data.every((a) => a.bone !== r), l + "Bone '" + h + "' already exists."), r.updateMatrixWorld(!0);
|
|
315
|
+
const u = {
|
|
316
|
+
name: h,
|
|
317
317
|
// Bone name
|
|
318
318
|
bone: r,
|
|
319
319
|
// Bone object
|
|
@@ -338,9 +338,9 @@ class et {
|
|
|
338
338
|
ea: [0, 0, 0, 0]
|
|
339
339
|
// External acceleration [m/s^2]
|
|
340
340
|
};
|
|
341
|
-
|
|
341
|
+
u.boneParent.matrixWorld.decompose(k, ie, ne), k.copy(He).applyQuaternion(ie).setY(0).normalize(), ie.premultiply(Ne.setFromUnitVectors(He, k).invert()).normalize(), u.qWorldInverseYaw = ie.clone().normalize(), this.data.push(u), this.dict[h] = u;
|
|
342
342
|
try {
|
|
343
|
-
this.setValue(
|
|
343
|
+
this.setValue(h, "type", s.type), this.setValue(h, "stiffness", s.stiffness), this.setValue(h, "damping", s.damping), this.setValue(h, "external", s.external), this.setValue(h, "limits", s.limits), this.setValue(h, "excludes", s.excludes), this.setValue(h, "deltaLocal", s.deltaLocal), this.setValue(h, "deltaWorld", s.deltaWorld), this.setValue(h, "pivot", s.pivot), this.setValue(h, "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], k.copy(o.vWorld),
|
|
359
|
+
if (o = this.data[e], k.copy(o.vWorld), fe.copy(o.boneParent.matrixWorld), xe.copy(fe).invert(), o.vWorld.setFromMatrixPosition(fe), k.applyMatrix4(xe), k.length() > 0.5 && (console.info("Info: Unrealistic jump of " + k.length().toFixed(2) + " meters."), k.setLength(0.5)), k.applyQuaternion(o.bone.quaternion), A[0] = k.x, A[1] = k.y, A[2] = -k.z, A[3] = k.length() / 3, o.children)
|
|
360
360
|
for (n = 0, s = o.children.length; n < s; n++)
|
|
361
361
|
m = o.children[n], A[0] -= m.v[0] * t / 3, A[1] -= m.v[1] * t / 3, A[2] += m.v[2] * t / 3, A[3] -= m.v[3] * t / 3;
|
|
362
362
|
if (m = this.opt.sensitivityFactor, A[0] *= o.ext * m, A[1] *= o.ext * m, A[2] *= o.ext * m, A[3] *= o.ext * m, o.isX && (m = A[0] / t, o.ea[0] = (m - o.ev[0]) / t, o.ev[0] = m, o.a[0] = -o.k[0] * o.p[0] - o.c[0] * o.v[0] - o.ea[0], o.p[0] += o.v[0] * t + o.a[0] * t * t / 2 + A[0], m = o.v[0] + o.a[0] * t / 2, m = -o.k[0] * o.p[0] - o.c[0] * m - o.ea[0], o.v[0] = o.v[0] + (m + o.a[0]) * t / 2), o.isY && (m = A[1] / t, o.ea[1] = (m - o.ev[1]) / t, o.ev[1] = m, o.a[1] = -o.k[1] * o.p[1] - o.c[1] * o.v[1] - o.ea[1], o.p[1] += o.v[1] * t + o.a[1] * t * t / 2 + A[1], m = o.v[1] + o.a[1] * t / 2, m = -o.k[1] * o.p[1] - o.c[1] * m - o.ea[1], o.v[1] = o.v[1] + (m + o.a[1]) * t / 2), o.isZ && (m = A[2] / t, o.ea[2] = (m - o.ev[2]) / t, o.ev[2] = m, o.a[2] = -o.k[2] * o.p[2] - o.c[2] * o.v[2] - o.ea[2], o.p[2] += o.v[2] * t + o.a[2] * t * t / 2 + A[2], m = o.v[2] + o.a[2] * t / 2, m = -o.k[2] * o.p[2] - o.c[2] * m - o.ea[2], o.v[2] = o.v[2] + (m + o.a[2]) * t / 2), o.isT && (m = A[3] / t, o.ea[3] = (m - o.ev[3]) / t, o.ev[3] = m, o.a[3] = -o.k[3] * o.p[3] - o.c[3] * o.v[3] - o.ea[3], o.p[3] += o.v[3] * t + o.a[3] * t * t / 2 + A[3], m = o.v[3] + o.a[3] * t / 2, m = -o.k[3] * o.p[3] - o.c[3] * m - o.ea[3], o.v[3] = o.v[3] + (m + o.a[3]) * t / 2), this.timerMs < this.opt.warmupMs && (o.v[0] *= 1e-4, o.p[0] *= 1e-4, o.v[1] *= 1e-4, o.p[1] *= 1e-4, o.v[2] *= 1e-4, o.p[2] *= 1e-4, o.v[3] *= 1e-4, o.p[3] *= 1e-4), A[0] = o.p[0], A[1] = o.p[1], A[2] = o.p[2], A[3] = o.p[3], m = this.opt.movementFactor, A[0] *= m, A[1] *= m, A[2] *= m, A[3] *= m, o.dl && (m = o.dl, A[0] += m[0], A[1] += m[1], A[2] += m[2]), o.dw && (m = o.dw, k.set(
|
|
363
363
|
o.vBasis.x + A[0],
|
|
364
364
|
o.vBasis.y + A[1],
|
|
365
365
|
o.vBasis.z + A[2]
|
|
366
|
-
), k.applyMatrix4(
|
|
366
|
+
), k.applyMatrix4(fe), k.x += m[0], k.y += m[1], k.z += m[2], k.applyMatrix4(xe), A[0] += k.x - o.vBasis.x, A[1] += k.y - o.vBasis.y, A[2] += k.z - o.vBasis.z), o.limits && this.opt.isLimits && (m = o.limits, m[0] && (m[0][0] !== null && A[0] < m[0][0] && (A[0] = m[0][0]), m[0][1] !== null && A[0] > m[0][1] && (A[0] = m[0][1])), m[1] && (m[1][0] !== null && A[1] < m[1][0] && (A[1] = m[1][0]), m[1][1] !== null && A[1] > m[1][1] && (A[1] = m[1][1])), m[2] && (m[2][0] !== null && A[2] < m[2][0] && (A[2] = m[2][0]), m[2][1] !== null && A[2] > m[2][1] && (A[2] = m[2][1])), m[3] && (m[3][0] !== null && A[3] < m[3][0] && (A[3] = m[3][0]), m[3][1] !== null && A[3] > m[3][1] && (A[3] = m[3][1]))), o.isPoint)
|
|
367
367
|
o.bone.position.set(
|
|
368
368
|
o.vBasis.x + A[0],
|
|
369
369
|
o.vBasis.y + A[1],
|
|
370
370
|
o.vBasis.z - A[2]
|
|
371
371
|
);
|
|
372
|
-
else if (o.boneParent.quaternion.copy(o.qBasis), o.pivot && this.opt.isPivots && (o.boneParent.updateWorldMatrix(!1, !1), o.boneParent.matrixWorld.decompose(k,
|
|
372
|
+
else if (o.boneParent.quaternion.copy(o.qBasis), o.pivot && this.opt.isPivots && (o.boneParent.updateWorldMatrix(!1, !1), o.boneParent.matrixWorld.decompose(k, ie, ne), k.copy(He).applyQuaternion(ie).setY(0).normalize(), ie.premultiply(Ne.setFromUnitVectors(He, k).invert()).normalize(), o.boneParent.quaternion.multiply(ie.invert()), o.boneParent.quaternion.multiply(o.qWorldInverseYaw)), o.isZ && (m = Math.atan(A[0] / o.l), ie.setFromAxisAngle($e, -m), o.boneParent.quaternion.multiply(ie)), o.isY && (m = o.l / 3, m = m * Math.tanh(A[1] / m), o.bone.position.setLength(o.l + m)), o.isX && (m = Math.atan(A[2] / o.l), ie.setFromAxisAngle(_e, -m), o.boneParent.quaternion.multiply(ie)), o.isT && (m = 1.5 * Math.tanh(A[3] * 1.5), ie.setFromAxisAngle(Je, -m), o.boneParent.quaternion.multiply(ie)), o.boneParent.updateWorldMatrix(!1, !0), o.excludes && this.opt.isExcludes)
|
|
373
373
|
for (n = 0, s = o.excludes.length; n < s; n++)
|
|
374
|
-
m = o.excludes[n],
|
|
374
|
+
m = o.excludes[n], ne.set(0, 0, 0), m.deltaLocal && (ne.x += m.deltaLocal[0], ne.y += m.deltaLocal[1], ne.z += m.deltaLocal[2]), ne.applyMatrix4(m.bone.matrixWorld), xe.copy(o.boneParent.matrixWorld).invert(), ne.applyMatrix4(xe), k.copy(o.bone.position), !(k.distanceToSquared(ne) >= m.radiusSq) && (ue = k.length(), re = ne.length(), !(re > m.radius + ue) && (re < Math.abs(m.radius - ue) || (re = (re * re + ue * ue - m.radiusSq) / (2 * re), ne.normalize(), Ce.copy(ne).multiplyScalar(re), re = Math.sqrt(ue * ue - re * re), k.subVectors(k, Ce).projectOnPlane(ne).normalize().multiplyScalar(re), ze.subVectors(o.vBasis, Ce).projectOnPlane(ne).normalize(), ue = ze.dot(k), ue < 0 && (ue = Math.sqrt(re * re - ue * ue), ze.multiplyScalar(ue), k.add(ze)), k.add(Ce).normalize(), ne.copy(o.bone.position).normalize(), ie.setFromUnitVectors(ne, k), o.boneParent.quaternion.premultiply(ie), o.boneParent.updateWorldMatrix(!1, !0))));
|
|
375
375
|
}
|
|
376
376
|
this.helpers.isActive && this.updateHelpers();
|
|
377
377
|
}
|
|
@@ -393,7 +393,7 @@ class et {
|
|
|
393
393
|
i || (m.excludes.bones.push(n.bone), m.excludes.radii.push(n.radius), m.excludes.deltaLocals.push(n.deltaLocal ? [...n.deltaLocal] : null), m.excludes.objects.push(null));
|
|
394
394
|
}));
|
|
395
395
|
}), m = this.helpers.excludes, this.opt.isExcludes && m.bones.length && m.bones.forEach((e, n) => {
|
|
396
|
-
const i = new
|
|
396
|
+
const i = new x.SphereGeometry(m.radii[n], 6, 6), s = new x.MeshBasicMaterial({
|
|
397
397
|
depthTest: !1,
|
|
398
398
|
depthWrite: !1,
|
|
399
399
|
toneMapped: !1,
|
|
@@ -401,18 +401,18 @@ class et {
|
|
|
401
401
|
wireframe: !0,
|
|
402
402
|
color: this.opt.helperExcludesColor
|
|
403
403
|
});
|
|
404
|
-
m.objects[n] = new
|
|
404
|
+
m.objects[n] = new x.Mesh(i, s), m.objects[n].renderOrder = 997, e.add(m.objects[n]), m.deltaLocals[n] && m.objects[n].position.set(
|
|
405
405
|
m.deltaLocals[n][0],
|
|
406
406
|
m.deltaLocals[n][1],
|
|
407
407
|
m.deltaLocals[n][2]
|
|
408
408
|
);
|
|
409
409
|
}), m = this.helpers.points, m.bones.length) {
|
|
410
410
|
this.helpers.isActive = !0;
|
|
411
|
-
const e = new
|
|
412
|
-
e.setAttribute("position", new
|
|
413
|
-
const i = new
|
|
414
|
-
e.setAttribute("color", new
|
|
415
|
-
const l = new
|
|
411
|
+
const e = new x.BufferGeometry(), n = m.bones.map((h) => [0, 0, 0]).flat();
|
|
412
|
+
e.setAttribute("position", new x.Float32BufferAttribute(n, 3));
|
|
413
|
+
const i = new x.Color(this.opt.helperBoneColor1), s = new x.Color(this.opt.helperBoneColor2), o = m.pivots.map((h) => h && this.opt.isPivots ? [s.r, s.g, s.b] : [i.r, i.g, i.b]).flat();
|
|
414
|
+
e.setAttribute("color", new x.Float32BufferAttribute(o, 3));
|
|
415
|
+
const l = new x.PointsMaterial({
|
|
416
416
|
depthTest: !1,
|
|
417
417
|
depthWrite: !1,
|
|
418
418
|
toneMapped: !1,
|
|
@@ -420,21 +420,21 @@ class et {
|
|
|
420
420
|
size: 0.2,
|
|
421
421
|
vertexColors: !0
|
|
422
422
|
});
|
|
423
|
-
m.object = new
|
|
423
|
+
m.object = new x.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
|
|
427
|
-
e.setAttribute("position", new
|
|
428
|
-
const i = new
|
|
429
|
-
e.setAttribute("color", new
|
|
430
|
-
const l = new
|
|
426
|
+
const e = new x.BufferGeometry(), n = m.bones.map((h) => [0, 0, 0, 0, 0, 0]).flat();
|
|
427
|
+
e.setAttribute("position", new x.Float32BufferAttribute(n, 3));
|
|
428
|
+
const i = new x.Color(this.opt.helperLinkColor1), s = new x.Color(this.opt.helperLinkColor2), o = m.bones.map((h) => [i.r, i.g, i.b, s.r, s.g, s.b]).flat();
|
|
429
|
+
e.setAttribute("color", new x.Float32BufferAttribute(o, 3));
|
|
430
|
+
const l = new x.LineBasicMaterial({
|
|
431
431
|
vertexColors: !0,
|
|
432
432
|
depthTest: !1,
|
|
433
433
|
depthWrite: !1,
|
|
434
434
|
toneMapped: !1,
|
|
435
435
|
transparent: !0
|
|
436
436
|
});
|
|
437
|
-
m.object = new
|
|
437
|
+
m.object = new x.LineSegments(e, l), m.object.renderOrder = 999, m.object.matrix = this.armature.matrixWorld, m.object.matrixAutoUpdate = !1, this.scene.add(m.object);
|
|
438
438
|
}
|
|
439
439
|
}
|
|
440
440
|
/**
|
|
@@ -442,17 +442,17 @@ class et {
|
|
|
442
442
|
*/
|
|
443
443
|
updateHelpers() {
|
|
444
444
|
if (m = this.helpers.points, m.bones.length) {
|
|
445
|
-
|
|
445
|
+
xe.copy(this.armature.matrixWorld).invert();
|
|
446
446
|
const t = m.object.geometry.getAttribute("position");
|
|
447
447
|
for (let e = 0, n = m.bones.length; e < n; e++)
|
|
448
|
-
|
|
448
|
+
fe.multiplyMatrices(xe, m.bones[e].matrixWorld), k.setFromMatrixPosition(fe), t.setXYZ(e, k.x, k.y, k.z);
|
|
449
449
|
t.needsUpdate = !0, m.object.updateMatrixWorld();
|
|
450
450
|
}
|
|
451
451
|
if (m = this.helpers.lines, m.bones.length) {
|
|
452
|
-
|
|
452
|
+
xe.copy(this.armature.matrixWorld).invert();
|
|
453
453
|
const t = m.object.geometry.getAttribute("position");
|
|
454
454
|
for (let e = 0, n = 0, i = m.bones.length; e < i; e++, n += 2)
|
|
455
|
-
|
|
455
|
+
fe.multiplyMatrices(xe, m.bones[e].matrixWorld), k.setFromMatrixPosition(fe), t.setXYZ(n, k.x, k.y, k.z), fe.multiplyMatrices(xe, m.bones[e].parent.matrixWorld), k.setFromMatrixPosition(fe), t.setXYZ(n + 1, k.x, k.y, k.z);
|
|
456
456
|
t.needsUpdate = !0, m.object.updateMatrixWorld();
|
|
457
457
|
}
|
|
458
458
|
}
|
|
@@ -519,13 +519,13 @@ 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 h = l * s, r = Math.min(h + i, t.length), u = t.slice(h, r), a = this.calculateEnergy(u);
|
|
523
523
|
n.energy.push(a);
|
|
524
|
-
const c = this.calculateSpectralCentroid(
|
|
524
|
+
const c = this.calculateSpectralCentroid(u);
|
|
525
525
|
n.spectralCentroid.push(c);
|
|
526
|
-
const d = this.calculateZeroCrossingRate(
|
|
526
|
+
const d = this.calculateZeroCrossingRate(u);
|
|
527
527
|
n.zeroCrossingRate.push(d);
|
|
528
|
-
const g = this.calculateMFCC(
|
|
528
|
+
const g = this.calculateMFCC(u);
|
|
529
529
|
n.mfcc.push(g);
|
|
530
530
|
}
|
|
531
531
|
return n.onsets = this.detectOnsets(n.energy), n.phonemeBoundaries = this.detectPhonemeBoundaries(n), n;
|
|
@@ -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], h = 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] = h;
|
|
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
|
|
607
|
-
let r = 1,
|
|
606
|
+
for (let h = 0; h < e; h += i) {
|
|
607
|
+
let r = 1, u = 0;
|
|
608
608
|
for (let a = 0; a < i / 2; a++) {
|
|
609
|
-
const c = n[(
|
|
610
|
-
n[(
|
|
611
|
-
const
|
|
612
|
-
r =
|
|
609
|
+
const c = n[(h + a) * 2], d = n[(h + a) * 2 + 1], g = n[(h + a + i / 2) * 2] * r - n[(h + a + i / 2) * 2 + 1] * u, y = n[(h + a + i / 2) * 2] * u + n[(h + a + i / 2) * 2 + 1] * r;
|
|
610
|
+
n[(h + a) * 2] = c + g, n[(h + a) * 2 + 1] = d + y, n[(h + a + i / 2) * 2] = c - g, n[(h + a + i / 2) * 2 + 1] = d - y;
|
|
611
|
+
const b = r * o - u * l, I = r * l + u * o;
|
|
612
|
+
r = b, u = I;
|
|
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], h = o * 0.023;
|
|
628
|
+
l > 0.1 && h - s > 0.1 && (e.push(h), s = h);
|
|
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, h = Math.abs(n[o] - n[o - 1]), r = Math.abs(i[o] - i[o - 1]), u = Math.abs(s[o] - s[o - 1]);
|
|
641
|
+
h + r * 0.1 + u * 0.5 > 0.2 && e.push(l);
|
|
642
642
|
}
|
|
643
643
|
return e;
|
|
644
644
|
}
|
|
@@ -654,14 +654,14 @@ 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 h = 0; h < i.length; h++) {
|
|
658
|
+
const r = i[h], u = this.estimateWordDuration(r, n / i.length);
|
|
659
659
|
s.push({
|
|
660
660
|
word: r,
|
|
661
661
|
startTime: o,
|
|
662
|
-
endTime: o +
|
|
663
|
-
duration:
|
|
664
|
-
}), o +=
|
|
662
|
+
endTime: o + u,
|
|
663
|
+
duration: u
|
|
664
|
+
}), o += u;
|
|
665
665
|
}
|
|
666
666
|
const l = this.generateVisemeTimings(t, e, n);
|
|
667
667
|
return {
|
|
@@ -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, h = 0;
|
|
705
705
|
for (let r = 0; r < s.length && l < o.length; r++) {
|
|
706
|
-
const
|
|
706
|
+
const u = s[r], a = o[l], c = t.energy[Math.floor(u / 0.023)] || 0, d = this.calculateVisemeDuration(a, c);
|
|
707
707
|
i.push({
|
|
708
708
|
viseme: a,
|
|
709
|
-
startTime:
|
|
710
|
-
endTime:
|
|
709
|
+
startTime: h,
|
|
710
|
+
endTime: h + d,
|
|
711
711
|
duration: d,
|
|
712
712
|
intensity: Math.min(1, c * 2)
|
|
713
713
|
// Map energy to viseme intensity
|
|
714
|
-
}),
|
|
714
|
+
}), h += d, l++;
|
|
715
715
|
}
|
|
716
716
|
for (; l < o.length; ) {
|
|
717
|
-
const r = o[l],
|
|
717
|
+
const r = o[l], u = this.calculateVisemeDuration(r, 0.5);
|
|
718
718
|
i.push({
|
|
719
719
|
viseme: r,
|
|
720
|
-
startTime:
|
|
721
|
-
endTime:
|
|
722
|
-
duration:
|
|
720
|
+
startTime: h,
|
|
721
|
+
endTime: h + u,
|
|
722
|
+
duration: u,
|
|
723
723
|
intensity: 0.6
|
|
724
|
-
}),
|
|
724
|
+
}), h += 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 h = 3; h >= 2; h--) {
|
|
779
|
+
const r = s.substr(o, h);
|
|
780
780
|
if (e[r]) {
|
|
781
|
-
n.push(e[r]), o +=
|
|
781
|
+
n.push(e[r]), o += h, l = !0;
|
|
782
782
|
break;
|
|
783
783
|
}
|
|
784
784
|
}
|
|
785
785
|
if (!l) {
|
|
786
|
-
const
|
|
787
|
-
e[
|
|
786
|
+
const h = s[o];
|
|
787
|
+
e[h] && n.push(e[h]), o++;
|
|
788
788
|
}
|
|
789
789
|
}
|
|
790
790
|
}
|
|
@@ -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), h = n.substring(i + 1, s), r = n.substring(s + 1, o), u = n.substring(o + 1), a = { regex: "", move: 0, visemes: [] };
|
|
1210
1210
|
let c = "";
|
|
1211
1211
|
c += [...l].map((g) => t[g] || g).join("");
|
|
1212
|
-
const d = [...
|
|
1213
|
-
return d[0] = d[0].toLowerCase(), c += d.join(""), a.move = d.length, c += [...r].map((g) => t[g] || g).join(""), a.regex = new RegExp(c),
|
|
1212
|
+
const d = [...h];
|
|
1213
|
+
return d[0] = d[0].toLowerCase(), c += d.join(""), a.move = d.length, c += [...r].map((g) => t[g] || g).join(""), a.regex = new RegExp(c), 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 h = [];
|
|
1328
|
+
return s ? h.push(this.convertNumberToWords(s).trim(), "thousands") : (o && h.push(this.convertNumberToWords(o).trim()), l ? h.push(this.decades[l] || this.convertNumberToWords(l).trim() + "s") : o ? h.push("hundreds") : h.push(t)), h.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 h = o[l];
|
|
1380
|
+
if ((e.words.substring(0, e.i) + s.toLowerCase() + e.words.substring(e.i + 1)).match(h.regex)) {
|
|
1381
|
+
h.visemes.forEach((a) => {
|
|
1382
1382
|
if (e.visemes.length && e.visemes[e.visemes.length - 1] === a) {
|
|
1383
1383
|
const c = 0.7 * (this.visemeDurations[a] || 1);
|
|
1384
1384
|
e.durations[e.durations.length - 1] += c, n += c;
|
|
@@ -1386,7 +1386,7 @@ class nt {
|
|
|
1386
1386
|
const c = this.visemeDurations[a] || 1;
|
|
1387
1387
|
e.visemes.push(a), e.times.push(n), e.durations.push(c), n += c;
|
|
1388
1388
|
}
|
|
1389
|
-
}), e.i +=
|
|
1389
|
+
}), e.i += h.move;
|
|
1390
1390
|
break;
|
|
1391
1391
|
}
|
|
1392
1392
|
}
|
|
@@ -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), h = n.substring(i + 1, s), r = n.substring(s + 1, o), u = n.substring(o + 1), a = { regex: "", move: 0, visemes: [] };
|
|
1620
1620
|
let c = "";
|
|
1621
1621
|
c += [...l].map((g) => t[g] || g).join("");
|
|
1622
|
-
const d = [...
|
|
1623
|
-
return d[0] = d[0].toLowerCase(), c += d.join(""), a.move = d.length, c += [...r].map((g) => t[g] || g).join(""), a.regex = new RegExp(c),
|
|
1622
|
+
const d = [...h];
|
|
1623
|
+
return d[0] = d[0].toLowerCase(), c += d.join(""), a.move = d.length, c += [...r].map((g) => t[g] || g).join(""), a.regex = new RegExp(c), u.length && u.split(" ").forEach((g) => {
|
|
1624
1624
|
a.visemes.push(g);
|
|
1625
1625
|
}), a;
|
|
1626
1626
|
});
|
|
@@ -1732,8 +1732,8 @@ 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 h = 0; h < o.length; h++) {
|
|
1736
|
+
const r = o[h];
|
|
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((c) => {
|
|
1739
1739
|
if (e.visemes.length && e.visemes[e.visemes.length - 1] === c) {
|
|
@@ -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), h = n.substring(i + 1, s), r = n.substring(s + 1, o), u = n.substring(o + 1), a = { regex: "", move: 0, visemes: [] };
|
|
2135
2135
|
let c = "";
|
|
2136
2136
|
c += [...l].map((g) => t[g] || g).join("");
|
|
2137
|
-
const d = [...
|
|
2138
|
-
return d[0] = d[0].toLowerCase(), c += d.join(""), a.move = d.length, c += [...r].map((g) => t[g] || g).join(""), a.regex = new RegExp(c, "i"),
|
|
2137
|
+
const d = [...h];
|
|
2138
|
+
return d[0] = d[0].toLowerCase(), c += d.join(""), a.move = d.length, c += [...r].map((g) => t[g] || g).join(""), a.regex = new RegExp(c, "i"), u.length && u.split(" ").forEach((g) => {
|
|
2139
2139
|
g && a.visemes.push(g);
|
|
2140
2140
|
}), a;
|
|
2141
2141
|
});
|
|
@@ -2267,8 +2267,8 @@ 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 h = 0; h < o.length; h++) {
|
|
2271
|
+
const r = o[h];
|
|
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((c) => {
|
|
2274
2274
|
if (e.visemes.length && e.visemes[e.visemes.length - 1] === c) {
|
|
@@ -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, h, r) => {
|
|
2385
2385
|
if (s < o) return s;
|
|
2386
|
-
const
|
|
2387
|
-
return e.push(l + (
|
|
2386
|
+
const u = Math.floor(s / o);
|
|
2387
|
+
return e.push(l + (u === 1 ? h : 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,11 +2436,11 @@ class lt {
|
|
|
2436
2436
|
return e;
|
|
2437
2437
|
}
|
|
2438
2438
|
}
|
|
2439
|
-
const
|
|
2439
|
+
const ut = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
2440
2440
|
__proto__: null,
|
|
2441
2441
|
LipsyncFi: lt
|
|
2442
2442
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
2443
|
-
class
|
|
2443
|
+
class ht {
|
|
2444
2444
|
/**
|
|
2445
2445
|
* @constructor
|
|
2446
2446
|
*/
|
|
@@ -2559,10 +2559,10 @@ class ut {
|
|
|
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, h, r) => {
|
|
2563
2563
|
if (s < o) return s;
|
|
2564
|
-
const
|
|
2565
|
-
return
|
|
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(h), 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 ut {
|
|
|
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 h = 0.7 * (this.durations[o] || 1);
|
|
2612
|
+
e.durations[e.durations.length - 1] += h, n += h;
|
|
2613
2613
|
} else {
|
|
2614
|
-
const
|
|
2615
|
-
e.visemes.push(l), e.times.push(n), e.durations.push(
|
|
2614
|
+
const h = this.durations[o] || 1;
|
|
2615
|
+
e.visemes.push(l), e.times.push(n), e.durations.push(h), n += h;
|
|
2616
2616
|
}
|
|
2617
2617
|
else
|
|
2618
2618
|
n += this.pauses[i[s]] || 0;
|
|
@@ -2622,22 +2622,22 @@ class ut {
|
|
|
2622
2622
|
}
|
|
2623
2623
|
const ct = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
2624
2624
|
__proto__: null,
|
|
2625
|
-
LipsyncLt:
|
|
2626
|
-
}, Symbol.toStringTag, { value: "Module" })), dt = new URL("data:text/javascript;base64,Y2xhc3MgUGxheWJhY2tXb3JrbGV0IGV4dGVuZHMgQXVkaW9Xb3JrbGV0UHJvY2Vzc29yIHsKICBzdGF0aWMgRlNNID0gewogICAgSURMRTogMCwKICAgIFBMQVlJTkc6IDEsCiAgfTsKCiAgY29uc3RydWN0b3Iob3B0aW9ucykgewogICAgc3VwZXIoKTsKICAgIHRoaXMucG9ydC5vbm1lc3NhZ2UgPSB0aGlzLmhhbmRsZU1lc3NhZ2UuYmluZCh0aGlzKTsKCiAgICB0aGlzLl9zYW1wbGVSYXRlID0gb3B0aW9ucz8ucHJvY2Vzc29yT3B0aW9ucz8uc2FtcGxlUmF0ZSB8fCBzYW1wbGVSYXRlOwogICAgdGhpcy5fc2NhbGUgPSAxIC8gMzI3Njg7IC8vIFBDTTE2IC0+IGZsb2F0CgogICAgLy8gU2lsZW5jZSBkZXRlY3Rpb24gdGhyZXNob2xkICgxIHNlY29uZCkgYXMgYSBmYWxsYmFjayBzYWZldHkgbmV0CiAgICBjb25zdCBzaWxlbmNlRHVyYXRpb25TZWNvbmRzID0gMS4wOwogICAgdGhpcy5fc2lsZW5jZVRocmVzaG9sZEJsb2NrcyA9IE1hdGguY2VpbCgodGhpcy5fc2FtcGxlUmF0ZSAqIHNpbGVuY2VEdXJhdGlvblNlY29uZHMpIC8gMTI4KTsKCiAgICAvLyBNZXRyaWNzIGNvbmZpZ3VyYXRpb24gdmlhIG9wdGlvbnMKICAgIGNvbnN0IG1ldHJpY3NDZmcgPSBvcHRpb25zPy5wcm9jZXNzb3JPcHRpb25zPy5tZXRyaWNzIHx8IHt9OwogICAgdGhpcy5fbWV0cmljc0VuYWJsZWQgPSBtZXRyaWNzQ2ZnLmVuYWJsZWQgIT09IGZhbHNlOwogICAgY29uc3QgaW50ZXJ2YWxIeiA9ICh0eXBlb2YgbWV0cmljc0NmZy5pbnRlcnZhbEh6ID09PSAibnVtYmVyIiAmJiBtZXRyaWNzQ2ZnLmludGVydmFsSHogPiAwKQogICAgICA/IG1ldHJpY3NDZmcuaW50ZXJ2YWxIeiA6IDI7CiAgICAvLyBNZXRyaWNzIHN0YXRlIChsb3ctb3ZlcmhlYWQpCiAgICB0aGlzLl9mcmFtZXNQcm9jZXNzZWQgPSAwOwogICAgdGhpcy5fdW5kZXJydW5CbG9ja3MgPSAwOwogICAgdGhpcy5fbWF4UXVldWVTYW1wbGVzID0gMDsKICAgIHRoaXMuX2xhc3RNZXRyaWNzU2VudEF0RnJhbWUgPSAwOwogICAgLy8gQ29udmVydCB0byBmcmFtZXMgYmV0d2VlbiByZXBvcnRzCiAgICB0aGlzLl9tZXRyaWNzSW50ZXJ2YWxGcmFtZXMgPSBNYXRoLm1heCgxMjgsIE1hdGgucm91bmQodGhpcy5fc2FtcGxlUmF0ZSAvIGludGVydmFsSHopKTsKCiAgICB0aGlzLnJlc2V0KCk7CiAgfQoKICAvKioKICAgKiBSZXNldHMgdGhlIHdvcmtsZXQgdG8gaXRzIGluaXRpYWwgSURMRSBzdGF0ZS4KICAgKi8KICByZXNldCgpIHsKICAgIHRoaXMuX2J1ZmZlclF1ZXVlID0gW107CiAgICB0aGlzLl9jdXJyZW50Q2h1bmsgPSBudWxsOwogICAgdGhpcy5fY3VycmVudENodW5rT2Zmc2V0ID0gMDsKICAgIHRoaXMuX3N0YXRlID0gUGxheWJhY2tXb3JrbGV0LkZTTS5JRExFOwoKICAgIHRoaXMuX25vTW9yZURhdGFSZWNlaXZlZCA9IGZhbHNlOwogICAgdGhpcy5fc2lsZW5jZUZyYW1lc0NvdW50ID0gMDsKICAgIHRoaXMuX2hhc1NlbnRFbmRlZCA9IGZhbHNlOwogICAgLy8gUmVzZXQgbWF4IHF1ZXVlIHRyYWNrZXIgb25seSB3aGVuIGdvaW5nIGlkbGUKICAgIHRoaXMuX21heFF1ZXVlU2FtcGxlcyA9IDA7CiAgfQoKICBoYW5kbGVNZXNzYWdlKGV2ZW50KSB7CiAgICBjb25zdCB7IHR5cGUsIGRhdGEgfSA9IGV2ZW50LmRhdGE7CgogICAgLy8gSU5URVJSVVBUOiBUaGUgbWFpbiB0aHJlYWQgd2FudHMgdG8gc3RvcCBpbW1lZGlhdGVseS4KICAgIGlmICh0eXBlID09PSAic3RvcCIpIHsKICAgICAgdGhpcy5yZXNldCgpOwogICAgICAvLyBTZW5kIGZpbmFsIG1ldHJpY3Mgc2hvd2luZyBjbGVhcmVkIHN0YXRlCiAgICAgIGlmICh0aGlzLl9tZXRyaWNzRW5hYmxlZCkgewogICAgICAgIHRyeSB7CiAgICAgICAgICB0aGlzLnBvcnQucG9zdE1lc3NhZ2UoewogICAgICAgICAgICB0eXBlOiAibWV0cmljcyIsCiAgICAgICAgICAgIGRhdGE6IHsKICAgICAgICAgICAgICBzdGF0ZTogUGxheWJhY2tXb3JrbGV0LkZTTS5JRExFLAogICAgICAgICAgICAgIHF1ZXVlZFNhbXBsZXM6IDAsCiAgICAgICAgICAgICAgcXVldWVkTXM6IDAsCiAgICAgICAgICAgICAgbWF4UXVldWVkTXM6IE1hdGgucm91bmQoKHRoaXMuX21heFF1ZXVlU2FtcGxlcyAvIHRoaXMuX3NhbXBsZVJhdGUpICogMTAwMCksCiAgICAgICAgICAgICAgdW5kZXJydW5CbG9ja3M6IHRoaXMuX3VuZGVycnVuQmxvY2tzLAogICAgICAgICAgICAgIGZyYW1lc1Byb2Nlc3NlZDogdGhpcy5fZnJhbWVzUHJvY2Vzc2VkCiAgICAgICAgICAgIH0KICAgICAgICAgIH0pOwogICAgICAgIH0gY2F0Y2ggKF8pIHsgfQogICAgICB9CiAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBNYWluIHRocmVhZCBoYXMgc2lnbmFsZWQgdGhhdCBubyBtb3JlIGF1ZGlvIGNodW5rcyB3aWxsIGJlIHNlbnQgZm9yIHRoaXMgdXR0ZXJhbmNlLgogICAgaWYgKHR5cGUgPT09ICJuby1tb3JlLWRhdGEiKSB7CiAgICAgIHRoaXMuX25vTW9yZURhdGFSZWNlaXZlZCA9IHRydWU7CiAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBVcGRhdGUgbWV0cmljcyBjb25maWd1cmF0aW9uIGF0IHJ1bnRpbWUKICAgIGlmICh0eXBlID09PSAiY29uZmlnLW1ldHJpY3MiICYmIGRhdGEgJiYgdHlwZW9mIGRhdGEgPT09ICJvYmplY3QiKSB7CiAgICAgIGlmICgiZW5hYmxlZCIgaW4gZGF0YSkgdGhpcy5fbWV0cmljc0VuYWJsZWQgPSAhIWRhdGEuZW5hYmxlZDsKICAgICAgaWYgKHR5cGVvZiBkYXRhLmludGVydmFsSHogPT09ICJudW1iZXIiICYmIGRhdGEuaW50ZXJ2YWxIeiA+IDApIHsKICAgICAgICBjb25zdCBpbnRlcnZhbEh6ID0gZGF0YS5pbnRlcnZhbEh6OwogICAgICAgIHRoaXMuX21ldHJpY3NJbnRlcnZhbEZyYW1lcyA9IE1hdGgubWF4KDEyOCwgTWF0aC5yb3VuZCh0aGlzLl9zYW1wbGVSYXRlIC8gaW50ZXJ2YWxIeikpOwogICAgICB9CiAgICAgIC8vIFJlc2V0IHBhY2luZyBzbyB0aGUgbmV4dCByZXBvcnQgYWxpZ25zIHdpdGggbmV3IGludGVydmFsCiAgICAgIHRoaXMuX2xhc3RNZXRyaWNzU2VudEF0RnJhbWUgPSB0aGlzLl9mcmFtZXNQcm9jZXNzZWQ7CiAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBOZXcgYXVkaW8gZGF0YSBoYXMgYXJyaXZlZC4KICAgIGlmICh0eXBlID09PSAiYXVkaW9EYXRhIiAmJiBkYXRhIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHsKICAgICAgdGhpcy5fbm9Nb3JlRGF0YVJlY2VpdmVkID0gZmFsc2U7CiAgICAgIC8vIElmIHdlIHdlcmUgaWRsZSwgdGhpcyBuZXcgZGF0YSBraWNrcyBvZmYgdGhlIHBsYXliYWNrLgogICAgICBpZiAodGhpcy5fc3RhdGUgPT09IFBsYXliYWNrV29ya2xldC5GU00uSURMRSkgewogICAgICAgIHRoaXMuX3N0YXRlID0gUGxheWJhY2tXb3JrbGV0LkZTTS5QTEFZSU5HOwogICAgICAgIHRoaXMucG9ydC5wb3N0TWVzc2FnZSh7IHR5cGU6ICJwbGF5YmFjay1zdGFydGVkIiB9KTsKICAgICAgfQoKICAgICAgLy8gV2Ugb25seSBxdWV1ZSBkYXRhIGlmIHdlIGFyZSBpbiB0aGUgUExBWUlORyBzdGF0ZS4gVGhpcyBwcmV2ZW50cwogICAgICAvLyBkYXRhIGZyb20gYSBwcmV2aW91cywgaW50ZXJydXB0ZWQgc3RyZWFtIGZyb20gbGluZ2VyaW5nLgogICAgICBpZiAodGhpcy5fc3RhdGUgPT09IFBsYXliYWNrV29ya2xldC5GU00uUExBWUlORykgewogICAgICAgIC8vIFN0b3JlIGFzIEludDE2QXJyYXkgdmlldyB0byBhdm9pZCBjb25zdHJ1Y3RpbmcgaXQgaW4gcHJvY2VzcygpCiAgICAgICAgdGhpcy5fYnVmZmVyUXVldWUucHVzaChuZXcgSW50MTZBcnJheShkYXRhKSk7CiAgICAgICAgdGhpcy5fc2lsZW5jZUZyYW1lc0NvdW50ID0gMDsgLy8gUmVzZXQgc2lsZW5jZSBjb3VudGVyIG9uIG5ldyBkYXRhCiAgICAgIH0KICAgIH0KICB9CgogIHByb2Nlc3MoaW5wdXRzLCBvdXRwdXRzLCBwYXJhbWV0ZXJzKSB7CiAgICBjb25zdCBvdXRwdXRDaGFubmVsID0gb3V0cHV0c1swXT8uWzBdOwogICAgaWYgKCFvdXRwdXRDaGFubmVsKSB7CiAgICAgIHJldHVybiB0cnVlOyAvLyBLZWVwIGFsaXZlIGV2ZW4gaWYgb3V0cHV0IGlzIHRlbXBvcmFyaWx5IGRpc2Nvbm5lY3RlZAogICAgfQoKICAgIC8vIElmIHdlIGFyZSBub3QgcGxheWluZywganVzdCBvdXRwdXQgc2lsZW5jZSBhbmQgd2FpdC4KICAgIGlmICh0aGlzLl9zdGF0ZSAhPT0gUGxheWJhY2tXb3JrbGV0LkZTTS5QTEFZSU5HKSB7CiAgICAgIG91dHB1dENoYW5uZWwuZmlsbCgwKTsKICAgICAgcmV0dXJuIHRydWU7IC8vIEFsd2F5cyByZXR1cm4gdHJ1ZSB0byBrZWVwIHRoZSBwcm9jZXNzb3IgYWxpdmUKICAgIH0KCiAgICAvLyBDb3JlIFBMQVlJTkcgTG9naWMKICAgIGNvbnN0IGJsb2NrU2l6ZSA9IG91dHB1dENoYW5uZWwubGVuZ3RoOwogICAgbGV0IHNhbXBsZXNDb3BpZWQgPSAwOwoKICAgIHdoaWxlIChzYW1wbGVzQ29waWVkIDwgYmxvY2tTaXplKSB7CiAgICAgIGlmICghdGhpcy5fY3VycmVudENodW5rIHx8IHRoaXMuX2N1cnJlbnRDaHVua09mZnNldCA+PSB0aGlzLl9jdXJyZW50Q2h1bmsubGVuZ3RoKSB7CiAgICAgICAgaWYgKHRoaXMuX2J1ZmZlclF1ZXVlLmxlbmd0aCA+IDApIHsKICAgICAgICAgIHRoaXMuX2N1cnJlbnRDaHVuayA9IHRoaXMuX2J1ZmZlclF1ZXVlLnNoaWZ0KCk7CiAgICAgICAgICB0aGlzLl9jdXJyZW50Q2h1bmtPZmZzZXQgPSAwOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAvLyBCdWZmZXIgaXMgZW1wdHkuIENoZWNrIGZvciBlbmQgY29uZGl0aW9ucy4KICAgICAgICAgIGNvbnN0IGlzVGltZWRPdXQgPSB0aGlzLl9zaWxlbmNlRnJhbWVzQ291bnQgPiB0aGlzLl9zaWxlbmNlVGhyZXNob2xkQmxvY2tzOwoKICAgICAgICAgIGlmICh0aGlzLl9ub01vcmVEYXRhUmVjZWl2ZWQgfHwgaXNUaW1lZE91dCkgewogICAgICAgICAgICAvLyBFTkQgT0YgUExBWUJBQ0s6IEVpdGhlciBleHBsaWNpdGx5IHNpZ25hbGVkIG9yIHRpbWVkIG91dC4KICAgICAgICAgICAgaWYgKCF0aGlzLl9oYXNTZW50RW5kZWQpIHsKICAgICAgICAgICAgICB0aGlzLnBvcnQucG9zdE1lc3NhZ2UoeyB0eXBlOiAicGxheWJhY2stZW5kZWQiIH0pOwogICAgICAgICAgICAgIHRoaXMuX2hhc1NlbnRFbmRlZCA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gU2VuZCBmaW5hbCBtZXRyaWNzIHNob3dpbmcgY2xlYXJlZCBzdGF0ZQogICAgICAgICAgICBpZiAodGhpcy5fbWV0cmljc0VuYWJsZWQpIHsKICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgdGhpcy5wb3J0LnBvc3RNZXNzYWdlKHsKICAgICAgICAgICAgICAgICAgdHlwZTogIm1ldHJpY3MiLAogICAgICAgICAgICAgICAgICBkYXRhOiB7CiAgICAgICAgICAgICAgICAgICAgc3RhdGU6IFBsYXliYWNrV29ya2xldC5GU00uSURMRSwKICAgICAgICAgICAgICAgICAgICBxdWV1ZWRTYW1wbGVzOiAwLAogICAgICAgICAgICAgICAgICAgIHF1ZXVlZE1zOiAwLAogICAgICAgICAgICAgICAgICAgIG1heFF1ZXVlZE1zOiBNYXRoLnJvdW5kKCh0aGlzLl9tYXhRdWV1ZVNhbXBsZXMgLyB0aGlzLl9zYW1wbGVSYXRlKSAqIDEwMDApLAogICAgICAgICAgICAgICAgICAgIHVuZGVycnVuQmxvY2tzOiB0aGlzLl91bmRlcnJ1bkJsb2NrcywKICAgICAgICAgICAgICAgICAgICBmcmFtZXNQcm9jZXNzZWQ6IHRoaXMuX2ZyYW1lc1Byb2Nlc3NlZAogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICB9IGNhdGNoIChfKSB7IH0KICAgICAgICAgICAgfQogICAgICAgICAgICB0aGlzLnJlc2V0KCk7IC8vIFJlc2V0IHRvIElETEUgc3RhdGUgZm9yIHJldXNlCiAgICAgICAgICAgIGJyZWFrOyAvLyBFeGl0IHdoaWxlIGxvb3AKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8vIEJVRkZFUiBVTkRFUlJVTiAoTEFHKTogUGxheSBzaWxlbmNlIGFuZCB3YWl0IGZvciBtb3JlIGRhdGEuCiAgICAgICAgICAgIHRoaXMuX3NpbGVuY2VGcmFtZXNDb3VudCsrOwogICAgICAgICAgICBpZiAodGhpcy5fbWV0cmljc0VuYWJsZWQpIHRoaXMuX3VuZGVycnVuQmxvY2tzKys7CiAgICAgICAgICAgIGJyZWFrOyAvLyBFeGl0IHdoaWxlIGxvb3AKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KCiAgICAgIC8vIElmIHdlIGhhdmUgYSBjaHVuayAoY291bGQgYmUgYSBuZXcgb25lIGZyb20gdGhlIGxvZ2ljIGFib3ZlKSwgcHJvY2VzcyBpdC4KICAgICAgaWYgKHRoaXMuX2N1cnJlbnRDaHVuaykgewogICAgICAgIGNvbnN0IHNhbXBsZXNUb0NvcHkgPSBNYXRoLm1pbigKICAgICAgICAgIGJsb2NrU2l6ZSAtIHNhbXBsZXNDb3BpZWQsCiAgICAgICAgICB0aGlzLl9jdXJyZW50Q2h1bmsubGVuZ3RoIC0gdGhpcy5fY3VycmVudENodW5rT2Zmc2V0CiAgICAgICAgKTsKICAgICAgICAvLyBEaXJlY3RseSB3cml0ZSB0byBvdXRwdXRDaGFubmVsIHRvIGF2b2lkIGV4dHJhIGNvcHkKICAgICAgICBjb25zdCBzcmMgPSB0aGlzLl9jdXJyZW50Q2h1bms7CiAgICAgICAgY29uc3QgYmFzZVNyYyA9IHRoaXMuX2N1cnJlbnRDaHVua09mZnNldDsKICAgICAgICBjb25zdCBiYXNlRHN0ID0gc2FtcGxlc0NvcGllZDsKICAgICAgICBjb25zdCBzY2FsZSA9IHRoaXMuX3NjYWxlOwogICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2FtcGxlc1RvQ29weTsgaSsrKSB7CiAgICAgICAgICBvdXRwdXRDaGFubmVsW2Jhc2VEc3QgKyBpXSA9IHNyY1tiYXNlU3JjICsgaV0gKiBzY2FsZTsKICAgICAgICB9CgogICAgICAgIHRoaXMuX2N1cnJlbnRDaHVua09mZnNldCArPSBzYW1wbGVzVG9Db3B5OwogICAgICAgIHNhbXBsZXNDb3BpZWQgKz0gc2FtcGxlc1RvQ29weTsKICAgICAgfQogICAgfQoKICAgIC8vIFplcm8tZmlsbCB0aGUgcmVtYWluZGVyLCBpZiBhbnksIG9uY2UgcGVyIGJsb2NrCiAgICBpZiAoc2FtcGxlc0NvcGllZCA8IGJsb2NrU2l6ZSkgewogICAgICBvdXRwdXRDaGFubmVsLmZpbGwoMCwgc2FtcGxlc0NvcGllZCk7CiAgICB9CgogICAgLy8gVXBkYXRlIG1ldHJpY3MgKG9wdGlvbmFsKQogICAgaWYgKHRoaXMuX21ldHJpY3NFbmFibGVkKSB7CiAgICAgIHRoaXMuX2ZyYW1lc1Byb2Nlc3NlZCArPSBibG9ja1NpemU7CgogICAgICAvLyBUcmFjayBxdWV1ZSBkZXB0aCBpbiBzYW1wbGVzIChhcHByb3hpbWF0ZSkKICAgICAgbGV0IHF1ZXVlZFNhbXBsZXMgPSAwOwogICAgICBpZiAodGhpcy5fY3VycmVudENodW5rKSBxdWV1ZWRTYW1wbGVzICs9IE1hdGgubWF4KDAsIHRoaXMuX2N1cnJlbnRDaHVuay5sZW5ndGggLSB0aGlzLl9jdXJyZW50Q2h1bmtPZmZzZXQpOwogICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX2J1ZmZlclF1ZXVlLmxlbmd0aDsgaSsrKSBxdWV1ZWRTYW1wbGVzICs9IHRoaXMuX2J1ZmZlclF1ZXVlW2ldLmxlbmd0aDsKICAgICAgaWYgKHF1ZXVlZFNhbXBsZXMgPiB0aGlzLl9tYXhRdWV1ZVNhbXBsZXMpIHRoaXMuX21heFF1ZXVlU2FtcGxlcyA9IHF1ZXVlZFNhbXBsZXM7CgogICAgICAvLyBQZXJpb2RpY2FsbHkgc2VuZCBtZXRyaWNzIHRvIG1haW4gdGhyZWFkCiAgICAgIGlmICh0aGlzLl9mcmFtZXNQcm9jZXNzZWQgLSB0aGlzLl9sYXN0TWV0cmljc1NlbnRBdEZyYW1lID49IHRoaXMuX21ldHJpY3NJbnRlcnZhbEZyYW1lcykgewogICAgICAgIHRoaXMuX2xhc3RNZXRyaWNzU2VudEF0RnJhbWUgPSB0aGlzLl9mcmFtZXNQcm9jZXNzZWQ7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIHRoaXMucG9ydC5wb3N0TWVzc2FnZSh7CiAgICAgICAgICAgIHR5cGU6ICJtZXRyaWNzIiwKICAgICAgICAgICAgZGF0YTogewogICAgICAgICAgICAgIHN0YXRlOiB0aGlzLl9zdGF0ZSwKICAgICAgICAgICAgICBxdWV1ZWRTYW1wbGVzLAogICAgICAgICAgICAgIHF1ZXVlZE1zOiBNYXRoLnJvdW5kKChxdWV1ZWRTYW1wbGVzIC8gdGhpcy5fc2FtcGxlUmF0ZSkgKiAxMDAwKSwKICAgICAgICAgICAgICBtYXhRdWV1ZWRNczogTWF0aC5yb3VuZCgodGhpcy5fbWF4UXVldWVTYW1wbGVzIC8gdGhpcy5fc2FtcGxlUmF0ZSkgKiAxMDAwKSwKICAgICAgICAgICAgICB1bmRlcnJ1bkJsb2NrczogdGhpcy5fdW5kZXJydW5CbG9ja3MsCiAgICAgICAgICAgICAgZnJhbWVzUHJvY2Vzc2VkOiB0aGlzLl9mcmFtZXNQcm9jZXNzZWQKICAgICAgICAgICAgfQogICAgICAgICAgfSk7CiAgICAgICAgfSBjYXRjaCAoXykgeyB9CiAgICAgICAgLy8gRG9uJ3QgcmVzZXQgbWF4IHRyYWNrZXIgLSBrZWVwIHNlc3Npb24gcGVhayB1bnRpbCBpZGxlCiAgICAgIH0KICAgIH0KCiAgICAvLyBBTFdBWVMgcmV0dXJuIHRydWUgdG8ga2VlcCB0aGUgcHJvY2Vzc29yIGFsaXZlIGZvciByZXVzZS4KICAgIHJldHVybiB0cnVlOwogIH0KfQoKcmVnaXN0ZXJQcm9jZXNzb3IoInBsYXliYWNrLXdvcmtsZXQiLCBQbGF5YmFja1dvcmtsZXQpOwo=", import.meta.url), Pe = {
|
|
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
2627
|
en: it,
|
|
2628
2628
|
de: st,
|
|
2629
2629
|
fr: rt,
|
|
2630
|
-
fi:
|
|
2630
|
+
fi: ut,
|
|
2631
2631
|
lt: ct
|
|
2632
|
-
},
|
|
2633
|
-
new
|
|
2634
|
-
new
|
|
2635
|
-
new
|
|
2636
|
-
new
|
|
2637
|
-
const mt = new
|
|
2638
|
-
new
|
|
2639
|
-
new
|
|
2640
|
-
class
|
|
2632
|
+
}, Q = new x.Quaternion(), W = new x.Euler(), ve = new x.Vector3(), Re = new x.Vector3(), We = new x.Box3();
|
|
2633
|
+
new x.Matrix4();
|
|
2634
|
+
new x.Matrix4();
|
|
2635
|
+
new x.Vector3();
|
|
2636
|
+
new x.Vector3(0, 0, 1);
|
|
2637
|
+
const mt = new x.Vector3(1, 0, 0);
|
|
2638
|
+
new x.Vector3(0, 1, 0);
|
|
2639
|
+
new x.Vector3(0, 0, 1);
|
|
2640
|
+
class Be {
|
|
2641
2641
|
/**
|
|
2642
2642
|
* Avatar.
|
|
2643
2643
|
* @typedef {Object} Avatar
|
|
@@ -2763,7 +2763,7 @@ class Ne {
|
|
|
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 Ne {
|
|
|
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((h) => {
|
|
3573
|
+
this.poseDelta.props[l + h + ".quaternion"] = { x: 0, y: 0, z: 0 };
|
|
3574
|
+
}), ["HandThumb", "HandIndex", "HandMiddle", "HandRing", "HandPinky"].forEach((h) => {
|
|
3575
|
+
this.poseDelta.props[l + h + "1.quaternion"] = { x: 0, y: 0, z: 0 }, this.poseDelta.props[l + h + "2.quaternion"] = { x: 0, y: 0, z: 0 }, this.poseDelta.props[l + h + "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((h) => n.add(h));
|
|
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 = {
|
|
@@ -4049,22 +4049,22 @@ class Ne {
|
|
|
4049
4049
|
if (this.isAvatarOnly = this.opt.avatarOnly, this.isAvatarOnly)
|
|
4050
4050
|
this.scene = this.opt.avatarOnlyScene, this.camera = this.opt.avatarOnlyCamera;
|
|
4051
4051
|
else {
|
|
4052
|
-
this.renderer = new
|
|
4053
|
-
new
|
|
4052
|
+
this.renderer = new x.WebGLRenderer({ antialias: !0, alpha: !0 }), this.renderer.setPixelRatio(this.opt.modelPixelRatio * window.devicePixelRatio), this.renderer.setSize(this.nodeAvatar.clientWidth, this.nodeAvatar.clientHeight), this.renderer.outputColorSpace = x.SRGBColorSpace, this.renderer.toneMapping = x.ACESFilmicToneMapping, this.renderer.shadowMap.enabled = !1, this.nodeAvatar.appendChild(this.renderer.domElement), this.camera = new x.PerspectiveCamera(10, this.nodeAvatar.clientWidth / this.nodeAvatar.clientHeight, 0.1, 2e3), this.scene = new x.Scene(), this.lightAmbient = new x.AmbientLight(
|
|
4053
|
+
new x.Color(this.opt.lightAmbientColor),
|
|
4054
4054
|
this.opt.lightAmbientIntensity
|
|
4055
|
-
), this.lightDirect = new
|
|
4056
|
-
new
|
|
4055
|
+
), this.lightDirect = new x.DirectionalLight(
|
|
4056
|
+
new x.Color(this.opt.lightDirectColor),
|
|
4057
4057
|
this.opt.lightDirectIntensity
|
|
4058
|
-
), this.lightSpot = new
|
|
4059
|
-
new
|
|
4058
|
+
), this.lightSpot = new x.SpotLight(
|
|
4059
|
+
new x.Color(this.opt.lightSpotColor),
|
|
4060
4060
|
this.opt.lightSpotIntensity,
|
|
4061
4061
|
0,
|
|
4062
4062
|
this.opt.lightSpotDispersion
|
|
4063
4063
|
), this.setLighting(this.opt);
|
|
4064
|
-
const l = new
|
|
4064
|
+
const l = new x.PMREMGenerator(this.renderer);
|
|
4065
4065
|
l.compileEquirectangularShader(), this.scene.environment = l.fromScene(new qe()).texture, this.resizeobserver = new ResizeObserver(this.onResize.bind(this)), this.resizeobserver.observe(this.nodeAvatar), this.controls = new 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;
|
|
4066
4066
|
}
|
|
4067
|
-
this.ikMesh = new
|
|
4067
|
+
this.ikMesh = new x.SkinnedMesh();
|
|
4068
4068
|
const s = {
|
|
4069
4069
|
LeftShoulder: null,
|
|
4070
4070
|
LeftArm: "LeftShoulder",
|
|
@@ -4077,10 +4077,10 @@ class Ne {
|
|
|
4077
4077
|
RightHand: "RightForeArm",
|
|
4078
4078
|
RightHandMiddle1: "RightHand"
|
|
4079
4079
|
}, o = [];
|
|
4080
|
-
Object.entries(s).forEach((l,
|
|
4081
|
-
const r = new
|
|
4080
|
+
Object.entries(s).forEach((l, h) => {
|
|
4081
|
+
const r = new x.Bone();
|
|
4082
4082
|
r.name = l[0], l[1] ? this.ikMesh.getObjectByName(l[1]).add(r) : this.ikMesh.add(r), o.push(r);
|
|
4083
|
-
}), this.ikMesh.bind(new
|
|
4083
|
+
}), this.ikMesh.bind(new x.Skeleton(o)), this.dynamicbones = new et(), this.isStreaming = !1, this.streamWorkletNode = null, this.streamAudioStartTime = null, this.streamWaitForAudioChunks = !0, this.streamLipsyncLang = null, this.streamLipsyncType = "visemes", this.streamLipsyncQueue = [];
|
|
4084
4084
|
}
|
|
4085
4085
|
/**
|
|
4086
4086
|
* Helper that re/creates the audio context and the other nodes.
|
|
@@ -4126,9 +4126,9 @@ class Ne {
|
|
|
4126
4126
|
let e = 3 * t.length / 4;
|
|
4127
4127
|
t[t.length - 1] === "=" && (e--, t[t.length - 2] === "=" && e--);
|
|
4128
4128
|
const n = new ArrayBuffer(e), i = new Uint8Array(n);
|
|
4129
|
-
let s, o = 0, l,
|
|
4129
|
+
let s, o = 0, l, h, r, u;
|
|
4130
4130
|
for (s = 0; s < t.length; s += 4)
|
|
4131
|
-
l = this.b64Lookup[t.charCodeAt(s)],
|
|
4131
|
+
l = this.b64Lookup[t.charCodeAt(s)], h = this.b64Lookup[t.charCodeAt(s + 1)], r = this.b64Lookup[t.charCodeAt(s + 2)], u = this.b64Lookup[t.charCodeAt(s + 3)], i[o++] = l << 2 | h >> 4, i[o++] = (h & 15) << 4 | r >> 2, i[o++] = (r & 3) << 6 | u & 63;
|
|
4132
4132
|
return n;
|
|
4133
4133
|
}
|
|
4134
4134
|
/**
|
|
@@ -4169,8 +4169,8 @@ class Ne {
|
|
|
4169
4169
|
const e = {};
|
|
4170
4170
|
for (let [n, i] of Object.entries(t)) {
|
|
4171
4171
|
const s = n.split(".");
|
|
4172
|
-
let o = Array.isArray(i.x) ? this.gaussianRandom(...i.x) : i.x, l = Array.isArray(i.y) ? this.gaussianRandom(...i.y) : i.y,
|
|
4173
|
-
s[1] === "position" || s[1] === "scale" ? e[n] = new
|
|
4172
|
+
let o = Array.isArray(i.x) ? this.gaussianRandom(...i.x) : i.x, l = Array.isArray(i.y) ? this.gaussianRandom(...i.y) : i.y, h = Array.isArray(i.z) ? this.gaussianRandom(...i.z) : i.z;
|
|
4173
|
+
s[1] === "position" || s[1] === "scale" ? e[n] = new x.Vector3(o, l, h) : s[1] === "rotation" ? (n = s[0] + ".quaternion", e[n] = new x.Quaternion().setFromEuler(new x.Euler(o, l, h, "XYZ")).normalize()) : s[1] === "quaternion" && (e[n] = new x.Quaternion(o, l, h, i.w).normalize());
|
|
4174
4174
|
}
|
|
4175
4175
|
return e;
|
|
4176
4176
|
}
|
|
@@ -4198,23 +4198,23 @@ class Ne {
|
|
|
4198
4198
|
t.forEach((s) => {
|
|
4199
4199
|
if (!i && s.morphTargetDictionary.hasOwnProperty(e)) return;
|
|
4200
4200
|
const o = s.geometry;
|
|
4201
|
-
let l = null,
|
|
4202
|
-
for (const [r,
|
|
4201
|
+
let l = null, h = null;
|
|
4202
|
+
for (const [r, u] of Object.entries(n))
|
|
4203
4203
|
if (s.morphTargetDictionary.hasOwnProperty(r)) {
|
|
4204
4204
|
const a = s.morphTargetDictionary[r], c = o.morphAttributes.position[a], d = o.morphAttributes.normal?.[a];
|
|
4205
|
-
l || (l = new
|
|
4205
|
+
l || (l = new x.Float32BufferAttribute(c.count * 3, 3), d && (h = new x.Float32BufferAttribute(c.count * 3, 3)));
|
|
4206
4206
|
for (let g = 0; g < c.count; g++) {
|
|
4207
|
-
const y = l.getX(g) + c.getX(g) *
|
|
4208
|
-
l.setXYZ(g, y,
|
|
4207
|
+
const y = l.getX(g) + c.getX(g) * u, b = l.getY(g) + c.getY(g) * u, I = l.getZ(g) + c.getZ(g) * u;
|
|
4208
|
+
l.setXYZ(g, y, b, I);
|
|
4209
4209
|
}
|
|
4210
4210
|
if (d)
|
|
4211
4211
|
for (let g = 0; g < c.count; g++) {
|
|
4212
|
-
const y =
|
|
4213
|
-
|
|
4212
|
+
const y = h.getX(g) + d.getX(g) * u, b = h.getY(g) + d.getY(g) * u, I = h.getZ(g) + d.getZ(g) * u;
|
|
4213
|
+
h.setXYZ(g, y, b, I);
|
|
4214
4214
|
}
|
|
4215
4215
|
}
|
|
4216
4216
|
if (l) {
|
|
4217
|
-
o.morphAttributes.position.push(l),
|
|
4217
|
+
o.morphAttributes.position.push(l), h && o.morphAttributes.normal.push(h);
|
|
4218
4218
|
const r = o.morphAttributes.position.length - 1;
|
|
4219
4219
|
s.morphTargetInfluences[r] = 0, s.morphTargetDictionary[e] = r;
|
|
4220
4220
|
}
|
|
@@ -4244,7 +4244,7 @@ class Ne {
|
|
|
4244
4244
|
throw new Error("Blend shapes not found");
|
|
4245
4245
|
const o = new Set(this.mtCustoms);
|
|
4246
4246
|
this.morphs.forEach((r) => {
|
|
4247
|
-
Object.keys(r.morphTargetDictionary).forEach((
|
|
4247
|
+
Object.keys(r.morphTargetDictionary).forEach((u) => o.add(u));
|
|
4248
4248
|
}), this.mtExtras.forEach((r) => {
|
|
4249
4249
|
o.has(r.key) || (this.addMixedMorphTarget(this.morphs, r.key, r.mix), o.add(r.key));
|
|
4250
4250
|
});
|
|
@@ -4271,16 +4271,16 @@ class Ne {
|
|
|
4271
4271
|
ms: [],
|
|
4272
4272
|
is: []
|
|
4273
4273
|
}, l[r].value = l[r].baseline, l[r].applied = l[r].baseline;
|
|
4274
|
-
const
|
|
4275
|
-
|
|
4276
|
-
l[r][a] =
|
|
4274
|
+
const u = this.mtAvatar[r];
|
|
4275
|
+
u && ["fixed", "system", "systemd", "realtime", "base", "v", "value", "applied"].forEach((a) => {
|
|
4276
|
+
l[r][a] = u[a];
|
|
4277
4277
|
}), this.morphs.forEach((a) => {
|
|
4278
4278
|
const c = a.morphTargetDictionary[r];
|
|
4279
4279
|
c !== void 0 && (l[r].ms.push(a.morphTargetInfluences), l[r].is.push(c), a.morphTargetInfluences[c] = l[r].applied);
|
|
4280
4280
|
});
|
|
4281
4281
|
}), this.mtAvatar = l, this.poseAvatar = { props: {} }, this.posePropNames.forEach((r) => {
|
|
4282
|
-
const
|
|
4283
|
-
this.poseAvatar.props[r] = a[
|
|
4282
|
+
const u = r.split("."), a = this.armature.getObjectByName(u[0]);
|
|
4283
|
+
this.poseAvatar.props[r] = a[u[1]], this.poseBase.props.hasOwnProperty(r) ? this.poseAvatar.props[r].copy(this.poseBase.props[r]) : this.poseBase.props[r] = this.poseAvatar.props[r].clone(), this.poseDelta.props.hasOwnProperty(r) && !this.poseTarget.props.hasOwnProperty(r) && (this.poseTarget.props[r] = this.poseAvatar.props[r].clone()), this.poseTarget.props[r].t = this.animClock, this.poseTarget.props[r].d = 2e3;
|
|
4284
4284
|
}), this.ikMesh.traverse((r) => {
|
|
4285
4285
|
r.isBone && r.position.copy(this.armature.getObjectByName(r.name).position);
|
|
4286
4286
|
}), this.isAvatarOnly ? this.scene && this.scene.add(this.armature) : (this.scene.add(i.scene), this.scene.add(this.lightAmbient), this.scene.add(this.lightDirect), this.scene.add(this.lightSpot), this.lightSpot.target = this.armature.getObjectByName("Head")), t.hasOwnProperty("modelDynamicBones"))
|
|
@@ -4290,8 +4290,8 @@ class Ne {
|
|
|
4290
4290
|
console.error("Dynamic bones setup failed: " + r);
|
|
4291
4291
|
}
|
|
4292
4292
|
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");
|
|
4293
|
-
const
|
|
4294
|
-
this.objectLeftEye.getWorldPosition(
|
|
4293
|
+
const h = new x.Vector3();
|
|
4294
|
+
this.objectLeftEye.getWorldPosition(h), this.avatarHeight = h.y + 0.2, this.viewName || this.setView(this.opt.cameraView), this.setMood(this.avatar.avatarMood || this.moodName || this.opt.avatarMood), this.initializeFBXAnimationLoader(), this.bodyMovement && this.bodyMovement !== "idle" && this.applyBodyMovementAnimation(), this.start();
|
|
4295
4295
|
}
|
|
4296
4296
|
/**
|
|
4297
4297
|
* Get view names.
|
|
@@ -4319,29 +4319,29 @@ class Ne {
|
|
|
4319
4319
|
return;
|
|
4320
4320
|
}
|
|
4321
4321
|
if (this.viewName = t || this.viewName, e = e || {}, this.isAvatarOnly) return;
|
|
4322
|
-
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,
|
|
4323
|
-
let r = -n * Math.tan(
|
|
4322
|
+
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, h = this.camera.fov * (Math.PI / 180);
|
|
4323
|
+
let r = -n * Math.tan(h / 2), u = (1 - i) * Math.tan(h / 2), a = s;
|
|
4324
4324
|
switch (this.viewName) {
|
|
4325
4325
|
case "head":
|
|
4326
|
-
a += 2,
|
|
4326
|
+
a += 2, u = u * a + 4 * this.avatarHeight / 5;
|
|
4327
4327
|
break;
|
|
4328
4328
|
case "upper":
|
|
4329
|
-
a += 4.5,
|
|
4329
|
+
a += 4.5, u = u * a + 2 * this.avatarHeight / 3;
|
|
4330
4330
|
break;
|
|
4331
4331
|
case "mid":
|
|
4332
|
-
a += 8,
|
|
4332
|
+
a += 8, u = u * a + this.avatarHeight / 3;
|
|
4333
4333
|
break;
|
|
4334
4334
|
default:
|
|
4335
|
-
a += 12,
|
|
4335
|
+
a += 12, u = u * a;
|
|
4336
4336
|
}
|
|
4337
|
-
r = r * a, this.controlsEnd = new
|
|
4337
|
+
r = r * a, this.controlsEnd = new x.Vector3(r, u, 0), this.cameraEnd = new x.Vector3(r, u, a).applyEuler(new x.Euler(o, l, 0)), this.cameraClock === null && (this.controls.target.copy(this.controlsEnd), this.camera.position.copy(this.cameraEnd)), this.controlsStart = this.controls.target.clone(), this.cameraStart = this.camera.position.clone(), this.cameraClock = 0;
|
|
4338
4338
|
}
|
|
4339
4339
|
/**
|
|
4340
4340
|
* Change light colors and intensities.
|
|
4341
4341
|
* @param {Object} opt Options
|
|
4342
4342
|
*/
|
|
4343
4343
|
setLighting(t) {
|
|
4344
|
-
this.isAvatarOnly || (t = t || {}, t.hasOwnProperty("lightAmbientColor") && this.lightAmbient.color.set(new
|
|
4344
|
+
this.isAvatarOnly || (t = t || {}, t.hasOwnProperty("lightAmbientColor") && this.lightAmbient.color.set(new x.Color(t.lightAmbientColor)), t.hasOwnProperty("lightAmbientIntensity") && (this.lightAmbient.intensity = t.lightAmbientIntensity, this.lightAmbient.visible = t.lightAmbientIntensity !== 0), t.hasOwnProperty("lightDirectColor") && this.lightDirect.color.set(new x.Color(t.lightDirectColor)), t.hasOwnProperty("lightDirectIntensity") && (this.lightDirect.intensity = t.lightDirectIntensity, this.lightDirect.visible = t.lightDirectIntensity !== 0), t.hasOwnProperty("lightDirectPhi") && t.hasOwnProperty("lightDirectTheta") && this.lightDirect.position.setFromSphericalCoords(2, t.lightDirectPhi, t.lightDirectTheta), t.hasOwnProperty("lightSpotColor") && this.lightSpot.color.set(new x.Color(t.lightSpotColor)), t.hasOwnProperty("lightSpotIntensity") && (this.lightSpot.intensity = t.lightSpotIntensity, this.lightSpot.visible = t.lightSpotIntensity !== 0), t.hasOwnProperty("lightSpotPhi") && t.hasOwnProperty("lightSpotTheta") && (this.lightSpot.position.setFromSphericalCoords(2, t.lightSpotPhi, t.lightSpotTheta), this.lightSpot.position.add(new x.Vector3(0, 1.5, 0))), t.hasOwnProperty("lightSpotDispersion") && (this.lightSpot.angle = t.lightSpotDispersion));
|
|
4345
4345
|
}
|
|
4346
4346
|
/**
|
|
4347
4347
|
* Render scene.
|
|
@@ -4374,9 +4374,9 @@ class Ne {
|
|
|
4374
4374
|
updatePoseDelta() {
|
|
4375
4375
|
for (const [t, e] of Object.entries(this.poseDelta.props)) {
|
|
4376
4376
|
if (e.x === 0 && e.y === 0 && e.z === 0) continue;
|
|
4377
|
-
|
|
4377
|
+
W.set(e.x, e.y, e.z);
|
|
4378
4378
|
const n = this.poseAvatar.props[t];
|
|
4379
|
-
n.isQuaternion ? (
|
|
4379
|
+
n.isQuaternion ? (Q.setFromEuler(W), n.multiply(Q)) : n.isVector3 && n.add(W);
|
|
4380
4380
|
}
|
|
4381
4381
|
}
|
|
4382
4382
|
/**
|
|
@@ -4431,17 +4431,17 @@ class Ne {
|
|
|
4431
4431
|
"HandMiddle",
|
|
4432
4432
|
"HandRing",
|
|
4433
4433
|
"HandPinky"
|
|
4434
|
-
].forEach((
|
|
4435
|
-
a === 0 ? (this.poseDelta.props[o +
|
|
4434
|
+
].forEach((u, a) => {
|
|
4435
|
+
a === 0 ? (this.poseDelta.props[o + u + "1.quaternion"].x = 0, this.poseDelta.props[o + u + "2.quaternion"].z = (o === "Left" ? -1 : 1) * n.applied, this.poseDelta.props[o + u + "3.quaternion"].z = (o === "Left" ? -1 : 1) * n.applied) : (this.poseDelta.props[o + u + "1.quaternion"].x = n.applied, this.poseDelta.props[o + u + "2.quaternion"].x = 1.5 * n.applied, this.poseDelta.props[o + u + "3.quaternion"].x = 1.5 * n.applied);
|
|
4436
4436
|
});
|
|
4437
4437
|
break;
|
|
4438
4438
|
case "chestInhale":
|
|
4439
|
-
const l = n.applied / 20,
|
|
4440
|
-
this.poseDelta.props["Spine1.scale"] =
|
|
4439
|
+
const l = n.applied / 20, h = { 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 };
|
|
4440
|
+
this.poseDelta.props["Spine1.scale"] = h, this.poseDelta.props["Neck.scale"] = r, this.poseDelta.props["LeftArm.scale"] = r, this.poseDelta.props["RightArm.scale"] = r;
|
|
4441
4441
|
break;
|
|
4442
4442
|
default:
|
|
4443
|
-
for (let
|
|
4444
|
-
n.ms[
|
|
4443
|
+
for (let u = 0, a = n.ms.length; u < a; u++)
|
|
4444
|
+
n.ms[u][n.is[u]] = n.applied;
|
|
4445
4445
|
}
|
|
4446
4446
|
}
|
|
4447
4447
|
}
|
|
@@ -4456,8 +4456,8 @@ class Ne {
|
|
|
4456
4456
|
return Object.entries(t).forEach((i, s) => {
|
|
4457
4457
|
const o = i[0].split(".");
|
|
4458
4458
|
if (o[1] === "position" || o[1] === "rotation" || o[1] === "quaternion") {
|
|
4459
|
-
const l = o[1] === "quaternion" ? o[0] + ".rotation" : i[0],
|
|
4460
|
-
n += (s ? ", " : "") + "'" + l + "':{", n += "x:" + Math.round(
|
|
4459
|
+
const l = o[1] === "quaternion" ? o[0] + ".rotation" : i[0], h = i[1].isQuaternion ? new x.Euler().setFromQuaternion(i[1]) : i[1];
|
|
4460
|
+
n += (s ? ", " : "") + "'" + l + "':{", n += "x:" + Math.round(h.x * e) / e, n += ", y:" + Math.round(h.y * e) / e, n += ", z:" + Math.round(h.z * e) / e, n += "}";
|
|
4461
4461
|
}
|
|
4462
4462
|
}), n += "}", n;
|
|
4463
4463
|
}
|
|
@@ -4527,8 +4527,8 @@ class Ne {
|
|
|
4527
4527
|
if (n ? (this.poseCurrentTemplate = this.poseTemplates.oneknee, setTimeout(() => {
|
|
4528
4528
|
this.setPoseFromTemplate(t, e);
|
|
4529
4529
|
}, 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)
|
|
4530
|
-
for (let [l,
|
|
4531
|
-
this.poseTarget.props.hasOwnProperty(l) && (this.poseTarget.props[l].copy(
|
|
4530
|
+
for (let [l, h] of Object.entries(this.gesture))
|
|
4531
|
+
this.poseTarget.props.hasOwnProperty(l) && (this.poseTarget.props[l].copy(h), this.poseTarget.props[l].t = h.t, this.poseTarget.props[l].d = h.d);
|
|
4532
4532
|
Object.keys(this.poseDelta.props).forEach((l) => {
|
|
4533
4533
|
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);
|
|
4534
4534
|
});
|
|
@@ -4973,11 +4973,11 @@ class Ne {
|
|
|
4973
4973
|
else if (l.hasOwnProperty("alt")) {
|
|
4974
4974
|
let r = l.alt[0];
|
|
4975
4975
|
if (l.alt.length > 1) {
|
|
4976
|
-
const
|
|
4976
|
+
const u = Math.random();
|
|
4977
4977
|
let a = 0;
|
|
4978
4978
|
for (let c = 0; c < l.alt.length; c++) {
|
|
4979
4979
|
let d = this.valueFn(l.alt[c].p);
|
|
4980
|
-
if (a += d === void 0 ? (1 - a) / (l.alt.length - 1 - c) : d,
|
|
4980
|
+
if (a += d === void 0 ? (1 - a) / (l.alt.length - 1 - c) : d, u < a) {
|
|
4981
4981
|
r = l.alt[c];
|
|
4982
4982
|
break;
|
|
4983
4983
|
}
|
|
@@ -4986,19 +4986,19 @@ class Ne {
|
|
|
4986
4986
|
l = r;
|
|
4987
4987
|
} else
|
|
4988
4988
|
break;
|
|
4989
|
-
let
|
|
4990
|
-
if (Array.isArray(
|
|
4991
|
-
l.dt.forEach((r,
|
|
4989
|
+
let h = this.valueFn(l.delay) || 0;
|
|
4990
|
+
if (Array.isArray(h) && (h = this.gaussianRandom(...h)), l.hasOwnProperty("dt"))
|
|
4991
|
+
l.dt.forEach((r, u) => {
|
|
4992
4992
|
let a = this.valueFn(r);
|
|
4993
|
-
Array.isArray(a) && (a = this.gaussianRandom(...a)), o.ts[
|
|
4993
|
+
Array.isArray(a) && (a = this.gaussianRandom(...a)), o.ts[u + 1] = o.ts[u] + a;
|
|
4994
4994
|
});
|
|
4995
4995
|
else {
|
|
4996
|
-
let r = Object.values(l.vs).reduce((
|
|
4996
|
+
let r = Object.values(l.vs).reduce((u, a) => a.length > u ? a.length : u, 0);
|
|
4997
4997
|
o.ts = Array(r + 1).fill(0);
|
|
4998
4998
|
}
|
|
4999
|
-
s ? o.ts = o.ts.map((r) =>
|
|
5000
|
-
for (let [r,
|
|
5001
|
-
const a = this.getBaselineValue(r), c =
|
|
4999
|
+
s ? o.ts = o.ts.map((r) => h + r * n) : o.ts = o.ts.map((r) => this.animClock + h + r * n);
|
|
5000
|
+
for (let [r, u] of Object.entries(l.vs)) {
|
|
5001
|
+
const a = this.getBaselineValue(r), c = u.map((d) => (d = this.valueFn(d), d === null ? null : typeof d == "function" ? d : typeof d == "string" || d instanceof String ? d.slice() : Array.isArray(d) ? r === "gesture" ? d.slice() : (a === void 0 ? 0 : a) + i * this.gaussianRandom(...d) : typeof d == "boolean" ? d : d instanceof Object && d.constructor === Object ? Object.assign({}, d) : (a === void 0 ? 0 : a) + i * d));
|
|
5002
5002
|
r === "eyesRotateY" ? (o.vs.eyeLookOutLeft = [null, ...c.map((d) => d > 0 ? d : 0)], o.vs.eyeLookInLeft = [null, ...c.map((d) => d > 0 ? 0 : -d)], o.vs.eyeLookOutRight = [null, ...c.map((d) => d > 0 ? 0 : -d)], o.vs.eyeLookInRight = [null, ...c.map((d) => d > 0 ? d : 0)]) : r === "eyesRotateX" ? (o.vs.eyesLookDown = [null, ...c.map((d) => d > 0 ? d : 0)], o.vs.eyesLookUp = [null, ...c.map((d) => d > 0 ? 0 : -d)]) : o.vs[r] = [null, ...c];
|
|
5003
5003
|
}
|
|
5004
5004
|
for (let r of Object.keys(o.vs))
|
|
@@ -5080,8 +5080,8 @@ class Ne {
|
|
|
5080
5080
|
if (this.isSpeaking)
|
|
5081
5081
|
for (l = 0, this.audioAnalyzerNode.getByteFrequencyData(this.volumeFrequencyData), n = 2, s = 10; n < s; n++)
|
|
5082
5082
|
this.volumeFrequencyData[n] > l && (l = this.volumeFrequencyData[n]);
|
|
5083
|
-
let
|
|
5084
|
-
const
|
|
5083
|
+
let h = null, r = null;
|
|
5084
|
+
const u = [];
|
|
5085
5085
|
for (n = 0, s = this.animQueue.length; n < s; n++) {
|
|
5086
5086
|
const a = this.animQueue[n];
|
|
5087
5087
|
if (!(!a || !a.ts || !a.ts.length || this.animClock < a.ts[0])) {
|
|
@@ -5095,8 +5095,8 @@ class Ne {
|
|
|
5095
5095
|
else {
|
|
5096
5096
|
g.newvalue = d[i + 1];
|
|
5097
5097
|
const y = a.ts[i + 1] - a.ts[i];
|
|
5098
|
-
let
|
|
5099
|
-
y > 1e-4 && (
|
|
5098
|
+
let b = 1;
|
|
5099
|
+
y > 1e-4 && (b = (this.animClock - a.ts[i]) / y), b < 1 && (g.easing && (b = g.easing(b)), g.newvalue = (1 - b) * d[i] + b * g.newvalue), g.ref && g.ref !== a.vs && g.ref.hasOwnProperty(c) && delete g.ref[c], g.ref = a.vs;
|
|
5100
5100
|
}
|
|
5101
5101
|
if (l)
|
|
5102
5102
|
switch (c) {
|
|
@@ -5108,12 +5108,12 @@ class Ne {
|
|
|
5108
5108
|
g.newvalue *= 1 + l / 255 - 0.5;
|
|
5109
5109
|
}
|
|
5110
5110
|
g.needsUpdate = !0;
|
|
5111
|
-
} else c === "eyeContact" && d[i] !== null &&
|
|
5111
|
+
} else c === "eyeContact" && d[i] !== null && h !== !1 ? h = !!d[i] : c === "headMove" && d[i] !== null && r !== !1 ? d[i] === 0 ? r = !1 : (Math.random() < d[i] && (r = !0), d[i] = null) : d[i] !== null && (u.push({ mt: c, val: d[i] }), d[i] = null);
|
|
5112
5112
|
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;
|
|
5113
5113
|
}
|
|
5114
5114
|
}
|
|
5115
|
-
for (let a = 0, c =
|
|
5116
|
-
switch (i =
|
|
5115
|
+
for (let a = 0, c = u.length; a < c; a++)
|
|
5116
|
+
switch (i = u[a].val, u[a].mt) {
|
|
5117
5117
|
case "speak":
|
|
5118
5118
|
this.speakText(i);
|
|
5119
5119
|
break;
|
|
@@ -5144,7 +5144,7 @@ class Ne {
|
|
|
5144
5144
|
{ link: "LeftForeArm", minx: -0.5, maxx: 1.5, miny: -1.5, maxy: 1.5, minz: -0.5, maxz: 3 },
|
|
5145
5145
|
{ link: "LeftArm", minx: -1.5, maxx: 1.5, miny: 0, maxy: 0, minz: -1, maxz: 3 }
|
|
5146
5146
|
]
|
|
5147
|
-
}, i.x ? new
|
|
5147
|
+
}, i.x ? new x.Vector3(i.x, i.y, i.z) : null, !0, i.d);
|
|
5148
5148
|
break;
|
|
5149
5149
|
case "handRight":
|
|
5150
5150
|
this.ikSolve({
|
|
@@ -5156,10 +5156,10 @@ class Ne {
|
|
|
5156
5156
|
{ link: "RightForeArm", minx: -0.5, maxx: 1.5, miny: -1.5, maxy: 1.5, minz: -3, maxz: 0.5, maxAngle: 0.2 },
|
|
5157
5157
|
{ link: "RightArm", minx: -1.5, maxx: 1.5, miny: 0, maxy: 0, minz: -1, maxz: 3 }
|
|
5158
5158
|
]
|
|
5159
|
-
}, i.x ? new
|
|
5159
|
+
}, i.x ? new x.Vector3(i.x, i.y, i.z) : null, !0, i.d);
|
|
5160
5160
|
break;
|
|
5161
5161
|
}
|
|
5162
|
-
if ((
|
|
5162
|
+
if ((h || r) && (W.setFromQuaternion(this.poseAvatar.props["Head.quaternion"]), W.x = Math.max(-0.9, Math.min(0.9, 2 * W.x - 0.5)), W.y = Math.max(-0.9, Math.min(0.9, -2.5 * W.y)), h ? (Object.assign(this.mtAvatar.eyesLookDown, { system: W.x < 0 ? -W.x : 0, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyesLookUp, { system: W.x < 0 ? 0 : W.x, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookInLeft, { system: W.y < 0 ? -W.y : 0, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookOutLeft, { system: W.y < 0 ? 0 : W.y, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookInRight, { system: W.y < 0 ? 0 : W.y, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookOutRight, { system: W.y < 0 ? -W.y : 0, needsUpdate: !0 }), r && (n = -this.mtAvatar.bodyRotateY.value, i = this.gaussianRandom(-0.2, 0.2), this.animQueue.push(this.animFactory({
|
|
5163
5163
|
name: "headmove",
|
|
5164
5164
|
dt: [[1e3, 2e3], [1e3, 2e3, 1, 2], [1e3, 2e3], [1e3, 2e3, 1, 2]],
|
|
5165
5165
|
vs: {
|
|
@@ -5180,12 +5180,12 @@ class Ne {
|
|
|
5180
5180
|
eyeLookOutRight: [null, 0],
|
|
5181
5181
|
eyeContact: [0]
|
|
5182
5182
|
}
|
|
5183
|
-
})))), e > 2 * this.animFrameDur && (e = 2 * this.animFrameDur), (this.viewName !== "full" || this.isAvatarOnly) && (n = this.mtRandomized[Math.floor(Math.random() * this.mtRandomized.length)], i = this.mtAvatar[n], i.needsUpdate || Object.assign(i, { base: (this.mood.baseline[n] || 0) + (1 + l / 255) * Math.random() / 5, needsUpdate: !0 })), this.updatePoseBase(this.animClock), this.mixer && this.mixer.update(e / 1e3 * this.mixer.timeScale), this.updatePoseDelta(), (this.isSpeaking || this.isListening) &&
|
|
5183
|
+
})))), e > 2 * this.animFrameDur && (e = 2 * this.animFrameDur), (this.viewName !== "full" || this.isAvatarOnly) && (n = this.mtRandomized[Math.floor(Math.random() * this.mtRandomized.length)], i = this.mtAvatar[n], i.needsUpdate || Object.assign(i, { base: (this.mood.baseline[n] || 0) + (1 + l / 255) * Math.random() / 5, needsUpdate: !0 })), this.updatePoseBase(this.animClock), this.mixer && this.mixer.update(e / 1e3 * this.mixer.timeScale), this.updatePoseDelta(), (this.isSpeaking || this.isListening) && h ? l > this.volumeMax ? (this.volumeHeadBase = 0.05, Math.random() > 0.6 && (this.volumeHeadTarget = -0.05 - Math.random() / 15), this.volumeMax = l) : (this.volumeMax *= 0.92, this.volumeHeadTarget = this.volumeHeadBase - 0.9 * (this.volumeHeadBase - this.volumeHeadTarget)) : (this.volumeHeadTarget = 0, this.volumeMax = 0), n = this.volumeHeadTarget - this.volumeHeadCurrent, i = Math.abs(n), i > 1e-4 && (o = i * (this.volumeHeadEasing(Math.min(1, this.volumeHeadVelocity * e / 1e3 / i) / 2 + 0.5) - 0.5), this.volumeHeadCurrent += Math.sign(n) * Math.min(i, o)), Math.abs(this.volumeHeadCurrent) > 1e-4 && (Q.setFromAxisAngle(mt, this.volumeHeadCurrent), this.objectNeck.quaternion.multiply(Q)), We.setFromObject(this.armature), this.objectLeftToeBase.getWorldPosition(ve), ve.sub(this.armature.position), this.objectRightToeBase.getWorldPosition(Re), Re.sub(this.armature.position), this.objectHips.position.y -= We.min.y / 2, this.objectHips.position.x -= (ve.x + Re.x) / 4, this.objectHips.position.z -= (ve.z + Re.z) / 2, this.dynamicbones.update(e), this.fbxAnimationLoader && this.fbxAnimationLoader.update(), this.opt.update && this.opt.update(e), this.updateMorphTargets(e), this.isAvatarOnly)
|
|
5184
5184
|
this.stats && this.stats.end();
|
|
5185
5185
|
else {
|
|
5186
5186
|
if (this.cameraClock !== null && this.cameraClock < 1e3) {
|
|
5187
5187
|
this.cameraClock += e, this.cameraClock > 1e3 && (this.cameraClock = 1e3);
|
|
5188
|
-
let a = new
|
|
5188
|
+
let a = new x.Spherical().setFromVector3(this.cameraStart), c = new x.Spherical().setFromVector3(this.cameraEnd);
|
|
5189
5189
|
a.phi += this.easing(this.cameraClock / 1e3) * (c.phi - a.phi), a.theta += this.easing(this.cameraClock / 1e3) * (c.theta - a.theta), a.radius += this.easing(this.cameraClock / 1e3) * (c.radius - a.radius), a.makeSafe(), this.camera.position.setFromSpherical(a), this.controlsStart.x !== this.controlsEnd.x ? this.controls.target.copy(this.controlsStart.lerp(this.controlsEnd, this.easing(this.cameraClock / 1e3))) : (a.setFromVector3(this.controlsStart), c.setFromVector3(this.controlsEnd), a.phi += this.easing(this.cameraClock / 1e3) * (c.phi - a.phi), a.theta += this.easing(this.cameraClock / 1e3) * (c.theta - a.theta), a.radius += this.easing(this.cameraClock / 1e3) * (c.radius - a.radius), a.makeSafe(), this.controls.target.setFromSpherical(a)), this.controls.update();
|
|
5190
5190
|
}
|
|
5191
5191
|
this.controls.autoRotate && this.controls.update(), this.stats && this.stats.end(), this.render();
|
|
@@ -5211,8 +5211,8 @@ class Ne {
|
|
|
5211
5211
|
if (!this.lipsync.hasOwnProperty(t)) {
|
|
5212
5212
|
const n = t.toLowerCase(), i = "Lipsync" + t.charAt(0).toUpperCase() + t.slice(1);
|
|
5213
5213
|
try {
|
|
5214
|
-
const s =
|
|
5215
|
-
s && s[i] ? (this.lipsync[t] = new s[i](), console.log(`Loaded lip-sync module for ${t}`)) : console.warn(`Lip-sync module for ${t} not found. Available modules:`, Object.keys(
|
|
5214
|
+
const s = Ue[n];
|
|
5215
|
+
s && s[i] ? (this.lipsync[t] = new s[i](), console.log(`Loaded lip-sync module for ${t}`)) : console.warn(`Lip-sync module for ${t} not found. Available modules:`, Object.keys(Ue));
|
|
5216
5216
|
} catch (s) {
|
|
5217
5217
|
console.warn(`Failed to load lip-sync module for ${t}:`, s);
|
|
5218
5218
|
}
|
|
@@ -5247,49 +5247,49 @@ class Ne {
|
|
|
5247
5247
|
*/
|
|
5248
5248
|
speakText(t, e = null, n = null, i = null) {
|
|
5249
5249
|
e = e || {};
|
|
5250
|
-
const s = /[!\.\?\n\p{Extended_Pictographic}]/ug, o = /[ ]/ug, l = /[\p{L}\p{N},\.\p{Quotation_Mark}!€\$\+\p{Dash_Punctuation}%&\?]/ug,
|
|
5251
|
-
let
|
|
5252
|
-
const y = Array.from(this.segmenter.segment(t), (
|
|
5253
|
-
for (let
|
|
5254
|
-
const
|
|
5255
|
-
let p = y[
|
|
5256
|
-
const
|
|
5257
|
-
if (p && !
|
|
5250
|
+
const s = /[!\.\?\n\p{Extended_Pictographic}]/ug, o = /[ ]/ug, l = /[\p{L}\p{N},\.\p{Quotation_Mark}!€\$\+\p{Dash_Punctuation}%&\?]/ug, h = /[\p{Extended_Pictographic}]/ug, r = e.lipsyncLang || this.avatar.lipsyncLang || this.opt.lipsyncLang;
|
|
5251
|
+
let u = "", a = "", c = 0, d = [], g = [];
|
|
5252
|
+
const y = Array.from(this.segmenter.segment(t), (b) => b.segment);
|
|
5253
|
+
for (let b = 0; b < y.length; b++) {
|
|
5254
|
+
const I = b === y.length - 1, V = y[b].match(l);
|
|
5255
|
+
let p = y[b].match(s);
|
|
5256
|
+
const M = y[b].match(h), w = y[b].match(o);
|
|
5257
|
+
if (p && !I && !M && y[b + 1].match(s) && (p = !1), n && (u += y[b]), V && (!i || i.every((f) => b < f[0] || b > f[1])) && (a += y[b]), (w || p || I) && (a.length && (a = this.lipsyncPreProcessText(a, r), a.length && d.push({
|
|
5258
5258
|
mark: c,
|
|
5259
5259
|
word: a
|
|
5260
|
-
})),
|
|
5260
|
+
})), u.length && (g.push({
|
|
5261
5261
|
mark: c,
|
|
5262
5262
|
template: { name: "subtitles" },
|
|
5263
5263
|
ts: [0],
|
|
5264
5264
|
vs: {
|
|
5265
|
-
subtitles: [
|
|
5265
|
+
subtitles: [u]
|
|
5266
5266
|
}
|
|
5267
|
-
}),
|
|
5268
|
-
const
|
|
5269
|
-
if (
|
|
5270
|
-
const
|
|
5271
|
-
for (let
|
|
5267
|
+
}), u = ""), a.length)) {
|
|
5268
|
+
const f = this.lipsyncWordsToVisemes(a, r);
|
|
5269
|
+
if (f && f.visemes && f.visemes.length) {
|
|
5270
|
+
const E = f.times[f.visemes.length - 1] + f.durations[f.visemes.length - 1];
|
|
5271
|
+
for (let P = 0; P < f.visemes.length; P++)
|
|
5272
5272
|
g.push({
|
|
5273
5273
|
mark: c,
|
|
5274
5274
|
template: { name: "viseme" },
|
|
5275
|
-
ts: [(
|
|
5275
|
+
ts: [(f.times[P] - 0.6) / E, (f.times[P] + 0.5) / E, (f.times[P] + f.durations[P] + 0.5) / E],
|
|
5276
5276
|
vs: {
|
|
5277
|
-
["viseme_" +
|
|
5277
|
+
["viseme_" + f.visemes[P]]: [null, f.visemes[P] === "PP" || f.visemes[P] === "FF" ? 0.9 : 0.6, 0]
|
|
5278
5278
|
}
|
|
5279
5279
|
});
|
|
5280
5280
|
}
|
|
5281
5281
|
a = "", c++;
|
|
5282
5282
|
}
|
|
5283
|
-
if (p ||
|
|
5284
|
-
if (d.length ||
|
|
5285
|
-
const
|
|
5283
|
+
if (p || I) {
|
|
5284
|
+
if (d.length || I && g.length) {
|
|
5285
|
+
const f = {
|
|
5286
5286
|
anim: g
|
|
5287
5287
|
};
|
|
5288
|
-
n && (
|
|
5288
|
+
n && (f.onSubtitles = n), d.length && !e.avatarMute && (f.text = d, e.avatarMood && (f.mood = e.avatarMood), e.ttsLang && (f.lang = e.ttsLang), e.ttsVoice && (f.voice = e.ttsVoice), e.ttsRate && (f.rate = e.ttsRate), e.ttsVoice && (f.pitch = e.ttsPitch), e.ttsVolume && (f.volume = e.ttsVolume)), this.speechQueue.push(f), d = [], a = "", c = 0, g = [];
|
|
5289
5289
|
}
|
|
5290
|
-
if (
|
|
5291
|
-
let
|
|
5292
|
-
|
|
5290
|
+
if (M) {
|
|
5291
|
+
let f = this.animEmojis[y[b]];
|
|
5292
|
+
f && f.link && (f = this.animEmojis[f.link]), f && this.speechQueue.push({ emoji: f });
|
|
5293
5293
|
}
|
|
5294
5294
|
this.speechQueue.push({ break: 100 });
|
|
5295
5295
|
}
|
|
@@ -5370,27 +5370,27 @@ class Ne {
|
|
|
5370
5370
|
if (t.words) {
|
|
5371
5371
|
let o = [];
|
|
5372
5372
|
for (let l = 0; l < t.words.length; l++) {
|
|
5373
|
-
const
|
|
5374
|
-
let
|
|
5375
|
-
if (
|
|
5373
|
+
const h = t.words[l], r = t.wtimes[l];
|
|
5374
|
+
let u = t.wdurations[l];
|
|
5375
|
+
if (h.length && (n && o.push({
|
|
5376
5376
|
template: { name: "subtitles" },
|
|
5377
5377
|
ts: [r],
|
|
5378
5378
|
vs: {
|
|
5379
|
-
subtitles: [" " +
|
|
5379
|
+
subtitles: [" " + h]
|
|
5380
5380
|
}
|
|
5381
5381
|
}), !t.visemes)) {
|
|
5382
|
-
const a = this.lipsyncPreProcessText(
|
|
5382
|
+
const a = this.lipsyncPreProcessText(h, i), c = this.lipsyncWordsToVisemes(a, i);
|
|
5383
5383
|
if (c && c.visemes && c.visemes.length) {
|
|
5384
|
-
const d = c.times[c.visemes.length - 1] + c.durations[c.visemes.length - 1], g = Math.min(
|
|
5385
|
-
let y = 0.6 + this.convertRange(g, [0,
|
|
5386
|
-
if (
|
|
5387
|
-
for (let
|
|
5388
|
-
const
|
|
5384
|
+
const d = c.times[c.visemes.length - 1] + c.durations[c.visemes.length - 1], g = Math.min(u, Math.max(0, u - c.visemes.length * 150));
|
|
5385
|
+
let y = 0.6 + this.convertRange(g, [0, u], [0, 0.4]);
|
|
5386
|
+
if (u = Math.min(u, c.visemes.length * 200), d > 0)
|
|
5387
|
+
for (let b = 0; b < c.visemes.length; b++) {
|
|
5388
|
+
const I = r + c.times[b] / d * u, V = c.durations[b] / d * u;
|
|
5389
5389
|
o.push({
|
|
5390
5390
|
template: { name: "viseme" },
|
|
5391
|
-
ts: [
|
|
5391
|
+
ts: [I - Math.min(60, 2 * V / 3), I + Math.min(25, V / 2), I + V + Math.min(60, V / 2)],
|
|
5392
5392
|
vs: {
|
|
5393
|
-
["viseme_" + c.visemes[
|
|
5393
|
+
["viseme_" + c.visemes[b]]: [null, c.visemes[b] === "PP" || c.visemes[b] === "FF" ? 0.9 : y, 0]
|
|
5394
5394
|
}
|
|
5395
5395
|
});
|
|
5396
5396
|
}
|
|
@@ -5399,22 +5399,22 @@ class Ne {
|
|
|
5399
5399
|
}
|
|
5400
5400
|
if (t.visemes)
|
|
5401
5401
|
for (let l = 0; l < t.visemes.length; l++) {
|
|
5402
|
-
const
|
|
5402
|
+
const h = t.visemes[l], r = t.vtimes[l], u = t.vdurations[l];
|
|
5403
5403
|
o.push({
|
|
5404
5404
|
template: { name: "viseme" },
|
|
5405
|
-
ts: [r - 2 *
|
|
5405
|
+
ts: [r - 2 * u / 3, r + u / 2, r + u + u / 2],
|
|
5406
5406
|
vs: {
|
|
5407
|
-
["viseme_" +
|
|
5407
|
+
["viseme_" + h]: [null, h === "PP" || h === "FF" ? 0.9 : 0.6, 0]
|
|
5408
5408
|
}
|
|
5409
5409
|
});
|
|
5410
5410
|
}
|
|
5411
5411
|
if (t.markers)
|
|
5412
5412
|
for (let l = 0; l < t.markers.length; l++) {
|
|
5413
|
-
const
|
|
5413
|
+
const h = t.markers[l], r = t.mtimes[l];
|
|
5414
5414
|
o.push({
|
|
5415
5415
|
template: { name: "markers" },
|
|
5416
5416
|
ts: [r],
|
|
5417
|
-
vs: { function: [
|
|
5417
|
+
vs: { function: [h] }
|
|
5418
5418
|
});
|
|
5419
5419
|
}
|
|
5420
5420
|
o.length && (s.anim = o);
|
|
@@ -5434,7 +5434,7 @@ class Ne {
|
|
|
5434
5434
|
if (this.isAudioPlaying = !0, this.audioPlaylist.length) {
|
|
5435
5435
|
const e = this.audioPlaylist.shift();
|
|
5436
5436
|
if (this.audioCtx.state === "suspended" || this.audioCtx.state === "interrupted") {
|
|
5437
|
-
const s = this.audioCtx.resume(), o = new Promise((l,
|
|
5437
|
+
const s = this.audioCtx.resume(), o = new Promise((l, h) => setTimeout(() => h("p2"), 1e3));
|
|
5438
5438
|
try {
|
|
5439
5439
|
await Promise.race([s, o]);
|
|
5440
5440
|
} catch {
|
|
@@ -5466,38 +5466,38 @@ class Ne {
|
|
|
5466
5466
|
*/
|
|
5467
5467
|
async synthesizeWithBrowserTTS(t) {
|
|
5468
5468
|
return new Promise((e, n) => {
|
|
5469
|
-
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,
|
|
5470
|
-
s.lang = o, s.rate = Math.max(0.1, Math.min(10, l)), s.pitch = Math.max(0, Math.min(2,
|
|
5471
|
-
const
|
|
5472
|
-
if (a &&
|
|
5473
|
-
const p =
|
|
5469
|
+
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, h = (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;
|
|
5470
|
+
s.lang = o, s.rate = Math.max(0.1, Math.min(10, l)), s.pitch = Math.max(0, Math.min(2, h)), s.volume = Math.max(0, Math.min(1, r));
|
|
5471
|
+
const u = speechSynthesis.getVoices(), a = t.voice || this.avatar.ttsVoice || this.opt.ttsVoice;
|
|
5472
|
+
if (a && u.length > 0) {
|
|
5473
|
+
const p = u.find((M) => M.name.includes(a) || M.lang === o);
|
|
5474
5474
|
p && (s.voice = p);
|
|
5475
5475
|
}
|
|
5476
|
-
const c = i.length * 100 / s.rate, d = this.audioCtx.createBuffer(1, this.audioCtx.sampleRate * (c / 1e3), this.audioCtx.sampleRate), g = this.avatar.lipsyncLang || this.opt.lipsyncLang || "en", y = this.lipsyncPreProcessText(i, g),
|
|
5476
|
+
const c = i.length * 100 / s.rate, d = this.audioCtx.createBuffer(1, this.audioCtx.sampleRate * (c / 1e3), this.audioCtx.sampleRate), g = this.avatar.lipsyncLang || this.opt.lipsyncLang || "en", y = this.lipsyncPreProcessText(i, g), b = this.lipsyncWordsToVisemes(y, g);
|
|
5477
5477
|
console.log("Browser TTS Lip-sync Debug:", {
|
|
5478
5478
|
text: i,
|
|
5479
5479
|
lipsyncLang: g,
|
|
5480
5480
|
processedText: y,
|
|
5481
|
-
lipsyncData:
|
|
5482
|
-
hasVisemes:
|
|
5481
|
+
lipsyncData: b,
|
|
5482
|
+
hasVisemes: b && b.visemes && b.visemes.length > 0,
|
|
5483
5483
|
estimatedDuration: c
|
|
5484
5484
|
});
|
|
5485
|
-
const
|
|
5486
|
-
if (
|
|
5487
|
-
const p =
|
|
5488
|
-
for (let
|
|
5489
|
-
const
|
|
5490
|
-
|
|
5485
|
+
const I = [];
|
|
5486
|
+
if (b && b.visemes && b.visemes.length > 0) {
|
|
5487
|
+
const p = b.times[b.visemes.length - 1] + b.durations[b.visemes.length - 1];
|
|
5488
|
+
for (let M = 0; M < b.visemes.length; M++) {
|
|
5489
|
+
const w = b.visemes[M], f = b.times[M] / p, E = b.durations[M] / p, P = f * c, U = E * c;
|
|
5490
|
+
I.push({
|
|
5491
5491
|
template: { name: "viseme" },
|
|
5492
|
-
ts: [
|
|
5492
|
+
ts: [P - Math.min(60, 2 * U / 3), P + Math.min(25, U / 2), P + U + Math.min(60, U / 2)],
|
|
5493
5493
|
vs: {
|
|
5494
|
-
["viseme_" +
|
|
5494
|
+
["viseme_" + w]: [null, w === "PP" || w === "FF" ? 0.9 : 0.6, 0]
|
|
5495
5495
|
}
|
|
5496
5496
|
});
|
|
5497
5497
|
}
|
|
5498
5498
|
}
|
|
5499
|
-
const
|
|
5500
|
-
this.audioPlaylist.push({ anim:
|
|
5499
|
+
const V = [...t.anim, ...I];
|
|
5500
|
+
this.audioPlaylist.push({ anim: V, audio: d }), this.onSubtitles = t.onSubtitles || null, this.resetLips(), t.mood && this.setMood(t.mood), this.playAudio(), s.onend = () => {
|
|
5501
5501
|
e();
|
|
5502
5502
|
}, s.onerror = (p) => {
|
|
5503
5503
|
console.error("Speech synthesis error:", p.error), n(p.error);
|
|
@@ -5531,15 +5531,15 @@ class Ne {
|
|
|
5531
5531
|
throw new Error(`ElevenLabs TTS error: ${s.status} ${s.statusText}`);
|
|
5532
5532
|
const o = await s.arrayBuffer(), l = await this.audioCtx.decodeAudioData(o);
|
|
5533
5533
|
console.log("Using text-based lip-sync for debugging...");
|
|
5534
|
-
const
|
|
5534
|
+
const h = this.avatar.lipsyncLang || this.opt.lipsyncLang || "en";
|
|
5535
5535
|
let r;
|
|
5536
5536
|
try {
|
|
5537
5537
|
console.log("Lip-sync modules available:", {
|
|
5538
5538
|
hasLipsync: !!this.lipsync,
|
|
5539
5539
|
lipsyncKeys: this.lipsync ? Object.keys(this.lipsync) : [],
|
|
5540
|
-
lipsyncLang:
|
|
5540
|
+
lipsyncLang: h
|
|
5541
5541
|
});
|
|
5542
|
-
const c = this.lipsyncPreProcessText(e,
|
|
5542
|
+
const c = this.lipsyncPreProcessText(e, h), d = this.lipsyncWordsToVisemes(c, h);
|
|
5543
5543
|
if (console.log("Lip-sync data:", {
|
|
5544
5544
|
processedText: c,
|
|
5545
5545
|
lipsyncData: d,
|
|
@@ -5563,15 +5563,15 @@ class Ne {
|
|
|
5563
5563
|
console.error("Text-based lip-sync failed, using fallback:", c);
|
|
5564
5564
|
const d = e.toLowerCase().split(/\s+/), g = [];
|
|
5565
5565
|
for (const y of d)
|
|
5566
|
-
for (const
|
|
5567
|
-
let
|
|
5568
|
-
"aeiou".includes(
|
|
5566
|
+
for (const b of y) {
|
|
5567
|
+
let I = "aa";
|
|
5568
|
+
"aeiou".includes(b) ? I = "aa" : "bp".includes(b) ? I = "PP" : "fv".includes(b) ? I = "FF" : "st".includes(b) ? I = "SS" : "dln".includes(b) ? I = "DD" : "kg".includes(b) ? I = "kk" : "rw".includes(b) && (I = "RR"), g.push(I);
|
|
5569
5569
|
}
|
|
5570
5570
|
r = {
|
|
5571
|
-
visemes: g.map((y,
|
|
5571
|
+
visemes: g.map((y, b) => ({
|
|
5572
5572
|
viseme: y,
|
|
5573
|
-
startTime:
|
|
5574
|
-
endTime: (
|
|
5573
|
+
startTime: b * l.duration / g.length,
|
|
5574
|
+
endTime: (b + 1) * l.duration / g.length,
|
|
5575
5575
|
duration: l.duration / g.length,
|
|
5576
5576
|
intensity: 0.6
|
|
5577
5577
|
})),
|
|
@@ -5592,24 +5592,24 @@ class Ne {
|
|
|
5592
5592
|
visemes: r.visemes ? r.visemes.slice(0, 3) : []
|
|
5593
5593
|
// Show first 3 visemes for debugging
|
|
5594
5594
|
});
|
|
5595
|
-
const
|
|
5595
|
+
const u = [];
|
|
5596
5596
|
if (r.visemes && r.visemes.length > 0) {
|
|
5597
5597
|
console.log("ElevenLabs: Generating lip-sync animation from", r.visemes.length, "visemes");
|
|
5598
5598
|
for (let c = 0; c < r.visemes.length; c++) {
|
|
5599
|
-
const d = r.visemes[c], g = d.startTime * 1e3, y = d.duration * 1e3,
|
|
5600
|
-
|
|
5599
|
+
const d = r.visemes[c], g = d.startTime * 1e3, y = d.duration * 1e3, b = d.intensity;
|
|
5600
|
+
u.push({
|
|
5601
5601
|
template: { name: "viseme" },
|
|
5602
5602
|
ts: [g - Math.min(60, 2 * y / 3), g + Math.min(25, y / 2), g + y + Math.min(60, y / 2)],
|
|
5603
5603
|
vs: {
|
|
5604
|
-
["viseme_" + d.viseme]: [null,
|
|
5604
|
+
["viseme_" + d.viseme]: [null, b, 0]
|
|
5605
5605
|
}
|
|
5606
5606
|
});
|
|
5607
5607
|
}
|
|
5608
|
-
console.log("ElevenLabs: Generated",
|
|
5608
|
+
console.log("ElevenLabs: Generated", u.length, "lip-sync animation frames");
|
|
5609
5609
|
} else
|
|
5610
5610
|
console.warn("ElevenLabs: No visemes available for lip-sync animation");
|
|
5611
|
-
const a = [...t.anim, ...
|
|
5612
|
-
console.log("ElevenLabs: Combined animation frames:", a.length, "(original:", t.anim.length, "+ lipsync:",
|
|
5611
|
+
const a = [...t.anim, ...u];
|
|
5612
|
+
console.log("ElevenLabs: Combined animation frames:", a.length, "(original:", t.anim.length, "+ lipsync:", u.length, ")"), this.audioPlaylist.push({ anim: a, audio: l }), this.onSubtitles = t.onSubtitles || null, this.resetLips(), t.mood && this.setMood(t.mood), this.playAudio();
|
|
5613
5613
|
}
|
|
5614
5614
|
/**
|
|
5615
5615
|
* Synthesize speech using Deepgram Aura-2 TTS
|
|
@@ -5629,15 +5629,15 @@ class Ne {
|
|
|
5629
5629
|
throw new Error(`Deepgram TTS error: ${s.status} ${s.statusText}`);
|
|
5630
5630
|
const o = await s.arrayBuffer(), l = await this.audioCtx.decodeAudioData(o);
|
|
5631
5631
|
console.log("Using text-based lip-sync for Deepgram...");
|
|
5632
|
-
const
|
|
5632
|
+
const h = this.avatar.lipsyncLang || this.opt.lipsyncLang || "en";
|
|
5633
5633
|
let r;
|
|
5634
5634
|
try {
|
|
5635
5635
|
console.log("Lip-sync modules available:", {
|
|
5636
5636
|
hasLipsync: !!this.lipsync,
|
|
5637
5637
|
lipsyncKeys: this.lipsync ? Object.keys(this.lipsync) : [],
|
|
5638
|
-
lipsyncLang:
|
|
5638
|
+
lipsyncLang: h
|
|
5639
5639
|
});
|
|
5640
|
-
const c = this.lipsyncPreProcessText(e,
|
|
5640
|
+
const c = this.lipsyncPreProcessText(e, h), d = this.lipsyncWordsToVisemes(c, h);
|
|
5641
5641
|
if (console.log("Lip-sync data:", {
|
|
5642
5642
|
processedText: c,
|
|
5643
5643
|
lipsyncData: d,
|
|
@@ -5661,15 +5661,15 @@ class Ne {
|
|
|
5661
5661
|
console.error("Text-based lip-sync failed, using fallback:", c);
|
|
5662
5662
|
const d = e.toLowerCase().split(/\s+/), g = [];
|
|
5663
5663
|
for (const y of d)
|
|
5664
|
-
for (const
|
|
5665
|
-
let
|
|
5666
|
-
"aeiou".includes(
|
|
5664
|
+
for (const b of y) {
|
|
5665
|
+
let I = "aa";
|
|
5666
|
+
"aeiou".includes(b) ? I = "aa" : "bp".includes(b) ? I = "PP" : "fv".includes(b) ? I = "FF" : "st".includes(b) ? I = "SS" : "dln".includes(b) ? I = "DD" : "kg".includes(b) ? I = "kk" : "rw".includes(b) && (I = "RR"), g.push(I);
|
|
5667
5667
|
}
|
|
5668
5668
|
r = {
|
|
5669
|
-
visemes: g.map((y,
|
|
5669
|
+
visemes: g.map((y, b) => ({
|
|
5670
5670
|
viseme: y,
|
|
5671
|
-
startTime:
|
|
5672
|
-
endTime: (
|
|
5671
|
+
startTime: b * l.duration / g.length,
|
|
5672
|
+
endTime: (b + 1) * l.duration / g.length,
|
|
5673
5673
|
duration: l.duration / g.length,
|
|
5674
5674
|
intensity: 0.6
|
|
5675
5675
|
})),
|
|
@@ -5690,24 +5690,24 @@ class Ne {
|
|
|
5690
5690
|
visemes: r.visemes ? r.visemes.slice(0, 3) : []
|
|
5691
5691
|
// Show first 3 visemes for debugging
|
|
5692
5692
|
});
|
|
5693
|
-
const
|
|
5693
|
+
const u = [];
|
|
5694
5694
|
if (r.visemes && r.visemes.length > 0) {
|
|
5695
5695
|
console.log("Deepgram: Generating lip-sync animation from", r.visemes.length, "visemes");
|
|
5696
5696
|
for (let c = 0; c < r.visemes.length; c++) {
|
|
5697
|
-
const d = r.visemes[c], g = d.startTime * 1e3, y = d.duration * 1e3,
|
|
5698
|
-
|
|
5697
|
+
const d = r.visemes[c], g = d.startTime * 1e3, y = d.duration * 1e3, b = d.intensity;
|
|
5698
|
+
u.push({
|
|
5699
5699
|
template: { name: "viseme" },
|
|
5700
5700
|
ts: [g - Math.min(60, 2 * y / 3), g + Math.min(25, y / 2), g + y + Math.min(60, y / 2)],
|
|
5701
5701
|
vs: {
|
|
5702
|
-
["viseme_" + d.viseme]: [null,
|
|
5702
|
+
["viseme_" + d.viseme]: [null, b, 0]
|
|
5703
5703
|
}
|
|
5704
5704
|
});
|
|
5705
5705
|
}
|
|
5706
|
-
console.log("Deepgram: Generated",
|
|
5706
|
+
console.log("Deepgram: Generated", u.length, "lip-sync animation frames");
|
|
5707
5707
|
} else
|
|
5708
5708
|
console.warn("Deepgram: No visemes available for lip-sync animation");
|
|
5709
|
-
const a = [...t.anim, ...
|
|
5710
|
-
console.log("Deepgram: Combined animation frames:", a.length, "(original:", t.anim.length, "+ lipsync:",
|
|
5709
|
+
const a = [...t.anim, ...u];
|
|
5710
|
+
console.log("Deepgram: Combined animation frames:", a.length, "(original:", t.anim.length, "+ lipsync:", u.length, ")"), this.audioPlaylist.push({ anim: a, audio: l }), this.onSubtitles = t.onSubtitles || null, this.resetLips(), t.mood && this.setMood(t.mood), this.playAudio();
|
|
5711
5711
|
}
|
|
5712
5712
|
/**
|
|
5713
5713
|
* Synthesize speech using Azure TTS
|
|
@@ -5733,20 +5733,20 @@ class Ne {
|
|
|
5733
5733
|
throw new Error(`Azure TTS error: ${s.status} ${s.statusText}`);
|
|
5734
5734
|
const o = await s.arrayBuffer(), l = await this.audioCtx.decodeAudioData(o);
|
|
5735
5735
|
console.log("Analyzing audio for precise lip-sync...");
|
|
5736
|
-
const
|
|
5736
|
+
const h = await this.audioAnalyzer.analyzeAudio(l, e);
|
|
5737
5737
|
console.log("Azure TTS Audio Analysis:", {
|
|
5738
5738
|
text: e,
|
|
5739
5739
|
audioDuration: l.duration,
|
|
5740
|
-
visemeCount:
|
|
5741
|
-
wordCount:
|
|
5740
|
+
visemeCount: h.visemes.length,
|
|
5741
|
+
wordCount: h.words.length,
|
|
5742
5742
|
features: {
|
|
5743
|
-
onsets:
|
|
5744
|
-
boundaries:
|
|
5743
|
+
onsets: h.features.onsets.length,
|
|
5744
|
+
boundaries: h.features.phonemeBoundaries.length
|
|
5745
5745
|
}
|
|
5746
5746
|
});
|
|
5747
5747
|
const r = [];
|
|
5748
|
-
for (let a = 0; a <
|
|
5749
|
-
const c =
|
|
5748
|
+
for (let a = 0; a < h.visemes.length; a++) {
|
|
5749
|
+
const c = h.visemes[a], d = c.startTime * 1e3, g = c.duration * 1e3, y = c.intensity;
|
|
5750
5750
|
r.push({
|
|
5751
5751
|
template: { name: "viseme" },
|
|
5752
5752
|
ts: [d - Math.min(60, 2 * g / 3), d + Math.min(25, g / 2), d + g + Math.min(60, g / 2)],
|
|
@@ -5755,8 +5755,8 @@ class Ne {
|
|
|
5755
5755
|
}
|
|
5756
5756
|
});
|
|
5757
5757
|
}
|
|
5758
|
-
const
|
|
5759
|
-
this.audioPlaylist.push({ anim:
|
|
5758
|
+
const u = [...t.anim, ...r];
|
|
5759
|
+
this.audioPlaylist.push({ anim: u, audio: l }), this.onSubtitles = t.onSubtitles || null, this.resetLips(), t.mood && this.setMood(t.mood), this.playAudio();
|
|
5760
5760
|
}
|
|
5761
5761
|
/**
|
|
5762
5762
|
* Synthesize speech using external TTS service (Google Cloud, etc.)
|
|
@@ -5795,24 +5795,24 @@ class Ne {
|
|
|
5795
5795
|
if (i.status === 200 && s && s.audioContent) {
|
|
5796
5796
|
const o = this.b64ToArrayBuffer(s.audioContent), l = await this.audioCtx.decodeAudioData(o);
|
|
5797
5797
|
this.speakWithHands();
|
|
5798
|
-
const
|
|
5798
|
+
const h = [0];
|
|
5799
5799
|
let r = 0;
|
|
5800
5800
|
t.text.forEach((c, d) => {
|
|
5801
5801
|
if (d > 0) {
|
|
5802
|
-
let g =
|
|
5803
|
-
s.timepoints[r] && (g = s.timepoints[r].timeSeconds * 1e3, s.timepoints[r].markName === "" + c.mark && r++),
|
|
5802
|
+
let g = h[h.length - 1];
|
|
5803
|
+
s.timepoints[r] && (g = s.timepoints[r].timeSeconds * 1e3, s.timepoints[r].markName === "" + c.mark && r++), h.push(g);
|
|
5804
5804
|
}
|
|
5805
5805
|
});
|
|
5806
|
-
const
|
|
5807
|
-
|
|
5806
|
+
const u = [{ mark: 0, time: 0 }];
|
|
5807
|
+
h.forEach((c, d) => {
|
|
5808
5808
|
if (d > 0) {
|
|
5809
|
-
let g = c -
|
|
5810
|
-
|
|
5809
|
+
let g = c - h[d - 1];
|
|
5810
|
+
u[d - 1].duration = g, u.push({ mark: d, time: c });
|
|
5811
5811
|
}
|
|
5812
5812
|
});
|
|
5813
5813
|
let a = 1e3 * l.duration;
|
|
5814
|
-
a > this.opt.ttsTrimEnd && (a = a - this.opt.ttsTrimEnd),
|
|
5815
|
-
const d =
|
|
5814
|
+
a > this.opt.ttsTrimEnd && (a = a - this.opt.ttsTrimEnd), u[u.length - 1].duration = a - u[u.length - 1].time, t.anim.forEach((c) => {
|
|
5815
|
+
const d = u[c.mark];
|
|
5816
5816
|
if (d)
|
|
5817
5817
|
for (let g = 0; g < c.ts.length; g++)
|
|
5818
5818
|
c.ts[g] = d.time + c.ts[g] * d.duration + this.opt.ttsTrimStart;
|
|
@@ -5895,10 +5895,10 @@ class Ne {
|
|
|
5895
5895
|
}
|
|
5896
5896
|
if (!this.workletLoaded)
|
|
5897
5897
|
try {
|
|
5898
|
-
const l = this.audioCtx.audioWorklet.addModule(dt.href),
|
|
5899
|
-
(r,
|
|
5898
|
+
const l = this.audioCtx.audioWorklet.addModule(dt.href), h = new Promise(
|
|
5899
|
+
(r, u) => setTimeout(() => u(new Error("Worklet loading timed out")), 5e3)
|
|
5900
5900
|
);
|
|
5901
|
-
await Promise.race([l,
|
|
5901
|
+
await Promise.race([l, h]), this.workletLoaded = !0;
|
|
5902
5902
|
} catch (l) {
|
|
5903
5903
|
throw console.error("Failed to load audio worklet:", l), new Error("Failed to initialize streaming speech");
|
|
5904
5904
|
}
|
|
@@ -5911,8 +5911,8 @@ class Ne {
|
|
|
5911
5911
|
if (l.data.type === "playback-started" && (this.isSpeaking = !0, this.stateName = "speaking", this.streamWaitForAudioChunks && (this.streamAudioStartTime = this.animClock), this._processStreamLipsyncQueue(), this.speakWithHands(), this.onAudioStart))
|
|
5912
5912
|
try {
|
|
5913
5913
|
this.onAudioStart?.();
|
|
5914
|
-
} catch (
|
|
5915
|
-
console.error(
|
|
5914
|
+
} catch (h) {
|
|
5915
|
+
console.error(h);
|
|
5916
5916
|
}
|
|
5917
5917
|
if (l.data.type === "playback-ended" && (this._streamPause(), this.onAudioEnd))
|
|
5918
5918
|
try {
|
|
@@ -5932,9 +5932,9 @@ class Ne {
|
|
|
5932
5932
|
} catch {
|
|
5933
5933
|
}
|
|
5934
5934
|
if (this.resetLips(), this.lookAtCamera(500), t.mood && this.setMood(t.mood), this.onSubtitles = i || null, this.audioCtx.state === "suspended" || this.audioCtx.state === "interrupted") {
|
|
5935
|
-
const l = this.audioCtx.resume(),
|
|
5935
|
+
const l = this.audioCtx.resume(), h = new Promise((r, u) => setTimeout(() => u("p2"), 1e3));
|
|
5936
5936
|
try {
|
|
5937
|
-
await Promise.race([l,
|
|
5937
|
+
await Promise.race([l, h]);
|
|
5938
5938
|
} catch {
|
|
5939
5939
|
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.");
|
|
5940
5940
|
return;
|
|
@@ -6031,13 +6031,13 @@ class Ne {
|
|
|
6031
6031
|
subtitles: [" " + i]
|
|
6032
6032
|
}
|
|
6033
6033
|
}), this.streamLipsyncType == "words")) {
|
|
6034
|
-
const l = this.streamLipsyncLang || this.avatar.lipsyncLang || this.opt.lipsyncLang,
|
|
6034
|
+
const l = this.streamLipsyncLang || this.avatar.lipsyncLang || this.opt.lipsyncLang, h = this.lipsyncPreProcessText(i, l), r = this.lipsyncWordsToVisemes(h, l);
|
|
6035
6035
|
if (r && r.visemes && r.visemes.length) {
|
|
6036
|
-
const
|
|
6036
|
+
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));
|
|
6037
6037
|
let c = 0.6 + this.convertRange(a, [0, o], [0, 0.4]);
|
|
6038
|
-
if (o = Math.min(o, r.visemes.length * 200),
|
|
6038
|
+
if (o = Math.min(o, r.visemes.length * 200), u > 0)
|
|
6039
6039
|
for (let d = 0; d < r.visemes.length; d++) {
|
|
6040
|
-
const g = e + s + r.times[d] /
|
|
6040
|
+
const g = e + s + r.times[d] / u * o, y = r.durations[d] / u * o;
|
|
6041
6041
|
this.animQueue.push({
|
|
6042
6042
|
template: { name: "viseme" },
|
|
6043
6043
|
ts: [g - Math.min(60, 2 * y / 3), g + Math.min(25, y / 2), g + y + Math.min(60, y / 2)],
|
|
@@ -6133,7 +6133,7 @@ class Ne {
|
|
|
6133
6133
|
*/
|
|
6134
6134
|
lookAtCamera(t) {
|
|
6135
6135
|
let e;
|
|
6136
|
-
if (this.speakTo && (e = new
|
|
6136
|
+
if (this.speakTo && (e = new x.Vector3(), this.speakTo.objectLeftEye?.isObject3D ? (this.speakTo.armature.objectHead, this.speakTo.objectLeftEye.updateMatrixWorld(!0), this.speakTo.objectRightEye.updateMatrixWorld(!0), ve.setFromMatrixPosition(this.speakTo.objectLeftEye.matrixWorld), Re.setFromMatrixPosition(this.speakTo.objectRightEye.matrixWorld), e.addVectors(ve, Re).divideScalar(2)) : this.speakTo.isObject3D ? this.speakTo.getWorldPosition(e) : this.speakTo.isVector3 ? e.set(this.speakTo) : this.speakTo.x && this.speakTo.y && this.speakTo.z && e.set(this.speakTo.x, this.speakTo.y, this.speakTo.z)), !e) {
|
|
6137
6137
|
if (this.avatar.hasOwnProperty("avatarIgnoreCamera")) {
|
|
6138
6138
|
if (this.avatar.avatarIgnoreCamera) {
|
|
6139
6139
|
this.lookAhead(t);
|
|
@@ -6146,16 +6146,16 @@ class Ne {
|
|
|
6146
6146
|
this.lookAt(null, null, t);
|
|
6147
6147
|
return;
|
|
6148
6148
|
}
|
|
6149
|
-
this.objectLeftEye.updateMatrixWorld(!0), this.objectRightEye.updateMatrixWorld(!0),
|
|
6150
|
-
const n = new
|
|
6151
|
-
|
|
6152
|
-
const l = new
|
|
6153
|
-
|
|
6154
|
-
let r =
|
|
6149
|
+
this.objectLeftEye.updateMatrixWorld(!0), this.objectRightEye.updateMatrixWorld(!0), ve.setFromMatrixPosition(this.objectLeftEye.matrixWorld), Re.setFromMatrixPosition(this.objectRightEye.matrixWorld), ve.add(Re).divideScalar(2), Q.copy(this.armature.quaternion), Q.multiply(this.poseTarget.props["Hips.quaternion"]), Q.multiply(this.poseTarget.props["Spine.quaternion"]), Q.multiply(this.poseTarget.props["Spine1.quaternion"]), Q.multiply(this.poseTarget.props["Spine2.quaternion"]), Q.multiply(this.poseTarget.props["Neck.quaternion"]), Q.multiply(this.poseTarget.props["Head.quaternion"]);
|
|
6150
|
+
const n = new x.Vector3().subVectors(e, ve).normalize(), i = Math.atan2(n.x, n.z), s = Math.asin(-n.y);
|
|
6151
|
+
W.set(s, i, 0, "YXZ");
|
|
6152
|
+
const l = new x.Quaternion().setFromEuler(W), h = new x.Quaternion().copy(l).multiply(Q.clone().invert());
|
|
6153
|
+
W.setFromQuaternion(h, "YXZ");
|
|
6154
|
+
let r = W.x / (40 / 24) + 0.2, u = W.y / (9 / 4), a = Math.min(0.6, Math.max(-0.3, r)), c = Math.min(0.8, Math.max(-0.8, u)), d = (Math.random() - 0.5) / 4, g = (Math.random() - 0.5) / 4;
|
|
6155
6155
|
if (t) {
|
|
6156
|
-
let y = this.animQueue.findIndex((
|
|
6156
|
+
let y = this.animQueue.findIndex((I) => I.template.name === "lookat");
|
|
6157
6157
|
y !== -1 && this.animQueue.splice(y, 1);
|
|
6158
|
-
const
|
|
6158
|
+
const b = {
|
|
6159
6159
|
name: "lookat",
|
|
6160
6160
|
dt: [750, t],
|
|
6161
6161
|
vs: {
|
|
@@ -6170,7 +6170,7 @@ class Ne {
|
|
|
6170
6170
|
headMove: [0]
|
|
6171
6171
|
}
|
|
6172
6172
|
};
|
|
6173
|
-
this.animQueue.push(this.animFactory(
|
|
6173
|
+
this.animQueue.push(this.animFactory(b));
|
|
6174
6174
|
}
|
|
6175
6175
|
}
|
|
6176
6176
|
/**
|
|
@@ -6183,23 +6183,23 @@ class Ne {
|
|
|
6183
6183
|
if (!this.camera) return;
|
|
6184
6184
|
const i = this.nodeAvatar.getBoundingClientRect();
|
|
6185
6185
|
this.objectLeftEye.updateMatrixWorld(!0), this.objectRightEye.updateMatrixWorld(!0);
|
|
6186
|
-
const s = new
|
|
6186
|
+
const s = new x.Vector3().setFromMatrixPosition(this.objectLeftEye.matrixWorld), o = new x.Vector3().setFromMatrixPosition(this.objectRightEye.matrixWorld), l = new x.Vector3().addVectors(s, o).divideScalar(2);
|
|
6187
6187
|
l.project(this.camera);
|
|
6188
|
-
let
|
|
6189
|
-
t === null && (t =
|
|
6190
|
-
let
|
|
6191
|
-
|
|
6192
|
-
let
|
|
6188
|
+
let h = (l.x + 1) / 2 * i.width + i.left, r = -(l.y - 1) / 2 * i.height + i.top;
|
|
6189
|
+
t === null && (t = h), e === null && (e = r), Q.copy(this.armature.quaternion), Q.multiply(this.poseTarget.props["Hips.quaternion"]), Q.multiply(this.poseTarget.props["Spine.quaternion"]), Q.multiply(this.poseTarget.props["Spine1.quaternion"]), Q.multiply(this.poseTarget.props["Spine2.quaternion"]), Q.multiply(this.poseTarget.props["Neck.quaternion"]), Q.multiply(this.poseTarget.props["Head.quaternion"]), W.setFromQuaternion(Q);
|
|
6190
|
+
let u = W.x / (40 / 24), a = W.y / (9 / 4), c = Math.min(0.4, Math.max(-0.4, this.camera.rotation.x)), d = Math.min(0.4, Math.max(-0.4, this.camera.rotation.y)), g = Math.max(window.innerWidth - h, h), y = Math.max(window.innerHeight - r, r), b = this.convertRange(e, [r - y, r + y], [-0.3, 0.6]) - u + c, I = this.convertRange(t, [h - g, h + g], [-0.8, 0.8]) - a + d;
|
|
6191
|
+
b = Math.min(0.6, Math.max(-0.3, b)), I = Math.min(0.8, Math.max(-0.8, I));
|
|
6192
|
+
let V = (Math.random() - 0.5) / 4, p = (Math.random() - 0.5) / 4;
|
|
6193
6193
|
if (n) {
|
|
6194
|
-
let
|
|
6195
|
-
|
|
6196
|
-
const
|
|
6194
|
+
let M = this.animQueue.findIndex((f) => f.template.name === "lookat");
|
|
6195
|
+
M !== -1 && this.animQueue.splice(M, 1);
|
|
6196
|
+
const w = {
|
|
6197
6197
|
name: "lookat",
|
|
6198
6198
|
dt: [750, n],
|
|
6199
6199
|
vs: {
|
|
6200
|
-
bodyRotateX: [
|
|
6201
|
-
bodyRotateY: [
|
|
6202
|
-
eyesRotateX: [-3 *
|
|
6200
|
+
bodyRotateX: [b + V],
|
|
6201
|
+
bodyRotateY: [I + p],
|
|
6202
|
+
eyesRotateX: [-3 * V + 0.1],
|
|
6203
6203
|
eyesRotateY: [-5 * p],
|
|
6204
6204
|
browInnerUp: [[0, 0.7]],
|
|
6205
6205
|
mouthLeft: [[0, 0.7]],
|
|
@@ -6208,7 +6208,7 @@ class Ne {
|
|
|
6208
6208
|
headMove: [0]
|
|
6209
6209
|
}
|
|
6210
6210
|
};
|
|
6211
|
-
this.animQueue.push(this.animFactory(
|
|
6211
|
+
this.animQueue.push(this.animFactory(w));
|
|
6212
6212
|
}
|
|
6213
6213
|
}
|
|
6214
6214
|
/**
|
|
@@ -6219,17 +6219,17 @@ class Ne {
|
|
|
6219
6219
|
*/
|
|
6220
6220
|
touchAt(t, e) {
|
|
6221
6221
|
if (!this.camera) return;
|
|
6222
|
-
const n = this.nodeAvatar.getBoundingClientRect(), i = new
|
|
6222
|
+
const n = this.nodeAvatar.getBoundingClientRect(), i = new x.Vector2(
|
|
6223
6223
|
(t - n.left) / n.width * 2 - 1,
|
|
6224
6224
|
-((e - n.top) / n.height) * 2 + 1
|
|
6225
|
-
), s = new
|
|
6225
|
+
), s = new x.Raycaster();
|
|
6226
6226
|
s.setFromCamera(i, this.camera);
|
|
6227
6227
|
const o = s.intersectObject(this.armature);
|
|
6228
6228
|
if (o.length > 0) {
|
|
6229
|
-
const l = o[0].point,
|
|
6230
|
-
this.objectLeftArm.getWorldPosition(
|
|
6231
|
-
const
|
|
6232
|
-
|
|
6229
|
+
const l = o[0].point, h = new x.Vector3(), r = new x.Vector3();
|
|
6230
|
+
this.objectLeftArm.getWorldPosition(h), this.objectRightArm.getWorldPosition(r);
|
|
6231
|
+
const u = h.distanceToSquared(l), a = r.distanceToSquared(l);
|
|
6232
|
+
u < a ? (this.ikSolve({
|
|
6233
6233
|
iterations: 20,
|
|
6234
6234
|
root: "LeftShoulder",
|
|
6235
6235
|
effector: "LeftHandMiddle1",
|
|
@@ -6250,8 +6250,8 @@ class Ne {
|
|
|
6250
6250
|
}, l, !1, 1e3), this.setValue("handFistRight", 0));
|
|
6251
6251
|
} else
|
|
6252
6252
|
["LeftArm", "LeftForeArm", "LeftHand", "RightArm", "RightForeArm", "RightHand"].forEach((l) => {
|
|
6253
|
-
let
|
|
6254
|
-
this.poseTarget.props[
|
|
6253
|
+
let h = l + ".quaternion";
|
|
6254
|
+
this.poseTarget.props[h].copy(this.getPoseTemplateProp(h)), this.poseTarget.props[h].t = this.animClock, this.poseTarget.props[h].d = 1e3;
|
|
6255
6255
|
});
|
|
6256
6256
|
return o.length > 0;
|
|
6257
6257
|
}
|
|
@@ -6270,7 +6270,7 @@ class Ne {
|
|
|
6270
6270
|
{ link: "LeftForeArm", minx: -0.5, maxx: 1.5, miny: -1.5, maxy: 1.5, minz: -0.5, maxz: 3 },
|
|
6271
6271
|
{ link: "LeftArm", minx: -1.5, maxx: 1.5, miny: -1.5, maxy: 1.5, minz: -1, maxz: 3 }
|
|
6272
6272
|
]
|
|
6273
|
-
}, new
|
|
6273
|
+
}, new x.Vector3(
|
|
6274
6274
|
this.gaussianRandom(0, 0.5),
|
|
6275
6275
|
this.gaussianRandom(-0.8, -0.2),
|
|
6276
6276
|
this.gaussianRandom(0, 0.5)
|
|
@@ -6282,15 +6282,15 @@ class Ne {
|
|
|
6282
6282
|
{ link: "RightForeArm", minx: -0.5, maxx: 1.5, miny: -1.5, maxy: 1.5, minz: -3, maxz: 0.5 },
|
|
6283
6283
|
{ link: "RightArm" }
|
|
6284
6284
|
]
|
|
6285
|
-
}, new
|
|
6285
|
+
}, new x.Vector3(
|
|
6286
6286
|
this.gaussianRandom(-0.5, 0),
|
|
6287
6287
|
this.gaussianRandom(-0.8, -0.2),
|
|
6288
6288
|
this.gaussianRandom(0, 0.5)
|
|
6289
6289
|
), !0);
|
|
6290
6290
|
const n = [], i = [];
|
|
6291
6291
|
n.push(100 + Math.round(Math.random() * 500)), i.push({ duration: 1e3, props: {
|
|
6292
|
-
"LeftHand.quaternion": new
|
|
6293
|
-
"RightHand.quaternion": new
|
|
6292
|
+
"LeftHand.quaternion": new x.Quaternion().setFromEuler(new x.Euler(0, -1 - Math.random(), 0)),
|
|
6293
|
+
"RightHand.quaternion": new x.Quaternion().setFromEuler(new x.Euler(0, 1 + Math.random(), 0))
|
|
6294
6294
|
} }), ["LeftArm", "LeftForeArm", "RightArm", "RightForeArm"].forEach((o) => {
|
|
6295
6295
|
i[0].props[o + ".quaternion"] = this.ikMesh.getObjectByName(o).quaternion.clone();
|
|
6296
6296
|
}), n.push(1e3 + Math.round(Math.random() * 500)), i.push({ duration: 2e3, props: {} }), ["LeftArm", "LeftForeArm", "RightArm", "RightForeArm", "LeftHand", "RightHand"].forEach((o) => {
|
|
@@ -6370,21 +6370,21 @@ class Ne {
|
|
|
6370
6370
|
async playAnimation(t, e = null, n = 10, i = 0, s = 0.01, o = !1) {
|
|
6371
6371
|
if (!this.armature) return;
|
|
6372
6372
|
this.positionWasLocked = !o, o ? console.log("Position locking disabled for FBX animation:", t) : (this.lockAvatarPosition(), console.log("Position locked immediately before FBX animation:", t));
|
|
6373
|
-
let l = this.animClips.find((
|
|
6373
|
+
let l = this.animClips.find((h) => h.url === t + "-" + i);
|
|
6374
6374
|
if (l) {
|
|
6375
|
-
let
|
|
6376
|
-
|
|
6375
|
+
let h = this.animQueue.find((a) => a.template.name === "pose");
|
|
6376
|
+
h && (h.ts[0] = 1 / 0), Object.entries(l.pose.props).forEach((a) => {
|
|
6377
6377
|
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;
|
|
6378
|
-
}), this.mixer ? console.log("Using existing mixer for FBX animation, preserving morph targets") : (this.mixer = new
|
|
6379
|
-
const r = Math.ceil(n / l.clip.duration),
|
|
6380
|
-
|
|
6378
|
+
}), this.mixer ? console.log("Using existing mixer for FBX animation, preserving morph targets") : (this.mixer = new x.AnimationMixer(this.armature), console.log("Created new mixer for FBX animation")), this.mixer.addEventListener("finished", this.stopAnimation.bind(this), { once: !0 });
|
|
6379
|
+
const r = Math.ceil(n / l.clip.duration), u = this.mixer.clipAction(l.clip);
|
|
6380
|
+
u.setLoop(x.LoopRepeat, r), u.clampWhenFinished = !0, this.currentFBXAction = u;
|
|
6381
6381
|
try {
|
|
6382
|
-
|
|
6382
|
+
u.fadeIn(0.5).play(), console.log("FBX animation started successfully:", t);
|
|
6383
6383
|
} catch (a) {
|
|
6384
6384
|
console.warn("FBX animation failed to start:", a), this.stopAnimation();
|
|
6385
6385
|
return;
|
|
6386
6386
|
}
|
|
6387
|
-
if (
|
|
6387
|
+
if (u.getClip().tracks.length === 0) {
|
|
6388
6388
|
console.warn("FBX animation has no valid tracks, stopping"), this.stopAnimation();
|
|
6389
6389
|
return;
|
|
6390
6390
|
}
|
|
@@ -6403,10 +6403,10 @@ class Ne {
|
|
|
6403
6403
|
} catch (c) {
|
|
6404
6404
|
console.warn(`Could not verify file existence for ${t}, attempting to load anyway:`, c);
|
|
6405
6405
|
}
|
|
6406
|
-
const
|
|
6406
|
+
const u = new Oe();
|
|
6407
6407
|
let a;
|
|
6408
6408
|
try {
|
|
6409
|
-
a = await
|
|
6409
|
+
a = await u.loadAsync(t, e);
|
|
6410
6410
|
} catch (c) {
|
|
6411
6411
|
console.error(`Failed to load FBX animation from ${t}:`, c), console.error("Error details:", {
|
|
6412
6412
|
message: c.message,
|
|
@@ -6431,12 +6431,12 @@ class Ne {
|
|
|
6431
6431
|
const d = {};
|
|
6432
6432
|
c.tracks.forEach((y) => {
|
|
6433
6433
|
y.name = y.name.replaceAll("mixamorig", "");
|
|
6434
|
-
const
|
|
6435
|
-
if (
|
|
6436
|
-
for (let
|
|
6437
|
-
y.values[
|
|
6438
|
-
d[y.name] = new
|
|
6439
|
-
} else
|
|
6434
|
+
const b = y.name.split(".");
|
|
6435
|
+
if (b[1] === "position") {
|
|
6436
|
+
for (let I = 0; I < y.values.length; I++)
|
|
6437
|
+
y.values[I] = y.values[I] * s;
|
|
6438
|
+
d[y.name] = new x.Vector3(y.values[0], y.values[1], y.values[2]);
|
|
6439
|
+
} else b[1] === "quaternion" ? d[y.name] = new x.Quaternion(y.values[0], y.values[1], y.values[2], y.values[3]) : b[1] === "rotation" && (d[b[0] + ".quaternion"] = new x.Quaternion().setFromEuler(new x.Euler(y.values[0], y.values[1], y.values[2], "XYZ")).normalize());
|
|
6440
6440
|
});
|
|
6441
6441
|
const g = { props: d };
|
|
6442
6442
|
d["Hips.position"] && (d["Hips.position"].y < 0.5 ? g.lying = !0 : g.standing = !0), this.animClips.push({
|
|
@@ -6472,25 +6472,25 @@ class Ne {
|
|
|
6472
6472
|
if (!this.armature) return;
|
|
6473
6473
|
let o = this.poseTemplates[t];
|
|
6474
6474
|
if (!o) {
|
|
6475
|
-
const l = this.animPoses.find((
|
|
6475
|
+
const l = this.animPoses.find((h) => h.url === t + "-" + i);
|
|
6476
6476
|
l && (o = l.pose);
|
|
6477
6477
|
}
|
|
6478
6478
|
if (o) {
|
|
6479
6479
|
this.poseName = t, this.mixer = null;
|
|
6480
|
-
let l = this.animQueue.find((
|
|
6480
|
+
let l = this.animQueue.find((h) => h.template.name === "pose");
|
|
6481
6481
|
l && (l.ts[0] = this.animClock + n * 1e3 + 2e3), this.setPoseFromTemplate(o);
|
|
6482
6482
|
} else {
|
|
6483
|
-
let
|
|
6484
|
-
if (
|
|
6485
|
-
let r =
|
|
6486
|
-
const
|
|
6483
|
+
let h = await new Oe().loadAsync(t, e);
|
|
6484
|
+
if (h && h.animations && h.animations[i]) {
|
|
6485
|
+
let r = h.animations[i];
|
|
6486
|
+
const u = {};
|
|
6487
6487
|
r.tracks.forEach((c) => {
|
|
6488
6488
|
c.name = c.name.replaceAll("mixamorig", "");
|
|
6489
6489
|
const d = c.name.split(".");
|
|
6490
|
-
d[1] === "position" ?
|
|
6490
|
+
d[1] === "position" ? u[c.name] = new x.Vector3(c.values[0] * s, c.values[1] * s, c.values[2] * s) : d[1] === "quaternion" ? u[c.name] = new x.Quaternion(c.values[0], c.values[1], c.values[2], c.values[3]) : d[1] === "rotation" && (u[d[0] + ".quaternion"] = new x.Quaternion().setFromEuler(new x.Euler(c.values[0], c.values[1], c.values[2], "XYZ")).normalize());
|
|
6491
6491
|
});
|
|
6492
|
-
const a = { props:
|
|
6493
|
-
|
|
6492
|
+
const a = { props: u };
|
|
6493
|
+
u["Hips.position"] && (u["Hips.position"].y < 0.5 ? a.lying = !0 : a.standing = !0), this.animPoses.push({
|
|
6494
6494
|
url: t + "-" + i,
|
|
6495
6495
|
pose: a
|
|
6496
6496
|
}), this.playPose(t, e, n, i, s);
|
|
@@ -6519,10 +6519,10 @@ class Ne {
|
|
|
6519
6519
|
let s = this.gestureTemplates[t];
|
|
6520
6520
|
if (s) {
|
|
6521
6521
|
this.gestureTimeout && (clearTimeout(this.gestureTimeout), this.gestureTimeout = null);
|
|
6522
|
-
let l = this.animQueue.findIndex((
|
|
6523
|
-
l !== -1 && (this.animQueue[l].ts = this.animQueue[l].ts.map((
|
|
6524
|
-
for (let [
|
|
6525
|
-
r.t = this.animClock, r.d = i, this.poseTarget.props.hasOwnProperty(
|
|
6522
|
+
let l = this.animQueue.findIndex((h) => h.template.name === "talkinghands");
|
|
6523
|
+
l !== -1 && (this.animQueue[l].ts = this.animQueue[l].ts.map((h) => 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 x.Quaternion(0, 1, 0, 0), -0.25), this.gesture["LeftArm.quaternion"].rotateTowards(new x.Quaternion(0, 1, 0, 0), -0.25));
|
|
6524
|
+
for (let [h, r] of Object.entries(this.gesture))
|
|
6525
|
+
r.t = this.animClock, r.d = i, this.poseTarget.props.hasOwnProperty(h) && (this.poseTarget.props[h].copy(r), this.poseTarget.props[h].t = this.animClock, this.poseTarget.props[h].d = i);
|
|
6526
6526
|
e && Number.isFinite(e) && (this.gestureTimeout = setTimeout(this.stopGesture.bind(this, i), 1e3 * e));
|
|
6527
6527
|
}
|
|
6528
6528
|
let o = this.animEmojis[t];
|
|
@@ -6530,15 +6530,15 @@ class Ne {
|
|
|
6530
6530
|
this.lookAtCamera(500);
|
|
6531
6531
|
const l = this.animFactory(o);
|
|
6532
6532
|
if (l.gesture = !0, e && Number.isFinite(e)) {
|
|
6533
|
-
const
|
|
6534
|
-
if (e * 1e3 -
|
|
6533
|
+
const h = l.ts[0], u = l.ts[l.ts.length - 1] - h;
|
|
6534
|
+
if (e * 1e3 - u > 0) {
|
|
6535
6535
|
const c = [];
|
|
6536
6536
|
for (let y = 1; y < l.ts.length; y++) c.push(l.ts[y] - l.ts[y - 1]);
|
|
6537
|
-
const d = o.template?.rescale || c.map((y) => y /
|
|
6538
|
-
l.ts = l.ts.map((y,
|
|
6537
|
+
const d = o.template?.rescale || c.map((y) => y / u), g = e * 1e3 - u;
|
|
6538
|
+
l.ts = l.ts.map((y, b, I) => b === 0 ? h : I[b - 1] + c[b - 1] + d[b - 1] * g);
|
|
6539
6539
|
} else {
|
|
6540
|
-
const c = e * 1e3 /
|
|
6541
|
-
l.ts = l.ts.map((d) =>
|
|
6540
|
+
const c = e * 1e3 / u;
|
|
6541
|
+
l.ts = l.ts.map((d) => h + c * (d - h));
|
|
6542
6542
|
}
|
|
6543
6543
|
}
|
|
6544
6544
|
this.animQueue.push(l);
|
|
@@ -6568,34 +6568,34 @@ class Ne {
|
|
|
6568
6568
|
* @param {numeric} [d=null] If set, apply in d milliseconds
|
|
6569
6569
|
*/
|
|
6570
6570
|
ikSolve(t, e = null, n = !1, i = null) {
|
|
6571
|
-
const s = new
|
|
6571
|
+
const s = new x.Vector3(), o = new x.Vector3(), l = new x.Vector3(), h = new x.Vector3(), r = new x.Quaternion(), u = new x.Vector3(), a = new x.Vector3(), c = new x.Vector3(), d = this.ikMesh.getObjectByName(t.root);
|
|
6572
6572
|
d.position.setFromMatrixPosition(this.armature.getObjectByName(t.root).matrixWorld), d.quaternion.setFromRotationMatrix(this.armature.getObjectByName(t.root).matrixWorld), e && n && e.applyQuaternion(this.armature.quaternion).add(d.position);
|
|
6573
6573
|
const g = this.ikMesh.getObjectByName(t.effector), y = t.links;
|
|
6574
|
-
y.forEach((
|
|
6575
|
-
|
|
6574
|
+
y.forEach((I) => {
|
|
6575
|
+
I.bone = this.ikMesh.getObjectByName(I.link), I.bone.quaternion.copy(this.getPoseTemplateProp(I.link + ".quaternion"));
|
|
6576
6576
|
}), d.updateMatrixWorld(!0);
|
|
6577
|
-
const
|
|
6577
|
+
const b = t.iterations || 10;
|
|
6578
6578
|
if (e)
|
|
6579
|
-
for (let
|
|
6580
|
-
let
|
|
6581
|
-
for (let p = 0,
|
|
6582
|
-
const
|
|
6583
|
-
|
|
6584
|
-
let
|
|
6585
|
-
|
|
6579
|
+
for (let I = 0; I < b; I++) {
|
|
6580
|
+
let V = !1;
|
|
6581
|
+
for (let p = 0, M = y.length; p < M; p++) {
|
|
6582
|
+
const w = y[p].bone;
|
|
6583
|
+
w.matrixWorld.decompose(h, r, u), r.invert(), o.setFromMatrixPosition(g.matrixWorld), l.subVectors(o, h), l.applyQuaternion(r), l.normalize(), s.subVectors(e, h), s.applyQuaternion(r), s.normalize();
|
|
6584
|
+
let f = s.dot(l);
|
|
6585
|
+
f > 1 ? f = 1 : f < -1 && (f = -1), f = Math.acos(f), !(f < 1e-5) && (y[p].minAngle !== void 0 && f < y[p].minAngle && (f = y[p].minAngle), y[p].maxAngle !== void 0 && f > y[p].maxAngle && (f = y[p].maxAngle), a.crossVectors(l, s), a.normalize(), Q.setFromAxisAngle(a, f), w.quaternion.multiply(Q), w.rotation.setFromVector3(c.setFromEuler(w.rotation).clamp(new x.Vector3(
|
|
6586
6586
|
y[p].minx !== void 0 ? y[p].minx : -1 / 0,
|
|
6587
6587
|
y[p].miny !== void 0 ? y[p].miny : -1 / 0,
|
|
6588
6588
|
y[p].minz !== void 0 ? y[p].minz : -1 / 0
|
|
6589
|
-
), new
|
|
6589
|
+
), new x.Vector3(
|
|
6590
6590
|
y[p].maxx !== void 0 ? y[p].maxx : 1 / 0,
|
|
6591
6591
|
y[p].maxy !== void 0 ? y[p].maxy : 1 / 0,
|
|
6592
6592
|
y[p].maxz !== void 0 ? y[p].maxz : 1 / 0
|
|
6593
|
-
))),
|
|
6593
|
+
))), w.updateMatrixWorld(!0), V = !0);
|
|
6594
6594
|
}
|
|
6595
|
-
if (!
|
|
6595
|
+
if (!V) break;
|
|
6596
6596
|
}
|
|
6597
|
-
i && y.forEach((
|
|
6598
|
-
this.poseTarget.props[
|
|
6597
|
+
i && y.forEach((I) => {
|
|
6598
|
+
this.poseTarget.props[I.link + ".quaternion"].copy(I.bone.quaternion), this.poseTarget.props[I.link + ".quaternion"].t = this.animClock, this.poseTarget.props[I.link + ".quaternion"].d = i;
|
|
6599
6599
|
});
|
|
6600
6600
|
}
|
|
6601
6601
|
/**
|
|
@@ -6605,7 +6605,7 @@ class Ne {
|
|
|
6605
6605
|
this.isRunning = !1, this.stop(), this.stopSpeaking(), this.streamStop(), this.isAvatarOnly ? this.armature && (this.armature.parent && this.armature.parent.remove(this.armature), this.clearThree(this.armature)) : (this.clearThree(this.scene), this.resizeobserver.disconnect(), this.renderer && (this.renderer.dispose(), this.renderer.domElement && this.renderer.domElement.parentNode && this.renderer.domElement.parentNode.removeChild(this.renderer.domElement), this.renderer = null)), this.clearThree(this.ikMesh), this.dynamicbones.dispose();
|
|
6606
6606
|
}
|
|
6607
6607
|
}
|
|
6608
|
-
const
|
|
6608
|
+
const Ie = {
|
|
6609
6609
|
apiKey: "sk_ace57ef3ef65a92b9d3bee2a00183b78ca790bc3e10964f2",
|
|
6610
6610
|
// Replace with your actual API key (should start with sk_)
|
|
6611
6611
|
endpoint: "https://api.elevenlabs.io/v1/text-to-speech",
|
|
@@ -6625,7 +6625,7 @@ const Re = {
|
|
|
6625
6625
|
josh: "VR6AewLTigWG4xSOukaG"
|
|
6626
6626
|
// Male, American
|
|
6627
6627
|
}
|
|
6628
|
-
},
|
|
6628
|
+
}, Te = {
|
|
6629
6629
|
defaultVoice: "aura-2-thalia-en",
|
|
6630
6630
|
// Thalia (Female, English)
|
|
6631
6631
|
voices: {
|
|
@@ -6645,26 +6645,26 @@ const Re = {
|
|
|
6645
6645
|
// Male, English - Powerful
|
|
6646
6646
|
}
|
|
6647
6647
|
};
|
|
6648
|
-
function
|
|
6648
|
+
function Fe() {
|
|
6649
6649
|
return {
|
|
6650
6650
|
service: "elevenlabs",
|
|
6651
|
-
endpoint:
|
|
6652
|
-
apiKey:
|
|
6653
|
-
defaultVoice:
|
|
6654
|
-
voices:
|
|
6651
|
+
endpoint: Ie.endpoint,
|
|
6652
|
+
apiKey: Ie.apiKey,
|
|
6653
|
+
defaultVoice: Ie.defaultVoice,
|
|
6654
|
+
voices: Ie.voices
|
|
6655
6655
|
};
|
|
6656
6656
|
}
|
|
6657
|
-
function
|
|
6658
|
-
const
|
|
6659
|
-
return Object.entries(
|
|
6657
|
+
function kt() {
|
|
6658
|
+
const G = Fe(), t = [];
|
|
6659
|
+
return Object.entries(G.voices).forEach(([e, n]) => {
|
|
6660
6660
|
t.push({
|
|
6661
6661
|
value: n,
|
|
6662
|
-
label: `${e.charAt(0).toUpperCase() + e.slice(1)} (${
|
|
6662
|
+
label: `${e.charAt(0).toUpperCase() + e.slice(1)} (${G.service})`
|
|
6663
6663
|
});
|
|
6664
6664
|
}), t;
|
|
6665
6665
|
}
|
|
6666
|
-
const
|
|
6667
|
-
avatarUrl:
|
|
6666
|
+
const Ve = Me(({
|
|
6667
|
+
avatarUrl: G = "/avatars/brunette.glb",
|
|
6668
6668
|
avatarBody: t = "F",
|
|
6669
6669
|
mood: e = "neutral",
|
|
6670
6670
|
ttsLang: n = "en",
|
|
@@ -6672,9 +6672,9 @@ const Ue = ze(({
|
|
|
6672
6672
|
ttsVoice: s = null,
|
|
6673
6673
|
ttsApiKey: o = null,
|
|
6674
6674
|
bodyMovement: l = "idle",
|
|
6675
|
-
movementIntensity:
|
|
6675
|
+
movementIntensity: h = 0.5,
|
|
6676
6676
|
showFullAvatar: r = !0,
|
|
6677
|
-
cameraView:
|
|
6677
|
+
cameraView: u = "upper",
|
|
6678
6678
|
onReady: a = () => {
|
|
6679
6679
|
},
|
|
6680
6680
|
onLoading: c = () => {
|
|
@@ -6683,270 +6683,270 @@ const Ue = ze(({
|
|
|
6683
6683
|
},
|
|
6684
6684
|
className: g = "",
|
|
6685
6685
|
style: y = {},
|
|
6686
|
-
animations:
|
|
6687
|
-
},
|
|
6688
|
-
const
|
|
6689
|
-
|
|
6690
|
-
|
|
6691
|
-
}, [
|
|
6692
|
-
|
|
6686
|
+
animations: b = {}
|
|
6687
|
+
}, I) => {
|
|
6688
|
+
const V = D(null), p = D(null), M = D(r), w = D(null), f = D(null), E = D(!1), P = D({ remainingText: null, originalText: null, options: null }), U = D([]), oe = D(0), [S, Z] = ce(!0), [K, X] = ce(null), [$, se] = ce(!1), [ae, pe] = ce(!1);
|
|
6689
|
+
de(() => {
|
|
6690
|
+
E.current = ae;
|
|
6691
|
+
}, [ae]), de(() => {
|
|
6692
|
+
M.current = r;
|
|
6693
6693
|
}, [r]);
|
|
6694
|
-
const
|
|
6695
|
-
let
|
|
6696
|
-
|
|
6694
|
+
const ee = Fe(), le = i || ee.service;
|
|
6695
|
+
let O;
|
|
6696
|
+
le === "browser" ? O = {
|
|
6697
6697
|
service: "browser",
|
|
6698
6698
|
endpoint: "",
|
|
6699
6699
|
apiKey: null,
|
|
6700
6700
|
defaultVoice: "Google US English"
|
|
6701
|
-
} :
|
|
6701
|
+
} : le === "elevenlabs" ? O = {
|
|
6702
6702
|
service: "elevenlabs",
|
|
6703
6703
|
endpoint: "https://api.elevenlabs.io/v1/text-to-speech",
|
|
6704
|
-
apiKey: o ||
|
|
6705
|
-
defaultVoice: s ||
|
|
6706
|
-
voices:
|
|
6707
|
-
} :
|
|
6704
|
+
apiKey: o || ee.apiKey,
|
|
6705
|
+
defaultVoice: s || ee.defaultVoice || Ie.defaultVoice,
|
|
6706
|
+
voices: ee.voices || Ie.voices
|
|
6707
|
+
} : le === "deepgram" ? O = {
|
|
6708
6708
|
service: "deepgram",
|
|
6709
6709
|
endpoint: "https://api.deepgram.com/v1/speak",
|
|
6710
|
-
apiKey: o ||
|
|
6711
|
-
defaultVoice: s ||
|
|
6712
|
-
voices:
|
|
6713
|
-
} :
|
|
6714
|
-
...
|
|
6710
|
+
apiKey: o || ee.apiKey,
|
|
6711
|
+
defaultVoice: s || ee.defaultVoice || Te.defaultVoice,
|
|
6712
|
+
voices: ee.voices || Te.voices
|
|
6713
|
+
} : O = {
|
|
6714
|
+
...ee,
|
|
6715
6715
|
// Override API key if provided via props
|
|
6716
|
-
apiKey: o !== null ? o :
|
|
6716
|
+
apiKey: o !== null ? o : ee.apiKey
|
|
6717
6717
|
};
|
|
6718
|
-
const
|
|
6719
|
-
url:
|
|
6718
|
+
const v = {
|
|
6719
|
+
url: G,
|
|
6720
6720
|
body: t,
|
|
6721
6721
|
avatarMood: e,
|
|
6722
|
-
ttsLang:
|
|
6723
|
-
ttsVoice: s ||
|
|
6722
|
+
ttsLang: le === "browser" ? "en-US" : n,
|
|
6723
|
+
ttsVoice: s || O.defaultVoice,
|
|
6724
6724
|
lipsyncLang: "en",
|
|
6725
6725
|
showFullAvatar: r,
|
|
6726
6726
|
bodyMovement: l,
|
|
6727
|
-
movementIntensity:
|
|
6727
|
+
movementIntensity: h
|
|
6728
6728
|
}, R = {
|
|
6729
|
-
ttsEndpoint:
|
|
6730
|
-
ttsApikey:
|
|
6731
|
-
ttsService:
|
|
6729
|
+
ttsEndpoint: O.endpoint,
|
|
6730
|
+
ttsApikey: O.apiKey,
|
|
6731
|
+
ttsService: le,
|
|
6732
6732
|
lipsyncModules: ["en"],
|
|
6733
|
-
cameraView:
|
|
6734
|
-
},
|
|
6735
|
-
if (!(!
|
|
6733
|
+
cameraView: u
|
|
6734
|
+
}, z = T(async () => {
|
|
6735
|
+
if (!(!V.current || p.current))
|
|
6736
6736
|
try {
|
|
6737
|
-
if (
|
|
6738
|
-
if (
|
|
6739
|
-
const
|
|
6740
|
-
c(
|
|
6737
|
+
if (Z(!0), X(null), p.current = new Be(V.current, R), p.current.controls && (p.current.controls.enableRotate = !1, p.current.controls.enableZoom = !1, p.current.controls.enablePan = !1, p.current.controls.enableDamping = !1), b && Object.keys(b).length > 0 && (p.current.customAnimations = b), await p.current.showAvatar(v, (B) => {
|
|
6738
|
+
if (B.lengthComputable) {
|
|
6739
|
+
const J = Math.min(100, Math.round(B.loaded / B.total * 100));
|
|
6740
|
+
c(J);
|
|
6741
6741
|
}
|
|
6742
|
-
}), await new Promise((
|
|
6743
|
-
const
|
|
6744
|
-
p.current.lipsync && Object.keys(p.current.lipsync).length > 0 ?
|
|
6742
|
+
}), await new Promise((B) => {
|
|
6743
|
+
const J = () => {
|
|
6744
|
+
p.current.lipsync && Object.keys(p.current.lipsync).length > 0 ? B() : setTimeout(J, 100);
|
|
6745
6745
|
};
|
|
6746
|
-
|
|
6746
|
+
J();
|
|
6747
6747
|
}), p.current && p.current.setShowFullAvatar)
|
|
6748
6748
|
try {
|
|
6749
6749
|
p.current.setShowFullAvatar(r);
|
|
6750
|
-
} catch (
|
|
6751
|
-
console.warn("Error setting full body mode on initialization:",
|
|
6750
|
+
} catch (B) {
|
|
6751
|
+
console.warn("Error setting full body mode on initialization:", B);
|
|
6752
6752
|
}
|
|
6753
|
-
p.current && p.current.controls && (p.current.controls.enableRotate = !1, p.current.controls.enableZoom = !1, p.current.controls.enablePan = !1, p.current.controls.enableDamping = !1, p.current.controls.update()),
|
|
6754
|
-
const
|
|
6753
|
+
p.current && p.current.controls && (p.current.controls.enableRotate = !1, p.current.controls.enableZoom = !1, p.current.controls.enablePan = !1, p.current.controls.enableDamping = !1, p.current.controls.update()), Z(!1), se(!0), a(p.current);
|
|
6754
|
+
const F = () => {
|
|
6755
6755
|
document.visibilityState === "visible" ? p.current?.start() : p.current?.stop();
|
|
6756
6756
|
};
|
|
6757
|
-
return document.addEventListener("visibilitychange",
|
|
6758
|
-
document.removeEventListener("visibilitychange",
|
|
6757
|
+
return document.addEventListener("visibilitychange", F), () => {
|
|
6758
|
+
document.removeEventListener("visibilitychange", F);
|
|
6759
6759
|
};
|
|
6760
6760
|
} catch (L) {
|
|
6761
|
-
console.error("Error initializing TalkingHead:", L),
|
|
6761
|
+
console.error("Error initializing TalkingHead:", L), X(L.message || "Failed to initialize avatar"), Z(!1), d(L);
|
|
6762
6762
|
}
|
|
6763
|
-
}, [
|
|
6764
|
-
|
|
6763
|
+
}, [G, t, e, n, i, s, o, r, l, h, u]);
|
|
6764
|
+
de(() => (z(), () => {
|
|
6765
6765
|
p.current && (p.current.stop(), p.current.dispose(), p.current = null);
|
|
6766
|
-
}), [
|
|
6767
|
-
if (!
|
|
6768
|
-
const L = new ResizeObserver((
|
|
6769
|
-
for (const
|
|
6766
|
+
}), [z]), de(() => {
|
|
6767
|
+
if (!V.current || !p.current) return;
|
|
6768
|
+
const L = new ResizeObserver((B) => {
|
|
6769
|
+
for (const J of B)
|
|
6770
6770
|
p.current && p.current.onResize && p.current.onResize();
|
|
6771
6771
|
});
|
|
6772
|
-
L.observe(
|
|
6773
|
-
const
|
|
6772
|
+
L.observe(V.current);
|
|
6773
|
+
const F = () => {
|
|
6774
6774
|
p.current && p.current.onResize && p.current.onResize();
|
|
6775
6775
|
};
|
|
6776
|
-
return window.addEventListener("resize",
|
|
6777
|
-
L.disconnect(), window.removeEventListener("resize",
|
|
6776
|
+
return window.addEventListener("resize", F), () => {
|
|
6777
|
+
L.disconnect(), window.removeEventListener("resize", F);
|
|
6778
6778
|
};
|
|
6779
6779
|
}, [$]);
|
|
6780
|
-
const
|
|
6780
|
+
const H = T(async () => {
|
|
6781
6781
|
if (p.current && p.current.audioCtx)
|
|
6782
6782
|
try {
|
|
6783
6783
|
(p.current.audioCtx.state === "suspended" || p.current.audioCtx.state === "interrupted") && (await p.current.audioCtx.resume(), console.log("Audio context resumed"));
|
|
6784
6784
|
} catch (L) {
|
|
6785
6785
|
console.warn("Failed to resume audio context:", L);
|
|
6786
6786
|
}
|
|
6787
|
-
}, []),
|
|
6787
|
+
}, []), N = T(async (L, F = {}) => {
|
|
6788
6788
|
if (p.current && $)
|
|
6789
6789
|
try {
|
|
6790
|
-
|
|
6791
|
-
const
|
|
6792
|
-
|
|
6793
|
-
const
|
|
6794
|
-
...
|
|
6795
|
-
lipsyncLang:
|
|
6790
|
+
f.current && (clearInterval(f.current), f.current = null), w.current = { text: L, options: F }, P.current = { remainingText: null, originalText: null, options: null };
|
|
6791
|
+
const B = /[!\.\?\n\p{Extended_Pictographic}]/ug, J = L.split(B).map((Y) => Y.trim()).filter((Y) => Y.length > 0);
|
|
6792
|
+
U.current = J, oe.current = 0, pe(!1), E.current = !1, await H();
|
|
6793
|
+
const ge = {
|
|
6794
|
+
...F,
|
|
6795
|
+
lipsyncLang: F.lipsyncLang || v.lipsyncLang || "en"
|
|
6796
6796
|
};
|
|
6797
|
-
if (
|
|
6798
|
-
const
|
|
6799
|
-
let
|
|
6800
|
-
const
|
|
6801
|
-
let
|
|
6802
|
-
|
|
6803
|
-
if (
|
|
6797
|
+
if (F.onSpeechEnd && p.current) {
|
|
6798
|
+
const Y = p.current;
|
|
6799
|
+
let he = null, Se = 0;
|
|
6800
|
+
const Ae = 1200;
|
|
6801
|
+
let be = !1;
|
|
6802
|
+
he = setInterval(() => {
|
|
6803
|
+
if (Se++, E.current)
|
|
6804
6804
|
return;
|
|
6805
|
-
if (
|
|
6806
|
-
if (
|
|
6807
|
-
|
|
6805
|
+
if (Se > Ae) {
|
|
6806
|
+
if (he && (clearInterval(he), he = null, f.current = null), !be && !E.current) {
|
|
6807
|
+
be = !0;
|
|
6808
6808
|
try {
|
|
6809
|
-
|
|
6810
|
-
} catch (
|
|
6811
|
-
console.error("Error in onSpeechEnd callback (timeout):",
|
|
6809
|
+
F.onSpeechEnd();
|
|
6810
|
+
} catch (De) {
|
|
6811
|
+
console.error("Error in onSpeechEnd callback (timeout):", De);
|
|
6812
6812
|
}
|
|
6813
6813
|
}
|
|
6814
6814
|
return;
|
|
6815
6815
|
}
|
|
6816
|
-
const
|
|
6817
|
-
|
|
6818
|
-
if (
|
|
6819
|
-
|
|
6816
|
+
const ye = !Y.speechQueue || Y.speechQueue.length === 0, ke = !Y.audioPlaylist || Y.audioPlaylist.length === 0;
|
|
6817
|
+
Y && Y.isSpeaking === !1 && ye && ke && Y.isAudioPlaying === !1 && !be && !E.current && setTimeout(() => {
|
|
6818
|
+
if (Y && !E.current && Y.isSpeaking === !1 && (!Y.speechQueue || Y.speechQueue.length === 0) && (!Y.audioPlaylist || Y.audioPlaylist.length === 0) && Y.isAudioPlaying === !1 && !be && !E.current) {
|
|
6819
|
+
be = !0, he && (clearInterval(he), he = null, f.current = null);
|
|
6820
6820
|
try {
|
|
6821
|
-
|
|
6821
|
+
F.onSpeechEnd();
|
|
6822
6822
|
} catch (Ze) {
|
|
6823
6823
|
console.error("Error in onSpeechEnd callback:", Ze);
|
|
6824
6824
|
}
|
|
6825
6825
|
}
|
|
6826
6826
|
}, 100);
|
|
6827
|
-
}, 100),
|
|
6827
|
+
}, 100), f.current = he;
|
|
6828
6828
|
}
|
|
6829
|
-
p.current.lipsync && Object.keys(p.current.lipsync).length > 0 ? (p.current.setSlowdownRate && p.current.setSlowdownRate(1.05), p.current.speakText(L,
|
|
6830
|
-
await
|
|
6829
|
+
p.current.lipsync && Object.keys(p.current.lipsync).length > 0 ? (p.current.setSlowdownRate && p.current.setSlowdownRate(1.05), p.current.speakText(L, ge)) : setTimeout(async () => {
|
|
6830
|
+
await H(), p.current && p.current.lipsync && (p.current.setSlowdownRate && p.current.setSlowdownRate(1.05), p.current.speakText(L, ge));
|
|
6831
6831
|
}, 100);
|
|
6832
|
-
} catch (
|
|
6833
|
-
console.error("Error speaking text:",
|
|
6832
|
+
} catch (B) {
|
|
6833
|
+
console.error("Error speaking text:", B), X(B.message || "Failed to speak text");
|
|
6834
6834
|
}
|
|
6835
|
-
}, [$,
|
|
6836
|
-
p.current && (p.current.stopSpeaking(), p.current.setSlowdownRate && p.current.setSlowdownRate(1),
|
|
6837
|
-
}, []),
|
|
6835
|
+
}, [$, H, v.lipsyncLang]), _ = T(() => {
|
|
6836
|
+
p.current && (p.current.stopSpeaking(), p.current.setSlowdownRate && p.current.setSlowdownRate(1), w.current = null, pe(!1));
|
|
6837
|
+
}, []), j = T(() => {
|
|
6838
6838
|
if (p.current && p.current.pauseSpeaking) {
|
|
6839
6839
|
const L = p.current;
|
|
6840
6840
|
if (L.isSpeaking || L.audioPlaylist && L.audioPlaylist.length > 0 || L.speechQueue && L.speechQueue.length > 0) {
|
|
6841
|
-
|
|
6842
|
-
let
|
|
6843
|
-
if (
|
|
6844
|
-
const
|
|
6845
|
-
if (
|
|
6846
|
-
const
|
|
6847
|
-
|
|
6841
|
+
f.current && (clearInterval(f.current), f.current = null);
|
|
6842
|
+
let B = "";
|
|
6843
|
+
if (w.current && U.current.length > 0) {
|
|
6844
|
+
const J = U.current.length, ge = L.speechQueue ? L.speechQueue.filter((Ae) => Ae && Ae.text && Array.isArray(Ae.text) && Ae.text.length > 0).length : 0, Y = L.audioPlaylist && L.audioPlaylist.length > 0, he = ge + (Y ? 1 : 0), Se = J - he;
|
|
6845
|
+
if (he > 0 && Se < J && (B = U.current.slice(Se).join(". ").trim(), !B && ge > 0 && L.speechQueue)) {
|
|
6846
|
+
const be = L.speechQueue.filter((ye) => ye && ye.text && Array.isArray(ye.text) && ye.text.length > 0).map((ye) => ye.text.map((ke) => ke.word || "").filter((ke) => ke.length > 0).join(" ")).filter((ye) => ye.length > 0).join(" ");
|
|
6847
|
+
be && be.trim() && (B = be.trim());
|
|
6848
6848
|
}
|
|
6849
6849
|
}
|
|
6850
|
-
|
|
6851
|
-
remainingText:
|
|
6852
|
-
originalText:
|
|
6853
|
-
options:
|
|
6854
|
-
}), L.speechQueue && (L.speechQueue.length = 0), p.current.pauseSpeaking(),
|
|
6850
|
+
w.current && (P.current = {
|
|
6851
|
+
remainingText: B || null,
|
|
6852
|
+
originalText: w.current.text,
|
|
6853
|
+
options: w.current.options
|
|
6854
|
+
}), L.speechQueue && (L.speechQueue.length = 0), p.current.pauseSpeaking(), E.current = !0, pe(!0);
|
|
6855
6855
|
}
|
|
6856
6856
|
}
|
|
6857
|
-
}, []),
|
|
6858
|
-
if (!p.current || !
|
|
6857
|
+
}, []), q = T(async () => {
|
|
6858
|
+
if (!p.current || !ae)
|
|
6859
6859
|
return;
|
|
6860
|
-
let L = "",
|
|
6861
|
-
if (
|
|
6862
|
-
L =
|
|
6863
|
-
else if (
|
|
6864
|
-
L =
|
|
6860
|
+
let L = "", F = {};
|
|
6861
|
+
if (P.current && P.current.remainingText)
|
|
6862
|
+
L = P.current.remainingText, F = P.current.options || {}, P.current = { remainingText: null, originalText: null, options: null };
|
|
6863
|
+
else if (w.current && w.current.text)
|
|
6864
|
+
L = w.current.text, F = w.current.options || {};
|
|
6865
6865
|
else {
|
|
6866
|
-
console.warn("Resume called but no paused speech found"),
|
|
6866
|
+
console.warn("Resume called but no paused speech found"), pe(!1), E.current = !1;
|
|
6867
6867
|
return;
|
|
6868
6868
|
}
|
|
6869
|
-
|
|
6870
|
-
const
|
|
6871
|
-
...
|
|
6872
|
-
lipsyncLang:
|
|
6869
|
+
pe(!1), E.current = !1, await H();
|
|
6870
|
+
const B = {
|
|
6871
|
+
...F,
|
|
6872
|
+
lipsyncLang: F.lipsyncLang || v.lipsyncLang || "en"
|
|
6873
6873
|
};
|
|
6874
6874
|
try {
|
|
6875
|
-
await
|
|
6876
|
-
} catch (
|
|
6877
|
-
console.error("Error resuming speech:",
|
|
6875
|
+
await N(L, B);
|
|
6876
|
+
} catch (J) {
|
|
6877
|
+
console.error("Error resuming speech:", J), pe(!1), E.current = !1;
|
|
6878
6878
|
}
|
|
6879
|
-
}, [
|
|
6879
|
+
}, [H, ae, N, v]), Le = T((L) => {
|
|
6880
6880
|
p.current && p.current.setMood(L);
|
|
6881
|
-
}, []),
|
|
6881
|
+
}, []), we = T((L) => {
|
|
6882
6882
|
p.current && p.current.setSlowdownRate && p.current.setSlowdownRate(L);
|
|
6883
|
-
}, []),
|
|
6883
|
+
}, []), C = T((L, F = !1) => {
|
|
6884
6884
|
if (p.current && p.current.playAnimation) {
|
|
6885
|
-
if (
|
|
6885
|
+
if (b && b[L] && (L = b[L]), p.current.setShowFullAvatar)
|
|
6886
6886
|
try {
|
|
6887
|
-
p.current.setShowFullAvatar(
|
|
6888
|
-
} catch (
|
|
6889
|
-
console.warn("Error setting full body mode:",
|
|
6887
|
+
p.current.setShowFullAvatar(M.current);
|
|
6888
|
+
} catch (J) {
|
|
6889
|
+
console.warn("Error setting full body mode:", J);
|
|
6890
6890
|
}
|
|
6891
6891
|
if (L.includes("."))
|
|
6892
6892
|
try {
|
|
6893
|
-
p.current.playAnimation(L, null, 10, 0, 0.01,
|
|
6894
|
-
} catch (
|
|
6895
|
-
console.warn(`Failed to play ${L}:`,
|
|
6893
|
+
p.current.playAnimation(L, null, 10, 0, 0.01, F);
|
|
6894
|
+
} catch (J) {
|
|
6895
|
+
console.warn(`Failed to play ${L}:`, J);
|
|
6896
6896
|
try {
|
|
6897
6897
|
p.current.setBodyMovement("idle");
|
|
6898
|
-
} catch (
|
|
6899
|
-
console.warn("Fallback animation also failed:",
|
|
6898
|
+
} catch (ge) {
|
|
6899
|
+
console.warn("Fallback animation also failed:", ge);
|
|
6900
6900
|
}
|
|
6901
6901
|
}
|
|
6902
6902
|
else {
|
|
6903
|
-
const
|
|
6904
|
-
let
|
|
6905
|
-
for (const
|
|
6903
|
+
const J = [".fbx", ".glb", ".gltf"];
|
|
6904
|
+
let ge = !1;
|
|
6905
|
+
for (const Y of J)
|
|
6906
6906
|
try {
|
|
6907
|
-
p.current.playAnimation(L +
|
|
6907
|
+
p.current.playAnimation(L + Y, null, 10, 0, 0.01, F), ge = !0;
|
|
6908
6908
|
break;
|
|
6909
6909
|
} catch {
|
|
6910
6910
|
}
|
|
6911
|
-
if (!
|
|
6911
|
+
if (!ge) {
|
|
6912
6912
|
console.warn("Animation not found:", L);
|
|
6913
6913
|
try {
|
|
6914
6914
|
p.current.setBodyMovement("idle");
|
|
6915
|
-
} catch (
|
|
6916
|
-
console.warn("Fallback animation also failed:",
|
|
6915
|
+
} catch (Y) {
|
|
6916
|
+
console.warn("Fallback animation also failed:", Y);
|
|
6917
6917
|
}
|
|
6918
6918
|
}
|
|
6919
6919
|
}
|
|
6920
6920
|
}
|
|
6921
|
-
}, [
|
|
6921
|
+
}, [b]), te = T(() => {
|
|
6922
6922
|
p.current && p.current.onResize && p.current.onResize();
|
|
6923
6923
|
}, []);
|
|
6924
|
-
return
|
|
6925
|
-
speakText:
|
|
6926
|
-
stopSpeaking:
|
|
6927
|
-
pauseSpeaking:
|
|
6928
|
-
resumeSpeaking:
|
|
6929
|
-
resumeAudioContext:
|
|
6930
|
-
setMood:
|
|
6931
|
-
setTimingAdjustment:
|
|
6932
|
-
playAnimation:
|
|
6924
|
+
return Ee(I, () => ({
|
|
6925
|
+
speakText: N,
|
|
6926
|
+
stopSpeaking: _,
|
|
6927
|
+
pauseSpeaking: j,
|
|
6928
|
+
resumeSpeaking: q,
|
|
6929
|
+
resumeAudioContext: H,
|
|
6930
|
+
setMood: Le,
|
|
6931
|
+
setTimingAdjustment: we,
|
|
6932
|
+
playAnimation: C,
|
|
6933
6933
|
isReady: $,
|
|
6934
|
-
isPaused:
|
|
6934
|
+
isPaused: ae,
|
|
6935
6935
|
talkingHead: p.current,
|
|
6936
|
-
handleResize:
|
|
6936
|
+
handleResize: te,
|
|
6937
6937
|
setBodyMovement: (L) => {
|
|
6938
6938
|
if (p.current && p.current.setShowFullAvatar && p.current.setBodyMovement)
|
|
6939
6939
|
try {
|
|
6940
|
-
p.current.setShowFullAvatar(
|
|
6941
|
-
} catch (
|
|
6942
|
-
console.warn("Error setting body movement:",
|
|
6940
|
+
p.current.setShowFullAvatar(M.current), p.current.setBodyMovement(L);
|
|
6941
|
+
} catch (F) {
|
|
6942
|
+
console.warn("Error setting body movement:", F);
|
|
6943
6943
|
}
|
|
6944
6944
|
},
|
|
6945
6945
|
setMovementIntensity: (L) => p.current?.setMovementIntensity(L),
|
|
6946
6946
|
playRandomDance: () => {
|
|
6947
6947
|
if (p.current && p.current.setShowFullAvatar && p.current.playRandomDance)
|
|
6948
6948
|
try {
|
|
6949
|
-
p.current.setShowFullAvatar(
|
|
6949
|
+
p.current.setShowFullAvatar(M.current), p.current.playRandomDance();
|
|
6950
6950
|
} catch (L) {
|
|
6951
6951
|
console.warn("Error playing random dance:", L);
|
|
6952
6952
|
}
|
|
@@ -6954,15 +6954,15 @@ const Ue = ze(({
|
|
|
6954
6954
|
playReaction: (L) => {
|
|
6955
6955
|
if (p.current && p.current.setShowFullAvatar && p.current.playReaction)
|
|
6956
6956
|
try {
|
|
6957
|
-
p.current.setShowFullAvatar(
|
|
6958
|
-
} catch (
|
|
6959
|
-
console.warn("Error playing reaction:",
|
|
6957
|
+
p.current.setShowFullAvatar(M.current), p.current.playReaction(L);
|
|
6958
|
+
} catch (F) {
|
|
6959
|
+
console.warn("Error playing reaction:", F);
|
|
6960
6960
|
}
|
|
6961
6961
|
},
|
|
6962
6962
|
playCelebration: () => {
|
|
6963
6963
|
if (p.current && p.current.setShowFullAvatar && p.current.playCelebration)
|
|
6964
6964
|
try {
|
|
6965
|
-
p.current.setShowFullAvatar(
|
|
6965
|
+
p.current.setShowFullAvatar(M.current), p.current.playCelebration();
|
|
6966
6966
|
} catch (L) {
|
|
6967
6967
|
console.warn("Error playing celebration:", L);
|
|
6968
6968
|
}
|
|
@@ -6970,9 +6970,9 @@ const Ue = ze(({
|
|
|
6970
6970
|
setShowFullAvatar: (L) => {
|
|
6971
6971
|
if (p.current && p.current.setShowFullAvatar)
|
|
6972
6972
|
try {
|
|
6973
|
-
|
|
6974
|
-
} catch (
|
|
6975
|
-
console.warn("Error setting showFullAvatar:",
|
|
6973
|
+
M.current = L, p.current.setShowFullAvatar(L);
|
|
6974
|
+
} catch (F) {
|
|
6975
|
+
console.warn("Error setting showFullAvatar:", F);
|
|
6976
6976
|
}
|
|
6977
6977
|
},
|
|
6978
6978
|
lockAvatarPosition: () => {
|
|
@@ -6991,7 +6991,7 @@ const Ue = ze(({
|
|
|
6991
6991
|
console.warn("Error unlocking avatar position:", L);
|
|
6992
6992
|
}
|
|
6993
6993
|
}
|
|
6994
|
-
})), /* @__PURE__ */
|
|
6994
|
+
})), /* @__PURE__ */ Pe(
|
|
6995
6995
|
"div",
|
|
6996
6996
|
{
|
|
6997
6997
|
className: `talking-head-avatar ${g}`,
|
|
@@ -7002,10 +7002,10 @@ const Ue = ze(({
|
|
|
7002
7002
|
...y
|
|
7003
7003
|
},
|
|
7004
7004
|
children: [
|
|
7005
|
-
/* @__PURE__ */
|
|
7005
|
+
/* @__PURE__ */ me(
|
|
7006
7006
|
"div",
|
|
7007
7007
|
{
|
|
7008
|
-
ref:
|
|
7008
|
+
ref: V,
|
|
7009
7009
|
className: "talking-head-viewer",
|
|
7010
7010
|
style: {
|
|
7011
7011
|
width: "100%",
|
|
@@ -7014,7 +7014,7 @@ const Ue = ze(({
|
|
|
7014
7014
|
}
|
|
7015
7015
|
}
|
|
7016
7016
|
),
|
|
7017
|
-
S && /* @__PURE__ */
|
|
7017
|
+
S && /* @__PURE__ */ me("div", { className: "loading-overlay", style: {
|
|
7018
7018
|
position: "absolute",
|
|
7019
7019
|
top: "50%",
|
|
7020
7020
|
left: "50%",
|
|
@@ -7023,7 +7023,7 @@ const Ue = ze(({
|
|
|
7023
7023
|
fontSize: "18px",
|
|
7024
7024
|
zIndex: 10
|
|
7025
7025
|
}, children: "Loading avatar..." }),
|
|
7026
|
-
|
|
7026
|
+
K && /* @__PURE__ */ me("div", { className: "error-overlay", style: {
|
|
7027
7027
|
position: "absolute",
|
|
7028
7028
|
top: "50%",
|
|
7029
7029
|
left: "50%",
|
|
@@ -7034,14 +7034,14 @@ const Ue = ze(({
|
|
|
7034
7034
|
zIndex: 10,
|
|
7035
7035
|
padding: "20px",
|
|
7036
7036
|
borderRadius: "8px"
|
|
7037
|
-
}, children:
|
|
7037
|
+
}, children: K })
|
|
7038
7038
|
]
|
|
7039
7039
|
}
|
|
7040
7040
|
);
|
|
7041
7041
|
});
|
|
7042
|
-
|
|
7043
|
-
const pt =
|
|
7044
|
-
text:
|
|
7042
|
+
Ve.displayName = "TalkingHeadAvatar";
|
|
7043
|
+
const pt = Me(({
|
|
7044
|
+
text: G = "Hello! I'm a talking avatar. How are you today?",
|
|
7045
7045
|
onLoading: t = () => {
|
|
7046
7046
|
},
|
|
7047
7047
|
onError: e = () => {
|
|
@@ -7052,23 +7052,23 @@ const pt = ze(({
|
|
|
7052
7052
|
style: s = {},
|
|
7053
7053
|
avatarConfig: o = {}
|
|
7054
7054
|
}, l) => {
|
|
7055
|
-
const
|
|
7055
|
+
const h = D(null), r = D(null), [u, a] = ce(!0), [c, d] = ce(null), [g, y] = ce(!1), b = Fe(), I = o.ttsService || b.service, V = I === "browser" ? {
|
|
7056
7056
|
endpoint: "",
|
|
7057
7057
|
apiKey: null,
|
|
7058
7058
|
defaultVoice: "Google US English"
|
|
7059
7059
|
} : {
|
|
7060
|
-
...
|
|
7060
|
+
...b,
|
|
7061
7061
|
// Override API key if provided via avatarConfig
|
|
7062
|
-
apiKey: o.ttsApiKey !== void 0 && o.ttsApiKey !== null ? o.ttsApiKey :
|
|
7062
|
+
apiKey: o.ttsApiKey !== void 0 && o.ttsApiKey !== null ? o.ttsApiKey : b.apiKey,
|
|
7063
7063
|
// Override endpoint for ElevenLabs if service is explicitly set
|
|
7064
|
-
endpoint:
|
|
7064
|
+
endpoint: I === "elevenlabs" && o.ttsApiKey ? "https://api.elevenlabs.io/v1/text-to-speech" : b.endpoint
|
|
7065
7065
|
}, p = {
|
|
7066
7066
|
url: "/avatars/brunette.glb",
|
|
7067
7067
|
// Use brunette avatar (working glTF file)
|
|
7068
7068
|
body: "F",
|
|
7069
7069
|
avatarMood: "neutral",
|
|
7070
|
-
ttsLang:
|
|
7071
|
-
ttsVoice: o.ttsVoice ||
|
|
7070
|
+
ttsLang: I === "browser" ? "en-US" : "en",
|
|
7071
|
+
ttsVoice: o.ttsVoice || V.defaultVoice,
|
|
7072
7072
|
lipsyncLang: "en",
|
|
7073
7073
|
// English lip-sync
|
|
7074
7074
|
showFullAvatar: !0,
|
|
@@ -7076,81 +7076,81 @@ const pt = ze(({
|
|
|
7076
7076
|
bodyMovement: "idle",
|
|
7077
7077
|
movementIntensity: 0.5,
|
|
7078
7078
|
...o
|
|
7079
|
-
},
|
|
7080
|
-
ttsEndpoint:
|
|
7081
|
-
ttsApikey:
|
|
7082
|
-
ttsService:
|
|
7079
|
+
}, M = {
|
|
7080
|
+
ttsEndpoint: V.endpoint,
|
|
7081
|
+
ttsApikey: V.apiKey,
|
|
7082
|
+
ttsService: I,
|
|
7083
7083
|
lipsyncModules: ["en"],
|
|
7084
7084
|
cameraView: "upper"
|
|
7085
|
-
},
|
|
7086
|
-
if (!(!
|
|
7085
|
+
}, w = T(async () => {
|
|
7086
|
+
if (!(!h.current || r.current))
|
|
7087
7087
|
try {
|
|
7088
|
-
if (a(!0), d(null), r.current = new
|
|
7089
|
-
if (
|
|
7090
|
-
const
|
|
7091
|
-
t(
|
|
7088
|
+
if (a(!0), d(null), r.current = new Be(h.current, M), await r.current.showAvatar(p, (K) => {
|
|
7089
|
+
if (K.lengthComputable) {
|
|
7090
|
+
const X = Math.min(100, Math.round(K.loaded / K.total * 100));
|
|
7091
|
+
t(X);
|
|
7092
7092
|
}
|
|
7093
7093
|
}), r.current.morphs && r.current.morphs.length > 0) {
|
|
7094
|
-
const
|
|
7095
|
-
console.log("Available morph targets:", Object.keys(
|
|
7096
|
-
const
|
|
7097
|
-
console.log("Viseme morph targets found:",
|
|
7094
|
+
const K = r.current.morphs[0].morphTargetDictionary;
|
|
7095
|
+
console.log("Available morph targets:", Object.keys(K));
|
|
7096
|
+
const X = Object.keys(K).filter(($) => $.startsWith("viseme_"));
|
|
7097
|
+
console.log("Viseme morph targets found:", X), X.length === 0 && (console.warn("No viseme morph targets found! Lip-sync will not work properly."), console.log("Expected viseme targets: viseme_aa, viseme_E, viseme_I, viseme_O, viseme_U, viseme_PP, viseme_SS, viseme_TH, viseme_DD, viseme_FF, viseme_kk, viseme_nn, viseme_RR, viseme_CH, viseme_sil"));
|
|
7098
7098
|
}
|
|
7099
|
-
if (await new Promise((
|
|
7100
|
-
const
|
|
7101
|
-
r.current.lipsync && Object.keys(r.current.lipsync).length > 0 ? (console.log("Lip-sync modules loaded:", Object.keys(r.current.lipsync)),
|
|
7099
|
+
if (await new Promise((K) => {
|
|
7100
|
+
const X = () => {
|
|
7101
|
+
r.current.lipsync && Object.keys(r.current.lipsync).length > 0 ? (console.log("Lip-sync modules loaded:", Object.keys(r.current.lipsync)), K()) : (console.log("Waiting for lip-sync modules to load..."), setTimeout(X, 100));
|
|
7102
7102
|
};
|
|
7103
|
-
|
|
7103
|
+
X();
|
|
7104
7104
|
}), r.current && r.current.setShowFullAvatar)
|
|
7105
7105
|
try {
|
|
7106
7106
|
r.current.setShowFullAvatar(!0), console.log("Avatar initialized in full body mode");
|
|
7107
|
-
} catch (
|
|
7108
|
-
console.warn("Error setting full body mode on initialization:",
|
|
7107
|
+
} catch (K) {
|
|
7108
|
+
console.warn("Error setting full body mode on initialization:", K);
|
|
7109
7109
|
}
|
|
7110
7110
|
a(!1), y(!0), n(r.current);
|
|
7111
|
-
const
|
|
7111
|
+
const Z = () => {
|
|
7112
7112
|
document.visibilityState === "visible" ? r.current?.start() : r.current?.stop();
|
|
7113
7113
|
};
|
|
7114
|
-
return document.addEventListener("visibilitychange",
|
|
7115
|
-
document.removeEventListener("visibilitychange",
|
|
7114
|
+
return document.addEventListener("visibilitychange", Z), () => {
|
|
7115
|
+
document.removeEventListener("visibilitychange", Z);
|
|
7116
7116
|
};
|
|
7117
7117
|
} catch (S) {
|
|
7118
7118
|
console.error("Error initializing TalkingHead:", S), d(S.message || "Failed to initialize avatar"), a(!1), e(S);
|
|
7119
7119
|
}
|
|
7120
7120
|
}, []);
|
|
7121
|
-
|
|
7121
|
+
de(() => (w(), () => {
|
|
7122
7122
|
r.current && (r.current.stop(), r.current.dispose(), r.current = null);
|
|
7123
|
-
}), [
|
|
7124
|
-
const
|
|
7123
|
+
}), [w]);
|
|
7124
|
+
const f = T((S) => {
|
|
7125
7125
|
if (r.current && g)
|
|
7126
7126
|
try {
|
|
7127
7127
|
console.log("Speaking text:", S), console.log("Avatar config:", p), console.log("TalkingHead instance:", r.current), r.current.lipsync && Object.keys(r.current.lipsync).length > 0 ? (console.log("Lip-sync modules loaded:", Object.keys(r.current.lipsync)), r.current.setSlowdownRate && (r.current.setSlowdownRate(1.05), console.log("Applied timing adjustment for better lip-sync")), r.current.speakText(S)) : (console.warn("Lip-sync modules not ready, waiting..."), setTimeout(() => {
|
|
7128
7128
|
r.current && r.current.lipsync ? (console.log("Lip-sync now ready, speaking..."), r.current.setSlowdownRate && (r.current.setSlowdownRate(1.05), console.log("Applied timing adjustment for better lip-sync")), r.current.speakText(S)) : console.error("Lip-sync still not ready after waiting");
|
|
7129
7129
|
}, 500));
|
|
7130
|
-
} catch (
|
|
7131
|
-
console.error("Error speaking text:",
|
|
7130
|
+
} catch (Z) {
|
|
7131
|
+
console.error("Error speaking text:", Z), d(Z.message || "Failed to speak text");
|
|
7132
7132
|
}
|
|
7133
7133
|
else
|
|
7134
7134
|
console.warn("Avatar not ready for speaking. isReady:", g, "talkingHeadRef:", !!r.current);
|
|
7135
|
-
}, [g, p]),
|
|
7135
|
+
}, [g, p]), E = T(() => {
|
|
7136
7136
|
r.current && (r.current.stopSpeaking(), r.current.setSlowdownRate && (r.current.setSlowdownRate(1), console.log("Reset timing to normal")));
|
|
7137
|
-
}, []),
|
|
7137
|
+
}, []), P = T((S) => {
|
|
7138
7138
|
r.current && r.current.setMood(S);
|
|
7139
|
-
}, []),
|
|
7139
|
+
}, []), U = T((S) => {
|
|
7140
7140
|
r.current && r.current.setSlowdownRate && (r.current.setSlowdownRate(S), console.log("Timing adjustment set to:", S));
|
|
7141
|
-
}, []),
|
|
7141
|
+
}, []), oe = T((S, Z = !1) => {
|
|
7142
7142
|
if (r.current && r.current.playAnimation) {
|
|
7143
7143
|
if (r.current.setShowFullAvatar)
|
|
7144
7144
|
try {
|
|
7145
7145
|
r.current.setShowFullAvatar(!0);
|
|
7146
|
-
} catch (
|
|
7147
|
-
console.warn("Error setting full body mode:",
|
|
7146
|
+
} catch (X) {
|
|
7147
|
+
console.warn("Error setting full body mode:", X);
|
|
7148
7148
|
}
|
|
7149
7149
|
if (S.includes("."))
|
|
7150
7150
|
try {
|
|
7151
|
-
r.current.playAnimation(S, null, 10, 0, 0.01,
|
|
7152
|
-
} catch (
|
|
7153
|
-
console.log(`Failed to play ${S}:`,
|
|
7151
|
+
r.current.playAnimation(S, null, 10, 0, 0.01, Z), console.log("Playing animation:", S);
|
|
7152
|
+
} catch (X) {
|
|
7153
|
+
console.log(`Failed to play ${S}:`, X);
|
|
7154
7154
|
try {
|
|
7155
7155
|
r.current.setBodyMovement("idle"), console.log("Fallback to idle animation");
|
|
7156
7156
|
} catch ($) {
|
|
@@ -7158,11 +7158,11 @@ const pt = ze(({
|
|
|
7158
7158
|
}
|
|
7159
7159
|
}
|
|
7160
7160
|
else {
|
|
7161
|
-
const
|
|
7161
|
+
const X = [".fbx", ".glb", ".gltf"];
|
|
7162
7162
|
let $ = !1;
|
|
7163
|
-
for (const se of
|
|
7163
|
+
for (const se of X)
|
|
7164
7164
|
try {
|
|
7165
|
-
r.current.playAnimation(S + se, null, 10, 0, 0.01,
|
|
7165
|
+
r.current.playAnimation(S + se, null, 10, 0, 0.01, Z), console.log("Playing animation:", S + se), $ = !0;
|
|
7166
7166
|
break;
|
|
7167
7167
|
} catch {
|
|
7168
7168
|
console.log(`Failed to play ${S}${se}, trying next format...`);
|
|
@@ -7179,20 +7179,20 @@ const pt = ze(({
|
|
|
7179
7179
|
} else
|
|
7180
7180
|
console.warn("Animation system not available or animation not found:", S);
|
|
7181
7181
|
}, []);
|
|
7182
|
-
return
|
|
7183
|
-
speakText:
|
|
7184
|
-
stopSpeaking:
|
|
7185
|
-
setMood:
|
|
7186
|
-
setTimingAdjustment:
|
|
7187
|
-
playAnimation:
|
|
7182
|
+
return Ee(l, () => ({
|
|
7183
|
+
speakText: f,
|
|
7184
|
+
stopSpeaking: E,
|
|
7185
|
+
setMood: P,
|
|
7186
|
+
setTimingAdjustment: U,
|
|
7187
|
+
playAnimation: oe,
|
|
7188
7188
|
isReady: g,
|
|
7189
7189
|
talkingHead: r.current,
|
|
7190
7190
|
setBodyMovement: (S) => {
|
|
7191
7191
|
if (r.current && r.current.setShowFullAvatar && r.current.setBodyMovement)
|
|
7192
7192
|
try {
|
|
7193
7193
|
r.current.setShowFullAvatar(!0), r.current.setBodyMovement(S), console.log("Body movement set with full body mode:", S);
|
|
7194
|
-
} catch (
|
|
7195
|
-
console.warn("Error setting body movement:",
|
|
7194
|
+
} catch (Z) {
|
|
7195
|
+
console.warn("Error setting body movement:", Z);
|
|
7196
7196
|
}
|
|
7197
7197
|
},
|
|
7198
7198
|
setMovementIntensity: (S) => r.current?.setMovementIntensity(S),
|
|
@@ -7208,8 +7208,8 @@ const pt = ze(({
|
|
|
7208
7208
|
if (r.current && r.current.setShowFullAvatar && r.current.playReaction)
|
|
7209
7209
|
try {
|
|
7210
7210
|
r.current.setShowFullAvatar(!0), r.current.playReaction(S), console.log("Reaction played with full body mode:", S);
|
|
7211
|
-
} catch (
|
|
7212
|
-
console.warn("Error playing reaction:",
|
|
7211
|
+
} catch (Z) {
|
|
7212
|
+
console.warn("Error playing reaction:", Z);
|
|
7213
7213
|
}
|
|
7214
7214
|
},
|
|
7215
7215
|
playCelebration: () => {
|
|
@@ -7224,8 +7224,8 @@ const pt = ze(({
|
|
|
7224
7224
|
if (r.current && r.current.setShowFullAvatar)
|
|
7225
7225
|
try {
|
|
7226
7226
|
r.current.setShowFullAvatar(S), console.log("Show full avatar set to:", S);
|
|
7227
|
-
} catch (
|
|
7228
|
-
console.warn("Error setting showFullAvatar:",
|
|
7227
|
+
} catch (Z) {
|
|
7228
|
+
console.warn("Error setting showFullAvatar:", Z);
|
|
7229
7229
|
}
|
|
7230
7230
|
},
|
|
7231
7231
|
lockAvatarPosition: () => {
|
|
@@ -7244,11 +7244,11 @@ const pt = ze(({
|
|
|
7244
7244
|
console.warn("Error unlocking avatar position:", S);
|
|
7245
7245
|
}
|
|
7246
7246
|
}
|
|
7247
|
-
})), /* @__PURE__ */
|
|
7248
|
-
/* @__PURE__ */
|
|
7247
|
+
})), /* @__PURE__ */ Pe("div", { className: `talking-head-container ${i}`, style: s, children: [
|
|
7248
|
+
/* @__PURE__ */ me(
|
|
7249
7249
|
"div",
|
|
7250
7250
|
{
|
|
7251
|
-
ref:
|
|
7251
|
+
ref: h,
|
|
7252
7252
|
className: "talking-head-viewer",
|
|
7253
7253
|
style: {
|
|
7254
7254
|
width: "100%",
|
|
@@ -7257,7 +7257,7 @@ const pt = ze(({
|
|
|
7257
7257
|
}
|
|
7258
7258
|
}
|
|
7259
7259
|
),
|
|
7260
|
-
|
|
7260
|
+
u && /* @__PURE__ */ me("div", { className: "loading-overlay", style: {
|
|
7261
7261
|
position: "absolute",
|
|
7262
7262
|
top: "50%",
|
|
7263
7263
|
left: "50%",
|
|
@@ -7266,7 +7266,7 @@ const pt = ze(({
|
|
|
7266
7266
|
fontSize: "18px",
|
|
7267
7267
|
zIndex: 10
|
|
7268
7268
|
}, children: "Loading avatar..." }),
|
|
7269
|
-
c && /* @__PURE__ */
|
|
7269
|
+
c && /* @__PURE__ */ me("div", { className: "error-overlay", style: {
|
|
7270
7270
|
position: "absolute",
|
|
7271
7271
|
top: "50%",
|
|
7272
7272
|
left: "50%",
|
|
@@ -7281,8 +7281,222 @@ const pt = ze(({
|
|
|
7281
7281
|
] });
|
|
7282
7282
|
});
|
|
7283
7283
|
pt.displayName = "TalkingHeadComponent";
|
|
7284
|
-
const gt =
|
|
7285
|
-
|
|
7284
|
+
const gt = Me(({
|
|
7285
|
+
text: G = null,
|
|
7286
|
+
avatarUrl: t = "/avatars/brunette.glb",
|
|
7287
|
+
avatarBody: e = "F",
|
|
7288
|
+
mood: n = "neutral",
|
|
7289
|
+
ttsLang: i = "en",
|
|
7290
|
+
ttsService: s = null,
|
|
7291
|
+
ttsVoice: o = null,
|
|
7292
|
+
ttsApiKey: l = null,
|
|
7293
|
+
bodyMovement: h = "idle",
|
|
7294
|
+
movementIntensity: r = 0.5,
|
|
7295
|
+
showFullAvatar: u = !1,
|
|
7296
|
+
cameraView: a = "upper",
|
|
7297
|
+
onReady: c = () => {
|
|
7298
|
+
},
|
|
7299
|
+
onLoading: d = () => {
|
|
7300
|
+
},
|
|
7301
|
+
onError: g = () => {
|
|
7302
|
+
},
|
|
7303
|
+
onSpeechEnd: y = () => {
|
|
7304
|
+
},
|
|
7305
|
+
className: b = "",
|
|
7306
|
+
style: I = {},
|
|
7307
|
+
animations: V = {},
|
|
7308
|
+
autoSpeak: p = !1
|
|
7309
|
+
}, M) => {
|
|
7310
|
+
const w = D(null), f = D(null), E = D(u), P = D(null), U = D(null), oe = D(!1), S = D({ remainingText: null, originalText: null, options: null }), Z = D([]), [K, X] = ce(!0), [$, se] = ce(null), [ae, pe] = ce(!1), [ee, le] = ce(!1);
|
|
7311
|
+
de(() => {
|
|
7312
|
+
oe.current = ee;
|
|
7313
|
+
}, [ee]), de(() => {
|
|
7314
|
+
E.current = u;
|
|
7315
|
+
}, [u]);
|
|
7316
|
+
const O = Fe(), v = s || O.service;
|
|
7317
|
+
let R;
|
|
7318
|
+
v === "browser" ? R = {
|
|
7319
|
+
service: "browser",
|
|
7320
|
+
endpoint: "",
|
|
7321
|
+
apiKey: null,
|
|
7322
|
+
defaultVoice: "Google US English"
|
|
7323
|
+
} : v === "elevenlabs" ? R = {
|
|
7324
|
+
service: "elevenlabs",
|
|
7325
|
+
endpoint: "https://api.elevenlabs.io/v1/text-to-speech",
|
|
7326
|
+
apiKey: l || O.apiKey,
|
|
7327
|
+
defaultVoice: o || O.defaultVoice || Ie.defaultVoice,
|
|
7328
|
+
voices: O.voices || Ie.voices
|
|
7329
|
+
} : v === "deepgram" ? R = {
|
|
7330
|
+
service: "deepgram",
|
|
7331
|
+
endpoint: "https://api.deepgram.com/v1/speak",
|
|
7332
|
+
apiKey: l || O.apiKey,
|
|
7333
|
+
defaultVoice: o || O.defaultVoice || Te.defaultVoice,
|
|
7334
|
+
voices: O.voices || Te.voices
|
|
7335
|
+
} : R = {
|
|
7336
|
+
...O,
|
|
7337
|
+
apiKey: l !== null ? l : O.apiKey
|
|
7338
|
+
};
|
|
7339
|
+
const z = {
|
|
7340
|
+
url: t,
|
|
7341
|
+
body: e,
|
|
7342
|
+
avatarMood: n,
|
|
7343
|
+
ttsLang: v === "browser" ? "en-US" : i,
|
|
7344
|
+
ttsVoice: o || R.defaultVoice,
|
|
7345
|
+
lipsyncLang: "en",
|
|
7346
|
+
showFullAvatar: u,
|
|
7347
|
+
bodyMovement: h,
|
|
7348
|
+
movementIntensity: r
|
|
7349
|
+
}, H = {
|
|
7350
|
+
ttsEndpoint: R.endpoint,
|
|
7351
|
+
ttsApikey: R.apiKey,
|
|
7352
|
+
ttsService: v,
|
|
7353
|
+
lipsyncModules: ["en"],
|
|
7354
|
+
cameraView: a
|
|
7355
|
+
}, N = T(async () => {
|
|
7356
|
+
if (!(!w.current || f.current))
|
|
7357
|
+
try {
|
|
7358
|
+
X(!0), se(null), f.current = new Be(w.current, H), await f.current.showAvatar(z, (te) => {
|
|
7359
|
+
if (te.lengthComputable) {
|
|
7360
|
+
const L = Math.min(100, Math.round(te.loaded / te.total * 100));
|
|
7361
|
+
d(L);
|
|
7362
|
+
}
|
|
7363
|
+
}), X(!1), pe(!0), c(f.current);
|
|
7364
|
+
const C = () => {
|
|
7365
|
+
document.visibilityState === "visible" ? f.current?.start() : f.current?.stop();
|
|
7366
|
+
};
|
|
7367
|
+
return document.addEventListener("visibilitychange", C), () => {
|
|
7368
|
+
document.removeEventListener("visibilitychange", C);
|
|
7369
|
+
};
|
|
7370
|
+
} catch (C) {
|
|
7371
|
+
console.error("Error initializing TalkingHead:", C), se(C.message || "Failed to initialize avatar"), X(!1), g(C);
|
|
7372
|
+
}
|
|
7373
|
+
}, []);
|
|
7374
|
+
de(() => (N(), () => {
|
|
7375
|
+
f.current && (f.current.stop(), f.current.dispose(), f.current = null);
|
|
7376
|
+
}), [N]);
|
|
7377
|
+
const _ = T(async () => {
|
|
7378
|
+
if (f.current)
|
|
7379
|
+
try {
|
|
7380
|
+
const C = f.current.audioCtx || f.current.audioContext;
|
|
7381
|
+
C && (C.state === "suspended" || C.state === "interrupted") && (await C.resume(), console.log("Audio context resumed"));
|
|
7382
|
+
} catch (C) {
|
|
7383
|
+
console.warn("Failed to resume audio context:", C);
|
|
7384
|
+
}
|
|
7385
|
+
}, []);
|
|
7386
|
+
de(() => {
|
|
7387
|
+
ae && G && p && f.current && j(G);
|
|
7388
|
+
}, [ae, G, p, j]);
|
|
7389
|
+
const j = T(async (C, te = {}) => {
|
|
7390
|
+
if (!f.current || !ae) {
|
|
7391
|
+
console.warn("Avatar not ready for speaking");
|
|
7392
|
+
return;
|
|
7393
|
+
}
|
|
7394
|
+
if (!C || C.trim() === "") {
|
|
7395
|
+
console.warn("No text provided to speak");
|
|
7396
|
+
return;
|
|
7397
|
+
}
|
|
7398
|
+
await _(), S.current = { remainingText: null, originalText: null, options: null }, Z.current = [], P.current = { text: C, options: te }, U.current && (clearInterval(U.current), U.current = null), le(!1), oe.current = !1;
|
|
7399
|
+
const L = C.split(/[.!?]+/).filter((B) => B.trim().length > 0);
|
|
7400
|
+
Z.current = L;
|
|
7401
|
+
const F = {
|
|
7402
|
+
lipsyncLang: te.lipsyncLang || "en",
|
|
7403
|
+
onSpeechEnd: () => {
|
|
7404
|
+
U.current && (clearInterval(U.current), U.current = null), te.onSpeechEnd && te.onSpeechEnd(), y();
|
|
7405
|
+
}
|
|
7406
|
+
};
|
|
7407
|
+
try {
|
|
7408
|
+
f.current.speakText(C, F);
|
|
7409
|
+
} catch (B) {
|
|
7410
|
+
console.error("Error speaking text:", B), se(B.message || "Failed to speak text");
|
|
7411
|
+
}
|
|
7412
|
+
}, [ae, y, _]), q = T(() => {
|
|
7413
|
+
if (f.current)
|
|
7414
|
+
try {
|
|
7415
|
+
const C = f.current.isSpeaking || !1, te = f.current.audioPlaylist || [], L = f.current.speechQueue || [];
|
|
7416
|
+
if (C || te.length > 0 || L.length > 0) {
|
|
7417
|
+
U.current && (clearInterval(U.current), U.current = null);
|
|
7418
|
+
let F = "";
|
|
7419
|
+
L.length > 0 && (F = L.map((B) => B.text && Array.isArray(B.text) ? B.text.map((J) => J.word).join(" ") : B.text || "").join(" ")), S.current = {
|
|
7420
|
+
remainingText: F || null,
|
|
7421
|
+
originalText: P.current?.text || null,
|
|
7422
|
+
options: P.current?.options || null
|
|
7423
|
+
}, f.current.speechQueue.length = 0, f.current.pauseSpeaking(), le(!0), oe.current = !0;
|
|
7424
|
+
}
|
|
7425
|
+
} catch (C) {
|
|
7426
|
+
console.warn("Error pausing speech:", C);
|
|
7427
|
+
}
|
|
7428
|
+
}, []), Le = T(async () => {
|
|
7429
|
+
if (!(!f.current || !ee))
|
|
7430
|
+
try {
|
|
7431
|
+
await _(), le(!1), oe.current = !1;
|
|
7432
|
+
const C = S.current?.remainingText, te = S.current?.originalText || P.current?.text, L = S.current?.options || P.current?.options || {}, F = C || te;
|
|
7433
|
+
F && j(F, L);
|
|
7434
|
+
} catch (C) {
|
|
7435
|
+
console.warn("Error resuming speech:", C), le(!1), oe.current = !1;
|
|
7436
|
+
}
|
|
7437
|
+
}, [ee, j, _]), we = T(() => {
|
|
7438
|
+
f.current && (f.current.stopSpeaking(), U.current && (clearInterval(U.current), U.current = null), le(!1), oe.current = !1);
|
|
7439
|
+
}, []);
|
|
7440
|
+
return Ee(M, () => ({
|
|
7441
|
+
speakText: j,
|
|
7442
|
+
pauseSpeaking: q,
|
|
7443
|
+
resumeSpeaking: Le,
|
|
7444
|
+
stopSpeaking: we,
|
|
7445
|
+
resumeAudioContext: _,
|
|
7446
|
+
isPaused: () => ee,
|
|
7447
|
+
setMood: (C) => f.current?.setMood(C),
|
|
7448
|
+
setBodyMovement: (C) => {
|
|
7449
|
+
f.current && f.current.setBodyMovement(C);
|
|
7450
|
+
},
|
|
7451
|
+
playAnimation: (C, te = !1) => {
|
|
7452
|
+
f.current && f.current.playAnimation && f.current.playAnimation(C, null, 10, 0, 0.01, te);
|
|
7453
|
+
},
|
|
7454
|
+
playReaction: (C) => f.current?.playReaction(C),
|
|
7455
|
+
playCelebration: () => f.current?.playCelebration(),
|
|
7456
|
+
setShowFullAvatar: (C) => {
|
|
7457
|
+
f.current && (E.current = C, f.current.setShowFullAvatar(C));
|
|
7458
|
+
},
|
|
7459
|
+
isReady: ae,
|
|
7460
|
+
talkingHead: f.current
|
|
7461
|
+
})), /* @__PURE__ */ Pe("div", { className: `simple-talking-avatar-container ${b}`, style: I, children: [
|
|
7462
|
+
/* @__PURE__ */ me(
|
|
7463
|
+
"div",
|
|
7464
|
+
{
|
|
7465
|
+
ref: w,
|
|
7466
|
+
className: "talking-head-viewer",
|
|
7467
|
+
style: {
|
|
7468
|
+
width: "100%",
|
|
7469
|
+
height: "100%",
|
|
7470
|
+
minHeight: "400px"
|
|
7471
|
+
}
|
|
7472
|
+
}
|
|
7473
|
+
),
|
|
7474
|
+
K && /* @__PURE__ */ me("div", { className: "loading-overlay", style: {
|
|
7475
|
+
position: "absolute",
|
|
7476
|
+
top: "50%",
|
|
7477
|
+
left: "50%",
|
|
7478
|
+
transform: "translate(-50%, -50%)",
|
|
7479
|
+
color: "white",
|
|
7480
|
+
fontSize: "18px",
|
|
7481
|
+
zIndex: 10
|
|
7482
|
+
}, children: "Loading avatar..." }),
|
|
7483
|
+
$ && /* @__PURE__ */ me("div", { className: "error-overlay", style: {
|
|
7484
|
+
position: "absolute",
|
|
7485
|
+
top: "50%",
|
|
7486
|
+
left: "50%",
|
|
7487
|
+
transform: "translate(-50%, -50%)",
|
|
7488
|
+
color: "#ff6b6b",
|
|
7489
|
+
fontSize: "16px",
|
|
7490
|
+
textAlign: "center",
|
|
7491
|
+
zIndex: 10,
|
|
7492
|
+
padding: "20px",
|
|
7493
|
+
borderRadius: "8px"
|
|
7494
|
+
}, children: $ })
|
|
7495
|
+
] });
|
|
7496
|
+
});
|
|
7497
|
+
gt.displayName = "SimpleTalkingAvatar";
|
|
7498
|
+
const yt = Me(({
|
|
7499
|
+
curriculumData: G = null,
|
|
7286
7500
|
avatarConfig: t = {},
|
|
7287
7501
|
animations: e = {},
|
|
7288
7502
|
onLessonStart: n = () => {
|
|
@@ -7295,9 +7509,9 @@ const gt = ze(({
|
|
|
7295
7509
|
},
|
|
7296
7510
|
onCustomAction: l = () => {
|
|
7297
7511
|
},
|
|
7298
|
-
autoStart:
|
|
7512
|
+
autoStart: h = !1
|
|
7299
7513
|
}, r) => {
|
|
7300
|
-
const
|
|
7514
|
+
const u = D(null), a = D({
|
|
7301
7515
|
currentModuleIndex: 0,
|
|
7302
7516
|
currentLessonIndex: 0,
|
|
7303
7517
|
currentQuestionIndex: 0,
|
|
@@ -7307,18 +7521,18 @@ const gt = ze(({
|
|
|
7307
7521
|
curriculumCompleted: !1,
|
|
7308
7522
|
score: 0,
|
|
7309
7523
|
totalQuestions: 0
|
|
7310
|
-
}), c =
|
|
7524
|
+
}), c = D({
|
|
7311
7525
|
onLessonStart: n,
|
|
7312
7526
|
onLessonComplete: i,
|
|
7313
7527
|
onQuestionAnswer: s,
|
|
7314
7528
|
onCurriculumComplete: o,
|
|
7315
7529
|
onCustomAction: l
|
|
7316
|
-
}), d =
|
|
7530
|
+
}), d = D(null), g = D(null), y = D(null), b = D(null), I = D(null), V = D(null), p = D(null), M = D(G?.curriculum || {
|
|
7317
7531
|
title: "Default Curriculum",
|
|
7318
7532
|
description: "No curriculum data provided",
|
|
7319
7533
|
language: "en",
|
|
7320
7534
|
modules: []
|
|
7321
|
-
}),
|
|
7535
|
+
}), w = D({
|
|
7322
7536
|
avatarUrl: t.avatarUrl || "/avatars/brunette.glb",
|
|
7323
7537
|
avatarBody: t.avatarBody || "F",
|
|
7324
7538
|
mood: t.mood || "happy",
|
|
@@ -7332,7 +7546,7 @@ const gt = ze(({
|
|
|
7332
7546
|
animations: e,
|
|
7333
7547
|
lipsyncLang: "en"
|
|
7334
7548
|
});
|
|
7335
|
-
|
|
7549
|
+
de(() => {
|
|
7336
7550
|
c.current = {
|
|
7337
7551
|
onLessonStart: n,
|
|
7338
7552
|
onLessonComplete: i,
|
|
@@ -7340,13 +7554,13 @@ const gt = ze(({
|
|
|
7340
7554
|
onCurriculumComplete: o,
|
|
7341
7555
|
onCustomAction: l
|
|
7342
7556
|
};
|
|
7343
|
-
}, [n, i, s, o, l]),
|
|
7344
|
-
|
|
7557
|
+
}, [n, i, s, o, l]), de(() => {
|
|
7558
|
+
M.current = G?.curriculum || {
|
|
7345
7559
|
title: "Default Curriculum",
|
|
7346
7560
|
description: "No curriculum data provided",
|
|
7347
7561
|
language: "en",
|
|
7348
7562
|
modules: []
|
|
7349
|
-
},
|
|
7563
|
+
}, w.current = {
|
|
7350
7564
|
avatarUrl: t.avatarUrl || "/avatars/brunette.glb",
|
|
7351
7565
|
avatarBody: t.avatarBody || "F",
|
|
7352
7566
|
mood: t.mood || "happy",
|
|
@@ -7360,34 +7574,34 @@ const gt = ze(({
|
|
|
7360
7574
|
animations: e,
|
|
7361
7575
|
lipsyncLang: "en"
|
|
7362
7576
|
};
|
|
7363
|
-
}, [
|
|
7364
|
-
const
|
|
7577
|
+
}, [G, t, e]);
|
|
7578
|
+
const f = T(() => (M.current || { modules: [] }).modules[a.current.currentModuleIndex]?.lessons[a.current.currentLessonIndex], []), E = T(() => f()?.questions[a.current.currentQuestionIndex], [f]), P = T((v, R) => R.type === "multiple_choice" || R.type === "true_false" ? v === R.answer : R.type === "code_test" && typeof v == "object" && v !== null ? v.passed === !0 : !1, []), U = T(() => {
|
|
7365
7579
|
a.current.lessonCompleted = !0, a.current.isQuestionMode = !1;
|
|
7366
|
-
const
|
|
7580
|
+
const v = a.current.totalQuestions > 0 ? Math.round(a.current.score / a.current.totalQuestions * 100) : 100;
|
|
7367
7581
|
let R = "Congratulations! You've completed this lesson";
|
|
7368
|
-
if (a.current.totalQuestions > 0 ? R += ` You got ${a.current.score} correct out of ${a.current.totalQuestions} question${a.current.totalQuestions === 1 ? "" : "s"}, achieving a score of ${
|
|
7582
|
+
if (a.current.totalQuestions > 0 ? R += ` You got ${a.current.score} correct out of ${a.current.totalQuestions} question${a.current.totalQuestions === 1 ? "" : "s"}, achieving a score of ${v} percent. ` : R += "! ", v >= 80 ? R += "Excellent work! You have a great understanding of this topic." : v >= 60 ? R += "Good job! You understand most of the concepts." : R += "Keep practicing! You're making progress.", c.current.onLessonComplete({
|
|
7369
7583
|
moduleIndex: a.current.currentModuleIndex,
|
|
7370
7584
|
lessonIndex: a.current.currentLessonIndex,
|
|
7371
7585
|
score: a.current.score,
|
|
7372
7586
|
totalQuestions: a.current.totalQuestions,
|
|
7373
|
-
percentage:
|
|
7587
|
+
percentage: v
|
|
7374
7588
|
}), c.current.onCustomAction({
|
|
7375
7589
|
type: "lessonComplete",
|
|
7376
7590
|
moduleIndex: a.current.currentModuleIndex,
|
|
7377
7591
|
lessonIndex: a.current.currentLessonIndex,
|
|
7378
7592
|
score: a.current.score,
|
|
7379
7593
|
totalQuestions: a.current.totalQuestions,
|
|
7380
|
-
percentage:
|
|
7381
|
-
}),
|
|
7382
|
-
if (
|
|
7594
|
+
percentage: v
|
|
7595
|
+
}), u.current) {
|
|
7596
|
+
if (u.current.setMood("happy"), e.lessonComplete)
|
|
7383
7597
|
try {
|
|
7384
|
-
|
|
7598
|
+
u.current.playAnimation(e.lessonComplete, !0);
|
|
7385
7599
|
} catch {
|
|
7386
|
-
|
|
7600
|
+
u.current.playCelebration();
|
|
7387
7601
|
}
|
|
7388
|
-
const
|
|
7389
|
-
|
|
7390
|
-
lipsyncLang:
|
|
7602
|
+
const z = M.current || { modules: [] }, H = z.modules[a.current.currentModuleIndex], N = a.current.currentLessonIndex < (H?.lessons?.length || 0) - 1, _ = a.current.currentModuleIndex < (z.modules?.length || 0) - 1, j = N || _, q = w.current || { lipsyncLang: "en" };
|
|
7603
|
+
u.current.speakText(R, {
|
|
7604
|
+
lipsyncLang: q.lipsyncLang,
|
|
7391
7605
|
onSpeechEnd: () => {
|
|
7392
7606
|
c.current.onCustomAction({
|
|
7393
7607
|
type: "lessonCompleteFeedbackDone",
|
|
@@ -7395,32 +7609,32 @@ const gt = ze(({
|
|
|
7395
7609
|
lessonIndex: a.current.currentLessonIndex,
|
|
7396
7610
|
score: a.current.score,
|
|
7397
7611
|
totalQuestions: a.current.totalQuestions,
|
|
7398
|
-
percentage:
|
|
7399
|
-
hasNextLesson:
|
|
7612
|
+
percentage: v,
|
|
7613
|
+
hasNextLesson: j
|
|
7400
7614
|
});
|
|
7401
7615
|
}
|
|
7402
7616
|
});
|
|
7403
7617
|
}
|
|
7404
|
-
}, [e.lessonComplete]),
|
|
7618
|
+
}, [e.lessonComplete]), oe = T(() => {
|
|
7405
7619
|
a.current.curriculumCompleted = !0;
|
|
7406
|
-
const
|
|
7620
|
+
const v = M.current || { modules: [] };
|
|
7407
7621
|
if (c.current.onCurriculumComplete({
|
|
7408
|
-
modules:
|
|
7409
|
-
totalLessons:
|
|
7410
|
-
}),
|
|
7411
|
-
if (
|
|
7622
|
+
modules: v.modules.length,
|
|
7623
|
+
totalLessons: v.modules.reduce((R, z) => R + z.lessons.length, 0)
|
|
7624
|
+
}), u.current) {
|
|
7625
|
+
if (u.current.setMood("celebrating"), e.curriculumComplete)
|
|
7412
7626
|
try {
|
|
7413
|
-
|
|
7627
|
+
u.current.playAnimation(e.curriculumComplete, !0);
|
|
7414
7628
|
} catch {
|
|
7415
|
-
|
|
7629
|
+
u.current.playCelebration();
|
|
7416
7630
|
}
|
|
7417
|
-
const R =
|
|
7418
|
-
|
|
7631
|
+
const R = w.current || { lipsyncLang: "en" };
|
|
7632
|
+
u.current.speakText("Amazing! You've completed the entire curriculum! You're now ready to move on to more advanced topics. Well done!", { lipsyncLang: R.lipsyncLang });
|
|
7419
7633
|
}
|
|
7420
|
-
}, [e.curriculumComplete]), S =
|
|
7421
|
-
const
|
|
7422
|
-
a.current.isQuestionMode = !0, a.current.currentQuestionIndex = 0, a.current.totalQuestions =
|
|
7423
|
-
const R =
|
|
7634
|
+
}, [e.curriculumComplete]), S = T(() => {
|
|
7635
|
+
const v = f();
|
|
7636
|
+
a.current.isQuestionMode = !0, a.current.currentQuestionIndex = 0, a.current.totalQuestions = v?.questions?.length || 0, a.current.score = 0;
|
|
7637
|
+
const R = E();
|
|
7424
7638
|
R && c.current.onCustomAction({
|
|
7425
7639
|
type: "questionStart",
|
|
7426
7640
|
moduleIndex: a.current.currentModuleIndex,
|
|
@@ -7430,35 +7644,35 @@ const gt = ze(({
|
|
|
7430
7644
|
question: R,
|
|
7431
7645
|
score: a.current.score
|
|
7432
7646
|
});
|
|
7433
|
-
const
|
|
7434
|
-
if (!
|
|
7435
|
-
if (
|
|
7647
|
+
const z = () => {
|
|
7648
|
+
if (!u.current || !R) return;
|
|
7649
|
+
if (u.current.setMood("happy"), e.questionStart)
|
|
7436
7650
|
try {
|
|
7437
|
-
|
|
7438
|
-
} catch (
|
|
7439
|
-
console.warn("Failed to play questionStart animation:",
|
|
7651
|
+
u.current.playAnimation(e.questionStart, !0);
|
|
7652
|
+
} catch (N) {
|
|
7653
|
+
console.warn("Failed to play questionStart animation:", N);
|
|
7440
7654
|
}
|
|
7441
|
-
const
|
|
7442
|
-
R.type === "code_test" ?
|
|
7655
|
+
const H = w.current || { lipsyncLang: "en" };
|
|
7656
|
+
R.type === "code_test" ? u.current.speakText(`Let's test your coding skills! Here's your first challenge: ${R.question}`, { lipsyncLang: H.lipsyncLang }) : R.type === "multiple_choice" ? u.current.speakText(`Now let me ask you some questions. Here's the first one: ${R.question}`, { lipsyncLang: H.lipsyncLang }) : R.type === "true_false" ? u.current.speakText(`Let's start with some true or false questions. First question: ${R.question}`, { lipsyncLang: H.lipsyncLang }) : u.current.speakText(`Now let me ask you some questions. Here's the first one: ${R.question}`, { lipsyncLang: H.lipsyncLang });
|
|
7443
7657
|
};
|
|
7444
|
-
if (
|
|
7445
|
-
|
|
7446
|
-
else if (
|
|
7447
|
-
const
|
|
7448
|
-
|
|
7658
|
+
if (u.current && u.current.isReady && R)
|
|
7659
|
+
z();
|
|
7660
|
+
else if (u.current && u.current.isReady) {
|
|
7661
|
+
const H = w.current || { lipsyncLang: "en" };
|
|
7662
|
+
u.current.speakText("Now let me ask you some questions to test your understanding.", { lipsyncLang: H.lipsyncLang });
|
|
7449
7663
|
} else {
|
|
7450
|
-
const
|
|
7451
|
-
|
|
7664
|
+
const H = setInterval(() => {
|
|
7665
|
+
u.current && u.current.isReady && (clearInterval(H), R && z());
|
|
7452
7666
|
}, 100);
|
|
7453
7667
|
setTimeout(() => {
|
|
7454
|
-
clearInterval(
|
|
7668
|
+
clearInterval(H);
|
|
7455
7669
|
}, 5e3);
|
|
7456
7670
|
}
|
|
7457
|
-
}, [e.questionStart,
|
|
7458
|
-
const
|
|
7459
|
-
if (a.current.currentQuestionIndex < (
|
|
7460
|
-
|
|
7461
|
-
const R =
|
|
7671
|
+
}, [e.questionStart, f, E]), Z = T(() => {
|
|
7672
|
+
const v = f();
|
|
7673
|
+
if (a.current.currentQuestionIndex < (v?.questions?.length || 0) - 1) {
|
|
7674
|
+
u.current && u.current.stopSpeaking && u.current.stopSpeaking(), a.current.currentQuestionIndex += 1;
|
|
7675
|
+
const R = E();
|
|
7462
7676
|
R && c.current.onCustomAction({
|
|
7463
7677
|
type: "nextQuestion",
|
|
7464
7678
|
moduleIndex: a.current.currentModuleIndex,
|
|
@@ -7468,45 +7682,45 @@ const gt = ze(({
|
|
|
7468
7682
|
question: R,
|
|
7469
7683
|
score: a.current.score
|
|
7470
7684
|
});
|
|
7471
|
-
const
|
|
7472
|
-
if (!
|
|
7473
|
-
if (
|
|
7685
|
+
const z = () => {
|
|
7686
|
+
if (!u.current || !R) return;
|
|
7687
|
+
if (u.current.setMood("happy"), u.current.setBodyMovement("idle"), e.nextQuestion)
|
|
7474
7688
|
try {
|
|
7475
|
-
|
|
7476
|
-
} catch (
|
|
7477
|
-
console.warn("Failed to play nextQuestion animation:",
|
|
7689
|
+
u.current.playAnimation(e.nextQuestion, !0);
|
|
7690
|
+
} catch (q) {
|
|
7691
|
+
console.warn("Failed to play nextQuestion animation:", q);
|
|
7478
7692
|
}
|
|
7479
|
-
const
|
|
7693
|
+
const H = w.current || { lipsyncLang: "en" }, _ = f()?.questions?.length || 0, j = a.current.currentQuestionIndex >= _ - 1;
|
|
7480
7694
|
if (R.type === "code_test") {
|
|
7481
|
-
const
|
|
7482
|
-
|
|
7483
|
-
lipsyncLang:
|
|
7695
|
+
const q = j ? `Great! Here's your final coding challenge: ${R.question}` : `Great! Now let's move on to your next coding challenge: ${R.question}`;
|
|
7696
|
+
u.current.speakText(q, {
|
|
7697
|
+
lipsyncLang: H.lipsyncLang
|
|
7484
7698
|
});
|
|
7485
7699
|
} else if (R.type === "multiple_choice") {
|
|
7486
|
-
const
|
|
7487
|
-
|
|
7488
|
-
lipsyncLang:
|
|
7700
|
+
const q = j ? `Alright! Here's your final question: ${R.question}` : `Alright! Here's your next question: ${R.question}`;
|
|
7701
|
+
u.current.speakText(q, {
|
|
7702
|
+
lipsyncLang: H.lipsyncLang
|
|
7489
7703
|
});
|
|
7490
7704
|
} else if (R.type === "true_false") {
|
|
7491
|
-
const
|
|
7492
|
-
|
|
7493
|
-
lipsyncLang:
|
|
7705
|
+
const q = j ? `Now let's try this final one: ${R.question}` : `Now let's try this one: ${R.question}`;
|
|
7706
|
+
u.current.speakText(q, {
|
|
7707
|
+
lipsyncLang: H.lipsyncLang
|
|
7494
7708
|
});
|
|
7495
7709
|
} else {
|
|
7496
|
-
const
|
|
7497
|
-
|
|
7498
|
-
lipsyncLang:
|
|
7710
|
+
const q = j ? `Here's your final question: ${R.question}` : `Here's the next question: ${R.question}`;
|
|
7711
|
+
u.current.speakText(q, {
|
|
7712
|
+
lipsyncLang: H.lipsyncLang
|
|
7499
7713
|
});
|
|
7500
7714
|
}
|
|
7501
7715
|
};
|
|
7502
|
-
if (
|
|
7503
|
-
|
|
7716
|
+
if (u.current && u.current.isReady && R)
|
|
7717
|
+
z();
|
|
7504
7718
|
else if (R) {
|
|
7505
|
-
const
|
|
7506
|
-
|
|
7719
|
+
const H = setInterval(() => {
|
|
7720
|
+
u.current && u.current.isReady && (clearInterval(H), z());
|
|
7507
7721
|
}, 100);
|
|
7508
7722
|
setTimeout(() => {
|
|
7509
|
-
clearInterval(
|
|
7723
|
+
clearInterval(H);
|
|
7510
7724
|
}, 5e3);
|
|
7511
7725
|
}
|
|
7512
7726
|
} else
|
|
@@ -7517,108 +7731,108 @@ const gt = ze(({
|
|
|
7517
7731
|
totalQuestions: a.current.totalQuestions,
|
|
7518
7732
|
score: a.current.score
|
|
7519
7733
|
});
|
|
7520
|
-
}, [e.nextQuestion,
|
|
7521
|
-
const
|
|
7734
|
+
}, [e.nextQuestion, f, E]), K = T(() => {
|
|
7735
|
+
const v = M.current || { modules: [] }, R = v.modules[a.current.currentModuleIndex];
|
|
7522
7736
|
if (a.current.currentLessonIndex < (R?.lessons?.length || 0) - 1) {
|
|
7523
7737
|
a.current.currentLessonIndex += 1, a.current.currentQuestionIndex = 0, a.current.lessonCompleted = !1, a.current.isQuestionMode = !1, a.current.isTeaching = !1, a.current.score = 0, a.current.totalQuestions = 0;
|
|
7524
|
-
const
|
|
7738
|
+
const H = v.modules[a.current.currentModuleIndex], N = a.current.currentLessonIndex < (H?.lessons?.length || 0) - 1, _ = a.current.currentModuleIndex < (v.modules?.length || 0) - 1, j = N || _;
|
|
7525
7739
|
c.current.onCustomAction({
|
|
7526
7740
|
type: "lessonStart",
|
|
7527
7741
|
moduleIndex: a.current.currentModuleIndex,
|
|
7528
7742
|
lessonIndex: a.current.currentLessonIndex,
|
|
7529
|
-
hasNextLesson:
|
|
7743
|
+
hasNextLesson: j
|
|
7530
7744
|
}), c.current.onLessonStart({
|
|
7531
7745
|
moduleIndex: a.current.currentModuleIndex,
|
|
7532
7746
|
lessonIndex: a.current.currentLessonIndex,
|
|
7533
|
-
lesson:
|
|
7534
|
-
}),
|
|
7535
|
-
} else if (a.current.currentModuleIndex < (
|
|
7747
|
+
lesson: f()
|
|
7748
|
+
}), u.current && (u.current.setMood("happy"), u.current.setBodyMovement("idle"));
|
|
7749
|
+
} else if (a.current.currentModuleIndex < (v.modules?.length || 0) - 1) {
|
|
7536
7750
|
a.current.currentModuleIndex += 1, a.current.currentLessonIndex = 0, a.current.currentQuestionIndex = 0, a.current.lessonCompleted = !1, a.current.isQuestionMode = !1, a.current.isTeaching = !1, a.current.score = 0, a.current.totalQuestions = 0;
|
|
7537
|
-
const
|
|
7751
|
+
const N = v.modules[a.current.currentModuleIndex], _ = a.current.currentLessonIndex < (N?.lessons?.length || 0) - 1, j = a.current.currentModuleIndex < (v.modules?.length || 0) - 1, q = _ || j;
|
|
7538
7752
|
c.current.onCustomAction({
|
|
7539
7753
|
type: "lessonStart",
|
|
7540
7754
|
moduleIndex: a.current.currentModuleIndex,
|
|
7541
7755
|
lessonIndex: a.current.currentLessonIndex,
|
|
7542
|
-
hasNextLesson:
|
|
7756
|
+
hasNextLesson: q
|
|
7543
7757
|
}), c.current.onLessonStart({
|
|
7544
7758
|
moduleIndex: a.current.currentModuleIndex,
|
|
7545
7759
|
lessonIndex: a.current.currentLessonIndex,
|
|
7546
|
-
lesson:
|
|
7547
|
-
}),
|
|
7760
|
+
lesson: f()
|
|
7761
|
+
}), u.current && (u.current.setMood("happy"), u.current.setBodyMovement("idle"));
|
|
7548
7762
|
} else
|
|
7549
|
-
|
|
7550
|
-
}, []),
|
|
7551
|
-
const
|
|
7763
|
+
I.current && I.current();
|
|
7764
|
+
}, []), X = T(() => {
|
|
7765
|
+
const v = f();
|
|
7552
7766
|
let R = null;
|
|
7553
|
-
if (
|
|
7554
|
-
const
|
|
7555
|
-
R = `${
|
|
7767
|
+
if (v?.avatar_script && v?.body) {
|
|
7768
|
+
const z = v.avatar_script.trim(), H = v.body.trim(), N = z.match(/[.!?]$/) ? " " : ". ";
|
|
7769
|
+
R = `${z}${N}${H}`;
|
|
7556
7770
|
} else
|
|
7557
|
-
R =
|
|
7558
|
-
if (
|
|
7559
|
-
a.current.isTeaching = !0, a.current.isQuestionMode = !1, a.current.score = 0, a.current.totalQuestions = 0,
|
|
7560
|
-
let
|
|
7771
|
+
R = v?.avatar_script || v?.body || null;
|
|
7772
|
+
if (u.current && u.current.isReady && R) {
|
|
7773
|
+
a.current.isTeaching = !0, a.current.isQuestionMode = !1, a.current.score = 0, a.current.totalQuestions = 0, u.current.setMood("happy");
|
|
7774
|
+
let z = !1;
|
|
7561
7775
|
if (e.teaching)
|
|
7562
7776
|
try {
|
|
7563
|
-
|
|
7564
|
-
} catch (
|
|
7565
|
-
console.warn("Failed to play teaching animation:",
|
|
7777
|
+
u.current.playAnimation(e.teaching, !0), z = !0;
|
|
7778
|
+
} catch (N) {
|
|
7779
|
+
console.warn("Failed to play teaching animation:", N);
|
|
7566
7780
|
}
|
|
7567
|
-
|
|
7568
|
-
const
|
|
7781
|
+
z || u.current.setBodyMovement("gesturing");
|
|
7782
|
+
const H = w.current || { lipsyncLang: "en" };
|
|
7569
7783
|
c.current.onLessonStart({
|
|
7570
7784
|
moduleIndex: a.current.currentModuleIndex,
|
|
7571
7785
|
lessonIndex: a.current.currentLessonIndex,
|
|
7572
|
-
lesson:
|
|
7786
|
+
lesson: v
|
|
7573
7787
|
}), c.current.onCustomAction({
|
|
7574
7788
|
type: "teachingStart",
|
|
7575
7789
|
moduleIndex: a.current.currentModuleIndex,
|
|
7576
7790
|
lessonIndex: a.current.currentLessonIndex,
|
|
7577
|
-
lesson:
|
|
7578
|
-
}),
|
|
7579
|
-
lipsyncLang:
|
|
7791
|
+
lesson: v
|
|
7792
|
+
}), u.current.speakText(R, {
|
|
7793
|
+
lipsyncLang: H.lipsyncLang,
|
|
7580
7794
|
onSpeechEnd: () => {
|
|
7581
7795
|
a.current.isTeaching = !1, c.current.onCustomAction({
|
|
7582
7796
|
type: "teachingComplete",
|
|
7583
7797
|
moduleIndex: a.current.currentModuleIndex,
|
|
7584
7798
|
lessonIndex: a.current.currentLessonIndex,
|
|
7585
|
-
lesson:
|
|
7586
|
-
hasQuestions:
|
|
7587
|
-
}),
|
|
7799
|
+
lesson: v,
|
|
7800
|
+
hasQuestions: v.questions && v.questions.length > 0
|
|
7801
|
+
}), v?.code_example && c.current.onCustomAction({
|
|
7588
7802
|
type: "codeExampleReady",
|
|
7589
7803
|
moduleIndex: a.current.currentModuleIndex,
|
|
7590
7804
|
lessonIndex: a.current.currentLessonIndex,
|
|
7591
|
-
lesson:
|
|
7592
|
-
codeExample:
|
|
7805
|
+
lesson: v,
|
|
7806
|
+
codeExample: v.code_example
|
|
7593
7807
|
});
|
|
7594
7808
|
}
|
|
7595
7809
|
});
|
|
7596
7810
|
}
|
|
7597
|
-
}, [e.teaching,
|
|
7598
|
-
const R =
|
|
7599
|
-
if (
|
|
7811
|
+
}, [e.teaching, f]), $ = T((v) => {
|
|
7812
|
+
const R = E(), z = P(v, R);
|
|
7813
|
+
if (z && (a.current.score += 1), c.current.onQuestionAnswer({
|
|
7600
7814
|
moduleIndex: a.current.currentModuleIndex,
|
|
7601
7815
|
lessonIndex: a.current.currentLessonIndex,
|
|
7602
7816
|
questionIndex: a.current.currentQuestionIndex,
|
|
7603
|
-
answer:
|
|
7604
|
-
isCorrect:
|
|
7817
|
+
answer: v,
|
|
7818
|
+
isCorrect: z,
|
|
7605
7819
|
question: R
|
|
7606
|
-
}),
|
|
7607
|
-
if (
|
|
7608
|
-
if (
|
|
7820
|
+
}), u.current)
|
|
7821
|
+
if (z) {
|
|
7822
|
+
if (u.current.setMood("happy"), e.correct)
|
|
7609
7823
|
try {
|
|
7610
|
-
|
|
7824
|
+
u.current.playReaction("happy");
|
|
7611
7825
|
} catch {
|
|
7612
|
-
|
|
7826
|
+
u.current.setBodyMovement("happy");
|
|
7613
7827
|
}
|
|
7614
|
-
|
|
7615
|
-
const
|
|
7616
|
-
a.current.currentQuestionIndex >=
|
|
7617
|
-
const
|
|
7618
|
-
console.log("[CurriculumLearning] Answer feedback - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:",
|
|
7619
|
-
const
|
|
7620
|
-
|
|
7621
|
-
lipsyncLang:
|
|
7828
|
+
u.current.setBodyMovement("gesturing");
|
|
7829
|
+
const N = f()?.questions?.length || 0;
|
|
7830
|
+
a.current.currentQuestionIndex >= N - 1;
|
|
7831
|
+
const _ = a.current.currentQuestionIndex < N - 1;
|
|
7832
|
+
console.log("[CurriculumLearning] Answer feedback - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:", N, "hasNextQuestion:", _);
|
|
7833
|
+
const j = R.type === "code_test" ? `Great job! Your code passed all the tests! ${R.explanation || ""}` : `Excellent! That's correct! ${R.explanation || ""}`, q = w.current || { lipsyncLang: "en" };
|
|
7834
|
+
u.current.speakText(j, {
|
|
7835
|
+
lipsyncLang: q.lipsyncLang,
|
|
7622
7836
|
onSpeechEnd: () => {
|
|
7623
7837
|
c.current.onCustomAction({
|
|
7624
7838
|
type: "answerFeedbackComplete",
|
|
@@ -7626,25 +7840,25 @@ const gt = ze(({
|
|
|
7626
7840
|
lessonIndex: a.current.currentLessonIndex,
|
|
7627
7841
|
questionIndex: a.current.currentQuestionIndex,
|
|
7628
7842
|
isCorrect: !0,
|
|
7629
|
-
hasNextQuestion:
|
|
7843
|
+
hasNextQuestion: _,
|
|
7630
7844
|
score: a.current.score,
|
|
7631
7845
|
totalQuestions: a.current.totalQuestions
|
|
7632
7846
|
});
|
|
7633
7847
|
}
|
|
7634
7848
|
});
|
|
7635
7849
|
} else {
|
|
7636
|
-
if (
|
|
7850
|
+
if (u.current.setMood("sad"), e.incorrect)
|
|
7637
7851
|
try {
|
|
7638
|
-
|
|
7852
|
+
u.current.playAnimation(e.incorrect, !0);
|
|
7639
7853
|
} catch {
|
|
7640
|
-
|
|
7854
|
+
u.current.setBodyMovement("idle");
|
|
7641
7855
|
}
|
|
7642
|
-
|
|
7643
|
-
const
|
|
7644
|
-
console.log("[CurriculumLearning] Answer feedback (incorrect) - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:",
|
|
7645
|
-
const
|
|
7646
|
-
|
|
7647
|
-
lipsyncLang:
|
|
7856
|
+
u.current.setBodyMovement("gesturing");
|
|
7857
|
+
const N = f()?.questions?.length || 0, _ = a.current.currentQuestionIndex >= N - 1, j = a.current.currentQuestionIndex < N - 1;
|
|
7858
|
+
console.log("[CurriculumLearning] Answer feedback (incorrect) - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:", N, "hasNextQuestion:", j);
|
|
7859
|
+
const q = R.type === "code_test" ? `Your code didn't pass all the tests. ${R.explanation || "Try again!"}` : `Not quite right, but don't worry! ${R.explanation || ""}${_ ? "" : " Let's move on to the next question."}`, Le = w.current || { lipsyncLang: "en" };
|
|
7860
|
+
u.current.speakText(q, {
|
|
7861
|
+
lipsyncLang: Le.lipsyncLang,
|
|
7648
7862
|
onSpeechEnd: () => {
|
|
7649
7863
|
c.current.onCustomAction({
|
|
7650
7864
|
type: "answerFeedbackComplete",
|
|
@@ -7652,7 +7866,7 @@ const gt = ze(({
|
|
|
7652
7866
|
lessonIndex: a.current.currentLessonIndex,
|
|
7653
7867
|
questionIndex: a.current.currentQuestionIndex,
|
|
7654
7868
|
isCorrect: !1,
|
|
7655
|
-
hasNextQuestion:
|
|
7869
|
+
hasNextQuestion: j,
|
|
7656
7870
|
score: a.current.score,
|
|
7657
7871
|
totalQuestions: a.current.totalQuestions
|
|
7658
7872
|
});
|
|
@@ -7660,22 +7874,22 @@ const gt = ze(({
|
|
|
7660
7874
|
});
|
|
7661
7875
|
}
|
|
7662
7876
|
else {
|
|
7663
|
-
const
|
|
7877
|
+
const N = f()?.questions?.length || 0;
|
|
7664
7878
|
c.current.onCustomAction({
|
|
7665
7879
|
type: "answerFeedbackComplete",
|
|
7666
7880
|
moduleIndex: a.current.currentModuleIndex,
|
|
7667
7881
|
lessonIndex: a.current.currentLessonIndex,
|
|
7668
7882
|
questionIndex: a.current.currentQuestionIndex,
|
|
7669
|
-
isCorrect:
|
|
7670
|
-
hasNextQuestion: a.current.currentQuestionIndex <
|
|
7883
|
+
isCorrect: z,
|
|
7884
|
+
hasNextQuestion: a.current.currentQuestionIndex < N - 1,
|
|
7671
7885
|
score: a.current.score,
|
|
7672
7886
|
totalQuestions: a.current.totalQuestions,
|
|
7673
7887
|
avatarNotReady: !0
|
|
7674
7888
|
});
|
|
7675
7889
|
}
|
|
7676
|
-
}, [e.correct, e.incorrect,
|
|
7677
|
-
const R =
|
|
7678
|
-
if (!
|
|
7890
|
+
}, [e.correct, e.incorrect, E, f, P]), se = T((v) => {
|
|
7891
|
+
const R = E();
|
|
7892
|
+
if (!v || typeof v != "object") {
|
|
7679
7893
|
console.error("Invalid code test result format. Expected object with {passed: boolean, ...}");
|
|
7680
7894
|
return;
|
|
7681
7895
|
}
|
|
@@ -7683,61 +7897,61 @@ const gt = ze(({
|
|
|
7683
7897
|
console.warn("Current question is not a code test. Use handleAnswerSelect for other question types.");
|
|
7684
7898
|
return;
|
|
7685
7899
|
}
|
|
7686
|
-
const
|
|
7687
|
-
passed:
|
|
7688
|
-
results:
|
|
7689
|
-
output:
|
|
7690
|
-
error:
|
|
7691
|
-
executionTime:
|
|
7692
|
-
testCount:
|
|
7693
|
-
passedCount:
|
|
7694
|
-
failedCount:
|
|
7900
|
+
const z = {
|
|
7901
|
+
passed: v.passed === !0,
|
|
7902
|
+
results: v.results || [],
|
|
7903
|
+
output: v.output || "",
|
|
7904
|
+
error: v.error || null,
|
|
7905
|
+
executionTime: v.executionTime || null,
|
|
7906
|
+
testCount: v.testCount || 0,
|
|
7907
|
+
passedCount: v.passedCount || 0,
|
|
7908
|
+
failedCount: v.failedCount || 0
|
|
7695
7909
|
};
|
|
7696
7910
|
c.current.onCustomAction({
|
|
7697
7911
|
type: "codeTestSubmitted",
|
|
7698
7912
|
moduleIndex: a.current.currentModuleIndex,
|
|
7699
7913
|
lessonIndex: a.current.currentLessonIndex,
|
|
7700
7914
|
questionIndex: a.current.currentQuestionIndex,
|
|
7701
|
-
testResult:
|
|
7915
|
+
testResult: z,
|
|
7702
7916
|
question: R
|
|
7703
|
-
}), p.current && p.current(
|
|
7704
|
-
}, [
|
|
7917
|
+
}), p.current && p.current(z);
|
|
7918
|
+
}, [E, P]), ae = T(() => {
|
|
7705
7919
|
if (a.current.currentQuestionIndex > 0) {
|
|
7706
7920
|
a.current.currentQuestionIndex -= 1;
|
|
7707
|
-
const
|
|
7708
|
-
|
|
7921
|
+
const v = E();
|
|
7922
|
+
v && c.current.onCustomAction({
|
|
7709
7923
|
type: "questionStart",
|
|
7710
7924
|
moduleIndex: a.current.currentModuleIndex,
|
|
7711
7925
|
lessonIndex: a.current.currentLessonIndex,
|
|
7712
7926
|
questionIndex: a.current.currentQuestionIndex,
|
|
7713
7927
|
totalQuestions: a.current.totalQuestions,
|
|
7714
|
-
question:
|
|
7928
|
+
question: v,
|
|
7715
7929
|
score: a.current.score
|
|
7716
7930
|
});
|
|
7717
7931
|
const R = () => {
|
|
7718
|
-
if (!
|
|
7719
|
-
|
|
7720
|
-
const
|
|
7721
|
-
|
|
7722
|
-
lipsyncLang:
|
|
7723
|
-
}) :
|
|
7724
|
-
lipsyncLang:
|
|
7932
|
+
if (!u.current || !v) return;
|
|
7933
|
+
u.current.setMood("happy"), u.current.setBodyMovement("idle");
|
|
7934
|
+
const z = w.current || { lipsyncLang: "en" };
|
|
7935
|
+
v.type === "code_test" ? u.current.speakText(`Let's go back to this coding challenge: ${v.question}`, {
|
|
7936
|
+
lipsyncLang: z.lipsyncLang
|
|
7937
|
+
}) : u.current.speakText(`Going back to: ${v.question}`, {
|
|
7938
|
+
lipsyncLang: z.lipsyncLang
|
|
7725
7939
|
});
|
|
7726
7940
|
};
|
|
7727
|
-
if (
|
|
7941
|
+
if (u.current && u.current.isReady && v)
|
|
7728
7942
|
R();
|
|
7729
|
-
else if (
|
|
7730
|
-
const
|
|
7731
|
-
|
|
7943
|
+
else if (v) {
|
|
7944
|
+
const z = setInterval(() => {
|
|
7945
|
+
u.current && u.current.isReady && (clearInterval(z), R());
|
|
7732
7946
|
}, 100);
|
|
7733
7947
|
setTimeout(() => {
|
|
7734
|
-
clearInterval(
|
|
7948
|
+
clearInterval(z);
|
|
7735
7949
|
}, 5e3);
|
|
7736
7950
|
}
|
|
7737
7951
|
}
|
|
7738
|
-
}, [
|
|
7739
|
-
const
|
|
7740
|
-
if (
|
|
7952
|
+
}, [E]), pe = T(() => {
|
|
7953
|
+
const v = M.current || { modules: [] };
|
|
7954
|
+
if (v.modules[a.current.currentModuleIndex], a.current.currentLessonIndex > 0)
|
|
7741
7955
|
a.current.currentLessonIndex -= 1, a.current.currentQuestionIndex = 0, a.current.lessonCompleted = !1, a.current.isQuestionMode = !1, a.current.isTeaching = !1, a.current.score = 0, a.current.totalQuestions = 0, c.current.onCustomAction({
|
|
7742
7956
|
type: "lessonStart",
|
|
7743
7957
|
moduleIndex: a.current.currentModuleIndex,
|
|
@@ -7745,99 +7959,99 @@ const gt = ze(({
|
|
|
7745
7959
|
}), c.current.onLessonStart({
|
|
7746
7960
|
moduleIndex: a.current.currentModuleIndex,
|
|
7747
7961
|
lessonIndex: a.current.currentLessonIndex,
|
|
7748
|
-
lesson:
|
|
7749
|
-
}),
|
|
7962
|
+
lesson: f()
|
|
7963
|
+
}), u.current && (u.current.setMood("happy"), u.current.setBodyMovement("idle"));
|
|
7750
7964
|
else if (a.current.currentModuleIndex > 0) {
|
|
7751
|
-
const
|
|
7752
|
-
a.current.currentModuleIndex -= 1, a.current.currentLessonIndex = (
|
|
7965
|
+
const H = v.modules[a.current.currentModuleIndex - 1];
|
|
7966
|
+
a.current.currentModuleIndex -= 1, a.current.currentLessonIndex = (H?.lessons?.length || 1) - 1, a.current.currentQuestionIndex = 0, a.current.lessonCompleted = !1, a.current.isQuestionMode = !1, a.current.isTeaching = !1, a.current.score = 0, a.current.totalQuestions = 0, c.current.onCustomAction({
|
|
7753
7967
|
type: "lessonStart",
|
|
7754
7968
|
moduleIndex: a.current.currentModuleIndex,
|
|
7755
7969
|
lessonIndex: a.current.currentLessonIndex
|
|
7756
7970
|
}), c.current.onLessonStart({
|
|
7757
7971
|
moduleIndex: a.current.currentModuleIndex,
|
|
7758
7972
|
lessonIndex: a.current.currentLessonIndex,
|
|
7759
|
-
lesson:
|
|
7760
|
-
}),
|
|
7973
|
+
lesson: f()
|
|
7974
|
+
}), u.current && (u.current.setMood("happy"), u.current.setBodyMovement("idle"));
|
|
7761
7975
|
}
|
|
7762
|
-
}, [
|
|
7976
|
+
}, [f]), ee = T(() => {
|
|
7763
7977
|
a.current.currentModuleIndex = 0, a.current.currentLessonIndex = 0, a.current.currentQuestionIndex = 0, a.current.isTeaching = !1, a.current.isQuestionMode = !1, a.current.lessonCompleted = !1, a.current.curriculumCompleted = !1, a.current.score = 0, a.current.totalQuestions = 0;
|
|
7764
|
-
}, []),
|
|
7765
|
-
console.log("Avatar is ready!",
|
|
7766
|
-
const R =
|
|
7767
|
-
|
|
7978
|
+
}, []), le = T((v) => {
|
|
7979
|
+
console.log("Avatar is ready!", v);
|
|
7980
|
+
const R = f(), z = R?.avatar_script || R?.body;
|
|
7981
|
+
h && z && setTimeout(() => {
|
|
7768
7982
|
d.current && d.current();
|
|
7769
7983
|
}, 10);
|
|
7770
|
-
}, [
|
|
7984
|
+
}, [h, f]);
|
|
7771
7985
|
Xe(() => {
|
|
7772
|
-
d.current =
|
|
7773
|
-
}),
|
|
7986
|
+
d.current = X, g.current = K, y.current = U, b.current = Z, I.current = oe, V.current = S, p.current = $;
|
|
7987
|
+
}), Ee(r, () => ({
|
|
7774
7988
|
// Curriculum control methods
|
|
7775
|
-
startTeaching:
|
|
7989
|
+
startTeaching: X,
|
|
7776
7990
|
startQuestions: S,
|
|
7777
7991
|
handleAnswerSelect: $,
|
|
7778
7992
|
handleCodeTestResult: se,
|
|
7779
|
-
nextQuestion:
|
|
7780
|
-
previousQuestion:
|
|
7781
|
-
nextLesson:
|
|
7782
|
-
previousLesson:
|
|
7783
|
-
completeLesson:
|
|
7784
|
-
completeCurriculum:
|
|
7785
|
-
resetCurriculum:
|
|
7993
|
+
nextQuestion: Z,
|
|
7994
|
+
previousQuestion: ae,
|
|
7995
|
+
nextLesson: K,
|
|
7996
|
+
previousLesson: pe,
|
|
7997
|
+
completeLesson: U,
|
|
7998
|
+
completeCurriculum: oe,
|
|
7999
|
+
resetCurriculum: ee,
|
|
7786
8000
|
getState: () => ({ ...a.current }),
|
|
7787
|
-
getCurrentQuestion: () =>
|
|
7788
|
-
getCurrentLesson: () =>
|
|
8001
|
+
getCurrentQuestion: () => E(),
|
|
8002
|
+
getCurrentLesson: () => f(),
|
|
7789
8003
|
// Direct access to avatar ref (always returns current value)
|
|
7790
|
-
getAvatarRef: () =>
|
|
8004
|
+
getAvatarRef: () => u.current,
|
|
7791
8005
|
// Convenience methods that delegate to avatar (always check current ref)
|
|
7792
|
-
speakText: async (
|
|
7793
|
-
await
|
|
7794
|
-
const
|
|
7795
|
-
|
|
8006
|
+
speakText: async (v, R = {}) => {
|
|
8007
|
+
await u.current?.resumeAudioContext?.();
|
|
8008
|
+
const z = w.current || { lipsyncLang: "en" };
|
|
8009
|
+
u.current?.speakText(v, { ...R, lipsyncLang: R.lipsyncLang || z.lipsyncLang });
|
|
7796
8010
|
},
|
|
7797
8011
|
resumeAudioContext: async () => {
|
|
7798
|
-
if (
|
|
7799
|
-
return await
|
|
7800
|
-
const
|
|
7801
|
-
if (
|
|
7802
|
-
const R =
|
|
8012
|
+
if (u.current?.resumeAudioContext)
|
|
8013
|
+
return await u.current.resumeAudioContext();
|
|
8014
|
+
const v = u.current?.talkingHead;
|
|
8015
|
+
if (v?.audioCtx) {
|
|
8016
|
+
const R = v.audioCtx;
|
|
7803
8017
|
if (R.state === "suspended" || R.state === "interrupted")
|
|
7804
8018
|
try {
|
|
7805
8019
|
await R.resume(), console.log("Audio context resumed via talkingHead");
|
|
7806
|
-
} catch (
|
|
7807
|
-
console.warn("Failed to resume audio context:",
|
|
8020
|
+
} catch (z) {
|
|
8021
|
+
console.warn("Failed to resume audio context:", z);
|
|
7808
8022
|
}
|
|
7809
8023
|
} else
|
|
7810
8024
|
console.warn("Audio context not available yet");
|
|
7811
8025
|
},
|
|
7812
|
-
stopSpeaking: () =>
|
|
7813
|
-
pauseSpeaking: () =>
|
|
7814
|
-
resumeSpeaking: async () => await
|
|
7815
|
-
isPaused: () =>
|
|
7816
|
-
setMood: (
|
|
7817
|
-
playAnimation: (
|
|
7818
|
-
setBodyMovement: (
|
|
7819
|
-
setMovementIntensity: (
|
|
7820
|
-
playRandomDance: () =>
|
|
7821
|
-
playReaction: (
|
|
7822
|
-
playCelebration: () =>
|
|
7823
|
-
setShowFullAvatar: (
|
|
7824
|
-
setTimingAdjustment: (
|
|
7825
|
-
lockAvatarPosition: () =>
|
|
7826
|
-
unlockAvatarPosition: () =>
|
|
8026
|
+
stopSpeaking: () => u.current?.stopSpeaking(),
|
|
8027
|
+
pauseSpeaking: () => u.current?.pauseSpeaking(),
|
|
8028
|
+
resumeSpeaking: async () => await u.current?.resumeSpeaking(),
|
|
8029
|
+
isPaused: () => u.current && typeof u.current.isPaused < "u" ? u.current.isPaused : !1,
|
|
8030
|
+
setMood: (v) => u.current?.setMood(v),
|
|
8031
|
+
playAnimation: (v, R) => u.current?.playAnimation(v, R),
|
|
8032
|
+
setBodyMovement: (v) => u.current?.setBodyMovement(v),
|
|
8033
|
+
setMovementIntensity: (v) => u.current?.setMovementIntensity(v),
|
|
8034
|
+
playRandomDance: () => u.current?.playRandomDance(),
|
|
8035
|
+
playReaction: (v) => u.current?.playReaction(v),
|
|
8036
|
+
playCelebration: () => u.current?.playCelebration(),
|
|
8037
|
+
setShowFullAvatar: (v) => u.current?.setShowFullAvatar(v),
|
|
8038
|
+
setTimingAdjustment: (v) => u.current?.setTimingAdjustment(v),
|
|
8039
|
+
lockAvatarPosition: () => u.current?.lockAvatarPosition(),
|
|
8040
|
+
unlockAvatarPosition: () => u.current?.unlockAvatarPosition(),
|
|
7827
8041
|
// Custom action trigger
|
|
7828
|
-
triggerCustomAction: (
|
|
8042
|
+
triggerCustomAction: (v, R) => {
|
|
7829
8043
|
c.current.onCustomAction({
|
|
7830
|
-
type:
|
|
8044
|
+
type: v,
|
|
7831
8045
|
...R,
|
|
7832
8046
|
state: { ...a.current }
|
|
7833
8047
|
});
|
|
7834
8048
|
},
|
|
7835
8049
|
// Responsive resize handler
|
|
7836
|
-
handleResize: () =>
|
|
8050
|
+
handleResize: () => u.current?.handleResize(),
|
|
7837
8051
|
// Avatar readiness check (always returns current value)
|
|
7838
|
-
isAvatarReady: () =>
|
|
7839
|
-
}), [
|
|
7840
|
-
const
|
|
8052
|
+
isAvatarReady: () => u.current?.isReady || !1
|
|
8053
|
+
}), [X, S, $, se, Z, K, U, oe, ee, E, f]);
|
|
8054
|
+
const O = w.current || {
|
|
7841
8055
|
avatarUrl: "/avatars/brunette.glb",
|
|
7842
8056
|
avatarBody: "F",
|
|
7843
8057
|
mood: "happy",
|
|
@@ -7850,33 +8064,33 @@ const gt = ze(({
|
|
|
7850
8064
|
showFullAvatar: !1,
|
|
7851
8065
|
animations: e
|
|
7852
8066
|
};
|
|
7853
|
-
return /* @__PURE__ */
|
|
7854
|
-
|
|
8067
|
+
return /* @__PURE__ */ me("div", { style: { width: "100%", height: "100%" }, children: /* @__PURE__ */ me(
|
|
8068
|
+
Ve,
|
|
7855
8069
|
{
|
|
7856
|
-
ref:
|
|
7857
|
-
avatarUrl:
|
|
7858
|
-
avatarBody:
|
|
7859
|
-
mood:
|
|
7860
|
-
ttsLang:
|
|
7861
|
-
ttsService:
|
|
7862
|
-
ttsVoice:
|
|
7863
|
-
ttsApiKey:
|
|
7864
|
-
bodyMovement:
|
|
7865
|
-
movementIntensity:
|
|
7866
|
-
showFullAvatar:
|
|
8070
|
+
ref: u,
|
|
8071
|
+
avatarUrl: O.avatarUrl,
|
|
8072
|
+
avatarBody: O.avatarBody,
|
|
8073
|
+
mood: O.mood,
|
|
8074
|
+
ttsLang: O.ttsLang,
|
|
8075
|
+
ttsService: O.ttsService,
|
|
8076
|
+
ttsVoice: O.ttsVoice,
|
|
8077
|
+
ttsApiKey: O.ttsApiKey,
|
|
8078
|
+
bodyMovement: O.bodyMovement,
|
|
8079
|
+
movementIntensity: O.movementIntensity,
|
|
8080
|
+
showFullAvatar: O.showFullAvatar,
|
|
7867
8081
|
cameraView: "upper",
|
|
7868
|
-
animations:
|
|
7869
|
-
onReady:
|
|
8082
|
+
animations: O.animations,
|
|
8083
|
+
onReady: le,
|
|
7870
8084
|
onLoading: () => {
|
|
7871
8085
|
},
|
|
7872
|
-
onError: (
|
|
7873
|
-
console.error("Avatar error:",
|
|
8086
|
+
onError: (v) => {
|
|
8087
|
+
console.error("Avatar error:", v);
|
|
7874
8088
|
}
|
|
7875
8089
|
}
|
|
7876
8090
|
) });
|
|
7877
8091
|
});
|
|
7878
|
-
|
|
7879
|
-
const
|
|
8092
|
+
yt.displayName = "CurriculumLearning";
|
|
8093
|
+
const Ge = {
|
|
7880
8094
|
// Code-based dance animations (no FBX required)
|
|
7881
8095
|
dance: {
|
|
7882
8096
|
name: "dance",
|
|
@@ -7979,14 +8193,15 @@ const We = {
|
|
|
7979
8193
|
duration: 5e3,
|
|
7980
8194
|
description: "Excited, energetic movement"
|
|
7981
8195
|
}
|
|
7982
|
-
},
|
|
8196
|
+
}, wt = (G) => Ge[G] || null, zt = (G) => Ge.hasOwnProperty(G);
|
|
7983
8197
|
export {
|
|
7984
|
-
|
|
7985
|
-
|
|
8198
|
+
yt as CurriculumLearning,
|
|
8199
|
+
gt as SimpleTalkingAvatar,
|
|
8200
|
+
Ve as TalkingHeadAvatar,
|
|
7986
8201
|
pt as TalkingHeadComponent,
|
|
7987
|
-
|
|
7988
|
-
|
|
7989
|
-
|
|
7990
|
-
|
|
7991
|
-
|
|
8202
|
+
Ge as animations,
|
|
8203
|
+
Fe as getActiveTTSConfig,
|
|
8204
|
+
wt as getAnimation,
|
|
8205
|
+
kt as getVoiceOptions,
|
|
8206
|
+
zt as hasAnimation
|
|
7992
8207
|
};
|