synxed-sdk 0.2.6 → 0.2.7
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/README.md +1 -1
- package/dist/index.d.mts +20 -23
- package/dist/index.d.ts +20 -23
- package/dist/index.js +11 -4
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +11 -4
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Synxed SDK
|
|
2
2
|
|
|
3
|
-
Add
|
|
3
|
+
Add Music to your website, Game or App in a few minutes — Stream Songs, playlists, live radio, voice commands, and a ready-made player UI.
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/synxed-sdk)
|
|
6
6
|
|
package/dist/index.d.mts
CHANGED
|
@@ -86,12 +86,6 @@ interface VoiceHoldOptions {
|
|
|
86
86
|
listenerId?: string;
|
|
87
87
|
/** Auto-end capture when the user stops talking. Default `true`. */
|
|
88
88
|
autoEndOnSilence?: boolean;
|
|
89
|
-
/** RMS level below which audio counts as silence (0–1). Default `0.018`. */
|
|
90
|
-
silenceThreshold?: number;
|
|
91
|
-
/** Ms of silence after speech before auto-end. Default `1500`. */
|
|
92
|
-
silenceDurationMs?: number;
|
|
93
|
-
/** Minimum speech ms before silence can trigger end. Default `400`. */
|
|
94
|
-
minSpeechMs?: number;
|
|
95
89
|
/** Max capture length in ms. Default `30000`. */
|
|
96
90
|
maxDurationMs?: number;
|
|
97
91
|
}
|
|
@@ -270,43 +264,46 @@ declare function fetchRadioNowPlaying(serverUrl: string, init?: RequestInit): Pr
|
|
|
270
264
|
interface VoiceCaptureEvents {
|
|
271
265
|
chunk: (data: Uint8Array, sequence: number) => void;
|
|
272
266
|
error: (error: Error) => void;
|
|
273
|
-
/** User started speaking (level crossed above silence threshold). */
|
|
274
267
|
speechStart: () => void;
|
|
275
|
-
/** User stopped speaking (silence after speech, or max duration reached). */
|
|
276
268
|
speechEnd: () => void;
|
|
277
269
|
}
|
|
278
270
|
interface VoiceCaptureOptions {
|
|
279
|
-
/** RMS level below which audio counts as silence (0–1). Default `0.018`. */
|
|
280
|
-
silenceThreshold?: number;
|
|
281
|
-
/** Ms of silence after speech before `speechEnd`. Default `1500`. */
|
|
282
|
-
silenceDurationMs?: number;
|
|
283
|
-
/** Minimum speech ms before silence can end capture. Default `400`. */
|
|
284
|
-
minSpeechMs?: number;
|
|
285
271
|
/** Safety cap — auto `speechEnd` after this many ms. Default `30000`. */
|
|
286
272
|
maxDurationMs?: number;
|
|
287
|
-
/**
|
|
288
|
-
|
|
273
|
+
/**
|
|
274
|
+
* Base URL where `@ricky0123/vad-web` model / worklet assets are served.
|
|
275
|
+
* Defaults to the jsDelivr CDN.
|
|
276
|
+
*/
|
|
277
|
+
vadBaseAssetPath?: string;
|
|
278
|
+
/**
|
|
279
|
+
* Base URL where ONNX Runtime WASM binaries are served.
|
|
280
|
+
* Defaults to the jsDelivr CDN.
|
|
281
|
+
*/
|
|
282
|
+
onnxWasmBasePath?: string;
|
|
289
283
|
}
|
|
290
284
|
/**
|
|
291
|
-
*
|
|
285
|
+
* Captures microphone audio and buffers it locally. Once the user is finished
|
|
286
|
+
* talking (detected via Silero VAD), the complete audio file is emitted to the
|
|
287
|
+
* backend as a single chunk, followed by the stream termination.
|
|
292
288
|
*/
|
|
293
289
|
declare class VoiceCaptureManager extends EventEmitter<VoiceCaptureEvents> {
|
|
294
290
|
private stream;
|
|
295
|
-
private
|
|
291
|
+
private audioContext;
|
|
292
|
+
private mediaStreamSource;
|
|
293
|
+
private processor;
|
|
294
|
+
private muteNode;
|
|
296
295
|
private sequence;
|
|
297
296
|
private capturing;
|
|
298
297
|
private mimeType;
|
|
299
|
-
private
|
|
300
|
-
private silenceRaf;
|
|
298
|
+
private micVad;
|
|
301
299
|
private speechEndEmitted;
|
|
302
|
-
private captureOptions;
|
|
303
300
|
get isCapturing(): boolean;
|
|
304
301
|
get activeMimeType(): string;
|
|
305
302
|
start(options?: VoiceCaptureOptions): Promise<string>;
|
|
306
303
|
stop(): Promise<void>;
|
|
307
304
|
cancel(): void;
|
|
308
|
-
private
|
|
309
|
-
private
|
|
305
|
+
private startVadMonitor;
|
|
306
|
+
private teardownVad;
|
|
310
307
|
private releaseStream;
|
|
311
308
|
}
|
|
312
309
|
|
package/dist/index.d.ts
CHANGED
|
@@ -86,12 +86,6 @@ interface VoiceHoldOptions {
|
|
|
86
86
|
listenerId?: string;
|
|
87
87
|
/** Auto-end capture when the user stops talking. Default `true`. */
|
|
88
88
|
autoEndOnSilence?: boolean;
|
|
89
|
-
/** RMS level below which audio counts as silence (0–1). Default `0.018`. */
|
|
90
|
-
silenceThreshold?: number;
|
|
91
|
-
/** Ms of silence after speech before auto-end. Default `1500`. */
|
|
92
|
-
silenceDurationMs?: number;
|
|
93
|
-
/** Minimum speech ms before silence can trigger end. Default `400`. */
|
|
94
|
-
minSpeechMs?: number;
|
|
95
89
|
/** Max capture length in ms. Default `30000`. */
|
|
96
90
|
maxDurationMs?: number;
|
|
97
91
|
}
|
|
@@ -270,43 +264,46 @@ declare function fetchRadioNowPlaying(serverUrl: string, init?: RequestInit): Pr
|
|
|
270
264
|
interface VoiceCaptureEvents {
|
|
271
265
|
chunk: (data: Uint8Array, sequence: number) => void;
|
|
272
266
|
error: (error: Error) => void;
|
|
273
|
-
/** User started speaking (level crossed above silence threshold). */
|
|
274
267
|
speechStart: () => void;
|
|
275
|
-
/** User stopped speaking (silence after speech, or max duration reached). */
|
|
276
268
|
speechEnd: () => void;
|
|
277
269
|
}
|
|
278
270
|
interface VoiceCaptureOptions {
|
|
279
|
-
/** RMS level below which audio counts as silence (0–1). Default `0.018`. */
|
|
280
|
-
silenceThreshold?: number;
|
|
281
|
-
/** Ms of silence after speech before `speechEnd`. Default `1500`. */
|
|
282
|
-
silenceDurationMs?: number;
|
|
283
|
-
/** Minimum speech ms before silence can end capture. Default `400`. */
|
|
284
|
-
minSpeechMs?: number;
|
|
285
271
|
/** Safety cap — auto `speechEnd` after this many ms. Default `30000`. */
|
|
286
272
|
maxDurationMs?: number;
|
|
287
|
-
/**
|
|
288
|
-
|
|
273
|
+
/**
|
|
274
|
+
* Base URL where `@ricky0123/vad-web` model / worklet assets are served.
|
|
275
|
+
* Defaults to the jsDelivr CDN.
|
|
276
|
+
*/
|
|
277
|
+
vadBaseAssetPath?: string;
|
|
278
|
+
/**
|
|
279
|
+
* Base URL where ONNX Runtime WASM binaries are served.
|
|
280
|
+
* Defaults to the jsDelivr CDN.
|
|
281
|
+
*/
|
|
282
|
+
onnxWasmBasePath?: string;
|
|
289
283
|
}
|
|
290
284
|
/**
|
|
291
|
-
*
|
|
285
|
+
* Captures microphone audio and buffers it locally. Once the user is finished
|
|
286
|
+
* talking (detected via Silero VAD), the complete audio file is emitted to the
|
|
287
|
+
* backend as a single chunk, followed by the stream termination.
|
|
292
288
|
*/
|
|
293
289
|
declare class VoiceCaptureManager extends EventEmitter<VoiceCaptureEvents> {
|
|
294
290
|
private stream;
|
|
295
|
-
private
|
|
291
|
+
private audioContext;
|
|
292
|
+
private mediaStreamSource;
|
|
293
|
+
private processor;
|
|
294
|
+
private muteNode;
|
|
296
295
|
private sequence;
|
|
297
296
|
private capturing;
|
|
298
297
|
private mimeType;
|
|
299
|
-
private
|
|
300
|
-
private silenceRaf;
|
|
298
|
+
private micVad;
|
|
301
299
|
private speechEndEmitted;
|
|
302
|
-
private captureOptions;
|
|
303
300
|
get isCapturing(): boolean;
|
|
304
301
|
get activeMimeType(): string;
|
|
305
302
|
start(options?: VoiceCaptureOptions): Promise<string>;
|
|
306
303
|
stop(): Promise<void>;
|
|
307
304
|
cancel(): void;
|
|
308
|
-
private
|
|
309
|
-
private
|
|
305
|
+
private startVadMonitor;
|
|
306
|
+
private teardownVad;
|
|
310
307
|
private releaseStream;
|
|
311
308
|
}
|
|
312
309
|
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
'use strict';var
|
|
1
|
+
'use strict';var F=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 F__namespace=/*#__PURE__*/_interopNamespace(F);var ct=`
|
|
2
2
|
syntax = "proto3";
|
|
3
3
|
|
|
4
4
|
enum ContentKind {
|
|
@@ -117,20 +117,27 @@ message SdkServerAdPayload {
|
|
|
117
117
|
string campaignName = 13;
|
|
118
118
|
}
|
|
119
119
|
|
|
120
|
+
message SdkServerVoiceAudio {
|
|
121
|
+
bytes audioData = 1;
|
|
122
|
+
string mimeType = 2;
|
|
123
|
+
bool isFinal = 3;
|
|
124
|
+
}
|
|
125
|
+
|
|
120
126
|
message SdkServerEnvelope {
|
|
121
127
|
oneof payload {
|
|
122
128
|
SdkServerInitAck initAck = 1;
|
|
123
129
|
SdkServerError error = 2;
|
|
124
130
|
SdkServerAdPayload ad = 3;
|
|
125
131
|
SdkServerVoiceAck voiceAck = 4;
|
|
132
|
+
SdkServerVoiceAudio voiceAudio = 5;
|
|
126
133
|
}
|
|
127
134
|
}
|
|
128
|
-
`,G=Y__namespace.parse(vt).root,D=G.lookupType("SdkClientEnvelope"),B=G.lookupType("SdkServerEnvelope"),O=(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))(O||{}),K=(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))(K||{}),X=(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))(X||{});var S=class{static encodeClientEnvelope(e){let t=D.create(e);return D.encode(t).finish()}static decodeServerEnvelope(e){let t=B.decode(e);return B.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 J=false;function Q(r){J=r;}function h(...r){J&&console.debug("[Synxed]",...r);}function f(...r){console.warn("[Synxed]",...r);}function Z(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 C=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=Z(i,t);h("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(h("Waiting for connection\u2026"),this.ws?.readyState===WebSocket.OPEN){h("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=()=>{h("WebSocket connected"),l(),t();},s=()=>{f("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");h("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"),h("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()){h("Using Hls.js for playback");let a=new s({xhrSetup:u=>{u.setRequestHeader("ngrok-skip-browser-warning","true");}}),l=new Audio;return new Promise((u,p)=>{let c=()=>n!==this.loadGeneration,y=()=>{c()||(this.emit("playing"),this.startTimeUpdateLoop());},m=()=>{c()||(this.emit("paused"),this.stopTimeUpdateLoop());},E=()=>{c()||(this.emit("ended"),this.stopTimeUpdateLoop());},k=()=>{c()||this.emit("loaded");},R=()=>{c()||(f("HLS audio element error"),this.emit("error",new Error("HLS playback failed")));};l.addEventListener("play",y),l.addEventListener("pause",m),l.addEventListener("ended",E),l.addEventListener("loadedmetadata",k),l.addEventListener("error",R),a.on(s.Events.MANIFEST_PARSED,()=>{c()||(this.emit("loaded"),u());}),a.on(s.Events.ERROR,(U,T)=>{c()||T.fatal&&(f("Fatal HLS error",T),p(T));}),a.loadSource(t),a.attachMedia(l),this.hls=a,this.audioEl=l;})}}catch(s){f("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()||(h("AudioEngine loaded"),this.emit("loaded"),s());},onloaderror:(u,p)=>{l()||(f("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=>f("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 _=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";}},M=class extends x{constructor(e){super(e),this.name="SynxedConnectionError";}},P=class extends x{constructor(e){super(typeof e=="string"?e:"Playback failed"),this.name="SynxedPlaybackError";}},tt=class extends x{constructor(e){super(e),this.name="SynxedProtocolError";}};function W(r,...e){for(let t of e){let i=r[t];if(typeof i=="string"&&i.length>0)return i}}function yt(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 et(r){let e=r.initAck??r.init_ack;if(!e||typeof e!="object")return null;let t=e,i=W(t,"playbackUrl","playback_url");return i?{sessionId:W(t,"sessionId","session_id")??"",playbackUrl:i,isHls:!!(t.isHls??t.is_hls),heartbeatIntervalMs:yt(t,"heartbeatIntervalMs","heartbeat_interval_ms")??0,contentSummary:W(t,"contentSummary","content_summary")}:null}function gt(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 it(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 u of o){let p=gt(u);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 g(r,...e){for(let t of e){let i=r[t];if(typeof i=="string")return i}return ""}function nt(r,...e){for(let t of e){let i=r[t];if(typeof i=="boolean")return i}return false}function rt(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 st(r){let e=r.ad;if(!e||typeof e!="object")return null;let t=e,i=g(t,"playbackUrl","playback_url");return i?{adId:g(t,"adId","ad_id"),campaignId:g(t,"campaignId","campaign_id"),playbackUrl:i,isHls:nt(t,"isHls","is_hls")||i.includes(".m3u8"),durationSeconds:rt(t,"durationSeconds","duration_seconds")||15,isSkippable:nt(t,"isSkippable","is_skippable"),skipAfterSeconds:rt(t,"skipAfterSeconds","skip_after_seconds"),ctaType:g(t,"ctaType","cta_type"),ctaValue:g(t,"ctaValue","cta_value"),brandName:g(t,"brandName","brand_name"),creativeName:g(t,"creativeName","creative_name"),companionBannerUrl:g(t,"companionBannerUrl","companion_banner_url"),campaignName:g(t,"campaignName","campaign_name")}:null}function L(r,...e){for(let t of e){let i=r[t];if(typeof i=="string")return i}return ""}function at(r){let e=r.voiceAck??r.voice_ack;if(!e||typeof e!="object")return null;let t=e,i=L(t,"status");return i?{status:i,transcript:L(t,"transcript")||void 0,playlistCode:L(t,"playlistCode","playlist_code")||void 0,playlistName:L(t,"playlistName","playlist_name")||void 0}:null}function ot(){let r=["audio/webm;codecs=opus","audio/webm","audio/ogg;codecs=opus","audio/mp4"];for(let e of r)if(MediaRecorder.isTypeSupported(e))return e;return "audio/webm"}var I=class extends v{constructor(){super(...arguments);this.stream=null;this.recorder=null;this.sequence=0;this.capturing=false;this.mimeType=ot();this.audioContext=null;this.silenceRaf=null;this.speechEndEmitted=false;this.captureOptions={};}get isCapturing(){return this.capturing}get activeMimeType(){return this.mimeType}async start(t={}){return this.capturing?this.mimeType:(this.captureOptions=t,this.speechEndEmitted=false,this.mimeType=ot(),this.sequence=0,this.stream=await navigator.mediaDevices.getUserMedia({audio:{echoCancellation:true,noiseSuppression:true,autoGainControl:true},video:false}),this.recorder=new MediaRecorder(this.stream,{mimeType:this.mimeType,audioBitsPerSecond:32e3}),this.recorder.ondataavailable=i=>{!this.capturing||!i.data.size||i.data.arrayBuffer().then(n=>{this.capturing&&(this.sequence+=1,this.emit("chunk",new Uint8Array(n),this.sequence));});},this.recorder.onerror=()=>{this.emit("error",new Error("Microphone capture failed"));},this.capturing=true,this.recorder.start(40),t.detectSilence!==false&&this.startSilenceMonitor(t),this.mimeType)}async stop(){if(!this.recorder||!this.capturing)return;this.capturing=false,this.stopSilenceMonitor();let t=this.recorder;await new Promise(i=>{if(t.state==="inactive"){this.releaseStream(),i();return}t.addEventListener("stop",()=>{this.releaseStream(),i();},{once:true});try{t.stop();}catch{this.releaseStream(),i();}});}cancel(){this.capturing=false,this.stopSilenceMonitor();let t=this.recorder;if(t&&t.state!=="inactive")try{t.stop();}catch{}this.releaseStream();}startSilenceMonitor(t){if(!this.stream)return;let i=t.silenceThreshold??.018,n=t.silenceDurationMs??1500,o=t.minSpeechMs??400,s=t.maxDurationMs??3e4,a=new AudioContext,l=a.createMediaStreamSource(this.stream),u=a.createAnalyser();u.fftSize=512,l.connect(u);let p=new Uint8Array(u.fftSize),c=false,y=0,m=null,E=Date.now(),k=()=>{this.speechEndEmitted||!this.capturing||(this.speechEndEmitted=true,this.emit("speechEnd"));},R=()=>{if(!this.capturing)return;u.getByteTimeDomainData(p);let U=0;for(let H=0;H<p.length;H++){let j=(p[H]-128)/128;U+=j*j;}let T=Math.sqrt(U/p.length),A=Date.now();if(A-E>=s){k();return}if(T>i)c||(c=true,y=A,this.emit("speechStart")),m=null;else if(c&&A-y>=o){if(m===null)m=A;else if(A-m>=n){k();return}}this.silenceRaf=requestAnimationFrame(R);};this.audioContext=a,this.silenceRaf=requestAnimationFrame(R);}stopSilenceMonitor(){this.silenceRaf!==null&&(cancelAnimationFrame(this.silenceRaf),this.silenceRaf=null),this.audioContext&&(this.audioContext.close(),this.audioContext=null);}releaseStream(){if(this.stream){for(let t of this.stream.getTracks())t.stop();this.stream=null;}this.recorder=null;}};var V=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,Q(!!t.debug),this.transport=new C,this.audio=new N,this.playlist=new _,this.voiceCapture=new I,this.setupListeners(),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 M(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){f("Ad playback error \u2014 waiting for next track",t);return}this.emit("error",new P(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")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.voiceMimeType=await this.voiceCapture.start({silenceThreshold:i.silenceThreshold,silenceDurationMs:i.silenceDurationMs,minSpeechMs:i.minSpeechMs,maxDurationMs:i.maxDurationMs,detectSilence:this.voiceAutoEndOnSilence}),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"}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=it(t,this.activeContentKind);if(i){this.playlist.setQueue(i.tracks,i.currentIndex);return}t?.trim()&&f("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){h("Received server message",t);let i=at(t);if(i){this.handleVoiceAck(i);return}let n=st(t);if(n){await this.handleAdPlayback(n);return}let o=et(t);if(o){await this.startContentPlayback(o);return}let s=t.error;if(s&&typeof s=="object"){let a=s,l=typeof a.message=="string"?a.message:"Unknown server error",u=typeof a.code=="string"?a.code:void 0;(this._voiceState==="processing"||this._voiceState==="listening")&&this.setVoiceState("error"),this.emit("error",new x(l,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.setVoiceState("idle"),this.pausedForVoice=false,h("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 P(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},h("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),f("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.audio.stop(),this.transport.disconnect(),this.playlist.reset(),this.removeAllListeners();}};async function F(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 b(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 z="M8 5v14l11-7L8 5z",lt="M6 5h4v14H6V5zm8 0h4v14h-4V5z",w="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=`
|
|
135
|
+
`,z=F__namespace.parse(ct).root,L=z.lookupType("SdkClientEnvelope"),M=z.lookupType("SdkServerEnvelope"),P=(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))(P||{}),U=(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))(U||{}),q=(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))(q||{});var S=class{static encodeClientEnvelope(e){let t=L.create(e);return L.encode(t).finish()}static decodeServerEnvelope(e){let t=M.decode(e);return M.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 j=false;function $(r){j=r;}function m(...r){j&&console.debug("[Synxed]",...r);}function u(...r){console.warn("[Synxed]",...r);}function G(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=G(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"),d(),t();},s=()=>{u("WebSocket connection error"),d(),i(new Error("WebSocket connection failed"));},a=()=>{d(),i(new Error("WebSocket closed before connection was established"));},d=()=>{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 I=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:h=>{h.setRequestHeader("ngrok-skip-browser-warning","true");}}),d=new Audio;return new Promise((h,p)=>{let c=()=>n!==this.loadGeneration,g=()=>{c()||(this.emit("playing"),this.startTimeUpdateLoop());},b=()=>{c()||(this.emit("paused"),this.stopTimeUpdateLoop());},C=()=>{c()||(this.emit("ended"),this.stopTimeUpdateLoop());},T=()=>{c()||this.emit("loaded");},dt=()=>{c()||(u("HLS audio element error"),this.emit("error",new Error("HLS playback failed")));};d.addEventListener("play",g),d.addEventListener("pause",b),d.addEventListener("ended",C),d.addEventListener("loadedmetadata",T),d.addEventListener("error",dt),a.on(s.Events.MANIFEST_PARSED,()=>{c()||(this.emit("loaded"),h());}),a.on(s.Events.ERROR,(yt,R)=>{c()||R.fatal&&(u("Fatal HLS error",R),p(R));}),a.loadSource(t),a.attachMedia(d),this.hls=a,this.audioEl=d;})}}catch(s){u("hls.js not available, falling back to native playback",s);}return new Promise((s,a)=>{let d=()=>n!==this.loadGeneration;this.howl=new howler.Howl({src:[t],html5:true,format:i?["m3u8"]:void 0,onload:()=>{d()||(m("AudioEngine loaded"),this.emit("loaded"),s());},onloaderror:(h,p)=>{d()||(u("AudioEngine load error",p),a(p));},onplay:()=>{d()||(this.emit("playing"),this.startTimeUpdateLoop());},onpause:()=>{d()||(this.emit("paused"),this.stopTimeUpdateLoop());},onstop:()=>{d()||(this.emit("stopped"),this.stopTimeUpdateLoop());},onend:()=>{d()||(this.emit("ended"),this.stopTimeUpdateLoop());}});})}play(){this.audioEl?this.audioEl.play().catch(t=>u("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 N=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";}},w=class extends x{constructor(e){super(typeof e=="string"?e:"Playback failed"),this.name="SynxedPlaybackError";}},Y=class extends x{constructor(e){super(e),this.name="SynxedProtocolError";}};function H(r,...e){for(let t of e){let i=r[t];if(typeof i=="string"&&i.length>0)return i}}function ut(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 X(r){let e=r.initAck??r.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:ut(t,"heartbeatIntervalMs","heartbeat_interval_ms")??0,contentSummary:H(t,"contentSummary","content_summary")}:null}function ht(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 J(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 h of o){let p=ht(h);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,d=Math.max(0,Math.min(Math.floor(a),s.length-1));return {tracks:s,currentIndex:d}}function f(r,...e){for(let t of e){let i=r[t];if(typeof i=="string")return i}return ""}function Q(r,...e){for(let t of e){let i=r[t];if(typeof i=="boolean")return i}return false}function Z(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 tt(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:Q(t,"isHls","is_hls")||i.includes(".m3u8"),durationSeconds:Z(t,"durationSeconds","duration_seconds")||15,isSkippable:Q(t,"isSkippable","is_skippable"),skipAfterSeconds:Z(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 O(r,...e){for(let t of e){let i=r[t];if(typeof i=="string")return i}return ""}function et(r){let e=r.voiceAck??r.voice_ack;if(!e||typeof e!="object")return null;let t=e,i=O(t,"status");return i?{status:i,transcript:O(t,"transcript")||void 0,playlistCode:O(t,"playlistCode","playlist_code")||void 0,playlistName:O(t,"playlistName","playlist_name")||void 0}:null}var mt="https://cdn.jsdelivr.net/npm/@ricky0123/vad-web@0.0.29/dist/",vt="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 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}),this.mediaStreamSource=this.audioContext.createMediaStreamSource(this.stream),this.processor=this.audioContext.createScriptProcessor(4096,1,1),this.muteNode=this.audioContext.createGain(),this.muteNode.gain.value=0,this.processor.onaudioprocess=i=>{if(!this.capturing)return;let n=i.inputBuffer.getChannelData(0),o=new Int16Array(n.length);for(let s=0;s<n.length;s++)o[s]=Math.max(-32768,Math.min(32767,n[s]*32768));this.sequence++,this.emit("chunk",new Uint8Array(o.buffer),this.sequence);},this.mediaStreamSource.connect(this.processor),this.processor.connect(this.muteNode),this.muteNode.connect(this.audioContext.destination),this.capturing=true;try{await this.startVadMonitor(t);}catch(i){this.emit("error",new Error(`Failed to initialize Voice Activity Detection: ${i instanceof Error?i.message:String(i)}`));}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,s=()=>{this.speechEndEmitted||!this.capturing||(this.speechEndEmitted=true,this.emit("speechEnd"));},a=await i.new({getStream:async()=>this.stream,baseAssetPath:t.vadBaseAssetPath??mt,onnxWASMBasePath:t.onnxWasmBasePath??vt,onSpeechStart:()=>{this.capturing&&(this.emit("speechStart"),o===null&&(o=setTimeout(()=>{s();},n)));},onSpeechEnd:()=>{o!==null&&(clearTimeout(o),o=null),s();}});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){u("VAD pause failed during teardown",t);}try{this.micVad.destroy();}catch(t){u("VAD destroy failed during teardown",t);}this.micVad=null;}}releaseStream(){if(this.processor&&(this.processor.disconnect(),this.processor.onaudioprocess=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 _=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,$(!!t.debug),this.transport=new E,this.audio=new I,this.playlist=new N,this.voiceCapture=new A,this.setupListeners(),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){u("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")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.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"}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=J(t,this.activeContentKind);if(i){this.playlist.setQueue(i.tracks,i.currentIndex);return}t?.trim()&&u("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=et(t);if(i){this.handleVoiceAck(i);return}let n=tt(t);if(n){await this.handleAdPlayback(n);return}let o=X(t);if(o){await this.startContentPlayback(o);return}let s=t.error;if(s&&typeof s=="object"){let a=s,d=typeof a.message=="string"?a.message:"Unknown server error",h=typeof a.code=="string"?a.code:void 0;(this._voiceState==="processing"||this._voiceState==="listening")&&this.setVoiceState("error"),this.emit("error",new x(d,h));}}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.setVoiceState("idle"),this.pausedForVoice=false,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),u("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.audio.stop(),this.transport.disconnect(),this.playlist.reset(),this.removeAllListeners();}};async function D(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 l(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 B="M8 5v14l11-7L8 5z",it="M6 5h4v14H6V5zm8 0h4v14h-4V5z",k="M6 18l8.5-6L6 6v12zM16 6v12h2V6h-2z",nt="M6 6h2v12H6V6zm11.5 12L9 12l8.5-6v12z";function rt(){let r="synxed-web-player-styles";if(document.getElementById(r))return;let e=document.createElement("style");e.id=r,e.textContent=`
|
|
129
136
|
@keyframes synxed-wp-spin { from { transform: rotate(0); } to { transform: rotate(360deg); } }
|
|
130
137
|
@keyframes synxed-wp-vbar {
|
|
131
138
|
0%, 100% { transform: scaleY(0.28); opacity: 0.45; }
|
|
132
139
|
50% { transform: scaleY(1); opacity: 1; }
|
|
133
140
|
}
|
|
134
|
-
`,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 q="https://cdn.synxed.com/avater-image/avatar.svg",bt="https://cdn.synxed.com/avater-image/generative-ai.svg",$=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 c=p,y=c.target;if(y.closest("[data-synxed-avatar-ring]")||this.avatarVoiceHolding||this.mode!=="mini"&&y.closest("button, a, input"))return;e=true,t=false;let m=this.root.getBoundingClientRect();o=m.left,s=m.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 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",u),document.addEventListener("touchmove",l,{passive:false}),document.addEventListener("touchend",u);},l=p=>{if(!e)return;p.preventDefault();let c=p,y,m;"touches"in c?(y=c.touches[0].clientX,m=c.touches[0].clientY):(y=c.clientX,m=c.clientY);let E=y-i,k=m-n;(Math.abs(E)>3||Math.abs(k)>3)&&(t=true),this.root.style.left=`${o+E}px`,this.root.style.top=`${s+k}px`;},u=()=>{e=false,document.removeEventListener("mousemove",l),document.removeEventListener("mouseup",u),document.removeEventListener("touchmove",l),document.removeEventListener("touchend",u),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:q,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:[b(w,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:[b(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:[b(w,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:[b(z,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 V({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 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")&&(this.voiceUiDismissed=false),e==="listening"?(this.avatarRing.style.animation="",this.avatarRing.style.borderColor="#ef4444",this.avatarRing.style.boxShadow="0 0 20px rgba(239,68,68,0.55), 0 0 40px rgba(239,68,68,0.25)"):e==="processing"?(this.avatarRing.style.animation="",this.avatarRing.style.borderColor="#6366f1",this.avatarRing.style.boxShadow="0 0 20px rgba(99,102,241,0.5), 0 0 40px rgba(99,102,241,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"}getContentAvatarUrl(){return q}getAvatarImageUrl(){return this.currentAd?.companionBannerUrl?this.currentAd.companionBannerUrl:this.isVoiceAvatarActive()?bt:this.avatarImageBeforeAd?this.avatarImageBeforeAd:q}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="contain",this.avatarImgEl.style.objectPosition="center",this.avatarImgEl.style.transform="scale(1)",this.avatarImgEl.style.padding="14%",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 F(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(b(w,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(b(w,22));}restoreTrackSkipButton(){this.skipBtn&&(this.skipBtn.disabled=false,this.skipBtn.textContent="",this.skipBtn.replaceChildren(b(w,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(b(e?lt:z,20)),this.playBtn.setAttribute("aria-label",e?"Pause":"Play"));}togglePlay(){this.engine&&(this.isPlaying?this.engine.pause():this.engine.resume());}};
|
|
135
|
-
exports.ContentKind=
|
|
141
|
+
`,document.head.appendChild(e);}function st(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 at(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 ot(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 lt(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 W="https://cdn.synxed.com/avater-image/avatar.svg",ft="https://cdn.synxed.com/avater-image/AI%20Star%20UI%20animation.gif",K=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=ot(this.options.theme),this.ownsRoot=!e.container,this.root=e.container??document.createElement("div"),this.ownsRoot&&document.body.appendChild(this.root),rt(),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,lt(this.root,this.theme),Object.assign(this.root.style,at(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 c=p,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,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 c?(i=c.touches[0].clientX,n=c.touches[0].clientY):(i=c.clientX,n=c.clientY),document.addEventListener("mousemove",d,{passive:false}),document.addEventListener("mouseup",h),document.addEventListener("touchmove",d,{passive:false}),document.addEventListener("touchend",h);},d=p=>{if(!e)return;p.preventDefault();let c=p,g,b;"touches"in c?(g=c.touches[0].clientX,b=c.touches[0].clientY):(g=c.clientX,b=c.clientY);let C=g-i,T=b-n;(Math.abs(C)>3||Math.abs(T)>3)&&(t=true),this.root.style.left=`${o+C}px`,this.root.style.top=`${s+T}px`;},h=()=>{e=false,document.removeEventListener("mousemove",d),document.removeEventListener("mouseup",h),document.removeEventListener("touchmove",d),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",p=>{t&&(p.stopPropagation(),p.preventDefault());},true);}buildAvatar(e,t=false){let i=l("div",{style:{position:"relative",flexShrink:"0"}});this.avatarRing=l("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=l("div",{style:{width:"100%",height:"100%",borderRadius:"50%",background:"var(--sw-bg-inner)",overflow:"hidden"}});return this.avatarImgEl=l("img",{attrs:{src:W,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=l("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(l("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=l("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=l("div",{style:{position:"relative",display:"flex",alignItems:"center",width:"100%"}}),n=Math.max(90*.42,40);i.appendChild(l("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:[l("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=l("div",{style:{position:"relative",zIndex:"1",flex:"1",minWidth:"0",marginLeft:"14px",padding:"18px 8px"}}),a=l("div",{style:{display:"flex",alignItems:"baseline",gap:"8px",overflow:"hidden"}});this.titleEl=l("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=l("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=l("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 d=l("div",{style:{position:"relative",zIndex:"1",flexShrink:"0",display:"flex",alignItems:"center",gap:"14px",paddingRight:"16px"}});this.playBtn=this.createPlayButton(52),d.appendChild(this.playBtn),this.isRadio||(this.skipBtn=l("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)]}),d.appendChild(this.skipBtn)),d.appendChild(this.decoLines()),i.appendChild(d),this.root.appendChild(i);}buildLarge(){this.root.style.width="min(calc(100vw - 24px), 380px)";let t=l("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=l("div",{style:{display:"flex",gap:"12px",alignItems:"center",minWidth:"0"}});i.appendChild(this.buildAvatar(96,true));let n=l("div",{style:{minWidth:"0",flex:"1"}});this.titleEl=l("h3",{style:{margin:"0",fontSize:"18px",fontWeight:"900",color:"var(--sw-text)",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}}),n.appendChild(this.titleEl),this.artistBlockEl=l("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=l("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(l("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=l("div",{style:{display:"flex",alignItems:"center",justifyContent:"center",gap:"18px"}});this.isRadio||o.appendChild(l("button",{attrs:{type:"button","aria-label":"Previous"},style:this.roundControlStyle(),onClick:()=>this.engine?.previous(),children:[y(nt,22)]})),this.playBtn=this.createPlayButton(56),o.appendChild(this.playBtn),this.isRadio||(this.skipBtn=l("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 l("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(B,e>=56?22:20)]})}buildVisualizer(){let e=l("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(l("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=l("div",{style:{display:"flex",flexDirection:"column",gap:"3px",opacity:"0.22"}});return e.appendChild(l("span",{style:{display:"block",width:"16px",height:"2px",borderRadius:"999px",background:"var(--sw-text)",transform:"translateX(3px)"}})),e.appendChild(l("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 _({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 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")&&(this.voiceUiDismissed=false),e==="listening"?(this.avatarRing.style.animation="",this.avatarRing.style.borderColor="#ef4444",this.avatarRing.style.boxShadow="0 0 20px rgba(239,68,68,0.55), 0 0 40px rgba(239,68,68,0.25)"):e==="processing"?(this.avatarRing.style.animation="",this.avatarRing.style.borderColor="#6366f1",this.avatarRing.style.boxShadow="0 0 20px rgba(99,102,241,0.5), 0 0 40px rgba(99,102,241,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"}getContentAvatarUrl(){return W}getAvatarImageUrl(){return this.currentAd?.companionBannerUrl?this.currentAd.companionBannerUrl:this.isVoiceAvatarActive()?ft:this.avatarImageBeforeAd?this.avatarImageBeforeAd:W}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 D(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?st(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?it:B,20)),this.playBtn.setAttribute("aria-label",e?"Pause":"Play"));}togglePlay(){this.engine&&(this.isPlaying?this.engine.pause():this.engine.resume());}};
|
|
142
|
+
exports.ContentKind=P;exports.ErrorCode=q;exports.SdkVoiceAction=U;exports.SynxedConnectionError=V;exports.SynxedError=x;exports.SynxedPlaybackError=w;exports.SynxedPlayer=_;exports.SynxedProtocolError=Y;exports.SynxedWebPlayer=K;exports.TransportManager=E;exports.VoiceCaptureManager=A;exports.buildSdkWebSocketUrl=G;exports.fetchRadioNowPlaying=D;//# sourceMappingURL=index.js.map
|
|
136
143
|
//# sourceMappingURL=index.js.map
|