@paramms/chat-widget 1.0.46 → 1.0.48

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/index.js CHANGED
@@ -11,7 +11,7 @@ const Ue = `
11
11
  position:relative;
12
12
  display:flex; flex-direction:column; height:100%; min-height:320px; background:var(--ocw-bg);
13
13
  font-family:var(--ocw-fb); color:var(--ocw-ink); overflow:hidden; }
14
- @media (prefers-color-scheme: dark) { .ocw:not([data-theme="light"]) { ${ge("ocw")} } }
14
+ @media (prefers-color-scheme: dark) { .ocw[data-theme="auto"] { ${ge("ocw")} } }
15
15
  .ocw[data-theme="dark"] { ${ge("ocw")} }
16
16
  /* ── Responsive sizing ──────────────────────────────────────────────────────
17
17
  * Sizing is driven by the WIDGET'S OWN width (ResizeObserver toggles
@@ -67,7 +67,6 @@ const Ue = `
67
67
  .ocw-row { display:flex; align-items:flex-end; gap:8px; max-width:86%; }
68
68
  .ocw-row.mine { align-self:flex-end; flex-direction:row-reverse; }
69
69
  .ocw-row.theirs { align-self:flex-start; }
70
- .ocw-dot { width:26px; height:26px; border-radius:50%; background:var(--ocw-tint); color:var(--ocw-accent); font-size:12px; font-weight:700; display:flex; align-items:center; justify-content:center; flex:none; }
71
70
  .ocw-bubble { padding:10px 14px; border-radius:18px; font-size:13.5px; line-height:1.45; word-wrap:break-word; max-width:80%; }
72
71
  .theirs .ocw-bubble { background:var(--ocw-tint); border-bottom-left-radius:4px; }
73
72
  .mine .ocw-bubble { background:var(--ocw-accent2); color:#fff; border-bottom-right-radius:4px; }
@@ -118,7 +117,7 @@ const Ue = `
118
117
  .ocw button:focus-visible, .ocw textarea:focus-visible, .ocw a:focus-visible, .ocw [tabindex]:focus-visible { outline:2px solid var(--ocw-accent); outline-offset:2px; border-radius:8px; }
119
118
  .ocw-sendbtn:active { transform:scale(.92); }
120
119
  .ocw-quick button:active, .ocw-chip:active { transform:scale(.97); }
121
- @media (prefers-color-scheme: dark) { .ocw:not([data-theme="light"]) .ocw-away { background:#3a3018; border-color:#5a4a1f; color:#e8d9a8; } .ocw:not([data-theme="light"]) .ocw-note .ocw-bubble { background:#332b12; border-color:#7a5c17; color:#f0e2bd; } .ocw:not([data-theme="light"]) .ocw-note .ocw-bubble::before { color:#e0c060; } }
120
+ @media (prefers-color-scheme: dark) { .ocw[data-theme="auto"] .ocw-away { background:#3a3018; border-color:#5a4a1f; color:#e8d9a8; } .ocw[data-theme="auto"] .ocw-note .ocw-bubble { background:#332b12; border-color:#7a5c17; color:#f0e2bd; } .ocw[data-theme="auto"] .ocw-note .ocw-bubble::before { color:#e0c060; } }
122
121
  .ocw[data-theme="dark"] .ocw-away { background:#3a3018; border-color:#5a4a1f; color:#e8d9a8; }
123
122
  .ocw[data-theme="dark"] .ocw-note .ocw-bubble { background:#332b12; border-color:#7a5c17; color:#f0e2bd; }
124
123
  .ocw[data-theme="dark"] .ocw-note .ocw-bubble::before { color:#e0c060; }
@@ -196,7 +195,8 @@ const Ue = `
196
195
  .ocw-translate-btn { position:absolute; bottom:2px; right:-26px; background:var(--ocw-card); border:1px solid var(--ocw-line); border-radius:50%; width:22px; height:22px; font-size:11px; cursor:pointer; color:var(--ocw-mut); display:flex; align-items:center; justify-content:center; opacity:0; transition:opacity .15s; padding:0; }
197
196
  .ocw-row.theirs .ocw-translate-btn { right:auto; left:-26px; }
198
197
  .ocw-bubble-wrap:hover .ocw-translate-btn { opacity:1; }
199
- .ocw-translated-tag { font-size:10px; color:var(--ocw-mut); margin-top:2px; }
198
+ .ocw-translation { margin-top:6px; padding-top:6px; border-top:1px solid var(--ocw-line); font-size:13px; line-height:1.45; }
199
+ .ocw-translation::before { content:'🌐 '; opacity:.75; }
200
200
  `, ye = "objectchat-widget-styles", Fe = ["👍", "❤️", "😂", "😮", "😢", "🙏"], We = 400, Ge = '<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><path d="M22 2 11 13M22 2l-7 20-4-9-9-4 20-7z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>';
201
201
  function Ke() {
202
202
  if (typeof document > "u" || document.getElementById(ye)) return;
@@ -239,7 +239,7 @@ function ae(t) {
239
239
  }
240
240
  class Xe {
241
241
  /** Last seq the guest has seen per conversationId — used to compute unread badges. */
242
- constructor(e, l, c, i = {}) {
242
+ constructor(e, l, c, a = {}) {
243
243
  T(this, "scroll");
244
244
  T(this, "chips");
245
245
  T(this, "typing");
@@ -274,64 +274,59 @@ class Xe {
274
274
  /** Whether the subject card (server Subject entity, mount config fallback)
275
275
  * has been built — built once when data first arrives. */
276
276
  T(this, "subjectBuilt", !1);
277
- var r, C, v, u, f, R, B, A, k, S, D;
278
- this.root = e, this.me = l, this.h = c, this.cfg = i, Ke(), i.webfont !== !1 && Ve(), e.replaceChildren(), e.classList.add("ocw"), i.accent && e.style.setProperty("--ocw-accent", i.accent);
279
- const x = i.accent2 ?? i.accent;
280
- x && e.style.setProperty("--ocw-accent2", x), this.cfgAccent2 = i.accent2, i.theme && i.theme !== "auto" && (e.dataset.theme = i.theme);
277
+ var g, y, f, u, L, P, R, C, S, D, _;
278
+ this.root = e, this.me = l, this.h = c, this.cfg = a, Ke(), a.webfont !== !1 && Ve(), e.replaceChildren(), e.classList.add("ocw"), a.accent && e.style.setProperty("--ocw-accent", a.accent);
279
+ const x = a.accent2 ?? a.accent;
280
+ x && e.style.setProperty("--ocw-accent2", x), this.cfgAccent2 = a.accent2, e.dataset.theme = a.theme ?? "light";
281
281
  const w = n("div", "ocw-head");
282
282
  if (this.h.onBack) {
283
- const g = n("button", "ocw-back", "‹");
284
- g.type = "button", g.setAttribute("aria-label", "Back"), g.addEventListener("click", () => this.h.onBack()), w.append(g);
283
+ const v = n("button", "ocw-back", "‹");
284
+ v.type = "button", v.setAttribute("aria-label", "Back"), v.addEventListener("click", () => this.h.onBack()), w.append(v);
285
285
  }
286
- const y = n("div", "ocw-avatar");
287
- if ((r = i.userInfo) != null && r.avatar) {
288
- const g = document.createElement("img");
289
- g.src = i.userInfo.avatar, g.alt = i.userInfo.name ?? "You", g.style.cssText = "width:100%;height:100%;border-radius:50%;object-fit:cover", y.append(g);
290
- } else
291
- y.textContent = (C = i.userInfo) != null && C.name ? i.userInfo.name[0].toUpperCase() : "🧑";
292
- w.append(y);
286
+ const m = ((g = a.subject) == null ? void 0 : g.ownerLabel) ?? ((y = a.subject) == null ? void 0 : y.title) ?? "", h = n("div", "ocw-avatar");
287
+ m.trim() && (h.textContent = m.trim()[0].toUpperCase(), w.append(h));
293
288
  const p = n("div", "ocw-head-main");
294
- this.headerName = n("div", "ocw-head-name", ((v = i.subject) == null ? void 0 : v.ownerLabel) ?? ((u = i.subject) == null ? void 0 : u.title) ?? ""), p.append(this.headerName), this.headStatus = n("div", "ocw-head-status"), this.headStatus.style.display = "none", p.append(this.headStatus), (f = i.subject) != null && f.subtitle && p.append(n("div", "ocw-head-meta", i.subject.subtitle)), w.append(p), this.statusBadge = n("span", "ocw-badge", ((R = i.subject) == null ? void 0 : R.status) ?? ""), (B = i.subject) != null && B.status || (this.statusBadge.style.display = "none"), w.append(this.statusBadge), this.e2eBadge = n("span", "ocw-e2e", "🔒 E2E"), this.e2eBadge.style.display = "none", w.append(this.e2eBadge), this.connStatus = n("span", "ocw-conn-status"), this.connStatus.style.display = "none", w.append(this.connStatus), w.append(n("button", "ocw-menu", "⋯")), this.chips = n("div", "ocw-chiprow"), this.scroll = n("div", "ocw-scroll"), this.subjectCard = n("div", "ocw-subject"), this.typing = n("div", "ocw-typing");
295
- const h = n("div", "ocw-typing-bubble");
296
- h.append(n("div", "ocw-typing-dot"), n("div", "ocw-typing-dot"), n("div", "ocw-typing-dot")), this.typing.append(n("div", "ocw-dot", "🧑"), h), this.quick = n("div", "ocw-quick");
297
- for (const g of i.quickReplies ?? []) {
298
- const N = n("button", void 0, g);
289
+ this.headerName = n("div", "ocw-head-name", ((f = a.subject) == null ? void 0 : f.ownerLabel) ?? ((u = a.subject) == null ? void 0 : u.title) ?? ""), p.append(this.headerName), this.headStatus = n("div", "ocw-head-status"), this.headStatus.style.display = "none", p.append(this.headStatus), (L = a.subject) != null && L.subtitle && p.append(n("div", "ocw-head-meta", a.subject.subtitle)), w.append(p), this.statusBadge = n("span", "ocw-badge", ((P = a.subject) == null ? void 0 : P.status) ?? ""), (R = a.subject) != null && R.status || (this.statusBadge.style.display = "none"), w.append(this.statusBadge), this.e2eBadge = n("span", "ocw-e2e", "🔒 E2E"), this.e2eBadge.style.display = "none", w.append(this.e2eBadge), this.connStatus = n("span", "ocw-conn-status"), this.connStatus.style.display = "none", w.append(this.connStatus), w.append(n("button", "ocw-menu", "⋯")), this.chips = n("div", "ocw-chiprow"), this.scroll = n("div", "ocw-scroll"), this.subjectCard = n("div", "ocw-subject"), this.typing = n("div", "ocw-typing");
290
+ const k = n("div", "ocw-typing-bubble");
291
+ k.append(n("div", "ocw-typing-dot"), n("div", "ocw-typing-dot"), n("div", "ocw-typing-dot")), this.typing.append(k), this.quick = n("div", "ocw-quick");
292
+ for (const v of a.quickReplies ?? []) {
293
+ const N = n("button", void 0, v);
299
294
  N.addEventListener("click", () => {
300
- this.h.onSend(g), this.quick.style.display = "none";
295
+ this.h.onSend(v), this.quick.style.display = "none";
301
296
  }), this.quick.append(N);
302
297
  }
303
- this.formHost = n("div", "ocw-form-host"), this.csatPanel = n("div", "ocw-csat"), this.csatPanel.style.display = "none", this.awayNotice = n("div", "ocw-away"), this.awayNotice.style.display = "none", this.preChatPanel = n("div", "ocw-prechat"), this.preChatPanel.style.display = "none", this.deflectPanel = n("div", "ocw-deflect"), this.deflectPanel.style.display = "none", this.input = n("textarea", void 0), this.input.rows = 1, this.input.placeholder = ((A = i.i18n) == null ? void 0 : A.placeholder) ?? "Message…";
304
- const b = n("button", "ocw-sendbtn");
305
- b.type = "button";
306
- const a = (k = i.i18n) == null ? void 0 : k.send;
307
- a ? (b.textContent = a, b.classList.add("ocw-sendbtn-label"), b.setAttribute("aria-label", a)) : (b.innerHTML = Ge, b.setAttribute("aria-label", "Send message")), b.disabled = !0, this.sendBtn = b, b.addEventListener("click", () => this.flushSend()), this.input.addEventListener("input", () => {
308
- var g, N;
309
- this.sendBtn.disabled = this.input.value.trim().length === 0, this.autoGrowInput(), this.storeRef && !this.storeRef.messages().some((H) => H.senderRole === "guest") ? (N = (g = this.h).onDeflectQuery) == null || N.call(g, this.input.value) : this.hideDeflection();
310
- }), this.input.addEventListener("keydown", (g) => {
311
- g.isComposing || g.keyCode === 229 || (g.key === "Enter" && !g.shiftKey ? (g.preventDefault(), this.flushSend()) : this.signalTyping());
298
+ this.formHost = n("div", "ocw-form-host"), this.csatPanel = n("div", "ocw-csat"), this.csatPanel.style.display = "none", this.awayNotice = n("div", "ocw-away"), this.awayNotice.style.display = "none", this.preChatPanel = n("div", "ocw-prechat"), this.preChatPanel.style.display = "none", this.deflectPanel = n("div", "ocw-deflect"), this.deflectPanel.style.display = "none", this.input = n("textarea", void 0), this.input.rows = 1, this.input.placeholder = ((C = a.i18n) == null ? void 0 : C.placeholder) ?? "Message…";
299
+ const i = n("button", "ocw-sendbtn");
300
+ i.type = "button";
301
+ const $ = (S = a.i18n) == null ? void 0 : S.send;
302
+ $ ? (i.textContent = $, i.classList.add("ocw-sendbtn-label"), i.setAttribute("aria-label", $)) : (i.innerHTML = Ge, i.setAttribute("aria-label", "Send message")), i.disabled = !0, this.sendBtn = i, i.addEventListener("click", () => this.flushSend()), this.input.addEventListener("input", () => {
303
+ var v, N;
304
+ this.sendBtn.disabled = this.input.value.trim().length === 0, this.autoGrowInput(), this.storeRef && !this.storeRef.messages().some((H) => H.senderRole === "guest") ? (N = (v = this.h).onDeflectQuery) == null || N.call(v, this.input.value) : this.hideDeflection();
305
+ }), this.input.addEventListener("keydown", (v) => {
306
+ v.isComposing || v.keyCode === 229 || (v.key === "Enter" && !v.shiftKey ? (v.preventDefault(), this.flushSend()) : this.signalTyping());
312
307
  });
313
- const P = n("button", "ocw-attach", "📎");
314
- P.title = "Attach image or file";
308
+ const z = n("button", "ocw-attach", "📎");
309
+ z.title = "Attach image or file";
315
310
  const I = document.createElement("input");
316
- I.type = "file", I.accept = "image/*,.pdf,.txt,.doc,.docx", I.style.display = "none", P.addEventListener("click", () => I.click()), I.addEventListener("change", () => {
317
- var g;
318
- (g = I.files) != null && g[0] && this.h.onAttach && this.h.onAttach(I.files[0]), I.value = "";
311
+ I.type = "file", I.accept = "image/*,.pdf,.txt,.doc,.docx", I.style.display = "none", z.addEventListener("click", () => I.click()), I.addEventListener("change", () => {
312
+ var v;
313
+ (v = I.files) != null && v[0] && this.h.onAttach && this.h.onAttach(I.files[0]), I.value = "";
319
314
  });
320
315
  const M = n("div", "ocw-input");
321
- M.append(P, I, this.input, b);
322
- const j = n("div", "ocw-footer");
323
- ((S = i.i18n) == null ? void 0 : S.poweredBy) !== void 0 ? j.textContent = i.i18n.poweredBy : j.innerHTML = 'Powered by <a href="https://relay.paramms.com" target="_blank" rel="noopener">Relay</a>', this.footer = j, this.reopenBtn = n("button", "ocw-reopen", ((D = this.cfg.i18n) == null ? void 0 : D.reopen) ?? "Reopen conversation"), this.reopenBtn.type = "button", this.reopenBtn.addEventListener("click", () => {
316
+ M.append(z, I, this.input, i);
317
+ const d = n("div", "ocw-footer");
318
+ ((D = a.i18n) == null ? void 0 : D.poweredBy) !== void 0 ? d.textContent = a.i18n.poweredBy : d.innerHTML = 'Powered by <a href="https://relay.paramms.com" target="_blank" rel="noopener">Relay</a>', this.footer = d, this.reopenBtn = n("button", "ocw-reopen", ((_ = this.cfg.i18n) == null ? void 0 : _.reopen) ?? "Reopen conversation"), this.reopenBtn.type = "button", this.reopenBtn.addEventListener("click", () => {
324
319
  this.reopenBtn.style.display = "none";
325
- const g = this.root.querySelector(".ocw-input textarea");
326
- g == null || g.focus();
320
+ const v = this.root.querySelector(".ocw-input textarea");
321
+ v == null || v.focus();
327
322
  }), e.append(w, this.chips, this.scroll, this.typing, this.quick, this.formHost, this.csatPanel, this.preChatPanel, this.deflectPanel, this.awayNotice, M, this.reopenBtn, this.footer);
328
- const d = (g) => {
329
- e.classList.toggle("ocw-compact", g > 0 && g < We);
323
+ const r = (v) => {
324
+ e.classList.toggle("ocw-compact", v > 0 && v < We);
330
325
  };
331
- d(e.clientWidth), typeof ResizeObserver < "u" && (this.compactObserver = new ResizeObserver((g) => {
326
+ r(e.clientWidth), typeof ResizeObserver < "u" && (this.compactObserver = new ResizeObserver((v) => {
332
327
  var H;
333
- const N = ((H = g[0]) == null ? void 0 : H.contentRect.width) ?? e.clientWidth;
334
- d(N);
328
+ const N = ((H = v[0]) == null ? void 0 : H.contentRect.width) ?? e.clientWidth;
329
+ r(N);
335
330
  }), this.compactObserver.observe(e));
336
331
  }
337
332
  /** Returns the scroll container so history.ts can attach scroll listeners. */
@@ -366,48 +361,48 @@ class Xe {
366
361
  this.h.onTyping(!0, e), this.typingTimer && clearTimeout(this.typingTimer), this.typingTimer = setTimeout(() => this.h.onTyping(!1), 2e3);
367
362
  }
368
363
  render(e) {
369
- var I, M, j, d, r, C, v, u;
364
+ var z, I, M, d, r, g, y, f;
370
365
  if (this.storeRef = e, e.accent && (this.root.style.setProperty("--ocw-accent", e.accent), this.root.style.setProperty("--ocw-accent2", this.cfgAccent2 ?? e.accent)), this.e2eBadge.style.display = e.e2e ? "inline-flex" : "none", this.buildSubjectCard(e), e.subject) {
371
- const f = (I = this.cfg.subject) == null ? void 0 : I.ownerLabel;
372
- f && (this.headerName.textContent = f);
366
+ const u = (z = this.cfg.subject) == null ? void 0 : z.ownerLabel;
367
+ u && (this.headerName.textContent = u);
373
368
  }
374
369
  this.quick.style.display = e.messages().length === 0 ? "flex" : "none", this.chips.replaceChildren();
375
370
  const l = e.visibleActions();
376
371
  this.chips.style.display = l.length ? "flex" : "none";
377
- for (const f of l) this.chips.append(this.chipEl(f));
378
- const c = this.scroll.scrollHeight, i = this.scroll.scrollTop;
372
+ for (const u of l) this.chips.append(this.chipEl(u));
373
+ const c = this.scroll.scrollHeight, a = this.scroll.scrollTop;
379
374
  if (this.scroll.replaceChildren(), this.subjectCard.childNodes.length && this.scroll.append(this.subjectCard), e.hasMoreHistory) {
380
- const f = n("div", "ocw-load-more");
381
- f.textContent = "↑ Loading earlier messages…", f.style.pointerEvents = "none", this.scroll.append(f);
375
+ const u = n("div", "ocw-load-more");
376
+ u.textContent = "↑ Loading earlier messages…", u.style.pointerEvents = "none", this.scroll.append(u);
382
377
  }
383
378
  let x = 0, w = null;
384
- for (const f of e.messages()) {
385
- const R = f.senderRole !== "system" && f.senderId !== this.me && !f.internal && f.senderId !== w;
386
- this.scroll.append(this.messageEl(f, e, R)), f.senderRole !== "system" && (w = f.senderId), f.senderId !== this.me && f.seq > x && (x = f.seq);
379
+ for (const u of e.messages()) {
380
+ const L = u.senderRole !== "system" && u.senderId !== this.me && !u.internal && u.senderId !== w;
381
+ this.scroll.append(this.messageEl(u, e, L)), u.senderRole !== "system" && (w = u.senderId), u.senderId !== this.me && u.seq > x && (x = u.seq);
387
382
  }
388
- i > 20 ? this.scroll.scrollTop = this.scroll.scrollHeight - c + i : this.scroll.scrollTop = this.scroll.scrollHeight, x > 0 && this.h.onReadUpTo(x);
389
- const y = [...e.typing];
390
- this.typing.classList.toggle("active", y.length > 0);
391
- const p = this.typing.querySelector(".ocw-typing-bubble");
392
- p && p.setAttribute("aria-label", y.length ? "typing" : ""), this.footer.style.display = e.whiteLabel ? "none" : "block";
393
- const h = e.messages().some((f) => f.senderRole === "guest");
394
- if (!!((M = e.preChat) != null && M.enabled) && !this.preChatDone && !h && (e.preChat.showWhen !== "offline" || e.offline))
395
- this.preChatBuilt || this.buildPreChatPanel(e.preChat), this.preChatPanel.style.display = "block", this.awayNotice.style.display = "none", (j = this.root.querySelector(".ocw-input")) == null || j.style.setProperty("display", "none");
383
+ a > 20 ? this.scroll.scrollTop = this.scroll.scrollHeight - c + a : this.scroll.scrollTop = this.scroll.scrollHeight, x > 0 && this.h.onReadUpTo(x);
384
+ const m = [...e.typing];
385
+ this.typing.classList.toggle("active", m.length > 0);
386
+ const h = this.typing.querySelector(".ocw-typing-bubble");
387
+ h && h.setAttribute("aria-label", m.length ? "typing" : ""), this.footer.style.display = e.whiteLabel ? "none" : "block";
388
+ const p = e.messages().some((u) => u.senderRole === "guest");
389
+ if (!!((I = e.preChat) != null && I.enabled) && !this.preChatDone && !p && (e.preChat.showWhen !== "offline" || e.offline))
390
+ this.preChatBuilt || this.buildPreChatPanel(e.preChat), this.preChatPanel.style.display = "block", this.awayNotice.style.display = "none", (M = this.root.querySelector(".ocw-input")) == null || M.style.setProperty("display", "none");
396
391
  else {
397
392
  if (this.preChatPanel.style.display = "none", e.offline) {
398
393
  this.awayNotice.firstChild || this.awayNotice.append(n("span", "ocw-away-icon", "🌙"), n("span", "", ""));
399
- const f = this.awayNotice.lastChild;
400
- f.textContent = e.offlineMessage || ((d = this.cfg.i18n) == null ? void 0 : d.offline) || "We're away right now — send your message and we'll reply as soon as we're back.", this.awayNotice.style.display = "flex";
394
+ const u = this.awayNotice.lastChild;
395
+ u.textContent = e.offlineMessage || ((d = this.cfg.i18n) == null ? void 0 : d.offline) || "We're away right now — send your message and we'll reply as soon as we're back.", this.awayNotice.style.display = "flex";
401
396
  } else
402
397
  this.awayNotice.style.display = "none";
403
398
  (r = this.root.querySelector(".ocw-input")) == null || r.style.removeProperty("display");
404
399
  }
405
- const a = ["resolved", "closed", "sold", "issued", "checked_out"];
406
- this.h.onCsat && !this.csatSubmitted && a.includes(e.state) && e.messages().length > 0 && (this.csatPanel.style.display === "none" && this.buildCsatPanel(), this.csatPanel.style.display = "block");
407
- const P = a.includes(e.state);
408
- if (e.offline ? (this.headStatus.textContent = `● ${e.offlineMessage || ((C = this.cfg.i18n) == null ? void 0 : C.away) || "Away"}`, this.headStatus.className = "ocw-head-status away", this.headStatus.style.display = "") : e.conversationId ? (this.headStatus.textContent = `● ${((v = this.cfg.i18n) == null ? void 0 : v.online) ?? "Online"}`, this.headStatus.className = "ocw-head-status online", this.headStatus.style.display = "") : this.headStatus.style.display = "none", P && e.messages().length > 0) {
409
- const f = n("div", "ocw-resolved-note", `— ${((u = this.cfg.i18n) == null ? void 0 : u.resolved) ?? "Marked as resolved"} —`);
410
- this.scroll.append(f), this.reopenBtn.style.display = "block";
400
+ const i = ["resolved", "closed", "sold", "issued", "checked_out"];
401
+ this.h.onCsat && !this.csatSubmitted && i.includes(e.state) && e.messages().length > 0 && (this.csatPanel.style.display === "none" && this.buildCsatPanel(), this.csatPanel.style.display = "block");
402
+ const $ = i.includes(e.state);
403
+ if (e.offline ? (this.headStatus.textContent = `● ${e.offlineMessage || ((g = this.cfg.i18n) == null ? void 0 : g.away) || "Away"}`, this.headStatus.className = "ocw-head-status away", this.headStatus.style.display = "") : e.conversationId ? (this.headStatus.textContent = `● ${((y = this.cfg.i18n) == null ? void 0 : y.online) ?? "Online"}`, this.headStatus.className = "ocw-head-status online", this.headStatus.style.display = "") : this.headStatus.style.display = "none", $ && e.messages().length > 0) {
404
+ const u = n("div", "ocw-resolved-note", `— ${((f = this.cfg.i18n) == null ? void 0 : f.resolved) ?? "Marked as resolved"} —`);
405
+ this.scroll.append(u), this.reopenBtn.style.display = "block";
411
406
  } else
412
407
  this.reopenBtn.style.display = "none";
413
408
  }
@@ -421,54 +416,54 @@ class Xe {
421
416
  this.connStatus.className = `ocw-conn-status${c ? " err" : e === "reconnecting" ? " warn" : ""}`, this.connStatus.textContent = c ? `⚠ ${l ?? "Chat unavailable"}` : e === "reconnecting" ? l ?? "↻ reconnecting…" : "● connecting…";
422
417
  }
423
418
  buildPreChatPanel(e) {
424
- var p;
419
+ var h;
425
420
  this.preChatBuilt = !0, this.preChatPanel.replaceChildren(), this.preChatPanel.append(n("div", "ocw-prechat-title", e.title ?? "Before we start…"));
426
421
  const l = n("div", "ocw-offline-form"), c = {};
427
- for (const h of e.fields ?? ["name", "email"]) {
428
- const b = n("input", "ocw-offline-input");
429
- b.type = h === "email" ? "email" : h === "phone" ? "tel" : "text", b.placeholder = h === "name" ? "Your name" : h === "email" ? "Your email" : "Your phone number", c[h] = b, l.append(b);
422
+ for (const p of e.fields ?? ["name", "email"]) {
423
+ const k = n("input", "ocw-offline-input");
424
+ k.type = p === "email" ? "email" : p === "phone" ? "tel" : "text", k.placeholder = p === "name" ? "Your name" : p === "email" ? "Your email" : "Your phone number", c[p] = k, l.append(k);
430
425
  }
431
- let i = null;
432
- if ((p = e.topics) != null && p.length) {
433
- i = n("select", void 0);
434
- const h = document.createElement("option");
435
- h.value = "", h.textContent = "What is this about?", i.append(h);
436
- for (const b of e.topics) {
437
- const a = document.createElement("option");
438
- a.value = b, a.textContent = b, i.append(a);
426
+ let a = null;
427
+ if ((h = e.topics) != null && h.length) {
428
+ a = n("select", void 0);
429
+ const p = document.createElement("option");
430
+ p.value = "", p.textContent = "What is this about?", a.append(p);
431
+ for (const k of e.topics) {
432
+ const i = document.createElement("option");
433
+ i.value = k, i.textContent = k, a.append(i);
439
434
  }
440
- l.append(i);
435
+ l.append(a);
441
436
  }
442
437
  let x = null, w = null;
443
438
  if (e.callbackOption) {
444
- const h = n("label", "ocw-prechat-cb");
445
- x = document.createElement("input"), x.type = "checkbox", h.append(x, document.createTextNode("📞 Request a call back")), l.append(h), c.phone || (w = n("input", "ocw-offline-input"), w.type = "tel", w.placeholder = "Phone number for the call", w.style.display = "none", x.addEventListener("change", () => w.style.setProperty("display", x.checked ? "block" : "none")), l.append(w));
439
+ const p = n("label", "ocw-prechat-cb");
440
+ x = document.createElement("input"), x.type = "checkbox", p.append(x, document.createTextNode("📞 Request a call back")), l.append(p), c.phone || (w = n("input", "ocw-offline-input"), w.type = "tel", w.placeholder = "Phone number for the call", w.style.display = "none", x.addEventListener("change", () => w.style.setProperty("display", x.checked ? "block" : "none")), l.append(w));
446
441
  }
447
- const y = n("button", "ocw-offline-submit", "Start chat");
448
- y.type = "button", y.addEventListener("click", () => {
449
- var P, I, M, j, d, r, C;
450
- const h = (P = c.email) == null ? void 0 : P.value.trim();
451
- if (c.email && (!h || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(h))) {
442
+ const m = n("button", "ocw-offline-submit", "Start chat");
443
+ m.type = "button", m.addEventListener("click", () => {
444
+ var $, z, I, M, d, r, g;
445
+ const p = ($ = c.email) == null ? void 0 : $.value.trim();
446
+ if (c.email && (!p || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(p))) {
452
447
  c.email.focus();
453
448
  return;
454
449
  }
455
- const b = !!(x != null && x.checked), a = (((I = c.phone) == null ? void 0 : I.value) ?? (w == null ? void 0 : w.value) ?? "").trim();
456
- if (b && !a) {
457
- (M = c.phone ?? w) == null || M.focus();
450
+ const k = !!(x != null && x.checked), i = (((z = c.phone) == null ? void 0 : z.value) ?? (w == null ? void 0 : w.value) ?? "").trim();
451
+ if (k && !i) {
452
+ (I = c.phone ?? w) == null || I.focus();
458
453
  return;
459
454
  }
460
- if (i && ((j = e.topics) != null && j.length) && !i.value) {
461
- i.focus();
455
+ if (a && ((M = e.topics) != null && M.length) && !a.value) {
456
+ a.focus();
462
457
  return;
463
458
  }
464
- y.disabled = !0, this.completePreChat(), (C = (r = this.h).onPreChat) == null || C.call(r, {
459
+ m.disabled = !0, this.completePreChat(), (g = (r = this.h).onPreChat) == null || g.call(r, {
465
460
  ...(d = c.name) != null && d.value.trim() ? { name: c.name.value.trim() } : {},
466
- ...h ? { email: h } : {},
467
- ...a ? { phone: a } : {},
468
- ...i != null && i.value ? { topic: i.value } : {},
469
- ...b ? { callback: !0 } : {}
461
+ ...p ? { email: p } : {},
462
+ ...i ? { phone: i } : {},
463
+ ...a != null && a.value ? { topic: a.value } : {},
464
+ ...k ? { callback: !0 } : {}
470
465
  });
471
- }), l.append(y), this.preChatPanel.append(l);
466
+ }), l.append(m), this.preChatPanel.append(l);
472
467
  }
473
468
  /** Mark pre-chat complete (submitted now or in a previous session). */
474
469
  completePreChat() {
@@ -491,22 +486,22 @@ class Xe {
491
486
  this.csatPanel.replaceChildren(), this.csatPanel.append(n("div", "ocw-csat-title", "How did we do?"));
492
487
  const e = n("div", "ocw-csat-stars"), l = [];
493
488
  for (let c = 1; c <= 5; c++) {
494
- const i = n("button", "ocw-csat-star", "★");
495
- i.dataset.score = String(c), i.addEventListener("mouseenter", () => l.forEach((x, w) => x.classList.toggle("lit", w < c))), i.addEventListener("mouseleave", () => l.forEach((x) => x.classList.remove("lit"))), i.addEventListener("click", () => {
489
+ const a = n("button", "ocw-csat-star", "★");
490
+ a.dataset.score = String(c), a.addEventListener("mouseenter", () => l.forEach((x, w) => x.classList.toggle("lit", w < c))), a.addEventListener("mouseleave", () => l.forEach((x) => x.classList.remove("lit"))), a.addEventListener("click", () => {
496
491
  var x, w;
497
492
  this.csatSubmitted = !0, this.csatPanel.replaceChildren(n("div", "ocw-csat-done", `Thanks for your ${c}★ rating!`)), (w = (x = this.h).onCsat) == null || w.call(x, c);
498
- }), l.push(i), e.append(i);
493
+ }), l.push(a), e.append(a);
499
494
  }
500
495
  this.csatPanel.append(e);
501
496
  }
502
497
  buildSubjectCard(e) {
503
498
  if (this.subjectBuilt) return;
504
- const l = e.subject, c = this.cfg.subject, i = (l == null ? void 0 : l.title) ?? (c == null ? void 0 : c.title);
505
- if (!i) return;
506
- this.subjectBuilt = !0, this.subjectCard.replaceChildren(), this.subjectCard.append(n("div", "ocw-subject-title", i)), c != null && c.subtitle && this.subjectCard.append(n("div", "ocw-subject-sub", c.subtitle));
499
+ const l = e.subject, c = this.cfg.subject, a = (l == null ? void 0 : l.title) ?? (c == null ? void 0 : c.title);
500
+ if (!a) return;
501
+ this.subjectBuilt = !0, this.subjectCard.replaceChildren(), this.subjectCard.append(n("div", "ocw-subject-title", a)), c != null && c.subtitle && this.subjectCard.append(n("div", "ocw-subject-sub", c.subtitle));
507
502
  const x = n("div", "ocw-tags");
508
- if (l) for (const [y, p] of Object.entries(l.fields)) x.append(n("span", "ocw-tag", `${y}: ${p}`));
509
- else for (const y of (c == null ? void 0 : c.tags) ?? []) x.append(n("span", "ocw-tag", y));
503
+ if (l) for (const [m, h] of Object.entries(l.fields)) x.append(n("span", "ocw-tag", `${m}: ${h}`));
504
+ else for (const m of (c == null ? void 0 : c.tags) ?? []) x.append(n("span", "ocw-tag", m));
510
505
  x.childNodes.length && this.subjectCard.append(x);
511
506
  const w = (l == null ? void 0 : l.state) ?? (c == null ? void 0 : c.status);
512
507
  w && (this.statusBadge.textContent = w, this.statusBadge.style.display = "inline-flex");
@@ -521,185 +516,193 @@ class Xe {
521
516
  /** In-widget confirmation modal (replaces window.confirm). */
522
517
  confirm(e) {
523
518
  return new Promise((l) => {
524
- const c = n("div", "ocw-modal"), i = n("div", "ocw-modal-card");
525
- i.append(n("div", "ocw-modal-title", e)), i.append(n("div", "ocw-modal-body", `Confirm “${e}”?`));
526
- const x = n("div", "ocw-modal-actions"), w = n("button", "ocw-modal-cancel", "Cancel"), y = n("button", "ocw-modal-ok", "Confirm"), p = (h) => {
527
- c.remove(), l(h);
519
+ const c = n("div", "ocw-modal"), a = n("div", "ocw-modal-card");
520
+ a.append(n("div", "ocw-modal-title", e)), a.append(n("div", "ocw-modal-body", `Confirm “${e}”?`));
521
+ const x = n("div", "ocw-modal-actions"), w = n("button", "ocw-modal-cancel", "Cancel"), m = n("button", "ocw-modal-ok", "Confirm"), h = (p) => {
522
+ c.remove(), l(p);
528
523
  };
529
- w.addEventListener("click", () => p(!1)), y.addEventListener("click", () => p(!0)), c.addEventListener("click", (h) => {
530
- h.target === c && p(!1);
531
- }), x.append(w, y), i.append(x), c.append(i), this.root.append(c), y.focus();
524
+ w.addEventListener("click", () => h(!1)), m.addEventListener("click", () => h(!0)), c.addEventListener("click", (p) => {
525
+ p.target === c && h(!1);
526
+ }), x.append(w, m), a.append(x), c.append(a), this.root.append(c), m.focus();
532
527
  });
533
528
  }
534
529
  /** Inline form for a form-effect action: typed inputs (date picker, number,
535
530
  * text) rendered above the composer — no browser prompts. */
536
531
  openForm(e) {
537
- var y, p;
532
+ var m, h;
538
533
  this.formHost.replaceChildren();
539
534
  const l = n("div", "ocw-form");
540
535
  l.append(n("div", "ocw-form-title", e.icon ? `${e.icon} ${e.label}` : e.label));
541
536
  const c = /* @__PURE__ */ new Map();
542
- for (const h of e.input ?? []) {
543
- const b = n("label", "ocw-form-row");
544
- if (b.append(n("span", "ocw-form-lbl", h.label)), h.type === "select" && ((y = h.options) != null && y.length)) {
545
- const a = n("select", "ocw-form-input");
546
- h.required || a.append(n("option", void 0, "— select —"));
547
- for (const P of h.options) {
548
- const I = n("option");
549
- I.value = P, I.textContent = P, a.append(I);
537
+ for (const p of e.input ?? []) {
538
+ const k = n("label", "ocw-form-row");
539
+ if (k.append(n("span", "ocw-form-lbl", p.label)), p.type === "select" && ((m = p.options) != null && m.length)) {
540
+ const i = n("select", "ocw-form-input");
541
+ p.required || i.append(n("option", void 0, "— select —"));
542
+ for (const $ of p.options) {
543
+ const z = n("option");
544
+ z.value = $, z.textContent = $, i.append(z);
550
545
  }
551
- h.required && (a.required = !0), b.append(a), c.set(h.name, a);
546
+ p.required && (i.required = !0), k.append(i), c.set(p.name, i);
552
547
  } else {
553
- const a = n("input", "ocw-form-input");
554
- a.type = h.type === "number" ? "number" : h.type === "date" ? "datetime-local" : "text", h.required && (a.required = !0), b.append(a), c.set(h.name, a);
548
+ const i = n("input", "ocw-form-input");
549
+ i.type = p.type === "number" ? "number" : p.type === "date" ? "datetime-local" : "text", p.required && (i.required = !0), k.append(i), c.set(p.name, i);
555
550
  }
556
- l.append(b);
551
+ l.append(k);
557
552
  }
558
- const i = n("div", "ocw-form-actions"), x = n("button", "ocw-form-cancel", "Cancel"), w = n("button", "ocw-form-submit", "Send");
553
+ const a = n("div", "ocw-form-actions"), x = n("button", "ocw-form-cancel", "Cancel"), w = n("button", "ocw-form-submit", "Send");
559
554
  x.addEventListener("click", () => this.formHost.replaceChildren()), w.addEventListener("click", () => {
560
- const h = {};
561
- for (const [b, a] of c) {
562
- if (a.required && !a.value) {
563
- a.style.borderColor = "#e5484d";
555
+ const p = {};
556
+ for (const [k, i] of c) {
557
+ if (i.required && !i.value) {
558
+ i.style.borderColor = "#e5484d";
564
559
  return;
565
560
  }
566
- h[b] = a.type === "number" ? Number(a.value) : a.value;
561
+ p[k] = i.type === "number" ? Number(i.value) : i.value;
567
562
  }
568
- this.formHost.replaceChildren(), this.h.onInvoke(e.id, h);
569
- }), i.append(x, w), l.append(i), this.formHost.append(l), (p = c.values().next().value) == null || p.focus();
563
+ this.formHost.replaceChildren(), this.h.onInvoke(e.id, p);
564
+ }), a.append(x, w), l.append(a), this.formHost.append(l), (h = c.values().next().value) == null || h.focus();
570
565
  }
571
566
  messageEl(e, l, c = !1) {
572
- var P, I, M, j;
567
+ var $, z, I, M;
573
568
  if (e.senderRole === "system") {
574
569
  const d = n("div", "ocw-sys");
575
570
  return d.textContent = e.deletedAt ? "message deleted" : ae(e.content), d;
576
571
  }
577
- const i = e.senderId === this.me, x = !!e.internal, w = n("div", `ocw-row ${x ? "ocw-note mine" : i ? "mine" : "theirs"} ${e.senderRole === "bot" ? "ocw-bot" : ""}`);
578
- !i && !x && w.append(n("div", "ocw-dot", e.senderRole === "bot" ? "🤖" : "🧑"));
579
- const y = n("div");
572
+ const a = e.senderId === this.me, x = !!e.internal, w = n("div", `ocw-row ${x ? "ocw-note mine" : a ? "mine" : "theirs"} ${e.senderRole === "bot" ? "ocw-bot" : ""}`), m = n("div");
580
573
  if (c) {
581
- const d = e.senderRole === "bot" ? ((P = this.cfg.i18n) == null ? void 0 : P.aiAssistant) ?? "AI Assistant" : ((I = this.cfg.subject) == null ? void 0 : I.ownerLabel) ?? ((M = this.cfg.subject) == null ? void 0 : M.title) ?? "Support";
582
- y.append(n("div", "ocw-msg-sender", d));
574
+ const d = e.senderRole === "bot" ? (($ = this.cfg.i18n) == null ? void 0 : $.aiAssistant) ?? "AI Assistant" : ((z = this.cfg.subject) == null ? void 0 : z.ownerLabel) ?? ((I = this.cfg.subject) == null ? void 0 : I.title) ?? "Support";
575
+ m.append(n("div", "ocw-msg-sender", d));
583
576
  }
584
- const p = n("div", "ocw-bubble-wrap");
577
+ const h = n("div", "ocw-bubble-wrap");
585
578
  if (e.replyToId) {
586
579
  const d = n("div", "ocw-reply-to", "↩ replying to a message");
587
- d.style.cssText = "font-size:11px;color:var(--ocw-mut);margin-bottom:2px;font-style:italic", y.append(d);
580
+ d.style.cssText = "font-size:11px;color:var(--ocw-mut);margin-bottom:2px;font-style:italic", m.append(d);
588
581
  }
589
- const h = n("div", "ocw-bubble");
590
- let b = null;
591
- if (e.deletedAt) h.append(n("span", "ocw-deleted", "message deleted"));
582
+ const p = n("div", "ocw-bubble");
583
+ let k = null;
584
+ if (e.deletedAt) p.append(n("span", "ocw-deleted", "message deleted"));
592
585
  else if (e.content.kind === "attachment") {
593
586
  const d = e.content;
594
- if ((j = d.mime) != null && j.startsWith("image/")) {
587
+ if ((M = d.mime) != null && M.startsWith("image/")) {
595
588
  const r = document.createElement("img");
596
- r.src = d.url, r.alt = d.name ?? "image", r.style.cssText = "max-width:220px;max-height:160px;border-radius:10px;display:block;cursor:pointer", r.addEventListener("click", () => window.open(d.url, "_blank")), h.append(r);
589
+ r.src = d.url, r.alt = d.name ?? "image", r.style.cssText = "max-width:220px;max-height:160px;border-radius:10px;display:block;cursor:pointer", r.addEventListener("click", () => window.open(d.url, "_blank")), p.append(r);
597
590
  } else {
598
591
  const r = document.createElement("a");
599
- r.href = d.url, r.target = "_blank", r.rel = "noopener", r.style.cssText = "display:flex;align-items:center;gap:8px;color:inherit;text-decoration:none", r.append(n("span", void 0, "📄"), n("span", void 0, d.name ?? "file")), h.append(r);
592
+ r.href = d.url, r.target = "_blank", r.rel = "noopener", r.style.cssText = "display:flex;align-items:center;gap:8px;color:inherit;text-decoration:none", r.append(n("span", void 0, "📄"), n("span", void 0, d.name ?? "file")), p.append(r);
600
593
  }
601
594
  } else if (e.content.kind === "appointment") {
602
595
  const d = e.content, r = n("div", "ocw-appt");
603
596
  r.append(n("div", "ocw-appt-title", `📅 ${d.title}`)), r.append(n("div", "ocw-appt-time", new Date(d.startIso).toLocaleString() + " – " + new Date(d.endIso).toLocaleTimeString())), d.location && r.append(n("div", "ocw-appt-loc", `📍 ${d.location}`)), d.description && r.append(n("div", "ocw-appt-desc", d.description));
604
- const C = n("div", "ocw-appt-links"), v = document.createElement("a");
605
- v.href = d.googleUrl, v.target = "_blank", v.rel = "noopener", v.className = "ocw-appt-btn", v.textContent = "📅 Add to Google Calendar";
606
- const u = document.createElement("a");
607
- u.href = d.icalUrl, u.download = `${d.title}.ics`, u.className = "ocw-appt-btn ocw-appt-btn-sec", u.textContent = "🍎 Apple / iCal", C.append(v, u), r.append(C), h.append(r);
597
+ const g = n("div", "ocw-appt-links"), y = document.createElement("a");
598
+ y.href = d.googleUrl, y.target = "_blank", y.rel = "noopener", y.className = "ocw-appt-btn", y.textContent = "📅 Add to Google Calendar";
599
+ const f = document.createElement("a");
600
+ f.href = d.icalUrl, f.download = `${d.title}.ics`, f.className = "ocw-appt-btn ocw-appt-btn-sec", f.textContent = "🍎 Apple / iCal", g.append(y, f), r.append(g), p.append(r);
608
601
  } else
609
- b = document.createTextNode(ae(e.content)), h.append(b), e.editedAt && h.append(n("span", "ocw-edited", "(edited)"));
610
- if (p.append(h), !i && !x && this.h.onTranslate && e.content.kind === "text" && !e.deletedAt && e.seq > 0 && b) {
602
+ k = document.createTextNode(ae(e.content)), p.append(k), e.editedAt && p.append(n("span", "ocw-edited", "(edited)"));
603
+ if (h.append(p), !a && !x && this.h.onTranslate && e.content.kind === "text" && !e.deletedAt && e.seq > 0 && k) {
611
604
  const d = e.content.text;
612
605
  if (d.trim()) {
613
606
  const r = n("button", "ocw-translate-btn", "🌐");
614
- r.type = "button", r.title = "Translate", r.addEventListener("click", (C) => {
615
- if (C.stopPropagation(), this.showingTranslation.has(e.id)) {
616
- this.showingTranslation.delete(e.id), b.textContent = d, r.textContent = "🌐", r.title = "Translate";
607
+ r.type = "button", r.title = "Translate";
608
+ const g = n("div", "ocw-translation");
609
+ g.style.display = "none", p.append(g);
610
+ const y = (L) => {
611
+ g.textContent = L, g.style.display = "", this.showingTranslation.add(e.id), r.textContent = "↩", r.title = "Show original";
612
+ }, f = () => {
613
+ g.style.display = "none", this.showingTranslation.delete(e.id), r.textContent = "🌐", r.title = "Translate";
614
+ };
615
+ r.addEventListener("click", (L) => {
616
+ if (L.stopPropagation(), this.showingTranslation.has(e.id)) {
617
+ f();
617
618
  return;
618
619
  }
619
- const v = this.translationCache.get(e.id);
620
- if (v !== void 0) {
621
- this.showingTranslation.add(e.id), b.textContent = v, r.textContent = "↩", r.title = "Show original";
620
+ const P = this.translationCache.get(e.id);
621
+ if (P !== void 0) {
622
+ y(P);
622
623
  return;
623
624
  }
624
- r.textContent = "⏳", this.h.onTranslate(d).then((u) => {
625
- if (u === null) {
625
+ r.textContent = "⏳", this.h.onTranslate(d).then((R) => {
626
+ if (R === null) {
626
627
  r.textContent = "⚠️", r.title = "Translation unavailable", setTimeout(() => {
627
628
  r.textContent = "🌐", r.title = "Translate";
628
629
  }, 1500);
629
630
  return;
630
631
  }
631
- this.translationCache.set(e.id, u), this.showingTranslation.add(e.id), b.textContent = u, r.textContent = "↩", r.title = "Show original";
632
+ this.translationCache.set(e.id, R), y(R);
632
633
  });
633
- }), p.append(r);
634
+ }), h.append(r);
635
+ const u = this.translationCache.get(e.id);
636
+ this.showingTranslation.has(e.id) && u !== void 0 && y(u);
634
637
  }
635
638
  }
636
- if (i && !e.deletedAt && e.seq > 0 && (this.h.onEdit ?? this.h.onDelete)) {
639
+ if (a && !e.deletedAt && e.seq > 0 && (this.h.onEdit ?? this.h.onDelete)) {
637
640
  const d = n("div", "ocw-msg-menu");
638
641
  if (this.h.onEdit) {
639
642
  const r = n("button", void 0, "✏️");
640
- r.title = "Edit", r.addEventListener("click", (C) => {
641
- C.stopPropagation();
642
- const v = ae(e.content), u = document.createElement("textarea");
643
- u.value = v, u.rows = Math.min(4, Math.ceil(v.length / 40) + 1), u.style.cssText = "width:100%;resize:vertical;border:1px solid var(--ocw-accent);border-radius:8px;padding:6px 10px;font:inherit;font-size:14px;background:var(--ocw-card);color:#1c1b1a;box-sizing:border-box";
644
- const f = n("button", "ocw-form-submit", "Save");
645
- f.style.cssText = "margin-top:6px;padding:5px 14px;font-size:13px";
646
- const R = n("button", "ocw-form-cancel", "Cancel");
647
- R.style.cssText = "margin-top:6px;padding:5px 10px;font-size:13px";
648
- const B = n("div");
649
- B.style.cssText = "display:flex;gap:6px;justify-content:flex-end", B.append(R, f);
650
- const A = n("div");
651
- A.append(u, B), h.replaceChildren(A), u.focus(), u.select();
652
- const k = () => h.replaceChildren(b ?? document.createTextNode(v));
653
- R.addEventListener("click", k), f.addEventListener("click", () => {
654
- const S = u.value.trim();
655
- S && S !== v && this.h.onEdit(e.id, S), k();
656
- }), u.addEventListener("keydown", (S) => {
657
- S.key === "Enter" && !S.shiftKey && (S.preventDefault(), f.click()), S.key === "Escape" && k();
643
+ r.title = "Edit", r.addEventListener("click", (g) => {
644
+ g.stopPropagation();
645
+ const y = ae(e.content), f = document.createElement("textarea");
646
+ f.value = y, f.rows = Math.min(4, Math.ceil(y.length / 40) + 1), f.style.cssText = "width:100%;resize:vertical;border:1px solid var(--ocw-accent);border-radius:8px;padding:6px 10px;font:inherit;font-size:14px;background:var(--ocw-card);color:#1c1b1a;box-sizing:border-box";
647
+ const u = n("button", "ocw-form-submit", "Save");
648
+ u.style.cssText = "margin-top:6px;padding:5px 14px;font-size:13px";
649
+ const L = n("button", "ocw-form-cancel", "Cancel");
650
+ L.style.cssText = "margin-top:6px;padding:5px 10px;font-size:13px";
651
+ const P = n("div");
652
+ P.style.cssText = "display:flex;gap:6px;justify-content:flex-end", P.append(L, u);
653
+ const R = n("div");
654
+ R.append(f, P), p.replaceChildren(R), f.focus(), f.select();
655
+ const C = () => p.replaceChildren(k ?? document.createTextNode(y));
656
+ L.addEventListener("click", C), u.addEventListener("click", () => {
657
+ const S = f.value.trim();
658
+ S && S !== y && this.h.onEdit(e.id, S), C();
659
+ }), f.addEventListener("keydown", (S) => {
660
+ S.key === "Enter" && !S.shiftKey && (S.preventDefault(), u.click()), S.key === "Escape" && C();
658
661
  });
659
662
  }), d.append(r);
660
663
  }
661
664
  if (this.h.onDelete) {
662
665
  const r = n("button", "del", "🗑");
663
- r.title = "Delete", r.addEventListener("click", (C) => {
664
- C.stopPropagation(), this.h.onDelete(e.id);
666
+ r.title = "Delete", r.addEventListener("click", (g) => {
667
+ g.stopPropagation(), this.h.onDelete(e.id);
665
668
  }), d.append(r);
666
669
  }
667
- p.append(d);
670
+ h.append(d);
668
671
  }
669
- if (y.append(p), this.h.onReact && !e.deletedAt && e.seq > 0) {
672
+ if (m.append(h), this.h.onReact && !e.deletedAt && e.seq > 0) {
670
673
  const d = n("div", "ocw-react-wrap"), r = n("div", "ocw-react");
671
674
  if (e.reactions && Object.keys(e.reactions).length)
672
- for (const [u, f] of Object.entries(e.reactions)) {
673
- const R = n("button", `ocw-react-pill${f.includes(this.me) ? " mine" : ""}`, `${u} ${f.length}`);
674
- R.addEventListener("click", () => {
675
- var B, A;
676
- return (A = (B = this.h).onReact) == null ? void 0 : A.call(B, e.id, u, f.includes(this.me));
677
- }), r.append(R);
675
+ for (const [f, u] of Object.entries(e.reactions)) {
676
+ const L = n("button", `ocw-react-pill${u.includes(this.me) ? " mine" : ""}`, `${f} ${u.length}`);
677
+ L.addEventListener("click", () => {
678
+ var P, R;
679
+ return (R = (P = this.h).onReact) == null ? void 0 : R.call(P, e.id, f, u.includes(this.me));
680
+ }), r.append(L);
678
681
  }
679
- const C = n("button", "ocw-react-btn", "+"), v = n("div", "ocw-react-picker");
680
- for (const u of Fe) {
681
- const f = n("button", void 0, u);
682
- f.addEventListener("click", (R) => {
683
- var A, k, S, D;
684
- R.stopPropagation();
685
- const B = (k = (A = e.reactions) == null ? void 0 : A[u]) == null ? void 0 : k.includes(this.me);
686
- (D = (S = this.h).onReact) == null || D.call(S, e.id, u, !!B), v.style.display = "none";
687
- }), v.append(f);
682
+ const g = n("button", "ocw-react-btn", "+"), y = n("div", "ocw-react-picker");
683
+ for (const f of Fe) {
684
+ const u = n("button", void 0, f);
685
+ u.addEventListener("click", (L) => {
686
+ var R, C, S, D;
687
+ L.stopPropagation();
688
+ const P = (C = (R = e.reactions) == null ? void 0 : R[f]) == null ? void 0 : C.includes(this.me);
689
+ (D = (S = this.h).onReact) == null || D.call(S, e.id, f, !!P), y.style.display = "none";
690
+ }), y.append(u);
688
691
  }
689
- v.style.display = "none", C.addEventListener("click", (u) => {
690
- u.stopPropagation();
691
- const f = v.style.display === "none";
692
- v.style.display = f ? "flex" : "none", f && document.addEventListener("click", () => {
693
- v.style.display = "none";
692
+ y.style.display = "none", g.addEventListener("click", (f) => {
693
+ f.stopPropagation();
694
+ const u = y.style.display === "none";
695
+ y.style.display = u ? "flex" : "none", u && document.addEventListener("click", () => {
696
+ y.style.display = "none";
694
697
  }, { once: !0 });
695
- }), r.append(C), d.append(r, v), y.append(d);
696
- } else e.reactions && Object.keys(e.reactions).length && y.append(n("div", "ocw-react", Object.entries(e.reactions).map(([d, r]) => `${d}${r.length}`).join(" ")));
697
- const a = n("div", "ocw-time ocw-meta", Ye(e.ts));
698
- if (i && e.status) {
698
+ }), r.append(g), d.append(r, y), m.append(d);
699
+ } else e.reactions && Object.keys(e.reactions).length && m.append(n("div", "ocw-react", Object.entries(e.reactions).map(([d, r]) => `${d}${r.length}`).join(" ")));
700
+ const i = n("div", "ocw-time ocw-meta", Ye(e.ts));
701
+ if (a && e.status) {
699
702
  const d = n("span", `ocw-tick${e.status === "read" ? " read" : e.status === "delivered" ? " delivered" : ""}`, Qe(e.status));
700
- a.append(d);
703
+ i.append(d);
701
704
  }
702
- return i && e.seq > 0 && l.lastReadByOthers >= e.seq && a.append(n("span", "ocw-seen", " · Seen")), y.append(a), w.append(y), w;
705
+ return a && e.seq > 0 && l.lastReadByOthers >= e.seq && i.append(n("span", "ocw-seen", " · Seen")), m.append(i), w.append(m), w;
703
706
  }
704
707
  }
705
708
  function Qe(t) {
@@ -714,40 +717,40 @@ function Qe(t) {
714
717
  return "🕓";
715
718
  }
716
719
  }
717
- const _ = /* @__PURE__ */ new WeakMap(), Z = /* @__PURE__ */ new Map();
720
+ const U = /* @__PURE__ */ new WeakMap(), ee = /* @__PURE__ */ new Map();
718
721
  function ke(t) {
719
722
  return `relay-launcher::${t.profileId}::${t.subjectId ?? ""}`;
720
723
  }
721
- let K = null;
724
+ let V = null;
722
725
  function Je() {
723
- if (K && K.state !== "closed") return K;
726
+ if (V && V.state !== "closed") return V;
724
727
  try {
725
- return K = new AudioContext(), K;
728
+ return V = new AudioContext(), V;
726
729
  } catch {
727
730
  return null;
728
731
  }
729
732
  }
730
733
  function it(t) {
731
734
  var e;
732
- (e = _.get(t)) == null || e.close(), _.delete(t);
735
+ (e = U.get(t)) == null || e.close(), U.delete(t);
733
736
  }
734
737
  function at(t) {
735
738
  var se, le, de, pe, he, ue, fe, we;
736
- _.has(t.el) && (_.get(t.el).close(), _.delete(t.el)), t.launcher && ((se = Z.get(ke(t))) == null || se.close());
739
+ U.has(t.el) && (U.get(t.el).close(), U.delete(t.el)), t.launcher && ((se = ee.get(ke(t))) == null || se.close());
737
740
  const e = Re();
738
741
  let l, c = !1;
739
- const i = t.token ?? t.userId ?? e, x = i !== e ? e : void 0, { wsUrl: w, httpBase: y } = Ae(t.url, t.apiUrl);
740
- let p = new Oe(i);
741
- const h = t.subjectId ? `${i}::${t.subjectId}` : i, b = new Ne(h);
742
- let a, P = !1, I = null, M = null, j = null, d = null;
742
+ const a = t.token ?? t.userId ?? e, x = a !== e ? e : void 0, { wsUrl: w, httpBase: m } = Ae(t.url, t.apiUrl);
743
+ let h = new Oe(a);
744
+ const p = t.subjectId ? `${a}::${t.subjectId}` : a, k = new Ne(p);
745
+ let i, $ = !1, z = null, I = null, M = null, d = null;
743
746
  !t.launcher && !t.el.style.height && t.el.clientHeight === 0 && (t.el.style.width = t.el.style.width || "100%", t.el.style.height = "600px");
744
- for (const o of b.load()) p.addOptimistic(o.clientMsgId, o.content);
745
- let r = null, C = null, v = 0, u = !t.launcher;
747
+ for (const o of k.load()) h.addOptimistic(o.clientMsgId, o.content);
748
+ let r = null, g = null, y = 0, f = !t.launcher;
746
749
  if (t.launcher) {
747
750
  const s = (t.position ?? "bottom-right").includes("right");
748
751
  r = document.createElement("div"), r.style.cssText = `position:fixed;${s ? "right:20px" : "left:20px"};bottom:20px;z-index:9999;display:flex;flex-direction:column;align-items:${s ? "flex-end" : "flex-start"};gap:12px`;
749
- const m = document.createElement("div"), L = typeof window < "u" && typeof window.matchMedia == "function" ? window.matchMedia("(max-width: 479px)") : null, W = (z) => {
750
- t.el.classList.toggle("ocw-fs", z), m.style.cssText = z ? [
752
+ const b = document.createElement("div"), B = typeof window < "u" && typeof window.matchMedia == "function" ? window.matchMedia("(max-width: 479px)") : null, G = (j) => {
753
+ t.el.classList.toggle("ocw-fs", j), b.style.cssText = j ? [
751
754
  "position:fixed",
752
755
  "inset:0",
753
756
  "width:100%",
@@ -776,10 +779,10 @@ function at(t) {
776
779
  "transform:scale(.95)"
777
780
  ].join(";");
778
781
  };
779
- W((L == null ? void 0 : L.matches) ?? !1);
780
- const G = (z) => W(z.matches);
781
- L == null || L.addEventListener("change", G), I = L, M = G, t.el.style.cssText = "width:100%;height:100%;overflow:hidden", m.append(t.el);
782
- const Y = '<svg viewBox="0 0 24 24" width="26" height="26" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><path d="M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z" fill="currentColor" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>', X = '<svg viewBox="0 0 24 24" width="22" height="22" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><path d="M18 6 6 18M6 6l12 12" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"/></svg>', q = document.createElement("button");
782
+ G((B == null ? void 0 : B.matches) ?? !1);
783
+ const K = (j) => G(j.matches);
784
+ B == null || B.addEventListener("change", K), z = B, I = K, t.el.style.cssText = "width:100%;height:100%;overflow:hidden", b.append(t.el);
785
+ const X = '<svg viewBox="0 0 24 24" width="26" height="26" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><path d="M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z" fill="currentColor" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>', Q = '<svg viewBox="0 0 24 24" width="22" height="22" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><path d="M18 6 6 18M6 6l12 12" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"/></svg>', q = document.createElement("button");
783
786
  q.type = "button", q.style.cssText = [
784
787
  "width:56px;height:56px;border-radius:50%",
785
788
  `background:${t.accent ?? "#6c5ce7"}`,
@@ -792,12 +795,12 @@ function at(t) {
792
795
  q.style.transform = "scale(1.08)";
793
796
  }, q.onmouseleave = () => {
794
797
  q.style.transform = "scale(1)";
795
- }, C = document.createElement("span"), C.style.cssText = "position:absolute;top:-4px;right:-4px;background:#4c6fff;color:#fff;border-radius:50%;width:20px;height:20px;font-size:11px;font-weight:700;display:none;align-items:center;justify-content:center";
796
- const Q = () => {
797
- q.innerHTML = u ? X : Y, q.setAttribute("aria-label", u ? "Close chat" : "Open chat"), q.setAttribute("aria-expanded", String(u)), q.append(C);
798
+ }, g = document.createElement("span"), g.style.cssText = "position:absolute;top:-4px;right:-4px;background:#4c6fff;color:#fff;border-radius:50%;width:20px;height:20px;font-size:11px;font-weight:700;display:none;align-items:center;justify-content:center";
799
+ const J = () => {
800
+ q.innerHTML = f ? Q : X, q.setAttribute("aria-label", f ? "Close chat" : "Open chat"), q.setAttribute("aria-expanded", String(f)), q.append(g);
798
801
  };
799
- Q(), r.append(m, q), document.body.append(r);
800
- const te = `ocw-teaser-dismissed::${t.profileId}`, J = typeof t.launcherMessage == "string" ? { title: t.launcherMessage } : t.launcherMessage;
802
+ J(), r.append(b, q), document.body.append(r);
803
+ const te = `ocw-teaser-dismissed::${t.profileId}`, Z = typeof t.launcherMessage == "string" ? { title: t.launcherMessage } : t.launcherMessage;
801
804
  let E = null;
802
805
  const Le = () => {
803
806
  try {
@@ -806,13 +809,13 @@ function at(t) {
806
809
  return !1;
807
810
  }
808
811
  }, Pe = '<svg viewBox="0 0 24 24" width="15" height="15" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><path d="M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z" fill="currentColor" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>', be = () => {
809
- const z = J != null && J.title ? J : p.launcherMessage ?? void 0;
810
- if (!(!!(z != null && z.title) && !u && !Le())) {
812
+ const j = Z != null && Z.title ? Z : h.launcherMessage ?? void 0;
813
+ if (!(!!(j != null && j.title) && !f && !Le())) {
811
814
  E && (E.remove(), E = null);
812
815
  return;
813
816
  }
814
817
  if (E) return;
815
- E = document.createElement("div"), E.setAttribute("role", "button"), E.setAttribute("tabindex", "0"), E.setAttribute("aria-label", z.title), E.style.cssText = [
818
+ E = document.createElement("div"), E.setAttribute("role", "button"), E.setAttribute("tabindex", "0"), E.setAttribute("aria-label", j.title), E.style.cssText = [
816
819
  "max-width:280px",
817
820
  "background:#fff",
818
821
  "border-radius:16px",
@@ -825,138 +828,138 @@ function at(t) {
825
828
  "animation:ocw-teaser-in .22s ease-out"
826
829
  ].join(";");
827
830
  const oe = document.createElement("div");
828
- if (oe.textContent = z.title, oe.style.cssText = "font-size:15px;font-weight:600;color:#111;line-height:1.35", E.append(oe), z.subtitle) {
831
+ if (oe.textContent = j.title, oe.style.cssText = "font-size:15px;font-weight:600;color:#111;line-height:1.35", E.append(oe), j.subtitle) {
829
832
  const O = document.createElement("div");
830
833
  O.style.cssText = "display:flex;align-items:center;gap:6px;margin-top:6px;font-size:13px;color:#6b7280";
831
834
  const ie = document.createElement("span");
832
835
  ie.innerHTML = Pe, ie.style.cssText = `color:${t.accent ?? "#6c5ce7"};display:inline-flex`;
833
836
  const me = document.createElement("span");
834
- me.textContent = z.subtitle, O.append(ie, me), E.append(O);
837
+ me.textContent = j.subtitle, O.append(ie, me), E.append(O);
835
838
  }
836
- const U = document.createElement("button");
837
- U.type = "button", U.setAttribute("aria-label", "Dismiss"), U.innerHTML = '<svg viewBox="0 0 24 24" width="14" height="14" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M18 6 6 18M6 6l12 12" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"/></svg>', U.style.cssText = "position:absolute;top:8px;right:8px;width:24px;height:24px;border:none;border-radius:50%;background:#f3f4f6;color:#6b7280;cursor:pointer;display:flex;align-items:center;justify-content:center;padding:0", U.addEventListener("click", (O) => {
839
+ const F = document.createElement("button");
840
+ F.type = "button", F.setAttribute("aria-label", "Dismiss"), F.innerHTML = '<svg viewBox="0 0 24 24" width="14" height="14" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M18 6 6 18M6 6l12 12" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"/></svg>', F.style.cssText = "position:absolute;top:8px;right:8px;width:24px;height:24px;border:none;border-radius:50%;background:#f3f4f6;color:#6b7280;cursor:pointer;display:flex;align-items:center;justify-content:center;padding:0", F.addEventListener("click", (O) => {
838
841
  O.stopPropagation();
839
842
  try {
840
843
  sessionStorage.setItem(te, "1");
841
844
  } catch {
842
845
  }
843
846
  E && (E.remove(), E = null);
844
- }), E.append(U);
847
+ }), E.append(F);
845
848
  const xe = () => {
846
- u || (u = !0, ne(!0), Q(), v = 0, C && (C.style.display = "none"), E && (E.remove(), E = null));
849
+ f || (f = !0, ne(!0), J(), y = 0, g && (g.style.display = "none"), E && (E.remove(), E = null));
847
850
  };
848
851
  E.addEventListener("click", xe), E.addEventListener("keydown", (O) => {
849
852
  (O.key === "Enter" || O.key === " ") && (O.preventDefault(), xe());
850
853
  }), r.insertBefore(E, q);
851
854
  };
852
855
  if (!document.getElementById("ocw-teaser-style")) {
853
- const z = document.createElement("style");
854
- z.id = "ocw-teaser-style", z.textContent = "@keyframes ocw-teaser-in{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}", document.head.append(z);
856
+ const j = document.createElement("style");
857
+ j.id = "ocw-teaser-style", j.textContent = "@keyframes ocw-teaser-in{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}", document.head.append(j);
855
858
  }
856
859
  d = be, be();
857
- const ne = (z) => {
858
- z ? (m.style.display = "flex", requestAnimationFrame(() => {
859
- m.style.opacity = "1", m.style.transform = "scale(1)";
860
- })) : (m.style.opacity = "0", m.style.transform = "scale(.95)", setTimeout(() => {
861
- u || (m.style.display = "none");
860
+ const ne = (j) => {
861
+ j ? (b.style.display = "flex", requestAnimationFrame(() => {
862
+ b.style.opacity = "1", b.style.transform = "scale(1)";
863
+ })) : (b.style.opacity = "0", b.style.transform = "scale(.95)", setTimeout(() => {
864
+ f || (b.style.display = "none");
862
865
  }, 180));
863
866
  };
864
867
  q.addEventListener("click", () => {
865
- if (u = !u, ne(u), Q(), u) {
866
- v = 0, C && (C.style.display = "none");
868
+ if (f = !f, ne(f), J(), f) {
869
+ y = 0, g && (g.style.display = "none");
867
870
  try {
868
871
  sessionStorage.setItem(te, "1");
869
872
  } catch {
870
873
  }
871
874
  }
872
875
  d == null || d();
873
- }), j = (z) => {
874
- z.key === "Escape" && u && (u = !1, ne(!1), Q());
875
- }, document.addEventListener("keydown", j);
876
+ }), M = (j) => {
877
+ j.key === "Escape" && f && (f = !1, ne(!1), J());
878
+ }, document.addEventListener("keydown", M);
876
879
  }
877
- const f = () => {
878
- u || (v++, C && (C.textContent = String(v), C.style.display = "flex"));
879
- }, R = () => {
880
+ const u = () => {
881
+ f || (y++, g && (g.textContent = String(y), g.style.display = "flex"));
882
+ }, L = () => {
880
883
  try {
881
884
  const o = Je();
882
885
  if (!o) return;
883
886
  o.state === "suspended" && o.resume().catch(() => {
884
887
  });
885
- const s = o.createOscillator(), m = o.createGain();
886
- s.connect(m), m.connect(o.destination), s.frequency.setValueAtTime(880, o.currentTime), s.frequency.exponentialRampToValueAtTime(440, o.currentTime + 0.15), m.gain.setValueAtTime(0.3, o.currentTime), m.gain.exponentialRampToValueAtTime(1e-3, o.currentTime + 0.3), s.start(), s.stop(o.currentTime + 0.3);
888
+ const s = o.createOscillator(), b = o.createGain();
889
+ s.connect(b), b.connect(o.destination), s.frequency.setValueAtTime(880, o.currentTime), s.frequency.exponentialRampToValueAtTime(440, o.currentTime + 0.15), b.gain.setValueAtTime(0.3, o.currentTime), b.gain.exponentialRampToValueAtTime(1e-3, o.currentTime + 0.3), s.start(), s.stop(o.currentTime + 0.3);
887
890
  } catch {
888
891
  }
889
- }, B = [], A = (o) => {
890
- for (; B.length; ) {
891
- const s = B.shift();
892
- b.add({ clientMsgId: s.clientMsgId, content: s.content, ts: Date.now() }), k.send({ type: "send", conversationId: o, clientMsgId: s.clientMsgId, content: s.content });
892
+ }, P = [], R = (o) => {
893
+ for (; P.length; ) {
894
+ const s = P.shift();
895
+ k.add({ clientMsgId: s.clientMsgId, content: s.content, ts: Date.now() }), C.send({ type: "send", conversationId: o, clientMsgId: s.clientMsgId, content: s.content });
893
896
  }
894
897
  };
895
- let k;
898
+ let C;
896
899
  const S = new He(`ocw-e2e-${t.profileId}`);
897
900
  let D = !1;
898
- const g = [], N = [];
899
- let H = !1;
900
- const ee = (o, s) => {
901
- S.sealText(s).then((m) => {
902
- a && k.send({ type: "send", conversationId: a, clientMsgId: o, content: m });
901
+ const _ = [], v = [];
902
+ let N = !1;
903
+ const H = (o, s) => {
904
+ S.sealText(s).then((b) => {
905
+ i && C.send({ type: "send", conversationId: i, clientMsgId: o, content: b });
903
906
  });
904
- }, Ce = (o, s, m) => {
905
- S.sealText(s, m).then((L) => {
906
- a && k.send({ type: "send", conversationId: a, clientMsgId: o, content: L });
907
+ }, Ce = (o, s, b) => {
908
+ S.sealText(s, b).then((B) => {
909
+ i && C.send({ type: "send", conversationId: i, clientMsgId: o, content: B });
907
910
  });
908
911
  }, Te = () => {
909
- for (; g.length; ) {
910
- const o = g.shift();
911
- ee(o.clientMsgId, o.text);
912
+ for (; _.length; ) {
913
+ const o = _.shift();
914
+ H(o.clientMsgId, o.text);
912
915
  }
913
- for (; N.length; ) {
914
- const o = N.shift();
915
- ee(o.clientMsgId, o.text);
916
+ for (; v.length; ) {
917
+ const o = v.shift();
918
+ H(o.clientMsgId, o.text);
916
919
  }
917
- }, Ie = (o) => {
918
- k.send({ type: "fetchPrekey", targetUserId: o });
919
- }, Se = t.i18n ?? {}, Ee = ["ar", "he", "fa", "ur"], ze = typeof navigator < "u" ? (navigator.language ?? "").slice(0, 2).toLowerCase() : "";
920
+ }, Se = (o) => {
921
+ C.send({ type: "fetchPrekey", targetUserId: o });
922
+ }, Ie = t.i18n ?? {}, Ee = ["ar", "he", "fa", "ur"], ze = typeof navigator < "u" ? (navigator.language ?? "").slice(0, 2).toLowerCase() : "";
920
923
  Ee.includes(ze) && !t.el.dir && (t.el.dir = "rtl", t.el.style.fontFamily = t.el.style.fontFamily || "Tahoma,Arial,system-ui,sans-serif");
921
- const re = `oc_prechat_${t.profileId}_${i.slice(-8)}`, $ = new Xe(t.el, i, {
924
+ const ce = `oc_prechat_${t.profileId}_${a.slice(-8)}`, A = new Xe(t.el, a, {
922
925
  onSend(o) {
923
- const s = `cm_${Math.random().toString(36).slice(2)}`, m = { kind: "text", text: o };
924
- p.addOptimistic(s, m), $.render(p), p.e2e ? S.ready ? ee(s, o) : H ? N.push({ clientMsgId: s, text: o }) : (g.push({ clientMsgId: s, text: o }), p.assignedAgentId && Ie(p.assignedAgentId)) : a ? (b.add({ clientMsgId: s, content: m, ts: Date.now() }), k.send({ type: "send", conversationId: a, clientMsgId: s, content: m })) : B.push({ clientMsgId: s, content: m });
926
+ const s = `cm_${Math.random().toString(36).slice(2)}`, b = { kind: "text", text: o };
927
+ h.addOptimistic(s, b), A.render(h), h.e2e ? S.ready ? H(s, o) : N ? v.push({ clientMsgId: s, text: o }) : (_.push({ clientMsgId: s, text: o }), h.assignedAgentId && Se(h.assignedAgentId)) : i ? (k.add({ clientMsgId: s, content: b, ts: Date.now() }), C.send({ type: "send", conversationId: i, clientMsgId: s, content: b })) : P.push({ clientMsgId: s, content: b });
925
928
  },
926
929
  async onAttach(o) {
927
- if (!a) return;
928
- const s = `${y}/upload?name=${encodeURIComponent(o.name)}`, m = `cm_${Math.random().toString(36).slice(2)}`;
929
- p.addOptimistic(m, { kind: "text", text: `📎 Uploading ${o.name}…` }), $.render(p);
930
+ if (!i) return;
931
+ const s = `${m}/upload?name=${encodeURIComponent(o.name)}`, b = `cm_${Math.random().toString(36).slice(2)}`;
932
+ h.addOptimistic(b, { kind: "text", text: `📎 Uploading ${o.name}…` }), A.render(h);
930
933
  try {
931
- const L = await fetch(s, {
934
+ const B = await fetch(s, {
932
935
  method: "POST",
933
936
  // Use the resolved connection token (a signed JWT, an explicit userId,
934
937
  // or the anonymous persistent uid) — NOT just opts.token. The server
935
938
  // requires an Authorization header, and the verifier accepts an
936
939
  // anonymous id as a guest; keying off opts.token alone meant anonymous
937
940
  // visitors (the common case) sent no auth and every upload 401'd.
938
- headers: { "content-type": o.type, authorization: `Bearer ${i}` },
941
+ headers: { "content-type": o.type, authorization: `Bearer ${a}` },
939
942
  body: o
940
943
  });
941
- if (!L.ok) throw new Error(`Upload failed: ${L.status}`);
942
- const { url: W, name: G, mime: Y, size: X } = await L.json();
943
- p.addOptimistic(m, { kind: "attachment", url: W, name: G, mime: Y, size: X }), $.render(p), k.send({ type: "send", conversationId: a, clientMsgId: m, content: { kind: "attachment", url: W, name: G, mime: Y, size: X } });
944
- } catch (L) {
945
- p.addOptimistic(m, { kind: "text", text: `⚠️ Upload failed: ${L.message}` }), $.render(p);
944
+ if (!B.ok) throw new Error(`Upload failed: ${B.status}`);
945
+ const { url: G, name: K, mime: X, size: Q } = await B.json();
946
+ h.addOptimistic(b, { kind: "attachment", url: G, name: K, mime: X, size: Q }), A.render(h), C.send({ type: "send", conversationId: i, clientMsgId: b, content: { kind: "attachment", url: G, name: K, mime: X, size: Q } });
947
+ } catch (B) {
948
+ h.addOptimistic(b, { kind: "text", text: `⚠️ Upload failed: ${B.message}` }), A.render(h);
946
949
  }
947
950
  },
948
951
  onInvoke(o, s) {
949
- a && k.send({ type: "invoke", conversationId: a, actionId: o, clientInvokeId: `iv_${Math.random().toString(36).slice(2)}`, ...s ? { inputs: s } : {} });
952
+ i && C.send({ type: "invoke", conversationId: i, actionId: o, clientInvokeId: `iv_${Math.random().toString(36).slice(2)}`, ...s ? { inputs: s } : {} });
950
953
  },
951
954
  onTyping(o, s) {
952
- a && k.send({ type: "typing", conversationId: a, isTyping: o, ...s ? { preview: s } : {} });
955
+ i && C.send({ type: "typing", conversationId: i, isTyping: o, ...s ? { preview: s } : {} });
953
956
  },
954
957
  onPreChat(o) {
955
958
  try {
956
- localStorage.setItem(re, "1");
959
+ localStorage.setItem(ce, "1");
957
960
  } catch {
958
961
  }
959
- k.send({
962
+ C.send({
960
963
  type: "open",
961
964
  profileId: t.profileId,
962
965
  ...t.subjectId ? { subjectId: t.subjectId } : {},
@@ -970,7 +973,7 @@ function at(t) {
970
973
  }
971
974
  });
972
975
  const s = o.callback ? `📞 Call-back requested${o.phone ? `: ${o.phone}` : ""}${o.topic ? ` — ${o.topic}` : ""}` : o.topic ? `Topic: ${o.topic}` : "";
973
- s && a && !p.e2e && k.send({ type: "send", conversationId: a, clientMsgId: `pc_${Math.random().toString(36).slice(2, 12)}`, content: { kind: "text", text: s } });
976
+ s && i && !h.e2e && C.send({ type: "send", conversationId: i, clientMsgId: `pc_${Math.random().toString(36).slice(2, 12)}`, content: { kind: "text", text: s } });
974
977
  },
975
978
  ...((le = t.features) == null ? void 0 : le.deflection) !== !1 ? {
976
979
  onDeflectQuery(o) {
@@ -978,38 +981,38 @@ function at(t) {
978
981
  clearTimeout(l);
979
982
  const s = o.trim();
980
983
  if (s.length < 3) {
981
- $.hideDeflection();
984
+ A.hideDeflection();
982
985
  return;
983
986
  }
984
987
  l = setTimeout(() => {
985
- fetch(`${y}/kb/search?profileId=${encodeURIComponent(t.profileId)}&q=${encodeURIComponent(s.slice(0, 200))}`).then((m) => m.ok ? m.json() : { articles: [] }).then((m) => $.showDeflection(m.articles ?? [])).catch(() => $.hideDeflection());
988
+ fetch(`${m}/kb/search?profileId=${encodeURIComponent(t.profileId)}&q=${encodeURIComponent(s.slice(0, 200))}`).then((b) => b.ok ? b.json() : { articles: [] }).then((b) => A.showDeflection(b.articles ?? [])).catch(() => A.hideDeflection());
986
989
  }, 350);
987
990
  }
988
991
  } : {},
989
992
  onReadUpTo(o) {
990
- a && k.send({ type: "read", conversationId: a, seq: o });
993
+ i && C.send({ type: "read", conversationId: i, seq: o });
991
994
  },
992
995
  onLoadMore() {
993
- if (!a || !p.e2e) return;
994
- const o = p.messages()[0];
995
- o && k.send({ type: "history", conversationId: a, beforeSeq: o.seq, limit: 20 });
996
+ if (!i || !h.e2e) return;
997
+ const o = h.messages()[0];
998
+ o && C.send({ type: "history", conversationId: i, beforeSeq: o.seq, limit: 20 });
996
999
  },
997
1000
  onEdit(o, s) {
998
- a && k.send({ type: "edit", conversationId: a, messageId: o, content: { kind: "text", text: s } });
1001
+ i && C.send({ type: "edit", conversationId: i, messageId: o, content: { kind: "text", text: s } });
999
1002
  },
1000
1003
  onDelete(o) {
1001
- a && k.send({ type: "delete", conversationId: a, messageId: o });
1004
+ i && C.send({ type: "delete", conversationId: i, messageId: o });
1002
1005
  },
1003
1006
  ...((de = t.features) == null ? void 0 : de.reactions) !== !1 ? {
1004
- onReact(o, s, m) {
1005
- a && k.send({ type: "react", conversationId: a, messageId: o, emoji: s, remove: m });
1007
+ onReact(o, s, b) {
1008
+ i && C.send({ type: "react", conversationId: i, messageId: o, emoji: s, remove: b });
1006
1009
  }
1007
1010
  } : {},
1008
1011
  ...((pe = t.features) == null ? void 0 : pe.csat) !== !1 ? {
1009
1012
  onCsat(o) {
1010
- a && fetch(`${y}/conversations/${a}/csat`, {
1013
+ i && fetch(`${m}/conversations/${i}/csat`, {
1011
1014
  method: "POST",
1012
- headers: { "Content-Type": "application/json", Authorization: `Bearer ${i}` },
1015
+ headers: { "Content-Type": "application/json", Authorization: `Bearer ${a}` },
1013
1016
  body: JSON.stringify({ score: o })
1014
1017
  }).catch(() => {
1015
1018
  });
@@ -1018,14 +1021,14 @@ function at(t) {
1018
1021
  ...t.translateLang ? {
1019
1022
  async onTranslate(o) {
1020
1023
  try {
1021
- const s = await fetch(`${y}/translate`, {
1024
+ const s = await fetch(`${m}/translate`, {
1022
1025
  method: "POST",
1023
- headers: { "content-type": "application/json", authorization: `Bearer ${i}` },
1026
+ headers: { "content-type": "application/json", authorization: `Bearer ${a}` },
1024
1027
  body: JSON.stringify({ text: o, targetLang: t.translateLang })
1025
1028
  });
1026
1029
  if (!s.ok) return null;
1027
- const { translated: m } = await s.json();
1028
- return m;
1030
+ const { translated: b } = await s.json();
1031
+ return b;
1029
1032
  } catch {
1030
1033
  return null;
1031
1034
  }
@@ -1040,13 +1043,13 @@ function at(t) {
1040
1043
  ...t.theme ? { theme: t.theme } : {},
1041
1044
  ...t.webfont === !1 ? { webfont: !1 } : {},
1042
1045
  ...(he = t.user) != null && he.name || (ue = t.user) != null && ue.avatar ? { userInfo: { ...t.user.name ? { name: t.user.name } : {}, ...t.user.avatar ? { avatar: t.user.avatar } : {} } } : {},
1043
- i18n: Se
1046
+ i18n: Ie
1044
1047
  });
1045
1048
  try {
1046
- localStorage.getItem(re) && $.completePreChat();
1049
+ localStorage.getItem(ce) && A.completePreChat();
1047
1050
  } catch {
1048
1051
  }
1049
- const ce = t.user && (t.user.name || t.user.email || t.user.avatar || t.user.meta) ? {
1052
+ const re = t.user && (t.user.name || t.user.email || t.user.avatar || t.user.meta) ? {
1050
1053
  ...t.user.name ? { name: t.user.name } : {},
1051
1054
  ...t.user.email ? { email: t.user.email } : {},
1052
1055
  ...t.user.avatar ? { avatar: t.user.avatar } : {},
@@ -1059,7 +1062,7 @@ function at(t) {
1059
1062
  // NON-owner side would find-or-create a junk duplicate thread.
1060
1063
  ...t.kind === "direct" && t.peerId ? { kind: "direct", peerId: t.peerId } : t.subjectId ? { subjectId: t.subjectId } : {},
1061
1064
  ...x ? { linkFrom: x } : {},
1062
- ...ce ? { userInfo: ce } : {},
1065
+ ...re ? { userInfo: re } : {},
1063
1066
  ...typeof location < "u" ? { pageUrl: location.href } : {},
1064
1067
  ...typeof document < "u" && document.title ? { pageTitle: document.title } : {},
1065
1068
  // Pass subject display info so the server can persist it to the Subject record.
@@ -1067,61 +1070,61 @@ function at(t) {
1067
1070
  ...(fe = t.subject) != null && fe.title ? { subjectTitle: t.subject.title } : {},
1068
1071
  ...(we = t.subject) != null && we.subtitle ? { subjectMeta: t.subject.subtitle } : {}
1069
1072
  };
1070
- k = new De({
1073
+ C = new De({
1071
1074
  ...t.refreshToken ? { refreshToken: t.refreshToken } : {},
1072
1075
  url: w,
1073
- token: i,
1076
+ token: a,
1074
1077
  open: je,
1075
- getCursor: () => p.highestSeq(),
1076
- onStatusChange: (o, s) => $.setConnStatus(o, s),
1078
+ getCursor: () => h.highestSeq(),
1079
+ onStatusChange: (o, s) => A.setConnStatus(o, s),
1077
1080
  onFrame(o) {
1078
1081
  if (o.type === "opened") {
1079
- if (a = o.conversation.id, !P) {
1080
- P = !0;
1081
- for (const s of b.load())
1082
- k.send({ type: "send", conversationId: a, clientMsgId: s.clientMsgId, content: s.content });
1082
+ if (i = o.conversation.id, !$) {
1083
+ $ = !0;
1084
+ for (const s of k.load())
1085
+ C.send({ type: "send", conversationId: i, clientMsgId: s.clientMsgId, content: s.content });
1083
1086
  }
1084
- qe(w, i, a, p, $, y), B.length && A(a);
1087
+ qe(w, a, i, h, A, m), P.length && R(i);
1085
1088
  }
1086
- if (o.type === "ack" && b.remove(o.clientMsgId), o.type === "prekeyBundle") {
1087
- o.bundle && (H = !0, S.x3dhSendTo(o.bundle).then((s) => {
1088
- const m = [...g.splice(0), ...N.splice(0)];
1089
- for (const L of m) Ce(L.clientMsgId, L.text, s);
1090
- $.render(p);
1089
+ if (o.type === "ack" && k.remove(o.clientMsgId), o.type === "prekeyBundle") {
1090
+ o.bundle && (N = !0, S.x3dhSendTo(o.bundle).then((s) => {
1091
+ const b = [..._.splice(0), ...v.splice(0)];
1092
+ for (const B of b) Ce(B.clientMsgId, B.text, s);
1093
+ A.render(h);
1091
1094
  }));
1092
1095
  return;
1093
1096
  }
1094
- if (o.type === "message" && p.e2e) {
1097
+ if (o.type === "message" && h.e2e) {
1095
1098
  const s = _e(o.message.content);
1096
1099
  if (s && !S.ready) {
1097
1100
  S.x3dhReceiveFrom(s.x3dhIK, s.x3dhEK, s.x3dhSPK, s.x3dhOTP).then(async () => {
1098
- await S.openFrame(o), p.apply(o), $.render(p);
1101
+ await S.openFrame(o), h.apply(o), A.render(h);
1099
1102
  });
1100
1103
  return;
1101
1104
  }
1102
1105
  }
1103
1106
  if (o.type === "peerkey") {
1104
1107
  S.onPeerKey(o.key).then(() => {
1105
- Te(), $.render(p);
1108
+ Te(), A.render(h);
1106
1109
  });
1107
1110
  return;
1108
1111
  }
1109
1112
  (async () => {
1110
- if (p.e2e && await S.openFrame(o), p.apply(o), o.type === "manifest" && (d == null || d()), o.type === "message" && o.message.senderId !== i && !o.message.internal && (f(), R()), p.e2e && a && !D) {
1113
+ if (h.e2e && await S.openFrame(o), h.apply(o), o.type === "manifest" && (d == null || d()), o.type === "message" && o.message.senderId !== a && !o.message.internal && (u(), L()), h.e2e && i && !D) {
1111
1114
  D = !0;
1112
1115
  const s = await S.initX3DH();
1113
- k.send({ type: "uploadPrekeys", ...s });
1114
- const m = await S.begin();
1115
- k.send({ type: "pubkey", conversationId: a, key: m });
1116
+ C.send({ type: "uploadPrekeys", ...s });
1117
+ const b = await S.begin();
1118
+ C.send({ type: "pubkey", conversationId: i, key: b });
1116
1119
  }
1117
- $.render(p);
1120
+ A.render(h);
1118
1121
  })();
1119
1122
  }
1120
- }), k.connect(), $.render(p);
1121
- const F = t.launcher ? ke(t) : null, V = { close: () => {
1122
- c = !0, clearTimeout(l), k.close(), r == null || r.remove(), $.destroy(), I && M && I.removeEventListener("change", M), j && (document.removeEventListener("keydown", j), j = null), _.delete(t.el), F && Z.get(F) === V && Z.delete(F);
1123
+ }), C.connect(), A.render(h);
1124
+ const W = t.launcher ? ke(t) : null, Y = { close: () => {
1125
+ c = !0, clearTimeout(l), C.close(), r == null || r.remove(), A.destroy(), z && I && z.removeEventListener("change", I), M && (document.removeEventListener("keydown", M), M = null), U.delete(t.el), W && ee.get(W) === Y && ee.delete(W);
1123
1126
  } };
1124
- return _.set(t.el, V), F && Z.set(F, V), V;
1127
+ return U.set(t.el, Y), W && ee.set(W, Y), Y;
1125
1128
  }
1126
1129
  export {
1127
1130
  Oe as ChatStore,