claudius-chat-widget 1.6.0 → 1.9.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.
Files changed (39) hide show
  1. package/dist/claudius.cjs +2 -2
  2. package/dist/claudius.iife.js +11 -11
  3. package/dist/claudius.js +871 -608
  4. package/dist/index.d.cts +676 -0
  5. package/dist/index.d.ts +676 -12
  6. package/package.json +20 -7
  7. package/dist/api/client.d.ts +0 -24
  8. package/dist/api/errors.d.ts +0 -9
  9. package/dist/api/index.d.ts +0 -4
  10. package/dist/api/types.d.ts +0 -22
  11. package/dist/components/ChatInput.d.ts +0 -9
  12. package/dist/components/ChatMessage.d.ts +0 -10
  13. package/dist/components/ChatSources.d.ts +0 -7
  14. package/dist/components/ChatToggleButton.d.ts +0 -10
  15. package/dist/components/ChatWidget.d.ts +0 -29
  16. package/dist/components/ChatWindow.d.ts +0 -21
  17. package/dist/components/GreetingBubble.d.ts +0 -10
  18. package/dist/components/SourceIcon.d.ts +0 -7
  19. package/dist/embed.d.ts +0 -38
  20. package/dist/hooks/useChat.d.ts +0 -20
  21. package/dist/hooks/useFocusTrap.d.ts +0 -2
  22. package/dist/hooks/useMediaQuery.d.ts +0 -1
  23. package/dist/hooks/useSwipeToDismiss.d.ts +0 -4
  24. package/dist/hooks/useTriggers.d.ts +0 -32
  25. package/dist/i18n.d.ts +0 -21
  26. package/dist/locales/de.d.ts +0 -2
  27. package/dist/locales/en.d.ts +0 -2
  28. package/dist/locales/es.d.ts +0 -2
  29. package/dist/locales/fr.d.ts +0 -2
  30. package/dist/locales/index.d.ts +0 -9
  31. package/dist/main.d.ts +0 -1
  32. package/dist/test-utils/MockChatApiClient.d.ts +0 -64
  33. package/dist/theme/index.d.ts +0 -4
  34. package/dist/theme/resolve.d.ts +0 -19
  35. package/dist/theme/themes.d.ts +0 -8
  36. package/dist/theme/types.d.ts +0 -34
  37. package/dist/theme/useTheme.d.ts +0 -14
  38. package/dist/utils/sanitize.d.ts +0 -36
  39. package/dist/utils/stripAnnouncementFormatting.d.ts +0 -1
package/dist/claudius.js CHANGED
@@ -1,49 +1,74 @@
1
- var ye = Object.defineProperty;
2
- var we = (t, e, r) => e in t ? ye(t, e, { enumerable: !0, configurable: !0, writable: !0, value: r }) : t[e] = r;
3
- var $ = (t, e, r) => we(t, typeof e != "symbol" ? e + "" : e, r);
4
- import { jsx as i, jsxs as d, Fragment as ve } from "react/jsx-runtime";
5
- import { useMemo as F, useState as C, useRef as N, useCallback as R, useEffect as k, forwardRef as Ee, memo as K, useId as Re } from "react";
1
+ var Ee = Object.defineProperty;
2
+ var Re = (e, t, r) => t in e ? Ee(e, t, { enumerable: !0, configurable: !0, writable: !0, value: r }) : e[t] = r;
3
+ var G = (e, t, r) => Re(e, typeof t != "symbol" ? t + "" : t, r);
4
+ import { jsx as i, jsxs as h, Fragment as Te } from "react/jsx-runtime";
5
+ import { useMemo as Y, useState as k, useRef as C, useCallback as M, useEffect as H, forwardRef as Me, memo as J, useId as Ce } from "react";
6
6
  class U extends Error {
7
- constructor(e, r, s, n) {
8
- super(e), this.status = r, this.code = s, this.retryAfter = n, this.name = "ChatApiError";
7
+ /**
8
+ * Create a {@link ChatApiError}.
9
+ *
10
+ * @param message - Human-readable error message.
11
+ * @param status - HTTP status code, or `0` for network and timeout failures.
12
+ * @param code - Optional machine-readable error code (e.g. `"TIMEOUT"`, `"NETWORK_ERROR"`).
13
+ * @param retryAfter - Seconds to wait before retrying, from the `Retry-After` header.
14
+ */
15
+ constructor(t, r, s, n) {
16
+ super(t), this.status = r, this.code = s, this.retryAfter = n, this.name = "ChatApiError";
9
17
  }
10
18
  }
11
- class se extends Error {
19
+ class ae extends Error {
20
+ /** Creates a `DebounceError` with a fixed message. */
12
21
  constructor() {
13
22
  super("Request debounced"), this.name = "DebounceError";
14
23
  }
15
24
  }
16
- const Te = 3e4;
17
- class Me {
18
- constructor(e, r) {
19
- $(this, "baseUrl");
20
- $(this, "maxRetries");
21
- $(this, "debounceMs");
22
- $(this, "timeoutMs");
23
- $(this, "lastSendTime", 0);
24
- this.baseUrl = e, this.maxRetries = (r == null ? void 0 : r.maxRetries) ?? 2, this.debounceMs = (r == null ? void 0 : r.debounceMs) ?? 300, this.timeoutMs = (r == null ? void 0 : r.timeoutMs) ?? Te;
25
+ const Ne = 3e4;
26
+ class Se {
27
+ /**
28
+ * Create a chat client for the given Worker base URL.
29
+ *
30
+ * @param baseUrl - Base URL of the Worker. Requests post to `${baseUrl}/api/chat`.
31
+ * @param options - Optional retry, debounce, and timeout settings.
32
+ */
33
+ constructor(t, r) {
34
+ G(this, "baseUrl");
35
+ G(this, "maxRetries");
36
+ G(this, "debounceMs");
37
+ G(this, "timeoutMs");
38
+ G(this, "lastSendTime", 0);
39
+ this.baseUrl = t, this.maxRetries = (r == null ? void 0 : r.maxRetries) ?? 2, this.debounceMs = (r == null ? void 0 : r.debounceMs) ?? 300, this.timeoutMs = (r == null ? void 0 : r.timeoutMs) ?? Ne;
25
40
  }
26
- async sendMessage(e) {
41
+ /**
42
+ * Send the conversation to the chat endpoint and return the assistant's
43
+ * reply, retrying transient failures with backoff up to
44
+ * {@link ChatApiClientOptions.maxRetries} times.
45
+ *
46
+ * @param messages - The full conversation so far, oldest message first.
47
+ * @returns The assistant's reply and any cited sources.
48
+ * @throws {@link DebounceError} when called within the debounce window.
49
+ * @throws {@link ChatApiError} when the request fails after all retries.
50
+ */
51
+ async sendMessage(t) {
27
52
  if (this.debounceMs > 0 && Date.now() - this.lastSendTime < this.debounceMs)
28
- throw new se();
53
+ throw new ae();
29
54
  this.lastSendTime = Date.now();
30
55
  let r;
31
56
  for (let s = 0; s <= this.maxRetries; s++)
32
57
  try {
33
- const n = await this.fetchWithTimeout(e);
58
+ const n = await this.fetchWithTimeout(t);
34
59
  if (n.ok)
35
60
  return await n.json();
36
- const o = await n.json().catch(() => ({})), a = n.headers.get("Retry-After"), l = a ? Number(a) : void 0;
61
+ const o = await n.json().catch(() => ({})), c = n.headers.get("Retry-After"), a = c ? Number(c) : void 0;
37
62
  if (r = new U(
38
63
  o.error ?? `Request failed with status ${n.status}`,
39
64
  n.status,
40
65
  o.code,
41
- l
66
+ a
42
67
  ), !this.isRetryable(n.status))
43
68
  throw r;
44
69
  if (s < this.maxRetries) {
45
- const c = this.getRetryDelay(n, s);
46
- await this.delay(c);
70
+ const u = this.getRetryDelay(n, s);
71
+ await this.delay(u);
47
72
  }
48
73
  } catch (n) {
49
74
  if (n instanceof U) {
@@ -64,19 +89,19 @@ class Me {
64
89
  }
65
90
  throw r;
66
91
  }
67
- async fetchWithTimeout(e) {
92
+ async fetchWithTimeout(t) {
68
93
  if (this.timeoutMs <= 0)
69
94
  return fetch(`${this.baseUrl}/api/chat`, {
70
95
  method: "POST",
71
96
  headers: { "Content-Type": "application/json" },
72
- body: JSON.stringify({ messages: e })
97
+ body: JSON.stringify({ messages: t })
73
98
  });
74
99
  const r = new AbortController(), s = setTimeout(() => r.abort(), this.timeoutMs);
75
100
  try {
76
101
  return await fetch(`${this.baseUrl}/api/chat`, {
77
102
  method: "POST",
78
103
  headers: { "Content-Type": "application/json" },
79
- body: JSON.stringify({ messages: e }),
104
+ body: JSON.stringify({ messages: t }),
80
105
  signal: r.signal
81
106
  });
82
107
  } catch (n) {
@@ -89,12 +114,12 @@ class Me {
89
114
  clearTimeout(s);
90
115
  }
91
116
  }
92
- isRetryable(e, r) {
93
- return r === "TIMEOUT" || r === "NETWORK_ERROR" ? !0 : e === 429 || e === 503;
117
+ isRetryable(t, r) {
118
+ return r === "TIMEOUT" || r === "NETWORK_ERROR" ? !0 : t === 429 || t === 503;
94
119
  }
95
- getRetryDelay(e, r) {
96
- if (e && e.status === 429) {
97
- const s = e.headers.get("Retry-After");
120
+ getRetryDelay(t, r) {
121
+ if (t && t.status === 429) {
122
+ const s = t.headers.get("Retry-After");
98
123
  if (s) {
99
124
  const n = Number(s);
100
125
  return Math.min(n * 1e3, 6e4);
@@ -102,32 +127,96 @@ class Me {
102
127
  }
103
128
  return r === 0 ? 1e3 : 3e3;
104
129
  }
105
- delay(e) {
106
- return new Promise((r) => setTimeout(r, e));
130
+ delay(t) {
131
+ return new Promise((r) => setTimeout(r, t));
107
132
  }
108
133
  }
109
- const Ce = 200, Ne = "claudius:messages";
110
- function Se(t, e) {
134
+ function ue(e) {
135
+ return typeof e == "string" ? { content: e } : e;
136
+ }
137
+ function Q(e, t, r) {
138
+ console.error(`[claudius] plugin "${e.name}" failed in ${t}:`, r);
139
+ }
140
+ async function Le(e, t, r) {
141
+ let s = t;
142
+ for (const n of e) {
143
+ if (!n.onBeforeSend) continue;
144
+ let o = null;
145
+ const c = {
146
+ ...r,
147
+ respondWith(a) {
148
+ o = {
149
+ type: "respond",
150
+ message: s,
151
+ reply: ue(a)
152
+ };
153
+ },
154
+ abort(a) {
155
+ o = { type: "abort", reason: a };
156
+ }
157
+ };
158
+ try {
159
+ const a = await n.onBeforeSend(s, c);
160
+ if (o) return o;
161
+ a && (s = a);
162
+ } catch (a) {
163
+ Q(n, "onBeforeSend", a);
164
+ }
165
+ }
166
+ return { type: "send", message: s };
167
+ }
168
+ async function ke(e, t, r) {
169
+ let s = t;
170
+ for (const n of e)
171
+ if (n.onAfterReceive)
172
+ try {
173
+ const o = await n.onAfterReceive(s, r);
174
+ o && (s = o);
175
+ } catch (o) {
176
+ Q(n, "onAfterReceive", o);
177
+ }
178
+ return s;
179
+ }
180
+ async function Ae(e, t, r) {
181
+ for (const s of e) {
182
+ if (!s.onError) continue;
183
+ let n = null;
184
+ const o = {
185
+ ...r,
186
+ respondWith(c) {
187
+ n = ue(c);
188
+ }
189
+ };
190
+ try {
191
+ if (await s.onError(t, o), n) return n;
192
+ } catch (c) {
193
+ Q(s, "onError", c);
194
+ }
195
+ }
196
+ return null;
197
+ }
198
+ const Oe = 200, Ie = "claudius:messages";
199
+ function De(e, t) {
111
200
  let r;
112
201
  try {
113
- r = new URL(e).host;
202
+ r = new URL(t).host;
114
203
  } catch {
115
- r = e;
204
+ r = t;
116
205
  }
117
- return `${t}:${r}`;
206
+ return `${e}:${r}`;
118
207
  }
119
- function V() {
208
+ function Z() {
120
209
  try {
121
210
  return typeof sessionStorage < "u" ? sessionStorage : null;
122
211
  } catch {
123
212
  return null;
124
213
  }
125
214
  }
126
- function Le(t) {
127
- const e = V();
128
- if (!e) return [];
215
+ function _e(e) {
216
+ const t = Z();
217
+ if (!t) return [];
129
218
  try {
130
- const r = e.getItem(t);
219
+ const r = t.getItem(e);
131
220
  if (!r) return [];
132
221
  const s = JSON.parse(r);
133
222
  return Array.isArray(s) ? s : [];
@@ -135,189 +224,246 @@ function Le(t) {
135
224
  return [];
136
225
  }
137
226
  }
138
- function ke({
139
- apiUrl: t,
140
- persistMessages: e = !0,
141
- storageKeyPrefix: r = Ne,
227
+ function He({
228
+ apiUrl: e,
229
+ persistMessages: t = !0,
230
+ storageKeyPrefix: r = Ie,
142
231
  timeoutMs: s,
143
- translations: n
232
+ translations: n,
233
+ plugins: o
144
234
  }) {
145
- const o = F(
146
- () => new Me(t, { debounceMs: 0, timeoutMs: s }),
147
- [t, s]
148
- ), a = Se(r, t), l = e ? Le(a) : [], [c, u] = C(l), [h, E] = C(!1), [g, x] = C(null), [f, w] = C(!1), v = N(l.length), y = N(!1), T = N(l), O = R(
149
- (m) => {
150
- if (!e) return;
151
- const p = V();
152
- if (p)
235
+ const c = Y(
236
+ () => new Se(e, { debounceMs: 0, timeoutMs: s }),
237
+ [e, s]
238
+ ), a = De(r, e), u = t ? _e(a) : [], [l, d] = k(u), [R, p] = k(!1), [w, y] = k(null), [b, x] = k(!1), v = C(u.length), N = C(!1), E = C(u), I = C(o ?? []);
239
+ I.current = o ?? [];
240
+ const A = M(
241
+ (f) => {
242
+ if (!t) return;
243
+ const g = Z();
244
+ if (g)
153
245
  try {
154
- const H = m.slice(-Ce);
155
- p.setItem(a, JSON.stringify(H));
246
+ const L = f.slice(-Oe);
247
+ g.setItem(a, JSON.stringify(L));
156
248
  } catch {
157
249
  }
158
250
  },
159
- [e, a]
160
- ), A = () => (v.current += 1, `msg-${v.current}`), I = R(
161
- (m, p) => {
251
+ [t, a]
252
+ ), D = () => (v.current += 1, `msg-${v.current}`), S = M(
253
+ (f, g) => {
162
254
  if (!n)
163
- return p ?? "Something went wrong. Please try again.";
164
- switch (m) {
255
+ return g ?? "Something went wrong. Please try again.";
256
+ switch (f) {
165
257
  case "TIMEOUT":
166
258
  return n.errorTimeout;
167
259
  case "NETWORK_ERROR":
168
260
  return n.errorConnection;
169
261
  case "RATE_LIMITED":
170
- return p != null && p.includes("minute") ? n.errorRateLimitMinute : n.errorRateLimitHour;
262
+ return g != null && g.includes("minute") ? n.errorRateLimitMinute : n.errorRateLimitHour;
171
263
  case "VALIDATION_ERROR":
172
264
  case "CONFIG_ERROR":
173
265
  case "SERVICE_ERROR":
174
266
  case "UNKNOWN_ERROR":
175
267
  default:
176
- return p ?? n.errorGeneric;
268
+ return g ?? n.errorGeneric;
177
269
  }
178
270
  },
179
271
  [n]
180
- ), M = R((m) => !(m instanceof U) || m.code === "TIMEOUT" || m.code === "NETWORK_ERROR" || m.code === "RATE_LIMITED" || m.code === "SERVICE_ERROR" || m.code === "UNKNOWN_ERROR" || m.status >= 500 || m.status === 0, []), D = R(
181
- async (m) => {
182
- E(!0), y.current = !0, x(null), w(!1);
272
+ ), j = M((f) => !(f instanceof U) || f.code === "TIMEOUT" || f.code === "NETWORK_ERROR" || f.code === "RATE_LIMITED" || f.code === "SERVICE_ERROR" || f.code === "UNKNOWN_ERROR" || f.status >= 500 || f.status === 0, []), m = M(
273
+ async (f) => {
274
+ p(!0), N.current = !0, y(null), x(!1);
183
275
  try {
184
- const p = await o.sendMessage(m), H = {
185
- id: A(),
276
+ const g = await c.sendMessage(f);
277
+ let L = {
278
+ id: D(),
186
279
  role: "assistant",
187
- content: p.reply,
188
- sources: p.sources
189
- }, S = [...m, H];
190
- T.current = S, u(S), O(S);
191
- } catch (p) {
192
- if (p instanceof se) return;
193
- p instanceof U ? x(I(p.code, p.message)) : x(
280
+ content: g.reply,
281
+ sources: g.sources
282
+ };
283
+ I.current.length > 0 && (L = await ke(
284
+ I.current,
285
+ L,
286
+ { messages: f, apiUrl: e }
287
+ ));
288
+ const T = [...f, L];
289
+ E.current = T, d(T), A(T);
290
+ } catch (g) {
291
+ if (g instanceof ae) return;
292
+ if (I.current.length > 0) {
293
+ const L = g instanceof Error ? g : new Error(String(g)), T = await Ae(I.current, L, {
294
+ messages: f,
295
+ apiUrl: e
296
+ });
297
+ if (T) {
298
+ const B = {
299
+ id: D(),
300
+ role: "assistant",
301
+ content: T.content,
302
+ sources: T.sources
303
+ }, O = [...f, B];
304
+ E.current = O, d(O), A(O), y(null), x(!1);
305
+ return;
306
+ }
307
+ }
308
+ g instanceof U ? y(S(g.code, g.message)) : y(
194
309
  (n == null ? void 0 : n.errorConnection) ?? "Failed to connect. Please try again."
195
- ), w(M(p));
310
+ ), x(j(g));
196
311
  } finally {
197
- E(!1), y.current = !1;
312
+ p(!1), N.current = !1;
198
313
  }
199
314
  },
200
- [o, I, M, O, n]
201
- ), _ = R(
202
- async (m) => {
203
- const p = m.trim();
204
- if (!p || y.current) return;
205
- const H = {
206
- id: A(),
315
+ [
316
+ e,
317
+ c,
318
+ S,
319
+ j,
320
+ A,
321
+ n
322
+ ]
323
+ ), P = M(
324
+ async (f) => {
325
+ const g = f.trim();
326
+ if (!g || N.current) return;
327
+ const L = {
328
+ id: D(),
207
329
  role: "user",
208
- content: p
209
- }, S = [...T.current, H];
210
- T.current = S, u(S), O(S), await D(S);
330
+ content: g
331
+ };
332
+ let T = L;
333
+ if (I.current.length > 0) {
334
+ const O = await Le(I.current, L, {
335
+ messages: E.current,
336
+ apiUrl: e
337
+ });
338
+ if (O.type === "abort") return;
339
+ if (O.type === "respond") {
340
+ const z = {
341
+ id: D(),
342
+ role: "assistant",
343
+ content: O.reply.content,
344
+ sources: O.reply.sources
345
+ }, $ = [
346
+ ...E.current,
347
+ O.message,
348
+ z
349
+ ];
350
+ E.current = $, d($), A($), y(null), x(!1);
351
+ return;
352
+ }
353
+ T = O.message;
354
+ }
355
+ const B = [...E.current, T];
356
+ E.current = B, d(B), A(B), await m(B);
211
357
  },
212
- [O, D]
213
- ), b = R(async () => {
214
- if (y.current) return;
215
- const m = T.current[T.current.length - 1];
216
- !m || m.role !== "user" || await D(T.current);
217
- }, [D]), j = R(() => {
218
- if (T.current = [], u([]), x(null), w(!1), e) {
219
- const m = V();
220
- if (!m) return;
358
+ [e, A, m]
359
+ ), V = M(async () => {
360
+ if (N.current) return;
361
+ const f = E.current[E.current.length - 1];
362
+ !f || f.role !== "user" || await m(E.current);
363
+ }, [m]), K = M(() => {
364
+ if (E.current = [], d([]), y(null), x(!1), t) {
365
+ const f = Z();
366
+ if (!f) return;
221
367
  try {
222
- m.removeItem(a);
368
+ f.removeItem(a);
223
369
  } catch {
224
370
  }
225
371
  }
226
- }, [e, a]);
372
+ }, [t, a]);
227
373
  return {
228
- messages: c,
229
- isLoading: h,
230
- error: g,
231
- canRetry: f,
232
- sendMessage: _,
233
- retry: b,
234
- clearMessages: j
374
+ messages: l,
375
+ isLoading: R,
376
+ error: w,
377
+ canRetry: b,
378
+ sendMessage: P,
379
+ retry: V,
380
+ clearMessages: K
235
381
  };
236
382
  }
237
- function Oe(t) {
238
- const [e, r] = C(() => typeof window > "u" ? !1 : window.matchMedia(t).matches);
239
- return k(() => {
240
- const s = window.matchMedia(t);
383
+ function Be(e) {
384
+ const [t, r] = k(() => typeof window > "u" ? !1 : window.matchMedia(e).matches);
385
+ return H(() => {
386
+ const s = window.matchMedia(e);
241
387
  r(s.matches);
242
388
  const n = (o) => r(o.matches);
243
389
  return s.addEventListener("change", n), () => s.removeEventListener("change", n);
244
- }, [t]), e;
390
+ }, [e]), t;
245
391
  }
246
- function W(t, e) {
247
- return t instanceof RegExp ? t.test(e) : e.toLowerCase().includes(t.toLowerCase());
392
+ function F(e, t) {
393
+ return e instanceof RegExp ? e.test(t) : t.toLowerCase().includes(e.toLowerCase());
248
394
  }
249
- function Ae() {
250
- const t = document.documentElement, e = document.body, r = t.scrollTop || e.scrollTop || 0, s = Math.max(t.scrollHeight, e.scrollHeight), n = t.clientHeight || window.innerHeight, o = s - n;
395
+ function $e() {
396
+ const e = document.documentElement, t = document.body, r = e.scrollTop || t.scrollTop || 0, s = Math.max(e.scrollHeight, t.scrollHeight), n = e.clientHeight || window.innerHeight, o = s - n;
251
397
  return o <= 0 ? 100 : r / o * 100;
252
398
  }
253
- function Ie({
254
- triggers: t,
255
- enabled: e,
399
+ function je({
400
+ triggers: e,
401
+ enabled: t,
256
402
  onOpen: r,
257
403
  onGreeting: s
258
404
  }) {
259
- k(() => {
260
- if (!e || !t || t.length === 0) return;
261
- const n = /* @__PURE__ */ new Set(), o = [], a = typeof window < "u" ? window.location.href : "", l = (c, u) => {
262
- n.has(c) || (n.add(c), u === "open" ? r() : s(u.greeting));
405
+ H(() => {
406
+ if (!t || !e || e.length === 0) return;
407
+ const n = /* @__PURE__ */ new Set(), o = [], c = typeof window < "u" ? window.location.href : "", a = (u, l) => {
408
+ n.has(u) || (n.add(u), l === "open" ? r() : s(l.greeting));
263
409
  };
264
- return t.forEach((c, u) => {
265
- switch (c.on) {
410
+ return e.forEach((u, l) => {
411
+ switch (u.on) {
266
412
  case "url": {
267
- W(c.pattern, a) && l(u, c.action);
413
+ F(u.pattern, c) && a(l, u.action);
268
414
  break;
269
415
  }
270
416
  case "time": {
271
- if (c.matchUrl && !W(c.matchUrl, a))
417
+ if (u.matchUrl && !F(u.matchUrl, c))
272
418
  return;
273
- const h = window.setTimeout(
274
- () => l(u, c.action),
275
- Math.max(0, c.seconds * 1e3)
419
+ const d = window.setTimeout(
420
+ () => a(l, u.action),
421
+ Math.max(0, u.seconds * 1e3)
276
422
  );
277
- o.push(() => window.clearTimeout(h));
423
+ o.push(() => window.clearTimeout(d));
278
424
  break;
279
425
  }
280
426
  case "scroll": {
281
- if (c.matchUrl && !W(c.matchUrl, a))
427
+ if (u.matchUrl && !F(u.matchUrl, c))
282
428
  return;
283
- const h = () => {
284
- Ae() >= c.percent && l(u, c.action);
429
+ const d = () => {
430
+ $e() >= u.percent && a(l, u.action);
285
431
  };
286
- h(), window.addEventListener("scroll", h, { passive: !0 }), o.push(() => window.removeEventListener("scroll", h));
432
+ d(), window.addEventListener("scroll", d, { passive: !0 }), o.push(() => window.removeEventListener("scroll", d));
287
433
  break;
288
434
  }
289
435
  case "exit-intent": {
290
- if (c.matchUrl && !W(c.matchUrl, a))
436
+ if (u.matchUrl && !F(u.matchUrl, c))
291
437
  return;
292
- const h = (E) => {
293
- E.clientY <= 0 && l(u, c.action);
438
+ const d = (R) => {
439
+ R.clientY <= 0 && a(l, u.action);
294
440
  };
295
- document.addEventListener("mouseleave", h), o.push(
296
- () => document.removeEventListener("mouseleave", h)
441
+ document.addEventListener("mouseleave", d), o.push(
442
+ () => document.removeEventListener("mouseleave", d)
297
443
  );
298
444
  break;
299
445
  }
300
446
  }
301
447
  }), () => {
302
- o.forEach((c) => c());
448
+ o.forEach((u) => u());
303
449
  };
304
- }, [t, e, r, s]);
450
+ }, [e, t, r, s]);
305
451
  }
306
- const De = {
452
+ const Pe = {
307
453
  "bottom-right": "bottom-6 right-6",
308
454
  "bottom-left": "bottom-6 left-6",
309
455
  "top-right": "top-6 right-6",
310
456
  "top-left": "top-6 left-6"
311
- }, He = Ee(function({ isOpen: e, onClick: r, position: s = "bottom-right", translations: n }, o) {
312
- const a = e ? (n == null ? void 0 : n.closeChat) ?? "Close chat" : (n == null ? void 0 : n.openChat) ?? "Open chat";
457
+ }, Ge = Me(function({ isOpen: t, onClick: r, position: s = "bottom-right", translations: n }, o) {
458
+ const c = t ? (n == null ? void 0 : n.closeChat) ?? "Close chat" : (n == null ? void 0 : n.openChat) ?? "Open chat";
313
459
  return /* @__PURE__ */ i(
314
460
  "button",
315
461
  {
316
462
  ref: o,
317
463
  onClick: r,
318
- "aria-label": a,
319
- className: `fixed ${De[s]} z-50 flex h-14 w-14 items-center justify-center rounded-claudius-full bg-claudius-accent text-claudius-accent-text shadow-claudius-floating transition-transform hover:scale-105 focus:outline-none focus:ring-2 focus:ring-claudius-accent focus:ring-offset-2`,
320
- children: e ? /* @__PURE__ */ d(
464
+ "aria-label": c,
465
+ className: `fixed ${Pe[s]} z-50 flex h-14 w-14 items-center justify-center rounded-claudius-full bg-claudius-accent text-claudius-accent-text shadow-claudius-floating transition-transform hover:scale-105 focus:outline-none focus:ring-2 focus:ring-claudius-accent focus:ring-offset-2`,
466
+ children: t ? /* @__PURE__ */ h(
321
467
  "svg",
322
468
  {
323
469
  width: "24",
@@ -351,12 +497,12 @@ const De = {
351
497
  )
352
498
  }
353
499
  );
354
- }), _e = K(function({
355
- count: e,
500
+ }), Ue = J(function({
501
+ count: t,
356
502
  isActive: r,
357
503
  onClick: s
358
504
  }) {
359
- return /* @__PURE__ */ d(
505
+ return /* @__PURE__ */ h(
360
506
  "button",
361
507
  {
362
508
  onClick: s,
@@ -364,7 +510,7 @@ const De = {
364
510
  title: "View sources",
365
511
  className: `group relative flex h-7 w-7 items-center justify-center rounded-claudius-full transition-colors ${r ? "bg-claudius-accent text-claudius-accent-text" : "text-claudius-text-muted hover:bg-claudius-surface-muted hover:text-claudius-text"}`,
366
512
  children: [
367
- /* @__PURE__ */ d(
513
+ /* @__PURE__ */ h(
368
514
  "svg",
369
515
  {
370
516
  width: "14",
@@ -384,29 +530,29 @@ const De = {
384
530
  ]
385
531
  }
386
532
  ),
387
- /* @__PURE__ */ i("span", { className: "absolute -right-1 -top-1 flex h-4 min-w-4 items-center justify-center rounded-claudius-full bg-claudius-accent px-1 text-[10px] font-bold text-claudius-accent-text", children: e })
533
+ /* @__PURE__ */ i("span", { className: "absolute -right-1 -top-1 flex h-4 min-w-4 items-center justify-center rounded-claudius-full bg-claudius-accent px-1 text-[10px] font-bold text-claudius-accent-text", children: t })
388
534
  ]
389
535
  }
390
536
  );
391
- }), je = ["http:", "https:"];
392
- function oe(t) {
393
- if (!t || typeof t != "string")
537
+ }), We = ["http:", "https:"];
538
+ function le(e) {
539
+ if (!e || typeof e != "string")
394
540
  return null;
395
- const e = t.trim();
396
- if (!e)
541
+ const t = e.trim();
542
+ if (!t)
397
543
  return null;
398
544
  try {
399
- const r = new URL(e);
400
- return je.includes(r.protocol) ? e : null;
545
+ const r = new URL(t);
546
+ return We.includes(r.protocol) ? t : null;
401
547
  } catch {
402
548
  return null;
403
549
  }
404
550
  }
405
- const Q = /(https?:\/\/[^\s)]+)/, ee = /(\*\*[^*]+\*\*)/, te = /(\*[^*]+\*)/;
406
- function $e(t, e) {
407
- const r = t.match(/[.,;:!?'"]+$/), s = r ? t.slice(0, -r[0].length) : t, n = r ? r[0] : "", o = oe(s);
408
- return o ? /* @__PURE__ */ d(ve, { children: [
409
- /* @__PURE__ */ d(
551
+ const ne = /(https?:\/\/[^\s)]+)/, se = /(\*\*[^*]+\*\*)/, oe = /(\*[^*]+\*)/;
552
+ function ze(e, t) {
553
+ const r = e.match(/[.,;:!?'"]+$/), s = r ? e.slice(0, -r[0].length) : e, n = r ? r[0] : "", o = le(s);
554
+ return o ? /* @__PURE__ */ h(Te, { children: [
555
+ /* @__PURE__ */ h(
410
556
  "a",
411
557
  {
412
558
  href: o,
@@ -418,57 +564,57 @@ function $e(t, e) {
418
564
  /* @__PURE__ */ i("span", { className: "sr-only", children: " (opens in a new tab)" })
419
565
  ]
420
566
  },
421
- e
567
+ t
422
568
  ),
423
569
  n
424
- ] }) : t;
570
+ ] }) : e;
425
571
  }
426
- function Ue(t, e) {
427
- const r = t.split(ee), s = [];
572
+ function Fe(e, t) {
573
+ const r = e.split(se), s = [];
428
574
  return r.forEach((n, o) => {
429
- if (ee.test(n)) {
430
- const a = n.slice(2, -2);
431
- s.push(/* @__PURE__ */ i("strong", { children: a }, `${e}-b${o}`));
575
+ if (se.test(n)) {
576
+ const c = n.slice(2, -2);
577
+ s.push(/* @__PURE__ */ i("strong", { children: c }, `${t}-b${o}`));
432
578
  } else
433
- n.split(te).forEach((l, c) => {
434
- if (te.test(l)) {
435
- const u = l.slice(1, -1);
436
- s.push(/* @__PURE__ */ i("em", { children: u }, `${e}-b${o}-i${c}`));
579
+ n.split(oe).forEach((a, u) => {
580
+ if (oe.test(a)) {
581
+ const l = a.slice(1, -1);
582
+ s.push(/* @__PURE__ */ i("em", { children: l }, `${t}-b${o}-i${u}`));
437
583
  } else
438
- l.split(Q).forEach((h, E) => {
439
- Q.test(h) ? s.push(
440
- $e(h, `${e}-b${o}-i${c}-u${E}`)
441
- ) : h && s.push(h);
584
+ a.split(ne).forEach((d, R) => {
585
+ ne.test(d) ? s.push(
586
+ ze(d, `${t}-b${o}-i${u}-u${R}`)
587
+ ) : d && s.push(d);
442
588
  });
443
589
  });
444
590
  }), s;
445
591
  }
446
- function Be(t) {
447
- const e = t.split(`
592
+ function Ye(e) {
593
+ const t = e.split(`
448
594
  `);
449
- return e.map((r, s) => /* @__PURE__ */ d("span", { children: [
450
- Ue(r, `l${s}`),
451
- s < e.length - 1 && /* @__PURE__ */ i("br", {})
595
+ return t.map((r, s) => /* @__PURE__ */ h("span", { children: [
596
+ Fe(r, `l${s}`),
597
+ s < t.length - 1 && /* @__PURE__ */ i("br", {})
452
598
  ] }, s));
453
599
  }
454
- const Ge = K(function({
455
- role: e,
600
+ const Ve = J(function({
601
+ role: t,
456
602
  content: r,
457
603
  sources: s,
458
604
  onSourceClick: n,
459
605
  isSourceActive: o
460
606
  }) {
461
- const a = e === "user";
462
- return /* @__PURE__ */ d("div", { className: `${a ? "ml-auto" : "mr-auto"} max-w-[85%]`, children: [
607
+ const c = t === "user";
608
+ return /* @__PURE__ */ h("div", { className: `${c ? "ml-auto" : "mr-auto"} max-w-[85%]`, children: [
463
609
  /* @__PURE__ */ i(
464
610
  "div",
465
611
  {
466
- className: `rounded-claudius-bubble px-4 py-2.5 text-sm leading-relaxed font-body ${a ? "bg-claudius-user-bubble text-claudius-user-bubble-text rounded-br-claudius-tail" : "bg-claudius-assistant-bubble text-claudius-assistant-bubble-text rounded-bl-claudius-tail"}`,
467
- children: Be(r)
612
+ className: `rounded-claudius-bubble px-4 py-2.5 text-sm leading-relaxed font-body ${c ? "bg-claudius-user-bubble text-claudius-user-bubble-text rounded-br-claudius-tail" : "bg-claudius-assistant-bubble text-claudius-assistant-bubble-text rounded-bl-claudius-tail"}`,
613
+ children: Ye(r)
468
614
  }
469
615
  ),
470
- !a && s && s.length > 0 && n && /* @__PURE__ */ i("div", { className: "mt-1", children: /* @__PURE__ */ i(
471
- _e,
616
+ !c && s && s.length > 0 && n && /* @__PURE__ */ i("div", { className: "mt-1", children: /* @__PURE__ */ i(
617
+ Ue,
472
618
  {
473
619
  count: s.length,
474
620
  isActive: o ?? !1,
@@ -476,42 +622,42 @@ const Ge = K(function({
476
622
  }
477
623
  ) })
478
624
  ] });
479
- }), z = 2e3, Pe = 1800;
480
- function We({
481
- onSend: t,
482
- isLoading: e,
625
+ }), X = 2e3, Ke = 1800;
626
+ function qe({
627
+ onSend: e,
628
+ isLoading: t,
483
629
  placeholder: r,
484
630
  translations: s
485
631
  }) {
486
- const [n, o] = C(""), a = N(null), l = n.length, c = l >= Pe, u = l >= z, h = r ?? (s == null ? void 0 : s.placeholder) ?? "Type your message...", E = (s == null ? void 0 : s.sendMessage) ?? "Send message", g = (s == null ? void 0 : s.typeYourMessage) ?? "Type your message";
487
- return k(() => {
488
- var w;
489
- e || (w = a.current) == null || w.focus();
490
- }, [e]), /* @__PURE__ */ d(
632
+ const [n, o] = k(""), c = C(null), a = n.length, u = a >= Ke, l = a >= X, d = r ?? (s == null ? void 0 : s.placeholder) ?? "Type your message...", R = (s == null ? void 0 : s.sendMessage) ?? "Send message", p = (s == null ? void 0 : s.typeYourMessage) ?? "Type your message";
633
+ return H(() => {
634
+ var b;
635
+ t || (b = c.current) == null || b.focus();
636
+ }, [t]), /* @__PURE__ */ h(
491
637
  "form",
492
638
  {
493
- onSubmit: (w) => {
494
- w.preventDefault();
495
- const v = n.trim();
496
- !v || u || (t(v), o(""));
639
+ onSubmit: (b) => {
640
+ b.preventDefault();
641
+ const x = n.trim();
642
+ !x || l || (e(x), o(""));
497
643
  },
498
644
  className: "border-t border-claudius-border bg-claudius-surface p-3",
499
645
  children: [
500
- /* @__PURE__ */ d("div", { className: "flex gap-2", children: [
646
+ /* @__PURE__ */ h("div", { className: "flex gap-2", children: [
501
647
  /* @__PURE__ */ i(
502
648
  "input",
503
649
  {
504
- ref: a,
650
+ ref: c,
505
651
  type: "text",
506
652
  value: n,
507
- onChange: (w) => {
508
- const v = w.target.value;
509
- v.length <= z && o(v);
653
+ onChange: (b) => {
654
+ const x = b.target.value;
655
+ x.length <= X && o(x);
510
656
  },
511
- placeholder: h,
512
- disabled: e,
513
- "aria-label": g,
514
- "aria-describedby": c ? "char-count" : void 0,
657
+ placeholder: d,
658
+ disabled: t,
659
+ "aria-label": p,
660
+ "aria-describedby": u ? "char-count" : void 0,
515
661
  className: "flex-1 rounded-claudius-sm border border-claudius-border bg-claudius-field px-3 py-2 text-sm font-body text-claudius-text placeholder:text-claudius-text-muted focus:border-claudius-accent focus:outline-none focus:ring-1 focus:ring-claudius-accent disabled:opacity-50"
516
662
  }
517
663
  ),
@@ -519,10 +665,10 @@ function We({
519
665
  "button",
520
666
  {
521
667
  type: "submit",
522
- disabled: e || u,
523
- "aria-label": E,
668
+ disabled: t || l,
669
+ "aria-label": R,
524
670
  className: "flex h-11 w-11 shrink-0 items-center justify-center rounded-claudius-sm bg-claudius-accent text-claudius-accent-text transition-colors hover:opacity-90 disabled:opacity-50",
525
- children: /* @__PURE__ */ d(
671
+ children: /* @__PURE__ */ h(
526
672
  "svg",
527
673
  {
528
674
  width: "16",
@@ -543,16 +689,16 @@ function We({
543
689
  }
544
690
  )
545
691
  ] }),
546
- c && /* @__PURE__ */ d(
692
+ u && /* @__PURE__ */ h(
547
693
  "div",
548
694
  {
549
695
  id: "char-count",
550
- className: `mt-1 text-xs text-right ${u ? "text-claudius-error" : "text-claudius-text-muted"}`,
696
+ className: `mt-1 text-xs text-right ${l ? "text-claudius-error" : "text-claudius-text-muted"}`,
551
697
  "aria-live": "polite",
552
698
  children: [
553
- l,
699
+ a,
554
700
  "/",
555
- z
701
+ X
556
702
  ]
557
703
  }
558
704
  )
@@ -560,30 +706,30 @@ function We({
560
706
  }
561
707
  );
562
708
  }
563
- const Fe = ["blog", "page", "external"], Ye = {
709
+ const Xe = ["blog", "page", "external"], Ze = {
564
710
  blog: "Blog",
565
711
  page: "Page",
566
712
  external: "External"
567
713
  };
568
- function ze(t) {
714
+ function Je(e) {
569
715
  try {
570
- return new URL(t).hostname;
716
+ return new URL(e).hostname;
571
717
  } catch {
572
- return t;
718
+ return e;
573
719
  }
574
720
  }
575
- const Ve = K(function({
576
- sources: e,
721
+ const Qe = J(function({
722
+ sources: t,
577
723
  onClose: r
578
724
  }) {
579
- const s = Fe.map((o) => ({
725
+ const s = Xe.map((o) => ({
580
726
  type: o,
581
- label: Ye[o],
582
- items: e.filter((a) => a.type === o)
583
- })).filter((o) => o.items.length > 0), n = e.length === 1 ? "1 source found" : `${e.length} sources found`;
584
- return /* @__PURE__ */ d("div", { className: "absolute inset-y-0 left-0 z-10 flex w-[280px] flex-col border-r-2 border-claudius-border bg-claudius-surface rounded-r-claudius-lg transition-transform duration-200 ease-out", children: [
585
- /* @__PURE__ */ d("div", { className: "flex items-center justify-between border-b border-claudius-border px-4 py-3", children: [
586
- /* @__PURE__ */ d("div", { children: [
727
+ label: Ze[o],
728
+ items: t.filter((c) => c.type === o)
729
+ })).filter((o) => o.items.length > 0), n = t.length === 1 ? "1 source found" : `${t.length} sources found`;
730
+ return /* @__PURE__ */ h("div", { className: "absolute inset-y-0 left-0 z-10 flex w-[280px] flex-col border-r-2 border-claudius-border bg-claudius-surface rounded-r-claudius-lg transition-transform duration-200 ease-out", children: [
731
+ /* @__PURE__ */ h("div", { className: "flex items-center justify-between border-b border-claudius-border px-4 py-3", children: [
732
+ /* @__PURE__ */ h("div", { children: [
587
733
  /* @__PURE__ */ i("h3", { className: "text-sm font-heading font-semibold text-claudius-text", children: "Sources" }),
588
734
  /* @__PURE__ */ i("p", { className: "text-xs text-claudius-text-muted", children: n })
589
735
  ] }),
@@ -593,7 +739,7 @@ const Ve = K(function({
593
739
  onClick: r,
594
740
  "aria-label": "Close sources",
595
741
  className: "flex h-7 w-7 items-center justify-center rounded-claudius-full text-claudius-text-muted transition-colors hover:bg-claudius-surface-muted hover:text-claudius-text",
596
- children: /* @__PURE__ */ d(
742
+ children: /* @__PURE__ */ h(
597
743
  "svg",
598
744
  {
599
745
  width: "14",
@@ -614,248 +760,280 @@ const Ve = K(function({
614
760
  }
615
761
  )
616
762
  ] }),
617
- /* @__PURE__ */ i("div", { className: "flex-1 overflow-y-auto px-3 py-3 space-y-4", children: s.map((o) => /* @__PURE__ */ d("div", { children: [
763
+ /* @__PURE__ */ i("div", { className: "flex-1 overflow-y-auto px-3 py-3 space-y-4", children: s.map((o) => /* @__PURE__ */ h("div", { children: [
618
764
  /* @__PURE__ */ i("h4", { className: "mb-2 text-xs font-semibold uppercase tracking-wide text-claudius-text-muted", children: o.label }),
619
- /* @__PURE__ */ i("div", { className: "space-y-2", children: o.items.map((a) => {
620
- const l = oe(a.url);
621
- return l ? /* @__PURE__ */ d(
765
+ /* @__PURE__ */ i("div", { className: "space-y-2", children: o.items.map((c) => {
766
+ const a = le(c.url);
767
+ return a ? /* @__PURE__ */ h(
622
768
  "a",
623
769
  {
624
- href: l,
770
+ href: a,
625
771
  target: "_blank",
626
772
  rel: "noopener noreferrer",
627
773
  className: "block rounded-claudius-md border-2 border-claudius-border bg-claudius-surface-muted p-3 transition-colors hover:bg-claudius-border",
628
774
  children: [
629
- /* @__PURE__ */ i("p", { className: "truncate text-sm font-medium text-claudius-text", children: a.title }),
630
- /* @__PURE__ */ i("p", { className: "mt-0.5 text-xs text-claudius-text-muted", children: ze(l) })
775
+ /* @__PURE__ */ i("p", { className: "truncate text-sm font-medium text-claudius-text", children: c.title }),
776
+ /* @__PURE__ */ i("p", { className: "mt-0.5 text-xs text-claudius-text-muted", children: Je(a) })
631
777
  ]
632
778
  },
633
- l
779
+ a
634
780
  ) : null;
635
781
  }) })
636
782
  ] }, o.type)) })
637
783
  ] });
638
784
  });
639
- function Ke(t, e, r) {
640
- const [s, n] = C(0), o = N(0), a = N(0), l = N(0), c = N(!1);
641
- return k(() => {
642
- const u = t.current;
643
- if (!r || !u) return;
644
- const h = (x) => {
645
- if (u.scrollTop > 0) {
646
- c.current = !1;
785
+ function et({
786
+ title: e,
787
+ subtitle: t,
788
+ titleId: r,
789
+ closeLabel: s,
790
+ onClose: n
791
+ }) {
792
+ return /* @__PURE__ */ h("div", { className: "flex items-center gap-3 bg-claudius-accent px-5 py-4", children: [
793
+ /* @__PURE__ */ i(
794
+ "div",
795
+ {
796
+ "aria-hidden": "true",
797
+ className: "flex h-8 w-8 items-center justify-center rounded-claudius-full bg-claudius-accent-soft text-sm font-bold text-claudius-accent-text",
798
+ children: e.charAt(0).toUpperCase()
799
+ }
800
+ ),
801
+ /* @__PURE__ */ h("div", { className: "flex-1", children: [
802
+ /* @__PURE__ */ i(
803
+ "h2",
804
+ {
805
+ id: r,
806
+ className: "text-sm font-heading font-semibold text-claudius-accent-text",
807
+ children: e
808
+ }
809
+ ),
810
+ /* @__PURE__ */ i("p", { className: "text-xs text-claudius-accent-text", children: t })
811
+ ] }),
812
+ /* @__PURE__ */ i(
813
+ "button",
814
+ {
815
+ onClick: n,
816
+ "aria-label": s,
817
+ className: "flex h-10 w-10 items-center justify-center rounded-claudius-full text-claudius-accent-text-muted transition-colors hover:bg-claudius-accent-soft hover:text-claudius-accent-text",
818
+ children: /* @__PURE__ */ h(
819
+ "svg",
820
+ {
821
+ width: "18",
822
+ height: "18",
823
+ viewBox: "0 0 24 24",
824
+ fill: "none",
825
+ stroke: "currentColor",
826
+ strokeWidth: "2",
827
+ strokeLinecap: "round",
828
+ strokeLinejoin: "round",
829
+ "aria-hidden": "true",
830
+ children: [
831
+ /* @__PURE__ */ i("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
832
+ /* @__PURE__ */ i("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
833
+ ]
834
+ }
835
+ )
836
+ }
837
+ )
838
+ ] });
839
+ }
840
+ function tt({
841
+ message: e,
842
+ retryLabel: t,
843
+ onRetry: r
844
+ }) {
845
+ return /* @__PURE__ */ h(
846
+ "div",
847
+ {
848
+ role: "alert",
849
+ className: "mx-auto flex max-w-[90%] flex-col items-center gap-2 rounded-claudius-sm bg-claudius-error-surface px-3 py-2 text-center text-xs text-claudius-error",
850
+ children: [
851
+ /* @__PURE__ */ i("span", { children: e }),
852
+ r && /* @__PURE__ */ i(
853
+ "button",
854
+ {
855
+ type: "button",
856
+ onClick: r,
857
+ className: "rounded-claudius-md bg-claudius-error px-3 py-1 text-xs font-semibold text-claudius-error-text transition-opacity hover:opacity-90 focus:outline-none focus-visible:ring-2 focus-visible:ring-claudius-error focus-visible:ring-offset-1",
858
+ children: t
859
+ }
860
+ )
861
+ ]
862
+ }
863
+ );
864
+ }
865
+ function rt({ label: e }) {
866
+ return /* @__PURE__ */ i(
867
+ "div",
868
+ {
869
+ role: "status",
870
+ "aria-live": "polite",
871
+ "aria-label": e,
872
+ className: "mr-auto flex max-w-[85%]",
873
+ children: /* @__PURE__ */ h("div", { className: "flex gap-1 rounded-claudius-bubble rounded-bl-claudius-tail bg-claudius-assistant-bubble px-4 py-3", children: [
874
+ /* @__PURE__ */ i("span", { className: "h-2 w-2 motion-safe:animate-bounce rounded-claudius-full bg-claudius-text-muted [animation-delay:0ms]" }),
875
+ /* @__PURE__ */ i("span", { className: "h-2 w-2 motion-safe:animate-bounce rounded-claudius-full bg-claudius-text-muted [animation-delay:150ms]" }),
876
+ /* @__PURE__ */ i("span", { className: "h-2 w-2 motion-safe:animate-bounce rounded-claudius-full bg-claudius-text-muted [animation-delay:300ms]" })
877
+ ] })
878
+ }
879
+ );
880
+ }
881
+ function nt(e, t, r) {
882
+ const [s, n] = k(0), o = C(0), c = C(0), a = C(0), u = C(!1);
883
+ return H(() => {
884
+ const l = e.current;
885
+ if (!r || !l) return;
886
+ const d = (w) => {
887
+ if (l.scrollTop > 0) {
888
+ u.current = !1;
647
889
  return;
648
890
  }
649
- c.current = !0, a.current = x.touches[0].clientY, l.current = Date.now();
650
- }, E = (x) => {
651
- if (!c.current) return;
652
- let f = x.touches[0].clientY - a.current;
653
- f < 0 && (f = f * 0.3), o.current = f, n(f);
654
- }, g = () => {
655
- if (!c.current) return;
656
- c.current = !1;
657
- const x = o.current, f = (Date.now() - l.current) / 1e3, w = u.getBoundingClientRect().height, v = f > 0.05 && x > 0 && x / f > 500, y = x > w * 0.3;
658
- v || y ? e() : (o.current = 0, n(0));
891
+ u.current = !0, c.current = w.touches[0].clientY, a.current = Date.now();
892
+ }, R = (w) => {
893
+ if (!u.current) return;
894
+ let y = w.touches[0].clientY - c.current;
895
+ y < 0 && (y = y * 0.3), o.current = y, n(y);
896
+ }, p = () => {
897
+ if (!u.current) return;
898
+ u.current = !1;
899
+ const w = o.current, y = (Date.now() - a.current) / 1e3, b = l.getBoundingClientRect().height, x = y > 0.05 && w > 0 && w / y > 500, v = w > b * 0.3;
900
+ x || v ? t() : (o.current = 0, n(0));
659
901
  };
660
- return u.addEventListener("touchstart", h, { passive: !0 }), u.addEventListener("touchmove", E, { passive: !0 }), u.addEventListener("touchend", g), () => {
661
- u.removeEventListener("touchstart", h), u.removeEventListener("touchmove", E), u.removeEventListener("touchend", g);
902
+ return l.addEventListener("touchstart", d, { passive: !0 }), l.addEventListener("touchmove", R, { passive: !0 }), l.addEventListener("touchend", p), () => {
903
+ l.removeEventListener("touchstart", d), l.removeEventListener("touchmove", R), l.removeEventListener("touchend", p);
662
904
  };
663
- }, [t, e, r]), { offsetY: s };
905
+ }, [e, t, r]), { offsetY: s };
664
906
  }
665
- const qe = 'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';
666
- function Xe(t, e) {
667
- k(() => {
668
- const r = t.current;
907
+ const st = 'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';
908
+ function ot(e, t) {
909
+ H(() => {
910
+ const r = e.current;
669
911
  if (!r) return;
670
912
  const s = (n) => {
671
913
  if (n.key !== "Tab") return;
672
914
  const o = Array.from(
673
- r.querySelectorAll(qe)
674
- ).filter((u) => !u.hasAttribute("aria-hidden"));
915
+ r.querySelectorAll(st)
916
+ ).filter((l) => !l.hasAttribute("aria-hidden"));
675
917
  if (o.length === 0) return;
676
- const a = o[0], l = o[o.length - 1], c = document.activeElement;
677
- n.shiftKey && c === a ? (n.preventDefault(), l.focus()) : !n.shiftKey && c === l && (n.preventDefault(), a.focus());
918
+ const c = o[0], a = o[o.length - 1], u = document.activeElement;
919
+ n.shiftKey && u === c ? (n.preventDefault(), a.focus()) : !n.shiftKey && u === a && (n.preventDefault(), c.focus());
678
920
  };
679
921
  return r.addEventListener("keydown", s), () => r.removeEventListener("keydown", s);
680
- }, [t, e]);
922
+ }, [e, t]);
681
923
  }
682
- const Je = /\*\*([^*]+)\*\*/g, Ze = /\*([^*]+)\*/g, Qe = /https?:\/\/[^\s)]+/g;
683
- function et(t) {
684
- return t.replace(Je, "$1").replace(Ze, "$1").replace(Qe, (e) => {
924
+ const it = /\*\*([^*]+)\*\*/g, ct = /\*([^*]+)\*/g, at = /https?:\/\/[^\s)]+/g;
925
+ function ut(e) {
926
+ return e.replace(it, "$1").replace(ct, "$1").replace(at, (t) => {
685
927
  try {
686
- return new URL(e).hostname;
928
+ return new URL(t).hostname;
687
929
  } catch {
688
- return e;
930
+ return t;
689
931
  }
690
932
  });
691
933
  }
692
- function tt({ label: t }) {
693
- return /* @__PURE__ */ i(
694
- "div",
695
- {
696
- role: "status",
697
- "aria-live": "polite",
698
- "aria-label": t,
699
- className: "mr-auto flex max-w-[85%]",
700
- children: /* @__PURE__ */ d("div", { className: "flex gap-1 rounded-claudius-bubble rounded-bl-claudius-tail bg-claudius-assistant-bubble px-4 py-3", children: [
701
- /* @__PURE__ */ i("span", { className: "h-2 w-2 motion-safe:animate-bounce rounded-claudius-full bg-claudius-text-muted [animation-delay:0ms]" }),
702
- /* @__PURE__ */ i("span", { className: "h-2 w-2 motion-safe:animate-bounce rounded-claudius-full bg-claudius-text-muted [animation-delay:150ms]" }),
703
- /* @__PURE__ */ i("span", { className: "h-2 w-2 motion-safe:animate-bounce rounded-claudius-full bg-claudius-text-muted [animation-delay:300ms]" })
704
- ] })
705
- }
706
- );
707
- }
708
- const rt = {
934
+ const lt = {
709
935
  "bottom-right": "bottom-24 right-3 sm:right-6",
710
936
  "bottom-left": "bottom-24 left-3 sm:left-6",
711
937
  "top-right": "top-24 right-3 sm:right-6",
712
938
  "top-left": "top-24 left-3 sm:left-6"
713
939
  };
714
- function nt({
715
- messages: t,
716
- isLoading: e,
940
+ function dt({
941
+ messages: e,
942
+ isLoading: t,
717
943
  error: r,
718
944
  canRetry: s = !1,
719
945
  onSend: n,
720
946
  onRetry: o,
721
- onClose: a,
722
- title: l = "Chat",
723
- subtitle: c = "Ask me anything",
724
- welcomeMessage: u = "Hi! How can I help you today?",
725
- placeholder: h,
726
- position: E = "bottom-right",
727
- translations: g,
728
- isMobile: x = !1
947
+ onClose: c,
948
+ title: a = "Chat",
949
+ subtitle: u = "Ask me anything",
950
+ welcomeMessage: l = "Hi! How can I help you today?",
951
+ placeholder: d,
952
+ position: R = "bottom-right",
953
+ translations: p,
954
+ isMobile: w = !1
729
955
  }) {
730
- const f = Re(), w = N(null), v = N(null), [y, T] = C(null);
731
- Xe(w, !0);
732
- const { offsetY: O } = Ke(
733
- v,
734
- a,
735
- x
736
- ), A = O !== 0, I = typeof window < "u" && typeof window.matchMedia == "function" ? window.matchMedia("(prefers-reduced-motion: reduce)").matches : !1;
737
- k(() => {
738
- const b = v.current;
739
- b && (b.scrollTop = b.scrollHeight);
740
- }, [t, e]), k(() => {
741
- const b = (j) => {
742
- j.key === "Escape" && !j.isComposing && a();
956
+ const y = Ce(), b = C(null), x = C(null), [v, N] = k(null);
957
+ ot(b, !0);
958
+ const { offsetY: E } = nt(
959
+ x,
960
+ c,
961
+ w
962
+ ), I = E !== 0, A = typeof window < "u" && typeof window.matchMedia == "function" ? window.matchMedia("(prefers-reduced-motion: reduce)").matches : !1;
963
+ H(() => {
964
+ const m = x.current;
965
+ m && (m.scrollTop = m.scrollHeight);
966
+ }, [e, t]), H(() => {
967
+ const m = (P) => {
968
+ P.key === "Escape" && !P.isComposing && c();
743
969
  };
744
- return document.addEventListener("keydown", b), () => document.removeEventListener("keydown", b);
745
- }, [a]);
746
- const M = (g == null ? void 0 : g.closeChat) ?? "Close chat", D = (g == null ? void 0 : g.chatMessages) ?? "Chat messages", _ = [...t].reverse().find((b) => b.role === "assistant");
747
- return /* @__PURE__ */ d(
970
+ return document.addEventListener("keydown", m), () => document.removeEventListener("keydown", m);
971
+ }, [c]);
972
+ const D = (p == null ? void 0 : p.closeChat) ?? "Close chat", S = (p == null ? void 0 : p.chatMessages) ?? "Chat messages", j = [...e].reverse().find((m) => m.role === "assistant");
973
+ return /* @__PURE__ */ h(
748
974
  "div",
749
975
  {
750
- ref: w,
976
+ ref: b,
751
977
  role: "dialog",
752
- "aria-modal": x ? "true" : void 0,
753
- "aria-labelledby": f,
754
- className: x ? "claudius-bottom-sheet fixed inset-x-0 bottom-0 z-50 flex h-[90vh] w-full flex-col overflow-hidden rounded-t-claudius-lg bg-claudius-surface shadow-claudius-elevated font-body" : `fixed ${rt[E]} z-50 flex h-[min(500px,calc(100vh-7rem))] w-[calc(100vw-1.5rem)] max-w-[380px] sm:max-w-[400px] md:max-w-[440px] flex-col overflow-hidden rounded-claudius-lg bg-claudius-surface shadow-claudius-elevated font-body`,
755
- style: x && !I ? { transform: `translateY(${Math.max(0, O)}px)` } : void 0,
756
- "data-dragging": A || void 0,
978
+ "aria-modal": w ? "true" : void 0,
979
+ "aria-labelledby": y,
980
+ className: w ? "claudius-bottom-sheet fixed inset-x-0 bottom-0 z-50 flex h-[90vh] w-full flex-col overflow-hidden rounded-t-claudius-lg bg-claudius-surface shadow-claudius-elevated font-body" : `fixed ${lt[R]} z-50 flex h-[min(500px,calc(100vh-7rem))] w-[calc(100vw-1.5rem)] max-w-[380px] sm:max-w-[400px] md:max-w-[440px] flex-col overflow-hidden rounded-claudius-lg bg-claudius-surface shadow-claudius-elevated font-body`,
981
+ style: w && !A ? { transform: `translateY(${Math.max(0, E)}px)` } : void 0,
982
+ "data-dragging": I || void 0,
757
983
  children: [
758
- x && /* @__PURE__ */ i("div", { className: "flex justify-center py-2", "aria-hidden": "true", children: /* @__PURE__ */ i("div", { className: "h-1 w-8 rounded-claudius-full bg-claudius-border" }) }),
759
- /* @__PURE__ */ d("div", { className: "flex items-center gap-3 bg-claudius-accent px-5 py-4", children: [
760
- /* @__PURE__ */ i(
761
- "div",
762
- {
763
- "aria-hidden": "true",
764
- className: "flex h-8 w-8 items-center justify-center rounded-claudius-full bg-claudius-accent-soft text-sm font-bold text-claudius-accent-text",
765
- children: l.charAt(0).toUpperCase()
766
- }
767
- ),
768
- /* @__PURE__ */ d("div", { className: "flex-1", children: [
769
- /* @__PURE__ */ i(
770
- "h2",
771
- {
772
- id: f,
773
- className: "text-sm font-heading font-semibold text-claudius-accent-text",
774
- children: l
775
- }
776
- ),
777
- /* @__PURE__ */ i("p", { className: "text-xs text-claudius-accent-text", children: c })
778
- ] }),
779
- /* @__PURE__ */ i(
780
- "button",
781
- {
782
- onClick: a,
783
- "aria-label": M,
784
- className: "flex h-10 w-10 items-center justify-center rounded-claudius-full text-claudius-accent-text-muted transition-colors hover:bg-claudius-accent-soft hover:text-claudius-accent-text",
785
- children: /* @__PURE__ */ d(
786
- "svg",
787
- {
788
- width: "18",
789
- height: "18",
790
- viewBox: "0 0 24 24",
791
- fill: "none",
792
- stroke: "currentColor",
793
- strokeWidth: "2",
794
- strokeLinecap: "round",
795
- strokeLinejoin: "round",
796
- "aria-hidden": "true",
797
- children: [
798
- /* @__PURE__ */ i("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
799
- /* @__PURE__ */ i("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
800
- ]
801
- }
802
- )
803
- }
804
- )
805
- ] }),
806
- /* @__PURE__ */ d("div", { className: "relative flex-1 overflow-hidden", children: [
807
- y && /* @__PURE__ */ i(
808
- Ve,
984
+ w && /* @__PURE__ */ i("div", { className: "flex justify-center py-2", "aria-hidden": "true", children: /* @__PURE__ */ i("div", { className: "h-1 w-8 rounded-claudius-full bg-claudius-border" }) }),
985
+ /* @__PURE__ */ i(
986
+ et,
987
+ {
988
+ title: a,
989
+ subtitle: u,
990
+ titleId: y,
991
+ closeLabel: D,
992
+ onClose: c
993
+ }
994
+ ),
995
+ /* @__PURE__ */ h("div", { className: "relative flex-1 overflow-hidden", children: [
996
+ v && /* @__PURE__ */ i(
997
+ Qe,
809
998
  {
810
- sources: y.sources,
811
- onClose: () => T(null)
999
+ sources: v.sources,
1000
+ onClose: () => N(null)
812
1001
  }
813
1002
  ),
814
- /* @__PURE__ */ d(
1003
+ /* @__PURE__ */ h(
815
1004
  "div",
816
1005
  {
817
- ref: v,
1006
+ ref: x,
818
1007
  role: "log",
819
- "aria-label": D,
1008
+ "aria-label": S,
820
1009
  className: "h-full space-y-3 overflow-y-auto px-4 py-4",
821
1010
  children: [
822
- t.length === 0 && !r && /* @__PURE__ */ i("div", { className: "mr-auto flex max-w-[85%]", children: /* @__PURE__ */ i("div", { className: "rounded-claudius-bubble rounded-bl-claudius-tail bg-claudius-assistant-bubble px-4 py-2.5 text-sm leading-relaxed text-claudius-assistant-bubble-text", children: u }) }),
823
- t.map((b) => /* @__PURE__ */ i(
824
- Ge,
1011
+ e.length === 0 && !r && /* @__PURE__ */ i("div", { className: "mr-auto flex max-w-[85%]", children: /* @__PURE__ */ i("div", { className: "rounded-claudius-bubble rounded-bl-claudius-tail bg-claudius-assistant-bubble px-4 py-2.5 text-sm leading-relaxed text-claudius-assistant-bubble-text", children: l }) }),
1012
+ e.map((m) => /* @__PURE__ */ i(
1013
+ Ve,
825
1014
  {
826
- role: b.role,
827
- content: b.content,
828
- sources: b.sources,
829
- isSourceActive: (y == null ? void 0 : y.messageId) === b.id,
1015
+ role: m.role,
1016
+ content: m.content,
1017
+ sources: m.sources,
1018
+ isSourceActive: (v == null ? void 0 : v.messageId) === m.id,
830
1019
  onSourceClick: () => {
831
- (y == null ? void 0 : y.messageId) === b.id ? T(null) : b.sources && b.sources.length > 0 && T({ messageId: b.id, sources: b.sources });
1020
+ (v == null ? void 0 : v.messageId) === m.id ? N(null) : m.sources && m.sources.length > 0 && N({ messageId: m.id, sources: m.sources });
832
1021
  }
833
1022
  },
834
- b.id
1023
+ m.id
835
1024
  )),
836
- e && /* @__PURE__ */ i(
837
- tt,
1025
+ t && /* @__PURE__ */ i(
1026
+ rt,
838
1027
  {
839
- label: (g == null ? void 0 : g.typingIndicator) ?? "Assistant is typing"
1028
+ label: (p == null ? void 0 : p.typingIndicator) ?? "Assistant is typing"
840
1029
  }
841
1030
  ),
842
- r && /* @__PURE__ */ d(
843
- "div",
1031
+ r && /* @__PURE__ */ i(
1032
+ tt,
844
1033
  {
845
- role: "alert",
846
- className: "mx-auto flex max-w-[90%] flex-col items-center gap-2 rounded-claudius-sm bg-claudius-error-surface px-3 py-2 text-center text-xs text-claudius-error",
847
- children: [
848
- /* @__PURE__ */ i("span", { children: r }),
849
- s && o && !e && /* @__PURE__ */ i(
850
- "button",
851
- {
852
- type: "button",
853
- onClick: o,
854
- className: "rounded-claudius-md bg-claudius-error px-3 py-1 text-xs font-semibold text-claudius-error-text transition-opacity hover:opacity-90 focus:outline-none focus-visible:ring-2 focus-visible:ring-claudius-error focus-visible:ring-offset-1",
855
- children: (g == null ? void 0 : g.errorRetry) ?? "Retry"
856
- }
857
- )
858
- ]
1034
+ message: r,
1035
+ retryLabel: (p == null ? void 0 : p.errorRetry) ?? "Retry",
1036
+ onRetry: s && o && !t ? o : void 0
859
1037
  }
860
1038
  )
861
1039
  ]
@@ -869,51 +1047,51 @@ function nt({
869
1047
  "aria-live": "polite",
870
1048
  "aria-atomic": "true",
871
1049
  className: "sr-only",
872
- children: _ ? et(_.content) : ""
1050
+ children: j ? ut(j.content) : ""
873
1051
  }
874
1052
  ),
875
1053
  /* @__PURE__ */ i(
876
- We,
1054
+ qe,
877
1055
  {
878
1056
  onSend: n,
879
- isLoading: e,
880
- placeholder: h,
881
- translations: g
1057
+ isLoading: t,
1058
+ placeholder: d,
1059
+ translations: p
882
1060
  }
883
1061
  )
884
1062
  ]
885
1063
  }
886
1064
  );
887
1065
  }
888
- function st({
889
- message: t,
890
- position: e,
1066
+ function ft({
1067
+ message: e,
1068
+ position: t,
891
1069
  onOpen: r,
892
1070
  onDismiss: s,
893
1071
  dismissLabel: n
894
1072
  }) {
895
- const o = e.startsWith("bottom"), a = e.endsWith("right"), l = [
1073
+ const o = t.startsWith("bottom"), c = t.endsWith("right"), a = [
896
1074
  "claudius-greeting-bubble",
897
1075
  "fixed z-40 max-w-xs",
898
1076
  o ? "bottom-20" : "top-20",
899
- a ? "right-4" : "left-4"
1077
+ c ? "right-4" : "left-4"
900
1078
  ].join(" ");
901
- return /* @__PURE__ */ d("div", { className: l, role: "status", "aria-live": "polite", children: [
1079
+ return /* @__PURE__ */ h("div", { className: a, role: "status", "aria-live": "polite", children: [
902
1080
  /* @__PURE__ */ i(
903
1081
  "button",
904
1082
  {
905
1083
  type: "button",
906
1084
  onClick: r,
907
1085
  className: "block w-full rounded-claudius-lg bg-claudius-surface p-4 pr-8 text-left text-sm font-body text-claudius-text shadow-claudius-floating ring-1 ring-claudius-border transition hover:shadow-claudius-floating-hover focus:outline-none focus:ring-2 focus:ring-claudius-accent",
908
- children: t
1086
+ children: e
909
1087
  }
910
1088
  ),
911
1089
  /* @__PURE__ */ i(
912
1090
  "button",
913
1091
  {
914
1092
  type: "button",
915
- onClick: (c) => {
916
- c.stopPropagation(), s();
1093
+ onClick: (u) => {
1094
+ u.stopPropagation(), s();
917
1095
  },
918
1096
  "aria-label": n,
919
1097
  className: "absolute right-1 top-1 flex h-6 w-6 items-center justify-center rounded-claudius-full text-claudius-text-muted hover:bg-claudius-surface-muted focus:outline-none focus:ring-2 focus:ring-claudius-accent",
@@ -922,7 +1100,7 @@ function st({
922
1100
  )
923
1101
  ] });
924
1102
  }
925
- const ie = {
1103
+ const de = {
926
1104
  // ChatWindow
927
1105
  title: "Chat",
928
1106
  subtitle: "Ask me anything",
@@ -945,11 +1123,11 @@ const ie = {
945
1123
  errorRateLimitMinute: "Too many requests. Please wait a minute.",
946
1124
  errorRateLimitHour: "Hourly limit reached. Please try again later.",
947
1125
  errorRetry: "Retry"
948
- }, ot = ie;
949
- function Nt(t) {
950
- return { ...ot, ...t };
1126
+ }, ht = de;
1127
+ function $t(e) {
1128
+ return { ...ht, ...e };
951
1129
  }
952
- const it = {
1130
+ const mt = {
953
1131
  // ChatWindow
954
1132
  title: "Chat",
955
1133
  subtitle: "Pregúntame lo que quieras",
@@ -972,7 +1150,7 @@ const it = {
972
1150
  errorRateLimitMinute: "Demasiadas solicitudes. Espera un minuto.",
973
1151
  errorRateLimitHour: "Has alcanzado el límite por hora. Inténtalo más tarde.",
974
1152
  errorRetry: "Reintentar"
975
- }, at = {
1153
+ }, gt = {
976
1154
  // ChatWindow
977
1155
  title: "Chat",
978
1156
  subtitle: "Posez-moi vos questions",
@@ -995,7 +1173,7 @@ const it = {
995
1173
  errorRateLimitMinute: "Trop de requêtes. Veuillez patienter une minute.",
996
1174
  errorRateLimitHour: "Limite horaire atteinte. Veuillez réessayer plus tard.",
997
1175
  errorRetry: "Réessayer"
998
- }, ct = {
1176
+ }, pt = {
999
1177
  // ChatWindow
1000
1178
  title: "Chat",
1001
1179
  subtitle: "Fragen Sie mich alles",
@@ -1018,28 +1196,28 @@ const it = {
1018
1196
  errorRateLimitMinute: "Zu viele Anfragen. Bitte warten Sie eine Minute.",
1019
1197
  errorRateLimitHour: "Stündliches Limit erreicht. Bitte versuchen Sie es später erneut.",
1020
1198
  errorRetry: "Erneut versuchen"
1021
- }, ae = {
1022
- en: ie,
1023
- es: it,
1024
- fr: at,
1025
- de: ct
1199
+ }, fe = {
1200
+ en: de,
1201
+ es: mt,
1202
+ fr: gt,
1203
+ de: pt
1026
1204
  };
1027
- function re(t) {
1028
- if (!t) return;
1029
- const e = t.toLowerCase().split("-")[0];
1030
- return Object.prototype.hasOwnProperty.call(ae, e) ? e : void 0;
1205
+ function ie(e) {
1206
+ if (!e) return;
1207
+ const t = e.toLowerCase().split("-")[0];
1208
+ return Object.prototype.hasOwnProperty.call(fe, t) ? t : void 0;
1031
1209
  }
1032
- function ut() {
1033
- const t = typeof document < "u" ? re(document.documentElement.lang) : void 0;
1034
- if (t) return t;
1035
- const e = typeof navigator < "u" ? re(navigator.language) : void 0;
1036
- return e || "en";
1210
+ function bt() {
1211
+ const e = typeof document < "u" ? ie(document.documentElement.lang) : void 0;
1212
+ if (e) return e;
1213
+ const t = typeof navigator < "u" ? ie(navigator.language) : void 0;
1214
+ return t || "en";
1037
1215
  }
1038
- function lt(t = {}) {
1039
- const { locale: e, translations: r } = t, s = ae[e ?? ut()];
1216
+ function yt(e = {}) {
1217
+ const { locale: t, translations: r } = e, s = fe[t ?? bt()];
1040
1218
  return r ? { ...s, ...r } : { ...s };
1041
1219
  }
1042
- const ne = [
1220
+ const ce = [
1043
1221
  "accent",
1044
1222
  "accentText",
1045
1223
  "accentSoft",
@@ -1059,11 +1237,11 @@ const ne = [
1059
1237
  "errorText",
1060
1238
  "link",
1061
1239
  "scrim"
1062
- ], dt = ["sm", "md", "lg", "full", "tail"], ht = [
1240
+ ], xt = ["sm", "md", "lg", "full", "tail"], wt = [
1063
1241
  "elevated",
1064
1242
  "floating",
1065
1243
  "floatingHover"
1066
- ], ft = ["heading", "body"], ce = {
1244
+ ], vt = ["heading", "body"], he = {
1067
1245
  default: {
1068
1246
  name: "default"
1069
1247
  },
@@ -1148,226 +1326,311 @@ const ne = [
1148
1326
  }
1149
1327
  }
1150
1328
  };
1151
- function mt(t) {
1152
- return Object.prototype.hasOwnProperty.call(ce, t);
1329
+ function Et(e) {
1330
+ return Object.prototype.hasOwnProperty.call(he, e);
1153
1331
  }
1154
- const gt = /* @__PURE__ */ new Set(["light", "dark", "auto"]);
1155
- function bt(t) {
1156
- if (t === void 0)
1332
+ const Rt = /* @__PURE__ */ new Set(["light", "dark", "auto"]);
1333
+ function Tt(e) {
1334
+ if (e === void 0)
1157
1335
  return { mode: "light" };
1158
- if (typeof t == "string") {
1159
- if (gt.has(t))
1160
- return { mode: t };
1161
- if (mt(t)) {
1162
- const e = ce[t];
1163
- return { mode: e.colorScheme ?? "light", theme: e };
1336
+ if (typeof e == "string") {
1337
+ if (Rt.has(e))
1338
+ return { mode: e };
1339
+ if (Et(e)) {
1340
+ const t = he[e];
1341
+ return { mode: t.colorScheme ?? "light", theme: t };
1164
1342
  }
1165
- return { mode: "light", url: t };
1343
+ return { mode: "light", url: e };
1166
1344
  }
1167
- return { mode: t.colorScheme ?? "light", theme: t };
1345
+ return { mode: e.colorScheme ?? "light", theme: e };
1168
1346
  }
1169
- function pt(t) {
1170
- return t.replace(/[A-Z]/g, (e) => `-${e.toLowerCase()}`);
1347
+ function Mt(e) {
1348
+ return e.replace(/[A-Z]/g, (t) => `-${t.toLowerCase()}`);
1171
1349
  }
1172
- function xt(t, e) {
1350
+ function Ct(e, t) {
1173
1351
  console.warn(
1174
- `[Claudius] Ignoring unknown theme token "${e}" in "${t}"`
1352
+ `[Claudius] Ignoring unknown theme token "${t}" in "${e}"`
1175
1353
  );
1176
1354
  }
1177
- function B(t, e, r, s, n, o = "") {
1355
+ function W(e, t, r, s, n, o = "") {
1178
1356
  if (n)
1179
- for (const [a, l] of Object.entries(n)) {
1180
- if (!s.includes(a)) {
1181
- xt(e, a);
1357
+ for (const [c, a] of Object.entries(n)) {
1358
+ if (!s.includes(c)) {
1359
+ Ct(t, c);
1182
1360
  continue;
1183
1361
  }
1184
- typeof l == "string" && (t[`${r}${pt(a)}${o}`] = l);
1362
+ typeof a == "string" && (e[`${r}${Mt(c)}${o}`] = a);
1185
1363
  }
1186
1364
  }
1187
- function yt(t) {
1188
- const e = {};
1189
- B(e, "colors", "--cl-color-", ne, t.colors);
1190
- for (const [r, s] of Object.entries({ ...e }))
1191
- e[`${r}-dark`] = s;
1192
- return B(
1193
- e,
1365
+ function Nt(e) {
1366
+ const t = {};
1367
+ W(t, "colors", "--cl-color-", ce, e.colors);
1368
+ for (const [r, s] of Object.entries({ ...t }))
1369
+ t[`${r}-dark`] = s;
1370
+ return W(
1371
+ t,
1194
1372
  "colorsDark",
1195
1373
  "--cl-color-",
1196
- ne,
1197
- t.colorsDark,
1374
+ ce,
1375
+ e.colorsDark,
1198
1376
  "-dark"
1199
- ), B(e, "radii", "--cl-radius-", dt, t.radii), B(e, "shadows", "--cl-shadow-", ht, t.shadows), B(e, "fonts", "--cl-font-", ft, t.fonts), e;
1377
+ ), W(t, "radii", "--cl-radius-", xt, e.radii), W(t, "shadows", "--cl-shadow-", wt, e.shadows), W(t, "fonts", "--cl-font-", vt, e.fonts), t;
1200
1378
  }
1201
- function wt(t) {
1202
- return typeof t == "object" && t !== null && !Array.isArray(t);
1379
+ function St(e) {
1380
+ return typeof e == "object" && e !== null && !Array.isArray(e);
1203
1381
  }
1204
- function vt(t) {
1205
- const e = F(() => bt(t), [t]), [r, s] = C(null), n = e.url;
1206
- k(() => {
1382
+ function Lt(e) {
1383
+ const t = Y(() => Tt(e), [e]), [r, s] = k(null), n = t.url;
1384
+ H(() => {
1207
1385
  if (s(null), !n) return;
1208
- const c = new AbortController();
1209
- return fetch(n, { signal: c.signal }).then((u) => {
1210
- if (!u.ok)
1211
- throw new Error(`HTTP ${u.status}`);
1212
- return u.json();
1213
- }).then((u) => {
1214
- if (!wt(u))
1386
+ const u = new AbortController();
1387
+ return fetch(n, { signal: u.signal }).then((l) => {
1388
+ if (!l.ok)
1389
+ throw new Error(`HTTP ${l.status}`);
1390
+ return l.json();
1391
+ }).then((l) => {
1392
+ if (!St(l))
1215
1393
  throw new Error("theme JSON must be an object");
1216
- s(u);
1217
- }).catch((u) => {
1218
- c.signal.aborted || console.error(`[Claudius] Failed to load theme from ${n}:`, u);
1219
- }), () => c.abort();
1394
+ s(l);
1395
+ }).catch((l) => {
1396
+ u.signal.aborted || console.error(`[Claudius] Failed to load theme from ${n}:`, l);
1397
+ }), () => u.abort();
1220
1398
  }, [n]);
1221
- const o = e.theme ?? r ?? null, a = (r == null ? void 0 : r.colorScheme) ?? e.mode, l = F(
1222
- () => o ? yt(o) : {},
1399
+ const o = t.theme ?? r ?? null, c = (r == null ? void 0 : r.colorScheme) ?? t.mode, a = Y(
1400
+ () => o ? Nt(o) : {},
1223
1401
  [o]
1224
1402
  );
1225
- return { mode: a, cssVars: l };
1403
+ return { mode: c, cssVars: a };
1226
1404
  }
1227
- const ue = "claudius:triggers:dismissed";
1228
- function Et() {
1405
+ const me = "claudius:triggers:dismissed";
1406
+ function kt() {
1229
1407
  if (typeof window > "u") return !1;
1230
1408
  try {
1231
- return window.sessionStorage.getItem(ue) === "1";
1409
+ return window.sessionStorage.getItem(me) === "1";
1232
1410
  } catch {
1233
1411
  return !1;
1234
1412
  }
1235
1413
  }
1236
- function Rt() {
1414
+ function At() {
1237
1415
  if (!(typeof window > "u"))
1238
1416
  try {
1239
- window.sessionStorage.setItem(ue, "1");
1417
+ window.sessionStorage.setItem(me, "1");
1240
1418
  } catch {
1241
1419
  }
1242
1420
  }
1243
- function St({
1244
- apiUrl: t,
1245
- title: e,
1421
+ function jt({
1422
+ apiUrl: e,
1423
+ title: t,
1246
1424
  subtitle: r,
1247
1425
  welcomeMessage: s,
1248
1426
  placeholder: n,
1249
1427
  persistMessages: o,
1250
- storageKeyPrefix: a,
1251
- requestTimeoutMs: l,
1252
- theme: c = "light",
1253
- accentColor: u,
1254
- position: h = "bottom-right",
1255
- locale: E,
1256
- translations: g,
1257
- triggers: x
1428
+ storageKeyPrefix: c,
1429
+ requestTimeoutMs: a,
1430
+ theme: u = "light",
1431
+ accentColor: l,
1432
+ position: d = "bottom-right",
1433
+ locale: R,
1434
+ translations: p,
1435
+ triggers: w,
1436
+ plugins: y
1258
1437
  }) {
1259
- const [f, w] = C(!1), [v, y] = C(null), [T, O] = C(Et), A = N(!1), I = Oe("(max-width: 639px)"), M = F(
1260
- () => lt({ locale: E, translations: g }),
1261
- [E, g]
1262
- ), { messages: D, isLoading: _, error: b, canRetry: j, sendMessage: m, retry: p } = ke({
1263
- apiUrl: t,
1438
+ const [b, x] = k(!1), [v, N] = k(null), [E, I] = k(kt), A = C(!1), D = Be("(max-width: 639px)"), S = Y(
1439
+ () => yt({ locale: R, translations: p }),
1440
+ [R, p]
1441
+ ), { messages: j, isLoading: m, error: P, canRetry: V, sendMessage: K, retry: f } = He({
1442
+ apiUrl: e,
1264
1443
  persistMessages: o,
1265
- storageKeyPrefix: a,
1266
- timeoutMs: l,
1267
- translations: M
1268
- }), H = N(null), S = N(f), { mode: G, cssVars: le } = vt(c), [de, q] = C(!1);
1269
- k(() => {
1270
- if (G !== "auto") return;
1271
- const L = window.matchMedia("(prefers-color-scheme: dark)");
1272
- q(L.matches);
1273
- const Z = (xe) => q(xe.matches);
1274
- return L.addEventListener("change", Z), () => L.removeEventListener("change", Z);
1275
- }, [G]), k(() => {
1276
- var L;
1277
- S.current && !f && ((L = H.current) == null || L.focus()), S.current = f;
1278
- }, [f]);
1279
- const P = R(() => {
1280
- O(!0), Rt();
1281
- }, []), X = R(() => {
1282
- w(!1), A.current && (A.current = !1, P());
1283
- }, [P]), he = R(() => {
1284
- w((L) => !L);
1285
- }, []), Y = R(() => {
1286
- A.current = !0, y(null), w(!0);
1287
- }, []), fe = R((L) => {
1288
- y(L);
1289
- }, []), me = R(() => {
1290
- y(null), Y();
1291
- }, [Y]), ge = R(() => {
1292
- y(null), P();
1293
- }, [P]);
1294
- Ie({
1295
- triggers: x,
1296
- enabled: !T && !f,
1297
- onOpen: Y,
1298
- onGreeting: fe
1444
+ storageKeyPrefix: c,
1445
+ timeoutMs: a,
1446
+ translations: S,
1447
+ plugins: y
1448
+ }), g = C(null), L = C(b), { mode: T, cssVars: B } = Lt(u), [O, z] = k(!1);
1449
+ H(() => {
1450
+ if (T !== "auto") return;
1451
+ const _ = window.matchMedia("(prefers-color-scheme: dark)");
1452
+ z(_.matches);
1453
+ const re = (ve) => z(ve.matches);
1454
+ return _.addEventListener("change", re), () => _.removeEventListener("change", re);
1455
+ }, [T]), H(() => {
1456
+ var _;
1457
+ L.current && !b && ((_ = g.current) == null || _.focus()), L.current = b;
1458
+ }, [b]);
1459
+ const $ = M(() => {
1460
+ I(!0), At();
1461
+ }, []), ee = M(() => {
1462
+ x(!1), A.current && (A.current = !1, $());
1463
+ }, [$]), ge = M(() => {
1464
+ x((_) => !_);
1465
+ }, []), q = M(() => {
1466
+ A.current = !0, N(null), x(!0);
1467
+ }, []), pe = M((_) => {
1468
+ N(_);
1469
+ }, []), be = M(() => {
1470
+ N(null), q();
1471
+ }, [q]), ye = M(() => {
1472
+ N(null), $();
1473
+ }, [$]);
1474
+ je({
1475
+ triggers: w,
1476
+ enabled: !E && !b,
1477
+ onOpen: q,
1478
+ onGreeting: pe
1299
1479
  });
1300
- const be = G === "dark" || G === "auto" && de, J = {
1301
- ...le,
1302
- ...u ? {
1303
- "--cl-color-accent": u,
1304
- "--cl-color-accent-dark": u
1480
+ const xe = T === "dark" || T === "auto" && O, te = {
1481
+ ...B,
1482
+ ...l ? {
1483
+ "--cl-color-accent": l,
1484
+ "--cl-color-accent-dark": l
1305
1485
  } : {}
1306
- }, pe = Object.keys(J).length > 0 ? J : void 0;
1486
+ }, we = Object.keys(te).length > 0 ? te : void 0;
1307
1487
  return (
1308
1488
  // Outer div carries theme token vars; the inner div carries the dark-mode
1309
1489
  // attribute so the [data-claudius-dark] token reassignments in styles.css
1310
1490
  // beat inherited (inline) light values.
1311
- /* @__PURE__ */ i("div", { className: "claudius-root", style: pe, children: /* @__PURE__ */ d("div", { "data-claudius-dark": be ? "true" : "false", children: [
1312
- f && I && /* @__PURE__ */ i(
1491
+ /* @__PURE__ */ i("div", { className: "claudius-root", style: we, children: /* @__PURE__ */ h("div", { "data-claudius-dark": xe ? "true" : "false", children: [
1492
+ b && D && /* @__PURE__ */ i(
1313
1493
  "div",
1314
1494
  {
1315
1495
  className: "claudius-scrim fixed inset-0 z-40 bg-claudius-scrim",
1316
- onClick: X,
1496
+ onClick: ee,
1317
1497
  "aria-hidden": "true"
1318
1498
  }
1319
1499
  ),
1320
- f && /* @__PURE__ */ i(
1321
- nt,
1500
+ b && /* @__PURE__ */ i(
1501
+ dt,
1322
1502
  {
1323
- messages: D,
1324
- isLoading: _,
1325
- error: b,
1326
- canRetry: j,
1327
- onSend: m,
1328
- onRetry: p,
1329
- onClose: X,
1330
- title: e ?? M.title,
1331
- subtitle: r ?? M.subtitle,
1332
- welcomeMessage: s ?? M.welcomeMessage,
1333
- placeholder: n ?? M.placeholder,
1334
- position: h,
1335
- translations: M,
1336
- isMobile: I
1503
+ messages: j,
1504
+ isLoading: m,
1505
+ error: P,
1506
+ canRetry: V,
1507
+ onSend: K,
1508
+ onRetry: f,
1509
+ onClose: ee,
1510
+ title: t ?? S.title,
1511
+ subtitle: r ?? S.subtitle,
1512
+ welcomeMessage: s ?? S.welcomeMessage,
1513
+ placeholder: n ?? S.placeholder,
1514
+ position: d,
1515
+ translations: S,
1516
+ isMobile: D
1337
1517
  }
1338
1518
  ),
1339
- !(f && I) && /* @__PURE__ */ i(
1340
- He,
1519
+ !(b && D) && /* @__PURE__ */ i(
1520
+ Ge,
1341
1521
  {
1342
- ref: H,
1343
- isOpen: f,
1344
- onClick: he,
1345
- position: h,
1346
- translations: M
1522
+ ref: g,
1523
+ isOpen: b,
1524
+ onClick: ge,
1525
+ position: d,
1526
+ translations: S
1347
1527
  }
1348
1528
  ),
1349
- !f && v && /* @__PURE__ */ i(
1350
- st,
1529
+ !b && v && /* @__PURE__ */ i(
1530
+ ft,
1351
1531
  {
1352
1532
  message: v,
1353
- position: h,
1354
- onOpen: me,
1355
- onDismiss: ge,
1356
- dismissLabel: M.dismissGreeting
1533
+ position: d,
1534
+ onOpen: be,
1535
+ onDismiss: ye,
1536
+ dismissLabel: S.dismissGreeting
1357
1537
  }
1358
1538
  )
1359
1539
  ] }) })
1360
1540
  );
1361
1541
  }
1542
+ function Pt(e) {
1543
+ const { onEvent: t, includeContent: r = !0 } = e, s = (n) => r ? n : "";
1544
+ return {
1545
+ name: "analytics",
1546
+ onBeforeSend(n) {
1547
+ t({
1548
+ type: "message_sent",
1549
+ role: "user",
1550
+ content: s(n.content),
1551
+ chars: n.content.length
1552
+ });
1553
+ },
1554
+ onAfterReceive(n) {
1555
+ t({
1556
+ type: "message_received",
1557
+ role: "assistant",
1558
+ content: s(n.content),
1559
+ chars: n.content.length
1560
+ });
1561
+ },
1562
+ onError(n) {
1563
+ t({
1564
+ type: "chat_error",
1565
+ message: n.message,
1566
+ code: n.code
1567
+ });
1568
+ }
1569
+ };
1570
+ }
1571
+ const Ot = [
1572
+ // Email
1573
+ /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b/g,
1574
+ // US SSN (before the looser card pattern so it wins on 9-digit groups)
1575
+ /\b\d{3}-\d{2}-\d{4}\b/g,
1576
+ // Card-like: 13–16 digits, optionally separated by spaces or hyphens
1577
+ /\b(?:\d[ -]?){13,16}\b/g,
1578
+ // Phone: optional +1, area code, 7 digits with common separators
1579
+ /\b(?:\+?1[-.\s]?)?\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}\b/g
1580
+ ];
1581
+ function It(e, t, r) {
1582
+ return t.reduce(
1583
+ // Reset lastIndex defensively: a shared global regex is stateful.
1584
+ (s, n) => (n.lastIndex = 0, s.replace(n, r)),
1585
+ e
1586
+ );
1587
+ }
1588
+ function Gt(e = {}) {
1589
+ const {
1590
+ patterns: t = Ot,
1591
+ replacement: r = "[redacted]",
1592
+ redactReplies: s = !1
1593
+ } = e, n = (o) => {
1594
+ const c = It(o.content, t, r);
1595
+ if (c !== o.content)
1596
+ return { ...o, content: c };
1597
+ };
1598
+ return {
1599
+ name: "redact-pii",
1600
+ onBeforeSend: n,
1601
+ onAfterReceive: s ? n : void 0
1602
+ };
1603
+ }
1604
+ function Dt(e, t, r) {
1605
+ return typeof e == "function" ? e(t) : e instanceof RegExp ? e.test(t) : r ? t.includes(e) : t.toLowerCase().includes(e.toLowerCase());
1606
+ }
1607
+ function Ut(e) {
1608
+ const { rules: t, caseSensitive: r = !1 } = e;
1609
+ return {
1610
+ name: "canned-responses",
1611
+ onBeforeSend(s, n) {
1612
+ for (const o of t)
1613
+ if (Dt(o.match, s.content, r)) {
1614
+ n.respondWith(o.reply);
1615
+ return;
1616
+ }
1617
+ }
1618
+ };
1619
+ }
1362
1620
  export {
1363
- Me as ChatApiClient,
1621
+ Se as ChatApiClient,
1364
1622
  U as ChatApiError,
1365
- St as ChatWidget,
1366
- se as DebounceError,
1367
- ce as builtinThemes,
1368
- Nt as createTranslations,
1369
- ot as defaultTranslations,
1370
- ut as detectLocale,
1371
- ae as locales,
1372
- lt as resolveTranslations
1623
+ jt as ChatWidget,
1624
+ Ot as DEFAULT_PII_PATTERNS,
1625
+ ae as DebounceError,
1626
+ he as builtinThemes,
1627
+ $t as createTranslations,
1628
+ ht as defaultTranslations,
1629
+ bt as detectLocale,
1630
+ fe as locales,
1631
+ Pt as pluginAnalytics,
1632
+ Ut as pluginCannedResponses,
1633
+ Gt as pluginRedactPII,
1634
+ It as redactText,
1635
+ yt as resolveTranslations
1373
1636
  };