@osvi-ai/chat 0.1.0 → 0.1.1
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/core.js +1 -1
- package/dist/{index-BsRyQwUM.js → index-HWHyM4-l.js} +9 -9
- package/dist/index-HWHyM4-l.js.map +1 -0
- package/dist/types/core/client.d.ts +3 -1
- package/dist/types/ui/icons.d.ts +9 -0
- package/dist/types/ui/osvi-chat.d.ts +1 -0
- package/dist/types/widget/config.d.ts +1 -0
- package/dist/ui.js +103 -43
- package/dist/ui.js.map +1 -1
- package/dist/ui.mjs +363 -287
- package/dist/ui.mjs.map +1 -1
- package/dist/widget.js +129 -56
- package/dist/widget.js.map +1 -1
- package/package.json +2 -2
- package/dist/index-BsRyQwUM.js.map +0 -1
package/dist/ui.mjs
CHANGED
|
@@ -1,30 +1,32 @@
|
|
|
1
|
-
import { nothing as
|
|
2
|
-
import { property as l, state as
|
|
3
|
-
import { c as
|
|
4
|
-
import { repeat as
|
|
5
|
-
import { live as
|
|
6
|
-
const
|
|
7
|
-
function
|
|
8
|
-
const t = { ...i?.mode === "dark" ?
|
|
9
|
-
|
|
10
|
-
const
|
|
11
|
-
|
|
1
|
+
import { nothing as c, html as a, svg as b, LitElement as W, css as X, unsafeCSS as nt } from "lit";
|
|
2
|
+
import { property as l, state as v } from "lit/decorators.js";
|
|
3
|
+
import { c as at, i as ot, a as lt, b as B } from "./index-HWHyM4-l.js";
|
|
4
|
+
import { repeat as dt } from "lit/directives/repeat.js";
|
|
5
|
+
import { live as ct } from "lit/directives/live.js";
|
|
6
|
+
const Z = { primary: "#4f46e5", background: "#ffffff", surface: "#f4f4f5", text: "#18181b", userBubble: "#4f46e5", assistantBubble: "#f4f4f5" }, pt = { primary: "#6366f1", background: "#0a0a12", surface: "#1c1c27", text: "#f4f4f5", userBubble: "#6366f1", assistantBubble: "#1f1f2b" }, ht = { none: "0px", sm: "6px", md: "10px", lg: "16px", full: "9999px" }, C = { primary: "--osvi-color-primary", background: "--osvi-color-background", surface: "--osvi-color-surface", text: "--osvi-color-text", userBubble: "--osvi-color-user-bubble", assistantBubble: "--osvi-color-assistant-bubble" }, ut = (i) => `var(${C[i]}, ${Z[i]})`;
|
|
7
|
+
function E(i) {
|
|
8
|
+
const t = { ...i?.mode === "dark" ? pt : Z, ...i?.colors };
|
|
9
|
+
!i?.colors?.userBubble && i?.colors?.primary && (t.userBubble = i.colors.primary);
|
|
10
|
+
const e = {};
|
|
11
|
+
for (const s of Object.keys(C)) e[C[s]] = t[s];
|
|
12
|
+
const r = i?.radius ?? "md";
|
|
13
|
+
return e["--osvi-radius"] = typeof r == "number" ? `${r}px` : ht[r], e;
|
|
12
14
|
}
|
|
13
|
-
function
|
|
15
|
+
function bt(i) {
|
|
14
16
|
if (!i) return {};
|
|
15
|
-
if (i.mode) return
|
|
16
|
-
const t =
|
|
17
|
-
for (const
|
|
17
|
+
if (i.mode) return E(i);
|
|
18
|
+
const t = E(i), e = {};
|
|
19
|
+
for (const r of Object.keys(i.colors ?? {})) e[C[r]] = t[C[r]];
|
|
18
20
|
return i.radius !== void 0 && (e["--osvi-radius"] = t["--osvi-radius"]), e;
|
|
19
21
|
}
|
|
20
|
-
const
|
|
21
|
-
function
|
|
22
|
-
for (const
|
|
23
|
-
const e =
|
|
24
|
-
for (const [
|
|
25
|
-
|
|
22
|
+
const O = /* @__PURE__ */ new WeakMap();
|
|
23
|
+
function Q(i, t) {
|
|
24
|
+
for (const r of O.get(i) ?? []) i.style.removeProperty(r);
|
|
25
|
+
const e = bt(t);
|
|
26
|
+
for (const [r, s] of Object.entries(e)) i.style.setProperty(r, s);
|
|
27
|
+
O.set(i, Object.keys(e));
|
|
26
28
|
}
|
|
27
|
-
const
|
|
29
|
+
const H = {
|
|
28
30
|
placeholder: "Type your message…",
|
|
29
31
|
send: "Send",
|
|
30
32
|
typing: "Typing…",
|
|
@@ -43,32 +45,32 @@ const N = {
|
|
|
43
45
|
rateLimited: "Too many requests. Please try again in a few minutes.",
|
|
44
46
|
tryAgain: "Try again",
|
|
45
47
|
closeChat: "Close chat",
|
|
46
|
-
poweredBy: "Powered by
|
|
48
|
+
poweredBy: "Powered by Osvi AI",
|
|
47
49
|
newChat: "New chat",
|
|
48
50
|
emptyState: "Send a message to start chatting.",
|
|
49
51
|
defaultTitle: "Chat"
|
|
50
|
-
},
|
|
51
|
-
function
|
|
52
|
-
|
|
52
|
+
}, N = /* @__PURE__ */ new Set();
|
|
53
|
+
function tt(i, t) {
|
|
54
|
+
N.has(i) || (N.add(i), console.warn(`[osvi-chat] ${t}`));
|
|
53
55
|
}
|
|
54
|
-
function
|
|
56
|
+
function x(i, t) {
|
|
55
57
|
return i != null && t.includes(i) ? i : void 0;
|
|
56
58
|
}
|
|
57
59
|
function K(i) {
|
|
58
60
|
if (i != null)
|
|
59
|
-
return
|
|
61
|
+
return x(i, ["none", "sm", "md", "lg", "full"]) ?? (/^\d{1,2}(?:px)?$/.test(i) ? Number(i.replace(/px$/, "")) : void 0);
|
|
60
62
|
}
|
|
61
|
-
function
|
|
63
|
+
function V(i) {
|
|
62
64
|
if (i) {
|
|
63
65
|
try {
|
|
64
66
|
const t = new URL(i);
|
|
65
67
|
if (!t.username && !t.password && (t.protocol === "https:" || t.protocol === "http:" && ["localhost", "127.0.0.1"].includes(t.hostname))) return i.replace(/\/+$/, "");
|
|
66
68
|
} catch {
|
|
67
69
|
}
|
|
68
|
-
|
|
70
|
+
tt("base-url", "ignored an invalid base-url (https required, http only for localhost)");
|
|
69
71
|
}
|
|
70
72
|
}
|
|
71
|
-
function
|
|
73
|
+
function ft(i) {
|
|
72
74
|
if (i) {
|
|
73
75
|
if (/^data:image\/(png|jpeg|gif|webp);base64,[a-z0-9+/]+={0,2}$/i.test(i)) return i;
|
|
74
76
|
try {
|
|
@@ -85,11 +87,11 @@ function J(i, t) {
|
|
|
85
87
|
if (e && typeof e == "object" && !Array.isArray(e)) return e;
|
|
86
88
|
} catch {
|
|
87
89
|
}
|
|
88
|
-
|
|
90
|
+
tt(i, `ignored invalid JSON in the ${i} attribute`);
|
|
89
91
|
}
|
|
90
92
|
}
|
|
91
|
-
const
|
|
92
|
-
function
|
|
93
|
+
const gt = /https?:\/\/[^\s<>"']+/g, S = (i, t) => i.split(t).length - 1;
|
|
94
|
+
function vt(i) {
|
|
93
95
|
for (; ; ) {
|
|
94
96
|
const t = i[i.length - 1];
|
|
95
97
|
if (t && ".,!?;:".includes(t) || t === ")" && S(i, ")") > S(i, "(") || t === "]" && S(i, "]") > S(i, "[")) {
|
|
@@ -99,65 +101,76 @@ function ht(i) {
|
|
|
99
101
|
return i;
|
|
100
102
|
}
|
|
101
103
|
}
|
|
102
|
-
function
|
|
104
|
+
function mt(i) {
|
|
103
105
|
const t = [];
|
|
104
106
|
let e = 0;
|
|
105
|
-
for (const
|
|
106
|
-
const
|
|
107
|
+
for (const r of i.matchAll(gt)) {
|
|
108
|
+
const s = vt(r[0]), n = r.index;
|
|
107
109
|
try {
|
|
108
|
-
const o = new URL(
|
|
110
|
+
const o = new URL(s);
|
|
109
111
|
if (!["http:", "https:"].includes(o.protocol)) continue;
|
|
110
112
|
} catch {
|
|
111
113
|
continue;
|
|
112
114
|
}
|
|
113
|
-
|
|
115
|
+
n > e && t.push({ text: i.slice(e, n) }), t.push({ href: s, text: s }), e = n + s.length;
|
|
114
116
|
}
|
|
115
117
|
return e < i.length && t.push({ text: i.slice(e) }), t.length ? t : [{ text: i }];
|
|
116
118
|
}
|
|
117
|
-
function
|
|
118
|
-
return a`${i.items.length ?
|
|
119
|
-
if (
|
|
120
|
-
if (
|
|
121
|
-
const o =
|
|
119
|
+
function yt(i, t, e, r, s) {
|
|
120
|
+
return a`${i.items.length ? dt(i.items, (n) => n.id, (n) => {
|
|
121
|
+
if (n.kind === "divider") return a`<p class="divider">${t.sessionEnded}</p>`;
|
|
122
|
+
if (n.kind === "message") return a`<article class=${`bubble ${n.role}`}>${n.role === "human" ? a`<small class="team">Team</small>` : c}<p>${mt(n.content).map((k) => "href" in k ? a`<a href=${k.href} target="_blank" rel="noopener noreferrer">${k.text}</a>` : k.text)}</p>${n.role === "user" && n.status === "failed" ? a`<span class="failed"><span>${t.sendFailed}</span><button type="button" @click=${() => s(n.id)}>${t.retry}</button></span>` : c}</article>`;
|
|
123
|
+
const o = n.interaction, h = o.interaction_id === i.activeInteraction?.interaction_id && o.interaction_status === "pending", f = !h || i.interactionPending || i.mode === "human";
|
|
122
124
|
switch (o.tool_type) {
|
|
123
125
|
case "ui_buttons":
|
|
124
|
-
return a`<osvi-buttons data-live=${
|
|
126
|
+
return a`<osvi-buttons data-live=${h ? "true" : "false"} .interaction=${o} .disabled=${f} .variant=${e.buttons ?? "chips"} base-url=${r}></osvi-buttons>`;
|
|
125
127
|
case "ui_carousel":
|
|
126
|
-
return a`<osvi-carousel data-live=${
|
|
128
|
+
return a`<osvi-carousel data-live=${h ? "true" : "false"} .interaction=${o} .disabled=${f} .variant=${e.carousel ?? "slider"} base-url=${r}></osvi-carousel>`;
|
|
127
129
|
case "ui_date_picker":
|
|
128
|
-
return a`<osvi-date-picker data-live=${
|
|
130
|
+
return a`<osvi-date-picker data-live=${h ? "true" : "false"} .interaction=${o} .disabled=${f} base-url=${r}></osvi-date-picker>`;
|
|
129
131
|
default:
|
|
130
132
|
return a`<p>${o.content}</p>`;
|
|
131
133
|
}
|
|
132
|
-
}) : a`<p>${t.emptyState}</p>`}${i.awaitingReply ? a`<
|
|
134
|
+
}) : a`<p class="empty">${t.emptyState}</p>`}${i.awaitingReply ? a`<div class="typing" role="img" aria-label=${t.typing}><i></i><i></i><i></i></div>` : c}`;
|
|
133
135
|
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
+
const m = (i, t = "") => b`<svg class=${t} viewBox="0 0 24 24" aria-hidden="true" focusable="false" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">${i}</svg>`;
|
|
137
|
+
m(b`<path d="M4 5.5A2.5 2.5 0 0 1 6.5 3h11A2.5 2.5 0 0 1 20 5.5v8a2.5 2.5 0 0 1-2.5 2.5H10l-4.2 3.6c-.5.4-1.3.1-1.3-.6V16A2.5 2.5 0 0 1 4 13.5z"/><path d="M8.5 8.5h7M8.5 11.5h4"/>`);
|
|
138
|
+
const xt = m(b`<path d="M4 5.5A2.5 2.5 0 0 1 6.5 3h11A2.5 2.5 0 0 1 20 5.5v8a2.5 2.5 0 0 1-2.5 2.5H10l-4.2 3.6c-.5.4-1.3.1-1.3-.6V16A2.5 2.5 0 0 1 4 13.5z"/><path d="M12 6.5v6M9 9.5h6"/>`), $t = m(b`<path d="M6 6l12 12M18 6L6 18"/>`);
|
|
139
|
+
m(b`<path d="M4 5.5A2.5 2.5 0 0 1 6.5 3h11A2.5 2.5 0 0 1 20 5.5v8a2.5 2.5 0 0 1-2.5 2.5H10l-4.2 3.6c-.5.4-1.3.1-1.3-.6V16A2.5 2.5 0 0 1 4 13.5z"/><path d="M8.5 8.5h7M8.5 11.5h4"/>`, "chat");
|
|
140
|
+
m(b`<path d="M6 6l12 12M18 6L6 18"/>`, "close");
|
|
141
|
+
const wt = m(b`<path d="M12 19V5M5.5 11.5L12 5l6.5 6.5"/>`), et = m(b`<path d="M15 6l-6 6 6 6"/>`), R = m(b`<path d="M9 6l6 6-6 6"/>`), kt = b`<svg viewBox="0 0 134 134" aria-hidden="true" focusable="false"><defs><linearGradient id="osvi-g" x1="-36.28" y1="32.2" x2="161.98" y2="93.64" gradientUnits="userSpaceOnUse"><stop offset=".304" stop-color="#155DFC"/><stop offset=".822" stop-color="#353333"/></linearGradient><mask id="osvi-m" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="-7" y="-6" width="149" height="150"><path fill-rule="evenodd" clip-rule="evenodd" fill="#0F0F0F" d="M141.385 114.008L141.622 108.411V29.4704L141.385 23.8743C139.964 7.44314 126.224 -5.41602 109.523 -5.41602H25.3094C8.60869 -5.41602 -5.13083 7.44314 -6.55216 23.8743L-6.78906 29.4704V108.411L-6.55216 114.008C-5.13083 130.439 8.60869 143.298 25.3094 143.298H109.523C126.224 143.298 139.964 130.439 141.385 114.008ZM25.3094 102.339C9.55625 102.339 65.7059 83.8874 53.6176 66.6191C42.3654 50.5452 93.7703 32.6852 109.523 32.6852C125.277 32.6852 73.161 54.1172 81.4521 80.9071C86.1899 96.2156 40.944 102.339 25.3094 102.339Z"/></mask></defs><g mask="url(#osvi-m)"><ellipse cx="66.88" cy="66.79" rx="67.22" ry="66.81" fill="url(#osvi-g)"/></g></svg>`;
|
|
142
|
+
function _t(i) {
|
|
143
|
+
return a`<div class="composer"><textarea rows="1" aria-label="Message" placeholder=${i.placeholder} .value=${ct(i.draft)} ?disabled=${i.disabled} @input=${(t) => {
|
|
144
|
+
const e = t.target;
|
|
145
|
+
e.style.height = "auto", e.style.height = `${Math.min(e.scrollHeight, 120)}px`, i.input(t);
|
|
146
|
+
}} @keydown=${(t) => {
|
|
136
147
|
t.key === "Enter" && !t.shiftKey && !t.isComposing && !i.disabled && (t.preventDefault(), i.send());
|
|
137
|
-
}}></textarea><button type="button" aria-label=${i.strings.send} ?disabled=${i.disabled || !i.draft.trim()} @click=${i.send}>${i.strings.send}</button></div>`;
|
|
148
|
+
}}></textarea><button type="button" class="send" title=${i.strings.send} aria-label=${i.strings.send} ?disabled=${i.disabled || !i.draft.trim()} @click=${i.send}>${wt}<span class="sr">${i.strings.send}</span></button></div>`;
|
|
138
149
|
}
|
|
139
|
-
var
|
|
140
|
-
for (var
|
|
141
|
-
(o = i[
|
|
142
|
-
return
|
|
150
|
+
var Ct = Object.defineProperty, p = (i, t, e, r) => {
|
|
151
|
+
for (var s = void 0, n = i.length - 1, o; n >= 0; n--)
|
|
152
|
+
(o = i[n]) && (s = o(t, e, s) || s);
|
|
153
|
+
return s && Ct(t, e, s), s;
|
|
143
154
|
};
|
|
144
|
-
const
|
|
145
|
-
var
|
|
146
|
-
const
|
|
155
|
+
const G = () => ({ status: "idle", mode: "ai", awaitingReply: !1, items: [], activeInteraction: null, interactionPending: !1, agent: null, error: null }), it = { fromAttribute: (i) => i !== "false" };
|
|
156
|
+
var g;
|
|
157
|
+
const d = (g = class extends W {
|
|
147
158
|
constructor() {
|
|
148
|
-
super(...arguments), this.agentId = "", this.baseUrl = "", this.client = null, this.theme = {}, this.variants = {}, this.strings = {}, this.poweredBy = !0, this.newChat = !0, this.header = {}, this.closable = !1, this.chatState =
|
|
159
|
+
super(...arguments), this.agentId = "", this.baseUrl = "", this.client = null, this.theme = {}, this.variants = {}, this.strings = {}, this.poweredBy = !0, this.newChat = !0, this.header = {}, this.closable = !1, this.chatState = G(), this.draft = "", this.busy = !1, this.typed = null, this.ownClient = null, this.boundClient = null, this.ownKey = "", this.generation = 0, this.followBottom = !0, this.focusedInteraction = null, this.send = () => {
|
|
149
160
|
if (this.blocked || !this.draft.trim() || !this.boundClient) return;
|
|
150
|
-
const t = this.boundClient, e = this.draft.trim(),
|
|
151
|
-
this.draft = "",
|
|
161
|
+
const t = this.boundClient, e = this.draft.trim(), r = this.typed;
|
|
162
|
+
this.draft = "", r && this.restoreDraft(), this.requestUpdate();
|
|
163
|
+
const s = this.renderRoot.querySelector("textarea");
|
|
164
|
+
s && (s.style.height = ""), this.run(() => r ? t.respond(r.id, { kind: "text", value: e }) : t.send(e));
|
|
152
165
|
}, this.respond = (t) => {
|
|
153
|
-
const e = t.detail,
|
|
154
|
-
if (!e || this.busy ||
|
|
166
|
+
const e = t.detail, r = this.chatState;
|
|
167
|
+
if (!e || this.busy || r.mode !== "ai" || r.interactionPending || r.activeInteraction?.interaction_status !== "pending" || e.interactionId !== r.activeInteraction.interaction_id) return;
|
|
155
168
|
t.stopPropagation();
|
|
156
|
-
const
|
|
157
|
-
|
|
169
|
+
const s = this.boundClient;
|
|
170
|
+
s && this.run(() => s.respond(e.interactionId, e.response));
|
|
158
171
|
}, this.requestInput = (t) => {
|
|
159
|
-
const e = t.detail,
|
|
160
|
-
!e || this.busy ||
|
|
172
|
+
const e = t.detail, r = this.chatState;
|
|
173
|
+
!e || this.busy || r.mode !== "ai" || r.interactionPending || r.activeInteraction?.interaction_status !== "pending" || e.interactionId !== r.activeInteraction.interaction_id || (t.stopPropagation(), this.typed = { id: e.interactionId, placeholder: typeof e.placeholder == "string" ? e.placeholder : void 0, previousDraft: this.typed?.previousDraft ?? this.draft }, this.draft = "", this.requestUpdate(), this.updateComplete.then(() => this.renderRoot.querySelector("textarea")?.focus()));
|
|
161
174
|
};
|
|
162
175
|
}
|
|
163
176
|
connectedCallback() {
|
|
@@ -173,33 +186,33 @@ const c = (f = class extends W {
|
|
|
173
186
|
}
|
|
174
187
|
syncClient() {
|
|
175
188
|
if (!this.isConnected || !this.client && !this.agentId && !this.boundClient) return;
|
|
176
|
-
const t = JSON.stringify([this.agentId,
|
|
177
|
-
if ((this.client ? this.boundClient === this.client && !this.ownClient : this.ownClient && t === this.ownKey) || (this.releaseClient(), this.chatState =
|
|
178
|
-
const e = !this.client,
|
|
179
|
-
this.boundClient =
|
|
180
|
-
const
|
|
181
|
-
this.chatState =
|
|
182
|
-
this.generation !==
|
|
183
|
-
}), e && this.run(() =>
|
|
189
|
+
const t = JSON.stringify([this.agentId, V(this.baseUrl)]);
|
|
190
|
+
if ((this.client ? this.boundClient === this.client && !this.ownClient : this.ownClient && t === this.ownKey) || (this.releaseClient(), this.chatState = G(), !this.client && !this.agentId)) return;
|
|
191
|
+
const e = !this.client, r = this.client ?? g.clientFactory({ agentId: this.agentId, baseUrl: V(this.baseUrl) });
|
|
192
|
+
this.boundClient = r, e && (this.ownClient = r, this.ownKey = t);
|
|
193
|
+
const s = this.generation;
|
|
194
|
+
this.chatState = r.getState(), this.requestUpdate(), this.unsubscribe = r.subscribe((n) => {
|
|
195
|
+
this.generation !== s || this.boundClient !== r || (this.chatState = n, this.requestUpdate(), this.typed && (n.mode === "human" || n.activeInteraction?.interaction_id !== this.typed.id || n.activeInteraction.interaction_status !== "pending") && this.restoreDraft());
|
|
196
|
+
}), e && this.run(() => r.start());
|
|
184
197
|
}
|
|
185
198
|
willUpdate() {
|
|
186
|
-
this.syncClient(),
|
|
199
|
+
this.syncClient(), Q(this, this.mergedTheme());
|
|
187
200
|
}
|
|
188
201
|
mergedTheme() {
|
|
189
|
-
const t = J("theme", this.themeAttribute), e = {},
|
|
190
|
-
if (
|
|
202
|
+
const t = J("theme", this.themeAttribute), e = {}, r = t?.colors;
|
|
203
|
+
if (r && typeof r == "object" && !Array.isArray(r))
|
|
191
204
|
for (const o of ["primary", "background", "surface", "text", "userBubble", "assistantBubble"]) {
|
|
192
|
-
const
|
|
193
|
-
typeof
|
|
205
|
+
const h = r[o];
|
|
206
|
+
typeof h == "string" && (e[o] = h);
|
|
194
207
|
}
|
|
195
208
|
typeof this.primaryColor == "string" && (e.primary = this.primaryColor);
|
|
196
|
-
const
|
|
197
|
-
return { ...this.theme, colors: { ...this.theme?.colors, ...e }, ...
|
|
209
|
+
const s = K(this.radius) ?? (typeof t?.radius == "number" && Number.isInteger(t.radius) && t.radius >= 0 && t.radius <= 99 ? t.radius : typeof t?.radius == "string" ? K(t.radius) : void 0), n = x(this.mode, ["light", "dark"]) ?? x(typeof t?.mode == "string" ? t.mode : void 0, ["light", "dark"]);
|
|
210
|
+
return { ...this.theme, colors: { ...this.theme?.colors, ...e }, ...s === void 0 ? {} : { radius: s }, ...n === void 0 ? {} : { mode: n } };
|
|
198
211
|
}
|
|
199
212
|
get labels() {
|
|
200
|
-
const t = { ...
|
|
213
|
+
const t = { ...H };
|
|
201
214
|
for (const e of [this.strings, J("strings", this.stringsAttribute)])
|
|
202
|
-
for (const
|
|
215
|
+
for (const r of Object.keys(H)) typeof e?.[r] == "string" && (t[r] = e[r]);
|
|
203
216
|
return t;
|
|
204
217
|
}
|
|
205
218
|
get blocked() {
|
|
@@ -241,121 +254,184 @@ const c = (f = class extends W {
|
|
|
241
254
|
return e.error?.code === "origin_not_allowed" ? t.originBlocked : e.error && ["agent_inactive", "agent_archived", "agent_not_found"].includes(e.error.code) ? t.unavailable : e.error?.code === "rate_limited" ? t.rateLimited : e.error?.code === "token_failed" ? e.error.message : e.status === "recovering" ? t.reconnecting : e.status === "offline" ? t.offline : e.interactionPending || this.busy && this.typed ? t.sending : e.activeInteraction?.interaction_status === "pending" ? e.mode === "human" ? t.pausedForHuman : this.typed ? t.typeAnswer : t.chooseOption : e.status === "closed" ? t.sessionEnded : "";
|
|
242
255
|
}
|
|
243
256
|
render() {
|
|
244
|
-
const t = this.labels, e = this.chatState,
|
|
245
|
-
return a`<header>${
|
|
246
|
-
${this.newChat ? a`<button type="button" ?disabled=${!
|
|
247
|
-
${this.closable ? a`<button type="button" aria-label=${t.closeChat} @click=${() => this.dispatchEvent(new CustomEvent("osvi-close", { bubbles: !0, composed: !0 }))}
|
|
248
|
-
<div class="transcript" role="log" aria-live="polite" aria-label="Conversation" @scroll=${(
|
|
249
|
-
const
|
|
250
|
-
this.followBottom =
|
|
251
|
-
}} @osvi-respond=${this.respond} @osvi-request-input=${this.requestInput}>${
|
|
252
|
-
|
|
257
|
+
const t = this.labels, e = this.chatState, r = this.boundClient, s = ft(this.headerAvatar ?? this.header.avatarUrl), n = { ...this.variants, ...x(this.buttons, ["chips", "list"]) ? { buttons: x(this.buttons, ["chips", "list"]) } : {}, ...x(this.carousel, ["slider", "list"]) ? { carousel: x(this.carousel, ["slider", "list"]) } : {} }, o = this.headerTitle ?? this.header.title ?? e.agent?.name ?? t.defaultTitle;
|
|
258
|
+
return a`<header>${s ? a`<img class="avatar" src=${s} alt="" referrerpolicy="no-referrer">` : a`<span class="avatar" aria-hidden="true">${o.trim().charAt(0).toUpperCase()}</span>`}<div class="heading"><h2>${o}</h2>${this.headerSubtitle ?? this.header.subtitle ? a`<p>${this.headerSubtitle ?? this.header.subtitle}</p>` : c}${e.mode === "human" ? a`<small>${t.humanJoined}</small>` : c}</div>
|
|
259
|
+
${this.newChat ? a`<button type="button" class="icon" title=${t.newChat} ?disabled=${!r || this.sessionBusy} @click=${() => r && !this.sessionBusy && void this.run(() => r.newSession({ keepHistory: this.newChatHistory === "keep" }))}>${xt}<span class="sr">${t.newChat}</span></button>` : c}
|
|
260
|
+
${this.closable ? a`<button type="button" class="icon" title=${t.closeChat} aria-label=${t.closeChat} @click=${() => this.dispatchEvent(new CustomEvent("osvi-close", { bubbles: !0, composed: !0 }))}>${$t}</button>` : c}</header>
|
|
261
|
+
<div class="transcript" role="log" aria-live="polite" aria-label="Conversation" @scroll=${(h) => {
|
|
262
|
+
const f = h.currentTarget;
|
|
263
|
+
this.followBottom = f.scrollHeight - f.scrollTop - f.clientHeight <= 80;
|
|
264
|
+
}} @osvi-respond=${this.respond} @osvi-request-input=${this.requestInput}>${yt(e, t, n, r?.resolveUrl("") ?? "", (h) => {
|
|
265
|
+
r && this.run(() => r.retry(h));
|
|
253
266
|
})}</div>
|
|
254
|
-
<div class="status" role="status">${this.statusText(t)}${e.error?.retryable && (e.status === "idle" || e.status === "closed") ? a`<button type="button" ?disabled=${this.busy || !
|
|
255
|
-
${
|
|
256
|
-
this.draft =
|
|
267
|
+
<div class="status" role="status">${this.statusText(t)}${e.error?.retryable && (e.status === "idle" || e.status === "closed") ? a`<button type="button" ?disabled=${this.busy || !r} @click=${() => r && void this.run(() => r.start())}>${t.tryAgain}</button>` : c}</div>
|
|
268
|
+
${_t({ strings: t, draft: this.draft, placeholder: this.typed?.placeholder ?? t.placeholder, disabled: this.blocked, input: (h) => {
|
|
269
|
+
this.draft = h.target.value, this.requestUpdate();
|
|
257
270
|
}, send: this.send })}
|
|
258
|
-
${this.poweredBy ? a`<footer><a href="https://osvi.ai" target="_blank" rel="noopener noreferrer">${t.poweredBy}</a></footer>` :
|
|
259
|
-
}
|
|
260
|
-
},
|
|
261
|
-
:host {
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
271
|
+
${this.poweredBy ? a`<footer><a href="https://osvi.ai" target="_blank" rel="noopener noreferrer">${kt}<span>${t.poweredBy}</span></a></footer>` : c}`;
|
|
272
|
+
}
|
|
273
|
+
}, g.clientFactory = at, g.properties = { themeAttribute: { attribute: "theme" }, stringsAttribute: { attribute: "strings" } }, g.styles = X`
|
|
274
|
+
:host { --p:var(--osvi-color-primary,#4f46e5); --bg:var(--osvi-color-background,#fff); --surface:var(--osvi-color-surface,#f4f4f5); --text:var(--osvi-color-text,#18181b);
|
|
275
|
+
--ub:var(--osvi-color-user-bubble,var(--p)); --ab:var(--osvi-color-assistant-bubble,var(--surface)); --r:var(--osvi-radius,14px);
|
|
276
|
+
--sub:color-mix(in srgb,var(--text) 58%,var(--bg)); --line:color-mix(in srgb,var(--text) 11%,var(--bg));
|
|
277
|
+
display:flex; flex-direction:column; height:100%; min-height:260px; color:var(--text); background:var(--bg); font-family:inherit; font-size:14px; line-height:1.5; border-radius:var(--r); overflow:hidden; }
|
|
278
|
+
* { box-sizing:border-box; } h2,p { margin:0; }
|
|
279
|
+
button,textarea { font:inherit; color:inherit; } button { cursor:pointer; } button:disabled { cursor:default; opacity:.45; }
|
|
280
|
+
button:focus-visible,textarea:focus-visible,a:focus-visible { outline:3px solid color-mix(in srgb,var(--p) 55%,transparent); outline-offset:2px; }
|
|
281
|
+
.sr { position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; }
|
|
282
|
+
header { display:flex; align-items:center; gap:12px; padding:14px 12px 14px 16px; border-bottom:1px solid var(--line); }
|
|
283
|
+
.avatar { width:38px; height:38px; border-radius:50%; flex:none; object-fit:cover; display:grid; place-items:center; background:var(--p); color:#fff; font-weight:700; font-size:15px; }
|
|
284
|
+
.heading { flex:1; min-width:0; } h2 { font-size:15px; line-height:1.3; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
|
|
285
|
+
.heading p,.heading small { display:block; font-size:12.5px; color:var(--sub); }
|
|
286
|
+
.heading small { color:var(--p); font-weight:600; }
|
|
287
|
+
.icon { width:34px; height:34px; border:0; border-radius:10px; background:transparent; color:var(--sub); display:grid; place-items:center; flex:none; }
|
|
288
|
+
.icon:hover:not(:disabled) { background:var(--surface); color:var(--text); } .icon svg { width:18px; height:18px; }
|
|
289
|
+
.transcript { flex:1; overflow:auto; padding:18px 16px; min-height:0; display:flex; flex-direction:column; gap:10px; }
|
|
290
|
+
.empty { margin:auto; color:var(--sub); text-align:center; }
|
|
291
|
+
.bubble { width:fit-content; max-width:84%; padding:10px 14px; border-radius:var(--r); border-bottom-left-radius:6px; background:var(--ab); overflow-wrap:anywhere; white-space:pre-wrap; }
|
|
292
|
+
.bubble.user { align-self:flex-end; color:#fff; background:var(--ub); border-bottom-left-radius:var(--r); border-bottom-right-radius:6px; }
|
|
293
|
+
.bubble a { color:inherit; } .team { display:block; font-size:11px; font-weight:600; color:var(--p); margin-bottom:2px; }
|
|
294
|
+
.failed { display:flex; align-items:center; gap:8px; font-size:12px; margin-top:6px; } .failed button { border:0; background:rgb(255 255 255/.2); border-radius:8px; padding:2px 8px; }
|
|
295
|
+
.divider { display:flex; align-items:center; gap:10px; color:var(--sub); font-size:12px; } .divider::before,.divider::after { content:""; flex:1; height:1px; background:var(--line); }
|
|
296
|
+
.typing { display:inline-flex; gap:4px; padding:12px 14px; background:var(--ab); border-radius:var(--r); border-bottom-left-radius:6px; width:fit-content; }
|
|
297
|
+
.typing i { width:6px; height:6px; border-radius:50%; background:var(--sub); animation:osvi-dot 1.2s infinite; } .typing i:nth-child(2) { animation-delay:.15s; } .typing i:nth-child(3) { animation-delay:.3s; }
|
|
298
|
+
@keyframes osvi-dot { 0%,60%,100% { opacity:.35; transform:none; } 30% { opacity:1; transform:translateY(-3px); } }
|
|
299
|
+
osvi-buttons,osvi-carousel,osvi-date-picker { display:block; max-width:100%; }
|
|
300
|
+
.status { padding:0 16px; font-size:12.5px; color:var(--sub); display:flex; gap:8px; align-items:center; } .status:empty { display:none; }
|
|
301
|
+
.status button { border:1px solid var(--line); background:var(--bg); border-radius:8px; padding:3px 10px; }
|
|
302
|
+
.composer { margin:10px 12px; display:flex; align-items:flex-end; gap:8px; border:1px solid var(--line); border-radius:18px; padding:6px 6px 6px 14px; background:var(--surface); }
|
|
303
|
+
.composer:focus-within { border-color:var(--p); box-shadow:0 0 0 3px color-mix(in srgb,var(--p) 18%,transparent); }
|
|
304
|
+
textarea { flex:1; min-width:0; border:0; outline:0; background:transparent; resize:none; min-height:24px; max-height:120px; padding:6px 0; field-sizing:content; }
|
|
305
|
+
textarea::placeholder { color:var(--sub); } textarea:focus-visible { outline:0; }
|
|
306
|
+
.send { width:36px; height:36px; border:0; border-radius:50%; background:var(--p); color:#fff; display:grid; place-items:center; flex:none; } .send svg { width:17px; height:17px; }
|
|
307
|
+
footer { padding:0 16px 12px; text-align:center; font-size:11.5px; } footer a { color:var(--sub); text-decoration:none; display:inline-flex; align-items:center; gap:6px; }
|
|
308
|
+
footer a:hover { color:var(--text); } footer svg { width:14px; height:14px; flex:none; }
|
|
309
|
+
@media (prefers-reduced-motion:reduce) { .typing i { animation:none; } }
|
|
310
|
+
`, g);
|
|
311
|
+
p([
|
|
266
312
|
l({ attribute: "agent-id" })
|
|
267
|
-
],
|
|
268
|
-
|
|
313
|
+
], d.prototype, "agentId");
|
|
314
|
+
p([
|
|
269
315
|
l({ attribute: "base-url" })
|
|
270
|
-
],
|
|
271
|
-
|
|
316
|
+
], d.prototype, "baseUrl");
|
|
317
|
+
p([
|
|
272
318
|
l({ attribute: !1 })
|
|
273
|
-
],
|
|
274
|
-
|
|
319
|
+
], d.prototype, "client");
|
|
320
|
+
p([
|
|
275
321
|
l({ attribute: !1 })
|
|
276
|
-
],
|
|
277
|
-
|
|
322
|
+
], d.prototype, "theme");
|
|
323
|
+
p([
|
|
278
324
|
l({ attribute: !1 })
|
|
279
|
-
],
|
|
280
|
-
|
|
325
|
+
], d.prototype, "variants");
|
|
326
|
+
p([
|
|
281
327
|
l({ attribute: !1 })
|
|
282
|
-
],
|
|
283
|
-
|
|
284
|
-
l({ attribute: "powered-by", converter:
|
|
285
|
-
],
|
|
286
|
-
|
|
287
|
-
l({ attribute: "new-chat", converter:
|
|
288
|
-
],
|
|
289
|
-
|
|
328
|
+
], d.prototype, "strings");
|
|
329
|
+
p([
|
|
330
|
+
l({ attribute: "powered-by", converter: it })
|
|
331
|
+
], d.prototype, "poweredBy");
|
|
332
|
+
p([
|
|
333
|
+
l({ attribute: "new-chat", converter: it })
|
|
334
|
+
], d.prototype, "newChat");
|
|
335
|
+
p([
|
|
336
|
+
l({ attribute: "new-chat-history" })
|
|
337
|
+
], d.prototype, "newChatHistory");
|
|
338
|
+
p([
|
|
290
339
|
l({ attribute: !1 })
|
|
291
|
-
],
|
|
292
|
-
|
|
340
|
+
], d.prototype, "header");
|
|
341
|
+
p([
|
|
293
342
|
l({ type: Boolean })
|
|
294
|
-
],
|
|
295
|
-
|
|
343
|
+
], d.prototype, "closable");
|
|
344
|
+
p([
|
|
296
345
|
l({ attribute: "header-title" })
|
|
297
|
-
],
|
|
298
|
-
|
|
346
|
+
], d.prototype, "headerTitle");
|
|
347
|
+
p([
|
|
299
348
|
l({ attribute: "header-subtitle" })
|
|
300
|
-
],
|
|
301
|
-
|
|
349
|
+
], d.prototype, "headerSubtitle");
|
|
350
|
+
p([
|
|
302
351
|
l({ attribute: "header-avatar" })
|
|
303
|
-
],
|
|
304
|
-
|
|
352
|
+
], d.prototype, "headerAvatar");
|
|
353
|
+
p([
|
|
305
354
|
l({ attribute: "primary-color" })
|
|
306
|
-
],
|
|
307
|
-
|
|
355
|
+
], d.prototype, "primaryColor");
|
|
356
|
+
p([
|
|
308
357
|
l()
|
|
309
|
-
],
|
|
310
|
-
|
|
358
|
+
], d.prototype, "radius");
|
|
359
|
+
p([
|
|
311
360
|
l()
|
|
312
|
-
],
|
|
313
|
-
|
|
361
|
+
], d.prototype, "mode");
|
|
362
|
+
p([
|
|
314
363
|
l()
|
|
315
|
-
],
|
|
316
|
-
|
|
364
|
+
], d.prototype, "buttons");
|
|
365
|
+
p([
|
|
317
366
|
l()
|
|
318
|
-
],
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
],
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
],
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
],
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
],
|
|
331
|
-
let
|
|
332
|
-
function
|
|
367
|
+
], d.prototype, "carousel");
|
|
368
|
+
p([
|
|
369
|
+
v()
|
|
370
|
+
], d.prototype, "chatState");
|
|
371
|
+
p([
|
|
372
|
+
v()
|
|
373
|
+
], d.prototype, "draft");
|
|
374
|
+
p([
|
|
375
|
+
v()
|
|
376
|
+
], d.prototype, "busy");
|
|
377
|
+
p([
|
|
378
|
+
v()
|
|
379
|
+
], d.prototype, "typed");
|
|
380
|
+
let St = d;
|
|
381
|
+
function U(i, t) {
|
|
333
382
|
typeof customElements > "u" || customElements.get(i) || customElements.define(i, t);
|
|
334
383
|
}
|
|
335
|
-
const
|
|
336
|
-
:host {
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
.
|
|
348
|
-
.
|
|
349
|
-
.
|
|
350
|
-
.
|
|
351
|
-
.
|
|
384
|
+
const I = (i) => nt(ut(i)), D = X`
|
|
385
|
+
:host { --p:${I("primary")}; --bg:${I("background")}; --surface:${I("surface")}; --text:${I("text")}; --r:var(--osvi-radius,14px);
|
|
386
|
+
--sub:color-mix(in srgb,var(--text) 58%,var(--bg)); --line:color-mix(in srgb,var(--text) 11%,var(--bg));
|
|
387
|
+
display:block; font:inherit; color:var(--text); }
|
|
388
|
+
* { box-sizing:border-box; }
|
|
389
|
+
p { margin:0 0 6px; } .label { font-weight:600; } .description { color:var(--sub); font-size:13px; }
|
|
390
|
+
.answer { display:inline-block; margin-top:2px; padding:4px 10px; border-radius:999px; background:color-mix(in srgb,var(--p) 12%,var(--bg)); color:var(--p); font-weight:600; font-size:13px; }
|
|
391
|
+
.sr { position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; }
|
|
392
|
+
button { font:inherit; color:inherit; cursor:pointer; }
|
|
393
|
+
button:focus-visible { outline:3px solid color-mix(in srgb,var(--p) 55%,transparent); outline-offset:2px; }
|
|
394
|
+
button:disabled { opacity:.45; cursor:default; }
|
|
395
|
+
small { display:block; color:var(--sub); font-size:12px; font-weight:400; }
|
|
396
|
+
.chips { display:flex; flex-wrap:wrap; gap:8px; }
|
|
397
|
+
.chips button { border:1.5px solid color-mix(in srgb,var(--p) 55%,var(--line)); background:var(--bg); color:var(--p); border-radius:999px; padding:7px 14px; font-weight:600; font-size:13px; text-align:center; }
|
|
398
|
+
.chips button:hover:not(:disabled) { background:color-mix(in srgb,var(--p) 10%,var(--bg)); }
|
|
399
|
+
.text { display:grid; gap:1px; min-width:0; }
|
|
400
|
+
.chips small { color:inherit; opacity:.8; }
|
|
401
|
+
.list { display:grid; gap:6px; }
|
|
402
|
+
.list > button { display:flex; justify-content:space-between; align-items:center; gap:10px; width:100%; text-align:left; border:1px solid var(--line); background:var(--bg); border-radius:12px; padding:10px 12px; }
|
|
403
|
+
.list > button:hover:not(:disabled) { border-color:var(--p); }
|
|
404
|
+
.list > button svg { width:16px; height:16px; flex:none; color:var(--sub); }
|
|
405
|
+
.card { background:var(--bg); border:1px solid var(--line); border-radius:var(--r); overflow:hidden; box-shadow:0 6px 18px -10px rgb(16 18 30/.35); }
|
|
406
|
+
.card .body { padding:10px 12px 12px; display:grid; gap:4px; } .card h3 { margin:0; font-size:14px; } .card p { margin:0; color:var(--sub); font-size:12.5px; }
|
|
407
|
+
.image { aspect-ratio:16 / 9; max-width:100%; display:grid; place-items:center; overflow:hidden; background:var(--surface); color:var(--sub); font-size:12px; }
|
|
408
|
+
.image img { width:100%; height:100%; object-fit:cover; display:block; }
|
|
409
|
+
.primary { justify-self:start; margin-top:6px; border:0; border-radius:10px; background:var(--p); color:#fff; font-weight:600; font-size:13px; padding:8px 14px; }
|
|
410
|
+
.list .card { display:grid; grid-template-columns:minmax(0,88px) 1fr; } .list .card .image { aspect-ratio:auto; height:100%; min-height:88px; }
|
|
411
|
+
.list .card:not(:has(.image)) { grid-template-columns:1fr; }
|
|
412
|
+
.navigation { display:flex; align-items:center; justify-content:space-between; gap:8px; margin:10px 0 0; }
|
|
413
|
+
.round { width:32px; height:32px; border-radius:50%; border:1px solid var(--line); background:var(--bg); display:grid; place-items:center; padding:0; flex:none; }
|
|
414
|
+
.round:hover:not(:disabled) { border-color:var(--p); } .round svg { width:15px; height:15px; }
|
|
415
|
+
.dots { display:flex; gap:5px; align-items:center; } .dots i { width:6px; height:6px; border-radius:3px; background:var(--line); transition:width .2s; } .dots i.on { width:16px; background:var(--p); }
|
|
416
|
+
.calendar { border:1px solid var(--line); border-radius:var(--r); padding:10px; background:var(--bg); display:grid; gap:6px; }
|
|
417
|
+
.calendar .navigation { margin:0; font-weight:600; font-size:13px; }
|
|
418
|
+
.days, .weekdays { display:grid; grid-template-columns:repeat(7, minmax(0, 1fr)); gap:2px 0; text-align:center; }
|
|
419
|
+
.weekdays { color:var(--sub); font-size:11px; }
|
|
420
|
+
.days button { border:0; background:transparent; height:30px; border-radius:8px; padding:0; font-size:12.5px; font-variant-numeric:tabular-nums; }
|
|
421
|
+
.days button:hover:not(:disabled) { background:var(--surface); }
|
|
422
|
+
.days button.today { box-shadow:inset 0 0 0 1.5px var(--line); }
|
|
423
|
+
.days button.in { background:color-mix(in srgb,var(--p) 14%,transparent); border-radius:0; }
|
|
424
|
+
.days button[aria-pressed="true"] { background:var(--p); color:#fff; }
|
|
425
|
+
.days button.start:not(.end) { border-radius:8px 0 0 8px; } .days button.end:not(.start) { border-radius:0 8px 8px 0; }
|
|
426
|
+
.hint { color:var(--sub); font-size:12px; margin:0; }
|
|
427
|
+
@media (prefers-reduced-motion:reduce) { .dots i { transition:none; } }
|
|
352
428
|
`;
|
|
353
|
-
var
|
|
354
|
-
for (var
|
|
355
|
-
(o = i[
|
|
356
|
-
return
|
|
429
|
+
var It = Object.defineProperty, P = (i, t, e, r) => {
|
|
430
|
+
for (var s = void 0, n = i.length - 1, o; n >= 0; n--)
|
|
431
|
+
(o = i[n]) && (s = o(t, e, s) || s);
|
|
432
|
+
return s && It(t, e, s), s;
|
|
357
433
|
};
|
|
358
|
-
class
|
|
434
|
+
class w extends W {
|
|
359
435
|
constructor() {
|
|
360
436
|
super(...arguments), this.interaction = null, this.disabled = !1, this.baseUrl = "";
|
|
361
437
|
}
|
|
@@ -364,66 +440,66 @@ class m extends W {
|
|
|
364
440
|
}
|
|
365
441
|
get valid() {
|
|
366
442
|
const t = this.interaction;
|
|
367
|
-
return !!t && t.tool_type === this.toolType &&
|
|
443
|
+
return !!t && t.tool_type === this.toolType && ot(t, t.presentation);
|
|
368
444
|
}
|
|
369
445
|
respond(t) {
|
|
370
446
|
!this.interaction || !this.live || !this.valid || this.dispatchEvent(new CustomEvent("osvi-respond", { bubbles: !0, composed: !0, detail: { interactionId: this.interaction.interaction_id, response: t } }));
|
|
371
447
|
}
|
|
372
448
|
updated(t) {
|
|
373
|
-
t.has("theme") &&
|
|
449
|
+
t.has("theme") && Q(this, this.theme);
|
|
374
450
|
}
|
|
375
451
|
}
|
|
376
452
|
P([
|
|
377
453
|
l({ attribute: !1 })
|
|
378
|
-
],
|
|
454
|
+
], w.prototype, "interaction");
|
|
379
455
|
P([
|
|
380
456
|
l({ type: Boolean })
|
|
381
|
-
],
|
|
457
|
+
], w.prototype, "disabled");
|
|
382
458
|
P([
|
|
383
459
|
l({ attribute: !1 })
|
|
384
|
-
],
|
|
460
|
+
], w.prototype, "theme");
|
|
385
461
|
P([
|
|
386
462
|
l({ attribute: "base-url" })
|
|
387
|
-
],
|
|
388
|
-
var
|
|
389
|
-
for (var
|
|
390
|
-
(o = i[
|
|
391
|
-
return
|
|
463
|
+
], w.prototype, "baseUrl");
|
|
464
|
+
var At = Object.defineProperty, Mt = (i, t, e, r) => {
|
|
465
|
+
for (var s = void 0, n = i.length - 1, o; n >= 0; n--)
|
|
466
|
+
(o = i[n]) && (s = o(t, e, s) || s);
|
|
467
|
+
return s && At(t, e, s), s;
|
|
392
468
|
};
|
|
393
|
-
const
|
|
469
|
+
const j = class j extends w {
|
|
394
470
|
constructor() {
|
|
395
471
|
super(...arguments), this.toolType = "ui_buttons", this.variant = "chips";
|
|
396
472
|
}
|
|
397
473
|
render() {
|
|
398
474
|
const t = this.interaction;
|
|
399
|
-
if (!t) return
|
|
475
|
+
if (!t) return c;
|
|
400
476
|
if (!this.valid) return a`<p>${t.content}</p>`;
|
|
401
|
-
const e = t.presentation,
|
|
402
|
-
return a`<p>${e.label}</p>${e.description ? a`<p>${e.description}</p>` :
|
|
477
|
+
const e = t.presentation, r = t.response_payload?.kind === "text" ? t.response_payload.value : e.options.find((s) => s.id === (t.response_payload?.kind === "selection" ? t.response_payload.value : t.selected_option_id))?.label;
|
|
478
|
+
return a`<p class="label">${e.label}</p>${e.description ? a`<p class="description">${e.description}</p>` : c}
|
|
403
479
|
${this.live ? a`<div role="group" aria-label="Options" class=${this.variant} @keydown=${this.onKey}>
|
|
404
|
-
${e.options.map((
|
|
405
|
-
</div>` :
|
|
480
|
+
${e.options.map((s) => a`<button type="button" @click=${() => this.pick(s.id, s.allow_input, s.input_placeholder)}><span class="text"><span>${s.label}</span>${s.description ? a`<small>${s.description}</small>` : c}</span>${this.variant === "list" ? R : c}</button>`)}
|
|
481
|
+
</div>` : r ? a`<p class="answer">${r}</p>` : c}`;
|
|
406
482
|
}
|
|
407
|
-
pick(t, e,
|
|
408
|
-
!this.live || !this.valid || !this.interaction || (this.interaction.schema_version === 2 && e ? this.dispatchEvent(new CustomEvent("osvi-request-input", { bubbles: !0, composed: !0, detail: { interactionId: this.interaction.interaction_id, placeholder:
|
|
483
|
+
pick(t, e, r) {
|
|
484
|
+
!this.live || !this.valid || !this.interaction || (this.interaction.schema_version === 2 && e ? this.dispatchEvent(new CustomEvent("osvi-request-input", { bubbles: !0, composed: !0, detail: { interactionId: this.interaction.interaction_id, placeholder: r } })) : this.respond({ kind: "selection", value: t }));
|
|
409
485
|
}
|
|
410
486
|
onKey(t) {
|
|
411
487
|
if (!["ArrowDown", "ArrowUp", "ArrowRight", "ArrowLeft"].includes(t.key)) return;
|
|
412
|
-
const e = [...this.renderRoot.querySelectorAll("button")],
|
|
413
|
-
e[(
|
|
488
|
+
const e = [...this.renderRoot.querySelectorAll("button")], r = e.indexOf(this.renderRoot.activeElement), s = t.key === "ArrowDown" || t.key === "ArrowRight" ? 1 : -1;
|
|
489
|
+
e[(r + s + e.length) % e.length]?.focus(), t.preventDefault();
|
|
414
490
|
}
|
|
415
491
|
};
|
|
416
|
-
|
|
417
|
-
let
|
|
418
|
-
|
|
492
|
+
j.styles = D;
|
|
493
|
+
let M = j;
|
|
494
|
+
Mt([
|
|
419
495
|
l()
|
|
420
|
-
],
|
|
421
|
-
var
|
|
422
|
-
for (var
|
|
423
|
-
(o = i[
|
|
424
|
-
return
|
|
496
|
+
], M.prototype, "variant");
|
|
497
|
+
var Ut = Object.defineProperty, q = (i, t, e, r) => {
|
|
498
|
+
for (var s = void 0, n = i.length - 1, o; n >= 0; n--)
|
|
499
|
+
(o = i[n]) && (s = o(t, e, s) || s);
|
|
500
|
+
return s && Ut(t, e, s), s;
|
|
425
501
|
};
|
|
426
|
-
const
|
|
502
|
+
const F = class F extends w {
|
|
427
503
|
constructor() {
|
|
428
504
|
super(...arguments), this.toolType = "ui_carousel", this.variant = "slider", this.index = 0, this.imageFailed = /* @__PURE__ */ new Set(), this.suppressPointerClick = !1;
|
|
429
505
|
}
|
|
@@ -432,20 +508,20 @@ const O = class O extends m {
|
|
|
432
508
|
}
|
|
433
509
|
render() {
|
|
434
510
|
const t = this.interaction;
|
|
435
|
-
if (!t) return
|
|
511
|
+
if (!t) return c;
|
|
436
512
|
if (!this.valid) return a`<p>${t.content}</p>`;
|
|
437
|
-
const e = t.presentation,
|
|
438
|
-
return a`<p>${e.label}</p>${e.description ? a`<p>${e.description}</p>` :
|
|
439
|
-
${this.live ? this.variant === "list" ? a`<div class="list">${e.items.map((
|
|
440
|
-
this.pointerStart =
|
|
441
|
-
}} @pointerup=${(
|
|
442
|
-
this.pointerStart !== void 0 && Math.abs(
|
|
513
|
+
const e = t.presentation, r = e.items.find((s) => s.id === (t.response_payload?.kind === "selection" ? t.response_payload.value : t.selected_option_id));
|
|
514
|
+
return a`<p class="label">${e.label}</p>${e.description ? a`<p class="description">${e.description}</p>` : c}
|
|
515
|
+
${this.live ? this.variant === "list" ? a`<div class="list">${e.items.map((s, n) => this.card(s, n))}</div>` : a`<div @pointerdown=${(s) => {
|
|
516
|
+
this.pointerStart = s.clientX, this.suppressPointerClick = !1;
|
|
517
|
+
}} @pointerup=${(s) => {
|
|
518
|
+
this.pointerStart !== void 0 && Math.abs(s.clientX - this.pointerStart) > 40 && (this.suppressPointerClick = !0, this.navigate(s.clientX < this.pointerStart ? 1 : -1, e.items.length)), this.pointerStart = void 0;
|
|
443
519
|
}} @pointercancel=${() => {
|
|
444
520
|
this.pointerStart = void 0;
|
|
445
521
|
}}>${this.card(e.items[this.index], this.index)}</div>
|
|
446
|
-
<div class="navigation"><button type="button" aria-label="Previous card" ?disabled=${this.index === 0} @click=${() => this.navigate(-1, e.items.length)}
|
|
447
|
-
<span aria-live="polite">${this.index + 1} of ${e.items.length}</span>
|
|
448
|
-
<button type="button" aria-label="Next card" ?disabled=${this.index === e.items.length - 1} @click=${() => this.navigate(1, e.items.length)}
|
|
522
|
+
<div class="navigation"><button type="button" class="round" aria-label="Previous card" ?disabled=${this.index === 0} @click=${() => this.navigate(-1, e.items.length)}>${et}</button>
|
|
523
|
+
<span class="dots" aria-hidden="true">${e.items.map((s, n) => a`<i class=${n === this.index ? "on" : ""}></i>`)}</span><span class="sr" aria-live="polite">${this.index + 1} of ${e.items.length}</span>
|
|
524
|
+
<button type="button" class="round" aria-label="Next card" ?disabled=${this.index === e.items.length - 1} @click=${() => this.navigate(1, e.items.length)}>${R}</button></div>` : r ? a`<p class="answer">${r.title}</p>` : c}`;
|
|
449
525
|
}
|
|
450
526
|
navigate(t, e) {
|
|
451
527
|
this.index = Math.max(0, Math.min(e - 1, this.index + t));
|
|
@@ -458,113 +534,113 @@ const O = class O extends m {
|
|
|
458
534
|
this.respond({ kind: "selection", value: e });
|
|
459
535
|
}
|
|
460
536
|
card(t, e) {
|
|
461
|
-
const
|
|
462
|
-
return a`<article class="card">${
|
|
537
|
+
const r = t.image;
|
|
538
|
+
return a`<article class="card">${r && lt(r.url) ? a`<div class="image">${this.imageFailed.has(e) ? a`<span role="img" aria-label="Image unavailable">Image unavailable</span>` : a`<img src=${this.baseUrl.replace(/\/$/, "") + r.url} alt=${r.alt} referrerpolicy="no-referrer" loading="lazy" @error=${() => {
|
|
463
539
|
this.imageFailed = /* @__PURE__ */ new Set([...this.imageFailed, e]);
|
|
464
|
-
}}>`}</div>` :
|
|
465
|
-
<h3>${t.title}</h3>${t.description ? a`<p>${t.description}</p>` :
|
|
466
|
-
<button type="button" @click=${(
|
|
540
|
+
}}>`}</div>` : c}
|
|
541
|
+
<div class="body"><h3>${t.title}</h3>${t.description ? a`<p>${t.description}</p>` : c}
|
|
542
|
+
<button type="button" class="primary" @click=${(s) => this.select(s, t.id)}>${t.action_label ?? "Select"}</button></div></article>`;
|
|
467
543
|
}
|
|
468
544
|
};
|
|
469
|
-
|
|
470
|
-
let
|
|
545
|
+
F.styles = D;
|
|
546
|
+
let _ = F;
|
|
471
547
|
q([
|
|
472
548
|
l()
|
|
473
|
-
],
|
|
549
|
+
], _.prototype, "variant");
|
|
474
550
|
q([
|
|
475
|
-
|
|
476
|
-
],
|
|
551
|
+
v()
|
|
552
|
+
], _.prototype, "index");
|
|
477
553
|
q([
|
|
478
|
-
|
|
479
|
-
],
|
|
480
|
-
var
|
|
481
|
-
for (var
|
|
482
|
-
(o = i[
|
|
483
|
-
return
|
|
554
|
+
v()
|
|
555
|
+
], _.prototype, "imageFailed");
|
|
556
|
+
var Pt = Object.defineProperty, T = (i, t, e, r) => {
|
|
557
|
+
for (var s = void 0, n = i.length - 1, o; n >= 0; n--)
|
|
558
|
+
(o = i[n]) && (s = o(t, e, s) || s);
|
|
559
|
+
return s && Pt(t, e, s), s;
|
|
484
560
|
};
|
|
485
|
-
const
|
|
561
|
+
const st = (i) => `${String(i.getFullYear()).padStart(4, "0")}-${String(i.getMonth() + 1).padStart(2, "0")}-${String(i.getDate()).padStart(2, "0")}`, A = () => st(/* @__PURE__ */ new Date()), Y = (i) => {
|
|
486
562
|
const t = /* @__PURE__ */ new Date(0);
|
|
487
563
|
return t.setHours(0, 0, 0, 0), t.setFullYear(Number(i.slice(0, 4)), Number(i.slice(5, 7)) - 1, Number(i.slice(8, 10))), t;
|
|
488
|
-
},
|
|
564
|
+
}, y = (i) => i.slice(0, 7), L = class L extends w {
|
|
489
565
|
constructor() {
|
|
490
|
-
super(...arguments), this.toolType = "ui_date_picker", this.variant = "grid", this.month =
|
|
566
|
+
super(...arguments), this.toolType = "ui_date_picker", this.variant = "grid", this.month = y(A()), this.start = "", this.end = "";
|
|
491
567
|
}
|
|
492
568
|
earliest(t) {
|
|
493
|
-
return t.min_date && t.min_date >
|
|
569
|
+
return t.min_date && t.min_date > A() ? t.min_date : A();
|
|
494
570
|
}
|
|
495
571
|
willUpdate(t) {
|
|
496
|
-
t.has("interaction") && (this.start = "", this.end = "", this.valid && (this.month =
|
|
572
|
+
t.has("interaction") && (this.start = "", this.end = "", this.valid && (this.month = y(this.earliest(this.interaction.presentation))));
|
|
497
573
|
}
|
|
498
574
|
render() {
|
|
499
575
|
const t = this.interaction;
|
|
500
|
-
if (!t) return
|
|
576
|
+
if (!t) return c;
|
|
501
577
|
if (!this.valid) return a`<p>${t.content}</p>`;
|
|
502
|
-
const e = t.presentation,
|
|
503
|
-
if (!this.live) return a`<p>${e.label}</p>${e.description ? a`<p>${e.description}</p>` :
|
|
504
|
-
const
|
|
578
|
+
const e = t.presentation, r = t.response_payload, s = r?.kind === "date_range" ? `${r.value.start_date} – ${r.value.end_date}` : r?.kind === "date" || r?.kind === "text" ? r.value : t.selected_option_id;
|
|
579
|
+
if (!this.live) return a`<p class="label">${e.label}</p>${e.description ? a`<p class="description">${e.description}</p>` : c}${s ? a`<p class="answer">${s}</p>` : c}`;
|
|
580
|
+
const n = Y(`${this.month}-01`), o = new Date(n);
|
|
505
581
|
o.setMonth(o.getMonth() + 1, 0);
|
|
506
|
-
const
|
|
507
|
-
return a`<p>${e.label}</p>${e.description ? a`<p>${e.description}</p>` :
|
|
508
|
-
<div class="navigation"><button type="button" aria-label="Previous month" ?disabled=${this.month <=
|
|
509
|
-
<span aria-live="polite">${
|
|
510
|
-
<button type="button" aria-label="Next month" ?disabled=${!!e.max_date && this.month >=
|
|
511
|
-
<div class="weekdays" aria-hidden="true">${["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"].map((
|
|
582
|
+
const h = this.earliest(e), f = Array.from({ length: o.getDate() }, (u, z) => `${this.month}-${String(z + 1).padStart(2, "0")}`), k = e.selection_mode === "range" ? this.start ? this.end ? `${this.start} – ${this.end}` : `Check-in: ${this.start}. Choose check-out.` : "Choose check-in, then check-out." : this.start, rt = A();
|
|
583
|
+
return a`<p class="label">${e.label}</p>${e.description ? a`<p class="description">${e.description}</p>` : c}
|
|
584
|
+
<div class="calendar"><div class="navigation"><button type="button" class="round" aria-label="Previous month" ?disabled=${this.month <= y(h)} @click=${() => this.moveMonth(-1, e)}>${et}</button>
|
|
585
|
+
<span aria-live="polite">${n.toLocaleDateString(void 0, { month: "long", year: "numeric" })}</span>
|
|
586
|
+
<button type="button" class="round" aria-label="Next month" ?disabled=${!!e.max_date && this.month >= y(e.max_date)} @click=${() => this.moveMonth(1, e)}>${R}</button></div>
|
|
587
|
+
<div class="weekdays" aria-hidden="true">${["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"].map((u) => a`<span>${u}</span>`)}</div>
|
|
512
588
|
<div class="days" role="group" aria-label="Choose date" @keydown=${this.onKey}>
|
|
513
|
-
${Array.from({ length:
|
|
514
|
-
${
|
|
515
|
-
</div><p aria-live="polite">${
|
|
516
|
-
<button type="button" ?disabled=${!this.start || e.selection_mode === "range" && (!this.end || this.start >= this.end)} @click=${() => this.confirm(e)}>${e.confirm_label ?? "Confirm date"}</button>`;
|
|
589
|
+
${Array.from({ length: n.getDay() }, () => a`<span></span>`)}
|
|
590
|
+
${f.map((u, z) => a`<button type="button" class=${[u === rt ? "today" : "", u === this.start ? "start" : "", u === this.end ? "end" : "", this.start && this.end && u > this.start && u < this.end ? "in" : ""].filter(Boolean).join(" ")} aria-label=${u} aria-pressed=${u === this.start || u === this.end} ?disabled=${u < h || !!e.max_date && u > e.max_date} @click=${() => this.pick(u, e)}>${z + 1}</button>`)}
|
|
591
|
+
</div><p class="hint" aria-live="polite">${k}</p>
|
|
592
|
+
<button type="button" class="primary" ?disabled=${!this.start || e.selection_mode === "range" && (!this.end || this.start >= this.end)} @click=${() => this.confirm(e)}>${e.confirm_label ?? "Confirm date"}</button></div>`;
|
|
517
593
|
}
|
|
518
594
|
moveMonth(t, e) {
|
|
519
|
-
const
|
|
520
|
-
|
|
521
|
-
const
|
|
522
|
-
|
|
595
|
+
const r = Y(`${this.month}-01`);
|
|
596
|
+
r.setMonth(r.getMonth() + t);
|
|
597
|
+
const s = y(st(r));
|
|
598
|
+
s >= y(this.earliest(e)) && (!e.max_date || s <= y(e.max_date)) && (this.month = s);
|
|
523
599
|
}
|
|
524
600
|
pick(t, e) {
|
|
525
|
-
!this.live || !this.valid || !
|
|
601
|
+
!this.live || !this.valid || !B(t) || t < this.earliest(e) || e.max_date && t > e.max_date || (e.selection_mode === "single" || !this.start || this.end || t <= this.start ? (this.start = t, this.end = "") : this.end = t);
|
|
526
602
|
}
|
|
527
603
|
confirm(t) {
|
|
528
|
-
!
|
|
604
|
+
!B(this.start) || this.start < this.earliest(t) || t.max_date && this.start > t.max_date || (t.selection_mode === "single" ? this.respond({ kind: "date", value: this.start }) : B(this.end) && this.start < this.end && (!t.max_date || this.end <= t.max_date) && this.respond({ kind: "date_range", value: { start_date: this.start, end_date: this.end } }));
|
|
529
605
|
}
|
|
530
606
|
onKey(t) {
|
|
531
|
-
const
|
|
532
|
-
if (
|
|
533
|
-
const
|
|
534
|
-
if (
|
|
535
|
-
let o =
|
|
536
|
-
for (; o >= 0 && o <
|
|
537
|
-
|
|
607
|
+
const r = { ArrowLeft: -1, ArrowRight: 1, ArrowUp: -7, ArrowDown: 7 }[t.key];
|
|
608
|
+
if (r === void 0) return;
|
|
609
|
+
const s = [...this.renderRoot.querySelectorAll(".days button")], n = s.indexOf(this.renderRoot.activeElement);
|
|
610
|
+
if (n < 0) return;
|
|
611
|
+
let o = n + r;
|
|
612
|
+
for (; o >= 0 && o < s.length && s[o]?.disabled; ) o += r > 0 ? 1 : -1;
|
|
613
|
+
s[o]?.focus(), t.preventDefault();
|
|
538
614
|
}
|
|
539
615
|
};
|
|
540
|
-
|
|
541
|
-
let
|
|
616
|
+
L.styles = D;
|
|
617
|
+
let $ = L;
|
|
542
618
|
T([
|
|
543
619
|
l()
|
|
544
|
-
],
|
|
620
|
+
], $.prototype, "variant");
|
|
545
621
|
T([
|
|
546
|
-
|
|
547
|
-
],
|
|
622
|
+
v()
|
|
623
|
+
], $.prototype, "month");
|
|
548
624
|
T([
|
|
549
|
-
|
|
550
|
-
],
|
|
625
|
+
v()
|
|
626
|
+
], $.prototype, "start");
|
|
551
627
|
T([
|
|
552
|
-
|
|
553
|
-
],
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
628
|
+
v()
|
|
629
|
+
], $.prototype, "end");
|
|
630
|
+
U("osvi-chat", St);
|
|
631
|
+
U("osvi-buttons", M);
|
|
632
|
+
U("osvi-carousel", _);
|
|
633
|
+
U("osvi-date-picker", $);
|
|
558
634
|
export {
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
635
|
+
H as DEFAULT_STRINGS,
|
|
636
|
+
M as OsviButtons,
|
|
637
|
+
_ as OsviCarousel,
|
|
638
|
+
St as OsviChat,
|
|
639
|
+
$ as OsviDatePicker,
|
|
640
|
+
Q as applyTheme,
|
|
641
|
+
ut as cssVar,
|
|
642
|
+
U as defineOnce,
|
|
643
|
+
bt as explicitThemeVariables,
|
|
644
|
+
E as themeVariables
|
|
569
645
|
};
|
|
570
646
|
//# sourceMappingURL=ui.mjs.map
|