@burdenoff/website-sdk 2026.1102.2 → 2026.1104.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/README.md +63 -8
- package/dist/avatar-live-view/index.d.mts +29 -5
- package/dist/avatar-live-view/index.d.ts +29 -5
- package/dist/avatar-live-view/index.js +1319 -271
- package/dist/avatar-live-view/index.js.map +1 -1
- package/dist/avatar-live-view/index.mjs +1317 -269
- package/dist/avatar-live-view/index.mjs.map +1 -1
- package/dist/{chunk-R742FS5E.js → chunk-22OT6E26.js} +61 -27
- package/dist/chunk-22OT6E26.js.map +1 -0
- package/dist/{chunk-ETI2HQEC.mjs → chunk-5JQGE3XI.mjs} +46 -14
- package/dist/chunk-5JQGE3XI.mjs.map +1 -0
- package/dist/{chunk-FQH3AJN3.js → chunk-7O2I32ZN.js} +2 -2
- package/dist/chunk-7O2I32ZN.js.map +1 -0
- package/dist/{chunk-SFT3WHN5.mjs → chunk-K3QZGJEH.mjs} +2 -2
- package/dist/chunk-K3QZGJEH.mjs.map +1 -0
- package/dist/{chunk-SK5UGG6A.js → chunk-P5GMVPR6.js} +76 -20
- package/dist/chunk-P5GMVPR6.js.map +1 -0
- package/dist/{chunk-EUPFS6MZ.mjs → chunk-SMD7MEEA.mjs} +76 -20
- package/dist/chunk-SMD7MEEA.mjs.map +1 -0
- package/dist/components/explore.d.mts +2 -2
- package/dist/components/explore.d.ts +2 -2
- package/dist/components/explore.js +14 -14
- package/dist/components/explore.mjs +2 -2
- package/dist/{explore-DUTNYUOm.d.mts → explore-BV4dRwoC.d.ts} +8 -1
- package/dist/{explore-DjQE7Xia.d.ts → explore-BgEeGPvY.d.mts} +8 -1
- package/dist/{explore-avatar-live-config-Cetx8-Zu.d.ts → explore-avatar-live-config-CAfN5eAX.d.ts} +6 -3
- package/dist/{explore-avatar-live-config-Bp3kQbU2.d.mts → explore-avatar-live-config-N4WhJzgS.d.mts} +6 -3
- package/dist/{explore-types-Bb2Ih3d8.d.mts → explore-types-Ol1Mm3dW.d.mts} +12 -1
- package/dist/{explore-types-Bb2Ih3d8.d.ts → explore-types-Ol1Mm3dW.d.ts} +12 -1
- package/dist/hooks/index.d.mts +2 -2
- package/dist/hooks/index.d.ts +2 -2
- package/dist/hooks/index.js +9 -9
- package/dist/hooks/index.mjs +1 -1
- package/dist/index.d.mts +14 -8
- package/dist/index.d.ts +14 -8
- package/dist/index.js +100 -63
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +43 -6
- package/dist/index.mjs.map +1 -1
- package/dist/{use-explore-chat-DunjG-3p.d.ts → use-explore-chat-B3dOOvJN.d.ts} +43 -3
- package/dist/{use-explore-chat-zRuoAin6.d.mts → use-explore-chat-CbfohA9O.d.mts} +43 -3
- package/package.json +1 -1
- package/dist/chunk-ETI2HQEC.mjs.map +0 -1
- package/dist/chunk-EUPFS6MZ.mjs.map +0 -1
- package/dist/chunk-FQH3AJN3.js.map +0 -1
- package/dist/chunk-R742FS5E.js.map +0 -1
- package/dist/chunk-SFT3WHN5.mjs.map +0 -1
- package/dist/chunk-SK5UGG6A.js.map +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunk7O2I32ZN_js = require('../chunk-7O2I32ZN.js');
|
|
4
4
|
var chunkO4GS3XPZ_js = require('../chunk-O4GS3XPZ.js');
|
|
5
5
|
var chunkC6OJIHNO_js = require('../chunk-C6OJIHNO.js');
|
|
6
6
|
require('../chunk-ZSTFX7FV.js');
|
|
@@ -49,6 +49,15 @@ function readBotCheck(value) {
|
|
|
49
49
|
}
|
|
50
50
|
return mode === "off" ? "off" : "turnstile";
|
|
51
51
|
}
|
|
52
|
+
var QUESTION_MODES = /* @__PURE__ */ new Set([
|
|
53
|
+
"any",
|
|
54
|
+
"suggested"
|
|
55
|
+
]);
|
|
56
|
+
function readQuestions(value) {
|
|
57
|
+
if (value === void 0) return "suggested";
|
|
58
|
+
if (typeof value !== "string" || !QUESTION_MODES.has(value)) return null;
|
|
59
|
+
return value === "any" ? "any" : "suggested";
|
|
60
|
+
}
|
|
52
61
|
function readAvailability(status, body) {
|
|
53
62
|
if (status !== 200 || !isRecord(body)) return INERT;
|
|
54
63
|
const { available, reason } = body;
|
|
@@ -58,16 +67,21 @@ function readAvailability(status, body) {
|
|
|
58
67
|
if (reason === "ok") {
|
|
59
68
|
const { consentVersion, maxSessionSeconds } = body;
|
|
60
69
|
const botCheck = readBotCheck(body.botCheck);
|
|
61
|
-
|
|
70
|
+
const questions = readQuestions(body.questions);
|
|
71
|
+
if (available !== true || typeof consentVersion !== "string" || !chunk7O2I32ZN_js.isAvatarVersion(consentVersion) || typeof maxSessionSeconds !== "number" || !Number.isInteger(maxSessionSeconds) || maxSessionSeconds < 1 || botCheck === null || questions === null) {
|
|
62
72
|
return INERT;
|
|
63
73
|
}
|
|
64
74
|
return {
|
|
65
75
|
kind: "available",
|
|
66
|
-
offer: { consentVersion, maxSessionSeconds, botCheck }
|
|
76
|
+
offer: { consentVersion, maxSessionSeconds, botCheck, questions }
|
|
67
77
|
};
|
|
68
78
|
}
|
|
69
79
|
const meaning = available ? void 0 : AVAILABILITY_REASONS.get(reason);
|
|
70
|
-
return meaning === void 0 || meaning === "inert" ? INERT : {
|
|
80
|
+
return meaning === void 0 || meaning === "inert" ? INERT : {
|
|
81
|
+
kind: "refused",
|
|
82
|
+
reason: meaning,
|
|
83
|
+
questions: body.questions === "any" ? "any" : "suggested"
|
|
84
|
+
};
|
|
71
85
|
}
|
|
72
86
|
var CREATE_REFUSALS = /* @__PURE__ */ new Map([
|
|
73
87
|
["busy", "busy"],
|
|
@@ -146,7 +160,7 @@ function deadline(timeoutMs, outer) {
|
|
|
146
160
|
};
|
|
147
161
|
}
|
|
148
162
|
async function requestAvailability(target) {
|
|
149
|
-
if (!
|
|
163
|
+
if (!chunk7O2I32ZN_js.isAvatarSite(target.site) || !LOCALE.test(target.locale)) return INERT;
|
|
150
164
|
const query = new URLSearchParams({
|
|
151
165
|
site: target.site,
|
|
152
166
|
locale: target.locale
|
|
@@ -287,7 +301,31 @@ var EN = {
|
|
|
287
301
|
locale: "The live avatar isn't offered in this language yet.",
|
|
288
302
|
paused: "The live avatar is paused right now.",
|
|
289
303
|
notEligible: "The avatar reads the first answer to a suggested question, within fifteen minutes. Start a new chat and choose a suggested question.",
|
|
290
|
-
answerClaimed: "The avatar has already read this answer."
|
|
304
|
+
answerClaimed: "The avatar has already read this answer.",
|
|
305
|
+
askHeadline: "Ask a question, and the avatar reads the answer aloud.",
|
|
306
|
+
askLabel: "Question for the avatar",
|
|
307
|
+
askPlaceholder: "Ask the avatar\u2026",
|
|
308
|
+
askFooter: "Answers are AI-generated and can be wrong. Don't include personal details.",
|
|
309
|
+
askNoFiles: "To attach files, use Chat.",
|
|
310
|
+
askBusy: "You can ask when the current answer is ready.",
|
|
311
|
+
askUnavailable: "Chat isn't available right now.",
|
|
312
|
+
gettingAnswer: "Getting the answer\u2026",
|
|
313
|
+
startWhenReady: "Start when ready",
|
|
314
|
+
armed: "The avatar will start when the answer is ready.",
|
|
315
|
+
cancel: "Cancel",
|
|
316
|
+
armedCancelled: "The avatar didn't start. Press Start when ready to try again.",
|
|
317
|
+
notSpoken: "This answer stays in Chat as text. The avatar reads only answers that pass its speech checks.",
|
|
318
|
+
answerFailed: "The assistant couldn't answer. Try asking again.",
|
|
319
|
+
declined: "No problem. The answer is in Chat.",
|
|
320
|
+
askHere: "To hear an answer, ask it here.",
|
|
321
|
+
newChatForAvatar: "New chat for the avatar",
|
|
322
|
+
newChatNote: "Your current chat stays in History.",
|
|
323
|
+
newChatStarted: "Started a new chat for the avatar.",
|
|
324
|
+
readInChat: "Read the answer and sources in Chat",
|
|
325
|
+
usedToday: "You've had today's avatar session. Answers will show here as text.",
|
|
326
|
+
needsAnswerAny: "Ask a question here, and the avatar reads the answer aloud.",
|
|
327
|
+
startNewChatDetailAny: "The avatar reads aloud only the first answer in a new chat started in the Avatar tab, provided it passes the speech checks.",
|
|
328
|
+
notEligibleAny: "The avatar can't read this answer aloud. The answer and sources are in Chat."
|
|
291
329
|
};
|
|
292
330
|
var ZH = {
|
|
293
331
|
checking: "\u6B63\u5728\u68C0\u67E5\u5B9E\u65F6\u865A\u62DF\u5F62\u8C61\u662F\u5426\u53EF\u7528\u2026",
|
|
@@ -321,7 +359,32 @@ var ZH = {
|
|
|
321
359
|
paused: "\u5B9E\u65F6\u865A\u62DF\u5F62\u8C61\u76EE\u524D\u5DF2\u6682\u505C\u3002",
|
|
322
360
|
// TRANSLATION REVIEW PENDING (BOFF-9797): draft.
|
|
323
361
|
notEligible: "\u865A\u62DF\u5F62\u8C61\u53EA\u6717\u8BFB\u63A8\u8350\u95EE\u9898\u7684\u7B2C\u4E00\u4E2A\u56DE\u7B54\uFF0C\u4E14\u987B\u5728\u5341\u4E94\u5206\u949F\u5185\u3002\u8BF7\u5F00\u59CB\u65B0\u7684\u804A\u5929\uFF0C\u5E76\u9009\u62E9\u4E00\u4E2A\u63A8\u8350\u95EE\u9898\u3002",
|
|
324
|
-
answerClaimed: "\u865A\u62DF\u5F62\u8C61\u5DF2\u7ECF\u6717\u8BFB\u8FC7\u8FD9\u4E2A\u56DE\u7B54\u3002"
|
|
362
|
+
answerClaimed: "\u865A\u62DF\u5F62\u8C61\u5DF2\u7ECF\u6717\u8BFB\u8FC7\u8FD9\u4E2A\u56DE\u7B54\u3002",
|
|
363
|
+
// TRANSLATION REVIEW PENDING (BOFF-9797): draft, the Avatar tab's question box.
|
|
364
|
+
askHeadline: "\u63D0\u51FA\u95EE\u9898\uFF0C\u865A\u62DF\u5F62\u8C61\u4F1A\u6717\u8BFB\u56DE\u7B54\u3002",
|
|
365
|
+
askLabel: "\u5411\u865A\u62DF\u5F62\u8C61\u63D0\u7684\u95EE\u9898",
|
|
366
|
+
askPlaceholder: "\u5411\u865A\u62DF\u5F62\u8C61\u63D0\u95EE\u2026",
|
|
367
|
+
askFooter: "\u56DE\u7B54\u7531 AI \u751F\u6210\uFF0C\u53EF\u80FD\u6709\u8BEF\u3002\u8BF7\u52FF\u5305\u542B\u4E2A\u4EBA\u4FE1\u606F\u3002",
|
|
368
|
+
askNoFiles: "\u5982\u9700\u9644\u52A0\u6587\u4EF6\uFF0C\u8BF7\u4F7F\u7528\u804A\u5929\u3002",
|
|
369
|
+
askBusy: "\u5F53\u524D\u56DE\u7B54\u51C6\u5907\u597D\u540E\u5373\u53EF\u63D0\u95EE\u3002",
|
|
370
|
+
askUnavailable: "\u804A\u5929\u76EE\u524D\u4E0D\u53EF\u7528\u3002",
|
|
371
|
+
gettingAnswer: "\u6B63\u5728\u83B7\u53D6\u56DE\u7B54\u2026",
|
|
372
|
+
startWhenReady: "\u51C6\u5907\u597D\u540E\u5F00\u59CB",
|
|
373
|
+
armed: "\u56DE\u7B54\u51C6\u5907\u597D\u540E\uFF0C\u865A\u62DF\u5F62\u8C61\u5C06\u5F00\u59CB\u3002",
|
|
374
|
+
cancel: "\u53D6\u6D88",
|
|
375
|
+
armedCancelled: "\u865A\u62DF\u5F62\u8C61\u672A\u542F\u52A8\u3002\u53EF\u518D\u6B21\u6309\u201C\u51C6\u5907\u597D\u540E\u5F00\u59CB\u201D\u3002",
|
|
376
|
+
notSpoken: "\u6B64\u56DE\u7B54\u4EE5\u6587\u5B57\u5F62\u5F0F\u4FDD\u7559\u5728\u804A\u5929\u4E2D\u3002\u865A\u62DF\u5F62\u8C61\u53EA\u6717\u8BFB\u901A\u8FC7\u5176\u8BED\u97F3\u68C0\u67E5\u7684\u56DE\u7B54\u3002",
|
|
377
|
+
answerFailed: "\u52A9\u624B\u65E0\u6CD5\u56DE\u7B54\u3002\u8BF7\u91CD\u65B0\u63D0\u95EE\u3002",
|
|
378
|
+
declined: "\u6CA1\u5173\u7CFB\u3002\u56DE\u7B54\u5728\u804A\u5929\u4E2D\u3002",
|
|
379
|
+
askHere: "\u5982\u9700\u542C\u53D6\u56DE\u7B54\uFF0C\u8BF7\u5728\u8FD9\u91CC\u63D0\u95EE\u3002",
|
|
380
|
+
newChatForAvatar: "\u4E3A\u865A\u62DF\u5F62\u8C61\u5F00\u59CB\u65B0\u804A\u5929",
|
|
381
|
+
newChatNote: "\u5F53\u524D\u804A\u5929\u4F1A\u4FDD\u7559\u5728\u5386\u53F2\u8BB0\u5F55\u4E2D\u3002",
|
|
382
|
+
newChatStarted: "\u5DF2\u4E3A\u865A\u62DF\u5F62\u8C61\u5F00\u59CB\u65B0\u7684\u804A\u5929\u3002",
|
|
383
|
+
readInChat: "\u5728\u804A\u5929\u4E2D\u67E5\u770B\u56DE\u7B54\u548C\u6765\u6E90",
|
|
384
|
+
usedToday: "\u60A8\u4ECA\u5929\u5DF2\u4F7F\u7528\u8FC7\u865A\u62DF\u5F62\u8C61\u3002\u56DE\u7B54\u5C06\u4EE5\u6587\u5B57\u663E\u793A\u5728\u8FD9\u91CC\u3002",
|
|
385
|
+
needsAnswerAny: "\u5728\u8FD9\u91CC\u63D0\u95EE\uFF0C\u865A\u62DF\u5F62\u8C61\u4F1A\u6717\u8BFB\u56DE\u7B54\u3002",
|
|
386
|
+
startNewChatDetailAny: "\u865A\u62DF\u5F62\u8C61\u53EA\u6717\u8BFB\u5728\u201C\u865A\u62DF\u5F62\u8C61\u201D\u6807\u7B7E\u9875\u4E2D\u5F00\u59CB\u7684\u65B0\u804A\u5929\u7684\u7B2C\u4E00\u4E2A\u56DE\u7B54\uFF0C\u4E14\u8BE5\u56DE\u7B54\u987B\u901A\u8FC7\u8BED\u97F3\u68C0\u67E5\u3002",
|
|
387
|
+
notEligibleAny: "\u865A\u62DF\u5F62\u8C61\u65E0\u6CD5\u6717\u8BFB\u6B64\u56DE\u7B54\u3002\u56DE\u7B54\u548C\u6765\u6E90\u5728\u804A\u5929\u4E2D\u3002"
|
|
325
388
|
};
|
|
326
389
|
var HI = {
|
|
327
390
|
checking: "\u091C\u093E\u0901\u091A \u0939\u094B \u0930\u0939\u0940 \u0939\u0948 \u0915\u093F \u0932\u093E\u0907\u0935 \u0905\u0935\u0924\u093E\u0930 \u0909\u092A\u0932\u092C\u094D\u0927 \u0939\u0948 \u092F\u093E \u0928\u0939\u0940\u0902\u2026",
|
|
@@ -355,7 +418,32 @@ var HI = {
|
|
|
355
418
|
paused: "\u0932\u093E\u0907\u0935 \u0905\u0935\u0924\u093E\u0930 \u0905\u092D\u0940 \u0930\u0941\u0915\u093E \u0939\u0941\u0906 \u0939\u0948\u0964",
|
|
356
419
|
// TRANSLATION REVIEW PENDING (BOFF-9797): draft.
|
|
357
420
|
notEligible: "\u0905\u0935\u0924\u093E\u0930 \u0938\u0941\u091D\u093E\u090F \u0917\u090F \u092A\u094D\u0930\u0936\u094D\u0928 \u0915\u093E \u092A\u0939\u0932\u093E \u0909\u0924\u094D\u0924\u0930 \u0939\u0940 \u092A\u0922\u093C\u0924\u093E \u0939\u0948, \u092A\u0902\u0926\u094D\u0930\u0939 \u092E\u093F\u0928\u091F \u0915\u0947 \u092D\u0940\u0924\u0930\u0964 \u0928\u0908 \u091A\u0948\u091F \u0936\u0941\u0930\u0942 \u0915\u0930\u0947\u0902 \u0914\u0930 \u0915\u094B\u0908 \u0938\u0941\u091D\u093E\u092F\u093E \u0917\u092F\u093E \u092A\u094D\u0930\u0936\u094D\u0928 \u091A\u0941\u0928\u0947\u0902\u0964",
|
|
358
|
-
answerClaimed: "\u0905\u0935\u0924\u093E\u0930 \u092F\u0939 \u0909\u0924\u094D\u0924\u0930 \u092A\u0939\u0932\u0947 \u0939\u0940 \u092A\u0922\u093C \u091A\u0941\u0915\u093E \u0939\u0948\u0964"
|
|
421
|
+
answerClaimed: "\u0905\u0935\u0924\u093E\u0930 \u092F\u0939 \u0909\u0924\u094D\u0924\u0930 \u092A\u0939\u0932\u0947 \u0939\u0940 \u092A\u0922\u093C \u091A\u0941\u0915\u093E \u0939\u0948\u0964",
|
|
422
|
+
// TRANSLATION REVIEW PENDING (BOFF-9797): draft, the Avatar tab's question box.
|
|
423
|
+
askHeadline: "\u0915\u094B\u0908 \u092A\u094D\u0930\u0936\u094D\u0928 \u092A\u0942\u091B\u0947\u0902, \u0914\u0930 \u0905\u0935\u0924\u093E\u0930 \u0909\u0938\u0915\u093E \u0909\u0924\u094D\u0924\u0930 \u091C\u093C\u094B\u0930 \u0938\u0947 \u092A\u0922\u093C\u0947\u0917\u093E\u0964",
|
|
424
|
+
askLabel: "\u0905\u0935\u0924\u093E\u0930 \u0915\u0947 \u0932\u093F\u090F \u092A\u094D\u0930\u0936\u094D\u0928",
|
|
425
|
+
askPlaceholder: "\u0905\u0935\u0924\u093E\u0930 \u0938\u0947 \u092A\u0942\u091B\u0947\u0902\u2026",
|
|
426
|
+
askFooter: "\u0909\u0924\u094D\u0924\u0930 AI \u0926\u094D\u0935\u093E\u0930\u093E \u092C\u0928\u093E\u090F \u091C\u093E\u0924\u0947 \u0939\u0948\u0902 \u0914\u0930 \u0917\u0932\u0924 \u0939\u094B \u0938\u0915\u0924\u0947 \u0939\u0948\u0902\u0964 \u0928\u093F\u091C\u0940 \u091C\u093E\u0928\u0915\u093E\u0930\u0940 \u0936\u093E\u092E\u093F\u0932 \u0928 \u0915\u0930\u0947\u0902\u0964",
|
|
427
|
+
askNoFiles: "\u092B\u093C\u093E\u0907\u0932\u0947\u0902 \u091C\u094B\u0921\u093C\u0928\u0947 \u0915\u0947 \u0932\u093F\u090F \u091A\u0948\u091F \u0915\u093E \u0909\u092A\u092F\u094B\u0917 \u0915\u0930\u0947\u0902\u0964",
|
|
428
|
+
askBusy: "\u092E\u094C\u091C\u0942\u0926\u093E \u0909\u0924\u094D\u0924\u0930 \u0924\u0948\u092F\u093E\u0930 \u0939\u094B\u0928\u0947 \u092A\u0930 \u0906\u092A \u092A\u0942\u091B \u0938\u0915\u0924\u0947 \u0939\u0948\u0902\u0964",
|
|
429
|
+
askUnavailable: "\u091A\u0948\u091F \u0905\u092D\u0940 \u0909\u092A\u0932\u092C\u094D\u0927 \u0928\u0939\u0940\u0902 \u0939\u0948\u0964",
|
|
430
|
+
gettingAnswer: "\u0909\u0924\u094D\u0924\u0930 \u0932\u093E\u092F\u093E \u091C\u093E \u0930\u0939\u093E \u0939\u0948\u2026",
|
|
431
|
+
startWhenReady: "\u0924\u0948\u092F\u093E\u0930 \u0939\u094B\u0928\u0947 \u092A\u0930 \u0936\u0941\u0930\u0942 \u0915\u0930\u0947\u0902",
|
|
432
|
+
armed: "\u0909\u0924\u094D\u0924\u0930 \u0924\u0948\u092F\u093E\u0930 \u0939\u094B\u0924\u0947 \u0939\u0940 \u0905\u0935\u0924\u093E\u0930 \u0936\u0941\u0930\u0942 \u0939\u094B\u0917\u093E\u0964",
|
|
433
|
+
cancel: "\u0930\u0926\u094D\u0926 \u0915\u0930\u0947\u0902",
|
|
434
|
+
armedCancelled: "\u0905\u0935\u0924\u093E\u0930 \u0936\u0941\u0930\u0942 \u0928\u0939\u0940\u0902 \u0939\u0941\u0906\u0964 \u092B\u093F\u0930 \u0938\u0947 \u0915\u094B\u0936\u093F\u0936 \u0915\u0930\u0928\u0947 \u0915\u0947 \u0932\u093F\u090F \u201C\u0924\u0948\u092F\u093E\u0930 \u0939\u094B\u0928\u0947 \u092A\u0930 \u0936\u0941\u0930\u0942 \u0915\u0930\u0947\u0902\u201D \u0926\u092C\u093E\u090F\u0901\u0964",
|
|
435
|
+
notSpoken: "\u092F\u0939 \u0909\u0924\u094D\u0924\u0930 \u091A\u0948\u091F \u092E\u0947\u0902 \u091F\u0947\u0915\u094D\u0938\u094D\u091F \u0915\u0947 \u0930\u0942\u092A \u092E\u0947\u0902 \u0930\u0939\u0947\u0917\u093E\u0964 \u0905\u0935\u0924\u093E\u0930 \u0915\u0947\u0935\u0932 \u0935\u0939\u0940 \u0909\u0924\u094D\u0924\u0930 \u092A\u0922\u093C\u0924\u093E \u0939\u0948 \u091C\u094B \u0909\u0938\u0915\u0940 \u0935\u093E\u0923\u0940 \u091C\u093E\u0901\u091A \u092E\u0947\u0902 \u092A\u093E\u0938 \u0939\u094B\u0924\u0947 \u0939\u0948\u0902\u0964",
|
|
436
|
+
answerFailed: "\u0938\u0939\u093E\u092F\u0915 \u0909\u0924\u094D\u0924\u0930 \u0928\u0939\u0940\u0902 \u0926\u0947 \u0938\u0915\u093E\u0964 \u092B\u093F\u0930 \u0938\u0947 \u092A\u0942\u091B\u0915\u0930 \u0926\u0947\u0916\u0947\u0902\u0964",
|
|
437
|
+
declined: "\u0915\u094B\u0908 \u092C\u093E\u0924 \u0928\u0939\u0940\u0902\u0964 \u0909\u0924\u094D\u0924\u0930 \u091A\u0948\u091F \u092E\u0947\u0902 \u0939\u0948\u0964",
|
|
438
|
+
askHere: "\u0909\u0924\u094D\u0924\u0930 \u0938\u0941\u0928\u0928\u0947 \u0915\u0947 \u0932\u093F\u090F, \u092F\u0939\u093E\u0901 \u092A\u0942\u091B\u0947\u0902\u0964",
|
|
439
|
+
newChatForAvatar: "\u0905\u0935\u0924\u093E\u0930 \u0915\u0947 \u0932\u093F\u090F \u0928\u0908 \u091A\u0948\u091F",
|
|
440
|
+
newChatNote: "\u0906\u092A\u0915\u0940 \u092E\u094C\u091C\u0942\u0926\u093E \u091A\u0948\u091F \u0907\u0924\u093F\u0939\u093E\u0938 \u092E\u0947\u0902 \u0930\u0939\u0947\u0917\u0940\u0964",
|
|
441
|
+
newChatStarted: "\u0905\u0935\u0924\u093E\u0930 \u0915\u0947 \u0932\u093F\u090F \u0928\u0908 \u091A\u0948\u091F \u0936\u0941\u0930\u0942 \u0915\u0940 \u0917\u0908\u0964",
|
|
442
|
+
readInChat: "\u0909\u0924\u094D\u0924\u0930 \u0914\u0930 \u0938\u094D\u0930\u094B\u0924 \u091A\u0948\u091F \u092E\u0947\u0902 \u092A\u0922\u093C\u0947\u0902",
|
|
443
|
+
usedToday: "\u0906\u091C \u0915\u093E \u0905\u0935\u0924\u093E\u0930 \u0938\u0924\u094D\u0930 \u0906\u092A \u0932\u0947 \u091A\u0941\u0915\u0947 \u0939\u0948\u0902\u0964 \u0909\u0924\u094D\u0924\u0930 \u092F\u0939\u093E\u0901 \u091F\u0947\u0915\u094D\u0938\u094D\u091F \u0915\u0947 \u0930\u0942\u092A \u092E\u0947\u0902 \u0926\u093F\u0916\u0947\u0902\u0917\u0947\u0964",
|
|
444
|
+
needsAnswerAny: "\u092F\u0939\u093E\u0901 \u092A\u094D\u0930\u0936\u094D\u0928 \u092A\u0942\u091B\u0947\u0902, \u0914\u0930 \u0905\u0935\u0924\u093E\u0930 \u0909\u0924\u094D\u0924\u0930 \u091C\u093C\u094B\u0930 \u0938\u0947 \u092A\u0922\u093C\u0947\u0917\u093E\u0964",
|
|
445
|
+
startNewChatDetailAny: "\u0905\u0935\u0924\u093E\u0930 \u0915\u0947\u0935\u0932 \u0905\u0935\u0924\u093E\u0930 \u091F\u0948\u092C \u092E\u0947\u0902 \u0936\u0941\u0930\u0942 \u0915\u0940 \u0917\u0908 \u0928\u0908 \u091A\u0948\u091F \u0915\u093E \u092A\u0939\u0932\u093E \u0909\u0924\u094D\u0924\u0930 \u091C\u093C\u094B\u0930 \u0938\u0947 \u092A\u0922\u093C\u0924\u093E \u0939\u0948, \u092C\u0936\u0930\u094D\u0924\u0947 \u0935\u0939 \u0935\u093E\u0923\u0940 \u091C\u093E\u0901\u091A \u092E\u0947\u0902 \u092A\u093E\u0938 \u0939\u094B\u0964",
|
|
446
|
+
notEligibleAny: "\u0905\u0935\u0924\u093E\u0930 \u092F\u0939 \u0909\u0924\u094D\u0924\u0930 \u091C\u093C\u094B\u0930 \u0938\u0947 \u0928\u0939\u0940\u0902 \u092A\u0922\u093C \u0938\u0915\u0924\u093E\u0964 \u0909\u0924\u094D\u0924\u0930 \u0914\u0930 \u0938\u094D\u0930\u094B\u0924 \u091A\u0948\u091F \u092E\u0947\u0902 \u0939\u0948\u0902\u0964"
|
|
359
447
|
};
|
|
360
448
|
var ES = {
|
|
361
449
|
checking: "Comprobando si el avatar en vivo est\xE1 disponible\u2026",
|
|
@@ -389,7 +477,32 @@ var ES = {
|
|
|
389
477
|
paused: "El avatar en vivo est\xE1 en pausa en este momento.",
|
|
390
478
|
// TRANSLATION REVIEW PENDING (BOFF-9797): draft.
|
|
391
479
|
notEligible: "El avatar lee la primera respuesta a una pregunta sugerida, en un plazo de quince minutos. Inicia un chat nuevo y elige una pregunta sugerida.",
|
|
392
|
-
answerClaimed: "El avatar ya ha le\xEDdo esta respuesta."
|
|
480
|
+
answerClaimed: "El avatar ya ha le\xEDdo esta respuesta.",
|
|
481
|
+
// TRANSLATION REVIEW PENDING (BOFF-9797): draft, the Avatar tab's question box.
|
|
482
|
+
askHeadline: "Haz una pregunta y el avatar leer\xE1 la respuesta en voz alta.",
|
|
483
|
+
askLabel: "Pregunta para el avatar",
|
|
484
|
+
askPlaceholder: "Pregunta al avatar\u2026",
|
|
485
|
+
askFooter: "Las respuestas las genera la IA y pueden contener errores. No incluyas datos personales.",
|
|
486
|
+
askNoFiles: "Para adjuntar archivos, usa el chat.",
|
|
487
|
+
askBusy: "Podr\xE1s preguntar cuando la respuesta actual est\xE9 lista.",
|
|
488
|
+
askUnavailable: "El chat no est\xE1 disponible en este momento.",
|
|
489
|
+
gettingAnswer: "Obteniendo la respuesta\u2026",
|
|
490
|
+
startWhenReady: "Iniciar cuando est\xE9 lista",
|
|
491
|
+
armed: "El avatar empezar\xE1 cuando la respuesta est\xE9 lista.",
|
|
492
|
+
cancel: "Cancelar",
|
|
493
|
+
armedCancelled: "El avatar no se ha iniciado. Pulsa Iniciar cuando est\xE9 lista para volver a intentarlo.",
|
|
494
|
+
notSpoken: "Esta respuesta se queda en el chat como texto. El avatar solo lee respuestas que superan sus comprobaciones de voz.",
|
|
495
|
+
answerFailed: "El asistente no pudo responder. Vuelve a preguntar.",
|
|
496
|
+
declined: "De acuerdo. La respuesta est\xE1 en el chat.",
|
|
497
|
+
askHere: "Para escuchar una respuesta, pregunta aqu\xED.",
|
|
498
|
+
newChatForAvatar: "Chat nuevo para el avatar",
|
|
499
|
+
newChatNote: "Tu chat actual se queda en el historial.",
|
|
500
|
+
newChatStarted: "Se ha iniciado un chat nuevo para el avatar.",
|
|
501
|
+
readInChat: "Leer la respuesta y las fuentes en el chat",
|
|
502
|
+
usedToday: "Ya has usado la sesi\xF3n de avatar de hoy. Las respuestas se mostrar\xE1n aqu\xED como texto.",
|
|
503
|
+
needsAnswerAny: "Haz una pregunta aqu\xED y el avatar leer\xE1 la respuesta en voz alta.",
|
|
504
|
+
startNewChatDetailAny: "El avatar solo lee en voz alta la primera respuesta de un chat nuevo iniciado en la pesta\xF1a Avatar, si supera las comprobaciones de voz.",
|
|
505
|
+
notEligibleAny: "El avatar no puede leer esta respuesta en voz alta. La respuesta y las fuentes est\xE1n en el chat."
|
|
393
506
|
};
|
|
394
507
|
var AR = {
|
|
395
508
|
checking: "\u062C\u0627\u0631\u064D \u0627\u0644\u062A\u062D\u0642\u0642 \u0645\u0646 \u062A\u0648\u0641\u0631 \u0627\u0644\u0623\u0641\u0627\u062A\u0627\u0631 \u0627\u0644\u0645\u0628\u0627\u0634\u0631\u2026",
|
|
@@ -423,7 +536,32 @@ var AR = {
|
|
|
423
536
|
paused: "\u0627\u0644\u0623\u0641\u0627\u062A\u0627\u0631 \u0627\u0644\u0645\u0628\u0627\u0634\u0631 \u0645\u062A\u0648\u0642\u0641 \u0645\u0624\u0642\u062A\u064B\u0627 \u0627\u0644\u0622\u0646.",
|
|
424
537
|
// TRANSLATION REVIEW PENDING (BOFF-9797): draft.
|
|
425
538
|
notEligible: "\u064A\u0642\u0631\u0623 \u0627\u0644\u0623\u0641\u0627\u062A\u0627\u0631 \u0627\u0644\u0625\u062C\u0627\u0628\u0629 \u0627\u0644\u0623\u0648\u0644\u0649 \u0639\u0646 \u0633\u0624\u0627\u0644 \u0645\u0642\u062A\u0631\u062D\u060C \u062E\u0644\u0627\u0644 \u062E\u0645\u0633 \u0639\u0634\u0631\u0629 \u062F\u0642\u064A\u0642\u0629. \u0627\u0628\u062F\u0623 \u062F\u0631\u062F\u0634\u0629 \u062C\u062F\u064A\u062F\u0629 \u0648\u0627\u062E\u062A\u0631 \u0633\u0624\u0627\u0644\u064B\u0627 \u0645\u0642\u062A\u0631\u062D\u064B\u0627.",
|
|
426
|
-
answerClaimed: "\u0642\u0631\u0623 \u0627\u0644\u0623\u0641\u0627\u062A\u0627\u0631 \u0647\u0630\u0647 \u0627\u0644\u0625\u062C\u0627\u0628\u0629 \u0645\u0646 \u0642\u0628\u0644."
|
|
539
|
+
answerClaimed: "\u0642\u0631\u0623 \u0627\u0644\u0623\u0641\u0627\u062A\u0627\u0631 \u0647\u0630\u0647 \u0627\u0644\u0625\u062C\u0627\u0628\u0629 \u0645\u0646 \u0642\u0628\u0644.",
|
|
540
|
+
// TRANSLATION REVIEW PENDING (BOFF-9797): draft, the Avatar tab's question box.
|
|
541
|
+
askHeadline: "\u0627\u0637\u0631\u062D \u0633\u0624\u0627\u0644\u064B\u0627\u060C \u0648\u0633\u064A\u0642\u0631\u0623 \u0627\u0644\u0623\u0641\u0627\u062A\u0627\u0631 \u0627\u0644\u0625\u062C\u0627\u0628\u0629 \u0628\u0635\u0648\u062A \u0639\u0627\u0644\u064D.",
|
|
542
|
+
askLabel: "\u0633\u0624\u0627\u0644 \u0644\u0644\u0623\u0641\u0627\u062A\u0627\u0631",
|
|
543
|
+
askPlaceholder: "\u0627\u0633\u0623\u0644 \u0627\u0644\u0623\u0641\u0627\u062A\u0627\u0631\u2026",
|
|
544
|
+
askFooter: "\u0627\u0644\u0625\u062C\u0627\u0628\u0627\u062A \u0645\u064F\u0648\u0644\u064E\u0651\u062F\u0629 \u0628\u0627\u0644\u0630\u0643\u0627\u0621 \u0627\u0644\u0627\u0635\u0637\u0646\u0627\u0639\u064A \u0648\u0642\u062F \u062A\u0643\u0648\u0646 \u062E\u0627\u0637\u0626\u0629. \u0644\u0627 \u062A\u0636\u0645\u0651\u0646 \u0628\u064A\u0627\u0646\u0627\u062A \u0634\u062E\u0635\u064A\u0629.",
|
|
545
|
+
askNoFiles: "\u0644\u0625\u0631\u0641\u0627\u0642 \u0645\u0644\u0641\u0627\u062A\u060C \u0627\u0633\u062A\u062E\u062F\u0645 \u0627\u0644\u062F\u0631\u062F\u0634\u0629.",
|
|
546
|
+
askBusy: "\u064A\u0645\u0643\u0646\u0643 \u0627\u0644\u0633\u0624\u0627\u0644 \u0639\u0646\u062F\u0645\u0627 \u062A\u0635\u0628\u062D \u0627\u0644\u0625\u062C\u0627\u0628\u0629 \u0627\u0644\u062D\u0627\u0644\u064A\u0629 \u062C\u0627\u0647\u0632\u0629.",
|
|
547
|
+
askUnavailable: "\u0627\u0644\u062F\u0631\u062F\u0634\u0629 \u063A\u064A\u0631 \u0645\u062A\u0627\u062D\u0629 \u0627\u0644\u0622\u0646.",
|
|
548
|
+
gettingAnswer: "\u062C\u0627\u0631\u064D \u0627\u0644\u062D\u0635\u0648\u0644 \u0639\u0644\u0649 \u0627\u0644\u0625\u062C\u0627\u0628\u0629\u2026",
|
|
549
|
+
startWhenReady: "\u0627\u0644\u0628\u062F\u0621 \u0639\u0646\u062F \u0627\u0644\u062C\u0627\u0647\u0632\u064A\u0629",
|
|
550
|
+
armed: "\u0633\u064A\u0628\u062F\u0623 \u0627\u0644\u0623\u0641\u0627\u062A\u0627\u0631 \u0639\u0646\u062F\u0645\u0627 \u062A\u0635\u0628\u062D \u0627\u0644\u0625\u062C\u0627\u0628\u0629 \u062C\u0627\u0647\u0632\u0629.",
|
|
551
|
+
cancel: "\u0625\u0644\u063A\u0627\u0621",
|
|
552
|
+
armedCancelled: "\u0644\u0645 \u064A\u0628\u062F\u0623 \u0627\u0644\u0623\u0641\u0627\u062A\u0627\u0631. \u0627\u0636\u063A\u0637 \u0639\u0644\u0649 \u0627\u0644\u0628\u062F\u0621 \u0639\u0646\u062F \u0627\u0644\u062C\u0627\u0647\u0632\u064A\u0629 \u0644\u0644\u0645\u062D\u0627\u0648\u0644\u0629 \u0645\u0631\u0629 \u0623\u062E\u0631\u0649.",
|
|
553
|
+
notSpoken: "\u062A\u0628\u0642\u0649 \u0647\u0630\u0647 \u0627\u0644\u0625\u062C\u0627\u0628\u0629 \u0641\u064A \u0627\u0644\u062F\u0631\u062F\u0634\u0629 \u0646\u0635\u064B\u0627. \u064A\u0642\u0631\u0623 \u0627\u0644\u0623\u0641\u0627\u062A\u0627\u0631 \u0641\u0642\u0637 \u0627\u0644\u0625\u062C\u0627\u0628\u0627\u062A \u0627\u0644\u062A\u064A \u062A\u062C\u062A\u0627\u0632 \u0641\u062D\u0648\u0635 \u0627\u0644\u0646\u0637\u0642.",
|
|
554
|
+
answerFailed: "\u062A\u0639\u0630\u0651\u0631 \u0639\u0644\u0649 \u0627\u0644\u0645\u0633\u0627\u0639\u062F \u0627\u0644\u0625\u062C\u0627\u0628\u0629. \u062D\u0627\u0648\u0644 \u0627\u0644\u0633\u0624\u0627\u0644 \u0645\u0631\u0629 \u0623\u062E\u0631\u0649.",
|
|
555
|
+
declined: "\u0644\u0627 \u0628\u0623\u0633. \u0627\u0644\u0625\u062C\u0627\u0628\u0629 \u0645\u0648\u062C\u0648\u062F\u0629 \u0641\u064A \u0627\u0644\u062F\u0631\u062F\u0634\u0629.",
|
|
556
|
+
askHere: "\u0644\u0633\u0645\u0627\u0639 \u0625\u062C\u0627\u0628\u0629\u060C \u0627\u0633\u0623\u0644 \u0647\u0646\u0627.",
|
|
557
|
+
newChatForAvatar: "\u062F\u0631\u062F\u0634\u0629 \u062C\u062F\u064A\u062F\u0629 \u0644\u0644\u0623\u0641\u0627\u062A\u0627\u0631",
|
|
558
|
+
newChatNote: "\u062A\u0628\u0642\u0649 \u062F\u0631\u062F\u0634\u062A\u0643 \u0627\u0644\u062D\u0627\u0644\u064A\u0629 \u0641\u064A \u0627\u0644\u0633\u062C\u0644.",
|
|
559
|
+
newChatStarted: "\u0628\u062F\u0623\u062A \u062F\u0631\u062F\u0634\u0629 \u062C\u062F\u064A\u062F\u0629 \u0644\u0644\u0623\u0641\u0627\u062A\u0627\u0631.",
|
|
560
|
+
readInChat: "\u0627\u0642\u0631\u0623 \u0627\u0644\u0625\u062C\u0627\u0628\u0629 \u0648\u0627\u0644\u0645\u0635\u0627\u062F\u0631 \u0641\u064A \u0627\u0644\u062F\u0631\u062F\u0634\u0629",
|
|
561
|
+
usedToday: "\u0644\u0642\u062F \u0627\u0633\u062A\u062E\u062F\u0645\u062A \u062C\u0644\u0633\u0629 \u0627\u0644\u0623\u0641\u0627\u062A\u0627\u0631 \u0644\u0647\u0630\u0627 \u0627\u0644\u064A\u0648\u0645. \u0633\u062A\u0638\u0647\u0631 \u0627\u0644\u0625\u062C\u0627\u0628\u0627\u062A \u0647\u0646\u0627 \u0646\u0635\u064B\u0627.",
|
|
562
|
+
needsAnswerAny: "\u0627\u0637\u0631\u062D \u0633\u0624\u0627\u0644\u064B\u0627 \u0647\u0646\u0627\u060C \u0648\u0633\u064A\u0642\u0631\u0623 \u0627\u0644\u0623\u0641\u0627\u062A\u0627\u0631 \u0627\u0644\u0625\u062C\u0627\u0628\u0629 \u0628\u0635\u0648\u062A \u0639\u0627\u0644\u064D.",
|
|
563
|
+
startNewChatDetailAny: "\u064A\u0642\u0631\u0623 \u0627\u0644\u0623\u0641\u0627\u062A\u0627\u0631 \u0628\u0635\u0648\u062A \u0639\u0627\u0644\u064D \u0627\u0644\u0625\u062C\u0627\u0628\u0629 \u0627\u0644\u0623\u0648\u0644\u0649 \u0641\u0642\u0637 \u0641\u064A \u062F\u0631\u062F\u0634\u0629 \u062C\u062F\u064A\u062F\u0629 \u0628\u062F\u0623\u062A \u0641\u064A \u0639\u0644\u0627\u0645\u0629 \u062A\u0628\u0648\u064A\u0628 \u0627\u0644\u0623\u0641\u0627\u062A\u0627\u0631\u060C \u0628\u0634\u0631\u0637 \u0623\u0646 \u062A\u062C\u062A\u0627\u0632 \u0641\u062D\u0648\u0635 \u0627\u0644\u0646\u0637\u0642.",
|
|
564
|
+
notEligibleAny: "\u0644\u0627 \u064A\u0645\u0643\u0646 \u0644\u0644\u0623\u0641\u0627\u062A\u0627\u0631 \u0642\u0631\u0627\u0621\u0629 \u0647\u0630\u0647 \u0627\u0644\u0625\u062C\u0627\u0628\u0629 \u0628\u0635\u0648\u062A \u0639\u0627\u0644\u064D. \u0627\u0644\u0625\u062C\u0627\u0628\u0629 \u0648\u0627\u0644\u0645\u0635\u0627\u062F\u0631 \u0645\u0648\u062C\u0648\u062F\u0629 \u0641\u064A \u0627\u0644\u062F\u0631\u062F\u0634\u0629."
|
|
427
565
|
};
|
|
428
566
|
var TA = {
|
|
429
567
|
checking: "\u0BA8\u0BC7\u0BB0\u0BB2\u0BC8 \u0B85\u0BB5\u0BA4\u0BBE\u0BB0\u0BCD \u0B95\u0BBF\u0B9F\u0BC8\u0B95\u0BCD\u0B95\u0BBF\u0BB1\u0BA4\u0BBE \u0B8E\u0BA9\u0B9A\u0BCD \u0B9A\u0BB0\u0BBF\u0BAA\u0BBE\u0BB0\u0BCD\u0B95\u0BCD\u0B95\u0BBF\u0BB1\u0BA4\u0BC1\u2026",
|
|
@@ -457,7 +595,32 @@ var TA = {
|
|
|
457
595
|
paused: "\u0BA8\u0BC7\u0BB0\u0BB2\u0BC8 \u0B85\u0BB5\u0BA4\u0BBE\u0BB0\u0BCD \u0B87\u0BAA\u0BCD\u0BAA\u0BCB\u0BA4\u0BC1 \u0B87\u0B9F\u0BC8\u0BA8\u0BBF\u0BB1\u0BC1\u0BA4\u0BCD\u0BA4\u0BAA\u0BCD\u0BAA\u0B9F\u0BCD\u0B9F\u0BC1\u0BB3\u0BCD\u0BB3\u0BA4\u0BC1.",
|
|
458
596
|
// TRANSLATION REVIEW PENDING (BOFF-9797): draft.
|
|
459
597
|
notEligible: "\u0BAA\u0BB0\u0BBF\u0BA8\u0BCD\u0BA4\u0BC1\u0BB0\u0BC8\u0B95\u0BCD\u0B95\u0BAA\u0BCD\u0BAA\u0B9F\u0BCD\u0B9F \u0B95\u0BC7\u0BB3\u0BCD\u0BB5\u0BBF\u0B95\u0BCD\u0B95\u0BBE\u0BA9 \u0BAE\u0BC1\u0BA4\u0BB2\u0BCD \u0BAA\u0BA4\u0BBF\u0BB2\u0BC8 \u0BAE\u0B9F\u0BCD\u0B9F\u0BC1\u0BAE\u0BC7, \u0BAA\u0BA4\u0BBF\u0BA9\u0BC8\u0BA8\u0BCD\u0BA4\u0BC1 \u0BA8\u0BBF\u0BAE\u0BBF\u0B9F\u0B99\u0BCD\u0B95\u0BB3\u0BC1\u0B95\u0BCD\u0B95\u0BC1\u0BB3\u0BCD, \u0B85\u0BB5\u0BA4\u0BBE\u0BB0\u0BCD \u0BAA\u0B9F\u0BBF\u0B95\u0BCD\u0B95\u0BC1\u0BAE\u0BCD. \u0BAA\u0BC1\u0BA4\u0BBF\u0BAF \u0B85\u0BB0\u0B9F\u0BCD\u0B9F\u0BC8\u0BAF\u0BC8\u0BA4\u0BCD \u0BA4\u0BCA\u0B9F\u0B99\u0BCD\u0B95\u0BBF, \u0BAA\u0BB0\u0BBF\u0BA8\u0BCD\u0BA4\u0BC1\u0BB0\u0BC8\u0B95\u0BCD\u0B95\u0BAA\u0BCD\u0BAA\u0B9F\u0BCD\u0B9F \u0B92\u0BB0\u0BC1 \u0B95\u0BC7\u0BB3\u0BCD\u0BB5\u0BBF\u0BAF\u0BC8\u0BA4\u0BCD \u0BA4\u0BC7\u0BB0\u0BCD\u0BA8\u0BCD\u0BA4\u0BC6\u0B9F\u0BC1\u0B95\u0BCD\u0B95\u0BB5\u0BC1\u0BAE\u0BCD.",
|
|
460
|
-
answerClaimed: "\u0B87\u0BA8\u0BCD\u0BA4\u0BAA\u0BCD \u0BAA\u0BA4\u0BBF\u0BB2\u0BC8 \u0B85\u0BB5\u0BA4\u0BBE\u0BB0\u0BCD \u0B8F\u0BB1\u0BCD\u0B95\u0BC6\u0BA9\u0BB5\u0BC7 \u0BAA\u0B9F\u0BBF\u0BA4\u0BCD\u0BA4\u0BC1\u0BB5\u0BBF\u0B9F\u0BCD\u0B9F\u0BA4\u0BC1."
|
|
598
|
+
answerClaimed: "\u0B87\u0BA8\u0BCD\u0BA4\u0BAA\u0BCD \u0BAA\u0BA4\u0BBF\u0BB2\u0BC8 \u0B85\u0BB5\u0BA4\u0BBE\u0BB0\u0BCD \u0B8F\u0BB1\u0BCD\u0B95\u0BC6\u0BA9\u0BB5\u0BC7 \u0BAA\u0B9F\u0BBF\u0BA4\u0BCD\u0BA4\u0BC1\u0BB5\u0BBF\u0B9F\u0BCD\u0B9F\u0BA4\u0BC1.",
|
|
599
|
+
// TRANSLATION REVIEW PENDING (BOFF-9797): draft, the Avatar tab's question box.
|
|
600
|
+
askHeadline: "\u0B92\u0BB0\u0BC1 \u0B95\u0BC7\u0BB3\u0BCD\u0BB5\u0BBF\u0BAF\u0BC8\u0B95\u0BCD \u0B95\u0BC7\u0BB3\u0BC1\u0B99\u0BCD\u0B95\u0BB3\u0BCD, \u0B85\u0BB5\u0BA4\u0BBE\u0BB0\u0BCD \u0BAA\u0BA4\u0BBF\u0BB2\u0BC8 \u0B89\u0BB0\u0B95\u0BCD\u0B95\u0BAA\u0BCD \u0BAA\u0B9F\u0BBF\u0B95\u0BCD\u0B95\u0BC1\u0BAE\u0BCD.",
|
|
601
|
+
askLabel: "\u0B85\u0BB5\u0BA4\u0BBE\u0BB0\u0BC1\u0B95\u0BCD\u0B95\u0BBE\u0BA9 \u0B95\u0BC7\u0BB3\u0BCD\u0BB5\u0BBF",
|
|
602
|
+
askPlaceholder: "\u0B85\u0BB5\u0BA4\u0BBE\u0BB0\u0BBF\u0B9F\u0BAE\u0BCD \u0B95\u0BC7\u0BB3\u0BC1\u0B99\u0BCD\u0B95\u0BB3\u0BCD\u2026",
|
|
603
|
+
askFooter: "\u0BAA\u0BA4\u0BBF\u0BB2\u0BCD\u0B95\u0BB3\u0BCD AI \u0B89\u0BB0\u0BC1\u0BB5\u0BBE\u0B95\u0BCD\u0B95\u0BBF\u0BAF\u0BB5\u0BC8, \u0BA4\u0BB5\u0BB1\u0BBE\u0B95 \u0B87\u0BB0\u0BC1\u0B95\u0BCD\u0B95\u0BB2\u0BBE\u0BAE\u0BCD. \u0BA4\u0BA9\u0BBF\u0BAA\u0BCD\u0BAA\u0B9F\u0BCD\u0B9F \u0BB5\u0BBF\u0BB5\u0BB0\u0B99\u0BCD\u0B95\u0BB3\u0BC8\u0B9A\u0BCD \u0B9A\u0BC7\u0BB0\u0BCD\u0B95\u0BCD\u0B95 \u0BB5\u0BC7\u0BA3\u0BCD\u0B9F\u0BBE\u0BAE\u0BCD.",
|
|
604
|
+
askNoFiles: "\u0B95\u0BCB\u0BAA\u0BCD\u0BAA\u0BC1\u0B95\u0BB3\u0BC8 \u0B87\u0BA3\u0BC8\u0B95\u0BCD\u0B95, \u0B85\u0BB0\u0B9F\u0BCD\u0B9F\u0BC8\u0BAF\u0BC8\u0BAA\u0BCD \u0BAA\u0BAF\u0BA9\u0BCD\u0BAA\u0B9F\u0BC1\u0BA4\u0BCD\u0BA4\u0BB5\u0BC1\u0BAE\u0BCD.",
|
|
605
|
+
askBusy: "\u0BA4\u0BB1\u0BCD\u0BAA\u0BCB\u0BA4\u0BC8\u0BAF \u0BAA\u0BA4\u0BBF\u0BB2\u0BCD \u0BA4\u0BAF\u0BBE\u0BB0\u0BBE\u0BA9\u0BA4\u0BC1\u0BAE\u0BCD \u0BA8\u0BC0\u0B99\u0BCD\u0B95\u0BB3\u0BCD \u0B95\u0BC7\u0B9F\u0BCD\u0B95\u0BB2\u0BBE\u0BAE\u0BCD.",
|
|
606
|
+
askUnavailable: "\u0B85\u0BB0\u0B9F\u0BCD\u0B9F\u0BC8 \u0B87\u0BAA\u0BCD\u0BAA\u0BCB\u0BA4\u0BC1 \u0B95\u0BBF\u0B9F\u0BC8\u0B95\u0BCD\u0B95\u0BB5\u0BBF\u0BB2\u0BCD\u0BB2\u0BC8.",
|
|
607
|
+
gettingAnswer: "\u0BAA\u0BA4\u0BBF\u0BB2\u0BC8\u0BAA\u0BCD \u0BAA\u0BC6\u0BB1\u0BC1\u0B95\u0BBF\u0BB1\u0BA4\u0BC1\u2026",
|
|
608
|
+
startWhenReady: "\u0BA4\u0BAF\u0BBE\u0BB0\u0BBE\u0BA9\u0BA4\u0BC1\u0BAE\u0BCD \u0BA4\u0BCA\u0B9F\u0B99\u0BCD\u0B95\u0BC1",
|
|
609
|
+
armed: "\u0BAA\u0BA4\u0BBF\u0BB2\u0BCD \u0BA4\u0BAF\u0BBE\u0BB0\u0BBE\u0BA9\u0BA4\u0BC1\u0BAE\u0BCD \u0B85\u0BB5\u0BA4\u0BBE\u0BB0\u0BCD \u0BA4\u0BCA\u0B9F\u0B99\u0BCD\u0B95\u0BC1\u0BAE\u0BCD.",
|
|
610
|
+
cancel: "\u0BB0\u0BA4\u0BCD\u0BA4\u0BC1\u0B9A\u0BC6\u0BAF\u0BCD",
|
|
611
|
+
armedCancelled: "\u0B85\u0BB5\u0BA4\u0BBE\u0BB0\u0BCD \u0BA4\u0BCA\u0B9F\u0B99\u0BCD\u0B95\u0BB5\u0BBF\u0BB2\u0BCD\u0BB2\u0BC8. \u0BAE\u0BC0\u0BA3\u0BCD\u0B9F\u0BC1\u0BAE\u0BCD \u0BAE\u0BC1\u0BAF\u0BB2, \u0BA4\u0BAF\u0BBE\u0BB0\u0BBE\u0BA9\u0BA4\u0BC1\u0BAE\u0BCD \u0BA4\u0BCA\u0B9F\u0B99\u0BCD\u0B95\u0BC1 \u0B8E\u0BA9\u0BCD\u0BAA\u0BA4\u0BC8 \u0B85\u0BB4\u0BC1\u0BA4\u0BCD\u0BA4\u0BB5\u0BC1\u0BAE\u0BCD.",
|
|
612
|
+
notSpoken: "\u0B87\u0BA8\u0BCD\u0BA4\u0BAA\u0BCD \u0BAA\u0BA4\u0BBF\u0BB2\u0BCD \u0B85\u0BB0\u0B9F\u0BCD\u0B9F\u0BC8\u0BAF\u0BBF\u0BB2\u0BCD \u0B89\u0BB0\u0BC8\u0BAF\u0BBE\u0B95\u0BB5\u0BC7 \u0B87\u0BB0\u0BC1\u0B95\u0BCD\u0B95\u0BC1\u0BAE\u0BCD. \u0BAA\u0BC7\u0B9A\u0BCD\u0B9A\u0BC1\u0B9A\u0BCD \u0B9A\u0BB0\u0BBF\u0BAA\u0BBE\u0BB0\u0BCD\u0BAA\u0BCD\u0BAA\u0BC1\u0B95\u0BB3\u0BBF\u0BB2\u0BCD \u0BA4\u0BC7\u0BB1\u0BC1\u0BAE\u0BCD \u0BAA\u0BA4\u0BBF\u0BB2\u0BCD\u0B95\u0BB3\u0BC8 \u0BAE\u0B9F\u0BCD\u0B9F\u0BC1\u0BAE\u0BC7 \u0B85\u0BB5\u0BA4\u0BBE\u0BB0\u0BCD \u0BAA\u0B9F\u0BBF\u0B95\u0BCD\u0B95\u0BC1\u0BAE\u0BCD.",
|
|
613
|
+
answerFailed: "\u0B89\u0BA4\u0BB5\u0BBF\u0BAF\u0BBE\u0BB3\u0BB0\u0BBE\u0BB2\u0BCD \u0BAA\u0BA4\u0BBF\u0BB2\u0BB3\u0BBF\u0B95\u0BCD\u0B95 \u0BAE\u0BC1\u0B9F\u0BBF\u0BAF\u0BB5\u0BBF\u0BB2\u0BCD\u0BB2\u0BC8. \u0BAE\u0BC0\u0BA3\u0BCD\u0B9F\u0BC1\u0BAE\u0BCD \u0B95\u0BC7\u0B9F\u0BCD\u0B9F\u0BC1\u0BAA\u0BCD \u0BAA\u0BBE\u0BB0\u0BC1\u0B99\u0BCD\u0B95\u0BB3\u0BCD.",
|
|
614
|
+
declined: "\u0BAA\u0BB0\u0BB5\u0BBE\u0BAF\u0BBF\u0BB2\u0BCD\u0BB2\u0BC8. \u0BAA\u0BA4\u0BBF\u0BB2\u0BCD \u0B85\u0BB0\u0B9F\u0BCD\u0B9F\u0BC8\u0BAF\u0BBF\u0BB2\u0BCD \u0B89\u0BB3\u0BCD\u0BB3\u0BA4\u0BC1.",
|
|
615
|
+
askHere: "\u0BAA\u0BA4\u0BBF\u0BB2\u0BC8\u0B95\u0BCD \u0B95\u0BC7\u0B9F\u0BCD\u0B95, \u0B87\u0B99\u0BCD\u0B95\u0BC7 \u0B95\u0BC7\u0BB3\u0BC1\u0B99\u0BCD\u0B95\u0BB3\u0BCD.",
|
|
616
|
+
newChatForAvatar: "\u0B85\u0BB5\u0BA4\u0BBE\u0BB0\u0BC1\u0B95\u0BCD\u0B95\u0BBE\u0BA9 \u0BAA\u0BC1\u0BA4\u0BBF\u0BAF \u0B85\u0BB0\u0B9F\u0BCD\u0B9F\u0BC8",
|
|
617
|
+
newChatNote: "\u0B89\u0B99\u0BCD\u0B95\u0BB3\u0BCD \u0BA4\u0BB1\u0BCD\u0BAA\u0BCB\u0BA4\u0BC8\u0BAF \u0B85\u0BB0\u0B9F\u0BCD\u0B9F\u0BC8 \u0BB5\u0BB0\u0BB2\u0BBE\u0BB1\u0BCD\u0BB1\u0BBF\u0BB2\u0BCD \u0B87\u0BB0\u0BC1\u0B95\u0BCD\u0B95\u0BC1\u0BAE\u0BCD.",
|
|
618
|
+
newChatStarted: "\u0B85\u0BB5\u0BA4\u0BBE\u0BB0\u0BC1\u0B95\u0BCD\u0B95\u0BBE\u0B95\u0BAA\u0BCD \u0BAA\u0BC1\u0BA4\u0BBF\u0BAF \u0B85\u0BB0\u0B9F\u0BCD\u0B9F\u0BC8 \u0BA4\u0BCA\u0B9F\u0B99\u0BCD\u0B95\u0BAA\u0BCD\u0BAA\u0B9F\u0BCD\u0B9F\u0BA4\u0BC1.",
|
|
619
|
+
readInChat: "\u0BAA\u0BA4\u0BBF\u0BB2\u0BC8\u0BAF\u0BC1\u0BAE\u0BCD \u0B86\u0BA4\u0BBE\u0BB0\u0B99\u0BCD\u0B95\u0BB3\u0BC8\u0BAF\u0BC1\u0BAE\u0BCD \u0B85\u0BB0\u0B9F\u0BCD\u0B9F\u0BC8\u0BAF\u0BBF\u0BB2\u0BCD \u0BAA\u0B9F\u0BBF\u0B95\u0BCD\u0B95\u0BB5\u0BC1\u0BAE\u0BCD",
|
|
620
|
+
usedToday: "\u0B87\u0BA9\u0BCD\u0BB1\u0BC8\u0BAF \u0B85\u0BB5\u0BA4\u0BBE\u0BB0\u0BCD \u0B85\u0BAE\u0BB0\u0BCD\u0BB5\u0BC8 \u0BA8\u0BC0\u0B99\u0BCD\u0B95\u0BB3\u0BCD \u0BAA\u0BAF\u0BA9\u0BCD\u0BAA\u0B9F\u0BC1\u0BA4\u0BCD\u0BA4\u0BBF\u0BB5\u0BBF\u0B9F\u0BCD\u0B9F\u0BC0\u0BB0\u0BCD\u0B95\u0BB3\u0BCD. \u0BAA\u0BA4\u0BBF\u0BB2\u0BCD\u0B95\u0BB3\u0BCD \u0B87\u0B99\u0BCD\u0B95\u0BC7 \u0B89\u0BB0\u0BC8\u0BAF\u0BBE\u0B95\u0B95\u0BCD \u0B95\u0BBE\u0B9F\u0BCD\u0B9F\u0BAA\u0BCD\u0BAA\u0B9F\u0BC1\u0BAE\u0BCD.",
|
|
621
|
+
needsAnswerAny: "\u0B87\u0B99\u0BCD\u0B95\u0BC7 \u0B92\u0BB0\u0BC1 \u0B95\u0BC7\u0BB3\u0BCD\u0BB5\u0BBF\u0BAF\u0BC8\u0B95\u0BCD \u0B95\u0BC7\u0BB3\u0BC1\u0B99\u0BCD\u0B95\u0BB3\u0BCD, \u0B85\u0BB5\u0BA4\u0BBE\u0BB0\u0BCD \u0BAA\u0BA4\u0BBF\u0BB2\u0BC8 \u0B89\u0BB0\u0B95\u0BCD\u0B95\u0BAA\u0BCD \u0BAA\u0B9F\u0BBF\u0B95\u0BCD\u0B95\u0BC1\u0BAE\u0BCD.",
|
|
622
|
+
startNewChatDetailAny: "\u0B85\u0BB5\u0BA4\u0BBE\u0BB0\u0BCD \u0BA4\u0BBE\u0BB5\u0BB2\u0BBF\u0BB2\u0BCD \u0BA4\u0BCA\u0B9F\u0B99\u0BCD\u0B95\u0BBF\u0BAF \u0BAA\u0BC1\u0BA4\u0BBF\u0BAF \u0B85\u0BB0\u0B9F\u0BCD\u0B9F\u0BC8\u0BAF\u0BBF\u0BA9\u0BCD \u0BAE\u0BC1\u0BA4\u0BB2\u0BCD \u0BAA\u0BA4\u0BBF\u0BB2\u0BC8 \u0BAE\u0B9F\u0BCD\u0B9F\u0BC1\u0BAE\u0BC7, \u0B85\u0BA4\u0BC1 \u0BAA\u0BC7\u0B9A\u0BCD\u0B9A\u0BC1\u0B9A\u0BCD \u0B9A\u0BB0\u0BBF\u0BAA\u0BBE\u0BB0\u0BCD\u0BAA\u0BCD\u0BAA\u0BC1\u0B95\u0BB3\u0BBF\u0BB2\u0BCD \u0BA4\u0BC7\u0BB1\u0BBF\u0BA9\u0BBE\u0BB2\u0BCD, \u0B85\u0BB5\u0BA4\u0BBE\u0BB0\u0BCD \u0B89\u0BB0\u0B95\u0BCD\u0B95\u0BAA\u0BCD \u0BAA\u0B9F\u0BBF\u0B95\u0BCD\u0B95\u0BC1\u0BAE\u0BCD.",
|
|
623
|
+
notEligibleAny: "\u0B87\u0BA8\u0BCD\u0BA4\u0BAA\u0BCD \u0BAA\u0BA4\u0BBF\u0BB2\u0BC8 \u0B85\u0BB5\u0BA4\u0BBE\u0BB0\u0BBE\u0BB2\u0BCD \u0B89\u0BB0\u0B95\u0BCD\u0B95\u0BAA\u0BCD \u0BAA\u0B9F\u0BBF\u0B95\u0BCD\u0B95 \u0BAE\u0BC1\u0B9F\u0BBF\u0BAF\u0BBE\u0BA4\u0BC1. \u0BAA\u0BA4\u0BBF\u0BB2\u0BC1\u0BAE\u0BCD \u0B86\u0BA4\u0BBE\u0BB0\u0B99\u0BCD\u0B95\u0BB3\u0BC1\u0BAE\u0BCD \u0B85\u0BB0\u0B9F\u0BCD\u0B9F\u0BC8\u0BAF\u0BBF\u0BB2\u0BCD \u0B89\u0BB3\u0BCD\u0BB3\u0BA9."
|
|
461
624
|
};
|
|
462
625
|
var STRINGS = {
|
|
463
626
|
en: EN,
|
|
@@ -481,7 +644,8 @@ var CONSENT = /* @__PURE__ */ new Map([
|
|
|
481
644
|
processing: "When you start, Cloudflare checks for bots. The answer text goes to Google to create the voice. Your browser connects to LiveKit, which sees your IP address. LiveKit fetches our temporary audio file and passes the voice to Protoface, which makes the avatar video streamed through LiveKit.",
|
|
482
645
|
storage: "Your microphone and camera are not used. We do not record the live session. We temporarily store the generated voice file and keep a record of this consent. The privacy notice explains our safeguards, storage periods and the providers' processing. For people aged eighteen and over.",
|
|
483
646
|
privacyLink: "How we handle this",
|
|
484
|
-
botCheck: "turnstile"
|
|
647
|
+
botCheck: "turnstile",
|
|
648
|
+
questions: "suggested"
|
|
485
649
|
}
|
|
486
650
|
}
|
|
487
651
|
],
|
|
@@ -496,7 +660,8 @@ var CONSENT = /* @__PURE__ */ new Map([
|
|
|
496
660
|
processing: "When you start, Cloudflare checks for bots. The answer text goes to Google to create the voice. Our server sends that voice through LiveKit to Protoface, which makes the avatar video streamed through LiveKit. Your browser connects to LiveKit, which sees your IP address.",
|
|
497
661
|
storage: "Your microphone and camera are not used. We do not record the live session or store the generated voice. We keep a record of this consent. The privacy notice explains our safeguards, storage periods and the providers' processing. For people aged eighteen and over.",
|
|
498
662
|
privacyLink: "How we handle this",
|
|
499
|
-
botCheck: "turnstile"
|
|
663
|
+
botCheck: "turnstile",
|
|
664
|
+
questions: "suggested"
|
|
500
665
|
}
|
|
501
666
|
}
|
|
502
667
|
],
|
|
@@ -512,7 +677,8 @@ var CONSENT = /* @__PURE__ */ new Map([
|
|
|
512
677
|
processing: "When you start, Cloudflare checks for bots. The answer text goes to Google to create the voice. Our server sends that voice through LiveKit to Protoface, which makes the avatar video streamed through LiveKit. Your browser connects to LiveKit, which sees your IP address.",
|
|
513
678
|
storage: "Your microphone and camera are not used. We do not record the live session or store the generated voice. We keep a record of this consent. The privacy notice explains our safeguards, storage periods and the providers' processing. For people aged eighteen and over.",
|
|
514
679
|
privacyLink: "How we handle this",
|
|
515
|
-
botCheck: "turnstile"
|
|
680
|
+
botCheck: "turnstile",
|
|
681
|
+
questions: "suggested"
|
|
516
682
|
}
|
|
517
683
|
}
|
|
518
684
|
],
|
|
@@ -528,13 +694,50 @@ var CONSENT = /* @__PURE__ */ new Map([
|
|
|
528
694
|
processing: "The answer text goes to Google to create the voice. Our server sends that voice through LiveKit to Protoface, which makes the avatar video streamed through LiveKit. Your browser connects to LiveKit, which sees your IP address.",
|
|
529
695
|
storage: "Your microphone and camera are not used. We do not record the live session or store the generated voice. We keep a record of this consent. The privacy notice explains our safeguards, storage periods and the providers' processing. For people aged eighteen and over.",
|
|
530
696
|
privacyLink: "How we handle this",
|
|
531
|
-
botCheck: "off"
|
|
697
|
+
botCheck: "off",
|
|
698
|
+
questions: "suggested"
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
],
|
|
702
|
+
[
|
|
703
|
+
// The Avatar tab's own question box (contract v1.3, `questions: "any"`): the first answer in a new chat started in
|
|
704
|
+
// the Avatar tab is read whether the visitor chose a suggested question or typed their own, so the intro says so and
|
|
705
|
+
// warns against personal details in a typed one. Product-neutral, with the bot check: one notice and one digest for
|
|
706
|
+
// every site (gitops docs/avatar-web/en-web-consent-2026-11-05.txt).
|
|
707
|
+
"web-consent-2026-11-05",
|
|
708
|
+
{
|
|
709
|
+
en: {
|
|
710
|
+
title: "Live AI avatar (beta)",
|
|
711
|
+
introProduct: null,
|
|
712
|
+
intro: "This is an AI avatar, not a real person. It reads aloud, for up to a minute, the first answer in a new chat started in the Avatar tab, provided it passes the speech checks, whether you chose a suggested question or typed your own. The answer is AI-generated and can be wrong. Don't put personal details in a question you type.",
|
|
713
|
+
processing: "When you start, Cloudflare checks for bots. The answer text goes to Google to create the voice. Our server sends that voice through LiveKit to Protoface, which makes the avatar video streamed through LiveKit. Your browser connects to LiveKit, which sees your IP address.",
|
|
714
|
+
storage: "Your microphone and camera are not used. We do not record the live session or store the generated voice. We keep a record of this consent. The privacy notice explains our safeguards, storage periods and the providers' processing. For people aged eighteen and over.",
|
|
715
|
+
privacyLink: "How we handle this",
|
|
716
|
+
botCheck: "turnstile",
|
|
717
|
+
questions: "any"
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
],
|
|
721
|
+
[
|
|
722
|
+
// The words of web-consent-2026-11-05 without "When you start, Cloudflare checks for bots.", for a server that runs
|
|
723
|
+
// no bot check (gitops docs/avatar-web/en-web-consent-2026-11-06.txt).
|
|
724
|
+
"web-consent-2026-11-06",
|
|
725
|
+
{
|
|
726
|
+
en: {
|
|
727
|
+
title: "Live AI avatar (beta)",
|
|
728
|
+
introProduct: null,
|
|
729
|
+
intro: "This is an AI avatar, not a real person. It reads aloud, for up to a minute, the first answer in a new chat started in the Avatar tab, provided it passes the speech checks, whether you chose a suggested question or typed your own. The answer is AI-generated and can be wrong. Don't put personal details in a question you type.",
|
|
730
|
+
processing: "The answer text goes to Google to create the voice. Our server sends that voice through LiveKit to Protoface, which makes the avatar video streamed through LiveKit. Your browser connects to LiveKit, which sees your IP address.",
|
|
731
|
+
storage: "Your microphone and camera are not used. We do not record the live session or store the generated voice. We keep a record of this consent. The privacy notice explains our safeguards, storage periods and the providers' processing. For people aged eighteen and over.",
|
|
732
|
+
privacyLink: "How we handle this",
|
|
733
|
+
botCheck: "off",
|
|
734
|
+
questions: "any"
|
|
532
735
|
}
|
|
533
736
|
}
|
|
534
737
|
]
|
|
535
738
|
]);
|
|
536
739
|
function avatarConsentCopy(version, locale) {
|
|
537
|
-
if (!
|
|
740
|
+
if (!chunk7O2I32ZN_js.isAvatarLiveLocaleReviewed(locale)) return null;
|
|
538
741
|
return CONSENT.get(version)?.[locale] ?? null;
|
|
539
742
|
}
|
|
540
743
|
|
|
@@ -659,6 +862,9 @@ var CLOCK_TOLERANCE_MS = 5e3;
|
|
|
659
862
|
var SERVICE_MAX_AGE_MS = 15 * 6e4;
|
|
660
863
|
var ANSWER_OFFER_MS = SERVICE_MAX_AGE_MS - 6e4;
|
|
661
864
|
var MAX_TIMER_MS = 2147483647;
|
|
865
|
+
var ASK_MAX_LENGTH = 300;
|
|
866
|
+
var MAX_REFERENCES = 64;
|
|
867
|
+
var USED_ON_KEY = "boff.explore.avatarUsedOn";
|
|
662
868
|
var PRIMARY = '[data-avatar-primary], [data-boff-explore="panel-continue-chat"]';
|
|
663
869
|
var IDLE = { name: "idle" };
|
|
664
870
|
var INERT2 = { name: "inert" };
|
|
@@ -671,12 +877,26 @@ var REFUSAL_TEXT = {
|
|
|
671
877
|
not_eligible: "notEligible",
|
|
672
878
|
answer_claimed: "answerClaimed"
|
|
673
879
|
};
|
|
674
|
-
var
|
|
675
|
-
|
|
880
|
+
var EMPTY = {
|
|
881
|
+
kind: "empty",
|
|
676
882
|
answerId: null,
|
|
677
|
-
startOver:
|
|
678
|
-
offerUntil: NaN
|
|
883
|
+
startOver: false,
|
|
884
|
+
offerUntil: NaN,
|
|
885
|
+
question: null,
|
|
886
|
+
pendingAnswerId: null,
|
|
887
|
+
askedHere: false
|
|
888
|
+
};
|
|
889
|
+
var START_OVER = { ...EMPTY, kind: "start-over", startOver: true };
|
|
890
|
+
var SUGGESTED_RULES = {
|
|
891
|
+
any: false,
|
|
892
|
+
askedHere: null,
|
|
893
|
+
token: null,
|
|
894
|
+
inFlight: false
|
|
679
895
|
};
|
|
896
|
+
function isAskedHere(question, rules) {
|
|
897
|
+
const asked = rules.askedHere;
|
|
898
|
+
return rules.any && asked !== null && question.id === asked.messageId && asked.token === rules.token;
|
|
899
|
+
}
|
|
680
900
|
function createdAtOf(message) {
|
|
681
901
|
const raw = message.createdAt;
|
|
682
902
|
return typeof raw === "string" && raw !== "" ? Date.parse(raw) : NaN;
|
|
@@ -684,25 +904,110 @@ function createdAtOf(message) {
|
|
|
684
904
|
function offeredAt(exchange, now) {
|
|
685
905
|
return exchange.answerId !== null && !(now < exchange.offerUntil) ? START_OVER : exchange;
|
|
686
906
|
}
|
|
687
|
-
function
|
|
688
|
-
|
|
907
|
+
function readable(question, answer) {
|
|
908
|
+
const references = answer.references?.length ?? 0;
|
|
909
|
+
return answer.answered === true && references >= 1 && references <= MAX_REFERENCES && (question.attachments?.length ?? 0) === 0;
|
|
910
|
+
}
|
|
911
|
+
function firstExchange(messages, rules = SUGGESTED_RULES) {
|
|
912
|
+
if (!messages || messages.length === 0) return EMPTY;
|
|
689
913
|
if (messages.length > 2) return START_OVER;
|
|
690
914
|
const [question, answer] = messages;
|
|
691
915
|
if (question?.role !== "USER") return START_OVER;
|
|
692
|
-
|
|
916
|
+
const first = { question, askedHere: isAskedHere(question, rules) };
|
|
917
|
+
if (answer === void 0) {
|
|
918
|
+
if (rules.inFlight) return { ...EMPTY, ...first, kind: "asking" };
|
|
919
|
+
return rules.any ? { ...START_OVER, ...first, kind: "failed" } : EMPTY;
|
|
920
|
+
}
|
|
693
921
|
if (answer.role !== "ASSISTANT") return START_OVER;
|
|
694
922
|
if (answer.status === "PENDING" || answer.status === "RUNNING") {
|
|
695
|
-
return
|
|
923
|
+
return {
|
|
924
|
+
...EMPTY,
|
|
925
|
+
...first,
|
|
926
|
+
kind: "asking",
|
|
927
|
+
pendingAnswerId: isAvatarMessageId(answer.id) ? answer.id : null
|
|
928
|
+
};
|
|
929
|
+
}
|
|
930
|
+
if (rules.any && answer.status === "FAILED") {
|
|
931
|
+
return { ...START_OVER, ...first, kind: "failed" };
|
|
696
932
|
}
|
|
697
933
|
if (answer.status !== "COMPLETED" || answer.content.trim() === "" || !isAvatarMessageId(answer.id)) {
|
|
698
934
|
return START_OVER;
|
|
699
935
|
}
|
|
936
|
+
if (rules.any && !first.askedHere) {
|
|
937
|
+
return { ...START_OVER, ...first, kind: "ask-here" };
|
|
938
|
+
}
|
|
939
|
+
if (rules.any && !readable(question, answer)) {
|
|
940
|
+
return { ...START_OVER, ...first, kind: "text-only" };
|
|
941
|
+
}
|
|
700
942
|
return {
|
|
943
|
+
...EMPTY,
|
|
944
|
+
...first,
|
|
945
|
+
kind: "answer",
|
|
701
946
|
answerId: answer.id,
|
|
702
|
-
startOver: false,
|
|
703
947
|
offerUntil: createdAtOf(answer) + ANSWER_OFFER_MS
|
|
704
948
|
};
|
|
705
949
|
}
|
|
950
|
+
function inFlight(conversation) {
|
|
951
|
+
return conversation?.phase === "sending" || conversation?.phase === "streaming";
|
|
952
|
+
}
|
|
953
|
+
function utcToday() {
|
|
954
|
+
return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
955
|
+
}
|
|
956
|
+
function usedTodayHere() {
|
|
957
|
+
try {
|
|
958
|
+
return window.localStorage.getItem(USED_ON_KEY) === utcToday();
|
|
959
|
+
} catch {
|
|
960
|
+
return false;
|
|
961
|
+
}
|
|
962
|
+
}
|
|
963
|
+
function noteUsedToday() {
|
|
964
|
+
try {
|
|
965
|
+
window.localStorage.setItem(USED_ON_KEY, utcToday());
|
|
966
|
+
} catch {
|
|
967
|
+
}
|
|
968
|
+
}
|
|
969
|
+
var silence = null;
|
|
970
|
+
function silentWav() {
|
|
971
|
+
if (silence !== null) return silence;
|
|
972
|
+
const rate = 8e3;
|
|
973
|
+
const samples = rate / 10;
|
|
974
|
+
const bytes = new Uint8Array(44 + samples);
|
|
975
|
+
const view = new DataView(bytes.buffer);
|
|
976
|
+
const text = (at, value) => {
|
|
977
|
+
for (let i = 0; i < value.length; i += 1) {
|
|
978
|
+
bytes[at + i] = value.charCodeAt(i);
|
|
979
|
+
}
|
|
980
|
+
};
|
|
981
|
+
text(0, "RIFF");
|
|
982
|
+
view.setUint32(4, 36 + samples, true);
|
|
983
|
+
text(8, "WAVE");
|
|
984
|
+
text(12, "fmt ");
|
|
985
|
+
view.setUint32(16, 16, true);
|
|
986
|
+
view.setUint16(20, 1, true);
|
|
987
|
+
view.setUint16(22, 1, true);
|
|
988
|
+
view.setUint32(24, rate, true);
|
|
989
|
+
view.setUint32(28, rate, true);
|
|
990
|
+
view.setUint16(32, 1, true);
|
|
991
|
+
view.setUint16(34, 8, true);
|
|
992
|
+
text(36, "data");
|
|
993
|
+
view.setUint32(40, samples, true);
|
|
994
|
+
bytes.fill(128, 44);
|
|
995
|
+
let binary = "";
|
|
996
|
+
for (const byte of bytes) binary += String.fromCharCode(byte);
|
|
997
|
+
silence = `data:audio/wav;base64,${btoa(binary)}`;
|
|
998
|
+
return silence;
|
|
999
|
+
}
|
|
1000
|
+
function unlockSound(audio) {
|
|
1001
|
+
if (audio === null || audio.srcObject) return;
|
|
1002
|
+
try {
|
|
1003
|
+
audio.src = silentWav();
|
|
1004
|
+
void Promise.resolve(audio.play()).then(
|
|
1005
|
+
() => audio.pause(),
|
|
1006
|
+
() => void 0
|
|
1007
|
+
);
|
|
1008
|
+
} catch {
|
|
1009
|
+
}
|
|
1010
|
+
}
|
|
706
1011
|
function offering(offer, messageId, claimed) {
|
|
707
1012
|
return claimed.has(messageId) ? { name: "refused", reason: "answer_claimed" } : { name: "consent", offer, messageId };
|
|
708
1013
|
}
|
|
@@ -721,13 +1026,20 @@ function clock(seconds) {
|
|
|
721
1026
|
function AvatarLiveView({
|
|
722
1027
|
live,
|
|
723
1028
|
active,
|
|
1029
|
+
open,
|
|
724
1030
|
locale,
|
|
725
1031
|
productName,
|
|
726
1032
|
still,
|
|
727
1033
|
fallback,
|
|
728
1034
|
onContinueInChat,
|
|
1035
|
+
onVoiceHold,
|
|
729
1036
|
continueInChat,
|
|
730
1037
|
newChat,
|
|
1038
|
+
send,
|
|
1039
|
+
tryAsking,
|
|
1040
|
+
prompts,
|
|
1041
|
+
touchFirst,
|
|
1042
|
+
currentPath,
|
|
731
1043
|
off,
|
|
732
1044
|
base,
|
|
733
1045
|
headers,
|
|
@@ -736,18 +1048,56 @@ function AvatarLiveView({
|
|
|
736
1048
|
const S = avatarLiveStrings(locale);
|
|
737
1049
|
const uid = react.useId();
|
|
738
1050
|
const consentTitleId = `${uid}-consent`;
|
|
739
|
-
const
|
|
1051
|
+
const [questions, setQuestions] = react.useState("suggested");
|
|
1052
|
+
const questionsRef = react.useRef("suggested");
|
|
1053
|
+
const askedHereRef = react.useRef(null);
|
|
1054
|
+
const askSeqRef = react.useRef(0);
|
|
1055
|
+
const [, setAskedHereTick] = react.useState(0);
|
|
1056
|
+
const setAskedHere = react.useCallback((next) => {
|
|
1057
|
+
if (next === null) {
|
|
1058
|
+
askSeqRef.current += 1;
|
|
1059
|
+
if (askedHereRef.current === null) return;
|
|
1060
|
+
}
|
|
1061
|
+
askedHereRef.current = next;
|
|
1062
|
+
setAskedHereTick((tick) => tick + 1);
|
|
1063
|
+
}, []);
|
|
1064
|
+
const token = conversation?.getConversationToken() ?? null;
|
|
1065
|
+
const exchange = firstExchange(conversation?.messages, {
|
|
1066
|
+
any: questions === "any",
|
|
1067
|
+
askedHere: askedHereRef.current,
|
|
1068
|
+
token,
|
|
1069
|
+
inFlight: inFlight(conversation)
|
|
1070
|
+
});
|
|
740
1071
|
const [ageTick, setAgeTick] = react.useState(0);
|
|
741
|
-
const
|
|
1072
|
+
const shown = offeredAt(exchange, Date.now());
|
|
1073
|
+
const { answerId, startOver } = shown;
|
|
742
1074
|
const offerUntil = answerId === null ? null : exchange.offerUntil;
|
|
743
1075
|
const [phase, setPhase] = react.useState(IDLE);
|
|
744
1076
|
const [blocked, setBlocked] = react.useState(false);
|
|
745
1077
|
const [now, setNow] = react.useState(() => Date.now());
|
|
1078
|
+
const [draft, setDraft] = react.useState("");
|
|
1079
|
+
const chatMaxLength = conversation?.catalog.limits.maxMessageLength;
|
|
1080
|
+
const askMaxLength = chatMaxLength !== void 0 && Number.isFinite(chatMaxLength) && chatMaxLength >= 1 ? Math.min(ASK_MAX_LENGTH, Math.floor(chatMaxLength)) : ASK_MAX_LENGTH;
|
|
1081
|
+
const [note, setNote] = react.useState(null);
|
|
1082
|
+
const [usedToday, setUsedToday] = react.useState(false);
|
|
1083
|
+
const showing = active && !off;
|
|
1084
|
+
const behindChat = open && !active && !off;
|
|
746
1085
|
const phaseRef = react.useRef(IDLE);
|
|
747
|
-
const latest = react.useRef({
|
|
748
|
-
|
|
1086
|
+
const latest = react.useRef({
|
|
1087
|
+
live,
|
|
1088
|
+
locale,
|
|
1089
|
+
base,
|
|
1090
|
+
headers,
|
|
1091
|
+
off,
|
|
1092
|
+
currentPath,
|
|
1093
|
+
showing
|
|
1094
|
+
});
|
|
1095
|
+
latest.current = { live, locale, base, headers, off, currentPath, showing };
|
|
749
1096
|
const conversationRef = react.useRef(conversation);
|
|
750
1097
|
conversationRef.current = conversation;
|
|
1098
|
+
const waitRef = react.useRef(null);
|
|
1099
|
+
const sendingRef = react.useRef(false);
|
|
1100
|
+
const textBoxRef = react.useRef(false);
|
|
751
1101
|
const checkRef = react.useRef(null);
|
|
752
1102
|
const askedLocale = react.useRef(locale);
|
|
753
1103
|
const startRef = react.useRef(null);
|
|
@@ -761,8 +1111,32 @@ function AvatarLiveView({
|
|
|
761
1111
|
phaseRef.current = next;
|
|
762
1112
|
setPhase(next);
|
|
763
1113
|
}, []);
|
|
1114
|
+
const inSight = react.useCallback(
|
|
1115
|
+
() => latest.current.showing && (typeof document === "undefined" || document.visibilityState !== "hidden"),
|
|
1116
|
+
[]
|
|
1117
|
+
);
|
|
1118
|
+
const setMode = react.useCallback((next) => {
|
|
1119
|
+
questionsRef.current = next;
|
|
1120
|
+
setQuestions(next);
|
|
1121
|
+
}, []);
|
|
1122
|
+
const exchangeNow = react.useCallback(
|
|
1123
|
+
() => offeredAt(
|
|
1124
|
+
firstExchange(conversationRef.current?.messages, {
|
|
1125
|
+
any: questionsRef.current === "any",
|
|
1126
|
+
askedHere: askedHereRef.current,
|
|
1127
|
+
token: conversationRef.current?.getConversationToken() ?? null,
|
|
1128
|
+
inFlight: inFlight(conversationRef.current)
|
|
1129
|
+
}),
|
|
1130
|
+
Date.now()
|
|
1131
|
+
),
|
|
1132
|
+
[]
|
|
1133
|
+
);
|
|
764
1134
|
const offeredNow = react.useCallback(
|
|
765
|
-
() =>
|
|
1135
|
+
() => exchangeNow().answerId,
|
|
1136
|
+
[exchangeNow]
|
|
1137
|
+
);
|
|
1138
|
+
const pathNow = react.useCallback(
|
|
1139
|
+
() => latest.current.currentPath ?? (typeof window === "undefined" ? "" : window.location.pathname),
|
|
766
1140
|
[]
|
|
767
1141
|
);
|
|
768
1142
|
const reoffer = react.useCallback(
|
|
@@ -795,6 +1169,17 @@ function AvatarLiveView({
|
|
|
795
1169
|
},
|
|
796
1170
|
[go]
|
|
797
1171
|
);
|
|
1172
|
+
const goLive = react.useCallback(() => {
|
|
1173
|
+
const current = phaseRef.current;
|
|
1174
|
+
const handle = sessionRef.current;
|
|
1175
|
+
if (current.name !== "pending" || !handle) return;
|
|
1176
|
+
handle.speakerArrived = true;
|
|
1177
|
+
if (questionsRef.current === "any") {
|
|
1178
|
+
noteUsedToday();
|
|
1179
|
+
setUsedToday(true);
|
|
1180
|
+
}
|
|
1181
|
+
go({ name: "live", session: current.session });
|
|
1182
|
+
}, [go]);
|
|
798
1183
|
const cancelStart = react.useCallback((reason) => {
|
|
799
1184
|
const run = startRef.current;
|
|
800
1185
|
if (!run) return;
|
|
@@ -802,6 +1187,36 @@ function AvatarLiveView({
|
|
|
802
1187
|
run.cancelled = reason;
|
|
803
1188
|
run.turnstile?.cancel();
|
|
804
1189
|
}, []);
|
|
1190
|
+
const applyAvailability = react.useCallback(
|
|
1191
|
+
(result, locale2) => {
|
|
1192
|
+
const { live: live2 } = latest.current;
|
|
1193
|
+
if (result.kind === "inert") {
|
|
1194
|
+
setMode("suggested");
|
|
1195
|
+
go(INERT2);
|
|
1196
|
+
return;
|
|
1197
|
+
}
|
|
1198
|
+
if (result.kind === "refused") {
|
|
1199
|
+
setMode(result.questions);
|
|
1200
|
+
go({ name: "refused", reason: result.reason });
|
|
1201
|
+
return;
|
|
1202
|
+
}
|
|
1203
|
+
setUsedToday(usedTodayHere());
|
|
1204
|
+
const copy = avatarConsentCopy(result.offer.consentVersion, locale2);
|
|
1205
|
+
if (copy === null || copy.botCheck !== result.offer.botCheck || copy.questions !== result.offer.questions) {
|
|
1206
|
+
setMode("suggested");
|
|
1207
|
+
go(INERT2);
|
|
1208
|
+
return;
|
|
1209
|
+
}
|
|
1210
|
+
if (result.offer.botCheck === "turnstile" && chunk7O2I32ZN_js.turnstileSiteKeyOf(live2) === null) {
|
|
1211
|
+
setMode("suggested");
|
|
1212
|
+
go(INERT2);
|
|
1213
|
+
return;
|
|
1214
|
+
}
|
|
1215
|
+
setMode(result.offer.questions);
|
|
1216
|
+
go(reoffer({ ...result.offer, locale: locale2, copy }));
|
|
1217
|
+
},
|
|
1218
|
+
[go, reoffer, setMode]
|
|
1219
|
+
);
|
|
805
1220
|
const check = react.useCallback(() => {
|
|
806
1221
|
const { live: live2, locale: locale2, base: base2, headers: headers2, off: off2 } = latest.current;
|
|
807
1222
|
checkRef.current?.abort();
|
|
@@ -823,26 +1238,9 @@ function AvatarLiveView({
|
|
|
823
1238
|
}).then((result) => {
|
|
824
1239
|
if (checkRef.current !== controller) return;
|
|
825
1240
|
checkRef.current = null;
|
|
826
|
-
|
|
827
|
-
go(INERT2);
|
|
828
|
-
return;
|
|
829
|
-
}
|
|
830
|
-
if (result.kind === "refused") {
|
|
831
|
-
go({ name: "refused", reason: result.reason });
|
|
832
|
-
return;
|
|
833
|
-
}
|
|
834
|
-
const copy = avatarConsentCopy(result.offer.consentVersion, locale2);
|
|
835
|
-
if (copy === null || copy.botCheck !== result.offer.botCheck) {
|
|
836
|
-
go(INERT2);
|
|
837
|
-
return;
|
|
838
|
-
}
|
|
839
|
-
if (result.offer.botCheck === "turnstile" && chunkFQH3AJN3_js.turnstileSiteKeyOf(live2) === null) {
|
|
840
|
-
go(INERT2);
|
|
841
|
-
return;
|
|
842
|
-
}
|
|
843
|
-
go(reoffer({ ...result.offer, locale: locale2, copy }));
|
|
1241
|
+
applyAvailability(result, locale2);
|
|
844
1242
|
});
|
|
845
|
-
}, [
|
|
1243
|
+
}, [applyAvailability, go]);
|
|
846
1244
|
const begin = react.useCallback(
|
|
847
1245
|
(session, module, offer, target) => {
|
|
848
1246
|
const received = Date.now();
|
|
@@ -887,8 +1285,8 @@ function AvatarLiveView({
|
|
|
887
1285
|
reason: run.cancelled
|
|
888
1286
|
});
|
|
889
1287
|
}
|
|
890
|
-
const
|
|
891
|
-
if (claimed &&
|
|
1288
|
+
const shown2 = phaseRef.current;
|
|
1289
|
+
if (claimed && shown2.name === "consent" && shown2.messageId === context.messageId) {
|
|
892
1290
|
go({ name: "refused", reason: "answer_claimed" });
|
|
893
1291
|
}
|
|
894
1292
|
return;
|
|
@@ -923,86 +1321,186 @@ function AvatarLiveView({
|
|
|
923
1321
|
},
|
|
924
1322
|
[begin, check, go]
|
|
925
1323
|
);
|
|
1324
|
+
const launch = react.useCallback(
|
|
1325
|
+
(offer, messageId, preloaded) => {
|
|
1326
|
+
const { live: live2, base: base2, headers: headers2 } = latest.current;
|
|
1327
|
+
if (base2 === null) return;
|
|
1328
|
+
const exchangeAtStart = exchangeNow();
|
|
1329
|
+
if (exchangeAtStart.answerId !== messageId) {
|
|
1330
|
+
go(reoffer(offer));
|
|
1331
|
+
return;
|
|
1332
|
+
}
|
|
1333
|
+
if (claimedRef.current.has(messageId)) {
|
|
1334
|
+
go({ name: "refused", reason: "answer_claimed" });
|
|
1335
|
+
return;
|
|
1336
|
+
}
|
|
1337
|
+
const refusedFrom = exchangeAtStart.offerUntil - ANSWER_OFFER_MS + SERVICE_MAX_AGE_MS;
|
|
1338
|
+
const siteKey = offer.botCheck === "turnstile" ? chunk7O2I32ZN_js.turnstileSiteKeyOf(live2) : null;
|
|
1339
|
+
if (offer.botCheck === "turnstile" && (siteKey === null || !canBindBotCheck())) {
|
|
1340
|
+
go(INERT2);
|
|
1341
|
+
return;
|
|
1342
|
+
}
|
|
1343
|
+
const conversationToken = conversationRef.current?.getConversationToken() ?? null;
|
|
1344
|
+
const idempotencyKey = newIdempotencyKey();
|
|
1345
|
+
if (conversationToken === null || !isAvatarConversationToken(conversationToken) || idempotencyKey === null) {
|
|
1346
|
+
go({ name: "ended", how: "failed" });
|
|
1347
|
+
return;
|
|
1348
|
+
}
|
|
1349
|
+
const body2 = {
|
|
1350
|
+
site: live2.site,
|
|
1351
|
+
locale: offer.locale,
|
|
1352
|
+
conversationToken,
|
|
1353
|
+
messageId,
|
|
1354
|
+
consentVersion: offer.consentVersion,
|
|
1355
|
+
manifestVersion: live2.manifestVersion
|
|
1356
|
+
};
|
|
1357
|
+
const run = { cancelled: null, turnstile: null };
|
|
1358
|
+
startRef.current = run;
|
|
1359
|
+
const module = preloaded ?? loadModule(live2.load);
|
|
1360
|
+
let turnstile = null;
|
|
1361
|
+
if (siteKey === null) {
|
|
1362
|
+
go({ name: "creating" });
|
|
1363
|
+
} else {
|
|
1364
|
+
go({ name: "bot-check", offer, messageId });
|
|
1365
|
+
turnstile = runTurnstile(
|
|
1366
|
+
botBoxRef.current,
|
|
1367
|
+
siteKey,
|
|
1368
|
+
"avatar_start",
|
|
1369
|
+
avatarBotBinding(body2)
|
|
1370
|
+
);
|
|
1371
|
+
run.turnstile = turnstile;
|
|
1372
|
+
}
|
|
1373
|
+
void (async () => {
|
|
1374
|
+
let loaded;
|
|
1375
|
+
let botToken;
|
|
1376
|
+
try {
|
|
1377
|
+
[loaded, botToken] = await Promise.all([module, turnstile?.token]);
|
|
1378
|
+
} catch {
|
|
1379
|
+
turnstile?.cancel();
|
|
1380
|
+
if (run.cancelled === null) {
|
|
1381
|
+
startRef.current = null;
|
|
1382
|
+
go(INERT2);
|
|
1383
|
+
}
|
|
1384
|
+
return;
|
|
1385
|
+
}
|
|
1386
|
+
turnstile?.cancel();
|
|
1387
|
+
if (run.cancelled !== null) return;
|
|
1388
|
+
if (!(Date.now() < refusedFrom)) {
|
|
1389
|
+
startRef.current = null;
|
|
1390
|
+
go({ name: "needs-answer", offer });
|
|
1391
|
+
return;
|
|
1392
|
+
}
|
|
1393
|
+
if (turnstile !== null) go({ name: "creating" });
|
|
1394
|
+
const result = await requestCreate({
|
|
1395
|
+
base: base2,
|
|
1396
|
+
headers: headers2,
|
|
1397
|
+
idempotencyKey,
|
|
1398
|
+
botToken,
|
|
1399
|
+
body: body2
|
|
1400
|
+
});
|
|
1401
|
+
if (startRef.current === run) startRef.current = null;
|
|
1402
|
+
settle(result, run, {
|
|
1403
|
+
module: loaded,
|
|
1404
|
+
offer,
|
|
1405
|
+
messageId,
|
|
1406
|
+
base: base2,
|
|
1407
|
+
headers: headers2
|
|
1408
|
+
});
|
|
1409
|
+
})();
|
|
1410
|
+
},
|
|
1411
|
+
[exchangeNow, go, reoffer, settle]
|
|
1412
|
+
);
|
|
926
1413
|
const start = react.useCallback(() => {
|
|
927
1414
|
const current = phaseRef.current;
|
|
928
1415
|
if (current.name !== "consent") return;
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
}
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
1416
|
+
if (current.offer.questions === "any") unlockSound(audioRef.current);
|
|
1417
|
+
launch(current.offer, current.messageId, null);
|
|
1418
|
+
}, [launch]);
|
|
1419
|
+
const cancelWaiting = react.useCallback(
|
|
1420
|
+
(told) => {
|
|
1421
|
+
const wait = waitRef.current;
|
|
1422
|
+
waitRef.current = null;
|
|
1423
|
+
wait?.check?.abort();
|
|
1424
|
+
const current = phaseRef.current;
|
|
1425
|
+
if (current.name !== "waiting") return;
|
|
1426
|
+
if (told) setNote("cancelled");
|
|
1427
|
+
go({ name: "needs-answer", offer: current.offer });
|
|
1428
|
+
},
|
|
1429
|
+
[go]
|
|
1430
|
+
);
|
|
1431
|
+
const bindingHolds = react.useCallback(
|
|
1432
|
+
(bound, exchange2) => {
|
|
1433
|
+
const { live: live2, locale: locale2 } = latest.current;
|
|
1434
|
+
return conversationRef.current?.getConversationToken() === bound.token && exchange2.question?.id === bound.questionId && live2.site === bound.site && locale2 === bound.locale && pathNow() === bound.path;
|
|
1435
|
+
},
|
|
1436
|
+
[pathNow]
|
|
1437
|
+
);
|
|
1438
|
+
const startWhenReady = react.useCallback(() => {
|
|
1439
|
+
const current = phaseRef.current;
|
|
1440
|
+
if (current.name !== "needs-answer") return;
|
|
1441
|
+
const { live: live2, locale: locale2 } = latest.current;
|
|
1442
|
+
const exchange2 = exchangeNow();
|
|
1443
|
+
const token2 = conversationRef.current?.getConversationToken() ?? null;
|
|
1444
|
+
if (exchange2.kind !== "asking" || !exchange2.askedHere || exchange2.question === null || exchange2.pendingAnswerId === null || token2 === null || !isAvatarConversationToken(token2)) {
|
|
946
1445
|
return;
|
|
947
1446
|
}
|
|
948
|
-
|
|
949
|
-
site: live2.site,
|
|
950
|
-
locale: offer.locale,
|
|
951
|
-
conversationToken,
|
|
952
|
-
messageId,
|
|
953
|
-
consentVersion: offer.consentVersion,
|
|
954
|
-
manifestVersion: live2.manifestVersion
|
|
955
|
-
};
|
|
956
|
-
const run = { cancelled: null, turnstile: null };
|
|
957
|
-
startRef.current = run;
|
|
1447
|
+
unlockSound(audioRef.current);
|
|
958
1448
|
const module = loadModule(live2.load);
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
}
|
|
983
|
-
return;
|
|
984
|
-
}
|
|
985
|
-
turnstile?.cancel();
|
|
986
|
-
if (run.cancelled !== null) return;
|
|
987
|
-
if (!(Date.now() < refusedFrom)) {
|
|
988
|
-
startRef.current = null;
|
|
989
|
-
go({ name: "needs-answer", offer });
|
|
1449
|
+
module.catch(() => void 0);
|
|
1450
|
+
waitRef.current = {
|
|
1451
|
+
bound: {
|
|
1452
|
+
token: token2,
|
|
1453
|
+
questionId: exchange2.question.id,
|
|
1454
|
+
answerId: exchange2.pendingAnswerId,
|
|
1455
|
+
site: live2.site,
|
|
1456
|
+
locale: locale2,
|
|
1457
|
+
path: pathNow(),
|
|
1458
|
+
consentVersion: current.offer.consentVersion,
|
|
1459
|
+
botCheck: current.offer.botCheck
|
|
1460
|
+
},
|
|
1461
|
+
module,
|
|
1462
|
+
check: null
|
|
1463
|
+
};
|
|
1464
|
+
setNote(null);
|
|
1465
|
+
go({ name: "waiting", offer: current.offer });
|
|
1466
|
+
}, [exchangeNow, go, pathNow]);
|
|
1467
|
+
const confirm = react.useCallback(
|
|
1468
|
+
(offer, wait) => {
|
|
1469
|
+
const { live: live2, locale: locale2, base: base2, headers: headers2 } = latest.current;
|
|
1470
|
+
if (base2 === null) {
|
|
1471
|
+
cancelWaiting(true);
|
|
990
1472
|
return;
|
|
991
1473
|
}
|
|
992
|
-
|
|
993
|
-
|
|
1474
|
+
const controller = new AbortController();
|
|
1475
|
+
wait.check = controller;
|
|
1476
|
+
void requestAvailability({
|
|
994
1477
|
base: base2,
|
|
995
1478
|
headers: headers2,
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
1479
|
+
site: live2.site,
|
|
1480
|
+
locale: locale2,
|
|
1481
|
+
signal: controller.signal
|
|
1482
|
+
}).then((result) => {
|
|
1483
|
+
if (waitRef.current !== wait || phaseRef.current.name !== "waiting") {
|
|
1484
|
+
return;
|
|
1485
|
+
}
|
|
1486
|
+
waitRef.current = null;
|
|
1487
|
+
const exchange2 = exchangeNow();
|
|
1488
|
+
const same = result.kind === "available" && result.offer.consentVersion === wait.bound.consentVersion && result.offer.botCheck === wait.bound.botCheck && result.offer.questions === "any" && exchange2.kind === "answer" && exchange2.answerId === wait.bound.answerId && bindingHolds(wait.bound, exchange2);
|
|
1489
|
+
if (!same || result.kind !== "available") {
|
|
1490
|
+
applyAvailability(result, locale2);
|
|
1491
|
+
return;
|
|
1492
|
+
}
|
|
1493
|
+
launch({ ...offer, ...result.offer }, wait.bound.answerId, wait.module);
|
|
999
1494
|
});
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
}, [go, offeredNow, reoffer, settle]);
|
|
1495
|
+
},
|
|
1496
|
+
[applyAvailability, bindingHolds, cancelWaiting, exchangeNow, launch]
|
|
1497
|
+
);
|
|
1004
1498
|
const stop = react.useCallback(() => {
|
|
1005
1499
|
const current = phaseRef.current;
|
|
1500
|
+
if (current.name === "waiting") {
|
|
1501
|
+
cancelWaiting(false);
|
|
1502
|
+
return;
|
|
1503
|
+
}
|
|
1006
1504
|
if (current.name === "bot-check") {
|
|
1007
1505
|
cancelStart("user");
|
|
1008
1506
|
go(reoffer(current.offer));
|
|
@@ -1016,11 +1514,13 @@ function AvatarLiveView({
|
|
|
1016
1514
|
if (current.name === "pending" || current.name === "live") {
|
|
1017
1515
|
finish("stopped", "user");
|
|
1018
1516
|
}
|
|
1019
|
-
}, [cancelStart, finish, go, reoffer]);
|
|
1517
|
+
}, [cancelStart, cancelWaiting, finish, go, reoffer]);
|
|
1020
1518
|
const leave = react.useCallback(
|
|
1021
|
-
(
|
|
1519
|
+
(event) => {
|
|
1022
1520
|
const current = phaseRef.current;
|
|
1521
|
+
const reason = event === "user" || event === "chat" ? "user" : "page_hide";
|
|
1023
1522
|
const how = reason === "user" ? "stopped" : "interrupted";
|
|
1523
|
+
const keepsSession = event === "chat" || event === "hidden";
|
|
1024
1524
|
switch (current.name) {
|
|
1025
1525
|
case "checking": {
|
|
1026
1526
|
if (reason !== "user") return;
|
|
@@ -1030,49 +1530,63 @@ function AvatarLiveView({
|
|
|
1030
1530
|
go(IDLE);
|
|
1031
1531
|
return;
|
|
1032
1532
|
}
|
|
1533
|
+
case "waiting":
|
|
1534
|
+
cancelWaiting(true);
|
|
1535
|
+
return;
|
|
1033
1536
|
case "bot-check":
|
|
1034
1537
|
cancelStart(reason);
|
|
1035
1538
|
go(reason === "user" ? IDLE : reoffer(current.offer));
|
|
1036
1539
|
return;
|
|
1037
1540
|
case "creating":
|
|
1541
|
+
if (keepsSession) return;
|
|
1038
1542
|
cancelStart(reason);
|
|
1039
1543
|
go({ name: "ended", how });
|
|
1040
1544
|
return;
|
|
1041
1545
|
case "pending":
|
|
1042
1546
|
case "live":
|
|
1547
|
+
if (keepsSession) {
|
|
1548
|
+
if (current.name === "pending" && sessionRef.current?.speakerArrived) {
|
|
1549
|
+
goLive();
|
|
1550
|
+
}
|
|
1551
|
+
return;
|
|
1552
|
+
}
|
|
1043
1553
|
finish(how, reason);
|
|
1044
1554
|
return;
|
|
1045
1555
|
default:
|
|
1046
1556
|
return;
|
|
1047
1557
|
}
|
|
1048
1558
|
},
|
|
1049
|
-
[cancelStart, finish, go, reoffer]
|
|
1559
|
+
[cancelStart, cancelWaiting, finish, go, goLive, reoffer]
|
|
1050
1560
|
);
|
|
1051
|
-
const showing = active && !off;
|
|
1052
1561
|
react.useEffect(() => {
|
|
1053
1562
|
if (!showing) {
|
|
1054
|
-
leave("user");
|
|
1563
|
+
leave(behindChat ? "chat" : "user");
|
|
1055
1564
|
return;
|
|
1056
1565
|
}
|
|
1057
1566
|
const current = phaseRef.current;
|
|
1567
|
+
if (current.name === "creating" || current.name === "pending" || current.name === "live") {
|
|
1568
|
+
setNow(Date.now());
|
|
1569
|
+
return;
|
|
1570
|
+
}
|
|
1058
1571
|
const offered = offeredNow();
|
|
1059
1572
|
const used = offered !== null && claimedRef.current.has(offered);
|
|
1060
1573
|
if (current.name === "ended" && used) return;
|
|
1061
1574
|
if (current.name === "refused" && current.reason === "answer_claimed" && used) {
|
|
1062
1575
|
return;
|
|
1063
1576
|
}
|
|
1064
|
-
if (current.name === "idle" || current.name === "inert" || current.name === "refused" || current.name === "needs-answer" || current.name === "consent" || current.name === "ended" || // Asking, with nothing actually asking: React's strict mode unmounts and mounts a component again with the state it
|
|
1577
|
+
if (current.name === "idle" || current.name === "inert" || current.name === "refused" || current.name === "needs-answer" || current.name === "consent" || current.name === "declined" || current.name === "ended" || // Asking, with nothing actually asking: React's strict mode unmounts and mounts a component again with the state it
|
|
1065
1578
|
// left, and the unmount in between dropped the question. (This view mounts already showing, the first time the
|
|
1066
1579
|
// Avatar view opens.)
|
|
1067
1580
|
current.name === "checking" && checkRef.current === null) {
|
|
1068
1581
|
check();
|
|
1069
1582
|
}
|
|
1070
|
-
}, [showing, check, leave, offeredNow]);
|
|
1583
|
+
}, [showing, behindChat, check, leave, offeredNow]);
|
|
1071
1584
|
react.useEffect(() => {
|
|
1072
1585
|
if (askedLocale.current === locale) return;
|
|
1073
1586
|
askedLocale.current = locale;
|
|
1587
|
+
if (phaseRef.current.name === "waiting") cancelWaiting(true);
|
|
1074
1588
|
const current = phaseRef.current.name;
|
|
1075
|
-
if (current !== "checking" && current !== "needs-answer" && current !== "consent" && current !== "refused" && current !== "inert") {
|
|
1589
|
+
if (current !== "checking" && current !== "needs-answer" && current !== "consent" && current !== "declined" && current !== "refused" && current !== "inert") {
|
|
1076
1590
|
return;
|
|
1077
1591
|
}
|
|
1078
1592
|
if (active) {
|
|
@@ -1082,7 +1596,8 @@ function AvatarLiveView({
|
|
|
1082
1596
|
checkRef.current = null;
|
|
1083
1597
|
go(IDLE);
|
|
1084
1598
|
}
|
|
1085
|
-
}, [active, check, go, locale]);
|
|
1599
|
+
}, [active, cancelWaiting, check, go, locale]);
|
|
1600
|
+
const kind = shown.kind;
|
|
1086
1601
|
react.useEffect(() => {
|
|
1087
1602
|
const current = phaseRef.current;
|
|
1088
1603
|
if (current.name === "needs-answer" && answerId !== null) {
|
|
@@ -1091,8 +1606,49 @@ function AvatarLiveView({
|
|
|
1091
1606
|
go(
|
|
1092
1607
|
answerId === null ? { name: "needs-answer", offer: current.offer } : { ...current, messageId: answerId }
|
|
1093
1608
|
);
|
|
1609
|
+
} else if (current.name === "declined" && answerId === null) {
|
|
1610
|
+
if (kind !== "asking") go({ name: "needs-answer", offer: current.offer });
|
|
1094
1611
|
}
|
|
1095
|
-
}, [answerId, go]);
|
|
1612
|
+
}, [answerId, kind, go]);
|
|
1613
|
+
react.useEffect(() => {
|
|
1614
|
+
const current = phaseRef.current;
|
|
1615
|
+
const wait = waitRef.current;
|
|
1616
|
+
if (current.name !== "waiting" || wait === null || wait.check !== null) {
|
|
1617
|
+
return;
|
|
1618
|
+
}
|
|
1619
|
+
const now2 = exchangeNow();
|
|
1620
|
+
const holds = bindingHolds(wait.bound, now2);
|
|
1621
|
+
if (holds && now2.kind === "asking" && now2.pendingAnswerId === wait.bound.answerId) {
|
|
1622
|
+
return;
|
|
1623
|
+
}
|
|
1624
|
+
if (!holds || now2.kind !== "answer" || now2.answerId !== wait.bound.answerId) {
|
|
1625
|
+
cancelWaiting(now2.kind !== "failed" && now2.kind !== "text-only");
|
|
1626
|
+
return;
|
|
1627
|
+
}
|
|
1628
|
+
confirm(current.offer, wait);
|
|
1629
|
+
});
|
|
1630
|
+
const resent = conversation?.resent ?? null;
|
|
1631
|
+
react.useEffect(() => {
|
|
1632
|
+
const asked = askedHereRef.current;
|
|
1633
|
+
if (resent === null || asked === null || !resent.replacedMessageIds.includes(asked.messageId)) {
|
|
1634
|
+
return;
|
|
1635
|
+
}
|
|
1636
|
+
setAskedHere({
|
|
1637
|
+
messageId: resent.sent.userMessageId,
|
|
1638
|
+
token: resent.sent.conversationToken
|
|
1639
|
+
});
|
|
1640
|
+
}, [resent, setAskedHere]);
|
|
1641
|
+
const empty = (conversation?.messages.length ?? 0) === 0;
|
|
1642
|
+
react.useEffect(() => {
|
|
1643
|
+
if (empty) setAskedHere(null);
|
|
1644
|
+
}, [empty, setAskedHere]);
|
|
1645
|
+
react.useEffect(() => {
|
|
1646
|
+
const asked = askedHereRef.current;
|
|
1647
|
+
if (asked !== null && asked.token !== token) setAskedHere(null);
|
|
1648
|
+
}, [token, setAskedHere]);
|
|
1649
|
+
react.useEffect(() => {
|
|
1650
|
+
if (showing) setUsedToday(usedTodayHere());
|
|
1651
|
+
}, [showing]);
|
|
1096
1652
|
react.useEffect(() => {
|
|
1097
1653
|
if (offerUntil === null) return;
|
|
1098
1654
|
const timer = setTimeout(
|
|
@@ -1111,7 +1667,9 @@ function AvatarLiveView({
|
|
|
1111
1667
|
const wasLive = phaseRef.current.name === "live";
|
|
1112
1668
|
switch (event.type) {
|
|
1113
1669
|
case "speaker-track":
|
|
1114
|
-
if (event.kind
|
|
1670
|
+
if (event.kind !== "video") return;
|
|
1671
|
+
handle.speakerArrived = true;
|
|
1672
|
+
if (!inSight()) goLive();
|
|
1115
1673
|
return;
|
|
1116
1674
|
case "playback-blocked":
|
|
1117
1675
|
setBlocked(event.blocked);
|
|
@@ -1128,7 +1686,7 @@ function AvatarLiveView({
|
|
|
1128
1686
|
return;
|
|
1129
1687
|
}
|
|
1130
1688
|
},
|
|
1131
|
-
[finish]
|
|
1689
|
+
[finish, goLive, inSight]
|
|
1132
1690
|
);
|
|
1133
1691
|
react.useEffect(() => {
|
|
1134
1692
|
if (phase.name !== "pending") return;
|
|
@@ -1202,11 +1760,23 @@ function AvatarLiveView({
|
|
|
1202
1760
|
const timer = setInterval(() => setNow(Date.now()), 1e3);
|
|
1203
1761
|
return () => clearInterval(timer);
|
|
1204
1762
|
}, [ticking]);
|
|
1763
|
+
const voiceLine = phase.name === "live" ? S.speaking : phase.name === "creating" || phase.name === "pending" ? S.connecting : null;
|
|
1764
|
+
const onVoiceHoldRef = react.useRef(onVoiceHold);
|
|
1765
|
+
onVoiceHoldRef.current = onVoiceHold;
|
|
1766
|
+
react.useEffect(() => {
|
|
1767
|
+
onVoiceHoldRef.current?.(voiceLine);
|
|
1768
|
+
}, [voiceLine]);
|
|
1769
|
+
react.useEffect(() => () => onVoiceHoldRef.current?.(null), []);
|
|
1205
1770
|
react.useEffect(() => {
|
|
1206
1771
|
if (typeof window === "undefined") return;
|
|
1207
1772
|
const onPageHide = () => leave("page_hide");
|
|
1208
1773
|
const onVisibility = () => {
|
|
1209
|
-
if (document.visibilityState === "hidden")
|
|
1774
|
+
if (document.visibilityState === "hidden") {
|
|
1775
|
+
leave("hidden");
|
|
1776
|
+
return;
|
|
1777
|
+
}
|
|
1778
|
+
const current = phaseRef.current.name;
|
|
1779
|
+
if (current === "pending" || current === "live") setNow(Date.now());
|
|
1210
1780
|
};
|
|
1211
1781
|
window.addEventListener("pagehide", onPageHide);
|
|
1212
1782
|
document.addEventListener("visibilitychange", onVisibility);
|
|
@@ -1226,6 +1796,9 @@ function AvatarLiveView({
|
|
|
1226
1796
|
run.cancelled = "user";
|
|
1227
1797
|
run.turnstile?.cancel();
|
|
1228
1798
|
}
|
|
1799
|
+
const wait = waitRef.current;
|
|
1800
|
+
waitRef.current = null;
|
|
1801
|
+
wait?.check?.abort();
|
|
1229
1802
|
const handle = sessionRef.current;
|
|
1230
1803
|
sessionRef.current = null;
|
|
1231
1804
|
if (handle && !handle.done) {
|
|
@@ -1242,19 +1815,74 @@ function AvatarLiveView({
|
|
|
1242
1815
|
},
|
|
1243
1816
|
[]
|
|
1244
1817
|
);
|
|
1818
|
+
const any = questions === "any";
|
|
1819
|
+
const textMode = any && (usedToday && (phase.name === "needs-answer" || phase.name === "consent" || phase.name === "declined" || phase.name === "ended") || phase.name === "refused" && phase.reason === "limits");
|
|
1820
|
+
textBoxRef.current = textMode;
|
|
1821
|
+
const askState = !any ? void 0 : textMode ? "text" : phase.name === "needs-answer" ? kind === "empty" ? "ready" : kind : phase.name;
|
|
1822
|
+
const notNow = react.useCallback(() => {
|
|
1823
|
+
const current = phaseRef.current;
|
|
1824
|
+
if ((current.name === "consent" || current.name === "needs-answer") && current.offer.questions === "any") {
|
|
1825
|
+
go({ name: "declined", offer: current.offer });
|
|
1826
|
+
return;
|
|
1827
|
+
}
|
|
1828
|
+
onContinueInChat();
|
|
1829
|
+
}, [go, onContinueInChat]);
|
|
1830
|
+
const ask = react.useCallback(
|
|
1831
|
+
(text) => {
|
|
1832
|
+
const conversation2 = conversationRef.current;
|
|
1833
|
+
const question = text.trim();
|
|
1834
|
+
if (conversation2 === null || question === "" || sendingRef.current) {
|
|
1835
|
+
return;
|
|
1836
|
+
}
|
|
1837
|
+
const spoken = !textBoxRef.current;
|
|
1838
|
+
if (spoken && conversation2.messages.length > 0) return;
|
|
1839
|
+
sendingRef.current = true;
|
|
1840
|
+
setAskedHere(null);
|
|
1841
|
+
const seq = askSeqRef.current;
|
|
1842
|
+
setNote(null);
|
|
1843
|
+
setDraft("");
|
|
1844
|
+
void conversation2.send(question, [], spoken ? { surface: "AVATAR" } : {}).then((added) => {
|
|
1845
|
+
if (added === null) {
|
|
1846
|
+
setDraft((current) => current === "" ? question : current);
|
|
1847
|
+
}
|
|
1848
|
+
if (!spoken || added === null || askSeqRef.current !== seq || added.conversationToken !== (conversationRef.current?.getConversationToken() ?? null)) {
|
|
1849
|
+
return;
|
|
1850
|
+
}
|
|
1851
|
+
setAskedHere({
|
|
1852
|
+
messageId: added.userMessageId,
|
|
1853
|
+
token: added.conversationToken
|
|
1854
|
+
});
|
|
1855
|
+
}).finally(() => {
|
|
1856
|
+
sendingRef.current = false;
|
|
1857
|
+
});
|
|
1858
|
+
},
|
|
1859
|
+
[setAskedHere]
|
|
1860
|
+
);
|
|
1861
|
+
const newChatForAvatar = react.useCallback(() => {
|
|
1862
|
+
const conversation2 = conversationRef.current;
|
|
1863
|
+
if (conversation2 === null) return;
|
|
1864
|
+
const now2 = exchangeNow();
|
|
1865
|
+
const failedQuestion = now2.kind === "failed" ? now2.question?.content ?? null : null;
|
|
1866
|
+
conversation2.reset();
|
|
1867
|
+
setAskedHere(null);
|
|
1868
|
+
setNote("new-chat");
|
|
1869
|
+
if (failedQuestion !== null) {
|
|
1870
|
+
setDraft((current2) => current2 === "" ? failedQuestion : current2);
|
|
1871
|
+
}
|
|
1872
|
+
const current = phaseRef.current;
|
|
1873
|
+
if (current.name === "needs-answer" || current.name === "consent" || current.name === "declined") {
|
|
1874
|
+
go({ name: "needs-answer", offer: current.offer });
|
|
1875
|
+
} else {
|
|
1876
|
+
check();
|
|
1877
|
+
}
|
|
1878
|
+
}, [check, exchangeNow, go, setAskedHere]);
|
|
1245
1879
|
react.useEffect(() => {
|
|
1246
1880
|
if (!active) return;
|
|
1247
1881
|
const focused = document.activeElement;
|
|
1248
1882
|
if (focused && focused !== document.body && focused.isConnected) return;
|
|
1249
1883
|
rootRef.current?.querySelector(PRIMARY)?.focus();
|
|
1250
|
-
}, [active, phase.name, blocked]);
|
|
1251
|
-
const onPlaying =
|
|
1252
|
-
const current = phaseRef.current;
|
|
1253
|
-
const handle = sessionRef.current;
|
|
1254
|
-
if (current.name !== "pending" || !handle) return;
|
|
1255
|
-
handle.speakerArrived = true;
|
|
1256
|
-
go({ name: "live", session: current.session });
|
|
1257
|
-
}, [go]);
|
|
1884
|
+
}, [active, phase.name, askState, shown.pendingAnswerId, blocked]);
|
|
1885
|
+
const onPlaying = goLive;
|
|
1258
1886
|
const enablePlayback = react.useCallback(() => {
|
|
1259
1887
|
void sessionRef.current?.joined?.enablePlayback().catch(() => void 0);
|
|
1260
1888
|
}, []);
|
|
@@ -1285,7 +1913,7 @@ function AvatarLiveView({
|
|
|
1285
1913
|
height: small ? 64 : 128,
|
|
1286
1914
|
className: chunkC6OJIHNO_js.cn(
|
|
1287
1915
|
"shrink-0 rounded-full border border-border object-cover shadow-sm",
|
|
1288
|
-
small ? "h-16 w-16" : "h-32 w-32"
|
|
1916
|
+
small ? "h-16 w-16" : any ? "h-[min(12rem,32dvh)] w-[min(12rem,32dvh)]" : "h-32 w-32"
|
|
1289
1917
|
)
|
|
1290
1918
|
}
|
|
1291
1919
|
);
|
|
@@ -1334,12 +1962,440 @@ function AvatarLiveView({
|
|
|
1334
1962
|
children: S.stop
|
|
1335
1963
|
}
|
|
1336
1964
|
);
|
|
1965
|
+
const readInChatButton = (primary) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1966
|
+
"button",
|
|
1967
|
+
{
|
|
1968
|
+
type: "button",
|
|
1969
|
+
"data-avatar-primary": primary ? "" : void 0,
|
|
1970
|
+
"data-boff-explore": "avatar-live-read-in-chat",
|
|
1971
|
+
className: primary ? primaryButton : secondaryButton,
|
|
1972
|
+
onClick: onContinueInChat,
|
|
1973
|
+
children: S.readInChat
|
|
1974
|
+
}
|
|
1975
|
+
);
|
|
1976
|
+
const consentCard = (copy) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1977
|
+
"section",
|
|
1978
|
+
{
|
|
1979
|
+
"aria-labelledby": consentTitleId,
|
|
1980
|
+
"data-boff-explore": "avatar-live-consent",
|
|
1981
|
+
className: "w-full max-w-sm rounded-lg border border-border p-4 text-start",
|
|
1982
|
+
children: [
|
|
1983
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { id: consentTitleId, className: "text-base font-semibold", children: copy.title }),
|
|
1984
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-2 text-sm", children: productName === null || copy.introProduct === null ? copy.intro : chunkO4GS3XPZ_js.fill(copy.introProduct, { product: productName }) }),
|
|
1985
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-2 text-sm text-muted-foreground", children: copy.processing }),
|
|
1986
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-2 text-sm text-muted-foreground", children: copy.storage }),
|
|
1987
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1988
|
+
"a",
|
|
1989
|
+
{
|
|
1990
|
+
href: PRIVACY_HREF,
|
|
1991
|
+
target: "_blank",
|
|
1992
|
+
rel: "noopener noreferrer",
|
|
1993
|
+
"data-boff-explore": "avatar-live-privacy",
|
|
1994
|
+
className: "mt-2 inline-block text-sm font-medium text-primary underline underline-offset-2 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
1995
|
+
children: [
|
|
1996
|
+
copy.privacyLink,
|
|
1997
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "sr-only", children: [
|
|
1998
|
+
" ",
|
|
1999
|
+
S.opensInNewTab
|
|
2000
|
+
] })
|
|
2001
|
+
]
|
|
2002
|
+
}
|
|
2003
|
+
)
|
|
2004
|
+
]
|
|
2005
|
+
}
|
|
2006
|
+
);
|
|
2007
|
+
const consentActions = (whenReady) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center justify-center gap-2", children: [
|
|
2008
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2009
|
+
"button",
|
|
2010
|
+
{
|
|
2011
|
+
type: "button",
|
|
2012
|
+
"data-avatar-primary": "",
|
|
2013
|
+
"data-boff-explore": whenReady ? "avatar-live-start-when-ready" : "avatar-live-start",
|
|
2014
|
+
className: primaryButton,
|
|
2015
|
+
onClick: whenReady ? startWhenReady : start,
|
|
2016
|
+
children: whenReady ? S.startWhenReady : S.start
|
|
2017
|
+
}
|
|
2018
|
+
),
|
|
2019
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2020
|
+
"button",
|
|
2021
|
+
{
|
|
2022
|
+
type: "button",
|
|
2023
|
+
"data-boff-explore": "avatar-live-not-now",
|
|
2024
|
+
className: secondaryButton,
|
|
2025
|
+
onClick: notNow,
|
|
2026
|
+
children: S.notNow
|
|
2027
|
+
}
|
|
2028
|
+
)
|
|
2029
|
+
] });
|
|
2030
|
+
const liveMedia = (playing) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2031
|
+
"div",
|
|
2032
|
+
{
|
|
2033
|
+
className: chunkC6OJIHNO_js.cn(
|
|
2034
|
+
"relative shrink-0 overflow-hidden rounded-xl border border-border bg-muted",
|
|
2035
|
+
any ? "h-[min(12rem,32dvh)] w-[min(12rem,32dvh)]" : "h-48 w-48"
|
|
2036
|
+
),
|
|
2037
|
+
children: [
|
|
2038
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2039
|
+
"video",
|
|
2040
|
+
{
|
|
2041
|
+
ref: videoRef,
|
|
2042
|
+
"aria-label": S.video,
|
|
2043
|
+
"data-boff-explore": "avatar-live-video",
|
|
2044
|
+
playsInline: true,
|
|
2045
|
+
autoPlay: true,
|
|
2046
|
+
muted: true,
|
|
2047
|
+
onPlaying,
|
|
2048
|
+
className: chunkC6OJIHNO_js.cn("h-full w-full object-cover", !playing && "opacity-0")
|
|
2049
|
+
}
|
|
2050
|
+
),
|
|
2051
|
+
playing ? null : /* @__PURE__ */ jsxRuntime.jsx(
|
|
2052
|
+
"img",
|
|
2053
|
+
{
|
|
2054
|
+
src: still.src,
|
|
2055
|
+
alt: "",
|
|
2056
|
+
decoding: "async",
|
|
2057
|
+
className: "absolute inset-0 h-full w-full object-cover"
|
|
2058
|
+
}
|
|
2059
|
+
),
|
|
2060
|
+
any ? null : /* @__PURE__ */ jsxRuntime.jsx("audio", { ref: audioRef, "data-boff-explore": "avatar-live-audio" })
|
|
2061
|
+
]
|
|
2062
|
+
}
|
|
2063
|
+
);
|
|
2064
|
+
const liveBody = (session) => /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2065
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2066
|
+
"section",
|
|
2067
|
+
{
|
|
2068
|
+
"aria-label": S.captions,
|
|
2069
|
+
"data-boff-explore": "avatar-live-captions",
|
|
2070
|
+
lang: session.captions.locale || void 0,
|
|
2071
|
+
dir: "auto",
|
|
2072
|
+
tabIndex: 0,
|
|
2073
|
+
className: "max-h-32 w-full max-w-sm overflow-y-auto rounded-lg bg-muted p-3 text-start text-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
2074
|
+
children: session.captions.text
|
|
2075
|
+
}
|
|
2076
|
+
),
|
|
2077
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: S.answerInChat }),
|
|
2078
|
+
/* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-sm tabular-nums text-muted-foreground", children: [
|
|
2079
|
+
S.timeLeft,
|
|
2080
|
+
" ",
|
|
2081
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { role: "timer", "data-boff-explore": "avatar-live-countdown", children: clock(Math.max(0, (session.endsAt - now) / 1e3)) })
|
|
2082
|
+
] })
|
|
2083
|
+
] });
|
|
2084
|
+
const liveActions = (back) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center justify-center gap-2", children: [
|
|
2085
|
+
blocked ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2086
|
+
"button",
|
|
2087
|
+
{
|
|
2088
|
+
type: "button",
|
|
2089
|
+
"data-boff-explore": "avatar-live-sound",
|
|
2090
|
+
className: primaryButton,
|
|
2091
|
+
onClick: enablePlayback,
|
|
2092
|
+
children: S.tapForSound
|
|
2093
|
+
}
|
|
2094
|
+
) : null,
|
|
2095
|
+
stopButton,
|
|
2096
|
+
back
|
|
2097
|
+
] });
|
|
2098
|
+
const badge = /* @__PURE__ */ jsxRuntime.jsx(
|
|
2099
|
+
"p",
|
|
2100
|
+
{
|
|
2101
|
+
"data-boff-explore": "avatar-live-badge",
|
|
2102
|
+
className: "rounded-full bg-muted px-3 py-1 text-xs font-medium text-foreground",
|
|
2103
|
+
children: S.badge
|
|
2104
|
+
}
|
|
2105
|
+
);
|
|
2106
|
+
if (any) {
|
|
2107
|
+
let status = "";
|
|
2108
|
+
let outcome2 = false;
|
|
2109
|
+
let lead = null;
|
|
2110
|
+
let top2 = null;
|
|
2111
|
+
let media2 = stillPicture(false);
|
|
2112
|
+
let body2 = null;
|
|
2113
|
+
let actions2 = null;
|
|
2114
|
+
let newChatOffer = false;
|
|
2115
|
+
let box = null;
|
|
2116
|
+
const first = exchange.question;
|
|
2117
|
+
const questionLine = first === null ? null : /* @__PURE__ */ jsxRuntime.jsx(
|
|
2118
|
+
"p",
|
|
2119
|
+
{
|
|
2120
|
+
"data-boff-explore": "avatar-live-question",
|
|
2121
|
+
dir: "auto",
|
|
2122
|
+
className: "line-clamp-2 w-full max-w-sm break-words text-sm font-medium",
|
|
2123
|
+
children: first.content
|
|
2124
|
+
}
|
|
2125
|
+
);
|
|
2126
|
+
const activity = conversation?.activity ?? null;
|
|
2127
|
+
const activityLine = activity === null ? null : /* @__PURE__ */ jsxRuntime.jsx(
|
|
2128
|
+
"p",
|
|
2129
|
+
{
|
|
2130
|
+
"data-boff-explore": "avatar-live-activity",
|
|
2131
|
+
className: "text-xs text-muted-foreground",
|
|
2132
|
+
children: activity
|
|
2133
|
+
}
|
|
2134
|
+
);
|
|
2135
|
+
if (textMode) {
|
|
2136
|
+
const messages = conversation?.messages ?? [];
|
|
2137
|
+
let questionAt = messages.length - 1;
|
|
2138
|
+
while (questionAt >= 0 && messages[questionAt]?.role !== "USER") {
|
|
2139
|
+
questionAt -= 1;
|
|
2140
|
+
}
|
|
2141
|
+
const lastQuestion = questionAt === -1 ? void 0 : messages[questionAt];
|
|
2142
|
+
const after = questionAt === -1 ? void 0 : messages[questionAt + 1];
|
|
2143
|
+
const lastAnswer = after?.role === "ASSISTANT" ? after : void 0;
|
|
2144
|
+
const chatPhase = conversation?.phase;
|
|
2145
|
+
const unanswered = lastQuestion === void 0 || lastAnswer !== void 0 ? null : chatPhase === "sending" || chatPhase === "streaming" ? "waiting" : chatPhase === "error" || chatPhase === "limited" ? "failed" : null;
|
|
2146
|
+
if (phase.name === "refused") {
|
|
2147
|
+
status = S[REFUSAL_TEXT[phase.reason]];
|
|
2148
|
+
outcome2 = true;
|
|
2149
|
+
} else if (phase.name === "ended") {
|
|
2150
|
+
status = S[phase.how];
|
|
2151
|
+
outcome2 = true;
|
|
2152
|
+
}
|
|
2153
|
+
body2 = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2154
|
+
lastQuestion === void 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(
|
|
2155
|
+
"p",
|
|
2156
|
+
{
|
|
2157
|
+
"data-boff-explore": "avatar-live-question",
|
|
2158
|
+
dir: "auto",
|
|
2159
|
+
className: "line-clamp-2 w-full max-w-sm break-words text-sm font-medium",
|
|
2160
|
+
children: lastQuestion.content
|
|
2161
|
+
}
|
|
2162
|
+
),
|
|
2163
|
+
lastAnswer === void 0 ? unanswered === "waiting" ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: activity ?? S.gettingAnswer }) : unanswered === "failed" ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", children: S.answerFailed }) : null : lastAnswer.status === "PENDING" || lastAnswer.status === "RUNNING" ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: activity ?? S.gettingAnswer }) : lastAnswer.status === "FAILED" ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", children: S.answerFailed }) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
2164
|
+
"p",
|
|
2165
|
+
{
|
|
2166
|
+
"data-boff-explore": "avatar-live-text-answer",
|
|
2167
|
+
dir: "auto",
|
|
2168
|
+
className: "line-clamp-6 w-full max-w-sm whitespace-pre-wrap break-words text-start text-sm",
|
|
2169
|
+
children: lastAnswer.content
|
|
2170
|
+
}
|
|
2171
|
+
)
|
|
2172
|
+
] });
|
|
2173
|
+
const ended = phase.name === "ended";
|
|
2174
|
+
actions2 = lastAnswer === void 0 && unanswered !== "failed" && !ended ? null : readInChatButton(ended);
|
|
2175
|
+
box = "text";
|
|
2176
|
+
} else {
|
|
2177
|
+
switch (phase.name) {
|
|
2178
|
+
case "checking":
|
|
2179
|
+
status = S.checking;
|
|
2180
|
+
break;
|
|
2181
|
+
case "needs-answer":
|
|
2182
|
+
switch (shown.kind) {
|
|
2183
|
+
case "empty":
|
|
2184
|
+
status = note === "new-chat" ? S.newChatStarted : "";
|
|
2185
|
+
lead = /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-base font-semibold", children: S.askHeadline });
|
|
2186
|
+
box = "spoken";
|
|
2187
|
+
break;
|
|
2188
|
+
case "asking":
|
|
2189
|
+
case "answer": {
|
|
2190
|
+
const card = shown.askedHere && shown.pendingAnswerId !== null;
|
|
2191
|
+
status = note === "cancelled" ? S.armedCancelled : S.gettingAnswer;
|
|
2192
|
+
if (card) media2 = stillPicture(true);
|
|
2193
|
+
body2 = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2194
|
+
questionLine,
|
|
2195
|
+
activityLine,
|
|
2196
|
+
card ? consentCard(phase.offer.copy) : null
|
|
2197
|
+
] });
|
|
2198
|
+
actions2 = card ? consentActions(true) : null;
|
|
2199
|
+
break;
|
|
2200
|
+
}
|
|
2201
|
+
case "text-only":
|
|
2202
|
+
status = S.notSpoken;
|
|
2203
|
+
outcome2 = true;
|
|
2204
|
+
body2 = questionLine;
|
|
2205
|
+
actions2 = readInChatButton(false);
|
|
2206
|
+
newChatOffer = true;
|
|
2207
|
+
break;
|
|
2208
|
+
case "failed":
|
|
2209
|
+
status = S.answerFailed;
|
|
2210
|
+
outcome2 = true;
|
|
2211
|
+
body2 = questionLine;
|
|
2212
|
+
newChatOffer = true;
|
|
2213
|
+
break;
|
|
2214
|
+
case "ask-here":
|
|
2215
|
+
status = S.askHere;
|
|
2216
|
+
outcome2 = true;
|
|
2217
|
+
actions2 = readInChatButton(false);
|
|
2218
|
+
newChatOffer = true;
|
|
2219
|
+
break;
|
|
2220
|
+
default:
|
|
2221
|
+
status = S.startNewChat;
|
|
2222
|
+
outcome2 = true;
|
|
2223
|
+
body2 = /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", children: S.startNewChatDetailAny });
|
|
2224
|
+
actions2 = readInChatButton(false);
|
|
2225
|
+
newChatOffer = true;
|
|
2226
|
+
break;
|
|
2227
|
+
}
|
|
2228
|
+
break;
|
|
2229
|
+
case "consent":
|
|
2230
|
+
media2 = stillPicture(true);
|
|
2231
|
+
body2 = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2232
|
+
questionLine,
|
|
2233
|
+
consentCard(phase.offer.copy)
|
|
2234
|
+
] });
|
|
2235
|
+
actions2 = consentActions(false);
|
|
2236
|
+
break;
|
|
2237
|
+
case "declined":
|
|
2238
|
+
status = S.declined;
|
|
2239
|
+
actions2 = readInChatButton(true);
|
|
2240
|
+
break;
|
|
2241
|
+
case "waiting":
|
|
2242
|
+
status = S.armed;
|
|
2243
|
+
body2 = questionLine;
|
|
2244
|
+
actions2 = /* @__PURE__ */ jsxRuntime.jsx(
|
|
2245
|
+
"button",
|
|
2246
|
+
{
|
|
2247
|
+
type: "button",
|
|
2248
|
+
"data-avatar-primary": "",
|
|
2249
|
+
"data-boff-explore": "avatar-live-cancel",
|
|
2250
|
+
className: secondaryButton,
|
|
2251
|
+
onClick: stop,
|
|
2252
|
+
children: S.cancel
|
|
2253
|
+
}
|
|
2254
|
+
);
|
|
2255
|
+
break;
|
|
2256
|
+
case "refused":
|
|
2257
|
+
outcome2 = true;
|
|
2258
|
+
if (phase.reason === "not_eligible" || phase.reason === "answer_claimed") {
|
|
2259
|
+
status = phase.reason === "not_eligible" ? S.notEligibleAny : S.answerClaimed;
|
|
2260
|
+
actions2 = readInChatButton(false);
|
|
2261
|
+
newChatOffer = true;
|
|
2262
|
+
} else {
|
|
2263
|
+
status = S[REFUSAL_TEXT[phase.reason]];
|
|
2264
|
+
actions2 = continueButton;
|
|
2265
|
+
}
|
|
2266
|
+
break;
|
|
2267
|
+
case "bot-check":
|
|
2268
|
+
status = S.botCheck;
|
|
2269
|
+
actions2 = stopButton;
|
|
2270
|
+
break;
|
|
2271
|
+
case "creating":
|
|
2272
|
+
status = S.connecting;
|
|
2273
|
+
actions2 = stopButton;
|
|
2274
|
+
break;
|
|
2275
|
+
case "pending":
|
|
2276
|
+
case "live":
|
|
2277
|
+
status = phase.name === "live" ? S.speaking : S.connecting;
|
|
2278
|
+
top2 = badge;
|
|
2279
|
+
media2 = liveMedia(phase.name === "live");
|
|
2280
|
+
body2 = liveBody(phase.session);
|
|
2281
|
+
actions2 = liveActions(readInChatButton(false));
|
|
2282
|
+
break;
|
|
2283
|
+
case "ended":
|
|
2284
|
+
status = S[phase.how];
|
|
2285
|
+
outcome2 = true;
|
|
2286
|
+
actions2 = readInChatButton(true);
|
|
2287
|
+
newChatOffer = true;
|
|
2288
|
+
break;
|
|
2289
|
+
}
|
|
2290
|
+
}
|
|
2291
|
+
const reason = inFlight(conversation) ? S.askBusy : conversation?.canSend ? null : S.askUnavailable;
|
|
2292
|
+
const chips = box !== null && shown.kind === "empty" && prompts.length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
2293
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs font-medium text-muted-foreground", children: tryAsking }),
|
|
2294
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex max-h-28 flex-wrap gap-2 overflow-y-auto", children: prompts.map((prompt) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
2295
|
+
"button",
|
|
2296
|
+
{
|
|
2297
|
+
type: "button",
|
|
2298
|
+
"data-boff-explore": "avatar-live-chip",
|
|
2299
|
+
"aria-disabled": reason !== null ? "true" : void 0,
|
|
2300
|
+
className: "min-h-11 rounded-full border border-border bg-background px-3 py-2 text-start text-sm text-foreground transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring aria-disabled:cursor-not-allowed aria-disabled:opacity-50 motion-reduce:transition-none",
|
|
2301
|
+
onClick: () => {
|
|
2302
|
+
if (reason === null) ask(prompt);
|
|
2303
|
+
},
|
|
2304
|
+
children: prompt
|
|
2305
|
+
},
|
|
2306
|
+
prompt
|
|
2307
|
+
)) })
|
|
2308
|
+
] }) : null;
|
|
2309
|
+
const foot = box === null && !newChatOffer ? null : /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2310
|
+
"div",
|
|
2311
|
+
{
|
|
2312
|
+
"data-boff-explore": "avatar-live-foot",
|
|
2313
|
+
className: "flex shrink-0 flex-col gap-2 border-t border-border bg-background p-3 pb-[max(0.75rem,env(safe-area-inset-bottom))]",
|
|
2314
|
+
children: [
|
|
2315
|
+
newChatOffer ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center gap-1 text-center", children: [
|
|
2316
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2317
|
+
"button",
|
|
2318
|
+
{
|
|
2319
|
+
type: "button",
|
|
2320
|
+
"data-avatar-primary": "",
|
|
2321
|
+
"data-boff-explore": "avatar-live-new-chat-avatar",
|
|
2322
|
+
className: chunkC6OJIHNO_js.cn(primaryButton, "min-h-11"),
|
|
2323
|
+
onClick: newChatForAvatar,
|
|
2324
|
+
children: S.newChatForAvatar
|
|
2325
|
+
}
|
|
2326
|
+
),
|
|
2327
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: S.newChatNote })
|
|
2328
|
+
] }) : null,
|
|
2329
|
+
chips,
|
|
2330
|
+
box !== null && usedToday ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2331
|
+
"p",
|
|
2332
|
+
{
|
|
2333
|
+
"data-boff-explore": "avatar-live-used-today",
|
|
2334
|
+
className: "text-xs text-muted-foreground",
|
|
2335
|
+
children: S.usedToday
|
|
2336
|
+
}
|
|
2337
|
+
) : null,
|
|
2338
|
+
box === null ? null : /* @__PURE__ */ jsxRuntime.jsx(
|
|
2339
|
+
AskBox,
|
|
2340
|
+
{
|
|
2341
|
+
value: draft,
|
|
2342
|
+
maxLength: askMaxLength,
|
|
2343
|
+
onChange: setDraft,
|
|
2344
|
+
onAsk: ask,
|
|
2345
|
+
reason,
|
|
2346
|
+
label: S.askLabel,
|
|
2347
|
+
placeholder: S.askPlaceholder,
|
|
2348
|
+
send,
|
|
2349
|
+
footer: S.askFooter,
|
|
2350
|
+
noFiles: S.askNoFiles,
|
|
2351
|
+
hint: box === "spoken" ? S.needsAnswerAny : null,
|
|
2352
|
+
touchFirst
|
|
2353
|
+
}
|
|
2354
|
+
)
|
|
2355
|
+
]
|
|
2356
|
+
}
|
|
2357
|
+
);
|
|
2358
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2359
|
+
"div",
|
|
2360
|
+
{
|
|
2361
|
+
ref: rootRef,
|
|
2362
|
+
"data-boff-explore": "avatar-live",
|
|
2363
|
+
"data-phase": phase.name,
|
|
2364
|
+
"data-ask": askState,
|
|
2365
|
+
className: "absolute inset-0 flex flex-col bg-background",
|
|
2366
|
+
children: [
|
|
2367
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-h-0 flex-1 flex-col items-center gap-4 overflow-y-auto p-6 text-center", children: [
|
|
2368
|
+
top2,
|
|
2369
|
+
media2,
|
|
2370
|
+
lead,
|
|
2371
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2372
|
+
"p",
|
|
2373
|
+
{
|
|
2374
|
+
role: "status",
|
|
2375
|
+
"data-boff-explore": "avatar-live-status",
|
|
2376
|
+
className: outcome2 ? "text-base font-semibold" : "text-sm text-muted-foreground",
|
|
2377
|
+
children: status
|
|
2378
|
+
}
|
|
2379
|
+
),
|
|
2380
|
+
body2,
|
|
2381
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { ref: botBoxRef, "data-boff-explore": "avatar-live-bot-check" }),
|
|
2382
|
+
actions2
|
|
2383
|
+
] }),
|
|
2384
|
+
foot,
|
|
2385
|
+
/* @__PURE__ */ jsxRuntime.jsx("audio", { ref: audioRef, "data-boff-explore": "avatar-live-audio" })
|
|
2386
|
+
]
|
|
2387
|
+
}
|
|
2388
|
+
);
|
|
2389
|
+
}
|
|
1337
2390
|
const headline = {
|
|
1338
2391
|
idle: "",
|
|
1339
2392
|
checking: S.checking,
|
|
1340
2393
|
inert: "",
|
|
1341
|
-
|
|
2394
|
+
// A question asked and its answer on its way: the answer is coming (the avatar is offered once it completes).
|
|
2395
|
+
"needs-answer": startOver ? S.startNewChat : shown.kind === "asking" ? S.gettingAnswer : S.needsAnswer,
|
|
1342
2396
|
consent: "",
|
|
2397
|
+
declined: S.declined,
|
|
2398
|
+
waiting: S.armed,
|
|
1343
2399
|
refused: phase.name === "refused" ? S[REFUSAL_TEXT[phase.reason]] : "",
|
|
1344
2400
|
"bot-check": S.botCheck,
|
|
1345
2401
|
creating: S.connecting,
|
|
@@ -1357,65 +2413,11 @@ function AvatarLiveView({
|
|
|
1357
2413
|
body = /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", children: startOver ? S.startNewChatDetail : S.needsAnswerDetail });
|
|
1358
2414
|
actions = startOver ? startOverActions : continueButton;
|
|
1359
2415
|
break;
|
|
1360
|
-
case "consent":
|
|
1361
|
-
const { copy } = phase.offer;
|
|
2416
|
+
case "consent":
|
|
1362
2417
|
media = stillPicture(true);
|
|
1363
|
-
body =
|
|
1364
|
-
|
|
1365
|
-
{
|
|
1366
|
-
"aria-labelledby": consentTitleId,
|
|
1367
|
-
"data-boff-explore": "avatar-live-consent",
|
|
1368
|
-
className: "w-full max-w-sm rounded-lg border border-border p-4 text-start",
|
|
1369
|
-
children: [
|
|
1370
|
-
/* @__PURE__ */ jsxRuntime.jsx("h2", { id: consentTitleId, className: "text-base font-semibold", children: copy.title }),
|
|
1371
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-2 text-sm", children: productName === null || copy.introProduct === null ? copy.intro : chunkO4GS3XPZ_js.fill(copy.introProduct, { product: productName }) }),
|
|
1372
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-2 text-sm text-muted-foreground", children: copy.processing }),
|
|
1373
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-2 text-sm text-muted-foreground", children: copy.storage }),
|
|
1374
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1375
|
-
"a",
|
|
1376
|
-
{
|
|
1377
|
-
href: PRIVACY_HREF,
|
|
1378
|
-
target: "_blank",
|
|
1379
|
-
rel: "noopener noreferrer",
|
|
1380
|
-
"data-boff-explore": "avatar-live-privacy",
|
|
1381
|
-
className: "mt-2 inline-block text-sm font-medium text-primary underline underline-offset-2 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
1382
|
-
children: [
|
|
1383
|
-
copy.privacyLink,
|
|
1384
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "sr-only", children: [
|
|
1385
|
-
" ",
|
|
1386
|
-
S.opensInNewTab
|
|
1387
|
-
] })
|
|
1388
|
-
]
|
|
1389
|
-
}
|
|
1390
|
-
)
|
|
1391
|
-
]
|
|
1392
|
-
}
|
|
1393
|
-
);
|
|
1394
|
-
actions = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center justify-center gap-2", children: [
|
|
1395
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1396
|
-
"button",
|
|
1397
|
-
{
|
|
1398
|
-
type: "button",
|
|
1399
|
-
"data-avatar-primary": "",
|
|
1400
|
-
"data-boff-explore": "avatar-live-start",
|
|
1401
|
-
className: primaryButton,
|
|
1402
|
-
onClick: start,
|
|
1403
|
-
children: S.start
|
|
1404
|
-
}
|
|
1405
|
-
),
|
|
1406
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1407
|
-
"button",
|
|
1408
|
-
{
|
|
1409
|
-
type: "button",
|
|
1410
|
-
"data-boff-explore": "avatar-live-not-now",
|
|
1411
|
-
className: secondaryButton,
|
|
1412
|
-
onClick: onContinueInChat,
|
|
1413
|
-
children: S.notNow
|
|
1414
|
-
}
|
|
1415
|
-
)
|
|
1416
|
-
] });
|
|
2418
|
+
body = consentCard(phase.offer.copy);
|
|
2419
|
+
actions = consentActions(false);
|
|
1417
2420
|
break;
|
|
1418
|
-
}
|
|
1419
2421
|
case "refused":
|
|
1420
2422
|
actions = phase.reason === "not_eligible" ? startOverActions : continueButton;
|
|
1421
2423
|
break;
|
|
@@ -1424,77 +2426,11 @@ function AvatarLiveView({
|
|
|
1424
2426
|
actions = stopButton;
|
|
1425
2427
|
break;
|
|
1426
2428
|
case "pending":
|
|
1427
|
-
case "live":
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
{
|
|
1433
|
-
"data-boff-explore": "avatar-live-badge",
|
|
1434
|
-
className: "rounded-full bg-muted px-3 py-1 text-xs font-medium text-foreground",
|
|
1435
|
-
children: S.badge
|
|
1436
|
-
}
|
|
1437
|
-
);
|
|
1438
|
-
media = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative h-48 w-48 shrink-0 overflow-hidden rounded-xl border border-border bg-muted", children: [
|
|
1439
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1440
|
-
"video",
|
|
1441
|
-
{
|
|
1442
|
-
ref: videoRef,
|
|
1443
|
-
"aria-label": S.video,
|
|
1444
|
-
"data-boff-explore": "avatar-live-video",
|
|
1445
|
-
playsInline: true,
|
|
1446
|
-
autoPlay: true,
|
|
1447
|
-
muted: true,
|
|
1448
|
-
onPlaying,
|
|
1449
|
-
className: chunkC6OJIHNO_js.cn(
|
|
1450
|
-
"h-full w-full object-cover",
|
|
1451
|
-
!playing && "opacity-0"
|
|
1452
|
-
)
|
|
1453
|
-
}
|
|
1454
|
-
),
|
|
1455
|
-
playing ? null : /* @__PURE__ */ jsxRuntime.jsx(
|
|
1456
|
-
"img",
|
|
1457
|
-
{
|
|
1458
|
-
src: still.src,
|
|
1459
|
-
alt: "",
|
|
1460
|
-
decoding: "async",
|
|
1461
|
-
className: "absolute inset-0 h-full w-full object-cover"
|
|
1462
|
-
}
|
|
1463
|
-
),
|
|
1464
|
-
/* @__PURE__ */ jsxRuntime.jsx("audio", { ref: audioRef, "data-boff-explore": "avatar-live-audio" })
|
|
1465
|
-
] });
|
|
1466
|
-
body = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1467
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1468
|
-
"section",
|
|
1469
|
-
{
|
|
1470
|
-
"aria-label": S.captions,
|
|
1471
|
-
"data-boff-explore": "avatar-live-captions",
|
|
1472
|
-
lang: phase.session.captions.locale || void 0,
|
|
1473
|
-
dir: "auto",
|
|
1474
|
-
tabIndex: 0,
|
|
1475
|
-
className: "max-h-32 w-full max-w-sm overflow-y-auto rounded-lg bg-muted p-3 text-start text-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
1476
|
-
children: phase.session.captions.text
|
|
1477
|
-
}
|
|
1478
|
-
),
|
|
1479
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: S.answerInChat }),
|
|
1480
|
-
/* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-sm tabular-nums text-muted-foreground", children: [
|
|
1481
|
-
S.timeLeft,
|
|
1482
|
-
" ",
|
|
1483
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { role: "timer", "data-boff-explore": "avatar-live-countdown", children: clock(left) })
|
|
1484
|
-
] })
|
|
1485
|
-
] });
|
|
1486
|
-
actions = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center justify-center gap-2", children: [
|
|
1487
|
-
blocked ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
1488
|
-
"button",
|
|
1489
|
-
{
|
|
1490
|
-
type: "button",
|
|
1491
|
-
"data-boff-explore": "avatar-live-sound",
|
|
1492
|
-
className: primaryButton,
|
|
1493
|
-
onClick: enablePlayback,
|
|
1494
|
-
children: S.tapForSound
|
|
1495
|
-
}
|
|
1496
|
-
) : null,
|
|
1497
|
-
stopButton,
|
|
2429
|
+
case "live":
|
|
2430
|
+
top = badge;
|
|
2431
|
+
media = liveMedia(phase.name === "live");
|
|
2432
|
+
body = liveBody(phase.session);
|
|
2433
|
+
actions = liveActions(
|
|
1498
2434
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1499
2435
|
"button",
|
|
1500
2436
|
{
|
|
@@ -1505,9 +2441,8 @@ function AvatarLiveView({
|
|
|
1505
2441
|
children: continueInChat
|
|
1506
2442
|
}
|
|
1507
2443
|
)
|
|
1508
|
-
|
|
2444
|
+
);
|
|
1509
2445
|
break;
|
|
1510
|
-
}
|
|
1511
2446
|
case "ended":
|
|
1512
2447
|
body = /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", children: S.answerInChat });
|
|
1513
2448
|
actions = /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -1549,6 +2484,119 @@ function AvatarLiveView({
|
|
|
1549
2484
|
}
|
|
1550
2485
|
);
|
|
1551
2486
|
}
|
|
2487
|
+
function AskBox({
|
|
2488
|
+
value,
|
|
2489
|
+
maxLength,
|
|
2490
|
+
onChange,
|
|
2491
|
+
onAsk,
|
|
2492
|
+
reason,
|
|
2493
|
+
label,
|
|
2494
|
+
placeholder,
|
|
2495
|
+
send,
|
|
2496
|
+
footer,
|
|
2497
|
+
noFiles,
|
|
2498
|
+
hint,
|
|
2499
|
+
touchFirst
|
|
2500
|
+
}) {
|
|
2501
|
+
const uid = react.useId();
|
|
2502
|
+
const reasonId = `${uid}-reason`;
|
|
2503
|
+
const hintId = `${uid}-hint`;
|
|
2504
|
+
const footerId = `${uid}-footer`;
|
|
2505
|
+
const [refusedFiles, setRefusedFiles] = react.useState(false);
|
|
2506
|
+
const empty = value.trim() === "";
|
|
2507
|
+
const submit = () => {
|
|
2508
|
+
if (reason !== null || empty) return;
|
|
2509
|
+
onAsk(value);
|
|
2510
|
+
};
|
|
2511
|
+
const onKeyDown = (event) => {
|
|
2512
|
+
if (event.nativeEvent.isComposing || event.keyCode === 229) {
|
|
2513
|
+
if (event.key === "Escape") event.stopPropagation();
|
|
2514
|
+
return;
|
|
2515
|
+
}
|
|
2516
|
+
if (event.key === "Enter" && !event.shiftKey) {
|
|
2517
|
+
event.preventDefault();
|
|
2518
|
+
submit();
|
|
2519
|
+
}
|
|
2520
|
+
};
|
|
2521
|
+
const onPaste = (event) => {
|
|
2522
|
+
if (event.clipboardData.files.length === 0) return;
|
|
2523
|
+
event.preventDefault();
|
|
2524
|
+
setRefusedFiles(true);
|
|
2525
|
+
};
|
|
2526
|
+
const onDrop = (event) => {
|
|
2527
|
+
if (!Array.from(event.dataTransfer.types).includes("Files")) return;
|
|
2528
|
+
event.preventDefault();
|
|
2529
|
+
setRefusedFiles(true);
|
|
2530
|
+
};
|
|
2531
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2532
|
+
"form",
|
|
2533
|
+
{
|
|
2534
|
+
"data-boff-explore": "avatar-live-ask",
|
|
2535
|
+
className: "flex w-full flex-col gap-1",
|
|
2536
|
+
onSubmit: (event) => {
|
|
2537
|
+
event.preventDefault();
|
|
2538
|
+
submit();
|
|
2539
|
+
},
|
|
2540
|
+
children: [
|
|
2541
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-end gap-2", children: [
|
|
2542
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2543
|
+
"textarea",
|
|
2544
|
+
{
|
|
2545
|
+
value,
|
|
2546
|
+
rows: 1,
|
|
2547
|
+
maxLength,
|
|
2548
|
+
"aria-label": label,
|
|
2549
|
+
"aria-describedby": hint === null ? footerId : `${hintId} ${footerId}`,
|
|
2550
|
+
placeholder,
|
|
2551
|
+
dir: "auto",
|
|
2552
|
+
"data-avatar-primary": touchFirst ? void 0 : "",
|
|
2553
|
+
"data-boff-explore": "avatar-live-ask-input",
|
|
2554
|
+
className: "max-h-32 min-h-11 flex-1 resize-none rounded-md border border-border bg-background px-3 py-2.5 text-base text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring sm:text-sm",
|
|
2555
|
+
onChange: (event) => {
|
|
2556
|
+
setRefusedFiles(false);
|
|
2557
|
+
onChange(event.target.value);
|
|
2558
|
+
},
|
|
2559
|
+
onKeyDown,
|
|
2560
|
+
onPaste,
|
|
2561
|
+
onDrop
|
|
2562
|
+
}
|
|
2563
|
+
),
|
|
2564
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2565
|
+
"button",
|
|
2566
|
+
{
|
|
2567
|
+
type: "submit",
|
|
2568
|
+
"aria-disabled": reason !== null || empty ? "true" : void 0,
|
|
2569
|
+
"aria-describedby": reason !== null ? reasonId : void 0,
|
|
2570
|
+
"data-avatar-primary": touchFirst ? "" : void 0,
|
|
2571
|
+
"data-boff-explore": "avatar-live-ask-send",
|
|
2572
|
+
className: "inline-flex h-11 min-w-11 shrink-0 items-center justify-center rounded-md bg-primary px-4 text-sm font-medium text-primary-foreground transition-opacity hover:opacity-90 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background aria-disabled:cursor-not-allowed aria-disabled:opacity-50 motion-reduce:transition-none",
|
|
2573
|
+
children: send
|
|
2574
|
+
}
|
|
2575
|
+
)
|
|
2576
|
+
] }),
|
|
2577
|
+
reason === null ? null : /* @__PURE__ */ jsxRuntime.jsx(
|
|
2578
|
+
"p",
|
|
2579
|
+
{
|
|
2580
|
+
id: reasonId,
|
|
2581
|
+
"data-boff-explore": "avatar-live-ask-reason",
|
|
2582
|
+
className: "text-xs text-muted-foreground",
|
|
2583
|
+
children: reason
|
|
2584
|
+
}
|
|
2585
|
+
),
|
|
2586
|
+
refusedFiles ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2587
|
+
"p",
|
|
2588
|
+
{
|
|
2589
|
+
"data-boff-explore": "avatar-live-ask-files",
|
|
2590
|
+
className: "text-xs text-muted-foreground",
|
|
2591
|
+
children: noFiles
|
|
2592
|
+
}
|
|
2593
|
+
) : null,
|
|
2594
|
+
hint === null ? null : /* @__PURE__ */ jsxRuntime.jsx("p", { id: hintId, className: "sr-only", children: hint }),
|
|
2595
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { id: footerId, className: "text-xs text-muted-foreground", children: footer })
|
|
2596
|
+
]
|
|
2597
|
+
}
|
|
2598
|
+
);
|
|
2599
|
+
}
|
|
1552
2600
|
|
|
1553
2601
|
exports.AvatarLiveView = AvatarLiveView;
|
|
1554
2602
|
//# sourceMappingURL=index.js.map
|