@vibexnpm/talkx 6.1.0 → 7.0.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=(...n)=>{this.off(e,s),t.apply(this,n)};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",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"},n={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"},i={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"},l={DIRECT:"DIRECT",GROUP:"GROUP",PRIVATE_GROUP:"PRIVATE_GROUP",TEAM:"TEAM"},h={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",MESSAGE_RETENTION_CLEANUP:"MESSAGE_RETENTION_CLEANUP",ROOM_UNREAD_UPDATED:"ROOM_UNREAD_UPDATED"},f={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",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"},_={DEVELOPMENT:"development",STAGING:"staging",PRODUCTION:"production"},b={[_.DEVELOPMENT]:{serverUrl:"https://dev-chat.apiorbit.net",wsEndpoint:"/ws-chat"},[_.STAGING]:{serverUrl:"https://stg-api.talk-x.app",wsEndpoint:"/ws-chat"},[_.PRODUCTION]:{serverUrl:"https://prod-api.talk-x.app",wsEndpoint:"/ws-chat"}},y={environment:_.PRODUCTION,reconnectDelay:5e3,maxReconnectDelay:3e4,maxReconnectAttempts:10,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(b[e]||b[_.PRODUCTION]).serverUrl}const E={DEBUG:0,INFO:1,WARN:2,ERROR:3,NONE:4};class S{constructor(e=E.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<=E.DEBUG&&console.debug(...this._format("DEBUG",...e))}info(...e){this.level<=E.INFO&&console.info(...this._format("INFO",...e))}warn(...e){this.level<=E.WARN&&console.warn(...this._format("WARN",...e))}error(...e){this.level<=E.ERROR&&console.error(...this._format("ERROR",...e))}}class w{constructor(e){this.baseUrl=e.baseUrl.replace(/\/$/,""),this.apiKey=e.apiKey,this.projectId=e.projectId,this.jwtToken=e.jwtToken,this.timeout=e.timeout||y.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,n={}){const{body:i,params:r,headers:o}=n;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,l=setTimeout(()=>c.abort(),this.timeout);let h;try{this.logger.debug(`${e} ${a}`,i?{body:i}:""),h=await fetch(a,{method:e,headers:o?{...this._getHeaders(),...o}:this._getHeaders(),body:i?JSON.stringify(i):void 0,signal:c.signal})}catch(t){if(clearTimeout(l),"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(l);const d=h.headers.get("content-type");let u;if(u=d&&d.includes("application/json")?await h.json():await h.text(),!h.ok){const t=new Error(u?.message||`HTTP ${h.status}`);throw t.code=s.API_ERROR,t.status=h.status,t.response=u,this.logger.error(`API Error: ${e} ${a}`,t),t}return this.logger.debug(`Response ${h.status}:`,u),u}get(e,t){return this.request("GET",e,{params:t})}post(e,t,s,n){return this.request("POST",e,{body:t,params:s,headers:n})}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})}upload(e,t,n={}){const{fieldName:i="file",onProgress:r,signal:o,timeout:a=6e5}=n;return new Promise((n,c)=>{const l=`${this.baseUrl}${e}`,h=new XMLHttpRequest,d=new FormData;d.append(i,t),h.open("POST",l),h.timeout=a,h.setRequestHeader("X-API-KEY",this.apiKey),h.setRequestHeader("X-PROJECT-ID",this.projectId),this.jwtToken&&h.setRequestHeader("Authorization",this.jwtToken.startsWith("Bearer ")?this.jwtToken:`Bearer ${this.jwtToken}`),"function"==typeof r&&(h.upload.onprogress=e=>{e.lengthComputable&&r({loaded:e.loaded,total:e.total,percent:Math.round(e.loaded/e.total*100)})});const u=()=>h.abort();if(o){if(o.aborted)return void c(new Error("Upload cancelled"));o.addEventListener("abort",u)}const p=()=>{o&&o.removeEventListener("abort",u)};h.onload=()=>{p();let e=h.responseText;if((h.getResponseHeader("content-type")||"").includes("application/json"))try{e=JSON.parse(h.responseText)}catch{}if(h.status>=200&&h.status<300)this.logger.debug(`Upload ${h.status}:`,e),n(e);else{const t=new Error(e?.message||`HTTP ${h.status}`);t.code=s.API_ERROR,t.status=h.status,t.response=e,this.logger.error(`Upload Error: POST ${l}`,t),c(t)}},h.onerror=()=>{p();const e=new Error("Network error during upload");e.code=s.API_ERROR,this.logger.error(`Upload Network Error: POST ${l}`,e),c(e)},h.ontimeout=()=>{p();const e=new Error("Upload timeout");e.code=s.API_TIMEOUT,this.logger.error(`Upload Timeout: POST ${l}`,e),c(e)},h.onabort=()=>{p(),c(new Error("Upload cancelled"))},this.logger.debug(`POST ${l} (multipart, ${t.size} bytes)`),h.send(d)})}}function I(e){return e&&"string"==typeof e?e.replace(/^Bearer\s+/i,""):""}function T(e){let t=e.replace(/-/g,"+").replace(/_/g,"/");const s=t.length%4;s&&(t+="=".repeat(4-s));const n=atob(t),i=Uint8Array.from(n,e=>e.charCodeAt(0));return(new TextDecoder).decode(i)}function C(e,t={}){const{bufferSeconds:n=30,validateExpiry:i=!0}=t;if(!e||"string"!=typeof e){const e=new Error("JWT token is required");throw e.code=s.JWT_INVALID,e}const r=I(e).split(".");if(3!==r.length){const e=new Error("Invalid JWT format: expected 3 parts separated by dots");throw e.code=s.JWT_INVALID,e}let o;try{o=JSON.parse(T(r[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(i&&o.exp){const e=1e3*o.exp,t=1e3*n,i=Date.now();if(e<i+t){const t=new Error(e<i?"JWT token expired":`JWT token expires within ${n} seconds`);throw t.code=s.JWT_EXPIRED,t.expiredAt=new Date(e).toISOString(),t}}if(o.iat){const e=6e4;if(1e3*o.iat>Date.now()+e){const e=new Error("JWT token issued in the future");throw e.code=s.JWT_INVALID,e}}const a=o.userId||o.sub||o.user_id;if(!a){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:a,payload:o}}function A(e){try{const t=I(e).split(".");if(3!==t.length)return null;const s=JSON.parse(T(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 R(e,t=0){try{const s=I(e).split(".");if(3!==s.length)return!0;const n=JSON.parse(T(s[1]));if(!n.exp)return!1;const i=1e3*n.exp,r=1e3*t;return i<Date.now()+r}catch(e){return console.error("Failed to check JWT expiration:",e),!0}}function M(e){try{const t=I(e).split(".");if(3!==t.length)return-1;const s=JSON.parse(T(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 O(e){try{const t=I(e).split(".");return 3!==t.length?null:JSON.parse(T(t[1]))}catch(e){return console.error("Failed to decode JWT payload:",e),null}}const N="\n",k="\0";class L{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:n,binaryBody:i,escapeHeaderValues:r,skipContentLengthHeader:o}=e;this.command=t,this.headers=Object.assign({},s||{}),i?(this._binaryBody=i,this.isBinaryBody=!0):(this._body=n||"",this.isBinaryBody=!1),this.escapeHeaderValues=r||!1,this.skipContentLengthHeader=o||!1}static fromRawFrame(e,t){const s={},n=e=>e.replace(/^\s+|\s+$/g,"");for(const i of e.headers.reverse()){i.indexOf(":");const r=n(i[0]);let o=n(i[1]);t&&"CONNECT"!==e.command&&"CONNECTED"!==e.command&&(o=L.hdrValueUnEscape(o)),s[r]=o}return new L({command:e.command,headers:s,binaryBody:e.binaryBody,escapeHeaderValues:t})}toString(){return this.serializeCmdAndHeaders()}serialize(){const e=this.serializeCmdAndHeaders();return this.isBinaryBody?L.toUnit8Array(e,this._binaryBody).buffer:e+this._body+k}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}:${L.hdrValueEscape(`${s}`)}`):e.push(`${t}:${s}`)}return(this.isBinaryBody||!this.isBodyEmpty()&&!this.skipContentLengthHeader)&&e.push(`content-length:${this.bodyLength()}`),e.join(N)+N+N}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),n=new Uint8Array([0]),i=new Uint8Array(s.length+t.length+n.length);return i.set(s),i.set(t,s.length),i.set(n,s.length+t.length),i}static marshall(e){return new L(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 D{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 P,x,U,$;!function(e){e[e.CONNECTING=0]="CONNECTING",e[e.OPEN=1]="OPEN",e[e.CLOSING=2]="CLOSING",e[e.CLOSED=3]="CLOSED"}(P||(P={})),function(e){e[e.ACTIVE=0]="ACTIVE",e[e.DEACTIVATING=1]="DEACTIVATING",e[e.INACTIVE=2]="INACTIVE"}(x||(x={})),function(e){e[e.LINEAR=0]="LINEAR",e[e.EXPONENTIAL=1]="EXPONENTIAL"}(U||(U={})),function(e){e.Interval="interval",e.Worker="worker"}($||($={}));class W{constructor(e,t=$.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===$.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 F{constructor(e){this.versions=e}supportedVersions(){return this.versions.join(",")}protocolVersions(){return this.versions.map(e=>`v${e.replace(".","")}.stomp`)}}F.V1_0="1.0",F.V1_1="1.1",F.V1_2="1.2",F.default=new F([F.V1_2,F.V1_1,F.V1_0]);class j{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===F.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,n=e,i=this,r=this._connectedVersion===F.V1_2?n.headers.ack:n.headers["message-id"];n.ack=(e={})=>i.ack(r,t,e),n.nack=(e={})=>i.nack(r,t,e),s(n)},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 D(e=>{const t=L.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!==F.V1_1&&e.version!==F.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 W(e,this._client.heartbeatStrategy,this.debug),this._pinger.start(()=>{this._webSocket.readyState===P.OPEN&&(this._webSocket.send(N),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!==P.CONNECTING&&this._webSocket.readyState!==P.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 n=new Date,i=Math.random().toString().substring(2,8),r=this.onclose;this.onclose=e=>{const s=(new Date).getTime()-n.getTime();t(`Discarded socket (#${i}) closed after ${s}ms, with code/reason: ${e.code}/${e.reason}`)},this.close(),r?.call(e,{code:4001,reason:`Quick discarding socket (#${i}) without waiting for the shutdown sequence.`,wasClean:!1})}),this._webSocket.terminate()}_transmit(e){const{command:t,headers:s,body:n,binaryBody:i,skipContentLengthHeader:r}=e,o=new L({command:t,headers:s,body:n,binaryBody:i,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!==P.CONNECTING&&this._webSocket.readyState!==P.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:n,binaryBody:i,skipContentLengthHeader:r}=e,o=Object.assign({destination:t},s);this._transmit({command:"SEND",headers:o,body:n,binaryBody:i,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 n=this;return{id:s.id,unsubscribe:e=>n.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===F.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===F.V1_2?s.id=e:s["message-id"]=e,s.subscription=t,this._transmit({command:"NACK",headers:s})}}class V{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===x.ACTIVE}_changeState(e){this.state=e,this.onChangeState(e)}constructor(e={}){this.stompVersions=F.default,this.connectionTimeout=0,this.reconnectDelay=5e3,this._nextReconnectDelay=0,this.maxReconnectDelay=9e5,this.reconnectTimeMode=U.LINEAR,this.heartbeatIncoming=1e4,this.heartbeatToleranceMultiplier=2,this.heartbeatOutgoing=1e4,this.heartbeatStrategy=$.Interval,this.splitLargeFrames=!1,this.maxWebSocketChunkSize=8192,this.forceBinaryWSFrames=!1,this.appendMissingNULLonIncoming=!1,this.discardWebsocketOnCommFailure=!1,this.state=x.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(x.ACTIVE),this._nextReconnectDelay=this.reconnectDelay,this._connect())};this.state===x.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 j(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===x.DEACTIVATING&&this._changeState(x.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===U.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 n;if(this.state===x.INACTIVE)return this.debug("Already INACTIVE, nothing more to do"),Promise.resolve();if(this._changeState(x.DEACTIVATING),this._nextReconnectDelay=0,this._reconnector&&(clearTimeout(this._reconnector),this._reconnector=void 0),!this._stompHandler||this.webSocket.readyState===P.CLOSED)return this._changeState(x.INACTIVE),Promise.resolve();{const e=this._stompHandler.onWebSocketClose;n=new Promise((t,s)=>{this._stompHandler.onWebSocketClose=s=>{e(s),t()}})}return t?this._stompHandler?.discardWebsocket():s&&this._disposeStompHandler(),n}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 H="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};function G(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var B,J,q,z,K,X,Y={exports:{}},Q={};function Z(){if(q)return J;q=1;var e=(B||(B=1,H.crypto&&H.crypto.getRandomValues?Q.randomBytes=function(e){var t=new Uint8Array(e);return H.crypto.getRandomValues(t),t}:Q.randomBytes=function(e){for(var t=new Array(e),s=0;s<e;s++)t[s]=Math.floor(256*Math.random());return t}),Q),t="abcdefghijklmnopqrstuvwxyz012345";return J={string:function(s){for(var n=e.randomBytes(s),i=[],r=0;r<s;r++)i.push(t.substr(n[r]%32,1));return i.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 ee(){return z||(z=1,function(e){var t=Z(),s={},n=!1,i=H.chrome&&H.chrome.app&&H.chrome.app.runtime;e.exports={attachEvent:function(e,t){void 0!==H.addEventListener?H.addEventListener(e,t,!1):H.document&&H.attachEvent&&(H.document.attachEvent("on"+e,t),H.attachEvent("on"+e,t))},detachEvent:function(e,t){void 0!==H.addEventListener?H.removeEventListener(e,t,!1):H.document&&H.detachEvent&&(H.document.detachEvent("on"+e,t),H.detachEvent("on"+e,t))},unloadAdd:function(e){if(i)return null;var r=t.string(8);return s[r]=e,n&&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]}};i||e.exports.attachEvent("unload",function(){n||(n=!0,e.exports.triggerUnloadCallbacks())})}(Y)),Y.exports}var te,se,ne,ie,re,oe={};function ae(){if(ne)return se;ne=1;var e=X?K:(X=1,K=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(te)return oe;te=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 oe.stringify=function(t,n){n=n||"";var i,r,o=[];for(r in"string"!=typeof n&&(n="?"),t)if(e.call(t,r)){if((i=t[r])||null!=i&&!isNaN(i)||(i=""),r=s(r),i=s(i),null===r||null===i)continue;o.push(r+"="+i)}return o.length?n+o.join("&"):""},oe.parse=function(e){for(var s,n=/([^=?#&]+)=?([^&]*)/g,i={};s=n.exec(e);){var r=t(s[1]),o=t(s[2]);null===r||null===o||r in i||(i[r]=o)}return i},oe}(),s=/^[\x00-\x20\u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]+/,n=/[\n\r\t]/g,i=/^[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 l=[["#","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]],h={hash:1,query:1};function d(e){var t,s=("undefined"!=typeof window?window:void 0!==H?H:"undefined"!=typeof self?self:{}).location||{},n={},r=typeof(e=e||s);if("blob:"===e.protocol)n=new g(unescape(e.pathname),{});else if("string"===r)for(t in n=new g(e,{}),h)delete n[t];else if("object"===r){for(t in e)t in h||(n[t]=e[t]);void 0===n.slashes&&(n.slashes=i.test(e.href))}return n}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(n,""),t=t||{};var s,i=o.exec(e),r=i[1]?i[1].toLowerCase():"",a=!!i[2],l=!!i[3],h=0;return a?l?(s=i[2]+i[3]+i[4],h=i[2].length+i[3].length):(s=i[2]+i[4],h=i[2].length):l?(s=i[3]+i[4],h=i[3].length):s=i[4],"file:"===r?h>=2&&(s=s.slice(2)):u(r)?s=i[4]:r?a&&(s=s.slice(2)):h>=2&&u(t.protocol)&&(s=i[4]),{protocol:r,slashes:a||u(r),slashesCount:h,rest:s}}function g(s,i,r){if(s=(s=c(s)).replace(n,""),!(this instanceof g))return new g(s,i,r);var o,h,m,f,_,b,y=l.slice(),v=typeof i,E=this,S=0;for("object"!==v&&"string"!==v&&(r=i,i=null),r&&"function"!=typeof r&&(r=t.parse),o=!(h=p(s||"",i=d(i))).protocol&&!h.slashes,E.slashes=h.slashes||o&&i.slashes,E.protocol=h.protocol||i.protocol||"",s=h.rest,("file:"===h.protocol&&(2!==h.slashesCount||a.test(s))||!h.slashes&&(h.protocol||h.slashesCount<2||!u(E.protocol)))&&(y[3]=[/(.*)/,"pathname"]);S<y.length;S++)"function"!=typeof(f=y[S])?(m=f[0],b=f[1],m!=m?E[b]=s:"string"==typeof m?~(_="@"===m?s.lastIndexOf(m):s.indexOf(m))&&("number"==typeof f[2]?(E[b]=s.slice(0,_),s=s.slice(_+f[2])):(E[b]=s.slice(_),s=s.slice(0,_))):(_=m.exec(s))&&(E[b]=_[1],s=s.slice(0,_.index)),E[b]=E[b]||o&&f[3]&&i[b]||"",f[4]&&(E[b]=E[b].toLowerCase())):s=f(s,E);r&&(E.query=r(E.query)),o&&i.slashes&&"/"!==E.pathname.charAt(0)&&(""!==E.pathname||""!==i.pathname)&&(E.pathname=function(e,t){if(""===e)return t;for(var s=(t||"/").split("/").slice(0,-1).concat(e.split("/")),n=s.length,i=s[n-1],r=!1,o=0;n--;)"."===s[n]?s.splice(n,1):".."===s[n]?(s.splice(n,1),o++):o&&(0===n&&(r=!0),s.splice(n,1),o--);return r&&s.unshift(""),"."!==i&&".."!==i||s.push(""),s.join("/")}(E.pathname,i.pathname)),"/"!==E.pathname.charAt(0)&&u(E.protocol)&&(E.pathname="/"+E.pathname),e(E.port,E.protocol)||(E.host=E.hostname,E.port=""),E.username=E.password="",E.auth&&(~(_=E.auth.indexOf(":"))?(E.username=E.auth.slice(0,_),E.username=encodeURIComponent(decodeURIComponent(E.username)),E.password=E.auth.slice(_+1),E.password=encodeURIComponent(decodeURIComponent(E.password))):E.username=encodeURIComponent(decodeURIComponent(E.auth)),E.auth=E.password?E.username+":"+E.password:E.username),E.origin="file:"!==E.protocol&&u(E.protocol)&&E.host?E.protocol+"//"+E.host:"null",E.href=E.toString()}return g.prototype={set:function(s,n,i){var o=this;switch(s){case"query":"string"==typeof n&&n.length&&(n=(i||t.parse)(n)),o[s]=n;break;case"port":o[s]=n,e(n,o.protocol)?n&&(o.host=o.hostname+":"+n):(o.host=o.hostname,o[s]="");break;case"hostname":o[s]=n,o.port&&(n+=":"+o.port),o.host=n;break;case"host":o[s]=n,r.test(n)?(n=n.split(":"),o.port=n.pop(),o.hostname=n.join(":")):(o.hostname=n,o.port="");break;case"protocol":o.protocol=n.toLowerCase(),o.slashes=!i;break;case"pathname":case"hash":if(n){var a="pathname"===s?"/":"#";o[s]=n.charAt(0)!==a?a+n:n}else o[s]=n;break;case"username":case"password":o[s]=encodeURIComponent(n);break;case"auth":var c=n.indexOf(":");~c?(o.username=n.slice(0,c),o.username=encodeURIComponent(decodeURIComponent(o.username)),o.password=n.slice(c+1),o.password=encodeURIComponent(decodeURIComponent(o.password))):o.username=encodeURIComponent(decodeURIComponent(n))}for(var h=0;h<l.length;h++){var d=l[h];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,n=this,i=n.host,o=n.protocol;o&&":"!==o.charAt(o.length-1)&&(o+=":");var a=o+(n.protocol&&n.slashes||u(n.protocol)?"//":"");return n.username?(a+=n.username,n.password&&(a+=":"+n.password),a+="@"):n.password?(a+=":"+n.password,a+="@"):"file:"!==n.protocol&&u(n.protocol)&&!i&&"/"!==n.pathname&&(a+="@"),(":"===i[i.length-1]||r.test(n.hostname)&&!n.port)&&(i+=":"),a+=i+n.pathname,(s="object"==typeof n.query?e(n.query):n.query)&&(a+="?"!==s.charAt(0)?"?"+s:s),n.hash&&(a+=n.hash),a}},g.extractProtocol=p,g.location=d,g.trimLeft=c,g.qs=t,se=g}function ce(){if(re)return ie;re=1;var e=ae();return ie={getOrigin:function(t){if(!t)return null;var s=new e(t);if("file:"===s.protocol)return null;var n=s.port;return n||(n="https:"===s.protocol?"443":"80"),s.protocol+"//"+s.hostname+":"+n},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 le,he={exports:{}};function de(){return le||(le=1,"function"==typeof Object.create?he.exports=function(e,t){t&&(e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}))}:he.exports=function(e,t){if(t){e.super_=t;var s=function(){};s.prototype=t.prototype,e.prototype=new s,e.prototype.constructor=e}}),he.exports}var ue,pe,ge,me={};function fe(){if(pe)return ue;function e(){this._listeners={}}return pe=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 n=s.indexOf(t);-1===n||(s.length>1?this._listeners[e]=s.slice(0,n).concat(s.slice(n+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 n=this._listeners[t],i=0;i<n.length;i++)n[i].apply(this,s)},ue=e}function _e(){if(ge)return me;ge=1;var e=de(),t=fe();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,n=!1;this.on(e,function i(){s.removeListener(e,i),n||(n=!0,t.apply(this,arguments))})},s.prototype.emit=function(){var e=arguments[0],t=this._listeners[e];if(t){for(var s=arguments.length,n=new Array(s-1),i=1;i<s;i++)n[i-1]=arguments[i];for(var r=0;r<t.length;r++)t[r].apply(this,n)}},s.prototype.on=s.prototype.addListener=t.prototype.addEventListener,s.prototype.removeListener=t.prototype.removeEventListener,me.EventEmitter=s,me}var be,ye,ve,Ee,Se,we,Ie,Te,Ce,Ae,Re,Me,Oe,Ne,ke,Le,De,Pe,xe,Ue,$e,We,Fe,je,Ve,He,Ge,Be,Je,qe,ze,Ke,Xe,Ye,Qe,Ze={exports:{}};function et(){if(ve)return ye;ve=1;var e=ee(),t=ce(),s=de(),n=_e().EventEmitter,i=function(){if(be)return Ze.exports;be=1;var e=H.WebSocket||H.MozWebSocket;return Ze.exports=e?function(t){return new e(t)}:void 0,Ze.exports}();function r(s,o,a){if(!r.enabled())throw new Error("Transport created when disabled");n.call(this);var c=this,l=t.addPath(s,"/websocket");l="https"===l.slice(0,5)?"wss"+l.slice(5):"ws"+l.slice(4),this.url=l,this.ws=new i(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,n),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!!i},r.transportName="websocket",r.roundTrips=2,ye=r}function tt(){if(Ce)return Te;Ce=1;var e=de(),t=ce(),s=function(){if(Se)return Ee;Se=1;var e=de(),t=_e().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)},Ee=s}(),n=function(){if(Ie)return we;Ie=1;var e=de(),t=_e().EventEmitter;function s(e,s,n){t.call(this),this.Receiver=e,this.receiveUrl=s,this.AjaxObject=n,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,n){e.pollIsClosing,e.poll=t=null,e.pollIsClosing||("network"===n?e._scheduleReceiver():(e.emit("close",s||1006,n),e.removeAllListeners()))})},s.prototype.abort=function(){this.removeAllListeners(),this.pollIsClosing=!0,this.poll&&this.poll.abort()},we=s}();function i(e,i,r,o,a){var c=t.addPath(e,i),l=this;s.call(this,e,r),this.poll=new n(o,c,a),this.poll.on("message",function(e){l.emit("message",e)}),this.poll.once("close",function(e,t){l.poll=null,l.emit("close",e,t),l.close()})}return e(i,s),i.prototype.close=function(){s.prototype.close.call(this),this.removeAllListeners(),this.poll&&(this.poll.abort(),this.poll=null)},Te=i}function st(){if(Re)return Ae;Re=1;var e=de(),t=ce(),s=tt();function n(e,n,i,r){s.call(this,e,n,function(e){return function(s,n,i){var r={};"string"==typeof n&&(r.headers={"Content-type":"text/plain"});var o=t.addPath(s,"/xhr_send"),a=new e("POST",o,n,r);return a.once("finish",function(e){if(a=null,200!==e&&204!==e)return i(new Error("http status "+e));i()}),function(){a.close(),a=null;var e=new Error("Aborted");e.code=1e3,i(e)}}}(r),i,r)}return e(n,s),Ae=n}function nt(){if(Oe)return Me;Oe=1;var e=de(),t=_e().EventEmitter;function s(e,s){t.call(this);var n=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){n._chunkHandler(e,t),n.xo=null;var s=200===e?"network":"permanent";n.emit("close",null,s),n._cleanup()})}return e(s,t),s.prototype._chunkHandler=function(e,t){if(200===e&&t)for(var s=-1;;this.bufferPosition+=s+1){var n=t.slice(this.bufferPosition);if(-1===(s=n.indexOf("\n")))break;var i=n.slice(0,s);i&&this.emit("message",i)}},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()},Me=s}function it(){if(ke)return Ne;ke=1;var e=_e().EventEmitter,t=de(),s=ee(),n=ce(),i=H.XMLHttpRequest;function r(t,s,n,i){var r=this;e.call(this),setTimeout(function(){r._start(t,s,n,i)},0)}t(r,e),r.prototype._start=function(e,t,o,a){var c=this;try{this.xhr=new i}catch(e){}if(!this.xhr)return this.emit("finish",0,"no xhr support"),void this._cleanup();t=n.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 l in a.headers)this.xhr.setRequestHeader(l,a.headers[l]);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=!!i;var o=["Active"].concat("Object").join("X");!r.enabled&&o in H&&(i=function(){try{return new H[o]("Microsoft.XMLHTTP")}catch(e){return null}},r.enabled=!!new i);var a=!1;try{a="withCredentials"in new i}catch(e){}return r.supportsCORS=a,Ne=r}function rt(){if(De)return Le;De=1;var e=de(),t=it();function s(e,s,n,i){t.call(this,e,s,n,i)}return e(s,t),s.enabled=t.enabled&&t.supportsCORS,Le=s}function ot(){if(xe)return Pe;xe=1;var e=de(),t=it();function s(e,s,n){t.call(this,e,s,n,{noCredentials:!0})}return e(s,t),s.enabled=t.enabled,Pe=s}function at(){return $e?Ue:($e=1,Ue={isOpera:function(){return H.navigator&&/opera/i.test(H.navigator.userAgent)},isKonqueror:function(){return H.navigator&&/konqueror/i.test(H.navigator.userAgent)},hasDomain:function(){if(!H.document)return!0;try{return!!H.document.domain}catch(e){return!1}}})}function ct(){if(Fe)return We;Fe=1;var e=de(),t=st(),s=nt(),n=rt(),i=ot(),r=at();function o(e){if(!i.enabled&&!n.enabled)throw new Error("Transport created when disabled");t.call(this,e,"/xhr_streaming",s,n)}return e(o,t),o.enabled=function(e){return!e.nullOrigin&&(!r.isOpera()&&n.enabled)},o.transportName="xhr-streaming",o.roundTrips=2,o.needBody=!!H.document,We=o}function lt(){if(Ve)return je;Ve=1;var e=_e().EventEmitter,t=de(),s=ee(),n=at(),i=ce();function r(t,s,n){var i=this;e.call(this),setTimeout(function(){i._start(t,s,n)},0)}return t(r,e),r.prototype._start=function(e,t,n){var r=this,o=new H.XDomainRequest;t=i.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(n)}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=!(!H.XDomainRequest||!n.hasDomain()),je=r}function ht(){if(Ge)return He;Ge=1;var e=de(),t=st(),s=nt(),n=lt();function i(e){if(!n.enabled)throw new Error("Transport created when disabled");t.call(this,e,"/xhr_streaming",s,n)}return e(i,t),i.enabled=function(e){return!e.cookie_needed&&!e.nullOrigin&&(n.enabled&&e.sameScheme)},i.transportName="xdr-streaming",i.roundTrips=2,He=i}function dt(){return Je?Be:(Je=1,Be=H.EventSource)}function ut(){if(Xe)return Ke;Xe=1;var e=de(),t=st(),s=function(){if(ze)return qe;ze=1;var e=de(),t=_e().EventEmitter,s=dt();function n(e){t.call(this);var n=this,i=this.es=new s(e);i.onmessage=function(e){e.data,n.emit("message",decodeURI(e.data))},i.onerror=function(e){i.readyState;var t=2!==i.readyState?"network":"permanent";n._cleanup(),n._close(t)}}return e(n,t),n.prototype.abort=function(){this._cleanup(),this._close("user")},n.prototype._cleanup=function(){var e=this.es;e&&(e.onmessage=e.onerror=null,e.close(),this.es=null)},n.prototype._close=function(e){var t=this;setTimeout(function(){t.emit("close",null,e),t.removeAllListeners()},200)},qe=n}(),n=rt(),i=dt();function r(e){if(!r.enabled())throw new Error("Transport created when disabled");t.call(this,e,"/eventsource",s,n)}return e(r,t),r.enabled=function(){return!!i},r.transportName="eventsource",r.roundTrips=2,Ke=r}function pt(){return Qe?Ye:(Qe=1,Ye="1.6.1")}var gt,mt,ft,_t,bt,yt,vt,Et,St,wt,It,Tt,Ct,At,Rt,Mt,Ot,Nt,kt,Lt,Dt,Pt,xt,Ut={exports:{}};function $t(){return gt||(gt=1,function(e){var t=ee(),s=at();e.exports={WPrefix:"_jp",currentWindowId:null,polluteGlobalNamespace:function(){e.exports.WPrefix in H||(H[e.exports.WPrefix]={})},postMessage:function(t,s){H.parent!==H&&H.parent.postMessage(JSON.stringify({windowId:e.exports.currentWindowId,type:t,data:s||""}),"*")},createIframe:function(e,s){var n,i,r=H.document.createElement("iframe"),o=function(){clearTimeout(n);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(i))},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(n),n=setTimeout(function(){c("onload timeout")},2e3)},H.document.body.appendChild(r),n=setTimeout(function(){c("timeout")},15e3),i=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,n){var i,r,o,a=["Active"].concat("Object").join("X"),c=new H[a]("htmlfile"),l=function(){clearTimeout(i),o.onerror=null},h=function(){c&&(l(),t.unloadDel(r),o.parentNode.removeChild(o),o=c=null,CollectGarbage())},d=function(e){c&&(h(),n(e))};c.open(),c.write('<html><script>document.domain="'+H.document.domain+'";<\/script></html>'),c.close(),c.parentWindow[e.exports.WPrefix]=H[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")},i=setTimeout(function(){d("timeout")},15e3),r=t.unloadAdd(h),{post:function(e,t){try{setTimeout(function(){o&&o.contentWindow&&o.contentWindow.postMessage(e,t)},0)}catch(e){}},cleanup:h,loaded:l}}},e.exports.iframeEnabled=!1,H.document&&(e.exports.iframeEnabled=("function"==typeof H.postMessage||"object"==typeof H.postMessage)&&!s.isKonqueror())}(Ut)),Ut.exports}function Wt(){if(ft)return mt;ft=1;var e=de(),t=_e().EventEmitter,s=pt(),n=ce(),i=$t(),r=ee(),o=Z();function a(e,s,c){if(!a.enabled())throw new Error("Transport created when disabled");t.call(this);var l=this;this.origin=n.getOrigin(c),this.baseUrl=c,this.transUrl=s,this.transport=e,this.windowId=o.string(8);var h=n.addPath(c,"/iframe.html")+"#"+this.windowId;this.iframeObj=i.createIframe(h,function(e){l.emit("close",1006,"Unable to load an iframe ("+e+")"),l.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,!n.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 i;try{i=JSON.parse(t.data)}catch(e){return void t.data}this.emit("close",i[0],i[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 i.iframeEnabled},a.transportName="iframe",a.roundTrips=2,mt=a}function Ft(){return bt||(bt=1,_t={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,n=1,i=arguments.length;n<i;n++)for(s in t=arguments[n])Object.prototype.hasOwnProperty.call(t,s)&&(e[s]=t[s]);return e}}),_t}function jt(){if(vt)return yt;vt=1;var e=de(),t=Wt(),s=Ft();return yt=function(n){function i(e,s){t.call(this,n.transportName,e,s)}return e(i,t),i.enabled=function(e,i){if(!H.document)return!1;var r=s.extend({},i);return r.sameOrigin=!0,n.enabled(r)&&t.enabled()},i.transportName="iframe-"+n.transportName,i.needBody=!0,i.roundTrips=t.roundTrips+n.roundTrips-1,i.facadeTransport=n,i},yt}function Vt(){if(It)return wt;It=1;var e=de(),t=function(){if(St)return Et;St=1;var e=de(),t=$t(),s=ce(),n=_e().EventEmitter,i=Z();function r(e){n.call(this);var o=this;t.polluteGlobalNamespace(),this.id="a"+i.string(6),e=s.addQuery(e,"c="+decodeURIComponent(t.WPrefix+"."+this.id)),r.htmlfileEnabled;var a=r.htmlfileEnabled?t.createHtmlfile:t.createIframe;H[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,n),r.prototype.abort=function(){this._cleanup(),this._close("user")},r.prototype._cleanup=function(){this.iframeObj&&(this.iframeObj.cleanup(),this.iframeObj=null),delete H[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 H)try{r.htmlfileEnabled=!!new H[o]("htmlfile")}catch(e){}return r.enabled=r.htmlfileEnabled||t.iframeEnabled,Et=r}(),s=ot(),n=st();function i(e){if(!t.enabled)throw new Error("Transport created when disabled");n.call(this,e,"/htmlfile",t,s)}return e(i,n),i.enabled=function(e){return t.enabled&&e.sameOrigin},i.transportName="htmlfile",i.roundTrips=2,wt=i}function Ht(){if(Ct)return Tt;Ct=1;var e=de(),t=st(),s=nt(),n=rt(),i=ot();function r(e){if(!i.enabled&&!n.enabled)throw new Error("Transport created when disabled");t.call(this,e,"/xhr",s,n)}return e(r,t),r.enabled=function(e){return!e.nullOrigin&&(!(!i.enabled||!e.sameOrigin)||n.enabled)},r.transportName="xhr-polling",r.roundTrips=2,Tt=r}function Gt(){if(Rt)return At;Rt=1;var e=de(),t=st(),s=ht(),n=nt(),i=lt();function r(e){if(!i.enabled)throw new Error("Transport created when disabled");t.call(this,e,"/xhr",n,i)}return e(r,t),r.enabled=s.enabled,r.transportName="xdr-polling",r.roundTrips=2,At=r}function Bt(){if(kt)return Nt;kt=1;var e,t,s=Z(),n=ce();return Nt=function(i,r,o){e||((e=H.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=H.document.createElement("textarea")).name="d",e.appendChild(t),H.document.body.appendChild(e));var a="a"+s.string(8);e.target=a,e.action=n.addQuery(n.addPath(i,"/jsonp_send"),"i="+a);var c=function(e){try{return H.document.createElement('<iframe name="'+e+'">')}catch(s){var t=H.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 l=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(){l()},c.onload=function(){l()},c.onreadystatechange=function(e){c.readyState,"complete"===c.readyState&&l()},function(){l(new Error("Aborted"))}},Nt}function Jt(){if(Dt)return Lt;Dt=1;var e=de(),t=tt(),s=function(){if(Ot)return Mt;Ot=1;var e=$t(),t=Z(),s=at(),n=ce(),i=de(),r=_e().EventEmitter;function o(s){var i=this;r.call(this),e.polluteGlobalNamespace(),this.id="a"+t.string(6);var a=n.addQuery(s,"c="+encodeURIComponent(e.WPrefix+"."+this.id));H[e.WPrefix][this.id]=this._callback.bind(this),this._createScript(a),this.timeoutId=setTimeout(function(){i._abort(new Error("JSONP script loaded abnormally (timeout)"))},o.timeout)}return i(o,r),o.prototype.abort=function(){if(H[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 H[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 n,i=this,r=this.script=H.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(){i._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){i.loadedOkay=!0;try{r.onclick()}catch(e){}}r&&i._abort(new Error("JSONP script loaded abnormally (onreadystatechange)"))}},void 0===r.async&&H.document.attachEvent)if(s.isOpera())(n=this.script2=H.document.createElement("script")).text="try{var a = document.getElementById('"+r.id+"'); if(a)a.onerror();}catch(x){};",r.async=n.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=H.document.getElementsByTagName("head")[0];o.insertBefore(r,o.firstChild),n&&o.insertBefore(n,o.firstChild)},Mt=o}(),n=Bt();function i(e){if(!i.enabled())throw new Error("Transport created when disabled");t.call(this,e,"/jsonp",n,s)}return e(i,t),i.enabled=function(){return!!H.document},i.transportName="jsonp-polling",i.roundTrips=1,i.needBody=!0,Lt=i}function qt(){return xt?Pt:(xt=1,Pt=[et(),ct(),ht(),ut(),jt()(ut()),Vt(),jt()(Vt()),Ht(),Gt(),jt()(Ht()),Jt()])}var zt,Kt,Xt,Yt,Qt,Zt,es,ts,ss,ns,is,rs,os,as,cs,ls,hs,ds,us,ps,gs,ms,fs,_s,bs,ys,vs,Es,Ss,ws,Is,Ts,Cs,As={};function Rs(){if(zt)return As;zt=1;var e,t=Array.prototype,s=Object.prototype,n=Function.prototype,i=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)},l=Object.defineProperty&&function(){try{return Object.defineProperty({},"x",{}),!0}catch(e){return!1}}();e=l?function(e,t,s,n){!n&&t in e||Object.defineProperty(e,t,{configurable:!0,enumerable:!1,writable:!0,value:s})}:function(e,t,s,n){!n&&t in e||(e[t]=s)};var h=function(t,n,i){for(var r in n)s.hasOwnProperty.call(n,r)&&e(t,r,n[r],i)},d=function(e){if(null==e)throw new TypeError("can't convert "+e+" to object");return Object(e)};function u(){}h(n,{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),n=Math.max(0,t.length-s.length),i=[],o=0;o<n;o++)i.push("$"+o);var c=Function("binder","return function ("+i.join(",")+"){ return binder.apply(this, arguments); }")(function(){if(this instanceof c){var n=t.apply(this,s.concat(r.call(arguments)));return Object(n)===n?n: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}}),h(Array,{isArray:function(e){return"[object Array]"===o.call(e)}});var p,g,m,f=Object("a"),_="a"!==f[0]||!(0 in f);h(t,{forEach:function(e){var t=d(this),s=_&&c(this)?this.split(""):t,n=arguments[1],i=-1,r=s.length>>>0;if(!a(e))throw new TypeError;for(;++i<r;)i in s&&e.call(n,s[i],i,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 b=Array.prototype.indexOf&&-1!==[0,1].indexOf(1,2);h(t,{indexOf:function(e){var t=_&&c(this)?this.split(""):d(this),s=t.length>>>0;if(!s)return-1;var n,i=0;for(arguments.length>1&&((n=+arguments[1])!=n?n=0:0!==n&&n!==1/0&&n!==-1/0&&(n=(n>0||-1)*Math.floor(Math.abs(n))),i=n),i=i>=0?i:Math.max(0,s+i);i<s;i++)if(i in t&&t[i]===e)return i;return-1}},b);var y,v=i.split;2!=="ab".split(/(?:ab)*/).length||4!==".".split(/(.?)(.?)/).length||"t"==="tesst".split(/(s)*/)[1]||4!=="test".split(/(?:)/,-1).length||"".split(/.?/).length||".".split(/()()/).length>1?(y=void 0===/()??/.exec("")[1],i.split=function(e,s){var n=this;if(void 0===e&&0===s)return[];if("[object RegExp]"!==o.call(e))return v.call(this,e,s);var i,r,a,c,l=[],h=(e.ignoreCase?"i":"")+(e.multiline?"m":"")+(e.extended?"x":"")+(e.sticky?"y":""),d=0;for(e=new RegExp(e.source,h+"g"),n+="",y||(i=new RegExp("^"+e.source+"$(?!\\s)",h)),s=void 0===s?-1>>>0:s>>>0;(r=e.exec(n))&&!((a=r.index+r[0].length)>d&&(l.push(n.slice(d,r.index)),!y&&r.length>1&&r[0].replace(i,function(){for(var e=1;e<arguments.length-2;e++)void 0===arguments[e]&&(r[e]=void 0)}),r.length>1&&r.index<n.length&&t.push.apply(l,r.slice(1)),c=r[0].length,d=a,l.length>=s));)e.lastIndex===r.index&&e.lastIndex++;return d===n.length?!c&&e.test("")||l.push(""):l.push(n.slice(d)),l.length>s?l.slice(0,s):l}):"0".split(void 0,0).length&&(i.split=function(e,t){return void 0===e&&0===t?[]:v.call(this,e,t)});var E=i.substr,S="".substr&&"b"!=="0b".substr(-1);return h(i,{substr:function(e,t){return E.call(this,e<0&&(e=this.length+e)<0?0:e,t)}},S),As}function Ms(){if(Xt)return Kt;Xt=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 Kt={quote:function(s){var n=JSON.stringify(s);return t.lastIndex=0,t.test(n)?(e||(e=function(e){var t,s={},n=[];for(t=0;t<65536;t++)n.push(String.fromCharCode(t));return e.lastIndex=0,n.join("").replace(e,function(e){return s[e]="\\u"+("0000"+e.charCodeAt(0).toString(16)).slice(-4),""}),e.lastIndex=0,s}(t)),n.replace(t,function(t){return e[t]})):n}}}function Os(){if(Qt)return Yt;Qt=1;return Yt=function(e){return{filterToEnabled:function(t,s){var n={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,n.main.push(e),e.facadeTransport&&n.facade.push(e.facadeTransport)):e.transportName))}),n}}}}function Ns(){if(es)return Zt;es=1;var e={};return["log","debug","warn"].forEach(function(t){var s;try{s=H.console&&H.console[t]&&H.console[t].apply}catch(e){}e[t]=s?function(){return H.console[t].apply(H.console,arguments)}:"log"===t?function(){}:e.log}),Zt=e}function ks(){if(ss)return ts;function e(e){this.type=e}return ss=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,ts=e}function Ls(){return is?ns:(is=1,ns=H.location||{origin:"http://localhost:80",protocol:"http:",host:"localhost",port:80,href:"http://localhost/",hash:""})}function Ds(){if(us)return ds;us=1;var e=_e().EventEmitter,t=de(),s=Ft();function n(t,n){e.call(this);var i=this,r=+new Date;this.xo=new n("GET",t),this.xo.once("finish",function(e,t){var n,o;if(200===e){if(o=+new Date-r,t)try{n=JSON.parse(t)}catch(e){}s.isObject(n)||(n={})}i.emit("finish",n,o),i.removeAllListeners()})}return t(n,e),n.prototype.close=function(){this.removeAllListeners(),this.xo.close()},ds=n}function Ps(){if(gs)return ps;gs=1;var e=de(),t=_e().EventEmitter,s=ot(),n=Ds();function i(e){var i=this;t.call(this),this.ir=new n(e,s),this.ir.once("finish",function(e,t){i.ir=null,i.emit("message",JSON.stringify([e,t]))})}return e(i,t),i.transportName="iframe-info-receiver",i.prototype.close=function(){this.ir&&(this.ir.close(),this.ir=null),this.removeAllListeners()},ps=i}function xs(){if(bs)return _s;bs=1;var e=_e().EventEmitter,t=de(),s=ce(),n=lt(),i=rt(),r=ot(),o=function(){if(hs)return ls;hs=1;var e=_e().EventEmitter;function t(){var s=this;e.call(this),this.to=setTimeout(function(){s.emit("finish",200,"{}")},t.timeout)}return de()(t,e),t.prototype.close=function(){clearTimeout(this.to)},t.timeout=2e3,ls=t}(),a=function(){if(fs)return ms;fs=1;var e=_e().EventEmitter,t=de(),s=ee(),n=Wt(),i=Ps();function r(t,r){var o=this;e.call(this);var a=function(){var e=o.ifr=new n(i.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],n=t[1];o.emit("finish",s,n)}o.close()}),e.once("close",function(){o.emit("finish"),o.close()})};H.document.body?a():s.attachEvent("load",a)}return t(r,e),r.enabled=function(){return n.enabled()},r.prototype.close=function(){this.ifr&&this.ifr.close(),this.removeAllListeners(),this.ifr=null},ms=r}(),c=Ds();function l(t,s){var n=this;e.call(this),setTimeout(function(){n.doXhr(t,s)},0)}return t(l,e),l._getReceiver=function(e,t,s){return s.sameOrigin?new c(t,r):i.enabled?new c(t,i):n.enabled&&s.sameScheme?new c(t,n):a.enabled()?new a(e,t):new c(t,o)},l.prototype.doXhr=function(e,t){var n=this,i=s.addPath(e,"/info");this.xo=l._getReceiver(e,i,t),this.timeoutRef=setTimeout(function(){n._cleanup(!1),n.emit("finish")},l.timeout),this.xo.once("finish",function(e,t){n._cleanup(!0),n.emit("finish",e,t)})},l.prototype._cleanup=function(e){clearTimeout(this.timeoutRef),this.timeoutRef=null,!e&&this.xo&&this.xo.close(),this.xo=null},l.prototype.close=function(){this.removeAllListeners(),this._cleanup(!1)},l.timeout=8e3,_s=l}function Us(){if(Ss)return Es;Ss=1;var e=ce(),t=ee(),s=function(){if(vs)return ys;vs=1;var e=$t();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()},ys=t}(),n=Ps(),i=$t(),r=Ls();return Es=function(o,a){var c,l={};a.forEach(function(e){e.facadeTransport&&(l[e.facadeTransport.transportName]=e.facadeTransport)}),l[n.transportName]=n,o.bootstrap_iframe=function(){var n;i.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===i.currentWindowId)switch(a.type){case"s":var h;try{h=JSON.parse(a.data)}catch(e){a.data;break}var d=h[0],u=h[1],p=h[2],g=h[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+")");n=new s(new l[u](p,g));break;case"m":n._send(a.data);break;case"c":n&&n._close(),n=null}}}),i.postMessage("s")}},Es}function $s(){if(Is)return ws;Is=1,Rs();var e,t=ae(),s=de(),n=Z(),i=Ms(),r=ce(),o=ee(),a=Os(),c=Ft(),l=at(),h=Ns(),d=ks(),u=fe(),p=Ls(),g=function(){if(os)return rs;os=1;var e=de(),t=ks();function s(){t.call(this),this.initEvent("close",!1,!1),this.wasClean=!1,this.code=0,this.reason=""}return e(s,t),rs=s}(),m=function(){if(cs)return as;cs=1;var e=de(),t=ks();function s(e){t.call(this),this.initEvent("message",!1,!1),this.data=e}return e(s,t),as=s}(),f=xs(),_=function(){};function b(e,s,i){if(!(this instanceof b))return new b(e,s,i);if(arguments.length<1)throw new TypeError("Failed to construct 'SockJS: 1 argument required, but only 0 present");u.call(this),this.readyState=b.CONNECTING,this.extensions="",this.protocol="",(i=i||{}).protocols_whitelist&&h.warn("'protocols_whitelist' is DEPRECATED. Use 'transports' instead."),this._transportsWhitelist=i.transports,this._transportOptions=i.transportOptions||{},this._timeout=i.timeout||0;var o=i.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 n.string(o)}}this._server=i.server||n.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:!l.hasDomain(),sameOrigin:r.isOriginEqual(this.url,p.href),sameScheme:r.isSchemeEqual(this.url,p.href)},this._ir=new f(this.url,this._urlInfo),this._ir.once("finish",this._receiveInfo.bind(this))}function y(e){return 1e3===e||e>=3e3&&e<=4999}return s(b,u),b.prototype.close=function(e,t){if(e&&!y(e))throw new Error("InvalidAccessError: Invalid code");if(t&&t.length>123)throw new SyntaxError("reason argument has an invalid length");if(this.readyState!==b.CLOSING&&this.readyState!==b.CLOSED){this._close(e||1e3,t||"Normal closure",!0)}},b.prototype.send=function(e){if("string"!=typeof e&&(e=""+e),this.readyState===b.CONNECTING)throw new Error("InvalidStateError: The connection has not been established yet");this.readyState===b.OPEN&&this._transport.send(i.quote(e))},b.version=pt(),b.CONNECTING=0,b.OPEN=1,b.CLOSING=2,b.CLOSED=3,b.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 n=e.filterToEnabled(this._transportsWhitelist,t);this._transports=n.main,this._transports.length,this._connect()}else this._close(1002,"Cannot connect to server")},b.prototype._connect=function(){for(var e=this._transports.shift();e;e=this._transports.shift()){if(_(e.transportName),e.needBody&&(!H.document.body||void 0!==H.document.readyState&&"complete"!==H.document.readyState&&"interactive"!==H.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()),n=this._transportOptions[e.transportName],i=new e(s,this._transUrl,n);return i.on("message",this._transportMessage.bind(this)),i.once("close",this._transportClose.bind(this)),i.transportName=e.transportName,void(this._transport=i)}this._close(2e3,"All transports failed",!1)},b.prototype._transportTimeout=function(){this.readyState===b.CONNECTING&&(this._transport&&this._transport.close(),this._transportClose(2007,"Transport timed out"))},b.prototype._transportMessage=function(e){var t,s=this,n=e.slice(0,1),i=e.slice(1);switch(n){case"o":return void this._open();case"h":return this.dispatchEvent(new d("heartbeat")),void this.transport}if(i)try{t=JSON.parse(i)}catch(e){}if(void 0!==t)switch(n){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)}},b.prototype._transportClose=function(e,t){this.transport,this._transport&&(this._transport.removeAllListeners(),this._transport=null,this.transport=null),y(e)||2e3===e||this.readyState!==b.CONNECTING?this._close(e,t):this._connect()},b.prototype._open=function(){this._transport&&this._transport.transportName,this.readyState,this.readyState===b.CONNECTING?(this._transportTimeoutId&&(clearTimeout(this._transportTimeoutId),this._transportTimeoutId=null),this.readyState=b.OPEN,this.transport=this._transport.transportName,this.dispatchEvent(new d("open")),this.transport):this._close(1006,"Server lost session")},b.prototype._close=function(e,t,s){this.transport,this.readyState;var n=!1;if(this._ir&&(n=!0,this._ir.close(),this._ir=null),this._transport&&(this._transport.close(),this._transport=null,this.transport=null),this.readyState===b.CLOSED)throw new Error("InvalidStateError: SockJS has already been closed");this.readyState=b.CLOSING,setTimeout(function(){this.readyState=b.CLOSED,n&&this.dispatchEvent(new d("error"));var i=new g("close");i.wasClean=s||!1,i.code=e||1e3,i.reason=t,this.dispatchEvent(i),this.onmessage=this.onclose=this.onerror=null}.bind(this),0)},b.prototype.countRTO=function(e){return e>100?4*e:300+e},ws=function(t){return e=a(t),Us()(b,t),b}}var Ws=function(){if(Cs)return Ts;Cs=1;var e=qt();return Ts=$s()(e),"_sockjs_onload"in H&&setTimeout(H._sockjs_onload,1),Ts}(),Fs=G(Ws);const js=()=>"undefined"!=typeof window&&window.StompJs&&window.StompJs.Client?window.StompJs.Client:V,Vs=()=>"undefined"!=typeof window&&window.SockJS?window.SockJS:Fs;class Hs 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||y.reconnectDelay,this.maxReconnectDelay=e.maxReconnectDelay||y.maxReconnectDelay,this.maxReconnectAttempts=e.maxReconnectAttempts||y.maxReconnectAttempts,this.heartbeatIncoming=e.heartbeatIncoming||y.heartbeatIncoming,this.heartbeatOutgoing=e.heartbeatOutgoing||y.heartbeatOutgoing,this.resumeOnVisibility=!1!==e.resumeOnVisibility,this.logger=new S(e.logLevel||E.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._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)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===P.OPEN}async forceReconnect(e){if(!this._intentionalDisconnect&&this.state!==t.CONNECTING)return this._forceReconnectPromise?(this.logger.debug(`Force reconnect already in progress, joining: ${e}`),this._forceReconnectPromise):(this._forceReconnectPromise=this._doForceReconnect(e).finally(()=>{this._forceReconnectPromise=null}),this._forceReconnectPromise)}async _doForceReconnect(e){if(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}this._setState(t.DISCONNECTED),this.reconnectAttempts=0;try{await this.connect()}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?f.SOCKJS_ENDPOINT:f.NATIVE_ENDPOINT;return`${this.serverUrl}${e}`}_createStompClient(){const e=this._getWebSocketUrl(),t={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,reconnectTimeMode:U.EXPONENTIAL,maxReconnectDelay:this.maxReconnectDelay,debug:e=>{this.logger.level<=E.DEBUG&&this.logger.debug("STOMP:",e)},onConnect:e=>this._onConnect(e),onDisconnect:e=>this._onDisconnect(e),onStompError:e=>this._onStompError(e),onWebSocketClose:e=>this._onWebSocketClose(e),onWebSocketError:e=>this._onWebSocketError(e)};if(this.useSockJS){const s=Vs();t.webSocketFactory=()=>new s(e)}else{const e=this.serverUrl.startsWith("https")?"wss":"ws",s=this.serverUrl.replace(/^https?:\/\//,"");t.brokerURL=`${e}://${s}${f.NATIVE_ENDPOINT}`}return new(js())(t)}async connect(){if(this.state!==t.CONNECTED){if(this.state!==t.CONNECTING)return this._setState(t.CONNECTING),this.reconnectAttempts=0,this._intentionalDisconnect=!1,this._connectRequested=!0,new Promise((e,s)=>{this._connectResolve=e,this._connectReject=s;try{this.stompClient=this._createStompClient(),this.stompClient.activate()}catch(e){this._setState(t.ERROR),this._drainPendingSubscriptions("Connection activation failed"),s(e)}});this.logger.warn("Connection in progress")}else this.logger.warn("Already connected")}_onConnect(e){const s=this.reconnectAttempts,n=s>0||!0===this._hasConnectedBefore;this._setState(t.CONNECTED),this.reconnectAttempts=0,this._hasConnectedBefore=!0,this.logger.info("Connected to server",e),this._restoreSubscriptions(),this._processPendingSubscriptions(),this.emit("connected",{frame:e}),n&&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){this.logger.error("STOMP error:",e),this._setState(t.ERROR);const n={type:s.CONNECTION_FAILED,message:e.headers?.message||"STOMP error",frame:e};this._drainPendingSubscriptions(`STOMP error: ${n.message}`),this.emit("error",n),this._connectReject&&(this._connectReject(new Error(n.message)),this._connectResolve=null,this._connectReject=null)}_onWebSocketClose(e){this.logger.warn("WebSocket closed:",e),this._tearingDown?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._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){if(this.stompClient){try{this.stompClient.deactivate()}catch(e){this.logger.warn("Error deactivating stomp client on max reconnect:",e)}this.stompClient=null}return 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}`)}_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:n}=this.pendingSubscriptions.shift(),i=this._subscribeInternal(e,t,s);n&&n(i)}}_subscribeInternal(e,t,s={}){const n=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:n,callback:t,headers:s}),this.logger.debug(`Subscribed to: ${e}`),n}subscribe(e,s,n={}){return this.subscriptions.has(e)&&this.unsubscribe(e),this.state!==t.CONNECTED?new Promise((t,i)=>{this.pendingSubscriptions.push({destination:e,callback:s,headers:n,resolve:t,reject:i}),this.logger.debug(`Queued subscription for: ${e}`)}):Promise.resolve(this._subscribeInternal(e,s,n))}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,n={}){return this.state!==t.CONNECTED?(this.logger.warn("Cannot send message: not connected"),!1):(this.stompClient.publish({destination:e,body:JSON.stringify(s),headers:n}),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}`})}async disconnect(){this._intentionalDisconnect=!0,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 Gs=new Set(["text/plain","text/markdown","text/x-markdown"]);class Bs extends e{constructor(e){super(),this.connectionManager=e.connectionManager,this.apiClient=e.apiClient,this.userId=e.userId,this.logger=new S(e.logLevel||E.WARN,"ChatClient"),this.subscribedRooms=new Map,this.roomListSubscribed=!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:"기획 중…",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:y.rewindMillis,this.maxSyncPages=e.maxSyncPages||y.maxSyncPages,this.syncPageSize=e.syncPageSize||y.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._installSyncTriggers()}_installSyncTriggers(){this.connectionManager&&"function"==typeof this.connectionManager.on&&(this._onReconnectedForSync=({attempts:e}={})=>{this.syncAfterReconnect(`reconnected:${e??0}`).catch(e=>this.logger.warn("Gap sync after reconnect failed:",e)),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.connectionManager.on("reconnected",this._onReconnectedForSync),this.connectionManager.on("resumed",this._onResumedForSync))}_shouldDedupMessage(e,t,s){if(!t||!s)return!1;let n=e.get(t);if(n||(n=new Map,e.set(t,n)),n.has(s))return!0;if(n.set(s,!0),n.size>this._maxSeenPerRoom){const e=n.keys().next().value;n.delete(e)}return!1}async getRooms(e={}){const{size:t=50,lastId:s,lastSortValue:n,type:i}=e;return this.apiClient.get("/api/v1/rooms/my",{size:t,lastId:s,lastSortValue:n,type:i})}async getRoom(e){const t=this._anchorGen.get(e)||0,s=await this.apiClient.get(`/api/v1/rooms/${e}`),n=this._unwrapSuccessResponse(s);return n&&Array.isArray(n.messages)&&this._seedAnchorFromLatest(e,n.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||l.GROUP;if(t===l.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===l.GROUP){if(e.password)throw new Error("Public GROUP rooms cannot have a password")}else if(t===l.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,n){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:n})}async summarizeWithAssistant(e,t={}){const{personaId:s,format:n,messageCount:i}=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:n,messageCount:i});return this._unwrapSuccessResponse(r)}async translateWithAssistant(e,t={}){const{targetLang:s,sourceMessageId:n}=t;if(!n)throw new Error("translateWithAssistant requires options.sourceMessageId");if(!s)throw new Error("translateWithAssistant requires options.targetLang");const i=await this.apiClient.post(`/api/v1/rooms/${e}/assistant/tools/translate`,{targetLang:s,sourceMessageId:n});return this._unwrapSuccessResponse(i)}async refreshSummary(e,t={}){const{format:s,lang:n}=t,i=await this.apiClient.post(`/api/v1/rooms/${e}/summary/refresh`,{format:s,lang:n});return this._unwrapSuccessResponse(i)}async getSummary(e,t={}){const{format:s,lang:n,afterSeq:i,size:r}=t,o=await this.apiClient.get(`/api/v1/rooms/${e}/summary`,{format:s,lang:n,afterSeq:i,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){const t=await this.apiClient.post(`/api/v1/rooms/${e}/leave`);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:n}=s;if(!n)throw new Error("createVote: options.idempotencyKey is required — generate it once per vote and reuse the same value on retry (재시도에 같은 키를 넘겨야 투표가 중복 생성되지 않는다).");const i=await this.apiClient.post(`/api/v1/rooms/${e}/votes`,t,void 0,{"X-Idempotency-Key":n});return this._unwrapSuccessResponse(i)}async getVotes(e,t={}){const{cursor:s,limit:n}=t,i=await this.apiClient.get(`/api/v1/rooms/${e}/votes`,{cursor:s,limit:n});return this._unwrapSuccessResponse(i)}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 n=await this.apiClient.patch(`/api/v1/rooms/${e}/votes/${t}`,s);return this._unwrapSuccessResponse(n)}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 n=await this.apiClient.put(`/api/v1/rooms/${e}/votes/${t}/responses`,{optionIds:s});return this._unwrapSuccessResponse(n)}async uploadVoteImage(e,t,s={}){if(!e)throw new Error("roomId is required");if(!t)throw new Error("file is required");const n=await this.apiClient.upload(`/api/v1/rooms/${e}/votes/images`,t,{onProgress:s.onProgress,signal:s.signal});return this._unwrapSuccessResponse(n)}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:n}=e;return this.apiClient.get("/api/v1/rooms/groups/available",{size:t,lastId:s,lastSortValue:n})}async getAllGroupRooms(e={}){const{size:t=50,lastId:s,lastSortValue:n}=e;return this.apiClient.get("/api/v1/rooms/groups/all",{size:t,lastId:s,lastSortValue:n})}async getMessages(e,t={}){const{size:s=50,lastId:n,lastSortValue:i}=t,r=null==n&&null==i,o=this._anchorGen.get(e)||0,a=await this.apiClient.get(`/api/v1/chat-messages/${e}/list`,{size:s,lastId:n,lastSortValue:i}),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 n=t[0];return!(!n||!n.id)&&this._commitAnchorFromSync(e,n.id,s)}async syncMessages(e,t={}){const{afterId:s,rewindMillis:n,size:i=this.syncPageSize}=t,r=await this.apiClient.get(`/api/v1/chat-messages/${e}/sync`,{afterId:s,rewindMillis:n,size:i}),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}),n=this._unwrapSuccessResponse(s)||{},i=(Array.isArray(n.content)?n.content:[]).slice().reverse(),r=this._replayMessages(e,i),o=i.length?i[i.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){const t=this._anchor.get(e);if(!t)return null;if(this._syncInFlight.has(e))return null;this._syncInFlight.add(e);const s=this._anchorGen.get(e)||0,n=Date.now();try{const i=[];let r=t,o=this.rewindMillis,a=!0,c=0;for(;a&&c<this.maxSyncPages;){const t=await this.syncMessages(e,{afterId:r,rewindMillis:o}),s=this._unwrapSuccessResponse(t)||{},n=Array.isArray(s.content)?s.content:[];i.push(...n),o=0,a=!!s.hasNext,s.lastId&&(r=s.lastId),c+=1}if(a){this.logger.info(`Gap too large, falling back to latest page: room=${e}`),this.emit("gapTruncated",{roomId:e,fetched:i.length});return{roomId:e,recovered:await this._reloadLatestPage(e,s),truncated:!0,durationMs:Date.now()-n}}const l=this._replayMessages(e,i);return this._commitAnchorFromSync(e,r,s),{roomId:e,recovered:l,truncated:!1,durationMs:Date.now()-n}}catch(t){if(this._isCursorExpired(t)){this.logger.warn(`Sync cursor expired, reloading latest: room=${e}`),this.emit("gapTruncated",{roomId:e,fetched:0,reason:"cursorExpired"});return{roomId:e,recovered:await this._reloadLatestPage(e,s),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(),n=[];for(const e of t)try{const t=await this._syncRoom(e);t&&n.push(t)}catch(t){this.logger.warn(`Gap sync failed: room=${e}`,t)}await this._refreshRoomList(e),this.emit("syncCompleted",{rooms:n,totalRecovered:n.reduce((e,t)=>e+(t.recovered||0),0),durationMs:Date.now()-s,reason: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(),n=[s],i=this._sendMessageWithId(e,s,t).then(e=>this._attachOptimisticMetadata(n,e));return{baseMessageId:s,messageIds:n,promise:i}}async _sendMessageWithId(e,t,s){this.stopTyping(e);const n=await this.apiClient.post(`/api/v1/chat-messages/${e}/send`,{messageId:t,message:s.message,fileInfos:s.fileInfos,replyToMessageId:s.replyToMessageId,decisionResponse:s.decisionResponse}),i=this._unwrapSuccessResponse(n);return i&&Array.isArray(i.messages)&&i.messages.forEach(e=>this._normalizeMessageTimestamps(e)),i}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 n=await this.apiClient.upload(`/api/v1/files/${e}/upload`,t,{onProgress:s.onProgress,signal:s.signal});return this._unwrapSuccessResponse(n)}async sendFileMessage(e,t,s={}){const n=this._normalizeFileArray(t),i=await this._uploadFiles(e,n,s),r=this._applyFileMetadata(i,s.metadata);return this.sendMessage(e,{message:s.message,fileInfos:r,replyToMessageId:s.replyToMessageId})}sendFileMessageOptimistic(e,t,s={}){const n=this._normalizeFileArray(t),i=this._generateMessageId(),r=[i],o=(async()=>{const t=await this._uploadFiles(e,n,s),o=this._applyFileMetadata(t,s.metadata),a=await this._sendMessageWithId(e,i,{message:s.message,fileInfos:o,replyToMessageId:s.replyToMessageId});return this._attachOptimisticMetadata(r,a)})();return{baseMessageId:i,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,n)=>this.uploadFile(e,t,{signal:s.signal,onProgress:s.onUploadProgress?e=>s.onUploadProgress({...e,fileIndex:n}):void 0})))}_applyFileMetadata(e,t){return null==t?e:e.map((e,s)=>{const n=Array.isArray(t)?t[s]:t;return null==n?e:{...e,metadata:n}})}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")||Gs.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 n=new Set(s.map(e=>this.classifyFileType(e&&e.fileType||"")));return 1===n.size?n.values().next().value:"MIXED"}_attachOptimisticMetadata(e,t){const s=t&&Array.isArray(t.messages)?t.messages.map(e=>e&&e.messageId||null):[],n=s.length===e.length&&e.every((e,t)=>e===s[t]);return n||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:n}}}_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=f.getChatDestination(e);await this.connectionManager.subscribe(t,t=>{this._handleChatMessage(e,t)});const s=f.getChatReadDestination(e);await this.connectionManager.subscribe(s,t=>{this._handleReadEvent(e,t)});const n=f.getChatTypingDestination(e);await this.connectionManager.subscribe(n,t=>{this._handleTypingEvent(e,t)});const i=this.assistantStreamReplay?this._armAssistantSnapshot(e):null,r=f.getChatAssistantStreamDestination(e);await this.connectionManager.subscribe(r,t=>{this._handleAssistantStreamEvent(e,t)}),null!==i&&this._loadAssistantSnapshot(e,i).catch(t=>this.logger.warn(`Assistant snapshot merge failed: room=${e}`,t));const o=f.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:n,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=f.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(f.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}markAsRead(e,t){return this.connectionManager.isConnected()?this.connectionManager.send(f.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_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;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(f.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(f.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 n=this._assistantSnapshotPending.get(e);if(n&&"DONE"!==t.type)n.events.push(t);else{if("PHASE"===t.type){const n=this._assistantSlot(e,s),i="number"==typeof t.createdAt?t.createdAt:null;if(n&&null!==i&&i<=(n.phaseUpdatedAt||0))return void this.logger.debug(`Stale assistant PHASE ignored: room=${e}, stream=${s}, createdAt=${i}, applied=${n.phaseUpdatedAt}`);const r=t.phase||null,o=n,a=this._setAssistantSlot(e,s,t,{phase:r,phaseUpdatedAt:null!==i?i:o?o.phaseUpdatedAt:0,text:o&&o.text||"",lastSeq:o?this._seqOf(o.lastSeq):-1,textAvailable:!o||!1!==o.textAvailable});return void this._emitAssistantStream(e,s,a,{active:!0,text:a.textAvailable&&a.text||null})}if("DELTA"===t.type){const n=this._assistantSlot(e,s),i=n&&n.phase||"WRITING",r="number"==typeof t.seq?t.seq:null;let o=n?this._seqOf(n.lastSeq):-1,a=!n||!1!==n.textAvailable,c=n&&n.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 l=this._setAssistantSlot(e,s,t,{phase:i,text:c,lastSeq:o,textAvailable:a});return void this._emitAssistantStream(e,s,l,{active:!0,text:l.textAvailable?l.text:null,delta:l.textAvailable&&t.delta||null,seq:r})}if("DONE"===t.type){const n=this._assistantSlot(e,s);n&&n.timer&&clearTimeout(n.timer),this._deleteAssistantSlot(e,s),this._tombstoneAssistantStream(e,s),this._emitAssistantStream(e,s,n,{active:!1,personaId:t.personaId||n&&n.personaId||null,phase: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 n=(async()=>{let s=null;try{const t=await this.apiClient.get(`/api/v1/rooms/${e}/assistant/streams`),n=this._unwrapSuccessResponse(t);s=n&&Array.isArray(n.streams)?n.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:n});try{await n}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,label:null,personaId:t.personaId||null,status:t.doneStatus||null,messageId:t.messageId||null,resumed:!0});const n=!1!==t.textAvailable,i=this._setAssistantSlot(e,s,{personaId:t.personaId,expiresAt:void 0},{phase:t.phase||null,phaseUpdatedAt:"number"==typeof t.phaseUpdatedAt?t.phaseUpdatedAt:0,text:n&&t.text||"",lastSeq:this._seqOf(t.lastSeq),textAvailable:n,resumed:!0});this._emitAssistantStream(e,s,i,{active:!0,text:i.textAvailable&&i.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 n=s.get(t);return void 0!==n&&(!(n<=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 n=Date.now();s.forEach((e,t)=>{e<=n&&s.delete(t)}),s.set(t,n+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,n){const i=this._assistantSlot(e,t);i&&i.timer&&clearTimeout(i.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||i&&i.personaId||null,phase:n.phase,phaseUpdatedAt:void 0!==n.phaseUpdatedAt?n.phaseUpdatedAt:i&&i.phaseUpdatedAt||0,text:n.text||"",lastSeq:this._seqOf(n.lastSeq),textAvailable:!1!==n.textAvailable,resumed:!0===n.resumed||!!i&&!0===i.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,label:null,reason:"timeout"}))}_emitAssistantStream(e,t,s,n){const i="phase"in n?n.phase:s?s.phase:null;this.emit("assistantProgress",{roomId:e,streamId:t,personaId:s?s.personaId:null,phase:i,label:i&&this._assistantPhaseLabels[i]||null,textAvailable:!s||s.textAvailable,lastSeq:s?s.lastSeq:-1,...n}),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,streams:[]};const[n,i]=s.reduce((e,t)=>t[1].order>e[1].order?t:e);return{roomId:e,active:!0,streamCount:s.length,streamId:n,personaId:i.personaId,phase:i.phase,label:i.phase&&this._assistantPhaseLabels[i.phase]||null,text:i.textAvailable&&i.text||null,textAvailable:i.textAvailable,streams:s.sort((e,t)=>e[1].order-t[1].order).map(([e,t])=>({streamId:e,personaId:t.personaId,phase:t.phase,label:t.phase&&this._assistantPhaseLabels[t.phase]||null,text:t.textAvailable&&t.text||null,textAvailable:t.textAvailable,resumed:!0===t.resumed}))}}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)}destroy(){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 Js extends e{constructor(e={}){super(),this.localStream=null,this.screenStream=null,this.videoEnabled=!0,this.audioEnabled=!0,this.logger=new S(e.logLevel||E.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}}},n=(await navigator.mediaDevices.getUserMedia(s)).getTracks()[0],i="video"===t?this.localStream.getVideoTracks()[0]:this.localStream.getAudioTracks()[0];return i&&(this.replaceTrack(i,n),this.emit("deviceSwitched",{kind:t,deviceId:e,newTrack:n}),this.logger.info(`${t} device switched to ${e}`)),n}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 qs extends e{constructor(e={}){super(),this.iceServers=e.iceServers||y.iceServers,this.logger=new S(e.logLevel||E.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 n={iceServers:this.iceServers,iceCandidatePoolSize:10},i=new RTCPeerConnection(n),r={connection:i,polite:t,makingOffer:!1,ignoreOffer:!1,isSettingRemoteAnswerPending:!1,skipAutoNegotiation:s.skipAutoNegotiation||!1};return this.peers.set(e,r),this._setupConnectionHandlers(e,i,r),this.localStream&&this._addTracksToConnection(i),this.logger.info(`Peer connection created: ${e} (polite: ${t}, skipAutoNegotiation: ${r.skipAutoNegotiation})`),i}_setupConnectionHandlers(e,t,n){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(n.skipAutoNegotiation)this.logger.debug(`Skipping auto negotiation for ${e} (manual offer will be sent)`);else try{n.makingOffer=!0,await t.setLocalDescription(),this.emit("negotiationNeeded",{peerId:e,description:t.localDescription})}catch(t){this.logger.error(`Negotiation error (${e}):`,t)}finally{n.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:n,polite:i,makingOffer:r}=s,o="offer"===t.type&&(r||"stable"!==n.signalingState);if(s.ignoreOffer=!i&&o,s.ignoreOffer)this.logger.debug(`Ignoring offer collision from ${e} (I am impolite)`);else try{if(o&&i&&(this.logger.debug(`Offer collision detected, rolling back local offer for ${e} (I am polite)`),await n.setLocalDescription({type:"rollback"})),s.isSettingRemoteAnswerPending="answer"===t.type,await n.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((n,i)=>{const r=n.connection.getSenders().find(t=>t.track&&t.track.kind===e.kind);r&&s.push(r.replaceTrack(t).then(()=>this.logger.debug(`Track replaced for ${i}`)).catch(e=>this.logger.error(`Failed to replace track for ${i}:`,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")}}class zs extends e{constructor(e){super(),this.connectionManager=e.connectionManager,this.apiClient=e.apiClient,this.userId=e.userId,this.logLevel=e.logLevel||E.WARN,this.logger=new S(this.logLevel,"WebRTCClient"),this.mediaManager=new Js({logLevel:this.logLevel}),this.peerManager=new qs({iceServers:e.iceServers||y.iceServers,logLevel:this.logLevel}),this.currentRoom=null,this.isGroupCall=!1,this.participants=new Map,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:n.ICE_CANDIDATE,receiverId:e,data:{candidate:t}})}),this.peerManager.on("negotiationNeeded",({peerId:e,description:t})=>{this._sendSignal({type:n.CALL_OFFER,receiverId:e,data:{sdp:t}})}),this.peerManager.on("answerCreated",({peerId:e,answer:t})=>{this._sendSignal({type:n.CALL_ANSWER,receiverId:e,data:{sdp:t}})})}async getTurnCredentials(){return(await this.apiClient.get("/api/v1/webrtc/turn-credentials")).data}async createCallRoom(e){return this.apiClient.post("/api/v1/webrtc/rooms",e)}async getCallRoom(e){return this.apiClient.get(`/api/v1/webrtc/rooms/${e}`)}async joinCallRoomApi(e){return this.apiClient.post(`/api/v1/webrtc/rooms/${e}/join`)}async leaveCallRoomApi(e){return this.apiClient.delete(`/api/v1/webrtc/rooms/${e}/leave`)}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=f.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:i=!1,mediaConstraints:r={video:!0,audio:!0}}=e;try{await this.initializeIceServers();const e=await this.mediaManager.getUserMedia(r);return this.peerManager.setLocalStream(e),this.currentRoom=t,this.isGroupCall=i,await this._subscribeToSignaling(t,i),this._sendSignal({type:n.JOIN_ROOM,roomId:t}),this.logger.info(`Call started in room: ${t}`),this.emit("callStarted",{roomId:t,isGroup:i,localStream:e}),e}catch(e){throw this.logger.error("Failed to start call:",e),this.emit("error",{type:s.PEER_CONNECTION_FAILED,message:e.message,error:e}),e}}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._waitingForCallAccept=!0,this._pendingCallTarget=e,this._sendSignal({type:n.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._sendSignal({type:n.CALL_ACCEPT,receiverId:e}),this.emit("callAccepted",{callerId:e})}catch(e){throw this.logger.error("Failed to accept call:",e),e}}rejectCall(e){this._sendSignal({type:n.CALL_REJECT,receiverId:e}),this.emit("callRejected",{callerId:e})}cancelCall(){this._waitingForCallAccept&&this._pendingCallTarget&&(this._sendSignal({type:n.CALL_CANCEL,receiverId:this._pendingCallTarget}),this.emit("callCancelled",{targetUserId:this._pendingCallTarget}),this._waitingForCallAccept=!1,this._pendingCallTarget=null,this.mediaManager.stopAll())}endCall(){this._waitingForCallAccept&&this._pendingCallTarget&&this._sendSignal({type:n.CALL_CANCEL,receiverId:this._pendingCallTarget}),this._waitingForCallAccept=!1,this._pendingCallTarget=null,this.currentRoom&&(this._sendSignal({type:n.LEAVE_ROOM,roomId:this.currentRoom}),this._unsubscribeFromSignaling()),this.peerManager.getPeerIds().forEach(e=>{this._sendSignal({type:n.CALL_END,receiverId:e})}),this.peerManager.closeAllPeerConnections(),this.mediaManager.stopAll(),this.participants.clear(),this._pendingIceCandidates.clear();const e=this.currentRoom;this.currentRoom=null,this.isGroupCall=!1,this.emit("callEnded",{roomId:e}),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),n=await this.mediaManager.switchDevice(e,t);return s&&await this.peerManager.replaceTrack(s,n),n}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=f.getWebRTCDestination(e);await this.connectionManager.subscribe(t,e=>{this._handleSignal(e)})}await this._subscribeToDirectSignaling()}async _subscribeToDirectSignaling(){const e=f.getWebRTCUserDestination();await this.connectionManager.subscribe(e,e=>{this._handleSignal(e)})}_unsubscribeFromSignaling(){if(this.currentRoom&&this.isGroupCall){const e=f.getWebRTCDestination(this.currentRoom);this.connectionManager.unsubscribe(e)}if(!this._incomingCallsEnabled){const e=f.getWebRTCUserDestination();this.connectionManager.unsubscribe(e)}}_sendSignal(e){const t={type:e.type,roomId:e.roomId||this.currentRoom,receiverId:e.receiverId,data:e.data};this.connectionManager.send(f.WEBRTC_SIGNAL,t),this.logger.debug("Signal sent:",t)}_sendMediaState(){if(!this.currentRoom&&0===this.peerManager.getPeerIds().length)return;const e={videoEnabled:this.mediaManager.isVideoEnabled(),audioEnabled:this.mediaManager.isAudioEnabled()};this._sendSignal({type:n.VIDEO_STATE_CHANGED,data:e}),this.emit("mediaStateChanged",e)}async _handleSignal(e){const{type:t,senderId:s,data:i}=e;if(s!==this.userId)switch(this.logger.debug(`Signal received: ${t} from ${s}`),t){case n.JOIN_ROOM:case n.PEER_JOINED:await this._handleUserJoined(s);break;case n.LEAVE_ROOM:case n.PEER_LEFT:this._handleUserLeft(s);break;case n.CALL_OFFER:await this._handleOffer(s,i.sdp);break;case n.CALL_ANSWER:await this._handleAnswer(s,i.sdp);break;case n.ICE_CANDIDATE:await this._handleIceCandidate(s,i.candidate);break;case n.VIDEO_STATE_CHANGED:case n.AUDIO_STATE_CHANGED:this._handleMediaState(s,i);break;case n.CALL_REQUEST:this.isInCall()||this._waitingForCallAccept?(this._sendSignal({type:n.CALL_BUSY,receiverId:s}),this.emit("incomingCallWhileBusy",{callerId:s})):this.emit("incomingCall",{callerId:s});break;case n.CALL_BUSY:this._waitingForCallAccept=!1,this._pendingCallTarget=null,this.mediaManager.stopAll(),this.emit("callBusy",{userId:s});break;case n.CALL_INVITATION:this.emit("callInvitation",{callRoomId:i?.callRoomId||e.roomId,title:i?.title,hostUserId:i?.hostUserId||s,maxParticipants:i?.maxParticipants,createdAt:i?.createdAt});break;case n.CALL_ACCEPT:await this._handleCallAccepted(s);break;case n.CALL_REJECT:this._waitingForCallAccept=!1,this._pendingCallTarget=null,this.mediaManager.stopAll(),this.emit("callRejected",{userId:s});break;case n.CALL_CANCEL:this._waitingForCallAccept=!1,this._pendingCallTarget=null,this.emit("callCancelled",{userId:s});break;case n.CALL_END:this._handleCallEnded(s);break;default:this.logger.warn(`Unknown signal type: ${t}`)}}async _handleUserJoined(e){this.participants.set(e,{joinedAt:new Date});const t=this.userId<e;this.peerManager.createPeerConnection(e,t),this.emit("userJoined",{userId:e}),this.logger.info(`User joined: ${e} (I am ${t?"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){if(!this.peerManager.getPeerConnection(e)){const t=this.userId<e;this.peerManager.createPeerConnection(e,t,{skipAutoNegotiation:!0})}await this.peerManager.handleRemoteDescription(e,t),await this._processPendingIceCandidates(e)}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._waitingForCallAccept=!1,this._pendingCallTarget=null,this.peerManager.createPeerConnection(e,!1,{skipAutoNegotiation:!0});const t=await this.peerManager.createOffer(e);this._sendSignal({type:n.CALL_OFFER,receiverId:e,data:{sdp:t}}),this.emit("callAccepted",{userId:e})}_handleCallEnded(e){this.peerManager.closePeerConnection(e),this.participants.delete(e),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.endCall(),this.mediaManager.destroy(),this.peerManager.destroy(),this.removeAllListeners(),this.logger.info("WebRTCClient destroyed")}}const Ks=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 Xs extends Error{constructor(e,t,s){super(t),this.name="PushError",this.code=e,void 0!==s&&(this.cause=s)}}const Ys={apiKey:"AIzaSyB8VhRg6rSvUI7K3Ua7h6sBpLvaQGmIkRc",authDomain:"chatting-c3e5d.firebaseapp.com",projectId:"chatting-c3e5d",storageBucket:"chatting-c3e5d.firebasestorage.app",messagingSenderId:"1020496565673",appId:"1:1020496565673:web:5039167257fd83f5ce20b8"},Qs="pendingNavigation",Zs="pending-room",en="deviceInfo",tn="device-id",sn="talkflow_device_id";function nn(){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(Qs)||e.createObjectStore(Qs,{keyPath:"id"}),e.objectStoreNames.contains(en)||e.createObjectStore(en,{keyPath:"id"})},s.onsuccess=()=>e(s.result),s.onerror=()=>t(s.error||new Error("IndexedDB open failed"))})}function rn(){return nn().then(e=>e?new Promise((t,s)=>{const n=e.transaction(en,"readonly"),i=n.objectStore(en).get(tn);i.onsuccess=()=>{const e=i.result;t(e&&e.value?e.value:null)},i.onerror=()=>s(i.error||new Error("IndexedDB read failed")),n.oncomplete=()=>e.close(),n.onerror=()=>e.close(),n.onabort=()=>e.close()}):null)}function on(e){return nn().then(t=>!!t&&new Promise(s=>{try{const n=t.transaction(en,"readwrite");n.objectStore(en).put({id:tn,value:e}),n.oncomplete=()=>{t.close(),s(!0)},n.onerror=()=>{t.close(),s(!1)},n.onabort=()=>{t.close(),s(!1)}}catch(e){try{t.close()}catch(e){}s(!1)}})).catch(()=>!1)}function an(){return"web-"+("undefined"!=typeof crypto&&crypto.randomUUID?crypto.randomUUID():Date.now().toString(36)+Math.random().toString(36).substring(2))}async function cn(e){const t=await nn();if(!t)return null;const s=function(e){return e&&"string"==typeof e&&""!==e.trim()?"pending-room:"+e:Zs}(e),n=!!e&&s!==Zs;return new Promise((i,r)=>{const o=t.transaction(Qs,"readwrite"),a=o.objectStore(Qs);let c=null;const l=a.get(s);l.onsuccess=()=>{const t=l.result;if(t&&t.roomId){if((t.projectId||null)===(e||null))return c=t.roomId,void a.delete(s)}if(!n)return;const i=a.get(Zs);i.onsuccess=()=>{const e=i.result;e&&e.roomId&&!e.projectId&&(c=e.roomId,a.delete(Zs))}},l.onerror=()=>{r(l.error||new Error("IndexedDB read failed"))},o.oncomplete=()=>{t.close(),i(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 ln{constructor(e){this.apiClient=e.apiClient,this.projectId=e.projectId||null,this.firebaseConfig=e.firebaseConfig||Ys,this.vapidKey=e.vapidKey||"BGP8qaSm1ntjWd4n9pc0lX_rw4BmMxm9u4pvRIANCitbmYaV0iy-gn05suTKBo88kUBejxdxM8sb6x2nt3avu8c",this.serviceWorkerPath=e.serviceWorkerPath||"/firebase-messaging-sw.js",this.logger=new S(e.logLevel||E.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 cn(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 Xs(Ks.UNSUPPORTED_BROWSER,"푸시 알림은 브라우저 환경에서만 사용 가능합니다");if(!("serviceWorker"in navigator))throw new Xs(Ks.UNSUPPORTED_BROWSER,"이 브라우저는 서비스 워커를 지원하지 않습니다");if("denied"===Notification.permission)throw new Xs(Ks.PERMISSION_DENIED,"알림 권한이 이미 거부되어 있습니다. 브라우저 사이트 설정에서 허용해주세요.");let e,t,s;try{e=await import("firebase/app"),t=await import("firebase/messaging")}catch(e){throw new Xs(Ks.FIREBASE_NOT_INSTALLED,"firebase 패키지가 설치되지 않았습니다. npm install firebase 를 실행하세요.",e)}try{s=e.getApp("talkflow")}catch{s=e.initializeApp(this.firebaseConfig,"talkflow")}const n=await this._registerServiceWorker();if("granted"!==("granted"===Notification.permission?"granted":await Notification.requestPermission()))throw new Xs(Ks.PERMISSION_DENIED,"알림 권한이 거부되었습니다. 브라우저 설정에서 허용해주세요.");this._messaging=t.getMessaging(s);const i={serviceWorkerRegistration:n};this.vapidKey&&(i.vapidKey=this.vapidKey);try{this._currentToken=await t.getToken(this._messaging,i)}catch(e){throw new Xs(Ks.TOKEN_FAILED,"FCM 토큰 획득 중 오류 발생: "+(e?.message||e),e)}if(!this._currentToken)throw new Xs(Ks.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=n,await this._registerProjectToSW(),this._installVisibilityReRegister();try{await n.update()}catch(e){this.logger.debug("SW 업데이트 체크 실패 (무시):",e.message)}const r=await this._getSWVersion(n);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 Xs(Ks.SW_REGISTER_FAILED,`서비스 워커 등록 실패: ${this.serviceWorkerPath}\n프로젝트 public 폴더에 firebase-messaging-sw.js 파일을 배치하세요.`,e)}}async _registerTokenToServer(e){try{const t=await this._getDeviceId();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 Xs)throw e;throw new Xs(Ks.SERVER_REGISTER_FAILED,"디바이스 토큰 서버 등록 실패: "+(e?.message||e),e)}}async _getDeviceId(){if(this._deviceIdCache)return this._deviceIdCache;try{let e=await rn();if(!e&&"undefined"!=typeof localStorage){const t=localStorage.getItem(sn);if(t){e=t;if(await on(e)){if(await rn()===e)try{localStorage.removeItem(sn),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=an();await on(e)||this.logger.warn("신규 deviceId IDB 저장 실패, 이번 세션만 유효")}return this._deviceIdCache=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(sn)}catch(e){}this._deviceIdCache=e||an()}return this._deviceIdCache}}_onForegroundMessage(e){}async consumePendingRoom(){return ln.consumePendingRoom(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),n=new MessageChannel;n.port1.onmessage=s=>{clearTimeout(t),e(s.data?.version||null)};try{s.postMessage({type:"TALKFLOW_SW_VERSION"},[n.port2])}catch(s){clearTimeout(t),e(null)}}):null}catch{return null}}setLogLevel(e){this.logger.setLevel(e)}}const hn=[["connected","connected"],["disconnected","disconnected"],["reconnecting","reconnecting"],["reconnected","reconnected"],["resumed","resumed"],["error","connectionError"]],dn=[["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"],["roomListCreated","roomListCreated"],["roomListJoined","roomListJoined"],["roomListLeft","roomListLeft"],["roomListSelfLeft","roomListSelfLeft"],["roomListKicked","roomListKicked"],["roomListSelfKicked","roomListSelfKicked"],["roomListBanned","roomListBanned"],["roomListSelfBanned","roomListSelfBanned"],["roomListRoomUpdated","roomListRoomUpdated"],["roomListUnreadUpdated","roomListUnreadUpdated"],["retentionCleanup","retentionCleanup"]],un=[["localStreamStarted","localStreamStarted"],["localStreamStopped","localStreamStopped"],["remoteTrack","remoteTrack"],["screenShareStarted","screenShareStarted"],["screenShareEnded","screenShareEnded"],["deviceChange","deviceChange"],["mediaStateChanged","mediaStateChanged"],["callStarted","callStarted"],["callEnded","callEnded"],["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 pn(e,t,s){s.forEach(([s,n])=>{e.on(s,e=>{t.emit(n,e)})})}const gn=["getRooms","getRoom","getRoomInfo","setMyRoomLanguage","createOneToOneRoom","createGroupRoom","joinGroupRoom","leaveRoom","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","getSubscribedRooms","isSubscribed","startTyping","stopTyping","getAssistantProgress","resumeAssistantStreams","getAssistants","getRoomAiMeta","rateAssistantMessage","summarizeWithAssistant","translateWithAssistant","refreshSummary","getSummary","getRoomPmPrompt","upsertRoomPmPrompt","activateRoomPmPrompt","deactivateRoomPmPrompt","getRoomPmPromptVersions","activateRoomPmPromptVersion","previewRoomPmPrompt","createVote","getVotes","getVote","updateVote","deleteVote","closeVote","submitVote","uploadVoteImage"],mn=["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 fn(e,t,s){s.forEach(s=>{e[s]=function(...e){return this[t][s](...e)}})}class _n extends e{constructor(e){super(),this._validateOptions(e);const s=e.env||y.environment,n=(e.serverUrl||v(s)).replace(/\/$/,"");this.options={serverUrl:n,env:s,apiKey:e.apiKey,projectId:e.projectId,jwtToken:e.jwtToken||null,useSockJS:!1!==e.useSockJS,reconnectDelay:e.reconnectDelay||y.reconnectDelay,maxReconnectDelay:e.maxReconnectDelay||y.maxReconnectDelay,maxReconnectAttempts:e.maxReconnectAttempts||y.maxReconnectAttempts,heartbeatIncoming:e.heartbeatIncoming||y.heartbeatIncoming,heartbeatOutgoing:e.heartbeatOutgoing||y.heartbeatOutgoing,resumeOnVisibility:!1!==e.resumeOnVisibility,syncOnReconnect:!1!==e.syncOnReconnect,assistantStreamReplay:!1!==e.assistantStreamReplay,rewindMillis:void 0!==e.rewindMillis?e.rewindMillis:y.rewindMillis,maxSyncPages:e.maxSyncPages||y.maxSyncPages,syncPageSize:e.syncPageSize||y.syncPageSize,iceServers:e.iceServers||y.iceServers,autoSubscribeRoomList:!1!==e.autoSubscribeRoomList,logLevel:void 0!==e.logLevel?e.logLevel:E.WARN},this.logger=new S(this.options.logLevel,"TalkFlowClient"),this._initialized=!1,this._state=t.DISCONNECTED,this._userId=null,this.options.jwtToken&&(this._userId=A(this.options.jwtToken)),this.apiClient=new w({baseUrl:this.options.serverUrl,apiKey:this.options.apiKey,projectId:this.options.projectId,jwtToken:this.options.jwtToken,logLevel:this.options.logLevel}),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,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)throw new Error("apiKey is required");if(!e.projectId)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 Hs({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,heartbeatIncoming:e.options.heartbeatIncoming,heartbeatOutgoing:e.options.heartbeatOutgoing,resumeOnVisibility:e.options.resumeOnVisibility,logLevel:e.options.logLevel}),e._chat=new Bs({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 zs({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(){var e;(e=this).connectionManager&&(e.connectionManager.on("stateChange",({state:t,prevState:s})=>{e._state=t,e.emit("stateChange",{state:t,prevState:s})}),pn(e.connectionManager,e,hn),e.chat&&pn(e.chat,e,dn),e.webrtc&&pn(e.webrtc,e,un))}isConnected(){return!!this.connectionManager&&this.connectionManager.isConnected()}getState(){return this._state}hasToken(){return!!this.options.jwtToken}static async loginUser({serverUrl:e,email:t,password:s}){if(!e)throw new Error("serverUrl is required");if(!t)throw new Error("email is required");if(!s)throw new Error("password is required");const n=new w({baseUrl:e,apiKey:"",projectId:""}),i=await n.post("/api/v1/auth/login",{email:t,password:s});return i&&i.data?i.data:i}async loginUser({email:e,password:t}){const s=await this.apiClient.post("/api/v1/auth/login",{email:e,password:t}),n=s&&s.data?s.data:s;return n&&n.accessToken&&(await this.setToken(n.accessToken),this.logger.info("Member logged in, token auto-set")),n}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}){return this._checkToken(),this.apiClient.put("/api/v1/me/password",{currentPassword:e,newPassword:t})}async updateMyInfo(e){this._checkToken();const t=await this.apiClient.put("/api/v1/users/update",e);if(t?.data?.accessToken)try{await this.setToken(t.data.accessToken)}catch(e){this.logger.warn("Profile updated but token refresh failed; keeping the old token",e)}return t}async setPreferredLanguage(e){return this.updateMyInfo({preferredLanguage:e})}static detectBrowserLanguage(){return"undefined"!=typeof navigator&&navigator.language?_n.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(),n=s.indexOf("-");if(n<0)return s;const i=s.slice(0,n);return"zh"===i?s:i}static displayText(e,t){const s=_n.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:n}=e;return this.apiClient.get("/api/v1/users",{size:t,lastId:s,lastSortValue:n})}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.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")}}_n.ConnectionState=t,_n.ErrorTypes=s,_n.LogLevel=E,_n.Environment=_,function(e){e.prototype.connect=async function(e,t={}){const{enablePush:s=!1}=t;if(e&&await this.setToken(e),!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(R(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.connectionManager&&(this.webrtc&&this.webrtc.isInCall()&&this.webrtc.endCall(),this.webrtc&&this.webrtc.disableIncomingCalls(),this.chat&&(this.chat.unsubscribeAllRooms(),this.chat.unsubscribeRoomList()),await this.connectionManager.disconnect(),this.logger.info("Disconnected from server"))},e.prototype.logout=async function(){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 ln({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);const n=this.chat?.getActiveRoom();if(n&&n===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 ln.consumePendingRoom(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 ln.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}=C(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(),await this.connectionManager.destroy(),this.pushManager&&(this.pushManager.reset(),this._pushEnablePromise=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.emit("tokenSet",{userId:t})},e.prototype.updateToken=async function(e){await this.setToken(e)}}(_n),function(e){fn(e.prototype,"chat",gn),fn(e.prototype,"webrtc",mn)}(_n);class bn{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 n=null==s?null:s,i=this._room(e);if(!(null!=i.snapshotVersion&&null==n||null!=i.snapshotVersion&&null!=n&&n<i.snapshotVersion||(i.snapshotCount=t,null!=n&&(i.snapshotVersion=n),null==n)))for(const[e,t]of i.pendingDeltas)(null==t.version||t.version<=n)&&i.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{h as AssistantMode,Bs as ChatClient,i as ChatMessageType,l as ChatRoomType,Hs as ConnectionManager,t as ConnectionState,r as DecisionCardLimits,y as DefaultConfig,b as Endpoints,u as EngagementIntensity,_ as Environment,s as ErrorTypes,e as EventEmitter,E as LogLevel,S as Logger,Js as MediaStreamManager,qs as PeerConnectionManager,a as PersonaRole,g as PmPromptLayerEditorType,p as PmPromptLayerScope,Xs as PushError,Ks as PushErrorCode,ln as PushManager,d as RoomAiType,m as RoomListEventType,bn as RoomUnreadReconciler,o as SenderType,n as SignalTypes,c as SummarizeFormat,zs as WebRTCClient,f as WebSocketPaths,O as decodeJWTPayload,_n as default,A as extractUserIdFromJWT,M as getJWTRemainingTime,v as getServerUrl,R as isJWTExpired,C 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=(...n)=>{this.off(e,s),t.apply(this,n)};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",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"},n={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"},i={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"},l={DIRECT:"DIRECT",GROUP:"GROUP",PRIVATE_GROUP:"PRIVATE_GROUP",TEAM:"TEAM"},h={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",MESSAGE_RETENTION_CLEANUP:"MESSAGE_RETENTION_CLEANUP",ROOM_UNREAD_UPDATED:"ROOM_UNREAD_UPDATED"},f={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",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"},_={DEVELOPMENT:"development",STAGING:"staging",PRODUCTION:"production"},b={[_.DEVELOPMENT]:{serverUrl:"https://dev-chat.apiorbit.net",wsEndpoint:"/ws-chat"},[_.STAGING]:{serverUrl:"https://stg-api.talk-x.app",wsEndpoint:"/ws-chat"},[_.PRODUCTION]:{serverUrl:"https://prod-api.talk-x.app",wsEndpoint:"/ws-chat"}},y={environment:_.PRODUCTION,reconnectDelay:5e3,maxReconnectDelay:3e4,maxReconnectAttempts:10,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(b[e]||b[_.PRODUCTION]).serverUrl}const E={DEBUG:0,INFO:1,WARN:2,ERROR:3,NONE:4};class S{constructor(e=E.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<=E.DEBUG&&console.debug(...this._format("DEBUG",...e))}info(...e){this.level<=E.INFO&&console.info(...this._format("INFO",...e))}warn(...e){this.level<=E.WARN&&console.warn(...this._format("WARN",...e))}error(...e){this.level<=E.ERROR&&console.error(...this._format("ERROR",...e))}}class w{constructor(e){this.baseUrl=e.baseUrl.replace(/\/$/,""),this.apiKey=e.apiKey,this.projectId=e.projectId,this.jwtToken=e.jwtToken,this.timeout=e.timeout||y.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,n={}){const{body:i,params:r,headers:o}=n;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,l=setTimeout(()=>c.abort(),this.timeout);let h;try{this.logger.debug(`${e} ${a}`,i?{body:i}:""),h=await fetch(a,{method:e,headers:o?{...this._getHeaders(),...o}:this._getHeaders(),body:i?JSON.stringify(i):void 0,signal:c.signal})}catch(t){if(clearTimeout(l),"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(l);const d=h.headers.get("content-type");let u;if(u=d&&d.includes("application/json")?await h.json():await h.text(),!h.ok){const t=new Error(u?.message||`HTTP ${h.status}`);throw t.code=s.API_ERROR,t.status=h.status,t.response=u,this.logger.error(`API Error: ${e} ${a}`,t),t}return this.logger.debug(`Response ${h.status}:`,u),u}get(e,t){return this.request("GET",e,{params:t})}post(e,t,s,n){return this.request("POST",e,{body:t,params:s,headers:n})}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})}upload(e,t,n={}){const{fieldName:i="file",onProgress:r,signal:o,timeout:a=6e5}=n;return new Promise((n,c)=>{const l=`${this.baseUrl}${e}`,h=new XMLHttpRequest,d=new FormData;d.append(i,t),h.open("POST",l),h.timeout=a,h.setRequestHeader("X-API-KEY",this.apiKey),h.setRequestHeader("X-PROJECT-ID",this.projectId),this.jwtToken&&h.setRequestHeader("Authorization",this.jwtToken.startsWith("Bearer ")?this.jwtToken:`Bearer ${this.jwtToken}`),"function"==typeof r&&(h.upload.onprogress=e=>{e.lengthComputable&&r({loaded:e.loaded,total:e.total,percent:Math.round(e.loaded/e.total*100)})});const u=()=>h.abort();if(o){if(o.aborted)return void c(new Error("Upload cancelled"));o.addEventListener("abort",u)}const p=()=>{o&&o.removeEventListener("abort",u)};h.onload=()=>{p();let e=h.responseText;if((h.getResponseHeader("content-type")||"").includes("application/json"))try{e=JSON.parse(h.responseText)}catch{}if(h.status>=200&&h.status<300)this.logger.debug(`Upload ${h.status}:`,e),n(e);else{const t=new Error(e?.message||`HTTP ${h.status}`);t.code=s.API_ERROR,t.status=h.status,t.response=e,this.logger.error(`Upload Error: POST ${l}`,t),c(t)}},h.onerror=()=>{p();const e=new Error("Network error during upload");e.code=s.API_ERROR,this.logger.error(`Upload Network Error: POST ${l}`,e),c(e)},h.ontimeout=()=>{p();const e=new Error("Upload timeout");e.code=s.API_TIMEOUT,this.logger.error(`Upload Timeout: POST ${l}`,e),c(e)},h.onabort=()=>{p(),c(new Error("Upload cancelled"))},this.logger.debug(`POST ${l} (multipart, ${t.size} bytes)`),h.send(d)})}}function I(e){return e&&"string"==typeof e?e.replace(/^Bearer\s+/i,""):""}function T(e){let t=e.replace(/-/g,"+").replace(/_/g,"/");const s=t.length%4;s&&(t+="=".repeat(4-s));const n=atob(t),i=Uint8Array.from(n,e=>e.charCodeAt(0));return(new TextDecoder).decode(i)}function C(e,t={}){const{bufferSeconds:n=30,validateExpiry:i=!0}=t;if(!e||"string"!=typeof e){const e=new Error("JWT token is required");throw e.code=s.JWT_INVALID,e}const r=I(e).split(".");if(3!==r.length){const e=new Error("Invalid JWT format: expected 3 parts separated by dots");throw e.code=s.JWT_INVALID,e}let o;try{o=JSON.parse(T(r[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(i&&o.exp){const e=1e3*o.exp,t=1e3*n,i=Date.now();if(e<i+t){const t=new Error(e<i?"JWT token expired":`JWT token expires within ${n} seconds`);throw t.code=s.JWT_EXPIRED,t.expiredAt=new Date(e).toISOString(),t}}if(o.iat){const e=6e4;if(1e3*o.iat>Date.now()+e){const e=new Error("JWT token issued in the future");throw e.code=s.JWT_INVALID,e}}const a=o.userId||o.sub||o.user_id;if(!a){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:a,payload:o}}function A(e){try{const t=I(e).split(".");if(3!==t.length)return null;const s=JSON.parse(T(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 R(e,t=0){try{const s=I(e).split(".");if(3!==s.length)return!0;const n=JSON.parse(T(s[1]));if(!n.exp)return!1;const i=1e3*n.exp,r=1e3*t;return i<Date.now()+r}catch(e){return console.error("Failed to check JWT expiration:",e),!0}}function M(e){try{const t=I(e).split(".");if(3!==t.length)return-1;const s=JSON.parse(T(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 O(e){try{const t=I(e).split(".");return 3!==t.length?null:JSON.parse(T(t[1]))}catch(e){return console.error("Failed to decode JWT payload:",e),null}}const N="\n",k="\0";class L{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:n,binaryBody:i,escapeHeaderValues:r,skipContentLengthHeader:o}=e;this.command=t,this.headers=Object.assign({},s||{}),i?(this._binaryBody=i,this.isBinaryBody=!0):(this._body=n||"",this.isBinaryBody=!1),this.escapeHeaderValues=r||!1,this.skipContentLengthHeader=o||!1}static fromRawFrame(e,t){const s={},n=e=>e.replace(/^\s+|\s+$/g,"");for(const i of e.headers.reverse()){i.indexOf(":");const r=n(i[0]);let o=n(i[1]);t&&"CONNECT"!==e.command&&"CONNECTED"!==e.command&&(o=L.hdrValueUnEscape(o)),s[r]=o}return new L({command:e.command,headers:s,binaryBody:e.binaryBody,escapeHeaderValues:t})}toString(){return this.serializeCmdAndHeaders()}serialize(){const e=this.serializeCmdAndHeaders();return this.isBinaryBody?L.toUnit8Array(e,this._binaryBody).buffer:e+this._body+k}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}:${L.hdrValueEscape(`${s}`)}`):e.push(`${t}:${s}`)}return(this.isBinaryBody||!this.isBodyEmpty()&&!this.skipContentLengthHeader)&&e.push(`content-length:${this.bodyLength()}`),e.join(N)+N+N}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),n=new Uint8Array([0]),i=new Uint8Array(s.length+t.length+n.length);return i.set(s),i.set(t,s.length),i.set(n,s.length+t.length),i}static marshall(e){return new L(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 D{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 P,x,U,$;!function(e){e[e.CONNECTING=0]="CONNECTING",e[e.OPEN=1]="OPEN",e[e.CLOSING=2]="CLOSING",e[e.CLOSED=3]="CLOSED"}(P||(P={})),function(e){e[e.ACTIVE=0]="ACTIVE",e[e.DEACTIVATING=1]="DEACTIVATING",e[e.INACTIVE=2]="INACTIVE"}(x||(x={})),function(e){e[e.LINEAR=0]="LINEAR",e[e.EXPONENTIAL=1]="EXPONENTIAL"}(U||(U={})),function(e){e.Interval="interval",e.Worker="worker"}($||($={}));class W{constructor(e,t=$.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===$.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 F{constructor(e){this.versions=e}supportedVersions(){return this.versions.join(",")}protocolVersions(){return this.versions.map(e=>`v${e.replace(".","")}.stomp`)}}F.V1_0="1.0",F.V1_1="1.1",F.V1_2="1.2",F.default=new F([F.V1_2,F.V1_1,F.V1_0]);class j{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===F.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,n=e,i=this,r=this._connectedVersion===F.V1_2?n.headers.ack:n.headers["message-id"];n.ack=(e={})=>i.ack(r,t,e),n.nack=(e={})=>i.nack(r,t,e),s(n)},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 D(e=>{const t=L.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!==F.V1_1&&e.version!==F.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 W(e,this._client.heartbeatStrategy,this.debug),this._pinger.start(()=>{this._webSocket.readyState===P.OPEN&&(this._webSocket.send(N),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!==P.CONNECTING&&this._webSocket.readyState!==P.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 n=new Date,i=Math.random().toString().substring(2,8),r=this.onclose;this.onclose=e=>{const s=(new Date).getTime()-n.getTime();t(`Discarded socket (#${i}) closed after ${s}ms, with code/reason: ${e.code}/${e.reason}`)},this.close(),r?.call(e,{code:4001,reason:`Quick discarding socket (#${i}) without waiting for the shutdown sequence.`,wasClean:!1})}),this._webSocket.terminate()}_transmit(e){const{command:t,headers:s,body:n,binaryBody:i,skipContentLengthHeader:r}=e,o=new L({command:t,headers:s,body:n,binaryBody:i,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!==P.CONNECTING&&this._webSocket.readyState!==P.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:n,binaryBody:i,skipContentLengthHeader:r}=e,o=Object.assign({destination:t},s);this._transmit({command:"SEND",headers:o,body:n,binaryBody:i,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 n=this;return{id:s.id,unsubscribe:e=>n.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===F.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===F.V1_2?s.id=e:s["message-id"]=e,s.subscription=t,this._transmit({command:"NACK",headers:s})}}class V{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===x.ACTIVE}_changeState(e){this.state=e,this.onChangeState(e)}constructor(e={}){this.stompVersions=F.default,this.connectionTimeout=0,this.reconnectDelay=5e3,this._nextReconnectDelay=0,this.maxReconnectDelay=9e5,this.reconnectTimeMode=U.LINEAR,this.heartbeatIncoming=1e4,this.heartbeatToleranceMultiplier=2,this.heartbeatOutgoing=1e4,this.heartbeatStrategy=$.Interval,this.splitLargeFrames=!1,this.maxWebSocketChunkSize=8192,this.forceBinaryWSFrames=!1,this.appendMissingNULLonIncoming=!1,this.discardWebsocketOnCommFailure=!1,this.state=x.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(x.ACTIVE),this._nextReconnectDelay=this.reconnectDelay,this._connect())};this.state===x.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 j(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===x.DEACTIVATING&&this._changeState(x.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===U.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 n;if(this.state===x.INACTIVE)return this.debug("Already INACTIVE, nothing more to do"),Promise.resolve();if(this._changeState(x.DEACTIVATING),this._nextReconnectDelay=0,this._reconnector&&(clearTimeout(this._reconnector),this._reconnector=void 0),!this._stompHandler||this.webSocket.readyState===P.CLOSED)return this._changeState(x.INACTIVE),Promise.resolve();{const e=this._stompHandler.onWebSocketClose;n=new Promise((t,s)=>{this._stompHandler.onWebSocketClose=s=>{e(s),t()}})}return t?this._stompHandler?.discardWebsocket():s&&this._disposeStompHandler(),n}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 H="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};function G(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var B,J,q,z,K,X,Y={exports:{}},Q={};function Z(){if(q)return J;q=1;var e=(B||(B=1,H.crypto&&H.crypto.getRandomValues?Q.randomBytes=function(e){var t=new Uint8Array(e);return H.crypto.getRandomValues(t),t}:Q.randomBytes=function(e){for(var t=new Array(e),s=0;s<e;s++)t[s]=Math.floor(256*Math.random());return t}),Q),t="abcdefghijklmnopqrstuvwxyz012345";return J={string:function(s){for(var n=e.randomBytes(s),i=[],r=0;r<s;r++)i.push(t.substr(n[r]%32,1));return i.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 ee(){return z||(z=1,function(e){var t=Z(),s={},n=!1,i=H.chrome&&H.chrome.app&&H.chrome.app.runtime;e.exports={attachEvent:function(e,t){void 0!==H.addEventListener?H.addEventListener(e,t,!1):H.document&&H.attachEvent&&(H.document.attachEvent("on"+e,t),H.attachEvent("on"+e,t))},detachEvent:function(e,t){void 0!==H.addEventListener?H.removeEventListener(e,t,!1):H.document&&H.detachEvent&&(H.document.detachEvent("on"+e,t),H.detachEvent("on"+e,t))},unloadAdd:function(e){if(i)return null;var r=t.string(8);return s[r]=e,n&&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]}};i||e.exports.attachEvent("unload",function(){n||(n=!0,e.exports.triggerUnloadCallbacks())})}(Y)),Y.exports}var te,se,ne,ie,re,oe={};function ae(){if(ne)return se;ne=1;var e=X?K:(X=1,K=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(te)return oe;te=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 oe.stringify=function(t,n){n=n||"";var i,r,o=[];for(r in"string"!=typeof n&&(n="?"),t)if(e.call(t,r)){if((i=t[r])||null!=i&&!isNaN(i)||(i=""),r=s(r),i=s(i),null===r||null===i)continue;o.push(r+"="+i)}return o.length?n+o.join("&"):""},oe.parse=function(e){for(var s,n=/([^=?#&]+)=?([^&]*)/g,i={};s=n.exec(e);){var r=t(s[1]),o=t(s[2]);null===r||null===o||r in i||(i[r]=o)}return i},oe}(),s=/^[\x00-\x20\u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]+/,n=/[\n\r\t]/g,i=/^[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 l=[["#","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]],h={hash:1,query:1};function d(e){var t,s=("undefined"!=typeof window?window:void 0!==H?H:"undefined"!=typeof self?self:{}).location||{},n={},r=typeof(e=e||s);if("blob:"===e.protocol)n=new g(unescape(e.pathname),{});else if("string"===r)for(t in n=new g(e,{}),h)delete n[t];else if("object"===r){for(t in e)t in h||(n[t]=e[t]);void 0===n.slashes&&(n.slashes=i.test(e.href))}return n}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(n,""),t=t||{};var s,i=o.exec(e),r=i[1]?i[1].toLowerCase():"",a=!!i[2],l=!!i[3],h=0;return a?l?(s=i[2]+i[3]+i[4],h=i[2].length+i[3].length):(s=i[2]+i[4],h=i[2].length):l?(s=i[3]+i[4],h=i[3].length):s=i[4],"file:"===r?h>=2&&(s=s.slice(2)):u(r)?s=i[4]:r?a&&(s=s.slice(2)):h>=2&&u(t.protocol)&&(s=i[4]),{protocol:r,slashes:a||u(r),slashesCount:h,rest:s}}function g(s,i,r){if(s=(s=c(s)).replace(n,""),!(this instanceof g))return new g(s,i,r);var o,h,m,f,_,b,y=l.slice(),v=typeof i,E=this,S=0;for("object"!==v&&"string"!==v&&(r=i,i=null),r&&"function"!=typeof r&&(r=t.parse),o=!(h=p(s||"",i=d(i))).protocol&&!h.slashes,E.slashes=h.slashes||o&&i.slashes,E.protocol=h.protocol||i.protocol||"",s=h.rest,("file:"===h.protocol&&(2!==h.slashesCount||a.test(s))||!h.slashes&&(h.protocol||h.slashesCount<2||!u(E.protocol)))&&(y[3]=[/(.*)/,"pathname"]);S<y.length;S++)"function"!=typeof(f=y[S])?(m=f[0],b=f[1],m!=m?E[b]=s:"string"==typeof m?~(_="@"===m?s.lastIndexOf(m):s.indexOf(m))&&("number"==typeof f[2]?(E[b]=s.slice(0,_),s=s.slice(_+f[2])):(E[b]=s.slice(_),s=s.slice(0,_))):(_=m.exec(s))&&(E[b]=_[1],s=s.slice(0,_.index)),E[b]=E[b]||o&&f[3]&&i[b]||"",f[4]&&(E[b]=E[b].toLowerCase())):s=f(s,E);r&&(E.query=r(E.query)),o&&i.slashes&&"/"!==E.pathname.charAt(0)&&(""!==E.pathname||""!==i.pathname)&&(E.pathname=function(e,t){if(""===e)return t;for(var s=(t||"/").split("/").slice(0,-1).concat(e.split("/")),n=s.length,i=s[n-1],r=!1,o=0;n--;)"."===s[n]?s.splice(n,1):".."===s[n]?(s.splice(n,1),o++):o&&(0===n&&(r=!0),s.splice(n,1),o--);return r&&s.unshift(""),"."!==i&&".."!==i||s.push(""),s.join("/")}(E.pathname,i.pathname)),"/"!==E.pathname.charAt(0)&&u(E.protocol)&&(E.pathname="/"+E.pathname),e(E.port,E.protocol)||(E.host=E.hostname,E.port=""),E.username=E.password="",E.auth&&(~(_=E.auth.indexOf(":"))?(E.username=E.auth.slice(0,_),E.username=encodeURIComponent(decodeURIComponent(E.username)),E.password=E.auth.slice(_+1),E.password=encodeURIComponent(decodeURIComponent(E.password))):E.username=encodeURIComponent(decodeURIComponent(E.auth)),E.auth=E.password?E.username+":"+E.password:E.username),E.origin="file:"!==E.protocol&&u(E.protocol)&&E.host?E.protocol+"//"+E.host:"null",E.href=E.toString()}return g.prototype={set:function(s,n,i){var o=this;switch(s){case"query":"string"==typeof n&&n.length&&(n=(i||t.parse)(n)),o[s]=n;break;case"port":o[s]=n,e(n,o.protocol)?n&&(o.host=o.hostname+":"+n):(o.host=o.hostname,o[s]="");break;case"hostname":o[s]=n,o.port&&(n+=":"+o.port),o.host=n;break;case"host":o[s]=n,r.test(n)?(n=n.split(":"),o.port=n.pop(),o.hostname=n.join(":")):(o.hostname=n,o.port="");break;case"protocol":o.protocol=n.toLowerCase(),o.slashes=!i;break;case"pathname":case"hash":if(n){var a="pathname"===s?"/":"#";o[s]=n.charAt(0)!==a?a+n:n}else o[s]=n;break;case"username":case"password":o[s]=encodeURIComponent(n);break;case"auth":var c=n.indexOf(":");~c?(o.username=n.slice(0,c),o.username=encodeURIComponent(decodeURIComponent(o.username)),o.password=n.slice(c+1),o.password=encodeURIComponent(decodeURIComponent(o.password))):o.username=encodeURIComponent(decodeURIComponent(n))}for(var h=0;h<l.length;h++){var d=l[h];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,n=this,i=n.host,o=n.protocol;o&&":"!==o.charAt(o.length-1)&&(o+=":");var a=o+(n.protocol&&n.slashes||u(n.protocol)?"//":"");return n.username?(a+=n.username,n.password&&(a+=":"+n.password),a+="@"):n.password?(a+=":"+n.password,a+="@"):"file:"!==n.protocol&&u(n.protocol)&&!i&&"/"!==n.pathname&&(a+="@"),(":"===i[i.length-1]||r.test(n.hostname)&&!n.port)&&(i+=":"),a+=i+n.pathname,(s="object"==typeof n.query?e(n.query):n.query)&&(a+="?"!==s.charAt(0)?"?"+s:s),n.hash&&(a+=n.hash),a}},g.extractProtocol=p,g.location=d,g.trimLeft=c,g.qs=t,se=g}function ce(){if(re)return ie;re=1;var e=ae();return ie={getOrigin:function(t){if(!t)return null;var s=new e(t);if("file:"===s.protocol)return null;var n=s.port;return n||(n="https:"===s.protocol?"443":"80"),s.protocol+"//"+s.hostname+":"+n},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 le,he={exports:{}};function de(){return le||(le=1,"function"==typeof Object.create?he.exports=function(e,t){t&&(e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}))}:he.exports=function(e,t){if(t){e.super_=t;var s=function(){};s.prototype=t.prototype,e.prototype=new s,e.prototype.constructor=e}}),he.exports}var ue,pe,ge,me={};function fe(){if(pe)return ue;function e(){this._listeners={}}return pe=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 n=s.indexOf(t);-1===n||(s.length>1?this._listeners[e]=s.slice(0,n).concat(s.slice(n+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 n=this._listeners[t],i=0;i<n.length;i++)n[i].apply(this,s)},ue=e}function _e(){if(ge)return me;ge=1;var e=de(),t=fe();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,n=!1;this.on(e,function i(){s.removeListener(e,i),n||(n=!0,t.apply(this,arguments))})},s.prototype.emit=function(){var e=arguments[0],t=this._listeners[e];if(t){for(var s=arguments.length,n=new Array(s-1),i=1;i<s;i++)n[i-1]=arguments[i];for(var r=0;r<t.length;r++)t[r].apply(this,n)}},s.prototype.on=s.prototype.addListener=t.prototype.addEventListener,s.prototype.removeListener=t.prototype.removeEventListener,me.EventEmitter=s,me}var be,ye,ve,Ee,Se,we,Ie,Te,Ce,Ae,Re,Me,Oe,Ne,ke,Le,De,Pe,xe,Ue,$e,We,Fe,je,Ve,He,Ge,Be,Je,qe,ze,Ke,Xe,Ye,Qe,Ze={exports:{}};function et(){if(ve)return ye;ve=1;var e=ee(),t=ce(),s=de(),n=_e().EventEmitter,i=function(){if(be)return Ze.exports;be=1;var e=H.WebSocket||H.MozWebSocket;return Ze.exports=e?function(t){return new e(t)}:void 0,Ze.exports}();function r(s,o,a){if(!r.enabled())throw new Error("Transport created when disabled");n.call(this);var c=this,l=t.addPath(s,"/websocket");l="https"===l.slice(0,5)?"wss"+l.slice(5):"ws"+l.slice(4),this.url=l,this.ws=new i(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,n),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!!i},r.transportName="websocket",r.roundTrips=2,ye=r}function tt(){if(Ce)return Te;Ce=1;var e=de(),t=ce(),s=function(){if(Se)return Ee;Se=1;var e=de(),t=_e().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)},Ee=s}(),n=function(){if(Ie)return we;Ie=1;var e=de(),t=_e().EventEmitter;function s(e,s,n){t.call(this),this.Receiver=e,this.receiveUrl=s,this.AjaxObject=n,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,n){e.pollIsClosing,e.poll=t=null,e.pollIsClosing||("network"===n?e._scheduleReceiver():(e.emit("close",s||1006,n),e.removeAllListeners()))})},s.prototype.abort=function(){this.removeAllListeners(),this.pollIsClosing=!0,this.poll&&this.poll.abort()},we=s}();function i(e,i,r,o,a){var c=t.addPath(e,i),l=this;s.call(this,e,r),this.poll=new n(o,c,a),this.poll.on("message",function(e){l.emit("message",e)}),this.poll.once("close",function(e,t){l.poll=null,l.emit("close",e,t),l.close()})}return e(i,s),i.prototype.close=function(){s.prototype.close.call(this),this.removeAllListeners(),this.poll&&(this.poll.abort(),this.poll=null)},Te=i}function st(){if(Re)return Ae;Re=1;var e=de(),t=ce(),s=tt();function n(e,n,i,r){s.call(this,e,n,function(e){return function(s,n,i){var r={};"string"==typeof n&&(r.headers={"Content-type":"text/plain"});var o=t.addPath(s,"/xhr_send"),a=new e("POST",o,n,r);return a.once("finish",function(e){if(a=null,200!==e&&204!==e)return i(new Error("http status "+e));i()}),function(){a.close(),a=null;var e=new Error("Aborted");e.code=1e3,i(e)}}}(r),i,r)}return e(n,s),Ae=n}function nt(){if(Oe)return Me;Oe=1;var e=de(),t=_e().EventEmitter;function s(e,s){t.call(this);var n=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){n._chunkHandler(e,t),n.xo=null;var s=200===e?"network":"permanent";n.emit("close",null,s),n._cleanup()})}return e(s,t),s.prototype._chunkHandler=function(e,t){if(200===e&&t)for(var s=-1;;this.bufferPosition+=s+1){var n=t.slice(this.bufferPosition);if(-1===(s=n.indexOf("\n")))break;var i=n.slice(0,s);i&&this.emit("message",i)}},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()},Me=s}function it(){if(ke)return Ne;ke=1;var e=_e().EventEmitter,t=de(),s=ee(),n=ce(),i=H.XMLHttpRequest;function r(t,s,n,i){var r=this;e.call(this),setTimeout(function(){r._start(t,s,n,i)},0)}t(r,e),r.prototype._start=function(e,t,o,a){var c=this;try{this.xhr=new i}catch(e){}if(!this.xhr)return this.emit("finish",0,"no xhr support"),void this._cleanup();t=n.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 l in a.headers)this.xhr.setRequestHeader(l,a.headers[l]);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=!!i;var o=["Active"].concat("Object").join("X");!r.enabled&&o in H&&(i=function(){try{return new H[o]("Microsoft.XMLHTTP")}catch(e){return null}},r.enabled=!!new i);var a=!1;try{a="withCredentials"in new i}catch(e){}return r.supportsCORS=a,Ne=r}function rt(){if(De)return Le;De=1;var e=de(),t=it();function s(e,s,n,i){t.call(this,e,s,n,i)}return e(s,t),s.enabled=t.enabled&&t.supportsCORS,Le=s}function ot(){if(xe)return Pe;xe=1;var e=de(),t=it();function s(e,s,n){t.call(this,e,s,n,{noCredentials:!0})}return e(s,t),s.enabled=t.enabled,Pe=s}function at(){return $e?Ue:($e=1,Ue={isOpera:function(){return H.navigator&&/opera/i.test(H.navigator.userAgent)},isKonqueror:function(){return H.navigator&&/konqueror/i.test(H.navigator.userAgent)},hasDomain:function(){if(!H.document)return!0;try{return!!H.document.domain}catch(e){return!1}}})}function ct(){if(Fe)return We;Fe=1;var e=de(),t=st(),s=nt(),n=rt(),i=ot(),r=at();function o(e){if(!i.enabled&&!n.enabled)throw new Error("Transport created when disabled");t.call(this,e,"/xhr_streaming",s,n)}return e(o,t),o.enabled=function(e){return!e.nullOrigin&&(!r.isOpera()&&n.enabled)},o.transportName="xhr-streaming",o.roundTrips=2,o.needBody=!!H.document,We=o}function lt(){if(Ve)return je;Ve=1;var e=_e().EventEmitter,t=de(),s=ee(),n=at(),i=ce();function r(t,s,n){var i=this;e.call(this),setTimeout(function(){i._start(t,s,n)},0)}return t(r,e),r.prototype._start=function(e,t,n){var r=this,o=new H.XDomainRequest;t=i.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(n)}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=!(!H.XDomainRequest||!n.hasDomain()),je=r}function ht(){if(Ge)return He;Ge=1;var e=de(),t=st(),s=nt(),n=lt();function i(e){if(!n.enabled)throw new Error("Transport created when disabled");t.call(this,e,"/xhr_streaming",s,n)}return e(i,t),i.enabled=function(e){return!e.cookie_needed&&!e.nullOrigin&&(n.enabled&&e.sameScheme)},i.transportName="xdr-streaming",i.roundTrips=2,He=i}function dt(){return Je?Be:(Je=1,Be=H.EventSource)}function ut(){if(Xe)return Ke;Xe=1;var e=de(),t=st(),s=function(){if(ze)return qe;ze=1;var e=de(),t=_e().EventEmitter,s=dt();function n(e){t.call(this);var n=this,i=this.es=new s(e);i.onmessage=function(e){e.data,n.emit("message",decodeURI(e.data))},i.onerror=function(e){i.readyState;var t=2!==i.readyState?"network":"permanent";n._cleanup(),n._close(t)}}return e(n,t),n.prototype.abort=function(){this._cleanup(),this._close("user")},n.prototype._cleanup=function(){var e=this.es;e&&(e.onmessage=e.onerror=null,e.close(),this.es=null)},n.prototype._close=function(e){var t=this;setTimeout(function(){t.emit("close",null,e),t.removeAllListeners()},200)},qe=n}(),n=rt(),i=dt();function r(e){if(!r.enabled())throw new Error("Transport created when disabled");t.call(this,e,"/eventsource",s,n)}return e(r,t),r.enabled=function(){return!!i},r.transportName="eventsource",r.roundTrips=2,Ke=r}function pt(){return Qe?Ye:(Qe=1,Ye="1.6.1")}var gt,mt,ft,_t,bt,yt,vt,Et,St,wt,It,Tt,Ct,At,Rt,Mt,Ot,Nt,kt,Lt,Dt,Pt,xt,Ut={exports:{}};function $t(){return gt||(gt=1,function(e){var t=ee(),s=at();e.exports={WPrefix:"_jp",currentWindowId:null,polluteGlobalNamespace:function(){e.exports.WPrefix in H||(H[e.exports.WPrefix]={})},postMessage:function(t,s){H.parent!==H&&H.parent.postMessage(JSON.stringify({windowId:e.exports.currentWindowId,type:t,data:s||""}),"*")},createIframe:function(e,s){var n,i,r=H.document.createElement("iframe"),o=function(){clearTimeout(n);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(i))},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(n),n=setTimeout(function(){c("onload timeout")},2e3)},H.document.body.appendChild(r),n=setTimeout(function(){c("timeout")},15e3),i=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,n){var i,r,o,a=["Active"].concat("Object").join("X"),c=new H[a]("htmlfile"),l=function(){clearTimeout(i),o.onerror=null},h=function(){c&&(l(),t.unloadDel(r),o.parentNode.removeChild(o),o=c=null,CollectGarbage())},d=function(e){c&&(h(),n(e))};c.open(),c.write('<html><script>document.domain="'+H.document.domain+'";<\/script></html>'),c.close(),c.parentWindow[e.exports.WPrefix]=H[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")},i=setTimeout(function(){d("timeout")},15e3),r=t.unloadAdd(h),{post:function(e,t){try{setTimeout(function(){o&&o.contentWindow&&o.contentWindow.postMessage(e,t)},0)}catch(e){}},cleanup:h,loaded:l}}},e.exports.iframeEnabled=!1,H.document&&(e.exports.iframeEnabled=("function"==typeof H.postMessage||"object"==typeof H.postMessage)&&!s.isKonqueror())}(Ut)),Ut.exports}function Wt(){if(ft)return mt;ft=1;var e=de(),t=_e().EventEmitter,s=pt(),n=ce(),i=$t(),r=ee(),o=Z();function a(e,s,c){if(!a.enabled())throw new Error("Transport created when disabled");t.call(this);var l=this;this.origin=n.getOrigin(c),this.baseUrl=c,this.transUrl=s,this.transport=e,this.windowId=o.string(8);var h=n.addPath(c,"/iframe.html")+"#"+this.windowId;this.iframeObj=i.createIframe(h,function(e){l.emit("close",1006,"Unable to load an iframe ("+e+")"),l.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,!n.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 i;try{i=JSON.parse(t.data)}catch(e){return void t.data}this.emit("close",i[0],i[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 i.iframeEnabled},a.transportName="iframe",a.roundTrips=2,mt=a}function Ft(){return bt||(bt=1,_t={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,n=1,i=arguments.length;n<i;n++)for(s in t=arguments[n])Object.prototype.hasOwnProperty.call(t,s)&&(e[s]=t[s]);return e}}),_t}function jt(){if(vt)return yt;vt=1;var e=de(),t=Wt(),s=Ft();return yt=function(n){function i(e,s){t.call(this,n.transportName,e,s)}return e(i,t),i.enabled=function(e,i){if(!H.document)return!1;var r=s.extend({},i);return r.sameOrigin=!0,n.enabled(r)&&t.enabled()},i.transportName="iframe-"+n.transportName,i.needBody=!0,i.roundTrips=t.roundTrips+n.roundTrips-1,i.facadeTransport=n,i},yt}function Vt(){if(It)return wt;It=1;var e=de(),t=function(){if(St)return Et;St=1;var e=de(),t=$t(),s=ce(),n=_e().EventEmitter,i=Z();function r(e){n.call(this);var o=this;t.polluteGlobalNamespace(),this.id="a"+i.string(6),e=s.addQuery(e,"c="+decodeURIComponent(t.WPrefix+"."+this.id)),r.htmlfileEnabled;var a=r.htmlfileEnabled?t.createHtmlfile:t.createIframe;H[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,n),r.prototype.abort=function(){this._cleanup(),this._close("user")},r.prototype._cleanup=function(){this.iframeObj&&(this.iframeObj.cleanup(),this.iframeObj=null),delete H[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 H)try{r.htmlfileEnabled=!!new H[o]("htmlfile")}catch(e){}return r.enabled=r.htmlfileEnabled||t.iframeEnabled,Et=r}(),s=ot(),n=st();function i(e){if(!t.enabled)throw new Error("Transport created when disabled");n.call(this,e,"/htmlfile",t,s)}return e(i,n),i.enabled=function(e){return t.enabled&&e.sameOrigin},i.transportName="htmlfile",i.roundTrips=2,wt=i}function Ht(){if(Ct)return Tt;Ct=1;var e=de(),t=st(),s=nt(),n=rt(),i=ot();function r(e){if(!i.enabled&&!n.enabled)throw new Error("Transport created when disabled");t.call(this,e,"/xhr",s,n)}return e(r,t),r.enabled=function(e){return!e.nullOrigin&&(!(!i.enabled||!e.sameOrigin)||n.enabled)},r.transportName="xhr-polling",r.roundTrips=2,Tt=r}function Gt(){if(Rt)return At;Rt=1;var e=de(),t=st(),s=ht(),n=nt(),i=lt();function r(e){if(!i.enabled)throw new Error("Transport created when disabled");t.call(this,e,"/xhr",n,i)}return e(r,t),r.enabled=s.enabled,r.transportName="xdr-polling",r.roundTrips=2,At=r}function Bt(){if(kt)return Nt;kt=1;var e,t,s=Z(),n=ce();return Nt=function(i,r,o){e||((e=H.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=H.document.createElement("textarea")).name="d",e.appendChild(t),H.document.body.appendChild(e));var a="a"+s.string(8);e.target=a,e.action=n.addQuery(n.addPath(i,"/jsonp_send"),"i="+a);var c=function(e){try{return H.document.createElement('<iframe name="'+e+'">')}catch(s){var t=H.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 l=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(){l()},c.onload=function(){l()},c.onreadystatechange=function(e){c.readyState,"complete"===c.readyState&&l()},function(){l(new Error("Aborted"))}},Nt}function Jt(){if(Dt)return Lt;Dt=1;var e=de(),t=tt(),s=function(){if(Ot)return Mt;Ot=1;var e=$t(),t=Z(),s=at(),n=ce(),i=de(),r=_e().EventEmitter;function o(s){var i=this;r.call(this),e.polluteGlobalNamespace(),this.id="a"+t.string(6);var a=n.addQuery(s,"c="+encodeURIComponent(e.WPrefix+"."+this.id));H[e.WPrefix][this.id]=this._callback.bind(this),this._createScript(a),this.timeoutId=setTimeout(function(){i._abort(new Error("JSONP script loaded abnormally (timeout)"))},o.timeout)}return i(o,r),o.prototype.abort=function(){if(H[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 H[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 n,i=this,r=this.script=H.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(){i._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){i.loadedOkay=!0;try{r.onclick()}catch(e){}}r&&i._abort(new Error("JSONP script loaded abnormally (onreadystatechange)"))}},void 0===r.async&&H.document.attachEvent)if(s.isOpera())(n=this.script2=H.document.createElement("script")).text="try{var a = document.getElementById('"+r.id+"'); if(a)a.onerror();}catch(x){};",r.async=n.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=H.document.getElementsByTagName("head")[0];o.insertBefore(r,o.firstChild),n&&o.insertBefore(n,o.firstChild)},Mt=o}(),n=Bt();function i(e){if(!i.enabled())throw new Error("Transport created when disabled");t.call(this,e,"/jsonp",n,s)}return e(i,t),i.enabled=function(){return!!H.document},i.transportName="jsonp-polling",i.roundTrips=1,i.needBody=!0,Lt=i}function qt(){return xt?Pt:(xt=1,Pt=[et(),ct(),ht(),ut(),jt()(ut()),Vt(),jt()(Vt()),Ht(),Gt(),jt()(Ht()),Jt()])}var zt,Kt,Xt,Yt,Qt,Zt,es,ts,ss,ns,is,rs,os,as,cs,ls,hs,ds,us,ps,gs,ms,fs,_s,bs,ys,vs,Es,Ss,ws,Is,Ts,Cs,As={};function Rs(){if(zt)return As;zt=1;var e,t=Array.prototype,s=Object.prototype,n=Function.prototype,i=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)},l=Object.defineProperty&&function(){try{return Object.defineProperty({},"x",{}),!0}catch(e){return!1}}();e=l?function(e,t,s,n){!n&&t in e||Object.defineProperty(e,t,{configurable:!0,enumerable:!1,writable:!0,value:s})}:function(e,t,s,n){!n&&t in e||(e[t]=s)};var h=function(t,n,i){for(var r in n)s.hasOwnProperty.call(n,r)&&e(t,r,n[r],i)},d=function(e){if(null==e)throw new TypeError("can't convert "+e+" to object");return Object(e)};function u(){}h(n,{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),n=Math.max(0,t.length-s.length),i=[],o=0;o<n;o++)i.push("$"+o);var c=Function("binder","return function ("+i.join(",")+"){ return binder.apply(this, arguments); }")(function(){if(this instanceof c){var n=t.apply(this,s.concat(r.call(arguments)));return Object(n)===n?n: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}}),h(Array,{isArray:function(e){return"[object Array]"===o.call(e)}});var p,g,m,f=Object("a"),_="a"!==f[0]||!(0 in f);h(t,{forEach:function(e){var t=d(this),s=_&&c(this)?this.split(""):t,n=arguments[1],i=-1,r=s.length>>>0;if(!a(e))throw new TypeError;for(;++i<r;)i in s&&e.call(n,s[i],i,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 b=Array.prototype.indexOf&&-1!==[0,1].indexOf(1,2);h(t,{indexOf:function(e){var t=_&&c(this)?this.split(""):d(this),s=t.length>>>0;if(!s)return-1;var n,i=0;for(arguments.length>1&&((n=+arguments[1])!=n?n=0:0!==n&&n!==1/0&&n!==-1/0&&(n=(n>0||-1)*Math.floor(Math.abs(n))),i=n),i=i>=0?i:Math.max(0,s+i);i<s;i++)if(i in t&&t[i]===e)return i;return-1}},b);var y,v=i.split;2!=="ab".split(/(?:ab)*/).length||4!==".".split(/(.?)(.?)/).length||"t"==="tesst".split(/(s)*/)[1]||4!=="test".split(/(?:)/,-1).length||"".split(/.?/).length||".".split(/()()/).length>1?(y=void 0===/()??/.exec("")[1],i.split=function(e,s){var n=this;if(void 0===e&&0===s)return[];if("[object RegExp]"!==o.call(e))return v.call(this,e,s);var i,r,a,c,l=[],h=(e.ignoreCase?"i":"")+(e.multiline?"m":"")+(e.extended?"x":"")+(e.sticky?"y":""),d=0;for(e=new RegExp(e.source,h+"g"),n+="",y||(i=new RegExp("^"+e.source+"$(?!\\s)",h)),s=void 0===s?-1>>>0:s>>>0;(r=e.exec(n))&&!((a=r.index+r[0].length)>d&&(l.push(n.slice(d,r.index)),!y&&r.length>1&&r[0].replace(i,function(){for(var e=1;e<arguments.length-2;e++)void 0===arguments[e]&&(r[e]=void 0)}),r.length>1&&r.index<n.length&&t.push.apply(l,r.slice(1)),c=r[0].length,d=a,l.length>=s));)e.lastIndex===r.index&&e.lastIndex++;return d===n.length?!c&&e.test("")||l.push(""):l.push(n.slice(d)),l.length>s?l.slice(0,s):l}):"0".split(void 0,0).length&&(i.split=function(e,t){return void 0===e&&0===t?[]:v.call(this,e,t)});var E=i.substr,S="".substr&&"b"!=="0b".substr(-1);return h(i,{substr:function(e,t){return E.call(this,e<0&&(e=this.length+e)<0?0:e,t)}},S),As}function Ms(){if(Xt)return Kt;Xt=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 Kt={quote:function(s){var n=JSON.stringify(s);return t.lastIndex=0,t.test(n)?(e||(e=function(e){var t,s={},n=[];for(t=0;t<65536;t++)n.push(String.fromCharCode(t));return e.lastIndex=0,n.join("").replace(e,function(e){return s[e]="\\u"+("0000"+e.charCodeAt(0).toString(16)).slice(-4),""}),e.lastIndex=0,s}(t)),n.replace(t,function(t){return e[t]})):n}}}function Os(){if(Qt)return Yt;Qt=1;return Yt=function(e){return{filterToEnabled:function(t,s){var n={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,n.main.push(e),e.facadeTransport&&n.facade.push(e.facadeTransport)):e.transportName))}),n}}}}function Ns(){if(es)return Zt;es=1;var e={};return["log","debug","warn"].forEach(function(t){var s;try{s=H.console&&H.console[t]&&H.console[t].apply}catch(e){}e[t]=s?function(){return H.console[t].apply(H.console,arguments)}:"log"===t?function(){}:e.log}),Zt=e}function ks(){if(ss)return ts;function e(e){this.type=e}return ss=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,ts=e}function Ls(){return is?ns:(is=1,ns=H.location||{origin:"http://localhost:80",protocol:"http:",host:"localhost",port:80,href:"http://localhost/",hash:""})}function Ds(){if(us)return ds;us=1;var e=_e().EventEmitter,t=de(),s=Ft();function n(t,n){e.call(this);var i=this,r=+new Date;this.xo=new n("GET",t),this.xo.once("finish",function(e,t){var n,o;if(200===e){if(o=+new Date-r,t)try{n=JSON.parse(t)}catch(e){}s.isObject(n)||(n={})}i.emit("finish",n,o),i.removeAllListeners()})}return t(n,e),n.prototype.close=function(){this.removeAllListeners(),this.xo.close()},ds=n}function Ps(){if(gs)return ps;gs=1;var e=de(),t=_e().EventEmitter,s=ot(),n=Ds();function i(e){var i=this;t.call(this),this.ir=new n(e,s),this.ir.once("finish",function(e,t){i.ir=null,i.emit("message",JSON.stringify([e,t]))})}return e(i,t),i.transportName="iframe-info-receiver",i.prototype.close=function(){this.ir&&(this.ir.close(),this.ir=null),this.removeAllListeners()},ps=i}function xs(){if(bs)return _s;bs=1;var e=_e().EventEmitter,t=de(),s=ce(),n=lt(),i=rt(),r=ot(),o=function(){if(hs)return ls;hs=1;var e=_e().EventEmitter;function t(){var s=this;e.call(this),this.to=setTimeout(function(){s.emit("finish",200,"{}")},t.timeout)}return de()(t,e),t.prototype.close=function(){clearTimeout(this.to)},t.timeout=2e3,ls=t}(),a=function(){if(fs)return ms;fs=1;var e=_e().EventEmitter,t=de(),s=ee(),n=Wt(),i=Ps();function r(t,r){var o=this;e.call(this);var a=function(){var e=o.ifr=new n(i.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],n=t[1];o.emit("finish",s,n)}o.close()}),e.once("close",function(){o.emit("finish"),o.close()})};H.document.body?a():s.attachEvent("load",a)}return t(r,e),r.enabled=function(){return n.enabled()},r.prototype.close=function(){this.ifr&&this.ifr.close(),this.removeAllListeners(),this.ifr=null},ms=r}(),c=Ds();function l(t,s){var n=this;e.call(this),setTimeout(function(){n.doXhr(t,s)},0)}return t(l,e),l._getReceiver=function(e,t,s){return s.sameOrigin?new c(t,r):i.enabled?new c(t,i):n.enabled&&s.sameScheme?new c(t,n):a.enabled()?new a(e,t):new c(t,o)},l.prototype.doXhr=function(e,t){var n=this,i=s.addPath(e,"/info");this.xo=l._getReceiver(e,i,t),this.timeoutRef=setTimeout(function(){n._cleanup(!1),n.emit("finish")},l.timeout),this.xo.once("finish",function(e,t){n._cleanup(!0),n.emit("finish",e,t)})},l.prototype._cleanup=function(e){clearTimeout(this.timeoutRef),this.timeoutRef=null,!e&&this.xo&&this.xo.close(),this.xo=null},l.prototype.close=function(){this.removeAllListeners(),this._cleanup(!1)},l.timeout=8e3,_s=l}function Us(){if(Ss)return Es;Ss=1;var e=ce(),t=ee(),s=function(){if(vs)return ys;vs=1;var e=$t();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()},ys=t}(),n=Ps(),i=$t(),r=Ls();return Es=function(o,a){var c,l={};a.forEach(function(e){e.facadeTransport&&(l[e.facadeTransport.transportName]=e.facadeTransport)}),l[n.transportName]=n,o.bootstrap_iframe=function(){var n;i.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===i.currentWindowId)switch(a.type){case"s":var h;try{h=JSON.parse(a.data)}catch(e){a.data;break}var d=h[0],u=h[1],p=h[2],g=h[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+")");n=new s(new l[u](p,g));break;case"m":n._send(a.data);break;case"c":n&&n._close(),n=null}}}),i.postMessage("s")}},Es}function $s(){if(Is)return ws;Is=1,Rs();var e,t=ae(),s=de(),n=Z(),i=Ms(),r=ce(),o=ee(),a=Os(),c=Ft(),l=at(),h=Ns(),d=ks(),u=fe(),p=Ls(),g=function(){if(os)return rs;os=1;var e=de(),t=ks();function s(){t.call(this),this.initEvent("close",!1,!1),this.wasClean=!1,this.code=0,this.reason=""}return e(s,t),rs=s}(),m=function(){if(cs)return as;cs=1;var e=de(),t=ks();function s(e){t.call(this),this.initEvent("message",!1,!1),this.data=e}return e(s,t),as=s}(),f=xs(),_=function(){};function b(e,s,i){if(!(this instanceof b))return new b(e,s,i);if(arguments.length<1)throw new TypeError("Failed to construct 'SockJS: 1 argument required, but only 0 present");u.call(this),this.readyState=b.CONNECTING,this.extensions="",this.protocol="",(i=i||{}).protocols_whitelist&&h.warn("'protocols_whitelist' is DEPRECATED. Use 'transports' instead."),this._transportsWhitelist=i.transports,this._transportOptions=i.transportOptions||{},this._timeout=i.timeout||0;var o=i.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 n.string(o)}}this._server=i.server||n.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:!l.hasDomain(),sameOrigin:r.isOriginEqual(this.url,p.href),sameScheme:r.isSchemeEqual(this.url,p.href)},this._ir=new f(this.url,this._urlInfo),this._ir.once("finish",this._receiveInfo.bind(this))}function y(e){return 1e3===e||e>=3e3&&e<=4999}return s(b,u),b.prototype.close=function(e,t){if(e&&!y(e))throw new Error("InvalidAccessError: Invalid code");if(t&&t.length>123)throw new SyntaxError("reason argument has an invalid length");if(this.readyState!==b.CLOSING&&this.readyState!==b.CLOSED){this._close(e||1e3,t||"Normal closure",!0)}},b.prototype.send=function(e){if("string"!=typeof e&&(e=""+e),this.readyState===b.CONNECTING)throw new Error("InvalidStateError: The connection has not been established yet");this.readyState===b.OPEN&&this._transport.send(i.quote(e))},b.version=pt(),b.CONNECTING=0,b.OPEN=1,b.CLOSING=2,b.CLOSED=3,b.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 n=e.filterToEnabled(this._transportsWhitelist,t);this._transports=n.main,this._transports.length,this._connect()}else this._close(1002,"Cannot connect to server")},b.prototype._connect=function(){for(var e=this._transports.shift();e;e=this._transports.shift()){if(_(e.transportName),e.needBody&&(!H.document.body||void 0!==H.document.readyState&&"complete"!==H.document.readyState&&"interactive"!==H.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()),n=this._transportOptions[e.transportName],i=new e(s,this._transUrl,n);return i.on("message",this._transportMessage.bind(this)),i.once("close",this._transportClose.bind(this)),i.transportName=e.transportName,void(this._transport=i)}this._close(2e3,"All transports failed",!1)},b.prototype._transportTimeout=function(){this.readyState===b.CONNECTING&&(this._transport&&this._transport.close(),this._transportClose(2007,"Transport timed out"))},b.prototype._transportMessage=function(e){var t,s=this,n=e.slice(0,1),i=e.slice(1);switch(n){case"o":return void this._open();case"h":return this.dispatchEvent(new d("heartbeat")),void this.transport}if(i)try{t=JSON.parse(i)}catch(e){}if(void 0!==t)switch(n){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)}},b.prototype._transportClose=function(e,t){this.transport,this._transport&&(this._transport.removeAllListeners(),this._transport=null,this.transport=null),y(e)||2e3===e||this.readyState!==b.CONNECTING?this._close(e,t):this._connect()},b.prototype._open=function(){this._transport&&this._transport.transportName,this.readyState,this.readyState===b.CONNECTING?(this._transportTimeoutId&&(clearTimeout(this._transportTimeoutId),this._transportTimeoutId=null),this.readyState=b.OPEN,this.transport=this._transport.transportName,this.dispatchEvent(new d("open")),this.transport):this._close(1006,"Server lost session")},b.prototype._close=function(e,t,s){this.transport,this.readyState;var n=!1;if(this._ir&&(n=!0,this._ir.close(),this._ir=null),this._transport&&(this._transport.close(),this._transport=null,this.transport=null),this.readyState===b.CLOSED)throw new Error("InvalidStateError: SockJS has already been closed");this.readyState=b.CLOSING,setTimeout(function(){this.readyState=b.CLOSED,n&&this.dispatchEvent(new d("error"));var i=new g("close");i.wasClean=s||!1,i.code=e||1e3,i.reason=t,this.dispatchEvent(i),this.onmessage=this.onclose=this.onerror=null}.bind(this),0)},b.prototype.countRTO=function(e){return e>100?4*e:300+e},ws=function(t){return e=a(t),Us()(b,t),b}}var Ws=function(){if(Cs)return Ts;Cs=1;var e=qt();return Ts=$s()(e),"_sockjs_onload"in H&&setTimeout(H._sockjs_onload,1),Ts}(),Fs=G(Ws);const js=()=>"undefined"!=typeof window&&window.StompJs&&window.StompJs.Client?window.StompJs.Client:V,Vs=()=>"undefined"!=typeof window&&window.SockJS?window.SockJS:Fs;class Hs 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||y.reconnectDelay,this.maxReconnectDelay=e.maxReconnectDelay||y.maxReconnectDelay,this.maxReconnectAttempts=e.maxReconnectAttempts||y.maxReconnectAttempts,this.heartbeatIncoming=e.heartbeatIncoming||y.heartbeatIncoming,this.heartbeatOutgoing=e.heartbeatOutgoing||y.heartbeatOutgoing,this.resumeOnVisibility=!1!==e.resumeOnVisibility,this.logger=new S(e.logLevel||E.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._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)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===P.OPEN}async forceReconnect(e){if(!this._intentionalDisconnect&&this.state!==t.CONNECTING)return this._forceReconnectPromise?(this.logger.debug(`Force reconnect already in progress, joining: ${e}`),this._forceReconnectPromise):(this._forceReconnectPromise=this._doForceReconnect(e).finally(()=>{this._forceReconnectPromise=null}),this._forceReconnectPromise)}async _doForceReconnect(e){if(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}this._setState(t.DISCONNECTED),this.reconnectAttempts=0;try{await this.connect()}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?f.SOCKJS_ENDPOINT:f.NATIVE_ENDPOINT;return`${this.serverUrl}${e}`}_createStompClient(){const e=this._getWebSocketUrl(),t={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,reconnectTimeMode:U.EXPONENTIAL,maxReconnectDelay:this.maxReconnectDelay,debug:e=>{this.logger.level<=E.DEBUG&&this.logger.debug("STOMP:",e)},onConnect:e=>this._onConnect(e),onDisconnect:e=>this._onDisconnect(e),onStompError:e=>this._onStompError(e),onWebSocketClose:e=>this._onWebSocketClose(e),onWebSocketError:e=>this._onWebSocketError(e)};if(this.useSockJS){const s=Vs();t.webSocketFactory=()=>new s(e)}else{const e=this.serverUrl.startsWith("https")?"wss":"ws",s=this.serverUrl.replace(/^https?:\/\//,"");t.brokerURL=`${e}://${s}${f.NATIVE_ENDPOINT}`}return new(js())(t)}async connect(){if(this.state!==t.CONNECTED){if(this.state!==t.CONNECTING)return this._setState(t.CONNECTING),this.reconnectAttempts=0,this._intentionalDisconnect=!1,this._connectRequested=!0,new Promise((e,s)=>{this._connectResolve=e,this._connectReject=s;try{this.stompClient=this._createStompClient(),this.stompClient.activate()}catch(e){this._setState(t.ERROR),this._drainPendingSubscriptions("Connection activation failed"),s(e)}});this.logger.warn("Connection in progress")}else this.logger.warn("Already connected")}_onConnect(e){const s=this.reconnectAttempts,n=s>0||!0===this._hasConnectedBefore;this._setState(t.CONNECTED),this.reconnectAttempts=0,this._hasConnectedBefore=!0,this.logger.info("Connected to server",e),this._restoreSubscriptions(),this._processPendingSubscriptions(),this.emit("connected",{frame:e}),n&&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){this.logger.error("STOMP error:",e),this._setState(t.ERROR);const n={type:s.CONNECTION_FAILED,message:e.headers?.message||"STOMP error",frame:e};this._drainPendingSubscriptions(`STOMP error: ${n.message}`),this.emit("error",n),this._connectReject&&(this._connectReject(new Error(n.message)),this._connectResolve=null,this._connectReject=null)}_onWebSocketClose(e){this.logger.warn("WebSocket closed:",e),this._tearingDown?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._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){if(this.stompClient){try{this.stompClient.deactivate()}catch(e){this.logger.warn("Error deactivating stomp client on max reconnect:",e)}this.stompClient=null}return 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}`)}_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:n}=this.pendingSubscriptions.shift(),i=this._subscribeInternal(e,t,s);n&&n(i)}}_subscribeInternal(e,t,s={}){const n=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:n,callback:t,headers:s}),this.logger.debug(`Subscribed to: ${e}`),n}subscribe(e,s,n={}){return this.subscriptions.has(e)&&this.unsubscribe(e),this.state!==t.CONNECTED?new Promise((t,i)=>{this.pendingSubscriptions.push({destination:e,callback:s,headers:n,resolve:t,reject:i}),this.logger.debug(`Queued subscription for: ${e}`)}):Promise.resolve(this._subscribeInternal(e,s,n))}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,n={}){return this.state!==t.CONNECTED?(this.logger.warn("Cannot send message: not connected"),!1):(this.stompClient.publish({destination:e,body:JSON.stringify(s),headers:n}),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}`})}async disconnect(){this._intentionalDisconnect=!0,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 Gs=new Set(["text/plain","text/markdown","text/x-markdown"]);class Bs extends e{constructor(e){super(),this.connectionManager=e.connectionManager,this.apiClient=e.apiClient,this.userId=e.userId,this.logger=new S(e.logLevel||E.WARN,"ChatClient"),this.subscribedRooms=new Map,this.roomListSubscribed=!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:"기획 중…",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:y.rewindMillis,this.maxSyncPages=e.maxSyncPages||y.maxSyncPages,this.syncPageSize=e.syncPageSize||y.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._installSyncTriggers()}_installSyncTriggers(){this.connectionManager&&"function"==typeof this.connectionManager.on&&(this._onReconnectedForSync=({attempts:e}={})=>{this.syncAfterReconnect(`reconnected:${e??0}`).catch(e=>this.logger.warn("Gap sync after reconnect failed:",e)),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.connectionManager.on("reconnected",this._onReconnectedForSync),this.connectionManager.on("resumed",this._onResumedForSync))}_shouldDedupMessage(e,t,s){if(!t||!s)return!1;let n=e.get(t);if(n||(n=new Map,e.set(t,n)),n.has(s))return!0;if(n.set(s,!0),n.size>this._maxSeenPerRoom){const e=n.keys().next().value;n.delete(e)}return!1}async getRooms(e={}){const{size:t=50,lastId:s,lastSortValue:n,type:i}=e;return this.apiClient.get("/api/v1/rooms/my",{size:t,lastId:s,lastSortValue:n,type:i})}async getRoom(e){const t=this._anchorGen.get(e)||0,s=await this.apiClient.get(`/api/v1/rooms/${e}`),n=this._unwrapSuccessResponse(s);return n&&Array.isArray(n.messages)&&this._seedAnchorFromLatest(e,n.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||l.GROUP;if(t===l.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===l.GROUP){if(e.password)throw new Error("Public GROUP rooms cannot have a password")}else if(t===l.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,n){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:n})}async summarizeWithAssistant(e,t={}){const{personaId:s,format:n,messageCount:i}=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:n,messageCount:i});return this._unwrapSuccessResponse(r)}async translateWithAssistant(e,t={}){const{targetLang:s,sourceMessageId:n}=t;if(!n)throw new Error("translateWithAssistant requires options.sourceMessageId");if(!s)throw new Error("translateWithAssistant requires options.targetLang");const i=await this.apiClient.post(`/api/v1/rooms/${e}/assistant/tools/translate`,{targetLang:s,sourceMessageId:n});return this._unwrapSuccessResponse(i)}async refreshSummary(e,t={}){const{format:s,lang:n}=t,i=await this.apiClient.post(`/api/v1/rooms/${e}/summary/refresh`,{format:s,lang:n});return this._unwrapSuccessResponse(i)}async getSummary(e,t={}){const{format:s,lang:n,afterSeq:i,size:r}=t,o=await this.apiClient.get(`/api/v1/rooms/${e}/summary`,{format:s,lang:n,afterSeq:i,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){const t=await this.apiClient.post(`/api/v1/rooms/${e}/leave`);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:n}=s;if(!n)throw new Error("createVote: options.idempotencyKey is required — generate it once per vote and reuse the same value on retry (재시도에 같은 키를 넘겨야 투표가 중복 생성되지 않는다).");const i=await this.apiClient.post(`/api/v1/rooms/${e}/votes`,t,void 0,{"X-Idempotency-Key":n});return this._unwrapSuccessResponse(i)}async getVotes(e,t={}){const{cursor:s,limit:n}=t,i=await this.apiClient.get(`/api/v1/rooms/${e}/votes`,{cursor:s,limit:n});return this._unwrapSuccessResponse(i)}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 n=await this.apiClient.patch(`/api/v1/rooms/${e}/votes/${t}`,s);return this._unwrapSuccessResponse(n)}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 n=await this.apiClient.put(`/api/v1/rooms/${e}/votes/${t}/responses`,{optionIds:s});return this._unwrapSuccessResponse(n)}async uploadVoteImage(e,t,s={}){if(!e)throw new Error("roomId is required");if(!t)throw new Error("file is required");const n=await this.apiClient.upload(`/api/v1/rooms/${e}/votes/images`,t,{onProgress:s.onProgress,signal:s.signal});return this._unwrapSuccessResponse(n)}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:n}=e;return this.apiClient.get("/api/v1/rooms/groups/available",{size:t,lastId:s,lastSortValue:n})}async getAllGroupRooms(e={}){const{size:t=50,lastId:s,lastSortValue:n}=e;return this.apiClient.get("/api/v1/rooms/groups/all",{size:t,lastId:s,lastSortValue:n})}async getMessages(e,t={}){const{size:s=50,lastId:n,lastSortValue:i}=t,r=null==n&&null==i,o=this._anchorGen.get(e)||0,a=await this.apiClient.get(`/api/v1/chat-messages/${e}/list`,{size:s,lastId:n,lastSortValue:i}),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 n=t[0];return!(!n||!n.id)&&this._commitAnchorFromSync(e,n.id,s)}async syncMessages(e,t={}){const{afterId:s,rewindMillis:n,size:i=this.syncPageSize}=t,r=await this.apiClient.get(`/api/v1/chat-messages/${e}/sync`,{afterId:s,rewindMillis:n,size:i}),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}),n=this._unwrapSuccessResponse(s)||{},i=(Array.isArray(n.content)?n.content:[]).slice().reverse(),r=this._replayMessages(e,i),o=i.length?i[i.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){const t=this._anchor.get(e);if(!t)return null;if(this._syncInFlight.has(e))return null;this._syncInFlight.add(e);const s=this._anchorGen.get(e)||0,n=Date.now();try{const i=[];let r=t,o=this.rewindMillis,a=!0,c=0;for(;a&&c<this.maxSyncPages;){const t=await this.syncMessages(e,{afterId:r,rewindMillis:o}),s=this._unwrapSuccessResponse(t)||{},n=Array.isArray(s.content)?s.content:[];i.push(...n),o=0,a=!!s.hasNext,s.lastId&&(r=s.lastId),c+=1}if(a){this.logger.info(`Gap too large, falling back to latest page: room=${e}`),this.emit("gapTruncated",{roomId:e,fetched:i.length});return{roomId:e,recovered:await this._reloadLatestPage(e,s),truncated:!0,durationMs:Date.now()-n}}const l=this._replayMessages(e,i);return this._commitAnchorFromSync(e,r,s),{roomId:e,recovered:l,truncated:!1,durationMs:Date.now()-n}}catch(t){if(this._isCursorExpired(t)){this.logger.warn(`Sync cursor expired, reloading latest: room=${e}`),this.emit("gapTruncated",{roomId:e,fetched:0,reason:"cursorExpired"});return{roomId:e,recovered:await this._reloadLatestPage(e,s),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(),n=[];for(const e of t)try{const t=await this._syncRoom(e);t&&n.push(t)}catch(t){this.logger.warn(`Gap sync failed: room=${e}`,t)}await this._refreshRoomList(e),this.emit("syncCompleted",{rooms:n,totalRecovered:n.reduce((e,t)=>e+(t.recovered||0),0),durationMs:Date.now()-s,reason: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(),n=[s],i=this._sendMessageWithId(e,s,t).then(e=>this._attachOptimisticMetadata(n,e));return{baseMessageId:s,messageIds:n,promise:i}}async _sendMessageWithId(e,t,s){this.stopTyping(e);const n=await this.apiClient.post(`/api/v1/chat-messages/${e}/send`,{messageId:t,message:s.message,fileInfos:s.fileInfos,replyToMessageId:s.replyToMessageId,decisionResponse:s.decisionResponse}),i=this._unwrapSuccessResponse(n);return i&&Array.isArray(i.messages)&&i.messages.forEach(e=>this._normalizeMessageTimestamps(e)),i}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 n=await this.apiClient.upload(`/api/v1/files/${e}/upload`,t,{onProgress:s.onProgress,signal:s.signal});return this._unwrapSuccessResponse(n)}async sendFileMessage(e,t,s={}){const n=this._normalizeFileArray(t),i=await this._uploadFiles(e,n,s),r=this._applyFileMetadata(i,s.metadata);return this.sendMessage(e,{message:s.message,fileInfos:r,replyToMessageId:s.replyToMessageId})}sendFileMessageOptimistic(e,t,s={}){const n=this._normalizeFileArray(t),i=this._generateMessageId(),r=[i],o=(async()=>{const t=await this._uploadFiles(e,n,s),o=this._applyFileMetadata(t,s.metadata),a=await this._sendMessageWithId(e,i,{message:s.message,fileInfos:o,replyToMessageId:s.replyToMessageId});return this._attachOptimisticMetadata(r,a)})();return{baseMessageId:i,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,n)=>this.uploadFile(e,t,{signal:s.signal,onProgress:s.onUploadProgress?e=>s.onUploadProgress({...e,fileIndex:n}):void 0})))}_applyFileMetadata(e,t){return null==t?e:e.map((e,s)=>{const n=Array.isArray(t)?t[s]:t;return null==n?e:{...e,metadata:n}})}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")||Gs.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 n=new Set(s.map(e=>this.classifyFileType(e&&e.fileType||"")));return 1===n.size?n.values().next().value:"MIXED"}_attachOptimisticMetadata(e,t){const s=t&&Array.isArray(t.messages)?t.messages.map(e=>e&&e.messageId||null):[],n=s.length===e.length&&e.every((e,t)=>e===s[t]);return n||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:n}}}_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=f.getChatDestination(e);await this.connectionManager.subscribe(t,t=>{this._handleChatMessage(e,t)});const s=f.getChatReadDestination(e);await this.connectionManager.subscribe(s,t=>{this._handleReadEvent(e,t)});const n=f.getChatTypingDestination(e);await this.connectionManager.subscribe(n,t=>{this._handleTypingEvent(e,t)});const i=this.assistantStreamReplay?this._armAssistantSnapshot(e):null,r=f.getChatAssistantStreamDestination(e);await this.connectionManager.subscribe(r,t=>{this._handleAssistantStreamEvent(e,t)}),null!==i&&this._loadAssistantSnapshot(e,i).catch(t=>this.logger.warn(`Assistant snapshot merge failed: room=${e}`,t));const o=f.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:n,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=f.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(f.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}markAsRead(e,t){return this.connectionManager.isConnected()?this.connectionManager.send(f.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_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;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(f.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(f.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 n=this._assistantSnapshotPending.get(e);if(n&&"DONE"!==t.type)n.events.push(t);else{if("PHASE"===t.type){const n=this._assistantSlot(e,s),i="number"==typeof t.createdAt?t.createdAt:null;if(n&&null!==i&&i<=(n.phaseUpdatedAt||0))return void this.logger.debug(`Stale assistant PHASE ignored: room=${e}, stream=${s}, createdAt=${i}, applied=${n.phaseUpdatedAt}`);const r=t.phase||null,o=n,a=this._setAssistantSlot(e,s,t,{phase:r,phaseUpdatedAt:null!==i?i:o?o.phaseUpdatedAt:0,text:o&&o.text||"",lastSeq:o?this._seqOf(o.lastSeq):-1,textAvailable:!o||!1!==o.textAvailable});return void this._emitAssistantStream(e,s,a,{active:!0,text:a.textAvailable&&a.text||null})}if("DELTA"===t.type){const n=this._assistantSlot(e,s),i=n&&n.phase||"WRITING",r="number"==typeof t.seq?t.seq:null;let o=n?this._seqOf(n.lastSeq):-1,a=!n||!1!==n.textAvailable,c=n&&n.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 l=this._setAssistantSlot(e,s,t,{phase:i,text:c,lastSeq:o,textAvailable:a});return void this._emitAssistantStream(e,s,l,{active:!0,text:l.textAvailable?l.text:null,delta:l.textAvailable&&t.delta||null,seq:r})}if("DONE"===t.type){const n=this._assistantSlot(e,s);n&&n.timer&&clearTimeout(n.timer),this._deleteAssistantSlot(e,s),this._tombstoneAssistantStream(e,s),this._emitAssistantStream(e,s,n,{active:!1,personaId:t.personaId||n&&n.personaId||null,phase: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 n=(async()=>{let s=null;try{const t=await this.apiClient.get(`/api/v1/rooms/${e}/assistant/streams`),n=this._unwrapSuccessResponse(t);s=n&&Array.isArray(n.streams)?n.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:n});try{await n}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,label:null,personaId:t.personaId||null,status:t.doneStatus||null,messageId:t.messageId||null,resumed:!0});const n=!1!==t.textAvailable,i=this._setAssistantSlot(e,s,{personaId:t.personaId,expiresAt:void 0},{phase:t.phase||null,phaseUpdatedAt:"number"==typeof t.phaseUpdatedAt?t.phaseUpdatedAt:0,text:n&&t.text||"",lastSeq:this._seqOf(t.lastSeq),textAvailable:n,resumed:!0});this._emitAssistantStream(e,s,i,{active:!0,text:i.textAvailable&&i.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 n=s.get(t);return void 0!==n&&(!(n<=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 n=Date.now();s.forEach((e,t)=>{e<=n&&s.delete(t)}),s.set(t,n+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,n){const i=this._assistantSlot(e,t);i&&i.timer&&clearTimeout(i.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||i&&i.personaId||null,phase:n.phase,phaseUpdatedAt:void 0!==n.phaseUpdatedAt?n.phaseUpdatedAt:i&&i.phaseUpdatedAt||0,text:n.text||"",lastSeq:this._seqOf(n.lastSeq),textAvailable:!1!==n.textAvailable,resumed:!0===n.resumed||!!i&&!0===i.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,label:null,reason:"timeout"}))}_emitAssistantStream(e,t,s,n){const i="phase"in n?n.phase:s?s.phase:null;this.emit("assistantProgress",{roomId:e,streamId:t,personaId:s?s.personaId:null,phase:i,label:i&&this._assistantPhaseLabels[i]||null,textAvailable:!s||s.textAvailable,lastSeq:s?s.lastSeq:-1,...n}),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,streams:[]};const[n,i]=s.reduce((e,t)=>t[1].order>e[1].order?t:e);return{roomId:e,active:!0,streamCount:s.length,streamId:n,personaId:i.personaId,phase:i.phase,label:i.phase&&this._assistantPhaseLabels[i.phase]||null,text:i.textAvailable&&i.text||null,textAvailable:i.textAvailable,streams:s.sort((e,t)=>e[1].order-t[1].order).map(([e,t])=>({streamId:e,personaId:t.personaId,phase:t.phase,label:t.phase&&this._assistantPhaseLabels[t.phase]||null,text:t.textAvailable&&t.text||null,textAvailable:t.textAvailable,resumed:!0===t.resumed}))}}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)}destroy(){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 Js extends e{constructor(e={}){super(),this.localStream=null,this.screenStream=null,this.videoEnabled=!0,this.audioEnabled=!0,this.logger=new S(e.logLevel||E.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}}},n=(await navigator.mediaDevices.getUserMedia(s)).getTracks()[0],i="video"===t?this.localStream.getVideoTracks()[0]:this.localStream.getAudioTracks()[0];return i&&(this.replaceTrack(i,n),this.emit("deviceSwitched",{kind:t,deviceId:e,newTrack:n}),this.logger.info(`${t} device switched to ${e}`)),n}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 qs extends e{constructor(e={}){super(),this.iceServers=e.iceServers||y.iceServers,this.logger=new S(e.logLevel||E.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 n={iceServers:this.iceServers,iceCandidatePoolSize:10},i=new RTCPeerConnection(n),r={connection:i,polite:t,makingOffer:!1,ignoreOffer:!1,isSettingRemoteAnswerPending:!1,skipAutoNegotiation:s.skipAutoNegotiation||!1};return this.peers.set(e,r),this._setupConnectionHandlers(e,i,r),this.localStream&&this._addTracksToConnection(i),this.logger.info(`Peer connection created: ${e} (polite: ${t}, skipAutoNegotiation: ${r.skipAutoNegotiation})`),i}_setupConnectionHandlers(e,t,n){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(n.skipAutoNegotiation)this.logger.debug(`Skipping auto negotiation for ${e} (manual offer will be sent)`);else try{n.makingOffer=!0,await t.setLocalDescription(),this.emit("negotiationNeeded",{peerId:e,description:t.localDescription})}catch(t){this.logger.error(`Negotiation error (${e}):`,t)}finally{n.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:n,polite:i,makingOffer:r}=s,o="offer"===t.type&&(r||"stable"!==n.signalingState);if(s.ignoreOffer=!i&&o,s.ignoreOffer)this.logger.debug(`Ignoring offer collision from ${e} (I am impolite)`);else try{if(o&&i&&(this.logger.debug(`Offer collision detected, rolling back local offer for ${e} (I am polite)`),await n.setLocalDescription({type:"rollback"})),s.isSettingRemoteAnswerPending="answer"===t.type,await n.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((n,i)=>{const r=n.connection.getSenders().find(t=>t.track&&t.track.kind===e.kind);r&&s.push(r.replaceTrack(t).then(()=>this.logger.debug(`Track replaced for ${i}`)).catch(e=>this.logger.error(`Failed to replace track for ${i}:`,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")}}class zs extends e{constructor(e){super(),this.connectionManager=e.connectionManager,this.apiClient=e.apiClient,this.userId=e.userId,this.logLevel=e.logLevel||E.WARN,this.logger=new S(this.logLevel,"WebRTCClient"),this.mediaManager=new Js({logLevel:this.logLevel}),this.peerManager=new qs({iceServers:e.iceServers||y.iceServers,logLevel:this.logLevel}),this.currentRoom=null,this.isGroupCall=!1,this.participants=new Map,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:n.ICE_CANDIDATE,receiverId:e,data:{candidate:t}})}),this.peerManager.on("negotiationNeeded",({peerId:e,description:t})=>{this._sendSignal({type:n.CALL_OFFER,receiverId:e,data:{sdp:t}})}),this.peerManager.on("answerCreated",({peerId:e,answer:t})=>{this._sendSignal({type:n.CALL_ANSWER,receiverId:e,data:{sdp:t}})})}async getTurnCredentials(){return(await this.apiClient.get("/api/v1/webrtc/turn-credentials")).data}async createCallRoom(e){return this.apiClient.post("/api/v1/webrtc/rooms",e)}async getCallRoom(e){return this.apiClient.get(`/api/v1/webrtc/rooms/${e}`)}async joinCallRoomApi(e){return this.apiClient.post(`/api/v1/webrtc/rooms/${e}/join`)}async leaveCallRoomApi(e){return this.apiClient.delete(`/api/v1/webrtc/rooms/${e}/leave`)}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=f.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:i=!1,mediaConstraints:r={video:!0,audio:!0}}=e;try{await this.initializeIceServers();const e=await this.mediaManager.getUserMedia(r);return this.peerManager.setLocalStream(e),this.currentRoom=t,this.isGroupCall=i,await this._subscribeToSignaling(t,i),this._sendSignal({type:n.JOIN_ROOM,roomId:t}),this.logger.info(`Call started in room: ${t}`),this.emit("callStarted",{roomId:t,isGroup:i,localStream:e}),e}catch(e){throw this.logger.error("Failed to start call:",e),this.emit("error",{type:s.PEER_CONNECTION_FAILED,message:e.message,error:e}),e}}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._waitingForCallAccept=!0,this._pendingCallTarget=e,this._sendSignal({type:n.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._sendSignal({type:n.CALL_ACCEPT,receiverId:e}),this.emit("callAccepted",{callerId:e})}catch(e){throw this.logger.error("Failed to accept call:",e),e}}rejectCall(e){this._sendSignal({type:n.CALL_REJECT,receiverId:e}),this.emit("callRejected",{callerId:e})}cancelCall(){this._waitingForCallAccept&&this._pendingCallTarget&&(this._sendSignal({type:n.CALL_CANCEL,receiverId:this._pendingCallTarget}),this.emit("callCancelled",{targetUserId:this._pendingCallTarget}),this._waitingForCallAccept=!1,this._pendingCallTarget=null,this.mediaManager.stopAll())}endCall(){this._waitingForCallAccept&&this._pendingCallTarget&&this._sendSignal({type:n.CALL_CANCEL,receiverId:this._pendingCallTarget}),this._waitingForCallAccept=!1,this._pendingCallTarget=null,this.currentRoom&&(this._sendSignal({type:n.LEAVE_ROOM,roomId:this.currentRoom}),this._unsubscribeFromSignaling()),this.peerManager.getPeerIds().forEach(e=>{this._sendSignal({type:n.CALL_END,receiverId:e})}),this.peerManager.closeAllPeerConnections(),this.mediaManager.stopAll(),this.participants.clear(),this._pendingIceCandidates.clear();const e=this.currentRoom;this.currentRoom=null,this.isGroupCall=!1,this.emit("callEnded",{roomId:e}),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),n=await this.mediaManager.switchDevice(e,t);return s&&await this.peerManager.replaceTrack(s,n),n}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=f.getWebRTCDestination(e);await this.connectionManager.subscribe(t,e=>{this._handleSignal(e)})}await this._subscribeToDirectSignaling()}async _subscribeToDirectSignaling(){const e=f.getWebRTCUserDestination();await this.connectionManager.subscribe(e,e=>{this._handleSignal(e)})}_unsubscribeFromSignaling(){if(this.currentRoom&&this.isGroupCall){const e=f.getWebRTCDestination(this.currentRoom);this.connectionManager.unsubscribe(e)}if(!this._incomingCallsEnabled){const e=f.getWebRTCUserDestination();this.connectionManager.unsubscribe(e)}}_sendSignal(e){const t={type:e.type,roomId:e.roomId||this.currentRoom,receiverId:e.receiverId,data:e.data};this.connectionManager.send(f.WEBRTC_SIGNAL,t),this.logger.debug("Signal sent:",t)}_sendMediaState(){if(!this.currentRoom&&0===this.peerManager.getPeerIds().length)return;const e={videoEnabled:this.mediaManager.isVideoEnabled(),audioEnabled:this.mediaManager.isAudioEnabled()};this._sendSignal({type:n.VIDEO_STATE_CHANGED,data:e}),this.emit("mediaStateChanged",e)}async _handleSignal(e){const{type:t,senderId:s,data:i}=e;if(s!==this.userId)switch(this.logger.debug(`Signal received: ${t} from ${s}`),t){case n.JOIN_ROOM:case n.PEER_JOINED:await this._handleUserJoined(s);break;case n.LEAVE_ROOM:case n.PEER_LEFT:this._handleUserLeft(s);break;case n.CALL_OFFER:await this._handleOffer(s,i.sdp);break;case n.CALL_ANSWER:await this._handleAnswer(s,i.sdp);break;case n.ICE_CANDIDATE:await this._handleIceCandidate(s,i.candidate);break;case n.VIDEO_STATE_CHANGED:case n.AUDIO_STATE_CHANGED:this._handleMediaState(s,i);break;case n.CALL_REQUEST:this.isInCall()||this._waitingForCallAccept?(this._sendSignal({type:n.CALL_BUSY,receiverId:s}),this.emit("incomingCallWhileBusy",{callerId:s})):this.emit("incomingCall",{callerId:s});break;case n.CALL_BUSY:this._waitingForCallAccept=!1,this._pendingCallTarget=null,this.mediaManager.stopAll(),this.emit("callBusy",{userId:s});break;case n.CALL_INVITATION:this.emit("callInvitation",{callRoomId:i?.callRoomId||e.roomId,title:i?.title,hostUserId:i?.hostUserId||s,maxParticipants:i?.maxParticipants,createdAt:i?.createdAt});break;case n.CALL_ACCEPT:await this._handleCallAccepted(s);break;case n.CALL_REJECT:this._waitingForCallAccept=!1,this._pendingCallTarget=null,this.mediaManager.stopAll(),this.emit("callRejected",{userId:s});break;case n.CALL_CANCEL:this._waitingForCallAccept=!1,this._pendingCallTarget=null,this.emit("callCancelled",{userId:s});break;case n.CALL_END:this._handleCallEnded(s);break;default:this.logger.warn(`Unknown signal type: ${t}`)}}async _handleUserJoined(e){this.participants.set(e,{joinedAt:new Date});const t=this.userId<e;this.peerManager.createPeerConnection(e,t),this.emit("userJoined",{userId:e}),this.logger.info(`User joined: ${e} (I am ${t?"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){if(!this.peerManager.getPeerConnection(e)){const t=this.userId<e;this.peerManager.createPeerConnection(e,t,{skipAutoNegotiation:!0})}await this.peerManager.handleRemoteDescription(e,t),await this._processPendingIceCandidates(e)}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._waitingForCallAccept=!1,this._pendingCallTarget=null,this.peerManager.createPeerConnection(e,!1,{skipAutoNegotiation:!0});const t=await this.peerManager.createOffer(e);this._sendSignal({type:n.CALL_OFFER,receiverId:e,data:{sdp:t}}),this.emit("callAccepted",{userId:e})}_handleCallEnded(e){this.peerManager.closePeerConnection(e),this.participants.delete(e),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.endCall(),this.mediaManager.destroy(),this.peerManager.destroy(),this.removeAllListeners(),this.logger.info("WebRTCClient destroyed")}}const Ks=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 Xs extends Error{constructor(e,t,s){super(t),this.name="PushError",this.code=e,void 0!==s&&(this.cause=s)}}const Ys={apiKey:"AIzaSyB8VhRg6rSvUI7K3Ua7h6sBpLvaQGmIkRc",authDomain:"chatting-c3e5d.firebaseapp.com",projectId:"chatting-c3e5d",storageBucket:"chatting-c3e5d.firebasestorage.app",messagingSenderId:"1020496565673",appId:"1:1020496565673:web:5039167257fd83f5ce20b8"},Qs="pendingNavigation",Zs="pending-room",en="deviceInfo",tn="device-id",sn="talkflow_device_id";function nn(){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(Qs)||e.createObjectStore(Qs,{keyPath:"id"}),e.objectStoreNames.contains(en)||e.createObjectStore(en,{keyPath:"id"})},s.onsuccess=()=>e(s.result),s.onerror=()=>t(s.error||new Error("IndexedDB open failed"))})}function rn(){return nn().then(e=>e?new Promise((t,s)=>{const n=e.transaction(en,"readonly"),i=n.objectStore(en).get(tn);i.onsuccess=()=>{const e=i.result;t(e&&e.value?e.value:null)},i.onerror=()=>s(i.error||new Error("IndexedDB read failed")),n.oncomplete=()=>e.close(),n.onerror=()=>e.close(),n.onabort=()=>e.close()}):null)}function on(e){return nn().then(t=>!!t&&new Promise(s=>{try{const n=t.transaction(en,"readwrite");n.objectStore(en).put({id:tn,value:e}),n.oncomplete=()=>{t.close(),s(!0)},n.onerror=()=>{t.close(),s(!1)},n.onabort=()=>{t.close(),s(!1)}}catch(e){try{t.close()}catch(e){}s(!1)}})).catch(()=>!1)}function an(){return"web-"+("undefined"!=typeof crypto&&crypto.randomUUID?crypto.randomUUID():Date.now().toString(36)+Math.random().toString(36).substring(2))}async function cn(e){const t=await nn();if(!t)return null;const s=function(e){return e&&"string"==typeof e&&""!==e.trim()?"pending-room:"+e:Zs}(e),n=!!e&&s!==Zs;return new Promise((i,r)=>{const o=t.transaction(Qs,"readwrite"),a=o.objectStore(Qs);let c=null;const l=a.get(s);l.onsuccess=()=>{const t=l.result;if(t&&t.roomId){if((t.projectId||null)===(e||null))return c=t.roomId,void a.delete(s)}if(!n)return;const i=a.get(Zs);i.onsuccess=()=>{const e=i.result;e&&e.roomId&&!e.projectId&&(c=e.roomId,a.delete(Zs))}},l.onerror=()=>{r(l.error||new Error("IndexedDB read failed"))},o.oncomplete=()=>{t.close(),i(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 ln{constructor(e){this.apiClient=e.apiClient,this.projectId=e.projectId||null,this.firebaseConfig=e.firebaseConfig||Ys,this.vapidKey=e.vapidKey||"BGP8qaSm1ntjWd4n9pc0lX_rw4BmMxm9u4pvRIANCitbmYaV0iy-gn05suTKBo88kUBejxdxM8sb6x2nt3avu8c",this.serviceWorkerPath=e.serviceWorkerPath||"/firebase-messaging-sw.js",this.logger=new S(e.logLevel||E.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 cn(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 Xs(Ks.UNSUPPORTED_BROWSER,"푸시 알림은 브라우저 환경에서만 사용 가능합니다");if(!("serviceWorker"in navigator))throw new Xs(Ks.UNSUPPORTED_BROWSER,"이 브라우저는 서비스 워커를 지원하지 않습니다");if("denied"===Notification.permission)throw new Xs(Ks.PERMISSION_DENIED,"알림 권한이 이미 거부되어 있습니다. 브라우저 사이트 설정에서 허용해주세요.");let e,t,s;try{e=await import("firebase/app"),t=await import("firebase/messaging")}catch(e){throw new Xs(Ks.FIREBASE_NOT_INSTALLED,"firebase 패키지가 설치되지 않았습니다. npm install firebase 를 실행하세요.",e)}try{s=e.getApp("talkflow")}catch{s=e.initializeApp(this.firebaseConfig,"talkflow")}const n=await this._registerServiceWorker();if("granted"!==("granted"===Notification.permission?"granted":await Notification.requestPermission()))throw new Xs(Ks.PERMISSION_DENIED,"알림 권한이 거부되었습니다. 브라우저 설정에서 허용해주세요.");this._messaging=t.getMessaging(s);const i={serviceWorkerRegistration:n};this.vapidKey&&(i.vapidKey=this.vapidKey);try{this._currentToken=await t.getToken(this._messaging,i)}catch(e){throw new Xs(Ks.TOKEN_FAILED,"FCM 토큰 획득 중 오류 발생: "+(e?.message||e),e)}if(!this._currentToken)throw new Xs(Ks.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=n,await this._registerProjectToSW(),this._installVisibilityReRegister();try{await n.update()}catch(e){this.logger.debug("SW 업데이트 체크 실패 (무시):",e.message)}const r=await this._getSWVersion(n);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 Xs(Ks.SW_REGISTER_FAILED,`서비스 워커 등록 실패: ${this.serviceWorkerPath}\n프로젝트 public 폴더에 firebase-messaging-sw.js 파일을 배치하세요.`,e)}}async _registerTokenToServer(e){try{const t=await this._getDeviceId();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 Xs)throw e;throw new Xs(Ks.SERVER_REGISTER_FAILED,"디바이스 토큰 서버 등록 실패: "+(e?.message||e),e)}}async _getDeviceId(){if(this._deviceIdCache)return this._deviceIdCache;try{let e=await rn();if(!e&&"undefined"!=typeof localStorage){const t=localStorage.getItem(sn);if(t){e=t;if(await on(e)){if(await rn()===e)try{localStorage.removeItem(sn),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=an();await on(e)||this.logger.warn("신규 deviceId IDB 저장 실패, 이번 세션만 유효")}return this._deviceIdCache=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(sn)}catch(e){}this._deviceIdCache=e||an()}return this._deviceIdCache}}_onForegroundMessage(e){}async consumePendingRoom(){return ln.consumePendingRoom(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),n=new MessageChannel;n.port1.onmessage=s=>{clearTimeout(t),e(s.data?.version||null)};try{s.postMessage({type:"TALKFLOW_SW_VERSION"},[n.port2])}catch(s){clearTimeout(t),e(null)}}):null}catch{return null}}setLogLevel(e){this.logger.setLevel(e)}}const hn=[["connected","connected"],["disconnected","disconnected"],["reconnecting","reconnecting"],["reconnected","reconnected"],["resumed","resumed"],["error","connectionError"]],dn=[["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"],["roomListCreated","roomListCreated"],["roomListJoined","roomListJoined"],["roomListLeft","roomListLeft"],["roomListSelfLeft","roomListSelfLeft"],["roomListKicked","roomListKicked"],["roomListSelfKicked","roomListSelfKicked"],["roomListBanned","roomListBanned"],["roomListSelfBanned","roomListSelfBanned"],["roomListRoomUpdated","roomListRoomUpdated"],["roomListUnreadUpdated","roomListUnreadUpdated"],["retentionCleanup","retentionCleanup"]],un=[["localStreamStarted","localStreamStarted"],["localStreamStopped","localStreamStopped"],["remoteTrack","remoteTrack"],["screenShareStarted","screenShareStarted"],["screenShareEnded","screenShareEnded"],["deviceChange","deviceChange"],["mediaStateChanged","mediaStateChanged"],["callStarted","callStarted"],["callEnded","callEnded"],["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 pn(e,t,s){s.forEach(([s,n])=>{e.on(s,e=>{t.emit(n,e)})})}const gn=["getRooms","getRoom","getRoomInfo","setMyRoomLanguage","createOneToOneRoom","createGroupRoom","joinGroupRoom","leaveRoom","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","getSubscribedRooms","isSubscribed","startTyping","stopTyping","getAssistantProgress","resumeAssistantStreams","getAssistants","getRoomAiMeta","rateAssistantMessage","summarizeWithAssistant","translateWithAssistant","refreshSummary","getSummary","getRoomPmPrompt","upsertRoomPmPrompt","activateRoomPmPrompt","deactivateRoomPmPrompt","getRoomPmPromptVersions","activateRoomPmPromptVersion","previewRoomPmPrompt","createVote","getVotes","getVote","updateVote","deleteVote","closeVote","submitVote","uploadVoteImage"],mn=["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 fn(e,t,s){s.forEach(s=>{e[s]=function(...e){return this[t][s](...e)}})}class _n extends e{constructor(e){super(),this._validateOptions(e);const s=e.env||y.environment,n=(e.serverUrl||v(s)).replace(/\/$/,"");this.options={serverUrl:n,env:s,apiKey:e.apiKey,projectId:e.projectId,jwtToken:e.jwtToken||null,useSockJS:!1!==e.useSockJS,reconnectDelay:e.reconnectDelay||y.reconnectDelay,maxReconnectDelay:e.maxReconnectDelay||y.maxReconnectDelay,maxReconnectAttempts:e.maxReconnectAttempts||y.maxReconnectAttempts,heartbeatIncoming:e.heartbeatIncoming||y.heartbeatIncoming,heartbeatOutgoing:e.heartbeatOutgoing||y.heartbeatOutgoing,resumeOnVisibility:!1!==e.resumeOnVisibility,syncOnReconnect:!1!==e.syncOnReconnect,assistantStreamReplay:!1!==e.assistantStreamReplay,rewindMillis:void 0!==e.rewindMillis?e.rewindMillis:y.rewindMillis,maxSyncPages:e.maxSyncPages||y.maxSyncPages,syncPageSize:e.syncPageSize||y.syncPageSize,iceServers:e.iceServers||y.iceServers,autoSubscribeRoomList:!1!==e.autoSubscribeRoomList,logLevel:void 0!==e.logLevel?e.logLevel:E.WARN},this.logger=new S(this.options.logLevel,"TalkFlowClient"),this._initialized=!1,this._state=t.DISCONNECTED,this._userId=null,this.options.jwtToken&&(this._userId=A(this.options.jwtToken)),this.apiClient=new w({baseUrl:this.options.serverUrl,apiKey:this.options.apiKey,projectId:this.options.projectId,jwtToken:this.options.jwtToken,logLevel:this.options.logLevel}),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,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)throw new Error("apiKey is required");if(!e.projectId)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 Hs({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,heartbeatIncoming:e.options.heartbeatIncoming,heartbeatOutgoing:e.options.heartbeatOutgoing,resumeOnVisibility:e.options.resumeOnVisibility,logLevel:e.options.logLevel}),e._chat=new Bs({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 zs({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(){var e;(e=this).connectionManager&&(e.connectionManager.on("stateChange",({state:t,prevState:s})=>{e._state=t,e.emit("stateChange",{state:t,prevState:s})}),pn(e.connectionManager,e,hn),e.chat&&pn(e.chat,e,dn),e.webrtc&&pn(e.webrtc,e,un))}isConnected(){return!!this.connectionManager&&this.connectionManager.isConnected()}getState(){return this._state}hasToken(){return!!this.options.jwtToken}static async loginUser({serverUrl:e,email:t,password:s}){if(!e)throw new Error("serverUrl is required");if(!t)throw new Error("email is required");if(!s)throw new Error("password is required");const n=new w({baseUrl:e,apiKey:"",projectId:""}),i=await n.post("/api/v1/auth/login",{email:t,password:s});return i&&i.data?i.data:i}async loginUser({email:e,password:t}){const s=await this.apiClient.post("/api/v1/auth/login",{email:e,password:t}),n=s&&s.data?s.data:s;return n&&n.accessToken&&(await this.setToken(n.accessToken),this.logger.info("Member logged in, token auto-set")),n}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}){return this._checkToken(),this.apiClient.put("/api/v1/me/password",{currentPassword:e,newPassword:t})}async setPreferredLanguage(e){return this.updateMyProfile({preferredLanguage:e})}static detectBrowserLanguage(){return"undefined"!=typeof navigator&&navigator.language?_n.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(),n=s.indexOf("-");if(n<0)return s;const i=s.slice(0,n);return"zh"===i?s:i}static displayText(e,t){const s=_n.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:n}=e;return this.apiClient.get("/api/v1/users",{size:t,lastId:s,lastSortValue:n})}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.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")}}_n.ConnectionState=t,_n.ErrorTypes=s,_n.LogLevel=E,_n.Environment=_,function(e){e.prototype.connect=async function(e,t={}){const{enablePush:s=!1}=t;if(e&&await this.setToken(e),!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(R(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.connectionManager&&(this.webrtc&&this.webrtc.isInCall()&&this.webrtc.endCall(),this.webrtc&&this.webrtc.disableIncomingCalls(),this.chat&&(this.chat.unsubscribeAllRooms(),this.chat.unsubscribeRoomList()),await this.connectionManager.disconnect(),this.logger.info("Disconnected from server"))},e.prototype.logout=async function(){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 ln({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);const n=this.chat?.getActiveRoom();if(n&&n===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 ln.consumePendingRoom(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 ln.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}=C(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(),await this.connectionManager.destroy(),this.pushManager&&(this.pushManager.reset(),this._pushEnablePromise=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.emit("tokenSet",{userId:t})},e.prototype.updateToken=async function(e){await this.setToken(e)}}(_n),function(e){fn(e.prototype,"chat",gn),fn(e.prototype,"webrtc",mn)}(_n);class bn{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 n=null==s?null:s,i=this._room(e);if(!(null!=i.snapshotVersion&&null==n||null!=i.snapshotVersion&&null!=n&&n<i.snapshotVersion||(i.snapshotCount=t,null!=n&&(i.snapshotVersion=n),null==n)))for(const[e,t]of i.pendingDeltas)(null==t.version||t.version<=n)&&i.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{h as AssistantMode,Bs as ChatClient,i as ChatMessageType,l as ChatRoomType,Hs as ConnectionManager,t as ConnectionState,r as DecisionCardLimits,y as DefaultConfig,b as Endpoints,u as EngagementIntensity,_ as Environment,s as ErrorTypes,e as EventEmitter,E as LogLevel,S as Logger,Js as MediaStreamManager,qs as PeerConnectionManager,a as PersonaRole,g as PmPromptLayerEditorType,p as PmPromptLayerScope,Xs as PushError,Ks as PushErrorCode,ln as PushManager,d as RoomAiType,m as RoomListEventType,bn as RoomUnreadReconciler,o as SenderType,n as SignalTypes,c as SummarizeFormat,zs as WebRTCClient,f as WebSocketPaths,O as decodeJWTPayload,_n as default,A as extractUserIdFromJWT,M as getJWTRemainingTime,v as getServerUrl,R as isJWTExpired,C as validateAndParseJWT};
2
2
  //# sourceMappingURL=talkflow-sdk.esm.js.map