@vibexnpm/talkx 8.10.0 → 8.12.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.
@@ -1,2 +1,2 @@
1
- class e{constructor(){this._events=new Map}on(e,t){return this._events.has(e)||this._events.set(e,new Set),this._events.get(e).add(t),()=>this.off(e,t)}once(e,t){const s=(...i)=>{this.off(e,s),t.apply(this,i)};return s._originalListener=t,this.on(e,s)}off(e,t){const s=this._events.get(e);if(s){for(const e of s)if(e===t||e._originalListener===t){s.delete(e);break}0===s.size&&this._events.delete(e)}}emit(e,t){const s=this._events.get(e);s&&s.forEach(s=>{try{s(t)}catch(t){console.error(`Error in event listener for '${e}':`,t)}})}removeAllListeners(e){e?this._events.delete(e):this._events.clear()}listenerCount(e){const t=this._events.get(e);return t?t.size:0}eventNames(){return Array.from(this._events.keys())}}const t={DISCONNECTED:"disconnected",CONNECTING:"connecting",CONNECTED:"connected",RECONNECTING:"reconnecting",ERROR:"error"},s={CONNECTION_FAILED:"CONNECTION_FAILED",CONNECTION_LOST:"CONNECTION_LOST",CONNECTION_TIMEOUT:"CONNECTION_TIMEOUT",SUBSCRIPTION_REQUIRED:"SUBSCRIPTION_REQUIRED",JWT_INVALID:"JWT_INVALID",JWT_EXPIRED:"JWT_EXPIRED",JWT_PARSE_FAILED:"JWT_PARSE_FAILED",UNAUTHORIZED:"UNAUTHORIZED",API_ERROR:"API_ERROR",API_TIMEOUT:"API_TIMEOUT",CHAT_ROOM_NOT_FOUND:"CHAT_ROOM_NOT_FOUND",CHAT_MESSAGE_FAILED:"CHAT_MESSAGE_FAILED",CHAT_SUBSCRIPTION_FAILED:"CHAT_SUBSCRIPTION_FAILED",MEDIA_ACCESS_DENIED:"MEDIA_ACCESS_DENIED",SCREEN_SHARE_DENIED:"SCREEN_SHARE_DENIED",PEER_CONNECTION_FAILED:"PEER_CONNECTION_FAILED",ICE_CONNECTION_FAILED:"ICE_CONNECTION_FAILED",SIGNALING_FAILED:"SIGNALING_FAILED",DEVICE_SWITCH_FAILED:"DEVICE_SWITCH_FAILED",ENUMERATE_DEVICES_FAILED:"ENUMERATE_DEVICES_FAILED",CALL_ROOM_NOT_FOUND:"CALL_ROOM_NOT_FOUND",INVALID_STATE:"INVALID_STATE",UNKNOWN_ERROR:"UNKNOWN_ERROR"},i={CALL_OFFER:"call_offer",CALL_ANSWER:"call_answer",ICE_CANDIDATE:"ice_candidate",JOIN_ROOM:"join_room",LEAVE_ROOM:"leave_room",PEER_JOINED:"peer_joined",PEER_LEFT:"peer_left",VIDEO_STATE_CHANGED:"video_state_changed",AUDIO_STATE_CHANGED:"audio_state_changed",SCREEN_SHARE_STARTED:"screen_share_started",SCREEN_SHARE_ENDED:"screen_share_ended",CALL_REQUEST:"call_request",CALL_ACCEPT:"call_accept",CALL_REJECT:"call_reject",CALL_CANCEL:"call_cancel",CALL_END:"call_end",CALL_INVITATION:"call_invitation",CALL_BUSY:"call_busy"},n={TEXT:"TEXT",IMAGE:"IMAGE",FILE:"FILE",VIDEO:"VIDEO",AUDIO:"AUDIO",DOCUMENT:"DOCUMENT",MIXED:"MIXED",GALLERY:"GALLERY",SYSTEM:"SYSTEM"},r={MIN_OPTIONS:2,MAX_OPTIONS:5,LABEL_MAX_LENGTH:80,QUESTION_MAX_LENGTH:200},o={USER:"USER",ASSISTANT:"ASSISTANT"},a={LEGAL_ADVISOR:"LEGAL_ADVISOR",MARKETING:"MARKETING",PRODUCT_PLANNING:"PRODUCT_PLANNING",HR:"HR",FINANCE:"FINANCE",CUSTOMER_SUPPORT:"CUSTOMER_SUPPORT",SALES:"SALES",ENGINEERING:"ENGINEERING",DATA_ANALYST:"DATA_ANALYST",PROJECT_MANAGEMENT:"PROJECT_MANAGEMENT",RESEARCH:"RESEARCH",TRANSLATION:"TRANSLATION",DESIGN:"DESIGN",PM:"PM"},c={MINUTES:"MINUTES",SHORT:"SHORT",TIMELINE:"TIMELINE",ACTIONS:"ACTIONS",OPTIONS:"OPTIONS"},h={DIRECT:"DIRECT",GROUP:"GROUP",PRIVATE_GROUP:"PRIVATE_GROUP",TEAM:"TEAM"},l={GENERAL:"GENERAL",PEOPLE_ONLY:"PEOPLE_ONLY",CALL_ONLY:"CALL_ONLY"},d={NONE:"NONE",PERSONA_MULTI:"PERSONA_MULTI",PM_BACKSTAGE:"PM_BACKSTAGE"},u={QUIET:"QUIET",NORMAL:"NORMAL",ACTIVE:"ACTIVE"},p={PROJECT:"PROJECT",ROOM:"ROOM"},g={SUPER_ADMIN:"SUPER_ADMIN",PROJECT_ADMIN:"PROJECT_ADMIN",ROOM_OWNER:"ROOM_OWNER"},m={MESSAGE_RECEIVED:"MESSAGE_RECEIVED",MESSAGE_DELETED:"MESSAGE_DELETED",MESSAGE_UPDATED:"MESSAGE_UPDATED",ROOM_CREATED:"ROOM_CREATED",ROOM_JOINED:"ROOM_JOINED",ROOM_LEFT:"ROOM_LEFT",ROOM_UPDATED:"ROOM_UPDATED",ROOM_KICKED:"ROOM_KICKED",ROOM_BANNED:"ROOM_BANNED",ROOM_OWNER_CHANGED:"ROOM_OWNER_CHANGED",ROOM_DELETED:"ROOM_DELETED",MESSAGE_RETENTION_CLEANUP:"MESSAGE_RETENTION_CLEANUP",ROOM_UNREAD_UPDATED:"ROOM_UNREAD_UPDATED",AI_UNAVAILABLE:"AI_UNAVAILABLE"},_={SOCKJS_ENDPOINT:"/ws-chat",NATIVE_ENDPOINT:"/ws-chat-native",APP_PREFIX:"/app",TOPIC_PREFIX:"/topic",QUEUE_PREFIX:"/queue",USER_PREFIX:"/user",getChatDestination:e=>`/topic/chat/${e}`,getChatReadDestination:e=>`/topic/chat/${e}/read`,getChatTypingDestination:e=>`/topic/chat/${e}/typing`,getChatAssistantStreamDestination:e=>`/topic/chat/${e}/assistant-stream`,getChatSummaryDestination:e=>`/topic/chat/${e}/summary`,ROOM_LIST_USER_DESTINATION:"/user/queue/rooms",MAIL_USER_DESTINATION:"/user/queue/mail",getWebRTCDestination:e=>`/topic/webrtc/${e}`,getWebRTCUserDestination:()=>"/user/queue/webrtc",CHAT_SEND:"/app/chat/send",CHAT_READ:"/app/chat/read",CHAT_TYPING:"/app/chat/typing",WEBRTC_SIGNAL:"/app/webrtc/signal"},f={DEVELOPMENT:"development",STAGING:"staging",PRODUCTION:"production"},y={[f.DEVELOPMENT]:{serverUrl:"https://dev-chat.apiorbit.net",wsEndpoint:"/ws-chat"},[f.STAGING]:{serverUrl:"https://stg-api.talk-x.app",wsEndpoint:"/ws-chat"},[f.PRODUCTION]:{serverUrl:"https://prod-api.talk-x.app",wsEndpoint:"/ws-chat"}},b={environment:f.PRODUCTION,reconnectDelay:5e3,maxReconnectDelay:3e4,maxReconnectAttempts:10,reconnectRecoveryDelay:6e4,heartbeatIncoming:1e4,heartbeatOutgoing:1e4,resumeOnVisibility:!0,syncOnReconnect:!0,rewindMillis:3e3,maxSyncPages:5,syncPageSize:100,apiTimeout:3e4,iceServers:[{urls:"stun:stun.l.google.com:19302"},{urls:"stun:stun1.l.google.com:19302"}],logLevel:2};function v(e){return(y[e]||y[f.PRODUCTION]).serverUrl}const w={DEBUG:0,INFO:1,WARN:2,ERROR:3,NONE:4};class S{constructor(e=w.WARN,t="TalkFlow"){this.level=e,this.prefix=t}setLevel(e){this.level=e}setPrefix(e){this.prefix=e}_format(e,...t){return[`[${(new Date).toISOString()}] [${e}] [${this.prefix}]`,...t]}debug(...e){this.level<=w.DEBUG&&console.debug(...this._format("DEBUG",...e))}info(...e){this.level<=w.INFO&&console.info(...this._format("INFO",...e))}warn(...e){this.level<=w.WARN&&console.warn(...this._format("WARN",...e))}error(...e){this.level<=w.ERROR&&console.error(...this._format("ERROR",...e))}}class E{constructor(e){this.baseUrl=e.baseUrl.replace(/\/$/,""),this.apiKey=e.apiKey,this.projectId=e.projectId,this.jwtToken=e.jwtToken,this.timeout=e.timeout||b.apiTimeout,this.logger=new S(e.logLevel,"ApiClient")}setJwtToken(e){this.jwtToken=e}_getHeaders(){const e={"Content-Type":"application/json","X-API-KEY":this.apiKey,"X-PROJECT-ID":this.projectId};return this.jwtToken&&(e.Authorization=this.jwtToken.startsWith("Bearer ")?this.jwtToken:`Bearer ${this.jwtToken}`),e}async request(e,t,s={}){if(!this.authProvider||s.skipAuth)return this._request(e,t,s);this.jwtToken=await this.authProvider.getAccessToken();const i=this.jwtToken,n=this.authProvider.generation;try{return await this._request(e,t,s)}catch(r){if(401===r.status&&["ACCESS_UNAUTHORIZED","TOKEN_INVALID"].includes(r.response?.code)){if(n!==this.authProvider.generation)throw r;this.jwtToken=await this.authProvider.getAccessToken({forceRefresh:!0,rejectedToken:i});const o=this.jwtToken,a=this.authProvider.generation;try{return await this._request(e,t,s)}catch(e){throw await this.authProvider.authenticationFailed(e,{rejectedToken:o,generation:a}),e}}throw await this.authProvider.authenticationFailed(r,{rejectedToken:i,generation:n}),r}}async _request(e,t,i={}){const{body:n,params:r,headers:o}=i;let a=`${this.baseUrl}${t}`;if(r){const e=new URLSearchParams;Object.entries(r).forEach(([t,s])=>{null!=s&&e.append(t,s)});const t=e.toString();t&&(a+=`?${t}`)}const c=new AbortController,h=setTimeout(()=>c.abort(),this.timeout);let l;try{this.logger.debug(`${e} ${a}`),l=await fetch(a,{method:e,headers:{...this._getHeaders(),...o},credentials:this.authProvider?"omit":"same-origin",body:n?JSON.stringify(n):void 0,signal:c.signal})}catch(t){if(clearTimeout(h),"AbortError"===t.name){const e=new Error("Request timeout");throw e.code=s.API_TIMEOUT,e}throw this.logger.error(`API Error: ${e} ${a}`,t),t}clearTimeout(h);const d=l.headers.get("content-type");let u;if(u=d&&d.includes("application/json")?await l.json():await l.text(),!l.ok){const t=new Error(u?.message||`HTTP ${l.status}`);throw t.code=s.API_ERROR,t.status=l.status,t.response=u,this.logger.error(`API Error: ${e} ${a}`,t),t}return this.logger.debug(`Response ${l.status}`),u}get(e,t){return this.request("GET",e,{params:t})}post(e,t,s,i){return this.request("POST",e,{body:t,params:s,headers:i})}put(e,t){return this.request("PUT",e,{body:t})}patch(e,t){return this.request("PATCH",e,{body:t})}delete(e,t){return this.request("DELETE",e,{params:t})}async upload(e,t,s={}){if(!this.authProvider)return this._upload(e,t,s);this.jwtToken=await this.authProvider.getAccessToken();const i=this.jwtToken,n=this.authProvider.generation;try{return await this._upload(e,t,s)}catch(r){if(401===r.status&&["ACCESS_UNAUTHORIZED","TOKEN_INVALID"].includes(r.response?.code)){if(n!==this.authProvider.generation)throw r;this.jwtToken=await this.authProvider.getAccessToken({forceRefresh:!0,rejectedToken:i});const o=this.jwtToken,a=this.authProvider.generation;try{return await this._upload(e,t,s)}catch(e){throw await this.authProvider.authenticationFailed(e,{rejectedToken:o,generation:a}),e}}throw await this.authProvider.authenticationFailed(r,{rejectedToken:i,generation:n}),r}}_upload(e,t,i={}){const{fieldName:n="file",onProgress:r,signal:o,timeout:a=6e5}=i;return new Promise((i,c)=>{const h=`${this.baseUrl}${e}`,l=new XMLHttpRequest,d=new FormData;d.append(n,t),l.open("POST",h),l.timeout=a,l.setRequestHeader("X-API-KEY",this.apiKey),l.setRequestHeader("X-PROJECT-ID",this.projectId),this.jwtToken&&l.setRequestHeader("Authorization",this.jwtToken.startsWith("Bearer ")?this.jwtToken:`Bearer ${this.jwtToken}`),"function"==typeof r&&(l.upload.onprogress=e=>{e.lengthComputable&&r({loaded:e.loaded,total:e.total,percent:Math.round(e.loaded/e.total*100)})});const u=()=>l.abort();if(o){if(o.aborted)return void c(new Error("Upload cancelled"));o.addEventListener("abort",u)}const p=()=>{o&&o.removeEventListener("abort",u)};l.onload=()=>{p();let e=l.responseText;if((l.getResponseHeader("content-type")||"").includes("application/json"))try{e=JSON.parse(l.responseText)}catch{}if(l.status>=200&&l.status<300)this.logger.debug(`Upload ${l.status}:`,e),i(e);else{const t=new Error(e?.message||`HTTP ${l.status}`);t.code=s.API_ERROR,t.status=l.status,t.response=e,this.logger.error(`Upload Error: POST ${h}`,t),c(t)}},l.onerror=()=>{p();const e=new Error("Network error during upload");e.code=s.API_ERROR,this.logger.error(`Upload Network Error: POST ${h}`,e),c(e)},l.ontimeout=()=>{p();const e=new Error("Upload timeout");e.code=s.API_TIMEOUT,this.logger.error(`Upload Timeout: POST ${h}`,e),c(e)},l.onabort=()=>{p(),c(new Error("Upload cancelled"))},this.logger.debug(`POST ${h} (multipart, ${t.size} bytes)`),l.send(d)})}}const I=new Map,T=new Set(["REFRESH_INVALID","REFRESH_REUSED","SESSION_REVOKED","ACCOUNT_BLOCKED","LOGIN_FAILED"]),R=e=>T.has(e?.response?.code||e?.code);function C(e){try{const t=e.replace(/^Bearer\s+/i,"").split(".")[1].replace(/-/g,"+").replace(/_/g,"/");return JSON.parse(atob(t))}catch{return{}}}class A extends e{static forServer(e){const t=e.replace(/\/$/,"");return I.has(t)||I.set(t,new A(t)),I.get(t)}constructor(e){super(),this.serverUrl=e,this.state="checking",this.data=null,this.clients=new Set,this.generation=0,this.refreshPromise=null,this.timer=null,this.peerWaiters=new Map,this.markerKey=`talkflow:auth:${e}`,this.marker=this._readMarker(),this.serverClock=null,this.channel=null,this.storageListener=e=>{if(e.key!==this.markerKey)return;const t=this._readMarker();(t.revision!==this.marker.revision||t.logout)&&(this.marker=t,this.generation++,this._clear(!1).catch(e=>this.emit("authError",e)))},globalThis.addEventListener?.("storage",this.storageListener),"undefined"!=typeof window&&"undefined"!=typeof BroadcastChannel&&(this.channel=new BroadcastChannel(`talkflow:auth:${e}`),this.channel.onmessage=e=>this._receive(e.data),this.channel.unref?.())}_readMarker(){try{const e=globalThis.localStorage?.getItem(this.markerKey);return e?JSON.parse(e):{revision:"initial",logout:!1}}catch{throw this._storageError()}}_storageError(){const e=new Error("Authentication storage is unavailable");return e.code="AUTH_STORAGE_UNAVAILABLE",e}_writeMarker(e){try{if(!globalThis.localStorage)throw this._storageError();globalThis.localStorage.setItem(this.markerKey,JSON.stringify(e)),this.marker=e}catch{throw this._storageError()}}_newMarker(e,t=e){const s=this._readMarker(),i={revision:globalThis.crypto?.randomUUID?.()||String(Date.now())+"-"+Math.random(),logout:e,deviceId:s.deviceId,pending:t,pendingRefreshToken:e&&t?s.refreshToken||s.pendingRefreshToken:void 0};return this._writeMarker(i),i}setDeviceId(e){this._writeMarker({...this._readMarker(),deviceId:e})}_monotonic(){return globalThis.performance?.now?.()??Date.now()}_serverNow(){return this.serverClock?this.serverClock.server+Math.max(this._monotonic()-this.serverClock.mono,Date.now()-this.serverClock.wall):Date.now()}_shareData(){return this.data?{...this.data,refreshToken:void 0,serverTime:this._serverNow()}:null}_publish(e,t,s=this.marker){const{revision:i,logout:n,pending:r}=s;this.channel?.postMessage({type:e,marker:{revision:i,logout:n,pending:r},data:t})}_setState(e,t,s=!1){const i=this.state;this.state=e,(i!==e||t||s)&&this.emit("authStateChanged",{state:e,previous:i,error:t})}getAuthState(){return this.state}isLoggedIn(){return"authenticated"===this.state}_fresh(e=this.data?.accessToken){return 1e3*Number(C(e||"").exp||0)>this._serverNow()+(this.refreshMargin??6e4)}attach(e){this.clients.add(e)}detach(e){this.clients.delete(e),this.schedule()}_enqueue(e){const t=(this.transition||Promise.resolve()).then(e);return this.transition=t.catch(()=>{}),t}_accept(e,t=!0){const s=this.generation,i=this.marker;return this._enqueue(async()=>{if(s!==this.generation)throw this._cancelled();if(!(e?.accessToken&&e?.projectId&&e?.clientKey&&e?.user?.userId)){const e=new Error("Invalid authentication response");throw e.code="AUTH_UNAVAILABLE",e}const n=this.data&&(this.data.user.userId!==e.user.userId||this.data.projectId!==e.projectId);if(t&&e.refreshToken){const t=this._readMarker();if(t.revision!==i.revision||t.logout)throw this._cancelled();this._writeMarker({...t,refreshToken:e.refreshToken,refreshRequestId:void 0,pending:!1,pendingRefreshToken:void 0})}if(Number.isFinite(e.serverTime)&&(this.serverClock={server:e.serverTime+(e._roundTripMillis||0),mono:this._monotonic(),wall:Date.now()}),this.refreshMargin=Math.min(6e4,Math.max(0,1e3*Number(C(e.accessToken).exp)-this._serverNow())/10),this.data={...e,refreshToken:void 0},await Promise.all([...this.clients].map(t=>t._acceptAuthSession(e))),s!==this.generation)throw this._cancelled();return this._setState("authenticated",void 0,n),t&&this._publish("tokens",this._shareData(),this.marker),this._reconnectClients(),this.schedule(),e})}_reconnectClients(){for(const e of this.clients)if(e._authConnectionRequested&&e.isConnected?.()){const t=e.connectionManager;t?._authenticatedToken!==this.data?.accessToken&&t.forceReconnect("access-token-renewed").catch(e=>this.emit("authError",e))}}_clear(e=!0){const t=this.marker;return this._enqueue(async()=>{this.data=null,clearTimeout(this.timer),this.timer=null,this._setState("unauthenticated"),await Promise.all([...this.clients].map(e=>e._clearAuthSession())),e&&this._publish("logout",void 0,t)})}async _receive(e){if(e?.marker)try{const t=this._readMarker();if(e.marker.revision!==t.revision&&t.revision!==this.marker.revision)return;if("logout"===e.type||"login-start"===e.type){if(e.marker.revision!==t.revision)return;return this.marker=e.marker,this.generation++,await this._clear(!1),void("login-start"===e.type&&this._setState("checking"))}if(e.marker.revision!==this._readMarker().revision||e.marker.logout)return;if("request-token"===e.type&&this._fresh())this._publish("peer-token",{requestId:e.data.requestId,session:this._shareData()});else if("peer-token"===e.type)this.peerWaiters.get(e.data.requestId)?.(e.data.session);else if("tokens"===e.type){this.marker.revision!==e.marker.revision&&this.generation++,this.marker=e.marker;const t=C(e.data?.accessToken||""),s=C(this.data?.accessToken||"");if(t.sid===s.sid&&t.exp<s.exp)return;await this._accept(e.data,!1)}}catch(e){this.emit("authError",e)}}async _peerToken(e){if(!this.channel)return null;const t=`${Date.now()}-${Math.random()}`;return new Promise(s=>{const i=i=>{i&&(i.accessToken===e||1e3*Number(C(i.accessToken).exp)<=Number(i.serverTime)+6e4)||(clearTimeout(n),this.peerWaiters.delete(t),s(i))},n=setTimeout(()=>i(null),100);this.peerWaiters.set(t,i),this._publish("request-token",{requestId:t})})}_locked(e){const t="undefined"!=typeof navigator?navigator.locks:null,s=(this.httpQueue||Promise.resolve()).then(()=>t?.request?t.request(`talkflow:auth:${this.serverUrl}`,e):e());return this.httpQueue=s.catch(()=>{}),s}_newRefreshRequestId(){const e=new Uint8Array(32);if(!globalThis.crypto?.getRandomValues){const e=new Error("Secure randomness is unavailable");throw e.code="AUTH_RANDOM_UNAVAILABLE",e}return globalThis.crypto.getRandomValues(e),Array.from(e,e=>e.toString(16).padStart(2,"0")).join("")}async _request(e,t,s={}){const i=this._monotonic(),n=new AbortController,r=setTimeout(()=>n.abort(),15e3);try{const r=await fetch(`${this.serverUrl}${e}`,{method:"POST",credentials:"omit",signal:n.signal,headers:{"Content-Type":"application/json","X-TalkFlow-Session":"refresh",...s},body:void 0===t?void 0:JSON.stringify(t)}),o=r.headers.get("content-type")?.includes("application/json")?await r.json():await r.text();if(!r.ok){const e=new Error(o?.message||`HTTP ${r.status}`);throw e.status=r.status,e.code=o?.code,e.response=o,e}const a=void 0!==o?.data?o.data:o;return a&&"object"==typeof a?Object.defineProperty({...a},"_roundTripMillis",{value:this._monotonic()-i}):a}finally{clearTimeout(r)}}async login({email:e,password:t,projectId:s}){const i=++this.generation;return this._locked(async()=>{const n=this._readMarker();this._writeMarker(n),n.pendingRefreshToken&&await this._request("/v1/auth/signout",{refreshToken:n.pendingRefreshToken,deviceId:n.deviceId});const r=await this._request("/api/v1/auth/login",{email:e,password:t,previousRefreshToken:n.refreshToken,...s?{projectId:s}:{}});if(!0===r?.workspaceSelectionRequired){if(i!==this.generation)throw this._cancelled();return function(e){const t=Array.isArray(e.workspaces)?e.workspaces:[];if(0===t.length||t.some(e=>!e?.projectId)){const e=new Error("Invalid authentication response");throw e.code="AUTH_UNAVAILABLE",e}return{workspaceSelectionRequired:!0,workspaces:t.map(({projectId:e,companyName:t,companyRole:s})=>({projectId:e,companyName:t??null,companyRole:s}))}}(r)}if(!r?.refreshToken){const e=new Error("Server does not support the refresh session contract");throw e.code="AUTH_PROTOCOL_UNSUPPORTED",e}if(i!==this.generation||this._readMarker().revision!==n.revision)throw await this._request("/v1/auth/signout",{refreshToken:r.refreshToken}),this._cancelled();return this._newMarker(!1),this._accept(r)})}async restoreSession(){if(this._readMarker().logout)return this._readMarker().pending?await this.logout():await this._clear(!1),null;if(this._fresh())return this.data;if(!this._readMarker().refreshToken)return await this._clear(!1),null;this.data||this._setState("checking");try{return await this.getAccessToken(),this.data}catch(e){if(R(e))return null;throw e}}async getAccessToken({forceRefresh:e=!1,rejectedToken:t}={}){if(this._readMarker().logout)throw this._loggedOut();if(this._fresh()&&(!e||t&&t!==this.data.accessToken))return this.data.accessToken;if(this.refreshPromise)return this.refreshPromise;const s=this.generation,i=this._readMarker().revision,n=this._locked(async()=>{if(s!==this.generation||i!==this._readMarker().revision)throw this._cancelled();if(this._fresh()&&(!e||t&&t!==this.data.accessToken))return this.data.accessToken;if(this.marker=this._readMarker(),!this.marker.refreshToken)throw this._loggedOut();this._writeMarker(this.marker);const n=await this._peerToken(t);let r=n;if(!r){const e=this._readMarker();if(s!==this.generation||i!==e.revision||e.logout)throw this._cancelled();const t=e.refreshRequestId||this._newRefreshRequestId();this._writeMarker({...e,refreshRequestId:t}),r=await this._request("/api/v1/auth/refresh",{refreshToken:e.refreshToken,requestId:t})}if(s!==this.generation||i!==this._readMarker().revision)throw this._cancelled();return await this._accept(r,!n),r.accessToken}).catch(async e=>{throw s===this.generation&&i===this._readMarker().revision&&(R(e)?await this.authenticationFailed(e):this.data?this.emit("authError",e):this._setState("unavailable",e)),e}).finally(()=>{this.refreshPromise===n&&(this.refreshPromise=null)});return this.refreshPromise=n,n}async logout(){const e=this.data?.accessToken;this.generation++;const t=this._newMarker(!0),s=this._clear(),i=this._locked(async()=>{const s=await this._request("/v1/auth/signout",{refreshToken:t.pendingRefreshToken,deviceId:t.deviceId},e?{Authorization:"Bearer "+e.replace(/^Bearer\s+/i,"")}:{});return this._readMarker().revision===t.revision&&this._writeMarker({...t,pending:!1,pendingRefreshToken:void 0}),s});await Promise.all([s,i]),this._readMarker().revision===t.revision&&this._writeMarker({...t,pending:!1,pendingRefreshToken:void 0})}async changePassword(e){await this.getAccessToken();const t=++this.generation;return this._locked(async()=>{const s=await e();if(t!==this.generation)throw this._cancelled();const i=s?.data??s;return i?.reauthenticationRequired?(this._newMarker(!0,!1),await this._clear(),s):(this._newMarker(!1),await this._accept(i),s)}).catch(async e=>{throw t===this.generation&&await this.authenticationFailed(e),e})}_loggedOut(){const e=new Error("Sign in is required");return e.code="SESSION_REVOKED",e}async authenticationFailed(e,{rejectedToken:t,generation:s}={}){void 0!==s&&s!==this.generation||t&&this.data&&t!==this.data.accessToken||R(e)&&(this.generation++,this._newMarker(!0,!1),await this._clear())}replaceAccessToken(e){if(!this.data||this.data.accessToken===e)return;const t=C(e);t.sid===C(this.data.accessToken).sid&&t.sub===this.data.user.userId&&(this.data={...this.data,accessToken:e,expiresIn:t.exp},this._publish("tokens",this._shareData()),this._reconnectClients(),this.schedule())}_cancelled(){const e=new Error("Authentication operation was superseded");return e.code="AUTH_OPERATION_CANCELLED",e}schedule(e){if(clearTimeout(this.timer),this.timer=null,!this.data||![...this.clients].some(e=>e._authConnectionRequested))return;const t=e??Math.max(1e3,1e3*Number(C(this.data.accessToken).exp||0)-this._serverNow()-(this.refreshMargin??6e4));this.timer=setTimeout(async()=>{try{const e=this.data?.accessToken;await this.getAccessToken({forceRefresh:!0,rejectedToken:e}),this.data&&await Promise.all([...this.clients].filter(e=>e._authConnectionRequested&&!e.isConnected()).map(e=>e.connectionManager.forceReconnect("access-token-renewed"))),this.schedule()}catch(e){R(e)||this.schedule(3e4)}},t),this.timer.unref?.()}destroy(){this.generation++,clearTimeout(this.timer),this.channel?.close(),globalThis.removeEventListener?.("storage",this.storageListener),this.clients.clear(),this.removeAllListeners(),I.get(this.serverUrl)===this&&I.delete(this.serverUrl)}}function k(e){return e&&"string"==typeof e?e.replace(/^Bearer\s+/i,""):""}function M(e){let t=e.replace(/-/g,"+").replace(/_/g,"/");const s=t.length%4;s&&(t+="=".repeat(4-s));const i=atob(t),n=Uint8Array.from(i,e=>e.charCodeAt(0));return(new TextDecoder).decode(n)}function N(e,t={}){const{bufferSeconds:i=30,validateExpiry:n=!0,validateIssuedAt:r=!1}=t;if(!e||"string"!=typeof e){const e=new Error("JWT token is required");throw e.code=s.JWT_INVALID,e}const o=k(e).split(".");if(3!==o.length){const e=new Error("Invalid JWT format: expected 3 parts separated by dots");throw e.code=s.JWT_INVALID,e}let a;try{a=JSON.parse(M(o[1]))}catch(e){const t=new Error("Invalid JWT: failed to decode payload");throw t.code=s.JWT_PARSE_FAILED,t.originalError=e,t}if(n&&a.exp){const e=1e3*a.exp,t=1e3*i,n=Date.now();if(e<n+t){const t=new Error(e<n?"JWT token expired":`JWT token expires within ${i} seconds`);throw t.code=s.JWT_EXPIRED,t.expiredAt=new Date(e).toISOString(),t}}if(r&&a.iat){const e=6e4;if(1e3*a.iat>Date.now()+e){const e=new Error("JWT token issued in the future");throw e.code=s.JWT_INVALID,e}}const c=a.userId||a.sub||a.user_id;if(!c){const e=new Error("Cannot extract userId from JWT: missing userId, sub, or user_id claim");throw e.code=s.JWT_INVALID,e}return{userId:c,payload:a}}function O(e){try{const t=k(e).split(".");if(3!==t.length)return null;const s=JSON.parse(M(t[1]));return s.userId||s.sub||s.user_id||null}catch(e){return console.error("Failed to extract userId from JWT:",e),null}}function L(e,t=0){try{const s=k(e).split(".");if(3!==s.length)return!0;const i=JSON.parse(M(s[1]));if(!i.exp)return!1;const n=1e3*i.exp,r=1e3*t;return n<Date.now()+r}catch(e){return console.error("Failed to check JWT expiration:",e),!0}}function D(e){try{const t=k(e).split(".");if(3!==t.length)return-1;const s=JSON.parse(M(t[1]));return s.exp?1e3*s.exp-Date.now():1/0}catch(e){return console.error("Failed to get JWT remaining time:",e),-1}}function P(e){try{const t=k(e).split(".");return 3!==t.length?null:JSON.parse(M(t[1]))}catch(e){return console.error("Failed to decode JWT payload:",e),null}}const U="\n",x="\0";class j{get body(){return!this._body&&this.isBinaryBody&&(this._body=(new TextDecoder).decode(this._binaryBody)),this._body||""}get binaryBody(){return this._binaryBody||this.isBinaryBody||(this._binaryBody=(new TextEncoder).encode(this._body)),this._binaryBody}constructor(e){const{command:t,headers:s,body:i,binaryBody:n,escapeHeaderValues:r,skipContentLengthHeader:o}=e;this.command=t,this.headers=Object.assign({},s||{}),n?(this._binaryBody=n,this.isBinaryBody=!0):(this._body=i||"",this.isBinaryBody=!1),this.escapeHeaderValues=r||!1,this.skipContentLengthHeader=o||!1}static fromRawFrame(e,t){const s={},i=e=>e.replace(/^\s+|\s+$/g,"");for(const n of e.headers.reverse()){n.indexOf(":");const r=i(n[0]);let o=i(n[1]);t&&"CONNECT"!==e.command&&"CONNECTED"!==e.command&&(o=j.hdrValueUnEscape(o)),s[r]=o}return new j({command:e.command,headers:s,binaryBody:e.binaryBody,escapeHeaderValues:t})}toString(){return this.serializeCmdAndHeaders()}serialize(){const e=this.serializeCmdAndHeaders();return this.isBinaryBody?j.toUnit8Array(e,this._binaryBody).buffer:e+this._body+x}serializeCmdAndHeaders(){const e=[this.command];this.skipContentLengthHeader&&delete this.headers["content-length"];for(const t of Object.keys(this.headers||{})){const s=this.headers[t];this.escapeHeaderValues&&"CONNECT"!==this.command&&"CONNECTED"!==this.command?e.push(`${t}:${j.hdrValueEscape(`${s}`)}`):e.push(`${t}:${s}`)}return(this.isBinaryBody||!this.isBodyEmpty()&&!this.skipContentLengthHeader)&&e.push(`content-length:${this.bodyLength()}`),e.join(U)+U+U}isBodyEmpty(){return 0===this.bodyLength()}bodyLength(){const e=this.binaryBody;return e?e.length:0}static sizeOfUTF8(e){return e?(new TextEncoder).encode(e).length:0}static toUnit8Array(e,t){const s=(new TextEncoder).encode(e),i=new Uint8Array([0]),n=new Uint8Array(s.length+t.length+i.length);return n.set(s),n.set(t,s.length),n.set(i,s.length+t.length),n}static marshall(e){return new j(e).serialize()}static hdrValueEscape(e){return e.replace(/\\/g,"\\\\").replace(/\r/g,"\\r").replace(/\n/g,"\\n").replace(/:/g,"\\c")}static hdrValueUnEscape(e){return e.replace(/\\r/g,"\r").replace(/\\n/g,"\n").replace(/\\c/g,":").replace(/\\\\/g,"\\")}}class ${constructor(e,t){this.onFrame=e,this.onIncomingPing=t,this._encoder=new TextEncoder,this._decoder=new TextDecoder,this._token=[],this._initState()}parseChunk(e,t=!1){let s;if(s="string"==typeof e?this._encoder.encode(e):new Uint8Array(e),t&&0!==s[s.length-1]){const e=new Uint8Array(s.length+1);e.set(s,0),e[s.length]=0,s=e}for(let e=0;e<s.length;e++){const t=s[e];this._onByte(t)}}_collectFrame(e){0!==e&&13!==e&&(10!==e?(this._onByte=this._collectCommand,this._reinjectByte(e)):this.onIncomingPing())}_collectCommand(e){if(13!==e)return 10===e?(this._results.command=this._consumeTokenAsUTF8(),void(this._onByte=this._collectHeaders)):void this._consumeByte(e)}_collectHeaders(e){13!==e&&(10!==e?(this._onByte=this._collectHeaderKey,this._reinjectByte(e)):this._setupCollectBody())}_reinjectByte(e){this._onByte(e)}_collectHeaderKey(e){if(58===e)return this._headerKey=this._consumeTokenAsUTF8(),void(this._onByte=this._collectHeaderValue);this._consumeByte(e)}_collectHeaderValue(e){if(13!==e)return 10===e?(this._results.headers.push([this._headerKey,this._consumeTokenAsUTF8()]),this._headerKey=void 0,void(this._onByte=this._collectHeaders)):void this._consumeByte(e)}_setupCollectBody(){const e=this._results.headers.filter(e=>"content-length"===e[0])[0];e?(this._bodyBytesRemaining=parseInt(e[1],10),this._onByte=this._collectBodyFixedSize):this._onByte=this._collectBodyNullTerminated}_collectBodyNullTerminated(e){0!==e?this._consumeByte(e):this._retrievedBody()}_collectBodyFixedSize(e){0!==this._bodyBytesRemaining--?this._consumeByte(e):this._retrievedBody()}_retrievedBody(){this._results.binaryBody=this._consumeTokenAsRaw();try{this.onFrame(this._results)}catch(e){console.log("Ignoring an exception thrown by a frame handler. Original exception: ",e)}this._initState()}_consumeByte(e){this._token.push(e)}_consumeTokenAsUTF8(){return this._decoder.decode(this._consumeTokenAsRaw())}_consumeTokenAsRaw(){const e=new Uint8Array(this._token);return this._token=[],e}_initState(){this._results={command:void 0,headers:[],binaryBody:void 0},this._token=[],this._headerKey=void 0,this._onByte=this._collectFrame}}var F,W,G,V;!function(e){e[e.CONNECTING=0]="CONNECTING",e[e.OPEN=1]="OPEN",e[e.CLOSING=2]="CLOSING",e[e.CLOSED=3]="CLOSED"}(F||(F={})),function(e){e[e.ACTIVE=0]="ACTIVE",e[e.DEACTIVATING=1]="DEACTIVATING",e[e.INACTIVE=2]="INACTIVE"}(W||(W={})),function(e){e[e.LINEAR=0]="LINEAR",e[e.EXPONENTIAL=1]="EXPONENTIAL"}(G||(G={})),function(e){e.Interval="interval",e.Worker="worker"}(V||(V={}));class H{constructor(e,t=V.Interval,s){this._interval=e,this._strategy=t,this._debug=s,this._workerScript=`\n var startTime = Date.now();\n setInterval(function() {\n self.postMessage(Date.now() - startTime);\n }, ${this._interval});\n `}start(e){this.stop(),this.shouldUseWorker()?this.runWorker(e):this.runInterval(e)}stop(){this.disposeWorker(),this.disposeInterval()}shouldUseWorker(){return"undefined"!=typeof Worker&&this._strategy===V.Worker}runWorker(e){this._debug("Using runWorker for outgoing pings"),this._worker||(this._worker=new Worker(URL.createObjectURL(new Blob([this._workerScript],{type:"text/javascript"}))),this._worker.onmessage=t=>e(t.data))}runInterval(e){if(this._debug("Using runInterval for outgoing pings"),!this._timer){const t=Date.now();this._timer=setInterval(()=>{e(Date.now()-t)},this._interval)}}disposeWorker(){this._worker&&(this._worker.terminate(),delete this._worker,this._debug("Outgoing ping disposeWorker"))}disposeInterval(){this._timer&&(clearInterval(this._timer),delete this._timer,this._debug("Outgoing ping disposeInterval"))}}class B{constructor(e){this.versions=e}supportedVersions(){return this.versions.join(",")}protocolVersions(){return this.versions.map(e=>`v${e.replace(".","")}.stomp`)}}B.V1_0="1.0",B.V1_1="1.1",B.V1_2="1.2",B.default=new B([B.V1_2,B.V1_1,B.V1_0]);class q{get connectedVersion(){return this._connectedVersion}get connected(){return this._connected}constructor(e,t,s){this._client=e,this._webSocket=t,this._connected=!1,this._serverFrameHandlers={CONNECTED:e=>{this.debug(`connected to server ${e.headers.server}`),this._connected=!0,this._connectedVersion=e.headers.version,this._connectedVersion===B.V1_2&&(this._escapeHeaderValues=!0),this._setupHeartbeat(e.headers),this.onConnect(e)},MESSAGE:e=>{const t=e.headers.subscription,s=this._subscriptions[t]||this.onUnhandledMessage,i=e,n=this,r=this._connectedVersion===B.V1_2?i.headers.ack:i.headers["message-id"];i.ack=(e={})=>n.ack(r,t,e),i.nack=(e={})=>n.nack(r,t,e),s(i)},RECEIPT:e=>{const t=this._receiptWatchers[e.headers["receipt-id"]];t?(t(e),delete this._receiptWatchers[e.headers["receipt-id"]]):this.onUnhandledReceipt(e)},ERROR:e=>{this.onStompError(e)}},this._counter=0,this._subscriptions={},this._receiptWatchers={},this._partialData="",this._escapeHeaderValues=!1,this._lastServerActivityTS=Date.now(),this.debug=s.debug,this.stompVersions=s.stompVersions,this.connectHeaders=s.connectHeaders,this.disconnectHeaders=s.disconnectHeaders,this.heartbeatIncoming=s.heartbeatIncoming,this.heartbeatToleranceMultiplier=s.heartbeatGracePeriods,this.heartbeatOutgoing=s.heartbeatOutgoing,this.splitLargeFrames=s.splitLargeFrames,this.maxWebSocketChunkSize=s.maxWebSocketChunkSize,this.forceBinaryWSFrames=s.forceBinaryWSFrames,this.logRawCommunication=s.logRawCommunication,this.appendMissingNULLonIncoming=s.appendMissingNULLonIncoming,this.discardWebsocketOnCommFailure=s.discardWebsocketOnCommFailure,this.onConnect=s.onConnect,this.onDisconnect=s.onDisconnect,this.onStompError=s.onStompError,this.onWebSocketClose=s.onWebSocketClose,this.onWebSocketError=s.onWebSocketError,this.onUnhandledMessage=s.onUnhandledMessage,this.onUnhandledReceipt=s.onUnhandledReceipt,this.onUnhandledFrame=s.onUnhandledFrame,this.onHeartbeatReceived=s.onHeartbeatReceived,this.onHeartbeatLost=s.onHeartbeatLost}start(){const e=new $(e=>{const t=j.fromRawFrame(e,this._escapeHeaderValues);this.logRawCommunication||this.debug(`<<< ${t}`);(this._serverFrameHandlers[t.command]||this.onUnhandledFrame)(t)},()=>{this.debug("<<< PONG"),this.onHeartbeatReceived()});this._webSocket.onmessage=t=>{if(this.debug("Received data"),this._lastServerActivityTS=Date.now(),this.logRawCommunication){const e=t.data instanceof ArrayBuffer?(new TextDecoder).decode(t.data):t.data;this.debug(`<<< ${e}`)}e.parseChunk(t.data,this.appendMissingNULLonIncoming)},this._webSocket.onclose=e=>{this.debug(`Connection closed to ${this._webSocket.url}`),this._cleanUp(),this.onWebSocketClose(e)},this._webSocket.onerror=e=>{this.onWebSocketError(e)},this._webSocket.onopen=()=>{const e=Object.assign({},this.connectHeaders);this.debug("Web Socket Opened..."),e["accept-version"]=this.stompVersions.supportedVersions(),e["heart-beat"]=[this.heartbeatOutgoing,this.heartbeatIncoming].join(","),this._transmit({command:"CONNECT",headers:e})}}_setupHeartbeat(e){if(e.version!==B.V1_1&&e.version!==B.V1_2)return;if(!e["heart-beat"])return;const[t,s]=e["heart-beat"].split(",").map(e=>parseInt(e,10));if(0!==this.heartbeatOutgoing&&0!==s){const e=Math.max(this.heartbeatOutgoing,s);this.debug(`send PING every ${e}ms`),this._pinger=new H(e,this._client.heartbeatStrategy,this.debug),this._pinger.start(()=>{this._webSocket.readyState===F.OPEN&&(this._webSocket.send(U),this.debug(">>> PING"))})}if(0!==this.heartbeatIncoming&&0!==t){const e=Math.max(this.heartbeatIncoming,t);this.debug(`check PONG every ${e}ms`),this._ponger=setInterval(()=>{const t=Date.now()-this._lastServerActivityTS;t>e*this.heartbeatToleranceMultiplier&&(this.debug(`did not receive server activity for the last ${t}ms`),this.onHeartbeatLost(),this._closeOrDiscardWebsocket())},e)}}_closeOrDiscardWebsocket(){this.discardWebsocketOnCommFailure?(this.debug("Discarding websocket, the underlying socket may linger for a while"),this.discardWebsocket()):(this.debug("Issuing close on the websocket"),this._closeWebsocket())}forceDisconnect(){this._webSocket&&(this._webSocket.readyState!==F.CONNECTING&&this._webSocket.readyState!==F.OPEN||this._closeOrDiscardWebsocket())}_closeWebsocket(){this._webSocket.onmessage=()=>{},this._webSocket.close()}discardWebsocket(){var e,t;"function"!=typeof this._webSocket.terminate&&(e=this._webSocket,t=e=>this.debug(e),e.terminate=function(){const s=()=>{};this.onerror=s,this.onmessage=s,this.onopen=s;const i=new Date,n=Math.random().toString().substring(2,8),r=this.onclose;this.onclose=e=>{const s=(new Date).getTime()-i.getTime();t(`Discarded socket (#${n}) closed after ${s}ms, with code/reason: ${e.code}/${e.reason}`)},this.close(),r?.call(e,{code:4001,reason:`Quick discarding socket (#${n}) without waiting for the shutdown sequence.`,wasClean:!1})}),this._webSocket.terminate()}_transmit(e){const{command:t,headers:s,body:i,binaryBody:n,skipContentLengthHeader:r}=e,o=new j({command:t,headers:s,body:i,binaryBody:n,escapeHeaderValues:this._escapeHeaderValues,skipContentLengthHeader:r});let a=o.serialize();if(this.logRawCommunication?this.debug(`>>> ${a}`):this.debug(`>>> ${o}`),this.forceBinaryWSFrames&&"string"==typeof a&&(a=(new TextEncoder).encode(a)),"string"==typeof a&&this.splitLargeFrames){let e=a;for(;e.length>0;){const t=e.substring(0,this.maxWebSocketChunkSize);e=e.substring(this.maxWebSocketChunkSize),this._webSocket.send(t),this.debug(`chunk sent = ${t.length}, remaining = ${e.length}`)}}else this._webSocket.send(a)}dispose(){if(this.connected)try{const e=Object.assign({},this.disconnectHeaders);e.receipt||(e.receipt="close-"+this._counter++),this.watchForReceipt(e.receipt,e=>{this._closeWebsocket(),this._cleanUp(),this.onDisconnect(e)}),this._transmit({command:"DISCONNECT",headers:e})}catch(e){this.debug(`Ignoring error during disconnect ${e}`)}else this._webSocket.readyState!==F.CONNECTING&&this._webSocket.readyState!==F.OPEN||this._closeWebsocket()}_cleanUp(){this._connected=!1,this._pinger&&(this._pinger.stop(),this._pinger=void 0),this._ponger&&(clearInterval(this._ponger),this._ponger=void 0)}publish(e){const{destination:t,headers:s,body:i,binaryBody:n,skipContentLengthHeader:r}=e,o=Object.assign({destination:t},s);this._transmit({command:"SEND",headers:o,body:i,binaryBody:n,skipContentLengthHeader:r})}watchForReceipt(e,t){this._receiptWatchers[e]=t}subscribe(e,t,s={}){(s=Object.assign({},s)).id||(s.id="sub-"+this._counter++),s.destination=e,this._subscriptions[s.id]=t,this._transmit({command:"SUBSCRIBE",headers:s});const i=this;return{id:s.id,unsubscribe:e=>i.unsubscribe(s.id,e)}}unsubscribe(e,t={}){t=Object.assign({},t),delete this._subscriptions[e],t.id=e,this._transmit({command:"UNSUBSCRIBE",headers:t})}begin(e){const t=e||"tx-"+this._counter++;this._transmit({command:"BEGIN",headers:{transaction:t}});const s=this;return{id:t,commit(){s.commit(t)},abort(){s.abort(t)}}}commit(e){this._transmit({command:"COMMIT",headers:{transaction:e}})}abort(e){this._transmit({command:"ABORT",headers:{transaction:e}})}ack(e,t,s={}){s=Object.assign({},s),this._connectedVersion===B.V1_2?s.id=e:s["message-id"]=e,s.subscription=t,this._transmit({command:"ACK",headers:s})}nack(e,t,s={}){return s=Object.assign({},s),this._connectedVersion===B.V1_2?s.id=e:s["message-id"]=e,s.subscription=t,this._transmit({command:"NACK",headers:s})}}class J{get webSocket(){return this._stompHandler?._webSocket}get disconnectHeaders(){return this._disconnectHeaders}set disconnectHeaders(e){this._disconnectHeaders=e,this._stompHandler&&(this._stompHandler.disconnectHeaders=this._disconnectHeaders)}get connected(){return!!this._stompHandler&&this._stompHandler.connected}get connectedVersion(){return this._stompHandler?this._stompHandler.connectedVersion:void 0}get active(){return this.state===W.ACTIVE}_changeState(e){this.state=e,this.onChangeState(e)}constructor(e={}){this.stompVersions=B.default,this.connectionTimeout=0,this.reconnectDelay=5e3,this._nextReconnectDelay=0,this.maxReconnectDelay=9e5,this.reconnectTimeMode=G.LINEAR,this.heartbeatIncoming=1e4,this.heartbeatToleranceMultiplier=2,this.heartbeatOutgoing=1e4,this.heartbeatStrategy=V.Interval,this.splitLargeFrames=!1,this.maxWebSocketChunkSize=8192,this.forceBinaryWSFrames=!1,this.appendMissingNULLonIncoming=!1,this.discardWebsocketOnCommFailure=!1,this.state=W.INACTIVE;const t=()=>{};this.debug=t,this.beforeConnect=t,this.onConnect=t,this.onDisconnect=t,this.onUnhandledMessage=t,this.onUnhandledReceipt=t,this.onUnhandledFrame=t,this.onHeartbeatReceived=t,this.onHeartbeatLost=t,this.onStompError=t,this.onWebSocketClose=t,this.onWebSocketError=t,this.logRawCommunication=!1,this.onChangeState=t,this.connectHeaders={},this._disconnectHeaders={},this.configure(e)}configure(e){Object.assign(this,e),this.maxReconnectDelay>0&&this.maxReconnectDelay<this.reconnectDelay&&(this.debug(`Warning: maxReconnectDelay (${this.maxReconnectDelay}ms) is less than reconnectDelay (${this.reconnectDelay}ms). Using reconnectDelay as the maxReconnectDelay delay.`),this.maxReconnectDelay=this.reconnectDelay)}activate(){const e=()=>{this.active?this.debug("Already ACTIVE, ignoring request to activate"):(this._changeState(W.ACTIVE),this._nextReconnectDelay=this.reconnectDelay,this._connect())};this.state===W.DEACTIVATING?(this.debug("Waiting for deactivation to finish before activating"),this.deactivate().then(()=>{e()})):e()}async _connect(){if(await this.beforeConnect(this),this._stompHandler)return void this.debug("There is already a stompHandler, skipping the call to connect");if(!this.active)return void this.debug("Client has been marked inactive, will not attempt to connect");this.connectionTimeout>0&&(this._connectionWatcher&&clearTimeout(this._connectionWatcher),this._connectionWatcher=setTimeout(()=>{this.connected||(this.debug(`Connection not established in ${this.connectionTimeout}ms, closing socket`),this.forceDisconnect())},this.connectionTimeout)),this.debug("Opening Web Socket...");const e=this._createWebSocket();this._stompHandler=new q(this,e,{debug:this.debug,stompVersions:this.stompVersions,connectHeaders:this.connectHeaders,disconnectHeaders:this._disconnectHeaders,heartbeatIncoming:this.heartbeatIncoming,heartbeatGracePeriods:this.heartbeatToleranceMultiplier,heartbeatOutgoing:this.heartbeatOutgoing,heartbeatStrategy:this.heartbeatStrategy,splitLargeFrames:this.splitLargeFrames,maxWebSocketChunkSize:this.maxWebSocketChunkSize,forceBinaryWSFrames:this.forceBinaryWSFrames,logRawCommunication:this.logRawCommunication,appendMissingNULLonIncoming:this.appendMissingNULLonIncoming,discardWebsocketOnCommFailure:this.discardWebsocketOnCommFailure,onConnect:e=>{if(this._connectionWatcher&&(clearTimeout(this._connectionWatcher),this._connectionWatcher=void 0),this._nextReconnectDelay=this.reconnectDelay,!this.active)return this.debug("STOMP got connected while deactivate was issued, will disconnect now"),void this._disposeStompHandler();this.onConnect(e)},onDisconnect:e=>{this.onDisconnect(e)},onStompError:e=>{this.onStompError(e)},onWebSocketClose:e=>{this._stompHandler=void 0,this.state===W.DEACTIVATING&&this._changeState(W.INACTIVE),this.onWebSocketClose(e),this.active&&this._schedule_reconnect()},onWebSocketError:e=>{this.onWebSocketError(e)},onUnhandledMessage:e=>{this.onUnhandledMessage(e)},onUnhandledReceipt:e=>{this.onUnhandledReceipt(e)},onUnhandledFrame:e=>{this.onUnhandledFrame(e)},onHeartbeatReceived:()=>{this.onHeartbeatReceived()},onHeartbeatLost:()=>{this.onHeartbeatLost()}}),this._stompHandler.start()}_createWebSocket(){let e;if(this.webSocketFactory)e=this.webSocketFactory();else{if(!this.brokerURL)throw new Error("Either brokerURL or webSocketFactory must be provided");e=new WebSocket(this.brokerURL,this.stompVersions.protocolVersions())}return e.binaryType="arraybuffer",e}_schedule_reconnect(){this._nextReconnectDelay>0&&(this.debug(`STOMP: scheduling reconnection in ${this._nextReconnectDelay}ms`),this._reconnector=setTimeout(()=>{this.reconnectTimeMode===G.EXPONENTIAL&&(this._nextReconnectDelay=2*this._nextReconnectDelay,0!==this.maxReconnectDelay&&(this._nextReconnectDelay=Math.min(this._nextReconnectDelay,this.maxReconnectDelay))),this._connect()},this._nextReconnectDelay))}async deactivate(e={}){const t=e.force||!1,s=this.active;let i;if(this.state===W.INACTIVE)return this.debug("Already INACTIVE, nothing more to do"),Promise.resolve();if(this._changeState(W.DEACTIVATING),this._nextReconnectDelay=0,this._reconnector&&(clearTimeout(this._reconnector),this._reconnector=void 0),!this._stompHandler||this.webSocket.readyState===F.CLOSED)return this._changeState(W.INACTIVE),Promise.resolve();{const e=this._stompHandler.onWebSocketClose;i=new Promise((t,s)=>{this._stompHandler.onWebSocketClose=s=>{e(s),t()}})}return t?this._stompHandler?.discardWebsocket():s&&this._disposeStompHandler(),i}forceDisconnect(){this._stompHandler&&this._stompHandler.forceDisconnect()}_disposeStompHandler(){this._stompHandler&&this._stompHandler.dispose()}publish(e){this._checkConnection(),this._stompHandler.publish(e)}_checkConnection(){if(!this.connected)throw new TypeError("There is no underlying STOMP connection")}watchForReceipt(e,t){this._checkConnection(),this._stompHandler.watchForReceipt(e,t)}subscribe(e,t,s={}){return this._checkConnection(),this._stompHandler.subscribe(e,t,s)}unsubscribe(e,t={}){this._checkConnection(),this._stompHandler.unsubscribe(e,t)}begin(e){return this._checkConnection(),this._stompHandler.begin(e)}commit(e){this._checkConnection(),this._stompHandler.commit(e)}abort(e){this._checkConnection(),this._stompHandler.abort(e)}ack(e,t,s={}){this._checkConnection(),this._stompHandler.ack(e,t,s)}nack(e,t,s={}){this._checkConnection(),this._stompHandler.nack(e,t,s)}}var z="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};function K(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var X,Y,Q,Z,ee,te,se={exports:{}},ie={};function ne(){if(Q)return Y;Q=1;var e=(X||(X=1,z.crypto&&z.crypto.getRandomValues?ie.randomBytes=function(e){var t=new Uint8Array(e);return z.crypto.getRandomValues(t),t}:ie.randomBytes=function(e){for(var t=new Array(e),s=0;s<e;s++)t[s]=Math.floor(256*Math.random());return t}),ie),t="abcdefghijklmnopqrstuvwxyz012345";return Y={string:function(s){for(var i=e.randomBytes(s),n=[],r=0;r<s;r++)n.push(t.substr(i[r]%32,1));return n.join("")},number:function(e){return Math.floor(Math.random()*e)},numberString:function(e){var t=(""+(e-1)).length;return(new Array(t+1).join("0")+this.number(e)).slice(-t)}}}function re(){return Z||(Z=1,function(e){var t=ne(),s={},i=!1,n=z.chrome&&z.chrome.app&&z.chrome.app.runtime;e.exports={attachEvent:function(e,t){void 0!==z.addEventListener?z.addEventListener(e,t,!1):z.document&&z.attachEvent&&(z.document.attachEvent("on"+e,t),z.attachEvent("on"+e,t))},detachEvent:function(e,t){void 0!==z.addEventListener?z.removeEventListener(e,t,!1):z.document&&z.detachEvent&&(z.document.detachEvent("on"+e,t),z.detachEvent("on"+e,t))},unloadAdd:function(e){if(n)return null;var r=t.string(8);return s[r]=e,i&&setTimeout(this.triggerUnloadCallbacks,0),r},unloadDel:function(e){e in s&&delete s[e]},triggerUnloadCallbacks:function(){for(var e in s)s[e](),delete s[e]}};n||e.exports.attachEvent("unload",function(){i||(i=!0,e.exports.triggerUnloadCallbacks())})}(se)),se.exports}var oe,ae,ce,he,le,de={};function ue(){if(ce)return ae;ce=1;var e=te?ee:(te=1,ee=function(e,t){if(t=t.split(":")[0],!(e=+e))return!1;switch(t){case"http":case"ws":return 80!==e;case"https":case"wss":return 443!==e;case"ftp":return 21!==e;case"gopher":return 70!==e;case"file":return!1}return 0!==e}),t=function(){if(oe)return de;oe=1;var e=Object.prototype.hasOwnProperty;function t(e){try{return decodeURIComponent(e.replace(/\+/g," "))}catch(e){return null}}function s(e){try{return encodeURIComponent(e)}catch(e){return null}}return de.stringify=function(t,i){i=i||"";var n,r,o=[];for(r in"string"!=typeof i&&(i="?"),t)if(e.call(t,r)){if((n=t[r])||null!=n&&!isNaN(n)||(n=""),r=s(r),n=s(n),null===r||null===n)continue;o.push(r+"="+n)}return o.length?i+o.join("&"):""},de.parse=function(e){for(var s,i=/([^=?#&]+)=?([^&]*)/g,n={};s=i.exec(e);){var r=t(s[1]),o=t(s[2]);null===r||null===o||r in n||(n[r]=o)}return n},de}(),s=/^[\x00-\x20\u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]+/,i=/[\n\r\t]/g,n=/^[A-Za-z][A-Za-z0-9+-.]*:\/\//,r=/:\d+$/,o=/^([a-z][a-z0-9.+-]*:)?(\/\/)?([\\/]+)?([\S\s]*)/i,a=/^[a-zA-Z]:/;function c(e){return(e||"").toString().replace(s,"")}var h=[["#","hash"],["?","query"],function(e,t){return u(t.protocol)?e.replace(/\\/g,"/"):e},["/","pathname"],["@","auth",1],[NaN,"host",void 0,1,1],[/:(\d*)$/,"port",void 0,1],[NaN,"hostname",void 0,1,1]],l={hash:1,query:1};function d(e){var t,s=("undefined"!=typeof window?window:void 0!==z?z:"undefined"!=typeof self?self:{}).location||{},i={},r=typeof(e=e||s);if("blob:"===e.protocol)i=new g(unescape(e.pathname),{});else if("string"===r)for(t in i=new g(e,{}),l)delete i[t];else if("object"===r){for(t in e)t in l||(i[t]=e[t]);void 0===i.slashes&&(i.slashes=n.test(e.href))}return i}function u(e){return"file:"===e||"ftp:"===e||"http:"===e||"https:"===e||"ws:"===e||"wss:"===e}function p(e,t){e=(e=c(e)).replace(i,""),t=t||{};var s,n=o.exec(e),r=n[1]?n[1].toLowerCase():"",a=!!n[2],h=!!n[3],l=0;return a?h?(s=n[2]+n[3]+n[4],l=n[2].length+n[3].length):(s=n[2]+n[4],l=n[2].length):h?(s=n[3]+n[4],l=n[3].length):s=n[4],"file:"===r?l>=2&&(s=s.slice(2)):u(r)?s=n[4]:r?a&&(s=s.slice(2)):l>=2&&u(t.protocol)&&(s=n[4]),{protocol:r,slashes:a||u(r),slashesCount:l,rest:s}}function g(s,n,r){if(s=(s=c(s)).replace(i,""),!(this instanceof g))return new g(s,n,r);var o,l,m,_,f,y,b=h.slice(),v=typeof n,w=this,S=0;for("object"!==v&&"string"!==v&&(r=n,n=null),r&&"function"!=typeof r&&(r=t.parse),o=!(l=p(s||"",n=d(n))).protocol&&!l.slashes,w.slashes=l.slashes||o&&n.slashes,w.protocol=l.protocol||n.protocol||"",s=l.rest,("file:"===l.protocol&&(2!==l.slashesCount||a.test(s))||!l.slashes&&(l.protocol||l.slashesCount<2||!u(w.protocol)))&&(b[3]=[/(.*)/,"pathname"]);S<b.length;S++)"function"!=typeof(_=b[S])?(m=_[0],y=_[1],m!=m?w[y]=s:"string"==typeof m?~(f="@"===m?s.lastIndexOf(m):s.indexOf(m))&&("number"==typeof _[2]?(w[y]=s.slice(0,f),s=s.slice(f+_[2])):(w[y]=s.slice(f),s=s.slice(0,f))):(f=m.exec(s))&&(w[y]=f[1],s=s.slice(0,f.index)),w[y]=w[y]||o&&_[3]&&n[y]||"",_[4]&&(w[y]=w[y].toLowerCase())):s=_(s,w);r&&(w.query=r(w.query)),o&&n.slashes&&"/"!==w.pathname.charAt(0)&&(""!==w.pathname||""!==n.pathname)&&(w.pathname=function(e,t){if(""===e)return t;for(var s=(t||"/").split("/").slice(0,-1).concat(e.split("/")),i=s.length,n=s[i-1],r=!1,o=0;i--;)"."===s[i]?s.splice(i,1):".."===s[i]?(s.splice(i,1),o++):o&&(0===i&&(r=!0),s.splice(i,1),o--);return r&&s.unshift(""),"."!==n&&".."!==n||s.push(""),s.join("/")}(w.pathname,n.pathname)),"/"!==w.pathname.charAt(0)&&u(w.protocol)&&(w.pathname="/"+w.pathname),e(w.port,w.protocol)||(w.host=w.hostname,w.port=""),w.username=w.password="",w.auth&&(~(f=w.auth.indexOf(":"))?(w.username=w.auth.slice(0,f),w.username=encodeURIComponent(decodeURIComponent(w.username)),w.password=w.auth.slice(f+1),w.password=encodeURIComponent(decodeURIComponent(w.password))):w.username=encodeURIComponent(decodeURIComponent(w.auth)),w.auth=w.password?w.username+":"+w.password:w.username),w.origin="file:"!==w.protocol&&u(w.protocol)&&w.host?w.protocol+"//"+w.host:"null",w.href=w.toString()}return g.prototype={set:function(s,i,n){var o=this;switch(s){case"query":"string"==typeof i&&i.length&&(i=(n||t.parse)(i)),o[s]=i;break;case"port":o[s]=i,e(i,o.protocol)?i&&(o.host=o.hostname+":"+i):(o.host=o.hostname,o[s]="");break;case"hostname":o[s]=i,o.port&&(i+=":"+o.port),o.host=i;break;case"host":o[s]=i,r.test(i)?(i=i.split(":"),o.port=i.pop(),o.hostname=i.join(":")):(o.hostname=i,o.port="");break;case"protocol":o.protocol=i.toLowerCase(),o.slashes=!n;break;case"pathname":case"hash":if(i){var a="pathname"===s?"/":"#";o[s]=i.charAt(0)!==a?a+i:i}else o[s]=i;break;case"username":case"password":o[s]=encodeURIComponent(i);break;case"auth":var c=i.indexOf(":");~c?(o.username=i.slice(0,c),o.username=encodeURIComponent(decodeURIComponent(o.username)),o.password=i.slice(c+1),o.password=encodeURIComponent(decodeURIComponent(o.password))):o.username=encodeURIComponent(decodeURIComponent(i))}for(var l=0;l<h.length;l++){var d=h[l];d[4]&&(o[d[1]]=o[d[1]].toLowerCase())}return o.auth=o.password?o.username+":"+o.password:o.username,o.origin="file:"!==o.protocol&&u(o.protocol)&&o.host?o.protocol+"//"+o.host:"null",o.href=o.toString(),o},toString:function(e){e&&"function"==typeof e||(e=t.stringify);var s,i=this,n=i.host,o=i.protocol;o&&":"!==o.charAt(o.length-1)&&(o+=":");var a=o+(i.protocol&&i.slashes||u(i.protocol)?"//":"");return i.username?(a+=i.username,i.password&&(a+=":"+i.password),a+="@"):i.password?(a+=":"+i.password,a+="@"):"file:"!==i.protocol&&u(i.protocol)&&!n&&"/"!==i.pathname&&(a+="@"),(":"===n[n.length-1]||r.test(i.hostname)&&!i.port)&&(n+=":"),a+=n+i.pathname,(s="object"==typeof i.query?e(i.query):i.query)&&(a+="?"!==s.charAt(0)?"?"+s:s),i.hash&&(a+=i.hash),a}},g.extractProtocol=p,g.location=d,g.trimLeft=c,g.qs=t,ae=g}function pe(){if(le)return he;le=1;var e=ue();return he={getOrigin:function(t){if(!t)return null;var s=new e(t);if("file:"===s.protocol)return null;var i=s.port;return i||(i="https:"===s.protocol?"443":"80"),s.protocol+"//"+s.hostname+":"+i},isOriginEqual:function(e,t){return this.getOrigin(e)===this.getOrigin(t)},isSchemeEqual:function(e,t){return e.split(":")[0]===t.split(":")[0]},addPath:function(e,t){var s=e.split("?");return s[0]+t+(s[1]?"?"+s[1]:"")},addQuery:function(e,t){return e+(-1===e.indexOf("?")?"?"+t:"&"+t)},isLoopbackAddr:function(e){return/^127\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$/i.test(e)||/^\[::1\]$/.test(e)}}}var ge,me={exports:{}};function _e(){return ge||(ge=1,"function"==typeof Object.create?me.exports=function(e,t){t&&(e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}))}:me.exports=function(e,t){if(t){e.super_=t;var s=function(){};s.prototype=t.prototype,e.prototype=new s,e.prototype.constructor=e}}),me.exports}var fe,ye,be,ve={};function we(){if(ye)return fe;function e(){this._listeners={}}return ye=1,e.prototype.addEventListener=function(e,t){e in this._listeners||(this._listeners[e]=[]);var s=this._listeners[e];-1===s.indexOf(t)&&(s=s.concat([t])),this._listeners[e]=s},e.prototype.removeEventListener=function(e,t){var s=this._listeners[e];if(s){var i=s.indexOf(t);-1===i||(s.length>1?this._listeners[e]=s.slice(0,i).concat(s.slice(i+1)):delete this._listeners[e])}},e.prototype.dispatchEvent=function(){var e=arguments[0],t=e.type,s=1===arguments.length?[e]:Array.apply(null,arguments);if(this["on"+t]&&this["on"+t].apply(this,s),t in this._listeners)for(var i=this._listeners[t],n=0;n<i.length;n++)i[n].apply(this,s)},fe=e}function Se(){if(be)return ve;be=1;var e=_e(),t=we();function s(){t.call(this)}return e(s,t),s.prototype.removeAllListeners=function(e){e?delete this._listeners[e]:this._listeners={}},s.prototype.once=function(e,t){var s=this,i=!1;this.on(e,function n(){s.removeListener(e,n),i||(i=!0,t.apply(this,arguments))})},s.prototype.emit=function(){var e=arguments[0],t=this._listeners[e];if(t){for(var s=arguments.length,i=new Array(s-1),n=1;n<s;n++)i[n-1]=arguments[n];for(var r=0;r<t.length;r++)t[r].apply(this,i)}},s.prototype.on=s.prototype.addListener=t.prototype.addEventListener,s.prototype.removeListener=t.prototype.removeEventListener,ve.EventEmitter=s,ve}var Ee,Ie,Te,Re,Ce,Ae,ke,Me,Ne,Oe,Le,De,Pe,Ue,xe,je,$e,Fe,We,Ge,Ve,He,Be,qe,Je,ze,Ke,Xe,Ye,Qe,Ze,et,tt,st,it,nt={exports:{}};function rt(){if(Te)return Ie;Te=1;var e=re(),t=pe(),s=_e(),i=Se().EventEmitter,n=function(){if(Ee)return nt.exports;Ee=1;var e=z.WebSocket||z.MozWebSocket;return nt.exports=e?function(t){return new e(t)}:void 0,nt.exports}();function r(s,o,a){if(!r.enabled())throw new Error("Transport created when disabled");i.call(this);var c=this,h=t.addPath(s,"/websocket");h="https"===h.slice(0,5)?"wss"+h.slice(5):"ws"+h.slice(4),this.url=h,this.ws=new n(this.url,[],a),this.ws.onmessage=function(e){e.data,c.emit("message",e.data)},this.unloadRef=e.unloadAdd(function(){c.ws.close()}),this.ws.onclose=function(e){e.code,e.reason,c.emit("close",e.code,e.reason),c._cleanup()},this.ws.onerror=function(e){c.emit("close",1006,"WebSocket connection broken"),c._cleanup()}}return s(r,i),r.prototype.send=function(e){var t="["+e+"]";this.ws.send(t)},r.prototype.close=function(){var e=this.ws;this._cleanup(),e&&e.close()},r.prototype._cleanup=function(){var t=this.ws;t&&(t.onmessage=t.onclose=t.onerror=null),e.unloadDel(this.unloadRef),this.unloadRef=this.ws=null,this.removeAllListeners()},r.enabled=function(){return!!n},r.transportName="websocket",r.roundTrips=2,Ie=r}function ot(){if(Ne)return Me;Ne=1;var e=_e(),t=pe(),s=function(){if(Ce)return Re;Ce=1;var e=_e(),t=Se().EventEmitter;function s(e,s){t.call(this),this.sendBuffer=[],this.sender=s,this.url=e}return e(s,t),s.prototype.send=function(e){this.sendBuffer.push(e),this.sendStop||this.sendSchedule()},s.prototype.sendScheduleWait=function(){var e,t=this;this.sendStop=function(){t.sendStop=null,clearTimeout(e)},e=setTimeout(function(){t.sendStop=null,t.sendSchedule()},25)},s.prototype.sendSchedule=function(){this.sendBuffer.length;var e=this;if(this.sendBuffer.length>0){var t="["+this.sendBuffer.join(",")+"]";this.sendStop=this.sender(this.url,t,function(t){e.sendStop=null,t?(e.emit("close",t.code||1006,"Sending error: "+t),e.close()):e.sendScheduleWait()}),this.sendBuffer=[]}},s.prototype._cleanup=function(){this.removeAllListeners()},s.prototype.close=function(){this._cleanup(),this.sendStop&&(this.sendStop(),this.sendStop=null)},Re=s}(),i=function(){if(ke)return Ae;ke=1;var e=_e(),t=Se().EventEmitter;function s(e,s,i){t.call(this),this.Receiver=e,this.receiveUrl=s,this.AjaxObject=i,this._scheduleReceiver()}return e(s,t),s.prototype._scheduleReceiver=function(){var e=this,t=this.poll=new this.Receiver(this.receiveUrl,this.AjaxObject);t.on("message",function(t){e.emit("message",t)}),t.once("close",function(s,i){e.pollIsClosing,e.poll=t=null,e.pollIsClosing||("network"===i?e._scheduleReceiver():(e.emit("close",s||1006,i),e.removeAllListeners()))})},s.prototype.abort=function(){this.removeAllListeners(),this.pollIsClosing=!0,this.poll&&this.poll.abort()},Ae=s}();function n(e,n,r,o,a){var c=t.addPath(e,n),h=this;s.call(this,e,r),this.poll=new i(o,c,a),this.poll.on("message",function(e){h.emit("message",e)}),this.poll.once("close",function(e,t){h.poll=null,h.emit("close",e,t),h.close()})}return e(n,s),n.prototype.close=function(){s.prototype.close.call(this),this.removeAllListeners(),this.poll&&(this.poll.abort(),this.poll=null)},Me=n}function at(){if(Le)return Oe;Le=1;var e=_e(),t=pe(),s=ot();function i(e,i,n,r){s.call(this,e,i,function(e){return function(s,i,n){var r={};"string"==typeof i&&(r.headers={"Content-type":"text/plain"});var o=t.addPath(s,"/xhr_send"),a=new e("POST",o,i,r);return a.once("finish",function(e){if(a=null,200!==e&&204!==e)return n(new Error("http status "+e));n()}),function(){a.close(),a=null;var e=new Error("Aborted");e.code=1e3,n(e)}}}(r),n,r)}return e(i,s),Oe=i}function ct(){if(Pe)return De;Pe=1;var e=_e(),t=Se().EventEmitter;function s(e,s){t.call(this);var i=this;this.bufferPosition=0,this.xo=new s("POST",e,null),this.xo.on("chunk",this._chunkHandler.bind(this)),this.xo.once("finish",function(e,t){i._chunkHandler(e,t),i.xo=null;var s=200===e?"network":"permanent";i.emit("close",null,s),i._cleanup()})}return e(s,t),s.prototype._chunkHandler=function(e,t){if(200===e&&t)for(var s=-1;;this.bufferPosition+=s+1){var i=t.slice(this.bufferPosition);if(-1===(s=i.indexOf("\n")))break;var n=i.slice(0,s);n&&this.emit("message",n)}},s.prototype._cleanup=function(){this.removeAllListeners()},s.prototype.abort=function(){this.xo&&(this.xo.close(),this.emit("close",null,"user"),this.xo=null),this._cleanup()},De=s}function ht(){if(xe)return Ue;xe=1;var e=Se().EventEmitter,t=_e(),s=re(),i=pe(),n=z.XMLHttpRequest;function r(t,s,i,n){var r=this;e.call(this),setTimeout(function(){r._start(t,s,i,n)},0)}t(r,e),r.prototype._start=function(e,t,o,a){var c=this;try{this.xhr=new n}catch(e){}if(!this.xhr)return this.emit("finish",0,"no xhr support"),void this._cleanup();t=i.addQuery(t,"t="+ +new Date),this.unloadRef=s.unloadAdd(function(){c._cleanup(!0)});try{this.xhr.open(e,t,!0),this.timeout&&"timeout"in this.xhr&&(this.xhr.timeout=this.timeout,this.xhr.ontimeout=function(){c.emit("finish",0,""),c._cleanup(!1)})}catch(e){return this.emit("finish",0,""),void this._cleanup(!1)}if(a&&a.noCredentials||!r.supportsCORS||(this.xhr.withCredentials=!0),a&&a.headers)for(var h in a.headers)this.xhr.setRequestHeader(h,a.headers[h]);this.xhr.onreadystatechange=function(){if(c.xhr){var e,t,s=c.xhr;switch(s.readyState,s.readyState){case 3:try{t=s.status,e=s.responseText}catch(e){}1223===t&&(t=204),200===t&&e&&e.length>0&&c.emit("chunk",t,e);break;case 4:1223===(t=s.status)&&(t=204),12005!==t&&12029!==t||(t=0),s.responseText,c.emit("finish",t,s.responseText),c._cleanup(!1)}}};try{c.xhr.send(o)}catch(e){c.emit("finish",0,""),c._cleanup(!1)}},r.prototype._cleanup=function(e){if(this.xhr){if(this.removeAllListeners(),s.unloadDel(this.unloadRef),this.xhr.onreadystatechange=function(){},this.xhr.ontimeout&&(this.xhr.ontimeout=null),e)try{this.xhr.abort()}catch(e){}this.unloadRef=this.xhr=null}},r.prototype.close=function(){this._cleanup(!0)},r.enabled=!!n;var o=["Active"].concat("Object").join("X");!r.enabled&&o in z&&(n=function(){try{return new z[o]("Microsoft.XMLHTTP")}catch(e){return null}},r.enabled=!!new n);var a=!1;try{a="withCredentials"in new n}catch(e){}return r.supportsCORS=a,Ue=r}function lt(){if($e)return je;$e=1;var e=_e(),t=ht();function s(e,s,i,n){t.call(this,e,s,i,n)}return e(s,t),s.enabled=t.enabled&&t.supportsCORS,je=s}function dt(){if(We)return Fe;We=1;var e=_e(),t=ht();function s(e,s,i){t.call(this,e,s,i,{noCredentials:!0})}return e(s,t),s.enabled=t.enabled,Fe=s}function ut(){return Ve?Ge:(Ve=1,Ge={isOpera:function(){return z.navigator&&/opera/i.test(z.navigator.userAgent)},isKonqueror:function(){return z.navigator&&/konqueror/i.test(z.navigator.userAgent)},hasDomain:function(){if(!z.document)return!0;try{return!!z.document.domain}catch(e){return!1}}})}function pt(){if(Be)return He;Be=1;var e=_e(),t=at(),s=ct(),i=lt(),n=dt(),r=ut();function o(e){if(!n.enabled&&!i.enabled)throw new Error("Transport created when disabled");t.call(this,e,"/xhr_streaming",s,i)}return e(o,t),o.enabled=function(e){return!e.nullOrigin&&(!r.isOpera()&&i.enabled)},o.transportName="xhr-streaming",o.roundTrips=2,o.needBody=!!z.document,He=o}function gt(){if(Je)return qe;Je=1;var e=Se().EventEmitter,t=_e(),s=re(),i=ut(),n=pe();function r(t,s,i){var n=this;e.call(this),setTimeout(function(){n._start(t,s,i)},0)}return t(r,e),r.prototype._start=function(e,t,i){var r=this,o=new z.XDomainRequest;t=n.addQuery(t,"t="+ +new Date),o.onerror=function(){r._error()},o.ontimeout=function(){r._error()},o.onprogress=function(){o.responseText,r.emit("chunk",200,o.responseText)},o.onload=function(){r.emit("finish",200,o.responseText),r._cleanup(!1)},this.xdr=o,this.unloadRef=s.unloadAdd(function(){r._cleanup(!0)});try{this.xdr.open(e,t),this.timeout&&(this.xdr.timeout=this.timeout),this.xdr.send(i)}catch(e){this._error()}},r.prototype._error=function(){this.emit("finish",0,""),this._cleanup(!1)},r.prototype._cleanup=function(e){if(this.xdr){if(this.removeAllListeners(),s.unloadDel(this.unloadRef),this.xdr.ontimeout=this.xdr.onerror=this.xdr.onprogress=this.xdr.onload=null,e)try{this.xdr.abort()}catch(e){}this.unloadRef=this.xdr=null}},r.prototype.close=function(){this._cleanup(!0)},r.enabled=!(!z.XDomainRequest||!i.hasDomain()),qe=r}function mt(){if(Ke)return ze;Ke=1;var e=_e(),t=at(),s=ct(),i=gt();function n(e){if(!i.enabled)throw new Error("Transport created when disabled");t.call(this,e,"/xhr_streaming",s,i)}return e(n,t),n.enabled=function(e){return!e.cookie_needed&&!e.nullOrigin&&(i.enabled&&e.sameScheme)},n.transportName="xdr-streaming",n.roundTrips=2,ze=n}function _t(){return Ye?Xe:(Ye=1,Xe=z.EventSource)}function ft(){if(tt)return et;tt=1;var e=_e(),t=at(),s=function(){if(Ze)return Qe;Ze=1;var e=_e(),t=Se().EventEmitter,s=_t();function i(e){t.call(this);var i=this,n=this.es=new s(e);n.onmessage=function(e){e.data,i.emit("message",decodeURI(e.data))},n.onerror=function(e){n.readyState;var t=2!==n.readyState?"network":"permanent";i._cleanup(),i._close(t)}}return e(i,t),i.prototype.abort=function(){this._cleanup(),this._close("user")},i.prototype._cleanup=function(){var e=this.es;e&&(e.onmessage=e.onerror=null,e.close(),this.es=null)},i.prototype._close=function(e){var t=this;setTimeout(function(){t.emit("close",null,e),t.removeAllListeners()},200)},Qe=i}(),i=lt(),n=_t();function r(e){if(!r.enabled())throw new Error("Transport created when disabled");t.call(this,e,"/eventsource",s,i)}return e(r,t),r.enabled=function(){return!!n},r.transportName="eventsource",r.roundTrips=2,et=r}function yt(){return it?st:(it=1,st="1.6.1")}var bt,vt,wt,St,Et,It,Tt,Rt,Ct,At,kt,Mt,Nt,Ot,Lt,Dt,Pt,Ut,xt,jt,$t,Ft,Wt,Gt={exports:{}};function Vt(){return bt||(bt=1,function(e){var t=re(),s=ut();e.exports={WPrefix:"_jp",currentWindowId:null,polluteGlobalNamespace:function(){e.exports.WPrefix in z||(z[e.exports.WPrefix]={})},postMessage:function(t,s){z.parent!==z&&z.parent.postMessage(JSON.stringify({windowId:e.exports.currentWindowId,type:t,data:s||""}),"*")},createIframe:function(e,s){var i,n,r=z.document.createElement("iframe"),o=function(){clearTimeout(i);try{r.onload=null}catch(e){}r.onerror=null},a=function(){r&&(o(),setTimeout(function(){r&&r.parentNode.removeChild(r),r=null},0),t.unloadDel(n))},c=function(e){r&&(a(),s(e))};return r.src=e,r.style.display="none",r.style.position="absolute",r.onerror=function(){c("onerror")},r.onload=function(){clearTimeout(i),i=setTimeout(function(){c("onload timeout")},2e3)},z.document.body.appendChild(r),i=setTimeout(function(){c("timeout")},15e3),n=t.unloadAdd(a),{post:function(e,t){setTimeout(function(){try{r&&r.contentWindow&&r.contentWindow.postMessage(e,t)}catch(e){}},0)},cleanup:a,loaded:o}},createHtmlfile:function(s,i){var n,r,o,a=["Active"].concat("Object").join("X"),c=new z[a]("htmlfile"),h=function(){clearTimeout(n),o.onerror=null},l=function(){c&&(h(),t.unloadDel(r),o.parentNode.removeChild(o),o=c=null,CollectGarbage())},d=function(e){c&&(l(),i(e))};c.open(),c.write('<html><script>document.domain="'+z.document.domain+'";<\/script></html>'),c.close(),c.parentWindow[e.exports.WPrefix]=z[e.exports.WPrefix];var u=c.createElement("div");return c.body.appendChild(u),o=c.createElement("iframe"),u.appendChild(o),o.src=s,o.onerror=function(){d("onerror")},n=setTimeout(function(){d("timeout")},15e3),r=t.unloadAdd(l),{post:function(e,t){try{setTimeout(function(){o&&o.contentWindow&&o.contentWindow.postMessage(e,t)},0)}catch(e){}},cleanup:l,loaded:h}}},e.exports.iframeEnabled=!1,z.document&&(e.exports.iframeEnabled=("function"==typeof z.postMessage||"object"==typeof z.postMessage)&&!s.isKonqueror())}(Gt)),Gt.exports}function Ht(){if(wt)return vt;wt=1;var e=_e(),t=Se().EventEmitter,s=yt(),i=pe(),n=Vt(),r=re(),o=ne();function a(e,s,c){if(!a.enabled())throw new Error("Transport created when disabled");t.call(this);var h=this;this.origin=i.getOrigin(c),this.baseUrl=c,this.transUrl=s,this.transport=e,this.windowId=o.string(8);var l=i.addPath(c,"/iframe.html")+"#"+this.windowId;this.iframeObj=n.createIframe(l,function(e){h.emit("close",1006,"Unable to load an iframe ("+e+")"),h.close()}),this.onmessageCallback=this._message.bind(this),r.attachEvent("message",this.onmessageCallback)}return e(a,t),a.prototype.close=function(){if(this.removeAllListeners(),this.iframeObj){r.detachEvent("message",this.onmessageCallback);try{this.postMessage("c")}catch(e){}this.iframeObj.cleanup(),this.iframeObj=null,this.onmessageCallback=this.iframeObj=null}},a.prototype._message=function(e){if(e.data,!i.isOriginEqual(e.origin,this.origin))return e.origin,void this.origin;var t;try{t=JSON.parse(e.data)}catch(t){return void e.data}if(t.windowId!==this.windowId)return t.windowId,void this.windowId;switch(t.type){case"s":this.iframeObj.loaded(),this.postMessage("s",JSON.stringify([s,this.transport,this.transUrl,this.baseUrl]));break;case"t":this.emit("message",t.data);break;case"c":var n;try{n=JSON.parse(t.data)}catch(e){return void t.data}this.emit("close",n[0],n[1]),this.close()}},a.prototype.postMessage=function(e,t){this.iframeObj.post(JSON.stringify({windowId:this.windowId,type:e,data:t||""}),this.origin)},a.prototype.send=function(e){this.postMessage("m",e)},a.enabled=function(){return n.iframeEnabled},a.transportName="iframe",a.roundTrips=2,vt=a}function Bt(){return Et||(Et=1,St={isObject:function(e){var t=typeof e;return"function"===t||"object"===t&&!!e},extend:function(e){if(!this.isObject(e))return e;for(var t,s,i=1,n=arguments.length;i<n;i++)for(s in t=arguments[i])Object.prototype.hasOwnProperty.call(t,s)&&(e[s]=t[s]);return e}}),St}function qt(){if(Tt)return It;Tt=1;var e=_e(),t=Ht(),s=Bt();return It=function(i){function n(e,s){t.call(this,i.transportName,e,s)}return e(n,t),n.enabled=function(e,n){if(!z.document)return!1;var r=s.extend({},n);return r.sameOrigin=!0,i.enabled(r)&&t.enabled()},n.transportName="iframe-"+i.transportName,n.needBody=!0,n.roundTrips=t.roundTrips+i.roundTrips-1,n.facadeTransport=i,n},It}function Jt(){if(kt)return At;kt=1;var e=_e(),t=function(){if(Ct)return Rt;Ct=1;var e=_e(),t=Vt(),s=pe(),i=Se().EventEmitter,n=ne();function r(e){i.call(this);var o=this;t.polluteGlobalNamespace(),this.id="a"+n.string(6),e=s.addQuery(e,"c="+decodeURIComponent(t.WPrefix+"."+this.id)),r.htmlfileEnabled;var a=r.htmlfileEnabled?t.createHtmlfile:t.createIframe;z[t.WPrefix][this.id]={start:function(){o.iframeObj.loaded()},message:function(e){o.emit("message",e)},stop:function(){o._cleanup(),o._close("network")}},this.iframeObj=a(e,function(){o._cleanup(),o._close("permanent")})}e(r,i),r.prototype.abort=function(){this._cleanup(),this._close("user")},r.prototype._cleanup=function(){this.iframeObj&&(this.iframeObj.cleanup(),this.iframeObj=null),delete z[t.WPrefix][this.id]},r.prototype._close=function(e){this.emit("close",null,e),this.removeAllListeners()},r.htmlfileEnabled=!1;var o=["Active"].concat("Object").join("X");if(o in z)try{r.htmlfileEnabled=!!new z[o]("htmlfile")}catch(e){}return r.enabled=r.htmlfileEnabled||t.iframeEnabled,Rt=r}(),s=dt(),i=at();function n(e){if(!t.enabled)throw new Error("Transport created when disabled");i.call(this,e,"/htmlfile",t,s)}return e(n,i),n.enabled=function(e){return t.enabled&&e.sameOrigin},n.transportName="htmlfile",n.roundTrips=2,At=n}function zt(){if(Nt)return Mt;Nt=1;var e=_e(),t=at(),s=ct(),i=lt(),n=dt();function r(e){if(!n.enabled&&!i.enabled)throw new Error("Transport created when disabled");t.call(this,e,"/xhr",s,i)}return e(r,t),r.enabled=function(e){return!e.nullOrigin&&(!(!n.enabled||!e.sameOrigin)||i.enabled)},r.transportName="xhr-polling",r.roundTrips=2,Mt=r}function Kt(){if(Lt)return Ot;Lt=1;var e=_e(),t=at(),s=mt(),i=ct(),n=gt();function r(e){if(!n.enabled)throw new Error("Transport created when disabled");t.call(this,e,"/xhr",i,n)}return e(r,t),r.enabled=s.enabled,r.transportName="xdr-polling",r.roundTrips=2,Ot=r}function Xt(){if(xt)return Ut;xt=1;var e,t,s=ne(),i=pe();return Ut=function(n,r,o){e||((e=z.document.createElement("form")).style.display="none",e.style.position="absolute",e.method="POST",e.enctype="application/x-www-form-urlencoded",e.acceptCharset="UTF-8",(t=z.document.createElement("textarea")).name="d",e.appendChild(t),z.document.body.appendChild(e));var a="a"+s.string(8);e.target=a,e.action=i.addQuery(i.addPath(n,"/jsonp_send"),"i="+a);var c=function(e){try{return z.document.createElement('<iframe name="'+e+'">')}catch(s){var t=z.document.createElement("iframe");return t.name=e,t}}(a);c.id=a,c.style.display="none",e.appendChild(c);try{t.value=r}catch(e){}e.submit();var h=function(e){c.onerror&&(c.onreadystatechange=c.onerror=c.onload=null,setTimeout(function(){c.parentNode.removeChild(c),c=null},500),t.value="",o(e))};return c.onerror=function(){h()},c.onload=function(){h()},c.onreadystatechange=function(e){c.readyState,"complete"===c.readyState&&h()},function(){h(new Error("Aborted"))}},Ut}function Yt(){if($t)return jt;$t=1;var e=_e(),t=ot(),s=function(){if(Pt)return Dt;Pt=1;var e=Vt(),t=ne(),s=ut(),i=pe(),n=_e(),r=Se().EventEmitter;function o(s){var n=this;r.call(this),e.polluteGlobalNamespace(),this.id="a"+t.string(6);var a=i.addQuery(s,"c="+encodeURIComponent(e.WPrefix+"."+this.id));z[e.WPrefix][this.id]=this._callback.bind(this),this._createScript(a),this.timeoutId=setTimeout(function(){n._abort(new Error("JSONP script loaded abnormally (timeout)"))},o.timeout)}return n(o,r),o.prototype.abort=function(){if(z[e.WPrefix][this.id]){var t=new Error("JSONP user aborted read");t.code=1e3,this._abort(t)}},o.timeout=35e3,o.scriptErrorTimeout=1e3,o.prototype._callback=function(e){this._cleanup(),this.aborting||(e&&this.emit("message",e),this.emit("close",null,"network"),this.removeAllListeners())},o.prototype._abort=function(e){this._cleanup(),this.aborting=!0,this.emit("close",e.code,e.message),this.removeAllListeners()},o.prototype._cleanup=function(){if(clearTimeout(this.timeoutId),this.script2&&(this.script2.parentNode.removeChild(this.script2),this.script2=null),this.script){var t=this.script;t.parentNode.removeChild(t),t.onreadystatechange=t.onerror=t.onload=t.onclick=null,this.script=null}delete z[e.WPrefix][this.id]},o.prototype._scriptError=function(){var e=this;this.errorTimer||(this.errorTimer=setTimeout(function(){e.loadedOkay||e._abort(new Error("JSONP script loaded abnormally (onerror)"))},o.scriptErrorTimeout))},o.prototype._createScript=function(e){var i,n=this,r=this.script=z.document.createElement("script");if(r.id="a"+t.string(8),r.src=e,r.type="text/javascript",r.charset="UTF-8",r.onerror=this._scriptError.bind(this),r.onload=function(){n._abort(new Error("JSONP script loaded abnormally (onload)"))},r.onreadystatechange=function(){if(r.readyState,/loaded|closed/.test(r.readyState)){if(r&&r.htmlFor&&r.onclick){n.loadedOkay=!0;try{r.onclick()}catch(e){}}r&&n._abort(new Error("JSONP script loaded abnormally (onreadystatechange)"))}},void 0===r.async&&z.document.attachEvent)if(s.isOpera())(i=this.script2=z.document.createElement("script")).text="try{var a = document.getElementById('"+r.id+"'); if(a)a.onerror();}catch(x){};",r.async=i.async=!1;else{try{r.htmlFor=r.id,r.event="onclick"}catch(e){}r.async=!0}void 0!==r.async&&(r.async=!0);var o=z.document.getElementsByTagName("head")[0];o.insertBefore(r,o.firstChild),i&&o.insertBefore(i,o.firstChild)},Dt=o}(),i=Xt();function n(e){if(!n.enabled())throw new Error("Transport created when disabled");t.call(this,e,"/jsonp",i,s)}return e(n,t),n.enabled=function(){return!!z.document},n.transportName="jsonp-polling",n.roundTrips=1,n.needBody=!0,jt=n}function Qt(){return Wt?Ft:(Wt=1,Ft=[rt(),pt(),mt(),ft(),qt()(ft()),Jt(),qt()(Jt()),zt(),Kt(),qt()(zt()),Yt()])}var Zt,es,ts,ss,is,ns,rs,os,as,cs,hs,ls,ds,us,ps,gs,ms,_s,fs,ys,bs,vs,ws,Ss,Es,Is,Ts,Rs,Cs,As,ks,Ms,Ns,Os={};function Ls(){if(Zt)return Os;Zt=1;var e,t=Array.prototype,s=Object.prototype,i=Function.prototype,n=String.prototype,r=t.slice,o=s.toString,a=function(e){return"[object Function]"===s.toString.call(e)},c=function(e){return"[object String]"===o.call(e)},h=Object.defineProperty&&function(){try{return Object.defineProperty({},"x",{}),!0}catch(e){return!1}}();e=h?function(e,t,s,i){!i&&t in e||Object.defineProperty(e,t,{configurable:!0,enumerable:!1,writable:!0,value:s})}:function(e,t,s,i){!i&&t in e||(e[t]=s)};var l=function(t,i,n){for(var r in i)s.hasOwnProperty.call(i,r)&&e(t,r,i[r],n)},d=function(e){if(null==e)throw new TypeError("can't convert "+e+" to object");return Object(e)};function u(){}l(i,{bind:function(e){var t=this;if(!a(t))throw new TypeError("Function.prototype.bind called on incompatible "+t);for(var s=r.call(arguments,1),i=Math.max(0,t.length-s.length),n=[],o=0;o<i;o++)n.push("$"+o);var c=Function("binder","return function ("+n.join(",")+"){ return binder.apply(this, arguments); }")(function(){if(this instanceof c){var i=t.apply(this,s.concat(r.call(arguments)));return Object(i)===i?i:this}return t.apply(e,s.concat(r.call(arguments)))});return t.prototype&&(u.prototype=t.prototype,c.prototype=new u,u.prototype=null),c}}),l(Array,{isArray:function(e){return"[object Array]"===o.call(e)}});var p,g,m,_=Object("a"),f="a"!==_[0]||!(0 in _);l(t,{forEach:function(e){var t=d(this),s=f&&c(this)?this.split(""):t,i=arguments[1],n=-1,r=s.length>>>0;if(!a(e))throw new TypeError;for(;++n<r;)n in s&&e.call(i,s[n],n,t)}},(p=t.forEach,g=!0,m=!0,p&&(p.call("foo",function(e,t,s){"object"!=typeof s&&(g=!1)}),p.call([1],function(){m="string"==typeof this},"x")),!(p&&g&&m)));var y=Array.prototype.indexOf&&-1!==[0,1].indexOf(1,2);l(t,{indexOf:function(e){var t=f&&c(this)?this.split(""):d(this),s=t.length>>>0;if(!s)return-1;var i,n=0;for(arguments.length>1&&((i=+arguments[1])!=i?i=0:0!==i&&i!==1/0&&i!==-1/0&&(i=(i>0||-1)*Math.floor(Math.abs(i))),n=i),n=n>=0?n:Math.max(0,s+n);n<s;n++)if(n in t&&t[n]===e)return n;return-1}},y);var b,v=n.split;2!=="ab".split(/(?:ab)*/).length||4!==".".split(/(.?)(.?)/).length||"t"==="tesst".split(/(s)*/)[1]||4!=="test".split(/(?:)/,-1).length||"".split(/.?/).length||".".split(/()()/).length>1?(b=void 0===/()??/.exec("")[1],n.split=function(e,s){var i=this;if(void 0===e&&0===s)return[];if("[object RegExp]"!==o.call(e))return v.call(this,e,s);var n,r,a,c,h=[],l=(e.ignoreCase?"i":"")+(e.multiline?"m":"")+(e.extended?"x":"")+(e.sticky?"y":""),d=0;for(e=new RegExp(e.source,l+"g"),i+="",b||(n=new RegExp("^"+e.source+"$(?!\\s)",l)),s=void 0===s?-1>>>0:s>>>0;(r=e.exec(i))&&!((a=r.index+r[0].length)>d&&(h.push(i.slice(d,r.index)),!b&&r.length>1&&r[0].replace(n,function(){for(var e=1;e<arguments.length-2;e++)void 0===arguments[e]&&(r[e]=void 0)}),r.length>1&&r.index<i.length&&t.push.apply(h,r.slice(1)),c=r[0].length,d=a,h.length>=s));)e.lastIndex===r.index&&e.lastIndex++;return d===i.length?!c&&e.test("")||h.push(""):h.push(i.slice(d)),h.length>s?h.slice(0,s):h}):"0".split(void 0,0).length&&(n.split=function(e,t){return void 0===e&&0===t?[]:v.call(this,e,t)});var w=n.substr,S="".substr&&"b"!=="0b".substr(-1);return l(n,{substr:function(e,t){return w.call(this,e<0&&(e=this.length+e)<0?0:e,t)}},S),Os}function Ds(){if(ts)return es;ts=1;var e,t=/[\x00-\x1f\ud800-\udfff\ufffe\uffff\u0300-\u0333\u033d-\u0346\u034a-\u034c\u0350-\u0352\u0357-\u0358\u035c-\u0362\u0374\u037e\u0387\u0591-\u05af\u05c4\u0610-\u0617\u0653-\u0654\u0657-\u065b\u065d-\u065e\u06df-\u06e2\u06eb-\u06ec\u0730\u0732-\u0733\u0735-\u0736\u073a\u073d\u073f-\u0741\u0743\u0745\u0747\u07eb-\u07f1\u0951\u0958-\u095f\u09dc-\u09dd\u09df\u0a33\u0a36\u0a59-\u0a5b\u0a5e\u0b5c-\u0b5d\u0e38-\u0e39\u0f43\u0f4d\u0f52\u0f57\u0f5c\u0f69\u0f72-\u0f76\u0f78\u0f80-\u0f83\u0f93\u0f9d\u0fa2\u0fa7\u0fac\u0fb9\u1939-\u193a\u1a17\u1b6b\u1cda-\u1cdb\u1dc0-\u1dcf\u1dfc\u1dfe\u1f71\u1f73\u1f75\u1f77\u1f79\u1f7b\u1f7d\u1fbb\u1fbe\u1fc9\u1fcb\u1fd3\u1fdb\u1fe3\u1feb\u1fee-\u1fef\u1ff9\u1ffb\u1ffd\u2000-\u2001\u20d0-\u20d1\u20d4-\u20d7\u20e7-\u20e9\u2126\u212a-\u212b\u2329-\u232a\u2adc\u302b-\u302c\uaab2-\uaab3\uf900-\ufa0d\ufa10\ufa12\ufa15-\ufa1e\ufa20\ufa22\ufa25-\ufa26\ufa2a-\ufa2d\ufa30-\ufa6d\ufa70-\ufad9\ufb1d\ufb1f\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40-\ufb41\ufb43-\ufb44\ufb46-\ufb4e\ufff0-\uffff]/g;return es={quote:function(s){var i=JSON.stringify(s);return t.lastIndex=0,t.test(i)?(e||(e=function(e){var t,s={},i=[];for(t=0;t<65536;t++)i.push(String.fromCharCode(t));return e.lastIndex=0,i.join("").replace(e,function(e){return s[e]="\\u"+("0000"+e.charCodeAt(0).toString(16)).slice(-4),""}),e.lastIndex=0,s}(t)),i.replace(t,function(t){return e[t]})):i}}}function Ps(){if(is)return ss;is=1;return ss=function(e){return{filterToEnabled:function(t,s){var i={main:[],facade:[]};return t?"string"==typeof t&&(t=[t]):t=[],e.forEach(function(e){e&&("websocket"===e.transportName&&!1===s.websocket||(t.length&&-1===t.indexOf(e.transportName)?e.transportName:e.enabled(s)?(e.transportName,i.main.push(e),e.facadeTransport&&i.facade.push(e.facadeTransport)):e.transportName))}),i}}}}function Us(){if(rs)return ns;rs=1;var e={};return["log","debug","warn"].forEach(function(t){var s;try{s=z.console&&z.console[t]&&z.console[t].apply}catch(e){}e[t]=s?function(){return z.console[t].apply(z.console,arguments)}:"log"===t?function(){}:e.log}),ns=e}function xs(){if(as)return os;function e(e){this.type=e}return as=1,e.prototype.initEvent=function(e,t,s){return this.type=e,this.bubbles=t,this.cancelable=s,this.timeStamp=+new Date,this},e.prototype.stopPropagation=function(){},e.prototype.preventDefault=function(){},e.CAPTURING_PHASE=1,e.AT_TARGET=2,e.BUBBLING_PHASE=3,os=e}function js(){return hs?cs:(hs=1,cs=z.location||{origin:"http://localhost:80",protocol:"http:",host:"localhost",port:80,href:"http://localhost/",hash:""})}function $s(){if(fs)return _s;fs=1;var e=Se().EventEmitter,t=_e(),s=Bt();function i(t,i){e.call(this);var n=this,r=+new Date;this.xo=new i("GET",t),this.xo.once("finish",function(e,t){var i,o;if(200===e){if(o=+new Date-r,t)try{i=JSON.parse(t)}catch(e){}s.isObject(i)||(i={})}n.emit("finish",i,o),n.removeAllListeners()})}return t(i,e),i.prototype.close=function(){this.removeAllListeners(),this.xo.close()},_s=i}function Fs(){if(bs)return ys;bs=1;var e=_e(),t=Se().EventEmitter,s=dt(),i=$s();function n(e){var n=this;t.call(this),this.ir=new i(e,s),this.ir.once("finish",function(e,t){n.ir=null,n.emit("message",JSON.stringify([e,t]))})}return e(n,t),n.transportName="iframe-info-receiver",n.prototype.close=function(){this.ir&&(this.ir.close(),this.ir=null),this.removeAllListeners()},ys=n}function Ws(){if(Es)return Ss;Es=1;var e=Se().EventEmitter,t=_e(),s=pe(),i=gt(),n=lt(),r=dt(),o=function(){if(ms)return gs;ms=1;var e=Se().EventEmitter;function t(){var s=this;e.call(this),this.to=setTimeout(function(){s.emit("finish",200,"{}")},t.timeout)}return _e()(t,e),t.prototype.close=function(){clearTimeout(this.to)},t.timeout=2e3,gs=t}(),a=function(){if(ws)return vs;ws=1;var e=Se().EventEmitter,t=_e(),s=re(),i=Ht(),n=Fs();function r(t,r){var o=this;e.call(this);var a=function(){var e=o.ifr=new i(n.transportName,r,t);e.once("message",function(e){if(e){var t;try{t=JSON.parse(e)}catch(e){return o.emit("finish"),void o.close()}var s=t[0],i=t[1];o.emit("finish",s,i)}o.close()}),e.once("close",function(){o.emit("finish"),o.close()})};z.document.body?a():s.attachEvent("load",a)}return t(r,e),r.enabled=function(){return i.enabled()},r.prototype.close=function(){this.ifr&&this.ifr.close(),this.removeAllListeners(),this.ifr=null},vs=r}(),c=$s();function h(t,s){var i=this;e.call(this),setTimeout(function(){i.doXhr(t,s)},0)}return t(h,e),h._getReceiver=function(e,t,s){return s.sameOrigin?new c(t,r):n.enabled?new c(t,n):i.enabled&&s.sameScheme?new c(t,i):a.enabled()?new a(e,t):new c(t,o)},h.prototype.doXhr=function(e,t){var i=this,n=s.addPath(e,"/info");this.xo=h._getReceiver(e,n,t),this.timeoutRef=setTimeout(function(){i._cleanup(!1),i.emit("finish")},h.timeout),this.xo.once("finish",function(e,t){i._cleanup(!0),i.emit("finish",e,t)})},h.prototype._cleanup=function(e){clearTimeout(this.timeoutRef),this.timeoutRef=null,!e&&this.xo&&this.xo.close(),this.xo=null},h.prototype.close=function(){this.removeAllListeners(),this._cleanup(!1)},h.timeout=8e3,Ss=h}function Gs(){if(Cs)return Rs;Cs=1;var e=pe(),t=re(),s=function(){if(Ts)return Is;Ts=1;var e=Vt();function t(e){this._transport=e,e.on("message",this._transportMessage.bind(this)),e.on("close",this._transportClose.bind(this))}return t.prototype._transportClose=function(t,s){e.postMessage("c",JSON.stringify([t,s]))},t.prototype._transportMessage=function(t){e.postMessage("t",t)},t.prototype._send=function(e){this._transport.send(e)},t.prototype._close=function(){this._transport.close(),this._transport.removeAllListeners()},Is=t}(),i=Fs(),n=Vt(),r=js();return Rs=function(o,a){var c,h={};a.forEach(function(e){e.facadeTransport&&(h[e.facadeTransport.transportName]=e.facadeTransport)}),h[i.transportName]=i,o.bootstrap_iframe=function(){var i;n.currentWindowId=r.hash.slice(1);t.attachEvent("message",function(t){if(t.source===parent&&(void 0===c&&(c=t.origin),t.origin===c)){var a;try{a=JSON.parse(t.data)}catch(e){return void t.data}if(a.windowId===n.currentWindowId)switch(a.type){case"s":var l;try{l=JSON.parse(a.data)}catch(e){a.data;break}var d=l[0],u=l[1],p=l[2],g=l[3];if(d!==o.version)throw new Error('Incompatible SockJS! Main site uses: "'+d+'", the iframe: "'+o.version+'".');if(!e.isOriginEqual(p,r.href)||!e.isOriginEqual(g,r.href))throw new Error("Can't connect to different domain from within an iframe. ("+r.href+", "+p+", "+g+")");i=new s(new h[u](p,g));break;case"m":i._send(a.data);break;case"c":i&&i._close(),i=null}}}),n.postMessage("s")}},Rs}function Vs(){if(ks)return As;ks=1,Ls();var e,t=ue(),s=_e(),i=ne(),n=Ds(),r=pe(),o=re(),a=Ps(),c=Bt(),h=ut(),l=Us(),d=xs(),u=we(),p=js(),g=function(){if(ds)return ls;ds=1;var e=_e(),t=xs();function s(){t.call(this),this.initEvent("close",!1,!1),this.wasClean=!1,this.code=0,this.reason=""}return e(s,t),ls=s}(),m=function(){if(ps)return us;ps=1;var e=_e(),t=xs();function s(e){t.call(this),this.initEvent("message",!1,!1),this.data=e}return e(s,t),us=s}(),_=Ws(),f=function(){};function y(e,s,n){if(!(this instanceof y))return new y(e,s,n);if(arguments.length<1)throw new TypeError("Failed to construct 'SockJS: 1 argument required, but only 0 present");u.call(this),this.readyState=y.CONNECTING,this.extensions="",this.protocol="",(n=n||{}).protocols_whitelist&&l.warn("'protocols_whitelist' is DEPRECATED. Use 'transports' instead."),this._transportsWhitelist=n.transports,this._transportOptions=n.transportOptions||{},this._timeout=n.timeout||0;var o=n.sessionId||8;if("function"==typeof o)this._generateSessionId=o;else{if("number"!=typeof o)throw new TypeError("If sessionId is used in the options, it needs to be a number or a function.");this._generateSessionId=function(){return i.string(o)}}this._server=n.server||i.numberString(1e3);var a=new t(e);if(!a.host||!a.protocol)throw new SyntaxError("The URL '"+e+"' is invalid");if(a.hash)throw new SyntaxError("The URL must not contain a fragment");if("http:"!==a.protocol&&"https:"!==a.protocol)throw new SyntaxError("The URL's scheme must be either 'http:' or 'https:'. '"+a.protocol+"' is not allowed.");var c="https:"===a.protocol;if("https:"===p.protocol&&!c&&!r.isLoopbackAddr(a.hostname))throw new Error("SecurityError: An insecure SockJS connection may not be initiated from a page loaded over HTTPS");s?Array.isArray(s)||(s=[s]):s=[];var d=s.sort();d.forEach(function(e,t){if(!e)throw new SyntaxError("The protocols entry '"+e+"' is invalid.");if(t<d.length-1&&e===d[t+1])throw new SyntaxError("The protocols entry '"+e+"' is duplicated.")});var g=r.getOrigin(p.href);this._origin=g?g.toLowerCase():null,a.set("pathname",a.pathname.replace(/\/+$/,"")),this.url=a.href,this.url,this._urlInfo={nullOrigin:!h.hasDomain(),sameOrigin:r.isOriginEqual(this.url,p.href),sameScheme:r.isSchemeEqual(this.url,p.href)},this._ir=new _(this.url,this._urlInfo),this._ir.once("finish",this._receiveInfo.bind(this))}function b(e){return 1e3===e||e>=3e3&&e<=4999}return s(y,u),y.prototype.close=function(e,t){if(e&&!b(e))throw new Error("InvalidAccessError: Invalid code");if(t&&t.length>123)throw new SyntaxError("reason argument has an invalid length");if(this.readyState!==y.CLOSING&&this.readyState!==y.CLOSED){this._close(e||1e3,t||"Normal closure",!0)}},y.prototype.send=function(e){if("string"!=typeof e&&(e=""+e),this.readyState===y.CONNECTING)throw new Error("InvalidStateError: The connection has not been established yet");this.readyState===y.OPEN&&this._transport.send(n.quote(e))},y.version=yt(),y.CONNECTING=0,y.OPEN=1,y.CLOSING=2,y.CLOSED=3,y.prototype._receiveInfo=function(t,s){if(this._ir=null,t){this._rto=this.countRTO(s),this._transUrl=t.base_url?t.base_url:this.url,t=c.extend(t,this._urlInfo);var i=e.filterToEnabled(this._transportsWhitelist,t);this._transports=i.main,this._transports.length,this._connect()}else this._close(1002,"Cannot connect to server")},y.prototype._connect=function(){for(var e=this._transports.shift();e;e=this._transports.shift()){if(f(e.transportName),e.needBody&&(!z.document.body||void 0!==z.document.readyState&&"complete"!==z.document.readyState&&"interactive"!==z.document.readyState))return this._transports.unshift(e),void o.attachEvent("load",this._connect.bind(this));var t=Math.max(this._timeout,this._rto*e.roundTrips||5e3);this._transportTimeoutId=setTimeout(this._transportTimeout.bind(this),t);var s=r.addPath(this._transUrl,"/"+this._server+"/"+this._generateSessionId()),i=this._transportOptions[e.transportName],n=new e(s,this._transUrl,i);return n.on("message",this._transportMessage.bind(this)),n.once("close",this._transportClose.bind(this)),n.transportName=e.transportName,void(this._transport=n)}this._close(2e3,"All transports failed",!1)},y.prototype._transportTimeout=function(){this.readyState===y.CONNECTING&&(this._transport&&this._transport.close(),this._transportClose(2007,"Transport timed out"))},y.prototype._transportMessage=function(e){var t,s=this,i=e.slice(0,1),n=e.slice(1);switch(i){case"o":return void this._open();case"h":return this.dispatchEvent(new d("heartbeat")),void this.transport}if(n)try{t=JSON.parse(n)}catch(e){}if(void 0!==t)switch(i){case"a":Array.isArray(t)&&t.forEach(function(e){s.transport,s.dispatchEvent(new m(e))});break;case"m":this.transport,this.dispatchEvent(new m(t));break;case"c":Array.isArray(t)&&2===t.length&&this._close(t[0],t[1],!0)}},y.prototype._transportClose=function(e,t){this.transport,this._transport&&(this._transport.removeAllListeners(),this._transport=null,this.transport=null),b(e)||2e3===e||this.readyState!==y.CONNECTING?this._close(e,t):this._connect()},y.prototype._open=function(){this._transport&&this._transport.transportName,this.readyState,this.readyState===y.CONNECTING?(this._transportTimeoutId&&(clearTimeout(this._transportTimeoutId),this._transportTimeoutId=null),this.readyState=y.OPEN,this.transport=this._transport.transportName,this.dispatchEvent(new d("open")),this.transport):this._close(1006,"Server lost session")},y.prototype._close=function(e,t,s){this.transport,this.readyState;var i=!1;if(this._ir&&(i=!0,this._ir.close(),this._ir=null),this._transport&&(this._transport.close(),this._transport=null,this.transport=null),this.readyState===y.CLOSED)throw new Error("InvalidStateError: SockJS has already been closed");this.readyState=y.CLOSING,setTimeout(function(){this.readyState=y.CLOSED,i&&this.dispatchEvent(new d("error"));var n=new g("close");n.wasClean=s||!1,n.code=e||1e3,n.reason=t,this.dispatchEvent(n),this.onmessage=this.onclose=this.onerror=null}.bind(this),0)},y.prototype.countRTO=function(e){return e>100?4*e:300+e},As=function(t){return e=a(t),Gs()(y,t),y}}var Hs=function(){if(Ns)return Ms;Ns=1;var e=Qt();return Ms=Vs()(e),"_sockjs_onload"in z&&setTimeout(z._sockjs_onload,1),Ms}(),Bs=K(Hs);const qs="NOT_SUBSCRIBED",Js=()=>"undefined"!=typeof window&&window.StompJs&&window.StompJs.Client?window.StompJs.Client:J,zs=()=>"undefined"!=typeof window&&window.SockJS?window.SockJS:Bs;class Ks extends e{constructor(e){super(),this.serverUrl=e.serverUrl.replace(/\/$/,""),this.jwtToken=e.jwtToken,this.apiKey=e.apiKey,this.projectId=e.projectId,this.useSockJS=!1!==e.useSockJS,this.reconnectDelay=e.reconnectDelay||b.reconnectDelay,this.maxReconnectDelay=e.maxReconnectDelay||b.maxReconnectDelay,this.maxReconnectAttempts=e.maxReconnectAttempts||b.maxReconnectAttempts,this.reconnectRecoveryDelay=e.reconnectRecoveryDelay??b.reconnectRecoveryDelay,this.heartbeatIncoming=e.heartbeatIncoming||b.heartbeatIncoming,this.heartbeatOutgoing=e.heartbeatOutgoing||b.heartbeatOutgoing,this.resumeOnVisibility=!1!==e.resumeOnVisibility,this.logger=new S(e.logLevel||w.WARN,"ConnectionManager"),this.state=t.DISCONNECTED,this.stompClient=null,this.reconnectAttempts=0,this.subscriptions=new Map,this.pendingSubscriptions=[],this.userId=null,this._intentionalDisconnect=!1,this._tearingDown=!1,this._connectRequested=!1,this._forceReconnectPromise=null,this._lifecycleHandlers=null,this._recoveryTimer=null,this._terminalAuthError=!1,this._recoveryEligible=!1,this._subscriptionRequired=!1,this._installLifecycleListeners()}_installLifecycleListeners(){if("undefined"==typeof window||"function"!=typeof window.addEventListener)return;const e=()=>{"undefined"!=typeof document&&"visible"===document.visibilityState&&this._onResume("visibilitychange")},t=()=>this._onResume("pageshow"),s=()=>this._onResume("online");"undefined"!=typeof document&&"function"==typeof document.addEventListener&&document.addEventListener("visibilitychange",e),window.addEventListener("pageshow",t),window.addEventListener("online",s),this._lifecycleHandlers={onVisibilityChange:e,onPageShow:t,onOnline:s}}_removeLifecycleListeners(){if(!this._lifecycleHandlers)return;const{onVisibilityChange:e,onPageShow:t,onOnline:s}=this._lifecycleHandlers;"undefined"!=typeof document&&"function"==typeof document.removeEventListener&&document.removeEventListener("visibilitychange",e),"undefined"!=typeof window&&"function"==typeof window.removeEventListener&&(window.removeEventListener("pageshow",t),window.removeEventListener("online",s)),this._lifecycleHandlers=null}_onResume(e){if(this.resumeOnVisibility&&!this._intentionalDisconnect&&!this._terminalAuthError&&!this._subscriptionRequired)if(this._connectRequested){if(this.state!==t.CONNECTING&&!this._forceReconnectPromise){if(this.state===t.CONNECTED)return this._isSocketAlive()?(this.logger.debug(`Resume (${e}): connection alive`),void this.emit("resumed",{reason:e})):(this.logger.warn(`Resume (${e}): zombie socket detected, forcing reconnect`),void this.forceReconnect(`zombie-socket:${e}`));this.logger.info(`Resume (${e}): reviving connection from state=${this.state}`),this.forceReconnect(e)}}else this.logger.debug(`Resume (${e}) ignored — connect() has not been called yet`)}_isSocketAlive(){const e=this.stompClient&&this.stompClient.webSocket;return!!e&&e.readyState===F.OPEN}async forceReconnect(e){if(!this._intentionalDisconnect&&!this._terminalAuthError&&this.state!==t.CONNECTING){this._forceReconnectPromise||(this._forceReconnectPromise=this._doForceReconnect(e).finally(()=>{this._forceReconnectPromise=null})),await this._forceReconnectPromise;try{await this._connectPromise}catch{}}}async _doForceReconnect(e){if(this._cancelReconnectRecovery(),this.logger.info(`Force reconnect: ${e}`),this.stompClient){this._tearingDown=!0;try{await this.stompClient.deactivate()}catch(e){this.logger.warn("Error deactivating stomp client on force reconnect:",e)}finally{this._tearingDown=!1}this.stompClient=null}if(!(this._intentionalDisconnect||this._terminalAuthError||this._subscriptionRequired)){this._setState(t.DISCONNECTED),this.reconnectAttempts=0;try{this.connect().catch(t=>this.logger.warn(`Force reconnect failed (${e}):`,t))}catch(t){this.logger.warn(`Force reconnect failed (${e}):`,t)}}}_setState(e){const t=this.state;this.state=e,this.emit("stateChange",{state:e,prevState:t}),this.logger.info(`State changed: ${t} -> ${e}`)}_getWebSocketUrl(){const e=this.useSockJS?_.SOCKJS_ENDPOINT:_.NATIVE_ENDPOINT;return`${this.serverUrl}${e}`}_createStompClient(){const e=this._getWebSocketUrl();let t=null;const i=()=>!this.stompClient||this.stompClient===t,n={beforeConnect:async e=>{if(!this.getAccessToken)return void(this._connectionToken=this.jwtToken);let t=0;for(;!this._intentionalDisconnect&&(!e||e.active);)try{const t=await this.getAccessToken({forceRefresh:!0===this._authRejected});if(this._intentionalDisconnect||e&&!e.active)return;return!this._authRejected||t&&t.replace(/^Bearer\s+/i,"")!==this._rejectedToken?(this.updateToken(t),this._connectionToken=t,void(this._authRejected=!1)):void this._stopForAuthError(new Error("Authentication rejected without a new access token"),e)}catch(i){if(this.emit("error",{type:s.CONNECTION_FAILED,message:i.message,error:i}),R(i))return void this._stopForAuthError(i,e);const n=Math.min(3e4,1e3*2**Math.min(t++,5))*(.8+.4*Math.random());await new Promise(e=>{this._cancelAuthRetry=()=>{clearTimeout(this._authRetryTimer),e()},this._authRetryTimer=setTimeout(e,n),this._authRetryTimer.unref?.()}),this._cancelAuthRetry=null}},connectHeaders:{Authorization:this.jwtToken.startsWith("Bearer ")?this.jwtToken:`Bearer ${this.jwtToken}`,"X-API-KEY":this.apiKey,"X-PROJECT-ID":this.projectId},heartbeatIncoming:this.heartbeatIncoming,heartbeatOutgoing:this.heartbeatOutgoing,reconnectDelay:this.reconnectDelay*(.8+.4*Math.random()),reconnectTimeMode:G.EXPONENTIAL,maxReconnectDelay:this.maxReconnectDelay,debug:e=>{this.logger.level<=w.DEBUG&&this.logger.debug("STOMP:",e)},onConnect:e=>{i()&&this._onConnect(e)},onDisconnect:e=>{i()&&this._onDisconnect(e)},onStompError:e=>{i()&&this._onStompError(e)},onWebSocketClose:e=>{i()&&this._onWebSocketClose(e)},onWebSocketError:e=>{i()&&this._onWebSocketError(e)}};if(this.useSockJS){const t=zs();n.webSocketFactory=()=>new t(e)}else{const e=this.serverUrl.startsWith("https")?"wss":"ws",t=this.serverUrl.replace(/^https?:\/\//,"");n.brokerURL=`${e}://${t}${_.NATIVE_ENDPOINT}`}const r=Js();return t=new r(n),t}async connect(){if(this.state===t.CONNECTED)return void this.logger.warn("Already connected");this._connectPromise||(this._connectPromise=new Promise((e,t)=>{const s=()=>{this._connectPromise=null,this._connectResolve=this._connectReject=null};this._connectResolve=()=>{s(),e()},this._connectReject=e=>{s(),t(e)}}));const e=this._connectPromise;if(this.stompClient&&(this.state===t.CONNECTING||this.state===t.RECONNECTING))return e;this._cancelReconnectRecovery(),this._terminalAuthError=!1,this._subscriptionRequired=!1,this._setState(t.CONNECTING),this.reconnectAttempts=0,this._intentionalDisconnect=!1,this._connectRequested=!0;try{this.stompClient=this._createStompClient(),this.stompClient.activate()}catch(e){this._setState(t.ERROR),this._drainPendingSubscriptions("Connection activation failed"),this._connectReject?.(e)}return e}_onConnect(e){this._authenticatedToken=this.jwtToken;const s=this.reconnectAttempts,i=s>0||!0===this._hasConnectedBefore;this._setState(t.CONNECTED),this.reconnectAttempts=0,this._hasConnectedBefore=!0,this._recoveryEligible=!0,this._authRejected=!1,this._rejectedToken=null,this._notifiedRejectedToken=null,this.logger.info("Connected to server",e),this._restoreSubscriptions(),this._processPendingSubscriptions(),this.emit("connected",{frame:e}),i&&this.emit("reconnected",{attempts:s}),this._connectResolve&&(this._connectResolve(),this._connectResolve=null,this._connectReject=null)}_onDisconnect(e){this.logger.info("Disconnected from server",e),this._setState(t.DISCONNECTED),this.emit("disconnected",{frame:e})}_onStompError(e){let i=null,n=null;try{const t=JSON.parse(e.body||e.headers?.message||"{}");i=t.code??null,n="string"==typeof t.message?t.message:null,this._authRejected=["ACCESS_UNAUTHORIZED","SESSION_REVOKED","TOKEN_INVALID"].includes(i)}catch{}if(i===qs)return void this._stopForSubscription(n);this.logger.error("STOMP error:",e),this._setState(t.ERROR);const r={type:s.CONNECTION_FAILED,message:e.headers?.message||"STOMP error",frame:e};this._authRejected&&this._recordAuthRejection();const o="SUBSCRIPTION_CHECK_UNAVAILABLE"!==i&&!this._canRecoverConnection();o&&this._drainPendingSubscriptions(`STOMP error: ${r.message}`),this.emit("error",r),o&&this._connectReject&&(this._connectReject(new Error(r.message)),this._connectResolve=null,this._connectReject=null)}_onWebSocketClose(e){4001===e?.code&&this._recordAuthRejection(),this.logger.warn("WebSocket closed:",e),this._tearingDown||this._intentionalDisconnect||this._terminalAuthError||this._subscriptionRequired?this.logger.debug("WebSocket closed during intentional teardown — not counting as reconnect"):this.state!==t.DISCONNECTED&&this._handleReconnect()}_onWebSocketError(e){this.logger.error("WebSocket error:",e),this._connectReject&&!this._canRecoverConnection()&&(this._drainPendingSubscriptions("WebSocket connection failed"),this._connectReject(new Error("WebSocket connection failed")),this._connectResolve=null,this._connectReject=null)}_handleReconnect(){if(this.reconnectAttempts++,this.reconnectAttempts>this.maxReconnectAttempts){const e=this.stompClient;let i;this.stompClient=null;try{i=e?.deactivate()}catch(e){this.logger.warn("Error deactivating stomp client on max reconnect:",e)}return Promise.resolve(i).catch(e=>{this.logger.warn("Error deactivating stomp client on max reconnect:",e)}).then(()=>this._scheduleReconnectRecovery()),this._canRecoverConnection()||(this._connectReject?.(new Error("Max reconnection attempts exceeded")),this._connectResolve=this._connectReject=null,this._drainPendingSubscriptions("Max reconnection attempts exceeded")),this._setState(t.ERROR),void this.emit("error",{type:s.CONNECTION_LOST,message:"Max reconnection attempts exceeded"})}this._setState(t.RECONNECTING),this.emit("reconnecting",{attempt:this.reconnectAttempts}),this.logger.info(`Reconnecting... attempt ${this.reconnectAttempts}`)}_recordAuthRejection(){this._authRejected=!0,this._rejectedToken=(this._connectionToken||this.jwtToken).replace(/^Bearer\s+/i,""),this.getAccessToken||this._stopForAuthError(new Error("STOMP error: authentication rejected"))}_stopForAuthError(e,i=this.stompClient){const n=!this._terminalAuthError&&this._usesStaticToken()&&this._rejectedToken!==this._notifiedRejectedToken;this._terminalAuthError=!0,this._recoveryEligible=!1,this._cancelReconnectRecovery(),this._setState(t.ERROR),this._connectReject?.(e),this._drainPendingSubscriptions(e.message),Promise.resolve(i?.deactivate()).catch(e=>this.logger.warn("Auth teardown failed:",e)),n&&(this._notifiedRejectedToken=this._rejectedToken,Promise.resolve().then(()=>this.emit("error",{type:s.CONNECTION_LOST,message:e.message,error:e})))}_usesStaticToken(){return!this.getAccessToken||!1===this.canRefreshToken?.()}_canRecoverConnection(){return this._recoveryEligible&&!this._intentionalDisconnect&&!this._terminalAuthError&&!this._subscriptionRequired&&this.reconnectRecoveryDelay>0}isSubscriptionRequired(){return this._subscriptionRequired}_stopForSubscription(e){const i=!this._subscriptionRequired;this._subscriptionRequired=!0,this._cancelReconnectRecovery(),this._setState(t.ERROR);const n=e||"Company subscription required",r=Object.assign(new Error("Company subscription required"),{code:qs,type:s.SUBSCRIPTION_REQUIRED});this._connectReject?.(r),this._connectResolve=this._connectReject=null,this._drainPendingSubscriptions("Company subscription required");const o=this.stompClient;Promise.resolve(o?.deactivate()).catch(e=>this.logger.warn("Subscription teardown failed:",e)),this.logger.warn("Company subscription required — connection stopped until connect() is called again"),i&&Promise.resolve().then(()=>this.emit("subscriptionRequired",{code:qs,message:n}))}_scheduleReconnectRecovery(){if(!this._canRecoverConnection()||this.state!==t.ERROR||this.stompClient)return;this._cancelReconnectRecovery();const e=this.reconnectRecoveryDelay*(.8+.4*Math.random());this._recoveryTimer=setTimeout(()=>{this._recoveryTimer=null,this._intentionalDisconnect||this._terminalAuthError||this.state!==t.ERROR||this.forceReconnect("retry-cooldown")},e),this._recoveryTimer.unref?.()}_cancelReconnectRecovery(){clearTimeout(this._recoveryTimer),this._recoveryTimer=null}_restoreSubscriptions(){if(0===this.subscriptions.size)return;this.logger.info(`Restoring ${this.subscriptions.size} subscriptions after reconnect`);const e=new Map(this.subscriptions);this.subscriptions.clear(),e.forEach(({callback:e,headers:t},s)=>{this._subscribeInternal(s,e,t),this.logger.debug(`Restored subscription: ${s}`)})}_processPendingSubscriptions(){for(;this.pendingSubscriptions.length>0;){const{destination:e,callback:t,headers:s,resolve:i}=this.pendingSubscriptions.shift(),n=this._subscribeInternal(e,t,s);i&&i(n)}}_subscribeInternal(e,t,s={}){const i=this.stompClient.subscribe(e,e=>{try{const s=JSON.parse(e.body);t(s,e)}catch(s){this.logger.error("Failed to parse message:",s),t(e.body,e)}},s);return this.subscriptions.set(e,{subscription:i,callback:t,headers:s}),this.logger.debug(`Subscribed to: ${e}`),i}subscribe(e,s,i={}){return this.subscriptions.has(e)&&this.unsubscribe(e),this.state!==t.CONNECTED?new Promise((t,n)=>{this.pendingSubscriptions.push({destination:e,callback:s,headers:i,resolve:t,reject:n}),this.logger.debug(`Queued subscription for: ${e}`)}):Promise.resolve(this._subscribeInternal(e,s,i))}unsubscribe(e){const t=this.subscriptions.get(e);t&&(t.subscription.unsubscribe(),this.subscriptions.delete(e),this.logger.debug(`Unsubscribed from: ${e}`))}unsubscribeAll(){this.subscriptions.forEach(({subscription:e},t)=>{e.unsubscribe(),this.logger.debug(`Unsubscribed from: ${t}`)}),this.subscriptions.clear()}send(e,s,i={}){return this.state!==t.CONNECTED?(this.logger.warn("Cannot send message: not connected"),!1):(this.stompClient.publish({destination:e,body:JSON.stringify(s),headers:i}),this.logger.debug(`Sent to ${e}:`,s),!0)}updateToken(e){this.jwtToken=e,this.stompClient&&(this.stompClient.connectHeaders={...this.stompClient.connectHeaders,Authorization:e.startsWith("Bearer ")?e:`Bearer ${e}`}),this._terminalAuthError&&!this._intentionalDisconnect&&this._usesStaticToken()&&e.replace(/^Bearer\s+/i,"")!==this._rejectedToken&&this.connect().catch(e=>this.logger.warn("Reconnect with updated token failed:",e))}async disconnect(){this._intentionalDisconnect=!0,this._recoveryEligible=!1,this._subscriptionRequired=!1,this._authRejected=!1,this._rejectedToken=null,this._cancelReconnectRecovery(),this._connectRequested=!1,this._cancelAuthRetry?.(),this._connectReject?.(Object.assign(new Error("Connection cancelled"),{code:"AUTH_OPERATION_CANCELLED"})),this._connectResolve=this._connectReject=null,this._drainPendingSubscriptions("Disconnected before subscription completed"),this.stompClient&&(this.unsubscribeAll(),await this.stompClient.deactivate(),this.stompClient=null),this._setState(t.DISCONNECTED),this.logger.info("Disconnected")}_drainPendingSubscriptions(e){if(0===this.pendingSubscriptions.length)return;const t=this.pendingSubscriptions;this.pendingSubscriptions=[],t.forEach(({destination:t,reject:s})=>{s&&s(new Error(`${e}: ${t}`))}),this.logger.debug(`Drained ${t.length} pending subscriptions: ${e}`)}isConnected(){return this.state===t.CONNECTED}getState(){return this.state}setLogLevel(e){this.logger.setLevel(e)}async destroy(){this._removeLifecycleListeners(),await this.disconnect(),this.removeAllListeners(),this.logger.info("ConnectionManager destroyed")}}const Xs=new Set(["text/plain","text/markdown","text/x-markdown"]);class Ys extends e{constructor(e){super(),this.connectionManager=e.connectionManager,this.apiClient=e.apiClient,this.userId=e.userId,this.logger=new S(e.logLevel||w.WARN,"ChatClient"),this.subscribedRooms=new Map,this.roomListSubscribed=!1,this.mailSubscribed=!1,this._activeRoomId=null,this._typingTimers=new Map,this._assistantTypingTimers=new Map,this._assistantTypingTimeoutMs=3e4,this._assistantTypingUserId="__assistant__",this._assistantTypingUserName="AI",this._assistantProgress=new Map,this._assistantStreamTombstones=new Map,this._assistantTombstoneTtlMs=12e4,this._assistantTombstoneWarnThreshold=32,this._assistantTombstoneWarned=new Set,this._assistantSlotSeq=0,this._assistantRoomGeneration=new Map,this._assistantSnapshotPending=new Map,this._assistantSnapshotInFlight=new Map,this.assistantStreamReplay=!1!==e.assistantStreamReplay,this._assistantPhaseLabels={THINKING:"생각 중…",SEARCHING:"검색 중…",PLANNING:"기획 중…",DOCUMENT_ANALYSIS:"문서 분석 중…",VIDEO_ANALYSIS:"영상 분석 중…",WEB_READING:"페이지 읽는 중…",WRITING:"작성 중…"},this._assistantProgressFallbackTtlMs=35e3,this._seenChatMessageIdsByRoom=new Map,this._seenRoomListMessageIdsByRoom=new Map,this.syncOnReconnect=!1!==e.syncOnReconnect,this.rewindMillis=void 0!==e.rewindMillis?e.rewindMillis:b.rewindMillis,this.maxSyncPages=e.maxSyncPages||b.maxSyncPages,this.syncPageSize=e.syncPageSize||b.syncPageSize,this._anchor=new Map,this._anchorGen=new Map,this._syncInFlight=new Set,this._replaying=!1,this._maxSeenPerRoom=Math.max(200,this.maxSyncPages*this.syncPageSize+100),this._reconnectSyncGeneration=0,this._delayedReconnectSyncTimer=null,this._installSyncTriggers()}_installSyncTriggers(){this.connectionManager&&"function"==typeof this.connectionManager.on&&(this._onReconnectedForSync=({attempts:e}={})=>{this._cancelDelayedReconnectSync();const t=this._reconnectSyncGeneration;this.syncAfterReconnect(`reconnected:${e??0}`).catch(e=>this.logger.warn("Gap sync after reconnect failed:",e)).then(e=>{this.syncOnReconnect&&e&&t===this._reconnectSyncGeneration&&(this._delayedReconnectSyncTimer=setTimeout(()=>{this._delayedReconnectSyncTimer=null,this._supplementAfterReconnect(e,t).catch(e=>this.logger.warn("Delayed gap sync failed:",e))},1e3),this._delayedReconnectSyncTimer.unref?.())}),this.resumeAssistantStreams(`reconnected:${e??0}`).catch(e=>this.logger.warn("Assistant stream replay after reconnect failed:",e))},this._onResumedForSync=({reason:e}={})=>{this.syncAfterReconnect(`resumed:${e??"unknown"}`).catch(e=>this.logger.warn("Gap sync after resume failed:",e)),this.resumeAssistantStreams(`resumed:${e??"unknown"}`).catch(e=>this.logger.warn("Assistant stream replay after resume failed:",e))},this._onStateChangeForSync=({state:e})=>{e!==t.CONNECTED&&this._cancelDelayedReconnectSync()},this.connectionManager.on("stateChange",this._onStateChangeForSync),this.connectionManager.on("reconnected",this._onReconnectedForSync),this.connectionManager.on("resumed",this._onResumedForSync))}_shouldDedupMessage(e,t,s){if(!t||!s)return!1;let i=e.get(t);if(i||(i=new Map,e.set(t,i)),i.has(s))return!0;if(i.set(s,!0),i.size>this._maxSeenPerRoom){const e=i.keys().next().value;i.delete(e)}return!1}async getRooms(e={}){const{size:t=50,lastId:s,lastSortValue:i,type:n}=e;return this.apiClient.get("/api/v1/rooms/my",{size:t,lastId:s,lastSortValue:i,type:n})}async getRoom(e){const t=this._anchorGen.get(e)||0,s=await this.apiClient.get(`/api/v1/rooms/${e}`),i=this._unwrapSuccessResponse(s);return i&&Array.isArray(i.messages)&&this._seedAnchorFromLatest(e,i.messages,t),s}async enterRoom(e){const t=this.subscribedRooms.has(e);if(t){if(this.assistantStreamReplay){const t=this._armAssistantSnapshot(e);this._loadAssistantSnapshot(e,t).catch(t=>this.logger.warn(`Assistant snapshot on re-enter failed: room=${e}`,t))}}else await this.subscribeRoom(e);this.setActiveRoom(e);try{return await this.getRoom(e)}catch(s){throw this.getActiveRoom()===e&&this.clearActiveRoom(),t||this.unsubscribeRoom(e),s}}async getRoomInfo(e){return this.apiClient.get(`/api/v1/rooms/${e}/info`)}async setMyRoomLanguage(e,t){return this.apiClient.put(`/api/v1/rooms/${e}/my-language`,{language:t})}async createOneToOneRoom(e){return this.apiClient.post(`/api/v1/rooms/direct/${e}`)}async createGroupRoom(e){const t=e.roomType||h.GROUP;if(t===h.PRIVATE_GROUP){if(!e.password||e.password.length<4)throw new Error("PRIVATE_GROUP requires a password of at least 4 characters")}else if(t===h.GROUP){if(e.password)throw new Error("Public GROUP rooms cannot have a password")}else if(t===h.TEAM&&e.password)throw new Error("TEAM rooms cannot have a password (invite-only)");return this.apiClient.post("/api/v1/rooms/group",{roomName:e.roomName,description:e.description,invitedUserIds:e.invitedUserIds,roomType:t,password:e.password,messageRetentionHours:e.messageRetentionHours,invitedAssistantPersonaIds:e.invitedAssistantPersonaIds,assistantMode:e.assistantMode,roomAiType:e.roomAiType,engagementIntensity:e.engagementIntensity})}async getAssistants(){const e=await this.apiClient.get("/api/v1/assistants");return this._unwrapSuccessResponse(e)}async getRoomAiMeta(){const e=await this.apiClient.get("/api/v1/rooms/ai-meta");return this._unwrapSuccessResponse(e)}async rateAssistantMessage(e,t,s,i){if(!Number.isInteger(s)||s<1||s>5)throw new Error("rating must be an integer between 1 and 5");await this.apiClient.post(`/api/v1/chat-messages/${e}/messages/${t}/rating`,{rating:s,comment:i})}async summarizeWithAssistant(e,t={}){const{personaId:s,format:i,messageCount:n}=t;if(!s)throw new Error("summarizeWithAssistant requires options.personaId");const r=await this.apiClient.post(`/api/v1/rooms/${e}/assistant/tools/summarize`,{personaId:s,format:i,messageCount:n});return this._unwrapSuccessResponse(r)}async uploadVideoAsset(e,t={}){if(!e)throw new Error("file is required");return this._unwrapSuccessResponse(await this.apiClient.upload("/api/v1/video-assets",e,{onProgress:t.onProgress,signal:t.signal}))}async analyzeVideo(e,t={}){if("string"!=typeof t.idempotencyKey||!t.idempotencyKey.trim())throw new Error("idempotencyKey is required for video analysis");return this._unwrapSuccessResponse(await this.apiClient.post("/api/v1/video-analyses",e,void 0,{"Idempotency-Key":t.idempotencyKey}))}async analyzeVideoWithAssistant(e,t,s={}){if(!e||!t?.personaId||!t?.triggerMessageId)throw new Error("roomId, personaId and triggerMessageId are required");if("string"!=typeof s.idempotencyKey||!s.idempotencyKey.trim())throw new Error("idempotencyKey is required for video analysis");return this._unwrapSuccessResponse(await this.apiClient.post(`/api/v1/rooms/${encodeURIComponent(e)}/assistant/tools/analyze-video`,t,void 0,{"Idempotency-Key":s.idempotencyKey}))}async getVideoAnalysis(e){if(!e)throw new Error("jobId is required");return this._unwrapSuccessResponse(await this.apiClient.get(`/api/v1/video-analyses/${encodeURIComponent(e)}`))}async cancelVideoAnalysis(e){if(!e)throw new Error("jobId is required");return this._unwrapSuccessResponse(await this.apiClient.post(`/api/v1/video-analyses/${encodeURIComponent(e)}/cancel`))}async getVideoAnalysisCapabilities(){return this._unwrapSuccessResponse(await this.apiClient.get("/api/v1/video-analyses/capabilities"))}async translateWithAssistant(e,t={}){const{targetLang:s,sourceMessageId:i}=t;if(!i)throw new Error("translateWithAssistant requires options.sourceMessageId");if(!s)throw new Error("translateWithAssistant requires options.targetLang");const n=await this.apiClient.post(`/api/v1/rooms/${e}/assistant/tools/translate`,{targetLang:s,sourceMessageId:i});return this._unwrapSuccessResponse(n)}async refreshSummary(e,t={}){const{format:s,lang:i}=t,n=await this.apiClient.post(`/api/v1/rooms/${e}/summary/refresh`,{format:s,lang:i});return this._unwrapSuccessResponse(n)}async getSummary(e,t={}){const{format:s,lang:i,afterSeq:n,size:r}=t,o=await this.apiClient.get(`/api/v1/rooms/${e}/summary`,{format:s,lang:i,afterSeq:n,size:r});return this._unwrapSuccessResponse(o)}async getRoomPmPrompt(e){const t=await this.apiClient.get(`/api/v1/rooms/${e}/pm-prompt`);return this._unwrapSuccessResponse(t)}async upsertRoomPmPrompt(e,t){if("string"!=typeof t||!t.trim())throw new Error("upsertRoomPmPrompt requires non-blank content");if(t.length>2e4)throw new Error("upsertRoomPmPrompt content exceeds 20000 characters");const s=await this.apiClient.put(`/api/v1/rooms/${e}/pm-prompt`,{content:t});return this._unwrapSuccessResponse(s)}async activateRoomPmPrompt(e){const t=await this.apiClient.patch(`/api/v1/rooms/${e}/pm-prompt/activate`);return this._unwrapSuccessResponse(t)}async deactivateRoomPmPrompt(e){const t=await this.apiClient.patch(`/api/v1/rooms/${e}/pm-prompt/deactivate`);return this._unwrapSuccessResponse(t)}async getRoomPmPromptVersions(e){const t=await this.apiClient.get(`/api/v1/rooms/${e}/pm-prompt/versions`);return this._unwrapSuccessResponse(t)}async activateRoomPmPromptVersion(e,t){if(!Number.isInteger(t)||t<1)throw new Error("activateRoomPmPromptVersion requires a positive integer version");const s=await this.apiClient.post(`/api/v1/rooms/${e}/pm-prompt/versions/${t}/activate`);return this._unwrapSuccessResponse(s)}async previewRoomPmPrompt(e){const t=await this.apiClient.get(`/api/v1/rooms/${e}/pm-prompt/preview`);return this._unwrapSuccessResponse(t)}async joinGroupRoom(e,t){const s=t?{password:t}:void 0;return this.apiClient.post(`/api/v1/rooms/group/${e}/join`,s)}async leaveRoom(e,t={}){const s=t.newOwnerId?{newOwnerId:t.newOwnerId}:void 0,i=await this.apiClient.post(`/api/v1/rooms/${e}/leave`,s);return this.unsubscribeRoom(e),i}async transferOwnership(e,t){const s=await this.apiClient.put(`/api/v1/rooms/${e}/owner`,{newOwnerId:t});return s&&"object"==typeof s&&"data"in s?s.data:s}async deleteRoom(e){const t=await this.apiClient.delete(`/api/v1/rooms/${e}`);return this.unsubscribeRoom(e),t}async updateGroupRoom(e,t){return this.apiClient.put(`/api/v1/rooms/group/${e}`,t)}async inviteToGroupRoom(e,t){const s=Array.isArray(t)?{userIds:t}:{userIds:t?.userIds,assistantPersonaIds:t?.assistantPersonaIds};return this.apiClient.post(`/api/v1/rooms/group/${e}/invite`,s)}async kickMember(e,t){return this.apiClient.delete(`/api/v1/rooms/${e}/members/${t}`)}async banMember(e,t){return this.apiClient.post(`/api/v1/rooms/${e}/banned-members`,{userId:t})}async unbanMember(e,t){return this.apiClient.delete(`/api/v1/rooms/${e}/banned-members/${t}`)}async getBannedMembers(e){const t=await this.apiClient.get(`/api/v1/rooms/${e}/banned-members`);return t&&"object"==typeof t&&"data"in t?t.data:t}async pinMessage(e,t){return this.apiClient.post(`/api/v1/rooms/group/${e}/pin/${t}`)}async unpinMessage(e){return this.apiClient.post(`/api/v1/rooms/group/${e}/unpin`)}async createVote(e,t,s={}){if(!e)throw new Error("roomId is required");const{idempotencyKey:i}=s;if(!i)throw new Error("createVote: options.idempotencyKey is required — generate it once per vote and reuse the same value on retry (재시도에 같은 키를 넘겨야 투표가 중복 생성되지 않는다).");const n=await this.apiClient.post(`/api/v1/rooms/${e}/votes`,t,void 0,{"X-Idempotency-Key":i});return this._unwrapSuccessResponse(n)}async getVotes(e,t={}){const{cursor:s,limit:i}=t,n=await this.apiClient.get(`/api/v1/rooms/${e}/votes`,{cursor:s,limit:i});return this._unwrapSuccessResponse(n)}async getVote(e,t){const s=await this.apiClient.get(`/api/v1/rooms/${e}/votes/${t}`);return this._unwrapSuccessResponse(s)}async updateVote(e,t,s){const i=await this.apiClient.patch(`/api/v1/rooms/${e}/votes/${t}`,s);return this._unwrapSuccessResponse(i)}async deleteVote(e,t){await this.apiClient.delete(`/api/v1/rooms/${e}/votes/${t}`)}async closeVote(e,t){await this.apiClient.patch(`/api/v1/rooms/${e}/votes/${t}/close`)}async submitVote(e,t,s){const i=await this.apiClient.put(`/api/v1/rooms/${e}/votes/${t}/responses`,{optionIds:s});return this._unwrapSuccessResponse(i)}async uploadVoteImage(e,t,s={}){if(!e)throw new Error("roomId is required");if(!t)throw new Error("file is required");const i=await this.apiClient.upload(`/api/v1/rooms/${e}/votes/images`,t,{onProgress:s.onProgress,signal:s.signal});return this._unwrapSuccessResponse(i)}async toggleReaction(e,t,s){return this.apiClient.post(`/api/v1/chat-messages/${e}/messages/${t}/reaction`,{emoji:s})}async getAvailableGroupRooms(e={}){const{size:t=50,lastId:s,lastSortValue:i}=e;return this.apiClient.get("/api/v1/rooms/groups/available",{size:t,lastId:s,lastSortValue:i})}async getAllGroupRooms(e={}){const{size:t=50,lastId:s,lastSortValue:i}=e;return this.apiClient.get("/api/v1/rooms/groups/all",{size:t,lastId:s,lastSortValue:i})}async getMessages(e,t={}){const{size:s=50,lastId:i,lastSortValue:n}=t,r=null==i&&null==n,o=this._anchorGen.get(e)||0,a=await this.apiClient.get(`/api/v1/chat-messages/${e}/list`,{size:s,lastId:i,lastSortValue:n}),c=this._unwrapSuccessResponse(a);return c&&Array.isArray(c.content)&&(c.content.forEach(e=>this._normalizeMessageTimestamps(e)),r&&this._seedAnchorFromLatest(e,c.content,o)),a}_seedAnchorFromLatest(e,t,s){if(!Array.isArray(t)||0===t.length)return!1;const i=t[0];return!(!i||!i.id)&&this._commitAnchorFromSync(e,i.id,s)}async syncMessages(e,t={}){const{afterId:s,rewindMillis:i,size:n=this.syncPageSize}=t,r=await this.apiClient.get(`/api/v1/chat-messages/${e}/sync`,{afterId:s,rewindMillis:i,size:n}),o=this._unwrapSuccessResponse(r);return o&&Array.isArray(o.content)&&o.content.forEach(e=>this._normalizeMessageTimestamps(e)),r}_advanceAnchorFromLive(e,t){e&&t&&(this._anchor.set(e,t),this._anchorGen.set(e,(this._anchorGen.get(e)||0)+1))}_commitAnchorFromSync(e,t,s){return!!t&&((this._anchorGen.get(e)||0)!==s?(this.logger.debug(`Anchor commit skipped (live advanced): room=${e}`),!1):(this._anchor.set(e,t),!0))}_replayMessages(e,t){if(!Array.isArray(t)||0===t.length)return 0;let s=0;this._replaying=!0;try{t.forEach(t=>{this._handleChatMessage(e,{...t,eventType:t.eventType||"MESSAGE_CREATED"})&&(s+=1)})}finally{this._replaying=!1}return s}async _reloadLatestPage(e,t){const s=await this.getMessages(e,{size:this.syncPageSize}),i=this._unwrapSuccessResponse(s)||{},n=(Array.isArray(i.content)?i.content:[]).slice().reverse(),r=this._replayMessages(e,n),o=n.length?n[n.length-1].id:null;return this._commitAnchorFromSync(e,o,t),r}_isCursorExpired(e){return 410===e?.status||"SYNC_CURSOR_EXPIRED"===e?.response?.code}async _syncRoom(e,t=this._anchor.get(e),s=!1){if(!t)return null;if(this._syncInFlight.has(e))return null;this._syncInFlight.add(e);const i=this._anchorGen.get(e)||0,n=Date.now();try{const r=[];let o=t,a=this.rewindMillis,c=!0,h=0;for(;c&&h<this.maxSyncPages;){const t=await this.syncMessages(e,{afterId:o,rewindMillis:a}),s=this._unwrapSuccessResponse(t)||{},i=Array.isArray(s.content)?s.content:[];r.push(...i),a=0,c=!!s.hasNext,s.lastId&&(o=s.lastId),h+=1}if(c){this.logger.info(`Gap too large, falling back to latest page: room=${e}`),s||this.emit("gapTruncated",{roomId:e,fetched:r.length});const t=await this._reloadLatestPage(e,i);return{roomId:e,cursor:this._anchor.get(e),recovered:t,truncated:!0,durationMs:Date.now()-n}}const l=this._replayMessages(e,r);return this._commitAnchorFromSync(e,o,i),{roomId:e,cursor:o,recovered:l,truncated:!1,durationMs:Date.now()-n}}catch(t){if(this._isCursorExpired(t)){this.logger.warn(`Sync cursor expired, reloading latest: room=${e}`),s||this.emit("gapTruncated",{roomId:e,fetched:0,reason:"cursorExpired"});const t=await this._reloadLatestPage(e,i);return{roomId:e,cursor:this._anchor.get(e),recovered:t,truncated:!0,durationMs:Date.now()-n}}throw t}finally{this._syncInFlight.delete(e)}}async syncAfterReconnect(e="manual"){if(!this.syncOnReconnect)return;const t=Array.from(this.subscribedRooms.keys()).filter(e=>this._anchor.has(e));if(0===t.length)return void await this._refreshRoomList(e);this.emit("syncStarted",{roomIds:t,reason:e});const s=Date.now(),i=[],n=new Map;for(const e of t)try{const t=await this._syncRoom(e);t&&(i.push(t),n.set(e,t.cursor))}catch(t){this.logger.warn(`Gap sync failed: room=${e}`,t)}return await this._refreshRoomList(e),this.emit("syncCompleted",{rooms:i,totalRecovered:i.reduce((e,t)=>e+(t.recovered||0),0),durationMs:Date.now()-s,reason:e}),n}async _supplementAfterReconnect(e,t){for(const[s,i]of e){if(t!==this._reconnectSyncGeneration)return;if(this.subscribedRooms.has(s))try{await this._syncRoom(s,i,!0)}catch(e){this.logger.warn(`Supplemental gap sync failed: room=${s}`,e)}}}async _refreshRoomList(e){if(this.roomListSubscribed)try{const t=await this.getRooms({size:50}),s=this._unwrapSuccessResponse(t)||{};this.emit("roomListSynced",{rooms:s.content||[],reason:e})}catch(e){this.logger.warn("Room list refresh failed (non-fatal):",e)}}async fetchLinkPreview(e){const t="string"==typeof e?e.trim():"";if(!t)throw new Error("url is required");const s=await this.apiClient.post("/api/v1/link-preview",{url:t});return this._unwrapSuccessResponse(s)}async sendMessage(e,t){const s=this._generateMessageId();return this._sendMessageWithId(e,s,t)}sendMessageOptimistic(e,t){const s=this._generateMessageId(),i=[s],n=this._sendMessageWithId(e,s,t).then(e=>this._attachOptimisticMetadata(i,e));return{baseMessageId:s,messageIds:i,promise:n}}async _sendMessageWithId(e,t,s){this.stopTyping(e);const i=await this.apiClient.post(`/api/v1/chat-messages/${e}/send`,{messageId:t,message:s.message,fileInfos:s.fileInfos,replyToMessageId:s.replyToMessageId,decisionResponse:s.decisionResponse}),n=this._unwrapSuccessResponse(i);return n&&Array.isArray(n.messages)&&n.messages.forEach(e=>this._normalizeMessageTimestamps(e)),n}async sendTextMessage(e,t){return this.sendMessage(e,{message:t})}sendTextMessageOptimistic(e,t){return this.sendMessageOptimistic(e,{message:t})}async uploadFile(e,t,s={}){if(!e)throw new Error("roomId is required");if(!t)throw new Error("file is required");const i=await this.apiClient.upload(`/api/v1/files/${e}/upload`,t,{onProgress:s.onProgress,signal:s.signal});return this._unwrapSuccessResponse(i)}async sendFileMessage(e,t,s={}){const i=this._normalizeFileArray(t),n=await this._uploadFiles(e,i,s),r=this._applyFileMetadata(n,s.metadata);return this.sendMessage(e,{message:s.message,fileInfos:r,replyToMessageId:s.replyToMessageId})}sendFileMessageOptimistic(e,t,s={}){const i=this._normalizeFileArray(t),n=this._generateMessageId(),r=[n],o=(async()=>{const t=await this._uploadFiles(e,i,s),o=this._applyFileMetadata(t,s.metadata),a=await this._sendMessageWithId(e,n,{message:s.message,fileInfos:o,replyToMessageId:s.replyToMessageId});return this._attachOptimisticMetadata(r,a)})();return{baseMessageId:n,messageIds:r,promise:o}}_normalizeFileArray(e){const t=Array.isArray(e)?e:[e];if(0===t.length)throw new Error("At least one file is required");if(t.length>20)throw new Error("A maximum of 20 files can be sent in one message");return t}async _uploadFiles(e,t,s={}){return Promise.all(t.map((t,i)=>this.uploadFile(e,t,{signal:s.signal,onProgress:s.onUploadProgress?e=>s.onUploadProgress({...e,fileIndex:i}):void 0})))}_applyFileMetadata(e,t){return null==t?e:e.map((e,s)=>{const i=Array.isArray(t)?t[s]:t;return null==i?e:{...e,metadata:i}})}async sendReply(e,t,s){return this.sendMessage(e,{message:t,replyToMessageId:s})}sendReplyOptimistic(e,t,s){return this.sendMessageOptimistic(e,{message:t,replyToMessageId:s})}async sendDecisionChoice(e,t,s){if(!t||!t.messageId)throw new Error("sendDecisionChoice: card with messageId is required");if(!s||!s.id)throw new Error("sendDecisionChoice: option with id is required");return this.sendMessage(e,{message:s.label,replyToMessageId:t.messageId,decisionResponse:{optionId:s.id}})}async deleteMessage(e,t,s="ALL"){return this.apiClient.post(`/api/v1/chat-messages/${e}/messages/${t}/delete`,{deleteType:s})}async editMessage(e,t,s){return this.apiClient.put(`/api/v1/chat-messages/${e}/messages/${t}`,{message:s})}_hasTextMessage(e){return"string"==typeof e&&e.trim().length>0}_baseMimeType(e){const t=e||"",s=t.indexOf(";");return(s>=0?t.slice(0,s):t).trim().toLowerCase()}classifyFileType(e){const t=this._baseMimeType(e);return t.startsWith("image/")?"IMAGE":t.startsWith("video/")?"VIDEO":t.startsWith("audio/")?"AUDIO":t.includes("pdf")||t.includes("document")||t.includes("msword")||t.includes("ms-excel")||t.includes("ms-powerpoint")||Xs.has(t)?"DOCUMENT":"FILE"}_classifyFileType(e){return this.classifyFileType(e)}resolveMessageCategory(e){const t=e&&e.chatMessageType,s=e&&e.fileMetaDataList||[];if("GALLERY"!==t)return t||"TEXT";if(0===s.length)return"FILE";const i=new Set(s.map(e=>this.classifyFileType(e&&e.fileType||"")));return 1===i.size?i.values().next().value:"MIXED"}_attachOptimisticMetadata(e,t){const s=t&&Array.isArray(t.messages)?t.messages.map(e=>e&&e.messageId||null):[],i=s.length===e.length&&e.every((e,t)=>e===s[t]);return i||this.logger.warn("Optimistic messageId prediction mismatch — server may have changed grouping rules. Use result.optimistic.actualMessageIds to reconcile.",{predicted:e,actual:s}),{...t,optimistic:{predictedMessageIds:e,actualMessageIds:s,predictionMatched:i}}}_generateMessageId(){return"undefined"!=typeof crypto&&"function"==typeof crypto.randomUUID?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{const t=16*Math.random()|0;return("x"===e?t:3&t|8).toString(16)})}_unwrapSuccessResponse(e){return e&&"object"==typeof e&&Object.prototype.hasOwnProperty.call(e,"data")?e.data:e}_normalizeMessageTimestamps(e){return e&&"object"==typeof e?(e.sentAt=this._toEpochMillis(e.sentAt),e.editedAt=this._toEpochMillis(e.editedAt),e.replyTo&&"object"==typeof e.replyTo&&(e.replyTo.sentAt=this._toEpochMillis(e.replyTo.sentAt)),e):e}_toEpochMillis(e){if("string"!=typeof e)return e;const t=Date.parse(e);return Number.isNaN(t)?e:t}async subscribeRoom(e){if(this.subscribedRooms.has(e))return void this.logger.warn(`Already subscribed to room: ${e}`);const t=_.getChatDestination(e);await this.connectionManager.subscribe(t,t=>{this._handleChatMessage(e,t)});const s=_.getChatReadDestination(e);await this.connectionManager.subscribe(s,t=>{this._handleReadEvent(e,t)});const i=_.getChatTypingDestination(e);await this.connectionManager.subscribe(i,t=>{this._handleTypingEvent(e,t)});const n=this.assistantStreamReplay?this._armAssistantSnapshot(e):null,r=_.getChatAssistantStreamDestination(e);await this.connectionManager.subscribe(r,t=>{this._handleAssistantStreamEvent(e,t)}),null!==n&&this._loadAssistantSnapshot(e,n).catch(t=>this.logger.warn(`Assistant snapshot merge failed: room=${e}`,t));const o=_.getChatSummaryDestination(e);await this.connectionManager.subscribe(o,t=>{this._handleSummaryEvent(e,t)});const a=t=>{t.roomId===e&&this.emit("memberJoined",{roomId:e,members:t.members||[],participantCount:t.activeParticipantCount,timestamp:t.timestamp})},c=t=>{t.roomId===e&&this.emit("memberLeft",{roomId:e,members:t.members||[],participantCount:t.activeParticipantCount,timestamp:t.timestamp})};this.on("roomListJoined",a),this.on("roomListLeft",c),this.subscribedRooms.set(e,{chatDestination:t,readDestination:s,typingDestination:i,assistantStreamDestination:r,summaryDestination:o,memberJoinedHandler:a,memberLeftHandler:c,subscribedAt:new Date}),this.logger.info(`Subscribed to room: ${e}`),this.emit("roomSubscribed",{roomId:e})}unsubscribeRoom(e){const t=this.subscribedRooms.get(e);t?(this.connectionManager.unsubscribe(t.chatDestination),this.connectionManager.unsubscribe(t.readDestination),t.typingDestination&&this.connectionManager.unsubscribe(t.typingDestination),t.assistantStreamDestination&&this.connectionManager.unsubscribe(t.assistantStreamDestination),t.summaryDestination&&this.connectionManager.unsubscribe(t.summaryDestination),t.memberJoinedHandler&&this.off("roomListJoined",t.memberJoinedHandler),t.memberLeftHandler&&this.off("roomListLeft",t.memberLeftHandler),this._clearTypingTimer(e),this._clearAssistantTypingTimer(e),this._clearAssistantProgress(e),this._activeRoomId===e&&(this._activeRoomId=null),this.subscribedRooms.delete(e),this._seenChatMessageIdsByRoom.delete(e),this._seenRoomListMessageIdsByRoom.delete(e),this.logger.info(`Unsubscribed from room: ${e}`),this.emit("roomUnsubscribed",{roomId:e})):this.logger.warn(`Not subscribed to room: ${e}`)}unsubscribeAllRooms(){this.subscribedRooms.forEach((e,t)=>{this.unsubscribeRoom(t)})}setActiveRoom(e){this._activeRoomId=e,this.logger.debug(`Active room set: ${e}`)}clearActiveRoom(){this.logger.debug(`Active room cleared (was: ${this._activeRoomId})`),this._activeRoomId=null}getActiveRoom(){return this._activeRoomId}async subscribeRoomList(){if(this.roomListSubscribed)return void this.logger.warn("Already subscribed to room list");const e=_.ROOM_LIST_USER_DESTINATION;await this.connectionManager.subscribe(e,e=>{this._handleRoomListEvent(e)}),this.roomListSubscribed=!0,this.logger.info("Subscribed to room list"),this.emit("roomListSubscribed",{})}unsubscribeRoomList(){this.roomListSubscribed?(this.connectionManager.unsubscribe(_.ROOM_LIST_USER_DESTINATION),this.roomListSubscribed=!1,this.logger.info("Unsubscribed from room list"),this.emit("roomListUnsubscribed",{})):this.logger.warn("Not subscribed to room list")}isRoomListSubscribed(){return this.roomListSubscribed}async subscribeMail(){this.mailSubscribed?this.logger.debug("Already subscribed to mail"):(await this.connectionManager.subscribe(_.MAIL_USER_DESTINATION,e=>{this._handleMailEvent(e)}),this.mailSubscribed=!0,this.logger.info("Subscribed to mail"),this.emit("mailSubscribed",{}))}unsubscribeMail(){this.mailSubscribed&&(this.connectionManager.unsubscribe(_.MAIL_USER_DESTINATION),this.mailSubscribed=!1,this.logger.info("Unsubscribed from mail"),this.emit("mailUnsubscribed",{}))}isMailSubscribed(){return this.mailSubscribed}_handleMailEvent(e){e&&"MAIL_CHANGED"===e.eventType&&(this.logger.debug("Mail changed:",e.connectionId,Array.isArray(e.messages)?e.messages.length:0),this.emit("mailChanged",e))}markAsRead(e,t){return this.connectionManager.isConnected()?this.connectionManager.send(_.CHAT_READ,{roomId:e,messageId:t}):(this.logger.warn("Cannot mark as read: not connected"),!1)}_handleChatMessage(e,t){if(this.logger.debug(`Message received in room ${e} (${t.eventType}):`,t),"MESSAGE_CREATED"===t.eventType&&this._shouldDedupMessage(this._seenChatMessageIdsByRoom,e,t.messageId))return this.logger.debug(`Duplicate MESSAGE_CREATED suppressed: room=${e}, messageId=${t.messageId}`),!1;switch("MESSAGE_CREATED"!==t.eventType||this._replaying||this._advanceAnchorFromLive(e,t.id),"MESSAGE_UPDATED"===t.eventType&&(void 0===t.translations&&(t.translations=null),void 0===t.sourceLang&&(t.sourceLang=null),void 0===t.translationsOf&&(t.translationsOf=null)),this.emit("message",{roomId:e,message:t}),t.eventType){case"MESSAGE_CREATED":"ASSISTANT"===t.senderType&&(this._clearAssistantTypingTimer(e),this.emit("typing",{roomId:e,userId:this._assistantTypingUserId,userName:this._assistantTypingUserName,typing:!1,senderType:"ASSISTANT"})),t.userId!==this.userId&&(this.emit("newMessage",{roomId:e,message:t}),this._activeRoomId===e&&t.messageId&&this.markAsRead(e,t.messageId));break;case"MESSAGE_UPDATED":this.emit("messageUpdated",{roomId:e,message:t});break;case"MESSAGE_DELETED":this.emit("messageDeleted",{roomId:e,message:t});break;case"REACTION_CHANGED":this.emit("reactionChanged",{roomId:e,message:t});break;case"LINK_PREVIEW_ATTACHED":this.emit("linkPreviewAttached",{roomId:e,message:t});break;case"MESSAGE_TRANSLATED":this.emit("messageTranslated",{roomId:e,message:t});break;default:this.logger.warn(`Unknown eventType "${t.eventType}" — falling back to legacy behavior`),t.userId!==this.userId&&(this.emit("newMessage",{roomId:e,message:t}),this._activeRoomId===e&&t.messageId&&this.markAsRead(e,t.messageId))}return!0}_handleRoomListEvent(e){if(this.logger.debug("Room list event:",e),e.eventType===m.MESSAGE_RECEIVED&&e.messageId&&this._shouldDedupMessage(this._seenRoomListMessageIdsByRoom,e.roomId,e.messageId))this.logger.debug(`Duplicate roomList MESSAGE_RECEIVED suppressed: room=${e.roomId}, messageId=${e.messageId}`);else switch(this.emit("roomListUpdate",e),e.eventType){case m.MESSAGE_RECEIVED:this.emit("roomListMessage",e);break;case m.MESSAGE_DELETED:this.emit("roomListMessageDeleted",e);break;case m.MESSAGE_UPDATED:this.emit("roomListMessageUpdated",e);break;case m.ROOM_CREATED:this.emit("roomListCreated",e);break;case m.ROOM_JOINED:this.emit("roomListJoined",e);break;case m.ROOM_LEFT:this.emit("roomListLeft",e),e.actorId===this.userId&&this.emit("roomListSelfLeft",e);break;case m.ROOM_KICKED:this.emit("roomListKicked",e),this._isSelfInMembers(e)&&this.emit("roomListSelfKicked",e);break;case m.ROOM_OWNER_CHANGED:this.emit("roomListOwnerChanged",e);break;case m.ROOM_DELETED:this.subscribedRooms.has(e.roomId)&&this.unsubscribeRoom(e.roomId),this.emit("roomListDeleted",e);break;case m.ROOM_BANNED:this.emit("roomListBanned",e),this._isSelfInMembers(e)&&this.emit("roomListSelfBanned",e);break;case m.ROOM_UPDATED:this.emit("roomListRoomUpdated",e);break;case m.MESSAGE_RETENTION_CLEANUP:this.emit("retentionCleanup",{roomId:e.roomId,cutoffTime:e.cutoffTime});break;case m.ROOM_UNREAD_UPDATED:this.emit("roomListUnreadUpdated",{roomId:e.roomId,roomUnreadCount:e.roomUnreadCount,unreadVersion:e.unreadVersion});break;case m.AI_UNAVAILABLE:this.emit("aiUnavailable",{roomId:e.roomId,messageId:e.messageId,aiBlocked:e.aiBlocked,timestamp:e.timestamp});break;default:this.logger.warn("Unknown room list event type:",e.eventType)}}_handleReadEvent(e,t){this.logger.debug(`Read event in room ${e}:`,t);const s=t.roomId||e;t.events&&Array.isArray(t.events)?t.events.forEach(e=>{this.emit("messageRead",{roomId:s,messageId:e.messageId,userId:t.userId,remainingUnreadCount:e.remainingUnreadCount})}):this.emit("messageRead",{roomId:s,messageId:t.messageId,userId:t.userId,remainingUnreadCount:t.remainingUnreadCount})}startTyping(e){if(!this.connectionManager.isConnected())return;const t=this._typingTimers.get(e);t?clearTimeout(t):this.connectionManager.send(_.CHAT_TYPING,{roomId:e,typing:!0});const s=setTimeout(()=>{this.stopTyping(e)},3e3);this._typingTimers.set(e,s)}stopTyping(e){this._clearTypingTimer(e),this.connectionManager.isConnected()&&this.connectionManager.send(_.CHAT_TYPING,{roomId:e,typing:!1})}_isSelfInMembers(e){return Array.isArray(e.members)&&e.members.some(e=>e&&e.userId===this.userId)}_handleTypingEvent(e,t){"ASSISTANT"!==t.senderType&&t.userId===this.userId||("ASSISTANT"===t.senderType&&!0===t.typing&&this._startAssistantTypingTimer(e),this.emit("typing",{roomId:e,userId:t.userId,userName:t.userName,typing:t.typing,senderType:t.senderType||"USER"}))}_startAssistantTypingTimer(e){this._clearAssistantTypingTimer(e);const t=setTimeout(()=>{this._assistantTypingTimers.delete(e),this.emit("typing",{roomId:e,userId:this._assistantTypingUserId,userName:this._assistantTypingUserName,typing:!1,senderType:"ASSISTANT"}),this.logger.debug(`Assistant typing auto-cleared (timeout): room=${e}`)},this._assistantTypingTimeoutMs);this._assistantTypingTimers.set(e,t)}_clearAssistantTypingTimer(e){const t=this._assistantTypingTimers.get(e);t&&(clearTimeout(t),this._assistantTypingTimers.delete(e))}_clearTypingTimer(e){const t=this._typingTimers.get(e);t&&(clearTimeout(t),this._typingTimers.delete(e))}_handleAssistantStreamEvent(e,t){if(!t||!t.type)return;const s=t.streamId||null;if(!s)return void this.logger.debug(`Assistant stream event without streamId ignored: room=${e}, type=${t.type}`);if(this._isAssistantStreamClosed(e,s))return void this.logger.debug(`Assistant event for closed stream ignored: room=${e}, stream=${s}, type=${t.type}`);const i=this._assistantSnapshotPending.get(e);if(i&&"DONE"!==t.type)i.events.push(t);else{if("PHASE"===t.type){const i=this._assistantSlot(e,s),n="number"==typeof t.createdAt?t.createdAt:null;if(i&&null!==n&&n<=(i.phaseUpdatedAt||0))return void this.logger.debug(`Stale assistant PHASE ignored: room=${e}, stream=${s}, createdAt=${n}, applied=${i.phaseUpdatedAt}`);const r=t.phase||null,o=Boolean(i&&i.phase===r),a=t.progress?this._normalizeAssistantProgress(t.progress):o&&i?i.progress:null,c=i,h=this._setAssistantSlot(e,s,t,{phase:r,progress:a,phaseUpdatedAt:null!==n?n:c?c.phaseUpdatedAt:0,text:c&&c.text||"",lastSeq:c?this._seqOf(c.lastSeq):-1,textAvailable:!c||!1!==c.textAvailable});return void this._emitAssistantStream(e,s,h,{active:!0,text:h.textAvailable&&h.text||null})}if("DELTA"===t.type){const i=this._assistantSlot(e,s),n=i&&i.phase||"WRITING",r="number"==typeof t.seq?t.seq:null;let o=i?this._seqOf(i.lastSeq):-1,a=!i||!1!==i.textAvailable,c=i&&i.text||"";if(null===r)a&&(c+=t.delta||"");else{if(r<=o)return void this.logger.debug(`Duplicate assistant DELTA ignored: room=${e}, stream=${s}, seq=${r}, lastSeq=${o}`);r===o+1?(a&&(c+=t.delta||""),o=r):(this.logger.debug(`Assistant DELTA gap — text dropped: room=${e}, stream=${s}, seq=${r}, lastSeq=${o}`),a=!1,c="",o=r)}const h=this._setAssistantSlot(e,s,t,{phase:n,progress:i&&i.progress||null,text:c,lastSeq:o,textAvailable:a});return void this._emitAssistantStream(e,s,h,{active:!0,text:h.textAvailable?h.text:null,delta:h.textAvailable&&t.delta||null,seq:r})}if("DONE"===t.type){const i=this._assistantSlot(e,s);i&&i.timer&&clearTimeout(i.timer),this._deleteAssistantSlot(e,s),this._tombstoneAssistantStream(e,s),this._emitAssistantStream(e,s,i,{active:!1,personaId:t.personaId||i&&i.personaId||null,phase:null,progress:null,label:null,status:t.status||null,messageId:t.messageId||null})}}}async _loadAssistantSnapshot(e,t){const s=this._assistantSnapshotInFlight.get(e);if(s&&s.generation===t)return s.task;const i=(async()=>{let s=null;try{const t=await this.apiClient.get(`/api/v1/rooms/${e}/assistant/streams`),i=this._unwrapSuccessResponse(t);s=i&&Array.isArray(i.streams)?i.streams:[]}catch(t){this.logger.warn(`Assistant stream snapshot failed (live-only fallback): room=${e}`,t)}if(this._assistantGeneration(e)!==t)return this.logger.debug(`Assistant snapshot discarded (stale generation): room=${e}`),void this._deleteAssistantPendingIfGeneration(e,t);s&&this._applyAssistantSnapshot(e,s),this._drainAssistantPending(e,t)})();this._assistantSnapshotInFlight.set(e,{generation:t,task:i});try{await i}finally{const s=this._assistantSnapshotInFlight.get(e);s&&s.generation===t&&this._assistantSnapshotInFlight.delete(e)}}_deleteAssistantPendingIfGeneration(e,t){const s=this._assistantSnapshotPending.get(e);s&&s.generation===t&&this._assistantSnapshotPending.delete(e)}_applyAssistantSnapshot(e,t){t.forEach(t=>{const s=t&&t.streamId;if(!s)return;if(this._isAssistantStreamClosed(e,s))return;if("DONE"===t.status)return this._tombstoneAssistantStream(e,s),void this._emitAssistantStream(e,s,null,{active:!1,phase:null,progress:null,label:null,personaId:t.personaId||null,status:t.doneStatus||null,messageId:t.messageId||null,resumed:!0});const i=!1!==t.textAvailable,n=this._setAssistantSlot(e,s,{personaId:t.personaId,expiresAt:void 0},{phase:t.phase||null,progress:this._normalizeAssistantProgress(t.progress),phaseUpdatedAt:"number"==typeof t.phaseUpdatedAt?t.phaseUpdatedAt:0,text:i&&t.text||"",lastSeq:this._seqOf(t.lastSeq),textAvailable:i,resumed:!0});this._emitAssistantStream(e,s,n,{active:!0,text:n.textAvailable&&n.text||null,resumed:!0})})}_drainAssistantPending(e,t){const s=this._assistantSnapshotPending.get(e);s&&(void 0!==t&&s.generation!==t||(this._assistantSnapshotPending.delete(e),s.events.forEach(t=>this._handleAssistantStreamEvent(e,t))))}_assistantGeneration(e){return this._assistantRoomGeneration.get(e)||0}_armAssistantSnapshot(e){const t=this._assistantGeneration(e)+1;this._assistantRoomGeneration.set(e,t);const s=this._assistantSnapshotPending.get(e);return this._assistantSnapshotPending.set(e,{generation:t,events:s?s.events:[]}),t}async resumeAssistantStreams(e="manual"){if(!this.assistantStreamReplay)return;const t=Array.from(this.subscribedRooms.keys());0!==t.length&&(this.logger.debug(`Assistant stream replay: rooms=${t.length}, reason=${e}`),await Promise.all(t.map(e=>{const t=this._armAssistantSnapshot(e);return this._loadAssistantSnapshot(e,t).catch(t=>this.logger.warn(`Assistant stream replay failed: room=${e}`,t))})))}_assistantSlots(e){let t=this._assistantProgress.get(e);return t||(t=new Map,this._assistantProgress.set(e,t)),t}_assistantSlot(e,t){const s=this._assistantProgress.get(e);return s?s.get(t):void 0}_deleteAssistantSlot(e,t){const s=this._assistantProgress.get(e);s&&(s.delete(t),0===s.size&&this._assistantProgress.delete(e))}_isAssistantStreamClosed(e,t){const s=this._assistantStreamTombstones.get(e);if(!s)return!1;const i=s.get(t);return void 0!==i&&(!(i<=Date.now())||(s.delete(t),!1))}_tombstoneAssistantStream(e,t){let s=this._assistantStreamTombstones.get(e);s||(s=new Map,this._assistantStreamTombstones.set(e,s));const i=Date.now();s.forEach((e,t)=>{e<=i&&s.delete(t)}),s.set(t,i+this._assistantTombstoneTtlMs),s.size>this._assistantTombstoneWarnThreshold?this._assistantTombstoneWarned.has(e)||(this._assistantTombstoneWarned.add(e),this.logger.warn(`Assistant tombstones above threshold — NOT pruning (TTL only): room=${e}, size=${s.size}, threshold=${this._assistantTombstoneWarnThreshold}`)):this._assistantTombstoneWarned.delete(e)}_handleSummaryEvent(e,t){t&&t.status&&this.emit("summaryUpdate",{roomId:e,status:t.status,format:t.format||null,languages:t.languages||null,updatedAt:t.updatedAt||null})}_seqOf(e){return"number"==typeof e?e:-1}_setAssistantSlot(e,t,s,i){const n=this._assistantSlot(e,t);n&&n.timer&&clearTimeout(n.timer);let r=this._assistantProgressFallbackTtlMs;"number"==typeof s.expiresAt&&(r=Math.min(12e4,Math.max(5e3,s.expiresAt-Date.now())));const o=setTimeout(()=>{this._expireAssistantStream(e,t)},r),a={personaId:s.personaId||n&&n.personaId||null,phase:i.phase,progress:i.progress||null,phaseUpdatedAt:void 0!==i.phaseUpdatedAt?i.phaseUpdatedAt:n&&n.phaseUpdatedAt||0,text:i.text||"",lastSeq:this._seqOf(i.lastSeq),textAvailable:!1!==i.textAvailable,resumed:!0===i.resumed||!!n&&!0===n.resumed,updatedAt:Date.now(),order:++this._assistantSlotSeq,timer:o};return this._assistantSlots(e).set(t,a),a}_expireAssistantStream(e,t){const s=this._assistantSlot(e,t);s&&(s.timer&&clearTimeout(s.timer),this._deleteAssistantSlot(e,t),this.logger.debug(`Assistant progress auto-cleared (timeout): room=${e}, stream=${t}`),this._emitAssistantStream(e,t,s,{active:!1,phase:null,progress:null,label:null,reason:"timeout"}))}_emitAssistantStream(e,t,s,i){const n="phase"in i?i.phase:s?s.phase:null,r="progress"in i?i.progress:s?s.progress:null;this.emit("assistantProgress",{roomId:e,streamId:t,personaId:s?s.personaId:null,phase:n,progress:r,label:this._assistantPhaseLabel(n,r),textAvailable:!s||s.textAvailable,lastSeq:s?s.lastSeq:-1,...i}),this._emitAssistantRoomProgress(e)}_emitAssistantRoomProgress(e){const{streams:t,...s}=this._assistantRoomProgressPayload(e);this.emit("assistantRoomProgress",s)}_assistantRoomProgressPayload(e){const t=this._assistantProgress.get(e),s=t?Array.from(t.entries()):[];if(0===s.length)return{roomId:e,active:!1,streamCount:0,streamId:null,personaId:null,phase:null,label:null,text:null,textAvailable:!0,progress:null,streams:[]};const[i,n]=s.reduce((e,t)=>t[1].order>e[1].order?t:e);return{roomId:e,active:!0,streamCount:s.length,streamId:i,personaId:n.personaId,phase:n.phase,progress:n.progress||null,label:this._assistantPhaseLabel(n.phase,n.progress),text:n.textAvailable&&n.text||null,textAvailable:n.textAvailable,streams:s.sort((e,t)=>e[1].order-t[1].order).map(([e,t])=>({streamId:e,personaId:t.personaId,phase:t.phase,progress:t.progress||null,label:this._assistantPhaseLabel(t.phase,t.progress),text:t.textAvailable&&t.text||null,textAvailable:t.textAvailable,resumed:!0===t.resumed}))}}_normalizeAssistantProgress(e){if(!e||!["ANALYZING","SUMMARIZING"].includes(e.stage))return null;if("SUMMARIZING"===e.stage)return{stage:"SUMMARIZING",current:null,total:null,unit:null};const t=Number.isInteger(e.current)?e.current:null,s=Number.isInteger(e.total)?e.total:null,i=["DOCUMENT","PAGE","TEXT_CHUNK"].includes(e.unit)?e.unit:null;return null===t||null===s||!i||t<0||s<1||t>s?null:{stage:"ANALYZING",current:t,total:s,unit:i}}_assistantPhaseLabel(e,t){if(!e)return null;if("DOCUMENT_ANALYSIS"!==e)return this._assistantPhaseLabels[e]||null;if(t&&"SUMMARIZING"===t.stage)return"분석 결과 종합 중…";if(!t||"ANALYZING"!==t.stage)return this._assistantPhaseLabels[e];const s="PAGE"===t.unit?"페이지":"TEXT_CHUNK"===t.unit?"구간":"개";return`문서 분석 중… (${t.current}/${t.total}${s})`}getAssistantProgress(e){return this._assistantRoomProgressPayload(e)}_clearAssistantProgress(e){const t=this._assistantProgress.get(e);t&&(t.forEach(e=>e.timer&&clearTimeout(e.timer)),this._assistantProgress.delete(e)),this._assistantStreamTombstones.delete(e),this._assistantTombstoneWarned.delete(e),this._assistantSnapshotPending.delete(e),this._assistantRoomGeneration.set(e,(this._assistantRoomGeneration.get(e)||0)+1)}getSubscribedRooms(){return Array.from(this.subscribedRooms.keys())}isSubscribed(e){return this.subscribedRooms.has(e)}setLogLevel(e){this.logger.setLevel(e)}_cancelDelayedReconnectSync(){this._reconnectSyncGeneration++,clearTimeout(this._delayedReconnectSyncTimer),this._delayedReconnectSyncTimer=null}destroy(){this._cancelDelayedReconnectSync(),this.connectionManager.off?.("stateChange",this._onStateChangeForSync),this.unsubscribeAllRooms(),this.roomListSubscribed&&this.unsubscribeRoomList(),this._typingTimers.forEach(e=>clearTimeout(e)),this._typingTimers.clear(),this._assistantTypingTimers.forEach(e=>clearTimeout(e)),this._assistantTypingTimers.clear(),this._assistantProgress.forEach(e=>e.forEach(e=>e.timer&&clearTimeout(e.timer))),this._assistantProgress.clear(),this._assistantStreamTombstones.clear(),this._assistantTombstoneWarned.clear(),this._assistantRoomGeneration.clear(),this._assistantSnapshotPending.clear(),this._assistantSnapshotInFlight.clear(),this._seenChatMessageIdsByRoom.clear(),this._seenRoomListMessageIdsByRoom.clear(),this.connectionManager&&"function"==typeof this.connectionManager.off&&(this._onReconnectedForSync&&this.connectionManager.off("reconnected",this._onReconnectedForSync),this._onResumedForSync&&this.connectionManager.off("resumed",this._onResumedForSync)),this._anchor.clear(),this._anchorGen.clear(),this._syncInFlight.clear(),this.removeAllListeners(),this.logger.info("ChatClient destroyed")}}class Qs extends e{constructor(e={}){super(),this.localStream=null,this.screenStream=null,this.videoEnabled=!0,this.audioEnabled=!0,this.logger=new S(e.logLevel||w.WARN,"MediaStreamManager"),this._deviceChangeHandler=null}async getUserMedia(e={video:!0,audio:!0}){try{return this.localStream=await navigator.mediaDevices.getUserMedia(e),this.videoEnabled=!1!==e.video,this.audioEnabled=!1!==e.audio,this.emit("streamStarted",{stream:this.localStream}),this.logger.info("User media stream started"),this.localStream}catch(e){throw this.logger.error("Failed to get user media:",e),this.emit("error",{type:s.MEDIA_ACCESS_DENIED,message:this._getMediaErrorMessage(e),error:e}),e}}_getMediaErrorMessage(e){switch(e.name){case"NotAllowedError":return"Camera/Microphone permission denied";case"NotFoundError":return"Camera/Microphone not found";case"NotReadableError":return"Camera/Microphone is already in use";case"OverconstrainedError":return"Camera/Microphone constraints cannot be satisfied";case"AbortError":return"Media access aborted";default:return e.message||"Unknown media error"}}async getDisplayMedia(e={video:!0,audio:!1}){try{return this.screenStream=await navigator.mediaDevices.getDisplayMedia(e),this.screenStream.getVideoTracks()[0].onended=()=>{this.emit("screenShareEnded",{}),this.screenStream=null},this.emit("screenShareStarted",{stream:this.screenStream}),this.logger.info("Screen share stream started"),this.screenStream}catch(e){throw this.logger.error("Failed to get display media:",e),this.emit("error",{type:s.SCREEN_SHARE_DENIED,message:"NotAllowedError"===e.name?"Screen share permission denied":e.message,error:e}),e}}toggleVideo(){if(!this.localStream)return this.logger.warn("No local stream available"),this.videoEnabled;const e=this.localStream.getVideoTracks();return 0===e.length?(this.logger.warn("No video track available"),this.videoEnabled):(this.videoEnabled=!this.videoEnabled,e.forEach(e=>{e.enabled=this.videoEnabled}),this.emit("videoToggled",{enabled:this.videoEnabled}),this.logger.debug(`Video toggled: ${this.videoEnabled}`),this.videoEnabled)}toggleAudio(){if(!this.localStream)return this.logger.warn("No local stream available"),this.audioEnabled;const e=this.localStream.getAudioTracks();return 0===e.length?(this.logger.warn("No audio track available"),this.audioEnabled):(this.audioEnabled=!this.audioEnabled,e.forEach(e=>{e.enabled=this.audioEnabled}),this.emit("audioToggled",{enabled:this.audioEnabled}),this.logger.debug(`Audio toggled: ${this.audioEnabled}`),this.audioEnabled)}setVideoEnabled(e){if(!this.localStream)return void this.logger.warn("No local stream available");this.localStream.getVideoTracks().forEach(t=>{t.enabled=e}),this.videoEnabled=e,this.emit("videoToggled",{enabled:e})}setAudioEnabled(e){if(!this.localStream)return void this.logger.warn("No local stream available");this.localStream.getAudioTracks().forEach(t=>{t.enabled=e}),this.audioEnabled=e,this.emit("audioToggled",{enabled:e})}getLocalStream(){return this.localStream}getScreenStream(){return this.screenStream}isVideoEnabled(){return this.videoEnabled}isAudioEnabled(){return this.audioEnabled}stopAll(){this.localStream&&(this.localStream.getTracks().forEach(e=>e.stop()),this.localStream=null,this.emit("streamStopped",{}),this.logger.info("All media tracks stopped")),this.screenStream&&(this.screenStream.getTracks().forEach(e=>e.stop()),this.screenStream=null)}replaceTrack(e,t){this.localStream?(this.localStream.removeTrack(e),this.localStream.addTrack(t),e.stop(),this.emit("trackReplaced",{oldTrack:e,newTrack:t}),this.logger.debug(`Track replaced: ${e.kind}`)):this.logger.warn("No local stream available")}getTrack(e){if(!this.localStream)return null;const t="video"===e?this.localStream.getVideoTracks():this.localStream.getAudioTracks();return t.length>0?t[0]:null}async getDevices(){try{const e=await navigator.mediaDevices.enumerateDevices();return{videoInputs:e.filter(e=>"videoinput"===e.kind),audioInputs:e.filter(e=>"audioinput"===e.kind),audioOutputs:e.filter(e=>"audiooutput"===e.kind)}}catch(e){throw this.logger.error("Failed to enumerate devices:",e),this.emit("error",{type:s.ENUMERATE_DEVICES_FAILED,message:e.message,error:e}),e}}async switchDevice(e,t){if(!this.localStream)throw new Error("No local stream available");try{const s="video"===t?{video:{deviceId:{exact:e}},audio:!1}:{video:!1,audio:{deviceId:{exact:e}}},i=(await navigator.mediaDevices.getUserMedia(s)).getTracks()[0],n="video"===t?this.localStream.getVideoTracks()[0]:this.localStream.getAudioTracks()[0];return n&&(this.replaceTrack(n,i),this.emit("deviceSwitched",{kind:t,deviceId:e,newTrack:i}),this.logger.info(`${t} device switched to ${e}`)),i}catch(e){throw this.logger.error(`Failed to switch ${t} device:`,e),this.emit("error",{type:s.DEVICE_SWITCH_FAILED,message:e.message,error:e}),e}}startDeviceChangeDetection(){this._deviceChangeHandler||(this._deviceChangeHandler=async()=>{try{const e=await this.getDevices();this.emit("deviceChange",e),this.logger.debug("Device change detected")}catch(e){this.logger.warn("Failed to get devices on change:",e)}},navigator.mediaDevices.addEventListener("devicechange",this._deviceChangeHandler),this.logger.debug("Device change detection started"))}stopDeviceChangeDetection(){this._deviceChangeHandler&&(navigator.mediaDevices.removeEventListener("devicechange",this._deviceChangeHandler),this._deviceChangeHandler=null,this.logger.debug("Device change detection stopped"))}getStreamInfo(){return this.localStream?{hasStream:!0,videoEnabled:this.videoEnabled,audioEnabled:this.audioEnabled,tracks:this.localStream.getTracks().map(e=>({kind:e.kind,id:e.id,label:e.label,enabled:e.enabled,readyState:e.readyState,muted:e.muted}))}:{hasStream:!1,videoEnabled:this.videoEnabled,audioEnabled:this.audioEnabled,tracks:[]}}async applyVideoConstraints(e){if(!this.localStream)throw new Error("No local stream available");const t=this.localStream.getVideoTracks()[0];if(!t)throw new Error("No video track available");try{await t.applyConstraints(e),this.emit("videoConstraintsApplied",{constraints:e}),this.logger.info("Video constraints applied:",e)}catch(e){throw this.logger.error("Failed to apply video constraints:",e),e}}getVideoSettings(){if(!this.localStream)return null;const e=this.localStream.getVideoTracks()[0];return e?e.getSettings():null}getAudioSettings(){if(!this.localStream)return null;const e=this.localStream.getAudioTracks()[0];return e?e.getSettings():null}setLogLevel(e){this.logger.setLevel(e)}destroy(){this.stopAll(),this.stopDeviceChangeDetection(),this.removeAllListeners(),this.logger.info("MediaStreamManager destroyed")}}class Zs extends e{constructor(e={}){super(),this.iceServers=e.iceServers||b.iceServers,this.logger=new S(e.logLevel||w.WARN,"PeerConnectionManager"),this.peers=new Map,this.localStream=null}setLocalStream(e){this.localStream=e,this.peers.forEach(e=>{this._addTracksToConnection(e.connection)})}setIceServers(e){this.iceServers=e}createPeerConnection(e,t=!1,s={}){if(this.peers.has(e))return this.logger.warn(`Peer connection already exists: ${e}`),this.peers.get(e).connection;const i={iceServers:this.iceServers,iceCandidatePoolSize:10},n=new RTCPeerConnection(i),r={connection:n,polite:t,makingOffer:!1,ignoreOffer:!1,isSettingRemoteAnswerPending:!1,skipAutoNegotiation:s.skipAutoNegotiation||!1};return this.peers.set(e,r),this._setupConnectionHandlers(e,n,r),this.localStream&&this._addTracksToConnection(n),this.logger.info(`Peer connection created: ${e} (polite: ${t}, skipAutoNegotiation: ${r.skipAutoNegotiation})`),n}async resumeAutoNegotiation(e){const t=this.peers.get(e);return!(!t||"stable"!==t.connection.signalingState)&&(t.skipAutoNegotiation=!1,await t.connection.onnegotiationneeded(),!0)}_setupConnectionHandlers(e,t,i){t.onicecandidate=t=>{t.candidate&&this.emit("iceCandidate",{peerId:e,candidate:t.candidate})},t.oniceconnectionstatechange=()=>{this.logger.debug(`ICE connection state (${e}): ${t.iceConnectionState}`),this.emit("iceConnectionStateChange",{peerId:e,state:t.iceConnectionState}),"failed"===t.iceConnectionState&&this.emit("error",{type:s.ICE_CONNECTION_FAILED,peerId:e,message:"ICE connection failed"})},t.onconnectionstatechange=()=>{this.logger.debug(`Connection state (${e}): ${t.connectionState}`),this.emit("connectionStateChange",{peerId:e,state:t.connectionState}),"connected"===t.connectionState?this.emit("peerConnected",{peerId:e}):"disconnected"!==t.connectionState&&"failed"!==t.connectionState||this.emit("peerDisconnected",{peerId:e})},t.onnegotiationneeded=async()=>{if(i.skipAutoNegotiation||i.makingOffer||"stable"!==t.signalingState)this.logger.debug(`Skipping auto negotiation for ${e} (manual offer will be sent)`);else try{i.makingOffer=!0,await t.setLocalDescription(),this.emit("negotiationNeeded",{peerId:e,description:t.localDescription})}catch(t){this.logger.error(`Negotiation error (${e}):`,t)}finally{i.makingOffer=!1}},t.ontrack=t=>{this.logger.info(`Remote track received from ${e}:`,t.track.kind),this.emit("remoteTrack",{peerId:e,track:t.track,streams:t.streams})},t.ondatachannel=t=>{this.logger.info(`Data channel received from ${e}`),this.emit("dataChannel",{peerId:e,channel:t.channel})}}_addTracksToConnection(e){if(!this.localStream)return;const t=e.getSenders();this.localStream.getTracks().forEach(s=>{t.find(e=>e.track&&e.track.kind===s.kind)||e.addTrack(s,this.localStream)})}async createOffer(e){const t=this.peers.get(e);if(!t)throw new Error(`Peer not found: ${e}`);try{const s=await t.connection.createOffer();return await t.connection.setLocalDescription(s),this.logger.debug(`Offer created for ${e}`),t.connection.localDescription}catch(t){throw this.logger.error(`Failed to create offer for ${e}:`,t),t}}async createAnswer(e){const t=this.peers.get(e);if(!t)throw new Error(`Peer not found: ${e}`);try{const s=await t.connection.createAnswer();return await t.connection.setLocalDescription(s),this.logger.debug(`Answer created for ${e}`),t.connection.localDescription}catch(t){throw this.logger.error(`Failed to create answer for ${e}:`,t),t}}async handleRemoteDescription(e,t){const s=this.peers.get(e);if(!s)throw new Error(`Peer not found: ${e}`);const{connection:i,polite:n,makingOffer:r}=s,o="offer"===t.type&&(r||"stable"!==i.signalingState);if(s.ignoreOffer=!n&&o,s.ignoreOffer)this.logger.debug(`Ignoring offer collision from ${e} (I am impolite)`);else try{if(o&&n&&(this.logger.debug(`Offer collision detected, rolling back local offer for ${e} (I am polite)`),await i.setLocalDescription({type:"rollback"})),s.isSettingRemoteAnswerPending="answer"===t.type,await i.setRemoteDescription(t),s.isSettingRemoteAnswerPending=!1,this.logger.debug(`Remote ${t.type} set for ${e}`),"offer"===t.type){const t=await this.createAnswer(e);this.emit("answerCreated",{peerId:e,answer:t})}}catch(t){throw this.logger.error(`Failed to set remote description for ${e}:`,t),t}}async addIceCandidate(e,t){const s=this.peers.get(e);if(!s)return this.logger.warn(`Peer not found for ICE candidate: ${e}`),!1;if(!s.connection.remoteDescription)return this.logger.debug(`Remote description not set yet for ${e}, ICE candidate queued`),!1;try{return await s.connection.addIceCandidate(t),this.logger.debug(`ICE candidate added for ${e}`),!0}catch(t){return s.ignoreOffer||this.logger.error(`Failed to add ICE candidate for ${e}:`,t),!1}}getPeerConnection(e){const t=this.peers.get(e);return t?t.connection:null}getPeerIds(){return Array.from(this.peers.keys())}closePeerConnection(e){const t=this.peers.get(e);t&&(t.connection.close(),this.peers.delete(e),this.emit("peerClosed",{peerId:e}),this.logger.info(`Peer connection closed: ${e}`))}closeAllPeerConnections(){this.peers.forEach((e,t)=>{e.connection.close(),this.logger.debug(`Peer connection closed: ${t}`)}),this.peers.clear(),this.emit("allPeersClosed",{})}async replaceTrack(e,t){const s=[];this.peers.forEach((i,n)=>{const r=i.connection.getSenders().find(t=>t.track&&t.track.kind===e.kind);r&&s.push(r.replaceTrack(t).then(()=>this.logger.debug(`Track replaced for ${n}`)).catch(e=>this.logger.error(`Failed to replace track for ${n}:`,e)))}),await Promise.all(s)}async getStats(e){const t=this.peers.get(e);return t?t.connection.getStats():null}getConnectionSummary(){const e={};return this.peers.forEach((t,s)=>{e[s]={connectionState:t.connection.connectionState,iceConnectionState:t.connection.iceConnectionState,signalingState:t.connection.signalingState,polite:t.polite}}),e}setLogLevel(e){this.logger.setLevel(e)}destroy(){this.closeAllPeerConnections(),this.localStream=null,this.removeAllListeners(),this.logger.info("PeerConnectionManager destroyed")}}const ei=new Set([i.CALL_REQUEST,i.CALL_ACCEPT,i.CALL_REJECT,i.CALL_CANCEL,i.CALL_BUSY]);class ti extends e{constructor(e){super(),this.connectionManager=e.connectionManager,this.apiClient=e.apiClient,this.userId=e.userId,this.logLevel=e.logLevel||w.WARN,this.logger=new S(this.logLevel,"WebRTCClient"),this.mediaManager=new Qs({logLevel:this.logLevel}),this.peerManager=new Zs({iceServers:e.iceServers||b.iceServers,logLevel:this.logLevel}),this.currentRoom=null,this.isGroupCall=!1,this.participants=new Map,this._callActive=!1,this._callGeneration=0,this._deferredGroupPeers=new Map,this._joinedGroupRoom=null,this._groupJoin=null,this._directCallPeer=null,this._incomingCallPeer=null,this._receivedInvitations=new Map,this._hostedCallRooms=new Map,this._pendingRoomCreations=0,this._earlyRoomRejects=[],this._groupRecoveryTimer=null,this._groupRecoveryAttempts=0,this._onReconnected=()=>{this._recoverGroupParticipation().catch(e=>this.logger.error("Call recovery failed:",e))},this.connectionManager.on?.("reconnected",this._onReconnected),this._iceServersFetched=!1,this._waitingForCallAccept=!1,this._pendingCallTarget=null,this._pendingIceCandidates=new Map,this._setupEventHandlers()}async initializeIceServers(){if(!this._iceServersFetched)try{const e=await this.getTurnCredentials();e&&e.iceServers&&(this.peerManager.setIceServers(e.iceServers),this._iceServersFetched=!0,this.logger.info("ICE servers fetched successfully"))}catch(e){this.logger.warn("Failed to fetch TURN credentials, using fallback ICE servers:",e.message),this._setFallbackIceServers()}}_setFallbackIceServers(){this.peerManager.setIceServers([{urls:"stun:stun.l.google.com:19302"},{urls:"stun:stun1.l.google.com:19302"}])}_setupEventHandlers(){this.mediaManager.on("streamStarted",e=>this.emit("localStreamStarted",e)),this.mediaManager.on("streamStopped",e=>this.emit("localStreamStopped",e)),this.mediaManager.on("videoToggled",()=>this._sendMediaState()),this.mediaManager.on("audioToggled",()=>this._sendMediaState()),this.mediaManager.on("screenShareStarted",e=>this.emit("screenShareStarted",e)),this.mediaManager.on("screenShareEnded",e=>this.emit("screenShareEnded",e)),this.mediaManager.on("error",e=>this.emit("error",e)),this.peerManager.on("remoteTrack",e=>this.emit("remoteTrack",e)),this.peerManager.on("peerConnected",e=>this.emit("peerConnected",e)),this.peerManager.on("peerDisconnected",e=>this.emit("peerDisconnected",e)),this.peerManager.on("peerClosed",e=>this.emit("peerClosed",e)),this.peerManager.on("error",e=>this.emit("error",e)),this.peerManager.on("iceCandidate",({peerId:e,candidate:t})=>{this._sendSignal({type:i.ICE_CANDIDATE,receiverId:e,data:{candidate:t}})}),this.peerManager.on("negotiationNeeded",({peerId:e,description:t})=>{this._sendSignal({type:i.CALL_OFFER,receiverId:e,data:{sdp:t}})}),this.peerManager.on("answerCreated",({peerId:e,answer:t})=>{this._sendSignal({type:i.CALL_ANSWER,receiverId:e,data:{sdp:t}})})}async getTurnCredentials(){return(await this.apiClient.get("/api/v1/webrtc/turn-credentials")).data}async createCallRoom(e){this._pendingRoomCreations++;try{const t=await this.apiClient.post("/api/v1/webrtc/rooms",e),s=t?.data?.callRoomId;return s&&this._rememberCallRoom(this._hostedCallRooms,s,this.userId),t}finally{this._pendingRoomCreations--;for(const e of this._earlyRoomRejects.splice(0))this._handleSignal(e).catch(e=>this.logger.error("Early rejection handling failed:",e))}}async getCallRoom(e){return this.apiClient.get(`/api/v1/webrtc/rooms/${e}`)}async joinCallRoomApi(e){const t={roomId:e,generation:this._callGeneration};this._groupJoin=t;try{const s=await this.apiClient.post(`/api/v1/webrtc/rooms/${e}/join`);return this._groupJoin===t&&this._callGeneration===t.generation&&(this._joinedGroupRoom=e),s}catch(s){throw this._groupJoin===t&&this.currentRoom!==e&&this._clearDeferredGroup(e),s}finally{this._groupJoin===t&&(this._groupJoin=null)}}async leaveCallRoomApi(e){const t=await this.apiClient.post(`/api/v1/webrtc/rooms/${e}/leave`);return this._joinedGroupRoom===e&&(this._joinedGroupRoom=null),this._groupJoin?.roomId===e&&(this._groupJoin=null),this.currentRoom!==e&&this._clearDeferredGroup(e),t}async enableIncomingCalls(){this._incomingCallsEnabled?this.logger.debug("Incoming calls already enabled"):(await this._subscribeToDirectSignaling(),this._incomingCallsEnabled=!0,this.logger.info("Incoming calls enabled - now listening for call invitations"))}disableIncomingCalls(){if(!this._incomingCallsEnabled)return;const e=_.getWebRTCUserDestination();this.connectionManager.unsubscribe(e),this._incomingCallsEnabled=!1,this.logger.info("Incoming calls disabled")}isIncomingCallsEnabled(){return this._incomingCallsEnabled||!1}async startCall(e){const{roomId:t,isGroup:n=!1,mediaConstraints:r={video:!0,audio:!0}}=e;if(this._pendingStart)throw new Error("A call is already starting");if(null!==this.currentRoom||this._callActive||this._waitingForCallAccept)throw new Error("A call is already active");this._callGeneration++,this._cancelGroupRecoveryRetry(),this._groupRecoveryAttempts=0,this._groupRecovery=null;const o={cancelled:!1};this._pendingStart=o;const a=()=>{if(o.cancelled)throw new Error("Call start cancelled")};try{this.currentRoom=t,this.isGroupCall=n;for(const e of new Set(this._deferredGroupPeers.values()))n&&e===t||this._clearDeferredGroup(e);await this._subscribeToSignaling(t,n),a(),await this.initializeIceServers(),a();const e=await this.mediaManager.getUserMedia(r);a(),this.peerManager.setLocalStream(e);for(const e of this._deferredGroupPeers.keys())await this._resumeGroupNegotiation(e),a();return this._callActive=!0,this._sendSignal({type:i.JOIN_ROOM,roomId:t}),this.logger.info(`Call started in room: ${t}`),this.emit("callStarted",{roomId:t,isGroup:n,localStream:e}),e}catch(e){throw n&&this.connectionManager.unsubscribe(_.getWebRTCDestination(t)),this._unsubscribeFromSignaling(),this.mediaManager.stopAll(),this.peerManager.closeAllPeerConnections(),this.peerManager.setLocalStream(null),this.participants.clear(),this._pendingIceCandidates.clear(),this._deferredGroupPeers.clear(),this._callActive=!1,this.currentRoom=null,this.isGroupCall=!1,this._joinedGroupRoom=null,this._groupJoin=null,this.logger.error("Failed to start call:",e),this.emit("error",{type:s.PEER_CONNECTION_FAILED,message:e.message,error:e}),e}finally{this._pendingStart=null}}async callUser(e,t={video:!0,audio:!0}){try{await this.initializeIceServers();const s=await this.mediaManager.getUserMedia(t);this.peerManager.setLocalStream(s),await this._subscribeToDirectSignaling(),this._callActive=!0,this._waitingForCallAccept=!0,this._pendingCallTarget=e,this._incomingCallPeer=null,this._sendSignal({type:i.CALL_REQUEST,receiverId:e}),this.currentRoom=null,this.isGroupCall=!1,this.emit("callRequested",{targetUserId:e,localStream:s})}catch(e){throw this.logger.error("Failed to call user:",e),this._waitingForCallAccept=!1,this._pendingCallTarget=null,e}}async acceptCall(e,t={video:!0,audio:!0}){try{await this.initializeIceServers();const s=await this.mediaManager.getUserMedia(t);this.peerManager.setLocalStream(s),this.peerManager.createPeerConnection(e,!0,{skipAutoNegotiation:!0}),this._directCallPeer=e,this._incomingCallPeer=null,this._sendSignal({type:i.CALL_ACCEPT,receiverId:e}),this._callActive=!0,this.emit("callAccepted",{callerId:e})}catch(e){throw this.logger.error("Failed to accept call:",e),e}}rejectCall(e){this._incomingCallPeer===e&&(this._incomingCallPeer=null),this._sendSignal({type:i.CALL_REJECT,receiverId:e}),this.emit("callRejected",{callerId:e})}cancelCall(){this._waitingForCallAccept&&this._pendingCallTarget&&(this._sendSignal({type:i.CALL_CANCEL,receiverId:this._pendingCallTarget}),this.emit("callCancelled",{targetUserId:this._pendingCallTarget}),this._waitingForCallAccept=!1,this._pendingCallTarget=null,this._callActive=!1,this.mediaManager.stopAll())}endCall(){this._endCall(!0)}_endCall(e){this._callGeneration++,this._cancelGroupRecoveryRetry(),this._groupRecoveryAttempts=0,this._groupRecovery=null,this._callActive=!1,this._deferredGroupPeers.clear(),this._joinedGroupRoom=null,this._groupJoin=null,this._incomingCallPeer=null,this._pendingStart&&(this._pendingStart.cancelled=!0),e&&this._waitingForCallAccept&&this._pendingCallTarget&&this._sendSignal({type:i.CALL_CANCEL,receiverId:this._pendingCallTarget}),this._waitingForCallAccept=!1,this._pendingCallTarget=null,this.currentRoom&&(e&&this._sendSignal({type:i.LEAVE_ROOM,roomId:this.currentRoom}),this._unsubscribeFromSignaling()),e&&this.peerManager.getPeerIds().forEach(e=>{this._sendSignal({type:i.CALL_END,receiverId:e})}),this._directCallPeer=null,this.peerManager.closeAllPeerConnections(),this.peerManager.setLocalStream(null),this.mediaManager.stopAll(),this.participants.clear(),this._pendingIceCandidates.clear();const t=this.currentRoom;this.currentRoom=null,this.isGroupCall=!1,this.emit("callEnded",{roomId:t}),this.logger.info("Call ended")}toggleVideo(){return this.mediaManager.toggleVideo()}toggleAudio(){return this.mediaManager.toggleAudio()}async startScreenShare(){const e=await this.mediaManager.getDisplayMedia(),t=e.getVideoTracks()[0],s=this.mediaManager.getTrack("video");return s&&t&&await this.peerManager.replaceTrack(s,t),t.onended=async()=>{const e=this.mediaManager.getTrack("video");e&&await this.peerManager.replaceTrack(t,e),this.emit("screenShareEnded",{})},e}stopScreenShare(){const e=this.mediaManager.getScreenStream();e&&e.getTracks().forEach(e=>e.stop())}getLocalStream(){return this.mediaManager.getLocalStream()}async getDevices(){return this.mediaManager.getDevices()}async switchDevice(e,t){const s=this.mediaManager.getTrack(t),i=await this.mediaManager.switchDevice(e,t);return s&&await this.peerManager.replaceTrack(s,i),i}setVideoEnabled(e){this.mediaManager.setVideoEnabled(e),this._sendMediaState()}setAudioEnabled(e){this.mediaManager.setAudioEnabled(e),this._sendMediaState()}startDeviceChangeDetection(){this.mediaManager.startDeviceChangeDetection(),this.mediaManager.on("deviceChange",e=>{this.emit("deviceChange",e)})}stopDeviceChangeDetection(){this.mediaManager.stopDeviceChangeDetection()}async applyVideoConstraints(e){return this.mediaManager.applyVideoConstraints(e)}getVideoSettings(){return this.mediaManager.getVideoSettings()}getAudioSettings(){return this.mediaManager.getAudioSettings()}async _subscribeToSignaling(e,t){if(t){const t=_.getWebRTCDestination(e);await this.connectionManager.subscribe(t,e=>{this._handleSignal(e)})}await this._subscribeToDirectSignaling()}async _subscribeToDirectSignaling(){const e=_.getWebRTCUserDestination();await this.connectionManager.subscribe(e,e=>{this._handleSignal(e)})}_unsubscribeFromSignaling(){if(this.currentRoom&&this.isGroupCall){const e=_.getWebRTCDestination(this.currentRoom);this.connectionManager.unsubscribe(e)}if(!this._incomingCallsEnabled){const e=_.getWebRTCUserDestination();this.connectionManager.unsubscribe(e)}}_sendSignal(e){const t={type:e.type,roomId:e.roomId||this._groupRoomFor(e),receiverId:e.receiverId,data:e.data};this.connectionManager.send(_.WEBRTC_SIGNAL,t),this.logger.debug("Signal sent:",t)}_groupRoomFor({type:e,receiverId:t}){if(!(ei.has(e)||t&&t===this._directCallPeer))return this.currentRoom||this._deferredGroupPeers.get(t)}_sendMediaState(){if(!this.currentRoom&&0===this.peerManager.getPeerIds().length)return;const e={videoEnabled:this.mediaManager.isVideoEnabled(),audioEnabled:this.mediaManager.isAudioEnabled()};this._sendSignal({type:i.VIDEO_STATE_CHANGED,data:e}),this.emit("mediaStateChanged",e)}async _handleSignal(e){const{type:t,senderId:s,data:n}=e;if(s!==this.userId&&!this._holdsEarlyRoomReject(e)&&this._acceptsSignal(e))switch(this.logger.debug(`Signal received: ${t} from ${s}`),t){case i.JOIN_ROOM:case i.PEER_JOINED:await this._handleUserJoined(s,e.roomId);break;case i.LEAVE_ROOM:case i.PEER_LEFT:this._handleUserLeft(s);break;case i.CALL_OFFER:await this._handleOffer(s,n.sdp,e.roomId);break;case i.CALL_ANSWER:await this._handleAnswer(s,n.sdp);break;case i.ICE_CANDIDATE:await this._handleIceCandidate(s,n.candidate);break;case i.VIDEO_STATE_CHANGED:case i.AUDIO_STATE_CHANGED:this._handleMediaState(s,n);break;case i.CALL_REQUEST:this.isInCall()||this._waitingForCallAccept?(this._sendSignal({type:i.CALL_BUSY,receiverId:s}),this.emit("incomingCallWhileBusy",{callerId:s})):(this._incomingCallPeer=s,this.emit("incomingCall",{callerId:s}));break;case i.CALL_BUSY:this._waitingForCallAccept=!1,this._pendingCallTarget=null,this._callActive=!1,this.mediaManager.stopAll(),this.emit("callBusy",{userId:s});break;case i.CALL_INVITATION:{const t=n?.callRoomId||e.roomId;e.roomId&&this._rememberCallRoom(this._receivedInvitations,e.roomId,s),this.emit("callInvitation",{callRoomId:t,title:n?.title,hostUserId:n?.hostUserId||s,maxParticipants:n?.maxParticipants,createdAt:n?.createdAt});break}case i.CALL_ACCEPT:await this._handleCallAccepted(s);break;case i.CALL_REJECT:if(e.roomId){this.emit("callRejected",{userId:s,roomId:e.roomId});break}this._waitingForCallAccept=!1,this._pendingCallTarget=null,this._callActive=!1,this.mediaManager.stopAll(),this.emit("callRejected",{userId:s});break;case i.CALL_CANCEL:if(e.roomId){this._receivedInvitations.delete(e.roomId),this.emit("callCancelled",{userId:s,roomId:e.roomId});break}this._incomingCallPeer=null,this._waitingForCallAccept=!1,this._pendingCallTarget=null,this.emit("callCancelled",{userId:s});break;case i.CALL_END:"ROOM"===n?.callEndScope?this._endCall(!1):this._handleCallEnded(s);break;default:this.logger.warn(`Unknown signal type: ${t}`)}}_acceptsSignal({type:e,senderId:t,roomId:s}){if(!t)return!1;if(e===i.CALL_INVITATION)return!0;if(e===i.CALL_REQUEST)return!s;if(s&&e===i.CALL_REJECT)return this._hostedCallRooms.has(s);if(s&&e===i.CALL_CANCEL)return this._receivedInvitations.get(s)===t;if([i.CALL_ACCEPT,i.CALL_BUSY,i.CALL_REJECT].includes(e))return!s&&this._waitingForCallAccept&&t===this._pendingCallTarget;if(e===i.CALL_CANCEL)return!s&&t===this._incomingCallPeer;if(!s&&t===this._directCallPeer)return!0;const n=this.isGroupCall?this.currentRoom:this._callActive||this._waitingForCallAccept?null:this._groupJoin?.roomId||this._joinedGroupRoom;return n?s===n:!s&&t===this._pendingCallTarget}_holdsEarlyRoomReject(e){const{type:t,roomId:s}=e;return!(t!==i.CALL_REJECT||!s||0===this._pendingRoomCreations||this._hostedCallRooms.has(s))&&(this._earlyRoomRejects.push(e),this._earlyRoomRejects.length>32&&this._earlyRoomRejects.shift(),!0)}_rememberCallRoom(e,t,s){e.delete(t),e.set(t,s),e.size>32&&e.delete(e.keys().next().value)}_clearDeferredGroup(e){for(const[t,s]of this._deferredGroupPeers)s===e&&(this.peerManager.closePeerConnection(t),this.participants.delete(t),this._pendingIceCandidates.delete(t),this._deferredGroupPeers.delete(t))}async _handleUserJoined(e,t){this.participants.set(e,{joinedAt:new Date});const s=this.userId<e,i=!!t&&!this.peerManager.localStream;this.peerManager.createPeerConnection(e,s,{skipAutoNegotiation:i}),i&&this._deferredGroupPeers.set(e,t),this.emit("userJoined",{userId:e}),this.logger.info(`User joined: ${e} (I am ${s?"polite":"impolite"})`)}_handleUserLeft(e){this.participants.delete(e),this.peerManager.closePeerConnection(e),this.emit("userLeft",{userId:e}),this.logger.info(`User left: ${e}`)}async _handleOffer(e,t,s=(this.isGroupCall?this.currentRoom:null)){if(!this.peerManager.getPeerConnection(e)){const t=this.userId<e;this.peerManager.createPeerConnection(e,t,{skipAutoNegotiation:!0}),s&&!this.peerManager.localStream&&this._deferredGroupPeers.set(e,s)}await this.peerManager.handleRemoteDescription(e,t),await this._resumeGroupNegotiation(e),await this._processPendingIceCandidates(e)}async _resumeGroupNegotiation(e){this.isGroupCall&&this._deferredGroupPeers.get(e)===this.currentRoom&&this.peerManager.localStream&&await this.peerManager.resumeAutoNegotiation(e)&&this._deferredGroupPeers.delete(e)}async _recoverGroupParticipation(){if(!this.isGroupCall||!this.currentRoom||this._groupRecovery)return;this._cancelGroupRecoveryRetry();const e=this.currentRoom,t=this._callGeneration,s=()=>this.currentRoom===e&&this._callGeneration===t,n=(async()=>{try{const t=await this.apiClient.get(`/api/v1/webrtc/rooms/${e}/participation`);if(!s())return;if(!t.data.participating){if(await this.joinCallRoomApi(e),!s())return;this._sendSignal({type:i.JOIN_ROOM,roomId:e})}this._groupRecoveryAttempts=0}catch(t){if(!s())return;if([403,404,409].includes(t?.status??t?.response?.status))this._endCall(!1),this.emit("callRecoveryFailed",{roomId:e,error:t});else{const e=Math.min(3e4,1e3*2**Math.min(this._groupRecoveryAttempts++,5));this._groupRecoveryTimer=setTimeout(()=>{this._groupRecoveryTimer=null,s()&&this._onReconnected()},e),this._groupRecoveryTimer.unref?.(),this.logger.warn("Call participation recovery will retry:",t)}}})();this._groupRecovery=n;try{await n}finally{this._groupRecovery===n&&(this._groupRecovery=null)}}_cancelGroupRecoveryRetry(){clearTimeout(this._groupRecoveryTimer),this._groupRecoveryTimer=null}async _handleAnswer(e,t){await this.peerManager.handleRemoteDescription(e,t),await this._processPendingIceCandidates(e)}async _handleIceCandidate(e,t){if(!this.peerManager.getPeerConnection(e))return void this._queueIceCandidate(e,t);await this.peerManager.addIceCandidate(e,new RTCIceCandidate(t))||this._queueIceCandidate(e,t)}_queueIceCandidate(e,t){this._pendingIceCandidates.has(e)||this._pendingIceCandidates.set(e,[]),this._pendingIceCandidates.get(e).push(t),this.logger.debug(`ICE candidate queued for ${e}`)}async _processPendingIceCandidates(e){const t=this._pendingIceCandidates.get(e);if(t&&0!==t.length){this.logger.debug(`Processing ${t.length} pending ICE candidates for ${e}`);for(const s of t)await this.peerManager.addIceCandidate(e,new RTCIceCandidate(s));this._pendingIceCandidates.delete(e)}}_handleMediaState(e,t){this.emit("participantMediaState",{userId:e,videoEnabled:t.videoEnabled,audioEnabled:t.audioEnabled})}async _handleCallAccepted(e){this._directCallPeer=e,this._waitingForCallAccept=!1,this._pendingCallTarget=null,this.peerManager.createPeerConnection(e,!1,{skipAutoNegotiation:!0});const t=await this.peerManager.createOffer(e);this._sendSignal({type:i.CALL_OFFER,receiverId:e,data:{sdp:t}}),this.emit("callAccepted",{userId:e})}_handleCallEnded(e){this.peerManager.closePeerConnection(e),this.participants.delete(e),e===this._directCallPeer&&(this._directCallPeer=null),this.emit("participantLeft",{userId:e}),0===this.peerManager.getPeerIds().length&&this.endCall()}isInCall(){return null!==this.currentRoom||this.peerManager.getPeerIds().length>0}getCurrentRoom(){return this.currentRoom}getParticipants(){return Array.from(this.participants.keys())}getConnectionSummary(){return this.peerManager.getConnectionSummary()}async getStats(e){return this.peerManager.getStats(e)}getMediaState(){return{videoEnabled:this.mediaManager.isVideoEnabled(),audioEnabled:this.mediaManager.isAudioEnabled(),streamInfo:this.mediaManager.getStreamInfo()}}setLogLevel(e){this.logger.setLevel(e),this.mediaManager.setLogLevel(e),this.peerManager.setLogLevel(e)}destroy(){this.connectionManager.off?.("reconnected",this._onReconnected),this.endCall(),this.mediaManager.destroy(),this.peerManager.destroy(),this.removeAllListeners(),this.logger.info("WebRTCClient destroyed")}}const si=Object.freeze({UNSUPPORTED_BROWSER:"UNSUPPORTED_BROWSER",FIREBASE_NOT_INSTALLED:"FIREBASE_NOT_INSTALLED",SW_REGISTER_FAILED:"SW_REGISTER_FAILED",PERMISSION_DENIED:"PERMISSION_DENIED",TOKEN_FAILED:"TOKEN_FAILED",SERVER_REGISTER_FAILED:"SERVER_REGISTER_FAILED"});class ii extends Error{constructor(e,t,s){super(t),this.name="PushError",this.code=e,void 0!==s&&(this.cause=s)}}const ni={apiKey:"AIzaSyB8VhRg6rSvUI7K3Ua7h6sBpLvaQGmIkRc",authDomain:"chatting-c3e5d.firebaseapp.com",projectId:"chatting-c3e5d",storageBucket:"chatting-c3e5d.firebasestorage.app",messagingSenderId:"1020496565673",appId:"1:1020496565673:web:5039167257fd83f5ce20b8"},ri="pendingNavigation",oi="pending-room",ai="deviceInfo",ci="device-id",hi="talkflow_device_id";function li(){return"undefined"==typeof indexedDB?Promise.resolve(null):new Promise((e,t)=>{const s=indexedDB.open("talkflowPush",2);s.onupgradeneeded=()=>{const e=s.result;e.objectStoreNames.contains(ri)||e.createObjectStore(ri,{keyPath:"id"}),e.objectStoreNames.contains(ai)||e.createObjectStore(ai,{keyPath:"id"})},s.onsuccess=()=>e(s.result),s.onerror=()=>t(s.error||new Error("IndexedDB open failed"))})}function di(){return li().then(e=>e?new Promise((t,s)=>{const i=e.transaction(ai,"readonly"),n=i.objectStore(ai).get(ci);n.onsuccess=()=>{const e=n.result;t(e&&e.value?e.value:null)},n.onerror=()=>s(n.error||new Error("IndexedDB read failed")),i.oncomplete=()=>e.close(),i.onerror=()=>e.close(),i.onabort=()=>e.close()}):null)}function ui(e){return li().then(t=>!!t&&new Promise(s=>{try{const i=t.transaction(ai,"readwrite");i.objectStore(ai).put({id:ci,value:e}),i.oncomplete=()=>{t.close(),s(!0)},i.onerror=()=>{t.close(),s(!1)},i.onabort=()=>{t.close(),s(!1)}}catch(e){try{t.close()}catch(e){}s(!1)}})).catch(()=>!1)}function pi(){return"web-"+("undefined"!=typeof crypto&&crypto.randomUUID?crypto.randomUUID():Date.now().toString(36)+Math.random().toString(36).substring(2))}async function gi(e){const t=await li();if(!t)return null;const s=function(e){return e&&"string"==typeof e&&""!==e.trim()?"pending-room:"+e:oi}(e),i=!!e&&s!==oi;return new Promise((n,r)=>{const o=t.transaction(ri,"readwrite"),a=o.objectStore(ri);let c=null;const h=a.get(s);h.onsuccess=()=>{const t=h.result;if(t&&t.roomId){if((t.projectId||null)===(e||null))return c=t.roomId,void a.delete(s)}if(!i)return;const n=a.get(oi);n.onsuccess=()=>{const e=n.result;e&&e.roomId&&!e.projectId&&(c=e.roomId,a.delete(oi))}},h.onerror=()=>{r(h.error||new Error("IndexedDB read failed"))},o.oncomplete=()=>{t.close(),n(c)},o.onerror=()=>{t.close(),r(o.error||new Error("IndexedDB transaction failed"))},o.onabort=()=>{t.close(),r(o.error||new Error("IndexedDB transaction aborted"))}})}class mi{constructor(e){this.apiClient=e.apiClient,this.projectId=e.projectId||null,this.firebaseConfig=e.firebaseConfig||ni,this.vapidKey=e.vapidKey||"BGP8qaSm1ntjWd4n9pc0lX_rw4BmMxm9u4pvRIANCitbmYaV0iy-gn05suTKBo88kUBejxdxM8sb6x2nt3avu8c",this.serviceWorkerPath=e.serviceWorkerPath||"/firebase-messaging-sw.js",this.logger=new S(e.logLevel||w.WARN,"PushManager"),this._messaging=null,this._currentToken=null,this._enabled=!1,this._enablePromise=null,this._foregroundMessageUnsubscribe=null,this._swRegistration=null,this._projectRegisteredToSW=!1,this._visibilityHandler=null,this._deviceIdCache=null}static async consumePendingRoom(e){return gi(e)}static async consumePendingMail(e){return async function(e){if(!e||"string"!=typeof e||""===e.trim())return null;const t=await li();if(!t)return null;const s="pending-mail:"+e;return new Promise((i,n)=>{const r=t.transaction(ri,"readwrite"),o=r.objectStore(ri);let a=null;const c=o.get(s);c.onsuccess=()=>{const t=c.result;t&&(o.delete(s),"number"==typeof t.savedAt&&Date.now()-t.savedAt<=6e5&&t.projectId===e&&t.connectionId&&(a={connectionId:t.connectionId,messageId:t.messageId||null}))},c.onerror=()=>{n(c.error||new Error("IndexedDB read failed"))},r.oncomplete=()=>{t.close(),i(a)},r.onerror=()=>{t.close(),n(r.error||new Error("IndexedDB transaction failed"))},r.onabort=()=>{t.close(),n(r.error||new Error("IndexedDB transaction aborted"))}})}(e)}static getPermissionState(){return"undefined"==typeof window||"undefined"==typeof Notification?"unsupported":"undefined"!=typeof navigator&&"serviceWorker"in navigator?Notification.permission:"unsupported"}async enable(){if(this._enabled)this.logger.debug("푸시 알림이 이미 활성화되어 있습니다.");else{if(this._enablePromise)return this.logger.debug("푸시 알림 활성화가 이미 진행 중입니다."),this._enablePromise;this._enablePromise=this._enableInternal();try{return await this._enablePromise}finally{this._enablePromise=null}}}async _enableInternal(){if("undefined"==typeof window||!("Notification"in window))throw new ii(si.UNSUPPORTED_BROWSER,"푸시 알림은 브라우저 환경에서만 사용 가능합니다");if(!("serviceWorker"in navigator))throw new ii(si.UNSUPPORTED_BROWSER,"이 브라우저는 서비스 워커를 지원하지 않습니다");if("denied"===Notification.permission)throw new ii(si.PERMISSION_DENIED,"알림 권한이 이미 거부되어 있습니다. 브라우저 사이트 설정에서 허용해주세요.");let e,t,s;try{e=await import("firebase/app"),t=await import("firebase/messaging")}catch(e){throw new ii(si.FIREBASE_NOT_INSTALLED,"firebase 패키지가 설치되지 않았습니다. npm install firebase 를 실행하세요.",e)}try{s=e.getApp("talkflow")}catch{s=e.initializeApp(this.firebaseConfig,"talkflow")}const i=await this._registerServiceWorker();if("granted"!==("granted"===Notification.permission?"granted":await Notification.requestPermission()))throw new ii(si.PERMISSION_DENIED,"알림 권한이 거부되었습니다. 브라우저 설정에서 허용해주세요.");this._messaging=t.getMessaging(s);const n={serviceWorkerRegistration:i};this.vapidKey&&(n.vapidKey=this.vapidKey);try{this._currentToken=await t.getToken(this._messaging,n)}catch(e){throw new ii(si.TOKEN_FAILED,"FCM 토큰 획득 중 오류 발생: "+(e?.message||e),e)}if(!this._currentToken)throw new ii(si.TOKEN_FAILED,"FCM 토큰 획득 실패 (응답이 비어있음)");await this._registerTokenToServer(this._currentToken),this._foregroundMessageUnsubscribe&&this._foregroundMessageUnsubscribe(),this._foregroundMessageUnsubscribe=t.onMessage(this._messaging,e=>{this.logger.debug("포그라운드 푸시 수신:",e),this._onForegroundMessage(e)}),this._swRegistration=i,await this._registerProjectToSW(),this._installVisibilityReRegister();try{await i.update()}catch(e){this.logger.debug("SW 업데이트 체크 실패 (무시):",e.message)}const r=await this._getSWVersion(i);r?this.logger.debug("SW 버전:",r):this.logger.warn("[TalkFlow] 서비스 워커가 구버전(v1)입니다. 이미지 미리보기 등 리치 알림 기능을 사용하려면 firebase-messaging-sw.js 를 v2 로 업데이트하세요. 가이드: https://docs.talkflow.ai/push/sw-upgrade"),this._enabled=!0,this.logger.info("푸시 알림 활성화 완료")}async _registerServiceWorker(){try{const e=await navigator.serviceWorker.register(this.serviceWorkerPath,{updateViaCache:"none"});return this.logger.debug("서비스 워커 등록 완료:",this.serviceWorkerPath),e}catch(e){throw new ii(si.SW_REGISTER_FAILED,`서비스 워커 등록 실패: ${this.serviceWorkerPath}\n프로젝트 public 폴더에 firebase-messaging-sw.js 파일을 배치하세요.`,e)}}async _registerTokenToServer(e){try{const t=await this._getDeviceId();this.apiClient?.authProvider?.setDeviceId(t),await this.apiClient.post("/api/v1/push/devices",{deviceToken:e,deviceType:"WEB",deviceId:t}),this.logger.info("디바이스 토큰 서버 등록 완료")}catch(e){if(this.logger.error("디바이스 토큰 서버 등록 실패:",e),e instanceof ii)throw e;throw new ii(si.SERVER_REGISTER_FAILED,"디바이스 토큰 서버 등록 실패: "+(e?.message||e),e)}}async _getDeviceId(){if(this._deviceIdCache)return this._deviceIdCache;try{let e=await di();if(!e&&"undefined"!=typeof localStorage){const t=localStorage.getItem(hi);if(t){e=t;if(await ui(e)){if(await di()===e)try{localStorage.removeItem(hi),this.logger.debug("deviceId migrated from localStorage to IndexedDB")}catch(e){}else this.logger.warn("deviceId IDB read-back 불일치, localStorage 보존")}else this.logger.warn("deviceId IDB 저장 실패 (private mode / quota 등), localStorage 보존")}}if(!e){e=pi();await ui(e)||this.logger.warn("신규 deviceId IDB 저장 실패, 이번 세션만 유효")}return this._deviceIdCache=e,this.apiClient?.authProvider?.setDeviceId(e),e}catch(e){if(this.logger.warn("IndexedDB deviceId 조회/저장 실패, fallback:",e),!this._deviceIdCache){let e=null;if("undefined"!=typeof localStorage)try{e=localStorage.getItem(hi)}catch(e){}this._deviceIdCache=e||pi()}return this._deviceIdCache}}_onForegroundMessage(e){}async consumePendingRoom(){return mi.consumePendingRoom(this.projectId)}async consumePendingMail(){return mi.consumePendingMail(this.projectId)}reset(){if(this._foregroundMessageUnsubscribe)try{this._foregroundMessageUnsubscribe()}catch(e){this.logger.debug("포그라운드 푸시 리스너 해제 실패 (무시):",e?.message||e)}this._uninstallVisibilityReRegister(),this._unregisterProjectFromSW(),this._foregroundMessageUnsubscribe=null,this._enablePromise=null,this._messaging=null,this._currentToken=null,this._enabled=!1,this._swRegistration=null,this._projectRegisteredToSW=!1}async _registerProjectToSW(){if(this.projectId)try{const e=(await navigator.serviceWorker.ready).active||this._swRegistration&&this._swRegistration.active;if(!e)return void this.logger.debug("SW active worker 없음 — projectId 등록 스킵");e.postMessage({type:"TALKFLOW_REGISTER_PROJECT",projectId:this.projectId}),this._projectRegisteredToSW=!0}catch(e){this.logger.debug("SW projectId 등록 실패 (무시):",e?.message||e)}}_unregisterProjectFromSW(){if(this._projectRegisteredToSW)try{if("undefined"==typeof navigator||!navigator.serviceWorker)return;const e=navigator.serviceWorker.controller;if(!e)return;e.postMessage({type:"TALKFLOW_UNREGISTER_PROJECT"})}catch(e){this.logger.debug("SW projectId 해제 실패 (무시):",e?.message||e)}}_installVisibilityReRegister(){"undefined"==typeof document||this._visibilityHandler||(this._visibilityHandler=()=>{"visible"===document.visibilityState&&this._enabled&&this.projectId&&this._registerProjectToSW().catch(()=>{})},document.addEventListener("visibilitychange",this._visibilityHandler))}_uninstallVisibilityReRegister(){if("undefined"!=typeof document&&this._visibilityHandler){try{document.removeEventListener("visibilitychange",this._visibilityHandler)}catch(e){}this._visibilityHandler=null}}getToken(){return this._currentToken}isEnabled(){return this._enabled}async getMyDevices(){const e=await this.apiClient.get("/api/v1/push/devices/me");return e&&"object"==typeof e&&"data"in e?e.data:e}async setDeviceEnabled(e,t){await this.apiClient.patch("/api/v1/push/devices/me/enabled",{deviceId:e,enabled:t}),this.logger.info(`디바이스 푸시 enabled=${t}: deviceId=${e}`)}async setCurrentDeviceEnabled(e){const t=await this._getDeviceId();await this.setDeviceEnabled(t,e)}async _getSWVersion(e){try{const t=await navigator.serviceWorker.ready,s=t.waiting||t.installing||t.active||e.waiting||e.installing||e.active;return s?new Promise(e=>{const t=setTimeout(()=>e(null),2e3),i=new MessageChannel;i.port1.onmessage=s=>{clearTimeout(t),e(s.data?.version||null)};try{s.postMessage({type:"TALKFLOW_SW_VERSION"},[i.port2])}catch(s){clearTimeout(t),e(null)}}):null}catch{return null}}setLogLevel(e){this.logger.setLevel(e)}}function _i(e){return e._mailNotificationDeduper||(e._mailNotificationDeduper=function({ttlMs:e=36e5,max:t=1e3,now:s=()=>Date.now()}={}){const i=new Map;return{accept(n){const r=s();for(const[t,s]of i){if(r-s<e)break;i.delete(t)}if(i.has(n))return!1;for(i.set(n,r);i.size>t;)i.delete(i.keys().next().value);return!0},size:()=>i.size}}()),e._mailNotificationDeduper}function fi(e){return e.options&&e.options.projectId||null}function yi(e,t,s){return`${e||""}:${t}:${s}`}function bi(e){return e&&"object"==typeof e?"string"==typeof e.name&&""!==e.name.trim()?e.name:e.email||null:null}const vi=[["connected","connected"],["disconnected","disconnected"],["reconnecting","reconnecting"],["reconnected","reconnected"],["resumed","resumed"],["subscriptionRequired","subscriptionRequired"],["error","connectionError"]],wi=[["syncStarted","syncStarted"],["syncCompleted","syncCompleted"],["gapTruncated","gapTruncated"],["roomListSynced","roomListSynced"],["message","chatMessage"],["newMessage","newChatMessage"],["messageUpdated","messageUpdated"],["messageDeleted","messageDeleted"],["reactionChanged","reactionChanged"],["linkPreviewAttached","linkPreviewAttached"],["messageTranslated","messageTranslated"],["messageRead","messageRead"],["typing","typing"],["assistantProgress","assistantProgress"],["assistantRoomProgress","assistantRoomProgress"],["summaryUpdate","summaryUpdate"],["memberJoined","memberJoined"],["memberLeft","memberLeft"],["roomSubscribed","roomSubscribed"],["roomUnsubscribed","roomUnsubscribed"],["roomListSubscribed","roomListSubscribed"],["roomListUnsubscribed","roomListUnsubscribed"],["roomListUpdate","roomListUpdate"],["roomListMessage","roomListMessage"],["roomListMessageDeleted","roomListMessageDeleted"],["roomListMessageUpdated","roomListMessageUpdated"],["roomListCreated","roomListCreated"],["roomListJoined","roomListJoined"],["roomListLeft","roomListLeft"],["roomListSelfLeft","roomListSelfLeft"],["roomListKicked","roomListKicked"],["roomListSelfKicked","roomListSelfKicked"],["roomListBanned","roomListBanned"],["roomListSelfBanned","roomListSelfBanned"],["roomListOwnerChanged","roomListOwnerChanged"],["roomListDeleted","roomListDeleted"],["roomListRoomUpdated","roomListRoomUpdated"],["roomListUnreadUpdated","roomListUnreadUpdated"],["aiUnavailable","aiUnavailable"],["mailSubscribed","mailSubscribed"],["mailUnsubscribed","mailUnsubscribed"],["mailChanged","mailChanged"],["retentionCleanup","retentionCleanup"]],Si=[["localStreamStarted","localStreamStarted"],["localStreamStopped","localStreamStopped"],["remoteTrack","remoteTrack"],["screenShareStarted","screenShareStarted"],["screenShareEnded","screenShareEnded"],["deviceChange","deviceChange"],["mediaStateChanged","mediaStateChanged"],["callStarted","callStarted"],["callEnded","callEnded"],["callRecoveryFailed","callRecoveryFailed"],["callRequested","callRequested"],["callAccepted","callAccepted"],["callRejected","callRejected"],["callCancelled","callCancelled"],["callBusy","callBusy"],["incomingCall","incomingCall"],["incomingCallWhileBusy","incomingCallWhileBusy"],["callInvitation","callInvitation"],["userJoined","userJoined"],["userLeft","userLeft"],["participantLeft","participantLeft"],["participantMediaState","participantMediaState"],["peerConnected","peerConnected"],["peerDisconnected","peerDisconnected"],["peerClosed","peerClosed"],["error","webrtcError"]];function Ei(e,t,s){s.forEach(([s,i])=>{e.on(s,e=>{t.emit(i,e)})})}function Ii(e){e.connectionManager&&(e.connectionManager.on("stateChange",({state:t,prevState:s})=>{e._state=t,e.emit("stateChange",{state:t,prevState:s})}),Ei(e.connectionManager,e,vi),e.chat&&(Ei(e.chat,e,wi),e.chat.on("mailChanged",t=>function(e,t){if(!t||"MAIL_CHANGED"!==t.eventType||!Array.isArray(t.messages)||!t.connectionId)return;const s=fi(e),i=_i(e);for(const n of t.messages)n&&n.messageId&&i.accept(yi(s,t.connectionId,n.messageId))&&e.emit("newMail",{projectId:s,connectionId:t.connectionId,messageId:n.messageId,threadId:n.threadId||null,sender:bi(n.from),from:n.from||null,subject:n.subject||null,receivedAt:n.receivedAt||null,source:"socket"})}(e,t))),e.webrtc&&Ei(e.webrtc,e,Si))}const Ti=["getRooms","getRoom","getRoomInfo","setMyRoomLanguage","createOneToOneRoom","createGroupRoom","joinGroupRoom","leaveRoom","transferOwnership","deleteRoom","updateGroupRoom","inviteToGroupRoom","kickMember","banMember","unbanMember","getBannedMembers","getAvailableGroupRooms","getAllGroupRooms","enterRoom","getMessages","fetchLinkPreview","sendMessage","sendMessageOptimistic","sendTextMessage","sendTextMessageOptimistic","sendReply","sendReplyOptimistic","sendDecisionChoice","uploadFile","sendFileMessage","sendFileMessageOptimistic","classifyFileType","resolveMessageCategory","editMessage","deleteMessage","markAsRead","pinMessage","unpinMessage","toggleReaction","subscribeRoom","unsubscribeRoom","unsubscribeAllRooms","setActiveRoom","clearActiveRoom","getActiveRoom","subscribeRoomList","unsubscribeRoomList","isRoomListSubscribed","subscribeMail","unsubscribeMail","isMailSubscribed","getSubscribedRooms","isSubscribed","startTyping","stopTyping","getAssistantProgress","resumeAssistantStreams","getAssistants","getRoomAiMeta","rateAssistantMessage","summarizeWithAssistant","translateWithAssistant","uploadVideoAsset","analyzeVideo","analyzeVideoWithAssistant","getVideoAnalysis","cancelVideoAnalysis","getVideoAnalysisCapabilities","refreshSummary","getSummary","getRoomPmPrompt","upsertRoomPmPrompt","activateRoomPmPrompt","deactivateRoomPmPrompt","getRoomPmPromptVersions","activateRoomPmPromptVersion","previewRoomPmPrompt","createVote","getVotes","getVote","updateVote","deleteVote","closeVote","submitVote","uploadVoteImage"],Ri=["initializeIceServers","getTurnCredentials","createCallRoom","getCallRoom","joinCallRoomApi","leaveCallRoomApi","enableIncomingCalls","disableIncomingCalls","isIncomingCallsEnabled","startCall","callUser","acceptCall","rejectCall","cancelCall","endCall","toggleVideo","toggleAudio","setVideoEnabled","setAudioEnabled","startScreenShare","stopScreenShare","getLocalStream","getDevices","switchDevice","startDeviceChangeDetection","stopDeviceChangeDetection","applyVideoConstraints","getVideoSettings","getAudioSettings","isInCall","getCurrentRoom","getParticipants","getMediaState","getConnectionSummary","getStats"];function Ci(e,t,s){s.forEach(s=>{e[s]=function(...e){return this[t][s](...e)}})}class Ai extends e{constructor(e){super(),this._validateOptions(e);const s=e.env||b.environment,i=(e.serverUrl||v(s)).replace(/\/$/,"");this.options={serverUrl:i,env:s,apiKey:e.apiKey,projectId:e.projectId,jwtToken:e.jwtToken||null,sessionMode:e.sessionMode||(C(e.jwtToken||"").sid?"refresh":"legacy"),useSockJS:!1!==e.useSockJS,reconnectDelay:e.reconnectDelay||b.reconnectDelay,maxReconnectDelay:e.maxReconnectDelay||b.maxReconnectDelay,maxReconnectAttempts:e.maxReconnectAttempts||b.maxReconnectAttempts,reconnectRecoveryDelay:e.reconnectRecoveryDelay??b.reconnectRecoveryDelay,heartbeatIncoming:e.heartbeatIncoming||b.heartbeatIncoming,heartbeatOutgoing:e.heartbeatOutgoing||b.heartbeatOutgoing,resumeOnVisibility:!1!==e.resumeOnVisibility,syncOnReconnect:!1!==e.syncOnReconnect,assistantStreamReplay:!1!==e.assistantStreamReplay,rewindMillis:void 0!==e.rewindMillis?e.rewindMillis:b.rewindMillis,maxSyncPages:e.maxSyncPages||b.maxSyncPages,syncPageSize:e.syncPageSize||b.syncPageSize,iceServers:e.iceServers||b.iceServers,autoSubscribeRoomList:!1!==e.autoSubscribeRoomList,logLevel:void 0!==e.logLevel?e.logLevel:w.WARN},this.logger=new S(this.options.logLevel,"TalkFlowClient"),this._initialized=!1,this._state=t.DISCONNECTED,this._userId=null,this.options.jwtToken&&(this._userId=O(this.options.jwtToken)),this.apiClient=new E({baseUrl:this.options.serverUrl,apiKey:this.options.apiKey,projectId:this.options.projectId,jwtToken:this.options.jwtToken,logLevel:this.options.logLevel}),this.authSession=null,this._authConnectionRequested=!1,this.connectionManager=null,this._chat=null,this._webrtc=null,this._pushManager=null,this._pushEnablePromise=null,this.options.jwtToken&&this._userId&&this._initializeSubClients(),this._initialized=!0,"refresh"===this.options.sessionMode&&this._enableRefreshSession(),this.logger.info("TalkFlowClient initialized",{userId:this._userId,hasToken:!!this.options.jwtToken})}get chat(){return this._chat}get webrtc(){return this._webrtc}get pushManager(){return this._pushManager}get userId(){return this._userId}_validateOptions(e){if(!e)throw new Error("Options are required");if(!e.apiKey&&"refresh"!==e.sessionMode)throw new Error("apiKey is required");if(!e.projectId&&"refresh"!==e.sessionMode)throw new Error("projectId is required");e.apiKey?.startsWith("sk-")&&console.error("🚨 [TalkFlow] Server Key (sk-) 로 SDK 를 초기화했습니다. SDK 는 Client Key (ck-) 만 사용합니다 — loginUser() 응답의 clientKey 를 그대로 쓰세요.")}_initializeSubClients(){!function(e){if(!e.connectionManager){if(!e.userId)throw new Error("userId is required to initialize sub-clients. Please set JWT token first.");e.connectionManager=new Ks({serverUrl:e.options.serverUrl,jwtToken:e.options.jwtToken,apiKey:e.options.apiKey,projectId:e.options.projectId,useSockJS:e.options.useSockJS,reconnectDelay:e.options.reconnectDelay,maxReconnectDelay:e.options.maxReconnectDelay,maxReconnectAttempts:e.options.maxReconnectAttempts,reconnectRecoveryDelay:e.options.reconnectRecoveryDelay,heartbeatIncoming:e.options.heartbeatIncoming,heartbeatOutgoing:e.options.heartbeatOutgoing,resumeOnVisibility:e.options.resumeOnVisibility,logLevel:e.options.logLevel}),e.connectionManager.getAccessToken=async({forceRefresh:t=!1}={})=>e.authSession?e.authSession.getAccessToken({forceRefresh:t,rejectedToken:e.connectionManager?.jwtToken}):e.options.jwtToken,e.connectionManager.canRefreshToken=()=>!!e.authSession,e._chat=new Ys({connectionManager:e.connectionManager,apiClient:e.apiClient,userId:e._userId,syncOnReconnect:e.options.syncOnReconnect,assistantStreamReplay:e.options.assistantStreamReplay,rewindMillis:e.options.rewindMillis,maxSyncPages:e.options.maxSyncPages,syncPageSize:e.options.syncPageSize,logLevel:e.options.logLevel}),e._webrtc=new ti({connectionManager:e.connectionManager,apiClient:e.apiClient,userId:e._userId,iceServers:e.options.iceServers,logLevel:e.options.logLevel}),e._setupEventForwarding(),e.logger.debug("Sub-clients initialized")}}(this)}_setupEventForwarding(){Ii(this)}isConnected(){return!!this.connectionManager&&this.connectionManager.isConnected()}isSubscriptionRequired(){return!!this.connectionManager&&this.connectionManager.isSubscriptionRequired()}_enableRefreshSession(){this.authSession||(this.options.sessionMode="refresh",this.authSession=A.forServer(this.options.serverUrl),this.authSession.attach(this),this.apiClient.authProvider=this.authSession,this._authUnsubscribe=this.authSession.on("authStateChanged",e=>this.emit("authStateChanged",e)),this._authErrorUnsubscribe=this.authSession.on("authError",e=>this.emit("authError",e)),!this.authSession.data&&this.options.jwtToken&&C(this.options.jwtToken).sid&&(this.authSession.data={accessToken:this.options.jwtToken,projectId:this.options.projectId,clientKey:this.options.apiKey,user:{userId:this.userId}},this.authSession._setState("authenticated")),this._authReady=Promise.resolve(),this.authSession.data&&(this._authReady=this._acceptAuthSession(this.authSession.data).catch(e=>{throw this._authReady=Promise.resolve(),e})))}async _acceptAuthSession(e){this.options.projectId&&this.options.projectId!==e.projectId&&this.connectionManager&&await this._clearAuthSession(),this.options.apiKey=e.clientKey,this.options.projectId=e.projectId,this.apiClient.apiKey=e.clientKey,this.apiClient.projectId=e.projectId,await this.setToken(e.accessToken)}async _clearAuthSession(){this._authConnectionRequested=!1,this.options.jwtToken=null,this._userId=null,this.apiClient.setJwtToken(null),await this.disconnect(),this._chat?.destroy(),this._webrtc?.destroy(),await(this.connectionManager?.destroy()),this._chat=null,this._webrtc=null,this.connectionManager=null,this.pushManager?.reset(),this._pushManager=null,this._pushEnablePromise=null,this.emit("loggedOut")}getAuthState(){return this.authSession?.getAuthState()||(1e3*Number(C(this.options.jwtToken||"").exp||0)>Date.now()?"authenticated":"unauthenticated")}isLoggedIn(){return"authenticated"===this.getAuthState()}async getAccessToken(e={}){if(this.authSession)return await this._authReady,this.authSession.getAccessToken(e);if(!this.isLoggedIn()){const e=new Error("Sign in is required");throw e.code="SESSION_REVOKED",e}return this.options.jwtToken}async restoreSession(){return this._enableRefreshSession(),await this._authReady,this.authSession.restoreSession()}static async restoreSession({serverUrl:e}){if(!e)throw new Error("serverUrl is required");return A.forServer(e).restoreSession()}async request(e,t,s={}){if(!t.startsWith("/")||t.startsWith("//"))throw new Error("Use an API-relative path");return await this._authReady,this.apiClient.request(e,t,s)}getState(){return this._state}hasToken(){return!!this.options.jwtToken}static async loginUser({serverUrl:e,email:t,password:s,projectId:i}){if(!e)throw new Error("serverUrl is required");if(!t)throw new Error("email is required");if(!s)throw new Error("password is required");return A.forServer(e).login({email:t,password:s,projectId:i})}async loginUser({email:e,password:t,projectId:s}){if(!e||!t)throw new Error("email and password are required");return this._enableRefreshSession(),await this._authReady,this.authSession.login({email:e,password:t,projectId:s})}async getMyProfile(){this._checkToken();const e=await this.apiClient.get("/api/v1/me");return e&&e.data?e.data:e}async updateMyProfile(e){this._checkToken();const t=await this.apiClient.put("/api/v1/me",e),s=t&&t.data?t.data:t;if(s&&s.accessToken)try{await this.setToken(s.accessToken)}catch(e){this.logger.warn("Profile updated but token refresh failed; keeping the old token",e)}return s}async changeMyPassword({currentPassword:e,newPassword:t}){if(this._checkToken(),this.authSession)return this.authSession.changePassword(()=>this.apiClient.request("PUT","/api/v1/me/password",{body:{currentPassword:e,newPassword:t},skipAuth:!0}));const s=await this.apiClient.put("/api/v1/me/password",{currentPassword:e,newPassword:t}),i=s?.data??s;return i?.accessToken&&i?.refreshToken&&(this._enableRefreshSession(),this.authSession._newMarker(!1),await this.authSession._accept(i)),s}async setPreferredLanguage(e){return this.updateMyProfile({preferredLanguage:e})}static detectBrowserLanguage(){return"undefined"!=typeof navigator&&navigator.language?Ai.normalizeLanguageCode(navigator.language):null}static normalizeLanguageCode(e){if(!e||"string"!=typeof e)return null;const t=e.trim();if(!t)return null;if("OFF"===t.toUpperCase())return"OFF";const s=t.toLowerCase(),i=s.indexOf("-");if(i<0)return s;const n=s.slice(0,i);return"zh"===n?s:n}static displayText(e,t){const s=Ai.normalizeLanguageCode(t);return e&&e.translations&&s&&e.translations[s]?e.translations[s]:e?e.content:null}async getCompanyDirectory(){return this._checkToken(),this.apiClient.get("/api/v1/company/directory")}async getUsers(e={}){this._checkToken();const{size:t=50,lastId:s,lastSortValue:i}=e;return this.apiClient.get("/api/v1/users",{size:t,lastId:s,lastSortValue:i})}async searchUsers(e){this._checkToken();const{keyword:t,limit:s=20}=e;return this.apiClient.get("/api/v1/users/search",{keyword:t,limit:s})}_checkToken(){if(!this.options.jwtToken)throw new Error('JWT token is required for this operation. Sign in with TalkFlowClient.loginUser({ serverUrl, email, password }) and pass the returned accessToken via setToken(). See README "로그인".')}getUserId(){return this.userId}isInitialized(){return this._initialized}isReady(){return this._initialized&&!!this.connectionManager}setLogLevel(e){this.options.logLevel=e,this.logger.setLevel(e),this.apiClient.logger?.setLevel(e),this.connectionManager&&this.connectionManager.setLogLevel(e),this.chat&&this.chat.setLogLevel(e),this.webrtc&&this.webrtc.setLogLevel(e)}getStatus(){return{initialized:this._initialized,ready:this.isReady(),hasToken:this.hasToken(),connectionState:this._state,isConnected:this.isConnected(),userId:this.userId,chat:this.chat?{subscribedRooms:this.chat.getSubscribedRooms()}:null,webrtc:this.webrtc?{isInCall:this.webrtc.isInCall(),currentRoom:this.webrtc.getCurrentRoom(),participants:this.webrtc.getParticipants(),mediaState:this.webrtc.getMediaState()}:null}}async destroy(){await this.disconnect(),this._authUnsubscribe?.(),this._authErrorUnsubscribe?.(),this.authSession?.detach(this),this.chat&&this.chat.destroy(),this.webrtc&&this.webrtc.destroy(),this.connectionManager&&await this.connectionManager.destroy(),this.removeAllListeners(),this._initialized=!1,this.logger.info("TalkFlowClient destroyed")}}Ai.ConnectionState=t,Ai.ErrorTypes=s,Ai.LogLevel=w,Ai.Environment=f,function(e){e.prototype.connect=async function(e,t={}){const{enablePush:s=!1}=t;if(e&&await this.setToken(e),this.authSession){await this._authReady,this._authConnectionRequested=!0;const e=await this.authSession.getAccessToken();await this.setToken(e),this.authSession.schedule()}if(!this.options.jwtToken)throw new Error('JWT token is required. Sign in with TalkFlowClient.loginUser({ serverUrl, email, password }) and pass the returned accessToken to the SDK via the jwtToken option, setToken(), or connect(jwt). See README "로그인".');if(!this.authSession&&L(this.options.jwtToken))throw new Error("JWT token has expired. Please update the token before connecting.");if(this.connectionManager||this._initializeSubClients(),await this.connectionManager.connect(),this.webrtc&&await this.webrtc.enableIncomingCalls(),this.chat&&this.options.autoSubscribeRoomList)try{await this.chat.subscribeRoomList()}catch(e){this.logger.warn("Failed to auto-subscribe room list (non-fatal):",e)}s&&this.enablePushNotifications(),this.logger.info("Connected to server")},e.prototype.disconnect=async function(){this._authConnectionRequested=!1,this.authSession?.schedule(),this.connectionManager&&(this.webrtc&&this.webrtc.isInCall()&&this.webrtc.endCall(),this.webrtc&&this.webrtc.disableIncomingCalls(),this.chat&&(this.chat.unsubscribeAllRooms(),this.chat.unsubscribeRoomList(),this.chat.unsubscribeMail()),await this.connectionManager.disconnect(),this.logger.info("Disconnected from server"))},e.prototype.logout=async function(){if(this.authSession)return this.authSession.logout();try{await this.apiClient.post("/v1/auth/signout"),this.logger.info("Logged out from server")}catch(e){this.logger.warn("Server logout failed (proceeding with local cleanup):",e.message)}await this.disconnect(),this.pushManager&&(this.pushManager.reset(),this._pushEnablePromise=null),this.options.jwtToken=null,this._userId=null,this.apiClient.setJwtToken(null),this.emit("loggedOut")},e.prototype.enablePushNotifications=async function(e={}){if(!this.options.jwtToken){const e=new Error("JWT token is required to enable push notifications.");return this.emit("pushFailed",{reason:"NO_TOKEN",error:e}),{ok:!1,reason:"NO_TOKEN",error:e}}if(!this.pushManager){this._pushManager=new mi({apiClient:this.apiClient,projectId:this.options.projectId,firebaseConfig:e.firebaseConfig,vapidKey:e.vapidKey,serviceWorkerPath:e.serviceWorkerPath,logLevel:this.options.logLevel});const t=3e5;this.pushManager._onForegroundMessage=e=>{const s=e.data||{};if(s.projectId&&s.projectId!==this.options.projectId)return void this.logger.debug("다른 프로젝트 푸시 무시:",s.projectId);if(function(e,t){const s=t&&t.data||{};if("MAIL"!==s.target)return!1;const i=fi(e);if(!s.connectionId)return!0;if("SUMMARY"===s.kind){const t="string"==typeof s.messageIds?s.messageIds.split(",").map(e=>e.trim()).filter(Boolean):[];if(0===t.length){const t=Number.parseInt(s.count,10);return e.emit("newMailSummary",{projectId:i,connectionId:s.connectionId,count:Number.isFinite(t)?t:null,messageIds:[],source:"push"}),!0}const n=_i(e),r=t.filter(e=>n.accept(yi(i,s.connectionId,e)));return r.length>0&&e.emit("newMailSummary",{projectId:i,connectionId:s.connectionId,count:r.length,messageIds:r,source:"push"}),!0}return!s.messageId||!_i(e).accept(yi(i,s.connectionId,s.messageId))||(e.emit("newMail",{projectId:i,connectionId:s.connectionId,messageId:s.messageId,threadId:s.threadId||null,sender:t.notification&&t.notification.title||s.title||null,from:null,subject:t.notification&&t.notification.body||s.body||null,receivedAt:null,source:"push"}),!0)}(this,e))return;const i=this.chat?.getActiveRoom();if(i&&i===s.roomId)this.logger.debug("포그라운드 푸시 suppress (현재 방):",s.roomId);else{if(s.messageId){if(this._recentPushMessageIds||(this._recentPushMessageIds=new Map),this._recentPushMessageIds.has(s.messageId))return void this.logger.debug("포그라운드 푸시 dedup:",s.messageId);const e=setTimeout(()=>{this._recentPushMessageIds.delete(s.messageId)},t);this._recentPushMessageIds.set(s.messageId,e)}this.emit("pushNotification",{title:e.notification?.title||s.title,body:e.notification?.body||s.body,data:s})}}}if(this.pushManager.isEnabled())return this.logger.debug("웹 푸시가 이미 활성화되어 있어 중복 호출을 건너뜁니다."),{ok:!0,alreadyEnabled:!0};if(this._pushEnablePromise)return this.logger.debug("웹 푸시 활성화가 이미 진행 중입니다."),this._pushEnablePromise;const t=(async()=>{try{return await this.pushManager.enable(),this.emit("pushEnabled"),{ok:!0}}catch(e){const t=e&&e.code?e.code:"UNKNOWN";return this.logger.warn("Failed to enable push notifications:",t,e?.message),this.emit("pushFailed",{reason:t,error:e}),{ok:!1,reason:t,error:e}}})();return this._pushEnablePromise=t,t.finally(()=>{this._pushEnablePromise===t&&(this._pushEnablePromise=null)}),t},e.prototype.consumePendingRoom=async function(){return mi.consumePendingRoom(this.options.projectId)},e.prototype.consumePendingMail=async function(){return mi.consumePendingMail(this.options.projectId)},e.prototype.setCurrentDeviceEnabled=function(e){return this.pushManager?.setCurrentDeviceEnabled(e)},e.prototype.setDeviceEnabled=function(e,t){return this.pushManager?.setDeviceEnabled(e,t)},e.prototype.getMyDevices=function(){return this.pushManager?.getMyDevices()},e.prototype.getPushPermissionState=function(){return mi.getPermissionState()},e.prototype.isPushEnabled=function(){return this.pushManager?.isEnabled()??!1},e.prototype.getPushToken=function(){return this.pushManager?.getToken()??null},e.prototype.resetPush=function(){this.pushManager?.reset(),this._pushEnablePromise=null},e.prototype.setToken=async function(e){const{userId:t}=N(e,{validateExpiry:!1}),s=this.userId&&this.userId!==t;this.options.jwtToken=e,this._userId=t,this.apiClient.setJwtToken(e),s&&this.connectionManager?(await this.disconnect(),this._chat?.destroy(),this._webrtc?.destroy(),await this.connectionManager.destroy(),this.pushManager&&(this.pushManager.reset(),this._pushEnablePromise=null,this._pushManager=null),this.connectionManager=null,this._chat=null,this._webrtc=null,this._initializeSubClients()):this.connectionManager?this.connectionManager.updateToken(e):this._initializeSubClients(),this.logger.info("JWT token set",{userId:t}),this.authSession?.replaceAccessToken(e),this.emit("tokenSet",{userId:t})},e.prototype.updateToken=async function(e){await this.setToken(e)}}(Ai),function(e){Ci(e.prototype,"chat",Ti),Ci(e.prototype,"webrtc",Ri)}(Ai);class ki{constructor(e){this._currentUserId=e,this._rooms=new Map}_room(e){let t=this._rooms.get(e);return t||(t={snapshotCount:null,snapshotVersion:null,pendingDeltas:new Map},this._rooms.set(e,t)),t}applyMessageReceived(e){if(!e||!e.roomId||!e.messageId)return;if(null!=e.actorId&&e.actorId===this._currentUserId)return;const t=this._room(e.roomId);if(t.pendingDeltas.has(e.messageId))return;const s=null==e.unreadVersion?null:e.unreadVersion;null!=t.snapshotVersion&&null!=s&&s<=t.snapshotVersion||t.pendingDeltas.set(e.messageId,{version:s,delta:1})}applySnapshot(e,t,s){if(!e||null==t)return;const i=null==s?null:s,n=this._room(e);if(!(null!=n.snapshotVersion&&null==i||null!=n.snapshotVersion&&null!=i&&i<n.snapshotVersion||(n.snapshotCount=t,null!=i&&(n.snapshotVersion=i),null==i)))for(const[e,t]of n.pendingDeltas)(null==t.version||t.version<=i)&&n.pendingDeltas.delete(e)}getCount(e){const t=this._rooms.get(e);if(!t||null==t.snapshotCount)return null;let s=t.snapshotCount;for(const e of t.pendingDeltas.values())s+=e.delta;return s}removeRoom(e){this._rooms.delete(e)}clear(){this._rooms.clear()}}export{l as AssistantMode,Ys as ChatClient,n as ChatMessageType,h as ChatRoomType,Ks as ConnectionManager,t as ConnectionState,r as DecisionCardLimits,b as DefaultConfig,y as Endpoints,u as EngagementIntensity,f as Environment,s as ErrorTypes,e as EventEmitter,w as LogLevel,S as Logger,Qs as MediaStreamManager,Zs as PeerConnectionManager,a as PersonaRole,g as PmPromptLayerEditorType,p as PmPromptLayerScope,ii as PushError,si as PushErrorCode,mi as PushManager,d as RoomAiType,m as RoomListEventType,ki as RoomUnreadReconciler,o as SenderType,i as SignalTypes,c as SummarizeFormat,ti as WebRTCClient,_ as WebSocketPaths,P as decodeJWTPayload,Ai as default,O as extractUserIdFromJWT,D as getJWTRemainingTime,v as getServerUrl,L as isJWTExpired,N as validateAndParseJWT};
1
+ class e{constructor(){this._events=new Map}on(e,t){return this._events.has(e)||this._events.set(e,new Set),this._events.get(e).add(t),()=>this.off(e,t)}once(e,t){const s=(...i)=>{this.off(e,s),t.apply(this,i)};return s._originalListener=t,this.on(e,s)}off(e,t){const s=this._events.get(e);if(s){for(const e of s)if(e===t||e._originalListener===t){s.delete(e);break}0===s.size&&this._events.delete(e)}}emit(e,t){const s=this._events.get(e);s&&s.forEach(s=>{try{s(t)}catch(t){console.error(`Error in event listener for '${e}':`,t)}})}removeAllListeners(e){e?this._events.delete(e):this._events.clear()}listenerCount(e){const t=this._events.get(e);return t?t.size:0}eventNames(){return Array.from(this._events.keys())}}const t={DISCONNECTED:"disconnected",CONNECTING:"connecting",CONNECTED:"connected",RECONNECTING:"reconnecting",ERROR:"error"},s={CONNECTION_FAILED:"CONNECTION_FAILED",CONNECTION_LOST:"CONNECTION_LOST",CONNECTION_TIMEOUT:"CONNECTION_TIMEOUT",SUBSCRIPTION_REQUIRED:"SUBSCRIPTION_REQUIRED",JWT_INVALID:"JWT_INVALID",JWT_EXPIRED:"JWT_EXPIRED",JWT_PARSE_FAILED:"JWT_PARSE_FAILED",UNAUTHORIZED:"UNAUTHORIZED",API_ERROR:"API_ERROR",API_TIMEOUT:"API_TIMEOUT",CHAT_ROOM_NOT_FOUND:"CHAT_ROOM_NOT_FOUND",CHAT_MESSAGE_FAILED:"CHAT_MESSAGE_FAILED",CHAT_SUBSCRIPTION_FAILED:"CHAT_SUBSCRIPTION_FAILED",MEDIA_ACCESS_DENIED:"MEDIA_ACCESS_DENIED",SCREEN_SHARE_DENIED:"SCREEN_SHARE_DENIED",PEER_CONNECTION_FAILED:"PEER_CONNECTION_FAILED",ICE_CONNECTION_FAILED:"ICE_CONNECTION_FAILED",SIGNALING_FAILED:"SIGNALING_FAILED",DEVICE_SWITCH_FAILED:"DEVICE_SWITCH_FAILED",ENUMERATE_DEVICES_FAILED:"ENUMERATE_DEVICES_FAILED",CALL_ROOM_NOT_FOUND:"CALL_ROOM_NOT_FOUND",INVALID_STATE:"INVALID_STATE",UNKNOWN_ERROR:"UNKNOWN_ERROR"},i={CALL_OFFER:"call_offer",CALL_ANSWER:"call_answer",ICE_CANDIDATE:"ice_candidate",JOIN_ROOM:"join_room",LEAVE_ROOM:"leave_room",PEER_JOINED:"peer_joined",PEER_LEFT:"peer_left",VIDEO_STATE_CHANGED:"video_state_changed",AUDIO_STATE_CHANGED:"audio_state_changed",SCREEN_SHARE_STARTED:"screen_share_started",SCREEN_SHARE_ENDED:"screen_share_ended",CALL_REQUEST:"call_request",CALL_ACCEPT:"call_accept",CALL_REJECT:"call_reject",CALL_CANCEL:"call_cancel",CALL_END:"call_end",CALL_INVITATION:"call_invitation",CALL_BUSY:"call_busy"},n={TEXT:"TEXT",IMAGE:"IMAGE",FILE:"FILE",VIDEO:"VIDEO",AUDIO:"AUDIO",DOCUMENT:"DOCUMENT",MIXED:"MIXED",GALLERY:"GALLERY",SYSTEM:"SYSTEM"},r={MIN_OPTIONS:2,MAX_OPTIONS:5,LABEL_MAX_LENGTH:80,QUESTION_MAX_LENGTH:200},o={USER:"USER",ASSISTANT:"ASSISTANT"},a={LEGAL_ADVISOR:"LEGAL_ADVISOR",MARKETING:"MARKETING",PRODUCT_PLANNING:"PRODUCT_PLANNING",HR:"HR",FINANCE:"FINANCE",CUSTOMER_SUPPORT:"CUSTOMER_SUPPORT",SALES:"SALES",ENGINEERING:"ENGINEERING",DATA_ANALYST:"DATA_ANALYST",PROJECT_MANAGEMENT:"PROJECT_MANAGEMENT",RESEARCH:"RESEARCH",TRANSLATION:"TRANSLATION",DESIGN:"DESIGN",PM:"PM"},c={MINUTES:"MINUTES",SHORT:"SHORT",TIMELINE:"TIMELINE",ACTIONS:"ACTIONS",OPTIONS:"OPTIONS"},h={DIRECT:"DIRECT",GROUP:"GROUP",PRIVATE_GROUP:"PRIVATE_GROUP",TEAM:"TEAM"},l={GENERAL:"GENERAL",PEOPLE_ONLY:"PEOPLE_ONLY",CALL_ONLY:"CALL_ONLY"},d={NONE:"NONE",PERSONA_MULTI:"PERSONA_MULTI",PM_BACKSTAGE:"PM_BACKSTAGE"},u={QUIET:"QUIET",NORMAL:"NORMAL",ACTIVE:"ACTIVE"},p={PROJECT:"PROJECT",ROOM:"ROOM"},g={SUPER_ADMIN:"SUPER_ADMIN",PROJECT_ADMIN:"PROJECT_ADMIN",ROOM_OWNER:"ROOM_OWNER"},m={MESSAGE_RECEIVED:"MESSAGE_RECEIVED",MESSAGE_DELETED:"MESSAGE_DELETED",MESSAGE_UPDATED:"MESSAGE_UPDATED",ROOM_CREATED:"ROOM_CREATED",ROOM_JOINED:"ROOM_JOINED",ROOM_LEFT:"ROOM_LEFT",ROOM_UPDATED:"ROOM_UPDATED",ROOM_KICKED:"ROOM_KICKED",ROOM_BANNED:"ROOM_BANNED",ROOM_OWNER_CHANGED:"ROOM_OWNER_CHANGED",ROOM_DELETED:"ROOM_DELETED",MESSAGE_RETENTION_CLEANUP:"MESSAGE_RETENTION_CLEANUP",ROOM_UNREAD_UPDATED:"ROOM_UNREAD_UPDATED",AI_UNAVAILABLE:"AI_UNAVAILABLE"},_={SOCKJS_ENDPOINT:"/ws-chat",NATIVE_ENDPOINT:"/ws-chat-native",APP_PREFIX:"/app",TOPIC_PREFIX:"/topic",QUEUE_PREFIX:"/queue",USER_PREFIX:"/user",getChatDestination:e=>`/topic/chat/${e}`,getChatReadDestination:e=>`/topic/chat/${e}/read`,getChatTypingDestination:e=>`/topic/chat/${e}/typing`,getChatAssistantStreamDestination:e=>`/topic/chat/${e}/assistant-stream`,getChatSummaryDestination:e=>`/topic/chat/${e}/summary`,ROOM_LIST_USER_DESTINATION:"/user/queue/rooms",MAIL_USER_DESTINATION:"/user/queue/mail",getWebRTCDestination:e=>`/topic/webrtc/${e}`,getWebRTCUserDestination:()=>"/user/queue/webrtc",CHAT_SEND:"/app/chat/send",CHAT_READ:"/app/chat/read",CHAT_TYPING:"/app/chat/typing",WEBRTC_SIGNAL:"/app/webrtc/signal"},f={DEVELOPMENT:"development",STAGING:"staging",PRODUCTION:"production"},y={[f.DEVELOPMENT]:{serverUrl:"https://dev-chat.apiorbit.net",wsEndpoint:"/ws-chat"},[f.STAGING]:{serverUrl:"https://stg-api.talk-x.app",wsEndpoint:"/ws-chat"},[f.PRODUCTION]:{serverUrl:"https://prod-api.talk-x.app",wsEndpoint:"/ws-chat"}},b={environment:f.PRODUCTION,reconnectDelay:5e3,maxReconnectDelay:3e4,maxReconnectAttempts:10,reconnectRecoveryDelay:6e4,heartbeatIncoming:1e4,heartbeatOutgoing:1e4,resumeOnVisibility:!0,syncOnReconnect:!0,rewindMillis:3e3,maxSyncPages:5,syncPageSize:100,apiTimeout:3e4,iceServers:[{urls:"stun:stun.l.google.com:19302"},{urls:"stun:stun1.l.google.com:19302"}],logLevel:2};function v(e){return(y[e]||y[f.PRODUCTION]).serverUrl}const w={DEBUG:0,INFO:1,WARN:2,ERROR:3,NONE:4};class S{constructor(e=w.WARN,t="TalkFlow"){this.level=e,this.prefix=t}setLevel(e){this.level=e}setPrefix(e){this.prefix=e}_format(e,...t){return[`[${(new Date).toISOString()}] [${e}] [${this.prefix}]`,...t]}debug(...e){this.level<=w.DEBUG&&console.debug(...this._format("DEBUG",...e))}info(...e){this.level<=w.INFO&&console.info(...this._format("INFO",...e))}warn(...e){this.level<=w.WARN&&console.warn(...this._format("WARN",...e))}error(...e){this.level<=w.ERROR&&console.error(...this._format("ERROR",...e))}}class E{constructor(e){this.baseUrl=e.baseUrl.replace(/\/$/,""),this.apiKey=e.apiKey,this.projectId=e.projectId,this.jwtToken=e.jwtToken,this.timeout=e.timeout||b.apiTimeout,this.logger=new S(e.logLevel,"ApiClient")}setJwtToken(e){this.jwtToken=e}_getHeaders(){const e={"Content-Type":"application/json","X-API-KEY":this.apiKey,"X-PROJECT-ID":this.projectId};return this.jwtToken&&(e.Authorization=this.jwtToken.startsWith("Bearer ")?this.jwtToken:`Bearer ${this.jwtToken}`),e}async request(e,t,s={}){if(!this.authProvider||s.skipAuth)return this._request(e,t,s);this.jwtToken=await this.authProvider.getAccessToken();const i=this.jwtToken,n=this.authProvider.generation;try{return await this._request(e,t,s)}catch(r){if(401===r.status&&["ACCESS_UNAUTHORIZED","TOKEN_INVALID"].includes(r.response?.code)){if(n!==this.authProvider.generation)throw r;this.jwtToken=await this.authProvider.getAccessToken({forceRefresh:!0,rejectedToken:i});const o=this.jwtToken,a=this.authProvider.generation;try{return await this._request(e,t,s)}catch(e){throw await this.authProvider.authenticationFailed(e,{rejectedToken:o,generation:a}),e}}throw await this.authProvider.authenticationFailed(r,{rejectedToken:i,generation:n}),r}}async _request(e,t,i={}){const{body:n,params:r,headers:o}=i;let a=`${this.baseUrl}${t}`;if(r){const e=new URLSearchParams;Object.entries(r).forEach(([t,s])=>{null!=s&&e.append(t,s)});const t=e.toString();t&&(a+=`?${t}`)}const c=new AbortController,h=setTimeout(()=>c.abort(),this.timeout);let l;try{this.logger.debug(`${e} ${a}`),l=await fetch(a,{method:e,headers:{...this._getHeaders(),...o},credentials:this.authProvider?"omit":"same-origin",body:n?JSON.stringify(n):void 0,signal:c.signal})}catch(t){if(clearTimeout(h),"AbortError"===t.name){const e=new Error("Request timeout");throw e.code=s.API_TIMEOUT,e}throw this.logger.error(`API Error: ${e} ${a}`,t),t}clearTimeout(h);const d=l.headers.get("content-type");let u;if(u=d&&d.includes("application/json")?await l.json():await l.text(),!l.ok){const t=new Error(u?.message||`HTTP ${l.status}`);throw t.code=s.API_ERROR,t.status=l.status,t.response=u,this.logger.error(`API Error: ${e} ${a}`,t),t}return this.logger.debug(`Response ${l.status}`),u}get(e,t){return this.request("GET",e,{params:t})}post(e,t,s,i){return this.request("POST",e,{body:t,params:s,headers:i})}put(e,t){return this.request("PUT",e,{body:t})}patch(e,t){return this.request("PATCH",e,{body:t})}delete(e,t){return this.request("DELETE",e,{params:t})}async upload(e,t,s={}){if(!this.authProvider)return this._upload(e,t,s);this.jwtToken=await this.authProvider.getAccessToken();const i=this.jwtToken,n=this.authProvider.generation;try{return await this._upload(e,t,s)}catch(r){if(401===r.status&&["ACCESS_UNAUTHORIZED","TOKEN_INVALID"].includes(r.response?.code)){if(n!==this.authProvider.generation)throw r;this.jwtToken=await this.authProvider.getAccessToken({forceRefresh:!0,rejectedToken:i});const o=this.jwtToken,a=this.authProvider.generation;try{return await this._upload(e,t,s)}catch(e){throw await this.authProvider.authenticationFailed(e,{rejectedToken:o,generation:a}),e}}throw await this.authProvider.authenticationFailed(r,{rejectedToken:i,generation:n}),r}}_upload(e,t,i={}){const{fieldName:n="file",onProgress:r,signal:o,timeout:a=6e5}=i;return new Promise((i,c)=>{const h=`${this.baseUrl}${e}`,l=new XMLHttpRequest,d=new FormData;d.append(n,t),l.open("POST",h),l.timeout=a,l.setRequestHeader("X-API-KEY",this.apiKey),l.setRequestHeader("X-PROJECT-ID",this.projectId),this.jwtToken&&l.setRequestHeader("Authorization",this.jwtToken.startsWith("Bearer ")?this.jwtToken:`Bearer ${this.jwtToken}`),"function"==typeof r&&(l.upload.onprogress=e=>{e.lengthComputable&&r({loaded:e.loaded,total:e.total,percent:Math.round(e.loaded/e.total*100)})});const u=()=>l.abort();if(o){if(o.aborted)return void c(new Error("Upload cancelled"));o.addEventListener("abort",u)}const p=()=>{o&&o.removeEventListener("abort",u)};l.onload=()=>{p();let e=l.responseText;if((l.getResponseHeader("content-type")||"").includes("application/json"))try{e=JSON.parse(l.responseText)}catch{}if(l.status>=200&&l.status<300)this.logger.debug(`Upload ${l.status}:`,e),i(e);else{const t=new Error(e?.message||`HTTP ${l.status}`);t.code=s.API_ERROR,t.status=l.status,t.response=e,this.logger.error(`Upload Error: POST ${h}`,t),c(t)}},l.onerror=()=>{p();const e=new Error("Network error during upload");e.code=s.API_ERROR,this.logger.error(`Upload Network Error: POST ${h}`,e),c(e)},l.ontimeout=()=>{p();const e=new Error("Upload timeout");e.code=s.API_TIMEOUT,this.logger.error(`Upload Timeout: POST ${h}`,e),c(e)},l.onabort=()=>{p(),c(new Error("Upload cancelled"))},this.logger.debug(`POST ${h} (multipart, ${t.size} bytes)`),l.send(d)})}}const I=new Map,T=new Set(["REFRESH_INVALID","REFRESH_REUSED","SESSION_REVOKED","ACCOUNT_BLOCKED","LOGIN_FAILED"]),R=e=>T.has(e?.response?.code||e?.code);function C(e){try{const t=e.replace(/^Bearer\s+/i,"").split(".")[1].replace(/-/g,"+").replace(/_/g,"/");return JSON.parse(atob(t))}catch{return{}}}class A extends e{static forServer(e){const t=e.replace(/\/$/,"");return I.has(t)||I.set(t,new A(t)),I.get(t)}constructor(e){super(),this.serverUrl=e,this.state="checking",this.data=null,this.clients=new Set,this.generation=0,this.refreshPromise=null,this.timer=null,this.peerWaiters=new Map,this.markerKey=`talkflow:auth:${e}`,this.marker=this._readMarker(),this.serverClock=null,this.channel=null,this.storageListener=e=>{if(e.key!==this.markerKey)return;const t=this._readMarker();(t.revision!==this.marker.revision||t.logout)&&(this.marker=t,this.generation++,this._clear(!1).catch(e=>this.emit("authError",e)))},globalThis.addEventListener?.("storage",this.storageListener),"undefined"!=typeof window&&"undefined"!=typeof BroadcastChannel&&(this.channel=new BroadcastChannel(`talkflow:auth:${e}`),this.channel.onmessage=e=>this._receive(e.data),this.channel.unref?.())}_readMarker(){try{const e=globalThis.localStorage?.getItem(this.markerKey);return e?JSON.parse(e):{revision:"initial",logout:!1}}catch{throw this._storageError()}}_storageError(){const e=new Error("Authentication storage is unavailable");return e.code="AUTH_STORAGE_UNAVAILABLE",e}_writeMarker(e){try{if(!globalThis.localStorage)throw this._storageError();globalThis.localStorage.setItem(this.markerKey,JSON.stringify(e)),this.marker=e}catch{throw this._storageError()}}_newMarker(e,t=e){const s=this._readMarker(),i={revision:globalThis.crypto?.randomUUID?.()||String(Date.now())+"-"+Math.random(),logout:e,deviceId:s.deviceId,pending:t,pendingRefreshToken:e&&t?s.refreshToken||s.pendingRefreshToken:void 0};return this._writeMarker(i),i}setDeviceId(e){this._writeMarker({...this._readMarker(),deviceId:e})}_monotonic(){return globalThis.performance?.now?.()??Date.now()}_serverNow(){return this.serverClock?this.serverClock.server+Math.max(this._monotonic()-this.serverClock.mono,Date.now()-this.serverClock.wall):Date.now()}_shareData(){return this.data?{...this.data,refreshToken:void 0,serverTime:this._serverNow()}:null}_publish(e,t,s=this.marker){const{revision:i,logout:n,pending:r}=s;this.channel?.postMessage({type:e,marker:{revision:i,logout:n,pending:r},data:t})}_setState(e,t,s=!1){const i=this.state;this.state=e,(i!==e||t||s)&&this.emit("authStateChanged",{state:e,previous:i,error:t})}getAuthState(){return this.state}isLoggedIn(){return"authenticated"===this.state}_fresh(e=this.data?.accessToken){return 1e3*Number(C(e||"").exp||0)>this._serverNow()+(this.refreshMargin??6e4)}attach(e){this.clients.add(e)}detach(e){this.clients.delete(e),this.schedule()}_enqueue(e){const t=(this.transition||Promise.resolve()).then(e);return this.transition=t.catch(()=>{}),t}_accept(e,t=!0){const s=this.generation,i=this.marker;return this._enqueue(async()=>{if(s!==this.generation)throw this._cancelled();if(!(e?.accessToken&&e?.projectId&&e?.clientKey&&e?.user?.userId)){const e=new Error("Invalid authentication response");throw e.code="AUTH_UNAVAILABLE",e}const n=this.data&&(this.data.user.userId!==e.user.userId||this.data.projectId!==e.projectId);if(t&&e.refreshToken){const t=this._readMarker();if(t.revision!==i.revision||t.logout)throw this._cancelled();this._writeMarker({...t,refreshToken:e.refreshToken,refreshRequestId:void 0,pending:!1,pendingRefreshToken:void 0})}if(Number.isFinite(e.serverTime)&&(this.serverClock={server:e.serverTime+(e._roundTripMillis||0),mono:this._monotonic(),wall:Date.now()}),this.refreshMargin=Math.min(6e4,Math.max(0,1e3*Number(C(e.accessToken).exp)-this._serverNow())/10),this.data={...e,refreshToken:void 0},await Promise.all([...this.clients].map(t=>t._acceptAuthSession(e))),s!==this.generation)throw this._cancelled();return this._setState("authenticated",void 0,n),t&&this._publish("tokens",this._shareData(),this.marker),this._reconnectClients(),this.schedule(),e})}_reconnectClients(){for(const e of this.clients)if(e._authConnectionRequested&&e.isConnected?.()){const t=e.connectionManager;t?._authenticatedToken!==this.data?.accessToken&&t.forceReconnect("access-token-renewed").catch(e=>this.emit("authError",e))}}_clear(e=!0){const t=this.marker;return this._enqueue(async()=>{this.data=null,clearTimeout(this.timer),this.timer=null,this._setState("unauthenticated"),await Promise.all([...this.clients].map(e=>e._clearAuthSession())),e&&this._publish("logout",void 0,t)})}async _receive(e){if(e?.marker)try{const t=this._readMarker();if(e.marker.revision!==t.revision&&t.revision!==this.marker.revision)return;if("logout"===e.type||"login-start"===e.type){if(e.marker.revision!==t.revision)return;return this.marker=e.marker,this.generation++,await this._clear(!1),void("login-start"===e.type&&this._setState("checking"))}if(e.marker.revision!==this._readMarker().revision||e.marker.logout)return;if("request-token"===e.type&&this._fresh())this._publish("peer-token",{requestId:e.data.requestId,session:this._shareData()});else if("peer-token"===e.type)this.peerWaiters.get(e.data.requestId)?.(e.data.session);else if("tokens"===e.type){this.marker.revision!==e.marker.revision&&this.generation++,this.marker=e.marker;const t=C(e.data?.accessToken||""),s=C(this.data?.accessToken||"");if(t.sid===s.sid&&t.exp<s.exp)return;await this._accept(e.data,!1)}}catch(e){this.emit("authError",e)}}async _peerToken(e){if(!this.channel)return null;const t=`${Date.now()}-${Math.random()}`;return new Promise(s=>{const i=i=>{i&&(i.accessToken===e||1e3*Number(C(i.accessToken).exp)<=Number(i.serverTime)+6e4)||(clearTimeout(n),this.peerWaiters.delete(t),s(i))},n=setTimeout(()=>i(null),100);this.peerWaiters.set(t,i),this._publish("request-token",{requestId:t})})}_locked(e){const t="undefined"!=typeof navigator?navigator.locks:null,s=(this.httpQueue||Promise.resolve()).then(()=>t?.request?t.request(`talkflow:auth:${this.serverUrl}`,e):e());return this.httpQueue=s.catch(()=>{}),s}_newRefreshRequestId(){const e=new Uint8Array(32);if(!globalThis.crypto?.getRandomValues){const e=new Error("Secure randomness is unavailable");throw e.code="AUTH_RANDOM_UNAVAILABLE",e}return globalThis.crypto.getRandomValues(e),Array.from(e,e=>e.toString(16).padStart(2,"0")).join("")}async _request(e,t,s={}){const i=this._monotonic(),n=new AbortController,r=setTimeout(()=>n.abort(),15e3);try{const r=await fetch(`${this.serverUrl}${e}`,{method:"POST",credentials:"omit",signal:n.signal,headers:{"Content-Type":"application/json","X-TalkFlow-Session":"refresh",...s},body:void 0===t?void 0:JSON.stringify(t)}),o=r.headers.get("content-type")?.includes("application/json")?await r.json():await r.text();if(!r.ok){const e=new Error(o?.message||`HTTP ${r.status}`);throw e.status=r.status,e.code=o?.code,e.response=o,e}const a=void 0!==o?.data?o.data:o;return a&&"object"==typeof a?Object.defineProperty({...a},"_roundTripMillis",{value:this._monotonic()-i}):a}finally{clearTimeout(r)}}async login({email:e,password:t,projectId:s}){const i=++this.generation;return this._locked(async()=>{const n=this._readMarker();this._writeMarker(n),n.pendingRefreshToken&&await this._request("/v1/auth/signout",{refreshToken:n.pendingRefreshToken,deviceId:n.deviceId});const r=await this._request("/api/v1/auth/login",{email:e,password:t,previousRefreshToken:n.refreshToken,...s?{projectId:s}:{}});if(!0===r?.workspaceSelectionRequired){if(i!==this.generation)throw this._cancelled();return function(e){const t=Array.isArray(e.workspaces)?e.workspaces:[];if(0===t.length||t.some(e=>!e?.projectId)){const e=new Error("Invalid authentication response");throw e.code="AUTH_UNAVAILABLE",e}return{workspaceSelectionRequired:!0,workspaces:t.map(({projectId:e,companyName:t,companyRole:s})=>({projectId:e,companyName:t??null,companyRole:s}))}}(r)}if(!r?.refreshToken){const e=new Error("Server does not support the refresh session contract");throw e.code="AUTH_PROTOCOL_UNSUPPORTED",e}if(i!==this.generation||this._readMarker().revision!==n.revision)throw await this._request("/v1/auth/signout",{refreshToken:r.refreshToken}),this._cancelled();return this._newMarker(!1),this._accept(r)})}async restoreSession(){if(this._readMarker().logout)return this._readMarker().pending?await this.logout():await this._clear(!1),null;if(this._fresh())return this.data;if(!this._readMarker().refreshToken)return await this._clear(!1),null;this.data||this._setState("checking");try{return await this.getAccessToken(),this.data}catch(e){if(R(e))return null;throw e}}async getAccessToken({forceRefresh:e=!1,rejectedToken:t}={}){if(this._readMarker().logout)throw this._loggedOut();if(this._fresh()&&(!e||t&&t!==this.data.accessToken))return this.data.accessToken;if(this.refreshPromise)return this.refreshPromise;const s=this.generation,i=this._readMarker().revision,n=this._locked(async()=>{if(s!==this.generation||i!==this._readMarker().revision)throw this._cancelled();if(this._fresh()&&(!e||t&&t!==this.data.accessToken))return this.data.accessToken;if(this.marker=this._readMarker(),!this.marker.refreshToken)throw this._loggedOut();this._writeMarker(this.marker);const n=await this._peerToken(t);let r=n;if(!r){const e=this._readMarker();if(s!==this.generation||i!==e.revision||e.logout)throw this._cancelled();const t=e.refreshRequestId||this._newRefreshRequestId();this._writeMarker({...e,refreshRequestId:t}),r=await this._request("/api/v1/auth/refresh",{refreshToken:e.refreshToken,requestId:t})}if(s!==this.generation||i!==this._readMarker().revision)throw this._cancelled();return await this._accept(r,!n),r.accessToken}).catch(async e=>{throw s===this.generation&&i===this._readMarker().revision&&(R(e)?await this.authenticationFailed(e):this.data?this.emit("authError",e):this._setState("unavailable",e)),e}).finally(()=>{this.refreshPromise===n&&(this.refreshPromise=null)});return this.refreshPromise=n,n}async logout(){const e=this.data?.accessToken;this.generation++;const t=this._newMarker(!0),s=this._clear(),i=this._locked(async()=>{const s=await this._request("/v1/auth/signout",{refreshToken:t.pendingRefreshToken,deviceId:t.deviceId},e?{Authorization:"Bearer "+e.replace(/^Bearer\s+/i,"")}:{});return this._readMarker().revision===t.revision&&this._writeMarker({...t,pending:!1,pendingRefreshToken:void 0}),s});await Promise.all([s,i]),this._readMarker().revision===t.revision&&this._writeMarker({...t,pending:!1,pendingRefreshToken:void 0})}async changePassword(e){await this.getAccessToken();const t=++this.generation;return this._locked(async()=>{const s=await e();if(t!==this.generation)throw this._cancelled();const i=s?.data??s;return i?.reauthenticationRequired?(this._newMarker(!0,!1),await this._clear(),s):(this._newMarker(!1),await this._accept(i),s)}).catch(async e=>{throw t===this.generation&&await this.authenticationFailed(e),e})}_loggedOut(){const e=new Error("Sign in is required");return e.code="SESSION_REVOKED",e}async authenticationFailed(e,{rejectedToken:t,generation:s}={}){void 0!==s&&s!==this.generation||t&&this.data&&t!==this.data.accessToken||R(e)&&(this.generation++,this._newMarker(!0,!1),await this._clear())}replaceAccessToken(e){if(!this.data||this.data.accessToken===e)return;const t=C(e);t.sid===C(this.data.accessToken).sid&&t.sub===this.data.user.userId&&(this.data={...this.data,accessToken:e,expiresIn:t.exp},this._publish("tokens",this._shareData()),this._reconnectClients(),this.schedule())}_cancelled(){const e=new Error("Authentication operation was superseded");return e.code="AUTH_OPERATION_CANCELLED",e}schedule(e){if(clearTimeout(this.timer),this.timer=null,!this.data||![...this.clients].some(e=>e._authConnectionRequested))return;const t=e??Math.max(1e3,1e3*Number(C(this.data.accessToken).exp||0)-this._serverNow()-(this.refreshMargin??6e4));this.timer=setTimeout(async()=>{try{const e=this.data?.accessToken;await this.getAccessToken({forceRefresh:!0,rejectedToken:e}),this.data&&await Promise.all([...this.clients].filter(e=>e._authConnectionRequested&&!e.isConnected()).map(e=>e.connectionManager.forceReconnect("access-token-renewed"))),this.schedule()}catch(e){R(e)||this.schedule(3e4)}},t),this.timer.unref?.()}destroy(){this.generation++,clearTimeout(this.timer),this.channel?.close(),globalThis.removeEventListener?.("storage",this.storageListener),this.clients.clear(),this.removeAllListeners(),I.get(this.serverUrl)===this&&I.delete(this.serverUrl)}}function k(e){return e&&"string"==typeof e?e.replace(/^Bearer\s+/i,""):""}function M(e){let t=e.replace(/-/g,"+").replace(/_/g,"/");const s=t.length%4;s&&(t+="=".repeat(4-s));const i=atob(t),n=Uint8Array.from(i,e=>e.charCodeAt(0));return(new TextDecoder).decode(n)}function N(e,t={}){const{bufferSeconds:i=30,validateExpiry:n=!0,validateIssuedAt:r=!1}=t;if(!e||"string"!=typeof e){const e=new Error("JWT token is required");throw e.code=s.JWT_INVALID,e}const o=k(e).split(".");if(3!==o.length){const e=new Error("Invalid JWT format: expected 3 parts separated by dots");throw e.code=s.JWT_INVALID,e}let a;try{a=JSON.parse(M(o[1]))}catch(e){const t=new Error("Invalid JWT: failed to decode payload");throw t.code=s.JWT_PARSE_FAILED,t.originalError=e,t}if(n&&a.exp){const e=1e3*a.exp,t=1e3*i,n=Date.now();if(e<n+t){const t=new Error(e<n?"JWT token expired":`JWT token expires within ${i} seconds`);throw t.code=s.JWT_EXPIRED,t.expiredAt=new Date(e).toISOString(),t}}if(r&&a.iat){const e=6e4;if(1e3*a.iat>Date.now()+e){const e=new Error("JWT token issued in the future");throw e.code=s.JWT_INVALID,e}}const c=a.userId||a.sub||a.user_id;if(!c){const e=new Error("Cannot extract userId from JWT: missing userId, sub, or user_id claim");throw e.code=s.JWT_INVALID,e}return{userId:c,payload:a}}function O(e){try{const t=k(e).split(".");if(3!==t.length)return null;const s=JSON.parse(M(t[1]));return s.userId||s.sub||s.user_id||null}catch(e){return console.error("Failed to extract userId from JWT:",e),null}}function L(e,t=0){try{const s=k(e).split(".");if(3!==s.length)return!0;const i=JSON.parse(M(s[1]));if(!i.exp)return!1;const n=1e3*i.exp,r=1e3*t;return n<Date.now()+r}catch(e){return console.error("Failed to check JWT expiration:",e),!0}}function D(e){try{const t=k(e).split(".");if(3!==t.length)return-1;const s=JSON.parse(M(t[1]));return s.exp?1e3*s.exp-Date.now():1/0}catch(e){return console.error("Failed to get JWT remaining time:",e),-1}}function P(e){try{const t=k(e).split(".");return 3!==t.length?null:JSON.parse(M(t[1]))}catch(e){return console.error("Failed to decode JWT payload:",e),null}}const U="\n",x="\0";class j{get body(){return!this._body&&this.isBinaryBody&&(this._body=(new TextDecoder).decode(this._binaryBody)),this._body||""}get binaryBody(){return this._binaryBody||this.isBinaryBody||(this._binaryBody=(new TextEncoder).encode(this._body)),this._binaryBody}constructor(e){const{command:t,headers:s,body:i,binaryBody:n,escapeHeaderValues:r,skipContentLengthHeader:o}=e;this.command=t,this.headers=Object.assign({},s||{}),n?(this._binaryBody=n,this.isBinaryBody=!0):(this._body=i||"",this.isBinaryBody=!1),this.escapeHeaderValues=r||!1,this.skipContentLengthHeader=o||!1}static fromRawFrame(e,t){const s={},i=e=>e.replace(/^\s+|\s+$/g,"");for(const n of e.headers.reverse()){n.indexOf(":");const r=i(n[0]);let o=i(n[1]);t&&"CONNECT"!==e.command&&"CONNECTED"!==e.command&&(o=j.hdrValueUnEscape(o)),s[r]=o}return new j({command:e.command,headers:s,binaryBody:e.binaryBody,escapeHeaderValues:t})}toString(){return this.serializeCmdAndHeaders()}serialize(){const e=this.serializeCmdAndHeaders();return this.isBinaryBody?j.toUnit8Array(e,this._binaryBody).buffer:e+this._body+x}serializeCmdAndHeaders(){const e=[this.command];this.skipContentLengthHeader&&delete this.headers["content-length"];for(const t of Object.keys(this.headers||{})){const s=this.headers[t];this.escapeHeaderValues&&"CONNECT"!==this.command&&"CONNECTED"!==this.command?e.push(`${t}:${j.hdrValueEscape(`${s}`)}`):e.push(`${t}:${s}`)}return(this.isBinaryBody||!this.isBodyEmpty()&&!this.skipContentLengthHeader)&&e.push(`content-length:${this.bodyLength()}`),e.join(U)+U+U}isBodyEmpty(){return 0===this.bodyLength()}bodyLength(){const e=this.binaryBody;return e?e.length:0}static sizeOfUTF8(e){return e?(new TextEncoder).encode(e).length:0}static toUnit8Array(e,t){const s=(new TextEncoder).encode(e),i=new Uint8Array([0]),n=new Uint8Array(s.length+t.length+i.length);return n.set(s),n.set(t,s.length),n.set(i,s.length+t.length),n}static marshall(e){return new j(e).serialize()}static hdrValueEscape(e){return e.replace(/\\/g,"\\\\").replace(/\r/g,"\\r").replace(/\n/g,"\\n").replace(/:/g,"\\c")}static hdrValueUnEscape(e){return e.replace(/\\r/g,"\r").replace(/\\n/g,"\n").replace(/\\c/g,":").replace(/\\\\/g,"\\")}}class ${constructor(e,t){this.onFrame=e,this.onIncomingPing=t,this._encoder=new TextEncoder,this._decoder=new TextDecoder,this._token=[],this._initState()}parseChunk(e,t=!1){let s;if(s="string"==typeof e?this._encoder.encode(e):new Uint8Array(e),t&&0!==s[s.length-1]){const e=new Uint8Array(s.length+1);e.set(s,0),e[s.length]=0,s=e}for(let e=0;e<s.length;e++){const t=s[e];this._onByte(t)}}_collectFrame(e){0!==e&&13!==e&&(10!==e?(this._onByte=this._collectCommand,this._reinjectByte(e)):this.onIncomingPing())}_collectCommand(e){if(13!==e)return 10===e?(this._results.command=this._consumeTokenAsUTF8(),void(this._onByte=this._collectHeaders)):void this._consumeByte(e)}_collectHeaders(e){13!==e&&(10!==e?(this._onByte=this._collectHeaderKey,this._reinjectByte(e)):this._setupCollectBody())}_reinjectByte(e){this._onByte(e)}_collectHeaderKey(e){if(58===e)return this._headerKey=this._consumeTokenAsUTF8(),void(this._onByte=this._collectHeaderValue);this._consumeByte(e)}_collectHeaderValue(e){if(13!==e)return 10===e?(this._results.headers.push([this._headerKey,this._consumeTokenAsUTF8()]),this._headerKey=void 0,void(this._onByte=this._collectHeaders)):void this._consumeByte(e)}_setupCollectBody(){const e=this._results.headers.filter(e=>"content-length"===e[0])[0];e?(this._bodyBytesRemaining=parseInt(e[1],10),this._onByte=this._collectBodyFixedSize):this._onByte=this._collectBodyNullTerminated}_collectBodyNullTerminated(e){0!==e?this._consumeByte(e):this._retrievedBody()}_collectBodyFixedSize(e){0!==this._bodyBytesRemaining--?this._consumeByte(e):this._retrievedBody()}_retrievedBody(){this._results.binaryBody=this._consumeTokenAsRaw();try{this.onFrame(this._results)}catch(e){console.log("Ignoring an exception thrown by a frame handler. Original exception: ",e)}this._initState()}_consumeByte(e){this._token.push(e)}_consumeTokenAsUTF8(){return this._decoder.decode(this._consumeTokenAsRaw())}_consumeTokenAsRaw(){const e=new Uint8Array(this._token);return this._token=[],e}_initState(){this._results={command:void 0,headers:[],binaryBody:void 0},this._token=[],this._headerKey=void 0,this._onByte=this._collectFrame}}var F,W,G,V;!function(e){e[e.CONNECTING=0]="CONNECTING",e[e.OPEN=1]="OPEN",e[e.CLOSING=2]="CLOSING",e[e.CLOSED=3]="CLOSED"}(F||(F={})),function(e){e[e.ACTIVE=0]="ACTIVE",e[e.DEACTIVATING=1]="DEACTIVATING",e[e.INACTIVE=2]="INACTIVE"}(W||(W={})),function(e){e[e.LINEAR=0]="LINEAR",e[e.EXPONENTIAL=1]="EXPONENTIAL"}(G||(G={})),function(e){e.Interval="interval",e.Worker="worker"}(V||(V={}));class H{constructor(e,t=V.Interval,s){this._interval=e,this._strategy=t,this._debug=s,this._workerScript=`\n var startTime = Date.now();\n setInterval(function() {\n self.postMessage(Date.now() - startTime);\n }, ${this._interval});\n `}start(e){this.stop(),this.shouldUseWorker()?this.runWorker(e):this.runInterval(e)}stop(){this.disposeWorker(),this.disposeInterval()}shouldUseWorker(){return"undefined"!=typeof Worker&&this._strategy===V.Worker}runWorker(e){this._debug("Using runWorker for outgoing pings"),this._worker||(this._worker=new Worker(URL.createObjectURL(new Blob([this._workerScript],{type:"text/javascript"}))),this._worker.onmessage=t=>e(t.data))}runInterval(e){if(this._debug("Using runInterval for outgoing pings"),!this._timer){const t=Date.now();this._timer=setInterval(()=>{e(Date.now()-t)},this._interval)}}disposeWorker(){this._worker&&(this._worker.terminate(),delete this._worker,this._debug("Outgoing ping disposeWorker"))}disposeInterval(){this._timer&&(clearInterval(this._timer),delete this._timer,this._debug("Outgoing ping disposeInterval"))}}class B{constructor(e){this.versions=e}supportedVersions(){return this.versions.join(",")}protocolVersions(){return this.versions.map(e=>`v${e.replace(".","")}.stomp`)}}B.V1_0="1.0",B.V1_1="1.1",B.V1_2="1.2",B.default=new B([B.V1_2,B.V1_1,B.V1_0]);class q{get connectedVersion(){return this._connectedVersion}get connected(){return this._connected}constructor(e,t,s){this._client=e,this._webSocket=t,this._connected=!1,this._serverFrameHandlers={CONNECTED:e=>{this.debug(`connected to server ${e.headers.server}`),this._connected=!0,this._connectedVersion=e.headers.version,this._connectedVersion===B.V1_2&&(this._escapeHeaderValues=!0),this._setupHeartbeat(e.headers),this.onConnect(e)},MESSAGE:e=>{const t=e.headers.subscription,s=this._subscriptions[t]||this.onUnhandledMessage,i=e,n=this,r=this._connectedVersion===B.V1_2?i.headers.ack:i.headers["message-id"];i.ack=(e={})=>n.ack(r,t,e),i.nack=(e={})=>n.nack(r,t,e),s(i)},RECEIPT:e=>{const t=this._receiptWatchers[e.headers["receipt-id"]];t?(t(e),delete this._receiptWatchers[e.headers["receipt-id"]]):this.onUnhandledReceipt(e)},ERROR:e=>{this.onStompError(e)}},this._counter=0,this._subscriptions={},this._receiptWatchers={},this._partialData="",this._escapeHeaderValues=!1,this._lastServerActivityTS=Date.now(),this.debug=s.debug,this.stompVersions=s.stompVersions,this.connectHeaders=s.connectHeaders,this.disconnectHeaders=s.disconnectHeaders,this.heartbeatIncoming=s.heartbeatIncoming,this.heartbeatToleranceMultiplier=s.heartbeatGracePeriods,this.heartbeatOutgoing=s.heartbeatOutgoing,this.splitLargeFrames=s.splitLargeFrames,this.maxWebSocketChunkSize=s.maxWebSocketChunkSize,this.forceBinaryWSFrames=s.forceBinaryWSFrames,this.logRawCommunication=s.logRawCommunication,this.appendMissingNULLonIncoming=s.appendMissingNULLonIncoming,this.discardWebsocketOnCommFailure=s.discardWebsocketOnCommFailure,this.onConnect=s.onConnect,this.onDisconnect=s.onDisconnect,this.onStompError=s.onStompError,this.onWebSocketClose=s.onWebSocketClose,this.onWebSocketError=s.onWebSocketError,this.onUnhandledMessage=s.onUnhandledMessage,this.onUnhandledReceipt=s.onUnhandledReceipt,this.onUnhandledFrame=s.onUnhandledFrame,this.onHeartbeatReceived=s.onHeartbeatReceived,this.onHeartbeatLost=s.onHeartbeatLost}start(){const e=new $(e=>{const t=j.fromRawFrame(e,this._escapeHeaderValues);this.logRawCommunication||this.debug(`<<< ${t}`);(this._serverFrameHandlers[t.command]||this.onUnhandledFrame)(t)},()=>{this.debug("<<< PONG"),this.onHeartbeatReceived()});this._webSocket.onmessage=t=>{if(this.debug("Received data"),this._lastServerActivityTS=Date.now(),this.logRawCommunication){const e=t.data instanceof ArrayBuffer?(new TextDecoder).decode(t.data):t.data;this.debug(`<<< ${e}`)}e.parseChunk(t.data,this.appendMissingNULLonIncoming)},this._webSocket.onclose=e=>{this.debug(`Connection closed to ${this._webSocket.url}`),this._cleanUp(),this.onWebSocketClose(e)},this._webSocket.onerror=e=>{this.onWebSocketError(e)},this._webSocket.onopen=()=>{const e=Object.assign({},this.connectHeaders);this.debug("Web Socket Opened..."),e["accept-version"]=this.stompVersions.supportedVersions(),e["heart-beat"]=[this.heartbeatOutgoing,this.heartbeatIncoming].join(","),this._transmit({command:"CONNECT",headers:e})}}_setupHeartbeat(e){if(e.version!==B.V1_1&&e.version!==B.V1_2)return;if(!e["heart-beat"])return;const[t,s]=e["heart-beat"].split(",").map(e=>parseInt(e,10));if(0!==this.heartbeatOutgoing&&0!==s){const e=Math.max(this.heartbeatOutgoing,s);this.debug(`send PING every ${e}ms`),this._pinger=new H(e,this._client.heartbeatStrategy,this.debug),this._pinger.start(()=>{this._webSocket.readyState===F.OPEN&&(this._webSocket.send(U),this.debug(">>> PING"))})}if(0!==this.heartbeatIncoming&&0!==t){const e=Math.max(this.heartbeatIncoming,t);this.debug(`check PONG every ${e}ms`),this._ponger=setInterval(()=>{const t=Date.now()-this._lastServerActivityTS;t>e*this.heartbeatToleranceMultiplier&&(this.debug(`did not receive server activity for the last ${t}ms`),this.onHeartbeatLost(),this._closeOrDiscardWebsocket())},e)}}_closeOrDiscardWebsocket(){this.discardWebsocketOnCommFailure?(this.debug("Discarding websocket, the underlying socket may linger for a while"),this.discardWebsocket()):(this.debug("Issuing close on the websocket"),this._closeWebsocket())}forceDisconnect(){this._webSocket&&(this._webSocket.readyState!==F.CONNECTING&&this._webSocket.readyState!==F.OPEN||this._closeOrDiscardWebsocket())}_closeWebsocket(){this._webSocket.onmessage=()=>{},this._webSocket.close()}discardWebsocket(){var e,t;"function"!=typeof this._webSocket.terminate&&(e=this._webSocket,t=e=>this.debug(e),e.terminate=function(){const s=()=>{};this.onerror=s,this.onmessage=s,this.onopen=s;const i=new Date,n=Math.random().toString().substring(2,8),r=this.onclose;this.onclose=e=>{const s=(new Date).getTime()-i.getTime();t(`Discarded socket (#${n}) closed after ${s}ms, with code/reason: ${e.code}/${e.reason}`)},this.close(),r?.call(e,{code:4001,reason:`Quick discarding socket (#${n}) without waiting for the shutdown sequence.`,wasClean:!1})}),this._webSocket.terminate()}_transmit(e){const{command:t,headers:s,body:i,binaryBody:n,skipContentLengthHeader:r}=e,o=new j({command:t,headers:s,body:i,binaryBody:n,escapeHeaderValues:this._escapeHeaderValues,skipContentLengthHeader:r});let a=o.serialize();if(this.logRawCommunication?this.debug(`>>> ${a}`):this.debug(`>>> ${o}`),this.forceBinaryWSFrames&&"string"==typeof a&&(a=(new TextEncoder).encode(a)),"string"==typeof a&&this.splitLargeFrames){let e=a;for(;e.length>0;){const t=e.substring(0,this.maxWebSocketChunkSize);e=e.substring(this.maxWebSocketChunkSize),this._webSocket.send(t),this.debug(`chunk sent = ${t.length}, remaining = ${e.length}`)}}else this._webSocket.send(a)}dispose(){if(this.connected)try{const e=Object.assign({},this.disconnectHeaders);e.receipt||(e.receipt="close-"+this._counter++),this.watchForReceipt(e.receipt,e=>{this._closeWebsocket(),this._cleanUp(),this.onDisconnect(e)}),this._transmit({command:"DISCONNECT",headers:e})}catch(e){this.debug(`Ignoring error during disconnect ${e}`)}else this._webSocket.readyState!==F.CONNECTING&&this._webSocket.readyState!==F.OPEN||this._closeWebsocket()}_cleanUp(){this._connected=!1,this._pinger&&(this._pinger.stop(),this._pinger=void 0),this._ponger&&(clearInterval(this._ponger),this._ponger=void 0)}publish(e){const{destination:t,headers:s,body:i,binaryBody:n,skipContentLengthHeader:r}=e,o=Object.assign({destination:t},s);this._transmit({command:"SEND",headers:o,body:i,binaryBody:n,skipContentLengthHeader:r})}watchForReceipt(e,t){this._receiptWatchers[e]=t}subscribe(e,t,s={}){(s=Object.assign({},s)).id||(s.id="sub-"+this._counter++),s.destination=e,this._subscriptions[s.id]=t,this._transmit({command:"SUBSCRIBE",headers:s});const i=this;return{id:s.id,unsubscribe:e=>i.unsubscribe(s.id,e)}}unsubscribe(e,t={}){t=Object.assign({},t),delete this._subscriptions[e],t.id=e,this._transmit({command:"UNSUBSCRIBE",headers:t})}begin(e){const t=e||"tx-"+this._counter++;this._transmit({command:"BEGIN",headers:{transaction:t}});const s=this;return{id:t,commit(){s.commit(t)},abort(){s.abort(t)}}}commit(e){this._transmit({command:"COMMIT",headers:{transaction:e}})}abort(e){this._transmit({command:"ABORT",headers:{transaction:e}})}ack(e,t,s={}){s=Object.assign({},s),this._connectedVersion===B.V1_2?s.id=e:s["message-id"]=e,s.subscription=t,this._transmit({command:"ACK",headers:s})}nack(e,t,s={}){return s=Object.assign({},s),this._connectedVersion===B.V1_2?s.id=e:s["message-id"]=e,s.subscription=t,this._transmit({command:"NACK",headers:s})}}class J{get webSocket(){return this._stompHandler?._webSocket}get disconnectHeaders(){return this._disconnectHeaders}set disconnectHeaders(e){this._disconnectHeaders=e,this._stompHandler&&(this._stompHandler.disconnectHeaders=this._disconnectHeaders)}get connected(){return!!this._stompHandler&&this._stompHandler.connected}get connectedVersion(){return this._stompHandler?this._stompHandler.connectedVersion:void 0}get active(){return this.state===W.ACTIVE}_changeState(e){this.state=e,this.onChangeState(e)}constructor(e={}){this.stompVersions=B.default,this.connectionTimeout=0,this.reconnectDelay=5e3,this._nextReconnectDelay=0,this.maxReconnectDelay=9e5,this.reconnectTimeMode=G.LINEAR,this.heartbeatIncoming=1e4,this.heartbeatToleranceMultiplier=2,this.heartbeatOutgoing=1e4,this.heartbeatStrategy=V.Interval,this.splitLargeFrames=!1,this.maxWebSocketChunkSize=8192,this.forceBinaryWSFrames=!1,this.appendMissingNULLonIncoming=!1,this.discardWebsocketOnCommFailure=!1,this.state=W.INACTIVE;const t=()=>{};this.debug=t,this.beforeConnect=t,this.onConnect=t,this.onDisconnect=t,this.onUnhandledMessage=t,this.onUnhandledReceipt=t,this.onUnhandledFrame=t,this.onHeartbeatReceived=t,this.onHeartbeatLost=t,this.onStompError=t,this.onWebSocketClose=t,this.onWebSocketError=t,this.logRawCommunication=!1,this.onChangeState=t,this.connectHeaders={},this._disconnectHeaders={},this.configure(e)}configure(e){Object.assign(this,e),this.maxReconnectDelay>0&&this.maxReconnectDelay<this.reconnectDelay&&(this.debug(`Warning: maxReconnectDelay (${this.maxReconnectDelay}ms) is less than reconnectDelay (${this.reconnectDelay}ms). Using reconnectDelay as the maxReconnectDelay delay.`),this.maxReconnectDelay=this.reconnectDelay)}activate(){const e=()=>{this.active?this.debug("Already ACTIVE, ignoring request to activate"):(this._changeState(W.ACTIVE),this._nextReconnectDelay=this.reconnectDelay,this._connect())};this.state===W.DEACTIVATING?(this.debug("Waiting for deactivation to finish before activating"),this.deactivate().then(()=>{e()})):e()}async _connect(){if(await this.beforeConnect(this),this._stompHandler)return void this.debug("There is already a stompHandler, skipping the call to connect");if(!this.active)return void this.debug("Client has been marked inactive, will not attempt to connect");this.connectionTimeout>0&&(this._connectionWatcher&&clearTimeout(this._connectionWatcher),this._connectionWatcher=setTimeout(()=>{this.connected||(this.debug(`Connection not established in ${this.connectionTimeout}ms, closing socket`),this.forceDisconnect())},this.connectionTimeout)),this.debug("Opening Web Socket...");const e=this._createWebSocket();this._stompHandler=new q(this,e,{debug:this.debug,stompVersions:this.stompVersions,connectHeaders:this.connectHeaders,disconnectHeaders:this._disconnectHeaders,heartbeatIncoming:this.heartbeatIncoming,heartbeatGracePeriods:this.heartbeatToleranceMultiplier,heartbeatOutgoing:this.heartbeatOutgoing,heartbeatStrategy:this.heartbeatStrategy,splitLargeFrames:this.splitLargeFrames,maxWebSocketChunkSize:this.maxWebSocketChunkSize,forceBinaryWSFrames:this.forceBinaryWSFrames,logRawCommunication:this.logRawCommunication,appendMissingNULLonIncoming:this.appendMissingNULLonIncoming,discardWebsocketOnCommFailure:this.discardWebsocketOnCommFailure,onConnect:e=>{if(this._connectionWatcher&&(clearTimeout(this._connectionWatcher),this._connectionWatcher=void 0),this._nextReconnectDelay=this.reconnectDelay,!this.active)return this.debug("STOMP got connected while deactivate was issued, will disconnect now"),void this._disposeStompHandler();this.onConnect(e)},onDisconnect:e=>{this.onDisconnect(e)},onStompError:e=>{this.onStompError(e)},onWebSocketClose:e=>{this._stompHandler=void 0,this.state===W.DEACTIVATING&&this._changeState(W.INACTIVE),this.onWebSocketClose(e),this.active&&this._schedule_reconnect()},onWebSocketError:e=>{this.onWebSocketError(e)},onUnhandledMessage:e=>{this.onUnhandledMessage(e)},onUnhandledReceipt:e=>{this.onUnhandledReceipt(e)},onUnhandledFrame:e=>{this.onUnhandledFrame(e)},onHeartbeatReceived:()=>{this.onHeartbeatReceived()},onHeartbeatLost:()=>{this.onHeartbeatLost()}}),this._stompHandler.start()}_createWebSocket(){let e;if(this.webSocketFactory)e=this.webSocketFactory();else{if(!this.brokerURL)throw new Error("Either brokerURL or webSocketFactory must be provided");e=new WebSocket(this.brokerURL,this.stompVersions.protocolVersions())}return e.binaryType="arraybuffer",e}_schedule_reconnect(){this._nextReconnectDelay>0&&(this.debug(`STOMP: scheduling reconnection in ${this._nextReconnectDelay}ms`),this._reconnector=setTimeout(()=>{this.reconnectTimeMode===G.EXPONENTIAL&&(this._nextReconnectDelay=2*this._nextReconnectDelay,0!==this.maxReconnectDelay&&(this._nextReconnectDelay=Math.min(this._nextReconnectDelay,this.maxReconnectDelay))),this._connect()},this._nextReconnectDelay))}async deactivate(e={}){const t=e.force||!1,s=this.active;let i;if(this.state===W.INACTIVE)return this.debug("Already INACTIVE, nothing more to do"),Promise.resolve();if(this._changeState(W.DEACTIVATING),this._nextReconnectDelay=0,this._reconnector&&(clearTimeout(this._reconnector),this._reconnector=void 0),!this._stompHandler||this.webSocket.readyState===F.CLOSED)return this._changeState(W.INACTIVE),Promise.resolve();{const e=this._stompHandler.onWebSocketClose;i=new Promise((t,s)=>{this._stompHandler.onWebSocketClose=s=>{e(s),t()}})}return t?this._stompHandler?.discardWebsocket():s&&this._disposeStompHandler(),i}forceDisconnect(){this._stompHandler&&this._stompHandler.forceDisconnect()}_disposeStompHandler(){this._stompHandler&&this._stompHandler.dispose()}publish(e){this._checkConnection(),this._stompHandler.publish(e)}_checkConnection(){if(!this.connected)throw new TypeError("There is no underlying STOMP connection")}watchForReceipt(e,t){this._checkConnection(),this._stompHandler.watchForReceipt(e,t)}subscribe(e,t,s={}){return this._checkConnection(),this._stompHandler.subscribe(e,t,s)}unsubscribe(e,t={}){this._checkConnection(),this._stompHandler.unsubscribe(e,t)}begin(e){return this._checkConnection(),this._stompHandler.begin(e)}commit(e){this._checkConnection(),this._stompHandler.commit(e)}abort(e){this._checkConnection(),this._stompHandler.abort(e)}ack(e,t,s={}){this._checkConnection(),this._stompHandler.ack(e,t,s)}nack(e,t,s={}){this._checkConnection(),this._stompHandler.nack(e,t,s)}}var z="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};function K(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var X,Y,Q,Z,ee,te,se={exports:{}},ie={};function ne(){if(Q)return Y;Q=1;var e=(X||(X=1,z.crypto&&z.crypto.getRandomValues?ie.randomBytes=function(e){var t=new Uint8Array(e);return z.crypto.getRandomValues(t),t}:ie.randomBytes=function(e){for(var t=new Array(e),s=0;s<e;s++)t[s]=Math.floor(256*Math.random());return t}),ie),t="abcdefghijklmnopqrstuvwxyz012345";return Y={string:function(s){for(var i=e.randomBytes(s),n=[],r=0;r<s;r++)n.push(t.substr(i[r]%32,1));return n.join("")},number:function(e){return Math.floor(Math.random()*e)},numberString:function(e){var t=(""+(e-1)).length;return(new Array(t+1).join("0")+this.number(e)).slice(-t)}}}function re(){return Z||(Z=1,function(e){var t=ne(),s={},i=!1,n=z.chrome&&z.chrome.app&&z.chrome.app.runtime;e.exports={attachEvent:function(e,t){void 0!==z.addEventListener?z.addEventListener(e,t,!1):z.document&&z.attachEvent&&(z.document.attachEvent("on"+e,t),z.attachEvent("on"+e,t))},detachEvent:function(e,t){void 0!==z.addEventListener?z.removeEventListener(e,t,!1):z.document&&z.detachEvent&&(z.document.detachEvent("on"+e,t),z.detachEvent("on"+e,t))},unloadAdd:function(e){if(n)return null;var r=t.string(8);return s[r]=e,i&&setTimeout(this.triggerUnloadCallbacks,0),r},unloadDel:function(e){e in s&&delete s[e]},triggerUnloadCallbacks:function(){for(var e in s)s[e](),delete s[e]}};n||e.exports.attachEvent("unload",function(){i||(i=!0,e.exports.triggerUnloadCallbacks())})}(se)),se.exports}var oe,ae,ce,he,le,de={};function ue(){if(ce)return ae;ce=1;var e=te?ee:(te=1,ee=function(e,t){if(t=t.split(":")[0],!(e=+e))return!1;switch(t){case"http":case"ws":return 80!==e;case"https":case"wss":return 443!==e;case"ftp":return 21!==e;case"gopher":return 70!==e;case"file":return!1}return 0!==e}),t=function(){if(oe)return de;oe=1;var e=Object.prototype.hasOwnProperty;function t(e){try{return decodeURIComponent(e.replace(/\+/g," "))}catch(e){return null}}function s(e){try{return encodeURIComponent(e)}catch(e){return null}}return de.stringify=function(t,i){i=i||"";var n,r,o=[];for(r in"string"!=typeof i&&(i="?"),t)if(e.call(t,r)){if((n=t[r])||null!=n&&!isNaN(n)||(n=""),r=s(r),n=s(n),null===r||null===n)continue;o.push(r+"="+n)}return o.length?i+o.join("&"):""},de.parse=function(e){for(var s,i=/([^=?#&]+)=?([^&]*)/g,n={};s=i.exec(e);){var r=t(s[1]),o=t(s[2]);null===r||null===o||r in n||(n[r]=o)}return n},de}(),s=/^[\x00-\x20\u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]+/,i=/[\n\r\t]/g,n=/^[A-Za-z][A-Za-z0-9+-.]*:\/\//,r=/:\d+$/,o=/^([a-z][a-z0-9.+-]*:)?(\/\/)?([\\/]+)?([\S\s]*)/i,a=/^[a-zA-Z]:/;function c(e){return(e||"").toString().replace(s,"")}var h=[["#","hash"],["?","query"],function(e,t){return u(t.protocol)?e.replace(/\\/g,"/"):e},["/","pathname"],["@","auth",1],[NaN,"host",void 0,1,1],[/:(\d*)$/,"port",void 0,1],[NaN,"hostname",void 0,1,1]],l={hash:1,query:1};function d(e){var t,s=("undefined"!=typeof window?window:void 0!==z?z:"undefined"!=typeof self?self:{}).location||{},i={},r=typeof(e=e||s);if("blob:"===e.protocol)i=new g(unescape(e.pathname),{});else if("string"===r)for(t in i=new g(e,{}),l)delete i[t];else if("object"===r){for(t in e)t in l||(i[t]=e[t]);void 0===i.slashes&&(i.slashes=n.test(e.href))}return i}function u(e){return"file:"===e||"ftp:"===e||"http:"===e||"https:"===e||"ws:"===e||"wss:"===e}function p(e,t){e=(e=c(e)).replace(i,""),t=t||{};var s,n=o.exec(e),r=n[1]?n[1].toLowerCase():"",a=!!n[2],h=!!n[3],l=0;return a?h?(s=n[2]+n[3]+n[4],l=n[2].length+n[3].length):(s=n[2]+n[4],l=n[2].length):h?(s=n[3]+n[4],l=n[3].length):s=n[4],"file:"===r?l>=2&&(s=s.slice(2)):u(r)?s=n[4]:r?a&&(s=s.slice(2)):l>=2&&u(t.protocol)&&(s=n[4]),{protocol:r,slashes:a||u(r),slashesCount:l,rest:s}}function g(s,n,r){if(s=(s=c(s)).replace(i,""),!(this instanceof g))return new g(s,n,r);var o,l,m,_,f,y,b=h.slice(),v=typeof n,w=this,S=0;for("object"!==v&&"string"!==v&&(r=n,n=null),r&&"function"!=typeof r&&(r=t.parse),o=!(l=p(s||"",n=d(n))).protocol&&!l.slashes,w.slashes=l.slashes||o&&n.slashes,w.protocol=l.protocol||n.protocol||"",s=l.rest,("file:"===l.protocol&&(2!==l.slashesCount||a.test(s))||!l.slashes&&(l.protocol||l.slashesCount<2||!u(w.protocol)))&&(b[3]=[/(.*)/,"pathname"]);S<b.length;S++)"function"!=typeof(_=b[S])?(m=_[0],y=_[1],m!=m?w[y]=s:"string"==typeof m?~(f="@"===m?s.lastIndexOf(m):s.indexOf(m))&&("number"==typeof _[2]?(w[y]=s.slice(0,f),s=s.slice(f+_[2])):(w[y]=s.slice(f),s=s.slice(0,f))):(f=m.exec(s))&&(w[y]=f[1],s=s.slice(0,f.index)),w[y]=w[y]||o&&_[3]&&n[y]||"",_[4]&&(w[y]=w[y].toLowerCase())):s=_(s,w);r&&(w.query=r(w.query)),o&&n.slashes&&"/"!==w.pathname.charAt(0)&&(""!==w.pathname||""!==n.pathname)&&(w.pathname=function(e,t){if(""===e)return t;for(var s=(t||"/").split("/").slice(0,-1).concat(e.split("/")),i=s.length,n=s[i-1],r=!1,o=0;i--;)"."===s[i]?s.splice(i,1):".."===s[i]?(s.splice(i,1),o++):o&&(0===i&&(r=!0),s.splice(i,1),o--);return r&&s.unshift(""),"."!==n&&".."!==n||s.push(""),s.join("/")}(w.pathname,n.pathname)),"/"!==w.pathname.charAt(0)&&u(w.protocol)&&(w.pathname="/"+w.pathname),e(w.port,w.protocol)||(w.host=w.hostname,w.port=""),w.username=w.password="",w.auth&&(~(f=w.auth.indexOf(":"))?(w.username=w.auth.slice(0,f),w.username=encodeURIComponent(decodeURIComponent(w.username)),w.password=w.auth.slice(f+1),w.password=encodeURIComponent(decodeURIComponent(w.password))):w.username=encodeURIComponent(decodeURIComponent(w.auth)),w.auth=w.password?w.username+":"+w.password:w.username),w.origin="file:"!==w.protocol&&u(w.protocol)&&w.host?w.protocol+"//"+w.host:"null",w.href=w.toString()}return g.prototype={set:function(s,i,n){var o=this;switch(s){case"query":"string"==typeof i&&i.length&&(i=(n||t.parse)(i)),o[s]=i;break;case"port":o[s]=i,e(i,o.protocol)?i&&(o.host=o.hostname+":"+i):(o.host=o.hostname,o[s]="");break;case"hostname":o[s]=i,o.port&&(i+=":"+o.port),o.host=i;break;case"host":o[s]=i,r.test(i)?(i=i.split(":"),o.port=i.pop(),o.hostname=i.join(":")):(o.hostname=i,o.port="");break;case"protocol":o.protocol=i.toLowerCase(),o.slashes=!n;break;case"pathname":case"hash":if(i){var a="pathname"===s?"/":"#";o[s]=i.charAt(0)!==a?a+i:i}else o[s]=i;break;case"username":case"password":o[s]=encodeURIComponent(i);break;case"auth":var c=i.indexOf(":");~c?(o.username=i.slice(0,c),o.username=encodeURIComponent(decodeURIComponent(o.username)),o.password=i.slice(c+1),o.password=encodeURIComponent(decodeURIComponent(o.password))):o.username=encodeURIComponent(decodeURIComponent(i))}for(var l=0;l<h.length;l++){var d=h[l];d[4]&&(o[d[1]]=o[d[1]].toLowerCase())}return o.auth=o.password?o.username+":"+o.password:o.username,o.origin="file:"!==o.protocol&&u(o.protocol)&&o.host?o.protocol+"//"+o.host:"null",o.href=o.toString(),o},toString:function(e){e&&"function"==typeof e||(e=t.stringify);var s,i=this,n=i.host,o=i.protocol;o&&":"!==o.charAt(o.length-1)&&(o+=":");var a=o+(i.protocol&&i.slashes||u(i.protocol)?"//":"");return i.username?(a+=i.username,i.password&&(a+=":"+i.password),a+="@"):i.password?(a+=":"+i.password,a+="@"):"file:"!==i.protocol&&u(i.protocol)&&!n&&"/"!==i.pathname&&(a+="@"),(":"===n[n.length-1]||r.test(i.hostname)&&!i.port)&&(n+=":"),a+=n+i.pathname,(s="object"==typeof i.query?e(i.query):i.query)&&(a+="?"!==s.charAt(0)?"?"+s:s),i.hash&&(a+=i.hash),a}},g.extractProtocol=p,g.location=d,g.trimLeft=c,g.qs=t,ae=g}function pe(){if(le)return he;le=1;var e=ue();return he={getOrigin:function(t){if(!t)return null;var s=new e(t);if("file:"===s.protocol)return null;var i=s.port;return i||(i="https:"===s.protocol?"443":"80"),s.protocol+"//"+s.hostname+":"+i},isOriginEqual:function(e,t){return this.getOrigin(e)===this.getOrigin(t)},isSchemeEqual:function(e,t){return e.split(":")[0]===t.split(":")[0]},addPath:function(e,t){var s=e.split("?");return s[0]+t+(s[1]?"?"+s[1]:"")},addQuery:function(e,t){return e+(-1===e.indexOf("?")?"?"+t:"&"+t)},isLoopbackAddr:function(e){return/^127\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$/i.test(e)||/^\[::1\]$/.test(e)}}}var ge,me={exports:{}};function _e(){return ge||(ge=1,"function"==typeof Object.create?me.exports=function(e,t){t&&(e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}))}:me.exports=function(e,t){if(t){e.super_=t;var s=function(){};s.prototype=t.prototype,e.prototype=new s,e.prototype.constructor=e}}),me.exports}var fe,ye,be,ve={};function we(){if(ye)return fe;function e(){this._listeners={}}return ye=1,e.prototype.addEventListener=function(e,t){e in this._listeners||(this._listeners[e]=[]);var s=this._listeners[e];-1===s.indexOf(t)&&(s=s.concat([t])),this._listeners[e]=s},e.prototype.removeEventListener=function(e,t){var s=this._listeners[e];if(s){var i=s.indexOf(t);-1===i||(s.length>1?this._listeners[e]=s.slice(0,i).concat(s.slice(i+1)):delete this._listeners[e])}},e.prototype.dispatchEvent=function(){var e=arguments[0],t=e.type,s=1===arguments.length?[e]:Array.apply(null,arguments);if(this["on"+t]&&this["on"+t].apply(this,s),t in this._listeners)for(var i=this._listeners[t],n=0;n<i.length;n++)i[n].apply(this,s)},fe=e}function Se(){if(be)return ve;be=1;var e=_e(),t=we();function s(){t.call(this)}return e(s,t),s.prototype.removeAllListeners=function(e){e?delete this._listeners[e]:this._listeners={}},s.prototype.once=function(e,t){var s=this,i=!1;this.on(e,function n(){s.removeListener(e,n),i||(i=!0,t.apply(this,arguments))})},s.prototype.emit=function(){var e=arguments[0],t=this._listeners[e];if(t){for(var s=arguments.length,i=new Array(s-1),n=1;n<s;n++)i[n-1]=arguments[n];for(var r=0;r<t.length;r++)t[r].apply(this,i)}},s.prototype.on=s.prototype.addListener=t.prototype.addEventListener,s.prototype.removeListener=t.prototype.removeEventListener,ve.EventEmitter=s,ve}var Ee,Ie,Te,Re,Ce,Ae,ke,Me,Ne,Oe,Le,De,Pe,Ue,xe,je,$e,Fe,We,Ge,Ve,He,Be,qe,Je,ze,Ke,Xe,Ye,Qe,Ze,et,tt,st,it,nt={exports:{}};function rt(){if(Te)return Ie;Te=1;var e=re(),t=pe(),s=_e(),i=Se().EventEmitter,n=function(){if(Ee)return nt.exports;Ee=1;var e=z.WebSocket||z.MozWebSocket;return nt.exports=e?function(t){return new e(t)}:void 0,nt.exports}();function r(s,o,a){if(!r.enabled())throw new Error("Transport created when disabled");i.call(this);var c=this,h=t.addPath(s,"/websocket");h="https"===h.slice(0,5)?"wss"+h.slice(5):"ws"+h.slice(4),this.url=h,this.ws=new n(this.url,[],a),this.ws.onmessage=function(e){e.data,c.emit("message",e.data)},this.unloadRef=e.unloadAdd(function(){c.ws.close()}),this.ws.onclose=function(e){e.code,e.reason,c.emit("close",e.code,e.reason),c._cleanup()},this.ws.onerror=function(e){c.emit("close",1006,"WebSocket connection broken"),c._cleanup()}}return s(r,i),r.prototype.send=function(e){var t="["+e+"]";this.ws.send(t)},r.prototype.close=function(){var e=this.ws;this._cleanup(),e&&e.close()},r.prototype._cleanup=function(){var t=this.ws;t&&(t.onmessage=t.onclose=t.onerror=null),e.unloadDel(this.unloadRef),this.unloadRef=this.ws=null,this.removeAllListeners()},r.enabled=function(){return!!n},r.transportName="websocket",r.roundTrips=2,Ie=r}function ot(){if(Ne)return Me;Ne=1;var e=_e(),t=pe(),s=function(){if(Ce)return Re;Ce=1;var e=_e(),t=Se().EventEmitter;function s(e,s){t.call(this),this.sendBuffer=[],this.sender=s,this.url=e}return e(s,t),s.prototype.send=function(e){this.sendBuffer.push(e),this.sendStop||this.sendSchedule()},s.prototype.sendScheduleWait=function(){var e,t=this;this.sendStop=function(){t.sendStop=null,clearTimeout(e)},e=setTimeout(function(){t.sendStop=null,t.sendSchedule()},25)},s.prototype.sendSchedule=function(){this.sendBuffer.length;var e=this;if(this.sendBuffer.length>0){var t="["+this.sendBuffer.join(",")+"]";this.sendStop=this.sender(this.url,t,function(t){e.sendStop=null,t?(e.emit("close",t.code||1006,"Sending error: "+t),e.close()):e.sendScheduleWait()}),this.sendBuffer=[]}},s.prototype._cleanup=function(){this.removeAllListeners()},s.prototype.close=function(){this._cleanup(),this.sendStop&&(this.sendStop(),this.sendStop=null)},Re=s}(),i=function(){if(ke)return Ae;ke=1;var e=_e(),t=Se().EventEmitter;function s(e,s,i){t.call(this),this.Receiver=e,this.receiveUrl=s,this.AjaxObject=i,this._scheduleReceiver()}return e(s,t),s.prototype._scheduleReceiver=function(){var e=this,t=this.poll=new this.Receiver(this.receiveUrl,this.AjaxObject);t.on("message",function(t){e.emit("message",t)}),t.once("close",function(s,i){e.pollIsClosing,e.poll=t=null,e.pollIsClosing||("network"===i?e._scheduleReceiver():(e.emit("close",s||1006,i),e.removeAllListeners()))})},s.prototype.abort=function(){this.removeAllListeners(),this.pollIsClosing=!0,this.poll&&this.poll.abort()},Ae=s}();function n(e,n,r,o,a){var c=t.addPath(e,n),h=this;s.call(this,e,r),this.poll=new i(o,c,a),this.poll.on("message",function(e){h.emit("message",e)}),this.poll.once("close",function(e,t){h.poll=null,h.emit("close",e,t),h.close()})}return e(n,s),n.prototype.close=function(){s.prototype.close.call(this),this.removeAllListeners(),this.poll&&(this.poll.abort(),this.poll=null)},Me=n}function at(){if(Le)return Oe;Le=1;var e=_e(),t=pe(),s=ot();function i(e,i,n,r){s.call(this,e,i,function(e){return function(s,i,n){var r={};"string"==typeof i&&(r.headers={"Content-type":"text/plain"});var o=t.addPath(s,"/xhr_send"),a=new e("POST",o,i,r);return a.once("finish",function(e){if(a=null,200!==e&&204!==e)return n(new Error("http status "+e));n()}),function(){a.close(),a=null;var e=new Error("Aborted");e.code=1e3,n(e)}}}(r),n,r)}return e(i,s),Oe=i}function ct(){if(Pe)return De;Pe=1;var e=_e(),t=Se().EventEmitter;function s(e,s){t.call(this);var i=this;this.bufferPosition=0,this.xo=new s("POST",e,null),this.xo.on("chunk",this._chunkHandler.bind(this)),this.xo.once("finish",function(e,t){i._chunkHandler(e,t),i.xo=null;var s=200===e?"network":"permanent";i.emit("close",null,s),i._cleanup()})}return e(s,t),s.prototype._chunkHandler=function(e,t){if(200===e&&t)for(var s=-1;;this.bufferPosition+=s+1){var i=t.slice(this.bufferPosition);if(-1===(s=i.indexOf("\n")))break;var n=i.slice(0,s);n&&this.emit("message",n)}},s.prototype._cleanup=function(){this.removeAllListeners()},s.prototype.abort=function(){this.xo&&(this.xo.close(),this.emit("close",null,"user"),this.xo=null),this._cleanup()},De=s}function ht(){if(xe)return Ue;xe=1;var e=Se().EventEmitter,t=_e(),s=re(),i=pe(),n=z.XMLHttpRequest;function r(t,s,i,n){var r=this;e.call(this),setTimeout(function(){r._start(t,s,i,n)},0)}t(r,e),r.prototype._start=function(e,t,o,a){var c=this;try{this.xhr=new n}catch(e){}if(!this.xhr)return this.emit("finish",0,"no xhr support"),void this._cleanup();t=i.addQuery(t,"t="+ +new Date),this.unloadRef=s.unloadAdd(function(){c._cleanup(!0)});try{this.xhr.open(e,t,!0),this.timeout&&"timeout"in this.xhr&&(this.xhr.timeout=this.timeout,this.xhr.ontimeout=function(){c.emit("finish",0,""),c._cleanup(!1)})}catch(e){return this.emit("finish",0,""),void this._cleanup(!1)}if(a&&a.noCredentials||!r.supportsCORS||(this.xhr.withCredentials=!0),a&&a.headers)for(var h in a.headers)this.xhr.setRequestHeader(h,a.headers[h]);this.xhr.onreadystatechange=function(){if(c.xhr){var e,t,s=c.xhr;switch(s.readyState,s.readyState){case 3:try{t=s.status,e=s.responseText}catch(e){}1223===t&&(t=204),200===t&&e&&e.length>0&&c.emit("chunk",t,e);break;case 4:1223===(t=s.status)&&(t=204),12005!==t&&12029!==t||(t=0),s.responseText,c.emit("finish",t,s.responseText),c._cleanup(!1)}}};try{c.xhr.send(o)}catch(e){c.emit("finish",0,""),c._cleanup(!1)}},r.prototype._cleanup=function(e){if(this.xhr){if(this.removeAllListeners(),s.unloadDel(this.unloadRef),this.xhr.onreadystatechange=function(){},this.xhr.ontimeout&&(this.xhr.ontimeout=null),e)try{this.xhr.abort()}catch(e){}this.unloadRef=this.xhr=null}},r.prototype.close=function(){this._cleanup(!0)},r.enabled=!!n;var o=["Active"].concat("Object").join("X");!r.enabled&&o in z&&(n=function(){try{return new z[o]("Microsoft.XMLHTTP")}catch(e){return null}},r.enabled=!!new n);var a=!1;try{a="withCredentials"in new n}catch(e){}return r.supportsCORS=a,Ue=r}function lt(){if($e)return je;$e=1;var e=_e(),t=ht();function s(e,s,i,n){t.call(this,e,s,i,n)}return e(s,t),s.enabled=t.enabled&&t.supportsCORS,je=s}function dt(){if(We)return Fe;We=1;var e=_e(),t=ht();function s(e,s,i){t.call(this,e,s,i,{noCredentials:!0})}return e(s,t),s.enabled=t.enabled,Fe=s}function ut(){return Ve?Ge:(Ve=1,Ge={isOpera:function(){return z.navigator&&/opera/i.test(z.navigator.userAgent)},isKonqueror:function(){return z.navigator&&/konqueror/i.test(z.navigator.userAgent)},hasDomain:function(){if(!z.document)return!0;try{return!!z.document.domain}catch(e){return!1}}})}function pt(){if(Be)return He;Be=1;var e=_e(),t=at(),s=ct(),i=lt(),n=dt(),r=ut();function o(e){if(!n.enabled&&!i.enabled)throw new Error("Transport created when disabled");t.call(this,e,"/xhr_streaming",s,i)}return e(o,t),o.enabled=function(e){return!e.nullOrigin&&(!r.isOpera()&&i.enabled)},o.transportName="xhr-streaming",o.roundTrips=2,o.needBody=!!z.document,He=o}function gt(){if(Je)return qe;Je=1;var e=Se().EventEmitter,t=_e(),s=re(),i=ut(),n=pe();function r(t,s,i){var n=this;e.call(this),setTimeout(function(){n._start(t,s,i)},0)}return t(r,e),r.prototype._start=function(e,t,i){var r=this,o=new z.XDomainRequest;t=n.addQuery(t,"t="+ +new Date),o.onerror=function(){r._error()},o.ontimeout=function(){r._error()},o.onprogress=function(){o.responseText,r.emit("chunk",200,o.responseText)},o.onload=function(){r.emit("finish",200,o.responseText),r._cleanup(!1)},this.xdr=o,this.unloadRef=s.unloadAdd(function(){r._cleanup(!0)});try{this.xdr.open(e,t),this.timeout&&(this.xdr.timeout=this.timeout),this.xdr.send(i)}catch(e){this._error()}},r.prototype._error=function(){this.emit("finish",0,""),this._cleanup(!1)},r.prototype._cleanup=function(e){if(this.xdr){if(this.removeAllListeners(),s.unloadDel(this.unloadRef),this.xdr.ontimeout=this.xdr.onerror=this.xdr.onprogress=this.xdr.onload=null,e)try{this.xdr.abort()}catch(e){}this.unloadRef=this.xdr=null}},r.prototype.close=function(){this._cleanup(!0)},r.enabled=!(!z.XDomainRequest||!i.hasDomain()),qe=r}function mt(){if(Ke)return ze;Ke=1;var e=_e(),t=at(),s=ct(),i=gt();function n(e){if(!i.enabled)throw new Error("Transport created when disabled");t.call(this,e,"/xhr_streaming",s,i)}return e(n,t),n.enabled=function(e){return!e.cookie_needed&&!e.nullOrigin&&(i.enabled&&e.sameScheme)},n.transportName="xdr-streaming",n.roundTrips=2,ze=n}function _t(){return Ye?Xe:(Ye=1,Xe=z.EventSource)}function ft(){if(tt)return et;tt=1;var e=_e(),t=at(),s=function(){if(Ze)return Qe;Ze=1;var e=_e(),t=Se().EventEmitter,s=_t();function i(e){t.call(this);var i=this,n=this.es=new s(e);n.onmessage=function(e){e.data,i.emit("message",decodeURI(e.data))},n.onerror=function(e){n.readyState;var t=2!==n.readyState?"network":"permanent";i._cleanup(),i._close(t)}}return e(i,t),i.prototype.abort=function(){this._cleanup(),this._close("user")},i.prototype._cleanup=function(){var e=this.es;e&&(e.onmessage=e.onerror=null,e.close(),this.es=null)},i.prototype._close=function(e){var t=this;setTimeout(function(){t.emit("close",null,e),t.removeAllListeners()},200)},Qe=i}(),i=lt(),n=_t();function r(e){if(!r.enabled())throw new Error("Transport created when disabled");t.call(this,e,"/eventsource",s,i)}return e(r,t),r.enabled=function(){return!!n},r.transportName="eventsource",r.roundTrips=2,et=r}function yt(){return it?st:(it=1,st="1.6.1")}var bt,vt,wt,St,Et,It,Tt,Rt,Ct,At,kt,Mt,Nt,Ot,Lt,Dt,Pt,Ut,xt,jt,$t,Ft,Wt,Gt={exports:{}};function Vt(){return bt||(bt=1,function(e){var t=re(),s=ut();e.exports={WPrefix:"_jp",currentWindowId:null,polluteGlobalNamespace:function(){e.exports.WPrefix in z||(z[e.exports.WPrefix]={})},postMessage:function(t,s){z.parent!==z&&z.parent.postMessage(JSON.stringify({windowId:e.exports.currentWindowId,type:t,data:s||""}),"*")},createIframe:function(e,s){var i,n,r=z.document.createElement("iframe"),o=function(){clearTimeout(i);try{r.onload=null}catch(e){}r.onerror=null},a=function(){r&&(o(),setTimeout(function(){r&&r.parentNode.removeChild(r),r=null},0),t.unloadDel(n))},c=function(e){r&&(a(),s(e))};return r.src=e,r.style.display="none",r.style.position="absolute",r.onerror=function(){c("onerror")},r.onload=function(){clearTimeout(i),i=setTimeout(function(){c("onload timeout")},2e3)},z.document.body.appendChild(r),i=setTimeout(function(){c("timeout")},15e3),n=t.unloadAdd(a),{post:function(e,t){setTimeout(function(){try{r&&r.contentWindow&&r.contentWindow.postMessage(e,t)}catch(e){}},0)},cleanup:a,loaded:o}},createHtmlfile:function(s,i){var n,r,o,a=["Active"].concat("Object").join("X"),c=new z[a]("htmlfile"),h=function(){clearTimeout(n),o.onerror=null},l=function(){c&&(h(),t.unloadDel(r),o.parentNode.removeChild(o),o=c=null,CollectGarbage())},d=function(e){c&&(l(),i(e))};c.open(),c.write('<html><script>document.domain="'+z.document.domain+'";<\/script></html>'),c.close(),c.parentWindow[e.exports.WPrefix]=z[e.exports.WPrefix];var u=c.createElement("div");return c.body.appendChild(u),o=c.createElement("iframe"),u.appendChild(o),o.src=s,o.onerror=function(){d("onerror")},n=setTimeout(function(){d("timeout")},15e3),r=t.unloadAdd(l),{post:function(e,t){try{setTimeout(function(){o&&o.contentWindow&&o.contentWindow.postMessage(e,t)},0)}catch(e){}},cleanup:l,loaded:h}}},e.exports.iframeEnabled=!1,z.document&&(e.exports.iframeEnabled=("function"==typeof z.postMessage||"object"==typeof z.postMessage)&&!s.isKonqueror())}(Gt)),Gt.exports}function Ht(){if(wt)return vt;wt=1;var e=_e(),t=Se().EventEmitter,s=yt(),i=pe(),n=Vt(),r=re(),o=ne();function a(e,s,c){if(!a.enabled())throw new Error("Transport created when disabled");t.call(this);var h=this;this.origin=i.getOrigin(c),this.baseUrl=c,this.transUrl=s,this.transport=e,this.windowId=o.string(8);var l=i.addPath(c,"/iframe.html")+"#"+this.windowId;this.iframeObj=n.createIframe(l,function(e){h.emit("close",1006,"Unable to load an iframe ("+e+")"),h.close()}),this.onmessageCallback=this._message.bind(this),r.attachEvent("message",this.onmessageCallback)}return e(a,t),a.prototype.close=function(){if(this.removeAllListeners(),this.iframeObj){r.detachEvent("message",this.onmessageCallback);try{this.postMessage("c")}catch(e){}this.iframeObj.cleanup(),this.iframeObj=null,this.onmessageCallback=this.iframeObj=null}},a.prototype._message=function(e){if(e.data,!i.isOriginEqual(e.origin,this.origin))return e.origin,void this.origin;var t;try{t=JSON.parse(e.data)}catch(t){return void e.data}if(t.windowId!==this.windowId)return t.windowId,void this.windowId;switch(t.type){case"s":this.iframeObj.loaded(),this.postMessage("s",JSON.stringify([s,this.transport,this.transUrl,this.baseUrl]));break;case"t":this.emit("message",t.data);break;case"c":var n;try{n=JSON.parse(t.data)}catch(e){return void t.data}this.emit("close",n[0],n[1]),this.close()}},a.prototype.postMessage=function(e,t){this.iframeObj.post(JSON.stringify({windowId:this.windowId,type:e,data:t||""}),this.origin)},a.prototype.send=function(e){this.postMessage("m",e)},a.enabled=function(){return n.iframeEnabled},a.transportName="iframe",a.roundTrips=2,vt=a}function Bt(){return Et||(Et=1,St={isObject:function(e){var t=typeof e;return"function"===t||"object"===t&&!!e},extend:function(e){if(!this.isObject(e))return e;for(var t,s,i=1,n=arguments.length;i<n;i++)for(s in t=arguments[i])Object.prototype.hasOwnProperty.call(t,s)&&(e[s]=t[s]);return e}}),St}function qt(){if(Tt)return It;Tt=1;var e=_e(),t=Ht(),s=Bt();return It=function(i){function n(e,s){t.call(this,i.transportName,e,s)}return e(n,t),n.enabled=function(e,n){if(!z.document)return!1;var r=s.extend({},n);return r.sameOrigin=!0,i.enabled(r)&&t.enabled()},n.transportName="iframe-"+i.transportName,n.needBody=!0,n.roundTrips=t.roundTrips+i.roundTrips-1,n.facadeTransport=i,n},It}function Jt(){if(kt)return At;kt=1;var e=_e(),t=function(){if(Ct)return Rt;Ct=1;var e=_e(),t=Vt(),s=pe(),i=Se().EventEmitter,n=ne();function r(e){i.call(this);var o=this;t.polluteGlobalNamespace(),this.id="a"+n.string(6),e=s.addQuery(e,"c="+decodeURIComponent(t.WPrefix+"."+this.id)),r.htmlfileEnabled;var a=r.htmlfileEnabled?t.createHtmlfile:t.createIframe;z[t.WPrefix][this.id]={start:function(){o.iframeObj.loaded()},message:function(e){o.emit("message",e)},stop:function(){o._cleanup(),o._close("network")}},this.iframeObj=a(e,function(){o._cleanup(),o._close("permanent")})}e(r,i),r.prototype.abort=function(){this._cleanup(),this._close("user")},r.prototype._cleanup=function(){this.iframeObj&&(this.iframeObj.cleanup(),this.iframeObj=null),delete z[t.WPrefix][this.id]},r.prototype._close=function(e){this.emit("close",null,e),this.removeAllListeners()},r.htmlfileEnabled=!1;var o=["Active"].concat("Object").join("X");if(o in z)try{r.htmlfileEnabled=!!new z[o]("htmlfile")}catch(e){}return r.enabled=r.htmlfileEnabled||t.iframeEnabled,Rt=r}(),s=dt(),i=at();function n(e){if(!t.enabled)throw new Error("Transport created when disabled");i.call(this,e,"/htmlfile",t,s)}return e(n,i),n.enabled=function(e){return t.enabled&&e.sameOrigin},n.transportName="htmlfile",n.roundTrips=2,At=n}function zt(){if(Nt)return Mt;Nt=1;var e=_e(),t=at(),s=ct(),i=lt(),n=dt();function r(e){if(!n.enabled&&!i.enabled)throw new Error("Transport created when disabled");t.call(this,e,"/xhr",s,i)}return e(r,t),r.enabled=function(e){return!e.nullOrigin&&(!(!n.enabled||!e.sameOrigin)||i.enabled)},r.transportName="xhr-polling",r.roundTrips=2,Mt=r}function Kt(){if(Lt)return Ot;Lt=1;var e=_e(),t=at(),s=mt(),i=ct(),n=gt();function r(e){if(!n.enabled)throw new Error("Transport created when disabled");t.call(this,e,"/xhr",i,n)}return e(r,t),r.enabled=s.enabled,r.transportName="xdr-polling",r.roundTrips=2,Ot=r}function Xt(){if(xt)return Ut;xt=1;var e,t,s=ne(),i=pe();return Ut=function(n,r,o){e||((e=z.document.createElement("form")).style.display="none",e.style.position="absolute",e.method="POST",e.enctype="application/x-www-form-urlencoded",e.acceptCharset="UTF-8",(t=z.document.createElement("textarea")).name="d",e.appendChild(t),z.document.body.appendChild(e));var a="a"+s.string(8);e.target=a,e.action=i.addQuery(i.addPath(n,"/jsonp_send"),"i="+a);var c=function(e){try{return z.document.createElement('<iframe name="'+e+'">')}catch(s){var t=z.document.createElement("iframe");return t.name=e,t}}(a);c.id=a,c.style.display="none",e.appendChild(c);try{t.value=r}catch(e){}e.submit();var h=function(e){c.onerror&&(c.onreadystatechange=c.onerror=c.onload=null,setTimeout(function(){c.parentNode.removeChild(c),c=null},500),t.value="",o(e))};return c.onerror=function(){h()},c.onload=function(){h()},c.onreadystatechange=function(e){c.readyState,"complete"===c.readyState&&h()},function(){h(new Error("Aborted"))}},Ut}function Yt(){if($t)return jt;$t=1;var e=_e(),t=ot(),s=function(){if(Pt)return Dt;Pt=1;var e=Vt(),t=ne(),s=ut(),i=pe(),n=_e(),r=Se().EventEmitter;function o(s){var n=this;r.call(this),e.polluteGlobalNamespace(),this.id="a"+t.string(6);var a=i.addQuery(s,"c="+encodeURIComponent(e.WPrefix+"."+this.id));z[e.WPrefix][this.id]=this._callback.bind(this),this._createScript(a),this.timeoutId=setTimeout(function(){n._abort(new Error("JSONP script loaded abnormally (timeout)"))},o.timeout)}return n(o,r),o.prototype.abort=function(){if(z[e.WPrefix][this.id]){var t=new Error("JSONP user aborted read");t.code=1e3,this._abort(t)}},o.timeout=35e3,o.scriptErrorTimeout=1e3,o.prototype._callback=function(e){this._cleanup(),this.aborting||(e&&this.emit("message",e),this.emit("close",null,"network"),this.removeAllListeners())},o.prototype._abort=function(e){this._cleanup(),this.aborting=!0,this.emit("close",e.code,e.message),this.removeAllListeners()},o.prototype._cleanup=function(){if(clearTimeout(this.timeoutId),this.script2&&(this.script2.parentNode.removeChild(this.script2),this.script2=null),this.script){var t=this.script;t.parentNode.removeChild(t),t.onreadystatechange=t.onerror=t.onload=t.onclick=null,this.script=null}delete z[e.WPrefix][this.id]},o.prototype._scriptError=function(){var e=this;this.errorTimer||(this.errorTimer=setTimeout(function(){e.loadedOkay||e._abort(new Error("JSONP script loaded abnormally (onerror)"))},o.scriptErrorTimeout))},o.prototype._createScript=function(e){var i,n=this,r=this.script=z.document.createElement("script");if(r.id="a"+t.string(8),r.src=e,r.type="text/javascript",r.charset="UTF-8",r.onerror=this._scriptError.bind(this),r.onload=function(){n._abort(new Error("JSONP script loaded abnormally (onload)"))},r.onreadystatechange=function(){if(r.readyState,/loaded|closed/.test(r.readyState)){if(r&&r.htmlFor&&r.onclick){n.loadedOkay=!0;try{r.onclick()}catch(e){}}r&&n._abort(new Error("JSONP script loaded abnormally (onreadystatechange)"))}},void 0===r.async&&z.document.attachEvent)if(s.isOpera())(i=this.script2=z.document.createElement("script")).text="try{var a = document.getElementById('"+r.id+"'); if(a)a.onerror();}catch(x){};",r.async=i.async=!1;else{try{r.htmlFor=r.id,r.event="onclick"}catch(e){}r.async=!0}void 0!==r.async&&(r.async=!0);var o=z.document.getElementsByTagName("head")[0];o.insertBefore(r,o.firstChild),i&&o.insertBefore(i,o.firstChild)},Dt=o}(),i=Xt();function n(e){if(!n.enabled())throw new Error("Transport created when disabled");t.call(this,e,"/jsonp",i,s)}return e(n,t),n.enabled=function(){return!!z.document},n.transportName="jsonp-polling",n.roundTrips=1,n.needBody=!0,jt=n}function Qt(){return Wt?Ft:(Wt=1,Ft=[rt(),pt(),mt(),ft(),qt()(ft()),Jt(),qt()(Jt()),zt(),Kt(),qt()(zt()),Yt()])}var Zt,es,ts,ss,is,ns,rs,os,as,cs,hs,ls,ds,us,ps,gs,ms,_s,fs,ys,bs,vs,ws,Ss,Es,Is,Ts,Rs,Cs,As,ks,Ms,Ns,Os={};function Ls(){if(Zt)return Os;Zt=1;var e,t=Array.prototype,s=Object.prototype,i=Function.prototype,n=String.prototype,r=t.slice,o=s.toString,a=function(e){return"[object Function]"===s.toString.call(e)},c=function(e){return"[object String]"===o.call(e)},h=Object.defineProperty&&function(){try{return Object.defineProperty({},"x",{}),!0}catch(e){return!1}}();e=h?function(e,t,s,i){!i&&t in e||Object.defineProperty(e,t,{configurable:!0,enumerable:!1,writable:!0,value:s})}:function(e,t,s,i){!i&&t in e||(e[t]=s)};var l=function(t,i,n){for(var r in i)s.hasOwnProperty.call(i,r)&&e(t,r,i[r],n)},d=function(e){if(null==e)throw new TypeError("can't convert "+e+" to object");return Object(e)};function u(){}l(i,{bind:function(e){var t=this;if(!a(t))throw new TypeError("Function.prototype.bind called on incompatible "+t);for(var s=r.call(arguments,1),i=Math.max(0,t.length-s.length),n=[],o=0;o<i;o++)n.push("$"+o);var c=Function("binder","return function ("+n.join(",")+"){ return binder.apply(this, arguments); }")(function(){if(this instanceof c){var i=t.apply(this,s.concat(r.call(arguments)));return Object(i)===i?i:this}return t.apply(e,s.concat(r.call(arguments)))});return t.prototype&&(u.prototype=t.prototype,c.prototype=new u,u.prototype=null),c}}),l(Array,{isArray:function(e){return"[object Array]"===o.call(e)}});var p,g,m,_=Object("a"),f="a"!==_[0]||!(0 in _);l(t,{forEach:function(e){var t=d(this),s=f&&c(this)?this.split(""):t,i=arguments[1],n=-1,r=s.length>>>0;if(!a(e))throw new TypeError;for(;++n<r;)n in s&&e.call(i,s[n],n,t)}},(p=t.forEach,g=!0,m=!0,p&&(p.call("foo",function(e,t,s){"object"!=typeof s&&(g=!1)}),p.call([1],function(){m="string"==typeof this},"x")),!(p&&g&&m)));var y=Array.prototype.indexOf&&-1!==[0,1].indexOf(1,2);l(t,{indexOf:function(e){var t=f&&c(this)?this.split(""):d(this),s=t.length>>>0;if(!s)return-1;var i,n=0;for(arguments.length>1&&((i=+arguments[1])!=i?i=0:0!==i&&i!==1/0&&i!==-1/0&&(i=(i>0||-1)*Math.floor(Math.abs(i))),n=i),n=n>=0?n:Math.max(0,s+n);n<s;n++)if(n in t&&t[n]===e)return n;return-1}},y);var b,v=n.split;2!=="ab".split(/(?:ab)*/).length||4!==".".split(/(.?)(.?)/).length||"t"==="tesst".split(/(s)*/)[1]||4!=="test".split(/(?:)/,-1).length||"".split(/.?/).length||".".split(/()()/).length>1?(b=void 0===/()??/.exec("")[1],n.split=function(e,s){var i=this;if(void 0===e&&0===s)return[];if("[object RegExp]"!==o.call(e))return v.call(this,e,s);var n,r,a,c,h=[],l=(e.ignoreCase?"i":"")+(e.multiline?"m":"")+(e.extended?"x":"")+(e.sticky?"y":""),d=0;for(e=new RegExp(e.source,l+"g"),i+="",b||(n=new RegExp("^"+e.source+"$(?!\\s)",l)),s=void 0===s?-1>>>0:s>>>0;(r=e.exec(i))&&!((a=r.index+r[0].length)>d&&(h.push(i.slice(d,r.index)),!b&&r.length>1&&r[0].replace(n,function(){for(var e=1;e<arguments.length-2;e++)void 0===arguments[e]&&(r[e]=void 0)}),r.length>1&&r.index<i.length&&t.push.apply(h,r.slice(1)),c=r[0].length,d=a,h.length>=s));)e.lastIndex===r.index&&e.lastIndex++;return d===i.length?!c&&e.test("")||h.push(""):h.push(i.slice(d)),h.length>s?h.slice(0,s):h}):"0".split(void 0,0).length&&(n.split=function(e,t){return void 0===e&&0===t?[]:v.call(this,e,t)});var w=n.substr,S="".substr&&"b"!=="0b".substr(-1);return l(n,{substr:function(e,t){return w.call(this,e<0&&(e=this.length+e)<0?0:e,t)}},S),Os}function Ds(){if(ts)return es;ts=1;var e,t=/[\x00-\x1f\ud800-\udfff\ufffe\uffff\u0300-\u0333\u033d-\u0346\u034a-\u034c\u0350-\u0352\u0357-\u0358\u035c-\u0362\u0374\u037e\u0387\u0591-\u05af\u05c4\u0610-\u0617\u0653-\u0654\u0657-\u065b\u065d-\u065e\u06df-\u06e2\u06eb-\u06ec\u0730\u0732-\u0733\u0735-\u0736\u073a\u073d\u073f-\u0741\u0743\u0745\u0747\u07eb-\u07f1\u0951\u0958-\u095f\u09dc-\u09dd\u09df\u0a33\u0a36\u0a59-\u0a5b\u0a5e\u0b5c-\u0b5d\u0e38-\u0e39\u0f43\u0f4d\u0f52\u0f57\u0f5c\u0f69\u0f72-\u0f76\u0f78\u0f80-\u0f83\u0f93\u0f9d\u0fa2\u0fa7\u0fac\u0fb9\u1939-\u193a\u1a17\u1b6b\u1cda-\u1cdb\u1dc0-\u1dcf\u1dfc\u1dfe\u1f71\u1f73\u1f75\u1f77\u1f79\u1f7b\u1f7d\u1fbb\u1fbe\u1fc9\u1fcb\u1fd3\u1fdb\u1fe3\u1feb\u1fee-\u1fef\u1ff9\u1ffb\u1ffd\u2000-\u2001\u20d0-\u20d1\u20d4-\u20d7\u20e7-\u20e9\u2126\u212a-\u212b\u2329-\u232a\u2adc\u302b-\u302c\uaab2-\uaab3\uf900-\ufa0d\ufa10\ufa12\ufa15-\ufa1e\ufa20\ufa22\ufa25-\ufa26\ufa2a-\ufa2d\ufa30-\ufa6d\ufa70-\ufad9\ufb1d\ufb1f\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40-\ufb41\ufb43-\ufb44\ufb46-\ufb4e\ufff0-\uffff]/g;return es={quote:function(s){var i=JSON.stringify(s);return t.lastIndex=0,t.test(i)?(e||(e=function(e){var t,s={},i=[];for(t=0;t<65536;t++)i.push(String.fromCharCode(t));return e.lastIndex=0,i.join("").replace(e,function(e){return s[e]="\\u"+("0000"+e.charCodeAt(0).toString(16)).slice(-4),""}),e.lastIndex=0,s}(t)),i.replace(t,function(t){return e[t]})):i}}}function Ps(){if(is)return ss;is=1;return ss=function(e){return{filterToEnabled:function(t,s){var i={main:[],facade:[]};return t?"string"==typeof t&&(t=[t]):t=[],e.forEach(function(e){e&&("websocket"===e.transportName&&!1===s.websocket||(t.length&&-1===t.indexOf(e.transportName)?e.transportName:e.enabled(s)?(e.transportName,i.main.push(e),e.facadeTransport&&i.facade.push(e.facadeTransport)):e.transportName))}),i}}}}function Us(){if(rs)return ns;rs=1;var e={};return["log","debug","warn"].forEach(function(t){var s;try{s=z.console&&z.console[t]&&z.console[t].apply}catch(e){}e[t]=s?function(){return z.console[t].apply(z.console,arguments)}:"log"===t?function(){}:e.log}),ns=e}function xs(){if(as)return os;function e(e){this.type=e}return as=1,e.prototype.initEvent=function(e,t,s){return this.type=e,this.bubbles=t,this.cancelable=s,this.timeStamp=+new Date,this},e.prototype.stopPropagation=function(){},e.prototype.preventDefault=function(){},e.CAPTURING_PHASE=1,e.AT_TARGET=2,e.BUBBLING_PHASE=3,os=e}function js(){return hs?cs:(hs=1,cs=z.location||{origin:"http://localhost:80",protocol:"http:",host:"localhost",port:80,href:"http://localhost/",hash:""})}function $s(){if(fs)return _s;fs=1;var e=Se().EventEmitter,t=_e(),s=Bt();function i(t,i){e.call(this);var n=this,r=+new Date;this.xo=new i("GET",t),this.xo.once("finish",function(e,t){var i,o;if(200===e){if(o=+new Date-r,t)try{i=JSON.parse(t)}catch(e){}s.isObject(i)||(i={})}n.emit("finish",i,o),n.removeAllListeners()})}return t(i,e),i.prototype.close=function(){this.removeAllListeners(),this.xo.close()},_s=i}function Fs(){if(bs)return ys;bs=1;var e=_e(),t=Se().EventEmitter,s=dt(),i=$s();function n(e){var n=this;t.call(this),this.ir=new i(e,s),this.ir.once("finish",function(e,t){n.ir=null,n.emit("message",JSON.stringify([e,t]))})}return e(n,t),n.transportName="iframe-info-receiver",n.prototype.close=function(){this.ir&&(this.ir.close(),this.ir=null),this.removeAllListeners()},ys=n}function Ws(){if(Es)return Ss;Es=1;var e=Se().EventEmitter,t=_e(),s=pe(),i=gt(),n=lt(),r=dt(),o=function(){if(ms)return gs;ms=1;var e=Se().EventEmitter;function t(){var s=this;e.call(this),this.to=setTimeout(function(){s.emit("finish",200,"{}")},t.timeout)}return _e()(t,e),t.prototype.close=function(){clearTimeout(this.to)},t.timeout=2e3,gs=t}(),a=function(){if(ws)return vs;ws=1;var e=Se().EventEmitter,t=_e(),s=re(),i=Ht(),n=Fs();function r(t,r){var o=this;e.call(this);var a=function(){var e=o.ifr=new i(n.transportName,r,t);e.once("message",function(e){if(e){var t;try{t=JSON.parse(e)}catch(e){return o.emit("finish"),void o.close()}var s=t[0],i=t[1];o.emit("finish",s,i)}o.close()}),e.once("close",function(){o.emit("finish"),o.close()})};z.document.body?a():s.attachEvent("load",a)}return t(r,e),r.enabled=function(){return i.enabled()},r.prototype.close=function(){this.ifr&&this.ifr.close(),this.removeAllListeners(),this.ifr=null},vs=r}(),c=$s();function h(t,s){var i=this;e.call(this),setTimeout(function(){i.doXhr(t,s)},0)}return t(h,e),h._getReceiver=function(e,t,s){return s.sameOrigin?new c(t,r):n.enabled?new c(t,n):i.enabled&&s.sameScheme?new c(t,i):a.enabled()?new a(e,t):new c(t,o)},h.prototype.doXhr=function(e,t){var i=this,n=s.addPath(e,"/info");this.xo=h._getReceiver(e,n,t),this.timeoutRef=setTimeout(function(){i._cleanup(!1),i.emit("finish")},h.timeout),this.xo.once("finish",function(e,t){i._cleanup(!0),i.emit("finish",e,t)})},h.prototype._cleanup=function(e){clearTimeout(this.timeoutRef),this.timeoutRef=null,!e&&this.xo&&this.xo.close(),this.xo=null},h.prototype.close=function(){this.removeAllListeners(),this._cleanup(!1)},h.timeout=8e3,Ss=h}function Gs(){if(Cs)return Rs;Cs=1;var e=pe(),t=re(),s=function(){if(Ts)return Is;Ts=1;var e=Vt();function t(e){this._transport=e,e.on("message",this._transportMessage.bind(this)),e.on("close",this._transportClose.bind(this))}return t.prototype._transportClose=function(t,s){e.postMessage("c",JSON.stringify([t,s]))},t.prototype._transportMessage=function(t){e.postMessage("t",t)},t.prototype._send=function(e){this._transport.send(e)},t.prototype._close=function(){this._transport.close(),this._transport.removeAllListeners()},Is=t}(),i=Fs(),n=Vt(),r=js();return Rs=function(o,a){var c,h={};a.forEach(function(e){e.facadeTransport&&(h[e.facadeTransport.transportName]=e.facadeTransport)}),h[i.transportName]=i,o.bootstrap_iframe=function(){var i;n.currentWindowId=r.hash.slice(1);t.attachEvent("message",function(t){if(t.source===parent&&(void 0===c&&(c=t.origin),t.origin===c)){var a;try{a=JSON.parse(t.data)}catch(e){return void t.data}if(a.windowId===n.currentWindowId)switch(a.type){case"s":var l;try{l=JSON.parse(a.data)}catch(e){a.data;break}var d=l[0],u=l[1],p=l[2],g=l[3];if(d!==o.version)throw new Error('Incompatible SockJS! Main site uses: "'+d+'", the iframe: "'+o.version+'".');if(!e.isOriginEqual(p,r.href)||!e.isOriginEqual(g,r.href))throw new Error("Can't connect to different domain from within an iframe. ("+r.href+", "+p+", "+g+")");i=new s(new h[u](p,g));break;case"m":i._send(a.data);break;case"c":i&&i._close(),i=null}}}),n.postMessage("s")}},Rs}function Vs(){if(ks)return As;ks=1,Ls();var e,t=ue(),s=_e(),i=ne(),n=Ds(),r=pe(),o=re(),a=Ps(),c=Bt(),h=ut(),l=Us(),d=xs(),u=we(),p=js(),g=function(){if(ds)return ls;ds=1;var e=_e(),t=xs();function s(){t.call(this),this.initEvent("close",!1,!1),this.wasClean=!1,this.code=0,this.reason=""}return e(s,t),ls=s}(),m=function(){if(ps)return us;ps=1;var e=_e(),t=xs();function s(e){t.call(this),this.initEvent("message",!1,!1),this.data=e}return e(s,t),us=s}(),_=Ws(),f=function(){};function y(e,s,n){if(!(this instanceof y))return new y(e,s,n);if(arguments.length<1)throw new TypeError("Failed to construct 'SockJS: 1 argument required, but only 0 present");u.call(this),this.readyState=y.CONNECTING,this.extensions="",this.protocol="",(n=n||{}).protocols_whitelist&&l.warn("'protocols_whitelist' is DEPRECATED. Use 'transports' instead."),this._transportsWhitelist=n.transports,this._transportOptions=n.transportOptions||{},this._timeout=n.timeout||0;var o=n.sessionId||8;if("function"==typeof o)this._generateSessionId=o;else{if("number"!=typeof o)throw new TypeError("If sessionId is used in the options, it needs to be a number or a function.");this._generateSessionId=function(){return i.string(o)}}this._server=n.server||i.numberString(1e3);var a=new t(e);if(!a.host||!a.protocol)throw new SyntaxError("The URL '"+e+"' is invalid");if(a.hash)throw new SyntaxError("The URL must not contain a fragment");if("http:"!==a.protocol&&"https:"!==a.protocol)throw new SyntaxError("The URL's scheme must be either 'http:' or 'https:'. '"+a.protocol+"' is not allowed.");var c="https:"===a.protocol;if("https:"===p.protocol&&!c&&!r.isLoopbackAddr(a.hostname))throw new Error("SecurityError: An insecure SockJS connection may not be initiated from a page loaded over HTTPS");s?Array.isArray(s)||(s=[s]):s=[];var d=s.sort();d.forEach(function(e,t){if(!e)throw new SyntaxError("The protocols entry '"+e+"' is invalid.");if(t<d.length-1&&e===d[t+1])throw new SyntaxError("The protocols entry '"+e+"' is duplicated.")});var g=r.getOrigin(p.href);this._origin=g?g.toLowerCase():null,a.set("pathname",a.pathname.replace(/\/+$/,"")),this.url=a.href,this.url,this._urlInfo={nullOrigin:!h.hasDomain(),sameOrigin:r.isOriginEqual(this.url,p.href),sameScheme:r.isSchemeEqual(this.url,p.href)},this._ir=new _(this.url,this._urlInfo),this._ir.once("finish",this._receiveInfo.bind(this))}function b(e){return 1e3===e||e>=3e3&&e<=4999}return s(y,u),y.prototype.close=function(e,t){if(e&&!b(e))throw new Error("InvalidAccessError: Invalid code");if(t&&t.length>123)throw new SyntaxError("reason argument has an invalid length");if(this.readyState!==y.CLOSING&&this.readyState!==y.CLOSED){this._close(e||1e3,t||"Normal closure",!0)}},y.prototype.send=function(e){if("string"!=typeof e&&(e=""+e),this.readyState===y.CONNECTING)throw new Error("InvalidStateError: The connection has not been established yet");this.readyState===y.OPEN&&this._transport.send(n.quote(e))},y.version=yt(),y.CONNECTING=0,y.OPEN=1,y.CLOSING=2,y.CLOSED=3,y.prototype._receiveInfo=function(t,s){if(this._ir=null,t){this._rto=this.countRTO(s),this._transUrl=t.base_url?t.base_url:this.url,t=c.extend(t,this._urlInfo);var i=e.filterToEnabled(this._transportsWhitelist,t);this._transports=i.main,this._transports.length,this._connect()}else this._close(1002,"Cannot connect to server")},y.prototype._connect=function(){for(var e=this._transports.shift();e;e=this._transports.shift()){if(f(e.transportName),e.needBody&&(!z.document.body||void 0!==z.document.readyState&&"complete"!==z.document.readyState&&"interactive"!==z.document.readyState))return this._transports.unshift(e),void o.attachEvent("load",this._connect.bind(this));var t=Math.max(this._timeout,this._rto*e.roundTrips||5e3);this._transportTimeoutId=setTimeout(this._transportTimeout.bind(this),t);var s=r.addPath(this._transUrl,"/"+this._server+"/"+this._generateSessionId()),i=this._transportOptions[e.transportName],n=new e(s,this._transUrl,i);return n.on("message",this._transportMessage.bind(this)),n.once("close",this._transportClose.bind(this)),n.transportName=e.transportName,void(this._transport=n)}this._close(2e3,"All transports failed",!1)},y.prototype._transportTimeout=function(){this.readyState===y.CONNECTING&&(this._transport&&this._transport.close(),this._transportClose(2007,"Transport timed out"))},y.prototype._transportMessage=function(e){var t,s=this,i=e.slice(0,1),n=e.slice(1);switch(i){case"o":return void this._open();case"h":return this.dispatchEvent(new d("heartbeat")),void this.transport}if(n)try{t=JSON.parse(n)}catch(e){}if(void 0!==t)switch(i){case"a":Array.isArray(t)&&t.forEach(function(e){s.transport,s.dispatchEvent(new m(e))});break;case"m":this.transport,this.dispatchEvent(new m(t));break;case"c":Array.isArray(t)&&2===t.length&&this._close(t[0],t[1],!0)}},y.prototype._transportClose=function(e,t){this.transport,this._transport&&(this._transport.removeAllListeners(),this._transport=null,this.transport=null),b(e)||2e3===e||this.readyState!==y.CONNECTING?this._close(e,t):this._connect()},y.prototype._open=function(){this._transport&&this._transport.transportName,this.readyState,this.readyState===y.CONNECTING?(this._transportTimeoutId&&(clearTimeout(this._transportTimeoutId),this._transportTimeoutId=null),this.readyState=y.OPEN,this.transport=this._transport.transportName,this.dispatchEvent(new d("open")),this.transport):this._close(1006,"Server lost session")},y.prototype._close=function(e,t,s){this.transport,this.readyState;var i=!1;if(this._ir&&(i=!0,this._ir.close(),this._ir=null),this._transport&&(this._transport.close(),this._transport=null,this.transport=null),this.readyState===y.CLOSED)throw new Error("InvalidStateError: SockJS has already been closed");this.readyState=y.CLOSING,setTimeout(function(){this.readyState=y.CLOSED,i&&this.dispatchEvent(new d("error"));var n=new g("close");n.wasClean=s||!1,n.code=e||1e3,n.reason=t,this.dispatchEvent(n),this.onmessage=this.onclose=this.onerror=null}.bind(this),0)},y.prototype.countRTO=function(e){return e>100?4*e:300+e},As=function(t){return e=a(t),Gs()(y,t),y}}var Hs=function(){if(Ns)return Ms;Ns=1;var e=Qt();return Ms=Vs()(e),"_sockjs_onload"in z&&setTimeout(z._sockjs_onload,1),Ms}(),Bs=K(Hs);const qs="NOT_SUBSCRIBED",Js=()=>"undefined"!=typeof window&&window.StompJs&&window.StompJs.Client?window.StompJs.Client:J,zs=()=>"undefined"!=typeof window&&window.SockJS?window.SockJS:Bs;class Ks extends e{constructor(e){super(),this.serverUrl=e.serverUrl.replace(/\/$/,""),this.jwtToken=e.jwtToken,this.apiKey=e.apiKey,this.projectId=e.projectId,this.useSockJS=!1!==e.useSockJS,this.reconnectDelay=e.reconnectDelay||b.reconnectDelay,this.maxReconnectDelay=e.maxReconnectDelay||b.maxReconnectDelay,this.maxReconnectAttempts=e.maxReconnectAttempts||b.maxReconnectAttempts,this.reconnectRecoveryDelay=e.reconnectRecoveryDelay??b.reconnectRecoveryDelay,this.heartbeatIncoming=e.heartbeatIncoming||b.heartbeatIncoming,this.heartbeatOutgoing=e.heartbeatOutgoing||b.heartbeatOutgoing,this.resumeOnVisibility=!1!==e.resumeOnVisibility,this.logger=new S(e.logLevel||w.WARN,"ConnectionManager"),this.state=t.DISCONNECTED,this.stompClient=null,this.reconnectAttempts=0,this.subscriptions=new Map,this.pendingSubscriptions=[],this.userId=null,this._intentionalDisconnect=!1,this._tearingDown=!1,this._connectRequested=!1,this._forceReconnectPromise=null,this._lifecycleHandlers=null,this._recoveryTimer=null,this._terminalAuthError=!1,this._recoveryEligible=!1,this._subscriptionRequired=!1,this._installLifecycleListeners()}_installLifecycleListeners(){if("undefined"==typeof window||"function"!=typeof window.addEventListener)return;const e=()=>{"undefined"!=typeof document&&"visible"===document.visibilityState&&this._onResume("visibilitychange")},t=()=>this._onResume("pageshow"),s=()=>this._onResume("online");"undefined"!=typeof document&&"function"==typeof document.addEventListener&&document.addEventListener("visibilitychange",e),window.addEventListener("pageshow",t),window.addEventListener("online",s),this._lifecycleHandlers={onVisibilityChange:e,onPageShow:t,onOnline:s}}_removeLifecycleListeners(){if(!this._lifecycleHandlers)return;const{onVisibilityChange:e,onPageShow:t,onOnline:s}=this._lifecycleHandlers;"undefined"!=typeof document&&"function"==typeof document.removeEventListener&&document.removeEventListener("visibilitychange",e),"undefined"!=typeof window&&"function"==typeof window.removeEventListener&&(window.removeEventListener("pageshow",t),window.removeEventListener("online",s)),this._lifecycleHandlers=null}_onResume(e){if(this.resumeOnVisibility&&!this._intentionalDisconnect&&!this._terminalAuthError&&!this._subscriptionRequired)if(this._connectRequested){if(this.state!==t.CONNECTING&&!this._forceReconnectPromise){if(this.state===t.CONNECTED)return this._isSocketAlive()?(this.logger.debug(`Resume (${e}): connection alive`),void this.emit("resumed",{reason:e})):(this.logger.warn(`Resume (${e}): zombie socket detected, forcing reconnect`),void this.forceReconnect(`zombie-socket:${e}`));this.logger.info(`Resume (${e}): reviving connection from state=${this.state}`),this.forceReconnect(e)}}else this.logger.debug(`Resume (${e}) ignored — connect() has not been called yet`)}_isSocketAlive(){const e=this.stompClient&&this.stompClient.webSocket;return!!e&&e.readyState===F.OPEN}async forceReconnect(e){if(!this._intentionalDisconnect&&!this._terminalAuthError&&this.state!==t.CONNECTING){this._forceReconnectPromise||(this._forceReconnectPromise=this._doForceReconnect(e).finally(()=>{this._forceReconnectPromise=null})),await this._forceReconnectPromise;try{await this._connectPromise}catch{}}}async _doForceReconnect(e){if(this._cancelReconnectRecovery(),this.logger.info(`Force reconnect: ${e}`),this.stompClient){this._tearingDown=!0;try{await this.stompClient.deactivate()}catch(e){this.logger.warn("Error deactivating stomp client on force reconnect:",e)}finally{this._tearingDown=!1}this.stompClient=null}if(!(this._intentionalDisconnect||this._terminalAuthError||this._subscriptionRequired)){this._setState(t.DISCONNECTED),this.reconnectAttempts=0;try{this.connect().catch(t=>this.logger.warn(`Force reconnect failed (${e}):`,t))}catch(t){this.logger.warn(`Force reconnect failed (${e}):`,t)}}}_setState(e){const t=this.state;this.state=e,this.emit("stateChange",{state:e,prevState:t}),this.logger.info(`State changed: ${t} -> ${e}`)}_getWebSocketUrl(){const e=this.useSockJS?_.SOCKJS_ENDPOINT:_.NATIVE_ENDPOINT;return`${this.serverUrl}${e}`}_createStompClient(){const e=this._getWebSocketUrl();let t=null;const i=()=>!this.stompClient||this.stompClient===t,n={beforeConnect:async e=>{if(!this.getAccessToken)return void(this._connectionToken=this.jwtToken);let t=0;for(;!this._intentionalDisconnect&&(!e||e.active);)try{const t=await this.getAccessToken({forceRefresh:!0===this._authRejected});if(this._intentionalDisconnect||e&&!e.active)return;return!this._authRejected||t&&t.replace(/^Bearer\s+/i,"")!==this._rejectedToken?(this.updateToken(t),this._connectionToken=t,void(this._authRejected=!1)):void this._stopForAuthError(new Error("Authentication rejected without a new access token"),e)}catch(i){if(this.emit("error",{type:s.CONNECTION_FAILED,message:i.message,error:i}),R(i))return void this._stopForAuthError(i,e);const n=Math.min(3e4,1e3*2**Math.min(t++,5))*(.8+.4*Math.random());await new Promise(e=>{this._cancelAuthRetry=()=>{clearTimeout(this._authRetryTimer),e()},this._authRetryTimer=setTimeout(e,n),this._authRetryTimer.unref?.()}),this._cancelAuthRetry=null}},connectHeaders:{Authorization:this.jwtToken.startsWith("Bearer ")?this.jwtToken:`Bearer ${this.jwtToken}`,"X-API-KEY":this.apiKey,"X-PROJECT-ID":this.projectId},heartbeatIncoming:this.heartbeatIncoming,heartbeatOutgoing:this.heartbeatOutgoing,reconnectDelay:this.reconnectDelay*(.8+.4*Math.random()),reconnectTimeMode:G.EXPONENTIAL,maxReconnectDelay:this.maxReconnectDelay,debug:e=>{this.logger.level<=w.DEBUG&&this.logger.debug("STOMP:",e)},onConnect:e=>{i()&&this._onConnect(e)},onDisconnect:e=>{i()&&this._onDisconnect(e)},onStompError:e=>{i()&&this._onStompError(e)},onWebSocketClose:e=>{i()&&this._onWebSocketClose(e)},onWebSocketError:e=>{i()&&this._onWebSocketError(e)}};if(this.useSockJS){const t=zs();n.webSocketFactory=()=>new t(e)}else{const e=this.serverUrl.startsWith("https")?"wss":"ws",t=this.serverUrl.replace(/^https?:\/\//,"");n.brokerURL=`${e}://${t}${_.NATIVE_ENDPOINT}`}const r=Js();return t=new r(n),t}async connect(){if(this.state===t.CONNECTED)return void this.logger.warn("Already connected");this._connectPromise||(this._connectPromise=new Promise((e,t)=>{const s=()=>{this._connectPromise=null,this._connectResolve=this._connectReject=null};this._connectResolve=()=>{s(),e()},this._connectReject=e=>{s(),t(e)}}));const e=this._connectPromise;if(this.stompClient&&(this.state===t.CONNECTING||this.state===t.RECONNECTING))return e;this._cancelReconnectRecovery(),this._terminalAuthError=!1,this._subscriptionRequired=!1,this._setState(t.CONNECTING),this.reconnectAttempts=0,this._intentionalDisconnect=!1,this._connectRequested=!0;try{this.stompClient=this._createStompClient(),this.stompClient.activate()}catch(e){this._setState(t.ERROR),this._drainPendingSubscriptions("Connection activation failed"),this._connectReject?.(e)}return e}_onConnect(e){this._authenticatedToken=this.jwtToken;const s=this.reconnectAttempts,i=s>0||!0===this._hasConnectedBefore;this._setState(t.CONNECTED),this.reconnectAttempts=0,this._hasConnectedBefore=!0,this._recoveryEligible=!0,this._authRejected=!1,this._rejectedToken=null,this._notifiedRejectedToken=null,this.logger.info("Connected to server",e),this._restoreSubscriptions(),this._processPendingSubscriptions(),this.emit("connected",{frame:e}),i&&this.emit("reconnected",{attempts:s}),this._connectResolve&&(this._connectResolve(),this._connectResolve=null,this._connectReject=null)}_onDisconnect(e){this.logger.info("Disconnected from server",e),this._setState(t.DISCONNECTED),this.emit("disconnected",{frame:e})}_onStompError(e){let i=null,n=null;try{const t=JSON.parse(e.body||e.headers?.message||"{}");i=t.code??null,n="string"==typeof t.message?t.message:null,this._authRejected=["ACCESS_UNAUTHORIZED","SESSION_REVOKED","TOKEN_INVALID"].includes(i)}catch{}if(i===qs)return void this._stopForSubscription(n);this.logger.error("STOMP error:",e),this._setState(t.ERROR);const r={type:s.CONNECTION_FAILED,message:e.headers?.message||"STOMP error",frame:e};this._authRejected&&this._recordAuthRejection();const o="SUBSCRIPTION_CHECK_UNAVAILABLE"!==i&&!this._canRecoverConnection();o&&this._drainPendingSubscriptions(`STOMP error: ${r.message}`),this.emit("error",r),o&&this._connectReject&&(this._connectReject(new Error(r.message)),this._connectResolve=null,this._connectReject=null)}_onWebSocketClose(e){4001===e?.code&&this._recordAuthRejection(),this.logger.warn("WebSocket closed:",e),this._tearingDown||this._intentionalDisconnect||this._terminalAuthError||this._subscriptionRequired?this.logger.debug("WebSocket closed during intentional teardown — not counting as reconnect"):this.state!==t.DISCONNECTED&&this._handleReconnect()}_onWebSocketError(e){this.logger.error("WebSocket error:",e),this._connectReject&&!this._canRecoverConnection()&&(this._drainPendingSubscriptions("WebSocket connection failed"),this._connectReject(new Error("WebSocket connection failed")),this._connectResolve=null,this._connectReject=null)}_handleReconnect(){if(this.reconnectAttempts++,this.reconnectAttempts>this.maxReconnectAttempts){const e=this.stompClient;let i;this.stompClient=null;try{i=e?.deactivate()}catch(e){this.logger.warn("Error deactivating stomp client on max reconnect:",e)}return Promise.resolve(i).catch(e=>{this.logger.warn("Error deactivating stomp client on max reconnect:",e)}).then(()=>this._scheduleReconnectRecovery()),this._canRecoverConnection()||(this._connectReject?.(new Error("Max reconnection attempts exceeded")),this._connectResolve=this._connectReject=null,this._drainPendingSubscriptions("Max reconnection attempts exceeded")),this._setState(t.ERROR),void this.emit("error",{type:s.CONNECTION_LOST,message:"Max reconnection attempts exceeded"})}this._setState(t.RECONNECTING),this.emit("reconnecting",{attempt:this.reconnectAttempts}),this.logger.info(`Reconnecting... attempt ${this.reconnectAttempts}`)}_recordAuthRejection(){this._authRejected=!0,this._rejectedToken=(this._connectionToken||this.jwtToken).replace(/^Bearer\s+/i,""),this.getAccessToken||this._stopForAuthError(new Error("STOMP error: authentication rejected"))}_stopForAuthError(e,i=this.stompClient){const n=!this._terminalAuthError&&this._usesStaticToken()&&this._rejectedToken!==this._notifiedRejectedToken;this._terminalAuthError=!0,this._recoveryEligible=!1,this._cancelReconnectRecovery(),this._setState(t.ERROR),this._connectReject?.(e),this._drainPendingSubscriptions(e.message),Promise.resolve(i?.deactivate()).catch(e=>this.logger.warn("Auth teardown failed:",e)),n&&(this._notifiedRejectedToken=this._rejectedToken,Promise.resolve().then(()=>this.emit("error",{type:s.CONNECTION_LOST,message:e.message,error:e})))}_usesStaticToken(){return!this.getAccessToken||!1===this.canRefreshToken?.()}_canRecoverConnection(){return this._recoveryEligible&&!this._intentionalDisconnect&&!this._terminalAuthError&&!this._subscriptionRequired&&this.reconnectRecoveryDelay>0}isSubscriptionRequired(){return this._subscriptionRequired}_stopForSubscription(e){const i=!this._subscriptionRequired;this._subscriptionRequired=!0,this._cancelReconnectRecovery(),this._setState(t.ERROR);const n=e||"Company subscription required",r=Object.assign(new Error("Company subscription required"),{code:qs,type:s.SUBSCRIPTION_REQUIRED});this._connectReject?.(r),this._connectResolve=this._connectReject=null,this._drainPendingSubscriptions("Company subscription required");const o=this.stompClient;Promise.resolve(o?.deactivate()).catch(e=>this.logger.warn("Subscription teardown failed:",e)),this.logger.warn("Company subscription required — connection stopped until connect() is called again"),i&&Promise.resolve().then(()=>this.emit("subscriptionRequired",{code:qs,message:n}))}_scheduleReconnectRecovery(){if(!this._canRecoverConnection()||this.state!==t.ERROR||this.stompClient)return;this._cancelReconnectRecovery();const e=this.reconnectRecoveryDelay*(.8+.4*Math.random());this._recoveryTimer=setTimeout(()=>{this._recoveryTimer=null,this._intentionalDisconnect||this._terminalAuthError||this.state!==t.ERROR||this.forceReconnect("retry-cooldown")},e),this._recoveryTimer.unref?.()}_cancelReconnectRecovery(){clearTimeout(this._recoveryTimer),this._recoveryTimer=null}_restoreSubscriptions(){if(0===this.subscriptions.size)return;this.logger.info(`Restoring ${this.subscriptions.size} subscriptions after reconnect`);const e=new Map(this.subscriptions);this.subscriptions.clear(),e.forEach(({callback:e,headers:t},s)=>{this._subscribeInternal(s,e,t),this.logger.debug(`Restored subscription: ${s}`)})}_processPendingSubscriptions(){for(;this.pendingSubscriptions.length>0;){const{destination:e,callback:t,headers:s,resolve:i}=this.pendingSubscriptions.shift(),n=this._subscribeInternal(e,t,s);i&&i(n)}}_subscribeInternal(e,t,s={}){const i=this.stompClient.subscribe(e,e=>{try{const s=JSON.parse(e.body);t(s,e)}catch(s){this.logger.error("Failed to parse message:",s),t(e.body,e)}},s);return this.subscriptions.set(e,{subscription:i,callback:t,headers:s}),this.logger.debug(`Subscribed to: ${e}`),i}subscribe(e,s,i={}){return this.subscriptions.has(e)&&this.unsubscribe(e),this.state!==t.CONNECTED?new Promise((t,n)=>{this.pendingSubscriptions.push({destination:e,callback:s,headers:i,resolve:t,reject:n}),this.logger.debug(`Queued subscription for: ${e}`)}):Promise.resolve(this._subscribeInternal(e,s,i))}unsubscribe(e){const t=this.subscriptions.get(e);t&&(t.subscription.unsubscribe(),this.subscriptions.delete(e),this.logger.debug(`Unsubscribed from: ${e}`))}unsubscribeAll(){this.subscriptions.forEach(({subscription:e},t)=>{e.unsubscribe(),this.logger.debug(`Unsubscribed from: ${t}`)}),this.subscriptions.clear()}send(e,s,i={}){return this.state!==t.CONNECTED?(this.logger.warn("Cannot send message: not connected"),!1):(this.stompClient.publish({destination:e,body:JSON.stringify(s),headers:i}),this.logger.debug(`Sent to ${e}:`,s),!0)}updateToken(e){this.jwtToken=e,this.stompClient&&(this.stompClient.connectHeaders={...this.stompClient.connectHeaders,Authorization:e.startsWith("Bearer ")?e:`Bearer ${e}`}),this._terminalAuthError&&!this._intentionalDisconnect&&this._usesStaticToken()&&e.replace(/^Bearer\s+/i,"")!==this._rejectedToken&&this.connect().catch(e=>this.logger.warn("Reconnect with updated token failed:",e))}async disconnect(){this._intentionalDisconnect=!0,this._recoveryEligible=!1,this._subscriptionRequired=!1,this._authRejected=!1,this._rejectedToken=null,this._cancelReconnectRecovery(),this._connectRequested=!1,this._cancelAuthRetry?.(),this._connectReject?.(Object.assign(new Error("Connection cancelled"),{code:"AUTH_OPERATION_CANCELLED"})),this._connectResolve=this._connectReject=null,this._drainPendingSubscriptions("Disconnected before subscription completed"),this.stompClient&&(this.unsubscribeAll(),await this.stompClient.deactivate(),this.stompClient=null),this._setState(t.DISCONNECTED),this.logger.info("Disconnected")}_drainPendingSubscriptions(e){if(0===this.pendingSubscriptions.length)return;const t=this.pendingSubscriptions;this.pendingSubscriptions=[],t.forEach(({destination:t,reject:s})=>{s&&s(new Error(`${e}: ${t}`))}),this.logger.debug(`Drained ${t.length} pending subscriptions: ${e}`)}isConnected(){return this.state===t.CONNECTED}getState(){return this.state}setLogLevel(e){this.logger.setLevel(e)}async destroy(){this._removeLifecycleListeners(),await this.disconnect(),this.removeAllListeners(),this.logger.info("ConnectionManager destroyed")}}const Xs=new Set(["text/plain","text/markdown","text/x-markdown"]);class Ys extends e{constructor(e){super(),this.connectionManager=e.connectionManager,this.apiClient=e.apiClient,this.userId=e.userId,this.logger=new S(e.logLevel||w.WARN,"ChatClient"),this.subscribedRooms=new Map,this.roomListSubscribed=!1,this.mailSubscribed=!1,this._activeRoomId=null,this._typingTimers=new Map,this._assistantTypingTimers=new Map,this._assistantTypingTimeoutMs=3e4,this._assistantTypingUserId="__assistant__",this._assistantTypingUserName="AI",this._assistantProgress=new Map,this._assistantStreamTombstones=new Map,this._assistantTombstoneTtlMs=12e4,this._assistantTombstoneWarnThreshold=32,this._assistantTombstoneWarned=new Set,this._assistantSlotSeq=0,this._assistantRoomGeneration=new Map,this._assistantSnapshotPending=new Map,this._assistantSnapshotInFlight=new Map,this.assistantStreamReplay=!1!==e.assistantStreamReplay,this._assistantPhaseLabels={THINKING:"생각 중…",SEARCHING:"검색 중…",PLANNING:"기획 중…",DOCUMENT_ANALYSIS:"문서 분석 중…",VIDEO_ANALYSIS:"영상 분석 중…",WEB_READING:"페이지 읽는 중…",WRITING:"작성 중…"},this._assistantProgressFallbackTtlMs=35e3,this._seenChatMessageIdsByRoom=new Map,this._seenRoomListMessageIdsByRoom=new Map,this.syncOnReconnect=!1!==e.syncOnReconnect,this.rewindMillis=void 0!==e.rewindMillis?e.rewindMillis:b.rewindMillis,this.maxSyncPages=e.maxSyncPages||b.maxSyncPages,this.syncPageSize=e.syncPageSize||b.syncPageSize,this._anchor=new Map,this._anchorGen=new Map,this._syncInFlight=new Set,this._replaying=!1,this._maxSeenPerRoom=Math.max(200,this.maxSyncPages*this.syncPageSize+100),this._reconnectSyncGeneration=0,this._delayedReconnectSyncTimer=null,this._installSyncTriggers()}_installSyncTriggers(){this.connectionManager&&"function"==typeof this.connectionManager.on&&(this._onReconnectedForSync=({attempts:e}={})=>{this._cancelDelayedReconnectSync();const t=this._reconnectSyncGeneration;this.syncAfterReconnect(`reconnected:${e??0}`).catch(e=>this.logger.warn("Gap sync after reconnect failed:",e)).then(e=>{this.syncOnReconnect&&e&&t===this._reconnectSyncGeneration&&(this._delayedReconnectSyncTimer=setTimeout(()=>{this._delayedReconnectSyncTimer=null,this._supplementAfterReconnect(e,t).catch(e=>this.logger.warn("Delayed gap sync failed:",e))},1e3),this._delayedReconnectSyncTimer.unref?.())}),this.resumeAssistantStreams(`reconnected:${e??0}`).catch(e=>this.logger.warn("Assistant stream replay after reconnect failed:",e))},this._onResumedForSync=({reason:e}={})=>{this.syncAfterReconnect(`resumed:${e??"unknown"}`).catch(e=>this.logger.warn("Gap sync after resume failed:",e)),this.resumeAssistantStreams(`resumed:${e??"unknown"}`).catch(e=>this.logger.warn("Assistant stream replay after resume failed:",e))},this._onStateChangeForSync=({state:e})=>{e!==t.CONNECTED&&this._cancelDelayedReconnectSync()},this.connectionManager.on("stateChange",this._onStateChangeForSync),this.connectionManager.on("reconnected",this._onReconnectedForSync),this.connectionManager.on("resumed",this._onResumedForSync))}_shouldDedupMessage(e,t,s){if(!t||!s)return!1;let i=e.get(t);if(i||(i=new Map,e.set(t,i)),i.has(s))return!0;if(i.set(s,!0),i.size>this._maxSeenPerRoom){const e=i.keys().next().value;i.delete(e)}return!1}async getRooms(e={}){const{size:t=50,lastId:s,lastSortValue:i,type:n}=e;return this.apiClient.get("/api/v1/rooms/my",{size:t,lastId:s,lastSortValue:i,type:n})}async getRoom(e){const t=this._anchorGen.get(e)||0,s=await this.apiClient.get(`/api/v1/rooms/${e}`),i=this._unwrapSuccessResponse(s);return i&&Array.isArray(i.messages)&&this._seedAnchorFromLatest(e,i.messages,t),s}async enterRoom(e){const t=this.subscribedRooms.has(e);if(t){if(this.assistantStreamReplay){const t=this._armAssistantSnapshot(e);this._loadAssistantSnapshot(e,t).catch(t=>this.logger.warn(`Assistant snapshot on re-enter failed: room=${e}`,t))}}else await this.subscribeRoom(e);this.setActiveRoom(e);try{return await this.getRoom(e)}catch(s){throw this.getActiveRoom()===e&&this.clearActiveRoom(),t||this.unsubscribeRoom(e),s}}async getRoomInfo(e){return this.apiClient.get(`/api/v1/rooms/${e}/info`)}async setMyRoomLanguage(e,t){return this.apiClient.put(`/api/v1/rooms/${e}/my-language`,{language:t})}async createOneToOneRoom(e){return this.apiClient.post(`/api/v1/rooms/direct/${e}`)}async createGroupRoom(e){const t=e.roomType||h.GROUP;if(t===h.PRIVATE_GROUP){if(!e.password||e.password.length<4)throw new Error("PRIVATE_GROUP requires a password of at least 4 characters")}else if(t===h.GROUP){if(e.password)throw new Error("Public GROUP rooms cannot have a password")}else if(t===h.TEAM&&e.password)throw new Error("TEAM rooms cannot have a password (invite-only)");return this.apiClient.post("/api/v1/rooms/group",{roomName:e.roomName,description:e.description,invitedUserIds:e.invitedUserIds,roomType:t,password:e.password,messageRetentionHours:e.messageRetentionHours,invitedAssistantPersonaIds:e.invitedAssistantPersonaIds,assistantMode:e.assistantMode,roomAiType:e.roomAiType,engagementIntensity:e.engagementIntensity})}async getAssistants(){const e=await this.apiClient.get("/api/v1/assistants");return this._unwrapSuccessResponse(e)}async getRoomAiMeta(){const e=await this.apiClient.get("/api/v1/rooms/ai-meta");return this._unwrapSuccessResponse(e)}async rateAssistantMessage(e,t,s,i){if(!Number.isInteger(s)||s<1||s>5)throw new Error("rating must be an integer between 1 and 5");await this.apiClient.post(`/api/v1/chat-messages/${e}/messages/${t}/rating`,{rating:s,comment:i})}async summarizeWithAssistant(e,t={}){const{personaId:s,format:i,messageCount:n}=t;if(!s)throw new Error("summarizeWithAssistant requires options.personaId");const r=await this.apiClient.post(`/api/v1/rooms/${e}/assistant/tools/summarize`,{personaId:s,format:i,messageCount:n});return this._unwrapSuccessResponse(r)}async uploadVideoAsset(e,t={}){if(!e)throw new Error("file is required");return this._unwrapSuccessResponse(await this.apiClient.upload("/api/v1/video-assets",e,{onProgress:t.onProgress,signal:t.signal}))}async analyzeVideo(e,t={}){if("string"!=typeof t.idempotencyKey||!t.idempotencyKey.trim())throw new Error("idempotencyKey is required for video analysis");return this._unwrapSuccessResponse(await this.apiClient.post("/api/v1/video-analyses",e,void 0,{"Idempotency-Key":t.idempotencyKey}))}async analyzeVideoWithAssistant(e,t,s={}){if(!e||!t?.personaId||!t?.triggerMessageId)throw new Error("roomId, personaId and triggerMessageId are required");if("string"!=typeof s.idempotencyKey||!s.idempotencyKey.trim())throw new Error("idempotencyKey is required for video analysis");return this._unwrapSuccessResponse(await this.apiClient.post(`/api/v1/rooms/${encodeURIComponent(e)}/assistant/tools/analyze-video`,t,void 0,{"Idempotency-Key":s.idempotencyKey}))}async getVideoAnalysis(e){if(!e)throw new Error("jobId is required");return this._unwrapSuccessResponse(await this.apiClient.get(`/api/v1/video-analyses/${encodeURIComponent(e)}`))}async cancelVideoAnalysis(e){if(!e)throw new Error("jobId is required");return this._unwrapSuccessResponse(await this.apiClient.post(`/api/v1/video-analyses/${encodeURIComponent(e)}/cancel`))}async getVideoAnalysisCapabilities(){return this._unwrapSuccessResponse(await this.apiClient.get("/api/v1/video-analyses/capabilities"))}async translateWithAssistant(e,t={}){const{targetLang:s,sourceMessageId:i}=t;if(!i)throw new Error("translateWithAssistant requires options.sourceMessageId");if(!s)throw new Error("translateWithAssistant requires options.targetLang");const n=await this.apiClient.post(`/api/v1/rooms/${e}/assistant/tools/translate`,{targetLang:s,sourceMessageId:i});return this._unwrapSuccessResponse(n)}async refreshSummary(e,t={}){const{format:s,lang:i}=t,n=await this.apiClient.post(`/api/v1/rooms/${e}/summary/refresh`,{format:s,lang:i});return this._unwrapSuccessResponse(n)}async getSummary(e,t={}){const{format:s,lang:i,afterSeq:n,size:r}=t,o=await this.apiClient.get(`/api/v1/rooms/${e}/summary`,{format:s,lang:i,afterSeq:n,size:r});return this._unwrapSuccessResponse(o)}async getRoomPmPrompt(e){const t=await this.apiClient.get(`/api/v1/rooms/${e}/pm-prompt`);return this._unwrapSuccessResponse(t)}async upsertRoomPmPrompt(e,t){if("string"!=typeof t||!t.trim())throw new Error("upsertRoomPmPrompt requires non-blank content");if(t.length>2e4)throw new Error("upsertRoomPmPrompt content exceeds 20000 characters");const s=await this.apiClient.put(`/api/v1/rooms/${e}/pm-prompt`,{content:t});return this._unwrapSuccessResponse(s)}async activateRoomPmPrompt(e){const t=await this.apiClient.patch(`/api/v1/rooms/${e}/pm-prompt/activate`);return this._unwrapSuccessResponse(t)}async deactivateRoomPmPrompt(e){const t=await this.apiClient.patch(`/api/v1/rooms/${e}/pm-prompt/deactivate`);return this._unwrapSuccessResponse(t)}async getRoomPmPromptVersions(e){const t=await this.apiClient.get(`/api/v1/rooms/${e}/pm-prompt/versions`);return this._unwrapSuccessResponse(t)}async activateRoomPmPromptVersion(e,t){if(!Number.isInteger(t)||t<1)throw new Error("activateRoomPmPromptVersion requires a positive integer version");const s=await this.apiClient.post(`/api/v1/rooms/${e}/pm-prompt/versions/${t}/activate`);return this._unwrapSuccessResponse(s)}async previewRoomPmPrompt(e){const t=await this.apiClient.get(`/api/v1/rooms/${e}/pm-prompt/preview`);return this._unwrapSuccessResponse(t)}async joinGroupRoom(e,t){const s=t?{password:t}:void 0;return this.apiClient.post(`/api/v1/rooms/group/${e}/join`,s)}async leaveRoom(e,t={}){const s=t.newOwnerId?{newOwnerId:t.newOwnerId}:void 0,i=await this.apiClient.post(`/api/v1/rooms/${e}/leave`,s);return this.unsubscribeRoom(e),i}async transferOwnership(e,t){const s=await this.apiClient.put(`/api/v1/rooms/${e}/owner`,{newOwnerId:t});return s&&"object"==typeof s&&"data"in s?s.data:s}async deleteRoom(e){const t=await this.apiClient.delete(`/api/v1/rooms/${e}`);return this.unsubscribeRoom(e),t}async updateGroupRoom(e,t){return this.apiClient.put(`/api/v1/rooms/group/${e}`,t)}async inviteToGroupRoom(e,t){const s=Array.isArray(t)?{userIds:t}:{userIds:t?.userIds,assistantPersonaIds:t?.assistantPersonaIds};return this.apiClient.post(`/api/v1/rooms/group/${e}/invite`,s)}async kickMember(e,t){return this.apiClient.delete(`/api/v1/rooms/${e}/members/${t}`)}async banMember(e,t){return this.apiClient.post(`/api/v1/rooms/${e}/banned-members`,{userId:t})}async unbanMember(e,t){return this.apiClient.delete(`/api/v1/rooms/${e}/banned-members/${t}`)}async getBannedMembers(e){const t=await this.apiClient.get(`/api/v1/rooms/${e}/banned-members`);return t&&"object"==typeof t&&"data"in t?t.data:t}async pinMessage(e,t){return this.apiClient.post(`/api/v1/rooms/group/${e}/pin/${t}`)}async unpinMessage(e){return this.apiClient.post(`/api/v1/rooms/group/${e}/unpin`)}async createVote(e,t,s={}){if(!e)throw new Error("roomId is required");const{idempotencyKey:i}=s;if(!i)throw new Error("createVote: options.idempotencyKey is required — generate it once per vote and reuse the same value on retry (재시도에 같은 키를 넘겨야 투표가 중복 생성되지 않는다).");const n=await this.apiClient.post(`/api/v1/rooms/${e}/votes`,t,void 0,{"X-Idempotency-Key":i});return this._unwrapSuccessResponse(n)}async getVotes(e,t={}){const{cursor:s,limit:i}=t,n=await this.apiClient.get(`/api/v1/rooms/${e}/votes`,{cursor:s,limit:i});return this._unwrapSuccessResponse(n)}async getVote(e,t){const s=await this.apiClient.get(`/api/v1/rooms/${e}/votes/${t}`);return this._unwrapSuccessResponse(s)}async updateVote(e,t,s){const i=await this.apiClient.patch(`/api/v1/rooms/${e}/votes/${t}`,s);return this._unwrapSuccessResponse(i)}async deleteVote(e,t){await this.apiClient.delete(`/api/v1/rooms/${e}/votes/${t}`)}async closeVote(e,t){await this.apiClient.patch(`/api/v1/rooms/${e}/votes/${t}/close`)}async submitVote(e,t,s){const i=await this.apiClient.put(`/api/v1/rooms/${e}/votes/${t}/responses`,{optionIds:s});return this._unwrapSuccessResponse(i)}async uploadVoteImage(e,t,s={}){if(!e)throw new Error("roomId is required");if(!t)throw new Error("file is required");const i=await this.apiClient.upload(`/api/v1/rooms/${e}/votes/images`,t,{onProgress:s.onProgress,signal:s.signal});return this._unwrapSuccessResponse(i)}async toggleReaction(e,t,s){return this.apiClient.post(`/api/v1/chat-messages/${e}/messages/${t}/reaction`,{emoji:s})}async getAvailableGroupRooms(e={}){const{size:t=50,lastId:s,lastSortValue:i}=e;return this.apiClient.get("/api/v1/rooms/groups/available",{size:t,lastId:s,lastSortValue:i})}async getAllGroupRooms(e={}){const{size:t=50,lastId:s,lastSortValue:i}=e;return this.apiClient.get("/api/v1/rooms/groups/all",{size:t,lastId:s,lastSortValue:i})}async getFiles(e={}){const{roomId:t,type:s,size:i=50,lastId:n,lastSortValue:r}=e;return this.apiClient.get("/api/v1/files",{roomId:t,type:s,size:i,lastId:n,lastSortValue:r})}async getMessages(e,t={}){const{size:s=50,lastId:i,lastSortValue:n}=t,r=null==i&&null==n,o=this._anchorGen.get(e)||0,a=await this.apiClient.get(`/api/v1/chat-messages/${e}/list`,{size:s,lastId:i,lastSortValue:n}),c=this._unwrapSuccessResponse(a);return c&&Array.isArray(c.content)&&(c.content.forEach(e=>this._normalizeMessageTimestamps(e)),r&&this._seedAnchorFromLatest(e,c.content,o)),a}_seedAnchorFromLatest(e,t,s){if(!Array.isArray(t)||0===t.length)return!1;const i=t[0];return!(!i||!i.id)&&this._commitAnchorFromSync(e,i.id,s)}async syncMessages(e,t={}){const{afterId:s,rewindMillis:i,size:n=this.syncPageSize}=t,r=await this.apiClient.get(`/api/v1/chat-messages/${e}/sync`,{afterId:s,rewindMillis:i,size:n}),o=this._unwrapSuccessResponse(r);return o&&Array.isArray(o.content)&&o.content.forEach(e=>this._normalizeMessageTimestamps(e)),r}_advanceAnchorFromLive(e,t){e&&t&&(this._anchor.set(e,t),this._anchorGen.set(e,(this._anchorGen.get(e)||0)+1))}_commitAnchorFromSync(e,t,s){return!!t&&((this._anchorGen.get(e)||0)!==s?(this.logger.debug(`Anchor commit skipped (live advanced): room=${e}`),!1):(this._anchor.set(e,t),!0))}_replayMessages(e,t){if(!Array.isArray(t)||0===t.length)return 0;let s=0;this._replaying=!0;try{t.forEach(t=>{this._handleChatMessage(e,{...t,eventType:t.eventType||"MESSAGE_CREATED"})&&(s+=1)})}finally{this._replaying=!1}return s}async _reloadLatestPage(e,t){const s=await this.getMessages(e,{size:this.syncPageSize}),i=this._unwrapSuccessResponse(s)||{},n=(Array.isArray(i.content)?i.content:[]).slice().reverse(),r=this._replayMessages(e,n),o=n.length?n[n.length-1].id:null;return this._commitAnchorFromSync(e,o,t),r}_isCursorExpired(e){return 410===e?.status||"SYNC_CURSOR_EXPIRED"===e?.response?.code}async _syncRoom(e,t=this._anchor.get(e),s=!1){if(!t)return null;if(this._syncInFlight.has(e))return null;this._syncInFlight.add(e);const i=this._anchorGen.get(e)||0,n=Date.now();try{const r=[];let o=t,a=this.rewindMillis,c=!0,h=0;for(;c&&h<this.maxSyncPages;){const t=await this.syncMessages(e,{afterId:o,rewindMillis:a}),s=this._unwrapSuccessResponse(t)||{},i=Array.isArray(s.content)?s.content:[];r.push(...i),a=0,c=!!s.hasNext,s.lastId&&(o=s.lastId),h+=1}if(c){this.logger.info(`Gap too large, falling back to latest page: room=${e}`),s||this.emit("gapTruncated",{roomId:e,fetched:r.length});const t=await this._reloadLatestPage(e,i);return{roomId:e,cursor:this._anchor.get(e),recovered:t,truncated:!0,durationMs:Date.now()-n}}const l=this._replayMessages(e,r);return this._commitAnchorFromSync(e,o,i),{roomId:e,cursor:o,recovered:l,truncated:!1,durationMs:Date.now()-n}}catch(t){if(this._isCursorExpired(t)){this.logger.warn(`Sync cursor expired, reloading latest: room=${e}`),s||this.emit("gapTruncated",{roomId:e,fetched:0,reason:"cursorExpired"});const t=await this._reloadLatestPage(e,i);return{roomId:e,cursor:this._anchor.get(e),recovered:t,truncated:!0,durationMs:Date.now()-n}}throw t}finally{this._syncInFlight.delete(e)}}async syncAfterReconnect(e="manual"){if(!this.syncOnReconnect)return;const t=Array.from(this.subscribedRooms.keys()).filter(e=>this._anchor.has(e));if(0===t.length)return void await this._refreshRoomList(e);this.emit("syncStarted",{roomIds:t,reason:e});const s=Date.now(),i=[],n=new Map;for(const e of t)try{const t=await this._syncRoom(e);t&&(i.push(t),n.set(e,t.cursor))}catch(t){this.logger.warn(`Gap sync failed: room=${e}`,t)}return await this._refreshRoomList(e),this.emit("syncCompleted",{rooms:i,totalRecovered:i.reduce((e,t)=>e+(t.recovered||0),0),durationMs:Date.now()-s,reason:e}),n}async _supplementAfterReconnect(e,t){for(const[s,i]of e){if(t!==this._reconnectSyncGeneration)return;if(this.subscribedRooms.has(s))try{await this._syncRoom(s,i,!0)}catch(e){this.logger.warn(`Supplemental gap sync failed: room=${s}`,e)}}}async _refreshRoomList(e){if(this.roomListSubscribed)try{const t=await this.getRooms({size:50}),s=this._unwrapSuccessResponse(t)||{};this.emit("roomListSynced",{rooms:s.content||[],reason:e})}catch(e){this.logger.warn("Room list refresh failed (non-fatal):",e)}}async fetchLinkPreview(e){const t="string"==typeof e?e.trim():"";if(!t)throw new Error("url is required");const s=await this.apiClient.post("/api/v1/link-preview",{url:t});return this._unwrapSuccessResponse(s)}async sendMessage(e,t){const s=this._generateMessageId();return this._sendMessageWithId(e,s,t)}sendMessageOptimistic(e,t){const s=this._generateMessageId(),i=[s],n=this._sendMessageWithId(e,s,t).then(e=>this._attachOptimisticMetadata(i,e));return{baseMessageId:s,messageIds:i,promise:n}}async _sendMessageWithId(e,t,s){this.stopTyping(e);const i=await this.apiClient.post(`/api/v1/chat-messages/${e}/send`,{messageId:t,message:s.message,fileInfos:s.fileInfos,replyToMessageId:s.replyToMessageId,decisionResponse:s.decisionResponse}),n=this._unwrapSuccessResponse(i);return n&&Array.isArray(n.messages)&&n.messages.forEach(e=>this._normalizeMessageTimestamps(e)),n}async sendTextMessage(e,t){return this.sendMessage(e,{message:t})}sendTextMessageOptimistic(e,t){return this.sendMessageOptimistic(e,{message:t})}async uploadFile(e,t,s={}){if(!e)throw new Error("roomId is required");if(!t)throw new Error("file is required");const i=await this.apiClient.upload(`/api/v1/files/${e}/upload`,t,{onProgress:s.onProgress,signal:s.signal});return this._unwrapSuccessResponse(i)}async sendFileMessage(e,t,s={}){const i=this._normalizeFileArray(t),n=await this._uploadFiles(e,i,s),r=this._applyFileMetadata(n,s.metadata);return this.sendMessage(e,{message:s.message,fileInfos:r,replyToMessageId:s.replyToMessageId})}sendFileMessageOptimistic(e,t,s={}){const i=this._normalizeFileArray(t),n=this._generateMessageId(),r=[n],o=(async()=>{const t=await this._uploadFiles(e,i,s),o=this._applyFileMetadata(t,s.metadata),a=await this._sendMessageWithId(e,n,{message:s.message,fileInfos:o,replyToMessageId:s.replyToMessageId});return this._attachOptimisticMetadata(r,a)})();return{baseMessageId:n,messageIds:r,promise:o}}_normalizeFileArray(e){const t=Array.isArray(e)?e:[e];if(0===t.length)throw new Error("At least one file is required");if(t.length>20)throw new Error("A maximum of 20 files can be sent in one message");return t}async _uploadFiles(e,t,s={}){return Promise.all(t.map((t,i)=>this.uploadFile(e,t,{signal:s.signal,onProgress:s.onUploadProgress?e=>s.onUploadProgress({...e,fileIndex:i}):void 0})))}_applyFileMetadata(e,t){return null==t?e:e.map((e,s)=>{const i=Array.isArray(t)?t[s]:t;return null==i?e:{...e,metadata:i}})}async sendReply(e,t,s){return this.sendMessage(e,{message:t,replyToMessageId:s})}sendReplyOptimistic(e,t,s){return this.sendMessageOptimistic(e,{message:t,replyToMessageId:s})}async sendDecisionChoice(e,t,s){if(!t||!t.messageId)throw new Error("sendDecisionChoice: card with messageId is required");if(!s||!s.id)throw new Error("sendDecisionChoice: option with id is required");return this.sendMessage(e,{message:s.label,replyToMessageId:t.messageId,decisionResponse:{optionId:s.id}})}async deleteMessage(e,t,s="ALL"){return this.apiClient.post(`/api/v1/chat-messages/${e}/messages/${t}/delete`,{deleteType:s})}async editMessage(e,t,s){return this.apiClient.put(`/api/v1/chat-messages/${e}/messages/${t}`,{message:s})}_hasTextMessage(e){return"string"==typeof e&&e.trim().length>0}_baseMimeType(e){const t=e||"",s=t.indexOf(";");return(s>=0?t.slice(0,s):t).trim().toLowerCase()}classifyFileType(e){const t=this._baseMimeType(e);return t.startsWith("image/")?"IMAGE":t.startsWith("video/")?"VIDEO":t.startsWith("audio/")?"AUDIO":t.includes("pdf")||t.includes("document")||t.includes("msword")||t.includes("ms-excel")||t.includes("ms-powerpoint")||Xs.has(t)?"DOCUMENT":"FILE"}_classifyFileType(e){return this.classifyFileType(e)}resolveMessageCategory(e){const t=e&&e.chatMessageType,s=e&&e.fileMetaDataList||[];if("GALLERY"!==t)return t||"TEXT";if(0===s.length)return"FILE";const i=new Set(s.map(e=>this.classifyFileType(e&&e.fileType||"")));return 1===i.size?i.values().next().value:"MIXED"}_attachOptimisticMetadata(e,t){const s=t&&Array.isArray(t.messages)?t.messages.map(e=>e&&e.messageId||null):[],i=s.length===e.length&&e.every((e,t)=>e===s[t]);return i||this.logger.warn("Optimistic messageId prediction mismatch — server may have changed grouping rules. Use result.optimistic.actualMessageIds to reconcile.",{predicted:e,actual:s}),{...t,optimistic:{predictedMessageIds:e,actualMessageIds:s,predictionMatched:i}}}_generateMessageId(){return"undefined"!=typeof crypto&&"function"==typeof crypto.randomUUID?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{const t=16*Math.random()|0;return("x"===e?t:3&t|8).toString(16)})}_unwrapSuccessResponse(e){return e&&"object"==typeof e&&Object.prototype.hasOwnProperty.call(e,"data")?e.data:e}_normalizeMessageTimestamps(e){return e&&"object"==typeof e?(e.sentAt=this._toEpochMillis(e.sentAt),e.editedAt=this._toEpochMillis(e.editedAt),e.replyTo&&"object"==typeof e.replyTo&&(e.replyTo.sentAt=this._toEpochMillis(e.replyTo.sentAt)),e):e}_toEpochMillis(e){if("string"!=typeof e)return e;const t=Date.parse(e);return Number.isNaN(t)?e:t}async subscribeRoom(e){if(this.subscribedRooms.has(e))return void this.logger.warn(`Already subscribed to room: ${e}`);const t=_.getChatDestination(e);await this.connectionManager.subscribe(t,t=>{this._handleChatMessage(e,t)});const s=_.getChatReadDestination(e);await this.connectionManager.subscribe(s,t=>{this._handleReadEvent(e,t)});const i=_.getChatTypingDestination(e);await this.connectionManager.subscribe(i,t=>{this._handleTypingEvent(e,t)});const n=this.assistantStreamReplay?this._armAssistantSnapshot(e):null,r=_.getChatAssistantStreamDestination(e);await this.connectionManager.subscribe(r,t=>{this._handleAssistantStreamEvent(e,t)}),null!==n&&this._loadAssistantSnapshot(e,n).catch(t=>this.logger.warn(`Assistant snapshot merge failed: room=${e}`,t));const o=_.getChatSummaryDestination(e);await this.connectionManager.subscribe(o,t=>{this._handleSummaryEvent(e,t)});const a=t=>{t.roomId===e&&this.emit("memberJoined",{roomId:e,members:t.members||[],participantCount:t.activeParticipantCount,timestamp:t.timestamp})},c=t=>{t.roomId===e&&this.emit("memberLeft",{roomId:e,members:t.members||[],participantCount:t.activeParticipantCount,timestamp:t.timestamp})};this.on("roomListJoined",a),this.on("roomListLeft",c),this.subscribedRooms.set(e,{chatDestination:t,readDestination:s,typingDestination:i,assistantStreamDestination:r,summaryDestination:o,memberJoinedHandler:a,memberLeftHandler:c,subscribedAt:new Date}),this.logger.info(`Subscribed to room: ${e}`),this.emit("roomSubscribed",{roomId:e})}unsubscribeRoom(e){const t=this.subscribedRooms.get(e);t?(this.connectionManager.unsubscribe(t.chatDestination),this.connectionManager.unsubscribe(t.readDestination),t.typingDestination&&this.connectionManager.unsubscribe(t.typingDestination),t.assistantStreamDestination&&this.connectionManager.unsubscribe(t.assistantStreamDestination),t.summaryDestination&&this.connectionManager.unsubscribe(t.summaryDestination),t.memberJoinedHandler&&this.off("roomListJoined",t.memberJoinedHandler),t.memberLeftHandler&&this.off("roomListLeft",t.memberLeftHandler),this._clearTypingTimer(e),this._clearAssistantTypingTimer(e),this._clearAssistantProgress(e),this._activeRoomId===e&&(this._activeRoomId=null),this.subscribedRooms.delete(e),this._seenChatMessageIdsByRoom.delete(e),this._seenRoomListMessageIdsByRoom.delete(e),this.logger.info(`Unsubscribed from room: ${e}`),this.emit("roomUnsubscribed",{roomId:e})):this.logger.warn(`Not subscribed to room: ${e}`)}unsubscribeAllRooms(){this.subscribedRooms.forEach((e,t)=>{this.unsubscribeRoom(t)})}setActiveRoom(e){this._activeRoomId=e,this.logger.debug(`Active room set: ${e}`)}clearActiveRoom(){this.logger.debug(`Active room cleared (was: ${this._activeRoomId})`),this._activeRoomId=null}getActiveRoom(){return this._activeRoomId}async subscribeRoomList(){if(this.roomListSubscribed)return void this.logger.warn("Already subscribed to room list");const e=_.ROOM_LIST_USER_DESTINATION;await this.connectionManager.subscribe(e,e=>{this._handleRoomListEvent(e)}),this.roomListSubscribed=!0,this.logger.info("Subscribed to room list"),this.emit("roomListSubscribed",{})}unsubscribeRoomList(){this.roomListSubscribed?(this.connectionManager.unsubscribe(_.ROOM_LIST_USER_DESTINATION),this.roomListSubscribed=!1,this.logger.info("Unsubscribed from room list"),this.emit("roomListUnsubscribed",{})):this.logger.warn("Not subscribed to room list")}isRoomListSubscribed(){return this.roomListSubscribed}async subscribeMail(){this.mailSubscribed?this.logger.debug("Already subscribed to mail"):(await this.connectionManager.subscribe(_.MAIL_USER_DESTINATION,e=>{this._handleMailEvent(e)}),this.mailSubscribed=!0,this.logger.info("Subscribed to mail"),this.emit("mailSubscribed",{}))}unsubscribeMail(){this.mailSubscribed&&(this.connectionManager.unsubscribe(_.MAIL_USER_DESTINATION),this.mailSubscribed=!1,this.logger.info("Unsubscribed from mail"),this.emit("mailUnsubscribed",{}))}isMailSubscribed(){return this.mailSubscribed}_handleMailEvent(e){e&&"MAIL_CHANGED"===e.eventType&&(this.logger.debug("Mail changed:",e.connectionId,Array.isArray(e.messages)?e.messages.length:0),this.emit("mailChanged",e))}markAsRead(e,t){return this.connectionManager.isConnected()?this.connectionManager.send(_.CHAT_READ,{roomId:e,messageId:t}):(this.logger.warn("Cannot mark as read: not connected"),!1)}_handleChatMessage(e,t){if(this.logger.debug(`Message received in room ${e} (${t.eventType}):`,t),"MESSAGE_CREATED"===t.eventType&&this._shouldDedupMessage(this._seenChatMessageIdsByRoom,e,t.messageId))return this.logger.debug(`Duplicate MESSAGE_CREATED suppressed: room=${e}, messageId=${t.messageId}`),!1;switch("MESSAGE_CREATED"!==t.eventType||this._replaying||this._advanceAnchorFromLive(e,t.id),"MESSAGE_UPDATED"===t.eventType&&(void 0===t.translations&&(t.translations=null),void 0===t.sourceLang&&(t.sourceLang=null),void 0===t.translationsOf&&(t.translationsOf=null)),this.emit("message",{roomId:e,message:t}),t.eventType){case"MESSAGE_CREATED":"ASSISTANT"===t.senderType&&(this._clearAssistantTypingTimer(e),this.emit("typing",{roomId:e,userId:this._assistantTypingUserId,userName:this._assistantTypingUserName,typing:!1,senderType:"ASSISTANT"})),t.userId!==this.userId&&(this.emit("newMessage",{roomId:e,message:t}),this._activeRoomId===e&&t.messageId&&this.markAsRead(e,t.messageId));break;case"MESSAGE_UPDATED":this.emit("messageUpdated",{roomId:e,message:t});break;case"MESSAGE_DELETED":this.emit("messageDeleted",{roomId:e,message:t});break;case"REACTION_CHANGED":this.emit("reactionChanged",{roomId:e,message:t});break;case"LINK_PREVIEW_ATTACHED":this.emit("linkPreviewAttached",{roomId:e,message:t});break;case"MESSAGE_TRANSLATED":this.emit("messageTranslated",{roomId:e,message:t});break;default:this.logger.warn(`Unknown eventType "${t.eventType}" — falling back to legacy behavior`),t.userId!==this.userId&&(this.emit("newMessage",{roomId:e,message:t}),this._activeRoomId===e&&t.messageId&&this.markAsRead(e,t.messageId))}return!0}_handleRoomListEvent(e){if(this.logger.debug("Room list event:",e),e.eventType===m.MESSAGE_RECEIVED&&e.messageId&&this._shouldDedupMessage(this._seenRoomListMessageIdsByRoom,e.roomId,e.messageId))this.logger.debug(`Duplicate roomList MESSAGE_RECEIVED suppressed: room=${e.roomId}, messageId=${e.messageId}`);else switch(this.emit("roomListUpdate",e),e.eventType){case m.MESSAGE_RECEIVED:this.emit("roomListMessage",e);break;case m.MESSAGE_DELETED:this.emit("roomListMessageDeleted",e);break;case m.MESSAGE_UPDATED:this.emit("roomListMessageUpdated",e);break;case m.ROOM_CREATED:this.emit("roomListCreated",e);break;case m.ROOM_JOINED:this.emit("roomListJoined",e);break;case m.ROOM_LEFT:this.emit("roomListLeft",e),e.actorId===this.userId&&this.emit("roomListSelfLeft",e);break;case m.ROOM_KICKED:this.emit("roomListKicked",e),this._isSelfInMembers(e)&&this.emit("roomListSelfKicked",e);break;case m.ROOM_OWNER_CHANGED:this.emit("roomListOwnerChanged",e);break;case m.ROOM_DELETED:this.subscribedRooms.has(e.roomId)&&this.unsubscribeRoom(e.roomId),this.emit("roomListDeleted",e);break;case m.ROOM_BANNED:this.emit("roomListBanned",e),this._isSelfInMembers(e)&&this.emit("roomListSelfBanned",e);break;case m.ROOM_UPDATED:this.emit("roomListRoomUpdated",e);break;case m.MESSAGE_RETENTION_CLEANUP:this.emit("retentionCleanup",{roomId:e.roomId,cutoffTime:e.cutoffTime});break;case m.ROOM_UNREAD_UPDATED:this.emit("roomListUnreadUpdated",{roomId:e.roomId,roomUnreadCount:e.roomUnreadCount,unreadVersion:e.unreadVersion});break;case m.AI_UNAVAILABLE:this.emit("aiUnavailable",{roomId:e.roomId,messageId:e.messageId,aiBlocked:e.aiBlocked,timestamp:e.timestamp});break;default:this.logger.warn("Unknown room list event type:",e.eventType)}}_handleReadEvent(e,t){this.logger.debug(`Read event in room ${e}:`,t);const s=t.roomId||e;t.events&&Array.isArray(t.events)?t.events.forEach(e=>{this.emit("messageRead",{roomId:s,messageId:e.messageId,userId:t.userId,remainingUnreadCount:e.remainingUnreadCount})}):this.emit("messageRead",{roomId:s,messageId:t.messageId,userId:t.userId,remainingUnreadCount:t.remainingUnreadCount})}startTyping(e){if(!this.connectionManager.isConnected())return;const t=this._typingTimers.get(e);t?clearTimeout(t):this.connectionManager.send(_.CHAT_TYPING,{roomId:e,typing:!0});const s=setTimeout(()=>{this.stopTyping(e)},3e3);this._typingTimers.set(e,s)}stopTyping(e){this._clearTypingTimer(e),this.connectionManager.isConnected()&&this.connectionManager.send(_.CHAT_TYPING,{roomId:e,typing:!1})}_isSelfInMembers(e){return Array.isArray(e.members)&&e.members.some(e=>e&&e.userId===this.userId)}_handleTypingEvent(e,t){"ASSISTANT"!==t.senderType&&t.userId===this.userId||("ASSISTANT"===t.senderType&&!0===t.typing&&this._startAssistantTypingTimer(e),this.emit("typing",{roomId:e,userId:t.userId,userName:t.userName,typing:t.typing,senderType:t.senderType||"USER"}))}_startAssistantTypingTimer(e){this._clearAssistantTypingTimer(e);const t=setTimeout(()=>{this._assistantTypingTimers.delete(e),this.emit("typing",{roomId:e,userId:this._assistantTypingUserId,userName:this._assistantTypingUserName,typing:!1,senderType:"ASSISTANT"}),this.logger.debug(`Assistant typing auto-cleared (timeout): room=${e}`)},this._assistantTypingTimeoutMs);this._assistantTypingTimers.set(e,t)}_clearAssistantTypingTimer(e){const t=this._assistantTypingTimers.get(e);t&&(clearTimeout(t),this._assistantTypingTimers.delete(e))}_clearTypingTimer(e){const t=this._typingTimers.get(e);t&&(clearTimeout(t),this._typingTimers.delete(e))}_handleAssistantStreamEvent(e,t){if(!t||!t.type)return;const s=t.streamId||null;if(!s)return void this.logger.debug(`Assistant stream event without streamId ignored: room=${e}, type=${t.type}`);if(this._isAssistantStreamClosed(e,s))return void this.logger.debug(`Assistant event for closed stream ignored: room=${e}, stream=${s}, type=${t.type}`);const i=this._assistantSnapshotPending.get(e);if(i&&"DONE"!==t.type)i.events.push(t);else{if("PHASE"===t.type){const i=this._assistantSlot(e,s),n="number"==typeof t.createdAt?t.createdAt:null;if(i&&null!==n&&n<=(i.phaseUpdatedAt||0))return void this.logger.debug(`Stale assistant PHASE ignored: room=${e}, stream=${s}, createdAt=${n}, applied=${i.phaseUpdatedAt}`);const r=t.phase||null,o=Boolean(i&&i.phase===r),a=t.progress?this._normalizeAssistantProgress(t.progress):o&&i?i.progress:null,c=i,h=this._setAssistantSlot(e,s,t,{phase:r,progress:a,phaseUpdatedAt:null!==n?n:c?c.phaseUpdatedAt:0,text:c&&c.text||"",lastSeq:c?this._seqOf(c.lastSeq):-1,textAvailable:!c||!1!==c.textAvailable});return void this._emitAssistantStream(e,s,h,{active:!0,text:h.textAvailable&&h.text||null})}if("DELTA"===t.type){const i=this._assistantSlot(e,s),n=i&&i.phase||"WRITING",r="number"==typeof t.seq?t.seq:null;let o=i?this._seqOf(i.lastSeq):-1,a=!i||!1!==i.textAvailable,c=i&&i.text||"";if(null===r)a&&(c+=t.delta||"");else{if(r<=o)return void this.logger.debug(`Duplicate assistant DELTA ignored: room=${e}, stream=${s}, seq=${r}, lastSeq=${o}`);r===o+1?(a&&(c+=t.delta||""),o=r):(this.logger.debug(`Assistant DELTA gap — text dropped: room=${e}, stream=${s}, seq=${r}, lastSeq=${o}`),a=!1,c="",o=r)}const h=this._setAssistantSlot(e,s,t,{phase:n,progress:i&&i.progress||null,text:c,lastSeq:o,textAvailable:a});return void this._emitAssistantStream(e,s,h,{active:!0,text:h.textAvailable?h.text:null,delta:h.textAvailable&&t.delta||null,seq:r})}if("DONE"===t.type){const i=this._assistantSlot(e,s);i&&i.timer&&clearTimeout(i.timer),this._deleteAssistantSlot(e,s),this._tombstoneAssistantStream(e,s),this._emitAssistantStream(e,s,i,{active:!1,personaId:t.personaId||i&&i.personaId||null,phase:null,progress:null,label:null,status:t.status||null,messageId:t.messageId||null})}}}async _loadAssistantSnapshot(e,t){const s=this._assistantSnapshotInFlight.get(e);if(s&&s.generation===t)return s.task;const i=(async()=>{let s=null;try{const t=await this.apiClient.get(`/api/v1/rooms/${e}/assistant/streams`),i=this._unwrapSuccessResponse(t);s=i&&Array.isArray(i.streams)?i.streams:[]}catch(t){this.logger.warn(`Assistant stream snapshot failed (live-only fallback): room=${e}`,t)}if(this._assistantGeneration(e)!==t)return this.logger.debug(`Assistant snapshot discarded (stale generation): room=${e}`),void this._deleteAssistantPendingIfGeneration(e,t);s&&this._applyAssistantSnapshot(e,s),this._drainAssistantPending(e,t)})();this._assistantSnapshotInFlight.set(e,{generation:t,task:i});try{await i}finally{const s=this._assistantSnapshotInFlight.get(e);s&&s.generation===t&&this._assistantSnapshotInFlight.delete(e)}}_deleteAssistantPendingIfGeneration(e,t){const s=this._assistantSnapshotPending.get(e);s&&s.generation===t&&this._assistantSnapshotPending.delete(e)}_applyAssistantSnapshot(e,t){t.forEach(t=>{const s=t&&t.streamId;if(!s)return;if(this._isAssistantStreamClosed(e,s))return;if("DONE"===t.status)return this._tombstoneAssistantStream(e,s),void this._emitAssistantStream(e,s,null,{active:!1,phase:null,progress:null,label:null,personaId:t.personaId||null,status:t.doneStatus||null,messageId:t.messageId||null,resumed:!0});const i=!1!==t.textAvailable,n=this._setAssistantSlot(e,s,{personaId:t.personaId,expiresAt:void 0},{phase:t.phase||null,progress:this._normalizeAssistantProgress(t.progress),phaseUpdatedAt:"number"==typeof t.phaseUpdatedAt?t.phaseUpdatedAt:0,text:i&&t.text||"",lastSeq:this._seqOf(t.lastSeq),textAvailable:i,resumed:!0});this._emitAssistantStream(e,s,n,{active:!0,text:n.textAvailable&&n.text||null,resumed:!0})})}_drainAssistantPending(e,t){const s=this._assistantSnapshotPending.get(e);s&&(void 0!==t&&s.generation!==t||(this._assistantSnapshotPending.delete(e),s.events.forEach(t=>this._handleAssistantStreamEvent(e,t))))}_assistantGeneration(e){return this._assistantRoomGeneration.get(e)||0}_armAssistantSnapshot(e){const t=this._assistantGeneration(e)+1;this._assistantRoomGeneration.set(e,t);const s=this._assistantSnapshotPending.get(e);return this._assistantSnapshotPending.set(e,{generation:t,events:s?s.events:[]}),t}async resumeAssistantStreams(e="manual"){if(!this.assistantStreamReplay)return;const t=Array.from(this.subscribedRooms.keys());0!==t.length&&(this.logger.debug(`Assistant stream replay: rooms=${t.length}, reason=${e}`),await Promise.all(t.map(e=>{const t=this._armAssistantSnapshot(e);return this._loadAssistantSnapshot(e,t).catch(t=>this.logger.warn(`Assistant stream replay failed: room=${e}`,t))})))}_assistantSlots(e){let t=this._assistantProgress.get(e);return t||(t=new Map,this._assistantProgress.set(e,t)),t}_assistantSlot(e,t){const s=this._assistantProgress.get(e);return s?s.get(t):void 0}_deleteAssistantSlot(e,t){const s=this._assistantProgress.get(e);s&&(s.delete(t),0===s.size&&this._assistantProgress.delete(e))}_isAssistantStreamClosed(e,t){const s=this._assistantStreamTombstones.get(e);if(!s)return!1;const i=s.get(t);return void 0!==i&&(!(i<=Date.now())||(s.delete(t),!1))}_tombstoneAssistantStream(e,t){let s=this._assistantStreamTombstones.get(e);s||(s=new Map,this._assistantStreamTombstones.set(e,s));const i=Date.now();s.forEach((e,t)=>{e<=i&&s.delete(t)}),s.set(t,i+this._assistantTombstoneTtlMs),s.size>this._assistantTombstoneWarnThreshold?this._assistantTombstoneWarned.has(e)||(this._assistantTombstoneWarned.add(e),this.logger.warn(`Assistant tombstones above threshold — NOT pruning (TTL only): room=${e}, size=${s.size}, threshold=${this._assistantTombstoneWarnThreshold}`)):this._assistantTombstoneWarned.delete(e)}_handleSummaryEvent(e,t){t&&t.status&&this.emit("summaryUpdate",{roomId:e,status:t.status,format:t.format||null,languages:t.languages||null,updatedAt:t.updatedAt||null})}_seqOf(e){return"number"==typeof e?e:-1}_setAssistantSlot(e,t,s,i){const n=this._assistantSlot(e,t);n&&n.timer&&clearTimeout(n.timer);let r=this._assistantProgressFallbackTtlMs;"number"==typeof s.expiresAt&&(r=Math.min(12e4,Math.max(5e3,s.expiresAt-Date.now())));const o=setTimeout(()=>{this._expireAssistantStream(e,t)},r),a={personaId:s.personaId||n&&n.personaId||null,phase:i.phase,progress:i.progress||null,phaseUpdatedAt:void 0!==i.phaseUpdatedAt?i.phaseUpdatedAt:n&&n.phaseUpdatedAt||0,text:i.text||"",lastSeq:this._seqOf(i.lastSeq),textAvailable:!1!==i.textAvailable,resumed:!0===i.resumed||!!n&&!0===n.resumed,updatedAt:Date.now(),order:++this._assistantSlotSeq,timer:o};return this._assistantSlots(e).set(t,a),a}_expireAssistantStream(e,t){const s=this._assistantSlot(e,t);s&&(s.timer&&clearTimeout(s.timer),this._deleteAssistantSlot(e,t),this.logger.debug(`Assistant progress auto-cleared (timeout): room=${e}, stream=${t}`),this._emitAssistantStream(e,t,s,{active:!1,phase:null,progress:null,label:null,reason:"timeout"}))}_emitAssistantStream(e,t,s,i){const n="phase"in i?i.phase:s?s.phase:null,r="progress"in i?i.progress:s?s.progress:null;this.emit("assistantProgress",{roomId:e,streamId:t,personaId:s?s.personaId:null,phase:n,progress:r,label:this._assistantPhaseLabel(n,r),textAvailable:!s||s.textAvailable,lastSeq:s?s.lastSeq:-1,...i}),this._emitAssistantRoomProgress(e)}_emitAssistantRoomProgress(e){const{streams:t,...s}=this._assistantRoomProgressPayload(e);this.emit("assistantRoomProgress",s)}_assistantRoomProgressPayload(e){const t=this._assistantProgress.get(e),s=t?Array.from(t.entries()):[];if(0===s.length)return{roomId:e,active:!1,streamCount:0,streamId:null,personaId:null,phase:null,label:null,text:null,textAvailable:!0,progress:null,streams:[]};const[i,n]=s.reduce((e,t)=>t[1].order>e[1].order?t:e);return{roomId:e,active:!0,streamCount:s.length,streamId:i,personaId:n.personaId,phase:n.phase,progress:n.progress||null,label:this._assistantPhaseLabel(n.phase,n.progress),text:n.textAvailable&&n.text||null,textAvailable:n.textAvailable,streams:s.sort((e,t)=>e[1].order-t[1].order).map(([e,t])=>({streamId:e,personaId:t.personaId,phase:t.phase,progress:t.progress||null,label:this._assistantPhaseLabel(t.phase,t.progress),text:t.textAvailable&&t.text||null,textAvailable:t.textAvailable,resumed:!0===t.resumed}))}}_normalizeAssistantProgress(e){if(!e||!["ANALYZING","SUMMARIZING"].includes(e.stage))return null;if("SUMMARIZING"===e.stage)return{stage:"SUMMARIZING",current:null,total:null,unit:null};const t=Number.isInteger(e.current)?e.current:null,s=Number.isInteger(e.total)?e.total:null,i=["DOCUMENT","PAGE","TEXT_CHUNK"].includes(e.unit)?e.unit:null;return null===t||null===s||!i||t<0||s<1||t>s?null:{stage:"ANALYZING",current:t,total:s,unit:i}}_assistantPhaseLabel(e,t){if(!e)return null;if("DOCUMENT_ANALYSIS"!==e)return this._assistantPhaseLabels[e]||null;if(t&&"SUMMARIZING"===t.stage)return"분석 결과 종합 중…";if(!t||"ANALYZING"!==t.stage)return this._assistantPhaseLabels[e];const s="PAGE"===t.unit?"페이지":"TEXT_CHUNK"===t.unit?"구간":"개";return`문서 분석 중… (${t.current}/${t.total}${s})`}getAssistantProgress(e){return this._assistantRoomProgressPayload(e)}_clearAssistantProgress(e){const t=this._assistantProgress.get(e);t&&(t.forEach(e=>e.timer&&clearTimeout(e.timer)),this._assistantProgress.delete(e)),this._assistantStreamTombstones.delete(e),this._assistantTombstoneWarned.delete(e),this._assistantSnapshotPending.delete(e),this._assistantRoomGeneration.set(e,(this._assistantRoomGeneration.get(e)||0)+1)}getSubscribedRooms(){return Array.from(this.subscribedRooms.keys())}isSubscribed(e){return this.subscribedRooms.has(e)}setLogLevel(e){this.logger.setLevel(e)}_cancelDelayedReconnectSync(){this._reconnectSyncGeneration++,clearTimeout(this._delayedReconnectSyncTimer),this._delayedReconnectSyncTimer=null}destroy(){this._cancelDelayedReconnectSync(),this.connectionManager.off?.("stateChange",this._onStateChangeForSync),this.unsubscribeAllRooms(),this.roomListSubscribed&&this.unsubscribeRoomList(),this._typingTimers.forEach(e=>clearTimeout(e)),this._typingTimers.clear(),this._assistantTypingTimers.forEach(e=>clearTimeout(e)),this._assistantTypingTimers.clear(),this._assistantProgress.forEach(e=>e.forEach(e=>e.timer&&clearTimeout(e.timer))),this._assistantProgress.clear(),this._assistantStreamTombstones.clear(),this._assistantTombstoneWarned.clear(),this._assistantRoomGeneration.clear(),this._assistantSnapshotPending.clear(),this._assistantSnapshotInFlight.clear(),this._seenChatMessageIdsByRoom.clear(),this._seenRoomListMessageIdsByRoom.clear(),this.connectionManager&&"function"==typeof this.connectionManager.off&&(this._onReconnectedForSync&&this.connectionManager.off("reconnected",this._onReconnectedForSync),this._onResumedForSync&&this.connectionManager.off("resumed",this._onResumedForSync)),this._anchor.clear(),this._anchorGen.clear(),this._syncInFlight.clear(),this.removeAllListeners(),this.logger.info("ChatClient destroyed")}}class Qs extends e{constructor(e={}){super(),this.localStream=null,this.screenStream=null,this.videoEnabled=!0,this.audioEnabled=!0,this.logger=new S(e.logLevel||w.WARN,"MediaStreamManager"),this._deviceChangeHandler=null}async getUserMedia(e={video:!0,audio:!0}){try{return this.localStream=await navigator.mediaDevices.getUserMedia(e),this.videoEnabled=!1!==e.video,this.audioEnabled=!1!==e.audio,this.emit("streamStarted",{stream:this.localStream}),this.logger.info("User media stream started"),this.localStream}catch(e){throw this.logger.error("Failed to get user media:",e),this.emit("error",{type:s.MEDIA_ACCESS_DENIED,message:this._getMediaErrorMessage(e),error:e}),e}}_getMediaErrorMessage(e){switch(e.name){case"NotAllowedError":return"Camera/Microphone permission denied";case"NotFoundError":return"Camera/Microphone not found";case"NotReadableError":return"Camera/Microphone is already in use";case"OverconstrainedError":return"Camera/Microphone constraints cannot be satisfied";case"AbortError":return"Media access aborted";default:return e.message||"Unknown media error"}}async getDisplayMedia(e={video:!0,audio:!1}){try{return this.screenStream=await navigator.mediaDevices.getDisplayMedia(e),this.screenStream.getVideoTracks()[0].onended=()=>{this.emit("screenShareEnded",{}),this.screenStream=null},this.emit("screenShareStarted",{stream:this.screenStream}),this.logger.info("Screen share stream started"),this.screenStream}catch(e){throw this.logger.error("Failed to get display media:",e),this.emit("error",{type:s.SCREEN_SHARE_DENIED,message:"NotAllowedError"===e.name?"Screen share permission denied":e.message,error:e}),e}}toggleVideo(){if(!this.localStream)return this.logger.warn("No local stream available"),this.videoEnabled;const e=this.localStream.getVideoTracks();return 0===e.length?(this.logger.warn("No video track available"),this.videoEnabled):(this.videoEnabled=!this.videoEnabled,e.forEach(e=>{e.enabled=this.videoEnabled}),this.emit("videoToggled",{enabled:this.videoEnabled}),this.logger.debug(`Video toggled: ${this.videoEnabled}`),this.videoEnabled)}toggleAudio(){if(!this.localStream)return this.logger.warn("No local stream available"),this.audioEnabled;const e=this.localStream.getAudioTracks();return 0===e.length?(this.logger.warn("No audio track available"),this.audioEnabled):(this.audioEnabled=!this.audioEnabled,e.forEach(e=>{e.enabled=this.audioEnabled}),this.emit("audioToggled",{enabled:this.audioEnabled}),this.logger.debug(`Audio toggled: ${this.audioEnabled}`),this.audioEnabled)}setVideoEnabled(e){if(!this.localStream)return void this.logger.warn("No local stream available");this.localStream.getVideoTracks().forEach(t=>{t.enabled=e}),this.videoEnabled=e,this.emit("videoToggled",{enabled:e})}setAudioEnabled(e){if(!this.localStream)return void this.logger.warn("No local stream available");this.localStream.getAudioTracks().forEach(t=>{t.enabled=e}),this.audioEnabled=e,this.emit("audioToggled",{enabled:e})}getLocalStream(){return this.localStream}getScreenStream(){return this.screenStream}isVideoEnabled(){return this.videoEnabled}isAudioEnabled(){return this.audioEnabled}stopAll(){this.localStream&&(this.localStream.getTracks().forEach(e=>e.stop()),this.localStream=null,this.emit("streamStopped",{}),this.logger.info("All media tracks stopped")),this.screenStream&&(this.screenStream.getTracks().forEach(e=>e.stop()),this.screenStream=null)}replaceTrack(e,t){this.localStream?(this.localStream.removeTrack(e),this.localStream.addTrack(t),e.stop(),this.emit("trackReplaced",{oldTrack:e,newTrack:t}),this.logger.debug(`Track replaced: ${e.kind}`)):this.logger.warn("No local stream available")}getTrack(e){if(!this.localStream)return null;const t="video"===e?this.localStream.getVideoTracks():this.localStream.getAudioTracks();return t.length>0?t[0]:null}async getDevices(){try{const e=await navigator.mediaDevices.enumerateDevices();return{videoInputs:e.filter(e=>"videoinput"===e.kind),audioInputs:e.filter(e=>"audioinput"===e.kind),audioOutputs:e.filter(e=>"audiooutput"===e.kind)}}catch(e){throw this.logger.error("Failed to enumerate devices:",e),this.emit("error",{type:s.ENUMERATE_DEVICES_FAILED,message:e.message,error:e}),e}}async switchDevice(e,t){if(!this.localStream)throw new Error("No local stream available");try{const s="video"===t?{video:{deviceId:{exact:e}},audio:!1}:{video:!1,audio:{deviceId:{exact:e}}},i=(await navigator.mediaDevices.getUserMedia(s)).getTracks()[0],n="video"===t?this.localStream.getVideoTracks()[0]:this.localStream.getAudioTracks()[0];return n&&(this.replaceTrack(n,i),this.emit("deviceSwitched",{kind:t,deviceId:e,newTrack:i}),this.logger.info(`${t} device switched to ${e}`)),i}catch(e){throw this.logger.error(`Failed to switch ${t} device:`,e),this.emit("error",{type:s.DEVICE_SWITCH_FAILED,message:e.message,error:e}),e}}startDeviceChangeDetection(){this._deviceChangeHandler||(this._deviceChangeHandler=async()=>{try{const e=await this.getDevices();this.emit("deviceChange",e),this.logger.debug("Device change detected")}catch(e){this.logger.warn("Failed to get devices on change:",e)}},navigator.mediaDevices.addEventListener("devicechange",this._deviceChangeHandler),this.logger.debug("Device change detection started"))}stopDeviceChangeDetection(){this._deviceChangeHandler&&(navigator.mediaDevices.removeEventListener("devicechange",this._deviceChangeHandler),this._deviceChangeHandler=null,this.logger.debug("Device change detection stopped"))}getStreamInfo(){return this.localStream?{hasStream:!0,videoEnabled:this.videoEnabled,audioEnabled:this.audioEnabled,tracks:this.localStream.getTracks().map(e=>({kind:e.kind,id:e.id,label:e.label,enabled:e.enabled,readyState:e.readyState,muted:e.muted}))}:{hasStream:!1,videoEnabled:this.videoEnabled,audioEnabled:this.audioEnabled,tracks:[]}}async applyVideoConstraints(e){if(!this.localStream)throw new Error("No local stream available");const t=this.localStream.getVideoTracks()[0];if(!t)throw new Error("No video track available");try{await t.applyConstraints(e),this.emit("videoConstraintsApplied",{constraints:e}),this.logger.info("Video constraints applied:",e)}catch(e){throw this.logger.error("Failed to apply video constraints:",e),e}}getVideoSettings(){if(!this.localStream)return null;const e=this.localStream.getVideoTracks()[0];return e?e.getSettings():null}getAudioSettings(){if(!this.localStream)return null;const e=this.localStream.getAudioTracks()[0];return e?e.getSettings():null}setLogLevel(e){this.logger.setLevel(e)}destroy(){this.stopAll(),this.stopDeviceChangeDetection(),this.removeAllListeners(),this.logger.info("MediaStreamManager destroyed")}}class Zs extends e{constructor(e={}){super(),this.iceServers=e.iceServers||b.iceServers,this.logger=new S(e.logLevel||w.WARN,"PeerConnectionManager"),this.peers=new Map,this.localStream=null}setLocalStream(e){this.localStream=e,this.peers.forEach(e=>{this._addTracksToConnection(e.connection)})}setIceServers(e){this.iceServers=e}createPeerConnection(e,t=!1,s={}){if(this.peers.has(e))return this.logger.warn(`Peer connection already exists: ${e}`),this.peers.get(e).connection;const i={iceServers:this.iceServers,iceCandidatePoolSize:10},n=new RTCPeerConnection(i),r={connection:n,polite:t,makingOffer:!1,ignoreOffer:!1,isSettingRemoteAnswerPending:!1,skipAutoNegotiation:s.skipAutoNegotiation||!1};return this.peers.set(e,r),this._setupConnectionHandlers(e,n,r),this.localStream&&this._addTracksToConnection(n),this.logger.info(`Peer connection created: ${e} (polite: ${t}, skipAutoNegotiation: ${r.skipAutoNegotiation})`),n}async resumeAutoNegotiation(e){const t=this.peers.get(e);return!(!t||"stable"!==t.connection.signalingState)&&(t.skipAutoNegotiation=!1,await t.connection.onnegotiationneeded(),!0)}_setupConnectionHandlers(e,t,i){t.onicecandidate=t=>{t.candidate&&this.emit("iceCandidate",{peerId:e,candidate:t.candidate})},t.oniceconnectionstatechange=()=>{this.logger.debug(`ICE connection state (${e}): ${t.iceConnectionState}`),this.emit("iceConnectionStateChange",{peerId:e,state:t.iceConnectionState}),"failed"===t.iceConnectionState&&this.emit("error",{type:s.ICE_CONNECTION_FAILED,peerId:e,message:"ICE connection failed"})},t.onconnectionstatechange=()=>{this.logger.debug(`Connection state (${e}): ${t.connectionState}`),this.emit("connectionStateChange",{peerId:e,state:t.connectionState}),"connected"===t.connectionState?this.emit("peerConnected",{peerId:e}):"disconnected"!==t.connectionState&&"failed"!==t.connectionState||this.emit("peerDisconnected",{peerId:e})},t.onnegotiationneeded=async()=>{if(i.skipAutoNegotiation||i.makingOffer||"stable"!==t.signalingState)this.logger.debug(`Skipping auto negotiation for ${e} (manual offer will be sent)`);else try{i.makingOffer=!0,await t.setLocalDescription(),this.emit("negotiationNeeded",{peerId:e,description:t.localDescription})}catch(t){this.logger.error(`Negotiation error (${e}):`,t)}finally{i.makingOffer=!1}},t.ontrack=t=>{this.logger.info(`Remote track received from ${e}:`,t.track.kind),this.emit("remoteTrack",{peerId:e,track:t.track,streams:t.streams})},t.ondatachannel=t=>{this.logger.info(`Data channel received from ${e}`),this.emit("dataChannel",{peerId:e,channel:t.channel})}}_addTracksToConnection(e){if(!this.localStream)return;const t=e.getSenders();this.localStream.getTracks().forEach(s=>{t.find(e=>e.track&&e.track.kind===s.kind)||e.addTrack(s,this.localStream)})}async createOffer(e){const t=this.peers.get(e);if(!t)throw new Error(`Peer not found: ${e}`);try{const s=await t.connection.createOffer();return await t.connection.setLocalDescription(s),this.logger.debug(`Offer created for ${e}`),t.connection.localDescription}catch(t){throw this.logger.error(`Failed to create offer for ${e}:`,t),t}}async createAnswer(e){const t=this.peers.get(e);if(!t)throw new Error(`Peer not found: ${e}`);try{const s=await t.connection.createAnswer();return await t.connection.setLocalDescription(s),this.logger.debug(`Answer created for ${e}`),t.connection.localDescription}catch(t){throw this.logger.error(`Failed to create answer for ${e}:`,t),t}}async handleRemoteDescription(e,t){const s=this.peers.get(e);if(!s)throw new Error(`Peer not found: ${e}`);const{connection:i,polite:n,makingOffer:r}=s,o="offer"===t.type&&(r||"stable"!==i.signalingState);if(s.ignoreOffer=!n&&o,s.ignoreOffer)this.logger.debug(`Ignoring offer collision from ${e} (I am impolite)`);else try{if(o&&n&&(this.logger.debug(`Offer collision detected, rolling back local offer for ${e} (I am polite)`),await i.setLocalDescription({type:"rollback"})),s.isSettingRemoteAnswerPending="answer"===t.type,await i.setRemoteDescription(t),s.isSettingRemoteAnswerPending=!1,this.logger.debug(`Remote ${t.type} set for ${e}`),"offer"===t.type){const t=await this.createAnswer(e);this.emit("answerCreated",{peerId:e,answer:t})}}catch(t){throw this.logger.error(`Failed to set remote description for ${e}:`,t),t}}async addIceCandidate(e,t){const s=this.peers.get(e);if(!s)return this.logger.warn(`Peer not found for ICE candidate: ${e}`),!1;if(!s.connection.remoteDescription)return this.logger.debug(`Remote description not set yet for ${e}, ICE candidate queued`),!1;try{return await s.connection.addIceCandidate(t),this.logger.debug(`ICE candidate added for ${e}`),!0}catch(t){return s.ignoreOffer||this.logger.error(`Failed to add ICE candidate for ${e}:`,t),!1}}getPeerConnection(e){const t=this.peers.get(e);return t?t.connection:null}getPeerIds(){return Array.from(this.peers.keys())}closePeerConnection(e){const t=this.peers.get(e);t&&(t.connection.close(),this.peers.delete(e),this.emit("peerClosed",{peerId:e}),this.logger.info(`Peer connection closed: ${e}`))}closeAllPeerConnections(){this.peers.forEach((e,t)=>{e.connection.close(),this.logger.debug(`Peer connection closed: ${t}`)}),this.peers.clear(),this.emit("allPeersClosed",{})}async replaceTrack(e,t){const s=[];this.peers.forEach((i,n)=>{const r=i.connection.getSenders().find(t=>t.track&&t.track.kind===e.kind);r&&s.push(r.replaceTrack(t).then(()=>this.logger.debug(`Track replaced for ${n}`)).catch(e=>this.logger.error(`Failed to replace track for ${n}:`,e)))}),await Promise.all(s)}async getStats(e){const t=this.peers.get(e);return t?t.connection.getStats():null}getConnectionSummary(){const e={};return this.peers.forEach((t,s)=>{e[s]={connectionState:t.connection.connectionState,iceConnectionState:t.connection.iceConnectionState,signalingState:t.connection.signalingState,polite:t.polite}}),e}setLogLevel(e){this.logger.setLevel(e)}destroy(){this.closeAllPeerConnections(),this.localStream=null,this.removeAllListeners(),this.logger.info("PeerConnectionManager destroyed")}}const ei=new Set([i.CALL_REQUEST,i.CALL_ACCEPT,i.CALL_REJECT,i.CALL_CANCEL,i.CALL_BUSY]);class ti extends e{constructor(e){super(),this.connectionManager=e.connectionManager,this.apiClient=e.apiClient,this.userId=e.userId,this.logLevel=e.logLevel||w.WARN,this.logger=new S(this.logLevel,"WebRTCClient"),this.mediaManager=new Qs({logLevel:this.logLevel}),this.peerManager=new Zs({iceServers:e.iceServers||b.iceServers,logLevel:this.logLevel}),this.currentRoom=null,this.isGroupCall=!1,this.participants=new Map,this._callActive=!1,this._callGeneration=0,this._deferredGroupPeers=new Map,this._joinedGroupRoom=null,this._groupJoin=null,this._directCallPeer=null,this._incomingCallPeer=null,this._receivedInvitations=new Map,this._hostedCallRooms=new Map,this._pendingRoomCreations=0,this._earlyRoomRejects=[],this._groupRecoveryTimer=null,this._groupRecoveryAttempts=0,this._onReconnected=()=>{this._recoverGroupParticipation().catch(e=>this.logger.error("Call recovery failed:",e))},this.connectionManager.on?.("reconnected",this._onReconnected),this._iceServersFetched=!1,this._waitingForCallAccept=!1,this._pendingCallTarget=null,this._pendingIceCandidates=new Map,this._setupEventHandlers()}async initializeIceServers(){if(!this._iceServersFetched)try{const e=await this.getTurnCredentials();e&&e.iceServers&&(this.peerManager.setIceServers(e.iceServers),this._iceServersFetched=!0,this.logger.info("ICE servers fetched successfully"))}catch(e){this.logger.warn("Failed to fetch TURN credentials, using fallback ICE servers:",e.message),this._setFallbackIceServers()}}_setFallbackIceServers(){this.peerManager.setIceServers([{urls:"stun:stun.l.google.com:19302"},{urls:"stun:stun1.l.google.com:19302"}])}_setupEventHandlers(){this.mediaManager.on("streamStarted",e=>this.emit("localStreamStarted",e)),this.mediaManager.on("streamStopped",e=>this.emit("localStreamStopped",e)),this.mediaManager.on("videoToggled",()=>this._sendMediaState()),this.mediaManager.on("audioToggled",()=>this._sendMediaState()),this.mediaManager.on("screenShareStarted",e=>this.emit("screenShareStarted",e)),this.mediaManager.on("screenShareEnded",e=>this.emit("screenShareEnded",e)),this.mediaManager.on("error",e=>this.emit("error",e)),this.peerManager.on("remoteTrack",e=>this.emit("remoteTrack",e)),this.peerManager.on("peerConnected",e=>this.emit("peerConnected",e)),this.peerManager.on("peerDisconnected",e=>this.emit("peerDisconnected",e)),this.peerManager.on("peerClosed",e=>this.emit("peerClosed",e)),this.peerManager.on("error",e=>this.emit("error",e)),this.peerManager.on("iceCandidate",({peerId:e,candidate:t})=>{this._sendSignal({type:i.ICE_CANDIDATE,receiverId:e,data:{candidate:t}})}),this.peerManager.on("negotiationNeeded",({peerId:e,description:t})=>{this._sendSignal({type:i.CALL_OFFER,receiverId:e,data:{sdp:t}})}),this.peerManager.on("answerCreated",({peerId:e,answer:t})=>{this._sendSignal({type:i.CALL_ANSWER,receiverId:e,data:{sdp:t}})})}async getTurnCredentials(){return(await this.apiClient.get("/api/v1/webrtc/turn-credentials")).data}async createCallRoom(e){this._pendingRoomCreations++;try{const t=await this.apiClient.post("/api/v1/webrtc/rooms",e),s=t?.data?.callRoomId;return s&&this._rememberCallRoom(this._hostedCallRooms,s,this.userId),t}finally{this._pendingRoomCreations--;for(const e of this._earlyRoomRejects.splice(0))this._handleSignal(e).catch(e=>this.logger.error("Early rejection handling failed:",e))}}async getCallRoom(e){return this.apiClient.get(`/api/v1/webrtc/rooms/${e}`)}async joinCallRoomApi(e){const t={roomId:e,generation:this._callGeneration};this._groupJoin=t;try{const s=await this.apiClient.post(`/api/v1/webrtc/rooms/${e}/join`);return this._groupJoin===t&&this._callGeneration===t.generation&&(this._joinedGroupRoom=e),s}catch(s){throw this._groupJoin===t&&this.currentRoom!==e&&this._clearDeferredGroup(e),s}finally{this._groupJoin===t&&(this._groupJoin=null)}}async leaveCallRoomApi(e){const t=await this.apiClient.post(`/api/v1/webrtc/rooms/${e}/leave`);return this._joinedGroupRoom===e&&(this._joinedGroupRoom=null),this._groupJoin?.roomId===e&&(this._groupJoin=null),this.currentRoom!==e&&this._clearDeferredGroup(e),t}async enableIncomingCalls(){this._incomingCallsEnabled?this.logger.debug("Incoming calls already enabled"):(await this._subscribeToDirectSignaling(),this._incomingCallsEnabled=!0,this.logger.info("Incoming calls enabled - now listening for call invitations"))}disableIncomingCalls(){if(!this._incomingCallsEnabled)return;const e=_.getWebRTCUserDestination();this.connectionManager.unsubscribe(e),this._incomingCallsEnabled=!1,this.logger.info("Incoming calls disabled")}isIncomingCallsEnabled(){return this._incomingCallsEnabled||!1}async startCall(e){const{roomId:t,isGroup:n=!1,mediaConstraints:r={video:!0,audio:!0}}=e;if(this._pendingStart)throw new Error("A call is already starting");if(null!==this.currentRoom||this._callActive||this._waitingForCallAccept)throw new Error("A call is already active");this._callGeneration++,this._cancelGroupRecoveryRetry(),this._groupRecoveryAttempts=0,this._groupRecovery=null;const o={cancelled:!1};this._pendingStart=o;const a=()=>{if(o.cancelled)throw new Error("Call start cancelled")};try{this.currentRoom=t,this.isGroupCall=n;for(const e of new Set(this._deferredGroupPeers.values()))n&&e===t||this._clearDeferredGroup(e);await this._subscribeToSignaling(t,n),a(),await this.initializeIceServers(),a();const e=await this.mediaManager.getUserMedia(r);a(),this.peerManager.setLocalStream(e);for(const e of this._deferredGroupPeers.keys())await this._resumeGroupNegotiation(e),a();return this._callActive=!0,this._sendSignal({type:i.JOIN_ROOM,roomId:t}),this.logger.info(`Call started in room: ${t}`),this.emit("callStarted",{roomId:t,isGroup:n,localStream:e}),e}catch(e){throw n&&this.connectionManager.unsubscribe(_.getWebRTCDestination(t)),this._unsubscribeFromSignaling(),this.mediaManager.stopAll(),this.peerManager.closeAllPeerConnections(),this.peerManager.setLocalStream(null),this.participants.clear(),this._pendingIceCandidates.clear(),this._deferredGroupPeers.clear(),this._callActive=!1,this.currentRoom=null,this.isGroupCall=!1,this._joinedGroupRoom=null,this._groupJoin=null,this.logger.error("Failed to start call:",e),this.emit("error",{type:s.PEER_CONNECTION_FAILED,message:e.message,error:e}),e}finally{this._pendingStart=null}}async callUser(e,t={video:!0,audio:!0}){try{await this.initializeIceServers();const s=await this.mediaManager.getUserMedia(t);this.peerManager.setLocalStream(s),await this._subscribeToDirectSignaling(),this._callActive=!0,this._waitingForCallAccept=!0,this._pendingCallTarget=e,this._incomingCallPeer=null,this._sendSignal({type:i.CALL_REQUEST,receiverId:e}),this.currentRoom=null,this.isGroupCall=!1,this.emit("callRequested",{targetUserId:e,localStream:s})}catch(e){throw this.logger.error("Failed to call user:",e),this._waitingForCallAccept=!1,this._pendingCallTarget=null,e}}async acceptCall(e,t={video:!0,audio:!0}){try{await this.initializeIceServers();const s=await this.mediaManager.getUserMedia(t);this.peerManager.setLocalStream(s),this.peerManager.createPeerConnection(e,!0,{skipAutoNegotiation:!0}),this._directCallPeer=e,this._incomingCallPeer=null,this._sendSignal({type:i.CALL_ACCEPT,receiverId:e}),this._callActive=!0,this.emit("callAccepted",{callerId:e})}catch(e){throw this.logger.error("Failed to accept call:",e),e}}rejectCall(e){this._incomingCallPeer===e&&(this._incomingCallPeer=null),this._sendSignal({type:i.CALL_REJECT,receiverId:e}),this.emit("callRejected",{callerId:e})}cancelCall(){this._waitingForCallAccept&&this._pendingCallTarget&&(this._sendSignal({type:i.CALL_CANCEL,receiverId:this._pendingCallTarget}),this.emit("callCancelled",{targetUserId:this._pendingCallTarget}),this._waitingForCallAccept=!1,this._pendingCallTarget=null,this._callActive=!1,this.mediaManager.stopAll())}endCall(){this._endCall(!0)}_endCall(e){this._callGeneration++,this._cancelGroupRecoveryRetry(),this._groupRecoveryAttempts=0,this._groupRecovery=null,this._callActive=!1,this._deferredGroupPeers.clear(),this._joinedGroupRoom=null,this._groupJoin=null,this._incomingCallPeer=null,this._pendingStart&&(this._pendingStart.cancelled=!0),e&&this._waitingForCallAccept&&this._pendingCallTarget&&this._sendSignal({type:i.CALL_CANCEL,receiverId:this._pendingCallTarget}),this._waitingForCallAccept=!1,this._pendingCallTarget=null,this.currentRoom&&(e&&this._sendSignal({type:i.LEAVE_ROOM,roomId:this.currentRoom}),this._unsubscribeFromSignaling()),e&&this.peerManager.getPeerIds().forEach(e=>{this._sendSignal({type:i.CALL_END,receiverId:e})}),this._directCallPeer=null,this.peerManager.closeAllPeerConnections(),this.peerManager.setLocalStream(null),this.mediaManager.stopAll(),this.participants.clear(),this._pendingIceCandidates.clear();const t=this.currentRoom;this.currentRoom=null,this.isGroupCall=!1,this.emit("callEnded",{roomId:t}),this.logger.info("Call ended")}toggleVideo(){return this.mediaManager.toggleVideo()}toggleAudio(){return this.mediaManager.toggleAudio()}async startScreenShare(){const e=await this.mediaManager.getDisplayMedia(),t=e.getVideoTracks()[0],s=this.mediaManager.getTrack("video");return s&&t&&await this.peerManager.replaceTrack(s,t),t.onended=async()=>{const e=this.mediaManager.getTrack("video");e&&await this.peerManager.replaceTrack(t,e),this.emit("screenShareEnded",{})},e}stopScreenShare(){const e=this.mediaManager.getScreenStream();e&&e.getTracks().forEach(e=>e.stop())}getLocalStream(){return this.mediaManager.getLocalStream()}async getDevices(){return this.mediaManager.getDevices()}async switchDevice(e,t){const s=this.mediaManager.getTrack(t),i=await this.mediaManager.switchDevice(e,t);return s&&await this.peerManager.replaceTrack(s,i),i}setVideoEnabled(e){this.mediaManager.setVideoEnabled(e),this._sendMediaState()}setAudioEnabled(e){this.mediaManager.setAudioEnabled(e),this._sendMediaState()}startDeviceChangeDetection(){this.mediaManager.startDeviceChangeDetection(),this.mediaManager.on("deviceChange",e=>{this.emit("deviceChange",e)})}stopDeviceChangeDetection(){this.mediaManager.stopDeviceChangeDetection()}async applyVideoConstraints(e){return this.mediaManager.applyVideoConstraints(e)}getVideoSettings(){return this.mediaManager.getVideoSettings()}getAudioSettings(){return this.mediaManager.getAudioSettings()}async _subscribeToSignaling(e,t){if(t){const t=_.getWebRTCDestination(e);await this.connectionManager.subscribe(t,e=>{this._handleSignal(e)})}await this._subscribeToDirectSignaling()}async _subscribeToDirectSignaling(){const e=_.getWebRTCUserDestination();await this.connectionManager.subscribe(e,e=>{this._handleSignal(e)})}_unsubscribeFromSignaling(){if(this.currentRoom&&this.isGroupCall){const e=_.getWebRTCDestination(this.currentRoom);this.connectionManager.unsubscribe(e)}if(!this._incomingCallsEnabled){const e=_.getWebRTCUserDestination();this.connectionManager.unsubscribe(e)}}_sendSignal(e){const t={type:e.type,roomId:e.roomId||this._groupRoomFor(e),receiverId:e.receiverId,data:e.data};this.connectionManager.send(_.WEBRTC_SIGNAL,t),this.logger.debug("Signal sent:",t)}_groupRoomFor({type:e,receiverId:t}){if(!(ei.has(e)||t&&t===this._directCallPeer))return this.currentRoom||this._deferredGroupPeers.get(t)}_sendMediaState(){if(!this.currentRoom&&0===this.peerManager.getPeerIds().length)return;const e={videoEnabled:this.mediaManager.isVideoEnabled(),audioEnabled:this.mediaManager.isAudioEnabled()};this._sendSignal({type:i.VIDEO_STATE_CHANGED,data:e}),this.emit("mediaStateChanged",e)}async _handleSignal(e){const{type:t,senderId:s,data:n}=e;if(s!==this.userId&&!this._holdsEarlyRoomReject(e)&&this._acceptsSignal(e))switch(this.logger.debug(`Signal received: ${t} from ${s}`),t){case i.JOIN_ROOM:case i.PEER_JOINED:await this._handleUserJoined(s,e.roomId);break;case i.LEAVE_ROOM:case i.PEER_LEFT:this._handleUserLeft(s);break;case i.CALL_OFFER:await this._handleOffer(s,n.sdp,e.roomId);break;case i.CALL_ANSWER:await this._handleAnswer(s,n.sdp);break;case i.ICE_CANDIDATE:await this._handleIceCandidate(s,n.candidate);break;case i.VIDEO_STATE_CHANGED:case i.AUDIO_STATE_CHANGED:this._handleMediaState(s,n);break;case i.CALL_REQUEST:this.isInCall()||this._waitingForCallAccept?(this._sendSignal({type:i.CALL_BUSY,receiverId:s}),this.emit("incomingCallWhileBusy",{callerId:s})):(this._incomingCallPeer=s,this.emit("incomingCall",{callerId:s}));break;case i.CALL_BUSY:this._waitingForCallAccept=!1,this._pendingCallTarget=null,this._callActive=!1,this.mediaManager.stopAll(),this.emit("callBusy",{userId:s});break;case i.CALL_INVITATION:{const t=n?.callRoomId||e.roomId;e.roomId&&this._rememberCallRoom(this._receivedInvitations,e.roomId,s),this.emit("callInvitation",{callRoomId:t,title:n?.title,hostUserId:n?.hostUserId||s,maxParticipants:n?.maxParticipants,createdAt:n?.createdAt});break}case i.CALL_ACCEPT:await this._handleCallAccepted(s);break;case i.CALL_REJECT:if(e.roomId){this.emit("callRejected",{userId:s,roomId:e.roomId});break}this._waitingForCallAccept=!1,this._pendingCallTarget=null,this._callActive=!1,this.mediaManager.stopAll(),this.emit("callRejected",{userId:s});break;case i.CALL_CANCEL:if(e.roomId){this._receivedInvitations.delete(e.roomId),this.emit("callCancelled",{userId:s,roomId:e.roomId});break}this._incomingCallPeer=null,this._waitingForCallAccept=!1,this._pendingCallTarget=null,this.emit("callCancelled",{userId:s});break;case i.CALL_END:"ROOM"===n?.callEndScope?this._endCall(!1):this._handleCallEnded(s);break;default:this.logger.warn(`Unknown signal type: ${t}`)}}_acceptsSignal({type:e,senderId:t,roomId:s}){if(!t)return!1;if(e===i.CALL_INVITATION)return!0;if(e===i.CALL_REQUEST)return!s;if(s&&e===i.CALL_REJECT)return this._hostedCallRooms.has(s);if(s&&e===i.CALL_CANCEL)return this._receivedInvitations.get(s)===t;if([i.CALL_ACCEPT,i.CALL_BUSY,i.CALL_REJECT].includes(e))return!s&&this._waitingForCallAccept&&t===this._pendingCallTarget;if(e===i.CALL_CANCEL)return!s&&t===this._incomingCallPeer;if(!s&&t===this._directCallPeer)return!0;const n=this.isGroupCall?this.currentRoom:this._callActive||this._waitingForCallAccept?null:this._groupJoin?.roomId||this._joinedGroupRoom;return n?s===n:!s&&t===this._pendingCallTarget}_holdsEarlyRoomReject(e){const{type:t,roomId:s}=e;return!(t!==i.CALL_REJECT||!s||0===this._pendingRoomCreations||this._hostedCallRooms.has(s))&&(this._earlyRoomRejects.push(e),this._earlyRoomRejects.length>32&&this._earlyRoomRejects.shift(),!0)}_rememberCallRoom(e,t,s){e.delete(t),e.set(t,s),e.size>32&&e.delete(e.keys().next().value)}_clearDeferredGroup(e){for(const[t,s]of this._deferredGroupPeers)s===e&&(this.peerManager.closePeerConnection(t),this.participants.delete(t),this._pendingIceCandidates.delete(t),this._deferredGroupPeers.delete(t))}async _handleUserJoined(e,t){this.participants.set(e,{joinedAt:new Date});const s=this.userId<e,i=!!t&&!this.peerManager.localStream;this.peerManager.createPeerConnection(e,s,{skipAutoNegotiation:i}),i&&this._deferredGroupPeers.set(e,t),this.emit("userJoined",{userId:e}),this.logger.info(`User joined: ${e} (I am ${s?"polite":"impolite"})`)}_handleUserLeft(e){this.participants.delete(e),this.peerManager.closePeerConnection(e),this.emit("userLeft",{userId:e}),this.logger.info(`User left: ${e}`)}async _handleOffer(e,t,s=(this.isGroupCall?this.currentRoom:null)){if(!this.peerManager.getPeerConnection(e)){const t=this.userId<e;this.peerManager.createPeerConnection(e,t,{skipAutoNegotiation:!0}),s&&!this.peerManager.localStream&&this._deferredGroupPeers.set(e,s)}await this.peerManager.handleRemoteDescription(e,t),await this._resumeGroupNegotiation(e),await this._processPendingIceCandidates(e)}async _resumeGroupNegotiation(e){this.isGroupCall&&this._deferredGroupPeers.get(e)===this.currentRoom&&this.peerManager.localStream&&await this.peerManager.resumeAutoNegotiation(e)&&this._deferredGroupPeers.delete(e)}async _recoverGroupParticipation(){if(!this.isGroupCall||!this.currentRoom||this._groupRecovery)return;this._cancelGroupRecoveryRetry();const e=this.currentRoom,t=this._callGeneration,s=()=>this.currentRoom===e&&this._callGeneration===t,n=(async()=>{try{const t=await this.apiClient.get(`/api/v1/webrtc/rooms/${e}/participation`);if(!s())return;if(!t.data.participating){if(await this.joinCallRoomApi(e),!s())return;this._sendSignal({type:i.JOIN_ROOM,roomId:e})}this._groupRecoveryAttempts=0}catch(t){if(!s())return;if([403,404,409].includes(t?.status??t?.response?.status))this._endCall(!1),this.emit("callRecoveryFailed",{roomId:e,error:t});else{const e=Math.min(3e4,1e3*2**Math.min(this._groupRecoveryAttempts++,5));this._groupRecoveryTimer=setTimeout(()=>{this._groupRecoveryTimer=null,s()&&this._onReconnected()},e),this._groupRecoveryTimer.unref?.(),this.logger.warn("Call participation recovery will retry:",t)}}})();this._groupRecovery=n;try{await n}finally{this._groupRecovery===n&&(this._groupRecovery=null)}}_cancelGroupRecoveryRetry(){clearTimeout(this._groupRecoveryTimer),this._groupRecoveryTimer=null}async _handleAnswer(e,t){await this.peerManager.handleRemoteDescription(e,t),await this._processPendingIceCandidates(e)}async _handleIceCandidate(e,t){if(!this.peerManager.getPeerConnection(e))return void this._queueIceCandidate(e,t);await this.peerManager.addIceCandidate(e,new RTCIceCandidate(t))||this._queueIceCandidate(e,t)}_queueIceCandidate(e,t){this._pendingIceCandidates.has(e)||this._pendingIceCandidates.set(e,[]),this._pendingIceCandidates.get(e).push(t),this.logger.debug(`ICE candidate queued for ${e}`)}async _processPendingIceCandidates(e){const t=this._pendingIceCandidates.get(e);if(t&&0!==t.length){this.logger.debug(`Processing ${t.length} pending ICE candidates for ${e}`);for(const s of t)await this.peerManager.addIceCandidate(e,new RTCIceCandidate(s));this._pendingIceCandidates.delete(e)}}_handleMediaState(e,t){this.emit("participantMediaState",{userId:e,videoEnabled:t.videoEnabled,audioEnabled:t.audioEnabled})}async _handleCallAccepted(e){this._directCallPeer=e,this._waitingForCallAccept=!1,this._pendingCallTarget=null,this.peerManager.createPeerConnection(e,!1,{skipAutoNegotiation:!0});const t=await this.peerManager.createOffer(e);this._sendSignal({type:i.CALL_OFFER,receiverId:e,data:{sdp:t}}),this.emit("callAccepted",{userId:e})}_handleCallEnded(e){this.peerManager.closePeerConnection(e),this.participants.delete(e),e===this._directCallPeer&&(this._directCallPeer=null),this.emit("participantLeft",{userId:e}),0===this.peerManager.getPeerIds().length&&this.endCall()}isInCall(){return null!==this.currentRoom||this.peerManager.getPeerIds().length>0}getCurrentRoom(){return this.currentRoom}getParticipants(){return Array.from(this.participants.keys())}getConnectionSummary(){return this.peerManager.getConnectionSummary()}async getStats(e){return this.peerManager.getStats(e)}getMediaState(){return{videoEnabled:this.mediaManager.isVideoEnabled(),audioEnabled:this.mediaManager.isAudioEnabled(),streamInfo:this.mediaManager.getStreamInfo()}}setLogLevel(e){this.logger.setLevel(e),this.mediaManager.setLogLevel(e),this.peerManager.setLogLevel(e)}destroy(){this.connectionManager.off?.("reconnected",this._onReconnected),this.endCall(),this.mediaManager.destroy(),this.peerManager.destroy(),this.removeAllListeners(),this.logger.info("WebRTCClient destroyed")}}const si=Object.freeze({UNSUPPORTED_BROWSER:"UNSUPPORTED_BROWSER",FIREBASE_NOT_INSTALLED:"FIREBASE_NOT_INSTALLED",SW_REGISTER_FAILED:"SW_REGISTER_FAILED",PERMISSION_DENIED:"PERMISSION_DENIED",TOKEN_FAILED:"TOKEN_FAILED",SERVER_REGISTER_FAILED:"SERVER_REGISTER_FAILED"});class ii extends Error{constructor(e,t,s){super(t),this.name="PushError",this.code=e,void 0!==s&&(this.cause=s)}}const ni={apiKey:"AIzaSyB8VhRg6rSvUI7K3Ua7h6sBpLvaQGmIkRc",authDomain:"chatting-c3e5d.firebaseapp.com",projectId:"chatting-c3e5d",storageBucket:"chatting-c3e5d.firebasestorage.app",messagingSenderId:"1020496565673",appId:"1:1020496565673:web:5039167257fd83f5ce20b8"},ri="pendingNavigation",oi="pending-room",ai="deviceInfo",ci="device-id",hi="talkflow_device_id";function li(){return"undefined"==typeof indexedDB?Promise.resolve(null):new Promise((e,t)=>{const s=indexedDB.open("talkflowPush",2);s.onupgradeneeded=()=>{const e=s.result;e.objectStoreNames.contains(ri)||e.createObjectStore(ri,{keyPath:"id"}),e.objectStoreNames.contains(ai)||e.createObjectStore(ai,{keyPath:"id"})},s.onsuccess=()=>e(s.result),s.onerror=()=>t(s.error||new Error("IndexedDB open failed"))})}function di(){return li().then(e=>e?new Promise((t,s)=>{const i=e.transaction(ai,"readonly"),n=i.objectStore(ai).get(ci);n.onsuccess=()=>{const e=n.result;t(e&&e.value?e.value:null)},n.onerror=()=>s(n.error||new Error("IndexedDB read failed")),i.oncomplete=()=>e.close(),i.onerror=()=>e.close(),i.onabort=()=>e.close()}):null)}function ui(e){return li().then(t=>!!t&&new Promise(s=>{try{const i=t.transaction(ai,"readwrite");i.objectStore(ai).put({id:ci,value:e}),i.oncomplete=()=>{t.close(),s(!0)},i.onerror=()=>{t.close(),s(!1)},i.onabort=()=>{t.close(),s(!1)}}catch(e){try{t.close()}catch(e){}s(!1)}})).catch(()=>!1)}function pi(){return"web-"+("undefined"!=typeof crypto&&crypto.randomUUID?crypto.randomUUID():Date.now().toString(36)+Math.random().toString(36).substring(2))}async function gi(e){const t=await li();if(!t)return null;const s=function(e){return e&&"string"==typeof e&&""!==e.trim()?"pending-room:"+e:oi}(e),i=!!e&&s!==oi;return new Promise((n,r)=>{const o=t.transaction(ri,"readwrite"),a=o.objectStore(ri);let c=null;const h=a.get(s);h.onsuccess=()=>{const t=h.result;if(t&&t.roomId){if((t.projectId||null)===(e||null))return c=t.roomId,void a.delete(s)}if(!i)return;const n=a.get(oi);n.onsuccess=()=>{const e=n.result;e&&e.roomId&&!e.projectId&&(c=e.roomId,a.delete(oi))}},h.onerror=()=>{r(h.error||new Error("IndexedDB read failed"))},o.oncomplete=()=>{t.close(),n(c)},o.onerror=()=>{t.close(),r(o.error||new Error("IndexedDB transaction failed"))},o.onabort=()=>{t.close(),r(o.error||new Error("IndexedDB transaction aborted"))}})}class mi{constructor(e){this.apiClient=e.apiClient,this.projectId=e.projectId||null,this.firebaseConfig=e.firebaseConfig||ni,this.vapidKey=e.vapidKey||"BGP8qaSm1ntjWd4n9pc0lX_rw4BmMxm9u4pvRIANCitbmYaV0iy-gn05suTKBo88kUBejxdxM8sb6x2nt3avu8c",this.serviceWorkerPath=e.serviceWorkerPath||"/firebase-messaging-sw.js",this.logger=new S(e.logLevel||w.WARN,"PushManager"),this._messaging=null,this._currentToken=null,this._enabled=!1,this._enablePromise=null,this._foregroundMessageUnsubscribe=null,this._swRegistration=null,this._projectRegisteredToSW=!1,this._visibilityHandler=null,this._deviceIdCache=null}static async consumePendingRoom(e){return gi(e)}static async consumePendingMail(e){return async function(e){if(!e||"string"!=typeof e||""===e.trim())return null;const t=await li();if(!t)return null;const s="pending-mail:"+e;return new Promise((i,n)=>{const r=t.transaction(ri,"readwrite"),o=r.objectStore(ri);let a=null;const c=o.get(s);c.onsuccess=()=>{const t=c.result;t&&(o.delete(s),"number"==typeof t.savedAt&&Date.now()-t.savedAt<=6e5&&t.projectId===e&&t.connectionId&&(a={connectionId:t.connectionId,messageId:t.messageId||null}))},c.onerror=()=>{n(c.error||new Error("IndexedDB read failed"))},r.oncomplete=()=>{t.close(),i(a)},r.onerror=()=>{t.close(),n(r.error||new Error("IndexedDB transaction failed"))},r.onabort=()=>{t.close(),n(r.error||new Error("IndexedDB transaction aborted"))}})}(e)}static getPermissionState(){return"undefined"==typeof window||"undefined"==typeof Notification?"unsupported":"undefined"!=typeof navigator&&"serviceWorker"in navigator?Notification.permission:"unsupported"}async enable(){if(this._enabled)this.logger.debug("푸시 알림이 이미 활성화되어 있습니다.");else{if(this._enablePromise)return this.logger.debug("푸시 알림 활성화가 이미 진행 중입니다."),this._enablePromise;this._enablePromise=this._enableInternal();try{return await this._enablePromise}finally{this._enablePromise=null}}}async _enableInternal(){if("undefined"==typeof window||!("Notification"in window))throw new ii(si.UNSUPPORTED_BROWSER,"푸시 알림은 브라우저 환경에서만 사용 가능합니다");if(!("serviceWorker"in navigator))throw new ii(si.UNSUPPORTED_BROWSER,"이 브라우저는 서비스 워커를 지원하지 않습니다");if("denied"===Notification.permission)throw new ii(si.PERMISSION_DENIED,"알림 권한이 이미 거부되어 있습니다. 브라우저 사이트 설정에서 허용해주세요.");let e,t,s;try{e=await import("firebase/app"),t=await import("firebase/messaging")}catch(e){throw new ii(si.FIREBASE_NOT_INSTALLED,"firebase 패키지가 설치되지 않았습니다. npm install firebase 를 실행하세요.",e)}try{s=e.getApp("talkflow")}catch{s=e.initializeApp(this.firebaseConfig,"talkflow")}const i=await this._registerServiceWorker();if("granted"!==("granted"===Notification.permission?"granted":await Notification.requestPermission()))throw new ii(si.PERMISSION_DENIED,"알림 권한이 거부되었습니다. 브라우저 설정에서 허용해주세요.");this._messaging=t.getMessaging(s);const n={serviceWorkerRegistration:i};this.vapidKey&&(n.vapidKey=this.vapidKey);try{this._currentToken=await t.getToken(this._messaging,n)}catch(e){throw new ii(si.TOKEN_FAILED,"FCM 토큰 획득 중 오류 발생: "+(e?.message||e),e)}if(!this._currentToken)throw new ii(si.TOKEN_FAILED,"FCM 토큰 획득 실패 (응답이 비어있음)");await this._registerTokenToServer(this._currentToken),this._foregroundMessageUnsubscribe&&this._foregroundMessageUnsubscribe(),this._foregroundMessageUnsubscribe=t.onMessage(this._messaging,e=>{this.logger.debug("포그라운드 푸시 수신:",e),this._onForegroundMessage(e)}),this._swRegistration=i,await this._registerProjectToSW(),this._installVisibilityReRegister();try{await i.update()}catch(e){this.logger.debug("SW 업데이트 체크 실패 (무시):",e.message)}const r=await this._getSWVersion(i);r?this.logger.debug("SW 버전:",r):this.logger.warn("[TalkFlow] 서비스 워커가 구버전(v1)입니다. 이미지 미리보기 등 리치 알림 기능을 사용하려면 firebase-messaging-sw.js 를 v2 로 업데이트하세요. 가이드: https://docs.talkflow.ai/push/sw-upgrade"),this._enabled=!0,this.logger.info("푸시 알림 활성화 완료")}async _registerServiceWorker(){try{const e=await navigator.serviceWorker.register(this.serviceWorkerPath,{updateViaCache:"none"});return this.logger.debug("서비스 워커 등록 완료:",this.serviceWorkerPath),e}catch(e){throw new ii(si.SW_REGISTER_FAILED,`서비스 워커 등록 실패: ${this.serviceWorkerPath}\n프로젝트 public 폴더에 firebase-messaging-sw.js 파일을 배치하세요.`,e)}}async _registerTokenToServer(e){try{const t=await this._getDeviceId();this.apiClient?.authProvider?.setDeviceId(t),await this.apiClient.post("/api/v1/push/devices",{deviceToken:e,deviceType:"WEB",deviceId:t}),this.logger.info("디바이스 토큰 서버 등록 완료")}catch(e){if(this.logger.error("디바이스 토큰 서버 등록 실패:",e),e instanceof ii)throw e;throw new ii(si.SERVER_REGISTER_FAILED,"디바이스 토큰 서버 등록 실패: "+(e?.message||e),e)}}async _getDeviceId(){if(this._deviceIdCache)return this._deviceIdCache;try{let e=await di();if(!e&&"undefined"!=typeof localStorage){const t=localStorage.getItem(hi);if(t){e=t;if(await ui(e)){if(await di()===e)try{localStorage.removeItem(hi),this.logger.debug("deviceId migrated from localStorage to IndexedDB")}catch(e){}else this.logger.warn("deviceId IDB read-back 불일치, localStorage 보존")}else this.logger.warn("deviceId IDB 저장 실패 (private mode / quota 등), localStorage 보존")}}if(!e){e=pi();await ui(e)||this.logger.warn("신규 deviceId IDB 저장 실패, 이번 세션만 유효")}return this._deviceIdCache=e,this.apiClient?.authProvider?.setDeviceId(e),e}catch(e){if(this.logger.warn("IndexedDB deviceId 조회/저장 실패, fallback:",e),!this._deviceIdCache){let e=null;if("undefined"!=typeof localStorage)try{e=localStorage.getItem(hi)}catch(e){}this._deviceIdCache=e||pi()}return this._deviceIdCache}}_onForegroundMessage(e){}async consumePendingRoom(){return mi.consumePendingRoom(this.projectId)}async consumePendingMail(){return mi.consumePendingMail(this.projectId)}reset(){if(this._foregroundMessageUnsubscribe)try{this._foregroundMessageUnsubscribe()}catch(e){this.logger.debug("포그라운드 푸시 리스너 해제 실패 (무시):",e?.message||e)}this._uninstallVisibilityReRegister(),this._unregisterProjectFromSW(),this._foregroundMessageUnsubscribe=null,this._enablePromise=null,this._messaging=null,this._currentToken=null,this._enabled=!1,this._swRegistration=null,this._projectRegisteredToSW=!1}async _registerProjectToSW(){if(this.projectId)try{const e=(await navigator.serviceWorker.ready).active||this._swRegistration&&this._swRegistration.active;if(!e)return void this.logger.debug("SW active worker 없음 — projectId 등록 스킵");e.postMessage({type:"TALKFLOW_REGISTER_PROJECT",projectId:this.projectId}),this._projectRegisteredToSW=!0}catch(e){this.logger.debug("SW projectId 등록 실패 (무시):",e?.message||e)}}_unregisterProjectFromSW(){if(this._projectRegisteredToSW)try{if("undefined"==typeof navigator||!navigator.serviceWorker)return;const e=navigator.serviceWorker.controller;if(!e)return;e.postMessage({type:"TALKFLOW_UNREGISTER_PROJECT"})}catch(e){this.logger.debug("SW projectId 해제 실패 (무시):",e?.message||e)}}_installVisibilityReRegister(){"undefined"==typeof document||this._visibilityHandler||(this._visibilityHandler=()=>{"visible"===document.visibilityState&&this._enabled&&this.projectId&&this._registerProjectToSW().catch(()=>{})},document.addEventListener("visibilitychange",this._visibilityHandler))}_uninstallVisibilityReRegister(){if("undefined"!=typeof document&&this._visibilityHandler){try{document.removeEventListener("visibilitychange",this._visibilityHandler)}catch(e){}this._visibilityHandler=null}}getToken(){return this._currentToken}isEnabled(){return this._enabled}async getMyDevices(){const e=await this.apiClient.get("/api/v1/push/devices/me");return e&&"object"==typeof e&&"data"in e?e.data:e}async setDeviceEnabled(e,t){await this.apiClient.patch("/api/v1/push/devices/me/enabled",{deviceId:e,enabled:t}),this.logger.info(`디바이스 푸시 enabled=${t}: deviceId=${e}`)}async setCurrentDeviceEnabled(e){const t=await this._getDeviceId();await this.setDeviceEnabled(t,e)}async _getSWVersion(e){try{const t=await navigator.serviceWorker.ready,s=t.waiting||t.installing||t.active||e.waiting||e.installing||e.active;return s?new Promise(e=>{const t=setTimeout(()=>e(null),2e3),i=new MessageChannel;i.port1.onmessage=s=>{clearTimeout(t),e(s.data?.version||null)};try{s.postMessage({type:"TALKFLOW_SW_VERSION"},[i.port2])}catch(s){clearTimeout(t),e(null)}}):null}catch{return null}}setLogLevel(e){this.logger.setLevel(e)}}function _i(e){return e._mailNotificationDeduper||(e._mailNotificationDeduper=function({ttlMs:e=36e5,max:t=1e3,now:s=()=>Date.now()}={}){const i=new Map;return{accept(n){const r=s();for(const[t,s]of i){if(r-s<e)break;i.delete(t)}if(i.has(n))return!1;for(i.set(n,r);i.size>t;)i.delete(i.keys().next().value);return!0},size:()=>i.size}}()),e._mailNotificationDeduper}function fi(e){return e.options&&e.options.projectId||null}function yi(e,t,s){return`${e||""}:${t}:${s}`}function bi(e){return e&&"object"==typeof e?"string"==typeof e.name&&""!==e.name.trim()?e.name:e.email||null:null}const vi=[["connected","connected"],["disconnected","disconnected"],["reconnecting","reconnecting"],["reconnected","reconnected"],["resumed","resumed"],["subscriptionRequired","subscriptionRequired"],["error","connectionError"]],wi=[["syncStarted","syncStarted"],["syncCompleted","syncCompleted"],["gapTruncated","gapTruncated"],["roomListSynced","roomListSynced"],["message","chatMessage"],["newMessage","newChatMessage"],["messageUpdated","messageUpdated"],["messageDeleted","messageDeleted"],["reactionChanged","reactionChanged"],["linkPreviewAttached","linkPreviewAttached"],["messageTranslated","messageTranslated"],["messageRead","messageRead"],["typing","typing"],["assistantProgress","assistantProgress"],["assistantRoomProgress","assistantRoomProgress"],["summaryUpdate","summaryUpdate"],["memberJoined","memberJoined"],["memberLeft","memberLeft"],["roomSubscribed","roomSubscribed"],["roomUnsubscribed","roomUnsubscribed"],["roomListSubscribed","roomListSubscribed"],["roomListUnsubscribed","roomListUnsubscribed"],["roomListUpdate","roomListUpdate"],["roomListMessage","roomListMessage"],["roomListMessageDeleted","roomListMessageDeleted"],["roomListMessageUpdated","roomListMessageUpdated"],["roomListCreated","roomListCreated"],["roomListJoined","roomListJoined"],["roomListLeft","roomListLeft"],["roomListSelfLeft","roomListSelfLeft"],["roomListKicked","roomListKicked"],["roomListSelfKicked","roomListSelfKicked"],["roomListBanned","roomListBanned"],["roomListSelfBanned","roomListSelfBanned"],["roomListOwnerChanged","roomListOwnerChanged"],["roomListDeleted","roomListDeleted"],["roomListRoomUpdated","roomListRoomUpdated"],["roomListUnreadUpdated","roomListUnreadUpdated"],["aiUnavailable","aiUnavailable"],["mailSubscribed","mailSubscribed"],["mailUnsubscribed","mailUnsubscribed"],["mailChanged","mailChanged"],["retentionCleanup","retentionCleanup"]],Si=[["localStreamStarted","localStreamStarted"],["localStreamStopped","localStreamStopped"],["remoteTrack","remoteTrack"],["screenShareStarted","screenShareStarted"],["screenShareEnded","screenShareEnded"],["deviceChange","deviceChange"],["mediaStateChanged","mediaStateChanged"],["callStarted","callStarted"],["callEnded","callEnded"],["callRecoveryFailed","callRecoveryFailed"],["callRequested","callRequested"],["callAccepted","callAccepted"],["callRejected","callRejected"],["callCancelled","callCancelled"],["callBusy","callBusy"],["incomingCall","incomingCall"],["incomingCallWhileBusy","incomingCallWhileBusy"],["callInvitation","callInvitation"],["userJoined","userJoined"],["userLeft","userLeft"],["participantLeft","participantLeft"],["participantMediaState","participantMediaState"],["peerConnected","peerConnected"],["peerDisconnected","peerDisconnected"],["peerClosed","peerClosed"],["error","webrtcError"]];function Ei(e,t,s){s.forEach(([s,i])=>{e.on(s,e=>{t.emit(i,e)})})}function Ii(e){e.connectionManager&&(e.connectionManager.on("stateChange",({state:t,prevState:s})=>{e._state=t,e.emit("stateChange",{state:t,prevState:s})}),Ei(e.connectionManager,e,vi),e.chat&&(Ei(e.chat,e,wi),e.chat.on("mailChanged",t=>function(e,t){if(!t||"MAIL_CHANGED"!==t.eventType||!Array.isArray(t.messages)||!t.connectionId)return;const s=fi(e),i=_i(e);for(const n of t.messages)n&&n.messageId&&i.accept(yi(s,t.connectionId,n.messageId))&&e.emit("newMail",{projectId:s,connectionId:t.connectionId,messageId:n.messageId,threadId:n.threadId||null,sender:bi(n.from),from:n.from||null,subject:n.subject||null,receivedAt:n.receivedAt||null,source:"socket"})}(e,t))),e.webrtc&&Ei(e.webrtc,e,Si))}const Ti=["getRooms","getRoom","getRoomInfo","setMyRoomLanguage","createOneToOneRoom","createGroupRoom","joinGroupRoom","leaveRoom","transferOwnership","deleteRoom","updateGroupRoom","inviteToGroupRoom","kickMember","banMember","unbanMember","getBannedMembers","getAvailableGroupRooms","getAllGroupRooms","enterRoom","getMessages","getFiles","fetchLinkPreview","sendMessage","sendMessageOptimistic","sendTextMessage","sendTextMessageOptimistic","sendReply","sendReplyOptimistic","sendDecisionChoice","uploadFile","sendFileMessage","sendFileMessageOptimistic","classifyFileType","resolveMessageCategory","editMessage","deleteMessage","markAsRead","pinMessage","unpinMessage","toggleReaction","subscribeRoom","unsubscribeRoom","unsubscribeAllRooms","setActiveRoom","clearActiveRoom","getActiveRoom","subscribeRoomList","unsubscribeRoomList","isRoomListSubscribed","subscribeMail","unsubscribeMail","isMailSubscribed","getSubscribedRooms","isSubscribed","startTyping","stopTyping","getAssistantProgress","resumeAssistantStreams","getAssistants","getRoomAiMeta","rateAssistantMessage","summarizeWithAssistant","translateWithAssistant","uploadVideoAsset","analyzeVideo","analyzeVideoWithAssistant","getVideoAnalysis","cancelVideoAnalysis","getVideoAnalysisCapabilities","refreshSummary","getSummary","getRoomPmPrompt","upsertRoomPmPrompt","activateRoomPmPrompt","deactivateRoomPmPrompt","getRoomPmPromptVersions","activateRoomPmPromptVersion","previewRoomPmPrompt","createVote","getVotes","getVote","updateVote","deleteVote","closeVote","submitVote","uploadVoteImage"],Ri=["initializeIceServers","getTurnCredentials","createCallRoom","getCallRoom","joinCallRoomApi","leaveCallRoomApi","enableIncomingCalls","disableIncomingCalls","isIncomingCallsEnabled","startCall","callUser","acceptCall","rejectCall","cancelCall","endCall","toggleVideo","toggleAudio","setVideoEnabled","setAudioEnabled","startScreenShare","stopScreenShare","getLocalStream","getDevices","switchDevice","startDeviceChangeDetection","stopDeviceChangeDetection","applyVideoConstraints","getVideoSettings","getAudioSettings","isInCall","getCurrentRoom","getParticipants","getMediaState","getConnectionSummary","getStats"];function Ci(e,t,s){s.forEach(s=>{e[s]=function(...e){return this[t][s](...e)}})}class Ai extends e{constructor(e){super(),this._validateOptions(e);const s=e.env||b.environment,i=(e.serverUrl||v(s)).replace(/\/$/,"");this.options={serverUrl:i,env:s,apiKey:e.apiKey,projectId:e.projectId,jwtToken:e.jwtToken||null,sessionMode:e.sessionMode||(C(e.jwtToken||"").sid?"refresh":"legacy"),useSockJS:!1!==e.useSockJS,reconnectDelay:e.reconnectDelay||b.reconnectDelay,maxReconnectDelay:e.maxReconnectDelay||b.maxReconnectDelay,maxReconnectAttempts:e.maxReconnectAttempts||b.maxReconnectAttempts,reconnectRecoveryDelay:e.reconnectRecoveryDelay??b.reconnectRecoveryDelay,heartbeatIncoming:e.heartbeatIncoming||b.heartbeatIncoming,heartbeatOutgoing:e.heartbeatOutgoing||b.heartbeatOutgoing,resumeOnVisibility:!1!==e.resumeOnVisibility,syncOnReconnect:!1!==e.syncOnReconnect,assistantStreamReplay:!1!==e.assistantStreamReplay,rewindMillis:void 0!==e.rewindMillis?e.rewindMillis:b.rewindMillis,maxSyncPages:e.maxSyncPages||b.maxSyncPages,syncPageSize:e.syncPageSize||b.syncPageSize,iceServers:e.iceServers||b.iceServers,autoSubscribeRoomList:!1!==e.autoSubscribeRoomList,logLevel:void 0!==e.logLevel?e.logLevel:w.WARN},this.logger=new S(this.options.logLevel,"TalkFlowClient"),this._initialized=!1,this._state=t.DISCONNECTED,this._userId=null,this.options.jwtToken&&(this._userId=O(this.options.jwtToken)),this.apiClient=new E({baseUrl:this.options.serverUrl,apiKey:this.options.apiKey,projectId:this.options.projectId,jwtToken:this.options.jwtToken,logLevel:this.options.logLevel}),this.authSession=null,this._authConnectionRequested=!1,this.connectionManager=null,this._chat=null,this._webrtc=null,this._pushManager=null,this._pushEnablePromise=null,this.options.jwtToken&&this._userId&&this._initializeSubClients(),this._initialized=!0,"refresh"===this.options.sessionMode&&this._enableRefreshSession(),this.logger.info("TalkFlowClient initialized",{userId:this._userId,hasToken:!!this.options.jwtToken})}get chat(){return this._chat}get webrtc(){return this._webrtc}get pushManager(){return this._pushManager}get userId(){return this._userId}_validateOptions(e){if(!e)throw new Error("Options are required");if(!e.apiKey&&"refresh"!==e.sessionMode)throw new Error("apiKey is required");if(!e.projectId&&"refresh"!==e.sessionMode)throw new Error("projectId is required");e.apiKey?.startsWith("sk-")&&console.error("🚨 [TalkFlow] Server Key (sk-) 로 SDK 를 초기화했습니다. SDK 는 Client Key (ck-) 만 사용합니다 — loginUser() 응답의 clientKey 를 그대로 쓰세요.")}_initializeSubClients(){!function(e){if(!e.connectionManager){if(!e.userId)throw new Error("userId is required to initialize sub-clients. Please set JWT token first.");e.connectionManager=new Ks({serverUrl:e.options.serverUrl,jwtToken:e.options.jwtToken,apiKey:e.options.apiKey,projectId:e.options.projectId,useSockJS:e.options.useSockJS,reconnectDelay:e.options.reconnectDelay,maxReconnectDelay:e.options.maxReconnectDelay,maxReconnectAttempts:e.options.maxReconnectAttempts,reconnectRecoveryDelay:e.options.reconnectRecoveryDelay,heartbeatIncoming:e.options.heartbeatIncoming,heartbeatOutgoing:e.options.heartbeatOutgoing,resumeOnVisibility:e.options.resumeOnVisibility,logLevel:e.options.logLevel}),e.connectionManager.getAccessToken=async({forceRefresh:t=!1}={})=>e.authSession?e.authSession.getAccessToken({forceRefresh:t,rejectedToken:e.connectionManager?.jwtToken}):e.options.jwtToken,e.connectionManager.canRefreshToken=()=>!!e.authSession,e._chat=new Ys({connectionManager:e.connectionManager,apiClient:e.apiClient,userId:e._userId,syncOnReconnect:e.options.syncOnReconnect,assistantStreamReplay:e.options.assistantStreamReplay,rewindMillis:e.options.rewindMillis,maxSyncPages:e.options.maxSyncPages,syncPageSize:e.options.syncPageSize,logLevel:e.options.logLevel}),e._webrtc=new ti({connectionManager:e.connectionManager,apiClient:e.apiClient,userId:e._userId,iceServers:e.options.iceServers,logLevel:e.options.logLevel}),e._setupEventForwarding(),e.logger.debug("Sub-clients initialized")}}(this)}_setupEventForwarding(){Ii(this)}isConnected(){return!!this.connectionManager&&this.connectionManager.isConnected()}isSubscriptionRequired(){return!!this.connectionManager&&this.connectionManager.isSubscriptionRequired()}_enableRefreshSession(){this.authSession||(this.options.sessionMode="refresh",this.authSession=A.forServer(this.options.serverUrl),this.authSession.attach(this),this.apiClient.authProvider=this.authSession,this._authUnsubscribe=this.authSession.on("authStateChanged",e=>this.emit("authStateChanged",e)),this._authErrorUnsubscribe=this.authSession.on("authError",e=>this.emit("authError",e)),!this.authSession.data&&this.options.jwtToken&&C(this.options.jwtToken).sid&&(this.authSession.data={accessToken:this.options.jwtToken,projectId:this.options.projectId,clientKey:this.options.apiKey,user:{userId:this.userId}},this.authSession._setState("authenticated")),this._authReady=Promise.resolve(),this.authSession.data&&(this._authReady=this._acceptAuthSession(this.authSession.data).catch(e=>{throw this._authReady=Promise.resolve(),e})))}async _acceptAuthSession(e){this.options.projectId&&this.options.projectId!==e.projectId&&this.connectionManager&&await this._clearAuthSession(),this.options.apiKey=e.clientKey,this.options.projectId=e.projectId,this.apiClient.apiKey=e.clientKey,this.apiClient.projectId=e.projectId,await this.setToken(e.accessToken)}async _clearAuthSession(){this._authConnectionRequested=!1,this.options.jwtToken=null,this._userId=null,this.apiClient.setJwtToken(null),await this.disconnect(),this._chat?.destroy(),this._webrtc?.destroy(),await(this.connectionManager?.destroy()),this._chat=null,this._webrtc=null,this.connectionManager=null,this.pushManager?.reset(),this._pushManager=null,this._pushEnablePromise=null,this.emit("loggedOut")}getAuthState(){return this.authSession?.getAuthState()||(1e3*Number(C(this.options.jwtToken||"").exp||0)>Date.now()?"authenticated":"unauthenticated")}isLoggedIn(){return"authenticated"===this.getAuthState()}async getAccessToken(e={}){if(this.authSession)return await this._authReady,this.authSession.getAccessToken(e);if(!this.isLoggedIn()){const e=new Error("Sign in is required");throw e.code="SESSION_REVOKED",e}return this.options.jwtToken}async restoreSession(){return this._enableRefreshSession(),await this._authReady,this.authSession.restoreSession()}static async restoreSession({serverUrl:e}){if(!e)throw new Error("serverUrl is required");return A.forServer(e).restoreSession()}async request(e,t,s={}){if(!t.startsWith("/")||t.startsWith("//"))throw new Error("Use an API-relative path");return await this._authReady,this.apiClient.request(e,t,s)}getState(){return this._state}hasToken(){return!!this.options.jwtToken}static async loginUser({serverUrl:e,email:t,password:s,projectId:i}){if(!e)throw new Error("serverUrl is required");if(!t)throw new Error("email is required");if(!s)throw new Error("password is required");return A.forServer(e).login({email:t,password:s,projectId:i})}async loginUser({email:e,password:t,projectId:s}){if(!e||!t)throw new Error("email and password are required");return this._enableRefreshSession(),await this._authReady,this.authSession.login({email:e,password:t,projectId:s})}async getMyProfile(){this._checkToken();const e=await this.apiClient.get("/api/v1/me");return e&&e.data?e.data:e}async updateMyProfile(e){this._checkToken();const t=await this.apiClient.put("/api/v1/me",e),s=t&&t.data?t.data:t;if(s&&s.accessToken)try{await this.setToken(s.accessToken)}catch(e){this.logger.warn("Profile updated but token refresh failed; keeping the old token",e)}return s}async changeMyPassword({currentPassword:e,newPassword:t}){if(this._checkToken(),this.authSession)return this.authSession.changePassword(()=>this.apiClient.request("PUT","/api/v1/me/password",{body:{currentPassword:e,newPassword:t},skipAuth:!0}));const s=await this.apiClient.put("/api/v1/me/password",{currentPassword:e,newPassword:t}),i=s?.data??s;return i?.accessToken&&i?.refreshToken&&(this._enableRefreshSession(),this.authSession._newMarker(!1),await this.authSession._accept(i)),s}async setPreferredLanguage(e){return this.updateMyProfile({preferredLanguage:e})}static detectBrowserLanguage(){return"undefined"!=typeof navigator&&navigator.language?Ai.normalizeLanguageCode(navigator.language):null}static normalizeLanguageCode(e){if(!e||"string"!=typeof e)return null;const t=e.trim();if(!t)return null;if("OFF"===t.toUpperCase())return"OFF";const s=t.toLowerCase(),i=s.indexOf("-");if(i<0)return s;const n=s.slice(0,i);return"zh"===n?s:n}static displayText(e,t){const s=Ai.normalizeLanguageCode(t);return e&&e.translations&&s&&e.translations[s]?e.translations[s]:e?e.content:null}async getCompanyDirectory(){return this._checkToken(),this.apiClient.get("/api/v1/company/directory")}async getUsers(e={}){this._checkToken();const{size:t=50,lastId:s,lastSortValue:i}=e;return this.apiClient.get("/api/v1/users",{size:t,lastId:s,lastSortValue:i})}async searchUsers(e){this._checkToken();const{keyword:t,limit:s=20}=e;return this.apiClient.get("/api/v1/users/search",{keyword:t,limit:s})}_checkToken(){if(!this.options.jwtToken)throw new Error('JWT token is required for this operation. Sign in with TalkFlowClient.loginUser({ serverUrl, email, password }) and pass the returned accessToken via setToken(). See README "로그인".')}getUserId(){return this.userId}isInitialized(){return this._initialized}isReady(){return this._initialized&&!!this.connectionManager}setLogLevel(e){this.options.logLevel=e,this.logger.setLevel(e),this.apiClient.logger?.setLevel(e),this.connectionManager&&this.connectionManager.setLogLevel(e),this.chat&&this.chat.setLogLevel(e),this.webrtc&&this.webrtc.setLogLevel(e)}getStatus(){return{initialized:this._initialized,ready:this.isReady(),hasToken:this.hasToken(),connectionState:this._state,isConnected:this.isConnected(),userId:this.userId,chat:this.chat?{subscribedRooms:this.chat.getSubscribedRooms()}:null,webrtc:this.webrtc?{isInCall:this.webrtc.isInCall(),currentRoom:this.webrtc.getCurrentRoom(),participants:this.webrtc.getParticipants(),mediaState:this.webrtc.getMediaState()}:null}}async destroy(){await this.disconnect(),this._authUnsubscribe?.(),this._authErrorUnsubscribe?.(),this.authSession?.detach(this),this.chat&&this.chat.destroy(),this.webrtc&&this.webrtc.destroy(),this.connectionManager&&await this.connectionManager.destroy(),this.removeAllListeners(),this._initialized=!1,this.logger.info("TalkFlowClient destroyed")}}Ai.ConnectionState=t,Ai.ErrorTypes=s,Ai.LogLevel=w,Ai.Environment=f,function(e){e.prototype.connect=async function(e,t={}){const{enablePush:s=!1}=t;if(e&&await this.setToken(e),this.authSession){await this._authReady,this._authConnectionRequested=!0;const e=await this.authSession.getAccessToken();await this.setToken(e),this.authSession.schedule()}if(!this.options.jwtToken)throw new Error('JWT token is required. Sign in with TalkFlowClient.loginUser({ serverUrl, email, password }) and pass the returned accessToken to the SDK via the jwtToken option, setToken(), or connect(jwt). See README "로그인".');if(!this.authSession&&L(this.options.jwtToken))throw new Error("JWT token has expired. Please update the token before connecting.");if(this.connectionManager||this._initializeSubClients(),await this.connectionManager.connect(),this.webrtc&&await this.webrtc.enableIncomingCalls(),this.chat&&this.options.autoSubscribeRoomList)try{await this.chat.subscribeRoomList()}catch(e){this.logger.warn("Failed to auto-subscribe room list (non-fatal):",e)}s&&this.enablePushNotifications(),this.logger.info("Connected to server")},e.prototype.disconnect=async function(){this._authConnectionRequested=!1,this.authSession?.schedule(),this.connectionManager&&(this.webrtc&&this.webrtc.isInCall()&&this.webrtc.endCall(),this.webrtc&&this.webrtc.disableIncomingCalls(),this.chat&&(this.chat.unsubscribeAllRooms(),this.chat.unsubscribeRoomList(),this.chat.unsubscribeMail()),await this.connectionManager.disconnect(),this.logger.info("Disconnected from server"))},e.prototype.logout=async function(){if(this.authSession)return this.authSession.logout();try{await this.apiClient.post("/v1/auth/signout"),this.logger.info("Logged out from server")}catch(e){this.logger.warn("Server logout failed (proceeding with local cleanup):",e.message)}await this.disconnect(),this.pushManager&&(this.pushManager.reset(),this._pushEnablePromise=null),this.options.jwtToken=null,this._userId=null,this.apiClient.setJwtToken(null),this.emit("loggedOut")},e.prototype.enablePushNotifications=async function(e={}){if(!this.options.jwtToken){const e=new Error("JWT token is required to enable push notifications.");return this.emit("pushFailed",{reason:"NO_TOKEN",error:e}),{ok:!1,reason:"NO_TOKEN",error:e}}if(!this.pushManager){this._pushManager=new mi({apiClient:this.apiClient,projectId:this.options.projectId,firebaseConfig:e.firebaseConfig,vapidKey:e.vapidKey,serviceWorkerPath:e.serviceWorkerPath,logLevel:this.options.logLevel});const t=3e5;this.pushManager._onForegroundMessage=e=>{const s=e.data||{};if(s.projectId&&s.projectId!==this.options.projectId)return void this.logger.debug("다른 프로젝트 푸시 무시:",s.projectId);if(function(e,t){const s=t&&t.data||{};if("MAIL"!==s.target)return!1;const i=fi(e);if(!s.connectionId)return!0;if("SUMMARY"===s.kind){const t="string"==typeof s.messageIds?s.messageIds.split(",").map(e=>e.trim()).filter(Boolean):[];if(0===t.length){const t=Number.parseInt(s.count,10);return e.emit("newMailSummary",{projectId:i,connectionId:s.connectionId,count:Number.isFinite(t)?t:null,messageIds:[],source:"push"}),!0}const n=_i(e),r=t.filter(e=>n.accept(yi(i,s.connectionId,e)));return r.length>0&&e.emit("newMailSummary",{projectId:i,connectionId:s.connectionId,count:r.length,messageIds:r,source:"push"}),!0}return!s.messageId||!_i(e).accept(yi(i,s.connectionId,s.messageId))||(e.emit("newMail",{projectId:i,connectionId:s.connectionId,messageId:s.messageId,threadId:s.threadId||null,sender:t.notification&&t.notification.title||s.title||null,from:null,subject:t.notification&&t.notification.body||s.body||null,receivedAt:null,source:"push"}),!0)}(this,e))return;const i=this.chat?.getActiveRoom();if(i&&i===s.roomId)this.logger.debug("포그라운드 푸시 suppress (현재 방):",s.roomId);else{if(s.messageId){if(this._recentPushMessageIds||(this._recentPushMessageIds=new Map),this._recentPushMessageIds.has(s.messageId))return void this.logger.debug("포그라운드 푸시 dedup:",s.messageId);const e=setTimeout(()=>{this._recentPushMessageIds.delete(s.messageId)},t);this._recentPushMessageIds.set(s.messageId,e)}this.emit("pushNotification",{title:e.notification?.title||s.title,body:e.notification?.body||s.body,data:s})}}}if(this.pushManager.isEnabled())return this.logger.debug("웹 푸시가 이미 활성화되어 있어 중복 호출을 건너뜁니다."),{ok:!0,alreadyEnabled:!0};if(this._pushEnablePromise)return this.logger.debug("웹 푸시 활성화가 이미 진행 중입니다."),this._pushEnablePromise;const t=(async()=>{try{return await this.pushManager.enable(),this.emit("pushEnabled"),{ok:!0}}catch(e){const t=e&&e.code?e.code:"UNKNOWN";return this.logger.warn("Failed to enable push notifications:",t,e?.message),this.emit("pushFailed",{reason:t,error:e}),{ok:!1,reason:t,error:e}}})();return this._pushEnablePromise=t,t.finally(()=>{this._pushEnablePromise===t&&(this._pushEnablePromise=null)}),t},e.prototype.consumePendingRoom=async function(){return mi.consumePendingRoom(this.options.projectId)},e.prototype.consumePendingMail=async function(){return mi.consumePendingMail(this.options.projectId)},e.prototype.setCurrentDeviceEnabled=function(e){return this.pushManager?.setCurrentDeviceEnabled(e)},e.prototype.setDeviceEnabled=function(e,t){return this.pushManager?.setDeviceEnabled(e,t)},e.prototype.getMyDevices=function(){return this.pushManager?.getMyDevices()},e.prototype.getPushPermissionState=function(){return mi.getPermissionState()},e.prototype.isPushEnabled=function(){return this.pushManager?.isEnabled()??!1},e.prototype.getPushToken=function(){return this.pushManager?.getToken()??null},e.prototype.resetPush=function(){this.pushManager?.reset(),this._pushEnablePromise=null},e.prototype.setToken=async function(e){const{userId:t}=N(e,{validateExpiry:!1}),s=this.userId&&this.userId!==t;this.options.jwtToken=e,this._userId=t,this.apiClient.setJwtToken(e),s&&this.connectionManager?(await this.disconnect(),this._chat?.destroy(),this._webrtc?.destroy(),await this.connectionManager.destroy(),this.pushManager&&(this.pushManager.reset(),this._pushEnablePromise=null,this._pushManager=null),this.connectionManager=null,this._chat=null,this._webrtc=null,this._initializeSubClients()):this.connectionManager?this.connectionManager.updateToken(e):this._initializeSubClients(),this.logger.info("JWT token set",{userId:t}),this.authSession?.replaceAccessToken(e),this.emit("tokenSet",{userId:t})},e.prototype.updateToken=async function(e){await this.setToken(e)}}(Ai),function(e){Ci(e.prototype,"chat",Ti),Ci(e.prototype,"webrtc",Ri)}(Ai);class ki{constructor(e){this._currentUserId=e,this._rooms=new Map}_room(e){let t=this._rooms.get(e);return t||(t={snapshotCount:null,snapshotVersion:null,pendingDeltas:new Map},this._rooms.set(e,t)),t}applyMessageReceived(e){if(!e||!e.roomId||!e.messageId)return;if(null!=e.actorId&&e.actorId===this._currentUserId)return;const t=this._room(e.roomId);if(t.pendingDeltas.has(e.messageId))return;const s=null==e.unreadVersion?null:e.unreadVersion;null!=t.snapshotVersion&&null!=s&&s<=t.snapshotVersion||t.pendingDeltas.set(e.messageId,{version:s,delta:1})}applySnapshot(e,t,s){if(!e||null==t)return;const i=null==s?null:s,n=this._room(e);if(!(null!=n.snapshotVersion&&null==i||null!=n.snapshotVersion&&null!=i&&i<n.snapshotVersion||(n.snapshotCount=t,null!=i&&(n.snapshotVersion=i),null==i)))for(const[e,t]of n.pendingDeltas)(null==t.version||t.version<=i)&&n.pendingDeltas.delete(e)}getCount(e){const t=this._rooms.get(e);if(!t||null==t.snapshotCount)return null;let s=t.snapshotCount;for(const e of t.pendingDeltas.values())s+=e.delta;return s}removeRoom(e){this._rooms.delete(e)}clear(){this._rooms.clear()}}export{l as AssistantMode,Ys as ChatClient,n as ChatMessageType,h as ChatRoomType,Ks as ConnectionManager,t as ConnectionState,r as DecisionCardLimits,b as DefaultConfig,y as Endpoints,u as EngagementIntensity,f as Environment,s as ErrorTypes,e as EventEmitter,w as LogLevel,S as Logger,Qs as MediaStreamManager,Zs as PeerConnectionManager,a as PersonaRole,g as PmPromptLayerEditorType,p as PmPromptLayerScope,ii as PushError,si as PushErrorCode,mi as PushManager,d as RoomAiType,m as RoomListEventType,ki as RoomUnreadReconciler,o as SenderType,i as SignalTypes,c as SummarizeFormat,ti as WebRTCClient,_ as WebSocketPaths,P as decodeJWTPayload,Ai as default,O as extractUserIdFromJWT,D as getJWTRemainingTime,v as getServerUrl,L as isJWTExpired,N as validateAndParseJWT};
2
2
  //# sourceMappingURL=talkflow-sdk.esm.js.map