synxed-sdk 0.2.2 → 0.2.3

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 CHANGED
@@ -96,6 +96,7 @@ const ui = SynxedWebPlayer.mount({
96
96
  background: "#0a0707",
97
97
  },
98
98
  position: { placement: "top-left", offsetX: 16, offsetY: 16 },
99
+ draggable: true,
99
100
  });
100
101
 
101
102
  // Later: ui.destroy();
@@ -113,6 +114,7 @@ SynxedWebPlayer.mount({
113
114
  ```
114
115
 
115
116
  **Modes**: `mini` (avatar only), `wide` (pill bar, default), `large` (card + visualizer). Skip controls are hidden for radio.
117
+ **Draggable**: Set `draggable: true` (default is `false`) to allow users to move the floating player around the screen so it doesn't obstruct their view.
116
118
 
117
119
  In React/Vue, create the player in `useEffect` / `onMounted` and call `destroy()` on teardown — same class, no separate React package.
118
120
 
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- 'use strict';var _=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 ___namespace=/*#__PURE__*/_interopNamespace(_);var it=`
1
+ 'use strict';var W=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 W__namespace=/*#__PURE__*/_interopNamespace(W);var nt=`
2
2
  syntax = "proto3";
3
3
 
4
4
  enum ContentKind {
@@ -98,12 +98,12 @@ message SdkServerEnvelope {
98
98
  SdkServerAdPayload ad = 3;
99
99
  }
100
100
  }
101
- `,U=___namespace.parse(it).root,A=U.lookupType("SdkClientEnvelope"),N=U.lookupType("SdkServerEnvelope"),w=(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))(w||{}),B=(o=>(o[o.UNSPECIFIED=0]="UNSPECIFIED",o[o.UNAUTHORIZED=1]="UNAUTHORIZED",o[o.VALIDATION_ERROR=2]="VALIDATION_ERROR",o[o.NOT_FOUND=3]="NOT_FOUND",o[o.PROCESSING=4]="PROCESSING",o[o.SERVICE_UNAVAILABLE=5]="SERVICE_UNAVAILABLE",o[o.BAD_PROTOBUF=6]="BAD_PROTOBUF",o))(B||{});var g=class{static encodeClientEnvelope(e){let t=A.create(e);return A.encode(t).finish()}static decodeServerEnvelope(e){let t=N.decode(e);return N.toObject(t,{enums:String,longs:String,bytes:String,defaults:true,oneofs:true})}};var h=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=((...r)=>{t(...r),this.off(e,i);});this.on(e,i);}emit(e,...t){let i=this.listeners.get(e);i&&i.forEach(r=>r(...t));}removeAllListeners(){this.listeners.clear();}};var W=false;function K(n){W=n;}function p(...n){W&&console.debug("[Synxed]",...n);}function y(...n){console.warn("[Synxed]",...n);}function D(n,e){let i=(n.endsWith("/")?n.slice(0,-1):n).replace(/^http:/,"ws:").replace(/^https:/,"wss:"),r=new URL(`${i}/sdk`);return r.searchParams.set("apiKey",e),r.toString()}var k=class extends h{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 r=D(i,t);p("Opening native WebSocket",r.replace(/apiKey=[^&]+/,"apiKey=***")),this.ws=new WebSocket(r),this.ws.binaryType="arraybuffer",this.ws.onopen=()=>{this.connectPromise=null,this.emit("connected");},this.ws.onclose=s=>{let a=s.reason||`code ${s.code}`;this.ws=null,this.connectPromise=null,this.emit("disconnected",a);},this.ws.onerror=()=>{this.emit("error",new Error("WebSocket connection error"));},this.ws.onmessage=s=>{try{let{data:a}=s;if(!(a instanceof ArrayBuffer))return;let o=g.decodeServerEnvelope(new Uint8Array(a));this.emit("message",o);}catch(a){this.emit("error",new Error(`Failed to decode message: ${a}`));}};}async waitForConnection(){if(p("Waiting for connection\u2026"),this.ws?.readyState===WebSocket.OPEN){p("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 r=this.ws;if(r.readyState===WebSocket.OPEN){t();return}let s=()=>{p("WebSocket connected"),d(),t();},a=()=>{y("WebSocket connection error"),d(),i(new Error("WebSocket connection failed"));},o=()=>{d(),i(new Error("WebSocket closed before connection was established"));},d=()=>{r.removeEventListener("open",s),r.removeEventListener("error",a),r.removeEventListener("close",o);};r.addEventListener("open",s),r.addEventListener("error",a),r.addEventListener("close",o);}),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");p("Sending init packet",t),this.sendBytes(g.encodeClientEnvelope({init:t}));}sendControl(t){this.isConnected&&this.sendBytes(g.encodeClientEnvelope({control:t}));}sendAnalytics(t){this.isConnected&&this.sendBytes(g.encodeClientEnvelope({analytics: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 E=class extends h{constructor(){super();this.howl=null;this.hls=null;this.audioEl=null;this.updateTimer=null;}async load(t,i){this.stop(),this.emit("loading"),p("AudioEngine loading",{url:t,isHls:i});let r=/^((?!chrome|android).)*safari/i.test(navigator.userAgent);if(i&&!r)try{let{default:s}=await import('hls.js');if(s.isSupported()){p("Using Hls.js for playback");let o=new URL(t).search;this.hls=new s({xhrSetup:d=>{d.setRequestHeader("ngrok-skip-browser-warning","true");}}),this.audioEl=new Audio,this.hls.loadSource(t),this.hls.attachMedia(this.audioEl),this.audioEl.onplay=()=>{this.emit("playing"),this.startTimeUpdateLoop();},this.audioEl.onpause=()=>{this.emit("paused"),this.stopTimeUpdateLoop();},this.audioEl.onended=()=>{this.emit("ended"),this.stopTimeUpdateLoop();},this.audioEl.onerror=d=>{y("HLS audio element error",d),this.emit("error",d);},this.audioEl.onloadedmetadata=()=>{this.emit("loaded");},this.hls.on(s.Events.ERROR,(d,u)=>{u.fatal&&(y("Fatal HLS error",u),this.emit("error",u));});return}}catch{y("hls.js not available, falling back to native playback");}this.howl=new howler.Howl({src:[t],html5:true,format:i?["m3u8"]:void 0,onload:()=>{p("AudioEngine loaded"),this.emit("loaded");},onloaderror:(s,a)=>{y("AudioEngine load error",a,s),this.emit("error",a);},onplay:()=>{this.emit("playing"),this.startTimeUpdateLoop();},onpause:()=>{this.emit("paused"),this.stopTimeUpdateLoop();},onstop:()=>{this.emit("stopped"),this.stopTimeUpdateLoop();},onend:()=>{this.emit("ended"),this.stopTimeUpdateLoop();}});}play(){this.audioEl?this.audioEl.play().catch(t=>y("Play failed",t)):this.howl?.play();}pause(){this.audioEl?this.audioEl.pause():this.howl?.pause();}stop(){this.hls&&(this.hls.destroy(),this.hls=null),this.audioEl&&(this.audioEl.pause(),this.audioEl.src="",this.audioEl=null),this.howl&&(this.howl.stop(),this.howl.unload(),this.howl=null),this.stopTimeUpdateLoop();}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}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 T=class extends h{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 v=class extends Error{constructor(t,i){super(t);this.code=i;this.name="SynxedError";}},P=class extends v{constructor(e){super(e),this.name="SynxedConnectionError";}},I=class extends v{constructor(e){super(typeof e=="string"?e:"Playback failed"),this.name="SynxedPlaybackError";}},H=class extends v{constructor(e){super(e),this.name="SynxedProtocolError";}};function O(n,...e){for(let t of e){let i=n[t];if(typeof i=="string"&&i.length>0)return i}}function rt(n,...e){for(let t of e){let i=n[t];if(typeof i=="number"&&Number.isFinite(i))return i;if(typeof i=="string"&&i!==""&&!Number.isNaN(Number(i)))return Number(i)}}function z(n){let e=n.initAck??n.init_ack;if(!e||typeof e!="object")return null;let t=e,i=O(t,"playbackUrl","playback_url");return i?{sessionId:O(t,"sessionId","session_id")??"",playbackUrl:i,isHls:!!(t.isHls??t.is_hls),heartbeatIntervalMs:rt(t,"heartbeatIntervalMs","heartbeat_interval_ms")??0,contentSummary:O(t,"contentSummary","content_summary")}:null}function st(n){if(!n||typeof n!="object")return null;let e=n,t=e.id;if(typeof t!="string"||!t.trim())return null;let i=e.kind==="internal"?"internal":"catalog",r=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 r=="string"?r:void 0}}function V(n,e){if(!n?.trim())return null;let t;try{t=JSON.parse(n);}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 s=i.tracks;if(!Array.isArray(s)||s.length===0)return null;let a=[];for(let u of s){let c=st(u);c&&a.push(c);}if(a.length===0)return null;let o=typeof i.currentIndex=="number"?i.currentIndex:typeof i.current_index=="number"?i.current_index:0,d=Math.max(0,Math.min(Math.floor(o),a.length-1));return {tracks:a,currentIndex:d}}function m(n,...e){for(let t of e){let i=n[t];if(typeof i=="string")return i}return ""}function F(n,...e){for(let t of e){let i=n[t];if(typeof i=="boolean")return i}return false}function $(n,...e){for(let t of e){let i=n[t];if(typeof i=="number"&&Number.isFinite(i))return i;if(typeof i=="string"&&i.trim()){let r=Number(i);if(Number.isFinite(r))return r}}return 0}function j(n){let e=n.ad;if(!e||typeof e!="object")return null;let t=e,i=m(t,"playbackUrl","playback_url");return i?{adId:m(t,"adId","ad_id"),campaignId:m(t,"campaignId","campaign_id"),playbackUrl:i,isHls:F(t,"isHls","is_hls")||i.includes(".m3u8"),durationSeconds:$(t,"durationSeconds","duration_seconds")||15,isSkippable:F(t,"isSkippable","is_skippable"),skipAfterSeconds:$(t,"skipAfterSeconds","skip_after_seconds"),ctaType:m(t,"ctaType","cta_type"),ctaValue:m(t,"ctaValue","cta_value"),brandName:m(t,"brandName","brand_name"),creativeName:m(t,"creativeName","creative_name"),companionBannerUrl:m(t,"companionBannerUrl","companion_banner_url"),campaignName:m(t,"campaignName","campaign_name")}:null}var C=class extends h{constructor(t){super();this.status="idle";this.volume=.8;this.activeContentKind=0;this.heartbeatTimer=null;this.adPlaying=false;this.currentAd=null;this.config=t,K(!!t.debug),this.transport=new k,this.audio=new E,this.playlist=new T,this.setupListeners(),t.autoConnect&&this.connect();}get currentTrack(){return this.playlist.getCurrentTrack()}get contentKind(){return this.activeContentKind}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 P(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.updateStatus("idle")),this.audio.on("loading",()=>this.updateStatus("loading")),this.audio.on("error",t=>this.emit("error",new I(t))),this.audio.on("timeupdate",t=>this.emit("timeUpdate",t)),this.audio.on("ended",()=>this.handleTrackEnded()),this.playlist.on("trackChanged",t=>this.emit("trackChange",t)),this.playlist.on("queueUpdated",t=>this.emit("queueUpdated",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()});}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,r){this.transport.sendAnalytics({eventType:t,positionMs:this.positionMsForAnalytics(i),extraJson:r?JSON.stringify(r):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 r=this.activeContentKind===4?0:this.positionMsForAnalytics();this.emitAnalytics("heartbeat",r);},i));}applyContentSummary(t){let i=V(t,this.activeContentKind);if(i){this.playlist.setQueue(i.tracks,i.currentIndex);return}t?.trim()&&y("Could not parse contentSummary; queue metadata unavailable.");}async handleServerMessage(t){p("Received server message",t);let i=j(t);if(i){await this.handleAdPlayback(i);return}let r=z(t);if(r){this.currentAd&&this.emit("adEnd",this.currentAd),this.adPlaying=false,this.currentAd=null,p("Loading playback",{url:r.playbackUrl,isHls:r.isHls}),await this.audio.load(r.playbackUrl,r.isHls),this.audio.play(),this.emitAnalytics("stream_start",this.activeContentKind===4?0:void 0),this.startHeartbeat(r.heartbeatIntervalMs),this.applyContentSummary(r.contentSummary);return}let s=t.error;if(s&&typeof s=="object"){let a=s,o=typeof a.message=="string"?a.message:"Unknown server error",d=typeof a.code=="string"?a.code:void 0;this.emit("error",new v(o,d));}}async handleAdPlayback(t){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},p("Loading ad playback",{url:t.playbackUrl,isHls:t.isHls}),await this.audio.load(t.playbackUrl,t.isHls),this.audio.play(),this.emit("adStart",this.currentAd);}skipAd(){if(!this.adPlaying||!this.currentAd||!this.currentAd.isSkippable)return;let t=Math.floor(this.audio.currentTime);t<this.currentAd.skipAfterSeconds*1e3||(this.emitAnalytics("ad_skip",t),this.updateStatus("loading"));}clickAd(){if(!this.adPlaying||!this.currentAd)return;let t=Math.floor(this.audio.currentTime);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){this.emitAnalytics("ad_complete",Math.floor(this.audio.currentTime)),this.currentAd&&this.emit("adEnd",this.currentAd),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)),this.updateStatus("loading");return}this.playlist.hasNext?this.skip():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.audio.stop(),this.transport.disconnect(),this.playlist.reset(),this.removeAllListeners();}};async function R(n,e){let i=`${n.replace(/\/$/,"")}/radio/now-playing`;try{let r=await fetch(i,{...e,headers:{Accept:"application/json",...e?.headers}});if(!r.ok)return null;let a=(await r.json())?.data;return !a?.title||typeof a.title!="string"?null:{title:a.title,station:typeof a.station=="string"?a.station:void 0,isLive:typeof a.isLive=="boolean"?a.isLive:void 0}}catch{return null}}function l(n,e){let t=document.createElement(n);if(e?.className&&(t.className=e.className),e?.attrs)for(let[i,r]of Object.entries(e.attrs))t.setAttribute(i,r);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 f(n,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",n),t.appendChild(i),t}var L="M8 5v14l11-7L8 5z",q="M6 5h4v14H6V5zm8 0h4v14h-4V5z",x="M6 18l8.5-6L6 6v12zM16 6v12h2V6h-2z",Y="M6 6h2v12H6V6zm11.5 12L9 12l8.5-6v12z";function G(){let n="synxed-web-player-styles";if(document.getElementById(n))return;let e=document.createElement("style");e.id=n,e.textContent=`
101
+ `,K=W__namespace.parse(nt).root,N=K.lookupType("SdkClientEnvelope"),O=K.lookupType("SdkServerEnvelope"),E=(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))(E||{}),D=(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))(D||{});var v=class{static encodeClientEnvelope(e){let t=N.create(e);return N.encode(t).finish()}static decodeServerEnvelope(e){let t=O.decode(e);return O.toObject(t,{enums:String,longs:String,bytes:String,defaults:true,oneofs:true})}};var m=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=((...r)=>{t(...r),this.off(e,i);});this.on(e,i);}emit(e,...t){let i=this.listeners.get(e);i&&i.forEach(r=>r(...t));}removeAllListeners(){this.listeners.clear();}};var H=false;function z(n){H=n;}function c(...n){H&&console.debug("[Synxed]",...n);}function y(...n){console.warn("[Synxed]",...n);}function V(n,e){let i=(n.endsWith("/")?n.slice(0,-1):n).replace(/^http:/,"ws:").replace(/^https:/,"wss:"),r=new URL(`${i}/sdk`);return r.searchParams.set("apiKey",e),r.toString()}var w=class extends m{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 r=V(i,t);c("Opening native WebSocket",r.replace(/apiKey=[^&]+/,"apiKey=***")),this.ws=new WebSocket(r),this.ws.binaryType="arraybuffer",this.ws.onopen=()=>{this.connectPromise=null,this.emit("connected");},this.ws.onclose=s=>{let o=s.reason||`code ${s.code}`;this.ws=null,this.connectPromise=null,this.emit("disconnected",o);},this.ws.onerror=()=>{this.emit("error",new Error("WebSocket connection error"));},this.ws.onmessage=s=>{try{let{data:o}=s;if(!(o instanceof ArrayBuffer))return;let a=v.decodeServerEnvelope(new Uint8Array(o));this.emit("message",a);}catch(o){this.emit("error",new Error(`Failed to decode message: ${o}`));}};}async waitForConnection(){if(c("Waiting for connection\u2026"),this.ws?.readyState===WebSocket.OPEN){c("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 r=this.ws;if(r.readyState===WebSocket.OPEN){t();return}let s=()=>{c("WebSocket connected"),d(),t();},o=()=>{y("WebSocket connection error"),d(),i(new Error("WebSocket connection failed"));},a=()=>{d(),i(new Error("WebSocket closed before connection was established"));},d=()=>{r.removeEventListener("open",s),r.removeEventListener("error",o),r.removeEventListener("close",a);};r.addEventListener("open",s),r.addEventListener("error",o),r.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");c("Sending init packet",t),this.sendBytes(v.encodeClientEnvelope({init:t}));}sendControl(t){this.isConnected&&this.sendBytes(v.encodeClientEnvelope({control:t}));}sendAnalytics(t){this.isConnected&&this.sendBytes(v.encodeClientEnvelope({analytics: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 T=class extends m{constructor(){super();this.howl=null;this.hls=null;this.audioEl=null;this.updateTimer=null;}async load(t,i){this.stop(),this.emit("loading"),c("AudioEngine loading",{url:t,isHls:i});let r=/^((?!chrome|android).)*safari/i.test(navigator.userAgent);if(i&&!r)try{let{default:s}=await import('hls.js');if(s.isSupported()){c("Using Hls.js for playback");let a=new URL(t).search;this.hls=new s({xhrSetup:d=>{d.setRequestHeader("ngrok-skip-browser-warning","true");}}),this.audioEl=new Audio,this.hls.loadSource(t),this.hls.attachMedia(this.audioEl),this.audioEl.onplay=()=>{this.emit("playing"),this.startTimeUpdateLoop();},this.audioEl.onpause=()=>{this.emit("paused"),this.stopTimeUpdateLoop();},this.audioEl.onended=()=>{this.emit("ended"),this.stopTimeUpdateLoop();},this.audioEl.onerror=d=>{y("HLS audio element error",d),this.emit("error",d);},this.audioEl.onloadedmetadata=()=>{this.emit("loaded");},this.hls.on(s.Events.ERROR,(d,u)=>{u.fatal&&(y("Fatal HLS error",u),this.emit("error",u));});return}}catch{y("hls.js not available, falling back to native playback");}this.howl=new howler.Howl({src:[t],html5:true,format:i?["m3u8"]:void 0,onload:()=>{c("AudioEngine loaded"),this.emit("loaded");},onloaderror:(s,o)=>{y("AudioEngine load error",o,s),this.emit("error",o);},onplay:()=>{this.emit("playing"),this.startTimeUpdateLoop();},onpause:()=>{this.emit("paused"),this.stopTimeUpdateLoop();},onstop:()=>{this.emit("stopped"),this.stopTimeUpdateLoop();},onend:()=>{this.emit("ended"),this.stopTimeUpdateLoop();}});}play(){this.audioEl?this.audioEl.play().catch(t=>y("Play failed",t)):this.howl?.play();}pause(){this.audioEl?this.audioEl.pause():this.howl?.pause();}stop(){this.hls&&(this.hls.destroy(),this.hls=null),this.audioEl&&(this.audioEl.pause(),this.audioEl.src="",this.audioEl=null),this.howl&&(this.howl.stop(),this.howl.unload(),this.howl=null),this.stopTimeUpdateLoop();}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}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 P=class extends m{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 b=class extends Error{constructor(t,i){super(t);this.code=i;this.name="SynxedError";}},I=class extends b{constructor(e){super(e),this.name="SynxedConnectionError";}},C=class extends b{constructor(e){super(typeof e=="string"?e:"Playback failed"),this.name="SynxedPlaybackError";}},F=class extends b{constructor(e){super(e),this.name="SynxedProtocolError";}};function R(n,...e){for(let t of e){let i=n[t];if(typeof i=="string"&&i.length>0)return i}}function st(n,...e){for(let t of e){let i=n[t];if(typeof i=="number"&&Number.isFinite(i))return i;if(typeof i=="string"&&i!==""&&!Number.isNaN(Number(i)))return Number(i)}}function $(n){let e=n.initAck??n.init_ack;if(!e||typeof e!="object")return null;let t=e,i=R(t,"playbackUrl","playback_url");return i?{sessionId:R(t,"sessionId","session_id")??"",playbackUrl:i,isHls:!!(t.isHls??t.is_hls),heartbeatIntervalMs:st(t,"heartbeatIntervalMs","heartbeat_interval_ms")??0,contentSummary:R(t,"contentSummary","content_summary")}:null}function ot(n){if(!n||typeof n!="object")return null;let e=n,t=e.id;if(typeof t!="string"||!t.trim())return null;let i=e.kind==="internal"?"internal":"catalog",r=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 r=="string"?r:void 0}}function j(n,e){if(!n?.trim())return null;let t;try{t=JSON.parse(n);}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 s=i.tracks;if(!Array.isArray(s)||s.length===0)return null;let o=[];for(let u of s){let h=ot(u);h&&o.push(h);}if(o.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),o.length-1));return {tracks:o,currentIndex:d}}function f(n,...e){for(let t of e){let i=n[t];if(typeof i=="string")return i}return ""}function q(n,...e){for(let t of e){let i=n[t];if(typeof i=="boolean")return i}return false}function Y(n,...e){for(let t of e){let i=n[t];if(typeof i=="number"&&Number.isFinite(i))return i;if(typeof i=="string"&&i.trim()){let r=Number(i);if(Number.isFinite(r))return r}}return 0}function G(n){let e=n.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:Y(t,"durationSeconds","duration_seconds")||15,isSkippable:q(t,"isSkippable","is_skippable"),skipAfterSeconds:Y(t,"skipAfterSeconds","skip_after_seconds"),ctaType:f(t,"ctaType","cta_type"),ctaValue:f(t,"ctaValue","cta_value"),brandName:f(t,"brandName","brand_name"),creativeName:f(t,"creativeName","creative_name"),companionBannerUrl:f(t,"companionBannerUrl","companion_banner_url"),campaignName:f(t,"campaignName","campaign_name")}:null}var A=class extends m{constructor(t){super();this.status="idle";this.volume=.8;this.activeContentKind=0;this.heartbeatTimer=null;this.adPlaying=false;this.currentAd=null;this.config=t,z(!!t.debug),this.transport=new w,this.audio=new T,this.playlist=new P,this.setupListeners(),t.autoConnect&&this.connect();}get currentTrack(){return this.playlist.getCurrentTrack()}get contentKind(){return this.activeContentKind}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 I(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.updateStatus("idle")),this.audio.on("loading",()=>this.updateStatus("loading")),this.audio.on("error",t=>this.emit("error",new C(t))),this.audio.on("timeupdate",t=>this.emit("timeUpdate",t)),this.audio.on("ended",()=>this.handleTrackEnded()),this.playlist.on("trackChanged",t=>this.emit("trackChange",t)),this.playlist.on("queueUpdated",t=>this.emit("queueUpdated",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()});}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,r){this.transport.sendAnalytics({eventType:t,positionMs:this.positionMsForAnalytics(i),extraJson:r?JSON.stringify(r):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 r=this.activeContentKind===4?0:this.positionMsForAnalytics();this.emitAnalytics("heartbeat",r);},i));}applyContentSummary(t){let i=j(t,this.activeContentKind);if(i){this.playlist.setQueue(i.tracks,i.currentIndex);return}t?.trim()&&y("Could not parse contentSummary; queue metadata unavailable.");}async handleServerMessage(t){c("Received server message",t);let i=G(t);if(i){await this.handleAdPlayback(i);return}let r=$(t);if(r){this.currentAd&&this.emit("adEnd",this.currentAd),this.adPlaying=false,this.currentAd=null,c("Loading playback",{url:r.playbackUrl,isHls:r.isHls}),await this.audio.load(r.playbackUrl,r.isHls),this.audio.play(),this.emitAnalytics("stream_start",this.activeContentKind===4?0:void 0),this.startHeartbeat(r.heartbeatIntervalMs),this.applyContentSummary(r.contentSummary);return}let s=t.error;if(s&&typeof s=="object"){let o=s,a=typeof o.message=="string"?o.message:"Unknown server error",d=typeof o.code=="string"?o.code:void 0;this.emit("error",new b(a,d));}}async handleAdPlayback(t){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},c("Loading ad playback",{url:t.playbackUrl,isHls:t.isHls}),await this.audio.load(t.playbackUrl,t.isHls),this.audio.play(),this.emit("adStart",this.currentAd);}skipAd(){if(!this.adPlaying||!this.currentAd||!this.currentAd.isSkippable)return;let t=Math.floor(this.audio.currentTime);t<this.currentAd.skipAfterSeconds*1e3||(this.emitAnalytics("ad_skip",t),this.updateStatus("loading"));}clickAd(){if(!this.adPlaying||!this.currentAd)return;let t=Math.floor(this.audio.currentTime);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){this.emitAnalytics("ad_complete",Math.floor(this.audio.currentTime)),this.currentAd&&this.emit("adEnd",this.currentAd),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)),this.updateStatus("loading");return}this.playlist.hasNext?this.skip():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.audio.stop(),this.transport.disconnect(),this.playlist.reset(),this.removeAllListeners();}};async function L(n,e){let i=`${n.replace(/\/$/,"")}/radio/now-playing`;try{let r=await fetch(i,{...e,headers:{Accept:"application/json",...e?.headers}});if(!r.ok)return null;let o=(await r.json())?.data;return !o?.title||typeof o.title!="string"?null:{title:o.title,station:typeof o.station=="string"?o.station:void 0,isLive:typeof o.isLive=="boolean"?o.isLive:void 0}}catch{return null}}function l(n,e){let t=document.createElement(n);if(e?.className&&(t.className=e.className),e?.attrs)for(let[i,r]of Object.entries(e.attrs))t.setAttribute(i,r);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 g(n,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",n),t.appendChild(i),t}var M="M8 5v14l11-7L8 5z",X="M6 5h4v14H6V5zm8 0h4v14h-4V5z",k="M6 18l8.5-6L6 6v12zM16 6v12h2V6h-2z",J="M6 6h2v12H6V6zm11.5 12L9 12l8.5-6v12z";function Q(){let n="synxed-web-player-styles";if(document.getElementById(n))return;let e=document.createElement("style");e.id=n,e.textContent=`
102
102
  @keyframes synxed-wp-spin { from { transform: rotate(0); } to { transform: rotate(360deg); } }
103
103
  @keyframes synxed-wp-vbar {
104
104
  0%, 100% { transform: scaleY(0.28); opacity: 0.45; }
105
105
  50% { transform: scaleY(1); opacity: 1; }
106
106
  }
107
- `,document.head.appendChild(e);}function X(n){let e=[" \u2014 "," \u2013 "," - "," \u2014"," \u2013"," -"];for(let t of e){let i=n.indexOf(t);if(i>0)return {title:n.slice(0,i).trim(),artist:n.slice(i+t.length).trim()}}return {title:n.trim()}}function J(n="bottom-center",e=16,t=16){let i={position:"fixed",zIndex:"50"};switch(n){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 Q(n={}){return {accent:n.accent??"#22c55e",accentMuted:n.accentMuted??n.accent??"#22c55e",background:n.background??"#051107",backgroundInner:n.backgroundInner??"#0a1f10",border:n.border??"rgba(34, 197, 94, 0.35)",text:n.text??"#ffffff",textMuted:n.textMuted??"rgba(255,255,255,0.35)",stationText:n.stationText??"rgba(34, 197, 94, 0.85)",liveDot:n.liveDot??"#CCFF00",glow:n.glow??"rgba(34, 197, 94, 0.35)"}}function Z(n,e){n.style.setProperty("--sw-accent",e.accent),n.style.setProperty("--sw-accent-muted",e.accentMuted),n.style.setProperty("--sw-bg",e.background),n.style.setProperty("--sw-bg-inner",e.backgroundInner),n.style.setProperty("--sw-border",e.border),n.style.setProperty("--sw-text",e.text),n.style.setProperty("--sw-text-muted",e.textMuted),n.style.setProperty("--sw-station",e.stationText),n.style.setProperty("--sw-live",e.liveDot),n.style.setProperty("--sw-glow",e.glow);}var M=class n{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.options={mode:"wide",attribution:"Synxed",nowPlayingPollMs:12e3,powerByLabel:"Powered by Synxed",avatarUrl:"https://cdn.synxed.com/avater-image/avatar.webp",...e},this.theme=Q(this.options.theme),this.ownsRoot=!e.container,this.root=e.container??document.createElement("div"),this.ownsRoot&&document.body.appendChild(this.root),G(),this.mountShell(),this.initEngine(),this.options.source.type==="radio"&&this.startNowPlayingPoll();}static mount(e){return new n(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 isRadio(){return this.options.source.type==="radio"}get mode(){return this.options.mode??"wide"}mountShell(){let{position:e={},className:t,style:i}=this.options,r=e.placement??"bottom-center",s=e.offsetX??16,a=e.offsetY??(r==="bottom-center"?24:16);this.root.className=t??"",this.root.dataset.synxedWebPlayer=this.mode,Z(this.root,this.theme),Object.assign(this.root.style,J(r,s,a)),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=0,i=0,r=0,s=0,a=u=>{let c=u;if(c.target.closest('button, a, input, [style*="cursor: pointer"]'))return;e=true;let b=this.root.getBoundingClientRect();r=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=`${r}px`,this.root.style.top=`${s}px`,"touches"in c?(t=c.touches[0].clientX,i=c.touches[0].clientY):(t=c.clientX,i=c.clientY),document.addEventListener("mousemove",o,{passive:false}),document.addEventListener("mouseup",d),document.addEventListener("touchmove",o,{passive:false}),document.addEventListener("touchend",d);},o=u=>{if(!e)return;u.preventDefault();let c=u,S,b;"touches"in c?(S=c.touches[0].clientX,b=c.touches[0].clientY):(S=c.clientX,b=c.clientY);let tt=S-t,et=b-i;this.root.style.left=`${r+tt}px`,this.root.style.top=`${s+et}px`;},d=()=>{e=false,document.removeEventListener("mousemove",o),document.removeEventListener("mouseup",d),document.removeEventListener("touchmove",o),document.removeEventListener("touchend",d);};this.root.style.cursor="grab",this.root.addEventListener("mousedown",a),this.root.addEventListener("touchstart",a,{passive:false});}buildAvatar(e,t=false){let i=l("div",{style:{position:"relative",flexShrink:"0"}});this.avatarRing=l("div",{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 r=l("div",{style:{width:"100%",height:"100%",borderRadius:"50%",background:"var(--sw-bg-inner)",overflow:"hidden"}});return this.avatarImgEl=l("img",{attrs:{src:this.options.avatarUrl||"",alt:""},style:{width:"100%",height:"100%",objectFit:"cover",objectPosition:"top",transform:this.mode==="wide"?"scale(1.15)":"scale(1.12)",display:this.options.avatarUrl?"block":"none"}}),this.avatarTextEl=l("div",{text:"S",style:{width:"100%",height:"100%",display:this.options.avatarUrl?"none":"flex",alignItems:"center",justifyContent:"center",color:"var(--sw-accent)",fontWeight:"900",fontSize:`${Math.round(e*.28)}px`}}),r.appendChild(this.avatarImgEl),r.appendChild(this.avatarTextEl),r.style.cursor="default",r.addEventListener("click",s=>{this.currentAd&&this.engine&&(s.stopPropagation(),this.engine.clickAd());}),this.avatarRing.appendChild(r),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("button",{attrs:{type:"button","aria-label":this.options.onMiniClick?"Expand player":"Live DJ"},style:{position:"relative",padding:"0",border:"none",background:"transparent",cursor:this.options.onMiniClick?"pointer":"default"},onClick:()=>this.options.onMiniClick?.()});t.appendChild(this.buildAvatar(72)),this.root.appendChild(t);}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%"}}),r=Math.max(90*.42,40);i.appendChild(l("div",{style:{position:"absolute",top:"8px",bottom:"8px",left:`${r}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 s=this.buildAvatar(90);Object.assign(s.style,{position:"relative",zIndex:"1",marginLeft:"-2px"}),i.appendChild(s);let a=l("div",{style:{position:"relative",zIndex:"1",flex:"1",minWidth:"0",marginLeft:"14px",padding:"18px 8px"}}),o=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"}}),o.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"}}),o.appendChild(this.artistInlineEl),a.appendChild(o),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"}}),a.appendChild(this.footerEl),i.appendChild(a);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.engine?.skip(),children:[f(x,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 r=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"}}),r.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"}}),r.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"}}),r.appendChild(this.footerEl),i.appendChild(r),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 s=l("div",{style:{display:"flex",alignItems:"center",justifyContent:"center",gap:"18px"}});this.isRadio||s.appendChild(l("button",{attrs:{type:"button","aria-label":"Previous"},style:this.roundControlStyle(),onClick:()=>this.engine?.previous(),children:[f(Y,22)]})),this.playBtn=this.createPlayButton(56),s.appendChild(this.playBtn),this.isRadio||(this.skipBtn=l("button",{attrs:{type:"button","aria-label":"Skip"},style:{...this.roundControlStyle(),fontSize:"12px",fontWeight:"bold"},onClick:()=>this.engine?.skip(),children:[f(x,22)]}),s.appendChild(this.skipBtn)),t.appendChild(s),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:[f(L,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,r=new C({apiKey:e,serverUrl:t,autoConnect:true});this.engine=r;let s=o=>{this.isPlaying=o.status==="playing",o.currentTrack&&(this.currentTrack=o.currentTrack),this.setPlayingVisual(this.isPlaying),this.refreshLabels();};r.on("stateChange",s),r.on("trackChange",o=>{this.currentTrack=o,this.refreshLabels();}),r.on("adStart",o=>{this.currentAd=o,this.refreshLabels(),this.updateAvatar();}),r.on("adEnd",()=>{this.currentAd=null,this.refreshLabels(),this.updateAvatar(),this.skipBtn&&(this.skipBtn.replaceChildren(f(x,22)),this.skipBtn.style.opacity="1",this.skipBtn.style.cursor="pointer");}),r.on("timeUpdate",o=>{if(this.currentAd&&this.skipBtn)if(this.currentAd.isSkippable){let d=Math.ceil((this.currentAd.skipAfterSeconds*1e3-o.currentTime)/1e3);d>0?(this.skipBtn.textContent=`${d}s`,this.skipBtn.style.opacity="0.5",this.skipBtn.style.cursor="not-allowed"):this.skipBtn.textContent!==""&&(this.skipBtn.textContent="",this.skipBtn.replaceChildren(f(x,22)),this.skipBtn.style.opacity="1",this.skipBtn.style.cursor="pointer");}else this.skipBtn.style.opacity!=="0.2"&&(this.skipBtn.textContent="",this.skipBtn.replaceChildren(f(x,22)),this.skipBtn.style.opacity="0.2",this.skipBtn.style.cursor="not-allowed");}),(i.type==="radio"?()=>r.playRadio():()=>r.playPlaylist({playlistCode:i.playlistCode}))().catch(()=>{});}startNowPlayingPoll(){let e=async()=>{let t=await R(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);}displayLine(){return this.currentAd?{title:this.currentAd.campaignName||"Advertisement",artist:this.currentAd.creativeName}:this.isRadio&&this.nowPlaying?.title?X(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(){let e=this.currentAd?.companionBannerUrl||this.options.avatarUrl;if(e?(this.avatarImgEl&&(this.avatarImgEl.src=e,this.avatarImgEl.style.display="block"),this.avatarTextEl&&(this.avatarTextEl.style.display="none")):(this.avatarImgEl&&(this.avatarImgEl.style.display="none"),this.avatarTextEl&&(this.avatarTextEl.style.display="flex")),this.avatarRing){let t=this.avatarRing.firstChild;t&&(t.style.cursor=this.currentAd?"pointer":"default");}}setPlayingVisual(e){this.avatarRing&&(this.avatarRing.style.animation=e?"synxed-wp-spin 4s linear infinite":""),this.playBtn&&(this.playBtn.replaceChildren(f(e?q:L,20)),this.playBtn.setAttribute("aria-label",e?"Pause":"Play"));}togglePlay(){this.engine&&(this.isPlaying?this.engine.pause():this.engine.resume());}};
108
- exports.ContentKind=w;exports.ErrorCode=B;exports.SynxedConnectionError=P;exports.SynxedError=v;exports.SynxedPlaybackError=I;exports.SynxedPlayer=C;exports.SynxedProtocolError=H;exports.SynxedWebPlayer=M;exports.TransportManager=k;exports.buildSdkWebSocketUrl=D;exports.fetchRadioNowPlaying=R;//# sourceMappingURL=index.js.map
107
+ `,document.head.appendChild(e);}function Z(n){let e=[" \u2014 "," \u2013 "," - "," \u2014"," \u2013"," -"];for(let t of e){let i=n.indexOf(t);if(i>0)return {title:n.slice(0,i).trim(),artist:n.slice(i+t.length).trim()}}return {title:n.trim()}}function tt(n="bottom-center",e=16,t=16){let i={position:"fixed",zIndex:"50"};switch(n){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 et(n={}){return {accent:n.accent??"#22c55e",accentMuted:n.accentMuted??n.accent??"#22c55e",background:n.background??"#051107",backgroundInner:n.backgroundInner??"#0a1f10",border:n.border??"rgba(34, 197, 94, 0.35)",text:n.text??"#ffffff",textMuted:n.textMuted??"rgba(255,255,255,0.35)",stationText:n.stationText??"rgba(34, 197, 94, 0.85)",liveDot:n.liveDot??"#CCFF00",glow:n.glow??"rgba(34, 197, 94, 0.35)"}}function it(n,e){n.style.setProperty("--sw-accent",e.accent),n.style.setProperty("--sw-accent-muted",e.accentMuted),n.style.setProperty("--sw-bg",e.background),n.style.setProperty("--sw-bg-inner",e.backgroundInner),n.style.setProperty("--sw-border",e.border),n.style.setProperty("--sw-text",e.text),n.style.setProperty("--sw-text-muted",e.textMuted),n.style.setProperty("--sw-station",e.stationText),n.style.setProperty("--sw-live",e.liveDot),n.style.setProperty("--sw-glow",e.glow);}var _=class n{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.options={mode:"wide",attribution:"Synxed",nowPlayingPollMs:12e3,powerByLabel:"Powered by Synxed",avatarUrl:"https://cdn.synxed.com/avater-image/avatar.webp",...e},this.theme=et(this.options.theme),this.ownsRoot=!e.container,this.root=e.container??document.createElement("div"),this.ownsRoot&&document.body.appendChild(this.root),Q(),this.mountShell(),this.initEngine(),this.options.source.type==="radio"&&this.startNowPlayingPoll();}static mount(e){return new n(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 isRadio(){return this.options.source.type==="radio"}get mode(){return this.options.mode??"wide"}mountShell(){let{position:e={},className:t,style:i}=this.options,r=e.placement??"bottom-center",s=e.offsetX??16,o=e.offsetY??(r==="bottom-center"?24:16);this.root.className=t??"",this.root.dataset.synxedWebPlayer=this.mode,it(this.root,this.theme),Object.assign(this.root.style,tt(r,s,o)),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,r=0,s=0,o=0,a=h=>{let p=h,S=p.target;if(this.mode!=="mini"&&S.closest("button, a, input"))return;e=true,t=false;let x=this.root.getBoundingClientRect();s=x.left,o=x.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=`${s}px`,this.root.style.top=`${o}px`,"touches"in p?(i=p.touches[0].clientX,r=p.touches[0].clientY):(i=p.clientX,r=p.clientY),document.addEventListener("mousemove",d,{passive:false}),document.addEventListener("mouseup",u),document.addEventListener("touchmove",d,{passive:false}),document.addEventListener("touchend",u);},d=h=>{if(!e)return;h.preventDefault();let p=h,S,x;"touches"in p?(S=p.touches[0].clientX,x=p.touches[0].clientY):(S=p.clientX,x=p.clientY);let U=S-i,B=x-r;(Math.abs(U)>3||Math.abs(B)>3)&&(t=true),this.root.style.left=`${s+U}px`,this.root.style.top=`${o+B}px`;},u=()=>{e=false,document.removeEventListener("mousemove",d),document.removeEventListener("mouseup",u),document.removeEventListener("touchmove",d),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",h=>{t&&(h.stopPropagation(),h.preventDefault());},true);}buildAvatar(e,t=false){let i=l("div",{style:{position:"relative",flexShrink:"0"}});this.avatarRing=l("div",{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 r=l("div",{style:{width:"100%",height:"100%",borderRadius:"50%",background:"var(--sw-bg-inner)",overflow:"hidden"}});return this.avatarImgEl=l("img",{attrs:{src:this.options.avatarUrl||"",alt:""},style:{width:"100%",height:"100%",objectFit:"cover",objectPosition:"top",transform:this.mode==="wide"?"scale(1.15)":"scale(1.12)",display:this.options.avatarUrl?"block":"none"}}),this.avatarTextEl=l("div",{text:"S",style:{width:"100%",height:"100%",display:this.options.avatarUrl?"none":"flex",alignItems:"center",justifyContent:"center",color:"var(--sw-accent)",fontWeight:"900",fontSize:`${Math.round(e*.28)}px`}}),r.appendChild(this.avatarImgEl),r.appendChild(this.avatarTextEl),r.style.cursor="default",r.addEventListener("click",s=>{this.currentAd&&this.engine&&(s.stopPropagation(),this.engine.clickAd());}),this.avatarRing.appendChild(r),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("button",{attrs:{type:"button","aria-label":"Toggle Play"},style:{position:"relative",padding:"0",border:"none",background:"transparent",cursor:"pointer"},onClick:()=>{this.options.onMiniClick?this.options.onMiniClick():this.togglePlay();}});t.appendChild(this.buildAvatar(72)),this.root.appendChild(t);}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%"}}),r=Math.max(90*.42,40);i.appendChild(l("div",{style:{position:"absolute",top:"8px",bottom:"8px",left:`${r}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 s=this.buildAvatar(90);Object.assign(s.style,{position:"relative",zIndex:"1",marginLeft:"-2px"}),i.appendChild(s);let o=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),o.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"}}),o.appendChild(this.footerEl),i.appendChild(o);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.engine?.skip(),children:[g(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 r=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"}}),r.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"}}),r.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"}}),r.appendChild(this.footerEl),i.appendChild(r),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 s=l("div",{style:{display:"flex",alignItems:"center",justifyContent:"center",gap:"18px"}});this.isRadio||s.appendChild(l("button",{attrs:{type:"button","aria-label":"Previous"},style:this.roundControlStyle(),onClick:()=>this.engine?.previous(),children:[g(J,22)]})),this.playBtn=this.createPlayButton(56),s.appendChild(this.playBtn),this.isRadio||(this.skipBtn=l("button",{attrs:{type:"button","aria-label":"Skip"},style:{...this.roundControlStyle(),fontSize:"12px",fontWeight:"bold"},onClick:()=>this.engine?.skip(),children:[g(k,22)]}),s.appendChild(this.skipBtn)),t.appendChild(s),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:[g(M,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,r=new A({apiKey:e,serverUrl:t,autoConnect:true});this.engine=r;let s=a=>{this.isPlaying=a.status==="playing",a.currentTrack&&(this.currentTrack=a.currentTrack),this.setPlayingVisual(this.isPlaying),this.refreshLabels();};r.on("stateChange",s),r.on("trackChange",a=>{this.currentTrack=a,this.refreshLabels();}),r.on("adStart",a=>{this.currentAd=a,this.refreshLabels(),this.updateAvatar();}),r.on("adEnd",()=>{this.currentAd=null,this.refreshLabels(),this.updateAvatar(),this.skipBtn&&(this.skipBtn.replaceChildren(g(k,22)),this.skipBtn.style.opacity="1",this.skipBtn.style.cursor="pointer");}),r.on("timeUpdate",a=>{if(this.currentAd&&this.skipBtn)if(this.currentAd.isSkippable){let d=Math.ceil((this.currentAd.skipAfterSeconds*1e3-a.currentTime)/1e3);d>0?(this.skipBtn.textContent=`${d}s`,this.skipBtn.style.opacity="0.5",this.skipBtn.style.cursor="not-allowed"):this.skipBtn.textContent!==""&&(this.skipBtn.textContent="",this.skipBtn.replaceChildren(g(k,22)),this.skipBtn.style.opacity="1",this.skipBtn.style.cursor="pointer");}else this.skipBtn.style.opacity!=="0.2"&&(this.skipBtn.textContent="",this.skipBtn.replaceChildren(g(k,22)),this.skipBtn.style.opacity="0.2",this.skipBtn.style.cursor="not-allowed");}),(i.type==="radio"?()=>r.playRadio():()=>r.playPlaylist({playlistCode:i.playlistCode}))().catch(()=>{});}startNowPlayingPoll(){let e=async()=>{let t=await L(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);}displayLine(){return this.currentAd?{title:this.currentAd.campaignName||"Advertisement",artist:this.currentAd.creativeName}:this.isRadio&&this.nowPlaying?.title?Z(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(){let e=this.currentAd?.companionBannerUrl||this.options.avatarUrl;if(e?(this.avatarImgEl&&(this.avatarImgEl.src=e,this.avatarImgEl.style.display="block"),this.avatarTextEl&&(this.avatarTextEl.style.display="none")):(this.avatarImgEl&&(this.avatarImgEl.style.display="none"),this.avatarTextEl&&(this.avatarTextEl.style.display="flex")),this.avatarRing){let t=this.avatarRing.firstChild;t&&(t.style.cursor=this.currentAd?"pointer":"default");}}setPlayingVisual(e){this.avatarRing&&(this.avatarRing.style.animation=e?"synxed-wp-spin 4s linear infinite":""),this.playBtn&&(this.playBtn.replaceChildren(g(e?X:M,20)),this.playBtn.setAttribute("aria-label",e?"Pause":"Play"));}togglePlay(){this.engine&&(this.isPlaying?this.engine.pause():this.engine.resume());}};
108
+ exports.ContentKind=E;exports.ErrorCode=D;exports.SynxedConnectionError=I;exports.SynxedError=b;exports.SynxedPlaybackError=C;exports.SynxedPlayer=A;exports.SynxedProtocolError=F;exports.SynxedWebPlayer=_;exports.TransportManager=w;exports.buildSdkWebSocketUrl=V;exports.fetchRadioNowPlaying=L;//# sourceMappingURL=index.js.map
109
109
  //# sourceMappingURL=index.js.map