@vicaniddouglas/js_aide 1.7.2 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1487,5 +1487,5 @@ var lA=Object.defineProperty;var U2=Object.getOwnPropertyDescriptor;var E2=Objec
1487
1487
  <button class="confirm-btn">Confirm Location</button>
1488
1488
  </div>
1489
1489
  </div>
1490
- `,Y3(),document.body.appendChild(N),R3(),N}function b1(N,A){if(!N){alert("please provide an `onConfirm` callback!");return}let I=D3();return I._callbacks={onConfirm:N,onCancel:A},e3(I),I}var aA=class{constructor(A){this.viewConfigs=A,this.loadedStyles=new Set,this.currentView=null,this.currentModule=null}async loadView(A){if(!A)return;let I=A.replace("-view",""),O=document.getElementById(A);if(!O)return;let U=this.viewConfigs[I];if(!U){console.error(`\u274C No config found for view: ${I}`);return}if(this.currentView!==I){this.currentView&&await this.unloadView(this.currentView);try{U.css&&(console.log(`Loading CSS: ${U.css}`),await this.loadCSS(I,U.css)),console.log(`Loading HTML: ${U.html}`);let E=await fetch(U.html);if(!E.ok)throw new Error(`HTTP ${E.status}`);let K=await E.text();O.innerHTML=K,U.js&&(console.log(`Loading JS: ${U.js}`),await this.loadJS(I,U.js)),this.currentView=I,console.log(`View loaded: ${I}`)}catch(E){console.error(`Failed to load view ${I}:`,E),O.innerHTML=`<p style="color: red; padding: 20px;">Error loading ${I}: ${E.message}</p>`}}}async loadCSS(A,I){let O=`style-${A}`,U=document.getElementById(O);U&&U.remove();let E=document.createElement("link");return E.id=O,E.rel="stylesheet",E.href=I,new Promise(K=>{E.onload=()=>{this.loadedStyles.add(A),console.log(`CSS loaded: ${I}`),K()},E.onerror=()=>{console.log(`CSS failed to load: ${I} (continuing anyway)`),K()},document.head.appendChild(E)})}async loadJS(A,I){try{let O=await import(I);this.currentModule=O,console.log("module====>",O),O.init&&typeof O.init=="function"&&(console.log(`Initializing ${A}...`),O.init()),console.log(`JS loaded: ${I}`)}catch(O){console.log(`No JS module for ${A} or error:`,O)}}async unloadView(A){console.log(`Unloading view: ${A}`);let I=document.getElementById(`style-${A}`);I&&(I.remove(),this.loadedStyles.delete(A)),this.currentModule&&this.currentModule.cleanup&&(console.log(`Cleaning up ${A}...`),this.currentModule.cleanup()),this.currentModule=null,this.currentView=null}};var UA={threshold:0,rootMargin:"0px",root:null,triggerOnce:!1},F=new Map;function s3(N,A){return`${N?N.id||N.tagName+N.className:"viewport"}::${A}`}var gA=class{constructor(A,I,O){this.onEnter=A,this.onExit=I,this.options=O,this.currentlyIntersecting=!1}};function r3(N,A){let I=s3(N,A);return F.has(I)||F.set(I,{observer:null,callbacks:new Map,root:N,rootMargin:A,thresholds:new Set([0])}),F.get(I)}function i3(N){let A=new Set([0]);return N.callbacks.forEach(I=>{I.forEach(O=>{let U=O.options.threshold;Array.isArray(U)?U.forEach(E=>A.add(E)):typeof U=="number"&&A.add(U)})}),Array.from(A).sort((I,O)=>I-O)}function n3(N){let A=i3(N);if(N.observer){let I=Array.from(N.observer.thresholds);if(I.length===A.length&&I.every((U,E)=>U===A[E]))return;N.observer.disconnect()}N.observer=new IntersectionObserver(I=>{o3(N,I)},{root:N.root,rootMargin:N.rootMargin,threshold:A}),N.callbacks.forEach((I,O)=>{N.observer.observe(O)}),N.thresholds=new Set(A)}function o3(N,A){A.forEach(I=>{let O=I.target,U=N.callbacks.get(O);if(!U)return;let E=I.isIntersecting,K=I.intersectionRatio;Array.from(U).forEach(R=>{var Y,i;let{onEnter:M,onExit:L,options:G}=R,T=(Y=G.threshold)!=null?Y:UA.threshold,W=(i=G.triggerOnce)!=null?i:UA.triggerOnce,D=Array.isArray(T)?T.some(s=>K>=s):K>=T;E&&D&&!R.currentlyIntersecting&&(R.currentlyIntersecting=!0,M&&typeof M=="function"&&M(O,I),W&&k1(N,O,R)),!E&&R.currentlyIntersecting&&(R.currentlyIntersecting=!1,L&&typeof L=="function"&&L(O,I))}),U.size===0&&(N.callbacks.delete(O),N.observer&&N.observer.unobserve(O))})}function fA(N,A={}){var R,M,L,G;let I=H3(N);if(!I)return()=>{};let{onEnter:O,onExit:U}=A;if(!O&&!U)return console.warn("[IntersectionWatcher] No callbacks provided. At least onEnter or onExit required."),()=>{};let E={threshold:(R=A.threshold)!=null?R:UA.threshold,rootMargin:(M=A.rootMargin)!=null?M:UA.rootMargin,root:(L=A.root)!=null?L:UA.root,triggerOnce:(G=A.triggerOnce)!=null?G:UA.triggerOnce},K=r3(E.root,E.rootMargin),B=new gA(O,U,E);return K.callbacks.has(I)||K.callbacks.set(I,new Set),K.callbacks.get(I).add(B),n3(K),K.observer.observe(I),()=>{k1(K,I,B)}}function _1(N,A={}){if(typeof N!="string")return console.warn("[IntersectionWatcher] watchAll requires a CSS selector string."),()=>{};let I=document.querySelectorAll(N);if(I.length===0)return console.warn(`[IntersectionWatcher] No elements found for selector: "${N}"`),()=>{};let O=Array.from(I).map(U=>fA(U,A));return()=>{O.forEach(U=>U())}}function k1(N,A,I){let O=N.callbacks.get(A);if(O&&(O.delete(I),O.size===0&&(N.callbacks.delete(A),N.observer&&N.observer.unobserve(A)),N.callbacks.size===0)){N.observer&&(N.observer.disconnect(),N.observer=null);for(let[U,E]of F)if(E===N){F.delete(U);break}}}function H3(N){if(typeof N=="string"){let A=document.querySelector(N);return A||(console.warn(`[IntersectionWatcher] Element not found: "${N}"`),null)}return N instanceof Element?N:(console.warn("[IntersectionWatcher] Invalid target. Must be Element or selector string."),null)}function wA(){F.forEach(N=>{N.observer&&(N.observer.disconnect(),N.observer=null),N.callbacks.clear()}),F.clear()}function q1(N){for(let A of F.values())if(A.callbacks.has(N))return!0;return!1}function z1(){let N=0,A=0;return F.forEach(I=>{N+=I.callbacks.size,I.callbacks.forEach(O=>{A+=O.size})}),{elements:N,callbacks:A,pools:F.size}}typeof window<"u"&&window.addEventListener("beforeunload",()=>{wA()});var b={DEBUG:0,INFO:1,WARN:2,ERROR:3,SILENT:4},$1={level:b.ERROR,timestamps:!0,colors:!0,output:null,namespaces:{}},GA={reset:"\x1B[0m",debug:"\x1B[36m",info:"\x1B[32m",warn:"\x1B[33m",error:"\x1B[31m",namespace:"\x1B[35m"},VA=class N{constructor(A,I={}){if(typeof A!="string")throw new TypeError("Logger namespace must be a string");this.namespace=A,this.config={...$1,...I}}debug(...A){this._log(b.DEBUG,"DEBUG",...A)}info(...A){this._log(b.INFO,"INFO",...A)}warn(...A){this._log(b.WARN,"WARN",...A)}error(...A){this._log(b.ERROR,"ERROR",...A)}isDebugEnabled(){return this._shouldLog(b.DEBUG)}child(A){return new N(`${this.namespace}:${A}`,this.config)}_log(A,I,...O){if(!this._shouldLog(A))return;let U=this._formatMessage(I,...O);this._output(A,U)}_shouldLog(A){let I=this.config.namespaces[this.namespace];return I!==void 0?A>=I:A>=this.config.level}_formatMessage(A,...I){let O=[];if(this.config.timestamps&&O.push(`[${new Date().toISOString()}]`),this.config.colors){let U=GA[A.toLowerCase()]||GA.reset;O.push(`${U}[${A}]${GA.reset}`)}else O.push(`[${A}]`);return this.config.colors?O.push(`${GA.namespace}[${this.namespace}]${GA.reset}`):O.push(`[${this.namespace}]`),O.push(...I),O}_output(A,I){if(this.config.output){this.config.output(A,...I);return}A>=b.ERROR?console.error(...I):A>=b.WARN?console.warn(...I):console.log(...I)}},C3={...$1},vA=new Map;function S(N){if(vA.has(N))return vA.get(N);let A=new VA(N,C3);return vA.set(N,A),A}var a3=S("browser"),FA=class{constructor(){this._detectAll()}_detectAll(){if(this.isBrowser=typeof window<"u"&&typeof document<"u",this.isNode=!this.isBrowser&&typeof process<"u",!this.isBrowser){this._setNonBrowserDefaults();return}this.hasWebSocket=typeof window.WebSocket<"u",this.hasLocalStorage=this._checkStorage("localStorage"),this.hasSessionStorage=this._checkStorage("sessionStorage"),this.hasIndexedDB=this._checkIndexedDB(),this.hasBlob=typeof Blob<"u",this.hasArrayBuffer=typeof ArrayBuffer<"u",this.hasDataView=typeof DataView<"u",this.hasTypedArrays=typeof Uint8Array<"u",this.hasCrypto=typeof crypto<"u"&&typeof crypto.getRandomValues<"u",this.hasWorker=typeof Worker<"u",this.hasSharedWorker=typeof SharedWorker<"u",this.hasServiceWorker=typeof navigator<"u"&&"serviceWorker"in navigator,this.hasNetworkInfo=typeof navigator<"u"&&"connection"in navigator,this.hasBatteryInfo=typeof navigator<"u"&&"getBattery"in navigator,this.userAgent=navigator.userAgent,this.browserInfo=this._identifyBrowser(),this.osInfo=this._identifyOS(),this.isMobile=this._detectMobile(),this.isTablet=this._detectTablet(),this.screenSize={width:window.screen.width,height:window.screen.height},this.pixelRatio=window.devicePixelRatio||1,this.touchSupport="ontouchstart"in window||navigator.maxTouchPoints>0,this.hasPerformanceAPI=typeof performance<"u",this.deviceMemory=navigator.deviceMemory||4,this.hardwareConcurrency=navigator.hardwareConcurrency||2,a3.debug("Browser capabilities detected",{hasWebSocket:this.hasWebSocket,browser:this.browserInfo.name,mobile:this.isMobile,memory:this.deviceMemory})}_setNonBrowserDefaults(){this.hasWebSocket=!1,this.hasLocalStorage=!1,this.hasSessionStorage=!1,this.hasIndexedDB=!1,this.hasBlob=!1,this.hasArrayBuffer=!0,this.hasDataView=!0,this.hasTypedArrays=!0,this.hasCrypto=!1,this.hasWorker=!1,this.hasSharedWorker=!1,this.hasServiceWorker=!1,this.hasNetworkInfo=!1,this.hasBatteryInfo=!1,this.isMobile=!1,this.isTablet=!1,this.touchSupport=!1,this.hasPerformanceAPI=!0,this.deviceMemory=4,this.hardwareConcurrency=2,this.browserInfo={name:"node",version:process.version},this.osInfo={name:process.platform}}_checkStorage(A){try{let I=window[A],O="__websocket_test__";return I.setItem(O,"test"),I.removeItem(O),!0}catch{return!1}}_checkIndexedDB(){try{return typeof window.indexedDB<"u"}catch{return!1}}_identifyBrowser(){var U,E,K,B,R;let A=this.userAgent,I="unknown",O="unknown";return A.indexOf("Firefox")>-1?(I="firefox",O=((U=A.match(/Firefox\/(\d+\.\d+)/))==null?void 0:U[1])||"unknown"):A.indexOf("Chrome")>-1&&A.indexOf("Edg")===-1?(I="chrome",O=((E=A.match(/Chrome\/(\d+\.\d+)/))==null?void 0:E[1])||"unknown"):A.indexOf("Safari")>-1&&A.indexOf("Chrome")===-1?(I="safari",O=((K=A.match(/Version\/(\d+\.\d+)/))==null?void 0:K[1])||"unknown"):A.indexOf("Edg")>-1?(I="edge",O=((B=A.match(/Edg\/(\d+\.\d+)/))==null?void 0:B[1])||"unknown"):(A.indexOf("MSIE")>-1||A.indexOf("Trident")>-1)&&(I="ie",O=((R=A.match(/(?:MSIE |rv:)(\d+\.\d+)/))==null?void 0:R[1])||"unknown"),{name:I,version:O}}_identifyOS(){let A=this.userAgent,I="unknown",O="unknown";if(A.indexOf("Windows")>-1)I="windows",A.indexOf("Windows NT 10.0")>-1?O="10":A.indexOf("Windows NT 6.3")>-1?O="8.1":A.indexOf("Windows NT 6.2")>-1?O="8":A.indexOf("Windows NT 6.1")>-1&&(O="7");else if(A.indexOf("Mac OS X")>-1){I="macos";let U=A.match(/Mac OS X (\d+[._]\d+[._]\d+)/);U&&(O=U[1].replace(/_/g,"."))}else if(A.indexOf("Android")>-1){I="android";let U=A.match(/Android (\d+\.\d+)/);U&&(O=U[1])}else if(A.indexOf("iOS")>-1||A.indexOf("iPhone")>-1||A.indexOf("iPad")>-1){I="ios";let U=A.match(/OS (\d+[_\d]+) like Mac/);U&&(O=U[1].replace(/_/g,"."))}else A.indexOf("Linux")>-1&&(I="linux");return{name:I,version:O}}_detectMobile(){return/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(this.userAgent)}_detectTablet(){return/iPad|Android(?!.*Mobile)|Tablet/i.test(this.userAgent)}getRecommendedTransports(){let A=[];return this.hasWebSocket&&A.push("websocket"),typeof EventSource<"u"&&A.push("eventsource"),A.push("polling"),A}hasMemoryConstraints(){return this.isMobile||this.deviceMemory<=2}getMaxQueueSize(){return this.hasMemoryConstraints()?100:1e3}isLegacyBrowser(){let{name:A,version:I}=this.browserInfo,O=parseFloat(I);return A==="ie"||A==="firefox"&&O<50||A==="chrome"&&O<50||A==="safari"&&O<10}},yA=null;function y(){return yA||(yA=new FA),yA}var Q3=y();function _(N=""){let A=Date.now().toString(36),I=Math.random().toString(36).substring(2,10),O=`${A}${I}`;return N?`${N}_${O}`:O}function WA(N){if(typeof N!="string"||N.trim()===""||!N.startsWith("ws://")&&!N.startsWith("wss://"))return!1;try{let A=new URL(N);return A.hostname&&(A.hostname.includes(".")||A.hostname==="localhost")}catch{return!1}}function TA(N){if(N===null||typeof N!="object")return N;if(N instanceof Date)return new Date(N.getTime());if(N instanceof Array)return N.map(A=>TA(A));if(N instanceof Object){let A={};return Object.keys(N).forEach(I=>{A[I]=TA(N[I])}),A}return N}function xA(N,A){let I=TA(N);return!A||typeof A!="object"||Object.keys(A).forEach(O=>{let U=A[O],E=I[O];U instanceof Array?I[O]=TA(U):U instanceof Object&&E instanceof Object?I[O]=xA(E,U):I[O]=TA(U)}),I}function YA(N,A={}){let{baseDelay:I=1e3,maxDelay:O=3e4,jitter:U=!0}=A,E=I*Math.pow(2,N);if(E=Math.min(E,O),U){let K=.8+.4*Math.random();E=Math.floor(E*K)}return E}function PA(N){return new Promise(A=>setTimeout(A,N))}function EA(){let N,A;return{promise:new Promise((O,U)=>{N=O,A=U}),resolve:N,reject:A}}function bA(N){return typeof N!="string"?!1:N==="/"?!0:/^\/[a-zA-Z0-9_-]+(\/[a-zA-Z0-9_-]+)*$/.test(N)}var k=S("network"),c={OFFLINE:"offline",ONLINE:"online",DEGRADED:"degraded",CHECKING:"checking"},p={UNKNOWN:"unknown",ETHERNET:"ethernet",WIFI:"wifi",CELLULAR:"cellular",NONE:"none"},kA=class{constructor(){this.browser=y(),this.listeners=new Map,this.status={state:c.CHECKING,type:p.UNKNOWN,effectiveType:null,downlink:null,rtt:null,lastChanged:Date.now(),since:Date.now()},this._checkInterval=null,this._checking=!1,this._initialized=!1,this.browser.isBrowser&&this._initBrowserListeners()}_initBrowserListeners(){if(window.addEventListener("online",()=>this._handleBrowserOnline()),window.addEventListener("offline",()=>this._handleBrowserOffline()),this.browser.hasNetworkInfo){let A=navigator.connection||navigator.mozConnection||navigator.webkitConnection;A&&A.addEventListener("change",()=>this._handleConnectionChange())}this._startPeriodicChecks(),this._checkStatus().then(()=>{this._initialized=!0,k.info("Network monitor initialized",this.status)}),k.debug("Network listeners initialized")}_startPeriodicChecks(){this._checkInterval=setInterval(()=>{this._checkStatus()},3e4)}_handleBrowserOnline(){k.info("Browser reported online"),this._checkStatus(!0)}_handleBrowserOffline(){k.warn("Browser reported offline"),this._updateStatus({state:c.OFFLINE,type:p.NONE,lastChanged:Date.now()})}_handleConnectionChange(){k.debug("Network connection changed"),this._checkStatus(!0)}async _checkStatus(A=!1){if(this._checking)return this.status;this._checking=!0,this._updateStatus({state:c.CHECKING});try{if(!this._getBasicOnlineStatus()){this._updateStatus({state:c.OFFLINE,type:p.NONE},A);return}let O=this._getNetworkInfo();if(!await this._verifyConnectivity()){this._updateStatus({state:c.DEGRADED,type:(O==null?void 0:O.type)||p.UNKNOWN,effectiveType:O==null?void 0:O.effectiveType,downlink:O==null?void 0:O.downlink,rtt:O==null?void 0:O.rtt},A);return}let E=this._determineNetworkQuality(O);this._updateStatus({state:E,type:(O==null?void 0:O.type)||p.UNKNOWN,effectiveType:O==null?void 0:O.effectiveType,downlink:O==null?void 0:O.downlink,rtt:O==null?void 0:O.rtt,lastChanged:this.status.state!==E?Date.now():this.status.lastChanged},A)}catch(I){k.error("Error checking network status:",I)}finally{this._checking=!1}}_getBasicOnlineStatus(){return typeof navigator>"u"||typeof navigator.onLine!="boolean"?!0:navigator.onLine}_getNetworkInfo(){if(!this.browser.hasNetworkInfo)return null;let A=navigator.connection||navigator.mozConnection||navigator.webkitConnection;return A?{type:this._mapConnectionType(A.type),effectiveType:A.effectiveType,downlink:A.downlink,rtt:A.rtt,saveData:A.saveData}:null}_mapConnectionType(A){return A&&{wifi:p.WIFI,cellular:p.CELLULAR,ethernet:p.ETHERNET,none:p.NONE,unknown:p.UNKNOWN}[A]||p.UNKNOWN}async _verifyConnectivity(){if(!this._getBasicOnlineStatus())return!1;let A=["https://www.google.com/favicon.ico","https://www.cloudflare.com/favicon.ico","https://www.github.com/favicon.ico"];for(let I of A)try{let O=new AbortController,U=setTimeout(()=>O.abort(),3e3),E=await fetch(I,{method:"HEAD",mode:"no-cors",cache:"no-cache",signal:O.signal});return clearTimeout(U),!0}catch{continue}return!1}_determineNetworkQuality(A){return A&&(A.effectiveType&&(A.effectiveType==="slow-2g"||A.effectiveType==="2g")||A.rtt&&A.rtt>500||A.downlink&&A.downlink<.5)?c.DEGRADED:c.ONLINE}_updateStatus(A,I=!1){let O={...this.status};this.status={...this.status,...A},(I||O.state!==this.status.state||O.type!==this.status.type)&&(k.info(`Network status changed: ${O.state} -> ${this.status.state}`,{type:this.status.type,effectiveType:this.status.effectiveType}),this._notifyListeners(O,this.status))}_notifyListeners(A,I){this.listeners.forEach((O,U)=>{try{O(I,A)}catch(E){k.error(`Error in listener ${U}:`,E)}})}getStatus(){return{...this.status}}isOnline(){return this.status.state===c.ONLINE||this.status.state===c.DEGRADED}isFullyOnline(){return this.status.state===c.ONLINE}isOffline(){return this.status.state===c.OFFLINE}onChange(A){let I=Date.now()+Math.random().toString(36);return this.listeners.set(I,A),()=>{this.listeners.delete(I)}}waitForOnline(A=3e4){let I=EA();if(this.isOnline())return I.resolve(),I.promise;let O=setTimeout(()=>{U(),I.reject(new Error(`Timeout waiting for network after ${A}ms`))},A),U=this.onChange(E=>{(E.state===c.ONLINE||E.state===c.DEGRADED)&&(clearTimeout(O),U(),I.resolve())});return I.promise}async checkNow(){return await this._checkStatus(!0),this.getStatus()}destroy(){this._checkInterval&&(clearInterval(this._checkInterval),this._checkInterval=null),this.listeners.clear(),k.debug("Network monitor destroyed")}},_A=null;function q(){return _A||(_A=new kA),_A}function SA(){return q().isOnline()}var E4=q();var h=S("heartbeat"),g={PING_SENT:"ping_sent",PONG_RECEIVED:"pong_received",MISSED:"missed",DEAD:"dead",LATENCY_UPDATED:"latency_updated"},l={STOPPED:"stopped",RUNNING:"running",WAITING:"waiting",FAILED:"failed"},qA=class{constructor(A={}){this.options={interval:3e4,timeout:1e4,maxMissed:2,adaptive:!0,...A},this.network=q(),this.state=l.STOPPED,this.pingInterval=null,this.pingTimeout=null,this.missedCount=0,this.lastPingTime=0,this.lastPongTime=0,this.latency=null,this.latencyHistory=[],this.pingId=0,this.listeners=new Map,this.pendingPings=new Map,this._sendPing=this._sendPing.bind(this),this._handlePongTimeout=this._handlePongTimeout.bind(this),this._onNetworkChange=this._onNetworkChange.bind(this),h.debug("Heartbeat manager created",this.options)}start(){if(this.state!==l.STOPPED){h.warn("Heartbeat already running or failed");return}if(!this.network.isOnline()){h.info("Network offline, heartbeat will start when online"),this.network.onChange(this._onNetworkChange);return}this.state=l.RUNNING,this.missedCount=0,this._schedulePing(),h.info("Heartbeat started"),this._emit(g.PING_SENT,{state:this.state})}stop(){this.state=l.STOPPED,this._clearTimers(),this.missedCount=0,this.pendingPings.clear(),h.info("Heartbeat stopped")}reset(){this.stop(),this.missedCount=0,this.latency=null,this.pendingPings.clear(),h.debug("Heartbeat reset")}pongReceived(A){let I=Date.now();this.lastPongTime=I;let O=null,U=null;if(A&&A.id)O=A.id,U=this.pendingPings.get(O)||null,this.pendingPings.delete(O);else{let E=Array.from(this.pendingPings.entries()).sort((K,B)=>B[1]-K[1])[0];E&&(O=E[0],U=E[1],this.pendingPings.delete(O))}if(U){let E=I-U;this._updateLatency(E)}this.pingTimeout&&(clearTimeout(this.pingTimeout),this.pingTimeout=null),this.missedCount=0,this.state=l.RUNNING,h.debug("Pong received",{pingId:O,latency:this.latency,missed:this.missedCount}),this._emit(g.PONG_RECEIVED,{latency:this.latency,pingId:O}),this._schedulePing()}getStatus(){return{state:this.state,missed:this.missedCount,latency:this.latency,lastPing:this.lastPingTime,lastPong:this.lastPongTime,uptime:this.lastPingTime?Date.now()-this.lastPingTime:0}}getLatency(){return this.latency}isHealthy(){return this.state===l.RUNNING&&this.missedCount===0}isFailing(){return this.state===l.FAILED||this.missedCount>=this.options.maxMissed}onEvent(A){let I=Date.now()+Math.random().toString(36);return this.listeners.set(I,A),()=>{this.listeners.delete(I)}}_schedulePing(){this._clearTimers();let A=this.options.interval;this.options.adaptive&&this.network.getStatus().state==="degraded"&&(A=A*1.5),this.pingInterval=setTimeout(()=>{this._sendPing()},A)}_sendPing(){if(this.state===l.STOPPED)return;if(!this.network.isOnline()){h.debug("Network offline, skipping ping"),this._schedulePing();return}let A=Date.now();this.lastPingTime=A;let I=this.pingId++;this.pendingPings.set(I,A);try{let O={type:"ping",id:I,timestamp:A};this.options.sendPing(O),h.debug("Ping sent",{pingId:I}),this._emit(g.PING_SENT,{pingId:I})}catch(O){h.error("Failed to send ping:",O),this._handlePongTimeout();return}this.state=l.WAITING,this.pingTimeout=setTimeout(()=>{this._handlePongTimeout(I)},this.options.timeout)}_handlePongTimeout(A){if(this.missedCount++,h.warn("Pong timeout",{pingId:A,missed:this.missedCount,max:this.options.maxMissed}),this._emit(g.MISSED,{pingId:A,missed:this.missedCount,total:this.options.maxMissed}),this.pendingPings.delete(A),this.missedCount>=this.options.maxMissed){this._handleDeadConnection();return}this.state=l.RUNNING,this._schedulePing()}_handleDeadConnection(){this.state=l.FAILED,h.error("Heartbeat failed - connection appears dead",{missed:this.missedCount,lastPing:this.lastPingTime,lastPong:this.lastPongTime}),this._emit(g.DEAD,{missed:this.missedCount,latency:this.latency}),this.stop()}_updateLatency(A){this.latencyHistory.push(A),this.latencyHistory.length>10&&this.latencyHistory.shift();let I=this.latencyHistory.reduce((O,U)=>O+U,0)/this.latencyHistory.length;this.latency=Math.round(I),this._emit(g.LATENCY_UPDATED,{latency:this.latency,raw:A})}_onNetworkChange(A){A.state==="online"&&this.state===l.STOPPED&&(h.info("Network restored, starting heartbeat"),this.start()),A.state==="offline"&&this.state!==l.STOPPED&&(h.info("Network offline, stopping heartbeat"),this.stop())}_clearTimers(){this.pingInterval&&(clearTimeout(this.pingInterval),this.pingInterval=null),this.pingTimeout&&(clearTimeout(this.pingTimeout),this.pingTimeout=null)}_emit(A,I){this.listeners.forEach(O=>{try{O(A,I)}catch(U){h.error("Error in heartbeat listener:",U)}})}};function zA(N){return new qA(N)}var H=S("connection"),C={DISCONNECTED:"disconnected",CONNECTING:"connecting",CONNECTED:"connected",DISCONNECTING:"disconnecting",RECONNECTING:"reconnecting",FAILED:"failed"},f={INTENTIONAL:"intentional",NETWORK_LOST:"network_lost",SERVER_CLOSED:"server_closed",TIMEOUT:"timeout",HEARTBEAT_FAILED:"heartbeat_failed",ERROR:"error"},d={CONNECTED:"connected",DISCONNECTED:"disconnected",RECONNECTING:"reconnecting",RECONNECT_FAILED:"reconnect_failed",FAILED:"failed",STATE_CHANGED:"state_changed",STATS_UPDATED:"stats_updated"},$A=class{constructor(A,I={}){if(!WA(A))throw new Error(`Invalid WebSocket URL: ${A}`);this.url=A,this.options={timeout:1e4,autoConnect:!1,reconnect:{maxAttempts:10,baseDelay:1e3,maxDelay:3e4,jitter:!0},heartbeat:{enabled:!0,interval:3e4,timeout:1e4},createWebSocket:O=>new WebSocket(O),...I},this.network=q(),this.browser=y(),this.state=C.DISCONNECTED,this.ws=null,this.heartbeat=null,this.connectionAttempts=0,this.reconnectAttempts=0,this.lastConnectedAt=null,this.lastDisconnectedAt=null,this.disconnectReason=null,this.stats={connectedAt:null,disconnectedAt:null,connectionDuration:0,messagesSent:0,messagesReceived:0,bytesSent:0,bytesReceived:0,reconnectCount:0},this._connectionPromise=null,this._connectionResolve=null,this._connectionReject=null,this._disconnectPromise=null,this._disconnectResolve=null,this._reconnectTimer=null,this.listeners=new Map,this._networkUnsubscribe=this.network.onChange(O=>this._onNetworkChange(O)),this._handleOpen=this._handleOpen.bind(this),this._handleMessage=this._handleMessage.bind(this),this._handleClose=this._handleClose.bind(this),this._handleError=this._handleError.bind(this),this._handleHeartbeatEvent=this._handleHeartbeatEvent.bind(this),H.info("Connection manager created",{url:A}),this.options.autoConnect&&setTimeout(()=>this.connect(),0)}connect(){return this.state===C.CONNECTED?Promise.resolve():this.state===C.CONNECTING&&this._connectionPromise?this._connectionPromise:this.network.isOnline()?(this._setState(C.CONNECTING),this.reconnectAttempts=0,this.disconnectReason=null,this._connectionPromise=new Promise((A,I)=>{this._connectionResolve=A,this._connectionReject=I}),this._performConnection(),this._connectionPromise):(H.warn("Cannot connect: network offline"),Promise.reject(new Error("Network offline")))}disconnect(A=1e3,I=""){if(this.state===C.DISCONNECTED)return Promise.resolve();if(this._clearReconnectTimer(),this.disconnectReason=f.INTENTIONAL,this._setState(C.DISCONNECTING),this._disconnectPromise=new Promise(O=>{this._disconnectResolve=O}),this.heartbeat&&this.heartbeat.stop(),this.ws){this.ws.onopen=null,this.ws.onmessage=null,this.ws.onclose=null,this.ws.onerror=null;try{this.ws.close(A,I)}catch(O){H.error("Error closing WebSocket:",O)}}else this._cleanup(),this._setState(C.DISCONNECTED),this._disconnectResolve&&(this._disconnectResolve(),this._disconnectResolve=null);return this._disconnectPromise}async reconnect(){return H.info("Forcing reconnection"),this.state!==C.DISCONNECTED&&await this.disconnect(1e3,"Forced reconnection"),await PA(100),this.connect()}getStatus(){let A=Date.now();return{state:this.state,url:this.url,connectedAt:this.stats.connectedAt,disconnectedAt:this.stats.disconnectedAt,uptime:this.stats.connectedAt?A-this.stats.connectedAt:0,reconnectAttempts:this.reconnectAttempts,reconnectCount:this.stats.reconnectCount,disconnectReason:this.disconnectReason,messages:{sent:this.stats.messagesSent,received:this.stats.messagesReceived},bytes:{sent:this.stats.bytesSent,received:this.stats.bytesReceived},heartbeat:this.heartbeat?this.heartbeat.getStatus():null,network:this.network.getStatus()}}isConnected(){return this.state===C.CONNECTED}isHealthy(){return this.isConnected()&&(!this.heartbeat||this.heartbeat.isHealthy())}send(A){if(!this.isConnected()||!this.ws)throw new Error("Not connected");try{typeof A=="string"?this.stats.bytesSent+=new Blob([A]).size:A instanceof Blob?this.stats.bytesSent+=A.size:A instanceof ArrayBuffer&&(this.stats.bytesSent+=A.byteLength),this.ws.send(A),this.stats.messagesSent++}catch(I){throw H.error("Send failed:",I),I}}onEvent(A){let I=Date.now()+Math.random().toString(36);return this.listeners.set(I,A),()=>{this.listeners.delete(I)}}destroy(){H.info("Destroying connection manager"),this.state!==C.DISCONNECTED&&this.disconnect(1e3,"Manager destroyed"),this._networkUnsubscribe&&this._networkUnsubscribe(),this._clearReconnectTimer(),this.listeners.clear()}_performConnection(){if(!this.network.isOnline()){this._handleConnectionFailure(new Error("Network offline"),!0);return}H.info("Connecting...",{attempt:this.reconnectAttempts+1,url:this.url});try{this.ws=this.options.createWebSocket(this.url),this.ws.onopen=this._handleOpen,this.ws.onmessage=this._handleMessage,this.ws.onclose=this._handleClose,this.ws.onerror=this._handleError,this._connectionTimeout=setTimeout(()=>{if(this.state===C.CONNECTING){let A=new Error(`Connection timeout after ${this.options.timeout}ms`);this._handleConnectionFailure(A)}},this.options.timeout)}catch(A){this._handleConnectionFailure(A)}}_handleOpen(){H.info("WebSocket opened"),this._connectionTimeout&&(clearTimeout(this._connectionTimeout),this._connectionTimeout=null);let A=Date.now();this.lastConnectedAt=A,this.stats.connectedAt=A,this.stats.disconnectedAt=null,this.reconnectAttempts>0&&this.stats.reconnectCount++,this.reconnectAttempts=0,this.options.heartbeat.enabled&&this._setupHeartbeat(),this._setState(C.CONNECTED),this._connectionResolve&&(this._connectionResolve(),this._connectionResolve=null,this._connectionReject=null),this._emit(d.CONNECTED,{timestamp:A})}_handleMessage(A){if(this.stats.messagesReceived++,typeof A.data=="string"?this.stats.bytesReceived+=new Blob([A.data]).size:A.data instanceof Blob?this.stats.bytesReceived+=A.data.size:A.data instanceof ArrayBuffer&&(this.stats.bytesReceived+=A.data.byteLength),this.heartbeat)try{let I=JSON.parse(A.data);if(I.type==="pong"){this.heartbeat.pongReceived(I);return}}catch{}this._emit("message",A.data)}_handleClose(A){H.info("WebSocket closed",{code:A.code,reason:A.reason,wasClean:A.wasClean});let I=this.disconnectReason===f.INTENTIONAL;if(this.lastDisconnectedAt=Date.now(),this.stats.disconnectedAt=Date.now(),this.stats.connectedAt&&(this.stats.connectionDuration+=this.lastDisconnectedAt-this.stats.connectedAt),this.heartbeat&&(this.heartbeat.stop(),this.heartbeat=null),this._cleanup(),I){this._setState(C.DISCONNECTED),this._disconnectResolve&&(this._disconnectResolve(),this._disconnectResolve=null),this._emit(d.DISCONNECTED,{reason:f.INTENTIONAL,code:A.code});return}let O;this.network.isOnline()?A.code===1006?O=f.TIMEOUT:O=f.SERVER_CLOSED:O=f.NETWORK_LOST,this.disconnectReason=O,this._handleReconnection(O,A)}_handleError(A){H.error("WebSocket error",A),this._emit("error",A)}_handleConnectionFailure(A,I=!1){H.error("Connection failed:",A.message),this._connectionTimeout&&(clearTimeout(this._connectionTimeout),this._connectionTimeout=null),this._cleanup(),this._connectionReject&&(this._connectionReject(A),this._connectionResolve=null,this._connectionReject=null);let O=I?f.NETWORK_LOST:f.ERROR;this._handleReconnection(O,null,A)}_handleReconnection(A,I,O){if(this._setState(C.RECONNECTING),this.disconnectReason=A,this._emit(d.DISCONNECTED,{reason:A,code:I==null?void 0:I.code,error:O==null?void 0:O.message}),this.reconnectAttempts>=this.options.reconnect.maxAttempts){H.error("Max reconnection attempts reached",{attempts:this.reconnectAttempts}),this._setState(C.FAILED),this._emit(d.FAILED,{reason:"max_attempts",attempts:this.reconnectAttempts});return}let U=YA(this.reconnectAttempts,this.options.reconnect);H.info(`Reconnecting in ${U}ms`,{attempt:this.reconnectAttempts+1,max:this.options.reconnect.maxAttempts}),this._emit(d.RECONNECTING,{attempt:this.reconnectAttempts+1,maxAttempts:this.options.reconnect.maxAttempts,delay:U}),this._clearReconnectTimer(),this._reconnectTimer=setTimeout(()=>{this.reconnectAttempts++,this._performConnection()},U)}_onNetworkChange(A){H.debug("Network changed:",A.state),A.state==="online"&&(this.state===C.RECONNECTING||this.state===C.DISCONNECTED)&&(H.info("Network restored, retrying connection"),this._clearReconnectTimer(),this._performConnection()),A.state==="offline"&&this.isConnected()&&H.warn("Network lost, connection will likely fail")}_handleHeartbeatEvent(A,I){A===g.DEAD&&(H.error("Heartbeat dead, reconnecting"),this.disconnectReason=f.HEARTBEAT_FAILED,this.ws&&this.ws.close()),A===g.LATENCY_UPDATED&&this._emit("latency",{latency:I.latency})}_setupHeartbeat(){this.ws&&(this.heartbeat=zA({interval:this.options.heartbeat.interval,timeout:this.options.heartbeat.timeout,sendPing:A=>{try{this.ws.send(JSON.stringify(A)),this.stats.messagesSent++}catch(I){H.error("Failed to send ping:",I)}}}),this.heartbeat.onEvent(this._handleHeartbeatEvent),this.heartbeat.start())}_setState(A){let I=this.state;I!==A&&(this.state=A,H.debug(`State: ${I} -> ${A}`),this._emit(d.STATE_CHANGED,{from:I,to:A}))}_cleanup(){this.ws&&(this.ws.onopen=null,this.ws.onmessage=null,this.ws.onclose=null,this.ws.onerror=null,this.ws=null),this._connectionTimeout&&(clearTimeout(this._connectionTimeout),this._connectionTimeout=null)}_clearReconnectTimer(){this._reconnectTimer&&(clearTimeout(this._reconnectTimer),this._reconnectTimer=null)}_emit(A,I){this.listeners.forEach(O=>{try{O(A,I)}catch(U){H.error("Error in event listener:",U)}})}};function jA(N,A={}){return new $A(N,A)}var n=S("transport"),P={WEBSOCKET:"websocket",EVENTSOURCE:"eventsource",POLLING:"polling",NONE:"none"},e={IDLE:"idle",CONNECTING:"connecting",CONNECTED:"connected",DISCONNECTED:"disconnected",FAILED:"failed"},t={CONNECT:"connect",MESSAGE:"message",DISCONNECT:"disconnect",ERROR:"error",TRANSPORT_CHANGED:"transport_changed"},tA=class{constructor(A,I={}){this.url=A,this.options=I,this.state=e.IDLE,this.listeners=new Map}connect(){throw new Error("Not implemented")}disconnect(){throw new Error("Not implemented")}send(A){throw new Error("Not implemented")}on(A,I){return this.listeners.has(A)||this.listeners.set(A,[]),this.listeners.get(A).push(I),()=>{let O=this.listeners.get(A)||[],U=O.indexOf(I);U!==-1&&O.splice(U,1)}}_emit(A,I){(this.listeners.get(A)||[]).forEach(U=>{try{U(I)}catch(E){n.error("Error in event listener:",E)}})}getState(){return this.state}getType(){return P.NONE}},QA=class extends tA{constructor(A,I={}){super(A,I),this.ws=null,this.pendingMessages=[],this.type=P.WEBSOCKET}getType(){return this.type}connect(){if(this.state===e.IDLE){this.state=e.CONNECTING,n.info("WebSocket connecting to:",this.url);try{this.ws=new WebSocket(this.url),this.ws.onopen=()=>{for(n.info("WebSocket connected"),this.state=e.CONNECTED;this.pendingMessages.length>0;){let A=this.pendingMessages.shift();this.send(A)}this._emit(t.CONNECT,{transport:this.type})},this.ws.onmessage=A=>{this._emit(t.MESSAGE,A.data)},this.ws.onclose=A=>{n.info("WebSocket closed",{code:A.code,reason:A.reason}),this.state=e.DISCONNECTED,this._emit(t.DISCONNECT,{code:A.code,reason:A.reason,wasClean:A.wasClean})},this.ws.onerror=A=>{n.error("WebSocket error:",A),this._emit(t.ERROR,A)}}catch(A){n.error("WebSocket creation failed:",A),this.state=e.FAILED,this._emit(t.ERROR,A)}}}disconnect(){this.ws&&(this.ws.close(1e3,"Intentional disconnect"),this.ws=null),this.state=e.DISCONNECTED,this.pendingMessages=[]}send(A){if(this.state===e.CONNECTED&&this.ws)try{return this.ws.send(A),!0}catch(I){return n.error("WebSocket send failed:",I),!1}else return this.pendingMessages.push(A),!1}},XA=class extends tA{constructor(A,I={}){super(A,I),this.es=null,this.sendQueue=[],this.type=P.EVENTSOURCE,this.connectUrl=A,this.sendUrl=A.replace(/^ws/,"http").replace(/^wss/,"https")}getType(){return this.type}connect(){if(this.state===e.IDLE){this.state=e.CONNECTING,n.info("EventSource connecting to:",this.connectUrl);try{this.es=new EventSource(this.connectUrl),this.es.onopen=()=>{n.info("EventSource connected"),this.state=e.CONNECTED,this._emit(t.CONNECT,{transport:this.type})},this.es.onmessage=A=>{this._emit(t.MESSAGE,A.data)},this.es.onerror=A=>{n.error("EventSource error:",A),this.state===e.CONNECTED&&(this.state=e.DISCONNECTED,this._emit(t.DISCONNECT,{reason:"error"})),this._emit(t.ERROR,A)}}catch(A){n.error("EventSource creation failed:",A),this.state=e.FAILED,this._emit(t.ERROR,A)}}}disconnect(){this.es&&(this.es.close(),this.es=null),this.state=e.DISCONNECTED,this.sendQueue=[]}send(A){if(this.state!==e.CONNECTED)return this.sendQueue.push(A),!1;try{return fetch(this.sendUrl,{method:"POST",body:A,headers:{"Content-Type":"application/json"},keepalive:!0}).catch(I=>{n.error("EventSource send failed:",I),this._emit(t.ERROR,I)}),!0}catch(I){return n.error("EventSource send failed:",I),!1}}},A1=class extends tA{constructor(A,I={}){super(A,I),this.pollingInterval=I.pollingInterval||3e3,this.pollingActive=!1,this.sendQueue=[],this.messageQueue=[],this.pollTimeout=null,this.type=P.POLLING,this.baseUrl=A.replace(/^ws/,"http").replace(/^wss/,"https"),this.pollUrl=`${this.baseUrl}/poll`,this.sendUrl=`${this.baseUrl}/send`}getType(){return this.type}connect(){this.state===e.IDLE&&(this.state=e.CONNECTING,n.info("Polling connecting to:",this.baseUrl),this.pollingActive=!0,this._poll(),this.state=e.CONNECTED,this._emit(t.CONNECT,{transport:this.type}))}disconnect(){this.pollingActive=!1,this.pollTimeout&&(clearTimeout(this.pollTimeout),this.pollTimeout=null),this.state=e.DISCONNECTED,this.sendQueue=[],this.messageQueue=[]}send(A){if(this.state!==e.CONNECTED)return this.sendQueue.push(A),!1;try{return fetch(this.sendUrl,{method:"POST",body:A,headers:{"Content-Type":"application/json"},keepalive:!0}).catch(I=>{n.error("Polling send failed:",I),this._emit(t.ERROR,I)}),!0}catch(I){return n.error("Polling send failed:",I),!1}}async _poll(){if(this.pollingActive){try{let A=new AbortController,I=setTimeout(()=>A.abort(),3e4),O=await fetch(this.pollUrl,{method:"GET",signal:A.signal,headers:{"Cache-Control":"no-cache"}});if(clearTimeout(I),O.ok){let U=await O.text();U&&this._emit(t.MESSAGE,U)}}catch(A){if(A.name==="AbortError")n.debug("Poll timeout, restarting");else if(n.error("Poll failed:",A),this._emit(t.ERROR,A),!navigator.onLine){this.state=e.DISCONNECTED,this._emit(t.DISCONNECT,{reason:"network_lost"});return}}this.pollingActive&&(this.pollTimeout=setTimeout(()=>this._poll(),this.pollingInterval))}}},I1=class{constructor(A,I={}){this.url=A,this.options={transports:[P.WEBSOCKET,P.EVENTSOURCE,P.POLLING],timeout:1e4,pollingInterval:3e3,...I},this.browser=y(),this.network=q(),this.currentTransport=null,this.transportType=P.NONE,this.state=e.IDLE,this.listeners=new Map,this.availableTransports=this._getAvailableTransports(),n.info("Transport manager created",{available:this.availableTransports})}async connect(){if(this.state===e.CONNECTED)return;if(this.state=e.CONNECTING,!this.network.isOnline()){let I=new Error("Network offline");throw this._emit(t.ERROR,I),I}for(let I of this.availableTransports){n.info(`Trying transport: ${I}`);try{await this._tryTransport(I),n.info(`Connected using ${I}`),this.transportType=I,this.state=e.CONNECTED,this._emit(t.TRANSPORT_CHANGED,{transport:I}),this._emit(t.CONNECT,{transport:I});return}catch(O){n.warn(`Transport ${I} failed:`,O.message)}}this.state=e.FAILED;let A=new Error("No transport available");throw this._emit(t.ERROR,A),A}disconnect(){this.currentTransport&&(this.currentTransport.disconnect(),this.currentTransport=null),this.transportType=P.NONE,this.state=e.DISCONNECTED,this._emit(t.DISCONNECT,{reason:"intentional"})}send(A){return!this.currentTransport||this.state!==e.CONNECTED?!1:this.currentTransport.send(A)}getTransportType(){return this.transportType}getState(){return this.state}on(A,I){return this.listeners.has(A)||this.listeners.set(A,[]),this.listeners.get(A).push(I),()=>{let O=this.listeners.get(A)||[],U=O.indexOf(I);U!==-1&&O.splice(U,1)}}_tryTransport(A){return new Promise((I,O)=>{let U;switch(A){case P.WEBSOCKET:U=new QA(this.url,this.options);break;case P.EVENTSOURCE:U=new XA(this.url,this.options);break;case P.POLLING:U=new A1(this.url,this.options);break;default:O(new Error(`Unknown transport: ${A}`));return}let E,K,B=()=>{E&&E(),K&&K(),clearTimeout(R)},R=setTimeout(()=>{U.disconnect(),B(),O(new Error(`Transport ${A} timeout`))},this.options.timeout);E=U.on(t.CONNECT,()=>{this.currentTransport=U,this._forwardTransportEvents(U),B(),I()}),K=U.on(t.ERROR,M=>{B(),O(M||new Error(`Transport ${A} failed`))}),U.connect()})}_forwardTransportEvents(A){[t.MESSAGE,t.DISCONNECT,t.ERROR].forEach(O=>{A.on(O,U=>{this._emit(O,U),O===t.DISCONNECT&&(this.state=e.DISCONNECTED)})})}_getAvailableTransports(){return this.options.transports.filter(A=>{switch(A){case P.WEBSOCKET:return this.browser.hasWebSocket;case P.EVENTSOURCE:return typeof EventSource<"u";case P.POLLING:return!0;default:return!1}})}_emit(A,I){(this.listeners.get(A)||[]).forEach(U=>{try{U(I)}catch(E){n.error("Error in event listener:",E)}})}};function O1(N,A={}){return new I1(N,A)}var eA=S("client"),P3={autoConnect:!1,timeout:1e4,reconnect:!0,reconnectOptions:{maxAttempts:10,baseDelay:1e3,maxDelay:3e4,jitter:!0},heartbeat:{enabled:!0,interval:3e4,timeout:1e4},transport:{transports:["websocket","eventsource","polling"],pollingInterval:3e3},debug:!1},N1=class{constructor(A,I={}){if(!WA(A))throw new TypeError(`Invalid WebSocket URL: ${A}`);this.url=A,this.options=xA(P3,I),this.options.debug&&eA.debug("Debug mode enabled"),this.browser=y(),this.transport=O1(A,{transports:this.options.transport.transports,timeout:this.options.timeout,pollingInterval:this.options.transport.pollingInterval}),this.connection=jA(A,{timeout:this.options.timeout,reconnect:{maxAttempts:this.options.reconnectOptions.maxAttempts,baseDelay:this.options.reconnectOptions.baseDelay,maxDelay:this.options.reconnectOptions.maxDelay,jitter:this.options.reconnectOptions.jitter},heartbeat:this.options.heartbeat,transport:this.transport}),this.messageHandlers=new Map,this.eventHandlers={open:[],message:[],close:[],error:[],reconnect:[],reconnectAttempt:[]},this.messageCounter=0,this.pendingAcks=new Map,this._handleConnectionEvent=this._handleConnectionEvent.bind(this),this._handleTransportMessage=this._handleTransportMessage.bind(this),this._setupEventForwarding(),eA.info("WebSocket client created",{url:A,options:this.options,browser:this.browser.browserInfo.name}),this.options.autoConnect&&setTimeout(()=>this.connect(),0)}_setupEventForwarding(){this.connection.onEvent((A,I)=>{A==="message"?this._handleTransportMessage(I):this._handleConnectionEvent(A,I)}),this.transport.on(t.MESSAGE,A=>{this._handleTransportMessage(A)}),this.transport.on(t.ERROR,A=>{this._triggerEvent("error",A)})}_handleConnectionEvent(A,I){switch(A){case d.CONNECTED:this._triggerEvent("open",I);break;case d.DISCONNECTED:this._triggerEvent("close",I);break;case d.RECONNECTING:this._triggerEvent("reconnectAttempt",{attempt:I.attempt,maxAttempts:I.maxAttempts,delay:I.delay});break;case d.FAILED:this._triggerEvent("error",new Error(`Connection failed: ${I.reason}`));break;case"latency":this._triggerEvent("latency",I);break}}_handleTransportMessage(A){let I=A;if(typeof A=="string")try{I=JSON.parse(A)}catch{}if(I&&I.type==="ack"&&I.id){this._handleAck(I.id,I);return}I&&I.type&&this.messageHandlers.has(I.type)&&this.messageHandlers.get(I.type).forEach(U=>{try{U(I.data||I)}catch(E){eA.error("Error in message handler:",E)}}),this._triggerEvent("message",I)}_handleAck(A,I){if(this.pendingAcks.has(A)){let{resolve:O,reject:U}=this.pendingAcks.get(A);I.success?O(I.result||I):U(new Error(I.error||"Unknown error")),this.pendingAcks.delete(A)}}connect(){return this.connection.connect()}disconnect(A=1e3,I=""){return this.connection.disconnect(A,I)}send(A){if(!this.isConnected())throw new Error("Not connected");let I=A;A&&typeof A=="object"&&!(A instanceof ArrayBuffer)&&!(A instanceof Blob)&&(I=JSON.stringify(A)),this.connection.send(I)}sendWithAck(A,I,O=1e4){if(!this.isConnected())return Promise.reject(new Error("Not connected"));let U=`${Date.now()}-${this.messageCounter++}`,E=EA(),K={type:A,data:I,id:U,ack:!0},B=setTimeout(()=>{this.pendingAcks.has(U)&&(this.pendingAcks.delete(U),E.reject(new Error("Acknowledgement timeout")))},O);return this.pendingAcks.set(U,{resolve:R=>{clearTimeout(B),E.resolve(R)},reject:R=>{clearTimeout(B),E.reject(R)}}),this.connection.send(JSON.stringify(K)),E.promise}onMessage(A,I){return this.messageHandlers.has(A)||this.messageHandlers.set(A,[]),this.messageHandlers.get(A).push(I),this}offMessage(A,I){if(!this.messageHandlers.has(A))return this;if(I){let O=this.messageHandlers.get(A),U=O.indexOf(I);U!==-1&&O.splice(U,1)}else this.messageHandlers.delete(A);return this}on(A,I){if(!["open","message","close","error","reconnect","reconnectAttempt","latency"].includes(A))throw new TypeError(`Unknown event: ${A}`);if(typeof I!="function")throw new TypeError("Handler must be a function");return this.eventHandlers[A]||(this.eventHandlers[A]=[]),this.eventHandlers[A].push(I),this}off(A,I){if(!["open","message","close","error","reconnect","reconnectAttempt","latency"].includes(A))throw new TypeError(`Unknown event: ${A}`);if(!this.eventHandlers[A])return this;if(I){let U=this.eventHandlers[A].indexOf(I);U!==-1&&this.eventHandlers[A].splice(U,1)}else this.eventHandlers[A]=[];return this}_triggerEvent(A,I){(this.eventHandlers[A]||[]).forEach(U=>{try{U(I)}catch(E){eA.error(`Error in ${A} handler:`,E)}})}isConnected(){return this.connection.isConnected()}isHealthy(){return this.connection.isHealthy()}getStatus(){var O,U,E;let A=this.connection.getStatus(),I=SA();return{connected:this.isConnected(),state:A.state,url:this.url,transport:this.transport.getTransportType(),latency:(O=A.heartbeat)==null?void 0:O.latency,uptime:A.uptime,messagesSent:(U=A.messages)==null?void 0:U.sent,messagesReceived:(E=A.messages)==null?void 0:E.received,reconnectAttempts:A.reconnectAttempts,networkOnline:I,browser:this.browser.browserInfo.name}}reconnect(){return this.connection.reconnect()}getTransportType(){return this.transport.getTransportType()}destroy(){eA.info("Destroying client"),this.disconnect(1e3,"Client destroyed"),this.messageHandlers.clear(),this.eventHandlers={open:[],message:[],close:[],error:[],reconnect:[],reconnectAttempt:[]},this.pendingAcks.clear()}},j1=N1;var p4=S("packet"),DA={MESSAGE:"message",EVENT:"event",COMMAND:"command",RESPONSE:"response",ERROR:"error",PING:"ping",PONG:"pong",JOIN:"join",LEAVE:"leave",PRESENCE:"presence",ACK:"ack",AUTH:"auth",SYSTEM:"system"},U1={CRITICAL:"critical",HIGH:"high",NORMAL:"normal",LOW:"low"},E1={AT_MOST_ONCE:"at_most_once",AT_LEAST_ONCE:"at_least_once",EXACTLY_ONCE:"exactly_once"};var g4=256*1024;var m=S("router"),KA={EXACT:"exact",WILDCARD:"wildcard",REGEX:"regex",FUNCTION:"function"},Q1={CRITICAL:100,HIGH:200,NORMAL:300,LOW:400,FALLBACK:500},w={PRE:"pre",POST:"post",AROUND:"around"},K1=class{constructor(A,I,O={}){this.pattern=A,this.handler=I,this.matchType=O.matchType||KA.EXACT,this.priority=O.priority||Q1.NORMAL,this.namespace=O.namespace||null,this.description=O.description||A.toString(),this.id=`${Date.now()}-${Math.random().toString(36).substring(2,8)}`,this.created=Date.now(),this.callCount=0,this.lastCalled=null}matches(A){if(this.namespace&&A.namespace!==this.namespace)return!1;let I=A.type;switch(this.matchType){case KA.EXACT:return I===this.pattern;case KA.WILDCARD:return this._matchWildcard(I,this.pattern);case KA.REGEX:return this.pattern.test(I);case KA.FUNCTION:return this.pattern(A);default:return!1}}execute(A,I){this.callCount++,this.lastCalled=Date.now();try{return this.handler(A,I)}catch(O){throw m.error(`Handler ${this.description} failed:`,O),O}}_matchWildcard(A,I){if(I==="*")return!0;let O=I.replace(/\./g,"\\.").replace(/\*/g,".*");return new RegExp(`^${O}$`).test(A)}getStats(){return{id:this.id,description:this.description,matchType:this.matchType,priority:this.priority,namespace:this.namespace,callCount:this.callCount,lastCalled:this.lastCalled,created:this.created}}},B1=class N{constructor(A={}){this.options={catchErrors:!0,asyncHandlers:!1,maxHandlersPerRoute:10,logHandling:!0,...A},this.routes=new Map,this.namespaces=new Map,this.middleware={[w.PRE]:[],[w.POST]:[],[w.AROUND]:[]},this.stats={routesProcessed:0,handlersExecuted:0,errorsCaught:0,lastRoute:null},this._setupDefaultHandlers(),m.info("Router created")}_setupDefaultHandlers(){this.on("*",A=>{m.debug("Unhandled message type:",A.type)},{matchType:KA.WILDCARD,priority:Q1.FALLBACK,description:"Catch-all handler"}),this.on(DA.ERROR,A=>{m.error("Received error packet:",A.payload)},{description:"Error handler"})}on(A,I,O={}){if(typeof I!="function")throw new TypeError("Handler must be a function");let U=new K1(A,I,O),E=this._getRouteKey(A,O.namespace);this.routes.has(E)||this.routes.set(E,[]);let K=this.routes.get(E);return K.length>=this.options.maxHandlersPerRoute&&m.warn(`Max handlers (${this.options.maxHandlersPerRoute}) reached for route:`,E),K.push(U),K.sort((B,R)=>B.priority-R.priority),m.debug("Handler registered",{pattern:A,namespace:O.namespace,priority:O.priority}),()=>{this.off(A,I,O.namespace)}}off(A,I,O){let U=this._getRouteKey(A,O),E=this.routes.get(U);if(!E)return;let K=E.findIndex(B=>B.handler===I);K!==-1&&(E.splice(K,1),m.debug("Handler removed",{pattern:A,namespace:O})),E.length===0&&this.routes.delete(U)}once(A,I,O={}){let U=(E,K)=>{I(E,K),this.off(A,U,O.namespace)};this.on(A,U,O)}route(A,I={}){this.stats.routesProcessed++,this.stats.lastRoute=Date.now(),this._runMiddleware(w.PRE,A,I);let O=this._findHandlers(A);if(O.length===0){m.debug("No handlers for packet type:",A.type);return}m.debug("Routing packet",{type:A.type,namespace:A.namespace,handlers:O.length});let U=[];for(let E of O)try{let K=this._runAroundMiddleware(A,I,E);if(K!==void 0)U.push(K);else{let B=E.execute(A,I);U.push(B)}this.stats.handlersExecuted++}catch(K){if(this.stats.errorsCaught++,this.options.catchErrors)m.error("Handler error:",K);else throw K}return this._runMiddleware(w.POST,A,I,U),this.options.asyncHandlers?Promise.all(U):U}namespace(A){if(!this.namespaces.has(A)){let I=new N(this.options);I.on=(O,U,E={})=>this.on(O,U,{...E,namespace:A}),I.off=(O,U,E={})=>this.off(O,U,A),this.namespaces.set(A,I)}return this.namespaces.get(A)}use(A,I){if(!this.middleware[A])throw new Error(`Invalid middleware type: ${A}`);this.middleware[A].push(I),m.debug("Middleware added",{type:A})}removeMiddleware(A,I){let O=this.middleware[A].indexOf(I);O!==-1&&this.middleware[A].splice(O,1)}_findHandlers(A){let I=[];for(let[O,U]of this.routes)if(this._routeCouldMatch(O,A)){let E=U.filter(K=>K.matches(A));I.push(...E)}return I.sort((O,U)=>O.priority-U.priority),I}_routeCouldMatch(A,I){let[O,U,E]=A.split("|");return!(U&&U!==I.namespace)}_getRouteKey(A,I){return`${A instanceof RegExp?"regex":typeof A}|${I||""}|${A}`}_runMiddleware(A,I,O,U=null){for(let E of this.middleware[A])try{E(I,O,U)}catch(K){m.error(`Middleware (${A}) error:`,K)}}_runAroundMiddleware(A,I,O){let U;for(let E of this.middleware[w.AROUND])if(U=E(A,I,(B,R)=>O.execute(B,R)),U!==void 0)break;return U}getRoutes(){let A=[];for(let[I,O]of this.routes)A.push({key:I,handlers:O.map(U=>U.getStats())});return A}getStats(){return{...this.stats,totalRoutes:this.routes.size,totalHandlers:Array.from(this.routes.values()).reduce((A,I)=>A+I.length,0),middlewareCount:{pre:this.middleware[w.PRE].length,post:this.middleware[w.POST].length,around:this.middleware[w.AROUND].length},namespaces:this.namespaces.size}}reset(){this.routes.clear(),this.namespaces.clear(),this.middleware={[w.PRE]:[],[w.POST]:[],[w.AROUND]:[]},this._setupDefaultHandlers(),m.info("Router reset")}};function X1(N={}){return new B1(N)}var AA=S("namespace"),z={CREATED:"created",DESTROYED:"destroyed",USER_JOINED:"user_joined",USER_LEFT:"user_left",ERROR:"error"},h3={autoCreateRooms:!0,maxRooms:100,broadcastPresence:!0,persistState:!1,authRequired:!1},sA=class N{constructor(A,I,O={}){if(!bA(A))throw new Error(`Invalid namespace path: ${A}`);this.path=A,this.socket=I,this.options={...h3,...O},this.id=_("ns"),this.router=X1({catchErrors:!0}),this.rooms=new Map,this.users=new Map,this.children=new Map,this.handlers={[z.CREATED]:[],[z.DESTROYED]:[],[z.USER_JOINED]:[],[z.USER_LEFT]:[],[z.ERROR]:[]},this.state={created:Date.now(),messageCount:0,userCount:0,roomCount:0},this._handleMessage=this._handleMessage.bind(this),AA.info("Namespace created",{path:this.path,id:this.id})}on(A,I){if(typeof I!="function")throw new TypeError("Handler must be a function");return this.router.on(A,(O,U)=>{I(O.payload,U)}),this}onMessage(A,I){return this.on(A,I)}emit(A,I,O={}){let U={type:A,data:I,namespace:this.path,timestamp:Date.now()};if(this.state.messageCount++,O.ack)return this.socket.sendWithAck(A,U,O.timeout);this.socket.send(U)}broadcast(A,I,O=[]){this.emit("broadcast",{event:A,data:I,except:O,namespace:this.path})}async joinRoom(A,I){if(!this.rooms.has(A)){if(this.rooms.size>=this.options.maxRooms)return AA.warn("Max rooms reached",{namespace:this.path}),!1;this.rooms.set(A,new Set)}return this.rooms.get(A).add(I),this.state.roomCount=this.rooms.size,AA.debug("User joined room",{namespace:this.path,room:A,userId:I}),this.broadcast("user_joined",{room:A,userId:I},[I]),!0}leaveRoom(A,I){let O=this.rooms.get(A);O&&(O.delete(I),O.size===0&&this.rooms.delete(A),AA.debug("User left room",{namespace:this.path,room:A,userId:I}),this.broadcast("user_left",{room:A,userId:I},[I]))}getRoomUsers(A){let I=this.rooms.get(A);return I?Array.from(I):[]}getRooms(){return Array.from(this.rooms.keys())}addUser(A,I={}){this.users.set(A,{...I,joined:Date.now(),rooms:[]}),this.state.userCount=this.users.size,AA.debug("User added to namespace",{namespace:this.path,userId:A}),this.options.broadcastPresence&&this.broadcast("presence",{userId:A,status:"online",data:I})}removeUser(A){for(let[I,O]of this.rooms)O.has(A)&&this.leaveRoom(I,A);this.users.delete(A),this.state.userCount=this.users.size,AA.debug("User removed from namespace",{namespace:this.path,userId:A}),this.options.broadcastPresence&&this.broadcast("presence",{userId:A,status:"offline"})}namespace(A,I={}){let O=this.path==="/"?A:`${this.path}${A}`;if(!this.children.has(O)){let U=new N(O,this.socket,{...this.options,...I});this.children.set(O,U)}return this.children.get(O)}_handleMessage(A){return A.namespace!==this.path?!1:(this.router.route(A,{namespace:this,socket:this.socket}),!0)}hasUser(A){return this.users.has(A)}getStats(){return{...this.state,path:this.path,id:this.id,userCount:this.users.size,roomCount:this.rooms.size,childCount:this.children.size}}destroy(){this.rooms.clear(),this.users.clear();for(let A of this.children.values())A.destroy();this.children.clear(),AA.info("Namespace destroyed",{path:this.path}),this._emit(z.DESTROYED,{path:this.path,id:this.id})}_emit(A,I){(this.handlers[A]||[]).forEach(U=>{try{U(I)}catch(E){AA.error(`Error in ${A} handler:`,E)}})}_on(A,I){return this.handlers[A]||(this.handlers[A]=[]),this.handlers[A].push(I),this}};var $=S("rooms"),u={USER_JOINED:"user_joined",USER_LEFT:"user_left",ROOM_CREATED:"room_created",ROOM_DESTROYED:"room_destroyed",ROOM_MESSAGE:"room_message",ROOM_UPDATED:"room_updated",ERROR:"error"},cA={PUBLIC:"public",PRIVATE:"private",HIDDEN:"hidden"},BA={TEMPORARY:"temporary",PERSISTENT:"persistent",ANONYMOUS:"anonymous"},J3={maxUsers:100,visibility:cA.PUBLIC,type:BA.TEMPORARY,broadcastPresence:!0,persistMessages:!1,maxHistory:100,inviteOnly:!1},R1=class{constructor(A,I={}){this.userId=A,this.joinedAt=Date.now(),this.lastActivity=Date.now(),this.role=I.role||"member",this.metadata=I.metadata||{},this.presence="online"}updateActivity(){this.lastActivity=Date.now()}setPresence(A){this.presence=A,this.updateActivity()}toJSON(){return{userId:this.userId,joinedAt:this.joinedAt,lastActivity:this.lastActivity,role:this.role,metadata:this.metadata,presence:this.presence}}},rA=class{constructor(A,I={}){this.name=A,this.id=_("room"),this.options={...J3,...I},this.members=new Map,this.messageHistory=[],this.metadata={...this.options.metadata,createdAt:Date.now(),createdBy:null},this.state={active:!0,memberCount:0,messageCount:0,lastActivity:Date.now()},this.handlers={[u.USER_JOINED]:[],[u.USER_LEFT]:[],[u.ROOM_MESSAGE]:[],[u.ROOM_UPDATED]:[],[u.ERROR]:[]},$.info("Room created",{name:this.name,id:this.id,visibility:this.options.visibility})}addMember(A,I={}){if(this.members.has(A))return $.debug("User already in room",{userId:A,room:this.name}),!1;if(this.members.size>=this.options.maxUsers)return $.warn("Room full",{room:this.name,max:this.options.maxUsers}),this._emit(u.ERROR,{code:"room_full",message:"Room has reached maximum capacity"}),!1;if(this.options.inviteOnly&&!I.invited)return $.warn("Attempt to join invite-only room",{userId:A,room:this.name}),!1;let O=new R1(A,I);return this.members.set(A,O),this.state.memberCount=this.members.size,this.state.lastActivity=Date.now(),$.debug("User joined room",{userId:A,room:this.name,memberCount:this.members.size}),this.options.broadcastPresence&&this._emit(u.USER_JOINED,{userId:A,room:this.name,timestamp:Date.now(),memberData:O.toJSON()}),!0}removeMember(A,I="left"){if(!this.members.has(A))return!1;let O=this.members.get(A);return this.members.delete(A),this.state.memberCount=this.members.size,this.state.lastActivity=Date.now(),$.debug("User left room",{userId:A,room:this.name,reason:I,memberCount:this.members.size}),this.options.broadcastPresence&&this._emit(u.USER_LEFT,{userId:A,room:this.name,reason:I,timestamp:Date.now(),memberData:O.toJSON()}),this.options.type===BA.TEMPORARY&&this.members.size===0&&this.destroy("Room empty"),!0}hasMember(A){return this.members.has(A)}getMember(A){let I=this.members.get(A);return I?I.toJSON():null}getMembers(){return Array.from(this.members.values()).map(A=>A.toJSON())}getMemberCount(){return this.members.size}message(A,I,O={}){if(!this.members.has(A)&&this.options.type!==BA.ANONYMOUS)throw new Error(`User ${A} is not in room ${this.name}`);let U={id:_("msg"),room:this.name,userId:A,message:I,timestamp:Date.now(),type:O.type||"message",metadata:O.metadata||{}};return this.members.has(A)&&this.members.get(A).updateActivity(),this.state.messageCount++,this.state.lastActivity=Date.now(),this.options.persistMessages&&(this.messageHistory.push(U),this.messageHistory.length>this.options.maxHistory&&(this.messageHistory=this.messageHistory.slice(-this.options.maxHistory))),$.debug("Room message",{room:this.name,userId:A,msgId:U.id}),this._emit(u.ROOM_MESSAGE,U),U.id}broadcast(A,I,O=[]){let U={room:this.name,event:A,data:I,timestamp:Date.now()};this._emit(A,U,O)}update(A,I=null){this.metadata={...this.metadata,...A,updatedAt:Date.now(),updatedBy:I},this._emit(u.ROOM_UPDATED,{room:this.name,updates:A,userId:I,timestamp:Date.now()})}getInfo(){return{id:this.id,name:this.name,options:{...this.options},metadata:{...this.metadata},state:{...this.state},memberCount:this.members.size,messageCount:this.state.messageCount}}getHistory(A=this.options.maxHistory){return this.messageHistory.slice(-A)}on(A,I){return this.handlers[A]||(this.handlers[A]=[]),this.handlers[A].push(I),()=>{let O=this.handlers[A].indexOf(I);O!==-1&&this.handlers[A].splice(O,1)}}destroy(A="Room destroyed"){this.state.active=!1,$.info("Room destroyed",{name:this.name,id:this.id,reason:A,memberCount:this.members.size}),this._emit(u.ROOM_DESTROYED,{room:this.name,reason:A,timestamp:Date.now()}),this.members.clear(),this.messageHistory=[],this.handlers={}}_emit(A,I,O=[]){(this.handlers[A]||[]).forEach(E=>{try{E(I,O)}catch(K){$.error(`Error in ${A} handler:`,K)}})}};var O6=S("presence"),M1={ONLINE:"online",AWAY:"away",BUSY:"busy",OFFLINE:"offline",CONNECTING:"connecting",RECONNECTING:"reconnecting"},L1={TYPING:"typing",TYPING_STOPPED:"typing_stopped",VIEWING:"viewing",EDITING:"editing",IDLE:"idle"},G1={STATE_CHANGED:"state_changed",ACTIVITY_UPDATED:"activity_updated",USER_ONLINE:"user_online",USER_OFFLINE:"user_offline",TYPING_STARTED:"typing_started",TYPING_STOPPED:"typing_stopped",SUBSCRIBED:"subscribed",UNSUBSCRIBED:"unsubscribed",ERROR:"error"};var L6=S("ack");var Y6=S("queue");var S6={maxSize:1e3,maxAge:10080*60*1e3,autoProcess:!0,batchSize:10,batchDelay:100,maxRetries:5,preserveOrder:!0,dropOldestWhenFull:!0};var i6=S("storage");var n6={dbName:"websocket_queue",storeName:"messages",dbVersion:1,maxItems:1e4,maxSize:5*1024*1024,autoInit:!0,storageType:null};var a6=S("retry"),T1={EXPONENTIAL:"exponential",LINEAR:"linear",FIXED:"fixed",FIBONACCI:"fibonacci",IMMEDIATE:"immediate"},A2={ALL:"all",NETWORK:"network",SERVER:"server",TIMEOUT:"timeout",CUSTOM:"custom"};var P6={maxAttempts:5,initialDelay:1e3,maxDelay:3e4,strategy:T1.EXPONENTIAL,factor:2,jitter:!0,retryCondition:A2.ALL,customCondition:null,circuitBreaker:{enabled:!0,failureThreshold:5,openTimeout:3e4,successThreshold:2},resetOnSuccess:!0};var g6=S("recovery");var I2={FULL:"full",MINIMAL:"minimal",VERIFIED:"verified",CONNECTION_ONLY:"connection_only"},f6={strategy:I2.FULL,maxStateAge:10080*60*1e3,autoRecover:!0,enableCheckpoints:!0,checkpointInterval:300*1e3,maxCheckpoints:5,verifyWithServer:!0,recoveryTimeout:3e4,replayQueue:!0,restoreSubscriptions:!0,restorePresence:!0};var O2=j1;
1490
+ `,Y3(),document.body.appendChild(N),R3(),N}function b1(N,A){if(!N){alert("please provide an `onConfirm` callback!");return}let I=D3();return I._callbacks={onConfirm:N,onCancel:A},e3(I),I}var aA=class{constructor(A){this.viewConfigs=A,this.loadedStyles=new Set,this.currentView=null,this.currentModule=null}async loadView(A){if(!A)return;let I=A.replace("-view",""),O=document.getElementById(A);if(!O)return;let U=this.viewConfigs[I];if(!U){console.error(`\u274C No config found for view: ${I}`);return}if(this.currentView!==I){this.currentView&&await this.unloadView(this.currentView);try{U.css&&(console.log(`Loading CSS: ${U.css}`),await this.loadCSS(I,U.css)),console.log(`Loading HTML: ${U.html}`);let E=await fetch(U.html);if(!E.ok)throw new Error(`HTTP ${E.status}`);let K=await E.text();O.innerHTML=K,U.js&&(console.log(`Loading JS: ${U.js}`),await this.loadJS(I,U.js)),this.currentView=I,console.log(`View loaded: ${I}`)}catch(E){console.error(`Failed to load view ${I}:`,E),O.innerHTML=`<p style="color: red; padding: 20px;">Error loading ${I}: ${E.message}</p>`}}}async loadCSS(A,I){let O=`style-${A}`,U=document.getElementById(O);U&&U.remove();let E=document.createElement("link");return E.id=O,E.rel="stylesheet",E.href=I,new Promise(K=>{E.onload=()=>{this.loadedStyles.add(A),console.log(`CSS loaded: ${I}`),K()},E.onerror=()=>{console.log(`CSS failed to load: ${I} (continuing anyway)`),K()},document.head.appendChild(E)})}async loadJS(A,I){try{let O=await import(I);this.currentModule=O,console.log("module====>",O),O.init&&typeof O.init=="function"&&(console.log(`Initializing ${A}...`),O.init()),console.log(`JS loaded: ${I}`)}catch(O){console.log(`No JS module for ${A} or error:`,O)}}async unloadView(A){console.log(`Unloading view: ${A}`);let I=document.getElementById(`style-${A}`);I&&(I.remove(),this.loadedStyles.delete(A)),this.currentModule&&this.currentModule.cleanup&&(console.log(`Cleaning up ${A}...`),this.currentModule.cleanup()),this.currentModule=null,this.currentView=null}};var UA={threshold:0,rootMargin:"0px",root:null,triggerOnce:!1},F=new Map;function s3(N,A){return`${N?N.id||N.tagName+N.className:"viewport"}::${A}`}var gA=class{constructor(A,I,O){this.onEnter=A,this.onExit=I,this.options=O,this.currentlyIntersecting=!1}};function r3(N,A){let I=s3(N,A);return F.has(I)||F.set(I,{observer:null,callbacks:new Map,root:N,rootMargin:A,thresholds:new Set([0])}),F.get(I)}function i3(N){let A=new Set([0]);return N.callbacks.forEach(I=>{I.forEach(O=>{let U=O.options.threshold;Array.isArray(U)?U.forEach(E=>A.add(E)):typeof U=="number"&&A.add(U)})}),Array.from(A).sort((I,O)=>I-O)}function n3(N){let A=i3(N);if(N.observer){let I=Array.from(N.observer.thresholds);if(I.length===A.length&&I.every((U,E)=>U===A[E]))return;N.observer.disconnect()}N.observer=new IntersectionObserver(I=>{o3(N,I)},{root:N.root,rootMargin:N.rootMargin,threshold:A}),N.callbacks.forEach((I,O)=>{N.observer.observe(O)}),N.thresholds=new Set(A)}function o3(N,A){A.forEach(I=>{let O=I.target,U=N.callbacks.get(O);if(!U)return;let E=I.isIntersecting,K=I.intersectionRatio;Array.from(U).forEach(R=>{var Y,i;let{onEnter:M,onExit:L,options:G}=R,T=(Y=G.threshold)!=null?Y:UA.threshold,W=(i=G.triggerOnce)!=null?i:UA.triggerOnce,D=Array.isArray(T)?T.some(s=>K>=s):K>=T;E&&D&&!R.currentlyIntersecting&&(R.currentlyIntersecting=!0,M&&typeof M=="function"&&M(O,I),W&&k1(N,O,R)),!E&&R.currentlyIntersecting&&(R.currentlyIntersecting=!1,L&&typeof L=="function"&&L(O,I))}),U.size===0&&(N.callbacks.delete(O),N.observer&&N.observer.unobserve(O))})}function fA(N,A={}){var R,M,L,G;let I=H3(N);if(!I)return()=>{};let{onEnter:O,onExit:U}=A;if(!O&&!U)return console.warn("[IntersectionWatcher] No callbacks provided. At least onEnter or onExit required."),()=>{};let E={threshold:(R=A.threshold)!=null?R:UA.threshold,rootMargin:(M=A.rootMargin)!=null?M:UA.rootMargin,root:(L=A.root)!=null?L:UA.root,triggerOnce:(G=A.triggerOnce)!=null?G:UA.triggerOnce},K=r3(E.root,E.rootMargin),B=new gA(O,U,E);return K.callbacks.has(I)||K.callbacks.set(I,new Set),K.callbacks.get(I).add(B),n3(K),K.observer.observe(I),()=>{k1(K,I,B)}}function _1(N,A={}){if(typeof N!="string")return console.warn("[IntersectionWatcher] watchAll requires a CSS selector string."),()=>{};let I=document.querySelectorAll(N);if(I.length===0)return console.warn(`[IntersectionWatcher] No elements found for selector: "${N}"`),()=>{};let O=Array.from(I).map(U=>fA(U,A));return()=>{O.forEach(U=>U())}}function k1(N,A,I){let O=N.callbacks.get(A);if(O&&(O.delete(I),O.size===0&&(N.callbacks.delete(A),N.observer&&N.observer.unobserve(A)),N.callbacks.size===0)){N.observer&&(N.observer.disconnect(),N.observer=null);for(let[U,E]of F)if(E===N){F.delete(U);break}}}function H3(N){if(typeof N=="string"){let A=document.querySelector(N);return A||(console.warn(`[IntersectionWatcher] Element not found: "${N}"`),null)}return N instanceof Element?N:(console.warn("[IntersectionWatcher] Invalid target. Must be Element or selector string."),null)}function wA(){F.forEach(N=>{N.observer&&(N.observer.disconnect(),N.observer=null),N.callbacks.clear()}),F.clear()}function q1(N){for(let A of F.values())if(A.callbacks.has(N))return!0;return!1}function z1(){let N=0,A=0;return F.forEach(I=>{N+=I.callbacks.size,I.callbacks.forEach(O=>{A+=O.size})}),{elements:N,callbacks:A,pools:F.size}}typeof window<"u"&&window.addEventListener("beforeunload",()=>{wA()});var b={DEBUG:0,INFO:1,WARN:2,ERROR:3,SILENT:4},$1={level:b.ERROR,timestamps:!0,colors:!0,output:null,namespaces:{}},GA={reset:"\x1B[0m",debug:"\x1B[36m",info:"\x1B[32m",warn:"\x1B[33m",error:"\x1B[31m",namespace:"\x1B[35m"},VA=class N{constructor(A,I={}){if(typeof A!="string")throw new TypeError("Logger namespace must be a string");this.namespace=A,this.config={...$1,...I}}debug(...A){this._log(b.DEBUG,"DEBUG",...A)}info(...A){this._log(b.INFO,"INFO",...A)}warn(...A){this._log(b.WARN,"WARN",...A)}error(...A){this._log(b.ERROR,"ERROR",...A)}isDebugEnabled(){return this._shouldLog(b.DEBUG)}child(A){return new N(`${this.namespace}:${A}`,this.config)}_log(A,I,...O){if(!this._shouldLog(A))return;let U=this._formatMessage(I,...O);this._output(A,U)}_shouldLog(A){let I=this.config.namespaces[this.namespace];return I!==void 0?A>=I:A>=this.config.level}_formatMessage(A,...I){let O=[];if(this.config.timestamps&&O.push(`[${new Date().toISOString()}]`),this.config.colors){let U=GA[A.toLowerCase()]||GA.reset;O.push(`${U}[${A}]${GA.reset}`)}else O.push(`[${A}]`);return this.config.colors?O.push(`${GA.namespace}[${this.namespace}]${GA.reset}`):O.push(`[${this.namespace}]`),O.push(...I),O}_output(A,I){if(this.config.output){this.config.output(A,...I);return}A>=b.ERROR?console.error(...I):A>=b.WARN?console.warn(...I):console.log(...I)}},C3={...$1},vA=new Map;function S(N){if(vA.has(N))return vA.get(N);let A=new VA(N,C3);return vA.set(N,A),A}var a3=S("browser"),FA=class{constructor(){this._detectAll()}_detectAll(){if(this.isBrowser=typeof window<"u"&&typeof document<"u",this.isNode=!this.isBrowser&&typeof process<"u",!this.isBrowser){this._setNonBrowserDefaults();return}this.hasWebSocket=typeof window.WebSocket<"u",this.hasLocalStorage=this._checkStorage("localStorage"),this.hasSessionStorage=this._checkStorage("sessionStorage"),this.hasIndexedDB=this._checkIndexedDB(),this.hasBlob=typeof Blob<"u",this.hasArrayBuffer=typeof ArrayBuffer<"u",this.hasDataView=typeof DataView<"u",this.hasTypedArrays=typeof Uint8Array<"u",this.hasCrypto=typeof crypto<"u"&&typeof crypto.getRandomValues<"u",this.hasWorker=typeof Worker<"u",this.hasSharedWorker=typeof SharedWorker<"u",this.hasServiceWorker=typeof navigator<"u"&&"serviceWorker"in navigator,this.hasNetworkInfo=typeof navigator<"u"&&"connection"in navigator,this.hasBatteryInfo=typeof navigator<"u"&&"getBattery"in navigator,this.userAgent=navigator.userAgent,this.browserInfo=this._identifyBrowser(),this.osInfo=this._identifyOS(),this.isMobile=this._detectMobile(),this.isTablet=this._detectTablet(),this.screenSize={width:window.screen.width,height:window.screen.height},this.pixelRatio=window.devicePixelRatio||1,this.touchSupport="ontouchstart"in window||navigator.maxTouchPoints>0,this.hasPerformanceAPI=typeof performance<"u",this.deviceMemory=navigator.deviceMemory||4,this.hardwareConcurrency=navigator.hardwareConcurrency||2,a3.debug("Browser capabilities detected",{hasWebSocket:this.hasWebSocket,browser:this.browserInfo.name,mobile:this.isMobile,memory:this.deviceMemory})}_setNonBrowserDefaults(){this.hasWebSocket=!1,this.hasLocalStorage=!1,this.hasSessionStorage=!1,this.hasIndexedDB=!1,this.hasBlob=!1,this.hasArrayBuffer=!0,this.hasDataView=!0,this.hasTypedArrays=!0,this.hasCrypto=!1,this.hasWorker=!1,this.hasSharedWorker=!1,this.hasServiceWorker=!1,this.hasNetworkInfo=!1,this.hasBatteryInfo=!1,this.isMobile=!1,this.isTablet=!1,this.touchSupport=!1,this.hasPerformanceAPI=!0,this.deviceMemory=4,this.hardwareConcurrency=2,this.browserInfo={name:"node",version:process.version},this.osInfo={name:process.platform}}_checkStorage(A){try{let I=window[A],O="__websocket_test__";return I.setItem(O,"test"),I.removeItem(O),!0}catch{return!1}}_checkIndexedDB(){try{return typeof window.indexedDB<"u"}catch{return!1}}_identifyBrowser(){var U,E,K,B,R;let A=this.userAgent,I="unknown",O="unknown";return A.indexOf("Firefox")>-1?(I="firefox",O=((U=A.match(/Firefox\/(\d+\.\d+)/))==null?void 0:U[1])||"unknown"):A.indexOf("Chrome")>-1&&A.indexOf("Edg")===-1?(I="chrome",O=((E=A.match(/Chrome\/(\d+\.\d+)/))==null?void 0:E[1])||"unknown"):A.indexOf("Safari")>-1&&A.indexOf("Chrome")===-1?(I="safari",O=((K=A.match(/Version\/(\d+\.\d+)/))==null?void 0:K[1])||"unknown"):A.indexOf("Edg")>-1?(I="edge",O=((B=A.match(/Edg\/(\d+\.\d+)/))==null?void 0:B[1])||"unknown"):(A.indexOf("MSIE")>-1||A.indexOf("Trident")>-1)&&(I="ie",O=((R=A.match(/(?:MSIE |rv:)(\d+\.\d+)/))==null?void 0:R[1])||"unknown"),{name:I,version:O}}_identifyOS(){let A=this.userAgent,I="unknown",O="unknown";if(A.indexOf("Windows")>-1)I="windows",A.indexOf("Windows NT 10.0")>-1?O="10":A.indexOf("Windows NT 6.3")>-1?O="8.1":A.indexOf("Windows NT 6.2")>-1?O="8":A.indexOf("Windows NT 6.1")>-1&&(O="7");else if(A.indexOf("Mac OS X")>-1){I="macos";let U=A.match(/Mac OS X (\d+[._]\d+[._]\d+)/);U&&(O=U[1].replace(/_/g,"."))}else if(A.indexOf("Android")>-1){I="android";let U=A.match(/Android (\d+\.\d+)/);U&&(O=U[1])}else if(A.indexOf("iOS")>-1||A.indexOf("iPhone")>-1||A.indexOf("iPad")>-1){I="ios";let U=A.match(/OS (\d+[_\d]+) like Mac/);U&&(O=U[1].replace(/_/g,"."))}else A.indexOf("Linux")>-1&&(I="linux");return{name:I,version:O}}_detectMobile(){return/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(this.userAgent)}_detectTablet(){return/iPad|Android(?!.*Mobile)|Tablet/i.test(this.userAgent)}getRecommendedTransports(){let A=[];return this.hasWebSocket&&A.push("websocket"),typeof EventSource<"u"&&A.push("eventsource"),A.push("polling"),A}hasMemoryConstraints(){return this.isMobile||this.deviceMemory<=2}getMaxQueueSize(){return this.hasMemoryConstraints()?100:1e3}isLegacyBrowser(){let{name:A,version:I}=this.browserInfo,O=parseFloat(I);return A==="ie"||A==="firefox"&&O<50||A==="chrome"&&O<50||A==="safari"&&O<10}},yA=null;function y(){return yA||(yA=new FA),yA}var Q3=y();function _(N=""){let A=Date.now().toString(36),I=Math.random().toString(36).substring(2,10),O=`${A}${I}`;return N?`${N}_${O}`:O}function WA(N){if(typeof N!="string"||N.trim()===""||!N.startsWith("ws://")&&!N.startsWith("wss://"))return!1;try{let A=new URL(N);return A.hostname&&(A.hostname.includes(".")||A.hostname==="localhost")}catch{return!1}}function TA(N){if(N===null||typeof N!="object")return N;if(N instanceof Date)return new Date(N.getTime());if(N instanceof Array)return N.map(A=>TA(A));if(N instanceof Object){let A={};return Object.keys(N).forEach(I=>{A[I]=TA(N[I])}),A}return N}function xA(N,A){let I=TA(N);return!A||typeof A!="object"||Object.keys(A).forEach(O=>{let U=A[O],E=I[O];U instanceof Array?I[O]=TA(U):U instanceof Object&&E instanceof Object?I[O]=xA(E,U):I[O]=TA(U)}),I}function YA(N,A={}){let{baseDelay:I=1e3,maxDelay:O=3e4,jitter:U=!0}=A,E=I*Math.pow(2,N);if(E=Math.min(E,O),U){let K=.8+.4*Math.random();E=Math.floor(E*K)}return E}function PA(N){return new Promise(A=>setTimeout(A,N))}function EA(){let N,A;return{promise:new Promise((O,U)=>{N=O,A=U}),resolve:N,reject:A}}function bA(N){return typeof N!="string"?!1:N==="/"?!0:/^\/[a-zA-Z0-9_-]+(\/[a-zA-Z0-9_-]+)*$/.test(N)}var k=S("network"),c={OFFLINE:"offline",ONLINE:"online",DEGRADED:"degraded",CHECKING:"checking"},p={UNKNOWN:"unknown",ETHERNET:"ethernet",WIFI:"wifi",CELLULAR:"cellular",NONE:"none"},kA=class{constructor(){this.browser=y(),this.listeners=new Map,this.status={state:c.CHECKING,type:p.UNKNOWN,effectiveType:null,downlink:null,rtt:null,lastChanged:Date.now(),since:Date.now()},this._checkInterval=null,this._checking=!1,this._initialized=!1,this.browser.isBrowser&&this._initBrowserListeners()}_initBrowserListeners(){if(window.addEventListener("online",()=>this._handleBrowserOnline()),window.addEventListener("offline",()=>this._handleBrowserOffline()),this.browser.hasNetworkInfo){let A=navigator.connection||navigator.mozConnection||navigator.webkitConnection;A&&A.addEventListener("change",()=>this._handleConnectionChange())}this._startPeriodicChecks(),this._checkStatus().then(()=>{this._initialized=!0,k.info("Network monitor initialized",this.status)}),k.debug("Network listeners initialized")}_startPeriodicChecks(){this._checkInterval=setInterval(()=>{this._checkStatus()},3e4)}_handleBrowserOnline(){k.info("Browser reported online"),this._checkStatus(!0)}_handleBrowserOffline(){k.warn("Browser reported offline"),this._updateStatus({state:c.OFFLINE,type:p.NONE,lastChanged:Date.now()})}_handleConnectionChange(){k.debug("Network connection changed"),this._checkStatus(!0)}async _checkStatus(A=!1){if(this._checking)return this.status;this._checking=!0,this._updateStatus({state:c.CHECKING});try{if(!this._getBasicOnlineStatus()){this._updateStatus({state:c.OFFLINE,type:p.NONE},A);return}let O=this._getNetworkInfo();if(!await this._verifyConnectivity()){this._updateStatus({state:c.DEGRADED,type:(O==null?void 0:O.type)||p.UNKNOWN,effectiveType:O==null?void 0:O.effectiveType,downlink:O==null?void 0:O.downlink,rtt:O==null?void 0:O.rtt},A);return}let E=this._determineNetworkQuality(O);this._updateStatus({state:E,type:(O==null?void 0:O.type)||p.UNKNOWN,effectiveType:O==null?void 0:O.effectiveType,downlink:O==null?void 0:O.downlink,rtt:O==null?void 0:O.rtt,lastChanged:this.status.state!==E?Date.now():this.status.lastChanged},A)}catch(I){k.error("Error checking network status:",I)}finally{this._checking=!1}}_getBasicOnlineStatus(){return typeof navigator>"u"||typeof navigator.onLine!="boolean"?!0:navigator.onLine}_getNetworkInfo(){if(!this.browser.hasNetworkInfo)return null;let A=navigator.connection||navigator.mozConnection||navigator.webkitConnection;return A?{type:this._mapConnectionType(A.type),effectiveType:A.effectiveType,downlink:A.downlink,rtt:A.rtt,saveData:A.saveData}:null}_mapConnectionType(A){return A&&{wifi:p.WIFI,cellular:p.CELLULAR,ethernet:p.ETHERNET,none:p.NONE,unknown:p.UNKNOWN}[A]||p.UNKNOWN}async _verifyConnectivity(){if(!this._getBasicOnlineStatus())return!1;let A=["https://www.google.com/favicon.ico","https://www.cloudflare.com/favicon.ico","https://www.github.com/favicon.ico"];for(let I of A)try{let O=new AbortController,U=setTimeout(()=>O.abort(),3e3),E=await fetch(I,{method:"HEAD",mode:"no-cors",cache:"no-cache",signal:O.signal});return clearTimeout(U),!0}catch{continue}return!1}_determineNetworkQuality(A){return A&&(A.effectiveType&&(A.effectiveType==="slow-2g"||A.effectiveType==="2g")||A.rtt&&A.rtt>500||A.downlink&&A.downlink<.5)?c.DEGRADED:c.ONLINE}_updateStatus(A,I=!1){let O={...this.status};this.status={...this.status,...A},(I||O.state!==this.status.state||O.type!==this.status.type)&&(k.info(`Network status changed: ${O.state} -> ${this.status.state}`,{type:this.status.type,effectiveType:this.status.effectiveType}),this._notifyListeners(O,this.status))}_notifyListeners(A,I){this.listeners.forEach((O,U)=>{try{O(I,A)}catch(E){k.error(`Error in listener ${U}:`,E)}})}getStatus(){return{...this.status}}isOnline(){return this.status.state===c.ONLINE||this.status.state===c.DEGRADED}isFullyOnline(){return this.status.state===c.ONLINE}isOffline(){return this.status.state===c.OFFLINE}onChange(A){let I=Date.now()+Math.random().toString(36);return this.listeners.set(I,A),()=>{this.listeners.delete(I)}}waitForOnline(A=3e4){let I=EA();if(this.isOnline())return I.resolve(),I.promise;let O=setTimeout(()=>{U(),I.reject(new Error(`Timeout waiting for network after ${A}ms`))},A),U=this.onChange(E=>{(E.state===c.ONLINE||E.state===c.DEGRADED)&&(clearTimeout(O),U(),I.resolve())});return I.promise}async checkNow(){return await this._checkStatus(!0),this.getStatus()}destroy(){this._checkInterval&&(clearInterval(this._checkInterval),this._checkInterval=null),this.listeners.clear(),k.debug("Network monitor destroyed")}},_A=null;function q(){return _A||(_A=new kA),_A}function SA(){return q().isOnline()}var E4=q();var h=S("heartbeat"),g={PING_SENT:"ping_sent",PONG_RECEIVED:"pong_received",MISSED:"missed",DEAD:"dead",LATENCY_UPDATED:"latency_updated"},l={STOPPED:"stopped",RUNNING:"running",WAITING:"waiting",FAILED:"failed"},qA=class{constructor(A={}){this.options={interval:3e4,timeout:1e4,maxMissed:2,adaptive:!0,...A},this.network=q(),this.state=l.STOPPED,this.pingInterval=null,this.pingTimeout=null,this.missedCount=0,this.lastPingTime=0,this.lastPongTime=0,this.latency=null,this.latencyHistory=[],this.pingId=0,this.listeners=new Map,this.pendingPings=new Map,this._sendPing=this._sendPing.bind(this),this._handlePongTimeout=this._handlePongTimeout.bind(this),this._onNetworkChange=this._onNetworkChange.bind(this),h.debug("Heartbeat manager created",this.options)}start(){if(this.state!==l.STOPPED){h.warn("Heartbeat already running or failed");return}if(!this.network.isOnline()){h.info("Network offline, heartbeat will start when online"),this.network.onChange(this._onNetworkChange);return}this.state=l.RUNNING,this.missedCount=0,this._schedulePing(),h.info("Heartbeat started"),this._emit(g.PING_SENT,{state:this.state})}stop(){this.state=l.STOPPED,this._clearTimers(),this.missedCount=0,this.pendingPings.clear(),h.info("Heartbeat stopped")}reset(){this.stop(),this.missedCount=0,this.latency=null,this.pendingPings.clear(),h.debug("Heartbeat reset")}pongReceived(A){let I=Date.now();this.lastPongTime=I;let O=null,U=null;if(A&&A.id)O=A.id,U=this.pendingPings.get(O)||null,this.pendingPings.delete(O);else{let E=Array.from(this.pendingPings.entries()).sort((K,B)=>B[1]-K[1])[0];E&&(O=E[0],U=E[1],this.pendingPings.delete(O))}if(U){let E=I-U;this._updateLatency(E)}this.pingTimeout&&(clearTimeout(this.pingTimeout),this.pingTimeout=null),this.missedCount=0,this.state=l.RUNNING,h.debug("Pong received",{pingId:O,latency:this.latency,missed:this.missedCount}),this._emit(g.PONG_RECEIVED,{latency:this.latency,pingId:O}),this._schedulePing()}getStatus(){return{state:this.state,missed:this.missedCount,latency:this.latency,lastPing:this.lastPingTime,lastPong:this.lastPongTime,uptime:this.lastPingTime?Date.now()-this.lastPingTime:0}}getLatency(){return this.latency}isHealthy(){return this.state===l.RUNNING&&this.missedCount===0}isFailing(){return this.state===l.FAILED||this.missedCount>=this.options.maxMissed}onEvent(A){let I=Date.now()+Math.random().toString(36);return this.listeners.set(I,A),()=>{this.listeners.delete(I)}}_schedulePing(){this._clearTimers();let A=this.options.interval;this.options.adaptive&&this.network.getStatus().state==="degraded"&&(A=A*1.5),this.pingInterval=setTimeout(()=>{this._sendPing()},A)}_sendPing(){if(this.state===l.STOPPED)return;if(!this.network.isOnline()){h.debug("Network offline, skipping ping"),this._schedulePing();return}let A=Date.now();this.lastPingTime=A;let I=this.pingId++;this.pendingPings.set(I,A);try{let O={type:"ping",id:I,timestamp:A};this.options.sendPing(O),h.debug("Ping sent",{pingId:I}),this._emit(g.PING_SENT,{pingId:I})}catch(O){h.error("Failed to send ping:",O),this._handlePongTimeout();return}this.state=l.WAITING,this.pingTimeout=setTimeout(()=>{this._handlePongTimeout(I)},this.options.timeout)}_handlePongTimeout(A){if(this.missedCount++,h.warn("Pong timeout",{pingId:A,missed:this.missedCount,max:this.options.maxMissed}),this._emit(g.MISSED,{pingId:A,missed:this.missedCount,total:this.options.maxMissed}),this.pendingPings.delete(A),this.missedCount>=this.options.maxMissed){this._handleDeadConnection();return}this.state=l.RUNNING,this._schedulePing()}_handleDeadConnection(){this.state=l.FAILED,h.error("Heartbeat failed - connection appears dead",{missed:this.missedCount,lastPing:this.lastPingTime,lastPong:this.lastPongTime}),this._emit(g.DEAD,{missed:this.missedCount,latency:this.latency}),this.stop()}_updateLatency(A){this.latencyHistory.push(A),this.latencyHistory.length>10&&this.latencyHistory.shift();let I=this.latencyHistory.reduce((O,U)=>O+U,0)/this.latencyHistory.length;this.latency=Math.round(I),this._emit(g.LATENCY_UPDATED,{latency:this.latency,raw:A})}_onNetworkChange(A){A.state==="online"&&this.state===l.STOPPED&&(h.info("Network restored, starting heartbeat"),this.start()),A.state==="offline"&&this.state!==l.STOPPED&&(h.info("Network offline, stopping heartbeat"),this.stop())}_clearTimers(){this.pingInterval&&(clearTimeout(this.pingInterval),this.pingInterval=null),this.pingTimeout&&(clearTimeout(this.pingTimeout),this.pingTimeout=null)}_emit(A,I){this.listeners.forEach(O=>{try{O(A,I)}catch(U){h.error("Error in heartbeat listener:",U)}})}};function zA(N){return new qA(N)}var H=S("connection"),C={DISCONNECTED:"disconnected",CONNECTING:"connecting",CONNECTED:"connected",DISCONNECTING:"disconnecting",RECONNECTING:"reconnecting",FAILED:"failed"},f={INTENTIONAL:"intentional",NETWORK_LOST:"network_lost",SERVER_CLOSED:"server_closed",TIMEOUT:"timeout",HEARTBEAT_FAILED:"heartbeat_failed",ERROR:"error"},d={CONNECTED:"connected",DISCONNECTED:"disconnected",RECONNECTING:"reconnecting",RECONNECT_FAILED:"reconnect_failed",FAILED:"failed",STATE_CHANGED:"state_changed",STATS_UPDATED:"stats_updated"},$A=class{constructor(A,I={}){if(!WA(A))throw new Error(`Invalid WebSocket URL: ${A}`);this.url=A,this.options={timeout:1e4,autoConnect:!1,reconnect:{maxAttempts:10,baseDelay:1e3,maxDelay:3e4,jitter:!0},heartbeat:{enabled:!0,interval:3e4,timeout:1e4},createWebSocket:O=>new WebSocket(O),...I},this.network=q(),this.browser=y(),this.state=C.DISCONNECTED,this.ws=null,this.heartbeat=null,this.connectionAttempts=0,this.reconnectAttempts=0,this.lastConnectedAt=null,this.lastDisconnectedAt=null,this.disconnectReason=null,this.stats={connectedAt:null,disconnectedAt:null,connectionDuration:0,messagesSent:0,messagesReceived:0,bytesSent:0,bytesReceived:0,reconnectCount:0},this._connectionPromise=null,this._connectionResolve=null,this._connectionReject=null,this._disconnectPromise=null,this._disconnectResolve=null,this._reconnectTimer=null,this.listeners=new Map,this._networkUnsubscribe=this.network.onChange(O=>this._onNetworkChange(O)),this._handleOpen=this._handleOpen.bind(this),this._handleMessage=this._handleMessage.bind(this),this._handleClose=this._handleClose.bind(this),this._handleError=this._handleError.bind(this),this._handleHeartbeatEvent=this._handleHeartbeatEvent.bind(this),H.info("Connection manager created",{url:A}),this.options.autoConnect&&setTimeout(()=>this.connect(),0)}connect(){return this.state===C.CONNECTED?Promise.resolve():this.state===C.CONNECTING&&this._connectionPromise?this._connectionPromise:this.network.isOnline()?(this._setState(C.CONNECTING),this.reconnectAttempts=0,this.disconnectReason=null,this._connectionPromise=new Promise((A,I)=>{this._connectionResolve=A,this._connectionReject=I}),this._performConnection(),this._connectionPromise):(H.warn("Cannot connect: network offline"),Promise.reject(new Error("Network offline")))}disconnect(A=1e3,I=""){if(this.state===C.DISCONNECTED)return Promise.resolve();if(this._clearReconnectTimer(),this.disconnectReason=f.INTENTIONAL,this._setState(C.DISCONNECTING),this._disconnectPromise=new Promise(O=>{this._disconnectResolve=O}),this.heartbeat&&this.heartbeat.stop(),this.ws){this.ws.onopen=null,this.ws.onmessage=null,this.ws.onclose=null,this.ws.onerror=null;try{this.ws.close(A,I)}catch(O){H.error("Error closing WebSocket:",O)}}else this._cleanup(),this._setState(C.DISCONNECTED),this._disconnectResolve&&(this._disconnectResolve(),this._disconnectResolve=null);return this._disconnectPromise}async reconnect(){return H.info("Forcing reconnection"),this.state!==C.DISCONNECTED&&await this.disconnect(1e3,"Forced reconnection"),await PA(100),this.connect()}getStatus(){let A=Date.now();return{state:this.state,url:this.url,connectedAt:this.stats.connectedAt,disconnectedAt:this.stats.disconnectedAt,uptime:this.stats.connectedAt?A-this.stats.connectedAt:0,reconnectAttempts:this.reconnectAttempts,reconnectCount:this.stats.reconnectCount,disconnectReason:this.disconnectReason,messages:{sent:this.stats.messagesSent,received:this.stats.messagesReceived},bytes:{sent:this.stats.bytesSent,received:this.stats.bytesReceived},heartbeat:this.heartbeat?this.heartbeat.getStatus():null,network:this.network.getStatus()}}isConnected(){return this.state===C.CONNECTED}isHealthy(){return this.isConnected()&&(!this.heartbeat||this.heartbeat.isHealthy())}send(A){if(!this.isConnected()||!this.ws)throw new Error("Not connected");try{typeof A=="string"?this.stats.bytesSent+=new Blob([A]).size:A instanceof Blob?this.stats.bytesSent+=A.size:A instanceof ArrayBuffer&&(this.stats.bytesSent+=A.byteLength),this.ws.send(A),this.stats.messagesSent++}catch(I){throw H.error("Send failed:",I),I}}onEvent(A){let I=Date.now()+Math.random().toString(36);return this.listeners.set(I,A),()=>{this.listeners.delete(I)}}destroy(){H.info("Destroying connection manager"),this.state!==C.DISCONNECTED&&this.disconnect(1e3,"Manager destroyed"),this._networkUnsubscribe&&this._networkUnsubscribe(),this._clearReconnectTimer(),this.listeners.clear()}_performConnection(){if(!this.network.isOnline()){this._handleConnectionFailure(new Error("Network offline"),!0);return}H.info("Connecting...",{attempt:this.reconnectAttempts+1,url:this.url});try{this.ws=this.options.createWebSocket(this.url),this.ws.onopen=this._handleOpen,this.ws.onmessage=this._handleMessage,this.ws.onclose=this._handleClose,this.ws.onerror=this._handleError,this._connectionTimeout=setTimeout(()=>{if(this.state===C.CONNECTING){let A=new Error(`Connection timeout after ${this.options.timeout}ms`);this._handleConnectionFailure(A)}},this.options.timeout)}catch(A){this._handleConnectionFailure(A)}}_handleOpen(){H.info("WebSocket opened"),this._connectionTimeout&&(clearTimeout(this._connectionTimeout),this._connectionTimeout=null);let A=Date.now();this.lastConnectedAt=A,this.stats.connectedAt=A,this.stats.disconnectedAt=null,this.reconnectAttempts>0&&this.stats.reconnectCount++,this.reconnectAttempts=0,this.options.heartbeat.enabled&&this._setupHeartbeat(),this._setState(C.CONNECTED),this._connectionResolve&&(this._connectionResolve(),this._connectionResolve=null,this._connectionReject=null),this._emit(d.CONNECTED,{timestamp:A})}_handleMessage(A){if(this.stats.messagesReceived++,typeof A.data=="string"?this.stats.bytesReceived+=new Blob([A.data]).size:A.data instanceof Blob?this.stats.bytesReceived+=A.data.size:A.data instanceof ArrayBuffer&&(this.stats.bytesReceived+=A.data.byteLength),this.heartbeat)try{let I=JSON.parse(A.data);if(I.type==="pong"){this.heartbeat.pongReceived(I);return}}catch{}this._emit("message",A.data)}_handleClose(A){H.info("WebSocket closed",{code:A.code,reason:A.reason,wasClean:A.wasClean});let I=this.disconnectReason===f.INTENTIONAL;if(this.lastDisconnectedAt=Date.now(),this.stats.disconnectedAt=Date.now(),this.stats.connectedAt&&(this.stats.connectionDuration+=this.lastDisconnectedAt-this.stats.connectedAt),this.heartbeat&&(this.heartbeat.stop(),this.heartbeat=null),this._cleanup(),I){this._setState(C.DISCONNECTED),this._disconnectResolve&&(this._disconnectResolve(),this._disconnectResolve=null),this._emit(d.DISCONNECTED,{reason:f.INTENTIONAL,code:A.code});return}let O;this.network.isOnline()?A.code===1006?O=f.TIMEOUT:O=f.SERVER_CLOSED:O=f.NETWORK_LOST,this.disconnectReason=O,this._handleReconnection(O,A)}_handleError(A){H.error("WebSocket error",A),this._emit("error",A)}_handleConnectionFailure(A,I=!1){H.error("Connection failed:",A.message),this._connectionTimeout&&(clearTimeout(this._connectionTimeout),this._connectionTimeout=null),this._cleanup(),this._connectionReject&&(this._connectionReject(A),this._connectionResolve=null,this._connectionReject=null);let O=I?f.NETWORK_LOST:f.ERROR;this._handleReconnection(O,null,A)}_handleReconnection(A,I,O){if(this._setState(C.RECONNECTING),this.disconnectReason=A,this._emit(d.DISCONNECTED,{reason:A,code:I==null?void 0:I.code,error:O==null?void 0:O.message}),this.reconnectAttempts>=this.options.reconnect.maxAttempts){H.error("Max reconnection attempts reached",{attempts:this.reconnectAttempts}),this._setState(C.FAILED),this._emit(d.FAILED,{reason:"max_attempts",attempts:this.reconnectAttempts});return}let U=YA(this.reconnectAttempts,this.options.reconnect);H.info(`Reconnecting in ${U}ms`,{attempt:this.reconnectAttempts+1,max:this.options.reconnect.maxAttempts}),this._emit(d.RECONNECTING,{attempt:this.reconnectAttempts+1,maxAttempts:this.options.reconnect.maxAttempts,delay:U}),this._clearReconnectTimer(),this._reconnectTimer=setTimeout(()=>{this.reconnectAttempts++,this._performConnection()},U)}_onNetworkChange(A){H.debug("Network changed:",A.state),A.state==="online"&&(this.state===C.RECONNECTING||this.state===C.DISCONNECTED)&&(H.info("Network restored, retrying connection"),this._clearReconnectTimer(),this._performConnection()),A.state==="offline"&&this.isConnected()&&H.warn("Network lost, connection will likely fail")}_handleHeartbeatEvent(A,I){A===g.DEAD&&(H.error("Heartbeat dead, reconnecting"),this.disconnectReason=f.HEARTBEAT_FAILED,this.ws&&this.ws.close()),A===g.LATENCY_UPDATED&&this._emit("latency",{latency:I.latency})}_setupHeartbeat(){this.ws&&(this.heartbeat=zA({interval:this.options.heartbeat.interval,timeout:this.options.heartbeat.timeout,sendPing:A=>{try{this.ws.send(JSON.stringify(A)),this.stats.messagesSent++}catch(I){H.error("Failed to send ping:",I)}}}),this.heartbeat.onEvent(this._handleHeartbeatEvent),this.heartbeat.start())}_setState(A){let I=this.state;I!==A&&(this.state=A,H.debug(`State: ${I} -> ${A}`),this._emit(d.STATE_CHANGED,{from:I,to:A}))}_cleanup(){this.ws&&(this.ws.onopen=null,this.ws.onmessage=null,this.ws.onclose=null,this.ws.onerror=null,this.ws=null),this._connectionTimeout&&(clearTimeout(this._connectionTimeout),this._connectionTimeout=null)}_clearReconnectTimer(){this._reconnectTimer&&(clearTimeout(this._reconnectTimer),this._reconnectTimer=null)}_emit(A,I){this.listeners.forEach(O=>{try{O(A,I)}catch(U){H.error("Error in event listener:",U)}})}};function jA(N,A={}){return new $A(N,A)}var n=S("transport"),P={WEBSOCKET:"websocket",EVENTSOURCE:"eventsource",POLLING:"polling",NONE:"none"},e={IDLE:"idle",CONNECTING:"connecting",CONNECTED:"connected",DISCONNECTED:"disconnected",FAILED:"failed"},t={CONNECT:"connect",MESSAGE:"message",DISCONNECT:"disconnect",ERROR:"error",TRANSPORT_CHANGED:"transport_changed"},tA=class{constructor(A,I={}){this.url=A,this.options=I,this.state=e.IDLE,this.listeners=new Map}connect(){throw new Error("Not implemented")}disconnect(){throw new Error("Not implemented")}send(A){throw new Error("Not implemented")}on(A,I){return this.listeners.has(A)||this.listeners.set(A,[]),this.listeners.get(A).push(I),()=>{let O=this.listeners.get(A)||[],U=O.indexOf(I);U!==-1&&O.splice(U,1)}}_emit(A,I){(this.listeners.get(A)||[]).forEach(U=>{try{U(I)}catch(E){n.error("Error in event listener:",E)}})}getState(){return this.state}getType(){return P.NONE}},QA=class extends tA{constructor(A,I={}){super(A,I),this.ws=null,this.pendingMessages=[],this.type=P.WEBSOCKET}getType(){return this.type}connect(){if(this.state===e.IDLE){this.state=e.CONNECTING,n.info("WebSocket connecting to:",this.url);try{this.ws=new WebSocket(this.url),this.ws.onopen=()=>{for(n.info("WebSocket connected"),this.state=e.CONNECTED;this.pendingMessages.length>0;){let A=this.pendingMessages.shift();this.send(A)}this._emit(t.CONNECT,{transport:this.type})},this.ws.onmessage=A=>{this._emit(t.MESSAGE,A.data)},this.ws.onclose=A=>{n.info("WebSocket closed",{code:A.code,reason:A.reason}),this.state=e.DISCONNECTED,this._emit(t.DISCONNECT,{code:A.code,reason:A.reason,wasClean:A.wasClean})},this.ws.onerror=A=>{n.error("WebSocket error:",A),this._emit(t.ERROR,A)}}catch(A){n.error("WebSocket creation failed:",A),this.state=e.FAILED,this._emit(t.ERROR,A)}}}disconnect(){this.ws&&(this.ws.close(1e3,"Intentional disconnect"),this.ws=null),this.state=e.DISCONNECTED,this.pendingMessages=[]}send(A){if(this.state===e.CONNECTED&&this.ws)try{return this.ws.send(A),!0}catch(I){return n.error("WebSocket send failed:",I),!1}else return this.pendingMessages.push(A),!1}},XA=class extends tA{constructor(A,I={}){super(A,I),this.es=null,this.sendQueue=[],this.type=P.EVENTSOURCE,this.connectUrl=A,this.sendUrl=A.replace(/^ws/,"http").replace(/^wss/,"https")}getType(){return this.type}connect(){if(this.state===e.IDLE){this.state=e.CONNECTING,n.info("EventSource connecting to:",this.connectUrl);try{this.es=new EventSource(this.connectUrl),this.es.onopen=()=>{n.info("EventSource connected"),this.state=e.CONNECTED,this._emit(t.CONNECT,{transport:this.type})},this.es.onmessage=A=>{this._emit(t.MESSAGE,A.data)},this.es.onerror=A=>{n.error("EventSource error:",A),this.state===e.CONNECTED&&(this.state=e.DISCONNECTED,this._emit(t.DISCONNECT,{reason:"error"})),this._emit(t.ERROR,A)}}catch(A){n.error("EventSource creation failed:",A),this.state=e.FAILED,this._emit(t.ERROR,A)}}}disconnect(){this.es&&(this.es.close(),this.es=null),this.state=e.DISCONNECTED,this.sendQueue=[]}send(A){if(this.state!==e.CONNECTED)return this.sendQueue.push(A),!1;try{return fetch(this.sendUrl,{method:"POST",body:A,headers:{"Content-Type":"application/json"},keepalive:!0}).catch(I=>{n.error("EventSource send failed:",I),this._emit(t.ERROR,I)}),!0}catch(I){return n.error("EventSource send failed:",I),!1}}},A1=class extends tA{constructor(A,I={}){super(A,I),this.pollingInterval=I.pollingInterval||3e3,this.pollingActive=!1,this.sendQueue=[],this.messageQueue=[],this.pollTimeout=null,this.type=P.POLLING,this.baseUrl=A.replace(/^ws/,"http").replace(/^wss/,"https"),this.pollUrl=`${this.baseUrl}/poll`,this.sendUrl=`${this.baseUrl}/send`}getType(){return this.type}connect(){this.state===e.IDLE&&(this.state=e.CONNECTING,n.info("Polling connecting to:",this.baseUrl),this.pollingActive=!0,this._poll(),this.state=e.CONNECTED,this._emit(t.CONNECT,{transport:this.type}))}disconnect(){this.pollingActive=!1,this.pollTimeout&&(clearTimeout(this.pollTimeout),this.pollTimeout=null),this.state=e.DISCONNECTED,this.sendQueue=[],this.messageQueue=[]}send(A){if(this.state!==e.CONNECTED)return this.sendQueue.push(A),!1;try{return fetch(this.sendUrl,{method:"POST",body:A,headers:{"Content-Type":"application/json"},keepalive:!0}).catch(I=>{n.error("Polling send failed:",I),this._emit(t.ERROR,I)}),!0}catch(I){return n.error("Polling send failed:",I),!1}}async _poll(){if(this.pollingActive){try{let A=new AbortController,I=setTimeout(()=>A.abort(),3e4),O=await fetch(this.pollUrl,{method:"GET",signal:A.signal,headers:{"Cache-Control":"no-cache"}});if(clearTimeout(I),O.ok){let U=await O.text();U&&this._emit(t.MESSAGE,U)}}catch(A){if(A.name==="AbortError")n.debug("Poll timeout, restarting");else if(n.error("Poll failed:",A),this._emit(t.ERROR,A),!navigator.onLine){this.state=e.DISCONNECTED,this._emit(t.DISCONNECT,{reason:"network_lost"});return}}this.pollingActive&&(this.pollTimeout=setTimeout(()=>this._poll(),this.pollingInterval))}}},I1=class{constructor(A,I={}){this.url=A,this.options={transports:[P.WEBSOCKET,P.EVENTSOURCE,P.POLLING],timeout:1e4,pollingInterval:3e3,...I},this.browser=y(),this.network=q(),this.currentTransport=null,this.transportType=P.NONE,this.state=e.IDLE,this.listeners=new Map,this.availableTransports=this._getAvailableTransports(),n.info("Transport manager created",{available:this.availableTransports})}async connect(){if(this.state===e.CONNECTED)return;if(this.state=e.CONNECTING,!this.network.isOnline()){let I=new Error("Network offline");throw this._emit(t.ERROR,I),I}for(let I of this.availableTransports){n.info(`Trying transport: ${I}`);try{await this._tryTransport(I),n.info(`Connected using ${I}`),this.transportType=I,this.state=e.CONNECTED,this._emit(t.TRANSPORT_CHANGED,{transport:I}),this._emit(t.CONNECT,{transport:I});return}catch(O){n.warn(`Transport ${I} failed:`,O.message)}}this.state=e.FAILED;let A=new Error("No transport available");throw this._emit(t.ERROR,A),A}disconnect(){this.currentTransport&&(this.currentTransport.disconnect(),this.currentTransport=null),this.transportType=P.NONE,this.state=e.DISCONNECTED,this._emit(t.DISCONNECT,{reason:"intentional"})}send(A){return!this.currentTransport||this.state!==e.CONNECTED?!1:this.currentTransport.send(A)}getTransportType(){return this.transportType}getState(){return this.state}on(A,I){return this.listeners.has(A)||this.listeners.set(A,[]),this.listeners.get(A).push(I),()=>{let O=this.listeners.get(A)||[],U=O.indexOf(I);U!==-1&&O.splice(U,1)}}_tryTransport(A){return new Promise((I,O)=>{let U;switch(A){case P.WEBSOCKET:U=new QA(this.url,this.options);break;case P.EVENTSOURCE:U=new XA(this.url,this.options);break;case P.POLLING:U=new A1(this.url,this.options);break;default:O(new Error(`Unknown transport: ${A}`));return}let E,K,B=()=>{E&&E(),K&&K(),clearTimeout(R)},R=setTimeout(()=>{U.disconnect(),B(),O(new Error(`Transport ${A} timeout`))},this.options.timeout);E=U.on(t.CONNECT,()=>{this.currentTransport=U,this._forwardTransportEvents(U),B(),I()}),K=U.on(t.ERROR,M=>{B(),O(M||new Error(`Transport ${A} failed`))}),U.connect()})}_forwardTransportEvents(A){[t.MESSAGE,t.DISCONNECT,t.ERROR].forEach(O=>{A.on(O,U=>{this._emit(O,U),O===t.DISCONNECT&&(this.state=e.DISCONNECTED)})})}_getAvailableTransports(){return this.options.transports.filter(A=>{switch(A){case P.WEBSOCKET:return this.browser.hasWebSocket;case P.EVENTSOURCE:return typeof EventSource<"u";case P.POLLING:return!0;default:return!1}})}_emit(A,I){(this.listeners.get(A)||[]).forEach(U=>{try{U(I)}catch(E){n.error("Error in event listener:",E)}})}};function O1(N,A={}){return new I1(N,A)}var eA=S("client"),P3={autoConnect:!1,timeout:1e4,reconnect:!0,reconnectOptions:{maxAttempts:10,baseDelay:1e3,maxDelay:3e4,jitter:!0},heartbeat:{enabled:!0,interval:3e4,timeout:1e4},transport:{transports:["websocket","eventsource","polling"],pollingInterval:3e3},debug:!1},N1=class{constructor(A,I={}){if(!WA(A))throw new TypeError(`Invalid WebSocket URL: ${A}`);this.url=A,this.options=xA(P3,I),this.options.debug&&eA.debug("Debug mode enabled"),this.browser=y(),this.transport=O1(A,{transports:this.options.transport.transports,timeout:this.options.timeout,pollingInterval:this.options.transport.pollingInterval}),this.connection=jA(A,{timeout:this.options.timeout,reconnect:{maxAttempts:this.options.reconnectOptions.maxAttempts,baseDelay:this.options.reconnectOptions.baseDelay,maxDelay:this.options.reconnectOptions.maxDelay,jitter:this.options.reconnectOptions.jitter},heartbeat:this.options.heartbeat,transport:this.transport}),this.messageHandlers=new Map,this.eventHandlers={open:[],message:[],close:[],error:[],reconnect:[],reconnectAttempt:[]},this.messageCounter=0,this.pendingAcks=new Map,this._handleConnectionEvent=this._handleConnectionEvent.bind(this),this._handleTransportMessage=this._handleTransportMessage.bind(this),this._setupEventForwarding(),eA.info("WebSocket client created",{url:A,options:this.options,browser:this.browser.browserInfo.name}),this.options.autoConnect&&setTimeout(()=>this.connect(),0)}_setupEventForwarding(){this.connection.onEvent((A,I)=>{A==="message"?this._handleTransportMessage(I):this._handleConnectionEvent(A,I)}),this.transport.on(t.MESSAGE,A=>{this._handleTransportMessage(A)}),this.transport.on(t.ERROR,A=>{this._triggerEvent("error",A)})}_handleConnectionEvent(A,I){switch(A){case d.CONNECTED:this._triggerEvent("open",I);break;case d.DISCONNECTED:this._triggerEvent("close",I);break;case d.RECONNECTING:this._triggerEvent("reconnectAttempt",{attempt:I.attempt,maxAttempts:I.maxAttempts,delay:I.delay});break;case d.FAILED:this._triggerEvent("error",new Error(`Connection failed: ${I.reason}`));break;case"latency":this._triggerEvent("latency",I);break}}_handleTransportMessage(A){let I=A;if(typeof A=="string")try{I=JSON.parse(A)}catch{}if(I&&I.event==="ack"&&I.id){this._handleAck(I.id,I);return}I&&I.event&&this.messageHandlers.has(I.event)&&this.messageHandlers.get(I.event).forEach(U=>{try{U(I.data||I)}catch(E){eA.error("Error in message handler:",E)}}),this._triggerEvent("message",I)}_handleAck(A,I){if(this.pendingAcks.has(A)){let{resolve:O,reject:U}=this.pendingAcks.get(A);I.success?O(I.result||I):U(new Error(I.error||"Unknown error")),this.pendingAcks.delete(A)}}connect(){return this.connection.connect()}disconnect(A=1e3,I=""){return this.connection.disconnect(A,I)}send(A){if(!this.isConnected())throw new Error("Not connected");let I=A;A&&typeof A=="object"&&!(A instanceof ArrayBuffer)&&!(A instanceof Blob)&&(I=JSON.stringify(A)),this.connection.send(I)}sendWithAck(A,I,O=1e4){if(!this.isConnected())return Promise.reject(new Error("Not connected"));let U=`${Date.now()}-${this.messageCounter++}`,E=EA(),K={event:A,data:I,id:U,ack:!0},B=setTimeout(()=>{this.pendingAcks.has(U)&&(this.pendingAcks.delete(U),E.reject(new Error("Acknowledgement timeout")))},O);return this.pendingAcks.set(U,{resolve:R=>{clearTimeout(B),E.resolve(R)},reject:R=>{clearTimeout(B),E.reject(R)}}),this.connection.send(JSON.stringify(K)),E.promise}onMessage(A,I){return this.messageHandlers.has(A)||this.messageHandlers.set(A,[]),this.messageHandlers.get(A).push(I),this}offMessage(A,I){if(!this.messageHandlers.has(A))return this;if(I){let O=this.messageHandlers.get(A),U=O.indexOf(I);U!==-1&&O.splice(U,1)}else this.messageHandlers.delete(A);return this}on(A,I){if(!["open","message","close","error","reconnect","reconnectAttempt","latency"].includes(A))throw new TypeError(`Unknown event: ${A}`);if(typeof I!="function")throw new TypeError("Handler must be a function");return this.eventHandlers[A]||(this.eventHandlers[A]=[]),this.eventHandlers[A].push(I),this}off(A,I){if(!["open","message","close","error","reconnect","reconnectAttempt","latency"].includes(A))throw new TypeError(`Unknown event: ${A}`);if(!this.eventHandlers[A])return this;if(I){let U=this.eventHandlers[A].indexOf(I);U!==-1&&this.eventHandlers[A].splice(U,1)}else this.eventHandlers[A]=[];return this}_triggerEvent(A,I){(this.eventHandlers[A]||[]).forEach(U=>{try{U(I)}catch(E){eA.error(`Error in ${A} handler:`,E)}})}isConnected(){return this.connection.isConnected()}isHealthy(){return this.connection.isHealthy()}getStatus(){var O,U,E;let A=this.connection.getStatus(),I=SA();return{connected:this.isConnected(),state:A.state,url:this.url,transport:this.transport.getTransportType(),latency:(O=A.heartbeat)==null?void 0:O.latency,uptime:A.uptime,messagesSent:(U=A.messages)==null?void 0:U.sent,messagesReceived:(E=A.messages)==null?void 0:E.received,reconnectAttempts:A.reconnectAttempts,networkOnline:I,browser:this.browser.browserInfo.name}}reconnect(){return this.connection.reconnect()}getTransportType(){return this.transport.getTransportType()}destroy(){eA.info("Destroying client"),this.disconnect(1e3,"Client destroyed"),this.messageHandlers.clear(),this.eventHandlers={open:[],message:[],close:[],error:[],reconnect:[],reconnectAttempt:[]},this.pendingAcks.clear()}},j1=N1;var p4=S("packet"),DA={MESSAGE:"message",EVENT:"event",COMMAND:"command",RESPONSE:"response",ERROR:"error",PING:"ping",PONG:"pong",JOIN:"join",LEAVE:"leave",PRESENCE:"presence",ACK:"ack",AUTH:"auth",SYSTEM:"system"},U1={CRITICAL:"critical",HIGH:"high",NORMAL:"normal",LOW:"low"},E1={AT_MOST_ONCE:"at_most_once",AT_LEAST_ONCE:"at_least_once",EXACTLY_ONCE:"exactly_once"};var g4=256*1024;var m=S("router"),KA={EXACT:"exact",WILDCARD:"wildcard",REGEX:"regex",FUNCTION:"function"},Q1={CRITICAL:100,HIGH:200,NORMAL:300,LOW:400,FALLBACK:500},w={PRE:"pre",POST:"post",AROUND:"around"},K1=class{constructor(A,I,O={}){this.pattern=A,this.handler=I,this.matchType=O.matchType||KA.EXACT,this.priority=O.priority||Q1.NORMAL,this.namespace=O.namespace||null,this.description=O.description||A.toString(),this.id=`${Date.now()}-${Math.random().toString(36).substring(2,8)}`,this.created=Date.now(),this.callCount=0,this.lastCalled=null}matches(A){if(this.namespace&&A.namespace!==this.namespace)return!1;let I=A.type;switch(this.matchType){case KA.EXACT:return I===this.pattern;case KA.WILDCARD:return this._matchWildcard(I,this.pattern);case KA.REGEX:return this.pattern.test(I);case KA.FUNCTION:return this.pattern(A);default:return!1}}execute(A,I){this.callCount++,this.lastCalled=Date.now();try{return this.handler(A,I)}catch(O){throw m.error(`Handler ${this.description} failed:`,O),O}}_matchWildcard(A,I){if(I==="*")return!0;let O=I.replace(/\./g,"\\.").replace(/\*/g,".*");return new RegExp(`^${O}$`).test(A)}getStats(){return{id:this.id,description:this.description,matchType:this.matchType,priority:this.priority,namespace:this.namespace,callCount:this.callCount,lastCalled:this.lastCalled,created:this.created}}},B1=class N{constructor(A={}){this.options={catchErrors:!0,asyncHandlers:!1,maxHandlersPerRoute:10,logHandling:!0,...A},this.routes=new Map,this.namespaces=new Map,this.middleware={[w.PRE]:[],[w.POST]:[],[w.AROUND]:[]},this.stats={routesProcessed:0,handlersExecuted:0,errorsCaught:0,lastRoute:null},this._setupDefaultHandlers(),m.info("Router created")}_setupDefaultHandlers(){this.on("*",A=>{m.debug("Unhandled message type:",A.type)},{matchType:KA.WILDCARD,priority:Q1.FALLBACK,description:"Catch-all handler"}),this.on(DA.ERROR,A=>{m.error("Received error packet:",A.payload)},{description:"Error handler"})}on(A,I,O={}){if(typeof I!="function")throw new TypeError("Handler must be a function");let U=new K1(A,I,O),E=this._getRouteKey(A,O.namespace);this.routes.has(E)||this.routes.set(E,[]);let K=this.routes.get(E);return K.length>=this.options.maxHandlersPerRoute&&m.warn(`Max handlers (${this.options.maxHandlersPerRoute}) reached for route:`,E),K.push(U),K.sort((B,R)=>B.priority-R.priority),m.debug("Handler registered",{pattern:A,namespace:O.namespace,priority:O.priority}),()=>{this.off(A,I,O.namespace)}}off(A,I,O){let U=this._getRouteKey(A,O),E=this.routes.get(U);if(!E)return;let K=E.findIndex(B=>B.handler===I);K!==-1&&(E.splice(K,1),m.debug("Handler removed",{pattern:A,namespace:O})),E.length===0&&this.routes.delete(U)}once(A,I,O={}){let U=(E,K)=>{I(E,K),this.off(A,U,O.namespace)};this.on(A,U,O)}route(A,I={}){this.stats.routesProcessed++,this.stats.lastRoute=Date.now(),this._runMiddleware(w.PRE,A,I);let O=this._findHandlers(A);if(O.length===0){m.debug("No handlers for packet type:",A.type);return}m.debug("Routing packet",{type:A.type,namespace:A.namespace,handlers:O.length});let U=[];for(let E of O)try{let K=this._runAroundMiddleware(A,I,E);if(K!==void 0)U.push(K);else{let B=E.execute(A,I);U.push(B)}this.stats.handlersExecuted++}catch(K){if(this.stats.errorsCaught++,this.options.catchErrors)m.error("Handler error:",K);else throw K}return this._runMiddleware(w.POST,A,I,U),this.options.asyncHandlers?Promise.all(U):U}namespace(A){if(!this.namespaces.has(A)){let I=new N(this.options);I.on=(O,U,E={})=>this.on(O,U,{...E,namespace:A}),I.off=(O,U,E={})=>this.off(O,U,A),this.namespaces.set(A,I)}return this.namespaces.get(A)}use(A,I){if(!this.middleware[A])throw new Error(`Invalid middleware type: ${A}`);this.middleware[A].push(I),m.debug("Middleware added",{type:A})}removeMiddleware(A,I){let O=this.middleware[A].indexOf(I);O!==-1&&this.middleware[A].splice(O,1)}_findHandlers(A){let I=[];for(let[O,U]of this.routes)if(this._routeCouldMatch(O,A)){let E=U.filter(K=>K.matches(A));I.push(...E)}return I.sort((O,U)=>O.priority-U.priority),I}_routeCouldMatch(A,I){let[O,U,E]=A.split("|");return!(U&&U!==I.namespace)}_getRouteKey(A,I){return`${A instanceof RegExp?"regex":typeof A}|${I||""}|${A}`}_runMiddleware(A,I,O,U=null){for(let E of this.middleware[A])try{E(I,O,U)}catch(K){m.error(`Middleware (${A}) error:`,K)}}_runAroundMiddleware(A,I,O){let U;for(let E of this.middleware[w.AROUND])if(U=E(A,I,(B,R)=>O.execute(B,R)),U!==void 0)break;return U}getRoutes(){let A=[];for(let[I,O]of this.routes)A.push({key:I,handlers:O.map(U=>U.getStats())});return A}getStats(){return{...this.stats,totalRoutes:this.routes.size,totalHandlers:Array.from(this.routes.values()).reduce((A,I)=>A+I.length,0),middlewareCount:{pre:this.middleware[w.PRE].length,post:this.middleware[w.POST].length,around:this.middleware[w.AROUND].length},namespaces:this.namespaces.size}}reset(){this.routes.clear(),this.namespaces.clear(),this.middleware={[w.PRE]:[],[w.POST]:[],[w.AROUND]:[]},this._setupDefaultHandlers(),m.info("Router reset")}};function X1(N={}){return new B1(N)}var AA=S("namespace"),z={CREATED:"created",DESTROYED:"destroyed",USER_JOINED:"user_joined",USER_LEFT:"user_left",ERROR:"error"},h3={autoCreateRooms:!0,maxRooms:100,broadcastPresence:!0,persistState:!1,authRequired:!1},sA=class N{constructor(A,I,O={}){if(!bA(A))throw new Error(`Invalid namespace path: ${A}`);this.path=A,this.socket=I,this.options={...h3,...O},this.id=_("ns"),this.router=X1({catchErrors:!0}),this.rooms=new Map,this.users=new Map,this.children=new Map,this.handlers={[z.CREATED]:[],[z.DESTROYED]:[],[z.USER_JOINED]:[],[z.USER_LEFT]:[],[z.ERROR]:[]},this.state={created:Date.now(),messageCount:0,userCount:0,roomCount:0},this._handleMessage=this._handleMessage.bind(this),AA.info("Namespace created",{path:this.path,id:this.id})}on(A,I){if(typeof I!="function")throw new TypeError("Handler must be a function");return this.router.on(A,(O,U)=>{I(O.payload,U)}),this}onMessage(A,I){return this.on(A,I)}emit(A,I,O={}){let U={type:A,data:I,namespace:this.path,timestamp:Date.now()};if(this.state.messageCount++,O.ack)return this.socket.sendWithAck(A,U,O.timeout);this.socket.send(U)}broadcast(A,I,O=[]){this.emit("broadcast",{event:A,data:I,except:O,namespace:this.path})}async joinRoom(A,I){if(!this.rooms.has(A)){if(this.rooms.size>=this.options.maxRooms)return AA.warn("Max rooms reached",{namespace:this.path}),!1;this.rooms.set(A,new Set)}return this.rooms.get(A).add(I),this.state.roomCount=this.rooms.size,AA.debug("User joined room",{namespace:this.path,room:A,userId:I}),this.broadcast("user_joined",{room:A,userId:I},[I]),!0}leaveRoom(A,I){let O=this.rooms.get(A);O&&(O.delete(I),O.size===0&&this.rooms.delete(A),AA.debug("User left room",{namespace:this.path,room:A,userId:I}),this.broadcast("user_left",{room:A,userId:I},[I]))}getRoomUsers(A){let I=this.rooms.get(A);return I?Array.from(I):[]}getRooms(){return Array.from(this.rooms.keys())}addUser(A,I={}){this.users.set(A,{...I,joined:Date.now(),rooms:[]}),this.state.userCount=this.users.size,AA.debug("User added to namespace",{namespace:this.path,userId:A}),this.options.broadcastPresence&&this.broadcast("presence",{userId:A,status:"online",data:I})}removeUser(A){for(let[I,O]of this.rooms)O.has(A)&&this.leaveRoom(I,A);this.users.delete(A),this.state.userCount=this.users.size,AA.debug("User removed from namespace",{namespace:this.path,userId:A}),this.options.broadcastPresence&&this.broadcast("presence",{userId:A,status:"offline"})}namespace(A,I={}){let O=this.path==="/"?A:`${this.path}${A}`;if(!this.children.has(O)){let U=new N(O,this.socket,{...this.options,...I});this.children.set(O,U)}return this.children.get(O)}_handleMessage(A){return A.namespace!==this.path?!1:(this.router.route(A,{namespace:this,socket:this.socket}),!0)}hasUser(A){return this.users.has(A)}getStats(){return{...this.state,path:this.path,id:this.id,userCount:this.users.size,roomCount:this.rooms.size,childCount:this.children.size}}destroy(){this.rooms.clear(),this.users.clear();for(let A of this.children.values())A.destroy();this.children.clear(),AA.info("Namespace destroyed",{path:this.path}),this._emit(z.DESTROYED,{path:this.path,id:this.id})}_emit(A,I){(this.handlers[A]||[]).forEach(U=>{try{U(I)}catch(E){AA.error(`Error in ${A} handler:`,E)}})}_on(A,I){return this.handlers[A]||(this.handlers[A]=[]),this.handlers[A].push(I),this}};var $=S("rooms"),u={USER_JOINED:"user_joined",USER_LEFT:"user_left",ROOM_CREATED:"room_created",ROOM_DESTROYED:"room_destroyed",ROOM_MESSAGE:"room_message",ROOM_UPDATED:"room_updated",ERROR:"error"},cA={PUBLIC:"public",PRIVATE:"private",HIDDEN:"hidden"},BA={TEMPORARY:"temporary",PERSISTENT:"persistent",ANONYMOUS:"anonymous"},J3={maxUsers:100,visibility:cA.PUBLIC,type:BA.TEMPORARY,broadcastPresence:!0,persistMessages:!1,maxHistory:100,inviteOnly:!1},R1=class{constructor(A,I={}){this.userId=A,this.joinedAt=Date.now(),this.lastActivity=Date.now(),this.role=I.role||"member",this.metadata=I.metadata||{},this.presence="online"}updateActivity(){this.lastActivity=Date.now()}setPresence(A){this.presence=A,this.updateActivity()}toJSON(){return{userId:this.userId,joinedAt:this.joinedAt,lastActivity:this.lastActivity,role:this.role,metadata:this.metadata,presence:this.presence}}},rA=class{constructor(A,I={}){this.name=A,this.id=_("room"),this.options={...J3,...I},this.members=new Map,this.messageHistory=[],this.metadata={...this.options.metadata,createdAt:Date.now(),createdBy:null},this.state={active:!0,memberCount:0,messageCount:0,lastActivity:Date.now()},this.handlers={[u.USER_JOINED]:[],[u.USER_LEFT]:[],[u.ROOM_MESSAGE]:[],[u.ROOM_UPDATED]:[],[u.ERROR]:[]},$.info("Room created",{name:this.name,id:this.id,visibility:this.options.visibility})}addMember(A,I={}){if(this.members.has(A))return $.debug("User already in room",{userId:A,room:this.name}),!1;if(this.members.size>=this.options.maxUsers)return $.warn("Room full",{room:this.name,max:this.options.maxUsers}),this._emit(u.ERROR,{code:"room_full",message:"Room has reached maximum capacity"}),!1;if(this.options.inviteOnly&&!I.invited)return $.warn("Attempt to join invite-only room",{userId:A,room:this.name}),!1;let O=new R1(A,I);return this.members.set(A,O),this.state.memberCount=this.members.size,this.state.lastActivity=Date.now(),$.debug("User joined room",{userId:A,room:this.name,memberCount:this.members.size}),this.options.broadcastPresence&&this._emit(u.USER_JOINED,{userId:A,room:this.name,timestamp:Date.now(),memberData:O.toJSON()}),!0}removeMember(A,I="left"){if(!this.members.has(A))return!1;let O=this.members.get(A);return this.members.delete(A),this.state.memberCount=this.members.size,this.state.lastActivity=Date.now(),$.debug("User left room",{userId:A,room:this.name,reason:I,memberCount:this.members.size}),this.options.broadcastPresence&&this._emit(u.USER_LEFT,{userId:A,room:this.name,reason:I,timestamp:Date.now(),memberData:O.toJSON()}),this.options.type===BA.TEMPORARY&&this.members.size===0&&this.destroy("Room empty"),!0}hasMember(A){return this.members.has(A)}getMember(A){let I=this.members.get(A);return I?I.toJSON():null}getMembers(){return Array.from(this.members.values()).map(A=>A.toJSON())}getMemberCount(){return this.members.size}message(A,I,O={}){if(!this.members.has(A)&&this.options.type!==BA.ANONYMOUS)throw new Error(`User ${A} is not in room ${this.name}`);let U={id:_("msg"),room:this.name,userId:A,message:I,timestamp:Date.now(),type:O.type||"message",metadata:O.metadata||{}};return this.members.has(A)&&this.members.get(A).updateActivity(),this.state.messageCount++,this.state.lastActivity=Date.now(),this.options.persistMessages&&(this.messageHistory.push(U),this.messageHistory.length>this.options.maxHistory&&(this.messageHistory=this.messageHistory.slice(-this.options.maxHistory))),$.debug("Room message",{room:this.name,userId:A,msgId:U.id}),this._emit(u.ROOM_MESSAGE,U),U.id}broadcast(A,I,O=[]){let U={room:this.name,event:A,data:I,timestamp:Date.now()};this._emit(A,U,O)}update(A,I=null){this.metadata={...this.metadata,...A,updatedAt:Date.now(),updatedBy:I},this._emit(u.ROOM_UPDATED,{room:this.name,updates:A,userId:I,timestamp:Date.now()})}getInfo(){return{id:this.id,name:this.name,options:{...this.options},metadata:{...this.metadata},state:{...this.state},memberCount:this.members.size,messageCount:this.state.messageCount}}getHistory(A=this.options.maxHistory){return this.messageHistory.slice(-A)}on(A,I){return this.handlers[A]||(this.handlers[A]=[]),this.handlers[A].push(I),()=>{let O=this.handlers[A].indexOf(I);O!==-1&&this.handlers[A].splice(O,1)}}destroy(A="Room destroyed"){this.state.active=!1,$.info("Room destroyed",{name:this.name,id:this.id,reason:A,memberCount:this.members.size}),this._emit(u.ROOM_DESTROYED,{room:this.name,reason:A,timestamp:Date.now()}),this.members.clear(),this.messageHistory=[],this.handlers={}}_emit(A,I,O=[]){(this.handlers[A]||[]).forEach(E=>{try{E(I,O)}catch(K){$.error(`Error in ${A} handler:`,K)}})}};var O6=S("presence"),M1={ONLINE:"online",AWAY:"away",BUSY:"busy",OFFLINE:"offline",CONNECTING:"connecting",RECONNECTING:"reconnecting"},L1={TYPING:"typing",TYPING_STOPPED:"typing_stopped",VIEWING:"viewing",EDITING:"editing",IDLE:"idle"},G1={STATE_CHANGED:"state_changed",ACTIVITY_UPDATED:"activity_updated",USER_ONLINE:"user_online",USER_OFFLINE:"user_offline",TYPING_STARTED:"typing_started",TYPING_STOPPED:"typing_stopped",SUBSCRIBED:"subscribed",UNSUBSCRIBED:"unsubscribed",ERROR:"error"};var L6=S("ack");var Y6=S("queue");var S6={maxSize:1e3,maxAge:10080*60*1e3,autoProcess:!0,batchSize:10,batchDelay:100,maxRetries:5,preserveOrder:!0,dropOldestWhenFull:!0};var i6=S("storage");var n6={dbName:"websocket_queue",storeName:"messages",dbVersion:1,maxItems:1e4,maxSize:5*1024*1024,autoInit:!0,storageType:null};var a6=S("retry"),T1={EXPONENTIAL:"exponential",LINEAR:"linear",FIXED:"fixed",FIBONACCI:"fibonacci",IMMEDIATE:"immediate"},A2={ALL:"all",NETWORK:"network",SERVER:"server",TIMEOUT:"timeout",CUSTOM:"custom"};var P6={maxAttempts:5,initialDelay:1e3,maxDelay:3e4,strategy:T1.EXPONENTIAL,factor:2,jitter:!0,retryCondition:A2.ALL,customCondition:null,circuitBreaker:{enabled:!0,failureThreshold:5,openTimeout:3e4,successThreshold:2},resetOnSuccess:!0};var g6=S("recovery");var I2={FULL:"full",MINIMAL:"minimal",VERIFIED:"verified",CONNECTION_ONLY:"connection_only"},f6={strategy:I2.FULL,maxStateAge:10080*60*1e3,autoRecover:!0,enableCheckpoints:!0,checkpointInterval:300*1e3,maxCheckpoints:5,verifyWithServer:!0,recoveryTimeout:3e4,replayQueue:!0,restoreSubscriptions:!0,restorePresence:!0};var O2=j1;
1491
1491
  //# sourceMappingURL=js_aide.cjs.js.map