UNPKG

@ticketping/chat-widget

Version:

Customer support chat widget for Ticketping - Intercom-like experience with real-time messaging

7 lines 61.7 kB
var TicketpingChat=function(){"use strict";var e=Object.defineProperty,t=Object.defineProperties,s=Object.getOwnPropertyDescriptors,i=Object.getOwnPropertySymbols,n=Object.prototype.hasOwnProperty,o=Object.prototype.propertyIsEnumerable,a=(t,s,i)=>s in t?e(t,s,{enumerable:!0,configurable:!0,writable:!0,value:i}):t[s]=i,r=(e,t)=>{for(var s in t||(t={}))n.call(t,s)&&a(e,s,t[s]);if(i)for(var s of i(t))o.call(t,s)&&a(e,s,t[s]);return e},c=(e,i)=>t(e,s(i)),l=(e,t,s)=>new Promise((i,n)=>{var o=e=>{try{r(s.next(e))}catch(t){n(t)}},a=e=>{try{r(s.throw(e))}catch(t){n(t)}},r=e=>e.done?i(e.value):Promise.resolve(e.value).then(o,a);r((s=s.apply(e,t)).next())}); /*! * Ticketping Chat Widget v1.0.0 * (c) 2024 Ticketping * Licensed under MIT */ function h(e,t={}){const s=document.createElement(e);return t?(Object.entries(t).forEach(([e,t])=>{if(null!=t)if("className"===e)s.className=t;else if("textContent"===e)s.textContent=t;else if("innerHTML"===e)s.innerHTML=t;else if(e.startsWith("on")&&"function"==typeof t){const i=e.slice(2).toLowerCase();s.addEventListener(i,t)}else"boolean"==typeof t?t?(s.setAttribute(e,e),s[e]=!0):s[e]=!1:s.setAttribute(e,t)}),s):s}const d={appId:null,teamSlug:null,teamLogoIcon:null,apiBase:"https://api.ticketping.com",wsBase:"wss://ws.ticketping.com",userJWT:null,enableSecureMode:!0,position:"bottom-right",theme:"default",zIndex:999999,autoOpen:!1,enableTypingIndicators:!0,enableFileUpload:!0,enableEmojis:!0,maxFileSize:10485760,allowedFileTypes:["image/jpeg","image/png","image/gif","application/pdf","application/msword","application/vnd.openxmlformats-officedocument.wordprocessingml.document","text/plain"],maxMessageLength:5e3,enableMarkdown:!1,enableLinkPreviews:!0,showConversationHistory:!0,maxConversationsStored:50,autoDeleteAfterDays:30,enableSoundNotifications:!0,enableBrowserNotifications:!1,analytics:!0,trackUserInteractions:!0,locale:"en",timezone:Intl.DateTimeFormat().resolvedOptions().timeZone,debug:!1,logLevel:"error",labels:{headerTitle:"Ticketping",headerSubtitle:"We're here to help!",homeTab:"Home",messagesTab:"Messages",welcomeTitle:"👋 Welcome!",welcomeMessage:"Hi there! How can we help you today?",startConversationButton:"Send us a message",messageInputPlaceholder:"Type your message...",sendButton:"Send",attachButton:"Attach file",typingIndicator:"Support is typing...",agentOnline:"We're online and ready to help!",agentOffline:"We'll get back to you soon!",connectionLost:"Connection lost. Trying to reconnect...",fileTooLarge:"File size exceeds maximum limit",fileTypeNotAllowed:"File type not supported",messageTooLong:"Message is too long",sendError:"Failed to send message. Please try again.",loadError:"Failed to load conversation",noConversations:"No conversations yet",noConversationsDescription:"Start a conversation to get help from our support team.",helpArticlesTitle:"Popular articles",helpArticles:[{title:"Getting started guide",url:"/help/getting-started",icon:"article"},{title:"How to create tickets",url:"/help/create-tickets",icon:"check"},{title:"Best practices",url:"/help/best-practices",icon:"star"}]},customCSS:null,onReady:null,onOpen:null,onClose:null,onMessageSent:null,onMessageReceived:null,onConversationStarted:null,onError:null},g="/api/v1/jwt/auth/",u="/api/v1/chat-session/create/",p="/api/v1/chat-sessions/",m="/messages",v="/api/v1/chat-session/file-upload/",S={AUTH:"auth",TYPING_START:"typing_start",TYPING_STOP:"typing_stop",JOIN_CONVERSATION:"join_conversation",LEAVE_CONVERSATION:"leave_conversation",FILE_ATTACHMENT:"file_attachment",SERVER_STATE:"server_session_state",SERVER_MESSAGE_HISTORY:"server_message_history",SERVER_MESSAGE:"server_message",SERVER_AGENT_STATUS:"server_agent_status",SERVER_AGENT_JOINED:"server_agent_joined",SERVER_AGENT_LEFT:"server_agent_left",SERVER_CONVERSATION_UPDATED:"server_conversation_updated",SERVER_AUTH_SUCCESS:"server_auth_success",SERVER_AUTH_FAILED:"server_auth_failed",SERVER_ANONYMOUS_AUTH_SUCCESS:"server_anonymous_auth_success",SERVER_ANONYMOUS_AUTH_FAILED:"server_anonymous_auth_failed",PONG:"pong",ERROR:"error"},y={CONVERSATIONS:"ticketping_conversations",USER_DATA:"ticketping_user",SETTINGS:"ticketping_settings",DEVICE_ID:"ticketping_device_id"},w="ticketping-chat-bubble",C="ticketping-chat-window",f="open";class b{constructor(e,t={}){if(!e)return console.error("ChatBubble: Container is required"),this.container=null,this.element=null,this.notificationBadge=null,this.isOpen=!1,void(this.options=r({onClick:()=>{},showNotificationBadge:!1,notificationCount:0},t));this.container=e,this.options=r({onClick:()=>{},showNotificationBadge:!1,notificationCount:0},t),this.element=null,this.notificationBadge=null,this.isOpen=!1,this.render(),this.attachEventListeners()}render(){if(!this.container)return;this.element=h("button",{className:`${w}`,"aria-label":"Open chat","aria-expanded":"false",role:"button",tabindex:"0"});const e=this.createChatIcon();this.element.appendChild(e),this.options.showNotificationBadge&&this.createNotificationBadge(),this.container.appendChild(this.element)}createChatIcon(){const e=document.createElementNS("http://www.w3.org/2000/svg","svg");e.setAttribute("viewBox","0 0 256 256"),e.setAttribute("width","32"),e.setAttribute("height","32");const t=document.createElementNS("http://www.w3.org/2000/svg","path");return t.setAttribute("d","M146.476 232.21L152.258 222.442L138.489 214.291L132.706 224.061L146.476 232.21ZM103.742 222.442L109.524 232.21L123.293 224.061L117.511 214.291L103.742 222.442ZM132.706 224.061C130.651 227.534 125.349 227.534 123.293 224.061L109.524 232.21C117.776 246.151 138.224 246.151 146.476 232.21L132.706 224.061ZM112 29.3333H144V13.3333H112V29.3333ZM226.667 112V122.667H242.667V112H226.667ZM29.3335 122.667V112H13.3335V122.667H29.3335ZM13.3335 122.667C13.3335 134.982 13.3291 144.62 13.8595 152.393C14.3948 160.238 15.5013 166.767 18.0022 172.804L32.7843 166.682C31.2254 162.918 30.3021 158.334 29.8225 151.303C29.3379 144.202 29.3335 135.201 29.3335 122.667H13.3335ZM83.2268 194.577C69.8355 194.346 62.8186 193.494 57.3185 191.216L51.1956 205.998C59.7819 209.554 69.5615 210.343 82.9512 210.574L83.2268 194.577ZM18.0022 172.804C24.2272 187.832 36.1672 199.773 51.1956 205.998L57.3185 191.216C46.2105 186.614 37.3853 177.79 32.7843 166.682L18.0022 172.804ZM226.667 122.667C226.667 135.201 226.663 144.202 226.178 151.303C225.698 158.334 224.775 162.918 223.216 166.682L237.998 172.804C240.499 166.767 241.605 160.238 242.141 152.393C242.671 144.62 242.667 134.982 242.667 122.667H226.667ZM173.049 210.574C186.439 210.343 196.219 209.554 204.804 205.998L198.682 191.216C193.182 193.494 186.164 194.346 172.773 194.577L173.049 210.574ZM223.216 166.682C218.615 177.79 209.79 186.614 198.682 191.216L204.804 205.998C219.833 199.773 231.773 187.832 237.998 172.804L223.216 166.682ZM144 29.3333C161.613 29.3333 174.261 29.3417 184.127 30.2798C193.874 31.2065 200.076 32.9838 205.02 36.0136L213.38 22.3714C205.499 17.5421 196.559 15.3897 185.642 14.3517C174.843 13.3249 161.304 13.3333 144 13.3333V29.3333ZM242.667 112C242.667 94.6966 242.675 81.1573 241.648 70.3585C240.61 59.4406 238.458 50.5008 233.629 42.62L219.986 50.98C223.017 55.9244 224.794 62.1263 225.721 71.8729C226.658 81.7386 226.667 94.3867 226.667 112H242.667ZM205.02 36.0136C211.12 39.7517 216.249 44.8802 219.986 50.98L233.629 42.62C228.572 34.3673 221.633 27.4287 213.38 22.3714L205.02 36.0136ZM112 13.3333C94.6968 13.3333 81.1575 13.3249 70.3587 14.3517C59.4408 15.3897 50.501 17.5421 42.6202 22.3714L50.9802 36.0136C55.9245 32.9838 62.1265 31.2065 71.8731 30.2798C81.7388 29.3417 94.3869 29.3333 112 29.3333V13.3333ZM29.3335 112C29.3335 94.3867 29.3419 81.7386 30.28 71.8729C31.2067 62.1263 32.984 55.9244 36.0138 50.98L22.3716 42.62C17.5422 50.5008 15.3899 59.4406 14.3518 70.3585C13.3251 81.1573 13.3335 94.6966 13.3335 112H29.3335ZM42.6202 22.3714C34.3675 27.4287 27.4289 34.3673 22.3716 42.62L36.0138 50.98C39.7518 44.8802 44.8804 39.7517 50.9802 36.0136L42.6202 22.3714ZM117.511 214.291C115.345 210.632 113.444 207.404 111.596 204.867C109.648 202.196 107.416 199.791 104.319 197.989L96.2745 211.821C96.7802 212.114 97.4692 212.651 98.6652 214.291C99.9598 216.068 101.423 218.523 103.742 222.442L117.511 214.291ZM82.9512 210.574C87.6348 210.655 90.6014 210.715 92.8629 210.964C94.9761 211.199 95.7951 211.541 96.2745 211.821L104.319 197.989C101.196 196.173 97.9464 195.429 94.6238 195.061C91.4496 194.71 87.6135 194.653 83.2268 194.577L82.9512 210.574ZM152.258 222.442C154.577 218.523 156.04 216.068 157.335 214.291C158.53 212.651 159.219 212.114 159.725 211.821L151.681 197.989C148.585 199.791 146.351 202.196 144.404 204.867C142.556 207.404 140.655 210.632 138.489 214.291L152.258 222.442ZM172.773 194.577C168.386 194.653 164.551 194.71 161.376 195.061C158.053 195.429 154.804 196.173 151.681 197.989L159.725 211.821C160.205 211.541 161.024 211.199 163.137 210.964C165.399 210.715 168.365 210.655 173.049 210.574L172.773 194.577Z"),e.appendChild(t),e}createCloseIcon(){const e=document.createElementNS("http://www.w3.org/2000/svg","svg");e.setAttribute("viewBox","0 0 24 24"),e.setAttribute("width","24"),e.setAttribute("height","24");const t=document.createElementNS("http://www.w3.org/2000/svg","path");return t.setAttribute("d","M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"),e.appendChild(t),e}createNotificationBadge(){this.notificationBadge=h("div",{className:"notification-badge",textContent:this.options.notificationCount>99?"99+":this.options.notificationCount.toString()}),this.element.appendChild(this.notificationBadge)}attachEventListeners(){this.element.addEventListener("click",()=>{this.handleClick()}),this.element.addEventListener("keydown",e=>{"Enter"!==e.key&&" "!==e.key||(e.preventDefault(),this.handleClick())})}handleClick(){this.options.onClick(),this.notificationBadge&&this.hideNotificationBadge()}setOpen(e){if(this.isOpen=e,e){this.element.classList.add(f),this.element.setAttribute("aria-expanded","true"),this.element.setAttribute("aria-label","Close chat");const e=this.element.querySelector("svg");e&&(this.element.removeChild(e),this.element.appendChild(this.createCloseIcon()))}else{this.element.classList.remove(f),this.element.setAttribute("aria-expanded","false"),this.element.setAttribute("aria-label","Open chat");const e=this.element.querySelector("svg");e&&(this.element.removeChild(e),this.element.appendChild(this.createChatIcon()))}}showNotificationBadge(e=1){this.notificationBadge||this.createNotificationBadge(),this.options.notificationCount=e,this.notificationBadge.textContent=e>99?"99+":e.toString(),e>0?(this.notificationBadge.style.display="flex",this.notificationBadge.style.animation="tp-pulse 1s ease-in-out 3"):this.notificationBadge.style.display="none"}hideNotificationBadge(){this.notificationBadge&&(this.notificationBadge.style.display="none",this.options.notificationCount=0)}updateNotificationCount(e){this.options.notificationCount=e,e>0?this.showNotificationBadge(e):this.hideNotificationBadge()}setTheme(e){this.element.setAttribute("data-theme",e)}setPosition(e){this.element.setAttribute("data-position",e)}bounce(){this.element.style.animation="tp-bounce 0.6s ease-in-out",setTimeout(()=>{this.element.style.animation=""},600)}setAriaLabel(e){this.element.setAttribute("aria-label",e)}focus(){this.element.focus()}blur(){this.element.blur()}disable(){this.element.disabled=!0,this.element.setAttribute("aria-disabled","true")}enable(){this.element.disabled=!1,this.element.setAttribute("aria-disabled","false")}destroy(){this.element&&this.element.parentNode&&this.element.parentNode.removeChild(this.element)}showNotification(e=1){return this.showNotificationBadge(e)}hideNotification(){return this.hideNotificationBadge()}}class T{constructor(e,t={}){this.container=e,this.options=r({onClose:()=>{},onTabSwitch:()=>{},onSendMessage:()=>{},onFileUpload:()=>{},onConversationSelect:()=>{},onBackButtonClick:()=>{},teamLogoIcon:null},t),this.element=null,this.activeTab="home",this.conversations=[],this.currentMessages=[],this.render(),this.attachEventListeners()}render(){this.element=h("div",{className:C}),this.element.innerHTML=`\n <div class="ticketping-chat-content">\n <div class="ticketping-tab-content active" id="homeTab">\n <div class="ticketping-chat-header">\n <div class="ticketping-workspace-logo">\n ${this.getLogoHtml()}\n </div>\n <button class="ticketping-close-btn" aria-label="Close chat">\n <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">\n <path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/>\n </svg>\n </button>\n </div>\n <div class="ticketping-home-container">\n <div class="ticketping-home-content">\n <h4>Hi there 👋</h4>\n <p>How can we help you?</p>\n </div>\n <div class="ticketping-actions-container">\n <div class="ticketping-recent-conversation" id="recentConversationSection" style="display: none;">\n <div class="ticketping-recent-conversation-header">\n <span class="ticketping-recent-conversation-title">Recent Conversation</span>\n </div>\n <div class="ticketping-recent-conversation-item" id="recentConversationItem">\n <div class="ticketping-recent-conversation-preview"></div>\n <div class="ticketping-recent-conversation-time"></div>\n </div>\n </div>\n <button class="ticketping-start-conversation-btn">\n <div class="ticketping-start-conversation-btn-content">\n <span class="ticketping-start-conversation-btn-text">Send us a message</span>\n <span class="ticketping-start-conversation-btn-subtext">Typically respond within minutes</span>\n </div>\n <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" viewBox="0 0 256 256"><path d="M231.4,44.34s0,.1,0,.15l-58.2,191.94a15.88,15.88,0,0,1-14,11.51q-.69.06-1.38.06a15.86,15.86,0,0,1-14.42-9.15L107,164.15a4,4,0,0,1,.77-4.58l57.92-57.92a8,8,0,0,0-11.31-11.31L96.43,148.26a4,4,0,0,1-4.58.77L17.08,112.64a16,16,0,0,1,2.49-29.8l191.94-58.2.15,0A16,16,0,0,1,231.4,44.34Z"></path></svg>\n </button>\n </div>\n </div>\n <div class="ticketping-plug">\n <a href="https://ticketping.com" target="_blank" rel="noopener noreferrer">\n Powered by Ticketping\n </a>\n </div>\n </div>\n\n <div class="ticketping-tab-content" id="messagesTab">\n <div class="ticketping-messages-header">\n <button class="ticketping-back-btn" id="tpBackBtn" aria-label="Go back">\n <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 256 256"><path d="M165.66,202.34a8,8,0,0,1-11.32,11.32l-80-80a8,8,0,0,1,0-11.32l80-80a8,8,0,0,1,11.32,11.32L91.31,128Z"></path></svg>\n </button>\n <div class="ticketping-tab-heading">\n <span>Messages</span>\n </div>\n <button class="ticketping-close-btn-2" aria-label="Close chat">\n <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">\n <path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/>\n </svg>\n </button>\n </div>\n <div class="ticketping-messages-content">\n <div class="ticketping-conversation-container">\n <div class="ticketping-conversation-list ticketping-thin-scrollbar" id="conversationList">\n \x3c!-- Conversations will be populated here --\x3e\n </div>\n <div class="ticketping-send-a-message-container" id="sendMessageBtnContainer">\n <button class="ticketping-send-message-btn">\n <span class="ticketping-send-message-btn-text">Send us a message</span>\n <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 256 256"><path d="M231.4,44.34s0,.1,0,.15l-58.2,191.94a15.88,15.88,0,0,1-14,11.51q-.69.06-1.38.06a15.86,15.86,0,0,1-14.42-9.15L107,164.15a4,4,0,0,1,.77-4.58l57.92-57.92a8,8,0,0,0-11.31-11.31L96.43,148.26a4,4,0,0,1-4.58.77L17.08,112.64a16,16,0,0,1,2.49-29.8l191.94-58.2.15,0A16,16,0,0,1,231.4,44.34Z"></path></svg>\n </button>\n </div>\n </div>\n\n <div class="active-conversation" id="activeConversation" style="display: none;">\n <div class="ticketping-loading-state" id="loadingState" style="display: none;">\n <div class="ticketping-loading-content">\n <div class="ticketping-loading-spinner">\n <div class="tp-loading-spinner-child"></div>\n </div>\n <div class="ticketping-loading-text">\n <p>Starting conversation...</p>\n <p class="ticketping-loading-subtext">Connecting you with support</p>\n </div>\n </div>\n </div>\n\n <div class="ticketping-messages-list ticketping-thin-scrollbar" id="messagesList">\n \x3c!-- Messages will be populated here --\x3e\n </div>\n\n <div class="typing-indicator" id="typingIndicator">\n Support is typing\n <div class="typing-dots">\n <span></span>\n <span></span>\n <span></span>\n </div>\n </div>\n\n <div class="ticketping-message-input-container">\n <div class="ticketping-message-input-wrapper">\n <textarea\n id="messageInput"\n class="ticketping-message-input"\n placeholder="Type your message..."\n rows="1"\n ></textarea>\n <div class="ticketping-input-actions">\n <div class="ticketping-file-input-container">\n <input type="file" class="ticketping-file-input" accept="image/*,.pdf,.doc,.docx">\n <button class="ticketping-file-btn">\n <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 256 256"><path d="M209.66,122.34a8,8,0,0,1,0,11.32l-82.05,82a56,56,0,0,1-79.2-79.21L147.67,35.73a40,40,0,1,1,56.61,56.55L105,193A24,24,0,1,1,71,159L154.3,74.38A8,8,0,1,1,165.7,85.6L82.39,170.31a8,8,0,1,0,11.27,11.36L192.93,81A24,24,0,1,0,159,47L59.76,147.68a40,40,0,1,0,56.53,56.62l82.06-82A8,8,0,0,1,209.66,122.34Z"></path></svg>\n </button>\n </div>\n <button class="ticketping-send-btn" disabled>\n <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" viewBox="0 0 256 256"><path d="M208.49,120.49a12,12,0,0,1-17,0L140,69V216a12,12,0,0,1-24,0V69L64.49,120.49a12,12,0,0,1-17-17l72-72a12,12,0,0,1,17,0l72,72A12,12,0,0,1,208.49,120.49Z"></path></svg>\n </button>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <div class="ticketping-chat-tabs" id="ticketpingChatTabs">\n <button class="ticketping-tab active" data-tab="home">\n <div class="tab-icon">\n <svg class="icon-inactive" xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256"><path d="M219.31,108.68l-80-80a16,16,0,0,0-22.62,0l-80,80A15.87,15.87,0,0,0,32,120v96a8,8,0,0,0,8,8h64a8,8,0,0,0,8-8V160h32v56a8,8,0,0,0,8,8h64a8,8,0,0,0,8-8V120A15.87,15.87,0,0,0,219.31,108.68ZM208,208H160V152a8,8,0,0,0-8-8H104a8,8,0,0,0-8,8v56H48V120l80-80,80,80Z"></path></svg>\n <svg class="icon-active" xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256"><path d="M224,120v96a8,8,0,0,1-8,8H160a8,8,0,0,1-8-8V164a4,4,0,0,0-4-4H108a4,4,0,0,0-4,4v52a8,8,0,0,1-8,8H40a8,8,0,0,1-8-8V120a16,16,0,0,1,4.69-11.31l80-80a16,16,0,0,1,22.62,0l80,80A16,16,0,0,1,224,120Z"></path></svg>\n </div>\n\n <span>Home</span>\n </button>\n <button class="ticketping-tab" data-tab="messages">\n <div class="tab-icon">\n <svg class="icon-inactive" xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256"><path d="M216,48H40A16,16,0,0,0,24,64V224a15.85,15.85,0,0,0,9.24,14.5A16.13,16.13,0,0,0,40,240a15.89,15.89,0,0,0,10.25-3.78l.09-.07L83,208H216a16,16,0,0,0,16-16V64A16,16,0,0,0,216,48ZM40,224h0ZM216,192H80a8,8,0,0,0-5.23,1.95L40,224V64H216ZM88,112a8,8,0,0,1,8-8h64a8,8,0,0,1,0,16H96A8,8,0,0,1,88,112Zm0,32a8,8,0,0,1,8-8h64a8,8,0,1,1,0,16H96A8,8,0,0,1,88,144Z"></path></svg>\n <svg class="icon-active" xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256"><path d="M216,48H40A16,16,0,0,0,24,64V224a15.84,15.84,0,0,0,9.25,14.5A16.05,16.05,0,0,0,40,240a15.89,15.89,0,0,0,10.25-3.78l.09-.07L83,208H216a16,16,0,0,0,16-16V64A16,16,0,0,0,216,48ZM160,152H96a8,8,0,0,1,0-16h64a8,8,0,0,1,0,16Zm0-32H96a8,8,0,0,1,0-16h64a8,8,0,0,1,0,16Z"></path></svg>\n </div>\n <span>Messages</span>\n </button>\n </div>\n `,this.container.appendChild(this.element)}attachEventListeners(){this.element.querySelector(".ticketping-close-btn").addEventListener("click",()=>{this.options.onClose()}),this.element.querySelector(".ticketping-close-btn-2").addEventListener("click",()=>{this.options.onClose()}),this.element.querySelector("#tpBackBtn").addEventListener("click",()=>{this.showConversationList(),this.options.onBackButtonClick()}),this.element.querySelectorAll(".ticketping-tab").forEach(e=>{e.addEventListener("click",()=>{this.switchTab(e.dataset.tab)})}),this.element.querySelector(".ticketping-start-conversation-btn").addEventListener("click",()=>{this.options.onConversationSelect("new"),setTimeout(()=>{this.element.querySelector("#messageInput").focus()},50)}),this.element.querySelector(".ticketping-send-message-btn").addEventListener("click",()=>{this.options.onConversationSelect("new"),setTimeout(()=>{this.element.querySelector("#messageInput").focus()},50)});const e=this.element.querySelector("#recentConversationItem");e&&e.addEventListener("click",()=>{const t=e.dataset.conversationId;t&&this.options.onConversationSelect(t)});const t=this.element.querySelector("#messageInput"),s=this.element.querySelector(".ticketping-send-btn");t.addEventListener("input",()=>{this.handleInputChange(t,s)}),t.addEventListener("keypress",e=>{"Enter"!==e.key||e.shiftKey||(e.preventDefault(),this.sendMessage(t,s))}),s.addEventListener("click",()=>{this.sendMessage(t,s)});const i=this.element.querySelector(".ticketping-file-btn"),n=this.element.querySelector(".ticketping-file-input");i.addEventListener("click",()=>n.click()),n.addEventListener("change",()=>this.handleFileUpload(n))}show(){this.element.classList.add(f)}hide(){this.element.classList.remove(f)}switchTab(e){this.activeTab=e,this.element.querySelectorAll(".ticketping-tab").forEach(t=>{t.classList.toggle("active",t.dataset.tab===e)}),this.element.querySelectorAll(".ticketping-tab-content").forEach(t=>{t.classList.toggle("active",t.id===`${e}Tab`)}),"messages"===e?(this.element.querySelector("#conversationList").classList.add("show"),this.element.querySelector("#sendMessageBtnContainer").classList.add("show")):(this.element.querySelector("#conversationList").classList.remove("show"),this.element.querySelector("#sendMessageBtnContainer").classList.remove("show")),this.options.onTabSwitch(e)}setConversations(e){this.conversations=e,this.renderConversationList(),this.updateRecentConversation()}renderConversationList(){const e=this.element.querySelector("#conversationList");if(0===this.conversations.length)return void this.showEmptyState();e.innerHTML="";[...this.conversations].sort((e,t)=>{const s=new Date(e.modified||e.created);return new Date(t.modified||t.created)-s}).forEach(t=>{var s;const i=h("div",{className:"ticketping-conversation-item","data-conversation":t.sessionId}),n=null==(s=t.messages)?void 0:s[t.messages.length-1],o=n?n.messageText.substring(0,50)+"...":"";i.innerHTML=`\n <div class="ticketping-conversation-preview">${t.summary||o||"Support Chat"}</div>\n <div class="ticketping-conversation-time">${this.formatDateTime(t.modified||t.created)}</div>\n `,i.addEventListener("click",()=>{this.options.onConversationSelect(t.sessionId)}),e.appendChild(i)})}showEmptyState(){this.element.querySelector("#conversationList").innerHTML='\n <div class="empty-state">\n <div class="empty-state-content">\n <p>No conversations yet</p>\n <p class="empty-state-subtext">Send us a message to get help</p>\n </div>\n </div>\n '}showConversationItem(){this.element.querySelector("#conversationList").classList.remove("show"),this.element.querySelector("#activeConversation").style.display="flex",this.element.querySelector("#tpBackBtn").classList.add("show"),this.element.querySelector("#sendMessageBtnContainer").classList.remove("show"),this.element.querySelector("#ticketpingChatTabs").style.display="none",this.hideLoadingState(),setTimeout(()=>{this.element.querySelector("#messageInput").focus()},50)}showConversationList(){this.element.querySelector("#conversationList").classList.add("show"),this.element.querySelector("#activeConversation").style.display="none",this.element.querySelector("#tpBackBtn").classList.remove("show"),this.element.querySelector("#sendMessageBtnContainer").classList.add("show"),this.element.querySelector("#ticketpingChatTabs").style.display="flex",this.clearMessages(),this.hideLoadingState()}showLoadingState(){this.element.querySelector("#conversationList").classList.remove("show"),this.element.querySelector("#activeConversation").style.display="flex",this.element.querySelector("#loadingState").style.display="flex",this.element.querySelector("#messagesList").style.display="none",this.element.querySelector("#typingIndicator").style.display="none",this.element.querySelector(".ticketping-message-input-container").style.display="none",this.element.querySelector("#tpBackBtn").classList.add("show"),this.element.querySelector("#sendMessageBtnContainer").classList.remove("show"),this.element.querySelector("#ticketpingChatTabs").style.display="none"}hideLoadingState(){this.element.querySelector("#loadingState").style.display="none",this.element.querySelector("#messagesList").style.display="block",this.element.querySelector("#typingIndicator").style.display="none",this.element.querySelector(".ticketping-message-input-container").style.display="block"}addMessage(e){const t=this.element.querySelector("#messagesList"),s=this.currentMessages[this.currentMessages.length-1];this.currentMessages.push(e);const i=this.processNewMessageForGrouping(e,s);if(i.updatePrevious&&s){const e=t.querySelectorAll(".ticketping-message"),i=e[e.length-1];i&&this.updateMessageElementForGrouping(i,s,!1)}if(i.showDateSeparator){const e=this.createDateSeparatorElement(i.created);t.appendChild(e)}const n=this.createMessageElement(i);t.appendChild(n),this.scrollToBottom()}setMessages(e){const t=this.element.querySelector("#messagesList");t.innerHTML="",this.currentMessages=[...e];this.processMessagesForGrouping(e).forEach(e=>{if(e.showDateSeparator){const s=this.createDateSeparatorElement(e.created);t.appendChild(s)}const s=this.createMessageElement(e);t.appendChild(s)}),this.scrollToBottom()}clearMessages(){this.element.querySelector("#messagesList").innerHTML="",this.currentMessages=[]}createMessageElement(e){let t=`ticketping-message ${e.sender.toLowerCase()}`;e.isGrouped&&(t+=" grouped"),e.isFirstInGroup&&(t+=" first-in-group"),e.isLastInGroup&&(t+=" last-in-group");const s=h("div",{className:t}),i=e.filename&&e.filepath,n=!1!==e.showTimestamp;if(i){const t=e.messageHtml?e.messageHtml:this.escapeHtml(e.messageText||""),i=this.createAttachmentHtml(e.filename,e.filepath);s.innerHTML=`\n <div class="ticketping-message-bubble">\n ${t}\n ${i}\n </div>\n ${n?`<div class="ticketping-message-time">${this.formatTime(e.created)}</div>`:""}\n `}else s.innerHTML=`\n <div class="ticketping-message-bubble">${e.messageHtml?e.messageHtml:this.escapeHtml(e.messageText)}</div>\n ${n?`<div class="ticketping-message-time">${this.formatTime(e.created)}</div>`:""}\n `;return s}createDateSeparatorElement(e){const t=h("div",{className:"ticketping-date-separator"});return t.innerHTML=`\n <div class="ticketping-date-separator-line"></div>\n <div class="ticketping-date-separator-text">${this.formatDateSeparator(e)}</div>\n <div class="ticketping-date-separator-line"></div>\n `,t}processMessagesForGrouping(e){if(!e||0===e.length)return e;if(1===e.length)return[c(r({},e[0]),{showTimestamp:!0})];const t=e.map(e=>c(r({},e),{showTimestamp:!1,showDateSeparator:!1})),s=[];let i={start:0,end:0,sender:t[0].sender};for(let n=1;n<t.length;n++){const e=t[n],o=t[n-1];this.getDateInUserTimezone(e.created)!==this.getDateInUserTimezone(o.created)&&(t[n].showDateSeparator=!0);const a=new Date(e.created).getTime()-new Date(o.created).getTime();e.sender!==o.sender||a>3e5?(i.end=n-1,s.push(i),i={start:n,end:n,sender:e.sender}):i.end=n}return s.push(i),s.forEach(e=>{if(t[e.end].showTimestamp=!0,e.start===e.end)t[e.start].showTimestamp=!0;else for(let s=e.start;s<=e.end;s++)t[s].isGrouped=!0,t[s].isFirstInGroup=s===e.start,t[s].isLastInGroup=s===e.end}),t[0].showTimestamp=!0,t}processNewMessageForGrouping(e,t){const s=c(r({},e),{showTimestamp:!0,showDateSeparator:!1,isGrouped:!1,isFirstInGroup:!1,isLastInGroup:!1,updatePrevious:!1});if(!t)return s;this.getDateInUserTimezone(e.created)!==this.getDateInUserTimezone(t.created)&&(s.showDateSeparator=!0);const i=new Date(e.created).getTime()-new Date(t.created).getTime();return e.sender!==t.sender||i>3e5||(s.isGrouped=!0,s.isLastInGroup=!0,s.showTimestamp=!0,s.updatePrevious=!0),s}updateMessageElementForGrouping(e,t,s){e.classList.add("grouped"),e.classList.remove("last-in-group");const i=e.querySelector(".ticketping-message-time");i&&(i.style.display=s?"block":"none")}handleInputChange(e,t){const s=e.value.trim().length>0;t.disabled=!s,this.toggleFileInputButton(!s),this.autoResizeTextarea(e)}sendMessage(e,t){const s=e.value.trim();s&&(this.options.onSendMessage({text:s}),e.value="",t.disabled=!0,this.toggleFileInputButton(!0),this.autoResizeTextarea(e))}toggleFileInputButton(e){const t=this.element.querySelector(".ticketping-file-input-container");t&&t.classList.toggle("tp-hidden",!e)}handleFileUpload(e){const t=e.files[0];t&&(this.options.onFileUpload(t),e.value="")}showTypingIndicator(e=!0){this.element.querySelector("#typingIndicator").classList.toggle("show",e),e&&this.scrollToBottom()}autoResizeTextarea(e){e.style.height="auto",e.style.height=Math.min(e.scrollHeight,100)+"px"}scrollToBottom(){const e=this.element.querySelector("#messagesList");setTimeout(()=>{e.scrollTop=e.scrollHeight},100)}formatTime(e){return new Date(e).toLocaleTimeString([],{hour:"numeric",minute:"2-digit"})}formatDateTime(e){return new Date(e).toLocaleString([],{month:"long",day:"numeric",hour:"numeric",minute:"2-digit"})}getDateInUserTimezone(e){return new Date(e).toLocaleDateString()}formatDateSeparator(e){const t=new Date(e),s=new Date,i=new Date(s);i.setDate(i.getDate()-1);const n=this.getDateInUserTimezone(e),o=this.getDateInUserTimezone(s),a=this.getDateInUserTimezone(i);return n===o?"Today":n===a?"Yesterday":t.toLocaleDateString([],{weekday:"long",month:"long",day:"numeric",year:t.getFullYear()!==s.getFullYear()?"numeric":void 0})}escapeHtml(e){const t=document.createElement("div");return t.textContent=e,t.innerHTML}getLogoHtml(){const e=this.options.teamLogoIcon;return e?`<img src="${e}" alt="logo">`:'<svg width="40" height="40" viewBox="0 0 1.2 1.2" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M1.1 0.25a0.15 0.15 0 1 1 -0.3 0 0.15 0.15 0 0 1 0.3 0" fill="#4CB782"/><path opacity=".5" d="M0.762 0.127A0.5 0.5 0 0 0 0.6 0.1C0.324 0.1 0.1 0.324 0.1 0.6c0 0.08 0.019 0.156 0.052 0.223 0.009 0.018 0.012 0.038 0.007 0.057l-0.03 0.111a0.065 0.065 0 0 0 0.08 0.08l0.111 -0.03a0.082 0.082 0 0 1 0.057 0.007A0.498 0.498 0 0 0 0.6 1.1c0.276 0 0.5 -0.224 0.5 -0.5 0 -0.057 -0.009 -0.111 -0.027 -0.162a0.225 0.225 0 0 1 -0.312 -0.312" fill="#1C274C"/></svg>'}createAttachmentHtml(e,t){return`\n <div class="ticketping-message-attachment">\n <div class="ticketping-attachment-info">\n <div class="ticketping-attachment-name">\n <a href="${t}" target="_blank" rel="noopener noreferrer" style="color: inherit; text-decoration: none;">\n ${this.escapeHtml(e)}\n </a>\n </div>\n </div>\n </div>\n `}updateAgentStatus(e){const t=this.element.querySelector(".ticketping-chat-header-content p");t.textContent="online"===e?"We're online and ready to help!":"We'll get back to you soon!"}updateRecentConversation(){var e;const t=this.element.querySelector("#recentConversationSection"),s=this.element.querySelector("#recentConversationItem");if(!t||!s)return;if(0===this.conversations.length)return void(t.style.display="none");const i=[...this.conversations].sort((e,t)=>{const s=new Date(e.modified||e.created);return new Date(t.modified||t.created)-s})[0],n=null==(e=i.messages)?void 0:e[i.messages.length-1],o=n?n.messageText.substring(0,60)+"...":"",a=i.summary||o||"Support Chat";s.querySelector(".ticketping-recent-conversation-preview").textContent=a,s.querySelector(".ticketping-recent-conversation-time").textContent=this.formatDateTime(i.modified||i.created),s.dataset.conversationId=i.sessionId,t.style.display="block"}showError(e){console.error(e)}destroy(){this.element&&this.element.parentNode&&this.element.parentNode.removeChild(this.element)}}class k{constructor(e,t=null,s={}){this.wsUrl=e,this.token=t,this.isAnonymous=!t,this.options=r({onSessionState:()=>{},onMessage:()=>{},onFileAttachment:()=>{},onMessageHistory:()=>{},onTyping:()=>{},onStatusChange:()=>{},onError:()=>{},onConnect:()=>{},onDisconnect:()=>{},reconnectAttempts:5,reconnectDelay:1e3,heartbeatInterval:3e4},s),this.ws=null,this.isConnected=!1,this.reconnectCount=0,this.heartbeatTimer=null,this.reconnectTimer=null,this.typingTimer=null,this.connect()}connect(){try{this.ws=new WebSocket(this.wsUrl),this.attachEventListeners()}catch(e){console.error("WebSocket connection failed:",e),this.options.onError(e),this.scheduleReconnect()}}attachEventListeners(){this.ws.onopen=e=>{console.log("WebSocket connected"),this.isConnected=!0,this.reconnectCount=0,this.authenticate(),this.startHeartbeat(),this.options.onConnect(e)},this.ws.onmessage=e=>{try{const t=JSON.parse(e.data);this.handleMessage(t)}catch(t){console.error("Failed to parse WebSocket message:",t),this.options.onError(t)}},this.ws.onclose=e=>{console.log("WebSocket disconnected:",e.code,e.reason),this.isConnected=!1,this.stopHeartbeat(),this.options.onDisconnect(e),1e3!==e.code&&this.reconnectCount<this.options.reconnectAttempts&&this.scheduleReconnect()},this.ws.onerror=e=>{console.error("WebSocket error:",e),this.options.onError(e)}}authenticate(){this.isAnonymous?this.send({type:S.AUTH,anonymous:!0}):this.send({type:S.AUTH,token:this.token})}handleMessage(e){switch(e.type){case S.SERVER_STATE:this.options.onSessionState(e);break;case S.SERVER_MESSAGE:this.options.onMessage(e);break;case S.FILE_ATTACHMENT:this.options.onFileAttachment(e);break;case S.SERVER_MESSAGE_HISTORY:this.options.onMessageHistory(e);break;case S.SERVER_TYPING:this.options.onTyping(e);break;case S.SERVER_AGENT_STATUS:this.options.onStatusChange(e);break;case S.SERVER_AGENT_JOINED:this.options.onStatusChange(r({type:"agent_joined"},e));break;case S.SERVER_AGENT_LEFT:this.options.onStatusChange(r({type:"agent_left"},e));break;case S.SERVER_CONVERSATION_UPDATED:this.options.onMessage(e);break;case S.SERVER_AUTH_SUCCESS:console.log("WebSocket authentication successful");break;case S.SERVER_AUTH_FAILED:console.error("WebSocket authentication failed"),this.options.onError(new Error("Authentication failed")),this.disconnect();break;case S.SERVER_ANONYMOUS_AUTH_SUCCESS:console.log("Anonymous WebSocket authentication successful");break;case S.SERVER_ANONYMOUS_AUTH_FAILED:console.error("Anonymous WebSocket authentication failed"),this.options.onError(new Error("Anonymous authentication failed")),this.disconnect();break;case S.PONG:break;case S.ERROR:console.error("WebSocket error:",e.message),this.options.onError(new Error(e.message));break;default:console.warn("Unknown WebSocket message type:",e.type)}}send(e){if(!this.isConnected||this.ws.readyState!==WebSocket.OPEN)return console.warn("WebSocket not connected, message queued"),!1;try{return this.ws.send(JSON.stringify(e)),!0}catch(t){return console.error("Failed to send WebSocket message:",t),this.options.onError(t),!1}}sendMessage(e){return this.send(r(r({},e),e.file&&{file:e.file}))}sendTypingStart(e){this.typingTimer&&clearTimeout(this.typingTimer),this.send({type:S.TYPING_START,conversationId:e}),this.typingTimer=setTimeout(()=>{this.sendTypingStop(e)},3e3)}sendTypingStop(e){this.typingTimer&&(clearTimeout(this.typingTimer),this.typingTimer=null),this.send({type:S.TYPING_STOP,conversationId:e})}joinConversation(e){return this.send({type:S.JOIN_CONVERSATION,conversationId:e})}leaveConversation(e){return this.send({type:S.LEAVE_CONVERSATION,conversationId:e})}startHeartbeat(){this.heartbeatTimer=setInterval(()=>{this.isConnected&&this.send({type:"ping"})},this.options.heartbeatInterval)}stopHeartbeat(){this.heartbeatTimer&&(clearInterval(this.heartbeatTimer),this.heartbeatTimer=null)}scheduleReconnect(){if(this.reconnectCount>=this.options.reconnectAttempts)return console.error("Max reconnection attempts reached"),void this.options.onError(new Error("Max reconnection attempts reached"));this.reconnectCount++;const e=this.options.reconnectDelay*Math.pow(2,this.reconnectCount-1);console.log(`Reconnecting in ${e}ms (attempt ${this.reconnectCount})`),this.reconnectTimer=setTimeout(()=>{console.log(`Reconnection attempt ${this.reconnectCount}`),this.connect()},e)}reconnect(){this.disconnect(),this.reconnectCount=0,this.connect()}disconnect(){this.isConnected=!1,this.stopHeartbeat(),this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null),this.typingTimer&&(clearTimeout(this.typingTimer),this.typingTimer=null),this.ws&&(this.ws.close(1e3,"Client disconnect"),this.ws=null)}getConnectionState(){if(!this.ws)return"DISCONNECTED";switch(this.ws.readyState){case WebSocket.CONNECTING:return"CONNECTING";case WebSocket.OPEN:return"CONNECTED";case WebSocket.CLOSING:return"CLOSING";case WebSocket.CLOSED:return"DISCONNECTED";default:return"UNKNOWN"}}isAnonymousUser(){return this.isAnonymous}isWsConnected(){return this.isConnected&&this.ws&&this.ws.readyState===WebSocket.OPEN}on(e,t){switch(e){case"message":this.options.onMessage=t;break;case"typing":this.options.onTyping=t;break;case"status":this.options.onStatusChange=t;break;case"error":this.options.onError=t;break;case"connect":this.options.onConnect=t;break;case"disconnect":this.options.onDisconnect=t;break;default:console.warn("Unknown event type:",e)}}destroy(){this.disconnect()}}const I="ticketping_chat_jwt";class E{constructor(e){this.config=e,this.baseURL=e.apiBase}setCookie(e,t,s){const i=new Date;i.setTime(i.getTime()+60*s*60*1e3);const n=`expires=${i.toUTCString()}`;document.cookie=`${e}=${t};${n};path=/;SameSite=Strict`}getCookie(e){const t=e+"=",s=document.cookie.split(";");for(let i=0;i<s.length;i++){let e=s[i];for(;" "===e.charAt(0);)e=e.substring(1,e.length);if(0===e.indexOf(t))return e.substring(t.length,e.length)}return null}deleteCookie(e){document.cookie=`${e}=;expires=Thu, 01 Jan 1970 00:00:00 UTC;path=/;SameSite=Strict`}request(e){return l(this,arguments,function*(e,t={}){const s=`${this.baseURL}${e}`,i=r({"Content-Type":"application/json"},t.headers);this.config.appId&&(i["x-tpwidget-id"]=this.config.appId);const n=r({method:"GET",headers:i},t);try{const e=yield fetch(s,n);if(!e.ok)throw new Error(`HTTP ${e.status}: ${e.statusText}`);const t=e.headers.get("content-type");return t&&t.includes("application/json")?yield e.json():yield e.text()}catch(o){throw console.error(`API request failed: ${e}`,o),this.isAuthError(o)&&this.clearChatToken(),o}})}getChatToken(){return l(this,null,function*(){const e=this.getCookie(I);if(e)try{const t=JSON.parse(atob(e.split(".")[1])),s=Math.floor(Date.now()/1e3);if(t.exp&&t.exp>s)return{chatJWT:e}}catch(i){console.log("error",i),console.warn("Invalid cached JWT format, fetching new token"),this.deleteCookie(I)}const t=new URLSearchParams({jwt:this.config.userJWT,team:this.config.teamSlug}),s=yield this.request(`${g}?${t}`,{method:"GET"});return s.jwt&&this.setCookie(I,s.jwt,168),{chatJWT:s.jwt}})}clearChatToken(){this.deleteCookie(I)}createChatSession(){return l(this,null,function*(){return yield this.request(u,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({appId:this.config.appId,team:this.config.teamSlug,jwt:this.config.userJWT})})})}getConversations(e=50,t=0){return l(this,null,function*(){const{chatJWT:s}=yield this.getChatToken(),i={Authorization:`Bearer ${s}`,"Content-Type":"application/json"},n=new URLSearchParams({limit:e.toString(),offset:t.toString()});return yield this.request(`${p}?${n}`,{headers:i})})}getConversation(e){return l(this,null,function*(){return yield this.request(`${p}/${e}`)})}createConversation(){return l(this,arguments,function*(e={}){return yield this.request(p,{method:"POST",body:JSON.stringify(r({appId:this.config.appId},e))})})}updateConversation(e,t){return l(this,null,function*(){return yield this.request(`${p}/${e}`,{method:"PATCH",body:JSON.stringify(t)})})}getMessages(e,t=50,s=null){return l(this,null,function*(){const i=new URLSearchParams({conversationId:e,limit:t.toString()});return s&&i.append("before",s),yield this.request(`${m}?${i}`)})}sendMessage(e){return l(this,null,function*(){return yield this.request(m,{method:"POST",body:JSON.stringify(r({conversationId:e.conversationId,text:e.text,type:e.type||"user",timestamp:e.timestamp,messageId:e.id},e.file&&{file:e.file}))})})}markAsRead(e,t){return l(this,null,function*(){return yield this.request(`${m}/${t}/read`,{method:"POST",body:JSON.stringify({conversationId:e})})})}uploadFile(e,t){return l(this,null,function*(){const s=new FormData;s.append("file",e);const i={};if(this.config.userJWT){const{chatJWT:e}=yield this.getChatToken();e&&(i.Authorization=`Bearer ${e}`)}this.config.appId&&(i["x-tpwidget-id"]=this.config.appId);try{const e=yield fetch(`${this.baseURL}${v}${this.config.teamSlug}/${t}/`,{method:"POST",headers:i,body:s});if(!e.ok)throw new Error(`Upload failed: ${e.statusText}`);return(yield e.json()).url}catch(n){throw console.error("File upload failed:",n),n}})}track(e){return l(this,arguments,function*(e,t={}){})}updateUser(e){return l(this,null,function*(){return yield this.request("/users/me",{method:"PATCH",body:JSON.stringify(e)})})}getAgentStatus(){return l(this,null,function*(){return yield this.request("/agents/status")})}getHelpArticles(e="",t=5){return l(this,null,function*(){const s=new URLSearchParams({q:e,limit:t.toString(),appId:this.config.appId});return yield this.request(`/help/articles?${s}`)})}searchHelpArticles(e){return l(this,null,function*(){return yield this.request("/help/search",{method:"POST",body:JSON.stringify({query:e,appId:this.config.appId})})})}setToken(e){this.token=e}setAppId(e){this.config.appId=e}isNetworkError(e){return e instanceof TypeError&&e.message.includes("fetch")}isAuthError(e){return e.message.includes("401")||e.message.includes("Unauthorized")}isRateLimitError(e){return e.message.includes("429")||e.message.includes("Too Many Requests")}requestWithRetry(e){return l(this,arguments,function*(e,t={},s=3){let i;for(let o=1;o<=s;o++)try{return yield this.request(e,t)}catch(n){if(i=n,this.isAuthError(n)||n.message.includes("4")&&!this.isRateLimitError(n))throw n;if(o<s){const e=1e3*Math.pow(2,o);yield new Promise(t=>setTimeout(t,e))}}throw i})}batchRequest(e){return l(this,null,function*(){return yield this.request("/batch",{method:"POST",body:JSON.stringify({requests:e})})})}getPaginatedData(e){return l(this,arguments,function*(e,t={}){const{limit:s=50,maxItems:i=200,onPage:n=()=>{}}=t,o=[];let a=0,r=!0;for(;r&&o.length<i;){const t=new URLSearchParams({limit:s.toString(),offset:a.toString()}),i=yield this.request(`${e}?${t}`),c=i.data||i.items||i;o.push(...c),n(c,a),r=c.length===s,a+=s}return o.slice(0,i)})}healthCheck(){return l(this,null,function*(){try{return yield this.request("/health"),!0}catch(e){return console.warn("Health check failed:",e.message),!1}})}get(e){return l(this,arguments,function*(e,t={}){return yield this.request(e,r({method:"GET"},t))})}post(e){return l(this,arguments,function*(e,t=null,s={}){const i=r({method:"POST"},s);return t&&(i.body=JSON.stringify(t)),yield this.request(e,i)})}}class L{constructor(){this.isAvailable=this.checkStorageAvailability(),this.deviceId=this.getOrCreateDeviceId()}checkStorageAvailability(){try{const e="__storage_test__";return localStorage.setItem(e,e),localStorage.removeItem(e),!0}catch(e){return console.warn("localStorage not available, using memory storage:",e.message),this.memoryStorage=new Map,!1}}getOrCreateDeviceId(){let e=this.getItem(y.DEVICE_ID);return e||(e=`device_${Date.now()}_${Math.random().toString(36).substr(2,9)}`,this.setItem(y.DEVICE_ID,e)),e}getDeviceId(){return this.deviceId}setItem(e,t){try{const s=JSON.stringify(t);this.isAvailable?localStorage.setItem(e,s):this.memoryStorage.set(e,s)}catch(s){console.warn("Failed to store item:",e,s)}}getItem(e){try{let t;return t=this.isAvailable?localStorage.getItem(e):this.memoryStorage.get(e),t?JSON.parse(t):null}catch(t){return console.warn("Failed to retrieve item:",e,t),null}}removeItem(e){try{this.isAvailable?localStorage.removeItem(e):this.memoryStorage.delete(e)}catch(t){console.warn("Failed to remove item:",e,t)}}clear(){try{this.isAvailable?Object.values(y).forEach(e=>{localStorage.removeItem(e)}):this.memoryStorage.clear()}catch(e){console.warn("Failed to clear storage:",e)}}saveConversation(e){const t=this.getConversations(),s=t.findIndex(t=>t.sessionId===e.sessionId);s>=0?t[s]=e:t.push(e);t.length>50&&(t.sort((e,t)=>new Date(t.modified||t.created)-new Date(e.modified||e.created)),t.splice(50)),this.setItem(y.CONVERSATIONS,t)}getConversations(){return this.getItem(y.CONVERSATIONS)||[]}clearConversations(){this.removeItem(y.CONVERSATIONS)}getConversation(e){return this.getConversations().find(t=>t.sessionId===e)}deleteConversation(e){const t=this.getConversations().filter(t=>t.sessionId!==e);this.setItem(y.CONVERSATIONS,t)}setUser(e){this.setItem(y.USER_DATA,c(r({},e),{lastSeen:(new Date).toISOString()}))}getUser(){return this.getItem(y.USER_DATA)}clearUser(){this.removeItem(y.USER_DATA)}saveSettings(e){const t=this.getSettings();this.setItem(y.SETTINGS,r(r({},t),e))}setSettings(e){return this.saveSettings(e)}getSettings(){return this.getItem(y.SETTINGS)||{}}getSetting(e,t=null){const s=this.getSettings();return void 0!==s[e]?s[e]:t}setSetting(e,t){const s=this.getSettings();s[e]=t,this.setItem(y.SETTINGS,s)}cleanupOldData(e=30){const t=this.getConversations(),s=new Date;s.setDate(s.getDate()-e);const i=t.filter(e=>new Date(e.modified||e.created)>s);i.length!==t.length&&(this.setItem(y.CONVERSATIONS,i),console.log(`Cleaned up ${t.length-i.length} old conversations`))}exportData(){return{conversations:this.getConversations(),user:this.getUser(),settings:this.getSettings(),deviceId:this.deviceId,exportedAt:(new Date).toISOString()}}importData(e){try{return e.conversations&&this.setItem(y.CONVERSATIONS,e.conversations),e.user&&this.setItem(y.USER_DATA,e.user),e.settings&&this.setItem(y.SETTINGS,e.settings),!0}catch(t){return console.error("Failed to import data:",t),!1}}getStorageSize(){if(!this.isAvailable)return 0;let e=0;return Object.values(y).forEach(t=>{const s=localStorage.getItem(t);s&&(e+=s.length)}),e}getStorageSizeHuman(){const e=this.getStorageSize();if(0===e)return"0 B";const t=Math.floor(Math.log(e)/Math.log(1024));return parseFloat((e/Math.pow(1024,t)).toFixed(2))+" "+["B","KB","MB"][t]}migrateData(e,t){if(console.log(`Migrating storage from version ${e} to ${t}`),"1.0.0"===e&&"1.1.0"===t){const e=this.getConversations().map(e=>c(r({},e),{version:"1.1.0"}));this.setItem(y.CONVERSATIONS,e)}}clearPersonalData(){this.clearUser();const e=this.getConversations().map(e=>c(r({},e),{messages:e.messages.map(e=>c(r({},e),{text:"user"===e.type?"[User message removed]":e.text}))}));this.setItem(y.CONVERSATIONS,e)}hasData(){return this.getConversations().length>0||null!==this.getUser()}getDataSummary(){return{conversationCount:this.getConversations().length,hasUser:null!==this.getUser(),storageSize:this.getStorageSizeHuman(),deviceId:this.deviceId}}}class A{constructor(e={}){this.config=r(r({},d),e),this.isInitialized=!1,this.isOpen=!1,this.currentUser=null,this.api=new E(this.config),this.storage=new L,this.ws=null,this.chatBubble=null,this.chatWindow=null,this.widgetContainer=null,this.conversations=new Map,this.isChatSessionActive=!1,this.currentChatSession=null,this.init()}init(){return l(this,null,function*(){if(this.isInitialized)console.warn("TicketpingChat already initialized");else try{const e=function(e)