@spatialwalk/avatarkit 1.0.0-beta.21 → 1.0.0-beta.22

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.
@@ -1 +0,0 @@
1
- {"version":3,"file":"index-ChKhyUK4.js","sources":["../core/Avatar.ts","../types/character.ts","../types/index.ts","../config/constants.ts","../config/app-config.ts","../animation/utils/flameConverter.ts","../node_modules/.pnpm/stackframe@1.3.4/node_modules/stackframe/stackframe.js","../node_modules/.pnpm/error-stack-parser@2.1.4/node_modules/error-stack-parser/error-stack-parser.js","../node_modules/.pnpm/pathe@2.0.3/node_modules/pathe/dist/shared/pathe.M-eThtNZ.mjs","../node_modules/.pnpm/pathe@2.0.3/node_modules/pathe/dist/index.mjs","../node_modules/.pnpm/@guiiai+logg@1.2.5/node_modules/@guiiai/logg/dist/index.mjs","../utils/cls-tracker.ts","../utils/logger.ts","../config/sdk-config-loader.ts","../wasm/avatarCoreMemory.ts","../wasm/avatarCoreAdapter.ts","../core/AvatarKit.ts","../audio/AnimationPlayer.ts","../node_modules/.pnpm/nanoid@5.1.6/node_modules/nanoid/index.browser.js","../utils/conversationId.ts","../node_modules/.pnpm/@bufbuild+protobuf@2.10.1/node_modules/@bufbuild/protobuf/dist/esm/wire/varint.js","../node_modules/.pnpm/@bufbuild+protobuf@2.10.1/node_modules/@bufbuild/protobuf/dist/esm/proto-int64.js","../node_modules/.pnpm/@bufbuild+protobuf@2.10.1/node_modules/@bufbuild/protobuf/dist/esm/wire/text-encoding.js","../node_modules/.pnpm/@bufbuild+protobuf@2.10.1/node_modules/@bufbuild/protobuf/dist/esm/wire/binary-encoding.js","../generated/driveningress/v1/driveningress.ts","../animation/utils/eventEmitter.ts","../animation/AnimationWebSocketClient.ts","../core/NetworkLayer.ts","../core/AvatarController.ts","../utils/error-utils.ts","../core/AvatarDownloader.ts","../core/AvatarManager.ts","../renderer/sortSplats.ts","../renderer/webgl/reorderData.ts","../renderer/webgl/fragment.glsl?raw","../renderer/webgl/vertex.glsl?raw","../renderer/webgl/webglRenderer.ts","../renderer/webgpu/render.wgsl?raw","../renderer/webgpu/webgpuRenderer.ts","../renderer/RenderSystem.ts","../utils/animation-interpolation.ts","../core/AvatarView.ts"],"sourcesContent":["/**\n * Avatar:数字人模型\n * 构造函数:not public(由 AvatarManager 加载后返回数字人模型实例)\n * 公开属性:only id(其他字段都不公开)\n */\n\nimport type { CharacterMeta } from '../types'\nimport type { PreloadResult } from './AvatarDownloader'\n\nexport class Avatar {\n public readonly id: string\n private characterMeta: CharacterMeta\n private resources: PreloadResult\n\n /**\n * 构造函数(内部使用)\n * @param id 数字人 ID\n * @param characterMeta 角色元数据\n * @param resources 资源数据\n */\n constructor(id: string, characterMeta: CharacterMeta, resources: PreloadResult) {\n this.id = id\n this.characterMeta = characterMeta\n this.resources = resources\n }\n\n /**\n * 获取角色元数据(内部使用)\n * @internal\n */\n getCharacterMeta(): CharacterMeta {\n return this.characterMeta\n }\n\n /**\n * 获取资源数据(内部使用)\n * @internal\n */\n getResources(): PreloadResult {\n return this.resources\n }\n}\n","/**\n * iOS 兼容的角色数据类型定义\n * 对齐 iOS 版本的 API 结构\n */\n\nimport type { CharacterAsset } from '../generated/driveningress/v2/driveningress'\nimport type { CameraSettings, CharacterSettings } from './character-settings'\n\n/**\n * 角色元数据\n */\nexport type CharacterMeta = CharacterAsset & {\n characterSettings?: CharacterSettings\n}\n\nexport type PreloadResources<T> = {\n version: string\n} & T\n\nexport type PreloadCameraSettings = PreloadResources<{ camera: CameraSettings }>\n\n/**\n * 资源类型枚举\n */\nexport enum ResourceType {\n CAMERA = 'camera',\n ANIMATION_IDLE = 'frameIdle',\n MODEL_SHAPE = 'shape',\n MODEL_GS = 'gsStandard',\n}\n\n/**\n * 提取所有资源 URL\n */\nexport function extractResourceUrls(meta: CharacterMeta): Record<ResourceType, string | null> {\n return {\n [ResourceType.CAMERA]: meta.camera?.resource?.remote || null,\n [ResourceType.ANIMATION_IDLE]: meta.animations?.frameIdle?.resource?.remote || null,\n [ResourceType.MODEL_SHAPE]: meta.models?.shape?.resource?.remote || null,\n [ResourceType.MODEL_GS]: meta.models?.gsStandard?.resource?.remote || null,\n }\n}\n\n","/**\n * 统一公开类型 & 接口\n */\n\n// 环境配置\nexport enum Environment {\n cn = 'cn',\n us = 'us',\n test = 'test',\n}\n\n// 驱动服务模式\nexport enum DrivingServiceMode {\n /** 由 SDK 直接驱动(网络模式) */\n sdk = 'sdk',\n /** 由宿主应用驱动(外部数据模式) */\n host = 'host',\n}\n\n// SDK 配置\nexport interface Configuration {\n readonly environment: Environment\n /** 驱动服务模式,默认为 sdk(网络模式) */\n readonly drivingServiceMode?: DrivingServiceMode\n}\n\n// SDK 配置接口响应\nexport interface SdkConfigResponse {\n endpoints: {\n cn?: string\n us?: string\n test?: string\n }\n}\n\n// 加载进度\nexport enum LoadProgress {\n downloading = 'downloading',\n completed = 'completed',\n failed = 'failed',\n}\n\nexport interface LoadProgressInfo {\n type: LoadProgress\n progress?: number // 0-100\n error?: Error\n}\n\n// 连接状态\nexport enum ConnectionState {\n disconnected = 'disconnected',\n connecting = 'connecting',\n connected = 'connected',\n failed = 'failed',\n}\n\n// 数字人状态\nexport enum AvatarState {\n idle = 'idle', // 空闲状态,呈现呼吸态\n active = 'active', // 活跃中,等待可播放内容\n playing = 'playing', // 播放中\n paused = 'paused', // 暂停中\n}\n\n// 错误类型\nexport class SPAvatarError extends Error {\n constructor(message: string, public code?: string) {\n super(message)\n this.name = 'SPAvatarError'\n }\n}\n\n// ========== 渲染相关类型 ==========\n\nexport interface FlatSplatData {\n positions: Float32Array\n scales: Float32Array\n rotations: Float32Array\n colors: Float32Array\n opacities: Float32Array\n pointCount: number\n}\n\nexport interface CameraConfig {\n position: [number, number, number]\n target: [number, number, number]\n fov: number\n near: number\n far: number\n up?: [number, number, number]\n aspect?: number\n}\n\n/**\n * 渲染性能统计\n * @internal Not part of public API yet\n */\nexport interface RenderPerformanceStats {\n renderTime: number // 总渲染耗时(毫秒)\n sortTime: number // 排序耗时(毫秒)\n backend: 'webgpu' | 'webgl' | null // 当前使用的渲染后端\n pointCount?: number // 当前渲染的点云数量\n fps?: number // 当前渲染帧率\n}\n\n// ========== 播放模式 ==========\n\n/**\n * 播放模式\n */\nexport enum AvatarPlaybackMode {\n /** 网络模式:通过 WebSocket 发送音频,接收动画数据 */\n network = 'network',\n /** 外部数据模式:外部提供音频和动画数据, SDK 负责同步播放 */\n external = 'external',\n}\n\n\n// ========== 角色相关类型 ==========\n// 从 character.ts 重新导出所有角色相关类型,避免重复定义\n\nexport * from './character'\n","import { Environment } from '../types'\n\n// 腾讯云 CLS 配置\nexport const CLS_TRACK_EVENTS = import.meta.env.VITE_CLS_TRACK_EVENTS === 'true'\n\n/**\n * 根据环境获取 CLS endpoint(对齐 iOS 端)\n */\nfunction getCLSEndpoint(environment: Environment): string {\n // 如果环境变量有配置,优先使用环境变量\n if (import.meta.env.VITE_CLS_ENDPOINT) {\n return import.meta.env.VITE_CLS_ENDPOINT\n }\n \n // 否则根据环境返回默认值(对齐 iOS)\n switch (environment) {\n case Environment.cn:\n case Environment.test:\n return 'ap-chongqing.cls.tencentcs.com'\n case Environment.us:\n return 'na-siliconvalley.cls.tencentyun.com'\n default:\n return ''\n }\n}\n\n/**\n * 根据环境获取 CLS topic ID(对齐 iOS 端)\n */\nfunction getCLSTopicId(environment: Environment): string {\n // 如果环境变量有配置,优先使用环境变量\n if (import.meta.env.VITE_CLS_TOPIC_ID) {\n return import.meta.env.VITE_CLS_TOPIC_ID\n }\n \n // 否则根据环境返回默认值(对齐 iOS)\n switch (environment) {\n case Environment.cn:\n return '7fd0301a-5045-4b77-ba25-56af21682049'\n case Environment.test:\n return '4473852a-23af-425a-b7f2-75a90a28de41'\n case Environment.us:\n return 'd8972ae5-d841-498b-9777-11f9cd90fa0f'\n default:\n return ''\n }\n}\n\n/**\n * 获取 CLS 配置(需要传入环境)\n */\nexport function getCLSConfig(environment: Environment) {\n return {\n endpoint: getCLSEndpoint(environment),\n topicId: getCLSTopicId(environment),\n secretId: import.meta.env.VITE_CLS_SECRET_ID || '',\n secretKey: import.meta.env.VITE_CLS_SECRET_KEY || '',\n token: import.meta.env.VITE_CLS_TOKEN || '',\n }\n}\n\n// 兼容旧代码(如果没有环境信息,使用环境变量或空值)\nexport const CLS_CONFIG = {\n endpoint: import.meta.env.VITE_CLS_ENDPOINT || '',\n topicId: import.meta.env.VITE_CLS_TOPIC_ID || '',\n secretId: import.meta.env.VITE_CLS_SECRET_ID || '',\n secretKey: import.meta.env.VITE_CLS_SECRET_KEY || '',\n token: import.meta.env.VITE_CLS_TOKEN || '',\n}\n\nexport const ENV_TEST = !import.meta.env.VITE_ENV_PROD && (import.meta.env.VITE_ENV_TEST === 'true' || import.meta.env.DEV)\n\n/**\n * Check if URL has debug=1 parameter\n */\nfunction hasDebugParam(): boolean {\n if (typeof window === 'undefined') {\n return false\n }\n const params = new URLSearchParams(window.location.search)\n return params.get('debug') === '1'\n}\n\n/**\n * Comprehensive debug mode check\n * Returns true if:\n * - VITE_ENV_TEST is 'true', OR\n * - Running in DEV mode, OR\n * - URL has debug=1 parameter\n */\nexport function isDebugMode(): boolean {\n return ENV_TEST || hasDebugParam()\n}\n","import { ENV_TEST, isDebugMode } from './constants'\n\nexport const APP_CONFIG = {\n testEnv: ENV_TEST,\n // Dynamic debug mode check (includes URL parameter)\n get debug() {\n return isDebugMode()\n },\n\n rendering: {\n /**\n * 排序模式\n * - 'balance': 性能优先,首帧排序后复用(默认)\n * - 'quality': 质量优先,每帧重新排序\n */\n sortMode: 'balance' as 'balance' | 'quality',\n },\n\n camera: {\n position: [-0.02, -0.013, 1.5] as [number, number, number],\n target: [0, 0, 0] as [number, number, number],\n fov: 22,\n near: 0.01,\n far: 100,\n },\n\n animation: {\n fps: 25, // 动画帧率(从 CharacterMeta 加载动画资源)\n },\n\n audio: {\n sampleRate: 16000, // 音频采样率(后端要求 16kHz)\n },\n\n avatar: {\n baseAssetsPath: '',\n wasmPath: './wasm/avatar_core_wasm.js',\n },\n\n // FLAME 全局模板资源 CDN\n // 这些资源是所有角色共享的基础模板\n flame: {\n cdnBaseUrl: 'https://cdn.spatialwalk.top/public',\n resources: {\n flameModel: 'model.pb',\n flameTemplate: 'fm/template.pb',\n teethPb: 'fm/teeth.pb',\n teethNpz: 'teeth.npz',\n },\n },\n\n wasm: {\n logLevel: 'basic' as 'basic' | 'verbose',\n enableValidation: false,\n enablePerformanceMetrics: true,\n },\n}\n","/**\n * Convert proto Flame to WASM FlameParams\n */\n\nimport type { Flame } from '../../generated/driveningress/v1/driveningress'\n\nexport interface FlameParams {\n shape_params?: number[]\n expr_params?: number[]\n rotation?: number[]\n translation?: number[]\n neck_pose?: number[]\n jaw_pose?: number[]\n eyes_pose?: number[]\n eyelid?: number[]\n has_eyelid?: boolean\n}\n\n/**\n * Convert proto Flame to WASM FlameParams format\n */\nexport function convertProtoFlameToWasmParams(protoFlame: Flame): FlameParams {\n return {\n translation: protoFlame.translation || [0, 0, 0],\n rotation: protoFlame.rotation || [0, 0, 0],\n neck_pose: protoFlame.neckPose || [0, 0, 0],\n jaw_pose: protoFlame.jawPose || [0, 0, 0],\n eyes_pose: protoFlame.eyePose || [0, 0, 0, 0, 0, 0],\n eyelid: protoFlame.eyeLid || [0, 0],\n expr_params: protoFlame.expression || [],\n shape_params: [], // Realtime doesn't provide shape params, use default\n has_eyelid: (protoFlame.eyeLid?.length || 0) > 0,\n }\n}\n\n/**\n * Convert WASM FlameParams to proto Flame format\n * Used for transition animation from idle to speaking\n */\nexport function convertWasmParamsToProtoFlame(wasmParams: FlameParams): Flame {\n return {\n translation: wasmParams.translation || [0, 0, 0],\n rotation: wasmParams.rotation || [0, 0, 0],\n neckPose: wasmParams.neck_pose || [0, 0, 0],\n jawPose: wasmParams.jaw_pose || [0, 0, 0],\n eyePose: wasmParams.eyes_pose || [0, 0, 0, 0, 0, 0],\n eyeLid: wasmParams.eyelid || [0, 0],\n expression: wasmParams.expr_params || [],\n }\n}\n\n/**\n * Create a neutral proto Flame (zero pose)\n */\nexport function createNeutralFlameProto(): Flame {\n return {\n translation: [0, 0, 0],\n rotation: [0, 0, 0],\n neckPose: [0, 0, 0],\n jawPose: [0, 0, 0],\n eyePose: [0, 0, 0, 0, 0, 0],\n eyeLid: [0, 0],\n expression: [],\n }\n}\n","(function(root, factory) {\n 'use strict';\n // Universal Module Definition (UMD) to support AMD, CommonJS/Node.js, Rhino, and browsers.\n\n /* istanbul ignore next */\n if (typeof define === 'function' && define.amd) {\n define('stackframe', [], factory);\n } else if (typeof exports === 'object') {\n module.exports = factory();\n } else {\n root.StackFrame = factory();\n }\n}(this, function() {\n 'use strict';\n function _isNumber(n) {\n return !isNaN(parseFloat(n)) && isFinite(n);\n }\n\n function _capitalize(str) {\n return str.charAt(0).toUpperCase() + str.substring(1);\n }\n\n function _getter(p) {\n return function() {\n return this[p];\n };\n }\n\n var booleanProps = ['isConstructor', 'isEval', 'isNative', 'isToplevel'];\n var numericProps = ['columnNumber', 'lineNumber'];\n var stringProps = ['fileName', 'functionName', 'source'];\n var arrayProps = ['args'];\n var objectProps = ['evalOrigin'];\n\n var props = booleanProps.concat(numericProps, stringProps, arrayProps, objectProps);\n\n function StackFrame(obj) {\n if (!obj) return;\n for (var i = 0; i < props.length; i++) {\n if (obj[props[i]] !== undefined) {\n this['set' + _capitalize(props[i])](obj[props[i]]);\n }\n }\n }\n\n StackFrame.prototype = {\n getArgs: function() {\n return this.args;\n },\n setArgs: function(v) {\n if (Object.prototype.toString.call(v) !== '[object Array]') {\n throw new TypeError('Args must be an Array');\n }\n this.args = v;\n },\n\n getEvalOrigin: function() {\n return this.evalOrigin;\n },\n setEvalOrigin: function(v) {\n if (v instanceof StackFrame) {\n this.evalOrigin = v;\n } else if (v instanceof Object) {\n this.evalOrigin = new StackFrame(v);\n } else {\n throw new TypeError('Eval Origin must be an Object or StackFrame');\n }\n },\n\n toString: function() {\n var fileName = this.getFileName() || '';\n var lineNumber = this.getLineNumber() || '';\n var columnNumber = this.getColumnNumber() || '';\n var functionName = this.getFunctionName() || '';\n if (this.getIsEval()) {\n if (fileName) {\n return '[eval] (' + fileName + ':' + lineNumber + ':' + columnNumber + ')';\n }\n return '[eval]:' + lineNumber + ':' + columnNumber;\n }\n if (functionName) {\n return functionName + ' (' + fileName + ':' + lineNumber + ':' + columnNumber + ')';\n }\n return fileName + ':' + lineNumber + ':' + columnNumber;\n }\n };\n\n StackFrame.fromString = function StackFrame$$fromString(str) {\n var argsStartIndex = str.indexOf('(');\n var argsEndIndex = str.lastIndexOf(')');\n\n var functionName = str.substring(0, argsStartIndex);\n var args = str.substring(argsStartIndex + 1, argsEndIndex).split(',');\n var locationString = str.substring(argsEndIndex + 1);\n\n if (locationString.indexOf('@') === 0) {\n var parts = /@(.+?)(?::(\\d+))?(?::(\\d+))?$/.exec(locationString, '');\n var fileName = parts[1];\n var lineNumber = parts[2];\n var columnNumber = parts[3];\n }\n\n return new StackFrame({\n functionName: functionName,\n args: args || undefined,\n fileName: fileName,\n lineNumber: lineNumber || undefined,\n columnNumber: columnNumber || undefined\n });\n };\n\n for (var i = 0; i < booleanProps.length; i++) {\n StackFrame.prototype['get' + _capitalize(booleanProps[i])] = _getter(booleanProps[i]);\n StackFrame.prototype['set' + _capitalize(booleanProps[i])] = (function(p) {\n return function(v) {\n this[p] = Boolean(v);\n };\n })(booleanProps[i]);\n }\n\n for (var j = 0; j < numericProps.length; j++) {\n StackFrame.prototype['get' + _capitalize(numericProps[j])] = _getter(numericProps[j]);\n StackFrame.prototype['set' + _capitalize(numericProps[j])] = (function(p) {\n return function(v) {\n if (!_isNumber(v)) {\n throw new TypeError(p + ' must be a Number');\n }\n this[p] = Number(v);\n };\n })(numericProps[j]);\n }\n\n for (var k = 0; k < stringProps.length; k++) {\n StackFrame.prototype['get' + _capitalize(stringProps[k])] = _getter(stringProps[k]);\n StackFrame.prototype['set' + _capitalize(stringProps[k])] = (function(p) {\n return function(v) {\n this[p] = String(v);\n };\n })(stringProps[k]);\n }\n\n return StackFrame;\n}));\n","(function(root, factory) {\n 'use strict';\n // Universal Module Definition (UMD) to support AMD, CommonJS/Node.js, Rhino, and browsers.\n\n /* istanbul ignore next */\n if (typeof define === 'function' && define.amd) {\n define('error-stack-parser', ['stackframe'], factory);\n } else if (typeof exports === 'object') {\n module.exports = factory(require('stackframe'));\n } else {\n root.ErrorStackParser = factory(root.StackFrame);\n }\n}(this, function ErrorStackParser(StackFrame) {\n 'use strict';\n\n var FIREFOX_SAFARI_STACK_REGEXP = /(^|@)\\S+:\\d+/;\n var CHROME_IE_STACK_REGEXP = /^\\s*at .*(\\S+:\\d+|\\(native\\))/m;\n var SAFARI_NATIVE_CODE_REGEXP = /^(eval@)?(\\[native code])?$/;\n\n return {\n /**\n * Given an Error object, extract the most information from it.\n *\n * @param {Error} error object\n * @return {Array} of StackFrames\n */\n parse: function ErrorStackParser$$parse(error) {\n if (typeof error.stacktrace !== 'undefined' || typeof error['opera#sourceloc'] !== 'undefined') {\n return this.parseOpera(error);\n } else if (error.stack && error.stack.match(CHROME_IE_STACK_REGEXP)) {\n return this.parseV8OrIE(error);\n } else if (error.stack) {\n return this.parseFFOrSafari(error);\n } else {\n throw new Error('Cannot parse given Error object');\n }\n },\n\n // Separate line and column numbers from a string of the form: (URI:Line:Column)\n extractLocation: function ErrorStackParser$$extractLocation(urlLike) {\n // Fail-fast but return locations like \"(native)\"\n if (urlLike.indexOf(':') === -1) {\n return [urlLike];\n }\n\n var regExp = /(.+?)(?::(\\d+))?(?::(\\d+))?$/;\n var parts = regExp.exec(urlLike.replace(/[()]/g, ''));\n return [parts[1], parts[2] || undefined, parts[3] || undefined];\n },\n\n parseV8OrIE: function ErrorStackParser$$parseV8OrIE(error) {\n var filtered = error.stack.split('\\n').filter(function(line) {\n return !!line.match(CHROME_IE_STACK_REGEXP);\n }, this);\n\n return filtered.map(function(line) {\n if (line.indexOf('(eval ') > -1) {\n // Throw away eval information until we implement stacktrace.js/stackframe#8\n line = line.replace(/eval code/g, 'eval').replace(/(\\(eval at [^()]*)|(,.*$)/g, '');\n }\n var sanitizedLine = line.replace(/^\\s+/, '').replace(/\\(eval code/g, '(').replace(/^.*?\\s+/, '');\n\n // capture and preseve the parenthesized location \"(/foo/my bar.js:12:87)\" in\n // case it has spaces in it, as the string is split on \\s+ later on\n var location = sanitizedLine.match(/ (\\(.+\\)$)/);\n\n // remove the parenthesized location from the line, if it was matched\n sanitizedLine = location ? sanitizedLine.replace(location[0], '') : sanitizedLine;\n\n // if a location was matched, pass it to extractLocation() otherwise pass all sanitizedLine\n // because this line doesn't have function name\n var locationParts = this.extractLocation(location ? location[1] : sanitizedLine);\n var functionName = location && sanitizedLine || undefined;\n var fileName = ['eval', '<anonymous>'].indexOf(locationParts[0]) > -1 ? undefined : locationParts[0];\n\n return new StackFrame({\n functionName: functionName,\n fileName: fileName,\n lineNumber: locationParts[1],\n columnNumber: locationParts[2],\n source: line\n });\n }, this);\n },\n\n parseFFOrSafari: function ErrorStackParser$$parseFFOrSafari(error) {\n var filtered = error.stack.split('\\n').filter(function(line) {\n return !line.match(SAFARI_NATIVE_CODE_REGEXP);\n }, this);\n\n return filtered.map(function(line) {\n // Throw away eval information until we implement stacktrace.js/stackframe#8\n if (line.indexOf(' > eval') > -1) {\n line = line.replace(/ line (\\d+)(?: > eval line \\d+)* > eval:\\d+:\\d+/g, ':$1');\n }\n\n if (line.indexOf('@') === -1 && line.indexOf(':') === -1) {\n // Safari eval frames only have function names and nothing else\n return new StackFrame({\n functionName: line\n });\n } else {\n var functionNameRegex = /((.*\".+\"[^@]*)?[^@]*)(?:@)/;\n var matches = line.match(functionNameRegex);\n var functionName = matches && matches[1] ? matches[1] : undefined;\n var locationParts = this.extractLocation(line.replace(functionNameRegex, ''));\n\n return new StackFrame({\n functionName: functionName,\n fileName: locationParts[0],\n lineNumber: locationParts[1],\n columnNumber: locationParts[2],\n source: line\n });\n }\n }, this);\n },\n\n parseOpera: function ErrorStackParser$$parseOpera(e) {\n if (!e.stacktrace || (e.message.indexOf('\\n') > -1 &&\n e.message.split('\\n').length > e.stacktrace.split('\\n').length)) {\n return this.parseOpera9(e);\n } else if (!e.stack) {\n return this.parseOpera10(e);\n } else {\n return this.parseOpera11(e);\n }\n },\n\n parseOpera9: function ErrorStackParser$$parseOpera9(e) {\n var lineRE = /Line (\\d+).*script (?:in )?(\\S+)/i;\n var lines = e.message.split('\\n');\n var result = [];\n\n for (var i = 2, len = lines.length; i < len; i += 2) {\n var match = lineRE.exec(lines[i]);\n if (match) {\n result.push(new StackFrame({\n fileName: match[2],\n lineNumber: match[1],\n source: lines[i]\n }));\n }\n }\n\n return result;\n },\n\n parseOpera10: function ErrorStackParser$$parseOpera10(e) {\n var lineRE = /Line (\\d+).*script (?:in )?(\\S+)(?:: In function (\\S+))?$/i;\n var lines = e.stacktrace.split('\\n');\n var result = [];\n\n for (var i = 0, len = lines.length; i < len; i += 2) {\n var match = lineRE.exec(lines[i]);\n if (match) {\n result.push(\n new StackFrame({\n functionName: match[3] || undefined,\n fileName: match[2],\n lineNumber: match[1],\n source: lines[i]\n })\n );\n }\n }\n\n return result;\n },\n\n // Opera 10.65+ Error.stack very similar to FF/Safari\n parseOpera11: function ErrorStackParser$$parseOpera11(error) {\n var filtered = error.stack.split('\\n').filter(function(line) {\n return !!line.match(FIREFOX_SAFARI_STACK_REGEXP) && !line.match(/^Error created at/);\n }, this);\n\n return filtered.map(function(line) {\n var tokens = line.split('@');\n var locationParts = this.extractLocation(tokens.pop());\n var functionCall = (tokens.shift() || '');\n var functionName = functionCall\n .replace(/<anonymous function(: (\\w+))?>/, '$2')\n .replace(/\\([^)]*\\)/g, '') || undefined;\n var argsRaw;\n if (functionCall.match(/\\(([^)]*)\\)/)) {\n argsRaw = functionCall.replace(/^[^(]+\\(([^)]*)\\)$/, '$1');\n }\n var args = (argsRaw === undefined || argsRaw === '[arguments not available]') ?\n undefined : argsRaw.split(',');\n\n return new StackFrame({\n functionName: functionName,\n args: args,\n fileName: locationParts[0],\n lineNumber: locationParts[1],\n columnNumber: locationParts[2],\n source: line\n });\n }, this);\n }\n };\n}));\n","let _lazyMatch = () => { var __lib__=(()=>{var m=Object.defineProperty,V=Object.getOwnPropertyDescriptor,G=Object.getOwnPropertyNames,T=Object.prototype.hasOwnProperty,q=(r,e)=>{for(var n in e)m(r,n,{get:e[n],enumerable:true});},H=(r,e,n,a)=>{if(e&&typeof e==\"object\"||typeof e==\"function\")for(let t of G(e))!T.call(r,t)&&t!==n&&m(r,t,{get:()=>e[t],enumerable:!(a=V(e,t))||a.enumerable});return r},J=r=>H(m({},\"__esModule\",{value:true}),r),w={};q(w,{default:()=>re});var A=r=>Array.isArray(r),d=r=>typeof r==\"function\",Q=r=>r.length===0,W=r=>typeof r==\"number\",K=r=>typeof r==\"object\"&&r!==null,X=r=>r instanceof RegExp,b=r=>typeof r==\"string\",h=r=>r===void 0,Y=r=>{const e=new Map;return n=>{const a=e.get(n);if(a)return a;const t=r(n);return e.set(n,t),t}},rr=(r,e,n={})=>{const a={cache:{},input:r,index:0,indexMax:0,options:n,output:[]};if(v(e)(a)&&a.index===r.length)return a.output;throw new Error(`Failed to parse at index ${a.indexMax}`)},i=(r,e)=>A(r)?er(r,e):b(r)?ar(r,e):nr(r,e),er=(r,e)=>{const n={};for(const a of r){if(a.length!==1)throw new Error(`Invalid character: \"${a}\"`);const t=a.charCodeAt(0);n[t]=true;}return a=>{const t=a.index,o=a.input;for(;a.index<o.length&&o.charCodeAt(a.index)in n;)a.index+=1;const u=a.index;if(u>t){if(!h(e)&&!a.options.silent){const s=a.input.slice(t,u),c=d(e)?e(s,o,String(t)):e;h(c)||a.output.push(c);}a.indexMax=Math.max(a.indexMax,a.index);}return true}},nr=(r,e)=>{const n=r.source,a=r.flags.replace(/y|$/,\"y\"),t=new RegExp(n,a);return g(o=>{t.lastIndex=o.index;const u=t.exec(o.input);if(u){if(!h(e)&&!o.options.silent){const s=d(e)?e(...u,o.input,String(o.index)):e;h(s)||o.output.push(s);}return o.index+=u[0].length,o.indexMax=Math.max(o.indexMax,o.index),true}else return false})},ar=(r,e)=>n=>{if(n.input.startsWith(r,n.index)){if(!h(e)&&!n.options.silent){const t=d(e)?e(r,n.input,String(n.index)):e;h(t)||n.output.push(t);}return n.index+=r.length,n.indexMax=Math.max(n.indexMax,n.index),true}else return false},C=(r,e,n,a)=>{const t=v(r);return g(_(M(o=>{let u=0;for(;u<n;){const s=o.index;if(!t(o)||(u+=1,o.index===s))break}return u>=e})))},tr=(r,e)=>C(r,0,1),f=(r,e)=>C(r,0,1/0),x=(r,e)=>{const n=r.map(v);return g(_(M(a=>{for(let t=0,o=n.length;t<o;t++)if(!n[t](a))return false;return true})))},l=(r,e)=>{const n=r.map(v);return g(_(a=>{for(let t=0,o=n.length;t<o;t++)if(n[t](a))return true;return false}))},M=(r,e=false)=>{const n=v(r);return a=>{const t=a.index,o=a.output.length,u=n(a);return (!u||e)&&(a.index=t,a.output.length!==o&&(a.output.length=o)),u}},_=(r,e)=>{const n=v(r);return n},g=(()=>{let r=0;return e=>{const n=v(e),a=r+=1;return t=>{var o;if(t.options.memoization===false)return n(t);const u=t.index,s=(o=t.cache)[a]||(o[a]=new Map),c=s.get(u);if(c===false)return false;if(W(c))return t.index=c,true;if(c)return t.index=c.index,c.output?.length&&t.output.push(...c.output),true;{const Z=t.output.length;if(n(t)){const D=t.index,U=t.output.length;if(U>Z){const ee=t.output.slice(Z,U);s.set(u,{index:D,output:ee});}else s.set(u,D);return true}else return s.set(u,false),false}}}})(),E=r=>{let e;return n=>(e||(e=v(r())),e(n))},v=Y(r=>{if(d(r))return Q(r)?E(r):r;if(b(r)||X(r))return i(r);if(A(r))return x(r);if(K(r))return l(Object.values(r));throw new Error(\"Invalid rule\")}),P=\"abcdefghijklmnopqrstuvwxyz\",ir=r=>{let e=\"\";for(;r>0;){const n=(r-1)%26;e=P[n]+e,r=Math.floor((r-1)/26);}return e},O=r=>{let e=0;for(let n=0,a=r.length;n<a;n++)e=e*26+P.indexOf(r[n])+1;return e},S=(r,e)=>{if(e<r)return S(e,r);const n=[];for(;r<=e;)n.push(r++);return n},or=(r,e,n)=>S(r,e).map(a=>String(a).padStart(n,\"0\")),R=(r,e)=>S(O(r),O(e)).map(ir),p=r=>r,z=r=>ur(e=>rr(e,r,{memoization:false}).join(\"\")),ur=r=>{const e={};return n=>e[n]??(e[n]=r(n))},sr=i(/^\\*\\*\\/\\*$/,\".*\"),cr=i(/^\\*\\*\\/(\\*)?([ a-zA-Z0-9._-]+)$/,(r,e,n)=>`.*${e?\"\":\"(?:^|/)\"}${n.replaceAll(\".\",\"\\\\.\")}`),lr=i(/^\\*\\*\\/(\\*)?([ a-zA-Z0-9._-]*)\\{([ a-zA-Z0-9._-]+(?:,[ a-zA-Z0-9._-]+)*)\\}$/,(r,e,n,a)=>`.*${e?\"\":\"(?:^|/)\"}${n.replaceAll(\".\",\"\\\\.\")}(?:${a.replaceAll(\",\",\"|\").replaceAll(\".\",\"\\\\.\")})`),y=i(/\\\\./,p),pr=i(/[$.*+?^(){}[\\]\\|]/,r=>`\\\\${r}`),vr=i(/./,p),hr=i(/^(?:!!)*!(.*)$/,(r,e)=>`(?!^${L(e)}$).*?`),dr=i(/^(!!)+/,\"\"),fr=l([hr,dr]),xr=i(/\\/(\\*\\*\\/)+/,\"(?:/.+/|/)\"),gr=i(/^(\\*\\*\\/)+/,\"(?:^|.*/)\"),mr=i(/\\/(\\*\\*)$/,\"(?:/.*|$)\"),_r=i(/\\*\\*/,\".*\"),j=l([xr,gr,mr,_r]),Sr=i(/\\*\\/(?!\\*\\*\\/)/,\"[^/]*/\"),yr=i(/\\*/,\"[^/]*\"),N=l([Sr,yr]),k=i(\"?\",\"[^/]\"),$r=i(\"[\",p),wr=i(\"]\",p),Ar=i(/[!^]/,\"^/\"),br=i(/[a-z]-[a-z]|[0-9]-[0-9]/i,p),Cr=i(/[$.*+?^(){}[\\|]/,r=>`\\\\${r}`),Mr=i(/[^\\]]/,p),Er=l([y,Cr,br,Mr]),B=x([$r,tr(Ar),f(Er),wr]),Pr=i(\"{\",\"(?:\"),Or=i(\"}\",\")\"),Rr=i(/(\\d+)\\.\\.(\\d+)/,(r,e,n)=>or(+e,+n,Math.min(e.length,n.length)).join(\"|\")),zr=i(/([a-z]+)\\.\\.([a-z]+)/,(r,e,n)=>R(e,n).join(\"|\")),jr=i(/([A-Z]+)\\.\\.([A-Z]+)/,(r,e,n)=>R(e.toLowerCase(),n.toLowerCase()).join(\"|\").toUpperCase()),Nr=l([Rr,zr,jr]),I=x([Pr,Nr,Or]),kr=i(\"{\",\"(?:\"),Br=i(\"}\",\")\"),Ir=i(\",\",\"|\"),Fr=i(/[$.*+?^(){[\\]\\|]/,r=>`\\\\${r}`),Lr=i(/[^}]/,p),Zr=E(()=>F),Dr=l([j,N,k,B,I,Zr,y,Fr,Ir,Lr]),F=x([kr,f(Dr),Br]),Ur=f(l([sr,cr,lr,fr,j,N,k,B,I,F,y,pr,vr])),Vr=Ur,Gr=z(Vr),L=Gr,Tr=i(/\\\\./,p),qr=i(/./,p),Hr=i(/\\*\\*\\*+/,\"*\"),Jr=i(/([^/{[(!])\\*\\*/,(r,e)=>`${e}*`),Qr=i(/(^|.)\\*\\*(?=[^*/)\\]}])/,(r,e)=>`${e}*`),Wr=f(l([Tr,Hr,Jr,Qr,qr])),Kr=Wr,Xr=z(Kr),Yr=Xr,$=(r,e)=>{const n=Array.isArray(r)?r:[r];if(!n.length)return false;const a=n.map($.compile),t=n.every(s=>/(\\/(?:\\*\\*)?|\\[\\/\\])$/.test(s)),o=e.replace(/[\\\\\\/]+/g,\"/\").replace(/\\/$/,t?\"/\":\"\");return a.some(s=>s.test(o))};$.compile=r=>new RegExp(`^${L(Yr(r))}$`,\"s\");var re=$;return J(w)})();\n return __lib__.default || __lib__; };\nlet _match;\nconst zeptomatch = (path, pattern) => {\n if (!_match) {\n _match = _lazyMatch();\n _lazyMatch = null;\n }\n return _match(path, pattern);\n};\n\nconst _DRIVE_LETTER_START_RE = /^[A-Za-z]:\\//;\nfunction normalizeWindowsPath(input = \"\") {\n if (!input) {\n return input;\n }\n return input.replace(/\\\\/g, \"/\").replace(_DRIVE_LETTER_START_RE, (r) => r.toUpperCase());\n}\n\nconst _UNC_REGEX = /^[/\\\\]{2}/;\nconst _IS_ABSOLUTE_RE = /^[/\\\\](?![/\\\\])|^[/\\\\]{2}(?!\\.)|^[A-Za-z]:[/\\\\]/;\nconst _DRIVE_LETTER_RE = /^[A-Za-z]:$/;\nconst _ROOT_FOLDER_RE = /^\\/([A-Za-z]:)?$/;\nconst _EXTNAME_RE = /.(\\.[^./]+|\\.)$/;\nconst _PATH_ROOT_RE = /^[/\\\\]|^[a-zA-Z]:[/\\\\]/;\nconst sep = \"/\";\nconst normalize = function(path) {\n if (path.length === 0) {\n return \".\";\n }\n path = normalizeWindowsPath(path);\n const isUNCPath = path.match(_UNC_REGEX);\n const isPathAbsolute = isAbsolute(path);\n const trailingSeparator = path[path.length - 1] === \"/\";\n path = normalizeString(path, !isPathAbsolute);\n if (path.length === 0) {\n if (isPathAbsolute) {\n return \"/\";\n }\n return trailingSeparator ? \"./\" : \".\";\n }\n if (trailingSeparator) {\n path += \"/\";\n }\n if (_DRIVE_LETTER_RE.test(path)) {\n path += \"/\";\n }\n if (isUNCPath) {\n if (!isPathAbsolute) {\n return `//./${path}`;\n }\n return `//${path}`;\n }\n return isPathAbsolute && !isAbsolute(path) ? `/${path}` : path;\n};\nconst join = function(...segments) {\n let path = \"\";\n for (const seg of segments) {\n if (!seg) {\n continue;\n }\n if (path.length > 0) {\n const pathTrailing = path[path.length - 1] === \"/\";\n const segLeading = seg[0] === \"/\";\n const both = pathTrailing && segLeading;\n if (both) {\n path += seg.slice(1);\n } else {\n path += pathTrailing || segLeading ? seg : `/${seg}`;\n }\n } else {\n path += seg;\n }\n }\n return normalize(path);\n};\nfunction cwd() {\n if (typeof process !== \"undefined\" && typeof process.cwd === \"function\") {\n return process.cwd().replace(/\\\\/g, \"/\");\n }\n return \"/\";\n}\nconst resolve = function(...arguments_) {\n arguments_ = arguments_.map((argument) => normalizeWindowsPath(argument));\n let resolvedPath = \"\";\n let resolvedAbsolute = false;\n for (let index = arguments_.length - 1; index >= -1 && !resolvedAbsolute; index--) {\n const path = index >= 0 ? arguments_[index] : cwd();\n if (!path || path.length === 0) {\n continue;\n }\n resolvedPath = `${path}/${resolvedPath}`;\n resolvedAbsolute = isAbsolute(path);\n }\n resolvedPath = normalizeString(resolvedPath, !resolvedAbsolute);\n if (resolvedAbsolute && !isAbsolute(resolvedPath)) {\n return `/${resolvedPath}`;\n }\n return resolvedPath.length > 0 ? resolvedPath : \".\";\n};\nfunction normalizeString(path, allowAboveRoot) {\n let res = \"\";\n let lastSegmentLength = 0;\n let lastSlash = -1;\n let dots = 0;\n let char = null;\n for (let index = 0; index <= path.length; ++index) {\n if (index < path.length) {\n char = path[index];\n } else if (char === \"/\") {\n break;\n } else {\n char = \"/\";\n }\n if (char === \"/\") {\n if (lastSlash === index - 1 || dots === 1) ; else if (dots === 2) {\n if (res.length < 2 || lastSegmentLength !== 2 || res[res.length - 1] !== \".\" || res[res.length - 2] !== \".\") {\n if (res.length > 2) {\n const lastSlashIndex = res.lastIndexOf(\"/\");\n if (lastSlashIndex === -1) {\n res = \"\";\n lastSegmentLength = 0;\n } else {\n res = res.slice(0, lastSlashIndex);\n lastSegmentLength = res.length - 1 - res.lastIndexOf(\"/\");\n }\n lastSlash = index;\n dots = 0;\n continue;\n } else if (res.length > 0) {\n res = \"\";\n lastSegmentLength = 0;\n lastSlash = index;\n dots = 0;\n continue;\n }\n }\n if (allowAboveRoot) {\n res += res.length > 0 ? \"/..\" : \"..\";\n lastSegmentLength = 2;\n }\n } else {\n if (res.length > 0) {\n res += `/${path.slice(lastSlash + 1, index)}`;\n } else {\n res = path.slice(lastSlash + 1, index);\n }\n lastSegmentLength = index - lastSlash - 1;\n }\n lastSlash = index;\n dots = 0;\n } else if (char === \".\" && dots !== -1) {\n ++dots;\n } else {\n dots = -1;\n }\n }\n return res;\n}\nconst isAbsolute = function(p) {\n return _IS_ABSOLUTE_RE.test(p);\n};\nconst toNamespacedPath = function(p) {\n return normalizeWindowsPath(p);\n};\nconst extname = function(p) {\n if (p === \"..\") return \"\";\n const match = _EXTNAME_RE.exec(normalizeWindowsPath(p));\n return match && match[1] || \"\";\n};\nconst relative = function(from, to) {\n const _from = resolve(from).replace(_ROOT_FOLDER_RE, \"$1\").split(\"/\");\n const _to = resolve(to).replace(_ROOT_FOLDER_RE, \"$1\").split(\"/\");\n if (_to[0][1] === \":\" && _from[0][1] === \":\" && _from[0] !== _to[0]) {\n return _to.join(\"/\");\n }\n const _fromCopy = [..._from];\n for (const segment of _fromCopy) {\n if (_to[0] !== segment) {\n break;\n }\n _from.shift();\n _to.shift();\n }\n return [..._from.map(() => \"..\"), ..._to].join(\"/\");\n};\nconst dirname = function(p) {\n const segments = normalizeWindowsPath(p).replace(/\\/$/, \"\").split(\"/\").slice(0, -1);\n if (segments.length === 1 && _DRIVE_LETTER_RE.test(segments[0])) {\n segments[0] += \"/\";\n }\n return segments.join(\"/\") || (isAbsolute(p) ? \"/\" : \".\");\n};\nconst format = function(p) {\n const ext = p.ext ? p.ext.startsWith(\".\") ? p.ext : `.${p.ext}` : \"\";\n const segments = [p.root, p.dir, p.base ?? (p.name ?? \"\") + ext].filter(\n Boolean\n );\n return normalizeWindowsPath(\n p.root ? resolve(...segments) : segments.join(\"/\")\n );\n};\nconst basename = function(p, extension) {\n const segments = normalizeWindowsPath(p).split(\"/\");\n let lastSegment = \"\";\n for (let i = segments.length - 1; i >= 0; i--) {\n const val = segments[i];\n if (val) {\n lastSegment = val;\n break;\n }\n }\n return extension && lastSegment.endsWith(extension) ? lastSegment.slice(0, -extension.length) : lastSegment;\n};\nconst parse = function(p) {\n const root = _PATH_ROOT_RE.exec(p)?.[0]?.replace(/\\\\/g, \"/\") || \"\";\n const base = basename(p);\n const extension = extname(base);\n return {\n root,\n dir: dirname(p),\n base,\n ext: extension,\n name: base.slice(0, base.length - extension.length)\n };\n};\nconst matchesGlob = (path, pattern) => {\n return zeptomatch(pattern, normalize(path));\n};\n\nconst _path = {\n __proto__: null,\n basename: basename,\n dirname: dirname,\n extname: extname,\n format: format,\n isAbsolute: isAbsolute,\n join: join,\n matchesGlob: matchesGlob,\n normalize: normalize,\n normalizeString: normalizeString,\n parse: parse,\n relative: relative,\n resolve: resolve,\n sep: sep,\n toNamespacedPath: toNamespacedPath\n};\n\nexport { _path as _, normalizeString as a, relative as b, basename as c, dirname as d, extname as e, format as f, normalizeWindowsPath as g, isAbsolute as i, join as j, matchesGlob as m, normalize as n, parse as p, resolve as r, sep as s, toNamespacedPath as t };\n","import { _ as _path } from './shared/pathe.M-eThtNZ.mjs';\nexport { c as basename, d as dirname, e as extname, f as format, i as isAbsolute, j as join, m as matchesGlob, n as normalize, a as normalizeString, p as parse, b as relative, r as resolve, s as sep, t as toNamespacedPath } from './shared/pathe.M-eThtNZ.mjs';\n\nconst delimiter = /* @__PURE__ */ (() => globalThis.process?.platform === \"win32\" ? \";\" : \":\")();\nconst _platforms = { posix: void 0, win32: void 0 };\nconst mix = (del = delimiter) => {\n return new Proxy(_path, {\n get(_, prop) {\n if (prop === \"delimiter\") return del;\n if (prop === \"posix\") return posix;\n if (prop === \"win32\") return win32;\n return _platforms[prop] || _path[prop];\n }\n });\n};\nconst posix = /* @__PURE__ */ mix(\":\");\nconst win32 = /* @__PURE__ */ mix(\";\");\n\nexport { posix as default, delimiter, posix, win32 };\n","import ErrorStackParser from 'error-stack-parser';\nimport path from 'pathe';\n\nvar LogLevel = /* @__PURE__ */ ((LogLevel2) => {\n LogLevel2[LogLevel2[\"Error\"] = 0] = \"Error\";\n LogLevel2[LogLevel2[\"Warning\"] = 1] = \"Warning\";\n LogLevel2[LogLevel2[\"Log\"] = 2] = \"Log\";\n LogLevel2[LogLevel2[\"Verbose\"] = 3] = \"Verbose\";\n LogLevel2[LogLevel2[\"Debug\"] = 4] = \"Debug\";\n return LogLevel2;\n})(LogLevel || {});\nvar LogLevelString = /* @__PURE__ */ ((LogLevelString2) => {\n LogLevelString2[\"Error\"] = \"error\";\n LogLevelString2[\"Warning\"] = \"warn\";\n LogLevelString2[\"Log\"] = \"log\";\n LogLevelString2[\"Verbose\"] = \"verbose\";\n LogLevelString2[\"Debug\"] = \"debug\";\n return LogLevelString2;\n})(LogLevelString || {});\nvar Format = /* @__PURE__ */ ((Format2) => {\n Format2[\"JSON\"] = \"json\";\n Format2[\"Pretty\"] = \"pretty\";\n return Format2;\n})(Format || {});\n\nconst isColorSupported = true;\nfunction formatter(open, close, replace = open) {\n return (input) => {\n const string = `${input}`;\n const index = string.indexOf(close, open.length);\n return ~index ? open + replaceClose(string, close, replace, index) + close : open + string + close;\n };\n}\nfunction replaceClose(string, close, replace, index) {\n const start = string.substring(0, index) + replace;\n const end = string.substring(index + close.length);\n const nextIndex = end.indexOf(close);\n return ~nextIndex ? start + replaceClose(end, close, replace, nextIndex) : start + end;\n}\nfunction createColors(enabled = isColorSupported) {\n return {\n isColorSupported: enabled,\n reset: enabled ? (s) => `\\x1B[0m${s}\\x1B[0m` : String,\n bold: enabled ? formatter(\"\\x1B[1m\", \"\\x1B[22m\", \"\\x1B[22m\\x1B[1m\") : String,\n dim: enabled ? formatter(\"\\x1B[2m\", \"\\x1B[22m\", \"\\x1B[22m\\x1B[2m\") : String,\n italic: enabled ? formatter(\"\\x1B[3m\", \"\\x1B[23m\") : String,\n underline: enabled ? formatter(\"\\x1B[4m\", \"\\x1B[24m\") : String,\n inverse: enabled ? formatter(\"\\x1B[7m\", \"\\x1B[27m\") : String,\n hidden: enabled ? formatter(\"\\x1B[8m\", \"\\x1B[28m\") : String,\n strikethrough: enabled ? formatter(\"\\x1B[9m\", \"\\x1B[29m\") : String,\n black: enabled ? formatter(\"\\x1B[30m\", \"\\x1B[39m\") : String,\n red: enabled ? formatter(\"\\x1B[31m\", \"\\x1B[39m\") : String,\n green: enabled ? formatter(\"\\x1B[32m\", \"\\x1B[39m\") : String,\n yellow: enabled ? formatter(\"\\x1B[33m\", \"\\x1B[39m\") : String,\n blue: enabled ? formatter(\"\\x1B[34m\", \"\\x1B[39m\") : String,\n magenta: enabled ? formatter(\"\\x1B[35m\", \"\\x1B[39m\") : String,\n cyan: enabled ? formatter(\"\\x1B[36m\", \"\\x1B[39m\") : String,\n white: enabled ? formatter(\"\\x1B[37m\", \"\\x1B[39m\") : String,\n gray: enabled ? formatter(\"\\x1B[90m\", \"\\x1B[39m\") : String,\n bgBlack: enabled ? formatter(\"\\x1B[40m\", \"\\x1B[49m\") : String,\n bgRed: enabled ? formatter(\"\\x1B[41m\", \"\\x1B[49m\") : String,\n bgGreen: enabled ? formatter(\"\\x1B[42m\", \"\\x1B[49m\") : String,\n bgYellow: enabled ? formatter(\"\\x1B[43m\", \"\\x1B[49m\") : String,\n bgBlue: enabled ? formatter(\"\\x1B[44m\", \"\\x1B[49m\") : String,\n bgMagenta: enabled ? formatter(\"\\x1B[45m\", \"\\x1B[49m\") : String,\n bgCyan: enabled ? formatter(\"\\x1B[46m\", \"\\x1B[49m\") : String,\n bgWhite: enabled ? formatter(\"\\x1B[47m\", \"\\x1B[49m\") : String\n };\n}\nconst pc = createColors();\n\nconst logLevelStringToLogLevelMap = {\n [LogLevelString.Error]: LogLevel.Error,\n [LogLevelString.Warning]: LogLevel.Warning,\n [LogLevelString.Log]: LogLevel.Log,\n [LogLevelString.Verbose]: LogLevel.Verbose,\n [LogLevelString.Debug]: LogLevel.Debug\n};\nconst logLevelToLogLevelStringMap = {\n [LogLevel.Error]: LogLevelString.Error,\n [LogLevel.Warning]: LogLevelString.Warning,\n [LogLevel.Log]: LogLevelString.Log,\n [LogLevel.Verbose]: LogLevelString.Verbose,\n [LogLevel.Debug]: LogLevelString.Debug\n};\nconst availableLogLevelStrings = [\n LogLevelString.Error,\n LogLevelString.Warning,\n LogLevelString.Log,\n LogLevelString.Verbose,\n LogLevelString.Debug\n];\nconst logLevelToColorMap = {\n [LogLevel.Error]: pc.red,\n [LogLevel.Warning]: pc.yellow,\n [LogLevel.Log]: pc.blue,\n [LogLevel.Verbose]: pc.cyan,\n [LogLevel.Debug]: pc.green\n};\nconst availableLogLevels = [\n LogLevel.Error,\n LogLevel.Warning,\n LogLevel.Log,\n LogLevel.Verbose,\n LogLevel.Debug\n];\nconst availableFormats = [Format.JSON, Format.Pretty];\n\nfunction parseErrorStacks(errorLike) {\n if (errorLike.stack == null) {\n return [];\n }\n return errorLike.stack.split(\"\\n\").map((item) => item.trim()).slice(1).filter((item) => {\n const match = /^at (.*)( \\(.*:(\\d+):(\\d+)\\))|at (.*)(:(\\d+):(\\d+))/i.exec(item);\n if (!match)\n return false;\n return true;\n }).map((item) => {\n const match = /at (.*)( \\((.*):(\\d+):(\\d+)\\))|at (.*)(:(\\d+):(\\d+))/i.exec(item);\n if (!match) {\n return {\n invalid: true\n };\n }\n if (typeof match[1] !== \"undefined\" && typeof match[2] !== \"undefined\" && typeof match[3] !== \"undefined\" && typeof match[4] !== \"undefined\" && typeof match[5] !== \"undefined\") {\n return {\n invalid: false,\n function: match[1] ?? \"\",\n file: match[3] ?? \"\",\n line: Number.parseInt(match[4] ?? \"0\"),\n column: Number.parseInt(match[5] ?? \"0\")\n };\n } else if (typeof match[6] !== \"undefined\" && typeof match[7] !== \"undefined\" && typeof match[8] !== \"undefined\" && typeof match[9] !== \"undefined\") {\n return {\n invalid: false,\n function: match[6] ?? \"\",\n file: match[7] ?? \"\",\n line: Number.parseInt(match[8] ?? \"0\"),\n column: Number.parseInt(match[9] ?? \"0\")\n };\n } else {\n return {\n invalid: true\n };\n }\n });\n}\n\nfunction isErrorLike(err) {\n if (err == null) {\n return false;\n }\n if (err instanceof Error) {\n return true;\n }\n return false;\n}\nfunction newLog(logLevel, context, fields, message, timeFormatter) {\n let fieldsObj = { context: \"\" };\n if (typeof fields !== \"undefined\" && fields !== null) {\n fieldsObj = { ...fields };\n }\n if (typeof context !== \"undefined\" && context !== null) {\n fieldsObj.context = context;\n }\n const now = /* @__PURE__ */ new Date();\n const raw = {\n \"@timestamp\": now.getTime(),\n \"@localetime\": timeFormatter ? timeFormatter(now) : now.toISOString(),\n \"level\": logLevel,\n \"fields\": fieldsObj,\n \"message\": message\n };\n return raw;\n}\nfunction newErrorLog(logLevel, context, fields, message, errorStack, timeFormatter) {\n const log = newLog(logLevel, context, fields, message, timeFormatter);\n if (typeof errorStack !== \"undefined\" && errorStack !== null) {\n log.errored = true;\n log.error = { stack: errorStack };\n }\n return log;\n}\nfunction prettyFormatValue(value) {\n let valueString = \"\";\n switch (typeof value) {\n case \"number\":\n valueString = pc.yellow(value);\n break;\n case \"object\":\n valueString = pc.green(JSON.stringify(value));\n break;\n case \"boolean\":\n valueString = pc.yellow(String(value));\n break;\n case \"undefined\":\n valueString = pc.gray(\"undefined\");\n break;\n default:\n valueString = String(value);\n break;\n }\n return valueString;\n}\nfunction toPrettyString(log) {\n const messagePartials = [];\n messagePartials.push(log[\"@localetime\"]);\n messagePartials.push(\n logLevelToColorMap[logLevelStringToLogLevelMap[log.level]](\n `[${log.level}]`\n )\n );\n let contextString = \"\";\n if (log.fields.isNestSystemModule != null) {\n contextString = pc.magenta(`[${log.fields.nestSystemModule}]`);\n delete log.fields.isNestSystemModule;\n delete log.fields.nestSystemModule;\n }\n if (log.fields.context != null) {\n contextString = pc.magenta(`[${log.fields.context}]`);\n delete log.fields.context;\n }\n if (contextString.length > 0) {\n messagePartials.push(contextString);\n }\n if (\"module\" in log.fields && log.fields.module != null) {\n messagePartials.push(pc.magenta(`[${log.fields.module}]`));\n delete log.fields.module;\n }\n messagePartials.push(log.message);\n const fieldsEntries = Object.entries(log.fields);\n if (fieldsEntries.length > 0) {\n messagePartials.push(\" {\");\n }\n for (const [key, value] of fieldsEntries) {\n let valueString = value;\n if (isErrorLike(value)) {\n if (value.message) {\n valueString = prettyFormatValue(value.message);\n }\n if (!valueString) {\n valueString = \"\";\n }\n if (value.cause != null) {\n try {\n valueString += JSON.stringify(value.cause);\n } catch {\n valueString += String(value.cause);\n }\n }\n } else {\n valueString = prettyFormatValue(value);\n }\n messagePartials.push(`${pc.gray(key)}${pc.gray(\"=\")}${valueString}`);\n }\n if (fieldsEntries.length > 0) {\n messagePartials.push(\"}\");\n }\n let message = messagePartials.join(\" \");\n if (log.errored != null && log.errored && log.error && log.error.stack != null && log.error.stack) {\n message += `\n${log.error.stack}`;\n }\n return message;\n}\nfunction shouldOutputDebugLevelLogWhenLogLevelIsOneOf(logLevel) {\n return logLevel >= LogLevel.Debug;\n}\nfunction shouldOutputVerboseLevelLogWhenLogLevelIsOneOf(logLevel) {\n return logLevel >= LogLevel.Verbose;\n}\nfunction shouldOutputLogLevelLogWhenLogLevelIsOneOf(logLevel) {\n return logLevel >= LogLevel.Log;\n}\nfunction shouldOutputWarningLevelLogWhenLogLevelIsOneOf(logLevel) {\n return logLevel >= LogLevel.Warning;\n}\nfunction shouldOutputErrorLevelLogWhenLogLevelIsOneOf(logLevel) {\n return logLevel >= LogLevel.Error;\n}\n\nfunction isBrowser() {\n return typeof window !== \"undefined\";\n}\n\nfunction shouldUseHyperlink() {\n return !isBrowser() && getGlobalFormat() === Format.Pretty;\n}\nfunction withHyperlink(basePath, context) {\n return shouldUseHyperlink() ? `\\x1B]8;;file://${basePath}\\x1B\\\\${context}\\x1B]8;;\\x1B\\\\` : context;\n}\n\nconst GLOBAL_CONFIG = {\n configured: false,\n logLevel: LogLevel.Debug,\n format: Format.JSON,\n timeFormatter: (inputDate) => inputDate.toISOString()\n};\nfunction getGlobalLogLevel() {\n return GLOBAL_CONFIG.logLevel;\n}\nfunction setGlobalLogLevel(logLevel) {\n if (availableLogLevels.includes(logLevel)) {\n GLOBAL_CONFIG.logLevel = logLevel;\n } else {\n throw new Error(\n `log level ${logLevel} is not available. available log levels are: ${availableLogLevels.join(\n \", \"\n )}`\n );\n }\n GLOBAL_CONFIG.configured = true;\n}\nfunction getGlobalLogLevelString() {\n return logLevelToLogLevelStringMap[GLOBAL_CONFIG.logLevel];\n}\nfunction setGlobalLogLevelString(logLevelString) {\n if (availableLogLevelStrings.includes(logLevelString)) {\n GLOBAL_CONFIG.logLevel = logLevelStringToLogLevelMap[logLevelString];\n } else {\n throw new Error(\n `log level ${logLevelString} is not available. available log levels are: ${availableLogLevelStrings.join(\n \", \"\n )}`\n );\n }\n GLOBAL_CONFIG.configured = true;\n}\nfunction getGlobalFormat() {\n return GLOBAL_CONFIG.format;\n}\nfunction setGlobalFormat(format) {\n if (availableFormats.includes(format)) {\n GLOBAL_CONFIG.format = format;\n } else {\n throw new Error(\n `format ${format} is not available. available formats are: ${availableFormats.join(\n \", \"\n )}`\n );\n }\n GLOBAL_CONFIG.configured = true;\n}\nfunction setGlobalTimeFormatter(fn) {\n GLOBAL_CONFIG.timeFormatter = fn;\n GLOBAL_CONFIG.configured = true;\n}\nfunction getGlobalTimeFormatter() {\n return GLOBAL_CONFIG.timeFormatter;\n}\nfunction createLogg(context) {\n const logObj = {\n fields: {},\n context,\n logLevel: LogLevel.Debug,\n format: Format.JSON,\n shouldUseGlobalConfig: false,\n errorProcessor: (err) => err,\n timeFormatter: (inputDate) => inputDate.toISOString(),\n useGlobalConfig: () => {\n logObj.shouldUseGlobalConfig = true;\n logObj.format = getGlobalFormat();\n logObj.logLevel = getGlobalLogLevel();\n return logObj.child();\n },\n child: (fields) => {\n const logger = createLogg(logObj.context);\n if (fields != null) {\n logger.fields = { ...logObj.fields, ...fields };\n } else {\n logger.fields = logObj.fields;\n }\n if (logger.fields != null && \"context\" in logger.fields) {\n logger.context = logger.fields.context;\n } else {\n logger.context = logObj.context;\n }\n logger.logLevel = logObj.logLevel;\n logger.format = logObj.format;\n logger.shouldUseGlobalConfig = logObj.shouldUseGlobalConfig;\n return logger;\n },\n withContext: (context2) => {\n const logger = logObj.child();\n logger.context = context2;\n return logger;\n },\n withLogLevel: (logLevel) => {\n const logger = logObj.child();\n if (availableLogLevels.includes(logLevel)) {\n logger.logLevel = logLevel;\n logger.shouldUseGlobalConfig = false;\n logger.debug(\n `setting log level to ${logLevelToLogLevelStringMap[logLevel]} (${logLevel})`\n );\n } else {\n throw new Error(\n `log level ${logLevel} is not available. available log levels are: ${availableLogLevels.join(\n \", \"\n )}`\n );\n }\n return logger;\n },\n withLogLevelString: (logLevelString) => {\n const logger = logObj.child();\n if (availableLogLevelStrings.includes(logLevelString)) {\n logger.logLevel = logLevelStringToLogLevelMap[logLevelString];\n logger.shouldUseGlobalConfig = false;\n logger.debug(\n `setting log level to ${logLevelString} (${logLevelStringToLogLevelMap[logLevelString]})`\n );\n } else {\n throw new Error(\n `log level ${logLevelString} is not available. available log levels are: ${availableLogLevelStrings.join(\n \", \"\n )}`\n );\n }\n return logger;\n },\n withFormat: (format) => {\n const logger = logObj.child();\n if (availableFormats.includes(format)) {\n logger.format = format;\n logger.shouldUseGlobalConfig = false;\n logger.debug(`setting format to ${format}`);\n } else {\n throw new Error(\n `format ${format} is not available. available formats are: ${availableFormats.join(\n \", \"\n )}`\n );\n }\n return logger;\n },\n withFields: (fields) => {\n if (typeof fields === \"undefined\" || fields === null) {\n return logObj.child({});\n }\n return logObj.child(fields);\n },\n withField(key, value) {\n if (typeof key === \"undefined\" || key === null) {\n throw new Error(\"key is required\");\n }\n return logObj.child({ [key]: value });\n },\n withError: (err) => {\n err = logObj.errorProcessor(err);\n if (!isErrorLike(err)) {\n return logObj.withField(\"error\", String(err));\n }\n let logger = logObj;\n logger = logger.withField(\"error\", err.message);\n if (err.stack != null) {\n logger = logger.withField(\"stack\", err.stack);\n }\n if (err.cause != null) {\n try {\n logger = logger.withField(\"cause\", JSON.stringify(err.cause));\n } catch {\n logger = logger.withField(\"cause\", String(err.cause));\n }\n }\n return logger;\n },\n withCallStack(errorLike) {\n const stacks = parseErrorStacks(errorLike).slice(2).filter((item) => !item.invalid);\n if (stacks.length === 0) {\n return logObj;\n }\n return logObj.child({\n function: stacks[0].function,\n file: `${stacks[0].file}:${stacks[0].line}:${stacks[0].column}`,\n line: stacks[0].line,\n column: stacks[0].column\n });\n },\n // Placeholder implementations, will be overridden below\n debug: () => {\n },\n verbose: () => {\n },\n log: () => {\n },\n error: () => {\n },\n errorWithError: () => {\n },\n warn: () => {\n },\n // TODO: remove in next major release\n withTimeFormat: (_) => {\n const logger = logObj.child();\n return logger;\n },\n withTimeFormatter: (fn) => {\n const logger = logObj.child();\n logger.timeFormatter = fn;\n return logger;\n },\n withErrorProcessor: (fn) => {\n const logger = logObj.child();\n logger.errorProcessor = fn;\n return logger;\n }\n };\n const getEffectiveLogLevel = () => {\n return logObj.shouldUseGlobalConfig ? getGlobalLogLevel() : logObj.logLevel;\n };\n const getEffectiveFormat = () => {\n return logObj.shouldUseGlobalConfig ? getGlobalFormat() : logObj.format;\n };\n const getEffectiveTimeFormatter = () => {\n return logObj.shouldUseGlobalConfig ? getGlobalTimeFormatter() : logObj.timeFormatter ?? ((inputDate) => inputDate.toISOString());\n };\n const mergeOptionalParams = (optionalParams) => {\n if (optionalParams != null && optionalParams.length > 0) {\n if (Object.keys(logObj.fields).length > 0) {\n return [logObj.fields, ...optionalParams];\n } else {\n return optionalParams;\n }\n }\n return logObj.fields;\n };\n const outputToConsole = (raw, consoleMethod, mergedFields) => {\n const format = getEffectiveFormat();\n if (isBrowser() && format === Format.Pretty) {\n raw.fields = Object.fromEntries(\n Object.entries(raw.fields).filter(([key, value]) => {\n if (key === \"isNestSystemModule\" || key === \"nestSystemModule\" || key === \"context\") {\n return [key, value];\n }\n return void 0;\n })\n );\n const fieldsToOutput = mergedFields ?? logObj.fields;\n if (Array.isArray(fieldsToOutput) && fieldsToOutput.length > 0) {\n console[consoleMethod](toPrettyString(raw), ...fieldsToOutput);\n } else if (Object.keys(fieldsToOutput).length > 0) {\n console[consoleMethod](toPrettyString(raw), fieldsToOutput);\n } else {\n console[consoleMethod](toPrettyString(raw));\n }\n return;\n }\n const output = format === Format.Pretty ? toPrettyString(raw) : JSON.stringify(raw);\n console[consoleMethod](output);\n };\n const logLevelCheckMap = {\n [LogLevelString.Debug]: shouldOutputDebugLevelLogWhenLogLevelIsOneOf,\n [LogLevelString.Verbose]: shouldOutputVerboseLevelLogWhenLogLevelIsOneOf,\n [LogLevelString.Log]: shouldOutputLogLevelLogWhenLogLevelIsOneOf,\n [LogLevelString.Warning]: shouldOutputWarningLevelLogWhenLogLevelIsOneOf\n };\n const consoleMethodMap = {\n [LogLevelString.Debug]: \"debug\",\n [LogLevelString.Verbose]: \"log\",\n [LogLevelString.Log]: \"log\",\n [LogLevelString.Warning]: \"warn\"\n };\n const logWithLevel = (levelString, message, optionalParams) => {\n const logLevel = getEffectiveLogLevel();\n const shouldOutput = logLevelCheckMap[levelString];\n if (!shouldOutput(logLevel)) {\n return;\n }\n const mergedFields = mergeOptionalParams(optionalParams);\n const raw = newLog(\n levelString,\n logObj.context,\n mergedFields,\n message,\n getEffectiveTimeFormatter()\n );\n outputToConsole(raw, consoleMethodMap[levelString], mergedFields);\n };\n logObj.debug = (message, ...optionalParams) => {\n logWithLevel(LogLevelString.Debug, message, optionalParams);\n };\n logObj.verbose = (message, ...optionalParams) => {\n logWithLevel(LogLevelString.Verbose, message, optionalParams);\n };\n logObj.log = (message, ...optionalParams) => {\n logWithLevel(LogLevelString.Log, message, optionalParams);\n };\n logObj.warn = (message, ...optionalParams) => {\n logWithLevel(LogLevelString.Warning, message, optionalParams);\n };\n logObj.error = (message, stack, ...optionalParams) => {\n const logLevel = getEffectiveLogLevel();\n if (!shouldOutputErrorLevelLogWhenLogLevelIsOneOf(logLevel)) {\n return;\n }\n const mergedFields = mergeOptionalParams(optionalParams);\n const raw = newErrorLog(\n LogLevelString.Error,\n logObj.context,\n mergedFields,\n message,\n stack,\n getEffectiveTimeFormatter()\n );\n outputToConsole(raw, \"error\", mergedFields);\n };\n logObj.errorWithError = (message, err, ...optionalParams) => {\n return logObj.withError(err).error(message, void 0, ...optionalParams);\n };\n return logObj;\n}\nconst useLogg = createLogg;\nfunction createLogger(context) {\n const stack = ErrorStackParser.parse(new Error());\n const currentStack = stack[1];\n const basePath = currentStack.fileName?.replace(\"async\", \"\").trim() ?? \"\";\n const fileName = path.join(...basePath.split(path.sep).slice(-2));\n context = context ?? `${fileName}:${currentStack.lineNumber}`;\n return createLogg(withHyperlink(basePath, context));\n}\nconst useLogger = (context) => createLogger(context).useGlobalConfig();\nconst useGlobalLogger = useLogger;\nfunction initLogger(level = LogLevel.Verbose, format = Format.Pretty) {\n setGlobalLogLevel(level);\n setGlobalFormat(format);\n const logger = useLogg(\"logger\").useGlobalConfig();\n logger.withFields({ level: LogLevel[level], format }).log(\"Logger initialized\");\n}\n\nexport { Format, LogLevel, LogLevelString, Format as LoggerFormat, LogLevel as LoggerLevel, availableFormats, availableLogLevelStrings, availableLogLevels, createLogg, createLogger, getGlobalFormat, getGlobalLogLevel, getGlobalLogLevelString, getGlobalTimeFormatter, initLogger, logLevelStringToLogLevelMap, logLevelToColorMap, logLevelToLogLevelStringMap, setGlobalFormat, setGlobalLogLevel, setGlobalLogLevelString, setGlobalTimeFormatter, useGlobalLogger, useLogg, useLogger };\n","/**\n * 腾讯云 CLS 日志上报工具(浏览器版本)\n * \n * 统一使用腾讯云 CLS 进行埋点上报,对齐 Spatial-Walk 标准\n * 使用 CLS HTTP API 进行日志上传,适用于浏览器环境\n */\n\nimport { CLS_TRACK_EVENTS, getCLSConfig } from '../config/constants'\nimport { Environment } from '../types'\nimport { logger } from './logger'\n\n// 日志缓冲区,批量发送\nlet logBuffer: Array<{\n time: number\n contents: Array<{ key: string, value: string }>\n}> = []\n\nlet flushTimer: number | null = null\nconst FLUSH_INTERVAL = 2000 // 2秒刷新一次\nconst MAX_BUFFER_SIZE = 100 // 最大缓冲区大小\nlet currentEnvironment: Environment | null = null\nlet clsConfig: ReturnType<typeof getCLSConfig> | null = null\n\n/**\n * 初始化 CLS(需要传入环境信息)\n */\nexport function initializeCLS(environment: Environment): void {\n if (!CLS_TRACK_EVENTS) {\n return\n }\n\n currentEnvironment = environment\n clsConfig = getCLSConfig(environment)\n\n // 验证配置:必须要有 endpoint 和 topicId\n // 认证方式:可以使用 token 或 secretId/secretKey\n if (!clsConfig.endpoint || !clsConfig.topicId) {\n logger.warn('[CLS] Configuration incomplete (missing endpoint or topicId), tracking disabled')\n return\n }\n\n // 验证认证方式:至少要有一种认证方式\n const hasToken = !!clsConfig.token\n const hasSecret = !!clsConfig.secretId && !!clsConfig.secretKey\n \n if (!hasToken && !hasSecret) {\n logger.warn('[CLS] Configuration incomplete (missing authentication: token or secretId/secretKey), tracking disabled')\n return\n }\n\n logger.log(`[CLS] Initialized successfully (browser mode) - environment: ${environment}, endpoint: ${clsConfig.endpoint}, topicId: ${clsConfig.topicId}, authMethod: ${hasToken ? 'token' : 'secret'}`)\n \n // 启动定时刷新\n startFlushTimer()\n}\n\n/**\n * 启动定时刷新缓冲区\n */\nfunction startFlushTimer(): void {\n if (flushTimer !== null) {\n return\n }\n\n flushTimer = window.setInterval(() => {\n if (logBuffer.length > 0) {\n flushLogs()\n }\n }, FLUSH_INTERVAL)\n}\n\n/**\n * 停止定时刷新\n */\nfunction stopFlushTimer(): void {\n if (flushTimer !== null) {\n clearInterval(flushTimer)\n flushTimer = null\n }\n}\n\n/**\n * 刷新日志缓冲区,发送到 CLS\n */\nasync function flushLogs(): Promise<void> {\n if (logBuffer.length === 0) {\n return\n }\n\n const logsToSend = [...logBuffer]\n logBuffer = []\n\n try {\n await uploadLogsToCLS(logsToSend)\n }\n catch (error) {\n logger.warn('[CLS] Failed to flush logs:', error instanceof Error ? error.message : String(error))\n // 失败后重新加入缓冲区(避免丢失)\n logBuffer.unshift(...logsToSend)\n // 限制缓冲区大小\n if (logBuffer.length > MAX_BUFFER_SIZE) {\n logBuffer = logBuffer.slice(0, MAX_BUFFER_SIZE)\n }\n }\n}\n\n/**\n * 注意:如果使用 secretId/secretKey 认证,需要实现腾讯云 TC3-HMAC-SHA256 签名算法\n * 由于 Web Crypto API 是异步的,而签名计算需要同步,建议:\n * 1. 使用 token 认证(推荐,简单安全)\n * 2. 通过后端代理进行签名(如果必须使用 secretId/secretKey)\n * 3. 引入 crypto-js 等库实现同步签名算法\n */\n\n/**\n * 上传日志到 CLS(使用 HTTP API)\n */\nasync function uploadLogsToCLS(logs: Array<{ time: number, contents: Array<{ key: string, value: string }> }>): Promise<void> {\n if (!CLS_TRACK_EVENTS || !clsConfig || !clsConfig.endpoint || !clsConfig.topicId) {\n return\n }\n\n // 构建请求 URL(对齐 iOS 端使用的 TencentCloudLogProducer SDK)\n // 腾讯云 CLS HTTP API 格式:https://{endpoint}/structuredlog?topic_id={topicId}\n const url = `https://${clsConfig.endpoint}/structuredlog?topic_id=${clsConfig.topicId}`\n\n // 构建请求体\n const requestBody = {\n logs,\n }\n const payload = JSON.stringify(requestBody)\n\n // 构建请求头\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n }\n\n // 认证方式:优先使用 token,否则使用 secretId/secretKey 签名\n if (clsConfig.token) {\n // 使用 token 认证(简单方式)\n headers['Authorization'] = `Bearer ${clsConfig.token}`\n } else if (clsConfig.secretId && clsConfig.secretKey) {\n // 使用 secretId/secretKey 签名(需要实现完整的腾讯云签名算法)\n // 注意:在浏览器中直接使用 secretKey 不安全,建议通过后端代理\n // 这里暂时不实现签名算法,因为需要引入 crypto-js 等库\n // 如果需要在浏览器中使用 secretId/secretKey,建议通过后端代理\n logger.warn('[CLS] SecretId/SecretKey authentication requires signature algorithm, which is not implemented in browser. Please use token authentication or proxy through backend.')\n return\n } else {\n logger.warn('[CLS] No authentication method available')\n return\n }\n\n try {\n const response = await fetch(url, {\n method: 'POST',\n headers,\n body: payload,\n })\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => '')\n throw new Error(`CLS API error: ${response.status} ${response.statusText}${errorText ? ` - ${errorText}` : ''}`)\n }\n }\n catch (error) {\n throw error\n }\n}\n\n/**\n * 上报日志到 CLS\n * @param event 事件名称\n * @param level 日志级别\n * @param contents 日志内容\n */\nexport function trackEvent(\n event: string,\n level: 'debug' | 'info' | 'warning' | 'error' = 'info',\n contents: Record<string, unknown> = {},\n): void {\n if (!CLS_TRACK_EVENTS) {\n return\n }\n\n try {\n // 构建日志内容\n const logContents: Array<{ key: string, value: string }> = [\n { key: 'event', value: event },\n { key: 'level', value: level },\n { key: 'timestamp', value: Date.now().toString() },\n ]\n\n // 添加其他内容\n for (const [key, value] of Object.entries(contents)) {\n logContents.push({\n key,\n value: typeof value === 'string' ? value : JSON.stringify(value),\n })\n }\n\n // 添加到缓冲区\n logBuffer.push({\n time: Math.floor(Date.now() / 1000),\n contents: logContents,\n })\n\n // 如果缓冲区满了,立即刷新\n if (logBuffer.length >= MAX_BUFFER_SIZE) {\n flushLogs()\n }\n }\n catch (error) {\n logger.warn('[CLS] Failed to track event:', error instanceof Error ? error.message : String(error))\n }\n}\n\n/**\n * 清理 CLS(刷新剩余日志并停止定时器)\n */\nexport function cleanupCLS(): void {\n stopFlushTimer()\n \n // 刷新剩余日志\n if (logBuffer.length > 0) {\n flushLogs()\n }\n\n logger.log('[CLS] Cleaned up')\n}\n","/**\n * Logger Utility\n * Environment-aware logger wrapper\n * - Logs normally in test/dev environment\n * - In production: silently logs to console\n * - Errors and warnings are always reported to CLS (when enabled)\n *\n * Usage: Replace `console.log()` with `logger.log()`\n */\n\nimport { useLogger, setGlobalLogLevel, LogLevel } from '@guiiai/logg'\nimport { trackEvent } from './cls-tracker'\n\n// Check if debug logging is enabled via environment variable\n// By default, only show warnings and errors to reduce console noise\nconst DEBUG_LOG = import.meta.env.VITE_DEBUG_LOG === 'true'\n\n// Set global log level: only show warnings and errors by default\n// Set VITE_DEBUG_LOG=true to enable all logs (LogLevel.Debug)\nif (!DEBUG_LOG) {\n setGlobalLogLevel(LogLevel.Warning) // Only show warnings and errors\n}\n\n// Configure logger based on environment\nexport const logger = useLogger('Web')\n .withErrorProcessor((err: Error | unknown) => {\n captureErrorContext('error', err)\n return err\n })\n .useGlobalConfig()\n\n// 扩展 logger 类型以支持 unknown 参数\nexport const loggerWithUnknown = {\n ...logger,\n error: (message: string, error?: unknown) => {\n if (error !== undefined) {\n logger.error(`${message}: ${error instanceof Error ? error.message : String(error)}`)\n captureErrorContext('error', error)\n }\n else {\n logger.error(message)\n }\n },\n warn: (message: string, error?: unknown) => {\n if (error !== undefined) {\n logger.warn(`${message}: ${error instanceof Error ? error.message : String(error)}`)\n captureErrorContext('warning', error)\n }\n else {\n logger.warn(message)\n }\n },\n}\n\n/**\n * Capture error context for CLS\n */\nfunction captureErrorContext(level: 'error' | 'warning', error: unknown): void {\n const errorMessage = error instanceof Error ? error.message : String(error)\n const errorStack = error instanceof Error ? error.stack : undefined\n\n trackEvent('logger_error', level, {\n error: errorMessage,\n stack: errorStack,\n timestamp: Date.now(),\n environment: import.meta.env.MODE || 'production',\n user_agent: typeof navigator !== 'undefined' ? navigator.userAgent : '',\n })\n}\n","/**\n * SDK 配置加载器\n * 从远程配置接口获取 SDK 端点配置\n */\n\nimport type { SdkConfigResponse } from '../types'\n\nimport { Environment } from '../types'\nimport { logger } from '../utils/logger'\n\ninterface SdkConfigCache {\n config: Partial<Record<Environment, string>> | null\n promise: Promise<void> | null\n}\n\n// 全局缓存,避免重复请求\nconst configCache: SdkConfigCache = {\n config: null,\n promise: null,\n}\n\n/**\n * 从远程配置接口获取 SDK 配置\n * @param version SDK 版本号\n * @returns 解析后的配置映射\n */\nexport async function fetchSdkConfig(version: string): Promise<Partial<Record<Environment, string>>> {\n // 如果已经在获取中,等待之前的请求完成\n if (configCache.promise) {\n await configCache.promise\n return configCache.config || {}\n }\n\n // 如果已经有缓存,直接返回\n if (configCache.config) {\n return configCache.config\n }\n\n // 创建新的请求\n configCache.promise = (async () => {\n try {\n // 开发环境使用代理,生产环境直接请求\n const isDev = typeof window !== 'undefined' && (window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1')\n const configUrl = isDev\n ? `/api/config/sdk?version=${version}`\n : `https://config.spatialwalk.top/sdk?version=${version}`\n logger.log(`[SdkConfigLoader] Fetching SDK config from: ${configUrl}`)\n\n const response = await fetch(configUrl, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n },\n })\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status} ${response.statusText}`)\n }\n\n const data = await response.json() as SdkConfigResponse\n\n if (!data.endpoints) {\n throw new Error('Invalid config response: missing endpoints')\n }\n\n // 解析并存储配置\n const config: Partial<Record<Environment, string>> = {}\n if (data.endpoints.cn) {\n config[Environment.cn] = `https://${data.endpoints.cn}`\n }\n if (data.endpoints.us) {\n config[Environment.us] = `https://${data.endpoints.us}`\n }\n if (data.endpoints.test) {\n config[Environment.test] = `https://${data.endpoints.test}`\n }\n\n configCache.config = config\n logger.log(`[SdkConfigLoader] SDK config fetched successfully:`, config)\n }\n catch (error) {\n // Silently fail if config server is not available (e.g., local development)\n // Only log in debug mode to reduce console noise\n // The SDK will use default configuration in this case\n if (import.meta.env.VITE_DEBUG_LOG === 'true') {\n logger.warn('[SdkConfigLoader] Failed to fetch SDK config:', error instanceof Error ? error.message : String(error))\n }\n // 不抛出错误,返回空对象,让调用方使用默认配置\n configCache.config = {}\n }\n finally {\n configCache.promise = null\n }\n })()\n\n await configCache.promise\n return configCache.config || {}\n}\n\n/**\n * 清除配置缓存(用于测试或重新加载)\n */\nexport function clearSdkConfigCache(): void {\n configCache.config = null\n configCache.promise = null\n}\n","/* eslint-disable style/max-statements-per-line */\n\n/**\n * Avatar Core WASM 内存管理工具\n *\n * 提供高效的内存分配、数据传递和零拷贝访问功能\n * 专门为 avatar_core_wasm 优化\n */\n\n// WASM 模块接口定义\ninterface WASMModule {\n _malloc: (size: number) => number\n _free: (ptr: number) => void\n writeArrayToMemory: (array: Uint8Array, ptr: number) => void\n HEAPU8: Uint8Array\n HEAP32: Int32Array\n HEAPF32: Float32Array\n getValue: (ptr: number, type: string) => number\n setValue: (ptr: number, value: number, type: string) => void\n}\n\n// 内存分配结果\ninterface MemoryAllocation {\n ptr: number\n size: number\n}\n\n// 模板资源接口\nexport interface TemplateResources {\n flameModel: ArrayBuffer\n flameTemplate: ArrayBuffer\n teethPb: ArrayBuffer\n teethNpz: ArrayBuffer\n}\n\n// 角色数据接口(预留)\nexport interface CharacterData {\n shape: ArrayBuffer\n pointCloud: ArrayBuffer\n}\n\n// 表情参数接口(预留)\nexport interface ExpressionParams {\n expression?: number[]\n jaw?: number[]\n eyeR?: number[]\n eyeL?: number[]\n pose?: number[]\n neck?: number[]\n translation?: number[]\n}\n\n// 数组元数据(预留)\nexport interface ArrayMetadata {\n ptr: number\n size: number\n dtype: string\n}\n\nexport class AvatarCoreMemoryManager {\n private module: WASMModule\n private allocatedPointers: Set<number>\n private structPointers: Map<string, number>\n\n constructor(wasmModule: WASMModule) {\n this.module = wasmModule\n this.allocatedPointers = new Set() // 跟踪所有分配的指针\n this.structPointers = new Map() // 跟踪结构体指针\n }\n\n /**\n * 分配 WASM 内存并复制数据 - 纯 API 方式\n */\n allocateAndCopy(arrayBuffer: ArrayBuffer): MemoryAllocation {\n const size = arrayBuffer.byteLength\n const ptr = this.module._malloc(size)\n\n if (!ptr) {\n throw new Error(`Failed to allocate ${size} bytes in WASM memory`)\n }\n\n const uint8Array = new Uint8Array(arrayBuffer)\n\n // 使用 writeArrayToMemory 进行数据写入\n this.module.writeArrayToMemory(uint8Array, ptr)\n\n this.allocatedPointers.add(ptr)\n return { ptr, size }\n }\n\n /**\n * 创建 AvatarTemplateConfig 结构体\n */\n createTemplateConfig(resources: TemplateResources): number {\n const structSize = 10 * 4\n const configPtr = this.module._malloc(structSize)\n\n if (!configPtr) {\n throw new Error('Failed to allocate AvatarTemplateConfig structure')\n }\n\n // 验证必需资源\n if (!resources.flameModel || resources.flameModel.byteLength === 0) {\n throw new Error('flameModel is missing or empty!')\n }\n if (!resources.flameTemplate || resources.flameTemplate.byteLength === 0) {\n throw new Error('flameTemplate is missing or empty!')\n }\n if (!resources.teethPb || resources.teethPb.byteLength === 0) {\n throw new Error('teethPb is missing or empty!')\n }\n if (!resources.teethNpz || resources.teethNpz.byteLength === 0) {\n throw new Error('teethNpz is missing or empty!')\n }\n\n // 分配并复制所有资源数据\n const flameModel = this.allocateAndCopy(resources.flameModel)\n const flameTemplate = this.allocateAndCopy(resources.flameTemplate)\n const teethPb = this.allocateAndCopy(resources.teethPb)\n const teethNpz = this.allocateAndCopy(resources.teethNpz)\n\n let offset = 0\n\n // flame_model_data, flame_model_size\n this.module.setValue(configPtr + offset, flameModel.ptr, 'i32'); offset += 4\n this.module.setValue(configPtr + offset, flameModel.size, 'i32'); offset += 4\n\n // flame_template_data, flame_template_size\n this.module.setValue(configPtr + offset, flameTemplate.ptr, 'i32'); offset += 4\n this.module.setValue(configPtr + offset, flameTemplate.size, 'i32'); offset += 4\n\n // teeth_pb_data, teeth_pb_size\n this.module.setValue(configPtr + offset, teethPb.ptr, 'i32'); offset += 4\n this.module.setValue(configPtr + offset, teethPb.size, 'i32'); offset += 4\n\n // teeth_npz_data, teeth_npz_size\n this.module.setValue(configPtr + offset, teethNpz.ptr, 'i32'); offset += 4\n this.module.setValue(configPtr + offset, teethNpz.size, 'i32'); offset += 4\n\n // teeth_mask_npz_data, teeth_mask_npz_size (可选)\n this.module.setValue(configPtr + offset, 0, 'i32'); offset += 4\n this.module.setValue(configPtr + offset, 0, 'i32'); offset += 4\n\n this.structPointers.set('template_config', configPtr)\n return configPtr\n }\n\n /**\n * 创建 AvatarCharacterData 结构体 - 新版 Emscripten 方式\n */\n createCharacterData(shapeBuffer: ArrayBuffer, plyBuffer: ArrayBuffer, characterId?: string): { dataPtr: number, shapePtr: number, plyPtr: number } {\n const structSize = 4 * 4 // 4 个字段,在 Emscripten WASM 中指针和 size_t 都是 32 位\n const dataPtr = this.module._malloc(structSize)\n\n if (!dataPtr) {\n throw new Error('Failed to allocate AvatarCharacterData structure')\n }\n\n // 分配并复制数据\n const shape = this.allocateAndCopy(shapeBuffer)\n const ply = this.allocateAndCopy(plyBuffer)\n\n // 填充结构体 - 使用 setValue\n let offset = 0\n\n // shape_data, shape_size\n this.module.setValue(dataPtr + offset, shape.ptr, 'i32'); offset += 4\n this.module.setValue(dataPtr + offset, shape.size, 'i32'); offset += 4\n\n // gs_points_data, gs_points_size\n this.module.setValue(dataPtr + offset, ply.ptr, 'i32'); offset += 4\n this.module.setValue(dataPtr + offset, ply.size, 'i32'); offset += 4\n\n // Use unique key for multi-character support (for tracking only)\n const key = characterId ? `character_data_${characterId}` : 'character_data'\n this.structPointers.set(key, dataPtr)\n \n // Return both the struct pointer and the data pointers so caller can free them after WASM copies the data\n return { dataPtr, shapePtr: shape.ptr, plyPtr: ply.ptr }\n }\n\n /**\n * 读取 AvatarFlameParams 结构体数据\n * Used to extract current animation frame parameters from WASM memory\n */\n readFlameParams(paramsPtr: number): {\n shape_params: number[]\n expr_params: number[]\n rotation: number[]\n translation: number[]\n neck_pose: number[]\n jaw_pose: number[]\n eyes_pose: number[]\n eyelid: number[]\n has_eyelid: boolean\n } {\n let byteOffset = 0\n\n // shape_params[300]\n const shape_params: number[] = []\n for (let i = 0; i < 300; i++) {\n shape_params.push(this.module.getValue(paramsPtr + byteOffset, 'float'))\n byteOffset += 4\n }\n\n // expr_params[100]\n const expr_params: number[] = []\n for (let i = 0; i < 100; i++) {\n expr_params.push(this.module.getValue(paramsPtr + byteOffset, 'float'))\n byteOffset += 4\n }\n\n // rotation[3]\n const rotation: number[] = []\n for (let i = 0; i < 3; i++) {\n rotation.push(this.module.getValue(paramsPtr + byteOffset, 'float'))\n byteOffset += 4\n }\n\n // translation[3]\n const translation: number[] = []\n for (let i = 0; i < 3; i++) {\n translation.push(this.module.getValue(paramsPtr + byteOffset, 'float'))\n byteOffset += 4\n }\n\n // neck_pose[3]\n const neck_pose: number[] = []\n for (let i = 0; i < 3; i++) {\n neck_pose.push(this.module.getValue(paramsPtr + byteOffset, 'float'))\n byteOffset += 4\n }\n\n // jaw_pose[3]\n const jaw_pose: number[] = []\n for (let i = 0; i < 3; i++) {\n jaw_pose.push(this.module.getValue(paramsPtr + byteOffset, 'float'))\n byteOffset += 4\n }\n\n // eyes_pose[6]\n const eyes_pose: number[] = []\n for (let i = 0; i < 6; i++) {\n eyes_pose.push(this.module.getValue(paramsPtr + byteOffset, 'float'))\n byteOffset += 4\n }\n\n // eyelid[2]\n const eyelid: number[] = []\n for (let i = 0; i < 2; i++) {\n eyelid.push(this.module.getValue(paramsPtr + byteOffset, 'float'))\n byteOffset += 4\n }\n\n // has_eyelid\n const has_eyelid = this.module.getValue(paramsPtr + byteOffset, 'i32') !== 0\n\n return {\n shape_params,\n expr_params,\n rotation,\n translation,\n neck_pose,\n jaw_pose,\n eyes_pose,\n eyelid,\n has_eyelid,\n }\n }\n\n /**\n * 创建 AvatarFlameParams 结构体 - 新版 Emscripten 方式\n */\n createFlameParams(params: {\n shape_params?: number[]\n expr_params?: number[]\n rotation?: number[]\n translation?: number[]\n neck_pose?: number[]\n jaw_pose?: number[]\n eyes_pose?: number[]\n eyelid?: number[]\n has_eyelid?: boolean\n }): number {\n const structSize = (300 + 100 + 3 + 3 + 3 + 3 + 6 + 2 + 1) * 4 // shape[300] + expr[100] + rotation[3] + translation[3] + neck[3] + jaw[3] + eyes[6] + eyelid[2] + has_eyelid[1]\n const paramsPtr = this.module._malloc(structSize)\n\n if (!paramsPtr) {\n throw new Error('Failed to allocate AvatarFlameParams structure')\n }\n\n let byteOffset = 0\n\n // shape_params[300] - 必须在最前面!\n for (let i = 0; i < 300; i++) {\n const value = params.shape_params?.[i] || 0.0\n this.module.setValue(paramsPtr + byteOffset, value, 'float')\n byteOffset += 4\n }\n\n // expr_params[100]\n for (let i = 0; i < 100; i++) {\n const value = params.expr_params?.[i] || 0.0\n this.module.setValue(paramsPtr + byteOffset, value, 'float')\n byteOffset += 4\n }\n\n // rotation[3]\n for (let i = 0; i < 3; i++) {\n const value = params.rotation?.[i] || 0.0\n this.module.setValue(paramsPtr + byteOffset, value, 'float')\n byteOffset += 4\n }\n\n // translation[3]\n for (let i = 0; i < 3; i++) {\n const value = params.translation?.[i] || 0.0\n this.module.setValue(paramsPtr + byteOffset, value, 'float')\n byteOffset += 4\n }\n\n // neck_pose[3]\n for (let i = 0; i < 3; i++) {\n const value = params.neck_pose?.[i] || 0.0\n this.module.setValue(paramsPtr + byteOffset, value, 'float')\n byteOffset += 4\n }\n\n // jaw_pose[3]\n for (let i = 0; i < 3; i++) {\n const value = params.jaw_pose?.[i] || 0.0\n this.module.setValue(paramsPtr + byteOffset, value, 'float')\n byteOffset += 4\n }\n\n // eyes_pose[6]\n for (let i = 0; i < 6; i++) {\n const value = params.eyes_pose?.[i] || 0.0\n this.module.setValue(paramsPtr + byteOffset, value, 'float')\n byteOffset += 4\n }\n\n // eyelid[2]\n for (let i = 0; i < 2; i++) {\n const value = params.eyelid?.[i] || 0.0\n this.module.setValue(paramsPtr + byteOffset, value, 'float')\n byteOffset += 4\n }\n\n // has_eyelid\n this.module.setValue(paramsPtr + byteOffset, params.has_eyelid ? 1 : 0, 'i32')\n byteOffset += 4\n\n return paramsPtr\n }\n\n /**\n * 读取 AvatarSplatPointFlatArray 结构体数据(预计算协方差)\n *\n * 结构体布局:\n * - AvatarSplatPointFlat* points (0-3, 32位指针)\n * - uint32_t point_count (4-7)\n * - float compute_time_ms (8-11)\n *\n * 每个点布局 (52 bytes):\n * - position[3] (12 bytes)\n * - color[4] (16 bytes, RGBA)\n * - covariance[6] (24 bytes, 预计算好的协方差矩阵上三角)\n *\n * ⚠️ 使用 getValue 逐个读取,避免动态内存的 HEAPF32 detachment 问题\n */\n readSplatPointFlatArray(arrayPtr: number): Float32Array | null {\n if (!arrayPtr) {\n throw new Error('Invalid array pointer')\n }\n\n // 读取结构体头部\n const pointsPtr = this.module.getValue(arrayPtr, 'i32')\n const pointCount = this.module.getValue(arrayPtr + 4, 'i32')\n\n if (pointCount === 0 || !pointsPtr) {\n return null\n }\n\n // 每个点: position[3] + color[4] + covariance[6] = 13 floats\n const floatsPerPoint = 13\n const totalFloats = pointCount * floatsPerPoint\n const floatOffset = pointsPtr / 4 // Float32 是 4 字节对齐\n\n // 零拷贝: 直接从 HEAPF32 复制数据\n const flatData = new Float32Array(totalFloats)\n flatData.set(this.module.HEAPF32.subarray(floatOffset, floatOffset + totalFloats))\n\n return flatData\n }\n\n /**\n * 读取AvatarMeshData结构体数据\n */\n readMeshData(outputPtr: number): {\n vertices: Float32Array\n vertexCount: number\n faces: Uint32Array\n faceCount: number\n landmarks: Float32Array | null\n landmarkCount: number\n computeTime: number\n } {\n // AvatarMeshData WASM结构体布局 (32位指针):\n // float* vertices; // 0-3 (32位指针)\n // uint32_t vertex_count; // 4-7\n // uint32_t* faces; // 8-11 (32位指针)\n // uint32_t face_count; // 12-15\n // float compute_time_ms; // 16-19\n // float* landmarks; // 20-23 (32位指针)\n // uint32_t landmark_count; // 24-27\n\n const verticesPtr = this.module.getValue(outputPtr + 0, '*')\n const vertexCount = this.module.getValue(outputPtr + 4, 'i32')\n const facesPtr = this.module.getValue(outputPtr + 8, '*')\n const faceCount = this.module.getValue(outputPtr + 12, 'i32')\n const computeTime = this.module.getValue(outputPtr + 16, 'float')\n const landmarksPtr = this.module.getValue(outputPtr + 20, '*')\n const landmarkCount = this.module.getValue(outputPtr + 24, 'i32')\n\n // 读取顶点数据 (x,y,z,x,y,z,...)\n const vertices = new Float32Array(vertexCount * 3)\n if (verticesPtr && vertexCount > 0) {\n for (let i = 0; i < vertexCount * 3; i++) {\n vertices[i] = this.module.getValue(verticesPtr + i * 4, 'float')\n }\n }\n\n // 读取面片数据 (i1,i2,i3,i1,i2,i3,...)\n const faces = new Uint32Array(faceCount * 3)\n if (facesPtr && faceCount > 0) {\n for (let i = 0; i < faceCount * 3; i++) {\n faces[i] = this.module.getValue(facesPtr + i * 4, 'i32')\n }\n }\n\n // 读取关键点数据 (可选)\n let landmarks = null\n if (landmarksPtr && landmarkCount > 0) {\n landmarks = new Float32Array(landmarkCount * 3)\n for (let i = 0; i < landmarkCount * 3; i++) {\n landmarks[i] = this.module.getValue(landmarksPtr + i * 4, 'float')\n }\n }\n\n return {\n vertices,\n vertexCount,\n faces,\n faceCount,\n landmarks,\n landmarkCount,\n computeTime,\n }\n }\n\n /**\n * 释放指定指针的内存\n */\n free(ptr: number): void {\n if (ptr && this.allocatedPointers.has(ptr)) {\n this.module._free(ptr)\n this.allocatedPointers.delete(ptr)\n }\n }\n\n /**\n * 释放结构体内存\n */\n freeStruct(name: string): void {\n const ptr = this.structPointers.get(name)\n if (ptr) {\n this.module._free(ptr)\n this.structPointers.delete(name)\n }\n }\n\n /**\n * 清理所有分配的内存\n */\n cleanup(): void {\n // 释放所有分配的指针\n for (const ptr of this.allocatedPointers) {\n this.module._free(ptr)\n }\n this.allocatedPointers.clear()\n\n // 释放所有结构体指针\n for (const [, ptr] of this.structPointers) {\n this.module._free(ptr)\n }\n this.structPointers.clear()\n }\n\n /**\n * 获取内存使用统计\n */\n getMemoryStats(): {\n allocatedPointers: number\n structPointers: number\n totalAllocatedMB: number\n } {\n return {\n allocatedPointers: this.allocatedPointers.size,\n structPointers: this.structPointers.size,\n totalAllocatedMB: Math.round((this.allocatedPointers.size * 1024) / 1024),\n }\n }\n}\n","/**\n * Avatar Core WASM 适配器\n *\n * 完全替换 FlameComplete3DGSManager,提供 avatar_core_wasm 的完整功能\n * 包括牙齿细分、眼部追踪等高级特性\n */\n\nimport type { TemplateResources } from './avatarCoreMemory'\n\nimport { APP_CONFIG } from '../config/app-config'\nimport { logger } from '../utils/logger'\nimport { AvatarCoreMemoryManager } from './avatarCoreMemory'\n\n// WASM memory management (gc function may be available in debug mode)\ndeclare const gc: (() => void) | undefined\n\n// WASM 模块配置类型\nexport interface WasmModuleConfig {\n baseUrl?: string\n [key: string]: unknown\n}\n\n// 类型定义\nexport interface AvatarCoreOptions {\n logLevel?: 'basic' | 'verbose'\n enableValidation?: boolean\n enablePerformanceMetrics?: boolean\n retryCount?: number\n baseAssetsPath?: string\n modelFolder?: string\n wasmConfig?: WasmModuleConfig\n wasmPath?: string\n}\n\ninterface PerformanceMetrics {\n initTime: number\n loadTime: number\n computeFrames: number\n totalComputeTime: number\n averageComputeTime: number\n}\n\nexport interface FlameInfo {\n vertexCount: number\n faceCount: number\n jointCount: number\n}\n\nexport interface CharacterInfo {\n pointCount: number\n hasAnimation: boolean\n}\n\ninterface ProgressCallback {\n (info: { message: string, progress: number }): void\n}\n\nexport interface FlameParams {\n shape_params?: number[]\n expr_params?: number[]\n rotation?: number[]\n translation?: number[]\n neck_pose?: number[]\n jaw_pose?: number[]\n eyes_pose?: number[]\n eyelid?: number[]\n has_eyelid?: boolean\n}\n\nexport class AvatarCoreAdapter {\n // 配置\n private options: Required<Omit<AvatarCoreOptions, 'wasmConfig'>> & { wasmConfig?: WasmModuleConfig }\n private wasmConfig: WasmModuleConfig\n\n // 核心组件\n // eslint-disable-next-line ts/no-explicit-any\n private wasmModule: any\n private memoryManager: AvatarCoreMemoryManager | null\n\n // Avatar Core handles\n private coreHandle: number | null\n // Support multiple character handles (key: characterId, value: handle)\n private characterHandles: Map<string, number> = new Map()\n // Animation handles per character (key: characterId, value: { handle, totalFrames })\n private animationHandles: Map<string, { handle: number, totalFrames: number | null }> = new Map()\n \n // Legacy single character support (deprecated, kept for backward compatibility)\n private characterHandle: number | null\n private animationHandle: number | null\n private totalFrames: number | null\n\n // 状态管理\n private isInitialized: boolean\n private isCharacterLoaded: boolean\n\n // C API 函数包装\n // eslint-disable-next-line ts/no-explicit-any\n private api: any\n\n // 性能监控\n private performanceMetrics: PerformanceMetrics\n public wasmTime = 0 // 最近一次 WASM 计算耗时\n\n // 错误码映射\n private errorCodes: Record<number, string>\n\n // 模型信息\n private flameInfo?: FlameInfo\n private characterInfo?: CharacterInfo\n\n constructor(options: AvatarCoreOptions = {}) {\n this.options = {\n logLevel: 'basic',\n enableValidation: true,\n enablePerformanceMetrics: true,\n retryCount: 3,\n baseAssetsPath: '/',\n modelFolder: '3dgs',\n wasmPath: './wasm/avatar_core_wasm.wasm',\n ...options,\n }\n\n // Store wasmConfig for use in loadWASMModule\n this.wasmConfig = options.wasmConfig || { baseUrl: undefined }\n\n // 核心组件\n this.wasmModule = null\n this.memoryManager = null\n\n // Avatar Core handles\n this.coreHandle = null\n this.characterHandle = null\n this.animationHandle = null\n this.totalFrames = null // 缓存动画总帧数\n\n // 状态管理\n this.isInitialized = false\n this.isCharacterLoaded = false\n\n // C API 函数包装\n this.api = {}\n\n // 性能监控\n this.performanceMetrics = {\n initTime: 0,\n loadTime: 0,\n computeFrames: 0,\n totalComputeTime: 0,\n averageComputeTime: 0,\n }\n\n // 错误码映射\n this.errorCodes = {\n 0: 'AVATAR_SUCCESS',\n 1: 'AVATAR_ERROR_INVALID_PARAMETER',\n 2: 'AVATAR_ERROR_MEMORY_ALLOCATION',\n 3: 'AVATAR_ERROR_INVALID_DATA_FORMAT',\n 4: 'AVATAR_ERROR_CHARACTER_NOT_FOUND',\n 5: 'AVATAR_ERROR_ANIMATION_NOT_FOUND',\n 6: 'AVATAR_ERROR_COMPUTATION_FAILED',\n }\n }\n\n /**\n * 加载 WASM 模块并设置 API\n * 每次都创建全新的 WASM 实例,确保 C++ 内存是干净的\n * \n * 注意:这里使用动态 import() 导入 WASM 模块。\n * Vite 在构建时会自动为 WASM 文件和 JS glue 代码添加 hash(如 avatar_core_wasm-CxWuw7eS.wasm),\n * 确保浏览器缓存与版本一致,不会有缓存问题。\n * \n * Hash 的作用机制:\n * - WASM 文件内容变化 → hash 自动变化 → URL 变化 → 浏览器拉取新版本\n * - WASM 文件内容不变 → hash 保持不变 → URL 不变 → 浏览器使用缓存\n * - Emscripten 生成的 JS 内部会使用 hard-coded 的 hash 路径加载 .wasm 文件\n */\n async loadWASMModule(): Promise<void> {\n try {\n // 静态导入 WASM 模块(Vite 会正确处理路径)\n // @ts-expect-error - WASM module import\n const { default: AvatarCoreModule } = await import('./avatar_core_wasm.js')\n\n // 如果有 wasmConfig,传递给 WASM 模块初始化\n if (this.wasmConfig && Object.keys(this.wasmConfig).length > 0) {\n this.wasmModule = await AvatarCoreModule(this.wasmConfig)\n }\n else {\n this.wasmModule = await AvatarCoreModule()\n }\n\n // 验证 WASM 模块\n this.validateWASMModule()\n\n // 初始化内存管理器\n this.memoryManager = new AvatarCoreMemoryManager(this.wasmModule)\n\n // 设置 C API 函数\n this.setupCAPIFunctions()\n\n logger.log('✅ Created new WASM instance with clean C++ memory')\n }\n catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error)\n throw new Error(`Failed to load WASM module: ${errorMessage}`)\n }\n }\n\n /**\n * 验证 WASM 模块功能\n */\n private validateWASMModule(): void {\n // 验证基础函数\n const requiredFunctions = ['cwrap', '_malloc', '_free', 'setValue', 'getValue', 'writeArrayToMemory']\n\n for (const funcName of requiredFunctions) {\n if (typeof this.wasmModule[funcName] !== 'function') {\n throw new TypeError(`WASM module missing required function: ${funcName}`)\n }\n }\n\n // 初始化内存视图\n this.initializeMemoryViews()\n }\n\n /**\n * 初始化内存视图\n */\n private initializeMemoryViews(): void {\n try {\n // 测试内存分配和读写\n const testPtr = this.wasmModule._malloc(4)\n if (!testPtr) {\n throw new Error('Memory allocation test failed')\n }\n\n const testValue = 0x12345678\n this.wasmModule.setValue(testPtr, testValue, 'i32')\n const readValue = this.wasmModule.getValue(testPtr, 'i32')\n\n if (readValue !== testValue) {\n throw new Error('Memory read/write test failed')\n }\n\n this.wasmModule._free(testPtr)\n }\n catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error)\n throw new Error(`Memory system initialization failed: ${errorMessage}`)\n }\n }\n\n /**\n * 设置 C API 函数包装\n */\n private setupCAPIFunctions(): void {\n this.api = {\n // 核心系统管理\n initialize: this.wasmModule.cwrap('avatar_core_initialize', 'number', ['number']), // 返回 handle\n release: this.wasmModule.cwrap('avatar_core_release', null, ['number']),\n getVersion: this.wasmModule.cwrap('avatar_core_get_version', 'string', []),\n getErrorString: this.wasmModule.cwrap('avatar_core_get_error_string', 'string', ['number']),\n resetProcessorForReuse: this.wasmModule.cwrap('avatar_core_reset_processor_for_reuse', null, ['number']),\n // 角色管理\n loadCharacter: this.wasmModule.cwrap('avatar_core_load_character', 'number', ['number', 'number']), // 返回 handle\n removeCharacter: this.wasmModule.cwrap('avatar_core_remove_character', null, ['number', 'number']),\n getCharacterInfo: this.wasmModule.cwrap('avatar_core_get_character_info', 'number', ['number', 'number', 'number']),\n getCharacterShapeParams: this.wasmModule.cwrap('avatar_core_get_character_shape_params', 'number', ['number', 'number']), // characterHandle, outputPtr\n\n // 动画管理\n loadAnimation: this.wasmModule.cwrap('avatar_core_load_animation', 'number', ['number', 'number']),\n parseAnimationFramesFromFile: this.wasmModule.cwrap('avatar_core_parse_animation_frames_from_file', 'number', ['number', 'number', 'number']),\n getAnimationFrameCount: this.wasmModule.cwrap('avatar_core_get_animation_frame_count', 'number', ['number', 'number']),\n getFrameFromAnimation: this.wasmModule.cwrap('avatar_core_get_frame_from_animation', 'number', ['number', 'number', 'number']),\n removeAnimation: this.wasmModule.cwrap('avatar_core_remove_animation', null, ['number', 'number']),\n\n // 帧计算 (Flat 格式 - GPU 优化版本,协方差预计算)\n computeFrameFlat: this.wasmModule.cwrap('avatar_core_compute_frame_as_splat_points_flat', 'number', ['number', 'number', 'number', 'number']), // 返回错误码\n freeSplatPointsFlat: this.wasmModule.cwrap('avatar_core_free_splat_points_flat', null, ['number']),\n\n // Mesh 计算(用于传统 mesh 渲染)\n computeFrameAsMesh: this.wasmModule.cwrap('avatar_core_compute_frame_as_mesh', 'number', ['number', 'number', 'number', 'number']), // 返回错误码\n freeMeshData: this.wasmModule.cwrap('avatar_core_free_mesh_data', null, ['number']),\n\n // 眼部追踪(高级功能)\n setEyeTrackingConfig: this.wasmModule.cwrap('avatar_core_set_eye_tracking_config', 'number', ['number', 'number', 'number']), // core, character, config\n setGazeTarget: this.wasmModule.cwrap('avatar_core_set_gaze_target', 'number', ['number', 'number', 'number', 'number', 'number']), // core, character, x, y, z\n resetEyeTracking: this.wasmModule.cwrap('avatar_core_reset_eye_tracking', 'number', ['number']),\n\n // FLAME 信息查询\n getFlameInfo: this.wasmModule.cwrap('avatar_core_get_flame_info', 'number', ['number', 'number', 'number', 'number']),\n }\n }\n\n /**\n * 读取当前动画帧的 FlameParams(用于过渡或调试)\n */\n /**\n * Get current frame parameters\n * @param frameIndex Frame index\n * @param characterId Optional character ID for multi-character support\n */\n async getCurrentFrameParams(frameIndex: number = 0, characterId?: string): Promise<FlameParams> {\n // 直接复用已验证的 API:getAnimationFrameParams(出参 + 错误码)\n const paramsPtr = await this.getAnimationFrameParams(frameIndex, characterId)\n try {\n const params = this.memoryManager!.readFlameParams(paramsPtr)\n return params as FlameParams\n }\n finally {\n this.wasmModule._free(paramsPtr)\n }\n }\n\n /**\n * 初始化 Avatar Core 核心\n */\n private async initializeAvatarCore(templateResources: TemplateResources): Promise<void> {\n try {\n // 创建模板配置结构体\n const configPtr = this.memoryManager!.createTemplateConfig(templateResources)\n\n // 调用 avatar_core_initialize - 返回 handle,失败时返回 NULL\n const coreHandle = this.api.initialize(configPtr)\n\n if (!coreHandle) {\n throw new Error('avatar_core_initialize returned NULL - initialization failed')\n }\n\n // 保存 core handle\n this.coreHandle = coreHandle\n\n // 查询 FLAME 模型信息\n await this.queryFlameInfo()\n }\n catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error)\n throw new Error(`Failed to initialize Avatar Core: ${errorMessage}`)\n }\n }\n\n /**\n * 加载模板资源(从预加载的 ArrayBuffers)\n */\n async loadTemplateResourcesFromBuffers(templateResources: Record<string, ArrayBuffer>): Promise<boolean> {\n // Convert Record<string, ArrayBuffer> to TemplateResources format\n const formattedResources: TemplateResources = {\n flameModel: templateResources.flameModel || templateResources['model.pb'] || new ArrayBuffer(0),\n flameTemplate: templateResources.flameTemplate || templateResources['flame_template.pb'] || new ArrayBuffer(0),\n teethPb: templateResources.teethPb || templateResources['teeth.pb'] || new ArrayBuffer(0),\n teethNpz: templateResources.teethNpz || templateResources['teeth.npz'] || new ArrayBuffer(0),\n }\n if (!this.wasmModule || !this.memoryManager) {\n throw new Error('WASM module not loaded')\n }\n\n // 如果已经初始化,跳过\n if (this.isInitialized && this.coreHandle) {\n return true\n }\n\n try {\n // 初始化 Avatar Core\n await this.initializeAvatarCore(formattedResources)\n this.isInitialized = true\n return true\n }\n catch (error) {\n logger.errorWithError('❌ Template resources loading failed:', error)\n const errorMessage = error instanceof Error ? error.message : String(error)\n throw new Error(`Template resources loading failed: ${errorMessage}`)\n }\n }\n\n /**\n * 加载角色数据(从预加载的 ArrayBuffers)\n */\n /**\n * Load character from buffers and return handle\n * @param shapeBuffer Shape data buffer\n * @param pointCloudBuffer Point cloud data buffer\n * @param characterId Optional character ID for multi-character support\n * @returns Character handle\n */\n async loadCharacterFromBuffers(\n shapeBuffer: ArrayBuffer,\n pointCloudBuffer: ArrayBuffer,\n characterId?: string,\n ): Promise<number> {\n if (!this.isInitialized) {\n throw new Error('Avatar Core not initialized')\n }\n\n const startTime = performance.now()\n\n try {\n // 创建角色数据结构体 (pass characterId for multi-character support)\n const { dataPtr, shapePtr, plyPtr } = this.memoryManager!.createCharacterData(\n shapeBuffer,\n pointCloudBuffer,\n characterId,\n )\n\n // 调用 avatar_core_load_character - 返回 handle,失败时返回 NULL\n // WASM will copy the data internally, so we can free the temporary memory after this call\n const characterHandle = this.api.loadCharacter(this.coreHandle, dataPtr)\n\n if (!characterHandle) {\n // Free memory on error\n this.memoryManager!.free(shapePtr)\n this.memoryManager!.free(plyPtr)\n const key = characterId ? `character_data_${characterId}` : 'character_data'\n // freeStruct already frees dataPtr, so we don't need to call _free again\n this.memoryManager!.freeStruct(key)\n throw new Error('avatar_core_load_character returned NULL - character loading failed')\n }\n\n // Free the temporary memory after WASM has copied the data\n // Similar to loadAnimationFromData pattern: free struct immediately, data pointers are managed by memoryManager\n this.memoryManager!.free(shapePtr)\n this.memoryManager!.free(plyPtr)\n const key = characterId ? `character_data_${characterId}` : 'character_data'\n // freeStruct already frees dataPtr, so we don't need to call _free again\n this.memoryManager!.freeStruct(key)\n\n // 保存 character handle (support multi-character) - 每个角色独立管理\n const id = characterId || 'default'\n this.characterHandles.set(id, characterHandle)\n \n // Legacy support: only update default character handle for backward compatibility\n if (!characterId || id === 'default') {\n this.characterHandle = characterHandle\n this.isCharacterLoaded = true\n await this.queryCharacterInfo()\n } else if (!this.characterHandle) {\n // If no default character yet, set this as default (first character loaded)\n this.characterHandle = characterHandle\n this.isCharacterLoaded = true\n }\n\n this.performanceMetrics.loadTime = performance.now() - startTime\n\n return characterHandle\n }\n catch (error) {\n logger.errorWithError('❌ Character loading failed:', error)\n const errorMessage = error instanceof Error ? error.message : String(error)\n throw new Error(`Character loading failed: ${errorMessage}`)\n }\n }\n\n private async loadAnimationFromData(animData: ArrayBuffer): Promise<number> {\n const animPtr = this.memoryManager!.allocateAndCopy(animData)\n const animStruct = this.wasmModule._malloc(8)\n this.wasmModule.setValue(animStruct, animPtr.ptr, 'i32')\n this.wasmModule.setValue(animStruct + 4, animPtr.size, 'i32')\n\n const handle = this.api.loadAnimation(this.coreHandle, animStruct)\n this.wasmModule._free(animStruct)\n\n if (!handle) {\n throw new Error('avatar_core_load_animation returned NULL')\n }\n\n return handle\n }\n\n /**\n * Load animation from ArrayBuffer (for CDN-based dynamic loading)\n * @param animData Animation data buffer\n * @param characterId Optional character ID for multi-character support\n * @returns Animation handle\n */\n async loadAnimationFromBuffer(animData: ArrayBuffer, characterId?: string): Promise<number> {\n if (!this.isInitialized) {\n throw new Error('Avatar Core not initialized')\n }\n\n try {\n const animHandle = await this.loadAnimationFromData(animData)\n const totalFrames = await this.getAnimationTotalFrames(animHandle)\n \n // Store animation handle per character\n const id = characterId || 'default'\n this.animationHandles.set(id, { handle: animHandle, totalFrames })\n \n // Legacy support\n this.animationHandle = animHandle\n this.totalFrames = totalFrames\n \n return animHandle\n }\n catch (error) {\n logger.errorWithError('❌ Failed to load animation from buffer:', error)\n const errorMessage = error instanceof Error ? error.message : String(error)\n throw new Error(`Failed to load animation from buffer: ${errorMessage}`)\n }\n }\n\n async switchAnimationFile(animationFile: string): Promise<number> {\n if (!this.isInitialized) {\n throw new Error('Avatar Core not initialized')\n }\n\n try {\n const animationPath = `${this.options.baseAssetsPath}/${this.options.modelFolder}/${animationFile}`\n const fullUrl = this.wasmConfig.baseUrl ? `${this.wasmConfig.baseUrl}${animationPath}` : animationPath\n const response = await fetch(fullUrl)\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`)\n }\n\n const animData = await response.arrayBuffer()\n const newHandle = await this.loadAnimationFromData(animData)\n\n this.animationHandle = newHandle\n this.totalFrames = null\n await this.getAnimationTotalFrames()\n\n return this.totalFrames!\n }\n catch (error) {\n logger.errorWithError(`❌ Failed to switch animation to ${animationFile}:`, error)\n const errorMessage = error instanceof Error ? error.message : String(error)\n throw new Error(`Failed to switch animation: ${errorMessage}`)\n }\n }\n\n /**\n * 获取动画总帧数\n * @param animationHandle Optional animation handle (for multi-character support)\n */\n async getAnimationTotalFrames(animationHandle?: number): Promise<number> {\n const handle = animationHandle || this.animationHandle\n if (!handle) {\n throw new Error('No animation loaded')\n }\n\n try {\n // 分配输出参数内存\n const frameCountPtr = this.wasmModule._malloc(4) // uint32_t\n\n // 调用 avatar_core_get_animation_frame_count\n const result = this.api.getAnimationFrameCount(handle, frameCountPtr)\n\n if (result !== 0) { // AVATAR_SUCCESS = 0\n this.wasmModule._free(frameCountPtr)\n const errorMsg = this.api.getErrorString(result)\n throw new Error(`Failed to get animation frame count: ${errorMsg}`)\n }\n\n // 读取帧数\n const frameCount = this.wasmModule.getValue(frameCountPtr, 'i32') as number\n this.wasmModule._free(frameCountPtr)\n \n // Legacy support: update totalFrames if using default animation\n if (!animationHandle) {\n this.totalFrames = frameCount\n }\n\n return frameCount\n }\n catch (error) {\n logger.errorWithError('❌ Failed to get animation frame count:', error)\n const errorMessage = error instanceof Error ? error.message : String(error)\n throw new Error(`Failed to get animation frame count: ${errorMessage}`)\n }\n }\n\n /**\n * 从动画中获取指定帧的参数\n * @param frameIndex Frame index\n * @param characterId Optional character ID for multi-character support\n */\n async getAnimationFrameParams(frameIndex: number = 0, characterId?: string): Promise<number> {\n // Get animation handle (support multi-character)\n const id = characterId || 'default'\n const animInfo = this.animationHandles.get(id)\n const animHandle = animInfo?.handle || this.animationHandle\n \n if (!animHandle) {\n throw new Error('No animation loaded')\n }\n\n // Get total frames for validation\n const totalFrames = animInfo?.totalFrames ?? this.totalFrames\n\n // 验证帧索引范围,循环播放\n if (totalFrames !== null && totalFrames > 0) {\n frameIndex = frameIndex % totalFrames\n if (frameIndex < 0)\n frameIndex += totalFrames\n }\n\n try {\n // 分配AvatarFlameParams结构体内存\n // shape[300] + expr[100] + rotation[3] + translation[3] + neck[3] + jaw[3] + eyes[6] + eyelid[2] + has_eyelid[1] = 421个float\n const structSize = (300 + 100 + 3 + 3 + 3 + 3 + 6 + 2 + 1) * 4\n const paramsPtr = this.wasmModule._malloc(structSize)\n\n // 调用avatar_core_get_frame_from_animation\n const result = this.api.getFrameFromAnimation(animHandle, frameIndex, paramsPtr)\n\n if (result !== 0) { // AVATAR_SUCCESS = 0\n this.wasmModule._free(paramsPtr)\n const errorMsg = this.api.getErrorString(result)\n throw new Error(`Failed to get frame ${frameIndex}: ${errorMsg}`)\n }\n\n // 获取角色的 shape_params 并设置到 paramsPtr 中\n // GetFrameFromAnimation 不填充 shape_params,需要从角色数据中获取\n // shape_params 位于 paramsPtr 的开头(偏移 0),直接传入 paramsPtr\n const charHandle = this.characterHandles.get(id) || this.characterHandle\n if (charHandle) {\n const shapeResult = this.api.getCharacterShapeParams(charHandle, paramsPtr)\n if (shapeResult !== 0) {\n logger.warn(`Failed to get character shape params: ${this.api.getErrorString(shapeResult)}`)\n }\n }\n\n return paramsPtr // 返回参数指针,由computeFrame使用\n }\n catch (error) {\n logger.errorWithError(`❌ Failed to get animation frame ${frameIndex}:`, error)\n const errorMessage = error instanceof Error ? error.message : String(error)\n throw new Error(`Failed to get animation frame ${frameIndex}: ${errorMessage}`)\n }\n }\n\n /**\n * 设置眼部追踪配置(对齐 app 实现)\n */\n async setEyeTrackingConfig(config: {\n enabled: boolean\n auto_eyelid_adjustment?: boolean\n eyelid_threshold?: number\n }): Promise<boolean> {\n if (!this.isCharacterLoaded) {\n throw new Error('Character not loaded')\n }\n try {\n // struct { bool enabled; bool auto_eyelid_adjustment; float eyelid_threshold; }\n const configPtr = this.wasmModule._malloc(12)\n this.wasmModule.setValue(configPtr, config.enabled ? 1 : 0, 'i32')\n this.wasmModule.setValue(configPtr + 4, config.auto_eyelid_adjustment !== false ? 1 : 0, 'i32')\n this.wasmModule.setValue(configPtr + 8, config.eyelid_threshold || 0.2, 'float')\n\n const result = this.api.setEyeTrackingConfig(this.coreHandle, this.characterHandle, configPtr)\n this.wasmModule._free(configPtr)\n this.checkError(result, 'avatar_core_set_eye_tracking_config')\n return true\n }\n catch (error) {\n logger.errorWithError('❌ Failed to set eye tracking config:', error)\n const errorMessage = error instanceof Error ? error.message : String(error)\n throw new Error(`Failed to set eye tracking config: ${errorMessage}`)\n }\n }\n\n /**\n * 设置眼部追踪目标(高级功能)\n */\n async setGazeTarget(x: number, y: number, z: number): Promise<boolean> {\n if (!this.isCharacterLoaded) {\n throw new Error('Character not loaded')\n }\n\n try {\n const result = this.api.setGazeTarget(this.coreHandle, this.characterHandle, x, y, z)\n this.checkError(result, 'avatar_core_set_gaze_target')\n\n return true\n }\n catch (error) {\n logger.errorWithError('❌ Failed to set gaze target:', error)\n const errorMessage = error instanceof Error ? error.message : String(error)\n throw new Error(`Failed to set gaze target: ${errorMessage}`)\n }\n }\n\n /**\n * 重置眼部追踪\n */\n async resetEyeTracking(): Promise<boolean> {\n if (!this.isCharacterLoaded) {\n throw new Error('Character not loaded')\n }\n\n try {\n const result = this.api.resetEyeTracking(this.coreHandle)\n this.checkError(result, 'avatar_core_reset_eye_tracking')\n\n return true\n }\n catch (error) {\n logger.errorWithError('❌ Failed to reset eye tracking:', error)\n const errorMessage = error instanceof Error ? error.message : String(error)\n throw new Error(`Failed to reset eye tracking: ${errorMessage}`)\n }\n }\n\n /**\n * 查询 FLAME 模型信息\n */\n private async queryFlameInfo(): Promise<void> {\n try {\n // 分配输出参数\n const vertexCountPtr = this.wasmModule._malloc(4)\n const faceCountPtr = this.wasmModule._malloc(4)\n const jointCountPtr = this.wasmModule._malloc(4)\n\n const result = this.api.getFlameInfo(\n this.coreHandle,\n vertexCountPtr,\n faceCountPtr,\n jointCountPtr,\n )\n\n this.checkError(result, 'avatar_core_get_flame_info')\n\n // 读取结果\n const vertexCount = this.wasmModule.getValue(vertexCountPtr, 'i32')\n const faceCount = this.wasmModule.getValue(faceCountPtr, 'i32')\n const jointCount = this.wasmModule.getValue(jointCountPtr, 'i32')\n\n // 释放内存\n this.wasmModule._free(vertexCountPtr)\n this.wasmModule._free(faceCountPtr)\n this.wasmModule._free(jointCountPtr)\n\n this.flameInfo = { vertexCount, faceCount, jointCount }\n }\n catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error)\n logger.errorWithError('❌ Failed to query FLAME info:', errorMessage)\n }\n }\n\n /**\n * 查询角色信息\n */\n private async queryCharacterInfo(): Promise<void> {\n try {\n const pointCountPtr = this.wasmModule._malloc(4)\n const hasAnimationPtr = this.wasmModule._malloc(1)\n\n const result = this.api.getCharacterInfo(\n this.characterHandle,\n pointCountPtr,\n hasAnimationPtr,\n )\n\n this.checkError(result, 'avatar_core_get_character_info')\n\n const pointCount = this.wasmModule.getValue(pointCountPtr, 'i32')\n const hasAnimation = this.wasmModule.getValue(hasAnimationPtr, 'i8') !== 0\n\n this.wasmModule._free(pointCountPtr)\n this.wasmModule._free(hasAnimationPtr)\n\n this.characterInfo = { pointCount, hasAnimation }\n }\n catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error)\n logger.errorWithError('❌ Failed to query character info:', errorMessage)\n }\n }\n\n /**\n * 检查错误码并抛出异常\n */\n private checkError(errorCode: number, functionName: string): void {\n if (errorCode !== 0) {\n const errorName = this.errorCodes[errorCode] || `UNKNOWN_ERROR_${errorCode}`\n const errorMessage = this.api.getErrorString(errorCode)\n logger.errorWithError(`❌ ${functionName} failed: code=${errorCode}, name=${errorName}, message=${errorMessage}`, new Error(`${functionName} failed: ${errorName} - ${errorMessage}`))\n throw new Error(`${functionName} failed: ${errorName} - ${errorMessage}`)\n }\n }\n\n /**\n * 更新进度回调\n */\n private async updateProgress(callback: ProgressCallback | null, message: string, progress: number): Promise<void> {\n if (callback && typeof callback === 'function') {\n callback({ message, progress })\n }\n }\n\n /**\n * 获取性能指标\n */\n getPerformanceMetrics(): PerformanceMetrics & {\n flameInfo?: FlameInfo\n characterInfo?: CharacterInfo\n version?: string\n } {\n return {\n ...this.performanceMetrics,\n flameInfo: this.flameInfo,\n characterInfo: this.characterInfo,\n version: this.api.getVersion?.() || 'unknown',\n }\n }\n\n /**\n * 释放当前角色和动画资源(但保留 core)\n */\n /**\n * Remove a specific character by handle\n * @param characterHandle Character handle to remove\n * @param characterId Optional character ID for cleanup\n */\n removeCharacter(characterHandle: number, characterId?: string): void {\n try {\n if (!this.coreHandle) {\n throw new Error('Avatar Core not initialized')\n }\n\n // Remove character from WASM\n this.api.removeCharacter(this.coreHandle, characterHandle)\n\n // Clean up animation if exists\n const id = characterId || 'default'\n const animInfo = this.animationHandles.get(id)\n if (animInfo && this.coreHandle) {\n this.api.removeAnimation(this.coreHandle, animInfo.handle)\n this.animationHandles.delete(id)\n }\n\n // Remove from handles map\n this.characterHandles.delete(id)\n\n // Legacy support: clear if this was the default character\n if (!characterId && this.characterHandle === characterHandle) {\n this.characterHandle = null\n this.animationHandle = null\n this.totalFrames = null\n this.isCharacterLoaded = false\n }\n\n // Note: resetProcessorForReuse is no longer needed - WASM handles cleanup automatically\n }\n catch (error) {\n logger.errorWithError('❌ Failed to remove character:', error)\n }\n }\n\n /**\n * Release current character (legacy method, kept for backward compatibility)\n * @deprecated Use removeCharacter() instead for multi-character support\n */\n releaseCurrentCharacter(): void {\n if (this.characterHandle) {\n this.removeCharacter(this.characterHandle)\n }\n }\n\n /**\n * 释放所有资源(包括 core)\n */\n release(): void {\n try {\n // 先释放角色和动画\n this.releaseCurrentCharacter()\n\n // 释放 Core\n if (this.coreHandle) {\n this.api.release(this.coreHandle)\n this.coreHandle = null\n }\n\n // 清理内存\n if (this.memoryManager) {\n this.memoryManager.cleanup()\n }\n\n this.isInitialized = false\n\n if (this.wasmModule.HEAPU8) {\n // 清理可能的缓存\n if (this.wasmModule.HEAPU8.buffer) {\n // 强制垃圾回收(如果支持)\n if (typeof gc !== 'undefined') {\n gc()\n }\n }\n }\n }\n catch (error) {\n logger.errorWithError('❌ Failed to release resources:', error)\n }\n }\n\n /**\n * 兼容性接口:提供与 FlameComplete3DGSManager 相同的接口\n */\n\n // 兼容 loadFlameModel\n // eslint-disable-next-line ts/no-explicit-any\n async loadFlameModel(_modelData: any): Promise<boolean> {\n // Avatar Core 通过初始化时加载模板资源,这里是空实现\n return true\n }\n\n // 兼容 load3DGSData\n // eslint-disable-next-line ts/no-explicit-any\n async load3DGSData(_original3DGSPoints: any, _binding: any, _flameFaces: any): Promise<boolean> {\n // Avatar Core 通过 loadCharacter 处理,这里是空实现\n return true\n }\n\n /**\n * 计算帧并返回 GPU 友好的 flat 格式(零拷贝,协方差预计算)\n * 🚀 性能优化版本:\n * - C++ 预计算协方差矩阵\n * - 零拷贝直接访问 WASM 内存http://localhost:3000/us/\n * - 直接输出 GPU 格式 [pos3, color4, cov6]\n */\n /**\n * Compute complete frame from animation\n * @param params Frame parameters\n * @param characterHandle Optional character handle (for multi-character support)\n */\n async computeCompleteFrameFlat(params?: { frameIndex?: number }, characterHandle?: number): Promise<Float32Array | null> {\n if (!this.isCharacterLoaded) {\n throw new Error('Character not loaded')\n }\n\n const startTime = performance.now()\n let outputPtr: number | null = null\n let paramsPtr: number | null = null\n\n try {\n const frameIndex = params?.frameIndex ?? 0\n \n // Extract characterId from characterHandle if needed\n const charHandle = characterHandle || this.characterHandle\n let characterId: string | undefined\n if (charHandle) {\n // Reverse lookup: find characterId from characterHandle\n for (const [id, handle] of this.characterHandles.entries()) {\n if (handle === charHandle) {\n characterId = id\n break\n }\n }\n // If not found in map, use 'default' for legacy support\n if (!characterId && charHandle === this.characterHandle) {\n characterId = 'default'\n }\n }\n\n // 获取指定帧的参数\n paramsPtr = await this.getAnimationFrameParams(frameIndex, characterId)\n\n // 分配输出结构体\n outputPtr = this.wasmModule._malloc(16) // AvatarSplatPointFlatArray 大小\n\n // 调用 flat 版本的计算函数\n if (!charHandle) {\n throw new Error('No character loaded')\n }\n \n const result = this.api.computeFrameFlat(\n this.coreHandle,\n charHandle,\n paramsPtr,\n outputPtr,\n )\n\n this.checkError(result, 'avatar_core_compute_frame_as_splat_points_flat')\n\n // 读取结果(已经是复制的数据,无需再次复制)\n const flatData = this.memoryManager!.readSplatPointFlatArray(outputPtr!)\n\n // 更新性能指标\n const computeTime = performance.now() - startTime\n this.wasmTime = computeTime // 记录最近一次耗时\n this.performanceMetrics.computeFrames++\n this.performanceMetrics.totalComputeTime += computeTime\n this.performanceMetrics.averageComputeTime\n = this.performanceMetrics.totalComputeTime / this.performanceMetrics.computeFrames\n\n return flatData\n }\n catch (error) {\n logger.errorWithError('❌ computeCompleteFrameFlat failed:', error)\n const errorMessage = error instanceof Error ? error.message : String(error)\n throw new Error(`computeCompleteFrameFlat failed: ${errorMessage}`)\n }\n finally {\n // 清理内存(必须按正确顺序)\n if (outputPtr !== null) {\n // 释放 C++ 分配的点云数据\n this.api.freeSplatPointsFlat(outputPtr)\n // 释放输出结构体\n this.wasmModule._free(outputPtr)\n }\n if (paramsPtr !== null) {\n this.wasmModule._free(paramsPtr)\n }\n }\n }\n\n /**\n * 计算帧并返回 GPU 友好的 flat 格式(从 FLAME 参数)\n * 🔑 用于 Realtime: 接受自定义 FLAME 参数并计算 Splat\n */\n /**\n * Compute frame from Flame parameters\n * @param flameParams Flame parameters\n * @param characterHandle Optional character handle (for multi-character support)\n */\n async computeFrameFlatFromParams(flameParams: FlameParams, characterHandle?: number): Promise<Float32Array | null> {\n if (!this.isCharacterLoaded) {\n throw new Error('Character not loaded')\n }\n\n const startTime = performance.now()\n let outputPtr: number | null = null\n let paramsPtr: number | null = null\n\n try {\n // 创建参数结构体\n paramsPtr = this.memoryManager!.createFlameParams(flameParams)\n\n // 分配输出结构体\n outputPtr = this.wasmModule._malloc(16) // AvatarSplatPointFlatArray 大小\n\n // 调用 flat 版本的计算函数\n const charHandle = characterHandle || this.characterHandle\n if (!charHandle) {\n throw new Error('No character loaded')\n }\n \n const result = this.api.computeFrameFlat(\n this.coreHandle,\n charHandle,\n paramsPtr,\n outputPtr,\n )\n\n this.checkError(result, 'avatar_core_compute_frame_as_splat_points_flat')\n\n // 读取结果\n const flatData = this.memoryManager!.readSplatPointFlatArray(outputPtr!)\n\n // 更新性能指标\n const computeTime = performance.now() - startTime\n this.wasmTime = computeTime\n this.performanceMetrics.computeFrames++\n this.performanceMetrics.totalComputeTime += computeTime\n this.performanceMetrics.averageComputeTime\n = this.performanceMetrics.totalComputeTime / this.performanceMetrics.computeFrames\n\n return flatData\n }\n catch (error) {\n logger.errorWithError('❌ computeFrameFlatFromParams failed:', error)\n const errorMessage = error instanceof Error ? error.message : String(error)\n throw new Error(`computeFrameFlatFromParams failed: ${errorMessage}`)\n }\n finally {\n // 清理内存\n if (outputPtr !== null) {\n this.api.freeSplatPointsFlat(outputPtr)\n this.wasmModule._free(outputPtr)\n }\n if (paramsPtr !== null) {\n this.wasmModule._free(paramsPtr)\n }\n }\n }\n\n /**\n * 获取 WASM 内存使用情况(MB)\n * @returns WASM 内存使用量(MB),如果模块未加载则返回 null\n */\n getWASMMemoryMB(): number | null {\n if (!this.wasmModule) {\n return null\n }\n \n // Emscripten WASM 模块的 buffer 属性包含 WASM 内存\n if (this.wasmModule.buffer && this.wasmModule.buffer instanceof ArrayBuffer) {\n const bytes = this.wasmModule.buffer.byteLength\n const mb = bytes / (1024 * 1024)\n return Math.round(mb * 100) / 100 // 保留两位小数\n }\n \n // 如果没有 buffer,尝试从 HEAPU8 获取\n if (this.wasmModule.HEAPU8 && this.wasmModule.HEAPU8.buffer) {\n const bytes = this.wasmModule.HEAPU8.buffer.byteLength\n const mb = bytes / (1024 * 1024)\n return Math.round(mb * 100) / 100\n }\n \n return null\n }\n\n}\n","/**\n * AvatarKit:负责 SDK 初始化和配置\n * 所有公开接口全部采用 Class/Static Func;无需开发者访问单例/实例化\n */\n\nimport type { Configuration } from '../types'\n\nimport { clearSdkConfigCache, fetchSdkConfig } from '../config/sdk-config-loader'\nimport { Environment } from '../types'\nimport { logger } from '../utils/logger'\nimport { initializeCLS, trackEvent, cleanupCLS } from '../utils/cls-tracker'\nimport { AvatarCoreAdapter } from '../wasm/avatarCoreAdapter'\n\nexport class AvatarKit {\n private static _isInitialized = false\n private static _appId: string | null = null\n private static _configuration: Configuration | null = null\n private static _sessionToken: string | null = null\n private static _userId: string | null = null\n private static readonly _version: string = typeof __SDK_VERSION__ !== 'undefined' ? __SDK_VERSION__ : '1.0.0'\n private static _avatarCore: AvatarCoreAdapter | null = null\n private static _dynamicSdkConfig: Partial<Record<Environment, string>> | null = null\n private static readonly _logLevels = {\n debug: 'log',\n info: 'log',\n warning: 'warn',\n error: 'error',\n } as const\n\n /**\n * SDK 初始化\n * @param appId 前端需要在 HTTP Headers 和 WebSocket Headers 中都带上\n * @param configuration 配置参数\n */\n static async initialize(appId: string, configuration: Configuration): Promise<void> {\n try {\n if (this._isInitialized) {\n // 如果已经初始化,只需要更新配置\n logger.log(`[AvatarKit] Re-initializing with new environment: ${configuration.environment}`)\n this._appId = appId\n this._configuration = configuration\n return\n }\n\n logger.log(`[AvatarKit] Initializing with appId: ${appId}, environment: ${configuration.environment}`)\n\n // 1. 初始化配置\n this._appId = appId\n this._configuration = configuration\n\n // 2. 初始化 CLS 日志上报(传入环境信息)\n initializeCLS(configuration.environment)\n\n // 3. 从配置接口获取sdkApiBaseUrl(与WASM初始化并行)\n this._fetchSdkConfig().catch((err) => {\n const message = err instanceof Error ? err.message : String(err)\n logger.warn('Failed to fetch SDK config from remote, using defaults:', message)\n this.logEvent('sdk_config', 'warning', {\n reason: message,\n })\n })\n\n // 4. 初始化WASM模块\n await this.initializeWASMModule()\n\n // 5. 加载模板资源(失败直接抛出错误,阻止初始化)\n await this.initializeTemplateResources()\n\n this._isInitialized = true\n\n logger.log(`[AvatarKit] Successfully initialized`)\n }\n catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error)\n logger.error('Failed to initialize AvatarKit:', errorMessage)\n this.logEvent('sdk_startup', 'error', {\n reason: errorMessage,\n })\n throw error\n }\n }\n\n /**\n * 初始化WASM模块(跟随整个SDK生命周期)\n */\n private static async initializeWASMModule(): Promise<void> {\n try {\n logger.log('[AvatarKit] Initializing WASM module...')\n\n // 创建AvatarCoreAdapter实例\n this._avatarCore = new AvatarCoreAdapter({\n logLevel: 'basic',\n enableValidation: true,\n enablePerformanceMetrics: true,\n baseAssetsPath: '',\n wasmPath: './avatar_core_wasm.js',\n wasmConfig: {\n // Print function for debugging WASM output\n print: (text: string) => {\n logger.log(`[WASM] ${text}`)\n },\n printErr: (text: string) => {\n logger.error(`[WASM ERROR] ${text}`)\n },\n // 配置 locateFile 以确保能找到 WASM 文件\n // WASM 文件与 Emscripten JS 文件在同一目录(dist/ 根目录)\n locateFile: (path: string, prefix: string) => {\n // 如果 path 已经是完整 URL(data URL 或 http(s) URL),直接返回\n if (path.startsWith('data:') || path.startsWith('http://') || path.startsWith('https://')) {\n return path\n }\n // 确保路径拼接正确:如果 prefix 末尾没有斜杠,则添加\n return prefix.endsWith('/') ? prefix + path : `${prefix}/${path}`\n },\n },\n })\n\n // 加载WASM模块\n await this._avatarCore.loadWASMModule()\n\n logger.log('[AvatarKit] WASM module initialized successfully')\n }\n catch (error) {\n logger.error('Failed to initialize WASM module:', error instanceof Error ? error.message : String(error))\n throw new Error(`WASM module initialization failed: ${error instanceof Error ? error.message : String(error)}`)\n }\n }\n\n /**\n * 初始化模板资源(在SDK初始化时加载)\n * 失败时直接抛出错误,阻止SDK初始化\n */\n private static async initializeTemplateResources(): Promise<void> {\n if (!this._avatarCore) {\n throw new Error('AvatarCore not available')\n }\n\n logger.log('[AvatarKit] Loading template resources...')\n \n try {\n // 导入 AvatarDownloader(避免循环依赖)\n const { AvatarDownloader } = await import('./AvatarDownloader')\n const downloader = new AvatarDownloader()\n \n // 从全局 CDN 加载模板资源\n const templateResources = await downloader.loadGlobalFlameResources()\n \n // 加载到 WASM Core(如果已初始化,loadTemplateResourcesFromBuffers 内部会直接返回)\n const success = await this._avatarCore.loadTemplateResourcesFromBuffers(templateResources)\n if (success) {\n logger.log('[AvatarKit] Template resources initialized successfully')\n } else {\n logger.log('[AvatarKit] Template resources already initialized, skipping...')\n }\n }\n catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error)\n logger.error('[AvatarKit] Failed to initialize template resources:', errorMessage)\n this.logEvent('template_init', 'error', {\n reason: errorMessage,\n stage: 'sdk_init',\n })\n throw new Error(`SDK initialization failed: Template resources loading failed - ${errorMessage}`)\n }\n }\n\n /**\n * 设置 sessionToken\n * 开发者 Client -> 开发者 Server -> SP Server -> return sessionToken(最长一小时有效时间)\n * 在 WebSocket Headers 中带上,用于数字人 WebSocket 服务鉴权\n */\n static setSessionToken(token: string): void {\n this._sessionToken = token\n }\n\n /**\n * 设置 userId\n * 开发者可选接口,SDK 在日志埋点中带上\n */\n static setUserId(userId: string): void {\n this._userId = userId\n }\n\n // 只读属性\n static get isInitialized(): boolean {\n return this._isInitialized\n }\n\n static get appId(): string | null {\n return this._appId\n }\n\n static get configuration(): Configuration | null {\n return this._configuration\n }\n\n static get sessionToken(): string | null {\n return this._sessionToken\n }\n\n static get userId(): string | null {\n return this._userId\n }\n\n static get version(): string {\n return this._version\n }\n\n /**\n * 获取AvatarCore实例(仅供 SDK 内部使用)\n * @internal\n */\n static getAvatarCore(): AvatarCoreAdapter | null {\n return this._avatarCore\n }\n\n /**\n * 清理资源\n */\n static cleanup(): void {\n if (!this._isInitialized) {\n return\n }\n\n try {\n if (this._avatarCore) {\n this._avatarCore.release()\n this._avatarCore = null\n }\n\n this._appId = null\n this._configuration = null\n this._sessionToken = null\n this._userId = null\n this._dynamicSdkConfig = null\n this._isInitialized = false\n\n clearSdkConfigCache()\n cleanupCLS()\n\n logger.log('[AvatarKit] Cleanup completed')\n }\n catch (error) {\n logger.error('Failed to cleanup AvatarKit:', error instanceof Error ? error.message : String(error))\n }\n }\n\n /**\n * 从远程配置接口获取SDK配置(已简化,逻辑移到 config/sdk-config-loader.ts)\n */\n private static async _fetchSdkConfig(): Promise<void> {\n try {\n this._dynamicSdkConfig = await fetchSdkConfig(this._version)\n }\n catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n logger.warn('Failed to fetch SDK config from remote, using defaults:', message)\n this.logEvent('sdk_config', 'warning', {\n reason: message,\n })\n // 不抛出错误,使用默认配置\n }\n }\n\n /**\n * 获取环境配置(对齐 web 应用的 region-config)\n * @internal\n */\n static getEnvironmentConfig(): {\n sdkApiBaseUrl: string\n driveningressWsUrl: string\n } {\n if (!this._configuration) {\n throw new Error('AvatarKit not initialized')\n }\n\n // 默认配置(降级方案)\n const defaultConfigs: Record<Environment, { sdkApiBaseUrl: string, driveningressWsUrl: string }> = {\n [Environment.cn]: {\n sdkApiBaseUrl: 'https://api.spatialwalk.top',\n driveningressWsUrl: 'wss://api.spatialwalk.top/v1/driveningress/websocket',\n },\n [Environment.us]: {\n sdkApiBaseUrl: 'https://api.spatialwalk.cloud',\n driveningressWsUrl: 'wss://api.spatialwalk.cloud/v1/driveningress/websocket',\n },\n [Environment.test]: {\n sdkApiBaseUrl: 'https://api-test.spatialwalk.top',\n driveningressWsUrl: 'wss://api-test.spatialwalk.top/v1/driveningress/websocket',\n },\n }\n\n const defaultConfig = defaultConfigs[this._configuration.environment]\n if (!defaultConfig) {\n throw new Error('Unknown environment')\n }\n\n // 如果已获取动态配置,使用动态配置的sdkApiBaseUrl,否则使用默认值\n const sdkApiBaseUrl = this._dynamicSdkConfig?.[this._configuration.environment] || defaultConfig.sdkApiBaseUrl\n\n return {\n sdkApiBaseUrl,\n driveningressWsUrl: defaultConfig.driveningressWsUrl,\n }\n }\n\n /**\n * 统一的 Telemetry 日志接口,对齐 iOS 版本的 SPAvatarSDK.log\n * 使用腾讯云 CLS 进行日志上报\n * @internal\n */\n static logEvent(\n event: string,\n level: 'debug' | 'info' | 'warning' | 'error' = 'info',\n contents: Record<string, unknown> = {},\n ): void {\n const context = {\n environment: this._configuration?.environment ?? 'unknown',\n sessionToken: this._sessionToken ?? '',\n userId: this._userId ?? '',\n sdkVersion: this._version,\n ...contents,\n }\n\n const logMethod = this._logLevels[level] ?? 'log'\n // @ts-expect-error dynamic method access\n logger[logMethod](`[Telemetry] ${event}`, context)\n\n // 上报到腾讯云 CLS\n trackEvent(event, level, context)\n }\n}\n","/**\n * 音频动画同步播放器\n * 支持 HTMLAudioElement(传统方式)和 StreamingAudioPlayer(流式播放)\n */\n\nimport type { StreamingAudioPlayer } from './StreamingAudioPlayer'\n\nimport { APP_CONFIG } from '../config/app-config'\nimport { AvatarKit } from '../core/AvatarKit'\nimport { logger } from '../utils/logger'\n\nexport class AnimationPlayer {\n private audio: HTMLAudioElement | null = null\n private streamingPlayer: StreamingAudioPlayer | null = null\n private _isPlaying = false\n private fps = APP_CONFIG.animation.fps\n private onEndedCallback?: () => void\n private static audioUnlocked = false\n private useStreaming = false\n\n /**\n * 解锁音频上下文(Safari 自动播放策略)\n * 必须在用户交互事件(如 click)中调用\n */\n static async unlockAudioContext(): Promise<void> {\n if (AnimationPlayer.audioUnlocked) {\n return\n }\n\n try {\n // 创建一个极短的静音音频并播放\n const silentAudio = new Audio()\n silentAudio.src = 'data:audio/wav;base64,UklGRigAAABXQVZFZm10IBIAAAABAAEARKwAAIhYAQACABAAAABkYXRhAgAAAAEA'\n silentAudio.volume = 0\n\n // 尝试播放以解锁音频上下文\n await silentAudio.play()\n\n // 立即停止\n silentAudio.pause()\n silentAudio.currentTime = 0\n\n AnimationPlayer.audioUnlocked = true\n logger.log('✅ Audio context unlocked for Safari')\n }\n catch (err) {\n logger.warn('⚠️ Failed to unlock audio context:', err)\n // 不抛出错误,让后续正常流程继续\n }\n }\n\n /**\n * Initialize with HTMLAudioElement (traditional way)\n */\n async initialize(audioUrl: string, onEnded?: () => void): Promise<void> {\n this.onEndedCallback = onEnded\n this.useStreaming = false\n\n return new Promise((resolve, reject) => {\n this.audio = new Audio(audioUrl)\n\n this.audio.addEventListener('canplaythrough', () => {\n this.setupEventListeners()\n resolve()\n }, { once: true })\n\n this.audio.addEventListener('error', () => {\n reject(new Error(`Failed to load audio: ${audioUrl}`))\n }, { once: true })\n\n this.audio.load()\n })\n }\n\n /**\n * Initialize with StreamingAudioPlayer (streaming way)\n * @deprecated 使用 prepareStreamingPlayer() 代替\n */\n async initializeStreaming(streamingPlayer: StreamingAudioPlayer, onEnded?: () => void): Promise<void> {\n this.streamingPlayer = streamingPlayer\n this.onEndedCallback = onEnded\n this.useStreaming = true\n\n // Set ended callback on streaming player\n this.streamingPlayer.onEnded(() => {\n this._isPlaying = false\n this.onEndedCallback?.()\n })\n }\n\n /**\n * 检查流式播放器是否已准备好\n */\n isStreamingReady(): boolean {\n return this.useStreaming && this.streamingPlayer !== null\n }\n\n /**\n * 获取流式播放器实例\n */\n getStreamingPlayer(): StreamingAudioPlayer | null {\n return this.streamingPlayer\n }\n\n /**\n * 创建并初始化流式播放器\n * 在服务连接建立时调用\n */\n async createAndInitializeStreamingPlayer(): Promise<void> {\n if (this.streamingPlayer) {\n // 已创建,直接返回\n return\n }\n\n const { StreamingAudioPlayer } = await import('./StreamingAudioPlayer')\n this.streamingPlayer = new StreamingAudioPlayer({\n sampleRate: APP_CONFIG.audio.sampleRate,\n channelCount: 1,\n debug: false,\n })\n try {\n await this.streamingPlayer.initialize()\n }\n catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n logger.error('[AnimationPlayer] Failed to initialize streaming player:', message)\n AvatarKit.logEvent('character_player', 'error', {\n event: 'streaming_player_initialize_failed',\n reason: message,\n })\n throw error\n }\n this.useStreaming = true\n }\n\n /**\n * 准备流式播放器(如果未创建则创建并初始化)\n * 停止之前的播放并更新结束回调\n */\n async prepareStreamingPlayer(onEnded?: () => void): Promise<void> {\n if (!this.streamingPlayer) {\n // 如果播放器未创建,创建并初始化\n await this.createAndInitializeStreamingPlayer()\n }\n\n if (!this.streamingPlayer) {\n throw new Error('Failed to create streaming player')\n }\n\n // 停止之前的播放并更新回调\n this.streamingPlayer.stop()\n this.onEndedCallback = onEnded\n this.streamingPlayer.onEnded(() => {\n this._isPlaying = false\n this.onEndedCallback?.()\n })\n }\n\n private setupEventListeners(): void {\n if (!this.audio)\n return\n\n this.audio.addEventListener('play', () => {\n this._isPlaying = true\n })\n\n this.audio.addEventListener('ended', () => {\n this._isPlaying = false\n this.onEndedCallback?.()\n })\n\n }\n\n async play(): Promise<void> {\n if (this.useStreaming) {\n // Streaming mode: just mark as playing (chunks will auto-play)\n this._isPlaying = true\n }\n else {\n // Traditional mode\n if (!this.audio)\n throw new Error('Audio not loaded')\n this.audio.currentTime = 0\n await this.audio.play()\n }\n }\n\n stop(): void {\n this._isPlaying = false\n\n if (this.useStreaming) {\n this.streamingPlayer?.stop()\n }\n else {\n if (this.audio) {\n this.audio.pause()\n this.audio.currentTime = 0\n }\n }\n }\n\n isPlaying(): boolean {\n if (this.useStreaming) {\n return this._isPlaying && this.streamingPlayer?.isPlayingNow() === true\n }\n return this._isPlaying\n }\n\n getCurrentFrameIndex(): number {\n const currentTime = this.getCurrentTime()\n return Math.floor(currentTime * this.fps)\n }\n\n /**\n * Get current playback time\n */\n getCurrentTime(): number {\n if (this.useStreaming) {\n return this.streamingPlayer?.getCurrentTime() ?? 0\n }\n return this.audio?.currentTime ?? 0\n }\n\n /**\n * 添加音频块(仅用于流式播放)\n */\n addAudioChunk(audio: Uint8Array, isLast: boolean = false): void {\n if (this.useStreaming && this.streamingPlayer) {\n this.streamingPlayer.addChunk(audio, isLast)\n } else {\n logger.warn('[AnimationPlayer] Cannot add audio chunk - streaming player not ready')\n }\n }\n\n /**\n * 暂停播放\n */\n pause(): void {\n if (this.useStreaming) {\n this.streamingPlayer?.pause()\n } else {\n if (this.audio) {\n this.audio.pause()\n }\n }\n }\n\n /**\n * 继续播放\n */\n async resume(): Promise<void> {\n if (this.useStreaming) {\n await this.streamingPlayer?.resume()\n } else {\n if (this.audio) {\n await this.audio.play()\n }\n }\n }\n\n dispose(): void {\n this.stop()\n\n if (this.audio) {\n this.audio.src = ''\n this.audio = null\n }\n\n if (this.streamingPlayer) {\n this.streamingPlayer.dispose()\n this.streamingPlayer = null\n }\n\n this.onEndedCallback = undefined\n }\n}\n","/* @ts-self-types=\"./index.d.ts\" */\nimport { urlAlphabet as scopedUrlAlphabet } from './url-alphabet/index.js'\nexport { urlAlphabet } from './url-alphabet/index.js'\nexport let random = bytes => crypto.getRandomValues(new Uint8Array(bytes))\nexport let customRandom = (alphabet, defaultSize, getRandom) => {\n let mask = (2 << Math.log2(alphabet.length - 1)) - 1\n let step = -~((1.6 * mask * defaultSize) / alphabet.length)\n return (size = defaultSize) => {\n let id = ''\n while (true) {\n let bytes = getRandom(step)\n let j = step | 0\n while (j--) {\n id += alphabet[bytes[j] & mask] || ''\n if (id.length >= size) return id\n }\n }\n }\n}\nexport let customAlphabet = (alphabet, size = 21) =>\n customRandom(alphabet, size | 0, random)\nexport let nanoid = (size = 21) => {\n let id = ''\n let bytes = crypto.getRandomValues(new Uint8Array((size |= 0)))\n while (size--) {\n id += scopedUrlAlphabet[bytes[size] & 63]\n }\n return id\n}\n","/**\n * Conversation ID 生成工具\n * \n * 统一格式:时间戳(UTC时间,秒级,格式:YYYYMMDDHHmmss)+ 下划线 + 12位 NanoID\n * 示例:20251027143034_aB3dEf9hIjKl\n * \n * 时间部分使用 UTC 时间,便于跨端日志排查时统一转换时区检索\n */\n\nimport { customAlphabet } from 'nanoid'\n\n/**\n * 自定义字符集:只使用大小写字母和数字(URL 安全,不包含连字符)\n * 字符集:A-Z, a-z, 0-9 (62 个字符)\n */\nconst nanoid = customAlphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789', 12)\n\n/**\n * 生成统一的会话 ID\n * \n * 格式:时间戳(UTC时间,秒级,格式:YYYYMMDDHHmmss)+ 下划线 + 12位 NanoID\n * 时间部分使用 UTC 时间,便于跨端日志排查时统一转换时区检索\n * \n * @returns 格式为 YYYYMMDDHHmmss_nanoid 的会话 ID\n * @example\n * generateConversationId() // \"20251027143034_aB3dEf9hIjKl\"\n */\nexport function generateConversationId(): string {\n // 获取当前 UTC 时间\n const now = new Date()\n \n // 格式化为 YYYYMMDDHHmmss(UTC 时间)\n const year = now.getUTCFullYear()\n const month = String(now.getUTCMonth() + 1).padStart(2, '0')\n const day = String(now.getUTCDate()).padStart(2, '0')\n const hours = String(now.getUTCHours()).padStart(2, '0')\n const minutes = String(now.getUTCMinutes()).padStart(2, '0')\n const seconds = String(now.getUTCSeconds()).padStart(2, '0')\n \n const timestamp = `${year}${month}${day}${hours}${minutes}${seconds}`\n \n // 生成 12 位 NanoID(只包含字母和数字)\n const nanoId = nanoid()\n \n return `${timestamp}_${nanoId}`\n}\n\n","// Copyright 2008 Google Inc. All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n// * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n// * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n// * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n//\n// Code generated by the Protocol Buffer compiler is owned by the owner\n// of the input file used when generating it. This code is not\n// standalone and requires a support library to be linked with it. This\n// support library is itself covered by the above license.\n/**\n * Read a 64 bit varint as two JS numbers.\n *\n * Returns tuple:\n * [0]: low bits\n * [1]: high bits\n *\n * Copyright 2008 Google Inc. All rights reserved.\n *\n * See https://github.com/protocolbuffers/protobuf/blob/8a71927d74a4ce34efe2d8769fda198f52d20d12/js/experimental/runtime/kernel/buffer_decoder.js#L175\n */\nexport function varint64read() {\n let lowBits = 0;\n let highBits = 0;\n for (let shift = 0; shift < 28; shift += 7) {\n let b = this.buf[this.pos++];\n lowBits |= (b & 0x7f) << shift;\n if ((b & 0x80) == 0) {\n this.assertBounds();\n return [lowBits, highBits];\n }\n }\n let middleByte = this.buf[this.pos++];\n // last four bits of the first 32 bit number\n lowBits |= (middleByte & 0x0f) << 28;\n // 3 upper bits are part of the next 32 bit number\n highBits = (middleByte & 0x70) >> 4;\n if ((middleByte & 0x80) == 0) {\n this.assertBounds();\n return [lowBits, highBits];\n }\n for (let shift = 3; shift <= 31; shift += 7) {\n let b = this.buf[this.pos++];\n highBits |= (b & 0x7f) << shift;\n if ((b & 0x80) == 0) {\n this.assertBounds();\n return [lowBits, highBits];\n }\n }\n throw new Error(\"invalid varint\");\n}\n/**\n * Write a 64 bit varint, given as two JS numbers, to the given bytes array.\n *\n * Copyright 2008 Google Inc. All rights reserved.\n *\n * See https://github.com/protocolbuffers/protobuf/blob/8a71927d74a4ce34efe2d8769fda198f52d20d12/js/experimental/runtime/kernel/writer.js#L344\n */\nexport function varint64write(lo, hi, bytes) {\n for (let i = 0; i < 28; i = i + 7) {\n const shift = lo >>> i;\n const hasNext = !(shift >>> 7 == 0 && hi == 0);\n const byte = (hasNext ? shift | 0x80 : shift) & 0xff;\n bytes.push(byte);\n if (!hasNext) {\n return;\n }\n }\n const splitBits = ((lo >>> 28) & 0x0f) | ((hi & 0x07) << 4);\n const hasMoreBits = !(hi >> 3 == 0);\n bytes.push((hasMoreBits ? splitBits | 0x80 : splitBits) & 0xff);\n if (!hasMoreBits) {\n return;\n }\n for (let i = 3; i < 31; i = i + 7) {\n const shift = hi >>> i;\n const hasNext = !(shift >>> 7 == 0);\n const byte = (hasNext ? shift | 0x80 : shift) & 0xff;\n bytes.push(byte);\n if (!hasNext) {\n return;\n }\n }\n bytes.push((hi >>> 31) & 0x01);\n}\n// constants for binary math\nconst TWO_PWR_32_DBL = 0x100000000;\n/**\n * Parse decimal string of 64 bit integer value as two JS numbers.\n *\n * Copyright 2008 Google Inc. All rights reserved.\n *\n * See https://github.com/protocolbuffers/protobuf-javascript/blob/a428c58273abad07c66071d9753bc4d1289de426/experimental/runtime/int64.js#L10\n */\nexport function int64FromString(dec) {\n // Check for minus sign.\n const minus = dec[0] === \"-\";\n if (minus) {\n dec = dec.slice(1);\n }\n // Work 6 decimal digits at a time, acting like we're converting base 1e6\n // digits to binary. This is safe to do with floating point math because\n // Number.isSafeInteger(ALL_32_BITS * 1e6) == true.\n const base = 1e6;\n let lowBits = 0;\n let highBits = 0;\n function add1e6digit(begin, end) {\n // Note: Number('') is 0.\n const digit1e6 = Number(dec.slice(begin, end));\n highBits *= base;\n lowBits = lowBits * base + digit1e6;\n // Carry bits from lowBits to\n if (lowBits >= TWO_PWR_32_DBL) {\n highBits = highBits + ((lowBits / TWO_PWR_32_DBL) | 0);\n lowBits = lowBits % TWO_PWR_32_DBL;\n }\n }\n add1e6digit(-24, -18);\n add1e6digit(-18, -12);\n add1e6digit(-12, -6);\n add1e6digit(-6);\n return minus ? negate(lowBits, highBits) : newBits(lowBits, highBits);\n}\n/**\n * Losslessly converts a 64-bit signed integer in 32:32 split representation\n * into a decimal string.\n *\n * Copyright 2008 Google Inc. All rights reserved.\n *\n * See https://github.com/protocolbuffers/protobuf-javascript/blob/a428c58273abad07c66071d9753bc4d1289de426/experimental/runtime/int64.js#L10\n */\nexport function int64ToString(lo, hi) {\n let bits = newBits(lo, hi);\n // If we're treating the input as a signed value and the high bit is set, do\n // a manual two's complement conversion before the decimal conversion.\n const negative = bits.hi & 0x80000000;\n if (negative) {\n bits = negate(bits.lo, bits.hi);\n }\n const result = uInt64ToString(bits.lo, bits.hi);\n return negative ? \"-\" + result : result;\n}\n/**\n * Losslessly converts a 64-bit unsigned integer in 32:32 split representation\n * into a decimal string.\n *\n * Copyright 2008 Google Inc. All rights reserved.\n *\n * See https://github.com/protocolbuffers/protobuf-javascript/blob/a428c58273abad07c66071d9753bc4d1289de426/experimental/runtime/int64.js#L10\n */\nexport function uInt64ToString(lo, hi) {\n ({ lo, hi } = toUnsigned(lo, hi));\n // Skip the expensive conversion if the number is small enough to use the\n // built-in conversions.\n // Number.MAX_SAFE_INTEGER = 0x001FFFFF FFFFFFFF, thus any number with\n // highBits <= 0x1FFFFF can be safely expressed with a double and retain\n // integer precision.\n // Proven by: Number.isSafeInteger(0x1FFFFF * 2**32 + 0xFFFFFFFF) == true.\n if (hi <= 0x1fffff) {\n return String(TWO_PWR_32_DBL * hi + lo);\n }\n // What this code is doing is essentially converting the input number from\n // base-2 to base-1e7, which allows us to represent the 64-bit range with\n // only 3 (very large) digits. Those digits are then trivial to convert to\n // a base-10 string.\n // The magic numbers used here are -\n // 2^24 = 16777216 = (1,6777216) in base-1e7.\n // 2^48 = 281474976710656 = (2,8147497,6710656) in base-1e7.\n // Split 32:32 representation into 16:24:24 representation so our\n // intermediate digits don't overflow.\n const low = lo & 0xffffff;\n const mid = ((lo >>> 24) | (hi << 8)) & 0xffffff;\n const high = (hi >> 16) & 0xffff;\n // Assemble our three base-1e7 digits, ignoring carries. The maximum\n // value in a digit at this step is representable as a 48-bit integer, which\n // can be stored in a 64-bit floating point number.\n let digitA = low + mid * 6777216 + high * 6710656;\n let digitB = mid + high * 8147497;\n let digitC = high * 2;\n // Apply carries from A to B and from B to C.\n const base = 10000000;\n if (digitA >= base) {\n digitB += Math.floor(digitA / base);\n digitA %= base;\n }\n if (digitB >= base) {\n digitC += Math.floor(digitB / base);\n digitB %= base;\n }\n // If digitC is 0, then we should have returned in the trivial code path\n // at the top for non-safe integers. Given this, we can assume both digitB\n // and digitA need leading zeros.\n return (digitC.toString() +\n decimalFrom1e7WithLeadingZeros(digitB) +\n decimalFrom1e7WithLeadingZeros(digitA));\n}\nfunction toUnsigned(lo, hi) {\n return { lo: lo >>> 0, hi: hi >>> 0 };\n}\nfunction newBits(lo, hi) {\n return { lo: lo | 0, hi: hi | 0 };\n}\n/**\n * Returns two's compliment negation of input.\n * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#Signed_32-bit_integers\n */\nfunction negate(lowBits, highBits) {\n highBits = ~highBits;\n if (lowBits) {\n lowBits = ~lowBits + 1;\n }\n else {\n // If lowBits is 0, then bitwise-not is 0xFFFFFFFF,\n // adding 1 to that, results in 0x100000000, which leaves\n // the low bits 0x0 and simply adds one to the high bits.\n highBits += 1;\n }\n return newBits(lowBits, highBits);\n}\n/**\n * Returns decimal representation of digit1e7 with leading zeros.\n */\nconst decimalFrom1e7WithLeadingZeros = (digit1e7) => {\n const partial = String(digit1e7);\n return \"0000000\".slice(partial.length) + partial;\n};\n/**\n * Write a 32 bit varint, signed or unsigned. Same as `varint64write(0, value, bytes)`\n *\n * Copyright 2008 Google Inc. All rights reserved.\n *\n * See https://github.com/protocolbuffers/protobuf/blob/1b18833f4f2a2f681f4e4a25cdf3b0a43115ec26/js/binary/encoder.js#L144\n */\nexport function varint32write(value, bytes) {\n if (value >= 0) {\n // write value as varint 32\n while (value > 0x7f) {\n bytes.push((value & 0x7f) | 0x80);\n value = value >>> 7;\n }\n bytes.push(value);\n }\n else {\n for (let i = 0; i < 9; i++) {\n bytes.push((value & 127) | 128);\n value = value >> 7;\n }\n bytes.push(1);\n }\n}\n/**\n * Read an unsigned 32 bit varint.\n *\n * See https://github.com/protocolbuffers/protobuf/blob/8a71927d74a4ce34efe2d8769fda198f52d20d12/js/experimental/runtime/kernel/buffer_decoder.js#L220\n */\nexport function varint32read() {\n let b = this.buf[this.pos++];\n let result = b & 0x7f;\n if ((b & 0x80) == 0) {\n this.assertBounds();\n return result;\n }\n b = this.buf[this.pos++];\n result |= (b & 0x7f) << 7;\n if ((b & 0x80) == 0) {\n this.assertBounds();\n return result;\n }\n b = this.buf[this.pos++];\n result |= (b & 0x7f) << 14;\n if ((b & 0x80) == 0) {\n this.assertBounds();\n return result;\n }\n b = this.buf[this.pos++];\n result |= (b & 0x7f) << 21;\n if ((b & 0x80) == 0) {\n this.assertBounds();\n return result;\n }\n // Extract only last 4 bits\n b = this.buf[this.pos++];\n result |= (b & 0x0f) << 28;\n for (let readBytes = 5; (b & 0x80) !== 0 && readBytes < 10; readBytes++)\n b = this.buf[this.pos++];\n if ((b & 0x80) != 0)\n throw new Error(\"invalid varint\");\n this.assertBounds();\n // Result can have 32 bits, convert it to unsigned\n return result >>> 0;\n}\n","// Copyright 2021-2025 Buf Technologies, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\nimport { int64FromString, int64ToString, uInt64ToString, } from \"./wire/varint.js\";\n/**\n * Int64Support for the current environment.\n */\nexport const protoInt64 = /*@__PURE__*/ makeInt64Support();\nfunction makeInt64Support() {\n const dv = new DataView(new ArrayBuffer(8));\n // note that Safari 14 implements BigInt, but not the DataView methods\n const ok = typeof BigInt === \"function\" &&\n typeof dv.getBigInt64 === \"function\" &&\n typeof dv.getBigUint64 === \"function\" &&\n typeof dv.setBigInt64 === \"function\" &&\n typeof dv.setBigUint64 === \"function\" &&\n (!!globalThis.Deno ||\n typeof process != \"object\" ||\n typeof process.env != \"object\" ||\n process.env.BUF_BIGINT_DISABLE !== \"1\");\n if (ok) {\n const MIN = BigInt(\"-9223372036854775808\");\n const MAX = BigInt(\"9223372036854775807\");\n const UMIN = BigInt(\"0\");\n const UMAX = BigInt(\"18446744073709551615\");\n return {\n zero: BigInt(0),\n supported: true,\n parse(value) {\n const bi = typeof value == \"bigint\" ? value : BigInt(value);\n if (bi > MAX || bi < MIN) {\n throw new Error(`invalid int64: ${value}`);\n }\n return bi;\n },\n uParse(value) {\n const bi = typeof value == \"bigint\" ? value : BigInt(value);\n if (bi > UMAX || bi < UMIN) {\n throw new Error(`invalid uint64: ${value}`);\n }\n return bi;\n },\n enc(value) {\n dv.setBigInt64(0, this.parse(value), true);\n return {\n lo: dv.getInt32(0, true),\n hi: dv.getInt32(4, true),\n };\n },\n uEnc(value) {\n dv.setBigInt64(0, this.uParse(value), true);\n return {\n lo: dv.getInt32(0, true),\n hi: dv.getInt32(4, true),\n };\n },\n dec(lo, hi) {\n dv.setInt32(0, lo, true);\n dv.setInt32(4, hi, true);\n return dv.getBigInt64(0, true);\n },\n uDec(lo, hi) {\n dv.setInt32(0, lo, true);\n dv.setInt32(4, hi, true);\n return dv.getBigUint64(0, true);\n },\n };\n }\n return {\n zero: \"0\",\n supported: false,\n parse(value) {\n if (typeof value != \"string\") {\n value = value.toString();\n }\n assertInt64String(value);\n return value;\n },\n uParse(value) {\n if (typeof value != \"string\") {\n value = value.toString();\n }\n assertUInt64String(value);\n return value;\n },\n enc(value) {\n if (typeof value != \"string\") {\n value = value.toString();\n }\n assertInt64String(value);\n return int64FromString(value);\n },\n uEnc(value) {\n if (typeof value != \"string\") {\n value = value.toString();\n }\n assertUInt64String(value);\n return int64FromString(value);\n },\n dec(lo, hi) {\n return int64ToString(lo, hi);\n },\n uDec(lo, hi) {\n return uInt64ToString(lo, hi);\n },\n };\n}\nfunction assertInt64String(value) {\n if (!/^-?[0-9]+$/.test(value)) {\n throw new Error(\"invalid int64: \" + value);\n }\n}\nfunction assertUInt64String(value) {\n if (!/^[0-9]+$/.test(value)) {\n throw new Error(\"invalid uint64: \" + value);\n }\n}\n","// Copyright 2021-2025 Buf Technologies, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\nconst symbol = Symbol.for(\"@bufbuild/protobuf/text-encoding\");\n/**\n * Protobuf-ES requires the Text Encoding API to convert UTF-8 from and to\n * binary. This WHATWG API is widely available, but it is not part of the\n * ECMAScript standard. On runtimes where it is not available, use this\n * function to provide your own implementation.\n *\n * Note that the Text Encoding API does not provide a way to validate UTF-8.\n * Our implementation falls back to use encodeURIComponent().\n */\nexport function configureTextEncoding(textEncoding) {\n globalThis[symbol] = textEncoding;\n}\nexport function getTextEncoding() {\n if (globalThis[symbol] == undefined) {\n const te = new globalThis.TextEncoder();\n const td = new globalThis.TextDecoder();\n globalThis[symbol] = {\n encodeUtf8(text) {\n return te.encode(text);\n },\n decodeUtf8(bytes) {\n return td.decode(bytes);\n },\n checkUtf8(text) {\n try {\n encodeURIComponent(text);\n return true;\n }\n catch (_) {\n return false;\n }\n },\n };\n }\n return globalThis[symbol];\n}\n","// Copyright 2021-2025 Buf Technologies, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\nimport { varint32read, varint32write, varint64read, varint64write, } from \"./varint.js\";\nimport { protoInt64 } from \"../proto-int64.js\";\nimport { getTextEncoding } from \"./text-encoding.js\";\n/**\n * Protobuf binary format wire types.\n *\n * A wire type provides just enough information to find the length of the\n * following value.\n *\n * See https://developers.google.com/protocol-buffers/docs/encoding#structure\n */\nexport var WireType;\n(function (WireType) {\n /**\n * Used for int32, int64, uint32, uint64, sint32, sint64, bool, enum\n */\n WireType[WireType[\"Varint\"] = 0] = \"Varint\";\n /**\n * Used for fixed64, sfixed64, double.\n * Always 8 bytes with little-endian byte order.\n */\n WireType[WireType[\"Bit64\"] = 1] = \"Bit64\";\n /**\n * Used for string, bytes, embedded messages, packed repeated fields\n *\n * Only repeated numeric types (types which use the varint, 32-bit,\n * or 64-bit wire types) can be packed. In proto3, such fields are\n * packed by default.\n */\n WireType[WireType[\"LengthDelimited\"] = 2] = \"LengthDelimited\";\n /**\n * Start of a tag-delimited aggregate, such as a proto2 group, or a message\n * in editions with message_encoding = DELIMITED.\n */\n WireType[WireType[\"StartGroup\"] = 3] = \"StartGroup\";\n /**\n * End of a tag-delimited aggregate.\n */\n WireType[WireType[\"EndGroup\"] = 4] = \"EndGroup\";\n /**\n * Used for fixed32, sfixed32, float.\n * Always 4 bytes with little-endian byte order.\n */\n WireType[WireType[\"Bit32\"] = 5] = \"Bit32\";\n})(WireType || (WireType = {}));\n/**\n * Maximum value for a 32-bit floating point value (Protobuf FLOAT).\n */\nexport const FLOAT32_MAX = 3.4028234663852886e38;\n/**\n * Minimum value for a 32-bit floating point value (Protobuf FLOAT).\n */\nexport const FLOAT32_MIN = -3.4028234663852886e38;\n/**\n * Maximum value for an unsigned 32-bit integer (Protobuf UINT32, FIXED32).\n */\nexport const UINT32_MAX = 0xffffffff;\n/**\n * Maximum value for a signed 32-bit integer (Protobuf INT32, SFIXED32, SINT32).\n */\nexport const INT32_MAX = 0x7fffffff;\n/**\n * Minimum value for a signed 32-bit integer (Protobuf INT32, SFIXED32, SINT32).\n */\nexport const INT32_MIN = -0x80000000;\nexport class BinaryWriter {\n constructor(encodeUtf8 = getTextEncoding().encodeUtf8) {\n this.encodeUtf8 = encodeUtf8;\n /**\n * Previous fork states.\n */\n this.stack = [];\n this.chunks = [];\n this.buf = [];\n }\n /**\n * Return all bytes written and reset this writer.\n */\n finish() {\n if (this.buf.length) {\n this.chunks.push(new Uint8Array(this.buf)); // flush the buffer\n this.buf = [];\n }\n let len = 0;\n for (let i = 0; i < this.chunks.length; i++)\n len += this.chunks[i].length;\n let bytes = new Uint8Array(len);\n let offset = 0;\n for (let i = 0; i < this.chunks.length; i++) {\n bytes.set(this.chunks[i], offset);\n offset += this.chunks[i].length;\n }\n this.chunks = [];\n return bytes;\n }\n /**\n * Start a new fork for length-delimited data like a message\n * or a packed repeated field.\n *\n * Must be joined later with `join()`.\n */\n fork() {\n this.stack.push({ chunks: this.chunks, buf: this.buf });\n this.chunks = [];\n this.buf = [];\n return this;\n }\n /**\n * Join the last fork. Write its length and bytes, then\n * return to the previous state.\n */\n join() {\n // get chunk of fork\n let chunk = this.finish();\n // restore previous state\n let prev = this.stack.pop();\n if (!prev)\n throw new Error(\"invalid state, fork stack empty\");\n this.chunks = prev.chunks;\n this.buf = prev.buf;\n // write length of chunk as varint\n this.uint32(chunk.byteLength);\n return this.raw(chunk);\n }\n /**\n * Writes a tag (field number and wire type).\n *\n * Equivalent to `uint32( (fieldNo << 3 | type) >>> 0 )`.\n *\n * Generated code should compute the tag ahead of time and call `uint32()`.\n */\n tag(fieldNo, type) {\n return this.uint32(((fieldNo << 3) | type) >>> 0);\n }\n /**\n * Write a chunk of raw bytes.\n */\n raw(chunk) {\n if (this.buf.length) {\n this.chunks.push(new Uint8Array(this.buf));\n this.buf = [];\n }\n this.chunks.push(chunk);\n return this;\n }\n /**\n * Write a `uint32` value, an unsigned 32 bit varint.\n */\n uint32(value) {\n assertUInt32(value);\n // write value as varint 32, inlined for speed\n while (value > 0x7f) {\n this.buf.push((value & 0x7f) | 0x80);\n value = value >>> 7;\n }\n this.buf.push(value);\n return this;\n }\n /**\n * Write a `int32` value, a signed 32 bit varint.\n */\n int32(value) {\n assertInt32(value);\n varint32write(value, this.buf);\n return this;\n }\n /**\n * Write a `bool` value, a variant.\n */\n bool(value) {\n this.buf.push(value ? 1 : 0);\n return this;\n }\n /**\n * Write a `bytes` value, length-delimited arbitrary data.\n */\n bytes(value) {\n this.uint32(value.byteLength); // write length of chunk as varint\n return this.raw(value);\n }\n /**\n * Write a `string` value, length-delimited data converted to UTF-8 text.\n */\n string(value) {\n let chunk = this.encodeUtf8(value);\n this.uint32(chunk.byteLength); // write length of chunk as varint\n return this.raw(chunk);\n }\n /**\n * Write a `float` value, 32-bit floating point number.\n */\n float(value) {\n assertFloat32(value);\n let chunk = new Uint8Array(4);\n new DataView(chunk.buffer).setFloat32(0, value, true);\n return this.raw(chunk);\n }\n /**\n * Write a `double` value, a 64-bit floating point number.\n */\n double(value) {\n let chunk = new Uint8Array(8);\n new DataView(chunk.buffer).setFloat64(0, value, true);\n return this.raw(chunk);\n }\n /**\n * Write a `fixed32` value, an unsigned, fixed-length 32-bit integer.\n */\n fixed32(value) {\n assertUInt32(value);\n let chunk = new Uint8Array(4);\n new DataView(chunk.buffer).setUint32(0, value, true);\n return this.raw(chunk);\n }\n /**\n * Write a `sfixed32` value, a signed, fixed-length 32-bit integer.\n */\n sfixed32(value) {\n assertInt32(value);\n let chunk = new Uint8Array(4);\n new DataView(chunk.buffer).setInt32(0, value, true);\n return this.raw(chunk);\n }\n /**\n * Write a `sint32` value, a signed, zigzag-encoded 32-bit varint.\n */\n sint32(value) {\n assertInt32(value);\n // zigzag encode\n value = ((value << 1) ^ (value >> 31)) >>> 0;\n varint32write(value, this.buf);\n return this;\n }\n /**\n * Write a `fixed64` value, a signed, fixed-length 64-bit integer.\n */\n sfixed64(value) {\n let chunk = new Uint8Array(8), view = new DataView(chunk.buffer), tc = protoInt64.enc(value);\n view.setInt32(0, tc.lo, true);\n view.setInt32(4, tc.hi, true);\n return this.raw(chunk);\n }\n /**\n * Write a `fixed64` value, an unsigned, fixed-length 64 bit integer.\n */\n fixed64(value) {\n let chunk = new Uint8Array(8), view = new DataView(chunk.buffer), tc = protoInt64.uEnc(value);\n view.setInt32(0, tc.lo, true);\n view.setInt32(4, tc.hi, true);\n return this.raw(chunk);\n }\n /**\n * Write a `int64` value, a signed 64-bit varint.\n */\n int64(value) {\n let tc = protoInt64.enc(value);\n varint64write(tc.lo, tc.hi, this.buf);\n return this;\n }\n /**\n * Write a `sint64` value, a signed, zig-zag-encoded 64-bit varint.\n */\n sint64(value) {\n const tc = protoInt64.enc(value), \n // zigzag encode\n sign = tc.hi >> 31, lo = (tc.lo << 1) ^ sign, hi = ((tc.hi << 1) | (tc.lo >>> 31)) ^ sign;\n varint64write(lo, hi, this.buf);\n return this;\n }\n /**\n * Write a `uint64` value, an unsigned 64-bit varint.\n */\n uint64(value) {\n const tc = protoInt64.uEnc(value);\n varint64write(tc.lo, tc.hi, this.buf);\n return this;\n }\n}\nexport class BinaryReader {\n constructor(buf, decodeUtf8 = getTextEncoding().decodeUtf8) {\n this.decodeUtf8 = decodeUtf8;\n this.varint64 = varint64read; // dirty cast for `this`\n /**\n * Read a `uint32` field, an unsigned 32 bit varint.\n */\n this.uint32 = varint32read;\n this.buf = buf;\n this.len = buf.length;\n this.pos = 0;\n this.view = new DataView(buf.buffer, buf.byteOffset, buf.byteLength);\n }\n /**\n * Reads a tag - field number and wire type.\n */\n tag() {\n let tag = this.uint32(), fieldNo = tag >>> 3, wireType = tag & 7;\n if (fieldNo <= 0 || wireType < 0 || wireType > 5)\n throw new Error(\"illegal tag: field no \" + fieldNo + \" wire type \" + wireType);\n return [fieldNo, wireType];\n }\n /**\n * Skip one element and return the skipped data.\n *\n * When skipping StartGroup, provide the tags field number to check for\n * matching field number in the EndGroup tag.\n */\n skip(wireType, fieldNo) {\n let start = this.pos;\n switch (wireType) {\n case WireType.Varint:\n while (this.buf[this.pos++] & 0x80) {\n // ignore\n }\n break;\n // @ts-ignore TS7029: Fallthrough case in switch -- ignore instead of expect-error for compiler settings without noFallthroughCasesInSwitch: true\n case WireType.Bit64:\n this.pos += 4;\n case WireType.Bit32:\n this.pos += 4;\n break;\n case WireType.LengthDelimited:\n let len = this.uint32();\n this.pos += len;\n break;\n case WireType.StartGroup:\n for (;;) {\n const [fn, wt] = this.tag();\n if (wt === WireType.EndGroup) {\n if (fieldNo !== undefined && fn !== fieldNo) {\n throw new Error(\"invalid end group tag\");\n }\n break;\n }\n this.skip(wt, fn);\n }\n break;\n default:\n throw new Error(\"cant skip wire type \" + wireType);\n }\n this.assertBounds();\n return this.buf.subarray(start, this.pos);\n }\n /**\n * Throws error if position in byte array is out of range.\n */\n assertBounds() {\n if (this.pos > this.len)\n throw new RangeError(\"premature EOF\");\n }\n /**\n * Read a `int32` field, a signed 32 bit varint.\n */\n int32() {\n return this.uint32() | 0;\n }\n /**\n * Read a `sint32` field, a signed, zigzag-encoded 32-bit varint.\n */\n sint32() {\n let zze = this.uint32();\n // decode zigzag\n return (zze >>> 1) ^ -(zze & 1);\n }\n /**\n * Read a `int64` field, a signed 64-bit varint.\n */\n int64() {\n return protoInt64.dec(...this.varint64());\n }\n /**\n * Read a `uint64` field, an unsigned 64-bit varint.\n */\n uint64() {\n return protoInt64.uDec(...this.varint64());\n }\n /**\n * Read a `sint64` field, a signed, zig-zag-encoded 64-bit varint.\n */\n sint64() {\n let [lo, hi] = this.varint64();\n // decode zig zag\n let s = -(lo & 1);\n lo = ((lo >>> 1) | ((hi & 1) << 31)) ^ s;\n hi = (hi >>> 1) ^ s;\n return protoInt64.dec(lo, hi);\n }\n /**\n * Read a `bool` field, a variant.\n */\n bool() {\n let [lo, hi] = this.varint64();\n return lo !== 0 || hi !== 0;\n }\n /**\n * Read a `fixed32` field, an unsigned, fixed-length 32-bit integer.\n */\n fixed32() {\n // biome-ignore lint/suspicious/noAssignInExpressions: no\n return this.view.getUint32((this.pos += 4) - 4, true);\n }\n /**\n * Read a `sfixed32` field, a signed, fixed-length 32-bit integer.\n */\n sfixed32() {\n // biome-ignore lint/suspicious/noAssignInExpressions: no\n return this.view.getInt32((this.pos += 4) - 4, true);\n }\n /**\n * Read a `fixed64` field, an unsigned, fixed-length 64 bit integer.\n */\n fixed64() {\n return protoInt64.uDec(this.sfixed32(), this.sfixed32());\n }\n /**\n * Read a `fixed64` field, a signed, fixed-length 64-bit integer.\n */\n sfixed64() {\n return protoInt64.dec(this.sfixed32(), this.sfixed32());\n }\n /**\n * Read a `float` field, 32-bit floating point number.\n */\n float() {\n // biome-ignore lint/suspicious/noAssignInExpressions: no\n return this.view.getFloat32((this.pos += 4) - 4, true);\n }\n /**\n * Read a `double` field, a 64-bit floating point number.\n */\n double() {\n // biome-ignore lint/suspicious/noAssignInExpressions: no\n return this.view.getFloat64((this.pos += 8) - 8, true);\n }\n /**\n * Read a `bytes` field, length-delimited arbitrary data.\n */\n bytes() {\n let len = this.uint32(), start = this.pos;\n this.pos += len;\n this.assertBounds();\n return this.buf.subarray(start, start + len);\n }\n /**\n * Read a `string` field, length-delimited data converted to UTF-8 text.\n */\n string() {\n return this.decodeUtf8(this.bytes());\n }\n}\n/**\n * Assert a valid signed protobuf 32-bit integer as a number or string.\n */\nfunction assertInt32(arg) {\n if (typeof arg == \"string\") {\n arg = Number(arg);\n }\n else if (typeof arg != \"number\") {\n throw new Error(\"invalid int32: \" + typeof arg);\n }\n if (!Number.isInteger(arg) ||\n arg > INT32_MAX ||\n arg < INT32_MIN)\n throw new Error(\"invalid int32: \" + arg);\n}\n/**\n * Assert a valid unsigned protobuf 32-bit integer as a number or string.\n */\nfunction assertUInt32(arg) {\n if (typeof arg == \"string\") {\n arg = Number(arg);\n }\n else if (typeof arg != \"number\") {\n throw new Error(\"invalid uint32: \" + typeof arg);\n }\n if (!Number.isInteger(arg) ||\n arg > UINT32_MAX ||\n arg < 0)\n throw new Error(\"invalid uint32: \" + arg);\n}\n/**\n * Assert a valid protobuf float value as a number or string.\n */\nfunction assertFloat32(arg) {\n if (typeof arg == \"string\") {\n const o = arg;\n arg = Number(arg);\n if (Number.isNaN(arg) && o !== \"NaN\") {\n throw new Error(\"invalid float32: \" + o);\n }\n }\n else if (typeof arg != \"number\") {\n throw new Error(\"invalid float32: \" + typeof arg);\n }\n if (Number.isFinite(arg) &&\n (arg > FLOAT32_MAX || arg < FLOAT32_MIN))\n throw new Error(\"invalid float32: \" + arg);\n}\n","// Code generated by protoc-gen-ts_proto. DO NOT EDIT.\n// versions:\n// protoc-gen-ts_proto v2.6.1\n// protoc unknown\n// source: driveningress/v1/driveningress.proto\n\n/* eslint-disable */\nimport { BinaryReader, BinaryWriter } from \"@bufbuild/protobuf/wire\";\n\nexport const protobufPackage = \"driveningress.v1\";\n\nexport enum MessageType {\n MESSAGE_UNSPECIFIED = 0,\n MESSAGE_ERROR = 2,\n MESSAGE_SERVER_RESPONSE_ANIMATION = 1004,\n MESSAGE_CLIENT_AUDIO_INPUT = 2003,\n UNRECOGNIZED = -1,\n}\n\nexport function messageTypeFromJSON(object: any): MessageType {\n switch (object) {\n case 0:\n case \"MESSAGE_UNSPECIFIED\":\n return MessageType.MESSAGE_UNSPECIFIED;\n case 2:\n case \"MESSAGE_ERROR\":\n return MessageType.MESSAGE_ERROR;\n case 1004:\n case \"MESSAGE_SERVER_RESPONSE_ANIMATION\":\n return MessageType.MESSAGE_SERVER_RESPONSE_ANIMATION;\n case 2003:\n case \"MESSAGE_CLIENT_AUDIO_INPUT\":\n return MessageType.MESSAGE_CLIENT_AUDIO_INPUT;\n case -1:\n case \"UNRECOGNIZED\":\n default:\n return MessageType.UNRECOGNIZED;\n }\n}\n\nexport function messageTypeToJSON(object: MessageType): string {\n switch (object) {\n case MessageType.MESSAGE_UNSPECIFIED:\n return \"MESSAGE_UNSPECIFIED\";\n case MessageType.MESSAGE_ERROR:\n return \"MESSAGE_ERROR\";\n case MessageType.MESSAGE_SERVER_RESPONSE_ANIMATION:\n return \"MESSAGE_SERVER_RESPONSE_ANIMATION\";\n case MessageType.MESSAGE_CLIENT_AUDIO_INPUT:\n return \"MESSAGE_CLIENT_AUDIO_INPUT\";\n case MessageType.UNRECOGNIZED:\n default:\n return \"UNRECOGNIZED\";\n }\n}\n\n/**\n * 兼容流式传输,只要 req_id 相同,客户端可以将音频分段发若干个 ClientAudioInputData\n * 新 req_id 出现后,老 req_id 的请求将被忽略\n */\nexport interface ClientAudioInputData {\n reqId: string;\n audio: Uint8Array;\n end: boolean;\n}\n\nexport interface Flame {\n /** 平移 */\n translation: number[];\n /** 旋转 */\n rotation: number[];\n /** 脖子 */\n neckPose: number[];\n /** 下巴 */\n jawPose: number[];\n /** 眼睛 */\n eyePose: number[];\n /** 眼皮 */\n eyeLid: number[];\n /** 表情参数 */\n expression: number[];\n}\n\nexport interface FlameAnimation {\n keyframes: Flame[];\n}\n\nexport interface ServerResponseAnimationData {\n reqId: string;\n animation?: FlameAnimation | undefined;\n}\n\nexport interface ErrorInfo {\n reqId: string;\n code: number;\n reason: string;\n}\n\nexport interface Message {\n type: MessageType;\n error?: ErrorInfo | undefined;\n serverResponseAnimation?: ServerResponseAnimationData | undefined;\n clientAudioInput?: ClientAudioInputData | undefined;\n}\n\nfunction createBaseClientAudioInputData(): ClientAudioInputData {\n return { reqId: \"\", audio: new Uint8Array(0), end: false };\n}\n\nexport const ClientAudioInputData: MessageFns<ClientAudioInputData> = {\n encode(message: ClientAudioInputData, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {\n if (message.reqId !== \"\") {\n writer.uint32(10).string(message.reqId);\n }\n if (message.audio.length !== 0) {\n writer.uint32(18).bytes(message.audio);\n }\n if (message.end !== false) {\n writer.uint32(24).bool(message.end);\n }\n return writer;\n },\n\n decode(input: BinaryReader | Uint8Array, length?: number): ClientAudioInputData {\n const reader = input instanceof BinaryReader ? input : new BinaryReader(input);\n let end = length === undefined ? reader.len : reader.pos + length;\n const message = createBaseClientAudioInputData();\n while (reader.pos < end) {\n const tag = reader.uint32();\n switch (tag >>> 3) {\n case 1: {\n if (tag !== 10) {\n break;\n }\n\n message.reqId = reader.string();\n continue;\n }\n case 2: {\n if (tag !== 18) {\n break;\n }\n\n message.audio = reader.bytes();\n continue;\n }\n case 3: {\n if (tag !== 24) {\n break;\n }\n\n message.end = reader.bool();\n continue;\n }\n }\n if ((tag & 7) === 4 || tag === 0) {\n break;\n }\n reader.skip(tag & 7);\n }\n return message;\n },\n\n fromJSON(object: any): ClientAudioInputData {\n return {\n reqId: isSet(object.reqId) ? globalThis.String(object.reqId) : \"\",\n audio: isSet(object.audio) ? bytesFromBase64(object.audio) : new Uint8Array(0),\n end: isSet(object.end) ? globalThis.Boolean(object.end) : false,\n };\n },\n\n toJSON(message: ClientAudioInputData): unknown {\n const obj: any = {};\n if (message.reqId !== \"\") {\n obj.reqId = message.reqId;\n }\n if (message.audio.length !== 0) {\n obj.audio = base64FromBytes(message.audio);\n }\n if (message.end !== false) {\n obj.end = message.end;\n }\n return obj;\n },\n\n create<I extends Exact<DeepPartial<ClientAudioInputData>, I>>(base?: I): ClientAudioInputData {\n return ClientAudioInputData.fromPartial(base ?? ({} as any));\n },\n fromPartial<I extends Exact<DeepPartial<ClientAudioInputData>, I>>(object: I): ClientAudioInputData {\n const message = createBaseClientAudioInputData();\n message.reqId = object.reqId ?? \"\";\n message.audio = object.audio ?? new Uint8Array(0);\n message.end = object.end ?? false;\n return message;\n },\n};\n\nfunction createBaseFlame(): Flame {\n return { translation: [], rotation: [], neckPose: [], jawPose: [], eyePose: [], eyeLid: [], expression: [] };\n}\n\nexport const Flame: MessageFns<Flame> = {\n encode(message: Flame, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {\n writer.uint32(18).fork();\n for (const v of message.translation) {\n writer.float(v);\n }\n writer.join();\n writer.uint32(26).fork();\n for (const v of message.rotation) {\n writer.float(v);\n }\n writer.join();\n writer.uint32(34).fork();\n for (const v of message.neckPose) {\n writer.float(v);\n }\n writer.join();\n writer.uint32(42).fork();\n for (const v of message.jawPose) {\n writer.float(v);\n }\n writer.join();\n writer.uint32(50).fork();\n for (const v of message.eyePose) {\n writer.float(v);\n }\n writer.join();\n writer.uint32(58).fork();\n for (const v of message.eyeLid) {\n writer.float(v);\n }\n writer.join();\n writer.uint32(66).fork();\n for (const v of message.expression) {\n writer.float(v);\n }\n writer.join();\n return writer;\n },\n\n decode(input: BinaryReader | Uint8Array, length?: number): Flame {\n const reader = input instanceof BinaryReader ? input : new BinaryReader(input);\n let end = length === undefined ? reader.len : reader.pos + length;\n const message = createBaseFlame();\n while (reader.pos < end) {\n const tag = reader.uint32();\n switch (tag >>> 3) {\n case 2: {\n if (tag === 21) {\n message.translation.push(reader.float());\n\n continue;\n }\n\n if (tag === 18) {\n const end2 = reader.uint32() + reader.pos;\n while (reader.pos < end2) {\n message.translation.push(reader.float());\n }\n\n continue;\n }\n\n break;\n }\n case 3: {\n if (tag === 29) {\n message.rotation.push(reader.float());\n\n continue;\n }\n\n if (tag === 26) {\n const end2 = reader.uint32() + reader.pos;\n while (reader.pos < end2) {\n message.rotation.push(reader.float());\n }\n\n continue;\n }\n\n break;\n }\n case 4: {\n if (tag === 37) {\n message.neckPose.push(reader.float());\n\n continue;\n }\n\n if (tag === 34) {\n const end2 = reader.uint32() + reader.pos;\n while (reader.pos < end2) {\n message.neckPose.push(reader.float());\n }\n\n continue;\n }\n\n break;\n }\n case 5: {\n if (tag === 45) {\n message.jawPose.push(reader.float());\n\n continue;\n }\n\n if (tag === 42) {\n const end2 = reader.uint32() + reader.pos;\n while (reader.pos < end2) {\n message.jawPose.push(reader.float());\n }\n\n continue;\n }\n\n break;\n }\n case 6: {\n if (tag === 53) {\n message.eyePose.push(reader.float());\n\n continue;\n }\n\n if (tag === 50) {\n const end2 = reader.uint32() + reader.pos;\n while (reader.pos < end2) {\n message.eyePose.push(reader.float());\n }\n\n continue;\n }\n\n break;\n }\n case 7: {\n if (tag === 61) {\n message.eyeLid.push(reader.float());\n\n continue;\n }\n\n if (tag === 58) {\n const end2 = reader.uint32() + reader.pos;\n while (reader.pos < end2) {\n message.eyeLid.push(reader.float());\n }\n\n continue;\n }\n\n break;\n }\n case 8: {\n if (tag === 69) {\n message.expression.push(reader.float());\n\n continue;\n }\n\n if (tag === 66) {\n const end2 = reader.uint32() + reader.pos;\n while (reader.pos < end2) {\n message.expression.push(reader.float());\n }\n\n continue;\n }\n\n break;\n }\n }\n if ((tag & 7) === 4 || tag === 0) {\n break;\n }\n reader.skip(tag & 7);\n }\n return message;\n },\n\n fromJSON(object: any): Flame {\n return {\n translation: globalThis.Array.isArray(object?.translation)\n ? object.translation.map((e: any) => globalThis.Number(e))\n : [],\n rotation: globalThis.Array.isArray(object?.rotation) ? object.rotation.map((e: any) => globalThis.Number(e)) : [],\n neckPose: globalThis.Array.isArray(object?.neckPose) ? object.neckPose.map((e: any) => globalThis.Number(e)) : [],\n jawPose: globalThis.Array.isArray(object?.jawPose) ? object.jawPose.map((e: any) => globalThis.Number(e)) : [],\n eyePose: globalThis.Array.isArray(object?.eyePose) ? object.eyePose.map((e: any) => globalThis.Number(e)) : [],\n eyeLid: globalThis.Array.isArray(object?.eyeLid) ? object.eyeLid.map((e: any) => globalThis.Number(e)) : [],\n expression: globalThis.Array.isArray(object?.expression)\n ? object.expression.map((e: any) => globalThis.Number(e))\n : [],\n };\n },\n\n toJSON(message: Flame): unknown {\n const obj: any = {};\n if (message.translation?.length) {\n obj.translation = message.translation;\n }\n if (message.rotation?.length) {\n obj.rotation = message.rotation;\n }\n if (message.neckPose?.length) {\n obj.neckPose = message.neckPose;\n }\n if (message.jawPose?.length) {\n obj.jawPose = message.jawPose;\n }\n if (message.eyePose?.length) {\n obj.eyePose = message.eyePose;\n }\n if (message.eyeLid?.length) {\n obj.eyeLid = message.eyeLid;\n }\n if (message.expression?.length) {\n obj.expression = message.expression;\n }\n return obj;\n },\n\n create<I extends Exact<DeepPartial<Flame>, I>>(base?: I): Flame {\n return Flame.fromPartial(base ?? ({} as any));\n },\n fromPartial<I extends Exact<DeepPartial<Flame>, I>>(object: I): Flame {\n const message = createBaseFlame();\n message.translation = object.translation?.map((e) => e) || [];\n message.rotation = object.rotation?.map((e) => e) || [];\n message.neckPose = object.neckPose?.map((e) => e) || [];\n message.jawPose = object.jawPose?.map((e) => e) || [];\n message.eyePose = object.eyePose?.map((e) => e) || [];\n message.eyeLid = object.eyeLid?.map((e) => e) || [];\n message.expression = object.expression?.map((e) => e) || [];\n return message;\n },\n};\n\nfunction createBaseFlameAnimation(): FlameAnimation {\n return { keyframes: [] };\n}\n\nexport const FlameAnimation: MessageFns<FlameAnimation> = {\n encode(message: FlameAnimation, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {\n for (const v of message.keyframes) {\n Flame.encode(v!, writer.uint32(10).fork()).join();\n }\n return writer;\n },\n\n decode(input: BinaryReader | Uint8Array, length?: number): FlameAnimation {\n const reader = input instanceof BinaryReader ? input : new BinaryReader(input);\n let end = length === undefined ? reader.len : reader.pos + length;\n const message = createBaseFlameAnimation();\n while (reader.pos < end) {\n const tag = reader.uint32();\n switch (tag >>> 3) {\n case 1: {\n if (tag !== 10) {\n break;\n }\n\n message.keyframes.push(Flame.decode(reader, reader.uint32()));\n continue;\n }\n }\n if ((tag & 7) === 4 || tag === 0) {\n break;\n }\n reader.skip(tag & 7);\n }\n return message;\n },\n\n fromJSON(object: any): FlameAnimation {\n return {\n keyframes: globalThis.Array.isArray(object?.keyframes) ? object.keyframes.map((e: any) => Flame.fromJSON(e)) : [],\n };\n },\n\n toJSON(message: FlameAnimation): unknown {\n const obj: any = {};\n if (message.keyframes?.length) {\n obj.keyframes = message.keyframes.map((e) => Flame.toJSON(e));\n }\n return obj;\n },\n\n create<I extends Exact<DeepPartial<FlameAnimation>, I>>(base?: I): FlameAnimation {\n return FlameAnimation.fromPartial(base ?? ({} as any));\n },\n fromPartial<I extends Exact<DeepPartial<FlameAnimation>, I>>(object: I): FlameAnimation {\n const message = createBaseFlameAnimation();\n message.keyframes = object.keyframes?.map((e) => Flame.fromPartial(e)) || [];\n return message;\n },\n};\n\nfunction createBaseServerResponseAnimationData(): ServerResponseAnimationData {\n return { reqId: \"\", animation: undefined };\n}\n\nexport const ServerResponseAnimationData: MessageFns<ServerResponseAnimationData> = {\n encode(message: ServerResponseAnimationData, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {\n if (message.reqId !== \"\") {\n writer.uint32(10).string(message.reqId);\n }\n if (message.animation !== undefined) {\n FlameAnimation.encode(message.animation, writer.uint32(18).fork()).join();\n }\n return writer;\n },\n\n decode(input: BinaryReader | Uint8Array, length?: number): ServerResponseAnimationData {\n const reader = input instanceof BinaryReader ? input : new BinaryReader(input);\n let end = length === undefined ? reader.len : reader.pos + length;\n const message = createBaseServerResponseAnimationData();\n while (reader.pos < end) {\n const tag = reader.uint32();\n switch (tag >>> 3) {\n case 1: {\n if (tag !== 10) {\n break;\n }\n\n message.reqId = reader.string();\n continue;\n }\n case 2: {\n if (tag !== 18) {\n break;\n }\n\n message.animation = FlameAnimation.decode(reader, reader.uint32());\n continue;\n }\n }\n if ((tag & 7) === 4 || tag === 0) {\n break;\n }\n reader.skip(tag & 7);\n }\n return message;\n },\n\n fromJSON(object: any): ServerResponseAnimationData {\n return {\n reqId: isSet(object.reqId) ? globalThis.String(object.reqId) : \"\",\n animation: isSet(object.animation) ? FlameAnimation.fromJSON(object.animation) : undefined,\n };\n },\n\n toJSON(message: ServerResponseAnimationData): unknown {\n const obj: any = {};\n if (message.reqId !== \"\") {\n obj.reqId = message.reqId;\n }\n if (message.animation !== undefined) {\n obj.animation = FlameAnimation.toJSON(message.animation);\n }\n return obj;\n },\n\n create<I extends Exact<DeepPartial<ServerResponseAnimationData>, I>>(base?: I): ServerResponseAnimationData {\n return ServerResponseAnimationData.fromPartial(base ?? ({} as any));\n },\n fromPartial<I extends Exact<DeepPartial<ServerResponseAnimationData>, I>>(object: I): ServerResponseAnimationData {\n const message = createBaseServerResponseAnimationData();\n message.reqId = object.reqId ?? \"\";\n message.animation = (object.animation !== undefined && object.animation !== null)\n ? FlameAnimation.fromPartial(object.animation)\n : undefined;\n return message;\n },\n};\n\nfunction createBaseErrorInfo(): ErrorInfo {\n return { reqId: \"\", code: 0, reason: \"\" };\n}\n\nexport const ErrorInfo: MessageFns<ErrorInfo> = {\n encode(message: ErrorInfo, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {\n if (message.reqId !== \"\") {\n writer.uint32(10).string(message.reqId);\n }\n if (message.code !== 0) {\n writer.uint32(16).int32(message.code);\n }\n if (message.reason !== \"\") {\n writer.uint32(26).string(message.reason);\n }\n return writer;\n },\n\n decode(input: BinaryReader | Uint8Array, length?: number): ErrorInfo {\n const reader = input instanceof BinaryReader ? input : new BinaryReader(input);\n let end = length === undefined ? reader.len : reader.pos + length;\n const message = createBaseErrorInfo();\n while (reader.pos < end) {\n const tag = reader.uint32();\n switch (tag >>> 3) {\n case 1: {\n if (tag !== 10) {\n break;\n }\n\n message.reqId = reader.string();\n continue;\n }\n case 2: {\n if (tag !== 16) {\n break;\n }\n\n message.code = reader.int32();\n continue;\n }\n case 3: {\n if (tag !== 26) {\n break;\n }\n\n message.reason = reader.string();\n continue;\n }\n }\n if ((tag & 7) === 4 || tag === 0) {\n break;\n }\n reader.skip(tag & 7);\n }\n return message;\n },\n\n fromJSON(object: any): ErrorInfo {\n return {\n reqId: isSet(object.reqId) ? globalThis.String(object.reqId) : \"\",\n code: isSet(object.code) ? globalThis.Number(object.code) : 0,\n reason: isSet(object.reason) ? globalThis.String(object.reason) : \"\",\n };\n },\n\n toJSON(message: ErrorInfo): unknown {\n const obj: any = {};\n if (message.reqId !== \"\") {\n obj.reqId = message.reqId;\n }\n if (message.code !== 0) {\n obj.code = Math.round(message.code);\n }\n if (message.reason !== \"\") {\n obj.reason = message.reason;\n }\n return obj;\n },\n\n create<I extends Exact<DeepPartial<ErrorInfo>, I>>(base?: I): ErrorInfo {\n return ErrorInfo.fromPartial(base ?? ({} as any));\n },\n fromPartial<I extends Exact<DeepPartial<ErrorInfo>, I>>(object: I): ErrorInfo {\n const message = createBaseErrorInfo();\n message.reqId = object.reqId ?? \"\";\n message.code = object.code ?? 0;\n message.reason = object.reason ?? \"\";\n return message;\n },\n};\n\nfunction createBaseMessage(): Message {\n return { type: 0, error: undefined, serverResponseAnimation: undefined, clientAudioInput: undefined };\n}\n\nexport const Message: MessageFns<Message> = {\n encode(message: Message, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {\n if (message.type !== 0) {\n writer.uint32(8).int32(message.type);\n }\n if (message.error !== undefined) {\n ErrorInfo.encode(message.error, writer.uint32(18).fork()).join();\n }\n if (message.serverResponseAnimation !== undefined) {\n ServerResponseAnimationData.encode(message.serverResponseAnimation, writer.uint32(26).fork()).join();\n }\n if (message.clientAudioInput !== undefined) {\n ClientAudioInputData.encode(message.clientAudioInput, writer.uint32(34).fork()).join();\n }\n return writer;\n },\n\n decode(input: BinaryReader | Uint8Array, length?: number): Message {\n const reader = input instanceof BinaryReader ? input : new BinaryReader(input);\n let end = length === undefined ? reader.len : reader.pos + length;\n const message = createBaseMessage();\n while (reader.pos < end) {\n const tag = reader.uint32();\n switch (tag >>> 3) {\n case 1: {\n if (tag !== 8) {\n break;\n }\n\n message.type = reader.int32() as any;\n continue;\n }\n case 2: {\n if (tag !== 18) {\n break;\n }\n\n message.error = ErrorInfo.decode(reader, reader.uint32());\n continue;\n }\n case 3: {\n if (tag !== 26) {\n break;\n }\n\n message.serverResponseAnimation = ServerResponseAnimationData.decode(reader, reader.uint32());\n continue;\n }\n case 4: {\n if (tag !== 34) {\n break;\n }\n\n message.clientAudioInput = ClientAudioInputData.decode(reader, reader.uint32());\n continue;\n }\n }\n if ((tag & 7) === 4 || tag === 0) {\n break;\n }\n reader.skip(tag & 7);\n }\n return message;\n },\n\n fromJSON(object: any): Message {\n return {\n type: isSet(object.type) ? messageTypeFromJSON(object.type) : 0,\n error: isSet(object.error) ? ErrorInfo.fromJSON(object.error) : undefined,\n serverResponseAnimation: isSet(object.serverResponseAnimation)\n ? ServerResponseAnimationData.fromJSON(object.serverResponseAnimation)\n : undefined,\n clientAudioInput: isSet(object.clientAudioInput)\n ? ClientAudioInputData.fromJSON(object.clientAudioInput)\n : undefined,\n };\n },\n\n toJSON(message: Message): unknown {\n const obj: any = {};\n if (message.type !== 0) {\n obj.type = messageTypeToJSON(message.type);\n }\n if (message.error !== undefined) {\n obj.error = ErrorInfo.toJSON(message.error);\n }\n if (message.serverResponseAnimation !== undefined) {\n obj.serverResponseAnimation = ServerResponseAnimationData.toJSON(message.serverResponseAnimation);\n }\n if (message.clientAudioInput !== undefined) {\n obj.clientAudioInput = ClientAudioInputData.toJSON(message.clientAudioInput);\n }\n return obj;\n },\n\n create<I extends Exact<DeepPartial<Message>, I>>(base?: I): Message {\n return Message.fromPartial(base ?? ({} as any));\n },\n fromPartial<I extends Exact<DeepPartial<Message>, I>>(object: I): Message {\n const message = createBaseMessage();\n message.type = object.type ?? 0;\n message.error = (object.error !== undefined && object.error !== null)\n ? ErrorInfo.fromPartial(object.error)\n : undefined;\n message.serverResponseAnimation =\n (object.serverResponseAnimation !== undefined && object.serverResponseAnimation !== null)\n ? ServerResponseAnimationData.fromPartial(object.serverResponseAnimation)\n : undefined;\n message.clientAudioInput = (object.clientAudioInput !== undefined && object.clientAudioInput !== null)\n ? ClientAudioInputData.fromPartial(object.clientAudioInput)\n : undefined;\n return message;\n },\n};\n\nfunction bytesFromBase64(b64: string): Uint8Array {\n const bin = globalThis.atob(b64);\n const arr = new Uint8Array(bin.length);\n for (let i = 0; i < bin.length; ++i) {\n arr[i] = bin.charCodeAt(i);\n }\n return arr;\n}\n\nfunction base64FromBytes(arr: Uint8Array): string {\n const bin: string[] = [];\n arr.forEach((byte) => {\n bin.push(globalThis.String.fromCharCode(byte));\n });\n return globalThis.btoa(bin.join(\"\"));\n}\n\ntype Builtin = Date | Function | Uint8Array | string | number | boolean | undefined;\n\nexport type DeepPartial<T> = T extends Builtin ? T\n : T extends globalThis.Array<infer U> ? globalThis.Array<DeepPartial<U>>\n : T extends ReadonlyArray<infer U> ? ReadonlyArray<DeepPartial<U>>\n : T extends {} ? { [K in keyof T]?: DeepPartial<T[K]> }\n : Partial<T>;\n\ntype KeysOfUnion<T> = T extends T ? keyof T : never;\nexport type Exact<P, I extends P> = P extends Builtin ? P\n : P & { [K in keyof P]: Exact<P[K], I[K]> } & { [K in Exclude<keyof I, KeysOfUnion<P>>]: never };\n\nfunction isSet(value: any): boolean {\n return value !== null && value !== undefined;\n}\n\nexport interface MessageFns<T> {\n encode(message: T, writer?: BinaryWriter): BinaryWriter;\n decode(input: BinaryReader | Uint8Array, length?: number): T;\n fromJSON(object: any): T;\n toJSON(message: T): unknown;\n create<I extends Exact<DeepPartial<T>, I>>(base?: I): T;\n fromPartial<I extends Exact<DeepPartial<T>, I>>(object: I): T;\n}\n","/**\n * Simple Event Emitter\n */\n\n// eslint-disable-next-line ts/no-explicit-any\ntype EventHandler = (...args: any[]) => void\n\nexport class EventEmitter {\n private events: Map<string, Set<EventHandler>> = new Map()\n\n on(event: string, handler: EventHandler): void {\n if (!this.events.has(event)) {\n this.events.set(event, new Set())\n }\n this.events.get(event)!.add(handler)\n }\n\n off(event: string, handler: EventHandler): void {\n const handlers = this.events.get(event)\n if (handlers) {\n handlers.delete(handler)\n if (handlers.size === 0) {\n this.events.delete(event)\n }\n }\n }\n\n // eslint-disable-next-line ts/no-explicit-any\n emit(event: string, ...args: any[]): void {\n const handlers = this.events.get(event)\n if (handlers) {\n handlers.forEach(handler => handler(...args))\n }\n }\n\n removeAllListeners(event?: string): void {\n if (event) {\n this.events.delete(event)\n }\n else {\n this.events.clear()\n }\n }\n}\n","/**\n * AnimationWebSocketClient:动画专用 WebSocket 客户端\n * 使用 driveningress/v1 协议,只处理音频输入和动画输出\n */\n\nimport type { Message } from '../generated/driveningress/v1/driveningress'\n\nimport { BinaryReader, BinaryWriter } from '@bufbuild/protobuf/wire'\n\nimport { Message as MessageCodec, MessageType } from '../generated/driveningress/v1/driveningress'\nimport { AvatarKit } from '../core/AvatarKit'\nimport { errorToMessage } from '../utils/error-utils'\nimport { logger } from '../utils/logger'\nimport { generateConversationId } from '../utils/conversationId'\nimport { EventEmitter } from './utils/eventEmitter'\n\nexport interface AnimationWebSocketClientOptions {\n wsUrl: string\n reconnectAttempts?: number\n debug?: boolean\n jwtToken?: string\n appId?: string\n}\n\nexport class AnimationWebSocketClient extends EventEmitter {\n private wsUrl: string\n private reconnectAttempts: number\n private debug: boolean\n private jwtToken?: string\n private appId?: string\n\n private ws: WebSocket | null = null\n private currentCharacterId: string = ''\n private currentRetryCount: number = 0\n private isConnecting: boolean = false\n private isManuallyDisconnected: boolean = false\n private reconnectTimer: number | null = null\n\n constructor(options: AnimationWebSocketClientOptions) {\n super()\n this.wsUrl = options.wsUrl\n this.reconnectAttempts = options.reconnectAttempts ?? 5\n this.debug = options.debug ?? false\n this.jwtToken = options.jwtToken\n this.appId = options.appId\n }\n\n /**\n * 连接WebSocket\n */\n async connect(characterId: string): Promise<void> {\n if (this.ws && this.ws.readyState === WebSocket.OPEN) {\n logger.log('[AnimationWebSocketClient] Already connected')\n return\n }\n\n if (this.isConnecting) {\n logger.log('[AnimationWebSocketClient] Already connecting')\n return\n }\n\n try {\n this.isConnecting = true\n this.currentCharacterId = characterId\n\n const url = this.buildWebSocketUrl(characterId)\n logger.log('[AnimationWebSocketClient] Connecting to:', url)\n\n await this.connectWebSocket(url)\n logger.log('[AnimationWebSocketClient] Connected successfully')\n AvatarKit.logEvent('character_animation_service', 'info', {\n characterId,\n event: 'connect_success',\n url,\n })\n }\n catch (error) {\n this.isConnecting = false\n const message = error instanceof Error ? error.message : String(error)\n logger.error('[AnimationWebSocketClient] Connection failed:', message)\n AvatarKit.logEvent('character_animation_service', 'error', {\n characterId,\n event: 'connect_failed',\n reason: message,\n })\n throw error\n }\n }\n\n /**\n * 断开连接\n */\n disconnect(): void {\n if (this.ws) {\n this.ws.close(1000, 'Normal closure')\n this.ws = null\n }\n\n // 清理所有事件监听器,避免内存泄漏\n this.removeAllListeners()\n\n this.currentRetryCount = 0\n this.isConnecting = false\n this.isManuallyDisconnected = true\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer)\n this.reconnectTimer = null\n }\n logger.log('[AnimationWebSocketClient] Disconnected')\n }\n\n /**\n * 发送音频数据\n * @param conversationId - 会话ID(在 protobuf 协议中映射为 reqId 字段)\n */\n sendAudioData(conversationId: string, audioData: ArrayBuffer, end: boolean): boolean {\n if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {\n logger.error('[AnimationWebSocketClient] WebSocket not connected')\n return false\n }\n\n try {\n const message: Message = {\n type: MessageType.MESSAGE_CLIENT_AUDIO_INPUT,\n clientAudioInput: {\n reqId: conversationId, // protobuf 协议中使用 reqId 字段名\n audio: new Uint8Array(audioData),\n end,\n },\n }\n\n const writer = new BinaryWriter()\n MessageCodec.encode(message, writer)\n const bytes = writer.finish()\n\n this.ws.send(bytes)\n return true\n }\n catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n logger.error('[AnimationWebSocketClient] Failed to send audio data:', message)\n AvatarKit.logEvent('character_animation_service', 'warning', {\n characterId: this.currentCharacterId,\n event: 'send_audio_failed',\n conversationId,\n reason: message,\n })\n this.emit('error', error as Error)\n return false\n }\n }\n\n /**\n * 生成会话ID\n * 使用统一的会话ID生成规则:YYYYMMDDHHmmss_nanoid\n */\n generateConversationId(): string {\n return generateConversationId()\n }\n\n /**\n * 获取连接状态\n */\n isConnected(): boolean {\n return this.ws !== null && this.ws.readyState === WebSocket.OPEN\n }\n\n /**\n * 获取当前角色ID\n */\n getCurrentCharacterId(): string {\n return this.currentCharacterId\n }\n\n // ========== 私有方法 ==========\n\n private buildWebSocketUrl(characterId: string): string {\n const url = new URL(this.wsUrl)\n url.searchParams.set('id', characterId)\n\n if (this.jwtToken) {\n url.searchParams.set('token', this.jwtToken)\n }\n\n if (this.appId) {\n url.searchParams.set('appId', this.appId)\n }\n\n return url.toString()\n }\n\n private connectWebSocket(url: string): Promise<void> {\n return new Promise((resolve, reject) => {\n try {\n this.ws = new WebSocket(url)\n\n this.ws.onopen = () => {\n this.isConnecting = false\n this.currentRetryCount = 0\n this.isManuallyDisconnected = false\n this.emit('connected')\n resolve()\n }\n\n this.ws.onmessage = (event) => {\n if (event.data instanceof ArrayBuffer) {\n this.handleMessage(event.data)\n }\n else if (event.data instanceof Blob) {\n event.data.arrayBuffer().then(this.handleMessage.bind(this)).catch((err) => {\n logger.error('[AnimationWebSocketClient] Failed to convert Blob to ArrayBuffer:', err)\n AvatarKit.logEvent('character_animation_service', 'error', {\n characterId: this.currentCharacterId,\n event: 'decode_blob_failed',\n reason: err instanceof Error ? err.message : String(err),\n })\n this.emit('error', err as Error)\n })\n }\n else {\n logger.warn('[AnimationWebSocketClient] Received non-binary data:', typeof event.data)\n }\n }\n\n this.ws.onerror = (error) => {\n logger.errorWithError('[AnimationWebSocketClient] WebSocket error:', error)\n AvatarKit.logEvent('character_animation_service', 'error', {\n characterId: this.currentCharacterId,\n event: 'websocket_error',\n })\n this.emit('error', new Error('WebSocket error'))\n if (!this.isManuallyDisconnected && this.currentRetryCount < this.reconnectAttempts) {\n this.scheduleReconnect()\n }\n }\n\n this.ws.onclose = (event) => {\n logger.log('[AnimationWebSocketClient] WebSocket closed:', event.code, event.reason)\n this.emit('disconnected', event.reason || 'Connection closed')\n if (event.code === 1012) {\n AvatarKit.logEvent('character_animation_service', 'error', {\n characterId: this.currentCharacterId,\n event: 'service_restart',\n reason: event.reason || 'service restart',\n })\n }\n\n if (!this.isManuallyDisconnected && this.currentRetryCount < this.reconnectAttempts) {\n this.scheduleReconnect()\n }\n }\n }\n catch (error) {\n this.isConnecting = false\n reject(error)\n }\n })\n }\n\n private handleMessage(data: ArrayBuffer): void {\n try {\n const reader = new BinaryReader(new Uint8Array(data))\n const message = MessageCodec.decode(reader)\n\n // 检查消息中是否包含错误信息\n if (message.error) {\n logger.error(`[AnimationWebSocketClient] Server error: reqId=${message.error.reqId}, code=${message.error.code}, reason=${message.error.reason}`)\n AvatarKit.logEvent('character_animation_service', 'error', {\n characterId: this.currentCharacterId,\n event: 'server_error',\n reqId: message.error.reqId,\n code: message.error.code,\n reason: message.error.reason,\n })\n this.emit('error', new Error(message.error.reason || 'Server error'))\n return\n }\n\n if (message.type === MessageType.MESSAGE_ERROR) {\n logger.warn('[AnimationWebSocketClient] MESSAGE_ERROR received but no error field in message')\n AvatarKit.logEvent('character_animation_service', 'warning', {\n characterId: this.currentCharacterId,\n event: 'message_error_without_payload',\n })\n this.emit('error', new Error('Server returned error message without error details'))\n return\n }\n\n this.emit('message', message)\n }\n catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n logger.error('[AnimationWebSocketClient] Failed to decode message:', message)\n AvatarKit.logEvent('character_animation_service', 'error', {\n characterId: this.currentCharacterId,\n event: 'decode_failed',\n reason: message,\n })\n this.emit('error', error as Error)\n }\n }\n\n private scheduleReconnect(): void {\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer)\n }\n\n this.currentRetryCount++\n const delay = Math.min(1000 * Math.pow(2, this.currentRetryCount - 1), 30000)\n\n logger.log(`[AnimationWebSocketClient] Scheduling reconnect attempt ${this.currentRetryCount}/${this.reconnectAttempts} in ${delay}ms`)\n\n this.reconnectTimer = window.setTimeout(() => {\n if (!this.isManuallyDisconnected && this.currentCharacterId) {\n this.emit('reconnecting', `Reconnect attempt ${this.currentRetryCount}`)\n this.connect(this.currentCharacterId).catch((error) => {\n logger.error('[AnimationWebSocketClient] Reconnect failed:', error instanceof Error ? error.message : String(error))\n })\n }\n }, delay)\n }\n}\n","/**\n * NetworkLayer - Network communication layer\n * Responsible for WebSocket connections, protocol handling, and data retrieval\n * Automatically calls AvatarController (playback layer) interfaces after obtaining data\n * @internal Not part of public API\n */\n\nimport type { Message } from '../generated/driveningress/v1/driveningress'\nimport type { AvatarController } from './AvatarController'\n\nimport { MessageType } from '../generated/driveningress/v1/driveningress'\nimport { APP_CONFIG } from '../config/app-config'\nimport { ConnectionState, SPAvatarError } from '../types'\nimport { logger } from '../utils/logger'\nimport { AvatarKit } from './AvatarKit'\nimport { AnimationWebSocketClient } from '../animation/AnimationWebSocketClient'\n\n/**\n * Audio metrics\n * @internal\n */\ninterface AudioMetrics {\n accumulatedBytes: number\n startTimestamp: number\n tap2Timestamp: number\n tap4Timestamp: number\n endTimestamp: number\n recvFirstFlameTimestamp: number\n didRecvFirstFlame: boolean\n}\n\n/**\n * @internal\n */\nexport class NetworkLayer {\n private wsClient: AnimationWebSocketClient\n private dataController: AvatarController // 组合播放层\n private currentConversationId: string | null = null\n private readonly audioBytesPerSecond = APP_CONFIG.audio.sampleRate * 2\n private audioMetrics: AudioMetrics = this.createAudioMetrics()\n private isFallbackMode = false // 连接超时降级模式标记\n private isConnecting = false // 避免并发连接\n\n constructor(dataController: AvatarController) {\n this.dataController = dataController\n\n // 初始化 WebSocket 客户端\n const config = AvatarKit.getEnvironmentConfig()\n this.wsClient = new AnimationWebSocketClient({\n wsUrl: config.driveningressWsUrl,\n reconnectAttempts: 5,\n debug: false,\n jwtToken: AvatarKit.sessionToken || undefined,\n appId: AvatarKit.appId || undefined,\n })\n\n // 设置事件监听器\n this.setupWebSocketListeners()\n }\n\n /**\n * 连接服务\n */\n async connect(characterId: string): Promise<void> {\n // ✅ 避免并发连接\n if (this.isConnecting) {\n logger.warn('[NetworkLayer] Connection already in progress, waiting for current connection to complete')\n throw new SPAvatarError('Connection already in progress', 'CONNECTION_IN_PROGRESS')\n }\n\n // ✅ 通知外部:开始连接\n this.dataController.onConnectionState?.(ConnectionState.connecting)\n\n // ✅ 重新尝试连接时,清除降级标记\n this.isFallbackMode = false\n\n // 重新设置事件监听器(因为 disconnect 会调用 removeAllListeners 移除所有监听器)\n // 这确保了每次连接时监听器都存在\n this.setupWebSocketListeners()\n\n this.isConnecting = true\n\n const CONNECTION_TIMEOUT_MS = 15000\n let timeoutId: NodeJS.Timeout | null = null\n\n const connectPromise = this.wsClient.connect(characterId)\n const timeoutPromise = new Promise<void>((resolve) => {\n timeoutId = setTimeout(() => {\n if (!this.dataController.connected) {\n this.isFallbackMode = true\n logger.warn(`[NetworkLayer] WebSocket connection timeout (${CONNECTION_TIMEOUT_MS}ms) - entering fallback mode`)\n AvatarKit.logEvent('character_manager', 'warning', {\n characterId: this.dataController.getAvatarId(),\n event: 'websocket_connection_timeout_fallback',\n timeoutMs: CONNECTION_TIMEOUT_MS,\n })\n // ✅ 通知外部:连接超时\n this.dataController.onConnectionState?.(ConnectionState.failed)\n }\n resolve()\n }, CONNECTION_TIMEOUT_MS)\n })\n\n try {\n await Promise.race([connectPromise, timeoutPromise])\n if (timeoutId) {\n clearTimeout(timeoutId)\n }\n } catch (error) {\n if (timeoutId) {\n clearTimeout(timeoutId)\n }\n \n // ✅ 连接失败时也进入降级模式\n if (!this.isFallbackMode) {\n this.isFallbackMode = true\n logger.warn('[NetworkLayer] WebSocket connection failed - entering fallback mode')\n AvatarKit.logEvent('character_manager', 'warning', {\n characterId: this.dataController.getAvatarId(),\n event: 'websocket_connection_failed_fallback',\n })\n }\n \n // ✅ 通知外部:连接失败\n this.dataController.onConnectionState?.(ConnectionState.failed)\n \n throw error\n } finally {\n this.isConnecting = false\n }\n }\n\n /**\n * 检查是否可以发送音频数据(包括降级模式)\n * @internal\n */\n canSend(): boolean {\n // 降级模式下允许发送(虽然连接失败,但功能可用)\n return this.isFallbackMode || this.dataController.connected\n }\n\n /**\n * 发送音频数据到服务器\n * 注意:打断逻辑由 AvatarController.send() 统一处理,这里只负责网络通信\n */\n sendAudioData(audioData: ArrayBuffer, isLast: boolean): void {\n // 生成会话ID(如果还没有的话)\n if (!this.currentConversationId) {\n this.currentConversationId = this.wsClient.generateConversationId()\n this.resetAudioMetrics()\n AvatarKit.logEvent('character_manager', 'info', {\n characterId: this.dataController.getAvatarId(),\n event: 'conversation_started',\n conversationId: this.currentConversationId,\n })\n }\n\n // 统计音频指标\n const metrics = this.audioMetrics\n let shouldReportMetrics = false\n\n if (metrics.startTimestamp === 0) {\n metrics.startTimestamp = Date.now()\n shouldReportMetrics = true\n }\n\n metrics.accumulatedBytes += audioData.byteLength\n const currentDuration = metrics.accumulatedBytes / this.audioBytesPerSecond\n\n if (currentDuration >= 2 && metrics.tap2Timestamp === 0) {\n metrics.tap2Timestamp = Date.now()\n shouldReportMetrics = true\n }\n\n if (currentDuration >= 4 && metrics.tap4Timestamp === 0) {\n metrics.tap4Timestamp = Date.now()\n shouldReportMetrics = true\n }\n\n if (isLast && metrics.endTimestamp === 0) {\n metrics.endTimestamp = Date.now()\n shouldReportMetrics = true\n }\n\n // 检查音频数据是否为空\n if (audioData.byteLength === 0 && !isLast) {\n logger.warn('[NetworkLayer] Warning: sending empty audio data (size=0, end=false)')\n }\n\n // ✅ 如果处于降级模式,不发送到 WebSocket,直接触发降级逻辑\n if (this.isFallbackMode) {\n // 不发送到服务器\n // 直接调用 yieldFramesData([], conversationId) 触发降级逻辑(复用统一逻辑)\n if (this.currentConversationId) {\n logger.warn('[NetworkLayer] Fallback mode: skipping WebSocket send, triggering audio-only mode')\n this.dataController.yieldFramesData([], this.currentConversationId)\n }\n return\n }\n\n // 正常流程:发送到服务器(protobuf 协议中使用 reqId 字段名)\n const sent = this.wsClient.sendAudioData(this.currentConversationId!, audioData, isLast)\n if (!sent) {\n logger.error('[NetworkLayer] Failed to send audio data to WebSocket')\n this.dataController.onError?.(new SPAvatarError('Failed to send audio data to WebSocket', 'SEND_FAILED'))\n AvatarKit.logEvent('character_animation_service', 'error', {\n characterId: this.dataController.getAvatarId(),\n event: 'send_audio_failed',\n conversationId: this.currentConversationId,\n })\n return\n }\n\n if (shouldReportMetrics && this.currentConversationId) {\n this.reportAudioMetrics(this.currentConversationId)\n }\n }\n\n /**\n * 断开连接\n */\n disconnect(): void {\n // ✅ 断开连接时,清除降级标记\n this.isFallbackMode = false\n this.isConnecting = false\n // 移除所有WebSocket事件监听器,避免内存泄漏\n this.wsClient.removeAllListeners()\n this.wsClient.disconnect()\n this.currentConversationId = null\n }\n\n /**\n * 获取当前会话ID\n */\n getCurrentConversationId(): string | null {\n return this.currentConversationId\n }\n\n /**\n * 重置会话ID(用于打断后清理)\n */\n resetConversationId(): void {\n this.currentConversationId = null\n this.resetAudioMetrics()\n }\n\n /**\n * 设置 WebSocket 事件监听器\n * Safety: Remove existing listeners before adding new ones to prevent duplicates\n */\n private setupWebSocketListeners(): void {\n // Remove all listeners first to prevent duplicates if connect() is called multiple times\n this.wsClient.removeAllListeners()\n \n this.wsClient.on('connected', () => {\n // ✅ 连接成功,清除降级标记\n this.isFallbackMode = false\n this.dataController.setConnected(true)\n this.dataController.onConnectionState?.(ConnectionState.connected)\n AvatarKit.logEvent('character_animation_service', 'info', {\n characterId: this.dataController.getAvatarId(),\n event: 'connected',\n })\n })\n\n this.wsClient.on('disconnected', () => {\n this.dataController.setConnected(false)\n this.dataController.onConnectionState?.(ConnectionState.disconnected)\n AvatarKit.logEvent('character_animation_service', 'warning', {\n characterId: this.dataController.getAvatarId(),\n event: 'disconnected',\n })\n })\n\n this.wsClient.on('reconnecting', () => {\n AvatarKit.logEvent('character_animation_service', 'info', {\n characterId: this.dataController.getAvatarId(),\n event: 'reconnecting',\n })\n })\n\n this.wsClient.on('error', (error: Error) => {\n const message = error instanceof Error ? error.message : String(error)\n logger.error('[NetworkLayer] WebSocket error:', message)\n AvatarKit.logEvent('character_animation_service', 'error', {\n characterId: this.dataController.getAvatarId(),\n event: 'websocket_error',\n reason: message,\n })\n this.dataController.onConnectionState?.(ConnectionState.failed)\n this.dataController.onError?.(error)\n })\n\n this.wsClient.on('message', (message: Message) => {\n this.handleMessage(message)\n })\n }\n\n /**\n * 处理接收到的消息\n */\n private handleMessage(message: Message): void {\n try {\n switch (message.type) {\n case MessageType.MESSAGE_SERVER_RESPONSE_ANIMATION:\n this.handleAnimationMessage(message)\n break\n case MessageType.MESSAGE_ERROR:\n this.handleErrorMessage(message)\n break\n default:\n // 忽略未知消息类型\n }\n }\n catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n logger.error('[NetworkLayer] Failed to handle message:', message)\n AvatarKit.logEvent('character_manager', 'error', {\n characterId: this.dataController.getAvatarId(),\n event: 'handle_message_failed',\n reason: message,\n })\n }\n }\n\n /**\n * 处理动画消息\n */\n private handleAnimationMessage(message: Message): void {\n if (!message.serverResponseAnimation) {\n logger.error('[NetworkLayer] Invalid animation message')\n return\n }\n\n const { reqId, animation } = message.serverResponseAnimation\n // 将 protobuf 中的 reqId 映射为 conversationId\n const conversationId = reqId\n\n // 只接受当前活跃会话的动画\n if (!this.currentConversationId || conversationId !== this.currentConversationId) {\n logger.warn(`[NetworkLayer] Ignoring mismatched animation message - expected conversationId: ${this.currentConversationId}, received conversationId: ${conversationId}`)\n AvatarKit.logEvent('character_manager', 'warning', {\n characterId: this.dataController.getAvatarId(),\n event: 'animation_conversationid_mismatch',\n expectedConversationId: this.currentConversationId,\n receivedConversationId: conversationId,\n })\n return\n }\n\n if (animation?.keyframes && animation.keyframes.length > 0) {\n const keyframes = animation.keyframes\n\n // 网络层获取数据后,调用播放层接口(传入 conversationId)\n this.dataController.yieldFramesData(keyframes, conversationId)\n\n // 如果是第一条消息,触发播放\n if (!this.dataController.getIsPlaying()) {\n this.dataController.startStreamingPlayback()\n }\n\n // 统计第一条动画数据接收时间\n if (!this.audioMetrics.didRecvFirstFlame) {\n this.audioMetrics.didRecvFirstFlame = true\n this.audioMetrics.recvFirstFlameTimestamp = Date.now()\n if (this.currentConversationId) {\n this.reportAudioMetrics(this.currentConversationId)\n }\n }\n } else {\n logger.warn(`[NetworkLayer] Animation message has no keyframes - conversationId: ${conversationId}`)\n AvatarKit.logEvent('character_manager', 'warning', {\n characterId: this.dataController.getAvatarId(),\n event: 'animation_empty_keyframes',\n conversationId,\n })\n }\n }\n\n /**\n * 处理错误消息\n */\n private handleErrorMessage(message: Message): void {\n if (!message.error) {\n logger.warn('[NetworkLayer] MESSAGE_ERROR received but message.error is empty')\n // 检查是否包含动画数据(可能是消息类型解析错误)\n if (message.serverResponseAnimation) {\n logger.warn('[NetworkLayer] MESSAGE_ERROR contains animation data, treating as animation message')\n AvatarKit.logEvent('character_manager', 'warning', {\n characterId: this.dataController.getAvatarId(),\n event: 'message_error_with_payload',\n })\n this.handleAnimationMessage(message)\n }\n return\n }\n\n // 将 protobuf 中的 reqId 映射为 conversationId\n const conversationId = message.error.reqId\n logger.error(`[NetworkLayer] Server error: conversationId=${conversationId}, code=${message.error.code}, reason=${message.error.reason}`)\n AvatarKit.logEvent('character_manager', 'error', {\n characterId: this.dataController.getAvatarId(),\n event: 'server_error',\n conversationId,\n code: message.error.code,\n reason: message.error.reason,\n })\n\n const errorCode = message.error.code?.toString().toLowerCase() ?? ''\n if (errorCode.includes('unauth') || errorCode === '401') {\n AvatarKit.logEvent('sdk_verify', 'error', {\n characterId: this.dataController.getAvatarId(),\n conversationId,\n reason: message.error.reason,\n })\n }\n\n this.dataController.onError?.(new SPAvatarError(\n message.error.reason || 'Server error occurred',\n message.error.code?.toString() || 'SERVER_ERROR',\n ))\n\n // 如果是当前会话的错误,通过传入空动画数据来触发降级(复用统一逻辑)\n if (this.currentConversationId && conversationId === this.currentConversationId) {\n logger.warn('[NetworkLayer] Server error for current conversation - triggering audio-only mode via empty keyframes')\n // ✅ 复用 yieldFramesData 的降级逻辑,统一降级触发路径\n this.dataController.yieldFramesData([], conversationId)\n // ✅ 不调用 interrupt(),让音频继续播放\n }\n }\n\n /**\n * 创建音频指标\n */\n private createAudioMetrics(): AudioMetrics {\n return {\n accumulatedBytes: 0,\n startTimestamp: 0,\n tap2Timestamp: 0,\n tap4Timestamp: 0,\n endTimestamp: 0,\n recvFirstFlameTimestamp: 0,\n didRecvFirstFlame: false,\n }\n }\n\n /**\n * 重置音频指标\n */\n private resetAudioMetrics(): void {\n this.audioMetrics = this.createAudioMetrics()\n }\n\n /**\n * 上报音频指标\n */\n private reportAudioMetrics(conversationId: string): void {\n if (!conversationId || this.audioMetrics.startTimestamp === 0) {\n return\n }\n\n AvatarKit.logEvent('send_audio_measure', 'info', {\n conversationId,\n start: this.audioMetrics.startTimestamp,\n tap2: this.audioMetrics.tap2Timestamp,\n tap4: this.audioMetrics.tap4Timestamp,\n end: this.audioMetrics.endTimestamp,\n firstFlame: this.audioMetrics.recvFirstFlameTimestamp,\n })\n }\n\n}\n\n","/**\n * AvatarController: Unified data controller (playback layer)\n * Responsible for audio playback and animation rendering synchronization\n * Automatically decides whether to compose network layer based on configuration\n */\n\nimport type { Flame } from '../generated/driveningress/v1/driveningress'\nimport type { Avatar } from './Avatar'\n\nimport { APP_CONFIG } from '../config/app-config'\nimport { convertProtoFlameToWasmParams } from '../animation/utils/flameConverter'\nimport { AnimationPlayer } from '../audio/AnimationPlayer'\nimport { AvatarState, ConnectionState, SPAvatarError, AvatarPlaybackMode } from '../types'\nimport { logger } from '../utils/logger'\nimport { generateConversationId } from '../utils/conversationId'\nimport { AvatarKit } from './AvatarKit'\nimport { NetworkLayer } from './NetworkLayer'\n\nexport class AvatarController {\n // ========== Configuration and Composition ==========\n private networkLayer?: NetworkLayer\n public readonly playbackMode: AvatarPlaybackMode\n protected avatar: Avatar\n\n // ========== Player Management ==========\n protected animationPlayer: AnimationPlayer | null = null\n protected currentKeyframes: Flame[] = []\n protected pendingAudioChunks: Array<{ data: Uint8Array, isLast: boolean }> = []\n protected isPlaying = false\n\n // ========== State Management ==========\n protected isConnected = false\n protected currentState: AvatarState = AvatarState.idle\n \n // ========== Conversation ID Management (for external data mode) ==========\n private currentConversationId: string | null = null\n private reqEnd: boolean = false\n\n // ========== Event System ==========\n public onConnectionState: ((state: ConnectionState) => void) | null = null\n public onAvatarState: ((state: AvatarState) => void) | null = null\n public onError: ((error: Error) => void) | null = null\n private eventListeners = new Map<string, Set<(data?: any) => void>>()\n\n // ========== Callbacks ==========\n private renderCallback?: (splatData: Float32Array, frameIndex: number) => void\n private transitionCompleteCallback?: () => void\n private characterHandle: number | null = null // Character handle for multi-character support\n\n // ========== Playback Loop ==========\n private playbackLoopId: number | null = null\n private lastRenderedFrameIndex: number = -1\n private keyframesOffset = 0 // Offset to track how many frames were removed from the beginning\n private readonly MAX_KEYFRAMES = 5000 // Maximum keyframes to keep in memory during playback\n private readonly KEYFRAMES_CLEANUP_THRESHOLD = 3000 // Cleanup threshold (keep some buffer)\n private readonly MAX_PENDING_AUDIO_CHUNKS = 100 // Maximum pending audio chunks to prevent memory leak\n\n // ========== Audio Only Mode ==========\n private isAudioOnlyMode = false // 音频独立播放模式标志\n\n constructor(avatar: Avatar, options?: { playbackMode?: AvatarPlaybackMode }) {\n this.avatar = avatar\n this.playbackMode = options?.playbackMode ?? AvatarPlaybackMode.network\n\n // Create and compose network layer automatically if in network mode\n if (this.playbackMode === AvatarPlaybackMode.network) {\n this.networkLayer = new NetworkLayer(this)\n }\n }\n\n // ========== Internal Accessors (for NetworkLayer and AvatarView) ==========\n\n /**\n * Get Avatar ID (for NetworkLayer use)\n * @internal\n */\n getAvatarId(): string {\n return this.avatar.id\n }\n\n /**\n * Get playback state (for NetworkLayer use)\n * @internal\n */\n getIsPlaying(): boolean {\n return this.isPlaying\n }\n\n /**\n * Set connection state (for NetworkLayer use)\n * @internal\n */\n setConnected(connected: boolean): void {\n this.isConnected = connected\n }\n\n /**\n * Get connection state\n * @internal\n */\n get connected(): boolean {\n return this.isConnected\n }\n\n /**\n * Get current state\n * @internal\n */\n get state(): AvatarState {\n return this.currentState\n }\n\n /**\n * Get animation player instance\n * @internal\n */\n public getAnimationPlayer(): AnimationPlayer | null {\n return this.animationPlayer\n }\n\n /**\n * Get current conversation ID\n * Returns the current conversation ID for the active audio session\n * @returns Current conversation ID, or null if no active session\n */\n getCurrentConversationId(): string | null {\n return this.getEffectiveConversationId()\n }\n\n // ========== Network Mode Interface ==========\n\n /**\n * Start service (network mode only)\n */\n async start(): Promise<void> {\n if (!this.networkLayer) {\n throw new SPAvatarError(\n 'Network layer not available. Use network playback mode.',\n 'NETWORK_LAYER_NOT_AVAILABLE'\n )\n }\n\n // Initialize player\n if (!this.animationPlayer) {\n this.animationPlayer = new AnimationPlayer()\n try {\n await this.animationPlayer.createAndInitializeStreamingPlayer()\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n logger.error('[AvatarController] Failed to create streaming player:', message)\n AvatarKit.logEvent('character_player', 'error', {\n characterId: this.avatar.id,\n event: 'streaming_player_init_failed',\n reason: message,\n })\n throw error\n }\n }\n\n await this.networkLayer.connect(this.avatar.id)\n // Note: onConnectionState will be called when NetworkLayer's WebSocket connection succeeds\n // No need to call it here immediately, as connection is asynchronous\n }\n\n /**\n * Send audio to server (network mode only)\n * Also cache to data layer for playback\n * @returns conversationId - Conversation ID for this audio session\n */\n send(audioData: ArrayBuffer, end: boolean = false): string | null {\n if (!this.networkLayer) {\n this.onError?.(new SPAvatarError('Network layer not available', 'NETWORK_LAYER_NOT_AVAILABLE'))\n return null\n }\n\n // ✅ 连接检查(包括降级模式)由 NetworkLayer 负责\n if (!this.networkLayer.canSend()) {\n this.onError?.(new SPAvatarError('Service not connected', 'NOT_CONNECTED'))\n AvatarKit.logEvent('character_manager', 'warning', {\n characterId: this.avatar.id,\n event: 'send_not_connected',\n })\n return null\n }\n\n // 获取网络层的当前 conversation ID(网络模式由 NetworkLayer 管理 conversation ID)\n const networkConversationId = this.networkLayer.getCurrentConversationId()\n \n // 如果 reqEnd 为 true 且又传入了新音频,打断当前会话\n if (this.reqEnd && this.isPlaying && networkConversationId) {\n this.interrupt()\n // interrupt 会重置 NetworkLayer 的 conversation ID,所以需要重新生成\n }\n\n // ✅ 先添加音频数据到缓冲区(确保降级逻辑触发时数据已准备好)\n this.addAudioChunkToBuffer(new Uint8Array(audioData), end)\n\n // 发送到服务器(NetworkLayer 内部会处理 conversation ID 生成)\n // 降级模式下,这里会触发 yieldFramesData([], conversationId),此时音频数据已在缓冲区\n this.networkLayer.sendAudioData(audioData, end)\n\n // 如果 end=true,设置 reqEnd 标识\n if (end) {\n this.reqEnd = true\n }\n\n this.onAvatarState?.(AvatarState.active)\n\n // 返回当前的 conversation ID(NetworkLayer 管理)\n return this.networkLayer.getCurrentConversationId()\n }\n\n /**\n * Close service (network mode only)\n */\n close(): void {\n // If playing or paused, stop playback first (stopPlayback will reset all states)\n if (this.isPlaying || this.currentState === AvatarState.paused) {\n this.stopPlayback()\n }\n \n // Clean up data and state\n this.clearPlaybackData()\n \n // 重置 conversation ID 和 reqEnd\n if (this.networkLayer) {\n this.networkLayer.disconnect()\n } else {\n this.currentConversationId = null\n }\n this.reqEnd = false\n \n // Disconnect network\n this.isConnected = false\n this.onConnectionState?.(ConnectionState.disconnected)\n }\n\n // ========== External Data Mode Interface ==========\n\n /**\n * Playback existing audio and animation data (external data mode)\n * Starts a new conversation by generating a new conversation ID and interrupting any existing conversation\n * @param initialAudioChunks - Existing audio chunks to playback\n * @param initialKeyframes - Existing animation keyframes to playback\n * @returns conversationId - New conversation ID for this conversation session\n */\n async playback(\n initialAudioChunks?: Array<{ data: Uint8Array, isLast: boolean }>,\n initialKeyframes?: Flame[]\n ): Promise<string> {\n // 打断已有对话并生成新的 conversation ID\n if (this.isPlaying || this.currentConversationId) {\n this.interrupt()\n }\n \n // 生成新的 conversation ID\n this.currentConversationId = this.generateAndLogNewConversationId()\n this.reqEnd = false\n\n // 清空旧数据\n this.clearPlaybackData()\n\n // Lazy initialize player\n if (!this.animationPlayer) {\n this.animationPlayer = new AnimationPlayer()\n }\n\n if (!this.animationPlayer.isStreamingReady()) {\n await this.animationPlayer.createAndInitializeStreamingPlayer()\n }\n\n // Add initial data\n if (initialAudioChunks && initialAudioChunks.length > 0) {\n this.pendingAudioChunks.push(...initialAudioChunks)\n }\n\n // ✅ 如果动画数据为空,视作进入降级逻辑的信号\n if (initialKeyframes && initialKeyframes.length > 0) {\n this.currentKeyframes = initialKeyframes\n this.emit('keyframesUpdate', this.currentKeyframes)\n } else {\n // 动画数据为空,启用音频独立模式\n logger.warn('[AvatarController] Empty animation data in playback - enabling audio-only mode')\n AvatarKit.logEvent('character_manager', 'info', {\n characterId: this.avatar.id,\n event: 'empty_animation_data_audio_only_fallback',\n conversationId: this.currentConversationId,\n })\n this.isAudioOnlyMode = true\n }\n\n // Check if data is ready\n if (this.pendingAudioChunks.length === 0) {\n throw new SPAvatarError('No audio chunks to play', 'NO_AUDIO')\n }\n\n // 根据是否有动画数据选择播放方式\n if (this.isAudioOnlyMode) {\n // 音频独立模式:只播放音频\n await this.startAudioOnlyPlayback()\n } else {\n // 正常模式:播放音频和动画\n await this.startStreamingPlayback()\n }\n \n // 返回新的 conversation ID\n return this.currentConversationId\n }\n\n /**\n * Send audio data (external data mode)\n * Stream additional audio data after playback()\n * @returns conversationId - Conversation ID for this audio session\n */\n yieldAudioData(data: Uint8Array, isLast: boolean = false): string | null {\n // 如果 reqEnd 为 true 且又传入了新音频,打断当前会话并生成新的 conversation ID\n if (this.reqEnd && this.isPlaying && this.currentConversationId) {\n this.interrupt()\n // interrupt 会重置 currentConversationId,所以需要重新生成\n this.currentConversationId = this.generateAndLogNewConversationId()\n this.reqEnd = false\n }\n\n // 如果当前 conversation ID 为空,生成新的 conversation ID\n if (!this.currentConversationId) {\n // 如果正在播放,先打断当前播放(新 conversation ID = 新会话)\n if (this.isPlaying) {\n this.interrupt()\n }\n this.currentConversationId = this.generateAndLogNewConversationId()\n this.reqEnd = false\n // 新 conversation ID = 新会话,清空所有数据(动画和音频)\n this.clearPlaybackData()\n }\n\n // 如果 isLast=true,设置 reqEnd 标识\n if (isLast) {\n this.reqEnd = true\n }\n\n // If player is ready and playing, add directly to player\n if (this.isPlaying && this.animationPlayer?.isStreamingReady()) {\n this.animationPlayer.addAudioChunk(data, isLast)\n } else {\n // Otherwise cache to pendingAudioChunks\n if (data.length > 0 || isLast) {\n // Memory optimization: Limit pending chunks to prevent memory leak\n if (this.pendingAudioChunks.length >= this.MAX_PENDING_AUDIO_CHUNKS) {\n // Remove oldest chunk (FIFO), but preserve isLast chunk if present\n const lastChunkIndex = this.pendingAudioChunks.findIndex(chunk => chunk.isLast)\n if (lastChunkIndex >= 0 && lastChunkIndex < this.pendingAudioChunks.length - 1) {\n // Remove chunks before the last chunk, but keep the last chunk\n this.pendingAudioChunks.splice(0, lastChunkIndex)\n } else {\n // No isLast chunk or it's at the end, remove oldest chunk\n this.pendingAudioChunks.shift()\n }\n logger.warn(`[AvatarController] Pending audio chunks limit reached (${this.MAX_PENDING_AUDIO_CHUNKS}), removed oldest chunk`)\n }\n this.pendingAudioChunks.push({ data, isLast })\n this.onAvatarState?.(AvatarState.active)\n }\n }\n\n // 返回当前的 conversation ID\n return this.currentConversationId\n }\n\n /**\n * Send animation keyframes (external data mode or network mode)\n * Stream additional animation data after playback()\n * @param keyframes - Animation keyframes to send\n * @param conversationId - Conversation ID (required). If conversationId doesn't match current conversationId, keyframes will be discarded.\n * Use getCurrentConversationId() to get the current conversationId.\n */\n yieldFramesData(keyframes: Flame[], conversationId: string): void {\n // 验证 conversationId 参数\n if (!conversationId || typeof conversationId !== 'string') {\n logger.error(`[AvatarController] yieldFramesData requires a valid conversationId. Use getCurrentConversationId() to get the current conversationId.`)\n AvatarKit.logEvent('character_manager', 'error', {\n characterId: this.avatar.id,\n event: 'keyframes_missing_conversationid',\n receivedConversationId: conversationId,\n })\n return\n }\n\n // 验证 conversationId\n const expectedConversationId = this.getEffectiveConversationId()\n\n // 如果 conversationId 和当前的 conversationId 不一致,直接抛弃动画数据\n if (!expectedConversationId || conversationId !== expectedConversationId) {\n logger.warn(`[AvatarController] Ignoring mismatched keyframes - expected conversationId: ${expectedConversationId}, received conversationId: ${conversationId}`)\n AvatarKit.logEvent('character_manager', 'warning', {\n characterId: this.avatar.id,\n event: 'keyframes_conversationid_mismatch',\n expectedConversationId,\n receivedConversationId: conversationId,\n })\n return\n }\n\n // ✅ 关键:如果当前是音频独立模式,忽略动画数据\n if (this.isAudioOnlyMode) {\n logger.warn('[AvatarController] Ignoring animation data in audio-only mode')\n AvatarKit.logEvent('character_manager', 'info', {\n characterId: this.avatar.id,\n event: 'animation_data_ignored_audio_only',\n conversationId,\n })\n return // ✅ 直接返回,不处理动画数据\n }\n\n // ✅ 如果传入的动画数据为空数组,视作进入降级逻辑的信号(适用于外部数据模式和网络模式)\n if (!keyframes || keyframes.length === 0) {\n logger.warn('[AvatarController] Empty animation data received - enabling audio-only mode')\n AvatarKit.logEvent('character_manager', 'info', {\n characterId: this.avatar.id,\n event: 'empty_animation_data_audio_only_fallback',\n conversationId,\n })\n this.enableAudioOnlyMode()\n return\n }\n\n // conversationId 匹配,处理动画数据\n if (this.currentKeyframes.length === 0) {\n this.currentKeyframes = keyframes\n } else {\n this.currentKeyframes.push(...keyframes)\n }\n this.emit('keyframesUpdate', this.currentKeyframes)\n\n // 如果添加了动画数据且 conversationId 匹配,检查是否可以启动播放\n // 条件:还没有播放 && 有音频数据 && 有动画数据\n // 注意:StreamingAudioPlayer 支持流式播放,不需要等待足够的音频缓冲\n if (!this.isPlaying && this.pendingAudioChunks.length > 0 && this.currentKeyframes.length > 0) {\n // 有音频数据和动画数据,立即启动播放(后续音频会通过 yieldAudioData 继续添加)\n this.startStreamingPlayback().catch(error => {\n logger.error('[AvatarController] Failed to auto-start playback:', error)\n this.onError?.(new SPAvatarError('Failed to start playback', 'PLAYBACK_START_FAILED'))\n })\n }\n }\n\n // ========== Common Interface ==========\n\n /**\n * Pause playback (can be resumed later)\n * Pause audio playback and stop render loop, but preserve all state (keyframes, audio buffers, etc.)\n */\n pause(): void {\n if (!this.isPlaying || this.currentState === AvatarState.paused) {\n return\n }\n\n logger.log('[AvatarController] Pausing playback')\n\n // 1. Pause audio playback (synchronous operation - suspend AudioContext)\n this.animationPlayer?.pause()\n\n // 2. Stop render loop (but keep all state intact)\n this.stopPlaybackLoop()\n\n // 3. Update internal state\n this.currentState = AvatarState.paused\n\n // 4. Notify external state change\n this.onAvatarState?.(AvatarState.paused)\n\n logger.log('[AvatarController] Playback paused')\n AvatarKit.logEvent('character_player', 'info', {\n characterId: this.avatar.id,\n event: 'playback_paused',\n conversationId: this.networkLayer?.getCurrentConversationId() || undefined,\n })\n }\n\n /**\n * Resume playback (from paused state)\n * Resume audio playback and restart render loop\n * Animation will continue from paused frame (because animation time base comes from audio, will auto-sync)\n */\n async resume(): Promise<void> {\n if (!this.isPlaying || this.currentState !== AvatarState.paused) {\n return\n }\n\n logger.log('[AvatarController] Resuming playback')\n\n // 1. Resume audio playback (asynchronous operation - resume AudioContext)\n await this.animationPlayer?.resume()\n\n // 2. Restart render loop (will use audio time to calculate frame index)\n this.startPlaybackLoop()\n\n // 3. Update internal state\n this.currentState = AvatarState.playing\n\n // 4. Notify external state change\n this.onAvatarState?.(AvatarState.playing)\n\n logger.log('[AvatarController] Playback resumed')\n AvatarKit.logEvent('character_player', 'info', {\n characterId: this.avatar.id,\n event: 'playback_resumed',\n conversationId: this.networkLayer?.getCurrentConversationId() || undefined,\n })\n }\n\n /**\n * Interrupt current playback\n */\n interrupt(): void {\n // If in paused state, resume AudioContext first (but don't wait)\n if (this.currentState === AvatarState.paused) {\n // Note: No await here, as interrupt is a synchronous operation\n // Resume operation will complete in background, but we'll clean up state immediately\n this.animationPlayer?.resume().catch(() => {\n // Ignore resume errors, as we're interrupting playback\n })\n }\n\n // stopPlayback() will reset all states, including currentState\n this.stopPlayback()\n this.emit('interrupt')\n this.clearPlaybackData()\n // Note: No need to duplicate setting currentState, stopPlayback() already handles it\n \n // 重置 conversation ID 和 reqEnd\n this.resetConversationIdState()\n this.isAudioOnlyMode = false // ✅ 重置音频独立模式\n }\n\n /**\n * Clear all data and resources\n */\n clear(): void {\n if (this.isPlaying) {\n this.stopPlayback()\n }\n this.networkLayer?.disconnect()\n this.cleanupPlayers()\n this.clearPlaybackData()\n this.isConnected = false\n this.currentState = AvatarState.idle\n this.onAvatarState?.(AvatarState.idle)\n \n // 重置 conversation ID 和 reqEnd\n if (this.networkLayer) {\n // NetworkLayer.disconnect() 已经重置了 conversation ID\n } else {\n this.currentConversationId = null\n }\n this.reqEnd = false\n }\n\n /**\n * Dispose controller, clean up all callbacks to avoid memory leaks\n * Should be called when AvatarView.dispose()\n * @internal\n */\n dispose(): void {\n // Clean up all callbacks to avoid memory leaks\n this.onConnectionState = null\n this.onAvatarState = null\n this.onError = null\n this.renderCallback = undefined\n this.transitionCompleteCallback = undefined\n this.eventListeners.clear()\n }\n\n // ========== Internal Helper Methods ==========\n\n /**\n * Generate new conversation ID and log conversation started event\n * @private\n */\n private generateAndLogNewConversationId(): string {\n const conversationId = generateConversationId()\n AvatarKit.logEvent('character_manager', 'info', {\n characterId: this.avatar.id,\n event: 'conversation_started',\n conversationId,\n })\n return conversationId\n }\n\n /**\n * Clear playback data (keyframes, audio chunks, and playback state)\n * @private\n */\n private clearPlaybackData(): void {\n this.currentKeyframes = []\n this.pendingAudioChunks = []\n this.lastRenderedFrameIndex = -1\n this.keyframesOffset = 0\n this.isAudioOnlyMode = false // ✅ 重置音频独立模式\n }\n\n /**\n * Reset conversation ID state (for both network and external modes)\n * @private\n */\n private resetConversationIdState(): void {\n if (this.networkLayer) {\n // 网络模式:重置 NetworkLayer 的 conversation ID\n this.networkLayer.resetConversationId()\n } else {\n // 外部数据模式:重置 AvatarController 的 conversation ID\n this.currentConversationId = null\n }\n this.reqEnd = false\n this.isAudioOnlyMode = false // ✅ 重置音频独立模式\n }\n\n /**\n * Get effective conversation ID (handles both network and external modes)\n * @private\n */\n private getEffectiveConversationId(): string | null {\n if (this.playbackMode === AvatarPlaybackMode.network) {\n return this.networkLayer?.getCurrentConversationId() || null\n } else {\n return this.currentConversationId\n }\n }\n\n // ========== Internal Methods (for NetworkLayer and AvatarView use) ==========\n\n /**\n * Start streaming playback (internal method, called by NetworkLayer or playback())\n * @internal\n */\n startStreamingPlayback(): Promise<void> {\n return this.startStreamingPlaybackInternal()\n }\n\n /**\n * Set render callback (called by AvatarView)\n * @internal\n */\n setRenderCallback(callback: (splatData: Float32Array, frameIndex: number) => void, characterHandle?: number | null): void {\n this.renderCallback = callback\n if (characterHandle !== undefined) {\n this.characterHandle = characterHandle\n }\n }\n\n /**\n * Set transition complete callback (called by AvatarView)\n * @internal\n */\n setTransitionCompleteCallback(callback: () => void): void {\n this.transitionCompleteCallback = callback\n }\n\n /**\n * Transition complete notification (called by AvatarView)\n * @internal\n */\n onTransitionComplete(): void {\n const streamingPlayer = this.animationPlayer?.getStreamingPlayer()\n if (streamingPlayer) {\n streamingPlayer.play()\n }\n }\n\n /**\n * Provide interface for AvatarView to register internal events\n * @internal\n */\n public setupInternalEventListeners(callbacks: {\n onKeyframesUpdate?: (keyframes: Flame[]) => void\n onStartRendering?: () => void\n onStopRendering?: () => void\n onInterrupt?: () => void\n }): void {\n if (callbacks.onKeyframesUpdate) {\n this.registerEventListener('keyframesUpdate', callbacks.onKeyframesUpdate)\n }\n if (callbacks.onStartRendering) {\n this.registerEventListener('startRendering', callbacks.onStartRendering)\n }\n if (callbacks.onStopRendering) {\n this.registerEventListener('stopRendering', callbacks.onStopRendering)\n }\n if (callbacks.onInterrupt) {\n this.registerEventListener('interrupt', callbacks.onInterrupt)\n }\n }\n\n // ========== Private Methods ==========\n\n /**\n * Start streaming playback (internal implementation)\n */\n private async startStreamingPlaybackInternal(): Promise<void> {\n \n // Lazy initialize player (在需要播放时初始化)\n if (!this.animationPlayer) {\n this.animationPlayer = new AnimationPlayer()\n }\n\n if (!this.animationPlayer.isStreamingReady()) {\n try {\n await this.animationPlayer.createAndInitializeStreamingPlayer()\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n logger.error('[AvatarController] Failed to create streaming player:', message)\n AvatarKit.logEvent('character_player', 'error', {\n characterId: this.avatar.id,\n event: 'streaming_player_init_failed',\n reason: message,\n })\n throw error\n }\n }\n\n // Cannot play without animation data\n if (!this.currentKeyframes || this.currentKeyframes.length === 0) {\n logger.warn('[AvatarController] No animation keyframes to play')\n return\n }\n\n try {\n // Prepare player\n await this.animationPlayer.prepareStreamingPlayer(() => {\n this.isPlaying = false\n this.currentState = AvatarState.idle\n this.onAvatarState?.(AvatarState.idle)\n this.emit('stopRendering')\n \n // Clean up state to avoid affecting next conversation\n this.clearPlaybackData()\n \n // 重置 conversation ID 和 reqEnd(播放结束时)\n if (this.networkLayer) {\n this.networkLayer.resetConversationId()\n } else {\n this.currentConversationId = null\n }\n this.reqEnd = false\n this.isAudioOnlyMode = false // ✅ 播放结束时重置音频独立模式\n \n AvatarKit.logEvent('character_player', 'info', {\n characterId: this.avatar.id,\n event: 'playback_ended',\n conversationId: this.networkLayer?.getCurrentConversationId() || undefined,\n })\n })\n\n // Notify start rendering (triggers transition animation generation)\n this.emit('startRendering')\n\n // Get StreamingAudioPlayer and disable auto-play (wait for transition animation to complete)\n const streamingPlayer = this.animationPlayer.getStreamingPlayer()\n if (streamingPlayer) {\n streamingPlayer.setAutoStart(false)\n }\n\n // Add initial audio data (don't auto-play)\n if (streamingPlayer) {\n await streamingPlayer.startNewSession(this.pendingAudioChunks)\n }\n this.pendingAudioChunks = []\n\n // Mark as playing (audio will be started by onTransitionComplete after transition completes)\n this.isPlaying = true\n this.currentState = AvatarState.playing\n this.onAvatarState?.(AvatarState.playing)\n\n // Start playback loop (audio-visual synchronization)\n this.startPlaybackLoop()\n\n AvatarKit.logEvent('character_player', 'info', {\n characterId: this.avatar.id,\n event: 'playback_started',\n conversationId: this.networkLayer?.getCurrentConversationId() || undefined,\n })\n }\n catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n logger.error('[AvatarController] Failed to start streaming playback:', message)\n this.onError?.(new SPAvatarError('Failed to start streaming playback', 'INIT_FAILED'))\n this.isPlaying = false\n }\n }\n\n /**\n * Playback loop: Calculate animation frame based on audio time, notify render layer to render\n */\n private startPlaybackLoop(): void {\n if (this.playbackLoopId) {\n return\n }\n\n const fps = APP_CONFIG.animation.fps\n\n const playLoop = async () => {\n // Defensive check: If not playing, paused, or player doesn't exist, stop loop\n if (!this.isPlaying || this.currentState === AvatarState.paused || !this.animationPlayer) {\n this.playbackLoopId = null\n return\n }\n\n try {\n // Get audio time (master clock)\n const audioTime = this.animationPlayer.getCurrentTime()\n\n // If audio hasn't started playing yet (during transition animation), don't render real-time frames\n if (audioTime === 0) {\n this.playbackLoopId = requestAnimationFrame(playLoop)\n return\n }\n\n // Calculate animation frame index based on audio time\n // frameIndex is absolute (from audio start), need to convert to array index\n let frameIndex = Math.floor(audioTime * fps)\n\n // Limit to valid range (absolute index)\n if (frameIndex < 0) frameIndex = 0\n \n // Convert absolute frameIndex to array index (accounting for cleaned up frames)\n let arrayIndex = frameIndex - this.keyframesOffset\n \n // If frameIndex is before the offset, use first available frame\n if (arrayIndex < 0) {\n arrayIndex = 0\n }\n \n // Limit to array bounds\n if (arrayIndex >= this.currentKeyframes.length) {\n arrayIndex = this.currentKeyframes.length - 1\n }\n\n // Performance optimization: Skip duplicate frame rendering (compare absolute frameIndex)\n if (frameIndex === this.lastRenderedFrameIndex) {\n this.playbackLoopId = requestAnimationFrame(playLoop)\n return\n }\n\n this.lastRenderedFrameIndex = frameIndex\n\n // Memory optimization: Clean up old keyframes if array is too long\n // Keep current frame and some buffer frames before it, but remove frames that are far behind\n // frameIndex is absolute (from audio start), keyframesOffset tracks how many frames were removed\n if (this.currentKeyframes.length > this.MAX_KEYFRAMES) {\n const framesToKeep = this.KEYFRAMES_CLEANUP_THRESHOLD\n // Calculate how many frames to remove (keep framesToKeep frames before current frameIndex)\n const framesToRemove = frameIndex - framesToKeep\n \n // Only cleanup if we're far enough into the animation (avoid cleanup at the beginning)\n if (framesToRemove > 0 && framesToRemove < frameIndex) {\n // Remove frames before the cleanup threshold\n this.currentKeyframes.splice(0, framesToRemove)\n // Update offset to track how many frames were removed\n this.keyframesOffset += framesToRemove\n // Recalculate arrayIndex after cleanup\n arrayIndex = frameIndex - this.keyframesOffset\n if (arrayIndex < 0) arrayIndex = 0\n if (arrayIndex >= this.currentKeyframes.length) {\n arrayIndex = this.currentKeyframes.length - 1\n }\n logger.log(`[AvatarController] Cleaned up ${framesToRemove} old keyframes (kept ${this.currentKeyframes.length} frames, offset: ${this.keyframesOffset})`)\n }\n }\n\n // Get current frame and render using arrayIndex\n if (arrayIndex >= 0 && arrayIndex < this.currentKeyframes.length) {\n const currentFrame = this.currentKeyframes[arrayIndex]\n const wasmParams = convertProtoFlameToWasmParams(currentFrame)\n\n const avatarCore = AvatarKit.getAvatarCore()\n if (avatarCore) {\n const splatData = await avatarCore.computeFrameFlatFromParams(wasmParams, this.characterHandle ?? undefined)\n if (splatData && this.renderCallback) {\n // Notify render layer to render this frame (use original frameIndex for callback)\n this.renderCallback(splatData, frameIndex)\n }\n }\n }\n }\n catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error)\n logger.error('[AvatarController] Playback loop error:', errorMessage)\n }\n\n // Continue to next frame\n if (this.isPlaying) {\n this.playbackLoopId = requestAnimationFrame(playLoop)\n } else {\n this.playbackLoopId = null\n }\n }\n\n this.playbackLoopId = requestAnimationFrame(playLoop)\n }\n\n /**\n * Stop playback loop\n */\n private stopPlaybackLoop(): void {\n if (this.playbackLoopId) {\n cancelAnimationFrame(this.playbackLoopId)\n this.playbackLoopId = null\n }\n }\n\n // ========== Audio Only Mode ==========\n\n /**\n * 启用音频独立播放模式(当服务器错误或超时时调用)\n * 此模式下,音频会独立播放,不依赖动画数据\n * 一旦启用,本次会话后续的动画数据将被忽略\n * @private\n */\n private enableAudioOnlyMode(): void {\n if (this.isAudioOnlyMode) {\n return // 已经启用\n }\n \n logger.warn('[AvatarController] Enabling audio-only playback mode')\n this.isAudioOnlyMode = true\n \n // 如果还没开始播放,启动音频独立播放\n if (!this.isPlaying && this.pendingAudioChunks.length > 0) {\n this.startAudioOnlyPlayback().catch(error => {\n logger.error('[AvatarController] Failed to start audio-only playback:', error)\n this.isAudioOnlyMode = false\n })\n }\n }\n\n /**\n * 音频独立播放(完全独立的逻辑,不影响正常播放流程)\n * @private\n */\n private async startAudioOnlyPlayback(): Promise<void> {\n // Lazy initialize player\n if (!this.animationPlayer) {\n this.animationPlayer = new AnimationPlayer()\n }\n\n if (!this.animationPlayer.isStreamingReady()) {\n try {\n await this.animationPlayer.createAndInitializeStreamingPlayer()\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n logger.error('[AvatarController] Failed to create streaming player for audio-only mode:', message)\n AvatarKit.logEvent('character_player', 'error', {\n characterId: this.avatar.id,\n event: 'audio_only_streaming_player_init_failed',\n reason: message,\n })\n throw error\n }\n }\n\n try {\n // 准备播放器(独立的结束回调)\n await this.animationPlayer.prepareStreamingPlayer(() => {\n this.isPlaying = false\n this.currentState = AvatarState.idle\n this.onAvatarState?.(AvatarState.idle)\n this.isAudioOnlyMode = false\n this.clearPlaybackData()\n this.resetConversationIdState()\n \n AvatarKit.logEvent('character_player', 'info', {\n characterId: this.avatar.id,\n event: 'audio_only_playback_ended',\n conversationId: this.getEffectiveConversationId() || undefined,\n })\n })\n\n // ✅ 关键:不触发 startRendering(保持 idle 状态)\n // ✅ 不启动播放循环(因为没有动画数据)\n\n // 获取 StreamingAudioPlayer 并启用自动播放\n const streamingPlayer = this.animationPlayer.getStreamingPlayer()\n if (streamingPlayer) {\n streamingPlayer.setAutoStart(true) // 直接自动播放\n }\n\n // 添加音频数据并开始播放\n if (streamingPlayer) {\n await streamingPlayer.startNewSession(this.pendingAudioChunks)\n }\n this.pendingAudioChunks = []\n\n // 标记为播放中\n this.isPlaying = true\n this.currentState = AvatarState.playing\n this.onAvatarState?.(AvatarState.playing)\n\n // ✅ 启动音频监控循环(只检测音频是否结束,不渲染动画)\n this.startAudioMonitoringLoop()\n\n AvatarKit.logEvent('character_player', 'info', {\n characterId: this.avatar.id,\n event: 'audio_only_playback_started',\n conversationId: this.getEffectiveConversationId() || undefined,\n })\n }\n catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n logger.error('[AvatarController] Failed to start audio-only playback:', message)\n this.onError?.(new SPAvatarError('Failed to start audio-only playback', 'AUDIO_ONLY_INIT_FAILED'))\n this.isPlaying = false\n this.isAudioOnlyMode = false\n throw error\n }\n }\n\n /**\n * 音频监控循环(仅用于音频独立模式)\n * 只检测音频是否结束,不进行动画渲染\n * @private\n */\n private startAudioMonitoringLoop(): void {\n if (this.playbackLoopId) {\n return // 已有循环在运行\n }\n\n const monitorLoop = () => {\n // 检查是否还在音频独立模式\n if (!this.isAudioOnlyMode || !this.isPlaying) {\n this.playbackLoopId = null\n return\n }\n\n // 检查音频是否还在播放\n if (this.animationPlayer?.isPlaying()) {\n this.playbackLoopId = requestAnimationFrame(monitorLoop)\n } else {\n // 音频播放结束,停止循环(结束回调会处理清理)\n this.playbackLoopId = null\n }\n }\n\n this.playbackLoopId = requestAnimationFrame(monitorLoop)\n }\n\n /**\n * Stop playback\n */\n protected stopPlayback(): void {\n this.stopPlaybackLoop()\n if (this.animationPlayer) {\n this.animationPlayer.stop()\n const streamingPlayer = this.animationPlayer.getStreamingPlayer()\n streamingPlayer?.stop()\n }\n this.emit('stopRendering')\n this.isPlaying = false\n this.currentState = AvatarState.idle\n this.onAvatarState?.(AvatarState.idle)\n }\n\n /**\n * Clean up players\n */\n protected cleanupPlayers(): void {\n if (this.animationPlayer) {\n this.animationPlayer.dispose()\n this.animationPlayer = null\n }\n }\n\n /**\n * Add audio chunk to buffer\n */\n private addAudioChunkToBuffer(data: Uint8Array, isLast: boolean): void {\n if (!this.animationPlayer) {\n this.animationPlayer = new AnimationPlayer()\n }\n\n if (this.isPlaying && this.animationPlayer.isStreamingReady()) {\n this.animationPlayer.addAudioChunk(data, isLast)\n } else {\n // Memory optimization: Limit pending chunks to prevent memory leak\n if (this.pendingAudioChunks.length >= this.MAX_PENDING_AUDIO_CHUNKS) {\n // Remove oldest chunk (FIFO), but preserve isLast chunk if present\n const lastChunkIndex = this.pendingAudioChunks.findIndex(chunk => chunk.isLast)\n if (lastChunkIndex >= 0 && lastChunkIndex < this.pendingAudioChunks.length - 1) {\n // Remove chunks before the last chunk, but keep the last chunk\n this.pendingAudioChunks.splice(0, lastChunkIndex)\n } else {\n // No isLast chunk or it's at the end, remove oldest chunk\n this.pendingAudioChunks.shift()\n }\n logger.warn(`[AvatarController] Pending audio chunks limit reached (${this.MAX_PENDING_AUDIO_CHUNKS}), removed oldest chunk`)\n }\n this.pendingAudioChunks.push({ data, isLast })\n }\n }\n\n /**\n * Event system\n */\n private registerEventListener(event: string, callback: (data?: any) => void): void {\n if (!this.eventListeners.has(event)) {\n this.eventListeners.set(event, new Set())\n }\n this.eventListeners.get(event)!.add(callback)\n }\n\n /**\n * Emit event\n */\n protected emit(event: string, data?: any): void {\n const listeners = this.eventListeners.get(event)\n if (listeners) {\n listeners.forEach(callback => callback(data))\n }\n }\n}\n","/**\n * Error Utility Functions\n * Provides consistent error handling and formatting across the application\n */\n\n/**\n * Convert unknown error to a readable error message string\n *\n * @param err - Unknown error object (could be Error, string, object, etc.)\n * @returns Formatted error message string\n *\n * @example\n * try {\n * riskyOperation()\n * } catch (err) {\n * const message = errorToMessage(err)\n * logger.error('Operation failed:', message)\n * }\n */\nexport function errorToMessage(err: unknown): string {\n if (err instanceof Error) {\n return err.message\n }\n\n if (typeof err === 'string') {\n return err\n }\n\n if (typeof err === 'object' && err !== null) {\n // Try to extract message property if it exists\n if ('message' in err && typeof err.message === 'string') {\n return err.message\n }\n\n // Try to stringify object\n try {\n return JSON.stringify(err)\n }\n catch {\n return String(err)\n }\n }\n\n return String(err)\n}\n\n/**\n * Convert unknown error to a detailed error message with stack trace (for logging)\n *\n * @param err - Unknown error object\n * @returns Detailed error message with stack if available\n */\nexport function errorToDetailedMessage(err: unknown): string {\n if (err instanceof Error) {\n return err.stack || `${err.name}: ${err.message}`\n }\n\n return errorToMessage(err)\n}\n","/**\n * Avatar Downloader (iOS Compatible)\n * Downloads character resources from CharacterMeta structure\n */\n\nimport type { CharacterMeta, PreloadCameraSettings } from '../types/character'\nimport type { CharacterSettings } from '../types/character-settings'\n\nimport { APP_CONFIG } from '../config/app-config'\nimport { errorToMessage } from '../utils/error-utils'\nimport { logger } from '../utils/logger'\nimport { AvatarKit } from './AvatarKit'\n\ninterface ProgressInfo {\n stage: string\n filename: string\n loaded: number\n total: number\n progress: number\n}\n\ntype ProgressCallback = (info: ProgressInfo) => void\n\ninterface TemplateResources {\n [key: string]: ArrayBuffer\n}\n\ninterface FlameResources {\n flameModel?: { remote?: string }\n flameTemplate?: { remote?: string }\n teethPb?: { remote?: string }\n teethNpz?: { remote?: string }\n}\n\ninterface CharacterDataResult {\n shape: ArrayBuffer\n pointCloud: ArrayBuffer\n idleAnimation?: ArrayBuffer // optional: frameIdle animation\n}\n\nexport interface PreloadResult {\n templateResources: TemplateResources\n characterData: CharacterDataResult\n preloadCameraSettings?: PreloadCameraSettings // 相机配置\n characterSettings?: CharacterSettings // 角色设置(包含 eyelid 等)\n}\n\n/**\n * Simple download helper with CORS proxy support for development\n */\nasync function downloadResource(url: string): Promise<ArrayBuffer> {\n try {\n const headers: HeadersInit = {}\n \n // Add appId and token to headers if available\n const appId = AvatarKit.appId\n const token = AvatarKit.sessionToken\n \n if (appId) {\n headers['X-App-Id'] = appId\n }\n \n if (token) {\n headers['Authorization'] = `Bearer ${token}`\n }\n \n const response = await fetch(url, {\n headers: Object.keys(headers).length > 0 ? headers : undefined,\n })\n \n if (!response.ok) {\n throw new Error(`HTTP ${response.status} ${response.statusText}`)\n }\n return await response.arrayBuffer()\n }\n catch (err) {\n const msg = errorToMessage(err)\n throw new Error(`[downloadResource] ${url} → ${msg}`)\n }\n}\n\n/**\n * Cached download helper (in-memory)\n * Avoids duplicate network fetch for shared/template resources and repeated character loads\n * Uses LRU (Least Recently Used) cache with max size limit to prevent memory leaks\n * Multiple Avatar objects can safely share the same ArrayBuffer since WASM copies the data\n */\nconst MAX_CACHE_SIZE = 50 // Maximum number of cached resources\nconst _resourceCache = new Map<string, ArrayBuffer>()\n\nasync function downloadResourceCached(url: string): Promise<ArrayBuffer> {\n // Check cache (this also moves the entry to \"most recently used\" position in Map)\n const cached = _resourceCache.get(url)\n if (cached) {\n // Move to end (most recently used) - Map maintains insertion order\n _resourceCache.delete(url)\n _resourceCache.set(url, cached)\n return cached\n }\n \n // Download and cache\n const data = await downloadResource(url)\n \n // Remove oldest entry if cache is full (LRU eviction)\n if (_resourceCache.size >= MAX_CACHE_SIZE) {\n // Map.keys() returns entries in insertion order, first is oldest\n const oldestKey = _resourceCache.keys().next().value\n if (oldestKey) {\n _resourceCache.delete(oldestKey)\n }\n }\n \n _resourceCache.set(url, data)\n return data\n}\n\nexport class AvatarDownloader {\n private baseAssetsPath: string\n\n constructor(baseAssetsPath = '/') {\n this.baseAssetsPath = baseAssetsPath\n }\n\n /**\n * Load template resources from CharacterMeta flame CDN URLs\n * Falls back to global CDN config if not provided by API\n */\n async loadTemplateResources(\n flameResources?: FlameResources,\n progressCallback: ProgressCallback | null = null,\n ): Promise<TemplateResources> {\n // Determine resource URLs: use API-provided URLs if available, otherwise use global CDN config\n const useApiResources = flameResources && Object.keys(flameResources).length > 0\n\n if (!useApiResources) {\n logger.log('⚠️ FLAME resources not provided in CharacterMeta, using global CDN config')\n return this.loadGlobalFlameResources(progressCallback)\n }\n\n logger.log('✅ Using FLAME resources from CharacterMeta API')\n\n const templateFiles: Record<string, { url: string | undefined, resourceName: string }> = {\n flameModel: {\n url: flameResources.flameModel?.remote,\n resourceName: 'model.pb',\n },\n flameTemplate: {\n url: flameResources.flameTemplate?.remote,\n resourceName: 'flame_template.pb',\n },\n teethPb: {\n url: flameResources.teethPb?.remote,\n resourceName: 'teeth.pb',\n },\n teethNpz: {\n url: flameResources.teethNpz?.remote,\n resourceName: 'teeth.npz',\n },\n }\n\n const totalFiles = Object.keys(templateFiles).length\n let loadedFiles = 0\n\n const updateProgress = (filename: string, loaded: boolean): void => {\n if (progressCallback) {\n if (loaded)\n loadedFiles++\n\n progressCallback({\n stage: 'template',\n filename,\n loaded: loadedFiles,\n total: totalFiles,\n progress: Math.round((loadedFiles / totalFiles) * 100),\n })\n }\n }\n\n const templateResources: TemplateResources = {}\n\n // Load all template files in parallel from CDN\n const promises = Object.entries(templateFiles).map(async ([key, { url, resourceName }]) => {\n if (!url) {\n throw new Error(`[loadTemplateResources] Missing CDN URL for ${key} (${resourceName})`)\n }\n\n updateProgress(resourceName, false)\n\n logger.log(`📥 Loading ${key} from API CDN: ${url}`)\n const buffer = await downloadResourceCached(url)\n logger.log(`✅ ${key} loaded: ${buffer.byteLength} bytes`)\n\n templateResources[key] = buffer\n updateProgress(resourceName, true)\n })\n\n await Promise.all(promises)\n\n return templateResources\n }\n\n /**\n * Load global FLAME template resources from CDN\n * Uses centralized FLAME CDN config (shared across all characters)\n * @internal 供 AvatarKit 使用\n */\n async loadGlobalFlameResources(\n progressCallback: ProgressCallback | null = null,\n ): Promise<TemplateResources> {\n const { cdnBaseUrl, resources } = APP_CONFIG.flame\n\n const templateFiles: Record<string, { url: string, resourceName: string }> = {\n flameModel: {\n url: `${cdnBaseUrl}/${resources.flameModel}`,\n resourceName: resources.flameModel,\n },\n flameTemplate: {\n url: `${cdnBaseUrl}/${resources.flameTemplate}`,\n resourceName: resources.flameTemplate,\n },\n teethPb: {\n url: `${cdnBaseUrl}/${resources.teethPb}`,\n resourceName: resources.teethPb,\n },\n teethNpz: {\n url: `${cdnBaseUrl}/${resources.teethNpz}`,\n resourceName: resources.teethNpz,\n },\n }\n\n const totalFiles = Object.keys(templateFiles).length\n let loadedFiles = 0\n\n const updateProgress = (filename: string, loaded: boolean): void => {\n if (progressCallback) {\n if (loaded)\n loadedFiles++\n\n progressCallback({\n stage: 'template',\n filename,\n loaded: loadedFiles,\n total: totalFiles,\n progress: Math.round((loadedFiles / totalFiles) * 100),\n })\n }\n }\n\n const templateResources: TemplateResources = {}\n\n // Load all template files in parallel from global CDN\n const promises = Object.entries(templateFiles).map(async ([key, { url, resourceName }]) => {\n updateProgress(resourceName, false)\n\n logger.log(`📥 Loading ${key} from global CDN: ${url}`)\n const buffer = await downloadResourceCached(url)\n logger.log(`✅ ${key} loaded: ${buffer.byteLength} bytes`)\n\n templateResources[key] = buffer\n updateProgress(resourceName, true)\n })\n\n await Promise.all(promises)\n\n return templateResources\n }\n\n /**\n * Load camera settings from CharacterMeta (optional)\n */\n async loadCameraSettings(characterMeta: CharacterMeta): Promise<PreloadCameraSettings | undefined> {\n const cameraUrl = characterMeta.camera?.resource?.remote\n if (!cameraUrl) {\n logger.log('ℹ️ No camera resource URL provided')\n return undefined\n }\n\n try {\n logger.log(`📥 Loading camera info from: ${cameraUrl}`)\n \n const headers: HeadersInit = {}\n const appId = AvatarKit.appId\n const token = AvatarKit.sessionToken\n \n if (appId) {\n headers['X-App-Id'] = appId\n }\n \n if (token) {\n headers['Authorization'] = `Bearer ${token}`\n }\n \n const response = await fetch(cameraUrl, {\n headers: Object.keys(headers).length > 0 ? headers : undefined,\n })\n \n if (!response.ok) {\n throw new Error(`Failed to fetch camera info: ${response.statusText}`)\n }\n\n const cameraSettings = await response.json() as PreloadCameraSettings\n logger.log('✅ Camera info loaded:', cameraSettings)\n return cameraSettings\n }\n catch (error) {\n logger.warn('⚠️ Failed to load camera info, using default:', error)\n return undefined\n }\n }\n\n /**\n * Load character data from CharacterMeta (iOS compatible)\n */\n async loadCharacterData(\n characterMeta: CharacterMeta,\n options?: { progressCallback?: ProgressCallback | null },\n ): Promise<CharacterDataResult> {\n const { progressCallback = null } = options || {}\n // Extract required resource URLs\n const shapeUrl = characterMeta.models?.shape?.resource?.remote\n const pointCloudUrl = characterMeta.models?.gsStandard?.resource?.remote\n const idleAnimationUrl = characterMeta.animations?.frameIdle?.resource?.remote\n\n if (!shapeUrl || !pointCloudUrl) {\n const reason = 'Missing required resources: shape or gsStandard (point cloud)'\n AvatarKit.logEvent('character_load', 'error', {\n characterId: characterMeta.characterId ?? 'unknown',\n stage: 'resource_validation',\n reason,\n })\n throw new Error(reason)\n }\n\n const filesToLoad: Array<{ key: string, url: string, filename: string, optional?: boolean }> = [\n { key: 'shape', url: shapeUrl, filename: 'shape.pb' },\n { key: 'pointCloud', url: pointCloudUrl, filename: 'point_cloud.ply' },\n ]\n\n // Add idle animation if available\n if (idleAnimationUrl) {\n filesToLoad.push({ key: 'idleAnimation', url: idleAnimationUrl, filename: 'idle.pb', optional: true })\n }\n\n\n let loadedFiles = 0\n const totalFiles = filesToLoad.length\n\n const updateProgress = (filename: string, loaded: boolean): void => {\n if (progressCallback) {\n if (loaded)\n loadedFiles++\n\n progressCallback({\n stage: 'character',\n filename,\n loaded: loadedFiles,\n total: totalFiles,\n progress: Math.round((loadedFiles / totalFiles) * 100),\n })\n }\n }\n\n // Download assets in parallel\n const characterData: Partial<CharacterDataResult> = {}\n\n const downloadPromises = filesToLoad.map(async ({ key, url, filename, optional }) => {\n updateProgress(filename, false)\n try {\n const arrayBuffer = await downloadResourceCached(url)\n\n if (key === 'shape') {\n characterData.shape = arrayBuffer\n }\n else if (key === 'pointCloud') {\n characterData.pointCloud = arrayBuffer\n }\n else if (key === 'idleAnimation') {\n characterData.idleAnimation = arrayBuffer\n }\n\n updateProgress(filename, true)\n return { key, success: true }\n }\n catch (error) {\n if (!optional) {\n throw error\n }\n logger.warn(`⚠️ Optional resource ${filename} failed to load:`, error)\n updateProgress(filename, true)\n return { key, success: false }\n }\n })\n\n await Promise.all(downloadPromises)\n\n\n if (!characterData.shape || !characterData.pointCloud) {\n const reason = 'Failed to load character data'\n AvatarKit.logEvent('character_load', 'error', {\n characterId: characterMeta.characterId ?? 'unknown',\n stage: 'download',\n reason,\n })\n throw new Error(reason)\n }\n\n return characterData as CharacterDataResult\n }\n\n /**\n * Preload all resources (template + character data + camera info + settings)\n */\n async preloadResources(\n characterMeta: CharacterMeta,\n options?: {\n progressCallback?: ProgressCallback | null\n },\n ): Promise<PreloadResult> {\n const { progressCallback = null } = options || {}\n\n const [templateResources, characterData, preloadCameraSettings] = await Promise.all([\n this.loadTemplateResources((characterMeta as CharacterMeta & { flame?: FlameResources }).flame, (info) => {\n if (progressCallback) {\n progressCallback({\n ...info,\n stage: `template-${info.stage}`,\n })\n }\n }),\n this.loadCharacterData(characterMeta, {\n progressCallback: (info) => {\n if (progressCallback) {\n progressCallback({\n ...info,\n stage: `character-${info.stage}`,\n })\n }\n },\n }),\n this.loadCameraSettings(characterMeta),\n ])\n\n return {\n templateResources,\n characterData,\n preloadCameraSettings,\n characterSettings: characterMeta.characterSettings,\n }\n }\n\n /**\n * Clear cached assets (no-op, kept for API compatibility)\n */\n clear() {\n // No-op: removed characterAssets cache, relying on browser HTTP cache instead\n }\n\n // ============ API Client Methods ============\n\n /**\n * Get SPAvatarKit SDK API Client (api.spatialwalk.top)\n * Used for: character details and resource URLs (public endpoints, no auth required)\n */\n private getSdkApiClient() {\n return {\n async request(url: string, options: RequestInit = {}) {\n // Get environment config from AvatarKit\n const config = AvatarKit.getEnvironmentConfig()\n const baseUrl = config.sdkApiBaseUrl\n const fullUrl = baseUrl + url\n \n // Build headers with appId and token\n const headers: HeadersInit = {\n 'Content-Type': 'application/json',\n }\n \n const appId = AvatarKit.appId\n const token = AvatarKit.sessionToken\n \n if (appId) {\n headers['X-App-Id'] = appId\n }\n \n if (token) {\n headers['Authorization'] = `Bearer ${token}`\n }\n \n try {\n const response = await fetch(fullUrl, {\n method: options.method || 'GET',\n headers: {\n ...headers,\n ...options.headers,\n },\n body: options.body ? JSON.stringify(options.body) : undefined,\n })\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status} ${response.statusText}`)\n }\n\n return response.json()\n }\n catch (err) {\n const msg = errorToMessage(err)\n throw new Error(`[SdkApiClient] ${fullUrl} → ${msg}`)\n }\n },\n }\n }\n\n /**\n * Get single character by ID from SPAvatarKit SDK API (v2, iOS compatible)\n * Domain: api.spatialwalk.top\n * Auth: Public endpoint, no authentication required\n * Returns CharacterMeta with nested resource structure\n */\n async getCharacterById(characterId: string): Promise<CharacterMeta> {\n try {\n const client = this.getSdkApiClient()\n const response = await client.request(`/v2/character/${characterId}`, {\n method: 'GET',\n })\n\n return response as CharacterMeta\n }\n catch (error: unknown) {\n logger.errorWithError('Failed to fetch character:', error)\n const errorMessage = error && typeof error === 'object' && 'message' in error\n ? String((error as { message?: unknown }).message)\n : 'Failed to fetch character'\n const dataMessage = error && typeof error === 'object' && 'data' in error && typeof (error as { data?: unknown }).data === 'object' && (error as { data?: { message?: unknown } }).data?.message\n ? String((error as { data: { message?: unknown } }).data.message)\n : null\n AvatarKit.logEvent('character_load', 'error', {\n characterId: characterId ?? 'unknown',\n stage: 'fetch',\n reason: dataMessage || errorMessage,\n })\n throw new Error(dataMessage || errorMessage)\n }\n }\n\n}\n","/**\n * AvatarManager:负责数字人管理,内部协调「数字人下载」和「数字人缓存」\n */\n\nimport type { LoadProgressInfo } from '../types'\n\nimport { LoadProgress } from '../types'\nimport { logger } from '../utils/logger'\nimport { Avatar } from './Avatar'\nimport { AvatarDownloader } from './AvatarDownloader'\nimport { AvatarKit } from './AvatarKit'\n\nexport class AvatarManager {\n private static _instance: AvatarManager | null = null\n private avatarDownloader: AvatarDownloader | null = null\n\n /**\n * 通过全局单例来访问\n */\n static get shared(): AvatarManager {\n if (!this._instance) {\n this._instance = new AvatarManager()\n }\n return this._instance\n }\n\n /**\n * 加载数字人\n * @param id 数字人 ID\n * @param onProgress 进度回调\n * @param options 加载选项\n * @returns Promise<Avatar>\n */\n async load(\n id: string,\n onProgress?: (progress: LoadProgressInfo) => void,\n ): Promise<Avatar> {\n logger.log(`[AvatarManager] Loading avatar with id: ${id}`)\n\n try {\n // 检查AvatarKit是否已初始化\n if (!AvatarKit.isInitialized) {\n throw new Error('AvatarKit not initialized. Please call AvatarKit.initialize() first.')\n }\n\n // 1. 初始化资源下载器\n if (!this.avatarDownloader) {\n this.avatarDownloader = new AvatarDownloader()\n }\n\n // 2. 获取角色元数据\n logger.log('[AvatarManager] Step 1: Fetching character metadata...')\n onProgress?.({ type: LoadProgress.downloading, progress: 10 })\n const characterMeta = await this.avatarDownloader.getCharacterById(id)\n\n // 3. 下载资源\n logger.log('[AvatarManager] Step 2: Downloading resources...')\n onProgress?.({ type: LoadProgress.downloading, progress: 30 })\n\n const resources = await this.avatarDownloader.preloadResources(characterMeta, {\n progressCallback: (info) => {\n // 将内部进度转换为外部进度 (30-100%)\n const externalProgress = 30 + (info.progress / 100) * 70\n onProgress?.({\n type: LoadProgress.downloading,\n progress: Math.round(externalProgress),\n })\n },\n })\n\n // 4. 创建 Avatar 实例(模板资源已在初始化时加载)\n logger.log('[AvatarManager] Step 3: Creating Avatar instance...')\n const avatar = new Avatar(id, characterMeta, resources)\n\n logger.log('[AvatarManager] Avatar loaded successfully')\n onProgress?.({ type: LoadProgress.completed })\n\n // 埋点:角色加载成功\n AvatarKit.logEvent('character_load', 'info', {\n characterId: id,\n event: 'load_success',\n })\n\n return avatar\n }\n catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n logger.error('Failed to load avatar:', message)\n AvatarKit.logEvent('character_load', 'error', {\n characterId: id,\n reason: message,\n })\n onProgress?.({ type: LoadProgress.failed, error: error as Error })\n throw error\n }\n }\n\n /**\n * 清理资源加载器缓存\n */\n clearCache(): void {\n if (this.avatarDownloader) {\n this.avatarDownloader.clear()\n }\n }\n}\n","/**\n * Splat 深度排序(Radix Sort 优化版)\n * 使用 11-bit 两轮基数排序,O(n) 时间复杂度\n */\n\n// 复用缓冲区(避免每帧重新分配)\nlet depthBuffer: Float32Array | null = null\nlet depthInt: Uint32Array | null = null\nlet indices0: Uint32Array | null = null\nlet indices1: Uint32Array | null = null\nlet result: Uint32Array | null = null\nlet counts: Uint32Array | null = null\n\nconst BUCKET_SIZE = 2048 // 11 位 = 2^11\nconst MASK = BUCKET_SIZE - 1\n\n/**\n * 对 splats 进行深度排序(Radix Sort)\n * @param packedData Packed 格式数据 [pos3, color4, cov6] x N\n * @param cameraPosition 相机位置\n * @param cameraForward 相机前向向量\n */\nexport function sortSplats(\n packedData: Float32Array,\n cameraPosition: [number, number, number],\n cameraForward: [number, number, number],\n): Uint32Array {\n const floatsPerPoint = 13\n const splatCount = packedData.length / floatsPerPoint\n\n // 初始化或复用缓冲区\n if (!depthBuffer || depthBuffer.length !== splatCount) {\n depthBuffer = new Float32Array(splatCount)\n depthInt = new Uint32Array(depthBuffer.buffer)\n indices0 = new Uint32Array(splatCount)\n indices1 = new Uint32Array(splatCount)\n result = new Uint32Array(splatCount)\n counts = new Uint32Array(BUCKET_SIZE)\n }\n\n const depths = depthBuffer!\n const depthsInt = depthInt!\n const idx0 = indices0!\n const idx1 = indices1!\n const out = result!\n const cnt = counts!\n\n // 1. 计算深度值\n const cx = cameraPosition[0]\n const cy = cameraPosition[1]\n const cz = cameraPosition[2]\n const fx = cameraForward[0]\n const fy = cameraForward[1]\n const fz = cameraForward[2]\n\n for (let i = 0; i < splatCount; i++) {\n const offset = i * floatsPerPoint\n depths[i]\n = (packedData[offset] - cx) * fx\n + (packedData[offset + 1] - cy) * fy\n + (packedData[offset + 2] - cz) * fz\n idx0[i] = i\n }\n\n // 2. 转换深度为整数(用于基数排序)\n // 浮点数翻转负数位以保证排序正确\n for (let i = 0; i < splatCount; i++) {\n const d = depthsInt[i]\n depthsInt[i] = d ^ (-(d >> 31) | 0x80000000)\n }\n\n // 3. 第一轮:按低 11 位排序\n radixPass(depthsInt, idx0, idx1, cnt, 0, splatCount)\n\n // 4. 第二轮:按中间 11 位排序\n radixPass(depthsInt, idx1, idx0, cnt, 11, splatCount)\n\n // 5. 第三轮:按高 10 位排序(32 位总共需要 3 轮)\n radixPass(depthsInt, idx0, idx1, cnt, 22, splatCount)\n\n // 6. 翻转结果(从远到近)\n for (let i = 0; i < splatCount; i++) {\n out[i] = idx1[splatCount - 1 - i]\n }\n\n return out\n}\n\n/**\n * 基数排序单轮\n */\nfunction radixPass(\n keys: Uint32Array,\n indicesIn: Uint32Array,\n indicesOut: Uint32Array,\n counts: Uint32Array,\n shift: number,\n count: number,\n): void {\n // 清零计数\n counts.fill(0)\n\n // 统计桶\n for (let i = 0; i < count; i++) {\n const key = (keys[indicesIn[i]] >> shift) & MASK\n counts[key]++\n }\n\n // 累积计数(前缀和)\n let sum = 0\n for (let i = 0; i < BUCKET_SIZE; i++) {\n const c = counts[i]\n counts[i] = sum\n sum += c\n }\n\n // 分配到输出\n for (let i = 0; i < count; i++) {\n const idx = indicesIn[i]\n const key = (keys[idx] >> shift) & MASK\n indicesOut[counts[key]++] = idx\n }\n}\n","/**\n * Packed Data 工具函数\n *\n * Packed 格式:[pos3, color4, cov6] x N 个点\n * 每个点 13 个 float,共 52 bytes\n */\n\nconst FLOATS_PER_POINT = 13\n\n// 复用缓冲区,避免每帧分配\nlet reorderedBuffer: Float32Array | null = null\n\n/**\n * 重新排序 packed 数据(复用缓冲区)\n * @param packedData 原始数据 [pos3, color4, cov6] x N\n * @param sortOrder 排序索引数组\n * @returns 重排序后的数据(复用的缓冲区引用)\n */\nexport function reorderPackedData(\n packedData: Float32Array,\n sortOrder: Uint32Array,\n): Float32Array {\n const pointCount = sortOrder.length\n const requiredLength = pointCount * FLOATS_PER_POINT\n\n // 仅在尺寸变化时重新分配\n if (!reorderedBuffer || reorderedBuffer.length !== requiredLength) {\n reorderedBuffer = new Float32Array(requiredLength)\n }\n\n // 性能优化:使用 TypedArray.set() 批量复制,避免内层循环\n // subarray 创建视图(零开销),set() 批量复制数据\n for (let i = 0; i < pointCount; i++) {\n const srcIdx = sortOrder[i]\n const srcOffset = srcIdx * FLOATS_PER_POINT\n const dstOffset = i * FLOATS_PER_POINT\n\n // 批量复制 13 个 float(52 字节),比逐元素复制快\n reorderedBuffer.set(\n packedData.subarray(srcOffset, srcOffset + FLOATS_PER_POINT),\n dstOffset\n )\n }\n\n return reorderedBuffer\n}\n","export default \"#version 300 es\\nprecision highp float;\\n\\nin vec2 v_relativePosition;\\nin vec4 v_color;\\n\\nout vec4 fragColor;\\n\\nconst float BOUNDS_RADIUS = 3.0;\\nconst float BOUNDS_RADIUS_SQUARED = BOUNDS_RADIUS * BOUNDS_RADIUS;\\n\\nfloat splatFragmentAlpha(vec2 relativePosition, float splatAlpha) {\\n // ✅ 修复:完全匹配MetalSplatter的计算方式\\n float negativeMagnitudeSquared = -dot(relativePosition, relativePosition);\\n\\n // 边界检查:超出椭圆边界的点被剔除\\n if (negativeMagnitudeSquared < -BOUNDS_RADIUS_SQUARED) {\\n return 0.0;\\n }\\n\\n // ✅ 修复:高斯衰减,使用MetalSplatter的公式 exp(0.5 * negative)\\n return exp(0.5 * negativeMagnitudeSquared) * splatAlpha;\\n}\\n\\nvoid main() {\\n float alpha = splatFragmentAlpha(v_relativePosition, v_color.a);\\n\\n // 预乘 alpha 输出(匹配 premultipliedAlpha: true)\\n // 颜色值需要乘以 alpha,这样 WebGL 才能正确混合\\n fragColor = vec4(v_color.rgb * alpha, alpha);\\n}\"","export default \"#version 300 es\\nprecision highp float;\\n\\n// 基础四边形顶点属性(共享4个顶点)\\nlayout(location = 0) in vec2 a_quadVertex; // (-1,-1), (-1,1), (1,-1), (1,1)\\n\\n// 实例化属性(每个splat实例)\\nlayout(location = 1) in vec3 a_position; // splat中心位置\\nlayout(location = 2) in vec4 a_color; // RGBA颜色\\nlayout(location = 3) in vec3 a_covA; // 协方差矩阵上三角\\nlayout(location = 4) in vec3 a_covB; // 协方差矩阵下三角\\n\\n// Uniform变量\\nuniform mat4 u_viewMatrix;\\nuniform mat4 u_projectionMatrix;\\nuniform vec2 u_screenSize;\\nuniform int u_enableFrustumCulling;\\n\\n// 输出到片段着色器\\nout vec2 v_relativePosition;\\nout vec4 v_color;\\n\\n// 常量定义\\nconst float BOUNDS_RADIUS = 3.0;\\n\\n/**\\n * 计算2D协方差矩阵(复刻Metal版本)\\n */\\nvec3 calcCovariance2D(vec3 viewPos, vec3 cov3Da, vec3 cov3Db, mat4 viewMatrix, mat4 projectionMatrix, vec2 screenSize) {\\n float invViewPosZ = 1.0 / viewPos.z;\\n float invViewPosZSquared = invViewPosZ * invViewPosZ;\\n\\n // FOV限制\\n float tanHalfFovX = 1.0 / projectionMatrix[0][0];\\n float tanHalfFovY = 1.0 / projectionMatrix[1][1];\\n float limX = 1.3 * tanHalfFovX;\\n float limY = 1.3 * tanHalfFovY;\\n\\n viewPos.x = clamp(viewPos.x * invViewPosZ, -limX, limX) * viewPos.z;\\n viewPos.y = clamp(viewPos.y * invViewPosZ, -limY, limY) * viewPos.z;\\n\\n // 焦距计算\\n float focalX = screenSize.x * projectionMatrix[0][0] / 2.0;\\n float focalY = screenSize.y * projectionMatrix[1][1] / 2.0;\\n\\n // 雅可比矩阵 J\\n mat3 J = mat3(\\n focalX * invViewPosZ, 0.0, 0.0,\\n 0.0, focalY * invViewPosZ, 0.0,\\n -(focalX * viewPos.x) * invViewPosZSquared, -(focalY * viewPos.y) * invViewPosZSquared, 0.0\\n );\\n\\n // 视图变换矩阵 W (仅旋转部分) - 固定使用转置(经验最清晰)\\n mat3 W = transpose(mat3(viewMatrix[0].xyz, viewMatrix[1].xyz, viewMatrix[2].xyz));\\n\\n // 投影变换 T = J * W\\n mat3 T = J * W;\\n\\n // 3D协方差矩阵 Vrk\\n mat3 Vrk = mat3(\\n cov3Da.x, cov3Da.y, cov3Da.z,\\n cov3Da.y, cov3Db.x, cov3Db.y,\\n cov3Da.z, cov3Db.y, cov3Db.z\\n );\\n\\n // 2D协方差矩阵\\n mat3 cov = T * Vrk * transpose(T);\\n\\n // 低通滤波器\\n cov[0][0] += 0.3;\\n cov[1][1] += 0.3;\\n\\n return vec3(cov[0][0], cov[0][1], cov[1][1]);\\n}\\n\\n/**\\n * 分解协方差矩阵\\n */\\nvoid decomposeCovariance(vec3 cov2D, out vec2 v1, out vec2 v2) {\\n float a = cov2D.x;\\n float b = cov2D.y;\\n float d = cov2D.z;\\n\\n float det = a * d - b * b;\\n float trace = a + d;\\n\\n float mean = 0.5 * trace;\\n float dist = max(0.1, sqrt(mean * mean - det));\\n\\n // 特征值\\n float lambda1 = mean + dist;\\n float lambda2 = mean - dist;\\n\\n // 确保特征值为正\\n lambda1 = max(lambda1, 0.01);\\n lambda2 = max(lambda2, 0.01);\\n\\n // 特征向量 - 完全复刻MetalSplatter的算法\\n vec2 eigenvector1;\\n if (abs(b) < 1e-6) {\\n eigenvector1 = (a > d) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);\\n } else {\\n // ✅ 修复:使用MetalSplatter的公式 (b, d - lambda2) 而不是 (b, lambda1 - a)\\n eigenvector1 = normalize(vec2(b, d - lambda2));\\n }\\n\\n // ✅ 修复:正交特征向量,使用MetalSplatter的方向 (y, -x) 而不是 (-y, x)\\n vec2 eigenvector2 = vec2(eigenvector1.y, -eigenvector1.x);\\n\\n v1 = eigenvector1 * sqrt(lambda1);\\n v2 = eigenvector2 * sqrt(lambda2);\\n}\\n\\nvoid main() {\\n // 直接使用原始位置数据,不进行硬编码缩放\\n vec3 scaledPosition = a_position;\\n\\n // 转换到视图空间\\n vec4 viewPosition4 = u_viewMatrix * vec4(scaledPosition, 1.0);\\n vec3 viewPosition3 = viewPosition4.xyz;\\n\\n // 计算2D协方差矩阵\\n vec3 cov2D = calcCovariance2D(viewPosition3, a_covA, a_covB, u_viewMatrix, u_projectionMatrix, u_screenSize);\\n\\n // 分解协方差矩阵\\n vec2 axis1, axis2;\\n decomposeCovariance(cov2D, axis1, axis2);\\n\\n // 投影到屏幕空间\\n vec4 projectedCenter = u_projectionMatrix * viewPosition4;\\n\\n // 视锥体剔除(对齐MetalSplatter边界,可调试禁用)\\n if (u_enableFrustumCulling == 1) {\\n float bounds = 1.2 * projectedCenter.w;\\n if (projectedCenter.z < 0.0 ||\\n projectedCenter.z > projectedCenter.w ||\\n projectedCenter.x < -bounds ||\\n projectedCenter.x > bounds ||\\n projectedCenter.y < -bounds ||\\n projectedCenter.y > bounds) {\\n // 剔除到屏幕外\\n gl_Position = vec4(1.0, 1.0, 0.0, 1.0);\\n return;\\n }\\n }\\n\\n // 使用实例化的四边形顶点\\n vec2 relativeCoord = a_quadVertex;\\n\\n // 计算椭圆变换后的相对位置(像素单位)\\n vec2 ellipseRelativePos = relativeCoord.x * axis1 + relativeCoord.y * axis2;\\n\\n // 计算屏幕空间偏移\\n vec2 screenSizeFloat = u_screenSize;\\n vec2 projectedScreenDelta = ellipseRelativePos * 2.0 * BOUNDS_RADIUS / screenSizeFloat;\\n\\n // 最终顶点位置\\n gl_Position = vec4(\\n projectedCenter.x + projectedScreenDelta.x * projectedCenter.w,\\n projectedCenter.y + projectedScreenDelta.y * projectedCenter.w,\\n projectedCenter.z,\\n projectedCenter.w\\n );\\n\\n // 传递标准化坐标给片段着色器(椭圆内[-1,1]范围)\\n v_relativePosition = relativeCoord * BOUNDS_RADIUS;\\n v_color = a_color;\\n}\"","/**\n * WebGL 3DGS 渲染器\n */\n\nimport type { I3DGSRenderer } from '../renderer'\n\nimport { logger } from '../../utils/logger'\nimport fragmentShaderSource from './fragment.glsl?raw'\nimport vertexShaderSource from './vertex.glsl?raw'\n\nexport class WebGLRenderer implements I3DGSRenderer {\n private canvas: HTMLCanvasElement\n private backgroundColor: [number, number, number, number]\n private gl: WebGL2RenderingContext | null\n private shaderProgram: WebGLProgram | null\n private uniformLocations: Record<string, WebGLUniformLocation | null>\n private attributeLocations: Record<string, number>\n\n private splatBuffer: WebGLBuffer | null\n private quadVertexBuffer: WebGLBuffer | null\n private vertexArray: WebGLVertexArrayObject | null\n\n private splatCount: number\n private isInitialized: boolean\n private splatBufferSize: number // 跟踪当前 buffer 大小\n\n constructor(canvas: HTMLCanvasElement, backgroundColor?: [number, number, number, number]) {\n this.canvas = canvas\n this.backgroundColor = backgroundColor || [0, 0, 0, 0] // 默认透明背景\n\n // WebGL 上下文和程序\n this.gl = null\n this.shaderProgram = null\n this.uniformLocations = {}\n this.attributeLocations = {}\n\n // 缓冲区\n this.splatBuffer = null\n this.quadVertexBuffer = null\n this.vertexArray = null\n\n // 渲染状态\n this.splatCount = 0\n this.isInitialized = false\n this.splatBufferSize = 0\n }\n\n /**\n * 初始化 WebGL 渲染器\n */\n async initialize(): Promise<void> {\n try {\n // 创建 WebGL2 上下文\n this.gl = this.canvas.getContext('webgl2', {\n antialias: false,\n alpha: true, // 启用透明度,让 CSS 背景透出\n premultipliedAlpha: true,\n powerPreference: 'high-performance',\n preserveDrawingBuffer: false,\n })\n\n if (!this.gl) {\n throw new Error('WebGL2 not supported')\n }\n\n const gl = this.gl\n\n // 创建着色器程序\n this.shaderProgram = this.createShaderProgram(gl)\n\n // 获取 uniform 和 attribute 位置\n this.setupShaderLocations()\n\n // 设置 WebGL 状态\n this.setupWebGLState()\n\n // 创建缓冲区\n this.createBuffers()\n\n this.isInitialized = true\n }\n catch (error) {\n logger.error(`WebGLRenderer initialize failed: ${error instanceof Error ? error.message : String(error)}`)\n throw error\n }\n }\n\n /**\n * 设置着色器位置\n */\n private setupShaderLocations() {\n const gl = this.gl\n if (!gl)\n throw new Error('WebGL context not initialized')\n const program = this.shaderProgram\n if (!program)\n throw new Error('Shader program not initialized')\n\n this.uniformLocations = {\n viewMatrix: gl.getUniformLocation(program, 'u_viewMatrix'),\n projectionMatrix: gl.getUniformLocation(program, 'u_projectionMatrix'),\n screenSize: gl.getUniformLocation(program, 'u_screenSize'),\n enableFrustumCulling: gl.getUniformLocation(program, 'u_enableFrustumCulling'),\n }\n\n this.attributeLocations = {\n quadVertex: 0, // a_quadVertex (共享四边形顶点)\n position: 1, // a_position (实例化)\n color: 2, // a_color (实例化)\n covA: 3, // a_covA (实例化)\n covB: 4, // a_covB (实例化)\n }\n }\n\n /**\n * 设置 WebGL 渲染状态\n */\n private setupWebGLState() {\n const gl = this.gl\n if (!gl)\n throw new Error('WebGL context not initialized')\n\n gl.disable(gl.DEPTH_TEST)\n gl.depthMask(true)\n gl.enable(gl.BLEND)\n // 预乘 alpha 混合(匹配 premultipliedAlpha: true)\n gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA)\n // 透明背景,让 CSS 背景透出\n gl.clearColor(0.0, 0.0, 0.0, 0.0)\n }\n\n /**\n * 创建渲染缓冲区\n */\n private createBuffers() {\n const gl = this.gl\n if (!gl)\n throw new Error('WebGL context not initialized')\n\n // 创建实例化渲染 VAO 和缓冲区\n this.vertexArray = gl.createVertexArray()\n this.splatBuffer = gl.createBuffer()\n this.createQuadVertexBuffer()\n }\n\n /**\n * 创建四边形顶点缓冲区(实例化渲染用)\n */\n private createQuadVertexBuffer() {\n const gl = this.gl\n if (!gl)\n throw new Error('WebGL context not initialized')\n\n // 四边形顶点(2D 坐标,将被实例化)\n const quadVertices = new Float32Array([\n -1.0,\n -1.0, // 左下\n -1.0,\n 1.0, // 左上\n 1.0,\n -1.0, // 右下\n 1.0,\n 1.0, // 右上\n ])\n\n this.quadVertexBuffer = gl.createBuffer()\n gl.bindBuffer(gl.ARRAY_BUFFER, this.quadVertexBuffer)\n gl.bufferData(gl.ARRAY_BUFFER, quadVertices, gl.STATIC_DRAW)\n }\n\n /**\n * 从已打包数据加载(零拷贝,GPU 优化路径)\n * 🚀 性能优化版本:直接使用 WASM 输出的 packed 数据\n * 🚀 Buffer 复用:避免每帧重新分配,使用 bufferSubData 更新\n * @param packedData Float32Array [pos3, color4, cov6] x N 个点\n * @param pointCount 点数\n * @param _sortOrder WebGL 忽略此参数(已在 RenderSystem 中重排序)\n */\n loadSplatsFromPackedData(packedData: Float32Array, pointCount: number, _sortOrder?: Uint32Array) {\n if (!this.isInitialized) {\n throw new Error('Renderer not initialized')\n }\n\n this.splatCount = pointCount\n\n // 直接上传\n this.uploadToGPU(packedData)\n }\n\n /**\n * 上传数据到 GPU\n */\n private uploadToGPU(packedData: Float32Array) {\n const gl = this.gl\n if (!gl)\n throw new Error('WebGL context not initialized')\n\n gl.bindBuffer(gl.ARRAY_BUFFER, this.splatBuffer)\n\n // 只在 buffer 不存在或大小变化时重新分配\n if (this.splatBufferSize !== packedData.byteLength) {\n gl.bufferData(gl.ARRAY_BUFFER, packedData, gl.DYNAMIC_DRAW)\n this.splatBufferSize = packedData.byteLength\n }\n else {\n // 使用 bufferSubData 更新数据(无需重新分配)\n gl.bufferSubData(gl.ARRAY_BUFFER, 0, packedData)\n }\n }\n\n /**\n * 设置实例化渲染顶点属性\n */\n private setupVertexAttributes() {\n const gl = this.gl\n if (!gl)\n throw new Error('WebGL context not initialized')\n\n // 绑定 VAO\n gl.bindVertexArray(this.vertexArray)\n\n // 设置共享四边形顶点属性\n gl.bindBuffer(gl.ARRAY_BUFFER, this.quadVertexBuffer)\n gl.enableVertexAttribArray(this.attributeLocations.quadVertex)\n gl.vertexAttribPointer(\n this.attributeLocations.quadVertex,\n 2,\n gl.FLOAT,\n false,\n 0,\n 0,\n )\n\n // 设置实例化 splat 属性\n gl.bindBuffer(gl.ARRAY_BUFFER, this.splatBuffer)\n\n const floatsPerSplat = 13\n const bytesPerFloat = 4\n const strideBytes = floatsPerSplat * bytesPerFloat\n\n // Position 属性 (location 1)\n gl.enableVertexAttribArray(this.attributeLocations.position)\n gl.vertexAttribPointer(\n this.attributeLocations.position,\n 3,\n gl.FLOAT,\n false,\n strideBytes,\n 0,\n )\n gl.vertexAttribDivisor(this.attributeLocations.position, 1)\n\n // Color 属性 (location 2)\n gl.enableVertexAttribArray(this.attributeLocations.color)\n gl.vertexAttribPointer(\n this.attributeLocations.color,\n 4,\n gl.FLOAT,\n false,\n strideBytes,\n 3 * bytesPerFloat,\n )\n gl.vertexAttribDivisor(this.attributeLocations.color, 1)\n\n // CovA 属性 (location 3)\n gl.enableVertexAttribArray(this.attributeLocations.covA)\n gl.vertexAttribPointer(\n this.attributeLocations.covA,\n 3,\n gl.FLOAT,\n false,\n strideBytes,\n 7 * bytesPerFloat,\n )\n gl.vertexAttribDivisor(this.attributeLocations.covA, 1)\n\n // CovB 属性 (location 4)\n gl.enableVertexAttribArray(this.attributeLocations.covB)\n gl.vertexAttribPointer(\n this.attributeLocations.covB,\n 3,\n gl.FLOAT,\n false,\n strideBytes,\n 10 * bytesPerFloat,\n )\n gl.vertexAttribDivisor(this.attributeLocations.covB, 1)\n }\n\n /**\n * 渲染一帧\n */\n render(\n viewMatrix: Float32Array,\n projectionMatrix: Float32Array,\n screenSize: [number, number],\n ) {\n if (!this.isInitialized || this.splatCount === 0) {\n return\n }\n\n const gl = this.gl\n if (!gl)\n throw new Error('WebGL context not initialized')\n\n gl.viewport(0, 0, screenSize[0], screenSize[1])\n gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)\n\n // 使用实例化着色器\n gl.useProgram(this.shaderProgram)\n\n // 设置 uniform 变量\n gl.uniformMatrix4fv(this.uniformLocations.viewMatrix, false, viewMatrix)\n gl.uniformMatrix4fv(this.uniformLocations.projectionMatrix, false, projectionMatrix)\n gl.uniform2fv(this.uniformLocations.screenSize, screenSize)\n gl.uniform1i(this.uniformLocations.enableFrustumCulling, 1)\n\n // 设置顶点属性\n this.setupVertexAttributes()\n\n // 实例化绘制\n gl.drawArraysInstanced(gl.TRIANGLE_STRIP, 0, 4, this.splatCount)\n }\n\n /**\n * 创建着色器程序\n */\n private createShaderProgram(gl: WebGL2RenderingContext): WebGLProgram {\n // 编译顶点着色器\n const vertexShader = gl.createShader(gl.VERTEX_SHADER)\n if (!vertexShader)\n throw new Error('Failed to create vertex shader')\n\n gl.shaderSource(vertexShader, vertexShaderSource)\n gl.compileShader(vertexShader)\n\n if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {\n const info = gl.getShaderInfoLog(vertexShader)\n gl.deleteShader(vertexShader)\n throw new Error(`Vertex shader compilation failed: ${info}`)\n }\n\n // 编译片段着色器\n const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER)\n if (!fragmentShader) {\n gl.deleteShader(vertexShader)\n throw new Error('Failed to create fragment shader')\n }\n\n gl.shaderSource(fragmentShader, fragmentShaderSource)\n gl.compileShader(fragmentShader)\n\n if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {\n const info = gl.getShaderInfoLog(fragmentShader)\n gl.deleteShader(vertexShader)\n gl.deleteShader(fragmentShader)\n throw new Error(`Fragment shader compilation failed: ${info}`)\n }\n\n // 链接着色器程序\n const program = gl.createProgram()\n if (!program) {\n gl.deleteShader(vertexShader)\n gl.deleteShader(fragmentShader)\n throw new Error('Failed to create shader program')\n }\n\n gl.attachShader(program, vertexShader)\n gl.attachShader(program, fragmentShader)\n gl.linkProgram(program)\n\n if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n const info = gl.getProgramInfoLog(program)\n gl.deleteShader(vertexShader)\n gl.deleteShader(fragmentShader)\n gl.deleteProgram(program)\n throw new Error(`Shader program linking failed: ${info}`)\n }\n\n // 清理着色器对象\n gl.deleteShader(vertexShader)\n gl.deleteShader(fragmentShader)\n\n return program\n }\n\n /**\n * 清理资源\n */\n dispose() {\n if (!this.gl)\n return\n\n const gl = this.gl\n\n // 删除缓冲区\n if (this.splatBuffer)\n gl.deleteBuffer(this.splatBuffer)\n if (this.quadVertexBuffer)\n gl.deleteBuffer(this.quadVertexBuffer)\n if (this.vertexArray)\n gl.deleteVertexArray(this.vertexArray)\n\n // 删除着色器程序\n if (this.shaderProgram)\n gl.deleteProgram(this.shaderProgram)\n\n // Optionally lose the context to aggressively free VRAM\n try {\n const lose = gl.getExtension('WEBGL_lose_context') as { loseContext?: () => void } | null\n if (lose && typeof lose.loseContext === 'function') {\n lose.loseContext()\n }\n }\n catch {\n // best-effort only\n }\n\n // 清理引用\n this.gl = null\n this.isInitialized = false\n }\n}\n","export default \"/**\\n * WebGPU 3DGS 渲染着色器\\n *\\n * 实例化渲染:每个 splat 绘制一个四边形\\n * 对应 WebGL 版本的 GLSL 着色器\\n */\\n\\n// ============ Uniform Bindings ============\\n\\nstruct Uniforms {\\n viewMatrix: mat4x4f,\\n projectionMatrix: mat4x4f,\\n screenSize: vec2f,\\n enableFrustumCulling: u32,\\n}\\n\\n@group(0) @binding(0) var<uniform> uniforms: Uniforms;\\n\\n// ============ Storage Buffer Bindings (间接索引渲染) ============\\n\\n@group(1) @binding(0) var<storage, read> sortIndices: array<u32>;\\n@group(1) @binding(1) var<storage, read> splatData: array<f32>;\\n\\n// ============ Vertex Shader ============\\n\\nstruct VertexInput {\\n // 共享四边形顶点 (per-vertex)\\n @location(0) quadVertex: vec2f,\\n}\\n\\nstruct VertexOutput {\\n @builtin(position) position: vec4f,\\n @location(0) relativePosition: vec2f,\\n @location(1) color: vec4f,\\n}\\n\\n// 常量定义\\nconst BOUNDS_RADIUS: f32 = 3.0;\\n\\n/**\\n * 计算2D协方差矩阵(复刻 WebGL 版本)\\n */\\nfn calcCovariance2D(\\n viewPos: vec3f,\\n cov3Da: vec3f,\\n cov3Db: vec3f,\\n viewMatrix: mat4x4f,\\n projectionMatrix: mat4x4f,\\n screenSize: vec2f\\n) -> vec3f {\\n let invViewPosZ = 1.0 / viewPos.z;\\n let invViewPosZSquared = invViewPosZ * invViewPosZ;\\n\\n // FOV 限制\\n let tanHalfFovX = 1.0 / projectionMatrix[0][0];\\n let tanHalfFovY = 1.0 / projectionMatrix[1][1];\\n let limX = 1.3 * tanHalfFovX;\\n let limY = 1.3 * tanHalfFovY;\\n\\n var clampedViewPos = viewPos;\\n clampedViewPos.x = clamp(viewPos.x * invViewPosZ, -limX, limX) * viewPos.z;\\n clampedViewPos.y = clamp(viewPos.y * invViewPosZ, -limY, limY) * viewPos.z;\\n\\n // 焦距计算\\n let focalX = screenSize.x * projectionMatrix[0][0] / 2.0;\\n let focalY = screenSize.y * projectionMatrix[1][1] / 2.0;\\n\\n // 雅可比矩阵 J\\n let J = mat3x3f(\\n focalX * invViewPosZ, 0.0, -(focalX * clampedViewPos.x) * invViewPosZSquared,\\n 0.0, focalY * invViewPosZ, -(focalY * clampedViewPos.y) * invViewPosZSquared,\\n 0.0, 0.0, 0.0\\n );\\n\\n // 视图变换矩阵 W (仅旋转部分) - 转置\\n let W = transpose(mat3x3f(\\n viewMatrix[0].xyz,\\n viewMatrix[1].xyz,\\n viewMatrix[2].xyz\\n ));\\n\\n // 投影变换 T = J * W\\n let T = J * W;\\n\\n // 3D 协方差矩阵 Vrk(对称矩阵)\\n let Vrk = mat3x3f(\\n cov3Da.x, cov3Da.y, cov3Da.z,\\n cov3Da.y, cov3Db.x, cov3Db.y,\\n cov3Da.z, cov3Db.y, cov3Db.z\\n );\\n\\n // 2D 协方差矩阵: cov = T * Vrk * T^T\\n let cov = T * Vrk * transpose(T);\\n\\n // 低通滤波器\\n var result = vec3f(cov[0][0], cov[0][1], cov[1][1]);\\n result.x += 0.3;\\n result.z += 0.3;\\n\\n return result;\\n}\\n\\n/**\\n * 分解协方差矩阵\\n */\\nfn decomposeCovariance(cov2D: vec3f) -> array<vec2f, 2> {\\n let a = cov2D.x;\\n let b = cov2D.y;\\n let d = cov2D.z;\\n\\n let det = a * d - b * b;\\n let trace = a + d;\\n\\n let mean = 0.5 * trace;\\n let dist = max(0.1, sqrt(mean * mean - det));\\n\\n // 特征值\\n var lambda1 = mean + dist;\\n var lambda2 = mean - dist;\\n\\n // 确保特征值为正\\n lambda1 = max(lambda1, 0.01);\\n lambda2 = max(lambda2, 0.01);\\n\\n // 特征向量(复刻 WebGL MetalSplatter 算法)\\n var eigenvector1: vec2f;\\n if (abs(b) < 1e-6) {\\n eigenvector1 = select(vec2f(0.0, 1.0), vec2f(1.0, 0.0), a > d);\\n } else {\\n eigenvector1 = normalize(vec2f(b, d - lambda2));\\n }\\n\\n // 正交特征向量\\n let eigenvector2 = vec2f(eigenvector1.y, -eigenvector1.x);\\n\\n let v1 = eigenvector1 * sqrt(lambda1);\\n let v2 = eigenvector2 * sqrt(lambda2);\\n\\n return array<vec2f, 2>(v1, v2);\\n}\\n\\n@vertex\\nfn vertexMain(\\n input: VertexInput,\\n @builtin(instance_index) instanceIndex: u32\\n) -> VertexOutput {\\n var output: VertexOutput;\\n\\n // 🚀 间接索引:通过排序索引读取实际数据\\n let sortedIdx = sortIndices[instanceIndex];\\n let dataOffset = sortedIdx * 13u;\\n\\n // 从 storage buffer 读取 splat 数据\\n let position = vec3f(\\n splatData[dataOffset + 0u],\\n splatData[dataOffset + 1u],\\n splatData[dataOffset + 2u]\\n );\\n let color = vec4f(\\n splatData[dataOffset + 3u],\\n splatData[dataOffset + 4u],\\n splatData[dataOffset + 5u],\\n splatData[dataOffset + 6u]\\n );\\n let covA = vec3f(\\n splatData[dataOffset + 7u],\\n splatData[dataOffset + 8u],\\n splatData[dataOffset + 9u]\\n );\\n let covB = vec3f(\\n splatData[dataOffset + 10u],\\n splatData[dataOffset + 11u],\\n splatData[dataOffset + 12u]\\n );\\n\\n // 转换到视图空间\\n let viewPosition4 = uniforms.viewMatrix * vec4f(position, 1.0);\\n let viewPosition3 = viewPosition4.xyz;\\n\\n // 计算 2D 协方差矩阵\\n let cov2D = calcCovariance2D(\\n viewPosition3,\\n covA,\\n covB,\\n uniforms.viewMatrix,\\n uniforms.projectionMatrix,\\n uniforms.screenSize\\n );\\n\\n // 分解协方差矩阵\\n let axes = decomposeCovariance(cov2D);\\n let axis1 = axes[0];\\n let axis2 = axes[1];\\n\\n // 投影到屏幕空间\\n let projectedCenter = uniforms.projectionMatrix * viewPosition4;\\n\\n // 视锥体剔除\\n if (uniforms.enableFrustumCulling == 1u) {\\n let bounds = 1.2 * projectedCenter.w;\\n if (projectedCenter.z < 0.0 ||\\n projectedCenter.z > projectedCenter.w ||\\n projectedCenter.x < -bounds ||\\n projectedCenter.x > bounds ||\\n projectedCenter.y < -bounds ||\\n projectedCenter.y > bounds) {\\n // 剔除到屏幕外\\n output.position = vec4f(2.0, 2.0, 0.0, 1.0);\\n output.relativePosition = vec2f(0.0);\\n output.color = vec4f(0.0);\\n return output;\\n }\\n }\\n\\n // 使用实例化的四边形顶点\\n let relativeCoord = input.quadVertex;\\n\\n // 计算椭圆变换后的相对位置(像素单位)\\n let ellipseRelativePos = relativeCoord.x * axis1 + relativeCoord.y * axis2;\\n\\n // 计算屏幕空间偏移\\n let projectedScreenDelta = ellipseRelativePos * 2.0 * BOUNDS_RADIUS / uniforms.screenSize;\\n\\n // 最终顶点位置\\n output.position = vec4f(\\n projectedCenter.x + projectedScreenDelta.x * projectedCenter.w,\\n projectedCenter.y + projectedScreenDelta.y * projectedCenter.w,\\n projectedCenter.z,\\n projectedCenter.w\\n );\\n\\n // 传递给 fragment shader\\n output.relativePosition = relativeCoord * BOUNDS_RADIUS;\\n output.color = color;\\n\\n return output;\\n}\\n\\n// ============ Fragment Shader ============\\n\\nconst BOUNDS_RADIUS_SQUARED: f32 = BOUNDS_RADIUS * BOUNDS_RADIUS;\\n\\nfn splatFragmentAlpha(relativePosition: vec2f, splatAlpha: f32) -> f32 {\\n // 复刻 WebGL MetalSplatter 计算方式\\n let negativeMagnitudeSquared = -dot(relativePosition, relativePosition);\\n\\n // 边界检查:超出椭圆边界的点被剔除\\n if (negativeMagnitudeSquared < -BOUNDS_RADIUS_SQUARED) {\\n return 0.0;\\n }\\n\\n // 高斯衰减\\n return exp(0.5 * negativeMagnitudeSquared) * splatAlpha;\\n}\\n\\n@fragment\\nfn fragmentMain(input: VertexOutput) -> @location(0) vec4f {\\n let alpha = splatFragmentAlpha(input.relativePosition, input.color.a);\\n\\n // 预乘 alpha 输出(匹配 alphaMode: 'premultiplied')\\n return vec4f(input.color.rgb * alpha, alpha);\\n}\\n\"","/**\n * WebGPU 3DGS 渲染器\n */\n\nimport type { I3DGSRenderer } from '../renderer'\n\nimport renderShaderCode from './render.wgsl?raw'\n\nexport class WebGPURenderer implements I3DGSRenderer {\n private canvas: HTMLCanvasElement\n private backgroundColor: [number, number, number, number]\n private device: GPUDevice | null = null\n private context: GPUCanvasContext | null = null\n private renderPipeline: GPURenderPipeline | null = null\n private quadVertexBuffer: GPUBuffer | null = null\n private uniformBuffer: GPUBuffer | null = null\n private uniformBindGroup: GPUBindGroup | null = null\n\n // 🚀 间接索引渲染 buffers\n private sortIndexBuffer: GPUBuffer | null = null\n private splatDataBuffer: GPUBuffer | null = null\n private storageBindGroup: GPUBindGroup | null = null\n private lastSortOrder: Uint32Array | null = null // 缓存上次的排序索引\n private bindGroupNeedsUpdate = false // 标记 bind group 是否需要更新\n\n private splatCount = 0\n private presentationFormat: GPUTextureFormat = 'bgra8unorm'\n\n constructor(canvas: HTMLCanvasElement, backgroundColor?: [number, number, number, number]) {\n this.canvas = canvas\n this.backgroundColor = backgroundColor || [0, 0, 0, 0] // 默认透明背景\n }\n\n /**\n * 初始化 WebGPU 渲染器\n */\n async initialize(): Promise<void> {\n // 1. 获取 GPU adapter\n const adapter = await navigator.gpu.requestAdapter({\n powerPreference: 'high-performance',\n })\n if (!adapter) {\n throw new Error('WebGPU: No GPU adapter found')\n }\n\n // 2. 请求 device\n this.device = await adapter.requestDevice()\n\n // 3. 配置 canvas context\n this.context = this.canvas.getContext('webgpu')\n if (!this.context) {\n throw new Error('WebGPU: Failed to get canvas context')\n }\n\n this.presentationFormat = navigator.gpu.getPreferredCanvasFormat()\n this.context.configure({\n device: this.device,\n format: this.presentationFormat,\n alphaMode: 'premultiplied',\n })\n\n // 4. 创建 uniform buffer\n this.createUniformBuffer()\n\n // 5. 创建 quad vertex buffer(共享四边形)\n this.createQuadVertexBuffer()\n\n // 6. 创建 render pipeline\n await this.createRenderPipeline()\n }\n\n /**\n * 创建 Uniform Buffer\n */\n private createUniformBuffer(): void {\n if (!this.device)\n return\n\n // Uniform 结构:\n // - viewMatrix: mat4x4f (64 bytes)\n // - projectionMatrix: mat4x4f (64 bytes)\n // - screenSize: vec2f (8 bytes) + padding 8 bytes\n // - enableFrustumCulling: u32 (4 bytes) + padding 12 bytes\n // Total: 160 bytes\n\n const uniformBufferSize = 160\n\n this.uniformBuffer = this.device.createBuffer({\n label: 'Uniform Buffer',\n size: uniformBufferSize,\n usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,\n })\n }\n\n /**\n * 创建四边形顶点缓冲区(实例化渲染用)\n */\n private createQuadVertexBuffer(): void {\n if (!this.device)\n return\n\n const quadVertices = new Float32Array([\n -1.0,\n -1.0, // 左下\n -1.0,\n 1.0, // 左上\n 1.0,\n -1.0, // 右下\n 1.0,\n 1.0, // 右上\n ])\n\n this.quadVertexBuffer = this.device.createBuffer({\n label: 'Quad Vertex Buffer',\n size: quadVertices.byteLength,\n usage: GPUBufferUsage.VERTEX,\n mappedAtCreation: true,\n })\n\n new Float32Array(this.quadVertexBuffer.getMappedRange()).set(quadVertices)\n this.quadVertexBuffer.unmap()\n }\n\n /**\n * 创建 Render Pipeline\n */\n private async createRenderPipeline(): Promise<void> {\n if (!this.device)\n return\n\n // 创建 shader module\n const shaderModule = this.device.createShaderModule({\n label: '3DGS Render Shader',\n code: renderShaderCode,\n })\n\n // Bind Group 0: Uniforms\n const uniformBindGroupLayout = this.device.createBindGroupLayout({\n label: 'Uniform Bind Group Layout',\n entries: [\n {\n binding: 0,\n visibility: GPUShaderStage.VERTEX,\n buffer: { type: 'uniform' },\n },\n ],\n })\n\n // Bind Group 1: Storage Buffers (间接索引)\n const storageBindGroupLayout = this.device.createBindGroupLayout({\n label: 'Storage Bind Group Layout',\n entries: [\n {\n binding: 0, // sortIndices\n visibility: GPUShaderStage.VERTEX,\n buffer: { type: 'read-only-storage' },\n },\n {\n binding: 1, // splatData\n visibility: GPUShaderStage.VERTEX,\n buffer: { type: 'read-only-storage' },\n },\n ],\n })\n\n const pipelineLayout = this.device.createPipelineLayout({\n label: 'Render Pipeline Layout',\n bindGroupLayouts: [uniformBindGroupLayout, storageBindGroupLayout],\n })\n\n // Vertex buffer layouts (只保留 quad vertices)\n const vertexBufferLayouts: GPUVertexBufferLayout[] = [\n // Buffer 0: Quad vertices (per-vertex)\n {\n arrayStride: 8, // 2 floats\n stepMode: 'vertex',\n attributes: [\n {\n shaderLocation: 0, // quadVertex\n offset: 0,\n format: 'float32x2',\n },\n ],\n },\n ]\n\n // Create render pipeline\n this.renderPipeline = this.device.createRenderPipeline({\n label: '3DGS Render Pipeline',\n layout: pipelineLayout,\n vertex: {\n module: shaderModule,\n entryPoint: 'vertexMain',\n buffers: vertexBufferLayouts,\n },\n fragment: {\n module: shaderModule,\n entryPoint: 'fragmentMain',\n targets: [\n {\n format: this.presentationFormat,\n blend: {\n // 预乘 alpha 混合(匹配 alphaMode: 'premultiplied')\n color: {\n srcFactor: 'one',\n dstFactor: 'one-minus-src-alpha',\n operation: 'add',\n },\n alpha: {\n srcFactor: 'one',\n dstFactor: 'one-minus-src-alpha',\n operation: 'add',\n },\n },\n },\n ],\n },\n primitive: {\n topology: 'triangle-strip',\n stripIndexFormat: undefined,\n },\n depthStencil: undefined, // 3DGS 不使用深度测试\n })\n\n // 创建 uniform bind group (group 0)\n this.uniformBindGroup = this.device.createBindGroup({\n label: 'Uniform Bind Group',\n layout: uniformBindGroupLayout,\n entries: [\n {\n binding: 0,\n resource: { buffer: this.uniformBuffer! },\n },\n ],\n })\n\n // storage bind group 将在 loadSplatsFromPackedData 中创建\n }\n\n /**\n * 从已打包数据加载\n * 🚀 间接索引渲染:packedData 是原始数据,sortOrder 是排序索引\n * 🚀 完全消除 CPU 重排序开销\n */\n loadSplatsFromPackedData(\n packedData: Float32Array,\n pointCount: number,\n sortOrder?: Uint32Array,\n ): void {\n if (!this.device)\n throw new Error('Device not initialized')\n\n this.splatCount = pointCount\n\n // 1. 创建或更新 splat data buffer\n if (!this.splatDataBuffer || this.splatDataBuffer.size !== packedData.byteLength) {\n if (this.splatDataBuffer) {\n this.splatDataBuffer.destroy()\n }\n\n this.splatDataBuffer = this.device.createBuffer({\n label: 'Splat Data Buffer',\n size: packedData.byteLength,\n usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST,\n })\n this.bindGroupNeedsUpdate = true // buffer 重建,需要更新 bind group\n }\n\n // 上传原始数据\n this.device.queue.writeBuffer(\n this.splatDataBuffer,\n 0,\n packedData.buffer,\n packedData.byteOffset,\n packedData.byteLength,\n )\n\n // 2. 创建或更新 sort index buffer\n if (sortOrder) {\n const indexBufferSize = sortOrder.byteLength\n\n // 检查是否需要更新索引(避免重复上传相同数据)\n const sortOrderChanged = !this.lastSortOrder || sortOrder !== this.lastSortOrder\n\n if (!this.sortIndexBuffer || this.sortIndexBuffer.size !== indexBufferSize) {\n if (this.sortIndexBuffer) {\n this.sortIndexBuffer.destroy()\n }\n\n this.sortIndexBuffer = this.device.createBuffer({\n label: 'Sort Index Buffer',\n size: indexBufferSize,\n usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST,\n })\n this.bindGroupNeedsUpdate = true // buffer 重建,需要更新 bind group\n }\n\n // 只在排序索引变化时上传\n if (sortOrderChanged) {\n this.device.queue.writeBuffer(\n this.sortIndexBuffer,\n 0,\n sortOrder.buffer,\n sortOrder.byteOffset,\n sortOrder.byteLength,\n )\n this.lastSortOrder = sortOrder\n }\n\n // 3. 创建或更新 storage bind group (group 1)\n if (this.bindGroupNeedsUpdate && this.renderPipeline && this.sortIndexBuffer && this.splatDataBuffer) {\n const storageBindGroupLayout = this.renderPipeline.getBindGroupLayout(1)\n\n this.storageBindGroup = this.device.createBindGroup({\n label: 'Storage Bind Group',\n layout: storageBindGroupLayout,\n entries: [\n {\n binding: 0,\n resource: { buffer: this.sortIndexBuffer },\n },\n {\n binding: 1,\n resource: { buffer: this.splatDataBuffer },\n },\n ],\n })\n this.bindGroupNeedsUpdate = false\n }\n }\n }\n\n /**\n * 渲染一帧\n */\n render(\n viewMatrix: Float32Array,\n projectionMatrix: Float32Array,\n screenSize: [number, number],\n ): void {\n if (!this.device || !this.context || !this.renderPipeline)\n return\n if (this.splatCount === 0 || !this.storageBindGroup)\n return\n\n // 更新 uniform buffer\n this.updateUniforms(viewMatrix, projectionMatrix, screenSize)\n\n // 获取当前 texture\n const textureView = this.context.getCurrentTexture().createView()\n\n // 创建 command encoder\n const commandEncoder = this.device.createCommandEncoder({\n label: 'Render Command Encoder',\n })\n\n const renderPass = commandEncoder.beginRenderPass({\n label: 'Render Pass',\n colorAttachments: [\n {\n view: textureView,\n // 透明清屏以便 CSS 背景透出\n clearValue: { r: 0.0, g: 0.0, b: 0.0, a: 0.0 },\n loadOp: 'clear',\n storeOp: 'store',\n },\n ],\n })\n\n renderPass.setPipeline(this.renderPipeline)\n renderPass.setBindGroup(0, this.uniformBindGroup!) // Uniforms\n renderPass.setBindGroup(1, this.storageBindGroup!) // Storage buffers (间接索引)\n renderPass.setVertexBuffer(0, this.quadVertexBuffer!) // Quad vertices\n renderPass.draw(4, this.splatCount) // 4 vertices per quad, N instances\n\n renderPass.end()\n\n // Submit\n this.device.queue.submit([commandEncoder.finish()])\n }\n\n /**\n * 更新 Uniform Buffer\n */\n private updateUniforms(\n viewMatrix: Float32Array,\n projectionMatrix: Float32Array,\n screenSize: [number, number],\n ): void {\n if (!this.device || !this.uniformBuffer)\n return\n\n // 准备 uniform 数据(160 bytes)\n const uniformData = new ArrayBuffer(160)\n const float32View = new Float32Array(uniformData)\n const uint32View = new Uint32Array(uniformData)\n\n // viewMatrix (16 floats, 64 bytes)\n float32View.set(viewMatrix, 0)\n\n // projectionMatrix (16 floats, 64 bytes)\n float32View.set(projectionMatrix, 16)\n\n // screenSize (2 floats, 8 bytes) + padding 8 bytes\n float32View[32] = screenSize[0]\n float32View[33] = screenSize[1]\n\n // enableFrustumCulling (u32, 4 bytes) + padding 12 bytes\n uint32View[36] = 1 // true\n\n // 写入 buffer\n this.device.queue.writeBuffer(this.uniformBuffer, 0, uniformData)\n }\n\n /**\n * 清理资源\n */\n dispose(): void {\n this.sortIndexBuffer?.destroy()\n this.splatDataBuffer?.destroy()\n this.quadVertexBuffer?.destroy()\n this.uniformBuffer?.destroy()\n this.device?.destroy()\n\n this.sortIndexBuffer = null\n this.splatDataBuffer = null\n this.quadVertexBuffer = null\n this.uniformBuffer = null\n this.uniformBindGroup = null\n this.storageBindGroup = null\n this.device = null\n this.context = null\n this.renderPipeline = null\n }\n}\n","/**\n * Render System - Unified WebGL/WebGPU rendering management\n *\n * Responsibilities:\n * 1. Automatically select rendering backend (WebGPU preferred, fallback to WebGL)\n * 2. Camera management\n * 3. Matrix calculations\n */\n\nimport type { CameraConfig } from '../types'\nimport type { I3DGSRenderer, RenderBackend } from './renderer'\n\nimport { logger } from '../utils/logger'\nimport { sortSplats } from './sortSplats'\nimport { reorderPackedData } from './webgl/reorderData'\nimport { WebGLRenderer } from './webgl/webglRenderer'\nimport { WebGPURenderer } from './webgpu/webgpuRenderer'\n\n/** @internal */\nexport interface RenderSystemOptions {\n canvas: HTMLCanvasElement\n preferBackend?: RenderBackend\n backgroundColor?: [number, number, number, number]\n camera?: CameraConfig\n}\n\n/**\n * Render System - Internal implementation, not part of public API\n * @internal\n */\nexport class RenderSystem {\n private renderer: I3DGSRenderer | null = null\n private backend: RenderBackend | null = null\n private canvas: HTMLCanvasElement\n private options: RenderSystemOptions\n\n // Camera configuration\n private camera: CameraConfig & {\n up: [number, number, number]\n aspect: number\n }\n\n // Matrix cache (reuse buffers to avoid per-frame allocation)\n private viewMatrix = new Float32Array(16)\n private projectionMatrix = new Float32Array(16)\n \n // Camera forward vector cache (reuse to avoid per-frame allocation)\n private cachedForward: [number, number, number] = [0, 0, 1]\n private forwardCacheValid = false\n \n // Temporary vectors for view matrix calculation (reuse buffers)\n private tempForward: [number, number, number] = [0, 0, 0]\n private tempRight: [number, number, number] = [0, 0, 0]\n private tempUp: [number, number, number] = [0, 0, 0]\n \n // Camera parameter cache for matrix update optimization\n private cachedCameraParams: {\n position: [number, number, number]\n target: [number, number, number]\n up: [number, number, number]\n fov: number\n aspect: number\n near: number\n far: number\n } | null = null\n private matricesCacheValid = false\n\n // 当前数据(GPU 格式:[pos3, color4, cov6] x N)\n private originalPackedData: Float32Array | null = null\n\n // 性能统计\n public renderTime = 0 // 总渲染耗时\n public sortTime = 0 // 排序耗时\n\n constructor(options: RenderSystemOptions) {\n this.options = options\n this.canvas = options.canvas\n\n // Initialize camera (from config or use defaults)\n const cameraConfig = options.camera || {\n position: [-0.02, -0.013, 1.5],\n target: [0, 0, 0],\n fov: 22,\n near: 0.01,\n far: 100,\n }\n\n this.camera = {\n ...cameraConfig,\n up: [0, 1, 0],\n aspect: 1,\n }\n }\n\n /**\n * Initialize render system\n */\n async initialize(): Promise<void> {\n const { preferBackend, backgroundColor = [0, 0, 0, 0] } = this.options // Default transparent background\n\n if (preferBackend !== 'webgl') {\n const webgpuSupported = await this.checkWebGPUSupport()\n if (webgpuSupported) {\n try {\n this.renderer = new WebGPURenderer(this.canvas, backgroundColor)\n await this.renderer.initialize()\n this.backend = 'webgpu'\n logger.log('✅ Using WebGPU renderer')\n this.updateCameraAspect()\n return\n }\n catch (err) {\n logger.warn('⚠️ WebGPU init failed, fallback to WebGL:', err)\n }\n }\n }\n\n this.renderer = new WebGLRenderer(this.canvas, backgroundColor)\n await this.renderer.initialize()\n this.backend = 'webgl'\n logger.log('✅ Using WebGL renderer')\n this.updateCameraAspect()\n }\n\n /**\n * Load packed Splat data (zero-copy, GPU format)\n * Directly receives WASM packed data\n *\n * @param packedData Float32Array [pos3, color4, cov6] x N points\n */\n loadSplatsFromPackedData(packedData: Float32Array): void {\n if (!this.renderer)\n throw new Error('Renderer not initialized')\n\n // Save original data\n this.originalPackedData = packedData\n }\n\n /**\n * 渲染一帧\n */\n renderFrame(): void {\n if (!this.renderer || !this.originalPackedData)\n return\n\n this.updateCameraMatrices()\n\n const pointCount = Math.floor(this.originalPackedData.length / 13)\n\n // 计算排序索引(直接从 packed data 读取 position,无需提取)\n const startSort = performance.now()\n const sortOrder = sortSplats(\n this.originalPackedData,\n this.camera.position,\n this.getCameraForward(),\n )\n const sortTime = performance.now() - startSort\n this.sortTime = sortTime\n\n // 根据后端类型决定如何传递数据\n if (this.backend === 'webgpu') {\n // WebGPU: 传递原始数据 + 排序索引(GPU 间接索引渲染)\n this.renderer.loadSplatsFromPackedData(this.originalPackedData, pointCount, sortOrder)\n }\n else {\n // WebGL: 传递 CPU 重排序后的数据\n const reorderedData = reorderPackedData(this.originalPackedData, sortOrder)\n this.renderer.loadSplatsFromPackedData(reorderedData, pointCount)\n }\n\n // 渲染\n const startRender = performance.now()\n this.renderer.render(\n this.viewMatrix,\n this.projectionMatrix,\n [this.canvas.width, this.canvas.height],\n )\n\n const renderTime = performance.now() - startRender\n this.renderTime = renderTime\n }\n\n /**\n * Update camera parameters\n */\n updateCamera(params: Partial<CameraConfig>): void {\n Object.assign(this.camera, params)\n this.updateCameraAspect()\n }\n\n /**\n * Handle window resize\n */\n handleResize(): void {\n this.updateCameraAspect()\n this.updateCameraMatrices()\n }\n\n /**\n * 获取当前使用的后端\n */\n getBackend(): RenderBackend | null {\n return this.backend\n }\n\n /**\n * Dispose resources\n */\n dispose(): void {\n this.renderer?.dispose()\n this.renderer = null\n \n // Clear original data to avoid memory leaks (may occupy hundreds of MB)\n this.originalPackedData = null\n }\n\n // ========== Private Methods ==========\n\n /**\n * Check WebGPU support\n */\n private async checkWebGPUSupport(): Promise<boolean> {\n if (!navigator.gpu)\n return false\n try {\n const adapter = await navigator.gpu.requestAdapter()\n return adapter !== null\n }\n catch {\n return false\n }\n }\n\n /**\n * Update camera aspect ratio\n */\n private updateCameraAspect(): void {\n this.camera.aspect = this.canvas.width / this.canvas.height\n // Invalidate cache when aspect changes\n this.matricesCacheValid = false\n }\n\n /**\n * Update camera matrices (with caching to avoid unnecessary updates)\n */\n private updateCameraMatrices(): void {\n const { position, target, up, fov, aspect, near, far } = this.camera\n \n // Check if camera parameters have changed\n const paramsChanged = !this.cachedCameraParams ||\n this.cachedCameraParams.position[0] !== position[0] ||\n this.cachedCameraParams.position[1] !== position[1] ||\n this.cachedCameraParams.position[2] !== position[2] ||\n this.cachedCameraParams.target[0] !== target[0] ||\n this.cachedCameraParams.target[1] !== target[1] ||\n this.cachedCameraParams.target[2] !== target[2] ||\n this.cachedCameraParams.up[0] !== up[0] ||\n this.cachedCameraParams.up[1] !== up[1] ||\n this.cachedCameraParams.up[2] !== up[2] ||\n this.cachedCameraParams.fov !== fov ||\n this.cachedCameraParams.aspect !== aspect ||\n this.cachedCameraParams.near !== near ||\n this.cachedCameraParams.far !== far\n \n // Only update if parameters changed\n if (!paramsChanged && this.matricesCacheValid) {\n return\n }\n \n // Update cache\n if (!this.cachedCameraParams) {\n this.cachedCameraParams = {\n position: [position[0], position[1], position[2]],\n target: [target[0], target[1], target[2]],\n up: [up[0], up[1], up[2]],\n fov,\n aspect,\n near,\n far,\n }\n } else {\n this.cachedCameraParams.position[0] = position[0]\n this.cachedCameraParams.position[1] = position[1]\n this.cachedCameraParams.position[2] = position[2]\n this.cachedCameraParams.target[0] = target[0]\n this.cachedCameraParams.target[1] = target[1]\n this.cachedCameraParams.target[2] = target[2]\n this.cachedCameraParams.up[0] = up[0]\n this.cachedCameraParams.up[1] = up[1]\n this.cachedCameraParams.up[2] = up[2]\n this.cachedCameraParams.fov = fov\n this.cachedCameraParams.aspect = aspect\n this.cachedCameraParams.near = near\n this.cachedCameraParams.far = far\n }\n\n this.updatePerspectiveMatrix(fov, aspect, near, far)\n\n // Invalidate forward cache when camera changes\n this.forwardCacheValid = false\n \n this.updateViewMatrix(position, target, up)\n \n this.matricesCacheValid = true\n }\n\n /**\n * Get camera forward vector (cached version)\n */\n private getCameraForward(): [number, number, number] {\n // Reuse cached vector if camera hasn't changed\n if (this.forwardCacheValid) {\n return this.cachedForward\n }\n \n // Calculate forward vector (reuse buffer)\n this.cachedForward[0] = this.camera.target[0] - this.camera.position[0]\n this.cachedForward[1] = this.camera.target[1] - this.camera.position[1]\n this.cachedForward[2] = this.camera.target[2] - this.camera.position[2]\n\n const length = Math.hypot(\n this.cachedForward[0],\n this.cachedForward[1],\n this.cachedForward[2],\n ) || 1\n \n this.cachedForward[0] /= length\n this.cachedForward[1] /= length\n this.cachedForward[2] /= length\n \n this.forwardCacheValid = true\n return this.cachedForward\n }\n\n /**\n * Update perspective projection matrix (reuse buffer)\n */\n private updatePerspectiveMatrix(\n fov: number,\n aspect: number,\n near: number,\n far: number,\n ): void {\n const fovYRadians = (fov * Math.PI) / 180\n const f = 1.0 / Math.tan(fovYRadians / 2)\n const zs = far / (near - far)\n\n const m = this.projectionMatrix\n m[0] = f / aspect\n m[1] = 0\n m[2] = 0\n m[3] = 0\n m[4] = 0\n m[5] = f\n m[6] = 0\n m[7] = 0\n m[8] = 0\n m[9] = 0\n m[10] = zs\n m[11] = -1\n m[12] = 0\n m[13] = 0\n m[14] = zs * near\n m[15] = 0\n }\n\n /**\n * Update view matrix (directly update pre-allocated buffer to avoid per-frame allocation)\n * Equivalent to: inverse(translation) * inverse(rotation) = T^(-1) * R^(-1)\n * Where T is translation matrix, R is rotation matrix\n * Uses reusable temporary vector buffers to avoid allocations\n */\n private updateViewMatrix(\n position: [number, number, number],\n target: [number, number, number],\n up: [number, number, number],\n ): void {\n // Calculate forward vector (reuse buffer)\n this.tempForward[0] = target[0] - position[0]\n this.tempForward[1] = target[1] - position[1]\n this.tempForward[2] = target[2] - position[2]\n const fLen = Math.hypot(this.tempForward[0], this.tempForward[1], this.tempForward[2]) || 1\n this.tempForward[0] /= fLen\n this.tempForward[1] /= fLen\n this.tempForward[2] /= fLen\n\n // Calculate right vector (forward × up, reuse buffer)\n this.tempRight[0] = this.tempForward[1] * up[2] - this.tempForward[2] * up[1]\n this.tempRight[1] = this.tempForward[2] * up[0] - this.tempForward[0] * up[2]\n this.tempRight[2] = this.tempForward[0] * up[1] - this.tempForward[1] * up[0]\n const rLen = Math.hypot(this.tempRight[0], this.tempRight[1], this.tempRight[2]) || 1\n this.tempRight[0] /= rLen\n this.tempRight[1] /= rLen\n this.tempRight[2] /= rLen\n\n // Calculate up vector (right × forward, reuse buffer)\n this.tempUp[0] = this.tempRight[1] * this.tempForward[2] - this.tempRight[2] * this.tempForward[1]\n this.tempUp[1] = this.tempRight[2] * this.tempForward[0] - this.tempRight[0] * this.tempForward[2]\n this.tempUp[2] = this.tempRight[0] * this.tempForward[1] - this.tempRight[1] * this.tempForward[0]\n\n // Rotation matrix R (column-major): [right, newUp, -forward]\n // Inverse of rotation matrix R^(-1) = R^T (transpose)\n // Inverse of translation matrix T^(-1): translate by -position\n // View matrix = T^(-1) * R^(-1)\n // For column-major matrix multiplication T^(-1) * R^(-1):\n // - First three columns = first three columns of R^T (because first three columns of T^(-1) are identity)\n // - Fourth column = fourth column of T^(-1) * R^T = T^(-1) * [0, 0, 0, 1]^T = [-px, -py, -pz, 1]\n const m = this.viewMatrix\n const px = -position[0]\n const py = -position[1]\n const pz = -position[2]\n\n // First three columns: R^T (transpose of rotation matrix)\n m[0] = this.tempRight[0]\n m[1] = this.tempUp[0]\n m[2] = -this.tempForward[0]\n m[3] = 0\n m[4] = this.tempRight[1]\n m[5] = this.tempUp[1]\n m[6] = -this.tempForward[1]\n m[7] = 0\n m[8] = this.tempRight[2]\n m[9] = this.tempUp[2]\n m[10] = -this.tempForward[2]\n m[11] = 0\n\n // Fourth column: fourth column of T^(-1) * R^T = T^(-1) * [0, 0, 0, 1]^T = [-px, -py, -pz, 1]\n m[12] = px\n m[13] = py\n m[14] = pz\n m[15] = 1\n }\n}\n","/**\n * Animation Interpolation Utilities (SDK)\n * Linear interpolation with cosine easing between Flame frames\n * Aligned with app implementation and iOS behavior\n */\n\nimport type { Flame } from '../generated/driveningress/v1/driveningress'\n\nfunction lerpArrays(from: number[], to: number[], progress: number): number[] {\n const length = Math.min(from.length, to.length)\n const result: number[] = Array.from({ length })\n for (let i = 0; i < length; i++) {\n result[i] = from[i] + (to[i] - from[i]) * progress\n }\n return result\n}\n\n/**\n * Linear interpolation with cosine easing (ease-in-ease-out)\n * 0.5 - cos(progress * π) * 0.5\n */\nexport function linearLerp(from: Flame, to: Flame, progress: number): Flame {\n const easedProgress = 0.5 - Math.cos(progress * Math.PI) * 0.5\n\n return {\n translation: lerpArrays(from.translation || [0, 0, 0], to.translation || [0, 0, 0], easedProgress),\n rotation: lerpArrays(from.rotation || [0, 0, 0], to.rotation || [0, 0, 0], easedProgress),\n neckPose: lerpArrays(from.neckPose || [0, 0, 0], to.neckPose || [0, 0, 0], easedProgress),\n jawPose: lerpArrays(from.jawPose || [0, 0, 0], to.jawPose || [0, 0, 0], easedProgress),\n eyePose: lerpArrays(from.eyePose || [0, 0, 0, 0, 0, 0], to.eyePose || [0, 0, 0, 0, 0, 0], easedProgress),\n eyeLid: (() => {\n const fromEyelid = from.eyeLid\n const toEyelid = to.eyeLid\n if (fromEyelid && fromEyelid.length > 0 && toEyelid && toEyelid.length > 0)\n return lerpArrays(fromEyelid, toEyelid, easedProgress)\n return fromEyelid || toEyelid || []\n })(),\n expression: lerpArrays(from.expression || [], to.expression || [], easedProgress),\n }\n}\n\n/**\n * Generate transition keyframes between two Flame states\n * @param durationMs Transition duration (e.g. 400ms)\n * @param fps Frames per second (default 25)\n */\nexport function generateTransitionFrames(\n from: Flame,\n to: Flame,\n durationMs: number,\n fps = 25,\n): Flame[] {\n const steps = Math.max(1, Math.floor((durationMs / 1000) * fps))\n const frames: Flame[] = Array.from({ length: steps })\n for (let i = 0; i < steps; i++) {\n const progress = i / (steps - 1)\n frames[i] = linearLerp(from, to, progress)\n }\n return frames\n}\n\n/**\n * Create a neutral Flame\n */\nexport function createNeutralFlame(): Flame {\n return {\n translation: [0, 0, 0],\n rotation: [0, 0, 0],\n neckPose: [0, 0, 0],\n jawPose: [0, 0, 0],\n eyePose: [0, 0, 0, 0, 0, 0],\n eyeLid: [0, 0],\n expression: [],\n }\n}\n","/**\n * AvatarView:数字人视图\n * 构造函数内部使用 Avatar 实例来创建 AvatarController 实例\n * 由 SDK 内部来维护 AvatarController 实例的生命周期,并开放给开发者来控制数字人行为和监听事件\n */\n\nimport type { Flame } from '../generated/driveningress/v1/driveningress'\nimport type { CameraConfig, RenderPerformanceStats } from '../types'\nimport { AvatarPlaybackMode, DrivingServiceMode } from '../types'\nimport type { CameraSettings } from '../types/character-settings'\nimport type { PreloadResult } from './AvatarDownloader'\nimport type { Avatar } from './Avatar'\n\nimport { APP_CONFIG } from '../config/app-config'\nimport { convertProtoFlameToWasmParams, convertWasmParamsToProtoFlame } from '../animation/utils/flameConverter'\nimport { RenderSystem } from '../renderer/RenderSystem'\nimport { generateTransitionFrames } from '../utils/animation-interpolation'\nimport { logger } from '../utils/logger'\nimport { AvatarKit } from './AvatarKit'\nimport { AvatarController } from './AvatarController'\n\n/**\n * 渲染状态枚举\n */\nenum RenderingState {\n Idle = 'idle',\n TransitioningToSpeaking = 'transitioningToSpeaking',\n Speaking = 'speaking',\n TransitioningToIdle = 'transitioningToIdle',\n}\n\nexport class AvatarView {\n private readonly avatarController: AvatarController\n public readonly playbackMode: AvatarPlaybackMode\n private readonly avatar: Avatar\n\n // Initialization state\n public readonly ready: Promise<void>\n\n // Canvas and rendering\n private canvas: HTMLCanvasElement\n private renderSystem: RenderSystem | null = null\n private isInitialized: boolean = false\n private cameraConfig: CameraConfig | null = null\n\n // Rendering state machine\n private renderingState: RenderingState = RenderingState.Idle\n\n // Realtime animation data\n private currentKeyframes: Flame[] = []\n private lastRenderedFrameIndex: number = -1\n private lastRealtimeProtoFrame: Flame | null = null\n\n // Animation loop types\n private idleAnimationLoopId: number | null = null\n private realtimeAnimationLoopId: number | null = null\n private resizeObserver: ResizeObserver | null = null\n private onWindowResize = () => this.handleResize()\n\n // FPS 计算\n private frameCount = 0\n private lastFpsUpdate = 0\n private currentFPS = 0\n\n // Transition animation data\n private transitionKeyframes: Flame[] = []\n private transitionStartTime: number = 0\n private readonly transitionDurationMs: number = 400\n private cachedIdleFirstFrame: Flame | null = null\n private idleCurrentFrameIndex: number = 0\n\n // Character handle for multi-character support\n private characterHandle: number | null = null\n private characterId: string // Unique ID for this character instance\n\n /**\n * 对齐两端 Flame 维度:标量统一长度,expression 取最大长度并零填充\n */\n private alignFlamePair(from: Flame, to: Flame): { from: Flame, to: Flame } {\n const ensureLen = (arr: number[] | undefined, len: number): number[] => {\n const a = Array.isArray(arr) ? arr.slice(0, len) : []\n if (a.length < len) {\n // Use Array.from instead of loop push for better performance\n return Array.from({ length: len }, (_, i) => a[i] ?? 0)\n }\n return a\n }\n const fromFixed = {\n translation: ensureLen(from?.translation, 3),\n rotation: ensureLen(from?.rotation, 3),\n neckPose: ensureLen(from?.neckPose, 3),\n jawPose: ensureLen(from?.jawPose, 3),\n eyePose: ensureLen(from?.eyePose, 6),\n eyeLid: ensureLen(from?.eyeLid, 2),\n expression: Array.isArray(from?.expression) ? from.expression.slice() : [],\n }\n const toFixed = {\n translation: ensureLen(to?.translation, 3),\n rotation: ensureLen(to?.rotation, 3),\n neckPose: ensureLen(to?.neckPose, 3),\n jawPose: ensureLen(to?.jawPose, 3),\n eyePose: ensureLen(to?.eyePose, 6),\n eyeLid: ensureLen(to?.eyeLid, 2),\n expression: Array.isArray(to?.expression) ? to.expression.slice() : [],\n }\n const exprLen = Math.max(fromFixed.expression.length, toFixed.expression.length)\n fromFixed.expression = ensureLen(fromFixed.expression, exprLen)\n toFixed.expression = ensureLen(toFixed.expression, exprLen)\n return { from: fromFixed, to: toFixed }\n }\n\n /**\n * 生成并对齐过渡帧,确保首尾帧与起止帧完全一致\n */\n private generateAndAlignTransitionFrames(from: Flame, to: Flame): Flame[] {\n const aligned = this.alignFlamePair(from, to)\n let keyframes = generateTransitionFrames(\n aligned.from,\n aligned.to,\n this.transitionDurationMs,\n APP_CONFIG.animation.fps,\n )\n\n if (keyframes.length < 2) {\n keyframes = [aligned.from, aligned.to]\n }\n\n // 强制首尾帧与起止帧一致,避免边界离散\n keyframes[0] = aligned.from\n keyframes[keyframes.length - 1] = aligned.to\n\n return keyframes\n }\n\n /**\n * 获取缓存的 Idle 首帧,如果未缓存则获取并缓存\n */\n private async getCachedIdleFirstFrame(): Promise<Flame | null> {\n if (!this.cachedIdleFirstFrame) {\n const avatarCore = AvatarKit.getAvatarCore()\n if (avatarCore) {\n try {\n const idle0Params = await avatarCore.getCurrentFrameParams(0, this.characterId)\n this.cachedIdleFirstFrame = convertWasmParamsToProtoFlame(idle0Params)\n }\n catch (e) {\n logger.warn('[AvatarView] Failed to get idle first frame:', e instanceof Error ? e.message : String(e))\n }\n }\n }\n return this.cachedIdleFirstFrame\n }\n\n /**\n * 构造函数\n * 创建统一的 AvatarController,内部根据配置自动组合网络层\n */\n /**\n * 构造函数\n * 创建统一的 AvatarController,内部根据配置自动组合网络层\n * @param avatar - Avatar 实例\n * @param container - Canvas 容器元素(必选)\n */\n constructor(\n avatar: Avatar,\n container: HTMLElement\n ) {\n // 保存 avatar 引用\n this.avatar = avatar\n \n // Generate unique character ID for multi-character support\n this.characterId = `${avatar.id}-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`\n\n // 创建统一的 AvatarController,内部根据配置自动组合网络层\n // 从 AvatarKit 配置中读取 drivingServiceMode(必须在 AvatarKit.initialize() 中配置)\n const kitConfig = AvatarKit.configuration\n if (!kitConfig) {\n throw new Error('AvatarKit must be initialized before creating AvatarView. Call AvatarKit.initialize() first.')\n }\n \n const drivingServiceMode = kitConfig.drivingServiceMode ?? DrivingServiceMode.sdk // 默认为 sdk\n const mode: AvatarPlaybackMode = drivingServiceMode === DrivingServiceMode.sdk \n ? AvatarPlaybackMode.network \n : AvatarPlaybackMode.external\n this.playbackMode = mode\n this.avatarController = new AvatarController(avatar, {\n playbackMode: mode\n })\n\n // 设置渲染回调:播放层调用此回调来通知渲染层渲染\n // Note: characterHandle will be set after character is loaded in initializeView\n this.avatarController.setRenderCallback((splatData, frameIndex) => {\n this.renderRealtimeFrame(splatData, frameIndex)\n })\n\n // 设置过渡完成回调:过渡完成后通知播放层启动音频\n this.avatarController.setTransitionCompleteCallback(() => {\n this.onTransitionComplete()\n })\n\n \n // 创建自己管理的canvas\n this.canvas = this.createCanvas(container)\n\n // 初始化渲染和动画系统(暴露 Promise 给外部,以便等待初始化完成)\n this.ready = this.initializeView(avatar)\n\n // 监听 AvatarController 的事件\n this.setupControllerEventListeners()\n }\n\n /**\n * 获取控制器(公共接口)\n */\n get controller(): AvatarController {\n return this.avatarController\n }\n\n /**\n * 创建canvas元素\n */\n private createCanvas(container: HTMLElement): HTMLCanvasElement {\n const canvas = document.createElement('canvas')\n\n // 获取容器尺寸\n const containerWidth = container.offsetWidth || 800\n const containerHeight = container.offsetHeight || 600\n\n // 直接使用容器的完整尺寸(不再强制 1:1 比例)\n // 设置 Canvas 内部尺寸(实际渲染分辨率)\n const dpr = window.devicePixelRatio || 1\n canvas.width = Math.floor(containerWidth * dpr)\n canvas.height = Math.floor(containerHeight * dpr)\n\n // 设置 Canvas 显示尺寸(CSS 像素尺寸)\n canvas.style.width = `${containerWidth}px`\n canvas.style.height = `${containerHeight}px`\n canvas.style.display = 'block'\n canvas.style.margin = '0 auto'\n // 去除绝对定位,保持标准文档流(与线上一致)\n canvas.style.position = ''\n canvas.style.top = ''\n canvas.style.left = ''\n canvas.style.zIndex = ''\n canvas.style.background = 'none'\n canvas.style.border = 'none'\n\n // 添加到容器中\n container.appendChild(canvas)\n // 设置容器为 flex 布局,使 canvas 居中\n container.style.display = 'flex'\n container.style.justifyContent = 'center'\n container.style.alignItems = 'center'\n container.style.position = 'relative'\n\n // 监听容器尺寸变化,更新画布分辨率并通知渲染系统\n this.resizeObserver = new ResizeObserver(() => {\n const dpr = window.devicePixelRatio || 1\n const w = Math.floor(container.offsetWidth || 0)\n const h = Math.floor(container.offsetHeight || 0)\n // 直接使用容器的完整尺寸\n canvas.width = Math.floor(w * dpr)\n canvas.height = Math.floor(h * dpr)\n canvas.style.width = `${w}px`\n canvas.style.height = `${h}px`\n this.handleResize()\n })\n this.resizeObserver.observe(container)\n\n // 兜底监听窗口尺寸变化\n window.addEventListener('resize', this.onWindowResize)\n\n return canvas\n }\n\n /**\n * 获取canvas元素(供外部访问)\n * @internal\n */\n getCanvas(): HTMLCanvasElement {\n return this.canvas\n }\n\n /**\n * 初始化视图系统\n */\n private async initializeView(avatar: Avatar): Promise<void> {\n try {\n if (APP_CONFIG.debug)\n logger.log('[AvatarView] Initializing avatar view...')\n\n // 获取AvatarCore实例\n const avatarCore = AvatarKit.getAvatarCore()\n if (!avatarCore) {\n throw new Error('AvatarCore not available. AvatarKit initialization may have failed.')\n }\n\n // 获取资源数据\n const resources = avatar.getResources()\n\n // 加载角色数据(支持多角色,返回 handle)\n if (APP_CONFIG.debug)\n logger.log('[AvatarView] Loading character data...')\n this.characterHandle = await avatarCore.loadCharacterFromBuffers(\n resources.characterData.shape,\n resources.characterData.pointCloud,\n this.characterId,\n )\n\n // 加载idle动画(如果可用)\n if (resources.characterData.idleAnimation) {\n if (APP_CONFIG.debug)\n logger.log('[AvatarView] Loading idle animation...')\n await avatarCore.loadAnimationFromBuffer(resources.characterData.idleAnimation, this.characterId)\n }\n\n // 清理 resources 中的 ArrayBuffer 引用(数据已经传给 WASM,不再需要)\n // 这样可以避免多个 Avatar 对象同时持有大量 ArrayBuffer,依赖浏览器 HTTP 缓存即可\n resources.characterData.shape = new ArrayBuffer(0)\n resources.characterData.pointCloud = new ArrayBuffer(0)\n if (resources.characterData.idleAnimation) {\n resources.characterData.idleAnimation = new ArrayBuffer(0)\n }\n\n // 更新 AvatarController 的 characterHandle(用于播放循环中的计算)\n this.avatarController.setRenderCallback(\n (splatData, frameIndex) => {\n this.renderRealtimeFrame(splatData, frameIndex)\n },\n this.characterHandle,\n )\n\n // 初始化渲染系统(相机配置优先从 resources.preloadCameraSettings 获取)\n if (APP_CONFIG.debug)\n logger.log('[AvatarView] Initializing render system...')\n const cameraConfig = this.resolveCameraConfig(resources)\n await this.initializeRenderSystem(cameraConfig)\n\n // 开始渲染\n if (APP_CONFIG.debug)\n logger.log('[AvatarView] Starting rendering...')\n await this.renderFirstFrame()\n this.startIdleAnimationLoop()\n\n this.isInitialized = true\n if (APP_CONFIG.debug)\n logger.log('[AvatarView] Avatar view initialized successfully')\n }\n catch (error) {\n logger.error('[AvatarView] Failed to initialize avatar view:', error instanceof Error ? error.message : String(error))\n throw error\n }\n }\n\n /**\n * 初始化渲染系统\n */\n private async initializeRenderSystem(cameraInfo?: CameraConfig): Promise<void> {\n // 相机配置优先级:优先使用资源中的配置,不存在时使用默认静态配置\n this.cameraConfig = cameraInfo || this.getDefaultCameraConfig()\n\n if (cameraInfo) {\n logger.log('[AvatarView] Using resolved camera config:', cameraInfo)\n }\n else {\n logger.log('[AvatarView] No camera config in resources, using default static config:', this.cameraConfig)\n }\n\n // 创建RenderSystem实例\n this.renderSystem = new RenderSystem({\n canvas: this.canvas,\n camera: this.cameraConfig,\n backgroundColor: [0, 0, 0, 0], // 透明背景,让 CSS 背景透出\n })\n\n // 初始化渲染系统\n await this.renderSystem.initialize()\n if (APP_CONFIG.debug)\n logger.log('[AvatarView] Render system initialized successfully')\n }\n\n /**\n * 获取默认相机配置\n */\n private getDefaultCameraConfig(): CameraConfig {\n // 直接使用 APP_CONFIG.camera(包含 near: 0.01, far: 100,与 iOS 对齐)\n return { ...APP_CONFIG.camera }\n }\n\n /**\n * 根据资源解析最终的相机配置,优先使用角色设置,其次 camera.json\n */\n private resolveCameraConfig(resources: PreloadResult): CameraConfig {\n const defaultCamera = this.getDefaultCameraConfig()\n const characterCameraSettings = resources.characterSettings?.camera ?? null\n const preloadCameraSettings = resources.preloadCameraSettings?.camera ?? null\n\n const candidateSettings = characterCameraSettings ?? preloadCameraSettings\n\n if (!candidateSettings) {\n logger.warn('[AvatarView] Camera settings not found in resources, falling back to default camera config')\n return defaultCamera\n }\n\n const source: 'characterSettings' | 'camera.json' = characterCameraSettings ? 'characterSettings' : 'camera.json'\n return this.deriveCameraConfigFromSettings(candidateSettings, defaultCamera, source)\n }\n\n /**\n * 从角色设置中推导相机配置\n */\n private deriveCameraConfigFromSettings(\n cameraSettings: CameraSettings,\n fallback: CameraConfig,\n source: 'characterSettings' | 'camera.json',\n ): CameraConfig {\n const safeValue = (value: number | undefined, fallbackValue: number): number =>\n Number.isFinite(value) ? (value as number) : fallbackValue\n\n const translationX = safeValue(cameraSettings.translationX, fallback.position[0])\n const translationY = safeValue(cameraSettings.translationY, fallback.position[1])\n const translationZ = safeValue(cameraSettings.translationZ, fallback.position[2])\n const yaw = safeValue(cameraSettings.rotation, 0)\n const fovRadians = safeValue(cameraSettings.fovYRadians, 0)\n\n const hasCustomTranslation = Math.hypot(translationX, translationY, translationZ) > 1e-4\n const hasCustomFov = fovRadians > 0\n const hasCustomRotation = Math.abs(yaw) > 1e-4\n\n if (!hasCustomTranslation && !hasCustomFov && !hasCustomRotation) {\n logger.warn(`[AvatarView] Camera settings from ${source} appear empty, falling back to default config`)\n return fallback\n }\n\n const sinYaw = Math.sin(yaw)\n const cosYaw = Math.cos(yaw)\n\n const position: [number, number, number] = hasCustomTranslation\n ? [translationX, translationY, translationZ]\n : [...fallback.position]\n\n const forward: [number, number, number] = [\n -sinYaw,\n 0,\n -cosYaw,\n ]\n\n const forwardLength = Math.hypot(forward[0], forward[1], forward[2]) || 1\n const normalizedForward: [number, number, number] = [\n forward[0] / forwardLength,\n forward[1] / forwardLength,\n forward[2] / forwardLength,\n ]\n\n const target: [number, number, number] = [\n position[0] + normalizedForward[0],\n position[1] + normalizedForward[1],\n position[2] + normalizedForward[2],\n ]\n\n const up: [number, number, number] = [0, 1, 0]\n const fov = hasCustomFov ? (fovRadians * 180) / Math.PI : fallback.fov\n\n const derivedCamera: CameraConfig = {\n ...fallback, // 自动继承 near/far 等配置(来自 APP_CONFIG.camera)\n position,\n target,\n up,\n fov,\n // near/far 从 fallback 继承,无需硬编码\n }\n\n logger.log('[AvatarView] Applied camera settings from resources', {\n source,\n translation: [translationX, translationY, translationZ],\n yawRadians: yaw,\n position,\n target,\n fov,\n near: derivedCamera.near,\n far: derivedCamera.far,\n })\n\n return derivedCamera\n }\n\n /**\n * 渲染第一帧\n */\n private async renderFirstFrame(): Promise<void> {\n if (!this.renderSystem) {\n throw new Error('Render system not initialized')\n }\n\n // 获取AvatarCore实例\n const avatarCore = AvatarKit.getAvatarCore()\n if (!avatarCore) {\n throw new Error('AvatarCore not available')\n }\n\n // 计算第一帧(使用中性参数)\n const neutralParams = {\n shape_params: Array.from({ length: 100 }, () => 0),\n expr_params: Array.from({ length: 50 }, () => 0),\n rotation: [0, 0, 0],\n translation: [0, 0, 0],\n neck_pose: [0, 0, 0],\n jaw_pose: [0, 0, 0],\n eyes_pose: [0, 0, 0, 0, 0, 0],\n }\n\n // 计算第一帧的splat数据\n const splatData = await avatarCore.computeFrameFlatFromParams(neutralParams, this.characterHandle ?? undefined)\n if (splatData) {\n this.renderSystem.loadSplatsFromPackedData(splatData)\n\n // 渲染第一帧\n this.renderSystem.renderFrame()\n\n if (APP_CONFIG.debug)\n logger.log('[AvatarView] First frame rendered successfully')\n }\n else {\n throw new Error('Failed to compute first frame splat data')\n }\n }\n\n /**\n * 更新 FPS 统计(在 requestAnimationFrame 回调中调用)\n */\n private updateFPS(): void {\n this.frameCount++\n const now = performance.now()\n if (now - this.lastFpsUpdate >= 1000) {\n this.currentFPS = Math.round(this.frameCount / ((now - this.lastFpsUpdate) / 1000))\n this.frameCount = 0\n this.lastFpsUpdate = now\n }\n }\n\n /**\n * 初始化 FPS 计算\n */\n private initFPS(): void {\n this.frameCount = 0\n this.lastFpsUpdate = performance.now()\n }\n\n /**\n * 开始idle动画循环\n */\n private startIdleAnimationLoop(): void {\n // Safety: Stop any existing loop before starting new one\n if (this.idleAnimationLoopId) {\n this.stopIdleAnimationLoop()\n }\n // 若不在 Idle 状态,不启动 Idle 循环\n if (this.renderingState !== RenderingState.Idle) {\n if (APP_CONFIG.debug)\n logger.log('[AvatarView] Skip starting idle loop because not in idle state')\n return\n }\n\n this.idleCurrentFrameIndex = 0\n let lastTime = 0\n const targetFPS = APP_CONFIG.animation.fps\n const frameInterval = 1000 / targetFPS // 每帧间隔(毫秒)\n\n // 初始化 FPS 计算\n this.initFPS()\n\n const renderFrame = async (currentTime: number) => {\n try {\n if (!this.renderSystem) {\n return\n }\n\n // FPS 计算(在 requestAnimationFrame 回调中)\n this.updateFPS()\n\n // 如果不在 Idle 状态,暂停idle动画\n if (this.renderingState !== RenderingState.Idle) {\n this.idleAnimationLoopId = requestAnimationFrame(renderFrame)\n return\n }\n\n // 控制动画帧率\n if (currentTime - lastTime < frameInterval) {\n this.idleAnimationLoopId = requestAnimationFrame(renderFrame)\n return\n }\n lastTime = currentTime\n\n // 获取AvatarCore实例\n const avatarCore = AvatarKit.getAvatarCore()\n if (!avatarCore) {\n return\n }\n\n // Idle动画模式:使用递增的帧索引\n const splatData = await avatarCore.computeCompleteFrameFlat({ frameIndex: this.idleCurrentFrameIndex }, this.characterHandle ?? undefined)\n this.idleCurrentFrameIndex++\n\n if (splatData) {\n // 避免在状态切换帧仍渲染 Idle\n if (this.renderingState !== RenderingState.Idle) {\n return\n }\n // 加载splat数据到渲染系统\n this.renderSystem.loadSplatsFromPackedData(splatData)\n // 渲染当前帧(Idle)\n this.renderSystem.renderFrame()\n }\n\n // 继续下一帧\n this.idleAnimationLoopId = requestAnimationFrame(renderFrame)\n }\n catch (error) {\n logger.error('[AvatarView] Idle animation loop error:', error instanceof Error ? error.message : String(error))\n this.stopIdleAnimationLoop()\n }\n }\n\n this.idleAnimationLoopId = requestAnimationFrame(renderFrame)\n if (APP_CONFIG.debug)\n logger.log('[AvatarView] Idle animation loop started')\n }\n\n /**\n * 开始实时对话动画循环\n */\n private startRealtimeAnimationLoop(): void {\n // Safety: Stop any existing loop before starting new one\n if (this.realtimeAnimationLoopId) {\n this.stopRealtimeAnimationLoop()\n }\n\n let lastTime = 0\n const targetFPS = APP_CONFIG.animation.fps\n const frameInterval = 1000 / targetFPS // 每帧间隔(毫秒)\n\n // 初始化 FPS 计算\n this.initFPS()\n\n const renderFrame = async (currentTime: number) => {\n try {\n const state = this.renderingState\n \n // FPS 计算(在 requestAnimationFrame 回调中)\n this.updateFPS()\n \n // 如果不在实时相关状态,停止循环\n if (!this.renderSystem || state === RenderingState.Idle) {\n this.realtimeAnimationLoopId = null\n return\n }\n\n // 控制动画帧率\n if (currentTime - lastTime < frameInterval) {\n this.realtimeAnimationLoopId = requestAnimationFrame(renderFrame)\n return\n }\n lastTime = currentTime\n\n // 处理过渡状态\n if (state === RenderingState.TransitioningToSpeaking || \n state === RenderingState.TransitioningToIdle) {\n if (this.transitionKeyframes.length === 0) {\n this.realtimeAnimationLoopId = requestAnimationFrame(renderFrame)\n return\n }\n\n const elapsed = performance.now() - this.transitionStartTime\n const progress = Math.min(1, Math.max(0, elapsed / this.transitionDurationMs))\n const steps = this.transitionKeyframes.length\n const idx = Math.min(steps - 1, Math.floor(progress * (steps - 1)))\n const currentFrame = this.transitionKeyframes[idx]\n const wasmParams = convertProtoFlameToWasmParams(currentFrame)\n const avatarCore = AvatarKit.getAvatarCore()\n \n if (avatarCore) {\n const sd = await avatarCore.computeFrameFlatFromParams(wasmParams, this.characterHandle ?? undefined)\n if (sd) {\n this.renderSystem.loadSplatsFromPackedData(sd)\n this.renderSystem.renderFrame()\n }\n }\n\n if (progress >= 1) {\n // 过渡完成\n if (state === RenderingState.TransitioningToSpeaking) {\n this.setState(RenderingState.Speaking)\n this.transitionKeyframes = []\n this.avatarController.onTransitionComplete()\n } else if (state === RenderingState.TransitioningToIdle) {\n this.setState(RenderingState.Idle)\n this.transitionKeyframes = []\n this.stopRealtimeAnimationLoop()\n this.startIdleAnimationLoop()\n return\n }\n }\n \n this.realtimeAnimationLoopId = requestAnimationFrame(renderFrame)\n return\n }\n\n // Speaking 状态:等待播放层的回调驱动渲染\n if (state === RenderingState.Speaking) {\n this.realtimeAnimationLoopId = requestAnimationFrame(renderFrame)\n return\n }\n }\n catch (error) {\n logger.error('[AvatarView] Realtime animation loop error:', error instanceof Error ? error.message : String(error))\n this.stopRealtimeAnimationLoop()\n }\n }\n\n this.realtimeAnimationLoopId = requestAnimationFrame(renderFrame)\n if (APP_CONFIG.debug)\n logger.log('[AvatarView] Realtime animation loop started')\n }\n\n /**\n * 停止idle动画循环\n */\n private stopIdleAnimationLoop(): void {\n if (this.idleAnimationLoopId) {\n cancelAnimationFrame(this.idleAnimationLoopId)\n this.idleAnimationLoopId = null\n if (APP_CONFIG.debug)\n logger.log('[AvatarView] Idle animation loop stopped')\n }\n }\n\n /**\n * 停止实时对话动画循环\n */\n private stopRealtimeAnimationLoop(): void {\n if (this.realtimeAnimationLoopId) {\n cancelAnimationFrame(this.realtimeAnimationLoopId)\n this.realtimeAnimationLoopId = null\n if (APP_CONFIG.debug)\n logger.log('[AvatarView] Realtime animation loop stopped')\n }\n }\n\n /**\n * 停止所有动画循环\n */\n private stopAllAnimationLoops(): void {\n this.stopIdleAnimationLoop()\n this.stopRealtimeAnimationLoop()\n }\n\n /**\n * 渲染实时帧(由播放层回调调用)\n */\n private renderRealtimeFrame(splatData: Float32Array, frameIndex: number): void {\n // 只在 Speaking 状态且不在过渡中时渲染\n if (!this.renderSystem || this.renderingState !== RenderingState.Speaking) {\n return\n }\n\n // 只在非过渡状态下渲染实时帧\n this.renderSystem.loadSplatsFromPackedData(splatData)\n this.renderSystem.renderFrame()\n this.lastRenderedFrameIndex = frameIndex\n\n // 缓存当前帧,用于 Speaking -> Idle 过渡\n if (frameIndex >= 0 && frameIndex < this.currentKeyframes.length) {\n this.lastRealtimeProtoFrame = this.currentKeyframes[frameIndex]\n }\n }\n\n /**\n * 过渡完成回调(通知播放层启动音频)\n */\n private onTransitionComplete(): void {\n // 这个方法会被播放层调用,但这里不需要做任何事情\n // 因为过渡动画的渲染已经在 startRealtimeAnimationLoop 中处理\n // 音频启动由播放层的 onTransitionComplete 处理\n }\n\n /**\n * 状态转换方法\n * 统一管理状态转换,确保状态一致性\n */\n private setState(newState: RenderingState): void {\n const oldState = this.renderingState\n this.renderingState = newState\n\n // 状态退出时的清理\n if (oldState === RenderingState.TransitioningToIdle && \n newState !== RenderingState.TransitioningToIdle) {\n this.transitionKeyframes = []\n }\n if (oldState === RenderingState.TransitioningToSpeaking && \n newState !== RenderingState.TransitioningToSpeaking) {\n this.transitionKeyframes = []\n }\n\n // 状态进入时的初始化\n if (newState === RenderingState.Idle) {\n this.currentKeyframes = []\n this.lastRenderedFrameIndex = -1\n this.lastRealtimeProtoFrame = null\n this.transitionKeyframes = []\n this.transitionStartTime = 0\n }\n }\n\n /**\n * 检查是否在实时播放状态(Speaking 或过渡到 Speaking)\n */\n private get isRealtimePlaying(): boolean {\n return this.renderingState === RenderingState.Speaking || \n this.renderingState === RenderingState.TransitioningToSpeaking\n }\n\n /**\n * 检查是否在过渡中\n */\n private get isTransitioning(): boolean {\n return this.renderingState === RenderingState.TransitioningToSpeaking || \n this.renderingState === RenderingState.TransitioningToIdle\n }\n\n /**\n * 检查过渡结束后是否回到 Idle\n */\n private get endToIdleAfterTransition(): boolean {\n return this.renderingState === RenderingState.TransitioningToIdle\n }\n\n /**\n * 处理打断\n * 打断时应该生成过渡动画,而不是直接跳回 Idle\n */\n private handleInterrupt(): void {\n const state = this.renderingState\n \n // 如果已经在过渡到 Idle,说明 stopRealtimeRendering() 已经处理了,不需要重复处理\n if (state === RenderingState.TransitioningToIdle) {\n return\n }\n \n // 如果正在 Speaking 或过渡到 Speaking,生成过渡回到 Idle\n if (state === RenderingState.Speaking || \n state === RenderingState.TransitioningToSpeaking) {\n this.stopRealtimeRendering()\n } else {\n // 其他状态直接重置到 Idle\n this.setState(RenderingState.Idle)\n this.stopRealtimeAnimationLoop()\n this.startIdleAnimationLoop()\n }\n }\n\n /**\n * 设置 AvatarController 事件监听器\n */\n private setupControllerEventListeners(): void {\n this.avatarController.setupInternalEventListeners({\n onKeyframesUpdate: (keyframes: Flame[]) => {\n // 关键帧更新时,准备开始实时渲染\n this.prepareRealtimeRendering(keyframes)\n },\n onStartRendering: () => {\n // 播放层通知开始渲染,启动实时渲染循环\n this.startRealtimeRendering()\n },\n onStopRendering: () => {\n // 播放层通知停止渲染,生成 Speaking -> Idle 过渡\n this.stopRealtimeRendering()\n },\n onInterrupt: () => {\n // 播放层通知打断,立即停止\n this.handleInterrupt()\n },\n })\n }\n\n /**\n * 准备实时渲染(生成 Idle -> Speaking 过渡)\n */\n private async prepareRealtimeRendering(keyframes: Flame[]): Promise<void> {\n const state = this.renderingState\n \n // 如果已经在 Speaking 或过渡到 Speaking,只更新关键帧\n if ((state === RenderingState.Speaking || \n state === RenderingState.TransitioningToSpeaking) && \n this.currentKeyframes.length > 0) {\n this.currentKeyframes = keyframes\n return\n }\n\n // 确保 Idle 循环停止\n this.stopIdleAnimationLoop()\n \n // 设置状态并准备过渡\n this.currentKeyframes = keyframes\n this.setState(RenderingState.TransitioningToSpeaking)\n\n // 生成 Idle -> Speaking 过渡\n try {\n const avatarCore = AvatarKit.getAvatarCore()\n if (avatarCore && keyframes.length > 0) {\n // 检查状态是否已改变(可能被打断)\n if (this.renderingState !== RenderingState.TransitioningToSpeaking) {\n return\n }\n\n // 读取 Idle 的当前帧作为起点\n const idleParams = await avatarCore.getCurrentFrameParams(this.idleCurrentFrameIndex, this.characterId)\n const idleFrameProto = convertWasmParamsToProtoFlame(idleParams)\n\n // 缓存 Idle 首帧,用于后续 Speaking -> Idle 过渡\n await this.getCachedIdleFirstFrame()\n\n const firstSpeaking = keyframes[0]\n this.transitionKeyframes = this.generateAndAlignTransitionFrames(idleFrameProto, firstSpeaking)\n this.transitionStartTime = performance.now()\n\n if (this.transitionKeyframes.length === 0) {\n // 没有过渡动画,直接进入 Speaking 状态\n this.setState(RenderingState.Speaking)\n this.avatarController.onTransitionComplete()\n } else {\n if (APP_CONFIG.debug)\n logger.log('[AvatarView] Transition started:', this.transitionKeyframes.length, 'frames')\n }\n }\n } catch (e) {\n logger.warn('[AvatarView] Transition generation failed:', e instanceof Error ? e.message : String(e))\n // 过渡生成失败时,直接进入 Speaking 状态\n if (this.renderingState === RenderingState.TransitioningToSpeaking) {\n this.setState(RenderingState.Speaking)\n this.avatarController.onTransitionComplete()\n }\n }\n\n // 启动实时渲染循环\n this.startRealtimeAnimationLoop()\n }\n\n /**\n * 开始实时渲染循环\n */\n private startRealtimeRendering(): void {\n if (APP_CONFIG.debug)\n logger.log('[AvatarView] Starting realtime rendering with', this.currentKeyframes.length, 'keyframes')\n \n // 埋点:渲染开始\n AvatarKit.logEvent('character_view', 'info', {\n characterId: this.avatar.id,\n event: 'rendering_started',\n keyframesCount: this.currentKeyframes.length,\n })\n }\n\n /**\n * 停止实时对话渲染\n */\n private stopRealtimeRendering(): void {\n const state = this.renderingState\n \n // 如果已经在 Idle 或过渡到 Idle,不需要处理\n if (state === RenderingState.Idle || \n state === RenderingState.TransitioningToIdle) {\n return\n }\n\n // 如果不在 Speaking 状态,直接重置到 Idle\n if (state !== RenderingState.Speaking) {\n this.setState(RenderingState.Idle)\n this.stopRealtimeAnimationLoop()\n this.startIdleAnimationLoop()\n return\n }\n\n // 从 Speaking 状态生成过渡到 Idle\n this.setState(RenderingState.TransitioningToIdle)\n \n ;(async () => {\n try {\n // 检查状态是否已改变(可能被打断)\n if (this.renderingState !== RenderingState.TransitioningToIdle) {\n return\n }\n \n const avatarCore = AvatarKit.getAvatarCore()\n if (avatarCore && this.currentKeyframes.length > 0) {\n const lastSpeaking = this.lastRealtimeProtoFrame || \n this.currentKeyframes[Math.max(0, this.lastRenderedFrameIndex)]\n const idleFirstProto = await this.getCachedIdleFirstFrame()\n \n if (idleFirstProto) {\n this.transitionKeyframes = this.generateAndAlignTransitionFrames(lastSpeaking, idleFirstProto)\n this.transitionStartTime = performance.now()\n \n if (this.transitionKeyframes.length > 0 && \n this.renderingState === RenderingState.TransitioningToIdle) {\n if (APP_CONFIG.debug)\n logger.log('[AvatarView] Return transition started:', this.transitionKeyframes.length, 'frames')\n // 确保实时循环在跑,用于渲染这段回退过渡\n if (!this.realtimeAnimationLoopId) {\n this.startRealtimeAnimationLoop()\n }\n return\n }\n }\n }\n } catch (e) {\n logger.warn('[AvatarView] Return transition generation failed:', e instanceof Error ? e.message : String(e))\n }\n \n // 无法生成过渡,直接回到 Idle\n if (this.renderingState === RenderingState.TransitioningToIdle) {\n this.setState(RenderingState.Idle)\n this.stopRealtimeAnimationLoop()\n this.startIdleAnimationLoop()\n }\n })()\n }\n\n /**\n * 清理视图资源\n * 关闭 avatarController 并清理所有相关资源\n */\n dispose(): void {\n if (APP_CONFIG.debug)\n logger.log('[AvatarView] Disposing avatar view...')\n\n // 埋点:视图销毁\n AvatarKit.logEvent('character_view', 'info', {\n characterId: this.avatar.id,\n event: 'disposed',\n })\n\n // 关闭 avatarController(由其管理生命周期)\n if (this.avatarController) {\n this.avatarController.clear()\n // 清理回调,避免内存泄漏\n this.avatarController.dispose()\n }\n\n // 停止所有动画循环\n this.stopAllAnimationLoops()\n\n // 重置状态(会自动清理 currentKeyframes, lastRenderedFrameIndex, lastRealtimeProtoFrame, transitionKeyframes, transitionStartTime)\n this.setState(RenderingState.Idle)\n\n // 清理 setState 中没有清理的数据,避免内存泄漏\n this.cachedIdleFirstFrame = null\n this.idleCurrentFrameIndex = 0\n\n // 释放 AvatarCore 的角色和动画资源(支持多角色,只释放当前实例的角色)\n const avatarCore = AvatarKit.getAvatarCore()\n if (avatarCore && this.characterHandle) {\n try {\n avatarCore.removeCharacter(this.characterHandle, this.characterId)\n if (APP_CONFIG.debug)\n logger.log('[AvatarView] AvatarCore character resources released')\n this.characterHandle = null\n }\n catch (error) {\n logger.error('[AvatarView] Failed to release AvatarCore resources:', error instanceof Error ? error.message : String(error))\n }\n }\n\n // 清理渲染系统\n if (this.renderSystem) {\n this.renderSystem.dispose()\n this.renderSystem = null\n }\n\n // 清理canvas\n if (this.canvas && this.canvas.parentNode) {\n this.canvas.parentNode.removeChild(this.canvas)\n }\n\n // 取消尺寸监听\n if (this.resizeObserver) {\n this.resizeObserver.disconnect()\n this.resizeObserver = null\n }\n window.removeEventListener('resize', this.onWindowResize)\n\n this.isInitialized = false\n if (APP_CONFIG.debug)\n logger.log('[AvatarView] Avatar view disposed successfully')\n }\n\n /**\n * 获取相机配置\n * @internal\n */\n getCameraConfig(): CameraConfig | null {\n return this.cameraConfig\n }\n\n /**\n * 更新相机配置\n * @internal\n */\n updateCameraConfig(cameraConfig: CameraConfig): void {\n this.cameraConfig = cameraConfig\n if (APP_CONFIG.debug)\n logger.log('[AvatarView] Camera config updated:', cameraConfig)\n\n // 将新的相机配置应用到渲染系统\n if (this.renderSystem) {\n this.renderSystem.updateCamera(cameraConfig)\n if (APP_CONFIG.debug)\n logger.log('[AvatarView] Applied new camera config to render system')\n }\n }\n\n /**\n * 处理尺寸变化:通知渲染系统更新视口与投影\n */\n private handleResize(): void {\n if (this.renderSystem) {\n this.renderSystem.handleResize()\n }\n }\n\n /**\n * 获取渲染性能统计\n * @returns 渲染性能统计数据,如果渲染系统未初始化则返回 null\n * @internal Not part of public API yet\n */\n getPerformanceStats(): RenderPerformanceStats | null {\n if (!this.renderSystem || !this.isInitialized) {\n return null\n }\n\n return {\n renderTime: this.renderSystem.renderTime,\n sortTime: this.renderSystem.sortTime,\n backend: this.renderSystem.getBackend(),\n fps: this.currentFPS,\n // pointCount 可后续通过 AvatarCoreAdapter 添加公开方法获取\n }\n }\n\n}\n"],"names":["Avatar","id","characterMeta","resources","__publicField","ResourceType","extractResourceUrls","meta","_a","_b","_c","_d","_e","_f","_g","_h","_i","_j","_k","Environment","DrivingServiceMode","LoadProgress","ConnectionState","AvatarState","SPAvatarError","message","code","AvatarPlaybackMode","hasDebugParam","isDebugMode","APP_CONFIG","convertProtoFlameToWasmParams","protoFlame","convertWasmParamsToProtoFlame","wasmParams","root","factory","module","this","_isNumber","n","_capitalize","str","_getter","p","booleanProps","numericProps","stringProps","arrayProps","objectProps","props","StackFrame","obj","i","v","fileName","lineNumber","columnNumber","functionName","argsStartIndex","argsEndIndex","args","locationString","parts","j","k","require$$0","FIREFOX_SAFARI_STACK_REGEXP","CHROME_IE_STACK_REGEXP","SAFARI_NATIVE_CODE_REGEXP","error","urlLike","regExp","filtered","line","sanitizedLine","location","locationParts","functionNameRegex","matches","e","lineRE","lines","result","len","match","tokens","functionCall","argsRaw","_lazyMatch","__lib__","m","V","G","T","q","r","H","a","t","J","w","re","A","d","Q","W","K","X","b","h","Y","rr","er","ar","nr","o","u","s","c","g","C","_","M","tr","f","x","l","Z","D","U","ee","E","P","ir","O","S","or","R","z","ur","sr","cr","lr","y","pr","vr","hr","L","dr","fr","xr","gr","mr","_r","Sr","yr","N","$r","wr","Ar","br","Cr","Mr","Er","B","Pr","Or","Rr","zr","jr","Nr","I","kr","Br","Ir","Fr","Lr","Zr","F","Dr","Ur","Vr","Gr","Tr","qr","Hr","Jr","Qr","Wr","Kr","Xr","Yr","$","_match","zeptomatch","path","pattern","_DRIVE_LETTER_START_RE","normalizeWindowsPath","input","_UNC_REGEX","_IS_ABSOLUTE_RE","_DRIVE_LETTER_RE","_ROOT_FOLDER_RE","_EXTNAME_RE","_PATH_ROOT_RE","sep","normalize","isUNCPath","isPathAbsolute","isAbsolute","trailingSeparator","normalizeString","join","segments","seg","pathTrailing","segLeading","cwd","resolve","arguments_","argument","resolvedPath","resolvedAbsolute","index","allowAboveRoot","res","lastSegmentLength","lastSlash","dots","char","lastSlashIndex","toNamespacedPath","extname","relative","from","to","_from","_to","_fromCopy","segment","dirname","format","ext","basename","extension","lastSegment","val","parse","base","matchesGlob","_path","delimiter","_platforms","mix","del","prop","posix","win32","LogLevel","LogLevel2","LogLevelString","LogLevelString2","Format","Format2","isColorSupported","formatter","open","close","replace","string","replaceClose","start","end","nextIndex","createColors","enabled","pc","logLevelStringToLogLevelMap","logLevelToLogLevelStringMap","availableLogLevelStrings","logLevelToColorMap","availableLogLevels","availableFormats","parseErrorStacks","errorLike","item","isErrorLike","err","newLog","logLevel","context","fields","timeFormatter","fieldsObj","now","newErrorLog","errorStack","log","prettyFormatValue","value","valueString","toPrettyString","messagePartials","contextString","fieldsEntries","key","shouldOutputDebugLevelLogWhenLogLevelIsOneOf","shouldOutputVerboseLevelLogWhenLogLevelIsOneOf","shouldOutputLogLevelLogWhenLogLevelIsOneOf","shouldOutputWarningLevelLogWhenLogLevelIsOneOf","shouldOutputErrorLevelLogWhenLogLevelIsOneOf","isBrowser","shouldUseHyperlink","getGlobalFormat","withHyperlink","basePath","GLOBAL_CONFIG","inputDate","getGlobalLogLevel","setGlobalLogLevel","getGlobalTimeFormatter","createLogg","logObj","logger","context2","logLevelString","stacks","fn","getEffectiveLogLevel","getEffectiveFormat","getEffectiveTimeFormatter","mergeOptionalParams","optionalParams","outputToConsole","raw","consoleMethod","mergedFields","fieldsToOutput","output","logLevelCheckMap","consoleMethodMap","logWithLevel","levelString","shouldOutput","stack","createLogger","currentStack","ErrorStackParser","useLogger","logBuffer","MAX_BUFFER_SIZE","flushLogs","logsToSend","uploadLogsToCLS","logs","cleanupCLS","configCache","fetchSdkConfig","version","configUrl","response","data","config","clearSdkConfigCache","AvatarCoreMemoryManager","wasmModule","arrayBuffer","size","ptr","uint8Array","configPtr","flameModel","flameTemplate","teethPb","teethNpz","offset","shapeBuffer","plyBuffer","characterId","dataPtr","shape","ply","paramsPtr","byteOffset","shape_params","expr_params","rotation","translation","neck_pose","jaw_pose","eyes_pose","eyelid","has_eyelid","params","arrayPtr","pointsPtr","pointCount","totalFloats","floatOffset","flatData","outputPtr","verticesPtr","vertexCount","facesPtr","faceCount","computeTime","landmarksPtr","landmarkCount","vertices","faces","landmarks","name","AvatarCoreAdapter","options","AvatarCoreModule","errorMessage","requiredFunctions","funcName","testPtr","testValue","frameIndex","templateResources","coreHandle","formattedResources","pointCloudBuffer","startTime","shapePtr","plyPtr","characterHandle","animData","animPtr","animStruct","handle","animHandle","totalFrames","animationFile","animationPath","fullUrl","newHandle","animationHandle","frameCountPtr","errorMsg","frameCount","animInfo","charHandle","shapeResult","vertexCountPtr","faceCountPtr","jointCountPtr","jointCount","pointCountPtr","hasAnimationPtr","hasAnimation","errorCode","errorName","callback","progress","_modelData","_original3DGSPoints","_binding","_flameFaces","flameParams","mb","AvatarKit","appId","configuration","text","prefix","AvatarDownloader","AvatarDownloader$1","token","userId","defaultConfig","event","level","contents","logMethod","_AnimationPlayer","silentAudio","audioUrl","onEnded","reject","streamingPlayer","StreamingAudioPlayer","currentTime","audio","isLast","AnimationPlayer","random","bytes","customRandom","alphabet","defaultSize","getRandom","mask","step","customAlphabet","nanoid","generateConversationId","year","month","day","hours","minutes","seconds","timestamp","nanoId","varint64read","lowBits","highBits","shift","middleByte","varint64write","lo","hi","hasNext","byte","splitBits","hasMoreBits","TWO_PWR_32_DBL","int64FromString","dec","minus","add1e6digit","begin","digit1e6","negate","newBits","int64ToString","bits","negative","uInt64ToString","toUnsigned","low","mid","high","digitA","digitB","digitC","decimalFrom1e7WithLeadingZeros","digit1e7","partial","varint32write","varint32read","readBytes","protoInt64","makeInt64Support","dv","MIN","MAX","UMIN","UMAX","bi","assertInt64String","assertUInt64String","symbol","getTextEncoding","te","td","WireType","FLOAT32_MAX","FLOAT32_MIN","UINT32_MAX","INT32_MAX","INT32_MIN","BinaryWriter","encodeUtf8","chunk","prev","fieldNo","type","assertUInt32","assertInt32","assertFloat32","view","tc","sign","BinaryReader","buf","decodeUtf8","tag","wireType","wt","zze","arg","MessageType","messageTypeFromJSON","object","messageTypeToJSON","createBaseClientAudioInputData","ClientAudioInputData","writer","length","reader","isSet","bytesFromBase64","base64FromBytes","createBaseFlame","Flame","end2","createBaseFlameAnimation","FlameAnimation","createBaseServerResponseAnimationData","ServerResponseAnimationData","createBaseErrorInfo","ErrorInfo","createBaseMessage","Message","b64","bin","arr","EventEmitter","handler","handlers","AnimationWebSocketClient","url","conversationId","audioData","MessageCodec","delay","NetworkLayer","dataController","CONNECTION_TIMEOUT_MS","timeoutId","connectPromise","timeoutPromise","metrics","shouldReportMetrics","currentDuration","reqId","animation","keyframes","AvatarController","avatar","connected","networkConversationId","initialAudioChunks","initialKeyframes","lastChunkIndex","expectedConversationId","callbacks","fps","playLoop","audioTime","arrayIndex","framesToKeep","framesToRemove","currentFrame","avatarCore","splatData","monitorLoop","listeners","errorToMessage","downloadResource","headers","msg","MAX_CACHE_SIZE","_resourceCache","downloadResourceCached","cached","oldestKey","baseAssetsPath","flameResources","progressCallback","templateFiles","totalFiles","loadedFiles","updateProgress","filename","loaded","promises","resourceName","buffer","cdnBaseUrl","cameraUrl","cameraSettings","shapeUrl","pointCloudUrl","idleAnimationUrl","reason","filesToLoad","characterData","downloadPromises","optional","preloadCameraSettings","info","dataMessage","_AvatarManager","onProgress","externalProgress","AvatarManager","depthBuffer","depthInt","indices0","indices1","counts","BUCKET_SIZE","MASK","sortSplats","packedData","cameraPosition","cameraForward","splatCount","depths","depthsInt","idx0","idx1","out","cnt","cx","cy","cz","fx","fy","fz","radixPass","keys","indicesIn","indicesOut","count","sum","idx","FLOATS_PER_POINT","reorderedBuffer","reorderPackedData","sortOrder","requiredLength","srcOffset","dstOffset","fragmentShaderSource","vertexShaderSource","WebGLRenderer","canvas","backgroundColor","gl","program","quadVertices","_sortOrder","floatsPerSplat","bytesPerFloat","strideBytes","viewMatrix","projectionMatrix","screenSize","vertexShader","fragmentShader","lose","renderShaderCode","WebGPURenderer","adapter","uniformBufferSize","shaderModule","uniformBindGroupLayout","storageBindGroupLayout","pipelineLayout","vertexBufferLayouts","indexBufferSize","sortOrderChanged","textureView","commandEncoder","renderPass","uniformData","float32View","uint32View","RenderSystem","cameraConfig","preferBackend","startSort","sortTime","reorderedData","startRender","renderTime","position","target","up","fov","aspect","near","far","fovYRadians","zs","fLen","rLen","px","py","pz","lerpArrays","linearLerp","easedProgress","fromEyelid","toEyelid","generateTransitionFrames","durationMs","steps","frames","AvatarView","container","kitConfig","mode","ensureLen","fromFixed","toFixed","exprLen","aligned","idle0Params","containerWidth","containerHeight","dpr","cameraInfo","defaultCamera","characterCameraSettings","candidateSettings","source","fallback","safeValue","fallbackValue","translationX","translationY","translationZ","yaw","fovRadians","hasCustomTranslation","hasCustomFov","hasCustomRotation","sinYaw","cosYaw","forward","forwardLength","normalizedForward","derivedCamera","neutralParams","lastTime","frameInterval","renderFrame","state","elapsed","sd","newState","oldState","idleParams","idleFrameProto","firstSpeaking","lastSpeaking","idleFirstProto"],"mappings":"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","x_google_ignoreList":[6,7,8,9,10,18,20,21,22,23]}