sentifyd-bot 1.5.1 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,16 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ ## [1.6.0] - 2026-06-17
6
+
7
+ ### Added
8
+ - Pause button to put the avatar on hold without ending the conversation.
9
+ - Rich text formatting in chat messages (bold, lists, links, code, and headings).
10
+ - New avatar moods for more expressive, lifelike animations.
11
+
12
+ ### Fixed
13
+ - More reliable cleanup between sessions for smoother, longer-running performance.
14
+
5
15
  ## [1.5.1] - 2026-02-10
6
16
 
7
17
  ### Changed
@@ -0,0 +1 @@
1
+ import{C as t,c as e}from"./index-CUwL7tUc.js";import{AvatarVideoFormat as n,AvatarConfig as i,AvatarSynthesizer as s,ResultReason as o}from"microsoft-cognitiveservices-speech-sdk";import{L as c}from"./LiveCaptions-BHIQ1Gwu.js";const a={BASE_URL:"/",DEV:!1,MODE:"production",PROD:!0,SSR:!1};class r{constructor(t={}){this.backendUrl=t.backendUrl||"",this.character=t.character||"lisa",this.style=t.style||"casual-sitting",this.voice=t.voice||"en-US-AvaNeural",this.speechConfig=t.speechConfig,this.auth=t.auth,this.peerConnection=null,this.avatarSynthesizer=null,this.videoElement=null,this.audioElement=null,this.onConnected=t.onConnected||(()=>{}),this.onDisconnected=t.onDisconnected||(()=>{}),this.onTrack=t.onTrack||(()=>{}),this.onError=t.onError||(t=>{}),this.onSessionLost=t.onSessionLost||(()=>{}),this.onWebRtcEvent=t.onWebRtcEvent||(()=>{}),this._connected=!1,this._connecting=!1,this._reconnecting=!1,this._permanentFailure=!1,this._wasThrottled=!1,this._eventDataChannel=null,this._onDataChannelHandler=null,this._connectPromise=null,this._connectionAttemptId=0,this._lastDisconnectTime=null,this._autoplayBlocked=!1}async _safePlayMediaElement(t,e){try{if(!t)return;const e=t.play?.();return e&&"function"==typeof e.then&&await e,!0}catch(n){return this._autoplayBlocked=!0,!1}}get wasAutoplayBlocked(){return this._autoplayBlocked}async resumeMediaPlayback(){if(!this._autoplayBlocked)return!0;let t=!0;if(this.videoElement?.paused&&this.videoElement?.srcObject){const e=await this._safePlayMediaElement(this.videoElement,"video");t=t&&e}if(this.audioElement?.paused&&this.audioElement?.srcObject){const e=await this._safePlayMediaElement(this.audioElement,"audio");t=t&&e}return t&&(this._autoplayBlocked=!1),t}get isConnected(){return this._connected}get isConnecting(){return this._connecting}get isPermanentlyFailed(){return this._permanentFailure}setVideoElement(t){this.videoElement=t}setAudioElement(t){this.audioElement=t}_buildApiUrl(t){try{const e=new URL(this.backendUrl);return e.pathname=e.pathname.replace(/\/$/,"")+t,e.toString()}catch(e){return this.backendUrl.split("?")[0].replace(/\/$/,"")+t}}async getIceToken(){if(this.auth?.callSentifydApi){const t=await this.auth.callSentifydApi("/api/azure-avatar/ice-token","GET");return t?.data??t}const t=this._buildApiUrl("/api/azure-avatar/ice-token"),e=await fetch(t);if(404===e.status)throw this._permanentFailure=!0,new Error("Azure Avatar API endpoint not found - backend may not support Azure Avatars");if(500===e.status){const t=await e.text().catch(()=>"Internal server error");(t.includes("not implemented")||t.includes("not supported")||t.includes("not configured"))&&(this._permanentFailure=!0);const n=t.includes("not configured")?" (service not configured)":t.includes("not implemented")?" (not implemented)":t.includes("not supported")?" (not supported)":"";throw new Error(`Azure Avatar backend error${n}`)}if(501===e.status||503===e.status)throw this._permanentFailure=!0,new Error("Azure Avatar service not configured on backend");if(!e.ok)throw new Error(`Failed to get ICE token: ${e.status}`);return await e.json()}async connect(){return this._connectPromise||(this._connectPromise=(async()=>{if(this._connected)return this._connectPromise=null,!0;if(this._permanentFailure)return this._connectPromise=null,!1;this._connectionAttemptId++;const t=this._connectionAttemptId;this._connecting=!0;try{return await this._doConnect(t)}finally{this._connectionAttemptId===t&&(this._connectPromise=null)}})()),this._connectPromise}async _doConnect(t){try{if(!this.speechConfig)throw new Error("speechConfig is required to start AvatarSynthesizer");if(this._lastDisconnectTime){const t=5e3-(Date.now()-this._lastDisconnectTime);t>0&&await new Promise(e=>setTimeout(e,t))}const t=await this.getIceToken(),c="true"===(a||{}).VITE_ENABLE_PUBLIC_STUN_FALLBACKS,r=(Array.isArray(t?.Urls)?t.Urls:[]).filter(t=>"string"==typeof t).map(t=>t.trim()).filter(t=>/^(turns?):/i.test(t));if(0===r.length)throw new Error("ICE token did not include any TURN URLs (expected turn:/turns: only)");const h=[{urls:r,username:t.Username,credential:t.Password}];c&&h.push({urls:"stun:stun.l.google.com:19302"},{urls:"stun:stun1.l.google.com:19302"},{urls:"stun:global.stun.twilio.com:3478"}),this.peerConnection=new RTCPeerConnection({iceServers:h,iceTransportPolicy:c?"all":"relay"}),this._onDataChannelHandler=t=>{try{const e=t?.channel;if(!e)return;this._eventDataChannel=e,e.onmessage=async t=>{try{const e=t?.data;let n=null;if("string"==typeof e?n=e:e&&"undefined"!=typeof Blob&&e instanceof Blob?n=await e.text():e instanceof ArrayBuffer&&(n=new TextDecoder("utf-8").decode(new Uint8Array(e))),!n)return;const i=JSON.parse(n),s=i?.event?.eventType||i?.eventType||null;if(!s)return;this.onWebRtcEvent({eventType:s,raw:i})}catch(e){}}}catch(e){}},this.peerConnection.addEventListener("datachannel",this._onDataChannelHandler);try{this.peerConnection.createDataChannel("eventChannel")}catch(e){}this.peerConnection.ontrack=t=>{"video"===t.track.kind&&this.videoElement?(this.videoElement.srcObject=t.streams[0],this._safePlayMediaElement(this.videoElement,"video")):"audio"===t.track.kind&&this.audioElement&&(this.audioElement.srcObject=t.streams[0],this._safePlayMediaElement(this.audioElement,"audio")),this.onTrack(t)},this.peerConnection.onconnectionstatechange=()=>{const t=this.peerConnection?.connectionState;"connected"===t?(this._connected=!0,this.onConnected()):"disconnected"!==t&&"failed"!==t||(this._connected=!1,this.onDisconnected())},this.peerConnection.oniceconnectionstatechange=()=>{},this.peerConnection.addTransceiver("video",{direction:"sendrecv"}),this.peerConnection.addTransceiver("audio",{direction:"sendrecv"}),this.speechConfig.speechSynthesisVoiceName=this.voice;const d=new n,l=new i(this.character,this.style,d);this.avatarSynthesizer=new s(this.speechConfig,l);const u=await this.avatarSynthesizer.startAvatarAsync(this.peerConnection);if(u?.reason===o.Canceled)throw new Error(u?.errorDetails||"Avatar start canceled");return this._connecting=!1,this._wasThrottled=!1,!0}catch(c){this._connecting=!1;try{await this.disconnect({suppressCallback:!0})}catch(e){}throw(c?.message?.includes("4429")||c?.message?.toLowerCase().includes("throttl")||c?.message?.toLowerCase().includes("concurrent request limit"))&&(this._wasThrottled=!0),this.onError(c),c}}async speak(t,e=null){if(!this.avatarSynthesizer)throw new Error("Cannot speak - AvatarSynthesizer not initialized");e&&(this.voice=e,this.speechConfig.speechSynthesisVoiceName=this.voice);const n=await this.avatarSynthesizer.speakTextAsync(t);if(n?.reason===o.Canceled)throw new Error(n?.errorDetails||"Speech synthesis canceled");return n}async stopSpeaking(){if(this.avatarSynthesizer)try{await this.avatarSynthesizer.stopSpeakingAsync()}catch(t){}}async disconnect(t={}){const{suppressCallback:e=!1}=t;this._connected=!1,this._connecting=!1;try{this._eventDataChannel&&(this._eventDataChannel.onmessage=null,this._eventDataChannel.close?.())}catch(n){}this._eventDataChannel=null;try{this.avatarSynthesizer&&(await this.avatarSynthesizer.stopAvatarAsync(),await this.avatarSynthesizer.close())}catch(i){}finally{this.avatarSynthesizer=null}try{if(this.peerConnection){if(this.peerConnection.ontrack=null,this.peerConnection.onconnectionstatechange=null,this.peerConnection.oniceconnectionstatechange=null,this._onDataChannelHandler)try{this.peerConnection.removeEventListener("datachannel",this._onDataChannelHandler)}catch(n){}this.peerConnection.close()}}catch(i){}finally{this.peerConnection=null,this._onDataChannelHandler=null}if(this.videoElement)try{this.videoElement.srcObject=null}catch(n){}if(this.audioElement)try{this.audioElement.srcObject=null}catch(n){}this._lastDisconnectTime=Date.now(),e||this.onDisconnected()}async reconnect(){if(this._permanentFailure)return!1;if(this._reconnecting)return!1;if(this._connectPromise)try{return await this._connectPromise}catch(t){}this._reconnecting=!0;try{await this.disconnect({suppressCallback:!0});const t=5e3,e=7e3,n=this._wasThrottled?e:t,i=this._lastDisconnectTime?Date.now()-this._lastDisconnectTime:0,s=Math.max(0,n-i);if(s>0&&await new Promise(t=>setTimeout(t,s)),!(await this.connect()))return!1;const o=async(t=1e4)=>{const e=Date.now();for(;Date.now()-e<t;){if(this._connected)return!0;const t=this.peerConnection?.connectionState;if("failed"===t||"closed"===t)return!1;await new Promise(t=>setTimeout(t,200))}return this._connected};return await o()}catch(e){return!1}finally{this._reconnecting=!1}}}class h extends t{static isAzureAvatar=!0;isAzureAvatar=!0;isVideoAvatar=!0;constructor(t,e){super("talkingAvatar",{autoReconnect:!1}),this.bus=t,this.avatarOrchestrator=e,this.connection=null,this.videoElement=null,this.audioElement=null,this.currentTurnId=null,this.isStoppingSpeaking=!1,this._endedTurns=/* @__PURE__ */new Set,this.conversationStreamActive=!1,this._audioStartSent=!1,this._busHandlers=[],this._isSpeaking=!1,this._audioTrack=null,this._audioContext=null,this._audioAnalyser=null,this._audioSourceNode=null,this._speechMonitorIntervalId=null,this._speechMonitorState=null,this._speechCompletionTimeoutId=null,this._speechHardTimeoutId=null,this._lastWebRtcEventType=null,this._initializing=!1,this._initRetryCount=0,this._maxInitRetries=3,this._initRetryDelayMs=5e3,this._initRetryTimeoutId=null,this._pendingInitParams=null,this._reconnectRetryCount=0,this._maxReconnectRetries=3,this._reconnectRetryDelayMs=5e3,this._reconnectRetryTimeoutId=null,this._lastDisconnectTime=null,this.suspendTime=null,this._lastConnectedTime=null,this._connectionCooldownMs=5e3,this._idleDisconnectTimeoutId=null,this._idleDisconnectArmSeq=0,this._idleDisconnectArmId=null,this._idleDisconnectArmedAt=null,this._disconnectReason=null,this._disconnecting=!1,this._suspendGracePeriodTimeoutId=null,this._suspendGracePeriodMs=3e4,this._pendingSuspendReason=null,this._pendingMessage=null,this._readyToSpeak=!1,this.liveCaptions=new c,this.backendUrl=null,this.character="lisa",this.style="casual-sitting",this.voice="en-US-AvaNeural"}_videoDebugEnabled(){try{return!0===e?.videoAvatar?.debug||!0===e?.test?.enableDiagnostics}catch(t){return!1}}_logIdleTimer(t,e=null){this._videoDebugEnabled()}_isStreamActive(){const t=this.connection;if(!t)return!1;const e=t?.peerConnection?.connectionState,n=t?.peerConnection?.iceConnectionState;return!0===t.isConnected||"connected"===e||"connected"===n}_clearIdleDisconnectTimer(){if(!this._idleDisconnectTimeoutId)return;const t=this._idleDisconnectArmId,e=this._idleDisconnectArmedAt;try{clearTimeout(this._idleDisconnectTimeoutId)}catch(i){}this._idleDisconnectTimeoutId=null,this._idleDisconnectArmId=null,this._idleDisconnectArmedAt=null;const n="number"==typeof e?Date.now()-e:null;this._logIdleTimer("AzureTalkingAvatar: Cleared idle disconnect timer",{armId:t,elapsedMs:n})}_clearSuspendGracePeriodTimer(){if(this._suspendGracePeriodTimeoutId){try{clearTimeout(this._suspendGracePeriodTimeoutId)}catch(t){}this._suspendGracePeriodTimeoutId=null,this._pendingSuspendReason=null}}disarmIdleDisconnect(){this._clearIdleDisconnectTimer()}armIdleDisconnect(t=null){const n=e?.videoAvatar??{};if(!1===n.idleDisconnectEnabled)return;if(null!==t&&(!Number.isFinite(t)||t<=0))return;const i=Number(t??n.idleDisconnectMs??6e4);if(!Number.isFinite(i)||i<=0)return;this._clearIdleDisconnectTimer(),this._idleDisconnectArmSeq=(this._idleDisconnectArmSeq||0)+1,this._idleDisconnectArmId=`idle-${this._idleDisconnectArmSeq}-${Date.now()}`,this._idleDisconnectArmedAt=Date.now();const s=this._idleDisconnectArmId;this._logIdleTimer("AzureTalkingAvatar: Armed idle disconnect timer",{armId:s,idleMs:i,conversationStreamActive:this.conversationStreamActive,disconnectReason:this._disconnectReason,isStreamActive:this._isStreamActive?.()}),this._idleDisconnectTimeoutId=setTimeout(()=>{try{if(this._logIdleTimer("AzureTalkingAvatar: Idle disconnect timer fired",{armId:s,idleMs:i,conversationStreamActive:this.conversationStreamActive,disconnectReason:this._disconnectReason,isStreamActive:this._isStreamActive?.()}),!this._isStreamActive())return;this.disconnectForIdle().catch(()=>{})}catch(t){}},i)}async disconnectForIdle(){this._disconnectReason="idle",this.autoReconnect=!1,this._clearIdleDisconnectTimer(),this._clearSuspendGracePeriodTimer(),this.blocking=!1;try{await(this.interruptSpeaking?.())}catch(t){}try{this.connection&&await this.connection.disconnect()}catch(t){}this.setDisconnected();try{this.bus?.emit?.("event_status_Avatar_RenderingStateChanged",{running:!1,reason:"idle"})}catch(t){}try{this.bus?.emit?.("event_status_VideoAvatar_IdleDisconnected",{reason:"idle"})}catch(t){}}async disconnectForVisibility(t="visibility"){if(this.connection?.isConnected||this._isStreamActive()){this._disconnecting=!0,this._disconnectReason=t,"visibility"!==t&&(this.blocking=!1),this.autoReconnect=!1,this._clearIdleDisconnectTimer();try{await(this.interruptSpeaking?.())}catch(e){}try{this.connection&&await this.connection.disconnect()}catch(e){}this.setDisconnected(),this._lastDisconnectTime=Date.now(),this._disconnecting=!1;try{this.bus?.emit?.("event_status_Avatar_RenderingStateChanged",{running:!1,reason:t})}catch(e){}}else"visibility"!==t&&(this.blocking=!1)}async userReconnect(){if(this._disconnectReason=null,this.autoReconnect=!0,this.blocking=!0,this._clearIdleDisconnectTimer(),this._clearSuspendGracePeriodTimer(),!this.conversationStreamActive){const t=this.avatarOrchestrator?.getSnapshot?.()?.matches?.("lifecycle.conversation.inProgress");t&&(this.conversationStreamActive=!0)}await this.reconnect()}_stopSpeechMonitor(){try{this._speechMonitorIntervalId&&clearInterval(this._speechMonitorIntervalId)}catch(t){}this._speechMonitorIntervalId=null,this._speechMonitorState=null}_clearSpeechTimeouts(){try{this._speechCompletionTimeoutId&&clearTimeout(this._speechCompletionTimeoutId)}catch(t){}try{this._speechHardTimeoutId&&clearTimeout(this._speechHardTimeoutId)}catch(t){}this._speechCompletionTimeoutId=null,this._speechHardTimeoutId=null}_ensureAudioAnalyserFromStream(t){if(t&&!(this._audioAnalyser&&this._audioContext&&this._audioSourceNode))try{const e=window.AudioContext||window.webkitAudioContext;if(!e)return;this._audioContext=this._audioContext||new e;const n=this._audioContext.createMediaStreamSource(t),i=this._audioContext.createAnalyser();i.fftSize=1024,i.smoothingTimeConstant=.8,n.connect(i),this._audioSourceNode=n,this._audioAnalyser=i}catch(e){}}_startSpeechMonitor(t){if(this._stopSpeechMonitor(),!this._audioAnalyser)return;const e=new Uint8Array(this._audioAnalyser.fftSize),n={seenLoud:!1,lastLoudAt:Date.now(),startedAt:Date.now(),turnId:t};this._speechMonitorState=n;const i=()=>{this._audioAnalyser.getByteTimeDomainData(e);let t=0;for(let n=0;n<e.length;n++){const i=(e[n]-128)/128;t+=i*i}return Math.sqrt(t/e.length)};this._speechMonitorIntervalId=setInterval(()=>{try{if(!this._isSpeaking)return;const t=this.currentTurnId;if(n.turnId&&t&&n.turnId!==t)return;const e=i(),s=Date.now();if(e>=.005)return n.seenLoud=!0,void(n.lastLoudAt=s);n.seenLoud&&s-n.lastLoudAt>=800&&(this._isSpeaking=!1,this._stopSpeechMonitor(),this._clearSpeechTimeouts(),this.handleAudioEndOnce(n.turnId??t,"silence_detected"))}catch(t){this._stopSpeechMonitor()}},100)}_armSpeechFailSafes(t,e){this._clearSpeechTimeouts();const n=Date.now();this._speechHardTimeoutId=setTimeout(()=>{const e=this.currentTurnId;this._isSpeaking&&(t&&e&&t!==e||(this._isSpeaking=!1,this._stopSpeechMonitor(),this._clearSpeechTimeouts(),this.handleAudioEndOnce(t??e,"hard_timeout")))},9e4),this._speechMonitorState={...this._speechMonitorState||{},startedAt:n,turnId:t,textLength:"string"==typeof e?e.length:null}}async init(t,e,n={}){if(!this._initializing&&!this.connection?.isConnected){this._initializing=!0;try{if(this.connection){try{await this.connection.disconnect()}catch(i){}this.connection=null}this.backendUrl=t.azureBackendUrl||"http://localhost:5000",this.character=t.azureCharacter||"lisa",this.style=t.azureStyle||"casual-sitting",this.voice=t.voice||"en-US-AvaNeural",this._createVideoElements(e);const s=n?.speechConfig,o=n?.auth;if(!s)throw new Error("AzureTalkingAvatar requires speechConfig. Initialize VoiceBot before initializing the Azure avatar.");this.connection=new r({backendUrl:this.backendUrl,character:this.character,style:this.style,voice:this.voice,speechConfig:s,auth:o,onConnected:()=>this._onConnected(),onDisconnected:()=>this._onDisconnected(),onError:t=>this._onError(t),onTrack:t=>this._onTrack(t),onWebRtcEvent:t=>this._onWebRtcEvent(t),onSessionLost:()=>this._onSessionLost()}),this.connection.setVideoElement(this.videoElement),this.connection.setAudioElement(this.audioElement),await this.connection.connect(),this.addEventListeners(),this.setConnected()}catch(s){if((s?.message?.includes("4429")||s?.message?.toLowerCase().includes("throttl")||s?.message?.toLowerCase().includes("concurrent request limit"))&&this._initRetryCount<this._maxInitRetries){this._initRetryCount++;const i=this._initRetryDelayMs*this._initRetryCount;return this._pendingInitParams={avatarItem:t,avatarContainer:e,initOptions:n},this.blocking=!1,this.setConnecting(),void(this._initRetryTimeoutId=setTimeout(async()=>{if(this._initRetryTimeoutId=null,this._initializing=!1,this._pendingInitParams){const{avatarItem:e,avatarContainer:n,initOptions:i}=this._pendingInitParams;this._pendingInitParams=null,this.blocking=!0;try{await this.init(e,n,i)}catch(t){}}},i))}throw this.setFailed(),new Error("Error initializing AzureTalkingAvatar: "+s.message)}finally{this._initRetryTimeoutId||(this._initializing=!1)}}}_createVideoElements(t){t.innerHTML="",t.style.cssText="\n width: 100%;\n height: 100%;\n position: relative;\n overflow: hidden;\n ";const e=document.createElement("div");e.className="azure-avatar-wrapper",e.style.cssText="\n width: 100%;\n height: 100%;\n position: absolute;\n top: 0;\n left: 0;\n background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);\n overflow: hidden;\n ",this.videoElement=document.createElement("video"),this.videoElement.autoplay=!0,this.videoElement.playsInline=!0,this.videoElement.muted=!1,this.videoElement.style.cssText="\n width: 100%;\n height: 100%;\n object-fit: cover;\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n min-width: 100%;\n min-height: 100%;\n ",this.audioElement=document.createElement("audio"),this.audioElement.autoplay=!0,this.audioElement.style.display="none",e.appendChild(this.videoElement),e.appendChild(this.audioElement),t.appendChild(e)}_onConnected(){this.conversationStreamActive=!0,this._isSpeaking=!1,this._clearIdleDisconnectTimer();try{this.bus?.emit?.("event_status_AzureAvatar_WebRtcConnectionChanged",{connected:!0})}catch(t){}this._lastConnectedTime=Date.now(),this._initRetryCount=0,this._reconnectRetryCount=0,this._pendingInitParams=null,this._reconnectRetryTimeoutId&&(clearTimeout(this._reconnectRetryTimeoutId),this._reconnectRetryTimeoutId=null),this.blocking=!0,this.setConnected(),this._emitRenderingStateWhenVideoReady()}_emitRenderingStateWhenVideoReady(){const t=()=>{if(this.isRenderingActive())try{this.bus?.emit?.("event_status_Avatar_RenderingStateChanged",{running:!0,reason:"connected"})}catch(e){}else this.connection?.isConnected&&setTimeout(t,100)};t()}_onDisconnected(){"idle"===this._disconnectReason||"visibility"===this._disconnectReason||"session_lost"===this._disconnectReason||(this.conversationStreamActive=!1),this._isSpeaking=!1,this._clearIdleDisconnectTimer();try{this.bus?.emit?.("event_status_AzureAvatar_WebRtcConnectionChanged",{connected:!1})}catch(t){}this.blocking=!1,this.setDisconnected()}_onError(t){this._isSpeaking=!1,this._clearIdleDisconnectTimer(),this.bus?.emit?.("event_status_Avatar_Error",{error:t.message}),this.setFailed()}async _onSessionLost(){this._isSpeaking=!1,this._stopSpeechMonitor(),this._clearSpeechTimeouts(),this._clearIdleDisconnectTimer(),this._clearSuspendGracePeriodTimer(),this.disarmIdleDisconnect(),this._disconnectReason="session_lost",this.autoReconnect=!1,this.blocking=!0,this._reconnectRetryTimeoutId&&(clearTimeout(this._reconnectRetryTimeoutId),this._reconnectRetryTimeoutId=null);try{await(this.connection?.disconnect?.())}catch(t){}this._lastDisconnectTime=Date.now();try{this.bus?.emit?.("event_status_Avatar_Error",{error:"Avatar session lost. Click reconnect to resume.",recoverable:!0})}catch(t){}this.setDisconnected()}_onTrack(t){try{if("audio"===t?.track?.kind){this._audioTrack=t.track;const e=Array.isArray(t.streams)?t.streams[0]:null;e&&this._ensureAudioAnalyserFromStream(e),this._audioTrack.onended=()=>{try{this._isSpeaking&&(this._isSpeaking=!1,this._stopSpeechMonitor(),this.handleAudioEndOnce(this.currentTurnId,"track_ended"))}catch(t){}}}}catch(e){}}_onWebRtcEvent(t){try{const e=t?.eventType;if(!e)return;if(this._lastWebRtcEventType=e,"EVENT_TYPE_TURN_END"===e||"EVENT_TYPE_SWITCH_TO_IDLE"===e||"EVENT_TYPE_SESSION_END"===e){const t=this.currentTurnId;if(!t)return;if(this._endedTurns.has(t??"__null__"))return;this._isSpeaking=!1,this._stopSpeechMonitor(),this._clearSpeechTimeouts(),this.handleAudioEndOnce(t,`webrtc_${e.toLowerCase()}`)}}catch(e){}}isRenderingActive(){const t=this.connection;if(!t)return!1;const e=t?.peerConnection?.connectionState,n=t?.peerConnection?.iceConnectionState;if(!0!==t.isConnected&&"connected"!==e&&"connected"!==n)return!1;const i=this.videoElement;if(!i)return!1;const s=!!i.srcObject,o="number"!=typeof i.videoWidth||"number"!=typeof i.videoHeight||i.videoWidth>0&&i.videoHeight>0,c="number"!=typeof i.readyState||i.readyState>=2;return s&&c&&o}async startConversationStream(){if(this.conversationStreamActive||(this.conversationStreamActive=!0),!this.isRenderingActive()){this._disconnectReason=null,this._clearIdleDisconnectTimer(),this._clearSuspendGracePeriodTimer(),this.blocking=!0;try{await this.reconnect();const t=5e3,e=100;let n=0;for(;!this.isRenderingActive()&&n<t;)await new Promise(t=>setTimeout(t,e)),n+=e;this.isRenderingActive()}catch(t){}}}async stopConversationStream(){if(this.conversationStreamActive=!1,this.disarmIdleDisconnect(),this._clearSuspendGracePeriodTimer(),this.connection)try{await this.connection.disconnect()}catch(t){}this.bus?.emit?.("event_status_Avatar_RenderingStateChanged",{running:!1,reason:"conversation_ended"})}startTurn(t){this.currentTurnId=t,this._audioStartSent=!1,this._endedTurns.delete(t)}setPendingMessage(t,e){if(this._pendingMessage={text:t,turnId:e},this._readyToSpeak&&this.isRenderingActive()&&!this._isSpeaking){const t=this._pendingMessage;this._pendingMessage=null,this._readyToSpeak=!1,this.currentTurnId=t?.turnId??this.currentTurnId,this._audioStartSent=!1,this._endedTurns.delete(t?.turnId??"__null__"),this.speak(t?.text,t?.turnId)}}async startStreaming(t,e,n){this.currentTurnId=n,this.isStoppingSpeaking=!1,this._audioStartSent=!1,this._endedTurns.delete(n??"__null__"),this._readyToSpeak=!0;try{t?.cancel?.()}catch(i){}try{e?.cancel?.()}catch(i){}if(!this.isRenderingActive()){const t=5e3,e=100;let i=0;for(;!this.isRenderingActive()&&i<t;)await new Promise(t=>setTimeout(t,e)),i+=e;if(!this.isRenderingActive())return this.handleAudioEndOnce(n,"suppressed_timeout"),this.currentTurnId=null,void(this._pendingMessage=null)}if(this._pendingMessage&&this._pendingMessage.text){const{text:t}=this._pendingMessage;return this._pendingMessage=null,this._readyToSpeak=!1,void(await this.speak(t,n))}}async speak(t,e=null){if(!this.connection?.isConnected)return;const n=e||this.currentTurnId;this._audioStartSent=!1,this._endedTurns.delete(n??"__null__"),this._stopSpeechMonitor(),this._clearSpeechTimeouts();try{this._isSpeaking=!0,this._armSpeechFailSafes(n,t),this._startSpeechMonitor(n),this._notifyAudioStart(n),await this.connection.speak(t,this.voice),this._speechCompletionTimeoutId=setTimeout(()=>{const t=this.currentTurnId;this._isSpeaking&&(n&&t&&n!==t||(this._isSpeaking=!1,this._stopSpeechMonitor(),this._clearSpeechTimeouts(),this.handleAudioEndOnce(n??t,"completed_fallback")))},1500)}catch(i){this._isSpeaking=!1,this._stopSpeechMonitor(),this._clearSpeechTimeouts(),this.handleAudioEndOnce(n,"error")}}startStreamPump(t){}startLipsyncPump(t){}_notifyAudioStart(t,e=null){if(this._audioStartSent)return;this._audioStartSent=!0;const n=t?{turnId:t,audioStartTime:e}:{audioStartTime:e||Date.now()},i=()=>{try{this.avatarOrchestrator?.sendEvent("AUDIO_START",n)}catch(t){}};"function"==typeof queueMicrotask?queueMicrotask(i):setTimeout(i,0)}handleAudioEndOnce(t,e){const n=t??"__null__";this._endedTurns.has(n)||(this._endedTurns.add(n),this._stopSpeechMonitor(),this._clearSpeechTimeouts(),this.avatarOrchestrator.sendEvent("AUDIO_END",{turnId:t,reason:e}))}async interruptSpeaking(){if(this.isStoppingSpeaking)return;if(this.isStoppingSpeaking=!0,this._isSpeaking=!1,this._stopSpeechMonitor(),this._clearSpeechTimeouts(),this.connection?.isConnected)try{await this.connection.stopSpeaking()}catch(e){}try{this.liveCaptions?.clearCaptions?.()}catch(n){}try{this.bus?.emit?.("event_command_UI_ClearCaptions")}catch(n){}const t=this.currentTurnId;t&&(this.handleAudioEndOnce(t,"interrupted"),this.currentTurnId=null),this.isStoppingSpeaking=!1}async prepareForNewUserTurn(){(this._isSpeaking||this.connection?.isConnected)&&await this.interruptSpeaking()}finalizeTurn(){}async suspendRendering(t="hidden"){if(!this.connection?.isConnected&&!this._isStreamActive())return"visibility"!==t&&(this.blocking=!1),void(this._disconnectReason=t);this._suspendGracePeriodTimeoutId?this._pendingSuspendReason=t:(this.suspendTime=Date.now(),this._pendingSuspendReason=t,this._suspendGracePeriodTimeoutId=setTimeout(async()=>{this._suspendGracePeriodTimeoutId=null;const e=this._pendingSuspendReason||t;this._pendingSuspendReason=null,await this.disconnectForVisibility(e)},this._suspendGracePeriodMs))}async resumeRendering(t={}){if(!this._resumeInProgress){this._resumeInProgress=!0;try{await this._doResumeRendering(t)}finally{this._resumeInProgress=!1}}}async _doResumeRendering(t={}){const{forceReconnect:e=!1}=t,n=!!this._suspendGracePeriodTimeoutId,i=this._disconnectReason;if(n&&this._clearSuspendGracePeriodTimer(),this.blocking=!0,this._pendingSuspendReason=null,this._disconnectReason=null,n&&(this.connection?.isConnected||this._isStreamActive()))return;if(this._disconnecting){const t=2e3,e=50;let n=0;for(;this._disconnecting&&n<t;)await new Promise(t=>setTimeout(t,e)),n+=e}if((this.connection?.isConnected||this.connection?.isConnecting)&&this._isStreamActive())return;if(!this._isStreamActive())if(e||"visibility"===i||"conditions-change"===i)try{await this.reconnect({forceReconnect:!!e})}catch(r){if(this.conversationStreamActive)try{this.bus?.emit?.("event_status_VideoAvatar_IdleDisconnected",{reason:"reconnect_failed"})}catch(h){}}else if("idle"===i&&this.conversationStreamActive)try{this.bus?.emit?.("event_status_VideoAvatar_IdleDisconnected",{reason:"idle_persist"})}catch(h){}const s=Date.now(),o=!!(this.suspendTime&&s-this.suspendTime>15e3);this.suspendTime=null;const c=t=>new Promise(e=>setTimeout(e,t));try{const t=this.isRenderingActive();!o&&t||this.bus?.emit?.("event_status_Avatar_RenderingStateChanged",{running:!1,reason:"resume_start"})}catch(h){}const a=async t=>{if(!t)return{played:!1,error:null};try{return await t.play(),{played:!t.paused,error:null}}catch(e){return{played:!1,error:e}}};try{const t=await a(this.videoElement);await a(this.audioElement),this.videoElement&&(this.videoElement.paused||this.videoElement.readyState<2)&&((t=>{if(t)try{const e=t.srcObject;if(!e)return;t.srcObject=null,t.srcObject=e}catch(h){}})(this.videoElement),await a(this.videoElement));let e=!1;if(o&&this.videoElement&&!this.videoElement.paused)try{const t=this.videoElement.currentTime;await c(250),e=!(this.videoElement.currentTime>t+.01)}catch(h){}const n=!(!this.videoElement||!(this.videoElement.paused||this.videoElement.readyState<2)),i=(()=>{const e=t?.error,n=e?.name;return"NotAllowedError"===n||"NotSupportedError"===n})(),s=this.connection?.peerConnection?.connectionState,r=this.connection?.peerConnection?.iceConnectionState,d="connected"===s&&("connected"===r||"completed"===r||void 0===r),l="disconnected"===s||"failed"===s||"closed"===s||"disconnected"===r||"failed"===r;if(null==this._disconnectReason&&!i&&(o||n||e)&&this.connection&&(l||!d))try{await Promise.race([this.connection.reconnect(),c(8e3)])}catch(h){}}finally{try{const t=this.isRenderingActive();this.bus?.emit?.("event_status_Avatar_RenderingStateChanged",{running:t,reason:"resume"})}catch(h){}}}get wasAutoplayBlocked(){return this.connection?.wasAutoplayBlocked??!1}resumeAudioContext(){this.connection?.resumeMediaPlayback?this.connection.resumeMediaPlayback().catch(()=>{}):(this.videoElement?.paused&&this.videoElement?.srcObject&&this.videoElement.play().catch(t=>{}),this.audioElement?.paused&&this.audioElement?.srcObject&&this.audioElement.play().catch(t=>{}))}getSpeechAnalyzerNode(){return null}onResize(){}setView(t){}addEventListeners(){const t=(t,e)=>{try{this.bus.on(t,e),this._busHandlers.push([t,e])}catch(n){}};t("event_command_Avatar_DisconnectForIdle",async()=>{try{await this.disconnectForIdle()}catch(t){}}),t("event_command_Avatar_ReconnectAfterIdle",async()=>{try{await this.userReconnect()}catch(t){}}),t("event_command_Avatar_UserReconnect",async()=>{try{await this.userReconnect()}catch(t){}}),t("event_command_Avatar_SetAvatarView",t=>{this.setView(t.view)}),t("event_command_Avatar_SetAvatarMood",t=>{}),t("event_command_Avatar_PlayOrStopGesture",t=>{}),t("event_command_Avatar_PlayOrStopAnimation",t=>{}),t("event_command_Avatar_ControlAvatarLookAt",t=>{}),t("event_command_UI_ClearCaptions",()=>{try{this.liveCaptions?.clearCaptions?.()}catch(t){}})}async reconnect(t={}){const e=!!t?.forceReconnect;if((this.conversationStreamActive||e)&&!this._initializing&&!this.connection?.isConnecting&&!this.connection?.isPermanentlyFailed)if(this.connection?.isConnected)this.setConnected();else if(this.connection){if(this._lastDisconnectTime){const t=Date.now()-this._lastDisconnectTime,e=5e3;if(t<e){const n=e-t;await new Promise(t=>setTimeout(t,n))}}try{await this.connection.reconnect()?(this._reconnectRetryCount=0,this.setConnected()):this.connection.isPermanentlyFailed?this.setFailed():this._scheduleReconnectRetryIfThrottled()}catch(n){n?.message?.includes("4429")||n?.message?.toLowerCase().includes("throttl")||n?.message?.toLowerCase().includes("concurrent request limit")?this._scheduleReconnectRetryIfThrottled():this.connection.isPermanentlyFailed||this.setFailed()}}else this.setFailed()}_scheduleReconnectRetryIfThrottled(){if(this._reconnectRetryCount>=this._maxReconnectRetries)return void this.setFailed();this._reconnectRetryCount++;const t=this._reconnectRetryDelayMs*this._reconnectRetryCount;this.blocking=!1,this.setConnecting(),this._reconnectRetryTimeoutId&&clearTimeout(this._reconnectRetryTimeoutId),this._reconnectRetryTimeoutId=setTimeout(async()=>{this._reconnectRetryTimeoutId=null;try{await this.reconnect()}catch(t){}},t)}destroy(){this._clearIdleDisconnectTimer(),this._clearSuspendGracePeriodTimer(),this._initializing=!1,this._initRetryTimeoutId&&(clearTimeout(this._initRetryTimeoutId),this._initRetryTimeoutId=null),this._pendingInitParams=null,this._reconnectRetryTimeoutId&&(clearTimeout(this._reconnectRetryTimeoutId),this._reconnectRetryTimeoutId=null),this._stopSpeechMonitor();try{this._audioTrack=null}catch(t){}try{this._audioSourceNode?.disconnect?.()}catch(t){}try{this._audioAnalyser=null}catch(t){}try{this._audioSourceNode=null}catch(t){}try{this._audioContext?.close?.()}catch(t){}this._audioContext=null;for(const[e,n]of this._busHandlers)try{this.bus.off(e,n)}catch(t){}this._busHandlers=[],this.connection&&(this.connection.disconnect().catch(()=>{}),this.connection=null),this.videoElement=null,this.audioElement=null,this.setDisconnected()}}export{h as AzureTalkingAvatar};
@@ -1 +1 @@
1
- import{c as t}from"./index-BHDdsuP1.js";import"socket.io-client";import"microsoft-cognitiveservices-speech-sdk";import"js-cookie";import"jwt-decode";import"xstate";const e={maxChars:t.captions.maxCharactersPerCaption,minChars:t.captions.minCharactersPerCaption,softChars:Math.floor(.75*t.captions.maxCharactersPerCaption),pauseBreakMs:350,preferBreakAfter:/[.!?…]|—|–|;/,softBreakAfter:/,|:/};class i{constructor(){this.currentCaptions=[],this.currentCaptionIndex=0,this.displayTimeoutId=null,this.durationTimeoutId=null,this.settleTimeoutId=null,this._playAttemptActive=!1}isBoundaryTypeValid(t){return"SpeechSynthesisBoundaryType.Word"===t.boundaryType||"SpeechSynthesisBoundaryType.Punctuation"===t.boundaryType}handleWordBoundaryEvent(t){if(!this.isBoundaryTypeValid(t))return;const i=t.text,s=t.audioOffset,r=t.duration;let n=this.currentCaptions[this.currentCaptions.length-1],a=null;if(n&&Number.isFinite(n._lastEndOffsetMs)&&(a=s-n._lastEndOffsetMs),!n||function(t,i,s){const r=t.text,n=r.length,a=e.preferBreakAfter.test(r.slice(-1)),o=e.softBreakAfter.test(r.slice(-1));return!!t.isDisplayed||null!=s&&s>=e.pauseBreakMs&&n>=e.minChars||(u=n)+(u?1:0)+i.length>e.maxChars||!!(a&&n>=e.minChars)||!!(n>=e.softChars&&o);var u}(n,i,a)){const t={text:i,audioOffset:s,duration:r,isDisplayed:!1,_lastEndOffsetMs:s+r,get renderText(){return(t=this.text)?` ${t.trim()} `:" ";var t}};this.currentCaptions.push(t)}else n.text=(u=i,((o=n.text).length>0&&!/\s$/.test(o)&&!/^[\s.,!?;:…)]/.test(u)?o+" "+u:o+u).replace(/\s{2,}/g," ")),n.duration+=r,n._lastEndOffsetMs=s+r;var o,u;if(/^[\s.,!?;:…()\[\]{}'"—–-]$/.test(i)){const t=this.currentCaptions[this.currentCaptions.length-1];t&&(t.text=t.text.replace(/\s+([.,!?;:…)\]}])/g,"$1").replace(/([([{])\s+/g,"$1").replace(/\s{2,}/g," ").trim())}}playCaptions(t,e){this._playAttemptActive=!0;const i=async()=>{this._playAttemptActive&&(this.currentCaptions.length>0&&!this.currentCaptions[0].isDisplayed?(this._playAttemptActive=!1,this.startCaptionDisplay(t,e)):(await this.wait(100),i()))};i()}startCaptionDisplay(t,e){this.currentCaptionIndex=0,this.displayTimeoutId&&clearTimeout(this.displayTimeoutId),this.durationTimeoutId&&clearTimeout(this.durationTimeoutId),this.settleTimeoutId&&clearTimeout(this.settleTimeoutId),this.displayTimeoutId=null,this.durationTimeoutId=null,this.settleTimeoutId=null;const i=()=>{if(this.currentCaptionIndex>=this.currentCaptions.length)return void(this.settleTimeoutId=setTimeout((()=>{this.settleTimeoutId=null,this.currentCaptionIndex>=this.currentCaptions.length?t(!1):i()}),100));const s=this.currentCaptions[this.currentCaptionIndex];if(!s)return void t(!1);const r=Math.max(0,s.audioOffset-(performance.now()-e));this.displayTimeoutId=setTimeout((()=>{this.displayTimeoutId=null,this.currentCaptions[this.currentCaptionIndex]?(s.isDisplayed=!0,t(!0,s.text),this.durationTimeoutId=setTimeout((()=>{this.durationTimeoutId=null,this.currentCaptionIndex++,i()}),s.duration)):t(!1)}),r)};i()}clearCaptions(){this._playAttemptActive=!1,this.displayTimeoutId&&clearTimeout(this.displayTimeoutId),this.durationTimeoutId&&clearTimeout(this.durationTimeoutId),this.settleTimeoutId&&clearTimeout(this.settleTimeoutId),this.displayTimeoutId=null,this.durationTimeoutId=null,this.settleTimeoutId=null,this.currentCaptions=[],this.currentCaptionIndex=0}wait(t){return new Promise((e=>setTimeout(e,t)))}destroy(){this.clearCaptions()}}export{i as L};
1
+ import{c as t}from"./index-CUwL7tUc.js";import"socket.io-client";import"microsoft-cognitiveservices-speech-sdk";import"js-cookie";import"jwt-decode";import"xstate";const e={maxChars:t.captions.maxCharactersPerCaption,minChars:t.captions.minCharactersPerCaption,softChars:Math.floor(.75*t.captions.maxCharactersPerCaption),pauseBreakMs:350,preferBreakAfter:/[.!?…]|—|–|;/,softBreakAfter:/,|:/};class i{constructor(){this.currentCaptions=[],this.currentCaptionIndex=0,this.displayTimeoutId=null,this.durationTimeoutId=null,this.settleTimeoutId=null,this._playAttemptActive=!1}isBoundaryTypeValid(t){return"SpeechSynthesisBoundaryType.Word"===t.boundaryType||"SpeechSynthesisBoundaryType.Punctuation"===t.boundaryType}handleWordBoundaryEvent(t){if(!this.isBoundaryTypeValid(t))return;const i=t.text,s=t.audioOffset,r=t.duration;let n=this.currentCaptions[this.currentCaptions.length-1],a=null;if(n&&Number.isFinite(n._lastEndOffsetMs)&&(a=s-n._lastEndOffsetMs),!n||function(t,i,s){const r=t.text,n=r.length,a=e.preferBreakAfter.test(r.slice(-1)),o=e.softBreakAfter.test(r.slice(-1));return!!t.isDisplayed||null!=s&&s>=e.pauseBreakMs&&n>=e.minChars||(u=n)+(u?1:0)+i.length>e.maxChars||!!(a&&n>=e.minChars)||!!(n>=e.softChars&&o);var u}(n,i,a)){const t={text:i,audioOffset:s,duration:r,isDisplayed:!1,_lastEndOffsetMs:s+r,get renderText(){return(t=this.text)?` ${t.trim()} `:" ";var t}};this.currentCaptions.push(t)}else n.text=(u=i,((o=n.text).length>0&&!/\s$/.test(o)&&!/^[\s.,!?;:…)]/.test(u)?o+" "+u:o+u).replace(/\s{2,}/g," ")),n.duration+=r,n._lastEndOffsetMs=s+r;var o,u;if(/^[\s.,!?;:…()\[\]{}'"—–-]$/.test(i)){const t=this.currentCaptions[this.currentCaptions.length-1];t&&(t.text=t.text.replace(/\s+([.,!?;:…)\]}])/g,"$1").replace(/([([{])\s+/g,"$1").replace(/\s{2,}/g," ").trim())}}playCaptions(t,e){this._playAttemptActive=!0;const i=async()=>{this._playAttemptActive&&(this.currentCaptions.length>0&&!this.currentCaptions[0].isDisplayed?(this._playAttemptActive=!1,this.startCaptionDisplay(t,e)):(await this.wait(100),i()))};i()}startCaptionDisplay(t,e){this.currentCaptionIndex=0,this.displayTimeoutId&&clearTimeout(this.displayTimeoutId),this.durationTimeoutId&&clearTimeout(this.durationTimeoutId),this.settleTimeoutId&&clearTimeout(this.settleTimeoutId),this.displayTimeoutId=null,this.durationTimeoutId=null,this.settleTimeoutId=null;const i=()=>{if(this.currentCaptionIndex>=this.currentCaptions.length)return void(this.settleTimeoutId=setTimeout(()=>{this.settleTimeoutId=null,this.currentCaptionIndex>=this.currentCaptions.length?t(!1):i()},100));const s=this.currentCaptions[this.currentCaptionIndex];if(!s)return void t(!1);const r=Math.max(0,s.audioOffset-(performance.now()-e));this.displayTimeoutId=setTimeout(()=>{this.displayTimeoutId=null,this.currentCaptions[this.currentCaptionIndex]?(s.isDisplayed=!0,t(!0,s.text),this.durationTimeoutId=setTimeout(()=>{this.durationTimeoutId=null,this.currentCaptionIndex++,i()},s.duration)):t(!1)},r)};i()}clearCaptions(){this._playAttemptActive=!1,this.displayTimeoutId&&clearTimeout(this.displayTimeoutId),this.durationTimeoutId&&clearTimeout(this.durationTimeoutId),this.settleTimeoutId&&clearTimeout(this.settleTimeoutId),this.displayTimeoutId=null,this.durationTimeoutId=null,this.settleTimeoutId=null,this.currentCaptions=[],this.currentCaptionIndex=0}wait(t){return new Promise(e=>setTimeout(e,t))}destroy(){this.clearCaptions()}}export{i as L};
@@ -0,0 +1 @@
1
+ import{TalkingHead as e}from"@met4citizen/talkinghead";import{C as t,c as a}from"./index-CUwL7tUc.js";import{L as o}from"./LiveCaptions-BHIQ1Gwu.js";const i={dance:["dance\\M_Dances_007.fbx","dance\\M_Dances_008.fbx","dance\\M_Dances_009.fbx","dance\\M_Dances_011.fbx","dance\\F_Dances_001.fbx","dance\\F_Dances_004.fbx","dance\\F_Dances_005.fbx","dance\\F_Dances_006.fbx","dance\\F_Dances_007.fbx","dance\\M_Dances_001.fbx","dance\\M_Dances_002.fbx","dance\\M_Dances_003.fbx","dance\\M_Dances_004.fbx","dance\\M_Dances_005.fbx","dance\\M_Dances_006.fbx"],expression:["expression\\M_Standing_Expressions_016.fbx","expression\\M_Standing_Expressions_017.fbx","expression\\M_Standing_Expressions_018.fbx","expression\\M_Talking_Variations_001.fbx","expression\\M_Talking_Variations_002.fbx","expression\\M_Talking_Variations_003.fbx","expression\\M_Talking_Variations_004.fbx","expression\\M_Talking_Variations_005.fbx","expression\\M_Talking_Variations_006.fbx","expression\\M_Talking_Variations_007.fbx","expression\\M_Talking_Variations_008.fbx","expression\\M_Talking_Variations_009.fbx","expression\\M_Talking_Variations_010.fbx","expression\\F_Talking_Variations_001.fbx","expression\\F_Talking_Variations_002.fbx","expression\\F_Talking_Variations_003.fbx","expression\\F_Talking_Variations_004.fbx","expression\\F_Talking_Variations_005.fbx","expression\\F_Talking_Variations_006.fbx","expression\\M_Standing_Expressions_001.fbx","expression\\M_Standing_Expressions_002.fbx","expression\\M_Standing_Expressions_004.fbx","expression\\M_Standing_Expressions_005.fbx","expression\\M_Standing_Expressions_006.fbx","expression\\M_Standing_Expressions_007.fbx","expression\\M_Standing_Expressions_008.fbx","expression\\M_Standing_Expressions_009.fbx","expression\\M_Standing_Expressions_010.fbx","expression\\M_Standing_Expressions_011.fbx","expression\\M_Standing_Expressions_012.fbx","expression\\M_Standing_Expressions_013.fbx","expression\\M_Standing_Expressions_014.fbx","expression\\M_Standing_Expressions_015.fbx"],locomotion:["locomotion\\M_CrouchedWalk_Backwards_002.fbx","locomotion\\M_Falling_Idle_002.fbx","locomotion\\M_Jog_001.fbx","locomotion\\M_Jog_003.fbx","locomotion\\M_Jog_Backwards_001.fbx","locomotion\\M_Jog_Jump_001.fbx","locomotion\\M_Jog_Jump_002.fbx","locomotion\\M_Jog_Strafe_Left_001.fbx","locomotion\\M_Jog_Strafe_Right_001.fbx","locomotion\\M_Run_001.fbx","locomotion\\M_Run_Backwards_002.fbx","locomotion\\M_Run_Jump_001.fbx","locomotion\\M_Run_Jump_002.fbx","locomotion\\M_Run_Strafe_Left_002.fbx","locomotion\\M_Run_Strafe_Right_002.fbx","locomotion\\M_Walk_001.fbx","locomotion\\M_Walk_002.fbx","locomotion\\M_Walk_Backwards_001.fbx","locomotion\\M_Walk_Jump_001.fbx","locomotion\\M_Walk_Jump_002.fbx","locomotion\\M_Walk_Jump_003.fbx","locomotion\\M_Walk_Strafe_Left_002.fbx","locomotion\\M_Walk_Strafe_Right_002.fbx","locomotion\\F_Crouch_Strafe_Left.fbx","locomotion\\F_Crouch_Strafe_Right.fbx","locomotion\\F_Crouch_Walk_001.fbx","locomotion\\F_CrouchedWalk_Backwards_001.fbx","locomotion\\F_Falling_Idle_000.fbx","locomotion\\F_Falling_Idle_001.fbx","locomotion\\F_Jog_001.fbx","locomotion\\F_Jog_Backwards_001.fbx","locomotion\\F_Jog_Jump_Small_001.fbx","locomotion\\F_Jog_Strafe_Left_002.fbx","locomotion\\F_Jog_Strafe_Right_002.fbx","locomotion\\F_Run_001.fbx","locomotion\\F_Run_Backwards_001.fbx","locomotion\\F_Run_Jump_001.fbx","locomotion\\F_Run_Strafe_Left_001.fbx","locomotion\\F_Run_Strafe_Right_001.fbx","locomotion\\F_Walk_002.fbx","locomotion\\F_Walk_003.fbx","locomotion\\F_Walk_Backwards_001.fbx","locomotion\\F_Walk_Jump_001.fbx","locomotion\\F_Walk_Jump_002.fbx","locomotion\\F_Walk_Strafe_Left_001.fbx","locomotion\\F_Walk_Strafe_Right_001.fbx","locomotion\\M_Crouch_Strafe_Left_002.fbx","locomotion\\M_Crouch_Strafe_Right_002.fbx","locomotion\\M_Crouch_Walk_003.fbx"],idle:["idle\\M_Standing_Idle_Variations_001.fbx","idle\\M_Standing_Idle_Variations_002.fbx","idle\\M_Standing_Idle_Variations_003.fbx","idle\\M_Standing_Idle_Variations_004.fbx","idle\\M_Standing_Idle_Variations_005.fbx","idle\\M_Standing_Idle_Variations_006.fbx","idle\\M_Standing_Idle_Variations_007.fbx","idle\\M_Standing_Idle_Variations_008.fbx","idle\\M_Standing_Idle_Variations_009.fbx","idle\\M_Standing_Idle_Variations_010.fbx","idle\\F_Standing_Idle_001.fbx","idle\\F_Standing_Idle_Variations_001.fbx","idle\\F_Standing_Idle_Variations_002.fbx","idle\\F_Standing_Idle_Variations_003.fbx","idle\\F_Standing_Idle_Variations_004.fbx","idle\\F_Standing_Idle_Variations_005.fbx","idle\\F_Standing_Idle_Variations_006.fbx","idle\\F_Standing_Idle_Variations_007.fbx","idle\\F_Standing_Idle_Variations_008.fbx","idle\\F_Standing_Idle_Variations_009.fbx","idle\\M_Standing_Idle_001.fbx","idle\\M_Standing_Idle_002.fbx"]};function n(e){return e&&0!==e.length?e[Math.floor(Math.random()*e.length)]:null}function s(e,t,...a){return e.filter(e=>!!e.includes(`${t}_`)&&a.every(t=>e.includes(t)))}function r(e){const t=e.animTemplateEyes,a=e.animTemplateBlink,o={thinking:{baseline:{browDownLeft:.3,browInnerUp:.5,eyeSquintLeft:.4,eyeSquintRight:.4,eyesLookUp:.15,mouthPressLeft:.2,mouthPressRight:.2,mouthRollLower:.2},speech:{deltaRate:-.1,deltaPitch:0,deltaVolume:0},anims:[{name:"breathing",delay:2e3,dt:[1500,500,1200],vs:{chestInhale:[.4,.4,0]}},{name:"pose",alt:[{p:.6,delay:[5e3,3e4],vs:{pose:["side"]}},{delay:[5e3,3e4],vs:{pose:["straight"]}}]},{name:"head",idle:{delay:[500,2e3],dt:[[1e3,4e3]],vs:{bodyRotateX:[[-.02,.12]],bodyRotateY:[[-.15,.15]],bodyRotateZ:[[-.06,.06]]}},speaking:{dt:[[0,1e3,0]],vs:{bodyRotateX:[[-.04,.12,1,2]],bodyRotateY:[[-.08,.08]],bodyRotateZ:[[-.06,.06]]}}},t,a,{name:"mouth",delay:[2e3,6e3],dt:[[200,600],[200,4e3,2]],vs:{mouthRollLower:[[0,.3,2]],mouthRollUpper:[[0,.2,2]],mouthPressLeft:[[0,.3]],mouthPressRight:[[0,.3]]}},{name:"misc",delay:[500,4e3],dt:[[200,600],[1e3,4e3,2]],vs:{eyeSquintLeft:[[.2,.5,2]],eyeSquintRight:[[.2,.5,2]],browInnerUp:[[.3,.6,2]],browDownLeft:[[.1,.4]]}}]},curious:{baseline:{browInnerUp:.5,browOuterUpLeft:.3,browOuterUpRight:.3,eyeWideLeft:.3,eyeWideRight:.3,eyesLookDown:.05,mouthSmile:.1},speech:{deltaRate:.05,deltaPitch:.1,deltaVolume:0},anims:[{name:"breathing",delay:1200,dt:[1e3,500,900],vs:{chestInhale:[.5,.5,0]}},{name:"pose",alt:[{p:.5,delay:[5e3,25e3],vs:{pose:["side"]}},{p:.3,delay:[5e3,25e3],vs:{pose:["straight"]}},{delay:[5e3,2e4],vs:{pose:["hip"]},M:{delay:[5e3,2e4],vs:{pose:["wide"]}}}]},{name:"head",idle:{delay:[0,800],dt:[[300,3e3]],vs:{bodyRotateX:[[-.06,.08]],bodyRotateY:[[-.25,.25]],bodyRotateZ:[[-.1,.1]]}},speaking:{dt:[[0,1e3,0]],vs:{bodyRotateX:[[-.05,.12,1,2]],bodyRotateY:[[-.1,.1]],bodyRotateZ:[[-.08,.08]]}}},t,a,{name:"mouth",delay:[1e3,5e3],dt:[[100,500],[100,5e3,2]],vs:{mouthRollLower:[[0,.2,2]],mouthRollUpper:[[0,.2,2]],mouthStretchLeft:[[0,.2]],mouthStretchRight:[[0,.2]],mouthPucker:[[0,.2]]}},{name:"misc",delay:[100,4e3],dt:[[100,500],[1e3,4e3,2]],vs:{eyeSquintLeft:[[0,.2,2]],eyeSquintRight:[[0,.2,2]],browInnerUp:[[.3,.6,2]],browOuterUpLeft:[[.2,.4,2]],browOuterUpRight:[[.2,.4,2]]}}]},attentive:{baseline:{eyeWideLeft:.2,eyeWideRight:.2,browInnerUp:.2,eyesLookDown:.05},speech:{deltaRate:0,deltaPitch:0,deltaVolume:0},anims:[{name:"breathing",delay:1500,dt:[1200,500,1e3],vs:{chestInhale:[.4,.4,0]}},{name:"pose",alt:[{p:.7,delay:[8e3,4e4],vs:{pose:["straight"]}},{delay:[8e3,3e4],vs:{pose:["side"]}}]},{name:"head",idle:{delay:[1e3,3e3],dt:[[2e3,6e3]],vs:{bodyRotateX:[[-.02,.06]],bodyRotateY:[[-.1,.1]],bodyRotateZ:[[-.04,.04]]}},speaking:{dt:[[0,1e3,0]],vs:{bodyRotateX:[[-.03,.1,1,2]],bodyRotateY:[[-.08,.08]],bodyRotateZ:[[-.06,.06]]}}},t,a,{name:"mouth",delay:[2e3,7e3],dt:[[100,400],[200,5e3,2]],vs:{mouthRollLower:[[0,.2,2]],mouthRollUpper:[[0,.2,2]],mouthStretchLeft:[[0,.2]],mouthStretchRight:[[0,.2]]}},{name:"misc",delay:[500,5e3],dt:[[200,500],[1e3,5e3,2]],vs:{eyeSquintLeft:[[0,.2,2]],eyeSquintRight:[[0,.2,2]],browInnerUp:[[.1,.3,2]]}}]},excited:{baseline:{browInnerUp:.4,eyeWideLeft:.5,eyeWideRight:.5,mouthSmile:.4,mouthDimpleLeft:.2,mouthDimpleRight:.2,eyesLookDown:.05},speech:{deltaRate:.1,deltaPitch:.2,deltaVolume:0},anims:[{name:"breathing",delay:800,dt:[800,400,700],vs:{chestInhale:[.7,.7,0]}},{name:"pose",alt:[{p:.4,delay:[3e3,15e3],vs:{pose:["side"]}},{p:.3,delay:[3e3,15e3],vs:{pose:["straight"]}},{delay:[3e3,1e4],vs:{pose:["wide"]}}]},{name:"head",idle:{delay:[0,500],dt:[[200,3e3]],vs:{bodyRotateX:[[-.06,.12]],bodyRotateY:[[-.35,.35]],bodyRotateZ:[[-.1,.1]]}},speaking:{dt:[[0,800,0]],vs:{bodyRotateX:[[-.06,.16,1,2]],bodyRotateY:[[-.15,.15]],bodyRotateZ:[[-.12,.12]]}}},t,a,{name:"mouth",delay:[800,3e3],dt:[[100,400],[100,3e3,2]],vs:{mouthSmile:[[.2,.5,3]],mouthRollLower:[[0,.3,2]],mouthRollUpper:[[0,.3,2]],mouthStretchLeft:[[0,.3]],mouthStretchRight:[[0,.3]],mouthPucker:[[0,.2]]}},{name:"misc",delay:[100,3e3],dt:[[100,400],[500,3e3,2]],vs:{eyeSquintLeft:[[0,.3,2]],eyeSquintRight:[[0,.3,2]],browInnerUp:[[.2,.5,2]],browOuterUpLeft:[[.1,.4,2]],browOuterUpRight:[[.1,.4,2]]}}]},confident:{baseline:{mouthSmile:.15,eyesLookDown:.1,browOuterUpLeft:.1,browOuterUpRight:.1,bodyRotateX:-.03},speech:{deltaRate:0,deltaPitch:.05,deltaVolume:0},anims:[{name:"breathing",delay:1500,dt:[1200,500,1200],vs:{chestInhale:[.6,.6,0]}},{name:"pose",alt:[{p:.4,delay:[5e3,3e4],vs:{pose:["straight"]}},{p:.3,delay:[5e3,3e4],vs:{pose:["side"]}},{delay:[5e3,25e3],vs:{pose:["hip"]},M:{delay:[5e3,25e3],vs:{pose:["wide"]}}}]},{name:"head",idle:{delay:[500,2e3],dt:[[1e3,5e3]],vs:{bodyRotateX:[[-.05,.08]],bodyRotateY:[[-.2,.2]],bodyRotateZ:[[-.06,.06]]}},speaking:{dt:[[0,1e3,0]],vs:{bodyRotateX:[[-.05,.12,1,2]],bodyRotateY:[[-.1,.1]],bodyRotateZ:[[-.08,.08]]}}},t,a,{name:"mouth",delay:[1e3,5e3],dt:[[100,500],[100,5e3,2]],vs:{mouthSmile:[[0,.2,3]],mouthRollLower:[[0,.2,2]],mouthRollUpper:[[0,.2,2]],mouthStretchLeft:[[0,.2]],mouthStretchRight:[[0,.2]]}},{name:"misc",delay:[200,5e3],dt:[[200,500],[1e3,5e3,2]],vs:{eyeSquintLeft:[[0,.2,2]],eyeSquintRight:[[0,.2,2]],browInnerUp:[[0,.2,2]],browOuterUpLeft:[[0,.2,2]],browOuterUpRight:[[0,.2,2]]}}]},amused:{baseline:{mouthSmileLeft:.4,mouthSmileRight:.15,eyeSquintLeft:.4,eyeSquintRight:.2,browOuterUpRight:.2,noseSneerLeft:.2,eyesLookDown:.1},speech:{deltaRate:0,deltaPitch:.1,deltaVolume:0},anims:[{name:"breathing",delay:1200,dt:[1e3,500,1e3],vs:{chestInhale:[.5,.5,0]}},{name:"pose",alt:[{p:.5,delay:[5e3,25e3],vs:{pose:["side"]}},{p:.3,delay:[5e3,25e3],vs:{pose:["straight"]}},{delay:[5e3,2e4],vs:{pose:["hip"]},M:{delay:[5e3,2e4],vs:{pose:["wide"]}}}]},{name:"head",idle:{delay:[0,1e3],dt:[[500,4e3]],vs:{bodyRotateX:[[-.04,.1]],bodyRotateY:[[-.25,.25]],bodyRotateZ:[[-.08,.08]]}},speaking:{dt:[[0,1e3,0]],vs:{bodyRotateX:[[-.05,.12,1,2]],bodyRotateY:[[-.1,.1]],bodyRotateZ:[[-.08,.08]]}}},t,a,{name:"mouth",delay:[1e3,4e3],dt:[[100,500],[100,4e3,2]],vs:{mouthSmile:[[.1,.3,3]],mouthLeft:[[0,.2,2]],mouthRollLower:[[0,.3,2]],mouthRollUpper:[[0,.2,2]],mouthStretchLeft:[[0,.3]],mouthStretchRight:[[0,.2]]}},{name:"misc",delay:[200,4e3],dt:[[100,500],[1e3,4e3,2]],vs:{eyeSquintLeft:[[.2,.5,2]],eyeSquintRight:[[.1,.3,2]],browOuterUpRight:[[.1,.3,2]],noseSneerLeft:[[.1,.3]]}}]},proud:{baseline:{mouthSmile:.25,bodyRotateX:-.05,browOuterUpLeft:.15,browOuterUpRight:.15,eyesLookDown:.1,mouthDimpleLeft:.1,mouthDimpleRight:.1},speech:{deltaRate:-.05,deltaPitch:.1,deltaVolume:0},anims:[{name:"breathing",delay:1500,dt:[1400,500,1200],vs:{chestInhale:[.7,.7,0]}},{name:"pose",alt:[{p:.5,delay:[5e3,3e4],vs:{pose:["straight"]}},{p:.3,delay:[5e3,25e3],vs:{pose:["hip"]},M:{delay:[5e3,25e3],vs:{pose:["wide"]}}},{delay:[5e3,2e4],vs:{pose:["side"]}}]},{name:"head",idle:{delay:[500,2e3],dt:[[1e3,5e3]],vs:{bodyRotateX:[[-.06,.06]],bodyRotateY:[[-.2,.2]],bodyRotateZ:[[-.06,.06]]}},speaking:{dt:[[0,1e3,0]],vs:{bodyRotateX:[[-.06,.1,1,2]],bodyRotateY:[[-.1,.1]],bodyRotateZ:[[-.08,.08]]}}},t,a,{name:"mouth",delay:[1e3,5e3],dt:[[100,500],[100,5e3,2]],vs:{mouthSmile:[[.1,.3,3]],mouthRollLower:[[0,.2,2]],mouthRollUpper:[[0,.2,2]],mouthStretchLeft:[[0,.2]],mouthStretchRight:[[0,.2]]}},{name:"misc",delay:[200,5e3],dt:[[200,500],[1e3,5e3,2]],vs:{eyeSquintLeft:[[0,.3,2]],eyeSquintRight:[[0,.3,2]],browOuterUpLeft:[[.1,.3,2]],browOuterUpRight:[[.1,.3,2]]}}]},shy:{baseline:{eyesLookDown:.3,eyeSquintLeft:.3,eyeSquintRight:.3,mouthSmile:.1,bodyRotateX:.08,bodyRotateZ:.04,cheekSquintLeft:.2,cheekSquintRight:.2},speech:{deltaRate:-.15,deltaPitch:-.1,deltaVolume:0},anims:[{name:"breathing",delay:1800,dt:[1200,500,1200],vs:{chestInhale:[.4,.4,0]}},{name:"pose",alt:[{p:.7,delay:[5e3,3e4],vs:{pose:["side"]}},{delay:[5e3,3e4],vs:{pose:["straight"]}}]},{name:"head",idle:{delay:[500,2e3],dt:[[1e3,6e3]],vs:{bodyRotateX:[[0,.12]],bodyRotateY:[[-.15,.15]],bodyRotateZ:[[-.06,.06]]}},speaking:{dt:[[0,1e3,0]],vs:{bodyRotateX:[[-.02,.14,1,2]],bodyRotateY:[[-.08,.08]],bodyRotateZ:[[-.06,.06]]}}},t,a,{name:"mouth",delay:[2e3,6e3],dt:[[100,500],[200,5e3,2]],vs:{mouthRollLower:[[0,.3,2]],mouthRollUpper:[[0,.3,2]],mouthPucker:[[0,.3]],mouthSmile:[[0,.15,3]]}},{name:"misc",delay:[200,5e3],dt:[[200,500],[1e3,5e3,2]],vs:{eyeSquintLeft:[[.2,.4,2]],eyeSquintRight:[[.2,.4,2]],cheekSquintLeft:[[.1,.3]],cheekSquintRight:[[.1,.3]],browInnerUp:[[0,.3,2]]}}]},empathetic:{baseline:{browInnerUp:.4,mouthSmile:.1,eyeSquintLeft:.2,eyeSquintRight:.2,bodyRotateZ:.04,eyesLookDown:.1},speech:{deltaRate:-.1,deltaPitch:-.1,deltaVolume:0},anims:[{name:"breathing",delay:1500,dt:[1300,500,1100],vs:{chestInhale:[.5,.5,0]}},{name:"pose",alt:[{p:.5,delay:[5e3,3e4],vs:{pose:["side"]}},{p:.3,delay:[5e3,3e4],vs:{pose:["straight"]}},{delay:[5e3,25e3],vs:{pose:["hip"]},M:{delay:[5e3,25e3],vs:{pose:["side"]}}}]},{name:"head",idle:{delay:[0,1e3],dt:[[800,4e3]],vs:{bodyRotateX:[[-.04,.1]],bodyRotateY:[[-.2,.2]],bodyRotateZ:[[-.06,.08]]}},speaking:{dt:[[0,1e3,0]],vs:{bodyRotateX:[[-.05,.12,1,2]],bodyRotateY:[[-.1,.1]],bodyRotateZ:[[-.06,.06]]}}},t,a,{name:"mouth",delay:[1e3,5e3],dt:[[100,500],[100,5e3,2]],vs:{mouthSmile:[[0,.15,3]],mouthRollLower:[[0,.3,2]],mouthRollUpper:[[0,.2,2]],mouthStretchLeft:[[0,.2]],mouthStretchRight:[[0,.2]]}},{name:"misc",delay:[200,5e3],dt:[[200,500],[1e3,5e3,2]],vs:{eyeSquintLeft:[[.1,.3,2]],eyeSquintRight:[[.1,.3,2]],browInnerUp:[[.3,.5,2]],browOuterUpLeft:[[0,.2,2]],browOuterUpRight:[[0,.2,2]]}}]},concerned:{baseline:{browInnerUp:.6,eyeSquintLeft:.3,eyeSquintRight:.3,mouthFrownLeft:.3,mouthFrownRight:.3,mouthPressLeft:.2,mouthPressRight:.2,eyesLookDown:.1},speech:{deltaRate:-.1,deltaPitch:-.05,deltaVolume:0},anims:[{name:"breathing",delay:1500,dt:[1200,500,1e3],vs:{chestInhale:[.5,.5,0]}},{name:"pose",alt:[{p:.5,delay:[5e3,3e4],vs:{pose:["side"]}},{p:.3,delay:[5e3,3e4],vs:{pose:["straight"]}},{delay:[5e3,25e3],vs:{pose:["hip"]},M:{delay:[5e3,25e3],vs:{pose:["wide"]}}}]},{name:"head",idle:{delay:[200,1e3],dt:[[500,4e3]],vs:{bodyRotateX:[[-.04,.1]],bodyRotateY:[[-.2,.2]],bodyRotateZ:[[-.08,.08]]}},speaking:{dt:[[0,1e3,0]],vs:{bodyRotateX:[[-.05,.12,1,2]],bodyRotateY:[[-.1,.1]],bodyRotateZ:[[-.08,.08]]}}},t,a,{name:"mouth",delay:[1e3,5e3],dt:[[100,500],[100,5e3,2]],vs:{mouthFrownLeft:[[.1,.4]],mouthFrownRight:[[.1,.4]],mouthRollLower:[[0,.3,2]],mouthRollUpper:[[0,.3,2]],mouthPressLeft:[[0,.3]],mouthPressRight:[[0,.3]]}},{name:"misc",delay:[200,5e3],dt:[[200,500],[1e3,5e3,2]],vs:{eyeSquintLeft:[[.2,.4,2]],eyeSquintRight:[[.2,.4,2]],browInnerUp:[[.4,.7,2]],browOuterUpLeft:[[0,.2,2]],browOuterUpRight:[[0,.2,2]]}}]},surprised:{baseline:{browInnerUp:.7,browOuterUpLeft:.5,browOuterUpRight:.5,eyeWideLeft:.6,eyeWideRight:.6,jawOpen:.15,mouthFunnel:.2},speech:{deltaRate:.05,deltaPitch:.15,deltaVolume:0},anims:[{name:"breathing",delay:800,dt:[900,400,800],vs:{chestInhale:[.6,.6,0]}},{name:"pose",alt:[{p:.6,delay:[5e3,25e3],vs:{pose:["straight"]}},{delay:[5e3,2e4],vs:{pose:["side"]}}]},{name:"head",idle:{delay:[100,500],dt:[[200,3e3]],vs:{bodyRotateX:[[-.06,.08]],bodyRotateY:[[-.3,.3]],bodyRotateZ:[[-.1,.1]]}},speaking:{dt:[[0,800,0]],vs:{bodyRotateX:[[-.06,.12,1,2]],bodyRotateY:[[-.12,.12]],bodyRotateZ:[[-.1,.1]]}}},t,a,{name:"mouth",delay:[1e3,4e3],dt:[[100,400],[100,4e3,2]],vs:{mouthFunnel:[[0,.3]],jawOpen:[[0,.2]],mouthRollLower:[[0,.2,2]],mouthRollUpper:[[0,.2,2]]}},{name:"misc",delay:[100,3e3],dt:[[100,400],[500,3e3,2]],vs:{eyeWideLeft:[[.3,.7]],eyeWideRight:[[.3,.7]],browInnerUp:[[.5,.8,2]],browOuterUpLeft:[[.3,.6,2]],browOuterUpRight:[[.3,.6,2]]}}]},bored:{baseline:{eyeSquintLeft:.4,eyeSquintRight:.4,eyeBlinkLeft:.2,eyeBlinkRight:.2,eyesLookDown:.2,mouthFrownLeft:.2,mouthFrownRight:.2,mouthPucker:.1},speech:{deltaRate:-.15,deltaPitch:-.1,deltaVolume:0},anims:[{name:"breathing",delay:2e3,dt:[1500,500,1500],vs:{chestInhale:[.3,.3,0]}},{name:"pose",alt:[{p:.6,delay:[8e3,4e4],vs:{pose:["side"]}},{delay:[8e3,35e3],vs:{pose:["straight"]}}]},{name:"head",idle:{delay:[1e3,4e3],dt:[[2e3,8e3]],vs:{bodyRotateX:[[-.02,.12]],bodyRotateY:[[-.15,.15]],bodyRotateZ:[[-.06,.06]]}},speaking:{dt:[[0,1500,0]],vs:{bodyRotateX:[[-.04,.12,1,2]],bodyRotateY:[[-.08,.08]],bodyRotateZ:[[-.06,.06]]}}},t,a,{name:"mouth",delay:[2e3,8e3],dt:[[200,600],[200,6e3,2]],vs:{mouthFrownLeft:[[0,.3]],mouthFrownRight:[[0,.3]],mouthRollLower:[[0,.3,2]],mouthRollUpper:[[0,.2,2]],mouthPucker:[[0,.2]]}},{name:"misc",delay:[500,6e3],dt:[[200,600],[1e3,6e3,2]],vs:{eyeSquintLeft:[[.3,.5,2]],eyeSquintRight:[[.3,.5,2]],browInnerUp:[[0,.2,2]]}}]}};let i=0;for(const[n,s]of Object.entries(o))e.animMoods[n]=s,i++;return i}const l=["eyeBlinkLeft","eyeLookDownLeft","eyeLookInLeft","eyeLookOutLeft","eyeLookUpLeft","eyeSquintLeft","eyeWideLeft","eyeBlinkRight","eyeLookDownRight","eyeLookInRight","eyeLookOutRight","eyeLookUpRight","eyeSquintRight","eyeWideRight","jawForward","jawLeft","jawRight","jawOpen","mouthClose","mouthFunnel","mouthPucker","mouthLeft","mouthRight","mouthSmileLeft","mouthSmileRight","mouthFrownLeft","mouthFrownRight","mouthDimpleLeft","mouthDimpleRight","mouthStretchLeft","mouthStretchRight","mouthRollLower","mouthRollUpper","mouthShrugLower","mouthShrugUpper","mouthPressLeft","mouthPressRight","mouthLowerDownLeft","mouthLowerDownRight","mouthUpperUpLeft","mouthUpperUpRight","browDownLeft","browDownRight","browInnerUp","browOuterUpLeft","browOuterUpRight","cheekPuff","cheekSquintLeft","cheekSquintRight","noseSneerLeft","noseSneerRight","tongueOut","headRotateZ"],d=["sil","aa","aa","O","E","RR","I","U","O","O","O","I","kk","RR","nn","SS","CH","TH","FF","DD","kk","PP"];class h extends t{isVideoAvatar=!1;constructor(e,t){super("talkingAvatar"),this.bus=e,this.avatarOrchestrator=t,this.talkingAvatar=null,this.isFullBody=!0,this.bodyGender="M",this.resetSpeakData(),this.prevViseme=null,this.frameDuration=1e3/a.constants.FRAME_RATE,this.currentTurnId=null,this.isStoppingSpeaking=!1,this._endedTurns=/* @__PURE__ */new Set,this.conversationStreamActive=!1,this._pendingEndReason=null,this._audioStartSent=!1,this._busHandlers=[],this._webglContextLost=!1,this._webglListeners=null,this.liveCaptions=new o}resetSpeakData(){this.speak={audio:[],visemes:[],vtimes:[],vdurations:[],words:[],wtimes:[],wdurations:[],markers:[],mtimes:[],anim:{}},this.azureBlendShapes={frames:[],sbuffer:[],orderBuffer:{}},this.prevViseme=null}finalizeTurn(){this.handlePendingVisemes(),this.talkingAvatar.streamNotifyEnd(),this.resetSpeakData()}async init(t,a){try{this.talkingAvatar=new e(a,{ttsEndpoint:"/gtts/",cameraZoomEnable:!1,cameraPanEnable:!1,cameraRotateEnable:!1,cameraView:"full",cameraY:.25,cameraDistance:.5,avatarMood:"happy"});const o="male"===t.gender?"M":"F";this.bodyGender=o,this.currentAvatarConfig={url:t.url,body:o},await this.talkingAvatar.showAvatar(this.currentAvatarConfig),r(this.talkingAvatar),this._attachWebGLContextListeners(),this.addEventListeners(),this.setConnected(),this.lipsyncType=t.lipsyncType}catch(o){throw this.setFailed(),new Error("Error initializing TalkingAvatar: "+o)}}isRenderingActive(){return!!this.talkingAvatar?.isRunning}async suspendRendering(e="hidden"){if(this.isRenderingActive()){this.suspendTime=Date.now();try{this.talkingAvatar?.streamInterrupt?.()}catch(t){}try{this.audioReader?.cancel()}catch(t){}try{this.lipsyncReader?.cancel()}catch(t){}if(this.conversationStreamActive)try{await this.stopConversationStream()}catch(t){}try{this.talkingAvatar?.stop?.()}catch(t){}try{this.liveCaptions?.clearCaptions?.()}catch(t){}try{this.bus?.emit?.("event_command_UI_ClearCaptions")}catch(t){}try{const t=this.isRenderingActive();this.bus?.emit?.("event_status_Avatar_RenderingStateChanged",{running:t,reason:e})}catch(t){}}}async resumeRendering(){if(this.isRenderingActive())return;const e=this._webglContextLost,t=this.suspendTime&&Date.now()-this.suspendTime>15e3;(e||t)&&this.currentAvatarConfig&&(this._webglContextLost=!1,await this.refreshAvatar());try{this.talkingAvatar?.start?.()}catch(a){}try{const e=this.isRenderingActive();this.bus?.emit?.("event_status_Avatar_RenderingStateChanged",{running:e,reason:"resume"})}catch(a){}}async refreshAvatar(){if(!this.currentAvatarConfig)return!1;try{try{this.talkingAvatar?.streamInterrupt?.()}catch(e){}return await this.talkingAvatar.showAvatar(this.currentAvatarConfig),r(this.talkingAvatar),!0}catch(t){return!1}}resumeAudioContext(){try{const e=this.talkingAvatar?.audioCtx;if(!e)return;"suspended"!==e.state&&"interrupted"!==e.state||e.resume().then(()=>{}).catch(e=>{})}catch(e){}}getSpeechAnalyzerNode(){return this.talkingAvatar?.audioAnalyzerNode??null}startStreamPump(e){try{this.audioReader=e.readable.getReader()}catch(a){return}const t=this.currentTurnId;(async()=>{try{for(;;){const{value:a,done:o}=await this.audioReader.read();if(o)return;if(this.currentTurnId!==t){try{this.audioReader.cancel()}catch(e){}return}this._notifyAudioStart(t),this.handleSpeechSynthesizingChunk({audio:a})}}catch(a){"AbortError"===a.name||a.message.includes("cancel")}})().catch(e=>{})}startLipsyncPump(e){this.lipsyncReader=e.readable.getReader();const t=this.currentTurnId;(async()=>{try{for(;;){const{value:a,done:o}=await this.lipsyncReader.read();if(o)break;if(this.currentTurnId!==t){try{this.lipsyncReader.cancel()}catch(e){}break}switch(a.type){case"viseme":this.handleAddVisemeToStreaming(a);break;case"word":this.handleReceivedWordBoundaryEvent(a);break;case"blend":this.handleAddBlendShapestoStreaming(a)}}}catch(a){"AbortError"===a.name||a.message.includes("cancel")}})().catch(e=>{})}handleAudioEndOnce(e,t){const a=e??"__null__";this._endedTurns.has(a)||(this._endedTurns.add(a),this.avatarOrchestrator.sendEvent("AUDIO_END",{turnId:e,reason:t}))}async startConversationStream(){if(this.isRenderingActive()&&!this.conversationStreamActive)try{await this.talkingAvatar.streamStart({lipsyncType:this.lipsyncType,sampleRate:24e3},({turnId:e,audioStartTime:t}={})=>{const a=e??this.currentTurnId;this._notifyAudioStart(a,t)},()=>{const e=this._pendingEndReason||"completed";this._pendingEndReason=null,this.handleAudioEndOnce(this.currentTurnId,e),this.currentTurnId&&(this.currentTurnId=null)}),this.conversationStreamActive=!0}catch(e){throw this.conversationStreamActive=!1,e}}async stopConversationStream(){if(this.conversationStreamActive)try{this.talkingAvatar.streamStop(),this.conversationStreamActive=!1}catch(e){this.conversationStreamActive=!1}}addEventListeners(){const e=(e,t)=>{this.bus.on(e,t),this._busHandlers.push([e,t])};e("event_command_Avatar_SetAvatarView",e=>{this.setView(e.view)}),e("event_command_Avatar_SetAvatarMood",e=>{this.talkingAvatar.setMood(e.mood)}),e("event_command_Avatar_PlayOrStopGesture",e=>{"stop"!==e.gesture?this.talkingAvatar.playGesture(e.gesture,e.duration,e.mirror,e.ms):this.talkingAvatar.stopGesture()}),e("event_command_Avatar_PlayOrStopAnimation",e=>{if("stop"===e.animation)return void this.talkingAvatar.stopAnimation();const t=function(e,t="M"){let a=[];switch(e){case"dance":a=s(i.dance,t,"Dances");break;case"expression_talking":a=s(i.expression,t,"Talking_Variations");break;case"expression_standing":a=s(i.expression,t,"Standing_Expressions");break;case"idle_standing":a=s(i.idle,t,"Standing_Idle");break;case"locomotion_walk":a=s(i.locomotion,t,"Walk_");break;case"locomotion_walk_backwards":a=s(i.locomotion,t,"Walk_Backwards");break;case"locomotion_walk_jump":a=s(i.locomotion,t,"Walk_Jump");break;case"locomotion_walk_strafe_left":a=s(i.locomotion,t,"Walk_Strafe_Left");break;case"locomotion_walk_strafe_right":a=s(i.locomotion,t,"Walk_Strafe_Right");break;case"locomotion_run":a=s(i.locomotion,t,"Run_");break;case"locomotion_run_backwards":a=s(i.locomotion,t,"Run_Backwards");break;case"locomotion_run_jump":a=s(i.locomotion,t,"Run_Jump");break;case"locomotion_run_strafe_left":a=s(i.locomotion,t,"Run_Strafe_Left");break;case"locomotion_run_strafe_right":a=s(i.locomotion,t,"Run_Strafe_Right");break;case"locomotion_jog":a=s(i.locomotion,t,"Jog_");break;case"locomotion_jog_backwards":a=s(i.locomotion,t,"Jog_Backwards");break;case"locomotion_jog_jump":a=s(i.locomotion,t,"Jog_Jump");break;case"locomotion_jog_strafe_left":a=s(i.locomotion,t,"Jog_Strafe_Left");break;case"locomotion_jog_strafe_right":a=s(i.locomotion,t,"Jog_Strafe_Right");break;case"locomotion_crouch_walk":a=s(i.locomotion,t,"Crouch_Walk");break;case"locomotion_crouch_strafe_left":a=s(i.locomotion,t,"Crouch_Strafe_Left");break;case"locomotion_crouch_strafe_right":a=s(i.locomotion,t,"Crouch_Strafe_Right");break;case"locomotion_crouchedwalk_backwards":a=s(i.locomotion,t,"CrouchedWalk_Backwards");break;case"locomotion_falling_idle":a=s(i.locomotion,t,"Falling_Idle");break;default:a=[]}return n(a)||n(i.locomotion.filter(e=>e.includes(`${t}_Walk_`)))||"locomotion\\M_Walk_001.fbx"}(e.animation,this.bodyGender);this.playAnimation(t,e.dur)}),e("event_command_Avatar_ControlAvatarLookAt",e=>{"ahead"!==e.target?"point"!==e.target?"camera"!==e.target?"eye_contact"!==e.target||this.talkingAvatar.makeEyeContact(e.t):this.talkingAvatar.lookAtCamera(e.t):this.talkingAvatar.lookAt(e.x,e.y,e.t):this.talkingAvatar.lookAhead(e.t)}),e("event_command_UI_ClearCaptions",()=>{try{this.liveCaptions?.clearCaptions?.()}catch(e){}})}onResize(){this.talkingAvatar&&this.talkingAvatar.onResize()}handleSpeechSynthesizingChunk(e){switch(this.lipsyncType){case"blendshapes":this.talkingAvatar.streamAudio({audio:e.audio,anims:this.azureBlendShapes?.sbuffer.splice(0,this.azureBlendShapes?.sbuffer.length)});break;case"visemes":this.talkingAvatar.streamAudio({audio:e.audio,visemes:this.speak.visemes.splice(0,this.speak.visemes.length),vtimes:this.speak.vtimes.splice(0,this.speak.vtimes.length),vdurations:this.speak.vdurations.splice(0,this.speak.vdurations.length)});break;case"words":this.talkingAvatar.streamAudio({audio:e.audio,words:this.speak.words.splice(0,this.speak.words.length),wtimes:this.speak.wtimes.splice(0,this.speak.wtimes.length),wdurations:this.speak.wdurations.splice(0,this.speak.wdurations.length)})}}handleAddVisemeToStreaming(e){const t=d[e?.visemeId||0],a=e?.audioOffset||0;if(this.prevViseme){const e=this.prevViseme;let t=a-e.vtime;t<40&&(t=40),this.speak.visemes.push(e.viseme),this.speak.vtimes.push(e.vtime),this.speak.vdurations.push(t)}this.prevViseme={viseme:t,vtime:a}}handleAddBlendShapestoStreaming(e){const t=e?.BlendShapes;if(!t||0===t.length)return;const a=this._getBlendColumns(),o=t.length,i=/* @__PURE__ */Object.create(null);for(let s=0;s<a.length;s++){const[e,n]=a[s],r=new Float32Array(o);for(let a=0;a<o;a++){const o=t[a];r[a]=Array.isArray(o)||ArrayBuffer.isView(o)?o[e]??0:0}i[n]=r}const n=null!=e?.AudioOffset?Math.round(e.AudioOffset/1e4):(e?.FrameIndex||0)*this.frameDuration;this.azureBlendShapes.sbuffer.push({name:"blendshapes",delay:n,dt:this._getDtArray(o),vs:i})}handleReceivedWordBoundaryEvent(e){try{this.liveCaptions.handleWordBoundaryEvent(e)}catch(n){}const t=this.speak,a=e.text,o=e.audioOffset,i=e.duration;"SpeechSynthesisBoundaryType.Punctuation"===e.boundaryType&&t.words.length?t.words[t.words.length-1]+=a:"SpeechSynthesisBoundaryType.Word"===e.boundaryType||"SpeechSynthesisBoundaryType.Punctuation"===e.boundaryType?(t.words.push(a),t.wtimes.push(o),t.wdurations.push(i)):"SpeechSynthesisBoundaryType.Sentence"===e.boundaryType&&o>500&&(t.markers.push(()=>{this.talkingAvatar.lookAtCamera(500)}),t.mtimes.push(o-500))}handlePendingVisemes(e=null){if("visemes"===this.lipsyncType&&this.prevViseme){const t=this.prevViseme;e||(e=100),this.speak.visemes.push(t.viseme),this.speak.vtimes.push(t.vtime),this.speak.vdurations.push(e),this.prevViseme=null}"visemes"===this.lipsyncType&&this.speak.visemes.length&&this.talkingAvatar.streamAudio({visemes:this.speak.visemes.splice(0,this.speak.visemes.length),vtimes:this.speak.vtimes.splice(0,this.speak.vtimes.length),vdurations:this.speak.vdurations.splice(0,this.speak.vdurations.length)}),"blendshapes"===this.lipsyncType&&this.azureBlendShapes.sbuffer.length&&this.talkingAvatar.streamAudio({anims:this.azureBlendShapes.sbuffer.splice(0,this.azureBlendShapes.sbuffer.length)})}async startStreaming(e,t,a){if(this.currentTurnId=a,this.isStoppingSpeaking=!1,this._audioStartSent=!1,!this.isRenderingActive()){try{e?.cancel?.()}catch(i){}try{t?.cancel?.()}catch(i){}return this.handleAudioEndOnce(a,"suppressed"),void(this.currentTurnId=null)}const o=a;this._endedTurns.delete(o??"__null__");try{this.startStreamPump(e),this.startLipsyncPump(t),this.conversationStreamActive||await this.startConversationStream()}catch(n){this.handleAudioEndOnce(o,"error"),this.currentTurnId===o&&(this.currentTurnId=null),this.isStoppingSpeaking=!1}}_notifyAudioStart(e,t=null){if(this._audioStartSent)return;this._audioStartSent=!0;const a=t??("undefined"!=typeof performance?performance.now():Date.now()),o=e??this.currentTurnId,i=o||0===o?{turnId:o,audioStartTime:a}:{audioStartTime:a},n=()=>{try{this.avatarOrchestrator?.sendEvent("AUDIO_START",i)}catch(e){}};"function"==typeof queueMicrotask?queueMicrotask(n):setTimeout(n,0)}interruptSpeaking(){if(!this.isStoppingSpeaking){this.isStoppingSpeaking=!0,this.conversationStreamActive&&this.talkingAvatar.streamInterrupt(),this.audioReader?.cancel(),this.lipsyncReader?.cancel(),this._pendingEndReason="interrupted";try{this.liveCaptions?.clearCaptions?.()}catch(e){}try{this.bus?.emit?.("event_command_UI_ClearCaptions")}catch(e){}this.isStoppingSpeaking=!1}}setView(e){switch(e){case"full":this.talkingAvatar.setView("full");break;case"mid":this.talkingAvatar.setView("mid");break;case"upper":this.talkingAvatar.setView("upper");break;case"head":this.talkingAvatar.setView("head")}}playAnimation(e,t){const a=`https://sentifydfrontend.blob.core.windows.net/animationclips/${e}`;this.setView("full"),this.talkingAvatar.playAnimation(a,null,t)}_attachWebGLContextListeners(){this._detachWebGLContextListeners();const e=this.talkingAvatar?.renderer?.domElement;if(!e)return;const t=e=>{e.preventDefault(),this._webglContextLost=!0},a=()=>{};e.addEventListener("webglcontextlost",t),e.addEventListener("webglcontextrestored",a),this._webglListeners={canvas:e,onLost:t,onRestored:a}}_detachWebGLContextListeners(){if(!this._webglListeners)return;const{canvas:e,onLost:t,onRestored:a}=this._webglListeners;try{e.removeEventListener("webglcontextlost",t)}catch(o){}try{e.removeEventListener("webglcontextrestored",a)}catch(o){}this._webglListeners=null}reconnect(){}async destroy(){for(const[e,t]of this._busHandlers)try{this.bus.off(e,t)}catch{}this._busHandlers.length=0,this._detachWebGLContextListeners(),this.isStoppingSpeaking=!1,this.conversationStreamActive&&await this.stopConversationStream(),this._disposeTalkingHead(this.talkingAvatar),this.talkingAvatar=null}_disposeTalkingHead(e){if(e){try{e.dispose?.()}catch(t){}try{e.audioCtx?.close?.()}catch(t){}}}_getBlendColumns(){if(!this._blendCols){this._blendCols=[];for(let e=0;e<l.length;e++){const t=l[e];t&&this._blendCols.push([e,t])}}return this._blendCols}_getDtArray(e){this._dtCache||(this._dtCache=/* @__PURE__ */new Map);let t=this._dtCache.get(e);return t||(t=new Array(e).fill(this.frameDuration),this._dtCache.set(e,t)),t}}export{h as TalkingAvatar};