@singlebase/elements 0.3.0 → 0.5.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 (51) hide show
  1. package/README.md +2 -0
  2. package/dist/{display-8HEcKYR4.js → authui-display-BCZBP7HR.js} +11 -10
  3. package/dist/authui-display-BCZBP7HR.js.map +1 -0
  4. package/dist/{display-CLDNNZQy.cjs → authui-display-CLGFSqRi.cjs} +21 -21
  5. package/dist/authui-display-CLGFSqRi.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-DRenTJlI.cjs +3001 -0
  10. package/dist/chat-DRenTJlI.cjs.map +1 -0
  11. package/dist/chat-bXaRWel7.js +4926 -0
  12. package/dist/chat-bXaRWel7.js.map +1 -0
  13. package/dist/chat-messages.d.ts +109 -0
  14. package/dist/chat.cjs +2 -0
  15. package/dist/chat.cjs.map +1 -0
  16. package/dist/chat.d.ts +10 -0
  17. package/dist/chat.js +13 -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/{buttons.d.ts → authui-buttons.d.ts} +1 -1
  21. package/dist/elements/{display.d.ts → authui-display.d.ts} +1 -1
  22. package/dist/elements/{form-base.d.ts → authui-form-base.d.ts} +1 -1
  23. package/dist/elements/{guard.d.ts → authui-guard.d.ts} +1 -1
  24. package/dist/elements/{auth-screen.d.ts → authui.d.ts} +3 -3
  25. package/dist/elements/chat.d.ts +312 -0
  26. package/dist/files-BOwtpYyQ.js +168 -0
  27. package/dist/files-BOwtpYyQ.js.map +1 -0
  28. package/dist/files-DW8A4Jl-.cjs +38 -0
  29. package/dist/files-DW8A4Jl-.cjs.map +1 -0
  30. package/dist/index.cjs +1 -1
  31. package/dist/index.d.ts +3 -2
  32. package/dist/index.js +36 -25
  33. package/dist/index.js.map +1 -1
  34. package/dist/singlebase-elements.min.js +6841 -1824
  35. package/dist/singlebase-elements.min.js.map +1 -1
  36. package/dist/styles/chat.d.ts +6 -0
  37. package/dist/styles/tokens.d.ts +1 -1
  38. package/dist/{uploader-eFYKpk8b.cjs → uploader-DGV2y9uT.cjs} +41 -77
  39. package/dist/uploader-DGV2y9uT.cjs.map +1 -0
  40. package/dist/{uploader-D-Da1trc.js → uploader-abQoem5q.js} +309 -463
  41. package/dist/uploader-abQoem5q.js.map +1 -0
  42. package/dist/uploader.cjs +1 -1
  43. package/dist/uploader.js +5 -4
  44. package/dist/uploader.js.map +1 -1
  45. package/dist/utils/markdown.d.ts +108 -0
  46. package/package.json +13 -5
  47. package/dist/display-8HEcKYR4.js.map +0 -1
  48. package/dist/display-CLDNNZQy.cjs.map +0 -1
  49. package/dist/uploader-D-Da1trc.js.map +0 -1
  50. package/dist/uploader-eFYKpk8b.cjs.map +0 -1
  51. /package/dist/elements/{base.d.ts → authui-base.d.ts} +0 -0
@@ -0,0 +1,3001 @@
1
+ "use strict";var mt=Object.defineProperty;var We=o=>{throw TypeError(o)};var bt=(o,n,e)=>n in o?mt(o,n,{enumerable:!0,configurable:!0,writable:!0,value:e}):o[n]=e;var k=(o,n,e)=>bt(o,typeof n!="symbol"?n+"":n,e),qe=(o,n,e)=>n.has(o)||We("Cannot "+e);var d=(o,n,e)=>(qe(o,n,"read from private field"),e?e.call(o):n.get(o)),p=(o,n,e)=>n.has(o)?We("Cannot add the same private member more than once"):n instanceof WeakSet?n.add(o):n.set(o,e),h=(o,n,e,t)=>(qe(o,n,"write to private field"),t?t.call(o,e):n.set(o,e),e);const s=require("lit"),u=require("lit/decorators.js"),ft=require("lit/directives/repeat.js"),xt=require("@singlebase/core"),$=require("./files-DW8A4Jl-.cjs");if(typeof CSS<"u"&&"registerProperty"in CSS)try{CSS.registerProperty({name:"--sb-ai-angle",syntax:"<angle>",inherits:!1,initialValue:"0deg"})}catch{}const vt=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: var(--sb-radius, 4px);
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-note {
464
+ font-size: 12.5px;
465
+ color: var(--c-muted);
466
+ padding: 6px 10px;
467
+ }
468
+
469
+ .skeleton {
470
+ height: 28px;
471
+ margin: 3px 0;
472
+ border-radius: var(--c-r2);
473
+ background: linear-gradient(90deg, var(--c-hover) 0%, var(--c-line2) 50%, var(--c-hover) 100%);
474
+ background-size: 200% 100%;
475
+ animation: aiShimmer 1.6s linear infinite;
476
+ }
477
+
478
+ /* ── main column ──────────────────────────────────────── */
479
+
480
+ .main {
481
+ container: chat / inline-size;
482
+ position: relative;
483
+ flex: 1;
484
+ min-width: 0;
485
+ min-height: 0;
486
+ display: flex;
487
+ flex-direction: column;
488
+ }
489
+
490
+ .header {
491
+ display: flex;
492
+ align-items: center;
493
+ justify-content: space-between;
494
+ gap: 12px;
495
+ min-height: 52px;
496
+ padding: 10px 8px 10px 12px;
497
+ border-bottom: 1px solid var(--c-line);
498
+ }
499
+
500
+ .header-left {
501
+ display: flex;
502
+ align-items: center;
503
+ gap: 10px;
504
+ min-width: 0;
505
+ }
506
+
507
+ .header-right {
508
+ flex: 0 0 auto;
509
+ display: flex;
510
+ align-items: center;
511
+ gap: 2px;
512
+ }
513
+
514
+ .title {
515
+ min-width: 0;
516
+ font-size: 14px;
517
+ font-weight: 600;
518
+ letter-spacing: -0.01em;
519
+ overflow: hidden;
520
+ text-overflow: ellipsis;
521
+ white-space: nowrap;
522
+ background: none;
523
+ border: none;
524
+ padding: 2px 4px;
525
+ border-radius: var(--c-r);
526
+ cursor: text;
527
+ animation: aiIn 0.25s ease-out;
528
+ }
529
+
530
+ .title:hover:not(:disabled) {
531
+ background: var(--c-hover);
532
+ }
533
+
534
+ .title:disabled {
535
+ cursor: default;
536
+ }
537
+
538
+ .title-input {
539
+ min-width: 0;
540
+ width: 320px;
541
+ max-width: 100%;
542
+ font: inherit;
543
+ font-size: 14px;
544
+ font-weight: 600;
545
+ color: var(--c-ink);
546
+ background: var(--c-bg);
547
+ border: 1px solid var(--c-ink);
548
+ border-radius: var(--c-r);
549
+ padding: 2px 6px;
550
+ outline: none;
551
+ }
552
+
553
+ .divider {
554
+ width: 1px;
555
+ height: 18px;
556
+ background: var(--c-line);
557
+ margin: 0 4px;
558
+ }
559
+
560
+ .menu-wrap {
561
+ position: relative;
562
+ }
563
+
564
+ .menu-scrim {
565
+ position: fixed;
566
+ inset: 0;
567
+ z-index: 40;
568
+ }
569
+
570
+ .menu {
571
+ position: absolute;
572
+ right: 0;
573
+ top: 34px;
574
+ z-index: 41;
575
+ width: 220px;
576
+ display: flex;
577
+ flex-direction: column;
578
+ padding: 4px;
579
+ background: var(--c-bg);
580
+ border: 1px solid var(--c-line);
581
+ border-radius: var(--c-r2);
582
+ box-shadow: 0 12px 32px -12px rgba(22, 24, 26, 0.22);
583
+ animation: aiIn 0.15s ease-out;
584
+ }
585
+
586
+ .menu .label {
587
+ font-size: 10.5px;
588
+ padding: 8px 10px 6px;
589
+ }
590
+
591
+ .menu-item {
592
+ display: flex;
593
+ align-items: baseline;
594
+ justify-content: space-between;
595
+ gap: 10px;
596
+ width: 100%;
597
+ text-align: left;
598
+ font-size: 13px;
599
+ background: none;
600
+ border: none;
601
+ border-radius: var(--c-r);
602
+ padding: 8px 10px;
603
+ cursor: pointer;
604
+ }
605
+
606
+ .menu-item:hover {
607
+ background: var(--c-hover);
608
+ }
609
+
610
+ .menu-item .ext {
611
+ font-family: var(--c-mono);
612
+ font-size: 11px;
613
+ color: var(--c-muted);
614
+ }
615
+
616
+ .scroller {
617
+ position: relative;
618
+ flex: 1;
619
+ min-height: 0;
620
+ overflow-y: auto;
621
+ }
622
+
623
+ .banner {
624
+ margin: 10px 16px 0;
625
+ padding: 8px 12px;
626
+ font-size: 12.5px;
627
+ color: var(--c-ink2);
628
+ background: var(--c-bg2);
629
+ border: 1px solid var(--c-line);
630
+ border-radius: var(--c-r2);
631
+ }
632
+
633
+ /* ── welcome ──────────────────────────────────────────── */
634
+
635
+ .welcome {
636
+ max-width: 640px;
637
+ min-height: 100%;
638
+ margin: 0 auto;
639
+ display: flex;
640
+ flex-direction: column;
641
+ justify-content: center;
642
+ gap: 20px;
643
+ padding: 28px 18px;
644
+ }
645
+
646
+ .welcome-head {
647
+ display: flex;
648
+ flex-direction: column;
649
+ gap: 8px;
650
+ }
651
+
652
+ .welcome-logo {
653
+ width: 32px;
654
+ height: 32px;
655
+ object-fit: contain;
656
+ border-radius: var(--c-r2);
657
+ }
658
+
659
+ .welcome h2 {
660
+ margin: 0;
661
+ font-size: 24px;
662
+ font-weight: 600;
663
+ letter-spacing: -0.01em;
664
+ }
665
+
666
+ .welcome p {
667
+ margin: 0;
668
+ font-size: 14px;
669
+ line-height: 1.55;
670
+ color: var(--c-muted);
671
+ text-wrap: pretty;
672
+ }
673
+
674
+ .prompts {
675
+ display: grid;
676
+ grid-template-columns: repeat(2, minmax(0, 1fr));
677
+ gap: 8px;
678
+ }
679
+
680
+ .prompt {
681
+ display: flex;
682
+ flex-direction: column;
683
+ gap: 4px;
684
+ text-align: left;
685
+ background: var(--c-bg);
686
+ border: 1px solid var(--c-line);
687
+ border-radius: var(--c-r2);
688
+ padding: 12px 14px;
689
+ cursor: pointer;
690
+ transition:
691
+ border-color 0.15s,
692
+ box-shadow 0.15s;
693
+ }
694
+
695
+ .prompt:hover {
696
+ border-color: var(--c-ink);
697
+ box-shadow: 0 6px 18px -10px rgba(22, 24, 26, 0.25);
698
+ }
699
+
700
+ .prompt .label {
701
+ font-size: 10.5px;
702
+ letter-spacing: 0.06em;
703
+ }
704
+
705
+ .prompt-text {
706
+ font-size: 13.5px;
707
+ font-weight: 500;
708
+ line-height: 1.4;
709
+ }
710
+
711
+ @container chat (max-width: 480px) {
712
+ .prompts {
713
+ grid-template-columns: minmax(0, 1fr);
714
+ }
715
+ }
716
+
717
+ /* ── messages ─────────────────────────────────────────── */
718
+
719
+ .thread-view {
720
+ max-width: 760px;
721
+ margin: 0 auto;
722
+ display: flex;
723
+ flex-direction: column;
724
+ gap: 30px;
725
+ padding: 20px 16px 28px;
726
+ }
727
+
728
+ .msg {
729
+ position: relative;
730
+ display: flex;
731
+ flex-direction: column;
732
+ border-radius: var(--c-r3);
733
+ }
734
+
735
+ .msg.user {
736
+ align-self: flex-end;
737
+ max-width: 80%;
738
+ align-items: flex-end;
739
+ gap: 6px;
740
+ margin-bottom: -22px;
741
+ animation: aiIn 0.25s ease-out;
742
+ }
743
+
744
+ .bubble-user {
745
+ padding: 10px 14px;
746
+ font-size: 14.5px;
747
+ line-height: 1.6;
748
+ white-space: pre-wrap;
749
+ overflow-wrap: anywhere;
750
+ background: var(--c-hover);
751
+ border-radius: calc(var(--c-r) * 2.5) calc(var(--c-r) * 2.5) 2px calc(var(--c-r) * 2.5);
752
+ }
753
+
754
+ .attachments {
755
+ display: flex;
756
+ flex-wrap: wrap;
757
+ justify-content: flex-end;
758
+ gap: 6px;
759
+ }
760
+
761
+ .doc-chip {
762
+ display: inline-flex;
763
+ align-items: center;
764
+ gap: 8px;
765
+ padding: 6px 10px;
766
+ font-size: 12.5px;
767
+ border-radius: var(--c-r2);
768
+ border: 1px solid var(--c-line);
769
+ background: var(--c-bg);
770
+ }
771
+
772
+ .doc-chip .ext {
773
+ font-family: var(--c-mono);
774
+ font-size: 10px;
775
+ letter-spacing: 0.04em;
776
+ color: var(--c-muted);
777
+ }
778
+
779
+ .doc-chip .name {
780
+ max-width: 180px;
781
+ overflow: hidden;
782
+ text-overflow: ellipsis;
783
+ white-space: nowrap;
784
+ }
785
+
786
+ .toolbar {
787
+ display: flex;
788
+ align-items: center;
789
+ gap: 2px;
790
+ opacity: 0;
791
+ transition: opacity 0.15s;
792
+ }
793
+
794
+ .msg:hover .toolbar,
795
+ .msg:focus-within .toolbar,
796
+ .toolbar.pinned {
797
+ opacity: 1;
798
+ }
799
+
800
+ @media (hover: none) {
801
+ .toolbar {
802
+ opacity: 1;
803
+ }
804
+ }
805
+
806
+ .msg.bot .toolbar {
807
+ margin-left: -6px;
808
+ }
809
+
810
+ .time {
811
+ font-family: var(--c-mono);
812
+ font-size: 11px;
813
+ color: var(--c-faint);
814
+ padding: 0 6px;
815
+ font-variant-numeric: tabular-nums;
816
+ }
817
+
818
+ .note {
819
+ font-size: 12px;
820
+ color: var(--c-muted);
821
+ }
822
+
823
+ .spacer {
824
+ flex: 1;
825
+ }
826
+
827
+ .saved {
828
+ display: inline-flex;
829
+ align-items: center;
830
+ gap: 4px;
831
+ font-family: var(--c-mono);
832
+ font-size: 10.5px;
833
+ letter-spacing: 0.05em;
834
+ text-transform: uppercase;
835
+ color: var(--c-ink);
836
+ }
837
+
838
+ .saved svg {
839
+ width: 12px;
840
+ height: 12px;
841
+ fill: currentColor;
842
+ stroke: currentColor;
843
+ stroke-width: 1.5;
844
+ }
845
+
846
+ .bot-body {
847
+ position: relative;
848
+ z-index: 1;
849
+ display: flex;
850
+ flex-direction: column;
851
+ gap: 12px;
852
+ }
853
+
854
+ .edit-box {
855
+ width: 440px;
856
+ max-width: 100%;
857
+ display: flex;
858
+ flex-direction: column;
859
+ gap: 8px;
860
+ padding: 8px;
861
+ border: 1px solid var(--c-ink);
862
+ border-radius: var(--c-r3);
863
+ background: var(--c-bg);
864
+ }
865
+
866
+ .edit-box textarea {
867
+ width: 100%;
868
+ resize: vertical;
869
+ font: inherit;
870
+ font-size: 14px;
871
+ line-height: 1.5;
872
+ color: var(--c-ink);
873
+ background: transparent;
874
+ border: none;
875
+ outline: none;
876
+ padding: 4px;
877
+ }
878
+
879
+ .row-end {
880
+ display: flex;
881
+ justify-content: flex-end;
882
+ gap: 8px;
883
+ }
884
+
885
+ .btn {
886
+ font-size: 12.5px;
887
+ font-weight: 500;
888
+ border-radius: var(--c-r);
889
+ padding: 6px 12px;
890
+ cursor: pointer;
891
+ background: transparent;
892
+ color: var(--c-muted);
893
+ border: 1px solid var(--c-line);
894
+ }
895
+
896
+ .btn:hover {
897
+ color: var(--c-ink);
898
+ background: var(--c-bg2);
899
+ }
900
+
901
+ .btn.primary {
902
+ background: var(--c-brand);
903
+ color: var(--c-on-brand);
904
+ border-color: var(--c-brand);
905
+ }
906
+
907
+ .btn.primary:hover {
908
+ filter: brightness(1.2);
909
+ }
910
+
911
+ .error-card {
912
+ display: flex;
913
+ align-items: center;
914
+ justify-content: space-between;
915
+ gap: 12px;
916
+ padding: 10px 12px;
917
+ font-size: 13px;
918
+ color: var(--c-danger);
919
+ border: 1px solid var(--sb-danger-border, #f3d6d3);
920
+ background: var(--sb-danger-bg, #fdf1f0);
921
+ border-radius: var(--c-r2);
922
+ }
923
+
924
+ .followups {
925
+ display: flex;
926
+ flex-direction: column;
927
+ align-items: flex-start;
928
+ gap: 6px;
929
+ }
930
+
931
+ .followup {
932
+ display: inline-flex;
933
+ align-items: baseline;
934
+ gap: 8px;
935
+ text-align: left;
936
+ font-size: 13px;
937
+ background: var(--c-bg);
938
+ border: 1px solid var(--c-line);
939
+ border-radius: var(--c-r2);
940
+ padding: 6px 12px;
941
+ cursor: pointer;
942
+ animation: aiIn 0.25s ease-out;
943
+ }
944
+
945
+ .followup:hover {
946
+ background: var(--c-hover);
947
+ }
948
+
949
+ .followup .arrow {
950
+ font-family: var(--c-mono);
951
+ color: var(--c-muted);
952
+ }
953
+
954
+ .jump {
955
+ position: absolute;
956
+ left: 50%;
957
+ bottom: 8px;
958
+ transform: translateX(-50%);
959
+ z-index: 5;
960
+ font-size: 12.5px;
961
+ font-weight: 500;
962
+ color: var(--c-on-brand);
963
+ background: var(--c-brand);
964
+ border: none;
965
+ border-radius: 999px;
966
+ padding: 6px 14px;
967
+ cursor: pointer;
968
+ box-shadow: 0 8px 20px -10px rgba(22, 24, 26, 0.4);
969
+ animation: aiIn 0.2s ease-out;
970
+ }
971
+
972
+ /* ── rendered answer ──────────────────────────────────── */
973
+
974
+ .answer {
975
+ display: flex;
976
+ flex-direction: column;
977
+ gap: 14px;
978
+ font-size: 14.5px;
979
+ line-height: 1.7;
980
+ }
981
+
982
+ .answer p {
983
+ margin: 0;
984
+ text-wrap: pretty;
985
+ overflow-wrap: anywhere;
986
+ }
987
+
988
+ .answer .raw {
989
+ white-space: pre-wrap;
990
+ }
991
+
992
+ .answer h3 {
993
+ margin: 6px 0 0;
994
+ font-size: 15.5px;
995
+ font-weight: 600;
996
+ letter-spacing: -0.01em;
997
+ line-height: 1.4;
998
+ }
999
+
1000
+ .answer ul,
1001
+ .answer ol {
1002
+ margin: 0;
1003
+ padding-left: 20px;
1004
+ display: flex;
1005
+ flex-direction: column;
1006
+ gap: 6px;
1007
+ }
1008
+
1009
+ .answer li {
1010
+ line-height: 1.65;
1011
+ padding-left: 2px;
1012
+ }
1013
+
1014
+ .answer strong {
1015
+ font-weight: 600;
1016
+ }
1017
+
1018
+ .answer a {
1019
+ color: var(--c-ink);
1020
+ text-underline-offset: 3px;
1021
+ }
1022
+
1023
+ .answer code.inline {
1024
+ font-family: var(--c-mono);
1025
+ font-size: 12.5px;
1026
+ background: var(--c-hover);
1027
+ border-radius: calc(var(--c-r) * 0.75);
1028
+ padding: 1px 5px;
1029
+ }
1030
+
1031
+ .quote {
1032
+ font-size: 13.5px;
1033
+ line-height: 1.6;
1034
+ color: var(--c-ink2);
1035
+ background: var(--c-bg2);
1036
+ border: 1px solid var(--c-line);
1037
+ border-radius: var(--c-r2);
1038
+ padding: 10px 14px;
1039
+ }
1040
+
1041
+ .code {
1042
+ border: 1px solid var(--c-line);
1043
+ border-radius: var(--c-r2);
1044
+ overflow: hidden;
1045
+ background: var(--c-bg2);
1046
+ }
1047
+
1048
+ .code-head {
1049
+ display: flex;
1050
+ align-items: center;
1051
+ justify-content: space-between;
1052
+ padding: 7px 12px;
1053
+ border-bottom: 1px solid var(--c-line);
1054
+ }
1055
+
1056
+ .code-head .label {
1057
+ font-size: 11px;
1058
+ }
1059
+
1060
+ .text-btn {
1061
+ font-size: 12px;
1062
+ color: var(--c-muted);
1063
+ background: none;
1064
+ border: none;
1065
+ padding: 0;
1066
+ cursor: pointer;
1067
+ }
1068
+
1069
+ .text-btn:hover {
1070
+ color: var(--c-ink);
1071
+ }
1072
+
1073
+ .text-btn.underline {
1074
+ text-decoration: underline;
1075
+ text-underline-offset: 3px;
1076
+ }
1077
+
1078
+ .code pre {
1079
+ margin: 0;
1080
+ padding: 12px 14px;
1081
+ overflow-x: auto;
1082
+ font-family: var(--c-mono);
1083
+ font-size: 13px;
1084
+ line-height: 1.6;
1085
+ }
1086
+
1087
+ .table {
1088
+ border: 1px solid var(--c-line);
1089
+ border-radius: var(--c-r2);
1090
+ overflow-x: auto;
1091
+ }
1092
+
1093
+ .table table {
1094
+ width: 100%;
1095
+ border-collapse: collapse;
1096
+ font-size: 13px;
1097
+ font-variant-numeric: tabular-nums;
1098
+ }
1099
+
1100
+ .table th {
1101
+ text-align: left;
1102
+ font-size: 12px;
1103
+ font-weight: 500;
1104
+ color: var(--c-muted);
1105
+ background: var(--c-bg2);
1106
+ border-bottom: 1px solid var(--c-line);
1107
+ padding: 9px 12px;
1108
+ white-space: nowrap;
1109
+ }
1110
+
1111
+ .table td {
1112
+ padding: 9px 12px;
1113
+ border-top: 1px solid var(--c-line2);
1114
+ white-space: nowrap;
1115
+ }
1116
+
1117
+ .table th:first-child,
1118
+ .table td:first-child {
1119
+ min-width: 120px;
1120
+ }
1121
+
1122
+ .cite {
1123
+ display: inline-flex;
1124
+ align-items: center;
1125
+ justify-content: center;
1126
+ min-width: 17px;
1127
+ height: 17px;
1128
+ padding: 0 4px;
1129
+ margin: 0 1px 0 3px;
1130
+ vertical-align: 2px;
1131
+ font: 500 10px var(--c-mono);
1132
+ border-radius: calc(var(--c-r) * 0.75);
1133
+ cursor: pointer;
1134
+ border: 1px solid var(--c-strong);
1135
+ background: var(--c-hover);
1136
+ color: var(--c-ink);
1137
+ }
1138
+
1139
+ .cite:hover,
1140
+ .cite.active {
1141
+ background: var(--c-ink);
1142
+ color: var(--c-bg);
1143
+ border-color: var(--c-ink);
1144
+ }
1145
+
1146
+ .chart {
1147
+ margin: 0;
1148
+ display: flex;
1149
+ flex-direction: column;
1150
+ gap: 14px;
1151
+ border: 1px solid var(--c-line);
1152
+ border-radius: var(--c-r2);
1153
+ padding: 14px 16px 12px;
1154
+ background: var(--c-bg);
1155
+ }
1156
+
1157
+ .chart-head {
1158
+ display: flex;
1159
+ flex-wrap: wrap;
1160
+ align-items: baseline;
1161
+ justify-content: space-between;
1162
+ gap: 8px 16px;
1163
+ }
1164
+
1165
+ .chart-title {
1166
+ font-size: 13px;
1167
+ font-weight: 600;
1168
+ }
1169
+
1170
+ .legend {
1171
+ display: flex;
1172
+ flex-wrap: wrap;
1173
+ gap: 4px 12px;
1174
+ }
1175
+
1176
+ .legend span {
1177
+ display: inline-flex;
1178
+ align-items: center;
1179
+ gap: 6px;
1180
+ font-size: 12px;
1181
+ color: var(--c-ink2);
1182
+ }
1183
+
1184
+ .swatch {
1185
+ width: 8px;
1186
+ height: 8px;
1187
+ border-radius: 2px;
1188
+ }
1189
+
1190
+ .bars {
1191
+ display: flex;
1192
+ flex-direction: column;
1193
+ gap: 10px;
1194
+ }
1195
+
1196
+ .bar-row {
1197
+ display: grid;
1198
+ grid-template-columns: 92px minmax(0, 1fr) 64px;
1199
+ align-items: center;
1200
+ gap: 12px;
1201
+ }
1202
+
1203
+ .bar-label {
1204
+ font-size: 12.5px;
1205
+ color: var(--c-ink2);
1206
+ overflow: hidden;
1207
+ text-overflow: ellipsis;
1208
+ white-space: nowrap;
1209
+ }
1210
+
1211
+ .bar-track {
1212
+ display: flex;
1213
+ height: 12px;
1214
+ background: var(--c-hover);
1215
+ border-radius: 2px;
1216
+ overflow: hidden;
1217
+ }
1218
+
1219
+ .bar-fill {
1220
+ display: flex;
1221
+ height: 100%;
1222
+ transform-origin: left;
1223
+ animation: aiGrow 0.8s cubic-bezier(0.2, 0.8, 0.2, 1);
1224
+ }
1225
+
1226
+ .bar-value {
1227
+ font-family: var(--c-mono);
1228
+ font-size: 11.5px;
1229
+ text-align: right;
1230
+ font-variant-numeric: tabular-nums;
1231
+ }
1232
+
1233
+ .line-chart {
1234
+ display: flex;
1235
+ flex-direction: column;
1236
+ gap: 6px;
1237
+ padding-left: 48px;
1238
+ }
1239
+
1240
+ .plot {
1241
+ position: relative;
1242
+ height: 170px;
1243
+ }
1244
+
1245
+ .tick {
1246
+ position: absolute;
1247
+ left: 0;
1248
+ right: 0;
1249
+ border-top: 1px dashed var(--c-line2);
1250
+ }
1251
+
1252
+ .tick.base {
1253
+ border-top: 1px solid var(--c-strong);
1254
+ }
1255
+
1256
+ .tick span,
1257
+ .x-labels span {
1258
+ font-family: var(--c-mono);
1259
+ font-size: 10.5px;
1260
+ color: var(--c-faint);
1261
+ white-space: nowrap;
1262
+ font-variant-numeric: tabular-nums;
1263
+ }
1264
+
1265
+ .tick span {
1266
+ position: absolute;
1267
+ right: calc(100% + 8px);
1268
+ top: -7px;
1269
+ }
1270
+
1271
+ .plot svg {
1272
+ position: absolute;
1273
+ inset: 0;
1274
+ width: 100%;
1275
+ height: 100%;
1276
+ overflow: visible;
1277
+ }
1278
+
1279
+ .plot polyline {
1280
+ fill: none;
1281
+ stroke-width: 2;
1282
+ vector-effect: non-scaling-stroke;
1283
+ stroke-linejoin: round;
1284
+ stroke-linecap: round;
1285
+ stroke-dasharray: 1;
1286
+ animation: aiDraw 1s ease-out;
1287
+ }
1288
+
1289
+ .x-labels {
1290
+ display: flex;
1291
+ justify-content: space-between;
1292
+ gap: 4px;
1293
+ }
1294
+
1295
+ .chart-pending {
1296
+ display: flex;
1297
+ align-items: center;
1298
+ justify-content: center;
1299
+ height: 190px;
1300
+ border: 1px solid var(--c-line);
1301
+ border-radius: var(--c-r2);
1302
+ background: linear-gradient(90deg, var(--c-bg2) 0%, var(--c-hover) 50%, var(--c-bg2) 100%);
1303
+ background-size: 200% 100%;
1304
+ animation: aiShimmer 1.6s linear infinite;
1305
+ }
1306
+
1307
+ .gallery {
1308
+ display: grid;
1309
+ grid-template-columns: minmax(0, 1fr);
1310
+ gap: 10px;
1311
+ max-width: 520px;
1312
+ }
1313
+
1314
+ .gallery.many {
1315
+ grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
1316
+ max-width: 100%;
1317
+ }
1318
+
1319
+ .gallery figure {
1320
+ margin: 0;
1321
+ display: flex;
1322
+ flex-direction: column;
1323
+ gap: 6px;
1324
+ min-width: 0;
1325
+ }
1326
+
1327
+ .gallery img {
1328
+ width: 100%;
1329
+ aspect-ratio: 16 / 10;
1330
+ max-height: 320px;
1331
+ object-fit: contain;
1332
+ border-radius: var(--c-r2);
1333
+ border: 1px solid var(--c-line);
1334
+ background: var(--c-bg2);
1335
+ }
1336
+
1337
+ .img-missing {
1338
+ aspect-ratio: 16 / 9;
1339
+ display: flex;
1340
+ align-items: center;
1341
+ justify-content: center;
1342
+ border-radius: var(--c-r2);
1343
+ border: 1px dashed var(--c-strong);
1344
+ background: repeating-linear-gradient(135deg, var(--c-bg2) 0 10px, var(--c-hover) 10px 20px);
1345
+ }
1346
+
1347
+ figcaption {
1348
+ font-family: var(--c-mono);
1349
+ font-size: 11px;
1350
+ color: var(--c-muted);
1351
+ overflow: hidden;
1352
+ text-overflow: ellipsis;
1353
+ white-space: nowrap;
1354
+ }
1355
+
1356
+ .caret {
1357
+ display: inline-block;
1358
+ width: 7px;
1359
+ height: 15px;
1360
+ margin-top: -6px;
1361
+ background: var(--c-brand);
1362
+ animation: rgcaret 1s steps(1) infinite;
1363
+ }
1364
+
1365
+ /* ── sources ──────────────────────────────────────────── */
1366
+
1367
+ .retrieval {
1368
+ display: flex;
1369
+ flex-direction: column;
1370
+ border: 1px solid var(--c-line);
1371
+ border-radius: var(--c-r2);
1372
+ background: var(--c-bg2);
1373
+ }
1374
+
1375
+ .retrieval-toggle {
1376
+ display: flex;
1377
+ align-items: center;
1378
+ gap: 10px;
1379
+ width: 100%;
1380
+ text-align: left;
1381
+ font-size: 12.5px;
1382
+ color: var(--c-ink2);
1383
+ background: none;
1384
+ border: none;
1385
+ padding: 9px 12px;
1386
+ cursor: pointer;
1387
+ }
1388
+
1389
+ .retrieval-toggle .chev,
1390
+ .retrieval-toggle .ms {
1391
+ font-family: var(--c-mono);
1392
+ font-size: 11px;
1393
+ color: var(--c-muted);
1394
+ }
1395
+
1396
+ .retrieval-list {
1397
+ display: flex;
1398
+ flex-direction: column;
1399
+ border-top: 1px solid var(--c-line);
1400
+ padding: 4px 12px;
1401
+ }
1402
+
1403
+ .passage {
1404
+ display: grid;
1405
+ grid-template-columns: 22px minmax(0, 1fr) 64px;
1406
+ align-items: center;
1407
+ gap: 10px;
1408
+ width: 100%;
1409
+ text-align: left;
1410
+ background: none;
1411
+ border: none;
1412
+ border-bottom: 1px solid var(--c-line2);
1413
+ padding: 8px 0;
1414
+ cursor: pointer;
1415
+ }
1416
+
1417
+ .passage:last-child {
1418
+ border-bottom: none;
1419
+ }
1420
+
1421
+ .passage .n,
1422
+ .passage .score {
1423
+ font-family: var(--c-mono);
1424
+ font-size: 11px;
1425
+ color: var(--c-muted);
1426
+ font-variant-numeric: tabular-nums;
1427
+ }
1428
+
1429
+ .passage .what {
1430
+ display: flex;
1431
+ flex-direction: column;
1432
+ gap: 1px;
1433
+ min-width: 0;
1434
+ }
1435
+
1436
+ .passage .what span:first-child {
1437
+ font-size: 12.5px;
1438
+ overflow: hidden;
1439
+ text-overflow: ellipsis;
1440
+ white-space: nowrap;
1441
+ }
1442
+
1443
+ .passage .what span:last-child {
1444
+ font-size: 11.5px;
1445
+ color: var(--c-muted);
1446
+ }
1447
+
1448
+ .relevance {
1449
+ display: flex;
1450
+ flex-direction: column;
1451
+ gap: 3px;
1452
+ align-items: flex-end;
1453
+ }
1454
+
1455
+ .relevance-track {
1456
+ width: 64px;
1457
+ height: 3px;
1458
+ background: var(--c-line);
1459
+ border-radius: 99px;
1460
+ overflow: hidden;
1461
+ }
1462
+
1463
+ .relevance-fill {
1464
+ display: block;
1465
+ height: 100%;
1466
+ background: var(--c-brand);
1467
+ }
1468
+
1469
+ .cards {
1470
+ display: flex;
1471
+ flex-direction: column;
1472
+ gap: 8px;
1473
+ }
1474
+
1475
+ .card-grid {
1476
+ display: grid;
1477
+ grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
1478
+ gap: 8px;
1479
+ }
1480
+
1481
+ .source-card {
1482
+ display: flex;
1483
+ flex-direction: column;
1484
+ gap: 6px;
1485
+ min-width: 0;
1486
+ text-align: left;
1487
+ padding: 10px 12px;
1488
+ border-radius: var(--c-r2);
1489
+ cursor: pointer;
1490
+ background: var(--c-bg);
1491
+ border: 1px solid var(--c-line);
1492
+ }
1493
+
1494
+ .source-card:hover,
1495
+ .source-card.active {
1496
+ border-color: var(--c-ink);
1497
+ }
1498
+
1499
+ .source-card .top {
1500
+ display: flex;
1501
+ align-items: center;
1502
+ gap: 8px;
1503
+ min-width: 0;
1504
+ }
1505
+
1506
+ .num {
1507
+ min-width: 16px;
1508
+ height: 16px;
1509
+ padding: 0 4px;
1510
+ border-radius: calc(var(--c-r) * 0.75);
1511
+ border: 1px solid var(--c-strong);
1512
+ display: inline-flex;
1513
+ align-items: center;
1514
+ justify-content: center;
1515
+ font-family: var(--c-mono);
1516
+ font-size: 10px;
1517
+ background: var(--c-bg);
1518
+ }
1519
+
1520
+ .source-card .t {
1521
+ font-size: 13px;
1522
+ font-weight: 500;
1523
+ overflow: hidden;
1524
+ text-overflow: ellipsis;
1525
+ white-space: nowrap;
1526
+ }
1527
+
1528
+ .source-card .s {
1529
+ font-size: 12px;
1530
+ line-height: 1.45;
1531
+ color: var(--c-muted);
1532
+ display: -webkit-box;
1533
+ -webkit-line-clamp: 2;
1534
+ -webkit-box-orient: vertical;
1535
+ overflow: hidden;
1536
+ }
1537
+
1538
+ .panel {
1539
+ display: flex;
1540
+ flex-direction: column;
1541
+ min-height: 0;
1542
+ min-width: 0;
1543
+ background: var(--c-bg);
1544
+ border-left: 1px solid var(--c-line);
1545
+ animation: aiIn 0.15s ease-out;
1546
+ }
1547
+
1548
+ .panel.docked {
1549
+ position: relative;
1550
+ flex: 0 0 400px;
1551
+ width: 400px;
1552
+ }
1553
+
1554
+ .panel.overlay {
1555
+ position: absolute;
1556
+ right: 0;
1557
+ top: 0;
1558
+ bottom: 0;
1559
+ z-index: 30;
1560
+ width: min(420px, 100%);
1561
+ box-shadow: -12px 0 32px -16px rgba(22, 24, 26, 0.25);
1562
+ }
1563
+
1564
+ .panel-head {
1565
+ display: flex;
1566
+ align-items: center;
1567
+ justify-content: space-between;
1568
+ gap: 8px;
1569
+ padding: 14px 18px;
1570
+ border-bottom: 1px solid var(--c-line);
1571
+ }
1572
+
1573
+ .panel-body {
1574
+ flex: 1;
1575
+ min-height: 0;
1576
+ overflow-y: auto;
1577
+ display: flex;
1578
+ flex-direction: column;
1579
+ gap: 16px;
1580
+ padding: 18px;
1581
+ }
1582
+
1583
+ .panel-body h3 {
1584
+ margin: 0;
1585
+ font-size: 16px;
1586
+ font-weight: 600;
1587
+ letter-spacing: -0.01em;
1588
+ }
1589
+
1590
+ .panel-meta {
1591
+ display: flex;
1592
+ flex-direction: column;
1593
+ gap: 4px;
1594
+ }
1595
+
1596
+ .panel-meta .path {
1597
+ font-family: var(--c-mono);
1598
+ font-size: 11px;
1599
+ color: var(--c-muted);
1600
+ overflow-wrap: anywhere;
1601
+ }
1602
+
1603
+ .panel-meta .meta {
1604
+ font-size: 12px;
1605
+ color: var(--c-muted);
1606
+ }
1607
+
1608
+ .passage-box {
1609
+ display: flex;
1610
+ flex-direction: column;
1611
+ gap: 8px;
1612
+ padding: 12px 14px;
1613
+ border-radius: var(--c-r2);
1614
+ background: var(--c-hover);
1615
+ border: 1px solid var(--c-strong);
1616
+ }
1617
+
1618
+ .passage-box .text {
1619
+ font-size: 13px;
1620
+ line-height: 1.6;
1621
+ color: var(--c-ink2);
1622
+ white-space: pre-wrap;
1623
+ overflow-wrap: anywhere;
1624
+ }
1625
+
1626
+ .passage-foot {
1627
+ display: flex;
1628
+ align-items: center;
1629
+ justify-content: space-between;
1630
+ gap: 8px;
1631
+ padding-top: 8px;
1632
+ border-top: 1px solid var(--c-line);
1633
+ }
1634
+
1635
+ .copy-ref {
1636
+ display: inline-flex;
1637
+ align-items: center;
1638
+ gap: 6px;
1639
+ font-size: 12px;
1640
+ background: var(--c-bg);
1641
+ border: 1px solid var(--c-line);
1642
+ border-radius: var(--c-r);
1643
+ padding: 4px 8px;
1644
+ cursor: pointer;
1645
+ }
1646
+
1647
+ .copy-ref:hover {
1648
+ border-color: var(--c-strong);
1649
+ }
1650
+
1651
+ .panel-foot {
1652
+ display: flex;
1653
+ flex-direction: column;
1654
+ gap: 6px;
1655
+ padding: 12px 18px 16px;
1656
+ border-top: 1px solid var(--c-line);
1657
+ }
1658
+
1659
+ .chips {
1660
+ display: flex;
1661
+ flex-wrap: wrap;
1662
+ gap: 6px;
1663
+ }
1664
+
1665
+ .chip {
1666
+ font-size: 12px;
1667
+ background: var(--c-bg);
1668
+ border: 1px solid var(--c-line);
1669
+ border-radius: var(--c-r);
1670
+ padding: 4px 8px;
1671
+ cursor: pointer;
1672
+ max-width: 100%;
1673
+ overflow: hidden;
1674
+ text-overflow: ellipsis;
1675
+ white-space: nowrap;
1676
+ }
1677
+
1678
+ .chip:hover {
1679
+ border-color: var(--c-ink);
1680
+ }
1681
+
1682
+ /* ── composer ─────────────────────────────────────────── */
1683
+
1684
+ .composer-wrap {
1685
+ padding: 0 12px 12px;
1686
+ }
1687
+
1688
+ .composer-col {
1689
+ max-width: 760px;
1690
+ margin: 0 auto;
1691
+ display: flex;
1692
+ flex-direction: column;
1693
+ gap: 8px;
1694
+ }
1695
+
1696
+ .composer-box {
1697
+ position: relative;
1698
+ }
1699
+
1700
+ .composer {
1701
+ position: relative;
1702
+ z-index: 1;
1703
+ display: flex;
1704
+ flex-direction: column;
1705
+ gap: 4px;
1706
+ padding: 8px;
1707
+ border-radius: calc(var(--c-r) * 2.25);
1708
+ background: var(--c-bg);
1709
+ border: 1px solid var(--c-strong);
1710
+ box-shadow:
1711
+ 0 1px 2px rgba(22, 24, 26, 0.04),
1712
+ 0 12px 32px -18px rgba(22, 24, 26, 0.22);
1713
+ transition: border-color 0.15s;
1714
+ }
1715
+
1716
+ .composer:focus-within {
1717
+ border-color: var(--c-ink);
1718
+ }
1719
+
1720
+ .composer.busy {
1721
+ border-color: transparent;
1722
+ }
1723
+
1724
+ :host([glow="off"]) .composer.busy {
1725
+ border-color: var(--c-strong);
1726
+ }
1727
+
1728
+ .composer textarea {
1729
+ width: 100%;
1730
+ resize: none;
1731
+ font: inherit;
1732
+ font-size: 14.5px;
1733
+ line-height: 1.5;
1734
+ color: var(--c-ink);
1735
+ background: transparent;
1736
+ border: none;
1737
+ outline: none;
1738
+ padding: 6px 6px 2px;
1739
+ max-height: 176px;
1740
+ }
1741
+
1742
+ .composer textarea::placeholder {
1743
+ color: var(--c-faint);
1744
+ }
1745
+
1746
+ .composer-row {
1747
+ display: flex;
1748
+ align-items: center;
1749
+ justify-content: space-between;
1750
+ gap: 8px;
1751
+ }
1752
+
1753
+ .attach {
1754
+ display: inline-flex;
1755
+ align-items: center;
1756
+ gap: 6px;
1757
+ font-size: 12.5px;
1758
+ color: var(--c-muted);
1759
+ background: none;
1760
+ border: none;
1761
+ border-radius: var(--c-r);
1762
+ padding: 6px 8px;
1763
+ cursor: pointer;
1764
+ }
1765
+
1766
+ .attach:hover {
1767
+ background: var(--c-hover);
1768
+ color: var(--c-ink);
1769
+ }
1770
+
1771
+ .send {
1772
+ display: inline-flex;
1773
+ align-items: center;
1774
+ justify-content: center;
1775
+ width: 32px;
1776
+ height: 32px;
1777
+ padding: 0;
1778
+ border-radius: var(--c-r2);
1779
+ border: 1px solid var(--c-brand);
1780
+ cursor: pointer;
1781
+ background: var(--c-brand);
1782
+ color: var(--c-on-brand);
1783
+ transition: background 0.15s;
1784
+ }
1785
+
1786
+ .send:disabled {
1787
+ cursor: default;
1788
+ background: var(--c-line);
1789
+ border-color: var(--c-line);
1790
+ color: var(--c-faint);
1791
+ }
1792
+
1793
+ .send.stop {
1794
+ background: var(--c-bg);
1795
+ color: var(--c-ink);
1796
+ border-color: var(--c-ink);
1797
+ }
1798
+
1799
+ .send.stop svg {
1800
+ fill: currentColor;
1801
+ stroke: none;
1802
+ }
1803
+
1804
+ .pending-files {
1805
+ display: flex;
1806
+ flex-wrap: wrap;
1807
+ gap: 6px;
1808
+ padding: 2px 2px 4px;
1809
+ }
1810
+
1811
+ .pending-file {
1812
+ display: inline-flex;
1813
+ align-items: center;
1814
+ gap: 8px;
1815
+ padding: 4px 8px 4px 4px;
1816
+ font-size: 12.5px;
1817
+ border-radius: var(--c-r2);
1818
+ border: 1px solid var(--c-line);
1819
+ background: var(--c-bg2);
1820
+ animation: aiIn 0.2s ease-out;
1821
+ }
1822
+
1823
+ .pending-file .ext {
1824
+ width: 28px;
1825
+ height: 28px;
1826
+ display: inline-flex;
1827
+ align-items: center;
1828
+ justify-content: center;
1829
+ border-radius: var(--c-r);
1830
+ background: var(--c-bg);
1831
+ border: 1px solid var(--c-line);
1832
+ font-family: var(--c-mono);
1833
+ font-size: 9px;
1834
+ letter-spacing: 0.03em;
1835
+ color: var(--c-muted);
1836
+ }
1837
+
1838
+ .pending-file .meta {
1839
+ display: flex;
1840
+ flex-direction: column;
1841
+ gap: 1px;
1842
+ min-width: 0;
1843
+ }
1844
+
1845
+ .pending-file .name {
1846
+ max-width: 160px;
1847
+ overflow: hidden;
1848
+ text-overflow: ellipsis;
1849
+ white-space: nowrap;
1850
+ }
1851
+
1852
+ .pending-file .size {
1853
+ font-family: var(--c-mono);
1854
+ font-size: 10.5px;
1855
+ color: var(--c-muted);
1856
+ }
1857
+
1858
+ .pending-file button {
1859
+ font-size: 15px;
1860
+ line-height: 1;
1861
+ color: var(--c-muted);
1862
+ background: none;
1863
+ border: none;
1864
+ padding: 0 0 0 2px;
1865
+ cursor: pointer;
1866
+ }
1867
+
1868
+ .pending-file button:hover {
1869
+ color: var(--c-danger);
1870
+ }
1871
+
1872
+ .footnote,
1873
+ .branding {
1874
+ text-align: center;
1875
+ font-size: 11.5px;
1876
+ color: var(--c-muted);
1877
+ }
1878
+
1879
+ .branding {
1880
+ padding: 0 12px 10px;
1881
+ margin-top: -4px;
1882
+ }
1883
+
1884
+ .branding a {
1885
+ font-family: var(--c-mono);
1886
+ font-size: 10.5px;
1887
+ letter-spacing: 0.06em;
1888
+ text-transform: uppercase;
1889
+ color: var(--c-muted);
1890
+ text-decoration: none;
1891
+ }
1892
+
1893
+ .branding a:hover {
1894
+ color: var(--c-ink);
1895
+ }
1896
+
1897
+ .toast {
1898
+ position: absolute;
1899
+ left: 50%;
1900
+ bottom: 124px;
1901
+ transform: translateX(-50%);
1902
+ z-index: 35;
1903
+ display: flex;
1904
+ align-items: center;
1905
+ gap: 14px;
1906
+ padding: 9px 14px;
1907
+ background: var(--c-ink);
1908
+ color: var(--c-bg);
1909
+ font-size: 13px;
1910
+ border-radius: var(--c-r2);
1911
+ box-shadow: 0 12px 32px -12px rgba(22, 24, 26, 0.25);
1912
+ white-space: nowrap;
1913
+ animation: aiIn 0.2s ease-out;
1914
+ }
1915
+
1916
+ .toast button {
1917
+ font-size: 13px;
1918
+ font-weight: 500;
1919
+ color: var(--c-bg);
1920
+ background: none;
1921
+ border: none;
1922
+ padding: 0;
1923
+ cursor: pointer;
1924
+ text-decoration: underline;
1925
+ text-underline-offset: 3px;
1926
+ }
1927
+
1928
+ .drop {
1929
+ position: absolute;
1930
+ inset: 10px;
1931
+ z-index: 36;
1932
+ display: flex;
1933
+ flex-direction: column;
1934
+ align-items: center;
1935
+ justify-content: center;
1936
+ gap: 6px;
1937
+ text-align: center;
1938
+ padding: 16px;
1939
+ border: 1.5px dashed var(--c-ink);
1940
+ border-radius: var(--c-r3);
1941
+ background: color-mix(in srgb, var(--c-bg) 92%, transparent);
1942
+ }
1943
+
1944
+ .drop strong {
1945
+ font-size: 15px;
1946
+ font-weight: 600;
1947
+ }
1948
+
1949
+ .drop span {
1950
+ font-size: 12.5px;
1951
+ color: var(--c-muted);
1952
+ }
1953
+
1954
+ /* ── AI glow ──────────────────────────────────────────── */
1955
+
1956
+ .halo {
1957
+ position: absolute;
1958
+ inset: -18px -24px;
1959
+ z-index: 0;
1960
+ pointer-events: none;
1961
+ opacity: var(--c-glow);
1962
+ }
1963
+
1964
+ .halo::before {
1965
+ content: "";
1966
+ position: absolute;
1967
+ inset: 0;
1968
+ border-radius: 20px;
1969
+ background: var(--c-conic);
1970
+ filter: blur(32px);
1971
+ opacity: 0.45;
1972
+ animation:
1973
+ aiSpin 5s linear infinite,
1974
+ aiBreathe 2.6s ease-in-out infinite;
1975
+ }
1976
+
1977
+ .arrived {
1978
+ position: absolute;
1979
+ inset: -12px -16px;
1980
+ z-index: 0;
1981
+ pointer-events: none;
1982
+ border-radius: var(--c-r4);
1983
+ animation: aiDone 2.6s ease-out forwards;
1984
+ }
1985
+
1986
+ .arrived .wash {
1987
+ position: absolute;
1988
+ inset: 0;
1989
+ border-radius: inherit;
1990
+ background: var(--c-conic);
1991
+ filter: blur(26px);
1992
+ opacity: calc(0.22 * var(--c-glow) + 0.06);
1993
+ animation: aiSpin 2.6s linear infinite;
1994
+ }
1995
+
1996
+ .ring {
1997
+ position: absolute;
1998
+ inset: 0;
1999
+ border-radius: inherit;
2000
+ padding: 1px;
2001
+ background: var(--c-conic);
2002
+ -webkit-mask:
2003
+ linear-gradient(#000 0 0) content-box,
2004
+ linear-gradient(#000 0 0);
2005
+ -webkit-mask-composite: xor;
2006
+ mask-composite: exclude;
2007
+ animation: aiSpin 2.6s linear infinite;
2008
+ pointer-events: none;
2009
+ }
2010
+
2011
+ .arrived .sweep {
2012
+ position: absolute;
2013
+ inset: 0;
2014
+ border-radius: inherit;
2015
+ overflow: hidden;
2016
+ }
2017
+
2018
+ .arrived .sweep::before {
2019
+ content: "";
2020
+ position: absolute;
2021
+ inset: 0;
2022
+ background: linear-gradient(
2023
+ 100deg,
2024
+ transparent 25%,
2025
+ oklch(0.88 0.07 260 / 0.5) 50%,
2026
+ transparent 75%
2027
+ );
2028
+ animation: aiSweep 1.6s cubic-bezier(0.3, 0.6, 0.3, 1) forwards;
2029
+ }
2030
+
2031
+ .pill {
2032
+ position: relative;
2033
+ display: inline-flex;
2034
+ align-self: flex-start;
2035
+ align-items: center;
2036
+ gap: 9px;
2037
+ padding: 6px 14px 6px 10px;
2038
+ border-radius: 999px;
2039
+ background: var(--c-bg);
2040
+ box-shadow: 0 0 24px -6px oklch(0.7 0.15 280 / 0.5);
2041
+ animation: aiIn 0.25s ease-out;
2042
+ }
2043
+
2044
+ .pill .ring {
2045
+ border-radius: 999px;
2046
+ animation-duration: 2.4s;
2047
+ }
2048
+
2049
+ .pill .dot {
2050
+ width: 9px;
2051
+ height: 9px;
2052
+ border-radius: 50%;
2053
+ background: var(--c-conic);
2054
+ animation:
2055
+ aiSpin 1.6s linear infinite,
2056
+ aiPulse 1.6s ease-in-out infinite;
2057
+ }
2058
+
2059
+ .pill .shimmer {
2060
+ font-size: 12.5px;
2061
+ font-weight: 500;
2062
+ background: linear-gradient(90deg, var(--c-faint) 0%, var(--c-ink) 45%, var(--c-faint) 90%);
2063
+ background-size: 200% 100%;
2064
+ -webkit-background-clip: text;
2065
+ background-clip: text;
2066
+ color: transparent;
2067
+ animation: aiShimmer 1.8s linear infinite;
2068
+ }
2069
+
2070
+ .composer-glow {
2071
+ position: absolute;
2072
+ inset: -4px;
2073
+ z-index: 0;
2074
+ border-radius: var(--c-r4);
2075
+ background: var(--c-conic);
2076
+ filter: blur(14px);
2077
+ opacity: calc(0.32 + 0.23 * (var(--c-glow) - 0.6) / 0.4);
2078
+ animation: aiSpin 4s linear infinite;
2079
+ pointer-events: none;
2080
+ }
2081
+
2082
+ .composer-ring {
2083
+ position: absolute;
2084
+ inset: 0;
2085
+ z-index: 2;
2086
+ border-radius: calc(var(--c-r) * 2.25);
2087
+ pointer-events: none;
2088
+ }
2089
+
2090
+ .composer-ring .ring {
2091
+ animation-duration: 3s;
2092
+ }
2093
+
2094
+ :host([glow="off"]) .halo,
2095
+ :host([glow="off"]) .arrived,
2096
+ :host([glow="off"]) .composer-glow,
2097
+ :host([glow="off"]) .composer-ring,
2098
+ :host([glow="off"]) .pill .ring {
2099
+ display: none;
2100
+ }
2101
+
2102
+ :host([glow="off"]) .pill {
2103
+ box-shadow: inset 0 0 0 1px var(--c-line);
2104
+ }
2105
+
2106
+ :host([glow="off"]) .pill .dot {
2107
+ background: var(--c-ink);
2108
+ }
2109
+
2110
+ @keyframes aiSpin {
2111
+ to {
2112
+ --sb-ai-angle: 360deg;
2113
+ }
2114
+ }
2115
+
2116
+ @keyframes aiShimmer {
2117
+ from {
2118
+ background-position: 200% 0;
2119
+ }
2120
+ to {
2121
+ background-position: -200% 0;
2122
+ }
2123
+ }
2124
+
2125
+ @keyframes aiBreathe {
2126
+ 0%,
2127
+ 100% {
2128
+ transform: scale(0.97);
2129
+ }
2130
+ 50% {
2131
+ transform: scale(1.03);
2132
+ }
2133
+ }
2134
+
2135
+ @keyframes aiPulse {
2136
+ 0%,
2137
+ 100% {
2138
+ transform: scale(0.8);
2139
+ }
2140
+ 50% {
2141
+ transform: scale(1.15);
2142
+ }
2143
+ }
2144
+
2145
+ @keyframes aiDone {
2146
+ 0% {
2147
+ opacity: 0;
2148
+ }
2149
+ 12% {
2150
+ opacity: 1;
2151
+ }
2152
+ 100% {
2153
+ opacity: 0;
2154
+ }
2155
+ }
2156
+
2157
+ @keyframes aiSweep {
2158
+ from {
2159
+ transform: translateX(-100%);
2160
+ }
2161
+ to {
2162
+ transform: translateX(100%);
2163
+ }
2164
+ }
2165
+
2166
+ @keyframes aiIn {
2167
+ from {
2168
+ opacity: 0;
2169
+ transform: translateY(4px);
2170
+ }
2171
+ to {
2172
+ opacity: 1;
2173
+ transform: none;
2174
+ }
2175
+ }
2176
+
2177
+ @keyframes scaleIn {
2178
+ from {
2179
+ opacity: 0;
2180
+ transform: translateY(12px) scale(0.98);
2181
+ }
2182
+ to {
2183
+ opacity: 1;
2184
+ transform: none;
2185
+ }
2186
+ }
2187
+
2188
+ @keyframes slideIn {
2189
+ from {
2190
+ opacity: 0;
2191
+ transform: translateX(-8px);
2192
+ }
2193
+ to {
2194
+ opacity: 1;
2195
+ transform: none;
2196
+ }
2197
+ }
2198
+
2199
+ @keyframes aiGrow {
2200
+ from {
2201
+ transform: scaleX(0);
2202
+ }
2203
+ }
2204
+
2205
+ @keyframes aiDraw {
2206
+ from {
2207
+ stroke-dashoffset: 1;
2208
+ }
2209
+ to {
2210
+ stroke-dashoffset: 0;
2211
+ }
2212
+ }
2213
+
2214
+ @keyframes rgcaret {
2215
+ 0%,
2216
+ 100% {
2217
+ opacity: 1;
2218
+ }
2219
+ 50% {
2220
+ opacity: 0;
2221
+ }
2222
+ }
2223
+
2224
+ @media (prefers-reduced-motion: reduce) {
2225
+ *,
2226
+ *::before,
2227
+ *::after {
2228
+ animation-duration: 0.01ms !important;
2229
+ animation-iteration-count: 1 !important;
2230
+ }
2231
+ .caret {
2232
+ display: none;
2233
+ }
2234
+ }
2235
+
2236
+ @media print {
2237
+ .sidebar,
2238
+ .scrim,
2239
+ .header-right,
2240
+ .composer-wrap,
2241
+ .branding,
2242
+ .toolbar,
2243
+ .followups,
2244
+ .panel,
2245
+ .toast {
2246
+ display: none !important;
2247
+ }
2248
+ .frame,
2249
+ .scroller {
2250
+ overflow: visible;
2251
+ height: auto;
2252
+ }
2253
+ }
2254
+ `,ot={eyebrowChat:"Chat",eyebrowRag:"Grounded answers",eyebrowRich:"Charts · tables · images",headingChat:"What can I help with?",headingRag:"Ask your knowledge base",headingRich:"Ask for a chart or a table",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.",descriptionRich:"Answers come back with charts, tables and images when they help. Attach CSV or JSON files to use your own data.",placeholderChat:"Message {name}…",placeholderRag:"Ask about your sources…",placeholderRich:"Ask for a chart, table or breakdown…",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",building:"Building charts and tables",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",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 lt(o){return{...ot,...o??{}}}const yt=/^\|.*\|$/,kt=/^\|[\s:|-]+\|$/,Ge=/^!\[([^\]]*)\]\(([^)]*)\)$/,Ve=/^([-*]|\d+\.)\s+/;function ct(o){const n=[],e=(o??"").replace(/\r/g,"").split("```");return e.forEach((t,i)=>{if(i%2===1){const a=t.indexOf(`
2255
+ `),r=(a>-1?t.slice(0,a):t).trim().toLowerCase(),l=(a>-1?t.slice(a+1):"").replace(/\n$/,""),c=i===e.length-1;if(r==="chart"){const m=c?null:wt(l);n.push(m?{type:"chart",spec:m}:{type:"chartPending"})}else n.push({type:"code",lang:r||"code",text:l});return}for(const a of t.split(/\n{2,}/)){const r=a.trim();r&&n.push(...dt(r))}}),n}function dt(o){const n=o.split(`
2256
+ `).map(t=>t.trim()).filter(Boolean);if(n.length>1&&n.every(t=>yt.test(t))){const t=n.filter(i=>!kt.test(i)).map(i=>i.replace(/^\||\|$/g,"").split("|").map(a=>a.trim()));return[{type:"table",head:t[0]??[],rows:t.slice(1)}]}if(n.every(t=>Ge.test(t)))return[{type:"img",images:n.map(t=>{const i=t.match(Ge);return{alt:i[1],src:i[2]}})}];if(n.every(t=>t.startsWith(">")))return[{type:"quote",text:n.map(t=>t.replace(/^>\s?/,"")).join(" ")}];if(n.every(t=>Ve.test(t)))return[{type:"list",ordered:/^\d+\./.test(n[0]),items:n.map(t=>t.replace(Ve,""))}];const e=n[0].match(/^(#{1,4})\s+(.*)$/);if(e){const t=n.slice(1).join(`
2257
+ `);return[{type:"h",level:e[1].length,text:e[2]},...t?dt(t):[]]}return[{type:"p",text:n.join(" ")}]}function wt(o){let n;try{n=JSON.parse(o)}catch{return null}if(!n||typeof n!="object")return null;const e=(Array.isArray(n.series)?n.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(n.labels)?n.labels.map(String):e[0].values.map((i,a)=>String(a+1));return{type:n.type==="line"?"line":"bar",title:String(n.title??""),unit:String(n.unit??""),labels:t,series:e}}const Xe=/\*\*([^*]+)\*\*|`([^`]+)`|\[([^\]]+)\]\((https?:\/\/[^)\s]+)\)|\s?\[(\d+(?:\s*,\s*\d+)*)\]/g;function pt(o,n=0){const e=[];let t=0,i;Xe.lastIndex=0;const a=r=>{if(!r)return;const l=e[e.length-1];(l==null?void 0:l.type)==="text"?l.text+=r:e.push({type:"text",text:r})};for(;i=Xe.exec(o);){if(a(o.slice(t,i.index)),i[1]!==void 0)e.push({type:"bold",text:i[1]});else if(i[2]!==void 0)e.push({type:"code",text:i[2]});else if(i[3]!==void 0)e.push({type:"link",text:i[3],href:i[4]});else{const l=i[5].split(",").map(c=>Number(c.trim())).filter(c=>c>=1&&c<=n);n?l.forEach(c=>e.push({type:"cite",n:c})):a(i[0])}t=i.index+i[0].length}return a(o.slice(t)),e}function Pe(o){const n=new Set;for(const e of(o??"").match(/\[(\d+(?:\s*,\s*\d+)*)\]/g)??[])e.replace(/[[\]]/g,"").split(",").forEach(t=>n.add(Number(t.trim())));return n}function Ye(o){return{head:["",...o.series.map(n=>n.name)],rows:o.labels.map((n,e)=>[n,...o.series.map(t=>t.values[e]===void 0?"":`${t.values[e]}${o.unit}`)])}}const Fe=o=>o.replace(/\*\*/g,"").replace(/`/g,"").replace(/\[([^\]]+)\]\((https?:\/\/[^)\s]+)\)/g,"$1");function ht(o,n){if(n==="markdown")return o.flatMap(e=>{if(e.type==="chart"){const t=Ye(e.spec);return[...e.spec.title?[{type:"p",text:`**${e.spec.title}**`}]:[],{type:"table",...t}]}return e.type==="img"?e.images.map(t=>({type:"p",text:`Image: ${t.alt||"untitled"}`})):[e]});if(n==="text"){const e=o.map(t=>{switch(t.type){case"chart":{const i=Ye(t.spec);return[t.spec.title,...[i.head,...i.rows].map(a=>a.join(" · "))].filter(Boolean).join(`
2258
+ `)}case"chartPending":return"";case"img":return t.images.map(i=>`Image: ${i.alt||"untitled"}`).join(`
2259
+ `);case"table":return[t.head,...t.rows].map(i=>i.map(Fe).join(" · ")).join(`
2260
+ `);case"list":return t.items.map(i=>`- ${Fe(i)}`).join(`
2261
+ `);case"code":case"raw":return t.text;default:return Fe(t.text)}}).filter(Boolean).join(`
2262
+
2263
+ `);return e?[{type:"raw",text:e}]:[]}return o}function He(o){const n=o??"",e=n.search(/FOLLOWUPS:/i);if(e<0)return{text:n.trim(),followups:[]};const i=n.slice(e).replace(/^FOLLOWUPS:/i,"").split(/\||\n/).map(a=>a.replace(/^\s*(?:[-*↳→]|\d+[.)])\s*/,"").trim()).filter(Boolean).slice(0,3);return{text:n.slice(0,e).trim(),followups:i}}function $t(o){return(o??"").replace(/```(\w*)[\s\S]*?(```|$)/g,(n,e)=>e==="chart"?"[Chart] ":"[Code] ").replace(/!\[([^\]]*)\]\([^)]*\)/g,"[Image: $1]").replace(/\[([^\]]+)\]\((https?:\/\/[^)\s]+)\)/g,"$1").replace(/[*#>`]/g,"").replace(/\|/g," ").replace(/\s?\[\d+(?:\s*,\s*\d+)*\]/g,"").replace(/\s+/g," ").trim()}function Ct(o,n=48){const e=$t(o);if(e.length<=n)return e;const t=e.slice(0,n),i=t.lastIndexOf(" ");return(i>n/2?t.slice(0,i):t).trim()}function St(o){return String(o??"").split(`
2264
+ `)[0].trim().replace(/^["'“”‘’]+|["'“”‘’]+$/g,"").replace(/^title:\s*/i,"").replace(/[.!?:;,]+$/,"").trim().slice(0,80)}function Qe(o,n=!1){return/^https?:\/\//i.test(o)?!0:n&&/^(blob:|data:image\/)/i.test(o)}var ut=Object.defineProperty,Tt=Object.getOwnPropertyDescriptor,zt=(o,n,e)=>n in o?ut(o,n,{enumerable:!0,configurable:!0,writable:!0,value:e}):o[n]=e,g=(o,n,e,t)=>{for(var i=t>1?void 0:t?Tt(n,e):n,a=o.length-1,r;a>=0;a--)(r=o[a])&&(i=(t?r(n,e,i):r(i))||i);return t&&i&&ut(n,e,i),i},Mt=(o,n,e)=>zt(o,n+"",e);const Ze=["embed","mode","renderAs","glow","position","sidebar","showTitle","assistantName","logoUrl","heading","description","prompts","bubbleText","greetingBubble","unreadBadge","allowUpload","allowExport","branding","followups","autoTitle","model","params","systemMessage","retrieval","metadata","messages","theme"],Je={fromAttribute:o=>{if(o)try{return JSON.parse(o)}catch{console.warn("[singlebase-chat] an attribute holds invalid JSON; ignoring it");return}},toAttribute:o=>JSON.stringify(o??null)},M={fromAttribute:o=>o===null?!0:o!=="false",toAttribute:o=>o?null:"false"},Ot={fromAttribute:o=>o===null?void 0:o!=="false",toAttribute:o=>o===void 0?null:String(o)},_t=272,It=820,Lt=940,et=5,tt=512*1024,jt=/\.(md|markdown|txt|csv|tsv|json|html?|ya?ml|xml|log)$/i,At=5e3,Et=2600,z=["var(--c-ink)","oklch(0.58 0.13 255)","oklch(0.63 0.1 175)","oklch(0.74 0.12 70)"],it={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.",rich:'Lead with one sentence stating the key finding, with key numbers in **bold**. For trends and comparisons, include a chart as a fenced code block with the language "chart" containing only JSON: {"type":"bar"|"line","title":string,"unit":string,"labels":[string],"series":[{"name":string,"values":[number]}]}. Use Markdown tables for exact values. Keep prose short.'},Nt="After the answer, on a final line write FOLLOWUPS: followed by three short follow-up questions the user might ask next, separated by |.",st={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"]],rich:[["Bar chart","Compare the five most spoken languages in a bar chart"],["Line chart","Show world population from 1950 to 2020"],["Table","List the planets with their diameters in a table"],["Breakdown","Break down a $4,000 monthly budget by category"]]},w=(o,n="")=>s.html`<svg class="i ${n}" viewBox="0 0 16 16" aria-hidden="true">${o}</svg>`,v={sidebar:()=>w(s.svg`<rect x="2" y="2.5" width="12" height="11" rx="1.5"></rect><path d="M6 2.5v11"></path>`),plus:()=>w(s.svg`<path d="M8 3v10M3 8h10"></path>`),bookmark:(o=!1)=>w(s.svg`<path d="M4.5 2.5h7v11L8 11l-3.5 2.5z"></path>`,o?"filled":""),download:()=>w(s.svg`<path d="M8 2.5v8M4.5 7.5L8 11l3.5-3.5M2.5 13.5h11"></path>`),trash:()=>w(s.svg`<path d="M2.5 4.5h11M6.5 4.5v-2h3v2M4 4.5l.7 9h6.6l.7-9"></path>`),pencil:()=>w(s.svg`<path d="M10.5 2.5l3 3L6 13H3v-3z"></path>`),copy:()=>w(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>`),refresh:()=>w(s.svg`<path d="M13.5 8A5.5 5.5 0 1 1 11.9 4.1M13.5 2v3.5H10"></path>`),thumb:(o=!1)=>s.html`<svg
2265
+ class="i"
2266
+ viewBox="0 0 16 16"
2267
+ aria-hidden="true"
2268
+ style=${o?"transform:rotate(180deg)":""}
2269
+ >
2270
+ <path
2271
+ 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"
2272
+ ></path>
2273
+ </svg>`,expand:()=>w(s.svg`<path d="M9.5 2.5h4v4M13.5 2.5L9 7M6.5 13.5h-4v-4M2.5 13.5L7 9"></path>`),restore:()=>w(s.svg`<path d="M13.5 6.5h-4v-4M9.5 6.5l4-4M2.5 9.5h4v4M6.5 9.5l-4 4"></path>`),minimize:()=>w(s.svg`<path d="M4 8h8"></path>`),close:()=>w(s.svg`<path d="M4 4l8 8M12 4l-8 8"></path>`),clip:()=>w(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:()=>w(s.svg`<path d="M8 13V3M3.5 7.5L8 3l4.5 4.5"></path>`),stop:()=>w(s.svg`<rect x="4.5" y="4.5" width="7" height="7" rx="1"></rect>`),chat:()=>s.html`<svg
2274
+ width="22"
2275
+ height="22"
2276
+ viewBox="0 0 22 22"
2277
+ aria-hidden="true"
2278
+ style="fill:none;stroke:currentColor;stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round"
2279
+ >
2280
+ <path
2281
+ 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"
2282
+ ></path>
2283
+ </svg>`,chevronDown:()=>s.html`<svg
2284
+ width="20"
2285
+ height="20"
2286
+ viewBox="0 0 20 20"
2287
+ aria-hidden="true"
2288
+ style="fill:none;stroke:currentColor;stroke-width:1.6;stroke-linecap:round"
2289
+ >
2290
+ <path d="M5 8l5 5 5-5"></path>
2291
+ </svg>`};let Bt=0;const Ke=()=>`m${Date.now().toString(36)}${(Bt++).toString(36)}`;function at(o){var e;const n=o;return(n==null?void 0:n.message)==="NOT_FOUND"||(n==null?void 0:n.code)==="NOT_FOUND"||((e=n==null?void 0:n.details)==null?void 0:e.status)===404}function Dt(o){const n=o;return(n==null?void 0:n.code)||(n==null?void 0:n.message)||"UNKNOWN"}const Rt=()=>typeof matchMedia<"u"&&matchMedia("(prefers-reduced-motion: reduce)").matches,Re=(o,n)=>(Number.isInteger(o)?o.toLocaleString("en-US"):o.toFixed(1))+n,rt=o=>{const n=o.lastIndexOf(".");return n>0?o.slice(n+1,n+5).toUpperCase():"FILE"};function _(o,n){const e=o??{},t=e.metadata&&typeof e.metadata=="object"?e.metadata:{},i=(...l)=>l.find(c=>typeof c=="string"&&c.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(l=>typeof l=="number");return{n,title:i(e.title,e.name,e.filename,t.title,t.name)??`Source ${n}`,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 Ut(o){const n=[],e=[];for(const t of o)if(/\.csv$/i.test(t.name))n.push({type:"csv",data:t.content});else if(/\.json$/i.test(t.name))try{n.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&&n.push({type:"docs",payload:{documents:e}}),n}function Ue(o){const n=o?Date.parse(o):NaN;if(Number.isNaN(n))return"older";const e=new Date;e.setHours(0,0,0,0);const t=864e5;return n>=e.getTime()?"today":n>=e.getTime()-t?"yesterday":n>=e.getTime()-7*t?"week":"older"}var I,L,j,A,E,N,B,D,R,U,F,K,P,H,J,W,q,G,V,X,Y,Q,Z,ee,te,ie,se,ae,re,ne,oe,le,ce,de,pe,he,ue,ge,me,be,fe,xe,ve,ye,ke,we,$e,Ce,Se,Te,ze,Me,Oe,_e,Ie,Le,je,Ae,Ee,Ne,Be,nt;exports.SinglebaseChat=(nt=class extends s.LitElement{constructor(){super(...arguments);p(this,I,null);p(this,L,{});p(this,j);p(this,A,"chat");p(this,E,"rich");p(this,N,"subtle");p(this,B,!0);p(this,D,!0);p(this,R,"");p(this,U,{});p(this,F,"");p(this,K,[]);p(this,P,{});p(this,H,"page");p(this,J,"right");p(this,W);p(this,q,!0);p(this,G,"");p(this,V,"Assistant");p(this,X,"");p(this,Y,"");p(this,Q,"");p(this,Z,"");p(this,ee,"");p(this,te,!1);p(this,ie,!1);p(this,se,!0);p(this,ae,!0);p(this,re,!0);p(this,ne,[]);p(this,oe,"idle");p(this,le,null);p(this,ce,"");p(this,de,!1);p(this,pe,[]);p(this,he,!1);p(this,ue,"");p(this,ge,!1);p(this,me,"");p(this,be,[]);p(this,fe,"");p(this,xe,null);p(this,ve,0);p(this,ye,null);p(this,ke,!1);p(this,we,"");p(this,$e,"");p(this,Ce,!1);p(this,Se,"");p(this,Te,null);p(this,ze,"");p(this,Me,new Set);p(this,Oe,"");p(this,_e,!1);p(this,Ie,!1);p(this,Le,!1);p(this,je,!1);p(this,Ae,!1);p(this,Ee,!1);p(this,Ne,!1);p(this,Be,!1);k(this,"run",0);k(this,"abort",null);k(this,"revealTimer");k(this,"timers",new Set);k(this,"toastTimer");k(this,"stick",!0);k(this,"renamed",new Set);k(this,"observer",null);k(this,"observed",null);k(this,"media",null);k(this,"focusNext","");k(this,"bubbleScheduled",!1);k(this,"onNetwork",()=>{this.offline=navigator.onLine===!1});k(this,"onMedia",()=>{var e;this.mobile=!!((e=this.media)!=null&&e.matches)})}get client(){return d(this,I)}set client(e){h(this,I,e)}get messages(){return d(this,L)}set messages(e){h(this,L,e)}get theme(){return d(this,j)}set theme(e){h(this,j,e)}get mode(){return d(this,A)}set mode(e){h(this,A,e)}get renderAs(){return d(this,E)}set renderAs(e){h(this,E,e)}get glow(){return d(this,N)}set glow(e){h(this,N,e)}get followups(){return d(this,B)}set followups(e){h(this,B,e)}get autoTitle(){return d(this,D)}set autoTitle(e){h(this,D,e)}get model(){return d(this,R)}set model(e){h(this,R,e)}get params(){return d(this,U)}set params(e){h(this,U,e)}get systemMessage(){return d(this,F)}set systemMessage(e){h(this,F,e)}get retrieval(){return d(this,K)}set retrieval(e){h(this,K,e)}get metadata(){return d(this,P)}set metadata(e){h(this,P,e)}get embed(){return d(this,H)}set embed(e){h(this,H,e)}get position(){return d(this,J)}set position(e){h(this,J,e)}get sidebar(){return d(this,W)}set sidebar(e){h(this,W,e)}get showTitle(){return d(this,q)}set showTitle(e){h(this,q,e)}get chatIdAttr(){return d(this,G)}set chatIdAttr(e){h(this,G,e)}get assistantName(){return d(this,V)}set assistantName(e){h(this,V,e)}get logoUrl(){return d(this,X)}set logoUrl(e){h(this,X,e)}get heading(){return d(this,Y)}set heading(e){h(this,Y,e)}get description(){return d(this,Q)}set description(e){h(this,Q,e)}get prompts(){return d(this,Z)}set prompts(e){h(this,Z,e)}get bubbleText(){return d(this,ee)}set bubbleText(e){h(this,ee,e)}get greetingBubble(){return d(this,te)}set greetingBubble(e){h(this,te,e)}get unreadBadge(){return d(this,ie)}set unreadBadge(e){h(this,ie,e)}get allowUpload(){return d(this,se)}set allowUpload(e){h(this,se,e)}get allowExport(){return d(this,ae)}set allowExport(e){h(this,ae,e)}get branding(){return d(this,re)}set branding(e){h(this,re,e)}get chatList(){return d(this,ne)}set chatList(e){h(this,ne,e)}get listState(){return d(this,oe)}set listState(e){h(this,oe,e)}get activeId(){return d(this,le)}set activeId(e){h(this,le,e)}get chatTitle(){return d(this,ce)}set chatTitle(e){h(this,ce,e)}get bookmarked(){return d(this,de)}set bookmarked(e){h(this,de,e)}get msgs(){return d(this,pe)}set msgs(e){h(this,pe,e)}get loadingThread(){return d(this,he)}set loadingThread(e){h(this,he,e)}get threadError(){return d(this,ue)}set threadError(e){h(this,ue,e)}get busy(){return d(this,ge)}set busy(e){h(this,ge,e)}get draft(){return d(this,me)}set draft(e){h(this,me,e)}get files(){return d(this,be)}set files(e){h(this,be,e)}get search(){return d(this,fe)}set search(e){h(this,fe,e)}get sidebarOpen(){return d(this,xe)}set sidebarOpen(e){h(this,xe,e)}get width(){return d(this,ve)}set width(e){h(this,ve,e)}get panel(){return d(this,ye)}set panel(e){h(this,ye,e)}get menuOpen(){return d(this,ke)}set menuOpen(e){h(this,ke,e)}get editingKey(){return d(this,we)}set editingKey(e){h(this,we,e)}get editDraft(){return d(this,$e)}set editDraft(e){h(this,$e,e)}get editingTitle(){return d(this,Ce)}set editingTitle(e){h(this,Ce,e)}get renamingId(){return d(this,Se)}set renamingId(e){h(this,Se,e)}get toast(){return d(this,Te)}set toast(e){h(this,Te,e)}get copiedKey(){return d(this,ze)}set copiedKey(e){h(this,ze,e)}get retrievalOpen(){return d(this,Me)}set retrievalOpen(e){h(this,Me,e)}get arrivedKey(){return d(this,Oe)}set arrivedKey(e){h(this,Oe,e)}get dragging(){return d(this,_e)}set dragging(e){h(this,_e,e)}get showJump(){return d(this,Ie)}set showJump(e){h(this,Ie,e)}get offline(){return d(this,Le)}set offline(e){h(this,Le,e)}get isOpen(){return d(this,je)}set isOpen(e){h(this,je,e)}get expanded(){return d(this,Ae)}set expanded(e){h(this,Ae,e)}get bubble(){return d(this,Ee)}set bubble(e){h(this,Ee,e)}get seen(){return d(this,Ne)}set seen(e){h(this,Ne,e)}get mobile(){return d(this,Be)}set mobile(e){h(this,Be,e)}get msg(){return lt(this.messages)}get resolvedClient(){return this.client??xt.getDefaultClient()??null}get chatId(){return this.activeId}get thread(){return this.msgs}get chats(){return this.chatList}set config(e){const t=this;for(const i of Ze)e&&i in e&&(t[i]=e[i])}get config(){const e=this;return Object.fromEntries(Ze.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!==void 0&&(this.sidebarOpen=this.sidebar),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??this.docked))})),this.observer.observe(e))),this.sidebarOpen&&this.listState==="idle"&&this.resolvedClient&&this.loadChats(),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>=It}get panelDocked(){const e=this.docked&&this.sidebarOpen?_t:0;return this.width-e>=Lt}newChat(){this.halt(),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.threadError=this.msg.errNoClient;return}const a=++this.run;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(l=>l&&(l.role==="user"||l.role==="assistant")).map(l=>this.fromServer(l)),this.upsertChat({...i,...r,_id:e}),this.stick=!0,this.scrollToBottom()}catch(r){if(a!==this.run)return;at(r)?(this.chatList=this.chatList.filter(l=>l._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 T;if(!this.msgs.length)return;this.menuOpen=!1;const t=this.chatTitle||this.msg.untitled,i=y=>y.role==="user"?this.msg.you:this.assistantName,a=y=>new Date(y||Date.now()).toLocaleString(),r=y=>y.sources.map((O,gt)=>{const De=_(O,gt+1);return`[${De.n}] ${De.title}${De.path?` — ${De.path}`:""}`}),l=y=>(y.attachments??[]).map(O=>O.name);let c,m="text/markdown",x="md";if(e==="json"?(c=JSON.stringify({exportedAt:new Date().toISOString(),id:this.activeId,title:t,mode:this.mode,bookmarked:this.bookmarked,messages:this.msgs.map(y=>({role:y.role,text:y.content,at:new Date(y.at||Date.now()).toISOString(),bookmarked:y.bookmarked,attachments:l(y),sources:r(y)}))},null,2),m="application/json",x="json"):e==="txt"?(c=`${t}
2292
+ ${"=".repeat(t.length)}
2293
+
2294
+ `+this.msgs.map(y=>[`${i(y)} · ${a(y.at)}`,l(y).length?`Attachments: ${l(y).join(", ")}`:"",y.content,r(y).length?`Sources:
2295
+ ${r(y).join(`
2296
+ `)}`:""].filter(Boolean).join(`
2297
+ `)).join(`
2298
+
2299
+ `),m="text/plain",x="txt"):c=`# ${t}
2300
+
2301
+ `+this.msgs.map(y=>[`### ${i(y)} · ${a(y.at)}`,l(y).length?`Attachments: ${l(y).join(", ")}`:"",y.content,r(y).length?`**Sources**
2302
+
2303
+ ${r(y).map(O=>`- ${O}`).join(`
2304
+ `)}`:""].filter(Boolean).join(`
2305
+
2306
+ `)).join(`
2307
+
2308
+ ---
2309
+
2310
+ `)+`
2311
+ `,this.emit("singlebase-chat-export",{chatId:this.activeId,format:e}),e==="copy"){(T=navigator.clipboard)==null||T.writeText(c).catch(()=>{}),this.showToast(this.msg.copiedMarkdown);return}const S=`${t.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"")||"chat"}-${new Date().toISOString().slice(0,10)}.${x}`,C=URL.createObjectURL(new Blob([c],{type:m})),b=document.createElement("a");b.href=C,b.download=S,document.body.appendChild(b),b.click(),b.remove(),setTimeout(()=>URL.revokeObjectURL(C),2e3),this.showToast($.fill(this.msg.exported,{name:S}))}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:Ke(),id:null,role:"user",content:e,at:Date.now(),bookmarked:!1,sources:[],followups:[],phase:"done",attachments:t}}systemPrompt(){return[this.systemMessage,it[this.mode]??it.chat,this.followups?Nt:""].filter(Boolean).join(`
2312
+
2313
+ `)}payloadFor(e){const t={message:e.content,format:"markdown"};this.activeId?t._id=this.activeId:(t.title=Ct(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??[],...Ut(e.attachments??[])];return a.length&&(t.retrieval=a),t}async runTurn(e){const t={key:Ke(),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 l=!this.activeId,c=this.payloadFor(e);try{const m=await i.llm.call("chat",c,{signal:r.signal}),x=(m==null?void 0:m._id)||(m==null?void 0:m.chat_id)||this.activeId;if(l&&x&&this.upsertChat({_id:x,title:(m==null?void 0:m.title)||c.title,bookmarked:!!(m!=null&&m.bookmarked),_modified_at:new Date().toISOString()}),a!==this.run)return;x&&(this.activeId=x),l?(this.chatTitle=(m==null?void 0:m.title)||c.title,this.bookmarked=!!(m!=null&&m.bookmarked)):x&&this.touchChat(x);const f=(m==null?void 0:m.message)??{},S=typeof f.content=="string"?f.content:(m==null?void 0:m.json)!==void 0?JSON.stringify(m.json,null,2):"",{text:C,followups:b}=He(S);e.id=f.reply_to??null,Object.assign(t,{id:f._id??null,content:C,sources:Array.isArray(f.sources)?f.sources:[],followups:this.followups?b:[],execTime:typeof f.exec_time=="number"?f.exec_time:void 0,model:f.model,at:Date.now()}),this.emit("singlebase-chat-response",{chatId:x,message:t}),await this.reveal(t,a),l&&x&&this.autoTitle&&this.retitle(x,e.content,t.content)}catch(m){if(a!==this.run)return;const x=at(m);x&&(this.chatList=this.chatList.filter(f=>f._id!==this.activeId),this.activeId=null),this.failTurn(t,x?this.msg.errNotFound:this.msg.errGeneric,Dt(m))}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="")},Et),this.stick?this.scrollToBottom():this.showJump=!0};if(!i||Rt())return a(),Promise.resolve();const r=e.content,l=Math.max(4,Math.ceil(i/90));let c=0;return e.phase="streaming",e.content="",new Promise(m=>{this.revealTimer=setInterval(()=>{if(t!==this.run){clearInterval(this.revealTimer),m();return}if(c=Math.min(i,c+l),e.content=r.slice(0,c),c>=i){clearInterval(this.revealTimer),a(),m();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}
2314
+ 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"}),l=St(r==null?void 0:r.result);if(!l||this.renamed.has(e))return;await a.llm.call("update_chat",{_id:e,title:l}),this.applyTitle(e,l,!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,l;const i=t.trim().slice(0,80),a=((r=this.chatList.find(c=>c._id===e))==null?void 0:r.title)??this.chatTitle;if(!(!i||i===a)){this.renamed.add(e),this.applyTitle(e,i,!1);try{await((l=this.resolvedClient)==null?void 0:l.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?He(String(e.content??"")):{text:String(e.content??""),followups:[]};return{key:Ke(),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:this.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))}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,l;const t=((r=this.chatList.find(c=>c._id===e))==null?void 0:r.bookmarked)??(e===this.activeId?this.bookmarked:!1),i=!t,a=c=>{this.chatList=this.chatList.map(m=>m._id===e?{...m,bookmarked:c}:m),e===this.activeId&&(this.bookmarked=c)};a(i),this.showToast(i?this.msg.chatBookmarked:this.msg.chatUnbookmarked),this.emit("singlebase-chat-bookmark",{chatId:e,bookmarked:i});try{await((l=this.resolvedClient)==null?void 0:l.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(l=>l._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(l=>l._id!==e),a&&this.newChat(),this.showToast(this.msg.chatDeleted,{undo:()=>{const l=[...this.chatList];l.splice(Math.max(0,t),0,i),this.chatList=l,r&&!this.activeId&&!this.msgs.length&&(this.activeId=e,this.chatTitle=r.title,this.bookmarked=r.bookmarked,this.msgs=r.msgs)},commit:()=>{var l;this.emit("singlebase-chat-delete",{chatId:e}),(l=this.resolvedClient)==null||l.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()},At)}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>=et){this.showToast($.fill(this.msg.tooManyFiles,{n:et}));break}if(!jt.test(a.name)&&!a.type.startsWith("text/")){this.showToast($.fill(this.msg.fileType,{name:a.name}));continue}if(a.size>tt){this.showToast($.fill(this.msg.fileTooLarge,{name:a.name,size:$.formatSize(tt)}));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||!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">
2315
+ ${this.renderWorkspace()}
2316
+ </div>`:s.nothing,a=this.bubble&&!this.isOpen?s.html`<div class="bubble" part="bubble">
2317
+ <button type="button" class="bubble-text" @click=${()=>this.open()}>
2318
+ ${this.bubbleText||e.bubbleText}
2319
+ </button>
2320
+ <button
2321
+ type="button"
2322
+ class="icon sm"
2323
+ aria-label=${e.dismiss}
2324
+ title=${e.dismiss}
2325
+ @click=${()=>this.bubble=!1}
2326
+ >
2327
+ ${v.close()}
2328
+ </button>
2329
+ </div>`:s.nothing,l=this.isOpen&&(this.expanded||this.mobile)?s.nothing:s.html`<button
2330
+ type="button"
2331
+ class="launcher-btn"
2332
+ part="launcher"
2333
+ aria-label=${this.isOpen?e.closeChat:e.openChat}
2334
+ aria-expanded=${this.isOpen?"true":"false"}
2335
+ @click=${()=>this.isOpen?this.close():this.open()}
2336
+ >
2337
+ ${this.isOpen?v.chevronDown():v.chat()}
2338
+ ${this.unreadBadge&&!this.seen&&!this.isOpen?s.html`<span class="badge"></span>`:s.nothing}
2339
+ </button>`;return s.html`${i}${a}${l}`}renderWorkspace(){const e=!this.docked;return s.html`<div class="root" @keydown=${this.onKeydown}>
2340
+ ${this.sidebarOpen&&e?s.html`<div class="scrim" @click=${()=>this.sidebarOpen=!1}></div>`:s.nothing}
2341
+ ${this.sidebarOpen?this.renderSidebar(e):s.nothing}
2342
+ <main
2343
+ class="main"
2344
+ @dragenter=${this.onDragEnter}
2345
+ @dragover=${t=>t.preventDefault()}
2346
+ >
2347
+ ${this.renderHeader()}
2348
+ ${this.offline?s.html`<div class="banner" role="status">${this.msg.offline}</div>`:s.nothing}
2349
+ <div
2350
+ class="scroller"
2351
+ role="log"
2352
+ aria-live="polite"
2353
+ aria-busy=${this.busy?"true":"false"}
2354
+ part="messages"
2355
+ @scroll=${this.onScroll}
2356
+ >
2357
+ ${this.msgs.length||this.loadingThread||this.threadError?this.renderThread():this.renderWelcome()}
2358
+ </div>
2359
+ ${this.showJump?s.html`<button type="button" class="jump" @click=${this.jumpToLatest}>
2360
+ ↓ ${this.msg.newReply}
2361
+ </button>`:s.nothing}
2362
+ ${this.renderComposer()}
2363
+ ${this.branding?s.html`<div class="branding" part="branding">
2364
+ <a href="https://singlebase.cloud" target="_blank" rel="noopener noreferrer"
2365
+ >${this.msg.brandingLabel}</a
2366
+ >
2367
+ </div>`:s.nothing}
2368
+ ${this.toast?s.html`<div class="toast" role="status">
2369
+ <span>${this.toast.text}</span>
2370
+ ${this.toast.undo?s.html`<button type="button" @click=${this.undo}>${this.msg.undo}</button>`:s.nothing}
2371
+ </div>`:s.nothing}
2372
+ ${this.dragging?s.html`<div
2373
+ class="drop"
2374
+ @dragover=${t=>t.preventDefault()}
2375
+ @dragleave=${this.onDragLeave}
2376
+ @drop=${this.onDrop}
2377
+ >
2378
+ <strong>${this.msg.dropTitle}</strong><span>${this.msg.dropSub}</span>
2379
+ </div>`:s.nothing}
2380
+ </main>
2381
+ ${this.renderPanel()}
2382
+ </div>`}renderSidebar(e){const t=this.msg,i=this.search.trim().toLowerCase(),a=this.chatList.filter(c=>!i||(c.title??"").toLowerCase().includes(i)),r=[[t.groupBookmarked,a.filter(c=>c.bookmarked)],[t.groupToday,a.filter(c=>!c.bookmarked&&Ue(c._modified_at??c._created_at)==="today")],[t.groupYesterday,a.filter(c=>!c.bookmarked&&Ue(c._modified_at??c._created_at)==="yesterday")],[t.groupWeek,a.filter(c=>!c.bookmarked&&Ue(c._modified_at??c._created_at)==="week")],[t.groupOlder,a.filter(c=>!c.bookmarked&&Ue(c._modified_at??c._created_at)==="older")]];let l;return this.listState==="loading"&&!this.chatList.length?l=s.html`<div aria-label=${t.loadingChats}>
2383
+ ${[1,2,3,4].map(()=>s.html`<div class="skeleton"></div>`)}
2384
+ </div>`:a.length?l=r.filter(([,c])=>c.length).map(([c,m])=>s.html`<div class="group">${c}</div>
2385
+ ${m.map(x=>this.renderThreadRow(x))}`):l=s.html`<span class="side-note"
2386
+ >${i?$.fill(t.noMatch,{query:this.search.trim()}):t.noChats}</span
2387
+ >`,s.html`<aside
2388
+ class="sidebar ${e?"overlay":"docked"}"
2389
+ part="sidebar"
2390
+ aria-label=${t.chats}
2391
+ >
2392
+ <div class="side-head">
2393
+ <span class="label">${t.chats}</span>
2394
+ <button
2395
+ type="button"
2396
+ class="icon"
2397
+ title=${t.hideSidebar}
2398
+ aria-label=${t.hideSidebar}
2399
+ @click=${()=>this.sidebarOpen=!1}
2400
+ >
2401
+ ${v.sidebar()}
2402
+ </button>
2403
+ </div>
2404
+ <div class="side-tools">
2405
+ <button type="button" class="new-chat" @click=${()=>this.newChat()}>
2406
+ ${v.plus()}<span>${t.newChat}</span>
2407
+ </button>
2408
+ <input
2409
+ class="search"
2410
+ type="search"
2411
+ placeholder=${t.searchChats}
2412
+ aria-label=${t.searchChats}
2413
+ .value=${this.search}
2414
+ @input=${c=>this.search=c.target.value}
2415
+ />
2416
+ </div>
2417
+ <div class="threads">${l}</div>
2418
+ </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">
2419
+ <input
2420
+ class="thread-rename"
2421
+ maxlength="80"
2422
+ .value=${a}
2423
+ aria-label=${t.renameChat}
2424
+ @keydown=${l=>{l.key==="Enter"&&this.commitRename(e._id,l.target.value),l.key==="Escape"&&(l.stopPropagation(),this.renamingId="")}}
2425
+ @blur=${l=>this.commitRename(e._id,l.target.value)}
2426
+ />
2427
+ </div>`;const r=l=>c=>{c.stopPropagation(),l()};return s.html`<div
2428
+ class="thread ${i?"active":""}"
2429
+ role="button"
2430
+ tabindex="0"
2431
+ aria-current=${i?"true":"false"}
2432
+ @click=${()=>this.openChat(e._id)}
2433
+ @keydown=${l=>l.key==="Enter"&&this.openChat(e._id)}
2434
+ >
2435
+ <span class="thread-title">${a}</span>
2436
+ <span class="thread-actions">
2437
+ <button
2438
+ type="button"
2439
+ class="icon sm ${e.bookmarked?"on":""}"
2440
+ title=${e.bookmarked?t.unbookmarkChat:t.bookmarkChat}
2441
+ aria-label=${e.bookmarked?t.unbookmarkChat:t.bookmarkChat}
2442
+ @click=${r(()=>this.toggleChatBookmark(e._id))}
2443
+ >
2444
+ ${v.bookmark(!!e.bookmarked)}
2445
+ </button>
2446
+ <button
2447
+ type="button"
2448
+ class="icon sm"
2449
+ title=${t.renameChat}
2450
+ aria-label=${t.renameChat}
2451
+ @click=${r(()=>{this.renamingId=e._id,this.focusNext="input.thread-rename"})}
2452
+ >
2453
+ ${v.pencil()}
2454
+ </button>
2455
+ <button
2456
+ type="button"
2457
+ class="icon sm danger"
2458
+ title=${t.deleteChat}
2459
+ aria-label=${t.deleteChat}
2460
+ @click=${r(()=>this.deleteChat(e._id))}
2461
+ >
2462
+ ${v.trash()}
2463
+ </button>
2464
+ </span>
2465
+ </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
2466
+ class="title-input"
2467
+ maxlength="80"
2468
+ .value=${this.chatTitle}
2469
+ aria-label=${e.renameChat}
2470
+ @keydown=${l=>{l.key==="Enter"&&this.commitTitle(l.target.value),l.key==="Escape"&&(l.stopPropagation(),this.editingTitle=!1)}}
2471
+ @blur=${l=>this.commitTitle(l.target.value)}
2472
+ />`:s.html`<button
2473
+ type="button"
2474
+ class="title"
2475
+ part="title"
2476
+ ?disabled=${!t}
2477
+ title=${t?e.renameChat:""}
2478
+ @click=${()=>{this.editingTitle=!0,this.focusNext="input.title-input"}}
2479
+ >
2480
+ ${this.chatTitle||e.untitled}
2481
+ </button>`),s.html`<header class="header" part="header">
2482
+ <div class="header-left">
2483
+ ${this.sidebarOpen&&this.docked?s.nothing:s.html`<button
2484
+ type="button"
2485
+ class="icon"
2486
+ title=${e.showChats}
2487
+ aria-label=${e.showChats}
2488
+ @click=${()=>this.sidebarOpen=!0}
2489
+ >
2490
+ ${v.sidebar()}
2491
+ </button>`}
2492
+ ${r}
2493
+ </div>
2494
+ <div class="header-right">
2495
+ <button
2496
+ type="button"
2497
+ class="icon ${this.bookmarked?"on":""}"
2498
+ ?disabled=${!t}
2499
+ title=${this.bookmarked?e.unbookmarkChat:e.bookmarkChat}
2500
+ aria-label=${this.bookmarked?e.unbookmarkChat:e.bookmarkChat}
2501
+ @click=${()=>this.activeId&&this.toggleChatBookmark(this.activeId)}
2502
+ >
2503
+ ${v.bookmark(this.bookmarked)}
2504
+ </button>
2505
+ ${this.allowExport?s.html`<div class="menu-wrap">
2506
+ <button
2507
+ type="button"
2508
+ class="icon ${this.menuOpen?"on":""}"
2509
+ ?disabled=${!this.msgs.length}
2510
+ title=${e.exportChat}
2511
+ aria-label=${e.exportChat}
2512
+ aria-haspopup="menu"
2513
+ aria-expanded=${this.menuOpen?"true":"false"}
2514
+ @click=${()=>this.menuOpen=!this.menuOpen}
2515
+ >
2516
+ ${v.download()}
2517
+ </button>
2518
+ ${this.menuOpen?this.renderExportMenu():s.nothing}
2519
+ </div>`:s.nothing}
2520
+ <button
2521
+ type="button"
2522
+ class="icon danger"
2523
+ ?disabled=${!t}
2524
+ title=${e.deleteChat}
2525
+ aria-label=${e.deleteChat}
2526
+ @click=${()=>this.activeId&&this.deleteChat(this.activeId)}
2527
+ >
2528
+ ${v.trash()}
2529
+ </button>
2530
+ ${i||a?s.html`<span class="divider"></span> ${i?s.html`<button
2531
+ type="button"
2532
+ class="icon"
2533
+ title=${this.expanded?e.restore:e.expand}
2534
+ aria-label=${this.expanded?e.restore:e.expand}
2535
+ @click=${()=>this.expanded?this.collapse():this.expand()}
2536
+ >
2537
+ ${this.expanded?v.restore():v.expand()}
2538
+ </button>`:s.nothing}
2539
+ ${a?s.html`<button
2540
+ type="button"
2541
+ class="icon"
2542
+ title=${e.minimize}
2543
+ aria-label=${e.minimize}
2544
+ @click=${a}
2545
+ >
2546
+ ${v.minimize()}
2547
+ </button>`:s.nothing}`:s.nothing}
2548
+ </div>
2549
+ </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>
2550
+ <div class="menu" role="menu">
2551
+ <span class="label">${e.exportHeading}</span>
2552
+ ${t.map(([i,a,r])=>s.html`<button
2553
+ type="button"
2554
+ role="menuitem"
2555
+ class="menu-item"
2556
+ @click=${()=>this.exportChat(r)}
2557
+ >
2558
+ <span>${i}</span><span class="ext">${a}</span>
2559
+ </button>`)}
2560
+ </div>`}promptList(){const e=this.prompts;return Array.isArray(e)&&e.length?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()?e.split("|").map(t=>t.trim()).filter(Boolean).slice(0,4).map(t=>({text:t})):(st[this.mode]??st.chat).map(([t,i])=>({label:t,text:i}))}renderWelcome(){const e=this.msg,t=this.mode==="rag"?"Rag":this.mode==="rich"?"Rich":"Chat",i=a=>e[`${a}${t}`];return s.html`<div class="welcome" part="welcome">
2561
+ <div class="welcome-head">
2562
+ ${this.logoUrl&&Qe(this.logoUrl,!0)?s.html`<img class="welcome-logo" src=${this.logoUrl} alt="" />`:s.nothing}
2563
+ <span class="label">${i("eyebrow")}</span>
2564
+ <h2>${this.heading||i("heading")}</h2>
2565
+ <p>${this.description||i("description")}</p>
2566
+ </div>
2567
+ <div class="prompts">
2568
+ ${this.promptList().map(a=>s.html`<button
2569
+ type="button"
2570
+ class="prompt"
2571
+ part="prompt"
2572
+ @click=${()=>this.send(a.text)}
2573
+ >
2574
+ <span class="label">${a.label||"Suggested"}</span>
2575
+ <span class="prompt-text">${a.text}</span>
2576
+ </button>`)}
2577
+ </div>
2578
+ </div>`}renderThread(){const e=this.msgs.map(t=>t.role).lastIndexOf("assistant");return s.html`<div class="thread-view">
2579
+ ${this.threadError?s.html`<div class="error-card" role="alert">
2580
+ <span>${this.threadError}</span>
2581
+ ${this.activeId?s.html`<button
2582
+ type="button"
2583
+ class="btn"
2584
+ @click=${()=>this.openChat(this.activeId)}
2585
+ >
2586
+ ${this.msg.retry}
2587
+ </button>`:s.nothing}
2588
+ </div>`:s.nothing}
2589
+ ${this.loadingThread?s.html`${[1,2].map(()=>s.html`<div class="skeleton" style="height:48px"></div>`)}`:s.nothing}
2590
+ ${ft.repeat(this.msgs,t=>t.key,(t,i)=>t.role==="user"?this.renderUser(t):this.renderBot(t,i===e))}
2591
+ </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">
2592
+ ${a.length?s.html`<div class="attachments">
2593
+ ${a.map(r=>s.html`<span class="doc-chip"><span class="ext">${rt(r.name)}</span><span class="name">${r.name}</span></span>`)}
2594
+ </div>`:s.nothing}
2595
+ ${this.editingKey===e.key?s.html`<div class="edit-box">
2596
+ <textarea
2597
+ rows="3"
2598
+ class="edit-input"
2599
+ .value=${this.editDraft}
2600
+ @input=${r=>this.editDraft=r.target.value}
2601
+ @keydown=${r=>{r.key==="Escape"&&(r.stopPropagation(),this.editingKey="")}}
2602
+ ></textarea>
2603
+ <div class="row-end">
2604
+ <button type="button" class="btn" @click=${()=>this.editingKey=""}>
2605
+ ${t.cancel}
2606
+ </button>
2607
+ <button type="button" class="btn primary" @click=${()=>this.saveEdit(e)}>
2608
+ ${t.saveResend}
2609
+ </button>
2610
+ </div>
2611
+ </div>`:s.html`<div class="bubble-user">${e.content}</div>
2612
+ <div class="toolbar">
2613
+ ${e.bookmarked?s.html`<span class="saved">${v.bookmark(!0)}${t.saved}</span>`:s.nothing}
2614
+ <span class="time">${i}</span>
2615
+ ${this.busy?s.nothing:s.html`<button
2616
+ type="button"
2617
+ class="icon"
2618
+ title=${t.edit}
2619
+ aria-label=${t.edit}
2620
+ @click=${()=>{this.editingKey=e.key,this.editDraft=e.content,this.focusNext="textarea.edit-input"}}
2621
+ >
2622
+ ${v.pencil()}
2623
+ </button>`}
2624
+ <button
2625
+ type="button"
2626
+ class="icon"
2627
+ title=${this.copiedKey===e.key?t.copied:t.copy}
2628
+ aria-label=${t.copy}
2629
+ @click=${()=>this.copy(e.key,e.content)}
2630
+ >
2631
+ ${v.copy()}
2632
+ </button>
2633
+ ${e.id?s.html`<button
2634
+ type="button"
2635
+ class="icon ${e.bookmarked?"on":""}"
2636
+ title=${e.bookmarked?t.unbookmarkMessage:t.bookmarkMessage}
2637
+ aria-label=${e.bookmarked?t.unbookmarkMessage:t.bookmarkMessage}
2638
+ @click=${()=>this.toggleMessageBookmark(e)}
2639
+ >
2640
+ ${v.bookmark(e.bookmarked)}
2641
+ </button>`:s.nothing}
2642
+ <button
2643
+ type="button"
2644
+ class="icon danger"
2645
+ title=${t.deleteMessage}
2646
+ aria-label=${t.deleteMessage}
2647
+ @click=${()=>this.deleteMessage(e)}
2648
+ >
2649
+ ${v.trash()}
2650
+ </button>
2651
+ </div>`}
2652
+ </div>`}pillLabel(){return this.mode==="rag"?this.msg.searching:this.mode==="rich"?this.msg.building:this.msg.thinking}renderBot(e,t){const i=this.msg,a=e.phase==="pending",r=e.phase==="done",l=e.sources.length,c=Pe(e.content),m=e.sources.map((b,T)=>_(b,T+1)),x=c.size?m.filter(b=>c.has(b.n)):m,f=e.at?new Date(e.at).toLocaleTimeString([],{hour:"numeric",minute:"2-digit"}):"",S=e.content+(x.length?`
2653
+
2654
+ Sources:
2655
+ ${x.map(b=>`[${b.n}] ${b.title}`).join(`
2656
+ `)}`:""),C=this.retrievalOpen.has(e.key);return s.html`<div class="msg bot" part="message assistant">
2657
+ ${a?s.html`<div class="halo"></div>`:s.nothing}
2658
+ ${this.arrivedKey===e.key?s.html`<div class="arrived">
2659
+ <div class="wash"></div>
2660
+ <div class="ring"></div>
2661
+ <div class="sweep"></div>
2662
+ </div>`:s.nothing}
2663
+ <div class="bot-body">
2664
+ ${e.bookmarked?s.html`<span class="saved">${v.bookmark(!0)}${i.saved}</span>`:s.nothing}
2665
+ ${a?s.html`<div class="pill" role="status">
2666
+ <span class="ring"></span><span class="dot"></span>
2667
+ <span class="shimmer">${this.pillLabel()}</span>
2668
+ </div>`:s.nothing}
2669
+ ${l&&!a?s.html`<div class="retrieval">
2670
+ <button
2671
+ type="button"
2672
+ class="retrieval-toggle"
2673
+ aria-expanded=${C?"true":"false"}
2674
+ @click=${()=>{const b=new Set(this.retrievalOpen);b.has(e.key)?b.delete(e.key):b.add(e.key),this.retrievalOpen=b}}
2675
+ >
2676
+ <span class="chev">${C?"▾":"▸"}</span>
2677
+ <span style="flex:1">${$.fill(i.searchedSources,{n:l})}</span>
2678
+ ${e.execTime!==void 0?s.html`<span class="ms">${e.execTime.toFixed(1)}s</span>`:s.nothing}
2679
+ </button>
2680
+ ${C?s.html`<div class="retrieval-list">
2681
+ ${m.map(b=>s.html`<button
2682
+ type="button"
2683
+ class="passage"
2684
+ @click=${()=>this.panel={key:e.key,n:b.n}}
2685
+ >
2686
+ <span class="n">${b.n}</span>
2687
+ <span class="what"
2688
+ ><span>${b.title}</span><span>${b.collection||b.path}</span></span
2689
+ >
2690
+ ${b.score!==null?s.html`<span class="relevance"
2691
+ ><span class="score">${b.score.toFixed(2)}</span>
2692
+ <span class="relevance-track"
2693
+ ><span
2694
+ class="relevance-fill"
2695
+ style="width:${Math.round(b.score*100)}%"
2696
+ ></span></span
2697
+ ></span>`:s.html`<span></span>`}
2698
+ </button>`)}
2699
+ </div>`:s.nothing}
2700
+ </div>`:s.nothing}
2701
+ ${a?s.nothing:this.renderAnswer(e)}
2702
+ ${e.phase==="streaming"?s.html`<span class="caret"></span>`:s.nothing}
2703
+ ${e.phase==="error"?s.html`<div class="error-card" role="alert">
2704
+ <span>${e.error}</span>
2705
+ <button type="button" class="btn" @click=${()=>this.retry(e)}>
2706
+ ${i.retry}
2707
+ </button>
2708
+ </div>`:s.nothing}
2709
+ ${r&&x.length?s.html`<div class="cards">
2710
+ <span class="label">${c.size?i.sourcesCited:i.sourcesRetrieved}</span>
2711
+ <div class="card-grid">
2712
+ ${x.map(b=>{var T;return s.html`<button
2713
+ type="button"
2714
+ class="source-card ${((T=this.panel)==null?void 0:T.key)===e.key&&this.panel.n===b.n?"active":""}"
2715
+ @click=${()=>this.panel={key:e.key,n:b.n}}
2716
+ >
2717
+ <span class="top"
2718
+ ><span class="num">${b.n}</span
2719
+ >${b.collection?s.html`<span class="label">${b.collection}</span>`:s.nothing}</span
2720
+ >
2721
+ <span class="t">${b.title}</span>
2722
+ <span class="s">${b.text}</span>
2723
+ </button>`})}
2724
+ </div>
2725
+ </div>`:s.nothing}
2726
+ ${r?s.html`<div class="toolbar ${t?"pinned":""}">
2727
+ <button
2728
+ type="button"
2729
+ class="icon"
2730
+ title=${this.copiedKey===e.key?i.copied:i.copy}
2731
+ aria-label=${i.copy}
2732
+ @click=${()=>this.copy(e.key,S)}
2733
+ >
2734
+ ${v.copy()}
2735
+ </button>
2736
+ ${t&&!this.busy?s.html`<button
2737
+ type="button"
2738
+ class="icon"
2739
+ title=${i.regenerate}
2740
+ aria-label=${i.regenerate}
2741
+ @click=${()=>this.regenerate()}
2742
+ >
2743
+ ${v.refresh()}
2744
+ </button>`:s.nothing}
2745
+ ${e.id?s.html`<button
2746
+ type="button"
2747
+ class="icon ${e.bookmarked?"on":""}"
2748
+ title=${e.bookmarked?i.unbookmarkMessage:i.bookmarkMessage}
2749
+ aria-label=${e.bookmarked?i.unbookmarkMessage:i.bookmarkMessage}
2750
+ @click=${()=>this.toggleMessageBookmark(e)}
2751
+ >
2752
+ ${v.bookmark(e.bookmarked)}
2753
+ </button>`:s.nothing}
2754
+ <button
2755
+ type="button"
2756
+ class="icon danger"
2757
+ title=${i.deleteMessage}
2758
+ aria-label=${i.deleteMessage}
2759
+ @click=${()=>this.deleteMessage(e)}
2760
+ >
2761
+ ${v.trash()}
2762
+ </button>
2763
+ <span class="time">${f}</span>
2764
+ ${e.stopped?s.html`<span class="note">${i.stopped}</span>`:s.nothing}
2765
+ <span class="spacer"></span>
2766
+ ${e.feedback?s.html`<span class="note"
2767
+ >${e.feedback==="up"?i.markedHelpful:i.thanksFeedback}</span
2768
+ >`:s.html`<button
2769
+ type="button"
2770
+ class="icon"
2771
+ title=${i.helpful}
2772
+ aria-label=${i.helpful}
2773
+ @click=${()=>this.feedback(e,"up")}
2774
+ >
2775
+ ${v.thumb()}
2776
+ </button>
2777
+ <button
2778
+ type="button"
2779
+ class="icon"
2780
+ title=${i.notHelpful}
2781
+ aria-label=${i.notHelpful}
2782
+ @click=${()=>this.feedback(e,"down")}
2783
+ >
2784
+ ${v.thumb(!0)}
2785
+ </button>`}
2786
+ </div>`:s.nothing}
2787
+ ${r&&t&&!this.busy&&e.followups.length?s.html`<div class="followups">
2788
+ ${e.followups.map(b=>s.html`<button type="button" class="followup" @click=${()=>this.send(b)}>
2789
+ <span class="arrow">↳</span><span>${b}</span>
2790
+ </button>`)}
2791
+ </div>`:s.nothing}
2792
+ </div>
2793
+ </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=ht(ct(e.content),this.renderAs),i=this.renderAs==="text"?0:e.sources.length;return s.html`<div class="answer" part="answer">
2794
+ ${t.map((a,r)=>this.renderBlock(a,e,i,r))}
2795
+ </div>`}renderInline(e,t,i){return pt(e,i).map(a=>{var r;switch(a.type){case"bold":return s.html`<strong>${a.text}</strong>`;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"
2796
+ >${a.text}</a
2797
+ >`;case"cite":{const l=((r=this.panel)==null?void 0:r.key)===t.key&&this.panel.n===a.n?"cite active":"cite",c=$.fill(this.msg.openSource,{n:a.n}),m=()=>this.panel={key:t.key,n:a.n};return s.html`<button type="button" class=${l} aria-label=${c} @click=${m}>${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>${this.renderInline(e.text,t,i)}</h3>`;case"list":{const r=e.items.map(l=>s.html`<li>${this.renderInline(l,t,i)}</li>`);return e.ordered?s.html`<ol>
2798
+ ${r}
2799
+ </ol>`:s.html`<ul>
2800
+ ${r}
2801
+ </ul>`}case"quote":return s.html`<div class="quote">${this.renderInline(e.text,t,i)}</div>`;case"code":{const r=`${t.key}:${a}`;return s.html`<div class="code">
2802
+ <div class="code-head">
2803
+ <span class="label">${e.lang}</span>
2804
+ <button type="button" class="text-btn" @click=${()=>this.copy(r,e.text)}>
2805
+ ${this.copiedKey===r?this.msg.copied:this.msg.copy}
2806
+ </button>
2807
+ </div>
2808
+ <pre><code>${e.text}</code></pre>
2809
+ </div>`}case"table":return s.html`<div class="table">
2810
+ <table>
2811
+ <thead>
2812
+ <tr>
2813
+ ${e.head.map(r=>s.html`<th>${this.renderInline(r,t,i)}</th>`)}
2814
+ </tr>
2815
+ </thead>
2816
+ <tbody>
2817
+ ${e.rows.map(r=>s.html`<tr>
2818
+ ${r.map(l=>s.html`<td>${this.renderInline(l,t,i)}</td>`)}
2819
+ </tr>`)}
2820
+ </tbody>
2821
+ </table>
2822
+ </div>`;case"chart":return this.renderChart(e.spec);case"chartPending":return s.html`<div class="chart-pending"><span class="label">Rendering chart</span></div>`;case"img":return s.html`<div class="gallery ${e.images.length>1?"many":""}">
2823
+ ${e.images.map(r=>s.html`<figure>
2824
+ ${r.src&&Qe(r.src,!0)?s.html`<img
2825
+ src=${r.src}
2826
+ alt=${r.alt}
2827
+ loading="lazy"
2828
+ referrerpolicy="no-referrer"
2829
+ />`:s.html`<div class="img-missing"><span class="label">Image</span></div>`}
2830
+ ${r.alt?s.html`<figcaption>${r.alt}</figcaption>`:s.nothing}
2831
+ </figure>`)}
2832
+ </div>`;default:return s.nothing}}renderChart(e){const t=e.series.length>1?s.html`<span class="legend">
2833
+ ${e.series.map((l,c)=>s.html`<span
2834
+ ><span
2835
+ class="swatch"
2836
+ style="background:${z[c%z.length]}"
2837
+ ></span
2838
+ >${l.name}</span
2839
+ >`)}
2840
+ </span>`:s.nothing,i=s.html`<div class="chart-head">
2841
+ <span class="chart-title">${e.title}</span>${t}
2842
+ </div>`;if(e.type==="line"){const l=Math.max(0,...e.series.flatMap(f=>f.values)),c=Math.pow(10,Math.floor(Math.log10(l||1))),m=Math.ceil(l/c*2)/2*c||1,x=Math.max(e.labels.length,...e.series.map(f=>f.values.length));return s.html`<figure class="chart" part="chart" aria-label=${e.title}>
2843
+ ${i}
2844
+ <div class="line-chart">
2845
+ <div class="plot">
2846
+ ${[1,.5,0].map(f=>s.html`<div class="tick ${f===0?"base":""}" style="top:${(1-f)*100}%">
2847
+ <span>${Re(Math.round(m*f),e.unit)}</span>
2848
+ </div>`)}
2849
+ <svg
2850
+ viewBox="0 0 600 170"
2851
+ preserveAspectRatio="none"
2852
+ role="img"
2853
+ aria-label=${e.title}
2854
+ >
2855
+ ${e.series.map((f,S)=>s.svg`<polyline pathLength="1" stroke=${z[S%z.length]}
2856
+ points=${f.values.map((C,b)=>`${(x>1?b/(x-1)*600:300).toFixed(1)},${(170-C/m*170).toFixed(1)}`).join(" ")}><title>${f.name}: ${f.values.map(C=>Re(C,e.unit)).join(", ")}</title></polyline>`)}
2857
+ </svg>
2858
+ </div>
2859
+ <div class="x-labels">${e.labels.map(f=>s.html`<span>${f}</span>`)}</div>
2860
+ </div>
2861
+ </figure>`}const a=e.labels.map((l,c)=>e.series.reduce((m,x)=>m+(x.values[c]||0),0)),r=Math.max(0,...a)||1;return s.html`<figure class="chart" part="chart" aria-label=${e.title}>
2862
+ ${i}
2863
+ <div class="bars">
2864
+ ${e.labels.map((l,c)=>s.html`<div class="bar-row" title="${l}: ${Re(a[c],e.unit)}">
2865
+ <span class="bar-label">${l}</span>
2866
+ <span class="bar-track"
2867
+ ><span class="bar-fill" style="width:${Math.max(0,a[c])/r*100}%">
2868
+ ${e.series.map((m,x)=>s.html`<span
2869
+ style="flex:${Math.max(0,m.values[c]||0)};background:${e.series.length>1?z[x%z.length]:"var(--c-ink)"}"
2870
+ ></span>`)}
2871
+ </span></span
2872
+ >
2873
+ <span class="bar-value">${Re(a[c],e.unit)}</span>
2874
+ </div>`)}
2875
+ </div>
2876
+ </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=_(t,this.panel.n),r=Pe(e.content),l=e.sources.map((f,S)=>_(f,S+1)).filter(f=>f.n!==a.n&&(!r.size||r.has(f.n))),c=`ref:${e.key}:${a.n}`,m=`"${a.text}"
2877
+ — ${a.title} [${a.n}]${a.path?`
2878
+ ${a.path}`:""}${a.updated?` · Updated ${a.updated}`:""}`,x=[a.updated?`Updated ${a.updated}`:"",a.score!==null?`Relevance ${a.score.toFixed(2)}`:""].filter(Boolean).join(" · ");return s.html`<aside
2879
+ class="panel ${this.panelDocked?"docked":"overlay"}"
2880
+ part="panel"
2881
+ role="region"
2882
+ aria-label=${$.fill(i.sourceLabel,{n:a.n})}
2883
+ >
2884
+ <div class="panel-head">
2885
+ <span class="label"
2886
+ >${$.fill(i.sourceLabel,{n:a.n})}${a.collection?` · ${a.collection}`:""}</span
2887
+ >
2888
+ <button type="button" class="text-btn underline" @click=${()=>this.panel=null}>
2889
+ ${i.close}
2890
+ </button>
2891
+ </div>
2892
+ <div class="panel-body">
2893
+ <div class="panel-meta">
2894
+ <h3>${a.title}</h3>
2895
+ ${a.path?s.html`<span class="path">${a.path}</span>`:s.nothing}
2896
+ ${x?s.html`<span class="meta">${x}</span>`:s.nothing}
2897
+ </div>
2898
+ <div class="passage-box">
2899
+ <span class="text">${a.text}</span>
2900
+ <div class="passage-foot">
2901
+ <span class="label">${i.citedPassage}</span>
2902
+ <button
2903
+ type="button"
2904
+ class="copy-ref"
2905
+ title=${i.copyReference}
2906
+ aria-label=${i.copyReference}
2907
+ @click=${()=>this.copy(c,m)}
2908
+ >
2909
+ ${v.copy()}<span>${this.copiedKey===c?i.copied:i.copy}</span>
2910
+ </button>
2911
+ </div>
2912
+ </div>
2913
+ </div>
2914
+ ${l.length?s.html`<div class="panel-foot">
2915
+ <span class="label">${i.alsoCited}</span>
2916
+ <div class="chips">
2917
+ ${l.map(f=>s.html`<button
2918
+ type="button"
2919
+ class="chip"
2920
+ @click=${()=>this.panel={key:e.key,n:f.n}}
2921
+ >
2922
+ ${f.n} · ${f.title}
2923
+ </button>`)}
2924
+ </div>
2925
+ </div>`:s.nothing}
2926
+ </aside>`}renderComposer(){const e=this.msg,t=this.mode==="rag"?e.placeholderRag:this.mode==="rich"?e.placeholderRich:$.fill(e.placeholderChat,{name:this.assistantName}),i=!this.draft.trim();return s.html`<div class="composer-wrap">
2927
+ <div class="composer-col">
2928
+ <input
2929
+ type="file"
2930
+ multiple
2931
+ hidden
2932
+ accept=".md,.markdown,.txt,.csv,.tsv,.json,.html,.htm,.yaml,.yml,.xml,.log,text/*"
2933
+ @change=${a=>{const r=a.target;this.addFiles(r.files).then(()=>r.value="")}}
2934
+ />
2935
+ <div class="composer-box">
2936
+ ${this.busy?s.html`<div class="composer-glow"></div>`:s.nothing}
2937
+ <div class="composer ${this.busy?"busy":""}" part="composer">
2938
+ ${this.files.length?s.html`<div class="pending-files">
2939
+ ${this.files.map(a=>s.html`<div class="pending-file">
2940
+ <span class="ext">${rt(a.name)}</span>
2941
+ <span class="meta"
2942
+ ><span class="name">${a.name}</span
2943
+ ><span class="size">${$.formatSize(a.size)}</span></span
2944
+ >
2945
+ <button
2946
+ type="button"
2947
+ aria-label=${e.removeFile}
2948
+ title=${e.removeFile}
2949
+ @click=${()=>this.files=this.files.filter(r=>r!==a)}
2950
+ >
2951
+ ×
2952
+ </button>
2953
+ </div>`)}
2954
+ </div>`:s.nothing}
2955
+ <textarea
2956
+ class="input"
2957
+ rows="1"
2958
+ placeholder=${t}
2959
+ aria-label=${t}
2960
+ .value=${this.draft}
2961
+ @input=${this.onComposerInput}
2962
+ @keydown=${this.onComposerKey}
2963
+ ></textarea>
2964
+ <div class="composer-row">
2965
+ <div>
2966
+ ${this.allowUpload?s.html`<button
2967
+ type="button"
2968
+ class="attach"
2969
+ title=${e.attach}
2970
+ aria-label=${e.attach}
2971
+ @click=${()=>{var a;return(a=this.renderRoot.querySelector("input[type=file]"))==null?void 0:a.click()}}
2972
+ >
2973
+ ${v.clip()}
2974
+ </button>`:s.nothing}
2975
+ </div>
2976
+ ${this.busy?s.html`<button
2977
+ type="button"
2978
+ class="send stop"
2979
+ title=${e.stop}
2980
+ aria-label=${e.stop}
2981
+ @click=${()=>this.stop()}
2982
+ >
2983
+ ${v.stop()}
2984
+ </button>`:s.html`<button
2985
+ type="button"
2986
+ class="send"
2987
+ title=${e.send}
2988
+ aria-label=${e.send}
2989
+ ?disabled=${i}
2990
+ @click=${()=>this.send()}
2991
+ >
2992
+ ${v.up()}
2993
+ </button>`}
2994
+ </div>
2995
+ </div>
2996
+ ${this.busy?s.html`<div class="composer-ring"><div class="ring"></div></div>`:s.nothing}
2997
+ </div>
2998
+ <span class="footnote">${$.fill(e.footnote,{name:this.assistantName})}</span>
2999
+ </div>
3000
+ </div>`}},I=new WeakMap,L=new WeakMap,j=new WeakMap,A=new WeakMap,E=new WeakMap,N=new WeakMap,B=new WeakMap,D=new WeakMap,R=new WeakMap,U=new WeakMap,F=new WeakMap,K=new WeakMap,P=new WeakMap,H=new WeakMap,J=new WeakMap,W=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,pe=new WeakMap,he=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,ke=new WeakMap,we=new WeakMap,$e=new WeakMap,Ce=new WeakMap,Se=new WeakMap,Te=new WeakMap,ze=new WeakMap,Me=new WeakMap,Oe=new WeakMap,_e=new WeakMap,Ie=new WeakMap,Le=new WeakMap,je=new WeakMap,Ae=new WeakMap,Ee=new WeakMap,Ne=new WeakMap,Be=new WeakMap,nt);Mt(exports.SinglebaseChat,"styles",[$.tokenDefaults,vt]);g([u.property({attribute:!1})],exports.SinglebaseChat.prototype,"client",1);g([u.property({attribute:!1})],exports.SinglebaseChat.prototype,"messages",1);g([u.property({reflect:!0})],exports.SinglebaseChat.prototype,"theme",1);g([u.property({reflect:!0})],exports.SinglebaseChat.prototype,"mode",1);g([u.property({attribute:"render-as"})],exports.SinglebaseChat.prototype,"renderAs",1);g([u.property({reflect:!0})],exports.SinglebaseChat.prototype,"glow",1);g([u.property({converter:M})],exports.SinglebaseChat.prototype,"followups",1);g([u.property({converter:M,attribute:"auto-title"})],exports.SinglebaseChat.prototype,"autoTitle",1);g([u.property()],exports.SinglebaseChat.prototype,"model",1);g([u.property({converter:Je})],exports.SinglebaseChat.prototype,"params",1);g([u.property({attribute:"system-message"})],exports.SinglebaseChat.prototype,"systemMessage",1);g([u.property({converter:Je})],exports.SinglebaseChat.prototype,"retrieval",1);g([u.property({converter:Je})],exports.SinglebaseChat.prototype,"metadata",1);g([u.property({reflect:!0})],exports.SinglebaseChat.prototype,"embed",1);g([u.property({reflect:!0})],exports.SinglebaseChat.prototype,"position",1);g([u.property({converter:Ot})],exports.SinglebaseChat.prototype,"sidebar",1);g([u.property({converter:M,attribute:"show-title"})],exports.SinglebaseChat.prototype,"showTitle",1);g([u.property({attribute:"chat-id"})],exports.SinglebaseChat.prototype,"chatIdAttr",1);g([u.property({attribute:"assistant-name"})],exports.SinglebaseChat.prototype,"assistantName",1);g([u.property({attribute:"logo-url"})],exports.SinglebaseChat.prototype,"logoUrl",1);g([u.property()],exports.SinglebaseChat.prototype,"heading",1);g([u.property()],exports.SinglebaseChat.prototype,"description",1);g([u.property()],exports.SinglebaseChat.prototype,"prompts",1);g([u.property({attribute:"bubble-text"})],exports.SinglebaseChat.prototype,"bubbleText",1);g([u.property({type:Boolean,attribute:"greeting-bubble"})],exports.SinglebaseChat.prototype,"greetingBubble",1);g([u.property({type:Boolean,attribute:"unread-badge"})],exports.SinglebaseChat.prototype,"unreadBadge",1);g([u.property({converter:M,attribute:"allow-upload"})],exports.SinglebaseChat.prototype,"allowUpload",1);g([u.property({converter:M,attribute:"allow-export"})],exports.SinglebaseChat.prototype,"allowExport",1);g([u.property({converter:M})],exports.SinglebaseChat.prototype,"branding",1);g([u.state()],exports.SinglebaseChat.prototype,"chatList",1);g([u.state()],exports.SinglebaseChat.prototype,"listState",1);g([u.state()],exports.SinglebaseChat.prototype,"activeId",1);g([u.state()],exports.SinglebaseChat.prototype,"chatTitle",1);g([u.state()],exports.SinglebaseChat.prototype,"bookmarked",1);g([u.state()],exports.SinglebaseChat.prototype,"msgs",1);g([u.state()],exports.SinglebaseChat.prototype,"loadingThread",1);g([u.state()],exports.SinglebaseChat.prototype,"threadError",1);g([u.state()],exports.SinglebaseChat.prototype,"busy",1);g([u.state()],exports.SinglebaseChat.prototype,"draft",1);g([u.state()],exports.SinglebaseChat.prototype,"files",1);g([u.state()],exports.SinglebaseChat.prototype,"search",1);g([u.state()],exports.SinglebaseChat.prototype,"sidebarOpen",1);g([u.state()],exports.SinglebaseChat.prototype,"width",1);g([u.state()],exports.SinglebaseChat.prototype,"panel",1);g([u.state()],exports.SinglebaseChat.prototype,"menuOpen",1);g([u.state()],exports.SinglebaseChat.prototype,"editingKey",1);g([u.state()],exports.SinglebaseChat.prototype,"editDraft",1);g([u.state()],exports.SinglebaseChat.prototype,"editingTitle",1);g([u.state()],exports.SinglebaseChat.prototype,"renamingId",1);g([u.state()],exports.SinglebaseChat.prototype,"toast",1);g([u.state()],exports.SinglebaseChat.prototype,"copiedKey",1);g([u.state()],exports.SinglebaseChat.prototype,"retrievalOpen",1);g([u.state()],exports.SinglebaseChat.prototype,"arrivedKey",1);g([u.state()],exports.SinglebaseChat.prototype,"dragging",1);g([u.state()],exports.SinglebaseChat.prototype,"showJump",1);g([u.state()],exports.SinglebaseChat.prototype,"offline",1);g([u.state()],exports.SinglebaseChat.prototype,"isOpen",1);g([u.state()],exports.SinglebaseChat.prototype,"expanded",1);g([u.state()],exports.SinglebaseChat.prototype,"bubble",1);g([u.state()],exports.SinglebaseChat.prototype,"seen",1);g([u.state()],exports.SinglebaseChat.prototype,"mobile",1);exports.SinglebaseChat=g([u.customElement("singlebase-chat")],exports.SinglebaseChat);exports.adaptBlocks=ht;exports.citedNumbers=Pe;exports.defaultChatMessages=ot;exports.describeSource=_;exports.parseInline=pt;exports.parseMarkdown=ct;exports.resolveChatMessages=lt;exports.splitFollowups=He;
3001
+ //# sourceMappingURL=chat-DRenTJlI.cjs.map