@singlebase/elements 0.3.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/README.md +2 -0
  2. package/dist/{display-8HEcKYR4.js → authui-display-CKfGK5va.js} +519 -502
  3. package/dist/authui-display-CKfGK5va.js.map +1 -0
  4. package/dist/{display-CLDNNZQy.cjs → authui-display-aWNht0cW.cjs} +38 -58
  5. package/dist/authui-display-aWNht0cW.cjs.map +1 -0
  6. package/dist/authui.cjs +1 -1
  7. package/dist/authui.d.ts +9 -9
  8. package/dist/authui.js +2 -2
  9. package/dist/chat-C-gsskho.cjs +3258 -0
  10. package/dist/chat-C-gsskho.cjs.map +1 -0
  11. package/dist/chat-CEh6RygY.js +5746 -0
  12. package/dist/chat-CEh6RygY.js.map +1 -0
  13. package/dist/chat-messages.d.ts +115 -0
  14. package/dist/chat.cjs +2 -0
  15. package/dist/chat.cjs.map +1 -0
  16. package/dist/chat.d.ts +11 -0
  17. package/dist/chat.js +15 -0
  18. package/dist/chat.js.map +1 -0
  19. package/dist/elements/{account-screen.d.ts → authui-account.d.ts} +1 -1
  20. package/dist/elements/{base.d.ts → authui-base.d.ts} +2 -0
  21. package/dist/elements/{buttons.d.ts → authui-buttons.d.ts} +2 -2
  22. package/dist/elements/{display.d.ts → authui-display.d.ts} +2 -2
  23. package/dist/elements/{form-base.d.ts → authui-form-base.d.ts} +1 -1
  24. package/dist/elements/{guard.d.ts → authui-guard.d.ts} +1 -1
  25. package/dist/elements/{auth-screen.d.ts → authui.d.ts} +8 -4
  26. package/dist/elements/chat.d.ts +455 -0
  27. package/dist/elements/uploader.d.ts +14 -0
  28. package/dist/files-DDJWPzZW.js +215 -0
  29. package/dist/files-DDJWPzZW.js.map +1 -0
  30. package/dist/files-DyxcjZsx.cjs +75 -0
  31. package/dist/files-DyxcjZsx.cjs.map +1 -0
  32. package/dist/index.cjs +1 -1
  33. package/dist/index.d.ts +3 -2
  34. package/dist/index.js +34 -21
  35. package/dist/index.js.map +1 -1
  36. package/dist/singlebase-elements.min.js +8044 -2120
  37. package/dist/singlebase-elements.min.js.map +1 -1
  38. package/dist/styles/branding.d.ts +5 -0
  39. package/dist/styles/chat.d.ts +6 -0
  40. package/dist/styles/tokens.d.ts +3 -1
  41. package/dist/{uploader-eFYKpk8b.cjs → uploader-660JIgIN.cjs} +55 -114
  42. package/dist/uploader-660JIgIN.cjs.map +1 -0
  43. package/dist/{uploader-D-Da1trc.js → uploader-vfczkX51.js} +376 -507
  44. package/dist/uploader-vfczkX51.js.map +1 -0
  45. package/dist/uploader.cjs +1 -1
  46. package/dist/uploader.js +5 -4
  47. package/dist/uploader.js.map +1 -1
  48. package/dist/utils/branding.d.ts +8 -0
  49. package/dist/utils/markdown.d.ts +165 -0
  50. package/dist/utils/svg.d.ts +10 -0
  51. package/package.json +13 -5
  52. package/dist/display-8HEcKYR4.js.map +0 -1
  53. package/dist/display-CLDNNZQy.cjs.map +0 -1
  54. package/dist/uploader-D-Da1trc.js.map +0 -1
  55. package/dist/uploader-eFYKpk8b.cjs.map +0 -1
@@ -0,0 +1,3258 @@
1
+ "use strict";var Kt=Object.defineProperty;var bt=l=>{throw TypeError(l)};var Wt=(l,o,e)=>o in l?Kt(l,o,{enumerable:!0,configurable:!0,writable:!0,value:e}):l[o]=e;var O=(l,o,e)=>Wt(l,typeof o!="symbol"?o+"":o,e),ft=(l,o,e)=>o.has(l)||bt("Cannot "+e);var h=(l,o,e)=>(ft(l,o,"read from private field"),e?e.call(l):o.get(l)),p=(l,o,e)=>o.has(l)?bt("Cannot add the same private member more than once"):o instanceof WeakSet?o.add(l):o.set(l,e),u=(l,o,e,t)=>(ft(l,o,"write to private field"),t?t.call(l,e):o.set(l,e),e);const s=require("lit"),g=require("lit/decorators.js"),Jt=require("lit/directives/repeat.js"),Ht=require("@singlebase/core"),T=require("./files-DyxcjZsx.cjs");if(typeof CSS<"u"&&"registerProperty"in CSS)try{CSS.registerProperty({name:"--sb-ai-angle",syntax:"<angle>",inherits:!1,initialValue:"0deg"})}catch{}const qt=s.css`
2
+ :host {
3
+ --c-ink: var(--sb-ink, #16181a);
4
+ --c-ink2: var(--sb-ink-2, #41464b);
5
+ --c-muted: var(--sb-muted-ink, #61666c);
6
+ --c-faint: #8a8f95;
7
+ --c-bg: var(--sb-surface, #ffffff);
8
+ --c-bg2: var(--sb-surface-alt, #fafafa);
9
+ --c-hover: var(--sb-hover, #f2f3f4);
10
+ --c-line: var(--sb-border, #e4e6e9);
11
+ --c-line2: var(--sb-divider, #ecedee);
12
+ --c-strong: var(--sb-border-strong, #cdd1d6);
13
+ --c-brand: var(--sb-accent, #16181a);
14
+ --c-on-brand: var(--sb-on-accent, #ffffff);
15
+ --c-danger: var(--sb-danger, #b4231a);
16
+ --c-ok: var(--sb-ok, #0f6b4a);
17
+ --c-mono: var(--sb-mono, "Geist Mono", ui-monospace, monospace);
18
+ --c-r: calc(var(--sb-radius, 4px) * var(--sb-radius-scale, 1));
19
+ --c-r2: calc(var(--c-r) * 1.5);
20
+ --c-r3: calc(var(--c-r) * 2);
21
+ --c-r4: calc(var(--c-r) * 3);
22
+ --c-glow: 0.6;
23
+ --c-conic: conic-gradient(
24
+ from var(--sb-ai-angle, 0deg),
25
+ oklch(0.72 0.15 295),
26
+ oklch(0.74 0.13 245),
27
+ oklch(0.8 0.11 190),
28
+ oklch(0.84 0.12 85),
29
+ oklch(0.78 0.12 350),
30
+ oklch(0.72 0.15 295)
31
+ );
32
+ --c-z: var(--sb-chat-z, 1000);
33
+ display: block;
34
+ height: 100%;
35
+ min-height: 0;
36
+ color-scheme: light;
37
+ }
38
+
39
+ :host([theme="dark"]) {
40
+ --sb-hover: #24272b;
41
+ --sb-ink-2: #c9ccd0;
42
+ --sb-divider: #26292d;
43
+ --c-faint: #7c8187;
44
+ color-scheme: dark;
45
+ }
46
+
47
+ :host([glow="vivid"]) {
48
+ --c-glow: 1;
49
+ }
50
+
51
+ :host([embed="inline"]) {
52
+ height: auto;
53
+ }
54
+
55
+ :host([embed="launcher"]) {
56
+ height: 0;
57
+ }
58
+
59
+ * {
60
+ box-sizing: border-box;
61
+ }
62
+
63
+ button {
64
+ font: inherit;
65
+ color: inherit;
66
+ }
67
+
68
+ button:focus-visible,
69
+ input:focus-visible,
70
+ textarea:focus-visible,
71
+ [role="button"]:focus-visible {
72
+ outline: 2px solid var(--c-ink);
73
+ outline-offset: 1px;
74
+ }
75
+
76
+ .mono {
77
+ font-family: var(--c-mono);
78
+ }
79
+
80
+ .label {
81
+ font-family: var(--c-mono);
82
+ font-size: 11px;
83
+ letter-spacing: 0.07em;
84
+ text-transform: uppercase;
85
+ color: var(--c-muted);
86
+ }
87
+
88
+ /* ── frames ───────────────────────────────────────────── */
89
+
90
+ .frame {
91
+ position: relative;
92
+ display: flex;
93
+ height: 100%;
94
+ min-height: 0;
95
+ background: var(--c-bg);
96
+ color: var(--c-ink);
97
+ overflow: hidden;
98
+ }
99
+
100
+ .frame.boxed {
101
+ border: 1px solid var(--c-line);
102
+ border-radius: var(--c-r4);
103
+ }
104
+
105
+ .frame.inline {
106
+ width: 440px;
107
+ height: 660px;
108
+ min-width: 340px;
109
+ min-height: 480px;
110
+ max-width: 100%;
111
+ resize: both;
112
+ box-shadow: 0 1px 2px rgba(22, 24, 26, 0.06);
113
+ }
114
+
115
+ @media (max-width: 559px) {
116
+ .frame.inline {
117
+ width: 100%;
118
+ min-width: 0;
119
+ resize: none;
120
+ }
121
+ }
122
+
123
+ .frame.launcher {
124
+ position: fixed;
125
+ bottom: 96px;
126
+ right: 24px;
127
+ z-index: var(--c-z);
128
+ width: 420px;
129
+ height: min(680px, calc(100vh - 120px));
130
+ max-width: calc(100vw - 48px);
131
+ box-shadow: 0 24px 60px -24px rgba(22, 24, 26, 0.35);
132
+ transform-origin: bottom right;
133
+ animation: scaleIn 0.2s ease-out;
134
+ }
135
+
136
+ :host([position="left"]) .frame.launcher {
137
+ right: auto;
138
+ left: 24px;
139
+ transform-origin: bottom left;
140
+ }
141
+
142
+ .frame.expanded {
143
+ position: fixed;
144
+ inset: 24px;
145
+ width: auto;
146
+ height: auto;
147
+ max-width: none;
148
+ z-index: var(--c-z);
149
+ resize: none;
150
+ box-shadow: 0 24px 60px -24px rgba(22, 24, 26, 0.35);
151
+ animation: scaleIn 0.2s ease-out;
152
+ }
153
+
154
+ .frame.full {
155
+ position: fixed;
156
+ inset: 0;
157
+ width: auto;
158
+ height: auto;
159
+ max-width: none;
160
+ border-radius: 0;
161
+ border: none;
162
+ z-index: var(--c-z);
163
+ resize: none;
164
+ }
165
+
166
+ .root {
167
+ position: relative;
168
+ display: flex;
169
+ flex: 1;
170
+ min-width: 0;
171
+ min-height: 0;
172
+ font-family: var(--sb-font, "Geist", -apple-system, "Segoe UI", Helvetica, sans-serif);
173
+ background: var(--c-bg);
174
+ color: var(--c-ink);
175
+ }
176
+
177
+ /* ── launcher ─────────────────────────────────────────── */
178
+
179
+ .launcher-btn {
180
+ position: fixed;
181
+ bottom: 24px;
182
+ right: 24px;
183
+ z-index: calc(var(--c-z) + 1);
184
+ width: 56px;
185
+ height: 56px;
186
+ border-radius: 999px;
187
+ display: inline-flex;
188
+ align-items: center;
189
+ justify-content: center;
190
+ border: none;
191
+ cursor: pointer;
192
+ background: var(--c-brand);
193
+ color: var(--c-on-brand);
194
+ box-shadow: 0 12px 28px -10px rgba(22, 24, 26, 0.45);
195
+ }
196
+
197
+ :host([position="left"]) .launcher-btn,
198
+ :host([position="left"]) .bubble {
199
+ right: auto;
200
+ left: 24px;
201
+ }
202
+
203
+ .badge {
204
+ position: absolute;
205
+ top: 2px;
206
+ right: 2px;
207
+ width: 12px;
208
+ height: 12px;
209
+ border-radius: 999px;
210
+ background: var(--c-danger);
211
+ border: 2px solid var(--c-bg);
212
+ }
213
+
214
+ .bubble {
215
+ position: fixed;
216
+ bottom: 96px;
217
+ right: 24px;
218
+ z-index: var(--c-z);
219
+ width: 260px;
220
+ display: flex;
221
+ align-items: flex-start;
222
+ gap: 8px;
223
+ padding: 12px 10px 12px 14px;
224
+ background: var(--c-bg);
225
+ color: var(--c-ink);
226
+ border: 1px solid var(--c-line);
227
+ border-radius: calc(var(--c-r) * 2.5);
228
+ box-shadow: 0 12px 32px -12px rgba(22, 24, 26, 0.25);
229
+ font-family: var(--sb-font, "Geist", -apple-system, "Segoe UI", Helvetica, sans-serif);
230
+ animation: aiIn 0.25s ease-out;
231
+ }
232
+
233
+ .bubble-text {
234
+ flex: 1;
235
+ min-width: 0;
236
+ text-align: left;
237
+ font-size: 13.5px;
238
+ line-height: 1.45;
239
+ background: none;
240
+ border: none;
241
+ padding: 0;
242
+ cursor: pointer;
243
+ }
244
+
245
+ /* ── icon buttons ─────────────────────────────────────── */
246
+
247
+ .icon {
248
+ display: inline-flex;
249
+ align-items: center;
250
+ justify-content: center;
251
+ flex: 0 0 auto;
252
+ width: 28px;
253
+ height: 28px;
254
+ padding: 0;
255
+ border: none;
256
+ border-radius: var(--c-r);
257
+ background: transparent;
258
+ color: var(--c-muted);
259
+ cursor: pointer;
260
+ }
261
+
262
+ .icon:hover:not(:disabled),
263
+ .icon.on {
264
+ color: var(--c-ink);
265
+ }
266
+
267
+ .icon:hover:not(:disabled) {
268
+ background: var(--c-hover);
269
+ }
270
+
271
+ .icon.danger:hover:not(:disabled) {
272
+ color: var(--c-danger);
273
+ }
274
+
275
+ .icon:disabled {
276
+ opacity: 0.4;
277
+ cursor: default;
278
+ }
279
+
280
+ .icon.sm {
281
+ width: 24px;
282
+ height: 24px;
283
+ }
284
+
285
+ svg.i {
286
+ width: 16px;
287
+ height: 16px;
288
+ fill: none;
289
+ stroke: currentColor;
290
+ stroke-width: 1.5;
291
+ stroke-linecap: round;
292
+ stroke-linejoin: round;
293
+ }
294
+
295
+ svg.i.filled path {
296
+ fill: currentColor;
297
+ }
298
+
299
+ @media (pointer: coarse) {
300
+ .icon {
301
+ width: 44px;
302
+ height: 44px;
303
+ }
304
+ }
305
+
306
+ /* ── sidebar ──────────────────────────────────────────── */
307
+
308
+ .scrim {
309
+ position: absolute;
310
+ inset: 0;
311
+ z-index: 29;
312
+ background: rgba(22, 24, 26, 0.18);
313
+ }
314
+
315
+ .sidebar {
316
+ display: flex;
317
+ flex-direction: column;
318
+ min-height: 0;
319
+ min-width: 0;
320
+ background: var(--c-bg2);
321
+ border-right: 1px solid var(--c-line);
322
+ }
323
+
324
+ .sidebar.docked {
325
+ position: relative;
326
+ flex: 0 0 272px;
327
+ width: 272px;
328
+ }
329
+
330
+ .sidebar.overlay {
331
+ position: absolute;
332
+ left: 0;
333
+ top: 0;
334
+ bottom: 0;
335
+ z-index: 30;
336
+ width: min(280px, 86%);
337
+ box-shadow: 12px 0 32px -16px rgba(22, 24, 26, 0.25);
338
+ animation: slideIn 0.15s ease-out;
339
+ }
340
+
341
+ .side-head {
342
+ display: flex;
343
+ align-items: center;
344
+ justify-content: space-between;
345
+ gap: 8px;
346
+ padding: 14px 12px 10px 16px;
347
+ }
348
+
349
+ .side-tools {
350
+ display: flex;
351
+ flex-direction: column;
352
+ gap: 8px;
353
+ padding: 0 12px 8px;
354
+ }
355
+
356
+ .new-chat {
357
+ display: flex;
358
+ align-items: center;
359
+ gap: 8px;
360
+ width: 100%;
361
+ min-height: 34px;
362
+ font-size: 13px;
363
+ font-weight: 500;
364
+ color: var(--c-on-brand);
365
+ background: var(--c-brand);
366
+ border: 1px solid var(--c-brand);
367
+ border-radius: var(--c-r2);
368
+ padding: 8px 12px;
369
+ cursor: pointer;
370
+ }
371
+
372
+ .new-chat:hover {
373
+ filter: brightness(1.2);
374
+ }
375
+
376
+ .search {
377
+ width: 100%;
378
+ font: inherit;
379
+ font-size: 13px;
380
+ color: var(--c-ink);
381
+ background: var(--c-bg);
382
+ border: 1px solid var(--c-line);
383
+ border-radius: var(--c-r2);
384
+ padding: 8px 10px;
385
+ outline: none;
386
+ }
387
+
388
+ .search:focus {
389
+ border-color: var(--c-ink);
390
+ }
391
+
392
+ .threads {
393
+ flex: 1;
394
+ min-height: 0;
395
+ overflow-y: auto;
396
+ display: flex;
397
+ flex-direction: column;
398
+ gap: 1px;
399
+ padding: 4px 12px 12px;
400
+ }
401
+
402
+ .group {
403
+ font-family: var(--c-mono);
404
+ font-size: 11px;
405
+ letter-spacing: 0.07em;
406
+ text-transform: uppercase;
407
+ color: var(--c-muted);
408
+ padding: 10px 8px 6px;
409
+ }
410
+
411
+ .thread {
412
+ display: flex;
413
+ align-items: center;
414
+ gap: 4px;
415
+ min-height: 34px;
416
+ width: 100%;
417
+ font-size: 13px;
418
+ color: var(--c-ink);
419
+ border-radius: var(--c-r2);
420
+ padding: 3px 4px 3px 10px;
421
+ cursor: pointer;
422
+ }
423
+
424
+ .thread:hover {
425
+ background: var(--c-hover);
426
+ }
427
+
428
+ .thread.active {
429
+ background: var(--c-line2);
430
+ font-weight: 500;
431
+ }
432
+
433
+ .thread-title {
434
+ flex: 1;
435
+ min-width: 0;
436
+ overflow: hidden;
437
+ text-overflow: ellipsis;
438
+ white-space: nowrap;
439
+ }
440
+
441
+ .thread-actions {
442
+ display: none;
443
+ gap: 0;
444
+ }
445
+
446
+ .thread:hover .thread-actions,
447
+ .thread:focus-within .thread-actions {
448
+ display: flex;
449
+ }
450
+
451
+ .thread-rename {
452
+ flex: 1;
453
+ min-width: 0;
454
+ font: inherit;
455
+ color: var(--c-ink);
456
+ background: var(--c-bg);
457
+ border: 1px solid var(--c-ink);
458
+ border-radius: var(--c-r);
459
+ padding: 3px 6px;
460
+ outline: none;
461
+ }
462
+
463
+ .side-extra {
464
+ display: none;
465
+ }
466
+
467
+ .side-extra.filled {
468
+ display: block;
469
+ padding: 12px 16px;
470
+ border-top: 1px solid var(--c-line);
471
+ font-size: 12.5px;
472
+ }
473
+
474
+ .side-note {
475
+ font-size: 12.5px;
476
+ color: var(--c-muted);
477
+ padding: 6px 10px;
478
+ }
479
+
480
+ .skeleton {
481
+ height: 28px;
482
+ margin: 3px 0;
483
+ border-radius: var(--c-r2);
484
+ background: linear-gradient(90deg, var(--c-hover) 0%, var(--c-line2) 50%, var(--c-hover) 100%);
485
+ background-size: 200% 100%;
486
+ animation: aiShimmer 1.6s linear infinite;
487
+ }
488
+
489
+ /* ── main column ──────────────────────────────────────── */
490
+
491
+ .main {
492
+ container: chat / inline-size;
493
+ position: relative;
494
+ flex: 1;
495
+ min-width: 0;
496
+ min-height: 0;
497
+ display: flex;
498
+ flex-direction: column;
499
+ }
500
+
501
+ .header {
502
+ display: flex;
503
+ align-items: center;
504
+ justify-content: space-between;
505
+ gap: 12px;
506
+ min-height: 52px;
507
+ padding: 10px 8px 10px 12px;
508
+ border-bottom: 1px solid var(--c-line);
509
+ }
510
+
511
+ .header-left {
512
+ display: flex;
513
+ align-items: center;
514
+ gap: 10px;
515
+ min-width: 0;
516
+ }
517
+
518
+ .header-right {
519
+ flex: 0 0 auto;
520
+ display: flex;
521
+ align-items: center;
522
+ gap: 2px;
523
+ }
524
+
525
+ .title {
526
+ min-width: 0;
527
+ font-size: 14px;
528
+ font-weight: 600;
529
+ letter-spacing: -0.01em;
530
+ overflow: hidden;
531
+ text-overflow: ellipsis;
532
+ white-space: nowrap;
533
+ background: none;
534
+ border: none;
535
+ padding: 2px 4px;
536
+ border-radius: var(--c-r);
537
+ cursor: text;
538
+ animation: aiIn 0.25s ease-out;
539
+ }
540
+
541
+ .title:hover:not(:disabled) {
542
+ background: var(--c-hover);
543
+ }
544
+
545
+ .title:disabled {
546
+ cursor: default;
547
+ }
548
+
549
+ .title-input {
550
+ min-width: 0;
551
+ width: 320px;
552
+ max-width: 100%;
553
+ font: inherit;
554
+ font-size: 14px;
555
+ font-weight: 600;
556
+ color: var(--c-ink);
557
+ background: var(--c-bg);
558
+ border: 1px solid var(--c-ink);
559
+ border-radius: var(--c-r);
560
+ padding: 2px 6px;
561
+ outline: none;
562
+ }
563
+
564
+ .divider {
565
+ width: 1px;
566
+ height: 18px;
567
+ background: var(--c-line);
568
+ margin: 0 4px;
569
+ }
570
+
571
+ .menu-wrap {
572
+ position: relative;
573
+ }
574
+
575
+ .menu-scrim {
576
+ position: fixed;
577
+ inset: 0;
578
+ z-index: 40;
579
+ }
580
+
581
+ .menu {
582
+ position: absolute;
583
+ right: 0;
584
+ top: 34px;
585
+ z-index: 41;
586
+ width: 220px;
587
+ display: flex;
588
+ flex-direction: column;
589
+ padding: 4px;
590
+ background: var(--c-bg);
591
+ border: 1px solid var(--c-line);
592
+ border-radius: var(--c-r2);
593
+ box-shadow: 0 12px 32px -12px rgba(22, 24, 26, 0.22);
594
+ animation: aiIn 0.15s ease-out;
595
+ }
596
+
597
+ .menu .label {
598
+ font-size: 10.5px;
599
+ padding: 8px 10px 6px;
600
+ }
601
+
602
+ .menu-item {
603
+ display: flex;
604
+ align-items: baseline;
605
+ justify-content: space-between;
606
+ gap: 10px;
607
+ width: 100%;
608
+ text-align: left;
609
+ font-size: 13px;
610
+ background: none;
611
+ border: none;
612
+ border-radius: var(--c-r);
613
+ padding: 8px 10px;
614
+ cursor: pointer;
615
+ }
616
+
617
+ .menu-item:hover {
618
+ background: var(--c-hover);
619
+ }
620
+
621
+ .menu-item .ext {
622
+ font-family: var(--c-mono);
623
+ font-size: 11px;
624
+ color: var(--c-muted);
625
+ }
626
+
627
+ .scroller {
628
+ position: relative;
629
+ flex: 1;
630
+ min-height: 0;
631
+ overflow-y: auto;
632
+ }
633
+
634
+ .banner {
635
+ margin: 10px 16px 0;
636
+ padding: 8px 12px;
637
+ font-size: 12.5px;
638
+ color: var(--c-ink2);
639
+ background: var(--c-bg2);
640
+ border: 1px solid var(--c-line);
641
+ border-radius: var(--c-r2);
642
+ }
643
+
644
+ /* ── welcome ──────────────────────────────────────────── */
645
+
646
+ .welcome-slot {
647
+ min-height: 100%;
648
+ display: flex;
649
+ flex-direction: column;
650
+ justify-content: center;
651
+ }
652
+
653
+ ::slotted([slot="welcome"]) {
654
+ box-sizing: border-box;
655
+ width: 100%;
656
+ max-width: 640px;
657
+ margin: 0 auto;
658
+ padding: 28px 18px;
659
+ }
660
+
661
+ .welcome {
662
+ max-width: 640px;
663
+ min-height: 100%;
664
+ margin: 0 auto;
665
+ display: flex;
666
+ flex-direction: column;
667
+ justify-content: center;
668
+ gap: 20px;
669
+ padding: 28px 18px;
670
+ }
671
+
672
+ .welcome-head {
673
+ display: flex;
674
+ flex-direction: column;
675
+ gap: 8px;
676
+ }
677
+
678
+ .welcome-logo {
679
+ width: 32px;
680
+ height: 32px;
681
+ object-fit: contain;
682
+ border-radius: var(--c-r2);
683
+ }
684
+
685
+ .welcome h2 {
686
+ margin: 0;
687
+ font-size: 24px;
688
+ font-weight: 600;
689
+ letter-spacing: -0.01em;
690
+ }
691
+
692
+ .welcome p {
693
+ margin: 0;
694
+ font-size: 14px;
695
+ line-height: 1.55;
696
+ color: var(--c-muted);
697
+ text-wrap: pretty;
698
+ }
699
+
700
+ .prompts {
701
+ display: grid;
702
+ grid-template-columns: repeat(2, minmax(0, 1fr));
703
+ gap: 8px;
704
+ }
705
+
706
+ .prompt {
707
+ display: flex;
708
+ flex-direction: column;
709
+ gap: 4px;
710
+ text-align: left;
711
+ background: var(--c-bg);
712
+ border: 1px solid var(--c-line);
713
+ border-radius: var(--c-r2);
714
+ padding: 12px 14px;
715
+ cursor: pointer;
716
+ transition:
717
+ border-color 0.15s,
718
+ box-shadow 0.15s;
719
+ }
720
+
721
+ .prompt:hover {
722
+ border-color: var(--c-ink);
723
+ box-shadow: 0 6px 18px -10px rgba(22, 24, 26, 0.25);
724
+ }
725
+
726
+ .prompt .label {
727
+ font-size: 10.5px;
728
+ letter-spacing: 0.06em;
729
+ }
730
+
731
+ .prompt-text {
732
+ font-size: 13.5px;
733
+ font-weight: 500;
734
+ line-height: 1.4;
735
+ }
736
+
737
+ @container chat (max-width: 480px) {
738
+ .prompts {
739
+ grid-template-columns: minmax(0, 1fr);
740
+ }
741
+ }
742
+
743
+ /* ── messages ─────────────────────────────────────────── */
744
+
745
+ .thread-view {
746
+ max-width: 760px;
747
+ margin: 0 auto;
748
+ display: flex;
749
+ flex-direction: column;
750
+ gap: 30px;
751
+ padding: 20px 16px 28px;
752
+ }
753
+
754
+ .msg {
755
+ position: relative;
756
+ display: flex;
757
+ flex-direction: column;
758
+ border-radius: var(--c-r3);
759
+ }
760
+
761
+ .msg.user {
762
+ align-self: flex-end;
763
+ max-width: 80%;
764
+ align-items: flex-end;
765
+ gap: 6px;
766
+ margin-bottom: -22px;
767
+ animation: aiIn 0.25s ease-out;
768
+ }
769
+
770
+ .bubble-user {
771
+ padding: 10px 14px;
772
+ font-size: 14.5px;
773
+ line-height: 1.6;
774
+ white-space: pre-wrap;
775
+ overflow-wrap: anywhere;
776
+ background: var(--c-hover);
777
+ border-radius: calc(var(--c-r) * 2.5) calc(var(--c-r) * 2.5) 2px calc(var(--c-r) * 2.5);
778
+ }
779
+
780
+ .attachments {
781
+ display: flex;
782
+ flex-wrap: wrap;
783
+ justify-content: flex-end;
784
+ gap: 6px;
785
+ }
786
+
787
+ .doc-chip {
788
+ display: inline-flex;
789
+ align-items: center;
790
+ gap: 8px;
791
+ padding: 6px 10px;
792
+ font-size: 12.5px;
793
+ border-radius: var(--c-r2);
794
+ border: 1px solid var(--c-line);
795
+ background: var(--c-bg);
796
+ }
797
+
798
+ .doc-chip .ext {
799
+ font-family: var(--c-mono);
800
+ font-size: 10px;
801
+ letter-spacing: 0.04em;
802
+ color: var(--c-muted);
803
+ }
804
+
805
+ .doc-chip .name {
806
+ max-width: 180px;
807
+ overflow: hidden;
808
+ text-overflow: ellipsis;
809
+ white-space: nowrap;
810
+ }
811
+
812
+ .toolbar {
813
+ display: flex;
814
+ align-items: center;
815
+ gap: 2px;
816
+ opacity: 0;
817
+ transition: opacity 0.15s;
818
+ }
819
+
820
+ .msg:hover .toolbar,
821
+ .msg:focus-within .toolbar,
822
+ .toolbar.pinned {
823
+ opacity: 1;
824
+ }
825
+
826
+ @media (hover: none) {
827
+ .toolbar {
828
+ opacity: 1;
829
+ }
830
+ }
831
+
832
+ .msg.bot .toolbar {
833
+ margin-left: -6px;
834
+ }
835
+
836
+ .time {
837
+ font-family: var(--c-mono);
838
+ font-size: 11px;
839
+ color: var(--c-faint);
840
+ padding: 0 6px;
841
+ font-variant-numeric: tabular-nums;
842
+ }
843
+
844
+ .note {
845
+ font-size: 12px;
846
+ color: var(--c-muted);
847
+ }
848
+
849
+ .spacer {
850
+ flex: 1;
851
+ }
852
+
853
+ .saved {
854
+ display: inline-flex;
855
+ align-items: center;
856
+ gap: 4px;
857
+ font-family: var(--c-mono);
858
+ font-size: 10.5px;
859
+ letter-spacing: 0.05em;
860
+ text-transform: uppercase;
861
+ color: var(--c-ink);
862
+ }
863
+
864
+ .saved svg {
865
+ width: 12px;
866
+ height: 12px;
867
+ fill: currentColor;
868
+ stroke: currentColor;
869
+ stroke-width: 1.5;
870
+ }
871
+
872
+ .bot-body {
873
+ position: relative;
874
+ z-index: 1;
875
+ display: flex;
876
+ flex-direction: column;
877
+ gap: 12px;
878
+ }
879
+
880
+ .edit-box {
881
+ width: 440px;
882
+ max-width: 100%;
883
+ display: flex;
884
+ flex-direction: column;
885
+ gap: 8px;
886
+ padding: 8px;
887
+ border: 1px solid var(--c-ink);
888
+ border-radius: var(--c-r3);
889
+ background: var(--c-bg);
890
+ }
891
+
892
+ .edit-box textarea {
893
+ width: 100%;
894
+ resize: vertical;
895
+ font: inherit;
896
+ font-size: 14px;
897
+ line-height: 1.5;
898
+ color: var(--c-ink);
899
+ background: transparent;
900
+ border: none;
901
+ outline: none;
902
+ padding: 4px;
903
+ }
904
+
905
+ .row-end {
906
+ display: flex;
907
+ justify-content: flex-end;
908
+ gap: 8px;
909
+ }
910
+
911
+ .btn {
912
+ font-size: 12.5px;
913
+ font-weight: 500;
914
+ border-radius: var(--c-r);
915
+ padding: 6px 12px;
916
+ cursor: pointer;
917
+ background: transparent;
918
+ color: var(--c-muted);
919
+ border: 1px solid var(--c-line);
920
+ }
921
+
922
+ .btn:hover {
923
+ color: var(--c-ink);
924
+ background: var(--c-bg2);
925
+ }
926
+
927
+ .btn.primary {
928
+ background: var(--c-brand);
929
+ color: var(--c-on-brand);
930
+ border-color: var(--c-brand);
931
+ }
932
+
933
+ .btn.primary:hover {
934
+ filter: brightness(1.2);
935
+ }
936
+
937
+ .error-card {
938
+ display: flex;
939
+ align-items: center;
940
+ justify-content: space-between;
941
+ gap: 12px;
942
+ padding: 10px 12px;
943
+ font-size: 13px;
944
+ color: var(--c-danger);
945
+ border: 1px solid var(--sb-danger-border, #f3d6d3);
946
+ background: var(--sb-danger-bg, #fdf1f0);
947
+ border-radius: var(--c-r2);
948
+ }
949
+
950
+ .followups {
951
+ display: flex;
952
+ flex-direction: column;
953
+ align-items: flex-start;
954
+ gap: 6px;
955
+ }
956
+
957
+ .followup {
958
+ display: inline-flex;
959
+ align-items: baseline;
960
+ gap: 8px;
961
+ text-align: left;
962
+ font-size: 13px;
963
+ background: var(--c-bg);
964
+ border: 1px solid var(--c-line);
965
+ border-radius: var(--c-r2);
966
+ padding: 6px 12px;
967
+ cursor: pointer;
968
+ animation: aiIn 0.25s ease-out;
969
+ }
970
+
971
+ .followup:hover {
972
+ background: var(--c-hover);
973
+ }
974
+
975
+ .followup .arrow {
976
+ font-family: var(--c-mono);
977
+ color: var(--c-muted);
978
+ }
979
+
980
+ .jump {
981
+ position: absolute;
982
+ left: 50%;
983
+ bottom: 8px;
984
+ transform: translateX(-50%);
985
+ z-index: 5;
986
+ font-size: 12.5px;
987
+ font-weight: 500;
988
+ color: var(--c-on-brand);
989
+ background: var(--c-brand);
990
+ border: none;
991
+ border-radius: 999px;
992
+ padding: 6px 14px;
993
+ cursor: pointer;
994
+ box-shadow: 0 8px 20px -10px rgba(22, 24, 26, 0.4);
995
+ animation: aiIn 0.2s ease-out;
996
+ }
997
+
998
+ /* ── rendered answer ──────────────────────────────────── */
999
+
1000
+ .answer {
1001
+ display: flex;
1002
+ flex-direction: column;
1003
+ gap: 14px;
1004
+ font-size: 14.5px;
1005
+ line-height: 1.7;
1006
+ }
1007
+
1008
+ .answer p {
1009
+ margin: 0;
1010
+ text-wrap: pretty;
1011
+ overflow-wrap: anywhere;
1012
+ }
1013
+
1014
+ .answer .raw {
1015
+ white-space: pre-wrap;
1016
+ }
1017
+
1018
+ .answer h3 {
1019
+ margin: 6px 0 0;
1020
+ font-size: 15.5px;
1021
+ font-weight: 600;
1022
+ letter-spacing: -0.01em;
1023
+ line-height: 1.4;
1024
+ }
1025
+
1026
+ .answer ul,
1027
+ .answer ol {
1028
+ margin: 0;
1029
+ padding-left: 20px;
1030
+ display: flex;
1031
+ flex-direction: column;
1032
+ gap: 6px;
1033
+ }
1034
+
1035
+ .answer li {
1036
+ line-height: 1.65;
1037
+ padding-left: 2px;
1038
+ }
1039
+
1040
+ .answer strong {
1041
+ font-weight: 600;
1042
+ }
1043
+
1044
+ .answer a {
1045
+ color: var(--c-ink);
1046
+ text-underline-offset: 3px;
1047
+ }
1048
+
1049
+ .answer code.inline {
1050
+ font-family: var(--c-mono);
1051
+ font-size: 12.5px;
1052
+ background: var(--c-hover);
1053
+ border-radius: calc(var(--c-r) * 0.75);
1054
+ padding: 1px 5px;
1055
+ }
1056
+
1057
+ .answer h3.h1 {
1058
+ font-size: 18px;
1059
+ }
1060
+
1061
+ .answer h3.h2 {
1062
+ font-size: 16.5px;
1063
+ }
1064
+
1065
+ .answer h3.h4 {
1066
+ font-size: 14.5px;
1067
+ }
1068
+
1069
+ .answer hr {
1070
+ width: 100%;
1071
+ border: none;
1072
+ border-top: 1px solid var(--c-line);
1073
+ margin: 4px 0;
1074
+ }
1075
+
1076
+ .answer li.task {
1077
+ list-style: none;
1078
+ margin-left: -18px;
1079
+ }
1080
+
1081
+ .answer li.task input {
1082
+ margin: 0 6px 0 0;
1083
+ vertical-align: -1px;
1084
+ accent-color: var(--c-brand);
1085
+ }
1086
+
1087
+ .callout {
1088
+ display: flex;
1089
+ flex-direction: column;
1090
+ gap: 4px;
1091
+ font-size: 13.5px;
1092
+ line-height: 1.6;
1093
+ padding: 10px 14px;
1094
+ border: 1px solid var(--c-line);
1095
+ border-left: 3px solid var(--callout, var(--c-ink));
1096
+ border-radius: var(--c-r2);
1097
+ background: color-mix(in srgb, var(--callout, var(--c-ink)) 7%, var(--c-bg));
1098
+ }
1099
+
1100
+ .callout-title {
1101
+ font-weight: 600;
1102
+ color: var(--callout, var(--c-ink));
1103
+ }
1104
+
1105
+ .callout.note {
1106
+ --callout: oklch(0.55 0.15 255);
1107
+ }
1108
+
1109
+ .callout.tip {
1110
+ --callout: oklch(0.55 0.12 160);
1111
+ }
1112
+
1113
+ .callout.important {
1114
+ --callout: oklch(0.52 0.17 300);
1115
+ }
1116
+
1117
+ .callout.warning {
1118
+ --callout: oklch(0.6 0.14 70);
1119
+ }
1120
+
1121
+ .callout.caution {
1122
+ --callout: var(--c-danger);
1123
+ }
1124
+
1125
+ .jtree {
1126
+ padding: 10px 14px;
1127
+ overflow-x: auto;
1128
+ font-family: var(--c-mono);
1129
+ font-size: 12.5px;
1130
+ line-height: 1.7;
1131
+ }
1132
+
1133
+ .jtree summary {
1134
+ cursor: pointer;
1135
+ list-style-position: outside;
1136
+ }
1137
+
1138
+ .jkids {
1139
+ padding-left: 16px;
1140
+ border-left: 1px solid var(--c-line);
1141
+ margin-left: 4px;
1142
+ }
1143
+
1144
+ .jkey {
1145
+ color: var(--c-ink2);
1146
+ }
1147
+
1148
+ .jmeta {
1149
+ color: var(--c-muted);
1150
+ }
1151
+
1152
+ .jv.string {
1153
+ color: oklch(0.52 0.12 160);
1154
+ }
1155
+
1156
+ .jv.number {
1157
+ color: oklch(0.55 0.15 255);
1158
+ }
1159
+
1160
+ .jv.boolean,
1161
+ .jv.null {
1162
+ color: oklch(0.52 0.17 300);
1163
+ }
1164
+
1165
+ .table th button.sort {
1166
+ display: inline-flex;
1167
+ align-items: center;
1168
+ gap: 4px;
1169
+ font: inherit;
1170
+ color: inherit;
1171
+ background: none;
1172
+ border: none;
1173
+ padding: 0;
1174
+ cursor: pointer;
1175
+ }
1176
+
1177
+ .table th .arrow {
1178
+ font-size: 10px;
1179
+ opacity: 0.5;
1180
+ }
1181
+
1182
+ .table th[aria-sort="ascending"] .arrow,
1183
+ .table th[aria-sort="descending"] .arrow {
1184
+ opacity: 1;
1185
+ }
1186
+
1187
+ .table-note {
1188
+ padding: 7px 12px;
1189
+ font-size: 12px;
1190
+ color: var(--c-muted);
1191
+ border-top: 1px solid var(--c-line2);
1192
+ background: var(--c-bg2);
1193
+ }
1194
+
1195
+ figure.svg {
1196
+ margin: 0;
1197
+ display: flex;
1198
+ flex-direction: column;
1199
+ gap: 6px;
1200
+ align-items: flex-start;
1201
+ }
1202
+
1203
+ figure.svg img {
1204
+ display: block;
1205
+ width: min(100%, 480px);
1206
+ height: auto;
1207
+ max-height: 420px;
1208
+ object-fit: contain;
1209
+ padding: 12px;
1210
+ border: 1px solid var(--c-line);
1211
+ border-radius: var(--c-r2);
1212
+ background: #ffffff;
1213
+ }
1214
+
1215
+ .custom-block {
1216
+ min-width: 0;
1217
+ }
1218
+
1219
+ .quote {
1220
+ font-size: 13.5px;
1221
+ line-height: 1.6;
1222
+ color: var(--c-ink2);
1223
+ background: var(--c-bg2);
1224
+ border: 1px solid var(--c-line);
1225
+ border-radius: var(--c-r2);
1226
+ padding: 10px 14px;
1227
+ }
1228
+
1229
+ .code {
1230
+ border: 1px solid var(--c-line);
1231
+ border-radius: var(--c-r2);
1232
+ overflow: hidden;
1233
+ background: var(--c-bg2);
1234
+ }
1235
+
1236
+ .code-head {
1237
+ display: flex;
1238
+ align-items: center;
1239
+ justify-content: space-between;
1240
+ padding: 7px 12px;
1241
+ border-bottom: 1px solid var(--c-line);
1242
+ }
1243
+
1244
+ .code-head .label {
1245
+ font-size: 11px;
1246
+ }
1247
+
1248
+ .text-btn {
1249
+ font-size: 12px;
1250
+ color: var(--c-muted);
1251
+ background: none;
1252
+ border: none;
1253
+ padding: 0;
1254
+ cursor: pointer;
1255
+ }
1256
+
1257
+ .text-btn:hover {
1258
+ color: var(--c-ink);
1259
+ }
1260
+
1261
+ .text-btn.underline {
1262
+ text-decoration: underline;
1263
+ text-underline-offset: 3px;
1264
+ }
1265
+
1266
+ .code pre {
1267
+ margin: 0;
1268
+ padding: 12px 14px;
1269
+ overflow-x: auto;
1270
+ font-family: var(--c-mono);
1271
+ font-size: 13px;
1272
+ line-height: 1.6;
1273
+ }
1274
+
1275
+ .table {
1276
+ border: 1px solid var(--c-line);
1277
+ border-radius: var(--c-r2);
1278
+ overflow-x: auto;
1279
+ }
1280
+
1281
+ .table table {
1282
+ width: 100%;
1283
+ border-collapse: collapse;
1284
+ font-size: 13px;
1285
+ font-variant-numeric: tabular-nums;
1286
+ }
1287
+
1288
+ .table th {
1289
+ text-align: left;
1290
+ font-size: 12px;
1291
+ font-weight: 500;
1292
+ color: var(--c-muted);
1293
+ background: var(--c-bg2);
1294
+ border-bottom: 1px solid var(--c-line);
1295
+ padding: 9px 12px;
1296
+ white-space: nowrap;
1297
+ }
1298
+
1299
+ .table td {
1300
+ padding: 9px 12px;
1301
+ border-top: 1px solid var(--c-line2);
1302
+ white-space: nowrap;
1303
+ }
1304
+
1305
+ .table th:first-child,
1306
+ .table td:first-child {
1307
+ min-width: 120px;
1308
+ }
1309
+
1310
+ .cite {
1311
+ display: inline-flex;
1312
+ align-items: center;
1313
+ justify-content: center;
1314
+ min-width: 17px;
1315
+ height: 17px;
1316
+ padding: 0 4px;
1317
+ margin: 0 1px 0 3px;
1318
+ vertical-align: 2px;
1319
+ font: 500 10px var(--c-mono);
1320
+ border-radius: calc(var(--c-r) * 0.75);
1321
+ cursor: pointer;
1322
+ border: 1px solid var(--c-strong);
1323
+ background: var(--c-hover);
1324
+ color: var(--c-ink);
1325
+ }
1326
+
1327
+ .cite:hover,
1328
+ .cite.active {
1329
+ background: var(--c-ink);
1330
+ color: var(--c-bg);
1331
+ border-color: var(--c-ink);
1332
+ }
1333
+
1334
+ .chart {
1335
+ margin: 0;
1336
+ display: flex;
1337
+ flex-direction: column;
1338
+ gap: 14px;
1339
+ border: 1px solid var(--c-line);
1340
+ border-radius: var(--c-r2);
1341
+ padding: 14px 16px 12px;
1342
+ background: var(--c-bg);
1343
+ }
1344
+
1345
+ .chart-head {
1346
+ display: flex;
1347
+ flex-wrap: wrap;
1348
+ align-items: baseline;
1349
+ justify-content: space-between;
1350
+ gap: 8px 16px;
1351
+ }
1352
+
1353
+ .chart-title {
1354
+ font-size: 13px;
1355
+ font-weight: 600;
1356
+ }
1357
+
1358
+ .legend {
1359
+ display: flex;
1360
+ flex-wrap: wrap;
1361
+ gap: 4px 12px;
1362
+ }
1363
+
1364
+ .legend span {
1365
+ display: inline-flex;
1366
+ align-items: center;
1367
+ gap: 6px;
1368
+ font-size: 12px;
1369
+ color: var(--c-ink2);
1370
+ }
1371
+
1372
+ .swatch {
1373
+ width: 8px;
1374
+ height: 8px;
1375
+ border-radius: 2px;
1376
+ }
1377
+
1378
+ .bars {
1379
+ display: flex;
1380
+ flex-direction: column;
1381
+ gap: 10px;
1382
+ }
1383
+
1384
+ .bar-row {
1385
+ display: grid;
1386
+ grid-template-columns: 92px minmax(0, 1fr) 64px;
1387
+ align-items: center;
1388
+ gap: 12px;
1389
+ }
1390
+
1391
+ .bar-label {
1392
+ font-size: 12.5px;
1393
+ color: var(--c-ink2);
1394
+ overflow: hidden;
1395
+ text-overflow: ellipsis;
1396
+ white-space: nowrap;
1397
+ }
1398
+
1399
+ .bar-track {
1400
+ display: flex;
1401
+ height: 12px;
1402
+ background: var(--c-hover);
1403
+ border-radius: 2px;
1404
+ overflow: hidden;
1405
+ }
1406
+
1407
+ .bar-fill {
1408
+ display: flex;
1409
+ height: 100%;
1410
+ transform-origin: left;
1411
+ animation: aiGrow 0.8s cubic-bezier(0.2, 0.8, 0.2, 1);
1412
+ }
1413
+
1414
+ .bar-value {
1415
+ font-family: var(--c-mono);
1416
+ font-size: 11.5px;
1417
+ text-align: right;
1418
+ font-variant-numeric: tabular-nums;
1419
+ }
1420
+
1421
+ .line-chart {
1422
+ display: flex;
1423
+ flex-direction: column;
1424
+ gap: 6px;
1425
+ padding-left: 48px;
1426
+ }
1427
+
1428
+ .plot {
1429
+ position: relative;
1430
+ height: 170px;
1431
+ }
1432
+
1433
+ .tick {
1434
+ position: absolute;
1435
+ left: 0;
1436
+ right: 0;
1437
+ border-top: 1px dashed var(--c-line2);
1438
+ }
1439
+
1440
+ .tick.base {
1441
+ border-top: 1px solid var(--c-strong);
1442
+ }
1443
+
1444
+ .tick span,
1445
+ .x-labels span {
1446
+ font-family: var(--c-mono);
1447
+ font-size: 10.5px;
1448
+ color: var(--c-faint);
1449
+ white-space: nowrap;
1450
+ font-variant-numeric: tabular-nums;
1451
+ }
1452
+
1453
+ .tick span {
1454
+ position: absolute;
1455
+ right: calc(100% + 8px);
1456
+ top: -7px;
1457
+ }
1458
+
1459
+ .plot svg {
1460
+ position: absolute;
1461
+ inset: 0;
1462
+ width: 100%;
1463
+ height: 100%;
1464
+ overflow: visible;
1465
+ }
1466
+
1467
+ .plot polyline {
1468
+ fill: none;
1469
+ stroke-width: 2;
1470
+ vector-effect: non-scaling-stroke;
1471
+ stroke-linejoin: round;
1472
+ stroke-linecap: round;
1473
+ stroke-dasharray: 1;
1474
+ animation: aiDraw 1s ease-out;
1475
+ }
1476
+
1477
+ .x-labels {
1478
+ display: flex;
1479
+ justify-content: space-between;
1480
+ gap: 4px;
1481
+ }
1482
+
1483
+ .chart-pending {
1484
+ display: flex;
1485
+ align-items: center;
1486
+ justify-content: center;
1487
+ height: 190px;
1488
+ border: 1px solid var(--c-line);
1489
+ border-radius: var(--c-r2);
1490
+ background: linear-gradient(90deg, var(--c-bg2) 0%, var(--c-hover) 50%, var(--c-bg2) 100%);
1491
+ background-size: 200% 100%;
1492
+ animation: aiShimmer 1.6s linear infinite;
1493
+ }
1494
+
1495
+ .gallery {
1496
+ display: grid;
1497
+ grid-template-columns: minmax(0, 1fr);
1498
+ gap: 10px;
1499
+ max-width: 520px;
1500
+ }
1501
+
1502
+ .gallery.many {
1503
+ grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
1504
+ max-width: 100%;
1505
+ }
1506
+
1507
+ .gallery figure {
1508
+ margin: 0;
1509
+ display: flex;
1510
+ flex-direction: column;
1511
+ gap: 6px;
1512
+ min-width: 0;
1513
+ }
1514
+
1515
+ .gallery img {
1516
+ width: 100%;
1517
+ aspect-ratio: 16 / 10;
1518
+ max-height: 320px;
1519
+ object-fit: contain;
1520
+ border-radius: var(--c-r2);
1521
+ border: 1px solid var(--c-line);
1522
+ background: var(--c-bg2);
1523
+ }
1524
+
1525
+ .img-missing {
1526
+ aspect-ratio: 16 / 9;
1527
+ display: flex;
1528
+ align-items: center;
1529
+ justify-content: center;
1530
+ border-radius: var(--c-r2);
1531
+ border: 1px dashed var(--c-strong);
1532
+ background: repeating-linear-gradient(135deg, var(--c-bg2) 0 10px, var(--c-hover) 10px 20px);
1533
+ }
1534
+
1535
+ figcaption {
1536
+ font-family: var(--c-mono);
1537
+ font-size: 11px;
1538
+ color: var(--c-muted);
1539
+ overflow: hidden;
1540
+ text-overflow: ellipsis;
1541
+ white-space: nowrap;
1542
+ }
1543
+
1544
+ .caret {
1545
+ display: inline-block;
1546
+ width: 7px;
1547
+ height: 15px;
1548
+ margin-top: -6px;
1549
+ background: var(--c-brand);
1550
+ animation: rgcaret 1s steps(1) infinite;
1551
+ }
1552
+
1553
+ /* ── sources ──────────────────────────────────────────── */
1554
+
1555
+ .retrieval {
1556
+ display: flex;
1557
+ flex-direction: column;
1558
+ border: 1px solid var(--c-line);
1559
+ border-radius: var(--c-r2);
1560
+ background: var(--c-bg2);
1561
+ }
1562
+
1563
+ .retrieval-toggle {
1564
+ display: flex;
1565
+ align-items: center;
1566
+ gap: 10px;
1567
+ width: 100%;
1568
+ text-align: left;
1569
+ font-size: 12.5px;
1570
+ color: var(--c-ink2);
1571
+ background: none;
1572
+ border: none;
1573
+ padding: 9px 12px;
1574
+ cursor: pointer;
1575
+ }
1576
+
1577
+ .retrieval-toggle .chev,
1578
+ .retrieval-toggle .ms {
1579
+ font-family: var(--c-mono);
1580
+ font-size: 11px;
1581
+ color: var(--c-muted);
1582
+ }
1583
+
1584
+ .retrieval-list {
1585
+ display: flex;
1586
+ flex-direction: column;
1587
+ border-top: 1px solid var(--c-line);
1588
+ padding: 4px 12px;
1589
+ }
1590
+
1591
+ .passage {
1592
+ display: grid;
1593
+ grid-template-columns: 22px minmax(0, 1fr) 64px;
1594
+ align-items: center;
1595
+ gap: 10px;
1596
+ width: 100%;
1597
+ text-align: left;
1598
+ background: none;
1599
+ border: none;
1600
+ border-bottom: 1px solid var(--c-line2);
1601
+ padding: 8px 0;
1602
+ cursor: pointer;
1603
+ }
1604
+
1605
+ .passage:last-child {
1606
+ border-bottom: none;
1607
+ }
1608
+
1609
+ .passage .n,
1610
+ .passage .score {
1611
+ font-family: var(--c-mono);
1612
+ font-size: 11px;
1613
+ color: var(--c-muted);
1614
+ font-variant-numeric: tabular-nums;
1615
+ }
1616
+
1617
+ .passage .what {
1618
+ display: flex;
1619
+ flex-direction: column;
1620
+ gap: 1px;
1621
+ min-width: 0;
1622
+ }
1623
+
1624
+ .passage .what span:first-child {
1625
+ font-size: 12.5px;
1626
+ overflow: hidden;
1627
+ text-overflow: ellipsis;
1628
+ white-space: nowrap;
1629
+ }
1630
+
1631
+ .passage .what span:last-child {
1632
+ font-size: 11.5px;
1633
+ color: var(--c-muted);
1634
+ }
1635
+
1636
+ .relevance {
1637
+ display: flex;
1638
+ flex-direction: column;
1639
+ gap: 3px;
1640
+ align-items: flex-end;
1641
+ }
1642
+
1643
+ .relevance-track {
1644
+ width: 64px;
1645
+ height: 3px;
1646
+ background: var(--c-line);
1647
+ border-radius: 99px;
1648
+ overflow: hidden;
1649
+ }
1650
+
1651
+ .relevance-fill {
1652
+ display: block;
1653
+ height: 100%;
1654
+ background: var(--c-brand);
1655
+ }
1656
+
1657
+ .cards {
1658
+ display: flex;
1659
+ flex-direction: column;
1660
+ gap: 8px;
1661
+ }
1662
+
1663
+ .card-grid {
1664
+ display: grid;
1665
+ grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
1666
+ gap: 8px;
1667
+ }
1668
+
1669
+ .source-card {
1670
+ display: flex;
1671
+ flex-direction: column;
1672
+ gap: 6px;
1673
+ min-width: 0;
1674
+ text-align: left;
1675
+ padding: 10px 12px;
1676
+ border-radius: var(--c-r2);
1677
+ cursor: pointer;
1678
+ background: var(--c-bg);
1679
+ border: 1px solid var(--c-line);
1680
+ }
1681
+
1682
+ .source-card:hover,
1683
+ .source-card.active {
1684
+ border-color: var(--c-ink);
1685
+ }
1686
+
1687
+ .source-card .top {
1688
+ display: flex;
1689
+ align-items: center;
1690
+ gap: 8px;
1691
+ min-width: 0;
1692
+ }
1693
+
1694
+ .num {
1695
+ min-width: 16px;
1696
+ height: 16px;
1697
+ padding: 0 4px;
1698
+ border-radius: calc(var(--c-r) * 0.75);
1699
+ border: 1px solid var(--c-strong);
1700
+ display: inline-flex;
1701
+ align-items: center;
1702
+ justify-content: center;
1703
+ font-family: var(--c-mono);
1704
+ font-size: 10px;
1705
+ background: var(--c-bg);
1706
+ }
1707
+
1708
+ .source-card .t {
1709
+ font-size: 13px;
1710
+ font-weight: 500;
1711
+ overflow: hidden;
1712
+ text-overflow: ellipsis;
1713
+ white-space: nowrap;
1714
+ }
1715
+
1716
+ .source-card .s {
1717
+ font-size: 12px;
1718
+ line-height: 1.45;
1719
+ color: var(--c-muted);
1720
+ display: -webkit-box;
1721
+ -webkit-line-clamp: 2;
1722
+ -webkit-box-orient: vertical;
1723
+ overflow: hidden;
1724
+ }
1725
+
1726
+ .panel {
1727
+ display: flex;
1728
+ flex-direction: column;
1729
+ min-height: 0;
1730
+ min-width: 0;
1731
+ background: var(--c-bg);
1732
+ border-left: 1px solid var(--c-line);
1733
+ animation: aiIn 0.15s ease-out;
1734
+ }
1735
+
1736
+ .panel.docked {
1737
+ position: relative;
1738
+ flex: 0 0 400px;
1739
+ width: 400px;
1740
+ }
1741
+
1742
+ .panel.overlay {
1743
+ position: absolute;
1744
+ right: 0;
1745
+ top: 0;
1746
+ bottom: 0;
1747
+ z-index: 30;
1748
+ width: min(420px, 100%);
1749
+ box-shadow: -12px 0 32px -16px rgba(22, 24, 26, 0.25);
1750
+ }
1751
+
1752
+ .panel-head {
1753
+ display: flex;
1754
+ align-items: center;
1755
+ justify-content: space-between;
1756
+ gap: 8px;
1757
+ padding: 14px 18px;
1758
+ border-bottom: 1px solid var(--c-line);
1759
+ }
1760
+
1761
+ .panel-body {
1762
+ flex: 1;
1763
+ min-height: 0;
1764
+ overflow-y: auto;
1765
+ display: flex;
1766
+ flex-direction: column;
1767
+ gap: 16px;
1768
+ padding: 18px;
1769
+ }
1770
+
1771
+ .panel-body h3 {
1772
+ margin: 0;
1773
+ font-size: 16px;
1774
+ font-weight: 600;
1775
+ letter-spacing: -0.01em;
1776
+ }
1777
+
1778
+ .panel-meta {
1779
+ display: flex;
1780
+ flex-direction: column;
1781
+ gap: 4px;
1782
+ }
1783
+
1784
+ .panel-meta .path {
1785
+ font-family: var(--c-mono);
1786
+ font-size: 11px;
1787
+ color: var(--c-muted);
1788
+ overflow-wrap: anywhere;
1789
+ }
1790
+
1791
+ .panel-meta .meta {
1792
+ font-size: 12px;
1793
+ color: var(--c-muted);
1794
+ }
1795
+
1796
+ .passage-box {
1797
+ display: flex;
1798
+ flex-direction: column;
1799
+ gap: 8px;
1800
+ padding: 12px 14px;
1801
+ border-radius: var(--c-r2);
1802
+ background: var(--c-hover);
1803
+ border: 1px solid var(--c-strong);
1804
+ }
1805
+
1806
+ .passage-box .text {
1807
+ font-size: 13px;
1808
+ line-height: 1.6;
1809
+ color: var(--c-ink2);
1810
+ white-space: pre-wrap;
1811
+ overflow-wrap: anywhere;
1812
+ }
1813
+
1814
+ .passage-foot {
1815
+ display: flex;
1816
+ align-items: center;
1817
+ justify-content: space-between;
1818
+ gap: 8px;
1819
+ padding-top: 8px;
1820
+ border-top: 1px solid var(--c-line);
1821
+ }
1822
+
1823
+ .copy-ref {
1824
+ display: inline-flex;
1825
+ align-items: center;
1826
+ gap: 6px;
1827
+ font-size: 12px;
1828
+ background: var(--c-bg);
1829
+ border: 1px solid var(--c-line);
1830
+ border-radius: var(--c-r);
1831
+ padding: 4px 8px;
1832
+ cursor: pointer;
1833
+ }
1834
+
1835
+ .copy-ref:hover {
1836
+ border-color: var(--c-strong);
1837
+ }
1838
+
1839
+ .panel-foot {
1840
+ display: flex;
1841
+ flex-direction: column;
1842
+ gap: 6px;
1843
+ padding: 12px 18px 16px;
1844
+ border-top: 1px solid var(--c-line);
1845
+ }
1846
+
1847
+ .chips {
1848
+ display: flex;
1849
+ flex-wrap: wrap;
1850
+ gap: 6px;
1851
+ }
1852
+
1853
+ .chip {
1854
+ font-size: 12px;
1855
+ background: var(--c-bg);
1856
+ border: 1px solid var(--c-line);
1857
+ border-radius: var(--c-r);
1858
+ padding: 4px 8px;
1859
+ cursor: pointer;
1860
+ max-width: 100%;
1861
+ overflow: hidden;
1862
+ text-overflow: ellipsis;
1863
+ white-space: nowrap;
1864
+ }
1865
+
1866
+ .chip:hover {
1867
+ border-color: var(--c-ink);
1868
+ }
1869
+
1870
+ /* ── composer ─────────────────────────────────────────── */
1871
+
1872
+ .composer-wrap {
1873
+ padding: 0 12px 12px;
1874
+ }
1875
+
1876
+ .composer-wrap.reader {
1877
+ padding-top: 10px;
1878
+ }
1879
+
1880
+ .composer-col {
1881
+ max-width: 760px;
1882
+ margin: 0 auto;
1883
+ display: flex;
1884
+ flex-direction: column;
1885
+ gap: 8px;
1886
+ }
1887
+
1888
+ .composer-box {
1889
+ position: relative;
1890
+ }
1891
+
1892
+ .composer {
1893
+ position: relative;
1894
+ z-index: 1;
1895
+ display: flex;
1896
+ flex-direction: column;
1897
+ gap: 4px;
1898
+ padding: 8px;
1899
+ border-radius: calc(var(--c-r) * 2.25);
1900
+ background: var(--c-bg);
1901
+ border: 1px solid var(--c-strong);
1902
+ box-shadow:
1903
+ 0 1px 2px rgba(22, 24, 26, 0.04),
1904
+ 0 12px 32px -18px rgba(22, 24, 26, 0.22);
1905
+ transition: border-color 0.15s;
1906
+ }
1907
+
1908
+ .composer:focus-within {
1909
+ border-color: var(--c-ink);
1910
+ }
1911
+
1912
+ .composer.busy {
1913
+ border-color: transparent;
1914
+ }
1915
+
1916
+ :host([glow="off"]) .composer.busy {
1917
+ border-color: var(--c-strong);
1918
+ }
1919
+
1920
+ .composer textarea {
1921
+ width: 100%;
1922
+ resize: none;
1923
+ font: inherit;
1924
+ font-size: 14.5px;
1925
+ line-height: 1.5;
1926
+ color: var(--c-ink);
1927
+ background: transparent;
1928
+ border: none;
1929
+ outline: none;
1930
+ padding: 6px 6px 2px;
1931
+ max-height: 176px;
1932
+ }
1933
+
1934
+ .composer textarea::placeholder {
1935
+ color: var(--c-faint);
1936
+ }
1937
+
1938
+ .composer-row {
1939
+ display: flex;
1940
+ align-items: center;
1941
+ justify-content: space-between;
1942
+ gap: 8px;
1943
+ }
1944
+
1945
+ .attach {
1946
+ display: inline-flex;
1947
+ align-items: center;
1948
+ gap: 6px;
1949
+ font-size: 12.5px;
1950
+ color: var(--c-muted);
1951
+ background: none;
1952
+ border: none;
1953
+ border-radius: var(--c-r);
1954
+ padding: 6px 8px;
1955
+ cursor: pointer;
1956
+ }
1957
+
1958
+ .attach:hover {
1959
+ background: var(--c-hover);
1960
+ color: var(--c-ink);
1961
+ }
1962
+
1963
+ .send {
1964
+ display: inline-flex;
1965
+ align-items: center;
1966
+ justify-content: center;
1967
+ width: 32px;
1968
+ height: 32px;
1969
+ padding: 0;
1970
+ border-radius: var(--c-r2);
1971
+ border: 1px solid var(--c-brand);
1972
+ cursor: pointer;
1973
+ background: var(--c-brand);
1974
+ color: var(--c-on-brand);
1975
+ transition: background 0.15s;
1976
+ }
1977
+
1978
+ .send:disabled {
1979
+ cursor: default;
1980
+ background: var(--c-line);
1981
+ border-color: var(--c-line);
1982
+ color: var(--c-faint);
1983
+ }
1984
+
1985
+ .send.stop {
1986
+ background: var(--c-bg);
1987
+ color: var(--c-ink);
1988
+ border-color: var(--c-ink);
1989
+ }
1990
+
1991
+ .send.stop svg {
1992
+ fill: currentColor;
1993
+ stroke: none;
1994
+ }
1995
+
1996
+ .pending-files {
1997
+ display: flex;
1998
+ flex-wrap: wrap;
1999
+ gap: 6px;
2000
+ padding: 2px 2px 4px;
2001
+ }
2002
+
2003
+ .pending-file {
2004
+ display: inline-flex;
2005
+ align-items: center;
2006
+ gap: 8px;
2007
+ padding: 4px 8px 4px 4px;
2008
+ font-size: 12.5px;
2009
+ border-radius: var(--c-r2);
2010
+ border: 1px solid var(--c-line);
2011
+ background: var(--c-bg2);
2012
+ animation: aiIn 0.2s ease-out;
2013
+ }
2014
+
2015
+ .pending-file .ext {
2016
+ width: 28px;
2017
+ height: 28px;
2018
+ display: inline-flex;
2019
+ align-items: center;
2020
+ justify-content: center;
2021
+ border-radius: var(--c-r);
2022
+ background: var(--c-bg);
2023
+ border: 1px solid var(--c-line);
2024
+ font-family: var(--c-mono);
2025
+ font-size: 9px;
2026
+ letter-spacing: 0.03em;
2027
+ color: var(--c-muted);
2028
+ }
2029
+
2030
+ .pending-file .meta {
2031
+ display: flex;
2032
+ flex-direction: column;
2033
+ gap: 1px;
2034
+ min-width: 0;
2035
+ }
2036
+
2037
+ .pending-file .name {
2038
+ max-width: 160px;
2039
+ overflow: hidden;
2040
+ text-overflow: ellipsis;
2041
+ white-space: nowrap;
2042
+ }
2043
+
2044
+ .pending-file .size {
2045
+ font-family: var(--c-mono);
2046
+ font-size: 10.5px;
2047
+ color: var(--c-muted);
2048
+ }
2049
+
2050
+ .pending-file button {
2051
+ font-size: 15px;
2052
+ line-height: 1;
2053
+ color: var(--c-muted);
2054
+ background: none;
2055
+ border: none;
2056
+ padding: 0 0 0 2px;
2057
+ cursor: pointer;
2058
+ }
2059
+
2060
+ .pending-file button:hover {
2061
+ color: var(--c-danger);
2062
+ }
2063
+
2064
+ .footnote {
2065
+ text-align: center;
2066
+ font-size: 11.5px;
2067
+ color: var(--c-muted);
2068
+ }
2069
+
2070
+ .branding {
2071
+ padding: 0 12px 10px;
2072
+ margin-top: -4px;
2073
+ }
2074
+
2075
+ .toast {
2076
+ position: absolute;
2077
+ left: 50%;
2078
+ bottom: 124px;
2079
+ transform: translateX(-50%);
2080
+ z-index: 35;
2081
+ display: flex;
2082
+ align-items: center;
2083
+ gap: 14px;
2084
+ padding: 9px 14px;
2085
+ background: var(--c-ink);
2086
+ color: var(--c-bg);
2087
+ font-size: 13px;
2088
+ border-radius: var(--c-r2);
2089
+ box-shadow: 0 12px 32px -12px rgba(22, 24, 26, 0.25);
2090
+ white-space: nowrap;
2091
+ animation: aiIn 0.2s ease-out;
2092
+ }
2093
+
2094
+ .toast button {
2095
+ font-size: 13px;
2096
+ font-weight: 500;
2097
+ color: var(--c-bg);
2098
+ background: none;
2099
+ border: none;
2100
+ padding: 0;
2101
+ cursor: pointer;
2102
+ text-decoration: underline;
2103
+ text-underline-offset: 3px;
2104
+ }
2105
+
2106
+ .drop {
2107
+ position: absolute;
2108
+ inset: 10px;
2109
+ z-index: 36;
2110
+ display: flex;
2111
+ flex-direction: column;
2112
+ align-items: center;
2113
+ justify-content: center;
2114
+ gap: 6px;
2115
+ text-align: center;
2116
+ padding: 16px;
2117
+ border: 1.5px dashed var(--c-ink);
2118
+ border-radius: var(--c-r3);
2119
+ background: color-mix(in srgb, var(--c-bg) 92%, transparent);
2120
+ }
2121
+
2122
+ .drop strong {
2123
+ font-size: 15px;
2124
+ font-weight: 600;
2125
+ }
2126
+
2127
+ .drop span {
2128
+ font-size: 12.5px;
2129
+ color: var(--c-muted);
2130
+ }
2131
+
2132
+ /* ── AI glow ──────────────────────────────────────────── */
2133
+
2134
+ .halo {
2135
+ position: absolute;
2136
+ inset: -18px -24px;
2137
+ z-index: 0;
2138
+ pointer-events: none;
2139
+ opacity: var(--c-glow);
2140
+ }
2141
+
2142
+ .halo::before {
2143
+ content: "";
2144
+ position: absolute;
2145
+ inset: 0;
2146
+ border-radius: 20px;
2147
+ background: var(--c-conic);
2148
+ filter: blur(32px);
2149
+ opacity: 0.45;
2150
+ animation:
2151
+ aiSpin 5s linear infinite,
2152
+ aiBreathe 2.6s ease-in-out infinite;
2153
+ }
2154
+
2155
+ .arrived {
2156
+ position: absolute;
2157
+ inset: -12px -16px;
2158
+ z-index: 0;
2159
+ pointer-events: none;
2160
+ border-radius: var(--c-r4);
2161
+ animation: aiDone 2.6s ease-out forwards;
2162
+ }
2163
+
2164
+ .arrived .wash {
2165
+ position: absolute;
2166
+ inset: 0;
2167
+ border-radius: inherit;
2168
+ background: var(--c-conic);
2169
+ filter: blur(26px);
2170
+ opacity: calc(0.22 * var(--c-glow) + 0.06);
2171
+ animation: aiSpin 2.6s linear infinite;
2172
+ }
2173
+
2174
+ .ring {
2175
+ position: absolute;
2176
+ inset: 0;
2177
+ border-radius: inherit;
2178
+ padding: 1px;
2179
+ background: var(--c-conic);
2180
+ -webkit-mask:
2181
+ linear-gradient(#000 0 0) content-box,
2182
+ linear-gradient(#000 0 0);
2183
+ -webkit-mask-composite: xor;
2184
+ mask-composite: exclude;
2185
+ animation: aiSpin 2.6s linear infinite;
2186
+ pointer-events: none;
2187
+ }
2188
+
2189
+ .arrived .sweep {
2190
+ position: absolute;
2191
+ inset: 0;
2192
+ border-radius: inherit;
2193
+ overflow: hidden;
2194
+ }
2195
+
2196
+ .arrived .sweep::before {
2197
+ content: "";
2198
+ position: absolute;
2199
+ inset: 0;
2200
+ background: linear-gradient(
2201
+ 100deg,
2202
+ transparent 25%,
2203
+ oklch(0.88 0.07 260 / 0.5) 50%,
2204
+ transparent 75%
2205
+ );
2206
+ animation: aiSweep 1.6s cubic-bezier(0.3, 0.6, 0.3, 1) forwards;
2207
+ }
2208
+
2209
+ .pill {
2210
+ position: relative;
2211
+ display: inline-flex;
2212
+ align-self: flex-start;
2213
+ align-items: center;
2214
+ gap: 9px;
2215
+ padding: 6px 14px 6px 10px;
2216
+ border-radius: 999px;
2217
+ background: var(--c-bg);
2218
+ box-shadow: 0 0 24px -6px oklch(0.7 0.15 280 / 0.5);
2219
+ animation: aiIn 0.25s ease-out;
2220
+ }
2221
+
2222
+ .pill .ring {
2223
+ border-radius: 999px;
2224
+ animation-duration: 2.4s;
2225
+ }
2226
+
2227
+ .pill .dot {
2228
+ width: 9px;
2229
+ height: 9px;
2230
+ border-radius: 50%;
2231
+ background: var(--c-conic);
2232
+ animation:
2233
+ aiSpin 1.6s linear infinite,
2234
+ aiPulse 1.6s ease-in-out infinite;
2235
+ }
2236
+
2237
+ .pill .shimmer {
2238
+ font-size: 12.5px;
2239
+ font-weight: 500;
2240
+ background: linear-gradient(90deg, var(--c-faint) 0%, var(--c-ink) 45%, var(--c-faint) 90%);
2241
+ background-size: 200% 100%;
2242
+ -webkit-background-clip: text;
2243
+ background-clip: text;
2244
+ color: transparent;
2245
+ animation: aiShimmer 1.8s linear infinite;
2246
+ }
2247
+
2248
+ .composer-glow {
2249
+ position: absolute;
2250
+ inset: -4px;
2251
+ z-index: 0;
2252
+ border-radius: var(--c-r4);
2253
+ background: var(--c-conic);
2254
+ filter: blur(14px);
2255
+ opacity: calc(0.32 + 0.23 * (var(--c-glow) - 0.6) / 0.4);
2256
+ animation: aiSpin 4s linear infinite;
2257
+ pointer-events: none;
2258
+ }
2259
+
2260
+ .composer-ring {
2261
+ position: absolute;
2262
+ inset: 0;
2263
+ z-index: 2;
2264
+ border-radius: calc(var(--c-r) * 2.25);
2265
+ pointer-events: none;
2266
+ }
2267
+
2268
+ .composer-ring .ring {
2269
+ animation-duration: 3s;
2270
+ }
2271
+
2272
+ :host([glow="off"]) .halo,
2273
+ :host([glow="off"]) .arrived,
2274
+ :host([glow="off"]) .composer-glow,
2275
+ :host([glow="off"]) .composer-ring,
2276
+ :host([glow="off"]) .pill .ring {
2277
+ display: none;
2278
+ }
2279
+
2280
+ :host([glow="off"]) .pill {
2281
+ box-shadow: inset 0 0 0 1px var(--c-line);
2282
+ }
2283
+
2284
+ :host([glow="off"]) .pill .dot {
2285
+ background: var(--c-ink);
2286
+ }
2287
+
2288
+ @keyframes aiSpin {
2289
+ to {
2290
+ --sb-ai-angle: 360deg;
2291
+ }
2292
+ }
2293
+
2294
+ @keyframes aiShimmer {
2295
+ from {
2296
+ background-position: 200% 0;
2297
+ }
2298
+ to {
2299
+ background-position: -200% 0;
2300
+ }
2301
+ }
2302
+
2303
+ @keyframes aiBreathe {
2304
+ 0%,
2305
+ 100% {
2306
+ transform: scale(0.97);
2307
+ }
2308
+ 50% {
2309
+ transform: scale(1.03);
2310
+ }
2311
+ }
2312
+
2313
+ @keyframes aiPulse {
2314
+ 0%,
2315
+ 100% {
2316
+ transform: scale(0.8);
2317
+ }
2318
+ 50% {
2319
+ transform: scale(1.15);
2320
+ }
2321
+ }
2322
+
2323
+ @keyframes aiDone {
2324
+ 0% {
2325
+ opacity: 0;
2326
+ }
2327
+ 12% {
2328
+ opacity: 1;
2329
+ }
2330
+ 100% {
2331
+ opacity: 0;
2332
+ }
2333
+ }
2334
+
2335
+ @keyframes aiSweep {
2336
+ from {
2337
+ transform: translateX(-100%);
2338
+ }
2339
+ to {
2340
+ transform: translateX(100%);
2341
+ }
2342
+ }
2343
+
2344
+ @keyframes aiIn {
2345
+ from {
2346
+ opacity: 0;
2347
+ transform: translateY(4px);
2348
+ }
2349
+ to {
2350
+ opacity: 1;
2351
+ transform: none;
2352
+ }
2353
+ }
2354
+
2355
+ @keyframes scaleIn {
2356
+ from {
2357
+ opacity: 0;
2358
+ transform: translateY(12px) scale(0.98);
2359
+ }
2360
+ to {
2361
+ opacity: 1;
2362
+ transform: none;
2363
+ }
2364
+ }
2365
+
2366
+ @keyframes slideIn {
2367
+ from {
2368
+ opacity: 0;
2369
+ transform: translateX(-8px);
2370
+ }
2371
+ to {
2372
+ opacity: 1;
2373
+ transform: none;
2374
+ }
2375
+ }
2376
+
2377
+ @keyframes aiGrow {
2378
+ from {
2379
+ transform: scaleX(0);
2380
+ }
2381
+ }
2382
+
2383
+ @keyframes aiDraw {
2384
+ from {
2385
+ stroke-dashoffset: 1;
2386
+ }
2387
+ to {
2388
+ stroke-dashoffset: 0;
2389
+ }
2390
+ }
2391
+
2392
+ @keyframes rgcaret {
2393
+ 0%,
2394
+ 100% {
2395
+ opacity: 1;
2396
+ }
2397
+ 50% {
2398
+ opacity: 0;
2399
+ }
2400
+ }
2401
+
2402
+ @media (prefers-reduced-motion: reduce) {
2403
+ *,
2404
+ *::before,
2405
+ *::after {
2406
+ animation-duration: 0.01ms !important;
2407
+ animation-iteration-count: 1 !important;
2408
+ }
2409
+ .caret {
2410
+ display: none;
2411
+ }
2412
+ }
2413
+
2414
+ @media print {
2415
+ .sidebar,
2416
+ .scrim,
2417
+ .header-right,
2418
+ .composer-wrap,
2419
+ .branding,
2420
+ .toolbar,
2421
+ .followups,
2422
+ .panel,
2423
+ .toast {
2424
+ display: none !important;
2425
+ }
2426
+ .frame,
2427
+ .scroller {
2428
+ overflow: visible;
2429
+ height: auto;
2430
+ }
2431
+ }
2432
+ `,Nt={eyebrowChat:"Chat",eyebrowRag:"Grounded answers",headingChat:"What can I help with?",headingRag:"Ask your knowledge base",descriptionChat:"Ask anything. Attach text files to give it more context.",descriptionRag:"Answers are grounded in your sources, with a citation for every claim. Attach text files to search them too.",placeholderChat:"Message {name}…",placeholderRag:"Ask about your sources…",footnote:"{name} can make mistakes. Check important details.",attach:"Attach files",send:"Send message",stop:"Stop generating",removeFile:"Remove file",dropTitle:"Drop files to attach",dropSub:"Text, Markdown, CSV and JSON files are added as context.",thinking:"Thinking",searching:"Searching sources",chats:"Chats",newChat:"New chat",searchChats:"Search chats",groupBookmarked:"Bookmarked",groupToday:"Today",groupYesterday:"Yesterday",groupWeek:"Previous 7 days",groupOlder:"Older",noChats:"No chats yet.",noMatch:"No chats match “{query}”.",loadingChats:"Loading chats",showChats:"Show chats",hideSidebar:"Hide sidebar",untitled:"New chat",renameChat:"Rename chat",bookmarkChat:"Bookmark chat",unbookmarkChat:"Remove chat bookmark",exportChat:"Export chat",deleteChat:"Delete chat",expand:"Expand",restore:"Restore size",minimize:"Minimize chat",exportHeading:"Export this chat",exportMarkdown:"Markdown",exportJson:"JSON",exportText:"Plain text",exportCopy:"Copy as Markdown",copy:"Copy",copied:"Copied",edit:"Edit and resend",saveResend:"Save & resend",cancel:"Cancel",regenerate:"Regenerate",helpful:"Helpful",notHelpful:"Not helpful",markedHelpful:"Marked helpful",thanksFeedback:"Thanks for the feedback",bookmarkMessage:"Bookmark message",unbookmarkMessage:"Remove bookmark",deleteMessage:"Delete message",saved:"Saved",stopped:"Stopped",emptyReply:"(empty response)",newReply:"New reply",you:"You",sourcesCited:"Cited sources",sourcesRetrieved:"Sources",searchedSources:"Searched {n} sources",sourceLabel:"Source {n}",openSource:"Open source {n}",citedPassage:"Cited passage",copyReference:"Copy passage with reference",alsoCited:"Also cited",close:"Close",renderingChart:"Rendering chart",renderingSvg:"Rendering drawing",copySvg:"Copy SVG",showRaw:"View raw",showFormatted:"View formatted",showingRows:"Showing {n} of {total} rows",calloutNote:"Note",calloutTip:"Tip",calloutImportant:"Important",calloutWarning:"Warning",calloutCaution:"Caution",undo:"Undo",chatDeleted:"Chat deleted",messageDeleted:"Message deleted",messageBookmarked:"Message bookmarked",bookmarkRemoved:"Bookmark removed",chatBookmarked:"Chat bookmarked",chatUnbookmarked:"Chat removed from bookmarks",exported:"Exported {name}",copiedMarkdown:"Copied as Markdown",fileTooLarge:"{name} is larger than {size}.",fileType:"{name} isn't a text file.",tooManyFiles:"Attach up to {n} files at a time.",errGeneric:"Something went wrong.",errNotFound:"This chat no longer exists. Retry to start a new one.",errNoClient:"Chat isn't connected. Create a SinglebaseClient() on this page.",errLoad:"Couldn't load this chat.",retry:"Retry",offline:"You're offline. Messages will send when you reconnect.",bubbleText:"Hi! Questions? Ask me here.",openChat:"Open chat",closeChat:"Close chat",dismiss:"Dismiss",brandingLabel:"Chat by Singlebase"};function At(l){return{...Nt,...l??{}}}const Gt=/^\|.*\|$/,xt=/^\|[\s:|-]+\|$/,vt=/^!\[([^\]]*)\]\(([^)]*)\)$/,yt=/^(\s*)([-*+]|\d+[.)])\s+(.*)$/,wt=/^\[( |x|X)\]\s+/,Vt=/^(-{3,}|\*{3,}|_{3,})$/,Xt=/^\[!(NOTE|TIP|IMPORTANT|WARNING|CAUTION)\]\s*(.*)$/i,Yt=["note","tip","important","warning","caution"];function Rt(l){const o=[],e=(l??"").replace(/\r/g,"").split("```");return e.forEach((t,i)=>{if(i%2===1){const a=t.indexOf(`
2433
+ `),r=(a>-1?t.slice(0,a):t).trim(),n=(a>-1?t.slice(a+1):"").replace(/\n$/,"");o.push(Qt(r,n,i===e.length-1));return}for(const a of t.split(/\n{2,}/))a.trim()&&o.push(...Et(a))}),o}function Qt(l,o,e){const[t="",...i]=l.split(/\s+/),a=t.toLowerCase();if(a==="chart"){const r=e?null:ei(o);return r?{type:"chart",spec:r}:{type:"pending",kind:"chart"}}if(a==="svg")return e||!/<svg[\s>]/i.test(o)?{type:"pending",kind:"svg"}:{type:"svg",source:o.trim()};if(!e&&(a==="csv"||a==="tsv")){const r=Zt(o,a==="tsv"?" ":",");if(r.length>1)return{type:"table",head:r[0],rows:r.slice(1),align:r[0].map(()=>null)}}if(!e&&a==="json")try{return{type:"json",value:JSON.parse(o),source:o}}catch{}if(a==="callout"){const r=(i[0]??"").toLowerCase(),n=Yt.includes(r);return{type:"callout",kind:n?r:"note",title:(n?i.slice(1):i).join(" "),text:o.trim()}}return{type:"code",lang:a||"code",text:o}}function Et(l){const o=l.split(`
2434
+ `).filter(i=>i.trim()),e=o.map(i=>i.trim());if(e.length>1&&e.every(i=>Gt.test(i))){const i=c=>c.replace(/^\||\|$/g,"").split("|").map(b=>b.trim()),a=e.findIndex(c=>xt.test(c)),r=a>-1?i(e[a]).map(c=>/^:-+:$/.test(c)?"center":/^-+:$/.test(c)?"right":/^:-+$/.test(c)?"left":null):[],n=e.filter(c=>!xt.test(c)).map(i),d=n[0]??[];return[{type:"table",head:d,rows:n.slice(1),align:d.map((c,b)=>r[b]??null)}]}if(e.length===1&&Vt.test(e[0]))return[{type:"hr"}];if(e.every(i=>vt.test(i)))return[{type:"img",images:e.map(i=>{const a=i.match(vt);return{alt:a[1],src:a[2]}})}];if(e.every(i=>i.startsWith(">"))){const i=e.map(r=>r.replace(/^>\s?/,"")),a=i[0].match(Xt);return a?[{type:"callout",kind:a[1].toLowerCase(),title:a[2].trim(),text:i.slice(1).join(`
2435
+ `).trim()}]:[{type:"quote",text:i.join(" ")}]}if(yt.test(o[0])){const i=[];for(const a of o){const r=a.match(yt);if(r){const n=r[3].match(wt);i.push({text:n?r[3].replace(wt,""):r[3],depth:Math.min(3,Math.floor(r[1].replace(/\t/g," ").length/2)),checked:n?n[1]!==" ":null})}else i[i.length-1].text+=` ${a.trim()}`}return[{type:"list",ordered:/^\s*\d/.test(o[0]),items:i}]}const t=e[0].match(/^(#{1,4})\s+(.*)$/);if(t){const i=o.slice(1).join(`
2436
+ `);return[{type:"h",level:t[1].length,text:t[2]},...i?Et(i):[]]}return[{type:"p",text:e.join(" ")}]}function Zt(l,o=","){var d;const e=[];let t=[],i="",a=!1;const r=l.replace(/\r/g,"");for(let c=0;c<r.length;c++){const b=r[c];a?b==='"'&&r[c+1]==='"'?(i+='"',c++):b==='"'?a=!1:i+=b:b==='"'&&i===""?a=!0:b===o?(t.push(i.trim()),i=""):b===`
2437
+ `?(t.push(i.trim()),t.some(Boolean)&&e.push(t),t=[],i=""):i+=b}t.push(i.trim()),t.some(Boolean)&&e.push(t);const n=((d=e[0])==null?void 0:d.length)??0;return e.map(c=>c.length<n?[...c,...Array(n-c.length).fill("")]:c)}function ei(l){let o;try{o=JSON.parse(l)}catch{return null}if(!o||typeof o!="object")return null;const e=(Array.isArray(o.series)?o.series:[]).filter(i=>i&&Array.isArray(i.values)).map((i,a)=>({name:String(i.name??`Series ${a+1}`),values:i.values.map(r=>Number(r)||0)}));if(!e.length)return null;const t=Array.isArray(o.labels)?o.labels.map(String):e[0].values.map((i,a)=>String(a+1));return{type:o.type==="line"?"line":"bar",title:String(o.title??""),unit:String(o.unit??""),labels:t,series:e}}const kt=new RegExp([/\*\*([^*]+)\*\*/.source,/~~([^~]+)~~/.source,/`([^`]+)`/.source,/\[([^\]]+)\]\((https?:\/\/[^)\s]+)\)/.source,/(https?:\/\/[^\s<>()]*[^\s<>().,;:!?'"\]])/.source,new RegExp("(?<![\\w*])\\*(?![\\s*])([^*\\n]+?)\\*(?![\\w*])").source,new RegExp("(?<![\\w_])_(?![\\s_])([^_\\n]+?)_(?![\\w_])").source,/\s?\[(\d+(?:\s*,\s*\d+)*)\]/.source].join("|"),"g");function Bt(l,o=0){const e=[];let t=0,i;kt.lastIndex=0;const a=r=>{if(!r)return;const n=e[e.length-1];(n==null?void 0:n.type)==="text"?n.text+=r:e.push({type:"text",text:r})};for(;i=kt.exec(l);){if(a(l.slice(t,i.index)),i[1]!==void 0)e.push({type:"bold",text:i[1]});else if(i[2]!==void 0)e.push({type:"strike",text:i[2]});else if(i[3]!==void 0)e.push({type:"code",text:i[3]});else if(i[4]!==void 0)e.push({type:"link",text:i[4],href:i[5]});else if(i[6]!==void 0)e.push({type:"link",text:i[6],href:i[6]});else if(i[7]!==void 0)e.push({type:"italic",text:i[7]});else if(i[8]!==void 0)e.push({type:"italic",text:i[8]});else{const n=i[9].split(",").map(d=>Number(d.trim())).filter(d=>d>=1&&d<=o);o?n.forEach(d=>e.push({type:"cite",n:d})):a(i[0])}t=i.index+i[0].length}return a(l.slice(t)),e}function Dt(l){if(((l??"").match(/```/g)??[]).length%2===1)return l;const o=l.lastIndexOf(`
2438
+
2439
+ `),e=o>-1?l.slice(0,o+2):"";let t=o>-1?l.slice(o+2):l;const i=t.split(`
2440
+ `),a=i[i.length-1];a.trimStart().startsWith("|")&&!a.trimEnd().endsWith("|")&&i.pop(),t=i.join(`
2441
+ `),t=t.replace(/!?\[[^\]\n]*(\]\([^)\n]*)?$/,"");for(const r of["**","~~","`"])if((t.split(r).length-1)%2===1){const d=t.lastIndexOf(r);t=t.slice(0,d)+t.slice(d+r.length)}return e+t}function ut(l){const o=new Set;for(const e of(l??"").match(/\[(\d+(?:\s*,\s*\d+)*)\]/g)??[])e.replace(/[[\]]/g,"").split(",").forEach(t=>o.add(Number(t.trim())));return o}function ti(l){return[["",...l.series.map(o=>o.name)],...l.labels.map((o,e)=>[o,...l.series.map(t=>t.values[e]===void 0?"":`${t.values[e]}${l.unit}`)])]}const $t=l=>l.map(o=>o.join(" · ")).join(`
2442
+ `),ii={note:"Note",tip:"Tip",important:"Important",warning:"Warning",caution:"Caution"};function Ft(l,o){if(o==="rich")return l;const e=o==="plain";return l.map(t=>{switch(t.type){case"chart":{const[i,...a]=ti(t.spec);return e?{type:"raw",text:[t.spec.title,$t([i,...a])].filter(Boolean).join(`
2443
+ `)}:{type:"table",head:t.spec.title?[t.spec.title,...i.slice(1)]:i,rows:a,align:i.map(()=>null)}}case"pending":return t.kind==="svg"&&!e?t:{type:"raw",text:""};case"callout":return{type:"quote",text:`**${t.title||ii[t.kind]}** ${t.text}`.trim()};case"img":return{type:"p",text:t.images.map(i=>`Image: ${i.alt||"untitled"}`).join(" · ")};case"table":return e?{type:"raw",text:$t([t.head,...t.rows])}:t;case"json":return e?{type:"code",lang:"json",text:t.source}:t;case"svg":return e?{type:"code",lang:"svg",text:t.source}:t;default:return t}})}function gt(l){const o=l??"",e=o.search(/FOLLOWUPS:/i);if(e<0)return{text:o.trim(),followups:[]};const i=o.slice(e).replace(/^FOLLOWUPS:/i,"").split(/\||\n/).map(a=>a.replace(/^\s*(?:[-*↳→]|\d+[.)])\s*/,"").trim()).filter(Boolean).slice(0,3);return{text:o.slice(0,e).trim(),followups:i}}function si(l){return(l??"").replace(/```(\w*)[\s\S]*?(```|$)/g,(o,e)=>e==="chart"?"[Chart] ":e==="svg"?"[Drawing] ":"[Code] ").replace(/!\[([^\]]*)\]\([^)]*\)/g,"[Image: $1]").replace(/\[([^\]]+)\]\((https?:\/\/[^)\s]+)\)/g,"$1").replace(/\[!(NOTE|TIP|IMPORTANT|WARNING|CAUTION)\]/gi,"").replace(/[*#>`~]/g,"").replace(/\|/g," ").replace(/\s?\[\d+(?:\s*,\s*\d+)*\]/g,"").replace(/\s+/g," ").trim()}function ai(l,o=48){const e=si(l);if(e.length<=o)return e;const t=e.slice(0,o),i=t.lastIndexOf(" ");return(i>o/2?t.slice(0,i):t).trim()}function ri(l){return String(l??"").split(`
2444
+ `)[0].trim().replace(/^["'“”‘’]+|["'“”‘’]+$/g,"").replace(/^title:\s*/i,"").replace(/[.!?:;,]+$/,"").trim().slice(0,80)}function Ct(l,o=!1){return/^https?:\/\//i.test(l)?!0:o&&/^(blob:|data:image\/)/i.test(l)}const ni=2e5,oi=new Set(["script","foreignobject","iframe","object","embed","image","audio","video","animate","set","animatemotion","animatetransform","handler","listener"]);function Ut(l){if(!l||l.length>ni||typeof DOMParser>"u")return null;const o=new DOMParser().parseFromString(l,"image/svg+xml"),e=o.documentElement;if(!e||e.nodeName.toLowerCase()!=="svg"||o.querySelector("parsererror"))return null;const t=a=>{for(const r of Array.from(a.children)){const n=r.nodeName.toLowerCase();if(oi.has(n))r.remove();else if(n==="a"){const d=Array.from(r.childNodes);r.replaceWith(...d),d.forEach(c=>c instanceof Element&&t(c))}else t(r)}for(const r of Array.from(a.attributes)){const n=r.name.toLowerCase(),d=r.value.trim().toLowerCase(),c=(n==="href"||n.endsWith(":href"))&&!d.startsWith("#"),b=d.includes("javascript:")||/url\(\s*['"]?(?!#)/.test(d);(n.startsWith("on")||c||b)&&a.removeAttribute(r.name)}};t(e);for(const a of Array.from(e.querySelectorAll("style")))a.textContent=(a.textContent??"").replace(/@import[^;]*;?/gi,"").replace(/url\(\s*['"]?(?!#)[^)]*\)/gi,"none");e.setAttribute("xmlns","http://www.w3.org/2000/svg");const i=new XMLSerializer().serializeToString(e);return`data:image/svg+xml;charset=utf-8,${encodeURIComponent(i)}`}var Pt=Object.defineProperty,li=Object.getOwnPropertyDescriptor,ci=(l,o,e)=>o in l?Pt(l,o,{enumerable:!0,configurable:!0,writable:!0,value:e}):l[o]=e,m=(l,o,e,t)=>{for(var i=t>1?void 0:t?li(o,e):o,a=l.length-1,r;a>=0;a--)(r=l[a])&&(i=(t?r(o,e,i):r(i))||i);return t&&i&&Pt(o,e,i),i},di=(l,o,e)=>ci(l,o+"",e);const St=["embed","mode","format","renderers","beforeSend","afterParse","glow","position","sidebar","showTitle","assistantName","logoUrl","heading","description","eyebrow","prompts","bubbleText","greetingBubble","unreadBadge","allowUpload","allowExport","allowRaw","allowCopy","allowRegenerate","allowBookmark","allowDelete","allowRename","allowFeedback","showTime","showComposer","footnote","brandingText","brandingUrl","branding","followups","showFollowups","showSources","showNewChat","showBookmarked","allowSearch","autoTitle","model","params","systemMessage","retrieval","metadata","messages","theme","radius"],mt={fromAttribute:l=>{if(l)try{return JSON.parse(l)}catch{console.warn("[singlebase-chat] an attribute holds invalid JSON; ignoring it");return}},toAttribute:l=>JSON.stringify(l??null)},S={fromAttribute:l=>l===null?!0:l!=="false",toAttribute:l=>l?null:"false"},hi={fromAttribute:l=>l===null?"auto":l===""||l==="true"?"open":l==="false"?"closed":["auto","open","closed","none"].includes(l)?l:"auto",toAttribute:l=>l==="auto"?null:l},pi=272,ui=820,gi=940,Tt=5,Ot=512*1024,mi=/\.(md|markdown|txt|csv|tsv|json|html?|ya?ml|xml|log)$/i,bi=5e3,fi=200,It=2e3,xi={note:"calloutNote",tip:"calloutTip",important:"calloutImportant",warning:"calloutWarning",caution:"calloutCaution"},vi=2600,_=["var(--c-ink)","oklch(0.58 0.13 255)","oklch(0.63 0.1 175)","oklch(0.74 0.12 70)"],Mt={chat:"Be helpful and concise. Use Markdown when it helps: headings, lists, **bold**, code blocks and tables.",rag:"Answer ONLY from the sources provided with each message, numbered in the order given. Put a citation like [1] right after each claim it supports. If the sources don't cover the question, say so plainly."},yi={raw:"Reply in plain text. Don't use Markdown or any other markup.",plain:"Format with light Markdown only: short paragraphs, lists, **bold**, *italics*, `inline code`, code blocks and links. Don't use tables, charts, callouts, images or other special blocks.",advanced:`You can use Markdown: headings, lists, task lists, **bold**, *italics*, links, code blocks and pipe tables. For data, use a fenced "csv" block or a fenced "json" block. For a diagram or illustration, write a self-contained fenced "svg" block with a viewBox, and no scripts, links or external images. Don't use charts, callouts or images.`,rich:'When the answer is about data, lead with one sentence stating the key finding, with key numbers in **bold**, then show the data visually. You can use Markdown: headings, lists, task lists, **bold**, *italics*, links, code blocks and pipe tables. For data, use a fenced "csv" block or a fenced "json" block. For a diagram or illustration, write a self-contained fenced "svg" block with a viewBox, and no scripts, links or external images. For trends and comparisons, use a fenced "chart" block containing only JSON: {"type":"bar"|"line","title":string,"unit":string,"labels":[string],"series":[{"name":string,"values":[number]}]}. For notes and warnings, use callouts: a quote starting with [!NOTE], [!TIP], [!IMPORTANT], [!WARNING] or [!CAUTION]. Images use ![alt](https://…).'},wi="After the answer, on a final line write FOLLOWUPS: followed by three short follow-up questions the user might ask next, separated by |.",zt={chat:[["Write","Draft a short welcome email for new users"],["Explain","Explain how refresh tokens work, simply"],["Code","Write a JavaScript debounce function"],["Plan","Outline a one-week plan to learn TypeScript"]],rag:[["Overview","What topics do these sources cover?"],["Summarize","Summarize the most important points"],["Find","Where is the refund policy described?"],["Explain","Explain the setup steps in plain language"]]},I=(l,o="")=>s.html`<svg class="i ${o}" viewBox="0 0 16 16" aria-hidden="true">${l}</svg>`,y={sidebar:()=>I(s.svg`<rect x="2" y="2.5" width="12" height="11" rx="1.5"></rect><path d="M6 2.5v11"></path>`),plus:()=>I(s.svg`<path d="M8 3v10M3 8h10"></path>`),bookmark:(l=!1)=>I(s.svg`<path d="M4.5 2.5h7v11L8 11l-3.5 2.5z"></path>`,l?"filled":""),download:()=>I(s.svg`<path d="M8 2.5v8M4.5 7.5L8 11l3.5-3.5M2.5 13.5h11"></path>`),trash:()=>I(s.svg`<path d="M2.5 4.5h11M6.5 4.5v-2h3v2M4 4.5l.7 9h6.6l.7-9"></path>`),pencil:()=>I(s.svg`<path d="M10.5 2.5l3 3L6 13H3v-3z"></path>`),copy:()=>I(s.svg`<rect x="5.5" y="5.5" width="8" height="8" rx="1.5"></rect><path d="M10.5 5.5v-2a1 1 0 0 0-1-1h-6a1 1 0 0 0-1 1v6a1 1 0 0 0 1 1h2"></path>`),raw:()=>I(s.svg`<path d="M5.5 4.5L2 8l3.5 3.5M10.5 4.5L14 8l-3.5 3.5"></path>`),refresh:()=>I(s.svg`<path d="M13.5 8A5.5 5.5 0 1 1 11.9 4.1M13.5 2v3.5H10"></path>`),thumb:(l=!1)=>s.html`<svg
2445
+ class="i"
2446
+ viewBox="0 0 16 16"
2447
+ aria-hidden="true"
2448
+ style=${l?"transform:rotate(180deg)":""}
2449
+ >
2450
+ <path
2451
+ d="M5 7v6.5H2.5V7zM5 7l2.5-4.5a1.3 1.3 0 0 1 1.9 1.4L9 6.5h3.6a1 1 0 0 1 1 1.2l-1 4.8a1 1 0 0 1-1 .8H5"
2452
+ ></path>
2453
+ </svg>`,expand:()=>I(s.svg`<path d="M9.5 2.5h4v4M13.5 2.5L9 7M6.5 13.5h-4v-4M2.5 13.5L7 9"></path>`),restore:()=>I(s.svg`<path d="M13.5 6.5h-4v-4M9.5 6.5l4-4M2.5 9.5h4v4M6.5 9.5l-4 4"></path>`),minimize:()=>I(s.svg`<path d="M4 8h8"></path>`),close:()=>I(s.svg`<path d="M4 4l8 8M12 4l-8 8"></path>`),clip:()=>I(s.svg`<path d="M13 7.5l-5.3 5.3a3 3 0 0 1-4.3-4.3L9 2.9a2 2 0 0 1 2.9 2.9L6.4 11.3a1 1 0 0 1-1.4-1.4L10 5"></path>`),up:()=>I(s.svg`<path d="M8 13V3M3.5 7.5L8 3l4.5 4.5"></path>`),stop:()=>I(s.svg`<rect x="4.5" y="4.5" width="7" height="7" rx="1"></rect>`),chat:()=>s.html`<svg
2454
+ width="22"
2455
+ height="22"
2456
+ viewBox="0 0 22 22"
2457
+ aria-hidden="true"
2458
+ style="fill:none;stroke:currentColor;stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round"
2459
+ >
2460
+ <path
2461
+ d="M4 5.5A2.5 2.5 0 0 1 6.5 3h9A2.5 2.5 0 0 1 18 5.5v7a2.5 2.5 0 0 1-2.5 2.5H9l-4 3.5V15H6.5"
2462
+ ></path>
2463
+ </svg>`,chevronDown:()=>s.html`<svg
2464
+ width="20"
2465
+ height="20"
2466
+ viewBox="0 0 20 20"
2467
+ aria-hidden="true"
2468
+ style="fill:none;stroke:currentColor;stroke-width:1.6;stroke-linecap:round"
2469
+ >
2470
+ <path d="M5 8l5 5 5-5"></path>
2471
+ </svg>`};let ki=0;const pt=()=>`m${Date.now().toString(36)}${(ki++).toString(36)}`;function _t(l){var e;const o=l;return(o==null?void 0:o.message)==="NOT_FOUND"||(o==null?void 0:o.code)==="NOT_FOUND"||((e=o==null?void 0:o.details)==null?void 0:e.status)===404}function $i(l){const o=l;return(o==null?void 0:o.code)||(o==null?void 0:o.message)||"UNKNOWN"}const Ci=()=>typeof matchMedia<"u"&&matchMedia("(prefers-reduced-motion: reduce)").matches,ht=(l,o)=>(Number.isInteger(l)?l.toLocaleString("en-US"):l.toFixed(1))+o,Lt=l=>{const o=l.lastIndexOf(".");return o>0?l.slice(o+1,o+5).toUpperCase():"FILE"};function L(l,o){const e=l??{},t=e.metadata&&typeof e.metadata=="object"?e.metadata:{},i=(...n)=>n.find(d=>typeof d=="string"&&d.trim()),a=i(e.content,e.text,e.page_content,e.body,e.snippet,e.chunk,t.content)??JSON.stringify(e,null,2),r=[e.score,e.relevance,e._score,t.score].find(n=>typeof n=="number");return{n:o,title:i(e.title,e.name,e.filename,t.title,t.name)??`Source ${o}`,path:i(e.path,e.url,e.key,e.source,t.path,t.url)??"",collection:i(e.collection,e.namespace,e.dbname,t.collection)??"",updated:i(e.updated,e._modified_at,t.updated)??"",text:a,score:r===void 0?null:Math.max(0,Math.min(1,r))}}function Si(l){const o=[],e=[];for(const t of l)if(/\.csv$/i.test(t.name))o.push({type:"csv",data:t.content});else if(/\.json$/i.test(t.name))try{o.push({type:"json",data:JSON.parse(t.content)})}catch{e.push({title:t.name,content:t.content})}else e.push({title:t.name,content:t.content});return e.length&&o.push({type:"docs",payload:{documents:e}}),o}function Ti(l){const o=l?Date.parse(l):NaN;if(Number.isNaN(o))return"older";const e=new Date;e.setHours(0,0,0,0);const t=864e5;return o>=e.getTime()?"today":o>=e.getTime()-t?"yesterday":o>=e.getTime()-7*t?"week":"older"}var j,N,A,R,E,B,D,F,U,P,K,W,J,H,q,G,V,X,Y,Q,Z,ee,te,ie,se,ae,re,ne,oe,le,ce,de,he,pe,ue,ge,me,be,fe,xe,ve,ye,we,ke,$e,Ce,Se,Te,Oe,Ie,Me,ze,_e,Le,je,Ne,Ae,Re,Ee,Be,De,Fe,Ue,Pe,Ke,We,Je,He,qe,Ge,Ve,Xe,Ye,Qe,Ze,et,tt,it,st,at,rt,nt,ot,lt,ct,dt,jt;exports.SinglebaseChat=(jt=class extends s.LitElement{constructor(){super(...arguments);p(this,j,null);p(this,N,{});p(this,A);p(this,R);p(this,E,"chat");p(this,B,"advanced");p(this,D,{});p(this,F,null);p(this,U,null);p(this,P,"subtle");p(this,K,!0);p(this,W,!0);p(this,J,!0);p(this,H,!0);p(this,q,!0);p(this,G,!0);p(this,V,!0);p(this,X,"");p(this,Y,{});p(this,Q,"");p(this,Z,[]);p(this,ee,{});p(this,te,"page");p(this,ie,"right");p(this,se,"auto");p(this,ae,!0);p(this,re,"");p(this,ne,"Assistant");p(this,oe,"");p(this,le,"");p(this,ce,"");p(this,de);p(this,he,"");p(this,pe,"");p(this,ue,!1);p(this,ge,!1);p(this,me,!0);p(this,be,!0);p(this,fe,!0);p(this,xe,!0);p(this,ve,!0);p(this,ye,!0);p(this,we,!0);p(this,ke,!0);p(this,$e,!0);p(this,Ce,!0);p(this,Se);p(this,Te,!1);p(this,Oe,!0);p(this,Ie,"");p(this,Me,"");p(this,ze,[]);p(this,_e,"idle");p(this,Le,null);p(this,je,"");p(this,Ne,!1);p(this,Ae,[]);p(this,Re,!1);p(this,Ee,"");p(this,Be,!1);p(this,De,"");p(this,Fe,[]);p(this,Ue,"");p(this,Pe,null);p(this,Ke,0);p(this,We,null);p(this,Je,!1);p(this,He,"");p(this,qe,"");p(this,Ge,!1);p(this,Ve,"");p(this,Xe,null);p(this,Ye,"");p(this,Qe,new Set);p(this,Ze,new Set);p(this,et,!1);p(this,tt,new Map);p(this,it,"");p(this,st,!1);p(this,at,!1);p(this,rt,!1);p(this,nt,!1);p(this,ot,!1);p(this,lt,!1);p(this,ct,!1);p(this,dt,!1);O(this,"run",0);O(this,"abort",null);O(this,"revealTimer");O(this,"timers",new Set);O(this,"toastTimer");O(this,"stick",!0);O(this,"renamed",new Set);O(this,"observer",null);O(this,"observed",null);O(this,"media",null);O(this,"focusNext","");O(this,"bubbleScheduled",!1);O(this,"pendingChatId","");O(this,"onNetwork",()=>{this.offline=navigator.onLine===!1});O(this,"onMedia",()=>{var e;this.mobile=!!((e=this.media)!=null&&e.matches)})}get client(){return h(this,j)}set client(e){u(this,j,e)}get messages(){return h(this,N)}set messages(e){u(this,N,e)}get theme(){return h(this,A)}set theme(e){u(this,A,e)}get radius(){return h(this,R)}set radius(e){u(this,R,e)}get mode(){return h(this,E)}set mode(e){u(this,E,e)}get format(){return h(this,B)}set format(e){u(this,B,e)}get renderers(){return h(this,D)}set renderers(e){u(this,D,e)}get beforeSend(){return h(this,F)}set beforeSend(e){u(this,F,e)}get afterParse(){return h(this,U)}set afterParse(e){u(this,U,e)}get glow(){return h(this,P)}set glow(e){u(this,P,e)}get followups(){return h(this,K)}set followups(e){u(this,K,e)}get showSources(){return h(this,W)}set showSources(e){u(this,W,e)}get showNewChat(){return h(this,J)}set showNewChat(e){u(this,J,e)}get showBookmarked(){return h(this,H)}set showBookmarked(e){u(this,H,e)}get showFollowups(){return h(this,q)}set showFollowups(e){u(this,q,e)}get allowSearch(){return h(this,G)}set allowSearch(e){u(this,G,e)}get autoTitle(){return h(this,V)}set autoTitle(e){u(this,V,e)}get model(){return h(this,X)}set model(e){u(this,X,e)}get params(){return h(this,Y)}set params(e){u(this,Y,e)}get systemMessage(){return h(this,Q)}set systemMessage(e){u(this,Q,e)}get retrieval(){return h(this,Z)}set retrieval(e){u(this,Z,e)}get metadata(){return h(this,ee)}set metadata(e){u(this,ee,e)}get embed(){return h(this,te)}set embed(e){u(this,te,e)}get position(){return h(this,ie)}set position(e){u(this,ie,e)}get sidebar(){return h(this,se)}set sidebar(e){u(this,se,e)}get showTitle(){return h(this,ae)}set showTitle(e){u(this,ae,e)}get chatIdAttr(){return h(this,re)}set chatIdAttr(e){u(this,re,e)}get assistantName(){return h(this,ne)}set assistantName(e){u(this,ne,e)}get logoUrl(){return h(this,oe)}set logoUrl(e){u(this,oe,e)}get heading(){return h(this,le)}set heading(e){u(this,le,e)}get description(){return h(this,ce)}set description(e){u(this,ce,e)}get eyebrow(){return h(this,de)}set eyebrow(e){u(this,de,e)}get prompts(){return h(this,he)}set prompts(e){u(this,he,e)}get bubbleText(){return h(this,pe)}set bubbleText(e){u(this,pe,e)}get greetingBubble(){return h(this,ue)}set greetingBubble(e){u(this,ue,e)}get unreadBadge(){return h(this,ge)}set unreadBadge(e){u(this,ge,e)}get allowUpload(){return h(this,me)}set allowUpload(e){u(this,me,e)}get allowExport(){return h(this,be)}set allowExport(e){u(this,be,e)}get allowCopy(){return h(this,fe)}set allowCopy(e){u(this,fe,e)}get allowRegenerate(){return h(this,xe)}set allowRegenerate(e){u(this,xe,e)}get allowBookmark(){return h(this,ve)}set allowBookmark(e){u(this,ve,e)}get allowDelete(){return h(this,ye)}set allowDelete(e){u(this,ye,e)}get allowRename(){return h(this,we)}set allowRename(e){u(this,we,e)}get allowFeedback(){return h(this,ke)}set allowFeedback(e){u(this,ke,e)}get showComposer(){return h(this,$e)}set showComposer(e){u(this,$e,e)}get showTime(){return h(this,Ce)}set showTime(e){u(this,Ce,e)}get footnote(){return h(this,Se)}set footnote(e){u(this,Se,e)}get allowRaw(){return h(this,Te)}set allowRaw(e){u(this,Te,e)}get branding(){return h(this,Oe)}set branding(e){u(this,Oe,e)}get brandingText(){return h(this,Ie)}set brandingText(e){u(this,Ie,e)}get brandingUrl(){return h(this,Me)}set brandingUrl(e){u(this,Me,e)}get chatList(){return h(this,ze)}set chatList(e){u(this,ze,e)}get listState(){return h(this,_e)}set listState(e){u(this,_e,e)}get activeId(){return h(this,Le)}set activeId(e){u(this,Le,e)}get chatTitle(){return h(this,je)}set chatTitle(e){u(this,je,e)}get bookmarked(){return h(this,Ne)}set bookmarked(e){u(this,Ne,e)}get msgs(){return h(this,Ae)}set msgs(e){u(this,Ae,e)}get loadingThread(){return h(this,Re)}set loadingThread(e){u(this,Re,e)}get threadError(){return h(this,Ee)}set threadError(e){u(this,Ee,e)}get busy(){return h(this,Be)}set busy(e){u(this,Be,e)}get draft(){return h(this,De)}set draft(e){u(this,De,e)}get files(){return h(this,Fe)}set files(e){u(this,Fe,e)}get search(){return h(this,Ue)}set search(e){u(this,Ue,e)}get sidebarOpen(){return h(this,Pe)}set sidebarOpen(e){u(this,Pe,e)}get width(){return h(this,Ke)}set width(e){u(this,Ke,e)}get panel(){return h(this,We)}set panel(e){u(this,We,e)}get menuOpen(){return h(this,Je)}set menuOpen(e){u(this,Je,e)}get editingKey(){return h(this,He)}set editingKey(e){u(this,He,e)}get editDraft(){return h(this,qe)}set editDraft(e){u(this,qe,e)}get editingTitle(){return h(this,Ge)}set editingTitle(e){u(this,Ge,e)}get renamingId(){return h(this,Ve)}set renamingId(e){u(this,Ve,e)}get toast(){return h(this,Xe)}set toast(e){u(this,Xe,e)}get copiedKey(){return h(this,Ye)}set copiedKey(e){u(this,Ye,e)}get retrievalOpen(){return h(this,Qe)}set retrievalOpen(e){u(this,Qe,e)}get rawKeys(){return h(this,Ze)}set rawKeys(e){u(this,Ze,e)}get hasSidebarContent(){return h(this,et)}set hasSidebarContent(e){u(this,et,e)}get sorts(){return h(this,tt)}set sorts(e){u(this,tt,e)}get arrivedKey(){return h(this,it)}set arrivedKey(e){u(this,it,e)}get dragging(){return h(this,st)}set dragging(e){u(this,st,e)}get showJump(){return h(this,at)}set showJump(e){u(this,at,e)}get offline(){return h(this,rt)}set offline(e){u(this,rt,e)}get isOpen(){return h(this,nt)}set isOpen(e){u(this,nt,e)}get expanded(){return h(this,ot)}set expanded(e){u(this,ot,e)}get bubble(){return h(this,lt)}set bubble(e){u(this,lt,e)}get seen(){return h(this,ct)}set seen(e){u(this,ct,e)}get mobile(){return h(this,dt)}set mobile(e){u(this,dt,e)}get msg(){return At(this.messages)}get resolvedClient(){return this.client??Ht.getDefaultClient()??null}get chatId(){return this.activeId}get thread(){return this.msgs}get formatLevel(){return["raw","plain","advanced","rich"].includes(this.format)?this.format:"advanced"}get chats(){return this.chatList}set config(e){if(!e)return;const t=this;"client"in e&&(this.client=e.client??null);for(const i of St)i in e&&(t[i]=e[i]);e.chatId&&e.chatId!==this.activeId&&(this.hasUpdated?this.openChat(e.chatId):this.chatIdAttr=e.chatId)}configure(e){return this.config=e,this}get config(){const e=this;return{client:this.client,chatId:this.activeId??"",...Object.fromEntries(St.map(t=>[t,e[t]]))}}connectedCallback(){var e,t;super.connectedCallback(),this.offline=typeof navigator<"u"&&navigator.onLine===!1,window.addEventListener("online",this.onNetwork),window.addEventListener("offline",this.onNetwork),this.media=typeof matchMedia<"u"?matchMedia("(max-width: 559px)"):null,this.mobile=!!((e=this.media)!=null&&e.matches),(t=this.media)==null||t.addEventListener("change",this.onMedia)}disconnectedCallback(){var e,t;super.disconnectedCallback(),window.removeEventListener("online",this.onNetwork),window.removeEventListener("offline",this.onNetwork),(e=this.media)==null||e.removeEventListener("change",this.onMedia),(t=this.observer)==null||t.disconnect(),this.observer=null,this.observed=null,this.flushToast(),this.halt(),this.timers.forEach(clearTimeout),this.timers.clear()}willUpdate(e){if(e.has("retrieval")&&!Array.isArray(this.retrieval)){const t=this.retrieval;this.retrieval=t&&typeof t=="object"?[t]:[]}e.has("params")&&(!this.params||typeof this.params!="object")&&(this.params={}),e.has("metadata")&&(!this.metadata||typeof this.metadata!="object")&&(this.metadata={}),e.has("sidebar")&&(this.sidebar==="open"?this.sidebarOpen=!0:this.sidebar==="closed"||this.sidebar==="none"?this.sidebarOpen=!1:this.width&&(this.sidebarOpen=this.docked)),this.embed==="launcher"&&this.greetingBubble&&!this.bubbleScheduled&&(this.bubbleScheduled=!0,this.later(()=>{!this.isOpen&&!this.seen&&(this.bubble=!0)},1200))}firstUpdated(){this.chatIdAttr&&this.openChat(this.chatIdAttr)}updated(){var t;const e=this.renderRoot.querySelector(".root");if(e!==this.observed&&((t=this.observer)==null||t.disconnect(),this.observed=e,e&&typeof ResizeObserver<"u"&&(this.observer??(this.observer=new ResizeObserver(([i])=>{const a=Math.round(i.contentRect.width);a!==this.width&&(this.width=a,this.sidebarOpen===null&&(this.sidebarOpen=this.sidebar==="auto"&&this.docked))})),this.observer.observe(e))),this.sidebarOpen&&this.listState==="idle"&&this.resolvedClient&&this.loadChats(),this.pendingChatId&&this.resolvedClient&&this.openChat(this.pendingChatId),this.focusNext){const i=this.renderRoot.querySelector(this.focusNext);this.focusNext="",i&&(i.focus(),"select"in i&&i.tagName==="INPUT"&&i.select())}}later(e,t){const i=setTimeout(()=>{this.timers.delete(i),e()},t);this.timers.add(i)}emit(e,t){this.dispatchEvent(new CustomEvent(e,{detail:t,bubbles:!0,composed:!0}))}get docked(){return this.embed==="page"&&this.width>=ui}get panelDocked(){const e=this.docked&&this.sidebarOpen?pi:0;return this.width-e>=gi}newChat(){this.halt(),this.pendingChatId="",this.loadingThread=!1,this.activeId=null,this.chatTitle="",this.bookmarked=!1,this.msgs=[],this.threadError="",this.resetViewState(),this.focusNext="textarea.input"}async openChat(e){const t=this.resolvedClient;if(!e)return;this.halt();const i=this.chatList.find(r=>r._id===e);if(this.activeId=e,this.chatTitle=(i==null?void 0:i.title)??"",this.bookmarked=!!(i!=null&&i.bookmarked),this.msgs=[],this.threadError="",this.resetViewState(),!t){this.pendingChatId=e,this.loadingThread=!0;return}const a=++this.run;this.pendingChatId="",this.loadingThread=!0;try{const r=await t.llm.call("get_chat",{_id:e});if(a!==this.run)return;this.chatTitle=(r==null?void 0:r.title)??"",this.bookmarked=!!(r!=null&&r.bookmarked),this.msgs=((r==null?void 0:r.messages)??[]).filter(n=>n&&(n.role==="user"||n.role==="assistant")).map(n=>this.fromServer(n)),this.upsertChat({...i,...r,_id:e}),this.stick=!0,this.scrollToBottom()}catch(r){if(a!==this.run)return;_t(r)?(this.chatList=this.chatList.filter(n=>n._id!==e),this.newChat(),this.showToast(this.msg.errNotFound)):this.threadError=this.msg.errLoad}finally{a===this.run&&(this.loadingThread=!1)}}async send(e){const t=(typeof e=="string"?e:this.draft).trim();if(!t||this.busy)return;const i=this.files;this.draft="",this.files=[];const a=this.renderRoot.querySelector("textarea.input");a&&(a.style.height="auto"),await this.runTurn(this.userMessage(t,i))}stop(){if(!this.busy)return;const e=this.msgs[this.msgs.length-1];this.halt(),(e==null?void 0:e.role)==="assistant"&&(e.phase==="pending"||e.phase==="streaming")&&(e.phase="done",e.stopped=!0,e.followups=[],this.msgs=[...this.msgs])}exportChat(e="md"){var M;if(!this.msgs.length)return;this.menuOpen=!1;const t=this.chatTitle||this.msg.untitled,i=x=>x.role==="user"?this.msg.you:this.assistantName,a=x=>new Date(x||Date.now()).toLocaleString(),r=x=>x.sources.map(($,w)=>{const z=L($,w+1);return`[${z.n}] ${z.title}${z.path?` — ${z.path}`:""}`}),n=x=>(x.attachments??[]).map($=>$.name);let d,c="text/markdown",b="md";if(e==="json"?(d=JSON.stringify({exportedAt:new Date().toISOString(),id:this.activeId,title:t,mode:this.mode,bookmarked:this.bookmarked,messages:this.msgs.map(x=>({role:x.role,text:x.content,at:new Date(x.at||Date.now()).toISOString(),bookmarked:x.bookmarked,attachments:n(x),sources:r(x)}))},null,2),c="application/json",b="json"):e==="txt"?(d=`${t}
2472
+ ${"=".repeat(t.length)}
2473
+
2474
+ `+this.msgs.map(x=>[`${i(x)} · ${a(x.at)}`,n(x).length?`Attachments: ${n(x).join(", ")}`:"",x.content,r(x).length?`Sources:
2475
+ ${r(x).join(`
2476
+ `)}`:""].filter(Boolean).join(`
2477
+ `)).join(`
2478
+
2479
+ `),c="text/plain",b="txt"):d=`# ${t}
2480
+
2481
+ `+this.msgs.map(x=>[`### ${i(x)} · ${a(x.at)}`,n(x).length?`Attachments: ${n(x).join(", ")}`:"",x.content,r(x).length?`**Sources**
2482
+
2483
+ ${r(x).map($=>`- ${$}`).join(`
2484
+ `)}`:""].filter(Boolean).join(`
2485
+
2486
+ `)).join(`
2487
+
2488
+ ---
2489
+
2490
+ `)+`
2491
+ `,this.emit("singlebase-chat-export",{chatId:this.activeId,format:e}),e==="copy"){(M=navigator.clipboard)==null||M.writeText(d).catch(()=>{}),this.showToast(this.msg.copiedMarkdown);return}const k=`${t.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"")||"chat"}-${new Date().toISOString().slice(0,10)}.${b}`,C=URL.createObjectURL(new Blob([d],{type:c})),v=document.createElement("a");v.href=C,v.download=k,document.body.appendChild(v),v.click(),v.remove(),setTimeout(()=>URL.revokeObjectURL(C),2e3),this.showToast(T.fill(this.msg.exported,{name:k}))}expand(){this.expanded=!0,this.emit("singlebase-chat-expand",{expanded:!0})}collapse(){this.expanded=!1,this.emit("singlebase-chat-expand",{expanded:!1})}open(){this.isOpen=!0,this.seen=!0,this.bubble=!1,this.focusNext="textarea.input",this.emit("singlebase-chat-open",{})}close(){this.isOpen=!1,this.expanded=!1,this.emit("singlebase-chat-close",{})}userMessage(e,t=[]){return{key:pt(),id:null,role:"user",content:e,at:Date.now(),bookmarked:!1,sources:[],followups:[],phase:"done",attachments:t}}systemPrompt(){return[this.systemMessage,Mt[this.mode]??Mt.chat,yi[this.formatLevel],this.followups?wi:""].filter(Boolean).join(`
2492
+
2493
+ `)}payloadFor(e){const t={message:e.content,format:"markdown"};this.activeId?t._id=this.activeId:(t.title=ai(e.content),t.system_message=this.systemPrompt()),this.model&&(t.model=this.model),Object.keys(this.params??{}).length&&(t.params=this.params);const i=(e.attachments??[]).map(r=>r.name);(Object.keys(this.metadata??{}).length||i.length)&&(t.metadata={...this.metadata,...i.length?{attachments:i}:{}});const a=[...this.retrieval??[],...Si(e.attachments??[])];return a.length&&(t.retrieval=a),t}async runTurn(e){const t={key:pt(),id:null,role:"assistant",content:"",at:Date.now(),bookmarked:!1,sources:[],followups:[],phase:"pending"};this.msgs=[...this.msgs,e,t],this.busy=!0,this.panel=null,this.stick=!0,this.scrollToBottom(),this.emit("singlebase-chat-send",{chatId:this.activeId,text:e.content});const i=this.resolvedClient;if(!i){this.failTurn(t,this.msg.errNoClient,"NO_CLIENT"),this.busy=!1;return}const a=++this.run,r=new AbortController;this.abort=r;const n=!this.activeId;let d=this.payloadFor(e);if(this.beforeSend){let c;try{c=await this.beforeSend(d,{chatId:this.activeId,isNew:n,message:e})}catch(f){c=f}if(a!==this.run)return;if(c===!1){this.msgs=this.msgs.filter(f=>f!==e&&f!==t),this.draft=e.content,this.busy=!1,this.abort=null;return}if(!(!!c&&typeof c=="object"&&typeof c.message=="string")||!c.message.trim()){console.error("[singlebase-chat] beforeSend must return the request object (with a message) or false to cancel; the message was not sent.",c),this.failTurn(t,this.msg.errGeneric,"BEFORE_SEND_INVALID"),this.busy=!1,this.abort=null;return}d=c}try{const c=await i.llm.call("chat",d,{signal:r.signal}),b=(c==null?void 0:c._id)||(c==null?void 0:c.chat_id)||this.activeId;if(n&&b&&this.upsertChat({_id:b,title:(c==null?void 0:c.title)||d.title,bookmarked:!!(c!=null&&c.bookmarked),_modified_at:new Date().toISOString()}),a!==this.run)return;b&&(this.activeId=b),n?(this.chatTitle=(c==null?void 0:c.title)||d.title,this.bookmarked=!!(c!=null&&c.bookmarked)):b&&this.touchChat(b);const f=(c==null?void 0:c.message)??{},k=typeof f.content=="string"?f.content:(c==null?void 0:c.json)!==void 0?JSON.stringify(c.json,null,2):"",{text:C,followups:v}=gt(k);e.id=f.reply_to??null,Object.assign(t,{id:f._id??null,content:C,sources:Array.isArray(f.sources)?f.sources:[],followups:v,execTime:typeof f.exec_time=="number"?f.exec_time:void 0,model:f.model,at:Date.now()}),this.emit("singlebase-chat-response",{chatId:b,message:t}),await this.reveal(t,a),n&&b&&this.autoTitle&&this.retitle(b,e.content,t.content)}catch(c){if(a!==this.run)return;const b=_t(c);b&&(this.chatList=this.chatList.filter(f=>f._id!==this.activeId),this.activeId=null),this.failTurn(t,b?this.msg.errNotFound:this.msg.errGeneric,$i(c))}finally{a===this.run&&(this.busy=!1,this.abort=null,this.stick&&this.scrollToBottom())}}failTurn(e,t,i){e.phase="error",e.error=t,this.msgs=[...this.msgs],this.emit("singlebase-chat-error",{chatId:this.activeId,code:i,message:t})}reveal(e,t){const i=e.content.length,a=()=>{e.phase="done",this.msgs=[...this.msgs],this.arrivedKey=e.key,this.later(()=>{this.arrivedKey===e.key&&(this.arrivedKey="")},vi),this.stick?this.scrollToBottom():this.showJump=!0};if(!i||Ci())return a(),Promise.resolve();const r=e.content,n=Math.max(4,Math.ceil(i/90));let d=0;return e.phase="streaming",e.content="",new Promise(c=>{this.revealTimer=setInterval(()=>{if(t!==this.run){clearInterval(this.revealTimer),c();return}if(d=Math.min(i,d+n),e.content=r.slice(0,d),d>=i){clearInterval(this.revealTimer),a(),c();return}this.msgs=[...this.msgs],this.stick&&this.scrollToBottom()},16)})}halt(){var e;this.run++,(e=this.abort)==null||e.abort(),this.abort=null,clearInterval(this.revealTimer),this.busy=!1}async retitle(e,t,i){const a=this.resolvedClient;if(!(!a||this.renamed.has(e)))try{const r=await a.llm.call("generate",{user_input:`user: ${t}
2494
+ assistant: ${i.slice(0,1500)}`,custom_instructions:"Write a concise title (3–6 words, sentence case, no quotes, no trailing punctuation) for this conversation.",format:"text"}),n=ri(r==null?void 0:r.result);if(!n||this.renamed.has(e))return;await a.llm.call("update_chat",{_id:e,title:n}),this.applyTitle(e,n,!0)}catch{}}applyTitle(e,t,i){this.chatList=this.chatList.map(a=>a._id===e?{...a,title:t}:a),this.activeId===e&&(this.chatTitle=t),this.emit("singlebase-chat-title",{chatId:e,title:t,auto:i})}commitTitle(e){this.editingTitle&&(this.editingTitle=!1,this.activeId&&this.renameChat(this.activeId,e))}commitRename(e,t){this.renamingId===e&&(this.renamingId="",this.renameChat(e,t))}async renameChat(e,t){var r,n;const i=t.trim().slice(0,80),a=((r=this.chatList.find(d=>d._id===e))==null?void 0:r.title)??this.chatTitle;if(!(!i||i===a)){this.renamed.add(e),this.applyTitle(e,i,!1);try{await((n=this.resolvedClient)==null?void 0:n.llm.call("update_chat",{_id:e,title:i}))}catch{this.applyTitle(e,a??"",!1),this.showToast(this.msg.errGeneric)}}}fromServer(e){const t=e.role==="assistant",{text:i,followups:a}=t?gt(String(e.content??"")):{text:String(e.content??""),followups:[]};return{key:pt(),id:e._id??null,role:t?"assistant":"user",content:i,at:Date.parse(e._created_at??"")||0,bookmarked:!!e.bookmarked,sources:Array.isArray(e.sources)?e.sources:[],followups:a,phase:"done",execTime:typeof e.exec_time=="number"?e.exec_time:void 0,model:e.model}}async loadChats(){const e=this.resolvedClient;if(e){this.listState="loading";try{const t=await e.llm.call("list_chats",{limit:100});this.chatList=[...(t==null?void 0:t.items)??[]],this.listState="ready"}catch{this.listState="error"}}}upsertChat(e){const t=this.chatList.filter(a=>a._id!==e._id),i=this.chatList.find(a=>a._id===e._id);this.chatList=[{...i,...e},...t]}touchChat(e){const t=this.chatList.find(i=>i._id===e);t&&this.upsertChat({...t,_modified_at:new Date().toISOString()})}resetViewState(){this.panel=null,this.menuOpen=!1,this.editingKey="",this.editingTitle=!1,this.showJump=!1,this.retrievalOpen=new Set,this.sidebarOpen&&!this.docked&&(this.sidebarOpen=!1)}async deleteOnServer(e){const t=this.resolvedClient,i=this.activeId;if(!(!t||!i))for(const a of e)a&&await t.llm.call("delete_chat_message",{_id:i,message_id:a}).catch(()=>{})}async regenerate(){if(this.busy)return;const e=this.msgs.map(a=>a.role).lastIndexOf("assistant"),t=this.msgs[e-1];if(e<1||(t==null?void 0:t.role)!=="user")return;const i=this.msgs.slice(e-1);this.msgs=this.msgs.slice(0,e-1),await this.deleteOnServer(i.map(a=>a.id)),await this.runTurn(this.userMessage(t.content,t.attachments))}async retry(e){if(this.busy)return;const t=this.msgs.indexOf(e),i=this.msgs[t-1];(i==null?void 0:i.role)==="user"&&(this.msgs=this.msgs.slice(0,t-1),await this.runTurn(this.userMessage(i.content,i.attachments)))}async saveEdit(e){const t=this.editDraft.trim(),i=this.msgs.indexOf(e);if(this.editingKey="",!t||i<0||this.busy)return;const a=this.msgs.slice(i);this.msgs=this.msgs.slice(0,i),await this.deleteOnServer(a.map(r=>r.id)),await this.runTurn(this.userMessage(t,e.attachments))}toggleRaw(e){const t=new Set(this.rawKeys);t.has(e)?t.delete(e):t.add(e),this.rawKeys=t}copy(e,t){var i;(i=navigator.clipboard)==null||i.writeText(t).catch(()=>{}),this.copiedKey=e,this.later(()=>{this.copiedKey===e&&(this.copiedKey="")},1400)}async toggleMessageBookmark(e){var i;const t=this.activeId;if(!(!t||!e.id)){e.bookmarked=!e.bookmarked,this.msgs=[...this.msgs],this.showToast(e.bookmarked?this.msg.messageBookmarked:this.msg.bookmarkRemoved),this.emit("singlebase-chat-bookmark",{chatId:t,messageId:e.id,bookmarked:e.bookmarked});try{await((i=this.resolvedClient)==null?void 0:i.llm.call("bookmark_chat_message",{_id:t,message_id:e.id,bookmarked:e.bookmarked}))}catch{e.bookmarked=!e.bookmarked,this.msgs=[...this.msgs],this.showToast(this.msg.errGeneric)}}}async toggleChatBookmark(e){var r,n;const t=((r=this.chatList.find(d=>d._id===e))==null?void 0:r.bookmarked)??(e===this.activeId?this.bookmarked:!1),i=!t,a=d=>{this.chatList=this.chatList.map(c=>c._id===e?{...c,bookmarked:d}:c),e===this.activeId&&(this.bookmarked=d)};a(i),this.showToast(i?this.msg.chatBookmarked:this.msg.chatUnbookmarked),this.emit("singlebase-chat-bookmark",{chatId:e,bookmarked:i});try{await((n=this.resolvedClient)==null?void 0:n.llm.call("bookmark_chat",{_id:e,bookmarked:i}))}catch{a(t),this.showToast(this.msg.errGeneric)}}deleteMessage(e){var a;const t=this.activeId,i=this.msgs.indexOf(e);i<0||(this.msgs=this.msgs.filter(r=>r!==e),((a=this.panel)==null?void 0:a.key)===e.key&&(this.panel=null),this.showToast(this.msg.messageDeleted,{undo:()=>{if(this.activeId!==t)return;const r=[...this.msgs];r.splice(i,0,e),this.msgs=r},commit:()=>{var r;this.emit("singlebase-chat-message-delete",{chatId:t,messageId:e.id}),t&&e.id&&((r=this.resolvedClient)==null||r.llm.call("delete_chat_message",{_id:t,message_id:e.id}).catch(()=>{}))}}))}deleteChat(e){const t=this.chatList.findIndex(n=>n._id===e),i=this.chatList[t]??{_id:e,title:this.chatTitle,bookmarked:this.bookmarked},a=e===this.activeId,r=a?{title:this.chatTitle,bookmarked:this.bookmarked,msgs:this.msgs}:null;this.chatList=this.chatList.filter(n=>n._id!==e),a&&this.newChat(),this.showToast(this.msg.chatDeleted,{undo:()=>{const n=[...this.chatList];n.splice(Math.max(0,t),0,i),this.chatList=n,r&&!this.activeId&&!this.msgs.length&&(this.activeId=e,this.chatTitle=r.title,this.bookmarked=r.bookmarked,this.msgs=r.msgs)},commit:()=>{var n;this.emit("singlebase-chat-delete",{chatId:e}),(n=this.resolvedClient)==null||n.llm.call("delete_chat",{_id:e}).catch(()=>{})}})}feedback(e,t){e.feedback=t,this.msgs=[...this.msgs],this.emit("singlebase-chat-feedback",{chatId:this.activeId,messageId:e.id,value:t,text:e.content})}showToast(e,t={}){this.flushToast();const i={key:Date.now(),text:e,...t};this.toast=i,this.toastTimer=setTimeout(()=>{this.toast===i&&this.flushToast()},bi)}flushToast(){var t;const e=this.toast;clearTimeout(this.toastTimer),this.toast=null,(t=e==null?void 0:e.commit)==null||t.call(e)}undo(){var t;const e=this.toast;clearTimeout(this.toastTimer),this.toast=null,(t=e==null?void 0:e.undo)==null||t.call(e)}async addFiles(e){const t=Array.from(e??[]);if(!t.length)return;const i=[];for(const a of t){if(this.files.length+i.length>=Tt){this.showToast(T.fill(this.msg.tooManyFiles,{n:Tt}));break}if(!mi.test(a.name)&&!a.type.startsWith("text/")){this.showToast(T.fill(this.msg.fileType,{name:a.name}));continue}if(a.size>Ot){this.showToast(T.fill(this.msg.fileTooLarge,{name:a.name,size:T.formatSize(Ot)}));continue}i.push({name:a.name,size:a.size,content:await a.text()})}i.length&&(this.files=[...this.files,...i],this.emit("singlebase-chat-files",{files:i.map(({name:a,size:r})=>({name:a,size:r}))}))}async scrollToBottom(){await this.updateComplete;const e=this.renderRoot.querySelector(".scroller");e&&(e.scrollTop=e.scrollHeight),this.showJump=!1}onScroll(e){const t=e.currentTarget;this.stick=t.scrollHeight-t.scrollTop-t.clientHeight<80,this.stick&&(this.showJump=!1)}jumpToLatest(){this.stick=!0,this.scrollToBottom()}onKeydown(e){if(e.key==="Escape"){if(this.menuOpen)this.menuOpen=!1;else if(this.panel)this.panel=null;else if(this.sidebarOpen&&!this.docked)this.sidebarOpen=!1;else if(this.expanded)this.collapse();else if(this.embed==="launcher"&&this.isOpen)this.close();else return;e.stopPropagation()}}onComposerKey(e){e.key==="Enter"&&!e.shiftKey&&!e.isComposing&&(e.preventDefault(),this.send())}onComposerInput(e){const t=e.target;t.style.height="auto",t.style.height=`${Math.min(176,t.scrollHeight)}px`,this.draft=t.value}onDragEnter(e){var t;!this.allowUpload||!this.showComposer||Array.from(((t=e.dataTransfer)==null?void 0:t.types)??[]).includes("Files")&&(e.preventDefault(),this.dragging=!0)}onDragLeave(e){e.currentTarget.contains(e.relatedTarget)||(this.dragging=!1)}onDrop(e){var t;e.preventDefault(),this.dragging=!1,this.allowUpload&&this.addFiles((t=e.dataTransfer)==null?void 0:t.files)}render(){if(this.embed==="launcher")return this.renderLauncher();const e=["frame",this.embed==="inline"?"inline boxed":"",this.expanded?"expanded boxed":""].join(" ");return s.html`<div class=${e} part="frame">${this.renderWorkspace()}</div>`}renderLauncher(){const e=this.msg,t=["frame launcher boxed",this.expanded?"expanded":"",this.mobile?"full":""].join(" "),i=this.isOpen?s.html`<div class=${t} role="dialog" aria-label=${this.assistantName} part="frame">
2495
+ ${this.renderWorkspace()}
2496
+ </div>`:s.nothing,a=this.bubble&&!this.isOpen?s.html`<div class="bubble" part="bubble">
2497
+ <button type="button" class="bubble-text" @click=${()=>this.open()}>
2498
+ ${this.bubbleText||e.bubbleText}
2499
+ </button>
2500
+ <button
2501
+ type="button"
2502
+ class="icon sm"
2503
+ aria-label=${e.dismiss}
2504
+ title=${e.dismiss}
2505
+ @click=${()=>this.bubble=!1}
2506
+ >
2507
+ ${y.close()}
2508
+ </button>
2509
+ </div>`:s.nothing,n=this.isOpen&&(this.expanded||this.mobile)?s.nothing:s.html`<button
2510
+ type="button"
2511
+ class="launcher-btn"
2512
+ part="launcher"
2513
+ aria-label=${this.isOpen?e.closeChat:e.openChat}
2514
+ aria-expanded=${this.isOpen?"true":"false"}
2515
+ @click=${()=>this.isOpen?this.close():this.open()}
2516
+ >
2517
+ ${this.isOpen?y.chevronDown():y.chat()}
2518
+ ${this.unreadBadge&&!this.seen&&!this.isOpen?s.html`<span class="badge"></span>`:s.nothing}
2519
+ </button>`;return s.html`${i}${a}${n}`}renderWorkspace(){const e=!this.docked;return s.html`<div class="root" @keydown=${this.onKeydown}>
2520
+ ${this.sidebarOpen&&e?s.html`<div class="scrim" @click=${()=>this.sidebarOpen=!1}></div>`:s.nothing}
2521
+ ${this.sidebarOpen&&this.sidebar!=="none"?this.renderSidebar(e):s.nothing}
2522
+ <main
2523
+ class="main"
2524
+ @dragenter=${this.onDragEnter}
2525
+ @dragover=${t=>t.preventDefault()}
2526
+ >
2527
+ ${this.renderHeader()}
2528
+ ${this.offline?s.html`<div class="banner" role="status">${this.msg.offline}</div>`:s.nothing}
2529
+ <div
2530
+ class="scroller"
2531
+ role="log"
2532
+ aria-live="polite"
2533
+ aria-busy=${this.busy?"true":"false"}
2534
+ part="messages"
2535
+ @scroll=${this.onScroll}
2536
+ >
2537
+ ${this.msgs.length||this.loadingThread||this.threadError?this.renderThread():this.renderWelcome()}
2538
+ </div>
2539
+ ${this.showJump?s.html`<button type="button" class="jump" @click=${this.jumpToLatest}>
2540
+ ↓ ${this.msg.newReply}
2541
+ </button>`:s.nothing}
2542
+ ${this.renderComposer()}
2543
+ ${T.renderBranding(this.branding,this.brandingText,this.msg.brandingLabel,this.brandingUrl)}
2544
+ ${this.toast?s.html`<div class="toast" role="status">
2545
+ <span>${this.toast.text}</span>
2546
+ ${this.toast.undo?s.html`<button type="button" @click=${this.undo}>${this.msg.undo}</button>`:s.nothing}
2547
+ </div>`:s.nothing}
2548
+ ${this.dragging?s.html`<div
2549
+ class="drop"
2550
+ @dragover=${t=>t.preventDefault()}
2551
+ @dragleave=${this.onDragLeave}
2552
+ @drop=${this.onDrop}
2553
+ >
2554
+ <strong>${this.msg.dropTitle}</strong><span>${this.msg.dropSub}</span>
2555
+ </div>`:s.nothing}
2556
+ </main>
2557
+ ${this.renderPanel()}
2558
+ </div>`}renderSidebar(e){const t=this.msg,i=this.allowSearch?this.search.trim().toLowerCase():"",a=this.chatList.filter(b=>!i||(b.title??"").toLowerCase().includes(i)),r=b=>this.showBookmarked&&!!b.bookmarked,n=b=>a.filter(f=>!r(f)&&Ti(f._modified_at??f._created_at)===b),d=[[t.groupBookmarked,a.filter(r)],[t.groupToday,n("today")],[t.groupYesterday,n("yesterday")],[t.groupWeek,n("week")],[t.groupOlder,n("older")]];let c;return this.listState==="loading"&&!this.chatList.length?c=s.html`<div aria-label=${t.loadingChats}>
2559
+ ${[1,2,3,4].map(()=>s.html`<div class="skeleton"></div>`)}
2560
+ </div>`:a.length?c=d.filter(([,b])=>b.length).map(([b,f])=>s.html`<div class="group">${b}</div>
2561
+ ${f.map(k=>this.renderThreadRow(k))}`):c=s.html`<span class="side-note"
2562
+ >${i?T.fill(t.noMatch,{query:this.search.trim()}):t.noChats}</span
2563
+ >`,s.html`<aside
2564
+ class="sidebar ${e?"overlay":"docked"}"
2565
+ part="sidebar"
2566
+ aria-label=${t.chats}
2567
+ >
2568
+ <div class="side-head">
2569
+ <span class="label">${t.chats}</span>
2570
+ <button
2571
+ type="button"
2572
+ class="icon"
2573
+ title=${t.hideSidebar}
2574
+ aria-label=${t.hideSidebar}
2575
+ @click=${()=>this.sidebarOpen=!1}
2576
+ >
2577
+ ${y.sidebar()}
2578
+ </button>
2579
+ </div>
2580
+ <div class="side-tools">
2581
+ ${this.showNewChat?s.html`<button type="button" class="new-chat" @click=${()=>this.newChat()}>
2582
+ ${y.plus()}<span>${t.newChat}</span>
2583
+ </button>`:s.nothing}
2584
+ ${this.allowSearch?s.html`<input
2585
+ class="search"
2586
+ type="search"
2587
+ placeholder=${t.searchChats}
2588
+ aria-label=${t.searchChats}
2589
+ .value=${this.search}
2590
+ @input=${b=>this.search=b.target.value}
2591
+ />`:s.nothing}
2592
+ </div>
2593
+ <div class="threads">${c}</div>
2594
+ <div class="side-extra ${this.hasSidebarContent?"filled":""}" part="sidebar-extra">
2595
+ <slot
2596
+ name="sidebar"
2597
+ @slotchange=${b=>this.hasSidebarContent=b.target.assignedNodes().length>0}
2598
+ ></slot>
2599
+ </div>
2600
+ </aside>`}renderThreadRow(e){const t=this.msg,i=e._id===this.activeId,a=e.title||t.untitled;if(this.renamingId===e._id)return s.html`<div class="thread active">
2601
+ <input
2602
+ class="thread-rename"
2603
+ maxlength="80"
2604
+ .value=${a}
2605
+ aria-label=${t.renameChat}
2606
+ @keydown=${n=>{n.key==="Enter"&&this.commitRename(e._id,n.target.value),n.key==="Escape"&&(n.stopPropagation(),this.renamingId="")}}
2607
+ @blur=${n=>this.commitRename(e._id,n.target.value)}
2608
+ />
2609
+ </div>`;const r=n=>d=>{d.stopPropagation(),n()};return s.html`<div
2610
+ class="thread ${i?"active":""}"
2611
+ role="button"
2612
+ tabindex="0"
2613
+ aria-current=${i?"true":"false"}
2614
+ @click=${()=>this.openChat(e._id)}
2615
+ @keydown=${n=>n.key==="Enter"&&this.openChat(e._id)}
2616
+ >
2617
+ <span class="thread-title">${a}</span>
2618
+ <span class="thread-actions">
2619
+ ${this.allowBookmark?s.html`<button
2620
+ type="button"
2621
+ class="icon sm ${e.bookmarked?"on":""}"
2622
+ title=${e.bookmarked?t.unbookmarkChat:t.bookmarkChat}
2623
+ aria-label=${e.bookmarked?t.unbookmarkChat:t.bookmarkChat}
2624
+ @click=${r(()=>this.toggleChatBookmark(e._id))}
2625
+ >
2626
+ ${y.bookmark(!!e.bookmarked)}
2627
+ </button>`:s.nothing}
2628
+ ${this.allowRename?s.html`<button
2629
+ type="button"
2630
+ class="icon sm"
2631
+ title=${t.renameChat}
2632
+ aria-label=${t.renameChat}
2633
+ @click=${r(()=>{this.renamingId=e._id,this.focusNext="input.thread-rename"})}
2634
+ >
2635
+ ${y.pencil()}
2636
+ </button>`:s.nothing}
2637
+ ${this.allowDelete?s.html`<button
2638
+ type="button"
2639
+ class="icon sm danger"
2640
+ title=${t.deleteChat}
2641
+ aria-label=${t.deleteChat}
2642
+ @click=${r(()=>this.deleteChat(e._id))}
2643
+ >
2644
+ ${y.trash()}
2645
+ </button>`:s.nothing}
2646
+ </span>
2647
+ </div>`}renderHeader(){const e=this.msg,t=!!this.activeId,i=(this.embed==="inline"||this.embed==="launcher")&&!this.mobile,a=this.embed==="launcher"?()=>this.close():this.expanded?()=>this.collapse():null;let r=s.nothing;return this.showTitle&&(r=this.editingTitle?s.html`<input
2648
+ class="title-input"
2649
+ maxlength="80"
2650
+ .value=${this.chatTitle}
2651
+ aria-label=${e.renameChat}
2652
+ @keydown=${n=>{n.key==="Enter"&&this.commitTitle(n.target.value),n.key==="Escape"&&(n.stopPropagation(),this.editingTitle=!1)}}
2653
+ @blur=${n=>this.commitTitle(n.target.value)}
2654
+ />`:s.html`<button
2655
+ type="button"
2656
+ class="title"
2657
+ part="title"
2658
+ ?disabled=${!t||!this.allowRename}
2659
+ title=${t&&this.allowRename?e.renameChat:""}
2660
+ @click=${()=>{this.editingTitle=!0,this.focusNext="input.title-input"}}
2661
+ >
2662
+ ${this.chatTitle||e.untitled}
2663
+ </button>`),s.html`<header class="header" part="header">
2664
+ <div class="header-left">
2665
+ ${this.sidebar==="none"||this.sidebarOpen&&this.docked?s.nothing:s.html`<button
2666
+ type="button"
2667
+ class="icon"
2668
+ title=${e.showChats}
2669
+ aria-label=${e.showChats}
2670
+ @click=${()=>this.sidebarOpen=!0}
2671
+ >
2672
+ ${y.sidebar()}
2673
+ </button>`}
2674
+ ${r}
2675
+ </div>
2676
+ <div class="header-right">
2677
+ ${this.sidebar==="none"&&this.showNewChat?s.html`<button
2678
+ type="button"
2679
+ class="icon"
2680
+ ?disabled=${!this.msgs.length&&!t}
2681
+ title=${e.newChat}
2682
+ aria-label=${e.newChat}
2683
+ @click=${()=>this.newChat()}
2684
+ >
2685
+ ${y.plus()}
2686
+ </button>`:s.nothing}
2687
+ ${this.allowBookmark?s.html`<button
2688
+ type="button"
2689
+ class="icon ${this.bookmarked?"on":""}"
2690
+ ?disabled=${!t}
2691
+ title=${this.bookmarked?e.unbookmarkChat:e.bookmarkChat}
2692
+ aria-label=${this.bookmarked?e.unbookmarkChat:e.bookmarkChat}
2693
+ @click=${()=>this.activeId&&this.toggleChatBookmark(this.activeId)}
2694
+ >
2695
+ ${y.bookmark(this.bookmarked)}
2696
+ </button>`:s.nothing}
2697
+ ${this.allowExport?s.html`<div class="menu-wrap">
2698
+ <button
2699
+ type="button"
2700
+ class="icon ${this.menuOpen?"on":""}"
2701
+ ?disabled=${!this.msgs.length}
2702
+ title=${e.exportChat}
2703
+ aria-label=${e.exportChat}
2704
+ aria-haspopup="menu"
2705
+ aria-expanded=${this.menuOpen?"true":"false"}
2706
+ @click=${()=>this.menuOpen=!this.menuOpen}
2707
+ >
2708
+ ${y.download()}
2709
+ </button>
2710
+ ${this.menuOpen?this.renderExportMenu():s.nothing}
2711
+ </div>`:s.nothing}
2712
+ ${this.allowDelete?s.html`<button
2713
+ type="button"
2714
+ class="icon danger"
2715
+ ?disabled=${!t}
2716
+ title=${e.deleteChat}
2717
+ aria-label=${e.deleteChat}
2718
+ @click=${()=>this.activeId&&this.deleteChat(this.activeId)}
2719
+ >
2720
+ ${y.trash()}
2721
+ </button>`:s.nothing}
2722
+ ${i||a?s.html`<span class="divider"></span> ${i?s.html`<button
2723
+ type="button"
2724
+ class="icon"
2725
+ title=${this.expanded?e.restore:e.expand}
2726
+ aria-label=${this.expanded?e.restore:e.expand}
2727
+ @click=${()=>this.expanded?this.collapse():this.expand()}
2728
+ >
2729
+ ${this.expanded?y.restore():y.expand()}
2730
+ </button>`:s.nothing}
2731
+ ${a?s.html`<button
2732
+ type="button"
2733
+ class="icon"
2734
+ title=${e.minimize}
2735
+ aria-label=${e.minimize}
2736
+ @click=${a}
2737
+ >
2738
+ ${y.minimize()}
2739
+ </button>`:s.nothing}`:s.nothing}
2740
+ </div>
2741
+ </header>`}renderExportMenu(){const e=this.msg,t=[[e.exportMarkdown,".md","md"],[e.exportJson,".json","json"],[e.exportText,".txt","txt"],[e.exportCopy,"","copy"]];return s.html`<div class="menu-scrim" @click=${()=>this.menuOpen=!1}></div>
2742
+ <div class="menu" role="menu">
2743
+ <span class="label">${e.exportHeading}</span>
2744
+ ${t.map(([i,a,r])=>s.html`<button
2745
+ type="button"
2746
+ role="menuitem"
2747
+ class="menu-item"
2748
+ @click=${()=>this.exportChat(r)}
2749
+ >
2750
+ <span>${i}</span><span class="ext">${a}</span>
2751
+ </button>`)}
2752
+ </div>`}promptList(){const e=this.prompts;return Array.isArray(e)?e.map(t=>typeof t=="string"?{text:t}:t).filter(t=>t==null?void 0:t.text).slice(0,4):typeof e=="string"&&e.trim().toLowerCase()==="none"?[]:typeof e=="string"&&e.trim()?e.split("|").map(t=>t.trim()).filter(Boolean).slice(0,4).map(t=>({text:t})):(zt[this.mode]??zt.chat).map(([t,i])=>({label:t,text:i}))}renderWelcome(){const e=this.msg,t=this.mode==="rag"?"Rag":"Chat",i=n=>e[`${n}${t}`],a=this.eyebrow??i("eyebrow"),r=this.promptList();return s.html`<div class="welcome-slot">
2753
+ <slot name="welcome"
2754
+ ><div class="welcome" part="welcome">
2755
+ <div class="welcome-head">
2756
+ ${this.logoUrl&&Ct(this.logoUrl,!0)?s.html`<img class="welcome-logo" src=${this.logoUrl} alt="" />`:s.nothing}
2757
+ ${a?s.html`<span class="label">${a}</span>`:s.nothing}
2758
+ <h2>${this.heading||i("heading")}</h2>
2759
+ <p>${this.description||i("description")}</p>
2760
+ </div>
2761
+ ${r.length?s.html`<div class="prompts">
2762
+ ${r.map(n=>s.html`<button
2763
+ type="button"
2764
+ class="prompt"
2765
+ part="prompt"
2766
+ @click=${()=>this.send(n.text)}
2767
+ >
2768
+ <span class="label">${n.label||"Suggested"}</span>
2769
+ <span class="prompt-text">${n.text}</span>
2770
+ </button>`)}
2771
+ </div>`:s.nothing}
2772
+ </div></slot
2773
+ >
2774
+ </div>`}renderThread(){const e=this.msgs.map(t=>t.role).lastIndexOf("assistant");return s.html`<div class="thread-view">
2775
+ ${this.threadError?s.html`<div class="error-card" role="alert">
2776
+ <span>${this.threadError}</span>
2777
+ ${this.activeId?s.html`<button
2778
+ type="button"
2779
+ class="btn"
2780
+ @click=${()=>this.openChat(this.activeId)}
2781
+ >
2782
+ ${this.msg.retry}
2783
+ </button>`:s.nothing}
2784
+ </div>`:s.nothing}
2785
+ ${this.loadingThread?s.html`${[1,2].map(()=>s.html`<div class="skeleton" style="height:48px"></div>`)}`:s.nothing}
2786
+ ${Jt.repeat(this.msgs,t=>t.key,(t,i)=>t.role==="user"?this.renderUser(t):this.renderBot(t,i===e))}
2787
+ </div>`}renderUser(e){const t=this.msg,i=e.at?new Date(e.at).toLocaleTimeString([],{hour:"numeric",minute:"2-digit"}):"",a=e.attachments??[];return s.html`<div class="msg user" part="message user">
2788
+ ${a.length?s.html`<div class="attachments">
2789
+ ${a.map(r=>s.html`<span class="doc-chip"><span class="ext">${Lt(r.name)}</span><span class="name">${r.name}</span></span>`)}
2790
+ </div>`:s.nothing}
2791
+ ${this.editingKey===e.key?s.html`<div class="edit-box">
2792
+ <textarea
2793
+ rows="3"
2794
+ class="edit-input"
2795
+ .value=${this.editDraft}
2796
+ @input=${r=>this.editDraft=r.target.value}
2797
+ @keydown=${r=>{r.key==="Escape"&&(r.stopPropagation(),this.editingKey="")}}
2798
+ ></textarea>
2799
+ <div class="row-end">
2800
+ <button type="button" class="btn" @click=${()=>this.editingKey=""}>
2801
+ ${t.cancel}
2802
+ </button>
2803
+ <button type="button" class="btn primary" @click=${()=>this.saveEdit(e)}>
2804
+ ${t.saveResend}
2805
+ </button>
2806
+ </div>
2807
+ </div>`:s.html`<div class="bubble-user">${e.content}</div>
2808
+ <div class="toolbar">
2809
+ ${this.allowBookmark&&e.bookmarked?s.html`<span class="saved">${y.bookmark(!0)}${t.saved}</span>`:s.nothing}
2810
+ ${this.showTime?s.html`<span class="time">${i}</span>`:s.nothing}
2811
+ ${this.busy?s.nothing:s.html`<button
2812
+ type="button"
2813
+ class="icon"
2814
+ title=${t.edit}
2815
+ aria-label=${t.edit}
2816
+ @click=${()=>{this.editingKey=e.key,this.editDraft=e.content,this.focusNext="textarea.edit-input"}}
2817
+ >
2818
+ ${y.pencil()}
2819
+ </button>`}
2820
+ ${this.allowCopy?s.html`<button
2821
+ type="button"
2822
+ class="icon"
2823
+ title=${this.copiedKey===e.key?t.copied:t.copy}
2824
+ aria-label=${t.copy}
2825
+ @click=${()=>this.copy(e.key,e.content)}
2826
+ >
2827
+ ${y.copy()}
2828
+ </button>`:s.nothing}
2829
+ ${this.allowBookmark&&e.id?s.html`<button
2830
+ type="button"
2831
+ class="icon ${e.bookmarked?"on":""}"
2832
+ title=${e.bookmarked?t.unbookmarkMessage:t.bookmarkMessage}
2833
+ aria-label=${e.bookmarked?t.unbookmarkMessage:t.bookmarkMessage}
2834
+ @click=${()=>this.toggleMessageBookmark(e)}
2835
+ >
2836
+ ${y.bookmark(e.bookmarked)}
2837
+ </button>`:s.nothing}
2838
+ ${this.allowDelete?s.html`<button
2839
+ type="button"
2840
+ class="icon danger"
2841
+ title=${t.deleteMessage}
2842
+ aria-label=${t.deleteMessage}
2843
+ @click=${()=>this.deleteMessage(e)}
2844
+ >
2845
+ ${y.trash()}
2846
+ </button>`:s.nothing}
2847
+ </div>`}
2848
+ </div>`}pillLabel(){return this.mode==="rag"?this.msg.searching:this.msg.thinking}renderBot(e,t){const i=this.msg,a=e.phase==="pending",r=e.phase==="done",n=e.sources.length,d=ut(e.content),c=e.sources.map((v,M)=>L(v,M+1)),b=d.size?c.filter(v=>d.has(v.n)):c,f=e.at?new Date(e.at).toLocaleTimeString([],{hour:"numeric",minute:"2-digit"}):"",k=e.content+(b.length?`
2849
+
2850
+ Sources:
2851
+ ${b.map(v=>`[${v.n}] ${v.title}`).join(`
2852
+ `)}`:""),C=this.retrievalOpen.has(e.key);return s.html`<div class="msg bot" part="message assistant">
2853
+ ${a?s.html`<div class="halo"></div>`:s.nothing}
2854
+ ${this.arrivedKey===e.key?s.html`<div class="arrived">
2855
+ <div class="wash"></div>
2856
+ <div class="ring"></div>
2857
+ <div class="sweep"></div>
2858
+ </div>`:s.nothing}
2859
+ <div class="bot-body">
2860
+ ${this.allowBookmark&&e.bookmarked?s.html`<span class="saved">${y.bookmark(!0)}${i.saved}</span>`:s.nothing}
2861
+ ${a?s.html`<div class="pill" role="status">
2862
+ <span class="ring"></span><span class="dot"></span>
2863
+ <span class="shimmer">${this.pillLabel()}</span>
2864
+ </div>`:s.nothing}
2865
+ ${this.showSources&&n&&!a?s.html`<div class="retrieval">
2866
+ <button
2867
+ type="button"
2868
+ class="retrieval-toggle"
2869
+ aria-expanded=${C?"true":"false"}
2870
+ @click=${()=>{const v=new Set(this.retrievalOpen);v.has(e.key)?v.delete(e.key):v.add(e.key),this.retrievalOpen=v}}
2871
+ >
2872
+ <span class="chev">${C?"▾":"▸"}</span>
2873
+ <span style="flex:1">${T.fill(i.searchedSources,{n})}</span>
2874
+ ${e.execTime!==void 0?s.html`<span class="ms">${e.execTime.toFixed(1)}s</span>`:s.nothing}
2875
+ </button>
2876
+ ${C?s.html`<div class="retrieval-list">
2877
+ ${c.map(v=>s.html`<button
2878
+ type="button"
2879
+ class="passage"
2880
+ @click=${()=>this.panel={key:e.key,n:v.n}}
2881
+ >
2882
+ <span class="n">${v.n}</span>
2883
+ <span class="what"
2884
+ ><span>${v.title}</span><span>${v.collection||v.path}</span></span
2885
+ >
2886
+ ${v.score!==null?s.html`<span class="relevance"
2887
+ ><span class="score">${v.score.toFixed(2)}</span>
2888
+ <span class="relevance-track"
2889
+ ><span
2890
+ class="relevance-fill"
2891
+ style="width:${Math.round(v.score*100)}%"
2892
+ ></span></span
2893
+ ></span>`:s.html`<span></span>`}
2894
+ </button>`)}
2895
+ </div>`:s.nothing}
2896
+ </div>`:s.nothing}
2897
+ ${a?s.nothing:this.renderAnswer(e)}
2898
+ ${e.phase==="streaming"?s.html`<span class="caret"></span>`:s.nothing}
2899
+ ${e.phase==="error"?s.html`<div class="error-card" role="alert">
2900
+ <span>${e.error}</span>
2901
+ <button type="button" class="btn" @click=${()=>this.retry(e)}>
2902
+ ${i.retry}
2903
+ </button>
2904
+ </div>`:s.nothing}
2905
+ ${this.showSources&&r&&b.length?s.html`<div class="cards">
2906
+ <span class="label">${d.size?i.sourcesCited:i.sourcesRetrieved}</span>
2907
+ <div class="card-grid">
2908
+ ${b.map(v=>{var M;return s.html`<button
2909
+ type="button"
2910
+ class="source-card ${((M=this.panel)==null?void 0:M.key)===e.key&&this.panel.n===v.n?"active":""}"
2911
+ @click=${()=>this.panel={key:e.key,n:v.n}}
2912
+ >
2913
+ <span class="top"
2914
+ ><span class="num">${v.n}</span
2915
+ >${v.collection?s.html`<span class="label">${v.collection}</span>`:s.nothing}</span
2916
+ >
2917
+ <span class="t">${v.title}</span>
2918
+ <span class="s">${v.text}</span>
2919
+ </button>`})}
2920
+ </div>
2921
+ </div>`:s.nothing}
2922
+ ${r?s.html`<div class="toolbar ${t?"pinned":""}">
2923
+ ${this.allowCopy?s.html`<button
2924
+ type="button"
2925
+ class="icon"
2926
+ title=${this.copiedKey===e.key?i.copied:i.copy}
2927
+ aria-label=${i.copy}
2928
+ @click=${()=>this.copy(e.key,k)}
2929
+ >
2930
+ ${y.copy()}
2931
+ </button>`:s.nothing}
2932
+ ${this.allowRaw&&this.formatLevel!=="raw"&&e.content?s.html`<button
2933
+ type="button"
2934
+ class="icon ${this.rawKeys.has(e.key)?"on":""}"
2935
+ title=${this.rawKeys.has(e.key)?i.showFormatted:i.showRaw}
2936
+ aria-label=${i.showRaw}
2937
+ aria-pressed=${this.rawKeys.has(e.key)?"true":"false"}
2938
+ @click=${()=>this.toggleRaw(e.key)}
2939
+ >
2940
+ ${y.raw()}
2941
+ </button>`:s.nothing}
2942
+ ${this.allowRegenerate&&t&&!this.busy?s.html`<button
2943
+ type="button"
2944
+ class="icon"
2945
+ title=${i.regenerate}
2946
+ aria-label=${i.regenerate}
2947
+ @click=${()=>this.regenerate()}
2948
+ >
2949
+ ${y.refresh()}
2950
+ </button>`:s.nothing}
2951
+ ${this.allowBookmark&&e.id?s.html`<button
2952
+ type="button"
2953
+ class="icon ${e.bookmarked?"on":""}"
2954
+ title=${e.bookmarked?i.unbookmarkMessage:i.bookmarkMessage}
2955
+ aria-label=${e.bookmarked?i.unbookmarkMessage:i.bookmarkMessage}
2956
+ @click=${()=>this.toggleMessageBookmark(e)}
2957
+ >
2958
+ ${y.bookmark(e.bookmarked)}
2959
+ </button>`:s.nothing}
2960
+ ${this.allowDelete?s.html`<button
2961
+ type="button"
2962
+ class="icon danger"
2963
+ title=${i.deleteMessage}
2964
+ aria-label=${i.deleteMessage}
2965
+ @click=${()=>this.deleteMessage(e)}
2966
+ >
2967
+ ${y.trash()}
2968
+ </button>`:s.nothing}
2969
+ ${this.showTime?s.html`<span class="time">${f}</span>`:s.nothing}
2970
+ ${e.stopped?s.html`<span class="note">${i.stopped}</span>`:s.nothing}
2971
+ <span class="spacer"></span>
2972
+ ${this.allowFeedback?e.feedback?s.html`<span class="note"
2973
+ >${e.feedback==="up"?i.markedHelpful:i.thanksFeedback}</span
2974
+ >`:s.html`<button
2975
+ type="button"
2976
+ class="icon"
2977
+ title=${i.helpful}
2978
+ aria-label=${i.helpful}
2979
+ @click=${()=>this.feedback(e,"up")}
2980
+ >
2981
+ ${y.thumb()}
2982
+ </button>
2983
+ <button
2984
+ type="button"
2985
+ class="icon"
2986
+ title=${i.notHelpful}
2987
+ aria-label=${i.notHelpful}
2988
+ @click=${()=>this.feedback(e,"down")}
2989
+ >
2990
+ ${y.thumb(!0)}
2991
+ </button>`:s.nothing}
2992
+ </div>`:s.nothing}
2993
+ ${this.showFollowups&&r&&t&&!this.busy&&e.followups.length?s.html`<div class="followups">
2994
+ ${e.followups.map(v=>s.html`<button type="button" class="followup" @click=${()=>this.send(v)}>
2995
+ <span class="arrow">↳</span><span>${v}</span>
2996
+ </button>`)}
2997
+ </div>`:s.nothing}
2998
+ </div>
2999
+ </div>`}renderAnswer(e){if(e.phase==="error"&&!e.content)return s.nothing;if(e.phase==="done"&&!e.content)return e.stopped?s.nothing:s.html`<div class="answer"><p class="note">${this.msg.emptyReply}</p></div>`;const t=this.formatLevel;if(t==="raw"||this.allowRaw&&this.rawKeys.has(e.key))return s.html`<div class="answer" part="answer"><p class="raw">${e.content}</p></div>`;const i=e.phase==="streaming"?Dt(e.content):e.content;let a=Ft(Rt(i),t);if(this.afterParse)try{const n=this.afterParse(a,{message:e,format:t});Array.isArray(n)?a=n:console.warn("[singlebase-chat] afterParse must return an array of blocks; showing the original.")}catch(n){console.warn("[singlebase-chat] afterParse failed; showing the original.",n)}const r=e.sources.length;return s.html`<div class="answer" part="answer">
3000
+ ${a.map((n,d)=>this.renderBlock(n,e,r,d))}
3001
+ </div>`}renderInline(e,t,i){return Bt(e,i).map(a=>{var r;switch(a.type){case"bold":return s.html`<strong>${a.text}</strong>`;case"italic":return s.html`<em>${a.text}</em>`;case"strike":return s.html`<s>${a.text}</s>`;case"code":return s.html`<code class="inline">${a.text}</code>`;case"link":return s.html`<a href=${a.href} target="_blank" rel="noopener noreferrer nofollow"
3002
+ >${a.text}</a
3003
+ >`;case"cite":{const n=((r=this.panel)==null?void 0:r.key)===t.key&&this.panel.n===a.n?"cite active":"cite",d=T.fill(this.msg.openSource,{n:a.n}),c=()=>this.panel={key:t.key,n:a.n};return s.html`<button type="button" class=${n} aria-label=${d} @click=${c}>${a.n}</button>`}default:return a.text}})}renderBlock(e,t,i,a){switch(e.type){case"p":return s.html`<p>${this.renderInline(e.text,t,i)}</p>`;case"raw":return s.html`<p class="raw">${e.text}</p>`;case"h":return s.html`<h3 class="h${e.level}">${this.renderInline(e.text,t,i)}</h3>`;case"hr":return s.html`<hr />`;case"list":return this.renderList(e.ordered,e.items,t,i);case"quote":return s.html`<div class="quote">${this.renderInline(e.text,t,i)}</div>`;case"callout":return s.html`<div class="callout ${e.kind}" role="note" part="callout">
3004
+ <strong class="callout-title"
3005
+ >${e.title||this.msg[xi[e.kind]]}</strong
3006
+ >
3007
+ ${e.text.split(`
3008
+ `).filter(r=>r.trim()).map(r=>s.html`<p>${this.renderInline(r,t,i)}</p>`)}
3009
+ </div>`;case"code":return this.renderCustom(e.lang,e.text,t)??this.renderCode(e.lang,e.text,`${t.key}:${a}`);case"table":return this.renderTable(e.head,e.rows,e.align,t,i,`${t.key}:${a}`);case"json":return this.renderJsonBlock(e.value,e.source,`${t.key}:${a}`);case"svg":{const r=Ut(e.source);if(!r)return this.renderCode("svg",e.source,`${t.key}:${a}`);const n=`${t.key}:${a}`;return s.html`<figure class="svg" part="svg">
3010
+ <img src=${r} alt="Drawing" />
3011
+ <figcaption>
3012
+ <button type="button" class="text-btn" @click=${()=>this.copy(n,e.source)}>
3013
+ ${this.copiedKey===n?this.msg.copied:this.msg.copySvg}
3014
+ </button>
3015
+ </figcaption>
3016
+ </figure>`}case"pending":return s.html`<div class="chart-pending">
3017
+ <span class="label"
3018
+ >${e.kind==="svg"?this.msg.renderingSvg:this.msg.renderingChart}</span
3019
+ >
3020
+ </div>`;case"chart":return this.renderChart(e.spec);case"img":return s.html`<div class="gallery ${e.images.length>1?"many":""}">
3021
+ ${e.images.map(r=>s.html`<figure>
3022
+ ${r.src&&Ct(r.src,!0)?s.html`<img
3023
+ src=${r.src}
3024
+ alt=${r.alt}
3025
+ loading="lazy"
3026
+ referrerpolicy="no-referrer"
3027
+ />`:s.html`<div class="img-missing"><span class="label">Image</span></div>`}
3028
+ ${r.alt?s.html`<figcaption>${r.alt}</figcaption>`:s.nothing}
3029
+ </figure>`)}
3030
+ </div>`;default:return s.nothing}}renderList(e,t,i,a){const r=t.map(n=>s.html`<li
3031
+ class=${n.checked===null?"":"task"}
3032
+ style=${n.depth?`margin-left:${n.depth*20}px`:""}
3033
+ >
3034
+ ${n.checked===null?s.nothing:s.html`<input type="checkbox" disabled .checked=${n.checked} aria-hidden="true" />`}
3035
+ ${this.renderInline(n.text,i,a)}
3036
+ </li>`);return e?s.html`<ol>
3037
+ ${r}
3038
+ </ol>`:s.html`<ul>
3039
+ ${r}
3040
+ </ul>`}renderCode(e,t,i){return s.html`<div class="code">
3041
+ <div class="code-head">
3042
+ <span class="label">${e}</span>
3043
+ <button type="button" class="text-btn" @click=${()=>this.copy(i,t)}>
3044
+ ${this.copiedKey===i?this.msg.copied:this.msg.copy}
3045
+ </button>
3046
+ </div>
3047
+ <pre><code>${t}</code></pre>
3048
+ </div>`}renderCustom(e,t,i){var r;const a=this.formatLevel==="rich"?(r=this.renderers)==null?void 0:r[e]:void 0;if(typeof a!="function"||i.phase==="streaming")return null;try{const n=a(t,{lang:e,message:i});return n==null?null:s.html`<div class="custom-block">${n}</div>`}catch(n){return console.warn(`[singlebase-chat] the "${e}" renderer failed; showing the source`,n),null}}renderTable(e,t,i,a,r,n){const d=x=>/^[-+]?[$€£¥]?\s?[\d,.]+\s?%?$/.test(x.trim())&&/\d/.test(x),c=x=>Number(x.replace(/[^\d.+-]/g,"")),b=e.map((x,$)=>{if(i[$])return i[$];const w=t.map(z=>z[$]??"").filter(Boolean);return w.length&&w.filter(d).length/w.length>=.8?"right":null}),f=this.sorts.get(n);let k=t;f&&(k=[...t].sort((x,$)=>{const w=x[f.col]??"",z=$[f.col]??"";return(d(w)&&d(z)?c(w)-c(z):w.localeCompare(z,void 0,{numeric:!0}))*f.dir}));const C=k.length;k=k.slice(0,fi);const v=x=>{const $=new Map(this.sorts),w=$.get(n);(w==null?void 0:w.col)===x&&w.dir===-1?$.delete(n):$.set(n,{col:x,dir:(w==null?void 0:w.col)===x?-1:1}),this.sorts=$},M=x=>b[x]?`text-align:${b[x]}`:"";return s.html`<div class="table" part="table">
3049
+ <table>
3050
+ <thead>
3051
+ <tr>
3052
+ ${e.map((x,$)=>{const w=(f==null?void 0:f.col)===$?f.dir===1?"ascending":"descending":"none";return s.html`<th style=${M($)} aria-sort=${w}>
3053
+ ${t.length>1?s.html`<button type="button" class="sort" @click=${()=>v($)}>
3054
+ ${this.renderInline(x,a,r)}<span class="arrow"
3055
+ >${w==="ascending"?"↑":w==="descending"?"↓":"↕"}</span
3056
+ >
3057
+ </button>`:this.renderInline(x,a,r)}
3058
+ </th>`})}
3059
+ </tr>
3060
+ </thead>
3061
+ <tbody>
3062
+ ${k.map(x=>s.html`<tr>
3063
+ ${e.map(($,w)=>s.html`<td style=${M(w)}>
3064
+ ${this.renderInline(x[w]??"",a,r)}
3065
+ </td>`)}
3066
+ </tr>`)}
3067
+ </tbody>
3068
+ </table>
3069
+ ${C>k.length?s.html`<div class="table-note">
3070
+ ${T.fill(this.msg.showingRows,{n:k.length,total:C})}
3071
+ </div>`:s.nothing}
3072
+ </div>`}renderJsonBlock(e,t,i){let a=0;const r=d=>{a++,a<=It&&d&&typeof d=="object"&&Object.values(d).forEach(r)};if(r(e),a>It)return this.renderCode("json",t,i);const n=(d,c,b)=>{const f=b===void 0?s.nothing:s.html`<span class="jkey">${b}</span>: `;if(d&&typeof d=="object"){const C=Object.entries(d),v=Array.isArray(d)?`[${C.length}]`:`{${C.length}}`;return s.html`<details class="jnode" ?open=${c<2}>
3073
+ <summary>${f}<span class="jmeta">${v}</span></summary>
3074
+ <div class="jkids">${C.map(([M,x])=>n(x,c+1,M))}</div>
3075
+ </details>`}const k=d===null?"null":typeof d;return s.html`<div class="jleaf">
3076
+ ${f}<span class="jv ${k}">${JSON.stringify(d)}</span>
3077
+ </div>`};return s.html`<div class="code json" part="json">
3078
+ <div class="code-head">
3079
+ <span class="label">json</span>
3080
+ <button type="button" class="text-btn" @click=${()=>this.copy(i,t)}>
3081
+ ${this.copiedKey===i?this.msg.copied:this.msg.copy}
3082
+ </button>
3083
+ </div>
3084
+ <div class="jtree">${n(e,0)}</div>
3085
+ </div>`}renderChart(e){const t=e.series.length>1?s.html`<span class="legend">
3086
+ ${e.series.map((n,d)=>s.html`<span
3087
+ ><span
3088
+ class="swatch"
3089
+ style="background:${_[d%_.length]}"
3090
+ ></span
3091
+ >${n.name}</span
3092
+ >`)}
3093
+ </span>`:s.nothing,i=s.html`<div class="chart-head">
3094
+ <span class="chart-title">${e.title}</span>${t}
3095
+ </div>`;if(e.type==="line"){const n=Math.max(0,...e.series.flatMap(f=>f.values)),d=Math.pow(10,Math.floor(Math.log10(n||1))),c=Math.ceil(n/d*2)/2*d||1,b=Math.max(e.labels.length,...e.series.map(f=>f.values.length));return s.html`<figure class="chart" part="chart" aria-label=${e.title}>
3096
+ ${i}
3097
+ <div class="line-chart">
3098
+ <div class="plot">
3099
+ ${[1,.5,0].map(f=>s.html`<div class="tick ${f===0?"base":""}" style="top:${(1-f)*100}%">
3100
+ <span>${ht(Math.round(c*f),e.unit)}</span>
3101
+ </div>`)}
3102
+ <svg
3103
+ viewBox="0 0 600 170"
3104
+ preserveAspectRatio="none"
3105
+ role="img"
3106
+ aria-label=${e.title}
3107
+ >
3108
+ ${e.series.map((f,k)=>s.svg`<polyline pathLength="1" stroke=${_[k%_.length]}
3109
+ points=${f.values.map((C,v)=>`${(b>1?v/(b-1)*600:300).toFixed(1)},${(170-C/c*170).toFixed(1)}`).join(" ")}><title>${f.name}: ${f.values.map(C=>ht(C,e.unit)).join(", ")}</title></polyline>`)}
3110
+ </svg>
3111
+ </div>
3112
+ <div class="x-labels">${e.labels.map(f=>s.html`<span>${f}</span>`)}</div>
3113
+ </div>
3114
+ </figure>`}const a=e.labels.map((n,d)=>e.series.reduce((c,b)=>c+(b.values[d]||0),0)),r=Math.max(0,...a)||1;return s.html`<figure class="chart" part="chart" aria-label=${e.title}>
3115
+ ${i}
3116
+ <div class="bars">
3117
+ ${e.labels.map((n,d)=>s.html`<div class="bar-row" title="${n}: ${ht(a[d],e.unit)}">
3118
+ <span class="bar-label">${n}</span>
3119
+ <span class="bar-track"
3120
+ ><span class="bar-fill" style="width:${Math.max(0,a[d])/r*100}%">
3121
+ ${e.series.map((c,b)=>s.html`<span
3122
+ style="flex:${Math.max(0,c.values[d]||0)};background:${e.series.length>1?_[b%_.length]:"var(--c-ink)"}"
3123
+ ></span>`)}
3124
+ </span></span
3125
+ >
3126
+ <span class="bar-value">${ht(a[d],e.unit)}</span>
3127
+ </div>`)}
3128
+ </div>
3129
+ </figure>`}renderPanel(){if(!this.panel)return s.nothing;const e=this.msgs.find(f=>f.key===this.panel.key),t=e==null?void 0:e.sources[this.panel.n-1];if(!e||!t)return s.nothing;const i=this.msg,a=L(t,this.panel.n),r=ut(e.content),n=e.sources.map((f,k)=>L(f,k+1)).filter(f=>f.n!==a.n&&(!r.size||r.has(f.n))),d=`ref:${e.key}:${a.n}`,c=`"${a.text}"
3130
+ — ${a.title} [${a.n}]${a.path?`
3131
+ ${a.path}`:""}${a.updated?` · Updated ${a.updated}`:""}`,b=[a.updated?`Updated ${a.updated}`:"",a.score!==null?`Relevance ${a.score.toFixed(2)}`:""].filter(Boolean).join(" · ");return s.html`<aside
3132
+ class="panel ${this.panelDocked?"docked":"overlay"}"
3133
+ part="panel"
3134
+ role="region"
3135
+ aria-label=${T.fill(i.sourceLabel,{n:a.n})}
3136
+ >
3137
+ <div class="panel-head">
3138
+ <span class="label"
3139
+ >${T.fill(i.sourceLabel,{n:a.n})}${a.collection?` · ${a.collection}`:""}</span
3140
+ >
3141
+ <button type="button" class="text-btn underline" @click=${()=>this.panel=null}>
3142
+ ${i.close}
3143
+ </button>
3144
+ </div>
3145
+ <div class="panel-body">
3146
+ <div class="panel-meta">
3147
+ <h3>${a.title}</h3>
3148
+ ${a.path?s.html`<span class="path">${a.path}</span>`:s.nothing}
3149
+ ${b?s.html`<span class="meta">${b}</span>`:s.nothing}
3150
+ </div>
3151
+ <div class="passage-box">
3152
+ <span class="text">${a.text}</span>
3153
+ <div class="passage-foot">
3154
+ <span class="label">${i.citedPassage}</span>
3155
+ <button
3156
+ type="button"
3157
+ class="copy-ref"
3158
+ title=${i.copyReference}
3159
+ aria-label=${i.copyReference}
3160
+ @click=${()=>this.copy(d,c)}
3161
+ >
3162
+ ${y.copy()}<span>${this.copiedKey===d?i.copied:i.copy}</span>
3163
+ </button>
3164
+ </div>
3165
+ </div>
3166
+ </div>
3167
+ ${n.length?s.html`<div class="panel-foot">
3168
+ <span class="label">${i.alsoCited}</span>
3169
+ <div class="chips">
3170
+ ${n.map(f=>s.html`<button
3171
+ type="button"
3172
+ class="chip"
3173
+ @click=${()=>this.panel={key:e.key,n:f.n}}
3174
+ >
3175
+ ${f.n} · ${f.title}
3176
+ </button>`)}
3177
+ </div>
3178
+ </div>`:s.nothing}
3179
+ </aside>`}renderComposer(){const e=this.msg,t=this.mode==="rag"?e.placeholderRag:T.fill(e.placeholderChat,{name:this.assistantName}),i=!this.draft.trim(),a=this.footnote===""?s.nothing:s.html`<span class="footnote" part="footnote"
3180
+ >${this.footnote??T.fill(e.footnote,{name:this.assistantName})}</span
3181
+ >`;return this.showComposer?s.html`<div class="composer-wrap">
3182
+ <div class="composer-col">
3183
+ <input
3184
+ type="file"
3185
+ multiple
3186
+ hidden
3187
+ accept=".md,.markdown,.txt,.csv,.tsv,.json,.html,.htm,.yaml,.yml,.xml,.log,text/*"
3188
+ @change=${r=>{const n=r.target;this.addFiles(n.files).then(()=>n.value="")}}
3189
+ />
3190
+ <div class="composer-box">
3191
+ ${this.busy?s.html`<div class="composer-glow"></div>`:s.nothing}
3192
+ <div class="composer ${this.busy?"busy":""}" part="composer">
3193
+ ${this.files.length?s.html`<div class="pending-files">
3194
+ ${this.files.map(r=>s.html`<div class="pending-file">
3195
+ <span class="ext">${Lt(r.name)}</span>
3196
+ <span class="meta"
3197
+ ><span class="name">${r.name}</span
3198
+ ><span class="size">${T.formatSize(r.size)}</span></span
3199
+ >
3200
+ <button
3201
+ type="button"
3202
+ aria-label=${e.removeFile}
3203
+ title=${e.removeFile}
3204
+ @click=${()=>this.files=this.files.filter(n=>n!==r)}
3205
+ >
3206
+ ×
3207
+ </button>
3208
+ </div>`)}
3209
+ </div>`:s.nothing}
3210
+ <textarea
3211
+ class="input"
3212
+ rows="1"
3213
+ placeholder=${t}
3214
+ aria-label=${t}
3215
+ .value=${this.draft}
3216
+ @input=${this.onComposerInput}
3217
+ @keydown=${this.onComposerKey}
3218
+ ></textarea>
3219
+ <div class="composer-row">
3220
+ <div>
3221
+ ${this.allowUpload?s.html`<button
3222
+ type="button"
3223
+ class="attach"
3224
+ title=${e.attach}
3225
+ aria-label=${e.attach}
3226
+ @click=${()=>{var r;return(r=this.renderRoot.querySelector("input[type=file]"))==null?void 0:r.click()}}
3227
+ >
3228
+ ${y.clip()}
3229
+ </button>`:s.nothing}
3230
+ </div>
3231
+ ${this.busy?s.html`<button
3232
+ type="button"
3233
+ class="send stop"
3234
+ title=${e.stop}
3235
+ aria-label=${e.stop}
3236
+ @click=${()=>this.stop()}
3237
+ >
3238
+ ${y.stop()}
3239
+ </button>`:s.html`<button
3240
+ type="button"
3241
+ class="send"
3242
+ title=${e.send}
3243
+ aria-label=${e.send}
3244
+ ?disabled=${i}
3245
+ @click=${()=>this.send()}
3246
+ >
3247
+ ${y.up()}
3248
+ </button>`}
3249
+ </div>
3250
+ </div>
3251
+ ${this.busy?s.html`<div class="composer-ring"><div class="ring"></div></div>`:s.nothing}
3252
+ </div>
3253
+ ${a}
3254
+ </div>
3255
+ </div>`:s.html`<div class="composer-wrap reader">
3256
+ <div class="composer-col">${a}</div>
3257
+ </div>`}},j=new WeakMap,N=new WeakMap,A=new WeakMap,R=new WeakMap,E=new WeakMap,B=new WeakMap,D=new WeakMap,F=new WeakMap,U=new WeakMap,P=new WeakMap,K=new WeakMap,W=new WeakMap,J=new WeakMap,H=new WeakMap,q=new WeakMap,G=new WeakMap,V=new WeakMap,X=new WeakMap,Y=new WeakMap,Q=new WeakMap,Z=new WeakMap,ee=new WeakMap,te=new WeakMap,ie=new WeakMap,se=new WeakMap,ae=new WeakMap,re=new WeakMap,ne=new WeakMap,oe=new WeakMap,le=new WeakMap,ce=new WeakMap,de=new WeakMap,he=new WeakMap,pe=new WeakMap,ue=new WeakMap,ge=new WeakMap,me=new WeakMap,be=new WeakMap,fe=new WeakMap,xe=new WeakMap,ve=new WeakMap,ye=new WeakMap,we=new WeakMap,ke=new WeakMap,$e=new WeakMap,Ce=new WeakMap,Se=new WeakMap,Te=new WeakMap,Oe=new WeakMap,Ie=new WeakMap,Me=new WeakMap,ze=new WeakMap,_e=new WeakMap,Le=new WeakMap,je=new WeakMap,Ne=new WeakMap,Ae=new WeakMap,Re=new WeakMap,Ee=new WeakMap,Be=new WeakMap,De=new WeakMap,Fe=new WeakMap,Ue=new WeakMap,Pe=new WeakMap,Ke=new WeakMap,We=new WeakMap,Je=new WeakMap,He=new WeakMap,qe=new WeakMap,Ge=new WeakMap,Ve=new WeakMap,Xe=new WeakMap,Ye=new WeakMap,Qe=new WeakMap,Ze=new WeakMap,et=new WeakMap,tt=new WeakMap,it=new WeakMap,st=new WeakMap,at=new WeakMap,rt=new WeakMap,nt=new WeakMap,ot=new WeakMap,lt=new WeakMap,ct=new WeakMap,dt=new WeakMap,jt);di(exports.SinglebaseChat,"styles",[T.tokenDefaults,T.brandingStyles,qt]);m([g.property({attribute:!1})],exports.SinglebaseChat.prototype,"client",1);m([g.property({attribute:!1})],exports.SinglebaseChat.prototype,"messages",1);m([g.property({reflect:!0})],exports.SinglebaseChat.prototype,"theme",1);m([g.property({reflect:!0})],exports.SinglebaseChat.prototype,"radius",1);m([g.property({reflect:!0})],exports.SinglebaseChat.prototype,"mode",1);m([g.property({reflect:!0})],exports.SinglebaseChat.prototype,"format",1);m([g.property({attribute:!1})],exports.SinglebaseChat.prototype,"renderers",1);m([g.property({attribute:!1})],exports.SinglebaseChat.prototype,"beforeSend",1);m([g.property({attribute:!1})],exports.SinglebaseChat.prototype,"afterParse",1);m([g.property({reflect:!0})],exports.SinglebaseChat.prototype,"glow",1);m([g.property({converter:S})],exports.SinglebaseChat.prototype,"followups",1);m([g.property({converter:S,attribute:"show-sources"})],exports.SinglebaseChat.prototype,"showSources",1);m([g.property({converter:S,attribute:"show-new-chat"})],exports.SinglebaseChat.prototype,"showNewChat",1);m([g.property({converter:S,attribute:"show-bookmarked"})],exports.SinglebaseChat.prototype,"showBookmarked",1);m([g.property({converter:S,attribute:"show-followups"})],exports.SinglebaseChat.prototype,"showFollowups",1);m([g.property({converter:S,attribute:"allow-search"})],exports.SinglebaseChat.prototype,"allowSearch",1);m([g.property({converter:S,attribute:"auto-title"})],exports.SinglebaseChat.prototype,"autoTitle",1);m([g.property()],exports.SinglebaseChat.prototype,"model",1);m([g.property({converter:mt})],exports.SinglebaseChat.prototype,"params",1);m([g.property({attribute:"system-message"})],exports.SinglebaseChat.prototype,"systemMessage",1);m([g.property({converter:mt})],exports.SinglebaseChat.prototype,"retrieval",1);m([g.property({converter:mt})],exports.SinglebaseChat.prototype,"metadata",1);m([g.property({reflect:!0})],exports.SinglebaseChat.prototype,"embed",1);m([g.property({reflect:!0})],exports.SinglebaseChat.prototype,"position",1);m([g.property({converter:hi})],exports.SinglebaseChat.prototype,"sidebar",1);m([g.property({converter:S,attribute:"show-title"})],exports.SinglebaseChat.prototype,"showTitle",1);m([g.property({attribute:"chat-id"})],exports.SinglebaseChat.prototype,"chatIdAttr",1);m([g.property({attribute:"assistant-name"})],exports.SinglebaseChat.prototype,"assistantName",1);m([g.property({attribute:"logo-url"})],exports.SinglebaseChat.prototype,"logoUrl",1);m([g.property()],exports.SinglebaseChat.prototype,"heading",1);m([g.property()],exports.SinglebaseChat.prototype,"description",1);m([g.property()],exports.SinglebaseChat.prototype,"eyebrow",1);m([g.property()],exports.SinglebaseChat.prototype,"prompts",1);m([g.property({attribute:"bubble-text"})],exports.SinglebaseChat.prototype,"bubbleText",1);m([g.property({type:Boolean,attribute:"greeting-bubble"})],exports.SinglebaseChat.prototype,"greetingBubble",1);m([g.property({type:Boolean,attribute:"unread-badge"})],exports.SinglebaseChat.prototype,"unreadBadge",1);m([g.property({converter:S,attribute:"allow-upload"})],exports.SinglebaseChat.prototype,"allowUpload",1);m([g.property({converter:S,attribute:"allow-export"})],exports.SinglebaseChat.prototype,"allowExport",1);m([g.property({converter:S,attribute:"allow-copy"})],exports.SinglebaseChat.prototype,"allowCopy",1);m([g.property({converter:S,attribute:"allow-regenerate"})],exports.SinglebaseChat.prototype,"allowRegenerate",1);m([g.property({converter:S,attribute:"allow-bookmark"})],exports.SinglebaseChat.prototype,"allowBookmark",1);m([g.property({converter:S,attribute:"allow-delete"})],exports.SinglebaseChat.prototype,"allowDelete",1);m([g.property({converter:S,attribute:"allow-rename"})],exports.SinglebaseChat.prototype,"allowRename",1);m([g.property({converter:S,attribute:"allow-feedback"})],exports.SinglebaseChat.prototype,"allowFeedback",1);m([g.property({converter:S,attribute:"show-composer"})],exports.SinglebaseChat.prototype,"showComposer",1);m([g.property({converter:S,attribute:"show-time"})],exports.SinglebaseChat.prototype,"showTime",1);m([g.property()],exports.SinglebaseChat.prototype,"footnote",1);m([g.property({type:Boolean,attribute:"allow-raw"})],exports.SinglebaseChat.prototype,"allowRaw",1);m([g.property({converter:S})],exports.SinglebaseChat.prototype,"branding",1);m([g.property({attribute:"branding-text"})],exports.SinglebaseChat.prototype,"brandingText",1);m([g.property({attribute:"branding-url"})],exports.SinglebaseChat.prototype,"brandingUrl",1);m([g.state()],exports.SinglebaseChat.prototype,"chatList",1);m([g.state()],exports.SinglebaseChat.prototype,"listState",1);m([g.state()],exports.SinglebaseChat.prototype,"activeId",1);m([g.state()],exports.SinglebaseChat.prototype,"chatTitle",1);m([g.state()],exports.SinglebaseChat.prototype,"bookmarked",1);m([g.state()],exports.SinglebaseChat.prototype,"msgs",1);m([g.state()],exports.SinglebaseChat.prototype,"loadingThread",1);m([g.state()],exports.SinglebaseChat.prototype,"threadError",1);m([g.state()],exports.SinglebaseChat.prototype,"busy",1);m([g.state()],exports.SinglebaseChat.prototype,"draft",1);m([g.state()],exports.SinglebaseChat.prototype,"files",1);m([g.state()],exports.SinglebaseChat.prototype,"search",1);m([g.state()],exports.SinglebaseChat.prototype,"sidebarOpen",1);m([g.state()],exports.SinglebaseChat.prototype,"width",1);m([g.state()],exports.SinglebaseChat.prototype,"panel",1);m([g.state()],exports.SinglebaseChat.prototype,"menuOpen",1);m([g.state()],exports.SinglebaseChat.prototype,"editingKey",1);m([g.state()],exports.SinglebaseChat.prototype,"editDraft",1);m([g.state()],exports.SinglebaseChat.prototype,"editingTitle",1);m([g.state()],exports.SinglebaseChat.prototype,"renamingId",1);m([g.state()],exports.SinglebaseChat.prototype,"toast",1);m([g.state()],exports.SinglebaseChat.prototype,"copiedKey",1);m([g.state()],exports.SinglebaseChat.prototype,"retrievalOpen",1);m([g.state()],exports.SinglebaseChat.prototype,"rawKeys",1);m([g.state()],exports.SinglebaseChat.prototype,"hasSidebarContent",1);m([g.state()],exports.SinglebaseChat.prototype,"sorts",1);m([g.state()],exports.SinglebaseChat.prototype,"arrivedKey",1);m([g.state()],exports.SinglebaseChat.prototype,"dragging",1);m([g.state()],exports.SinglebaseChat.prototype,"showJump",1);m([g.state()],exports.SinglebaseChat.prototype,"offline",1);m([g.state()],exports.SinglebaseChat.prototype,"isOpen",1);m([g.state()],exports.SinglebaseChat.prototype,"expanded",1);m([g.state()],exports.SinglebaseChat.prototype,"bubble",1);m([g.state()],exports.SinglebaseChat.prototype,"seen",1);m([g.state()],exports.SinglebaseChat.prototype,"mobile",1);exports.SinglebaseChat=m([g.customElement("singlebase-chat")],exports.SinglebaseChat);exports.adaptBlocks=Ft;exports.citedNumbers=ut;exports.defaultChatMessages=Nt;exports.describeSource=L;exports.parseInline=Bt;exports.parseMarkdown=Rt;exports.resolveChatMessages=At;exports.settleStreaming=Dt;exports.splitFollowups=gt;exports.svgDataUrl=Ut;
3258
+ //# sourceMappingURL=chat-C-gsskho.cjs.map