@skywu/virtual-chat-sdk 1.7.11 → 1.7.13

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 +1 @@
1
- class t extends Error{constructor(t,e,s){super(t),this.code=e,this.details=s,this.name="ChatSDKError"}}class e{constructor(){this.events=new Map}on(t,e){this.events.has(t)||this.events.set(t,[]),this.events.get(t).push(e)}off(t,e){if(!this.events.has(t))return;if(!e)return void this.events.delete(t);const s=this.events.get(t),n=s.indexOf(e);n>-1&&s.splice(n,1),0===s.length&&this.events.delete(t)}emit(t,e){if(!this.events.has(t))return;this.events.get(t).forEach(s=>{try{s(e)}catch(e){console.error(`Error in event callback for "${t}":`,e)}})}getEventNames(){return Array.from(this.events.keys())}listenerCount(t){var e;return(null===(e=this.events.get(t))||void 0===e?void 0:e.length)||0}removeAllListeners(){this.events.clear()}}class s{constructor(t){this.baseUrl=t.apiBaseUrl||window.location.origin,this.token=t.token}async request(e,s={}){const n=`${this.baseUrl}${e}`,i={"Content-Type":"application/json",...s.headers};this.token&&(i.Authorization=`Bearer ${this.token}`);try{const e=await fetch(n,{...s,headers:i,credentials:"include"});if(!e.ok)throw new t(`API request failed: ${e.status} ${e.statusText}`,"API_ERROR",{status:e.status,statusText:e.statusText});const o=await e.json();if(!o.success&&o.error)throw new t(o.error,"API_ERROR",o);return o}catch(e){if(e instanceof t)throw e;throw new t(`Network error: ${e.message}`,"NETWORK_ERROR",e)}}async getProject(t){return this.request(`/api/projects/${t}`)}async getTemplate(t,e){const s=e?`?lang=${encodeURIComponent(e)}`:"";return this.request(`/api/templates/${t}${s}`)}async getProjectTemplates(t){return this.request(`/api/projects/${t}/templates`)}async sendMessage(t,e,s,n="text"){return this.request("/api/chat/message",{method:"POST",body:JSON.stringify({projectId:t,userId:e,content:s,messageType:n})})}async joinProject(t,e,s){return this.request("/api/chat/join",{method:"POST",body:JSON.stringify({projectId:t,userId:e,username:s})})}async leaveProject(t,e){return this.request("/api/chat/leave",{method:"POST",body:JSON.stringify({projectId:t,userId:e})})}async getSimulationData(t,e,s){const n=new URLSearchParams({userId:e});return s&&n.append("lang",s),this.request(`/api/chat/simulation/${t}?${n.toString()}`)}async getSimulationMessages(t,e,s,n){const i=new URLSearchParams({userId:e});return s&&i.append("since",s),n&&i.append("limit",n.toString()),this.request(`/api/chat/simulation/${t}/messages?${i.toString()}`)}async sendUserMessage(t,e,s,n,i="text"){return this.request("/api/chat/send",{method:"POST",body:JSON.stringify({projectId:t,userId:e,username:s,content:n,messageType:i})})}async triggerAIReply(t,e,s,n,i="text"){return this.request("/api/chat/ai-reply",{method:"POST",body:JSON.stringify({projectId:t,userId:e,username:s,content:n,messageType:i})})}setToken(t){this.token=t}setBaseUrl(t){this.baseUrl=t}}const n=Object.create(null);n.open="0",n.close="1",n.ping="2",n.pong="3",n.message="4",n.upgrade="5",n.noop="6";const i=Object.create(null);Object.keys(n).forEach(t=>{i[n[t]]=t});const o={type:"error",data:"parser error"},a="function"==typeof Blob||"undefined"!=typeof Blob&&"[object BlobConstructor]"===Object.prototype.toString.call(Blob),r="function"==typeof ArrayBuffer,h=t=>"function"==typeof ArrayBuffer.isView?ArrayBuffer.isView(t):t&&t.buffer instanceof ArrayBuffer,c=({type:t,data:e},s,i)=>a&&e instanceof Blob?s?i(e):l(e,i):r&&(e instanceof ArrayBuffer||h(e))?s?i(e):l(new Blob([e]),i):i(n[t]+(e||"")),l=(t,e)=>{const s=new FileReader;return s.onload=function(){const t=s.result.split(",")[1];e("b"+(t||""))},s.readAsDataURL(t)};function d(t){return t instanceof Uint8Array?t:t instanceof ArrayBuffer?new Uint8Array(t):new Uint8Array(t.buffer,t.byteOffset,t.byteLength)}let u;const g="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",p="undefined"==typeof Uint8Array?[]:new Uint8Array(256);for(let t=0;t<64;t++)p[g.charCodeAt(t)]=t;const m="function"==typeof ArrayBuffer,f=(t,e)=>{if("string"!=typeof t)return{type:"message",data:v(t,e)};const s=t.charAt(0);if("b"===s)return{type:"message",data:y(t.substring(1),e)};return i[s]?t.length>1?{type:i[s],data:t.substring(1)}:{type:i[s]}:o},y=(t,e)=>{if(m){const s=(t=>{let e,s,n,i,o,a=.75*t.length,r=t.length,h=0;"="===t[t.length-1]&&(a--,"="===t[t.length-2]&&a--);const c=new ArrayBuffer(a),l=new Uint8Array(c);for(e=0;e<r;e+=4)s=p[t.charCodeAt(e)],n=p[t.charCodeAt(e+1)],i=p[t.charCodeAt(e+2)],o=p[t.charCodeAt(e+3)],l[h++]=s<<2|n>>4,l[h++]=(15&n)<<4|i>>2,l[h++]=(3&i)<<6|63&o;return c})(t);return v(s,e)}return{base64:!0,data:t}},v=(t,e)=>"blob"===e?t instanceof Blob?t:new Blob([t]):t instanceof ArrayBuffer?t:t.buffer,b=String.fromCharCode(30);function w(){return new TransformStream({transform(t,e){!function(t,e){a&&t.data instanceof Blob?t.data.arrayBuffer().then(d).then(e):r&&(t.data instanceof ArrayBuffer||h(t.data))?e(d(t.data)):c(t,!1,t=>{u||(u=new TextEncoder),e(u.encode(t))})}(t,s=>{const n=s.length;let i;if(n<126)i=new Uint8Array(1),new DataView(i.buffer).setUint8(0,n);else if(n<65536){i=new Uint8Array(3);const t=new DataView(i.buffer);t.setUint8(0,126),t.setUint16(1,n)}else{i=new Uint8Array(9);const t=new DataView(i.buffer);t.setUint8(0,127),t.setBigUint64(1,BigInt(n))}t.data&&"string"!=typeof t.data&&(i[0]|=128),e.enqueue(i),e.enqueue(s)})}})}let k;function x(t){return t.reduce((t,e)=>t+e.length,0)}function C(t,e){if(t[0].length===e)return t.shift();const s=new Uint8Array(e);let n=0;for(let i=0;i<e;i++)s[i]=t[0][n++],n===t[0].length&&(t.shift(),n=0);return t.length&&n<t[0].length&&(t[0]=t[0].slice(n)),s}function T(t){if(t)return function(t){for(var e in T.prototype)t[e]=T.prototype[e];return t}(t)}T.prototype.on=T.prototype.addEventListener=function(t,e){return this._callbacks=this._callbacks||{},(this._callbacks["$"+t]=this._callbacks["$"+t]||[]).push(e),this},T.prototype.once=function(t,e){function s(){this.off(t,s),e.apply(this,arguments)}return s.fn=e,this.on(t,s),this},T.prototype.off=T.prototype.removeListener=T.prototype.removeAllListeners=T.prototype.removeEventListener=function(t,e){if(this._callbacks=this._callbacks||{},0==arguments.length)return this._callbacks={},this;var s,n=this._callbacks["$"+t];if(!n)return this;if(1==arguments.length)return delete this._callbacks["$"+t],this;for(var i=0;i<n.length;i++)if((s=n[i])===e||s.fn===e){n.splice(i,1);break}return 0===n.length&&delete this._callbacks["$"+t],this},T.prototype.emit=function(t){this._callbacks=this._callbacks||{};for(var e=new Array(arguments.length-1),s=this._callbacks["$"+t],n=1;n<arguments.length;n++)e[n-1]=arguments[n];if(s){n=0;for(var i=(s=s.slice(0)).length;n<i;++n)s[n].apply(this,e)}return this},T.prototype.emitReserved=T.prototype.emit,T.prototype.listeners=function(t){return this._callbacks=this._callbacks||{},this._callbacks["$"+t]||[]},T.prototype.hasListeners=function(t){return!!this.listeners(t).length};const E="function"==typeof Promise&&"function"==typeof Promise.resolve?t=>Promise.resolve().then(t):(t,e)=>e(t,0),_="undefined"!=typeof self?self:"undefined"!=typeof window?window:Function("return this")();function S(t,...e){return e.reduce((e,s)=>(t.hasOwnProperty(s)&&(e[s]=t[s]),e),{})}const I=_.setTimeout,M=_.clearTimeout;function R(t,e){e.useNativeTimers?(t.setTimeoutFn=I.bind(_),t.clearTimeoutFn=M.bind(_)):(t.setTimeoutFn=_.setTimeout.bind(_),t.clearTimeoutFn=_.clearTimeout.bind(_))}function O(t){return"string"==typeof t?function(t){let e=0,s=0;for(let n=0,i=t.length;n<i;n++)e=t.charCodeAt(n),e<128?s+=1:e<2048?s+=2:e<55296||e>=57344?s+=3:(n++,s+=4);return s}(t):Math.ceil(1.33*(t.byteLength||t.size))}function L(){return Date.now().toString(36).substring(3)+Math.random().toString(36).substring(2,5)}class j extends Error{constructor(t,e,s){super(t),this.description=e,this.context=s,this.type="TransportError"}}class A extends T{constructor(t){super(),this.writable=!1,R(this,t),this.opts=t,this.query=t.query,this.socket=t.socket,this.supportsBinary=!t.forceBase64}onError(t,e,s){return super.emitReserved("error",new j(t,e,s)),this}open(){return this.readyState="opening",this.doOpen(),this}close(){return"opening"!==this.readyState&&"open"!==this.readyState||(this.doClose(),this.onClose()),this}send(t){"open"===this.readyState&&this.write(t)}onOpen(){this.readyState="open",this.writable=!0,super.emitReserved("open")}onData(t){const e=f(t,this.socket.binaryType);this.onPacket(e)}onPacket(t){super.emitReserved("packet",t)}onClose(t){this.readyState="closed",super.emitReserved("close",t)}pause(t){}createUri(t,e={}){return t+"://"+this._hostname()+this._port()+this.opts.path+this._query(e)}_hostname(){const t=this.opts.hostname;return-1===t.indexOf(":")?t:"["+t+"]"}_port(){return this.opts.port&&(this.opts.secure&&Number(443!==this.opts.port)||!this.opts.secure&&80!==Number(this.opts.port))?":"+this.opts.port:""}_query(t){const e=function(t){let e="";for(let s in t)t.hasOwnProperty(s)&&(e.length&&(e+="&"),e+=encodeURIComponent(s)+"="+encodeURIComponent(t[s]));return e}(t);return e.length?"?"+e:""}}class D extends A{constructor(){super(...arguments),this._polling=!1}get name(){return"polling"}doOpen(){this._poll()}pause(t){this.readyState="pausing";const e=()=>{this.readyState="paused",t()};if(this._polling||!this.writable){let t=0;this._polling&&(t++,this.once("pollComplete",function(){--t||e()})),this.writable||(t++,this.once("drain",function(){--t||e()}))}else e()}_poll(){this._polling=!0,this.doPoll(),this.emitReserved("poll")}onData(t){((t,e)=>{const s=t.split(b),n=[];for(let t=0;t<s.length;t++){const i=f(s[t],e);if(n.push(i),"error"===i.type)break}return n})(t,this.socket.binaryType).forEach(t=>{if("opening"===this.readyState&&"open"===t.type&&this.onOpen(),"close"===t.type)return this.onClose({description:"transport closed by the server"}),!1;this.onPacket(t)}),"closed"!==this.readyState&&(this._polling=!1,this.emitReserved("pollComplete"),"open"===this.readyState&&this._poll())}doClose(){const t=()=>{this.write([{type:"close"}])};"open"===this.readyState?t():this.once("open",t)}write(t){this.writable=!1,((t,e)=>{const s=t.length,n=new Array(s);let i=0;t.forEach((t,o)=>{c(t,!1,t=>{n[o]=t,++i===s&&e(n.join(b))})})})(t,t=>{this.doWrite(t,()=>{this.writable=!0,this.emitReserved("drain")})})}uri(){const t=this.opts.secure?"https":"http",e=this.query||{};return!1!==this.opts.timestampRequests&&(e[this.opts.timestampParam]=L()),this.supportsBinary||e.sid||(e.b64=1),this.createUri(t,e)}}let P=!1;try{P="undefined"!=typeof XMLHttpRequest&&"withCredentials"in new XMLHttpRequest}catch(t){}const B=P;function U(){}class N extends D{constructor(t){if(super(t),"undefined"!=typeof location){const e="https:"===location.protocol;let s=location.port;s||(s=e?"443":"80"),this.xd="undefined"!=typeof location&&t.hostname!==location.hostname||s!==t.port}}doWrite(t,e){const s=this.request({method:"POST",data:t});s.on("success",e),s.on("error",(t,e)=>{this.onError("xhr post error",t,e)})}doPoll(){const t=this.request();t.on("data",this.onData.bind(this)),t.on("error",(t,e)=>{this.onError("xhr poll error",t,e)}),this.pollXhr=t}}class F extends T{constructor(t,e,s){super(),this.createRequest=t,R(this,s),this._opts=s,this._method=s.method||"GET",this._uri=e,this._data=void 0!==s.data?s.data:null,this._create()}_create(){var t;const e=S(this._opts,"agent","pfx","key","passphrase","cert","ca","ciphers","rejectUnauthorized","autoUnref");e.xdomain=!!this._opts.xd;const s=this._xhr=this.createRequest(e);try{s.open(this._method,this._uri,!0);try{if(this._opts.extraHeaders){s.setDisableHeaderCheck&&s.setDisableHeaderCheck(!0);for(let t in this._opts.extraHeaders)this._opts.extraHeaders.hasOwnProperty(t)&&s.setRequestHeader(t,this._opts.extraHeaders[t])}}catch(t){}if("POST"===this._method)try{s.setRequestHeader("Content-type","text/plain;charset=UTF-8")}catch(t){}try{s.setRequestHeader("Accept","*/*")}catch(t){}null===(t=this._opts.cookieJar)||void 0===t||t.addCookies(s),"withCredentials"in s&&(s.withCredentials=this._opts.withCredentials),this._opts.requestTimeout&&(s.timeout=this._opts.requestTimeout),s.onreadystatechange=()=>{var t;3===s.readyState&&(null===(t=this._opts.cookieJar)||void 0===t||t.parseCookies(s.getResponseHeader("set-cookie"))),4===s.readyState&&(200===s.status||1223===s.status?this._onLoad():this.setTimeoutFn(()=>{this._onError("number"==typeof s.status?s.status:0)},0))},s.send(this._data)}catch(t){return void this.setTimeoutFn(()=>{this._onError(t)},0)}"undefined"!=typeof document&&(this._index=F.requestsCount++,F.requests[this._index]=this)}_onError(t){this.emitReserved("error",t,this._xhr),this._cleanup(!0)}_cleanup(t){if(void 0!==this._xhr&&null!==this._xhr){if(this._xhr.onreadystatechange=U,t)try{this._xhr.abort()}catch(t){}"undefined"!=typeof document&&delete F.requests[this._index],this._xhr=null}}_onLoad(){const t=this._xhr.responseText;null!==t&&(this.emitReserved("data",t),this.emitReserved("success"),this._cleanup())}abort(){this._cleanup()}}if(F.requestsCount=0,F.requests={},"undefined"!=typeof document)if("function"==typeof attachEvent)attachEvent("onunload",z);else if("function"==typeof addEventListener){addEventListener("onpagehide"in _?"pagehide":"unload",z,!1)}function z(){for(let t in F.requests)F.requests.hasOwnProperty(t)&&F.requests[t].abort()}const $=function(){const t=q({xdomain:!1});return t&&null!==t.responseType}();function q(t){const e=t.xdomain;try{if("undefined"!=typeof XMLHttpRequest&&(!e||B))return new XMLHttpRequest}catch(t){}if(!e)try{return new(_[["Active"].concat("Object").join("X")])("Microsoft.XMLHTTP")}catch(t){}}const K="undefined"!=typeof navigator&&"string"==typeof navigator.product&&"reactnative"===navigator.product.toLowerCase();class W extends A{get name(){return"websocket"}doOpen(){const t=this.uri(),e=this.opts.protocols,s=K?{}:S(this.opts,"agent","perMessageDeflate","pfx","key","passphrase","cert","ca","ciphers","rejectUnauthorized","localAddress","protocolVersion","origin","maxPayload","family","checkServerIdentity");this.opts.extraHeaders&&(s.headers=this.opts.extraHeaders);try{this.ws=this.createSocket(t,e,s)}catch(t){return this.emitReserved("error",t)}this.ws.binaryType=this.socket.binaryType,this.addEventListeners()}addEventListeners(){this.ws.onopen=()=>{this.opts.autoUnref&&this.ws._socket.unref(),this.onOpen()},this.ws.onclose=t=>this.onClose({description:"websocket connection closed",context:t}),this.ws.onmessage=t=>this.onData(t.data),this.ws.onerror=t=>this.onError("websocket error",t)}write(t){this.writable=!1;for(let e=0;e<t.length;e++){const s=t[e],n=e===t.length-1;c(s,this.supportsBinary,t=>{try{this.doWrite(s,t)}catch(t){}n&&E(()=>{this.writable=!0,this.emitReserved("drain")},this.setTimeoutFn)})}}doClose(){void 0!==this.ws&&(this.ws.onerror=()=>{},this.ws.close(),this.ws=null)}uri(){const t=this.opts.secure?"wss":"ws",e=this.query||{};return this.opts.timestampRequests&&(e[this.opts.timestampParam]=L()),this.supportsBinary||(e.b64=1),this.createUri(t,e)}}const H=_.WebSocket||_.MozWebSocket;const V={websocket:class extends W{createSocket(t,e,s){return K?new H(t,e,s):e?new H(t,e):new H(t)}doWrite(t,e){this.ws.send(e)}},webtransport:class extends A{get name(){return"webtransport"}doOpen(){try{this._transport=new WebTransport(this.createUri("https"),this.opts.transportOptions[this.name])}catch(t){return this.emitReserved("error",t)}this._transport.closed.then(()=>{this.onClose()}).catch(t=>{this.onError("webtransport error",t)}),this._transport.ready.then(()=>{this._transport.createBidirectionalStream().then(t=>{const e=function(t,e){k||(k=new TextDecoder);const s=[];let n=0,i=-1,a=!1;return new TransformStream({transform(r,h){for(s.push(r);;){if(0===n){if(x(s)<1)break;const t=C(s,1);a=!(128&~t[0]),i=127&t[0],n=i<126?3:126===i?1:2}else if(1===n){if(x(s)<2)break;const t=C(s,2);i=new DataView(t.buffer,t.byteOffset,t.length).getUint16(0),n=3}else if(2===n){if(x(s)<8)break;const t=C(s,8),e=new DataView(t.buffer,t.byteOffset,t.length),a=e.getUint32(0);if(a>Math.pow(2,21)-1){h.enqueue(o);break}i=a*Math.pow(2,32)+e.getUint32(4),n=3}else{if(x(s)<i)break;const t=C(s,i);h.enqueue(f(a?t:k.decode(t),e)),n=0}if(0===i||i>t){h.enqueue(o);break}}}})}(Number.MAX_SAFE_INTEGER,this.socket.binaryType),s=t.readable.pipeThrough(e).getReader(),n=w();n.readable.pipeTo(t.writable),this._writer=n.writable.getWriter();const i=()=>{s.read().then(({done:t,value:e})=>{t||(this.onPacket(e),i())}).catch(t=>{})};i();const a={type:"open"};this.query.sid&&(a.data=`{"sid":"${this.query.sid}"}`),this._writer.write(a).then(()=>this.onOpen())})})}write(t){this.writable=!1;for(let e=0;e<t.length;e++){const s=t[e],n=e===t.length-1;this._writer.write(s).then(()=>{n&&E(()=>{this.writable=!0,this.emitReserved("drain")},this.setTimeoutFn)})}}doClose(){var t;null===(t=this._transport)||void 0===t||t.close()}},polling:class extends N{constructor(t){super(t);const e=t&&t.forceBase64;this.supportsBinary=$&&!e}request(t={}){return Object.assign(t,{xd:this.xd},this.opts),new F(q,this.uri(),t)}}},J=/^(?:(?![^:@\/?#]+:[^:@\/]*@)(http|https|ws|wss):\/\/)?((?:(([^:@\/?#]*)(?::([^:@\/?#]*))?)?@)?((?:[a-f0-9]{0,4}:){2,7}[a-f0-9]{0,4}|[^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/,Y=["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"];function G(t){if(t.length>8e3)throw"URI too long";const e=t,s=t.indexOf("["),n=t.indexOf("]");-1!=s&&-1!=n&&(t=t.substring(0,s)+t.substring(s,n).replace(/:/g,";")+t.substring(n,t.length));let i=J.exec(t||""),o={},a=14;for(;a--;)o[Y[a]]=i[a]||"";return-1!=s&&-1!=n&&(o.source=e,o.host=o.host.substring(1,o.host.length-1).replace(/;/g,":"),o.authority=o.authority.replace("[","").replace("]","").replace(/;/g,":"),o.ipv6uri=!0),o.pathNames=function(t,e){const s=/\/{2,9}/g,n=e.replace(s,"/").split("/");"/"!=e.slice(0,1)&&0!==e.length||n.splice(0,1);"/"==e.slice(-1)&&n.splice(n.length-1,1);return n}(0,o.path),o.queryKey=function(t,e){const s={};return e.replace(/(?:^|&)([^&=]*)=?([^&]*)/g,function(t,e,n){e&&(s[e]=n)}),s}(0,o.query),o}const X="function"==typeof addEventListener&&"function"==typeof removeEventListener,Q=[];X&&addEventListener("offline",()=>{Q.forEach(t=>t())},!1);class Z extends T{constructor(t,e){if(super(),this.binaryType="arraybuffer",this.writeBuffer=[],this._prevBufferLen=0,this._pingInterval=-1,this._pingTimeout=-1,this._maxPayload=-1,this._pingTimeoutTime=1/0,t&&"object"==typeof t&&(e=t,t=null),t){const s=G(t);e.hostname=s.host,e.secure="https"===s.protocol||"wss"===s.protocol,e.port=s.port,s.query&&(e.query=s.query)}else e.host&&(e.hostname=G(e.host).host);R(this,e),this.secure=null!=e.secure?e.secure:"undefined"!=typeof location&&"https:"===location.protocol,e.hostname&&!e.port&&(e.port=this.secure?"443":"80"),this.hostname=e.hostname||("undefined"!=typeof location?location.hostname:"localhost"),this.port=e.port||("undefined"!=typeof location&&location.port?location.port:this.secure?"443":"80"),this.transports=[],this._transportsByName={},e.transports.forEach(t=>{const e=t.prototype.name;this.transports.push(e),this._transportsByName[e]=t}),this.opts=Object.assign({path:"/engine.io",agent:!1,withCredentials:!1,upgrade:!0,timestampParam:"t",rememberUpgrade:!1,addTrailingSlash:!0,rejectUnauthorized:!0,perMessageDeflate:{threshold:1024},transportOptions:{},closeOnBeforeunload:!1},e),this.opts.path=this.opts.path.replace(/\/$/,"")+(this.opts.addTrailingSlash?"/":""),"string"==typeof this.opts.query&&(this.opts.query=function(t){let e={},s=t.split("&");for(let t=0,n=s.length;t<n;t++){let n=s[t].split("=");e[decodeURIComponent(n[0])]=decodeURIComponent(n[1])}return e}(this.opts.query)),X&&(this.opts.closeOnBeforeunload&&(this._beforeunloadEventListener=()=>{this.transport&&(this.transport.removeAllListeners(),this.transport.close())},addEventListener("beforeunload",this._beforeunloadEventListener,!1)),"localhost"!==this.hostname&&(this._offlineEventListener=()=>{this._onClose("transport close",{description:"network connection lost"})},Q.push(this._offlineEventListener))),this.opts.withCredentials&&(this._cookieJar=void 0),this._open()}createTransport(t){const e=Object.assign({},this.opts.query);e.EIO=4,e.transport=t,this.id&&(e.sid=this.id);const s=Object.assign({},this.opts,{query:e,socket:this,hostname:this.hostname,secure:this.secure,port:this.port},this.opts.transportOptions[t]);return new this._transportsByName[t](s)}_open(){if(0===this.transports.length)return void this.setTimeoutFn(()=>{this.emitReserved("error","No transports available")},0);const t=this.opts.rememberUpgrade&&Z.priorWebsocketSuccess&&-1!==this.transports.indexOf("websocket")?"websocket":this.transports[0];this.readyState="opening";const e=this.createTransport(t);e.open(),this.setTransport(e)}setTransport(t){this.transport&&this.transport.removeAllListeners(),this.transport=t,t.on("drain",this._onDrain.bind(this)).on("packet",this._onPacket.bind(this)).on("error",this._onError.bind(this)).on("close",t=>this._onClose("transport close",t))}onOpen(){this.readyState="open",Z.priorWebsocketSuccess="websocket"===this.transport.name,this.emitReserved("open"),this.flush()}_onPacket(t){if("opening"===this.readyState||"open"===this.readyState||"closing"===this.readyState)switch(this.emitReserved("packet",t),this.emitReserved("heartbeat"),t.type){case"open":this.onHandshake(JSON.parse(t.data));break;case"ping":this._sendPacket("pong"),this.emitReserved("ping"),this.emitReserved("pong"),this._resetPingTimeout();break;case"error":const e=new Error("server error");e.code=t.data,this._onError(e);break;case"message":this.emitReserved("data",t.data),this.emitReserved("message",t.data)}}onHandshake(t){this.emitReserved("handshake",t),this.id=t.sid,this.transport.query.sid=t.sid,this._pingInterval=t.pingInterval,this._pingTimeout=t.pingTimeout,this._maxPayload=t.maxPayload,this.onOpen(),"closed"!==this.readyState&&this._resetPingTimeout()}_resetPingTimeout(){this.clearTimeoutFn(this._pingTimeoutTimer);const t=this._pingInterval+this._pingTimeout;this._pingTimeoutTime=Date.now()+t,this._pingTimeoutTimer=this.setTimeoutFn(()=>{this._onClose("ping timeout")},t),this.opts.autoUnref&&this._pingTimeoutTimer.unref()}_onDrain(){this.writeBuffer.splice(0,this._prevBufferLen),this._prevBufferLen=0,0===this.writeBuffer.length?this.emitReserved("drain"):this.flush()}flush(){if("closed"!==this.readyState&&this.transport.writable&&!this.upgrading&&this.writeBuffer.length){const t=this._getWritablePackets();this.transport.send(t),this._prevBufferLen=t.length,this.emitReserved("flush")}}_getWritablePackets(){if(!(this._maxPayload&&"polling"===this.transport.name&&this.writeBuffer.length>1))return this.writeBuffer;let t=1;for(let e=0;e<this.writeBuffer.length;e++){const s=this.writeBuffer[e].data;if(s&&(t+=O(s)),e>0&&t>this._maxPayload)return this.writeBuffer.slice(0,e);t+=2}return this.writeBuffer}_hasPingExpired(){if(!this._pingTimeoutTime)return!0;const t=Date.now()>this._pingTimeoutTime;return t&&(this._pingTimeoutTime=0,E(()=>{this._onClose("ping timeout")},this.setTimeoutFn)),t}write(t,e,s){return this._sendPacket("message",t,e,s),this}send(t,e,s){return this._sendPacket("message",t,e,s),this}_sendPacket(t,e,s,n){if("function"==typeof e&&(n=e,e=void 0),"function"==typeof s&&(n=s,s=null),"closing"===this.readyState||"closed"===this.readyState)return;(s=s||{}).compress=!1!==s.compress;const i={type:t,data:e,options:s};this.emitReserved("packetCreate",i),this.writeBuffer.push(i),n&&this.once("flush",n),this.flush()}close(){const t=()=>{this._onClose("forced close"),this.transport.close()},e=()=>{this.off("upgrade",e),this.off("upgradeError",e),t()},s=()=>{this.once("upgrade",e),this.once("upgradeError",e)};return"opening"!==this.readyState&&"open"!==this.readyState||(this.readyState="closing",this.writeBuffer.length?this.once("drain",()=>{this.upgrading?s():t()}):this.upgrading?s():t()),this}_onError(t){if(Z.priorWebsocketSuccess=!1,this.opts.tryAllTransports&&this.transports.length>1&&"opening"===this.readyState)return this.transports.shift(),this._open();this.emitReserved("error",t),this._onClose("transport error",t)}_onClose(t,e){if("opening"===this.readyState||"open"===this.readyState||"closing"===this.readyState){if(this.clearTimeoutFn(this._pingTimeoutTimer),this.transport.removeAllListeners("close"),this.transport.close(),this.transport.removeAllListeners(),X&&(this._beforeunloadEventListener&&removeEventListener("beforeunload",this._beforeunloadEventListener,!1),this._offlineEventListener)){const t=Q.indexOf(this._offlineEventListener);-1!==t&&Q.splice(t,1)}this.readyState="closed",this.id=null,this.emitReserved("close",t,e),this.writeBuffer=[],this._prevBufferLen=0}}}Z.protocol=4;class tt extends Z{constructor(){super(...arguments),this._upgrades=[]}onOpen(){if(super.onOpen(),"open"===this.readyState&&this.opts.upgrade)for(let t=0;t<this._upgrades.length;t++)this._probe(this._upgrades[t])}_probe(t){let e=this.createTransport(t),s=!1;Z.priorWebsocketSuccess=!1;const n=()=>{s||(e.send([{type:"ping",data:"probe"}]),e.once("packet",t=>{if(!s)if("pong"===t.type&&"probe"===t.data){if(this.upgrading=!0,this.emitReserved("upgrading",e),!e)return;Z.priorWebsocketSuccess="websocket"===e.name,this.transport.pause(()=>{s||"closed"!==this.readyState&&(c(),this.setTransport(e),e.send([{type:"upgrade"}]),this.emitReserved("upgrade",e),e=null,this.upgrading=!1,this.flush())})}else{const t=new Error("probe error");t.transport=e.name,this.emitReserved("upgradeError",t)}}))};function i(){s||(s=!0,c(),e.close(),e=null)}const o=t=>{const s=new Error("probe error: "+t);s.transport=e.name,i(),this.emitReserved("upgradeError",s)};function a(){o("transport closed")}function r(){o("socket closed")}function h(t){e&&t.name!==e.name&&i()}const c=()=>{e.removeListener("open",n),e.removeListener("error",o),e.removeListener("close",a),this.off("close",r),this.off("upgrading",h)};e.once("open",n),e.once("error",o),e.once("close",a),this.once("close",r),this.once("upgrading",h),-1!==this._upgrades.indexOf("webtransport")&&"webtransport"!==t?this.setTimeoutFn(()=>{s||e.open()},200):e.open()}onHandshake(t){this._upgrades=this._filterUpgrades(t.upgrades),super.onHandshake(t)}_filterUpgrades(t){const e=[];for(let s=0;s<t.length;s++)~this.transports.indexOf(t[s])&&e.push(t[s]);return e}}let et=class extends tt{constructor(t,e={}){const s="object"==typeof t?t:e;(!s.transports||s.transports&&"string"==typeof s.transports[0])&&(s.transports=(s.transports||["polling","websocket","webtransport"]).map(t=>V[t]).filter(t=>!!t)),super(t,s)}};const st="function"==typeof ArrayBuffer,nt=Object.prototype.toString,it="function"==typeof Blob||"undefined"!=typeof Blob&&"[object BlobConstructor]"===nt.call(Blob),ot="function"==typeof File||"undefined"!=typeof File&&"[object FileConstructor]"===nt.call(File);function at(t){return st&&(t instanceof ArrayBuffer||(t=>"function"==typeof ArrayBuffer.isView?ArrayBuffer.isView(t):t.buffer instanceof ArrayBuffer)(t))||it&&t instanceof Blob||ot&&t instanceof File}function rt(t,e){if(!t||"object"!=typeof t)return!1;if(Array.isArray(t)){for(let e=0,s=t.length;e<s;e++)if(rt(t[e]))return!0;return!1}if(at(t))return!0;if(t.toJSON&&"function"==typeof t.toJSON&&1===arguments.length)return rt(t.toJSON(),!0);for(const e in t)if(Object.prototype.hasOwnProperty.call(t,e)&&rt(t[e]))return!0;return!1}function ht(t){const e=[],s=t.data,n=t;return n.data=ct(s,e),n.attachments=e.length,{packet:n,buffers:e}}function ct(t,e){if(!t)return t;if(at(t)){const s={_placeholder:!0,num:e.length};return e.push(t),s}if(Array.isArray(t)){const s=new Array(t.length);for(let n=0;n<t.length;n++)s[n]=ct(t[n],e);return s}if("object"==typeof t&&!(t instanceof Date)){const s={};for(const n in t)Object.prototype.hasOwnProperty.call(t,n)&&(s[n]=ct(t[n],e));return s}return t}function lt(t,e){return t.data=dt(t.data,e),delete t.attachments,t}function dt(t,e){if(!t)return t;if(t&&!0===t._placeholder){if("number"==typeof t.num&&t.num>=0&&t.num<e.length)return e[t.num];throw new Error("illegal attachments")}if(Array.isArray(t))for(let s=0;s<t.length;s++)t[s]=dt(t[s],e);else if("object"==typeof t)for(const s in t)Object.prototype.hasOwnProperty.call(t,s)&&(t[s]=dt(t[s],e));return t}const ut=["connect","connect_error","disconnect","disconnecting","newListener","removeListener"];var gt;!function(t){t[t.CONNECT=0]="CONNECT",t[t.DISCONNECT=1]="DISCONNECT",t[t.EVENT=2]="EVENT",t[t.ACK=3]="ACK",t[t.CONNECT_ERROR=4]="CONNECT_ERROR",t[t.BINARY_EVENT=5]="BINARY_EVENT",t[t.BINARY_ACK=6]="BINARY_ACK"}(gt||(gt={}));function pt(t){return"[object Object]"===Object.prototype.toString.call(t)}class mt extends T{constructor(t){super(),this.reviver=t}add(t){let e;if("string"==typeof t){if(this.reconstructor)throw new Error("got plaintext data when reconstructing a packet");e=this.decodeString(t);const s=e.type===gt.BINARY_EVENT;s||e.type===gt.BINARY_ACK?(e.type=s?gt.EVENT:gt.ACK,this.reconstructor=new ft(e),0===e.attachments&&super.emitReserved("decoded",e)):super.emitReserved("decoded",e)}else{if(!at(t)&&!t.base64)throw new Error("Unknown type: "+t);if(!this.reconstructor)throw new Error("got binary data when not reconstructing a packet");e=this.reconstructor.takeBinaryData(t),e&&(this.reconstructor=null,super.emitReserved("decoded",e))}}decodeString(t){let e=0;const s={type:Number(t.charAt(0))};if(void 0===gt[s.type])throw new Error("unknown packet type "+s.type);if(s.type===gt.BINARY_EVENT||s.type===gt.BINARY_ACK){const n=e+1;for(;"-"!==t.charAt(++e)&&e!=t.length;);const i=t.substring(n,e);if(i!=Number(i)||"-"!==t.charAt(e))throw new Error("Illegal attachments");s.attachments=Number(i)}if("/"===t.charAt(e+1)){const n=e+1;for(;++e;){if(","===t.charAt(e))break;if(e===t.length)break}s.nsp=t.substring(n,e)}else s.nsp="/";const n=t.charAt(e+1);if(""!==n&&Number(n)==n){const n=e+1;for(;++e;){const s=t.charAt(e);if(null==s||Number(s)!=s){--e;break}if(e===t.length)break}s.id=Number(t.substring(n,e+1))}if(t.charAt(++e)){const n=this.tryParse(t.substr(e));if(!mt.isPayloadValid(s.type,n))throw new Error("invalid payload");s.data=n}return s}tryParse(t){try{return JSON.parse(t,this.reviver)}catch(t){return!1}}static isPayloadValid(t,e){switch(t){case gt.CONNECT:return pt(e);case gt.DISCONNECT:return void 0===e;case gt.CONNECT_ERROR:return"string"==typeof e||pt(e);case gt.EVENT:case gt.BINARY_EVENT:return Array.isArray(e)&&("number"==typeof e[0]||"string"==typeof e[0]&&-1===ut.indexOf(e[0]));case gt.ACK:case gt.BINARY_ACK:return Array.isArray(e)}}destroy(){this.reconstructor&&(this.reconstructor.finishedReconstruction(),this.reconstructor=null)}}class ft{constructor(t){this.packet=t,this.buffers=[],this.reconPack=t}takeBinaryData(t){if(this.buffers.push(t),this.buffers.length===this.reconPack.attachments){const t=lt(this.reconPack,this.buffers);return this.finishedReconstruction(),t}return null}finishedReconstruction(){this.reconPack=null,this.buffers=[]}}var yt=Object.freeze({__proto__:null,Decoder:mt,Encoder:class{constructor(t){this.replacer=t}encode(t){return t.type!==gt.EVENT&&t.type!==gt.ACK||!rt(t)?[this.encodeAsString(t)]:this.encodeAsBinary({type:t.type===gt.EVENT?gt.BINARY_EVENT:gt.BINARY_ACK,nsp:t.nsp,data:t.data,id:t.id})}encodeAsString(t){let e=""+t.type;return t.type!==gt.BINARY_EVENT&&t.type!==gt.BINARY_ACK||(e+=t.attachments+"-"),t.nsp&&"/"!==t.nsp&&(e+=t.nsp+","),null!=t.id&&(e+=t.id),null!=t.data&&(e+=JSON.stringify(t.data,this.replacer)),e}encodeAsBinary(t){const e=ht(t),s=this.encodeAsString(e.packet),n=e.buffers;return n.unshift(s),n}},get PacketType(){return gt},protocol:5});function vt(t,e,s){return t.on(e,s),function(){t.off(e,s)}}const bt=Object.freeze({connect:1,connect_error:1,disconnect:1,disconnecting:1,newListener:1,removeListener:1});class wt extends T{constructor(t,e,s){super(),this.connected=!1,this.recovered=!1,this.receiveBuffer=[],this.sendBuffer=[],this._queue=[],this._queueSeq=0,this.ids=0,this.acks={},this.flags={},this.io=t,this.nsp=e,s&&s.auth&&(this.auth=s.auth),this._opts=Object.assign({},s),this.io._autoConnect&&this.open()}get disconnected(){return!this.connected}subEvents(){if(this.subs)return;const t=this.io;this.subs=[vt(t,"open",this.onopen.bind(this)),vt(t,"packet",this.onpacket.bind(this)),vt(t,"error",this.onerror.bind(this)),vt(t,"close",this.onclose.bind(this))]}get active(){return!!this.subs}connect(){return this.connected||(this.subEvents(),this.io._reconnecting||this.io.open(),"open"===this.io._readyState&&this.onopen()),this}open(){return this.connect()}send(...t){return t.unshift("message"),this.emit.apply(this,t),this}emit(t,...e){var s,n,i;if(bt.hasOwnProperty(t))throw new Error('"'+t.toString()+'" is a reserved event name');if(e.unshift(t),this._opts.retries&&!this.flags.fromQueue&&!this.flags.volatile)return this._addToQueue(e),this;const o={type:gt.EVENT,data:e,options:{}};if(o.options.compress=!1!==this.flags.compress,"function"==typeof e[e.length-1]){const t=this.ids++,s=e.pop();this._registerAckCallback(t,s),o.id=t}const a=null===(n=null===(s=this.io.engine)||void 0===s?void 0:s.transport)||void 0===n?void 0:n.writable,r=this.connected&&!(null===(i=this.io.engine)||void 0===i?void 0:i._hasPingExpired());return this.flags.volatile&&!a||(r?(this.notifyOutgoingListeners(o),this.packet(o)):this.sendBuffer.push(o)),this.flags={},this}_registerAckCallback(t,e){var s;const n=null!==(s=this.flags.timeout)&&void 0!==s?s:this._opts.ackTimeout;if(void 0===n)return void(this.acks[t]=e);const i=this.io.setTimeoutFn(()=>{delete this.acks[t];for(let e=0;e<this.sendBuffer.length;e++)this.sendBuffer[e].id===t&&this.sendBuffer.splice(e,1);e.call(this,new Error("operation has timed out"))},n),o=(...t)=>{this.io.clearTimeoutFn(i),e.apply(this,t)};o.withError=!0,this.acks[t]=o}emitWithAck(t,...e){return new Promise((s,n)=>{const i=(t,e)=>t?n(t):s(e);i.withError=!0,e.push(i),this.emit(t,...e)})}_addToQueue(t){let e;"function"==typeof t[t.length-1]&&(e=t.pop());const s={id:this._queueSeq++,tryCount:0,pending:!1,args:t,flags:Object.assign({fromQueue:!0},this.flags)};t.push((t,...n)=>{if(s!==this._queue[0])return;return null!==t?s.tryCount>this._opts.retries&&(this._queue.shift(),e&&e(t)):(this._queue.shift(),e&&e(null,...n)),s.pending=!1,this._drainQueue()}),this._queue.push(s),this._drainQueue()}_drainQueue(t=!1){if(!this.connected||0===this._queue.length)return;const e=this._queue[0];e.pending&&!t||(e.pending=!0,e.tryCount++,this.flags=e.flags,this.emit.apply(this,e.args))}packet(t){t.nsp=this.nsp,this.io._packet(t)}onopen(){"function"==typeof this.auth?this.auth(t=>{this._sendConnectPacket(t)}):this._sendConnectPacket(this.auth)}_sendConnectPacket(t){this.packet({type:gt.CONNECT,data:this._pid?Object.assign({pid:this._pid,offset:this._lastOffset},t):t})}onerror(t){this.connected||this.emitReserved("connect_error",t)}onclose(t,e){this.connected=!1,delete this.id,this.emitReserved("disconnect",t,e),this._clearAcks()}_clearAcks(){Object.keys(this.acks).forEach(t=>{if(!this.sendBuffer.some(e=>String(e.id)===t)){const e=this.acks[t];delete this.acks[t],e.withError&&e.call(this,new Error("socket has been disconnected"))}})}onpacket(t){if(t.nsp===this.nsp)switch(t.type){case gt.CONNECT:t.data&&t.data.sid?this.onconnect(t.data.sid,t.data.pid):this.emitReserved("connect_error",new Error("It seems you are trying to reach a Socket.IO server in v2.x with a v3.x client, but they are not compatible (more information here: https://socket.io/docs/v3/migrating-from-2-x-to-3-0/)"));break;case gt.EVENT:case gt.BINARY_EVENT:this.onevent(t);break;case gt.ACK:case gt.BINARY_ACK:this.onack(t);break;case gt.DISCONNECT:this.ondisconnect();break;case gt.CONNECT_ERROR:this.destroy();const e=new Error(t.data.message);e.data=t.data.data,this.emitReserved("connect_error",e)}}onevent(t){const e=t.data||[];null!=t.id&&e.push(this.ack(t.id)),this.connected?this.emitEvent(e):this.receiveBuffer.push(Object.freeze(e))}emitEvent(t){if(this._anyListeners&&this._anyListeners.length){const e=this._anyListeners.slice();for(const s of e)s.apply(this,t)}super.emit.apply(this,t),this._pid&&t.length&&"string"==typeof t[t.length-1]&&(this._lastOffset=t[t.length-1])}ack(t){const e=this;let s=!1;return function(...n){s||(s=!0,e.packet({type:gt.ACK,id:t,data:n}))}}onack(t){const e=this.acks[t.id];"function"==typeof e&&(delete this.acks[t.id],e.withError&&t.data.unshift(null),e.apply(this,t.data))}onconnect(t,e){this.id=t,this.recovered=e&&this._pid===e,this._pid=e,this.connected=!0,this.emitBuffered(),this.emitReserved("connect"),this._drainQueue(!0)}emitBuffered(){this.receiveBuffer.forEach(t=>this.emitEvent(t)),this.receiveBuffer=[],this.sendBuffer.forEach(t=>{this.notifyOutgoingListeners(t),this.packet(t)}),this.sendBuffer=[]}ondisconnect(){this.destroy(),this.onclose("io server disconnect")}destroy(){this.subs&&(this.subs.forEach(t=>t()),this.subs=void 0),this.io._destroy(this)}disconnect(){return this.connected&&this.packet({type:gt.DISCONNECT}),this.destroy(),this.connected&&this.onclose("io client disconnect"),this}close(){return this.disconnect()}compress(t){return this.flags.compress=t,this}get volatile(){return this.flags.volatile=!0,this}timeout(t){return this.flags.timeout=t,this}onAny(t){return this._anyListeners=this._anyListeners||[],this._anyListeners.push(t),this}prependAny(t){return this._anyListeners=this._anyListeners||[],this._anyListeners.unshift(t),this}offAny(t){if(!this._anyListeners)return this;if(t){const e=this._anyListeners;for(let s=0;s<e.length;s++)if(t===e[s])return e.splice(s,1),this}else this._anyListeners=[];return this}listenersAny(){return this._anyListeners||[]}onAnyOutgoing(t){return this._anyOutgoingListeners=this._anyOutgoingListeners||[],this._anyOutgoingListeners.push(t),this}prependAnyOutgoing(t){return this._anyOutgoingListeners=this._anyOutgoingListeners||[],this._anyOutgoingListeners.unshift(t),this}offAnyOutgoing(t){if(!this._anyOutgoingListeners)return this;if(t){const e=this._anyOutgoingListeners;for(let s=0;s<e.length;s++)if(t===e[s])return e.splice(s,1),this}else this._anyOutgoingListeners=[];return this}listenersAnyOutgoing(){return this._anyOutgoingListeners||[]}notifyOutgoingListeners(t){if(this._anyOutgoingListeners&&this._anyOutgoingListeners.length){const e=this._anyOutgoingListeners.slice();for(const s of e)s.apply(this,t.data)}}}function kt(t){t=t||{},this.ms=t.min||100,this.max=t.max||1e4,this.factor=t.factor||2,this.jitter=t.jitter>0&&t.jitter<=1?t.jitter:0,this.attempts=0}kt.prototype.duration=function(){var t=this.ms*Math.pow(this.factor,this.attempts++);if(this.jitter){var e=Math.random(),s=Math.floor(e*this.jitter*t);t=1&Math.floor(10*e)?t+s:t-s}return 0|Math.min(t,this.max)},kt.prototype.reset=function(){this.attempts=0},kt.prototype.setMin=function(t){this.ms=t},kt.prototype.setMax=function(t){this.max=t},kt.prototype.setJitter=function(t){this.jitter=t};class xt extends T{constructor(t,e){var s;super(),this.nsps={},this.subs=[],t&&"object"==typeof t&&(e=t,t=void 0),(e=e||{}).path=e.path||"/socket.io",this.opts=e,R(this,e),this.reconnection(!1!==e.reconnection),this.reconnectionAttempts(e.reconnectionAttempts||1/0),this.reconnectionDelay(e.reconnectionDelay||1e3),this.reconnectionDelayMax(e.reconnectionDelayMax||5e3),this.randomizationFactor(null!==(s=e.randomizationFactor)&&void 0!==s?s:.5),this.backoff=new kt({min:this.reconnectionDelay(),max:this.reconnectionDelayMax(),jitter:this.randomizationFactor()}),this.timeout(null==e.timeout?2e4:e.timeout),this._readyState="closed",this.uri=t;const n=e.parser||yt;this.encoder=new n.Encoder,this.decoder=new n.Decoder,this._autoConnect=!1!==e.autoConnect,this._autoConnect&&this.open()}reconnection(t){return arguments.length?(this._reconnection=!!t,t||(this.skipReconnect=!0),this):this._reconnection}reconnectionAttempts(t){return void 0===t?this._reconnectionAttempts:(this._reconnectionAttempts=t,this)}reconnectionDelay(t){var e;return void 0===t?this._reconnectionDelay:(this._reconnectionDelay=t,null===(e=this.backoff)||void 0===e||e.setMin(t),this)}randomizationFactor(t){var e;return void 0===t?this._randomizationFactor:(this._randomizationFactor=t,null===(e=this.backoff)||void 0===e||e.setJitter(t),this)}reconnectionDelayMax(t){var e;return void 0===t?this._reconnectionDelayMax:(this._reconnectionDelayMax=t,null===(e=this.backoff)||void 0===e||e.setMax(t),this)}timeout(t){return arguments.length?(this._timeout=t,this):this._timeout}maybeReconnectOnOpen(){!this._reconnecting&&this._reconnection&&0===this.backoff.attempts&&this.reconnect()}open(t){if(~this._readyState.indexOf("open"))return this;this.engine=new et(this.uri,this.opts);const e=this.engine,s=this;this._readyState="opening",this.skipReconnect=!1;const n=vt(e,"open",function(){s.onopen(),t&&t()}),i=e=>{this.cleanup(),this._readyState="closed",this.emitReserved("error",e),t?t(e):this.maybeReconnectOnOpen()},o=vt(e,"error",i);if(!1!==this._timeout){const t=this._timeout,s=this.setTimeoutFn(()=>{n(),i(new Error("timeout")),e.close()},t);this.opts.autoUnref&&s.unref(),this.subs.push(()=>{this.clearTimeoutFn(s)})}return this.subs.push(n),this.subs.push(o),this}connect(t){return this.open(t)}onopen(){this.cleanup(),this._readyState="open",this.emitReserved("open");const t=this.engine;this.subs.push(vt(t,"ping",this.onping.bind(this)),vt(t,"data",this.ondata.bind(this)),vt(t,"error",this.onerror.bind(this)),vt(t,"close",this.onclose.bind(this)),vt(this.decoder,"decoded",this.ondecoded.bind(this)))}onping(){this.emitReserved("ping")}ondata(t){try{this.decoder.add(t)}catch(t){this.onclose("parse error",t)}}ondecoded(t){E(()=>{this.emitReserved("packet",t)},this.setTimeoutFn)}onerror(t){this.emitReserved("error",t)}socket(t,e){let s=this.nsps[t];return s?this._autoConnect&&!s.active&&s.connect():(s=new wt(this,t,e),this.nsps[t]=s),s}_destroy(t){const e=Object.keys(this.nsps);for(const t of e){if(this.nsps[t].active)return}this._close()}_packet(t){const e=this.encoder.encode(t);for(let s=0;s<e.length;s++)this.engine.write(e[s],t.options)}cleanup(){this.subs.forEach(t=>t()),this.subs.length=0,this.decoder.destroy()}_close(){this.skipReconnect=!0,this._reconnecting=!1,this.onclose("forced close")}disconnect(){return this._close()}onclose(t,e){var s;this.cleanup(),null===(s=this.engine)||void 0===s||s.close(),this.backoff.reset(),this._readyState="closed",this.emitReserved("close",t,e),this._reconnection&&!this.skipReconnect&&this.reconnect()}reconnect(){if(this._reconnecting||this.skipReconnect)return this;const t=this;if(this.backoff.attempts>=this._reconnectionAttempts)this.backoff.reset(),this.emitReserved("reconnect_failed"),this._reconnecting=!1;else{const e=this.backoff.duration();this._reconnecting=!0;const s=this.setTimeoutFn(()=>{t.skipReconnect||(this.emitReserved("reconnect_attempt",t.backoff.attempts),t.skipReconnect||t.open(e=>{e?(t._reconnecting=!1,t.reconnect(),this.emitReserved("reconnect_error",e)):t.onreconnect()}))},e);this.opts.autoUnref&&s.unref(),this.subs.push(()=>{this.clearTimeoutFn(s)})}}onreconnect(){const t=this.backoff.attempts;this._reconnecting=!1,this.backoff.reset(),this.emitReserved("reconnect",t)}}const Ct={};function Tt(t,e){"object"==typeof t&&(e=t,t=void 0);const s=function(t,e="",s){let n=t;s=s||"undefined"!=typeof location&&location,null==t&&(t=s.protocol+"//"+s.host),"string"==typeof t&&("/"===t.charAt(0)&&(t="/"===t.charAt(1)?s.protocol+t:s.host+t),/^(https?|wss?):\/\//.test(t)||(t=void 0!==s?s.protocol+"//"+t:"https://"+t),n=G(t)),n.port||(/^(http|ws)$/.test(n.protocol)?n.port="80":/^(http|ws)s$/.test(n.protocol)&&(n.port="443")),n.path=n.path||"/";const i=-1!==n.host.indexOf(":")?"["+n.host+"]":n.host;return n.id=n.protocol+"://"+i+":"+n.port+e,n.href=n.protocol+"://"+i+(s&&s.port===n.port?"":":"+n.port),n}(t,(e=e||{}).path||"/socket.io"),n=s.source,i=s.id,o=s.path,a=Ct[i]&&o in Ct[i].nsps;let r;return e.forceNew||e["force new connection"]||!1===e.multiplex||a?r=new xt(n,e):(Ct[i]||(Ct[i]=new xt(n,e)),r=Ct[i]),s.query&&!e.query&&(e.query=s.queryKey),r.socket(s.path,e)}Object.assign(Tt,{Manager:xt,Socket:wt,io:Tt,connect:Tt});class Et extends e{constructor(t){super(),this.socket=null,this.reconnectAttempts=0,this.maxReconnectAttempts=5,this.reconnectDelay=1e3,this.config=t}connect(){var e;if(null===(e=this.socket)||void 0===e?void 0:e.connected)return;const s=this.config.socketUrl||this.config.apiBaseUrl||window.location.origin;try{this.socket=Tt(s,{transports:["websocket","polling"],timeout:1e4,forceNew:!0}),this.setupEventListeners()}catch(e){this.emit("error",new t("Failed to connect to socket server","SOCKET_CONNECTION_ERROR",e))}}disconnect(){this.socket&&(this.socket.disconnect(),this.socket=null),this.reconnectAttempts=0}isConnected(){var t;return(null===(t=this.socket)||void 0===t?void 0:t.connected)||!1}joinRoom(e,s,n){var i;if(!(null===(i=this.socket)||void 0===i?void 0:i.connected))throw new t("Socket not connected","SOCKET_NOT_CONNECTED");this.socket.emit("join-project",{projectId:e,userId:s,username:n})}leaveRoom(t,e){var s;(null===(s=this.socket)||void 0===s?void 0:s.connected)&&this.socket.emit("leave-project",{projectId:t,userId:e})}sendMessage(e,s,n,i="text"){var o;if(!(null===(o=this.socket)||void 0===o?void 0:o.connected))throw new t("Socket not connected","SOCKET_NOT_CONNECTED");this.socket.emit("send-message",{projectId:e,userId:s,content:n,messageType:i,timestamp:(new Date).toISOString()})}startTyping(t,e){var s;(null===(s=this.socket)||void 0===s?void 0:s.connected)&&this.socket.emit("start-typing",{projectId:t,userId:e})}stopTyping(t,e){var s;(null===(s=this.socket)||void 0===s?void 0:s.connected)&&this.socket.emit("stop-typing",{projectId:t,userId:e})}setupEventListeners(){this.socket&&(this.socket.on("connect",()=>{this.reconnectAttempts=0,this.emit("connected")}),this.socket.on("disconnect",t=>{this.emit("disconnected",t),"io server disconnect"===t&&this.handleReconnect()}),this.socket.on("connect_error",e=>{this.emit("error",new t("Socket connection error","SOCKET_CONNECTION_ERROR",e)),this.handleReconnect()}),this.socket.on("user-joined",t=>{this.emit("user-joined",t)}),this.socket.on("user-left",t=>{this.emit("user-left",t)}),this.socket.on("new-message",t=>{this.emit("new-message",t)}),this.socket.on("user-typing",t=>{this.emit("user-typing",t)}),this.socket.on("user-stopped-typing",t=>{this.emit("user-stopped-typing",t)}),this.socket.on("simulation-ended",t=>{this.emit("simulation-ended",t)}),this.socket.on("error",e=>{this.emit("error",new t("Socket error","SOCKET_ERROR",e))}))}handleReconnect(){if(this.reconnectAttempts>=this.maxReconnectAttempts)return void this.emit("error",new t("Max reconnection attempts reached","SOCKET_RECONNECT_FAILED"));this.reconnectAttempts++;const e=this.reconnectDelay*Math.pow(2,this.reconnectAttempts-1);setTimeout(()=>{var t;(null===(t=this.socket)||void 0===t?void 0:t.connected)||this.connect()},e)}}function _t(t,e,s){const n=document.createElement(t);return e&&(n.className=e),n}function St(t){const e=document.createElement("div");return e.textContent=t,e.innerHTML}function It(t,e=!0){t.scrollTop=t.scrollHeight,t.scrollTo&&t.scrollTo({top:t.scrollHeight,behavior:e?"smooth":"auto"})}class Mt extends e{constructor(t,e){super(),this.simulationData=null,this.displayedMessages=[],this.currentMessageIndex=0,this.isRunning=!1,this.isPaused=!1,this.intervalId=null,this.pollingId=null,this.burstPhase=!0,this.totalToShow=1/0,this.virtualLastTimestamp=null,this.realLastTimestamp=null,this.lastTimestamp=null,this.lastDelayMs=0,this.userId="",this.config=t,this.apiClient=e}async initialize(){try{const t=this.config.language||"en",e=this.getPersistedUserId(),s=e||this.config.userId||this.generateUserId();this.userId=s,e||this.persistUserId(s);const n=await this.apiClient.getSimulationData(this.config.projectId,s,t);if(!n.success||!n.data)throw new Error("Failed to load simulation data");this.simulationData=n.data;const i=this.simulationData.project.initialBurstCount+this.simulationData.project.continuousCount;this.totalToShow=Math.min(i,this.simulationData.messages.length);const o=this.loadProgress();o&&"number"==typeof o.index?(this.currentMessageIndex=o.index,o.lastTimestamp&&(this.virtualLastTimestamp=new Date(o.lastTimestamp),this.lastTimestamp=new Date(o.lastTimestamp))):(this.currentMessageIndex=0,this.virtualLastTimestamp=null,this.lastTimestamp=null),this.realLastTimestamp=null,await this.loadExistingMessages(),await this.reconstructVirtualHistoryForDisplay(),this.emit("initialized",this.simulationData),this.startPolling(),!1!==this.config.autoStart&&this.start()}catch(t){throw this.emit("error",t),t}}start(){this.simulationData&&!this.isRunning&&(this.isRunning=!0,this.isPaused=!1,this.burstPhase=!0,this.emit("simulationStart"),this.performInitialBurst(),this.currentMessageIndex<this.totalToShow?(this.burstPhase=!1,this.scheduleNextMessage()):(this.isRunning=!1,this.emit("simulationEnd")))}performInitialBurst(){if(!this.simulationData)return;const{project:t,messages:e}=this.simulationData,s=t.initialBurstCount,n=Math.min(s,this.totalToShow,e.length);if(this.currentMessageIndex>=n)return;if(this.displayedMessages.some(t=>t.id.startsWith("sim-"))&&this.currentMessageIndex>0)return;const i=new Date,o=new Array(n);let a=new Date(i);for(let t=n-1;t>=0;t--)if(o[t]=new Date(a),t>0){const t=10+Math.floor(11*Math.random());a=new Date(a.getTime()-60*t*1e3)}const r=[];let h=!1;for(let t=this.currentMessageIndex;t<n;t++){const s=e[t];if(s.hasScreenshot&&s.screenshotUrl){const e={id:`sim-${t}-text-${Date.now()}`,content:s.content,messageType:"text",timestamp:o[t],isOwnMessage:!1,virtualUser:s.virtualUser};this.displayedMessages.push(e),r.push(e);const n=new Date(o[t].getTime()+2e3),i={id:`sim-${t}-image-${Date.now()}`,content:s.screenshotUrl,messageType:"image",timestamp:n,isOwnMessage:!1,virtualUser:s.virtualUser};this.displayedMessages.push(i),r.push(i)}else{const e={id:`sim-${t}-${Date.now()}`,content:s.content,messageType:s.messageType,timestamp:o[t],isOwnMessage:!1,virtualUser:s.virtualUser};this.displayedMessages.push(e),r.push(e)}this.currentMessageIndex=t+1,h=!0}h&&(this.lastTimestamp=o[n-1],this.virtualLastTimestamp=this.lastTimestamp,this.displayedMessages.sort((t,e)=>t.timestamp.getTime()-e.timestamp.getTime()),this.emit("messages-batch",r)),this.saveProgress()}pause(){this.isRunning&&(this.isPaused=!0,this.intervalId&&(clearTimeout(this.intervalId),this.intervalId=null),this.emit("simulationPause"))}resume(){this.isRunning&&this.isPaused&&(this.isPaused=!1,this.scheduleNextMessage(),this.emit("simulationResume"))}stop(){this.isRunning=!1,this.isPaused=!1,this.intervalId&&(clearTimeout(this.intervalId),this.intervalId=null),this.emit("simulationStop")}destroy(){this.stop(),this.stopPolling(),this.removeAllListeners()}scheduleNextMessage(){if(!this.simulationData||!this.isRunning||this.isPaused)return;const{project:t,messages:e}=this.simulationData;if(this.currentMessageIndex>=this.totalToShow)return this.isRunning=!1,void this.emit("simulationEnd");let s;if(this.burstPhase){const n=Math.min(t.initialBurstCount,e.length);this.currentMessageIndex<n?s=500+1e3*Math.random():(this.burstPhase=!1,s=this.getRandomInterval(t.messageIntervalMin,t.messageIntervalMax))}else{const n=Math.min(t.initialBurstCount,e.length);s=this.currentMessageIndex-n<5?1e3*(t.initialMessageInterval||10):this.getRandomInterval(t.messageIntervalMin,t.messageIntervalMax)}this.lastDelayMs=s,this.intervalId=setTimeout(()=>{this.displayNextMessage(),this.scheduleNextMessage()},s)}displayNextMessage(){if(!this.simulationData||this.currentMessageIndex>=this.simulationData.messages.length)return;const t=this.simulationData.messages[this.currentMessageIndex],e=this.lastTimestamp||new Date,s=new Date(e.getTime()+(this.lastDelayMs||0));if(this.lastTimestamp=s,t.hasScreenshot&&t.screenshotUrl){const e={id:`sim-${this.currentMessageIndex}-text-${Date.now()}`,content:t.content,messageType:"text",timestamp:s,isOwnMessage:!1,virtualUser:t.virtualUser};this.displayedMessages.push(e),this.emit("message",e);const n=new Date(s.getTime()+2e3),i={id:`sim-${this.currentMessageIndex}-image-${Date.now()}`,content:t.screenshotUrl,messageType:"image",timestamp:n,isOwnMessage:!1,virtualUser:t.virtualUser};this.displayedMessages.push(i),this.lastTimestamp=n,setTimeout(()=>{this.emit("message",i)},2e3)}else{const e={id:`sim-${this.currentMessageIndex}-${Date.now()}`,content:t.content,messageType:t.messageType,timestamp:s,isOwnMessage:!1,virtualUser:t.virtualUser};this.displayedMessages.push(e),this.emit("message",e)}this.currentMessageIndex++,this.saveProgress()}async loadExistingMessages(){if(this.simulationData)try{const t=this.userId||this.config.userId||this.generateUserId(),e=await this.apiClient.getSimulationMessages(this.config.projectId,t,void 0,100);if(e.success&&e.messages&&e.messages.length>0){const s=e.messages.sort((t,e)=>new Date(t.createdAt||t.timestamp).getTime()-new Date(e.createdAt||e.timestamp).getTime()),n=new Set(this.displayedMessages.map(t=>t.id));for(const e of s){if(n.has(e.id))continue;const s={id:e.id,content:e.content,messageType:e.messageType,timestamp:new Date(e.createdAt||e.timestamp),isOwnMessage:e.userId===t,virtualUser:e.virtualUser,user:e.userId===t?{id:t,username:this.config.username||"You"}:void 0};this.displayedMessages.push(s)}if(s.length>0){const t=s[s.length-1];this.realLastTimestamp=new Date(t.createdAt||t.timestamp)}this.displayedMessages.length>0&&this.emit("messages-batch",[...this.displayedMessages])}}catch(t){console.warn("Failed to load existing messages:",t)}}startPolling(){const t=this.config.pollingInterval||3e3;this.pollingId=setInterval(async()=>{await this.pollForNewMessages()},t)}stopPolling(){this.pollingId&&(clearInterval(this.pollingId),this.pollingId=null)}async pollForNewMessages(){if(this.simulationData)try{const t=this.userId||this.config.userId||this.generateUserId(),e=this.getLastMessageTimestamp(),s=await this.apiClient.getSimulationMessages(this.config.projectId,t,e);if(s.success&&s.messages&&s.messages.length>0){const e=new Set(this.displayedMessages.map(t=>t.id));let n=null;for(const i of s.messages){if(e.has(i.id))continue;const s=new Date(i.createdAt),o={id:i.id,content:i.content,messageType:i.messageType,timestamp:s,isOwnMessage:i.userId===t,virtualUser:i.virtualUser,user:i.userId===t?{id:t,username:this.config.username||"You"}:void 0};(!n||s>n)&&(n=s),this.displayedMessages.push(o),this.emit("message",o)}n&&(this.realLastTimestamp=n)}}catch(t){console.warn("Polling error:",t)}}async reconstructVirtualHistoryForDisplay(){if(!this.simulationData)return;const t=Math.min(this.currentMessageIndex,this.totalToShow,this.simulationData.messages.length);if(t<=0)return;const e=this.loadProgress(),s=(null==e?void 0:e.virtualMessages)||[];if(s.length>0){const t=[],e=new Set(this.displayedMessages.map(t=>t.id));for(const n of s)if(!e.has(n.id)){const e={id:n.id,content:n.content,messageType:n.messageType,timestamp:new Date(n.timestamp),isOwnMessage:!1,virtualUser:n.virtualUser};t.push(e)}if(t.length>0){this.displayedMessages.push(...t),this.displayedMessages.sort((t,e)=>t.timestamp.getTime()-e.timestamp.getTime());const e=t[t.length-1];this.virtualLastTimestamp=e.timestamp,this.lastTimestamp=e.timestamp,this.emit("messages-batch",t)}return}const n=new Date,i=new Array(t);let o=new Date(n);for(let e=t-1;e>=0;e--)if(i[e]=new Date(o),e>0){const t=10+Math.floor(11*Math.random());o=new Date(o.getTime()-60*t*1e3)}const a=[],{messages:r}=this.simulationData;for(let e=0;e<t;e++){const t=r[e],s=i[e];if(t.hasScreenshot&&t.screenshotUrl){const n={id:`sim-${e}-text`,content:t.content,messageType:"text",timestamp:s,isOwnMessage:!1,virtualUser:t.virtualUser},i={id:`sim-${e}-image`,content:t.screenshotUrl,messageType:"image",timestamp:new Date(s.getTime()+2e3),isOwnMessage:!1,virtualUser:t.virtualUser};a.push(n,i)}else{const n={id:`sim-${e}`,content:t.content,messageType:t.messageType,timestamp:s,isOwnMessage:!1,virtualUser:t.virtualUser};a.push(n)}}const h=new Set(this.displayedMessages.map(t=>t.id)),c=a.filter(t=>!h.has(t.id));if(0===c.length)return;this.displayedMessages.push(...c),this.displayedMessages.sort((t,e)=>t.timestamp.getTime()-e.timestamp.getTime());const l=c[c.length-1];this.virtualLastTimestamp=l.timestamp,this.lastTimestamp=l.timestamp,this.emit("messages-batch",c)}getLastMessageTimestamp(){if(this.realLastTimestamp)return this.realLastTimestamp.toISOString()}getUserKey(){return`vcs:user:${this.config.projectId}`}getProgressKey(){const t=this.userId||this.config.userId||"anon";return`vcs:progress:${this.config.projectId}:${t}`}getPersistedUserId(){try{return"undefined"==typeof window?null:window.localStorage.getItem(this.getUserKey())}catch(t){return null}}persistUserId(t){try{if("undefined"==typeof window)return;window.localStorage.setItem(this.getUserKey(),t)}catch(t){}}loadProgress(){try{if("undefined"==typeof window)return null;const t=window.localStorage.getItem(this.getProgressKey());return t?JSON.parse(t):null}catch(t){return null}}saveProgress(){try{if("undefined"==typeof window)return;const t=this.displayedMessages.filter(t=>t.id.startsWith("sim-")).map(t=>({id:t.id,content:t.content,messageType:t.messageType,timestamp:t.timestamp.toISOString(),virtualUser:t.virtualUser})),e={index:this.currentMessageIndex,lastTimestamp:this.lastTimestamp?this.lastTimestamp.toISOString():void 0,virtualMessages:t};window.localStorage.setItem(this.getProgressKey(),JSON.stringify(e))}catch(t){}}clearProgress(){try{if("undefined"==typeof window)return;window.localStorage.removeItem(this.getProgressKey())}catch(t){}}clearCachedProgress(){this.clearProgress()}getRandomInterval(t,e){return 1e3*(t+Math.random()*(e-t))}generateUserId(){return`user-${Date.now()}-${Math.random().toString(36).substring(2,11)}`}get messages(){return[...this.displayedMessages]}get isSimulationRunning(){return this.isRunning}get isSimulationPaused(){return this.isPaused}get data(){return this.simulationData}async sendMessage(t,e="text"){if(!this.simulationData)throw new Error("Simulation not initialized");const s=this.userId||this.config.userId||this.generateUserId(),n=this.config.username||"User";try{if("image"===e||"string"==typeof t&&t.startsWith("data:image/"))return;await Promise.all([this.apiClient.sendUserMessage(this.config.projectId,s,n,t,e),this.apiClient.triggerAIReply(this.config.projectId,s,n,t,e)])}catch(t){throw this.emit("error",t),t}}}class Rt extends e{constructor(t){var e,n;super(),this.emojiPanelOpen=!1,this.onlineCount=0,this.currentTheme="whatsapp",this.isDarkMode=!1,this.customColors={},this.visibleStartIndex=0,this.config=t,this.currentTheme="telegram"===t.uiTemplate?"telegram":"whatsapp",this.isDarkMode="dark"===t.theme,this.customColors={primary:t.primaryColor,background:t.backgroundColor},this.onlineCount=500+Math.floor(301*Math.random()),this.initialRenderCount=null!==(e=this.config.initialRenderCount)&&void 0!==e?e:Number.MAX_SAFE_INTEGER,this.lazyLoadBatchSize=null!==(n=this.config.lazyLoadBatchSize)&&void 0!==n?n:20,this.state={isInitialized:!1,isOpen:!1,isJoined:!1,isConnected:!1,isSimulationRunning:!1,isSimulationPaused:!1,messages:[],virtualUsers:[],realUsers:[],typingUsers:[],simulationEnded:!1,displayedMessageCount:0,unreadCount:0,lastReadMessageId:null,inputFocused:!1},this.apiClient=new s(t),this.simulator=new Mt(t,this.apiClient),this.setupSimulatorEvents(),this.init()}init(){try{console.log("[ChatWidget] Starting initialization..."),this.setupContainer(),console.log("[ChatWidget] Container setup complete"),this.createWidget(),console.log("[ChatWidget] Widget created"),"floating"===this.config.mode&&(console.log("[ChatWidget] Setting up floating mode"),this.widgetElement.style.display="none",this.createFloatingButton(),console.log("[ChatWidget] Floating button created")),this.setupEventListeners(),this.setupImageViewer(),this.state.isInitialized=!0,this.emit("ready"),console.log("[ChatWidget] Widget initialization complete"),this.initializeSimulation()}catch(e){this.emit("error",new t("Failed to initialize chat widget","WIDGET_INIT_ERROR",e))}}setupSimulatorEvents(){this.simulator.on("initialized",t=>{var e;this.state.currentProject=t.project,this.state.currentTemplate=t.template,null!=this.config.initialRenderCount?this.initialRenderCount=this.config.initialRenderCount:this.initialRenderCount=Number.MAX_SAFE_INTEGER;const s=(this.config.language||"en").startsWith("zh")?"条消息":"messages";this.setTitle((null===(e=t.project)||void 0===e?void 0:e.name)||"Chat",`0 ${s}`),this.setLoading(!1),this.emit("simulationInitialized",t)}),this.simulator.on("message",t=>{var e;this.setLoading(!1),this.addMessage(t),this.state.displayedMessageCount++;const s=(this.config.language||"en").startsWith("zh")?"条消息":"messages",n=(null===(e=this.state.currentProject)||void 0===e?void 0:e.name)||"Chat";this.setTitle(n,`${this.state.displayedMessageCount} ${s}`)}),this.simulator.on("messages-batch",t=>{var e;this.setLoading(!1),this.addMessagesBulk(t),this.state.displayedMessageCount+=t.length;const s=(this.config.language||"en").startsWith("zh")?"条消息":"messages",n=(null===(e=this.state.currentProject)||void 0===e?void 0:e.name)||"Chat";this.setTitle(n,`${this.state.displayedMessageCount} ${s}`),setTimeout(()=>{this.scrollToBottom(!0)},100)}),this.simulator.on("simulationStart",()=>{var t,e;this.state.isSimulationRunning=!0,this.state.isSimulationPaused=!1,null===(e=(t=this.config).onSimulationStart)||void 0===e||e.call(t)}),this.simulator.on("simulationEnd",()=>{var t,e;this.state.isSimulationRunning=!1,this.state.simulationEnded=!0,null===(e=(t=this.config).onSimulationEnd)||void 0===e||e.call(t)}),this.simulator.on("simulationPause",()=>{this.state.isSimulationPaused=!0}),this.simulator.on("simulationResume",()=>{this.state.isSimulationPaused=!1}),this.simulator.on("error",t=>{this.emit("error",t)})}async initializeSimulation(){try{await this.simulator.initialize()}catch(e){this.emit("error",new t("Failed to initialize simulation","SIMULATION_INIT_ERROR",e))}}setupContainer(){var e;const s="string"==typeof(n=this.config.container)?document.querySelector(n):n;var n;if(!s)throw new t("Container element not found","CONTAINER_NOT_FOUND");const i=null===(e=s.tagName)||void 0===e?void 0:e.toUpperCase();if("BODY"===i||"HTML"===i){const t=document.createElement("div");t.className="chat-sdk-host",t.style.position="static",t.style.width="0",t.style.height="0",document.body.appendChild(t),this.container=t}else this.container=s;this.shadowRoot=this.container.attachShadow({mode:"closed"});const o=this.getDefaultStyles();!function(t,e){const s=document.createElement("style");s.textContent=e,t.appendChild(s)}(this.shadowRoot,o)}createWidget(){var t;if(this.widgetElement&&this.messagesContainer)return;this.widgetElement=_t("div","chat-sdk-container");const e="telegram"===this.config.uiTemplate?"telegram":"whatsapp";this.currentTheme=e,this.widgetElement.classList.add(`${e}-theme`),"telegram"===e&&"dark"===this.config.theme&&(this.widgetElement.classList.add("dark"),this.isDarkMode=!0),this.widgetElement.style.position="fixed",this.widgetElement.style.top="0",this.widgetElement.style.left="0",this.widgetElement.style.width="100vw",this.widgetElement.style.height="100vh",this.widgetElement.style.zIndex=String(null!==(t=this.config.zIndex)&&void 0!==t?t:2147483e3),this.widgetElement.innerHTML='\n <div class="chat-sdk-header">\n <div class="chat-sdk-header-left">\n <div class="chat-sdk-title" id="chat-title"></div>\n <div class="chat-sdk-subtitle" id="chat-subtitle"></div>\n </div>\n <button class="chat-sdk-close-btn" type="button">\n <svg width="20" height="20" viewBox="0 0 16 16" fill="currentColor">\n <path d="M8 7.293l2.146-2.147a.5.5 0 01.708.708L8.707 8l2.147 2.146a.5.5 0 01-.708.708L8 8.707l-2.146 2.147a.5.5 0 01-.708-.708L7.293 8 5.146 5.854a.5.5 0 01.708-.708L8 7.293z"/>\n </svg>\n </button>\n </div>\n\n <div class="chat-sdk-messages" id="messages-container">\n <div class="chat-sdk-loading">\n <div class="chat-sdk-spinner"></div>\n Loading chat...\n </div>\n </div>\n\n <div class="chat-sdk-input-area">\n <button class="chat-sdk-icon-btn chat-sdk-emoji-btn" type="button" id="emoji-button" aria-label="Emoji">\n <span>😊</span>\n </button>\n <button class="chat-sdk-icon-btn chat-sdk-image-btn" type="button" id="image-button" aria-label="Image">\n <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor"><path d="M21 19V5a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v14h18zM5 5h14v8l-3-3-4 5-3-4-4 4V5z"/></svg>\n </button>\n <textarea\n class="chat-sdk-input"\n placeholder="Type a message..."\n rows="1"\n id="message-input"\n ></textarea>\n <input type="file" accept="image/*" id="image-input" style="display:none" />\n <button class="chat-sdk-send-btn" type="button" id="send-button" disabled>\n <svg width="16" height="16" viewBox="0 0 16 16" fill="currentColor">\n <path d="M15.854.146a.5.5 0 01.11.54l-5.819 14.547a.75.75 0 01-1.329.124l-3.178-4.995L.643 7.184a.75.75 0 01.124-1.33L15.314.037a.5.5 0 01.54.11z"/>\n </svg>\n </button>\n </div>\n <div class="chat-sdk-emoji-picker" id="emoji-picker" style="display:none">\n <div class="chat-sdk-emoji-grid">\n <button type="button" class="chat-sdk-emoji-item" data-emoji="😀">😀</button>\n <button type="button" class="chat-sdk-emoji-item" data-emoji="😁">😁</button>\n <button type="button" class="chat-sdk-emoji-item" data-emoji="😂">😂</button>\n <button type="button" class="chat-sdk-emoji-item" data-emoji="🤣">🤣</button>\n <button type="button" class="chat-sdk-emoji-item" data-emoji="😊">😊</button>\n <button type="button" class="chat-sdk-emoji-item" data-emoji="😍">😍</button>\n <button type="button" class="chat-sdk-emoji-item" data-emoji="😎">😎</button>\n <button type="button" class="chat-sdk-emoji-item" data-emoji="🤔">🤔</button>\n <button type="button" class="chat-sdk-emoji-item" data-emoji="👍">👍</button>\n <button type="button" class="chat-sdk-emoji-item" data-emoji="🙏">🙏</button>\n </div>\n </div>\n ',this.messagesContainer=this.widgetElement.querySelector("#messages-container"),this.inputElement=this.widgetElement.querySelector("#message-input"),this.sendButton=this.widgetElement.querySelector("#send-button"),this.emojiButton=this.widgetElement.querySelector("#emoji-button"),this.imageButton=this.widgetElement.querySelector("#image-button"),this.fileInput=this.widgetElement.querySelector("#image-input"),this.emojiPicker=this.widgetElement.querySelector("#emoji-picker"),this.shadowRoot.appendChild(this.widgetElement)}setupEventListeners(){var t,e,s,n;const i=this.widgetElement.querySelector(".chat-sdk-close-btn");null==i||i.addEventListener("click",()=>this.close()),this.messagesContainer.addEventListener("scroll",this.handleScrollLazyLoad.bind(this)),this.inputElement.addEventListener("input",this.handleInputChange.bind(this)),this.inputElement.addEventListener("keydown",this.handleKeyDown.bind(this)),this.inputElement.addEventListener("focus",this.handleInputFocus.bind(this)),this.inputElement.addEventListener("blur",this.handleInputBlur.bind(this)),this.sendButton.addEventListener("click",this.handleSendMessage.bind(this)),this.inputElement.addEventListener("input",this.autoResizeTextarea.bind(this)),null===(t=this.emojiButton)||void 0===t||t.addEventListener("click",t=>{t.preventDefault(),t.stopPropagation(),this.toggleEmojiPicker(!this.emojiPanelOpen)}),null===(e=this.emojiPicker)||void 0===e||e.addEventListener("click",t=>{const e=t.target.closest(".chat-sdk-emoji-item");if(e&&e.hasAttribute("data-emoji")){const t=e.getAttribute("data-emoji")||"";this.insertEmojiAtCursor(t),this.toggleEmojiPicker(!1)}}),this.shadowRoot.addEventListener("click",t=>{const e=t.target,s=e.closest("#emoji-picker"),n=e.closest("#emoji-button");s||n||this.toggleEmojiPicker(!1)}),null===(s=this.imageButton)||void 0===s||s.addEventListener("click",t=>{var e;t.preventDefault(),t.stopPropagation(),null===(e=this.fileInput)||void 0===e||e.click()}),null===(n=this.fileInput)||void 0===n||n.addEventListener("change",this.handleImageSelected.bind(this)),document.addEventListener("keydown",t=>{var e;if("Escape"!==t.key)return;if(!this.state.isOpen)return;const s=(null===(e=this.shadowRoot)||void 0===e?void 0:e.activeElement)||document.activeElement,n=!!s&&(s===this.inputElement||"TEXTAREA"===s.tagName||"INPUT"===s.tagName||s.isContentEditable);this.state.inputFocused||n?console.log("[ChatWidget] Ignored Escape while input focused"):this.isTelegramMiniprogram()?console.log("[ChatWidget] Ignored Escape in Telegram environment"):this.close()}),this.setupTelegramMiniprogramHandling()}createFloatingButton(){var t,e,s,n,i,o,a,r,h,c,l;if(console.log("[ChatWidget] Creating floating button..."),!this.shadowRoot)return void console.error("[ChatWidget] No shadow root available for floating button");const d=this.config.floatingButton||{},u=d.position||"bottom-right",g=String(null!==(e=null!==(t=d.zIndex)&&void 0!==t?t:this.config.zIndex)&&void 0!==e?e:2147483e3),p={top:null===(s=d.offset)||void 0===s?void 0:s.top,right:null===(n=d.offset)||void 0===n?void 0:n.right,bottom:null!==(o=null===(i=d.offset)||void 0===i?void 0:i.bottom)&&void 0!==o?o:20,left:null===(a=d.offset)||void 0===a?void 0:a.left};console.log("[ChatWidget] Floating button config:",{pos:u,z:g,offset:p});const m=document.createElement("button");m.className="chat-sdk-floating-btn",m.setAttribute("aria-label","Open chat"),m.innerHTML='\n <svg width="24" height="24" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">\n <path d="M20 2H4a2 2 0 00-2 2v14l4-4h14a2 2 0 002-2V4a2 2 0 00-2-2z"/>\n </svg>\n <span class="chat-sdk-unread-badge" style="\n position: absolute;\n top: -2px;\n right: -2px;\n background: #ff4444;\n color: white;\n border-radius: 10px;\n min-width: 20px;\n height: 20px;\n display: none;\n align-items: center;\n justify-content: center;\n font-size: 12px;\n font-weight: 600;\n line-height: 1;\n border: 2px solid white;\n box-shadow: 0 2px 4px rgba(0,0,0,0.2);\n "></span>\n ',m.style.position="fixed",m.style.zIndex=g,m.style.width="56px",m.style.height="56px",m.style.borderRadius="9999px",m.style.border="none",m.style.cursor="pointer",m.style.display="flex",m.style.alignItems="center",m.style.justifyContent="center",m.style.color="#fff",m.style.boxShadow="0 8px 20px rgba(0,0,0,0.2)",m.style.background="linear-gradient(135deg, #2481cc 0%, #1c7cd6 100%)",m.style.transition="transform .15s ease, box-shadow .15s ease, opacity .2s ease",u.includes("bottom")?(m.style.bottom=(null!==(r=p.bottom)&&void 0!==r?r:20)+"px",m.style.top=""):(m.style.top=(null!==(h=p.top)&&void 0!==h?h:20)+"px",m.style.bottom=""),u.includes("right")?(m.style.right=(null!==(c=p.right)&&void 0!==c?c:20)+"px",m.style.left=""):(m.style.left=(null!==(l=p.left)&&void 0!==l?l:20)+"px",m.style.right=""),m.addEventListener("mouseenter",()=>{m.style.transform="scale(1.06)",m.style.boxShadow="0 10px 24px rgba(0,0,0,0.24)"}),m.addEventListener("mouseleave",()=>{m.style.transform="scale(1)",m.style.boxShadow="0 8px 20px rgba(0,0,0,0.2)"}),m.addEventListener("mousedown",()=>{m.style.transform="scale(0.96)"}),m.addEventListener("mouseup",()=>{m.style.transform="scale(1.02)",setTimeout(()=>m.style.transform="scale(1)",120)}),m.addEventListener("click",t=>{t.preventDefault(),this.open()}),this.shadowRoot.appendChild(m),this.floatingButtonEl=m,console.log("[ChatWidget] Floating button successfully created and added to DOM"),console.log("[ChatWidget] Button element:",this.floatingButtonEl),console.log("[ChatWidget] Button visible:","none"!==this.floatingButtonEl.style.display)}updateUnreadBadge(){if(!this.floatingButtonEl)return;const t=this.floatingButtonEl.querySelector(".chat-sdk-unread-badge");if(!t)return;const e=this.state.unreadCount;e>0?(t.textContent=e>99?"99+":e.toString(),t.style.display="flex"):t.style.display="none"}markAllAsRead(){if(this.state.messages.length>0){const t=this.state.messages[this.state.messages.length-1];this.state.lastReadMessageId=t.id}this.state.unreadCount=0,this.updateUnreadBadge()}incrementUnreadCount(){this.state.isOpen||(this.state.unreadCount++,this.updateUnreadBadge())}toggleEmojiPicker(t){const e=this.emojiPicker;if(!e)return;const s="boolean"==typeof t?t:"none"===e.style.display;e.style.display=s?"block":"none",this.emojiPanelOpen=s}insertEmojiAtCursor(t){const e=this.inputElement,s=e.selectionStart||0,n=e.selectionEnd||0,i=e.value.substring(0,s),o=e.value.substring(n);e.value=i+t+o;const a=s+t.length;e.setSelectionRange(a,a),e.focus(),this.handleInputChange(),this.autoResizeTextarea()}isEmojiOnly(t){const e=t.trim();if(!e)return!1;if(e.length>6)return!1;let s=!1;for(let t=0;t<e.length;){const n=e.codePointAt(t)||0;if(t+=n>65535?2:1,!(n>=126976))return!1;s=!0}return s}async handleImageSelected(){const e=this.fileInput;if(!e||!e.files||0===e.files.length)return;const s=e.files[0];try{const t=await this.resizeImageFile(s,1280,.85),n={id:`local-img-failed-${Date.now()}-${Math.random().toString(36).slice(2,8)}`,content:t,messageType:"image",timestamp:new Date,isOwnMessage:!0,user:{id:this.config.userId||"me",username:this.config.username||"You"},failed:!0};this.state.messages.push(n),this.renderMessage(n),this.scrollToBottom(!0),e.value=""}catch(e){console.error("Image processing failed",e),this.emit("error",new t("Image processing failed","IMAGE_PROCESS_ERROR",e))}}resizeImageFile(t,e=1280,s=.85){return new Promise((n,i)=>{const o=URL.createObjectURL(t),a=new Image;a.onload=()=>{let{width:t,height:r}=a;const h=Math.min(1,e/Math.max(t,r)),c=document.createElement("canvas");h<1&&(t=Math.round(t*h),r=Math.round(r*h)),c.width=t,c.height=r;const l=c.getContext("2d");if(!l)return URL.revokeObjectURL(o),void i(new Error("Canvas not supported"));l.drawImage(a,0,0,t,r);const d=c.toDataURL("image/jpeg",s);URL.revokeObjectURL(o),n(d)},a.onerror=t=>{URL.revokeObjectURL(o),i(t)},a.src=o})}handleInputChange(){const t=this.inputElement.value.trim().length>0,e=!1!==this.config.enableUserInput&&!1!==this.config.allowInput;this.sendButton.disabled=!t||!e,t&&e&&this.emit("typing")}handleKeyDown(t){"Enter"!==t.key||t.shiftKey||(t.preventDefault(),this.handleSendMessage())}async handleSendMessage(){const e=this.inputElement.value.trim();if(!e)return;if(!1===this.config.enableUserInput||!1===this.config.allowInput)return;const s=this.isEmojiOnly(e)?"emoji":"text",n={id:`local-${Date.now()}-${Math.random().toString(36).slice(2,8)}`,content:e,messageType:s,timestamp:new Date,isOwnMessage:!0,user:{id:this.config.userId||"me",username:this.config.username||"You"}};this.state.messages.push(n),this.renderMessage(n),this.scrollToBottom(!0),this.inputElement.value="",this.sendButton.disabled=!0,this.autoResizeTextarea(),this.simulator.sendMessage(e,s).catch(e=>{console.error("Failed to send message:",e),this.emit("error",new t("Failed to send message","SEND_MESSAGE_ERROR",e))})}autoResizeTextarea(){this.inputElement.style.height="auto",this.inputElement.style.height=Math.min(this.inputElement.scrollHeight,100)+"px"}handleInputFocus(){this.isTelegramMiniprogram()&&(this.state.inputFocused=!0,this.state.isOpen||this.open())}handleInputBlur(){this.isTelegramMiniprogram()&&setTimeout(()=>{this.state.inputFocused=!1},100)}isTelegramMiniprogram(){var t;try{if("undefined"!=typeof window&&(null===(t=window.Telegram)||void 0===t?void 0:t.WebApp))return console.log("[ChatSDK] Detected Telegram WebApp API"),!0;if("undefined"!=typeof navigator){const t=navigator.userAgent.toLowerCase();if(t.includes("telegram")||t.includes("tgwebapp"))return console.log("[ChatSDK] Detected Telegram in User Agent:",t),!0}return!1}catch(t){return console.warn("[ChatSDK] Error detecting Telegram environment:",t),!1}}setupTelegramMiniprogramHandling(){const t=this.isTelegramMiniprogram();if(console.log("[ChatSDK] Telegram environment check:",t),!t)return void console.log("[ChatSDK] Not in Telegram environment, skipping special handling");console.log("[ChatSDK] Detected Telegram miniprogram environment, applying compatibility fixes");const e=this.close.bind(this);if(this.close=()=>{this.state.inputFocused?console.log("[ChatSDK] Prevented auto-close due to input focus in Telegram miniprogram"):e()},!document.querySelector('meta[name="viewport"]')){const t=document.createElement("meta");t.name="viewport",t.content="width=device-width, initial-scale=1.0, user-scalable=no",document.head.appendChild(t)}this.inputElement.addEventListener("touchstart",t=>{t.stopPropagation()}),this.inputElement.addEventListener("touchend",t=>{t.stopPropagation()})}open(){var t;if(this.state.isOpen)return;this.floatingButtonEl&&(this.floatingButtonEl.style.display="none"),this.widgetElement.style.opacity="0",this.widgetElement.style.display="flex",requestAnimationFrame(()=>{this.widgetElement.style.transition="opacity .2s ease",this.widgetElement.style.opacity="1"}),this.state.isOpen=!0,this.markAllAsRead(),this.emit("open");const e=(this.config.language||"en").startsWith("zh")?"条消息":"messages",s=(null===(t=this.state.currentProject)||void 0===t?void 0:t.name)||"Chat";this.setTitle(s,`${this.state.displayedMessageCount} ${e}`),this.scrollToBottom(!0),requestAnimationFrame(()=>this.scrollToBottom(!0)),setTimeout(()=>this.scrollToBottom(!0),0)}close(){this.state.isOpen&&(this.widgetElement.style.transition="opacity .2s ease",this.widgetElement.style.opacity="0",setTimeout(()=>{this.widgetElement.style.display="none",this.floatingButtonEl&&(this.floatingButtonEl.style.display="flex")},200),this.state.isOpen=!1,this.emit("close"))}setTitle(t,e){var s,n;const i=null===(s=this.widgetElement)||void 0===s?void 0:s.querySelector("#chat-title"),o=null===(n=this.widgetElement)||void 0===n?void 0:n.querySelector("#chat-subtitle");if("telegram"===this.currentTheme){if(i&&(i.textContent=t||"Chat"),o){const t=(this.config.language||"zh").startsWith("zh");o.textContent=t?`${this.onlineCount} 人在线`:`${this.onlineCount} online`,o.style.display="block"}}else i&&(i.textContent=""),o&&(o.textContent="")}buildMessageElement(t,e){const s=_t("div","chat-sdk-message");t.isOwnMessage&&s.classList.add("own");const n=!!e&&this.shouldGroupWithPrev(e,t);n&&s.classList.add("grouped");let i=null;t.isOwnMessage||(i=this.createAvatar(t),n&&i&&(i.style.visibility="hidden"));const o=!t.isOwnMessage&&!n,a="whatsapp"===this.currentTheme,r="telegram"===this.currentTheme&&t.isOwnMessage,h=this.createMessageContent(t,o,a,r);return i&&s.appendChild(i),s.appendChild(h),s}shouldGroupWithPrev(t,e){var s,n,i,o,a,r,h;if(!1===this.config.groupMessages)return!1;const c=null!==(s=this.config.groupTimeThresholdSec)&&void 0!==s?s:120,l=t.isOwnMessage===e.isOwnMessage,d=(null===(n=t.virtualUser)||void 0===n?void 0:n.id)&&(null===(i=t.virtualUser)||void 0===i?void 0:i.id)===(null===(o=e.virtualUser)||void 0===o?void 0:o.id),u=(null===(a=t.user)||void 0===a?void 0:a.id)&&(null===(r=t.user)||void 0===r?void 0:r.id)===(null===(h=e.user)||void 0===h?void 0:h.id),g=l&&(d||u||t.isOwnMessage&&e.isOwnMessage),p=Math.abs(e.timestamp.getTime()-t.timestamp.getTime())/1e3;return!!g&&p<=c}handleScrollLazyLoad(){if(this.messagesContainer.scrollTop<=20&&this.visibleStartIndex>0){const t=this.messagesContainer.scrollHeight,e=this.lazyLoadBatchSize,s=Math.max(0,this.visibleStartIndex-e),n=this.state.messages.slice(s,this.visibleStartIndex),i=document.createDocumentFragment();for(const t of n){const e=this.buildMessageElement(t);i.appendChild(e)}this.messagesContainer.insertBefore(i,this.messagesContainer.firstChild),this.visibleStartIndex=s;const o=this.messagesContainer.scrollHeight;this.messagesContainer.scrollTop+=o-t}}setLoading(t){if(t){if(!this.messagesContainer.querySelector(".chat-sdk-loading")){const t=document.createElement("div");t.className="chat-sdk-loading",t.innerHTML='\n <div class="chat-sdk-spinner"></div>\n Loading chat...\n ',this.messagesContainer.appendChild(t)}}else{const t=this.messagesContainer.querySelector(".chat-sdk-loading");null==t||t.remove()}}showJoinOverlay(){const t=_t("div","chat-sdk-overlay");t.innerHTML='\n <div class="chat-sdk-join-card">\n <h3 class="chat-sdk-join-title">Join the conversation</h3>\n <p class="chat-sdk-join-description">\n Click below to join this group chat and start interacting with other members.\n </p>\n <button class="chat-sdk-join-btn" type="button">Join Chat</button>\n </div>\n ';const e=t.querySelector(".chat-sdk-join-btn");null==e||e.addEventListener("click",()=>{this.hideJoinOverlay(),this.emit("join-requested")}),this.widgetElement.appendChild(t)}hideJoinOverlay(){const t=this.widgetElement.querySelector(".chat-sdk-overlay");t&&t.remove()}addMessage(t){if(t.isOwnMessage)for(let e=this.state.messages.length-1;e>=0;e--){const s=this.state.messages[e];if(s.isOwnMessage&&s.content===t.content){if(Math.abs(t.timestamp.getTime()-s.timestamp.getTime())<=1e4)return;break}}this.state.messages.find(e=>e.id===t.id)?console.warn("Duplicate message detected and ignored:",t.id):(this.state.messages.push(t),this.renderMessage(t),t.isOwnMessage||this.incrementUnreadCount(),this.scrollToBottom(!0))}addMessagesBulk(t){if(!t||0===t.length)return;if(0===this.messagesContainer.querySelectorAll(".chat-sdk-message").length){this.state.messages=[...t].sort((t,e)=>t.timestamp.getTime()-e.timestamp.getTime());const e=this.state.messages.length,s=this.initialRenderCount;this.visibleStartIndex=Math.max(0,e-s);const n=this.state.messages.slice(this.visibleStartIndex),i=document.createDocumentFragment();let o;for(const t of n){const e=this.buildMessageElement(t,o);i.appendChild(e),o=t}this.messagesContainer.appendChild(i),setTimeout(()=>{this.scrollToBottom(!0)},0)}else{const e=new Set(this.state.messages.map(t=>t.id)),s=t.filter(t=>!e.has(t.id));if(s.length>0){this.state.messages.push(...s),this.state.messages.sort((t,e)=>t.timestamp.getTime()-e.timestamp.getTime()),this.messagesContainer.innerHTML="";const t=this.state.messages.length,e=this.initialRenderCount;this.visibleStartIndex=Math.max(0,t-e);const n=this.state.messages.slice(this.visibleStartIndex),i=document.createDocumentFragment();let o;for(const t of n){const e=this.buildMessageElement(t,o);i.appendChild(e),o=t}this.messagesContainer.appendChild(i),this.scrollToBottom()}}}reRenderAllMessages(){this.messagesContainer.innerHTML="";const t=this.state.messages.length,e=Math.max(0,t-this.initialRenderCount);this.state.messages.slice(e).forEach(t=>{this.renderMessage(t)}),this.scrollToBottom()}renderMessage(t){const e=this.state.messages.length-1,s=e>0?this.state.messages[e-1]:void 0,n=this.buildMessageElement(t,s);this.messagesContainer.appendChild(n)}createAvatar(t){var e,s,n,i;const o=_t("div","chat-sdk-message-avatar");if(null===(e=t.virtualUser)||void 0===e?void 0:e.avatar)o.style.backgroundImage=`url(${t.virtualUser.avatar})`,o.style.backgroundSize="cover",o.style.backgroundPosition="center";else if(null===(s=t.user)||void 0===s?void 0:s.avatar)o.style.backgroundImage=`url(${t.user.avatar})`,o.style.backgroundSize="cover",o.style.backgroundPosition="center";else{const e=(null===(n=t.virtualUser)||void 0===n?void 0:n.username)||(null===(i=t.user)||void 0===i?void 0:i.username)||"U";o.textContent=e.charAt(0).toUpperCase()}return o}createMessageContent(t,e=!0,s=!1,n=!1){var i,o,a;const r=_t("div","chat-sdk-message-content"),h=(null===(i=t.virtualUser)||void 0===i?void 0:i.displayName)||(null===(o=t.virtualUser)||void 0===o?void 0:o.username)||(null===(a=t.user)||void 0===a?void 0:a.username)||"Unknown";let c="";if("image"===t.messageType){c=`\n <div class="chat-sdk-message-image${t.failed?" failed":""}">\n <img src="${St(t.content)}" alt="Image"\n style="max-width: 100%; height: auto; cursor: pointer;"\n data-image-url="${St(t.content)}"\n class="chat-sdk-image-preview" />\n </div>\n `}else c="emoji"===t.messageType?`<div class="chat-sdk-message-emoji" style="font-size: 2em; line-height: 1;">${St(t.content)}</div>`:`<p class="chat-sdk-message-text">${St(t.content)}</p>`;const l=`${function(t,e){const s=new Date,n=Math.floor((s.getTime()-t.getTime())/1e3),i=(e||("undefined"!=typeof navigator?navigator.language:"en")).toLowerCase().startsWith("zh");if(n<60)return i?"刚刚":"just now";if(n<3600){const t=Math.floor(n/60);return i?`${t} 分钟前`:`${t}m ago`}if(n<86400){const t=Math.floor(n/3600);return i?`${t} 小时前`:`${t}h ago`}const o=new Date(s.getFullYear(),s.getMonth(),s.getDate());if(t>=new Date(o.getTime()-864e5)&&t<o){const e=t.toLocaleTimeString(i?"zh-CN":void 0,{hour:"2-digit",minute:"2-digit",hour12:!1});return i?`昨天 ${e}`:`yesterday ${e}`}return s.getTime()-t.getTime()<6048e5?t.toLocaleString(i?"zh-CN":void 0,{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit",hour12:!1}):t.toLocaleString(i?"zh-CN":void 0,{year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",hour12:!1})}(t.timestamp,this.config.language)}`,d=n?'<span class="chat-sdk-read-status">✓✓</span>':"",u=t.failed&&t.isOwnMessage?'<div class="chat-sdk-message-failed-indicator">\n <svg width="16" height="16" viewBox="0 0 16 16" fill="currentColor">\n <circle cx="8" cy="8" r="8" fill="#ff4444"/>\n <path d="M8 4v4M8 10h.01" stroke="white" stroke-width="1.5" stroke-linecap="round"/>\n </svg>\n </div>':"";r.innerHTML=s?`\n ${e&&!t.isOwnMessage?`<div class="chat-sdk-message-username">${St(h)}</div>`:""}\n <div class="chat-sdk-message-bubble">\n ${c}\n <div class="chat-sdk-message-time-inside">${l}${d?" "+d:""}</div>\n </div>\n ${u}\n `:`\n ${e&&!t.isOwnMessage?`<div class="chat-sdk-message-username">${St(h)}</div>`:""}\n <div class="chat-sdk-message-bubble">\n ${c}\n </div>\n <div class="chat-sdk-message-time">${l}${d?" "+d:""}</div>\n ${u}\n `;const g=r.querySelector(".chat-sdk-image-preview");return g&&g.addEventListener("click",t=>{t.preventDefault();const e=t.target.getAttribute("data-image-url");e&&this.showImagePreview(e)}),r}scrollToBottom(t=!1){const e=this.messagesContainer;if(t)return void It(e);e.scrollTop+e.clientHeight>=e.scrollHeight-40&&It(e)}setupImageViewer(){this.messagesContainer.addEventListener("click",t=>{const e=t.target;if(e.classList.contains("chat-sdk-image-preview")){const t=e.getAttribute("data-image-url");t&&this.openImageViewer(t)}})}openImageViewer(t){const e=_t("div","chat-sdk-image-modal");e.innerHTML=`\n <div class="chat-sdk-image-backdrop">\n <div class="chat-sdk-image-container">\n <button class="chat-sdk-image-close" aria-label="Close">\n <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">\n <line x1="18" y1="6" x2="6" y2="18"></line>\n <line x1="6" y1="6" x2="18" y2="18"></line>\n </svg>\n </button>\n <img class="chat-sdk-image-full" src="${St(t)}" alt="Full size image" />\n </div>\n </div>\n `,this.shadowRoot.appendChild(e);const s=e.querySelector(".chat-sdk-image-close"),n=e.querySelector(".chat-sdk-image-backdrop"),i=()=>{e.remove()};null==s||s.addEventListener("click",i),null==n||n.addEventListener("click",t=>{t.target===n&&i()});const o=t=>{"Escape"===t.key&&(i(),document.removeEventListener("keydown",o))};document.addEventListener("keydown",o),requestAnimationFrame(()=>{e.classList.add("chat-sdk-image-modal-open")})}showImagePreview(t){const e=_t("div","chat-sdk-image-modal");e.innerHTML=`\n <div class="chat-sdk-image-modal-overlay">\n <div class="chat-sdk-image-modal-content">\n <button class="chat-sdk-image-modal-close">&times;</button>\n <img src="${St(t)}" alt="Image Preview" class="chat-sdk-image-modal-img" />\n </div>\n </div>\n `,this.widgetElement.appendChild(e);const s=e.querySelector(".chat-sdk-image-modal-close"),n=e.querySelector(".chat-sdk-image-modal-overlay"),i=()=>{e.remove()};null==s||s.addEventListener("click",i),null==n||n.addEventListener("click",t=>{t.target===n&&i()});const o=t=>{"Escape"===t.key&&(i(),document.removeEventListener("keydown",o))};document.addEventListener("keydown",o)}setJoined(t){this.state.isJoined=t,this.handleInputChange()}setUITemplate(t){this.currentTheme=t,this.config.uiTemplate=t,this.widgetElement.classList.remove("whatsapp-theme","telegram-theme","dark"),this.widgetElement.classList.add(`${t}-theme`),"telegram"===t&&this.isDarkMode&&this.widgetElement.classList.add("dark"),this.updateThemeStyles(),this.reRenderAllMessages()}setTheme(t){this.isDarkMode="dark"===t,this.config.theme=t,"telegram"===this.currentTheme&&(this.isDarkMode?this.widgetElement.classList.add("dark"):this.widgetElement.classList.remove("dark"),this.updateThemeStyles())}setCustomColors(t){this.customColors={...this.customColors,...t},this.config.primaryColor=t.primary,this.config.backgroundColor=t.background,this.updateThemeStyles()}updateThemeStyles(){const t=this.currentTheme,e=this.isDarkMode&&"telegram"===t,s=this.shadowRoot||document.documentElement;"whatsapp"===t?(this.setCSSProperty(s,"--chat-primary-color",this.customColors.primary||"#25D366"),this.setCSSProperty(s,"--chat-background-color",this.customColors.background||"#ECE5DD"),this.setCSSProperty(s,"--chat-message-own-bg","#DCF8C6"),this.setCSSProperty(s,"--chat-message-other-bg","#FFFFFF"),this.setCSSProperty(s,"--chat-header-bg","linear-gradient(135deg, #075e54 0%, #128c7e 100%)")):"telegram"===t&&(e?(this.setCSSProperty(s,"--chat-primary-color",this.customColors.primary||"#4FC3F7"),this.setCSSProperty(s,"--chat-background-color",this.customColors.background||"#212121"),this.setCSSProperty(s,"--chat-message-own-bg","linear-gradient(135deg, #4fc3f7 0%, #29b6f6 100%)"),this.setCSSProperty(s,"--chat-message-other-bg","#2F2F2F"),this.setCSSProperty(s,"--chat-header-bg","linear-gradient(135deg, #1976d2 0%, #1565c0 100%)"),this.setCSSProperty(s,"--chat-text-color","#FFFFFF")):(this.setCSSProperty(s,"--chat-primary-color",this.customColors.primary||"#2481CC"),this.setCSSProperty(s,"--chat-background-color",this.customColors.background||"#FFFFFF"),this.setCSSProperty(s,"--chat-message-own-bg","linear-gradient(135deg, #4fc3f7 0%, #29b6f6 100%)"),this.setCSSProperty(s,"--chat-message-other-bg","#F1F1F1"),this.setCSSProperty(s,"--chat-header-bg","linear-gradient(135deg, #2481cc 0%, #1c7cd6 100%)"),this.setCSSProperty(s,"--chat-text-color","#000000")))}setCSSProperty(t,e,s){if(t instanceof ShadowRoot){const n=t.querySelector("style");if(n){const t=n.textContent||"",i=new RegExp(`${e}\\s*:\\s*[^;]+;`,"g"),o=`${e}: ${s};`;if(i.test(t))n.textContent=t.replace(i,o);else{const e=/:host\s*\{([^}]*)\}/;e.test(t)?n.textContent=t.replace(e,(t,e)=>`:host { ${e} ${o} }`):n.textContent=`:host { ${o} }\n${t}`}}}else t.style.setProperty(e,s)}getState(){return{...this.state}}getDefaultStyles(){return"\n :host {\n --chat-primary-color: #25D366;\n --chat-background-color: #ECE5DD;\n --chat-message-own-bg: #DCF8C6;\n --chat-message-other-bg: #FFFFFF;\n --chat-header-bg: linear-gradient(135deg, #075e54 0%, #128c7e 100%);\n --chat-text-color: #333333;\n --chat-border-radius-message: 18px;\n --chat-border-radius-input: 25px;\n }\n\n .chat-sdk-container {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;\n font-size: 14px;\n line-height: 1.5;\n color: var(--chat-text-color);\n background: var(--chat-background-color);\n border-radius: 12px;\n box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);\n overflow: hidden;\n display: flex;\n flex-direction: column;\n position: relative;\n max-width: 100%;\n max-height: 100%;\n }\n\n .chat-sdk-container * {\n box-sizing: border-box;\n }\n\n /* WhatsApp Theme */\n .chat-sdk-container.whatsapp-theme .chat-sdk-header {\n background: linear-gradient(135deg, #075e54 0%, #128c7e 100%);\n color: white;\n padding: 12px 16px;\n display: flex;\n align-items: center;\n justify-content: flex-end;\n min-height: 60px;\n box-shadow: 0 1px 3px rgba(0,0,0,0.12);\n }\n .chat-sdk-container.whatsapp-theme .chat-sdk-header-left { display: none; }\n\n .chat-sdk-container.whatsapp-theme .chat-sdk-messages {\n background-color: #ece5dd;\n background-image: url(\"data:image/svg+xml,%3Csvg width='60' height='60' viewBox='0 0 60 60' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cg fill='%23e5ddd5' fill-opacity='0.08'%3E%3Cpath d='M36 34v-4h-2v4h-4v2h4v4h2v-4h4v-2h-4zm0-30V0h-2v4h-4v2h4v4h2V6h4V4h-4zM6 34v-4H4v4H0v2h4v4h2v-4h4v-2H6zM6 4V0H4v4H0v2h4v4h2V6h4V4H6z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E\");\n }\n\n .chat-sdk-container.whatsapp-theme {\n --chat-primary-color: #25D366;\n --chat-background-color: #ECE5DD;\n --chat-message-own-bg: #DCF8C6;\n --chat-message-other-bg: #FFFFFF;\n --chat-header-bg: linear-gradient(135deg, #075e54 0%, #128c7e 100%);\n --chat-text-color: #303030;\n --chat-border-radius-message: 18px;\n --chat-border-radius-input: 25px;\n }\n\n .chat-sdk-container.whatsapp-theme .chat-sdk-message.own .chat-sdk-message-bubble {\n background: var(--chat-message-own-bg);\n color: var(--chat-text-color);\n border-radius: var(--chat-border-radius-message) var(--chat-border-radius-message) 4px var(--chat-border-radius-message);\n }\n\n .chat-sdk-container.whatsapp-theme .chat-sdk-message:not(.own) .chat-sdk-message-bubble {\n background: var(--chat-message-other-bg);\n color: var(--chat-text-color);\n border-radius: var(--chat-border-radius-message) var(--chat-border-radius-message) var(--chat-border-radius-message) 4px;\n }\n\n /* WhatsApp input + details */\n .chat-sdk-container.whatsapp-theme .chat-sdk-message-avatar {\n width: 28px;\n height: 28px;\n }\n .chat-sdk-container.whatsapp-theme .chat-sdk-message-content {\n max-width: 70%;\n }\n .chat-sdk-container.whatsapp-theme .chat-sdk-message-bubble {\n box-shadow: 0 1px 1px rgba(0,0,0,0.06);\n }\n .chat-sdk-container.whatsapp-theme .chat-sdk-input-area {\n background: #f0f2f5;\n border-top: none;\n }\n .chat-sdk-container.whatsapp-theme .chat-sdk-input {\n background: #fff;\n border: none;\n border-radius: 22px;\n padding: 10px 14px;\n box-shadow: inset 0 1px 0 rgba(0,0,0,0.02);\n }\n .chat-sdk-container.whatsapp-theme .chat-sdk-send-btn {\n background: #25D366;\n box-shadow: 0 2px 4px rgba(0,0,0,0.12);\n }\n\n\n /* Telegram Theme */\n .chat-sdk-container.telegram-theme {\n --chat-primary-color: #2481CC;\n --chat-background-color: #FFFFFF;\n --chat-message-own-bg: linear-gradient(135deg, #4fc3f7 0%, #29b6f6 100%);\n --chat-message-other-bg: #F1F1F1;\n --chat-header-bg: linear-gradient(135deg, #2481cc 0%, #1c7cd6 100%);\n --chat-text-color: #000000;\n --chat-border-radius-message: 12px;\n --chat-border-radius-input: 12px;\n\n /* Telegram input + details */\n .chat-sdk-container.telegram-theme .chat-sdk-message-content {\n max-width: 75%;\n }\n .chat-sdk-container.telegram-theme .chat-sdk-message-bubble {\n box-shadow: 0 1px 1px rgba(0,0,0,0.06);\n }\n .chat-sdk-container.telegram-theme .chat-sdk-input-area {\n background: #ffffff;\n border-top: 1px solid #e6e6e6;\n }\n .chat-sdk-container.telegram-theme .chat-sdk-input {\n background: #fff;\n border: 1px solid #cfd6dd;\n border-radius: 12px;\n padding: 9px 14px;\n }\n .chat-sdk-container.telegram-theme .chat-sdk-send-btn {\n background: #2481CC;\n border-radius: 10px;\n width: 38px;\n height: 36px;\n box-shadow: none;\n }\n /* Telegram dark */\n .chat-sdk-container.telegram-theme.dark .chat-sdk-input-area {\n background: #1f1f1f;\n border-top: 1px solid #2a2a2a;\n }\n .chat-sdk-container.telegram-theme.dark .chat-sdk-input {\n background: #2b2b2b;\n color: #e0e0e0;\n border-color: #444;\n }\n .chat-sdk-container.telegram-theme.dark .chat-sdk-send-btn {\n background: #1976d2;\n }\n\n\n .chat-sdk-container.telegram-theme .chat-sdk-header {\n background: var(--chat-header-bg);\n color: white;\n padding: 12px 16px;\n display: flex;\n align-items: center;\n justify-content: space-between;\n min-height: 60px;\n box-shadow: 0 1px 3px rgba(0,0,0,0.12);\n }\n\n .chat-sdk-container.telegram-theme .chat-sdk-messages {\n background-color: var(--chat-background-color);\n }\n\n .chat-sdk-container.telegram-theme .chat-sdk-message.own .chat-sdk-message-bubble {\n background: var(--chat-message-own-bg);\n color: white;\n border-radius: var(--chat-border-radius-message) var(--chat-border-radius-message) 4px var(--chat-border-radius-message);\n }\n\n .chat-sdk-container.telegram-theme .chat-sdk-message:not(.own) .chat-sdk-message-bubble {\n background: var(--chat-message-other-bg);\n color: var(--chat-text-color);\n border-radius: var(--chat-border-radius-message) var(--chat-border-radius-message) var(--chat-border-radius-message) 4px;\n }\n\n /* Telegram Dark Theme */\n .chat-sdk-container.telegram-theme.dark {\n --chat-background-color: #212121;\n --chat-message-other-bg: #2F2F2F;\n --chat-header-bg: linear-gradient(135deg, #1976d2 0%, #1565c0 100%);\n --chat-text-color: #FFFFFF;\n }\n\n /* Default header (fallback) */\n .chat-sdk-header {\n background: var(--chat-header-bg);\n color: white;\n padding: 12px 16px;\n display: flex;\n align-items: center;\n justify-content: space-between;\n min-height: 60px;\n }\n\n .chat-sdk-header-left { display: flex; flex-direction: column; gap: 2px; }\n .chat-sdk-title { font-size: 15px; font-weight: 600; }\n .chat-sdk-subtitle { font-size: 12px; opacity: 0.9; }\n\n .chat-sdk-close-btn {\n background: none;\n border: none;\n color: white;\n cursor: pointer;\n padding: 8px;\n border-radius: 50%;\n opacity: 0.8;\n transition: all 0.2s;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n }\n\n .chat-sdk-close-btn:hover {\n opacity: 1;\n background: rgba(255, 255, 255, 0.1);\n }\n\n .chat-sdk-messages {\n flex: 1;\n overflow-y: auto;\n padding: 16px;\n background: var(--chat-background-color);\n min-height: 0; /* allow flex to use full height */\n }\n\n .chat-sdk-message {\n margin-bottom: 12px;\n display: flex;\n align-items: flex-end;\n gap: 8px;\n }\n\n .chat-sdk-message.own {\n flex-direction: row-reverse;\n }\n\n .chat-sdk-message-avatar {\n width: 32px;\n height: 32px;\n border-radius: 50%;\n background: #ddd;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 12px;\n font-weight: 600;\n color: #666;\n flex-shrink: 0;\n }\n\n .chat-sdk-message-content {\n max-width: 70%;\n position: relative;\n }\n\n .chat-sdk-message-bubble {\n background: var(--chat-message-other-bg);\n color: var(--chat-text-color);\n padding: 8px 12px;\n border-radius: var(--chat-border-radius-message);\n position: relative;\n word-wrap: break-word;\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);\n }\n\n .chat-sdk-message.own .chat-sdk-message-bubble {\n background: var(--chat-message-own-bg);\n color: white;\n }\n\n .chat-sdk-message-username {\n font-size: 11px;\n color: #666;\n margin-bottom: 2px;\n font-weight: 600;\n }\n\n .chat-sdk-message-text {\n margin: 0;\n line-height: 1.4;\n }\n\n .chat-sdk-message-time {\n font-size: 10px;\n color: #999;\n margin-top: 4px;\n text-align: right;\n }\n\n /* Message grouping */\n .chat-sdk-message.grouped {\n margin-top: 4px;\n }\n .chat-sdk-message.grouped .chat-sdk-message-username { display: none; }\n .chat-sdk-message.grouped .chat-sdk-message-avatar { visibility: hidden; }\n\n /* WhatsApp: time inside bubble */\n .chat-sdk-container.whatsapp-theme .chat-sdk-message-bubble {\n position: relative;\n padding-right: 44px;\n padding-bottom: 16px;\n }\n .chat-sdk-container.whatsapp-theme .chat-sdk-message-time-inside {\n position: absolute;\n right: 8px;\n bottom: 4px;\n font-size: 11px;\n color: rgba(0,0,0,0.55);\n }\n\n /* Telegram: read status */\n .chat-sdk-container.telegram-theme .chat-sdk-message-time {\n display: flex;\n align-items: center;\n justify-content: flex-end;\n gap: 6px;\n }\n .chat-sdk-container.telegram-theme .chat-sdk-message.own .chat-sdk-read-status {\n font-size: 12px;\n color: var(--chat-primary-color);\n line-height: 1;\n }\n\n /* Theme-specific image radii */\n .chat-sdk-container.whatsapp-theme .chat-sdk-message-image img { border-radius: 12px; }\n .chat-sdk-container.telegram-theme .chat-sdk-message-image img { border-radius: 6px; }\n\n\n .chat-sdk-input-area {\n padding: 12px 16px;\n background: white;\n border-top: 1px solid #e0e0e0;\n display: flex;\n align-items: center;\n gap: 8px;\n }\n\n\n .chat-sdk-icon-btn {\n background: transparent;\n border: none;\n width: 32px;\n height: 32px;\n border-radius: 6px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: #666;\n }\n .chat-sdk-icon-btn:hover { background: rgba(0,0,0,0.06); }\n\n .chat-sdk-emoji-picker {\n position: absolute;\n left: 12px;\n bottom: 64px;\n background: #fff;\n border: 1px solid #e0e0e0;\n border-radius: 8px;\n box-shadow: 0 6px 16px rgba(0,0,0,0.12);\n padding: 6px;\n z-index: 5;\n }\n .chat-sdk-emoji-grid {\n display: grid;\n grid-template-columns: repeat(5, 28px);\n gap: 6px;\n }\n\n /* Failed message styles - Telegram style */\n .chat-sdk-message-failed-indicator {\n display: inline-flex;\n align-items: center;\n margin-left: 6px;\n color: #ff4444;\n cursor: pointer;\n }\n .chat-sdk-message-failed-indicator svg {\n width: 16px;\n height: 16px;\n }\n .chat-sdk-message.own .chat-sdk-message-content {\n display: flex;\n align-items: flex-end;\n gap: 6px;\n }\n .chat-sdk-message.own .chat-sdk-message-bubble {\n flex: 1;\n }\n .chat-sdk-emoji-item {\n background: none;\n border: none;\n font-size: 20px;\n line-height: 1;\n cursor: pointer;\n width: 28px;\n height: 28px;\n border-radius: 4px;\n }\n .chat-sdk-emoji-item:hover { background: #f3f4f6; }\n\n\n .chat-sdk-input {\n flex: 1;\n border: 1px solid #ddd;\n border-radius: var(--chat-border-radius-input);\n padding: 8px 16px;\n font-size: 14px;\n outline: none;\n resize: none;\n min-height: 36px;\n max-height: 100px;\n }\n\n .chat-sdk-input:focus {\n border-color: var(--chat-primary-color);\n }\n\n .chat-sdk-send-btn {\n background: var(--chat-primary-color);\n color: white;\n border: none;\n border-radius: 50%;\n width: 36px;\n height: 36px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: background-color 0.2s;\n }\n\n .chat-sdk-send-btn:hover {\n background: #064e45;\n }\n\n .chat-sdk-send-btn:disabled {\n background: #ccc;\n cursor: not-allowed;\n }\n\n .chat-sdk-overlay {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 10;\n }\n\n .chat-sdk-join-card {\n background: white;\n border-radius: 12px;\n padding: 24px;\n max-width: 300px;\n margin: 16px;\n text-align: center;\n }\n\n .chat-sdk-join-title {\n font-size: 18px;\n font-weight: 600;\n margin: 0 0 8px 0;\n color: #333;\n }\n\n .chat-sdk-join-description {\n font-size: 14px;\n color: #666;\n margin: 0 0 20px 0;\n line-height: 1.4;\n }\n\n .chat-sdk-join-btn {\n background: #075e54;\n color: white;\n border: none;\n border-radius: 8px;\n padding: 12px 24px;\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n transition: background-color 0.2s;\n width: 100%;\n }\n\n .chat-sdk-join-btn:hover {\n background: #064e45;\n }\n\n .chat-sdk-loading {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 40px;\n color: #666;\n }\n\n .chat-sdk-spinner {\n width: 20px;\n height: 20px;\n border: 2px solid #e0e0e0;\n border-top: 2px solid #075e54;\n border-radius: 50%;\n animation: chat-sdk-spin 1s linear infinite;\n margin-right: 8px;\n }\n\n @keyframes chat-sdk-spin {\n 0% { transform: rotate(0deg); }\n 100% { transform: rotate(360deg); }\n }\n\n .chat-sdk-container.dark {\n background: #1f1f1f;\n color: #e0e0e0;\n }\n\n .chat-sdk-container.dark .chat-sdk-header {\n background: #2d2d2d;\n }\n\n .chat-sdk-container.dark .chat-sdk-messages {\n background: #0d1117;\n }\n\n .chat-sdk-container.dark .chat-sdk-message-bubble {\n background: #2d2d2d;\n color: #e0e0e0;\n }\n\n .chat-sdk-container.dark .chat-sdk-message.own .chat-sdk-message-bubble {\n background: #0969da;\n color: white;\n }\n\n /* Image Modal Viewer */\n .chat-sdk-image-modal {\n position: fixed;\n top: 0; left: 0; right: 0; bottom: 0;\n z-index: 9999;\n opacity: 0;\n visibility: hidden;\n transition: opacity 0.2s ease, visibility 0.2s ease;\n }\n\n .chat-sdk-image-modal-open {\n opacity: 1;\n visibility: visible;\n }\n\n .chat-sdk-image-backdrop {\n position: absolute;\n top: 0; left: 0; right: 0; bottom: 0;\n background: rgba(0, 0, 0, 0.9);\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 20px;\n }\n\n .chat-sdk-image-container {\n position: relative;\n max-width: 90vw;\n max-height: 90vh;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n\n .chat-sdk-image-close {\n position: absolute;\n top: -50px;\n right: 0;\n background: rgba(255, 255, 255, 0.1);\n border: none;\n border-radius: 50%;\n width: 40px;\n height: 40px;\n color: white;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: background-color 0.2s;\n z-index: 1;\n }\n\n .chat-sdk-image-close:hover {\n background: rgba(255, 255, 255, 0.2);\n }\n\n .chat-sdk-image-full {\n max-width: 100%;\n max-height: 100%;\n object-fit: contain;\n border-radius: 8px;\n box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);\n }\n\n /* Responsive Design */\n @media (max-width: 640px) {\n .chat-sdk-container {\n border-radius: 0;\n height: 100vh;\n max-height: 100vh;\n }\n\n .chat-sdk-message-content {\n max-width: 85%;\n }\n\n .chat-sdk-message-bubble {\n font-size: 14px;\n padding: 8px 12px;\n }\n\n .chat-sdk-input {\n font-size: 16px; /* Prevent zoom on iOS */\n padding: 10px 14px;\n }\n\n .chat-sdk-header {\n padding: 8px 12px;\n min-height: 50px;\n }\n\n .chat-sdk-message-avatar {\n width: 28px;\n height: 28px;\n font-size: 11px;\n }\n }\n\n @media (min-width: 1024px) {\n .chat-sdk-message-content {\n max-width: 60%;\n }\n\n .chat-sdk-send-btn:hover:not(:disabled) {\n transform: scale(1.05);\n transition: all 0.2s ease;\n }\n }\n\n "}startSimulation(){this.simulator.start()}stopSimulation(){this.simulator.stop()}pauseSimulation(){this.simulator.pause()}resumeSimulation(){this.simulator.resume()}async sendMessage(t,e="text"){await this.simulator.sendMessage(t,e)}get isSimulationRunning(){return this.state.isSimulationRunning}get isSimulationPaused(){return this.state.isSimulationPaused}get simulationEnded(){return this.state.simulationEnded}get messageCount(){return this.state.displayedMessageCount}get messages(){return[...this.state.messages]}async reinitializeLanguage(t){this.config.language=t,this.setLoading(!0),this.messagesContainer.innerHTML="",this.state.messages=[],this.state.displayedMessageCount=0,this.state.unreadCount=0,this.updateUnreadBadge();try{this.simulator.clearCachedProgress()}catch(t){}try{this.simulator.destroy()}catch(t){}this.simulator=new Mt(this.config,this.apiClient),this.setupSimulatorEvents(),await this.initializeSimulation()}destroy(){if(this.simulator.destroy(),this.shadowRoot)try{for(;this.shadowRoot.firstChild;)this.shadowRoot.removeChild(this.shadowRoot.firstChild)}catch(t){}this.state.isOpen=!1,this.removeAllListeners()}clearMessages(){this.state.messages=[],this.state.displayedMessageCount=0,this.state.unreadCount=0,this.messagesContainer.innerHTML="",this.updateUnreadBadge()}rerender(){this.reRenderAllMessages()}getMessageCount(){return this.state.displayedMessageCount}isOpen(){return this.state.isOpen}updateLanguageElements(t){var e,s,n;const i=t.startsWith("zh"),o=null===(e=this.widgetElement)||void 0===e?void 0:e.querySelector("#chat-input");o&&(o.placeholder=i?"输入消息...":"Type a message...");const a=null===(s=this.widgetElement)||void 0===s?void 0:s.querySelector(".send-button");a&&a.textContent&&(a.textContent=i?"发送":"Send");const r=i?"条消息":"messages",h=this.getMessageCount(),c=(null===(n=this.state.currentProject)||void 0===n?void 0:n.name)||"Chat";this.setTitle(c,`${h} ${r}`)}}const Ot={en:"English",zh:"Chinese (Simplified)",es:"Spanish",ar:"Arabic",pt:"Portuguese",ru:"Russian",ja:"Japanese",fr:"French",de:"German",hi:"Hindi",it:"Italian",ko:"Korean",tr:"Turkish",pl:"Polish",nl:"Dutch",th:"Thai",vi:"Vietnamese",id:"Indonesian",uk:"Ukrainian",fa:"Persian (Farsi)","zh-TW":"Chinese (Traditional)","pt-BR":"Portuguese (Brazil)"},Lt={"en-US":"en","en-GB":"en","en-CA":"en","en-AU":"en","en-IN":"en","zh-CN":"zh","zh-Hans":"zh","zh-Hant":"zh-TW","zh-TW":"zh-TW","zh-HK":"zh-TW","zh-MO":"zh-TW","es-ES":"es","es-MX":"es","es-AR":"es","es-CO":"es","es-CL":"es","ar-SA":"ar","ar-EG":"ar","ar-AE":"ar","ar-MA":"ar","pt-BR":"pt-BR","pt-PT":"pt","ru-RU":"ru","ru-UA":"ru","ja-JP":"ja","fr-FR":"fr","fr-CA":"fr","fr-BE":"fr","de-DE":"de","de-AT":"de","de-CH":"de","hi-IN":"hi","it-IT":"it","ko-KR":"ko","tr-TR":"tr","pl-PL":"pl","nl-NL":"nl","nl-BE":"nl","th-TH":"th","vi-VN":"vi","id-ID":"id","uk-UA":"uk","fa-IR":"fa","fa-AF":"fa",zh_CN:"zh",zh_TW:"zh-TW",en_US:"en",en_GB:"en",fr_FR:"fr",de_DE:"de",es_ES:"es",ja_JP:"ja",ko_KR:"ko",pt_BR:"pt-BR",pt_PT:"pt",ru_RU:"ru",ar_SA:"ar",hi_IN:"hi",it_IT:"it",tr_TR:"tr",pl_PL:"pl",nl_NL:"nl",th_TH:"th",vi_VN:"vi",id_ID:"id",uk_UA:"uk",fa_IR:"fa",chinese:"zh",english:"en",spanish:"es",arabic:"ar",portuguese:"pt",russian:"ru",japanese:"ja",french:"fr",german:"de",hindi:"hi",italian:"it",korean:"ko",turkish:"tr",polish:"pl",dutch:"nl",thai:"th",vietnamese:"vi",indonesian:"id",ukrainian:"uk",persian:"fa",farsi:"fa",ZH:"zh",EN:"en",ES:"es",AR:"ar",PT:"pt",RU:"ru",JA:"ja",FR:"fr",DE:"de",HI:"hi",IT:"it",KO:"ko",TR:"tr",PL:"pl",NL:"nl",TH:"th",VI:"vi",ID:"id",UK:"uk",FA:"fa"};function jt(t){if(!t||"string"!=typeof t)return"en";const e=t.trim();if(!e)return"en";if(Ot[e])return e;if(Lt[e])return Lt[e];const s=e.toLowerCase();if(Ot[s])return s;if(Lt[s])return Lt[s];const n=s.split(/[-_]/)[0];if(n&&Ot[n])return n;if("zh"===n||e.toLowerCase().includes("chinese")){return["tw","hk","mo","hant","traditional"].some(t=>s.includes(t))?"zh-TW":"zh"}return console.warn(`[ChatSDK] Unsupported language code: "${t}", falling back to English`),"en"}function At(t){const e=jt(t);return"zh"===e||"zh-TW"===e}class Dt extends e{constructor(t){if(super(),this.isInitialized=!1,console.log("[ChatSDK] Initializing with config:",{projectId:t.projectId,apiBaseUrl:t.apiBaseUrl,container:"string"==typeof t.container?t.container:"[HTMLElement]"}),this.validateConfig(t),this.config={...this.getDefaultConfig(),...t},console.log("[ChatSDK] Final config:",{projectId:this.config.projectId,apiBaseUrl:this.config.apiBaseUrl,mode:this.config.mode}),this.config.language){const t=jt(this.config.language);t!==this.config.language&&(console.log(`[ChatSDK] Language normalized: "${this.config.language}" -> "${t}"`),this.config.language=t)}this.config.mode="floating",this.userId=this.config.userId||`sdk-user-${Math.random().toString(36).substr(2,9)}`,this.username=this.config.username||`User${Math.floor(1e3*Math.random())}`,this.apiClient=new s(this.config),this.socketClient=new Et(this.config),this.widget=new Rt(this.config),this.setupEventListeners(),this.initialize()}validateConfig(e){if(!e.container)throw new t("Container is required","INVALID_CONFIG");e.projectId||(console.warn("[ChatSDK] Project ID is missing, using default project"),e.projectId="default-project"),e.apiBaseUrl||(console.warn("[ChatSDK] API Base URL is missing, using current origin"),e.apiBaseUrl=window.location.origin)}getDefaultConfig(){return{language:"en",theme:"light",uiTemplate:"whatsapp",width:"400px",height:"600px",position:"relative",zIndex:2147483e3,mode:"floating",floatingButton:{position:"bottom-right",offset:{bottom:20,right:20},icon:"chat",zIndex:2147483e3},autoJoin:!1,showAvatars:!0,showUsernames:!0,allowInput:!0,initialRenderCount:10,lazyLoadBatchSize:20,groupMessages:!0,groupTimeThresholdSec:120}}async initialize(){var t,e,s;try{await this.loadProject();const n=At(this.config.language||"en")?"条消息":"messages";this.widget.setTitle((null===(t=this.currentProject)||void 0===t?void 0:t.name)||"Chat",`0 ${n}`),this.widget.setLoading(!1),this.joinChat(),this.isInitialized=!0,this.emit("ready"),null===(s=(e=this.config).onReady)||void 0===s||s.call(e)}catch(t){this.handleError(t)}}async loadProject(){try{const t=await this.apiClient.getProject(this.config.projectId);this.currentProject=t.project,this.config.templateId?await this.loadTemplate(this.config.templateId):this.currentProject.templates&&this.currentProject.templates.length>0&&await this.loadTemplate(this.currentProject.templates[0].id)}catch(e){throw new t("Failed to load project data","PROJECT_LOAD_ERROR",e)}}async loadTemplate(e){try{const t=await this.apiClient.getTemplate(e,this.config.language);this.currentTemplate=t.template}catch(e){throw new t("Failed to load template","TEMPLATE_LOAD_ERROR",e)}}setupEventListeners(){this.widget.on("ready",()=>{this.emit("widget-ready")}),this.widget.on("open",()=>{var t,e;this.emit("open"),null===(e=(t=this.config).onOpen)||void 0===e||e.call(t)}),this.widget.on("close",()=>{var t,e;this.emit("close"),null===(e=(t=this.config).onClose)||void 0===e||e.call(t)}),this.widget.on("join-requested",()=>{this.joinChat()}),this.widget.on("message",t=>{this.handleUserMessage(t)}),this.widget.on("typing",()=>{this.socketClient.isConnected()&&this.socketClient.startTyping(this.config.projectId,this.userId)}),this.socketClient.on("connected",()=>{this.emit("connected")}),this.socketClient.on("disconnected",()=>{this.emit("disconnected")}),this.socketClient.on("user-joined",t=>{this.emit("user-joined",t)}),this.socketClient.on("user-left",t=>{this.emit("user-left",t)}),this.socketClient.on("new-message",t=>{var e,s;this.widget.addMessage(t),this.emit("message",t),null===(s=(e=this.config).onMessage)||void 0===s||s.call(e,t)}),this.socketClient.on("user-typing",t=>{}),this.socketClient.on("user-stopped-typing",t=>{}),this.socketClient.on("error",t=>{this.handleError(t)})}async handleUserMessage(t){var e,s;try{this.socketClient.isConnected()&&this.socketClient.sendMessage(this.config.projectId,this.userId,t.content,t.messageType),await this.apiClient.sendMessage(this.config.projectId,this.userId,t.content,t.messageType),this.emit("user-message",t),null===(s=(e=this.config).onUserMessage)||void 0===s||s.call(e,t)}catch(t){this.handleError(t)}}handleError(e){var s,n;const i=e instanceof t?e:new t("Unknown error","UNKNOWN_ERROR",e);this.emit("error",i),null===(n=(s=this.config).onError)||void 0===n||n.call(s,i)}open(){this.widget.open()}close(){this.widget.close()}destroy(){this.socketClient.disconnect(),this.widget.destroy(),this.removeAllListeners()}async setLanguage(t){var e,s;const n=jt(t),i=this.config.language;if(n!==t&&console.log(`[ChatSDK] Language normalized: "${t}" -> "${n}"`),n!==i){console.log(`[ChatSDK] Changing language from "${i}" to "${n}"`),this.config.language=n;try{const t=this.widget.isOpen();await this.reinitializeWithNewLanguage(),t&&this.widget.open(),this.updateUILanguage(),this.emit("language-change",n),null===(s=(e=this.config).onLanguageChange)||void 0===s||s.call(e,n),console.log(`[ChatSDK] Language successfully changed to "${n}"`)}catch(t){throw console.error(`[ChatSDK] Failed to change language to "${n}":`,t),this.config.language=i,t}}else console.log(`[ChatSDK] Language already set to "${n}", skipping update`)}async reinitializeWithNewLanguage(){try{await this.loadProject(),this.currentTemplate&&await this.loadTemplate(this.currentTemplate.id),await this.widget.reinitializeLanguage(this.config.language||"en")}catch(t){throw console.error("[ChatSDK] Failed to reinitialize with new language:",t),t}}updateUILanguage(){var t;const e=At(this.config.language||"en")?"条消息":"messages",s=this.widget.getMessageCount();this.widget.setTitle((null===(t=this.currentProject)||void 0===t?void 0:t.name)||"Chat",`${s} ${e}`),this.widget.updateLanguageElements(this.config.language||"en")}setTheme(t){var e,s;this.config.theme=t,this.widget.setTheme("auto"===t?"light":t),this.emit("theme-change",t),null===(s=(e=this.config).onThemeChange)||void 0===s||s.call(e,t)}setUITemplate(t){var e,s;this.config.uiTemplate=t,this.widget.setUITemplate(t),this.emit("template-change",t),null===(s=(e=this.config).onTemplateChange)||void 0===s||s.call(e,t)}setCustomColors(t){var e,s;this.config.primaryColor=null!==(e=t.primary)&&void 0!==e?e:this.config.primaryColor,this.config.backgroundColor=null!==(s=t.background)&&void 0!==s?s:this.config.backgroundColor,this.widget.setCustomColors(t)}setTemplate(t){this.config.templateId=t,this.loadTemplate(t)}joinChat(){var t,e;this.widget.hideJoinOverlay(),this.emit("join",{userId:this.userId,username:this.username}),null===(e=(t=this.config).onJoin)||void 0===e||e.call(t,{userId:this.userId,username:this.username})}leaveChat(){this.widget.stopSimulation()}sendMessage(t,e="text"){return this.widget.sendMessage(t,e)}startSimulation(){this.widget.startSimulation()}stopSimulation(){this.widget.stopSimulation()}pauseSimulation(){this.widget.pauseSimulation()}resumeSimulation(){this.widget.resumeSimulation()}isOpen(){return this.widget.isSimulationRunning}isJoined(){return!0}getConfig(){return{...this.config}}getMessages(){return this.widget.messages}get isSimulationRunning(){return this.widget.isSimulationRunning}get isSimulationPaused(){return this.widget.isSimulationPaused}get simulationEnded(){return this.widget.simulationEnded}get messageCount(){return this.widget.messageCount}}function Pt(t){return new Dt(t)}var Bt={init:Pt,ChatSDK:Dt,ChatSDKError:t};"undefined"!=typeof window&&(window.ChatSDK={init:Pt,ChatSDK:Dt,ChatSDKError:t});export{t as ChatSDKError,Bt as default,Pt as init};
1
+ class t extends Error{constructor(t,e,s){super(t),this.code=e,this.details=s,this.name="ChatSDKError"}}class e{constructor(){this.events=new Map}on(t,e){this.events.has(t)||this.events.set(t,[]),this.events.get(t).push(e)}off(t,e){if(!this.events.has(t))return;if(!e)return void this.events.delete(t);const s=this.events.get(t),n=s.indexOf(e);n>-1&&s.splice(n,1),0===s.length&&this.events.delete(t)}emit(t,e){if(!this.events.has(t))return;this.events.get(t).forEach(s=>{try{s(e)}catch(e){console.error(`Error in event callback for "${t}":`,e)}})}getEventNames(){return Array.from(this.events.keys())}listenerCount(t){var e;return(null===(e=this.events.get(t))||void 0===e?void 0:e.length)||0}removeAllListeners(){this.events.clear()}}class s{constructor(t){this.baseUrl=t.apiBaseUrl||window.location.origin,this.token=t.token}async request(e,s={}){const n=`${this.baseUrl}${e}`,i={"Content-Type":"application/json",...s.headers};this.token&&(i.Authorization=`Bearer ${this.token}`);try{const e=await fetch(n,{...s,headers:i,credentials:"include"});if(!e.ok)throw new t(`API request failed: ${e.status} ${e.statusText}`,"API_ERROR",{status:e.status,statusText:e.statusText});const o=await e.json();if(!o.success&&o.error)throw new t(o.error,"API_ERROR",o);return o}catch(e){if(e instanceof t)throw e;throw new t(`Network error: ${e.message}`,"NETWORK_ERROR",e)}}async getProject(t){return this.request(`/api/projects/${t}`)}async getTemplate(t,e){const s=e?`?lang=${encodeURIComponent(e)}`:"";return this.request(`/api/templates/${t}${s}`)}async getProjectTemplates(t){return this.request(`/api/projects/${t}/templates`)}async sendMessage(t,e,s,n="text"){return this.request("/api/chat/message",{method:"POST",body:JSON.stringify({projectId:t,userId:e,content:s,messageType:n})})}async joinProject(t,e,s){return this.request("/api/chat/join",{method:"POST",body:JSON.stringify({projectId:t,userId:e,username:s})})}async leaveProject(t,e){return this.request("/api/chat/leave",{method:"POST",body:JSON.stringify({projectId:t,userId:e})})}async getSimulationData(t,e,s){const n=new URLSearchParams({userId:e});return s&&n.append("lang",s),this.request(`/api/chat/simulation/${t}?${n.toString()}`)}async getSimulationMessages(t,e,s,n){const i=new URLSearchParams({userId:e});return s&&i.append("since",s),n&&i.append("limit",n.toString()),this.request(`/api/chat/simulation/${t}/messages?${i.toString()}`)}async sendUserMessage(t,e,s,n,i="text"){return this.request("/api/chat/send",{method:"POST",body:JSON.stringify({projectId:t,userId:e,username:s,content:n,messageType:i})})}async triggerAIReply(t,e,s,n,i="text"){return this.request("/api/chat/ai-reply",{method:"POST",body:JSON.stringify({projectId:t,userId:e,username:s,content:n,messageType:i})})}setToken(t){this.token=t}setBaseUrl(t){this.baseUrl=t}}const n=Object.create(null);n.open="0",n.close="1",n.ping="2",n.pong="3",n.message="4",n.upgrade="5",n.noop="6";const i=Object.create(null);Object.keys(n).forEach(t=>{i[n[t]]=t});const o={type:"error",data:"parser error"},a="function"==typeof Blob||"undefined"!=typeof Blob&&"[object BlobConstructor]"===Object.prototype.toString.call(Blob),r="function"==typeof ArrayBuffer,h=t=>"function"==typeof ArrayBuffer.isView?ArrayBuffer.isView(t):t&&t.buffer instanceof ArrayBuffer,c=({type:t,data:e},s,i)=>a&&e instanceof Blob?s?i(e):l(e,i):r&&(e instanceof ArrayBuffer||h(e))?s?i(e):l(new Blob([e]),i):i(n[t]+(e||"")),l=(t,e)=>{const s=new FileReader;return s.onload=function(){const t=s.result.split(",")[1];e("b"+(t||""))},s.readAsDataURL(t)};function d(t){return t instanceof Uint8Array?t:t instanceof ArrayBuffer?new Uint8Array(t):new Uint8Array(t.buffer,t.byteOffset,t.byteLength)}let u;const g="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",p="undefined"==typeof Uint8Array?[]:new Uint8Array(256);for(let t=0;t<64;t++)p[g.charCodeAt(t)]=t;const m="function"==typeof ArrayBuffer,f=(t,e)=>{if("string"!=typeof t)return{type:"message",data:v(t,e)};const s=t.charAt(0);if("b"===s)return{type:"message",data:y(t.substring(1),e)};return i[s]?t.length>1?{type:i[s],data:t.substring(1)}:{type:i[s]}:o},y=(t,e)=>{if(m){const s=(t=>{let e,s,n,i,o,a=.75*t.length,r=t.length,h=0;"="===t[t.length-1]&&(a--,"="===t[t.length-2]&&a--);const c=new ArrayBuffer(a),l=new Uint8Array(c);for(e=0;e<r;e+=4)s=p[t.charCodeAt(e)],n=p[t.charCodeAt(e+1)],i=p[t.charCodeAt(e+2)],o=p[t.charCodeAt(e+3)],l[h++]=s<<2|n>>4,l[h++]=(15&n)<<4|i>>2,l[h++]=(3&i)<<6|63&o;return c})(t);return v(s,e)}return{base64:!0,data:t}},v=(t,e)=>"blob"===e?t instanceof Blob?t:new Blob([t]):t instanceof ArrayBuffer?t:t.buffer,b=String.fromCharCode(30);function w(){return new TransformStream({transform(t,e){!function(t,e){a&&t.data instanceof Blob?t.data.arrayBuffer().then(d).then(e):r&&(t.data instanceof ArrayBuffer||h(t.data))?e(d(t.data)):c(t,!1,t=>{u||(u=new TextEncoder),e(u.encode(t))})}(t,s=>{const n=s.length;let i;if(n<126)i=new Uint8Array(1),new DataView(i.buffer).setUint8(0,n);else if(n<65536){i=new Uint8Array(3);const t=new DataView(i.buffer);t.setUint8(0,126),t.setUint16(1,n)}else{i=new Uint8Array(9);const t=new DataView(i.buffer);t.setUint8(0,127),t.setBigUint64(1,BigInt(n))}t.data&&"string"!=typeof t.data&&(i[0]|=128),e.enqueue(i),e.enqueue(s)})}})}let k;function x(t){return t.reduce((t,e)=>t+e.length,0)}function C(t,e){if(t[0].length===e)return t.shift();const s=new Uint8Array(e);let n=0;for(let i=0;i<e;i++)s[i]=t[0][n++],n===t[0].length&&(t.shift(),n=0);return t.length&&n<t[0].length&&(t[0]=t[0].slice(n)),s}function T(t){if(t)return function(t){for(var e in T.prototype)t[e]=T.prototype[e];return t}(t)}T.prototype.on=T.prototype.addEventListener=function(t,e){return this._callbacks=this._callbacks||{},(this._callbacks["$"+t]=this._callbacks["$"+t]||[]).push(e),this},T.prototype.once=function(t,e){function s(){this.off(t,s),e.apply(this,arguments)}return s.fn=e,this.on(t,s),this},T.prototype.off=T.prototype.removeListener=T.prototype.removeAllListeners=T.prototype.removeEventListener=function(t,e){if(this._callbacks=this._callbacks||{},0==arguments.length)return this._callbacks={},this;var s,n=this._callbacks["$"+t];if(!n)return this;if(1==arguments.length)return delete this._callbacks["$"+t],this;for(var i=0;i<n.length;i++)if((s=n[i])===e||s.fn===e){n.splice(i,1);break}return 0===n.length&&delete this._callbacks["$"+t],this},T.prototype.emit=function(t){this._callbacks=this._callbacks||{};for(var e=new Array(arguments.length-1),s=this._callbacks["$"+t],n=1;n<arguments.length;n++)e[n-1]=arguments[n];if(s){n=0;for(var i=(s=s.slice(0)).length;n<i;++n)s[n].apply(this,e)}return this},T.prototype.emitReserved=T.prototype.emit,T.prototype.listeners=function(t){return this._callbacks=this._callbacks||{},this._callbacks["$"+t]||[]},T.prototype.hasListeners=function(t){return!!this.listeners(t).length};const E="function"==typeof Promise&&"function"==typeof Promise.resolve?t=>Promise.resolve().then(t):(t,e)=>e(t,0),S="undefined"!=typeof self?self:"undefined"!=typeof window?window:Function("return this")();function _(t,...e){return e.reduce((e,s)=>(t.hasOwnProperty(s)&&(e[s]=t[s]),e),{})}const I=S.setTimeout,M=S.clearTimeout;function R(t,e){e.useNativeTimers?(t.setTimeoutFn=I.bind(S),t.clearTimeoutFn=M.bind(S)):(t.setTimeoutFn=S.setTimeout.bind(S),t.clearTimeoutFn=S.clearTimeout.bind(S))}function L(t){return"string"==typeof t?function(t){let e=0,s=0;for(let n=0,i=t.length;n<i;n++)e=t.charCodeAt(n),e<128?s+=1:e<2048?s+=2:e<55296||e>=57344?s+=3:(n++,s+=4);return s}(t):Math.ceil(1.33*(t.byteLength||t.size))}function O(){return Date.now().toString(36).substring(3)+Math.random().toString(36).substring(2,5)}class j extends Error{constructor(t,e,s){super(t),this.description=e,this.context=s,this.type="TransportError"}}class A extends T{constructor(t){super(),this.writable=!1,R(this,t),this.opts=t,this.query=t.query,this.socket=t.socket,this.supportsBinary=!t.forceBase64}onError(t,e,s){return super.emitReserved("error",new j(t,e,s)),this}open(){return this.readyState="opening",this.doOpen(),this}close(){return"opening"!==this.readyState&&"open"!==this.readyState||(this.doClose(),this.onClose()),this}send(t){"open"===this.readyState&&this.write(t)}onOpen(){this.readyState="open",this.writable=!0,super.emitReserved("open")}onData(t){const e=f(t,this.socket.binaryType);this.onPacket(e)}onPacket(t){super.emitReserved("packet",t)}onClose(t){this.readyState="closed",super.emitReserved("close",t)}pause(t){}createUri(t,e={}){return t+"://"+this._hostname()+this._port()+this.opts.path+this._query(e)}_hostname(){const t=this.opts.hostname;return-1===t.indexOf(":")?t:"["+t+"]"}_port(){return this.opts.port&&(this.opts.secure&&Number(443!==this.opts.port)||!this.opts.secure&&80!==Number(this.opts.port))?":"+this.opts.port:""}_query(t){const e=function(t){let e="";for(let s in t)t.hasOwnProperty(s)&&(e.length&&(e+="&"),e+=encodeURIComponent(s)+"="+encodeURIComponent(t[s]));return e}(t);return e.length?"?"+e:""}}class D extends A{constructor(){super(...arguments),this._polling=!1}get name(){return"polling"}doOpen(){this._poll()}pause(t){this.readyState="pausing";const e=()=>{this.readyState="paused",t()};if(this._polling||!this.writable){let t=0;this._polling&&(t++,this.once("pollComplete",function(){--t||e()})),this.writable||(t++,this.once("drain",function(){--t||e()}))}else e()}_poll(){this._polling=!0,this.doPoll(),this.emitReserved("poll")}onData(t){((t,e)=>{const s=t.split(b),n=[];for(let t=0;t<s.length;t++){const i=f(s[t],e);if(n.push(i),"error"===i.type)break}return n})(t,this.socket.binaryType).forEach(t=>{if("opening"===this.readyState&&"open"===t.type&&this.onOpen(),"close"===t.type)return this.onClose({description:"transport closed by the server"}),!1;this.onPacket(t)}),"closed"!==this.readyState&&(this._polling=!1,this.emitReserved("pollComplete"),"open"===this.readyState&&this._poll())}doClose(){const t=()=>{this.write([{type:"close"}])};"open"===this.readyState?t():this.once("open",t)}write(t){this.writable=!1,((t,e)=>{const s=t.length,n=new Array(s);let i=0;t.forEach((t,o)=>{c(t,!1,t=>{n[o]=t,++i===s&&e(n.join(b))})})})(t,t=>{this.doWrite(t,()=>{this.writable=!0,this.emitReserved("drain")})})}uri(){const t=this.opts.secure?"https":"http",e=this.query||{};return!1!==this.opts.timestampRequests&&(e[this.opts.timestampParam]=O()),this.supportsBinary||e.sid||(e.b64=1),this.createUri(t,e)}}let P=!1;try{P="undefined"!=typeof XMLHttpRequest&&"withCredentials"in new XMLHttpRequest}catch(t){}const B=P;function U(){}class N extends D{constructor(t){if(super(t),"undefined"!=typeof location){const e="https:"===location.protocol;let s=location.port;s||(s=e?"443":"80"),this.xd="undefined"!=typeof location&&t.hostname!==location.hostname||s!==t.port}}doWrite(t,e){const s=this.request({method:"POST",data:t});s.on("success",e),s.on("error",(t,e)=>{this.onError("xhr post error",t,e)})}doPoll(){const t=this.request();t.on("data",this.onData.bind(this)),t.on("error",(t,e)=>{this.onError("xhr poll error",t,e)}),this.pollXhr=t}}class F extends T{constructor(t,e,s){super(),this.createRequest=t,R(this,s),this._opts=s,this._method=s.method||"GET",this._uri=e,this._data=void 0!==s.data?s.data:null,this._create()}_create(){var t;const e=_(this._opts,"agent","pfx","key","passphrase","cert","ca","ciphers","rejectUnauthorized","autoUnref");e.xdomain=!!this._opts.xd;const s=this._xhr=this.createRequest(e);try{s.open(this._method,this._uri,!0);try{if(this._opts.extraHeaders){s.setDisableHeaderCheck&&s.setDisableHeaderCheck(!0);for(let t in this._opts.extraHeaders)this._opts.extraHeaders.hasOwnProperty(t)&&s.setRequestHeader(t,this._opts.extraHeaders[t])}}catch(t){}if("POST"===this._method)try{s.setRequestHeader("Content-type","text/plain;charset=UTF-8")}catch(t){}try{s.setRequestHeader("Accept","*/*")}catch(t){}null===(t=this._opts.cookieJar)||void 0===t||t.addCookies(s),"withCredentials"in s&&(s.withCredentials=this._opts.withCredentials),this._opts.requestTimeout&&(s.timeout=this._opts.requestTimeout),s.onreadystatechange=()=>{var t;3===s.readyState&&(null===(t=this._opts.cookieJar)||void 0===t||t.parseCookies(s.getResponseHeader("set-cookie"))),4===s.readyState&&(200===s.status||1223===s.status?this._onLoad():this.setTimeoutFn(()=>{this._onError("number"==typeof s.status?s.status:0)},0))},s.send(this._data)}catch(t){return void this.setTimeoutFn(()=>{this._onError(t)},0)}"undefined"!=typeof document&&(this._index=F.requestsCount++,F.requests[this._index]=this)}_onError(t){this.emitReserved("error",t,this._xhr),this._cleanup(!0)}_cleanup(t){if(void 0!==this._xhr&&null!==this._xhr){if(this._xhr.onreadystatechange=U,t)try{this._xhr.abort()}catch(t){}"undefined"!=typeof document&&delete F.requests[this._index],this._xhr=null}}_onLoad(){const t=this._xhr.responseText;null!==t&&(this.emitReserved("data",t),this.emitReserved("success"),this._cleanup())}abort(){this._cleanup()}}if(F.requestsCount=0,F.requests={},"undefined"!=typeof document)if("function"==typeof attachEvent)attachEvent("onunload",z);else if("function"==typeof addEventListener){addEventListener("onpagehide"in S?"pagehide":"unload",z,!1)}function z(){for(let t in F.requests)F.requests.hasOwnProperty(t)&&F.requests[t].abort()}const $=function(){const t=q({xdomain:!1});return t&&null!==t.responseType}();function q(t){const e=t.xdomain;try{if("undefined"!=typeof XMLHttpRequest&&(!e||B))return new XMLHttpRequest}catch(t){}if(!e)try{return new(S[["Active"].concat("Object").join("X")])("Microsoft.XMLHTTP")}catch(t){}}const W="undefined"!=typeof navigator&&"string"==typeof navigator.product&&"reactnative"===navigator.product.toLowerCase();class H extends A{get name(){return"websocket"}doOpen(){const t=this.uri(),e=this.opts.protocols,s=W?{}:_(this.opts,"agent","perMessageDeflate","pfx","key","passphrase","cert","ca","ciphers","rejectUnauthorized","localAddress","protocolVersion","origin","maxPayload","family","checkServerIdentity");this.opts.extraHeaders&&(s.headers=this.opts.extraHeaders);try{this.ws=this.createSocket(t,e,s)}catch(t){return this.emitReserved("error",t)}this.ws.binaryType=this.socket.binaryType,this.addEventListeners()}addEventListeners(){this.ws.onopen=()=>{this.opts.autoUnref&&this.ws._socket.unref(),this.onOpen()},this.ws.onclose=t=>this.onClose({description:"websocket connection closed",context:t}),this.ws.onmessage=t=>this.onData(t.data),this.ws.onerror=t=>this.onError("websocket error",t)}write(t){this.writable=!1;for(let e=0;e<t.length;e++){const s=t[e],n=e===t.length-1;c(s,this.supportsBinary,t=>{try{this.doWrite(s,t)}catch(t){}n&&E(()=>{this.writable=!0,this.emitReserved("drain")},this.setTimeoutFn)})}}doClose(){void 0!==this.ws&&(this.ws.onerror=()=>{},this.ws.close(),this.ws=null)}uri(){const t=this.opts.secure?"wss":"ws",e=this.query||{};return this.opts.timestampRequests&&(e[this.opts.timestampParam]=O()),this.supportsBinary||(e.b64=1),this.createUri(t,e)}}const K=S.WebSocket||S.MozWebSocket;const V={websocket:class extends H{createSocket(t,e,s){return W?new K(t,e,s):e?new K(t,e):new K(t)}doWrite(t,e){this.ws.send(e)}},webtransport:class extends A{get name(){return"webtransport"}doOpen(){try{this._transport=new WebTransport(this.createUri("https"),this.opts.transportOptions[this.name])}catch(t){return this.emitReserved("error",t)}this._transport.closed.then(()=>{this.onClose()}).catch(t=>{this.onError("webtransport error",t)}),this._transport.ready.then(()=>{this._transport.createBidirectionalStream().then(t=>{const e=function(t,e){k||(k=new TextDecoder);const s=[];let n=0,i=-1,a=!1;return new TransformStream({transform(r,h){for(s.push(r);;){if(0===n){if(x(s)<1)break;const t=C(s,1);a=!(128&~t[0]),i=127&t[0],n=i<126?3:126===i?1:2}else if(1===n){if(x(s)<2)break;const t=C(s,2);i=new DataView(t.buffer,t.byteOffset,t.length).getUint16(0),n=3}else if(2===n){if(x(s)<8)break;const t=C(s,8),e=new DataView(t.buffer,t.byteOffset,t.length),a=e.getUint32(0);if(a>Math.pow(2,21)-1){h.enqueue(o);break}i=a*Math.pow(2,32)+e.getUint32(4),n=3}else{if(x(s)<i)break;const t=C(s,i);h.enqueue(f(a?t:k.decode(t),e)),n=0}if(0===i||i>t){h.enqueue(o);break}}}})}(Number.MAX_SAFE_INTEGER,this.socket.binaryType),s=t.readable.pipeThrough(e).getReader(),n=w();n.readable.pipeTo(t.writable),this._writer=n.writable.getWriter();const i=()=>{s.read().then(({done:t,value:e})=>{t||(this.onPacket(e),i())}).catch(t=>{})};i();const a={type:"open"};this.query.sid&&(a.data=`{"sid":"${this.query.sid}"}`),this._writer.write(a).then(()=>this.onOpen())})})}write(t){this.writable=!1;for(let e=0;e<t.length;e++){const s=t[e],n=e===t.length-1;this._writer.write(s).then(()=>{n&&E(()=>{this.writable=!0,this.emitReserved("drain")},this.setTimeoutFn)})}}doClose(){var t;null===(t=this._transport)||void 0===t||t.close()}},polling:class extends N{constructor(t){super(t);const e=t&&t.forceBase64;this.supportsBinary=$&&!e}request(t={}){return Object.assign(t,{xd:this.xd},this.opts),new F(q,this.uri(),t)}}},J=/^(?:(?![^:@\/?#]+:[^:@\/]*@)(http|https|ws|wss):\/\/)?((?:(([^:@\/?#]*)(?::([^:@\/?#]*))?)?@)?((?:[a-f0-9]{0,4}:){2,7}[a-f0-9]{0,4}|[^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/,Y=["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"];function G(t){if(t.length>8e3)throw"URI too long";const e=t,s=t.indexOf("["),n=t.indexOf("]");-1!=s&&-1!=n&&(t=t.substring(0,s)+t.substring(s,n).replace(/:/g,";")+t.substring(n,t.length));let i=J.exec(t||""),o={},a=14;for(;a--;)o[Y[a]]=i[a]||"";return-1!=s&&-1!=n&&(o.source=e,o.host=o.host.substring(1,o.host.length-1).replace(/;/g,":"),o.authority=o.authority.replace("[","").replace("]","").replace(/;/g,":"),o.ipv6uri=!0),o.pathNames=function(t,e){const s=/\/{2,9}/g,n=e.replace(s,"/").split("/");"/"!=e.slice(0,1)&&0!==e.length||n.splice(0,1);"/"==e.slice(-1)&&n.splice(n.length-1,1);return n}(0,o.path),o.queryKey=function(t,e){const s={};return e.replace(/(?:^|&)([^&=]*)=?([^&]*)/g,function(t,e,n){e&&(s[e]=n)}),s}(0,o.query),o}const X="function"==typeof addEventListener&&"function"==typeof removeEventListener,Q=[];X&&addEventListener("offline",()=>{Q.forEach(t=>t())},!1);class Z extends T{constructor(t,e){if(super(),this.binaryType="arraybuffer",this.writeBuffer=[],this._prevBufferLen=0,this._pingInterval=-1,this._pingTimeout=-1,this._maxPayload=-1,this._pingTimeoutTime=1/0,t&&"object"==typeof t&&(e=t,t=null),t){const s=G(t);e.hostname=s.host,e.secure="https"===s.protocol||"wss"===s.protocol,e.port=s.port,s.query&&(e.query=s.query)}else e.host&&(e.hostname=G(e.host).host);R(this,e),this.secure=null!=e.secure?e.secure:"undefined"!=typeof location&&"https:"===location.protocol,e.hostname&&!e.port&&(e.port=this.secure?"443":"80"),this.hostname=e.hostname||("undefined"!=typeof location?location.hostname:"localhost"),this.port=e.port||("undefined"!=typeof location&&location.port?location.port:this.secure?"443":"80"),this.transports=[],this._transportsByName={},e.transports.forEach(t=>{const e=t.prototype.name;this.transports.push(e),this._transportsByName[e]=t}),this.opts=Object.assign({path:"/engine.io",agent:!1,withCredentials:!1,upgrade:!0,timestampParam:"t",rememberUpgrade:!1,addTrailingSlash:!0,rejectUnauthorized:!0,perMessageDeflate:{threshold:1024},transportOptions:{},closeOnBeforeunload:!1},e),this.opts.path=this.opts.path.replace(/\/$/,"")+(this.opts.addTrailingSlash?"/":""),"string"==typeof this.opts.query&&(this.opts.query=function(t){let e={},s=t.split("&");for(let t=0,n=s.length;t<n;t++){let n=s[t].split("=");e[decodeURIComponent(n[0])]=decodeURIComponent(n[1])}return e}(this.opts.query)),X&&(this.opts.closeOnBeforeunload&&(this._beforeunloadEventListener=()=>{this.transport&&(this.transport.removeAllListeners(),this.transport.close())},addEventListener("beforeunload",this._beforeunloadEventListener,!1)),"localhost"!==this.hostname&&(this._offlineEventListener=()=>{this._onClose("transport close",{description:"network connection lost"})},Q.push(this._offlineEventListener))),this.opts.withCredentials&&(this._cookieJar=void 0),this._open()}createTransport(t){const e=Object.assign({},this.opts.query);e.EIO=4,e.transport=t,this.id&&(e.sid=this.id);const s=Object.assign({},this.opts,{query:e,socket:this,hostname:this.hostname,secure:this.secure,port:this.port},this.opts.transportOptions[t]);return new this._transportsByName[t](s)}_open(){if(0===this.transports.length)return void this.setTimeoutFn(()=>{this.emitReserved("error","No transports available")},0);const t=this.opts.rememberUpgrade&&Z.priorWebsocketSuccess&&-1!==this.transports.indexOf("websocket")?"websocket":this.transports[0];this.readyState="opening";const e=this.createTransport(t);e.open(),this.setTransport(e)}setTransport(t){this.transport&&this.transport.removeAllListeners(),this.transport=t,t.on("drain",this._onDrain.bind(this)).on("packet",this._onPacket.bind(this)).on("error",this._onError.bind(this)).on("close",t=>this._onClose("transport close",t))}onOpen(){this.readyState="open",Z.priorWebsocketSuccess="websocket"===this.transport.name,this.emitReserved("open"),this.flush()}_onPacket(t){if("opening"===this.readyState||"open"===this.readyState||"closing"===this.readyState)switch(this.emitReserved("packet",t),this.emitReserved("heartbeat"),t.type){case"open":this.onHandshake(JSON.parse(t.data));break;case"ping":this._sendPacket("pong"),this.emitReserved("ping"),this.emitReserved("pong"),this._resetPingTimeout();break;case"error":const e=new Error("server error");e.code=t.data,this._onError(e);break;case"message":this.emitReserved("data",t.data),this.emitReserved("message",t.data)}}onHandshake(t){this.emitReserved("handshake",t),this.id=t.sid,this.transport.query.sid=t.sid,this._pingInterval=t.pingInterval,this._pingTimeout=t.pingTimeout,this._maxPayload=t.maxPayload,this.onOpen(),"closed"!==this.readyState&&this._resetPingTimeout()}_resetPingTimeout(){this.clearTimeoutFn(this._pingTimeoutTimer);const t=this._pingInterval+this._pingTimeout;this._pingTimeoutTime=Date.now()+t,this._pingTimeoutTimer=this.setTimeoutFn(()=>{this._onClose("ping timeout")},t),this.opts.autoUnref&&this._pingTimeoutTimer.unref()}_onDrain(){this.writeBuffer.splice(0,this._prevBufferLen),this._prevBufferLen=0,0===this.writeBuffer.length?this.emitReserved("drain"):this.flush()}flush(){if("closed"!==this.readyState&&this.transport.writable&&!this.upgrading&&this.writeBuffer.length){const t=this._getWritablePackets();this.transport.send(t),this._prevBufferLen=t.length,this.emitReserved("flush")}}_getWritablePackets(){if(!(this._maxPayload&&"polling"===this.transport.name&&this.writeBuffer.length>1))return this.writeBuffer;let t=1;for(let e=0;e<this.writeBuffer.length;e++){const s=this.writeBuffer[e].data;if(s&&(t+=L(s)),e>0&&t>this._maxPayload)return this.writeBuffer.slice(0,e);t+=2}return this.writeBuffer}_hasPingExpired(){if(!this._pingTimeoutTime)return!0;const t=Date.now()>this._pingTimeoutTime;return t&&(this._pingTimeoutTime=0,E(()=>{this._onClose("ping timeout")},this.setTimeoutFn)),t}write(t,e,s){return this._sendPacket("message",t,e,s),this}send(t,e,s){return this._sendPacket("message",t,e,s),this}_sendPacket(t,e,s,n){if("function"==typeof e&&(n=e,e=void 0),"function"==typeof s&&(n=s,s=null),"closing"===this.readyState||"closed"===this.readyState)return;(s=s||{}).compress=!1!==s.compress;const i={type:t,data:e,options:s};this.emitReserved("packetCreate",i),this.writeBuffer.push(i),n&&this.once("flush",n),this.flush()}close(){const t=()=>{this._onClose("forced close"),this.transport.close()},e=()=>{this.off("upgrade",e),this.off("upgradeError",e),t()},s=()=>{this.once("upgrade",e),this.once("upgradeError",e)};return"opening"!==this.readyState&&"open"!==this.readyState||(this.readyState="closing",this.writeBuffer.length?this.once("drain",()=>{this.upgrading?s():t()}):this.upgrading?s():t()),this}_onError(t){if(Z.priorWebsocketSuccess=!1,this.opts.tryAllTransports&&this.transports.length>1&&"opening"===this.readyState)return this.transports.shift(),this._open();this.emitReserved("error",t),this._onClose("transport error",t)}_onClose(t,e){if("opening"===this.readyState||"open"===this.readyState||"closing"===this.readyState){if(this.clearTimeoutFn(this._pingTimeoutTimer),this.transport.removeAllListeners("close"),this.transport.close(),this.transport.removeAllListeners(),X&&(this._beforeunloadEventListener&&removeEventListener("beforeunload",this._beforeunloadEventListener,!1),this._offlineEventListener)){const t=Q.indexOf(this._offlineEventListener);-1!==t&&Q.splice(t,1)}this.readyState="closed",this.id=null,this.emitReserved("close",t,e),this.writeBuffer=[],this._prevBufferLen=0}}}Z.protocol=4;class tt extends Z{constructor(){super(...arguments),this._upgrades=[]}onOpen(){if(super.onOpen(),"open"===this.readyState&&this.opts.upgrade)for(let t=0;t<this._upgrades.length;t++)this._probe(this._upgrades[t])}_probe(t){let e=this.createTransport(t),s=!1;Z.priorWebsocketSuccess=!1;const n=()=>{s||(e.send([{type:"ping",data:"probe"}]),e.once("packet",t=>{if(!s)if("pong"===t.type&&"probe"===t.data){if(this.upgrading=!0,this.emitReserved("upgrading",e),!e)return;Z.priorWebsocketSuccess="websocket"===e.name,this.transport.pause(()=>{s||"closed"!==this.readyState&&(c(),this.setTransport(e),e.send([{type:"upgrade"}]),this.emitReserved("upgrade",e),e=null,this.upgrading=!1,this.flush())})}else{const t=new Error("probe error");t.transport=e.name,this.emitReserved("upgradeError",t)}}))};function i(){s||(s=!0,c(),e.close(),e=null)}const o=t=>{const s=new Error("probe error: "+t);s.transport=e.name,i(),this.emitReserved("upgradeError",s)};function a(){o("transport closed")}function r(){o("socket closed")}function h(t){e&&t.name!==e.name&&i()}const c=()=>{e.removeListener("open",n),e.removeListener("error",o),e.removeListener("close",a),this.off("close",r),this.off("upgrading",h)};e.once("open",n),e.once("error",o),e.once("close",a),this.once("close",r),this.once("upgrading",h),-1!==this._upgrades.indexOf("webtransport")&&"webtransport"!==t?this.setTimeoutFn(()=>{s||e.open()},200):e.open()}onHandshake(t){this._upgrades=this._filterUpgrades(t.upgrades),super.onHandshake(t)}_filterUpgrades(t){const e=[];for(let s=0;s<t.length;s++)~this.transports.indexOf(t[s])&&e.push(t[s]);return e}}let et=class extends tt{constructor(t,e={}){const s="object"==typeof t?t:e;(!s.transports||s.transports&&"string"==typeof s.transports[0])&&(s.transports=(s.transports||["polling","websocket","webtransport"]).map(t=>V[t]).filter(t=>!!t)),super(t,s)}};const st="function"==typeof ArrayBuffer,nt=Object.prototype.toString,it="function"==typeof Blob||"undefined"!=typeof Blob&&"[object BlobConstructor]"===nt.call(Blob),ot="function"==typeof File||"undefined"!=typeof File&&"[object FileConstructor]"===nt.call(File);function at(t){return st&&(t instanceof ArrayBuffer||(t=>"function"==typeof ArrayBuffer.isView?ArrayBuffer.isView(t):t.buffer instanceof ArrayBuffer)(t))||it&&t instanceof Blob||ot&&t instanceof File}function rt(t,e){if(!t||"object"!=typeof t)return!1;if(Array.isArray(t)){for(let e=0,s=t.length;e<s;e++)if(rt(t[e]))return!0;return!1}if(at(t))return!0;if(t.toJSON&&"function"==typeof t.toJSON&&1===arguments.length)return rt(t.toJSON(),!0);for(const e in t)if(Object.prototype.hasOwnProperty.call(t,e)&&rt(t[e]))return!0;return!1}function ht(t){const e=[],s=t.data,n=t;return n.data=ct(s,e),n.attachments=e.length,{packet:n,buffers:e}}function ct(t,e){if(!t)return t;if(at(t)){const s={_placeholder:!0,num:e.length};return e.push(t),s}if(Array.isArray(t)){const s=new Array(t.length);for(let n=0;n<t.length;n++)s[n]=ct(t[n],e);return s}if("object"==typeof t&&!(t instanceof Date)){const s={};for(const n in t)Object.prototype.hasOwnProperty.call(t,n)&&(s[n]=ct(t[n],e));return s}return t}function lt(t,e){return t.data=dt(t.data,e),delete t.attachments,t}function dt(t,e){if(!t)return t;if(t&&!0===t._placeholder){if("number"==typeof t.num&&t.num>=0&&t.num<e.length)return e[t.num];throw new Error("illegal attachments")}if(Array.isArray(t))for(let s=0;s<t.length;s++)t[s]=dt(t[s],e);else if("object"==typeof t)for(const s in t)Object.prototype.hasOwnProperty.call(t,s)&&(t[s]=dt(t[s],e));return t}const ut=["connect","connect_error","disconnect","disconnecting","newListener","removeListener"];var gt;!function(t){t[t.CONNECT=0]="CONNECT",t[t.DISCONNECT=1]="DISCONNECT",t[t.EVENT=2]="EVENT",t[t.ACK=3]="ACK",t[t.CONNECT_ERROR=4]="CONNECT_ERROR",t[t.BINARY_EVENT=5]="BINARY_EVENT",t[t.BINARY_ACK=6]="BINARY_ACK"}(gt||(gt={}));function pt(t){return"[object Object]"===Object.prototype.toString.call(t)}class mt extends T{constructor(t){super(),this.reviver=t}add(t){let e;if("string"==typeof t){if(this.reconstructor)throw new Error("got plaintext data when reconstructing a packet");e=this.decodeString(t);const s=e.type===gt.BINARY_EVENT;s||e.type===gt.BINARY_ACK?(e.type=s?gt.EVENT:gt.ACK,this.reconstructor=new ft(e),0===e.attachments&&super.emitReserved("decoded",e)):super.emitReserved("decoded",e)}else{if(!at(t)&&!t.base64)throw new Error("Unknown type: "+t);if(!this.reconstructor)throw new Error("got binary data when not reconstructing a packet");e=this.reconstructor.takeBinaryData(t),e&&(this.reconstructor=null,super.emitReserved("decoded",e))}}decodeString(t){let e=0;const s={type:Number(t.charAt(0))};if(void 0===gt[s.type])throw new Error("unknown packet type "+s.type);if(s.type===gt.BINARY_EVENT||s.type===gt.BINARY_ACK){const n=e+1;for(;"-"!==t.charAt(++e)&&e!=t.length;);const i=t.substring(n,e);if(i!=Number(i)||"-"!==t.charAt(e))throw new Error("Illegal attachments");s.attachments=Number(i)}if("/"===t.charAt(e+1)){const n=e+1;for(;++e;){if(","===t.charAt(e))break;if(e===t.length)break}s.nsp=t.substring(n,e)}else s.nsp="/";const n=t.charAt(e+1);if(""!==n&&Number(n)==n){const n=e+1;for(;++e;){const s=t.charAt(e);if(null==s||Number(s)!=s){--e;break}if(e===t.length)break}s.id=Number(t.substring(n,e+1))}if(t.charAt(++e)){const n=this.tryParse(t.substr(e));if(!mt.isPayloadValid(s.type,n))throw new Error("invalid payload");s.data=n}return s}tryParse(t){try{return JSON.parse(t,this.reviver)}catch(t){return!1}}static isPayloadValid(t,e){switch(t){case gt.CONNECT:return pt(e);case gt.DISCONNECT:return void 0===e;case gt.CONNECT_ERROR:return"string"==typeof e||pt(e);case gt.EVENT:case gt.BINARY_EVENT:return Array.isArray(e)&&("number"==typeof e[0]||"string"==typeof e[0]&&-1===ut.indexOf(e[0]));case gt.ACK:case gt.BINARY_ACK:return Array.isArray(e)}}destroy(){this.reconstructor&&(this.reconstructor.finishedReconstruction(),this.reconstructor=null)}}class ft{constructor(t){this.packet=t,this.buffers=[],this.reconPack=t}takeBinaryData(t){if(this.buffers.push(t),this.buffers.length===this.reconPack.attachments){const t=lt(this.reconPack,this.buffers);return this.finishedReconstruction(),t}return null}finishedReconstruction(){this.reconPack=null,this.buffers=[]}}var yt=Object.freeze({__proto__:null,Decoder:mt,Encoder:class{constructor(t){this.replacer=t}encode(t){return t.type!==gt.EVENT&&t.type!==gt.ACK||!rt(t)?[this.encodeAsString(t)]:this.encodeAsBinary({type:t.type===gt.EVENT?gt.BINARY_EVENT:gt.BINARY_ACK,nsp:t.nsp,data:t.data,id:t.id})}encodeAsString(t){let e=""+t.type;return t.type!==gt.BINARY_EVENT&&t.type!==gt.BINARY_ACK||(e+=t.attachments+"-"),t.nsp&&"/"!==t.nsp&&(e+=t.nsp+","),null!=t.id&&(e+=t.id),null!=t.data&&(e+=JSON.stringify(t.data,this.replacer)),e}encodeAsBinary(t){const e=ht(t),s=this.encodeAsString(e.packet),n=e.buffers;return n.unshift(s),n}},get PacketType(){return gt},protocol:5});function vt(t,e,s){return t.on(e,s),function(){t.off(e,s)}}const bt=Object.freeze({connect:1,connect_error:1,disconnect:1,disconnecting:1,newListener:1,removeListener:1});class wt extends T{constructor(t,e,s){super(),this.connected=!1,this.recovered=!1,this.receiveBuffer=[],this.sendBuffer=[],this._queue=[],this._queueSeq=0,this.ids=0,this.acks={},this.flags={},this.io=t,this.nsp=e,s&&s.auth&&(this.auth=s.auth),this._opts=Object.assign({},s),this.io._autoConnect&&this.open()}get disconnected(){return!this.connected}subEvents(){if(this.subs)return;const t=this.io;this.subs=[vt(t,"open",this.onopen.bind(this)),vt(t,"packet",this.onpacket.bind(this)),vt(t,"error",this.onerror.bind(this)),vt(t,"close",this.onclose.bind(this))]}get active(){return!!this.subs}connect(){return this.connected||(this.subEvents(),this.io._reconnecting||this.io.open(),"open"===this.io._readyState&&this.onopen()),this}open(){return this.connect()}send(...t){return t.unshift("message"),this.emit.apply(this,t),this}emit(t,...e){var s,n,i;if(bt.hasOwnProperty(t))throw new Error('"'+t.toString()+'" is a reserved event name');if(e.unshift(t),this._opts.retries&&!this.flags.fromQueue&&!this.flags.volatile)return this._addToQueue(e),this;const o={type:gt.EVENT,data:e,options:{}};if(o.options.compress=!1!==this.flags.compress,"function"==typeof e[e.length-1]){const t=this.ids++,s=e.pop();this._registerAckCallback(t,s),o.id=t}const a=null===(n=null===(s=this.io.engine)||void 0===s?void 0:s.transport)||void 0===n?void 0:n.writable,r=this.connected&&!(null===(i=this.io.engine)||void 0===i?void 0:i._hasPingExpired());return this.flags.volatile&&!a||(r?(this.notifyOutgoingListeners(o),this.packet(o)):this.sendBuffer.push(o)),this.flags={},this}_registerAckCallback(t,e){var s;const n=null!==(s=this.flags.timeout)&&void 0!==s?s:this._opts.ackTimeout;if(void 0===n)return void(this.acks[t]=e);const i=this.io.setTimeoutFn(()=>{delete this.acks[t];for(let e=0;e<this.sendBuffer.length;e++)this.sendBuffer[e].id===t&&this.sendBuffer.splice(e,1);e.call(this,new Error("operation has timed out"))},n),o=(...t)=>{this.io.clearTimeoutFn(i),e.apply(this,t)};o.withError=!0,this.acks[t]=o}emitWithAck(t,...e){return new Promise((s,n)=>{const i=(t,e)=>t?n(t):s(e);i.withError=!0,e.push(i),this.emit(t,...e)})}_addToQueue(t){let e;"function"==typeof t[t.length-1]&&(e=t.pop());const s={id:this._queueSeq++,tryCount:0,pending:!1,args:t,flags:Object.assign({fromQueue:!0},this.flags)};t.push((t,...n)=>{if(s!==this._queue[0])return;return null!==t?s.tryCount>this._opts.retries&&(this._queue.shift(),e&&e(t)):(this._queue.shift(),e&&e(null,...n)),s.pending=!1,this._drainQueue()}),this._queue.push(s),this._drainQueue()}_drainQueue(t=!1){if(!this.connected||0===this._queue.length)return;const e=this._queue[0];e.pending&&!t||(e.pending=!0,e.tryCount++,this.flags=e.flags,this.emit.apply(this,e.args))}packet(t){t.nsp=this.nsp,this.io._packet(t)}onopen(){"function"==typeof this.auth?this.auth(t=>{this._sendConnectPacket(t)}):this._sendConnectPacket(this.auth)}_sendConnectPacket(t){this.packet({type:gt.CONNECT,data:this._pid?Object.assign({pid:this._pid,offset:this._lastOffset},t):t})}onerror(t){this.connected||this.emitReserved("connect_error",t)}onclose(t,e){this.connected=!1,delete this.id,this.emitReserved("disconnect",t,e),this._clearAcks()}_clearAcks(){Object.keys(this.acks).forEach(t=>{if(!this.sendBuffer.some(e=>String(e.id)===t)){const e=this.acks[t];delete this.acks[t],e.withError&&e.call(this,new Error("socket has been disconnected"))}})}onpacket(t){if(t.nsp===this.nsp)switch(t.type){case gt.CONNECT:t.data&&t.data.sid?this.onconnect(t.data.sid,t.data.pid):this.emitReserved("connect_error",new Error("It seems you are trying to reach a Socket.IO server in v2.x with a v3.x client, but they are not compatible (more information here: https://socket.io/docs/v3/migrating-from-2-x-to-3-0/)"));break;case gt.EVENT:case gt.BINARY_EVENT:this.onevent(t);break;case gt.ACK:case gt.BINARY_ACK:this.onack(t);break;case gt.DISCONNECT:this.ondisconnect();break;case gt.CONNECT_ERROR:this.destroy();const e=new Error(t.data.message);e.data=t.data.data,this.emitReserved("connect_error",e)}}onevent(t){const e=t.data||[];null!=t.id&&e.push(this.ack(t.id)),this.connected?this.emitEvent(e):this.receiveBuffer.push(Object.freeze(e))}emitEvent(t){if(this._anyListeners&&this._anyListeners.length){const e=this._anyListeners.slice();for(const s of e)s.apply(this,t)}super.emit.apply(this,t),this._pid&&t.length&&"string"==typeof t[t.length-1]&&(this._lastOffset=t[t.length-1])}ack(t){const e=this;let s=!1;return function(...n){s||(s=!0,e.packet({type:gt.ACK,id:t,data:n}))}}onack(t){const e=this.acks[t.id];"function"==typeof e&&(delete this.acks[t.id],e.withError&&t.data.unshift(null),e.apply(this,t.data))}onconnect(t,e){this.id=t,this.recovered=e&&this._pid===e,this._pid=e,this.connected=!0,this.emitBuffered(),this.emitReserved("connect"),this._drainQueue(!0)}emitBuffered(){this.receiveBuffer.forEach(t=>this.emitEvent(t)),this.receiveBuffer=[],this.sendBuffer.forEach(t=>{this.notifyOutgoingListeners(t),this.packet(t)}),this.sendBuffer=[]}ondisconnect(){this.destroy(),this.onclose("io server disconnect")}destroy(){this.subs&&(this.subs.forEach(t=>t()),this.subs=void 0),this.io._destroy(this)}disconnect(){return this.connected&&this.packet({type:gt.DISCONNECT}),this.destroy(),this.connected&&this.onclose("io client disconnect"),this}close(){return this.disconnect()}compress(t){return this.flags.compress=t,this}get volatile(){return this.flags.volatile=!0,this}timeout(t){return this.flags.timeout=t,this}onAny(t){return this._anyListeners=this._anyListeners||[],this._anyListeners.push(t),this}prependAny(t){return this._anyListeners=this._anyListeners||[],this._anyListeners.unshift(t),this}offAny(t){if(!this._anyListeners)return this;if(t){const e=this._anyListeners;for(let s=0;s<e.length;s++)if(t===e[s])return e.splice(s,1),this}else this._anyListeners=[];return this}listenersAny(){return this._anyListeners||[]}onAnyOutgoing(t){return this._anyOutgoingListeners=this._anyOutgoingListeners||[],this._anyOutgoingListeners.push(t),this}prependAnyOutgoing(t){return this._anyOutgoingListeners=this._anyOutgoingListeners||[],this._anyOutgoingListeners.unshift(t),this}offAnyOutgoing(t){if(!this._anyOutgoingListeners)return this;if(t){const e=this._anyOutgoingListeners;for(let s=0;s<e.length;s++)if(t===e[s])return e.splice(s,1),this}else this._anyOutgoingListeners=[];return this}listenersAnyOutgoing(){return this._anyOutgoingListeners||[]}notifyOutgoingListeners(t){if(this._anyOutgoingListeners&&this._anyOutgoingListeners.length){const e=this._anyOutgoingListeners.slice();for(const s of e)s.apply(this,t.data)}}}function kt(t){t=t||{},this.ms=t.min||100,this.max=t.max||1e4,this.factor=t.factor||2,this.jitter=t.jitter>0&&t.jitter<=1?t.jitter:0,this.attempts=0}kt.prototype.duration=function(){var t=this.ms*Math.pow(this.factor,this.attempts++);if(this.jitter){var e=Math.random(),s=Math.floor(e*this.jitter*t);t=1&Math.floor(10*e)?t+s:t-s}return 0|Math.min(t,this.max)},kt.prototype.reset=function(){this.attempts=0},kt.prototype.setMin=function(t){this.ms=t},kt.prototype.setMax=function(t){this.max=t},kt.prototype.setJitter=function(t){this.jitter=t};class xt extends T{constructor(t,e){var s;super(),this.nsps={},this.subs=[],t&&"object"==typeof t&&(e=t,t=void 0),(e=e||{}).path=e.path||"/socket.io",this.opts=e,R(this,e),this.reconnection(!1!==e.reconnection),this.reconnectionAttempts(e.reconnectionAttempts||1/0),this.reconnectionDelay(e.reconnectionDelay||1e3),this.reconnectionDelayMax(e.reconnectionDelayMax||5e3),this.randomizationFactor(null!==(s=e.randomizationFactor)&&void 0!==s?s:.5),this.backoff=new kt({min:this.reconnectionDelay(),max:this.reconnectionDelayMax(),jitter:this.randomizationFactor()}),this.timeout(null==e.timeout?2e4:e.timeout),this._readyState="closed",this.uri=t;const n=e.parser||yt;this.encoder=new n.Encoder,this.decoder=new n.Decoder,this._autoConnect=!1!==e.autoConnect,this._autoConnect&&this.open()}reconnection(t){return arguments.length?(this._reconnection=!!t,t||(this.skipReconnect=!0),this):this._reconnection}reconnectionAttempts(t){return void 0===t?this._reconnectionAttempts:(this._reconnectionAttempts=t,this)}reconnectionDelay(t){var e;return void 0===t?this._reconnectionDelay:(this._reconnectionDelay=t,null===(e=this.backoff)||void 0===e||e.setMin(t),this)}randomizationFactor(t){var e;return void 0===t?this._randomizationFactor:(this._randomizationFactor=t,null===(e=this.backoff)||void 0===e||e.setJitter(t),this)}reconnectionDelayMax(t){var e;return void 0===t?this._reconnectionDelayMax:(this._reconnectionDelayMax=t,null===(e=this.backoff)||void 0===e||e.setMax(t),this)}timeout(t){return arguments.length?(this._timeout=t,this):this._timeout}maybeReconnectOnOpen(){!this._reconnecting&&this._reconnection&&0===this.backoff.attempts&&this.reconnect()}open(t){if(~this._readyState.indexOf("open"))return this;this.engine=new et(this.uri,this.opts);const e=this.engine,s=this;this._readyState="opening",this.skipReconnect=!1;const n=vt(e,"open",function(){s.onopen(),t&&t()}),i=e=>{this.cleanup(),this._readyState="closed",this.emitReserved("error",e),t?t(e):this.maybeReconnectOnOpen()},o=vt(e,"error",i);if(!1!==this._timeout){const t=this._timeout,s=this.setTimeoutFn(()=>{n(),i(new Error("timeout")),e.close()},t);this.opts.autoUnref&&s.unref(),this.subs.push(()=>{this.clearTimeoutFn(s)})}return this.subs.push(n),this.subs.push(o),this}connect(t){return this.open(t)}onopen(){this.cleanup(),this._readyState="open",this.emitReserved("open");const t=this.engine;this.subs.push(vt(t,"ping",this.onping.bind(this)),vt(t,"data",this.ondata.bind(this)),vt(t,"error",this.onerror.bind(this)),vt(t,"close",this.onclose.bind(this)),vt(this.decoder,"decoded",this.ondecoded.bind(this)))}onping(){this.emitReserved("ping")}ondata(t){try{this.decoder.add(t)}catch(t){this.onclose("parse error",t)}}ondecoded(t){E(()=>{this.emitReserved("packet",t)},this.setTimeoutFn)}onerror(t){this.emitReserved("error",t)}socket(t,e){let s=this.nsps[t];return s?this._autoConnect&&!s.active&&s.connect():(s=new wt(this,t,e),this.nsps[t]=s),s}_destroy(t){const e=Object.keys(this.nsps);for(const t of e){if(this.nsps[t].active)return}this._close()}_packet(t){const e=this.encoder.encode(t);for(let s=0;s<e.length;s++)this.engine.write(e[s],t.options)}cleanup(){this.subs.forEach(t=>t()),this.subs.length=0,this.decoder.destroy()}_close(){this.skipReconnect=!0,this._reconnecting=!1,this.onclose("forced close")}disconnect(){return this._close()}onclose(t,e){var s;this.cleanup(),null===(s=this.engine)||void 0===s||s.close(),this.backoff.reset(),this._readyState="closed",this.emitReserved("close",t,e),this._reconnection&&!this.skipReconnect&&this.reconnect()}reconnect(){if(this._reconnecting||this.skipReconnect)return this;const t=this;if(this.backoff.attempts>=this._reconnectionAttempts)this.backoff.reset(),this.emitReserved("reconnect_failed"),this._reconnecting=!1;else{const e=this.backoff.duration();this._reconnecting=!0;const s=this.setTimeoutFn(()=>{t.skipReconnect||(this.emitReserved("reconnect_attempt",t.backoff.attempts),t.skipReconnect||t.open(e=>{e?(t._reconnecting=!1,t.reconnect(),this.emitReserved("reconnect_error",e)):t.onreconnect()}))},e);this.opts.autoUnref&&s.unref(),this.subs.push(()=>{this.clearTimeoutFn(s)})}}onreconnect(){const t=this.backoff.attempts;this._reconnecting=!1,this.backoff.reset(),this.emitReserved("reconnect",t)}}const Ct={};function Tt(t,e){"object"==typeof t&&(e=t,t=void 0);const s=function(t,e="",s){let n=t;s=s||"undefined"!=typeof location&&location,null==t&&(t=s.protocol+"//"+s.host),"string"==typeof t&&("/"===t.charAt(0)&&(t="/"===t.charAt(1)?s.protocol+t:s.host+t),/^(https?|wss?):\/\//.test(t)||(t=void 0!==s?s.protocol+"//"+t:"https://"+t),n=G(t)),n.port||(/^(http|ws)$/.test(n.protocol)?n.port="80":/^(http|ws)s$/.test(n.protocol)&&(n.port="443")),n.path=n.path||"/";const i=-1!==n.host.indexOf(":")?"["+n.host+"]":n.host;return n.id=n.protocol+"://"+i+":"+n.port+e,n.href=n.protocol+"://"+i+(s&&s.port===n.port?"":":"+n.port),n}(t,(e=e||{}).path||"/socket.io"),n=s.source,i=s.id,o=s.path,a=Ct[i]&&o in Ct[i].nsps;let r;return e.forceNew||e["force new connection"]||!1===e.multiplex||a?r=new xt(n,e):(Ct[i]||(Ct[i]=new xt(n,e)),r=Ct[i]),s.query&&!e.query&&(e.query=s.queryKey),r.socket(s.path,e)}Object.assign(Tt,{Manager:xt,Socket:wt,io:Tt,connect:Tt});class Et extends e{constructor(t){super(),this.socket=null,this.reconnectAttempts=0,this.maxReconnectAttempts=5,this.reconnectDelay=1e3,this.config=t}connect(){var e;if(null===(e=this.socket)||void 0===e?void 0:e.connected)return;const s=this.config.socketUrl||this.config.apiBaseUrl||window.location.origin;try{this.socket=Tt(s,{transports:["websocket","polling"],timeout:1e4,forceNew:!0}),this.setupEventListeners()}catch(e){this.emit("error",new t("Failed to connect to socket server","SOCKET_CONNECTION_ERROR",e))}}disconnect(){this.socket&&(this.socket.disconnect(),this.socket=null),this.reconnectAttempts=0}isConnected(){var t;return(null===(t=this.socket)||void 0===t?void 0:t.connected)||!1}joinRoom(e,s,n){var i;if(!(null===(i=this.socket)||void 0===i?void 0:i.connected))throw new t("Socket not connected","SOCKET_NOT_CONNECTED");this.socket.emit("join-project",{projectId:e,userId:s,username:n})}leaveRoom(t,e){var s;(null===(s=this.socket)||void 0===s?void 0:s.connected)&&this.socket.emit("leave-project",{projectId:t,userId:e})}sendMessage(e,s,n,i="text"){var o;if(!(null===(o=this.socket)||void 0===o?void 0:o.connected))throw new t("Socket not connected","SOCKET_NOT_CONNECTED");this.socket.emit("send-message",{projectId:e,userId:s,content:n,messageType:i,timestamp:(new Date).toISOString()})}startTyping(t,e){var s;(null===(s=this.socket)||void 0===s?void 0:s.connected)&&this.socket.emit("start-typing",{projectId:t,userId:e})}stopTyping(t,e){var s;(null===(s=this.socket)||void 0===s?void 0:s.connected)&&this.socket.emit("stop-typing",{projectId:t,userId:e})}setupEventListeners(){this.socket&&(this.socket.on("connect",()=>{this.reconnectAttempts=0,this.emit("connected")}),this.socket.on("disconnect",t=>{this.emit("disconnected",t),"io server disconnect"===t&&this.handleReconnect()}),this.socket.on("connect_error",e=>{this.emit("error",new t("Socket connection error","SOCKET_CONNECTION_ERROR",e)),this.handleReconnect()}),this.socket.on("user-joined",t=>{this.emit("user-joined",t)}),this.socket.on("user-left",t=>{this.emit("user-left",t)}),this.socket.on("new-message",t=>{this.emit("new-message",t)}),this.socket.on("user-typing",t=>{this.emit("user-typing",t)}),this.socket.on("user-stopped-typing",t=>{this.emit("user-stopped-typing",t)}),this.socket.on("simulation-ended",t=>{this.emit("simulation-ended",t)}),this.socket.on("error",e=>{this.emit("error",new t("Socket error","SOCKET_ERROR",e))}))}handleReconnect(){if(this.reconnectAttempts>=this.maxReconnectAttempts)return void this.emit("error",new t("Max reconnection attempts reached","SOCKET_RECONNECT_FAILED"));this.reconnectAttempts++;const e=this.reconnectDelay*Math.pow(2,this.reconnectAttempts-1);setTimeout(()=>{var t;(null===(t=this.socket)||void 0===t?void 0:t.connected)||this.connect()},e)}}function St(t,e,s){const n=document.createElement(t);return e&&(n.className=e),n}function _t(t){const e=document.createElement("div");return e.textContent=t,e.innerHTML}function It(t,e=!0){t.scrollTop=t.scrollHeight,t.scrollTo&&t.scrollTo({top:t.scrollHeight,behavior:e?"smooth":"auto"})}class Mt extends e{constructor(t,e){super(),this.simulationData=null,this.displayedMessages=[],this.currentMessageIndex=0,this.isRunning=!1,this.isPaused=!1,this.intervalId=null,this.pollingId=null,this.burstPhase=!0,this.totalToShow=1/0,this.virtualLastTimestamp=null,this.realLastTimestamp=null,this.lastTimestamp=null,this.lastDelayMs=0,this.userId="",this.config=t,this.apiClient=e}async initialize(){try{const t=this.config.language||"en",e=this.getPersistedUserId(),s=e||this.config.userId||this.generateUserId();this.userId=s,e||this.persistUserId(s);const n=await this.apiClient.getSimulationData(this.config.projectId,s,t);if(!n.success||!n.data)throw new Error("Failed to load simulation data");this.simulationData=n.data;const i=this.simulationData.project.initialBurstCount+this.simulationData.project.continuousCount;this.totalToShow=Math.min(i,this.simulationData.messages.length);const o=this.loadProgress();o&&"number"==typeof o.index?(this.currentMessageIndex=o.index,o.lastTimestamp&&(this.virtualLastTimestamp=new Date(o.lastTimestamp),this.lastTimestamp=new Date(o.lastTimestamp))):(this.currentMessageIndex=0,this.virtualLastTimestamp=null,this.lastTimestamp=null),this.realLastTimestamp=null,await this.loadExistingMessages(),await this.reconstructVirtualHistoryForDisplay(),this.emit("initialized",this.simulationData),this.startPolling(),!1!==this.config.autoStart&&this.start()}catch(t){throw this.emit("error",t),t}}start(){this.simulationData&&!this.isRunning&&(this.isRunning=!0,this.isPaused=!1,this.burstPhase=!0,this.emit("simulationStart"),this.performInitialBurst(),this.currentMessageIndex<this.totalToShow?(this.burstPhase=!1,this.scheduleNextMessage()):(this.isRunning=!1,this.emit("simulationEnd")))}performInitialBurst(){if(!this.simulationData)return;const{project:t,messages:e}=this.simulationData,s=t.initialBurstCount,n=Math.min(s,this.totalToShow,e.length);if(this.currentMessageIndex>=n)return;if(this.displayedMessages.some(t=>t.id.startsWith("sim-"))&&this.currentMessageIndex>0)return;const i=new Date,o=new Array(n);let a=new Date(i);for(let t=n-1;t>=0;t--)if(o[t]=new Date(a),t>0){const t=10+Math.floor(11*Math.random());a=new Date(a.getTime()-60*t*1e3)}const r=[];let h=!1;for(let t=this.currentMessageIndex;t<n;t++){const s=e[t];if(s.hasScreenshot&&s.screenshotUrl){const e={id:`sim-${t}-text-${Date.now()}`,content:s.content,messageType:"text",timestamp:o[t],isOwnMessage:!1,virtualUser:s.virtualUser};this.displayedMessages.push(e),r.push(e);const n=new Date(o[t].getTime()+2e3),i={id:`sim-${t}-image-${Date.now()}`,content:s.screenshotUrl,messageType:"image",timestamp:n,isOwnMessage:!1,virtualUser:s.virtualUser};this.displayedMessages.push(i),r.push(i)}else{const e={id:`sim-${t}-${Date.now()}`,content:s.content,messageType:s.messageType,timestamp:o[t],isOwnMessage:!1,virtualUser:s.virtualUser};this.displayedMessages.push(e),r.push(e)}this.currentMessageIndex=t+1,h=!0}h&&(this.lastTimestamp=o[n-1],this.virtualLastTimestamp=this.lastTimestamp,this.displayedMessages.sort((t,e)=>t.timestamp.getTime()-e.timestamp.getTime()),this.emit("messages-batch",r)),this.saveProgress()}pause(){this.isRunning&&(this.isPaused=!0,this.intervalId&&(clearTimeout(this.intervalId),this.intervalId=null),this.emit("simulationPause"))}resume(){this.isRunning&&this.isPaused&&(this.isPaused=!1,this.scheduleNextMessage(),this.emit("simulationResume"))}stop(){this.isRunning=!1,this.isPaused=!1,this.intervalId&&(clearTimeout(this.intervalId),this.intervalId=null),this.emit("simulationStop")}destroy(){this.stop(),this.stopPolling(),this.removeAllListeners()}scheduleNextMessage(){if(!this.simulationData||!this.isRunning||this.isPaused)return;const{project:t,messages:e}=this.simulationData;if(this.currentMessageIndex>=this.totalToShow)return this.isRunning=!1,void this.emit("simulationEnd");let s;if(this.burstPhase){const n=Math.min(t.initialBurstCount,e.length);this.currentMessageIndex<n?s=500+1e3*Math.random():(this.burstPhase=!1,s=this.getRandomInterval(t.messageIntervalMin,t.messageIntervalMax))}else{const n=Math.min(t.initialBurstCount,e.length);s=this.currentMessageIndex-n<5?1e3*(t.initialMessageInterval||10):this.getRandomInterval(t.messageIntervalMin,t.messageIntervalMax)}this.lastDelayMs=s,this.intervalId=setTimeout(()=>{this.displayNextMessage(),this.scheduleNextMessage()},s)}displayNextMessage(){if(!this.simulationData||this.currentMessageIndex>=this.simulationData.messages.length)return;const t=this.simulationData.messages[this.currentMessageIndex],e=this.lastTimestamp||new Date,s=new Date(e.getTime()+(this.lastDelayMs||0));if(this.lastTimestamp=s,t.hasScreenshot&&t.screenshotUrl){const e={id:`sim-${this.currentMessageIndex}-text-${Date.now()}`,content:t.content,messageType:"text",timestamp:s,isOwnMessage:!1,virtualUser:t.virtualUser};this.displayedMessages.push(e),this.emit("message",e);const n=new Date(s.getTime()+2e3),i={id:`sim-${this.currentMessageIndex}-image-${Date.now()}`,content:t.screenshotUrl,messageType:"image",timestamp:n,isOwnMessage:!1,virtualUser:t.virtualUser};this.displayedMessages.push(i),this.lastTimestamp=n,setTimeout(()=>{this.emit("message",i)},2e3)}else{const e={id:`sim-${this.currentMessageIndex}-${Date.now()}`,content:t.content,messageType:t.messageType,timestamp:s,isOwnMessage:!1,virtualUser:t.virtualUser};this.displayedMessages.push(e),this.emit("message",e)}this.currentMessageIndex++,this.saveProgress()}async loadExistingMessages(){if(this.simulationData)try{const t=this.userId||this.config.userId||this.generateUserId(),e=await this.apiClient.getSimulationMessages(this.config.projectId,t,void 0,100);if(e.success&&e.messages&&e.messages.length>0){const s=e.messages.sort((t,e)=>new Date(t.createdAt||t.timestamp).getTime()-new Date(e.createdAt||e.timestamp).getTime()),n=new Set(this.displayedMessages.map(t=>t.id));for(const e of s){if(n.has(e.id))continue;const s={id:e.id,content:e.content,messageType:e.messageType,timestamp:new Date(e.createdAt||e.timestamp),isOwnMessage:e.userId===t,virtualUser:e.virtualUser,user:e.userId===t?{id:t,username:this.config.username||"You"}:void 0};this.displayedMessages.push(s)}if(s.length>0){const t=s[s.length-1];this.realLastTimestamp=new Date(t.createdAt||t.timestamp)}this.displayedMessages.length>0&&this.emit("messages-batch",[...this.displayedMessages])}}catch(t){console.warn("Failed to load existing messages:",t)}}startPolling(){const t=this.config.pollingInterval||3e3;this.pollingId=setInterval(async()=>{await this.pollForNewMessages()},t)}stopPolling(){this.pollingId&&(clearInterval(this.pollingId),this.pollingId=null)}async pollForNewMessages(){if(this.simulationData)try{const t=this.userId||this.config.userId||this.generateUserId(),e=this.getLastMessageTimestamp(),s=await this.apiClient.getSimulationMessages(this.config.projectId,t,e);if(s.success&&s.messages&&s.messages.length>0){const e=new Set(this.displayedMessages.map(t=>t.id));let n=null;for(const i of s.messages){if(e.has(i.id))continue;const s=new Date(i.createdAt),o={id:i.id,content:i.content,messageType:i.messageType,timestamp:s,isOwnMessage:i.userId===t,virtualUser:i.virtualUser,user:i.userId===t?{id:t,username:this.config.username||"You"}:void 0};(!n||s>n)&&(n=s),this.displayedMessages.push(o),this.emit("message",o)}n&&(this.realLastTimestamp=n)}}catch(t){console.warn("Polling error:",t)}}async reconstructVirtualHistoryForDisplay(){if(!this.simulationData)return;const t=Math.min(this.currentMessageIndex,this.totalToShow,this.simulationData.messages.length);if(t<=0)return;const e=this.loadProgress(),s=(null==e?void 0:e.virtualMessages)||[];if(s.length>0){const t=[],e=new Set(this.displayedMessages.map(t=>t.id));for(const n of s)if(!e.has(n.id)){const e={id:n.id,content:n.content,messageType:n.messageType,timestamp:new Date(n.timestamp),isOwnMessage:!1,virtualUser:n.virtualUser};t.push(e)}if(t.length>0){this.displayedMessages.push(...t),this.displayedMessages.sort((t,e)=>t.timestamp.getTime()-e.timestamp.getTime());const e=t[t.length-1];this.virtualLastTimestamp=e.timestamp,this.lastTimestamp=e.timestamp,this.emit("messages-batch",t)}return}const n=new Date,i=new Array(t);let o=new Date(n);for(let e=t-1;e>=0;e--)if(i[e]=new Date(o),e>0){const t=10+Math.floor(11*Math.random());o=new Date(o.getTime()-60*t*1e3)}const a=[],{messages:r}=this.simulationData;for(let e=0;e<t;e++){const t=r[e],s=i[e];if(t.hasScreenshot&&t.screenshotUrl){const n={id:`sim-${e}-text`,content:t.content,messageType:"text",timestamp:s,isOwnMessage:!1,virtualUser:t.virtualUser},i={id:`sim-${e}-image`,content:t.screenshotUrl,messageType:"image",timestamp:new Date(s.getTime()+2e3),isOwnMessage:!1,virtualUser:t.virtualUser};a.push(n,i)}else{const n={id:`sim-${e}`,content:t.content,messageType:t.messageType,timestamp:s,isOwnMessage:!1,virtualUser:t.virtualUser};a.push(n)}}const h=new Set(this.displayedMessages.map(t=>t.id)),c=a.filter(t=>!h.has(t.id));if(0===c.length)return;this.displayedMessages.push(...c),this.displayedMessages.sort((t,e)=>t.timestamp.getTime()-e.timestamp.getTime());const l=c[c.length-1];this.virtualLastTimestamp=l.timestamp,this.lastTimestamp=l.timestamp,this.emit("messages-batch",c)}getLastMessageTimestamp(){if(this.realLastTimestamp)return this.realLastTimestamp.toISOString()}getUserKey(){return`vcs:user:${this.config.projectId}`}getProgressKey(){const t=this.userId||this.config.userId||"anon";return`vcs:progress:${this.config.projectId}:${t}`}getPersistedUserId(){try{return"undefined"==typeof window?null:window.localStorage.getItem(this.getUserKey())}catch(t){return null}}persistUserId(t){try{if("undefined"==typeof window)return;window.localStorage.setItem(this.getUserKey(),t)}catch(t){}}loadProgress(){try{if("undefined"==typeof window)return null;const t=window.localStorage.getItem(this.getProgressKey());return t?JSON.parse(t):null}catch(t){return null}}saveProgress(){try{if("undefined"==typeof window)return;const t=this.displayedMessages.filter(t=>t.id.startsWith("sim-")).map(t=>({id:t.id,content:t.content,messageType:t.messageType,timestamp:t.timestamp.toISOString(),virtualUser:t.virtualUser})),e={index:this.currentMessageIndex,lastTimestamp:this.lastTimestamp?this.lastTimestamp.toISOString():void 0,virtualMessages:t};window.localStorage.setItem(this.getProgressKey(),JSON.stringify(e))}catch(t){}}clearProgress(){try{if("undefined"==typeof window)return;window.localStorage.removeItem(this.getProgressKey())}catch(t){}}clearCachedProgress(){this.clearProgress()}getRandomInterval(t,e){return 1e3*(t+Math.random()*(e-t))}generateUserId(){return`user-${Date.now()}-${Math.random().toString(36).substring(2,11)}`}get messages(){return[...this.displayedMessages]}get isSimulationRunning(){return this.isRunning}get isSimulationPaused(){return this.isPaused}get data(){return this.simulationData}async sendMessage(t,e="text"){if(!this.simulationData)throw new Error("Simulation not initialized");const s=this.userId||this.config.userId||this.generateUserId(),n=this.config.username||"User";try{if("image"===e||"string"==typeof t&&t.startsWith("data:image/"))return;await Promise.all([this.apiClient.sendUserMessage(this.config.projectId,s,n,t,e),this.apiClient.triggerAIReply(this.config.projectId,s,n,t,e)])}catch(t){throw this.emit("error",t),t}}}class Rt extends e{constructor(t){var e,n;super(),this.emojiPanelOpen=!1,this.onlineCount=0,this.debugEnabled=!1,this.currentTheme="whatsapp",this.isDarkMode=!1,this.customColors={},this.visibleStartIndex=0,this.config=t,this.currentTheme="telegram"===t.uiTemplate?"telegram":"whatsapp",this.isDarkMode="dark"===t.theme,this.customColors={primary:t.primaryColor,background:t.backgroundColor},this.onlineCount=500+Math.floor(301*Math.random()),this.initialRenderCount=null!==(e=this.config.initialRenderCount)&&void 0!==e?e:Number.MAX_SAFE_INTEGER,this.lazyLoadBatchSize=null!==(n=this.config.lazyLoadBatchSize)&&void 0!==n?n:20,this.state={isInitialized:!1,isOpen:!1,isJoined:!1,isConnected:!1,isSimulationRunning:!1,isSimulationPaused:!1,messages:[],virtualUsers:[],realUsers:[],typingUsers:[],simulationEnded:!1,displayedMessageCount:0,unreadCount:0,lastReadMessageId:null,inputFocused:!1},this.apiClient=new s(t),this.simulator=new Mt(t,this.apiClient),this.setupSimulatorEvents(),this.init()}init(){try{console.log("[ChatWidget] Starting initialization..."),this.setupContainer(),console.log("[ChatWidget] Container setup complete"),this.createWidget(),console.log("[ChatWidget] Widget created"),this.debugEnabled=!!this.config.enableDebugOverlay,this.debugEnabled&&(this.createDebugOverlay(),this.debugLog("Debug overlay enabled")),"floating"===this.config.mode&&(console.log("[ChatWidget] Setting up floating mode"),this.widgetElement.style.display="none",this.createFloatingButton(),console.log("[ChatWidget] Floating button created")),this.setupEventListeners(),this.setupImageViewer(),this.state.isInitialized=!0,this.emit("ready"),console.log("[ChatWidget] Widget initialization complete"),this.initializeSimulation()}catch(e){this.emit("error",new t("Failed to initialize chat widget","WIDGET_INIT_ERROR",e))}}setupSimulatorEvents(){this.simulator.on("initialized",t=>{var e;this.state.currentProject=t.project,this.state.currentTemplate=t.template,null!=this.config.initialRenderCount?this.initialRenderCount=this.config.initialRenderCount:this.initialRenderCount=Number.MAX_SAFE_INTEGER;const s=(this.config.language||"en").startsWith("zh")?"条消息":"messages";this.setTitle((null===(e=t.project)||void 0===e?void 0:e.name)||"Chat",`0 ${s}`),this.setLoading(!1),this.emit("simulationInitialized",t)}),this.simulator.on("message",t=>{var e;this.setLoading(!1),this.addMessage(t),this.state.displayedMessageCount++;const s=(this.config.language||"en").startsWith("zh")?"条消息":"messages",n=(null===(e=this.state.currentProject)||void 0===e?void 0:e.name)||"Chat";this.setTitle(n,`${this.state.displayedMessageCount} ${s}`)}),this.simulator.on("messages-batch",t=>{var e;this.setLoading(!1),this.addMessagesBulk(t),this.state.displayedMessageCount+=t.length;const s=(this.config.language||"en").startsWith("zh")?"条消息":"messages",n=(null===(e=this.state.currentProject)||void 0===e?void 0:e.name)||"Chat";this.setTitle(n,`${this.state.displayedMessageCount} ${s}`),setTimeout(()=>{this.scrollToBottom(!0)},100)}),this.simulator.on("simulationStart",()=>{var t,e;this.state.isSimulationRunning=!0,this.state.isSimulationPaused=!1,null===(e=(t=this.config).onSimulationStart)||void 0===e||e.call(t)}),this.simulator.on("simulationEnd",()=>{var t,e;this.state.isSimulationRunning=!1,this.state.simulationEnded=!0,null===(e=(t=this.config).onSimulationEnd)||void 0===e||e.call(t)}),this.simulator.on("simulationPause",()=>{this.state.isSimulationPaused=!0}),this.simulator.on("simulationResume",()=>{this.state.isSimulationPaused=!1}),this.simulator.on("error",t=>{this.emit("error",t)})}async initializeSimulation(){try{await this.simulator.initialize()}catch(e){this.emit("error",new t("Failed to initialize simulation","SIMULATION_INIT_ERROR",e))}}setupContainer(){var e;const s="string"==typeof(n=this.config.container)?document.querySelector(n):n;var n;if(!s)throw new t("Container element not found","CONTAINER_NOT_FOUND");const i=null===(e=s.tagName)||void 0===e?void 0:e.toUpperCase();if("BODY"===i||"HTML"===i){const t=document.createElement("div");t.className="chat-sdk-host",t.style.position="static",t.style.width="0",t.style.height="0",document.body.appendChild(t),this.container=t}else this.container=s;this.shadowRoot=this.container.attachShadow({mode:"closed"});const o=this.getDefaultStyles();!function(t,e){const s=document.createElement("style");s.textContent=e,t.appendChild(s)}(this.shadowRoot,o)}createWidget(){var t;if(this.widgetElement&&this.messagesContainer)return;this.widgetElement=St("div","chat-sdk-container");const e="telegram"===this.config.uiTemplate?"telegram":"whatsapp";this.currentTheme=e,this.widgetElement.classList.add(`${e}-theme`),"telegram"===e&&"dark"===this.config.theme&&(this.widgetElement.classList.add("dark"),this.isDarkMode=!0),this.widgetElement.style.position="fixed",this.widgetElement.style.top="0",this.widgetElement.style.left="0",this.widgetElement.style.width="100vw",this.widgetElement.style.height="100vh",this.widgetElement.style.zIndex=String(null!==(t=this.config.zIndex)&&void 0!==t?t:2147483e3),this.widgetElement.innerHTML='\n <div class="chat-sdk-header">\n <div class="chat-sdk-header-left">\n <div class="chat-sdk-title" id="chat-title"></div>\n <div class="chat-sdk-subtitle" id="chat-subtitle"></div>\n </div>\n <button class="chat-sdk-close-btn" type="button">\n <svg width="20" height="20" viewBox="0 0 16 16" fill="currentColor">\n <path d="M8 7.293l2.146-2.147a.5.5 0 01.708.708L8.707 8l2.147 2.146a.5.5 0 01-.708.708L8 8.707l-2.146 2.147a.5.5 0 01-.708-.708L7.293 8 5.146 5.854a.5.5 0 01.708-.708L8 7.293z"/>\n </svg>\n </button>\n </div>\n\n <div class="chat-sdk-messages" id="messages-container">\n <div class="chat-sdk-loading">\n <div class="chat-sdk-spinner"></div>\n Loading chat...\n </div>\n </div>\n\n <div class="chat-sdk-input-area">\n <button class="chat-sdk-icon-btn chat-sdk-emoji-btn" type="button" id="emoji-button" aria-label="Emoji">\n <span>😊</span>\n </button>\n <button class="chat-sdk-icon-btn chat-sdk-image-btn" type="button" id="image-button" aria-label="Image">\n <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor"><path d="M21 19V5a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v14h18zM5 5h14v8l-3-3-4 5-3-4-4 4V5z"/></svg>\n </button>\n <textarea\n class="chat-sdk-input"\n placeholder="Type a message..."\n rows="1"\n id="message-input"\n ></textarea>\n <input type="file" accept="image/*" id="image-input" style="display:none" />\n <button class="chat-sdk-send-btn" type="button" id="send-button" disabled>\n <svg width="16" height="16" viewBox="0 0 16 16" fill="currentColor">\n <path d="M15.854.146a.5.5 0 01.11.54l-5.819 14.547a.75.75 0 01-1.329.124l-3.178-4.995L.643 7.184a.75.75 0 01.124-1.33L15.314.037a.5.5 0 01.54.11z"/>\n </svg>\n </button>\n </div>\n <div class="chat-sdk-emoji-picker" id="emoji-picker" style="display:none">\n <div class="chat-sdk-emoji-grid">\n <button type="button" class="chat-sdk-emoji-item" data-emoji="😀">😀</button>\n <button type="button" class="chat-sdk-emoji-item" data-emoji="😁">😁</button>\n <button type="button" class="chat-sdk-emoji-item" data-emoji="😂">😂</button>\n <button type="button" class="chat-sdk-emoji-item" data-emoji="🤣">🤣</button>\n <button type="button" class="chat-sdk-emoji-item" data-emoji="😊">😊</button>\n <button type="button" class="chat-sdk-emoji-item" data-emoji="😍">😍</button>\n <button type="button" class="chat-sdk-emoji-item" data-emoji="😎">😎</button>\n <button type="button" class="chat-sdk-emoji-item" data-emoji="🤔">🤔</button>\n <button type="button" class="chat-sdk-emoji-item" data-emoji="👍">👍</button>\n <button type="button" class="chat-sdk-emoji-item" data-emoji="🙏">🙏</button>\n </div>\n </div>\n ',this.messagesContainer=this.widgetElement.querySelector("#messages-container"),this.inputElement=this.widgetElement.querySelector("#message-input"),this.sendButton=this.widgetElement.querySelector("#send-button"),this.emojiButton=this.widgetElement.querySelector("#emoji-button"),this.imageButton=this.widgetElement.querySelector("#image-button"),this.fileInput=this.widgetElement.querySelector("#image-input"),this.emojiPicker=this.widgetElement.querySelector("#emoji-picker"),this.shadowRoot.appendChild(this.widgetElement)}setupEventListeners(){var t,e,s,n;const i=this.widgetElement.querySelector(".chat-sdk-close-btn");null==i||i.addEventListener("click",()=>this.close()),this.messagesContainer.addEventListener("scroll",this.handleScrollLazyLoad.bind(this)),this.inputElement.addEventListener("input",this.handleInputChange.bind(this)),this.inputElement.addEventListener("keydown",this.handleKeyDown.bind(this)),this.inputElement.addEventListener("focus",this.handleInputFocus.bind(this)),this.inputElement.addEventListener("blur",this.handleInputBlur.bind(this)),this.sendButton.addEventListener("click",this.handleSendMessage.bind(this)),this.inputElement.addEventListener("input",this.autoResizeTextarea.bind(this)),null===(t=this.emojiButton)||void 0===t||t.addEventListener("click",t=>{t.preventDefault(),t.stopPropagation(),this.toggleEmojiPicker(!this.emojiPanelOpen)}),null===(e=this.emojiPicker)||void 0===e||e.addEventListener("click",t=>{const e=t.target.closest(".chat-sdk-emoji-item");if(e&&e.hasAttribute("data-emoji")){const t=e.getAttribute("data-emoji")||"";this.insertEmojiAtCursor(t),this.toggleEmojiPicker(!1)}}),this.shadowRoot.addEventListener("click",t=>{const e=t.target,s=e.closest("#emoji-picker"),n=e.closest("#emoji-button");s||n||this.toggleEmojiPicker(!1)}),null===(s=this.imageButton)||void 0===s||s.addEventListener("click",t=>{var e;t.preventDefault(),t.stopPropagation(),null===(e=this.fileInput)||void 0===e||e.click()}),null===(n=this.fileInput)||void 0===n||n.addEventListener("change",this.handleImageSelected.bind(this)),document.addEventListener("keydown",t=>{var e;if("Escape"!==t.key)return;if(!this.state.isOpen)return;const s=()=>{try{t.stopImmediatePropagation()}catch(t){}try{t.stopPropagation()}catch(t){}try{t.preventDefault()}catch(t){}};if(this.config.disableEscClose)return this.debugLog("ESC ignored (disableEscClose=true)"),void s();const n=(null===(e=this.shadowRoot)||void 0===e?void 0:e.activeElement)||document.activeElement,i=!!n&&(n===this.inputElement||"TEXTAREA"===n.tagName||"INPUT"===n.tagName||n.isContentEditable);return this.state.inputFocused||i?(this.debugLog("ESC ignored (input focused)"),void s()):this.isTelegramMiniprogram()?(this.debugLog("ESC ignored (Telegram environment)"),void s()):void this.close()},{capture:!0}),this.setupTelegramMiniprogramHandling()}createFloatingButton(){var t,e,s,n,i,o,a,r,h,c,l;if(console.log("[ChatWidget] Creating floating button..."),!this.shadowRoot)return void console.error("[ChatWidget] No shadow root available for floating button");const d=this.config.floatingButton||{},u=d.position||"bottom-right",g=String(null!==(e=null!==(t=d.zIndex)&&void 0!==t?t:this.config.zIndex)&&void 0!==e?e:2147483e3),p={top:null===(s=d.offset)||void 0===s?void 0:s.top,right:null===(n=d.offset)||void 0===n?void 0:n.right,bottom:null!==(o=null===(i=d.offset)||void 0===i?void 0:i.bottom)&&void 0!==o?o:20,left:null===(a=d.offset)||void 0===a?void 0:a.left};console.log("[ChatWidget] Floating button config:",{pos:u,z:g,offset:p});const m=document.createElement("button");m.className="chat-sdk-floating-btn",m.setAttribute("aria-label","Open chat"),m.innerHTML='\n <svg width="24" height="24" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">\n <path d="M20 2H4a2 2 0 00-2 2v14l4-4h14a2 2 0 002-2V4a2 2 0 00-2-2z"/>\n </svg>\n <span class="chat-sdk-unread-badge" style="\n position: absolute;\n top: -2px;\n right: -2px;\n background: #ff4444;\n color: white;\n border-radius: 10px;\n min-width: 20px;\n height: 20px;\n display: none;\n align-items: center;\n justify-content: center;\n font-size: 12px;\n font-weight: 600;\n line-height: 1;\n border: 2px solid white;\n box-shadow: 0 2px 4px rgba(0,0,0,0.2);\n "></span>\n ',m.style.position="fixed",m.style.zIndex=g,m.style.width="56px",m.style.height="56px",m.style.borderRadius="9999px",m.style.border="none",m.style.cursor="pointer",m.style.display="flex",m.style.alignItems="center",m.style.justifyContent="center",m.style.color="#fff",m.style.boxShadow="0 8px 20px rgba(0,0,0,0.2)",m.style.background="linear-gradient(135deg, #2481cc 0%, #1c7cd6 100%)",m.style.transition="transform .15s ease, box-shadow .15s ease, opacity .2s ease",u.includes("bottom")?(m.style.bottom=(null!==(r=p.bottom)&&void 0!==r?r:20)+"px",m.style.top=""):(m.style.top=(null!==(h=p.top)&&void 0!==h?h:20)+"px",m.style.bottom=""),u.includes("right")?(m.style.right=(null!==(c=p.right)&&void 0!==c?c:20)+"px",m.style.left=""):(m.style.left=(null!==(l=p.left)&&void 0!==l?l:20)+"px",m.style.right=""),m.addEventListener("mouseenter",()=>{m.style.transform="scale(1.06)",m.style.boxShadow="0 10px 24px rgba(0,0,0,0.24)"}),m.addEventListener("mouseleave",()=>{m.style.transform="scale(1)",m.style.boxShadow="0 8px 20px rgba(0,0,0,0.2)"}),m.addEventListener("mousedown",()=>{m.style.transform="scale(0.96)"}),m.addEventListener("mouseup",()=>{m.style.transform="scale(1.02)",setTimeout(()=>m.style.transform="scale(1)",120)}),m.addEventListener("click",t=>{t.preventDefault(),this.open()}),this.shadowRoot.appendChild(m),this.floatingButtonEl=m,console.log("[ChatWidget] Floating button successfully created and added to DOM"),console.log("[ChatWidget] Button element:",this.floatingButtonEl),console.log("[ChatWidget] Button visible:","none"!==this.floatingButtonEl.style.display)}updateUnreadBadge(){if(!this.floatingButtonEl)return;const t=this.floatingButtonEl.querySelector(".chat-sdk-unread-badge");if(!t)return;const e=this.state.unreadCount;e>0?(t.textContent=e>99?"99+":e.toString(),t.style.display="flex"):t.style.display="none"}markAllAsRead(){if(this.state.messages.length>0){const t=this.state.messages[this.state.messages.length-1];this.state.lastReadMessageId=t.id}this.state.unreadCount=0,this.updateUnreadBadge()}incrementUnreadCount(){this.state.isOpen||(this.state.unreadCount++,this.updateUnreadBadge())}toggleEmojiPicker(t){const e=this.emojiPicker;if(!e)return;const s="boolean"==typeof t?t:"none"===e.style.display;e.style.display=s?"block":"none",this.emojiPanelOpen=s}insertEmojiAtCursor(t){const e=this.inputElement,s=e.selectionStart||0,n=e.selectionEnd||0,i=e.value.substring(0,s),o=e.value.substring(n);e.value=i+t+o;const a=s+t.length;e.setSelectionRange(a,a),e.focus(),this.handleInputChange(),this.autoResizeTextarea()}isEmojiOnly(t){const e=t.trim();if(!e)return!1;if(e.length>6)return!1;let s=!1;for(let t=0;t<e.length;){const n=e.codePointAt(t)||0;if(t+=n>65535?2:1,!(n>=126976))return!1;s=!0}return s}async handleImageSelected(){const e=this.fileInput;if(!e||!e.files||0===e.files.length)return;const s=e.files[0];try{const t=await this.resizeImageFile(s,1280,.85),n={id:`local-img-failed-${Date.now()}-${Math.random().toString(36).slice(2,8)}`,content:t,messageType:"image",timestamp:new Date,isOwnMessage:!0,user:{id:this.config.userId||"me",username:this.config.username||"You"},failed:!0};this.state.messages.push(n),this.renderMessage(n),this.scrollToBottom(!0),e.value=""}catch(e){console.error("Image processing failed",e),this.emit("error",new t("Image processing failed","IMAGE_PROCESS_ERROR",e))}}resizeImageFile(t,e=1280,s=.85){return new Promise((n,i)=>{const o=URL.createObjectURL(t),a=new Image;a.onload=()=>{let{width:t,height:r}=a;const h=Math.min(1,e/Math.max(t,r)),c=document.createElement("canvas");h<1&&(t=Math.round(t*h),r=Math.round(r*h)),c.width=t,c.height=r;const l=c.getContext("2d");if(!l)return URL.revokeObjectURL(o),void i(new Error("Canvas not supported"));l.drawImage(a,0,0,t,r);const d=c.toDataURL("image/jpeg",s);URL.revokeObjectURL(o),n(d)},a.onerror=t=>{URL.revokeObjectURL(o),i(t)},a.src=o})}handleInputChange(){const t=this.inputElement.value.trim().length>0,e=!1!==this.config.enableUserInput&&!1!==this.config.allowInput;this.sendButton.disabled=!t||!e,t&&e&&this.emit("typing")}handleKeyDown(t){"Enter"!==t.key||t.shiftKey||(t.preventDefault(),this.handleSendMessage())}async handleSendMessage(){const e=this.inputElement.value.trim();if(!e)return;if(!1===this.config.enableUserInput||!1===this.config.allowInput)return;const s=this.isEmojiOnly(e)?"emoji":"text",n={id:`local-${Date.now()}-${Math.random().toString(36).slice(2,8)}`,content:e,messageType:s,timestamp:new Date,isOwnMessage:!0,user:{id:this.config.userId||"me",username:this.config.username||"You"}};this.state.messages.push(n),this.renderMessage(n),this.scrollToBottom(!0),this.inputElement.value="",this.sendButton.disabled=!0,this.autoResizeTextarea(),this.simulator.sendMessage(e,s).catch(e=>{console.error("Failed to send message:",e),this.emit("error",new t("Failed to send message","SEND_MESSAGE_ERROR",e))})}autoResizeTextarea(){this.inputElement.style.height="auto",this.inputElement.style.height=Math.min(this.inputElement.scrollHeight,100)+"px"}handleInputFocus(){this.debugLog("input: focus"),(this.config.preventCloseWhileInputFocused||this.isTelegramMiniprogram())&&(this.state.inputFocused=!0),this.state.isOpen||this.open();try{this.inputElement.addEventListener("mousedown",t=>t.stopPropagation(),{once:!0,capture:!0}),this.inputElement.addEventListener("touchstart",t=>t.stopPropagation(),{once:!0,capture:!0})}catch(t){}}handleInputBlur(){this.debugLog("input: blur"),this.isTelegramMiniprogram()&&setTimeout(()=>{this.state.inputFocused=!1,this.debugLog("input: focus flag cleared")},100)}isTelegramMiniprogram(){var t;try{if(this.config.forceTelegramCompat)return this.debugLog("Telegram compatibility forced by config"),!0;if("undefined"!=typeof window&&(null===(t=window.Telegram)||void 0===t?void 0:t.WebApp))return this.debugLog("Detected Telegram WebApp API"),!0;if("undefined"!=typeof navigator){const t=navigator.userAgent.toLowerCase();if(t.includes("telegram")||t.includes("tgwebapp"))return this.debugLog("Detected Telegram via userAgent"),!0}return!1}catch(t){return this.debugLog("Error detecting Telegram environment"),!1}}setupTelegramMiniprogramHandling(){var t,e,s,n,i,o;const a=this.isTelegramMiniprogram();if(console.log("[ChatSDK] Telegram environment check:",a),!a)return void console.log("[ChatSDK] Not in Telegram environment, skipping special handling");console.log("[ChatSDK] Detected Telegram miniprogram environment, applying compatibility fixes");try{const a=null===(t=window.Telegram)||void 0===t?void 0:t.WebApp;if(a){try{null===(s=null===(e=a.BackButton)||void 0===e?void 0:e.hide)||void 0===s||s.call(e)}catch(t){}try{null===(n=a.onEvent)||void 0===n||n.call(a,"backButtonClicked",()=>this.debugLog("tg: backButtonClicked (ignored)"))}catch(t){}try{null===(i=a.onEvent)||void 0===i||i.call(a,"viewportChanged",()=>this.debugLog("tg: viewportChanged"))}catch(t){}try{null===(o=a.onEvent)||void 0===o||o.call(a,"themeChanged",()=>this.debugLog("tg: themeChanged"))}catch(t){}}}catch(t){}const r=this.close.bind(this);if(this.close=()=>{this.state.inputFocused?console.log("[ChatSDK] Prevented auto-close due to input focus in Telegram miniprogram"):r()},!document.querySelector('meta[name="viewport"]')){const t=document.createElement("meta");t.name="viewport",t.content="width=device-width, initial-scale=1.0, user-scalable=no",document.head.appendChild(t)}this.inputElement.addEventListener("touchstart",t=>{t.stopPropagation()}),this.inputElement.addEventListener("touchend",t=>{t.stopPropagation()})}open(){var t;if(this.state.isOpen)return;this.floatingButtonEl&&(this.floatingButtonEl.style.display="none"),this.widgetElement.style.opacity="0",this.widgetElement.style.display="flex",requestAnimationFrame(()=>{this.widgetElement.style.transition="opacity .2s ease",this.widgetElement.style.opacity="1"}),this.state.isOpen=!0,this.markAllAsRead(),this.emit("open");const e=(this.config.language||"en").startsWith("zh")?"条消息":"messages",s=(null===(t=this.state.currentProject)||void 0===t?void 0:t.name)||"Chat";this.setTitle(s,`${this.state.displayedMessageCount} ${e}`),this.scrollToBottom(!0),requestAnimationFrame(()=>this.scrollToBottom(!0)),setTimeout(()=>this.scrollToBottom(!0),0)}close(){var t;if(!this.state.isOpen)return;const e=(null===(t=this.shadowRoot)||void 0===t?void 0:t.activeElement)||document.activeElement,s=!!e&&(e===this.inputElement||"TEXTAREA"===(null==e?void 0:e.tagName)||"INPUT"===(null==e?void 0:e.tagName)||(null==e?void 0:e.isContentEditable));this.config.preventCloseWhileInputFocused&&(this.state.inputFocused||s)?this.debugLog("close() ignored while input focused (preventCloseWhileInputFocused=true)"):(this.widgetElement.style.transition="opacity .2s ease",this.widgetElement.style.opacity="0",setTimeout(()=>{this.widgetElement.style.display="none",this.floatingButtonEl&&(this.floatingButtonEl.style.display="flex")},200),this.state.isOpen=!1,this.emit("close"))}createDebugOverlay(){if(!this.shadowRoot||this.debugOverlayEl)return;const t=document.createElement("div");t.setAttribute("data-chat-sdk-debug","true"),t.style.cssText=["position:fixed","left:8px","bottom:8px","max-width:60%","max-height:40%","overflow:auto","background:rgba(0,0,0,0.7)","color:#0f0","font:12px/1.4 monospace","padding:6px 8px","border-radius:6px","z-index:2147483647","box-shadow:0 2px 8px rgba(0,0,0,.35)"].join(";");const e=document.createElement("div");e.textContent="ChatSDK Debug",e.style.cssText="color:#fff;font-weight:bold;margin-bottom:4px;",t.appendChild(e),this.shadowRoot.appendChild(t),this.debugOverlayEl=t}debugLog(t){try{if(!this.debugEnabled)return;if(console.log("[ChatSDK][DEBUG]",t),!this.debugOverlayEl)return;const e=document.createElement("div"),s=new Date,n=t=>String(t).padStart(2,"0"),i=n(s.getHours()),o=n(s.getMinutes()),a=n(s.getSeconds());for(e.textContent=`[${i}:${o}:${a}] ${t}`,this.debugOverlayEl.appendChild(e);this.debugOverlayEl.childNodes.length>52;)this.debugOverlayEl.removeChild(this.debugOverlayEl.childNodes[2])}catch(t){}}setTitle(t,e){var s,n;const i=null===(s=this.widgetElement)||void 0===s?void 0:s.querySelector("#chat-title"),o=null===(n=this.widgetElement)||void 0===n?void 0:n.querySelector("#chat-subtitle");if("telegram"===this.currentTheme){if(i&&(i.textContent=t||"Chat"),o){const t=(this.config.language||"zh").startsWith("zh");o.textContent=t?`${this.onlineCount} 人在线`:`${this.onlineCount} online`,o.style.display="block"}}else i&&(i.textContent=""),o&&(o.textContent="")}buildMessageElement(t,e){const s=St("div","chat-sdk-message");t.isOwnMessage&&s.classList.add("own");const n=!!e&&this.shouldGroupWithPrev(e,t);n&&s.classList.add("grouped");let i=null;t.isOwnMessage||(i=this.createAvatar(t),n&&i&&(i.style.visibility="hidden"));const o=!t.isOwnMessage&&!n,a="whatsapp"===this.currentTheme,r="telegram"===this.currentTheme&&t.isOwnMessage,h=this.createMessageContent(t,o,a,r);return i&&s.appendChild(i),s.appendChild(h),s}shouldGroupWithPrev(t,e){var s,n,i,o,a,r,h;if(!1===this.config.groupMessages)return!1;const c=null!==(s=this.config.groupTimeThresholdSec)&&void 0!==s?s:120,l=t.isOwnMessage===e.isOwnMessage,d=(null===(n=t.virtualUser)||void 0===n?void 0:n.id)&&(null===(i=t.virtualUser)||void 0===i?void 0:i.id)===(null===(o=e.virtualUser)||void 0===o?void 0:o.id),u=(null===(a=t.user)||void 0===a?void 0:a.id)&&(null===(r=t.user)||void 0===r?void 0:r.id)===(null===(h=e.user)||void 0===h?void 0:h.id),g=l&&(d||u||t.isOwnMessage&&e.isOwnMessage),p=Math.abs(e.timestamp.getTime()-t.timestamp.getTime())/1e3;return!!g&&p<=c}handleScrollLazyLoad(){if(this.messagesContainer.scrollTop<=20&&this.visibleStartIndex>0){const t=this.messagesContainer.scrollHeight,e=this.lazyLoadBatchSize,s=Math.max(0,this.visibleStartIndex-e),n=this.state.messages.slice(s,this.visibleStartIndex),i=document.createDocumentFragment();for(const t of n){const e=this.buildMessageElement(t);i.appendChild(e)}this.messagesContainer.insertBefore(i,this.messagesContainer.firstChild),this.visibleStartIndex=s;const o=this.messagesContainer.scrollHeight;this.messagesContainer.scrollTop+=o-t}}setLoading(t){if(t){if(!this.messagesContainer.querySelector(".chat-sdk-loading")){const t=document.createElement("div");t.className="chat-sdk-loading",t.innerHTML='\n <div class="chat-sdk-spinner"></div>\n Loading chat...\n ',this.messagesContainer.appendChild(t)}}else{const t=this.messagesContainer.querySelector(".chat-sdk-loading");null==t||t.remove()}}showJoinOverlay(){const t=St("div","chat-sdk-overlay");t.innerHTML='\n <div class="chat-sdk-join-card">\n <h3 class="chat-sdk-join-title">Join the conversation</h3>\n <p class="chat-sdk-join-description">\n Click below to join this group chat and start interacting with other members.\n </p>\n <button class="chat-sdk-join-btn" type="button">Join Chat</button>\n </div>\n ';const e=t.querySelector(".chat-sdk-join-btn");null==e||e.addEventListener("click",()=>{this.hideJoinOverlay(),this.emit("join-requested")}),this.widgetElement.appendChild(t)}hideJoinOverlay(){const t=this.widgetElement.querySelector(".chat-sdk-overlay");t&&t.remove()}addMessage(t){if(t.isOwnMessage)for(let e=this.state.messages.length-1;e>=0;e--){const s=this.state.messages[e];if(s.isOwnMessage&&s.content===t.content){if(Math.abs(t.timestamp.getTime()-s.timestamp.getTime())<=1e4)return;break}}this.state.messages.find(e=>e.id===t.id)?console.warn("Duplicate message detected and ignored:",t.id):(this.state.messages.push(t),this.renderMessage(t),t.isOwnMessage||this.incrementUnreadCount(),this.scrollToBottom(!0))}addMessagesBulk(t){if(!t||0===t.length)return;if(0===this.messagesContainer.querySelectorAll(".chat-sdk-message").length){this.state.messages=[...t].sort((t,e)=>t.timestamp.getTime()-e.timestamp.getTime());const e=this.state.messages.length,s=this.initialRenderCount;this.visibleStartIndex=Math.max(0,e-s);const n=this.state.messages.slice(this.visibleStartIndex),i=document.createDocumentFragment();let o;for(const t of n){const e=this.buildMessageElement(t,o);i.appendChild(e),o=t}this.messagesContainer.appendChild(i),setTimeout(()=>{this.scrollToBottom(!0)},0)}else{const e=new Set(this.state.messages.map(t=>t.id)),s=t.filter(t=>!e.has(t.id));if(s.length>0){this.state.messages.push(...s),this.state.messages.sort((t,e)=>t.timestamp.getTime()-e.timestamp.getTime()),this.messagesContainer.innerHTML="";const t=this.state.messages.length,e=this.initialRenderCount;this.visibleStartIndex=Math.max(0,t-e);const n=this.state.messages.slice(this.visibleStartIndex),i=document.createDocumentFragment();let o;for(const t of n){const e=this.buildMessageElement(t,o);i.appendChild(e),o=t}this.messagesContainer.appendChild(i),this.scrollToBottom()}}}reRenderAllMessages(){this.messagesContainer.innerHTML="";const t=this.state.messages.length,e=Math.max(0,t-this.initialRenderCount);this.state.messages.slice(e).forEach(t=>{this.renderMessage(t)}),this.scrollToBottom()}renderMessage(t){const e=this.state.messages.length-1,s=e>0?this.state.messages[e-1]:void 0,n=this.buildMessageElement(t,s);this.messagesContainer.appendChild(n)}createAvatar(t){var e,s,n,i;const o=St("div","chat-sdk-message-avatar");if(null===(e=t.virtualUser)||void 0===e?void 0:e.avatar)o.style.backgroundImage=`url(${t.virtualUser.avatar})`,o.style.backgroundSize="cover",o.style.backgroundPosition="center";else if(null===(s=t.user)||void 0===s?void 0:s.avatar)o.style.backgroundImage=`url(${t.user.avatar})`,o.style.backgroundSize="cover",o.style.backgroundPosition="center";else{const e=(null===(n=t.virtualUser)||void 0===n?void 0:n.username)||(null===(i=t.user)||void 0===i?void 0:i.username)||"U";o.textContent=e.charAt(0).toUpperCase()}return o}createMessageContent(t,e=!0,s=!1,n=!1){var i,o,a;const r=St("div","chat-sdk-message-content"),h=(null===(i=t.virtualUser)||void 0===i?void 0:i.displayName)||(null===(o=t.virtualUser)||void 0===o?void 0:o.username)||(null===(a=t.user)||void 0===a?void 0:a.username)||"Unknown";let c="";if("image"===t.messageType){c=`\n <div class="chat-sdk-message-image${t.failed?" failed":""}">\n <img src="${_t(t.content)}" alt="Image"\n style="max-width: 100%; height: auto; cursor: pointer;"\n data-image-url="${_t(t.content)}"\n class="chat-sdk-image-preview" />\n </div>\n `}else c="emoji"===t.messageType?`<div class="chat-sdk-message-emoji" style="font-size: 2em; line-height: 1;">${_t(t.content)}</div>`:`<p class="chat-sdk-message-text">${_t(t.content)}</p>`;const l=`${function(t,e){const s=new Date,n=Math.floor((s.getTime()-t.getTime())/1e3),i=(e||("undefined"!=typeof navigator?navigator.language:"en")).toLowerCase().startsWith("zh");if(n<60)return i?"刚刚":"just now";if(n<3600){const t=Math.floor(n/60);return i?`${t} 分钟前`:`${t}m ago`}if(n<86400){const t=Math.floor(n/3600);return i?`${t} 小时前`:`${t}h ago`}const o=new Date(s.getFullYear(),s.getMonth(),s.getDate());if(t>=new Date(o.getTime()-864e5)&&t<o){const e=t.toLocaleTimeString(i?"zh-CN":void 0,{hour:"2-digit",minute:"2-digit",hour12:!1});return i?`昨天 ${e}`:`yesterday ${e}`}return s.getTime()-t.getTime()<6048e5?t.toLocaleString(i?"zh-CN":void 0,{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit",hour12:!1}):t.toLocaleString(i?"zh-CN":void 0,{year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",hour12:!1})}(t.timestamp,this.config.language)}`,d=n?'<span class="chat-sdk-read-status">✓✓</span>':"",u=t.failed&&t.isOwnMessage?'<div class="chat-sdk-message-failed-indicator">\n <svg width="16" height="16" viewBox="0 0 16 16" fill="currentColor">\n <circle cx="8" cy="8" r="8" fill="#ff4444"/>\n <path d="M8 4v4M8 10h.01" stroke="white" stroke-width="1.5" stroke-linecap="round"/>\n </svg>\n </div>':"";r.innerHTML=s?`\n ${e&&!t.isOwnMessage?`<div class="chat-sdk-message-username">${_t(h)}</div>`:""}\n <div class="chat-sdk-message-bubble">\n ${c}\n <div class="chat-sdk-message-time-inside">${l}${d?" "+d:""}</div>\n </div>\n ${u}\n `:`\n ${e&&!t.isOwnMessage?`<div class="chat-sdk-message-username">${_t(h)}</div>`:""}\n <div class="chat-sdk-message-bubble">\n ${c}\n </div>\n <div class="chat-sdk-message-time">${l}${d?" "+d:""}</div>\n ${u}\n `;const g=r.querySelector(".chat-sdk-image-preview");return g&&g.addEventListener("click",t=>{t.preventDefault();const e=t.target.getAttribute("data-image-url");e&&this.showImagePreview(e)}),r}scrollToBottom(t=!1){const e=this.messagesContainer;if(t)return void It(e);e.scrollTop+e.clientHeight>=e.scrollHeight-40&&It(e)}setupImageViewer(){this.messagesContainer.addEventListener("click",t=>{const e=t.target;if(e.classList.contains("chat-sdk-image-preview")){const t=e.getAttribute("data-image-url");t&&this.openImageViewer(t)}})}openImageViewer(t){const e=St("div","chat-sdk-image-modal");e.innerHTML=`\n <div class="chat-sdk-image-backdrop">\n <div class="chat-sdk-image-container">\n <button class="chat-sdk-image-close" aria-label="Close">\n <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">\n <line x1="18" y1="6" x2="6" y2="18"></line>\n <line x1="6" y1="6" x2="18" y2="18"></line>\n </svg>\n </button>\n <img class="chat-sdk-image-full" src="${_t(t)}" alt="Full size image" />\n </div>\n </div>\n `,this.shadowRoot.appendChild(e);const s=e.querySelector(".chat-sdk-image-close"),n=e.querySelector(".chat-sdk-image-backdrop"),i=()=>{e.remove()};null==s||s.addEventListener("click",i),null==n||n.addEventListener("click",t=>{t.target===n&&i()});const o=t=>{"Escape"===t.key&&(i(),document.removeEventListener("keydown",o))};document.addEventListener("keydown",o),requestAnimationFrame(()=>{e.classList.add("chat-sdk-image-modal-open")})}showImagePreview(t){const e=St("div","chat-sdk-image-modal");e.innerHTML=`\n <div class="chat-sdk-image-modal-overlay">\n <div class="chat-sdk-image-modal-content">\n <button class="chat-sdk-image-modal-close">&times;</button>\n <img src="${_t(t)}" alt="Image Preview" class="chat-sdk-image-modal-img" />\n </div>\n </div>\n `,this.widgetElement.appendChild(e);const s=e.querySelector(".chat-sdk-image-modal-close"),n=e.querySelector(".chat-sdk-image-modal-overlay"),i=()=>{e.remove()};null==s||s.addEventListener("click",i),null==n||n.addEventListener("click",t=>{t.target===n&&i()});const o=t=>{"Escape"===t.key&&(i(),document.removeEventListener("keydown",o))};document.addEventListener("keydown",o)}setJoined(t){this.state.isJoined=t,this.handleInputChange()}setUITemplate(t){this.currentTheme=t,this.config.uiTemplate=t,this.widgetElement.classList.remove("whatsapp-theme","telegram-theme","dark"),this.widgetElement.classList.add(`${t}-theme`),"telegram"===t&&this.isDarkMode&&this.widgetElement.classList.add("dark"),this.updateThemeStyles(),this.reRenderAllMessages()}setTheme(t){this.isDarkMode="dark"===t,this.config.theme=t,"telegram"===this.currentTheme&&(this.isDarkMode?this.widgetElement.classList.add("dark"):this.widgetElement.classList.remove("dark"),this.updateThemeStyles())}setCustomColors(t){this.customColors={...this.customColors,...t},this.config.primaryColor=t.primary,this.config.backgroundColor=t.background,this.updateThemeStyles()}updateThemeStyles(){const t=this.currentTheme,e=this.isDarkMode&&"telegram"===t,s=this.shadowRoot||document.documentElement;"whatsapp"===t?(this.setCSSProperty(s,"--chat-primary-color",this.customColors.primary||"#25D366"),this.setCSSProperty(s,"--chat-background-color",this.customColors.background||"#ECE5DD"),this.setCSSProperty(s,"--chat-message-own-bg","#DCF8C6"),this.setCSSProperty(s,"--chat-message-other-bg","#FFFFFF"),this.setCSSProperty(s,"--chat-header-bg","linear-gradient(135deg, #075e54 0%, #128c7e 100%)")):"telegram"===t&&(e?(this.setCSSProperty(s,"--chat-primary-color",this.customColors.primary||"#4FC3F7"),this.setCSSProperty(s,"--chat-background-color",this.customColors.background||"#212121"),this.setCSSProperty(s,"--chat-message-own-bg","linear-gradient(135deg, #4fc3f7 0%, #29b6f6 100%)"),this.setCSSProperty(s,"--chat-message-other-bg","#2F2F2F"),this.setCSSProperty(s,"--chat-header-bg","linear-gradient(135deg, #1976d2 0%, #1565c0 100%)"),this.setCSSProperty(s,"--chat-text-color","#FFFFFF")):(this.setCSSProperty(s,"--chat-primary-color",this.customColors.primary||"#2481CC"),this.setCSSProperty(s,"--chat-background-color",this.customColors.background||"#FFFFFF"),this.setCSSProperty(s,"--chat-message-own-bg","linear-gradient(135deg, #4fc3f7 0%, #29b6f6 100%)"),this.setCSSProperty(s,"--chat-message-other-bg","#F1F1F1"),this.setCSSProperty(s,"--chat-header-bg","linear-gradient(135deg, #2481cc 0%, #1c7cd6 100%)"),this.setCSSProperty(s,"--chat-text-color","#000000")))}setCSSProperty(t,e,s){if(t instanceof ShadowRoot){const n=t.querySelector("style");if(n){const t=n.textContent||"",i=new RegExp(`${e}\\s*:\\s*[^;]+;`,"g"),o=`${e}: ${s};`;if(i.test(t))n.textContent=t.replace(i,o);else{const e=/:host\s*\{([^}]*)\}/;e.test(t)?n.textContent=t.replace(e,(t,e)=>`:host { ${e} ${o} }`):n.textContent=`:host { ${o} }\n${t}`}}}else t.style.setProperty(e,s)}getState(){return{...this.state}}getDefaultStyles(){return"\n :host {\n --chat-primary-color: #25D366;\n --chat-background-color: #ECE5DD;\n --chat-message-own-bg: #DCF8C6;\n --chat-message-other-bg: #FFFFFF;\n --chat-header-bg: linear-gradient(135deg, #075e54 0%, #128c7e 100%);\n --chat-text-color: #333333;\n --chat-border-radius-message: 18px;\n --chat-border-radius-input: 25px;\n }\n\n .chat-sdk-container {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;\n font-size: 14px;\n line-height: 1.5;\n color: var(--chat-text-color);\n background: var(--chat-background-color);\n border-radius: 12px;\n box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);\n overflow: hidden;\n display: flex;\n flex-direction: column;\n position: relative;\n max-width: 100%;\n max-height: 100%;\n }\n\n .chat-sdk-container * {\n box-sizing: border-box;\n }\n\n /* WhatsApp Theme */\n .chat-sdk-container.whatsapp-theme .chat-sdk-header {\n background: linear-gradient(135deg, #075e54 0%, #128c7e 100%);\n color: white;\n padding: 12px 16px;\n display: flex;\n align-items: center;\n justify-content: flex-end;\n min-height: 60px;\n box-shadow: 0 1px 3px rgba(0,0,0,0.12);\n }\n .chat-sdk-container.whatsapp-theme .chat-sdk-header-left { display: none; }\n\n .chat-sdk-container.whatsapp-theme .chat-sdk-messages {\n background-color: #ece5dd;\n background-image: url(\"data:image/svg+xml,%3Csvg width='60' height='60' viewBox='0 0 60 60' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cg fill='%23e5ddd5' fill-opacity='0.08'%3E%3Cpath d='M36 34v-4h-2v4h-4v2h4v4h2v-4h4v-2h-4zm0-30V0h-2v4h-4v2h4v4h2V6h4V4h-4zM6 34v-4H4v4H0v2h4v4h2v-4h4v-2H6zM6 4V0H4v4H0v2h4v4h2V6h4V4H6z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E\");\n }\n\n .chat-sdk-container.whatsapp-theme {\n --chat-primary-color: #25D366;\n --chat-background-color: #ECE5DD;\n --chat-message-own-bg: #DCF8C6;\n --chat-message-other-bg: #FFFFFF;\n --chat-header-bg: linear-gradient(135deg, #075e54 0%, #128c7e 100%);\n --chat-text-color: #303030;\n --chat-border-radius-message: 18px;\n --chat-border-radius-input: 25px;\n }\n\n .chat-sdk-container.whatsapp-theme .chat-sdk-message.own .chat-sdk-message-bubble {\n background: var(--chat-message-own-bg);\n color: var(--chat-text-color);\n border-radius: var(--chat-border-radius-message) var(--chat-border-radius-message) 4px var(--chat-border-radius-message);\n }\n\n .chat-sdk-container.whatsapp-theme .chat-sdk-message:not(.own) .chat-sdk-message-bubble {\n background: var(--chat-message-other-bg);\n color: var(--chat-text-color);\n border-radius: var(--chat-border-radius-message) var(--chat-border-radius-message) var(--chat-border-radius-message) 4px;\n }\n\n /* WhatsApp input + details */\n .chat-sdk-container.whatsapp-theme .chat-sdk-message-avatar {\n width: 28px;\n height: 28px;\n }\n .chat-sdk-container.whatsapp-theme .chat-sdk-message-content {\n max-width: 70%;\n }\n .chat-sdk-container.whatsapp-theme .chat-sdk-message-bubble {\n box-shadow: 0 1px 1px rgba(0,0,0,0.06);\n }\n .chat-sdk-container.whatsapp-theme .chat-sdk-input-area {\n background: #f0f2f5;\n border-top: none;\n }\n .chat-sdk-container.whatsapp-theme .chat-sdk-input {\n background: #fff;\n border: none;\n border-radius: 22px;\n padding: 10px 14px;\n box-shadow: inset 0 1px 0 rgba(0,0,0,0.02);\n }\n .chat-sdk-container.whatsapp-theme .chat-sdk-send-btn {\n background: #25D366;\n box-shadow: 0 2px 4px rgba(0,0,0,0.12);\n }\n\n\n /* Telegram Theme */\n .chat-sdk-container.telegram-theme {\n --chat-primary-color: #2481CC;\n --chat-background-color: #FFFFFF;\n --chat-message-own-bg: linear-gradient(135deg, #4fc3f7 0%, #29b6f6 100%);\n --chat-message-other-bg: #F1F1F1;\n --chat-header-bg: linear-gradient(135deg, #2481cc 0%, #1c7cd6 100%);\n --chat-text-color: #000000;\n --chat-border-radius-message: 12px;\n --chat-border-radius-input: 12px;\n\n /* Telegram input + details */\n .chat-sdk-container.telegram-theme .chat-sdk-message-content {\n max-width: 75%;\n }\n .chat-sdk-container.telegram-theme .chat-sdk-message-bubble {\n box-shadow: 0 1px 1px rgba(0,0,0,0.06);\n }\n .chat-sdk-container.telegram-theme .chat-sdk-input-area {\n background: #ffffff;\n border-top: 1px solid #e6e6e6;\n }\n .chat-sdk-container.telegram-theme .chat-sdk-input {\n background: #fff;\n border: 1px solid #cfd6dd;\n border-radius: 12px;\n padding: 9px 14px;\n }\n .chat-sdk-container.telegram-theme .chat-sdk-send-btn {\n background: #2481CC;\n border-radius: 10px;\n width: 38px;\n height: 36px;\n box-shadow: none;\n }\n /* Telegram dark */\n .chat-sdk-container.telegram-theme.dark .chat-sdk-input-area {\n background: #1f1f1f;\n border-top: 1px solid #2a2a2a;\n }\n .chat-sdk-container.telegram-theme.dark .chat-sdk-input {\n background: #2b2b2b;\n color: #e0e0e0;\n border-color: #444;\n }\n .chat-sdk-container.telegram-theme.dark .chat-sdk-send-btn {\n background: #1976d2;\n }\n\n\n .chat-sdk-container.telegram-theme .chat-sdk-header {\n background: var(--chat-header-bg);\n color: white;\n padding: 12px 16px;\n display: flex;\n align-items: center;\n justify-content: space-between;\n min-height: 60px;\n box-shadow: 0 1px 3px rgba(0,0,0,0.12);\n }\n\n .chat-sdk-container.telegram-theme .chat-sdk-messages {\n background-color: var(--chat-background-color);\n }\n\n .chat-sdk-container.telegram-theme .chat-sdk-message.own .chat-sdk-message-bubble {\n background: var(--chat-message-own-bg);\n color: white;\n border-radius: var(--chat-border-radius-message) var(--chat-border-radius-message) 4px var(--chat-border-radius-message);\n }\n\n .chat-sdk-container.telegram-theme .chat-sdk-message:not(.own) .chat-sdk-message-bubble {\n background: var(--chat-message-other-bg);\n color: var(--chat-text-color);\n border-radius: var(--chat-border-radius-message) var(--chat-border-radius-message) var(--chat-border-radius-message) 4px;\n }\n\n /* Telegram Dark Theme */\n .chat-sdk-container.telegram-theme.dark {\n --chat-background-color: #212121;\n --chat-message-other-bg: #2F2F2F;\n --chat-header-bg: linear-gradient(135deg, #1976d2 0%, #1565c0 100%);\n --chat-text-color: #FFFFFF;\n }\n\n /* Default header (fallback) */\n .chat-sdk-header {\n background: var(--chat-header-bg);\n color: white;\n padding: 12px 16px;\n display: flex;\n align-items: center;\n justify-content: space-between;\n min-height: 60px;\n }\n\n .chat-sdk-header-left { display: flex; flex-direction: column; gap: 2px; }\n .chat-sdk-title { font-size: 15px; font-weight: 600; }\n .chat-sdk-subtitle { font-size: 12px; opacity: 0.9; }\n\n .chat-sdk-close-btn {\n background: none;\n border: none;\n color: white;\n cursor: pointer;\n padding: 8px;\n border-radius: 50%;\n opacity: 0.8;\n transition: all 0.2s;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n }\n\n .chat-sdk-close-btn:hover {\n opacity: 1;\n background: rgba(255, 255, 255, 0.1);\n }\n\n .chat-sdk-messages {\n flex: 1;\n overflow-y: auto;\n padding: 16px;\n background: var(--chat-background-color);\n min-height: 0; /* allow flex to use full height */\n }\n\n .chat-sdk-message {\n margin-bottom: 12px;\n display: flex;\n align-items: flex-end;\n gap: 8px;\n }\n\n .chat-sdk-message.own {\n flex-direction: row-reverse;\n }\n\n .chat-sdk-message-avatar {\n width: 32px;\n height: 32px;\n border-radius: 50%;\n background: #ddd;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 12px;\n font-weight: 600;\n color: #666;\n flex-shrink: 0;\n }\n\n .chat-sdk-message-content {\n max-width: 70%;\n position: relative;\n }\n\n .chat-sdk-message-bubble {\n background: var(--chat-message-other-bg);\n color: var(--chat-text-color);\n padding: 8px 12px;\n border-radius: var(--chat-border-radius-message);\n position: relative;\n word-wrap: break-word;\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);\n }\n\n .chat-sdk-message.own .chat-sdk-message-bubble {\n background: var(--chat-message-own-bg);\n color: white;\n }\n\n .chat-sdk-message-username {\n font-size: 11px;\n color: #666;\n margin-bottom: 2px;\n font-weight: 600;\n }\n\n .chat-sdk-message-text {\n margin: 0;\n line-height: 1.4;\n }\n\n .chat-sdk-message-time {\n font-size: 10px;\n color: #999;\n margin-top: 4px;\n text-align: right;\n }\n\n /* Message grouping */\n .chat-sdk-message.grouped {\n margin-top: 4px;\n }\n .chat-sdk-message.grouped .chat-sdk-message-username { display: none; }\n .chat-sdk-message.grouped .chat-sdk-message-avatar { visibility: hidden; }\n\n /* WhatsApp: time inside bubble */\n .chat-sdk-container.whatsapp-theme .chat-sdk-message-bubble {\n position: relative;\n padding-right: 44px;\n padding-bottom: 16px;\n }\n .chat-sdk-container.whatsapp-theme .chat-sdk-message-time-inside {\n position: absolute;\n right: 8px;\n bottom: 4px;\n font-size: 11px;\n color: rgba(0,0,0,0.55);\n }\n\n /* Telegram: read status */\n .chat-sdk-container.telegram-theme .chat-sdk-message-time {\n display: flex;\n align-items: center;\n justify-content: flex-end;\n gap: 6px;\n }\n .chat-sdk-container.telegram-theme .chat-sdk-message.own .chat-sdk-read-status {\n font-size: 12px;\n color: var(--chat-primary-color);\n line-height: 1;\n }\n\n /* Theme-specific image radii */\n .chat-sdk-container.whatsapp-theme .chat-sdk-message-image img { border-radius: 12px; }\n .chat-sdk-container.telegram-theme .chat-sdk-message-image img { border-radius: 6px; }\n\n\n .chat-sdk-input-area {\n padding: 12px 16px;\n background: white;\n border-top: 1px solid #e0e0e0;\n display: flex;\n align-items: center;\n gap: 8px;\n }\n\n\n .chat-sdk-icon-btn {\n background: transparent;\n border: none;\n width: 32px;\n height: 32px;\n border-radius: 6px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: #666;\n }\n .chat-sdk-icon-btn:hover { background: rgba(0,0,0,0.06); }\n\n .chat-sdk-emoji-picker {\n position: absolute;\n left: 12px;\n bottom: 64px;\n background: #fff;\n border: 1px solid #e0e0e0;\n border-radius: 8px;\n box-shadow: 0 6px 16px rgba(0,0,0,0.12);\n padding: 6px;\n z-index: 5;\n }\n .chat-sdk-emoji-grid {\n display: grid;\n grid-template-columns: repeat(5, 28px);\n gap: 6px;\n }\n\n /* Failed message styles - Telegram style */\n .chat-sdk-message-failed-indicator {\n display: inline-flex;\n align-items: center;\n margin-left: 6px;\n color: #ff4444;\n cursor: pointer;\n }\n .chat-sdk-message-failed-indicator svg {\n width: 16px;\n height: 16px;\n }\n .chat-sdk-message.own .chat-sdk-message-content {\n display: flex;\n align-items: flex-end;\n gap: 6px;\n }\n .chat-sdk-message.own .chat-sdk-message-bubble {\n flex: 1;\n }\n .chat-sdk-emoji-item {\n background: none;\n border: none;\n font-size: 20px;\n line-height: 1;\n cursor: pointer;\n width: 28px;\n height: 28px;\n border-radius: 4px;\n }\n .chat-sdk-emoji-item:hover { background: #f3f4f6; }\n\n\n .chat-sdk-input {\n flex: 1;\n border: 1px solid #ddd;\n border-radius: var(--chat-border-radius-input);\n padding: 8px 16px;\n font-size: 14px;\n outline: none;\n resize: none;\n min-height: 36px;\n max-height: 100px;\n }\n\n .chat-sdk-input:focus {\n border-color: var(--chat-primary-color);\n }\n\n .chat-sdk-send-btn {\n background: var(--chat-primary-color);\n color: white;\n border: none;\n border-radius: 50%;\n width: 36px;\n height: 36px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: background-color 0.2s;\n }\n\n .chat-sdk-send-btn:hover {\n background: #064e45;\n }\n\n .chat-sdk-send-btn:disabled {\n background: #ccc;\n cursor: not-allowed;\n }\n\n .chat-sdk-overlay {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 10;\n }\n\n .chat-sdk-join-card {\n background: white;\n border-radius: 12px;\n padding: 24px;\n max-width: 300px;\n margin: 16px;\n text-align: center;\n }\n\n .chat-sdk-join-title {\n font-size: 18px;\n font-weight: 600;\n margin: 0 0 8px 0;\n color: #333;\n }\n\n .chat-sdk-join-description {\n font-size: 14px;\n color: #666;\n margin: 0 0 20px 0;\n line-height: 1.4;\n }\n\n .chat-sdk-join-btn {\n background: #075e54;\n color: white;\n border: none;\n border-radius: 8px;\n padding: 12px 24px;\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n transition: background-color 0.2s;\n width: 100%;\n }\n\n .chat-sdk-join-btn:hover {\n background: #064e45;\n }\n\n .chat-sdk-loading {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 40px;\n color: #666;\n }\n\n .chat-sdk-spinner {\n width: 20px;\n height: 20px;\n border: 2px solid #e0e0e0;\n border-top: 2px solid #075e54;\n border-radius: 50%;\n animation: chat-sdk-spin 1s linear infinite;\n margin-right: 8px;\n }\n\n @keyframes chat-sdk-spin {\n 0% { transform: rotate(0deg); }\n 100% { transform: rotate(360deg); }\n }\n\n .chat-sdk-container.dark {\n background: #1f1f1f;\n color: #e0e0e0;\n }\n\n .chat-sdk-container.dark .chat-sdk-header {\n background: #2d2d2d;\n }\n\n .chat-sdk-container.dark .chat-sdk-messages {\n background: #0d1117;\n }\n\n .chat-sdk-container.dark .chat-sdk-message-bubble {\n background: #2d2d2d;\n color: #e0e0e0;\n }\n\n .chat-sdk-container.dark .chat-sdk-message.own .chat-sdk-message-bubble {\n background: #0969da;\n color: white;\n }\n\n /* Image Modal Viewer */\n .chat-sdk-image-modal {\n position: fixed;\n top: 0; left: 0; right: 0; bottom: 0;\n z-index: 9999;\n opacity: 0;\n visibility: hidden;\n transition: opacity 0.2s ease, visibility 0.2s ease;\n }\n\n .chat-sdk-image-modal-open {\n opacity: 1;\n visibility: visible;\n }\n\n .chat-sdk-image-backdrop {\n position: absolute;\n top: 0; left: 0; right: 0; bottom: 0;\n background: rgba(0, 0, 0, 0.9);\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 20px;\n }\n\n .chat-sdk-image-container {\n position: relative;\n max-width: 90vw;\n max-height: 90vh;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n\n .chat-sdk-image-close {\n position: absolute;\n top: -50px;\n right: 0;\n background: rgba(255, 255, 255, 0.1);\n border: none;\n border-radius: 50%;\n width: 40px;\n height: 40px;\n color: white;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: background-color 0.2s;\n z-index: 1;\n }\n\n .chat-sdk-image-close:hover {\n background: rgba(255, 255, 255, 0.2);\n }\n\n .chat-sdk-image-full {\n max-width: 100%;\n max-height: 100%;\n object-fit: contain;\n border-radius: 8px;\n box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);\n }\n\n /* Responsive Design */\n @media (max-width: 640px) {\n .chat-sdk-container {\n border-radius: 0;\n height: 100vh;\n max-height: 100vh;\n }\n\n .chat-sdk-message-content {\n max-width: 85%;\n }\n\n .chat-sdk-message-bubble {\n font-size: 14px;\n padding: 8px 12px;\n }\n\n .chat-sdk-input {\n font-size: 16px; /* Prevent zoom on iOS */\n padding: 10px 14px;\n }\n\n .chat-sdk-header {\n padding: 8px 12px;\n min-height: 50px;\n }\n\n .chat-sdk-message-avatar {\n width: 28px;\n height: 28px;\n font-size: 11px;\n }\n }\n\n @media (min-width: 1024px) {\n .chat-sdk-message-content {\n max-width: 60%;\n }\n\n .chat-sdk-send-btn:hover:not(:disabled) {\n transform: scale(1.05);\n transition: all 0.2s ease;\n }\n }\n\n "}startSimulation(){this.simulator.start()}stopSimulation(){this.simulator.stop()}pauseSimulation(){this.simulator.pause()}resumeSimulation(){this.simulator.resume()}async sendMessage(t,e="text"){await this.simulator.sendMessage(t,e)}get isSimulationRunning(){return this.state.isSimulationRunning}get isSimulationPaused(){return this.state.isSimulationPaused}get simulationEnded(){return this.state.simulationEnded}get messageCount(){return this.state.displayedMessageCount}get messages(){return[...this.state.messages]}async reinitializeLanguage(t){this.config.language=t,this.setLoading(!0),this.messagesContainer.innerHTML="",this.state.messages=[],this.state.displayedMessageCount=0,this.state.unreadCount=0,this.updateUnreadBadge();try{this.simulator.clearCachedProgress()}catch(t){}try{this.simulator.destroy()}catch(t){}this.simulator=new Mt(this.config,this.apiClient),this.setupSimulatorEvents(),await this.initializeSimulation()}destroy(){if(this.simulator.destroy(),this.shadowRoot)try{for(;this.shadowRoot.firstChild;)this.shadowRoot.removeChild(this.shadowRoot.firstChild)}catch(t){}this.state.isOpen=!1,this.removeAllListeners()}clearMessages(){this.state.messages=[],this.state.displayedMessageCount=0,this.state.unreadCount=0,this.messagesContainer.innerHTML="",this.updateUnreadBadge()}rerender(){this.reRenderAllMessages()}getMessageCount(){return this.state.displayedMessageCount}isOpen(){return this.state.isOpen}updateLanguageElements(t){var e,s,n;const i=t.startsWith("zh"),o=null===(e=this.widgetElement)||void 0===e?void 0:e.querySelector("#chat-input");o&&(o.placeholder=i?"输入消息...":"Type a message...");const a=null===(s=this.widgetElement)||void 0===s?void 0:s.querySelector(".send-button");a&&a.textContent&&(a.textContent=i?"发送":"Send");const r=i?"条消息":"messages",h=this.getMessageCount(),c=(null===(n=this.state.currentProject)||void 0===n?void 0:n.name)||"Chat";this.setTitle(c,`${h} ${r}`)}}const Lt={en:"English",zh:"Chinese (Simplified)",es:"Spanish",ar:"Arabic",pt:"Portuguese",ru:"Russian",ja:"Japanese",fr:"French",de:"German",hi:"Hindi",it:"Italian",ko:"Korean",tr:"Turkish",pl:"Polish",nl:"Dutch",th:"Thai",vi:"Vietnamese",id:"Indonesian",uk:"Ukrainian",fa:"Persian (Farsi)","zh-TW":"Chinese (Traditional)","pt-BR":"Portuguese (Brazil)"},Ot={"en-US":"en","en-GB":"en","en-CA":"en","en-AU":"en","en-IN":"en","zh-CN":"zh","zh-Hans":"zh","zh-Hant":"zh-TW","zh-TW":"zh-TW","zh-HK":"zh-TW","zh-MO":"zh-TW","es-ES":"es","es-MX":"es","es-AR":"es","es-CO":"es","es-CL":"es","ar-SA":"ar","ar-EG":"ar","ar-AE":"ar","ar-MA":"ar","pt-BR":"pt-BR","pt-PT":"pt","ru-RU":"ru","ru-UA":"ru","ja-JP":"ja","fr-FR":"fr","fr-CA":"fr","fr-BE":"fr","de-DE":"de","de-AT":"de","de-CH":"de","hi-IN":"hi","it-IT":"it","ko-KR":"ko","tr-TR":"tr","pl-PL":"pl","nl-NL":"nl","nl-BE":"nl","th-TH":"th","vi-VN":"vi","id-ID":"id","uk-UA":"uk","fa-IR":"fa","fa-AF":"fa",zh_CN:"zh",zh_TW:"zh-TW",en_US:"en",en_GB:"en",fr_FR:"fr",de_DE:"de",es_ES:"es",ja_JP:"ja",ko_KR:"ko",pt_BR:"pt-BR",pt_PT:"pt",ru_RU:"ru",ar_SA:"ar",hi_IN:"hi",it_IT:"it",tr_TR:"tr",pl_PL:"pl",nl_NL:"nl",th_TH:"th",vi_VN:"vi",id_ID:"id",uk_UA:"uk",fa_IR:"fa",chinese:"zh",english:"en",spanish:"es",arabic:"ar",portuguese:"pt",russian:"ru",japanese:"ja",french:"fr",german:"de",hindi:"hi",italian:"it",korean:"ko",turkish:"tr",polish:"pl",dutch:"nl",thai:"th",vietnamese:"vi",indonesian:"id",ukrainian:"uk",persian:"fa",farsi:"fa",ZH:"zh",EN:"en",ES:"es",AR:"ar",PT:"pt",RU:"ru",JA:"ja",FR:"fr",DE:"de",HI:"hi",IT:"it",KO:"ko",TR:"tr",PL:"pl",NL:"nl",TH:"th",VI:"vi",ID:"id",UK:"uk",FA:"fa"};function jt(t){if(!t||"string"!=typeof t)return"en";const e=t.trim();if(!e)return"en";if(Lt[e])return e;if(Ot[e])return Ot[e];const s=e.toLowerCase();if(Lt[s])return s;if(Ot[s])return Ot[s];const n=s.split(/[-_]/)[0];if(n&&Lt[n])return n;if("zh"===n||e.toLowerCase().includes("chinese")){return["tw","hk","mo","hant","traditional"].some(t=>s.includes(t))?"zh-TW":"zh"}return console.warn(`[ChatSDK] Unsupported language code: "${t}", falling back to English`),"en"}function At(t){const e=jt(t);return"zh"===e||"zh-TW"===e}class Dt extends e{constructor(t){if(super(),this.isInitialized=!1,console.log("[ChatSDK] Initializing with config:",{projectId:t.projectId,apiBaseUrl:t.apiBaseUrl,container:"string"==typeof t.container?t.container:"[HTMLElement]"}),this.validateConfig(t),this.config={...this.getDefaultConfig(),...t},console.log("[ChatSDK] Final config:",{projectId:this.config.projectId,apiBaseUrl:this.config.apiBaseUrl,mode:this.config.mode}),this.config.language){const t=jt(this.config.language);t!==this.config.language&&(console.log(`[ChatSDK] Language normalized: "${this.config.language}" -> "${t}"`),this.config.language=t)}this.config.mode="floating",this.userId=this.config.userId||`sdk-user-${Math.random().toString(36).substr(2,9)}`,this.username=this.config.username||`User${Math.floor(1e3*Math.random())}`,this.apiClient=new s(this.config),this.socketClient=new Et(this.config),this.widget=new Rt(this.config),this.setupEventListeners(),this.initialize()}validateConfig(e){if(!e.container)throw new t("Container is required","INVALID_CONFIG");e.projectId||(console.warn("[ChatSDK] Project ID is missing, using default project"),e.projectId="default-project"),e.apiBaseUrl||(console.warn("[ChatSDK] API Base URL is missing, using current origin"),e.apiBaseUrl=window.location.origin)}getDefaultConfig(){return{language:"en",theme:"light",uiTemplate:"whatsapp",width:"400px",height:"600px",position:"relative",zIndex:2147483e3,mode:"floating",floatingButton:{position:"bottom-right",offset:{bottom:20,right:20},icon:"chat",zIndex:2147483e3},autoJoin:!1,showAvatars:!0,showUsernames:!0,allowInput:!0,initialRenderCount:10,lazyLoadBatchSize:20,groupMessages:!0,groupTimeThresholdSec:120,disableEscClose:!1,preventCloseWhileInputFocused:!0,forceTelegramCompat:!1,enableDebugOverlay:!1}}async initialize(){var t,e,s;try{await this.loadProject();const n=At(this.config.language||"en")?"条消息":"messages";this.widget.setTitle((null===(t=this.currentProject)||void 0===t?void 0:t.name)||"Chat",`0 ${n}`),this.widget.setLoading(!1),this.joinChat(),this.isInitialized=!0,this.emit("ready"),null===(s=(e=this.config).onReady)||void 0===s||s.call(e)}catch(t){this.handleError(t)}}async loadProject(){try{const t=await this.apiClient.getProject(this.config.projectId);this.currentProject=t.project,this.config.templateId?await this.loadTemplate(this.config.templateId):this.currentProject.templates&&this.currentProject.templates.length>0&&await this.loadTemplate(this.currentProject.templates[0].id)}catch(e){throw new t("Failed to load project data","PROJECT_LOAD_ERROR",e)}}async loadTemplate(e){try{const t=await this.apiClient.getTemplate(e,this.config.language);this.currentTemplate=t.template}catch(e){throw new t("Failed to load template","TEMPLATE_LOAD_ERROR",e)}}setupEventListeners(){this.widget.on("ready",()=>{this.emit("widget-ready")}),this.widget.on("open",()=>{var t,e;this.emit("open"),null===(e=(t=this.config).onOpen)||void 0===e||e.call(t)}),this.widget.on("close",()=>{var t,e;this.emit("close"),null===(e=(t=this.config).onClose)||void 0===e||e.call(t)}),this.widget.on("join-requested",()=>{this.joinChat()}),this.widget.on("message",t=>{this.handleUserMessage(t)}),this.widget.on("typing",()=>{this.socketClient.isConnected()&&this.socketClient.startTyping(this.config.projectId,this.userId)}),this.socketClient.on("connected",()=>{this.emit("connected")}),this.socketClient.on("disconnected",()=>{this.emit("disconnected")}),this.socketClient.on("user-joined",t=>{this.emit("user-joined",t)}),this.socketClient.on("user-left",t=>{this.emit("user-left",t)}),this.socketClient.on("new-message",t=>{var e,s;this.widget.addMessage(t),this.emit("message",t),null===(s=(e=this.config).onMessage)||void 0===s||s.call(e,t)}),this.socketClient.on("user-typing",t=>{}),this.socketClient.on("user-stopped-typing",t=>{}),this.socketClient.on("error",t=>{this.handleError(t)})}async handleUserMessage(t){var e,s;try{this.socketClient.isConnected()&&this.socketClient.sendMessage(this.config.projectId,this.userId,t.content,t.messageType),await this.apiClient.sendMessage(this.config.projectId,this.userId,t.content,t.messageType),this.emit("user-message",t),null===(s=(e=this.config).onUserMessage)||void 0===s||s.call(e,t)}catch(t){this.handleError(t)}}handleError(e){var s,n;const i=e instanceof t?e:new t("Unknown error","UNKNOWN_ERROR",e);this.emit("error",i),null===(n=(s=this.config).onError)||void 0===n||n.call(s,i)}open(){this.widget.open()}close(){this.widget.close()}destroy(){this.socketClient.disconnect(),this.widget.destroy(),this.removeAllListeners()}async setLanguage(t){var e,s;const n=jt(t),i=this.config.language;if(n!==t&&console.log(`[ChatSDK] Language normalized: "${t}" -> "${n}"`),n!==i){console.log(`[ChatSDK] Changing language from "${i}" to "${n}"`),this.config.language=n;try{const t=this.widget.isOpen();await this.reinitializeWithNewLanguage(),t&&this.widget.open(),this.updateUILanguage(),this.emit("language-change",n),null===(s=(e=this.config).onLanguageChange)||void 0===s||s.call(e,n),console.log(`[ChatSDK] Language successfully changed to "${n}"`)}catch(t){throw console.error(`[ChatSDK] Failed to change language to "${n}":`,t),this.config.language=i,t}}else console.log(`[ChatSDK] Language already set to "${n}", skipping update`)}async reinitializeWithNewLanguage(){try{await this.loadProject(),this.currentTemplate&&await this.loadTemplate(this.currentTemplate.id),await this.widget.reinitializeLanguage(this.config.language||"en")}catch(t){throw console.error("[ChatSDK] Failed to reinitialize with new language:",t),t}}updateUILanguage(){var t;const e=At(this.config.language||"en")?"条消息":"messages",s=this.widget.getMessageCount();this.widget.setTitle((null===(t=this.currentProject)||void 0===t?void 0:t.name)||"Chat",`${s} ${e}`),this.widget.updateLanguageElements(this.config.language||"en")}setTheme(t){var e,s;this.config.theme=t,this.widget.setTheme("auto"===t?"light":t),this.emit("theme-change",t),null===(s=(e=this.config).onThemeChange)||void 0===s||s.call(e,t)}setUITemplate(t){var e,s;this.config.uiTemplate=t,this.widget.setUITemplate(t),this.emit("template-change",t),null===(s=(e=this.config).onTemplateChange)||void 0===s||s.call(e,t)}setCustomColors(t){var e,s;this.config.primaryColor=null!==(e=t.primary)&&void 0!==e?e:this.config.primaryColor,this.config.backgroundColor=null!==(s=t.background)&&void 0!==s?s:this.config.backgroundColor,this.widget.setCustomColors(t)}setTemplate(t){this.config.templateId=t,this.loadTemplate(t)}joinChat(){var t,e;this.widget.hideJoinOverlay(),this.emit("join",{userId:this.userId,username:this.username}),null===(e=(t=this.config).onJoin)||void 0===e||e.call(t,{userId:this.userId,username:this.username})}leaveChat(){this.widget.stopSimulation()}sendMessage(t,e="text"){return this.widget.sendMessage(t,e)}startSimulation(){this.widget.startSimulation()}stopSimulation(){this.widget.stopSimulation()}pauseSimulation(){this.widget.pauseSimulation()}resumeSimulation(){this.widget.resumeSimulation()}isOpen(){return this.widget.isSimulationRunning}isJoined(){return!0}getConfig(){return{...this.config}}getMessages(){return this.widget.messages}get isSimulationRunning(){return this.widget.isSimulationRunning}get isSimulationPaused(){return this.widget.isSimulationPaused}get simulationEnded(){return this.widget.simulationEnded}get messageCount(){return this.widget.messageCount}}function Pt(t){return new Dt(t)}var Bt={init:Pt,ChatSDK:Dt,ChatSDKError:t};"undefined"!=typeof window&&(window.ChatSDK={init:Pt,ChatSDK:Dt,ChatSDKError:t});export{t as ChatSDKError,Bt as default,Pt as init};