synxed-sdk 0.3.0 → 0.3.4

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.mts CHANGED
@@ -269,48 +269,24 @@ interface VoiceCaptureEvents {
269
269
  speechEnd: () => void;
270
270
  }
271
271
  interface VoiceCaptureOptions {
272
- /** Safety cap — auto `speechEnd` after this many ms. Default `30000`. */
273
272
  maxDurationMs?: number;
274
- /**
275
- * Base URL where `@ricky0123/vad-web` model / worklet assets are served.
276
- * Defaults to the jsDelivr CDN.
277
- */
278
273
  vadBaseAssetPath?: string;
279
- /**
280
- * Base URL where ONNX Runtime WASM binaries are served.
281
- * Defaults to the jsDelivr CDN.
282
- */
283
274
  onnxWasmBasePath?: string;
284
275
  }
285
276
  /**
286
- * Captures microphone audio and buffers it locally. Once the user is finished
287
- * talking (detected via Silero VAD), the complete audio file is emitted to the
288
- * backend as a single chunk, followed by the stream termination.
277
+ * Captures microphone audio using Silero VAD natively.
278
+ * Waits for the user to finish talking, then emits the complete audio segment.
289
279
  */
290
280
  declare class VoiceCaptureManager extends EventEmitter<VoiceCaptureEvents> {
291
- private stream;
292
- private audioContext;
293
- private mediaStreamSource;
294
- private processor;
295
- private muteNode;
296
- private sequence;
297
281
  private capturing;
298
282
  private mimeType;
299
283
  private micVad;
300
284
  private speechEndEmitted;
301
285
  get isCapturing(): boolean;
302
- get activeMimeType(): string;
303
- /**
304
- * Silently pre-fetches the VAD WebAssembly and Neural Network weights from the CDN
305
- * so that they are instantly available when the user presses the microphone.
306
- */
307
286
  preloadModels(options?: VoiceCaptureOptions): Promise<void>;
308
287
  start(options?: VoiceCaptureOptions): Promise<string>;
309
288
  stop(): Promise<void>;
310
289
  cancel(): void;
311
- private startVadMonitor;
312
- private teardownVad;
313
- private releaseStream;
314
290
  }
315
291
 
316
292
  type SynxedWebPlayerMode = "mini" | "wide" | "large";
@@ -360,6 +336,8 @@ interface SynxedWebPlayerOptions {
360
336
  /** Ms to hold before voice starts (prevents opening AI on quick tap). Default `450`. */
361
337
  voiceHoldMs?: number;
362
338
  listenerId?: string;
339
+ debug?: boolean;
340
+ voice?: VoiceHoldOptions;
363
341
  }
364
342
 
365
343
  /**
package/dist/index.d.ts CHANGED
@@ -269,48 +269,24 @@ interface VoiceCaptureEvents {
269
269
  speechEnd: () => void;
270
270
  }
271
271
  interface VoiceCaptureOptions {
272
- /** Safety cap — auto `speechEnd` after this many ms. Default `30000`. */
273
272
  maxDurationMs?: number;
274
- /**
275
- * Base URL where `@ricky0123/vad-web` model / worklet assets are served.
276
- * Defaults to the jsDelivr CDN.
277
- */
278
273
  vadBaseAssetPath?: string;
279
- /**
280
- * Base URL where ONNX Runtime WASM binaries are served.
281
- * Defaults to the jsDelivr CDN.
282
- */
283
274
  onnxWasmBasePath?: string;
284
275
  }
285
276
  /**
286
- * Captures microphone audio and buffers it locally. Once the user is finished
287
- * talking (detected via Silero VAD), the complete audio file is emitted to the
288
- * backend as a single chunk, followed by the stream termination.
277
+ * Captures microphone audio using Silero VAD natively.
278
+ * Waits for the user to finish talking, then emits the complete audio segment.
289
279
  */
290
280
  declare class VoiceCaptureManager extends EventEmitter<VoiceCaptureEvents> {
291
- private stream;
292
- private audioContext;
293
- private mediaStreamSource;
294
- private processor;
295
- private muteNode;
296
- private sequence;
297
281
  private capturing;
298
282
  private mimeType;
299
283
  private micVad;
300
284
  private speechEndEmitted;
301
285
  get isCapturing(): boolean;
302
- get activeMimeType(): string;
303
- /**
304
- * Silently pre-fetches the VAD WebAssembly and Neural Network weights from the CDN
305
- * so that they are instantly available when the user presses the microphone.
306
- */
307
286
  preloadModels(options?: VoiceCaptureOptions): Promise<void>;
308
287
  start(options?: VoiceCaptureOptions): Promise<string>;
309
288
  stop(): Promise<void>;
310
289
  cancel(): void;
311
- private startVadMonitor;
312
- private teardownVad;
313
- private releaseStream;
314
290
  }
315
291
 
316
292
  type SynxedWebPlayerMode = "mini" | "wide" | "large";
@@ -360,6 +336,8 @@ interface SynxedWebPlayerOptions {
360
336
  /** Ms to hold before voice starts (prevents opening AI on quick tap). Default `450`. */
361
337
  voiceHoldMs?: number;
362
338
  listenerId?: string;
339
+ debug?: boolean;
340
+ voice?: VoiceHoldOptions;
363
341
  }
364
342
 
365
343
  /**
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- 'use strict';var z=require('protobufjs'),howler=require('howler');function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var z__namespace=/*#__PURE__*/_interopNamespace(z);var ht=`
1
+ 'use strict';var j=require('protobufjs'),howler=require('howler');function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var j__namespace=/*#__PURE__*/_interopNamespace(j);var ft=`
2
2
  syntax = "proto3";
3
3
 
4
4
  enum ContentKind {
@@ -132,38 +132,12 @@ message SdkServerEnvelope {
132
132
  SdkServerVoiceAudio voiceAudio = 5;
133
133
  }
134
134
  }
135
- `,q=z__namespace.parse(ht).root,M=q.lookupType("SdkClientEnvelope"),U=q.lookupType("SdkServerEnvelope"),I=(r=>(r[r.UNSPECIFIED=0]="UNSPECIFIED",r[r.SONG=1]="SONG",r[r.PLAYLIST=2]="PLAYLIST",r[r.CATEGORY=3]="CATEGORY",r[r.RADIO=4]="RADIO",r[r.VOICE=5]="VOICE",r))(I||{}),D=(n=>(n[n.VOICE_UNSPECIFIED=0]="VOICE_UNSPECIFIED",n[n.VOICE_START=1]="VOICE_START",n[n.VOICE_CHUNK=2]="VOICE_CHUNK",n[n.VOICE_END=3]="VOICE_END",n))(D||{}),j=(a=>(a[a.UNSPECIFIED=0]="UNSPECIFIED",a[a.UNAUTHORIZED=1]="UNAUTHORIZED",a[a.VALIDATION_ERROR=2]="VALIDATION_ERROR",a[a.NOT_FOUND=3]="NOT_FOUND",a[a.PROCESSING=4]="PROCESSING",a[a.SERVICE_UNAVAILABLE=5]="SERVICE_UNAVAILABLE",a[a.BAD_PROTOBUF=6]="BAD_PROTOBUF",a))(j||{});var S=class{static encodeClientEnvelope(e){let t=M.create(e);return M.encode(t).finish()}static decodeServerEnvelope(e){let t=U.decode(e);return U.toObject(t,{enums:String,longs:String,bytes:String,defaults:true,oneofs:true})}};var v=class{constructor(){this.listeners=new Map;}on(e,t){this.listeners.has(e)||this.listeners.set(e,new Set),this.listeners.get(e).add(t);}off(e,t){let i=this.listeners.get(e);i&&i.delete(t);}once(e,t){let i=((...n)=>{t(...n),this.off(e,i);});this.on(e,i);}emit(e,...t){let i=this.listeners.get(e);i&&i.forEach(n=>n(...t));}removeAllListeners(){this.listeners.clear();}};var $=false;function G(s){$=s;}function m(...s){$&&console.debug("[Synxed]",...s);}function p(...s){console.warn("[Synxed]",...s);}function Y(s,e){let i=(s.endsWith("/")?s.slice(0,-1):s).replace(/^http:/,"ws:").replace(/^https:/,"wss:"),n=new URL(`${i}/sdk`);return n.searchParams.set("apiKey",e),n.toString()}var w=class extends v{constructor(){super(...arguments);this.ws=null;this.connectPromise=null;}connect(t,i){if(this.ws&&(this.ws.readyState===WebSocket.OPEN||this.ws.readyState===WebSocket.CONNECTING))return;let n=Y(i,t);m("Opening native WebSocket",n.replace(/apiKey=[^&]+/,"apiKey=***")),this.ws=new WebSocket(n),this.ws.binaryType="arraybuffer",this.ws.onopen=()=>{this.connectPromise=null,this.emit("connected");},this.ws.onclose=o=>{let r=o.reason||`code ${o.code}`;this.ws=null,this.connectPromise=null,this.emit("disconnected",r);},this.ws.onerror=()=>{this.emit("error",new Error("WebSocket connection error"));},this.ws.onmessage=o=>{try{let{data:r}=o;if(!(r instanceof ArrayBuffer))return;let a=S.decodeServerEnvelope(new Uint8Array(r));this.emit("message",a);}catch(r){this.emit("error",new Error(`Failed to decode message: ${r}`));}};}async waitForConnection(){if(m("Waiting for connection\u2026"),this.ws?.readyState===WebSocket.OPEN){m("Already connected");return}if(!this.ws)throw new Error("WebSocket not initialized. Call connect() first.");return this.connectPromise?this.connectPromise:(this.connectPromise=new Promise((t,i)=>{let n=this.ws;if(n.readyState===WebSocket.OPEN){t();return}let o=()=>{m("WebSocket connected"),l(),t();},r=()=>{p("WebSocket connection error"),l(),i(new Error("WebSocket connection failed"));},a=()=>{l(),i(new Error("WebSocket closed before connection was established"));},l=()=>{n.removeEventListener("open",o),n.removeEventListener("error",r),n.removeEventListener("close",a);};n.addEventListener("open",o),n.addEventListener("error",r),n.addEventListener("close",a);}),this.connectPromise)}disconnect(){this.ws&&(this.ws.onclose=null,this.ws.close(),this.ws=null,this.connectPromise=null);}sendInit(t){if(!this.isConnected)throw new Error("WebSocket not connected");m("Sending init packet",t),this.sendBytes(S.encodeClientEnvelope({init:t}));}sendControl(t){this.isConnected&&this.sendBytes(S.encodeClientEnvelope({control:t}));}sendAnalytics(t){this.isConnected&&this.sendBytes(S.encodeClientEnvelope({analytics:t}));}sendVoice(t){this.isConnected&&this.sendBytes(S.encodeClientEnvelope({voice:t}));}get isConnected(){return this.ws?.readyState===WebSocket.OPEN}sendBytes(t){if(!this.ws||this.ws.readyState!==WebSocket.OPEN)throw new Error("WebSocket not connected");this.ws.send(t);}};var N=class extends v{constructor(){super();this.howl=null;this.hls=null;this.audioEl=null;this.updateTimer=null;this.loadGeneration=0;}async load(t,i){let n=++this.loadGeneration;this.teardownPlayback(),this.emit("loading"),m("AudioEngine loading",{url:t,isHls:i});let o=/^((?!chrome|android).)*safari/i.test(navigator.userAgent);if(i&&!o)try{let{default:r}=await import('hls.js');if(r.isSupported()){m("Using Hls.js for playback");let a=new r({xhrSetup:h=>{h.setRequestHeader("ngrok-skip-browser-warning","true");}}),l=new Audio;return new Promise((h,u)=>{let c=()=>n!==this.loadGeneration,g=()=>{c()||(this.emit("playing"),this.startTimeUpdateLoop());},b=()=>{c()||(this.emit("paused"),this.stopTimeUpdateLoop());},T=()=>{c()||(this.emit("ended"),this.stopTimeUpdateLoop());},P=()=>{c()||this.emit("loaded");},ut=()=>{c()||(p("HLS audio element error"),this.emit("error",new Error("HLS playback failed")));};l.addEventListener("play",g),l.addEventListener("pause",b),l.addEventListener("ended",T),l.addEventListener("loadedmetadata",P),l.addEventListener("error",ut),a.on(r.Events.MANIFEST_PARSED,()=>{c()||(this.emit("loaded"),h());}),a.on(r.Events.ERROR,(bt,L)=>{c()||L.fatal&&(p("Fatal HLS error",L),u(L));}),a.loadSource(t),a.attachMedia(l),this.hls=a,this.audioEl=l;})}}catch(r){p("hls.js not available, falling back to native playback",r);}return new Promise((r,a)=>{let l=()=>n!==this.loadGeneration;this.howl=new howler.Howl({src:[t],html5:true,format:i?["m3u8"]:void 0,onload:()=>{l()||(m("AudioEngine loaded"),this.emit("loaded"),r());},onloaderror:(h,u)=>{l()||(p("AudioEngine load error",u),a(u));},onplay:()=>{l()||(this.emit("playing"),this.startTimeUpdateLoop());},onpause:()=>{l()||(this.emit("paused"),this.stopTimeUpdateLoop());},onstop:()=>{l()||(this.emit("stopped"),this.stopTimeUpdateLoop());},onend:()=>{l()||(this.emit("ended"),this.stopTimeUpdateLoop());}});})}play(){this.audioEl?this.audioEl.play().catch(t=>p("Play failed",t)):this.howl?.play();}pause(){this.audioEl?this.audioEl.pause():this.howl?.pause();}stop(){this.loadGeneration+=1,this.teardownPlayback(),this.emit("stopped");}seek(t){this.audioEl?this.audioEl.currentTime=t/1e3:this.howl?.seek(t/1e3);}setVolume(t){this.audioEl&&(this.audioEl.volume=t),this.howl&&this.howl.volume(t);}get duration(){return this.audioEl?this.audioEl.duration*1e3:(this.howl?.duration()||0)*1e3}get currentTime(){return this.audioEl?this.audioEl.currentTime*1e3:(this.howl?.seek()||0)*1e3}teardownPlayback(){if(this.hls){try{this.hls.destroy();}catch{}this.hls=null;}this.audioEl&&(this.audioEl.pause(),this.audioEl.removeAttribute("src"),this.audioEl.load(),this.audioEl=null),this.howl&&(this.howl.stop(),this.howl.unload(),this.howl=null),this.stopTimeUpdateLoop();}startTimeUpdateLoop(){this.stopTimeUpdateLoop();let t=()=>{(this.audioEl?!this.audioEl.paused:this.howl?.playing())&&(this.emit("timeupdate",{currentTime:this.currentTime,duration:this.duration}),this.updateTimer=requestAnimationFrame(t));};this.updateTimer=requestAnimationFrame(t);}stopTimeUpdateLoop(){this.updateTimer!==null&&(cancelAnimationFrame(this.updateTimer),this.updateTimer=null);}};var R=class extends v{constructor(){super();this.queue=[];this.currentIndex=-1;}setQueue(t,i){this.queue=t,this.currentIndex=typeof i=="number"&&i>=0&&i<t.length?i:t.length>0?0:-1,this.emit("queueUpdated",this.queue),this.getCurrentTrack()&&this.emit("trackChanged",this.getCurrentTrack());}getCurrentTrack(){return this.currentIndex>=0&&this.currentIndex<this.queue.length?this.queue[this.currentIndex]:null}next(){if(this.currentIndex<this.queue.length-1){this.currentIndex++;let t=this.getCurrentTrack();return this.emit("trackChanged",t),t}return null}previous(){if(this.currentIndex>0){this.currentIndex--;let t=this.getCurrentTrack();return this.emit("trackChanged",t),t}return null}skipTo(t){if(t>=0&&t<this.queue.length){this.currentIndex=t;let i=this.getCurrentTrack();return this.emit("trackChanged",i),i}return null}reset(){this.queue=[],this.currentIndex=-1,this.emit("queueUpdated",[]);}get hasNext(){return this.currentIndex<this.queue.length-1}get hasPrevious(){return this.currentIndex>0}get queueSnapshot(){return [...this.queue]}get currentIndexSnapshot(){return this.currentIndex}};var x=class extends Error{constructor(t,i){super(t);this.code=i;this.name="SynxedError";}},V=class extends x{constructor(e){super(e),this.name="SynxedConnectionError";}},E=class extends x{constructor(e){super(typeof e=="string"?e:"Playback failed"),this.name="SynxedPlaybackError";}},X=class extends x{constructor(e){super(e),this.name="SynxedProtocolError";}};function H(s,...e){for(let t of e){let i=s[t];if(typeof i=="string"&&i.length>0)return i}}function vt(s,...e){for(let t of e){let i=s[t];if(typeof i=="number"&&Number.isFinite(i))return i;if(typeof i=="string"&&i!==""&&!Number.isNaN(Number(i)))return Number(i)}}function J(s){let e=s.initAck??s.init_ack;if(!e||typeof e!="object")return null;let t=e,i=H(t,"playbackUrl","playback_url");return i?{sessionId:H(t,"sessionId","session_id")??"",playbackUrl:i,isHls:!!(t.isHls??t.is_hls),heartbeatIntervalMs:vt(t,"heartbeatIntervalMs","heartbeat_interval_ms")??0,contentSummary:H(t,"contentSummary","content_summary")}:null}function ft(s){if(!s||typeof s!="object")return null;let e=s,t=e.id;if(typeof t!="string"||!t.trim())return null;let i=e.kind==="internal"?"internal":"catalog",n=e.albumArt??e.album_art;return {id:t.trim(),kind:i,title:typeof e.title=="string"?e.title:void 0,artist:typeof e.artist=="string"?e.artist:void 0,duration:typeof e.duration=="number"?e.duration:void 0,albumArt:typeof n=="string"?n:void 0}}function Q(s,e){if(!s?.trim())return null;let t;try{t=JSON.parse(s);}catch{return null}if(!t||typeof t!="object")return null;let i=t;if(i.type==="live_radio"||e===4)return {tracks:[{id:"synxed-radio",kind:"catalog",title:typeof i.station=="string"&&i.station.trim()?i.station.trim():"Synxed Radio",artist:""}],currentIndex:0};let o=i.tracks;if(!Array.isArray(o)||o.length===0)return null;let r=[];for(let h of o){let u=ft(h);u&&r.push(u);}if(r.length===0)return null;let a=typeof i.currentIndex=="number"?i.currentIndex:typeof i.current_index=="number"?i.current_index:0,l=Math.max(0,Math.min(Math.floor(a),r.length-1));return {tracks:r,currentIndex:l}}function f(s,...e){for(let t of e){let i=s[t];if(typeof i=="string")return i}return ""}function Z(s,...e){for(let t of e){let i=s[t];if(typeof i=="boolean")return i}return false}function tt(s,...e){for(let t of e){let i=s[t];if(typeof i=="number"&&Number.isFinite(i))return i;if(typeof i=="string"&&i.trim()){let n=Number(i);if(Number.isFinite(n))return n}}return 0}function et(s){let e=s.ad;if(!e||typeof e!="object")return null;let t=e,i=f(t,"playbackUrl","playback_url");return i?{adId:f(t,"adId","ad_id"),campaignId:f(t,"campaignId","campaign_id"),playbackUrl:i,isHls:Z(t,"isHls","is_hls")||i.includes(".m3u8"),durationSeconds:tt(t,"durationSeconds","duration_seconds")||15,isSkippable:Z(t,"isSkippable","is_skippable"),skipAfterSeconds:tt(t,"skipAfterSeconds","skip_after_seconds"),ctaType:f(t,"ctaType","cta_type"),ctaValue:f(t,"ctaValue","cta_value"),brandName:f(t,"brandName","brand_name"),creativeName:f(t,"creativeName","creative_name"),companionBannerUrl:f(t,"companionBannerUrl","companion_banner_url"),campaignName:f(t,"campaignName","campaign_name")}:null}function C(s,...e){for(let t of e){let i=s[t];if(typeof i=="string")return i}return ""}function it(s){let e=s.voiceAck??s.voice_ack;if(!e||typeof e!="object")return null;let t=e,i=C(t,"status");return i?{status:i,transcript:C(t,"transcript")||void 0,playlistCode:C(t,"playlistCode","playlist_code")||void 0,playlistName:C(t,"playlistName","playlist_name")||void 0}:null}function nt(s){let e=s.voiceAudio??s.voice_audio;if(!e||typeof e!="object")return null;let t=e,i=t.audioData??t.audio_data,n=C(t,"mimeType","mime_type")||"audio/pcm;rate=24000",o=!!(t.isFinal??t.is_final);return i instanceof Uint8Array?{audioData:i,mimeType:n,isFinal:o}:null}var _=class{constructor(){this.audioContext=null;this.nextStartTime=0;}initContext(){this.audioContext||(this.audioContext=new(window.AudioContext||window.webkitAudioContext)({sampleRate:24e3}),this.nextStartTime=this.audioContext.currentTime);}enqueueChunk(e,t=24e3){try{if(this.initContext(),!this.audioContext)return;let i=new Int16Array(e.buffer,e.byteOffset,e.byteLength/2),n=new Float32Array(i.length);for(let l=0;l<i.length;l++)n[l]=i[l]/32768;let o=this.audioContext.createBuffer(1,n.length,t);o.getChannelData(0).set(n);let r=this.audioContext.createBufferSource();r.buffer=o,r.connect(this.audioContext.destination);let a=this.audioContext.currentTime;this.nextStartTime<a&&(this.nextStartTime=a+.05),r.start(this.nextStartTime),this.nextStartTime+=o.duration;}catch(i){p("VoiceResponsePlayer failed to enqueue chunk",i);}}stop(){this.audioContext&&(this.audioContext.close().catch(()=>{}),this.audioContext=null),this.nextStartTime=0;}};var st="https://cdn.jsdelivr.net/npm/@ricky0123/vad-web@0.0.29/dist/",yt="https://cdn.jsdelivr.net/npm/onnxruntime-web@1.22.0/dist/",A=class extends v{constructor(){super(...arguments);this.stream=null;this.audioContext=null;this.mediaStreamSource=null;this.processor=null;this.muteNode=null;this.sequence=0;this.capturing=false;this.mimeType="audio/pcm;rate=16000";this.micVad=null;this.speechEndEmitted=false;}get isCapturing(){return this.capturing}get activeMimeType(){return this.mimeType}async preloadModels(t={}){setTimeout(async()=>{try{let{utils:i}=await import('@ricky0123/vad-web'),n=t.vadBaseAssetPath??st;fetch(`${n}silero_vad_legacy.onnx`).catch(()=>{}),fetch(`${n}vad.worklet.bundle.min.js`).catch(()=>{});}catch(i){p("Failed to silently preload VAD models",i);}},5e3);}async start(t={}){if(this.capturing)return this.mimeType;this.speechEndEmitted=false,this.mimeType="audio/pcm;rate=16000",this.sequence=0,this.stream=await navigator.mediaDevices.getUserMedia({audio:{echoCancellation:true,noiseSuppression:true,autoGainControl:true,channelCount:1},video:false}),this.audioContext=new(window.AudioContext||window.webkitAudioContext)({sampleRate:16e3});let i=`
136
- class PcmProcessor extends AudioWorkletProcessor {
137
- constructor() {
138
- super();
139
- this.buffer = new Int16Array(4096);
140
- this.offset = 0;
141
- }
142
-
143
- process(inputs, outputs, parameters) {
144
- const input = inputs[0];
145
- if (!input || !input[0]) return true;
146
-
147
- const channelData = input[0];
148
- for (let i = 0; i < channelData.length; i++) {
149
- let s = Math.max(-1, Math.min(1, channelData[i]));
150
- this.buffer[this.offset++] = s < 0 ? s * 0x8000 : s * 0x7fff;
151
-
152
- if (this.offset >= 4096) {
153
- this.port.postMessage(this.buffer.buffer.slice(0));
154
- this.offset = 0;
155
- }
156
- }
157
- return true;
158
- }
159
- }
160
- registerProcessor('pcm-processor', PcmProcessor);
161
- `,n=new Blob([i],{type:"application/javascript"}),o=URL.createObjectURL(n);await this.audioContext.audioWorklet.addModule(o),this.mediaStreamSource=this.audioContext.createMediaStreamSource(this.stream),this.processor=new AudioWorkletNode(this.audioContext,"pcm-processor"),this.muteNode=this.audioContext.createGain(),this.muteNode.gain.value=0,this.processor.port.onmessage=r=>{this.capturing&&(this.sequence++,this.emit("chunk",new Uint8Array(r.data),this.sequence));},this.mediaStreamSource.connect(this.processor),this.processor.connect(this.muteNode),this.muteNode.connect(this.audioContext.destination),URL.revokeObjectURL(o),this.capturing=true;try{await this.startVadMonitor(t);}catch(r){this.emit("error",new Error(`Failed to initialize Voice Activity Detection: ${r instanceof Error?r.message:String(r)}`));}return this.mimeType}async stop(){this.capturing&&(this.capturing=false,this.teardownVad(),this.releaseStream());}cancel(){this.capturing=false,this.teardownVad(),this.releaseStream();}async startVadMonitor(t){let{MicVAD:i}=await import('@ricky0123/vad-web'),n=t.maxDurationMs??3e4,o=null,r=()=>{this.speechEndEmitted||!this.capturing||(this.speechEndEmitted=true,this.emit("speechEnd"));},a=await i.new({getStream:async()=>this.stream,baseAssetPath:t.vadBaseAssetPath??st,onnxWASMBasePath:t.onnxWasmBasePath??yt,positiveSpeechThreshold:.5,negativeSpeechThreshold:.35,redemptionMs:500,minSpeechMs:250,onSpeechStart:()=>{this.capturing&&(this.emit("speechStart"),o===null&&(o=setTimeout(()=>{r();},n)));},onSpeechEnd:()=>{o!==null&&(clearTimeout(o),o=null),r();}});this.micVad={start:()=>a.start(),pause:()=>a.pause(),destroy:()=>{o!==null&&(clearTimeout(o),o=null),a.destroy();}},this.micVad.start();}teardownVad(){if(this.micVad){try{this.micVad.pause();}catch(t){p("VAD pause failed during teardown",t);}try{this.micVad.destroy();}catch(t){p("VAD destroy failed during teardown",t);}this.micVad=null;}}releaseStream(){if(this.processor&&(this.processor.disconnect(),this.processor.port.onmessage=null,this.processor=null),this.muteNode&&(this.muteNode.disconnect(),this.muteNode=null),this.mediaStreamSource&&(this.mediaStreamSource.disconnect(),this.mediaStreamSource=null),this.audioContext&&(this.audioContext.close().catch(()=>{}),this.audioContext=null),this.stream){for(let t of this.stream.getTracks())t.stop();this.stream=null;}}};var O=class extends v{constructor(t){super();this.status="idle";this.volume=.8;this.activeContentKind=0;this.heartbeatTimer=null;this.adPlaying=false;this._currentAd=null;this._voiceState="idle";this.voiceMimeType="audio/webm";this.pendingPlaybackLoad=null;this.voiceAutoEndOnSilence=true;this.pausedForVoice=false;this.config=t,G(!!t.debug),this.transport=new w,this.audio=new N,this.playlist=new R,this.voiceCapture=new A,this.voiceResponsePlayer=new _,this.setupListeners(),this.voiceCapture.preloadModels(this.config.voice),t.autoConnect&&this.connect();}get currentTrack(){return this.playlist.getCurrentTrack()}get contentKind(){return this.activeContentKind}get currentAd(){return this._currentAd}get isAdPlaying(){return this.adPlaying}canSkipAd(){return !this.adPlaying||!this._currentAd?.isSkippable?false:Math.floor(this.audio.currentTime*1e3)>=this._currentAd.skipAfterSeconds*1e3}getAdSkipCountdownSeconds(){if(!this.adPlaying||!this._currentAd?.isSkippable)return null;let t=Math.floor(this.audio.currentTime*1e3),i=this._currentAd.skipAfterSeconds*1e3;return t>=i?0:Math.ceil((i-t)/1e3)}get voiceState(){return this._voiceState}controlPositionMs(){return this.activeContentKind===4?0:this.positionMsForAnalytics()}setupListeners(){this.transport.on("connected",()=>this.emit("connected")),this.transport.on("disconnected",t=>this.emit("disconnected",t)),this.transport.on("error",t=>this.emit("error",new V(t.message))),this.transport.on("message",t=>this.handleServerMessage(t)),this.audio.on("playing",()=>this.updateStatus("playing")),this.audio.on("paused",()=>this.updateStatus("paused")),this.audio.on("stopped",()=>{!this.adPlaying&&this._voiceState==="idle"&&this.updateStatus("idle");}),this.audio.on("loading",()=>this.updateStatus("loading")),this.audio.on("error",t=>{if(this.adPlaying){p("Ad playback error \u2014 waiting for next track",t);return}this.emit("error",new E(t));}),this.audio.on("timeupdate",t=>{this.emit("timeUpdate",t),this.adPlaying&&this._currentAd&&this.emitAdSkipUpdate(t.currentTime);}),this.audio.on("ended",()=>this.handleTrackEnded()),this.playlist.on("trackChanged",t=>this.emit("trackChange",t)),this.playlist.on("queueUpdated",t=>this.emit("queueUpdated",t)),this.voiceCapture.on("chunk",(t,i)=>{this.transport.sendVoice({action:2,audioData:t,mimeType:this.voiceMimeType,sequence:i,listenerId:this.voiceListenerId,deviceType:this.config.deviceType,gameContext:this.config.gameContext});}),this.voiceCapture.on("error",t=>{this.setVoiceState("error"),this.emit("error",new x(t.message,"VOICE_CAPTURE_FAILED"));}),this.voiceCapture.on("speechStart",()=>{this.emit("voiceSpeechStart");}),this.voiceCapture.on("speechEnd",()=>{this.emit("voiceSpeechEnd"),this.voiceAutoEndOnSilence&&this._voiceState==="listening"&&this.endVoiceHold();});}resolveVoiceOptions(t={}){return {...this.config.voice,...t}}connect(){this.transport.connect(this.config.apiKey,this.config.serverUrl);}buildInitExtras(){let t={};return this.config.gameContext?.trim()&&(t.gameContext=this.config.gameContext.trim()),this.config.deviceType?.trim()&&(t.deviceType=this.config.deviceType.trim()),t}async playSong(t){this.transport.isConnected||this.connect(),await this.transport.waitForConnection(),this.activeContentKind=1,this.transport.sendInit({contentKind:1,catalogTrackId:t.catalogTrackId,internalTrackId:t.internalTrackId,listenerId:t.listenerId,...this.buildInitExtras()});}async playPlaylist(t){this.transport.isConnected||this.connect(),await this.transport.waitForConnection(),this.activeContentKind=2,this.transport.sendInit({contentKind:2,playlistCode:t.playlistCode,listenerId:t.listenerId,...this.buildInitExtras()});}async playRadio(t={}){this.transport.isConnected||this.connect(),await this.transport.waitForConnection(),this.activeContentKind=4,this.transport.sendInit({contentKind:4,listenerId:t.listenerId,...this.buildInitExtras()});}async beginVoiceHold(t={}){if(this._voiceState==="listening"||this._voiceState==="processing"||this._voiceState==="responding")return;let i=this.resolveVoiceOptions(t);this.voiceAutoEndOnSilence=i.autoEndOnSilence!==false,this.transport.isConnected||this.connect(),await this.transport.waitForConnection(),this.voiceListenerId=i.listenerId?.trim()||void 0,this.pausedForVoice=this.status==="playing",this.pausedForVoice&&this.pause(),this.voiceResponsePlayer.stop(),this.voiceMimeType=await this.voiceCapture.start({maxDurationMs:i.maxDurationMs}),this.transport.sendVoice({action:1,mimeType:this.voiceMimeType,listenerId:this.voiceListenerId,...this.buildInitExtras()}),this.setVoiceState("listening");}async endVoiceHold(){this._voiceState==="listening"&&(await this.voiceCapture.stop(),this.transport.sendVoice({action:3,mimeType:this.voiceMimeType,listenerId:this.voiceListenerId,...this.buildInitExtras()}),this.setVoiceState("processing"));}cancelVoiceHold(){this._voiceState==="listening"&&(this.voiceCapture.cancel(),this.setVoiceState("idle"));}dismissVoiceAndResume(){this._voiceState==="listening"&&this.cancelVoiceHold(),this.pausedForVoice&&(this.resume(),this.pausedForVoice=false);}get isVoiceUiActive(){return this._voiceState==="listening"||this._voiceState==="processing"||this._voiceState==="responding"}pause(){this.audio.pause(),this.transport.sendControl({action:2,positionMs:this.controlPositionMs()});}resume(){this.audio.play(),this.transport.sendControl({action:1,positionMs:this.controlPositionMs()});}stop(){this.audio.stop(),this.transport.sendControl({action:3,positionMs:this.controlPositionMs()});}skip(){if(this.activeContentKind===4)return;if(this.adPlaying){this.skipAd();return}if(this.playlist.queueSnapshot.length>1){this.transport.sendControl({action:5,positionMs:this.controlPositionMs()}),this.updateStatus("loading");return}let t=this.playlist.next();t&&this.playSong(t.kind==="internal"?{internalTrackId:t.id}:{catalogTrackId:t.id});}previous(){if(this.activeContentKind===4)return;if(this.playlist.queueSnapshot.length>1){this.transport.sendControl({action:6,positionMs:this.controlPositionMs()}),this.updateStatus("loading");return}let t=this.playlist.previous();t&&this.playSong(t.kind==="internal"?{internalTrackId:t.id}:{catalogTrackId:t.id});}skipTo(t){if(this.activeContentKind===4)return;let i=this.playlist.skipTo(t);i&&this.playSong(i.kind==="internal"?{internalTrackId:i.id}:{catalogTrackId:i.id});}seek(t){this.activeContentKind===4||this.adPlaying||(this.audio.seek(t),this.transport.sendControl({action:4,positionMs:t}));}setVolume(t){this.volume=Math.max(0,Math.min(1,t)),this.audio.setVolume(this.volume);}positionMsForAnalytics(t){return typeof t=="number"?Math.max(0,Math.min(4294967295,Math.floor(t))):Math.max(0,Math.min(4294967295,Math.floor(this.audio.currentTime)))}emitAnalytics(t,i,n){this.transport.sendAnalytics({eventType:t,positionMs:this.positionMsForAnalytics(i),extraJson:n?JSON.stringify(n):void 0});}clearHeartbeat(){this.heartbeatTimer!==null&&(clearInterval(this.heartbeatTimer),this.heartbeatTimer=null);}startHeartbeat(t){this.clearHeartbeat();let i=Number(t);!i||i<1e3||(this.heartbeatTimer=setInterval(()=>{let n=this.activeContentKind===4?0:this.positionMsForAnalytics();this.emitAnalytics("heartbeat",n);},i));}applyContentSummary(t){let i=Q(t,this.activeContentKind);if(i){this.playlist.setQueue(i.tracks,i.currentIndex);return}t?.trim()&&p("Could not parse contentSummary; queue metadata unavailable.");}emitAdSkipUpdate(t){if(!this._currentAd)return;let i=this._currentAd.skipAfterSeconds*1e3,n=this._currentAd.isSkippable&&t>=i,o=n?0:Math.ceil((i-t)/1e3),r={ad:this._currentAd,canSkip:n,countdownSeconds:o};this.emit("adSkipUpdate",r);}setVoiceState(t){this._voiceState=t,this.emit("voiceStateChange",t);}handleVoiceAck(t){let i=t.status;if(i==="listening"){this.setVoiceState("listening");return}if(i==="processing"){this.setVoiceState("processing");return}if(i==="ready"){this.activeContentKind=2;let n={status:i,transcript:t.transcript,playlistCode:t.playlistCode,playlistName:t.playlistName};this.setVoiceState("ready"),this.emit("voiceResult",n);return}this.emit("voiceResult",{status:i,transcript:t.transcript,playlistCode:t.playlistCode,playlistName:t.playlistName});}async handleServerMessage(t){m("Received server message",t);let i=it(t);if(i){this.handleVoiceAck(i);return}let n=nt(t);if(n){this._voiceState==="processing"&&this.setVoiceState("responding"),n.audioData.length>0&&this.voiceResponsePlayer.enqueueChunk(n.audioData);return}let o=et(t);if(o){await this.handleAdPlayback(o);return}let r=J(t);if(r){await this.startContentPlayback(r);return}let a=t.error;if(a&&typeof a=="object"){let l=a,h=typeof l.message=="string"?l.message:"Unknown server error",u=typeof l.code=="string"?l.code:void 0;(this._voiceState==="processing"||this._voiceState==="listening"||this._voiceState==="responding")&&this.setVoiceState("error"),this.emit("error",new x(h,u));}}async startContentPlayback(t){if(this.adPlaying&&this._currentAd){let n=this._currentAd;this.adPlaying=false,this._currentAd=null,this.emit("adEnd",n);}else this.adPlaying=false,this._currentAd=null;(this._voiceState==="ready"||this._voiceState==="processing"||this._voiceState==="responding")&&this.setVoiceState("idle"),this.pausedForVoice=false,this.voiceResponsePlayer.stop(),m("Loading playback",{url:t.playbackUrl,isHls:t.isHls});let i=this.audio.load(t.playbackUrl,t.isHls);this.pendingPlaybackLoad=i;try{if(await i,this.pendingPlaybackLoad!==i)return;this.audio.play(),this.emitAnalytics("stream_start",this.activeContentKind===4?0:void 0),this.startHeartbeat(t.heartbeatIntervalMs),this.applyContentSummary(t.contentSummary);}catch(n){if(this.pendingPlaybackLoad!==i)return;this.emit("error",new E(n));}finally{this.pendingPlaybackLoad===i&&(this.pendingPlaybackLoad=null);}}async handleAdPlayback(t){this.pendingPlaybackLoad&&await this.pendingPlaybackLoad.catch(()=>{}),this.audio.stop(),this.adPlaying=true,this._currentAd={adId:t.adId,campaignId:t.campaignId,brandName:t.brandName,creativeName:t.creativeName,durationSeconds:t.durationSeconds,isSkippable:t.isSkippable,skipAfterSeconds:t.skipAfterSeconds,ctaType:t.ctaType,ctaValue:t.ctaValue,companionBannerUrl:t.companionBannerUrl,campaignName:t.campaignName},m("Loading ad playback",{url:t.playbackUrl,isHls:t.isHls});try{await this.audio.load(t.playbackUrl,t.isHls),this.audio.play(),this.emit("adStart",this._currentAd),this.emitAdSkipUpdate(0);}catch(i){let n=this._currentAd;this.adPlaying=false,this._currentAd=null,n&&this.emit("adEnd",n),p("Ad load failed",i),this.updateStatus("loading");}}skipAd(){if(!this.adPlaying||!this._currentAd||!this._currentAd.isSkippable)return;let t=Math.floor(this.audio.currentTime*1e3);if(t<this._currentAd.skipAfterSeconds*1e3)return;let i=this._currentAd;this.adPlaying=false,this._currentAd=null,this.audio.stop(),this.emit("adEnd",i),this.emitAnalytics("ad_skip",t),this.updateStatus("loading");}clickAd(){if(!this.adPlaying||!this._currentAd)return;let t=Math.floor(this.audio.currentTime*1e3);this.emitAnalytics("ad_cta_click",t),this._currentAd.ctaValue&&window.open(this._currentAd.ctaValue,"_blank");}handleTrackEnded(){if(this.activeContentKind!==4){if(this.adPlaying&&this._currentAd){let t=this._currentAd;this.audio.stop(),this.emitAnalytics("ad_complete",Math.floor(this.audio.currentTime*1e3)),this.emit("adEnd",t),this.adPlaying=false,this._currentAd=null,this.updateStatus("loading");return}if(this.playlist.queueSnapshot.length>1){this.emitAnalytics("track_complete",Math.floor(this.audio.duration*1e3)),this.updateStatus("loading");return}if(this.activeContentKind===1||this.activeContentKind===2){this.emitAnalytics("track_complete",Math.floor(this.audio.duration*1e3)),this.updateStatus("loading");return}this.updateStatus("idle");}}updateStatus(t){this.status=t,this.emit("stateChange",{status:t,currentTrack:this.playlist.getCurrentTrack(),currentTime:this.audio.currentTime,duration:this.audio.duration,volume:this.volume});}destroy(){this.clearHeartbeat(),this.cancelVoiceHold(),this.voiceResponsePlayer.stop(),this.audio.stop(),this.transport.disconnect(),this.playlist.reset(),this.removeAllListeners();}};async function B(s,e){let i=`${s.replace(/\/$/,"")}/radio/now-playing`;try{let n=await fetch(i,{...e,headers:{Accept:"application/json",...e?.headers}});if(!n.ok)return null;let r=(await n.json())?.data;return !r?.title||typeof r.title!="string"?null:{title:r.title,station:typeof r.station=="string"?r.station:void 0,isLive:typeof r.isLive=="boolean"?r.isLive:void 0}}catch{return null}}function d(s,e){let t=document.createElement(s);if(e?.className&&(t.className=e.className),e?.attrs)for(let[i,n]of Object.entries(e.attrs))t.setAttribute(i,n);return e?.style&&Object.assign(t.style,e.style),e?.text&&(t.textContent=e.text),e?.html&&(t.innerHTML=e.html),e?.onClick&&t.addEventListener("click",e.onClick),e?.children&&e.children.forEach(i=>t.appendChild(i)),t}function y(s,e=20){let t=document.createElementNS("http://www.w3.org/2000/svg","svg");t.setAttribute("width",String(e)),t.setAttribute("height",String(e)),t.setAttribute("viewBox","0 0 24 24"),t.setAttribute("fill","currentColor"),t.setAttribute("aria-hidden","true");let i=document.createElementNS("http://www.w3.org/2000/svg","path");return i.setAttribute("d",s),t.appendChild(i),t}var W="M8 5v14l11-7L8 5z",rt="M6 5h4v14H6V5zm8 0h4v14h-4V5z",k="M6 18l8.5-6L6 6v12zM16 6v12h2V6h-2z",at="M6 6h2v12H6V6zm11.5 12L9 12l8.5-6v12z";function ot(){let s="synxed-web-player-styles";if(document.getElementById(s))return;let e=document.createElement("style");e.id=s,e.textContent=`
135
+ `,$=j__namespace.parse(ft).root,U=$.lookupType("SdkClientEnvelope"),H=$.lookupType("SdkServerEnvelope"),R=(s=>(s[s.UNSPECIFIED=0]="UNSPECIFIED",s[s.SONG=1]="SONG",s[s.PLAYLIST=2]="PLAYLIST",s[s.CATEGORY=3]="CATEGORY",s[s.RADIO=4]="RADIO",s[s.VOICE=5]="VOICE",s))(R||{}),D=(n=>(n[n.VOICE_UNSPECIFIED=0]="VOICE_UNSPECIFIED",n[n.VOICE_START=1]="VOICE_START",n[n.VOICE_CHUNK=2]="VOICE_CHUNK",n[n.VOICE_END=3]="VOICE_END",n))(D||{}),Y=(a=>(a[a.UNSPECIFIED=0]="UNSPECIFIED",a[a.UNAUTHORIZED=1]="UNAUTHORIZED",a[a.VALIDATION_ERROR=2]="VALIDATION_ERROR",a[a.NOT_FOUND=3]="NOT_FOUND",a[a.PROCESSING=4]="PROCESSING",a[a.SERVICE_UNAVAILABLE=5]="SERVICE_UNAVAILABLE",a[a.BAD_PROTOBUF=6]="BAD_PROTOBUF",a))(Y||{});var S=class{static encodeClientEnvelope(e){let t=U.create(e);return U.encode(t).finish()}static decodeServerEnvelope(e){let t=H.decode(e);return H.toObject(t,{enums:String,longs:String,bytes:String,defaults:true,oneofs:true})}};var v=class{constructor(){this.listeners=new Map;}on(e,t){this.listeners.has(e)||this.listeners.set(e,new Set),this.listeners.get(e).add(t);}off(e,t){let i=this.listeners.get(e);i&&i.delete(t);}once(e,t){let i=((...n)=>{t(...n),this.off(e,i);});this.on(e,i);}emit(e,...t){let i=this.listeners.get(e);i&&i.forEach(n=>n(...t));}removeAllListeners(){this.listeners.clear();}};var G=false;function X(r){G=r;}function m(...r){G&&console.debug("[Synxed]",...r);}function h(...r){console.warn("[Synxed]",...r);}function J(r,e){let i=(r.endsWith("/")?r.slice(0,-1):r).replace(/^http:/,"ws:").replace(/^https:/,"wss:"),n=new URL(`${i}/sdk`);return n.searchParams.set("apiKey",e),n.toString()}var E=class extends v{constructor(){super(...arguments);this.ws=null;this.connectPromise=null;}connect(t,i){if(this.ws&&(this.ws.readyState===WebSocket.OPEN||this.ws.readyState===WebSocket.CONNECTING))return;let n=J(i,t);m("Opening native WebSocket",n.replace(/apiKey=[^&]+/,"apiKey=***")),this.ws=new WebSocket(n),this.ws.binaryType="arraybuffer",this.ws.onopen=()=>{this.connectPromise=null,this.emit("connected");},this.ws.onclose=o=>{let s=o.reason||`code ${o.code}`;this.ws=null,this.connectPromise=null,this.emit("disconnected",s);},this.ws.onerror=()=>{this.emit("error",new Error("WebSocket connection error"));},this.ws.onmessage=o=>{try{let{data:s}=o;if(!(s instanceof ArrayBuffer))return;let a=S.decodeServerEnvelope(new Uint8Array(s));this.emit("message",a);}catch(s){this.emit("error",new Error(`Failed to decode message: ${s}`));}};}async waitForConnection(){if(m("Waiting for connection\u2026"),this.ws?.readyState===WebSocket.OPEN){m("Already connected");return}if(!this.ws)throw new Error("WebSocket not initialized. Call connect() first.");return this.connectPromise?this.connectPromise:(this.connectPromise=new Promise((t,i)=>{let n=this.ws;if(n.readyState===WebSocket.OPEN){t();return}let o=()=>{m("WebSocket connected"),l(),t();},s=()=>{h("WebSocket connection error"),l(),i(new Error("WebSocket connection failed"));},a=()=>{l(),i(new Error("WebSocket closed before connection was established"));},l=()=>{n.removeEventListener("open",o),n.removeEventListener("error",s),n.removeEventListener("close",a);};n.addEventListener("open",o),n.addEventListener("error",s),n.addEventListener("close",a);}),this.connectPromise)}disconnect(){this.ws&&(this.ws.onclose=null,this.ws.close(),this.ws=null,this.connectPromise=null);}sendInit(t){if(!this.isConnected)throw new Error("WebSocket not connected");m("Sending init packet",t),this.sendBytes(S.encodeClientEnvelope({init:t}));}sendControl(t){this.isConnected&&this.sendBytes(S.encodeClientEnvelope({control:t}));}sendAnalytics(t){this.isConnected&&this.sendBytes(S.encodeClientEnvelope({analytics:t}));}sendVoice(t){this.isConnected&&this.sendBytes(S.encodeClientEnvelope({voice:t}));}get isConnected(){return this.ws?.readyState===WebSocket.OPEN}sendBytes(t){if(!this.ws||this.ws.readyState!==WebSocket.OPEN)throw new Error("WebSocket not connected");this.ws.send(t);}};var _=class extends v{constructor(){super();this.howl=null;this.hls=null;this.audioEl=null;this.updateTimer=null;this.loadGeneration=0;}async load(t,i){let n=++this.loadGeneration;this.teardownPlayback(),this.emit("loading"),m("AudioEngine loading",{url:t,isHls:i});let o=/^((?!chrome|android).)*safari/i.test(navigator.userAgent);if(i&&!o)try{let{default:s}=await import('hls.js');if(s.isSupported()){m("Using Hls.js for playback");let a=new s({xhrSetup:c=>{c.setRequestHeader("ngrok-skip-browser-warning","true");}}),l=new Audio;return new Promise((c,p)=>{let u=()=>n!==this.loadGeneration,g=()=>{u()||(this.emit("playing"),this.startTimeUpdateLoop());},b=()=>{u()||(this.emit("paused"),this.stopTimeUpdateLoop());},T=()=>{u()||(this.emit("ended"),this.stopTimeUpdateLoop());},I=()=>{u()||this.emit("loaded");},vt=()=>{u()||(h("HLS audio element error"),this.emit("error",new Error("HLS playback failed")));};l.addEventListener("play",g),l.addEventListener("pause",b),l.addEventListener("ended",T),l.addEventListener("loadedmetadata",I),l.addEventListener("error",vt),a.on(s.Events.MANIFEST_PARSED,()=>{u()||(this.emit("loaded"),c());}),a.on(s.Events.ERROR,(kt,M)=>{u()||M.fatal&&(h("Fatal HLS error",M),p(M));}),a.loadSource(t),a.attachMedia(l),this.hls=a,this.audioEl=l;})}}catch(s){h("hls.js not available, falling back to native playback",s);}return new Promise((s,a)=>{let l=()=>n!==this.loadGeneration;this.howl=new howler.Howl({src:[t],html5:true,format:i?["m3u8"]:void 0,onload:()=>{l()||(m("AudioEngine loaded"),this.emit("loaded"),s());},onloaderror:(c,p)=>{l()||(h("AudioEngine load error",p),a(p));},onplay:()=>{l()||(this.emit("playing"),this.startTimeUpdateLoop());},onpause:()=>{l()||(this.emit("paused"),this.stopTimeUpdateLoop());},onstop:()=>{l()||(this.emit("stopped"),this.stopTimeUpdateLoop());},onend:()=>{l()||(this.emit("ended"),this.stopTimeUpdateLoop());}});})}play(){this.audioEl?this.audioEl.play().catch(t=>h("Play failed",t)):this.howl?.play();}pause(){this.audioEl?this.audioEl.pause():this.howl?.pause();}stop(){this.loadGeneration+=1,this.teardownPlayback(),this.emit("stopped");}seek(t){this.audioEl?this.audioEl.currentTime=t/1e3:this.howl?.seek(t/1e3);}setVolume(t){this.audioEl&&(this.audioEl.volume=t),this.howl&&this.howl.volume(t);}get duration(){return this.audioEl?this.audioEl.duration*1e3:(this.howl?.duration()||0)*1e3}get currentTime(){return this.audioEl?this.audioEl.currentTime*1e3:(this.howl?.seek()||0)*1e3}teardownPlayback(){if(this.hls){try{this.hls.destroy();}catch{}this.hls=null;}this.audioEl&&(this.audioEl.pause(),this.audioEl.removeAttribute("src"),this.audioEl.load(),this.audioEl=null),this.howl&&(this.howl.stop(),this.howl.unload(),this.howl=null),this.stopTimeUpdateLoop();}startTimeUpdateLoop(){this.stopTimeUpdateLoop();let t=()=>{(this.audioEl?!this.audioEl.paused:this.howl?.playing())&&(this.emit("timeupdate",{currentTime:this.currentTime,duration:this.duration}),this.updateTimer=requestAnimationFrame(t));};this.updateTimer=requestAnimationFrame(t);}stopTimeUpdateLoop(){this.updateTimer!==null&&(cancelAnimationFrame(this.updateTimer),this.updateTimer=null);}};var O=class extends v{constructor(){super();this.queue=[];this.currentIndex=-1;}setQueue(t,i){this.queue=t,this.currentIndex=typeof i=="number"&&i>=0&&i<t.length?i:t.length>0?0:-1,this.emit("queueUpdated",this.queue),this.getCurrentTrack()&&this.emit("trackChanged",this.getCurrentTrack());}getCurrentTrack(){return this.currentIndex>=0&&this.currentIndex<this.queue.length?this.queue[this.currentIndex]:null}next(){if(this.currentIndex<this.queue.length-1){this.currentIndex++;let t=this.getCurrentTrack();return this.emit("trackChanged",t),t}return null}previous(){if(this.currentIndex>0){this.currentIndex--;let t=this.getCurrentTrack();return this.emit("trackChanged",t),t}return null}skipTo(t){if(t>=0&&t<this.queue.length){this.currentIndex=t;let i=this.getCurrentTrack();return this.emit("trackChanged",i),i}return null}reset(){this.queue=[],this.currentIndex=-1,this.emit("queueUpdated",[]);}get hasNext(){return this.currentIndex<this.queue.length-1}get hasPrevious(){return this.currentIndex>0}get queueSnapshot(){return [...this.queue]}get currentIndexSnapshot(){return this.currentIndex}};var x=class extends Error{constructor(t,i){super(t);this.code=i;this.name="SynxedError";}},N=class extends x{constructor(e){super(e),this.name="SynxedConnectionError";}},w=class extends x{constructor(e){super(typeof e=="string"?e:"Playback failed"),this.name="SynxedPlaybackError";}},Q=class extends x{constructor(e){super(e),this.name="SynxedProtocolError";}};function B(r,...e){for(let t of e){let i=r[t];if(typeof i=="string"&&i.length>0)return i}}function gt(r,...e){for(let t of e){let i=r[t];if(typeof i=="number"&&Number.isFinite(i))return i;if(typeof i=="string"&&i!==""&&!Number.isNaN(Number(i)))return Number(i)}}function Z(r){let e=r.initAck??r.init_ack;if(!e||typeof e!="object")return null;let t=e,i=B(t,"playbackUrl","playback_url");return i?{sessionId:B(t,"sessionId","session_id")??"",playbackUrl:i,isHls:!!(t.isHls??t.is_hls),heartbeatIntervalMs:gt(t,"heartbeatIntervalMs","heartbeat_interval_ms")??0,contentSummary:B(t,"contentSummary","content_summary")}:null}function bt(r){if(!r||typeof r!="object")return null;let e=r,t=e.id;if(typeof t!="string"||!t.trim())return null;let i=e.kind==="internal"?"internal":"catalog",n=e.albumArt??e.album_art;return {id:t.trim(),kind:i,title:typeof e.title=="string"?e.title:void 0,artist:typeof e.artist=="string"?e.artist:void 0,duration:typeof e.duration=="number"?e.duration:void 0,albumArt:typeof n=="string"?n:void 0}}function tt(r,e){if(!r?.trim())return null;let t;try{t=JSON.parse(r);}catch{return null}if(!t||typeof t!="object")return null;let i=t;if(i.type==="live_radio"||e===4)return {tracks:[{id:"synxed-radio",kind:"catalog",title:typeof i.station=="string"&&i.station.trim()?i.station.trim():"Synxed Radio",artist:""}],currentIndex:0};let o=i.tracks;if(!Array.isArray(o)||o.length===0)return null;let s=[];for(let c of o){let p=bt(c);p&&s.push(p);}if(s.length===0)return null;let a=typeof i.currentIndex=="number"?i.currentIndex:typeof i.current_index=="number"?i.current_index:0,l=Math.max(0,Math.min(Math.floor(a),s.length-1));return {tracks:s,currentIndex:l}}function f(r,...e){for(let t of e){let i=r[t];if(typeof i=="string")return i}return ""}function et(r,...e){for(let t of e){let i=r[t];if(typeof i=="boolean")return i}return false}function it(r,...e){for(let t of e){let i=r[t];if(typeof i=="number"&&Number.isFinite(i))return i;if(typeof i=="string"&&i.trim()){let n=Number(i);if(Number.isFinite(n))return n}}return 0}function nt(r){let e=r.ad;if(!e||typeof e!="object")return null;let t=e,i=f(t,"playbackUrl","playback_url");return i?{adId:f(t,"adId","ad_id"),campaignId:f(t,"campaignId","campaign_id"),playbackUrl:i,isHls:et(t,"isHls","is_hls")||i.includes(".m3u8"),durationSeconds:it(t,"durationSeconds","duration_seconds")||15,isSkippable:et(t,"isSkippable","is_skippable"),skipAfterSeconds:it(t,"skipAfterSeconds","skip_after_seconds"),ctaType:f(t,"ctaType","cta_type"),ctaValue:f(t,"ctaValue","cta_value"),brandName:f(t,"brandName","brand_name"),creativeName:f(t,"creativeName","creative_name"),companionBannerUrl:f(t,"companionBannerUrl","companion_banner_url"),campaignName:f(t,"campaignName","campaign_name")}:null}var rt="audio/pcm;rate=16000",A="audio/pcm;rate=24000";function W(r,e){let t=/rate=(\d+)/i.exec(r);if(!t)return e;let i=Number(t[1]);return Number.isFinite(i)&&i>0?i:e}function C(r,...e){for(let t of e){let i=r[t];if(typeof i=="string")return i}return ""}function st(r){let e=r.voiceAck??r.voice_ack;if(!e||typeof e!="object")return null;let t=e,i=C(t,"status");return i?{status:i,transcript:C(t,"transcript")||void 0,playlistCode:C(t,"playlistCode","playlist_code")||void 0,playlistName:C(t,"playlistName","playlist_name")||void 0}:null}function at(r){let e=r.voiceAudio??r.voice_audio;if(!e||typeof e!="object")return null;let t=e,i=t.audioData??t.audio_data,n=C(t,"mimeType","mime_type")||A,o=!!(t.isFinal??t.is_final),s;if(typeof i=="string"){let a=atob(i),l=a.length;s=new Uint8Array(l);for(let c=0;c<l;c++)s[c]=a.charCodeAt(c);}else if(i instanceof Uint8Array)s=i;else return null;return {audioData:s,mimeType:n,isFinal:o}}var V=class{constructor(){this.audioContext=null;this.nextStartTime=0;this.defaultSampleRate=W(A,24e3);}initContext(e){this.audioContext||(this.audioContext=new(window.AudioContext||window.webkitAudioContext)({sampleRate:e}),this.nextStartTime=this.audioContext.currentTime);}enqueueChunk(e,t=A){try{let i=W(t,this.defaultSampleRate);if(this.initContext(i),!this.audioContext)return;let n=new Int16Array(e.buffer,e.byteOffset,e.byteLength/2),o=new Float32Array(n.length);for(let c=0;c<n.length;c++)o[c]=n[c]/32768;let s=this.audioContext.createBuffer(1,o.length,i);s.getChannelData(0).set(o);let a=this.audioContext.createBufferSource();a.buffer=s,a.connect(this.audioContext.destination);let l=this.audioContext.currentTime;this.nextStartTime<l&&(this.nextStartTime=l+.05),a.start(this.nextStartTime),this.nextStartTime+=s.duration;}catch(i){h("VoiceResponsePlayer failed to enqueue chunk",i);}}stop(){this.audioContext&&(this.audioContext.close().catch(()=>{}),this.audioContext=null),this.nextStartTime=0;}};var ot="https://cdn.jsdelivr.net/npm/@ricky0123/vad-web@0.0.29/dist/",St="https://cdn.jsdelivr.net/npm/onnxruntime-web@1.22.0/dist/",P=class extends v{constructor(){super(...arguments);this.capturing=false;this.mimeType=rt;this.micVad=null;this.speechEndEmitted=false;}get isCapturing(){return this.capturing}async preloadModels(t={}){setTimeout(async()=>{try{let{utils:i}=await import('@ricky0123/vad-web'),n=t.vadBaseAssetPath??ot;fetch(`${n}silero_vad_legacy.onnx`).catch(()=>{}),fetch(`${n}vad.worklet.bundle.min.js`).catch(()=>{});}catch(i){h("Failed to silently preload VAD models",i);}},5e3);}async start(t={}){if(this.capturing)return this.mimeType;this.speechEndEmitted=false,this.capturing=true;try{let{MicVAD:i}=await import('@ricky0123/vad-web'),n=0;this.micVad=await i.new({baseAssetPath:t.vadBaseAssetPath??ot,onnxWASMBasePath:t.onnxWasmBasePath??St,positiveSpeechThreshold:.5,negativeSpeechThreshold:.35,redemptionMs:500,minSpeechMs:250,onFrameProcessed:(o,s)=>{if(!this.capturing||this.speechEndEmitted)return;let a=new Int16Array(s.length);for(let c=0;c<s.length;c++){let p=Math.max(-1,Math.min(1,s[c]));a[c]=p<0?p*32768:p*32767;}let l=new Uint8Array(a.buffer);n++,this.emit("chunk",l,n);},onSpeechStart:()=>{this.capturing&&this.emit("speechStart");},onSpeechEnd:()=>{!this.capturing||this.speechEndEmitted||(this.speechEndEmitted=!0,this.emit("speechEnd"));}}),this.micVad.start();}catch(i){this.capturing=false,this.emit("error",new Error(`Failed to init VAD: ${i}`));}return this.mimeType}async stop(){this.cancel();}cancel(){if(this.capturing=false,this.micVad){try{this.micVad.pause();}catch{}try{this.micVad.destroy();}catch{}this.micVad=null;}}};var L=class extends v{constructor(t){super();this.status="idle";this.volume=.8;this.activeContentKind=0;this.heartbeatTimer=null;this.adPlaying=false;this._currentAd=null;this._voiceState="idle";this.voiceMimeType="audio/webm";this.pendingPlaybackLoad=null;this.voiceAutoEndOnSilence=true;this.pausedForVoice=false;this.config=t,X(!!t.debug),this.transport=new E,this.audio=new _,this.playlist=new O,this.voiceCapture=new P,this.voiceResponsePlayer=new V,this.setupListeners(),this.voiceCapture.preloadModels(this.config.voice),t.autoConnect&&this.connect();}get currentTrack(){return this.playlist.getCurrentTrack()}get contentKind(){return this.activeContentKind}get currentAd(){return this._currentAd}get isAdPlaying(){return this.adPlaying}canSkipAd(){return !this.adPlaying||!this._currentAd?.isSkippable?false:Math.floor(this.audio.currentTime*1e3)>=this._currentAd.skipAfterSeconds*1e3}getAdSkipCountdownSeconds(){if(!this.adPlaying||!this._currentAd?.isSkippable)return null;let t=Math.floor(this.audio.currentTime*1e3),i=this._currentAd.skipAfterSeconds*1e3;return t>=i?0:Math.ceil((i-t)/1e3)}get voiceState(){return this._voiceState}controlPositionMs(){return this.activeContentKind===4?0:this.positionMsForAnalytics()}setupListeners(){this.transport.on("connected",()=>this.emit("connected")),this.transport.on("disconnected",t=>this.emit("disconnected",t)),this.transport.on("error",t=>this.emit("error",new N(t.message))),this.transport.on("message",t=>this.handleServerMessage(t)),this.audio.on("playing",()=>this.updateStatus("playing")),this.audio.on("paused",()=>this.updateStatus("paused")),this.audio.on("stopped",()=>{!this.adPlaying&&this._voiceState==="idle"&&this.updateStatus("idle");}),this.audio.on("loading",()=>this.updateStatus("loading")),this.audio.on("error",t=>{if(this.adPlaying){h("Ad playback error \u2014 waiting for next track",t);return}this.emit("error",new w(t));}),this.audio.on("timeupdate",t=>{this.emit("timeUpdate",t),this.adPlaying&&this._currentAd&&this.emitAdSkipUpdate(t.currentTime);}),this.audio.on("ended",()=>this.handleTrackEnded()),this.playlist.on("trackChanged",t=>this.emit("trackChange",t)),this.playlist.on("queueUpdated",t=>this.emit("queueUpdated",t)),this.voiceCapture.on("chunk",(t,i)=>{this.transport.sendVoice({action:2,audioData:t,mimeType:this.voiceMimeType,sequence:i,listenerId:this.voiceListenerId,deviceType:this.config.deviceType,gameContext:this.config.gameContext});}),this.voiceCapture.on("error",t=>{this.setVoiceState("error"),this.emit("error",new x(t.message,"VOICE_CAPTURE_FAILED"));}),this.voiceCapture.on("speechStart",()=>{this.emit("voiceSpeechStart");}),this.voiceCapture.on("speechEnd",()=>{this.emit("voiceSpeechEnd"),this.voiceAutoEndOnSilence&&this._voiceState==="listening"&&this.endVoiceHold();});}resolveVoiceOptions(t={}){return {...this.config.voice,...t}}connect(){this.transport.connect(this.config.apiKey,this.config.serverUrl);}buildInitExtras(){let t={};return this.config.gameContext?.trim()&&(t.gameContext=this.config.gameContext.trim()),this.config.deviceType?.trim()&&(t.deviceType=this.config.deviceType.trim()),t}async playSong(t){this.transport.isConnected||this.connect(),await this.transport.waitForConnection(),this.activeContentKind=1,this.transport.sendInit({contentKind:1,catalogTrackId:t.catalogTrackId,internalTrackId:t.internalTrackId,listenerId:t.listenerId,...this.buildInitExtras()});}async playPlaylist(t){this.transport.isConnected||this.connect(),await this.transport.waitForConnection(),this.activeContentKind=2,this.transport.sendInit({contentKind:2,playlistCode:t.playlistCode,listenerId:t.listenerId,...this.buildInitExtras()});}async playRadio(t={}){this.transport.isConnected||this.connect(),await this.transport.waitForConnection(),this.activeContentKind=4,this.transport.sendInit({contentKind:4,listenerId:t.listenerId,...this.buildInitExtras()});}async beginVoiceHold(t={}){if(this._voiceState==="listening"||this._voiceState==="processing"||this._voiceState==="responding")return;let i=this.resolveVoiceOptions(t);this.voiceAutoEndOnSilence=i.autoEndOnSilence!==false,this.transport.isConnected||this.connect(),await this.transport.waitForConnection(),this.voiceListenerId=i.listenerId?.trim()||void 0,this.pausedForVoice=this.status==="playing",this.pausedForVoice&&this.pause(),this.voiceResponsePlayer.stop(),this.voiceMimeType=await this.voiceCapture.start({maxDurationMs:i.maxDurationMs}),this.transport.sendVoice({action:1,mimeType:this.voiceMimeType,listenerId:this.voiceListenerId,...this.buildInitExtras()}),this.setVoiceState("listening");}async endVoiceHold(){this._voiceState==="listening"&&(await this.voiceCapture.stop(),this.transport.sendVoice({action:3,mimeType:this.voiceMimeType,listenerId:this.voiceListenerId,...this.buildInitExtras()}),this.setVoiceState("processing"));}cancelVoiceHold(){this._voiceState==="listening"&&(this.voiceCapture.cancel(),this.setVoiceState("idle"));}dismissVoiceAndResume(){this._voiceState==="listening"&&this.cancelVoiceHold(),this.pausedForVoice&&(this.resume(),this.pausedForVoice=false);}get isVoiceUiActive(){return this._voiceState==="listening"||this._voiceState==="processing"||this._voiceState==="responding"}pause(){this.audio.pause(),this.transport.sendControl({action:2,positionMs:this.controlPositionMs()});}resume(){this.audio.play(),this.transport.sendControl({action:1,positionMs:this.controlPositionMs()});}stop(){this.audio.stop(),this.transport.sendControl({action:3,positionMs:this.controlPositionMs()});}skip(){if(this.activeContentKind===4)return;if(this.adPlaying){this.skipAd();return}if(this.playlist.queueSnapshot.length>1){this.transport.sendControl({action:5,positionMs:this.controlPositionMs()}),this.updateStatus("loading");return}let t=this.playlist.next();t&&this.playSong(t.kind==="internal"?{internalTrackId:t.id}:{catalogTrackId:t.id});}previous(){if(this.activeContentKind===4)return;if(this.playlist.queueSnapshot.length>1){this.transport.sendControl({action:6,positionMs:this.controlPositionMs()}),this.updateStatus("loading");return}let t=this.playlist.previous();t&&this.playSong(t.kind==="internal"?{internalTrackId:t.id}:{catalogTrackId:t.id});}skipTo(t){if(this.activeContentKind===4)return;let i=this.playlist.skipTo(t);i&&this.playSong(i.kind==="internal"?{internalTrackId:i.id}:{catalogTrackId:i.id});}seek(t){this.activeContentKind===4||this.adPlaying||(this.audio.seek(t),this.transport.sendControl({action:4,positionMs:t}));}setVolume(t){this.volume=Math.max(0,Math.min(1,t)),this.audio.setVolume(this.volume);}positionMsForAnalytics(t){return typeof t=="number"?Math.max(0,Math.min(4294967295,Math.floor(t))):Math.max(0,Math.min(4294967295,Math.floor(this.audio.currentTime)))}emitAnalytics(t,i,n){this.transport.sendAnalytics({eventType:t,positionMs:this.positionMsForAnalytics(i),extraJson:n?JSON.stringify(n):void 0});}clearHeartbeat(){this.heartbeatTimer!==null&&(clearInterval(this.heartbeatTimer),this.heartbeatTimer=null);}startHeartbeat(t){this.clearHeartbeat();let i=Number(t);!i||i<1e3||(this.heartbeatTimer=setInterval(()=>{let n=this.activeContentKind===4?0:this.positionMsForAnalytics();this.emitAnalytics("heartbeat",n);},i));}applyContentSummary(t){let i=tt(t,this.activeContentKind);if(i){this.playlist.setQueue(i.tracks,i.currentIndex);return}t?.trim()&&h("Could not parse contentSummary; queue metadata unavailable.");}emitAdSkipUpdate(t){if(!this._currentAd)return;let i=this._currentAd.skipAfterSeconds*1e3,n=this._currentAd.isSkippable&&t>=i,o=n?0:Math.ceil((i-t)/1e3),s={ad:this._currentAd,canSkip:n,countdownSeconds:o};this.emit("adSkipUpdate",s);}setVoiceState(t){this._voiceState=t,this.emit("voiceStateChange",t);}handleVoiceAck(t){let i=t.status;if(i==="listening"){this.setVoiceState("listening");return}if(i==="processing"){this.setVoiceState("processing");return}if(i==="ready"){this.activeContentKind=2;let n={status:i,transcript:t.transcript,playlistCode:t.playlistCode,playlistName:t.playlistName};this.setVoiceState("ready"),this.emit("voiceResult",n);return}this.emit("voiceResult",{status:i,transcript:t.transcript,playlistCode:t.playlistCode,playlistName:t.playlistName});}async handleServerMessage(t){m("Received server message",t);let i=st(t);if(i){this.handleVoiceAck(i);return}let n=at(t);if(n){this._voiceState==="processing"&&this.setVoiceState("responding"),n.audioData.length>0&&this.voiceResponsePlayer.enqueueChunk(n.audioData,n.mimeType);return}let o=nt(t);if(o){await this.handleAdPlayback(o);return}let s=Z(t);if(s){await this.startContentPlayback(s);return}let a=t.error;if(a&&typeof a=="object"){let l=a,c=typeof l.message=="string"?l.message:"Unknown server error",p=typeof l.code=="string"?l.code:void 0;(this._voiceState==="processing"||this._voiceState==="listening"||this._voiceState==="responding")&&this.setVoiceState("error"),this.emit("error",new x(c,p));}}async startContentPlayback(t){if(this.adPlaying&&this._currentAd){let n=this._currentAd;this.adPlaying=false,this._currentAd=null,this.emit("adEnd",n);}else this.adPlaying=false,this._currentAd=null;(this._voiceState==="ready"||this._voiceState==="processing"||this._voiceState==="responding")&&this.setVoiceState("idle"),this.pausedForVoice=false,this.voiceResponsePlayer.stop(),m("Loading playback",{url:t.playbackUrl,isHls:t.isHls});let i=this.audio.load(t.playbackUrl,t.isHls);this.pendingPlaybackLoad=i;try{if(await i,this.pendingPlaybackLoad!==i)return;this.audio.play(),this.emitAnalytics("stream_start",this.activeContentKind===4?0:void 0),this.startHeartbeat(t.heartbeatIntervalMs),this.applyContentSummary(t.contentSummary);}catch(n){if(this.pendingPlaybackLoad!==i)return;this.emit("error",new w(n));}finally{this.pendingPlaybackLoad===i&&(this.pendingPlaybackLoad=null);}}async handleAdPlayback(t){this.pendingPlaybackLoad&&await this.pendingPlaybackLoad.catch(()=>{}),this.audio.stop(),this.adPlaying=true,this._currentAd={adId:t.adId,campaignId:t.campaignId,brandName:t.brandName,creativeName:t.creativeName,durationSeconds:t.durationSeconds,isSkippable:t.isSkippable,skipAfterSeconds:t.skipAfterSeconds,ctaType:t.ctaType,ctaValue:t.ctaValue,companionBannerUrl:t.companionBannerUrl,campaignName:t.campaignName},m("Loading ad playback",{url:t.playbackUrl,isHls:t.isHls});try{await this.audio.load(t.playbackUrl,t.isHls),this.audio.play(),this.emit("adStart",this._currentAd),this.emitAdSkipUpdate(0);}catch(i){let n=this._currentAd;this.adPlaying=false,this._currentAd=null,n&&this.emit("adEnd",n),h("Ad load failed",i),this.updateStatus("loading");}}skipAd(){if(!this.adPlaying||!this._currentAd||!this._currentAd.isSkippable)return;let t=Math.floor(this.audio.currentTime*1e3);if(t<this._currentAd.skipAfterSeconds*1e3)return;let i=this._currentAd;this.adPlaying=false,this._currentAd=null,this.audio.stop(),this.emit("adEnd",i),this.emitAnalytics("ad_skip",t),this.updateStatus("loading");}clickAd(){if(!this.adPlaying||!this._currentAd)return;let t=Math.floor(this.audio.currentTime*1e3);this.emitAnalytics("ad_cta_click",t),this._currentAd.ctaValue&&window.open(this._currentAd.ctaValue,"_blank");}handleTrackEnded(){if(this.activeContentKind!==4){if(this.adPlaying&&this._currentAd){let t=this._currentAd;this.audio.stop(),this.emitAnalytics("ad_complete",Math.floor(this.audio.currentTime*1e3)),this.emit("adEnd",t),this.adPlaying=false,this._currentAd=null,this.updateStatus("loading");return}if(this.playlist.queueSnapshot.length>1){this.emitAnalytics("track_complete",Math.floor(this.audio.duration*1e3)),this.updateStatus("loading");return}if(this.activeContentKind===1||this.activeContentKind===2){this.emitAnalytics("track_complete",Math.floor(this.audio.duration*1e3)),this.updateStatus("loading");return}this.updateStatus("idle");}}updateStatus(t){this.status=t,this.emit("stateChange",{status:t,currentTrack:this.playlist.getCurrentTrack(),currentTime:this.audio.currentTime,duration:this.audio.duration,volume:this.volume});}destroy(){this.clearHeartbeat(),this.cancelVoiceHold(),this.voiceResponsePlayer.stop(),this.audio.stop(),this.transport.disconnect(),this.playlist.reset(),this.removeAllListeners();}};async function K(r,e){let i=`${r.replace(/\/$/,"")}/radio/now-playing`;try{let n=await fetch(i,{...e,headers:{Accept:"application/json",...e?.headers}});if(!n.ok)return null;let s=(await n.json())?.data;return !s?.title||typeof s.title!="string"?null:{title:s.title,station:typeof s.station=="string"?s.station:void 0,isLive:typeof s.isLive=="boolean"?s.isLive:void 0}}catch{return null}}function d(r,e){let t=document.createElement(r);if(e?.className&&(t.className=e.className),e?.attrs)for(let[i,n]of Object.entries(e.attrs))t.setAttribute(i,n);return e?.style&&Object.assign(t.style,e.style),e?.text&&(t.textContent=e.text),e?.html&&(t.innerHTML=e.html),e?.onClick&&t.addEventListener("click",e.onClick),e?.children&&e.children.forEach(i=>t.appendChild(i)),t}function y(r,e=20){let t=document.createElementNS("http://www.w3.org/2000/svg","svg");t.setAttribute("width",String(e)),t.setAttribute("height",String(e)),t.setAttribute("viewBox","0 0 24 24"),t.setAttribute("fill","currentColor"),t.setAttribute("aria-hidden","true");let i=document.createElementNS("http://www.w3.org/2000/svg","path");return i.setAttribute("d",r),t.appendChild(i),t}var F="M8 5v14l11-7L8 5z",lt="M6 5h4v14H6V5zm8 0h4v14h-4V5z",k="M6 18l8.5-6L6 6v12zM16 6v12h2V6h-2z",dt="M6 6h2v12H6V6zm11.5 12L9 12l8.5-6v12z";function ct(){let r="synxed-web-player-styles";if(document.getElementById(r))return;let e=document.createElement("style");e.id=r,e.textContent=`
162
136
  @keyframes synxed-wp-spin { from { transform: rotate(0); } to { transform: rotate(360deg); } }
163
137
  @keyframes synxed-wp-vbar {
164
138
  0%, 100% { transform: scaleY(0.28); opacity: 0.45; }
165
139
  50% { transform: scaleY(1); opacity: 1; }
166
140
  }
167
- `,document.head.appendChild(e);}function lt(s){let e=[" \u2014 "," \u2013 "," - "," \u2014"," \u2013"," -"];for(let t of e){let i=s.indexOf(t);if(i>0)return {title:s.slice(0,i).trim(),artist:s.slice(i+t.length).trim()}}return {title:s.trim()}}function dt(s="bottom-center",e=16,t=16){let i={position:"fixed",zIndex:"50"};switch(s){case "top-left":return {...i,top:`${t}px`,left:`${e}px`};case "top-right":return {...i,top:`${t}px`,right:`${e}px`};case "bottom-left":return {...i,bottom:`${t}px`,left:`${e}px`};case "bottom-right":return {...i,bottom:`${t}px`,right:`${e}px`};default:return {...i,bottom:`${t}px`,left:"50%",transform:"translateX(-50%)"}}}function ct(s={}){return {accent:s.accent??"#22c55e",accentMuted:s.accentMuted??s.accent??"#22c55e",background:s.background??"#051107",backgroundInner:s.backgroundInner??"#0a1f10",border:s.border??"rgba(34, 197, 94, 0.35)",text:s.text??"#ffffff",textMuted:s.textMuted??"rgba(255,255,255,0.35)",stationText:s.stationText??"rgba(34, 197, 94, 0.85)",liveDot:s.liveDot??"#CCFF00",glow:s.glow??"rgba(34, 197, 94, 0.35)"}}function pt(s,e){s.style.setProperty("--sw-accent",e.accent),s.style.setProperty("--sw-accent-muted",e.accentMuted),s.style.setProperty("--sw-bg",e.background),s.style.setProperty("--sw-bg-inner",e.backgroundInner),s.style.setProperty("--sw-border",e.border),s.style.setProperty("--sw-text",e.text),s.style.setProperty("--sw-text-muted",e.textMuted),s.style.setProperty("--sw-station",e.stationText),s.style.setProperty("--sw-live",e.liveDot),s.style.setProperty("--sw-glow",e.glow);}var K="https://cdn.synxed.com/avater-image/avatar.svg",gt="https://cdn.synxed.com/avater-image/AI%20Star%20UI%20animation.gif",F=class s{constructor(e){this.engine=null;this.pollTimer=null;this.destroyed=false;this.isPlaying=false;this.currentTrack=null;this.nowPlaying=null;this.currentAd=null;this.skipBtn=null;this.avatarImgEl=null;this.avatarTextEl=null;this.avatarRing=null;this.titleEl=null;this.artistInlineEl=null;this.artistBlockEl=null;this.footerEl=null;this.playBtn=null;this.avatarVoiceHolding=false;this.suppressMiniClick=false;this.voiceAvatarPreview=false;this.voiceHoldActivated=false;this.voiceUiDismissed=false;this.voiceHoldTimer=null;this.defaultVoiceHoldMs=450;this.options={mode:"wide",attribution:"Synxed",nowPlayingPollMs:12e3,powerByLabel:"Powered by Synxed",enableVoice:true,...e},this.theme=ct(this.options.theme),this.ownsRoot=!e.container,this.root=e.container??document.createElement("div"),this.ownsRoot&&document.body.appendChild(this.root),ot(),this.mountShell(),this.initEngine(),this.options.source.type==="radio"&&this.startNowPlayingPoll();}static mount(e){return new s(e)}get player(){return this.engine}get element(){return this.root}destroy(){this.destroyed||(this.destroyed=true,this.stopNowPlayingPoll(),this.engine?.destroy(),this.engine=null,this.ownsRoot&&this.root.remove());}get voiceEnabled(){return this.options.enableVoice!==false}get isRadio(){return this.options.source.type==="radio"}get mode(){return this.options.mode??"wide"}mountShell(){let{position:e={},className:t,style:i}=this.options,n=e.placement??"bottom-center",o=e.offsetX??16,r=e.offsetY??(n==="bottom-center"?24:16);this.root.className=t??"",this.root.dataset.synxedWebPlayer=this.mode,pt(this.root,this.theme),Object.assign(this.root.style,dt(n,o,r)),i&&Object.assign(this.root.style,i),this.root.replaceChildren(),this.mode==="mini"?this.buildMini():this.mode==="large"?this.buildLarge():this.buildWide(),this.refreshLabels(),this.setPlayingVisual(this.isPlaying),this.options.draggable&&this.ownsRoot&&this.makeDraggable();}makeDraggable(){let e=false,t=false,i=0,n=0,o=0,r=0,a=u=>{let c=u,g=c.target;if(g.closest("[data-synxed-avatar-ring]")||this.avatarVoiceHolding||this.mode!=="mini"&&g.closest("button, a, input"))return;e=true,t=false;let b=this.root.getBoundingClientRect();o=b.left,r=b.top,this.root.style.bottom="auto",this.root.style.right="auto",this.root.style.transform="none",this.root.style.margin="0",this.root.style.left=`${o}px`,this.root.style.top=`${r}px`,"touches"in c?(i=c.touches[0].clientX,n=c.touches[0].clientY):(i=c.clientX,n=c.clientY),document.addEventListener("mousemove",l,{passive:false}),document.addEventListener("mouseup",h),document.addEventListener("touchmove",l,{passive:false}),document.addEventListener("touchend",h);},l=u=>{if(!e)return;u.preventDefault();let c=u,g,b;"touches"in c?(g=c.touches[0].clientX,b=c.touches[0].clientY):(g=c.clientX,b=c.clientY);let T=g-i,P=b-n;(Math.abs(T)>3||Math.abs(P)>3)&&(t=true),this.root.style.left=`${o+T}px`,this.root.style.top=`${r+P}px`;},h=()=>{e=false,document.removeEventListener("mousemove",l),document.removeEventListener("mouseup",h),document.removeEventListener("touchmove",l),document.removeEventListener("touchend",h),setTimeout(()=>{t=false;},0);};this.root.style.cursor="grab",this.root.addEventListener("mousedown",a),this.root.addEventListener("touchstart",a,{passive:false}),this.root.addEventListener("click",u=>{t&&(u.stopPropagation(),u.preventDefault());},true);}buildAvatar(e,t=false){let i=d("div",{style:{position:"relative",flexShrink:"0"}});this.avatarRing=d("div",{attrs:{"data-synxed-avatar-ring":"true"},style:{width:`${e}px`,height:`${e}px`,borderRadius:"50%",border:"3px solid var(--sw-accent)",padding:"3px",boxShadow:"0 0 24px var(--sw-glow), 0 0 48px rgba(0,0,0,0.25)",background:"var(--sw-bg)",boxSizing:"border-box"}});let n=d("div",{style:{width:"100%",height:"100%",borderRadius:"50%",background:"var(--sw-bg-inner)",overflow:"hidden"}});return this.avatarImgEl=d("img",{attrs:{src:K,alt:"Synxed DJ"},style:{width:"100%",height:"100%",objectFit:"cover",objectPosition:"top",transform:this.mode==="wide"?"scale(1.15)":"scale(1.12)",display:"block"}}),this.avatarTextEl=d("div",{text:"S",style:{width:"100%",height:"100%",display:"none",alignItems:"center",justifyContent:"center",color:"var(--sw-accent)",fontWeight:"900",fontSize:`${Math.round(e*.28)}px`}}),n.appendChild(this.avatarImgEl),n.appendChild(this.avatarTextEl),n.style.cursor=this.voiceEnabled?"pointer":"default",n.addEventListener("click",o=>{if(this.isVoiceUiOpen()){o.stopPropagation(),this.dismissVoiceUi();return}this.currentAd&&this.engine&&(o.stopPropagation(),this.engine.clickAd());}),this.voiceEnabled&&(this.avatarRing.style.touchAction="none",this.avatarRing.setAttribute("aria-label","Hold to speak to DJ")),this.avatarRing.appendChild(n),i.appendChild(this.avatarRing),i.appendChild(d("span",{style:{position:"absolute",...t?{top:"4px",left:"4px"}:{bottom:"6px",left:"6px"},width:t?"10px":"12px",height:t?"10px":"12px",borderRadius:"50%",background:"var(--sw-live)",border:"2px solid var(--sw-bg)",boxShadow:"0 0 8px var(--sw-live)"}})),i}buildMini(){let t=d("div",{attrs:{role:"button",tabindex:"0","aria-label":"Synxed mini player \u2014 tap to play, hold to speak","data-synxed-mini-shell":"true"},style:{position:"relative",padding:"0",cursor:"pointer",background:"transparent"}});t.addEventListener("keydown",i=>{i.key!=="Enter"&&i.key!==" "||(i.preventDefault(),!this.suppressMiniClick&&!this.avatarVoiceHolding&&this.handleMiniActivate());}),t.addEventListener("click",()=>{if(!this.suppressMiniClick){if(this.isVoiceUiOpen()){this.dismissVoiceUi();return}this.avatarVoiceHolding||this.handleMiniActivate();}}),t.appendChild(this.buildAvatar(72)),this.root.appendChild(t);}handleMiniActivate(){if(this.isVoiceUiOpen()){this.dismissVoiceUi();return}this.options.onMiniClick?this.options.onMiniClick():this.togglePlay();}buildWide(){let t="0 8px 40px var(--sw-glow), 0 0 0 1px var(--sw-border)";this.root.style.width="min(calc(100vw - 20px), 560px)";let i=d("div",{style:{position:"relative",display:"flex",alignItems:"center",width:"100%"}}),n=Math.max(90*.42,40);i.appendChild(d("div",{style:{position:"absolute",top:"8px",bottom:"8px",left:`${n}px`,right:"0",background:"var(--sw-bg)",border:"1px solid var(--sw-border)",borderRadius:"28px 20px 20px 28px",boxShadow:t,overflow:"hidden"},children:[d("div",{style:{position:"absolute",inset:"0",background:"linear-gradient(90deg, color-mix(in srgb, var(--sw-accent) 12%, transparent), transparent)",pointerEvents:"none"}})]}));let o=this.buildAvatar(90);Object.assign(o.style,{position:"relative",zIndex:"1",marginLeft:"-2px"}),i.appendChild(o);let r=d("div",{style:{position:"relative",zIndex:"1",flex:"1",minWidth:"0",marginLeft:"14px",padding:"18px 8px"}}),a=d("div",{style:{display:"flex",alignItems:"baseline",gap:"8px",overflow:"hidden"}});this.titleEl=d("h3",{style:{margin:"0",fontSize:"clamp(15px, 2.8vw, 20px)",fontWeight:"900",color:"var(--sw-text)",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}}),a.appendChild(this.titleEl),this.artistInlineEl=d("span",{style:{fontSize:"clamp(12px, 2.4vw, 15px)",fontWeight:"300",color:"var(--sw-text-muted)",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",display:"none"}}),a.appendChild(this.artistInlineEl),r.appendChild(a),this.footerEl=d("p",{style:{margin:"8px 0 0",fontSize:"9px",fontWeight:"700",color:"var(--sw-text-muted)",letterSpacing:"0.18em",textTransform:"uppercase",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}}),r.appendChild(this.footerEl),i.appendChild(r);let l=d("div",{style:{position:"relative",zIndex:"1",flexShrink:"0",display:"flex",alignItems:"center",gap:"14px",paddingRight:"16px"}});this.playBtn=this.createPlayButton(52),l.appendChild(this.playBtn),this.isRadio||(this.skipBtn=d("button",{attrs:{type:"button","aria-label":"Skip"},style:{border:"none",background:"transparent",color:"var(--sw-text-muted)",display:"flex",cursor:"pointer",fontSize:"13px",fontWeight:"bold"},onClick:()=>this.handleSkipClick(),children:[y(k,22)]}),l.appendChild(this.skipBtn)),l.appendChild(this.decoLines()),i.appendChild(l),this.root.appendChild(i);}buildLarge(){this.root.style.width="min(calc(100vw - 24px), 380px)";let t=d("div",{style:{borderRadius:"24px",border:"1px solid var(--sw-border)",background:"var(--sw-bg)",boxShadow:"0 8px 40px var(--sw-glow), 0 0 0 1px var(--sw-border)",padding:"16px",display:"flex",flexDirection:"column",gap:"14px",fontFamily:"system-ui, -apple-system, Segoe UI, Roboto, sans-serif"}}),i=d("div",{style:{display:"flex",gap:"12px",alignItems:"center",minWidth:"0"}});i.appendChild(this.buildAvatar(96,true));let n=d("div",{style:{minWidth:"0",flex:"1"}});this.titleEl=d("h3",{style:{margin:"0",fontSize:"18px",fontWeight:"900",color:"var(--sw-text)",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}}),n.appendChild(this.titleEl),this.artistBlockEl=d("p",{style:{margin:"6px 0 0",fontSize:"13px",fontWeight:"700",color:"var(--sw-accent-muted)",letterSpacing:"0.08em",textTransform:"uppercase",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",display:"none"}}),n.appendChild(this.artistBlockEl),this.footerEl=d("p",{style:{margin:"6px 0 0",fontSize:"10px",fontWeight:"700",color:"var(--sw-station)",letterSpacing:"0.18em",textTransform:"uppercase",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}}),n.appendChild(this.footerEl),i.appendChild(n),t.appendChild(i),t.appendChild(this.buildVisualizer()),t.appendChild(d("p",{text:this.options.powerByLabel??"Powered by Synxed",style:{margin:"0",fontSize:"9px",fontWeight:"600",color:"var(--sw-text-muted)",letterSpacing:"0.12em",textTransform:"uppercase",textAlign:"center"}}));let o=d("div",{style:{display:"flex",alignItems:"center",justifyContent:"center",gap:"18px"}});this.isRadio||o.appendChild(d("button",{attrs:{type:"button","aria-label":"Previous"},style:this.roundControlStyle(),onClick:()=>this.engine?.previous(),children:[y(at,22)]})),this.playBtn=this.createPlayButton(56),o.appendChild(this.playBtn),this.isRadio||(this.skipBtn=d("button",{attrs:{type:"button","aria-label":"Skip"},style:{...this.roundControlStyle(),fontSize:"12px",fontWeight:"bold"},onClick:()=>this.handleSkipClick(),children:[y(k,22)]}),o.appendChild(this.skipBtn)),t.appendChild(o),this.root.appendChild(t);}roundControlStyle(){return {width:"46px",height:"46px",borderRadius:"50%",border:"1px solid var(--sw-border)",background:"rgba(255,255,255,0.04)",color:"var(--sw-text)",display:"flex",alignItems:"center",justifyContent:"center",cursor:"pointer"}}createPlayButton(e){return d("button",{attrs:{type:"button","aria-label":"Play"},style:{width:`${e}px`,height:`${e}px`,borderRadius:"50%",border:"none",background:"var(--sw-accent)",color:"#0a0a0a",display:"flex",alignItems:"center",justifyContent:"center",cursor:"pointer",boxShadow:"0 0 18px var(--sw-glow)",flexShrink:"0"},onClick:()=>this.togglePlay(),children:[y(W,e>=56?22:20)]})}buildVisualizer(){let e=d("div",{style:{display:"flex",alignItems:"flex-end",gap:"4px",height:"52px",padding:"8px 4px",borderRadius:"14px",border:"1px solid var(--sw-border)",overflow:"hidden"}});for(let t=0;t<24;t++)e.appendChild(d("span",{style:{flex:"1",minWidth:"3px",height:"100%",borderRadius:"4px",background:"linear-gradient(180deg, var(--sw-accent), transparent)",transformOrigin:"center bottom",animation:`synxed-wp-vbar ${1+t%5*.12}s ease-in-out infinite`,animationDelay:`${t*.04}s`,opacity:"0.85"}}));return e}decoLines(){let e=d("div",{style:{display:"flex",flexDirection:"column",gap:"3px",opacity:"0.22"}});return e.appendChild(d("span",{style:{display:"block",width:"16px",height:"2px",borderRadius:"999px",background:"var(--sw-text)",transform:"translateX(3px)"}})),e.appendChild(d("span",{style:{display:"block",width:"16px",height:"2px",borderRadius:"999px",background:"var(--sw-text)"}})),e}initEngine(){let{apiKey:e,serverUrl:t,source:i}=this.options,n=new O({apiKey:e,serverUrl:t,autoConnect:true});this.engine=n;let o=a=>{this.isPlaying=a.status==="playing",a.currentTrack&&(this.currentTrack=a.currentTrack),this.setPlayingVisual(this.isPlaying),this.refreshLabels(),!this.currentAd&&!this.engine?.isAdPlaying&&(this.restoreTrackSkipButton(),this.refreshAvatarImage());};n.on("stateChange",o),n.on("trackChange",a=>{this.currentTrack=a,this.avatarImageBeforeAd=void 0,this.refreshLabels(),!this.currentAd&&!this.engine?.isAdPlaying&&(this.restoreTrackSkipButton(),this.refreshAvatarImage());}),n.on("adStart",a=>{this.avatarImageBeforeAd=this.getContentAvatarUrl(),this.voiceAvatarPreview=false,this.voiceHoldActivated=false,this.currentAd=a,this.refreshLabels(),this.updateAvatar();}),n.on("adSkipUpdate",a=>this.applyAdSkipUi(a)),n.on("adEnd",()=>{this.currentAd=null,this.voiceAvatarPreview=false,this.refreshLabels(),this.updateAvatar(),this.restoreTrackSkipButton();}),n.on("voiceStateChange",a=>this.applyVoiceVisual(a)),(i.type==="radio"?()=>n.playRadio():()=>n.playPlaylist({playlistCode:i.playlistCode}))().catch(()=>{}),this.voiceEnabled&&this.wireAvatarVoiceHold();}wireAvatarVoiceHold(){if(!this.avatarRing)return;let e=this.avatarRing,t=this.options.voiceHoldMs??this.defaultVoiceHoldMs,i=()=>{this.voiceHoldTimer!==null&&(clearTimeout(this.voiceHoldTimer),this.voiceHoldTimer=null);},n=a=>{if(!(this.currentAd||!this.engine)){if(this.isVoiceUiOpen()){a.preventDefault(),a.stopPropagation(),this.dismissVoiceUi();return}a.preventDefault(),a.stopPropagation(),e.setPointerCapture(a.pointerId),this.avatarVoiceHolding=true,this.voiceHoldActivated=false,i(),this.voiceHoldTimer=setTimeout(()=>{this.voiceHoldTimer=null,!(!this.avatarVoiceHolding||!this.engine)&&(this.voiceHoldActivated=true,this.voiceUiDismissed=false,this.voiceAvatarPreview=true,this.refreshAvatarImage(),this.engine.beginVoiceHold({listenerId:this.options.listenerId}).catch(()=>{this.resetVoiceHoldState();}));},t);}},o=a=>{this.currentAd||a.stopPropagation();};e.addEventListener("mousedown",o),e.addEventListener("touchstart",o,{passive:false});let r=()=>{if(i(),!this.avatarVoiceHolding||(this.avatarVoiceHolding=false,!this.voiceHoldActivated))return;this.mode==="mini"&&(this.suppressMiniClick=true,setTimeout(()=>{this.suppressMiniClick=false;},320)),this.engine?.voiceState==="listening"&&this.engine?.endVoiceHold();};e.addEventListener("pointerdown",n),e.addEventListener("pointerup",r),e.addEventListener("pointerleave",r),e.addEventListener("pointercancel",r);}isVoiceUiOpen(){return !this.voiceEnabled||this.currentAd||this.voiceUiDismissed?false:this.voiceHoldActivated||this.voiceAvatarPreview?true:!!this.engine?.isVoiceUiActive}dismissVoiceUi(){this.engine?.dismissVoiceAndResume(),this.resetVoiceHoldState(),this.voiceUiDismissed=true,this.applyVoiceVisual(this.engine?.voiceState??"idle"),this.refreshAvatarImage();}resetVoiceHoldState(){this.voiceHoldTimer!==null&&(clearTimeout(this.voiceHoldTimer),this.voiceHoldTimer=null),this.avatarVoiceHolding=false,this.voiceHoldActivated=false,this.voiceAvatarPreview=false;}applyVoiceVisual(e){this.avatarRing&&((e==="idle"||e==="ready"||e==="error")&&(this.avatarVoiceHolding||(this.voiceAvatarPreview=false),(e==="ready"||e==="idle")&&(this.voiceUiDismissed=false)),(e==="listening"||e==="processing"||e==="responding")&&(this.voiceUiDismissed=false),e==="listening"?(this.avatarRing.style.animation="",this.avatarRing.style.borderColor="#3b82f6",this.avatarRing.style.boxShadow="0 0 20px rgba(59,130,246,0.55), 0 0 40px rgba(59,130,246,0.25)"):e==="processing"?(this.avatarRing.style.animation="",this.avatarRing.style.borderColor="#ef4444",this.avatarRing.style.boxShadow="0 0 20px rgba(239,68,68,0.5), 0 0 40px rgba(239,68,68,0.2)"):e==="responding"?(this.avatarRing.style.animation="",this.avatarRing.style.borderColor="#06b6d4",this.avatarRing.style.boxShadow="0 0 20px rgba(6,182,212,0.5), 0 0 40px rgba(6,182,212,0.2)"):(this.avatarRing.style.borderColor="",this.avatarRing.style.boxShadow="0 0 24px var(--sw-glow), 0 0 48px rgba(0,0,0,0.25)",this.setPlayingVisual(this.isPlaying)),this.refreshAvatarImage());}isVoiceAvatarActive(){if(!this.voiceEnabled||this.currentAd||this.voiceUiDismissed)return false;if(this.voiceAvatarPreview)return true;let e=this.engine?.voiceState;return e==="listening"||e==="processing"||e==="responding"}getContentAvatarUrl(){return K}getAvatarImageUrl(){return this.currentAd?.companionBannerUrl?this.currentAd.companionBannerUrl:this.isVoiceAvatarActive()?gt:this.avatarImageBeforeAd?this.avatarImageBeforeAd:K}refreshAvatarImage(){let e=this.getAvatarImageUrl(),t=this.isVoiceAvatarActive();e&&this.avatarImgEl?(this.avatarImgEl.getAttribute("src")!==e&&this.avatarImgEl.setAttribute("src",e),this.avatarImgEl.style.display="block",t?(this.avatarImgEl.style.objectFit="cover",this.avatarImgEl.style.objectPosition="center",this.avatarImgEl.style.transform="scale(1)",this.avatarImgEl.style.padding="",this.avatarImgEl.style.background="var(--sw-bg-inner)"):(this.avatarImgEl.style.objectFit="cover",this.avatarImgEl.style.objectPosition="top",this.avatarImgEl.style.transform=this.mode==="wide"?"scale(1.15)":"scale(1.12)",this.avatarImgEl.style.padding="",this.avatarImgEl.style.background=""),this.avatarTextEl&&(this.avatarTextEl.style.display="none")):(this.avatarImgEl&&(this.avatarImgEl.style.display="none"),this.avatarTextEl&&(this.avatarTextEl.style.display="flex"));}startNowPlayingPoll(){let e=async()=>{let t=await B(this.options.serverUrl);!this.destroyed&&t&&(this.nowPlaying=t,this.refreshLabels());};e(),this.pollTimer=setInterval(e,this.options.nowPlayingPollMs??12e3);}stopNowPlayingPoll(){this.pollTimer!==null&&(clearInterval(this.pollTimer),this.pollTimer=null);}handleSkipClick(){let e=this.engine;if(e){if(this.currentAd){e.canSkipAd()&&e.skipAd();return}e.skip();}}applyAdSkipUi(e){if(!this.skipBtn)return;let{ad:t,canSkip:i,countdownSeconds:n}=e;if(!t.isSkippable){this.skipBtn.disabled=true,this.skipBtn.textContent="",this.skipBtn.replaceChildren(y(k,22));return}if(!i){this.skipBtn.disabled=true,this.skipBtn.replaceChildren(),this.skipBtn.textContent=`${n}s`;return}this.skipBtn.disabled=false,this.skipBtn.textContent="",this.skipBtn.replaceChildren(y(k,22));}restoreTrackSkipButton(){this.skipBtn&&(this.skipBtn.disabled=false,this.skipBtn.textContent="",this.skipBtn.replaceChildren(y(k,22)),this.skipBtn.setAttribute("aria-label","Skip"));}displayLine(){return this.currentAd?{title:this.currentAd.campaignName||"Advertisement",artist:this.currentAd.creativeName}:this.isRadio&&this.nowPlaying?.title?lt(this.nowPlaying.title):this.currentTrack?.title?{title:this.currentTrack.title,artist:this.currentTrack.artist}:{title:"Loading\u2026"}}refreshLabels(){let e=this.displayLine();if(this.titleEl&&(this.titleEl.textContent=e.title),this.artistInlineEl){let t=!!e.artist;this.artistInlineEl.style.display=t?"inline":"none",t&&(this.artistInlineEl.textContent=e.artist);}if(this.artistBlockEl){let t=!!e.artist;this.artistBlockEl.style.display=t?"block":"none",t&&(this.artistBlockEl.textContent=e.artist);}if(this.footerEl)if(this.currentAd)this.footerEl.textContent="Advertisement \xB7 Synxed Player";else {let t=this.isRadio&&(this.nowPlaying?.station??this.currentTrack?.title??"Synxed Radio");this.footerEl.textContent=t&&this.isRadio?`${t} \xB7 Synxed Player`:"Synxed Player";}}updateAvatar(){if(this.refreshAvatarImage(),this.avatarRing){let e=this.avatarRing.firstChild;e&&(e.style.cursor=this.currentAd||this.voiceEnabled?"pointer":"default");}}setPlayingVisual(e){this.avatarRing&&(this.avatarRing.style.animation=e?"synxed-wp-spin 4s linear infinite":""),this.playBtn&&(this.playBtn.replaceChildren(y(e?rt:W,20)),this.playBtn.setAttribute("aria-label",e?"Pause":"Play"));}togglePlay(){this.engine&&(this.isPlaying?this.engine.pause():this.engine.resume());}};
168
- exports.ContentKind=I;exports.ErrorCode=j;exports.SdkVoiceAction=D;exports.SynxedConnectionError=V;exports.SynxedError=x;exports.SynxedPlaybackError=E;exports.SynxedPlayer=O;exports.SynxedProtocolError=X;exports.SynxedWebPlayer=F;exports.TransportManager=w;exports.VoiceCaptureManager=A;exports.buildSdkWebSocketUrl=Y;exports.fetchRadioNowPlaying=B;//# sourceMappingURL=index.js.map
141
+ `,document.head.appendChild(e);}function pt(r){let e=[" \u2014 "," \u2013 "," - "," \u2014"," \u2013"," -"];for(let t of e){let i=r.indexOf(t);if(i>0)return {title:r.slice(0,i).trim(),artist:r.slice(i+t.length).trim()}}return {title:r.trim()}}function ut(r="bottom-center",e=16,t=16){let i={position:"fixed",zIndex:"50"};switch(r){case "top-left":return {...i,top:`${t}px`,left:`${e}px`};case "top-right":return {...i,top:`${t}px`,right:`${e}px`};case "bottom-left":return {...i,bottom:`${t}px`,left:`${e}px`};case "bottom-right":return {...i,bottom:`${t}px`,right:`${e}px`};default:return {...i,bottom:`${t}px`,left:"50%",transform:"translateX(-50%)"}}}function ht(r={}){return {accent:r.accent??"#22c55e",accentMuted:r.accentMuted??r.accent??"#22c55e",background:r.background??"#051107",backgroundInner:r.backgroundInner??"#0a1f10",border:r.border??"rgba(34, 197, 94, 0.35)",text:r.text??"#ffffff",textMuted:r.textMuted??"rgba(255,255,255,0.35)",stationText:r.stationText??"rgba(34, 197, 94, 0.85)",liveDot:r.liveDot??"#CCFF00",glow:r.glow??"rgba(34, 197, 94, 0.35)"}}function mt(r,e){r.style.setProperty("--sw-accent",e.accent),r.style.setProperty("--sw-accent-muted",e.accentMuted),r.style.setProperty("--sw-bg",e.background),r.style.setProperty("--sw-bg-inner",e.backgroundInner),r.style.setProperty("--sw-border",e.border),r.style.setProperty("--sw-text",e.text),r.style.setProperty("--sw-text-muted",e.textMuted),r.style.setProperty("--sw-station",e.stationText),r.style.setProperty("--sw-live",e.liveDot),r.style.setProperty("--sw-glow",e.glow);}var z="https://cdn.synxed.com/avater-image/avatar.svg",xt="https://cdn.synxed.com/avater-image/AI%20Star%20UI%20animation.gif",q=class r{constructor(e){this.engine=null;this.pollTimer=null;this.destroyed=false;this.isPlaying=false;this.currentTrack=null;this.nowPlaying=null;this.currentAd=null;this.skipBtn=null;this.avatarImgEl=null;this.avatarTextEl=null;this.avatarRing=null;this.titleEl=null;this.artistInlineEl=null;this.artistBlockEl=null;this.footerEl=null;this.playBtn=null;this.avatarVoiceHolding=false;this.suppressMiniClick=false;this.voiceAvatarPreview=false;this.voiceHoldActivated=false;this.voiceUiDismissed=false;this.voiceHoldTimer=null;this.defaultVoiceHoldMs=450;this.options={mode:"wide",attribution:"Synxed",nowPlayingPollMs:12e3,powerByLabel:"Powered by Synxed",enableVoice:true,...e},this.theme=ht(this.options.theme),this.ownsRoot=!e.container,this.root=e.container??document.createElement("div"),this.ownsRoot&&document.body.appendChild(this.root),ct(),this.mountShell(),this.initEngine(),this.options.source.type==="radio"&&this.startNowPlayingPoll();}static mount(e){return new r(e)}get player(){return this.engine}get element(){return this.root}destroy(){this.destroyed||(this.destroyed=true,this.stopNowPlayingPoll(),this.engine?.destroy(),this.engine=null,this.ownsRoot&&this.root.remove());}get voiceEnabled(){return this.options.enableVoice!==false}get isRadio(){return this.options.source.type==="radio"}get mode(){return this.options.mode??"wide"}mountShell(){let{position:e={},className:t,style:i}=this.options,n=e.placement??"bottom-center",o=e.offsetX??16,s=e.offsetY??(n==="bottom-center"?24:16);this.root.className=t??"",this.root.dataset.synxedWebPlayer=this.mode,mt(this.root,this.theme),Object.assign(this.root.style,ut(n,o,s)),i&&Object.assign(this.root.style,i),this.root.replaceChildren(),this.mode==="mini"?this.buildMini():this.mode==="large"?this.buildLarge():this.buildWide(),this.refreshLabels(),this.setPlayingVisual(this.isPlaying),this.options.draggable&&this.ownsRoot&&this.makeDraggable();}makeDraggable(){let e=false,t=false,i=0,n=0,o=0,s=0,a=p=>{let u=p,g=u.target;if(g.closest("[data-synxed-avatar-ring]")||this.avatarVoiceHolding||this.mode!=="mini"&&g.closest("button, a, input"))return;e=true,t=false;let b=this.root.getBoundingClientRect();o=b.left,s=b.top,this.root.style.bottom="auto",this.root.style.right="auto",this.root.style.transform="none",this.root.style.margin="0",this.root.style.left=`${o}px`,this.root.style.top=`${s}px`,"touches"in u?(i=u.touches[0].clientX,n=u.touches[0].clientY):(i=u.clientX,n=u.clientY),document.addEventListener("mousemove",l,{passive:false}),document.addEventListener("mouseup",c),document.addEventListener("touchmove",l,{passive:false}),document.addEventListener("touchend",c);},l=p=>{if(!e)return;p.preventDefault();let u=p,g,b;"touches"in u?(g=u.touches[0].clientX,b=u.touches[0].clientY):(g=u.clientX,b=u.clientY);let T=g-i,I=b-n;(Math.abs(T)>3||Math.abs(I)>3)&&(t=true),this.root.style.left=`${o+T}px`,this.root.style.top=`${s+I}px`;},c=()=>{e=false,document.removeEventListener("mousemove",l),document.removeEventListener("mouseup",c),document.removeEventListener("touchmove",l),document.removeEventListener("touchend",c),setTimeout(()=>{t=false;},0);};this.root.style.cursor="grab",this.root.addEventListener("mousedown",a),this.root.addEventListener("touchstart",a,{passive:false}),this.root.addEventListener("click",p=>{t&&(p.stopPropagation(),p.preventDefault());},true);}buildAvatar(e,t=false){let i=d("div",{style:{position:"relative",flexShrink:"0"}});this.avatarRing=d("div",{attrs:{"data-synxed-avatar-ring":"true"},style:{width:`${e}px`,height:`${e}px`,borderRadius:"50%",border:"3px solid var(--sw-accent)",padding:"3px",boxShadow:"0 0 24px var(--sw-glow), 0 0 48px rgba(0,0,0,0.25)",background:"var(--sw-bg)",boxSizing:"border-box"}});let n=d("div",{style:{width:"100%",height:"100%",borderRadius:"50%",background:"var(--sw-bg-inner)",overflow:"hidden"}});return this.avatarImgEl=d("img",{attrs:{src:z,alt:"Synxed DJ"},style:{width:"100%",height:"100%",objectFit:"cover",objectPosition:"top",transform:this.mode==="wide"?"scale(1.15)":"scale(1.12)",display:"block"}}),this.avatarTextEl=d("div",{text:"S",style:{width:"100%",height:"100%",display:"none",alignItems:"center",justifyContent:"center",color:"var(--sw-accent)",fontWeight:"900",fontSize:`${Math.round(e*.28)}px`}}),n.appendChild(this.avatarImgEl),n.appendChild(this.avatarTextEl),n.style.cursor=this.voiceEnabled?"pointer":"default",n.addEventListener("click",o=>{if(this.isVoiceUiOpen()){o.stopPropagation(),this.dismissVoiceUi();return}this.currentAd&&this.engine&&(o.stopPropagation(),this.engine.clickAd());}),this.voiceEnabled&&(this.avatarRing.style.touchAction="none",this.avatarRing.setAttribute("aria-label","Hold to speak to DJ")),this.avatarRing.appendChild(n),i.appendChild(this.avatarRing),i.appendChild(d("span",{style:{position:"absolute",...t?{top:"4px",left:"4px"}:{bottom:"6px",left:"6px"},width:t?"10px":"12px",height:t?"10px":"12px",borderRadius:"50%",background:"var(--sw-live)",border:"2px solid var(--sw-bg)",boxShadow:"0 0 8px var(--sw-live)"}})),i}buildMini(){let t=d("div",{attrs:{role:"button",tabindex:"0","aria-label":"Synxed mini player \u2014 tap to play, hold to speak","data-synxed-mini-shell":"true"},style:{position:"relative",padding:"0",cursor:"pointer",background:"transparent"}});t.addEventListener("keydown",i=>{i.key!=="Enter"&&i.key!==" "||(i.preventDefault(),!this.suppressMiniClick&&!this.avatarVoiceHolding&&this.handleMiniActivate());}),t.addEventListener("click",()=>{if(!this.suppressMiniClick){if(this.isVoiceUiOpen()){this.dismissVoiceUi();return}this.avatarVoiceHolding||this.handleMiniActivate();}}),t.appendChild(this.buildAvatar(72)),this.root.appendChild(t);}handleMiniActivate(){if(this.isVoiceUiOpen()){this.dismissVoiceUi();return}this.options.onMiniClick?this.options.onMiniClick():this.togglePlay();}buildWide(){let t="0 8px 40px var(--sw-glow), 0 0 0 1px var(--sw-border)";this.root.style.width="min(calc(100vw - 20px), 560px)";let i=d("div",{style:{position:"relative",display:"flex",alignItems:"center",width:"100%"}}),n=Math.max(90*.42,40);i.appendChild(d("div",{style:{position:"absolute",top:"8px",bottom:"8px",left:`${n}px`,right:"0",background:"var(--sw-bg)",border:"1px solid var(--sw-border)",borderRadius:"28px 20px 20px 28px",boxShadow:t,overflow:"hidden"},children:[d("div",{style:{position:"absolute",inset:"0",background:"linear-gradient(90deg, color-mix(in srgb, var(--sw-accent) 12%, transparent), transparent)",pointerEvents:"none"}})]}));let o=this.buildAvatar(90);Object.assign(o.style,{position:"relative",zIndex:"1",marginLeft:"-2px"}),i.appendChild(o);let s=d("div",{style:{position:"relative",zIndex:"1",flex:"1",minWidth:"0",marginLeft:"14px",padding:"18px 8px"}}),a=d("div",{style:{display:"flex",alignItems:"baseline",gap:"8px",overflow:"hidden"}});this.titleEl=d("h3",{style:{margin:"0",fontSize:"clamp(15px, 2.8vw, 20px)",fontWeight:"900",color:"var(--sw-text)",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}}),a.appendChild(this.titleEl),this.artistInlineEl=d("span",{style:{fontSize:"clamp(12px, 2.4vw, 15px)",fontWeight:"300",color:"var(--sw-text-muted)",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",display:"none"}}),a.appendChild(this.artistInlineEl),s.appendChild(a),this.footerEl=d("p",{style:{margin:"8px 0 0",fontSize:"9px",fontWeight:"700",color:"var(--sw-text-muted)",letterSpacing:"0.18em",textTransform:"uppercase",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}}),s.appendChild(this.footerEl),i.appendChild(s);let l=d("div",{style:{position:"relative",zIndex:"1",flexShrink:"0",display:"flex",alignItems:"center",gap:"14px",paddingRight:"16px"}});this.playBtn=this.createPlayButton(52),l.appendChild(this.playBtn),this.isRadio||(this.skipBtn=d("button",{attrs:{type:"button","aria-label":"Skip"},style:{border:"none",background:"transparent",color:"var(--sw-text-muted)",display:"flex",cursor:"pointer",fontSize:"13px",fontWeight:"bold"},onClick:()=>this.handleSkipClick(),children:[y(k,22)]}),l.appendChild(this.skipBtn)),l.appendChild(this.decoLines()),i.appendChild(l),this.root.appendChild(i);}buildLarge(){this.root.style.width="min(calc(100vw - 24px), 380px)";let t=d("div",{style:{borderRadius:"24px",border:"1px solid var(--sw-border)",background:"var(--sw-bg)",boxShadow:"0 8px 40px var(--sw-glow), 0 0 0 1px var(--sw-border)",padding:"16px",display:"flex",flexDirection:"column",gap:"14px",fontFamily:"system-ui, -apple-system, Segoe UI, Roboto, sans-serif"}}),i=d("div",{style:{display:"flex",gap:"12px",alignItems:"center",minWidth:"0"}});i.appendChild(this.buildAvatar(96,true));let n=d("div",{style:{minWidth:"0",flex:"1"}});this.titleEl=d("h3",{style:{margin:"0",fontSize:"18px",fontWeight:"900",color:"var(--sw-text)",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}}),n.appendChild(this.titleEl),this.artistBlockEl=d("p",{style:{margin:"6px 0 0",fontSize:"13px",fontWeight:"700",color:"var(--sw-accent-muted)",letterSpacing:"0.08em",textTransform:"uppercase",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",display:"none"}}),n.appendChild(this.artistBlockEl),this.footerEl=d("p",{style:{margin:"6px 0 0",fontSize:"10px",fontWeight:"700",color:"var(--sw-station)",letterSpacing:"0.18em",textTransform:"uppercase",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}}),n.appendChild(this.footerEl),i.appendChild(n),t.appendChild(i),t.appendChild(this.buildVisualizer()),t.appendChild(d("p",{text:this.options.powerByLabel??"Powered by Synxed",style:{margin:"0",fontSize:"9px",fontWeight:"600",color:"var(--sw-text-muted)",letterSpacing:"0.12em",textTransform:"uppercase",textAlign:"center"}}));let o=d("div",{style:{display:"flex",alignItems:"center",justifyContent:"center",gap:"18px"}});this.isRadio||o.appendChild(d("button",{attrs:{type:"button","aria-label":"Previous"},style:this.roundControlStyle(),onClick:()=>this.engine?.previous(),children:[y(dt,22)]})),this.playBtn=this.createPlayButton(56),o.appendChild(this.playBtn),this.isRadio||(this.skipBtn=d("button",{attrs:{type:"button","aria-label":"Skip"},style:{...this.roundControlStyle(),fontSize:"12px",fontWeight:"bold"},onClick:()=>this.handleSkipClick(),children:[y(k,22)]}),o.appendChild(this.skipBtn)),t.appendChild(o),this.root.appendChild(t);}roundControlStyle(){return {width:"46px",height:"46px",borderRadius:"50%",border:"1px solid var(--sw-border)",background:"rgba(255,255,255,0.04)",color:"var(--sw-text)",display:"flex",alignItems:"center",justifyContent:"center",cursor:"pointer"}}createPlayButton(e){return d("button",{attrs:{type:"button","aria-label":"Play"},style:{width:`${e}px`,height:`${e}px`,borderRadius:"50%",border:"none",background:"var(--sw-accent)",color:"#0a0a0a",display:"flex",alignItems:"center",justifyContent:"center",cursor:"pointer",boxShadow:"0 0 18px var(--sw-glow)",flexShrink:"0"},onClick:()=>this.togglePlay(),children:[y(F,e>=56?22:20)]})}buildVisualizer(){let e=d("div",{style:{display:"flex",alignItems:"flex-end",gap:"4px",height:"52px",padding:"8px 4px",borderRadius:"14px",border:"1px solid var(--sw-border)",overflow:"hidden"}});for(let t=0;t<24;t++)e.appendChild(d("span",{style:{flex:"1",minWidth:"3px",height:"100%",borderRadius:"4px",background:"linear-gradient(180deg, var(--sw-accent), transparent)",transformOrigin:"center bottom",animation:`synxed-wp-vbar ${1+t%5*.12}s ease-in-out infinite`,animationDelay:`${t*.04}s`,opacity:"0.85"}}));return e}decoLines(){let e=d("div",{style:{display:"flex",flexDirection:"column",gap:"3px",opacity:"0.22"}});return e.appendChild(d("span",{style:{display:"block",width:"16px",height:"2px",borderRadius:"999px",background:"var(--sw-text)",transform:"translateX(3px)"}})),e.appendChild(d("span",{style:{display:"block",width:"16px",height:"2px",borderRadius:"999px",background:"var(--sw-text)"}})),e}initEngine(){let{apiKey:e,serverUrl:t,source:i}=this.options,n=new L({apiKey:e,serverUrl:t,autoConnect:true,debug:this.options.debug,voice:this.options.voice});this.engine=n;let o=a=>{this.isPlaying=a.status==="playing",a.currentTrack&&(this.currentTrack=a.currentTrack),this.setPlayingVisual(this.isPlaying),this.refreshLabels(),!this.currentAd&&!this.engine?.isAdPlaying&&(this.restoreTrackSkipButton(),this.refreshAvatarImage());};n.on("stateChange",o),n.on("trackChange",a=>{this.currentTrack=a,this.avatarImageBeforeAd=void 0,this.refreshLabels(),!this.currentAd&&!this.engine?.isAdPlaying&&(this.restoreTrackSkipButton(),this.refreshAvatarImage());}),n.on("adStart",a=>{this.avatarImageBeforeAd=this.getContentAvatarUrl(),this.voiceAvatarPreview=false,this.voiceHoldActivated=false,this.currentAd=a,this.refreshLabels(),this.updateAvatar();}),n.on("adSkipUpdate",a=>this.applyAdSkipUi(a)),n.on("adEnd",()=>{this.currentAd=null,this.voiceAvatarPreview=false,this.refreshLabels(),this.updateAvatar(),this.restoreTrackSkipButton();}),n.on("voiceStateChange",a=>this.applyVoiceVisual(a)),(i.type==="radio"?()=>n.playRadio():()=>n.playPlaylist({playlistCode:i.playlistCode}))().catch(()=>{}),this.voiceEnabled&&this.wireAvatarVoiceHold();}wireAvatarVoiceHold(){if(!this.avatarRing)return;let e=this.avatarRing,t=this.options.voiceHoldMs??this.defaultVoiceHoldMs,i=()=>{this.voiceHoldTimer!==null&&(clearTimeout(this.voiceHoldTimer),this.voiceHoldTimer=null);},n=a=>{if(!(this.currentAd||!this.engine)){if(this.isVoiceUiOpen()){a.preventDefault(),a.stopPropagation(),this.dismissVoiceUi();return}a.preventDefault(),a.stopPropagation(),e.setPointerCapture(a.pointerId),this.avatarVoiceHolding=true,this.voiceHoldActivated=false,i(),this.voiceHoldTimer=setTimeout(()=>{this.voiceHoldTimer=null,!(!this.avatarVoiceHolding||!this.engine)&&(this.voiceHoldActivated=true,this.voiceUiDismissed=false,this.voiceAvatarPreview=true,this.refreshAvatarImage(),this.engine.beginVoiceHold({listenerId:this.options.listenerId}).catch(()=>{this.resetVoiceHoldState();}));},t);}},o=a=>{this.currentAd||a.stopPropagation();};e.addEventListener("mousedown",o),e.addEventListener("touchstart",o,{passive:false});let s=()=>{if(i(),!this.avatarVoiceHolding||(this.avatarVoiceHolding=false,!this.voiceHoldActivated))return;this.mode==="mini"&&(this.suppressMiniClick=true,setTimeout(()=>{this.suppressMiniClick=false;},320)),this.engine?.voiceState==="listening"&&this.engine?.endVoiceHold();};e.addEventListener("pointerdown",n),e.addEventListener("pointerup",s),e.addEventListener("pointerleave",s),e.addEventListener("pointercancel",s);}isVoiceUiOpen(){return !this.voiceEnabled||this.currentAd||this.voiceUiDismissed?false:this.voiceHoldActivated||this.voiceAvatarPreview?true:!!this.engine?.isVoiceUiActive}dismissVoiceUi(){this.engine?.dismissVoiceAndResume(),this.resetVoiceHoldState(),this.voiceUiDismissed=true,this.applyVoiceVisual(this.engine?.voiceState??"idle"),this.refreshAvatarImage();}resetVoiceHoldState(){this.voiceHoldTimer!==null&&(clearTimeout(this.voiceHoldTimer),this.voiceHoldTimer=null),this.avatarVoiceHolding=false,this.voiceHoldActivated=false,this.voiceAvatarPreview=false;}applyVoiceVisual(e){this.avatarRing&&((e==="idle"||e==="ready"||e==="error")&&(this.avatarVoiceHolding||(this.voiceAvatarPreview=false),(e==="ready"||e==="idle")&&(this.voiceUiDismissed=false)),(e==="listening"||e==="processing"||e==="responding")&&(this.voiceUiDismissed=false),e==="listening"?(this.avatarRing.style.animation="",this.avatarRing.style.borderColor="#3b82f6",this.avatarRing.style.boxShadow="0 0 20px rgba(59,130,246,0.55), 0 0 40px rgba(59,130,246,0.25)"):e==="processing"?(this.avatarRing.style.animation="",this.avatarRing.style.borderColor="#ef4444",this.avatarRing.style.boxShadow="0 0 20px rgba(239,68,68,0.5), 0 0 40px rgba(239,68,68,0.2)"):e==="responding"?(this.avatarRing.style.animation="",this.avatarRing.style.borderColor="#06b6d4",this.avatarRing.style.boxShadow="0 0 20px rgba(6,182,212,0.5), 0 0 40px rgba(6,182,212,0.2)"):(this.avatarRing.style.borderColor="",this.avatarRing.style.boxShadow="0 0 24px var(--sw-glow), 0 0 48px rgba(0,0,0,0.25)",this.setPlayingVisual(this.isPlaying)),this.refreshAvatarImage());}isVoiceAvatarActive(){if(!this.voiceEnabled||this.currentAd||this.voiceUiDismissed)return false;if(this.voiceAvatarPreview)return true;let e=this.engine?.voiceState;return e==="listening"||e==="processing"||e==="responding"}getContentAvatarUrl(){return z}getAvatarImageUrl(){return this.currentAd?.companionBannerUrl?this.currentAd.companionBannerUrl:this.isVoiceAvatarActive()?xt:this.avatarImageBeforeAd?this.avatarImageBeforeAd:z}refreshAvatarImage(){let e=this.getAvatarImageUrl(),t=this.isVoiceAvatarActive();e&&this.avatarImgEl?(this.avatarImgEl.getAttribute("src")!==e&&this.avatarImgEl.setAttribute("src",e),this.avatarImgEl.style.display="block",t?(this.avatarImgEl.style.objectFit="cover",this.avatarImgEl.style.objectPosition="center",this.avatarImgEl.style.transform="scale(1)",this.avatarImgEl.style.padding="",this.avatarImgEl.style.background="var(--sw-bg-inner)"):(this.avatarImgEl.style.objectFit="cover",this.avatarImgEl.style.objectPosition="top",this.avatarImgEl.style.transform=this.mode==="wide"?"scale(1.15)":"scale(1.12)",this.avatarImgEl.style.padding="",this.avatarImgEl.style.background=""),this.avatarTextEl&&(this.avatarTextEl.style.display="none")):(this.avatarImgEl&&(this.avatarImgEl.style.display="none"),this.avatarTextEl&&(this.avatarTextEl.style.display="flex"));}startNowPlayingPoll(){let e=async()=>{let t=await K(this.options.serverUrl);!this.destroyed&&t&&(this.nowPlaying=t,this.refreshLabels());};e(),this.pollTimer=setInterval(e,this.options.nowPlayingPollMs??12e3);}stopNowPlayingPoll(){this.pollTimer!==null&&(clearInterval(this.pollTimer),this.pollTimer=null);}handleSkipClick(){let e=this.engine;if(e){if(this.currentAd){e.canSkipAd()&&e.skipAd();return}e.skip();}}applyAdSkipUi(e){if(!this.skipBtn)return;let{ad:t,canSkip:i,countdownSeconds:n}=e;if(!t.isSkippable){this.skipBtn.disabled=true,this.skipBtn.textContent="",this.skipBtn.replaceChildren(y(k,22));return}if(!i){this.skipBtn.disabled=true,this.skipBtn.replaceChildren(),this.skipBtn.textContent=`${n}s`;return}this.skipBtn.disabled=false,this.skipBtn.textContent="",this.skipBtn.replaceChildren(y(k,22));}restoreTrackSkipButton(){this.skipBtn&&(this.skipBtn.disabled=false,this.skipBtn.textContent="",this.skipBtn.replaceChildren(y(k,22)),this.skipBtn.setAttribute("aria-label","Skip"));}displayLine(){return this.currentAd?{title:this.currentAd.campaignName||"Advertisement",artist:this.currentAd.creativeName}:this.isRadio&&this.nowPlaying?.title?pt(this.nowPlaying.title):this.currentTrack?.title?{title:this.currentTrack.title,artist:this.currentTrack.artist}:{title:"Loading\u2026"}}refreshLabels(){let e=this.displayLine();if(this.titleEl&&(this.titleEl.textContent=e.title),this.artistInlineEl){let t=!!e.artist;this.artistInlineEl.style.display=t?"inline":"none",t&&(this.artistInlineEl.textContent=e.artist);}if(this.artistBlockEl){let t=!!e.artist;this.artistBlockEl.style.display=t?"block":"none",t&&(this.artistBlockEl.textContent=e.artist);}if(this.footerEl)if(this.currentAd)this.footerEl.textContent="Advertisement \xB7 Synxed Player";else {let t=this.isRadio&&(this.nowPlaying?.station??this.currentTrack?.title??"Synxed Radio");this.footerEl.textContent=t&&this.isRadio?`${t} \xB7 Synxed Player`:"Synxed Player";}}updateAvatar(){if(this.refreshAvatarImage(),this.avatarRing){let e=this.avatarRing.firstChild;e&&(e.style.cursor=this.currentAd||this.voiceEnabled?"pointer":"default");}}setPlayingVisual(e){this.avatarRing&&(this.avatarRing.style.animation=e?"synxed-wp-spin 4s linear infinite":""),this.playBtn&&(this.playBtn.replaceChildren(y(e?lt:F,20)),this.playBtn.setAttribute("aria-label",e?"Pause":"Play"));}togglePlay(){this.engine&&(this.isPlaying?this.engine.pause():this.engine.resume());}};
142
+ exports.ContentKind=R;exports.ErrorCode=Y;exports.SdkVoiceAction=D;exports.SynxedConnectionError=N;exports.SynxedError=x;exports.SynxedPlaybackError=w;exports.SynxedPlayer=L;exports.SynxedProtocolError=Q;exports.SynxedWebPlayer=q;exports.TransportManager=E;exports.VoiceCaptureManager=P;exports.buildSdkWebSocketUrl=J;exports.fetchRadioNowPlaying=K;//# sourceMappingURL=index.js.map
169
143
  //# sourceMappingURL=index.js.map