@baseportal/chat-widget 0.1.0 → 0.1.2

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
- {"version":3,"sources":["../src/index.ts","../src/api/client.ts","../src/realtime/ably-client.ts","../src/ui/i18n.ts","../src/ui/mount.ts","../src/ui/App.tsx","../src/ui/icons.tsx","../src/ui/components/ChatBubble.tsx","../src/ui/components/ChatWindow.tsx","../src/ui/components/ConversationList.tsx","../src/ui/components/MessageInput.tsx","../src/ui/components/MessageList.tsx","../src/ui/components/ImageLightbox.tsx","../src/ui/components/MessageMedia.tsx","../src/ui/components/PreChatForm.tsx","../src/ui/styles/widget-css.ts","../src/utils/events.ts","../src/utils/storage.ts","../src/widget.ts"],"sourcesContent":["import { BaseportalChat } from './widget'\n\nexport { BaseportalChat }\nexport type {\n BaseportalChatConfig,\n ChannelInfo,\n Conversation,\n Message,\n VisitorData,\n} from './api/types'\n\nexport default BaseportalChat\n","import type { ChannelInfo, Conversation, Message } from './types'\n\nexport class ApiClient {\n private baseUrl: string\n private channelToken: string\n private visitorEmail?: string\n private visitorHash?: string\n\n constructor(channelToken: string, apiUrl: string) {\n this.channelToken = channelToken\n this.baseUrl = `${apiUrl}/public/chat`\n }\n\n setVisitorIdentity(email: string, hash?: string): void {\n this.visitorEmail = email\n this.visitorHash = hash\n }\n\n clearVisitorIdentity(): void {\n this.visitorEmail = undefined\n this.visitorHash = undefined\n }\n\n private headers(): Record<string, string> {\n const h: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'x-channel-token': this.channelToken,\n }\n if (this.visitorEmail) h['x-visitor-email'] = this.visitorEmail\n if (this.visitorHash) h['x-visitor-hash'] = this.visitorHash\n return h\n }\n\n private async request<T>(\n method: string,\n path: string,\n body?: unknown\n ): Promise<T> {\n const res = await fetch(`${this.baseUrl}${path}`, {\n method,\n headers: this.headers(),\n body: body ? JSON.stringify(body) : undefined,\n })\n\n if (!res.ok) {\n const text = await res.text().catch(() => '')\n throw new Error(`[BaseportalChat] API error ${res.status}: ${text}`)\n }\n\n return res.json()\n }\n\n async getChannelInfo(): Promise<ChannelInfo> {\n return this.request('GET', '/channel-info')\n }\n\n async initConversation(data: {\n name?: string\n email?: string\n }): Promise<Conversation & { messages?: Message[] }> {\n return this.request('POST', '/conversations', {\n ...data,\n channelToken: this.channelToken,\n })\n }\n\n async getMessages(\n conversationId: string,\n params?: { limit?: number; page?: number }\n ): Promise<Message[]> {\n const qs = new URLSearchParams()\n if (params?.limit) qs.set('limit', String(params.limit))\n if (params?.page) qs.set('page', String(params.page))\n const query = qs.toString() ? `?${qs.toString()}` : ''\n return this.request('GET', `/conversations/${conversationId}/messages${query}`)\n }\n\n async uploadFile(conversationId: string, file: File): Promise<{ id: string; url: string; name: string; mimeType: string }> {\n const formData = new FormData()\n formData.append('file', file)\n\n const headers: Record<string, string> = {\n 'x-channel-token': this.channelToken,\n }\n if (this.visitorEmail) headers['x-visitor-email'] = this.visitorEmail\n if (this.visitorHash) headers['x-visitor-hash'] = this.visitorHash\n\n const res = await fetch(`${this.baseUrl}/conversations/${conversationId}/upload`, {\n method: 'POST',\n headers,\n body: formData,\n })\n\n if (!res.ok) {\n const text = await res.text().catch(() => '')\n throw new Error(`[BaseportalChat] Upload error ${res.status}: ${text}`)\n }\n\n return res.json()\n }\n\n async sendMessage(\n conversationId: string,\n data: { content?: string; mediaId?: string }\n ): Promise<Message> {\n return this.request(\n 'POST',\n `/conversations/${conversationId}/messages`,\n data\n )\n }\n\n async getVisitorConversations(): Promise<Conversation[]> {\n return this.request('GET', '/conversations')\n }\n\n async reopenConversation(conversationId: string): Promise<Conversation> {\n return this.request('POST', `/conversations/${conversationId}/reopen`)\n }\n\n async getAblyToken(conversationId: string): Promise<unknown> {\n return this.request('POST', '/ably-token', { conversationId })\n }\n}\n","import * as Ably from 'ably'\n\nimport type { ApiClient } from '../api/client'\nimport type { Conversation, Message } from '../api/types'\n\nexport interface RealtimeHandlers {\n onMessage: (message: Message) => void\n onConversationStatusUpdate: (conversation: Conversation) => void\n}\n\nexport class RealtimeClient {\n private client: Ably.Realtime | null = null\n private channel: Ably.RealtimeChannel | null = null\n private conversationId: string | null = null\n private apiClient: ApiClient\n private handlers: RealtimeHandlers | null = null\n\n constructor(apiClient: ApiClient) {\n this.apiClient = apiClient\n }\n\n async subscribe(\n conversationId: string,\n handlers: RealtimeHandlers\n ): Promise<void> {\n // Unsubscribe from previous if any\n this.unsubscribe()\n\n this.conversationId = conversationId\n this.handlers = handlers\n\n try {\n const tokenRequest = await this.apiClient.getAblyToken(conversationId)\n\n this.client = new Ably.Realtime({\n authCallback: (_data, callback) => {\n callback(null, tokenRequest as Ably.TokenRequest)\n },\n clientId: `visitor-${conversationId}`,\n })\n\n const channelName = `conversation-${conversationId}`\n this.channel = this.client.channels.get(channelName)\n\n this.channel.subscribe((msg) => {\n if (!msg.data) return\n\n try {\n const data =\n typeof msg.data === 'string' ? JSON.parse(msg.data) : msg.data\n\n if (data.text === 'conversation_status_updated' && data.metadata) {\n handlers.onConversationStatusUpdate(data.metadata as Conversation)\n } else if (\n data.text === 'created_or_updated_message' &&\n data.metadata\n ) {\n handlers.onMessage(data.metadata as Message)\n }\n } catch (e) {\n console.error('[BaseportalChat] Error parsing realtime message:', e)\n }\n })\n } catch (e) {\n console.error('[BaseportalChat] Error connecting to realtime:', e)\n }\n }\n\n unsubscribe(): void {\n if (this.channel) {\n this.channel.unsubscribe()\n this.channel = null\n }\n if (this.client) {\n this.client.close()\n this.client = null\n }\n this.conversationId = null\n this.handlers = null\n }\n\n isConnected(): boolean {\n return this.client?.connection.state === 'connected'\n }\n}\n","export interface Translations {\n prechat: {\n title: string\n description: string\n name: string\n namePlaceholder: string\n email: string\n emailPlaceholder: string\n start: string\n loading: string\n privacyPrefix: string\n privacyLink: string\n }\n chat: {\n placeholder: string\n closed: string\n reopen: string\n attachFile: string\n uploading: string\n fileTooLarge: string\n download: string\n }\n conversations: {\n title: string\n newConversation: string\n empty: string\n open: string\n closed: string\n noMessages: string\n }\n}\n\nconst pt: Translations = {\n prechat: {\n title: 'Iniciar conversa',\n description: 'Preencha os dados abaixo para iniciar o atendimento.',\n name: 'Nome',\n namePlaceholder: 'Seu nome',\n email: 'E-mail',\n emailPlaceholder: 'seu@email.com',\n start: 'Iniciar conversa',\n loading: 'Iniciando...',\n privacyPrefix: 'Ao enviar, você concorda com nossa',\n privacyLink: 'Política de Privacidade',\n },\n chat: {\n placeholder: 'Digite uma mensagem...',\n closed: 'Esta conversa foi encerrada.',\n reopen: 'Reabrir conversa',\n attachFile: 'Anexar arquivo',\n uploading: 'Enviando...',\n fileTooLarge: 'Arquivo muito grande (máx. 25MB)',\n download: 'Baixar',\n },\n conversations: {\n title: 'Atendimento',\n newConversation: 'Nova conversa',\n empty: 'Nenhuma conversa encontrada.',\n open: 'Aberta',\n closed: 'Fechada',\n noMessages: 'Nenhuma mensagem ainda',\n },\n}\n\nconst en: Translations = {\n prechat: {\n title: 'Start a conversation',\n description: 'Fill in the details below to start chatting.',\n name: 'Name',\n namePlaceholder: 'Your name',\n email: 'Email',\n emailPlaceholder: 'you@email.com',\n start: 'Start conversation',\n loading: 'Starting...',\n privacyPrefix: 'By sending, you agree to our',\n privacyLink: 'Privacy Policy',\n },\n chat: {\n placeholder: 'Type a message...',\n closed: 'This conversation has been closed.',\n reopen: 'Reopen conversation',\n attachFile: 'Attach file',\n uploading: 'Uploading...',\n fileTooLarge: 'File too large (max 25MB)',\n download: 'Download',\n },\n conversations: {\n title: 'Support',\n newConversation: 'New conversation',\n empty: 'No conversations found.',\n open: 'Open',\n closed: 'Closed',\n noMessages: 'No messages yet',\n },\n}\n\nconst es: Translations = {\n prechat: {\n title: 'Iniciar conversación',\n description: 'Complete los datos a continuación para iniciar la atención.',\n name: 'Nombre',\n namePlaceholder: 'Tu nombre',\n email: 'Correo electrónico',\n emailPlaceholder: 'tu@email.com',\n start: 'Iniciar conversación',\n loading: 'Iniciando...',\n privacyPrefix: 'Al enviar, aceptas nuestra',\n privacyLink: 'Política de Privacidad',\n },\n chat: {\n placeholder: 'Escribe un mensaje...',\n closed: 'Esta conversación ha sido cerrada.',\n reopen: 'Reabrir conversación',\n attachFile: 'Adjuntar archivo',\n uploading: 'Subiendo...',\n fileTooLarge: 'Archivo demasiado grande (máx. 25MB)',\n download: 'Descargar',\n },\n conversations: {\n title: 'Atención',\n newConversation: 'Nueva conversación',\n empty: 'No se encontraron conversaciones.',\n open: 'Abierta',\n closed: 'Cerrada',\n noMessages: 'Sin mensajes aún',\n },\n}\n\nconst locales: Record<string, Translations> = { pt, en, es }\n\nexport function getTranslations(locale: string): Translations {\n return locales[locale] || locales['pt']\n}\n","import { render, h } from 'preact'\n\nimport type { ApiClient } from '../api/client'\nimport type { ChannelInfo, VisitorData } from '../api/types'\nimport type { RealtimeClient } from '../realtime/ably-client'\nimport type { EventEmitter } from '../utils/events'\nimport type { Storage } from '../utils/storage'\nimport { App } from './App'\nimport type { Translations } from './i18n'\nimport widgetCSS from './styles/widget-css'\n\ninterface MountOptions {\n channelInfo: ChannelInfo\n apiClient: ApiClient\n realtimeClient: RealtimeClient\n storage: Storage\n events: EventEmitter\n visitor: VisitorData | null\n isAuthenticated: boolean\n position: 'bottom-right' | 'bottom-left'\n hidden: boolean\n t: Translations\n container?: HTMLElement\n isOpenRef: { current: boolean }\n setIsOpen: (open: boolean) => void\n}\n\nlet styleElement: HTMLStyleElement | null = null\nlet hostElement: HTMLElement | null = null\n\nexport function mount(options: MountOptions): void {\n // Inject styles into document head (once)\n if (!styleElement) {\n styleElement = document.createElement('style')\n styleElement.id = 'baseportal-chat-styles'\n styleElement.textContent = widgetCSS\n document.head.appendChild(styleElement)\n }\n\n // Create host element directly on body — no shadow DOM\n hostElement = document.createElement('div')\n hostElement.id = 'baseportal-chat-widget'\n const target = options.container || document.body\n target.appendChild(hostElement)\n\n // Apply primary color as CSS variable\n const primaryColor =\n options.channelInfo.theme?.primaryColor || '#6366f1'\n const contrastColor = getContrastColor(primaryColor)\n hostElement.style.setProperty('--bp-primary', primaryColor)\n hostElement.style.setProperty('--bp-primary-contrast', contrastColor)\n\n // Render Preact app\n render(\n h(App, {\n channelInfo: options.channelInfo,\n apiClient: options.apiClient,\n realtimeClient: options.realtimeClient,\n storage: options.storage,\n events: options.events,\n visitor: options.visitor,\n isAuthenticated: options.isAuthenticated,\n position: options.position,\n hidden: options.hidden,\n t: options.t,\n isOpenRef: options.isOpenRef,\n setIsOpen: options.setIsOpen,\n }),\n hostElement\n )\n}\n\nexport function unmount(): void {\n if (hostElement) {\n render(null, hostElement)\n hostElement.remove()\n hostElement = null\n }\n if (styleElement) {\n styleElement.remove()\n styleElement = null\n }\n}\n\nexport function updateTheme(primaryColor: string): void {\n if (!hostElement) return\n hostElement.style.setProperty('--bp-primary', primaryColor)\n hostElement.style.setProperty(\n '--bp-primary-contrast',\n getContrastColor(primaryColor)\n )\n}\n\nfunction getContrastColor(hex: string): string {\n const r = parseInt(hex.slice(1, 3), 16)\n const g = parseInt(hex.slice(3, 5), 16)\n const b = parseInt(hex.slice(5, 7), 16)\n const luminance =\n (0.299 * r + 0.587 * g + 0.114 * b) / 255\n return luminance > 0.5 ? '#000000' : '#ffffff'\n}\n","/** @jsxImportSource preact */\n\nimport { useEffect, useState } from 'preact/hooks'\n\nimport type { ApiClient } from '../api/client'\nimport type { ChannelInfo, VisitorData } from '../api/types'\nimport type { RealtimeClient } from '../realtime/ably-client'\nimport type { EventEmitter } from '../utils/events'\nimport type { Storage } from '../utils/storage'\nimport { ChatBubble } from './components/ChatBubble'\nimport { ChatWindow } from './components/ChatWindow'\nimport type { Translations } from './i18n'\n\ninterface AppProps {\n channelInfo: ChannelInfo\n apiClient: ApiClient\n realtimeClient: RealtimeClient\n storage: Storage\n events: EventEmitter\n visitor: VisitorData | null\n isAuthenticated: boolean\n position: 'bottom-right' | 'bottom-left'\n hidden: boolean\n t: Translations\n // Controlled state from widget class\n isOpenRef: { current: boolean }\n setIsOpen: (open: boolean) => void\n}\n\nexport function App({\n channelInfo,\n apiClient,\n realtimeClient,\n storage,\n events,\n visitor,\n isAuthenticated,\n position,\n hidden,\n t,\n isOpenRef,\n setIsOpen,\n}: AppProps) {\n const [isOpen, setIsOpenState] = useState(isOpenRef.current)\n const [isHidden, setIsHidden] = useState(hidden)\n const [unreadCount] = useState(0)\n\n // Listen for external open/close/show/hide from SDK\n useEffect(() => {\n const onOpen = () => {\n setIsOpenState(true)\n isOpenRef.current = true\n setIsOpen(true)\n }\n const onClose = () => {\n setIsOpenState(false)\n isOpenRef.current = false\n setIsOpen(false)\n }\n const onShow = () => setIsHidden(false)\n const onHide = () => {\n setIsHidden(true)\n setIsOpenState(false)\n isOpenRef.current = false\n setIsOpen(false)\n }\n\n events.on('_open', onOpen)\n events.on('_close', onClose)\n events.on('show', onShow)\n events.on('hide', onHide)\n\n return () => {\n events.off('_open', onOpen)\n events.off('_close', onClose)\n events.off('show', onShow)\n events.off('hide', onHide)\n }\n }, [events, isOpenRef, setIsOpen])\n\n const handleToggle = () => {\n const next = !isOpen\n setIsOpenState(next)\n isOpenRef.current = next\n setIsOpen(next)\n events.emit(next ? 'open' : 'close')\n }\n\n const handleClose = () => {\n setIsOpenState(false)\n isOpenRef.current = false\n setIsOpen(false)\n events.emit('close')\n }\n\n return (\n <>\n {!isHidden && (\n <ChatBubble\n isOpen={isOpen}\n position={position}\n unreadCount={unreadCount}\n onClick={handleToggle}\n />\n )}\n {isOpen && (\n <ChatWindow\n channelInfo={channelInfo}\n apiClient={apiClient}\n realtimeClient={realtimeClient}\n storage={storage}\n events={events}\n visitor={visitor}\n isAuthenticated={isAuthenticated}\n position={position}\n onClose={handleClose}\n t={t}\n />\n )}\n </>\n )\n}\n","/** @jsxImportSource preact */\n\nexport const IconChat = () => (\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\" />\n </svg>\n)\n\nexport const IconX = () => (\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n)\n\nexport const IconArrowLeft = () => (\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <line x1=\"19\" y1=\"12\" x2=\"5\" y2=\"12\" />\n <polyline points=\"12 19 5 12 12 5\" />\n </svg>\n)\n\nexport const IconSend = () => (\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <line x1=\"22\" y1=\"2\" x2=\"11\" y2=\"13\" />\n <polygon points=\"22 2 15 22 11 13 2 9 22 2\" />\n </svg>\n)\n\nexport const IconPlus = () => (\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\" />\n <line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\" />\n </svg>\n)\n\nexport const IconPaperclip = () => (\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M21.44 11.05l-9.19 9.19a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66l-9.2 9.19a2 2 0 0 1-2.83-2.83l8.49-8.48\" />\n </svg>\n)\n\nexport const IconDownload = () => (\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\" />\n <polyline points=\"7 10 12 15 17 10\" />\n <line x1=\"12\" y1=\"15\" x2=\"12\" y2=\"3\" />\n </svg>\n)\n\nexport const IconFile = () => (\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\" />\n <polyline points=\"14 2 14 8 20 8\" />\n </svg>\n)\n","/** @jsxImportSource preact */\n\nimport { IconChat, IconX } from '../icons'\n\ninterface ChatBubbleProps {\n isOpen: boolean\n position: 'bottom-right' | 'bottom-left'\n unreadCount: number\n onClick: () => void\n}\n\nexport function ChatBubble({\n isOpen,\n position,\n unreadCount,\n onClick,\n}: ChatBubbleProps) {\n const posClass =\n position === 'bottom-left' ? 'bp-bubble--left' : 'bp-bubble--right'\n\n return (\n <button\n class={`bp-bubble ${posClass}`}\n onClick={onClick}\n aria-label={isOpen ? 'Close chat' : 'Open chat'}\n >\n {isOpen ? <IconX /> : <IconChat />}\n {!isOpen && unreadCount > 0 && (\n <span class=\"bp-bubble__badge\">\n {unreadCount > 99 ? '99+' : unreadCount}\n </span>\n )}\n </button>\n )\n}\n","/** @jsxImportSource preact */\n\nimport { useCallback, useEffect, useState } from 'preact/hooks'\n\nimport type { ApiClient } from '../../api/client'\nimport type {\n ChannelInfo,\n Conversation,\n Message,\n VisitorData,\n} from '../../api/types'\nimport type { RealtimeClient } from '../../realtime/ably-client'\nimport type { EventEmitter } from '../../utils/events'\nimport type { Storage } from '../../utils/storage'\nimport { IconArrowLeft, IconX } from '../icons'\nimport type { Translations } from '../i18n'\nimport { ConversationList } from './ConversationList'\nimport { MessageInput, type AttachedFile } from './MessageInput'\nimport { MessageList } from './MessageList'\nimport { PreChatForm } from './PreChatForm'\n\ntype View = 'prechat' | 'conversations' | 'chat'\n\ninterface ChatWindowProps {\n channelInfo: ChannelInfo\n apiClient: ApiClient\n realtimeClient: RealtimeClient\n storage: Storage\n events: EventEmitter\n visitor: VisitorData | null\n isAuthenticated: boolean\n position: 'bottom-right' | 'bottom-left'\n onClose: () => void\n t: Translations\n initialConversationId?: string | null\n}\n\nexport function ChatWindow({\n channelInfo,\n apiClient,\n realtimeClient,\n storage,\n events,\n visitor,\n isAuthenticated,\n position,\n onClose,\n t,\n initialConversationId,\n}: ChatWindowProps) {\n const [view, setView] = useState<View>('chat')\n const [conversation, setConversation] = useState<Conversation | null>(null)\n const [conversations, setConversations] = useState<Conversation[]>([])\n const [messages, setMessages] = useState<Message[]>([])\n const [inputValue, setInputValue] = useState('')\n const [loading, setLoading] = useState(true)\n const [sending, setSending] = useState(false)\n const [attachedFile, setAttachedFile] = useState<AttachedFile | null>(null)\n const [uploadedFileId, setUploadedFileId] = useState<string | null>(null)\n const [uploading, setUploading] = useState(false)\n\n const isOpen = conversation?.open !== false\n\n const allowViewHistory = channelInfo.config.allowViewHistory && isAuthenticated\n\n // Determine initial view\n useEffect(() => {\n const init = async () => {\n setLoading(true)\n try {\n if (allowViewHistory) {\n // History mode: load conversation list\n const convs = await apiClient.getVisitorConversations()\n setConversations(convs)\n\n if (initialConversationId) {\n const conv = convs.find((c) => c.id === initialConversationId)\n if (conv) {\n await openConversation(conv)\n return\n }\n }\n\n if (convs.length > 0) {\n setView('conversations')\n } else {\n if (needsPreChat()) {\n setView('prechat')\n } else {\n await startNewConversation()\n }\n }\n } else {\n // No history: check localStorage for existing conversation\n const storedId =\n initialConversationId || storage.getConversationId()\n\n if (storedId) {\n try {\n const msgs = await apiClient.getMessages(storedId, { limit: 50 })\n setMessages(Array.isArray(msgs) ? msgs.reverse() : [])\n setConversation({ id: storedId, open: true } as Conversation)\n setView('chat')\n connectRealtime(storedId)\n } catch {\n storage.clear()\n if (needsPreChat()) {\n setView('prechat')\n } else {\n await startNewConversation()\n }\n }\n } else {\n if (needsPreChat()) {\n setView('prechat')\n } else {\n await startNewConversation()\n }\n }\n }\n } catch (e) {\n console.error('[BaseportalChat] Error initializing:', e)\n } finally {\n setLoading(false)\n }\n }\n\n init()\n\n return () => {\n realtimeClient.unsubscribe()\n }\n }, [])\n\n const needsPreChat = useCallback((): boolean => {\n if (visitor?.name && visitor?.email) return false\n return (\n channelInfo.config.requireName || channelInfo.config.requireEmail\n )\n }, [channelInfo, visitor])\n\n const connectRealtime = useCallback(\n (convId: string) => {\n realtimeClient.subscribe(convId, {\n onMessage: (msg) => {\n setMessages((prev) => {\n if (prev.some((m) => m.id === msg.id)) {\n return prev.map((m) =>\n m.id === msg.id ? { ...m, ...msg } : m\n )\n }\n const withoutTemp = prev.filter(\n (m) =>\n !String(m.id).startsWith('temp-') ||\n m.content !== msg.content\n )\n return [...withoutTemp, msg]\n })\n events.emit('message:received', msg)\n },\n onConversationStatusUpdate: (conv) => {\n setConversation((prev) =>\n prev ? { ...prev, open: conv.open } : prev\n )\n if (!conv.open) {\n events.emit('conversation:closed', conv)\n }\n },\n })\n },\n [realtimeClient, events]\n )\n\n const openConversation = useCallback(\n async (conv: Conversation) => {\n setLoading(true)\n try {\n const msgs = await apiClient.getMessages(conv.id, { limit: 50 })\n setMessages(Array.isArray(msgs) ? msgs.reverse() : [])\n setConversation(conv)\n setView('chat')\n storage.setConversationId(conv.id)\n connectRealtime(conv.id)\n } catch (e) {\n console.error('[BaseportalChat] Error opening conversation:', e)\n } finally {\n setLoading(false)\n }\n },\n [apiClient, storage, connectRealtime]\n )\n\n const startNewConversation = useCallback(async () => {\n setLoading(true)\n try {\n const result = await apiClient.initConversation({\n name: visitor?.name,\n email: visitor?.email,\n })\n setConversation(result)\n setMessages(result.messages || [])\n setView('chat')\n storage.setConversationId(result.id)\n connectRealtime(result.id)\n events.emit('conversation:started', result)\n } catch (e) {\n console.error('[BaseportalChat] Error starting conversation:', e)\n } finally {\n setLoading(false)\n }\n }, [apiClient, visitor, storage, connectRealtime, events])\n\n const handlePreChatSubmit = useCallback(\n async (data: { name?: string; email?: string }) => {\n storage.setVisitor({ ...visitor, ...data })\n const result = await apiClient.initConversation(data)\n setConversation(result)\n setMessages(result.messages || [])\n setView('chat')\n storage.setConversationId(result.id)\n connectRealtime(result.id)\n events.emit('conversation:started', result)\n },\n [apiClient, visitor, storage, connectRealtime, events]\n )\n\n const handleFileSelect = useCallback(\n async (file: File) => {\n if (!conversation) return\n\n const MAX_SIZE = 25 * 1024 * 1024\n if (file.size > MAX_SIZE) {\n console.warn('[BaseportalChat] File too large')\n return\n }\n\n const preview = file.type.startsWith('image/')\n ? URL.createObjectURL(file)\n : undefined\n\n setAttachedFile({ file, preview })\n setUploading(true)\n\n try {\n const uploaded = await apiClient.uploadFile(conversation.id, file)\n setUploadedFileId(uploaded.id)\n } catch (e) {\n console.error('[BaseportalChat] Error uploading file:', e)\n setAttachedFile(null)\n if (preview) URL.revokeObjectURL(preview)\n } finally {\n setUploading(false)\n }\n },\n [apiClient, conversation]\n )\n\n const handleFileRemove = useCallback(() => {\n if (attachedFile?.preview) URL.revokeObjectURL(attachedFile.preview)\n setAttachedFile(null)\n setUploadedFileId(null)\n }, [attachedFile])\n\n const handleSend = useCallback(async () => {\n const content = inputValue.trim()\n if ((!content && !uploadedFileId) || !conversation || sending) return\n\n const tempId = `temp-${Date.now()}`\n const optimistic: Message = {\n id: tempId,\n content,\n role: 'client',\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n }\n\n const mediaId = uploadedFileId || undefined\n\n setInputValue('')\n setAttachedFile(null)\n setUploadedFileId(null)\n setSending(true)\n setMessages((prev) => [...prev, optimistic])\n\n try {\n const msg = await apiClient.sendMessage(conversation.id, {\n content: content || undefined,\n mediaId,\n })\n setMessages((prev) => prev.map((m) => (m.id === tempId ? msg : m)))\n events.emit('message:sent', msg)\n } catch (e) {\n console.error('[BaseportalChat] Error sending message:', e)\n setMessages((prev) => prev.filter((m) => m.id !== tempId))\n setInputValue(content)\n } finally {\n setSending(false)\n }\n }, [inputValue, uploadedFileId, conversation, sending, apiClient, events])\n\n const handleReopen = useCallback(async () => {\n if (!conversation) return\n try {\n const updated = await apiClient.reopenConversation(conversation.id)\n setConversation((prev) => prev ? { ...prev, open: updated.open ?? true } : prev)\n } catch (e) {\n console.error('[BaseportalChat] Error reopening conversation:', e)\n }\n }, [conversation, apiClient])\n\n const handleBack = useCallback(() => {\n if (allowViewHistory && view === 'chat') {\n realtimeClient.unsubscribe()\n setView('conversations')\n setConversation(null)\n setMessages([])\n apiClient.getVisitorConversations().then(setConversations).catch(() => {})\n } else {\n onClose()\n }\n }, [allowViewHistory, view, realtimeClient, apiClient, onClose])\n\n const posClass =\n position === 'bottom-left' ? 'bp-window--left' : 'bp-window--right'\n\n const headerTitle =\n view === 'conversations'\n ? t.conversations.title\n : channelInfo.name\n\n const showBack =\n (allowViewHistory && view === 'chat') || view === 'prechat'\n\n return (\n <div class={`bp-window ${posClass}`}>\n {/* Header */}\n <div class=\"bp-header\">\n <div class=\"bp-header__title\">\n {showBack && (\n <button class=\"bp-header__back\" onClick={handleBack}>\n <IconArrowLeft />\n </button>\n )}\n {headerTitle}\n </div>\n <button class=\"bp-header__close\" onClick={onClose}>\n <IconX />\n </button>\n </div>\n\n {/* Content */}\n {loading && view !== 'chat' ? (\n <div class=\"bp-loading\">\n <div class=\"bp-spinner\" />\n </div>\n ) : (\n <>\n {view === 'prechat' && (\n <PreChatForm\n channelInfo={channelInfo}\n onSubmit={handlePreChatSubmit}\n loading={loading}\n t={t}\n />\n )}\n\n {view === 'conversations' && (\n <ConversationList\n conversations={conversations}\n channelInfo={channelInfo}\n loading={loading}\n onSelect={openConversation}\n onNew={\n needsPreChat()\n ? () => setView('prechat')\n : startNewConversation\n }\n t={t}\n />\n )}\n\n {view === 'chat' && (\n <>\n <MessageList messages={messages} loading={loading} t={t} />\n {isOpen ? (\n <MessageInput\n value={inputValue}\n onChange={setInputValue}\n onSend={handleSend}\n onFileSelect={handleFileSelect}\n onFileRemove={handleFileRemove}\n attachedFile={attachedFile}\n uploading={uploading}\n disabled={sending || loading}\n placeholder={t.chat.placeholder}\n t={t}\n />\n ) : (\n <div class=\"bp-closed-banner\">\n <span class=\"bp-closed-banner__text\">{t.chat.closed}</span>\n {channelInfo.config.allowReopenConversation && (\n <button class=\"bp-closed-banner__reopen\" onClick={handleReopen}>\n {t.chat.reopen}\n </button>\n )}\n </div>\n )}\n {channelInfo.config.privacyPolicyUrl && (\n <div class=\"bp-privacy-footer\">\n <a\n href={channelInfo.config.privacyPolicyUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n {t.prechat.privacyLink}\n </a>\n </div>\n )}\n </>\n )}\n </>\n )}\n </div>\n )\n}\n","/** @jsxImportSource preact */\n\nimport type { ChannelInfo, Conversation } from '../../api/types'\nimport { IconPlus } from '../icons'\nimport type { Translations } from '../i18n'\n\ninterface ConversationListProps {\n conversations: Conversation[]\n channelInfo: ChannelInfo\n loading: boolean\n onSelect: (conversation: Conversation) => void\n onNew: () => void\n t: Translations\n}\n\nexport function ConversationList({\n conversations,\n channelInfo,\n loading,\n onSelect,\n onNew,\n t,\n}: ConversationListProps) {\n const hasOpen = conversations.some((c) => c.open)\n const canReopen = channelInfo.config.allowReopenConversation\n\n if (loading) {\n return (\n <div class=\"bp-loading\">\n <div class=\"bp-spinner\" />\n </div>\n )\n }\n\n return (\n <div class=\"bp-convlist\">\n {!hasOpen && (\n <div class=\"bp-convlist__new\">\n <button class=\"bp-convlist__new-btn\" onClick={onNew}>\n <IconPlus />\n {t.conversations.newConversation}\n </button>\n </div>\n )}\n\n <div class=\"bp-convlist__items\">\n {conversations.length === 0 ? (\n <div class=\"bp-convlist__empty\">{t.conversations.empty}</div>\n ) : (\n conversations.map((conv) => {\n const isClickable = conv.open || canReopen\n\n return (\n <button\n key={conv.id}\n class=\"bp-convlist__item\"\n onClick={() => isClickable && onSelect(conv)}\n disabled={!isClickable}\n >\n <div class=\"bp-convlist__item-top\">\n <span class=\"bp-convlist__item-title\">\n {channelInfo.name}\n </span>\n <span\n class={`bp-convlist__item-status ${conv.open ? 'bp-convlist__item-status--open' : 'bp-convlist__item-status--closed'}`}\n >\n {conv.open ? t.conversations.open : t.conversations.closed}\n </span>\n </div>\n <span class=\"bp-convlist__item-preview\">\n {conv.lastMessage?.content || t.conversations.noMessages}\n </span>\n </button>\n )\n })\n )}\n </div>\n </div>\n )\n}\n","/** @jsxImportSource preact */\n\nimport { useCallback, useRef } from 'preact/hooks'\n\nimport { IconFile, IconPaperclip, IconSend, IconX } from '../icons'\nimport type { Translations } from '../i18n'\n\nexport interface AttachedFile {\n file: File\n preview?: string\n}\n\ninterface MessageInputProps {\n value: string\n onChange: (value: string) => void\n onSend: () => void\n onFileSelect: (file: File) => void\n onFileRemove: () => void\n attachedFile: AttachedFile | null\n uploading: boolean\n disabled: boolean\n placeholder?: string\n t: Translations\n}\n\nexport function MessageInput({\n value,\n onChange,\n onSend,\n onFileSelect,\n onFileRemove,\n attachedFile,\n uploading,\n disabled,\n placeholder,\n t,\n}: MessageInputProps) {\n const textareaRef = useRef<HTMLTextAreaElement>(null)\n const fileInputRef = useRef<HTMLInputElement>(null)\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent) => {\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault()\n onSend()\n }\n },\n [onSend]\n )\n\n const handleInput = useCallback(\n (e: Event) => {\n const target = e.target as HTMLTextAreaElement\n onChange(target.value)\n target.style.height = 'auto'\n target.style.height = `${Math.min(target.scrollHeight, 100)}px`\n },\n [onChange]\n )\n\n const handleAttachClick = useCallback(() => {\n fileInputRef.current?.click()\n }, [])\n\n const handleFileChange = useCallback(\n (e: Event) => {\n const input = e.target as HTMLInputElement\n const file = input.files?.[0]\n if (file) {\n onFileSelect(file)\n }\n input.value = ''\n },\n [onFileSelect]\n )\n\n const isImage = attachedFile?.file.type.startsWith('image/')\n const canSend = (value.trim() || attachedFile) && !disabled && !uploading\n\n return (\n <div class=\"bp-composer\">\n {attachedFile && (\n <div class=\"bp-composer__preview\">\n {isImage && attachedFile.preview ? (\n <img\n src={attachedFile.preview}\n alt={attachedFile.file.name}\n class=\"bp-composer__preview-thumb\"\n />\n ) : (\n <div class=\"bp-composer__preview-icon\">\n <IconFile />\n </div>\n )}\n <div class=\"bp-composer__preview-info\">\n <div class=\"bp-composer__preview-name\">\n {attachedFile.file.name}\n </div>\n <div class=\"bp-composer__preview-status\">\n {uploading ? t.chat.uploading : formatSize(attachedFile.file.size)}\n </div>\n </div>\n {!uploading && (\n <button\n class=\"bp-composer__preview-remove\"\n onClick={onFileRemove}\n aria-label=\"Remove file\"\n >\n <IconX />\n </button>\n )}\n </div>\n )}\n\n <div class=\"bp-composer__row\">\n <button\n class=\"bp-composer__attach\"\n onClick={handleAttachClick}\n disabled={disabled || uploading || !!attachedFile}\n aria-label={t.chat.attachFile}\n >\n <IconPaperclip />\n </button>\n\n <textarea\n ref={textareaRef}\n class=\"bp-composer__field\"\n value={value}\n onInput={handleInput}\n onKeyDown={handleKeyDown}\n placeholder={placeholder || t.chat.placeholder}\n disabled={disabled}\n rows={1}\n />\n\n <button\n class=\"bp-composer__send\"\n onClick={onSend}\n disabled={!canSend}\n aria-label=\"Send message\"\n >\n <IconSend />\n </button>\n </div>\n\n <input\n type=\"file\"\n ref={fileInputRef}\n onChange={handleFileChange}\n style={{ display: 'none' }}\n accept=\"image/*,video/mp4,audio/*,.pdf,.doc,.docx,.xls,.xlsx,.txt\"\n />\n </div>\n )\n}\n\nfunction formatSize(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(0)} KB`\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`\n}\n","/** @jsxImportSource preact */\n\nimport { useEffect, useRef, useState } from 'preact/hooks'\n\nimport type { Message } from '../../api/types'\nimport type { Translations } from '../i18n'\nimport { ImageLightbox } from './ImageLightbox'\nimport { MessageMedia } from './MessageMedia'\n\ninterface MessageListProps {\n messages: Message[]\n loading: boolean\n t: Translations\n}\n\nexport function MessageList({ messages, loading, t }: MessageListProps) {\n const endRef = useRef<HTMLDivElement>(null)\n const [lightboxSrc, setLightboxSrc] = useState<string | null>(null)\n\n useEffect(() => {\n endRef.current?.scrollIntoView({ behavior: 'smooth' })\n }, [messages])\n\n if (loading) {\n return (\n <div class=\"bp-loading\">\n <div class=\"bp-spinner\" />\n </div>\n )\n }\n\n return (\n <div class=\"bp-messages\">\n {messages.map((msg) => (\n <MessageBubble\n key={msg.id}\n message={msg}\n onImageClick={setLightboxSrc}\n t={t}\n />\n ))}\n <div ref={endRef} />\n {lightboxSrc && (\n <ImageLightbox\n src={lightboxSrc}\n onClose={() => setLightboxSrc(null)}\n />\n )}\n </div>\n )\n}\n\nfunction MessageBubble({\n message,\n onImageClick,\n t,\n}: {\n message: Message\n onImageClick: (src: string) => void\n t: Translations\n}) {\n const isClient = message.role === 'client'\n const cls = isClient ? 'bp-msg bp-msg--client' : 'bp-msg bp-msg--agent'\n\n const time = new Date(message.createdAt).toLocaleTimeString([], {\n hour: '2-digit',\n minute: '2-digit',\n })\n\n return (\n <div class={cls}>\n {!isClient && (\n <div class=\"bp-msg__avatar\">\n {message.user?.avatar?.url ? (\n <img\n src={message.user.avatar.url}\n alt={message.user.firstName || 'Agent'}\n />\n ) : (\n (message.user?.firstName?.[0] || 'A').toUpperCase()\n )}\n </div>\n )}\n <div class=\"bp-msg__body\">\n {message.media && (\n <MessageMedia\n media={message.media}\n onImageClick={onImageClick}\n t={t}\n />\n )}\n {message.content && (\n <div class=\"bp-msg__content\">{message.content}</div>\n )}\n <div class=\"bp-msg__time\">{time}</div>\n </div>\n </div>\n )\n}\n","/** @jsxImportSource preact */\n\nimport { useCallback, useEffect } from 'preact/hooks'\n\nimport { IconX } from '../icons'\n\ninterface ImageLightboxProps {\n src: string\n alt?: string\n onClose: () => void\n}\n\nexport function ImageLightbox({ src, alt, onClose }: ImageLightboxProps) {\n const handleKeyDown = useCallback(\n (e: KeyboardEvent) => {\n if (e.key === 'Escape') onClose()\n },\n [onClose]\n )\n\n useEffect(() => {\n document.addEventListener('keydown', handleKeyDown)\n return () => document.removeEventListener('keydown', handleKeyDown)\n }, [handleKeyDown])\n\n return (\n <div class=\"bp-lightbox\" onClick={onClose}>\n <button class=\"bp-lightbox__close\" onClick={onClose}>\n <IconX />\n </button>\n <img\n src={src}\n alt={alt || ''}\n class=\"bp-lightbox__img\"\n onClick={(e) => e.stopPropagation()}\n />\n </div>\n )\n}\n","/** @jsxImportSource preact */\n\nimport type { Message } from '../../api/types'\nimport { IconDownload, IconFile } from '../icons'\nimport type { Translations } from '../i18n'\n\ninterface MessageMediaProps {\n media: NonNullable<Message['media']>\n onImageClick: (src: string) => void\n t: Translations\n}\n\nexport function MessageMedia({ media, onImageClick, t }: MessageMediaProps) {\n const mimeType = (media.mimeType || '').toLowerCase()\n\n if (mimeType.startsWith('image/') || media.kind === 'image') {\n const thumbSrc = media.streamUrlData?.small || media.url\n const fullSrc = media.streamUrlData?.large || media.url\n return (\n <img\n src={thumbSrc}\n alt={media.name}\n class=\"bp-media-img\"\n onClick={() => onImageClick(fullSrc)}\n />\n )\n }\n\n if (mimeType.startsWith('video/')) {\n return (\n <video controls class=\"bp-media-video\" preload=\"metadata\">\n <source src={media.url} type={mimeType} />\n </video>\n )\n }\n\n return (\n <a\n href={media.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n class=\"bp-media-file\"\n download={media.name}\n >\n <div class=\"bp-media-file__icon\">\n <IconFile />\n </div>\n <span class=\"bp-media-file__name\">{media.name}</span>\n <span class=\"bp-media-file__download\">\n <IconDownload />\n </span>\n </a>\n )\n}\n","/** @jsxImportSource preact */\n\nimport { useState } from 'preact/hooks'\n\nimport type { ChannelInfo } from '../../api/types'\nimport type { Translations } from '../i18n'\n\ninterface PreChatFormProps {\n channelInfo: ChannelInfo\n onSubmit: (data: { name?: string; email?: string }) => void\n loading: boolean\n t: Translations\n}\n\nexport function PreChatForm({\n channelInfo,\n onSubmit,\n loading,\n t,\n}: PreChatFormProps) {\n const [name, setName] = useState('')\n const [email, setEmail] = useState('')\n\n const { requireName, requireEmail, privacyPolicyUrl } = channelInfo.config\n\n const handleSubmit = (e: Event) => {\n e.preventDefault()\n onSubmit({\n name: name.trim() || undefined,\n email: email.trim() || undefined,\n })\n }\n\n const isValid =\n (!requireName || name.trim()) && (!requireEmail || email.trim())\n\n return (\n <form class=\"bp-prechat\" onSubmit={handleSubmit}>\n <div class=\"bp-prechat__title\">{t.prechat.title}</div>\n <div class=\"bp-prechat__desc\">{t.prechat.description}</div>\n\n {requireName && (\n <div class=\"bp-prechat__field\">\n <label class=\"bp-prechat__label\">{t.prechat.name}</label>\n <input\n class=\"bp-prechat__input\"\n type=\"text\"\n value={name}\n onInput={(e) => setName((e.target as HTMLInputElement).value)}\n placeholder={t.prechat.namePlaceholder}\n required\n />\n </div>\n )}\n\n {requireEmail && (\n <div class=\"bp-prechat__field\">\n <label class=\"bp-prechat__label\">{t.prechat.email}</label>\n <input\n class=\"bp-prechat__input\"\n type=\"email\"\n value={email}\n onInput={(e) => setEmail((e.target as HTMLInputElement).value)}\n placeholder={t.prechat.emailPlaceholder}\n required\n />\n </div>\n )}\n\n <button\n class=\"bp-prechat__submit\"\n type=\"submit\"\n disabled={!isValid || loading}\n >\n {loading ? t.prechat.loading : t.prechat.start}\n </button>\n\n {privacyPolicyUrl && (\n <div class=\"bp-prechat__privacy\">\n {t.prechat.privacyPrefix}{' '}\n <a href={privacyPolicyUrl} target=\"_blank\" rel=\"noopener noreferrer\">\n {t.prechat.privacyLink}\n </a>\n </div>\n )}\n </form>\n )\n}\n","// CSS exported as a string to prevent tsup from extracting it to a separate file.\n// This ensures the CSS is inlined in the JS bundle.\nexport default `#baseportal-chat-widget {\n display: block;\n position: static;\n width: 0;\n height: 0;\n overflow: visible;\n padding: 0;\n margin: 0;\n border: none;\n\n --bp-primary: #6366f1;\n --bp-primary-contrast: #ffffff;\n --bp-font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,\n 'Helvetica Neue', Arial, sans-serif;\n --bp-radius: 16px;\n --bp-radius-sm: 8px;\n --bp-bubble-size: 60px;\n --bp-shadow: 0 4px 24px rgba(0, 0, 0, 0.15);\n --bp-shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.1);\n --bp-gray-50: #f9fafb;\n --bp-gray-100: #f3f4f6;\n --bp-gray-200: #e5e7eb;\n --bp-gray-300: #d1d5db;\n --bp-gray-500: #6b7280;\n --bp-gray-700: #374151;\n --bp-gray-900: #111827;\n --bp-transition: 0.2s ease;\n}\n\n#baseportal-chat-widget *,\n#baseportal-chat-widget *::before,\n#baseportal-chat-widget *::after {\n box-sizing: border-box;\n}\n\n/* ===== Chat Bubble (FAB) ===== */\n.bp-bubble {\n pointer-events: auto;\n position: fixed;\n bottom: 24px;\n z-index: 2147483646;\n width: var(--bp-bubble-size);\n height: var(--bp-bubble-size);\n border-radius: 50%;\n background: var(--bp-primary);\n color: var(--bp-primary-contrast);\n border: none;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n box-shadow: var(--bp-shadow);\n transition: transform var(--bp-transition), box-shadow var(--bp-transition);\n font-family: var(--bp-font-family);\n font-size: 14px;\n line-height: 1.5;\n margin: 0;\n padding: 0;\n}\n\n.bp-bubble:hover {\n transform: scale(1.08);\n box-shadow: 0 6px 32px rgba(0, 0, 0, 0.2);\n}\n\n.bp-bubble--right {\n right: 24px;\n}\n\n.bp-bubble--left {\n left: 24px;\n}\n\n.bp-bubble svg {\n width: 28px;\n height: 28px;\n fill: currentColor;\n}\n\n.bp-bubble__badge {\n position: absolute;\n top: -2px;\n right: -2px;\n min-width: 20px;\n height: 20px;\n border-radius: 10px;\n background: #ef4444;\n color: #fff;\n font-size: 11px;\n font-weight: 600;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0 5px;\n}\n\n/* ===== Chat Window ===== */\n.bp-window {\n pointer-events: auto;\n position: fixed;\n bottom: 96px;\n z-index: 2147483647;\n width: 380px;\n height: 520px;\n border-radius: var(--bp-radius);\n background: #fff;\n box-shadow: var(--bp-shadow);\n display: flex;\n flex-direction: column;\n overflow: hidden;\n animation: bp-slide-up 0.25s ease-out;\n font-family: var(--bp-font-family);\n font-size: 14px;\n line-height: 1.5;\n color: var(--bp-gray-900);\n}\n\n.bp-window--right {\n right: 24px;\n}\n\n.bp-window--left {\n left: 24px;\n}\n\n@keyframes bp-slide-up {\n from {\n opacity: 0;\n transform: translateY(16px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n/* Mobile fullscreen */\n@media (max-width: 480px) {\n .bp-window {\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n width: 100%;\n height: 100%;\n border-radius: 0;\n }\n}\n\n/* ===== Header ===== */\n.bp-header {\n padding: 16px;\n background: var(--bp-primary);\n color: var(--bp-primary-contrast);\n display: flex;\n align-items: center;\n justify-content: space-between;\n flex-shrink: 0;\n}\n\n.bp-header__title {\n font-size: 16px;\n font-weight: 600;\n color: inherit;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.bp-header__back,\n.bp-header__close {\n background: none;\n border: none;\n color: inherit;\n cursor: pointer;\n padding: 4px;\n border-radius: 4px;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: background var(--bp-transition);\n}\n\n.bp-header__back:hover,\n.bp-header__close:hover {\n background: rgba(255, 255, 255, 0.15);\n}\n\n.bp-header__back svg,\n.bp-header__close svg {\n width: 18px;\n height: 18px;\n fill: currentColor;\n}\n\n/* ===== Message List ===== */\n.bp-messages {\n flex: 1;\n overflow-y: auto;\n padding: 16px;\n display: flex;\n flex-direction: column;\n gap: 8px;\n background: var(--bp-gray-50);\n}\n\n.bp-messages::-webkit-scrollbar {\n width: 4px;\n}\n\n.bp-messages::-webkit-scrollbar-thumb {\n background: var(--bp-gray-300);\n border-radius: 2px;\n}\n\n/* ===== Message Bubble ===== */\n.bp-msg {\n display: flex;\n max-width: 80%;\n}\n\n.bp-msg--client {\n align-self: flex-end;\n flex-direction: row-reverse;\n}\n\n.bp-msg--agent {\n align-self: flex-start;\n}\n\n.bp-msg__avatar {\n width: 28px;\n height: 28px;\n border-radius: 50%;\n background: var(--bp-primary);\n color: var(--bp-primary-contrast);\n font-size: 12px;\n font-weight: 600;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n margin-top: auto;\n}\n\n.bp-msg__avatar img {\n width: 100%;\n height: 100%;\n border-radius: 50%;\n object-fit: cover;\n}\n\n.bp-msg__body {\n margin: 0 8px;\n}\n\n.bp-msg__content {\n padding: 10px 14px;\n border-radius: 16px;\n white-space: pre-wrap;\n word-break: break-word;\n font-size: 14px;\n line-height: 1.4;\n}\n\n.bp-msg--client .bp-msg__content {\n background: var(--bp-primary);\n color: var(--bp-primary-contrast);\n border-bottom-right-radius: 4px;\n}\n\n.bp-msg--agent .bp-msg__content {\n background: var(--bp-gray-100);\n color: var(--bp-gray-900);\n border-bottom-left-radius: 4px;\n}\n\n.bp-msg__time {\n font-size: 11px;\n color: var(--bp-gray-500);\n margin-top: 2px;\n padding: 0 4px;\n}\n\n.bp-msg--client .bp-msg__time {\n text-align: right;\n}\n\n/* ===== Composer (Message Input) ===== */\n.bp-composer {\n margin: 8px 12px 12px;\n border: 1px solid var(--bp-gray-200);\n border-radius: 12px;\n background: #fff;\n flex-shrink: 0;\n overflow: hidden;\n transition: border-color var(--bp-transition);\n}\n\n.bp-composer:focus-within {\n border-color: var(--bp-primary);\n}\n\n.bp-composer__preview {\n padding: 8px 12px;\n border-bottom: 1px solid var(--bp-gray-100);\n display: flex;\n align-items: center;\n gap: 8px;\n background: var(--bp-gray-50);\n}\n\n.bp-composer__preview-thumb {\n width: 40px;\n height: 40px;\n border-radius: 6px;\n object-fit: cover;\n flex-shrink: 0;\n}\n\n.bp-composer__preview-icon {\n width: 36px;\n height: 36px;\n border-radius: 6px;\n background: var(--bp-gray-100);\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n color: var(--bp-gray-500);\n}\n\n.bp-composer__preview-icon svg {\n width: 18px;\n height: 18px;\n}\n\n.bp-composer__preview-info {\n flex: 1;\n min-width: 0;\n}\n\n.bp-composer__preview-name {\n font-size: 12px;\n font-weight: 500;\n color: var(--bp-gray-700);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.bp-composer__preview-status {\n font-size: 11px;\n color: var(--bp-gray-500);\n}\n\n.bp-composer__preview-remove {\n background: none;\n border: none;\n cursor: pointer;\n padding: 2px;\n color: var(--bp-gray-500);\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.bp-composer__preview-remove svg {\n width: 14px;\n height: 14px;\n}\n\n.bp-composer__preview-remove:hover {\n color: var(--bp-gray-700);\n}\n\n.bp-composer__row {\n display: flex;\n align-items: flex-end;\n padding: 4px;\n}\n\n.bp-composer__attach {\n width: 32px;\n height: 32px;\n background: none;\n border: none;\n cursor: pointer;\n color: var(--bp-gray-500);\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n border-radius: 6px;\n transition: color var(--bp-transition), background var(--bp-transition);\n}\n\n.bp-composer__attach:hover {\n color: var(--bp-primary);\n background: var(--bp-gray-50);\n}\n\n.bp-composer__attach:disabled {\n opacity: 0.4;\n cursor: not-allowed;\n}\n\n.bp-composer__attach svg {\n width: 18px;\n height: 18px;\n}\n\n.bp-composer__field {\n flex: 1;\n border: none;\n padding: 6px 4px;\n font-size: 14px;\n font-family: inherit;\n line-height: 1.4;\n resize: none;\n outline: none;\n max-height: 100px;\n overflow-y: auto;\n color: var(--bp-gray-900);\n background: transparent;\n}\n\n.bp-composer__field::placeholder {\n color: var(--bp-gray-500);\n}\n\n.bp-composer__field:disabled {\n cursor: not-allowed;\n}\n\n.bp-composer__send {\n width: 32px;\n height: 32px;\n border-radius: 50%;\n background: var(--bp-primary);\n color: var(--bp-primary-contrast);\n border: none;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n transition: opacity var(--bp-transition);\n}\n\n.bp-composer__send:disabled {\n opacity: 0.4;\n cursor: not-allowed;\n}\n\n.bp-composer__send svg {\n width: 16px;\n height: 16px;\n}\n\n/* ===== Message Media ===== */\n.bp-media-img {\n max-width: 100%;\n max-height: 240px;\n border-radius: 8px;\n cursor: pointer;\n display: block;\n object-fit: contain;\n}\n\n.bp-media-video {\n max-width: 100%;\n max-height: 240px;\n border-radius: 8px;\n display: block;\n}\n\n.bp-media-file {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n background: var(--bp-gray-50);\n border-radius: 8px;\n text-decoration: none;\n color: var(--bp-gray-700);\n transition: background var(--bp-transition);\n}\n\n.bp-media-file:hover {\n background: var(--bp-gray-100);\n}\n\n.bp-media-file__icon {\n width: 32px;\n height: 32px;\n border-radius: 6px;\n background: var(--bp-gray-200);\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n color: var(--bp-gray-500);\n}\n\n.bp-media-file__icon svg {\n width: 16px;\n height: 16px;\n}\n\n.bp-media-file__name {\n flex: 1;\n font-size: 13px;\n font-weight: 500;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n min-width: 0;\n}\n\n.bp-media-file__download svg {\n width: 16px;\n height: 16px;\n color: var(--bp-primary);\n}\n\n/* ===== Image Lightbox ===== */\n.bp-lightbox {\n position: fixed;\n inset: 0;\n z-index: 2147483647;\n background: rgba(0, 0, 0, 0.85);\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n}\n\n.bp-lightbox__img {\n max-width: 90vw;\n max-height: 90vh;\n object-fit: contain;\n border-radius: 4px;\n cursor: default;\n}\n\n.bp-lightbox__close {\n position: absolute;\n top: 16px;\n right: 16px;\n width: 36px;\n height: 36px;\n border-radius: 50%;\n background: rgba(255, 255, 255, 0.15);\n color: #fff;\n border: none;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: background var(--bp-transition);\n}\n\n.bp-lightbox__close:hover {\n background: rgba(255, 255, 255, 0.3);\n}\n\n.bp-lightbox__close svg {\n width: 20px;\n height: 20px;\n}\n\n/* ===== Pre-Chat Form ===== */\n.bp-prechat {\n flex: 1;\n padding: 24px 16px;\n display: flex;\n flex-direction: column;\n gap: 16px;\n overflow-y: auto;\n}\n\n.bp-prechat__title {\n font-size: 16px;\n font-weight: 600;\n color: var(--bp-gray-900);\n}\n\n.bp-prechat__desc {\n font-size: 13px;\n color: var(--bp-gray-500);\n}\n\n.bp-prechat__field {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.bp-prechat__label {\n font-size: 13px;\n font-weight: 500;\n color: var(--bp-gray-700);\n}\n\n.bp-prechat__input {\n border: 1px solid var(--bp-gray-200);\n border-radius: var(--bp-radius-sm);\n padding: 10px 12px;\n font-size: 14px;\n font-family: inherit;\n outline: none;\n transition: border-color var(--bp-transition);\n color: var(--bp-gray-900);\n background: #fff;\n}\n\n.bp-prechat__input:focus {\n border-color: var(--bp-primary);\n}\n\n.bp-prechat__submit {\n padding: 10px 20px;\n border-radius: var(--bp-radius-sm);\n background: var(--bp-primary);\n color: var(--bp-primary-contrast);\n border: none;\n font-size: 14px;\n font-weight: 500;\n font-family: inherit;\n cursor: pointer;\n transition: opacity var(--bp-transition);\n}\n\n.bp-prechat__submit:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.bp-prechat__privacy {\n font-size: 12px;\n color: var(--bp-gray-500);\n text-align: center;\n margin-top: auto;\n}\n\n.bp-prechat__privacy a {\n color: var(--bp-primary);\n text-decoration: underline;\n}\n\n/* ===== Conversation List ===== */\n.bp-convlist {\n flex: 1;\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n}\n\n.bp-convlist__new {\n padding: 12px 16px;\n border-bottom: 1px solid var(--bp-gray-200);\n}\n\n.bp-convlist__new-btn {\n width: 100%;\n padding: 10px 16px;\n border-radius: var(--bp-radius-sm);\n background: rgba(99, 102, 241, 0.08);\n border: none;\n cursor: pointer;\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 14px;\n font-weight: 500;\n font-family: inherit;\n color: var(--bp-primary);\n transition: background var(--bp-transition);\n}\n\n.bp-convlist__new-btn svg {\n width: 16px;\n height: 16px;\n flex-shrink: 0;\n}\n\n.bp-convlist__new-btn:hover {\n background: rgba(99, 102, 241, 0.15);\n}\n\n.bp-convlist__items {\n flex: 1;\n overflow-y: auto;\n padding: 8px;\n}\n\n.bp-convlist__item {\n width: 100%;\n padding: 12px;\n border-radius: var(--bp-radius-sm);\n background: none;\n border: none;\n cursor: pointer;\n display: flex;\n flex-direction: column;\n gap: 4px;\n text-align: left;\n font-family: inherit;\n transition: background var(--bp-transition);\n color: var(--bp-gray-900);\n}\n\n.bp-convlist__item:hover {\n background: var(--bp-gray-50);\n}\n\n.bp-convlist__item:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.bp-convlist__item-top {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n}\n\n.bp-convlist__item-title {\n font-size: 14px;\n font-weight: 500;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n flex: 1;\n}\n\n.bp-convlist__item-status {\n font-size: 11px;\n font-weight: 500;\n padding: 2px 8px;\n border-radius: 10px;\n flex-shrink: 0;\n}\n\n.bp-convlist__item-status--open {\n background: #dcfce7;\n color: #166534;\n}\n\n.bp-convlist__item-status--closed {\n background: var(--bp-gray-100);\n color: var(--bp-gray-500);\n}\n\n.bp-convlist__item-preview {\n font-size: 13px;\n color: var(--bp-gray-500);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.bp-convlist__empty {\n padding: 32px 16px;\n text-align: center;\n color: var(--bp-gray-500);\n font-size: 14px;\n}\n\n/* ===== Closed conversation banner ===== */\n.bp-closed-banner {\n padding: 14px 16px;\n border-top: 1px solid var(--bp-gray-200);\n background: var(--bp-gray-50);\n flex-shrink: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n flex-wrap: wrap;\n}\n\n.bp-closed-banner__text {\n font-size: 13px;\n color: var(--bp-gray-500);\n}\n\n.bp-closed-banner__reopen {\n background: none;\n border: none;\n padding: 0;\n font-size: 13px;\n font-weight: 500;\n font-family: inherit;\n color: var(--bp-primary);\n cursor: pointer;\n text-decoration: underline;\n text-underline-offset: 2px;\n}\n\n.bp-closed-banner__reopen:hover {\n opacity: 0.8;\n}\n\n/* ===== Privacy footer ===== */\n.bp-privacy-footer {\n padding: 4px 16px 8px;\n text-align: center;\n font-size: 11px;\n color: var(--bp-gray-500);\n flex-shrink: 0;\n}\n\n.bp-privacy-footer a {\n color: var(--bp-primary);\n text-decoration: underline;\n}\n\n/* ===== Loading ===== */\n.bp-loading {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.bp-spinner {\n width: 32px;\n height: 32px;\n border: 3px solid var(--bp-gray-200);\n border-top-color: var(--bp-primary);\n border-radius: 50%;\n animation: bp-spin 0.6s linear infinite;\n}\n\n@keyframes bp-spin {\n to {\n transform: rotate(360deg);\n }\n}\n\n/* ===== Hidden ===== */\n.bp-hidden {\n display: none !important;\n}\n` as string\n","export type EventCallback = (...args: any[]) => void\n\nexport class EventEmitter {\n private listeners = new Map<string, Set<EventCallback>>()\n\n on(event: string, callback: EventCallback): void {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set())\n }\n this.listeners.get(event)!.add(callback)\n }\n\n off(event: string, callback: EventCallback): void {\n this.listeners.get(event)?.delete(callback)\n }\n\n emit(event: string, ...args: any[]): void {\n this.listeners.get(event)?.forEach((cb) => {\n try {\n cb(...args)\n } catch (e) {\n console.error(`[BaseportalChat] Error in ${event} handler:`, e)\n }\n })\n }\n\n removeAllListeners(): void {\n this.listeners.clear()\n }\n}\n","import type { VisitorData } from '../api/types'\n\ninterface StoredData {\n conversationId?: string\n visitor?: VisitorData\n}\n\nexport class Storage {\n private prefix: string\n\n constructor(channelToken: string, email?: string) {\n this.prefix = email\n ? `bp_chat_${channelToken}_${email}`\n : `bp_chat_${channelToken}`\n }\n\n get(): StoredData {\n try {\n const raw = localStorage.getItem(this.prefix)\n return raw ? JSON.parse(raw) : {}\n } catch {\n return {}\n }\n }\n\n set(data: Partial<StoredData>): void {\n try {\n const current = this.get()\n localStorage.setItem(this.prefix, JSON.stringify({ ...current, ...data }))\n } catch {\n // localStorage unavailable (private browsing, etc.)\n }\n }\n\n getConversationId(): string | undefined {\n return this.get().conversationId\n }\n\n setConversationId(id: string): void {\n this.set({ conversationId: id })\n }\n\n getVisitor(): VisitorData | undefined {\n return this.get().visitor\n }\n\n setVisitor(visitor: VisitorData): void {\n this.set({ visitor })\n }\n\n clear(): void {\n try {\n localStorage.removeItem(this.prefix)\n } catch {\n // ignore\n }\n }\n}\n","import { ApiClient } from './api/client'\nimport type { BaseportalChatConfig, ChannelInfo, VisitorData } from './api/types'\nimport { RealtimeClient } from './realtime/ably-client'\nimport { getTranslations } from './ui/i18n'\nimport { mount, unmount, updateTheme } from './ui/mount'\nimport { EventCallback, EventEmitter } from './utils/events'\nimport { Storage } from './utils/storage'\n\nconst DEFAULT_API_URL = 'https://api.baseportal.io'\n\nexport class BaseportalChat {\n private config: Required<\n Pick<BaseportalChatConfig, 'channelToken' | 'apiUrl' | 'position' | 'locale'>\n > &\n BaseportalChatConfig\n private apiClient: ApiClient\n private realtimeClient: RealtimeClient\n private storage: Storage\n private events = new EventEmitter()\n private channelInfo: ChannelInfo | null = null\n private visitor: VisitorData | null = null\n private isAuthenticated = false\n private isOpenRef = { current: false }\n private hidden: boolean\n private mounted = false\n\n constructor(config: BaseportalChatConfig) {\n this.config = {\n ...config,\n apiUrl: config.apiUrl || DEFAULT_API_URL,\n position: config.position || 'bottom-right',\n locale: config.locale || 'pt',\n }\n\n this.hidden = config.hideOnLoad || false\n this.visitor = config.visitor || null\n this.isAuthenticated = !!config.visitor?.email\n\n this.apiClient = new ApiClient(\n this.config.channelToken,\n this.config.apiUrl\n )\n\n if (this.isAuthenticated && this.visitor?.email) {\n this.apiClient.setVisitorIdentity(this.visitor.email, this.visitor.hash)\n }\n\n this.storage = new Storage(\n this.config.channelToken,\n this.isAuthenticated ? this.visitor?.email : undefined\n )\n\n this.realtimeClient = new RealtimeClient(this.apiClient)\n\n // Restore visitor from storage\n if (!this.visitor) {\n this.visitor = this.storage.getVisitor() || null\n }\n\n this.init()\n }\n\n private async init(): Promise<void> {\n try {\n this.channelInfo = await this.apiClient.getChannelInfo()\n\n // Apply theme: SDK config > channel theme > default\n const primaryColor =\n this.config.theme?.primaryColor ||\n this.channelInfo.theme?.primaryColor ||\n '#6366f1'\n\n const t = getTranslations(this.config.locale)\n\n mount({\n channelInfo: this.channelInfo,\n apiClient: this.apiClient,\n realtimeClient: this.realtimeClient,\n storage: this.storage,\n events: this.events,\n visitor: this.visitor,\n isAuthenticated: this.isAuthenticated,\n position: this.config.position,\n hidden: this.hidden,\n t,\n container: this.config.container,\n isOpenRef: this.isOpenRef,\n setIsOpen: (open: boolean) => {\n this.isOpenRef.current = open\n },\n })\n\n // Override theme if needed\n if (primaryColor !== '#6366f1') {\n updateTheme(primaryColor)\n }\n\n this.mounted = true\n this.events.emit('ready')\n } catch (e) {\n console.error('[BaseportalChat] Failed to initialize:', e)\n }\n }\n\n // --- Visibility ---\n\n open(): void {\n if (!this.mounted) return\n this.events.emit('_open')\n this.events.emit('open')\n }\n\n close(): void {\n if (!this.mounted) return\n this.events.emit('_close')\n this.events.emit('close')\n }\n\n toggle(): void {\n if (this.isOpenRef.current) {\n this.close()\n } else {\n this.open()\n }\n }\n\n show(): void {\n this.hidden = false\n this.events.emit('show')\n }\n\n hide(): void {\n this.hidden = true\n this.events.emit('hide')\n }\n\n isOpen(): boolean {\n return this.isOpenRef.current\n }\n\n // --- Visitor ---\n\n identify(visitor: {\n email: string\n name?: string\n hash: string\n metadata?: Record<string, string>\n }): void {\n this.visitor = visitor\n this.isAuthenticated = true\n this.apiClient.setVisitorIdentity(visitor.email, visitor.hash)\n this.storage = new Storage(this.config.channelToken, visitor.email)\n this.storage.setVisitor(visitor)\n this.events.emit('identified', visitor)\n\n // Remount with new state\n if (this.mounted) {\n this.remount()\n }\n }\n\n updateVisitor(data: {\n name?: string\n metadata?: Record<string, string>\n }): void {\n if (this.visitor) {\n this.visitor = { ...this.visitor, ...data }\n this.storage.setVisitor(this.visitor)\n }\n }\n\n clearVisitor(): void {\n this.visitor = null\n this.isAuthenticated = false\n this.apiClient.clearVisitorIdentity()\n this.storage.clear()\n this.storage = new Storage(this.config.channelToken)\n this.realtimeClient.unsubscribe()\n\n if (this.mounted) {\n this.remount()\n }\n }\n\n // --- Actions ---\n\n sendMessage(content: string): void {\n // Implemented via events - App listens\n this.events.emit('_sendMessage', content)\n }\n\n setConversationId(id: string): void {\n this.events.emit('_setConversationId', id)\n }\n\n newConversation(): void {\n this.events.emit('_newConversation')\n }\n\n // --- Config ---\n\n setTheme(theme: { primaryColor?: string }): void {\n if (theme.primaryColor) {\n updateTheme(theme.primaryColor)\n }\n }\n\n setPosition(position: 'bottom-right' | 'bottom-left'): void {\n this.config.position = position\n if (this.mounted) {\n this.remount()\n }\n }\n\n setLocale(locale: 'pt' | 'en' | 'es'): void {\n this.config.locale = locale\n if (this.mounted) {\n this.remount()\n }\n }\n\n // --- Events ---\n\n on(event: string, callback: EventCallback): void {\n this.events.on(event, callback)\n }\n\n off(event: string, callback: EventCallback): void {\n this.events.off(event, callback)\n }\n\n // --- Lifecycle ---\n\n destroy(): void {\n this.realtimeClient.unsubscribe()\n this.events.removeAllListeners()\n unmount()\n this.mounted = false\n }\n\n private remount(): void {\n unmount()\n this.mounted = false\n this.init()\n }\n}\n"],"mappings":"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AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;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","names":["h","import_hooks","import_jsx_runtime","import_hooks","import_jsx_runtime","import_jsx_runtime","import_hooks","import_hooks","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_hooks","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/api/client.ts","../src/realtime/ably-client.ts","../src/ui/i18n.ts","../src/ui/mount.ts","../src/ui/App.tsx","../src/ui/icons.tsx","../src/ui/components/ChatBubble.tsx","../src/ui/components/ChatWindow.tsx","../src/ui/components/ConversationList.tsx","../src/ui/components/MessageInput.tsx","../src/ui/components/MessageList.tsx","../src/ui/components/ImageLightbox.tsx","../src/ui/components/MessageMedia.tsx","../src/ui/components/PreChatForm.tsx","../src/ui/styles/widget-css.ts","../src/utils/events.ts","../src/utils/storage.ts","../src/widget.ts"],"sourcesContent":["import { BaseportalChat } from './widget'\n\nexport { BaseportalChat }\nexport type {\n BaseportalChatConfig,\n ChannelInfo,\n Conversation,\n Message,\n VisitorData,\n} from './api/types'\n\nexport default BaseportalChat\n","import type { ChannelInfo, Conversation, Message } from './types'\n\nexport class ApiClient {\n private baseUrl: string\n private channelToken: string\n private visitorEmail?: string\n private visitorHash?: string\n\n constructor(channelToken: string, apiUrl: string) {\n this.channelToken = channelToken\n this.baseUrl = `${apiUrl}/public/chat`\n }\n\n setVisitorIdentity(email: string, hash?: string): void {\n this.visitorEmail = email\n this.visitorHash = hash\n }\n\n clearVisitorIdentity(): void {\n this.visitorEmail = undefined\n this.visitorHash = undefined\n }\n\n private headers(): Record<string, string> {\n const h: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'x-channel-token': this.channelToken,\n }\n if (this.visitorEmail) h['x-visitor-email'] = this.visitorEmail\n if (this.visitorHash) h['x-visitor-hash'] = this.visitorHash\n return h\n }\n\n private async request<T>(\n method: string,\n path: string,\n body?: unknown\n ): Promise<T> {\n const res = await fetch(`${this.baseUrl}${path}`, {\n method,\n headers: this.headers(),\n body: body ? JSON.stringify(body) : undefined,\n })\n\n if (!res.ok) {\n const text = await res.text().catch(() => '')\n throw new Error(`[BaseportalChat] API error ${res.status}: ${text}`)\n }\n\n return res.json()\n }\n\n async getChannelInfo(): Promise<ChannelInfo> {\n return this.request('GET', '/channel-info')\n }\n\n async initConversation(data: {\n name?: string\n email?: string\n }): Promise<Conversation & { messages?: Message[] }> {\n return this.request('POST', '/conversations', {\n ...data,\n channelToken: this.channelToken,\n })\n }\n\n async getConversation(conversationId: string): Promise<Conversation> {\n return this.request('GET', `/conversations/${conversationId}`)\n }\n\n async getMessages(\n conversationId: string,\n params?: { limit?: number; page?: number }\n ): Promise<Message[]> {\n const qs = new URLSearchParams()\n if (params?.limit) qs.set('limit', String(params.limit))\n if (params?.page) qs.set('page', String(params.page))\n const query = qs.toString() ? `?${qs.toString()}` : ''\n return this.request('GET', `/conversations/${conversationId}/messages${query}`)\n }\n\n async uploadFile(conversationId: string, file: File): Promise<{ id: string; url: string; name: string; mimeType: string }> {\n const formData = new FormData()\n formData.append('file', file)\n\n const headers: Record<string, string> = {\n 'x-channel-token': this.channelToken,\n }\n if (this.visitorEmail) headers['x-visitor-email'] = this.visitorEmail\n if (this.visitorHash) headers['x-visitor-hash'] = this.visitorHash\n\n const res = await fetch(`${this.baseUrl}/conversations/${conversationId}/upload`, {\n method: 'POST',\n headers,\n body: formData,\n })\n\n if (!res.ok) {\n const text = await res.text().catch(() => '')\n throw new Error(`[BaseportalChat] Upload error ${res.status}: ${text}`)\n }\n\n return res.json()\n }\n\n async sendMessage(\n conversationId: string,\n data: { content?: string; mediaId?: string }\n ): Promise<Message> {\n return this.request(\n 'POST',\n `/conversations/${conversationId}/messages`,\n data\n )\n }\n\n async getVisitorConversations(): Promise<Conversation[]> {\n return this.request('GET', '/conversations')\n }\n\n async reopenConversation(conversationId: string): Promise<Conversation> {\n return this.request('POST', `/conversations/${conversationId}/reopen`)\n }\n\n async getAblyToken(conversationId: string): Promise<unknown> {\n return this.request('POST', '/ably-token', { conversationId })\n }\n}\n","import * as Ably from 'ably'\n\nimport type { ApiClient } from '../api/client'\nimport type { Conversation, Message } from '../api/types'\n\nexport interface RealtimeHandlers {\n onMessage: (message: Message) => void\n onConversationStatusUpdate: (conversation: Conversation) => void\n}\n\nexport class RealtimeClient {\n private client: Ably.Realtime | null = null\n private channel: Ably.RealtimeChannel | null = null\n private conversationId: string | null = null\n private apiClient: ApiClient\n private handlers: RealtimeHandlers | null = null\n\n constructor(apiClient: ApiClient) {\n this.apiClient = apiClient\n }\n\n async subscribe(\n conversationId: string,\n handlers: RealtimeHandlers\n ): Promise<void> {\n // Unsubscribe from previous if any\n this.unsubscribe()\n\n this.conversationId = conversationId\n this.handlers = handlers\n\n try {\n const tokenRequest = await this.apiClient.getAblyToken(conversationId)\n\n this.client = new Ably.Realtime({\n authCallback: (_data, callback) => {\n callback(null, tokenRequest as Ably.TokenRequest)\n },\n clientId: `visitor-${conversationId}`,\n })\n\n const channelName = `conversation-${conversationId}`\n this.channel = this.client.channels.get(channelName)\n\n this.channel.subscribe((msg) => {\n if (!msg.data) return\n\n try {\n const data =\n typeof msg.data === 'string' ? JSON.parse(msg.data) : msg.data\n\n if (data.text === 'conversation_status_updated' && data.metadata) {\n handlers.onConversationStatusUpdate(data.metadata as Conversation)\n } else if (\n data.text === 'created_or_updated_message' &&\n data.metadata\n ) {\n handlers.onMessage(data.metadata as Message)\n }\n } catch (e) {\n console.error('[BaseportalChat] Error parsing realtime message:', e)\n }\n })\n } catch (e) {\n console.error('[BaseportalChat] Error connecting to realtime:', e)\n }\n }\n\n unsubscribe(): void {\n if (this.channel) {\n this.channel.unsubscribe()\n this.channel = null\n }\n if (this.client) {\n this.client.close()\n this.client = null\n }\n this.conversationId = null\n this.handlers = null\n }\n\n isConnected(): boolean {\n return this.client?.connection.state === 'connected'\n }\n}\n","export interface Translations {\n prechat: {\n title: string\n description: string\n name: string\n namePlaceholder: string\n email: string\n emailPlaceholder: string\n start: string\n loading: string\n privacyPrefix: string\n privacyLink: string\n }\n chat: {\n placeholder: string\n closed: string\n reopen: string\n attachFile: string\n uploading: string\n fileTooLarge: string\n download: string\n }\n conversations: {\n title: string\n newConversation: string\n empty: string\n open: string\n closed: string\n noMessages: string\n }\n}\n\nconst pt: Translations = {\n prechat: {\n title: 'Iniciar conversa',\n description: 'Preencha os dados abaixo para iniciar o atendimento.',\n name: 'Nome',\n namePlaceholder: 'Seu nome',\n email: 'E-mail',\n emailPlaceholder: 'seu@email.com',\n start: 'Iniciar conversa',\n loading: 'Iniciando...',\n privacyPrefix: 'Ao enviar, você concorda com nossa',\n privacyLink: 'Política de Privacidade',\n },\n chat: {\n placeholder: 'Digite uma mensagem...',\n closed: 'Esta conversa foi encerrada.',\n reopen: 'Reabrir conversa',\n attachFile: 'Anexar arquivo',\n uploading: 'Enviando...',\n fileTooLarge: 'Arquivo muito grande (máx. 25MB)',\n download: 'Baixar',\n },\n conversations: {\n title: 'Atendimento',\n newConversation: 'Nova conversa',\n empty: 'Nenhuma conversa encontrada.',\n open: 'Aberta',\n closed: 'Fechada',\n noMessages: 'Nenhuma mensagem ainda',\n },\n}\n\nconst en: Translations = {\n prechat: {\n title: 'Start a conversation',\n description: 'Fill in the details below to start chatting.',\n name: 'Name',\n namePlaceholder: 'Your name',\n email: 'Email',\n emailPlaceholder: 'you@email.com',\n start: 'Start conversation',\n loading: 'Starting...',\n privacyPrefix: 'By sending, you agree to our',\n privacyLink: 'Privacy Policy',\n },\n chat: {\n placeholder: 'Type a message...',\n closed: 'This conversation has been closed.',\n reopen: 'Reopen conversation',\n attachFile: 'Attach file',\n uploading: 'Uploading...',\n fileTooLarge: 'File too large (max 25MB)',\n download: 'Download',\n },\n conversations: {\n title: 'Support',\n newConversation: 'New conversation',\n empty: 'No conversations found.',\n open: 'Open',\n closed: 'Closed',\n noMessages: 'No messages yet',\n },\n}\n\nconst es: Translations = {\n prechat: {\n title: 'Iniciar conversación',\n description: 'Complete los datos a continuación para iniciar la atención.',\n name: 'Nombre',\n namePlaceholder: 'Tu nombre',\n email: 'Correo electrónico',\n emailPlaceholder: 'tu@email.com',\n start: 'Iniciar conversación',\n loading: 'Iniciando...',\n privacyPrefix: 'Al enviar, aceptas nuestra',\n privacyLink: 'Política de Privacidad',\n },\n chat: {\n placeholder: 'Escribe un mensaje...',\n closed: 'Esta conversación ha sido cerrada.',\n reopen: 'Reabrir conversación',\n attachFile: 'Adjuntar archivo',\n uploading: 'Subiendo...',\n fileTooLarge: 'Archivo demasiado grande (máx. 25MB)',\n download: 'Descargar',\n },\n conversations: {\n title: 'Atención',\n newConversation: 'Nueva conversación',\n empty: 'No se encontraron conversaciones.',\n open: 'Abierta',\n closed: 'Cerrada',\n noMessages: 'Sin mensajes aún',\n },\n}\n\nconst locales: Record<string, Translations> = { pt, en, es }\n\nexport function getTranslations(locale: string): Translations {\n return locales[locale] || locales['pt']\n}\n","import { render, h } from 'preact'\n\nimport type { ApiClient } from '../api/client'\nimport type { ChannelInfo, VisitorData } from '../api/types'\nimport type { RealtimeClient } from '../realtime/ably-client'\nimport type { EventEmitter } from '../utils/events'\nimport type { Storage } from '../utils/storage'\nimport { App } from './App'\nimport type { Translations } from './i18n'\nimport widgetCSS from './styles/widget-css'\n\ninterface MountOptions {\n channelInfo: ChannelInfo\n apiClient: ApiClient\n realtimeClient: RealtimeClient\n storage: Storage\n events: EventEmitter\n visitor: VisitorData | null\n isAuthenticated: boolean\n position: 'bottom-right' | 'bottom-left'\n hidden: boolean\n t: Translations\n container?: HTMLElement\n isOpenRef: { current: boolean }\n setIsOpen: (open: boolean) => void\n}\n\nlet styleElement: HTMLStyleElement | null = null\nlet hostElement: HTMLElement | null = null\n\nexport function mount(options: MountOptions): void {\n // Inject styles into document head (once)\n if (!styleElement) {\n styleElement = document.createElement('style')\n styleElement.id = 'baseportal-chat-styles'\n styleElement.textContent = widgetCSS\n document.head.appendChild(styleElement)\n }\n\n // Create host element directly on body — no shadow DOM\n hostElement = document.createElement('div')\n hostElement.id = 'baseportal-chat-widget'\n const target = options.container || document.body\n target.appendChild(hostElement)\n\n // Apply primary color as CSS variable\n const primaryColor =\n options.channelInfo.theme?.primaryColor || '#6366f1'\n const contrastColor = getContrastColor(primaryColor)\n hostElement.style.setProperty('--bp-primary', primaryColor)\n hostElement.style.setProperty('--bp-primary-contrast', contrastColor)\n\n // Render Preact app\n render(\n h(App, {\n channelInfo: options.channelInfo,\n apiClient: options.apiClient,\n realtimeClient: options.realtimeClient,\n storage: options.storage,\n events: options.events,\n visitor: options.visitor,\n isAuthenticated: options.isAuthenticated,\n position: options.position,\n hidden: options.hidden,\n t: options.t,\n isOpenRef: options.isOpenRef,\n setIsOpen: options.setIsOpen,\n }),\n hostElement\n )\n}\n\nexport function unmount(): void {\n if (hostElement) {\n render(null, hostElement)\n hostElement.remove()\n hostElement = null\n }\n if (styleElement) {\n styleElement.remove()\n styleElement = null\n }\n}\n\nexport function updateTheme(primaryColor: string): void {\n if (!hostElement) return\n hostElement.style.setProperty('--bp-primary', primaryColor)\n hostElement.style.setProperty(\n '--bp-primary-contrast',\n getContrastColor(primaryColor)\n )\n}\n\nfunction getContrastColor(hex: string): string {\n const r = parseInt(hex.slice(1, 3), 16)\n const g = parseInt(hex.slice(3, 5), 16)\n const b = parseInt(hex.slice(5, 7), 16)\n const luminance =\n (0.299 * r + 0.587 * g + 0.114 * b) / 255\n return luminance > 0.5 ? '#000000' : '#ffffff'\n}\n","/** @jsxImportSource preact */\n\nimport { useEffect, useState } from 'preact/hooks'\n\nimport type { ApiClient } from '../api/client'\nimport type { ChannelInfo, VisitorData } from '../api/types'\nimport type { RealtimeClient } from '../realtime/ably-client'\nimport type { EventEmitter } from '../utils/events'\nimport type { Storage } from '../utils/storage'\nimport { ChatBubble } from './components/ChatBubble'\nimport { ChatWindow } from './components/ChatWindow'\nimport type { Translations } from './i18n'\n\ninterface AppProps {\n channelInfo: ChannelInfo\n apiClient: ApiClient\n realtimeClient: RealtimeClient\n storage: Storage\n events: EventEmitter\n visitor: VisitorData | null\n isAuthenticated: boolean\n position: 'bottom-right' | 'bottom-left'\n hidden: boolean\n t: Translations\n // Controlled state from widget class\n isOpenRef: { current: boolean }\n setIsOpen: (open: boolean) => void\n}\n\nexport function App({\n channelInfo,\n apiClient,\n realtimeClient,\n storage,\n events,\n visitor,\n isAuthenticated,\n position,\n hidden,\n t,\n isOpenRef,\n setIsOpen,\n}: AppProps) {\n const [isOpen, setIsOpenState] = useState(isOpenRef.current)\n const [isHidden, setIsHidden] = useState(hidden)\n const [unreadCount] = useState(0)\n\n // Listen for external open/close/show/hide from SDK\n useEffect(() => {\n const onOpen = () => {\n setIsOpenState(true)\n isOpenRef.current = true\n setIsOpen(true)\n }\n const onClose = () => {\n setIsOpenState(false)\n isOpenRef.current = false\n setIsOpen(false)\n }\n const onShow = () => setIsHidden(false)\n const onHide = () => {\n setIsHidden(true)\n setIsOpenState(false)\n isOpenRef.current = false\n setIsOpen(false)\n }\n\n events.on('_open', onOpen)\n events.on('_close', onClose)\n events.on('show', onShow)\n events.on('hide', onHide)\n\n return () => {\n events.off('_open', onOpen)\n events.off('_close', onClose)\n events.off('show', onShow)\n events.off('hide', onHide)\n }\n }, [events, isOpenRef, setIsOpen])\n\n const handleToggle = () => {\n const next = !isOpen\n setIsOpenState(next)\n isOpenRef.current = next\n setIsOpen(next)\n events.emit(next ? 'open' : 'close')\n }\n\n const handleClose = () => {\n setIsOpenState(false)\n isOpenRef.current = false\n setIsOpen(false)\n events.emit('close')\n }\n\n return (\n <>\n {!isHidden && (\n <ChatBubble\n isOpen={isOpen}\n position={position}\n unreadCount={unreadCount}\n onClick={handleToggle}\n />\n )}\n {isOpen && (\n <ChatWindow\n channelInfo={channelInfo}\n apiClient={apiClient}\n realtimeClient={realtimeClient}\n storage={storage}\n events={events}\n visitor={visitor}\n isAuthenticated={isAuthenticated}\n position={position}\n onClose={handleClose}\n t={t}\n />\n )}\n </>\n )\n}\n","/** @jsxImportSource preact */\n\nexport const IconChat = () => (\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\" />\n </svg>\n)\n\nexport const IconX = () => (\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n)\n\nexport const IconArrowLeft = () => (\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <line x1=\"19\" y1=\"12\" x2=\"5\" y2=\"12\" />\n <polyline points=\"12 19 5 12 12 5\" />\n </svg>\n)\n\nexport const IconSend = () => (\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <line x1=\"22\" y1=\"2\" x2=\"11\" y2=\"13\" />\n <polygon points=\"22 2 15 22 11 13 2 9 22 2\" />\n </svg>\n)\n\nexport const IconPlus = () => (\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\" />\n <line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\" />\n </svg>\n)\n\nexport const IconPaperclip = () => (\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M21.44 11.05l-9.19 9.19a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66l-9.2 9.19a2 2 0 0 1-2.83-2.83l8.49-8.48\" />\n </svg>\n)\n\nexport const IconDownload = () => (\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\" />\n <polyline points=\"7 10 12 15 17 10\" />\n <line x1=\"12\" y1=\"15\" x2=\"12\" y2=\"3\" />\n </svg>\n)\n\nexport const IconFile = () => (\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\" />\n <polyline points=\"14 2 14 8 20 8\" />\n </svg>\n)\n","/** @jsxImportSource preact */\n\nimport { IconChat, IconX } from '../icons'\n\ninterface ChatBubbleProps {\n isOpen: boolean\n position: 'bottom-right' | 'bottom-left'\n unreadCount: number\n onClick: () => void\n}\n\nexport function ChatBubble({\n isOpen,\n position,\n unreadCount,\n onClick,\n}: ChatBubbleProps) {\n const posClass =\n position === 'bottom-left' ? 'bp-bubble--left' : 'bp-bubble--right'\n\n return (\n <button\n class={`bp-bubble ${posClass}`}\n onClick={onClick}\n aria-label={isOpen ? 'Close chat' : 'Open chat'}\n >\n {isOpen ? <IconX /> : <IconChat />}\n {!isOpen && unreadCount > 0 && (\n <span class=\"bp-bubble__badge\">\n {unreadCount > 99 ? '99+' : unreadCount}\n </span>\n )}\n </button>\n )\n}\n","/** @jsxImportSource preact */\n\nimport { useCallback, useEffect, useRef, useState } from 'preact/hooks'\n\nimport type { ApiClient } from '../../api/client'\nimport type {\n ChannelInfo,\n Conversation,\n Message,\n VisitorData,\n} from '../../api/types'\nimport type { RealtimeClient } from '../../realtime/ably-client'\nimport type { EventEmitter } from '../../utils/events'\nimport type { Storage } from '../../utils/storage'\nimport { IconArrowLeft, IconX } from '../icons'\nimport type { Translations } from '../i18n'\nimport { ConversationList } from './ConversationList'\nimport { MessageInput, type AttachedFile } from './MessageInput'\nimport { MessageList } from './MessageList'\nimport { PreChatForm } from './PreChatForm'\n\ntype View = 'prechat' | 'conversations' | 'chat'\n\ninterface ChatWindowProps {\n channelInfo: ChannelInfo\n apiClient: ApiClient\n realtimeClient: RealtimeClient\n storage: Storage\n events: EventEmitter\n visitor: VisitorData | null\n isAuthenticated: boolean\n position: 'bottom-right' | 'bottom-left'\n onClose: () => void\n t: Translations\n initialConversationId?: string | null\n}\n\nexport function ChatWindow({\n channelInfo,\n apiClient,\n realtimeClient,\n storage,\n events,\n visitor,\n isAuthenticated,\n position,\n onClose,\n t,\n initialConversationId,\n}: ChatWindowProps) {\n const [view, setView] = useState<View>('chat')\n const [conversation, setConversation] = useState<Conversation | null>(null)\n const [conversations, setConversations] = useState<Conversation[]>([])\n const [messages, setMessages] = useState<Message[]>([])\n const [inputValue, setInputValue] = useState('')\n const [loading, setLoading] = useState(true)\n const [sending, setSending] = useState(false)\n const [attachedFile, setAttachedFile] = useState<AttachedFile | null>(null)\n const [uploadedFileId, setUploadedFileId] = useState<string | null>(null)\n const [uploading, setUploading] = useState(false)\n\n const isOpen = conversation?.open !== false\n\n const allowViewHistory = channelInfo.config.allowViewHistory && isAuthenticated\n\n // Ref to break circular dependency between connectRealtime and startNewConversation\n const startNewConversationRef = useRef<() => Promise<void>>(async () => {})\n\n // Determine initial view\n useEffect(() => {\n const init = async () => {\n setLoading(true)\n try {\n if (allowViewHistory) {\n // History mode: load conversation list\n const convs = await apiClient.getVisitorConversations()\n setConversations(convs)\n\n if (initialConversationId) {\n const conv = convs.find((c) => c.id === initialConversationId)\n if (conv) {\n await openConversation(conv)\n return\n }\n }\n\n if (convs.length > 0) {\n setView('conversations')\n } else {\n if (needsPreChat()) {\n setView('prechat')\n } else {\n await startNewConversation()\n }\n }\n } else {\n // No history: check localStorage for existing conversation\n const storedId =\n initialConversationId || storage.getConversationId()\n\n if (storedId) {\n try {\n const conv = await apiClient.getConversation(storedId)\n if (!conv.open) {\n // Conversation is closed, clear and start fresh\n storage.clear()\n if (needsPreChat()) {\n setView('prechat')\n } else {\n await startNewConversation()\n }\n } else {\n const msgs = await apiClient.getMessages(storedId, { limit: 50 })\n setMessages(Array.isArray(msgs) ? msgs.reverse() : [])\n setConversation(conv)\n setView('chat')\n connectRealtime(storedId)\n }\n } catch {\n storage.clear()\n if (needsPreChat()) {\n setView('prechat')\n } else {\n await startNewConversation()\n }\n }\n } else {\n if (needsPreChat()) {\n setView('prechat')\n } else {\n await startNewConversation()\n }\n }\n }\n } catch (e) {\n console.error('[BaseportalChat] Error initializing:', e)\n } finally {\n setLoading(false)\n }\n }\n\n init()\n\n return () => {\n realtimeClient.unsubscribe()\n }\n }, [])\n\n const needsPreChat = useCallback((): boolean => {\n if (visitor?.name && visitor?.email) return false\n return (\n channelInfo.config.requireName || channelInfo.config.requireEmail\n )\n }, [channelInfo, visitor])\n\n const connectRealtime = useCallback(\n (convId: string) => {\n realtimeClient.subscribe(convId, {\n onMessage: (msg) => {\n setMessages((prev) => {\n if (prev.some((m) => m.id === msg.id)) {\n return prev.map((m) =>\n m.id === msg.id ? { ...m, ...msg } : m\n )\n }\n const withoutTemp = prev.filter(\n (m) =>\n !String(m.id).startsWith('temp-') ||\n m.content !== msg.content\n )\n return [...withoutTemp, msg]\n })\n events.emit('message:received', msg)\n },\n onConversationStatusUpdate: (conv) => {\n setConversation((prev) =>\n prev ? { ...prev, open: conv.open } : prev\n )\n if (!conv.open) {\n events.emit('conversation:closed', conv)\n // Reset widget so user can start a new conversation\n setTimeout(() => {\n realtimeClient.unsubscribe()\n storage.clear()\n setConversation(null)\n setMessages([])\n if (allowViewHistory) {\n apiClient\n .getVisitorConversations()\n .then(setConversations)\n .catch(() => {})\n setView('conversations')\n } else if (needsPreChat()) {\n setView('prechat')\n } else {\n startNewConversationRef.current()\n }\n }, 2000)\n }\n },\n })\n },\n [realtimeClient, events, storage, allowViewHistory, apiClient, needsPreChat]\n )\n\n const openConversation = useCallback(\n async (conv: Conversation) => {\n setLoading(true)\n try {\n const msgs = await apiClient.getMessages(conv.id, { limit: 50 })\n setMessages(Array.isArray(msgs) ? msgs.reverse() : [])\n setConversation(conv)\n setView('chat')\n storage.setConversationId(conv.id)\n connectRealtime(conv.id)\n } catch (e) {\n console.error('[BaseportalChat] Error opening conversation:', e)\n } finally {\n setLoading(false)\n }\n },\n [apiClient, storage, connectRealtime]\n )\n\n const startNewConversation = useCallback(async () => {\n setLoading(true)\n try {\n const result = await apiClient.initConversation({\n name: visitor?.name,\n email: visitor?.email,\n })\n setConversation(result)\n setMessages(result.messages || [])\n setView('chat')\n storage.setConversationId(result.id)\n connectRealtime(result.id)\n events.emit('conversation:started', result)\n } catch (e) {\n console.error('[BaseportalChat] Error starting conversation:', e)\n } finally {\n setLoading(false)\n }\n }, [apiClient, visitor, storage, connectRealtime, events])\n\n startNewConversationRef.current = startNewConversation\n\n const handlePreChatSubmit = useCallback(\n async (data: { name?: string; email?: string }) => {\n storage.setVisitor({ ...visitor, ...data })\n const result = await apiClient.initConversation(data)\n setConversation(result)\n setMessages(result.messages || [])\n setView('chat')\n storage.setConversationId(result.id)\n connectRealtime(result.id)\n events.emit('conversation:started', result)\n },\n [apiClient, visitor, storage, connectRealtime, events]\n )\n\n const handleFileSelect = useCallback(\n async (file: File) => {\n if (!conversation) return\n\n const MAX_SIZE = 25 * 1024 * 1024\n if (file.size > MAX_SIZE) {\n console.warn('[BaseportalChat] File too large')\n return\n }\n\n const preview = file.type.startsWith('image/')\n ? URL.createObjectURL(file)\n : undefined\n\n setAttachedFile({ file, preview })\n setUploading(true)\n\n try {\n const uploaded = await apiClient.uploadFile(conversation.id, file)\n setUploadedFileId(uploaded.id)\n } catch (e) {\n console.error('[BaseportalChat] Error uploading file:', e)\n setAttachedFile(null)\n if (preview) URL.revokeObjectURL(preview)\n } finally {\n setUploading(false)\n }\n },\n [apiClient, conversation]\n )\n\n const handleFileRemove = useCallback(() => {\n if (attachedFile?.preview) URL.revokeObjectURL(attachedFile.preview)\n setAttachedFile(null)\n setUploadedFileId(null)\n }, [attachedFile])\n\n const handleSend = useCallback(async () => {\n const content = inputValue.trim()\n if ((!content && !uploadedFileId) || !conversation || sending) return\n\n const tempId = `temp-${Date.now()}`\n const optimistic: Message = {\n id: tempId,\n content,\n role: 'client',\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n }\n\n const mediaId = uploadedFileId || undefined\n\n setInputValue('')\n setAttachedFile(null)\n setUploadedFileId(null)\n setSending(true)\n setMessages((prev) => [...prev, optimistic])\n\n try {\n const msg = await apiClient.sendMessage(conversation.id, {\n content: content || undefined,\n mediaId,\n })\n setMessages((prev) => prev.map((m) => (m.id === tempId ? msg : m)))\n events.emit('message:sent', msg)\n } catch (e) {\n console.error('[BaseportalChat] Error sending message:', e)\n setMessages((prev) => prev.filter((m) => m.id !== tempId))\n\n // If conversation no longer exists, reset to allow new conversation\n const errMsg = e instanceof Error ? e.message : ''\n if (errMsg.includes('Row not found') || errMsg.includes('404')) {\n realtimeClient.unsubscribe()\n storage.clear()\n setConversation(null)\n setMessages([])\n if (allowViewHistory) {\n apiClient\n .getVisitorConversations()\n .then(setConversations)\n .catch(() => {})\n setView('conversations')\n } else if (needsPreChat()) {\n setView('prechat')\n } else {\n await startNewConversationRef.current()\n }\n } else {\n setInputValue(content)\n }\n } finally {\n setSending(false)\n }\n }, [inputValue, uploadedFileId, conversation, sending, apiClient, events, realtimeClient, storage, allowViewHistory, needsPreChat])\n\n const handleReopen = useCallback(async () => {\n if (!conversation) return\n try {\n const updated = await apiClient.reopenConversation(conversation.id)\n setConversation((prev) => prev ? { ...prev, open: updated.open ?? true } : prev)\n } catch (e) {\n console.error('[BaseportalChat] Error reopening conversation:', e)\n }\n }, [conversation, apiClient])\n\n const handleBack = useCallback(() => {\n if (allowViewHistory && view === 'chat') {\n realtimeClient.unsubscribe()\n setView('conversations')\n setConversation(null)\n setMessages([])\n apiClient.getVisitorConversations().then(setConversations).catch(() => {})\n } else {\n onClose()\n }\n }, [allowViewHistory, view, realtimeClient, apiClient, onClose])\n\n const posClass =\n position === 'bottom-left' ? 'bp-window--left' : 'bp-window--right'\n\n const headerTitle =\n view === 'conversations'\n ? t.conversations.title\n : channelInfo.name\n\n const showBack =\n (allowViewHistory && view === 'chat') || view === 'prechat'\n\n return (\n <div class={`bp-window ${posClass}`}>\n {/* Header */}\n <div class=\"bp-header\">\n <div class=\"bp-header__title\">\n {showBack && (\n <button class=\"bp-header__back\" onClick={handleBack}>\n <IconArrowLeft />\n </button>\n )}\n {headerTitle}\n </div>\n <button class=\"bp-header__close\" onClick={onClose}>\n <IconX />\n </button>\n </div>\n\n {/* Content */}\n {loading && view !== 'chat' ? (\n <div class=\"bp-loading\">\n <div class=\"bp-spinner\" />\n </div>\n ) : (\n <>\n {view === 'prechat' && (\n <PreChatForm\n channelInfo={channelInfo}\n onSubmit={handlePreChatSubmit}\n loading={loading}\n t={t}\n />\n )}\n\n {view === 'conversations' && (\n <ConversationList\n conversations={conversations}\n channelInfo={channelInfo}\n loading={loading}\n onSelect={openConversation}\n onNew={\n needsPreChat()\n ? () => setView('prechat')\n : startNewConversation\n }\n t={t}\n />\n )}\n\n {view === 'chat' && (\n <>\n <MessageList messages={messages} loading={loading} t={t} />\n {isOpen ? (\n <MessageInput\n value={inputValue}\n onChange={setInputValue}\n onSend={handleSend}\n onFileSelect={handleFileSelect}\n onFileRemove={handleFileRemove}\n attachedFile={attachedFile}\n uploading={uploading}\n disabled={sending || loading}\n placeholder={t.chat.placeholder}\n t={t}\n />\n ) : (\n <div class=\"bp-closed-banner\">\n <span class=\"bp-closed-banner__text\">{t.chat.closed}</span>\n {channelInfo.config.allowReopenConversation && (\n <button class=\"bp-closed-banner__reopen\" onClick={handleReopen}>\n {t.chat.reopen}\n </button>\n )}\n </div>\n )}\n {channelInfo.config.privacyPolicyUrl && (\n <div class=\"bp-privacy-footer\">\n <a\n href={channelInfo.config.privacyPolicyUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n {t.prechat.privacyLink}\n </a>\n </div>\n )}\n </>\n )}\n </>\n )}\n </div>\n )\n}\n","/** @jsxImportSource preact */\n\nimport type { ChannelInfo, Conversation } from '../../api/types'\nimport { IconPlus } from '../icons'\nimport type { Translations } from '../i18n'\n\ninterface ConversationListProps {\n conversations: Conversation[]\n channelInfo: ChannelInfo\n loading: boolean\n onSelect: (conversation: Conversation) => void\n onNew: () => void\n t: Translations\n}\n\nexport function ConversationList({\n conversations,\n channelInfo,\n loading,\n onSelect,\n onNew,\n t,\n}: ConversationListProps) {\n const hasOpen = conversations.some((c) => c.open)\n const canReopen = channelInfo.config.allowReopenConversation\n\n if (loading) {\n return (\n <div class=\"bp-loading\">\n <div class=\"bp-spinner\" />\n </div>\n )\n }\n\n return (\n <div class=\"bp-convlist\">\n {!hasOpen && (\n <div class=\"bp-convlist__new\">\n <button class=\"bp-convlist__new-btn\" onClick={onNew}>\n <IconPlus />\n {t.conversations.newConversation}\n </button>\n </div>\n )}\n\n <div class=\"bp-convlist__items\">\n {conversations.length === 0 ? (\n <div class=\"bp-convlist__empty\">{t.conversations.empty}</div>\n ) : (\n conversations.map((conv) => {\n const isClickable = conv.open || canReopen\n\n return (\n <button\n key={conv.id}\n class=\"bp-convlist__item\"\n onClick={() => isClickable && onSelect(conv)}\n disabled={!isClickable}\n >\n <div class=\"bp-convlist__item-top\">\n <span class=\"bp-convlist__item-title\">\n {channelInfo.name}\n </span>\n <span\n class={`bp-convlist__item-status ${conv.open ? 'bp-convlist__item-status--open' : 'bp-convlist__item-status--closed'}`}\n >\n {conv.open ? t.conversations.open : t.conversations.closed}\n </span>\n </div>\n <span class=\"bp-convlist__item-preview\">\n {conv.lastMessage?.content || t.conversations.noMessages}\n </span>\n </button>\n )\n })\n )}\n </div>\n </div>\n )\n}\n","/** @jsxImportSource preact */\n\nimport { useCallback, useRef } from 'preact/hooks'\n\nimport { IconFile, IconPaperclip, IconSend, IconX } from '../icons'\nimport type { Translations } from '../i18n'\n\nexport interface AttachedFile {\n file: File\n preview?: string\n}\n\ninterface MessageInputProps {\n value: string\n onChange: (value: string) => void\n onSend: () => void\n onFileSelect: (file: File) => void\n onFileRemove: () => void\n attachedFile: AttachedFile | null\n uploading: boolean\n disabled: boolean\n placeholder?: string\n t: Translations\n}\n\nexport function MessageInput({\n value,\n onChange,\n onSend,\n onFileSelect,\n onFileRemove,\n attachedFile,\n uploading,\n disabled,\n placeholder,\n t,\n}: MessageInputProps) {\n const textareaRef = useRef<HTMLTextAreaElement>(null)\n const fileInputRef = useRef<HTMLInputElement>(null)\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent) => {\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault()\n onSend()\n }\n },\n [onSend]\n )\n\n const handleInput = useCallback(\n (e: Event) => {\n const target = e.target as HTMLTextAreaElement\n onChange(target.value)\n target.style.height = 'auto'\n target.style.height = `${Math.min(target.scrollHeight, 100)}px`\n },\n [onChange]\n )\n\n const handleAttachClick = useCallback(() => {\n fileInputRef.current?.click()\n }, [])\n\n const handleFileChange = useCallback(\n (e: Event) => {\n const input = e.target as HTMLInputElement\n const file = input.files?.[0]\n if (file) {\n onFileSelect(file)\n }\n input.value = ''\n },\n [onFileSelect]\n )\n\n const isImage = attachedFile?.file.type.startsWith('image/')\n const canSend = (value.trim() || attachedFile) && !disabled && !uploading\n\n return (\n <div class=\"bp-composer\">\n {attachedFile && (\n <div class=\"bp-composer__preview\">\n {isImage && attachedFile.preview ? (\n <img\n src={attachedFile.preview}\n alt={attachedFile.file.name}\n class=\"bp-composer__preview-thumb\"\n />\n ) : (\n <div class=\"bp-composer__preview-icon\">\n <IconFile />\n </div>\n )}\n <div class=\"bp-composer__preview-info\">\n <div class=\"bp-composer__preview-name\">\n {attachedFile.file.name}\n </div>\n <div class=\"bp-composer__preview-status\">\n {uploading ? t.chat.uploading : formatSize(attachedFile.file.size)}\n </div>\n </div>\n {!uploading && (\n <button\n class=\"bp-composer__preview-remove\"\n onClick={onFileRemove}\n aria-label=\"Remove file\"\n >\n <IconX />\n </button>\n )}\n </div>\n )}\n\n <div class=\"bp-composer__row\">\n <button\n class=\"bp-composer__attach\"\n onClick={handleAttachClick}\n disabled={disabled || uploading || !!attachedFile}\n aria-label={t.chat.attachFile}\n >\n <IconPaperclip />\n </button>\n\n <textarea\n ref={textareaRef}\n class=\"bp-composer__field\"\n value={value}\n onInput={handleInput}\n onKeyDown={handleKeyDown}\n placeholder={placeholder || t.chat.placeholder}\n disabled={disabled}\n rows={1}\n />\n\n <button\n class=\"bp-composer__send\"\n onClick={onSend}\n disabled={!canSend}\n aria-label=\"Send message\"\n >\n <IconSend />\n </button>\n </div>\n\n <input\n type=\"file\"\n ref={fileInputRef}\n onChange={handleFileChange}\n style={{ display: 'none' }}\n accept=\"image/*,video/mp4,audio/*,.pdf,.doc,.docx,.xls,.xlsx,.txt\"\n />\n </div>\n )\n}\n\nfunction formatSize(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(0)} KB`\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`\n}\n","/** @jsxImportSource preact */\n\nimport { useEffect, useRef, useState } from 'preact/hooks'\n\nimport type { Message } from '../../api/types'\nimport type { Translations } from '../i18n'\nimport { ImageLightbox } from './ImageLightbox'\nimport { MessageMedia } from './MessageMedia'\n\ninterface MessageListProps {\n messages: Message[]\n loading: boolean\n t: Translations\n}\n\nexport function MessageList({ messages, loading, t }: MessageListProps) {\n const endRef = useRef<HTMLDivElement>(null)\n const [lightboxSrc, setLightboxSrc] = useState<string | null>(null)\n\n useEffect(() => {\n endRef.current?.scrollIntoView({ behavior: 'smooth' })\n }, [messages])\n\n if (loading) {\n return (\n <div class=\"bp-loading\">\n <div class=\"bp-spinner\" />\n </div>\n )\n }\n\n return (\n <div class=\"bp-messages\">\n {messages.map((msg) => (\n <MessageBubble\n key={msg.id}\n message={msg}\n onImageClick={setLightboxSrc}\n t={t}\n />\n ))}\n <div ref={endRef} />\n {lightboxSrc && (\n <ImageLightbox\n src={lightboxSrc}\n onClose={() => setLightboxSrc(null)}\n />\n )}\n </div>\n )\n}\n\nfunction MessageBubble({\n message,\n onImageClick,\n t,\n}: {\n message: Message\n onImageClick: (src: string) => void\n t: Translations\n}) {\n const isClient = message.role === 'client'\n const cls = isClient ? 'bp-msg bp-msg--client' : 'bp-msg bp-msg--agent'\n\n const time = new Date(message.createdAt).toLocaleTimeString([], {\n hour: '2-digit',\n minute: '2-digit',\n })\n\n return (\n <div class={cls}>\n {!isClient && (\n <div class=\"bp-msg__avatar\">\n {message.user?.avatar?.url ? (\n <img\n src={message.user.avatar.url}\n alt={message.user.firstName || 'Agent'}\n />\n ) : (\n (message.user?.firstName?.[0] || 'A').toUpperCase()\n )}\n </div>\n )}\n <div class=\"bp-msg__body\">\n {message.media && (\n <MessageMedia\n media={message.media}\n onImageClick={onImageClick}\n t={t}\n />\n )}\n {message.content && (\n <div class=\"bp-msg__content\">{message.content}</div>\n )}\n <div class=\"bp-msg__time\">{time}</div>\n </div>\n </div>\n )\n}\n","/** @jsxImportSource preact */\n\nimport { useCallback, useEffect } from 'preact/hooks'\n\nimport { IconX } from '../icons'\n\ninterface ImageLightboxProps {\n src: string\n alt?: string\n onClose: () => void\n}\n\nexport function ImageLightbox({ src, alt, onClose }: ImageLightboxProps) {\n const handleKeyDown = useCallback(\n (e: KeyboardEvent) => {\n if (e.key === 'Escape') onClose()\n },\n [onClose]\n )\n\n useEffect(() => {\n document.addEventListener('keydown', handleKeyDown)\n return () => document.removeEventListener('keydown', handleKeyDown)\n }, [handleKeyDown])\n\n return (\n <div class=\"bp-lightbox\" onClick={onClose}>\n <button class=\"bp-lightbox__close\" onClick={onClose}>\n <IconX />\n </button>\n <img\n src={src}\n alt={alt || ''}\n class=\"bp-lightbox__img\"\n onClick={(e) => e.stopPropagation()}\n />\n </div>\n )\n}\n","/** @jsxImportSource preact */\n\nimport type { Message } from '../../api/types'\nimport { IconDownload, IconFile } from '../icons'\nimport type { Translations } from '../i18n'\n\ninterface MessageMediaProps {\n media: NonNullable<Message['media']>\n onImageClick: (src: string) => void\n t: Translations\n}\n\nexport function MessageMedia({ media, onImageClick, t }: MessageMediaProps) {\n const mimeType = (media.mimeType || '').toLowerCase()\n\n if (mimeType.startsWith('image/') || media.kind === 'image') {\n const thumbSrc = media.streamUrlData?.small || media.url\n const fullSrc = media.streamUrlData?.large || media.url\n return (\n <img\n src={thumbSrc}\n alt={media.name}\n class=\"bp-media-img\"\n onClick={() => onImageClick(fullSrc)}\n />\n )\n }\n\n if (mimeType.startsWith('video/')) {\n return (\n <video controls class=\"bp-media-video\" preload=\"metadata\">\n <source src={media.url} type={mimeType} />\n </video>\n )\n }\n\n return (\n <a\n href={media.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n class=\"bp-media-file\"\n download={media.name}\n >\n <div class=\"bp-media-file__icon\">\n <IconFile />\n </div>\n <span class=\"bp-media-file__name\">{media.name}</span>\n <span class=\"bp-media-file__download\">\n <IconDownload />\n </span>\n </a>\n )\n}\n","/** @jsxImportSource preact */\n\nimport { useState } from 'preact/hooks'\n\nimport type { ChannelInfo } from '../../api/types'\nimport type { Translations } from '../i18n'\n\ninterface PreChatFormProps {\n channelInfo: ChannelInfo\n onSubmit: (data: { name?: string; email?: string }) => void\n loading: boolean\n t: Translations\n}\n\nexport function PreChatForm({\n channelInfo,\n onSubmit,\n loading,\n t,\n}: PreChatFormProps) {\n const [name, setName] = useState('')\n const [email, setEmail] = useState('')\n\n const { requireName, requireEmail, privacyPolicyUrl } = channelInfo.config\n\n const handleSubmit = (e: Event) => {\n e.preventDefault()\n onSubmit({\n name: name.trim() || undefined,\n email: email.trim() || undefined,\n })\n }\n\n const isValid =\n (!requireName || name.trim()) && (!requireEmail || email.trim())\n\n return (\n <form class=\"bp-prechat\" onSubmit={handleSubmit}>\n <div class=\"bp-prechat__title\">{t.prechat.title}</div>\n <div class=\"bp-prechat__desc\">{t.prechat.description}</div>\n\n {requireName && (\n <div class=\"bp-prechat__field\">\n <label class=\"bp-prechat__label\">{t.prechat.name}</label>\n <input\n class=\"bp-prechat__input\"\n type=\"text\"\n value={name}\n onInput={(e) => setName((e.target as HTMLInputElement).value)}\n placeholder={t.prechat.namePlaceholder}\n required\n />\n </div>\n )}\n\n {requireEmail && (\n <div class=\"bp-prechat__field\">\n <label class=\"bp-prechat__label\">{t.prechat.email}</label>\n <input\n class=\"bp-prechat__input\"\n type=\"email\"\n value={email}\n onInput={(e) => setEmail((e.target as HTMLInputElement).value)}\n placeholder={t.prechat.emailPlaceholder}\n required\n />\n </div>\n )}\n\n <button\n class=\"bp-prechat__submit\"\n type=\"submit\"\n disabled={!isValid || loading}\n >\n {loading ? t.prechat.loading : t.prechat.start}\n </button>\n\n {privacyPolicyUrl && (\n <div class=\"bp-prechat__privacy\">\n {t.prechat.privacyPrefix}{' '}\n <a href={privacyPolicyUrl} target=\"_blank\" rel=\"noopener noreferrer\">\n {t.prechat.privacyLink}\n </a>\n </div>\n )}\n </form>\n )\n}\n","// CSS exported as a string to prevent tsup from extracting it to a separate file.\n// This ensures the CSS is inlined in the JS bundle.\nexport default `#baseportal-chat-widget {\n display: block;\n position: static;\n width: 0;\n height: 0;\n overflow: visible;\n padding: 0;\n margin: 0;\n border: none;\n\n --bp-primary: #6366f1;\n --bp-primary-contrast: #ffffff;\n --bp-font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,\n 'Helvetica Neue', Arial, sans-serif;\n --bp-radius: 16px;\n --bp-radius-sm: 8px;\n --bp-bubble-size: 60px;\n --bp-shadow: 0 4px 24px rgba(0, 0, 0, 0.15);\n --bp-shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.1);\n --bp-gray-50: #f9fafb;\n --bp-gray-100: #f3f4f6;\n --bp-gray-200: #e5e7eb;\n --bp-gray-300: #d1d5db;\n --bp-gray-500: #6b7280;\n --bp-gray-700: #374151;\n --bp-gray-900: #111827;\n --bp-transition: 0.2s ease;\n}\n\n#baseportal-chat-widget *,\n#baseportal-chat-widget *::before,\n#baseportal-chat-widget *::after {\n box-sizing: border-box;\n}\n\n/* ===== Chat Bubble (FAB) ===== */\n.bp-bubble {\n pointer-events: auto;\n position: fixed;\n bottom: 24px;\n z-index: 2147483646;\n width: var(--bp-bubble-size);\n height: var(--bp-bubble-size);\n border-radius: 50%;\n background: var(--bp-primary);\n color: var(--bp-primary-contrast);\n border: none;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n box-shadow: var(--bp-shadow);\n transition: transform var(--bp-transition), box-shadow var(--bp-transition);\n font-family: var(--bp-font-family);\n font-size: 14px;\n line-height: 1.5;\n margin: 0;\n padding: 0;\n}\n\n.bp-bubble:hover {\n transform: scale(1.08);\n box-shadow: 0 6px 32px rgba(0, 0, 0, 0.2);\n}\n\n.bp-bubble--right {\n right: 24px;\n}\n\n.bp-bubble--left {\n left: 24px;\n}\n\n.bp-bubble svg {\n width: 28px;\n height: 28px;\n fill: currentColor;\n}\n\n.bp-bubble__badge {\n position: absolute;\n top: -2px;\n right: -2px;\n min-width: 20px;\n height: 20px;\n border-radius: 10px;\n background: #ef4444;\n color: #fff;\n font-size: 11px;\n font-weight: 600;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0 5px;\n}\n\n/* ===== Chat Window ===== */\n.bp-window {\n pointer-events: auto;\n position: fixed;\n bottom: 96px;\n z-index: 2147483647;\n width: 380px;\n height: 520px;\n border-radius: var(--bp-radius);\n background: #fff;\n box-shadow: var(--bp-shadow);\n display: flex;\n flex-direction: column;\n overflow: hidden;\n animation: bp-slide-up 0.25s ease-out;\n font-family: var(--bp-font-family);\n font-size: 14px;\n line-height: 1.5;\n color: var(--bp-gray-900);\n}\n\n.bp-window--right {\n right: 24px;\n}\n\n.bp-window--left {\n left: 24px;\n}\n\n@keyframes bp-slide-up {\n from {\n opacity: 0;\n transform: translateY(16px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n/* Mobile fullscreen */\n@media (max-width: 480px) {\n .bp-window {\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n width: 100%;\n height: 100%;\n border-radius: 0;\n }\n}\n\n/* ===== Header ===== */\n.bp-header {\n padding: 16px;\n background: var(--bp-primary);\n color: var(--bp-primary-contrast);\n display: flex;\n align-items: center;\n justify-content: space-between;\n flex-shrink: 0;\n}\n\n.bp-header__title {\n font-size: 16px;\n font-weight: 600;\n color: inherit;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.bp-header__back,\n.bp-header__close {\n background: none;\n border: none;\n color: inherit;\n cursor: pointer;\n padding: 4px;\n border-radius: 4px;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: background var(--bp-transition);\n}\n\n.bp-header__back:hover,\n.bp-header__close:hover {\n background: rgba(255, 255, 255, 0.15);\n}\n\n.bp-header__back svg,\n.bp-header__close svg {\n width: 18px;\n height: 18px;\n fill: currentColor;\n}\n\n/* ===== Message List ===== */\n.bp-messages {\n flex: 1;\n overflow-y: auto;\n padding: 16px;\n display: flex;\n flex-direction: column;\n gap: 8px;\n background: var(--bp-gray-50);\n}\n\n.bp-messages::-webkit-scrollbar {\n width: 4px;\n}\n\n.bp-messages::-webkit-scrollbar-thumb {\n background: var(--bp-gray-300);\n border-radius: 2px;\n}\n\n/* ===== Message Bubble ===== */\n.bp-msg {\n display: flex;\n max-width: 80%;\n}\n\n.bp-msg--client {\n align-self: flex-end;\n flex-direction: row-reverse;\n}\n\n.bp-msg--agent {\n align-self: flex-start;\n}\n\n.bp-msg__avatar {\n width: 28px;\n height: 28px;\n border-radius: 50%;\n background: var(--bp-primary);\n color: var(--bp-primary-contrast);\n font-size: 12px;\n font-weight: 600;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n margin-top: auto;\n}\n\n.bp-msg__avatar img {\n width: 100%;\n height: 100%;\n border-radius: 50%;\n object-fit: cover;\n}\n\n.bp-msg__body {\n margin: 0 8px;\n}\n\n.bp-msg__content {\n padding: 10px 14px;\n border-radius: 16px;\n white-space: pre-wrap;\n word-break: break-word;\n font-size: 14px;\n line-height: 1.4;\n}\n\n.bp-msg--client .bp-msg__content {\n background: var(--bp-primary);\n color: var(--bp-primary-contrast);\n border-bottom-right-radius: 4px;\n}\n\n.bp-msg--agent .bp-msg__content {\n background: var(--bp-gray-100);\n color: var(--bp-gray-900);\n border-bottom-left-radius: 4px;\n}\n\n.bp-msg__time {\n font-size: 11px;\n color: var(--bp-gray-500);\n margin-top: 2px;\n padding: 0 4px;\n}\n\n.bp-msg--client .bp-msg__time {\n text-align: right;\n}\n\n/* ===== Composer (Message Input) ===== */\n.bp-composer {\n margin: 8px 12px 12px;\n border: 1px solid var(--bp-gray-200);\n border-radius: 12px;\n background: #fff;\n flex-shrink: 0;\n overflow: hidden;\n transition: border-color var(--bp-transition);\n}\n\n.bp-composer:focus-within {\n border-color: var(--bp-primary);\n}\n\n.bp-composer__preview {\n padding: 8px 12px;\n border-bottom: 1px solid var(--bp-gray-100);\n display: flex;\n align-items: center;\n gap: 8px;\n background: var(--bp-gray-50);\n}\n\n.bp-composer__preview-thumb {\n width: 40px;\n height: 40px;\n border-radius: 6px;\n object-fit: cover;\n flex-shrink: 0;\n}\n\n.bp-composer__preview-icon {\n width: 36px;\n height: 36px;\n border-radius: 6px;\n background: var(--bp-gray-100);\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n color: var(--bp-gray-500);\n}\n\n.bp-composer__preview-icon svg {\n width: 18px;\n height: 18px;\n}\n\n.bp-composer__preview-info {\n flex: 1;\n min-width: 0;\n}\n\n.bp-composer__preview-name {\n font-size: 12px;\n font-weight: 500;\n color: var(--bp-gray-700);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.bp-composer__preview-status {\n font-size: 11px;\n color: var(--bp-gray-500);\n}\n\n.bp-composer__preview-remove {\n background: none;\n border: none;\n cursor: pointer;\n padding: 2px;\n color: var(--bp-gray-500);\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.bp-composer__preview-remove svg {\n width: 14px;\n height: 14px;\n}\n\n.bp-composer__preview-remove:hover {\n color: var(--bp-gray-700);\n}\n\n.bp-composer__row {\n display: flex;\n align-items: flex-end;\n padding: 4px;\n}\n\n.bp-composer__attach {\n width: 32px;\n height: 32px;\n background: none;\n border: none;\n cursor: pointer;\n color: var(--bp-gray-500);\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n border-radius: 6px;\n transition: color var(--bp-transition), background var(--bp-transition);\n}\n\n.bp-composer__attach:hover {\n color: var(--bp-primary);\n background: var(--bp-gray-50);\n}\n\n.bp-composer__attach:disabled {\n opacity: 0.4;\n cursor: not-allowed;\n}\n\n.bp-composer__attach svg {\n width: 18px;\n height: 18px;\n}\n\n.bp-composer__field {\n flex: 1;\n border: none;\n padding: 6px 4px;\n font-size: 14px;\n font-family: inherit;\n line-height: 1.4;\n resize: none;\n outline: none;\n max-height: 100px;\n overflow-y: auto;\n color: var(--bp-gray-900);\n background: transparent;\n}\n\n.bp-composer__field::placeholder {\n color: var(--bp-gray-500);\n}\n\n.bp-composer__field:disabled {\n cursor: not-allowed;\n}\n\n.bp-composer__send {\n width: 32px;\n height: 32px;\n border-radius: 50%;\n background: var(--bp-primary);\n color: var(--bp-primary-contrast);\n border: none;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n transition: opacity var(--bp-transition);\n}\n\n.bp-composer__send:disabled {\n opacity: 0.4;\n cursor: not-allowed;\n}\n\n.bp-composer__send svg {\n width: 16px;\n height: 16px;\n}\n\n/* ===== Message Media ===== */\n.bp-media-img {\n max-width: 100%;\n max-height: 240px;\n border-radius: 8px;\n cursor: pointer;\n display: block;\n object-fit: contain;\n}\n\n.bp-media-video {\n max-width: 100%;\n max-height: 240px;\n border-radius: 8px;\n display: block;\n}\n\n.bp-media-file {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n background: var(--bp-gray-50);\n border-radius: 8px;\n text-decoration: none;\n color: var(--bp-gray-700);\n transition: background var(--bp-transition);\n}\n\n.bp-media-file:hover {\n background: var(--bp-gray-100);\n}\n\n.bp-media-file__icon {\n width: 32px;\n height: 32px;\n border-radius: 6px;\n background: var(--bp-gray-200);\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n color: var(--bp-gray-500);\n}\n\n.bp-media-file__icon svg {\n width: 16px;\n height: 16px;\n}\n\n.bp-media-file__name {\n flex: 1;\n font-size: 13px;\n font-weight: 500;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n min-width: 0;\n}\n\n.bp-media-file__download svg {\n width: 16px;\n height: 16px;\n color: var(--bp-primary);\n}\n\n/* ===== Image Lightbox ===== */\n.bp-lightbox {\n position: fixed;\n inset: 0;\n z-index: 2147483647;\n background: rgba(0, 0, 0, 0.85);\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n}\n\n.bp-lightbox__img {\n max-width: 90vw;\n max-height: 90vh;\n object-fit: contain;\n border-radius: 4px;\n cursor: default;\n}\n\n.bp-lightbox__close {\n position: absolute;\n top: 16px;\n right: 16px;\n width: 36px;\n height: 36px;\n border-radius: 50%;\n background: rgba(255, 255, 255, 0.15);\n color: #fff;\n border: none;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: background var(--bp-transition);\n}\n\n.bp-lightbox__close:hover {\n background: rgba(255, 255, 255, 0.3);\n}\n\n.bp-lightbox__close svg {\n width: 20px;\n height: 20px;\n}\n\n/* ===== Pre-Chat Form ===== */\n.bp-prechat {\n flex: 1;\n padding: 24px 16px;\n display: flex;\n flex-direction: column;\n gap: 16px;\n overflow-y: auto;\n}\n\n.bp-prechat__title {\n font-size: 16px;\n font-weight: 600;\n color: var(--bp-gray-900);\n}\n\n.bp-prechat__desc {\n font-size: 13px;\n color: var(--bp-gray-500);\n}\n\n.bp-prechat__field {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.bp-prechat__label {\n font-size: 13px;\n font-weight: 500;\n color: var(--bp-gray-700);\n}\n\n.bp-prechat__input {\n border: 1px solid var(--bp-gray-200);\n border-radius: var(--bp-radius-sm);\n padding: 10px 12px;\n font-size: 14px;\n font-family: inherit;\n outline: none;\n transition: border-color var(--bp-transition);\n color: var(--bp-gray-900);\n background: #fff;\n}\n\n.bp-prechat__input:focus {\n border-color: var(--bp-primary);\n}\n\n.bp-prechat__submit {\n padding: 10px 20px;\n border-radius: var(--bp-radius-sm);\n background: var(--bp-primary);\n color: var(--bp-primary-contrast);\n border: none;\n font-size: 14px;\n font-weight: 500;\n font-family: inherit;\n cursor: pointer;\n transition: opacity var(--bp-transition);\n}\n\n.bp-prechat__submit:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.bp-prechat__privacy {\n font-size: 12px;\n color: var(--bp-gray-500);\n text-align: center;\n margin-top: auto;\n}\n\n.bp-prechat__privacy a {\n color: var(--bp-primary);\n text-decoration: underline;\n}\n\n/* ===== Conversation List ===== */\n.bp-convlist {\n flex: 1;\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n}\n\n.bp-convlist__new {\n padding: 12px 16px;\n border-bottom: 1px solid var(--bp-gray-200);\n}\n\n.bp-convlist__new-btn {\n width: 100%;\n padding: 10px 16px;\n border-radius: var(--bp-radius-sm);\n background: rgba(99, 102, 241, 0.08);\n border: none;\n cursor: pointer;\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 14px;\n font-weight: 500;\n font-family: inherit;\n color: var(--bp-primary);\n transition: background var(--bp-transition);\n}\n\n.bp-convlist__new-btn svg {\n width: 16px;\n height: 16px;\n flex-shrink: 0;\n}\n\n.bp-convlist__new-btn:hover {\n background: rgba(99, 102, 241, 0.15);\n}\n\n.bp-convlist__items {\n flex: 1;\n overflow-y: auto;\n padding: 8px;\n}\n\n.bp-convlist__item {\n width: 100%;\n padding: 12px;\n border-radius: var(--bp-radius-sm);\n background: none;\n border: none;\n cursor: pointer;\n display: flex;\n flex-direction: column;\n gap: 4px;\n text-align: left;\n font-family: inherit;\n transition: background var(--bp-transition);\n color: var(--bp-gray-900);\n}\n\n.bp-convlist__item:hover {\n background: var(--bp-gray-50);\n}\n\n.bp-convlist__item:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.bp-convlist__item-top {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n}\n\n.bp-convlist__item-title {\n font-size: 14px;\n font-weight: 500;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n flex: 1;\n}\n\n.bp-convlist__item-status {\n font-size: 11px;\n font-weight: 500;\n padding: 2px 8px;\n border-radius: 10px;\n flex-shrink: 0;\n}\n\n.bp-convlist__item-status--open {\n background: #dcfce7;\n color: #166534;\n}\n\n.bp-convlist__item-status--closed {\n background: var(--bp-gray-100);\n color: var(--bp-gray-500);\n}\n\n.bp-convlist__item-preview {\n font-size: 13px;\n color: var(--bp-gray-500);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.bp-convlist__empty {\n padding: 32px 16px;\n text-align: center;\n color: var(--bp-gray-500);\n font-size: 14px;\n}\n\n/* ===== Closed conversation banner ===== */\n.bp-closed-banner {\n padding: 14px 16px;\n border-top: 1px solid var(--bp-gray-200);\n background: var(--bp-gray-50);\n flex-shrink: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n flex-wrap: wrap;\n}\n\n.bp-closed-banner__text {\n font-size: 13px;\n color: var(--bp-gray-500);\n}\n\n.bp-closed-banner__reopen {\n background: none;\n border: none;\n padding: 0;\n font-size: 13px;\n font-weight: 500;\n font-family: inherit;\n color: var(--bp-primary);\n cursor: pointer;\n text-decoration: underline;\n text-underline-offset: 2px;\n}\n\n.bp-closed-banner__reopen:hover {\n opacity: 0.8;\n}\n\n/* ===== Privacy footer ===== */\n.bp-privacy-footer {\n padding: 4px 16px 8px;\n text-align: center;\n font-size: 11px;\n color: var(--bp-gray-500);\n flex-shrink: 0;\n}\n\n.bp-privacy-footer a {\n color: var(--bp-primary);\n text-decoration: underline;\n}\n\n/* ===== Loading ===== */\n.bp-loading {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.bp-spinner {\n width: 32px;\n height: 32px;\n border: 3px solid var(--bp-gray-200);\n border-top-color: var(--bp-primary);\n border-radius: 50%;\n animation: bp-spin 0.6s linear infinite;\n}\n\n@keyframes bp-spin {\n to {\n transform: rotate(360deg);\n }\n}\n\n/* ===== Hidden ===== */\n.bp-hidden {\n display: none !important;\n}\n` as string\n","export type EventCallback = (...args: any[]) => void\n\nexport class EventEmitter {\n private listeners = new Map<string, Set<EventCallback>>()\n\n on(event: string, callback: EventCallback): void {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set())\n }\n this.listeners.get(event)!.add(callback)\n }\n\n off(event: string, callback: EventCallback): void {\n this.listeners.get(event)?.delete(callback)\n }\n\n emit(event: string, ...args: any[]): void {\n this.listeners.get(event)?.forEach((cb) => {\n try {\n cb(...args)\n } catch (e) {\n console.error(`[BaseportalChat] Error in ${event} handler:`, e)\n }\n })\n }\n\n removeAllListeners(): void {\n this.listeners.clear()\n }\n}\n","import type { VisitorData } from '../api/types'\n\ninterface StoredData {\n conversationId?: string\n visitor?: VisitorData\n}\n\nexport class Storage {\n private prefix: string\n\n constructor(channelToken: string, email?: string) {\n this.prefix = email\n ? `bp_chat_${channelToken}_${email}`\n : `bp_chat_${channelToken}`\n }\n\n get(): StoredData {\n try {\n const raw = localStorage.getItem(this.prefix)\n return raw ? JSON.parse(raw) : {}\n } catch {\n return {}\n }\n }\n\n set(data: Partial<StoredData>): void {\n try {\n const current = this.get()\n localStorage.setItem(this.prefix, JSON.stringify({ ...current, ...data }))\n } catch {\n // localStorage unavailable (private browsing, etc.)\n }\n }\n\n getConversationId(): string | undefined {\n return this.get().conversationId\n }\n\n setConversationId(id: string): void {\n this.set({ conversationId: id })\n }\n\n getVisitor(): VisitorData | undefined {\n return this.get().visitor\n }\n\n setVisitor(visitor: VisitorData): void {\n this.set({ visitor })\n }\n\n clear(): void {\n try {\n localStorage.removeItem(this.prefix)\n } catch {\n // ignore\n }\n }\n}\n","import { ApiClient } from './api/client'\nimport type { BaseportalChatConfig, ChannelInfo, VisitorData } from './api/types'\nimport { RealtimeClient } from './realtime/ably-client'\nimport { getTranslations } from './ui/i18n'\nimport { mount, unmount, updateTheme } from './ui/mount'\nimport { EventCallback, EventEmitter } from './utils/events'\nimport { Storage } from './utils/storage'\n\nconst DEFAULT_API_URL = 'https://api.baseportal.io'\n\nexport class BaseportalChat {\n private config: Required<\n Pick<BaseportalChatConfig, 'channelToken' | 'apiUrl' | 'position' | 'locale'>\n > &\n BaseportalChatConfig\n private apiClient: ApiClient\n private realtimeClient: RealtimeClient\n private storage: Storage\n private events = new EventEmitter()\n private channelInfo: ChannelInfo | null = null\n private visitor: VisitorData | null = null\n private isAuthenticated = false\n private isOpenRef = { current: false }\n private hidden: boolean\n private mounted = false\n\n constructor(config: BaseportalChatConfig) {\n this.config = {\n ...config,\n apiUrl: config.apiUrl || DEFAULT_API_URL,\n position: config.position || 'bottom-right',\n locale: config.locale || 'pt',\n }\n\n this.hidden = config.hideOnLoad || false\n this.visitor = config.visitor || null\n this.isAuthenticated = !!config.visitor?.email\n\n this.apiClient = new ApiClient(\n this.config.channelToken,\n this.config.apiUrl\n )\n\n if (this.isAuthenticated && this.visitor?.email) {\n this.apiClient.setVisitorIdentity(this.visitor.email, this.visitor.hash)\n }\n\n this.storage = new Storage(\n this.config.channelToken,\n this.isAuthenticated ? this.visitor?.email : undefined\n )\n\n this.realtimeClient = new RealtimeClient(this.apiClient)\n\n // Restore visitor from storage\n if (!this.visitor) {\n this.visitor = this.storage.getVisitor() || null\n }\n\n this.init()\n }\n\n private async init(): Promise<void> {\n try {\n this.channelInfo = await this.apiClient.getChannelInfo()\n\n // Apply theme: SDK config > channel theme > default\n const primaryColor =\n this.config.theme?.primaryColor ||\n this.channelInfo.theme?.primaryColor ||\n '#6366f1'\n\n const t = getTranslations(this.config.locale)\n\n mount({\n channelInfo: this.channelInfo,\n apiClient: this.apiClient,\n realtimeClient: this.realtimeClient,\n storage: this.storage,\n events: this.events,\n visitor: this.visitor,\n isAuthenticated: this.isAuthenticated,\n position: this.config.position,\n hidden: this.hidden,\n t,\n container: this.config.container,\n isOpenRef: this.isOpenRef,\n setIsOpen: (open: boolean) => {\n this.isOpenRef.current = open\n },\n })\n\n // Override theme if needed\n if (primaryColor !== '#6366f1') {\n updateTheme(primaryColor)\n }\n\n this.mounted = true\n this.events.emit('ready')\n } catch (e) {\n console.error('[BaseportalChat] Failed to initialize:', e)\n }\n }\n\n // --- Visibility ---\n\n open(): void {\n if (!this.mounted) return\n this.events.emit('_open')\n this.events.emit('open')\n }\n\n close(): void {\n if (!this.mounted) return\n this.events.emit('_close')\n this.events.emit('close')\n }\n\n toggle(): void {\n if (this.isOpenRef.current) {\n this.close()\n } else {\n this.open()\n }\n }\n\n show(): void {\n this.hidden = false\n this.events.emit('show')\n }\n\n hide(): void {\n this.hidden = true\n this.events.emit('hide')\n }\n\n isOpen(): boolean {\n return this.isOpenRef.current\n }\n\n // --- Visitor ---\n\n identify(visitor: {\n email: string\n name?: string\n hash: string\n metadata?: Record<string, string>\n }): void {\n this.visitor = visitor\n this.isAuthenticated = true\n this.apiClient.setVisitorIdentity(visitor.email, visitor.hash)\n this.storage = new Storage(this.config.channelToken, visitor.email)\n this.storage.setVisitor(visitor)\n this.events.emit('identified', visitor)\n\n // Remount with new state\n if (this.mounted) {\n this.remount()\n }\n }\n\n updateVisitor(data: {\n name?: string\n metadata?: Record<string, string>\n }): void {\n if (this.visitor) {\n this.visitor = { ...this.visitor, ...data }\n this.storage.setVisitor(this.visitor)\n }\n }\n\n clearVisitor(): void {\n this.visitor = null\n this.isAuthenticated = false\n this.apiClient.clearVisitorIdentity()\n this.storage.clear()\n this.storage = new Storage(this.config.channelToken)\n this.realtimeClient.unsubscribe()\n\n if (this.mounted) {\n this.remount()\n }\n }\n\n // --- Actions ---\n\n sendMessage(content: string): void {\n // Implemented via events - App listens\n this.events.emit('_sendMessage', content)\n }\n\n setConversationId(id: string): void {\n this.events.emit('_setConversationId', id)\n }\n\n newConversation(): void {\n this.events.emit('_newConversation')\n }\n\n // --- Config ---\n\n setTheme(theme: { primaryColor?: string }): void {\n if (theme.primaryColor) {\n updateTheme(theme.primaryColor)\n }\n }\n\n setPosition(position: 'bottom-right' | 'bottom-left'): void {\n this.config.position = position\n if (this.mounted) {\n this.remount()\n }\n }\n\n setLocale(locale: 'pt' | 'en' | 'es'): void {\n this.config.locale = locale\n if (this.mounted) {\n this.remount()\n }\n }\n\n // --- Events ---\n\n on(event: string, callback: EventCallback): void {\n this.events.on(event, callback)\n }\n\n off(event: string, callback: EventCallback): void {\n this.events.off(event, callback)\n }\n\n // --- Lifecycle ---\n\n destroy(): void {\n this.realtimeClient.unsubscribe()\n this.events.removeAllListeners()\n unmount()\n this.mounted = false\n }\n\n private remount(): void {\n unmount()\n this.mounted = false\n this.init()\n }\n}\n"],"mappings":"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AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;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","names":["h","import_hooks","import_jsx_runtime","import_hooks","import_jsx_runtime","import_jsx_runtime","import_hooks","import_hooks","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_hooks","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime"]}