UNPKG

@spatialwalk/avatarkit

Version:

SPAvatar SDK - 3D Gaussian Splatting Avatar Rendering SDK

1,374 lines 213 kB
var en = Object.defineProperty; var tn = (r, e, t) => e in r ? en(r, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : r[e] = t; var d = (r, e, t) => tn(r, typeof e != "symbol" ? e + "" : e, t); class rn { /** * 构造函数(内部使用) * @param id 数字人 ID * @param characterMeta 角色元数据 * @param resources 资源数据 */ constructor(e, t, n) { d(this, "id"); d(this, "characterMeta"); d(this, "resources"); this.id = e, this.characterMeta = t, this.resources = n; } /** * 获取角色元数据(内部使用) * @internal */ getCharacterMeta() { return this.characterMeta; } /** * 获取资源数据(内部使用) * @internal */ getResources() { return this.resources; } } var nn = /* @__PURE__ */ ((r) => (r.CAMERA = "camera", r.ANIMATION_IDLE = "frameIdle", r.ANIMATION_MONO = "frameMono", r.AUDIO_MONO = "audioMono", r.MODEL_SHAPE = "shape", r.MODEL_GS = "gsStandard", r))(nn || {}); function Ti(r) { var e, t, n, i, a, o, s, l, g, c, u, m, v, w, y, S, x; return { camera: ((t = (e = r.camera) == null ? void 0 : e.resource) == null ? void 0 : t.remote) || null, frameIdle: ((a = (i = (n = r.animations) == null ? void 0 : n.frameIdle) == null ? void 0 : i.resource) == null ? void 0 : a.remote) || null, frameMono: ((l = (s = (o = r.animations) == null ? void 0 : o.frameMono) == null ? void 0 : s.resource) == null ? void 0 : l.remote) || null, audioMono: ((u = (c = (g = r.animations) == null ? void 0 : g.audioMono) == null ? void 0 : c.resource) == null ? void 0 : u.remote) || null, shape: ((w = (v = (m = r.models) == null ? void 0 : m.shape) == null ? void 0 : v.resource) == null ? void 0 : w.remote) || null, gsStandard: ((x = (S = (y = r.models) == null ? void 0 : y.gsStandard) == null ? void 0 : S.resource) == null ? void 0 : x.remote) || null }; } function Bi(r) { var e, t, n, i, a, o; return !!((n = (t = (e = r.animations) == null ? void 0 : e.frameMono) == null ? void 0 : t.resource) != null && n.remote && ((o = (a = (i = r.animations) == null ? void 0 : i.audioMono) == null ? void 0 : a.resource) != null && o.remote)); } function Di(r) { var e, t, n, i, a, o; try { const s = JSON.parse(r); return !!((n = (t = (e = s == null ? void 0 : s.animations) == null ? void 0 : e.frameMono) == null ? void 0 : t.resource) != null && n.remote && ((o = (a = (i = s == null ? void 0 : s.animations) == null ? void 0 : i.audioMono) == null ? void 0 : a.resource) != null && o.remote)); } catch { return !1; } } var le = /* @__PURE__ */ ((r) => (r.cn = "cn", r.us = "us", r.test = "test", r))(le || {}), oe = /* @__PURE__ */ ((r) => (r.downloading = "downloading", r.completed = "completed", r.failed = "failed", r))(oe || {}), Se = /* @__PURE__ */ ((r) => (r.disconnected = "disconnected", r.connecting = "connecting", r.connected = "connected", r.failed = "failed", r))(Se || {}), Z = /* @__PURE__ */ ((r) => (r.idle = "idle", r.active = "active", r.playing = "playing", r))(Z || {}); class se extends Error { constructor(e, t) { super(e), this.code = t, this.name = "SPAvatarError"; } } var Ie = /* @__PURE__ */ ((r) => (r.network = "network", r.external = "external", r))(Ie || {}); function an() { return typeof window > "u" ? !1 : new URLSearchParams(window.location.search).get("debug") === "1"; } function on() { return an(); } const k = { // Dynamic debug mode check (includes URL parameter) get debug() { return on(); }, camera: { position: [-0.02, -0.013, 1.5], target: [0, 0, 0], fov: 22, near: 0.01, far: 100 }, animation: { fps: 25 // 动画帧率(从 CharacterMeta 加载动画资源) }, audio: { sampleRate: 16e3 // 音频采样率(后端要求 16kHz) }, // FLAME 全局模板资源 CDN // 这些资源是所有角色共享的基础模板 flame: { cdnBaseUrl: "https://cdn.spatialwalk.top/public", resources: { flameModel: "model.pb", flameTemplate: "fm/template.pb", teethPb: "fm/teeth.pb", teethNpz: "teeth.npz" } } }; function Vt(r) { var e; return { translation: r.translation || [0, 0, 0], rotation: r.rotation || [0, 0, 0], neck_pose: r.neckPose || [0, 0, 0], jaw_pose: r.jawPose || [0, 0, 0], eyes_pose: r.eyePose || [0, 0, 0, 0, 0, 0], eyelid: r.eyeLid || [0, 0], expr_params: r.expression || [], shape_params: [], // Realtime doesn't provide shape params, use default has_eyelid: (((e = r.eyeLid) == null ? void 0 : e.length) || 0) > 0 }; } function ut(r) { return { translation: r.translation || [0, 0, 0], rotation: r.rotation || [0, 0, 0], neckPose: r.neck_pose || [0, 0, 0], jawPose: r.jaw_pose || [0, 0, 0], eyePose: r.eyes_pose || [0, 0, 0, 0, 0, 0], eyeLid: r.eyelid || [0, 0], expression: r.expr_params || [] }; } var $t = typeof globalThis < "u" ? globalThis : typeof window < "u" ? window : typeof global < "u" ? global : typeof self < "u" ? self : {}; function sn(r) { return r && r.__esModule && Object.prototype.hasOwnProperty.call(r, "default") ? r.default : r; } var qt = { exports: {} }, Be = { exports: {} }, dt; function ln() { return dt || (dt = 1, function(r, e) { (function(t, n) { r.exports = n(); })($t, function() { function t(y) { return !isNaN(parseFloat(y)) && isFinite(y); } function n(y) { return y.charAt(0).toUpperCase() + y.substring(1); } function i(y) { return function() { return this[y]; }; } var a = ["isConstructor", "isEval", "isNative", "isToplevel"], o = ["columnNumber", "lineNumber"], s = ["fileName", "functionName", "source"], l = ["args"], g = ["evalOrigin"], c = a.concat(o, s, l, g); function u(y) { if (y) for (var S = 0; S < c.length; S++) y[c[S]] !== void 0 && this["set" + n(c[S])](y[c[S]]); } u.prototype = { getArgs: function() { return this.args; }, setArgs: function(y) { if (Object.prototype.toString.call(y) !== "[object Array]") throw new TypeError("Args must be an Array"); this.args = y; }, getEvalOrigin: function() { return this.evalOrigin; }, setEvalOrigin: function(y) { if (y instanceof u) this.evalOrigin = y; else if (y instanceof Object) this.evalOrigin = new u(y); else throw new TypeError("Eval Origin must be an Object or StackFrame"); }, toString: function() { var y = this.getFileName() || "", S = this.getLineNumber() || "", x = this.getColumnNumber() || "", L = this.getFunctionName() || ""; return this.getIsEval() ? y ? "[eval] (" + y + ":" + S + ":" + x + ")" : "[eval]:" + S + ":" + x : L ? L + " (" + y + ":" + S + ":" + x + ")" : y + ":" + S + ":" + x; } }, u.fromString = function(S) { var x = S.indexOf("("), L = S.lastIndexOf(")"), _ = S.substring(0, x), Y = S.substring(x + 1, L).split(","), W = S.substring(L + 1); if (W.indexOf("@") === 0) var N = /@(.+?)(?::(\d+))?(?::(\d+))?$/.exec(W, ""), G = N[1], X = N[2], K = N[3]; return new u({ functionName: _, args: Y || void 0, fileName: G, lineNumber: X || void 0, columnNumber: K || void 0 }); }; for (var m = 0; m < a.length; m++) u.prototype["get" + n(a[m])] = i(a[m]), u.prototype["set" + n(a[m])] = /* @__PURE__ */ function(y) { return function(S) { this[y] = !!S; }; }(a[m]); for (var v = 0; v < o.length; v++) u.prototype["get" + n(o[v])] = i(o[v]), u.prototype["set" + n(o[v])] = /* @__PURE__ */ function(y) { return function(S) { if (!t(S)) throw new TypeError(y + " must be a Number"); this[y] = Number(S); }; }(o[v]); for (var w = 0; w < s.length; w++) u.prototype["get" + n(s[w])] = i(s[w]), u.prototype["set" + n(s[w])] = /* @__PURE__ */ function(y) { return function(S) { this[y] = String(S); }; }(s[w]); return u; }); }(Be)), Be.exports; } (function(r, e) { (function(t, n) { r.exports = n(ln()); })($t, function(n) { var i = /(^|@)\S+:\d+/, a = /^\s*at .*(\S+:\d+|\(native\))/m, o = /^(eval@)?(\[native code])?$/; return { /** * Given an Error object, extract the most information from it. * * @param {Error} error object * @return {Array} of StackFrames */ parse: function(l) { if (typeof l.stacktrace < "u" || typeof l["opera#sourceloc"] < "u") return this.parseOpera(l); if (l.stack && l.stack.match(a)) return this.parseV8OrIE(l); if (l.stack) return this.parseFFOrSafari(l); throw new Error("Cannot parse given Error object"); }, // Separate line and column numbers from a string of the form: (URI:Line:Column) extractLocation: function(l) { if (l.indexOf(":") === -1) return [l]; var g = /(.+?)(?::(\d+))?(?::(\d+))?$/, c = g.exec(l.replace(/[()]/g, "")); return [c[1], c[2] || void 0, c[3] || void 0]; }, parseV8OrIE: function(l) { var g = l.stack.split(` `).filter(function(c) { return !!c.match(a); }, this); return g.map(function(c) { c.indexOf("(eval ") > -1 && (c = c.replace(/eval code/g, "eval").replace(/(\(eval at [^()]*)|(,.*$)/g, "")); var u = c.replace(/^\s+/, "").replace(/\(eval code/g, "(").replace(/^.*?\s+/, ""), m = u.match(/ (\(.+\)$)/); u = m ? u.replace(m[0], "") : u; var v = this.extractLocation(m ? m[1] : u), w = m && u || void 0, y = ["eval", "<anonymous>"].indexOf(v[0]) > -1 ? void 0 : v[0]; return new n({ functionName: w, fileName: y, lineNumber: v[1], columnNumber: v[2], source: c }); }, this); }, parseFFOrSafari: function(l) { var g = l.stack.split(` `).filter(function(c) { return !c.match(o); }, this); return g.map(function(c) { if (c.indexOf(" > eval") > -1 && (c = c.replace(/ line (\d+)(?: > eval line \d+)* > eval:\d+:\d+/g, ":$1")), c.indexOf("@") === -1 && c.indexOf(":") === -1) return new n({ functionName: c }); var u = /((.*".+"[^@]*)?[^@]*)(?:@)/, m = c.match(u), v = m && m[1] ? m[1] : void 0, w = this.extractLocation(c.replace(u, "")); return new n({ functionName: v, fileName: w[0], lineNumber: w[1], columnNumber: w[2], source: c }); }, this); }, parseOpera: function(l) { return !l.stacktrace || l.message.indexOf(` `) > -1 && l.message.split(` `).length > l.stacktrace.split(` `).length ? this.parseOpera9(l) : l.stack ? this.parseOpera11(l) : this.parseOpera10(l); }, parseOpera9: function(l) { for (var g = /Line (\d+).*script (?:in )?(\S+)/i, c = l.message.split(` `), u = [], m = 2, v = c.length; m < v; m += 2) { var w = g.exec(c[m]); w && u.push(new n({ fileName: w[2], lineNumber: w[1], source: c[m] })); } return u; }, parseOpera10: function(l) { for (var g = /Line (\d+).*script (?:in )?(\S+)(?:: In function (\S+))?$/i, c = l.stacktrace.split(` `), u = [], m = 0, v = c.length; m < v; m += 2) { var w = g.exec(c[m]); w && u.push( new n({ functionName: w[3] || void 0, fileName: w[2], lineNumber: w[1], source: c[m] }) ); } return u; }, // Opera 10.65+ Error.stack very similar to FF/Safari parseOpera11: function(l) { var g = l.stack.split(` `).filter(function(c) { return !!c.match(i) && !c.match(/^Error created at/); }, this); return g.map(function(c) { var u = c.split("@"), m = this.extractLocation(u.pop()), v = u.shift() || "", w = v.replace(/<anonymous function(: (\w+))?>/, "$2").replace(/\([^)]*\)/g, "") || void 0, y; v.match(/\(([^)]*)\)/) && (y = v.replace(/^[^(]+\(([^)]*)\)$/, "$1")); var S = y === void 0 || y === "[arguments not available]" ? void 0 : y.split(","); return new n({ functionName: w, args: S, fileName: m[0], lineNumber: m[1], columnNumber: m[2], source: c }); }, this); } }; }); })(qt); var cn = qt.exports; const un = /* @__PURE__ */ sn(cn); let ht = () => { var r = (() => { var e = Object.defineProperty, t = Object.getOwnPropertyDescriptor, n = Object.getOwnPropertyNames, i = Object.prototype.hasOwnProperty, a = (f, p) => { for (var A in p) e(f, A, { get: p[A], enumerable: !0 }); }, o = (f, p, A, C) => { if (p && typeof p == "object" || typeof p == "function") for (let E of n(p)) !i.call(f, E) && E !== A && e(f, E, { get: () => p[E], enumerable: !(C = t(p, E)) || C.enumerable }); return f; }, s = (f) => o(e({}, "__esModule", { value: !0 }), f), l = {}; a(l, { default: () => Xr }); var g = (f) => Array.isArray(f), c = (f) => typeof f == "function", u = (f) => f.length === 0, m = (f) => typeof f == "number", v = (f) => typeof f == "object" && f !== null, w = (f) => f instanceof RegExp, y = (f) => typeof f == "string", S = (f) => f === void 0, x = (f) => { const p = /* @__PURE__ */ new Map(); return (A) => { const C = p.get(A); if (C) return C; const E = f(A); return p.set(A, E), E; }; }, L = (f, p, A = {}) => { const C = { cache: {}, input: f, index: 0, indexMax: 0, options: A, output: [] }; if (z(p)(C) && C.index === f.length) return C.output; throw new Error(`Failed to parse at index ${C.indexMax}`); }, _ = (f, p) => g(f) ? Y(f, p) : y(f) ? N(f, p) : W(f, p), Y = (f, p) => { const A = {}; for (const C of f) { if (C.length !== 1) throw new Error(`Invalid character: "${C}"`); const E = C.charCodeAt(0); A[E] = !0; } return (C) => { const E = C.index, P = C.input; for (; C.index < P.length && P.charCodeAt(C.index) in A; ) C.index += 1; const R = C.index; if (R > E) { if (!S(p) && !C.options.silent) { const q = C.input.slice(E, R), j = c(p) ? p(q, P, String(E)) : p; S(j) || C.output.push(j); } C.indexMax = Math.max(C.indexMax, C.index); } return !0; }; }, W = (f, p) => { const A = f.source, C = f.flags.replace(/y|$/, "y"), E = new RegExp(A, C); return ne((P) => { E.lastIndex = P.index; const R = E.exec(P.input); if (R) { if (!S(p) && !P.options.silent) { const q = c(p) ? p(...R, P.input, String(P.index)) : p; S(q) || P.output.push(q); } return P.index += R[0].length, P.indexMax = Math.max(P.indexMax, P.index), !0; } else return !1; }); }, N = (f, p) => (A) => { if (A.input.startsWith(f, A.index)) { if (!S(p) && !A.options.silent) { const C = c(p) ? p(f, A.input, String(A.index)) : p; S(C) || A.output.push(C); } return A.index += f.length, A.indexMax = Math.max(A.indexMax, A.index), !0; } else return !1; }, G = (f, p, A, C) => { const E = z(f); return ne(de(we((P) => { let R = 0; for (; R < A; ) { const q = P.index; if (!E(P) || (R += 1, P.index === q)) break; } return R >= p; }))); }, X = (f, p) => G(f, 0, 1), K = (f, p) => G(f, 0, 1 / 0), re = (f, p) => { const A = f.map(z); return ne(de(we((C) => { for (let E = 0, P = A.length; E < P; E++) if (!A[E](C)) return !1; return !0; }))); }, U = (f, p) => { const A = f.map(z); return ne(de((C) => { for (let E = 0, P = A.length; E < P; E++) if (A[E](C)) return !0; return !1; })); }, we = (f, p = !1) => { const A = z(f); return (C) => { const E = C.index, P = C.output.length, R = A(C); return (!R || p) && (C.index = E, C.output.length !== P && (C.output.length = P)), R; }; }, de = (f, p) => z(f), ne = /* @__PURE__ */ (() => { let f = 0; return (p) => { const A = z(p), C = f += 1; return (E) => { var ot; var P; if (E.options.memoization === !1) return A(E); const R = E.index, q = (P = E.cache)[C] || (P[C] = /* @__PURE__ */ new Map()), j = q.get(R); if (j === !1) return !1; if (m(j)) return E.index = j, !0; if (j) return E.index = j.index, (ot = j.output) != null && ot.length && E.output.push(...j.output), !0; { const st = E.output.length; if (A(E)) { const lt = E.index, ct = E.output.length; if (ct > st) { const Qr = E.output.slice(st, ct); q.set(R, { index: lt, output: Qr }); } else q.set(R, lt); return !0; } else return q.set(R, !1), !1; } }; }; })(), T = (f) => { let p; return (A) => (p || (p = z(f())), p(A)); }, z = x((f) => { if (c(f)) return u(f) ? T(f) : f; if (y(f) || w(f)) return _(f); if (g(f)) return re(f); if (v(f)) return U(Object.values(f)); throw new Error("Invalid rule"); }), ie = "abcdefghijklmnopqrstuvwxyz", Fe = (f) => { let p = ""; for (; f > 0; ) { const A = (f - 1) % 26; p = ie[A] + p, f = Math.floor((f - 1) / 26); } return p; }, $ = (f) => { let p = 0; for (let A = 0, C = f.length; A < C; A++) p = p * 26 + ie.indexOf(f[A]) + 1; return p; }, Re = (f, p) => { if (p < f) return Re(p, f); const A = []; for (; f <= p; ) A.push(f++); return A; }, ir = (f, p, A) => Re(f, p).map((C) => String(C).padStart(A, "0")), Ye = (f, p) => Re($(f), $(p)).map(Fe), J = (f) => f, Xe = (f) => ar((p) => L(p, f, { memoization: !1 }).join("")), ar = (f) => { const p = {}; return (A) => p[A] ?? (p[A] = f(A)); }, or = _(/^\*\*\/\*$/, ".*"), sr = _(/^\*\*\/(\*)?([ a-zA-Z0-9._-]+)$/, (f, p, A) => `.*${p ? "" : "(?:^|/)"}${A.replaceAll(".", "\\.")}`), lr = _(/^\*\*\/(\*)?([ a-zA-Z0-9._-]*)\{([ a-zA-Z0-9._-]+(?:,[ a-zA-Z0-9._-]+)*)\}$/, (f, p, A, C) => `.*${p ? "" : "(?:^|/)"}${A.replaceAll(".", "\\.")}(?:${C.replaceAll(",", "|").replaceAll(".", "\\.")})`), Le = _(/\\./, J), cr = _(/[$.*+?^(){}[\]\|]/, (f) => `\\${f}`), ur = _(/./, J), dr = _(/^(?:!!)*!(.*)$/, (f, p) => `(?!^${at(p)}$).*?`), hr = _(/^(!!)+/, ""), fr = U([dr, hr]), mr = _(/\/(\*\*\/)+/, "(?:/.+/|/)"), gr = _(/^(\*\*\/)+/, "(?:^|.*/)"), pr = _(/\/(\*\*)$/, "(?:/.*|$)"), vr = _(/\*\*/, ".*"), Qe = U([mr, gr, pr, vr]), wr = _(/\*\/(?!\*\*\/)/, "[^/]*/"), yr = _(/\*/, "[^/]*"), et = U([wr, yr]), tt = _("?", "[^/]"), Ar = _("[", J), Sr = _("]", J), br = _(/[!^]/, "^/"), Cr = _(/[a-z]-[a-z]|[0-9]-[0-9]/i, J), _r = _(/[$.*+?^(){}[\|]/, (f) => `\\${f}`), Er = _(/[^\]]/, J), xr = U([Le, _r, Cr, Er]), rt = re([Ar, X(br), K(xr), Sr]), Pr = _("{", "(?:"), Ir = _("}", ")"), kr = _(/(\d+)\.\.(\d+)/, (f, p, A) => ir(+p, +A, Math.min(p.length, A.length)).join("|")), Mr = _(/([a-z]+)\.\.([a-z]+)/, (f, p, A) => Ye(p, A).join("|")), Fr = _(/([A-Z]+)\.\.([A-Z]+)/, (f, p, A) => Ye(p.toLowerCase(), A.toLowerCase()).join("|").toUpperCase()), Rr = U([kr, Mr, Fr]), nt = re([Pr, Rr, Ir]), Lr = _("{", "(?:"), Tr = _("}", ")"), Br = _(",", "|"), Dr = _(/[$.*+?^(){[\]\|]/, (f) => `\\${f}`), Or = _(/[^}]/, J), Nr = T(() => it), Ur = U([Qe, et, tt, rt, nt, Nr, Le, Dr, Br, Or]), it = re([Lr, K(Ur), Tr]), zr = K(U([or, sr, lr, fr, Qe, et, tt, rt, nt, it, Le, cr, ur])), Vr = zr, $r = Xe(Vr), at = $r, qr = _(/\\./, J), Wr = _(/./, J), Gr = _(/\*\*\*+/, "*"), jr = _(/([^/{[(!])\*\*/, (f, p) => `${p}*`), Hr = _(/(^|.)\*\*(?=[^*/)\]}])/, (f, p) => `${p}*`), Kr = K(U([qr, Gr, jr, Hr, Wr])), Jr = Kr, Zr = Xe(Jr), Yr = Zr, Te = (f, p) => { const A = Array.isArray(f) ? f : [f]; if (!A.length) return !1; const C = A.map(Te.compile), E = A.every((R) => /(\/(?:\*\*)?|\[\/\])$/.test(R)), P = p.replace(/[\\\/]+/g, "/").replace(/\/$/, E ? "/" : ""); return C.some((R) => R.test(P)); }; Te.compile = (f) => new RegExp(`^${at(Yr(f))}$`, "s"); var Xr = Te; return s(l); })(); return r.default || r; }, De; const dn = (r, e) => (De || (De = ht(), ht = null), De(r, e)), hn = /^[A-Za-z]:\//; function ce(r = "") { return r && r.replace(/\\/g, "/").replace(hn, (e) => e.toUpperCase()); } const fn = /^[/\\]{2}/, mn = /^[/\\](?![/\\])|^[/\\]{2}(?!\.)|^[A-Za-z]:[/\\]/, Wt = /^[A-Za-z]:$/, ft = /^\/([A-Za-z]:)?$/, gn = /.(\.[^./]+|\.)$/, pn = /^[/\\]|^[a-zA-Z]:[/\\]/, vn = "/", je = function(r) { if (r.length === 0) return "."; r = ce(r); const e = r.match(fn), t = ve(r), n = r[r.length - 1] === "/"; return r = He(r, !t), r.length === 0 ? t ? "/" : n ? "./" : "." : (n && (r += "/"), Wt.test(r) && (r += "/"), e ? t ? `//${r}` : `//./${r}` : t && !ve(r) ? `/${r}` : r); }, wn = function(...r) { let e = ""; for (const t of r) if (t) if (e.length > 0) { const n = e[e.length - 1] === "/", i = t[0] === "/"; n && i ? e += t.slice(1) : e += n || i ? t : `/${t}`; } else e += t; return je(e); }; function yn() { return typeof process < "u" && typeof process.cwd == "function" ? process.cwd().replace(/\\/g, "/") : "/"; } const ke = function(...r) { r = r.map((n) => ce(n)); let e = "", t = !1; for (let n = r.length - 1; n >= -1 && !t; n--) { const i = n >= 0 ? r[n] : yn(); !i || i.length === 0 || (e = `${i}/${e}`, t = ve(i)); } return e = He(e, !t), t && !ve(e) ? `/${e}` : e.length > 0 ? e : "."; }; function He(r, e) { let t = "", n = 0, i = -1, a = 0, o = null; for (let s = 0; s <= r.length; ++s) { if (s < r.length) o = r[s]; else { if (o === "/") break; o = "/"; } if (o === "/") { if (!(i === s - 1 || a === 1)) if (a === 2) { if (t.length < 2 || n !== 2 || t[t.length - 1] !== "." || t[t.length - 2] !== ".") { if (t.length > 2) { const l = t.lastIndexOf("/"); l === -1 ? (t = "", n = 0) : (t = t.slice(0, l), n = t.length - 1 - t.lastIndexOf("/")), i = s, a = 0; continue; } else if (t.length > 0) { t = "", n = 0, i = s, a = 0; continue; } } e && (t += t.length > 0 ? "/.." : "..", n = 2); } else t.length > 0 ? t += `/${r.slice(i + 1, s)}` : t = r.slice(i + 1, s), n = s - i - 1; i = s, a = 0; } else o === "." && a !== -1 ? ++a : a = -1; } return t; } const ve = function(r) { return mn.test(r); }, An = function(r) { return ce(r); }, Gt = function(r) { if (r === "..") return ""; const e = gn.exec(ce(r)); return e && e[1] || ""; }, Sn = function(r, e) { const t = ke(r).replace(ft, "$1").split("/"), n = ke(e).replace(ft, "$1").split("/"); if (n[0][1] === ":" && t[0][1] === ":" && t[0] !== n[0]) return n.join("/"); const i = [...t]; for (const a of i) { if (n[0] !== a) break; t.shift(), n.shift(); } return [...t.map(() => ".."), ...n].join("/"); }, jt = function(r) { const e = ce(r).replace(/\/$/, "").split("/").slice(0, -1); return e.length === 1 && Wt.test(e[0]) && (e[0] += "/"), e.join("/") || (ve(r) ? "/" : "."); }, bn = function(r) { const e = r.ext ? r.ext.startsWith(".") ? r.ext : `.${r.ext}` : "", t = [r.root, r.dir, r.base ?? (r.name ?? "") + e].filter( Boolean ); return ce( r.root ? ke(...t) : t.join("/") ); }, Ht = function(r, e) { const t = ce(r).split("/"); let n = ""; for (let i = t.length - 1; i >= 0; i--) { const a = t[i]; if (a) { n = a; break; } } return e && n.endsWith(e) ? n.slice(0, -e.length) : n; }, Cn = function(r) { var i, a; const e = ((a = (i = pn.exec(r)) == null ? void 0 : i[0]) == null ? void 0 : a.replace(/\\/g, "/")) || "", t = Ht(r), n = Gt(t); return { root: e, dir: jt(r), base: t, ext: n, name: t.slice(0, t.length - n.length) }; }, _n = (r, e) => dn(e, je(r)), mt = { __proto__: null, basename: Ht, dirname: jt, extname: Gt, format: bn, isAbsolute: ve, join: wn, matchesGlob: _n, normalize: je, normalizeString: He, parse: Cn, relative: Sn, resolve: ke, sep: vn, toNamespacedPath: An }, En = /* @__PURE__ */ (() => { var r; return ((r = globalThis.process) == null ? void 0 : r.platform) === "win32" ? ";" : ":"; })(), xn = { posix: void 0, win32: void 0 }, Kt = (r = En) => new Proxy(mt, { get(e, t) { return t === "delimiter" ? r : t === "posix" ? $e : t === "win32" ? Pn : xn[t] || mt[t]; } }), $e = /* @__PURE__ */ Kt(":"), Pn = /* @__PURE__ */ Kt(";"); var M = /* @__PURE__ */ ((r) => (r[r.Error = 0] = "Error", r[r.Warning = 1] = "Warning", r[r.Log = 2] = "Log", r[r.Verbose = 3] = "Verbose", r[r.Debug = 4] = "Debug", r))(M || {}), I = /* @__PURE__ */ ((r) => (r.Error = "error", r.Warning = "warn", r.Log = "log", r.Verbose = "verbose", r.Debug = "debug", r))(I || {}), te = /* @__PURE__ */ ((r) => (r.JSON = "json", r.Pretty = "pretty", r))(te || {}); const In = !0; function F(r, e, t = r) { return (n) => { const i = `${n}`, a = i.indexOf(e, r.length); return ~a ? r + Jt(i, e, t, a) + e : r + i + e; }; } function Jt(r, e, t, n) { const i = r.substring(0, n) + t, a = r.substring(n + e.length), o = a.indexOf(e); return ~o ? i + Jt(a, e, t, o) : i + a; } function kn(r = In) { return { isColorSupported: r, reset: r ? (e) => `\x1B[0m${e}\x1B[0m` : String, bold: r ? F("\x1B[1m", "\x1B[22m", "\x1B[22m\x1B[1m") : String, dim: r ? F("\x1B[2m", "\x1B[22m", "\x1B[22m\x1B[2m") : String, italic: r ? F("\x1B[3m", "\x1B[23m") : String, underline: r ? F("\x1B[4m", "\x1B[24m") : String, inverse: r ? F("\x1B[7m", "\x1B[27m") : String, hidden: r ? F("\x1B[8m", "\x1B[28m") : String, strikethrough: r ? F("\x1B[9m", "\x1B[29m") : String, black: r ? F("\x1B[30m", "\x1B[39m") : String, red: r ? F("\x1B[31m", "\x1B[39m") : String, green: r ? F("\x1B[32m", "\x1B[39m") : String, yellow: r ? F("\x1B[33m", "\x1B[39m") : String, blue: r ? F("\x1B[34m", "\x1B[39m") : String, magenta: r ? F("\x1B[35m", "\x1B[39m") : String, cyan: r ? F("\x1B[36m", "\x1B[39m") : String, white: r ? F("\x1B[37m", "\x1B[39m") : String, gray: r ? F("\x1B[90m", "\x1B[39m") : String, bgBlack: r ? F("\x1B[40m", "\x1B[49m") : String, bgRed: r ? F("\x1B[41m", "\x1B[49m") : String, bgGreen: r ? F("\x1B[42m", "\x1B[49m") : String, bgYellow: r ? F("\x1B[43m", "\x1B[49m") : String, bgBlue: r ? F("\x1B[44m", "\x1B[49m") : String, bgMagenta: r ? F("\x1B[45m", "\x1B[49m") : String, bgCyan: r ? F("\x1B[46m", "\x1B[49m") : String, bgWhite: r ? F("\x1B[47m", "\x1B[49m") : String }; } const B = kn(), qe = { [I.Error]: M.Error, [I.Warning]: M.Warning, [I.Log]: M.Log, [I.Verbose]: M.Verbose, [I.Debug]: M.Debug }, Mn = { [M.Error]: I.Error, [M.Warning]: I.Warning, [M.Log]: I.Log, [M.Verbose]: I.Verbose, [M.Debug]: I.Debug }, gt = [ I.Error, I.Warning, I.Log, I.Verbose, I.Debug ], Fn = { [M.Error]: B.red, [M.Warning]: B.yellow, [M.Log]: B.blue, [M.Verbose]: B.cyan, [M.Debug]: B.green }, pt = [ M.Error, M.Warning, M.Log, M.Verbose, M.Debug ], vt = [te.JSON, te.Pretty]; function Rn(r) { return r.stack == null ? [] : r.stack.split(` `).map((e) => e.trim()).slice(1).filter((e) => !!/^at (.*)( \(.*:(\d+):(\d+)\))|at (.*)(:(\d+):(\d+))/i.exec(e)).map((e) => { const t = /at (.*)( \((.*):(\d+):(\d+)\))|at (.*)(:(\d+):(\d+))/i.exec(e); return t ? typeof t[1] < "u" && typeof t[2] < "u" && typeof t[3] < "u" && typeof t[4] < "u" && typeof t[5] < "u" ? { invalid: !1, function: t[1] ?? "", file: t[3] ?? "", line: Number.parseInt(t[4] ?? "0"), column: Number.parseInt(t[5] ?? "0") } : typeof t[6] < "u" && typeof t[7] < "u" && typeof t[8] < "u" && typeof t[9] < "u" ? { invalid: !1, function: t[6] ?? "", file: t[7] ?? "", line: Number.parseInt(t[8] ?? "0"), column: Number.parseInt(t[9] ?? "0") } : { invalid: !0 } : { invalid: !0 }; }); } function Zt(r) { return r == null ? !1 : r instanceof Error; } function Yt(r, e, t, n, i) { let a = { context: "" }; typeof t < "u" && t !== null && (a = { ...t }), typeof e < "u" && e !== null && (a.context = e); const o = /* @__PURE__ */ new Date(); return { "@timestamp": o.getTime(), "@localetime": i ? i(o) : o.toISOString(), level: r, fields: a, message: n }; } function Ln(r, e, t, n, i, a) { const o = Yt(r, e, t, n, a); return typeof i < "u" && i !== null && (o.errored = !0, o.error = { stack: i }), o; } function wt(r) { let e = ""; switch (typeof r) { case "number": e = B.yellow(r); break; case "object": e = B.green(JSON.stringify(r)); break; case "boolean": e = B.yellow(String(r)); break; case "undefined": e = B.gray("undefined"); break; default: e = String(r); break; } return e; } function Ee(r) { const e = []; e.push(r["@localetime"]), e.push( Fn[qe[r.level]]( `[${r.level}]` ) ); let t = ""; r.fields.isNestSystemModule != null && (t = B.magenta(`[${r.fields.nestSystemModule}]`), delete r.fields.isNestSystemModule, delete r.fields.nestSystemModule), r.fields.context != null && (t = B.magenta(`[${r.fields.context}]`), delete r.fields.context), t.length > 0 && e.push(t), "module" in r.fields && r.fields.module != null && (e.push(B.magenta(`[${r.fields.module}]`)), delete r.fields.module), e.push(r.message); const n = Object.entries(r.fields); n.length > 0 && e.push(" {"); for (const [a, o] of n) { let s = o; if (Zt(o)) { if (o.message && (s = wt(o.message)), s || (s = ""), o.cause != null) try { s += JSON.stringify(o.cause); } catch { s += String(o.cause); } } else s = wt(o); e.push(`${B.gray(a)}${B.gray("=")}${s}`); } n.length > 0 && e.push("}"); let i = e.join(" "); return r.errored != null && r.errored && r.error && r.error.stack != null && r.error.stack && (i += ` ${r.error.stack}`), i; } function Tn(r) { return r >= M.Debug; } function Bn(r) { return r >= M.Verbose; } function Dn(r) { return r >= M.Log; } function On(r) { return r >= M.Warning; } function Nn(r) { return r >= M.Error; } function Xt() { return typeof window < "u"; } function Un() { return !Xt() && We() === te.Pretty; } function zn(r, e) { return Un() ? `\x1B]8;;file://${r}\x1B\\${e}\x1B]8;;\x1B\\` : e; } const Ke = { logLevel: M.Debug, format: te.JSON, timeFormatter: (r) => r.toISOString() }; function yt() { return Ke.logLevel; } function We() { return Ke.format; } function Vn() { return Ke.timeFormatter; } function Qt(r) { const e = { fields: {}, context: r, logLevel: M.Debug, format: te.JSON, shouldUseGlobalConfig: !1, errorProcessor: (c) => c, timeFormatter: (c) => c.toISOString(), useGlobalConfig: () => (e.shouldUseGlobalConfig = !0, e.format = We(), e.logLevel = yt(), e.child()), child: (c) => { const u = Qt(e.context); return c != null ? u.fields = { ...e.fields, ...c } : u.fields = e.fields, u.fields != null && "context" in u.fields ? u.context = u.fields.context : u.context = e.context, u.logLevel = e.logLevel, u.format = e.format, u.shouldUseGlobalConfig = e.shouldUseGlobalConfig, u; }, withContext: (c) => { const u = e.child(); return u.context = c, u; }, withLogLevel: (c) => { const u = e.child(); if (pt.includes(c)) u.logLevel = c, u.shouldUseGlobalConfig = !1, u.debug( `setting log level to ${Mn[c]} (${c})` ); else throw new Error( `log level ${c} is not available. available log levels are: ${pt.join( ", " )}` ); return u; }, withLogLevelString: (c) => { const u = e.child(); if (gt.includes(c)) u.logLevel = qe[c], u.shouldUseGlobalConfig = !1, u.debug( `setting log level to ${c} (${qe[c]})` ); else throw new Error( `log level ${c} is not available. available log levels are: ${gt.join( ", " )}` ); return u; }, withFormat: (c) => { const u = e.child(); if (vt.includes(c)) u.format = c, u.shouldUseGlobalConfig = !1, u.debug(`setting format to ${c}`); else throw new Error( `format ${c} is not available. available formats are: ${vt.join( ", " )}` ); return u; }, withFields: (c) => typeof c > "u" || c === null ? e.child({}) : e.child(c), withField(c, u) { if (typeof c > "u" || c === null) throw new Error("key is required"); return e.child({ [c]: u }); }, withError: (c) => { if (c = e.errorProcessor(c), !Zt(c)) return e.withField("error", String(c)); let u = e; if (u = u.withField("error", c.message), c.stack != null && (u = u.withField("stack", c.stack)), c.cause != null) try { u = u.withField("cause", JSON.stringify(c.cause)); } catch { u = u.withField("cause", String(c.cause)); } return u; }, withCallStack(c) { const u = Rn(c).slice(2).filter((m) => !m.invalid); return u.length === 0 ? e : e.child({ function: u[0].function, file: `${u[0].file}:${u[0].line}:${u[0].column}`, line: u[0].line, column: u[0].column }); }, // Placeholder implementations, will be overridden below debug: () => { }, verbose: () => { }, log: () => { }, error: () => { }, errorWithError: () => { }, warn: () => { }, // TODO: remove in next major release withTimeFormat: (c) => e.child(), withTimeFormatter: (c) => { const u = e.child(); return u.timeFormatter = c, u; }, withErrorProcessor: (c) => { const u = e.child(); return u.errorProcessor = c, u; } }, t = () => e.shouldUseGlobalConfig ? yt() : e.logLevel, n = () => e.shouldUseGlobalConfig ? We() : e.format, i = () => e.shouldUseGlobalConfig ? Vn() : e.timeFormatter ?? ((c) => c.toISOString()), a = (c) => c != null && c.length > 0 ? Object.keys(e.fields).length > 0 ? [e.fields, ...c] : c : e.fields, o = (c, u, m) => { const v = n(); if (Xt() && v === te.Pretty) { c.fields = Object.fromEntries( Object.entries(c.fields).filter(([S, x]) => { if (S === "isNestSystemModule" || S === "nestSystemModule" || S === "context") return [S, x]; }) ); const y = m ?? e.fields; Array.isArray(y) && y.length > 0 ? console[u](Ee(c), ...y) : Object.keys(y).length > 0 ? console[u](Ee(c), y) : console[u](Ee(c)); return; } const w = v === te.Pretty ? Ee(c) : JSON.stringify(c); console[u](w); }, s = { [I.Debug]: Tn, [I.Verbose]: Bn, [I.Log]: Dn, [I.Warning]: On }, l = { [I.Debug]: "debug", [I.Verbose]: "log", [I.Log]: "log", [I.Warning]: "warn" }, g = (c, u, m) => { const v = t(), w = s[c]; if (!w(v)) return; const y = a(m), S = Yt( c, e.context, y, u, i() ); o(S, l[c], y); }; return e.debug = (c, ...u) => { g(I.Debug, c, u); }, e.verbose = (c, ...u) => { g(I.Verbose, c, u); }, e.log = (c, ...u) => { g(I.Log, c, u); }, e.warn = (c, ...u) => { g(I.Warning, c, u); }, e.error = (c, u, ...m) => { const v = t(); if (!Nn(v)) return; const w = a(m), y = Ln( I.Error, e.context, w, c, u, i() ); o(y, "error", w); }, e.errorWithError = (c, u, ...m) => e.withError(u).error(c, void 0, ...m), e; } function $n(r) { var a; const t = un.parse(new Error())[1], n = ((a = t.fileName) == null ? void 0 : a.replace("async", "").trim()) ?? "", i = $e.join(...n.split($e.sep).slice(-2)); return r = r ?? `${i}:${t.lineNumber}`, Qt(zn(n, r)); } const qn = (r) => $n(r).useGlobalConfig(); let Q = []; const At = 100; async function Wn() { if (Q.length === 0) return; const r = [...Q]; Q = []; try { await Gn(); } catch (e) { h.warn("[CLS] Failed to flush logs:", e instanceof Error ? e.message : String(e)), Q.unshift(...r), Q.length > At && (Q = Q.slice(0, At)); } } async function Gn(r) { } function jn() { Q.length > 0 && Wn(), h.log("[CLS] Cleaned up"); } const h = qn("Web").withErrorProcessor((r) => r).useGlobalConfig(), D = { config: null, promise: null }; async function Hn(r) { return D.promise ? (await D.promise, D.config || {}) : D.config ? D.config : (D.promise = (async () => { try { const t = typeof window < "u" && (window.location.hostname === "localhost" || window.location.hostname === "127.0.0.1") ? `/api/config/sdk?version=${r}` : `https://config.spatialwalk.top/sdk?version=${r}`; h.log(`[SdkConfigLoader] Fetching SDK config from: ${t}`); const n = await fetch(t, { method: "GET", headers: { "Content-Type": "application/json" } }); if (!n.ok) throw new Error(`HTTP ${n.status} ${n.statusText}`); const i = await n.json(); if (!i.endpoints) throw new Error("Invalid config response: missing endpoints"); const a = {}; i.endpoints.cn && (a[le.cn] = `https://${i.endpoints.cn}`), i.endpoints.us && (a[le.us] = `https://${i.endpoints.us}`), i.endpoints.test && (a[le.test] = `https://${i.endpoints.test}`), D.config = a, h.log("[SdkConfigLoader] SDK config fetched successfully:", a); } catch (e) { h.warn("[SdkConfigLoader] Failed to fetch SDK config:", e instanceof Error ? e.message : String(e)), D.config = {}; } finally { D.promise = null; } })(), await D.promise, D.config || {}); } function Kn() { D.config = null, D.promise = null; } class Jn { constructor(e) { d(this, "module"); d(this, "allocatedPointers"); d(this, "structPointers"); this.module = e, this.allocatedPointers = /* @__PURE__ */ new Set(), this.structPointers = /* @__PURE__ */ new Map(); } /** * 分配 WASM 内存并复制数据 - 纯 API 方式 */ allocateAndCopy(e) { const t = e.byteLength, n = this.module._malloc(t); if (!n) throw new Error(`Failed to allocate ${t} bytes in WASM memory`); const i = new Uint8Array(e); return this.module.writeArrayToMemory(i, n), this.allocatedPointers.add(n), { ptr: n, size: t }; } /** * 创建 AvatarTemplateConfig 结构体 */ createTemplateConfig(e) { const n = this.module._malloc(40); if (!n) throw new Error("Failed to allocate AvatarTemplateConfig structure"); if (!e.flameModel || e.flameModel.byteLength === 0) throw new Error("flameModel is missing or empty!"); if (!e.flameTemplate || e.flameTemplate.byteLength === 0) throw new Error("flameTemplate is missing or empty!"); if (!e.teethPb || e.teethPb.byteLength === 0) throw new Error("teethPb is missing or empty!"); if (!e.teethNpz || e.teethNpz.byteLength === 0) throw new Error("teethNpz is missing or empty!"); const i = this.allocateAndCopy(e.flameModel), a = this.allocateAndCopy(e.flameTemplate), o = this.allocateAndCopy(e.teethPb), s = this.allocateAndCopy(e.teethNpz); let l = 0; return this.module.setValue(n + l, i.ptr, "i32"), l += 4, this.module.setValue(n + l, i.size, "i32"), l += 4, this.module.setValue(n + l, a.ptr, "i32"), l += 4, this.module.setValue(n + l, a.size, "i32"), l += 4, this.module.setValue(n + l, o.ptr, "i32"), l += 4, this.module.setValue(n + l, o.size, "i32"), l += 4, this.module.setValue(n + l, s.ptr, "i32"), l += 4, this.module.setValue(n + l, s.size, "i32"), l += 4, this.module.setValue(n + l, 0, "i32"), l += 4, this.module.setValue(n + l, 0, "i32"), l += 4, this.structPointers.set("template_config", n), n; } /** * 创建 AvatarCharacterData 结构体 - 新版 Emscripten 方式 */ createCharacterData(e, t) { const i = this.module._malloc(16); if (!i) throw new Error("Failed to allocate AvatarCharacterData structure"); const a = this.allocateAndCopy(e), o = this.allocateAndCopy(t); let s = 0; return this.module.setValue(i + s, a.ptr, "i32"), s += 4, this.module.setValue(i + s, a.size, "i32"), s += 4, this.module.setValue(i + s, o.ptr, "i32"), s += 4, this.module.setValue(i + s, o.size, "i32"), s += 4, this.structPointers.set("character_data", i), i; } /** * 读取 AvatarFlameParams 结构体数据 * Used to extract current animation frame parameters from WASM memory */ readFlameParams(e) { let t = 0; const n = []; for (let m = 0; m < 300; m++) n.push(this.module.getValue(e + t, "float")), t += 4; const i = []; for (let m = 0; m < 100; m++) i.push(this.module.getValue(e + t, "float")), t += 4; const a = []; for (let m = 0; m < 3; m++) a.push(this.module.getValue(e + t, "float")), t += 4; const o = []; for (let m = 0; m < 3; m++) o.push(this.module.getValue(e + t, "float")), t += 4; const s = []; for (let m = 0; m < 3; m++) s.push(this.module.getValue(e + t, "float")), t += 4; const l = []; for (let m = 0; m < 3; m++) l.push(this.module.getValue(e + t, "float")), t += 4; const g = []; for (let m = 0; m < 6; m++) g.push(this.module.getValue(e + t, "float")), t += 4; const c = []; for (let m = 0; m < 2; m++) c.push(this.module.getValue(e + t, "float")), t += 4; const u = this.module.getValue(e + t, "i32") !== 0; return { shape_params: n, expr_params: i, rotation: a, translation: o, neck_pose: s, jaw_pose: l, eyes_pose: g, eyelid: c, has_eyelid: u }; } /** * 创建 AvatarFlameParams 结构体 - 新版 Emscripten 方式 */ createFlameParams(e) { var a, o, s, l, g, c, u, m; const n = this.module._malloc(1684); if (!n) throw new Error("Failed to allocate AvatarFlameParams structure"); let i = 0; for (let v = 0; v < 300; v++) { const w = ((a = e.shape_params) == null ? void 0 : a[v]) || 0; this.module.setValue(n + i, w, "float"), i += 4; } for (let v = 0; v < 100; v++) { const w = ((o = e.expr_params) == null ? void 0 : o[v]) || 0; this.module.setValue(n + i, w, "float"), i += 4; } for (let v = 0; v < 3; v++) { const w = ((s = e.rotation) == null ? void 0 : s[v]) || 0; this.module.setValue(n + i, w, "float"), i += 4; } for (let v = 0; v < 3; v++) { const w = ((l = e.translation) == null ? void 0 : l[v]) || 0; this.module.setValue(n + i, w, "float"), i += 4; } for (let v = 0; v < 3; v++) { const w = ((g = e.neck_pose) == null ? void 0 : g[v]) || 0; this.module.setValue(n + i, w, "float"), i += 4; } for (let v = 0; v < 3; v++) { const w = ((c = e.jaw_pose) == null ? void 0 : c[v]) || 0; this.module.setValue(n + i, w, "float"), i += 4; } for (let v = 0; v < 6; v++) { const w = ((u = e.eyes_pose) == null ? void 0 : u[v]) || 0; this.module.setValue(n + i, w, "float"), i += 4; } for (let v = 0; v < 2; v++) { const w = ((m = e.eyelid) == null ? void 0 : m[v]) || 0; this.module.setValue(n + i, w, "float"), i += 4; } return this.module.setValue(n + i, e.has_eyelid ? 1 : 0, "i32"), i += 4, n; } /** * 读取 AvatarSplatPointFlatArray 结构体数据(预计算协方差) * * 结构体布局: * - AvatarSplatPointFlat* points (0-3, 32位指针) * - uint32_t point_count (4-7) * - float compute_time_ms (8-11) * * 每个点布局 (52 bytes): * - position[3] (12 bytes) * - color[4] (16 bytes, RGBA) * - covariance[6] (24 bytes, 预计算好的协方差矩阵上三角) * * ⚠️ 使用 getValue 逐个读取,避免动态内存的 HEAPF32 detachment 问题 */ readSplatPointFlatArray(e) { if (!e) throw new Error("Invalid array pointer"); const t = this.module.getValue(e, "i32"), n = this.module.getValue(e + 4, "i32"); if (n === 0 || !t) return null; const a = n * 13, o = t / 4, s = new Float32Array(a); return s.set(this.module.HEAPF32.subarray(o, o + a)), s; } /** * 读取AvatarMeshData结构体数据 */ readMeshData(e) { const t = this.module.getValue(e + 0, "*"), n = this.module.getValue(e + 4, "i32"), i = this.module.getValue(e + 8, "*"), a = this.module.getValue(e + 12, "i32"), o = this.module.getValue(e + 16, "float"), s = this.module.getValue(e + 20, "*"), l = this.module.getValue(e + 24, "i32"), g = new Float32Array(n * 3); if (t && n > 0) for (let m = 0; m < n * 3; m++) g[m] = this.module.getValue(t + m * 4, "float"); const c = new Uint32Array(a * 3); if (i && a > 0) for (let m = 0; m < a * 3; m++) c[m] = this.module.getValue(i + m * 4, "i32"); let u = null; if (s && l > 0) { u = new Float32Array(l * 3); for (let m = 0; m < l * 3; m++) u[m] = this.module.getValue(s + m * 4, "float"); } return { vertices: g, vertexCount: n, faces: c, faceCount: a, landmarks: u, landmarkCount: l, computeTime: o }; } /** * 释放指定指针的内存 */ free(e) { e && this.allocatedPointers.has(e) && (this.module._free(e), this.allocatedPointers.delete(e)); } /** * 释放结构体内存 */ freeStruct(e) { const t = this.structPointers.get(e); t && (this.module._free(t), this.structPointers.delete(e)); } /** * 清理所有分配的内存 */ cleanup() { for (const e of this.allocatedPointers) this.module._free(e); this.allocatedPointers.clear(); for (const [, e] of this.structPointers) this.module._free(e); this.structPointers.clear(); } /** * 获取内存使用统计 */ getMemoryStats() { return { allocatedPointers: this.allocatedPointers.size, structPointers: this.structPointers.size, totalAllocatedMB: Math.round(this.allocatedPointers.size * 1024 / 1024) }; } } class Zn { constructor(e = {}) { // 配置 d(this, "options"); d(this, "wasmConfig"); // 核心组件 // eslint-disable-next-line ts/no-explicit-any d(this, "wasmModule"); d(this, "memoryManager"); // Avatar Core handles d(this, "coreHandle"); d(this, "characterHandle"); d(this, "animationHandle"); d(this, "totalFrames"); // 状态管理 d(this, "isInitialized"); d(this, "isCharacterLoaded"); // C API 函数包装 // eslint-disable-next-line ts/no-explicit-any d(this, "api"); // 性能监控 d(this, "performanceMetrics"); d(this, "wasmTime", 0); // 最近一次 WASM 计算耗时 // 错误码映射 d(this, "errorCodes"); // 模型信息 d(this, "flameInfo"); d(this, "characterInfo"); this.options = { logLevel: "basic", enableValidation: !0, enablePerformanceMetrics: !0, retryCount: 3, baseAssetsPath: "/", modelFolder: "3dgs", wasmPath: "./wasm/avatar_core_wasm.wasm", ...e }, this.wasmConfig = e.wasmConfig || { baseUrl: void 0 }, this.wasmModule = null, this.memoryManager = null, this.coreHandle = null, this.characterHandle = null, this.animationHandle = null, this.totalFrames = null, this.isInitialized = !1, this.isCharacterLoaded = !1, this.api = {}, this.performanceMetrics = { initTime: 0, loadTime: 0, computeFrames: 0, totalComputeTime: 0, averageComputeTime: 0 }, this.errorCodes = { 0: "AVATAR_SUCCESS", 1: "AVATAR_ERROR_INVALID_PARAMETER", 2: "AVATAR_ERROR_MEMORY_ALLOCATION", 3: "AVATAR_ERROR_INVALID_DATA_FORMAT", 4: "AVATAR_ERROR_CHARACTER_NOT_FOUND", 5: "AVATAR_ERROR_ANIMATION_NOT_FOUND", 6: "AVATAR_ERROR_COMPUTATION_FAILED" }; } /** * 加载 WASM 模块并设置 API * 每次都创建全新的 WASM 实例,确保 C++ 内存是干净的 * * 注意:这里使用动态 import() 导入 WASM 模块。 * Vite 在构建时会自动为 WASM 文件和 JS glue 代码添加 hash(如 avatar_core_wasm-CxWuw7eS.wasm), * 确保浏览器缓存与版本一致,不会有缓存问题。 * * Hash 的作用机制: * - WASM 文件内容变化 → hash 自动变化 → URL 变化 → 浏览器拉取新版本 * - WASM 文件内容不变 → hash 保持不变 → URL 不变 → 浏览器使用缓存 * - Emscripten 生成的 JS 内部会使用 hard-coded 的 hash 路径加载 .wasm 文件 */ async loadWASMModule() { try { const { default: e } = await import("./avatar_core_wasm-D4eEi7Eh.js"); this.wasmConfig && Object.keys(this.wasmConfig).length > 0 ? this.wasmModule = await e(this.wasmConfig) : this.wasmModule = await e(), this.validateWASMModule(), this.memoryManager = new Jn(this.wasmModule), this.setupCAPIFunctions(), h.log("✅ Created new WASM instance with clean C++ memory"); } catch (e) { const t = e instanceof Error ? e.message : String(e); throw new Error(`Failed to load WASM module: ${t}`); } } /** * 验证 WASM 模块功能 */ validateWASMModule() { const e = ["cwrap", "_malloc", "_free", "setValue", "getValue", "writeArrayToMemory"]; for (const t of e) if (typeof this.wasmModule[t] != "function") throw new TypeError(`WASM module missing required function: ${t}`); this.initializeMemoryViews(); } /** * 初始化内存视图 */ initializeMemoryViews() { try { const e = this.wasmModule._malloc(4); if (!e) throw new Error("Memory allocation test failed"); con