@characterxyz/web 0.1.0 → 0.2.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/dist/index.d.ts +32 -3
- package/dist/index.js +6 -6
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -82,9 +82,31 @@ interface ChatMessage {
|
|
|
82
82
|
streaming?: boolean;
|
|
83
83
|
/** Set when a visitor's message could not be answered. */
|
|
84
84
|
failed?: boolean;
|
|
85
|
+
/** Why, in words a visitor can read (a daily limit, a slow-down). */
|
|
86
|
+
error?: string;
|
|
87
|
+
/** On a reply just written: what the visitor might ask next. Not kept in the history. */
|
|
88
|
+
suggestions?: string[];
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* How the agent opens the conversation on this site, written by the agent
|
|
92
|
+
* from her own persona and knowledge (and the key's product).
|
|
93
|
+
*/
|
|
94
|
+
interface Opening {
|
|
95
|
+
/** Her first message in an empty chat. */
|
|
96
|
+
greeting: string;
|
|
97
|
+
/** One line for a visitor coming back to an earlier conversation. */
|
|
98
|
+
welcomeBack: string;
|
|
99
|
+
/** A few words to show beside the closed launcher. May be empty. */
|
|
100
|
+
teaser: string;
|
|
101
|
+
/** What a visitor would most likely ask first. May be empty. */
|
|
102
|
+
suggestions: string[];
|
|
85
103
|
}
|
|
86
104
|
type CallPhase = 'idle' | 'joining' | 'queued' | 'ready' | 'connecting' | 'live' | 'ended';
|
|
87
|
-
type CallEndReason = 'hangup' | 'left' | 'missed' | 'timeout' | 'limit' | 'credits' | 'busy' | 'failed' | 'mic-denied' | 'unavailable'
|
|
105
|
+
type CallEndReason = 'hangup' | 'left' | 'missed' | 'timeout' | 'limit' | 'credits' | 'busy' | 'failed' | 'mic-denied' | 'unavailable'
|
|
106
|
+
/** Nobody spoke for a minute, so the server hung up. */
|
|
107
|
+
| 'silence'
|
|
108
|
+
/** The site's call minutes for today are used up. */
|
|
109
|
+
| 'daily_limit';
|
|
88
110
|
interface CallState {
|
|
89
111
|
phase: CallPhase;
|
|
90
112
|
callId: string | null;
|
|
@@ -319,6 +341,13 @@ declare class CharacterXYZ extends Emitter<ClientEvents> {
|
|
|
319
341
|
* the app's renderer. Null when the agent wears none.
|
|
320
342
|
*/
|
|
321
343
|
videoAvatar(): Promise<Record<string, unknown> | null>;
|
|
344
|
+
private openingP;
|
|
345
|
+
/**
|
|
346
|
+
* How the agent opens the conversation here — her greeting, a welcome-back
|
|
347
|
+
* line, a teaser and likely first questions — written by her and cached by
|
|
348
|
+
* the server. Fetched once per page; null if it could not be had.
|
|
349
|
+
*/
|
|
350
|
+
opening(): Promise<Opening | null>;
|
|
322
351
|
/** Start a voice call. Call from a click: it needs the microphone and audio unlocked. */
|
|
323
352
|
startCall(opts?: CallOptions): Promise<Call>;
|
|
324
353
|
destroy(): void;
|
|
@@ -344,6 +373,6 @@ declare class CharacterXYZ extends Emitter<ClientEvents> {
|
|
|
344
373
|
* is built on, for brands who want their own UI.
|
|
345
374
|
*/
|
|
346
375
|
|
|
347
|
-
declare const VERSION = "0.
|
|
376
|
+
declare const VERSION = "0.2.0";
|
|
348
377
|
|
|
349
|
-
export { type AgentCard, Call, type CallEndReason, type CallEvents, type CallOptions, type CallPhase, type CallState, type Caption, CharacterXYZ, Chat, type ChatEvents, type ChatMessage, type ClientEvents, CxError, type CxErrorCode, DEFAULT_API_URL, Emitter, type Features, type InitOptions, type SessionInfo, VERSION, type VideoCharacter, type VideoClip, type VisitorStore };
|
|
378
|
+
export { type AgentCard, Call, type CallEndReason, type CallEvents, type CallOptions, type CallPhase, type CallState, type Caption, CharacterXYZ, Chat, type ChatEvents, type ChatMessage, type ClientEvents, CxError, type CxErrorCode, DEFAULT_API_URL, Emitter, type Features, type InitOptions, type Opening, type SessionInfo, VERSION, type VideoCharacter, type VideoClip, type VisitorStore };
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var K=Object.defineProperty;var j=(r,n,e)=>n in r?K(r,n,{enumerable:true,configurable:true,writable:true,value:e}):r[n]=e;var i=(r,n,e)=>j(r,typeof n!="symbol"?n+"":n,e);var v=null;function
|
|
1
|
+
var K=Object.defineProperty;var j=(r,n,e)=>n in r?K(r,n,{enumerable:true,configurable:true,writable:true,value:e}):r[n]=e;var i=(r,n,e)=>j(r,typeof n!="symbol"?n+"":n,e);var v=null;function I(){return (!v||v.state==="closed")&&(v=new AudioContext({latencyHint:"interactive"})),v.state==="suspended"&&v.resume().catch(()=>{}),v}var C=class{constructor(n={}){i(this,"opts",n);i(this,"ctx");i(this,"gain");i(this,"analyser");i(this,"data");i(this,"nextAt",0);i(this,"started",false);i(this,"ended",false);i(this,"finishing",false);i(this,"sources",new Set);i(this,"startedAt",0);i(this,"sampleRate");this.ctx=I(),this.sampleRate=n.sampleRate??16e3,this.gain=this.ctx.createGain(),this.gain.gain.value=n.volume??1,this.analyser=this.ctx.createAnalyser(),this.analyser.fftSize=512,this.data=new Uint8Array(new ArrayBuffer(this.analyser.fftSize)),this.gain.connect(this.analyser).connect(this.ctx.destination);}enqueue(n){if(this.ended||n.byteLength<2)return;let e=Math.floor(n.byteLength/2),t=new DataView(n.buffer,n.byteOffset,e*2),s=this.ctx.createBuffer(1,e,this.sampleRate),o=s.getChannelData(0);for(let h=0;h<e;h++)o[h]=t.getInt16(h*2,true)/32768;let a=this.ctx.createBufferSource();a.buffer=s,a.connect(this.gain);let c=this.ctx.currentTime;if(this.nextAt<c&&(this.nextAt=c+(this.started?.02:.12)),a.start(this.nextAt),!this.started){this.started=true;let h=Math.max(0,(this.nextAt-c)*1e3);this.startedAt=performance.now()+h,setTimeout(()=>this.opts.onStart?.(),h);}this.nextAt+=s.duration,this.sources.add(a),a.onended=()=>{this.sources.delete(a),this.finishing&&this.sources.size===0&&this.finish();};}end(){this.finishing=true,this.sources.size===0&&this.finish();}stop(){this.ended=true;for(let n of this.sources)try{n.stop();}catch{}this.sources.clear(),this.gain.disconnect();}playedMs(){return this.started?Math.max(0,performance.now()-this.startedAt):0}level(){this.analyser.getByteTimeDomainData(this.data);let n=0;for(let e=0;e<this.data.length;e++){let t=(this.data[e]-128)/128;n+=t*t;}return Math.min(1,Math.sqrt(n/this.data.length)*3)}finish(){this.ended||(this.ended=true,this.gain.disconnect(),this.opts.onEnd?.());}};var F=`
|
|
2
2
|
class CxyzMic extends AudioWorkletProcessor {
|
|
3
3
|
constructor(o) {
|
|
4
4
|
super();
|
|
@@ -30,13 +30,13 @@ class CxyzMic extends AudioWorkletProcessor {
|
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
registerProcessor('cxyz-mic', CxyzMic);
|
|
33
|
-
`;function q(r){let n=new Int16Array(r);if(!n.length)return 0;let e=0;for(let t=0;t<n.length;t++){let s=n[t]/32768;e+=s*s;}return Math.sqrt(e/n.length)}async function
|
|
33
|
+
`;function q(r){let n=new Int16Array(r);if(!n.length)return 0;let e=0;for(let t=0;t<n.length;t++){let s=n[t]/32768;e+=s*s;}return Math.sqrt(e/n.length)}async function P(r){if(!navigator.mediaDevices?.getUserMedia)throw new Error("This browser cannot use a microphone here.");let n=await navigator.mediaDevices.getUserMedia({audio:{deviceId:r.deviceId?{exact:r.deviceId}:void 0,channelCount:1,echoCancellation:true,noiseSuppression:true,autoGainControl:true}}),e=new AudioContext({latencyHint:"interactive"}),t=e.createMediaStreamSource(n),s=false,o=l=>{if(s){r.onFrame(new ArrayBuffer(l.byteLength),0);return}r.onFrame(l,q(l));},a,c;try{let l=URL.createObjectURL(new Blob([F],{type:"application/javascript"}));try{await e.audioWorklet.addModule(l);}finally{URL.revokeObjectURL(l);}let u=new AudioWorkletNode(e,"cxyz-mic");u.port.onmessage=f=>o(f.data),a=u,c=()=>{u.port.onmessage=null;};}catch{let l=e.createScriptProcessor(4096,1,1),u=e.sampleRate/16e3,f=0,m=new Int16Array(480),p=0;l.onaudioprocess=k=>{let b=k.inputBuffer.getChannelData(0);for(let M=0;M<b.length;M++)if(f+=1,f>=u){f-=u;let R=Math.max(-1,Math.min(1,b[M]));m[p++]=R<0?R*32768:R*32767,p===480&&(o(m.buffer),m=new Int16Array(480),p=0);}},a=l,c=()=>{l.onaudioprocess=null;};}t.connect(a);let h=e.createGain();return h.gain.value=0,a.connect(h).connect(e.destination),e.state==="suspended"&&await e.resume().catch(()=>{}),{get muted(){return s},setMuted(l){s=l;for(let u of n.getAudioTracks())u.enabled=!l;},stop(){c();try{t.disconnect(),a.disconnect();}catch{}for(let l of n.getTracks())l.stop();e.close().catch(()=>{});}}}var y=class{constructor(){i(this,"handlers",{});}on(n,e){var t;return ((t=this.handlers)[n]??(t[n]=new Set)).add(e),()=>this.handlers[n]?.delete(e)}emit(n,e){for(let t of this.handlers[n]??[])try{t(e);}catch(s){console.error("[characterxyz] listener threw",s);}}clear(){this.handlers={};}};var d=class extends Error{constructor(e,t,s=0){super(t);i(this,"code");i(this,"status");this.name="CxError",this.code=e,this.status=s;}};function T(r){switch(r){case 401:return "unauthorized";case 403:return "forbidden";case 404:return "not_found";case 402:return "payment_required";case 422:return "invalid";case 429:return "rate_limited";case 503:return "unavailable";default:return "unknown"}}async function z(r){let n="";try{let e=await r.json();typeof e?.message=="string"&&(n=e.message);}catch{}return new d(T(r.status),n||`Request failed (${r.status})`,r.status)}async function w(r,n,e={}){let t={};e.body!==void 0&&(t["Content-Type"]="application/json"),e.token&&(t.Authorization=`Bearer ${e.token}`);let s;try{s=await fetch(r+n,{method:e.method??(e.body===void 0?"GET":"POST"),headers:t,body:e.body===void 0?void 0:JSON.stringify(e.body),signal:e.signal,credentials:"omit",cache:"no-store"});}catch(o){throw o?.name==="AbortError"?o:new d("network","Could not reach Character XYZ. Check your connection.")}if(!s.ok)throw await z(s);return s}async function g(r,n,e={}){return (await(await w(r,n,e)).json()).data}async function A(r,n,e){let t=r.body;if(!t)return;let s=t.getReader(),o=new TextDecoder,a="",c=()=>{s.cancel().catch(()=>{});};e?.addEventListener("abort",c);try{for(;;){let{value:h,done:l}=await s.read();if(l)break;a+=o.decode(h,{stream:!0}),a=U(a,n);}a+=o.decode(),U(a+`
|
|
34
34
|
|
|
35
|
-
`,n);}finally{e?.removeEventListener("abort",c);}}function
|
|
35
|
+
`,n);}finally{e?.removeEventListener("abort",c);}}function U(r,n){let t=r.replace(/\r\n/g,`
|
|
36
36
|
`),s;for(;(s=t.indexOf(`
|
|
37
37
|
|
|
38
38
|
`))!==-1;){let o=t.slice(0,s);t=t.slice(s+2);let a="message",c=[];for(let u of o.split(`
|
|
39
|
-
`)){if(!u||u.startsWith(":"))continue;let
|
|
40
|
-
`),l=h;try{l=JSON.parse(h);}catch{}n({event:a,data:l});}return t}function U(r){if(r.byteLength<25)return null;let n=new DataView(r);if(n.getUint8(0)!==67||n.getUint8(1)!==88||n.getUint8(2)!==89||n.getUint8(3)!==90||n.getUint8(4)!==1)return null;let e=n.getUint8(5),t=(n.getUint8(6)&1)!==0,s=7,o=n.getUint16(s,true);if(s+=2,s+o+20>r.byteLength)return null;let a=new TextDecoder().decode(new Uint8Array(r,s,o));s+=o+4+8+4;let c=n.getUint32(s,true);return s+=4,s+c>r.byteLength?null:{kind:e,final:t,corr:a,payload:new Uint8Array(r,s,c)}}var $=.09,V=350,J=25e3,W=()=>({phase:"idle",callId:null,position:null,etaSeconds:null,holdSeconds:null,maxSeconds:null,startedAt:null,endReason:null,muted:false,speaking:false,agentState:"idle",error:null}),b=class extends g{constructor(e,t,s,o={}){super();i(this,"apiUrl",e);i(this,"session",t);i(this,"agentId",s);i(this,"opts",o);i(this,"s",W());i(this,"ticket",null);i(this,"eventsAbort",null);i(this,"ws",null);i(this,"mic",null);i(this,"players",new Map);i(this,"sampleRates",new Map);i(this,"cancelled",new Set);i(this,"speakingCorr",null);i(this,"heartbeat",null);i(this,"loudSince",null);}get state(){return this.s}audible(){let e=this.speakingCorr,t=e?this.players.get(e):void 0;return e&&t?{corr:e,ms:t.playedMs()}:null}voiceLevel(){let e=this.speakingCorr?this.players.get(this.speakingCorr):void 0;return e?e.level():0}set(e){this.s={...this.s,...e},this.emit("state",this.s);}async start(){if(this.s.phase==="idle"){this.set({phase:"joining"}),M();try{this.mic=await _({deviceId:this.opts.deviceId,onFrame:(e,t)=>this.onMicFrame(e,t)});}catch{this.finish("mic-denied","Allow the microphone to talk, or chat instead.");return}try{let e=await this.session.token(),t=await y(this.apiUrl,"/sdk/v1/calls",{method:"POST",body:{},token:e});this.set({callId:t.callId,phase:t.state==="ready"?"joining":"queued",position:t.position??null,etaSeconds:t.etaSeconds??null}),this.follow();}catch(e){let t=e instanceof d?e:new d("unknown","Could not start the call."),s=t.code==="rate_limited"?"busy":"unavailable";this.finish(s,t.message),this.emit("error",t);}}}async follow(){let e=0;for(;this.s.callId&&this.s.phase!=="ended"&&this.s.phase!=="idle";){this.eventsAbort=new AbortController;try{let t=await this.session.token(),s=await w(this.apiUrl,`/sdk/v1/calls/${encodeURIComponent(this.s.callId)}/events`,{token:t,signal:this.eventsAbort.signal});e=0,await k(s,o=>this.onServerEvent(o.event,o.data),this.eventsAbort.signal);}catch(t){if(t?.name==="AbortError")return;if(t instanceof d&&t.code==="not_found"){this.finish("failed","The call ended.");return}if(e+=1,e>5){this.finish("failed","Lost the connection to the call.");return}}if(this.ended())return;await new Promise(t=>setTimeout(t,Math.min(4e3,500*2**e)));}}onServerEvent(e,t){switch(e){case "queued":(this.s.phase==="joining"||this.s.phase==="queued")&&this.set({phase:"queued",position:Number(t.position)||1,etaSeconds:Number(t.etaSeconds)||null});break;case "ready":{typeof t.ticket=="string"&&t.ticket&&(this.ticket=t.ticket);let s=Number(t.holdSeconds)||0;this.s.phase!=="ready"&&this.s.phase!=="connecting"&&this.s.phase!=="live"?(this.set({phase:"ready",holdSeconds:s,position:null,etaSeconds:null}),this.emit("ready",{holdSeconds:s}),this.opts.autoAccept!==false&&this.accept()):this.s.phase==="ready"&&this.set({holdSeconds:s});break}case "live":this.set({phase:"live",maxSeconds:Number(t.maxSeconds)||null,startedAt:this.s.startedAt??Date.now()-(Number(t.elapsedSeconds)||0)*1e3});break;case "ended":this.finish(String(t.reason||"hangup")||"hangup",null);break}}ended(){return this.s.phase==="ended"}accept(){if(this.s.phase!=="ready"||!this.ticket||this.ws)return;this.set({phase:"connecting"});let e=this.apiUrl.replace(/^http/,"ws")+"/sdk/v1/calls/socket",t=new WebSocket(e,[`cxyz-ticket.${this.ticket}`]);this.ticket=null,t.binaryType="arraybuffer",this.ws=t,t.onopen=()=>{let s=this.opts.face,o=s?.emotion?.()??null;t.send(JSON.stringify({type:"agent_identity",agent_id:this.agentId,skin_index:0,blendshapes:!!s,...s?{blendshape_stream:true}:{},...s&&o?{face_emotion:o}:{}})),t.send(JSON.stringify({type:"mic_state",silero:"off",denoise:false})),this.heartbeat=setInterval(()=>this.sendJson({type:"heartbeat"}),J),this.set({phase:"live",startedAt:this.s.startedAt??Date.now()});},t.onmessage=s=>this.onSocket(s.data),t.onclose=()=>{this.ws=null,setTimeout(()=>{(this.s.phase==="live"||this.s.phase==="connecting")&&this.finish("hangup",null);},1500);};}sendJson(e){this.ws?.readyState===WebSocket.OPEN&&this.ws.send(JSON.stringify(e));}onMicFrame(e,t){let s=this.ws;if(!(!s||s.readyState!==WebSocket.OPEN)){if(this.speakingCorr){let o=performance.now();if(t>$){if(this.loudSince??(this.loudSince=o),o-this.loudSince>=V){this.loudSince=null,this.interrupt(),s.send(e);return}}else this.loudSince=null;s.send(new ArrayBuffer(e.byteLength));return}s.send(e);}}onSocket(e){if(e instanceof ArrayBuffer){let s=U(e);if(!s||this.cancelled.has(s.corr))return;if(s.kind===3){this.opts.face&&this.emit("face",{corr:s.corr,payload:s.payload.slice()});return}if(s.kind!==1)return;let o=this.players.get(s.corr);if(!o){for(let[c,h]of this.players)h.stop(),this.players.delete(c);let a=s.corr;o=new x({sampleRate:this.sampleRates.get(a)??16e3,onStart:()=>{this.speakingCorr=a,this.set({speaking:true}),this.emit("line",{corr:a,event:"audible"}),this.sendJson({type:"playback_started",correlationId:a,timestampMs:Date.now()});},onEnd:()=>{this.players.delete(a),this.speakingCorr===a&&(this.speakingCorr=null),this.set({speaking:false}),this.emit("line",{corr:a,event:"end"}),this.sendJson({type:"playback_ended",correlationId:a,timestampMs:Date.now(),reason:"natural"}),this.sendJson({type:"speech_ended"});}}),this.players.set(a,o);}o.enqueue(s.payload),s.final&&o.end();return}if(typeof e!="string")return;let t;try{t=JSON.parse(e);}catch{return}if("AgentSpeechMeta"in t){let s=t.AgentSpeechMeta;s?.correlation_id&&s.sample_rate&&this.sampleRates.set(s.correlation_id,s.sample_rate);return}if("InteractorTranscript"in t){let s=t.InteractorTranscript;s?.text&&this.emit("caption",{id:`v:${s.correlation_id}`,role:"visitor",text:s.text});return}if("AgentReplyTranscript"in t){let s=t.AgentReplyTranscript;s?.text&&!this.cancelled.has(s.correlation_id)&&this.emit("caption",{id:`a:${s.correlation_id}`,role:"agent",text:s.text});return}if(t.type==="turn_cancelled"&&typeof t.correlationId=="string"){let s=t.correlationId;this.cancelled.add(s),this.players.get(s)?.stop(),this.players.delete(s),this.emit("line",{corr:s,event:"end"}),this.speakingCorr===s&&(this.speakingCorr=null,this.set({speaking:false})),this.emit("captionRemoved",`a:${s}`);return}t.kind==="agent_status"&&typeof t.state=="string"&&this.set({agentState:t.state.toLowerCase()});}interrupt(){let e=this.speakingCorr;if(!e)return;let t=this.players.get(e),s=Math.round(t?.playedMs()??0);t?.stop(),this.players.delete(e),this.cancelled.add(e),this.speakingCorr=null,this.set({speaking:false}),this.emit("line",{corr:e,event:"end"}),this.sendJson({type:"playback_ended",correlationId:e,timestampMs:Date.now(),reason:"interrupted"}),this.sendJson({type:"interrupt",correlationId:e,heardMs:s,timestampMs:Date.now()});}setMuted(e){this.mic?.setMuted(e),this.set({muted:e});}async hangUp(){let e=this.s.callId,t=this.s.phase;if(this.finish(t==="live"?"hangup":"left",null),!!e)try{let s=await this.session.token();await w(this.apiUrl,`/sdk/v1/calls/${encodeURIComponent(e)}`,{method:"DELETE",token:s});}catch{}}finish(e,t){if(this.s.phase==="ended")return;this.eventsAbort?.abort(),this.eventsAbort=null,this.heartbeat&&clearInterval(this.heartbeat),this.heartbeat=null;for(let o of this.players.values())o.stop();this.players.clear(),this.speakingCorr=null,this.mic?.stop(),this.mic=null;let s=this.ws;this.ws=null,s&&s.readyState<=WebSocket.OPEN&&s.close(1e3),this.ticket=null,this.set({phase:"ended",endReason:e,speaking:false,holdSeconds:null,error:t});}};var G=0,O=r=>`${r}_${Date.now().toString(36)}_${(G++).toString(36)}`,S=class extends g{constructor(e,t){super();i(this,"apiUrl",e);i(this,"session",t);i(this,"list",[]);i(this,"loaded",false);i(this,"busy",false);i(this,"abort",null);}get messages(){return this.list}get isBusy(){return this.busy}publish(){this.list=[...this.list],this.emit("messages",this.list);}async load(){if(this.loaded)return this.list;let e=await this.session.token(),t=await y(this.apiUrl,"/sdk/v1/chat/messages?limit=50",{token:e}),s=this.list;return this.list=[...t?.messages??[],...s],this.loaded=true,this.publish(),this.list}async send(e){let t=e.trim();if(!t)throw new d("invalid","Say something first.");if(this.busy)throw new d("rate_limited","Wait for the reply first.");this.setBusy(true);let s={id:O("local"),role:"visitor",text:t,createdAt:new Date().toISOString()},o={id:O("reply"),role:"agent",text:"",createdAt:new Date().toISOString(),streaming:true};this.list.push(s,o),this.publish(),this.abort=new AbortController;try{let a=await this.session.token(),c=await w(this.apiUrl,"/sdk/v1/chat/messages",{method:"POST",body:{text:t},token:a,signal:this.abort.signal}),h=null,l=null;if(await k(c,({event:p,data:m})=>{let f=m;p==="delta"&&typeof f?.text=="string"?(o.text+=f.text,this.publish()):p==="done"?h={id:String(f.id),role:"agent",text:String(f.text??o.text),createdAt:String(f.createdAt??o.createdAt)}:p==="error"&&(l=typeof f?.message=="string"?f.message:"Something went wrong.");},this.abort.signal),l||!h)throw new d("unknown",l??"The reply was cut off. Try again.");let u=h;return this.replace(o.id,u),u}catch(a){let c=a instanceof d?a:new d("network","The reply was cut off. Try again.");this.list=this.list.filter(l=>l.id!==o.id);let h=this.list.findIndex(l=>l.id===s.id);throw h!==-1&&(this.list[h]={...s,failed:true}),this.publish(),a?.name!=="AbortError"&&this.emit("error",c),c}finally{this.abort=null,this.setBusy(false);}}retry(e){let t=this.list.find(s=>s.id===e&&s.failed);if(!t)throw new d("not_found","Nothing to retry.");return this.list=this.list.filter(s=>s.id!==e),this.publish(),this.send(t.text)}stop(){this.abort?.abort();}replace(e,t){let s=this.list.findIndex(o=>o.id===e);s!==-1&&(this.list[s]=t),this.publish();}setBusy(e){this.busy=e,this.emit("busy",e);}};var L=()=>{let r=new Map;return {get:n=>r.get(n)??null,set:(n,e)=>{r.set(n,e);}}},B=()=>({get(r){try{return globalThis.localStorage?.getItem(r)??null}catch{return null}},set(r,n){try{globalThis.localStorage?.setItem(r,n);}catch{}}}),H=60,C=class{constructor(n){i(this,"src",n);i(this,"current",null);i(this,"inflight",null);if(!n.publishableKey&&!n.getSessionToken)throw new d("invalid","Pass a publishableKey, or getSessionToken for sessions your server mints.")}visitorKey(){return `cxyz:visitor:${(this.src.publishableKey??"server").slice(-12)}`}get info(){return this.current}async token(){let n=Date.now()/1e3;return this.current&&this.current.expiresAt-H>n?this.current.token:(await this.refresh()).token}refresh(){return this.inflight??(this.inflight=this.mint().finally(()=>{this.inflight=null;})),this.inflight}async mint(){let n;if(this.src.getSessionToken){let e=await this.src.getSessionToken();typeof e=="string"?n=await this.describe(e):n=e;}else {let e=this.src.store.get(this.visitorKey())??void 0;n=await y(this.src.apiUrl,"/sdk/v1/sessions",{method:"POST",body:{publishableKey:this.src.publishableKey,agentId:this.src.agentId,visitorId:e}}),this.src.store.set(this.visitorKey(),n.visitorId);}return this.current=n,n}async describe(n){return {...await y(this.src.apiUrl,"/sdk/v1/session",{token:n}),token:n}}};var N="https://api.character.xyz",R=class r extends g{constructor(e,t,s){super();i(this,"apiUrl",e);i(this,"session",t);i(this,"info",s);i(this,"chat");i(this,"currentCall",null);i(this,"destroyed",false);this.chat=new S(e,t);}static async init(e){let t=(e.apiUrl??N).replace(/\/+$/,"");if(e.publishableKey&&/^cxyz_sk_/.test(e.publishableKey))throw new d("invalid","That is a SECRET key. Never put it in a web page: use a publishable key (cxyz_pk_\u2026). Revoke the secret key now.");let s=e.storage==="memory"?L():e.storage&&typeof e.storage=="object"?e.storage:B(),o=new C({apiUrl:t,agentId:e.agentId,publishableKey:e.publishableKey,getSessionToken:e.getSessionToken,store:s}),a=await o.refresh();return new r(t,o,a)}get agent(){return (this.session.info??this.info).agent}get features(){return (this.session.info??this.info).features}get appearance(){return (this.session.info??this.info).appearance??{}}get visitorId(){return (this.session.info??this.info).visitorId}get mode(){return (this.session.info??this.info).mode}get call(){return this.currentCall&&this.currentCall.state.phase!=="ended"?this.currentCall:null}async videoAvatar(){let e=await this.session.token();return y(this.apiUrl,"/sdk/v1/agent/video-avatar",{token:e})}async startCall(e={}){if(this.destroyed)throw new d("invalid","This client was destroyed.");if(!this.features.call)throw new d("forbidden","Calls are not available on this site.");if(this.call)return this.call;let t=new b(this.apiUrl,this.session,this.agent.id,e);return this.currentCall=t,t.on("state",s=>{s.phase==="ended"&&this.currentCall===t&&this.emit("call",null);}),t.on("error",s=>this.emit("error",s)),this.emit("call",t),await t.start(),t}destroy(){this.destroyed=true,this.currentCall?.hangUp(),this.chat.stop(),this.chat.clear(),this.clear();}};var Pe="0.1.0";
|
|
41
|
-
export{
|
|
39
|
+
`)){if(!u||u.startsWith(":"))continue;let f=u.indexOf(":"),m=f===-1?u:u.slice(0,f),p=f===-1?"":u.slice(f+1).replace(/^ /,"");m==="event"?a=p:m==="data"&&c.push(p);}if(!c.length)continue;let h=c.join(`
|
|
40
|
+
`),l=h;try{l=JSON.parse(h);}catch{}n({event:a,data:l});}return t}function O(r){if(r.byteLength<25)return null;let n=new DataView(r);if(n.getUint8(0)!==67||n.getUint8(1)!==88||n.getUint8(2)!==89||n.getUint8(3)!==90||n.getUint8(4)!==1)return null;let e=n.getUint8(5),t=(n.getUint8(6)&1)!==0,s=7,o=n.getUint16(s,true);if(s+=2,s+o+20>r.byteLength)return null;let a=new TextDecoder().decode(new Uint8Array(r,s,o));s+=o+4+8+4;let c=n.getUint32(s,true);return s+=4,s+c>r.byteLength?null:{kind:e,final:t,corr:a,payload:new Uint8Array(r,s,c)}}var $=.09,V=350,J=25e3,W=()=>({phase:"idle",callId:null,position:null,etaSeconds:null,holdSeconds:null,maxSeconds:null,startedAt:null,endReason:null,muted:false,speaking:false,agentState:"idle",error:null}),S=class extends y{constructor(e,t,s,o={}){super();i(this,"apiUrl",e);i(this,"session",t);i(this,"agentId",s);i(this,"opts",o);i(this,"s",W());i(this,"ticket",null);i(this,"eventsAbort",null);i(this,"ws",null);i(this,"mic",null);i(this,"players",new Map);i(this,"sampleRates",new Map);i(this,"cancelled",new Set);i(this,"speakingCorr",null);i(this,"heartbeat",null);i(this,"loudSince",null);}get state(){return this.s}audible(){let e=this.speakingCorr,t=e?this.players.get(e):void 0;return e&&t?{corr:e,ms:t.playedMs()}:null}voiceLevel(){let e=this.speakingCorr?this.players.get(this.speakingCorr):void 0;return e?e.level():0}set(e){this.s={...this.s,...e},this.emit("state",this.s);}async start(){if(this.s.phase==="idle"){this.set({phase:"joining"}),I();try{this.mic=await P({deviceId:this.opts.deviceId,onFrame:(e,t)=>this.onMicFrame(e,t)});}catch{this.finish("mic-denied","Allow the microphone to talk, or chat instead.");return}try{let e=await this.session.token(),t=await g(this.apiUrl,"/sdk/v1/calls",{method:"POST",body:{},token:e});this.set({callId:t.callId,phase:t.state==="ready"?"joining":"queued",position:t.position??null,etaSeconds:t.etaSeconds??null}),this.follow();}catch(e){let t=e instanceof d?e:new d("unknown","Could not start the call."),s=t.code==="rate_limited"?"busy":"unavailable";this.finish(s,t.message),this.emit("error",t);}}}async follow(){let e=0;for(;this.s.callId&&this.s.phase!=="ended"&&this.s.phase!=="idle";){this.eventsAbort=new AbortController;try{let t=await this.session.token(),s=await w(this.apiUrl,`/sdk/v1/calls/${encodeURIComponent(this.s.callId)}/events`,{token:t,signal:this.eventsAbort.signal});e=0,await A(s,o=>this.onServerEvent(o.event,o.data),this.eventsAbort.signal);}catch(t){if(t?.name==="AbortError")return;if(t instanceof d&&t.code==="not_found"){this.finish("failed","The call ended.");return}if(e+=1,e>5){this.finish("failed","Lost the connection to the call.");return}}if(this.ended())return;await new Promise(t=>setTimeout(t,Math.min(4e3,500*2**e)));}}onServerEvent(e,t){switch(e){case "queued":(this.s.phase==="joining"||this.s.phase==="queued")&&this.set({phase:"queued",position:Number(t.position)||1,etaSeconds:Number(t.etaSeconds)||null});break;case "ready":{typeof t.ticket=="string"&&t.ticket&&(this.ticket=t.ticket);let s=Number(t.holdSeconds)||0;this.s.phase!=="ready"&&this.s.phase!=="connecting"&&this.s.phase!=="live"?(this.set({phase:"ready",holdSeconds:s,position:null,etaSeconds:null}),this.emit("ready",{holdSeconds:s}),this.opts.autoAccept!==false&&this.accept()):this.s.phase==="ready"&&this.set({holdSeconds:s});break}case "live":this.set({phase:"live",maxSeconds:Number(t.maxSeconds)||null,startedAt:this.s.startedAt??Date.now()-(Number(t.elapsedSeconds)||0)*1e3});break;case "ended":this.finish(String(t.reason||"hangup")||"hangup",null);break}}ended(){return this.s.phase==="ended"}accept(){if(this.s.phase!=="ready"||!this.ticket||this.ws)return;this.set({phase:"connecting"});let e=this.apiUrl.replace(/^http/,"ws")+"/sdk/v1/calls/socket",t=new WebSocket(e,[`cxyz-ticket.${this.ticket}`]);this.ticket=null,t.binaryType="arraybuffer",this.ws=t,t.onopen=()=>{let s=this.opts.face,o=s?.emotion?.()??null;t.send(JSON.stringify({type:"agent_identity",agent_id:this.agentId,skin_index:0,blendshapes:!!s,...s?{blendshape_stream:true}:{},...s&&o?{face_emotion:o}:{}})),t.send(JSON.stringify({type:"mic_state",silero:"off",denoise:false})),this.heartbeat=setInterval(()=>this.sendJson({type:"heartbeat"}),J),this.set({phase:"live",startedAt:this.s.startedAt??Date.now()});},t.onmessage=s=>this.onSocket(s.data),t.onclose=()=>{this.ws=null,setTimeout(()=>{(this.s.phase==="live"||this.s.phase==="connecting")&&this.finish("hangup",null);},1500);};}sendJson(e){this.ws?.readyState===WebSocket.OPEN&&this.ws.send(JSON.stringify(e));}onMicFrame(e,t){let s=this.ws;if(!(!s||s.readyState!==WebSocket.OPEN)){if(this.speakingCorr){let o=performance.now();if(t>$){if(this.loudSince??(this.loudSince=o),o-this.loudSince>=V){this.loudSince=null,this.interrupt(),s.send(e);return}}else this.loudSince=null;s.send(new ArrayBuffer(e.byteLength));return}s.send(e);}}onSocket(e){if(e instanceof ArrayBuffer){let s=O(e);if(!s||this.cancelled.has(s.corr))return;if(s.kind===3){this.opts.face&&this.emit("face",{corr:s.corr,payload:s.payload.slice()});return}if(s.kind!==1)return;let o=this.players.get(s.corr);if(!o){for(let[c,h]of this.players)h.stop(),this.players.delete(c);let a=s.corr;o=new C({sampleRate:this.sampleRates.get(a)??16e3,onStart:()=>{this.speakingCorr=a,this.set({speaking:true}),this.emit("line",{corr:a,event:"audible"}),this.sendJson({type:"playback_started",correlationId:a,timestampMs:Date.now()});},onEnd:()=>{this.players.delete(a),this.speakingCorr===a&&(this.speakingCorr=null),this.set({speaking:false}),this.emit("line",{corr:a,event:"end"}),this.sendJson({type:"playback_ended",correlationId:a,timestampMs:Date.now(),reason:"natural"}),this.sendJson({type:"speech_ended"});}}),this.players.set(a,o);}o.enqueue(s.payload),s.final&&o.end();return}if(typeof e!="string")return;let t;try{t=JSON.parse(e);}catch{return}if("AgentSpeechMeta"in t){let s=t.AgentSpeechMeta;s?.correlation_id&&s.sample_rate&&this.sampleRates.set(s.correlation_id,s.sample_rate);return}if("InteractorTranscript"in t){let s=t.InteractorTranscript;s?.text&&this.emit("caption",{id:`v:${s.correlation_id}`,role:"visitor",text:s.text});return}if("AgentReplyTranscript"in t){let s=t.AgentReplyTranscript;s?.text&&!this.cancelled.has(s.correlation_id)&&this.emit("caption",{id:`a:${s.correlation_id}`,role:"agent",text:s.text});return}if(t.type==="turn_cancelled"&&typeof t.correlationId=="string"){let s=t.correlationId;this.cancelled.add(s),this.players.get(s)?.stop(),this.players.delete(s),this.emit("line",{corr:s,event:"end"}),this.speakingCorr===s&&(this.speakingCorr=null,this.set({speaking:false})),this.emit("captionRemoved",`a:${s}`);return}t.kind==="agent_status"&&typeof t.state=="string"&&this.set({agentState:t.state.toLowerCase()});}interrupt(){let e=this.speakingCorr;if(!e)return;let t=this.players.get(e),s=Math.round(t?.playedMs()??0);t?.stop(),this.players.delete(e),this.cancelled.add(e),this.speakingCorr=null,this.set({speaking:false}),this.emit("line",{corr:e,event:"end"}),this.sendJson({type:"playback_ended",correlationId:e,timestampMs:Date.now(),reason:"interrupted"}),this.sendJson({type:"interrupt",correlationId:e,heardMs:s,timestampMs:Date.now()});}setMuted(e){this.mic?.setMuted(e),this.set({muted:e});}async hangUp(){let e=this.s.callId,t=this.s.phase;if(this.finish(t==="live"?"hangup":"left",null),!!e)try{let s=await this.session.token();await w(this.apiUrl,`/sdk/v1/calls/${encodeURIComponent(e)}`,{method:"DELETE",token:s});}catch{}}finish(e,t){if(this.s.phase==="ended")return;this.eventsAbort?.abort(),this.eventsAbort=null,this.heartbeat&&clearInterval(this.heartbeat),this.heartbeat=null;for(let o of this.players.values())o.stop();this.players.clear(),this.speakingCorr=null,this.mic?.stop(),this.mic=null;let s=this.ws;this.ws=null,s&&s.readyState<=WebSocket.OPEN&&s.close(1e3),this.ticket=null,this.set({phase:"ended",endReason:e,speaking:false,holdSeconds:null,error:t});}};var G=0,L=r=>`${r}_${Date.now().toString(36)}_${(G++).toString(36)}`,x=class extends y{constructor(e,t){super();i(this,"apiUrl",e);i(this,"session",t);i(this,"list",[]);i(this,"loaded",false);i(this,"busy",false);i(this,"abort",null);}get messages(){return this.list}get isBusy(){return this.busy}publish(){this.list=[...this.list],this.emit("messages",this.list);}async load(){if(this.loaded)return this.list;let e=await this.session.token(),t=await g(this.apiUrl,"/sdk/v1/chat/messages?limit=50",{token:e}),s=this.list;return this.list=[...t?.messages??[],...s],this.loaded=true,this.publish(),this.list}async send(e){let t=e.trim();if(!t)throw new d("invalid","Say something first.");if(this.busy)throw new d("rate_limited","Wait for the reply first.");this.setBusy(true);let s={id:L("local"),role:"visitor",text:t,createdAt:new Date().toISOString()},o={id:L("reply"),role:"agent",text:"",createdAt:new Date().toISOString(),streaming:true};this.list.push(s,o),this.publish(),this.abort=new AbortController;try{let a=await this.session.token(),c=await w(this.apiUrl,"/sdk/v1/chat/messages",{method:"POST",body:{text:t},token:a,signal:this.abort.signal}),h=null,l=null;if(await A(c,({event:f,data:m})=>{let p=m;if(f==="delta"&&typeof p?.text=="string")o.text+=p.text,this.publish();else if(f==="done"){let k=Array.isArray(p.suggestions)?p.suggestions.filter(b=>typeof b=="string"&&b.trim()!==""):[];h={id:String(p.id),role:"agent",text:String(p.text??o.text),createdAt:String(p.createdAt??o.createdAt),...k.length?{suggestions:k}:{}};}else f==="error"&&(l=typeof p?.message=="string"?p.message:"Something went wrong.");},this.abort.signal),l||!h)throw new d("unknown",l??"The reply was cut off. Try again.");let u=h;return this.replace(o.id,u),u}catch(a){let c=a instanceof d?a:new d("network","The reply was cut off. Try again.");this.list=this.list.filter(l=>l.id!==o.id);let h=this.list.findIndex(l=>l.id===s.id);throw h!==-1&&(this.list[h]={...s,failed:true,...c.status===429?{error:c.message}:{}}),this.publish(),a?.name!=="AbortError"&&this.emit("error",c),c}finally{this.abort=null,this.setBusy(false);}}retry(e){let t=this.list.find(s=>s.id===e&&s.failed);if(!t)throw new d("not_found","Nothing to retry.");return this.list=this.list.filter(s=>s.id!==e),this.publish(),this.send(t.text)}stop(){this.abort?.abort();}replace(e,t){let s=this.list.findIndex(o=>o.id===e);s!==-1&&(this.list[s]=t),this.publish();}setBusy(e){this.busy=e,this.emit("busy",e);}};var B=()=>{let r=new Map;return {get:n=>r.get(n)??null,set:(n,e)=>{r.set(n,e);}}},N=()=>({get(r){try{return globalThis.localStorage?.getItem(r)??null}catch{return null}},set(r,n){try{globalThis.localStorage?.setItem(r,n);}catch{}}}),H=60,E=class{constructor(n){i(this,"src",n);i(this,"current",null);i(this,"inflight",null);if(!n.publishableKey&&!n.getSessionToken)throw new d("invalid","Pass a publishableKey, or getSessionToken for sessions your server mints.")}visitorKey(){return `cxyz:visitor:${(this.src.publishableKey??"server").slice(-12)}`}get info(){return this.current}async token(){let n=Date.now()/1e3;return this.current&&this.current.expiresAt-H>n?this.current.token:(await this.refresh()).token}refresh(){return this.inflight??(this.inflight=this.mint().finally(()=>{this.inflight=null;})),this.inflight}async mint(){let n;if(this.src.getSessionToken){let e=await this.src.getSessionToken();typeof e=="string"?n=await this.describe(e):n=e;}else {let e=this.src.store.get(this.visitorKey())??void 0;n=await g(this.src.apiUrl,"/sdk/v1/sessions",{method:"POST",body:{publishableKey:this.src.publishableKey,agentId:this.src.agentId,visitorId:e}}),this.src.store.set(this.visitorKey(),n.visitorId);}return this.current=n,n}async describe(n){return {...await g(this.src.apiUrl,"/sdk/v1/session",{token:n}),token:n}}};var D="https://api.character.xyz",_=class r extends y{constructor(e,t,s){super();i(this,"apiUrl",e);i(this,"session",t);i(this,"info",s);i(this,"chat");i(this,"currentCall",null);i(this,"destroyed",false);i(this,"openingP",null);this.chat=new x(e,t);}static async init(e){let t=(e.apiUrl??D).replace(/\/+$/,"");if(e.publishableKey&&/^cxyz_sk_/.test(e.publishableKey))throw new d("invalid","That is a SECRET key. Never put it in a web page: use a publishable key (cxyz_pk_\u2026). Revoke the secret key now.");let s=e.storage==="memory"?B():e.storage&&typeof e.storage=="object"?e.storage:N(),o=new E({apiUrl:t,agentId:e.agentId,publishableKey:e.publishableKey,getSessionToken:e.getSessionToken,store:s}),a=await o.refresh();return new r(t,o,a)}get agent(){return (this.session.info??this.info).agent}get features(){return (this.session.info??this.info).features}get appearance(){return (this.session.info??this.info).appearance??{}}get visitorId(){return (this.session.info??this.info).visitorId}get mode(){return (this.session.info??this.info).mode}get call(){return this.currentCall&&this.currentCall.state.phase!=="ended"?this.currentCall:null}async videoAvatar(){let e=await this.session.token();return g(this.apiUrl,"/sdk/v1/agent/video-avatar",{token:e})}opening(){return this.openingP??(this.openingP=this.session.token().then(e=>g(this.apiUrl,"/sdk/v1/agent/opening",{token:e})).catch(()=>null)),this.openingP}async startCall(e={}){if(this.destroyed)throw new d("invalid","This client was destroyed.");if(!this.features.call)throw new d("forbidden","Calls are not available on this site.");if(this.call)return this.call;let t=new S(this.apiUrl,this.session,this.agent.id,e);return this.currentCall=t,t.on("state",s=>{s.phase==="ended"&&this.currentCall===t&&this.emit("call",null);}),t.on("error",s=>this.emit("error",s)),this.emit("call",t),await t.start(),t}destroy(){this.destroyed=true,this.currentCall?.hangUp(),this.chat.stop(),this.chat.clear(),this.clear();}};var Te="0.2.0";
|
|
41
|
+
export{S as Call,_ as CharacterXYZ,x as Chat,d as CxError,D as DEFAULT_API_URL,y as Emitter,Te as VERSION};//# sourceMappingURL=index.js.map
|
|
42
42
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/audio/player.ts","../src/audio/mic.ts","../src/emitter.ts","../src/errors.ts","../src/http.ts","../src/protocol.ts","../src/call.ts","../src/chat.ts","../src/session.ts","../src/client.ts","../src/index.ts"],"names":["shared","audioContext","PcmPlayer","opts","__publicField","bytes","count","view","buf","ch","i","src","now","delayMs","s","sum","v","WORKLET","levelOf","pcm","openMic","stream","ctx","source","muted","deliver","node","teardown","url","w","e","sp","ratio","pos","out","n","sink","m","t","Emitter","event","fn","_a","payload","CxError","code","message","status","codeForStatus","errorFrom","res","j","send","apiUrl","path","headers","request","readEvents","onEvent","signal","body","reader","decoder","onAbort","value","done","drain","rest","idx","block","data","line","colon","field","raw","parsed","parsePacket","kind","final","o","corrLen","corr","len","BARGE_IN_LEVEL","BARGE_IN_MS","HEARTBEAT_MS","initial","Call","session","agentId","p","patch","level","token","r","err","reason","failures","d","hold","ws","face","emotion","player","old","cid","heardMs","id","was","error","localSeq","localId","Chat","pending","text","mine","reply","finished","failure","x","next","b","memoryStore","k","localStore","RENEW_EARLY_S","SessionManager","info","got","visitorId","DEFAULT_API_URL","CharacterXYZ","_CharacterXYZ","store","call","VERSION"],"mappings":"0KAiBA,IAAIA,CAAAA,CAA8B,KAG3B,SAASC,CAAAA,EAA6B,CAC3C,OAAA,CAAI,CAACD,CAAAA,EAAUA,CAAAA,CAAO,KAAA,GAAU,QAAA,IAAUA,EAAS,IAAI,YAAA,CAAa,CAAE,WAAA,CAAa,aAAc,CAAC,CAAA,CAAA,CAC9FA,CAAAA,CAAO,KAAA,GAAU,WAAA,EAAkBA,CAAAA,CAAO,MAAA,GAAS,KAAA,CAAM,IAAM,CAAC,CAAC,CAAA,CAC9DA,CACT,CAEO,IAAME,CAAAA,CAAN,KAAgB,CAarB,WAAA,CAA6BC,EAAsB,EAAC,CAAG,CAA1BC,CAAAA,CAAA,IAAA,CAAA,MAAA,CAAAD,GAZ7BC,CAAAA,CAAA,IAAA,CAAiB,KAAA,CAAA,CACjBA,CAAAA,CAAA,IAAA,CAAiB,MAAA,CAAA,CACjBA,EAAA,IAAA,CAAiB,UAAA,CAAA,CACjBA,EAAA,IAAA,CAAiB,MAAA,CAAA,CACjBA,EAAA,IAAA,CAAQ,QAAA,CAAS,CAAA,CAAA,CACjBA,CAAAA,CAAA,IAAA,CAAQ,SAAA,CAAU,OAClBA,CAAAA,CAAA,IAAA,CAAQ,QAAQ,KAAA,CAAA,CAChBA,CAAAA,CAAA,KAAQ,WAAA,CAAY,KAAA,CAAA,CACpBA,CAAAA,CAAA,IAAA,CAAQ,SAAA,CAAU,IAAI,KACtBA,CAAAA,CAAA,IAAA,CAAQ,YAAY,CAAA,CAAA,CACpBA,CAAAA,CAAA,KAAS,YAAA,CAAA,CAGP,IAAA,CAAK,GAAA,CAAMH,CAAAA,EAAa,CACxB,IAAA,CAAK,WAAaE,CAAAA,CAAK,UAAA,EAAc,KACrC,IAAA,CAAK,IAAA,CAAO,KAAK,GAAA,CAAI,UAAA,EAAW,CAChC,IAAA,CAAK,IAAA,CAAK,IAAA,CAAK,MAAQA,CAAAA,CAAK,MAAA,EAAU,EACtC,IAAA,CAAK,QAAA,CAAW,KAAK,GAAA,CAAI,cAAA,EAAe,CACxC,IAAA,CAAK,QAAA,CAAS,OAAA,CAAU,IACxB,IAAA,CAAK,IAAA,CAAO,IAAI,UAAA,CAAW,IAAI,YAAY,IAAA,CAAK,QAAA,CAAS,OAAO,CAAC,CAAA,CACjE,IAAA,CAAK,KAAK,OAAA,CAAQ,IAAA,CAAK,QAAQ,CAAA,CAAE,OAAA,CAAQ,KAAK,GAAA,CAAI,WAAW,EAC/D,CAGA,OAAA,CAAQE,CAAAA,CAAyB,CAC/B,GAAI,IAAA,CAAK,OAASA,CAAAA,CAAM,UAAA,CAAa,EAAG,OACxC,IAAMC,CAAAA,CAAQ,IAAA,CAAK,KAAA,CAAMD,CAAAA,CAAM,WAAa,CAAC,CAAA,CACvCE,EAAO,IAAI,QAAA,CAASF,EAAM,MAAA,CAAQA,CAAAA,CAAM,UAAA,CAAYC,CAAAA,CAAQ,CAAC,CAAA,CAC7DE,EAAM,IAAA,CAAK,GAAA,CAAI,aAAa,CAAA,CAAGF,CAAAA,CAAO,KAAK,UAAU,CAAA,CACrDG,CAAAA,CAAKD,CAAAA,CAAI,cAAA,CAAe,CAAC,EAC/B,IAAA,IAASE,CAAAA,CAAI,EAAGA,CAAAA,CAAIJ,CAAAA,CAAOI,IAAKD,CAAAA,CAAGC,CAAC,CAAA,CAAIH,CAAAA,CAAK,QAAA,CAASG,CAAAA,CAAI,EAAG,IAAI,CAAA,CAAI,MACrE,IAAMC,CAAAA,CAAM,KAAK,GAAA,CAAI,kBAAA,EAAmB,CACxCA,CAAAA,CAAI,MAAA,CAASH,CAAAA,CACbG,EAAI,OAAA,CAAQ,IAAA,CAAK,IAAI,CAAA,CACrB,IAAMC,EAAM,IAAA,CAAK,GAAA,CAAI,WAAA,CAGrB,GAFI,IAAA,CAAK,MAAA,CAASA,IAAK,IAAA,CAAK,MAAA,CAASA,GAAO,IAAA,CAAK,OAAA,CAAU,IAAO,GAAA,CAAA,CAAA,CAClED,CAAAA,CAAI,KAAA,CAAM,IAAA,CAAK,MAAM,CAAA,CACjB,CAAC,IAAA,CAAK,OAAA,CAAS,CACjB,IAAA,CAAK,OAAA,CAAU,KACf,IAAME,CAAAA,CAAU,IAAA,CAAK,GAAA,CAAI,CAAA,CAAA,CAAI,IAAA,CAAK,OAASD,CAAAA,EAAO,GAAI,EACtD,IAAA,CAAK,SAAA,CAAY,YAAY,GAAA,EAAI,CAAIC,CAAAA,CACrC,UAAA,CAAW,IAAM,IAAA,CAAK,KAAK,OAAA,IAAU,CAAGA,CAAO,EACjD,CACA,KAAK,MAAA,EAAUL,CAAAA,CAAI,QAAA,CACnB,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAIG,CAAG,CAAA,CACpBA,CAAAA,CAAI,QAAU,IAAM,CAClB,KAAK,OAAA,CAAQ,MAAA,CAAOA,CAAG,CAAA,CACnB,IAAA,CAAK,SAAA,EAAa,KAAK,OAAA,CAAQ,IAAA,GAAS,GAAG,IAAA,CAAK,MAAA,GACtD,EACF,CAGA,GAAA,EAAY,CACV,IAAA,CAAK,SAAA,CAAY,KACb,IAAA,CAAK,OAAA,CAAQ,OAAS,CAAA,EAAG,IAAA,CAAK,SACpC,CAGA,IAAA,EAAa,CACX,IAAA,CAAK,KAAA,CAAQ,KACb,IAAA,IAAWG,CAAAA,IAAK,KAAK,OAAA,CACnB,GAAI,CACFA,CAAAA,CAAE,IAAA,GACJ,CAAA,KAAQ,CAER,CAEF,KAAK,OAAA,CAAQ,KAAA,GACb,IAAA,CAAK,IAAA,CAAK,aACZ,CAGA,QAAA,EAAmB,CACjB,OAAO,IAAA,CAAK,QAAU,IAAA,CAAK,GAAA,CAAI,EAAG,WAAA,CAAY,GAAA,GAAQ,IAAA,CAAK,SAAS,CAAA,CAAI,CAC1E,CAGA,KAAA,EAAgB,CACd,IAAA,CAAK,QAAA,CAAS,sBAAsB,IAAA,CAAK,IAAI,EAC7C,IAAIC,CAAAA,CAAM,CAAA,CACV,IAAA,IAASL,CAAAA,CAAI,CAAA,CAAGA,EAAI,IAAA,CAAK,IAAA,CAAK,OAAQA,CAAAA,EAAAA,CAAK,CACzC,IAAMM,CAAAA,CAAAA,CAAK,IAAA,CAAK,IAAA,CAAKN,CAAC,CAAA,CAAK,GAAA,EAAO,IAClCK,CAAAA,EAAOC,CAAAA,CAAIA,EACb,CACA,OAAO,KAAK,GAAA,CAAI,CAAA,CAAG,IAAA,CAAK,IAAA,CAAKD,CAAAA,CAAM,IAAA,CAAK,KAAK,MAAM,CAAA,CAAI,CAAC,CAC1D,CAEQ,QAAS,CACX,IAAA,CAAK,KAAA,GACT,IAAA,CAAK,KAAA,CAAQ,IAAA,CACb,KAAK,IAAA,CAAK,UAAA,GACV,IAAA,CAAK,IAAA,CAAK,SAAQ,EACpB,CACF,CAAA,CC5GA,IAAME,CAAAA,CAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CA8CT,SAASC,CAAAA,CAAQC,CAAAA,CAA0B,CAChD,IAAML,CAAAA,CAAI,IAAI,UAAA,CAAWK,CAAG,EAC5B,GAAI,CAACL,EAAE,MAAA,CAAQ,SACf,IAAIC,CAAAA,CAAM,EACV,IAAA,IAASL,CAAAA,CAAI,CAAA,CAAGA,CAAAA,CAAII,EAAE,MAAA,CAAQJ,CAAAA,EAAAA,CAAK,CACjC,IAAMM,CAAAA,CAAIF,EAAEJ,CAAC,CAAA,CAAK,MAClBK,CAAAA,EAAOC,CAAAA,CAAIA,EACb,CACA,OAAO,KAAK,IAAA,CAAKD,CAAAA,CAAMD,EAAE,MAAM,CACjC,CAEA,eAAsBM,EAAQjB,CAAAA,CAAgC,CAC5D,GAAI,CAAC,SAAA,CAAU,cAAc,YAAA,CAAc,MAAM,IAAI,KAAA,CAAM,4CAA4C,EACvG,IAAMkB,CAAAA,CAAS,MAAM,SAAA,CAAU,YAAA,CAAa,aAAa,CACvD,KAAA,CAAO,CACL,QAAA,CAAUlB,CAAAA,CAAK,SAAW,CAAE,KAAA,CAAOA,EAAK,QAAS,CAAA,CAAI,OACrD,YAAA,CAAc,CAAA,CAGd,iBAAkB,IAAA,CAClB,gBAAA,CAAkB,KAClB,eAAA,CAAiB,IACnB,CACF,CAAC,CAAA,CACKmB,EAAM,IAAI,YAAA,CAAa,CAAE,WAAA,CAAa,aAAc,CAAC,CAAA,CACrDC,EAASD,CAAAA,CAAI,uBAAA,CAAwBD,CAAM,CAAA,CAC7CG,CAAAA,CAAQ,MACNC,CAAAA,CAAWjB,CAAAA,EAAqB,CACpC,GAAIgB,CAAAA,CAAO,CAGTrB,CAAAA,CAAK,OAAA,CAAQ,IAAI,WAAA,CAAYK,CAAAA,CAAI,UAAU,CAAA,CAAG,CAAC,EAC/C,MACF,CACAL,EAAK,OAAA,CAAQK,CAAAA,CAAKU,EAAQV,CAAG,CAAC,EAChC,CAAA,CAEIkB,CAAAA,CACAC,EACJ,GAAI,CACF,IAAMC,CAAAA,CAAM,GAAA,CAAI,gBAAgB,IAAI,IAAA,CAAK,CAACX,CAAO,EAAG,CAAE,IAAA,CAAM,wBAAyB,CAAC,CAAC,EACvF,GAAI,CACF,MAAMK,CAAAA,CAAI,YAAA,CAAa,UAAUM,CAAG,EACtC,QAAE,CACA,GAAA,CAAI,gBAAgBA,CAAG,EACzB,CACA,IAAMC,CAAAA,CAAI,IAAI,gBAAA,CAAiBP,CAAAA,CAAK,UAAU,CAAA,CAC9CO,CAAAA,CAAE,KAAK,SAAA,CAAaC,CAAAA,EAAML,EAAQK,CAAAA,CAAE,IAAmB,EACvDJ,CAAAA,CAAOG,CAAAA,CACPF,EAAW,IAAM,CACfE,EAAE,IAAA,CAAK,SAAA,CAAY,KACrB,EACF,MAAQ,CAGN,IAAME,EAAKT,CAAAA,CAAI,qBAAA,CAAsB,KAAM,CAAA,CAAG,CAAC,EACzCU,CAAAA,CAAQV,CAAAA,CAAI,WAAa,IAAA,CAC3BW,CAAAA,CAAM,EACNC,CAAAA,CAAM,IAAI,WAAW,GAAa,CAAA,CAClCC,EAAI,CAAA,CACRJ,CAAAA,CAAG,eAAkBD,CAAAA,EAAM,CACzB,IAAMrB,CAAAA,CAAKqB,CAAAA,CAAE,YAAY,cAAA,CAAe,CAAC,EACzC,IAAA,IAASpB,CAAAA,CAAI,EAAGA,CAAAA,CAAID,CAAAA,CAAG,OAAQC,CAAAA,EAAAA,CAE7B,GADAuB,GAAO,CAAA,CACHA,CAAAA,EAAOD,CAAAA,CAAO,CAChBC,GAAOD,CAAAA,CACP,IAAMlB,EAAI,IAAA,CAAK,GAAA,CAAI,GAAI,IAAA,CAAK,GAAA,CAAI,EAAGL,CAAAA,CAAGC,CAAC,CAAE,CAAC,CAAA,CAC1CwB,EAAIC,CAAAA,EAAG,CAAA,CAAIrB,EAAI,CAAA,CAAIA,CAAAA,CAAI,MAASA,CAAAA,CAAI,KAAA,CAChCqB,IAAM,GAAA,GACRV,CAAAA,CAAQS,EAAI,MAAM,CAAA,CAClBA,EAAM,IAAI,UAAA,CAAW,GAAa,CAAA,CAClCC,CAAAA,CAAI,GAER,CAEJ,CAAA,CACAT,EAAOK,CAAAA,CACPJ,CAAAA,CAAW,IAAM,CACfI,CAAAA,CAAG,cAAA,CAAiB,KACtB,EACF,CACAR,CAAAA,CAAO,QAAQG,CAAI,CAAA,CAGnB,IAAMU,CAAAA,CAAOd,CAAAA,CAAI,YAAW,CAC5B,OAAAc,EAAK,IAAA,CAAK,KAAA,CAAQ,EAClBV,CAAAA,CAAK,OAAA,CAAQU,CAAI,CAAA,CAAE,OAAA,CAAQd,EAAI,WAAW,CAAA,CACtCA,EAAI,KAAA,GAAU,WAAA,EAAa,MAAMA,CAAAA,CAAI,MAAA,GAAS,KAAA,CAAM,IAAM,CAAC,CAAC,CAAA,CAEzD,CACL,IAAI,KAAA,EAAQ,CACV,OAAOE,CACT,EACA,QAAA,CAASa,CAAAA,CAAY,CACnBb,CAAAA,CAAQa,EACR,IAAA,IAAWC,CAAAA,IAAKjB,EAAO,cAAA,EAAe,CAAGiB,EAAE,OAAA,CAAU,CAACD,EACxD,CAAA,CACA,IAAA,EAAO,CACLV,CAAAA,EAAS,CACT,GAAI,CACFJ,CAAAA,CAAO,YAAW,CAClBG,CAAAA,CAAK,aACP,CAAA,KAAQ,CAER,CACA,IAAA,IAAWY,KAAKjB,CAAAA,CAAO,SAAA,GAAaiB,CAAAA,CAAE,IAAA,GACjChB,CAAAA,CAAI,KAAA,GAAQ,KAAA,CAAM,IAAM,CAAC,CAAC,EACjC,CACF,CACF,CCtKO,IAAMiB,CAAAA,CAAN,KAAsD,CAAtD,WAAA,EAAA,CACLnC,EAAA,IAAA,CAAQ,UAAA,CAAwE,EAAC,EAAA,CAEjF,EAAA,CAA2BoC,EAAUC,CAAAA,CAA8C,CAJrF,IAAAC,CAAAA,CAKI,OAAA,CAAA,CAACA,EAAA,IAAA,CAAK,QAAA,EAALF,KAAAE,CAAAA,CAAAF,CAAAA,CAAAA,CAAyB,IAAI,GAAA,CAAA,EAAO,GAAA,CAAIC,CAAE,CAAA,CACpC,IAAM,KAAK,QAAA,CAASD,CAAK,GAAG,MAAA,CAAOC,CAAE,CAC9C,CAEA,IAAA,CAA6BD,EAAUG,CAAAA,CAA0B,CAC/D,QAAWF,CAAAA,IAAM,IAAA,CAAK,SAASD,CAAK,CAAA,EAAK,EAAC,CACxC,GAAI,CACFC,CAAAA,CAAGE,CAAO,EACZ,CAAA,MAASb,EAAG,CAEV,OAAA,CAAQ,MAAM,+BAAA,CAAiCA,CAAC,EAClD,CAEJ,CAEA,OAAc,CACZ,IAAA,CAAK,SAAW,GAClB,CACF,ECXO,IAAMc,EAAN,cAAsB,KAAM,CAIjC,WAAA,CAAYC,CAAAA,CAAmBC,EAAiBC,CAAAA,CAAS,CAAA,CAAG,CAC1D,KAAA,CAAMD,CAAO,EAJf1C,CAAAA,CAAA,IAAA,CAAS,QACTA,CAAAA,CAAA,IAAA,CAAS,UAIP,IAAA,CAAK,IAAA,CAAO,SAAA,CACZ,IAAA,CAAK,KAAOyC,CAAAA,CACZ,IAAA,CAAK,OAASE,EAChB,CACF,EAEO,SAASC,CAAAA,CAAcD,EAA6B,CACzD,OAAQA,GACN,SACE,OAAO,cAAA,CACT,KAAK,GAAA,CACH,OAAO,YACT,KAAK,GAAA,CACH,OAAO,WAAA,CACT,SACE,OAAO,kBAAA,CACT,KAAK,GAAA,CACH,OAAO,UACT,KAAK,GAAA,CACH,OAAO,cAAA,CACT,SACE,OAAO,aAAA,CACT,QACE,OAAO,SACX,CACF,CClCA,eAAeE,CAAAA,CAAUC,CAAAA,CAAiC,CACxD,IAAIJ,CAAAA,CAAU,GACd,GAAI,CACF,IAAMK,CAAAA,CAAK,MAAMD,EAAI,IAAA,EAAK,CACtB,OAAOC,CAAAA,EAAG,OAAA,EAAY,WAAUL,CAAAA,CAAUK,CAAAA,CAAE,SAClD,CAAA,KAAQ,CAER,CACA,OAAO,IAAIP,EAAQI,CAAAA,CAAcE,CAAAA,CAAI,MAAM,CAAA,CAAGJ,CAAAA,EAAW,mBAAmBI,CAAAA,CAAI,MAAM,IAAKA,CAAAA,CAAI,MAAM,CACvG,CAEA,eAAsBE,EAAKC,CAAAA,CAAgBC,CAAAA,CAAcnD,CAAAA,CAAuB,GAAuB,CACrG,IAAMoD,EAAkC,EAAC,CACrCpD,EAAK,IAAA,GAAS,MAAA,GAAWoD,EAAQ,cAAc,CAAA,CAAI,oBACnDpD,CAAAA,CAAK,KAAA,GAAOoD,EAAQ,aAAA,CAAgB,CAAA,OAAA,EAAUpD,EAAK,KAAK,CAAA,CAAA,CAAA,CAC5D,IAAI+C,CAAAA,CACJ,GAAI,CACFA,CAAAA,CAAM,MAAM,MAAMG,CAAAA,CAASC,CAAAA,CAAM,CAC/B,MAAA,CAAQnD,CAAAA,CAAK,SAAWA,CAAAA,CAAK,IAAA,GAAS,OAAY,KAAA,CAAQ,MAAA,CAAA,CAC1D,QAAAoD,CAAAA,CACA,IAAA,CAAMpD,EAAK,IAAA,GAAS,KAAA,CAAA,CAAY,KAAA,CAAA,CAAY,IAAA,CAAK,UAAUA,CAAAA,CAAK,IAAI,EACpE,MAAA,CAAQA,CAAAA,CAAK,OAGb,WAAA,CAAa,MAAA,CACb,MAAO,UACT,CAAC,EACH,CAAA,MAAS2B,CAAAA,CAAG,CACV,MAAKA,CAAAA,EAAa,OAAS,YAAA,CAAoBA,CAAAA,CACzC,IAAIc,CAAAA,CAAQ,SAAA,CAAW,uDAAuD,CACtF,CACA,GAAI,CAACM,CAAAA,CAAI,GAAI,MAAM,MAAMD,EAAUC,CAAG,CAAA,CACtC,OAAOA,CACT,CAGA,eAAsBM,CAAAA,CAAWH,CAAAA,CAAgBC,EAAcnD,CAAAA,CAAuB,EAAC,CAAe,CAGpG,QADW,KAAA,CADC,MAAMiD,EAAKC,CAAAA,CAAQC,CAAAA,CAAMnD,CAAI,CAAA,EACpB,IAAA,IACZ,IACX,CAYA,eAAsBsD,CAAAA,CAAWP,CAAAA,CAAeQ,EAAmCC,CAAAA,CAAqC,CACtH,IAAMC,CAAAA,CAAOV,CAAAA,CAAI,KACjB,GAAI,CAACU,EAAM,OACX,IAAMC,EAASD,CAAAA,CAAK,SAAA,GACdE,CAAAA,CAAU,IAAI,YAChBtD,CAAAA,CAAM,EAAA,CACJuD,EAAU,IAAG,CAAQF,EAAO,MAAA,EAAO,CAAE,MAAM,IAAM,CAAC,CAAC,EAAA,CAAA,CACzDF,GAAQ,gBAAA,CAAiB,OAAA,CAASI,CAAO,CAAA,CACzC,GAAI,CACF,OAAS,CACP,GAAM,CAAE,KAAA,CAAAC,EAAO,IAAA,CAAAC,CAAK,EAAI,MAAMJ,CAAAA,CAAO,MAAK,CAC1C,GAAII,EAAM,MACVzD,CAAAA,EAAOsD,EAAQ,MAAA,CAAOE,CAAAA,CAAO,CAAE,MAAA,CAAQ,CAAA,CAAK,CAAC,CAAA,CAC7CxD,CAAAA,CAAM0D,EAAM1D,CAAAA,CAAKkD,CAAO,EAC1B,CACAlD,CAAAA,EAAOsD,EAAQ,MAAA,EAAO,CACtBI,EAAM1D,CAAAA,CAAM;;AAAA,CAAA,CAAQkD,CAAO,EAC7B,CAAA,OAAE,CACAC,GAAQ,mBAAA,CAAoB,OAAA,CAASI,CAAO,EAC9C,CACF,CAGO,SAASG,CAAAA,CAAM1D,EAAakD,CAAAA,CAA2C,CAE5E,IAAIS,CAAAA,CADe3D,CAAAA,CAAI,QAAQ,OAAA,CAAS;AAAA,CAAI,CAAA,CAExC4D,CAAAA,CACJ,KAAA,CAAQA,CAAAA,CAAMD,EAAK,OAAA,CAAQ;;AAAA,CAAM,CAAA,IAAO,EAAA,EAAI,CAC1C,IAAME,CAAAA,CAAQF,EAAK,KAAA,CAAM,CAAA,CAAGC,CAAG,CAAA,CAC/BD,CAAAA,CAAOA,CAAAA,CAAK,MAAMC,CAAAA,CAAM,CAAC,CAAA,CACzB,IAAI5B,CAAAA,CAAQ,SAAA,CACN8B,CAAAA,CAAiB,EAAC,CACxB,IAAA,IAAWC,CAAAA,IAAQF,CAAAA,CAAM,KAAA,CAAM;AAAA,CAAI,CAAA,CAAG,CACpC,GAAI,CAACE,CAAAA,EAAQA,CAAAA,CAAK,UAAA,CAAW,GAAG,CAAA,CAAG,SACnC,IAAMC,CAAAA,CAAQD,CAAAA,CAAK,QAAQ,GAAG,CAAA,CACxBE,CAAAA,CAAQD,CAAAA,GAAU,EAAA,CAAKD,CAAAA,CAAOA,CAAAA,CAAK,KAAA,CAAM,CAAA,CAAGC,CAAK,CAAA,CACjDR,CAAAA,CAAQQ,CAAAA,GAAU,EAAA,CAAK,GAAKD,CAAAA,CAAK,KAAA,CAAMC,CAAAA,CAAQ,CAAC,CAAA,CAAE,OAAA,CAAQ,IAAA,CAAM,EAAE,CAAA,CACpEC,CAAAA,GAAU,OAAA,CAASjC,CAAAA,CAAQwB,CAAAA,CACtBS,CAAAA,GAAU,MAAA,EAAQH,CAAAA,CAAK,IAAA,CAAKN,CAAK,EAC5C,CACA,GAAI,CAACM,CAAAA,CAAK,MAAA,CAAQ,SAClB,IAAMI,CAAAA,CAAMJ,CAAAA,CAAK,IAAA,CAAK;AAAA,CAAI,EACtBK,CAAAA,CAAkBD,CAAAA,CACtB,GAAI,CACFC,EAAS,IAAA,CAAK,KAAA,CAAMD,CAAG,EACzB,MAAQ,CAER,CACAhB,EAAQ,CAAE,KAAA,CAAAlB,EAAO,IAAA,CAAMmC,CAAO,CAAC,EACjC,CACA,OAAOR,CACT,CC/FO,SAASS,EAAYpE,CAAAA,CAAiC,CAC3D,GAAIA,CAAAA,CAAI,WAAa,EAAA,CAAI,OAAO,KAChC,IAAMQ,CAAAA,CAAI,IAAI,QAAA,CAASR,CAAG,CAAA,CAE1B,GADIQ,EAAE,QAAA,CAAS,CAAC,CAAA,GAAM,EAAA,EAAQA,EAAE,QAAA,CAAS,CAAC,CAAA,GAAM,EAAA,EAAQA,EAAE,QAAA,CAAS,CAAC,IAAM,EAAA,EAAQA,CAAAA,CAAE,SAAS,CAAC,CAAA,GAAM,EAAA,EAChGA,CAAAA,CAAE,SAAS,CAAC,CAAA,GAAM,EAAG,OAAO,IAAA,CAChC,IAAM6D,CAAAA,CAAO7D,CAAAA,CAAE,QAAA,CAAS,CAAC,EACnB8D,CAAAA,CAAAA,CAAS9D,CAAAA,CAAE,SAAS,CAAC,CAAA,CAAI,KAAO,CAAA,CAClC+D,CAAAA,CAAI,CAAA,CACFC,CAAAA,CAAUhE,EAAE,SAAA,CAAU+D,CAAAA,CAAG,IAAI,CAAA,CAEnC,GADAA,CAAAA,EAAK,CAAA,CACDA,CAAAA,CAAIC,CAAAA,CAAU,GAAKxE,CAAAA,CAAI,UAAA,CAAY,OAAO,IAAA,CAC9C,IAAMyE,EAAO,IAAI,WAAA,EAAY,CAAE,MAAA,CAAO,IAAI,UAAA,CAAWzE,CAAAA,CAAKuE,EAAGC,CAAO,CAAC,EACrED,CAAAA,EAAKC,CAAAA,CAAU,CAAA,CAAI,CAAA,CAAI,EACvB,IAAME,CAAAA,CAAMlE,EAAE,SAAA,CAAU+D,CAAAA,CAAG,IAAI,CAAA,CAE/B,OADAA,CAAAA,EAAK,CAAA,CACDA,EAAIG,CAAAA,CAAM1E,CAAAA,CAAI,UAAA,CAAmB,IAAA,CAC9B,CAAE,IAAA,CAAAqE,CAAAA,CAAM,KAAA,CAAAC,CAAAA,CAAO,KAAAG,CAAAA,CAAM,OAAA,CAAS,IAAI,UAAA,CAAWzE,CAAAA,CAAKuE,EAAGG,CAAG,CAAE,CACnE,KCGMC,CAAAA,CAAiB,GAAA,CACjBC,EAAc,GAAA,CACdC,CAAAA,CAAe,KAEfC,CAAAA,CAAU,KAAkB,CAChC,KAAA,CAAO,OACP,MAAA,CAAQ,IAAA,CACR,SAAU,IAAA,CACV,UAAA,CAAY,KACZ,WAAA,CAAa,IAAA,CACb,UAAA,CAAY,IAAA,CACZ,UAAW,IAAA,CACX,SAAA,CAAW,IAAA,CACX,KAAA,CAAO,MACP,QAAA,CAAU,KAAA,CACV,UAAA,CAAY,MAAA,CACZ,MAAO,IACT,CAAA,CAAA,CAMaC,EAAN,cAAmBhD,CAAoB,CAa5C,WAAA,CACmBc,CAAAA,CACAmC,CAAAA,CACAC,CAAAA,CACAtF,EAAoB,EAAC,CACtC,CACA,KAAA,GALiBC,CAAAA,CAAA,IAAA,CAAA,QAAA,CAAAiD,CAAAA,CAAAA,CACAjD,CAAAA,CAAA,eAAAoF,CAAAA,CAAAA,CACApF,CAAAA,CAAA,eAAAqF,CAAAA,CAAAA,CACArF,CAAAA,CAAA,YAAAD,CAAAA,CAAAA,CAhBnBC,CAAAA,CAAA,IAAA,CAAQ,GAAA,CAAekF,GAAQ,CAAA,CAC/BlF,CAAAA,CAAA,IAAA,CAAQ,QAAA,CAAwB,MAChCA,CAAAA,CAAA,IAAA,CAAQ,aAAA,CAAsC,IAAA,CAAA,CAC9CA,EAAA,IAAA,CAAQ,IAAA,CAAuB,MAC/BA,CAAAA,CAAA,IAAA,CAAQ,MAAkB,IAAA,CAAA,CAC1BA,CAAAA,CAAA,IAAA,CAAQ,SAAA,CAAU,IAAI,GAAA,CAAA,CACtBA,CAAAA,CAAA,KAAQ,aAAA,CAAc,IAAI,KAC1BA,CAAAA,CAAA,IAAA,CAAQ,WAAA,CAAY,IAAI,KACxBA,CAAAA,CAAA,IAAA,CAAQ,eAA8B,IAAA,CAAA,CACtCA,CAAAA,CAAA,KAAQ,WAAA,CAAmD,IAAA,CAAA,CAC3DA,CAAAA,CAAA,IAAA,CAAQ,YAA2B,IAAA,EASnC,CAEA,IAAI,KAAA,EAAmB,CACrB,OAAO,IAAA,CAAK,CACd,CAGA,SAA+C,CAC7C,IAAM6E,EAAO,IAAA,CAAK,YAAA,CACZS,EAAIT,CAAAA,CAAO,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAIA,CAAI,CAAA,CAAI,MAAA,CAC1C,OAAOA,CAAAA,EAAQS,CAAAA,CAAI,CAAE,IAAA,CAAAT,CAAAA,CAAM,EAAA,CAAIS,CAAAA,CAAE,UAAW,CAAA,CAAI,IAClD,CAGA,UAAA,EAAqB,CACnB,IAAMA,CAAAA,CAAI,IAAA,CAAK,YAAA,CAAe,KAAK,OAAA,CAAQ,GAAA,CAAI,IAAA,CAAK,YAAY,EAAI,MAAA,CACpE,OAAOA,CAAAA,CAAIA,CAAAA,CAAE,OAAM,CAAI,CACzB,CAEQ,GAAA,CAAIC,CAAAA,CAA2B,CACrC,IAAA,CAAK,CAAA,CAAI,CAAE,GAAG,KAAK,CAAA,CAAG,GAAGA,CAAM,CAAA,CAC/B,IAAA,CAAK,KAAK,OAAA,CAAS,IAAA,CAAK,CAAC,EAC3B,CAMA,MAAM,KAAA,EAAuB,CAC3B,GAAI,IAAA,CAAK,EAAE,KAAA,GAAU,MAAA,CACrB,CAAA,IAAA,CAAK,GAAA,CAAI,CAAE,KAAA,CAAO,SAAU,CAAC,CAAA,CAE7B1F,GAAa,CACb,GAAI,CACF,IAAA,CAAK,IAAM,MAAMmB,CAAAA,CAAQ,CAAE,QAAA,CAAU,IAAA,CAAK,KAAK,QAAA,CAAU,OAAA,CAAS,CAACD,CAAAA,CAAKyE,IAAU,IAAA,CAAK,UAAA,CAAWzE,CAAAA,CAAKyE,CAAK,CAAE,CAAC,EACjH,CAAA,KAAQ,CACN,KAAK,MAAA,CAAO,YAAA,CAAc,gDAAgD,CAAA,CAC1E,MACF,CACA,GAAI,CACF,IAAMC,CAAAA,CAAQ,MAAM,IAAA,CAAK,OAAA,CAAQ,KAAA,EAAM,CACjCC,EAAI,MAAMtC,CAAAA,CAAmF,IAAA,CAAK,MAAA,CAAQ,gBAAiB,CAC/H,MAAA,CAAQ,OACR,IAAA,CAAM,GACN,KAAA,CAAAqC,CACF,CAAC,CAAA,CACD,KAAK,GAAA,CAAI,CAAE,OAAQC,CAAAA,CAAE,MAAA,CAAQ,MAAOA,CAAAA,CAAE,KAAA,GAAU,OAAA,CAAU,SAAA,CAAY,SAAU,QAAA,CAAUA,CAAAA,CAAE,UAAY,IAAA,CAAM,UAAA,CAAYA,EAAE,UAAA,EAAc,IAAK,CAAC,CAAA,CAC3I,KAAK,MAAA,GACZ,CAAA,MAAS,CAAA,CAAG,CACV,IAAMC,CAAAA,CAAM,CAAA,YAAanD,CAAAA,CAAU,EAAI,IAAIA,CAAAA,CAAQ,UAAW,2BAA2B,CAAA,CACnFoD,EAAwBD,CAAAA,CAAI,IAAA,GAAS,cAAA,CAAiB,MAAA,CAAS,cACrE,IAAA,CAAK,MAAA,CAAOC,EAAQD,CAAAA,CAAI,OAAO,EAC/B,IAAA,CAAK,IAAA,CAAK,OAAA,CAASA,CAAG,EACxB,CAAA,CACF,CAGA,MAAc,MAAA,EAAwB,CACpC,IAAIE,CAAAA,CAAW,CAAA,CACf,KAAO,IAAA,CAAK,EAAE,MAAA,EAAU,IAAA,CAAK,CAAA,CAAE,KAAA,GAAU,SAAW,IAAA,CAAK,CAAA,CAAE,KAAA,GAAU,MAAA,EAAQ,CAC3E,IAAA,CAAK,WAAA,CAAc,IAAI,eAAA,CACvB,GAAI,CACF,IAAMJ,CAAAA,CAAQ,MAAM,IAAA,CAAK,QAAQ,KAAA,EAAM,CACjC3C,EAAM,MAAME,CAAAA,CAAK,KAAK,MAAA,CAAQ,CAAA,cAAA,EAAiB,kBAAA,CAAmB,IAAA,CAAK,EAAE,MAAM,CAAC,UAAW,CAAE,KAAA,CAAAyC,EAAO,MAAA,CAAQ,IAAA,CAAK,WAAA,CAAY,MAAO,CAAC,CAAA,CAC3II,CAAAA,CAAW,CAAA,CACX,MAAMxC,EAAWP,CAAAA,CAAMpB,CAAAA,EAAM,IAAA,CAAK,aAAA,CAAcA,EAAE,KAAA,CAAOA,CAAAA,CAAE,IAA+B,CAAA,CAAG,IAAA,CAAK,YAAY,MAAM,EACtH,CAAA,MAASA,CAAAA,CAAG,CACV,GAAKA,CAAAA,EAAa,IAAA,GAAS,YAAA,CAAc,OACzC,GAAIA,CAAAA,YAAac,CAAAA,EAAWd,CAAAA,CAAE,OAAS,WAAA,CAAa,CAClD,KAAK,MAAA,CAAO,QAAA,CAAU,iBAAiB,CAAA,CACvC,MACF,CAEA,GADAmE,GAAY,CAAA,CACRA,CAAAA,CAAW,CAAA,CAAG,CAChB,KAAK,MAAA,CAAO,QAAA,CAAU,kCAAkC,CAAA,CACxD,MACF,CACF,CACA,GAAI,IAAA,CAAK,KAAA,GAAS,OAClB,MAAM,IAAI,OAAA,CAASH,GAAM,UAAA,CAAWA,CAAAA,CAAG,KAAK,GAAA,CAAI,GAAA,CAAM,IAAM,CAAA,EAAKG,CAAQ,CAAC,CAAC,EAC7E,CACF,CAEQ,cAAczD,CAAAA,CAAe0D,CAAAA,CAA4B,CAC/D,OAAQ1D,CAAAA,EACN,KAAK,UACC,IAAA,CAAK,CAAA,CAAE,KAAA,GAAU,SAAA,EAAa,KAAK,CAAA,CAAE,KAAA,GAAU,QAAA,GACjD,IAAA,CAAK,IAAI,CAAE,KAAA,CAAO,SAAU,QAAA,CAAU,MAAA,CAAO0D,EAAE,QAAQ,CAAA,EAAK,CAAA,CAAG,UAAA,CAAY,OAAOA,CAAAA,CAAE,UAAU,GAAK,IAAK,CAAC,EAE3G,MACF,KAAK,OAAA,CAAS,CACR,OAAOA,CAAAA,CAAE,MAAA,EAAW,UAAYA,CAAAA,CAAE,MAAA,GAAQ,KAAK,MAAA,CAASA,CAAAA,CAAE,MAAA,CAAA,CAC9D,IAAMC,EAAO,MAAA,CAAOD,CAAAA,CAAE,WAAW,CAAA,EAAK,EAClC,IAAA,CAAK,CAAA,CAAE,KAAA,GAAU,OAAA,EAAW,KAAK,CAAA,CAAE,KAAA,GAAU,cAAgB,IAAA,CAAK,CAAA,CAAE,QAAU,MAAA,EAChF,IAAA,CAAK,GAAA,CAAI,CAAE,MAAO,OAAA,CAAS,WAAA,CAAaC,EAAM,QAAA,CAAU,IAAA,CAAM,WAAY,IAAK,CAAC,CAAA,CAChF,IAAA,CAAK,KAAK,OAAA,CAAS,CAAE,YAAaA,CAAK,CAAC,EACpC,IAAA,CAAK,IAAA,CAAK,UAAA,GAAe,KAAA,EAAO,KAAK,MAAA,EAAO,EACvC,IAAA,CAAK,CAAA,CAAE,QAAU,OAAA,EAC1B,IAAA,CAAK,GAAA,CAAI,CAAE,YAAaA,CAAK,CAAC,EAEhC,KACF,CACA,KAAK,MAAA,CACH,IAAA,CAAK,GAAA,CAAI,CAAE,MAAO,MAAA,CAAQ,UAAA,CAAY,MAAA,CAAOD,CAAAA,CAAE,UAAU,CAAA,EAAK,IAAA,CAAM,SAAA,CAAW,IAAA,CAAK,EAAE,SAAA,EAAa,IAAA,CAAK,KAAI,CAAA,CAAK,MAAA,CAAOA,EAAE,cAAc,CAAA,EAAK,CAAA,EAAK,GAAK,CAAC,CAAA,CACxJ,MACF,KAAK,OAAA,CACH,KAAK,MAAA,CAAQ,MAAA,CAAOA,CAAAA,CAAE,MAAA,EAAU,QAAQ,CAAA,EAAuB,QAAA,CAAU,IAAI,CAAA,CAC7E,KACJ,CACF,CAIQ,KAAA,EAAiB,CACvB,OAAO,KAAK,CAAA,CAAE,KAAA,GAAU,OAC1B,CAGA,MAAA,EAAe,CACb,GAAI,IAAA,CAAK,CAAA,CAAE,KAAA,GAAU,SAAW,CAAC,IAAA,CAAK,QAAU,IAAA,CAAK,EAAA,CAAI,OACzD,IAAA,CAAK,GAAA,CAAI,CAAE,KAAA,CAAO,YAAa,CAAC,CAAA,CAChC,IAAMtE,CAAAA,CAAM,KAAK,MAAA,CAAO,OAAA,CAAQ,OAAA,CAAS,IAAI,EAAI,sBAAA,CAC3CwE,CAAAA,CAAK,IAAI,SAAA,CAAUxE,CAAAA,CAAK,CAAC,CAAA,YAAA,EAAe,IAAA,CAAK,MAAM,CAAA,CAAE,CAAC,CAAA,CAC5D,IAAA,CAAK,OAAS,IAAA,CACdwE,CAAAA,CAAG,WAAa,aAAA,CAChB,IAAA,CAAK,EAAA,CAAKA,CAAAA,CACVA,EAAG,MAAA,CAAS,IAAM,CAChB,IAAMC,CAAAA,CAAO,KAAK,IAAA,CAAK,IAAA,CACjBC,CAAAA,CAAUD,CAAAA,EAAM,WAAU,EAAK,IAAA,CACrCD,CAAAA,CAAG,IAAA,CACD,KAAK,SAAA,CAAU,CACb,IAAA,CAAM,gBAAA,CACN,SAAU,IAAA,CAAK,OAAA,CACf,WAAY,CAAA,CACZ,WAAA,CAAa,CAAC,CAACC,CAAAA,CACf,GAAIA,CAAAA,CAAO,CAAE,iBAAA,CAAmB,IAAK,EAAI,EAAC,CAC1C,GAAIA,CAAAA,EAAQC,CAAAA,CAAU,CAAE,YAAA,CAAcA,CAAQ,CAAA,CAAI,EACpD,CAAC,CACH,EAGAF,CAAAA,CAAG,IAAA,CAAK,IAAA,CAAK,SAAA,CAAU,CAAE,IAAA,CAAM,WAAA,CAAa,MAAA,CAAQ,KAAA,CAAO,QAAS,KAAM,CAAC,CAAC,CAAA,CAC5E,KAAK,SAAA,CAAY,WAAA,CAAY,IAAM,IAAA,CAAK,QAAA,CAAS,CAAE,IAAA,CAAM,WAAY,CAAC,CAAA,CAAGf,CAAY,CAAA,CACrF,IAAA,CAAK,GAAA,CAAI,CAAE,MAAO,MAAA,CAAQ,SAAA,CAAW,IAAA,CAAK,CAAA,CAAE,WAAa,IAAA,CAAK,GAAA,EAAM,CAAC,EACvE,EACAe,CAAAA,CAAG,SAAA,CAAatE,CAAAA,EAAM,IAAA,CAAK,SAASA,CAAAA,CAAE,IAAI,CAAA,CAC1CsE,CAAAA,CAAG,QAAU,IAAM,CACjB,IAAA,CAAK,EAAA,CAAK,KAEV,UAAA,CAAW,IAAM,EACX,IAAA,CAAK,CAAA,CAAE,QAAU,MAAA,EAAU,IAAA,CAAK,CAAA,CAAE,KAAA,GAAU,eAAc,IAAA,CAAK,MAAA,CAAO,SAAU,IAAI,EAC1F,EAAG,IAAI,EACT,EACF,CAEQ,SAASrB,CAAAA,CAAY,CACvB,KAAK,EAAA,EAAI,UAAA,GAAe,UAAU,IAAA,EAAM,IAAA,CAAK,EAAA,CAAG,IAAA,CAAK,KAAK,SAAA,CAAUA,CAAC,CAAC,EAC5E,CAEQ,UAAA,CAAW5D,CAAAA,CAAkByE,CAAAA,CAAe,CAClD,IAAMQ,CAAAA,CAAK,IAAA,CAAK,GAChB,GAAI,EAAA,CAACA,GAAMA,CAAAA,CAAG,UAAA,GAAe,SAAA,CAAU,IAAA,CAAA,CACvC,IAAI,IAAA,CAAK,YAAA,CAAc,CAGrB,IAAMxF,CAAAA,CAAM,YAAY,GAAA,EAAI,CAC5B,GAAIgF,CAAAA,CAAQT,GAEV,GADA,IAAA,CAAK,YAAL,IAAA,CAAK,SAAA,CAAcvE,GACfA,CAAAA,CAAM,IAAA,CAAK,SAAA,EAAawE,CAAAA,CAAa,CACvC,IAAA,CAAK,SAAA,CAAY,IAAA,CACjB,IAAA,CAAK,WAAU,CACfgB,CAAAA,CAAG,IAAA,CAAKjF,CAAG,EACX,MACF,CAAA,CAAA,KAEA,KAAK,SAAA,CAAY,IAAA,CAEnBiF,EAAG,IAAA,CAAK,IAAI,WAAA,CAAYjF,CAAAA,CAAI,UAAU,CAAC,CAAA,CACvC,MACF,CACAiF,CAAAA,CAAG,KAAKjF,CAAG,EAAA,CACb,CAEQ,QAAA,CAASmD,EAAe,CAC9B,GAAIA,aAAgB,WAAA,CAAa,CAC/B,IAAMoB,CAAAA,CAAId,CAAAA,CAAYN,CAAI,CAAA,CAC1B,GAAI,CAACoB,CAAAA,EAAK,IAAA,CAAK,SAAA,CAAU,IAAIA,CAAAA,CAAE,IAAI,CAAA,CAAG,OACtC,GAAIA,CAAAA,CAAE,IAAA,GAAS,EAAG,CAEZ,IAAA,CAAK,KAAK,IAAA,EAAM,IAAA,CAAK,IAAA,CAAK,MAAA,CAAQ,CAAE,IAAA,CAAMA,CAAAA,CAAE,IAAA,CAAM,OAAA,CAASA,EAAE,OAAA,CAAQ,KAAA,EAAQ,CAAC,EAClF,MACF,CACA,GAAIA,CAAAA,CAAE,IAAA,GAAS,EAAG,OAClB,IAAIa,CAAAA,CAAS,IAAA,CAAK,QAAQ,GAAA,CAAIb,CAAAA,CAAE,IAAI,CAAA,CACpC,GAAI,CAACa,CAAAA,CAAQ,CAEX,IAAA,GAAW,CAAC,CAAA,CAAGC,CAAG,IAAK,IAAA,CAAK,OAAA,CAC1BA,EAAI,IAAA,EAAK,CACT,IAAA,CAAK,OAAA,CAAQ,OAAO,CAAC,CAAA,CAEvB,IAAMvB,CAAAA,CAAOS,CAAAA,CAAE,KACfa,CAAAA,CAAS,IAAIrG,CAAAA,CAAU,CACrB,WAAY,IAAA,CAAK,WAAA,CAAY,IAAI+E,CAAI,CAAA,EAAK,KAC1C,OAAA,CAAS,IAAM,CACb,IAAA,CAAK,aAAeA,CAAAA,CACpB,IAAA,CAAK,GAAA,CAAI,CAAE,SAAU,IAAK,CAAC,CAAA,CAC3B,IAAA,CAAK,KAAK,MAAA,CAAQ,CAAE,KAAAA,CAAAA,CAAM,KAAA,CAAO,SAAU,CAAC,CAAA,CAC5C,IAAA,CAAK,QAAA,CAAS,CAAE,IAAA,CAAM,kBAAA,CAAoB,cAAeA,CAAAA,CAAM,WAAA,CAAa,KAAK,GAAA,EAAM,CAAC,EAC1F,EACA,KAAA,CAAO,IAAM,CACX,IAAA,CAAK,OAAA,CAAQ,OAAOA,CAAI,CAAA,CACpB,IAAA,CAAK,YAAA,GAAiBA,IAAM,IAAA,CAAK,YAAA,CAAe,IAAA,CAAA,CACpD,IAAA,CAAK,IAAI,CAAE,QAAA,CAAU,KAAM,CAAC,EAC5B,IAAA,CAAK,IAAA,CAAK,OAAQ,CAAE,IAAA,CAAAA,EAAM,KAAA,CAAO,KAAM,CAAC,CAAA,CACxC,KAAK,QAAA,CAAS,CAAE,KAAM,gBAAA,CAAkB,aAAA,CAAeA,EAAM,WAAA,CAAa,IAAA,CAAK,GAAA,EAAI,CAAG,OAAQ,SAAU,CAAC,EACzG,IAAA,CAAK,QAAA,CAAS,CAAE,IAAA,CAAM,cAAe,CAAC,EACxC,CACF,CAAC,CAAA,CACD,IAAA,CAAK,OAAA,CAAQ,IAAIA,CAAAA,CAAMsB,CAAM,EAC/B,CACAA,EAAO,OAAA,CAAQb,CAAAA,CAAE,OAAO,CAAA,CACpBA,CAAAA,CAAE,OAAOa,CAAAA,CAAO,GAAA,EAAI,CACxB,MACF,CACA,GAAI,OAAOjC,GAAS,QAAA,CAAU,OAC9B,IAAIS,CAAAA,CACJ,GAAI,CACFA,CAAAA,CAAI,KAAK,KAAA,CAAMT,CAAI,EACrB,CAAA,KAAQ,CACN,MACF,CACA,GAAI,iBAAA,GAAqBS,CAAAA,CAAG,CAC1B,IAAM1C,CAAAA,CAAI0C,CAAAA,CAAE,eAAA,CACR1C,GAAG,cAAA,EAAkBA,CAAAA,CAAE,WAAA,EAAa,IAAA,CAAK,YAAY,GAAA,CAAIA,CAAAA,CAAE,eAAgBA,CAAAA,CAAE,WAAW,EAC5F,MACF,CACA,GAAI,sBAAA,GAA0B0C,EAAG,CAC/B,IAAMzC,EAAIyC,CAAAA,CAAE,oBAAA,CACRzC,GAAG,IAAA,EAAM,IAAA,CAAK,IAAA,CAAK,SAAA,CAAW,CAAE,EAAA,CAAI,CAAA,EAAA,EAAKA,EAAE,cAAc,CAAA,CAAA,CAAI,KAAM,SAAA,CAAW,IAAA,CAAMA,CAAAA,CAAE,IAAK,CAAC,CAAA,CAChG,MACF,CACA,GAAI,yBAA0ByC,CAAAA,CAAG,CAC/B,IAAMzC,CAAAA,CAAIyC,EAAE,oBAAA,CACRzC,CAAAA,EAAG,MAAQ,CAAC,IAAA,CAAK,UAAU,GAAA,CAAIA,CAAAA,CAAE,cAAc,CAAA,EAAG,KAAK,IAAA,CAAK,SAAA,CAAW,CAAE,EAAA,CAAI,CAAA,EAAA,EAAKA,EAAE,cAAc,CAAA,CAAA,CAAI,IAAA,CAAM,OAAA,CAAS,KAAMA,CAAAA,CAAE,IAAK,CAAC,CAAA,CACvI,MACF,CACA,GAAIyC,CAAAA,CAAE,IAAA,GAAS,gBAAA,EAAoB,OAAOA,CAAAA,CAAE,aAAA,EAAkB,QAAA,CAAU,CACtE,IAAM0B,CAAAA,CAAM1B,CAAAA,CAAE,aAAA,CACd,IAAA,CAAK,UAAU,GAAA,CAAI0B,CAAG,EACtB,IAAA,CAAK,OAAA,CAAQ,IAAIA,CAAG,CAAA,EAAG,IAAA,EAAK,CAC5B,KAAK,OAAA,CAAQ,MAAA,CAAOA,CAAG,CAAA,CACvB,IAAA,CAAK,KAAK,MAAA,CAAQ,CAAE,IAAA,CAAMA,CAAAA,CAAK,MAAO,KAAM,CAAC,EACzC,IAAA,CAAK,YAAA,GAAiBA,IACxB,IAAA,CAAK,YAAA,CAAe,IAAA,CACpB,IAAA,CAAK,IAAI,CAAE,QAAA,CAAU,KAAM,CAAC,GAE9B,IAAA,CAAK,IAAA,CAAK,gBAAA,CAAkB,CAAA,EAAA,EAAKA,CAAG,CAAA,CAAE,CAAA,CACtC,MACF,CACI1B,CAAAA,CAAE,OAAS,cAAA,EAAkB,OAAOA,CAAAA,CAAE,KAAA,EAAU,UAClD,IAAA,CAAK,GAAA,CAAI,CAAE,UAAA,CAAYA,EAAE,KAAA,CAAM,WAAA,EAAc,CAAC,EAElD,CAGA,SAAA,EAAkB,CAChB,IAAME,CAAAA,CAAO,KAAK,YAAA,CAClB,GAAI,CAACA,CAAAA,CAAM,OACX,IAAMS,CAAAA,CAAI,IAAA,CAAK,OAAA,CAAQ,IAAIT,CAAI,CAAA,CACzByB,CAAAA,CAAU,IAAA,CAAK,MAAMhB,CAAAA,EAAG,QAAA,IAAc,CAAC,CAAA,CAC7CA,GAAG,IAAA,EAAK,CACR,IAAA,CAAK,OAAA,CAAQ,OAAOT,CAAI,CAAA,CACxB,KAAK,SAAA,CAAU,GAAA,CAAIA,CAAI,CAAA,CACvB,IAAA,CAAK,YAAA,CAAe,IAAA,CACpB,KAAK,GAAA,CAAI,CAAE,SAAU,KAAM,CAAC,EAC5B,IAAA,CAAK,IAAA,CAAK,MAAA,CAAQ,CAAE,KAAAA,CAAAA,CAAM,KAAA,CAAO,KAAM,CAAC,EACxC,IAAA,CAAK,QAAA,CAAS,CAAE,IAAA,CAAM,iBAAkB,aAAA,CAAeA,CAAAA,CAAM,YAAa,IAAA,CAAK,GAAA,GAAO,MAAA,CAAQ,aAAc,CAAC,CAAA,CAC7G,KAAK,QAAA,CAAS,CAAE,KAAM,WAAA,CAAa,aAAA,CAAeA,EAAM,OAAA,CAAAyB,CAAAA,CAAS,WAAA,CAAa,IAAA,CAAK,KAAM,CAAC,EAC5F,CAEA,QAAA,CAASlF,EAAsB,CAC7B,IAAA,CAAK,GAAA,EAAK,QAAA,CAASA,CAAK,CAAA,CACxB,IAAA,CAAK,GAAA,CAAI,CAAE,MAAAA,CAAM,CAAC,EACpB,CAGA,MAAM,MAAA,EAAwB,CAC5B,IAAMmF,CAAAA,CAAK,IAAA,CAAK,EAAE,MAAA,CACZC,CAAAA,CAAM,IAAA,CAAK,CAAA,CAAE,MAEnB,GADA,IAAA,CAAK,OAAOA,CAAAA,GAAQ,MAAA,CAAS,SAAW,MAAA,CAAQ,IAAI,CAAA,CAChD,CAAA,CAACD,EACL,GAAI,CACF,IAAMd,CAAAA,CAAQ,MAAM,KAAK,OAAA,CAAQ,KAAA,EAAM,CACvC,MAAMzC,EAAK,IAAA,CAAK,MAAA,CAAQ,CAAA,cAAA,EAAiB,kBAAA,CAAmBuD,CAAE,CAAC,CAAA,CAAA,CAAI,CAAE,MAAA,CAAQ,SAAU,KAAA,CAAAd,CAAM,CAAC,EAChG,CAAA,KAAQ,CAER,CACF,CAEQ,MAAA,CAAOG,CAAAA,CAAuBa,EAAsB,CAC1D,GAAI,IAAA,CAAK,CAAA,CAAE,QAAU,OAAA,CAAS,OAC9B,IAAA,CAAK,WAAA,EAAa,OAAM,CACxB,IAAA,CAAK,YAAc,IAAA,CACf,IAAA,CAAK,WAAW,aAAA,CAAc,IAAA,CAAK,SAAS,CAAA,CAChD,KAAK,SAAA,CAAY,IAAA,CACjB,IAAA,IAAWnB,CAAAA,IAAK,KAAK,OAAA,CAAQ,MAAA,EAAO,CAAGA,CAAAA,CAAE,MAAK,CAC9C,IAAA,CAAK,QAAQ,KAAA,EAAM,CACnB,KAAK,YAAA,CAAe,IAAA,CACpB,IAAA,CAAK,GAAA,EAAK,MAAK,CACf,IAAA,CAAK,IAAM,IAAA,CACX,IAAMU,EAAK,IAAA,CAAK,EAAA,CAChB,IAAA,CAAK,EAAA,CAAK,KACNA,CAAAA,EAAMA,CAAAA,CAAG,YAAc,SAAA,CAAU,IAAA,EAAMA,EAAG,KAAA,CAAM,GAAI,CAAA,CACxD,IAAA,CAAK,OAAS,IAAA,CACd,IAAA,CAAK,GAAA,CAAI,CAAE,MAAO,OAAA,CAAS,SAAA,CAAWJ,CAAAA,CAAQ,QAAA,CAAU,MAAO,WAAA,CAAa,IAAA,CAAM,MAAAa,CAAM,CAAC,EAC3F,CACF,EC9XA,IAAIC,CAAAA,CAAW,EACTC,CAAAA,CAAWrB,CAAAA,EAAc,GAAGA,CAAC,CAAA,CAAA,EAAI,KAAK,GAAA,EAAI,CAAE,QAAA,CAAS,EAAE,CAAC,CAAA,CAAA,EAAA,CAAKoB,CAAAA,EAAAA,EAAY,SAAS,EAAE,CAAC,GAM9EE,CAAAA,CAAN,cAAmBzE,CAAoB,CAM5C,YACmBc,CAAAA,CACAmC,CAAAA,CACjB,CACA,KAAA,GAHiBpF,CAAAA,CAAA,IAAA,CAAA,QAAA,CAAAiD,CAAAA,CAAAA,CACAjD,CAAAA,CAAA,eAAAoF,CAAAA,CAAAA,CAPnBpF,CAAAA,CAAA,KAAQ,MAAA,CAAsB,IAC9BA,CAAAA,CAAA,IAAA,CAAQ,QAAA,CAAS,KAAA,CAAA,CACjBA,EAAA,IAAA,CAAQ,MAAA,CAAO,OACfA,CAAAA,CAAA,IAAA,CAAQ,QAAgC,IAAA,EAOxC,CAEA,IAAI,QAAA,EAAmC,CACrC,OAAO,IAAA,CAAK,IACd,CAEA,IAAI,QAAkB,CACpB,OAAO,IAAA,CAAK,IACd,CAEQ,OAAA,EAAU,CAChB,IAAA,CAAK,IAAA,CAAO,CAAC,GAAG,IAAA,CAAK,IAAI,CAAA,CACzB,KAAK,IAAA,CAAK,UAAA,CAAY,KAAK,IAAI,EACjC,CAGA,MAAM,IAAA,EAAwC,CAC5C,GAAI,KAAK,MAAA,CAAQ,OAAO,IAAA,CAAK,IAAA,CAC7B,IAAMyF,CAAAA,CAAQ,MAAM,IAAA,CAAK,OAAA,CAAQ,OAAM,CACjC3C,CAAAA,CAAM,MAAMM,CAAAA,CAAqC,IAAA,CAAK,OAAQ,gCAAA,CAAkC,CAAE,KAAA,CAAAqC,CAAM,CAAC,CAAA,CAEzGoB,CAAAA,CAAU,IAAA,CAAK,IAAA,CACrB,YAAK,IAAA,CAAO,CAAC,GAAI/D,CAAAA,EAAK,UAAY,EAAC,CAAI,GAAG+D,CAAO,CAAA,CACjD,KAAK,MAAA,CAAS,IAAA,CACd,IAAA,CAAK,OAAA,GACE,IAAA,CAAK,IACd,CAMA,MAAM,IAAA,CAAKC,EAAoC,CAC7C,IAAM,CAAA,CAAIA,CAAAA,CAAK,MAAK,CACpB,GAAI,CAAC,CAAA,CAAG,MAAM,IAAItE,CAAAA,CAAQ,SAAA,CAAW,sBAAsB,CAAA,CAC3D,GAAI,IAAA,CAAK,IAAA,CAAM,MAAM,IAAIA,EAAQ,cAAA,CAAgB,2BAA2B,CAAA,CAC5E,IAAA,CAAK,QAAQ,IAAI,CAAA,CACjB,IAAMuE,CAAAA,CAAoB,CAAE,GAAIJ,CAAAA,CAAQ,OAAO,CAAA,CAAG,IAAA,CAAM,UAAW,IAAA,CAAM,CAAA,CAAG,UAAW,IAAI,IAAA,GAAO,WAAA,EAAc,CAAA,CAC1GK,CAAAA,CAAqB,CAAE,EAAA,CAAIL,CAAAA,CAAQ,OAAO,CAAA,CAAG,IAAA,CAAM,QAAS,IAAA,CAAM,EAAA,CAAI,SAAA,CAAW,IAAI,MAAK,CAAE,WAAA,EAAY,CAAG,SAAA,CAAW,IAAK,CAAA,CACjI,IAAA,CAAK,IAAA,CAAK,IAAA,CAAKI,EAAMC,CAAK,CAAA,CAC1B,KAAK,OAAA,EAAQ,CAEb,KAAK,KAAA,CAAQ,IAAI,eAAA,CACjB,GAAI,CACF,IAAMvB,CAAAA,CAAQ,MAAM,IAAA,CAAK,OAAA,CAAQ,OAAM,CACjC3C,CAAAA,CAAM,MAAME,CAAAA,CAAK,KAAK,MAAA,CAAQ,uBAAA,CAAyB,CAAE,MAAA,CAAQ,MAAA,CAAQ,KAAM,CAAE,IAAA,CAAM,CAAE,CAAA,CAAG,MAAAyC,CAAAA,CAAO,MAAA,CAAQ,IAAA,CAAK,KAAA,CAAM,MAAO,CAAC,CAAA,CAChIwB,CAAAA,CAA+B,IAAA,CAC/BC,EAAyB,IAAA,CAgB7B,GAfA,MAAM7D,CAAAA,CACJP,CAAAA,CACA,CAAC,CAAE,KAAA,CAAAV,CAAAA,CAAO,IAAA,CAAA8B,CAAK,CAAA,GAAM,CACnB,IAAM4B,CAAAA,CAAI5B,CAAAA,CACN9B,IAAU,OAAA,EAAW,OAAO0D,CAAAA,EAAG,IAAA,EAAS,UAC1CkB,CAAAA,CAAM,IAAA,EAAQlB,EAAE,IAAA,CAChB,IAAA,CAAK,SAAQ,EACJ1D,CAAAA,GAAU,MAAA,CACnB6E,CAAAA,CAAW,CAAE,EAAA,CAAI,MAAA,CAAOnB,CAAAA,CAAE,EAAE,EAAG,IAAA,CAAM,OAAA,CAAS,IAAA,CAAM,MAAA,CAAOA,EAAE,IAAA,EAAQkB,CAAAA,CAAM,IAAI,CAAA,CAAG,SAAA,CAAW,OAAOlB,CAAAA,CAAE,SAAA,EAAakB,CAAAA,CAAM,SAAS,CAAE,CAAA,CAC3H5E,CAAAA,GAAU,UACnB8E,CAAAA,CAAU,OAAOpB,GAAG,OAAA,EAAY,QAAA,CAAWA,CAAAA,CAAE,OAAA,CAAU,yBAE3D,CAAA,CACA,IAAA,CAAK,MAAM,MACb,CAAA,CACIoB,GAAW,CAACD,CAAAA,CAAU,MAAM,IAAIzE,EAAQ,SAAA,CAAW0E,CAAAA,EAAW,mCAAmC,CAAA,CACrG,IAAMrD,CAAAA,CAAoBoD,CAAAA,CAC1B,OAAA,IAAA,CAAK,OAAA,CAAQD,EAAM,EAAA,CAAInD,CAAI,EACpBA,CACT,CAAA,MAASnC,EAAG,CACV,IAAMiE,CAAAA,CAAMjE,CAAAA,YAAac,EAAUd,CAAAA,CAAI,IAAIc,EAAQ,SAAA,CAAW,mCAAmC,EACjG,IAAA,CAAK,IAAA,CAAO,IAAA,CAAK,IAAA,CAAK,OAAQP,CAAAA,EAAMA,CAAAA,CAAE,KAAO+E,CAAAA,CAAM,EAAE,EACrD,IAAMhD,CAAAA,CAAM,IAAA,CAAK,IAAA,CAAK,UAAW/B,CAAAA,EAAMA,CAAAA,CAAE,EAAA,GAAO8E,CAAAA,CAAK,EAAE,CAAA,CACvD,MAAI/C,CAAAA,GAAQ,EAAA,GAAI,KAAK,IAAA,CAAKA,CAAG,EAAI,CAAE,GAAG+C,EAAM,MAAA,CAAQ,IAAK,CAAA,CAAA,CACzD,IAAA,CAAK,SAAQ,CACRrF,CAAAA,EAAa,OAAS,YAAA,EAAc,IAAA,CAAK,KAAK,OAAA,CAASiE,CAAG,CAAA,CACzDA,CACR,QAAE,CACA,IAAA,CAAK,MAAQ,IAAA,CACb,IAAA,CAAK,QAAQ,KAAK,EACpB,CACF,CAGA,MAAMY,CAAAA,CAAkC,CACtC,IAAMtE,CAAAA,CAAI,KAAK,IAAA,CAAK,IAAA,CAAMkF,CAAAA,EAAMA,CAAAA,CAAE,KAAOZ,CAAAA,EAAMY,CAAAA,CAAE,MAAM,CAAA,CACvD,GAAI,CAAClF,CAAAA,CAAG,MAAM,IAAIO,CAAAA,CAAQ,YAAa,mBAAmB,CAAA,CAC1D,OAAA,IAAA,CAAK,IAAA,CAAO,KAAK,IAAA,CAAK,MAAA,CAAQ2E,CAAAA,EAAMA,CAAAA,CAAE,KAAOZ,CAAE,CAAA,CAC/C,KAAK,OAAA,EAAQ,CACN,KAAK,IAAA,CAAKtE,CAAAA,CAAE,IAAI,CACzB,CAGA,IAAA,EAAa,CACX,IAAA,CAAK,KAAA,EAAO,QACd,CAEQ,OAAA,CAAQsE,CAAAA,CAAYa,EAAmB,CAC7C,IAAM9G,EAAI,IAAA,CAAK,IAAA,CAAK,UAAW2B,CAAAA,EAAMA,CAAAA,CAAE,EAAA,GAAOsE,CAAE,EAC5CjG,CAAAA,GAAM,EAAA,GAAI,KAAK,IAAA,CAAKA,CAAC,EAAI8G,CAAAA,CAAAA,CAC7B,IAAA,CAAK,OAAA,GACP,CAEQ,OAAA,CAAQC,CAAAA,CAAY,CAC1B,IAAA,CAAK,IAAA,CAAOA,EACZ,IAAA,CAAK,IAAA,CAAK,MAAA,CAAQA,CAAC,EACrB,CACF,EC/HO,IAAMC,CAAAA,CAAc,IAAoB,CAC7C,IAAMrF,CAAAA,CAAI,IAAI,IACd,OAAO,CAAE,IAAMsF,CAAAA,EAAMtF,CAAAA,CAAE,IAAIsF,CAAC,CAAA,EAAK,IAAA,CAAM,GAAA,CAAK,CAACA,CAAAA,CAAG3G,CAAAA,GAAG,CAAQqB,CAAAA,CAAE,GAAA,CAAIsF,EAAG3G,CAAC,EAAA,CAAE,CACzE,CAAA,CAEa4G,EAAa,KAAqB,CAC7C,IAAID,CAAAA,CAAG,CACL,GAAI,CACF,OAAO,UAAA,CAAW,YAAA,EAAc,QAAQA,CAAC,CAAA,EAAK,IAChD,CAAA,KAAQ,CACN,OAAO,IACT,CACF,CAAA,CACA,IAAIA,CAAAA,CAAG3G,CAAAA,CAAG,CACR,GAAI,CACF,WAAW,YAAA,EAAc,OAAA,CAAQ2G,CAAAA,CAAG3G,CAAC,EACvC,CAAA,KAAQ,CAER,CACF,CACF,CAAA,CAAA,CAiBM6G,EAAgB,EAAA,CAMTC,CAAAA,CAAN,KAAqB,CAI1B,YAA6BnH,CAAAA,CAAoB,CAApBP,EAAA,IAAA,CAAA,KAAA,CAAAO,CAAAA,CAAAA,CAH7BP,EAAA,IAAA,CAAQ,SAAA,CAA8B,IAAA,CAAA,CACtCA,CAAAA,CAAA,KAAQ,UAAA,CAAwC,IAAA,CAAA,CAG9C,GAAI,CAACO,EAAI,cAAA,EAAkB,CAACA,CAAAA,CAAI,eAAA,CAC9B,MAAM,IAAIiC,CAAAA,CAAQ,UAAW,2EAA2E,CAE5G,CAEQ,UAAA,EAAqB,CAG3B,OAAO,CAAA,aAAA,EAAA,CADG,KAAK,GAAA,CAAI,cAAA,EAAkB,QAAA,EACZ,KAAA,CAAM,GAAG,CAAC,CAAA,CACrC,CAEA,IAAI,MAA2B,CAC7B,OAAO,KAAK,OACd,CAGA,MAAM,KAAA,EAAyB,CAC7B,IAAMhC,CAAAA,CAAM,KAAK,GAAA,EAAI,CAAI,GAAA,CACzB,OAAI,KAAK,OAAA,EAAW,IAAA,CAAK,OAAA,CAAQ,SAAA,CAAYiH,EAAgBjH,CAAAA,CAAY,IAAA,CAAK,QAAQ,KAAA,CAAA,CAC9E,MAAM,KAAK,OAAA,EAAQ,EAAG,KAChC,CAEA,SAAgC,CAC9B,OAAA,IAAA,CAAK,WAAL,IAAA,CAAK,QAAA,CAAa,KAAK,IAAA,EAAK,CAAE,OAAA,CAAQ,IAAM,CAC1C,IAAA,CAAK,QAAA,CAAW,KAClB,CAAC,CAAA,CAAA,CACM,KAAK,QACd,CAEA,MAAc,IAAA,EAA6B,CACzC,IAAImH,CAAAA,CACJ,GAAI,IAAA,CAAK,IAAI,eAAA,CAAiB,CAC5B,IAAMC,CAAAA,CAAM,MAAM,IAAA,CAAK,GAAA,CAAI,iBAAgB,CACvC,OAAOA,GAAQ,QAAA,CAEjBD,CAAAA,CAAO,MAAM,IAAA,CAAK,SAASC,CAAG,CAAA,CAE9BD,EAAOC,EAEX,CAAA,KAAO,CACL,IAAMC,CAAAA,CAAY,IAAA,CAAK,GAAA,CAAI,MAAM,GAAA,CAAI,IAAA,CAAK,YAAY,CAAA,EAAK,OAC3DF,CAAAA,CAAO,MAAMvE,CAAAA,CAAqB,IAAA,CAAK,IAAI,MAAA,CAAQ,kBAAA,CAAoB,CACrE,MAAA,CAAQ,OACR,IAAA,CAAM,CAAE,cAAA,CAAgB,IAAA,CAAK,IAAI,cAAA,CAAgB,OAAA,CAAS,KAAK,GAAA,CAAI,OAAA,CAAS,UAAAyE,CAAU,CACxF,CAAC,CAAA,CACD,KAAK,GAAA,CAAI,KAAA,CAAM,IAAI,IAAA,CAAK,UAAA,GAAcF,CAAAA,CAAK,SAAS,EACtD,CACA,YAAK,OAAA,CAAUA,CAAAA,CACRA,CACT,CAGA,MAAc,SAASlC,CAAAA,CAAqC,CAE1D,OAAO,CAAE,GADI,MAAMrC,CAAAA,CAAqB,IAAA,CAAK,GAAA,CAAI,OAAQ,iBAAA,CAAmB,CAAE,KAAA,CAAAqC,CAAM,CAAC,CAAA,CACnE,KAAA,CAAAA,CAAM,CAC1B,CACF,EC1GO,IAAMqC,CAAAA,CAAkB,2BAAA,CA6BlBC,CAAAA,CAAN,MAAMC,CAAAA,SAAqB7F,CAAsB,CAK9C,WAAA,CACGc,EACQmC,CAAAA,CACTuC,CAAAA,CACR,CACA,KAAA,GAJS3H,CAAAA,CAAA,IAAA,CAAA,QAAA,CAAAiD,GACQjD,CAAAA,CAAA,IAAA,CAAA,SAAA,CAAAoF,GACTpF,CAAAA,CAAA,IAAA,CAAA,MAAA,CAAA2H,CAAAA,CAAAA,CAPV3H,CAAAA,CAAA,KAAS,MAAA,CAAA,CACTA,CAAAA,CAAA,IAAA,CAAQ,aAAA,CAA2B,MACnCA,CAAAA,CAAA,IAAA,CAAQ,WAAA,CAAY,KAAA,CAAA,CAQlB,KAAK,IAAA,CAAO,IAAI4G,EAAK3D,CAAAA,CAAQmC,CAAO,EACtC,CAEA,aAAa,IAAA,CAAKrF,CAAAA,CAA0C,CAC1D,IAAMkD,CAAAA,CAAAA,CAAUlD,EAAK,MAAA,EAAU+H,CAAAA,EAAiB,QAAQ,MAAA,CAAQ,EAAE,CAAA,CAClE,GAAI/H,EAAK,cAAA,EAAkB,WAAA,CAAY,KAAKA,CAAAA,CAAK,cAAc,EAE7D,MAAM,IAAIyC,CAAAA,CAAQ,SAAA,CAAW,sHAAiH,CAAA,CAEhJ,IAAMyF,CAAAA,CAAQlI,CAAAA,CAAK,UAAY,QAAA,CAAWuH,CAAAA,EAAY,CAAIvH,CAAAA,CAAK,SAAW,OAAOA,CAAAA,CAAK,SAAY,QAAA,CAAWA,CAAAA,CAAK,QAAUyH,CAAAA,EAAW,CACjIpC,CAAAA,CAAU,IAAIsC,EAAe,CAAE,MAAA,CAAAzE,EAAQ,OAAA,CAASlD,CAAAA,CAAK,QAAS,cAAA,CAAgBA,CAAAA,CAAK,cAAA,CAAgB,eAAA,CAAiBA,EAAK,eAAA,CAAiB,KAAA,CAAAkI,CAAM,CAAC,CAAA,CACjJN,EAAO,MAAMvC,CAAAA,CAAQ,OAAA,EAAQ,CACnC,OAAO,IAAI4C,CAAAA,CAAa/E,CAAAA,CAAQmC,CAAAA,CAASuC,CAAI,CAC/C,CAEA,IAAI,KAAA,EAAmB,CACrB,OAAA,CAAQ,IAAA,CAAK,QAAQ,IAAA,EAAQ,IAAA,CAAK,MAAM,KAC1C,CAEA,IAAI,QAAA,EAAqB,CACvB,OAAA,CAAQ,IAAA,CAAK,QAAQ,IAAA,EAAQ,IAAA,CAAK,MAAM,QAC1C,CAEA,IAAI,UAAA,EAAsC,CACxC,OAAA,CAAQ,IAAA,CAAK,QAAQ,IAAA,EAAQ,IAAA,CAAK,MAAM,UAAA,EAAc,EACxD,CAEA,IAAI,SAAA,EAAoB,CACtB,OAAA,CAAQ,IAAA,CAAK,QAAQ,IAAA,EAAQ,IAAA,CAAK,IAAA,EAAM,SAC1C,CAEA,IAAI,IAAA,EAAwB,CAC1B,OAAA,CAAQ,IAAA,CAAK,QAAQ,IAAA,EAAQ,IAAA,CAAK,IAAA,EAAM,IAC1C,CAGA,IAAI,IAAA,EAAoB,CACtB,OAAO,IAAA,CAAK,aAAe,IAAA,CAAK,WAAA,CAAY,KAAA,CAAM,KAAA,GAAU,QAAU,IAAA,CAAK,WAAA,CAAc,IAC3F,CAOA,MAAM,aAAuD,CAC3D,IAAMlC,CAAAA,CAAQ,MAAM,KAAK,OAAA,CAAQ,KAAA,EAAM,CACvC,OAAOrC,EAAwC,IAAA,CAAK,MAAA,CAAQ,4BAAA,CAA8B,CAAE,MAAAqC,CAAM,CAAC,CACrG,CAGA,MAAM,UAAU1F,CAAAA,CAAoB,EAAC,CAAkB,CACrD,GAAI,IAAA,CAAK,SAAA,CAAW,MAAM,IAAIyC,CAAAA,CAAQ,UAAW,4BAA4B,CAAA,CAC7E,GAAI,CAAC,KAAK,QAAA,CAAS,IAAA,CAAM,MAAM,IAAIA,CAAAA,CAAQ,YAAa,uCAAuC,CAAA,CAC/F,GAAI,IAAA,CAAK,KAAM,OAAO,IAAA,CAAK,IAAA,CAC3B,IAAM0F,EAAO,IAAI/C,CAAAA,CAAK,IAAA,CAAK,MAAA,CAAQ,KAAK,OAAA,CAAS,IAAA,CAAK,MAAM,EAAA,CAAIpF,CAAI,EACpE,OAAA,IAAA,CAAK,WAAA,CAAcmI,CAAAA,CACnBA,CAAAA,CAAK,GAAG,OAAA,CAAU,CAAA,EAAM,CAClB,CAAA,CAAE,KAAA,GAAU,SAAW,IAAA,CAAK,WAAA,GAAgBA,CAAAA,EAAM,IAAA,CAAK,KAAK,MAAA,CAAQ,IAAI,EAC9E,CAAC,CAAA,CACDA,EAAK,EAAA,CAAG,OAAA,CAAUxG,CAAAA,EAAM,IAAA,CAAK,KAAK,OAAA,CAASA,CAAC,CAAC,CAAA,CAC7C,KAAK,IAAA,CAAK,MAAA,CAAQwG,CAAI,CAAA,CACtB,MAAMA,CAAAA,CAAK,KAAA,GACJA,CACT,CAEA,SAAgB,CACd,IAAA,CAAK,SAAA,CAAY,IAAA,CACZ,KAAK,WAAA,EAAa,MAAA,GACvB,IAAA,CAAK,IAAA,CAAK,MAAK,CACf,IAAA,CAAK,IAAA,CAAK,KAAA,GACV,IAAA,CAAK,KAAA,GACP,CACF,MCpFaC,EAAAA,CAAU","file":"index.js","sourcesContent":["/**\n * Plays the agent's streamed voice (PCM16 chunks) gaplessly, and reports how\n * loud it is right now so a UI can draw a ring that follows the voice.\n *\n * Each chunk becomes an AudioBuffer scheduled right after the last one; the\n * first waits a short pre-roll so a slow second chunk does not open a gap.\n */\n\nexport interface PlayerOptions {\n sampleRate?: number;\n onStart?: () => void;\n onEnd?: () => void;\n volume?: number;\n}\n\nconst PREROLL_S = 0.12;\n\nlet shared: AudioContext | null = null;\n\n/** One output context for the page, created on first use (after a gesture). */\nexport function audioContext(): AudioContext {\n if (!shared || shared.state === 'closed') shared = new AudioContext({ latencyHint: 'interactive' });\n if (shared.state === 'suspended') void shared.resume().catch(() => {});\n return shared;\n}\n\nexport class PcmPlayer {\n private readonly ctx: AudioContext;\n private readonly gain: GainNode;\n private readonly analyser: AnalyserNode;\n private readonly data: Uint8Array<ArrayBuffer>;\n private nextAt = 0;\n private started = false;\n private ended = false;\n private finishing = false;\n private sources = new Set<AudioBufferSourceNode>();\n private startedAt = 0;\n readonly sampleRate: number;\n\n constructor(private readonly opts: PlayerOptions = {}) {\n this.ctx = audioContext();\n this.sampleRate = opts.sampleRate ?? 16_000;\n this.gain = this.ctx.createGain();\n this.gain.gain.value = opts.volume ?? 1;\n this.analyser = this.ctx.createAnalyser();\n this.analyser.fftSize = 512;\n this.data = new Uint8Array(new ArrayBuffer(this.analyser.fftSize));\n this.gain.connect(this.analyser).connect(this.ctx.destination);\n }\n\n /** Queue PCM16 little-endian mono bytes. */\n enqueue(bytes: Uint8Array): void {\n if (this.ended || bytes.byteLength < 2) return;\n const count = Math.floor(bytes.byteLength / 2);\n const view = new DataView(bytes.buffer, bytes.byteOffset, count * 2);\n const buf = this.ctx.createBuffer(1, count, this.sampleRate);\n const ch = buf.getChannelData(0);\n for (let i = 0; i < count; i++) ch[i] = view.getInt16(i * 2, true) / 32768;\n const src = this.ctx.createBufferSource();\n src.buffer = buf;\n src.connect(this.gain);\n const now = this.ctx.currentTime;\n if (this.nextAt < now) this.nextAt = now + (this.started ? 0.02 : PREROLL_S);\n src.start(this.nextAt);\n if (!this.started) {\n this.started = true;\n const delayMs = Math.max(0, (this.nextAt - now) * 1000);\n this.startedAt = performance.now() + delayMs;\n setTimeout(() => this.opts.onStart?.(), delayMs);\n }\n this.nextAt += buf.duration;\n this.sources.add(src);\n src.onended = () => {\n this.sources.delete(src);\n if (this.finishing && this.sources.size === 0) this.finish();\n };\n }\n\n /** No more chunks: report the end once the queue has played out. */\n end(): void {\n this.finishing = true;\n if (this.sources.size === 0) this.finish();\n }\n\n /** Silence now (an interruption). Does not call `onEnd`. */\n stop(): void {\n this.ended = true;\n for (const s of this.sources) {\n try {\n s.stop();\n } catch {\n /* not started */\n }\n }\n this.sources.clear();\n this.gain.disconnect();\n }\n\n /** Milliseconds of audio actually heard so far. */\n playedMs(): number {\n return this.started ? Math.max(0, performance.now() - this.startedAt) : 0;\n }\n\n /** Loudness now, 0..1. */\n level(): number {\n this.analyser.getByteTimeDomainData(this.data);\n let sum = 0;\n for (let i = 0; i < this.data.length; i++) {\n const v = (this.data[i]! - 128) / 128;\n sum += v * v;\n }\n return Math.min(1, Math.sqrt(sum / this.data.length) * 3);\n }\n\n private finish() {\n if (this.ended) return;\n this.ended = true;\n this.gain.disconnect();\n this.opts.onEnd?.();\n }\n}\n","/**\n * The microphone as the agent socket wants it: 16 kHz mono PCM16, 30 ms\n * (480-sample) frames, sent continuously.\n *\n * Resampled in an AudioWorklet from whatever rate the device runs at. A\n * context forced to 16 kHz would be simpler and is refused by Firefox for a\n * MediaStream source at another rate, so the worklet does it.\n */\n\nexport const TARGET_RATE = 16_000;\nexport const FRAME_SAMPLES = 480;\n\nconst WORKLET = `\nclass CxyzMic extends AudioWorkletProcessor {\n constructor(o) {\n super();\n this.ratio = sampleRate / ${TARGET_RATE};\n this.pos = 0;\n this.lp = 0;\n this.alpha = Math.min(1, 2 * Math.PI * 7000 / sampleRate / (1 + 2 * Math.PI * 7000 / sampleRate));\n this.out = new Int16Array(${FRAME_SAMPLES});\n this.n = 0;\n }\n process(inputs) {\n const ch = inputs[0] && inputs[0][0];\n if (!ch) return true;\n for (let i = 0; i < ch.length; i++) {\n this.lp += this.alpha * (ch[i] - this.lp);\n this.pos += 1;\n if (this.pos >= this.ratio) {\n this.pos -= this.ratio;\n const s = Math.max(-1, Math.min(1, this.lp));\n this.out[this.n++] = s < 0 ? s * 0x8000 : s * 0x7fff;\n if (this.n === ${FRAME_SAMPLES}) {\n this.port.postMessage(this.out.buffer, [this.out.buffer]);\n this.out = new Int16Array(${FRAME_SAMPLES});\n this.n = 0;\n }\n }\n }\n return true;\n }\n}\nregisterProcessor('cxyz-mic', CxyzMic);\n`;\n\nexport interface MicOptions {\n onFrame: (pcm: ArrayBuffer, level: number) => void;\n deviceId?: string;\n}\n\nexport interface Mic {\n stop(): void;\n setMuted(m: boolean): void;\n readonly muted: boolean;\n}\n\n/** RMS of a PCM16 frame, 0..1. */\nexport function levelOf(pcm: ArrayBuffer): number {\n const s = new Int16Array(pcm);\n if (!s.length) return 0;\n let sum = 0;\n for (let i = 0; i < s.length; i++) {\n const v = s[i]! / 32768;\n sum += v * v;\n }\n return Math.sqrt(sum / s.length);\n}\n\nexport async function openMic(opts: MicOptions): Promise<Mic> {\n if (!navigator.mediaDevices?.getUserMedia) throw new Error('This browser cannot use a microphone here.');\n const stream = await navigator.mediaDevices.getUserMedia({\n audio: {\n deviceId: opts.deviceId ? { exact: opts.deviceId } : undefined,\n channelCount: 1,\n // The agent's voice comes out of the speakers; without cancellation it\n // would hear itself and answer.\n echoCancellation: true,\n noiseSuppression: true,\n autoGainControl: true,\n },\n });\n const ctx = new AudioContext({ latencyHint: 'interactive' });\n const source = ctx.createMediaStreamSource(stream);\n let muted = false;\n const deliver = (buf: ArrayBuffer) => {\n if (muted) {\n // Silence, not nothing: the server keeps a pre-roll of the last frames\n // and splices it onto the next utterance.\n opts.onFrame(new ArrayBuffer(buf.byteLength), 0);\n return;\n }\n opts.onFrame(buf, levelOf(buf));\n };\n\n let node: AudioNode;\n let teardown: () => void;\n try {\n const url = URL.createObjectURL(new Blob([WORKLET], { type: 'application/javascript' }));\n try {\n await ctx.audioWorklet.addModule(url);\n } finally {\n URL.revokeObjectURL(url);\n }\n const w = new AudioWorkletNode(ctx, 'cxyz-mic');\n w.port.onmessage = (e) => deliver(e.data as ArrayBuffer);\n node = w;\n teardown = () => {\n w.port.onmessage = null;\n };\n } catch {\n // A strict Content-Security-Policy can refuse a blob: worklet. The old\n // ScriptProcessor path is deprecated but universal.\n const sp = ctx.createScriptProcessor(4096, 1, 1);\n const ratio = ctx.sampleRate / TARGET_RATE;\n let pos = 0;\n let out = new Int16Array(FRAME_SAMPLES);\n let n = 0;\n sp.onaudioprocess = (e) => {\n const ch = e.inputBuffer.getChannelData(0);\n for (let i = 0; i < ch.length; i++) {\n pos += 1;\n if (pos >= ratio) {\n pos -= ratio;\n const s = Math.max(-1, Math.min(1, ch[i]!));\n out[n++] = s < 0 ? s * 0x8000 : s * 0x7fff;\n if (n === FRAME_SAMPLES) {\n deliver(out.buffer);\n out = new Int16Array(FRAME_SAMPLES);\n n = 0;\n }\n }\n }\n };\n node = sp;\n teardown = () => {\n sp.onaudioprocess = null;\n };\n }\n source.connect(node);\n // A worklet/processor only runs while connected to the destination; a gain\n // of zero keeps the room from hearing itself.\n const sink = ctx.createGain();\n sink.gain.value = 0;\n node.connect(sink).connect(ctx.destination);\n if (ctx.state === 'suspended') await ctx.resume().catch(() => {});\n\n return {\n get muted() {\n return muted;\n },\n setMuted(m: boolean) {\n muted = m;\n for (const t of stream.getAudioTracks()) t.enabled = !m;\n },\n stop() {\n teardown();\n try {\n source.disconnect();\n node.disconnect();\n } catch {\n /* already disconnected */\n }\n for (const t of stream.getTracks()) t.stop();\n void ctx.close().catch(() => {});\n },\n };\n}\n","/** A tiny typed event emitter. `on` returns the unsubscribe. */\nexport class Emitter<Events extends Record<string, unknown>> {\n private handlers: { [K in keyof Events]?: Set<(payload: Events[K]) => void> } = {};\n\n on<K extends keyof Events>(event: K, fn: (payload: Events[K]) => void): () => void {\n (this.handlers[event] ??= new Set()).add(fn);\n return () => this.handlers[event]?.delete(fn);\n }\n\n emit<K extends keyof Events>(event: K, payload: Events[K]): void {\n for (const fn of this.handlers[event] ?? []) {\n try {\n fn(payload);\n } catch (e) {\n // A listener's bug must never break the SDK's own state machine.\n console.error('[characterxyz] listener threw', e);\n }\n }\n }\n\n clear(): void {\n this.handlers = {};\n }\n}\n","export type CxErrorCode =\n | 'unauthorized'\n | 'forbidden'\n | 'not_found'\n | 'invalid'\n | 'rate_limited'\n | 'payment_required'\n | 'unavailable'\n | 'network'\n | 'unknown';\n\n/** Every failure the SDK reports, with a message fit to show a visitor. */\nexport class CxError extends Error {\n readonly code: CxErrorCode;\n readonly status: number;\n\n constructor(code: CxErrorCode, message: string, status = 0) {\n super(message);\n this.name = 'CxError';\n this.code = code;\n this.status = status;\n }\n}\n\nexport function codeForStatus(status: number): CxErrorCode {\n switch (status) {\n case 401:\n return 'unauthorized';\n case 403:\n return 'forbidden';\n case 404:\n return 'not_found';\n case 402:\n return 'payment_required';\n case 422:\n return 'invalid';\n case 429:\n return 'rate_limited';\n case 503:\n return 'unavailable';\n default:\n return 'unknown';\n }\n}\n","import { CxError, codeForStatus } from './errors.js';\n\nexport interface RequestOptions {\n method?: string;\n body?: unknown;\n token?: string;\n signal?: AbortSignal;\n}\n\nasync function errorFrom(res: Response): Promise<CxError> {\n let message = '';\n try {\n const j = (await res.json()) as { message?: unknown };\n if (typeof j?.message === 'string') message = j.message;\n } catch {\n // not JSON: the status says enough\n }\n return new CxError(codeForStatus(res.status), message || `Request failed (${res.status})`, res.status);\n}\n\nexport async function send(apiUrl: string, path: string, opts: RequestOptions = {}): Promise<Response> {\n const headers: Record<string, string> = {};\n if (opts.body !== undefined) headers['Content-Type'] = 'application/json';\n if (opts.token) headers.Authorization = `Bearer ${opts.token}`;\n let res: Response;\n try {\n res = await fetch(apiUrl + path, {\n method: opts.method ?? (opts.body === undefined ? 'GET' : 'POST'),\n headers,\n body: opts.body === undefined ? undefined : JSON.stringify(opts.body),\n signal: opts.signal,\n // No cookies, ever: the SDK authenticates with its own bearer token, and\n // a credentialed request would carry the brand page's cookies to us.\n credentials: 'omit',\n cache: 'no-store',\n });\n } catch (e) {\n if ((e as Error)?.name === 'AbortError') throw e;\n throw new CxError('network', 'Could not reach Character XYZ. Check your connection.');\n }\n if (!res.ok) throw await errorFrom(res);\n return res;\n}\n\n/** JSON request; unwraps the API's `{message, data}` envelope. */\nexport async function request<T>(apiUrl: string, path: string, opts: RequestOptions = {}): Promise<T> {\n const res = await send(apiUrl, path, opts);\n const j = (await res.json()) as { data?: T };\n return j.data as T;\n}\n\nexport interface ServerEvent {\n event: string;\n data: unknown;\n}\n\n/**\n * Read a `text/event-stream` body, calling `onEvent` per event, until the\n * stream ends or `signal` aborts. Fetch-based on purpose: `EventSource` cannot\n * send an Authorization header, so it would need the token in the URL.\n */\nexport async function readEvents(res: Response, onEvent: (e: ServerEvent) => void, signal?: AbortSignal): Promise<void> {\n const body = res.body;\n if (!body) return;\n const reader = body.getReader();\n const decoder = new TextDecoder();\n let buf = '';\n const onAbort = () => void reader.cancel().catch(() => {});\n signal?.addEventListener('abort', onAbort);\n try {\n for (;;) {\n const { value, done } = await reader.read();\n if (done) break;\n buf += decoder.decode(value, { stream: true });\n buf = drain(buf, onEvent);\n }\n buf += decoder.decode();\n drain(buf + '\\n\\n', onEvent);\n } finally {\n signal?.removeEventListener('abort', onAbort);\n }\n}\n\n/** Dispatch every complete event in `buf`; return what is left over. */\nexport function drain(buf: string, onEvent: (e: ServerEvent) => void): string {\n const normalised = buf.replace(/\\r\\n/g, '\\n');\n let rest = normalised;\n let idx: number;\n while ((idx = rest.indexOf('\\n\\n')) !== -1) {\n const block = rest.slice(0, idx);\n rest = rest.slice(idx + 2);\n let event = 'message';\n const data: string[] = [];\n for (const line of block.split('\\n')) {\n if (!line || line.startsWith(':')) continue;\n const colon = line.indexOf(':');\n const field = colon === -1 ? line : line.slice(0, colon);\n const value = colon === -1 ? '' : line.slice(colon + 1).replace(/^ /, '');\n if (field === 'event') event = value;\n else if (field === 'data') data.push(value);\n }\n if (!data.length) continue;\n const raw = data.join('\\n');\n let parsed: unknown = raw;\n try {\n parsed = JSON.parse(raw);\n } catch {\n // plain text data\n }\n onEvent({ event, data: parsed });\n }\n return rest;\n}\n","/**\n * The agent socket's binary packet (the same one the Stage reads):\n *\n * \"CXYZ\" | version u8 (1) | kind u8 | flags u8 (bit 0 = final)\n * | corrLen u16 | corr utf8 | seq u32 | timestamp u64 | duration u32\n * | payloadLen u32 | payload\n *\n * All little-endian. Kind 1 is voice (PCM16), kind 2/3 are face data, which\n * this SDK does not draw yet.\n */\nexport interface Packet {\n kind: number;\n final: boolean;\n corr: string;\n payload: Uint8Array;\n}\n\nexport function parsePacket(buf: ArrayBuffer): Packet | null {\n if (buf.byteLength < 25) return null;\n const v = new DataView(buf);\n if (v.getUint8(0) !== 0x43 || v.getUint8(1) !== 0x58 || v.getUint8(2) !== 0x59 || v.getUint8(3) !== 0x5a) return null;\n if (v.getUint8(4) !== 1) return null;\n const kind = v.getUint8(5);\n const final = (v.getUint8(6) & 1) !== 0;\n let o = 7;\n const corrLen = v.getUint16(o, true);\n o += 2;\n if (o + corrLen + 20 > buf.byteLength) return null;\n const corr = new TextDecoder().decode(new Uint8Array(buf, o, corrLen));\n o += corrLen + 4 + 8 + 4;\n const len = v.getUint32(o, true);\n o += 4;\n if (o + len > buf.byteLength) return null;\n return { kind, final, corr, payload: new Uint8Array(buf, o, len) };\n}\n\n/** Build one (for tests and tools). */\nexport function buildPacket(p: { kind: number; final: boolean; corr: string; payload: Uint8Array }): ArrayBuffer {\n const corr = new TextEncoder().encode(p.corr);\n const head = 7 + 2 + corr.length + 4 + 8 + 4 + 4;\n const buf = new ArrayBuffer(head + p.payload.byteLength);\n const v = new DataView(buf);\n const bytes = new Uint8Array(buf);\n bytes.set([0x43, 0x58, 0x59, 0x5a], 0);\n v.setUint8(4, 1);\n v.setUint8(5, p.kind);\n v.setUint8(6, p.final ? 1 : 0);\n let o = 7;\n v.setUint16(o, corr.length, true);\n o += 2;\n bytes.set(corr, o);\n o += corr.length + 4 + 8 + 4;\n v.setUint32(o, p.payload.byteLength, true);\n o += 4;\n bytes.set(p.payload, o);\n return buf;\n}\n","import { audioContext, PcmPlayer } from './audio/player.js';\nimport { openMic, type Mic } from './audio/mic.js';\nimport { Emitter } from './emitter.js';\nimport { CxError } from './errors.js';\nimport { readEvents, request, send } from './http.js';\nimport { parsePacket } from './protocol.js';\nimport type { SessionManager } from './session.js';\nimport type { CallEndReason, CallState, Caption } from './types.js';\n\nexport interface CallEvents extends Record<string, unknown> {\n state: CallState;\n /** The visitor's words and the agent's reply, as they are recognised. */\n caption: Caption;\n /** A caption the server withdrew (the visitor was not finished). */\n captionRemoved: string;\n /** The turn is ready: accept() within `holdSeconds`. */\n ready: { holdSeconds: number };\n /** One streamed face batch (kind-3 msgpack payload) for line `corr` — only with `face`. */\n face: { corr: string; payload: Uint8Array };\n /** A line of the agent's voice became audible, or ended (naturally or interrupted). */\n line: { corr: string; event: 'audible' | 'end' };\n error: CxError;\n}\n\nexport interface CallOptions {\n /** Join the moment it is this visitor's turn (default true). */\n autoAccept?: boolean;\n deviceId?: string;\n /**\n * Ask for the agent's face streamed with the voice (Neural Lip Sync), for a\n * UI that draws it. `emotion()` is read when the call connects: the face's\n * mood as the face service takes it (`joy:0.3`), or null for neutral.\n */\n face?: { emotion?: () => string | null };\n}\n\n/** Talking over the agent this loud, this long, stops her. */\nconst BARGE_IN_LEVEL = 0.09;\nconst BARGE_IN_MS = 350;\nconst HEARTBEAT_MS = 25_000;\n\nconst initial = (): CallState => ({\n phase: 'idle',\n callId: null,\n position: null,\n etaSeconds: null,\n holdSeconds: null,\n maxSeconds: null,\n startedAt: null,\n endReason: null,\n muted: false,\n speaking: false,\n agentState: 'idle',\n error: null,\n});\n\n/**\n * One voice call: join the line, wait (chatting is fine meanwhile), accept,\n * talk, hang up. A call is single-use; start another for the next one.\n */\nexport class Call extends Emitter<CallEvents> {\n private s: CallState = initial();\n private ticket: string | null = null;\n private eventsAbort: AbortController | null = null;\n private ws: WebSocket | null = null;\n private mic: Mic | null = null;\n private players = new Map<string, PcmPlayer>();\n private sampleRates = new Map<string, number>();\n private cancelled = new Set<string>();\n private speakingCorr: string | null = null;\n private heartbeat: ReturnType<typeof setInterval> | null = null;\n private loudSince: number | null = null;\n\n constructor(\n private readonly apiUrl: string,\n private readonly session: SessionManager,\n private readonly agentId: string,\n private readonly opts: CallOptions = {},\n ) {\n super();\n }\n\n get state(): CallState {\n return this.s;\n }\n\n /** The line being voiced now, and how much of it has been heard (ms). */\n audible(): { corr: string; ms: number } | null {\n const corr = this.speakingCorr;\n const p = corr ? this.players.get(corr) : undefined;\n return corr && p ? { corr, ms: p.playedMs() } : null;\n }\n\n /** Loudness of the agent's voice right now, 0..1. */\n voiceLevel(): number {\n const p = this.speakingCorr ? this.players.get(this.speakingCorr) : undefined;\n return p ? p.level() : 0;\n }\n\n private set(patch: Partial<CallState>) {\n this.s = { ...this.s, ...patch };\n this.emit('state', this.s);\n }\n\n /**\n * Call from a click: it unlocks audio, asks for the microphone, then joins\n * the line (or goes straight through when a slot is free).\n */\n async start(): Promise<void> {\n if (this.s.phase !== 'idle') return;\n this.set({ phase: 'joining' });\n // Created inside the gesture, or the browser keeps it suspended.\n audioContext();\n try {\n this.mic = await openMic({ deviceId: this.opts.deviceId, onFrame: (pcm, level) => this.onMicFrame(pcm, level) });\n } catch {\n this.finish('mic-denied', 'Allow the microphone to talk, or chat instead.');\n return;\n }\n try {\n const token = await this.session.token();\n const r = await request<{ callId: string; state: string; position?: number; etaSeconds?: number }>(this.apiUrl, '/sdk/v1/calls', {\n method: 'POST',\n body: {},\n token,\n });\n this.set({ callId: r.callId, phase: r.state === 'ready' ? 'joining' : 'queued', position: r.position ?? null, etaSeconds: r.etaSeconds ?? null });\n void this.follow();\n } catch (e) {\n const err = e instanceof CxError ? e : new CxError('unknown', 'Could not start the call.');\n const reason: CallEndReason = err.code === 'rate_limited' ? 'busy' : 'unavailable';\n this.finish(reason, err.message);\n this.emit('error', err);\n }\n }\n\n /** Follow the call's server-side state, reconnecting the stream if it drops. */\n private async follow(): Promise<void> {\n let failures = 0;\n while (this.s.callId && this.s.phase !== 'ended' && this.s.phase !== 'idle') {\n this.eventsAbort = new AbortController();\n try {\n const token = await this.session.token();\n const res = await send(this.apiUrl, `/sdk/v1/calls/${encodeURIComponent(this.s.callId)}/events`, { token, signal: this.eventsAbort.signal });\n failures = 0;\n await readEvents(res, (e) => this.onServerEvent(e.event, e.data as Record<string, unknown>), this.eventsAbort.signal);\n } catch (e) {\n if ((e as Error)?.name === 'AbortError') return;\n if (e instanceof CxError && e.code === 'not_found') {\n this.finish('failed', 'The call ended.');\n return;\n }\n failures += 1;\n if (failures > 5) {\n this.finish('failed', 'Lost the connection to the call.');\n return;\n }\n }\n if (this.ended()) return;\n await new Promise((r) => setTimeout(r, Math.min(4000, 500 * 2 ** failures)));\n }\n }\n\n private onServerEvent(event: string, d: Record<string, unknown>) {\n switch (event) {\n case 'queued':\n if (this.s.phase === 'joining' || this.s.phase === 'queued') {\n this.set({ phase: 'queued', position: Number(d.position) || 1, etaSeconds: Number(d.etaSeconds) || null });\n }\n break;\n case 'ready': {\n if (typeof d.ticket === 'string' && d.ticket) this.ticket = d.ticket;\n const hold = Number(d.holdSeconds) || 0;\n if (this.s.phase !== 'ready' && this.s.phase !== 'connecting' && this.s.phase !== 'live') {\n this.set({ phase: 'ready', holdSeconds: hold, position: null, etaSeconds: null });\n this.emit('ready', { holdSeconds: hold });\n if (this.opts.autoAccept !== false) this.accept();\n } else if (this.s.phase === 'ready') {\n this.set({ holdSeconds: hold });\n }\n break;\n }\n case 'live':\n this.set({ phase: 'live', maxSeconds: Number(d.maxSeconds) || null, startedAt: this.s.startedAt ?? Date.now() - (Number(d.elapsedSeconds) || 0) * 1000 });\n break;\n case 'ended':\n this.finish((String(d.reason || 'hangup') as CallEndReason) || 'hangup', null);\n break;\n }\n }\n\n // A method, not an inline comparison: the phase changes across an await,\n // which TypeScript's narrowing cannot see.\n private ended(): boolean {\n return this.s.phase === 'ended';\n }\n\n /** Take the call now that it is this visitor's turn. */\n accept(): void {\n if (this.s.phase !== 'ready' || !this.ticket || this.ws) return;\n this.set({ phase: 'connecting' });\n const url = this.apiUrl.replace(/^http/, 'ws') + '/sdk/v1/calls/socket';\n const ws = new WebSocket(url, [`cxyz-ticket.${this.ticket}`]);\n this.ticket = null;\n ws.binaryType = 'arraybuffer';\n this.ws = ws;\n ws.onopen = () => {\n const face = this.opts.face;\n const emotion = face?.emotion?.() ?? null;\n ws.send(\n JSON.stringify({\n type: 'agent_identity',\n agent_id: this.agentId,\n skin_index: 0,\n blendshapes: !!face,\n ...(face ? { blendshape_stream: true } : {}),\n ...(face && emotion ? { face_emotion: emotion } : {}),\n }),\n );\n // This page does not gate the microphone: the server's own voice\n // detection judges every frame.\n ws.send(JSON.stringify({ type: 'mic_state', silero: 'off', denoise: false }));\n this.heartbeat = setInterval(() => this.sendJson({ type: 'heartbeat' }), HEARTBEAT_MS);\n this.set({ phase: 'live', startedAt: this.s.startedAt ?? Date.now() });\n };\n ws.onmessage = (e) => this.onSocket(e.data);\n ws.onclose = () => {\n this.ws = null;\n // The event stream says why; give it a moment before calling it ourselves.\n setTimeout(() => {\n if (this.s.phase === 'live' || this.s.phase === 'connecting') this.finish('hangup', null);\n }, 1500);\n };\n }\n\n private sendJson(o: unknown) {\n if (this.ws?.readyState === WebSocket.OPEN) this.ws.send(JSON.stringify(o));\n }\n\n private onMicFrame(pcm: ArrayBuffer, level: number) {\n const ws = this.ws;\n if (!ws || ws.readyState !== WebSocket.OPEN) return;\n if (this.speakingCorr) {\n // The agent must not hear itself: while she talks the frames go up as\n // silence, unless the visitor is clearly talking over her.\n const now = performance.now();\n if (level > BARGE_IN_LEVEL) {\n this.loudSince ??= now;\n if (now - this.loudSince >= BARGE_IN_MS) {\n this.loudSince = null;\n this.interrupt();\n ws.send(pcm);\n return;\n }\n } else {\n this.loudSince = null;\n }\n ws.send(new ArrayBuffer(pcm.byteLength));\n return;\n }\n ws.send(pcm);\n }\n\n private onSocket(data: unknown) {\n if (data instanceof ArrayBuffer) {\n const p = parsePacket(data);\n if (!p || this.cancelled.has(p.corr)) return;\n if (p.kind === 3) {\n // A copy, so the receiver may keep or transfer it.\n if (this.opts.face) this.emit('face', { corr: p.corr, payload: p.payload.slice() });\n return;\n }\n if (p.kind !== 1) return;\n let player = this.players.get(p.corr);\n if (!player) {\n // A new line: whatever was playing is over.\n for (const [c, old] of this.players) {\n old.stop();\n this.players.delete(c);\n }\n const corr = p.corr;\n player = new PcmPlayer({\n sampleRate: this.sampleRates.get(corr) ?? 16_000,\n onStart: () => {\n this.speakingCorr = corr;\n this.set({ speaking: true });\n this.emit('line', { corr, event: 'audible' });\n this.sendJson({ type: 'playback_started', correlationId: corr, timestampMs: Date.now() });\n },\n onEnd: () => {\n this.players.delete(corr);\n if (this.speakingCorr === corr) this.speakingCorr = null;\n this.set({ speaking: false });\n this.emit('line', { corr, event: 'end' });\n this.sendJson({ type: 'playback_ended', correlationId: corr, timestampMs: Date.now(), reason: 'natural' });\n this.sendJson({ type: 'speech_ended' });\n },\n });\n this.players.set(corr, player);\n }\n player.enqueue(p.payload);\n if (p.final) player.end();\n return;\n }\n if (typeof data !== 'string') return;\n let o: Record<string, unknown>;\n try {\n o = JSON.parse(data);\n } catch {\n return;\n }\n if ('AgentSpeechMeta' in o) {\n const m = o.AgentSpeechMeta as { correlation_id?: string; sample_rate?: number };\n if (m?.correlation_id && m.sample_rate) this.sampleRates.set(m.correlation_id, m.sample_rate);\n return;\n }\n if ('InteractorTranscript' in o) {\n const t = o.InteractorTranscript as { correlation_id: string; text: string };\n if (t?.text) this.emit('caption', { id: `v:${t.correlation_id}`, role: 'visitor', text: t.text });\n return;\n }\n if ('AgentReplyTranscript' in o) {\n const t = o.AgentReplyTranscript as { correlation_id: string; text: string };\n if (t?.text && !this.cancelled.has(t.correlation_id)) this.emit('caption', { id: `a:${t.correlation_id}`, role: 'agent', text: t.text });\n return;\n }\n if (o.type === 'turn_cancelled' && typeof o.correlationId === 'string') {\n const cid = o.correlationId;\n this.cancelled.add(cid);\n this.players.get(cid)?.stop();\n this.players.delete(cid);\n this.emit('line', { corr: cid, event: 'end' });\n if (this.speakingCorr === cid) {\n this.speakingCorr = null;\n this.set({ speaking: false });\n }\n this.emit('captionRemoved', `a:${cid}`);\n return;\n }\n if (o.kind === 'agent_status' && typeof o.state === 'string') {\n this.set({ agentState: o.state.toLowerCase() });\n }\n }\n\n /** Stop the agent mid-sentence (the visitor wants to speak). */\n interrupt(): void {\n const corr = this.speakingCorr;\n if (!corr) return;\n const p = this.players.get(corr);\n const heardMs = Math.round(p?.playedMs() ?? 0);\n p?.stop();\n this.players.delete(corr);\n this.cancelled.add(corr);\n this.speakingCorr = null;\n this.set({ speaking: false });\n this.emit('line', { corr, event: 'end' });\n this.sendJson({ type: 'playback_ended', correlationId: corr, timestampMs: Date.now(), reason: 'interrupted' });\n this.sendJson({ type: 'interrupt', correlationId: corr, heardMs, timestampMs: Date.now() });\n }\n\n setMuted(muted: boolean): void {\n this.mic?.setMuted(muted);\n this.set({ muted });\n }\n\n /** Leave the line, or hang up. */\n async hangUp(): Promise<void> {\n const id = this.s.callId;\n const was = this.s.phase;\n this.finish(was === 'live' ? 'hangup' : 'left', null);\n if (!id) return;\n try {\n const token = await this.session.token();\n await send(this.apiUrl, `/sdk/v1/calls/${encodeURIComponent(id)}`, { method: 'DELETE', token });\n } catch {\n // The server notices a closed socket / abandoned line on its own.\n }\n }\n\n private finish(reason: CallEndReason, error: string | null) {\n if (this.s.phase === 'ended') return;\n this.eventsAbort?.abort();\n this.eventsAbort = null;\n if (this.heartbeat) clearInterval(this.heartbeat);\n this.heartbeat = null;\n for (const p of this.players.values()) p.stop();\n this.players.clear();\n this.speakingCorr = null;\n this.mic?.stop();\n this.mic = null;\n const ws = this.ws;\n this.ws = null;\n if (ws && ws.readyState <= WebSocket.OPEN) ws.close(1000);\n this.ticket = null;\n this.set({ phase: 'ended', endReason: reason, speaking: false, holdSeconds: null, error });\n }\n}\n","import { Emitter } from './emitter.js';\nimport { CxError } from './errors.js';\nimport { readEvents, request, send } from './http.js';\nimport type { SessionManager } from './session.js';\nimport type { ChatMessage } from './types.js';\n\nexport interface ChatEvents extends Record<string, unknown> {\n /** The whole list, after any change. */\n messages: ChatMessage[];\n /** True from send until the reply is complete. */\n busy: boolean;\n error: CxError;\n}\n\nlet localSeq = 0;\nconst localId = (p: string) => `${p}_${Date.now().toString(36)}_${(localSeq++).toString(36)}`;\n\n/**\n * Text chat with the agent. History lives on the server, so it follows the\n * visitor across page loads (and, for an identified visitor, devices).\n */\nexport class Chat extends Emitter<ChatEvents> {\n private list: ChatMessage[] = [];\n private loaded = false;\n private busy = false;\n private abort: AbortController | null = null;\n\n constructor(\n private readonly apiUrl: string,\n private readonly session: SessionManager,\n ) {\n super();\n }\n\n get messages(): readonly ChatMessage[] {\n return this.list;\n }\n\n get isBusy(): boolean {\n return this.busy;\n }\n\n private publish() {\n this.list = [...this.list];\n this.emit('messages', this.list);\n }\n\n /** Load earlier messages (once; later calls return what is held). */\n async load(): Promise<readonly ChatMessage[]> {\n if (this.loaded) return this.list;\n const token = await this.session.token();\n const res = await request<{ messages: ChatMessage[] }>(this.apiUrl, '/sdk/v1/chat/messages?limit=50', { token });\n // Anything sent while the history was loading stays after it.\n const pending = this.list;\n this.list = [...(res?.messages ?? []), ...pending];\n this.loaded = true;\n this.publish();\n return this.list;\n }\n\n /**\n * Send a message; the reply streams into `messages` as it is written.\n * Resolves with the finished reply.\n */\n async send(text: string): Promise<ChatMessage> {\n const t = text.trim();\n if (!t) throw new CxError('invalid', 'Say something first.');\n if (this.busy) throw new CxError('rate_limited', 'Wait for the reply first.');\n this.setBusy(true);\n const mine: ChatMessage = { id: localId('local'), role: 'visitor', text: t, createdAt: new Date().toISOString() };\n const reply: ChatMessage = { id: localId('reply'), role: 'agent', text: '', createdAt: new Date().toISOString(), streaming: true };\n this.list.push(mine, reply);\n this.publish();\n\n this.abort = new AbortController();\n try {\n const token = await this.session.token();\n const res = await send(this.apiUrl, '/sdk/v1/chat/messages', { method: 'POST', body: { text: t }, token, signal: this.abort.signal });\n let finished: ChatMessage | null = null;\n let failure: string | null = null;\n await readEvents(\n res,\n ({ event, data }) => {\n const d = data as Record<string, unknown>;\n if (event === 'delta' && typeof d?.text === 'string') {\n reply.text += d.text;\n this.publish();\n } else if (event === 'done') {\n finished = { id: String(d.id), role: 'agent', text: String(d.text ?? reply.text), createdAt: String(d.createdAt ?? reply.createdAt) };\n } else if (event === 'error') {\n failure = typeof d?.message === 'string' ? d.message : 'Something went wrong.';\n }\n },\n this.abort.signal,\n );\n if (failure || !finished) throw new CxError('unknown', failure ?? 'The reply was cut off. Try again.');\n const done: ChatMessage = finished;\n this.replace(reply.id, done);\n return done;\n } catch (e) {\n const err = e instanceof CxError ? e : new CxError('network', 'The reply was cut off. Try again.');\n this.list = this.list.filter((m) => m.id !== reply.id);\n const idx = this.list.findIndex((m) => m.id === mine.id);\n if (idx !== -1) this.list[idx] = { ...mine, failed: true };\n this.publish();\n if ((e as Error)?.name !== 'AbortError') this.emit('error', err);\n throw err;\n } finally {\n this.abort = null;\n this.setBusy(false);\n }\n }\n\n /** Send a failed message again. */\n retry(id: string): Promise<ChatMessage> {\n const m = this.list.find((x) => x.id === id && x.failed);\n if (!m) throw new CxError('not_found', 'Nothing to retry.');\n this.list = this.list.filter((x) => x.id !== id);\n this.publish();\n return this.send(m.text);\n }\n\n /** Stop listening to a reply in progress (the server still finishes it). */\n stop(): void {\n this.abort?.abort();\n }\n\n private replace(id: string, next: ChatMessage) {\n const i = this.list.findIndex((m) => m.id === id);\n if (i !== -1) this.list[i] = next;\n this.publish();\n }\n\n private setBusy(b: boolean) {\n this.busy = b;\n this.emit('busy', b);\n }\n}\n","import { CxError } from './errors.js';\nimport { request } from './http.js';\nimport type { SessionInfo } from './types.js';\n\n/** Where the SDK may remember this browser's anonymous visitor id. */\nexport interface VisitorStore {\n get(key: string): string | null;\n set(key: string, value: string): void;\n}\n\nexport const memoryStore = (): VisitorStore => {\n const m = new Map<string, string>();\n return { get: (k) => m.get(k) ?? null, set: (k, v) => void m.set(k, v) };\n};\n\nexport const localStore = (): VisitorStore => ({\n get(k) {\n try {\n return globalThis.localStorage?.getItem(k) ?? null;\n } catch {\n return null;\n }\n },\n set(k, v) {\n try {\n globalThis.localStorage?.setItem(k, v);\n } catch {\n // private mode / blocked storage: the visitor is simply new each time\n }\n },\n});\n\nexport interface SessionSource {\n apiUrl: string;\n agentId?: string;\n /** Browser path: a publishable key, exchanged from this page's origin. */\n publishableKey?: string;\n /**\n * Server path: your backend mints the session with a secret key (an\n * identified visitor) and hands the token to the page. Called again when\n * the session is about to run out.\n */\n getSessionToken?: () => Promise<string | SessionInfo>;\n store: VisitorStore;\n}\n\n/** Renew this long before expiry. */\nconst RENEW_EARLY_S = 60;\n\n/**\n * Holds the current session, renews it before it runs out, and never runs\n * two renewals at once.\n */\nexport class SessionManager {\n private current: SessionInfo | null = null;\n private inflight: Promise<SessionInfo> | null = null;\n\n constructor(private readonly src: SessionSource) {\n if (!src.publishableKey && !src.getSessionToken) {\n throw new CxError('invalid', 'Pass a publishableKey, or getSessionToken for sessions your server mints.');\n }\n }\n\n private visitorKey(): string {\n // Per key, so two brands on one domain never share a visitor.\n const k = this.src.publishableKey ?? 'server';\n return `cxyz:visitor:${k.slice(-12)}`;\n }\n\n get info(): SessionInfo | null {\n return this.current;\n }\n\n /** A token valid for at least the next minute. */\n async token(): Promise<string> {\n const now = Date.now() / 1000;\n if (this.current && this.current.expiresAt - RENEW_EARLY_S > now) return this.current.token;\n return (await this.refresh()).token;\n }\n\n refresh(): Promise<SessionInfo> {\n this.inflight ??= this.mint().finally(() => {\n this.inflight = null;\n });\n return this.inflight;\n }\n\n private async mint(): Promise<SessionInfo> {\n let info: SessionInfo;\n if (this.src.getSessionToken) {\n const got = await this.src.getSessionToken();\n if (typeof got === 'string') {\n // A bare token: ask the server what it unlocks.\n info = await this.describe(got);\n } else {\n info = got;\n }\n } else {\n const visitorId = this.src.store.get(this.visitorKey()) ?? undefined;\n info = await request<SessionInfo>(this.src.apiUrl, '/sdk/v1/sessions', {\n method: 'POST',\n body: { publishableKey: this.src.publishableKey, agentId: this.src.agentId, visitorId },\n });\n this.src.store.set(this.visitorKey(), info.visitorId);\n }\n this.current = info;\n return info;\n }\n\n /** The session behind a token minted elsewhere (`getSessionToken` returned a string). */\n private async describe(token: string): Promise<SessionInfo> {\n const info = await request<SessionInfo>(this.src.apiUrl, '/sdk/v1/session', { token });\n return { ...info, token };\n }\n}\n","import { Call, type CallOptions } from './call.js';\nimport { Chat } from './chat.js';\nimport { Emitter } from './emitter.js';\nimport { CxError } from './errors.js';\nimport { request } from './http.js';\nimport { localStore, memoryStore, SessionManager, type VisitorStore } from './session.js';\nimport type { AgentCard, Features, SessionInfo } from './types.js';\n\nexport const DEFAULT_API_URL = 'https://api.character.xyz';\n\nexport interface InitOptions {\n /** `cxyz_pk_live_…` — safe in the page; works only from the key's allowed sites. */\n publishableKey?: string;\n /**\n * For signed-in visitors: return a session your server minted with its\n * secret key (see `@characterxyz/server`). Called again before expiry.\n */\n getSessionToken?: () => Promise<string | SessionInfo>;\n /** Which of the key's agents to talk to. Defaults to the key's first. */\n agentId?: string;\n /** Override the API (staging, local development). */\n apiUrl?: string;\n /** Remember the anonymous visitor across visits (default) or not at all. */\n storage?: 'local' | 'memory' | VisitorStore;\n}\n\nexport interface ClientEvents extends Record<string, unknown> {\n /** A call started or ended; the widget swaps its view on this. */\n call: Call | null;\n error: CxError;\n}\n\n/**\n * The headless SDK. `await CharacterXYZ.init({ publishableKey })`, then use\n * `chat` and `startCall()`. Everything the widget does goes through here, so\n * a brand can build its own UI on the same calls.\n */\nexport class CharacterXYZ extends Emitter<ClientEvents> {\n readonly chat: Chat;\n private currentCall: Call | null = null;\n private destroyed = false;\n\n private constructor(\n readonly apiUrl: string,\n private readonly session: SessionManager,\n private info: SessionInfo,\n ) {\n super();\n this.chat = new Chat(apiUrl, session);\n }\n\n static async init(opts: InitOptions): Promise<CharacterXYZ> {\n const apiUrl = (opts.apiUrl ?? DEFAULT_API_URL).replace(/\\/+$/, '');\n if (opts.publishableKey && /^cxyz_sk_/.test(opts.publishableKey)) {\n // A secret key in a page is a leak. Refuse loudly, before it is sent anywhere.\n throw new CxError('invalid', 'That is a SECRET key. Never put it in a web page: use a publishable key (cxyz_pk_…). Revoke the secret key now.');\n }\n const store = opts.storage === 'memory' ? memoryStore() : opts.storage && typeof opts.storage === 'object' ? opts.storage : localStore();\n const session = new SessionManager({ apiUrl, agentId: opts.agentId, publishableKey: opts.publishableKey, getSessionToken: opts.getSessionToken, store });\n const info = await session.refresh();\n return new CharacterXYZ(apiUrl, session, info);\n }\n\n get agent(): AgentCard {\n return (this.session.info ?? this.info).agent;\n }\n\n get features(): Features {\n return (this.session.info ?? this.info).features;\n }\n\n get appearance(): Record<string, unknown> {\n return (this.session.info ?? this.info).appearance ?? {};\n }\n\n get visitorId(): string {\n return (this.session.info ?? this.info).visitorId;\n }\n\n get mode(): 'live' | 'test' {\n return (this.session.info ?? this.info).mode;\n }\n\n /** The call in progress (queued, ready or live), if any. */\n get call(): Call | null {\n return this.currentCall && this.currentCall.state.phase !== 'ended' ? this.currentCall : null;\n }\n\n /**\n * The worn video character's full render data (the public projection the\n * app's Stage reads), for a UI that draws the face — the widget hands it to\n * the app's renderer. Null when the agent wears none.\n */\n async videoAvatar(): Promise<Record<string, unknown> | null> {\n const token = await this.session.token();\n return request<Record<string, unknown> | null>(this.apiUrl, '/sdk/v1/agent/video-avatar', { token });\n }\n\n /** Start a voice call. Call from a click: it needs the microphone and audio unlocked. */\n async startCall(opts: CallOptions = {}): Promise<Call> {\n if (this.destroyed) throw new CxError('invalid', 'This client was destroyed.');\n if (!this.features.call) throw new CxError('forbidden', 'Calls are not available on this site.');\n if (this.call) return this.call;\n const call = new Call(this.apiUrl, this.session, this.agent.id, opts);\n this.currentCall = call;\n call.on('state', (s) => {\n if (s.phase === 'ended' && this.currentCall === call) this.emit('call', null);\n });\n call.on('error', (e) => this.emit('error', e));\n this.emit('call', call);\n await call.start();\n return call;\n }\n\n destroy(): void {\n this.destroyed = true;\n void this.currentCall?.hangUp();\n this.chat.stop();\n this.chat.clear();\n this.clear();\n }\n}\n","/**\n * `@characterxyz/web` — Character XYZ on any web page, headless.\n *\n * ```ts\n * import { CharacterXYZ } from '@characterxyz/web';\n *\n * const cx = await CharacterXYZ.init({ publishableKey: 'cxyz_pk_live_…' });\n * cx.chat.on('messages', render);\n * await cx.chat.send('Hi!');\n *\n * button.onclick = async () => {\n * const call = await cx.startCall();\n * call.on('state', (s) => show(s.phase, s.position));\n * };\n * ```\n *\n * The ready-made widget is `@characterxyz/widget`; this package is what it\n * is built on, for brands who want their own UI.\n */\nexport { CharacterXYZ, DEFAULT_API_URL, type InitOptions, type ClientEvents } from './client.js';\nexport { Chat, type ChatEvents } from './chat.js';\nexport { Call, type CallEvents, type CallOptions } from './call.js';\nexport { CxError, type CxErrorCode } from './errors.js';\nexport { Emitter } from './emitter.js';\nexport type { VisitorStore } from './session.js';\nexport type {\n AgentCard,\n CallEndReason,\n CallPhase,\n CallState,\n Caption,\n ChatMessage,\n Features,\n SessionInfo,\n VideoCharacter,\n VideoClip,\n} from './types.js';\nexport const VERSION = '0.1.0';\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/audio/player.ts","../src/audio/mic.ts","../src/emitter.ts","../src/errors.ts","../src/http.ts","../src/protocol.ts","../src/call.ts","../src/chat.ts","../src/session.ts","../src/client.ts","../src/index.ts"],"names":["shared","audioContext","PcmPlayer","opts","__publicField","bytes","count","view","buf","ch","i","src","now","delayMs","s","sum","v","WORKLET","levelOf","pcm","openMic","stream","ctx","source","muted","deliver","node","teardown","url","w","e","sp","ratio","pos","out","n","sink","m","t","Emitter","event","fn","_a","payload","CxError","code","message","status","codeForStatus","errorFrom","res","j","send","apiUrl","path","headers","request","readEvents","onEvent","signal","body","reader","decoder","onAbort","value","done","drain","rest","idx","block","data","line","colon","field","raw","parsed","parsePacket","kind","final","o","corrLen","corr","len","BARGE_IN_LEVEL","BARGE_IN_MS","HEARTBEAT_MS","initial","Call","session","agentId","p","patch","level","token","r","err","reason","failures","d","hold","ws","face","emotion","player","old","cid","heardMs","id","was","error","localSeq","localId","Chat","pending","text","mine","reply","finished","failure","next","q","x","b","memoryStore","k","localStore","RENEW_EARLY_S","SessionManager","info","got","visitorId","DEFAULT_API_URL","CharacterXYZ","_CharacterXYZ","store","call","VERSION"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Plays the agent's streamed voice (PCM16 chunks) gaplessly, and reports how\n * loud it is right now so a UI can draw a ring that follows the voice.\n *\n * Each chunk becomes an AudioBuffer scheduled right after the last one; the\n * first waits a short pre-roll so a slow second chunk does not open a gap.\n */\n\nexport interface PlayerOptions {\n sampleRate?: number;\n onStart?: () => void;\n onEnd?: () => void;\n volume?: number;\n}\n\nconst PREROLL_S = 0.12;\n\nlet shared: AudioContext | null = null;\n\n/** One output context for the page, created on first use (after a gesture). */\nexport function audioContext(): AudioContext {\n if (!shared || shared.state === 'closed') shared = new AudioContext({ latencyHint: 'interactive' });\n if (shared.state === 'suspended') void shared.resume().catch(() => {});\n return shared;\n}\n\nexport class PcmPlayer {\n private readonly ctx: AudioContext;\n private readonly gain: GainNode;\n private readonly analyser: AnalyserNode;\n private readonly data: Uint8Array<ArrayBuffer>;\n private nextAt = 0;\n private started = false;\n private ended = false;\n private finishing = false;\n private sources = new Set<AudioBufferSourceNode>();\n private startedAt = 0;\n readonly sampleRate: number;\n\n constructor(private readonly opts: PlayerOptions = {}) {\n this.ctx = audioContext();\n this.sampleRate = opts.sampleRate ?? 16_000;\n this.gain = this.ctx.createGain();\n this.gain.gain.value = opts.volume ?? 1;\n this.analyser = this.ctx.createAnalyser();\n this.analyser.fftSize = 512;\n this.data = new Uint8Array(new ArrayBuffer(this.analyser.fftSize));\n this.gain.connect(this.analyser).connect(this.ctx.destination);\n }\n\n /** Queue PCM16 little-endian mono bytes. */\n enqueue(bytes: Uint8Array): void {\n if (this.ended || bytes.byteLength < 2) return;\n const count = Math.floor(bytes.byteLength / 2);\n const view = new DataView(bytes.buffer, bytes.byteOffset, count * 2);\n const buf = this.ctx.createBuffer(1, count, this.sampleRate);\n const ch = buf.getChannelData(0);\n for (let i = 0; i < count; i++) ch[i] = view.getInt16(i * 2, true) / 32768;\n const src = this.ctx.createBufferSource();\n src.buffer = buf;\n src.connect(this.gain);\n const now = this.ctx.currentTime;\n if (this.nextAt < now) this.nextAt = now + (this.started ? 0.02 : PREROLL_S);\n src.start(this.nextAt);\n if (!this.started) {\n this.started = true;\n const delayMs = Math.max(0, (this.nextAt - now) * 1000);\n this.startedAt = performance.now() + delayMs;\n setTimeout(() => this.opts.onStart?.(), delayMs);\n }\n this.nextAt += buf.duration;\n this.sources.add(src);\n src.onended = () => {\n this.sources.delete(src);\n if (this.finishing && this.sources.size === 0) this.finish();\n };\n }\n\n /** No more chunks: report the end once the queue has played out. */\n end(): void {\n this.finishing = true;\n if (this.sources.size === 0) this.finish();\n }\n\n /** Silence now (an interruption). Does not call `onEnd`. */\n stop(): void {\n this.ended = true;\n for (const s of this.sources) {\n try {\n s.stop();\n } catch {\n /* not started */\n }\n }\n this.sources.clear();\n this.gain.disconnect();\n }\n\n /** Milliseconds of audio actually heard so far. */\n playedMs(): number {\n return this.started ? Math.max(0, performance.now() - this.startedAt) : 0;\n }\n\n /** Loudness now, 0..1. */\n level(): number {\n this.analyser.getByteTimeDomainData(this.data);\n let sum = 0;\n for (let i = 0; i < this.data.length; i++) {\n const v = (this.data[i]! - 128) / 128;\n sum += v * v;\n }\n return Math.min(1, Math.sqrt(sum / this.data.length) * 3);\n }\n\n private finish() {\n if (this.ended) return;\n this.ended = true;\n this.gain.disconnect();\n this.opts.onEnd?.();\n }\n}\n","/**\n * The microphone as the agent socket wants it: 16 kHz mono PCM16, 30 ms\n * (480-sample) frames, sent continuously.\n *\n * Resampled in an AudioWorklet from whatever rate the device runs at. A\n * context forced to 16 kHz would be simpler and is refused by Firefox for a\n * MediaStream source at another rate, so the worklet does it.\n */\n\nexport const TARGET_RATE = 16_000;\nexport const FRAME_SAMPLES = 480;\n\nconst WORKLET = `\nclass CxyzMic extends AudioWorkletProcessor {\n constructor(o) {\n super();\n this.ratio = sampleRate / ${TARGET_RATE};\n this.pos = 0;\n this.lp = 0;\n this.alpha = Math.min(1, 2 * Math.PI * 7000 / sampleRate / (1 + 2 * Math.PI * 7000 / sampleRate));\n this.out = new Int16Array(${FRAME_SAMPLES});\n this.n = 0;\n }\n process(inputs) {\n const ch = inputs[0] && inputs[0][0];\n if (!ch) return true;\n for (let i = 0; i < ch.length; i++) {\n this.lp += this.alpha * (ch[i] - this.lp);\n this.pos += 1;\n if (this.pos >= this.ratio) {\n this.pos -= this.ratio;\n const s = Math.max(-1, Math.min(1, this.lp));\n this.out[this.n++] = s < 0 ? s * 0x8000 : s * 0x7fff;\n if (this.n === ${FRAME_SAMPLES}) {\n this.port.postMessage(this.out.buffer, [this.out.buffer]);\n this.out = new Int16Array(${FRAME_SAMPLES});\n this.n = 0;\n }\n }\n }\n return true;\n }\n}\nregisterProcessor('cxyz-mic', CxyzMic);\n`;\n\nexport interface MicOptions {\n onFrame: (pcm: ArrayBuffer, level: number) => void;\n deviceId?: string;\n}\n\nexport interface Mic {\n stop(): void;\n setMuted(m: boolean): void;\n readonly muted: boolean;\n}\n\n/** RMS of a PCM16 frame, 0..1. */\nexport function levelOf(pcm: ArrayBuffer): number {\n const s = new Int16Array(pcm);\n if (!s.length) return 0;\n let sum = 0;\n for (let i = 0; i < s.length; i++) {\n const v = s[i]! / 32768;\n sum += v * v;\n }\n return Math.sqrt(sum / s.length);\n}\n\nexport async function openMic(opts: MicOptions): Promise<Mic> {\n if (!navigator.mediaDevices?.getUserMedia) throw new Error('This browser cannot use a microphone here.');\n const stream = await navigator.mediaDevices.getUserMedia({\n audio: {\n deviceId: opts.deviceId ? { exact: opts.deviceId } : undefined,\n channelCount: 1,\n // The agent's voice comes out of the speakers; without cancellation it\n // would hear itself and answer.\n echoCancellation: true,\n noiseSuppression: true,\n autoGainControl: true,\n },\n });\n const ctx = new AudioContext({ latencyHint: 'interactive' });\n const source = ctx.createMediaStreamSource(stream);\n let muted = false;\n const deliver = (buf: ArrayBuffer) => {\n if (muted) {\n // Silence, not nothing: the server keeps a pre-roll of the last frames\n // and splices it onto the next utterance.\n opts.onFrame(new ArrayBuffer(buf.byteLength), 0);\n return;\n }\n opts.onFrame(buf, levelOf(buf));\n };\n\n let node: AudioNode;\n let teardown: () => void;\n try {\n const url = URL.createObjectURL(new Blob([WORKLET], { type: 'application/javascript' }));\n try {\n await ctx.audioWorklet.addModule(url);\n } finally {\n URL.revokeObjectURL(url);\n }\n const w = new AudioWorkletNode(ctx, 'cxyz-mic');\n w.port.onmessage = (e) => deliver(e.data as ArrayBuffer);\n node = w;\n teardown = () => {\n w.port.onmessage = null;\n };\n } catch {\n // A strict Content-Security-Policy can refuse a blob: worklet. The old\n // ScriptProcessor path is deprecated but universal.\n const sp = ctx.createScriptProcessor(4096, 1, 1);\n const ratio = ctx.sampleRate / TARGET_RATE;\n let pos = 0;\n let out = new Int16Array(FRAME_SAMPLES);\n let n = 0;\n sp.onaudioprocess = (e) => {\n const ch = e.inputBuffer.getChannelData(0);\n for (let i = 0; i < ch.length; i++) {\n pos += 1;\n if (pos >= ratio) {\n pos -= ratio;\n const s = Math.max(-1, Math.min(1, ch[i]!));\n out[n++] = s < 0 ? s * 0x8000 : s * 0x7fff;\n if (n === FRAME_SAMPLES) {\n deliver(out.buffer);\n out = new Int16Array(FRAME_SAMPLES);\n n = 0;\n }\n }\n }\n };\n node = sp;\n teardown = () => {\n sp.onaudioprocess = null;\n };\n }\n source.connect(node);\n // A worklet/processor only runs while connected to the destination; a gain\n // of zero keeps the room from hearing itself.\n const sink = ctx.createGain();\n sink.gain.value = 0;\n node.connect(sink).connect(ctx.destination);\n if (ctx.state === 'suspended') await ctx.resume().catch(() => {});\n\n return {\n get muted() {\n return muted;\n },\n setMuted(m: boolean) {\n muted = m;\n for (const t of stream.getAudioTracks()) t.enabled = !m;\n },\n stop() {\n teardown();\n try {\n source.disconnect();\n node.disconnect();\n } catch {\n /* already disconnected */\n }\n for (const t of stream.getTracks()) t.stop();\n void ctx.close().catch(() => {});\n },\n };\n}\n","/** A tiny typed event emitter. `on` returns the unsubscribe. */\nexport class Emitter<Events extends Record<string, unknown>> {\n private handlers: { [K in keyof Events]?: Set<(payload: Events[K]) => void> } = {};\n\n on<K extends keyof Events>(event: K, fn: (payload: Events[K]) => void): () => void {\n (this.handlers[event] ??= new Set()).add(fn);\n return () => this.handlers[event]?.delete(fn);\n }\n\n emit<K extends keyof Events>(event: K, payload: Events[K]): void {\n for (const fn of this.handlers[event] ?? []) {\n try {\n fn(payload);\n } catch (e) {\n // A listener's bug must never break the SDK's own state machine.\n console.error('[characterxyz] listener threw', e);\n }\n }\n }\n\n clear(): void {\n this.handlers = {};\n }\n}\n","export type CxErrorCode =\n | 'unauthorized'\n | 'forbidden'\n | 'not_found'\n | 'invalid'\n | 'rate_limited'\n | 'payment_required'\n | 'unavailable'\n | 'network'\n | 'unknown';\n\n/** Every failure the SDK reports, with a message fit to show a visitor. */\nexport class CxError extends Error {\n readonly code: CxErrorCode;\n readonly status: number;\n\n constructor(code: CxErrorCode, message: string, status = 0) {\n super(message);\n this.name = 'CxError';\n this.code = code;\n this.status = status;\n }\n}\n\nexport function codeForStatus(status: number): CxErrorCode {\n switch (status) {\n case 401:\n return 'unauthorized';\n case 403:\n return 'forbidden';\n case 404:\n return 'not_found';\n case 402:\n return 'payment_required';\n case 422:\n return 'invalid';\n case 429:\n return 'rate_limited';\n case 503:\n return 'unavailable';\n default:\n return 'unknown';\n }\n}\n","import { CxError, codeForStatus } from './errors.js';\n\nexport interface RequestOptions {\n method?: string;\n body?: unknown;\n token?: string;\n signal?: AbortSignal;\n}\n\nasync function errorFrom(res: Response): Promise<CxError> {\n let message = '';\n try {\n const j = (await res.json()) as { message?: unknown };\n if (typeof j?.message === 'string') message = j.message;\n } catch {\n // not JSON: the status says enough\n }\n return new CxError(codeForStatus(res.status), message || `Request failed (${res.status})`, res.status);\n}\n\nexport async function send(apiUrl: string, path: string, opts: RequestOptions = {}): Promise<Response> {\n const headers: Record<string, string> = {};\n if (opts.body !== undefined) headers['Content-Type'] = 'application/json';\n if (opts.token) headers.Authorization = `Bearer ${opts.token}`;\n let res: Response;\n try {\n res = await fetch(apiUrl + path, {\n method: opts.method ?? (opts.body === undefined ? 'GET' : 'POST'),\n headers,\n body: opts.body === undefined ? undefined : JSON.stringify(opts.body),\n signal: opts.signal,\n // No cookies, ever: the SDK authenticates with its own bearer token, and\n // a credentialed request would carry the brand page's cookies to us.\n credentials: 'omit',\n cache: 'no-store',\n });\n } catch (e) {\n if ((e as Error)?.name === 'AbortError') throw e;\n throw new CxError('network', 'Could not reach Character XYZ. Check your connection.');\n }\n if (!res.ok) throw await errorFrom(res);\n return res;\n}\n\n/** JSON request; unwraps the API's `{message, data}` envelope. */\nexport async function request<T>(apiUrl: string, path: string, opts: RequestOptions = {}): Promise<T> {\n const res = await send(apiUrl, path, opts);\n const j = (await res.json()) as { data?: T };\n return j.data as T;\n}\n\nexport interface ServerEvent {\n event: string;\n data: unknown;\n}\n\n/**\n * Read a `text/event-stream` body, calling `onEvent` per event, until the\n * stream ends or `signal` aborts. Fetch-based on purpose: `EventSource` cannot\n * send an Authorization header, so it would need the token in the URL.\n */\nexport async function readEvents(res: Response, onEvent: (e: ServerEvent) => void, signal?: AbortSignal): Promise<void> {\n const body = res.body;\n if (!body) return;\n const reader = body.getReader();\n const decoder = new TextDecoder();\n let buf = '';\n const onAbort = () => void reader.cancel().catch(() => {});\n signal?.addEventListener('abort', onAbort);\n try {\n for (;;) {\n const { value, done } = await reader.read();\n if (done) break;\n buf += decoder.decode(value, { stream: true });\n buf = drain(buf, onEvent);\n }\n buf += decoder.decode();\n drain(buf + '\\n\\n', onEvent);\n } finally {\n signal?.removeEventListener('abort', onAbort);\n }\n}\n\n/** Dispatch every complete event in `buf`; return what is left over. */\nexport function drain(buf: string, onEvent: (e: ServerEvent) => void): string {\n const normalised = buf.replace(/\\r\\n/g, '\\n');\n let rest = normalised;\n let idx: number;\n while ((idx = rest.indexOf('\\n\\n')) !== -1) {\n const block = rest.slice(0, idx);\n rest = rest.slice(idx + 2);\n let event = 'message';\n const data: string[] = [];\n for (const line of block.split('\\n')) {\n if (!line || line.startsWith(':')) continue;\n const colon = line.indexOf(':');\n const field = colon === -1 ? line : line.slice(0, colon);\n const value = colon === -1 ? '' : line.slice(colon + 1).replace(/^ /, '');\n if (field === 'event') event = value;\n else if (field === 'data') data.push(value);\n }\n if (!data.length) continue;\n const raw = data.join('\\n');\n let parsed: unknown = raw;\n try {\n parsed = JSON.parse(raw);\n } catch {\n // plain text data\n }\n onEvent({ event, data: parsed });\n }\n return rest;\n}\n","/**\n * The agent socket's binary packet (the same one the Stage reads):\n *\n * \"CXYZ\" | version u8 (1) | kind u8 | flags u8 (bit 0 = final)\n * | corrLen u16 | corr utf8 | seq u32 | timestamp u64 | duration u32\n * | payloadLen u32 | payload\n *\n * All little-endian. Kind 1 is voice (PCM16), kind 2/3 are face data, which\n * this SDK does not draw yet.\n */\nexport interface Packet {\n kind: number;\n final: boolean;\n corr: string;\n payload: Uint8Array;\n}\n\nexport function parsePacket(buf: ArrayBuffer): Packet | null {\n if (buf.byteLength < 25) return null;\n const v = new DataView(buf);\n if (v.getUint8(0) !== 0x43 || v.getUint8(1) !== 0x58 || v.getUint8(2) !== 0x59 || v.getUint8(3) !== 0x5a) return null;\n if (v.getUint8(4) !== 1) return null;\n const kind = v.getUint8(5);\n const final = (v.getUint8(6) & 1) !== 0;\n let o = 7;\n const corrLen = v.getUint16(o, true);\n o += 2;\n if (o + corrLen + 20 > buf.byteLength) return null;\n const corr = new TextDecoder().decode(new Uint8Array(buf, o, corrLen));\n o += corrLen + 4 + 8 + 4;\n const len = v.getUint32(o, true);\n o += 4;\n if (o + len > buf.byteLength) return null;\n return { kind, final, corr, payload: new Uint8Array(buf, o, len) };\n}\n\n/** Build one (for tests and tools). */\nexport function buildPacket(p: { kind: number; final: boolean; corr: string; payload: Uint8Array }): ArrayBuffer {\n const corr = new TextEncoder().encode(p.corr);\n const head = 7 + 2 + corr.length + 4 + 8 + 4 + 4;\n const buf = new ArrayBuffer(head + p.payload.byteLength);\n const v = new DataView(buf);\n const bytes = new Uint8Array(buf);\n bytes.set([0x43, 0x58, 0x59, 0x5a], 0);\n v.setUint8(4, 1);\n v.setUint8(5, p.kind);\n v.setUint8(6, p.final ? 1 : 0);\n let o = 7;\n v.setUint16(o, corr.length, true);\n o += 2;\n bytes.set(corr, o);\n o += corr.length + 4 + 8 + 4;\n v.setUint32(o, p.payload.byteLength, true);\n o += 4;\n bytes.set(p.payload, o);\n return buf;\n}\n","import { audioContext, PcmPlayer } from './audio/player.js';\nimport { openMic, type Mic } from './audio/mic.js';\nimport { Emitter } from './emitter.js';\nimport { CxError } from './errors.js';\nimport { readEvents, request, send } from './http.js';\nimport { parsePacket } from './protocol.js';\nimport type { SessionManager } from './session.js';\nimport type { CallEndReason, CallState, Caption } from './types.js';\n\nexport interface CallEvents extends Record<string, unknown> {\n state: CallState;\n /** The visitor's words and the agent's reply, as they are recognised. */\n caption: Caption;\n /** A caption the server withdrew (the visitor was not finished). */\n captionRemoved: string;\n /** The turn is ready: accept() within `holdSeconds`. */\n ready: { holdSeconds: number };\n /** One streamed face batch (kind-3 msgpack payload) for line `corr` — only with `face`. */\n face: { corr: string; payload: Uint8Array };\n /** A line of the agent's voice became audible, or ended (naturally or interrupted). */\n line: { corr: string; event: 'audible' | 'end' };\n error: CxError;\n}\n\nexport interface CallOptions {\n /** Join the moment it is this visitor's turn (default true). */\n autoAccept?: boolean;\n deviceId?: string;\n /**\n * Ask for the agent's face streamed with the voice (Neural Lip Sync), for a\n * UI that draws it. `emotion()` is read when the call connects: the face's\n * mood as the face service takes it (`joy:0.3`), or null for neutral.\n */\n face?: { emotion?: () => string | null };\n}\n\n/** Talking over the agent this loud, this long, stops her. */\nconst BARGE_IN_LEVEL = 0.09;\nconst BARGE_IN_MS = 350;\nconst HEARTBEAT_MS = 25_000;\n\nconst initial = (): CallState => ({\n phase: 'idle',\n callId: null,\n position: null,\n etaSeconds: null,\n holdSeconds: null,\n maxSeconds: null,\n startedAt: null,\n endReason: null,\n muted: false,\n speaking: false,\n agentState: 'idle',\n error: null,\n});\n\n/**\n * One voice call: join the line, wait (chatting is fine meanwhile), accept,\n * talk, hang up. A call is single-use; start another for the next one.\n */\nexport class Call extends Emitter<CallEvents> {\n private s: CallState = initial();\n private ticket: string | null = null;\n private eventsAbort: AbortController | null = null;\n private ws: WebSocket | null = null;\n private mic: Mic | null = null;\n private players = new Map<string, PcmPlayer>();\n private sampleRates = new Map<string, number>();\n private cancelled = new Set<string>();\n private speakingCorr: string | null = null;\n private heartbeat: ReturnType<typeof setInterval> | null = null;\n private loudSince: number | null = null;\n\n constructor(\n private readonly apiUrl: string,\n private readonly session: SessionManager,\n private readonly agentId: string,\n private readonly opts: CallOptions = {},\n ) {\n super();\n }\n\n get state(): CallState {\n return this.s;\n }\n\n /** The line being voiced now, and how much of it has been heard (ms). */\n audible(): { corr: string; ms: number } | null {\n const corr = this.speakingCorr;\n const p = corr ? this.players.get(corr) : undefined;\n return corr && p ? { corr, ms: p.playedMs() } : null;\n }\n\n /** Loudness of the agent's voice right now, 0..1. */\n voiceLevel(): number {\n const p = this.speakingCorr ? this.players.get(this.speakingCorr) : undefined;\n return p ? p.level() : 0;\n }\n\n private set(patch: Partial<CallState>) {\n this.s = { ...this.s, ...patch };\n this.emit('state', this.s);\n }\n\n /**\n * Call from a click: it unlocks audio, asks for the microphone, then joins\n * the line (or goes straight through when a slot is free).\n */\n async start(): Promise<void> {\n if (this.s.phase !== 'idle') return;\n this.set({ phase: 'joining' });\n // Created inside the gesture, or the browser keeps it suspended.\n audioContext();\n try {\n this.mic = await openMic({ deviceId: this.opts.deviceId, onFrame: (pcm, level) => this.onMicFrame(pcm, level) });\n } catch {\n this.finish('mic-denied', 'Allow the microphone to talk, or chat instead.');\n return;\n }\n try {\n const token = await this.session.token();\n const r = await request<{ callId: string; state: string; position?: number; etaSeconds?: number }>(this.apiUrl, '/sdk/v1/calls', {\n method: 'POST',\n body: {},\n token,\n });\n this.set({ callId: r.callId, phase: r.state === 'ready' ? 'joining' : 'queued', position: r.position ?? null, etaSeconds: r.etaSeconds ?? null });\n void this.follow();\n } catch (e) {\n const err = e instanceof CxError ? e : new CxError('unknown', 'Could not start the call.');\n const reason: CallEndReason = err.code === 'rate_limited' ? 'busy' : 'unavailable';\n this.finish(reason, err.message);\n this.emit('error', err);\n }\n }\n\n /** Follow the call's server-side state, reconnecting the stream if it drops. */\n private async follow(): Promise<void> {\n let failures = 0;\n while (this.s.callId && this.s.phase !== 'ended' && this.s.phase !== 'idle') {\n this.eventsAbort = new AbortController();\n try {\n const token = await this.session.token();\n const res = await send(this.apiUrl, `/sdk/v1/calls/${encodeURIComponent(this.s.callId)}/events`, { token, signal: this.eventsAbort.signal });\n failures = 0;\n await readEvents(res, (e) => this.onServerEvent(e.event, e.data as Record<string, unknown>), this.eventsAbort.signal);\n } catch (e) {\n if ((e as Error)?.name === 'AbortError') return;\n if (e instanceof CxError && e.code === 'not_found') {\n this.finish('failed', 'The call ended.');\n return;\n }\n failures += 1;\n if (failures > 5) {\n this.finish('failed', 'Lost the connection to the call.');\n return;\n }\n }\n if (this.ended()) return;\n await new Promise((r) => setTimeout(r, Math.min(4000, 500 * 2 ** failures)));\n }\n }\n\n private onServerEvent(event: string, d: Record<string, unknown>) {\n switch (event) {\n case 'queued':\n if (this.s.phase === 'joining' || this.s.phase === 'queued') {\n this.set({ phase: 'queued', position: Number(d.position) || 1, etaSeconds: Number(d.etaSeconds) || null });\n }\n break;\n case 'ready': {\n if (typeof d.ticket === 'string' && d.ticket) this.ticket = d.ticket;\n const hold = Number(d.holdSeconds) || 0;\n if (this.s.phase !== 'ready' && this.s.phase !== 'connecting' && this.s.phase !== 'live') {\n this.set({ phase: 'ready', holdSeconds: hold, position: null, etaSeconds: null });\n this.emit('ready', { holdSeconds: hold });\n if (this.opts.autoAccept !== false) this.accept();\n } else if (this.s.phase === 'ready') {\n this.set({ holdSeconds: hold });\n }\n break;\n }\n case 'live':\n this.set({ phase: 'live', maxSeconds: Number(d.maxSeconds) || null, startedAt: this.s.startedAt ?? Date.now() - (Number(d.elapsedSeconds) || 0) * 1000 });\n break;\n case 'ended':\n this.finish((String(d.reason || 'hangup') as CallEndReason) || 'hangup', null);\n break;\n }\n }\n\n // A method, not an inline comparison: the phase changes across an await,\n // which TypeScript's narrowing cannot see.\n private ended(): boolean {\n return this.s.phase === 'ended';\n }\n\n /** Take the call now that it is this visitor's turn. */\n accept(): void {\n if (this.s.phase !== 'ready' || !this.ticket || this.ws) return;\n this.set({ phase: 'connecting' });\n const url = this.apiUrl.replace(/^http/, 'ws') + '/sdk/v1/calls/socket';\n const ws = new WebSocket(url, [`cxyz-ticket.${this.ticket}`]);\n this.ticket = null;\n ws.binaryType = 'arraybuffer';\n this.ws = ws;\n ws.onopen = () => {\n const face = this.opts.face;\n const emotion = face?.emotion?.() ?? null;\n ws.send(\n JSON.stringify({\n type: 'agent_identity',\n agent_id: this.agentId,\n skin_index: 0,\n blendshapes: !!face,\n ...(face ? { blendshape_stream: true } : {}),\n ...(face && emotion ? { face_emotion: emotion } : {}),\n }),\n );\n // This page does not gate the microphone: the server's own voice\n // detection judges every frame.\n ws.send(JSON.stringify({ type: 'mic_state', silero: 'off', denoise: false }));\n this.heartbeat = setInterval(() => this.sendJson({ type: 'heartbeat' }), HEARTBEAT_MS);\n this.set({ phase: 'live', startedAt: this.s.startedAt ?? Date.now() });\n };\n ws.onmessage = (e) => this.onSocket(e.data);\n ws.onclose = () => {\n this.ws = null;\n // The event stream says why; give it a moment before calling it ourselves.\n setTimeout(() => {\n if (this.s.phase === 'live' || this.s.phase === 'connecting') this.finish('hangup', null);\n }, 1500);\n };\n }\n\n private sendJson(o: unknown) {\n if (this.ws?.readyState === WebSocket.OPEN) this.ws.send(JSON.stringify(o));\n }\n\n private onMicFrame(pcm: ArrayBuffer, level: number) {\n const ws = this.ws;\n if (!ws || ws.readyState !== WebSocket.OPEN) return;\n if (this.speakingCorr) {\n // The agent must not hear itself: while she talks the frames go up as\n // silence, unless the visitor is clearly talking over her.\n const now = performance.now();\n if (level > BARGE_IN_LEVEL) {\n this.loudSince ??= now;\n if (now - this.loudSince >= BARGE_IN_MS) {\n this.loudSince = null;\n this.interrupt();\n ws.send(pcm);\n return;\n }\n } else {\n this.loudSince = null;\n }\n ws.send(new ArrayBuffer(pcm.byteLength));\n return;\n }\n ws.send(pcm);\n }\n\n private onSocket(data: unknown) {\n if (data instanceof ArrayBuffer) {\n const p = parsePacket(data);\n if (!p || this.cancelled.has(p.corr)) return;\n if (p.kind === 3) {\n // A copy, so the receiver may keep or transfer it.\n if (this.opts.face) this.emit('face', { corr: p.corr, payload: p.payload.slice() });\n return;\n }\n if (p.kind !== 1) return;\n let player = this.players.get(p.corr);\n if (!player) {\n // A new line: whatever was playing is over.\n for (const [c, old] of this.players) {\n old.stop();\n this.players.delete(c);\n }\n const corr = p.corr;\n player = new PcmPlayer({\n sampleRate: this.sampleRates.get(corr) ?? 16_000,\n onStart: () => {\n this.speakingCorr = corr;\n this.set({ speaking: true });\n this.emit('line', { corr, event: 'audible' });\n this.sendJson({ type: 'playback_started', correlationId: corr, timestampMs: Date.now() });\n },\n onEnd: () => {\n this.players.delete(corr);\n if (this.speakingCorr === corr) this.speakingCorr = null;\n this.set({ speaking: false });\n this.emit('line', { corr, event: 'end' });\n this.sendJson({ type: 'playback_ended', correlationId: corr, timestampMs: Date.now(), reason: 'natural' });\n this.sendJson({ type: 'speech_ended' });\n },\n });\n this.players.set(corr, player);\n }\n player.enqueue(p.payload);\n if (p.final) player.end();\n return;\n }\n if (typeof data !== 'string') return;\n let o: Record<string, unknown>;\n try {\n o = JSON.parse(data);\n } catch {\n return;\n }\n if ('AgentSpeechMeta' in o) {\n const m = o.AgentSpeechMeta as { correlation_id?: string; sample_rate?: number };\n if (m?.correlation_id && m.sample_rate) this.sampleRates.set(m.correlation_id, m.sample_rate);\n return;\n }\n if ('InteractorTranscript' in o) {\n const t = o.InteractorTranscript as { correlation_id: string; text: string };\n if (t?.text) this.emit('caption', { id: `v:${t.correlation_id}`, role: 'visitor', text: t.text });\n return;\n }\n if ('AgentReplyTranscript' in o) {\n const t = o.AgentReplyTranscript as { correlation_id: string; text: string };\n if (t?.text && !this.cancelled.has(t.correlation_id)) this.emit('caption', { id: `a:${t.correlation_id}`, role: 'agent', text: t.text });\n return;\n }\n if (o.type === 'turn_cancelled' && typeof o.correlationId === 'string') {\n const cid = o.correlationId;\n this.cancelled.add(cid);\n this.players.get(cid)?.stop();\n this.players.delete(cid);\n this.emit('line', { corr: cid, event: 'end' });\n if (this.speakingCorr === cid) {\n this.speakingCorr = null;\n this.set({ speaking: false });\n }\n this.emit('captionRemoved', `a:${cid}`);\n return;\n }\n if (o.kind === 'agent_status' && typeof o.state === 'string') {\n this.set({ agentState: o.state.toLowerCase() });\n }\n }\n\n /** Stop the agent mid-sentence (the visitor wants to speak). */\n interrupt(): void {\n const corr = this.speakingCorr;\n if (!corr) return;\n const p = this.players.get(corr);\n const heardMs = Math.round(p?.playedMs() ?? 0);\n p?.stop();\n this.players.delete(corr);\n this.cancelled.add(corr);\n this.speakingCorr = null;\n this.set({ speaking: false });\n this.emit('line', { corr, event: 'end' });\n this.sendJson({ type: 'playback_ended', correlationId: corr, timestampMs: Date.now(), reason: 'interrupted' });\n this.sendJson({ type: 'interrupt', correlationId: corr, heardMs, timestampMs: Date.now() });\n }\n\n setMuted(muted: boolean): void {\n this.mic?.setMuted(muted);\n this.set({ muted });\n }\n\n /** Leave the line, or hang up. */\n async hangUp(): Promise<void> {\n const id = this.s.callId;\n const was = this.s.phase;\n this.finish(was === 'live' ? 'hangup' : 'left', null);\n if (!id) return;\n try {\n const token = await this.session.token();\n await send(this.apiUrl, `/sdk/v1/calls/${encodeURIComponent(id)}`, { method: 'DELETE', token });\n } catch {\n // The server notices a closed socket / abandoned line on its own.\n }\n }\n\n private finish(reason: CallEndReason, error: string | null) {\n if (this.s.phase === 'ended') return;\n this.eventsAbort?.abort();\n this.eventsAbort = null;\n if (this.heartbeat) clearInterval(this.heartbeat);\n this.heartbeat = null;\n for (const p of this.players.values()) p.stop();\n this.players.clear();\n this.speakingCorr = null;\n this.mic?.stop();\n this.mic = null;\n const ws = this.ws;\n this.ws = null;\n if (ws && ws.readyState <= WebSocket.OPEN) ws.close(1000);\n this.ticket = null;\n this.set({ phase: 'ended', endReason: reason, speaking: false, holdSeconds: null, error });\n }\n}\n","import { Emitter } from './emitter.js';\nimport { CxError } from './errors.js';\nimport { readEvents, request, send } from './http.js';\nimport type { SessionManager } from './session.js';\nimport type { ChatMessage } from './types.js';\n\nexport interface ChatEvents extends Record<string, unknown> {\n /** The whole list, after any change. */\n messages: ChatMessage[];\n /** True from send until the reply is complete. */\n busy: boolean;\n error: CxError;\n}\n\nlet localSeq = 0;\nconst localId = (p: string) => `${p}_${Date.now().toString(36)}_${(localSeq++).toString(36)}`;\n\n/**\n * Text chat with the agent. History lives on the server, so it follows the\n * visitor across page loads (and, for an identified visitor, devices).\n */\nexport class Chat extends Emitter<ChatEvents> {\n private list: ChatMessage[] = [];\n private loaded = false;\n private busy = false;\n private abort: AbortController | null = null;\n\n constructor(\n private readonly apiUrl: string,\n private readonly session: SessionManager,\n ) {\n super();\n }\n\n get messages(): readonly ChatMessage[] {\n return this.list;\n }\n\n get isBusy(): boolean {\n return this.busy;\n }\n\n private publish() {\n this.list = [...this.list];\n this.emit('messages', this.list);\n }\n\n /** Load earlier messages (once; later calls return what is held). */\n async load(): Promise<readonly ChatMessage[]> {\n if (this.loaded) return this.list;\n const token = await this.session.token();\n const res = await request<{ messages: ChatMessage[] }>(this.apiUrl, '/sdk/v1/chat/messages?limit=50', { token });\n // Anything sent while the history was loading stays after it.\n const pending = this.list;\n this.list = [...(res?.messages ?? []), ...pending];\n this.loaded = true;\n this.publish();\n return this.list;\n }\n\n /**\n * Send a message; the reply streams into `messages` as it is written.\n * Resolves with the finished reply.\n */\n async send(text: string): Promise<ChatMessage> {\n const t = text.trim();\n if (!t) throw new CxError('invalid', 'Say something first.');\n if (this.busy) throw new CxError('rate_limited', 'Wait for the reply first.');\n this.setBusy(true);\n const mine: ChatMessage = { id: localId('local'), role: 'visitor', text: t, createdAt: new Date().toISOString() };\n const reply: ChatMessage = { id: localId('reply'), role: 'agent', text: '', createdAt: new Date().toISOString(), streaming: true };\n this.list.push(mine, reply);\n this.publish();\n\n this.abort = new AbortController();\n try {\n const token = await this.session.token();\n const res = await send(this.apiUrl, '/sdk/v1/chat/messages', { method: 'POST', body: { text: t }, token, signal: this.abort.signal });\n let finished: ChatMessage | null = null;\n let failure: string | null = null;\n await readEvents(\n res,\n ({ event, data }) => {\n const d = data as Record<string, unknown>;\n if (event === 'delta' && typeof d?.text === 'string') {\n reply.text += d.text;\n this.publish();\n } else if (event === 'done') {\n const next = Array.isArray(d.suggestions) ? d.suggestions.filter((q): q is string => typeof q === 'string' && q.trim() !== '') : [];\n finished = {\n id: String(d.id),\n role: 'agent',\n text: String(d.text ?? reply.text),\n createdAt: String(d.createdAt ?? reply.createdAt),\n ...(next.length ? { suggestions: next } : {}),\n };\n } else if (event === 'error') {\n failure = typeof d?.message === 'string' ? d.message : 'Something went wrong.';\n }\n },\n this.abort.signal,\n );\n if (failure || !finished) throw new CxError('unknown', failure ?? 'The reply was cut off. Try again.');\n const done: ChatMessage = finished;\n this.replace(reply.id, done);\n return done;\n } catch (e) {\n const err = e instanceof CxError ? e : new CxError('network', 'The reply was cut off. Try again.');\n this.list = this.list.filter((m) => m.id !== reply.id);\n const idx = this.list.findIndex((m) => m.id === mine.id);\n // A refusal the server explained (a daily limit, a slow-down) is shown as\n // it was said; anything else is the generic \"not sent\".\n if (idx !== -1) this.list[idx] = { ...mine, failed: true, ...(err.status === 429 ? { error: err.message } : {}) };\n this.publish();\n if ((e as Error)?.name !== 'AbortError') this.emit('error', err);\n throw err;\n } finally {\n this.abort = null;\n this.setBusy(false);\n }\n }\n\n /** Send a failed message again. */\n retry(id: string): Promise<ChatMessage> {\n const m = this.list.find((x) => x.id === id && x.failed);\n if (!m) throw new CxError('not_found', 'Nothing to retry.');\n this.list = this.list.filter((x) => x.id !== id);\n this.publish();\n return this.send(m.text);\n }\n\n /** Stop listening to a reply in progress (the server still finishes it). */\n stop(): void {\n this.abort?.abort();\n }\n\n private replace(id: string, next: ChatMessage) {\n const i = this.list.findIndex((m) => m.id === id);\n if (i !== -1) this.list[i] = next;\n this.publish();\n }\n\n private setBusy(b: boolean) {\n this.busy = b;\n this.emit('busy', b);\n }\n}\n","import { CxError } from './errors.js';\nimport { request } from './http.js';\nimport type { SessionInfo } from './types.js';\n\n/** Where the SDK may remember this browser's anonymous visitor id. */\nexport interface VisitorStore {\n get(key: string): string | null;\n set(key: string, value: string): void;\n}\n\nexport const memoryStore = (): VisitorStore => {\n const m = new Map<string, string>();\n return { get: (k) => m.get(k) ?? null, set: (k, v) => void m.set(k, v) };\n};\n\nexport const localStore = (): VisitorStore => ({\n get(k) {\n try {\n return globalThis.localStorage?.getItem(k) ?? null;\n } catch {\n return null;\n }\n },\n set(k, v) {\n try {\n globalThis.localStorage?.setItem(k, v);\n } catch {\n // private mode / blocked storage: the visitor is simply new each time\n }\n },\n});\n\nexport interface SessionSource {\n apiUrl: string;\n agentId?: string;\n /** Browser path: a publishable key, exchanged from this page's origin. */\n publishableKey?: string;\n /**\n * Server path: your backend mints the session with a secret key (an\n * identified visitor) and hands the token to the page. Called again when\n * the session is about to run out.\n */\n getSessionToken?: () => Promise<string | SessionInfo>;\n store: VisitorStore;\n}\n\n/** Renew this long before expiry. */\nconst RENEW_EARLY_S = 60;\n\n/**\n * Holds the current session, renews it before it runs out, and never runs\n * two renewals at once.\n */\nexport class SessionManager {\n private current: SessionInfo | null = null;\n private inflight: Promise<SessionInfo> | null = null;\n\n constructor(private readonly src: SessionSource) {\n if (!src.publishableKey && !src.getSessionToken) {\n throw new CxError('invalid', 'Pass a publishableKey, or getSessionToken for sessions your server mints.');\n }\n }\n\n private visitorKey(): string {\n // Per key, so two brands on one domain never share a visitor.\n const k = this.src.publishableKey ?? 'server';\n return `cxyz:visitor:${k.slice(-12)}`;\n }\n\n get info(): SessionInfo | null {\n return this.current;\n }\n\n /** A token valid for at least the next minute. */\n async token(): Promise<string> {\n const now = Date.now() / 1000;\n if (this.current && this.current.expiresAt - RENEW_EARLY_S > now) return this.current.token;\n return (await this.refresh()).token;\n }\n\n refresh(): Promise<SessionInfo> {\n this.inflight ??= this.mint().finally(() => {\n this.inflight = null;\n });\n return this.inflight;\n }\n\n private async mint(): Promise<SessionInfo> {\n let info: SessionInfo;\n if (this.src.getSessionToken) {\n const got = await this.src.getSessionToken();\n if (typeof got === 'string') {\n // A bare token: ask the server what it unlocks.\n info = await this.describe(got);\n } else {\n info = got;\n }\n } else {\n const visitorId = this.src.store.get(this.visitorKey()) ?? undefined;\n info = await request<SessionInfo>(this.src.apiUrl, '/sdk/v1/sessions', {\n method: 'POST',\n body: { publishableKey: this.src.publishableKey, agentId: this.src.agentId, visitorId },\n });\n this.src.store.set(this.visitorKey(), info.visitorId);\n }\n this.current = info;\n return info;\n }\n\n /** The session behind a token minted elsewhere (`getSessionToken` returned a string). */\n private async describe(token: string): Promise<SessionInfo> {\n const info = await request<SessionInfo>(this.src.apiUrl, '/sdk/v1/session', { token });\n return { ...info, token };\n }\n}\n","import { Call, type CallOptions } from './call.js';\nimport { Chat } from './chat.js';\nimport { Emitter } from './emitter.js';\nimport { CxError } from './errors.js';\nimport { request } from './http.js';\nimport { localStore, memoryStore, SessionManager, type VisitorStore } from './session.js';\nimport type { AgentCard, Features, Opening, SessionInfo } from './types.js';\n\nexport const DEFAULT_API_URL = 'https://api.character.xyz';\n\nexport interface InitOptions {\n /** `cxyz_pk_live_…` — safe in the page; works only from the key's allowed sites. */\n publishableKey?: string;\n /**\n * For signed-in visitors: return a session your server minted with its\n * secret key (see `@characterxyz/server`). Called again before expiry.\n */\n getSessionToken?: () => Promise<string | SessionInfo>;\n /** Which of the key's agents to talk to. Defaults to the key's first. */\n agentId?: string;\n /** Override the API (staging, local development). */\n apiUrl?: string;\n /** Remember the anonymous visitor across visits (default) or not at all. */\n storage?: 'local' | 'memory' | VisitorStore;\n}\n\nexport interface ClientEvents extends Record<string, unknown> {\n /** A call started or ended; the widget swaps its view on this. */\n call: Call | null;\n error: CxError;\n}\n\n/**\n * The headless SDK. `await CharacterXYZ.init({ publishableKey })`, then use\n * `chat` and `startCall()`. Everything the widget does goes through here, so\n * a brand can build its own UI on the same calls.\n */\nexport class CharacterXYZ extends Emitter<ClientEvents> {\n readonly chat: Chat;\n private currentCall: Call | null = null;\n private destroyed = false;\n\n private constructor(\n readonly apiUrl: string,\n private readonly session: SessionManager,\n private info: SessionInfo,\n ) {\n super();\n this.chat = new Chat(apiUrl, session);\n }\n\n static async init(opts: InitOptions): Promise<CharacterXYZ> {\n const apiUrl = (opts.apiUrl ?? DEFAULT_API_URL).replace(/\\/+$/, '');\n if (opts.publishableKey && /^cxyz_sk_/.test(opts.publishableKey)) {\n // A secret key in a page is a leak. Refuse loudly, before it is sent anywhere.\n throw new CxError('invalid', 'That is a SECRET key. Never put it in a web page: use a publishable key (cxyz_pk_…). Revoke the secret key now.');\n }\n const store = opts.storage === 'memory' ? memoryStore() : opts.storage && typeof opts.storage === 'object' ? opts.storage : localStore();\n const session = new SessionManager({ apiUrl, agentId: opts.agentId, publishableKey: opts.publishableKey, getSessionToken: opts.getSessionToken, store });\n const info = await session.refresh();\n return new CharacterXYZ(apiUrl, session, info);\n }\n\n get agent(): AgentCard {\n return (this.session.info ?? this.info).agent;\n }\n\n get features(): Features {\n return (this.session.info ?? this.info).features;\n }\n\n get appearance(): Record<string, unknown> {\n return (this.session.info ?? this.info).appearance ?? {};\n }\n\n get visitorId(): string {\n return (this.session.info ?? this.info).visitorId;\n }\n\n get mode(): 'live' | 'test' {\n return (this.session.info ?? this.info).mode;\n }\n\n /** The call in progress (queued, ready or live), if any. */\n get call(): Call | null {\n return this.currentCall && this.currentCall.state.phase !== 'ended' ? this.currentCall : null;\n }\n\n /**\n * The worn video character's full render data (the public projection the\n * app's Stage reads), for a UI that draws the face — the widget hands it to\n * the app's renderer. Null when the agent wears none.\n */\n async videoAvatar(): Promise<Record<string, unknown> | null> {\n const token = await this.session.token();\n return request<Record<string, unknown> | null>(this.apiUrl, '/sdk/v1/agent/video-avatar', { token });\n }\n\n private openingP: Promise<Opening | null> | null = null;\n\n /**\n * How the agent opens the conversation here — her greeting, a welcome-back\n * line, a teaser and likely first questions — written by her and cached by\n * the server. Fetched once per page; null if it could not be had.\n */\n opening(): Promise<Opening | null> {\n this.openingP ??= this.session\n .token()\n .then((token) => request<Opening>(this.apiUrl, '/sdk/v1/agent/opening', { token }))\n .catch(() => null);\n return this.openingP;\n }\n\n /** Start a voice call. Call from a click: it needs the microphone and audio unlocked. */\n async startCall(opts: CallOptions = {}): Promise<Call> {\n if (this.destroyed) throw new CxError('invalid', 'This client was destroyed.');\n if (!this.features.call) throw new CxError('forbidden', 'Calls are not available on this site.');\n if (this.call) return this.call;\n const call = new Call(this.apiUrl, this.session, this.agent.id, opts);\n this.currentCall = call;\n call.on('state', (s) => {\n if (s.phase === 'ended' && this.currentCall === call) this.emit('call', null);\n });\n call.on('error', (e) => this.emit('error', e));\n this.emit('call', call);\n await call.start();\n return call;\n }\n\n destroy(): void {\n this.destroyed = true;\n void this.currentCall?.hangUp();\n this.chat.stop();\n this.chat.clear();\n this.clear();\n }\n}\n","/**\n * `@characterxyz/web` — Character XYZ on any web page, headless.\n *\n * ```ts\n * import { CharacterXYZ } from '@characterxyz/web';\n *\n * const cx = await CharacterXYZ.init({ publishableKey: 'cxyz_pk_live_…' });\n * cx.chat.on('messages', render);\n * await cx.chat.send('Hi!');\n *\n * button.onclick = async () => {\n * const call = await cx.startCall();\n * call.on('state', (s) => show(s.phase, s.position));\n * };\n * ```\n *\n * The ready-made widget is `@characterxyz/widget`; this package is what it\n * is built on, for brands who want their own UI.\n */\nexport { CharacterXYZ, DEFAULT_API_URL, type InitOptions, type ClientEvents } from './client.js';\nexport { Chat, type ChatEvents } from './chat.js';\nexport { Call, type CallEvents, type CallOptions } from './call.js';\nexport { CxError, type CxErrorCode } from './errors.js';\nexport { Emitter } from './emitter.js';\nexport type { VisitorStore } from './session.js';\nexport type {\n AgentCard,\n CallEndReason,\n CallPhase,\n CallState,\n Caption,\n ChatMessage,\n Features,\n Opening,\n SessionInfo,\n VideoCharacter,\n VideoClip,\n} from './types.js';\nexport const VERSION = '0.2.0';\n"]}
|
package/package.json
CHANGED