@green-on-grey/ui-kit 1.3.0 → 1.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.
package/dist/chat.js CHANGED
@@ -168,22 +168,23 @@ var S = /* @__PURE__ */ new Set([
168
168
  "image/gif",
169
169
  "image/webp",
170
170
  "image/svg+xml"
171
- ]), C = /\.(png|jpe?g|gif|webp|svg)$/, w = /\.(txt|log|json|ya?ml|xml|ini|toml|sql|sh|py|go|js|ts|tsx|java|kt|rb|rs|c|cpp|h|css|html?)$/;
171
+ ]), C = /\.(png|jpe?g|gif|webp|svg)$/, w = /\.(txt|log|json|ya?ml|xml|ini|toml|sql|sh|py|go|js|ts|tsx|java|kt|rb|rs|c|cpp|h|css)$/;
172
172
  function T(e) {
173
173
  let t = (e.mimeType ?? "").toLowerCase().split(";")[0].trim(), n = e.fileName.toLowerCase();
174
- return S.has(t) || (!t || t === "application/octet-stream") && C.test(n) ? "image" : t === "application/pdf" || n.endsWith(".pdf") ? "pdf" : t === "text/markdown" || /\.(md|markdown)$/.test(n) ? "markdown" : t === "text/csv" || t === "text/tab-separated-values" || /\.(csv|tsv)$/.test(n) ? "table" : t.startsWith("text/") || t === "application/json" || t === "application/xml" || w.test(n) ? "text" : null;
174
+ return S.has(t) || (!t || t === "application/octet-stream") && C.test(n) ? "image" : t === "application/pdf" || n.endsWith(".pdf") ? "pdf" : t === "text/markdown" || /\.(md|markdown)$/.test(n) ? "markdown" : t === "text/csv" || t === "text/tab-separated-values" || /\.(csv|tsv)$/.test(n) ? "table" : t === "text/html" || /\.html?$/.test(n) ? "html" : t.startsWith("text/") || t === "application/json" || t === "application/xml" || w.test(n) ? "text" : null;
175
175
  }
176
176
  var E = {
177
177
  image: "image",
178
178
  pdf: "pdf",
179
179
  markdown: "markdown",
180
180
  table: "table",
181
+ html: "globe",
181
182
  text: "source"
182
- };
183
- function D(e, t) {
184
- return t === "pdf" ? "PDF" : t === "markdown" ? "MD" : /\.([a-z0-9]{1,5})$/i.exec(e.fileName)?.[1]?.toUpperCase() ?? (t ? "TXT" : "FILE");
185
- }
183
+ }, D = (e) => E[e];
186
184
  function O(e, t) {
185
+ return t === "pdf" ? "PDF" : t === "markdown" ? "MD" : t === "html" ? "HTML" : /\.([a-z0-9]{1,5})$/i.exec(e.fileName)?.[1]?.toUpperCase() ?? (t ? "TXT" : "FILE");
186
+ }
187
+ function k(e, t) {
187
188
  let n = [
188
189
  "byte",
189
190
  "kilobyte",
@@ -198,7 +199,64 @@ function O(e, t) {
198
199
  maximumFractionDigits: i === 0 ? 0 : 1
199
200
  }).format(r);
200
201
  }
201
- function k(e, t) {
202
+ var A = "default-src 'none'; img-src data: blob:; media-src data: blob:; font-src data:; style-src 'unsafe-inline' data:";
203
+ function j(e) {
204
+ let t = `<meta http-equiv="Content-Security-Policy" content="${A}">`, n = /^\s*<!doctype[^>]*>/i.exec(e)?.[0] ?? "";
205
+ if (typeof DOMParser > "u") return n + t + e.slice(n.length);
206
+ let r = new DOMParser().parseFromString(e, "text/html");
207
+ r.querySelectorAll("script, noscript, iframe, frame, frameset, object, embed, applet, base, link, meta[http-equiv], portal").forEach((e) => e.remove()), r.querySelectorAll("*").forEach((e) => {
208
+ for (let t of Array.from(e.attributes)) {
209
+ let n = t.name.toLowerCase();
210
+ n.startsWith("on") || ee.has(n) && !M.test(t.value) || n === "srcset" && t.value.split(",").some((e) => !M.test(e)) ? e.removeAttribute(t.name) : n === "style" && e.setAttribute("style", N(t.value));
211
+ }
212
+ }), r.querySelectorAll("style").forEach((e) => {
213
+ e.textContent = N(e.textContent ?? "");
214
+ });
215
+ let i = r.createElement("meta");
216
+ return i.setAttribute("http-equiv", "Content-Security-Policy"), i.setAttribute("content", A), r.head.prepend(i), (n ? "<!doctype html>" : "") + r.documentElement.outerHTML;
217
+ }
218
+ var ee = /* @__PURE__ */ new Set([
219
+ "src",
220
+ "href",
221
+ "xlink:href",
222
+ "action",
223
+ "formaction",
224
+ "poster",
225
+ "background",
226
+ "data",
227
+ "ping",
228
+ "lowsrc",
229
+ "dynsrc",
230
+ "manifest",
231
+ "cite",
232
+ "longdesc",
233
+ "codebase",
234
+ "archive",
235
+ "usemap"
236
+ ]), M = /^\s*(data:|blob:|#|$)/i;
237
+ function N(e) {
238
+ return e.replace(/@import[^;]*;?/gi, "").replace(/url\(\s*(['"]?)(.*?)\1\s*\)/gi, (e, t, n) => M.test(n) && n.trim() !== "" ? e : "none");
239
+ }
240
+ var P = {
241
+ png: "image/png",
242
+ jpg: "image/jpeg",
243
+ jpeg: "image/jpeg",
244
+ gif: "image/gif",
245
+ webp: "image/webp",
246
+ svg: "image/svg+xml",
247
+ pdf: "application/pdf",
248
+ md: "text/markdown",
249
+ markdown: "text/markdown",
250
+ csv: "text/csv",
251
+ tsv: "text/tab-separated-values",
252
+ html: "text/html",
253
+ htm: "text/html"
254
+ };
255
+ function F(e) {
256
+ let t = (e.mimeType ?? "").split(";")[0].trim().toLowerCase();
257
+ return t && t !== "application/octet-stream" ? t : P[/\.([a-z0-9]+)$/i.exec(e.fileName)?.[1]?.toLowerCase() ?? ""] ?? (t || void 0);
258
+ }
259
+ function I(e, t) {
202
260
  if (t) return e.replace(/\r?\n$/, "").split(/\r?\n/).map((e) => e.split(" "));
203
261
  let n = [], r = [], i = "", a = !1;
204
262
  for (let t = 0; t < e.length; t++) {
@@ -207,7 +265,7 @@ function k(e, t) {
207
265
  }
208
266
  return (i !== "" || r.length > 0) && (r.push(i), n.push(r)), n;
209
267
  }
210
- function A(e, t, n = !0) {
268
+ function L(e, t, n = !0) {
211
269
  let [r, i] = h({}), { id: a, href: o, fileName: s, mimeType: c, size: l } = e;
212
270
  return d(() => {
213
271
  if (!n) return;
@@ -220,10 +278,13 @@ function A(e, t, n = !0) {
220
278
  size: l
221
279
  }).then((t) => {
222
280
  if (!r) return;
223
- let n = c && t.type !== c ? new Blob([t], { type: c }) : t;
224
- e = URL.createObjectURL(n), i({
281
+ let n = F({
282
+ fileName: s,
283
+ mimeType: c
284
+ }), a = n && t.type !== n ? new Blob([t], { type: n }) : t;
285
+ e = URL.createObjectURL(a), i({
225
286
  url: e,
226
- blob: n
287
+ blob: a
227
288
  });
228
289
  }, () => r && i({ failed: !0 })), () => {
229
290
  r = !1, e && URL.revokeObjectURL(e);
@@ -238,9 +299,9 @@ function A(e, t, n = !0) {
238
299
  l
239
300
  ]), r;
240
301
  }
241
- function j({ a: e, load: t, onOpen: n }) {
242
- let r = a(), { url: i, failed: o } = A(e, t);
243
- return o ? /* @__PURE__ */ c(M, {
302
+ function R({ a: e, load: t, onOpen: n }) {
303
+ let r = a(), { url: i, failed: o } = L(e, t);
304
+ return o ? /* @__PURE__ */ c(z, {
244
305
  a: e,
245
306
  kind: "image",
246
307
  onOpen: n
@@ -262,7 +323,7 @@ function j({ a: e, load: t, onOpen: n }) {
262
323
  })]
263
324
  });
264
325
  }
265
- function M({ a: e, kind: n, onOpen: r }) {
326
+ function z({ a: e, kind: n, onOpen: r }) {
266
327
  let i = a(), { i18n: u } = g(o), d = n !== null && r !== void 0, f = /* @__PURE__ */ l(s, { children: [
267
328
  /* @__PURE__ */ l("span", {
268
329
  className: "att-ic",
@@ -271,7 +332,7 @@ function M({ a: e, kind: n, onOpen: r }) {
271
332
  size: 24
272
333
  }), /* @__PURE__ */ c("span", {
273
334
  className: "att-kl",
274
- children: D(e, n)
335
+ children: O(e, n)
275
336
  })]
276
337
  }),
277
338
  /* @__PURE__ */ c("span", {
@@ -280,7 +341,7 @@ function M({ a: e, kind: n, onOpen: r }) {
280
341
  }),
281
342
  e.size != null && /* @__PURE__ */ c("span", {
282
343
  className: "att-size",
283
- children: O(e.size, u.language)
344
+ children: k(e.size, u.language)
284
345
  })
285
346
  ] });
286
347
  return d ? /* @__PURE__ */ c("button", {
@@ -299,16 +360,16 @@ function M({ a: e, kind: n, onOpen: r }) {
299
360
  children: f
300
361
  });
301
362
  }
302
- function N({ items: e, load: t, onOpen: n }) {
363
+ function B({ items: e, load: t, onOpen: n }) {
303
364
  return /* @__PURE__ */ c("div", {
304
365
  className: "atts",
305
366
  children: e.map((e) => {
306
367
  let r = t && n ? () => n(e) : void 0, i = T(e);
307
- return t && r && i === "image" ? /* @__PURE__ */ c(j, {
368
+ return t && r && i === "image" ? /* @__PURE__ */ c(R, {
308
369
  a: e,
309
370
  load: t,
310
371
  onOpen: r
311
- }, e.id) : /* @__PURE__ */ c(M, {
372
+ }, e.id) : /* @__PURE__ */ c(z, {
312
373
  a: e,
313
374
  kind: i,
314
375
  onOpen: r
@@ -316,8 +377,8 @@ function N({ items: e, load: t, onOpen: n }) {
316
377
  })
317
378
  });
318
379
  }
319
- function P({ text: e, tab: t }) {
320
- let n = a(), [r, ...i] = k(e, t), o = i.slice(0, 500);
380
+ function V({ text: e, tab: t }) {
381
+ let n = a(), [r, ...i] = I(e, t), o = i.slice(0, 500);
321
382
  return /* @__PURE__ */ l("div", {
322
383
  className: "att-table",
323
384
  children: [/* @__PURE__ */ l("table", { children: [r && /* @__PURE__ */ c("thead", { children: /* @__PURE__ */ c("tr", { children: r.map((e, t) => /* @__PURE__ */ c("th", { children: e }, t)) }) }), /* @__PURE__ */ c("tbody", { children: o.map((e, t) => /* @__PURE__ */ c("tr", { children: e.map((e, t) => /* @__PURE__ */ c("td", { children: e }, t)) }, t)) })] }), i.length > o.length && /* @__PURE__ */ c("div", {
@@ -329,32 +390,61 @@ function P({ text: e, tab: t }) {
329
390
  })]
330
391
  });
331
392
  }
332
- function ee({ a: e, load: i, onClose: u }) {
333
- let f = a(), { i18n: p } = g(o), m = T(e), _ = m === "markdown" || m === "table" || m === "text", v = _ && (e.size ?? 0) > 1048576, { url: y, blob: b, failed: x } = A(e, i, !v), [S, C] = h(null), w = v || _ && (b?.size ?? 0) > 1048576;
393
+ var H = 1280;
394
+ function U({ text: e, title: t }) {
395
+ let n = m(null), [r, i] = h(1);
334
396
  d(() => {
335
- _ && b && !w && b.arrayBuffer().then((e) => {
397
+ let e = n.current;
398
+ if (!e) return;
399
+ let t = () => i(Math.min(1, e.clientWidth / H));
400
+ if (t(), typeof ResizeObserver > "u") return;
401
+ let r = new ResizeObserver(t);
402
+ return r.observe(e), () => r.disconnect();
403
+ }, []);
404
+ let a = p(() => j(e), [e]);
405
+ return /* @__PURE__ */ c("div", {
406
+ className: "att-htmlbox",
407
+ ref: n,
408
+ children: /* @__PURE__ */ c("iframe", {
409
+ className: "att-html",
410
+ sandbox: "",
411
+ srcDoc: a,
412
+ title: t,
413
+ referrerPolicy: "no-referrer",
414
+ style: {
415
+ width: H,
416
+ height: `${100 / r}%`,
417
+ transform: `scale(${r})`
418
+ }
419
+ })
420
+ });
421
+ }
422
+ function te({ a: e, load: i, onClose: u }) {
423
+ let f = a(), { i18n: p } = g(o), m = T(e), _ = m === "markdown" || m === "table" || m === "html" || m === "text", [v, y] = h(!1), b = _ && (e.size ?? 0) > 1048576, { url: x, blob: S, failed: C } = L(e, i, !b), [w, E] = h(null), D = b || _ && (S?.size ?? 0) > 1048576;
424
+ d(() => {
425
+ _ && S && !D && S.arrayBuffer().then((e) => {
336
426
  try {
337
- C({ text: new TextDecoder("utf-8", { fatal: !0 }).decode(e) });
427
+ E({ text: new TextDecoder("utf-8", { fatal: !0 }).decode(e) });
338
428
  } catch {
339
- C({ text: null });
429
+ E({ text: null });
340
430
  }
341
- }, () => C({ text: null }));
431
+ }, () => E({ text: null }));
342
432
  }, [
343
433
  _,
344
- b,
345
- w
434
+ S,
435
+ D
346
436
  ]);
347
- let E = S?.text, D;
348
- return D = x ? /* @__PURE__ */ c("div", {
437
+ let O = w?.text, A;
438
+ return A = C ? /* @__PURE__ */ c("div", {
349
439
  className: "att-msg err-text",
350
440
  children: f("chat.files.failed")
351
- }) : w ? /* @__PURE__ */ c("div", {
441
+ }) : D ? /* @__PURE__ */ c("div", {
352
442
  className: "att-msg",
353
443
  children: f("chat.files.tooLarge")
354
- }) : S && E === null ? /* @__PURE__ */ c("div", {
444
+ }) : w && O === null ? /* @__PURE__ */ c("div", {
355
445
  className: "att-msg",
356
446
  children: f("chat.files.notUtf8")
357
- }) : !y || _ && E == null ? /* @__PURE__ */ l("div", {
447
+ }) : !x || _ && O == null ? /* @__PURE__ */ l("div", {
358
448
  className: "att-msg",
359
449
  children: [
360
450
  /* @__PURE__ */ c("span", {
@@ -366,11 +456,11 @@ function ee({ a: e, load: i, onClose: u }) {
366
456
  ]
367
457
  }) : m === "image" ? /* @__PURE__ */ c("img", {
368
458
  className: "att-img",
369
- src: y,
459
+ src: x,
370
460
  alt: e.fileName
371
461
  }) : m === "pdf" ? /* @__PURE__ */ c("object", {
372
462
  className: "att-pdf",
373
- data: y,
463
+ data: x,
374
464
  type: "application/pdf",
375
465
  "aria-label": e.fileName,
376
466
  children: /* @__PURE__ */ c("div", {
@@ -379,13 +469,16 @@ function ee({ a: e, load: i, onClose: u }) {
379
469
  })
380
470
  }) : m === "markdown" ? /* @__PURE__ */ c("div", {
381
471
  className: "att-md",
382
- children: /* @__PURE__ */ c(r, { text: E ?? "" })
383
- }) : m === "table" ? /* @__PURE__ */ c(P, {
384
- text: E ?? "",
472
+ children: /* @__PURE__ */ c(r, { text: O ?? "" })
473
+ }) : m === "table" ? /* @__PURE__ */ c(V, {
474
+ text: O ?? "",
385
475
  tab: /\.tsv$/i.test(e.fileName) || e.mimeType === "text/tab-separated-values"
476
+ }) : m === "html" && !v ? /* @__PURE__ */ c(U, {
477
+ text: O ?? "",
478
+ title: e.fileName
386
479
  }) : /* @__PURE__ */ c("pre", {
387
480
  className: "att-text",
388
- children: E
481
+ children: O
389
482
  }), /* @__PURE__ */ c(n, {
390
483
  wide: !0,
391
484
  onClose: u,
@@ -396,45 +489,61 @@ function ee({ a: e, load: i, onClose: u }) {
396
489
  children: e.fileName
397
490
  }), e.size != null && /* @__PURE__ */ c("span", {
398
491
  className: "muted small",
399
- children: O(e.size, p.language)
492
+ children: k(e.size, p.language)
400
493
  })]
401
494
  }),
402
- footer: /* @__PURE__ */ l(s, { children: [/* @__PURE__ */ l("a", {
403
- className: "btn ghost",
404
- href: y ?? e.href,
405
- download: e.fileName,
406
- children: [
407
- /* @__PURE__ */ c(t, {
408
- name: "download",
409
- size: 14
410
- }),
411
- " ",
412
- f("chat.files.download")
413
- ]
414
- }), /* @__PURE__ */ c("button", {
415
- type: "button",
416
- className: "btn primary",
417
- onClick: u,
418
- children: f("close")
419
- })] }),
495
+ footer: /* @__PURE__ */ l(s, { children: [
496
+ m === "html" && /* @__PURE__ */ l("button", {
497
+ type: "button",
498
+ className: "btn ghost",
499
+ onClick: () => y((e) => !e),
500
+ children: [
501
+ /* @__PURE__ */ c(t, {
502
+ name: v ? "globe" : "code",
503
+ size: 14
504
+ }),
505
+ " ",
506
+ f(v ? "chat.files.page" : "chat.files.source")
507
+ ]
508
+ }),
509
+ /* @__PURE__ */ l("a", {
510
+ className: "btn ghost",
511
+ href: x ?? e.href,
512
+ download: e.fileName,
513
+ children: [
514
+ /* @__PURE__ */ c(t, {
515
+ name: "download",
516
+ size: 14
517
+ }),
518
+ " ",
519
+ f("chat.files.download")
520
+ ]
521
+ }),
522
+ /* @__PURE__ */ c("button", {
523
+ type: "button",
524
+ className: "btn primary",
525
+ onClick: u,
526
+ children: f("close")
527
+ })
528
+ ] }),
420
529
  children: /* @__PURE__ */ c("div", {
421
530
  className: `att-view ${m ?? ""}`,
422
- children: D
531
+ children: A
423
532
  })
424
533
  });
425
534
  }
426
535
  //#endregion
427
536
  //#region src/chat/MessageView.tsx
428
- function F(e, t) {
537
+ function W(e, t) {
429
538
  return new Intl.DateTimeFormat(y(t), {
430
539
  hour: "2-digit",
431
540
  minute: "2-digit"
432
541
  }).format(new Date(e));
433
542
  }
434
- function I(e, t) {
543
+ function G(e, t) {
435
544
  return t || e.length <= 3 ? e : e.slice(-2);
436
545
  }
437
- var L = {
546
+ var K = {
438
547
  done: {
439
548
  icon: "check",
440
549
  cls: "ok"
@@ -448,13 +557,13 @@ var L = {
448
557
  cls: "run"
449
558
  }
450
559
  };
451
- function R({ m: e, busy: n, onRetry: i, loadAttachment: a, onOpenAttachment: u }) {
560
+ function ne({ m: e, busy: n, onRetry: i, loadAttachment: a, onOpenAttachment: u }) {
452
561
  let { t: d, i18n: f } = g(o), [p, m] = h(!1);
453
562
  if (e.role === "note") return /* @__PURE__ */ c("div", {
454
563
  className: "sysnote",
455
564
  children: e.text
456
565
  });
457
- if (e.role === "event" && e.event) return /* @__PURE__ */ c(z, { m: e });
566
+ if (e.role === "event" && e.event) return /* @__PURE__ */ c(q, { m: e });
458
567
  let _ = e.mark && /* @__PURE__ */ l("div", {
459
568
  className: "chan",
460
569
  children: [
@@ -465,9 +574,9 @@ function R({ m: e, busy: n, onRetry: i, loadAttachment: a, onOpenAttachment: u }
465
574
  " ",
466
575
  e.mark.text,
467
576
  " · ",
468
- F(e.createdAt, f.language)
577
+ W(e.createdAt, f.language)
469
578
  ]
470
- }), v = e.attachments && e.attachments.length > 0 && /* @__PURE__ */ c(N, {
579
+ }), v = e.attachments && e.attachments.length > 0 && /* @__PURE__ */ c(B, {
471
580
  items: e.attachments,
472
581
  load: a,
473
582
  onOpen: u
@@ -506,13 +615,13 @@ function R({ m: e, busy: n, onRetry: i, loadAttachment: a, onOpenAttachment: u }
506
615
  "aria-expanded": p,
507
616
  children: p ? d("chat.hideSteps") : d("chat.moreSteps", { count: y.length - 2 })
508
617
  }),
509
- I(y, p).map((e) => /* @__PURE__ */ l("div", {
618
+ G(y, p).map((e) => /* @__PURE__ */ l("div", {
510
619
  className: "tool",
511
620
  title: e.title,
512
621
  children: [/* @__PURE__ */ c(t, {
513
- name: L[e.status].icon,
622
+ name: K[e.status].icon,
514
623
  size: 14,
515
- className: L[e.status].cls
624
+ className: K[e.status].cls
516
625
  }), /* @__PURE__ */ c("span", {
517
626
  className: "tx",
518
627
  children: e.text
@@ -556,7 +665,7 @@ function R({ m: e, busy: n, onRetry: i, loadAttachment: a, onOpenAttachment: u }
556
665
  ]
557
666
  });
558
667
  }
559
- function z({ m: e }) {
668
+ function q({ m: e }) {
560
669
  let { t: n, i18n: r } = g(o), [i, a] = h(!1), s = e.event;
561
670
  return /* @__PURE__ */ l("div", {
562
671
  className: "evdiv",
@@ -572,7 +681,7 @@ function z({ m: e }) {
572
681
  }),
573
682
  s.text,
574
683
  " · ",
575
- F(e.createdAt, r.language),
684
+ W(e.createdAt, r.language),
576
685
  s.details && /* @__PURE__ */ l("button", {
577
686
  type: "button",
578
687
  className: "textbtn",
@@ -594,20 +703,20 @@ function z({ m: e }) {
594
703
  }
595
704
  //#endregion
596
705
  //#region src/chat/transcription.ts
597
- async function te(e, t, n) {
706
+ async function re(e, t, n) {
598
707
  n.busy(!0);
599
708
  let r;
600
709
  try {
601
710
  r = await t(e);
602
711
  } catch (r) {
603
- n.busy(!1), n.failed(r instanceof Error && r.message ? r.message : void 0, () => void te(e, t, n));
712
+ n.busy(!1), n.failed(r instanceof Error && r.message ? r.message : void 0, () => void re(e, t, n));
604
713
  return;
605
714
  }
606
715
  n.busy(!1), r !== null && (r ? n.text(r) : n.empty());
607
716
  }
608
717
  //#endregion
609
718
  //#region src/chat/useRecorder.ts
610
- function ne(e = 300, t) {
719
+ function ie(e = 300, t) {
611
720
  let n = typeof window < "u" && "MediaRecorder" in window && !!navigator.mediaDevices?.getUserMedia, [r, i] = h(!1), [a, o] = h(0), [s, c] = h(0), [l, f] = h(!1), p = m(null), g = m([]), _ = m(void 0), v = m(null), y = m(null), b = m(!1), x = m(t);
612
721
  d(() => {
613
722
  x.current = t;
@@ -669,59 +778,59 @@ function ne(e = 300, t) {
669
778
  cancel: T
670
779
  };
671
780
  }
672
- function re(e) {
781
+ function ae(e) {
673
782
  return `${Math.floor(e / 60)}:${String(e % 60).padStart(2, "0")}`;
674
783
  }
675
784
  //#endregion
676
785
  //#region src/chat/Chat.tsx
677
- function B(n) {
678
- let r = a(), i = e(), [o, u] = h(""), [g, y] = h([]), [b, S] = h(!1), [C, w] = h(null), [T, E] = h(0), [D, O] = h(!1), [k, A] = h(null), [j, M] = h(!1), [N, P] = h(null), F = m(n.loadAttachment);
786
+ function J(n) {
787
+ let r = a(), i = e(), [o, u] = h(""), [g, y] = h([]), [b, S] = h(!1), [C, w] = h(null), [T, E] = h(0), [D, O] = h(!1), [k, A] = h(null), [j, ee] = h(!1), [M, N] = h(null), P = m(n.loadAttachment);
679
788
  d(() => {
680
- F.current = n.loadAttachment;
789
+ P.current = n.loadAttachment;
681
790
  });
682
- let I = !!n.loadAttachment, L = p(() => I ? (e) => F.current ? F.current(e) : Promise.reject(/* @__PURE__ */ Error("no loader")) : void 0, [I]), z = m(!1), B = m(null), V = m(null), H = m(null), U = n.voiceMaxSeconds ?? 300, W = ne(U, () => void me()), { messages: G, busy: K = !1 } = n, ae = n.onPendingChange;
683
- d(() => ae?.(g), [g, ae]);
684
- let q = G[0]?.id, J = G[G.length - 1], Y = J?.id, oe = J?.text.length, se = J?.steps?.length, ce = m({ height: 0 });
791
+ let F = !!n.loadAttachment, I = p(() => F ? (e) => P.current ? P.current(e) : Promise.reject(/* @__PURE__ */ Error("no loader")) : void 0, [F]), L = m(!1), R = m(null), z = m(null), B = m(null), V = n.voiceMaxSeconds ?? 300, H = ie(V, () => void ge()), { messages: U, busy: W = !1 } = n, G = n.onPendingChange;
792
+ d(() => G?.(g), [g, G]);
793
+ let K = U[0]?.id, q = U[U.length - 1], J = q?.id, le = q?.text.length, ue = q?.steps?.length, Y = m({ height: 0 });
685
794
  f(() => {
686
- let e = B.current;
795
+ let e = R.current;
687
796
  if (!e) return;
688
- let t = ce.current;
689
- e.scrollTop = t.first !== void 0 && q !== t.first && Y === t.last ? e.scrollTop + (e.scrollHeight - t.height) : e.scrollHeight, ce.current = {
690
- first: q,
691
- last: Y,
797
+ let t = Y.current;
798
+ e.scrollTop = t.first !== void 0 && K !== t.first && J === t.last ? e.scrollTop + (e.scrollHeight - t.height) : e.scrollHeight, Y.current = {
799
+ first: K,
800
+ last: J,
692
801
  height: e.scrollHeight
693
802
  };
694
803
  }, [
695
- G.length,
696
- q,
697
- Y,
698
- oe,
699
- se
804
+ U.length,
805
+ K,
806
+ J,
807
+ le,
808
+ ue
700
809
  ]);
701
- let X = n.commands && !C && o.startsWith("/") && !/\s/.test(o) ? o.slice(1) : null, Z = X === null ? [] : _(n.commands ?? [], X), Q = X !== null && !D, le = () => {
702
- u(""), y([]), w(null), A(null), z.current = !1;
703
- }, ue = async (e, t) => {
810
+ let X = n.commands && !C && o.startsWith("/") && !/\s/.test(o) ? o.slice(1) : null, Z = X === null ? [] : _(n.commands ?? [], X), Q = X !== null && !D, de = () => {
811
+ u(""), y([]), w(null), A(null), L.current = !1;
812
+ }, fe = async (e, t) => {
704
813
  if (n.onCommand) try {
705
- await n.onCommand(e, t), le();
814
+ await n.onCommand(e, t), de();
706
815
  } catch {}
707
816
  }, $ = async (e, t = !1) => {
708
817
  let r = e.trim();
709
- if (!(!r && g.length === 0 && !C || K || n.readOnly)) {
818
+ if (!(!r && g.length === 0 && !C || W || n.readOnly)) {
710
819
  if (!t && !C && n.commands && r.startsWith("/")) {
711
820
  let [e, ...t] = r.slice(1).split(/\s+/), i = n.commands.find((t) => t.kind === "command" && t.name === e);
712
- if (i) return ue(i.name, t.join(" "));
821
+ if (i) return fe(i.name, t.join(" "));
713
822
  if (e && !r.includes("\n")) {
714
823
  A("/" + e);
715
824
  return;
716
825
  }
717
826
  }
718
827
  try {
719
- await n.onSend(r, g.map((e) => e.id), z.current, C ?? void 0), le();
828
+ await n.onSend(r, g.map((e) => e.id), L.current, C ?? void 0), de();
720
829
  } catch {}
721
830
  }
722
- }, de = (e) => {
723
- E(0), e.kind === "skill" ? (w(e.name), u("")) : e.takesText ? u("/" + e.name + " ") : ue(e.name, ""), H.current?.focus();
724
- }, fe = (e) => {
831
+ }, pe = (e) => {
832
+ E(0), e.kind === "skill" ? (w(e.name), u("")) : e.takesText ? u("/" + e.name + " ") : fe(e.name, ""), B.current?.focus();
833
+ }, me = (e) => {
725
834
  if (Q && Z.length > 0) {
726
835
  if (e.key === "ArrowDown" || e.key === "ArrowUp") {
727
836
  e.preventDefault();
@@ -730,12 +839,21 @@ function B(n) {
730
839
  return;
731
840
  }
732
841
  if (e.key === "Enter" && !e.shiftKey || e.key === "Tab") {
733
- e.preventDefault(), de(Z[Math.min(T, Z.length - 1)]);
842
+ e.preventDefault(), pe(Z[Math.min(T, Z.length - 1)]);
734
843
  return;
735
844
  }
736
845
  }
737
- Q && e.key === "Escape" ? (e.preventDefault(), O(!0)) : e.key === "Backspace" && C && o === "" ? w(null) : e.key === "Enter" && !e.shiftKey && !e.nativeEvent.isComposing && (e.preventDefault(), $(o));
738
- }, pe = async (e) => {
846
+ Q && e.key === "Escape" ? (e.preventDefault(), O(!0)) : e.key === "Backspace" && C && o === "" ? w(null) : e.key === "Enter" && !e.shiftKey && !e.nativeEvent.isComposing && !se() && (e.preventDefault(), $(o));
847
+ };
848
+ f(() => ce(B.current, R.current), [o]), d(() => {
849
+ let e = B.current;
850
+ if (!e || typeof ResizeObserver > "u") return;
851
+ let t = e.clientWidth, n = new ResizeObserver(() => {
852
+ e.clientWidth !== t && (t = e.clientWidth, ce(e, R.current));
853
+ });
854
+ return n.observe(e), () => n.disconnect();
855
+ }, [H.recording]);
856
+ let he = async (e) => {
739
857
  if (e?.length && n.onUpload) {
740
858
  S(!0);
741
859
  for (let t of Array.from(e)) {
@@ -750,13 +868,13 @@ function B(n) {
750
868
  let e = await n.onUpload(t).catch(() => null);
751
869
  e && y((t) => [...t, e]);
752
870
  }
753
- S(!1), V.current && (V.current.value = "");
871
+ S(!1), z.current && (z.current.value = "");
754
872
  }
755
873
  };
756
- async function me() {
757
- let e = await W.stop();
758
- e && n.onTranscribe && await te(e, n.onTranscribe, {
759
- busy: M,
874
+ async function ge() {
875
+ let e = await H.stop();
876
+ e && n.onTranscribe && await re(e, n.onTranscribe, {
877
+ busy: ee,
760
878
  empty: () => i({
761
879
  kind: "error",
762
880
  title: r("chat.voice.notRecognized")
@@ -771,13 +889,13 @@ function B(n) {
771
889
  }]
772
890
  }),
773
891
  text: (e) => {
774
- z.current = !0, u((t) => t.trim() ? t.trimEnd() + " " + e : e), H.current?.focus();
892
+ L.current = !0, u((t) => t.trim() ? t.trimEnd() + " " + e : e), B.current?.focus();
775
893
  }
776
894
  });
777
895
  }
778
- let he = (e) => {
779
- e.key === "Escape" && W.recording && (e.preventDefault(), W.cancel());
780
- }, ge = C ? r("chat.skillPlaceholder") : r("chat.placeholder", { name: n.agentName }), _e = U - W.seconds;
896
+ let _e = (e) => {
897
+ e.key === "Escape" && H.recording && (e.preventDefault(), H.cancel());
898
+ }, ve = C ? r("chat.skillPlaceholder") : r("chat.placeholder", { name: n.agentName }), ye = V - H.seconds;
781
899
  return /* @__PURE__ */ l("section", {
782
900
  className: "nb-chat",
783
901
  "aria-label": r("chat.title"),
@@ -785,7 +903,7 @@ function B(n) {
785
903
  n.header,
786
904
  /* @__PURE__ */ l("div", {
787
905
  className: "msgs",
788
- ref: B,
906
+ ref: R,
789
907
  "aria-live": "polite",
790
908
  children: [
791
909
  n.hasOlder && n.onLoadOlder && /* @__PURE__ */ c("button", {
@@ -799,7 +917,7 @@ function B(n) {
799
917
  className: "err-text",
800
918
  children: n.historyError
801
919
  }),
802
- G.length === 0 && !n.loading && !n.historyError && /* @__PURE__ */ l("div", {
920
+ U.length === 0 && !n.loading && !n.historyError && /* @__PURE__ */ l("div", {
803
921
  className: "empty",
804
922
  children: [
805
923
  /* @__PURE__ */ c("div", {
@@ -810,12 +928,12 @@ function B(n) {
810
928
  n.emptyHint
811
929
  ]
812
930
  }),
813
- G.map((e) => /* @__PURE__ */ c(R, {
931
+ U.map((e) => /* @__PURE__ */ c(ne, {
814
932
  m: e,
815
- busy: K,
933
+ busy: W,
816
934
  onRetry: n.onRetry && (() => n.onRetry?.(e.id)),
817
- loadAttachment: L,
818
- onOpenAttachment: P
935
+ loadAttachment: I,
936
+ onOpenAttachment: N
819
937
  }, e.id)),
820
938
  n.onConfirm && (n.confirmations ?? []).map((e) => /* @__PURE__ */ l("div", {
821
939
  className: "confirm",
@@ -860,7 +978,7 @@ function B(n) {
860
978
  Q && /* @__PURE__ */ c(v, {
861
979
  items: Z,
862
980
  active: Math.min(T, Math.max(Z.length - 1, 0)),
863
- onPick: de,
981
+ onPick: pe,
864
982
  onHover: E
865
983
  }),
866
984
  n.aboveComposer,
@@ -903,22 +1021,22 @@ function B(n) {
903
1021
  /* @__PURE__ */ l("div", {
904
1022
  className: "composer",
905
1023
  children: [
906
- n.onUpload && !W.recording && /* @__PURE__ */ l(s, { children: [/* @__PURE__ */ c("button", {
1024
+ n.onUpload && !H.recording && /* @__PURE__ */ l(s, { children: [/* @__PURE__ */ c("button", {
907
1025
  className: "iconbtn",
908
1026
  "aria-label": r("chat.attach"),
909
1027
  disabled: b,
910
- onClick: () => V.current?.click(),
1028
+ onClick: () => z.current?.click(),
911
1029
  children: /* @__PURE__ */ c(t, { name: "clip" })
912
1030
  }), /* @__PURE__ */ c("input", {
913
- ref: V,
1031
+ ref: z,
914
1032
  type: "file",
915
1033
  multiple: !0,
916
1034
  hidden: !0,
917
1035
  accept: n.upload?.accept,
918
- onChange: (e) => pe(e.target.files)
1036
+ onChange: (e) => he(e.target.files)
919
1037
  })] }),
920
- W.recording ? /* @__PURE__ */ l("div", {
921
- className: `recbar${_e <= 15 ? " ending" : ""}`,
1038
+ H.recording ? /* @__PURE__ */ l("div", {
1039
+ className: `recbar${ye <= 15 ? " ending" : ""}`,
922
1040
  role: "status",
923
1041
  "aria-label": r("chat.voice.recordingNow"),
924
1042
  children: [
@@ -929,27 +1047,27 @@ function B(n) {
929
1047
  /* @__PURE__ */ l("span", {
930
1048
  className: "tm",
931
1049
  children: [
932
- re(W.seconds),
1050
+ ae(H.seconds),
933
1051
  " / ",
934
- re(U)
1052
+ ae(V)
935
1053
  ]
936
1054
  }),
937
1055
  /* @__PURE__ */ c("span", {
938
1056
  className: "lvl",
939
1057
  "aria-hidden": "true",
940
- children: /* @__PURE__ */ c("i", { style: { transform: `scaleX(${Math.max(.04, W.level)})` } })
1058
+ children: /* @__PURE__ */ c("i", { style: { transform: `scaleX(${Math.max(.04, H.level)})` } })
941
1059
  }),
942
1060
  /* @__PURE__ */ c("button", {
943
1061
  type: "button",
944
1062
  className: "btn ghost sm",
945
- onClick: W.cancel,
1063
+ onClick: H.cancel,
946
1064
  children: r("cancel")
947
1065
  }),
948
1066
  /* @__PURE__ */ c("button", {
949
1067
  type: "button",
950
1068
  className: "btn primary sm",
951
- onKeyDown: he,
952
- onClick: () => void me(),
1069
+ onKeyDown: _e,
1070
+ onClick: () => void ge(),
953
1071
  children: r("chat.voice.done")
954
1072
  })
955
1073
  ]
@@ -979,31 +1097,31 @@ function B(n) {
979
1097
  })
980
1098
  ]
981
1099
  }), /* @__PURE__ */ c("textarea", {
982
- ref: H,
1100
+ ref: B,
983
1101
  rows: 1,
984
1102
  value: o,
985
- placeholder: j ? r("chat.voice.recognizing") : ge,
986
- "aria-label": ge,
1103
+ placeholder: j ? r("chat.voice.recognizing") : ve,
1104
+ "aria-label": ve,
987
1105
  disabled: j,
988
1106
  "aria-expanded": Q,
989
1107
  "aria-autocomplete": n.commands ? "list" : void 0,
990
1108
  onChange: (e) => {
991
1109
  u(e.target.value), O(!1), E(0), A(null);
992
1110
  },
993
- onKeyDown: fe
1111
+ onKeyDown: me
994
1112
  })]
995
1113
  }),
996
- n.context && !W.recording && /* @__PURE__ */ c(x, {
1114
+ n.context && !H.recording && /* @__PURE__ */ c(x, {
997
1115
  context: n.context,
998
1116
  onCompact: n.onCompact,
999
1117
  onReset: n.onReset
1000
1118
  }),
1001
- n.onTranscribe && !W.recording && /* @__PURE__ */ c(ie, {
1002
- supported: W.supported,
1119
+ n.onTranscribe && !H.recording && /* @__PURE__ */ c(oe, {
1120
+ supported: H.supported,
1003
1121
  recognizing: j,
1004
- onStart: () => void W.start()
1122
+ onStart: () => void H.start()
1005
1123
  }),
1006
- !W.recording && (n.onCancel && K ? /* @__PURE__ */ c("button", {
1124
+ !H.recording && (n.onCancel && W ? /* @__PURE__ */ c("button", {
1007
1125
  className: "iconbtn fill",
1008
1126
  "aria-label": r("chat.stop"),
1009
1127
  onClick: n.onCancel,
@@ -1011,28 +1129,28 @@ function B(n) {
1011
1129
  }) : /* @__PURE__ */ c("button", {
1012
1130
  className: "iconbtn fill",
1013
1131
  "aria-label": r("chat.send"),
1014
- disabled: !o.trim() && g.length === 0 && !C || K || j,
1132
+ disabled: !o.trim() && g.length === 0 && !C || W || j,
1015
1133
  onClick: () => $(o),
1016
1134
  children: /* @__PURE__ */ c(t, { name: "send" })
1017
1135
  }))
1018
1136
  ]
1019
1137
  }),
1020
- W.error && /* @__PURE__ */ c("div", {
1138
+ H.error && /* @__PURE__ */ c("div", {
1021
1139
  className: "err-text",
1022
1140
  style: { padding: "0 12px 8px" },
1023
1141
  children: r("chat.voice.micDenied")
1024
1142
  })
1025
1143
  ]
1026
1144
  }),
1027
- N && L && /* @__PURE__ */ c(ee, {
1028
- a: N,
1029
- load: L,
1030
- onClose: () => P(null)
1145
+ M && I && /* @__PURE__ */ c(te, {
1146
+ a: M,
1147
+ load: I,
1148
+ onClose: () => N(null)
1031
1149
  })
1032
1150
  ]
1033
1151
  });
1034
1152
  }
1035
- function ie({ supported: e, recognizing: n, onStart: r }) {
1153
+ function oe({ supported: e, recognizing: n, onStart: r }) {
1036
1154
  let i = a();
1037
1155
  return n ? /* @__PURE__ */ l("span", {
1038
1156
  className: "voicewait",
@@ -1055,9 +1173,17 @@ function ie({ supported: e, recognizing: n, onStart: r }) {
1055
1173
  children: /* @__PURE__ */ c(t, { name: "mic" })
1056
1174
  });
1057
1175
  }
1176
+ function se() {
1177
+ return typeof window < "u" && !!window.matchMedia?.("(hover: none) and (pointer: coarse)").matches;
1178
+ }
1179
+ function ce(e, t) {
1180
+ if (!e) return;
1181
+ let n = !!t && t.scrollHeight - t.scrollTop - t.clientHeight < 2;
1182
+ e.style.height = "auto", e.style.height = `${e.scrollHeight + e.offsetHeight - e.clientHeight}px`, t && n && (t.scrollTop = t.scrollHeight);
1183
+ }
1058
1184
  //#endregion
1059
1185
  //#region src/chat/ConversationList.tsx
1060
- function V({ conversations: e, currentId: n, open: r, onPick: i, onClose: o, onCreate: u }) {
1186
+ function le({ conversations: e, currentId: n, open: r, onPick: i, onClose: o, onCreate: u }) {
1061
1187
  let f = a(), [p, m] = h(!1);
1062
1188
  d(() => {
1063
1189
  if (!r) return;
@@ -1133,19 +1259,19 @@ function V({ conversations: e, currentId: n, open: r, onPick: i, onClose: o, onC
1133
1259
  "aria-label": f("close"),
1134
1260
  onClick: o
1135
1261
  }),
1136
- p && u && /* @__PURE__ */ c(U, {
1262
+ p && u && /* @__PURE__ */ c(Y, {
1137
1263
  onClose: () => m(!1),
1138
1264
  onCreate: u
1139
1265
  })
1140
1266
  ] });
1141
1267
  }
1142
- function H({ narrow: e, children: t }) {
1268
+ function ue({ narrow: e, children: t }) {
1143
1269
  return /* @__PURE__ */ c("div", {
1144
1270
  className: `nb-app${e ? " narrow" : ""}`,
1145
1271
  children: t
1146
1272
  });
1147
1273
  }
1148
- function U({ onClose: e, onCreate: t }) {
1274
+ function Y({ onClose: e, onCreate: t }) {
1149
1275
  let r = a(), [i, o] = h(""), [u, d] = h(!1), [f, p] = h(null), m = async () => {
1150
1276
  if (i.trim() && !u) {
1151
1277
  d(!0), p(null);
@@ -1197,7 +1323,7 @@ function U({ onClose: e, onCreate: t }) {
1197
1323
  }
1198
1324
  //#endregion
1199
1325
  //#region src/chat/AgentMenu.tsx
1200
- function W({ icon: e, label: n, title: r, expanded: i, small: a, disabled: o, onClick: s }) {
1326
+ function X({ icon: e, label: n, title: r, expanded: i, small: a, disabled: o, onClick: s }) {
1201
1327
  return /* @__PURE__ */ c("button", {
1202
1328
  type: "button",
1203
1329
  className: `agentbtn${a ? " s" : ""}`,
@@ -1213,7 +1339,7 @@ function W({ icon: e, label: n, title: r, expanded: i, small: a, disabled: o, on
1213
1339
  })
1214
1340
  });
1215
1341
  }
1216
- function G({ label: e, name: n, options: r, value: o, optionsLabel: u, hint: d, narrow: f, models: p, onRename: m, onPick: g, onClose: _ }) {
1342
+ function Z({ label: e, name: n, options: r, value: o, optionsLabel: u, hint: d, narrow: f, models: p, onRename: m, onPick: g, onClose: _ }) {
1217
1343
  let v = a(), [y, b] = h(n), x = i(!0, _);
1218
1344
  return /* @__PURE__ */ l("div", {
1219
1345
  className: `agentmenu${f ? " narrow" : ""}`,
@@ -1324,6 +1450,6 @@ function G({ label: e, name: n, options: r, value: o, optionsLabel: u, hint: d,
1324
1450
  });
1325
1451
  }
1326
1452
  //#endregion
1327
- export { W as AgentButton, G as AgentMenu, N as AttachmentList, ee as AttachmentPreview, B as Chat, H as ChatLayout, v as CommandPalette, x as ContextMeter, V as ConversationList, R as MessageView, U as NewTopicModal, ie as VoiceButton, O as fileSize, k as parseTable, T as previewKind, b as tokens, ne as useRecorder };
1453
+ export { X as AgentButton, Z as AgentMenu, B as AttachmentList, te as AttachmentPreview, J as Chat, ue as ChatLayout, v as CommandPalette, x as ContextMeter, le as ConversationList, ne as MessageView, Y as NewTopicModal, oe as VoiceButton, k as fileSize, I as parseTable, D as previewIcon, T as previewKind, b as tokens, ie as useRecorder };
1328
1454
 
1329
1455
  //# sourceMappingURL=chat.js.map