claudius-chat-widget 1.16.0 → 1.17.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/dist/claudius.js CHANGED
@@ -1,9 +1,9 @@
1
- var Ke = Object.defineProperty;
2
- var Ye = (e, t, n) => t in e ? Ke(e, t, { enumerable: !0, configurable: !0, writable: !0, value: n }) : e[t] = n;
3
- var oe = (e, t, n) => Ye(e, typeof t != "symbol" ? t + "" : t, n);
4
- import { jsx as i, jsxs as p, Fragment as we } from "react/jsx-runtime";
5
- import { useMemo as ae, useState as O, useRef as L, useCallback as M, useEffect as K, forwardRef as qe, memo as ge, useId as Qe } from "react";
6
- class V extends Error {
1
+ var dt = Object.defineProperty;
2
+ var ft = (e, t, n) => t in e ? dt(e, t, { enumerable: !0, configurable: !0, writable: !0, value: n }) : e[t] = n;
3
+ var he = (e, t, n) => ft(e, typeof t != "symbol" ? t + "" : t, n);
4
+ import { jsx as i, jsxs as w, Fragment as ve } from "react/jsx-runtime";
5
+ import { useMemo as se, useState as N, useRef as S, useCallback as M, useEffect as W, forwardRef as Je, memo as ke, useId as Ne } from "react";
6
+ class Z extends Error {
7
7
  /**
8
8
  * Create a {@link ChatApiError}.
9
9
  *
@@ -12,23 +12,23 @@ class V extends Error {
12
12
  * @param code - Optional machine-readable error code (e.g. `"TIMEOUT"`, `"NETWORK_ERROR"`).
13
13
  * @param retryAfter - Seconds to wait before retrying, from the `Retry-After` header.
14
14
  */
15
- constructor(t, n, r, s) {
16
- super(t), this.status = n, this.code = r, this.retryAfter = s, this.name = "ChatApiError";
15
+ constructor(t, n, r, o) {
16
+ super(t), this.status = n, this.code = r, this.retryAfter = o, this.name = "ChatApiError";
17
17
  }
18
18
  }
19
- class ye extends Error {
19
+ class De extends Error {
20
20
  /** Creates a `DebounceError` with a fixed message. */
21
21
  constructor() {
22
22
  super("Request debounced"), this.name = "DebounceError";
23
23
  }
24
24
  }
25
- const Ze = 3e4;
26
- function Je(e, t) {
25
+ const ht = 3e4;
26
+ function pt(e, t) {
27
27
  const n = atob(e), r = new Uint8Array(n.length);
28
- for (let s = 0; s < n.length; s++) r[s] = n.charCodeAt(s);
28
+ for (let o = 0; o < n.length; o++) r[o] = n.charCodeAt(o);
29
29
  return new Blob([r], { type: t });
30
30
  }
31
- class Xe {
31
+ class mt {
32
32
  /**
33
33
  * Create a chat client for the given Worker base URL.
34
34
  *
@@ -36,12 +36,12 @@ class Xe {
36
36
  * @param options - Optional retry, debounce, and timeout settings.
37
37
  */
38
38
  constructor(t, n) {
39
- oe(this, "baseUrl");
40
- oe(this, "maxRetries");
41
- oe(this, "debounceMs");
42
- oe(this, "timeoutMs");
43
- oe(this, "lastSendTime", 0);
44
- this.baseUrl = t, this.maxRetries = (n == null ? void 0 : n.maxRetries) ?? 2, this.debounceMs = (n == null ? void 0 : n.debounceMs) ?? 300, this.timeoutMs = (n == null ? void 0 : n.timeoutMs) ?? Ze;
39
+ he(this, "baseUrl");
40
+ he(this, "maxRetries");
41
+ he(this, "debounceMs");
42
+ he(this, "timeoutMs");
43
+ he(this, "lastSendTime", 0);
44
+ this.baseUrl = t, this.maxRetries = (n == null ? void 0 : n.maxRetries) ?? 2, this.debounceMs = (n == null ? void 0 : n.debounceMs) ?? 300, this.timeoutMs = (n == null ? void 0 : n.timeoutMs) ?? ht;
45
45
  }
46
46
  /**
47
47
  * Send the conversation to the chat endpoint and return the assistant's
@@ -55,41 +55,41 @@ class Xe {
55
55
  */
56
56
  async sendMessage(t) {
57
57
  if (this.debounceMs > 0 && Date.now() - this.lastSendTime < this.debounceMs)
58
- throw new ye();
58
+ throw new De();
59
59
  this.lastSendTime = Date.now();
60
60
  let n;
61
61
  for (let r = 0; r <= this.maxRetries; r++)
62
62
  try {
63
- const s = await this.fetchWithTimeout(t);
64
- if (s.ok)
65
- return await s.json();
66
- const o = await s.json().catch(() => ({})), a = s.headers.get("Retry-After"), c = a ? Number(a) : void 0;
67
- if (n = new V(
68
- o.error ?? `Request failed with status ${s.status}`,
69
- s.status,
70
- o.code,
63
+ const o = await this.fetchWithTimeout(t);
64
+ if (o.ok)
65
+ return await o.json();
66
+ const s = await o.json().catch(() => ({})), a = o.headers.get("Retry-After"), c = a ? Number(a) : void 0;
67
+ if (n = new Z(
68
+ s.error ?? `Request failed with status ${o.status}`,
69
+ o.status,
70
+ s.code,
71
71
  c
72
- ), !this.isRetryable(s.status))
72
+ ), !this.isRetryable(o.status))
73
73
  throw n;
74
74
  if (r < this.maxRetries) {
75
- const u = this.getRetryDelay(s, r);
76
- await this.delay(u);
75
+ const l = this.getRetryDelay(o, r);
76
+ await this.delay(l);
77
77
  }
78
- } catch (s) {
79
- if (s instanceof V) {
80
- if (!this.isRetryable(s.status, s.code))
81
- throw s;
82
- if (n = s, r < this.maxRetries) {
83
- const o = this.getRetryDelay(null, r);
84
- await this.delay(o);
78
+ } catch (o) {
79
+ if (o instanceof Z) {
80
+ if (!this.isRetryable(o.status, o.code))
81
+ throw o;
82
+ if (n = o, r < this.maxRetries) {
83
+ const s = this.getRetryDelay(null, r);
84
+ await this.delay(s);
85
85
  }
86
- } else if (n = new V(
86
+ } else if (n = new Z(
87
87
  "Failed to connect. Please try again.",
88
88
  0,
89
89
  "NETWORK_ERROR"
90
90
  ), r < this.maxRetries) {
91
- const o = this.getRetryDelay(null, r);
92
- await this.delay(o);
91
+ const s = this.getRetryDelay(null, r);
92
+ await this.delay(s);
93
93
  }
94
94
  }
95
95
  throw n;
@@ -101,26 +101,26 @@ class Xe {
101
101
  */
102
102
  buildRequest(t) {
103
103
  if (!t.some(
104
- (o) => {
104
+ (s) => {
105
105
  var a;
106
- return (a = o.attachments) == null ? void 0 : a.some((c) => !!c.data);
106
+ return (a = s.attachments) == null ? void 0 : a.some((c) => !!c.data);
107
107
  }
108
108
  ))
109
109
  return {
110
110
  headers: { "Content-Type": "application/json" },
111
111
  body: JSON.stringify({ messages: t })
112
112
  };
113
- const r = new FormData(), s = t.map((o) => o.attachments ? {
114
- ...o,
115
- attachments: o.attachments.map((a) => {
113
+ const r = new FormData(), o = t.map((s) => s.attachments ? {
114
+ ...s,
115
+ attachments: s.attachments.map((a) => {
116
116
  const c = { ...a };
117
117
  return delete c.data, c;
118
118
  })
119
- } : o);
120
- r.append("payload", JSON.stringify({ messages: s }));
121
- for (const o of t)
122
- for (const a of o.attachments ?? [])
123
- a.data && r.append(a.id, Je(a.data, a.mediaType), a.name);
119
+ } : s);
120
+ r.append("payload", JSON.stringify({ messages: o }));
121
+ for (const s of t)
122
+ for (const a of s.attachments ?? [])
123
+ a.data && r.append(a.id, pt(a.data, a.mediaType), a.name);
124
124
  return { body: r };
125
125
  }
126
126
  /**
@@ -144,41 +144,41 @@ class Xe {
144
144
  * the stream errors or is interrupted mid-reply (code `"STREAM_ERROR"`).
145
145
  */
146
146
  async streamMessage(t, n = {}) {
147
- var s;
147
+ var o;
148
148
  if (typeof ReadableStream > "u")
149
149
  return this.sendMessage(t);
150
150
  if (this.debounceMs > 0 && Date.now() - this.lastSendTime < this.debounceMs)
151
- throw new ye();
151
+ throw new De();
152
152
  this.lastSendTime = Date.now();
153
153
  let r;
154
- for (let o = 0; o <= this.maxRetries; o++) {
154
+ for (let s = 0; s <= this.maxRetries; s++) {
155
155
  let a;
156
156
  try {
157
157
  a = await this.fetchStream(t, n.signal);
158
- } catch (u) {
159
- if ((s = n.signal) != null && s.aborted)
158
+ } catch (l) {
159
+ if ((o = n.signal) != null && o.aborted)
160
160
  return { reply: "", aborted: !0 };
161
- if (r = u instanceof V ? u : new V(
161
+ if (r = l instanceof Z ? l : new Z(
162
162
  "Failed to connect. Please try again.",
163
163
  0,
164
164
  "NETWORK_ERROR"
165
165
  ), !this.isRetryable(r.status, r.code))
166
166
  throw r;
167
- o < this.maxRetries && await this.delay(this.getRetryDelay(null, o));
167
+ s < this.maxRetries && await this.delay(this.getRetryDelay(null, s));
168
168
  continue;
169
169
  }
170
170
  if (a.status === 404 || a.status === 405)
171
171
  return this.lastSendTime = 0, this.sendMessage(t);
172
172
  if (!a.ok) {
173
- const u = await a.json().catch(() => ({})), l = a.headers.get("Retry-After");
174
- if (r = new V(
175
- u.error ?? `Request failed with status ${a.status}`,
173
+ const l = await a.json().catch(() => ({})), u = a.headers.get("Retry-After");
174
+ if (r = new Z(
175
+ l.error ?? `Request failed with status ${a.status}`,
176
176
  a.status,
177
- u.code,
178
- l ? Number(l) : void 0
177
+ l.code,
178
+ u ? Number(u) : void 0
179
179
  ), !this.isRetryable(a.status))
180
180
  throw r;
181
- o < this.maxRetries && await this.delay(this.getRetryDelay(a, o));
181
+ s < this.maxRetries && await this.delay(this.getRetryDelay(a, s));
182
182
  continue;
183
183
  }
184
184
  if (!(a.headers.get("Content-Type") ?? "").includes("text/event-stream"))
@@ -197,56 +197,56 @@ class Xe {
197
197
  * resolving with the partial text when the caller aborts.
198
198
  */
199
199
  async readSseStream(t, n) {
200
- var m, E, N, g, d, f, v;
201
- const r = t.getReader(), s = new TextDecoder();
202
- let o = "", a = "";
200
+ var d, x, A, g, f, p, T;
201
+ const r = t.getReader(), o = new TextDecoder();
202
+ let s = "", a = "";
203
203
  const c = [];
204
- let u;
205
- const l = () => {
204
+ let l;
205
+ const u = () => {
206
206
  r.cancel().catch(() => {
207
207
  });
208
208
  };
209
- (m = n.signal) == null || m.addEventListener("abort", l, { once: !0 });
209
+ (d = n.signal) == null || d.addEventListener("abort", u, { once: !0 });
210
210
  try {
211
211
  for (; ; ) {
212
- let D;
212
+ let b;
213
213
  try {
214
- D = await r.read();
215
- } catch (T) {
216
- if ((E = n.signal) != null && E.aborted) break;
217
- throw T;
214
+ b = await r.read();
215
+ } catch (y) {
216
+ if ((x = n.signal) != null && x.aborted) break;
217
+ throw y;
218
218
  }
219
- if ((N = n.signal) != null && N.aborted || D.done) break;
220
- o += s.decode(D.value, { stream: !0 });
221
- let C;
222
- for (; (C = o.indexOf(`
219
+ if ((A = n.signal) != null && A.aborted || b.done) break;
220
+ s += o.decode(b.value, { stream: !0 });
221
+ let R;
222
+ for (; (R = s.indexOf(`
223
223
 
224
224
  `)) !== -1; ) {
225
- const T = o.slice(0, C);
226
- o = o.slice(C + 2);
227
- const b = et(T);
228
- if (b) {
229
- if (b.event === "chunk") {
230
- const k = typeof b.data.text == "string" ? b.data.text : "";
231
- k && (a += k, (g = n.onChunk) == null || g.call(n, k, a));
232
- } else if (b.event === "tool") {
233
- if (typeof b.data.name == "string") {
234
- const k = b.data;
235
- c.push(k), (d = n.onToolUse) == null || d.call(n, k, c);
225
+ const y = s.slice(0, R);
226
+ s = s.slice(R + 2);
227
+ const v = gt(y);
228
+ if (v) {
229
+ if (v.event === "chunk") {
230
+ const C = typeof v.data.text == "string" ? v.data.text : "";
231
+ C && (a += C, (g = n.onChunk) == null || g.call(n, C, a));
232
+ } else if (v.event === "tool") {
233
+ if (typeof v.data.name == "string") {
234
+ const C = v.data;
235
+ c.push(C), (f = n.onToolUse) == null || f.call(n, C, c);
236
236
  }
237
- } else if (b.event === "done") {
238
- const k = Array.isArray(b.data.toolUses) ? b.data.toolUses : c;
239
- u = {
240
- reply: typeof b.data.reply == "string" ? b.data.reply : a,
241
- sources: b.data.sources,
242
- ...k.length > 0 ? { toolUses: k } : {},
243
- ...Array.isArray(b.data.attachments) ? {
244
- attachments: b.data.attachments
237
+ } else if (v.event === "done") {
238
+ const C = Array.isArray(v.data.toolUses) ? v.data.toolUses : c;
239
+ l = {
240
+ reply: typeof v.data.reply == "string" ? v.data.reply : a,
241
+ sources: v.data.sources,
242
+ ...C.length > 0 ? { toolUses: C } : {},
243
+ ...Array.isArray(v.data.attachments) ? {
244
+ attachments: v.data.attachments
245
245
  } : {}
246
246
  };
247
- } else if (b.event === "error")
248
- throw new V(
249
- typeof b.data.error == "string" ? b.data.error : "Something went wrong. Please try again.",
247
+ } else if (v.event === "error")
248
+ throw new Z(
249
+ typeof v.data.error == "string" ? v.data.error : "Something went wrong. Please try again.",
250
250
  0,
251
251
  "STREAM_ERROR"
252
252
  );
@@ -254,43 +254,43 @@ class Xe {
254
254
  }
255
255
  }
256
256
  } finally {
257
- (f = n.signal) == null || f.removeEventListener("abort", l), r.releaseLock();
257
+ (p = n.signal) == null || p.removeEventListener("abort", u), r.releaseLock();
258
258
  }
259
- if ((v = n.signal) != null && v.aborted)
259
+ if ((T = n.signal) != null && T.aborted)
260
260
  return {
261
261
  reply: a,
262
262
  aborted: !0,
263
263
  ...c.length > 0 ? { toolUses: c } : {}
264
264
  };
265
- if (u) return u;
266
- throw new V(
265
+ if (l) return l;
266
+ throw new Z(
267
267
  "Connection interrupted. Please try again.",
268
268
  0,
269
269
  "STREAM_ERROR"
270
270
  );
271
271
  }
272
272
  async fetchStream(t, n) {
273
- const r = new AbortController(), s = () => r.abort();
274
- n == null || n.addEventListener("abort", s, { once: !0 });
275
- let o = !1;
273
+ const r = new AbortController(), o = () => r.abort();
274
+ n == null || n.addEventListener("abort", o, { once: !0 });
275
+ let s = !1;
276
276
  const a = this.timeoutMs > 0 ? setTimeout(() => {
277
- o = !0, r.abort();
278
- }, this.timeoutMs) : void 0, { headers: c, body: u } = this.buildRequest(t);
277
+ s = !0, r.abort();
278
+ }, this.timeoutMs) : void 0, { headers: c, body: l } = this.buildRequest(t);
279
279
  try {
280
280
  return await fetch(`${this.baseUrl}/api/chat/stream`, {
281
281
  method: "POST",
282
282
  headers: c,
283
- body: u,
283
+ body: l,
284
284
  signal: r.signal
285
285
  });
286
- } catch (l) {
287
- throw o ? new V(
286
+ } catch (u) {
287
+ throw s ? new Z(
288
288
  "Request timed out. Please try again.",
289
289
  0,
290
290
  "TIMEOUT"
291
- ) : l;
291
+ ) : u;
292
292
  } finally {
293
- a !== void 0 && clearTimeout(a), n == null || n.removeEventListener("abort", s);
293
+ a !== void 0 && clearTimeout(a), n == null || n.removeEventListener("abort", o);
294
294
  }
295
295
  }
296
296
  async fetchWithTimeout(t) {
@@ -301,22 +301,22 @@ class Xe {
301
301
  headers: n,
302
302
  body: r
303
303
  });
304
- const s = new AbortController(), o = setTimeout(() => s.abort(), this.timeoutMs);
304
+ const o = new AbortController(), s = setTimeout(() => o.abort(), this.timeoutMs);
305
305
  try {
306
306
  return await fetch(`${this.baseUrl}/api/chat`, {
307
307
  method: "POST",
308
308
  headers: n,
309
309
  body: r,
310
- signal: s.signal
310
+ signal: o.signal
311
311
  });
312
312
  } catch (a) {
313
- throw s.signal.aborted ? new V(
313
+ throw o.signal.aborted ? new Z(
314
314
  "Request timed out. Please try again.",
315
315
  0,
316
316
  "TIMEOUT"
317
317
  ) : a;
318
318
  } finally {
319
- clearTimeout(o);
319
+ clearTimeout(s);
320
320
  }
321
321
  }
322
322
  isRetryable(t, n) {
@@ -326,8 +326,8 @@ class Xe {
326
326
  if (t && t.status === 429) {
327
327
  const r = t.headers.get("Retry-After");
328
328
  if (r) {
329
- const s = Number(r);
330
- return Math.min(s * 1e3, 6e4);
329
+ const o = Number(r);
330
+ return Math.min(o * 1e3, 6e4);
331
331
  }
332
332
  }
333
333
  return n === 0 ? 1e3 : 3e3;
@@ -336,7 +336,7 @@ class Xe {
336
336
  return new Promise((n) => setTimeout(n, t));
337
337
  }
338
338
  }
339
- function et(e) {
339
+ function gt(e) {
340
340
  let t = "message";
341
341
  const n = [];
342
342
  for (const r of e.split(`
@@ -351,71 +351,71 @@ function et(e) {
351
351
  return null;
352
352
  }
353
353
  }
354
- function Be(e) {
354
+ function Qe(e) {
355
355
  return typeof e == "string" ? { content: e } : e;
356
356
  }
357
- function Re(e, t, n) {
357
+ function Ie(e, t, n) {
358
358
  console.error(`[claudius] plugin "${e.name}" failed in ${t}:`, n);
359
359
  }
360
- async function tt(e, t, n) {
360
+ async function bt(e, t, n) {
361
361
  let r = t;
362
- for (const s of e) {
363
- if (!s.onBeforeSend) continue;
364
- let o = null;
362
+ for (const o of e) {
363
+ if (!o.onBeforeSend) continue;
364
+ let s = null;
365
365
  const a = {
366
366
  ...n,
367
367
  respondWith(c) {
368
- o = {
368
+ s = {
369
369
  type: "respond",
370
370
  message: r,
371
- reply: Be(c)
371
+ reply: Qe(c)
372
372
  };
373
373
  },
374
374
  abort(c) {
375
- o = { type: "abort", reason: c };
375
+ s = { type: "abort", reason: c };
376
376
  }
377
377
  };
378
378
  try {
379
- const c = await s.onBeforeSend(r, a);
380
- if (o) return o;
379
+ const c = await o.onBeforeSend(r, a);
380
+ if (s) return s;
381
381
  c && (r = c);
382
382
  } catch (c) {
383
- Re(s, "onBeforeSend", c);
383
+ Ie(o, "onBeforeSend", c);
384
384
  }
385
385
  }
386
386
  return { type: "send", message: r };
387
387
  }
388
- async function nt(e, t, n) {
388
+ async function yt(e, t, n) {
389
389
  let r = t;
390
- for (const s of e)
391
- if (s.onAfterReceive)
390
+ for (const o of e)
391
+ if (o.onAfterReceive)
392
392
  try {
393
- const o = await s.onAfterReceive(r, n);
394
- o && (r = o);
395
- } catch (o) {
396
- Re(s, "onAfterReceive", o);
393
+ const s = await o.onAfterReceive(r, n);
394
+ s && (r = s);
395
+ } catch (s) {
396
+ Ie(o, "onAfterReceive", s);
397
397
  }
398
398
  return r;
399
399
  }
400
- async function rt(e, t, n) {
400
+ async function xt(e, t, n) {
401
401
  for (const r of e) {
402
402
  if (!r.onError) continue;
403
- let s = null;
404
- const o = {
403
+ let o = null;
404
+ const s = {
405
405
  ...n,
406
406
  respondWith(a) {
407
- s = Be(a);
407
+ o = Qe(a);
408
408
  }
409
409
  };
410
410
  try {
411
- if (await r.onError(t, o), s) return s;
411
+ if (await r.onError(t, s), o) return o;
412
412
  } catch (a) {
413
- Re(r, "onError", a);
413
+ Ie(r, "onError", a);
414
414
  }
415
415
  }
416
416
  return null;
417
417
  }
418
- const fe = {
418
+ const Te = {
419
419
  maxSizeBytes: 5 * 1024 * 1024,
420
420
  maxCount: 5,
421
421
  allowedTypes: [
@@ -426,14 +426,14 @@ const fe = {
426
426
  "application/pdf"
427
427
  ]
428
428
  };
429
- function st(e) {
430
- return e ? e === !0 ? fe : {
431
- maxSizeBytes: e.maxSizeBytes ?? fe.maxSizeBytes,
432
- maxCount: e.maxCount ?? fe.maxCount,
433
- allowedTypes: (e.allowedTypes ?? fe.allowedTypes).map((t) => t.trim().toLowerCase()).filter(Boolean)
429
+ function wt(e) {
430
+ return e ? e === !0 ? Te : {
431
+ maxSizeBytes: e.maxSizeBytes ?? Te.maxSizeBytes,
432
+ maxCount: e.maxCount ?? Te.maxCount,
433
+ allowedTypes: (e.allowedTypes ?? Te.allowedTypes).map((t) => t.trim().toLowerCase()).filter(Boolean)
434
434
  } : null;
435
435
  }
436
- function xe(e) {
436
+ function Se(e) {
437
437
  if (!Number.isFinite(e) || e < 0) return "0 B";
438
438
  if (e < 1024) return `${e} B`;
439
439
  const t = e / 1024;
@@ -441,7 +441,7 @@ function xe(e) {
441
441
  const n = t / 1024;
442
442
  return `${Number.isInteger(n) ? n : n.toFixed(1)} MB`;
443
443
  }
444
- const ot = {
444
+ const vt = {
445
445
  png: "image/png",
446
446
  jpg: "image/jpeg",
447
447
  jpeg: "image/jpeg",
@@ -449,18 +449,18 @@ const ot = {
449
449
  webp: "image/webp",
450
450
  pdf: "application/pdf"
451
451
  };
452
- function He(e) {
452
+ function Xe(e) {
453
453
  var r;
454
454
  const t = (e.type || "").trim().toLowerCase();
455
455
  if (t) return t;
456
456
  const n = ((r = e.name.split(".").pop()) == null ? void 0 : r.toLowerCase()) ?? "";
457
- return ot[n] ?? "";
457
+ return vt[n] ?? "";
458
458
  }
459
- function at(e) {
459
+ function Tt(e) {
460
460
  return e.startsWith("image/");
461
461
  }
462
- function it(e) {
463
- if (at(e.mediaType)) {
462
+ function Et(e) {
463
+ if (Tt(e.mediaType)) {
464
464
  if (e.url)
465
465
  try {
466
466
  const t = new URL(e.url);
@@ -471,63 +471,63 @@ function it(e) {
471
471
  if (e.data) return `data:${e.mediaType};base64,${e.data}`;
472
472
  }
473
473
  }
474
- function ct(e, t, n) {
475
- const r = [], s = [];
476
- let o = Math.max(0, n.maxCount - t);
474
+ function Rt(e, t, n) {
475
+ const r = [], o = [];
476
+ let s = Math.max(0, n.maxCount - t);
477
477
  for (const a of e) {
478
- const c = He(a);
479
- !c || !n.allowedTypes.includes(c) ? s.push({ file: a, reason: "type" }) : a.size > n.maxSizeBytes || a.size === 0 ? s.push({ file: a, reason: "size" }) : o <= 0 ? s.push({ file: a, reason: "count" }) : (r.push(a), o -= 1);
478
+ const c = Xe(a);
479
+ !c || !n.allowedTypes.includes(c) ? o.push({ file: a, reason: "type" }) : a.size > n.maxSizeBytes || a.size === 0 ? o.push({ file: a, reason: "size" }) : s <= 0 ? o.push({ file: a, reason: "count" }) : (r.push(a), s -= 1);
480
480
  }
481
- return { accepted: r, rejected: s };
481
+ return { accepted: r, rejected: o };
482
482
  }
483
- function lt(e) {
483
+ function At(e) {
484
484
  return new Promise((t, n) => {
485
485
  const r = new FileReader();
486
486
  r.onerror = () => n(r.error ?? new Error("Failed to read file")), r.onload = () => {
487
- const s = String(r.result ?? ""), o = s.indexOf(",");
488
- t(o >= 0 ? s.slice(o + 1) : s);
487
+ const o = String(r.result ?? ""), s = o.indexOf(",");
488
+ t(s >= 0 ? o.slice(s + 1) : o);
489
489
  }, r.readAsDataURL(e);
490
490
  });
491
491
  }
492
- let Se = 0;
493
- function ut() {
494
- return Se += 1, `att-${Date.now().toString(36)}-${Se}`;
492
+ let je = 0;
493
+ function St() {
494
+ return je += 1, `att-${Date.now().toString(36)}-${je}`;
495
495
  }
496
- async function dt(e) {
497
- const t = await lt(e);
496
+ async function kt(e) {
497
+ const t = await At(e);
498
498
  return {
499
- id: ut(),
499
+ id: St(),
500
500
  name: e.name || "attachment",
501
- mediaType: He(e),
501
+ mediaType: Xe(e),
502
502
  size: e.size,
503
503
  data: t
504
504
  };
505
505
  }
506
- function ht(e) {
506
+ function et(e) {
507
507
  return e.map((t) => {
508
508
  var n;
509
509
  return (n = t.attachments) != null && n.some((r) => r.data) ? {
510
510
  ...t,
511
511
  attachments: t.attachments.map((r) => {
512
512
  if (!r.data) return r;
513
- const s = { ...r };
514
- return delete s.data, s;
513
+ const o = { ...r };
514
+ return delete o.data, o;
515
515
  })
516
516
  } : t;
517
517
  });
518
518
  }
519
- function ft(e, t) {
519
+ function Ct(e, t) {
520
520
  if (!t || t.length === 0) return e;
521
521
  const n = new Map(t.map((r) => [r.id, r]));
522
522
  return e.map((r) => {
523
- var s;
524
- return (s = r.attachments) != null && s.some((o) => n.has(o.id)) ? {
523
+ var o;
524
+ return (o = r.attachments) != null && o.some((s) => n.has(s.id)) ? {
525
525
  ...r,
526
- attachments: r.attachments.map((o) => {
527
- const a = n.get(o.id);
528
- if (!a) return o;
526
+ attachments: r.attachments.map((s) => {
527
+ const a = n.get(s.id);
528
+ if (!a) return s;
529
529
  const c = {
530
- ...o,
530
+ ...s,
531
531
  key: a.key,
532
532
  url: a.url,
533
533
  expiresAt: a.expiresAt
@@ -537,8 +537,8 @@ function ft(e, t) {
537
537
  } : r;
538
538
  });
539
539
  }
540
- const mt = 200, pt = "claudius:messages";
541
- function gt(e, t) {
540
+ const Mt = 200, Nt = "claudius:messages", be = () => (/* @__PURE__ */ new Date()).toISOString();
541
+ function Dt(e, t) {
542
542
  let n;
543
543
  try {
544
544
  n = new URL(t).host;
@@ -547,15 +547,15 @@ function gt(e, t) {
547
547
  }
548
548
  return `${e}:${n}`;
549
549
  }
550
- function ve() {
550
+ function Le() {
551
551
  try {
552
552
  return typeof sessionStorage < "u" ? sessionStorage : null;
553
553
  } catch {
554
554
  return null;
555
555
  }
556
556
  }
557
- function bt(e) {
558
- const t = ve();
557
+ function Lt(e) {
558
+ const t = Le();
559
559
  if (!t) return [];
560
560
  try {
561
561
  const n = t.getItem(e);
@@ -566,318 +566,330 @@ function bt(e) {
566
566
  return [];
567
567
  }
568
568
  }
569
- function yt({
569
+ function It({
570
570
  apiUrl: e,
571
571
  persistMessages: t = !0,
572
- storageKeyPrefix: n = pt,
572
+ storageKeyPrefix: n = Nt,
573
573
  timeoutMs: r,
574
- translations: s,
575
- plugins: o,
574
+ translations: o,
575
+ plugins: s,
576
576
  streaming: a = !0
577
577
  }) {
578
- const c = ae(
579
- () => new Xe(e, { debounceMs: 0, timeoutMs: r }),
578
+ const c = se(
579
+ () => new mt(e, { debounceMs: 0, timeoutMs: r }),
580
580
  [e, r]
581
- ), u = gt(n, e), l = t ? bt(u) : [], [m, E] = O(l), [N, g] = O(!1), [d, f] = O(!1), [v, D] = O(
581
+ ), l = Dt(n, e), u = t ? Lt(l) : [], [d, x] = N(u), [A, g] = N(!1), [f, p] = N(!1), [T, b] = N(
582
582
  null
583
- ), [C, T] = O(null), [b, k] = O(!1), A = L(l.length), B = L(!1), y = L(l), W = L(null), U = L(o ?? []);
584
- U.current = o ?? [];
585
- const H = M(
586
- (x) => {
583
+ ), [R, y] = N(null), [v, C] = N(!1), $ = S(u.length), L = S(!1), E = S(u), B = S(null), O = S(s ?? []);
584
+ O.current = s ?? [];
585
+ const _ = M(
586
+ (h) => {
587
587
  if (!t) return;
588
- const z = ve();
589
- if (z)
588
+ const P = Le();
589
+ if (P)
590
590
  try {
591
- const I = ht(x.slice(-mt));
592
- z.setItem(u, JSON.stringify(I));
591
+ const U = et(h.slice(-Mt));
592
+ P.setItem(l, JSON.stringify(U));
593
593
  } catch {
594
594
  }
595
595
  },
596
- [t, u]
597
- ), _ = () => (A.current += 1, `msg-${A.current}`), J = M(
598
- (x, z) => {
599
- if (!s)
600
- return z ?? "Something went wrong. Please try again.";
601
- switch (x) {
596
+ [t, l]
597
+ ), q = () => ($.current += 1, `msg-${$.current}`), G = M(
598
+ (h, P) => {
599
+ if (!o)
600
+ return P ?? "Something went wrong. Please try again.";
601
+ switch (h) {
602
602
  case "TIMEOUT":
603
- return s.errorTimeout;
603
+ return o.errorTimeout;
604
604
  case "NETWORK_ERROR":
605
- return s.errorConnection;
605
+ return o.errorConnection;
606
606
  case "RATE_LIMITED":
607
- return z != null && z.includes("minute") ? s.errorRateLimitMinute : s.errorRateLimitHour;
607
+ return P != null && P.includes("minute") ? o.errorRateLimitMinute : o.errorRateLimitHour;
608
608
  case "ATTACHMENT_QUOTA_EXCEEDED":
609
- return s.errorAttachmentQuota;
609
+ return o.errorAttachmentQuota;
610
610
  case "ATTACHMENTS_DISABLED":
611
611
  case "ATTACHMENT_INVALID":
612
612
  case "ATTACHMENT_TOO_LARGE":
613
- return s.errorAttachmentRejected;
613
+ return o.errorAttachmentRejected;
614
614
  case "VALIDATION_ERROR":
615
615
  case "CONFIG_ERROR":
616
616
  case "SERVICE_ERROR":
617
617
  case "UNKNOWN_ERROR":
618
618
  default:
619
- return z ?? s.errorGeneric;
619
+ return P ?? o.errorGeneric;
620
620
  }
621
621
  },
622
- [s]
623
- ), re = M((x) => !(x instanceof V) || x.code === "TIMEOUT" || x.code === "NETWORK_ERROR" || x.code === "RATE_LIMITED" || x.code === "SERVICE_ERROR" || x.code === "UNKNOWN_ERROR" || x.status >= 500 || x.status === 0, []), X = M(
624
- async (x) => {
625
- var ne, Z;
626
- g(!0), B.current = !0, T(null), k(!1);
627
- const z = a && typeof c.streamMessage == "function";
628
- let I = null;
629
- const Q = (R) => {
630
- if (I === null) {
631
- I = _(), D(I);
632
- const j = [
633
- ...y.current,
634
- { id: I, role: "assistant", content: "", ...R }
622
+ [o]
623
+ ), J = M((h) => !(h instanceof Z) || h.code === "TIMEOUT" || h.code === "NETWORK_ERROR" || h.code === "RATE_LIMITED" || h.code === "SERVICE_ERROR" || h.code === "UNKNOWN_ERROR" || h.status >= 500 || h.status === 0, []), z = M(
624
+ async (h) => {
625
+ var ne, F, H;
626
+ g(!0), L.current = !0, y(null), C(!1);
627
+ const P = a && typeof c.streamMessage == "function";
628
+ let U = null;
629
+ const ee = (k) => {
630
+ if (U === null) {
631
+ U = q(), b(U);
632
+ const D = [
633
+ ...E.current,
634
+ {
635
+ id: U,
636
+ role: "assistant",
637
+ content: "",
638
+ createdAt: be(),
639
+ ...k
640
+ }
635
641
  ];
636
- y.current = j, E(j);
642
+ E.current = D, x(D);
637
643
  } else {
638
- const j = I, P = y.current.map(
639
- (Y) => Y.id === j ? { ...Y, ...R } : Y
644
+ const D = U, I = E.current.map(
645
+ (K) => K.id === D ? { ...K, ...k } : K
640
646
  );
641
- y.current = P, E(P);
647
+ E.current = I, x(I);
642
648
  }
643
- }, $ = () => {
644
- if (I === null) return;
645
- const R = I, j = y.current.filter((P) => P.id !== R);
646
- y.current = j, E(j);
649
+ }, te = () => {
650
+ if (U === null) return;
651
+ const k = U, D = E.current.filter((I) => I.id !== k);
652
+ E.current = D, x(D);
647
653
  };
648
654
  try {
649
- let R, j, P, Y, q = !1;
650
- if (z) {
651
- const S = new AbortController();
652
- W.current = S, f(!0);
653
- const F = await c.streamMessage(x, {
654
- signal: S.signal,
655
- onChunk: (ce, G) => Q({ content: G }),
656
- onToolUse: (ce, G) => Q({ toolUses: [...G] })
655
+ let k, D, I, K, Q = !1;
656
+ if (P) {
657
+ const V = new AbortController();
658
+ B.current = V, p(!0);
659
+ const oe = await c.streamMessage(h, {
660
+ signal: V.signal,
661
+ onChunk: (ge, de) => ee({ content: de }),
662
+ onToolUse: (ge, de) => ee({ toolUses: [...de] })
657
663
  });
658
- R = F.reply, j = F.sources, P = F.toolUses, Y = F.attachments, q = F.aborted ?? !1;
664
+ k = oe.reply, D = oe.sources, I = oe.toolUses, K = oe.attachments, Q = oe.aborted ?? !1;
659
665
  } else {
660
- const S = await c.sendMessage(x);
661
- R = S.reply, j = S.sources, P = S.toolUses, Y = S.attachments;
666
+ const V = await c.sendMessage(h);
667
+ k = V.reply, D = V.sources, I = V.toolUses, K = V.attachments;
662
668
  }
663
- if (q && !R) {
664
- $();
669
+ if (Q && !k) {
670
+ te();
665
671
  return;
666
672
  }
667
- let se = {
668
- id: I ?? _(),
673
+ const le = ((ne = E.current.find((V) => V.id === U)) == null ? void 0 : ne.createdAt) ?? be();
674
+ let Y = {
675
+ id: U ?? q(),
669
676
  role: "assistant",
670
- content: R,
671
- sources: j,
672
- toolUses: P
677
+ content: k,
678
+ createdAt: le,
679
+ sources: D,
680
+ toolUses: I
673
681
  };
674
- U.current.length > 0 && !q && (se = await nt(
675
- U.current,
676
- se,
677
- { messages: x, apiUrl: e }
678
- ));
679
- const he = I !== null ? y.current.map(
680
- (S) => S.id === se.id ? se : S
681
- ) : [...x, se], h = ft(he, Y);
682
- y.current = h, E(h), H(h);
683
- } catch (R) {
684
- if (R instanceof ye) return;
685
- if (R instanceof V && ((ne = R.code) != null && ne.startsWith("ATTACHMENT")) && x.length > 0) {
686
- const j = x[x.length - 1];
687
- if (j.role === "user" && ((Z = j.attachments) != null && Z.length)) {
688
- const P = x.slice(0, -1);
689
- y.current = P, E(P), H(P);
682
+ O.current.length > 0 && !Q && (Y = await yt(
683
+ O.current,
684
+ Y,
685
+ { messages: h, apiUrl: e }
686
+ ), Y.createdAt || (Y = { ...Y, createdAt: le }));
687
+ const me = U !== null ? E.current.map(
688
+ (V) => V.id === Y.id ? Y : V
689
+ ) : [...h, Y], ue = Ct(me, K);
690
+ E.current = ue, x(ue), _(ue);
691
+ } catch (k) {
692
+ if (k instanceof De) return;
693
+ if (k instanceof Z && ((F = k.code) != null && F.startsWith("ATTACHMENT")) && h.length > 0) {
694
+ const D = h[h.length - 1];
695
+ if (D.role === "user" && ((H = D.attachments) != null && H.length)) {
696
+ const I = h.slice(0, -1);
697
+ E.current = I, x(I), _(I);
690
698
  }
691
699
  }
692
- if (I !== null) {
693
- H(y.current), R instanceof V ? T(J(R.code, R.message)) : T(
694
- (s == null ? void 0 : s.errorConnection) ?? "Failed to connect. Please try again."
695
- ), k(!1);
700
+ if (U !== null) {
701
+ _(E.current), k instanceof Z ? y(G(k.code, k.message)) : y(
702
+ (o == null ? void 0 : o.errorConnection) ?? "Failed to connect. Please try again."
703
+ ), C(!1);
696
704
  return;
697
705
  }
698
- if (U.current.length > 0) {
699
- const j = R instanceof Error ? R : new Error(String(R)), P = await rt(U.current, j, {
700
- messages: x,
706
+ if (O.current.length > 0) {
707
+ const D = k instanceof Error ? k : new Error(String(k)), I = await xt(O.current, D, {
708
+ messages: h,
701
709
  apiUrl: e
702
710
  });
703
- if (P) {
704
- const Y = {
705
- id: _(),
711
+ if (I) {
712
+ const K = {
713
+ id: q(),
706
714
  role: "assistant",
707
- content: P.content,
708
- sources: P.sources
709
- }, q = [...x, Y];
710
- y.current = q, E(q), H(q), T(null), k(!1);
715
+ content: I.content,
716
+ createdAt: be(),
717
+ sources: I.sources
718
+ }, Q = [...h, K];
719
+ E.current = Q, x(Q), _(Q), y(null), C(!1);
711
720
  return;
712
721
  }
713
722
  }
714
- R instanceof V ? T(J(R.code, R.message)) : T(
715
- (s == null ? void 0 : s.errorConnection) ?? "Failed to connect. Please try again."
716
- ), k(re(R));
723
+ k instanceof Z ? y(G(k.code, k.message)) : y(
724
+ (o == null ? void 0 : o.errorConnection) ?? "Failed to connect. Please try again."
725
+ ), C(J(k));
717
726
  } finally {
718
- g(!1), B.current = !1, f(!1), D(null), W.current = null;
727
+ g(!1), L.current = !1, p(!1), b(null), B.current = null;
719
728
  }
720
729
  },
721
730
  [
722
731
  e,
723
732
  c,
733
+ G,
724
734
  J,
725
- re,
726
- H,
735
+ _,
727
736
  a,
728
- s
737
+ o
729
738
  ]
730
- ), te = M(() => {
731
- var x;
732
- (x = W.current) == null || x.abort();
733
- }, []), w = M(
734
- async (x, z) => {
735
- const I = x.trim(), Q = (z == null ? void 0 : z.filter((R) => R && R.id)) ?? [];
736
- if (!I && Q.length === 0 || B.current) return;
737
- const $ = {
738
- id: _(),
739
+ ), ae = M(() => {
740
+ var h;
741
+ (h = B.current) == null || h.abort();
742
+ }, []), ie = M(
743
+ async (h, P) => {
744
+ const U = h.trim(), ee = (P == null ? void 0 : P.filter((H) => H && H.id)) ?? [];
745
+ if (!U && ee.length === 0 || L.current) return;
746
+ const te = {
747
+ id: q(),
739
748
  role: "user",
740
- content: I,
741
- ...Q.length > 0 ? { attachments: Q } : {}
749
+ content: U,
750
+ createdAt: be(),
751
+ ...ee.length > 0 ? { attachments: ee } : {}
742
752
  };
743
- let ne = $;
744
- if (U.current.length > 0) {
745
- const R = await tt(U.current, $, {
746
- messages: y.current,
753
+ let ne = te;
754
+ if (O.current.length > 0) {
755
+ const H = await bt(O.current, te, {
756
+ messages: E.current,
747
757
  apiUrl: e
748
758
  });
749
- if (R.type === "abort") return;
750
- if (R.type === "respond") {
751
- const j = {
752
- id: _(),
759
+ if (H.type === "abort") return;
760
+ const k = (D) => D.createdAt ? D : { ...D, createdAt: te.createdAt };
761
+ if (H.type === "respond") {
762
+ const D = {
763
+ id: q(),
753
764
  role: "assistant",
754
- content: R.reply.content,
755
- sources: R.reply.sources
756
- }, P = [
757
- ...y.current,
758
- R.message,
759
- j
765
+ content: H.reply.content,
766
+ createdAt: be(),
767
+ sources: H.reply.sources
768
+ }, I = [
769
+ ...E.current,
770
+ k(H.message),
771
+ D
760
772
  ];
761
- y.current = P, E(P), H(P), T(null), k(!1);
773
+ E.current = I, x(I), _(I), y(null), C(!1);
762
774
  return;
763
775
  }
764
- ne = R.message;
776
+ ne = k(H.message);
765
777
  }
766
- const Z = [...y.current, ne];
767
- y.current = Z, E(Z), H(Z), await X(Z);
778
+ const F = [...E.current, ne];
779
+ E.current = F, x(F), _(F), await z(F);
768
780
  },
769
- [e, H, X]
770
- ), ee = M(async () => {
771
- if (B.current) return;
772
- const x = y.current[y.current.length - 1];
773
- !x || x.role !== "user" || await X(y.current);
774
- }, [X]), ie = M(() => {
775
- if (y.current = [], E([]), T(null), k(!1), t) {
776
- const x = ve();
777
- if (!x) return;
781
+ [e, _, z]
782
+ ), ce = M(async () => {
783
+ if (L.current) return;
784
+ const h = E.current[E.current.length - 1];
785
+ !h || h.role !== "user" || await z(E.current);
786
+ }, [z]), re = M(() => {
787
+ if (E.current = [], x([]), y(null), C(!1), t) {
788
+ const h = Le();
789
+ if (!h) return;
778
790
  try {
779
- x.removeItem(u);
791
+ h.removeItem(l);
780
792
  } catch {
781
793
  }
782
794
  }
783
- }, [t, u]);
795
+ }, [t, l]);
784
796
  return {
785
- messages: m,
786
- isLoading: N,
787
- isStreaming: d,
788
- streamingMessageId: v,
789
- error: C,
790
- canRetry: b,
791
- sendMessage: w,
792
- stop: te,
793
- retry: ee,
794
- clearMessages: ie
797
+ messages: d,
798
+ isLoading: A,
799
+ isStreaming: f,
800
+ streamingMessageId: T,
801
+ error: R,
802
+ canRetry: v,
803
+ sendMessage: ie,
804
+ stop: ae,
805
+ retry: ce,
806
+ clearMessages: re
795
807
  };
796
808
  }
797
- function xt(e) {
798
- const [t, n] = O(() => typeof window > "u" ? !1 : window.matchMedia(e).matches);
799
- return K(() => {
809
+ function Ot(e) {
810
+ const [t, n] = N(() => typeof window > "u" ? !1 : window.matchMedia(e).matches);
811
+ return W(() => {
800
812
  const r = window.matchMedia(e);
801
813
  n(r.matches);
802
- const s = (o) => n(o.matches);
803
- return r.addEventListener("change", s), () => r.removeEventListener("change", s);
814
+ const o = (s) => n(s.matches);
815
+ return r.addEventListener("change", o), () => r.removeEventListener("change", o);
804
816
  }, [e]), t;
805
817
  }
806
- function me(e, t) {
818
+ function Ee(e, t) {
807
819
  return e instanceof RegExp ? e.test(t) : t.toLowerCase().includes(e.toLowerCase());
808
820
  }
809
- function vt() {
810
- const e = document.documentElement, t = document.body, n = e.scrollTop || t.scrollTop || 0, r = Math.max(e.scrollHeight, t.scrollHeight), s = e.clientHeight || window.innerHeight, o = r - s;
811
- return o <= 0 ? 100 : n / o * 100;
821
+ function jt() {
822
+ const e = document.documentElement, t = document.body, n = e.scrollTop || t.scrollTop || 0, r = Math.max(e.scrollHeight, t.scrollHeight), o = e.clientHeight || window.innerHeight, s = r - o;
823
+ return s <= 0 ? 100 : n / s * 100;
812
824
  }
813
- function wt({
825
+ function $t({
814
826
  triggers: e,
815
827
  enabled: t,
816
828
  onOpen: n,
817
829
  onGreeting: r
818
830
  }) {
819
- K(() => {
831
+ W(() => {
820
832
  if (!t || !e || e.length === 0) return;
821
- const s = /* @__PURE__ */ new Set(), o = [], a = typeof window < "u" ? window.location.href : "", c = (u, l) => {
822
- s.has(u) || (s.add(u), l === "open" ? n() : r(l.greeting));
833
+ const o = /* @__PURE__ */ new Set(), s = [], a = typeof window < "u" ? window.location.href : "", c = (l, u) => {
834
+ o.has(l) || (o.add(l), u === "open" ? n() : r(u.greeting));
823
835
  };
824
- return e.forEach((u, l) => {
825
- switch (u.on) {
836
+ return e.forEach((l, u) => {
837
+ switch (l.on) {
826
838
  case "url": {
827
- me(u.pattern, a) && c(l, u.action);
839
+ Ee(l.pattern, a) && c(u, l.action);
828
840
  break;
829
841
  }
830
842
  case "time": {
831
- if (u.matchUrl && !me(u.matchUrl, a))
843
+ if (l.matchUrl && !Ee(l.matchUrl, a))
832
844
  return;
833
- const m = window.setTimeout(
834
- () => c(l, u.action),
835
- Math.max(0, u.seconds * 1e3)
845
+ const d = window.setTimeout(
846
+ () => c(u, l.action),
847
+ Math.max(0, l.seconds * 1e3)
836
848
  );
837
- o.push(() => window.clearTimeout(m));
849
+ s.push(() => window.clearTimeout(d));
838
850
  break;
839
851
  }
840
852
  case "scroll": {
841
- if (u.matchUrl && !me(u.matchUrl, a))
853
+ if (l.matchUrl && !Ee(l.matchUrl, a))
842
854
  return;
843
- const m = () => {
844
- vt() >= u.percent && c(l, u.action);
855
+ const d = () => {
856
+ jt() >= l.percent && c(u, l.action);
845
857
  };
846
- m(), window.addEventListener("scroll", m, { passive: !0 }), o.push(() => window.removeEventListener("scroll", m));
858
+ d(), window.addEventListener("scroll", d, { passive: !0 }), s.push(() => window.removeEventListener("scroll", d));
847
859
  break;
848
860
  }
849
861
  case "exit-intent": {
850
- if (u.matchUrl && !me(u.matchUrl, a))
862
+ if (l.matchUrl && !Ee(l.matchUrl, a))
851
863
  return;
852
- const m = (E) => {
853
- E.clientY <= 0 && c(l, u.action);
864
+ const d = (x) => {
865
+ x.clientY <= 0 && c(u, l.action);
854
866
  };
855
- document.addEventListener("mouseleave", m), o.push(
856
- () => document.removeEventListener("mouseleave", m)
867
+ document.addEventListener("mouseleave", d), s.push(
868
+ () => document.removeEventListener("mouseleave", d)
857
869
  );
858
870
  break;
859
871
  }
860
872
  }
861
873
  }), () => {
862
- o.forEach((u) => u());
874
+ s.forEach((l) => l());
863
875
  };
864
876
  }, [e, t, n, r]);
865
877
  }
866
- const Rt = {
878
+ const Pt = {
867
879
  "bottom-right": "bottom-6 right-6",
868
880
  "bottom-left": "bottom-6 left-6",
869
881
  "top-right": "top-6 right-6",
870
882
  "top-left": "top-6 left-6"
871
- }, Et = qe(function({ isOpen: t, onClick: n, position: r = "bottom-right", translations: s }, o) {
872
- const a = t ? (s == null ? void 0 : s.closeChat) ?? "Close chat" : (s == null ? void 0 : s.openChat) ?? "Open chat";
883
+ }, Ut = Je(function({ isOpen: t, onClick: n, position: r = "bottom-right", translations: o }, s) {
884
+ const a = t ? (o == null ? void 0 : o.closeChat) ?? "Close chat" : (o == null ? void 0 : o.openChat) ?? "Open chat";
873
885
  return /* @__PURE__ */ i(
874
886
  "button",
875
887
  {
876
- ref: o,
888
+ ref: s,
877
889
  onClick: n,
878
890
  "aria-label": a,
879
- className: `fixed ${Rt[r]} 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`,
880
- children: t ? /* @__PURE__ */ p(
891
+ className: `fixed ${Pt[r]} 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`,
892
+ children: t ? /* @__PURE__ */ w(
881
893
  "svg",
882
894
  {
883
895
  width: "24",
@@ -911,12 +923,12 @@ const Rt = {
911
923
  )
912
924
  }
913
925
  );
914
- }), Tt = ge(function({
926
+ }), Bt = ke(function({
915
927
  count: t,
916
928
  isActive: n,
917
929
  onClick: r
918
930
  }) {
919
- return /* @__PURE__ */ p(
931
+ return /* @__PURE__ */ w(
920
932
  "button",
921
933
  {
922
934
  onClick: r,
@@ -924,7 +936,7 @@ const Rt = {
924
936
  title: "View sources",
925
937
  className: `group relative flex h-7 w-7 items-center justify-center rounded-claudius-full transition-colors ${n ? "bg-claudius-accent text-claudius-accent-text" : "text-claudius-text-muted hover:bg-claudius-surface-muted hover:text-claudius-text"}`,
926
938
  children: [
927
- /* @__PURE__ */ p(
939
+ /* @__PURE__ */ w(
928
940
  "svg",
929
941
  {
930
942
  width: "14",
@@ -948,8 +960,8 @@ const Rt = {
948
960
  ]
949
961
  }
950
962
  );
951
- }), St = ["http:", "https:"];
952
- function Ee(e) {
963
+ }), _t = ["http:", "https:"];
964
+ function Ce(e) {
953
965
  if (!e || typeof e != "string")
954
966
  return null;
955
967
  const t = e.trim();
@@ -957,13 +969,13 @@ function Ee(e) {
957
969
  return null;
958
970
  try {
959
971
  const n = new URL(t);
960
- return St.includes(n.protocol) ? t : null;
972
+ return _t.includes(n.protocol) ? t : null;
961
973
  } catch {
962
974
  return null;
963
975
  }
964
976
  }
965
- function kt() {
966
- return /* @__PURE__ */ p(
977
+ function zt() {
978
+ return /* @__PURE__ */ w(
967
979
  "svg",
968
980
  {
969
981
  width: "14",
@@ -982,7 +994,7 @@ function kt() {
982
994
  }
983
995
  );
984
996
  }
985
- function ke({
997
+ function $e({
986
998
  label: e,
987
999
  onClick: t
988
1000
  }) {
@@ -993,7 +1005,7 @@ function ke({
993
1005
  onClick: t,
994
1006
  "aria-label": e,
995
1007
  className: "absolute -right-1.5 -top-1.5 flex h-5 w-5 items-center justify-center rounded-claudius-full bg-claudius-text text-claudius-surface shadow-claudius-floating hover:opacity-90 focus:outline-none focus-visible:ring-2 focus-visible:ring-claudius-accent",
996
- children: /* @__PURE__ */ p(
1008
+ children: /* @__PURE__ */ w(
997
1009
  "svg",
998
1010
  {
999
1011
  width: "10",
@@ -1013,76 +1025,72 @@ function ke({
1013
1025
  }
1014
1026
  );
1015
1027
  }
1016
- const _e = ge(function({
1028
+ const tt = ke(function({
1017
1029
  attachment: t,
1018
1030
  variant: n,
1019
1031
  onRemove: r,
1020
- removeLabel: s
1032
+ removeLabel: o
1021
1033
  }) {
1022
- const o = it(t), a = n === "composer", c = `${t.name} (${xe(t.size)})`, u = t.url ? Ee(t.url) : null;
1023
- if (o) {
1024
- const m = /* @__PURE__ */ i(
1034
+ const s = Et(t), a = n === "composer", c = `${t.name} (${Se(t.size)})`, l = t.url ? Ce(t.url) : null;
1035
+ if (s) {
1036
+ const d = /* @__PURE__ */ i(
1025
1037
  "img",
1026
1038
  {
1027
- src: o,
1039
+ src: s,
1028
1040
  alt: t.name,
1029
1041
  title: c,
1030
1042
  loading: "lazy",
1031
1043
  className: a ? "h-12 w-12 rounded-claudius-sm border border-claudius-border object-cover" : "max-h-48 max-w-full rounded-claudius-sm object-contain"
1032
1044
  }
1033
1045
  );
1034
- return /* @__PURE__ */ p("div", { className: "relative inline-block", children: [
1035
- !a && u ? /* @__PURE__ */ p("a", { href: u, target: "_blank", rel: "noopener noreferrer", children: [
1036
- m,
1037
- /* @__PURE__ */ p("span", { className: "sr-only", children: [
1046
+ return /* @__PURE__ */ w("div", { className: "relative inline-block", children: [
1047
+ !a && l ? /* @__PURE__ */ w("a", { href: l, target: "_blank", rel: "noopener noreferrer", children: [
1048
+ d,
1049
+ /* @__PURE__ */ w("span", { className: "sr-only", children: [
1038
1050
  c,
1039
1051
  " (opens in a new tab)"
1040
1052
  ] })
1041
- ] }) : m,
1042
- r && s && /* @__PURE__ */ i(ke, { label: s, onClick: r })
1053
+ ] }) : d,
1054
+ r && o && /* @__PURE__ */ i($e, { label: o, onClick: r })
1043
1055
  ] });
1044
1056
  }
1045
- const l = /* @__PURE__ */ p(
1057
+ const u = /* @__PURE__ */ w(
1046
1058
  "span",
1047
1059
  {
1048
1060
  title: c,
1049
1061
  className: `inline-flex max-w-[220px] items-center gap-1.5 rounded-claudius-sm border px-2 py-1 text-xs ${a ? "border-claudius-border bg-claudius-field text-claudius-text" : "border-current/30 bg-transparent"}`,
1050
1062
  children: [
1051
- /* @__PURE__ */ i(kt, {}),
1063
+ /* @__PURE__ */ i(zt, {}),
1052
1064
  /* @__PURE__ */ i("span", { className: "truncate", children: t.name }),
1053
- /* @__PURE__ */ i("span", { className: "shrink-0 opacity-70", children: xe(t.size) })
1065
+ /* @__PURE__ */ i("span", { className: "shrink-0 opacity-70", children: Se(t.size) })
1054
1066
  ]
1055
1067
  }
1056
1068
  );
1057
- return /* @__PURE__ */ p("div", { className: "relative inline-block", children: [
1058
- !a && u ? /* @__PURE__ */ p(
1069
+ return /* @__PURE__ */ w("div", { className: "relative inline-block", children: [
1070
+ !a && l ? /* @__PURE__ */ w(
1059
1071
  "a",
1060
1072
  {
1061
- href: u,
1073
+ href: l,
1062
1074
  target: "_blank",
1063
1075
  rel: "noopener noreferrer",
1064
1076
  className: "underline-offset-2 hover:underline",
1065
1077
  children: [
1066
- l,
1078
+ u,
1067
1079
  /* @__PURE__ */ i("span", { className: "sr-only", children: " (opens in a new tab)" })
1068
1080
  ]
1069
1081
  }
1070
- ) : l,
1071
- r && s && /* @__PURE__ */ i(ke, { label: s, onClick: r })
1082
+ ) : u,
1083
+ r && o && /* @__PURE__ */ i($e, { label: o, onClick: r })
1072
1084
  ] });
1073
- });
1074
- function pe({
1075
- label: e,
1076
- onClick: t,
1077
- children: n
1078
- }) {
1085
+ }), Pe = Je(function({ label: t, onClick: n, children: r }, o) {
1079
1086
  return /* @__PURE__ */ i(
1080
1087
  "button",
1081
1088
  {
1089
+ ref: o,
1082
1090
  type: "button",
1083
- onClick: t,
1084
- "aria-label": e,
1085
- title: e,
1091
+ onClick: n,
1092
+ "aria-label": t,
1093
+ title: t,
1086
1094
  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",
1087
1095
  children: /* @__PURE__ */ i(
1088
1096
  "svg",
@@ -1096,45 +1104,52 @@ function pe({
1096
1104
  strokeLinecap: "round",
1097
1105
  strokeLinejoin: "round",
1098
1106
  "aria-hidden": "true",
1099
- children: n
1107
+ children: r
1100
1108
  }
1101
1109
  )
1102
1110
  }
1103
1111
  );
1104
- }
1105
- function Ct({
1112
+ });
1113
+ function Ht({
1106
1114
  state: e,
1107
1115
  labels: t,
1108
1116
  onPlay: n,
1109
1117
  onPause: r,
1110
- onResume: s,
1111
- onStop: o
1118
+ onResume: o,
1119
+ onStop: s
1112
1120
  }) {
1113
- return e === "idle" ? /* @__PURE__ */ p(pe, { label: t.play, onClick: n, children: [
1114
- /* @__PURE__ */ i("polygon", { points: "11 5 6 9 2 9 2 15 6 15 11 19 11 5" }),
1115
- /* @__PURE__ */ i("path", { d: "M15.54 8.46a5 5 0 0 1 0 7.07", fill: "none" }),
1116
- /* @__PURE__ */ i("path", { d: "M19.07 4.93a10 10 0 0 1 0 14.14", fill: "none" })
1117
- ] }) : /* @__PURE__ */ p("div", { className: "flex items-center gap-1", children: [
1118
- e === "paused" ? /* @__PURE__ */ i(pe, { label: t.resume, onClick: s, children: /* @__PURE__ */ i("polygon", { points: "6 3 20 12 6 21 6 3" }) }) : /* @__PURE__ */ p(pe, { label: t.pause, onClick: r, children: [
1121
+ var d;
1122
+ const a = S(null), c = S(null), l = !!((d = a.current) != null && d.contains(document.activeElement));
1123
+ W(() => {
1124
+ var x, A;
1125
+ e === "idle" && l && !((x = a.current) != null && x.contains(document.activeElement)) && ((A = c.current) == null || A.focus());
1126
+ }, [e, l]);
1127
+ const u = e === "idle" ? { label: t.play, onClick: n } : e === "paused" ? { label: t.resume, onClick: o } : { label: t.pause, onClick: r };
1128
+ return /* @__PURE__ */ w("div", { ref: a, className: "flex items-center gap-1", children: [
1129
+ /* @__PURE__ */ i(Pe, { ref: c, ...u, children: e === "idle" ? /* @__PURE__ */ w(ve, { children: [
1130
+ /* @__PURE__ */ i("polygon", { points: "11 5 6 9 2 9 2 15 6 15 11 19 11 5" }),
1131
+ /* @__PURE__ */ i("path", { d: "M15.54 8.46a5 5 0 0 1 0 7.07", fill: "none" }),
1132
+ /* @__PURE__ */ i("path", { d: "M19.07 4.93a10 10 0 0 1 0 14.14", fill: "none" })
1133
+ ] }) : e === "paused" ? /* @__PURE__ */ i("polygon", { points: "6 3 20 12 6 21 6 3" }) : /* @__PURE__ */ w(ve, { children: [
1119
1134
  /* @__PURE__ */ i("rect", { x: "6", y: "4", width: "4", height: "16", rx: "1" }),
1120
1135
  /* @__PURE__ */ i("rect", { x: "14", y: "4", width: "4", height: "16", rx: "1" })
1121
- ] }),
1122
- /* @__PURE__ */ i(pe, { label: t.stop, onClick: o, children: /* @__PURE__ */ i("rect", { x: "6", y: "6", width: "12", height: "12", rx: "1.5" }) })
1136
+ ] }) }),
1137
+ e !== "idle" && /* @__PURE__ */ i(Pe, { label: t.stop, onClick: s, children: /* @__PURE__ */ i("rect", { x: "6", y: "6", width: "12", height: "12", rx: "1.5" }) })
1123
1138
  ] });
1124
1139
  }
1125
- function At(e) {
1140
+ function Ft(e) {
1126
1141
  const t = e.lastIndexOf(`
1127
1142
  `), n = t === -1 ? "" : e.slice(0, t + 1);
1128
1143
  let r = t === -1 ? e : e.slice(t + 1);
1129
- return r = Lt(r), r = Dt(r), n + r;
1144
+ return r = Kt(r), r = Vt(r), n + r;
1130
1145
  }
1131
- function Nt(e) {
1146
+ function Wt(e) {
1132
1147
  const t = [];
1133
1148
  for (let n = 0; n < e.length - 1; n++)
1134
1149
  e[n] === "*" && e[n + 1] === "*" && (t.push(n), n++);
1135
1150
  return t;
1136
1151
  }
1137
- function Mt(e) {
1152
+ function Gt(e) {
1138
1153
  const t = [];
1139
1154
  for (let n = 0; n < e.length; n++)
1140
1155
  if (e[n] === "*") {
@@ -1146,32 +1161,32 @@ function Mt(e) {
1146
1161
  }
1147
1162
  return t;
1148
1163
  }
1149
- function Lt(e) {
1150
- const t = Nt(e);
1164
+ function Kt(e) {
1165
+ const t = Wt(e);
1151
1166
  if (t.length % 2 === 0) return e;
1152
1167
  const n = t[t.length - 1], r = e.slice(n + 2);
1153
1168
  return r.trim() === "" ? e.slice(0, n) + r : e + "**";
1154
1169
  }
1155
- function Dt(e) {
1156
- const t = Mt(e);
1170
+ function Vt(e) {
1171
+ const t = Gt(e);
1157
1172
  if (t.length % 2 === 0) return e;
1158
1173
  const n = t[t.length - 1], r = e.slice(n + 1);
1159
1174
  return r.trim() === "" ? e.slice(0, n) + r : e + "*";
1160
1175
  }
1161
- function It({
1176
+ function Yt({
1162
1177
  toolUse: e,
1163
1178
  usedLabel: t,
1164
1179
  detailsLabel: n
1165
1180
  }) {
1166
- const [r, s] = O(!1), o = e.input !== void 0 || e.result !== void 0;
1167
- return /* @__PURE__ */ p("div", { className: "text-xs text-claudius-text-muted", children: [
1168
- /* @__PURE__ */ p(
1181
+ const [r, o] = N(!1), s = e.input !== void 0 || e.result !== void 0;
1182
+ return /* @__PURE__ */ w("div", { className: "text-xs text-claudius-text-muted", children: [
1183
+ /* @__PURE__ */ w(
1169
1184
  "button",
1170
1185
  {
1171
1186
  type: "button",
1172
- disabled: !o,
1173
- onClick: () => s((a) => !a),
1174
- "aria-expanded": o ? r : void 0,
1187
+ disabled: !s,
1188
+ onClick: () => o((a) => !a),
1189
+ "aria-expanded": s ? r : void 0,
1175
1190
  className: "flex items-center gap-1.5 rounded-claudius-full border border-claudius-border bg-claudius-surface px-2 py-0.5 hover:opacity-80 disabled:cursor-default disabled:hover:opacity-100",
1176
1191
  children: [
1177
1192
  /* @__PURE__ */ i(
@@ -1189,13 +1204,13 @@ function It({
1189
1204
  children: /* @__PURE__ */ i("path", { d: "M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z" })
1190
1205
  }
1191
1206
  ),
1192
- /* @__PURE__ */ p("span", { children: [
1207
+ /* @__PURE__ */ w("span", { children: [
1193
1208
  t,
1194
1209
  " ",
1195
1210
  /* @__PURE__ */ i("span", { className: "font-mono text-claudius-text", children: e.name }),
1196
1211
  e.isError && /* @__PURE__ */ i("span", { className: "text-claudius-error", children: " ✕" })
1197
1212
  ] }),
1198
- o && /* @__PURE__ */ p(we, { children: [
1213
+ s && /* @__PURE__ */ w(ve, { children: [
1199
1214
  /* @__PURE__ */ i("span", { className: "sr-only", children: n }),
1200
1215
  /* @__PURE__ */ i(
1201
1216
  "svg",
@@ -1217,113 +1232,113 @@ function It({
1217
1232
  ]
1218
1233
  }
1219
1234
  ),
1220
- r && o && /* @__PURE__ */ p("div", { className: "mt-1 overflow-x-auto rounded-claudius-sm border border-claudius-border bg-claudius-field p-2 font-mono", children: [
1235
+ r && s && /* @__PURE__ */ w("div", { className: "mt-1 overflow-x-auto rounded-claudius-sm border border-claudius-border bg-claudius-field p-2 font-mono", children: [
1221
1236
  e.input !== void 0 && /* @__PURE__ */ i("pre", { className: "whitespace-pre-wrap break-all", children: JSON.stringify(e.input, null, 2) }),
1222
1237
  e.result !== void 0 && /* @__PURE__ */ i("pre", { className: "mt-1 whitespace-pre-wrap break-all border-t border-claudius-border pt-1", children: e.result })
1223
1238
  ] })
1224
1239
  ] });
1225
1240
  }
1226
- const Ce = /(https?:\/\/[^\s)]+)/, Ae = /(\*\*[^*]+\*\*)/, Ne = /(\*[^*]+\*)/;
1227
- function Ot(e, t) {
1228
- const n = e.match(/[.,;:!?'"]+$/), r = n ? e.slice(0, -n[0].length) : e, s = n ? n[0] : "", o = Ee(r);
1229
- return o ? /* @__PURE__ */ p(we, { children: [
1230
- /* @__PURE__ */ p(
1241
+ const Ue = /(https?:\/\/[^\s)]+)/, Be = /(\*\*[^*]+\*\*)/, _e = /(\*[^*]+\*)/;
1242
+ function qt(e, t) {
1243
+ const n = e.match(/[.,;:!?'"]+$/), r = n ? e.slice(0, -n[0].length) : e, o = n ? n[0] : "", s = Ce(r);
1244
+ return s ? /* @__PURE__ */ w(ve, { children: [
1245
+ /* @__PURE__ */ w(
1231
1246
  "a",
1232
1247
  {
1233
- href: o,
1248
+ href: s,
1234
1249
  target: "_blank",
1235
1250
  rel: "noopener noreferrer",
1236
1251
  className: "underline font-medium hover:opacity-80 text-claudius-link",
1237
1252
  children: [
1238
- o.replace(/^https?:\/\//, ""),
1253
+ s.replace(/^https?:\/\//, ""),
1239
1254
  /* @__PURE__ */ i("span", { className: "sr-only", children: " (opens in a new tab)" })
1240
1255
  ]
1241
1256
  },
1242
1257
  t
1243
1258
  ),
1244
- s
1259
+ o
1245
1260
  ] }) : e;
1246
1261
  }
1247
- function jt(e, t) {
1248
- const n = e.split(Ae), r = [];
1249
- return n.forEach((s, o) => {
1250
- if (Ae.test(s)) {
1251
- const a = s.slice(2, -2);
1252
- r.push(/* @__PURE__ */ i("strong", { children: a }, `${t}-b${o}`));
1262
+ function Zt(e, t) {
1263
+ const n = e.split(Be), r = [];
1264
+ return n.forEach((o, s) => {
1265
+ if (Be.test(o)) {
1266
+ const a = o.slice(2, -2);
1267
+ r.push(/* @__PURE__ */ i("strong", { children: a }, `${t}-b${s}`));
1253
1268
  } else
1254
- s.split(Ne).forEach((c, u) => {
1255
- if (Ne.test(c)) {
1256
- const l = c.slice(1, -1);
1257
- r.push(/* @__PURE__ */ i("em", { children: l }, `${t}-b${o}-i${u}`));
1269
+ o.split(_e).forEach((c, l) => {
1270
+ if (_e.test(c)) {
1271
+ const u = c.slice(1, -1);
1272
+ r.push(/* @__PURE__ */ i("em", { children: u }, `${t}-b${s}-i${l}`));
1258
1273
  } else
1259
- c.split(Ce).forEach((m, E) => {
1260
- Ce.test(m) ? r.push(
1261
- Ot(m, `${t}-b${o}-i${u}-u${E}`)
1262
- ) : m && r.push(m);
1274
+ c.split(Ue).forEach((d, x) => {
1275
+ Ue.test(d) ? r.push(
1276
+ qt(d, `${t}-b${s}-i${l}-u${x}`)
1277
+ ) : d && r.push(d);
1263
1278
  });
1264
1279
  });
1265
1280
  }), r;
1266
1281
  }
1267
- function Pt(e) {
1282
+ function Jt(e) {
1268
1283
  const t = e.split(`
1269
1284
  `);
1270
- return t.map((n, r) => /* @__PURE__ */ p("span", { children: [
1271
- jt(n, `l${r}`),
1285
+ return t.map((n, r) => /* @__PURE__ */ w("span", { children: [
1286
+ Zt(n, `l${r}`),
1272
1287
  r < t.length - 1 && /* @__PURE__ */ i("br", {})
1273
1288
  ] }, r));
1274
1289
  }
1275
- const Bt = ge(function({
1290
+ const Qt = ke(function({
1276
1291
  role: t,
1277
1292
  content: n,
1278
1293
  isStreaming: r = !1,
1279
- sources: s,
1280
- attachments: o,
1294
+ sources: o,
1295
+ attachments: s,
1281
1296
  toolUses: a,
1282
1297
  toolUsedLabel: c = "Used tool:",
1283
- toolDetailsLabel: u = "Tool details",
1284
- onSourceClick: l,
1285
- isSourceActive: m,
1286
- speech: E
1298
+ toolDetailsLabel: l = "Tool details",
1299
+ onSourceClick: u,
1300
+ isSourceActive: d,
1301
+ speech: x
1287
1302
  }) {
1288
- const N = t === "user", g = !!o && o.length > 0, d = r ? At(n) : n, f = N || n !== "" || !(a != null && a.length);
1289
- return /* @__PURE__ */ p("div", { className: `${N ? "ml-auto" : "mr-auto"} max-w-[85%]`, children: [
1290
- f && /* @__PURE__ */ p(
1303
+ const A = t === "user", g = !!s && s.length > 0, f = r ? Ft(n) : n, p = A || n !== "" || !(a != null && a.length);
1304
+ return /* @__PURE__ */ w("div", { className: `${A ? "ml-auto" : "mr-auto"} max-w-[85%]`, children: [
1305
+ p && /* @__PURE__ */ w(
1291
1306
  "div",
1292
1307
  {
1293
- className: `rounded-claudius-bubble px-4 py-2.5 text-sm leading-relaxed font-body ${N ? "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"}`,
1308
+ 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"}`,
1294
1309
  children: [
1295
1310
  g && /* @__PURE__ */ i(
1296
1311
  "ul",
1297
1312
  {
1298
1313
  className: `flex flex-wrap gap-2 ${n ? "mb-2" : ""}`,
1299
1314
  "aria-label": "Attachments",
1300
- children: o.map((v) => /* @__PURE__ */ i("li", { children: /* @__PURE__ */ i(_e, { attachment: v, variant: "message" }) }, v.id))
1315
+ children: s.map((T) => /* @__PURE__ */ i("li", { children: /* @__PURE__ */ i(tt, { attachment: T, variant: "message" }) }, T.id))
1301
1316
  }
1302
1317
  ),
1303
- (n !== "" || !g) && Pt(d)
1318
+ (n !== "" || !g) && Jt(f)
1304
1319
  ]
1305
1320
  }
1306
1321
  ),
1307
- !N && a && a.length > 0 && /* @__PURE__ */ i("div", { className: "mt-1 space-y-1", children: a.map((v, D) => /* @__PURE__ */ i(
1308
- It,
1322
+ !A && a && a.length > 0 && /* @__PURE__ */ i("div", { className: "mt-1 space-y-1", children: a.map((T, b) => /* @__PURE__ */ i(
1323
+ Yt,
1309
1324
  {
1310
- toolUse: v,
1325
+ toolUse: T,
1311
1326
  usedLabel: c,
1312
- detailsLabel: u
1327
+ detailsLabel: l
1313
1328
  },
1314
- `${v.name}-${D}`
1329
+ `${T.name}-${b}`
1315
1330
  )) }),
1316
- !N && s && s.length > 0 && l && /* @__PURE__ */ i("div", { className: "mt-1", children: /* @__PURE__ */ i(
1317
- Tt,
1331
+ !A && o && o.length > 0 && u && /* @__PURE__ */ i("div", { className: "mt-1", children: /* @__PURE__ */ i(
1332
+ Bt,
1318
1333
  {
1319
- count: s.length,
1320
- isActive: m ?? !1,
1321
- onClick: l
1334
+ count: o.length,
1335
+ isActive: d ?? !1,
1336
+ onClick: u
1322
1337
  }
1323
1338
  ) }),
1324
- !N && E && /* @__PURE__ */ i("div", { className: "mt-1", children: /* @__PURE__ */ i(Ct, { ...E }) })
1339
+ !A && x && /* @__PURE__ */ i("div", { className: "mt-1", children: /* @__PURE__ */ i(Ht, { ...x }) })
1325
1340
  ] });
1326
- }), ze = {
1341
+ }), nt = {
1327
1342
  // ChatWindow
1328
1343
  title: "Chat",
1329
1344
  subtitle: "Ask me anything",
@@ -1362,6 +1377,19 @@ const Bt = ge(function({
1362
1377
  pauseReading: "Pause reading",
1363
1378
  resumeReading: "Resume reading",
1364
1379
  stopReading: "Stop reading",
1380
+ // Conversation export
1381
+ moreOptions: "More options",
1382
+ copyAsMarkdown: "Copy as Markdown",
1383
+ downloadAsMarkdown: "Download as Markdown",
1384
+ downloadAsJson: "Download as JSON",
1385
+ copiedToClipboard: "Copied to clipboard",
1386
+ copyFailed: "Could not copy. Try downloading instead.",
1387
+ transcriptTitle: "Chat transcript",
1388
+ transcriptExported: "Exported {date}",
1389
+ transcriptUser: "User",
1390
+ transcriptAssistant: "Assistant",
1391
+ transcriptAttachments: "Attachments:",
1392
+ transcriptSources: "Sources:",
1365
1393
  // Errors
1366
1394
  errorGeneric: "Something went wrong. Please try again.",
1367
1395
  errorConnection: "Failed to connect. Please try again.",
@@ -1371,54 +1399,58 @@ const Bt = ge(function({
1371
1399
  errorAttachmentRejected: "An attachment was rejected. Please remove it and try again.",
1372
1400
  errorAttachmentQuota: "Upload limit reached. Please try again later.",
1373
1401
  errorRetry: "Retry"
1374
- }, Ue = ze;
1375
- function Hn(e) {
1376
- return { ...Ue, ...e };
1402
+ }, Oe = nt;
1403
+ function xr(e) {
1404
+ return { ...Oe, ...e };
1377
1405
  }
1378
- function Me(e) {
1406
+ function ze(e) {
1379
1407
  return e.key === " " || e.key === "Enter";
1380
1408
  }
1381
- function Ht({
1409
+ function Xt({
1382
1410
  mode: e,
1383
1411
  isListening: t,
1384
1412
  disabled: n = !1,
1385
1413
  onStart: r,
1386
- onStop: s,
1387
- label: o
1414
+ onStop: o,
1415
+ label: s
1388
1416
  }) {
1389
- const a = e === "hold", c = L(!1), u = () => {
1390
- n || c.current || (c.current = !0, r());
1391
- }, l = () => {
1392
- c.current && (c.current = !1, s());
1417
+ const a = e === "hold", c = S(!1), l = () => {
1418
+ n || c.current || (c.current = !0, r({ held: !0 }));
1419
+ }, u = () => {
1420
+ c.current && (c.current = !1, o());
1393
1421
  };
1394
1422
  return /* @__PURE__ */ i(
1395
1423
  "button",
1396
1424
  {
1397
1425
  type: "button",
1398
1426
  disabled: n,
1399
- "aria-label": o,
1427
+ "aria-label": s,
1400
1428
  "aria-pressed": t,
1401
- title: o,
1402
- onClick: (d) => {
1403
- a && d.detail !== 0 || (t ? s() : r());
1429
+ title: s,
1430
+ onClick: (f) => {
1431
+ a && f.detail !== 0 || (t ? o() : r({ held: !1 }));
1404
1432
  },
1405
- onPointerDown: (d) => {
1406
- var f, v;
1407
- !a || d.button !== 0 || ((v = (f = d.currentTarget).setPointerCapture) == null || v.call(f, d.pointerId), u());
1433
+ onPointerDown: (f) => {
1434
+ var p, T;
1435
+ !a || f.button !== 0 || ((T = (p = f.currentTarget).setPointerCapture) == null || T.call(p, f.pointerId), l());
1408
1436
  },
1409
- onPointerUp: l,
1410
- onPointerCancel: l,
1411
- onLostPointerCapture: l,
1412
- onKeyDown: (d) => {
1413
- !a || !Me(d) || (d.preventDefault(), d.repeat || u());
1437
+ onPointerUp: u,
1438
+ onPointerCancel: u,
1439
+ onLostPointerCapture: u,
1440
+ onKeyDown: (f) => {
1441
+ !a || !ze(f) || (f.preventDefault(), f.repeat || l());
1414
1442
  },
1415
- onKeyUp: (d) => {
1416
- !a || !Me(d) || (d.preventDefault(), l());
1443
+ onKeyUp: (f) => {
1444
+ !a || !ze(f) || (f.preventDefault(), u());
1417
1445
  },
1418
- onBlur: l,
1419
- onContextMenu: a ? (d) => d.preventDefault() : void 0,
1446
+ onBlur: u,
1447
+ onContextMenu: a ? (f) => f.preventDefault() : void 0,
1420
1448
  style: a ? { WebkitTouchCallout: "none" } : void 0,
1421
- className: `flex h-11 w-11 shrink-0 items-center justify-center rounded-claudius-sm border transition-colors focus:outline-none focus:ring-1 focus:ring-claudius-accent disabled:opacity-50 ${t ? "border-claudius-accent bg-claudius-accent text-claudius-accent-text" : "border-claudius-border bg-claudius-field text-claudius-text-muted hover:text-claudius-text focus:border-claudius-accent"} ${a ? "touch-none select-none" : ""}`,
1449
+ className: `flex h-11 w-11 shrink-0 items-center justify-center rounded-claudius-sm border transition-colors focus:outline-none focus:ring-1 focus:ring-claudius-accent disabled:opacity-50 ${t ? (
1450
+ // An accent ring on an accent fill is invisible; offset it so
1451
+ // keyboard users can still see where focus is.
1452
+ "border-claudius-accent bg-claudius-accent text-claudius-accent-text focus:ring-2 focus:ring-offset-2 focus:ring-offset-claudius-surface"
1453
+ ) : "border-claudius-border bg-claudius-field text-claudius-text-muted hover:text-claudius-text focus:border-claudius-accent"} ${a ? "touch-none select-none" : ""}`,
1422
1454
  children: t && !a ? (
1423
1455
  // Same stop square the send button turns into while a reply streams:
1424
1456
  // it says what a click will do, and keeps this button from looking
@@ -1434,7 +1466,7 @@ function Ht({
1434
1466
  children: /* @__PURE__ */ i("rect", { x: "6", y: "6", width: "12", height: "12", rx: "1.5" })
1435
1467
  }
1436
1468
  )
1437
- ) : /* @__PURE__ */ p(
1469
+ ) : /* @__PURE__ */ w(
1438
1470
  "svg",
1439
1471
  {
1440
1472
  width: "16",
@@ -1456,8 +1488,8 @@ function Ht({
1456
1488
  }
1457
1489
  );
1458
1490
  }
1459
- function _t({ active: e }) {
1460
- return /* @__PURE__ */ p(
1491
+ function en({ active: e }) {
1492
+ return /* @__PURE__ */ w(
1461
1493
  "span",
1462
1494
  {
1463
1495
  "aria-hidden": "true",
@@ -1472,85 +1504,89 @@ function _t({ active: e }) {
1472
1504
  }
1473
1505
  );
1474
1506
  }
1475
- function be(e, t) {
1507
+ function Re(e, t) {
1476
1508
  return e.replace(
1477
1509
  /\{(\w+)\}/g,
1478
1510
  (n, r) => r in t ? String(t[r]) : n
1479
1511
  );
1480
1512
  }
1481
- const zt = {
1513
+ const tn = {
1482
1514
  en: "en-US",
1483
1515
  es: "es-ES",
1484
1516
  fr: "fr-FR",
1485
1517
  de: "de-DE"
1486
- }, Ut = ["toggle", "hold"];
1487
- function Le(e, t) {
1518
+ }, nn = ["toggle", "hold"];
1519
+ function He(e, t) {
1488
1520
  if (!(!e || !e.includes("-")))
1489
1521
  return e.toLowerCase().split("-")[0] === t ? e : void 0;
1490
1522
  }
1491
- function $t(e, t) {
1523
+ function rt(e, t) {
1492
1524
  const n = t == null ? void 0 : t.trim();
1493
1525
  if (n) return n;
1494
- const r = typeof document < "u" ? Le(document.documentElement.lang, e) : void 0;
1526
+ const r = typeof document < "u" ? He(document.documentElement.lang, e) : void 0;
1495
1527
  if (r) return r;
1496
- const s = typeof navigator < "u" ? Le(navigator.language, e) : void 0;
1497
- return s || zt[e];
1498
- }
1499
- function Ft(e, t) {
1500
- if (!e) return null;
1501
- const n = e === !0 ? {} : e, r = {
1502
- input: n.input ?? !0,
1503
- output: n.output ?? !0,
1528
+ const o = typeof navigator < "u" ? He(navigator.language, e) : void 0;
1529
+ return o || tn[e];
1530
+ }
1531
+ function rn(e, t) {
1532
+ const n = typeof e == "object" && e !== null && !Array.isArray(e);
1533
+ if (e !== !0 && !n) return null;
1534
+ const r = e === !0 ? {} : e, o = {
1535
+ input: r.input ?? !0,
1536
+ output: r.output ?? !0,
1504
1537
  // `mode` can arrive from an HTML attribute, so tolerate junk.
1505
- mode: Ut.includes(n.mode) ? n.mode : "toggle",
1506
- autoSubmit: n.autoSubmit ?? !1,
1507
- lang: $t(t, n.lang)
1538
+ mode: nn.includes(r.mode) ? r.mode : "toggle",
1539
+ autoSubmit: r.autoSubmit ?? !1,
1540
+ lang: rt(t, r.lang)
1508
1541
  };
1509
- return r.input || r.output ? r : null;
1542
+ return o.input || o.output ? o : null;
1510
1543
  }
1511
- function Wt(e, t, n) {
1544
+ function on(e, t, n) {
1512
1545
  const r = t.trim();
1513
1546
  if (!r) return e;
1514
- const s = e.trimEnd();
1515
- return (s ? `${s} ${r}` : r).slice(0, n);
1547
+ const o = e.trimEnd();
1548
+ return (o ? `${o} ${r}` : r).slice(0, n);
1516
1549
  }
1517
- function Gt(e) {
1550
+ function sn(e) {
1518
1551
  const t = [];
1519
1552
  let n = 0;
1520
1553
  for (let r = 0; r < e.length; r++) {
1521
- const s = e[r];
1522
- (s === `
1523
- ` || (s === "." || s === "!" || s === "?") && (r + 1 === e.length || /\s/.test(e[r + 1]))) && (t.push(e.slice(n, r + 1)), n = r + 1);
1554
+ const o = e[r];
1555
+ (o === `
1556
+ ` || o === "。" || o === "!" || o === "?" || (o === "." || o === "!" || o === "?") && (r + 1 === e.length || /\s/.test(e[r + 1]))) && (t.push(e.slice(n, r + 1)), n = r + 1);
1524
1557
  }
1525
1558
  return n < e.length && t.push(e.slice(n)), t;
1526
1559
  }
1527
- function Vt(e, t = 200) {
1560
+ function an(e, t = 150) {
1528
1561
  const n = [];
1529
1562
  let r = "";
1530
- const s = () => {
1531
- const o = r.trim();
1532
- o && n.push(o), r = "";
1563
+ const o = () => {
1564
+ const s = r.trim();
1565
+ s && n.push(s), r = "";
1533
1566
  };
1534
- for (const o of Gt(e)) {
1535
- if ((r + o).trim().length <= t) {
1536
- r += o;
1567
+ for (const s of sn(e)) {
1568
+ if ((r + s).trim().length <= t) {
1569
+ r += s;
1537
1570
  continue;
1538
1571
  }
1539
- if (s(), o.trim().length <= t) {
1540
- r = o;
1572
+ if (o(), s.trim().length <= t) {
1573
+ r = s;
1541
1574
  continue;
1542
1575
  }
1543
- for (const a of o.trim().split(/\s+/))
1544
- r && `${r} ${a}`.length > t && s(), r = r ? `${r} ${a}` : a;
1576
+ for (let a of s.trim().split(/\s+/)) {
1577
+ for (r && `${r} ${a}`.length > t && o(); a.length > t; )
1578
+ n.push(a.slice(0, t)), a = a.slice(t);
1579
+ r = r ? `${r} ${a}` : a;
1580
+ }
1545
1581
  }
1546
- return s(), n;
1582
+ return o(), n;
1547
1583
  }
1548
- function De() {
1584
+ function Fe() {
1549
1585
  if (typeof window > "u") return;
1550
1586
  const e = window;
1551
1587
  return e.SpeechRecognition ?? e.webkitSpeechRecognition;
1552
1588
  }
1553
- function Kt(e) {
1589
+ function cn(e) {
1554
1590
  switch (e) {
1555
1591
  case "not-allowed":
1556
1592
  case "service-not-allowed":
@@ -1563,217 +1599,237 @@ function Kt(e) {
1563
1599
  return "unavailable";
1564
1600
  }
1565
1601
  }
1566
- function Yt(e) {
1567
- const [t] = O(() => De() !== void 0), [n, r] = O(!1), [s, o] = O(!1), a = L(null), c = L(!1), u = L(e);
1568
- K(() => {
1569
- u.current = e;
1602
+ function ln(e) {
1603
+ const [t] = N(() => Fe() !== void 0), [n, r] = N(!1), [o, s] = N(!1), a = S(null), c = S(!1), l = S(e);
1604
+ W(() => {
1605
+ l.current = e;
1570
1606
  });
1571
- const l = M((g) => {
1572
- g.onstart = null, g.onend = null, g.onerror = null, g.onresult = null, g.onspeechstart = null, g.onspeechend = null, a.current === g && (a.current = null), r(!1), o(!1);
1573
- }, []), m = M(() => {
1607
+ const u = M((g) => {
1608
+ g.onstart = null, g.onend = null, g.onerror = null, g.onresult = null, g.onspeechstart = null, g.onspeechend = null, a.current === g && (a.current = null), r(!1), s(!1);
1609
+ }, []), d = M(() => {
1574
1610
  const g = a.current;
1575
- g && (l(g), g.abort());
1576
- }, [l]), E = M(() => {
1611
+ g && (u(g), g.abort());
1612
+ }, [u]), x = M(() => {
1577
1613
  const g = a.current;
1578
- if (g) {
1579
- if (!c.current) {
1580
- m();
1581
- return;
1582
- }
1583
- g.stop();
1584
- }
1585
- }, [m]), N = M(() => {
1586
- var D, C;
1587
- const g = De();
1588
- if (!g || a.current) return;
1589
- const d = new g();
1590
- d.lang = u.current.lang, d.interimResults = !0, d.continuous = !1;
1591
- let f = "", v = !1;
1592
- d.onstart = () => {
1614
+ return g ? (c.current ? g.stop() : d(), !0) : !1;
1615
+ }, [d]), A = M(() => {
1616
+ var b, R;
1617
+ const g = Fe();
1618
+ if (!g || a.current) return !1;
1619
+ const f = new g();
1620
+ f.lang = l.current.lang, f.interimResults = !0, f.continuous = !1;
1621
+ let p = "";
1622
+ const T = () => {
1593
1623
  c.current = !0;
1594
- }, d.onspeechstart = () => o(!0), d.onspeechend = () => o(!1), d.onresult = (T) => {
1595
- var A, B;
1596
- let b = "", k = "";
1597
- for (let y = 0; y < T.results.length; y++) {
1598
- const W = T.results[y];
1599
- W.isFinal ? b += W[0].transcript : k += W[0].transcript;
1624
+ };
1625
+ f.onstart = T, f.onspeechstart = () => {
1626
+ T(), s(!0);
1627
+ }, f.onspeechend = () => s(!1), f.onresult = (y) => {
1628
+ var $, L;
1629
+ let v = "", C = "";
1630
+ for (let E = 0; E < y.results.length; E++) {
1631
+ const B = y.results[E];
1632
+ B.isFinal ? v += B[0].transcript : C += B[0].transcript;
1600
1633
  }
1601
- f = b, o(!0), (B = (A = u.current).onTranscript) == null || B.call(A, b + k);
1602
- }, d.onerror = (T) => {
1603
- var b, k;
1604
- T.error !== "aborted" && (v = !0, (k = (b = u.current).onError) == null || k.call(b, Kt(T.error)));
1605
- }, d.onend = () => {
1606
- var T, b;
1607
- l(d), v || (b = (T = u.current).onEnd) == null || b.call(T, f);
1608
- }, a.current = d, c.current = !1, r(!0);
1634
+ p = v, T(), s(!0), (L = ($ = l.current).onTranscript) == null || L.call($, v + C);
1635
+ }, f.onerror = (y) => {
1636
+ var v, C;
1637
+ y.error !== "aborted" && ((C = (v = l.current).onError) == null || C.call(v, cn(y.error))), u(f), f.abort();
1638
+ }, f.onend = () => {
1639
+ var y, v;
1640
+ u(f), (v = (y = l.current).onEnd) == null || v.call(y, p);
1641
+ }, a.current = f, c.current = !1, r(!0);
1609
1642
  try {
1610
- d.start();
1643
+ f.start();
1611
1644
  } catch {
1612
- l(d), (C = (D = u.current).onError) == null || C.call(D, "unavailable");
1645
+ return u(f), (R = (b = l.current).onError) == null || R.call(b, "unavailable"), !1;
1613
1646
  }
1614
- }, [l]);
1615
- return K(() => m, [m]), { isSupported: t, isListening: n, isSpeechDetected: s, start: N, stop: E, abort: m };
1647
+ return !0;
1648
+ }, [u]);
1649
+ return W(() => d, [d]), { isSupported: t, isListening: n, isSpeechDetected: o, start: A, stop: x, abort: d };
1616
1650
  }
1617
- const le = 2e3, qt = 1800;
1618
- function Ie(e) {
1651
+ const ye = 2e3, un = 1800;
1652
+ function We(e) {
1619
1653
  var n;
1620
1654
  const t = (n = e.dataTransfer) == null ? void 0 : n.types;
1621
1655
  return !!t && Array.from(t).includes("Files");
1622
1656
  }
1623
- function Qt({
1657
+ function dn({
1624
1658
  onSend: e,
1625
1659
  isLoading: t,
1626
1660
  isStreaming: n = !1,
1627
1661
  onStop: r,
1628
- placeholder: s,
1629
- translations: o,
1662
+ placeholder: o,
1663
+ translations: s,
1630
1664
  attachments: a = null,
1631
1665
  voice: c = null,
1632
- onVoiceStart: u
1666
+ onVoiceStart: l,
1667
+ isReadingAloud: u = !1
1633
1668
  }) {
1634
- const l = o ?? Ue, [m, E] = O(""), [N, g] = O([]), [d, f] = O(null), [v, D] = O(!1), [C, T] = O(null), b = L(null), k = L(null), A = L([]), B = L(0), y = L(""), W = L(""), U = (h) => {
1635
- y.current = h, E(h);
1636
- }, H = m.length, _ = H >= qt, J = H >= le, re = s ?? l.placeholder, X = !!a && N.length < a.maxCount, te = n && !!r;
1637
- K(() => {
1638
- var h;
1639
- t || (h = b.current) == null || h.focus();
1669
+ const d = s ?? Oe, [x, A] = N(""), [g, f] = N([]), [p, T] = N(null), [b, R] = N(!1), [y, v] = N(null), C = S(null), $ = S(null), L = S([]), E = S(0), B = S(""), O = S(""), _ = S(!1), q = S(!1), G = S(!1), J = (m) => {
1670
+ B.current = m, A(m);
1671
+ }, z = x.length, ae = z >= un, ie = z >= ye, ce = o ?? d.placeholder, re = !!a && g.length < a.maxCount, h = n && !!r;
1672
+ W(() => {
1673
+ var m;
1674
+ t || (m = C.current) == null || m.focus();
1640
1675
  }, [t]);
1641
- const w = M(
1642
- (h, S) => {
1676
+ const P = M(
1677
+ (m, j) => {
1643
1678
  if (!a) return "";
1644
- switch (S) {
1679
+ switch (j) {
1645
1680
  case "size":
1646
- return be(l.attachmentTooLarge, {
1647
- name: h,
1648
- max: xe(a.maxSizeBytes)
1681
+ return Re(d.attachmentTooLarge, {
1682
+ name: m,
1683
+ max: Se(a.maxSizeBytes)
1649
1684
  });
1650
1685
  case "type":
1651
- return be(l.attachmentTypeNotAllowed, { name: h });
1686
+ return Re(d.attachmentTypeNotAllowed, { name: m });
1652
1687
  case "count":
1653
- return be(l.attachmentTooMany, {
1688
+ return Re(d.attachmentTooMany, {
1654
1689
  max: a.maxCount
1655
1690
  });
1656
1691
  }
1657
1692
  },
1658
- [a, l]
1659
- ), ee = M(
1660
- async (h) => {
1661
- if (!a || h.length === 0) return;
1662
- const { accepted: S, rejected: F } = ct(
1663
- h,
1664
- A.current.length,
1693
+ [a, d]
1694
+ ), U = M(
1695
+ async (m) => {
1696
+ if (!a || m.length === 0) return;
1697
+ const { accepted: j, rejected: fe } = Rt(
1698
+ m,
1699
+ L.current.length,
1665
1700
  a
1666
1701
  );
1667
- if (f(
1668
- F.length > 0 ? w(F[0].file.name, F[0].reason) : null
1669
- ), S.length === 0) return;
1670
- const ce = await Promise.all(S.map(dt));
1671
- A.current = [...A.current, ...ce], g(A.current);
1702
+ if (T(
1703
+ fe.length > 0 ? P(fe[0].file.name, fe[0].reason) : null
1704
+ ), j.length === 0) return;
1705
+ const ut = await Promise.all(j.map(kt));
1706
+ L.current = [...L.current, ...ut], f(L.current);
1672
1707
  },
1673
- [a, w]
1674
- ), ie = M((h) => {
1675
- A.current = A.current.filter((S) => S.id !== h), g(A.current), f(null);
1676
- }, []), x = () => {
1677
- const h = y.current.trim(), S = A.current;
1678
- !h && S.length === 0 || y.current.length >= le || (S.length > 0 ? e(h, S) : e(h), U(""), A.current = [], g([]), f(null));
1679
- }, z = (h) => {
1680
- switch (h) {
1708
+ [a, P]
1709
+ ), ee = M((m) => {
1710
+ L.current = L.current.filter((j) => j.id !== m), f(L.current), T(null);
1711
+ }, []), te = () => {
1712
+ const m = B.current.trim(), j = L.current;
1713
+ !m && j.length === 0 || B.current.length >= ye || (j.length > 0 ? e(m, j) : e(m), J(""), L.current = [], f([]), T(null), v(null));
1714
+ }, ne = (m) => {
1715
+ switch (m) {
1681
1716
  case "permission":
1682
- return l.voicePermissionDenied;
1717
+ return d.voicePermissionDenied;
1683
1718
  case "no-speech":
1684
- return l.voiceNoSpeech;
1719
+ return d.voiceNoSpeech;
1685
1720
  case "no-microphone":
1686
- return l.voiceNoMicrophone;
1721
+ return d.voiceNoMicrophone;
1687
1722
  case "unavailable":
1688
- return l.voiceUnavailable;
1723
+ return d.voiceUnavailable;
1689
1724
  }
1690
- }, I = Yt({
1725
+ }, F = ln({
1691
1726
  lang: (c == null ? void 0 : c.lang) ?? "en-US",
1692
- onTranscript: (h) => U(
1693
- Wt(W.current, h, le)
1727
+ onTranscript: (m) => J(
1728
+ on(O.current, m, ye)
1694
1729
  ),
1695
- onEnd: (h) => {
1696
- c != null && c.autoSubmit && h.trim() && x();
1730
+ onEnd: (m) => {
1731
+ const j = m.trim() !== "";
1732
+ if (j && (q.current = !0), !_.current) {
1733
+ D();
1734
+ return;
1735
+ }
1736
+ j && I();
1697
1737
  },
1698
- onError: (h) => T(z(h))
1699
- }), Q = !!(c != null && c.input) && I.isSupported, $ = I.isListening;
1700
- K(() => {
1701
- const h = b.current;
1702
- $ && h && (h.scrollLeft = h.scrollWidth);
1703
- }, [$, m]);
1704
- const ne = () => {
1705
- T(null), W.current = y.current, u == null || u(), I.start();
1706
- }, Z = (h) => {
1707
- h.preventDefault(), I.abort(), x();
1708
- }, R = (h) => {
1709
- const S = h.target.value;
1710
- S.length <= le && (I.abort(), T(null), U(S));
1711
- }, j = (h) => {
1712
- const S = Array.from(h.target.files ?? []);
1713
- h.target.value = "", ee(S);
1714
- }, P = (h) => {
1715
- var F;
1738
+ onError: (m) => {
1739
+ m === "no-speech" && q.current || (G.current = !0, v(ne(m)));
1740
+ }
1741
+ }), H = !!(c != null && c.input) && F.isSupported, k = F.isListening;
1742
+ W(() => {
1743
+ const m = C.current;
1744
+ k && m && (m.scrollLeft = m.scrollWidth);
1745
+ }, [k, x]);
1746
+ const D = () => {
1747
+ c != null && c.autoSubmit && q.current && !G.current && te();
1748
+ }, I = () => {
1749
+ const m = B.current;
1750
+ F.start() && (O.current = m);
1751
+ }, K = ({ held: m }) => {
1752
+ v(null), _.current = m, q.current = !1, G.current = !1, l == null || l(), I();
1753
+ }, Q = () => {
1754
+ const m = _.current;
1755
+ _.current = !1, !F.stop() && m && D();
1756
+ }, le = () => {
1757
+ _.current = !1, F.abort();
1758
+ }, { abort: Y } = F;
1759
+ W(() => {
1760
+ !t && !u || (_.current = !1, Y());
1761
+ }, [t, u, Y]);
1762
+ const me = (m) => {
1763
+ m.preventDefault(), le(), te();
1764
+ }, ue = (m) => {
1765
+ const j = m.target.value;
1766
+ j.length <= ye && (le(), v(null), J(j));
1767
+ }, V = (m) => {
1768
+ const j = Array.from(m.target.files ?? []);
1769
+ m.target.value = "", U(j);
1770
+ }, oe = (m) => {
1771
+ var fe;
1716
1772
  if (!a) return;
1717
- const S = Array.from(((F = h.clipboardData) == null ? void 0 : F.files) ?? []);
1718
- S.length !== 0 && (h.preventDefault(), ee(S));
1773
+ const j = Array.from(((fe = m.clipboardData) == null ? void 0 : fe.files) ?? []);
1774
+ j.length !== 0 && (m.preventDefault(), U(j));
1719
1775
  };
1720
- return /* @__PURE__ */ p(
1776
+ return /* @__PURE__ */ w(
1721
1777
  "form",
1722
1778
  {
1723
- onSubmit: Z,
1724
- onDragEnter: (h) => {
1725
- !a || !Ie(h) || (h.preventDefault(), B.current += 1, D(!0));
1779
+ onSubmit: me,
1780
+ onDragEnter: (m) => {
1781
+ !a || !We(m) || (m.preventDefault(), E.current += 1, R(!0));
1726
1782
  },
1727
- onDragOver: (h) => {
1728
- !a || !Ie(h) || h.preventDefault();
1783
+ onDragOver: (m) => {
1784
+ !a || !We(m) || m.preventDefault();
1729
1785
  },
1730
1786
  onDragLeave: () => {
1731
- a && (B.current = Math.max(0, B.current - 1), B.current === 0 && D(!1));
1787
+ a && (E.current = Math.max(0, E.current - 1), E.current === 0 && R(!1));
1732
1788
  },
1733
- onDrop: (h) => {
1734
- var S;
1735
- a && (h.preventDefault(), B.current = 0, D(!1), ee(Array.from(((S = h.dataTransfer) == null ? void 0 : S.files) ?? [])));
1789
+ onDrop: (m) => {
1790
+ var j;
1791
+ a && (m.preventDefault(), E.current = 0, R(!1), U(Array.from(((j = m.dataTransfer) == null ? void 0 : j.files) ?? [])));
1736
1792
  },
1737
- "data-drag-over": v || void 0,
1738
- className: `relative border-t border-claudius-border bg-claudius-surface p-3 ${v ? "ring-2 ring-inset ring-claudius-accent" : ""}`,
1793
+ "data-drag-over": b || void 0,
1794
+ className: `relative border-t border-claudius-border bg-claudius-surface p-3 ${b ? "ring-2 ring-inset ring-claudius-accent" : ""}`,
1739
1795
  children: [
1740
- v && /* @__PURE__ */ i(
1796
+ b && /* @__PURE__ */ i(
1741
1797
  "div",
1742
1798
  {
1743
1799
  "aria-hidden": "true",
1744
1800
  className: "pointer-events-none absolute inset-0 z-10 flex items-center justify-center bg-claudius-surface text-sm font-medium text-claudius-accent",
1745
- children: l.dropFilesHint
1801
+ children: d.dropFilesHint
1746
1802
  }
1747
1803
  ),
1748
- a && N.length > 0 && /* @__PURE__ */ i(
1804
+ a && g.length > 0 && /* @__PURE__ */ i(
1749
1805
  "ul",
1750
1806
  {
1751
- "aria-label": l.attachmentsLabel,
1807
+ "aria-label": d.attachmentsLabel,
1752
1808
  className: "mb-2 flex flex-wrap gap-3 pt-1",
1753
- children: N.map((h) => /* @__PURE__ */ i("li", { children: /* @__PURE__ */ i(
1754
- _e,
1809
+ children: g.map((m) => /* @__PURE__ */ i("li", { children: /* @__PURE__ */ i(
1810
+ tt,
1755
1811
  {
1756
- attachment: h,
1812
+ attachment: m,
1757
1813
  variant: "composer",
1758
- onRemove: () => ie(h.id),
1759
- removeLabel: `${l.removeAttachment}: ${h.name}`
1814
+ onRemove: () => ee(m.id),
1815
+ removeLabel: `${d.removeAttachment}: ${m.name}`
1760
1816
  }
1761
- ) }, h.id))
1817
+ ) }, m.id))
1762
1818
  }
1763
1819
  ),
1764
- /* @__PURE__ */ p("div", { className: "flex gap-2", children: [
1765
- a && /* @__PURE__ */ p(we, { children: [
1820
+ /* @__PURE__ */ w("div", { className: "flex gap-2", children: [
1821
+ a && /* @__PURE__ */ w(ve, { children: [
1766
1822
  /* @__PURE__ */ i(
1767
1823
  "input",
1768
1824
  {
1769
- ref: k,
1825
+ ref: $,
1770
1826
  type: "file",
1771
1827
  multiple: !0,
1772
1828
  hidden: !0,
1773
1829
  tabIndex: -1,
1774
1830
  accept: a.allowedTypes.join(","),
1775
- onChange: j,
1776
- "aria-label": l.attachFile
1831
+ onChange: V,
1832
+ "aria-label": d.attachFile
1777
1833
  }
1778
1834
  ),
1779
1835
  /* @__PURE__ */ i(
@@ -1781,12 +1837,12 @@ function Qt({
1781
1837
  {
1782
1838
  type: "button",
1783
1839
  onClick: () => {
1784
- var h;
1785
- return (h = k.current) == null ? void 0 : h.click();
1840
+ var m;
1841
+ return (m = $.current) == null ? void 0 : m.click();
1786
1842
  },
1787
- disabled: t || !X,
1788
- "aria-label": l.attachFile,
1789
- title: l.attachFile,
1843
+ disabled: t || !re,
1844
+ "aria-label": d.attachFile,
1845
+ title: d.attachFile,
1790
1846
  className: "flex h-11 w-11 shrink-0 items-center justify-center rounded-claudius-sm border border-claudius-border bg-claudius-field text-claudius-text-muted transition-colors hover:text-claudius-text focus:border-claudius-accent focus:outline-none focus:ring-1 focus:ring-claudius-accent disabled:opacity-50",
1791
1847
  children: /* @__PURE__ */ i(
1792
1848
  "svg",
@@ -1806,41 +1862,41 @@ function Qt({
1806
1862
  }
1807
1863
  )
1808
1864
  ] }),
1809
- /* @__PURE__ */ p("div", { className: "relative min-w-0 flex-1", children: [
1865
+ /* @__PURE__ */ w("div", { className: "relative min-w-0 flex-1", children: [
1810
1866
  /* @__PURE__ */ i(
1811
1867
  "input",
1812
1868
  {
1813
- ref: b,
1869
+ ref: C,
1814
1870
  type: "text",
1815
- value: m,
1816
- onChange: R,
1817
- onPaste: P,
1818
- placeholder: $ ? l.voiceListening : re,
1871
+ value: x,
1872
+ onChange: ue,
1873
+ onPaste: oe,
1874
+ placeholder: k ? d.voiceListening : ce,
1819
1875
  disabled: t,
1820
- "aria-label": l.typeYourMessage,
1821
- "aria-describedby": _ ? "char-count" : void 0,
1822
- className: `h-full w-full rounded-claudius-sm border border-claudius-border bg-claudius-field py-2 pl-3 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 ${$ ? "pr-10" : "pr-3"}`
1876
+ "aria-label": d.typeYourMessage,
1877
+ "aria-describedby": ae ? "char-count" : void 0,
1878
+ className: `h-full w-full rounded-claudius-sm border border-claudius-border bg-claudius-field py-2 pl-3 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 ${k ? "pr-10" : "pr-3"}`
1823
1879
  }
1824
1880
  ),
1825
- $ && /* @__PURE__ */ i(_t, { active: I.isSpeechDetected })
1881
+ k && /* @__PURE__ */ i(en, { active: F.isSpeechDetected })
1826
1882
  ] }),
1827
- Q && c && /* @__PURE__ */ i(
1828
- Ht,
1883
+ H && c && /* @__PURE__ */ i(
1884
+ Xt,
1829
1885
  {
1830
1886
  mode: c.mode,
1831
- isListening: $,
1887
+ isListening: k,
1832
1888
  disabled: t,
1833
- onStart: ne,
1834
- onStop: I.stop,
1835
- label: c.mode === "hold" ? l.voiceInputHold : l.voiceInput
1889
+ onStart: K,
1890
+ onStop: Q,
1891
+ label: c.mode === "hold" ? d.voiceInputHold : d.voiceInput
1836
1892
  }
1837
1893
  ),
1838
- te ? /* @__PURE__ */ i(
1894
+ h ? /* @__PURE__ */ i(
1839
1895
  "button",
1840
1896
  {
1841
1897
  type: "button",
1842
1898
  onClick: r,
1843
- "aria-label": l.stopGenerating,
1899
+ "aria-label": d.stopGenerating,
1844
1900
  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",
1845
1901
  children: /* @__PURE__ */ i(
1846
1902
  "svg",
@@ -1858,10 +1914,10 @@ function Qt({
1858
1914
  "button",
1859
1915
  {
1860
1916
  type: "submit",
1861
- disabled: t || J,
1862
- "aria-label": l.sendMessage,
1917
+ disabled: t || ie,
1918
+ "aria-label": d.sendMessage,
1863
1919
  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",
1864
- children: /* @__PURE__ */ p(
1920
+ children: /* @__PURE__ */ w(
1865
1921
  "svg",
1866
1922
  {
1867
1923
  width: "16",
@@ -1882,17 +1938,17 @@ function Qt({
1882
1938
  }
1883
1939
  )
1884
1940
  ] }),
1885
- (d ?? C) && /* @__PURE__ */ i("div", { role: "alert", className: "mt-1 text-xs text-claudius-error", children: d ?? C }),
1886
- _ && /* @__PURE__ */ p(
1941
+ (p ?? y) && /* @__PURE__ */ i("div", { role: "alert", className: "mt-1 text-xs text-claudius-error", children: p ?? y }),
1942
+ ae && /* @__PURE__ */ w(
1887
1943
  "div",
1888
1944
  {
1889
1945
  id: "char-count",
1890
- className: `mt-1 text-xs text-right ${J ? "text-claudius-error" : "text-claudius-text-muted"}`,
1946
+ className: `mt-1 text-xs text-right ${ie ? "text-claudius-error" : "text-claudius-text-muted"}`,
1891
1947
  "aria-live": "polite",
1892
1948
  children: [
1893
- H,
1949
+ z,
1894
1950
  "/",
1895
- le
1951
+ ye
1896
1952
  ]
1897
1953
  }
1898
1954
  )
@@ -1900,32 +1956,32 @@ function Qt({
1900
1956
  }
1901
1957
  );
1902
1958
  }
1903
- const Zt = ["blog", "page", "external"], Jt = {
1959
+ const fn = ["blog", "page", "external"], hn = {
1904
1960
  blog: "Blog",
1905
1961
  page: "Page",
1906
1962
  external: "External"
1907
1963
  };
1908
- function Xt(e) {
1964
+ function pn(e) {
1909
1965
  try {
1910
1966
  return new URL(e).hostname;
1911
1967
  } catch {
1912
1968
  return e;
1913
1969
  }
1914
1970
  }
1915
- const en = ge(function({
1971
+ const mn = ke(function({
1916
1972
  sources: t,
1917
1973
  onClose: n
1918
1974
  }) {
1919
- const r = Zt.map((o) => ({
1920
- type: o,
1921
- label: Jt[o],
1922
- items: t.filter((a) => a.type === o)
1923
- })).filter((o) => o.items.length > 0), s = t.length === 1 ? "1 source found" : `${t.length} sources found`;
1924
- return /* @__PURE__ */ p("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: [
1925
- /* @__PURE__ */ p("div", { className: "flex items-center justify-between border-b border-claudius-border px-4 py-3", children: [
1926
- /* @__PURE__ */ p("div", { children: [
1975
+ const r = fn.map((s) => ({
1976
+ type: s,
1977
+ label: hn[s],
1978
+ items: t.filter((a) => a.type === s)
1979
+ })).filter((s) => s.items.length > 0), o = t.length === 1 ? "1 source found" : `${t.length} sources found`;
1980
+ return /* @__PURE__ */ w("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: [
1981
+ /* @__PURE__ */ w("div", { className: "flex items-center justify-between border-b border-claudius-border px-4 py-3", children: [
1982
+ /* @__PURE__ */ w("div", { children: [
1927
1983
  /* @__PURE__ */ i("h3", { className: "text-sm font-heading font-semibold text-claudius-text", children: "Sources" }),
1928
- /* @__PURE__ */ i("p", { className: "text-xs text-claudius-text-muted", children: s })
1984
+ /* @__PURE__ */ i("p", { className: "text-xs text-claudius-text-muted", children: o })
1929
1985
  ] }),
1930
1986
  /* @__PURE__ */ i(
1931
1987
  "button",
@@ -1933,7 +1989,7 @@ const en = ge(function({
1933
1989
  onClick: n,
1934
1990
  "aria-label": "Close sources",
1935
1991
  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",
1936
- children: /* @__PURE__ */ p(
1992
+ children: /* @__PURE__ */ w(
1937
1993
  "svg",
1938
1994
  {
1939
1995
  width: "14",
@@ -1954,11 +2010,11 @@ const en = ge(function({
1954
2010
  }
1955
2011
  )
1956
2012
  ] }),
1957
- /* @__PURE__ */ i("div", { className: "flex-1 overflow-y-auto px-3 py-3 space-y-4", children: r.map((o) => /* @__PURE__ */ p("div", { children: [
1958
- /* @__PURE__ */ i("h4", { className: "mb-2 text-xs font-semibold uppercase tracking-wide text-claudius-text-muted", children: o.label }),
1959
- /* @__PURE__ */ i("div", { className: "space-y-2", children: o.items.map((a) => {
1960
- const c = Ee(a.url);
1961
- return c ? /* @__PURE__ */ p(
2013
+ /* @__PURE__ */ i("div", { className: "flex-1 overflow-y-auto px-3 py-3 space-y-4", children: r.map((s) => /* @__PURE__ */ w("div", { children: [
2014
+ /* @__PURE__ */ i("h4", { className: "mb-2 text-xs font-semibold uppercase tracking-wide text-claudius-text-muted", children: s.label }),
2015
+ /* @__PURE__ */ i("div", { className: "space-y-2", children: s.items.map((a) => {
2016
+ const c = Ce(a.url);
2017
+ return c ? /* @__PURE__ */ w(
1962
2018
  "a",
1963
2019
  {
1964
2020
  href: c,
@@ -1967,23 +2023,24 @@ const en = ge(function({
1967
2023
  className: "block rounded-claudius-md border-2 border-claudius-border bg-claudius-surface-muted p-3 transition-colors hover:bg-claudius-border",
1968
2024
  children: [
1969
2025
  /* @__PURE__ */ i("p", { className: "truncate text-sm font-medium text-claudius-text", children: a.title }),
1970
- /* @__PURE__ */ i("p", { className: "mt-0.5 text-xs text-claudius-text-muted", children: Xt(c) })
2026
+ /* @__PURE__ */ i("p", { className: "mt-0.5 text-xs text-claudius-text-muted", children: pn(c) })
1971
2027
  ]
1972
2028
  },
1973
2029
  c
1974
2030
  ) : null;
1975
2031
  }) })
1976
- ] }, o.type)) })
2032
+ ] }, s.type)) })
1977
2033
  ] });
1978
2034
  });
1979
- function tn({
2035
+ function gn({
1980
2036
  title: e,
1981
2037
  subtitle: t,
1982
2038
  titleId: n,
1983
2039
  closeLabel: r,
1984
- onClose: s
2040
+ onClose: o,
2041
+ actions: s
1985
2042
  }) {
1986
- return /* @__PURE__ */ p("div", { className: "flex items-center gap-3 bg-claudius-accent px-5 py-4", children: [
2043
+ return /* @__PURE__ */ w("div", { className: "flex items-center gap-3 bg-claudius-accent px-5 py-4", children: [
1987
2044
  /* @__PURE__ */ i(
1988
2045
  "div",
1989
2046
  {
@@ -1992,7 +2049,7 @@ function tn({
1992
2049
  children: e.charAt(0).toUpperCase()
1993
2050
  }
1994
2051
  ),
1995
- /* @__PURE__ */ p("div", { className: "flex-1", children: [
2052
+ /* @__PURE__ */ w("div", { className: "flex-1", children: [
1996
2053
  /* @__PURE__ */ i(
1997
2054
  "h2",
1998
2055
  {
@@ -2003,13 +2060,14 @@ function tn({
2003
2060
  ),
2004
2061
  /* @__PURE__ */ i("p", { className: "text-xs text-claudius-accent-text", children: t })
2005
2062
  ] }),
2063
+ s,
2006
2064
  /* @__PURE__ */ i(
2007
2065
  "button",
2008
2066
  {
2009
- onClick: s,
2067
+ onClick: o,
2010
2068
  "aria-label": r,
2011
2069
  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",
2012
- children: /* @__PURE__ */ p(
2070
+ children: /* @__PURE__ */ w(
2013
2071
  "svg",
2014
2072
  {
2015
2073
  width: "18",
@@ -2031,12 +2089,12 @@ function tn({
2031
2089
  )
2032
2090
  ] });
2033
2091
  }
2034
- function nn({
2092
+ function bn({
2035
2093
  message: e,
2036
2094
  retryLabel: t,
2037
2095
  onRetry: n
2038
2096
  }) {
2039
- return /* @__PURE__ */ p(
2097
+ return /* @__PURE__ */ w(
2040
2098
  "div",
2041
2099
  {
2042
2100
  role: "alert",
@@ -2056,7 +2114,7 @@ function nn({
2056
2114
  }
2057
2115
  );
2058
2116
  }
2059
- function rn({ label: e }) {
2117
+ function yn({ label: e }) {
2060
2118
  return /* @__PURE__ */ i(
2061
2119
  "div",
2062
2120
  {
@@ -2064,7 +2122,7 @@ function rn({ label: e }) {
2064
2122
  "aria-live": "polite",
2065
2123
  "aria-label": e,
2066
2124
  className: "mr-auto flex max-w-[85%]",
2067
- children: /* @__PURE__ */ p("div", { className: "flex gap-1 rounded-claudius-bubble rounded-bl-claudius-tail bg-claudius-assistant-bubble px-4 py-3", children: [
2125
+ children: /* @__PURE__ */ w("div", { className: "flex gap-1 rounded-claudius-bubble rounded-bl-claudius-tail bg-claudius-assistant-bubble px-4 py-3", children: [
2068
2126
  /* @__PURE__ */ i("span", { className: "h-2 w-2 motion-safe:animate-bounce rounded-claudius-full bg-claudius-text-muted [animation-delay:0ms]" }),
2069
2127
  /* @__PURE__ */ i("span", { className: "h-2 w-2 motion-safe:animate-bounce rounded-claudius-full bg-claudius-text-muted [animation-delay:150ms]" }),
2070
2128
  /* @__PURE__ */ i("span", { className: "h-2 w-2 motion-safe:animate-bounce rounded-claudius-full bg-claudius-text-muted [animation-delay:300ms]" })
@@ -2072,237 +2130,672 @@ function rn({ label: e }) {
2072
2130
  }
2073
2131
  );
2074
2132
  }
2075
- function sn(e, t, n) {
2076
- const [r, s] = O(0), o = L(0), a = L(0), c = L(0), u = L(!1);
2077
- return K(() => {
2078
- const l = e.current;
2079
- if (!n || !l) return;
2080
- const m = (g) => {
2081
- if (l.scrollTop > 0) {
2082
- u.current = !1;
2133
+ function xn({ label: e, items: t, onOpen: n }) {
2134
+ const [r, o] = N(!1), s = Ne(), a = Ne(), c = S(null), l = S(null), u = S([]), d = S(null), x = (b) => {
2135
+ d.current = b, o(!0), n == null || n();
2136
+ }, A = (b) => {
2137
+ var R;
2138
+ o(!1), (R = l.current) == null || R.focus();
2139
+ };
2140
+ W(() => {
2141
+ var R;
2142
+ if (!r) return;
2143
+ d.current !== null && ((R = u.current[d.current]) == null || R.focus(), d.current = null);
2144
+ const b = (y) => {
2145
+ var v;
2146
+ (v = c.current) != null && v.contains(y.target) || o(!1);
2147
+ };
2148
+ return document.addEventListener("pointerdown", b), () => document.removeEventListener("pointerdown", b);
2149
+ }, [r]);
2150
+ const g = (b) => {
2151
+ var y;
2152
+ const R = t.length;
2153
+ (y = u.current[(b + R) % R]) == null || y.focus();
2154
+ };
2155
+ return /* @__PURE__ */ w("div", { ref: c, className: "relative", children: [
2156
+ /* @__PURE__ */ i(
2157
+ "button",
2158
+ {
2159
+ ref: l,
2160
+ id: s,
2161
+ type: "button",
2162
+ "aria-label": e,
2163
+ "aria-haspopup": "menu",
2164
+ "aria-expanded": r,
2165
+ "aria-controls": r ? a : void 0,
2166
+ onClick: () => r ? A() : x(0),
2167
+ onKeyDown: (b) => {
2168
+ b.key === "ArrowDown" ? (b.preventDefault(), x(0)) : b.key === "ArrowUp" && (b.preventDefault(), x(t.length - 1));
2169
+ },
2170
+ 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",
2171
+ children: /* @__PURE__ */ w(
2172
+ "svg",
2173
+ {
2174
+ width: "18",
2175
+ height: "18",
2176
+ viewBox: "0 0 24 24",
2177
+ fill: "currentColor",
2178
+ "aria-hidden": "true",
2179
+ children: [
2180
+ /* @__PURE__ */ i("circle", { cx: "12", cy: "5", r: "1.75" }),
2181
+ /* @__PURE__ */ i("circle", { cx: "12", cy: "12", r: "1.75" }),
2182
+ /* @__PURE__ */ i("circle", { cx: "12", cy: "19", r: "1.75" })
2183
+ ]
2184
+ }
2185
+ )
2186
+ }
2187
+ ),
2188
+ r && /* @__PURE__ */ i(
2189
+ "div",
2190
+ {
2191
+ id: a,
2192
+ role: "menu",
2193
+ "aria-labelledby": s,
2194
+ tabIndex: -1,
2195
+ onKeyDown: (b) => {
2196
+ const R = u.current.findIndex(
2197
+ (y) => y === document.activeElement
2198
+ );
2199
+ switch (b.key) {
2200
+ case "ArrowDown":
2201
+ b.preventDefault(), g(R + 1);
2202
+ break;
2203
+ case "ArrowUp":
2204
+ b.preventDefault(), g(R === -1 ? t.length - 1 : R - 1);
2205
+ break;
2206
+ case "Home":
2207
+ b.preventDefault(), g(0);
2208
+ break;
2209
+ case "End":
2210
+ b.preventDefault(), g(t.length - 1);
2211
+ break;
2212
+ case "Escape":
2213
+ b.preventDefault(), b.stopPropagation(), A();
2214
+ break;
2215
+ case "Tab":
2216
+ b.shiftKey && (b.preventDefault(), A());
2217
+ break;
2218
+ }
2219
+ },
2220
+ onBlur: (b) => {
2221
+ var y;
2222
+ const R = b.relatedTarget;
2223
+ R && ((y = c.current) != null && y.contains(R) || o(!1));
2224
+ },
2225
+ className: "absolute right-0 top-full z-20 mt-1 min-w-[12rem] rounded-claudius-md border border-claudius-border bg-claudius-surface py-1 shadow-claudius-elevated",
2226
+ children: t.map((b, R) => /* @__PURE__ */ i(
2227
+ "button",
2228
+ {
2229
+ ref: (y) => {
2230
+ u.current[R] = y;
2231
+ },
2232
+ type: "button",
2233
+ role: "menuitem",
2234
+ tabIndex: -1,
2235
+ "aria-disabled": b.disabled || void 0,
2236
+ onClick: () => {
2237
+ b.disabled || (A(), b.onSelect());
2238
+ },
2239
+ className: "flex min-h-[40px] w-full items-center whitespace-nowrap px-4 text-left text-sm text-claudius-text hover:bg-claudius-surface-muted focus:bg-claudius-surface-muted aria-disabled:cursor-default aria-disabled:opacity-50 aria-disabled:hover:bg-transparent",
2240
+ children: b.label
2241
+ },
2242
+ b.id
2243
+ ))
2244
+ }
2245
+ )
2246
+ ] });
2247
+ }
2248
+ function wn(e, t, n) {
2249
+ const [r, o] = N(0), s = S(0), a = S(0), c = S(0), l = S(!1);
2250
+ return W(() => {
2251
+ const u = e.current;
2252
+ if (!n || !u) return;
2253
+ const d = (g) => {
2254
+ if (u.scrollTop > 0) {
2255
+ l.current = !1;
2083
2256
  return;
2084
2257
  }
2085
- u.current = !0, a.current = g.touches[0].clientY, c.current = Date.now();
2086
- }, E = (g) => {
2087
- if (!u.current) return;
2088
- let d = g.touches[0].clientY - a.current;
2089
- d < 0 && (d = d * 0.3), o.current = d, s(d);
2090
- }, N = () => {
2091
- if (!u.current) return;
2092
- u.current = !1;
2093
- const g = o.current, d = (Date.now() - c.current) / 1e3, f = l.getBoundingClientRect().height, v = d > 0.05 && g > 0 && g / d > 500, D = g > f * 0.3;
2094
- v || D ? t() : (o.current = 0, s(0));
2258
+ l.current = !0, a.current = g.touches[0].clientY, c.current = Date.now();
2259
+ }, x = (g) => {
2260
+ if (!l.current) return;
2261
+ let f = g.touches[0].clientY - a.current;
2262
+ f < 0 && (f = f * 0.3), s.current = f, o(f);
2263
+ }, A = () => {
2264
+ if (!l.current) return;
2265
+ l.current = !1;
2266
+ const g = s.current, f = (Date.now() - c.current) / 1e3, p = u.getBoundingClientRect().height, T = f > 0.05 && g > 0 && g / f > 500, b = g > p * 0.3;
2267
+ T || b ? t() : (s.current = 0, o(0));
2095
2268
  };
2096
- return l.addEventListener("touchstart", m, { passive: !0 }), l.addEventListener("touchmove", E, { passive: !0 }), l.addEventListener("touchend", N), () => {
2097
- l.removeEventListener("touchstart", m), l.removeEventListener("touchmove", E), l.removeEventListener("touchend", N);
2269
+ return u.addEventListener("touchstart", d, { passive: !0 }), u.addEventListener("touchmove", x, { passive: !0 }), u.addEventListener("touchend", A), () => {
2270
+ u.removeEventListener("touchstart", d), u.removeEventListener("touchmove", x), u.removeEventListener("touchend", A);
2098
2271
  };
2099
2272
  }, [e, t, n]), { offsetY: r };
2100
2273
  }
2101
- const on = 'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';
2102
- function an(e, t) {
2103
- K(() => {
2274
+ const vn = 'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';
2275
+ function Tn(e, t) {
2276
+ W(() => {
2104
2277
  const n = e.current;
2105
2278
  if (!n) return;
2106
- const r = (s) => {
2107
- if (s.key !== "Tab") return;
2108
- const o = Array.from(
2109
- n.querySelectorAll(on)
2110
- ).filter((l) => !l.hasAttribute("aria-hidden"));
2111
- if (o.length === 0) return;
2112
- const a = o[0], c = o[o.length - 1], u = document.activeElement;
2113
- s.shiftKey && u === a ? (s.preventDefault(), c.focus()) : !s.shiftKey && u === c && (s.preventDefault(), a.focus());
2279
+ const r = (o) => {
2280
+ if (o.key !== "Tab") return;
2281
+ const s = Array.from(
2282
+ n.querySelectorAll(vn)
2283
+ ).filter((u) => !u.hasAttribute("aria-hidden"));
2284
+ if (s.length === 0) return;
2285
+ const a = s[0], c = s[s.length - 1], l = document.activeElement;
2286
+ o.shiftKey && l === a ? (o.preventDefault(), c.focus()) : !o.shiftKey && l === c && (o.preventDefault(), a.focus());
2114
2287
  };
2115
2288
  return n.addEventListener("keydown", r), () => n.removeEventListener("keydown", r);
2116
2289
  }, [e, t]);
2117
2290
  }
2118
- function ue() {
2291
+ function xe() {
2119
2292
  if (!(typeof window > "u") && !(typeof window.SpeechSynthesisUtterance > "u"))
2120
2293
  return window.speechSynthesis ?? void 0;
2121
2294
  }
2122
- function cn(e) {
2123
- const [t] = O(() => ue() !== void 0), [n, r] = O(null), [s, o] = O(!1), a = L(0), c = L(!1), u = L([]), l = M(() => {
2124
- a.current += 1, c.current = !1, u.current = [], r(null), o(!1);
2125
- }, []), m = M(() => {
2126
- var d;
2127
- l(), (d = ue()) == null || d.cancel();
2128
- }, [l]), E = M(
2129
- (d, f) => {
2130
- const v = ue();
2131
- if (!v) return;
2132
- l(), (v.speaking || v.pending) && v.cancel();
2133
- const D = Vt(f);
2134
- if (D.length === 0) return;
2135
- const C = a.current, T = () => a.current === C;
2136
- u.current = D.map((b, k) => {
2137
- const A = new SpeechSynthesisUtterance(b);
2138
- return A.lang = e, A.onerror = () => {
2139
- T() && m();
2140
- }, A.onend = () => {
2141
- T() && (c.current && !v.paused ? m() : k === D.length - 1 && l());
2142
- }, A;
2143
- }), r(d);
2144
- for (const b of u.current) v.speak(b);
2295
+ function En(e) {
2296
+ const [t] = N(() => xe() !== void 0), [n, r] = N(null), [o, s] = N(!1), a = S(0), c = S(!1), l = S([]), u = M(() => {
2297
+ a.current += 1, c.current = !1, l.current = [], r(null), s(!1);
2298
+ }, []), d = M(() => {
2299
+ const f = l.current.length > 0;
2300
+ u();
2301
+ const p = xe();
2302
+ !f || !p || (p.cancel(), p.paused && p.resume());
2303
+ }, [u]), x = M(
2304
+ (f, p) => {
2305
+ const T = xe();
2306
+ if (!T) return;
2307
+ u(), (T.speaking || T.pending) && T.cancel(), T.paused && T.resume();
2308
+ const b = an(p);
2309
+ if (b.length === 0) return;
2310
+ const R = a.current, y = () => a.current === R;
2311
+ l.current = b.map((v, C) => {
2312
+ const $ = new SpeechSynthesisUtterance(v);
2313
+ return $.lang = e, $.onerror = (L) => {
2314
+ if (!y()) return;
2315
+ (L.error === "interrupted" || L.error === "canceled") && !c.current ? u() : d();
2316
+ }, $.onpause = () => {
2317
+ y() && s(!0);
2318
+ }, $.onresume = () => {
2319
+ y() && s(!1);
2320
+ }, $.onend = () => {
2321
+ y() && (c.current && !T.paused ? d() : C === b.length - 1 && u());
2322
+ }, $;
2323
+ }), r(f);
2324
+ for (const v of l.current) T.speak(v);
2145
2325
  },
2146
- [e, m, l]
2147
- ), N = M(() => {
2148
- const d = ue();
2149
- d && (c.current = !0, d.pause(), o(d.paused));
2326
+ [e, d, u]
2327
+ ), A = M(() => {
2328
+ const f = xe();
2329
+ f && (c.current = !0, f.pause(), f.paused && s(!0));
2150
2330
  }, []), g = M(() => {
2151
- const d = ue();
2152
- d && (c.current = !1, d.resume(), o(!1));
2331
+ const f = xe();
2332
+ f && (c.current = !1, f.resume(), s(!1));
2153
2333
  }, []);
2154
- return K(() => m, [m]), { isSupported: t, activeId: n, isPaused: s, speak: E, pause: N, resume: g, cancel: m };
2334
+ return W(() => d, [d]), { isSupported: t, activeId: n, isPaused: o, speak: x, pause: A, resume: g, cancel: d };
2335
+ }
2336
+ const Rn = /^([ \t]*)(`{3,}|~{3,})(.*)$/, An = /^( {0,3})<(?![A-Za-z][A-Za-z0-9+.-]{1,31}:[^<>\s]*>|[^\s<>@]+@[^\s<>]+>)(?=[A-Za-z!?/])/, Sn = /^(?: {4}|\t)/;
2337
+ function ot(e) {
2338
+ let t = 0;
2339
+ for (const n of e)
2340
+ if (n === " ") t += 1;
2341
+ else if (n === " ") t += 4 - t % 4;
2342
+ else break;
2343
+ return t;
2344
+ }
2345
+ function Ge(e) {
2346
+ let t = e.length;
2347
+ for (; t > 0 && (e[t - 1] === " " || e[t - 1] === " "); ) t -= 1;
2348
+ return t === e.length ? e : e.slice(0, t);
2349
+ }
2350
+ function kn(e) {
2351
+ const t = Rn.exec(e);
2352
+ if (!t) return null;
2353
+ const [, n, r, o] = t;
2354
+ return r[0] === "`" && o.includes("`") ? null : {
2355
+ indent: n,
2356
+ indentColumns: ot(n),
2357
+ char: r[0],
2358
+ length: r.length
2359
+ };
2155
2360
  }
2156
- const ln = /\*\*([^*]+)\*\*/g, un = /\*([^*]+)\*/g, dn = /https?:\/\/[^\s)]+/g;
2157
- function Oe(e) {
2158
- return e.replace(ln, "$1").replace(un, "$1").replace(dn, (t) => {
2361
+ function Cn(e, t) {
2362
+ const n = e.trim();
2363
+ if (n.length < t.length) return !1;
2364
+ for (const r of n)
2365
+ if (r !== t.char) return !1;
2366
+ return ot(e) <= t.indentColumns + 3;
2367
+ }
2368
+ function Mn(e) {
2369
+ const t = e.replace(/\r\n?/g, `
2370
+ `).split(`
2371
+ `), n = [];
2372
+ let r = null;
2373
+ for (let o = 0; o < t.length; o++) {
2374
+ const s = t[o];
2375
+ if (r) {
2376
+ n.push(s), Cn(s, r) && (r = null);
2377
+ continue;
2378
+ }
2379
+ const a = kn(s);
2380
+ if (a) {
2381
+ r = a, n.push(s);
2382
+ continue;
2383
+ }
2384
+ let c = s.replace(An, "$1\\<");
2385
+ const l = t[o + 1];
2386
+ s.trim() !== "" && l !== void 0 && l.trim() !== "" && // Possibly indented code, where trailing spaces would be content.
2387
+ !Sn.test(s) && // Already a hard break.
2388
+ !s.endsWith("\\") && (c = Ge(c) + " "), n.push(c);
2389
+ }
2390
+ if (r)
2391
+ n[n.length - 1] === "" && n.pop(), n.push(r.indent + r.char.repeat(r.length));
2392
+ else {
2393
+ for (; n.length > 0 && n[n.length - 1].trim() === ""; ) n.pop();
2394
+ n.length > 0 && (n[n.length - 1] = Ge(n[n.length - 1]));
2395
+ }
2396
+ return n.join(`
2397
+ `);
2398
+ }
2399
+ const Nn = /[\u00a0\u202f]/g;
2400
+ function Dn(e) {
2401
+ if (e.formatDate) return e.formatDate;
2402
+ const t = (o) => new Intl.DateTimeFormat(o, {
2403
+ dateStyle: "medium",
2404
+ timeStyle: "short",
2405
+ timeZone: e.timeZone
2406
+ });
2407
+ let n = null;
2408
+ try {
2409
+ n = t(e.locale);
2410
+ } catch {
2159
2411
  try {
2160
- return new URL(t).hostname;
2412
+ n = t(void 0);
2413
+ } catch {
2414
+ n = null;
2415
+ }
2416
+ }
2417
+ const r = n;
2418
+ return r ? (o) => r.format(o) : (o) => o.toISOString();
2419
+ }
2420
+ function Ln(e) {
2421
+ const t = Dn(e);
2422
+ return (n) => t(n).replace(Nn, " ");
2423
+ }
2424
+ function In(e, t) {
2425
+ var n;
2426
+ try {
2427
+ return ((n = new Intl.DateTimeFormat("en", {
2428
+ timeZone: t,
2429
+ timeZoneName: "longOffset"
2430
+ }).formatToParts(e).find((o) => o.type === "timeZoneName")) == null ? void 0 : n.value) ?? "";
2431
+ } catch {
2432
+ return "";
2433
+ }
2434
+ }
2435
+ function st(e) {
2436
+ const t = e.replace(/\s+/g, " ").trim();
2437
+ if (t === "") return "";
2438
+ const n = Math.max(
2439
+ 0,
2440
+ ...(t.match(/`+/g) ?? []).map((s) => s.length)
2441
+ ), r = "`".repeat(n + 1), o = t.startsWith("`") || t.endsWith("`") ? " " : "";
2442
+ return `${r}${o}${t}${o}${r}`;
2443
+ }
2444
+ const On = {
2445
+ "(": "%28",
2446
+ ")": "%29",
2447
+ "<": "%3C",
2448
+ ">": "%3E",
2449
+ "\\": "%5C"
2450
+ };
2451
+ function jn(e, t) {
2452
+ const n = pe(e.title || e.url).replace(/\s+/g, " ").trim().replace(/[\\[\]<]/g, "\\$&"), r = Ce(pe(e.url));
2453
+ if (!r) return `${t + 1}. ${n}`;
2454
+ const o = r.replace(/[()<>\\]/g, (s) => On[s]).replace(/\s/g, "%20");
2455
+ return `${t + 1}. [${n}](${o})`;
2456
+ }
2457
+ function $n(e) {
2458
+ const t = st(pe(e.name)), n = Se(Number(e.size));
2459
+ return `- ${t} (${pe(e.mediaType)}, ${n})`;
2460
+ }
2461
+ function pe(e) {
2462
+ return typeof e == "string" ? e : String(e ?? "");
2463
+ }
2464
+ function Ae(e) {
2465
+ return Array.isArray(e) ? e.filter(
2466
+ (t) => t !== null && typeof t == "object"
2467
+ ) : [];
2468
+ }
2469
+ function Pn(e, t) {
2470
+ const { labels: n } = t, r = Ln(t), o = t.now ?? /* @__PURE__ */ new Date(), s = In(o, t.timeZone), a = r(o) + (s ? ` (${s})` : ""), c = [
2471
+ `# ${n.title}`,
2472
+ Re(n.exported, { date: a })
2473
+ ];
2474
+ for (const l of e) {
2475
+ if (l === null || typeof l != "object") continue;
2476
+ const u = l.role === "user" ? n.user : n.assistant, d = l.createdAt ? new Date(l.createdAt) : null, x = d && !Number.isNaN(d.getTime()) ? ` · ${r(d)}` : "";
2477
+ c.push(`## ${u}${x}`);
2478
+ const A = Mn(pe(l.content));
2479
+ A && c.push(A);
2480
+ const g = Ae(l.attachments);
2481
+ g.length && c.push(
2482
+ n.attachments,
2483
+ g.map($n).join(`
2484
+ `)
2485
+ );
2486
+ const f = Ae(l.toolUses);
2487
+ f.length && c.push(
2488
+ f.map(
2489
+ (T) => `${n.toolUsed} ${st(pe(T.name))}`
2490
+ ).join(`
2491
+ `)
2492
+ );
2493
+ const p = Ae(l.sources);
2494
+ p.length && c.push(n.sources, p.map(jn).join(`
2495
+ `));
2496
+ }
2497
+ return c.join(`
2498
+
2499
+ `) + `
2500
+ `;
2501
+ }
2502
+ function Un(e) {
2503
+ const t = e.filter((n) => n !== null && typeof n == "object").map(
2504
+ (n) => n.attachments === void 0 ? n : {
2505
+ ...n,
2506
+ attachments: Ae(n.attachments)
2507
+ }
2508
+ );
2509
+ return JSON.stringify(et(t), null, 2) + `
2510
+ `;
2511
+ }
2512
+ function Ke(e, t = {}) {
2513
+ const n = t.now ?? /* @__PURE__ */ new Date();
2514
+ let r;
2515
+ try {
2516
+ const o = new Intl.DateTimeFormat("en", {
2517
+ timeZone: t.timeZone,
2518
+ year: "numeric",
2519
+ month: "2-digit",
2520
+ day: "2-digit"
2521
+ }).formatToParts(n), s = (a) => {
2522
+ var c;
2523
+ return ((c = o.find((l) => l.type === a)) == null ? void 0 : c.value) ?? "";
2524
+ };
2525
+ r = `${s("year")}-${s("month")}-${s("day")}`;
2526
+ } catch {
2527
+ r = n.toISOString().slice(0, 10);
2528
+ }
2529
+ return `chat-transcript-${r}.${e}`;
2530
+ }
2531
+ function Bn(e) {
2532
+ const t = document.activeElement;
2533
+ let n = null;
2534
+ try {
2535
+ return n = document.createElement("textarea"), n.value = e, n.setAttribute("readonly", ""), n.setAttribute("aria-hidden", "true"), n.style.position = "fixed", n.style.top = "0", n.style.left = "0", n.style.opacity = "0", document.body.appendChild(n), n.focus({ preventScroll: !0 }), n.select(), document.execCommand("copy");
2536
+ } catch {
2537
+ return !1;
2538
+ } finally {
2539
+ n == null || n.remove(), t == null || t.focus();
2540
+ }
2541
+ }
2542
+ async function _n(e) {
2543
+ var t;
2544
+ try {
2545
+ if ((t = navigator.clipboard) != null && t.writeText)
2546
+ return await navigator.clipboard.writeText(e), !0;
2547
+ } catch {
2548
+ }
2549
+ return Bn(e);
2550
+ }
2551
+ const zn = 4e4;
2552
+ function Ve(e, t, n) {
2553
+ const r = URL.createObjectURL(new Blob([t], { type: n })), o = document.createElement("a");
2554
+ o.href = r, o.download = e, o.style.display = "none", document.body.appendChild(o), o.click(), o.remove(), setTimeout(() => URL.revokeObjectURL(r), zn);
2555
+ }
2556
+ const Hn = 4e3;
2557
+ function Fn({
2558
+ enabled: e,
2559
+ messages: t,
2560
+ busy: n,
2561
+ locale: r,
2562
+ translations: o
2563
+ }) {
2564
+ const s = o ?? Oe, [a, c] = N(null), l = S(null), u = S(!0);
2565
+ W(() => (u.current = !0, () => {
2566
+ u.current = !1, l.current && clearTimeout(l.current);
2567
+ }), []);
2568
+ const d = M(() => {
2569
+ l.current && clearTimeout(l.current), l.current = null, c(null);
2570
+ }, []), x = M((g) => {
2571
+ u.current && (l.current && clearTimeout(l.current), c(g), l.current = setTimeout(() => {
2572
+ l.current = null, c(null);
2573
+ }, Hn));
2574
+ }, []);
2575
+ return { items: se(() => {
2576
+ if (!e) return [];
2577
+ const g = n || t.length === 0, f = () => Pn(t, {
2578
+ locale: r,
2579
+ labels: {
2580
+ title: s.transcriptTitle,
2581
+ exported: s.transcriptExported,
2582
+ user: s.transcriptUser,
2583
+ assistant: s.transcriptAssistant,
2584
+ attachments: s.transcriptAttachments,
2585
+ sources: s.transcriptSources,
2586
+ toolUsed: s.toolUsed
2587
+ }
2588
+ });
2589
+ return [
2590
+ {
2591
+ id: "copy-markdown",
2592
+ label: s.copyAsMarkdown,
2593
+ disabled: g,
2594
+ onSelect: () => {
2595
+ _n(f()).then(
2596
+ (p) => x(p ? s.copiedToClipboard : s.copyFailed)
2597
+ );
2598
+ }
2599
+ },
2600
+ {
2601
+ id: "download-markdown",
2602
+ label: s.downloadAsMarkdown,
2603
+ disabled: g,
2604
+ onSelect: () => Ve(
2605
+ Ke("md"),
2606
+ f(),
2607
+ "text/markdown;charset=utf-8"
2608
+ )
2609
+ },
2610
+ {
2611
+ id: "download-json",
2612
+ label: s.downloadAsJson,
2613
+ disabled: g,
2614
+ onSelect: () => Ve(
2615
+ Ke("json"),
2616
+ Un(t),
2617
+ "application/json"
2618
+ )
2619
+ }
2620
+ ];
2621
+ }, [e, n, t, r, s, x]), status: a, clearStatus: d };
2622
+ }
2623
+ const Wn = /\*\*([^*]+)\*\*/g, Gn = /\*([^*]+)\*/g, Kn = /https?:\/\/[^\s)]+/g;
2624
+ function Ye(e) {
2625
+ return e.replace(Wn, "$1").replace(Gn, "$1").replace(Kn, (t) => {
2626
+ var o;
2627
+ const n = ((o = t.match(/[.,;:!?'"]+$/)) == null ? void 0 : o[0]) ?? "", r = n ? t.slice(0, -n.length) : t;
2628
+ try {
2629
+ return new URL(r).hostname + n;
2161
2630
  } catch {
2162
2631
  return t;
2163
2632
  }
2164
2633
  });
2165
2634
  }
2166
- const hn = {
2635
+ const Vn = {
2167
2636
  "bottom-right": "bottom-24 right-3 sm:right-6",
2168
2637
  "bottom-left": "bottom-24 left-3 sm:left-6",
2169
2638
  "top-right": "top-24 right-3 sm:right-6",
2170
2639
  "top-left": "top-24 left-3 sm:left-6"
2171
2640
  };
2172
- function fn({
2641
+ function Yn({
2173
2642
  messages: e,
2174
2643
  isLoading: t,
2175
2644
  isStreaming: n = !1,
2176
2645
  streamingMessageId: r = null,
2177
- error: s,
2178
- canRetry: o = !1,
2646
+ error: o,
2647
+ canRetry: s = !1,
2179
2648
  onSend: a,
2180
2649
  onStop: c,
2181
- onRetry: u,
2182
- onClose: l,
2183
- title: m = "Chat",
2184
- subtitle: E = "Ask me anything",
2185
- welcomeMessage: N = "Hi! How can I help you today?",
2650
+ onRetry: l,
2651
+ onClose: u,
2652
+ title: d = "Chat",
2653
+ subtitle: x = "Ask me anything",
2654
+ welcomeMessage: A = "Hi! How can I help you today?",
2186
2655
  placeholder: g,
2187
- position: d = "bottom-right",
2188
- translations: f,
2189
- isMobile: v = !1,
2190
- attachments: D = null,
2191
- voice: C = null
2656
+ position: f = "bottom-right",
2657
+ translations: p,
2658
+ isMobile: T = !1,
2659
+ attachments: b = null,
2660
+ voice: R = null,
2661
+ conversationExport: y = !1,
2662
+ locale: v = "en-US"
2192
2663
  }) {
2193
- const T = Qe(), b = L(null), k = L(null), [A, B] = O(null);
2194
- an(b, !0);
2195
- const y = cn((C == null ? void 0 : C.lang) ?? "en-US"), W = !!(C != null && C.output) && y.isSupported, U = {
2196
- play: (f == null ? void 0 : f.readAloud) ?? "Read aloud",
2197
- pause: (f == null ? void 0 : f.pauseReading) ?? "Pause reading",
2198
- resume: (f == null ? void 0 : f.resumeReading) ?? "Resume reading",
2199
- stop: (f == null ? void 0 : f.stopReading) ?? "Stop reading"
2200
- }, { offsetY: H } = sn(
2201
- k,
2202
- l,
2203
- v
2204
- ), _ = H !== 0, J = typeof window < "u" && typeof window.matchMedia == "function" ? window.matchMedia("(prefers-reduced-motion: reduce)").matches : !1;
2205
- K(() => {
2206
- const w = k.current;
2207
- w && (w.scrollTop = w.scrollHeight);
2208
- }, [e, t]), K(() => {
2209
- const w = (ee) => {
2210
- ee.key === "Escape" && !ee.isComposing && l();
2664
+ const C = Ne(), $ = S(null), L = S(null), [E, B] = N(null);
2665
+ Tn($, !0);
2666
+ const O = En((R == null ? void 0 : R.lang) ?? "en-US"), _ = !!(R != null && R.output) && O.isSupported, q = {
2667
+ play: (p == null ? void 0 : p.readAloud) ?? "Read aloud",
2668
+ pause: (p == null ? void 0 : p.pauseReading) ?? "Pause reading",
2669
+ resume: (p == null ? void 0 : p.resumeReading) ?? "Resume reading",
2670
+ stop: (p == null ? void 0 : p.stopReading) ?? "Stop reading"
2671
+ }, G = Fn({
2672
+ enabled: y,
2673
+ messages: e,
2674
+ busy: t,
2675
+ locale: v,
2676
+ translations: p
2677
+ }), { offsetY: J } = wn(
2678
+ L,
2679
+ u,
2680
+ T
2681
+ ), z = J !== 0, ae = typeof window < "u" && typeof window.matchMedia == "function" ? window.matchMedia("(prefers-reduced-motion: reduce)").matches : !1;
2682
+ W(() => {
2683
+ const h = L.current;
2684
+ h && (h.scrollTop = h.scrollHeight);
2685
+ }, [e, t]), W(() => {
2686
+ const h = (P) => {
2687
+ P.key === "Escape" && !P.isComposing && !P.defaultPrevented && u();
2211
2688
  };
2212
- return document.addEventListener("keydown", w), () => document.removeEventListener("keydown", w);
2213
- }, [l]);
2214
- const re = (f == null ? void 0 : f.closeChat) ?? "Close chat", X = (f == null ? void 0 : f.chatMessages) ?? "Chat messages", te = [...e].reverse().find((w) => w.role === "assistant");
2215
- return /* @__PURE__ */ p(
2689
+ return document.addEventListener("keydown", h), () => document.removeEventListener("keydown", h);
2690
+ }, [u]);
2691
+ const ie = (p == null ? void 0 : p.closeChat) ?? "Close chat", ce = (p == null ? void 0 : p.chatMessages) ?? "Chat messages", re = [...e].reverse().find((h) => h.role === "assistant");
2692
+ return /* @__PURE__ */ w(
2216
2693
  "div",
2217
2694
  {
2218
- ref: b,
2695
+ ref: $,
2219
2696
  role: "dialog",
2220
- "aria-modal": v ? "true" : void 0,
2221
- "aria-labelledby": T,
2222
- className: v ? "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 ${hn[d]} 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`,
2223
- style: v && !J ? { transform: `translateY(${Math.max(0, H)}px)` } : void 0,
2224
- "data-dragging": _ || void 0,
2697
+ "aria-modal": T ? "true" : void 0,
2698
+ "aria-labelledby": C,
2699
+ className: T ? "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 ${Vn[f]} 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`,
2700
+ style: T && !ae ? { transform: `translateY(${Math.max(0, J)}px)` } : void 0,
2701
+ "data-dragging": z || void 0,
2225
2702
  children: [
2226
- v && /* @__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" }) }),
2703
+ T && /* @__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" }) }),
2227
2704
  /* @__PURE__ */ i(
2228
- tn,
2705
+ gn,
2229
2706
  {
2230
- title: m,
2231
- subtitle: E,
2232
- titleId: T,
2233
- closeLabel: re,
2234
- onClose: l
2707
+ title: d,
2708
+ subtitle: x,
2709
+ titleId: C,
2710
+ closeLabel: ie,
2711
+ onClose: u,
2712
+ actions: y ? /* @__PURE__ */ i(
2713
+ xn,
2714
+ {
2715
+ label: (p == null ? void 0 : p.moreOptions) ?? "More options",
2716
+ items: G.items,
2717
+ onOpen: G.clearStatus
2718
+ }
2719
+ ) : void 0
2235
2720
  }
2236
2721
  ),
2237
- /* @__PURE__ */ p("div", { className: "relative flex-1 overflow-hidden", children: [
2238
- A && /* @__PURE__ */ i(
2239
- en,
2722
+ /* @__PURE__ */ w("div", { className: "relative flex-1 overflow-hidden", children: [
2723
+ E && /* @__PURE__ */ i(
2724
+ mn,
2240
2725
  {
2241
- sources: A.sources,
2726
+ sources: E.sources,
2242
2727
  onClose: () => B(null)
2243
2728
  }
2244
2729
  ),
2245
- /* @__PURE__ */ p(
2730
+ y && /* @__PURE__ */ i(
2246
2731
  "div",
2247
2732
  {
2248
- ref: k,
2733
+ role: "status",
2734
+ className: "pointer-events-none absolute inset-x-0 top-2 z-10 flex justify-center px-4",
2735
+ children: G.status && /* @__PURE__ */ i("span", { className: "rounded-claudius-full bg-claudius-text px-3 py-1 text-xs text-claudius-surface shadow-claudius-elevated", children: G.status })
2736
+ }
2737
+ ),
2738
+ /* @__PURE__ */ w(
2739
+ "div",
2740
+ {
2741
+ ref: L,
2249
2742
  role: "log",
2250
- "aria-label": X,
2743
+ "aria-label": ce,
2251
2744
  className: "h-full space-y-3 overflow-y-auto px-4 py-4",
2252
2745
  children: [
2253
- e.length === 0 && !s && /* @__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: N }) }),
2254
- e.map((w) => /* @__PURE__ */ i(
2255
- Bt,
2746
+ e.length === 0 && !o && /* @__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: A }) }),
2747
+ e.map((h) => /* @__PURE__ */ i(
2748
+ Qt,
2256
2749
  {
2257
- role: w.role,
2258
- content: w.content,
2259
- isStreaming: w.id === r,
2260
- sources: w.sources,
2261
- attachments: w.attachments,
2262
- toolUses: w.toolUses,
2263
- toolUsedLabel: f == null ? void 0 : f.toolUsed,
2264
- toolDetailsLabel: f == null ? void 0 : f.toolDetails,
2265
- isSourceActive: (A == null ? void 0 : A.messageId) === w.id,
2750
+ role: h.role,
2751
+ content: h.content,
2752
+ isStreaming: h.id === r,
2753
+ sources: h.sources,
2754
+ attachments: h.attachments,
2755
+ toolUses: h.toolUses,
2756
+ toolUsedLabel: p == null ? void 0 : p.toolUsed,
2757
+ toolDetailsLabel: p == null ? void 0 : p.toolDetails,
2758
+ isSourceActive: (E == null ? void 0 : E.messageId) === h.id,
2266
2759
  onSourceClick: () => {
2267
- (A == null ? void 0 : A.messageId) === w.id ? B(null) : w.sources && w.sources.length > 0 && B({ messageId: w.id, sources: w.sources });
2760
+ (E == null ? void 0 : E.messageId) === h.id ? B(null) : h.sources && h.sources.length > 0 && B({ messageId: h.id, sources: h.sources });
2268
2761
  },
2269
2762
  speech: (
2270
2763
  // Only settled replies with something to say: reading a
2271
2764
  // message that is still streaming would stop mid-sentence.
2272
- W && w.role === "assistant" && w.id !== r && w.content.trim() !== "" ? {
2273
- state: y.activeId !== w.id ? "idle" : y.isPaused ? "paused" : "speaking",
2274
- labels: U,
2765
+ _ && h.role === "assistant" && h.id !== r && h.content.trim() !== "" ? {
2766
+ state: O.activeId !== h.id ? "idle" : O.isPaused ? "paused" : "speaking",
2767
+ labels: q,
2275
2768
  // Same cleanup as the screen-reader announcement:
2276
2769
  // no literal asterisks, URLs shortened to hostnames.
2277
- onPlay: () => y.speak(
2278
- w.id,
2279
- Oe(w.content)
2770
+ onPlay: () => O.speak(
2771
+ h.id,
2772
+ Ye(h.content)
2280
2773
  ),
2281
- onPause: y.pause,
2282
- onResume: y.resume,
2283
- onStop: y.cancel
2774
+ onPause: O.pause,
2775
+ onResume: O.resume,
2776
+ onStop: O.cancel
2284
2777
  } : void 0
2285
2778
  )
2286
2779
  },
2287
- w.id
2780
+ h.id
2288
2781
  )),
2289
2782
  t && /* Once streamed tokens are rendering in a bubble, the typing
2290
2783
  indicator is redundant — show it only until the first token.
2291
2784
  A tool-only placeholder (no text yet) keeps the indicator. */
2292
2785
  !(r !== null && e.some(
2293
- (w) => w.id === r && w.content.length > 0
2786
+ (h) => h.id === r && h.content.length > 0
2294
2787
  )) && /* @__PURE__ */ i(
2295
- rn,
2788
+ yn,
2296
2789
  {
2297
- label: (f == null ? void 0 : f.typingIndicator) ?? "Assistant is typing"
2790
+ label: (p == null ? void 0 : p.typingIndicator) ?? "Assistant is typing"
2298
2791
  }
2299
2792
  ),
2300
- s && /* @__PURE__ */ i(
2301
- nn,
2793
+ o && /* @__PURE__ */ i(
2794
+ bn,
2302
2795
  {
2303
- message: s,
2304
- retryLabel: (f == null ? void 0 : f.errorRetry) ?? "Retry",
2305
- onRetry: o && u && !t ? u : void 0
2796
+ message: o,
2797
+ retryLabel: (p == null ? void 0 : p.errorRetry) ?? "Retry",
2798
+ onRetry: s && l && !t ? l : void 0
2306
2799
  }
2307
2800
  )
2308
2801
  ]
@@ -2316,41 +2809,42 @@ function fn({
2316
2809
  "aria-live": "polite",
2317
2810
  "aria-atomic": "true",
2318
2811
  className: "sr-only",
2319
- children: te && te.id !== r ? Oe(te.content) : ""
2812
+ children: re && re.id !== r ? Ye(re.content) : ""
2320
2813
  }
2321
2814
  ),
2322
2815
  /* @__PURE__ */ i(
2323
- Qt,
2816
+ dn,
2324
2817
  {
2325
2818
  onSend: a,
2326
2819
  isLoading: t,
2327
2820
  isStreaming: n,
2328
2821
  onStop: c,
2329
2822
  placeholder: g,
2330
- translations: f,
2331
- attachments: D,
2332
- voice: C,
2333
- onVoiceStart: y.cancel
2823
+ translations: p,
2824
+ attachments: b,
2825
+ voice: R,
2826
+ onVoiceStart: O.cancel,
2827
+ isReadingAloud: O.activeId !== null
2334
2828
  }
2335
2829
  )
2336
2830
  ]
2337
2831
  }
2338
2832
  );
2339
2833
  }
2340
- function mn({
2834
+ function qn({
2341
2835
  message: e,
2342
2836
  position: t,
2343
2837
  onOpen: n,
2344
2838
  onDismiss: r,
2345
- dismissLabel: s
2839
+ dismissLabel: o
2346
2840
  }) {
2347
- const o = t.startsWith("bottom"), a = t.endsWith("right"), c = [
2841
+ const s = t.startsWith("bottom"), a = t.endsWith("right"), c = [
2348
2842
  "claudius-greeting-bubble",
2349
2843
  "fixed z-40 max-w-xs",
2350
- o ? "bottom-20" : "top-20",
2844
+ s ? "bottom-20" : "top-20",
2351
2845
  a ? "right-4" : "left-4"
2352
2846
  ].join(" ");
2353
- return /* @__PURE__ */ p("div", { className: c, role: "status", "aria-live": "polite", children: [
2847
+ return /* @__PURE__ */ w("div", { className: c, role: "status", "aria-live": "polite", children: [
2354
2848
  /* @__PURE__ */ i(
2355
2849
  "button",
2356
2850
  {
@@ -2364,17 +2858,17 @@ function mn({
2364
2858
  "button",
2365
2859
  {
2366
2860
  type: "button",
2367
- onClick: (u) => {
2368
- u.stopPropagation(), r();
2861
+ onClick: (l) => {
2862
+ l.stopPropagation(), r();
2369
2863
  },
2370
- "aria-label": s,
2864
+ "aria-label": o,
2371
2865
  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",
2372
2866
  children: /* @__PURE__ */ i("span", { "aria-hidden": "true", children: "×" })
2373
2867
  }
2374
2868
  )
2375
2869
  ] });
2376
2870
  }
2377
- const pn = {
2871
+ const Zn = {
2378
2872
  // ChatWindow
2379
2873
  title: "Chat",
2380
2874
  subtitle: "Pregúntame lo que quieras",
@@ -2413,6 +2907,19 @@ const pn = {
2413
2907
  pauseReading: "Pausar la lectura",
2414
2908
  resumeReading: "Reanudar la lectura",
2415
2909
  stopReading: "Detener la lectura",
2910
+ // Conversation export
2911
+ moreOptions: "Más opciones",
2912
+ copyAsMarkdown: "Copiar como Markdown",
2913
+ downloadAsMarkdown: "Descargar como Markdown",
2914
+ downloadAsJson: "Descargar como JSON",
2915
+ copiedToClipboard: "Copiado al portapapeles",
2916
+ copyFailed: "No se pudo copiar. Prueba a descargarlo.",
2917
+ transcriptTitle: "Transcripción del chat",
2918
+ transcriptExported: "Exportado el {date}",
2919
+ transcriptUser: "Usuario",
2920
+ transcriptAssistant: "Asistente",
2921
+ transcriptAttachments: "Adjuntos:",
2922
+ transcriptSources: "Fuentes:",
2416
2923
  // Errors
2417
2924
  errorGeneric: "Algo salió mal. Inténtalo de nuevo.",
2418
2925
  errorConnection: "No se pudo conectar. Inténtalo de nuevo.",
@@ -2422,7 +2929,7 @@ const pn = {
2422
2929
  errorAttachmentRejected: "Se rechazó un adjunto. Quítalo e inténtalo de nuevo.",
2423
2930
  errorAttachmentQuota: "Límite de subida alcanzado. Inténtalo más tarde.",
2424
2931
  errorRetry: "Reintentar"
2425
- }, gn = {
2932
+ }, Jn = {
2426
2933
  // ChatWindow
2427
2934
  title: "Chat",
2428
2935
  subtitle: "Posez-moi vos questions",
@@ -2461,6 +2968,19 @@ const pn = {
2461
2968
  pauseReading: "Mettre la lecture en pause",
2462
2969
  resumeReading: "Reprendre la lecture",
2463
2970
  stopReading: "Arrêter la lecture",
2971
+ // Conversation export
2972
+ moreOptions: "Plus d'options",
2973
+ copyAsMarkdown: "Copier en Markdown",
2974
+ downloadAsMarkdown: "Télécharger en Markdown",
2975
+ downloadAsJson: "Télécharger en JSON",
2976
+ copiedToClipboard: "Copié dans le presse-papiers",
2977
+ copyFailed: "Impossible de copier. Essayez plutôt de télécharger.",
2978
+ transcriptTitle: "Transcription du chat",
2979
+ transcriptExported: "Exporté le {date}",
2980
+ transcriptUser: "Utilisateur",
2981
+ transcriptAssistant: "Assistant",
2982
+ transcriptAttachments: "Pièces jointes :",
2983
+ transcriptSources: "Sources :",
2464
2984
  // Errors
2465
2985
  errorGeneric: "Une erreur s'est produite. Veuillez réessayer.",
2466
2986
  errorConnection: "Échec de la connexion. Veuillez réessayer.",
@@ -2470,7 +2990,7 @@ const pn = {
2470
2990
  errorAttachmentRejected: "Une pièce jointe a été refusée. Retirez-la et réessayez.",
2471
2991
  errorAttachmentQuota: "Limite d'envoi atteinte. Veuillez réessayer plus tard.",
2472
2992
  errorRetry: "Réessayer"
2473
- }, bn = {
2993
+ }, Qn = {
2474
2994
  // ChatWindow
2475
2995
  title: "Chat",
2476
2996
  subtitle: "Fragen Sie mich alles",
@@ -2509,6 +3029,19 @@ const pn = {
2509
3029
  pauseReading: "Vorlesen pausieren",
2510
3030
  resumeReading: "Vorlesen fortsetzen",
2511
3031
  stopReading: "Vorlesen beenden",
3032
+ // Conversation export
3033
+ moreOptions: "Weitere Optionen",
3034
+ copyAsMarkdown: "Als Markdown kopieren",
3035
+ downloadAsMarkdown: "Als Markdown herunterladen",
3036
+ downloadAsJson: "Als JSON herunterladen",
3037
+ copiedToClipboard: "In die Zwischenablage kopiert",
3038
+ copyFailed: "Kopieren nicht möglich. Bitte stattdessen herunterladen.",
3039
+ transcriptTitle: "Chat-Protokoll",
3040
+ transcriptExported: "Exportiert am {date}",
3041
+ transcriptUser: "Nutzer",
3042
+ transcriptAssistant: "Assistent",
3043
+ transcriptAttachments: "Anhänge:",
3044
+ transcriptSources: "Quellen:",
2512
3045
  // Errors
2513
3046
  errorGeneric: "Etwas ist schiefgelaufen. Bitte versuchen Sie es erneut.",
2514
3047
  errorConnection: "Verbindung fehlgeschlagen. Bitte versuchen Sie es erneut.",
@@ -2518,28 +3051,28 @@ const pn = {
2518
3051
  errorAttachmentRejected: "Ein Anhang wurde abgelehnt. Bitte entfernen Sie ihn und versuchen Sie es erneut.",
2519
3052
  errorAttachmentQuota: "Upload-Limit erreicht. Bitte versuchen Sie es später erneut.",
2520
3053
  errorRetry: "Erneut versuchen"
2521
- }, $e = {
2522
- en: ze,
2523
- es: pn,
2524
- fr: gn,
2525
- de: bn
3054
+ }, at = {
3055
+ en: nt,
3056
+ es: Zn,
3057
+ fr: Jn,
3058
+ de: Qn
2526
3059
  };
2527
- function je(e) {
3060
+ function qe(e) {
2528
3061
  if (!e) return;
2529
3062
  const t = e.toLowerCase().split("-")[0];
2530
- return Object.prototype.hasOwnProperty.call($e, t) ? t : void 0;
3063
+ return Object.prototype.hasOwnProperty.call(at, t) ? t : void 0;
2531
3064
  }
2532
- function Fe() {
2533
- const e = typeof document < "u" ? je(document.documentElement.lang) : void 0;
3065
+ function it() {
3066
+ const e = typeof document < "u" ? qe(document.documentElement.lang) : void 0;
2534
3067
  if (e) return e;
2535
- const t = typeof navigator < "u" ? je(navigator.language) : void 0;
3068
+ const t = typeof navigator < "u" ? qe(navigator.language) : void 0;
2536
3069
  return t || "en";
2537
3070
  }
2538
- function yn(e = {}) {
2539
- const { locale: t, translations: n } = e, r = $e[t ?? Fe()];
3071
+ function Xn(e = {}) {
3072
+ const { locale: t, translations: n } = e, r = at[t ?? it()];
2540
3073
  return n ? { ...r, ...n } : { ...r };
2541
3074
  }
2542
- const Pe = [
3075
+ const Ze = [
2543
3076
  "accent",
2544
3077
  "accentText",
2545
3078
  "accentSoft",
@@ -2559,11 +3092,11 @@ const Pe = [
2559
3092
  "errorText",
2560
3093
  "link",
2561
3094
  "scrim"
2562
- ], xn = ["sm", "md", "lg", "full", "tail"], vn = [
3095
+ ], er = ["sm", "md", "lg", "full", "tail"], tr = [
2563
3096
  "elevated",
2564
3097
  "floating",
2565
3098
  "floatingHover"
2566
- ], wn = ["heading", "body"], We = {
3099
+ ], nr = ["heading", "body"], ct = {
2567
3100
  default: {
2568
3101
  name: "default"
2569
3102
  },
@@ -2648,274 +3181,280 @@ const Pe = [
2648
3181
  }
2649
3182
  }
2650
3183
  };
2651
- function Rn(e) {
2652
- return Object.prototype.hasOwnProperty.call(We, e);
3184
+ function rr(e) {
3185
+ return Object.prototype.hasOwnProperty.call(ct, e);
2653
3186
  }
2654
- const En = /* @__PURE__ */ new Set(["light", "dark", "auto"]);
2655
- function Tn(e) {
3187
+ const or = /* @__PURE__ */ new Set(["light", "dark", "auto"]);
3188
+ function sr(e) {
2656
3189
  if (e === void 0)
2657
3190
  return { mode: "light" };
2658
3191
  if (typeof e == "string") {
2659
- if (En.has(e))
3192
+ if (or.has(e))
2660
3193
  return { mode: e };
2661
- if (Rn(e)) {
2662
- const t = We[e];
3194
+ if (rr(e)) {
3195
+ const t = ct[e];
2663
3196
  return { mode: t.colorScheme ?? "light", theme: t };
2664
3197
  }
2665
3198
  return { mode: "light", url: e };
2666
3199
  }
2667
3200
  return { mode: e.colorScheme ?? "light", theme: e };
2668
3201
  }
2669
- function Sn(e) {
3202
+ function ar(e) {
2670
3203
  return e.replace(/[A-Z]/g, (t) => `-${t.toLowerCase()}`);
2671
3204
  }
2672
- function kn(e, t) {
3205
+ function ir(e, t) {
2673
3206
  console.warn(
2674
3207
  `[Claudius] Ignoring unknown theme token "${t}" in "${e}"`
2675
3208
  );
2676
3209
  }
2677
- function de(e, t, n, r, s, o = "") {
2678
- if (s)
2679
- for (const [a, c] of Object.entries(s)) {
3210
+ function we(e, t, n, r, o, s = "") {
3211
+ if (o)
3212
+ for (const [a, c] of Object.entries(o)) {
2680
3213
  if (!r.includes(a)) {
2681
- kn(t, a);
3214
+ ir(t, a);
2682
3215
  continue;
2683
3216
  }
2684
- typeof c == "string" && (e[`${n}${Sn(a)}${o}`] = c);
3217
+ typeof c == "string" && (e[`${n}${ar(a)}${s}`] = c);
2685
3218
  }
2686
3219
  }
2687
- function Cn(e) {
3220
+ function cr(e) {
2688
3221
  const t = {};
2689
- de(t, "colors", "--cl-color-", Pe, e.colors);
3222
+ we(t, "colors", "--cl-color-", Ze, e.colors);
2690
3223
  for (const [n, r] of Object.entries({ ...t }))
2691
3224
  t[`${n}-dark`] = r;
2692
- return de(
3225
+ return we(
2693
3226
  t,
2694
3227
  "colorsDark",
2695
3228
  "--cl-color-",
2696
- Pe,
3229
+ Ze,
2697
3230
  e.colorsDark,
2698
3231
  "-dark"
2699
- ), de(t, "radii", "--cl-radius-", xn, e.radii), de(t, "shadows", "--cl-shadow-", vn, e.shadows), de(t, "fonts", "--cl-font-", wn, e.fonts), t;
3232
+ ), we(t, "radii", "--cl-radius-", er, e.radii), we(t, "shadows", "--cl-shadow-", tr, e.shadows), we(t, "fonts", "--cl-font-", nr, e.fonts), t;
2700
3233
  }
2701
- function An(e) {
3234
+ function lr(e) {
2702
3235
  return typeof e == "object" && e !== null && !Array.isArray(e);
2703
3236
  }
2704
- function Nn(e) {
2705
- const t = ae(() => Tn(e), [e]), [n, r] = O(null), s = t.url;
2706
- K(() => {
2707
- if (r(null), !s) return;
2708
- const u = new AbortController();
2709
- return fetch(s, { signal: u.signal }).then((l) => {
2710
- if (!l.ok)
2711
- throw new Error(`HTTP ${l.status}`);
2712
- return l.json();
2713
- }).then((l) => {
2714
- if (!An(l))
3237
+ function ur(e) {
3238
+ const t = se(() => sr(e), [e]), [n, r] = N(null), o = t.url;
3239
+ W(() => {
3240
+ if (r(null), !o) return;
3241
+ const l = new AbortController();
3242
+ return fetch(o, { signal: l.signal }).then((u) => {
3243
+ if (!u.ok)
3244
+ throw new Error(`HTTP ${u.status}`);
3245
+ return u.json();
3246
+ }).then((u) => {
3247
+ if (!lr(u))
2715
3248
  throw new Error("theme JSON must be an object");
2716
- r(l);
2717
- }).catch((l) => {
2718
- u.signal.aborted || console.error(`[Claudius] Failed to load theme from ${s}:`, l);
2719
- }), () => u.abort();
2720
- }, [s]);
2721
- const o = t.theme ?? n ?? null, a = (n == null ? void 0 : n.colorScheme) ?? t.mode, c = ae(
2722
- () => o ? Cn(o) : {},
2723
- [o]
3249
+ r(u);
3250
+ }).catch((u) => {
3251
+ l.signal.aborted || console.error(`[Claudius] Failed to load theme from ${o}:`, u);
3252
+ }), () => l.abort();
3253
+ }, [o]);
3254
+ const s = t.theme ?? n ?? null, a = (n == null ? void 0 : n.colorScheme) ?? t.mode, c = se(
3255
+ () => s ? cr(s) : {},
3256
+ [s]
2724
3257
  );
2725
3258
  return { mode: a, cssVars: c };
2726
3259
  }
2727
- const Ge = "claudius:triggers:dismissed";
2728
- function Mn() {
3260
+ const lt = "claudius:triggers:dismissed";
3261
+ function dr() {
2729
3262
  if (typeof window > "u") return !1;
2730
3263
  try {
2731
- return window.sessionStorage.getItem(Ge) === "1";
3264
+ return window.sessionStorage.getItem(lt) === "1";
2732
3265
  } catch {
2733
3266
  return !1;
2734
3267
  }
2735
3268
  }
2736
- function Ln() {
3269
+ function fr() {
2737
3270
  if (!(typeof window > "u"))
2738
3271
  try {
2739
- window.sessionStorage.setItem(Ge, "1");
3272
+ window.sessionStorage.setItem(lt, "1");
2740
3273
  } catch {
2741
3274
  }
2742
3275
  }
2743
- function _n({
3276
+ function wr({
2744
3277
  apiUrl: e,
2745
3278
  title: t,
2746
3279
  subtitle: n,
2747
3280
  welcomeMessage: r,
2748
- placeholder: s,
2749
- persistMessages: o,
3281
+ placeholder: o,
3282
+ persistMessages: s,
2750
3283
  storageKeyPrefix: a,
2751
3284
  requestTimeoutMs: c,
2752
- theme: u = "light",
2753
- accentColor: l,
2754
- position: m = "bottom-right",
2755
- locale: E,
2756
- translations: N,
3285
+ theme: l = "light",
3286
+ accentColor: u,
3287
+ position: d = "bottom-right",
3288
+ locale: x,
3289
+ translations: A,
2757
3290
  triggers: g,
2758
- plugins: d,
2759
- streaming: f = !0,
2760
- attachments: v = !1,
2761
- voice: D = !1
3291
+ plugins: f,
3292
+ streaming: p = !0,
3293
+ attachments: T = !1,
3294
+ voice: b = !1,
3295
+ conversationExport: R = !1
2762
3296
  }) {
2763
- const [C, T] = O(!1), b = ae(
2764
- () => st(v),
2765
- [v]
2766
- ), k = ae(
2767
- () => Ft(D, E ?? Fe()),
2768
- [D, E]
2769
- ), [A, B] = O(null), [y, W] = O(Mn), U = L(!1), H = xt("(max-width: 639px)"), _ = ae(
2770
- () => yn({ locale: E, translations: N }),
2771
- [E, N]
3297
+ const [y, v] = N(!1), C = se(
3298
+ () => wt(T),
3299
+ [T]
3300
+ ), $ = se(() => x ?? it(), [x]), L = se(
3301
+ () => rn(b, $),
3302
+ [b, $]
3303
+ ), E = se(
3304
+ () => rt($),
3305
+ [$]
3306
+ ), [B, O] = N(null), [_, q] = N(dr), G = S(!1), J = Ot("(max-width: 639px)"), z = se(
3307
+ () => Xn({ locale: x, translations: A }),
3308
+ [x, A]
2772
3309
  ), {
2773
- messages: J,
2774
- isLoading: re,
2775
- isStreaming: X,
2776
- streamingMessageId: te,
2777
- error: w,
2778
- canRetry: ee,
2779
- sendMessage: ie,
2780
- stop: x,
2781
- retry: z
2782
- } = yt({
3310
+ messages: ae,
3311
+ isLoading: ie,
3312
+ isStreaming: ce,
3313
+ streamingMessageId: re,
3314
+ error: h,
3315
+ canRetry: P,
3316
+ sendMessage: U,
3317
+ stop: ee,
3318
+ retry: te
3319
+ } = It({
2783
3320
  apiUrl: e,
2784
- persistMessages: o,
3321
+ persistMessages: s,
2785
3322
  storageKeyPrefix: a,
2786
3323
  timeoutMs: c,
2787
- translations: _,
2788
- plugins: d,
2789
- streaming: f
2790
- }), I = L(null), Q = L(C), { mode: $, cssVars: ne } = Nn(u), [Z, R] = O(!1);
2791
- K(() => {
2792
- if ($ !== "auto") return;
2793
- const G = window.matchMedia("(prefers-color-scheme: dark)");
2794
- R(G.matches);
2795
- const Te = (Ve) => R(Ve.matches);
2796
- return G.addEventListener("change", Te), () => G.removeEventListener("change", Te);
2797
- }, [$]), K(() => {
2798
- var G;
2799
- Q.current && !C && ((G = I.current) == null || G.focus()), Q.current = C;
2800
- }, [C]);
2801
- const j = M(() => {
2802
- W(!0), Ln();
2803
- }, []), P = M(() => {
2804
- T(!1), U.current && (U.current = !1, j());
2805
- }, [j]), Y = M(() => {
2806
- T((G) => !G);
2807
- }, []), q = M(() => {
2808
- U.current = !0, B(null), T(!0);
2809
- }, []), se = M((G) => {
2810
- B(G);
2811
- }, []), he = M(() => {
2812
- B(null), q();
2813
- }, [q]), h = M(() => {
2814
- B(null), j();
2815
- }, [j]);
2816
- wt({
3324
+ translations: z,
3325
+ plugins: f,
3326
+ streaming: p
3327
+ }), ne = S(null), F = S(y), { mode: H, cssVars: k } = ur(l), [D, I] = N(!1);
3328
+ W(() => {
3329
+ if (H !== "auto") return;
3330
+ const X = window.matchMedia("(prefers-color-scheme: dark)");
3331
+ I(X.matches);
3332
+ const Me = (m) => I(m.matches);
3333
+ return X.addEventListener("change", Me), () => X.removeEventListener("change", Me);
3334
+ }, [H]), W(() => {
3335
+ var X;
3336
+ F.current && !y && ((X = ne.current) == null || X.focus()), F.current = y;
3337
+ }, [y]);
3338
+ const K = M(() => {
3339
+ q(!0), fr();
3340
+ }, []), Q = M(() => {
3341
+ v(!1), G.current && (G.current = !1, K());
3342
+ }, [K]), le = M(() => {
3343
+ v((X) => !X);
3344
+ }, []), Y = M(() => {
3345
+ G.current = !0, O(null), v(!0);
3346
+ }, []), me = M((X) => {
3347
+ O(X);
3348
+ }, []), ue = M(() => {
3349
+ O(null), Y();
3350
+ }, [Y]), V = M(() => {
3351
+ O(null), K();
3352
+ }, [K]);
3353
+ $t({
2817
3354
  triggers: g,
2818
- enabled: !y && !C,
2819
- onOpen: q,
2820
- onGreeting: se
3355
+ enabled: !_ && !y,
3356
+ onOpen: Y,
3357
+ onGreeting: me
2821
3358
  });
2822
- const S = $ === "dark" || $ === "auto" && Z, F = {
2823
- ...ne,
2824
- ...l ? {
2825
- "--cl-color-accent": l,
2826
- "--cl-color-accent-dark": l
3359
+ const oe = H === "dark" || H === "auto" && D, ge = {
3360
+ ...k,
3361
+ ...u ? {
3362
+ "--cl-color-accent": u,
3363
+ "--cl-color-accent-dark": u
2827
3364
  } : {}
2828
- }, ce = Object.keys(F).length > 0 ? F : void 0;
3365
+ }, de = Object.keys(ge).length > 0 ? ge : void 0;
2829
3366
  return (
2830
3367
  // Outer div carries theme token vars; the inner div carries the dark-mode
2831
3368
  // attribute so the [data-claudius-dark] token reassignments in styles.css
2832
3369
  // beat inherited (inline) light values.
2833
- /* @__PURE__ */ i("div", { className: "claudius-root", style: ce, children: /* @__PURE__ */ p("div", { "data-claudius-dark": S ? "true" : "false", children: [
2834
- C && H && /* @__PURE__ */ i(
3370
+ /* @__PURE__ */ i("div", { className: "claudius-root", style: de, children: /* @__PURE__ */ w("div", { "data-claudius-dark": oe ? "true" : "false", children: [
3371
+ y && J && /* @__PURE__ */ i(
2835
3372
  "div",
2836
3373
  {
2837
3374
  className: "claudius-scrim fixed inset-0 z-40 bg-claudius-scrim",
2838
- onClick: P,
3375
+ onClick: Q,
2839
3376
  "aria-hidden": "true"
2840
3377
  }
2841
3378
  ),
2842
- C && /* @__PURE__ */ i(
2843
- fn,
3379
+ y && /* @__PURE__ */ i(
3380
+ Yn,
2844
3381
  {
2845
- messages: J,
2846
- isLoading: re,
2847
- isStreaming: X,
2848
- streamingMessageId: te,
2849
- error: w,
2850
- canRetry: ee,
2851
- onSend: ie,
2852
- onStop: x,
2853
- onRetry: z,
2854
- onClose: P,
2855
- title: t ?? _.title,
2856
- subtitle: n ?? _.subtitle,
2857
- welcomeMessage: r ?? _.welcomeMessage,
2858
- placeholder: s ?? _.placeholder,
2859
- position: m,
2860
- translations: _,
2861
- isMobile: H,
2862
- attachments: b,
2863
- voice: k
3382
+ messages: ae,
3383
+ isLoading: ie,
3384
+ isStreaming: ce,
3385
+ streamingMessageId: re,
3386
+ error: h,
3387
+ canRetry: P,
3388
+ onSend: U,
3389
+ onStop: ee,
3390
+ onRetry: te,
3391
+ onClose: Q,
3392
+ title: t ?? z.title,
3393
+ subtitle: n ?? z.subtitle,
3394
+ welcomeMessage: r ?? z.welcomeMessage,
3395
+ placeholder: o ?? z.placeholder,
3396
+ position: d,
3397
+ translations: z,
3398
+ isMobile: J,
3399
+ attachments: C,
3400
+ voice: L,
3401
+ conversationExport: R === !0,
3402
+ locale: E
2864
3403
  }
2865
3404
  ),
2866
- !(C && H) && /* @__PURE__ */ i(
2867
- Et,
3405
+ !(y && J) && /* @__PURE__ */ i(
3406
+ Ut,
2868
3407
  {
2869
- ref: I,
2870
- isOpen: C,
2871
- onClick: Y,
2872
- position: m,
2873
- translations: _
3408
+ ref: ne,
3409
+ isOpen: y,
3410
+ onClick: le,
3411
+ position: d,
3412
+ translations: z
2874
3413
  }
2875
3414
  ),
2876
- !C && A && /* @__PURE__ */ i(
2877
- mn,
3415
+ !y && B && /* @__PURE__ */ i(
3416
+ qn,
2878
3417
  {
2879
- message: A,
2880
- position: m,
2881
- onOpen: he,
2882
- onDismiss: h,
2883
- dismissLabel: _.dismissGreeting
3418
+ message: B,
3419
+ position: d,
3420
+ onOpen: ue,
3421
+ onDismiss: V,
3422
+ dismissLabel: z.dismissGreeting
2884
3423
  }
2885
3424
  )
2886
3425
  ] }) })
2887
3426
  );
2888
3427
  }
2889
- function zn(e) {
2890
- const { onEvent: t, includeContent: n = !0 } = e, r = (s) => n ? s : "";
3428
+ function vr(e) {
3429
+ const { onEvent: t, includeContent: n = !0 } = e, r = (o) => n ? o : "";
2891
3430
  return {
2892
3431
  name: "analytics",
2893
- onBeforeSend(s) {
3432
+ onBeforeSend(o) {
2894
3433
  t({
2895
3434
  type: "message_sent",
2896
3435
  role: "user",
2897
- content: r(s.content),
2898
- chars: s.content.length
3436
+ content: r(o.content),
3437
+ chars: o.content.length
2899
3438
  });
2900
3439
  },
2901
- onAfterReceive(s) {
3440
+ onAfterReceive(o) {
2902
3441
  t({
2903
3442
  type: "message_received",
2904
3443
  role: "assistant",
2905
- content: r(s.content),
2906
- chars: s.content.length
3444
+ content: r(o.content),
3445
+ chars: o.content.length
2907
3446
  });
2908
3447
  },
2909
- onError(s) {
3448
+ onError(o) {
2910
3449
  t({
2911
3450
  type: "chat_error",
2912
- message: s.message,
2913
- code: s.code
3451
+ message: o.message,
3452
+ code: o.code
2914
3453
  });
2915
3454
  }
2916
3455
  };
2917
3456
  }
2918
- const Dn = [
3457
+ const hr = [
2919
3458
  // Email
2920
3459
  /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b/g,
2921
3460
  // US SSN (before the looser card pattern so it wins on 9-digit groups)
@@ -2925,60 +3464,60 @@ const Dn = [
2925
3464
  // Phone: optional +1, area code, 7 digits with common separators
2926
3465
  /\b(?:\+?1[-.\s]?)?\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}\b/g
2927
3466
  ];
2928
- function In(e, t, n) {
3467
+ function pr(e, t, n) {
2929
3468
  return t.reduce(
2930
3469
  // Reset lastIndex defensively: a shared global regex is stateful.
2931
- (r, s) => (s.lastIndex = 0, r.replace(s, n)),
3470
+ (r, o) => (o.lastIndex = 0, r.replace(o, n)),
2932
3471
  e
2933
3472
  );
2934
3473
  }
2935
- function Un(e = {}) {
3474
+ function Tr(e = {}) {
2936
3475
  const {
2937
- patterns: t = Dn,
3476
+ patterns: t = hr,
2938
3477
  replacement: n = "[redacted]",
2939
3478
  redactReplies: r = !1
2940
- } = e, s = (o) => {
2941
- const a = In(o.content, t, n);
2942
- if (a !== o.content)
2943
- return { ...o, content: a };
3479
+ } = e, o = (s) => {
3480
+ const a = pr(s.content, t, n);
3481
+ if (a !== s.content)
3482
+ return { ...s, content: a };
2944
3483
  };
2945
3484
  return {
2946
3485
  name: "redact-pii",
2947
- onBeforeSend: s,
2948
- onAfterReceive: r ? s : void 0
3486
+ onBeforeSend: o,
3487
+ onAfterReceive: r ? o : void 0
2949
3488
  };
2950
3489
  }
2951
- function On(e, t, n) {
3490
+ function mr(e, t, n) {
2952
3491
  return typeof e == "function" ? e(t) : e instanceof RegExp ? e.test(t) : n ? t.includes(e) : t.toLowerCase().includes(e.toLowerCase());
2953
3492
  }
2954
- function $n(e) {
3493
+ function Er(e) {
2955
3494
  const { rules: t, caseSensitive: n = !1 } = e;
2956
3495
  return {
2957
3496
  name: "canned-responses",
2958
- onBeforeSend(r, s) {
2959
- for (const o of t)
2960
- if (On(o.match, r.content, n)) {
2961
- s.respondWith(o.reply);
3497
+ onBeforeSend(r, o) {
3498
+ for (const s of t)
3499
+ if (mr(s.match, r.content, n)) {
3500
+ o.respondWith(s.reply);
2962
3501
  return;
2963
3502
  }
2964
3503
  }
2965
3504
  };
2966
3505
  }
2967
3506
  export {
2968
- Xe as ChatApiClient,
2969
- V as ChatApiError,
2970
- _n as ChatWidget,
2971
- fe as DEFAULT_ATTACHMENT_OPTIONS,
2972
- Dn as DEFAULT_PII_PATTERNS,
2973
- ye as DebounceError,
2974
- We as builtinThemes,
2975
- Hn as createTranslations,
2976
- Ue as defaultTranslations,
2977
- Fe as detectLocale,
2978
- $e as locales,
2979
- zn as pluginAnalytics,
2980
- $n as pluginCannedResponses,
2981
- Un as pluginRedactPII,
2982
- In as redactText,
2983
- yn as resolveTranslations
3507
+ mt as ChatApiClient,
3508
+ Z as ChatApiError,
3509
+ wr as ChatWidget,
3510
+ Te as DEFAULT_ATTACHMENT_OPTIONS,
3511
+ hr as DEFAULT_PII_PATTERNS,
3512
+ De as DebounceError,
3513
+ ct as builtinThemes,
3514
+ xr as createTranslations,
3515
+ Oe as defaultTranslations,
3516
+ it as detectLocale,
3517
+ at as locales,
3518
+ vr as pluginAnalytics,
3519
+ Er as pluginCannedResponses,
3520
+ Tr as pluginRedactPII,
3521
+ pr as redactText,
3522
+ Xn as resolveTranslations
2984
3523
  };