@chatcops/widget 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @chatcops/widget
2
2
 
3
- Embeddable AI chatbot widget. Zero dependencies, Shadow DOM isolated, ~50KB gzipped.
3
+ Embeddable AI chatbot widget. Zero dependencies, Shadow DOM isolated, ~13KB gzipped.
4
4
 
5
5
  ## Install
6
6
 
@@ -157,7 +157,7 @@ All configuration can be set via `data-*` attributes:
157
157
  - **Conversation Persistence** - localStorage for history, sessionStorage for session ID
158
158
  - **Theming** - CSS custom properties, auto-derived surface colors from `bgColor`
159
159
  - **Mobile Responsive** - Full-screen panel on screens below 768px
160
- - **i18n** - Built-in locale strings with custom override support
160
+ - **i18n** - Ships in English with custom override support for any language
161
161
  - **Accessible** - ARIA labels, semantic HTML, keyboard navigation
162
162
 
163
163
  ## License
@@ -3,6 +3,8 @@ export interface ChatClientOptions {
3
3
  apiUrl: string;
4
4
  /** Inactivity timeout in milliseconds. Defaults to 30000. */
5
5
  timeout?: number;
6
+ /** Cloudflare Turnstile site key, when the server checks Turnstile before issuing a session. */
7
+ turnstileSiteKey?: string;
6
8
  }
7
9
  export interface SendMessageOptions {
8
10
  signal?: AbortSignal;
@@ -12,6 +14,10 @@ export interface SendMessageOptions {
12
14
  export declare class ChatClient {
13
15
  private apiUrl;
14
16
  private timeout;
17
+ private sessionKey;
18
+ /** The last token, kept across page loads so the server can resume the conversation. */
19
+ private saved;
20
+ private turnstileSiteKey?;
15
21
  constructor(options: ChatClientOptions);
16
22
  sendMessage(request: WidgetChatRequest, options?: SendMessageOptions): AsyncGenerator<WidgetChatChunk>;
17
23
  }
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAErE,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,6DAA6D;IAC7D,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,kFAAkF;IAClF,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,UAAU;IACrB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,OAAO,CAAS;gBAEZ,OAAO,EAAE,iBAAiB;IAK/B,WAAW,CAChB,OAAO,EAAE,iBAAiB,EAC1B,OAAO,GAAE,kBAAuB,GAC/B,cAAc,CAAC,eAAe,CAAC;CAmHnC"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAErE,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,6DAA6D;IAC7D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gGAAgG;IAChG,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,kFAAkF;IAClF,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAQD,qBAAa,UAAU;IACrB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,UAAU,CAAS;IAC3B,wFAAwF;IACxF,OAAO,CAAC,KAAK,CAAwB;IACrC,OAAO,CAAC,gBAAgB,CAAC,CAAS;gBAEtB,OAAO,EAAE,iBAAiB;IAY/B,WAAW,CAChB,OAAO,EAAE,iBAAiB,EAC1B,OAAO,GAAE,kBAAuB,GAC/B,cAAc,CAAC,eAAe,CAAC;CAqKnC"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * The protocol v1 parts the widget reads, copied from `@chatcops/core`
3
+ * (`packages/core/src/protocol/v1.ts`) so the widget's types don't depend on
4
+ * core. `tests/protocol.test-d.ts` fails if core changes them.
5
+ */
6
+ export type WirePart = {
7
+ type: 'start';
8
+ protocol: 1;
9
+ conversationId: string;
10
+ messageId: string;
11
+ } | {
12
+ type: 'text-delta';
13
+ id: string;
14
+ delta: string;
15
+ } | {
16
+ type: 'lead-captured';
17
+ lead: Record<string, unknown>;
18
+ } | {
19
+ type: 'error';
20
+ code: string;
21
+ message?: string;
22
+ retryable: boolean;
23
+ retryAfterMs?: number;
24
+ scope?: string;
25
+ } | {
26
+ type: 'finish';
27
+ reason: string;
28
+ }
29
+ /** Parts the widget doesn't use yet. */
30
+ | {
31
+ type: 'text-start' | 'text-end' | 'source' | 'tool-call' | 'tool-result' | 'handoff' | 'agent-message' | 'suggestions';
32
+ };
33
+ //# sourceMappingURL=protocol.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../src/api/protocol.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,MAAM,QAAQ,GAChB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,CAAC,CAAC;IAAC,cAAc,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GACzE;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACjD;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,GACxD;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GAC5G;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE;AACpC,wCAAwC;GACtC;IAAE,IAAI,EAAE,YAAY,GAAG,UAAU,GAAG,QAAQ,GAAG,WAAW,GAAG,aAAa,GAAG,SAAS,GAAG,eAAe,GAAG,aAAa,CAAA;CAAE,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * A Cloudflare Turnstile token, for the server to check before it issues a
3
+ * session. Cloudflare's script loads only when this first runs, and the
4
+ * challenge renders in the page itself (not the widget's shadow root), in a
5
+ * box that stays empty unless the visitor has to click.
6
+ */
7
+ export declare function turnstileToken(siteKey: string): Promise<string>;
8
+ //# sourceMappingURL=turnstile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"turnstile.d.ts","sourceRoot":"","sources":["../../src/api/turnstile.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAwBrE"}
@@ -2,7 +2,10 @@ export interface WidgetChatRequest {
2
2
  conversationId: string;
3
3
  message: string;
4
4
  messageId?: string;
5
- regenerate?: boolean;
5
+ /** `{ assistantMessageId }` only once the server speaks protocol v1; 0.5 servers take `true`. */
6
+ regenerate?: boolean | {
7
+ assistantMessageId: string;
8
+ };
6
9
  pageContext?: {
7
10
  url: string;
8
11
  title: string;
@@ -13,9 +16,15 @@ export interface WidgetChatRequest {
13
16
  userData?: Record<string, string>;
14
17
  }
15
18
  export interface WidgetChatChunk {
19
+ /** The server gave this conversation a new id along with its session token. */
20
+ conversationId?: string;
21
+ /** The id the server saves the reply under (protocol v1). */
22
+ messageId?: string;
16
23
  content?: string;
17
24
  done?: boolean;
18
25
  error?: string;
26
+ /** How long to wait before trying again, with a `rate_limit` error. */
27
+ retryAfterMs?: number;
19
28
  leadCaptured?: boolean;
20
29
  leadData?: Record<string, unknown>;
21
30
  suggestedActions?: string[];
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/api/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,iBAAiB;IAChC,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,WAAW,CAAC,EAAE;QACZ,GAAG,EAAE,MAAM,CAAC;QACZ,KAAK,EAAE,MAAM,CAAC;QACd,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,cAAc,CAAC,EAAE,MAAM,CAAC;KACzB,CAAC;IACF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACnC;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC7B"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/api/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,iBAAiB;IAChC,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iGAAiG;IACjG,UAAU,CAAC,EAAE,OAAO,GAAG;QAAE,kBAAkB,EAAE,MAAM,CAAA;KAAE,CAAC;IACtD,WAAW,CAAC,EAAE;QACZ,GAAG,EAAE,MAAM,CAAC;QACZ,KAAK,EAAE,MAAM,CAAC;QACd,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,cAAc,CAAC,EAAE,MAAM,CAAC;KACzB,CAAC;IACF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACnC;AAED,MAAM,WAAW,eAAe;IAC9B,+EAA+E;IAC/E,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,6DAA6D;IAC7D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,uEAAuE;IACvE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC7B"}
@@ -1,7 +1,4 @@
1
- var __defProp = Object.defineProperty;
2
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
- var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
- const widgetStyles = ":host{--cc-accent: #6366f1;--cc-accent-hover: #4f46e5;--cc-on-accent: #ffffff;--cc-accent-contrast: #6164ec;--cc-text: #ffffff;--cc-bg: #0a0a0a;--cc-bg-surface: #1a1a1a;--cc-bg-input: #2a2a2a;--cc-border: #333333;--cc-text-secondary: #a0a0a0;--cc-font: system-ui, -apple-system, sans-serif;--cc-radius: 12px;--cc-shadow: 0 8px 32px rgba(0, 0, 0, .4);--cc-fab-size: 56px;--cc-panel-width: 400px;--cc-panel-height: 560px;all:initial;font-family:var(--cc-font);font-size:14px;line-height:1.5;color:var(--cc-text);-webkit-font-smoothing:antialiased}*,*:before,*:after{box-sizing:border-box;margin:0;padding:0}.cc-fab{position:fixed;bottom:20px;right:20px;width:var(--cc-fab-size);height:var(--cc-fab-size);border-radius:50%;background:var(--cc-accent);border:none;cursor:pointer;display:flex;align-items:center;justify-content:center;box-shadow:0 4px 16px #0000004d;transition:transform .2s ease,box-shadow .2s ease;z-index:10000;outline:none}.cc-fab:hover{transform:scale(1.05);box-shadow:0 6px 24px #0006}.cc-fab:active{transform:scale(.95)}.cc-fab.cc-left{right:auto;left:20px}.cc-fab svg{width:24px;height:24px;fill:var(--cc-on-accent);transition:transform .3s ease}.cc-fab.cc-open svg{transform:rotate(90deg)}.cc-fab-badge{position:absolute;top:-2px;right:-2px;width:12px;height:12px;border-radius:50%;background:#ef4444;border:2px solid var(--cc-bg);display:none}.cc-fab-badge.cc-visible{display:block}@keyframes cc-pulse{0%,to{box-shadow:0 4px 16px #0000004d}50%{box-shadow:0 4px 16px #6366f180}}.cc-fab.cc-pulse{animation:cc-pulse 2s ease-in-out 3}.cc-panel{position:fixed;bottom:88px;right:20px;width:var(--cc-panel-width);height:var(--cc-panel-height);max-height:calc(100vh - 100px);background:var(--cc-bg);border-radius:var(--cc-radius);box-shadow:var(--cc-shadow);border:1px solid var(--cc-border);display:flex;flex-direction:column;overflow:hidden;z-index:9999;opacity:0;transform:translateY(16px) scale(.95);pointer-events:none;transition:opacity .2s ease,transform .2s ease}.cc-panel.cc-visible{opacity:1;transform:translateY(0) scale(1);pointer-events:auto}.cc-panel.cc-left{right:auto;left:20px}.cc-panel.cc-inline{position:relative;bottom:auto;right:auto;left:auto;width:100%;height:100%;max-height:100%;z-index:auto;transform:none;transition:none}.cc-panel.cc-inline:not(.cc-visible){visibility:hidden}.cc-panel.cc-inline.cc-visible{transform:none}.cc-header{display:flex;align-items:center;padding:16px;background:var(--cc-bg-surface);border-bottom:1px solid var(--cc-border);flex-shrink:0}.cc-header-avatar{width:36px;height:36px;border-radius:50%;margin-right:12px;object-fit:cover}.cc-header-avatar-placeholder{width:36px;height:36px;border-radius:50%;margin-right:12px;background:var(--cc-accent);display:flex;align-items:center;justify-content:center}.cc-header-avatar-placeholder svg{width:20px;height:20px;fill:var(--cc-on-accent)}.cc-header-info{flex:1}.cc-header-name{font-size:15px;font-weight:600;color:var(--cc-text)}.cc-header-subtitle{font-size:12px;color:var(--cc-text-secondary)}.cc-header-close{width:32px;height:32px;border-radius:8px;background:transparent;border:none;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:background .15s ease}.cc-header-close:hover{background:var(--cc-bg-input)}.cc-header-close svg{width:16px;height:16px;fill:var(--cc-text-secondary)}.cc-messages{flex:1;overflow-y:auto;padding:16px;display:flex;flex-direction:column;gap:12px}.cc-messages::-webkit-scrollbar{width:4px}.cc-messages::-webkit-scrollbar-track{background:transparent}.cc-messages::-webkit-scrollbar-thumb{background:var(--cc-border);border-radius:2px}.cc-message{max-width:85%;padding:10px 14px;border-radius:var(--cc-radius);word-wrap:break-word;overflow-wrap:break-word;font-size:14px;line-height:1.5;display:flex;flex-direction:column;gap:8px}.cc-message-user{align-self:flex-end;background:var(--cc-accent-contrast);color:var(--cc-on-accent);border-bottom-right-radius:4px}.cc-message-assistant{align-self:flex-start;background:var(--cc-bg-surface);color:var(--cc-text);border-bottom-left-radius:4px}.cc-message a{color:var(--cc-accent);text-decoration:underline}.cc-message-user a{color:var(--cc-on-accent)}.cc-message-error-note{margin-top:6px;font-size:12px;color:var(--cc-text-secondary)}.cc-message code{background:#0003;padding:1px 4px;border-radius:4px;font-family:SF Mono,Cascadia Code,Consolas,monospace;font-size:13px}.cc-message pre{background:#0000004d;padding:8px 12px;border-radius:8px;overflow-x:auto;margin:4px 0}.cc-message pre code{background:transparent;padding:0}.cc-message ul,.cc-message ol{padding-left:20px;margin:4px 0}.cc-message h1,.cc-message h2,.cc-message h3,.cc-message h4,.cc-message h5,.cc-message h6{font-size:15px;font-weight:600;line-height:1.4;margin:4px 0 0}.cc-message-actions{display:flex;align-items:center}.cc-message-retry,.cc-message-regenerate{display:inline-flex;align-items:center;gap:4px;padding:4px 10px;background:transparent;border:1px solid var(--cc-border);border-radius:6px;color:var(--cc-text-secondary);font-family:var(--cc-font);font-size:12px;cursor:pointer;transition:background .15s ease,color .15s ease,opacity .15s ease}.cc-message-retry:hover,.cc-message-regenerate:hover{background:var(--cc-bg-input);color:var(--cc-text)}.cc-message-retry svg,.cc-message-regenerate svg{fill:currentColor}.cc-message-regenerate{opacity:0}.cc-message:hover .cc-message-regenerate{opacity:1}.cc-message:focus-within .cc-message-regenerate,.cc-message-regenerate:focus-visible{opacity:1}@media(hover:none){.cc-message-regenerate{opacity:1}}.cc-message-retry{border-color:#ef4444;color:#ef4444}.cc-message-retry:hover{background:#ef44441a;color:#ef4444}.cc-typing{display:flex;align-items:center;gap:4px;padding:10px 14px;align-self:flex-start;background:var(--cc-bg-surface);border-radius:var(--cc-radius);border-bottom-left-radius:4px}.cc-typing-dot{width:6px;height:6px;border-radius:50%;background:var(--cc-text-secondary);animation:cc-bounce 1.2s infinite}.cc-typing-dot:nth-child(2){animation-delay:.2s}.cc-typing-dot:nth-child(3){animation-delay:.4s}@keyframes cc-bounce{0%,60%,to{transform:translateY(0)}30%{transform:translateY(-4px)}}.cc-input-area{display:flex;align-items:flex-end;padding:12px 16px;border-top:1px solid var(--cc-border);background:var(--cc-bg);gap:8px}.cc-input{flex:1;background:var(--cc-bg-input);border:1px solid var(--cc-border);border-radius:8px;padding:8px 12px;color:var(--cc-text);font-family:var(--cc-font);font-size:14px;line-height:1.5;resize:none;outline:none;max-height:96px;overflow-y:auto;transition:border-color .15s ease}.cc-input:focus{border-color:var(--cc-accent);outline:2px solid var(--cc-accent);outline-offset:1px}.cc-input::placeholder{color:var(--cc-text-secondary)}.cc-send-btn{width:36px;height:36px;border-radius:8px;background:var(--cc-accent);border:none;cursor:pointer;display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:background .15s ease,opacity .15s ease}.cc-send-btn:hover{background:var(--cc-accent-hover)}.cc-send-btn:disabled{opacity:.4;cursor:not-allowed}.cc-send-btn svg{width:16px;height:16px;fill:var(--cc-on-accent)}.cc-footer{padding:6px 16px;text-align:center;font-size:11px;color:var(--cc-text-secondary);border-top:1px solid var(--cc-border)}.cc-footer a{color:var(--cc-text-secondary);text-decoration:none}.cc-footer a:hover{text-decoration:underline}.cc-bubble{position:fixed;bottom:84px;right:20px;background:var(--cc-bg-surface);color:var(--cc-text);padding:10px 16px;border-radius:var(--cc-radius);box-shadow:var(--cc-shadow);border:1px solid var(--cc-border);max-width:260px;font-size:13px;line-height:1.4;z-index:9998;opacity:0;transform:translateY(8px);pointer-events:none;transition:opacity .3s ease,transform .3s ease;cursor:pointer}.cc-bubble.cc-visible{opacity:1;transform:translateY(0);pointer-events:auto}.cc-bubble.cc-left{right:auto;left:20px}.cc-bubble-close{position:absolute;top:-8px;right:-8px;width:20px;height:20px;border-radius:50%;background:var(--cc-bg);border:1px solid var(--cc-border);cursor:pointer;display:flex;align-items:center;justify-content:center;font-size:10px;color:var(--cc-text-secondary)}.cc-hidden{display:none}.cc-sr-only{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap}.cc-messages-wrapper{flex:1;display:flex;flex-direction:column;min-height:0}.cc-prechat{flex:1;overflow-y:auto;padding:24px 16px;display:flex;flex-direction:column;gap:16px}.cc-prechat-title{font-size:18px;font-weight:600;color:var(--cc-text)}.cc-prechat-subtitle{font-size:13px;color:var(--cc-text-secondary);margin-top:-8px}.cc-prechat-fields{display:flex;flex-direction:column;gap:14px}.cc-prechat-field{display:flex;flex-direction:column;gap:4px}.cc-prechat-label{font-size:13px;font-weight:500;color:var(--cc-text)}.cc-prechat-label .cc-required{color:#ef4444;margin-left:2px}.cc-prechat-input,.cc-prechat-select,.cc-prechat-textarea{background:var(--cc-bg-input);border:1px solid var(--cc-border);border-radius:8px;padding:8px 12px;color:var(--cc-text);font-family:var(--cc-font);font-size:14px;outline:none;transition:border-color .15s ease}.cc-prechat-input:focus,.cc-prechat-select:focus,.cc-prechat-textarea:focus{border-color:var(--cc-accent)}.cc-prechat-select{-webkit-appearance:auto;-moz-appearance:auto;appearance:auto}.cc-prechat-textarea{resize:none;line-height:1.5}.cc-prechat-error{font-size:12px;color:#ef4444;min-height:0}.cc-prechat-error:empty{display:none}.cc-prechat-submit{background:var(--cc-accent-contrast);color:var(--cc-on-accent);border:none;border-radius:8px;padding:10px 16px;font-family:var(--cc-font);font-size:14px;font-weight:500;cursor:pointer;transition:background .15s ease;margin-top:8px}.cc-prechat-submit:hover{background:var(--cc-accent-hover)}.cc-prechat-submit:disabled{opacity:.5;cursor:not-allowed}@media(max-width:768px){.cc-fab.cc-open{display:none}.cc-panel:not(.cc-inline){width:100%;height:100%;max-height:100%;bottom:0;right:0;left:0;border-radius:0;border:none}.cc-panel.cc-left:not(.cc-inline){left:0}.cc-bubble{bottom:84px;right:16px;left:16px;max-width:none}}.cc-fab:focus-visible,.cc-header-close:focus-visible,.cc-send-btn:focus-visible,.cc-message-retry:focus-visible,.cc-message-regenerate:focus-visible,.cc-bubble-close:focus-visible,.cc-prechat-submit:focus-visible{outline:2px solid var(--cc-accent);outline-offset:3px}@media(prefers-reduced-motion:reduce){.cc-fab.cc-pulse,.cc-typing-dot{animation:none}.cc-panel,.cc-bubble{transition:none}}";
1
+ const widgetStyles = ":host{--cc-accent: #6366f1;--cc-accent-hover: #4f46e5;--cc-on-accent: #ffffff;--cc-accent-contrast: #6164ec;--cc-text: #ffffff;--cc-bg: #0a0a0a;--cc-bg-surface: #1a1a1a;--cc-bg-input: #2a2a2a;--cc-border: #333333;--cc-text-secondary: #a0a0a0;--cc-font: system-ui, -apple-system, sans-serif;--cc-radius: 12px;--cc-shadow: 0 8px 32px rgba(0,0,0,.4);--cc-fab-size: 56px;--cc-panel-width: 400px;--cc-panel-height: 560px;all:initial;font-family:var(--cc-font);font-size:14px;line-height:1.5;color:var(--cc-text);-webkit-font-smoothing:antialiased}*,*:before,*:after{box-sizing:border-box;margin:0;padding:0}.cc-fab{position:fixed;bottom:20px;right:20px;width:var(--cc-fab-size);height:var(--cc-fab-size);border-radius:50%;background:var(--cc-accent);border:none;cursor:pointer;display:flex;align-items:center;justify-content:center;box-shadow:0 4px 16px #0000004d;transition:transform .2s,box-shadow .2s;z-index:10000;outline:none}.cc-fab:hover{transform:scale(1.05);box-shadow:0 6px 24px #0006}.cc-fab:active{transform:scale(.95)}.cc-fab.cc-left{right:auto;left:20px}.cc-fab svg{width:24px;height:24px;fill:var(--cc-on-accent);transition:transform .3s}.cc-fab.cc-open svg{transform:rotate(90deg)}.cc-fab-badge{position:absolute;top:-2px;right:-2px;width:12px;height:12px;border-radius:50%;background:#ef4444;border:2px solid var(--cc-bg);display:none}.cc-fab-badge.cc-visible{display:block}@keyframes cc-pulse{0%,to{box-shadow:0 4px 16px #0000004d}50%{box-shadow:0 4px 16px #6366f180}}.cc-fab.cc-pulse{animation:cc-pulse 2s ease-in-out 3}.cc-panel{position:fixed;bottom:88px;right:20px;width:var(--cc-panel-width);height:var(--cc-panel-height);max-height:calc(100vh - 100px);background:var(--cc-bg);border-radius:var(--cc-radius);box-shadow:var(--cc-shadow);border:1px solid var(--cc-border);display:flex;flex-direction:column;overflow:hidden;z-index:9999;opacity:0;transform:translateY(16px) scale(.95);pointer-events:none;transition:opacity .2s,transform .2s}.cc-panel.cc-visible{opacity:1;transform:translateY(0) scale(1);pointer-events:auto}.cc-panel.cc-left{right:auto;left:20px}.cc-panel.cc-inline{position:relative;bottom:auto;right:auto;left:auto;width:100%;height:100%;max-height:100%;z-index:auto;transform:none;transition:none}.cc-panel.cc-inline:not(.cc-visible){visibility:hidden}.cc-panel.cc-inline.cc-visible{transform:none}.cc-header{display:flex;align-items:center;padding:16px;background:var(--cc-bg-surface);border-bottom:1px solid var(--cc-border);flex-shrink:0}.cc-header-avatar{width:36px;height:36px;border-radius:50%;margin-right:12px;object-fit:cover}.cc-header-avatar-placeholder{width:36px;height:36px;border-radius:50%;margin-right:12px;background:var(--cc-accent);display:flex;align-items:center;justify-content:center}.cc-header-avatar-placeholder svg{width:20px;height:20px;fill:var(--cc-on-accent)}.cc-header-info{flex:1}.cc-header-name{font-size:15px;font-weight:600;color:var(--cc-text)}.cc-header-subtitle{font-size:12px;color:var(--cc-text-secondary)}.cc-header-close{width:32px;height:32px;border-radius:8px;background:transparent;border:none;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:background .15s}.cc-header-close:hover{background:var(--cc-bg-input)}.cc-header-close svg{width:16px;height:16px;fill:var(--cc-text-secondary)}.cc-messages{flex:1;overflow-y:auto;padding:16px;display:flex;flex-direction:column;gap:12px}.cc-messages::-webkit-scrollbar{width:4px}.cc-messages::-webkit-scrollbar-track{background:transparent}.cc-messages::-webkit-scrollbar-thumb{background:var(--cc-border);border-radius:2px}.cc-message{max-width:85%;padding:10px 14px;border-radius:var(--cc-radius);word-wrap:break-word;overflow-wrap:break-word;font-size:14px;line-height:1.5;display:flex;flex-direction:column;gap:8px}.cc-message-user{align-self:flex-end;background:var(--cc-accent-contrast);color:var(--cc-on-accent);border-bottom-right-radius:4px}.cc-message-assistant{align-self:flex-start;background:var(--cc-bg-surface);color:var(--cc-text);border-bottom-left-radius:4px}.cc-message a{color:var(--cc-accent);text-decoration:underline}.cc-message-user a{color:var(--cc-on-accent)}.cc-message-error-note{margin-top:6px;font-size:12px;color:var(--cc-text-secondary)}.cc-message code{background:#0003;padding:1px 4px;border-radius:4px;font-family:SF Mono,Cascadia Code,Consolas,monospace;font-size:13px}.cc-message pre{background:#0000004d;padding:8px 12px;border-radius:8px;overflow-x:auto;margin:4px 0}.cc-message pre code{background:transparent;padding:0}.cc-message ul,.cc-message ol{padding-left:20px;margin:4px 0}.cc-message h1,.cc-message h2,.cc-message h3,.cc-message h4,.cc-message h5,.cc-message h6{font-size:15px;font-weight:600;line-height:1.4;margin:4px 0 0}.cc-message-actions{display:flex;align-items:center}.cc-message-retry,.cc-message-regenerate{display:inline-flex;align-items:center;gap:4px;padding:4px 10px;background:transparent;border:1px solid var(--cc-border);border-radius:6px;color:var(--cc-text-secondary);font-family:var(--cc-font);font-size:12px;cursor:pointer;transition:background .15s,color .15s,opacity .15s}.cc-message-retry:hover,.cc-message-regenerate:hover{background:var(--cc-bg-input);color:var(--cc-text)}.cc-message-retry svg,.cc-message-regenerate svg{fill:currentColor}.cc-message-regenerate{opacity:0}.cc-message:hover .cc-message-regenerate{opacity:1}.cc-message:focus-within .cc-message-regenerate,.cc-message-regenerate:focus-visible{opacity:1}@media(hover:none){.cc-message-regenerate{opacity:1}}.cc-message-retry{border-color:#ef4444;color:#ef4444}.cc-message-retry:hover{background:#ef44441a;color:#ef4444}.cc-typing{display:flex;align-items:center;gap:4px;padding:10px 14px;align-self:flex-start;background:var(--cc-bg-surface);border-radius:var(--cc-radius);border-bottom-left-radius:4px}.cc-typing-dot{width:6px;height:6px;border-radius:50%;background:var(--cc-text-secondary);animation:cc-bounce 1.2s infinite}.cc-typing-dot:nth-child(2){animation-delay:.2s}.cc-typing-dot:nth-child(3){animation-delay:.4s}@keyframes cc-bounce{0%,60%,to{transform:translateY(0)}30%{transform:translateY(-4px)}}.cc-input-area{display:flex;align-items:flex-end;padding:12px 16px;border-top:1px solid var(--cc-border);background:var(--cc-bg);gap:8px}.cc-input{flex:1;background:var(--cc-bg-input);border:1px solid var(--cc-border);border-radius:8px;padding:8px 12px;color:var(--cc-text);font-family:var(--cc-font);font-size:14px;line-height:1.5;resize:none;outline:none;max-height:96px;overflow-y:auto;transition:border-color .15s}.cc-input:focus{border-color:var(--cc-accent);outline:2px solid var(--cc-accent);outline-offset:1px}.cc-input::placeholder{color:var(--cc-text-secondary)}.cc-send-btn{width:36px;height:36px;border-radius:8px;background:var(--cc-accent);border:none;cursor:pointer;display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:background .15s,opacity .15s}.cc-send-btn:hover{background:var(--cc-accent-hover)}.cc-send-btn:disabled{opacity:.4;cursor:not-allowed}.cc-send-btn svg{width:16px;height:16px;fill:var(--cc-on-accent)}.cc-footer{padding:6px 16px;text-align:center;font-size:11px;color:var(--cc-text-secondary);border-top:1px solid var(--cc-border)}.cc-footer a{color:var(--cc-text-secondary);text-decoration:none}.cc-footer a:hover{text-decoration:underline}.cc-bubble{position:fixed;bottom:84px;right:20px;background:var(--cc-bg-surface);color:var(--cc-text);padding:10px 16px;border-radius:var(--cc-radius);box-shadow:var(--cc-shadow);border:1px solid var(--cc-border);max-width:260px;font-size:13px;line-height:1.4;z-index:9998;opacity:0;transform:translateY(8px);pointer-events:none;transition:opacity .3s,transform .3s;cursor:pointer}.cc-bubble.cc-visible{opacity:1;transform:translateY(0);pointer-events:auto}.cc-bubble.cc-left{right:auto;left:20px}.cc-bubble-close{position:absolute;top:-8px;right:-8px;width:20px;height:20px;border-radius:50%;background:var(--cc-bg);border:1px solid var(--cc-border);cursor:pointer;display:flex;align-items:center;justify-content:center;font-size:10px;color:var(--cc-text-secondary)}.cc-hidden{display:none}.cc-sr-only{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap}.cc-messages-wrapper{flex:1;display:flex;flex-direction:column;min-height:0}.cc-prechat{flex:1;overflow-y:auto;padding:24px 16px;display:flex;flex-direction:column;gap:16px}.cc-prechat-title{font-size:18px;font-weight:600;color:var(--cc-text)}.cc-prechat-subtitle{font-size:13px;color:var(--cc-text-secondary);margin-top:-8px}.cc-prechat-fields{display:flex;flex-direction:column;gap:14px}.cc-prechat-field{display:flex;flex-direction:column;gap:4px}.cc-prechat-label{font-size:13px;font-weight:500;color:var(--cc-text)}.cc-prechat-label .cc-required{color:#ef4444;margin-left:2px}.cc-prechat-input,.cc-prechat-select,.cc-prechat-textarea{background:var(--cc-bg-input);border:1px solid var(--cc-border);border-radius:8px;padding:8px 12px;color:var(--cc-text);font-family:var(--cc-font);font-size:14px;outline:none;transition:border-color .15s}.cc-prechat-input:focus,.cc-prechat-select:focus,.cc-prechat-textarea:focus{border-color:var(--cc-accent)}.cc-prechat-select{-webkit-appearance:auto;-moz-appearance:auto;appearance:auto}.cc-prechat-textarea{resize:none;line-height:1.5}.cc-prechat-error{font-size:12px;color:#ef4444;min-height:0}.cc-prechat-error:empty{display:none}.cc-prechat-submit{background:var(--cc-accent-contrast);color:var(--cc-on-accent);border:none;border-radius:8px;padding:10px 16px;font-family:var(--cc-font);font-size:14px;font-weight:500;cursor:pointer;transition:background .15s;margin-top:8px}.cc-prechat-submit:hover{background:var(--cc-accent-hover)}.cc-prechat-submit:disabled{opacity:.5;cursor:not-allowed}@media(max-width:768px){.cc-fab.cc-open{display:none}.cc-panel:not(.cc-inline){width:100%;height:100%;max-height:100%;bottom:0;right:0;left:0;border-radius:0;border:none}.cc-panel.cc-left:not(.cc-inline){left:0}.cc-bubble{bottom:84px;right:16px;left:16px;max-width:none}}.cc-fab:focus-visible,.cc-header-close:focus-visible,.cc-send-btn:focus-visible,.cc-message-retry:focus-visible,.cc-message-regenerate:focus-visible,.cc-bubble-close:focus-visible,.cc-prechat-submit:focus-visible{outline:2px solid var(--cc-accent);outline-offset:3px}@media(prefers-reduced-motion:reduce){.cc-fab.cc-pulse,.cc-typing-dot{animation:none}.cc-panel,.cc-bubble{transition:none}}";
5
2
  const HOST_ID = "chatcops-root";
6
3
  function createShadowRoot(container) {
7
4
  const host = document.createElement("div");
@@ -93,9 +90,7 @@ const RETRY_ICON = '<svg viewBox="0 0 24 24" width="14" height="14" aria-hidden=
93
90
  const REGENERATE_ICON = '<svg viewBox="0 0 24 24" width="14" height="14" aria-hidden="true"><path d="M12 4V1L8 5l4 4V6c3.31 0 6 2.69 6 6 0 1.01-.25 1.97-.7 2.8l1.46 1.46A7.93 7.93 0 0020 12c0-4.42-3.58-8-8-8zm0 14c-3.31 0-6-2.69-6-6 0-1.01.25-1.97.7-2.8L5.24 7.74A7.93 7.93 0 004 12c0 4.42 3.58 8 8 8v3l4-4-4-4v3z"/></svg>';
94
91
  class Messages {
95
92
  constructor(parent, actions) {
96
- __publicField(this, "container");
97
- __publicField(this, "typingEl", null);
98
- __publicField(this, "actions");
93
+ this.typingEl = null;
99
94
  this.actions = actions;
100
95
  this.container = document.createElement("div");
101
96
  this.container.className = "cc-messages";
@@ -141,7 +136,9 @@ class Messages {
141
136
  el == null ? void 0 : el.remove();
142
137
  }
143
138
  clearRegenerateButtons() {
144
- this.container.querySelectorAll(".cc-message-regenerate").forEach((button) => button.remove());
139
+ this.container.querySelectorAll(".cc-message-regenerate").forEach((button) => {
140
+ button.remove();
141
+ });
145
142
  this.cleanupEmptyActionContainers();
146
143
  }
147
144
  showRegenerateButton(messageId) {
@@ -179,6 +176,9 @@ class Messages {
179
176
  renderMessageElement(el, msg) {
180
177
  el.className = `cc-message cc-message-${msg.role}`;
181
178
  el.dataset.id = msg.id;
179
+ if (msg.role === "assistant" && msg.id !== "welcome") {
180
+ el.dataset.aiGenerated = "true";
181
+ }
182
182
  if (msg.status) {
183
183
  el.dataset.status = msg.status;
184
184
  } else {
@@ -262,10 +262,6 @@ class Messages {
262
262
  const MAX_MESSAGE_LENGTH = 1e4;
263
263
  class Input {
264
264
  constructor(parent, options) {
265
- __publicField(this, "area");
266
- __publicField(this, "textarea");
267
- __publicField(this, "sendBtn");
268
- __publicField(this, "onSend");
269
265
  this.onSend = options.onSend;
270
266
  this.area = document.createElement("div");
271
267
  this.area.className = "cc-input-area";
@@ -281,7 +277,7 @@ class Input {
281
277
  this.sendBtn.className = "cc-send-btn";
282
278
  this.sendBtn.disabled = true;
283
279
  this.sendBtn.setAttribute("aria-label", options.sendLabel);
284
- this.sendBtn.innerHTML = '<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M2.01 21L23 12 2.01 3 2 10l15 2-15 2z"/></svg>';
280
+ this.sendBtn.innerHTML = '<svg viewBox="0 0 24 24"><path d="M2.01 21L23 12 2.01 3 2 10l15 2-15 2z"/></svg>';
285
281
  this.sendBtn.addEventListener("click", () => this.send());
286
282
  this.textarea.addEventListener("input", () => {
287
283
  this.sendBtn.disabled = this.textarea.value.trim().length === 0;
@@ -325,15 +321,10 @@ class Input {
325
321
  }
326
322
  }
327
323
  const PANEL_ID = "cc-panel";
328
- const BOT_ICON = `<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 3c1.66 0 3 1.34 3 3s-1.34 3-3 3-3-1.34-3-3 1.34-3 3-3zm0 14.2c-2.5 0-4.71-1.28-6-3.22.03-1.99 4-3.08 6-3.08 1.99 0 5.97 1.09 6 3.08-1.29 1.94-3.5 3.22-6 3.22z"/></svg>`;
329
- const CLOSE_ICON$1 = `<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z"/></svg>`;
324
+ const BOT_ICON = `<svg viewBox="0 0 24 24"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 3c1.66 0 3 1.34 3 3s-1.34 3-3 3-3-1.34-3-3 1.34-3 3-3zm0 14.2c-2.5 0-4.71-1.28-6-3.22.03-1.99 4-3.08 6-3.08 1.99 0 5.97 1.09 6 3.08-1.29 1.94-3.5 3.22-6 3.22z"/></svg>`;
325
+ const CLOSE_ICON$1 = `<svg viewBox="0 0 24 24"><path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z"/></svg>`;
330
326
  class Panel {
331
327
  constructor(root, options) {
332
- __publicField(this, "el");
333
- __publicField(this, "inline");
334
- __publicField(this, "messages");
335
- __publicField(this, "input");
336
- __publicField(this, "messagesContainer");
337
328
  this.inline = options.inline ?? false;
338
329
  this.el = document.createElement("div");
339
330
  this.el.className = "cc-panel";
@@ -439,15 +430,10 @@ class Panel {
439
430
  return div.innerHTML;
440
431
  }
441
432
  }
442
- const CHAT_ICON = `<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M20 2H4c-1.1 0-2 .9-2 2v18l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm0 14H5.17L4 17.17V4h16v12z"/><path d="M7 9h10v2H7zm0-3h10v2H7z"/></svg>`;
443
- const CLOSE_ICON = `<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z"/></svg>`;
433
+ const CHAT_ICON = `<svg viewBox="0 0 24 24"><path d="M20 2H4c-1.1 0-2 .9-2 2v18l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm0 14H5.17L4 17.17V4h16v12z"/><path d="M7 9h10v2H7zm0-3h10v2H7z"/></svg>`;
434
+ const CLOSE_ICON = `<svg viewBox="0 0 24 24"><path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z"/></svg>`;
444
435
  class FAB {
445
436
  constructor(root, options) {
446
- __publicField(this, "el");
447
- __publicField(this, "badge");
448
- __publicField(this, "isOpen", false);
449
- __publicField(this, "openLabel");
450
- __publicField(this, "closeLabel");
451
437
  this.openLabel = options.openLabel;
452
438
  this.closeLabel = options.closeLabel;
453
439
  this.el = document.createElement("button");
@@ -469,7 +455,6 @@ class FAB {
469
455
  root.appendChild(this.el);
470
456
  }
471
457
  setOpen(open) {
472
- this.isOpen = open;
473
458
  this.el.innerHTML = open ? CLOSE_ICON : CHAT_ICON;
474
459
  if (!open) this.el.appendChild(this.badge);
475
460
  this.el.classList.toggle("cc-open", open);
@@ -492,8 +477,7 @@ class FAB {
492
477
  const BUBBLE_SHOWN_KEY = "chatcops_bubble_shown";
493
478
  class WelcomeBubble {
494
479
  constructor(root, options) {
495
- __publicField(this, "el");
496
- __publicField(this, "timerId", null);
480
+ this.timerId = null;
497
481
  this.el = document.createElement("div");
498
482
  this.el.className = "cc-bubble";
499
483
  if (options.position === "bottom-left") {
@@ -546,12 +530,43 @@ class WelcomeBubble {
546
530
  this.el.remove();
547
531
  }
548
532
  }
533
+ let loading;
534
+ async function turnstileToken(siteKey) {
535
+ loading ?? (loading = new Promise((resolve, reject) => {
536
+ const script = document.createElement("script");
537
+ script.src = "https://challenges.cloudflare.com/turnstile/v0/api.js?render=explicit";
538
+ script.onload = resolve;
539
+ script.onerror = reject;
540
+ document.head.append(script);
541
+ }));
542
+ await loading;
543
+ const box = document.createElement("div");
544
+ box.style.cssText = "position:fixed;bottom:96px;right:24px;z-index:2147483647";
545
+ document.body.append(box);
546
+ try {
547
+ return await new Promise((resolve, reject) => {
548
+ window.turnstile.render(box, {
549
+ sitekey: siteKey,
550
+ appearance: "interaction-only",
551
+ callback: resolve,
552
+ "error-callback": reject
553
+ });
554
+ });
555
+ } finally {
556
+ box.remove();
557
+ }
558
+ }
549
559
  class ChatClient {
550
560
  constructor(options) {
551
- __publicField(this, "apiUrl");
552
- __publicField(this, "timeout");
561
+ this.saved = {};
553
562
  this.apiUrl = options.apiUrl;
563
+ this.turnstileSiteKey = options.turnstileSiteKey;
554
564
  this.timeout = options.timeout ?? 3e4;
565
+ this.sessionKey = `chatcops-session:${options.apiUrl}`;
566
+ try {
567
+ this.saved = JSON.parse(localStorage.getItem(this.sessionKey) || "{}");
568
+ } catch {
569
+ }
555
570
  }
556
571
  async *sendMessage(request, options = {}) {
557
572
  var _a;
@@ -596,19 +611,41 @@ class ChatClient {
596
611
  }
597
612
  resetTimeout();
598
613
  try {
599
- const response = await fetch(this.apiUrl, {
614
+ const post = (url, body, token) => fetch(url, {
600
615
  method: "POST",
601
- headers: { "Content-Type": "application/json" },
602
- body: JSON.stringify(request),
616
+ headers: { "Content-Type": "application/json", ...token && { Authorization: `Bearer ${token}` } },
617
+ body: JSON.stringify(body),
603
618
  signal: controller.signal
604
619
  });
620
+ const saved = this.saved;
621
+ const resumable = saved.conversationId === request.conversationId;
622
+ let response = await post(this.apiUrl, { protocol: 1, ...request }, resumable ? saved.token : void 0);
623
+ if (response.status === 401) {
624
+ const minted = await post(this.apiUrl.replace(/\/?(\?.*)?$/, "/session$1"), {
625
+ conversationId: request.conversationId,
626
+ previousToken: saved.token,
627
+ turnstileToken: this.turnstileSiteKey && !resumable ? await turnstileToken(this.turnstileSiteKey) : void 0
628
+ });
629
+ if (minted.ok) {
630
+ const session = await minted.json();
631
+ this.saved = session;
632
+ try {
633
+ localStorage.setItem(this.sessionKey, JSON.stringify(session));
634
+ } catch {
635
+ }
636
+ if (session.conversationId !== request.conversationId) {
637
+ request = { ...request, conversationId: session.conversationId };
638
+ yield { conversationId: session.conversationId };
639
+ }
640
+ response = await post(this.apiUrl, { protocol: 1, ...request }, session.token);
641
+ } else {
642
+ this.saved = {};
643
+ }
644
+ }
605
645
  if (!response.ok) {
646
+ const { error } = await response.json().catch(() => ({}));
606
647
  await cleanup();
607
- if (response.status === 429) {
608
- yield { error: "rate_limit" };
609
- return;
610
- }
611
- yield { error: `HTTP ${response.status}` };
648
+ yield (error == null ? void 0 : error.code) ? errorChunk(error.code, error.retryAfterMs) : { error: response.status === 429 ? "rate_limit" : `HTTP ${response.status}` };
612
649
  return;
613
650
  }
614
651
  reader = (_a = response.body) == null ? void 0 : _a.getReader();
@@ -619,6 +656,8 @@ class ChatClient {
619
656
  }
620
657
  const decoder = new TextDecoder();
621
658
  let buffer = "";
659
+ let v1 = false;
660
+ let finished = false;
622
661
  while (true) {
623
662
  const { done, value } = await reader.read();
624
663
  if (done) break;
@@ -632,17 +671,27 @@ class ChatClient {
632
671
  const data = trimmed.slice(6);
633
672
  if (data === "[DONE]") {
634
673
  await cleanup();
635
- yield { done: true };
674
+ yield v1 && !finished ? { error: "cut_off" } : { done: true };
636
675
  return;
637
676
  }
677
+ let chunk;
638
678
  try {
639
- yield JSON.parse(data);
679
+ chunk = JSON.parse(data);
640
680
  } catch {
681
+ continue;
682
+ }
683
+ if ("type" in chunk) {
684
+ v1 = true;
685
+ if (chunk.type === "finish") finished = true;
686
+ const mapped = fromPart(chunk);
687
+ if (mapped) yield mapped;
688
+ } else {
689
+ yield chunk;
641
690
  }
642
691
  }
643
692
  }
644
693
  await cleanup();
645
- yield { done: true };
694
+ yield buffer.trim() === "data: [DONE]" ? { done: true } : { error: v1 ? "cut_off" : "network" };
646
695
  } catch (err) {
647
696
  await cleanup();
648
697
  if (err instanceof DOMException && err.name === "AbortError") {
@@ -655,21 +704,65 @@ class ChatClient {
655
704
  }
656
705
  }
657
706
  }
707
+ const ERROR_TYPES = {
708
+ rate_limited: "rate_limit",
709
+ timeout: "timeout",
710
+ budget_exceeded: "budget",
711
+ budget_daily: "budget_daily",
712
+ provider_unavailable: "unavailable"
713
+ };
714
+ function errorChunk(code, retryAfterMs) {
715
+ return { error: ERROR_TYPES[code] ?? "provider_error", retryAfterMs };
716
+ }
717
+ function fromPart(part) {
718
+ switch (part.type) {
719
+ case "start":
720
+ return { messageId: part.messageId };
721
+ case "text-delta":
722
+ return { content: part.delta };
723
+ case "lead-captured":
724
+ return { leadCaptured: true, leadData: part.lead };
725
+ case "error":
726
+ return errorChunk(part.code === "budget_exceeded" && part.scope !== "conversation" ? "budget_daily" : part.code, part.retryAfterMs);
727
+ case "finish":
728
+ return part.reason === "error" || part.reason === "aborted" ? null : { done: true };
729
+ default:
730
+ return null;
731
+ }
732
+ }
658
733
  const KEY_PREFIX = "chatcops_conversation";
659
734
  const SESSION_KEY_PREFIX = "chatcops_session_id";
660
735
  class ConversationStorage {
661
736
  /** Without a siteId the keys are the ones the widget has always used. */
662
737
  constructor(siteId) {
663
- __publicField(this, "key");
664
- __publicField(this, "sessionKey");
665
738
  this.key = siteId ? `${KEY_PREFIX}_${siteId}` : KEY_PREFIX;
666
739
  this.sessionKey = siteId ? `${SESSION_KEY_PREFIX}_${siteId}` : SESSION_KEY_PREFIX;
667
740
  }
668
741
  load() {
669
742
  try {
670
743
  const raw = localStorage.getItem(this.key);
671
- if (!raw) return null;
672
- return JSON.parse(raw);
744
+ if (raw === null) return null;
745
+ let parsed;
746
+ try {
747
+ parsed = JSON.parse(raw);
748
+ } catch {
749
+ this.clear();
750
+ return null;
751
+ }
752
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed) || typeof parsed.id !== "string" || !Array.isArray(parsed.messages)) {
753
+ this.clear();
754
+ return null;
755
+ }
756
+ const record = parsed;
757
+ const rawMessages = record.messages;
758
+ const messages = rawMessages.filter(
759
+ (msg) => typeof msg === "object" && msg !== null && !Array.isArray(msg) && (msg.role === "user" || msg.role === "assistant") && typeof msg.content === "string"
760
+ );
761
+ return {
762
+ ...record,
763
+ id: record.id,
764
+ messages
765
+ };
673
766
  } catch {
674
767
  return null;
675
768
  }
@@ -741,7 +834,8 @@ class ConversationStorage {
741
834
  const DEFAULT = "";
742
835
  const CLAIMS_KEY = Symbol.for("chatcops.storageClaims");
743
836
  const store = globalThis;
744
- const claims = store[CLAIMS_KEY] ?? (store[CLAIMS_KEY] = /* @__PURE__ */ new Map());
837
+ store[CLAIMS_KEY] ?? (store[CLAIMS_KEY] = /* @__PURE__ */ new Map());
838
+ const claims = store[CLAIMS_KEY];
745
839
  function inUse(name) {
746
840
  const live = claims.get(name);
747
841
  if (!live) return false;
@@ -868,6 +962,11 @@ const en = {
868
962
  errorGeneric: "Something went wrong. Please try again.",
869
963
  errorNetwork: "Connection error. Please check your network.",
870
964
  errorRateLimit: "Too many messages. Please wait a moment.",
965
+ errorRateLimitWait: "Too many messages. Please try again in {seconds} seconds.",
966
+ errorBudget: "This chat has reached its limit.",
967
+ errorBudgetDaily: "The assistant has reached its limit for today. Please try again later.",
968
+ errorUnavailable: "The assistant is unavailable right now. Please try again later.",
969
+ errorCutOff: "The reply was cut off.",
871
970
  typingIndicator: "Typing...",
872
971
  poweredBy: "Powered by ChatCops",
873
972
  newConversation: "New conversation",
@@ -888,11 +987,8 @@ function getWidgetLocale(code, overrides) {
888
987
  const MAX_PRECHAT_FIELD_LENGTH = 500;
889
988
  class PreChatForm {
890
989
  constructor(parent, options) {
891
- __publicField(this, "container");
892
- __publicField(this, "fieldElements", /* @__PURE__ */ new Map());
893
- __publicField(this, "errorElements", /* @__PURE__ */ new Map());
894
- __publicField(this, "submitBtn");
895
- __publicField(this, "options");
990
+ this.fieldElements = /* @__PURE__ */ new Map();
991
+ this.errorElements = /* @__PURE__ */ new Map();
896
992
  this.options = options;
897
993
  this.container = document.createElement("div");
898
994
  this.container.className = "cc-prechat";
@@ -1027,7 +1123,6 @@ class PreChatForm {
1027
1123
  if (field.type === "email" && value && !this.isValidEmail(value)) {
1028
1124
  this.showError(field.name, this.options.locale.preChatInvalidEmail);
1029
1125
  valid = false;
1030
- continue;
1031
1126
  }
1032
1127
  }
1033
1128
  if (valid) {
@@ -1065,31 +1160,26 @@ class PreChatForm {
1065
1160
  this.errorElements.clear();
1066
1161
  }
1067
1162
  }
1163
+ const ERROR_MESSAGES = {
1164
+ network: "errorNetwork",
1165
+ timeout: "errorNetwork",
1166
+ provider_error: "errorGeneric",
1167
+ budget: "errorBudget",
1168
+ budget_daily: "errorBudgetDaily",
1169
+ unavailable: "errorUnavailable",
1170
+ cut_off: "errorCutOff"
1171
+ };
1068
1172
  class Widget {
1069
1173
  constructor(config) {
1070
- __publicField(this, "config");
1071
- __publicField(this, "shadow");
1072
- __publicField(this, "mounted", false);
1073
- __publicField(this, "fab");
1074
- __publicField(this, "panel");
1075
- __publicField(this, "bubble");
1076
- __publicField(this, "preChatFormEl");
1077
- __publicField(this, "client");
1078
- __publicField(this, "storage");
1079
- __publicField(this, "namespace");
1080
- __publicField(this, "locale");
1081
- __publicField(this, "conversationId");
1082
- __publicField(this, "messages", []);
1083
- __publicField(this, "userData");
1084
- __publicField(this, "isStreaming", false);
1085
- __publicField(this, "destroyed", false);
1086
- __publicField(this, "abortController");
1087
- __publicField(this, "retryRequests", /* @__PURE__ */ new Map());
1088
- __publicField(this, "eventHandlers", /* @__PURE__ */ new Map());
1089
- __publicField(this, "containerEl");
1090
- __publicField(this, "autoOpenTimer");
1174
+ this.mounted = false;
1175
+ this.messages = [];
1176
+ this.isStreaming = false;
1177
+ this.v1 = false;
1178
+ this.destroyed = false;
1179
+ this.retryRequests = /* @__PURE__ */ new Map();
1180
+ this.eventHandlers = /* @__PURE__ */ new Map();
1091
1181
  this.config = config;
1092
- this.client = new ChatClient({ apiUrl: config.apiUrl, timeout: config.timeout });
1182
+ this.client = new ChatClient({ apiUrl: config.apiUrl, timeout: config.timeout, turnstileSiteKey: config.turnstileSiteKey });
1093
1183
  this.namespace = claimNamespace(
1094
1184
  config.siteId,
1095
1185
  config.mode ?? "popup",
@@ -1263,7 +1353,9 @@ class Widget {
1263
1353
  emit(event, ...args) {
1264
1354
  var _a;
1265
1355
  if (this.destroyed) return;
1266
- (_a = this.eventHandlers.get(event)) == null ? void 0 : _a.forEach((h) => h(...args));
1356
+ (_a = this.eventHandlers.get(event)) == null ? void 0 : _a.forEach((h) => {
1357
+ h(...args);
1358
+ });
1267
1359
  }
1268
1360
  isPreChatCompleted() {
1269
1361
  return this.storage.isPreChatCompleted(this.conversationId);
@@ -1365,7 +1457,8 @@ class Widget {
1365
1457
  this.retryRequests.delete(assistantMessageId);
1366
1458
  this.messages = this.messages.filter((message) => message.id !== assistantMessageId);
1367
1459
  await this.sendToServer(userMessage.content, {
1368
- regenerate: true,
1460
+ // A v1 server saved the reply under this id; a 0.5 server only knows `true`.
1461
+ regenerate: this.v1 ? { assistantMessageId } : true,
1369
1462
  userMessageId: userMessage.id
1370
1463
  });
1371
1464
  }
@@ -1395,7 +1488,7 @@ class Widget {
1395
1488
  if (this.destroyed) break;
1396
1489
  if (chunk.error) {
1397
1490
  const errorType = this.resolveErrorType(chunk.error);
1398
- this.markFailed(assistantMsg, this.getErrorMessage(errorType));
1491
+ this.markFailed(assistantMsg, this.getErrorMessage(errorType, chunk.retryAfterMs));
1399
1492
  assistantMsg.errorType = errorType;
1400
1493
  hasError = true;
1401
1494
  this.retryRequests.set(assistantMsg.id, {
@@ -1418,6 +1511,11 @@ class Widget {
1418
1511
  requestCompleted = true;
1419
1512
  break;
1420
1513
  }
1514
+ if (chunk.conversationId) this.conversationId = chunk.conversationId;
1515
+ if (chunk.messageId) {
1516
+ assistantMsg.id = chunk.messageId;
1517
+ this.v1 = true;
1518
+ }
1421
1519
  if (chunk.leadCaptured) {
1422
1520
  (_d = (_c = this.config).onLeadCaptured) == null ? void 0 : _d.call(_c, chunk.leadData);
1423
1521
  this.emit("leadCaptured", chunk.leadData);
@@ -1483,7 +1581,7 @@ class Widget {
1483
1581
  createRequest(text, options) {
1484
1582
  var _a;
1485
1583
  const pageContext = this.config.pageContext !== false ? { url: window.location.href, title: document.title } : void 0;
1486
- const includeUserData = Boolean(((_a = this.config.preChatForm) == null ? void 0 : _a.enabled) && this.userData);
1584
+ const includeUserData = Boolean(((_a = this.config.preChatForm) == null ? void 0 : _a.enabled) && this.userData && !this.v1);
1487
1585
  return {
1488
1586
  conversationId: this.conversationId,
1489
1587
  message: text,
@@ -1524,15 +1622,7 @@ class Widget {
1524
1622
  }
1525
1623
  }
1526
1624
  resolveErrorType(error) {
1527
- switch (error) {
1528
- case "rate_limit":
1529
- case "network":
1530
- case "provider_error":
1531
- case "timeout":
1532
- return error;
1533
- default:
1534
- return "provider_error";
1535
- }
1625
+ return error in ERROR_MESSAGES || error === "rate_limit" ? error : "provider_error";
1536
1626
  }
1537
1627
  /**
1538
1628
  * Marks a reply as failed. Text that already streamed stays, and the error
@@ -1546,16 +1636,11 @@ class Widget {
1546
1636
  message.content = errorMessage;
1547
1637
  }
1548
1638
  }
1549
- getErrorMessage(errorType) {
1550
- switch (errorType) {
1551
- case "rate_limit":
1552
- return this.locale.errorRateLimit;
1553
- case "network":
1554
- case "timeout":
1555
- return this.locale.errorNetwork;
1556
- default:
1557
- return this.locale.errorGeneric;
1639
+ getErrorMessage(errorType, retryAfterMs) {
1640
+ if (errorType === "rate_limit") {
1641
+ return retryAfterMs ? this.locale.errorRateLimitWait.replace("{seconds}", String(Math.ceil(retryAfterMs / 1e3))) : this.locale.errorRateLimit;
1558
1642
  }
1643
+ return this.locale[ERROR_MESSAGES[errorType] ?? "errorGeneric"];
1559
1644
  }
1560
1645
  saveHistory() {
1561
1646
  if (this.config.persistHistory === false) return;
@@ -1634,6 +1719,7 @@ function autoInit(script) {
1634
1719
  const container = script.dataset.container;
1635
1720
  ChatCops.init({
1636
1721
  apiUrl,
1722
+ turnstileSiteKey: script.dataset.turnstileSiteKey,
1637
1723
  mode: mode || void 0,
1638
1724
  container: container || void 0,
1639
1725
  theme: {
@@ -1 +1 @@
1
- var ChatCops=function(e){"use strict";var t=Object.defineProperty,s=(e,s,a)=>((e,s,a)=>s in e?t(e,s,{enumerable:!0,configurable:!0,writable:!0,value:a}):e[s]=a)(e,"symbol"!=typeof s?s+"":s,a);const a="chatcops-root";function i(e){const t=document.createElement("div");t.id=function(){if(!document.getElementById(a))return a;let e=2;for(;document.getElementById(`${a}-${e}`);)e+=1;return`${a}-${e}`}(),t.className=a,e?e.appendChild(t):document.body.appendChild(t);const s=t.attachShadow({mode:"open"}),i=document.createElement("style");return i.textContent=":host{--cc-accent: #6366f1;--cc-accent-hover: #4f46e5;--cc-on-accent: #ffffff;--cc-accent-contrast: #6164ec;--cc-text: #ffffff;--cc-bg: #0a0a0a;--cc-bg-surface: #1a1a1a;--cc-bg-input: #2a2a2a;--cc-border: #333333;--cc-text-secondary: #a0a0a0;--cc-font: system-ui, -apple-system, sans-serif;--cc-radius: 12px;--cc-shadow: 0 8px 32px rgba(0, 0, 0, .4);--cc-fab-size: 56px;--cc-panel-width: 400px;--cc-panel-height: 560px;all:initial;font-family:var(--cc-font);font-size:14px;line-height:1.5;color:var(--cc-text);-webkit-font-smoothing:antialiased}*,*:before,*:after{box-sizing:border-box;margin:0;padding:0}.cc-fab{position:fixed;bottom:20px;right:20px;width:var(--cc-fab-size);height:var(--cc-fab-size);border-radius:50%;background:var(--cc-accent);border:none;cursor:pointer;display:flex;align-items:center;justify-content:center;box-shadow:0 4px 16px #0000004d;transition:transform .2s ease,box-shadow .2s ease;z-index:10000;outline:none}.cc-fab:hover{transform:scale(1.05);box-shadow:0 6px 24px #0006}.cc-fab:active{transform:scale(.95)}.cc-fab.cc-left{right:auto;left:20px}.cc-fab svg{width:24px;height:24px;fill:var(--cc-on-accent);transition:transform .3s ease}.cc-fab.cc-open svg{transform:rotate(90deg)}.cc-fab-badge{position:absolute;top:-2px;right:-2px;width:12px;height:12px;border-radius:50%;background:#ef4444;border:2px solid var(--cc-bg);display:none}.cc-fab-badge.cc-visible{display:block}@keyframes cc-pulse{0%,to{box-shadow:0 4px 16px #0000004d}50%{box-shadow:0 4px 16px #6366f180}}.cc-fab.cc-pulse{animation:cc-pulse 2s ease-in-out 3}.cc-panel{position:fixed;bottom:88px;right:20px;width:var(--cc-panel-width);height:var(--cc-panel-height);max-height:calc(100vh - 100px);background:var(--cc-bg);border-radius:var(--cc-radius);box-shadow:var(--cc-shadow);border:1px solid var(--cc-border);display:flex;flex-direction:column;overflow:hidden;z-index:9999;opacity:0;transform:translateY(16px) scale(.95);pointer-events:none;transition:opacity .2s ease,transform .2s ease}.cc-panel.cc-visible{opacity:1;transform:translateY(0) scale(1);pointer-events:auto}.cc-panel.cc-left{right:auto;left:20px}.cc-panel.cc-inline{position:relative;bottom:auto;right:auto;left:auto;width:100%;height:100%;max-height:100%;z-index:auto;transform:none;transition:none}.cc-panel.cc-inline:not(.cc-visible){visibility:hidden}.cc-panel.cc-inline.cc-visible{transform:none}.cc-header{display:flex;align-items:center;padding:16px;background:var(--cc-bg-surface);border-bottom:1px solid var(--cc-border);flex-shrink:0}.cc-header-avatar{width:36px;height:36px;border-radius:50%;margin-right:12px;object-fit:cover}.cc-header-avatar-placeholder{width:36px;height:36px;border-radius:50%;margin-right:12px;background:var(--cc-accent);display:flex;align-items:center;justify-content:center}.cc-header-avatar-placeholder svg{width:20px;height:20px;fill:var(--cc-on-accent)}.cc-header-info{flex:1}.cc-header-name{font-size:15px;font-weight:600;color:var(--cc-text)}.cc-header-subtitle{font-size:12px;color:var(--cc-text-secondary)}.cc-header-close{width:32px;height:32px;border-radius:8px;background:transparent;border:none;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:background .15s ease}.cc-header-close:hover{background:var(--cc-bg-input)}.cc-header-close svg{width:16px;height:16px;fill:var(--cc-text-secondary)}.cc-messages{flex:1;overflow-y:auto;padding:16px;display:flex;flex-direction:column;gap:12px}.cc-messages::-webkit-scrollbar{width:4px}.cc-messages::-webkit-scrollbar-track{background:transparent}.cc-messages::-webkit-scrollbar-thumb{background:var(--cc-border);border-radius:2px}.cc-message{max-width:85%;padding:10px 14px;border-radius:var(--cc-radius);word-wrap:break-word;overflow-wrap:break-word;font-size:14px;line-height:1.5;display:flex;flex-direction:column;gap:8px}.cc-message-user{align-self:flex-end;background:var(--cc-accent-contrast);color:var(--cc-on-accent);border-bottom-right-radius:4px}.cc-message-assistant{align-self:flex-start;background:var(--cc-bg-surface);color:var(--cc-text);border-bottom-left-radius:4px}.cc-message a{color:var(--cc-accent);text-decoration:underline}.cc-message-user a{color:var(--cc-on-accent)}.cc-message-error-note{margin-top:6px;font-size:12px;color:var(--cc-text-secondary)}.cc-message code{background:#0003;padding:1px 4px;border-radius:4px;font-family:SF Mono,Cascadia Code,Consolas,monospace;font-size:13px}.cc-message pre{background:#0000004d;padding:8px 12px;border-radius:8px;overflow-x:auto;margin:4px 0}.cc-message pre code{background:transparent;padding:0}.cc-message ul,.cc-message ol{padding-left:20px;margin:4px 0}.cc-message h1,.cc-message h2,.cc-message h3,.cc-message h4,.cc-message h5,.cc-message h6{font-size:15px;font-weight:600;line-height:1.4;margin:4px 0 0}.cc-message-actions{display:flex;align-items:center}.cc-message-retry,.cc-message-regenerate{display:inline-flex;align-items:center;gap:4px;padding:4px 10px;background:transparent;border:1px solid var(--cc-border);border-radius:6px;color:var(--cc-text-secondary);font-family:var(--cc-font);font-size:12px;cursor:pointer;transition:background .15s ease,color .15s ease,opacity .15s ease}.cc-message-retry:hover,.cc-message-regenerate:hover{background:var(--cc-bg-input);color:var(--cc-text)}.cc-message-retry svg,.cc-message-regenerate svg{fill:currentColor}.cc-message-regenerate{opacity:0}.cc-message:hover .cc-message-regenerate{opacity:1}.cc-message:focus-within .cc-message-regenerate,.cc-message-regenerate:focus-visible{opacity:1}@media(hover:none){.cc-message-regenerate{opacity:1}}.cc-message-retry{border-color:#ef4444;color:#ef4444}.cc-message-retry:hover{background:#ef44441a;color:#ef4444}.cc-typing{display:flex;align-items:center;gap:4px;padding:10px 14px;align-self:flex-start;background:var(--cc-bg-surface);border-radius:var(--cc-radius);border-bottom-left-radius:4px}.cc-typing-dot{width:6px;height:6px;border-radius:50%;background:var(--cc-text-secondary);animation:cc-bounce 1.2s infinite}.cc-typing-dot:nth-child(2){animation-delay:.2s}.cc-typing-dot:nth-child(3){animation-delay:.4s}@keyframes cc-bounce{0%,60%,to{transform:translateY(0)}30%{transform:translateY(-4px)}}.cc-input-area{display:flex;align-items:flex-end;padding:12px 16px;border-top:1px solid var(--cc-border);background:var(--cc-bg);gap:8px}.cc-input{flex:1;background:var(--cc-bg-input);border:1px solid var(--cc-border);border-radius:8px;padding:8px 12px;color:var(--cc-text);font-family:var(--cc-font);font-size:14px;line-height:1.5;resize:none;outline:none;max-height:96px;overflow-y:auto;transition:border-color .15s ease}.cc-input:focus{border-color:var(--cc-accent);outline:2px solid var(--cc-accent);outline-offset:1px}.cc-input::placeholder{color:var(--cc-text-secondary)}.cc-send-btn{width:36px;height:36px;border-radius:8px;background:var(--cc-accent);border:none;cursor:pointer;display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:background .15s ease,opacity .15s ease}.cc-send-btn:hover{background:var(--cc-accent-hover)}.cc-send-btn:disabled{opacity:.4;cursor:not-allowed}.cc-send-btn svg{width:16px;height:16px;fill:var(--cc-on-accent)}.cc-footer{padding:6px 16px;text-align:center;font-size:11px;color:var(--cc-text-secondary);border-top:1px solid var(--cc-border)}.cc-footer a{color:var(--cc-text-secondary);text-decoration:none}.cc-footer a:hover{text-decoration:underline}.cc-bubble{position:fixed;bottom:84px;right:20px;background:var(--cc-bg-surface);color:var(--cc-text);padding:10px 16px;border-radius:var(--cc-radius);box-shadow:var(--cc-shadow);border:1px solid var(--cc-border);max-width:260px;font-size:13px;line-height:1.4;z-index:9998;opacity:0;transform:translateY(8px);pointer-events:none;transition:opacity .3s ease,transform .3s ease;cursor:pointer}.cc-bubble.cc-visible{opacity:1;transform:translateY(0);pointer-events:auto}.cc-bubble.cc-left{right:auto;left:20px}.cc-bubble-close{position:absolute;top:-8px;right:-8px;width:20px;height:20px;border-radius:50%;background:var(--cc-bg);border:1px solid var(--cc-border);cursor:pointer;display:flex;align-items:center;justify-content:center;font-size:10px;color:var(--cc-text-secondary)}.cc-hidden{display:none}.cc-sr-only{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap}.cc-messages-wrapper{flex:1;display:flex;flex-direction:column;min-height:0}.cc-prechat{flex:1;overflow-y:auto;padding:24px 16px;display:flex;flex-direction:column;gap:16px}.cc-prechat-title{font-size:18px;font-weight:600;color:var(--cc-text)}.cc-prechat-subtitle{font-size:13px;color:var(--cc-text-secondary);margin-top:-8px}.cc-prechat-fields{display:flex;flex-direction:column;gap:14px}.cc-prechat-field{display:flex;flex-direction:column;gap:4px}.cc-prechat-label{font-size:13px;font-weight:500;color:var(--cc-text)}.cc-prechat-label .cc-required{color:#ef4444;margin-left:2px}.cc-prechat-input,.cc-prechat-select,.cc-prechat-textarea{background:var(--cc-bg-input);border:1px solid var(--cc-border);border-radius:8px;padding:8px 12px;color:var(--cc-text);font-family:var(--cc-font);font-size:14px;outline:none;transition:border-color .15s ease}.cc-prechat-input:focus,.cc-prechat-select:focus,.cc-prechat-textarea:focus{border-color:var(--cc-accent)}.cc-prechat-select{-webkit-appearance:auto;-moz-appearance:auto;appearance:auto}.cc-prechat-textarea{resize:none;line-height:1.5}.cc-prechat-error{font-size:12px;color:#ef4444;min-height:0}.cc-prechat-error:empty{display:none}.cc-prechat-submit{background:var(--cc-accent-contrast);color:var(--cc-on-accent);border:none;border-radius:8px;padding:10px 16px;font-family:var(--cc-font);font-size:14px;font-weight:500;cursor:pointer;transition:background .15s ease;margin-top:8px}.cc-prechat-submit:hover{background:var(--cc-accent-hover)}.cc-prechat-submit:disabled{opacity:.5;cursor:not-allowed}@media(max-width:768px){.cc-fab.cc-open{display:none}.cc-panel:not(.cc-inline){width:100%;height:100%;max-height:100%;bottom:0;right:0;left:0;border-radius:0;border:none}.cc-panel.cc-left:not(.cc-inline){left:0}.cc-bubble{bottom:84px;right:16px;left:16px;max-width:none}}.cc-fab:focus-visible,.cc-header-close:focus-visible,.cc-send-btn:focus-visible,.cc-message-retry:focus-visible,.cc-message-regenerate:focus-visible,.cc-bubble-close:focus-visible,.cc-prechat-submit:focus-visible{outline:2px solid var(--cc-accent);outline-offset:3px}@media(prefers-reduced-motion:reduce){.cc-fab.cc-pulse,.cc-typing-dot{animation:none}.cc-panel,.cc-bubble{transition:none}}",s.appendChild(i),s}const n={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"};const r=new Set(["http","https","mailto","tel"]);function o(e){let t=e.replace(/[&<>"']/g,e=>n[e]??e);const s=function(e){let t="\0";for(;e.includes(t);)t+="\0";return t}(t),a=[],i=e=>{const t=a.push(e)-1;return`${s}${t}${s}`};t=t.replace(/```(?:\w*)\n?([\s\S]*?)```/g,(e,t)=>i(`<pre><code>${t.trim()}</code></pre>`)),t=t.replace(/`([^`]+)`/g,(e,t)=>i(`<code>${t}</code>`)),t=t.replace(/^(#{1,6}) (.+)$/gm,(e,t,s)=>{const a=t.length;return`<h${a}>${s}</h${a}>`}),t=t.replace(/\*\*(.+?)\*\*/g,"<strong>$1</strong>"),t=t.replace(/\*(\S(?:.*?\S)??)\*/g,"<em>$1</em>"),t=t.replace(/\[([^\]]+)\]\(((?:[^()]*|\([^()]*\))*)\)/g,(e,t,s)=>function(e){const t=e.replace(/[\t\n\r]/g,"").replace(/^[\u0000-\u0020]+/,""),s=/^([^:/?#]+):/.exec(t);return!s||r.has(s[1].toLowerCase())}(s)?`<a href="${s}" target="_blank" rel="noopener noreferrer">${t}</a>`:t),t=t.replace(/^[-*+] (.+)$/gm,'<li data-md="ul">$1</li>'),t=t.replace(/^\d+\. (.+)$/gm,'<li data-md="ol">$1</li>'),t=t.replace(/(?:<li data-md="ul">.*?<\/li>\n?)+|(?:<li data-md="ol">.*?<\/li>\n?)+/g,e=>{const t=e.includes('data-md="ol"')?"ol":"ul";return`<${t}>${e.replace(/ data-md="(?:ul|ol)"/g,"").replace(/\n/g,"")}</${t}>`}),t=t.replace(/(<\/h[1-6]>)\n+/g,"$1"),t=t.replace(/\n\n/g,"<br><br>"),t=t.replace(/\n/g,"<br>");for(let n=0;n<a.length;n++)t=t.replace(`${s}${n}${s}`,()=>a[n]);return t}class c{constructor(e,t){s(this,"container"),s(this,"typingEl",null),s(this,"actions"),this.actions=t,this.container=document.createElement("div"),this.container.className="cc-messages",this.container.setAttribute("role","log"),this.container.setAttribute("aria-live","polite"),e.appendChild(this.container)}addMessage(e){this.removeTyping();const t=this.createMessageElement(e);return this.container.appendChild(t),this.scrollToBottom(),t}updateMessage(e){const t=this.findMessage(e.id);t&&(this.renderMessageElement(t,e),this.scrollToBottom())}showTyping(){var e;this.typingEl||(this.typingEl=document.createElement("div"),this.typingEl.className="cc-typing",this.typingEl.innerHTML=`<span class="cc-sr-only">${this.escapeHtml((null==(e=this.actions)?void 0:e.typingLabel)??"Typing...")}</span><div class="cc-typing-dot" aria-hidden="true"></div><div class="cc-typing-dot" aria-hidden="true"></div><div class="cc-typing-dot" aria-hidden="true"></div>`,this.container.appendChild(this.typingEl),this.scrollToBottom())}removeTyping(){this.typingEl&&(this.typingEl.remove(),this.typingEl=null)}clear(){this.container.innerHTML="",this.typingEl=null}removeMessage(e){const t=this.findMessage(e);null==t||t.remove()}clearRegenerateButtons(){this.container.querySelectorAll(".cc-message-regenerate").forEach(e=>e.remove()),this.cleanupEmptyActionContainers()}showRegenerateButton(e){var t;if(this.clearRegenerateButtons(),!(null==(t=this.actions)?void 0:t.onRegenerate))return;const s=this.findMessage(e);if(!s||!s.classList.contains("cc-message-assistant"))return;this.ensureActionsContainer(s).appendChild(this.createActionButton({className:"cc-message-regenerate",label:this.actions.regenerateLabel??"Regenerate",icon:'<svg viewBox="0 0 24 24" width="14" height="14" aria-hidden="true"><path d="M12 4V1L8 5l4 4V6c3.31 0 6 2.69 6 6 0 1.01-.25 1.97-.7 2.8l1.46 1.46A7.93 7.93 0 0020 12c0-4.42-3.58-8-8-8zm0 14c-3.31 0-6-2.69-6-6 0-1.01.25-1.97.7-2.8L5.24 7.74A7.93 7.93 0 004 12c0 4.42 3.58 8 8 8v3l4-4-4-4v3z"/></svg>',onClick:()=>{var t,s;return null==(s=null==(t=this.actions)?void 0:t.onRegenerate)?void 0:s.call(t,e)}}))}setVisible(e){this.container.classList.toggle("cc-hidden",!e)}findMessage(e){return Array.from(this.container.children).find(t=>t.dataset.id===e)??null}scrollToBottom(){this.container.scrollTop=this.container.scrollHeight}createMessageElement(e){const t=document.createElement("div");return this.renderMessageElement(t,e),t}renderMessageElement(e,t){e.className=`cc-message cc-message-${t.role}`,e.dataset.id=t.id,t.status?e.dataset.status=t.status:delete e.dataset.status,"streaming"===t.status?e.setAttribute("aria-busy","true"):e.removeAttribute("aria-busy"),t.errorType?e.dataset.errorType=t.errorType:delete e.dataset.errorType,e.innerHTML="";const s=document.createElement("div");if(s.className="cc-message-content",s.innerHTML="assistant"===t.role?o(t.content):this.escapeHtml(t.content),e.appendChild(s),"error"===t.status&&t.errorText){const s=document.createElement("div");s.className="cc-message-error-note",s.textContent=t.errorText,e.appendChild(s)}const a=this.createActionsContainer(t);a&&e.appendChild(a)}createActionsContainer(e){var t;if("error"!==e.status||!(null==(t=this.actions)?void 0:t.onRetry))return null;const s=document.createElement("div");return s.className="cc-message-actions",s.appendChild(this.createActionButton({className:"cc-message-retry",label:this.actions.retryLabel??"Retry",icon:'<svg viewBox="0 0 24 24" width="14" height="14" aria-hidden="true"><path d="M17.65 6.35A7.96 7.96 0 0012 4c-4.42 0-7.99 3.58-7.99 8s3.57 8 7.99 8c3.73 0 6.84-2.55 7.73-6h-2.08A5.99 5.99 0 0112 18c-3.31 0-6-2.69-6-6s2.69-6 6-6c1.66 0 3.14.69 4.22 1.78L13 11h7V4l-2.35 2.35z"/></svg>',onClick:()=>{var t,s;return null==(s=null==(t=this.actions)?void 0:t.onRetry)?void 0:s.call(t,e.id)}})),s}ensureActionsContainer(e){const t=e.querySelector(".cc-message-actions");if(t)return t;const s=document.createElement("div");return s.className="cc-message-actions",e.appendChild(s),s}cleanupEmptyActionContainers(){this.container.querySelectorAll(".cc-message-actions").forEach(e=>{e.hasChildNodes()||e.remove()})}createActionButton(e){const t=document.createElement("button");return t.type="button",t.className=e.className,t.innerHTML=`${e.icon}<span>${this.escapeHtml(e.label)}</span>`,t.addEventListener("click",e.onClick),t}escapeHtml(e){const t=document.createElement("div");return t.textContent=e,t.innerHTML}}class l{constructor(e,t){s(this,"area"),s(this,"textarea"),s(this,"sendBtn"),s(this,"onSend"),this.onSend=t.onSend,this.area=document.createElement("div"),this.area.className="cc-input-area",this.textarea=document.createElement("textarea"),this.textarea.className="cc-input",this.textarea.placeholder=t.placeholder,this.textarea.setAttribute("aria-label",t.placeholder),this.textarea.rows=1,this.textarea.maxLength=1e4,this.textarea.addEventListener("input",()=>this.autoResize()),this.textarea.addEventListener("keydown",e=>this.handleKeydown(e)),this.sendBtn=document.createElement("button"),this.sendBtn.className="cc-send-btn",this.sendBtn.disabled=!0,this.sendBtn.setAttribute("aria-label",t.sendLabel),this.sendBtn.innerHTML='<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M2.01 21L23 12 2.01 3 2 10l15 2-15 2z"/></svg>',this.sendBtn.addEventListener("click",()=>this.send()),this.textarea.addEventListener("input",()=>{this.sendBtn.disabled=0===this.textarea.value.trim().length}),this.area.appendChild(this.textarea),this.area.appendChild(this.sendBtn),e.appendChild(this.area)}focus(){this.textarea.focus()}setDisabled(e){this.textarea.disabled=e,this.sendBtn.disabled=e||0===this.textarea.value.trim().length}clear(){this.textarea.value="",this.sendBtn.disabled=!0,this.autoResize()}setVisible(e){this.area.classList.toggle("cc-hidden",!e)}send(){const e=this.textarea.value.trim();e&&(this.onSend(e),this.clear())}handleKeydown(e){e.isComposing||229===e.keyCode||"Enter"!==e.key||e.shiftKey||(e.preventDefault(),this.send())}autoResize(){this.textarea.style.height="auto";this.textarea.style.height=Math.min(this.textarea.scrollHeight,96)+"px"}}const d="cc-panel";class h{constructor(e,t){s(this,"el"),s(this,"inline"),s(this,"messages"),s(this,"input"),s(this,"messagesContainer"),this.inline=t.inline??!1,this.el=document.createElement("div"),this.el.className="cc-panel",t.inline&&this.el.classList.add("cc-inline"),"bottom-left"===t.position&&this.el.classList.add("cc-left"),t.inline||(this.el.id=d,this.el.setAttribute("role","dialog"),this.el.setAttribute("aria-label",t.branding.name),this.el.addEventListener("keydown",e=>{"Escape"===e.key&&t.onClose()}),this.setHidden(!0));const a=document.createElement("div");if(a.className="cc-header",t.branding.avatar){const e=document.createElement("img");e.className="cc-header-avatar",e.src=t.branding.avatar,e.alt=t.branding.name,a.appendChild(e)}else{const e=document.createElement("div");e.className="cc-header-avatar-placeholder",e.innerHTML='<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 3c1.66 0 3 1.34 3 3s-1.34 3-3 3-3-1.34-3-3 1.34-3 3-3zm0 14.2c-2.5 0-4.71-1.28-6-3.22.03-1.99 4-3.08 6-3.08 1.99 0 5.97 1.09 6 3.08-1.29 1.94-3.5 3.22-6 3.22z"/></svg>',a.appendChild(e)}const i=document.createElement("div");if(i.className="cc-header-info",i.innerHTML=`<div class="cc-header-name">${this.escapeHtml(t.branding.name)}</div><div class="cc-header-subtitle">${this.escapeHtml(t.branding.subtitle)}</div>`,a.appendChild(i),!t.inline){const e=document.createElement("button");e.className="cc-header-close",e.setAttribute("aria-label",t.closeLabel),e.innerHTML='<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z"/></svg>',e.addEventListener("click",t.onClose),a.appendChild(e)}this.el.appendChild(a),t.preChatEnabled?(this.messagesContainer=document.createElement("div"),this.messagesContainer.className="cc-messages-wrapper",this.el.appendChild(this.messagesContainer)):this.messagesContainer=this.el,this.messages=new c(this.messagesContainer,t.messageActions),this.input=new l(this.el,{placeholder:t.placeholder,sendLabel:t.sendLabel,onSend:t.onSend});const n=document.createElement("div");n.className="cc-footer",n.innerHTML=t.footerText,this.el.appendChild(n),e.appendChild(this.el)}show(){this.el.classList.add("cc-visible"),this.inline||(this.setHidden(!1),this.input.focus())}hide(){this.el.classList.remove("cc-visible"),this.inline||this.setHidden(!0)}containsFocus(){return this.el.contains(this.el.getRootNode().activeElement)}get isVisible(){return this.el.classList.contains("cc-visible")}addMessage(e){return this.messages.addMessage(e)}hideMessages(){this.messages.setVisible(!1)}showMessages(){this.messages.setVisible(!0)}destroy(){this.el.remove()}setHidden(e){this.el.toggleAttribute("inert",e),e?this.el.setAttribute("aria-hidden","true"):this.el.removeAttribute("aria-hidden")}escapeHtml(e){const t=document.createElement("div");return t.textContent=e,t.innerHTML}}const p='<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M20 2H4c-1.1 0-2 .9-2 2v18l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm0 14H5.17L4 17.17V4h16v12z"/><path d="M7 9h10v2H7zm0-3h10v2H7z"/></svg>';class u{constructor(e,t){s(this,"el"),s(this,"badge"),s(this,"isOpen",!1),s(this,"openLabel"),s(this,"closeLabel"),this.openLabel=t.openLabel,this.closeLabel=t.closeLabel,this.el=document.createElement("button"),this.el.className="cc-fab cc-pulse",this.el.setAttribute("aria-label",this.openLabel),this.el.setAttribute("aria-expanded","false"),this.el.setAttribute("aria-controls",d),"bottom-left"===t.position&&this.el.classList.add("cc-left"),this.el.innerHTML=p,this.badge=document.createElement("div"),this.badge.className="cc-fab-badge",this.el.appendChild(this.badge),this.el.addEventListener("click",()=>{this.el.classList.remove("cc-pulse"),t.onClick()}),e.appendChild(this.el)}setOpen(e){this.isOpen=e,this.el.innerHTML=e?'<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z"/></svg>':p,e||this.el.appendChild(this.badge),this.el.classList.toggle("cc-open",e),this.el.setAttribute("aria-label",e?this.closeLabel:this.openLabel),this.el.setAttribute("aria-expanded",String(e))}focus(){this.el.focus()}showBadge(){this.badge.classList.add("cc-visible")}hideBadge(){this.badge.classList.remove("cc-visible")}destroy(){this.el.remove()}}const m="chatcops_bubble_shown";class g{constructor(e,t){s(this,"el"),s(this,"timerId",null),this.el=document.createElement("div"),this.el.className="cc-bubble","bottom-left"===t.position&&this.el.classList.add("cc-left"),this.el.textContent=t.text,this.setHidden(!0);const a=document.createElement("button");if(a.type="button",a.className="cc-bubble-close",a.setAttribute("aria-label",t.dismissLabel),a.innerHTML="&times;",a.addEventListener("click",e=>{e.stopPropagation(),this.hide()}),this.el.appendChild(a),this.el.addEventListener("click",()=>{this.hide(),t.onClick()}),e.appendChild(this.el),t.showOnce)try{if(sessionStorage.getItem(m))return;sessionStorage.setItem(m,"1")}catch{}this.timerId=setTimeout(()=>{this.el.classList.add("cc-visible"),this.setHidden(!1)},t.delay??3e3)}hide(){this.el.classList.remove("cc-visible"),this.setHidden(!0),this.timerId&&(clearTimeout(this.timerId),this.timerId=null)}setHidden(e){this.el.toggleAttribute("inert",e),e?this.el.setAttribute("aria-hidden","true"):this.el.removeAttribute("aria-hidden")}destroy(){this.hide(),this.el.remove()}}class b{constructor(e){s(this,"apiUrl"),s(this,"timeout"),this.apiUrl=e.apiUrl,this.timeout=e.timeout??3e4}async*sendMessage(e,t={}){var s;const a=new AbortController,i=t.timeout??this.timeout;let n,r,o=!1;const c=t.signal,l=()=>{clearTimeout(n),a.abort()},d=()=>{clearTimeout(n),a.signal.aborted||(n=setTimeout(()=>{o=!0,a.abort()},i))},h=async()=>{if(clearTimeout(n),null==c||c.removeEventListener("abort",l),r){const e=r;r=void 0;try{await e.cancel()}catch{}finally{e.releaseLock()}}};c&&(c.aborted?a.abort():c.addEventListener("abort",l)),d();try{const t=await fetch(this.apiUrl,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e),signal:a.signal});if(!t.ok)return await h(),429===t.status?void(yield{error:"rate_limit"}):void(yield{error:`HTTP ${t.status}`});if(r=null==(s=t.body)?void 0:s.getReader(),!r)return await h(),void(yield{error:"No response body"});const i=new TextDecoder;let n="";for(;;){const{done:e,value:t}=await r.read();if(e)break;t.byteLength>0&&d(),n+=i.decode(t,{stream:!0});const s=n.split("\n");n=s.pop()??"";for(const a of s){const e=a.trim();if(!e||!e.startsWith("data: "))continue;const t=e.slice(6);if("[DONE]"===t)return await h(),void(yield{done:!0});try{yield JSON.parse(t)}catch{}}}await h(),yield{done:!0}}catch(p){await h(),p instanceof DOMException&&"AbortError"===p.name?yield o?{error:"timeout"}:{error:"aborted"}:yield{error:"network"}}finally{await h()}}}const f="chatcops_conversation",v="chatcops_session_id";class x{constructor(e){s(this,"key"),s(this,"sessionKey"),this.key=e?`${f}_${e}`:f,this.sessionKey=e?`${v}_${e}`:v}load(){try{const e=localStorage.getItem(this.key);return e?JSON.parse(e):null}catch{return null}}save(e){try{const t={...e,messages:e.messages.filter(e=>"error"!==e.status).map(({status:e,...t})=>t)};localStorage.setItem(this.key,JSON.stringify(t))}catch{}}clear(){try{localStorage.removeItem(this.key)}catch{}}getSessionId(){try{let e=sessionStorage.getItem(this.sessionKey);return e||(e=crypto.randomUUID(),sessionStorage.setItem(this.sessionKey,e)),e}catch{return crypto.randomUUID()}}isPreChatCompleted(e){try{return"true"===sessionStorage.getItem(`chatcops-prechat-${e}`)}catch{return!1}}setPreChatCompleted(e,t){try{sessionStorage.setItem(`chatcops-prechat-${e}`,"true")}catch{}t&&this.setPreChatData(e,t)}getPreChatData(e){try{const t=sessionStorage.getItem(`chatcops-prechat-data-${e}`);if(!t)return null;const s=JSON.parse(t);return"object"!=typeof s||null===s||Array.isArray(s)?null:s}catch{return null}}setPreChatData(e,t){try{sessionStorage.setItem(`chatcops-prechat-data-${e}`,JSON.stringify(t))}catch{}}}const y=Symbol.for("chatcops.storageClaims"),w=globalThis,C=w[y]??(w[y]=new Map);function E(e){const t=C.get(e);if(!t)return!1;for(const s of t)s()||t.delete(s);return 0===t.size&&C.delete(e),t.size>0}function M(e,t){const s=e.host;if(t.accent){s.style.setProperty("--cc-accent",t.accent),s.style.setProperty("--cc-accent-hover",N(t.accent,10));const e=function(e){if(!function(e){return/^#?[\da-f]{3}(?:[\da-f]{3})?$/i.test(e.trim())}(e))return null;const t=e.trim().startsWith("#")?e.trim():`#${e.trim()}`;if(B(L,t)>=k)return{onAccent:L,background:t};if(B(S,t)>=k)return{onAccent:S,background:t};for(let s=2;s<=60;s+=2){const e=N(t,s);if(B(L,e)>=k)return{onAccent:L,background:e}}return{onAccent:L,background:S}}(t.accent);e?(s.style.setProperty("--cc-on-accent",e.onAccent),s.style.setProperty("--cc-accent-contrast",e.background)):s.style.setProperty("--cc-accent-contrast",t.accent)}if(t.textColor&&s.style.setProperty("--cc-text",t.textColor),t.bgColor&&(s.style.setProperty("--cc-bg",t.bgColor),s.style.setProperty("--cc-bg-surface",$(t.bgColor,8)),s.style.setProperty("--cc-bg-input",$(t.bgColor,14))),t.fontFamily&&s.style.setProperty("--cc-font",t.fontFamily),void 0!==t.borderRadius){const e=function(e){if("number"==typeof e&&!Number.isFinite(e))return"";const t=String(e).trim();return/^(?:\d+(?:\.\d+)?|\.\d+)$/.test(t)?`${t}px`:t}(t.borderRadius);e&&s.style.setProperty("--cc-radius",e)}}const L="#ffffff",S="#0a0a0a",k=4.5;function T(e){const t=I(e).map(e=>{const t=e/255;return t<=.03928?t/12.92:((t+.055)/1.055)**2.4});return.2126*t[0]+.7152*t[1]+.0722*t[2]}function B(e,t){const[s,a]=[T(e),T(t)].sort((e,t)=>t-e);return(s+.05)/(a+.05)}function I(e){if(!/^#?[\da-f]{3}(?:[\da-f]{3})?$/i.test(e))return[0,0,0];const t=e.replace("#",""),s=parseInt(3===t.length?t.split("").map(e=>e+e).join(""):t,16);return[s>>16&255,s>>8&255,255&s]}function A(e,t,s){return"#"+[e,t,s].map(e=>Math.max(0,Math.min(255,e)).toString(16).padStart(2,"0")).join("")}function N(e,t){const[s,a,i]=I(e),n=1-t/100;return A(Math.round(s*n),Math.round(a*n),Math.round(i*n))}function $(e,t){const[s,a,i]=I(e),n=t/100;return A(Math.round(s+(255-s)*n),Math.round(a+(255-a)*n),Math.round(i+(255-i)*n))}const H={welcomeMessage:"How can I help you today?",inputPlaceholder:"Type a message...",sendButton:"Send",closeButton:"Close",openChat:"Open chat",defaultName:"AI Assistant",defaultSubtitle:"Online",greetingWithName:"Hi {name}!",selectPlaceholder:"Select {label}...",dismissBubble:"Dismiss",errorGeneric:"Something went wrong. Please try again.",errorNetwork:"Connection error. Please check your network.",errorRateLimit:"Too many messages. Please wait a moment.",typingIndicator:"Typing...",poweredBy:"Powered by ChatCops",newConversation:"New conversation",welcomeBubbleDefault:"Need help? Chat with us!",preChatTitle:"Before we start...",preChatSubtitle:"Tell us a bit about yourself",preChatSubmit:"Start Chat",preChatRequired:"This field is required",preChatInvalidEmail:"Please enter a valid email",retryButton:"Retry",regenerateButton:"Regenerate"},z={en:H};class R{constructor(e,t){if(s(this,"container"),s(this,"fieldElements",new Map),s(this,"errorElements",new Map),s(this,"submitBtn"),s(this,"options"),this.options=t,this.container=document.createElement("div"),this.container.className="cc-prechat",t.title){const e=document.createElement("div");e.className="cc-prechat-title",e.textContent=t.title,this.container.appendChild(e)}if(t.subtitle){const e=document.createElement("div");e.className="cc-prechat-subtitle",e.textContent=t.subtitle,this.container.appendChild(e)}const a=document.createElement("form");a.className="cc-prechat-fields",a.noValidate=!0,a.addEventListener("submit",e=>{e.preventDefault(),this.handleSubmit()});for(const s of t.fields)a.appendChild(this.createField(s));this.submitBtn=document.createElement("button"),this.submitBtn.type="submit",this.submitBtn.className="cc-prechat-submit",this.submitBtn.textContent=t.submitLabel,a.appendChild(this.submitBtn),this.container.appendChild(a),e.appendChild(this.container),this.updateSubmitState();const i=this.fieldElements.values().next().value;i&&setTimeout(()=>i.focus(),100)}createField(e){const t=document.createElement("div");t.className="cc-prechat-field";const s=`cc-prechat-${e.name}`,a=`cc-prechat-${e.name}-error`,i=document.createElement("label");if(i.className="cc-prechat-label",i.htmlFor=s,i.textContent=e.label,e.required){const e=document.createElement("span");e.className="cc-required",e.textContent="*",i.appendChild(e)}let n;if(t.appendChild(i),"select"===e.type){const t=document.createElement("select");t.className="cc-prechat-select";const s=document.createElement("option");s.value="",s.textContent=e.placeholder??this.options.locale.selectPlaceholder.replace("{label}",e.label.toLowerCase()),s.disabled=!0,s.selected=!0,t.appendChild(s);for(const a of e.options??[]){const e=document.createElement("option");e.value=a,e.textContent=a,t.appendChild(e)}n=t}else if("textarea"===e.type){const t=document.createElement("textarea");t.className="cc-prechat-textarea",t.placeholder=e.placeholder??"",t.rows=3,t.maxLength=500,n=t}else{const t=document.createElement("input");t.type=e.type,t.className="cc-prechat-input",t.maxLength=500,t.placeholder=e.placeholder??"",n=t}n.name=e.name,n.id=s,e.required&&n.setAttribute("aria-required","true"),n.addEventListener("input",()=>{this.clearError(e.name),this.updateSubmitState()}),n instanceof HTMLSelectElement&&n.addEventListener("change",()=>{this.clearError(e.name),this.updateSubmitState()}),t.appendChild(n),this.fieldElements.set(e.name,n);const r=document.createElement("div");return r.className="cc-prechat-error",r.id=a,t.appendChild(r),this.errorElements.set(e.name,r),t}updateSubmitState(){const e=this.options.fields.every(e=>{if(!e.required)return!0;const t=this.fieldElements.get(e.name);return!!t&&t.value.trim().length>0});this.submitBtn.disabled=!e}handleSubmit(){const e={};let t=!0;for(const s of this.options.fields){const a=this.fieldElements.get(s.name);if(!a)continue;const i=a.value.trim();e[s.name]=i,!s.required||i?"email"!==s.type||!i||this.isValidEmail(i)||(this.showError(s.name,this.options.locale.preChatInvalidEmail),t=!1):(this.showError(s.name,this.options.locale.preChatRequired),t=!1)}t&&this.options.onSubmit(e)}showError(e,t){const s=this.errorElements.get(e);s&&(s.textContent=t);const a=this.fieldElements.get(e);a&&s&&(a.setAttribute("aria-invalid","true"),a.setAttribute("aria-describedby",s.id))}clearError(e){const t=this.errorElements.get(e);t&&(t.textContent="");const s=this.fieldElements.get(e);s&&t&&(s.getAttribute("aria-describedby")===t.id&&s.removeAttribute("aria-describedby"),"true"===s.getAttribute("aria-invalid")&&s.removeAttribute("aria-invalid"))}isValidEmail(e){return/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e)}destroy(){this.container.remove(),this.fieldElements.clear(),this.errorElements.clear()}}class P{constructor(e){s(this,"config"),s(this,"shadow"),s(this,"mounted",!1),s(this,"fab"),s(this,"panel"),s(this,"bubble"),s(this,"preChatFormEl"),s(this,"client"),s(this,"storage"),s(this,"namespace"),s(this,"locale"),s(this,"conversationId"),s(this,"messages",[]),s(this,"userData"),s(this,"isStreaming",!1),s(this,"destroyed",!1),s(this,"abortController"),s(this,"retryRequests",new Map),s(this,"eventHandlers",new Map),s(this,"containerEl"),s(this,"autoOpenTimer"),this.config=e,this.client=new b({apiUrl:e.apiUrl,timeout:e.timeout}),this.namespace=function(e,t,s){let a=e??"";if(void 0===e&&E("")){a=t;for(let e=2;E(a);e+=1)a=`${t}-${e}`;console.warn(`[chatcops] Another widget on this page already uses the default storage, so this one keeps its conversation under "${a}". Set a \`siteId\` on each widget to name them yourself.`)}else void 0!==e&&E(e)&&console.warn(`[chatcops] Two widgets on this page use the siteId "${e}", so they share one conversation.`);return C.has(a)||C.set(a,new Set),C.get(a).add(s),{siteId:""===a?void 0:a,release(){var e,t;null==(e=C.get(a))||e.delete(s),0===(null==(t=C.get(a))?void 0:t.size)&&C.delete(a)}}}(e.siteId,e.mode??"popup",()=>!this.destroyed&&(!this.mounted||this.shadow.host.isConnected)),this.storage=new x(this.namespace.siteId),this.locale=function(e,t){const s=z[e]??H;return t?{...s,...t}:s}(e.locale??"en",e.strings),this.conversationId=this.storage.getSessionId()}get isInline(){return"inline"===this.config.mode}resolveContainer(){if(!this.config.container)throw new Error('ChatCops: "container" is required when mode is "inline"');if("string"==typeof this.config.container){const e=document.querySelector(this.config.container);if(!e)throw new Error(`ChatCops: container element not found: ${this.config.container}`);return e}return this.config.container}init(){var e,t,s,a,n,r,o;this.isInline?(this.containerEl=this.resolveContainer(),this.shadow=i(this.containerEl)):this.shadow=i(),this.mounted=!0,this.config.theme&&M(this.shadow,this.config.theme);const c=(null==(e=this.config.theme)?void 0:e.position)??"bottom-right";if(this.isInline||(this.fab=new u(this.shadow,{position:c,openLabel:this.locale.openChat,closeLabel:this.locale.closeButton,onClick:()=>this.toggle()})),this.panel=new h(this.shadow,{position:c,inline:this.isInline,preChatEnabled:(null==(t=this.config.preChatForm)?void 0:t.enabled)??!1,branding:{name:(null==(s=this.config.branding)?void 0:s.name)??this.locale.defaultName,avatar:null==(a=this.config.branding)?void 0:a.avatar,subtitle:(null==(n=this.config.branding)?void 0:n.subtitle)??this.locale.defaultSubtitle},placeholder:this.config.placeholder??this.locale.inputPlaceholder,footerText:this.locale.poweredBy,closeLabel:this.locale.closeButton,sendLabel:this.locale.sendButton,messageActions:{onRetry:e=>{this.handleRetry(e)},onRegenerate:e=>{this.handleRegenerate(e)},retryLabel:this.locale.retryButton,regenerateLabel:this.locale.regenerateButton,typingLabel:this.locale.typingIndicator},onSend:e=>this.handleSend(e),onClose:()=>this.close()}),!1!==this.config.persistHistory){const e=this.storage.load();if(e){this.conversationId=e.id;for(const t of e.messages)this.messages.push(t),this.panel.addMessage(t)}}if(null==(r=this.config.preChatForm)?void 0:r.enabled){const e=this.storage.getPreChatData(this.conversationId);e&&(this.userData=e)}if((null==(o=this.config.preChatForm)?void 0:o.enabled)&&!this.isPreChatCompleted()&&0===this.messages.length?this.showPreChatForm():this.showChatView(),this.showLatestRegenerateButton(),!this.isInline&&this.config.welcomeBubble&&(this.bubble=new g(this.shadow,{text:this.config.welcomeBubble.text,delay:this.config.welcomeBubble.delay,showOnce:this.config.welcomeBubble.showOnce??!0,position:c,dismissLabel:this.locale.dismissBubble,onClick:()=>this.open()})),this.isInline&&this.panel.show(),!this.isInline&&void 0!==this.config.autoOpen&&!1!==this.config.autoOpen){const e="number"==typeof this.config.autoOpen?this.config.autoOpen:0;this.autoOpenTimer=setTimeout(()=>this.open(),e)}}open(){var e,t,s,a,i;this.panel.show(),this.isInline||(null==(e=this.fab)||e.setOpen(!0),null==(t=this.fab)||t.hideBadge(),null==(s=this.bubble)||s.hide()),null==(i=(a=this.config).onOpen)||i.call(a),this.emit("open")}close(){var e,t,s,a;const i=this.panel.containsFocus();this.panel.hide(),this.isInline||(null==(e=this.fab)||e.setOpen(!1),i&&(null==(t=this.fab)||t.focus())),null==(a=(s=this.config).onClose)||a.call(s),this.emit("close")}toggle(){this.panel.isVisible?this.close():this.open()}destroy(){var e,t,s,a,i;this.destroyed=!0,void 0!==this.autoOpenTimer&&clearTimeout(this.autoOpenTimer),null==(e=this.abortController)||e.abort(),this.abortController=void 0,null==(t=this.preChatFormEl)||t.destroy(),null==(s=this.bubble)||s.destroy(),this.panel.destroy(),null==(a=this.fab)||a.destroy(),null==(i=this.shadow)||i.host.remove(),this.namespace.release(),this.eventHandlers.clear(),this.messages=[],this.userData=void 0}on(e,t){return this.eventHandlers.has(e)||this.eventHandlers.set(e,new Set),this.eventHandlers.get(e).add(t),()=>this.off(e,t)}off(e,t){var s;null==(s=this.eventHandlers.get(e))||s.delete(t)}emit(e,...t){var s;this.destroyed||null==(s=this.eventHandlers.get(e))||s.forEach(e=>e(...t))}isPreChatCompleted(){return this.storage.isPreChatCompleted(this.conversationId)}setPreChatCompleted(e){this.storage.setPreChatCompleted(this.conversationId,e)}showPreChatForm(){const e=this.config.preChatForm;this.panel.hideMessages(),this.panel.input.setVisible(!1),this.preChatFormEl=new R(this.panel.messagesContainer,{title:e.title??this.locale.preChatTitle,subtitle:e.subtitle??this.locale.preChatSubtitle,fields:e.fields,submitLabel:e.submitLabel??this.locale.preChatSubmit,locale:this.locale,onSubmit:e=>this.handlePreChatSubmit(e)})}handlePreChatSubmit(e){var t,s,a,i;(null==(t=this.config.preChatForm)?void 0:t.enabled)&&(this.userData=e,this.setPreChatCompleted(e),null==(s=this.preChatFormEl)||s.destroy(),this.preChatFormEl=void 0,this.panel.showMessages(),this.panel.input.setVisible(!0),this.showChatView(),null==(i=(a=this.config).onPreChatSubmit)||i.call(a,e),this.emit("preChatSubmit",e),e.message&&this.handleSend(e.message))}showChatView(){var e;if(0===this.messages.length){const t=null==(e=this.userData)?void 0:e.name,s=this.locale.greetingWithName.replace("{name}",()=>t),a={id:"welcome",role:"assistant",content:t?`${s} ${this.config.welcomeMessage??this.locale.welcomeMessage}`:this.config.welcomeMessage??this.locale.welcomeMessage};this.messages.push(a),this.panel.addMessage(a)}}async handleSend(e){var t,s;if(this.isStreaming)return;const a={id:crypto.randomUUID(),role:"user",content:e};this.messages.push(a),this.panel.addMessage(a),null==(s=(t=this.config).onMessage)||s.call(t,a),this.emit("message",a),await this.sendToServer(e,{userMessageId:a.id})}async handleRetry(e){if(this.isStreaming)return;const t=this.messages.findIndex(t=>t.id===e);if(-1===t)return;const s=this.retryRequests.get(e);let a=(null==s?void 0:s.userMessageId)?this.messages.find(e=>e.id===s.userMessageId):void 0;if(!a)for(let i=t-1;i>=0;i--)if("user"===this.messages[i].role){a=this.messages[i];break}a&&(this.panel.messages.removeMessage(e),this.retryRequests.delete(e),this.messages=this.messages.filter(t=>t.id!==e),await this.sendToServer(a.content,{regenerate:null==s?void 0:s.regenerate,userMessageId:(null==s?void 0:s.userMessageId)??a.id}))}async handleRegenerate(e){if(this.isStreaming)return;const t=this.messages.findIndex(t=>t.id===e);if(-1===t)return;if("assistant"!==this.messages[t].role)return;const s=this.findUserMessageForAssistant(t);s&&(this.panel.messages.clearRegenerateButtons(),this.panel.messages.removeMessage(e),this.retryRequests.delete(e),this.messages=this.messages.filter(t=>t.id!==e),await this.sendToServer(s.content,{regenerate:!0,userMessageId:s.id}))}async sendToServer(e,t={}){var s,a,i,n,r,o,c,l,d;if(this.isStreaming)return;this.isStreaming=!0,this.panel.input.setDisabled(!0),this.panel.messages.clearRegenerateButtons(),this.panel.messages.showTyping();const h={id:crypto.randomUUID(),role:"assistant",content:"",status:"streaming"};let p=!0,u=!1,m=!1;const g=new AbortController;this.abortController=g;try{for await(const r of this.client.sendMessage(this.createRequest(e,t),{signal:g.signal})){if(this.destroyed)break;if(r.error){const e=this.resolveErrorType(r.error);this.markFailed(h,this.getErrorMessage(e)),h.errorType=e,m=!0,this.retryRequests.set(h.id,{regenerate:t.regenerate,userMessageId:t.userMessageId}),this.panel.messages.removeTyping(),p?this.panel.addMessage(h):this.panel.messages.updateMessage(h),this.messages.push(h);const i=new Error(r.error);null==(a=(s=this.config).onError)||a.call(s,i),this.emit("error",i);break}if(r.done){u=!0;break}r.leadCaptured&&(null==(n=(i=this.config).onLeadCaptured)||n.call(i,r.leadData),this.emit("leadCaptured",r.leadData)),r.content&&(p&&(this.panel.messages.removeTyping(),this.panel.addMessage(h),p=!1),h.content+=r.content,this.panel.messages.updateMessage(h))}if(this.destroyed)return;m||u||(u=!0),!m&&p&&this.panel.messages.removeTyping(),!m&&h.content&&(h.status="complete",this.panel.messages.updateMessage(h),this.messages.push(h),null==(o=(r=this.config).onMessage)||o.call(r,h),this.emit("message",h),this.showLatestRegenerateButton(),this.isInline||this.panel.isVisible||null==(c=this.fab)||c.showBadge())}catch(b){if(this.destroyed)return;this.markFailed(h,this.locale.errorGeneric),h.errorType="network",this.retryRequests.set(h.id,{regenerate:t.regenerate,userMessageId:t.userMessageId}),this.panel.messages.removeTyping(),p?this.panel.addMessage(h):this.panel.messages.updateMessage(h),this.messages.push(h);const e=b instanceof Error?b:new Error(String(b));null==(d=(l=this.config).onError)||d.call(l,e),this.emit("error",e)}finally{this.abortController===g&&(this.abortController=void 0),this.destroyed||(this.isStreaming=!1,this.panel.input.setDisabled(!1),this.panel.input.focus(),this.saveHistory())}}createRequest(e,t){var s;const a=!1!==this.config.pageContext?{url:window.location.href,title:document.title}:void 0,i=Boolean((null==(s=this.config.preChatForm)?void 0:s.enabled)&&this.userData);return{conversationId:this.conversationId,message:e,messageId:t.userMessageId,regenerate:t.regenerate,pageContext:a,locale:this.config.locale,...i?{userData:this.userData}:{}}}findUserMessageForAssistant(e){for(let t=e-1;t>=0;t--)if("user"===this.messages[t].role)return this.messages[t]}findLatestRegeneratableAssistant(){for(let e=this.messages.length-1;e>=0;e--){const t=this.messages[e];if("welcome"!==t.id){if("assistant"!==t.role||"error"===t.status)return;return t}}}showLatestRegenerateButton(){const e=this.findLatestRegeneratableAssistant();e?this.panel.messages.showRegenerateButton(e.id):this.panel.messages.clearRegenerateButtons()}resolveErrorType(e){switch(e){case"rate_limit":case"network":case"provider_error":case"timeout":return e;default:return"provider_error"}}markFailed(e,t){e.status="error",e.content.trim()?e.errorText=t:e.content=t}getErrorMessage(e){switch(e){case"rate_limit":return this.locale.errorRateLimit;case"network":case"timeout":return this.locale.errorNetwork;default:return this.locale.errorGeneric}}saveHistory(){if(!1===this.config.persistHistory)return;const e=this.config.maxMessages??50,t=this.messages.filter(e=>"welcome"!==e.id).slice(-e);this.storage.save({id:this.conversationId,messages:t.map(e=>({id:e.id,role:e.role,content:e.content,status:e.status,errorType:e.errorType,timestamp:Date.now()})),updatedAt:Date.now()})}}let O=null;const D=new Map;function F(e){if(void 0!==e)return""===e||"true"===e||"false"!==e&&(/^\d+$/.test(e)?Number(e):void 0)}const q={init(e){O&&O.destroy(),O=new P(e);for(const[t,s]of D)for(const e of s)O.on(t,e);return O.init(),O},open(){null==O||O.open()},close(){null==O||O.close()},destroy(){null==O||O.destroy(),O=null},on(e,t){let s=D.get(e);return s||(s=new Set,D.set(e,s)),s.add(t),null==O||O.on(e,t),()=>{q.off(e,t)}},off(e,t){var s;null==(s=D.get(e))||s.delete(t),null==O||O.off(e,t)}};function V(e){if(!e)return;const t=e.dataset.apiUrl;if(!t)return;const s=e.dataset.mode,a=e.dataset.container;q.init({apiUrl:t,mode:s||void 0,container:a||void 0,theme:{accent:e.dataset.accent,textColor:e.dataset.textColor,bgColor:e.dataset.bgColor,fontFamily:e.dataset.fontFamily,borderRadius:e.dataset.borderRadius,position:e.dataset.position||void 0},branding:{name:e.dataset.brandName,avatar:e.dataset.brandAvatar,subtitle:e.dataset.brandSubtitle},welcomeMessage:e.dataset.welcomeMessage,welcomeBubble:e.dataset.welcomeBubble?{text:e.dataset.welcomeBubble,delay:e.dataset.welcomeBubbleDelay?parseInt(e.dataset.welcomeBubbleDelay,10):void 0}:void 0,autoOpen:F(e.dataset.autoOpen),placeholder:e.dataset.placeholder,locale:e.dataset.locale})}const U="undefined"!=typeof document?document.currentScript:null;return U&&U.dataset.apiUrl&&("loading"===document.readyState?document.addEventListener("DOMContentLoaded",()=>V(U),{once:!0}):V(U)),"undefined"!=typeof window&&(window.ChatCops=q),e.Widget=P,e.default=q,e.parseAutoOpen=F,Object.defineProperties(e,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}}),e}({});"undefined"!=typeof window&&window.ChatCops&&window.ChatCops.default&&Object.assign(window.ChatCops,window.ChatCops.default);
1
+ var ChatCops=function(e){"use strict";const t="chatcops-root";function s(e){const s=document.createElement("div");s.id=function(){if(!document.getElementById(t))return t;let e=2;for(;document.getElementById(`${t}-${e}`);)e+=1;return`${t}-${e}`}(),s.className=t,e?e.appendChild(s):document.body.appendChild(s);const a=s.attachShadow({mode:"open"}),i=document.createElement("style");return i.textContent=":host{--cc-accent: #6366f1;--cc-accent-hover: #4f46e5;--cc-on-accent: #ffffff;--cc-accent-contrast: #6164ec;--cc-text: #ffffff;--cc-bg: #0a0a0a;--cc-bg-surface: #1a1a1a;--cc-bg-input: #2a2a2a;--cc-border: #333333;--cc-text-secondary: #a0a0a0;--cc-font: system-ui, -apple-system, sans-serif;--cc-radius: 12px;--cc-shadow: 0 8px 32px rgba(0,0,0,.4);--cc-fab-size: 56px;--cc-panel-width: 400px;--cc-panel-height: 560px;all:initial;font-family:var(--cc-font);font-size:14px;line-height:1.5;color:var(--cc-text);-webkit-font-smoothing:antialiased}*,*:before,*:after{box-sizing:border-box;margin:0;padding:0}.cc-fab{position:fixed;bottom:20px;right:20px;width:var(--cc-fab-size);height:var(--cc-fab-size);border-radius:50%;background:var(--cc-accent);border:none;cursor:pointer;display:flex;align-items:center;justify-content:center;box-shadow:0 4px 16px #0000004d;transition:transform .2s,box-shadow .2s;z-index:10000;outline:none}.cc-fab:hover{transform:scale(1.05);box-shadow:0 6px 24px #0006}.cc-fab:active{transform:scale(.95)}.cc-fab.cc-left{right:auto;left:20px}.cc-fab svg{width:24px;height:24px;fill:var(--cc-on-accent);transition:transform .3s}.cc-fab.cc-open svg{transform:rotate(90deg)}.cc-fab-badge{position:absolute;top:-2px;right:-2px;width:12px;height:12px;border-radius:50%;background:#ef4444;border:2px solid var(--cc-bg);display:none}.cc-fab-badge.cc-visible{display:block}@keyframes cc-pulse{0%,to{box-shadow:0 4px 16px #0000004d}50%{box-shadow:0 4px 16px #6366f180}}.cc-fab.cc-pulse{animation:cc-pulse 2s ease-in-out 3}.cc-panel{position:fixed;bottom:88px;right:20px;width:var(--cc-panel-width);height:var(--cc-panel-height);max-height:calc(100vh - 100px);background:var(--cc-bg);border-radius:var(--cc-radius);box-shadow:var(--cc-shadow);border:1px solid var(--cc-border);display:flex;flex-direction:column;overflow:hidden;z-index:9999;opacity:0;transform:translateY(16px) scale(.95);pointer-events:none;transition:opacity .2s,transform .2s}.cc-panel.cc-visible{opacity:1;transform:translateY(0) scale(1);pointer-events:auto}.cc-panel.cc-left{right:auto;left:20px}.cc-panel.cc-inline{position:relative;bottom:auto;right:auto;left:auto;width:100%;height:100%;max-height:100%;z-index:auto;transform:none;transition:none}.cc-panel.cc-inline:not(.cc-visible){visibility:hidden}.cc-panel.cc-inline.cc-visible{transform:none}.cc-header{display:flex;align-items:center;padding:16px;background:var(--cc-bg-surface);border-bottom:1px solid var(--cc-border);flex-shrink:0}.cc-header-avatar{width:36px;height:36px;border-radius:50%;margin-right:12px;object-fit:cover}.cc-header-avatar-placeholder{width:36px;height:36px;border-radius:50%;margin-right:12px;background:var(--cc-accent);display:flex;align-items:center;justify-content:center}.cc-header-avatar-placeholder svg{width:20px;height:20px;fill:var(--cc-on-accent)}.cc-header-info{flex:1}.cc-header-name{font-size:15px;font-weight:600;color:var(--cc-text)}.cc-header-subtitle{font-size:12px;color:var(--cc-text-secondary)}.cc-header-close{width:32px;height:32px;border-radius:8px;background:transparent;border:none;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:background .15s}.cc-header-close:hover{background:var(--cc-bg-input)}.cc-header-close svg{width:16px;height:16px;fill:var(--cc-text-secondary)}.cc-messages{flex:1;overflow-y:auto;padding:16px;display:flex;flex-direction:column;gap:12px}.cc-messages::-webkit-scrollbar{width:4px}.cc-messages::-webkit-scrollbar-track{background:transparent}.cc-messages::-webkit-scrollbar-thumb{background:var(--cc-border);border-radius:2px}.cc-message{max-width:85%;padding:10px 14px;border-radius:var(--cc-radius);word-wrap:break-word;overflow-wrap:break-word;font-size:14px;line-height:1.5;display:flex;flex-direction:column;gap:8px}.cc-message-user{align-self:flex-end;background:var(--cc-accent-contrast);color:var(--cc-on-accent);border-bottom-right-radius:4px}.cc-message-assistant{align-self:flex-start;background:var(--cc-bg-surface);color:var(--cc-text);border-bottom-left-radius:4px}.cc-message a{color:var(--cc-accent);text-decoration:underline}.cc-message-user a{color:var(--cc-on-accent)}.cc-message-error-note{margin-top:6px;font-size:12px;color:var(--cc-text-secondary)}.cc-message code{background:#0003;padding:1px 4px;border-radius:4px;font-family:SF Mono,Cascadia Code,Consolas,monospace;font-size:13px}.cc-message pre{background:#0000004d;padding:8px 12px;border-radius:8px;overflow-x:auto;margin:4px 0}.cc-message pre code{background:transparent;padding:0}.cc-message ul,.cc-message ol{padding-left:20px;margin:4px 0}.cc-message h1,.cc-message h2,.cc-message h3,.cc-message h4,.cc-message h5,.cc-message h6{font-size:15px;font-weight:600;line-height:1.4;margin:4px 0 0}.cc-message-actions{display:flex;align-items:center}.cc-message-retry,.cc-message-regenerate{display:inline-flex;align-items:center;gap:4px;padding:4px 10px;background:transparent;border:1px solid var(--cc-border);border-radius:6px;color:var(--cc-text-secondary);font-family:var(--cc-font);font-size:12px;cursor:pointer;transition:background .15s,color .15s,opacity .15s}.cc-message-retry:hover,.cc-message-regenerate:hover{background:var(--cc-bg-input);color:var(--cc-text)}.cc-message-retry svg,.cc-message-regenerate svg{fill:currentColor}.cc-message-regenerate{opacity:0}.cc-message:hover .cc-message-regenerate{opacity:1}.cc-message:focus-within .cc-message-regenerate,.cc-message-regenerate:focus-visible{opacity:1}@media(hover:none){.cc-message-regenerate{opacity:1}}.cc-message-retry{border-color:#ef4444;color:#ef4444}.cc-message-retry:hover{background:#ef44441a;color:#ef4444}.cc-typing{display:flex;align-items:center;gap:4px;padding:10px 14px;align-self:flex-start;background:var(--cc-bg-surface);border-radius:var(--cc-radius);border-bottom-left-radius:4px}.cc-typing-dot{width:6px;height:6px;border-radius:50%;background:var(--cc-text-secondary);animation:cc-bounce 1.2s infinite}.cc-typing-dot:nth-child(2){animation-delay:.2s}.cc-typing-dot:nth-child(3){animation-delay:.4s}@keyframes cc-bounce{0%,60%,to{transform:translateY(0)}30%{transform:translateY(-4px)}}.cc-input-area{display:flex;align-items:flex-end;padding:12px 16px;border-top:1px solid var(--cc-border);background:var(--cc-bg);gap:8px}.cc-input{flex:1;background:var(--cc-bg-input);border:1px solid var(--cc-border);border-radius:8px;padding:8px 12px;color:var(--cc-text);font-family:var(--cc-font);font-size:14px;line-height:1.5;resize:none;outline:none;max-height:96px;overflow-y:auto;transition:border-color .15s}.cc-input:focus{border-color:var(--cc-accent);outline:2px solid var(--cc-accent);outline-offset:1px}.cc-input::placeholder{color:var(--cc-text-secondary)}.cc-send-btn{width:36px;height:36px;border-radius:8px;background:var(--cc-accent);border:none;cursor:pointer;display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:background .15s,opacity .15s}.cc-send-btn:hover{background:var(--cc-accent-hover)}.cc-send-btn:disabled{opacity:.4;cursor:not-allowed}.cc-send-btn svg{width:16px;height:16px;fill:var(--cc-on-accent)}.cc-footer{padding:6px 16px;text-align:center;font-size:11px;color:var(--cc-text-secondary);border-top:1px solid var(--cc-border)}.cc-footer a{color:var(--cc-text-secondary);text-decoration:none}.cc-footer a:hover{text-decoration:underline}.cc-bubble{position:fixed;bottom:84px;right:20px;background:var(--cc-bg-surface);color:var(--cc-text);padding:10px 16px;border-radius:var(--cc-radius);box-shadow:var(--cc-shadow);border:1px solid var(--cc-border);max-width:260px;font-size:13px;line-height:1.4;z-index:9998;opacity:0;transform:translateY(8px);pointer-events:none;transition:opacity .3s,transform .3s;cursor:pointer}.cc-bubble.cc-visible{opacity:1;transform:translateY(0);pointer-events:auto}.cc-bubble.cc-left{right:auto;left:20px}.cc-bubble-close{position:absolute;top:-8px;right:-8px;width:20px;height:20px;border-radius:50%;background:var(--cc-bg);border:1px solid var(--cc-border);cursor:pointer;display:flex;align-items:center;justify-content:center;font-size:10px;color:var(--cc-text-secondary)}.cc-hidden{display:none}.cc-sr-only{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap}.cc-messages-wrapper{flex:1;display:flex;flex-direction:column;min-height:0}.cc-prechat{flex:1;overflow-y:auto;padding:24px 16px;display:flex;flex-direction:column;gap:16px}.cc-prechat-title{font-size:18px;font-weight:600;color:var(--cc-text)}.cc-prechat-subtitle{font-size:13px;color:var(--cc-text-secondary);margin-top:-8px}.cc-prechat-fields{display:flex;flex-direction:column;gap:14px}.cc-prechat-field{display:flex;flex-direction:column;gap:4px}.cc-prechat-label{font-size:13px;font-weight:500;color:var(--cc-text)}.cc-prechat-label .cc-required{color:#ef4444;margin-left:2px}.cc-prechat-input,.cc-prechat-select,.cc-prechat-textarea{background:var(--cc-bg-input);border:1px solid var(--cc-border);border-radius:8px;padding:8px 12px;color:var(--cc-text);font-family:var(--cc-font);font-size:14px;outline:none;transition:border-color .15s}.cc-prechat-input:focus,.cc-prechat-select:focus,.cc-prechat-textarea:focus{border-color:var(--cc-accent)}.cc-prechat-select{-webkit-appearance:auto;-moz-appearance:auto;appearance:auto}.cc-prechat-textarea{resize:none;line-height:1.5}.cc-prechat-error{font-size:12px;color:#ef4444;min-height:0}.cc-prechat-error:empty{display:none}.cc-prechat-submit{background:var(--cc-accent-contrast);color:var(--cc-on-accent);border:none;border-radius:8px;padding:10px 16px;font-family:var(--cc-font);font-size:14px;font-weight:500;cursor:pointer;transition:background .15s;margin-top:8px}.cc-prechat-submit:hover{background:var(--cc-accent-hover)}.cc-prechat-submit:disabled{opacity:.5;cursor:not-allowed}@media(max-width:768px){.cc-fab.cc-open{display:none}.cc-panel:not(.cc-inline){width:100%;height:100%;max-height:100%;bottom:0;right:0;left:0;border-radius:0;border:none}.cc-panel.cc-left:not(.cc-inline){left:0}.cc-bubble{bottom:84px;right:16px;left:16px;max-width:none}}.cc-fab:focus-visible,.cc-header-close:focus-visible,.cc-send-btn:focus-visible,.cc-message-retry:focus-visible,.cc-message-regenerate:focus-visible,.cc-bubble-close:focus-visible,.cc-prechat-submit:focus-visible{outline:2px solid var(--cc-accent);outline-offset:3px}@media(prefers-reduced-motion:reduce){.cc-fab.cc-pulse,.cc-typing-dot{animation:none}.cc-panel,.cc-bubble{transition:none}}",a.appendChild(i),a}const a={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"};const i=new Set(["http","https","mailto","tel"]);function n(e){let t=e.replace(/[&<>"']/g,e=>a[e]??e);const s=function(e){let t="\0";for(;e.includes(t);)t+="\0";return t}(t),n=[],r=e=>{const t=n.push(e)-1;return`${s}${t}${s}`};t=t.replace(/```(?:\w*)\n?([\s\S]*?)```/g,(e,t)=>r(`<pre><code>${t.trim()}</code></pre>`)),t=t.replace(/`([^`]+)`/g,(e,t)=>r(`<code>${t}</code>`)),t=t.replace(/^(#{1,6}) (.+)$/gm,(e,t,s)=>{const a=t.length;return`<h${a}>${s}</h${a}>`}),t=t.replace(/\*\*(.+?)\*\*/g,"<strong>$1</strong>"),t=t.replace(/\*(\S(?:.*?\S)??)\*/g,"<em>$1</em>"),t=t.replace(/\[([^\]]+)\]\(((?:[^()]*|\([^()]*\))*)\)/g,(e,t,s)=>function(e){const t=e.replace(/[\t\n\r]/g,"").replace(/^[\u0000-\u0020]+/,""),s=/^([^:/?#]+):/.exec(t);return!s||i.has(s[1].toLowerCase())}(s)?`<a href="${s}" target="_blank" rel="noopener noreferrer">${t}</a>`:t),t=t.replace(/^[-*+] (.+)$/gm,'<li data-md="ul">$1</li>'),t=t.replace(/^\d+\. (.+)$/gm,'<li data-md="ol">$1</li>'),t=t.replace(/(?:<li data-md="ul">.*?<\/li>\n?)+|(?:<li data-md="ol">.*?<\/li>\n?)+/g,e=>{const t=e.includes('data-md="ol"')?"ol":"ul";return`<${t}>${e.replace(/ data-md="(?:ul|ol)"/g,"").replace(/\n/g,"")}</${t}>`}),t=t.replace(/(<\/h[1-6]>)\n+/g,"$1"),t=t.replace(/\n\n/g,"<br><br>"),t=t.replace(/\n/g,"<br>");for(let a=0;a<n.length;a++)t=t.replace(`${s}${a}${s}`,()=>n[a]);return t}class r{constructor(e,t){this.typingEl=null,this.actions=t,this.container=document.createElement("div"),this.container.className="cc-messages",this.container.setAttribute("role","log"),this.container.setAttribute("aria-live","polite"),e.appendChild(this.container)}addMessage(e){this.removeTyping();const t=this.createMessageElement(e);return this.container.appendChild(t),this.scrollToBottom(),t}updateMessage(e){const t=this.findMessage(e.id);t&&(this.renderMessageElement(t,e),this.scrollToBottom())}showTyping(){var e;this.typingEl||(this.typingEl=document.createElement("div"),this.typingEl.className="cc-typing",this.typingEl.innerHTML=`<span class="cc-sr-only">${this.escapeHtml((null==(e=this.actions)?void 0:e.typingLabel)??"Typing...")}</span><div class="cc-typing-dot" aria-hidden="true"></div><div class="cc-typing-dot" aria-hidden="true"></div><div class="cc-typing-dot" aria-hidden="true"></div>`,this.container.appendChild(this.typingEl),this.scrollToBottom())}removeTyping(){this.typingEl&&(this.typingEl.remove(),this.typingEl=null)}clear(){this.container.innerHTML="",this.typingEl=null}removeMessage(e){const t=this.findMessage(e);null==t||t.remove()}clearRegenerateButtons(){this.container.querySelectorAll(".cc-message-regenerate").forEach(e=>{e.remove()}),this.cleanupEmptyActionContainers()}showRegenerateButton(e){var t;if(this.clearRegenerateButtons(),!(null==(t=this.actions)?void 0:t.onRegenerate))return;const s=this.findMessage(e);if(!s||!s.classList.contains("cc-message-assistant"))return;this.ensureActionsContainer(s).appendChild(this.createActionButton({className:"cc-message-regenerate",label:this.actions.regenerateLabel??"Regenerate",icon:'<svg viewBox="0 0 24 24" width="14" height="14" aria-hidden="true"><path d="M12 4V1L8 5l4 4V6c3.31 0 6 2.69 6 6 0 1.01-.25 1.97-.7 2.8l1.46 1.46A7.93 7.93 0 0020 12c0-4.42-3.58-8-8-8zm0 14c-3.31 0-6-2.69-6-6 0-1.01.25-1.97.7-2.8L5.24 7.74A7.93 7.93 0 004 12c0 4.42 3.58 8 8 8v3l4-4-4-4v3z"/></svg>',onClick:()=>{var t,s;return null==(s=null==(t=this.actions)?void 0:t.onRegenerate)?void 0:s.call(t,e)}}))}setVisible(e){this.container.classList.toggle("cc-hidden",!e)}findMessage(e){return Array.from(this.container.children).find(t=>t.dataset.id===e)??null}scrollToBottom(){this.container.scrollTop=this.container.scrollHeight}createMessageElement(e){const t=document.createElement("div");return this.renderMessageElement(t,e),t}renderMessageElement(e,t){e.className=`cc-message cc-message-${t.role}`,e.dataset.id=t.id,"assistant"===t.role&&"welcome"!==t.id&&(e.dataset.aiGenerated="true"),t.status?e.dataset.status=t.status:delete e.dataset.status,"streaming"===t.status?e.setAttribute("aria-busy","true"):e.removeAttribute("aria-busy"),t.errorType?e.dataset.errorType=t.errorType:delete e.dataset.errorType,e.innerHTML="";const s=document.createElement("div");if(s.className="cc-message-content",s.innerHTML="assistant"===t.role?n(t.content):this.escapeHtml(t.content),e.appendChild(s),"error"===t.status&&t.errorText){const s=document.createElement("div");s.className="cc-message-error-note",s.textContent=t.errorText,e.appendChild(s)}const a=this.createActionsContainer(t);a&&e.appendChild(a)}createActionsContainer(e){var t;if("error"!==e.status||!(null==(t=this.actions)?void 0:t.onRetry))return null;const s=document.createElement("div");return s.className="cc-message-actions",s.appendChild(this.createActionButton({className:"cc-message-retry",label:this.actions.retryLabel??"Retry",icon:'<svg viewBox="0 0 24 24" width="14" height="14" aria-hidden="true"><path d="M17.65 6.35A7.96 7.96 0 0012 4c-4.42 0-7.99 3.58-7.99 8s3.57 8 7.99 8c3.73 0 6.84-2.55 7.73-6h-2.08A5.99 5.99 0 0112 18c-3.31 0-6-2.69-6-6s2.69-6 6-6c1.66 0 3.14.69 4.22 1.78L13 11h7V4l-2.35 2.35z"/></svg>',onClick:()=>{var t,s;return null==(s=null==(t=this.actions)?void 0:t.onRetry)?void 0:s.call(t,e.id)}})),s}ensureActionsContainer(e){const t=e.querySelector(".cc-message-actions");if(t)return t;const s=document.createElement("div");return s.className="cc-message-actions",e.appendChild(s),s}cleanupEmptyActionContainers(){this.container.querySelectorAll(".cc-message-actions").forEach(e=>{e.hasChildNodes()||e.remove()})}createActionButton(e){const t=document.createElement("button");return t.type="button",t.className=e.className,t.innerHTML=`${e.icon}<span>${this.escapeHtml(e.label)}</span>`,t.addEventListener("click",e.onClick),t}escapeHtml(e){const t=document.createElement("div");return t.textContent=e,t.innerHTML}}class o{constructor(e,t){this.onSend=t.onSend,this.area=document.createElement("div"),this.area.className="cc-input-area",this.textarea=document.createElement("textarea"),this.textarea.className="cc-input",this.textarea.placeholder=t.placeholder,this.textarea.setAttribute("aria-label",t.placeholder),this.textarea.rows=1,this.textarea.maxLength=1e4,this.textarea.addEventListener("input",()=>this.autoResize()),this.textarea.addEventListener("keydown",e=>this.handleKeydown(e)),this.sendBtn=document.createElement("button"),this.sendBtn.className="cc-send-btn",this.sendBtn.disabled=!0,this.sendBtn.setAttribute("aria-label",t.sendLabel),this.sendBtn.innerHTML='<svg viewBox="0 0 24 24"><path d="M2.01 21L23 12 2.01 3 2 10l15 2-15 2z"/></svg>',this.sendBtn.addEventListener("click",()=>this.send()),this.textarea.addEventListener("input",()=>{this.sendBtn.disabled=0===this.textarea.value.trim().length}),this.area.appendChild(this.textarea),this.area.appendChild(this.sendBtn),e.appendChild(this.area)}focus(){this.textarea.focus()}setDisabled(e){this.textarea.disabled=e,this.sendBtn.disabled=e||0===this.textarea.value.trim().length}clear(){this.textarea.value="",this.sendBtn.disabled=!0,this.autoResize()}setVisible(e){this.area.classList.toggle("cc-hidden",!e)}send(){const e=this.textarea.value.trim();e&&(this.onSend(e),this.clear())}handleKeydown(e){e.isComposing||229===e.keyCode||"Enter"!==e.key||e.shiftKey||(e.preventDefault(),this.send())}autoResize(){this.textarea.style.height="auto";this.textarea.style.height=Math.min(this.textarea.scrollHeight,96)+"px"}}const c="cc-panel";class l{constructor(e,t){this.inline=t.inline??!1,this.el=document.createElement("div"),this.el.className="cc-panel",t.inline&&this.el.classList.add("cc-inline"),"bottom-left"===t.position&&this.el.classList.add("cc-left"),t.inline||(this.el.id=c,this.el.setAttribute("role","dialog"),this.el.setAttribute("aria-label",t.branding.name),this.el.addEventListener("keydown",e=>{"Escape"===e.key&&t.onClose()}),this.setHidden(!0));const s=document.createElement("div");if(s.className="cc-header",t.branding.avatar){const e=document.createElement("img");e.className="cc-header-avatar",e.src=t.branding.avatar,e.alt=t.branding.name,s.appendChild(e)}else{const e=document.createElement("div");e.className="cc-header-avatar-placeholder",e.innerHTML='<svg viewBox="0 0 24 24"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 3c1.66 0 3 1.34 3 3s-1.34 3-3 3-3-1.34-3-3 1.34-3 3-3zm0 14.2c-2.5 0-4.71-1.28-6-3.22.03-1.99 4-3.08 6-3.08 1.99 0 5.97 1.09 6 3.08-1.29 1.94-3.5 3.22-6 3.22z"/></svg>',s.appendChild(e)}const a=document.createElement("div");if(a.className="cc-header-info",a.innerHTML=`<div class="cc-header-name">${this.escapeHtml(t.branding.name)}</div><div class="cc-header-subtitle">${this.escapeHtml(t.branding.subtitle)}</div>`,s.appendChild(a),!t.inline){const e=document.createElement("button");e.className="cc-header-close",e.setAttribute("aria-label",t.closeLabel),e.innerHTML='<svg viewBox="0 0 24 24"><path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z"/></svg>',e.addEventListener("click",t.onClose),s.appendChild(e)}this.el.appendChild(s),t.preChatEnabled?(this.messagesContainer=document.createElement("div"),this.messagesContainer.className="cc-messages-wrapper",this.el.appendChild(this.messagesContainer)):this.messagesContainer=this.el,this.messages=new r(this.messagesContainer,t.messageActions),this.input=new o(this.el,{placeholder:t.placeholder,sendLabel:t.sendLabel,onSend:t.onSend});const i=document.createElement("div");i.className="cc-footer",i.innerHTML=t.footerText,this.el.appendChild(i),e.appendChild(this.el)}show(){this.el.classList.add("cc-visible"),this.inline||(this.setHidden(!1),this.input.focus())}hide(){this.el.classList.remove("cc-visible"),this.inline||this.setHidden(!0)}containsFocus(){return this.el.contains(this.el.getRootNode().activeElement)}get isVisible(){return this.el.classList.contains("cc-visible")}addMessage(e){return this.messages.addMessage(e)}hideMessages(){this.messages.setVisible(!1)}showMessages(){this.messages.setVisible(!0)}destroy(){this.el.remove()}setHidden(e){this.el.toggleAttribute("inert",e),e?this.el.setAttribute("aria-hidden","true"):this.el.removeAttribute("aria-hidden")}escapeHtml(e){const t=document.createElement("div");return t.textContent=e,t.innerHTML}}const d='<svg viewBox="0 0 24 24"><path d="M20 2H4c-1.1 0-2 .9-2 2v18l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm0 14H5.17L4 17.17V4h16v12z"/><path d="M7 9h10v2H7zm0-3h10v2H7z"/></svg>';class h{constructor(e,t){this.openLabel=t.openLabel,this.closeLabel=t.closeLabel,this.el=document.createElement("button"),this.el.className="cc-fab cc-pulse",this.el.setAttribute("aria-label",this.openLabel),this.el.setAttribute("aria-expanded","false"),this.el.setAttribute("aria-controls",c),"bottom-left"===t.position&&this.el.classList.add("cc-left"),this.el.innerHTML=d,this.badge=document.createElement("div"),this.badge.className="cc-fab-badge",this.el.appendChild(this.badge),this.el.addEventListener("click",()=>{this.el.classList.remove("cc-pulse"),t.onClick()}),e.appendChild(this.el)}setOpen(e){this.el.innerHTML=e?'<svg viewBox="0 0 24 24"><path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z"/></svg>':d,e||this.el.appendChild(this.badge),this.el.classList.toggle("cc-open",e),this.el.setAttribute("aria-label",e?this.closeLabel:this.openLabel),this.el.setAttribute("aria-expanded",String(e))}focus(){this.el.focus()}showBadge(){this.badge.classList.add("cc-visible")}hideBadge(){this.badge.classList.remove("cc-visible")}destroy(){this.el.remove()}}const p="chatcops_bubble_shown";class u{constructor(e,t){this.timerId=null,this.el=document.createElement("div"),this.el.className="cc-bubble","bottom-left"===t.position&&this.el.classList.add("cc-left"),this.el.textContent=t.text,this.setHidden(!0);const s=document.createElement("button");if(s.type="button",s.className="cc-bubble-close",s.setAttribute("aria-label",t.dismissLabel),s.innerHTML="&times;",s.addEventListener("click",e=>{e.stopPropagation(),this.hide()}),this.el.appendChild(s),this.el.addEventListener("click",()=>{this.hide(),t.onClick()}),e.appendChild(this.el),t.showOnce)try{if(sessionStorage.getItem(p))return;sessionStorage.setItem(p,"1")}catch{}this.timerId=setTimeout(()=>{this.el.classList.add("cc-visible"),this.setHidden(!1)},t.delay??3e3)}hide(){this.el.classList.remove("cc-visible"),this.setHidden(!0),this.timerId&&(clearTimeout(this.timerId),this.timerId=null)}setHidden(e){this.el.toggleAttribute("inert",e),e?this.el.setAttribute("aria-hidden","true"):this.el.removeAttribute("aria-hidden")}destroy(){this.hide(),this.el.remove()}}let m;async function g(e){m??(m=new Promise((e,t)=>{const s=document.createElement("script");s.src="https://challenges.cloudflare.com/turnstile/v0/api.js?render=explicit",s.onload=e,s.onerror=t,document.head.append(s)})),await m;const t=document.createElement("div");t.style.cssText="position:fixed;bottom:96px;right:24px;z-index:2147483647",document.body.append(t);try{return await new Promise((s,a)=>{window.turnstile.render(t,{sitekey:e,appearance:"interaction-only",callback:s,"error-callback":a})})}finally{t.remove()}}class b{constructor(e){this.saved={},this.apiUrl=e.apiUrl,this.turnstileSiteKey=e.turnstileSiteKey,this.timeout=e.timeout??3e4,this.sessionKey=`chatcops-session:${e.apiUrl}`;try{this.saved=JSON.parse(localStorage.getItem(this.sessionKey)||"{}")}catch{}}async*sendMessage(e,t={}){var s;const a=new AbortController,i=t.timeout??this.timeout;let n,r,o=!1;const c=t.signal,l=()=>{clearTimeout(n),a.abort()},d=()=>{clearTimeout(n),a.signal.aborted||(n=setTimeout(()=>{o=!0,a.abort()},i))},h=async()=>{if(clearTimeout(n),null==c||c.removeEventListener("abort",l),r){const e=r;r=void 0;try{await e.cancel()}catch{}finally{e.releaseLock()}}};c&&(c.aborted?a.abort():c.addEventListener("abort",l)),d();try{const t=(e,t,s)=>fetch(e,{method:"POST",headers:{"Content-Type":"application/json",...s&&{Authorization:`Bearer ${s}`}},body:JSON.stringify(t),signal:a.signal}),i=this.saved,n=i.conversationId===e.conversationId;let o=await t(this.apiUrl,{protocol:1,...e},n?i.token:void 0);if(401===o.status){const s=await t(this.apiUrl.replace(/\/?(\?.*)?$/,"/session$1"),{conversationId:e.conversationId,previousToken:i.token,turnstileToken:this.turnstileSiteKey&&!n?await g(this.turnstileSiteKey):void 0});if(s.ok){const a=await s.json();this.saved=a;try{localStorage.setItem(this.sessionKey,JSON.stringify(a))}catch{}a.conversationId!==e.conversationId&&(e={...e,conversationId:a.conversationId},yield{conversationId:a.conversationId}),o=await t(this.apiUrl,{protocol:1,...e},a.token)}else this.saved={}}if(!o.ok){const{error:e}=await o.json().catch(()=>({}));return await h(),void(yield(null==e?void 0:e.code)?v(e.code,e.retryAfterMs):{error:429===o.status?"rate_limit":`HTTP ${o.status}`})}if(r=null==(s=o.body)?void 0:s.getReader(),!r)return await h(),void(yield{error:"No response body"});const c=new TextDecoder;let l="",p=!1,u=!1;for(;;){const{done:e,value:t}=await r.read();if(e)break;t.byteLength>0&&d(),l+=c.decode(t,{stream:!0});const s=l.split("\n");l=s.pop()??"";for(const a of s){const e=a.trim();if(!e||!e.startsWith("data: "))continue;const t=e.slice(6);if("[DONE]"===t)return await h(),void(yield p&&!u?{error:"cut_off"}:{done:!0});let s;try{s=JSON.parse(t)}catch{continue}if("type"in s){p=!0,"finish"===s.type&&(u=!0);const e=y(s);e&&(yield e)}else yield s}}await h(),yield"data: [DONE]"===l.trim()?{done:!0}:{error:p?"cut_off":"network"}}catch(p){await h(),p instanceof DOMException&&"AbortError"===p.name?yield o?{error:"timeout"}:{error:"aborted"}:yield{error:"network"}}finally{await h()}}}const f={rate_limited:"rate_limit",timeout:"timeout",budget_exceeded:"budget",budget_daily:"budget_daily",provider_unavailable:"unavailable"};function v(e,t){return{error:f[e]??"provider_error",retryAfterMs:t}}function y(e){switch(e.type){case"start":return{messageId:e.messageId};case"text-delta":return{content:e.delta};case"lead-captured":return{leadCaptured:!0,leadData:e.lead};case"error":return v("budget_exceeded"===e.code&&"conversation"!==e.scope?"budget_daily":e.code,e.retryAfterMs);case"finish":return"error"===e.reason||"aborted"===e.reason?null:{done:!0};default:return null}}const x="chatcops_conversation",w="chatcops_session_id";class C{constructor(e){this.key=e?`${x}_${e}`:x,this.sessionKey=e?`${w}_${e}`:w}load(){try{const e=localStorage.getItem(this.key);if(null===e)return null;let t;try{t=JSON.parse(e)}catch{return this.clear(),null}if("object"!=typeof t||null===t||Array.isArray(t)||"string"!=typeof t.id||!Array.isArray(t.messages))return this.clear(),null;const s=t,a=s.messages.filter(e=>"object"==typeof e&&null!==e&&!Array.isArray(e)&&("user"===e.role||"assistant"===e.role)&&"string"==typeof e.content);return{...s,id:s.id,messages:a}}catch{return null}}save(e){try{const t={...e,messages:e.messages.filter(e=>"error"!==e.status).map(({status:e,...t})=>t)};localStorage.setItem(this.key,JSON.stringify(t))}catch{}}clear(){try{localStorage.removeItem(this.key)}catch{}}getSessionId(){try{let e=sessionStorage.getItem(this.sessionKey);return e||(e=crypto.randomUUID(),sessionStorage.setItem(this.sessionKey,e)),e}catch{return crypto.randomUUID()}}isPreChatCompleted(e){try{return"true"===sessionStorage.getItem(`chatcops-prechat-${e}`)}catch{return!1}}setPreChatCompleted(e,t){try{sessionStorage.setItem(`chatcops-prechat-${e}`,"true")}catch{}t&&this.setPreChatData(e,t)}getPreChatData(e){try{const t=sessionStorage.getItem(`chatcops-prechat-data-${e}`);if(!t)return null;const s=JSON.parse(t);return"object"!=typeof s||null===s||Array.isArray(s)?null:s}catch{return null}}setPreChatData(e,t){try{sessionStorage.setItem(`chatcops-prechat-data-${e}`,JSON.stringify(t))}catch{}}}const E=Symbol.for("chatcops.storageClaims"),M=globalThis;M[E]??(M[E]=new Map);const S=M[E];function k(e){const t=S.get(e);if(!t)return!1;for(const s of t)s()||t.delete(s);return 0===t.size&&S.delete(e),t.size>0}function L(e,t){const s=e.host;if(t.accent){s.style.setProperty("--cc-accent",t.accent),s.style.setProperty("--cc-accent-hover",z(t.accent,10));const e=function(e){if(!function(e){return/^#?[\da-f]{3}(?:[\da-f]{3})?$/i.test(e.trim())}(e))return null;const t=e.trim().startsWith("#")?e.trim():`#${e.trim()}`;if(N(I,t)>=A)return{onAccent:I,background:t};if(N(T,t)>=A)return{onAccent:T,background:t};for(let s=2;s<=60;s+=2){const e=z(t,s);if(N(I,e)>=A)return{onAccent:I,background:e}}return{onAccent:I,background:T}}(t.accent);e?(s.style.setProperty("--cc-on-accent",e.onAccent),s.style.setProperty("--cc-accent-contrast",e.background)):s.style.setProperty("--cc-accent-contrast",t.accent)}if(t.textColor&&s.style.setProperty("--cc-text",t.textColor),t.bgColor&&(s.style.setProperty("--cc-bg",t.bgColor),s.style.setProperty("--cc-bg-surface",R(t.bgColor,8)),s.style.setProperty("--cc-bg-input",R(t.bgColor,14))),t.fontFamily&&s.style.setProperty("--cc-font",t.fontFamily),void 0!==t.borderRadius){const e=function(e){if("number"==typeof e&&!Number.isFinite(e))return"";const t=String(e).trim();return/^(?:\d+(?:\.\d+)?|\.\d+)$/.test(t)?`${t}px`:t}(t.borderRadius);e&&s.style.setProperty("--cc-radius",e)}}const I="#ffffff",T="#0a0a0a",A=4.5;function B(e){const t=$(e).map(e=>{const t=e/255;return t<=.03928?t/12.92:((t+.055)/1.055)**2.4});return.2126*t[0]+.7152*t[1]+.0722*t[2]}function N(e,t){const[s,a]=[B(e),B(t)].sort((e,t)=>t-e);return(s+.05)/(a+.05)}function $(e){if(!/^#?[\da-f]{3}(?:[\da-f]{3})?$/i.test(e))return[0,0,0];const t=e.replace("#",""),s=parseInt(3===t.length?t.split("").map(e=>e+e).join(""):t,16);return[s>>16&255,s>>8&255,255&s]}function H(e,t,s){return"#"+[e,t,s].map(e=>Math.max(0,Math.min(255,e)).toString(16).padStart(2,"0")).join("")}function z(e,t){const[s,a,i]=$(e),n=1-t/100;return H(Math.round(s*n),Math.round(a*n),Math.round(i*n))}function R(e,t){const[s,a,i]=$(e),n=t/100;return H(Math.round(s+(255-s)*n),Math.round(a+(255-a)*n),Math.round(i+(255-i)*n))}const P={welcomeMessage:"How can I help you today?",inputPlaceholder:"Type a message...",sendButton:"Send",closeButton:"Close",openChat:"Open chat",defaultName:"AI Assistant",defaultSubtitle:"Online",greetingWithName:"Hi {name}!",selectPlaceholder:"Select {label}...",dismissBubble:"Dismiss",errorGeneric:"Something went wrong. Please try again.",errorNetwork:"Connection error. Please check your network.",errorRateLimit:"Too many messages. Please wait a moment.",errorRateLimitWait:"Too many messages. Please try again in {seconds} seconds.",errorBudget:"This chat has reached its limit.",errorBudgetDaily:"The assistant has reached its limit for today. Please try again later.",errorUnavailable:"The assistant is unavailable right now. Please try again later.",errorCutOff:"The reply was cut off.",typingIndicator:"Typing...",poweredBy:"Powered by ChatCops",newConversation:"New conversation",welcomeBubbleDefault:"Need help? Chat with us!",preChatTitle:"Before we start...",preChatSubtitle:"Tell us a bit about yourself",preChatSubmit:"Start Chat",preChatRequired:"This field is required",preChatInvalidEmail:"Please enter a valid email",retryButton:"Retry",regenerateButton:"Regenerate"},D={en:P};class O{constructor(e,t){if(this.fieldElements=new Map,this.errorElements=new Map,this.options=t,this.container=document.createElement("div"),this.container.className="cc-prechat",t.title){const e=document.createElement("div");e.className="cc-prechat-title",e.textContent=t.title,this.container.appendChild(e)}if(t.subtitle){const e=document.createElement("div");e.className="cc-prechat-subtitle",e.textContent=t.subtitle,this.container.appendChild(e)}const s=document.createElement("form");s.className="cc-prechat-fields",s.noValidate=!0,s.addEventListener("submit",e=>{e.preventDefault(),this.handleSubmit()});for(const i of t.fields)s.appendChild(this.createField(i));this.submitBtn=document.createElement("button"),this.submitBtn.type="submit",this.submitBtn.className="cc-prechat-submit",this.submitBtn.textContent=t.submitLabel,s.appendChild(this.submitBtn),this.container.appendChild(s),e.appendChild(this.container),this.updateSubmitState();const a=this.fieldElements.values().next().value;a&&setTimeout(()=>a.focus(),100)}createField(e){const t=document.createElement("div");t.className="cc-prechat-field";const s=`cc-prechat-${e.name}`,a=`cc-prechat-${e.name}-error`,i=document.createElement("label");if(i.className="cc-prechat-label",i.htmlFor=s,i.textContent=e.label,e.required){const e=document.createElement("span");e.className="cc-required",e.textContent="*",i.appendChild(e)}let n;if(t.appendChild(i),"select"===e.type){const t=document.createElement("select");t.className="cc-prechat-select";const s=document.createElement("option");s.value="",s.textContent=e.placeholder??this.options.locale.selectPlaceholder.replace("{label}",e.label.toLowerCase()),s.disabled=!0,s.selected=!0,t.appendChild(s);for(const a of e.options??[]){const e=document.createElement("option");e.value=a,e.textContent=a,t.appendChild(e)}n=t}else if("textarea"===e.type){const t=document.createElement("textarea");t.className="cc-prechat-textarea",t.placeholder=e.placeholder??"",t.rows=3,t.maxLength=500,n=t}else{const t=document.createElement("input");t.type=e.type,t.className="cc-prechat-input",t.maxLength=500,t.placeholder=e.placeholder??"",n=t}n.name=e.name,n.id=s,e.required&&n.setAttribute("aria-required","true"),n.addEventListener("input",()=>{this.clearError(e.name),this.updateSubmitState()}),n instanceof HTMLSelectElement&&n.addEventListener("change",()=>{this.clearError(e.name),this.updateSubmitState()}),t.appendChild(n),this.fieldElements.set(e.name,n);const r=document.createElement("div");return r.className="cc-prechat-error",r.id=a,t.appendChild(r),this.errorElements.set(e.name,r),t}updateSubmitState(){const e=this.options.fields.every(e=>{if(!e.required)return!0;const t=this.fieldElements.get(e.name);return!!t&&t.value.trim().length>0});this.submitBtn.disabled=!e}handleSubmit(){const e={};let t=!0;for(const s of this.options.fields){const a=this.fieldElements.get(s.name);if(!a)continue;const i=a.value.trim();e[s.name]=i,!s.required||i?"email"===s.type&&i&&!this.isValidEmail(i)&&(this.showError(s.name,this.options.locale.preChatInvalidEmail),t=!1):(this.showError(s.name,this.options.locale.preChatRequired),t=!1)}t&&this.options.onSubmit(e)}showError(e,t){const s=this.errorElements.get(e);s&&(s.textContent=t);const a=this.fieldElements.get(e);a&&s&&(a.setAttribute("aria-invalid","true"),a.setAttribute("aria-describedby",s.id))}clearError(e){const t=this.errorElements.get(e);t&&(t.textContent="");const s=this.fieldElements.get(e);s&&t&&(s.getAttribute("aria-describedby")===t.id&&s.removeAttribute("aria-describedby"),"true"===s.getAttribute("aria-invalid")&&s.removeAttribute("aria-invalid"))}isValidEmail(e){return/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e)}destroy(){this.container.remove(),this.fieldElements.clear(),this.errorElements.clear()}}const F={network:"errorNetwork",timeout:"errorNetwork",provider_error:"errorGeneric",budget:"errorBudget",budget_daily:"errorBudgetDaily",unavailable:"errorUnavailable",cut_off:"errorCutOff"};class _{constructor(e){this.mounted=!1,this.messages=[],this.isStreaming=!1,this.v1=!1,this.destroyed=!1,this.retryRequests=new Map,this.eventHandlers=new Map,this.config=e,this.client=new b({apiUrl:e.apiUrl,timeout:e.timeout,turnstileSiteKey:e.turnstileSiteKey}),this.namespace=function(e,t,s){let a=e??"";if(void 0===e&&k("")){a=t;for(let e=2;k(a);e+=1)a=`${t}-${e}`;console.warn(`[chatcops] Another widget on this page already uses the default storage, so this one keeps its conversation under "${a}". Set a \`siteId\` on each widget to name them yourself.`)}else void 0!==e&&k(e)&&console.warn(`[chatcops] Two widgets on this page use the siteId "${e}", so they share one conversation.`);return S.has(a)||S.set(a,new Set),S.get(a).add(s),{siteId:""===a?void 0:a,release(){var e,t;null==(e=S.get(a))||e.delete(s),0===(null==(t=S.get(a))?void 0:t.size)&&S.delete(a)}}}(e.siteId,e.mode??"popup",()=>!this.destroyed&&(!this.mounted||this.shadow.host.isConnected)),this.storage=new C(this.namespace.siteId),this.locale=function(e,t){const s=D[e]??P;return t?{...s,...t}:s}(e.locale??"en",e.strings),this.conversationId=this.storage.getSessionId()}get isInline(){return"inline"===this.config.mode}resolveContainer(){if(!this.config.container)throw new Error('ChatCops: "container" is required when mode is "inline"');if("string"==typeof this.config.container){const e=document.querySelector(this.config.container);if(!e)throw new Error(`ChatCops: container element not found: ${this.config.container}`);return e}return this.config.container}init(){var e,t,a,i,n,r,o;this.isInline?(this.containerEl=this.resolveContainer(),this.shadow=s(this.containerEl)):this.shadow=s(),this.mounted=!0,this.config.theme&&L(this.shadow,this.config.theme);const c=(null==(e=this.config.theme)?void 0:e.position)??"bottom-right";if(this.isInline||(this.fab=new h(this.shadow,{position:c,openLabel:this.locale.openChat,closeLabel:this.locale.closeButton,onClick:()=>this.toggle()})),this.panel=new l(this.shadow,{position:c,inline:this.isInline,preChatEnabled:(null==(t=this.config.preChatForm)?void 0:t.enabled)??!1,branding:{name:(null==(a=this.config.branding)?void 0:a.name)??this.locale.defaultName,avatar:null==(i=this.config.branding)?void 0:i.avatar,subtitle:(null==(n=this.config.branding)?void 0:n.subtitle)??this.locale.defaultSubtitle},placeholder:this.config.placeholder??this.locale.inputPlaceholder,footerText:this.locale.poweredBy,closeLabel:this.locale.closeButton,sendLabel:this.locale.sendButton,messageActions:{onRetry:e=>{this.handleRetry(e)},onRegenerate:e=>{this.handleRegenerate(e)},retryLabel:this.locale.retryButton,regenerateLabel:this.locale.regenerateButton,typingLabel:this.locale.typingIndicator},onSend:e=>this.handleSend(e),onClose:()=>this.close()}),!1!==this.config.persistHistory){const e=this.storage.load();if(e){this.conversationId=e.id;for(const t of e.messages)this.messages.push(t),this.panel.addMessage(t)}}if(null==(r=this.config.preChatForm)?void 0:r.enabled){const e=this.storage.getPreChatData(this.conversationId);e&&(this.userData=e)}if((null==(o=this.config.preChatForm)?void 0:o.enabled)&&!this.isPreChatCompleted()&&0===this.messages.length?this.showPreChatForm():this.showChatView(),this.showLatestRegenerateButton(),!this.isInline&&this.config.welcomeBubble&&(this.bubble=new u(this.shadow,{text:this.config.welcomeBubble.text,delay:this.config.welcomeBubble.delay,showOnce:this.config.welcomeBubble.showOnce??!0,position:c,dismissLabel:this.locale.dismissBubble,onClick:()=>this.open()})),this.isInline&&this.panel.show(),!this.isInline&&void 0!==this.config.autoOpen&&!1!==this.config.autoOpen){const e="number"==typeof this.config.autoOpen?this.config.autoOpen:0;this.autoOpenTimer=setTimeout(()=>this.open(),e)}}open(){var e,t,s,a,i;this.panel.show(),this.isInline||(null==(e=this.fab)||e.setOpen(!0),null==(t=this.fab)||t.hideBadge(),null==(s=this.bubble)||s.hide()),null==(i=(a=this.config).onOpen)||i.call(a),this.emit("open")}close(){var e,t,s,a;const i=this.panel.containsFocus();this.panel.hide(),this.isInline||(null==(e=this.fab)||e.setOpen(!1),i&&(null==(t=this.fab)||t.focus())),null==(a=(s=this.config).onClose)||a.call(s),this.emit("close")}toggle(){this.panel.isVisible?this.close():this.open()}destroy(){var e,t,s,a,i;this.destroyed=!0,void 0!==this.autoOpenTimer&&clearTimeout(this.autoOpenTimer),null==(e=this.abortController)||e.abort(),this.abortController=void 0,null==(t=this.preChatFormEl)||t.destroy(),null==(s=this.bubble)||s.destroy(),this.panel.destroy(),null==(a=this.fab)||a.destroy(),null==(i=this.shadow)||i.host.remove(),this.namespace.release(),this.eventHandlers.clear(),this.messages=[],this.userData=void 0}on(e,t){return this.eventHandlers.has(e)||this.eventHandlers.set(e,new Set),this.eventHandlers.get(e).add(t),()=>this.off(e,t)}off(e,t){var s;null==(s=this.eventHandlers.get(e))||s.delete(t)}emit(e,...t){var s;this.destroyed||null==(s=this.eventHandlers.get(e))||s.forEach(e=>{e(...t)})}isPreChatCompleted(){return this.storage.isPreChatCompleted(this.conversationId)}setPreChatCompleted(e){this.storage.setPreChatCompleted(this.conversationId,e)}showPreChatForm(){const e=this.config.preChatForm;this.panel.hideMessages(),this.panel.input.setVisible(!1),this.preChatFormEl=new O(this.panel.messagesContainer,{title:e.title??this.locale.preChatTitle,subtitle:e.subtitle??this.locale.preChatSubtitle,fields:e.fields,submitLabel:e.submitLabel??this.locale.preChatSubmit,locale:this.locale,onSubmit:e=>this.handlePreChatSubmit(e)})}handlePreChatSubmit(e){var t,s,a,i;(null==(t=this.config.preChatForm)?void 0:t.enabled)&&(this.userData=e,this.setPreChatCompleted(e),null==(s=this.preChatFormEl)||s.destroy(),this.preChatFormEl=void 0,this.panel.showMessages(),this.panel.input.setVisible(!0),this.showChatView(),null==(i=(a=this.config).onPreChatSubmit)||i.call(a,e),this.emit("preChatSubmit",e),e.message&&this.handleSend(e.message))}showChatView(){var e;if(0===this.messages.length){const t=null==(e=this.userData)?void 0:e.name,s=this.locale.greetingWithName.replace("{name}",()=>t),a={id:"welcome",role:"assistant",content:t?`${s} ${this.config.welcomeMessage??this.locale.welcomeMessage}`:this.config.welcomeMessage??this.locale.welcomeMessage};this.messages.push(a),this.panel.addMessage(a)}}async handleSend(e){var t,s;if(this.isStreaming)return;const a={id:crypto.randomUUID(),role:"user",content:e};this.messages.push(a),this.panel.addMessage(a),null==(s=(t=this.config).onMessage)||s.call(t,a),this.emit("message",a),await this.sendToServer(e,{userMessageId:a.id})}async handleRetry(e){if(this.isStreaming)return;const t=this.messages.findIndex(t=>t.id===e);if(-1===t)return;const s=this.retryRequests.get(e);let a=(null==s?void 0:s.userMessageId)?this.messages.find(e=>e.id===s.userMessageId):void 0;if(!a)for(let i=t-1;i>=0;i--)if("user"===this.messages[i].role){a=this.messages[i];break}a&&(this.panel.messages.removeMessage(e),this.retryRequests.delete(e),this.messages=this.messages.filter(t=>t.id!==e),await this.sendToServer(a.content,{regenerate:null==s?void 0:s.regenerate,userMessageId:(null==s?void 0:s.userMessageId)??a.id}))}async handleRegenerate(e){if(this.isStreaming)return;const t=this.messages.findIndex(t=>t.id===e);if(-1===t)return;if("assistant"!==this.messages[t].role)return;const s=this.findUserMessageForAssistant(t);s&&(this.panel.messages.clearRegenerateButtons(),this.panel.messages.removeMessage(e),this.retryRequests.delete(e),this.messages=this.messages.filter(t=>t.id!==e),await this.sendToServer(s.content,{regenerate:!this.v1||{assistantMessageId:e},userMessageId:s.id}))}async sendToServer(e,t={}){var s,a,i,n,r,o,c,l,d;if(this.isStreaming)return;this.isStreaming=!0,this.panel.input.setDisabled(!0),this.panel.messages.clearRegenerateButtons(),this.panel.messages.showTyping();const h={id:crypto.randomUUID(),role:"assistant",content:"",status:"streaming"};let p=!0,u=!1,m=!1;const g=new AbortController;this.abortController=g;try{for await(const r of this.client.sendMessage(this.createRequest(e,t),{signal:g.signal})){if(this.destroyed)break;if(r.error){const e=this.resolveErrorType(r.error);this.markFailed(h,this.getErrorMessage(e,r.retryAfterMs)),h.errorType=e,m=!0,this.retryRequests.set(h.id,{regenerate:t.regenerate,userMessageId:t.userMessageId}),this.panel.messages.removeTyping(),p?this.panel.addMessage(h):this.panel.messages.updateMessage(h),this.messages.push(h);const i=new Error(r.error);null==(a=(s=this.config).onError)||a.call(s,i),this.emit("error",i);break}if(r.done){u=!0;break}r.conversationId&&(this.conversationId=r.conversationId),r.messageId&&(h.id=r.messageId,this.v1=!0),r.leadCaptured&&(null==(n=(i=this.config).onLeadCaptured)||n.call(i,r.leadData),this.emit("leadCaptured",r.leadData)),r.content&&(p&&(this.panel.messages.removeTyping(),this.panel.addMessage(h),p=!1),h.content+=r.content,this.panel.messages.updateMessage(h))}if(this.destroyed)return;m||u||(u=!0),!m&&p&&this.panel.messages.removeTyping(),!m&&h.content&&(h.status="complete",this.panel.messages.updateMessage(h),this.messages.push(h),null==(o=(r=this.config).onMessage)||o.call(r,h),this.emit("message",h),this.showLatestRegenerateButton(),this.isInline||this.panel.isVisible||null==(c=this.fab)||c.showBadge())}catch(b){if(this.destroyed)return;this.markFailed(h,this.locale.errorGeneric),h.errorType="network",this.retryRequests.set(h.id,{regenerate:t.regenerate,userMessageId:t.userMessageId}),this.panel.messages.removeTyping(),p?this.panel.addMessage(h):this.panel.messages.updateMessage(h),this.messages.push(h);const e=b instanceof Error?b:new Error(String(b));null==(d=(l=this.config).onError)||d.call(l,e),this.emit("error",e)}finally{this.abortController===g&&(this.abortController=void 0),this.destroyed||(this.isStreaming=!1,this.panel.input.setDisabled(!1),this.panel.input.focus(),this.saveHistory())}}createRequest(e,t){var s;const a=!1!==this.config.pageContext?{url:window.location.href,title:document.title}:void 0,i=Boolean((null==(s=this.config.preChatForm)?void 0:s.enabled)&&this.userData&&!this.v1);return{conversationId:this.conversationId,message:e,messageId:t.userMessageId,regenerate:t.regenerate,pageContext:a,locale:this.config.locale,...i?{userData:this.userData}:{}}}findUserMessageForAssistant(e){for(let t=e-1;t>=0;t--)if("user"===this.messages[t].role)return this.messages[t]}findLatestRegeneratableAssistant(){for(let e=this.messages.length-1;e>=0;e--){const t=this.messages[e];if("welcome"!==t.id){if("assistant"!==t.role||"error"===t.status)return;return t}}}showLatestRegenerateButton(){const e=this.findLatestRegeneratableAssistant();e?this.panel.messages.showRegenerateButton(e.id):this.panel.messages.clearRegenerateButtons()}resolveErrorType(e){return e in F||"rate_limit"===e?e:"provider_error"}markFailed(e,t){e.status="error",e.content.trim()?e.errorText=t:e.content=t}getErrorMessage(e,t){return"rate_limit"===e?t?this.locale.errorRateLimitWait.replace("{seconds}",String(Math.ceil(t/1e3))):this.locale.errorRateLimit:this.locale[F[e]??"errorGeneric"]}saveHistory(){if(!1===this.config.persistHistory)return;const e=this.config.maxMessages??50,t=this.messages.filter(e=>"welcome"!==e.id).slice(-e);this.storage.save({id:this.conversationId,messages:t.map(e=>({id:e.id,role:e.role,content:e.content,status:e.status,errorType:e.errorType,timestamp:Date.now()})),updatedAt:Date.now()})}}let q=null;const U=new Map;function V(e){if(void 0!==e)return""===e||"true"===e||"false"!==e&&(/^\d+$/.test(e)?Number(e):void 0)}const j={init(e){q&&q.destroy(),q=new _(e);for(const[t,s]of U)for(const e of s)q.on(t,e);return q.init(),q},open(){null==q||q.open()},close(){null==q||q.close()},destroy(){null==q||q.destroy(),q=null},on(e,t){let s=U.get(e);return s||(s=new Set,U.set(e,s)),s.add(t),null==q||q.on(e,t),()=>{j.off(e,t)}},off(e,t){var s;null==(s=U.get(e))||s.delete(t),null==q||q.off(e,t)}};function K(e){if(!e)return;const t=e.dataset.apiUrl;if(!t)return;const s=e.dataset.mode,a=e.dataset.container;j.init({apiUrl:t,turnstileSiteKey:e.dataset.turnstileSiteKey,mode:s||void 0,container:a||void 0,theme:{accent:e.dataset.accent,textColor:e.dataset.textColor,bgColor:e.dataset.bgColor,fontFamily:e.dataset.fontFamily,borderRadius:e.dataset.borderRadius,position:e.dataset.position||void 0},branding:{name:e.dataset.brandName,avatar:e.dataset.brandAvatar,subtitle:e.dataset.brandSubtitle},welcomeMessage:e.dataset.welcomeMessage,welcomeBubble:e.dataset.welcomeBubble?{text:e.dataset.welcomeBubble,delay:e.dataset.welcomeBubbleDelay?parseInt(e.dataset.welcomeBubbleDelay,10):void 0}:void 0,autoOpen:V(e.dataset.autoOpen),placeholder:e.dataset.placeholder,locale:e.dataset.locale})}const J="undefined"!=typeof document?document.currentScript:null;return J&&J.dataset.apiUrl&&("loading"===document.readyState?document.addEventListener("DOMContentLoaded",()=>K(J),{once:!0}):K(J)),"undefined"!=typeof window&&(window.ChatCops=j),e.Widget=_,e.default=j,e.parseAutoOpen=V,Object.defineProperties(e,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}}),e}({});"undefined"!=typeof window&&window.ChatCops&&window.ChatCops.default&&Object.assign(window.ChatCops,window.ChatCops.default);
package/dist/dom/fab.d.ts CHANGED
@@ -7,7 +7,6 @@ export interface FABOptions {
7
7
  export declare class FAB {
8
8
  private el;
9
9
  private badge;
10
- private isOpen;
11
10
  private openLabel;
12
11
  private closeLabel;
13
12
  constructor(root: ShadowRoot, options: FABOptions);
@@ -1 +1 @@
1
- {"version":3,"file":"fab.d.ts","sourceRoot":"","sources":["../../src/dom/fab.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,cAAc,GAAG,aAAa,CAAC;IACzC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,qBAAa,GAAG;IACd,OAAO,CAAC,EAAE,CAAoB;IAC9B,OAAO,CAAC,KAAK,CAAiB;IAC9B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,UAAU,CAAS;gBAEf,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU;IA0BjD,OAAO,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI;IAS5B,KAAK,IAAI,IAAI;IAIb,SAAS,IAAI,IAAI;IAIjB,SAAS,IAAI,IAAI;IAIjB,OAAO,IAAI,IAAI;CAGhB"}
1
+ {"version":3,"file":"fab.d.ts","sourceRoot":"","sources":["../../src/dom/fab.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,cAAc,GAAG,aAAa,CAAC;IACzC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,qBAAa,GAAG;IACd,OAAO,CAAC,EAAE,CAAoB;IAC9B,OAAO,CAAC,KAAK,CAAiB;IAC9B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,UAAU,CAAS;gBAEf,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU;IA0BjD,OAAO,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI;IAQ5B,KAAK,IAAI,IAAI;IAIb,SAAS,IAAI,IAAI;IAIjB,SAAS,IAAI,IAAI;IAIjB,OAAO,IAAI,IAAI;CAGhB"}
@@ -1,5 +1,5 @@
1
1
  export type MessageStatus = 'streaming' | 'complete' | 'error';
2
- export type MessageErrorType = 'rate_limit' | 'network' | 'provider_error' | 'timeout';
2
+ export type MessageErrorType = 'rate_limit' | 'network' | 'provider_error' | 'timeout' | 'budget' | 'budget_daily' | 'unavailable' | 'cut_off';
3
3
  export interface MessageData {
4
4
  id: string;
5
5
  role: 'user' | 'assistant';
@@ -1 +1 @@
1
- {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../src/dom/messages.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,aAAa,GAAG,WAAW,GAAG,UAAU,GAAG,OAAO,CAAC;AAC/D,MAAM,MAAM,gBAAgB,GAAG,YAAY,GAAG,SAAS,GAAG,gBAAgB,GAAG,SAAS,CAAC;AAEvF,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAC7B,oFAAoF;IACpF,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,YAAY,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,qBAAa,QAAQ;IACnB,OAAO,CAAC,SAAS,CAAiB;IAClC,OAAO,CAAC,QAAQ,CAA+B;IAC/C,OAAO,CAAC,OAAO,CAAC,CAAiB;gBAErB,MAAM,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,cAAc;IASzD,UAAU,CAAC,GAAG,EAAE,WAAW,GAAG,cAAc;IAQ5C,aAAa,CAAC,GAAG,EAAE,WAAW,GAAG,IAAI;IAQrC,UAAU,IAAI,IAAI;IASlB,YAAY,IAAI,IAAI;IAOpB,KAAK,IAAI,IAAI;IAKb,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAK/B,sBAAsB,IAAI,IAAI;IAK9B,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAiB7C,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAIlC,OAAO,CAAC,WAAW;IAKnB,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,oBAAoB;IAM5B,OAAO,CAAC,oBAAoB;IA0C5B,OAAO,CAAC,sBAAsB;IAgB9B,OAAO,CAAC,sBAAsB;IAY9B,OAAO,CAAC,4BAA4B;IAQpC,OAAO,CAAC,kBAAkB;IAc1B,OAAO,CAAC,UAAU;CAKnB"}
1
+ {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../src/dom/messages.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,aAAa,GAAG,WAAW,GAAG,UAAU,GAAG,OAAO,CAAC;AAC/D,MAAM,MAAM,gBAAgB,GAAG,YAAY,GAAG,SAAS,GAAG,gBAAgB,GAAG,SAAS,GAAG,QAAQ,GAAG,cAAc,GAAG,aAAa,GAAG,SAAS,CAAC;AAE/I,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAC7B,oFAAoF;IACpF,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,YAAY,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,qBAAa,QAAQ;IACnB,OAAO,CAAC,SAAS,CAAiB;IAClC,OAAO,CAAC,QAAQ,CAA+B;IAC/C,OAAO,CAAC,OAAO,CAAC,CAAiB;gBAErB,MAAM,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,cAAc;IASzD,UAAU,CAAC,GAAG,EAAE,WAAW,GAAG,cAAc;IAQ5C,aAAa,CAAC,GAAG,EAAE,WAAW,GAAG,IAAI;IAQrC,UAAU,IAAI,IAAI;IASlB,YAAY,IAAI,IAAI;IAOpB,KAAK,IAAI,IAAI;IAKb,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAK/B,sBAAsB,IAAI,IAAI;IAO9B,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAiB7C,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAIlC,OAAO,CAAC,WAAW;IAKnB,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,oBAAoB;IAM5B,OAAO,CAAC,oBAAoB;IA6C5B,OAAO,CAAC,sBAAsB;IAgB9B,OAAO,CAAC,sBAAsB;IAY9B,OAAO,CAAC,4BAA4B;IAQpC,OAAO,CAAC,kBAAkB;IAc1B,OAAO,CAAC,UAAU;CAKnB"}
@@ -1 +1 @@
1
- {"version":3,"file":"prechat-form.d.ts","sourceRoot":"","sources":["../../src/dom/prechat-form.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAKtD,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,mBAAmB,CAAC;IAC5B,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,IAAI,CAAC;CAClD;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,SAAS,CAAiB;IAClC,OAAO,CAAC,aAAa,CAAiF;IACtG,OAAO,CAAC,aAAa,CAAqC;IAC1D,OAAO,CAAC,SAAS,CAAqB;IACtC,OAAO,CAAC,OAAO,CAAqB;gBAExB,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,kBAAkB;IAgD5D,OAAO,CAAC,WAAW;IAiFnB,OAAO,CAAC,iBAAiB;IASzB,OAAO,CAAC,YAAY;IA4BpB,OAAO,CAAC,SAAS;IAUjB,OAAO,CAAC,UAAU;IAclB,OAAO,CAAC,YAAY;IAIpB,OAAO,IAAI,IAAI;CAKhB"}
1
+ {"version":3,"file":"prechat-form.d.ts","sourceRoot":"","sources":["../../src/dom/prechat-form.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAKtD,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,mBAAmB,CAAC;IAC5B,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,IAAI,CAAC;CAClD;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,SAAS,CAAiB;IAClC,OAAO,CAAC,aAAa,CAAiF;IACtG,OAAO,CAAC,aAAa,CAAqC;IAC1D,OAAO,CAAC,SAAS,CAAqB;IACtC,OAAO,CAAC,OAAO,CAAqB;gBAExB,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,kBAAkB;IAgD5D,OAAO,CAAC,WAAW;IAiFnB,OAAO,CAAC,iBAAiB;IASzB,OAAO,CAAC,YAAY;IA2BpB,OAAO,CAAC,SAAS;IAUjB,OAAO,CAAC,UAAU;IAclB,OAAO,CAAC,YAAY;IAIpB,OAAO,IAAI,IAAI;CAKhB"}
package/dist/i18n.d.ts CHANGED
@@ -12,6 +12,12 @@ export interface WidgetLocaleStrings {
12
12
  errorGeneric: string;
13
13
  errorNetwork: string;
14
14
  errorRateLimit: string;
15
+ /** `{seconds}` is how long to wait. */
16
+ errorRateLimitWait: string;
17
+ errorBudget: string;
18
+ errorBudgetDaily: string;
19
+ errorUnavailable: string;
20
+ errorCutOff: string;
15
21
  typingIndicator: string;
16
22
  poweredBy: string;
17
23
  newConversation: string;
@@ -1 +1 @@
1
- {"version":3,"file":"i18n.d.ts","sourceRoot":"","sources":["../src/i18n.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,mBAAmB;IAClC,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,EAAE,MAAM,CAAC;IACzB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AA+BD,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,OAAO,CAAC,mBAAmB,CAAC,GAAG,mBAAmB,CAG3G;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,mBAAmB,GAAG,IAAI,CAErF"}
1
+ {"version":3,"file":"i18n.d.ts","sourceRoot":"","sources":["../src/i18n.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,mBAAmB;IAClC,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,EAAE,MAAM,CAAC;IACzB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,uCAAuC;IACvC,kBAAkB,EAAE,MAAM,CAAC;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;IACzB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAoCD,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,OAAO,CAAC,mBAAmB,CAAC,GAAG,mBAAmB,CAG3G;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,mBAAmB,GAAG,IAAI,CAErF"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,MAAM,EACN,KAAK,YAAY,EACjB,KAAK,eAAe,EACpB,KAAK,kBAAkB,EACxB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,MAAM,EACN,KAAK,YAAY,EACjB,KAAK,eAAe,EACpB,KAAK,kBAAkB,GACxB,MAAM,aAAa,CAAC;AAKrB,wBAAgB,aAAa,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,SAAS,CAM1E;AAED,QAAA,MAAM,QAAQ;iBACC,YAAY,GAAG,MAAM;YAc1B,IAAI;aAIH,IAAI;eAIF,IAAI;cAKL,eAAe,WAAW,kBAAkB,GAAG,MAAM,IAAI;eAaxD,eAAe,WAAW,kBAAkB,GAAG,IAAI;CAI/D,CAAC;AAyDF,eAAe,QAAQ,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,MAAM,EACN,KAAK,YAAY,EACjB,KAAK,eAAe,EACpB,KAAK,kBAAkB,EACxB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,MAAM,EACN,KAAK,YAAY,EACjB,KAAK,eAAe,EACpB,KAAK,kBAAkB,GACxB,MAAM,aAAa,CAAC;AAKrB,wBAAgB,aAAa,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,SAAS,CAM1E;AAED,QAAA,MAAM,QAAQ;iBACC,YAAY,GAAG,MAAM;YAc1B,IAAI;aAIH,IAAI;eAIF,IAAI;cAKL,eAAe,WAAW,kBAAkB,GAAG,MAAM,IAAI;eAaxD,eAAe,WAAW,kBAAkB,GAAG,IAAI;CAI/D,CAAC;AA0DF,eAAe,QAAQ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../src/markdown.ts"],"names":[],"mappings":"AA+BA,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAqEpD"}
1
+ {"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../src/markdown.ts"],"names":[],"mappings":"AAgCA,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAqEpD"}
@@ -1 +1 @@
1
- {"version":3,"file":"namespace.d.ts","sourceRoot":"","sources":["../src/namespace.ts"],"names":[],"mappings":"AAkBA,MAAM,WAAW,gBAAgB;IAC/B,6EAA6E;IAC7E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,IAAI,IAAI,CAAC;CACjB;AAYD,wBAAgB,cAAc,CAC5B,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,IAAI,EAAE,OAAO,GAAG,QAAQ,EACxB,MAAM,EAAE,MAAM,OAAO,GACpB,gBAAgB,CAuBlB"}
1
+ {"version":3,"file":"namespace.d.ts","sourceRoot":"","sources":["../src/namespace.ts"],"names":[],"mappings":"AAmBA,MAAM,WAAW,gBAAgB;IAC/B,6EAA6E;IAC7E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,IAAI,IAAI,CAAC;CACjB;AAYD,wBAAgB,cAAc,CAC5B,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,IAAI,EAAE,OAAO,GAAG,QAAQ,EACxB,MAAM,EAAE,MAAM,OAAO,GACpB,gBAAgB,CAuBlB"}
package/dist/storage.d.ts CHANGED
@@ -5,7 +5,7 @@ interface StoredConversation {
5
5
  role: 'user' | 'assistant';
6
6
  content: string;
7
7
  status?: 'streaming' | 'complete' | 'error';
8
- errorType?: 'rate_limit' | 'network' | 'provider_error' | 'timeout';
8
+ errorType?: import('./dom/messages.js').MessageErrorType;
9
9
  timestamp: number;
10
10
  }>;
11
11
  updatedAt: number;
@@ -1 +1 @@
1
- {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"AAAA,UAAU,kBAAkB;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,KAAK,CAAC;QACd,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;QAC3B,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,CAAC,EAAE,WAAW,GAAG,UAAU,GAAG,OAAO,CAAC;QAC5C,SAAS,CAAC,EAAE,YAAY,GAAG,SAAS,GAAG,gBAAgB,GAAG,SAAS,CAAC;QACpE,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC,CAAC;IACH,SAAS,EAAE,MAAM,CAAC;CACnB;AAKD,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,GAAG,CAAS;IACpB,OAAO,CAAC,UAAU,CAAS;IAE3B,yEAAyE;gBAC7D,MAAM,CAAC,EAAE,MAAM;IAK3B,IAAI,IAAI,kBAAkB,GAAG,IAAI;IAUjC,IAAI,CAAC,YAAY,EAAE,kBAAkB,GAAG,IAAI;IAc5C,KAAK,IAAI,IAAI;IAQb,YAAY,IAAI,MAAM;IAatB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAQ9C,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI;IAW3E,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI;IAchE,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI;CAOtE"}
1
+ {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"AAAA,UAAU,kBAAkB;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,KAAK,CAAC;QACd,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;QAC3B,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,CAAC,EAAE,WAAW,GAAG,UAAU,GAAG,OAAO,CAAC;QAC5C,SAAS,CAAC,EAAE,OAAO,mBAAmB,EAAE,gBAAgB,CAAC;QACzD,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC,CAAC;IACH,SAAS,EAAE,MAAM,CAAC;CACnB;AAKD,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,GAAG,CAAS;IACpB,OAAO,CAAC,UAAU,CAAS;IAE3B,yEAAyE;gBAC7D,MAAM,CAAC,EAAE,MAAM;IAK3B,IAAI,IAAI,kBAAkB,GAAG,IAAI;IA8CjC,IAAI,CAAC,YAAY,EAAE,kBAAkB,GAAG,IAAI;IAc5C,KAAK,IAAI,IAAI;IAQb,YAAY,IAAI,MAAM;IAatB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAQ9C,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI;IAW3E,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI;IAchE,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI;CAOtE"}
package/dist/widget.d.ts CHANGED
@@ -19,6 +19,11 @@ export interface WidgetConfig {
19
19
  apiUrl: string;
20
20
  /** Request/stream inactivity timeout in milliseconds. Defaults to 30000. */
21
21
  timeout?: number;
22
+ /**
23
+ * Your Cloudflare Turnstile site key, when the server has `turnstile` set.
24
+ * Cloudflare's script loads only when the widget first needs a session.
25
+ */
26
+ turnstileSiteKey?: string;
22
27
  mode?: 'popup' | 'inline';
23
28
  /**
24
29
  * Names this widget's saved conversation. Set a different one on each widget
@@ -79,6 +84,8 @@ export declare class Widget {
79
84
  private messages;
80
85
  private userData?;
81
86
  private isStreaming;
87
+ /** Set once the server answers in protocol v1 (0.6 and later). */
88
+ private v1;
82
89
  private destroyed;
83
90
  private abortController?;
84
91
  private retryRequests;
@@ -1 +1 @@
1
- {"version":3,"file":"widget.d.ts","sourceRoot":"","sources":["../src/widget.ts"],"names":[],"mappings":"AAQA,OAAO,EAAmB,KAAK,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAGtE,OAAO,KAAK,EAAE,WAAW,EAAoB,MAAM,mBAAmB,CAAC;AAEvE,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,UAAU,CAAC;IAC/C,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,4EAA4E;IAC5E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;IAC1B;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,GAAG,WAAW,CAAC;IACjC,KAAK,CAAC,EAAE;QACN,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;QAC/B,QAAQ,CAAC,EAAE,cAAc,GAAG,aAAa,CAAC;KAC3C,CAAC;IACF,QAAQ,CAAC,EAAE;QACT,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC;IACF,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE;QACd,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,QAAQ,CAAC,EAAE,OAAO,CAAC;KACpB,CAAC;IACF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC,mBAAmB,CAAC,CAAC;IACvC,WAAW,CAAC,EAAE,iBAAiB,CAAC;IAChC,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,IAAI,CAAC;IAC3C,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACjC,cAAc,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;IAC9D,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,IAAI,CAAC;CAC1D;AAED,MAAM,MAAM,eAAe,GACvB,MAAM,GACN,OAAO,GACP,SAAS,GACT,OAAO,GACP,cAAc,GACd,eAAe,CAAC;AACpB,MAAM,MAAM,kBAAkB,GAAG,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;AAM9D,qBAAa,MAAM;IACjB,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,GAAG,CAAC,CAAM;IAClB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,MAAM,CAAC,CAAgB;IAC/B,OAAO,CAAC,aAAa,CAAC,CAAc;IACpC,OAAO,CAAC,MAAM,CAAa;IAC3B,OAAO,CAAC,OAAO,CAAsB;IACrC,OAAO,CAAC,SAAS,CAAmB;IACpC,OAAO,CAAC,MAAM,CAAsB;IACpC,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAqB;IACrC,OAAO,CAAC,QAAQ,CAAC,CAAyB;IAC1C,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,eAAe,CAAC,CAAkB;IAC1C,OAAO,CAAC,aAAa,CAAyC;IAC9D,OAAO,CAAC,aAAa,CAAuD;IAC5E,OAAO,CAAC,WAAW,CAAC,CAAc;IAClC,OAAO,CAAC,aAAa,CAAC,CAAgC;IAEtD,IAAI,QAAQ,IAAI,OAAO,CAEtB;gBAEW,MAAM,EAAE,YAAY;IAahC,OAAO,CAAC,gBAAgB;IAcxB,IAAI,IAAI,IAAI;IA6GZ,IAAI,IAAI,IAAI;IAWZ,KAAK,IAAI,IAAI;IAWb,MAAM,IAAI,IAAI;IAQd,OAAO,IAAI,IAAI;IAgBf,EAAE,CAAC,KAAK,EAAE,eAAe,EAAE,OAAO,EAAE,kBAAkB,GAAG,MAAM,IAAI;IAQnE,GAAG,CAAC,KAAK,EAAE,eAAe,EAAE,OAAO,EAAE,kBAAkB,GAAG,IAAI;IAI9D,OAAO,CAAC,IAAI;IAKZ,OAAO,CAAC,kBAAkB;IAI1B,OAAO,CAAC,mBAAmB;IAI3B,OAAO,CAAC,eAAe;IAevB,OAAO,CAAC,mBAAmB;IAqB3B,OAAO,CAAC,YAAY;YAiBN,UAAU;YAgBV,WAAW;YAgCX,gBAAgB;YAuBhB,YAAY;IAuI1B,OAAO,CAAC,aAAa;IAqBrB,OAAO,CAAC,2BAA2B;IAUnC,OAAO,CAAC,gCAAgC;IAiBxC,OAAO,CAAC,0BAA0B;IASlC,OAAO,CAAC,gBAAgB;IAYxB;;;OAGG;IACH,OAAO,CAAC,UAAU;IASlB,OAAO,CAAC,eAAe;IAYvB,OAAO,CAAC,WAAW;CAmBpB"}
1
+ {"version":3,"file":"widget.d.ts","sourceRoot":"","sources":["../src/widget.ts"],"names":[],"mappings":"AAQA,OAAO,EAAmB,KAAK,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAGtE,OAAO,KAAK,EAAE,WAAW,EAAoB,MAAM,mBAAmB,CAAC;AAavE,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,UAAU,CAAC;IAC/C,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,4EAA4E;IAC5E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,IAAI,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;IAC1B;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,GAAG,WAAW,CAAC;IACjC,KAAK,CAAC,EAAE;QACN,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;QAC/B,QAAQ,CAAC,EAAE,cAAc,GAAG,aAAa,CAAC;KAC3C,CAAC;IACF,QAAQ,CAAC,EAAE;QACT,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC;IACF,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE;QACd,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,QAAQ,CAAC,EAAE,OAAO,CAAC;KACpB,CAAC;IACF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC,mBAAmB,CAAC,CAAC;IACvC,WAAW,CAAC,EAAE,iBAAiB,CAAC;IAChC,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,IAAI,CAAC;IAC3C,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACjC,cAAc,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;IAC9D,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,IAAI,CAAC;CAC1D;AAED,MAAM,MAAM,eAAe,GACvB,MAAM,GACN,OAAO,GACP,SAAS,GACT,OAAO,GACP,cAAc,GACd,eAAe,CAAC;AACpB,MAAM,MAAM,kBAAkB,GAAG,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;AAM9D,qBAAa,MAAM;IACjB,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,GAAG,CAAC,CAAM;IAClB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,MAAM,CAAC,CAAgB;IAC/B,OAAO,CAAC,aAAa,CAAC,CAAc;IACpC,OAAO,CAAC,MAAM,CAAa;IAC3B,OAAO,CAAC,OAAO,CAAsB;IACrC,OAAO,CAAC,SAAS,CAAmB;IACpC,OAAO,CAAC,MAAM,CAAsB;IACpC,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAqB;IACrC,OAAO,CAAC,QAAQ,CAAC,CAAyB;IAC1C,OAAO,CAAC,WAAW,CAAS;IAC5B,kEAAkE;IAClE,OAAO,CAAC,EAAE,CAAS;IACnB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,eAAe,CAAC,CAAkB;IAC1C,OAAO,CAAC,aAAa,CAAyC;IAC9D,OAAO,CAAC,aAAa,CAAuD;IAC5E,OAAO,CAAC,WAAW,CAAC,CAAc;IAClC,OAAO,CAAC,aAAa,CAAC,CAAgC;IAEtD,IAAI,QAAQ,IAAI,OAAO,CAEtB;gBAEW,MAAM,EAAE,YAAY;IAahC,OAAO,CAAC,gBAAgB;IAcxB,IAAI,IAAI,IAAI;IA6GZ,IAAI,IAAI,IAAI;IAWZ,KAAK,IAAI,IAAI;IAWb,MAAM,IAAI,IAAI;IAQd,OAAO,IAAI,IAAI;IAgBf,EAAE,CAAC,KAAK,EAAE,eAAe,EAAE,OAAO,EAAE,kBAAkB,GAAG,MAAM,IAAI;IAQnE,GAAG,CAAC,KAAK,EAAE,eAAe,EAAE,OAAO,EAAE,kBAAkB,GAAG,IAAI;IAI9D,OAAO,CAAC,IAAI;IAOZ,OAAO,CAAC,kBAAkB;IAI1B,OAAO,CAAC,mBAAmB;IAI3B,OAAO,CAAC,eAAe;IAevB,OAAO,CAAC,mBAAmB;IAqB3B,OAAO,CAAC,YAAY;YAiBN,UAAU;YAgBV,WAAW;YAgCX,gBAAgB;YAwBhB,YAAY;IA+I1B,OAAO,CAAC,aAAa;IAsBrB,OAAO,CAAC,2BAA2B;IAUnC,OAAO,CAAC,gCAAgC;IAiBxC,OAAO,CAAC,0BAA0B;IASlC,OAAO,CAAC,gBAAgB;IAIxB;;;OAGG;IACH,OAAO,CAAC,UAAU;IASlB,OAAO,CAAC,eAAe;IASvB,OAAO,CAAC,WAAW;CAmBpB"}
package/package.json CHANGED
@@ -1,7 +1,18 @@
1
1
  {
2
2
  "name": "@chatcops/widget",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "description": "Embeddable AI chatbot widget - zero dependencies, Shadow DOM isolated",
5
+ "keywords": [
6
+ "chatcops",
7
+ "ai",
8
+ "chatbot",
9
+ "chat-widget",
10
+ "embeddable",
11
+ "shadow-dom",
12
+ "customer-support"
13
+ ],
14
+ "homepage": "https://chat.codercops.com",
15
+ "bugs": "https://github.com/codercops/chatcops/issues",
5
16
  "type": "module",
6
17
  "main": "dist/chatcops.min.js",
7
18
  "module": "dist/chatcops.esm.js",
@@ -9,32 +20,35 @@
9
20
  "exports": {
10
21
  ".": {
11
22
  "types": "./dist/index.d.ts",
12
- "import": "./dist/chatcops.esm.js",
13
- "require": "./dist/chatcops.min.js"
23
+ "import": "./dist/chatcops.esm.js"
14
24
  }
15
25
  },
16
26
  "files": [
17
27
  "dist"
18
28
  ],
19
29
  "devDependencies": {
30
+ "happy-dom": "^20.14.5",
31
+ "terser": "^5.37.0",
20
32
  "typescript": "^5.7.0",
21
33
  "vite": "^6.4.3",
22
- "terser": "^5.37.0",
23
34
  "vitest": "^4.1.11",
24
- "happy-dom": "^20.14.5"
35
+ "@chatcops/core": "^0.5.0"
25
36
  },
26
37
  "repository": {
27
38
  "type": "git",
28
- "url": "https://github.com/codercops/chatcops",
39
+ "url": "git+https://github.com/codercops/chatcops.git",
29
40
  "directory": "packages/widget"
30
41
  },
31
42
  "publishConfig": {
32
43
  "access": "public"
33
44
  },
34
45
  "license": "MIT",
46
+ "engines": {
47
+ "node": ">=22"
48
+ },
35
49
  "scripts": {
36
50
  "dev": "vite build --watch",
37
- "build": "vite build && tsc --emitDeclarationOnly",
51
+ "build": "vite build && rm -f tsconfig.tsbuildinfo && tsc --emitDeclarationOnly",
38
52
  "typecheck": "tsc --noEmit",
39
53
  "test": "vitest run",
40
54
  "test:watch": "vitest",