ttp-agent-sdk 2.46.3 → 2.48.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent-widget.dev.js +1404 -192
- package/dist/agent-widget.esm.js +1 -2
- package/dist/agent-widget.js +1 -2
- package/dist/demos/index.html +19 -0
- package/dist/demos/rimon-trips.html +415 -0
- package/dist/examples/rimon-trips.html +415 -0
- package/dist/examples/test-index.html +19 -0
- package/examples/rimon-trips.html +415 -0
- package/examples/test-index.html +19 -0
- package/package.json +8 -3
- package/dist/agent-widget.dev.js.map +0 -1
- package/dist/agent-widget.esm.js.map +0 -1
- package/dist/agent-widget.js.map +0 -1
package/dist/agent-widget.dev.js
CHANGED
|
@@ -9644,6 +9644,7 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
|
|
|
9644
9644
|
"use strict";
|
|
9645
9645
|
__webpack_require__.r(__webpack_exports__);
|
|
9646
9646
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
9647
|
+
/* harmony export */ buildAudioConstraints: () => (/* binding */ buildAudioConstraints),
|
|
9647
9648
|
/* harmony export */ "default": () => (/* binding */ AudioRecorder)
|
|
9648
9649
|
/* harmony export */ });
|
|
9649
9650
|
/* harmony import */ var _EventEmitter_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./EventEmitter.js */ "./src/core/EventEmitter.js");
|
|
@@ -11993,7 +11994,7 @@ var TextChatSDK = /*#__PURE__*/function (_EventEmitter) {
|
|
|
11993
11994
|
|
|
11994
11995
|
// SDK build time for debugging
|
|
11995
11996
|
if (true) {
|
|
11996
|
-
helloMessage.lastBuildTime = "2026-
|
|
11997
|
+
helloMessage.lastBuildTime = "2026-08-02T10:38:16.158Z";
|
|
11997
11998
|
}
|
|
11998
11999
|
try {
|
|
11999
12000
|
this.ws.send(JSON.stringify(helloMessage));
|
|
@@ -15310,7 +15311,8 @@ var MobileProductCarousel = /*#__PURE__*/function () {
|
|
|
15310
15311
|
__webpack_require__.r(__webpack_exports__);
|
|
15311
15312
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
15312
15313
|
/* harmony export */ PartnerScriptRunner: () => (/* binding */ PartnerScriptRunner),
|
|
15313
|
-
/* harmony export */ buildRunPartnerScriptTool: () => (/* binding */ buildRunPartnerScriptTool)
|
|
15314
|
+
/* harmony export */ buildRunPartnerScriptTool: () => (/* binding */ buildRunPartnerScriptTool),
|
|
15315
|
+
/* harmony export */ compileAdapter: () => (/* binding */ compileAdapter)
|
|
15314
15316
|
/* harmony export */ });
|
|
15315
15317
|
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
15316
15318
|
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
@@ -15476,19 +15478,62 @@ var AsyncFunction = Object.getPrototypeOf(/*#__PURE__*/_asyncToGenerator(/*#__PU
|
|
|
15476
15478
|
// back to compiling the code as a plain body. AsyncFunction (not
|
|
15477
15479
|
// `new Function`) enforces an async execution context — no accidental sync
|
|
15478
15480
|
// adapter bodies.
|
|
15481
|
+
//
|
|
15482
|
+
// Detection runs against the code with leading comments removed. Adapters are
|
|
15483
|
+
// routinely authored with a header comment block above the function, and a
|
|
15484
|
+
// header-prefixed function expression that falls through to body compilation
|
|
15485
|
+
// is a *silent* no-op: `// h\nasync (ctx) => {...}` is a syntactically valid
|
|
15486
|
+
// statement body that merely constructs the arrow and discards it, so the
|
|
15487
|
+
// adapter compiles, "succeeds", and returns undefined without ever running.
|
|
15479
15488
|
var FN_EXPR_RE = /^\s*(async[\s(])|^\s*function\b|^\s*\(|^\s*[A-Za-z_$][\w$]*\s*=>/;
|
|
15489
|
+
|
|
15490
|
+
// Drop leading whitespace and `//` / `/* */` comments. Detection-only — the
|
|
15491
|
+
// original source is always what gets compiled, so comments (and the line
|
|
15492
|
+
// numbers they occupy in stack traces) are preserved.
|
|
15493
|
+
function stripLeadingComments(code) {
|
|
15494
|
+
var i = 0;
|
|
15495
|
+
for (;;) {
|
|
15496
|
+
while (i < code.length && /\s/.test(code[i])) i++;
|
|
15497
|
+
if (code.startsWith('//', i)) {
|
|
15498
|
+
var nl = code.indexOf('\n', i);
|
|
15499
|
+
if (nl === -1) return '';
|
|
15500
|
+
i = nl + 1;
|
|
15501
|
+
} else if (code.startsWith('/*', i)) {
|
|
15502
|
+
var end = code.indexOf('*/', i + 2);
|
|
15503
|
+
if (end === -1) return '';
|
|
15504
|
+
i = end + 2;
|
|
15505
|
+
} else {
|
|
15506
|
+
return code.slice(i);
|
|
15507
|
+
}
|
|
15508
|
+
}
|
|
15509
|
+
}
|
|
15510
|
+
|
|
15511
|
+
/**
|
|
15512
|
+
* Exported so the offline adapter verifier (`scripts/verify-adapter.mjs`) can
|
|
15513
|
+
* gate authored scripts through the exact compiler the SDK uses at runtime,
|
|
15514
|
+
* rather than a copy that can drift out of sync with it.
|
|
15515
|
+
* @returns {{fn: Function, style: 'expression'|'body'}}
|
|
15516
|
+
*/
|
|
15480
15517
|
function compileAdapter(codeJs) {
|
|
15481
|
-
if (FN_EXPR_RE.test(codeJs)) {
|
|
15518
|
+
if (FN_EXPR_RE.test(stripLeadingComments(codeJs))) {
|
|
15482
15519
|
try {
|
|
15520
|
+
// Newline before `)` so a trailing `//` comment can't swallow it.
|
|
15483
15521
|
// eslint-disable-next-line no-new-func
|
|
15484
|
-
|
|
15522
|
+
var fn = new AsyncFunction('ctx', "\"use strict\"; return (".concat(codeJs, "\n).call(null, ctx);"));
|
|
15523
|
+
return {
|
|
15524
|
+
fn: fn,
|
|
15525
|
+
style: 'expression'
|
|
15526
|
+
};
|
|
15485
15527
|
} catch (e) {
|
|
15486
15528
|
// Looked like an expression but doesn't parse as one (e.g. an
|
|
15487
15529
|
// IIFE-opening statement body) — fall through to body compilation.
|
|
15488
15530
|
}
|
|
15489
15531
|
}
|
|
15490
15532
|
// eslint-disable-next-line no-new-func
|
|
15491
|
-
return
|
|
15533
|
+
return {
|
|
15534
|
+
fn: new AsyncFunction('ctx', "\"use strict\"; ".concat(codeJs)),
|
|
15535
|
+
style: 'body'
|
|
15536
|
+
};
|
|
15492
15537
|
}
|
|
15493
15538
|
|
|
15494
15539
|
// Cheap 32-bit string hash, rendered as 12 hex chars. NOT cryptographic —
|
|
@@ -15607,7 +15652,7 @@ var PartnerScriptRunner = /*#__PURE__*/function () {
|
|
|
15607
15652
|
var opts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
15608
15653
|
_classCallCheck(this, PartnerScriptRunner);
|
|
15609
15654
|
this.genericCtx = !!(opts && opts.genericCtx);
|
|
15610
|
-
/** @type {Map<string, {fn?: Function, version?: number, codeSha256?: string, meta?: object, category?: string|null, beforeActions?: string[], afterActions?: string[], poisoned?: boolean, error?: string}>} */
|
|
15655
|
+
/** @type {Map<string, {fn?: Function, style?: 'expression'|'body', version?: number, codeSha256?: string, meta?: object, category?: string|null, beforeActions?: string[], afterActions?: string[], poisoned?: boolean, error?: string}>} */
|
|
15611
15656
|
this.adapters = new Map();
|
|
15612
15657
|
this.partnerId = null;
|
|
15613
15658
|
this.platform = null;
|
|
@@ -15658,14 +15703,17 @@ var PartnerScriptRunner = /*#__PURE__*/function () {
|
|
|
15658
15703
|
}
|
|
15659
15704
|
try {
|
|
15660
15705
|
var _entry$version2, _entry$category;
|
|
15661
|
-
var
|
|
15706
|
+
var _compileAdapter = compileAdapter(entry.code_js),
|
|
15707
|
+
fn = _compileAdapter.fn,
|
|
15708
|
+
style = _compileAdapter.style;
|
|
15662
15709
|
// Inline pre/post hooks (optional). Compiled with the same
|
|
15663
15710
|
// AsyncFunction strict-mode wrapper as the main body so a syntax
|
|
15664
15711
|
// error in a hook poisons only this entry (caught below).
|
|
15665
|
-
var preFn = typeof entry.pre_code_js === 'string' ? compileAdapter(entry.pre_code_js) : null;
|
|
15666
|
-
var postFn = typeof entry.post_code_js === 'string' ? compileAdapter(entry.post_code_js) : null;
|
|
15712
|
+
var preFn = typeof entry.pre_code_js === 'string' ? compileAdapter(entry.pre_code_js).fn : null;
|
|
15713
|
+
var postFn = typeof entry.post_code_js === 'string' ? compileAdapter(entry.post_code_js).fn : null;
|
|
15667
15714
|
this.adapters.set(action, {
|
|
15668
15715
|
fn: fn,
|
|
15716
|
+
style: style,
|
|
15669
15717
|
preFn: preFn,
|
|
15670
15718
|
postFn: postFn,
|
|
15671
15719
|
version: (_entry$version2 = entry.version) !== null && _entry$version2 !== void 0 ? _entry$version2 : null,
|
|
@@ -15932,7 +15980,7 @@ var PartnerScriptRunner = /*#__PURE__*/function () {
|
|
|
15932
15980
|
}
|
|
15933
15981
|
}
|
|
15934
15982
|
ctx = this._buildCtx(args, action, entry);
|
|
15935
|
-
console.log("".concat(LOG, " exec ").concat(action, " v").concat((_entry$version4 = entry.version) !== null && _entry$version4 !== void 0 ? _entry$version4 : '?', " ") + "sha=".concat((entry.codeSha256 || '').slice(0, 12)));
|
|
15983
|
+
console.log("".concat(LOG, " exec ").concat(action, " v").concat((_entry$version4 = entry.version) !== null && _entry$version4 !== void 0 ? _entry$version4 : '?', " ") + "sha=".concat((entry.codeSha256 || '').slice(0, 12), " as=").concat(entry.style || '?'));
|
|
15936
15984
|
|
|
15937
15985
|
// Inline pre-hook (best-effort): an error is logged and main still runs.
|
|
15938
15986
|
if (!entry.preFn) {
|
|
@@ -21205,8 +21253,8 @@ var VoiceSDK = _v2_VoiceSDK_js__WEBPACK_IMPORTED_MODULE_0__["default"];
|
|
|
21205
21253
|
|
|
21206
21254
|
|
|
21207
21255
|
// Version - injected at build time from package.json via webpack DefinePlugin
|
|
21208
|
-
var VERSION = "2.
|
|
21209
|
-
var BUILD_TIME = "2026-
|
|
21256
|
+
var VERSION = "2.48.0";
|
|
21257
|
+
var BUILD_TIME = "2026-08-02T10:38:16.158Z";
|
|
21210
21258
|
console.log("%c TTP Agent SDK v".concat(VERSION, " (").concat(BUILD_TIME, ") "), 'background: #4f46e5; color: white; font-size: 12px; font-weight: bold; padding: 2px 6px; border-radius: 4px;');
|
|
21211
21259
|
|
|
21212
21260
|
// Named exports
|
|
@@ -28536,6 +28584,8 @@ var VoiceSDK_v2 = /*#__PURE__*/function (_EventEmitter) {
|
|
|
28536
28584
|
// The backend analyzes the audio stream and detects when user interrupts
|
|
28537
28585
|
// Frontend only responds to backend 'barge_in' messages (handled in handleMessage())
|
|
28538
28586
|
|
|
28587
|
+
// Report the capture track's real settings (AEC ground truth) to the backend
|
|
28588
|
+
_this4._sendClientAudioInfo();
|
|
28539
28589
|
_this4.emit('recordingStarted');
|
|
28540
28590
|
});
|
|
28541
28591
|
this.audioRecorder.on('recordingStopped', function () {
|
|
@@ -28809,6 +28859,83 @@ var VoiceSDK_v2 = /*#__PURE__*/function (_EventEmitter) {
|
|
|
28809
28859
|
fullLocale: fullLocale
|
|
28810
28860
|
};
|
|
28811
28861
|
}
|
|
28862
|
+
|
|
28863
|
+
/**
|
|
28864
|
+
* Client environment snapshot sent in hello (`client` field). Static facts known
|
|
28865
|
+
* before the mic opens — device/browser identification for backend logs + Langfuse
|
|
28866
|
+
* trace metadata. Audio-track ground truth (AEC etc.) is sent separately via
|
|
28867
|
+
* client_audio_info once recording starts, because track settings don't exist yet.
|
|
28868
|
+
*/
|
|
28869
|
+
}, {
|
|
28870
|
+
key: "_buildClientEnv",
|
|
28871
|
+
value: function _buildClientEnv() {
|
|
28872
|
+
try {
|
|
28873
|
+
var _uaData$mobile, _window$screen, _window$screen2;
|
|
28874
|
+
var ua = navigator.userAgent || '';
|
|
28875
|
+
var uaData = navigator.userAgentData;
|
|
28876
|
+
var conn = navigator.connection || navigator.mozConnection || navigator.webkitConnection;
|
|
28877
|
+
var isAndroid = /Android/i.test(ua);
|
|
28878
|
+
var isIos = /iPhone|iPad|iPod/i.test(ua) || ua.includes('Mac') && 'ontouchend' in document;
|
|
28879
|
+
// Webview heuristic: Android WebView marks itself with "; wv)" or "Version/x.x Chrome";
|
|
28880
|
+
// iOS in-app webviews lack "Safari" in the UA (real Safari always has it).
|
|
28881
|
+
var webview = isAndroid && (/\bwv\b/.test(ua) || /Version\/[\d.]+.*Chrome/.test(ua)) || isIos && !/Safari/i.test(ua) || false;
|
|
28882
|
+
var env = {
|
|
28883
|
+
sdkVersion: true ? "2.48.0" : 0,
|
|
28884
|
+
ua: ua,
|
|
28885
|
+
platform: (uaData === null || uaData === void 0 ? void 0 : uaData.platform) || navigator.platform || '',
|
|
28886
|
+
mobile: (_uaData$mobile = uaData === null || uaData === void 0 ? void 0 : uaData.mobile) !== null && _uaData$mobile !== void 0 ? _uaData$mobile : isAndroid || isIos,
|
|
28887
|
+
os: isIos ? 'ios' : isAndroid ? 'android' : 'other',
|
|
28888
|
+
webview: webview,
|
|
28889
|
+
screen: "".concat(((_window$screen = window.screen) === null || _window$screen === void 0 ? void 0 : _window$screen.width) || 0, "x").concat(((_window$screen2 = window.screen) === null || _window$screen2 === void 0 ? void 0 : _window$screen2.height) || 0, "@").concat(window.devicePixelRatio || 1),
|
|
28890
|
+
cores: navigator.hardwareConcurrency || null,
|
|
28891
|
+
memoryGb: navigator.deviceMemory || null,
|
|
28892
|
+
connection: (conn === null || conn === void 0 ? void 0 : conn.effectiveType) || null
|
|
28893
|
+
};
|
|
28894
|
+
return env;
|
|
28895
|
+
} catch (e) {
|
|
28896
|
+
console.warn('⚠️ VoiceSDK v2: Failed to build client env:', e);
|
|
28897
|
+
return {
|
|
28898
|
+
sdkVersion: true ? "2.48.0" : 0
|
|
28899
|
+
};
|
|
28900
|
+
}
|
|
28901
|
+
}
|
|
28902
|
+
|
|
28903
|
+
/**
|
|
28904
|
+
* One-shot telemetry sent right after recording starts (t:'client_audio_info').
|
|
28905
|
+
* Reports the capture track's ACTUAL settings from getSettings() — echoCancellation /
|
|
28906
|
+
* noiseSuppression / autoGainControl as the browser really applied them (not what we
|
|
28907
|
+
* requested), which is the ground truth for diagnosing speakerphone echo barge-in —
|
|
28908
|
+
* plus mic label, AudioContext rates, and whether the minimal-constraints fallback fired.
|
|
28909
|
+
*/
|
|
28910
|
+
}, {
|
|
28911
|
+
key: "_sendClientAudioInfo",
|
|
28912
|
+
value: function _sendClientAudioInfo() {
|
|
28913
|
+
try {
|
|
28914
|
+
var _this$audioRecorder, _this$audioRecorder$g, _s$echoCancellation, _s$noiseSuppression, _s$autoGainControl, _s$voiceIsolation, _s$sampleRate, _s$channelCount, _this$audioRecorder2, _this$audioPlayer, _this$audioRecorder3;
|
|
28915
|
+
var track = (_this$audioRecorder = this.audioRecorder) === null || _this$audioRecorder === void 0 || (_this$audioRecorder = _this$audioRecorder.mediaStream) === null || _this$audioRecorder === void 0 || (_this$audioRecorder$g = _this$audioRecorder.getAudioTracks) === null || _this$audioRecorder$g === void 0 ? void 0 : _this$audioRecorder$g.call(_this$audioRecorder)[0];
|
|
28916
|
+
if (!track) return;
|
|
28917
|
+
var s = track.getSettings ? track.getSettings() : {};
|
|
28918
|
+
var audio = {
|
|
28919
|
+
aec: (_s$echoCancellation = s.echoCancellation) !== null && _s$echoCancellation !== void 0 ? _s$echoCancellation : null,
|
|
28920
|
+
ns: (_s$noiseSuppression = s.noiseSuppression) !== null && _s$noiseSuppression !== void 0 ? _s$noiseSuppression : null,
|
|
28921
|
+
agc: (_s$autoGainControl = s.autoGainControl) !== null && _s$autoGainControl !== void 0 ? _s$autoGainControl : null,
|
|
28922
|
+
voiceIsolation: (_s$voiceIsolation = s.voiceIsolation) !== null && _s$voiceIsolation !== void 0 ? _s$voiceIsolation : null,
|
|
28923
|
+
trackRate: (_s$sampleRate = s.sampleRate) !== null && _s$sampleRate !== void 0 ? _s$sampleRate : null,
|
|
28924
|
+
channels: (_s$channelCount = s.channelCount) !== null && _s$channelCount !== void 0 ? _s$channelCount : null,
|
|
28925
|
+
mic: track.label || null,
|
|
28926
|
+
captureCtxRate: ((_this$audioRecorder2 = this.audioRecorder) === null || _this$audioRecorder2 === void 0 || (_this$audioRecorder2 = _this$audioRecorder2.audioContext) === null || _this$audioRecorder2 === void 0 ? void 0 : _this$audioRecorder2.sampleRate) || null,
|
|
28927
|
+
playbackCtxRate: ((_this$audioPlayer = this.audioPlayer) === null || _this$audioPlayer === void 0 || (_this$audioPlayer = _this$audioPlayer.audioContext) === null || _this$audioPlayer === void 0 ? void 0 : _this$audioPlayer.sampleRate) || null,
|
|
28928
|
+
constraintsFallback: ((_this$audioRecorder3 = this.audioRecorder) === null || _this$audioRecorder3 === void 0 || (_this$audioRecorder3 = _this$audioRecorder3.mediaStream) === null || _this$audioRecorder3 === void 0 ? void 0 : _this$audioRecorder3._ttpConstraintsFallback) === true
|
|
28929
|
+
};
|
|
28930
|
+
this.sendMessage({
|
|
28931
|
+
t: 'client_audio_info',
|
|
28932
|
+
audio: audio
|
|
28933
|
+
});
|
|
28934
|
+
console.log('🎛️ VoiceSDK v2: Sent client_audio_info:', audio);
|
|
28935
|
+
} catch (e) {
|
|
28936
|
+
console.warn('⚠️ VoiceSDK v2: Failed to send client_audio_info:', e);
|
|
28937
|
+
}
|
|
28938
|
+
}
|
|
28812
28939
|
}, {
|
|
28813
28940
|
key: "sendHelloMessage",
|
|
28814
28941
|
value: function () {
|
|
@@ -28909,9 +29036,12 @@ var VoiceSDK_v2 = /*#__PURE__*/function (_EventEmitter) {
|
|
|
28909
29036
|
|
|
28910
29037
|
// Include SDK build time for debugging
|
|
28911
29038
|
if (true) {
|
|
28912
|
-
helloMessage.lastBuildTime = "2026-
|
|
29039
|
+
helloMessage.lastBuildTime = "2026-08-02T10:38:16.158Z";
|
|
28913
29040
|
}
|
|
28914
29041
|
|
|
29042
|
+
// Client environment (device/browser/webview) for backend logs + Langfuse metadata
|
|
29043
|
+
helloMessage.client = this._buildClientEnv();
|
|
29044
|
+
|
|
28915
29045
|
// Page context is intentionally NOT attached to the hello message.
|
|
28916
29046
|
// The backend caches the system prompt across turns (Anthropic prompt
|
|
28917
29047
|
// caching), so anything that varies per-page would invalidate the
|
|
@@ -29048,15 +29178,21 @@ var VoiceSDK_v2 = /*#__PURE__*/function (_EventEmitter) {
|
|
|
29048
29178
|
this.stopAudioPlayback();
|
|
29049
29179
|
break;
|
|
29050
29180
|
case 'stop_playing':
|
|
29051
|
-
//
|
|
29052
|
-
//
|
|
29053
|
-
//
|
|
29054
|
-
|
|
29055
|
-
|
|
29056
|
-
|
|
29057
|
-
if (
|
|
29058
|
-
|
|
29059
|
-
|
|
29181
|
+
// An id-bearing stop is a deliberate barge-in flush and is honored UNCONDITIONALLY:
|
|
29182
|
+
// the WebSocket delivers messages in order, so every segment queued locally was sent
|
|
29183
|
+
// BEFORE this stop and is covered by it. The old 200ms-after-audio_start heuristic
|
|
29184
|
+
// silently swallowed barge-in during long multi-sentence replies (an audio_start
|
|
29185
|
+
// arrives every few hundred ms, so the quiet window never opened) — it is kept ONLY
|
|
29186
|
+
// for legacy backends whose stop carries no segmentId.
|
|
29187
|
+
if (message.segmentId == null) {
|
|
29188
|
+
var timeSinceAudioStart = Date.now() - this.lastAudioStartTime;
|
|
29189
|
+
var MIN_STOP_PLAYING_DELAY_MS = 200; // legacy grace period after audio_start
|
|
29190
|
+
if (timeSinceAudioStart < MIN_STOP_PLAYING_DELAY_MS) {
|
|
29191
|
+
console.warn("\u26A0\uFE0F VoiceSDK v2: Ignoring premature legacy stop_playing (".concat(timeSinceAudioStart, "ms after audio_start, minimum ").concat(MIN_STOP_PLAYING_DELAY_MS, "ms required)"));
|
|
29192
|
+
break;
|
|
29193
|
+
}
|
|
29194
|
+
} else {
|
|
29195
|
+
console.log("\uD83D\uDED1 VoiceSDK v2: Barge-in stop_playing (through segmentId ".concat(message.segmentId, ") - flushing playback"));
|
|
29060
29196
|
}
|
|
29061
29197
|
this.emit('stopPlaying', message);
|
|
29062
29198
|
this.stopAudioPlayback();
|
|
@@ -30384,7 +30520,7 @@ var VoiceSDK_v2 = /*#__PURE__*/function (_EventEmitter) {
|
|
|
30384
30520
|
}, {
|
|
30385
30521
|
key: "pauseCall",
|
|
30386
30522
|
value: function pauseCall() {
|
|
30387
|
-
var _this$
|
|
30523
|
+
var _this$audioRecorder4;
|
|
30388
30524
|
if (this.isPaused) return;
|
|
30389
30525
|
this.sendMessage({
|
|
30390
30526
|
t: 'pause_call'
|
|
@@ -30394,7 +30530,7 @@ var VoiceSDK_v2 = /*#__PURE__*/function (_EventEmitter) {
|
|
|
30394
30530
|
this.audioRecorder.stop();
|
|
30395
30531
|
}
|
|
30396
30532
|
// Flush AudioWorklet ring buffer
|
|
30397
|
-
if ((_this$
|
|
30533
|
+
if ((_this$audioRecorder4 = this.audioRecorder) !== null && _this$audioRecorder4 !== void 0 && _this$audioRecorder4.audioWorkletNode) {
|
|
30398
30534
|
this.audioRecorder.audioWorkletNode.port.postMessage({
|
|
30399
30535
|
type: 'flush'
|
|
30400
30536
|
});
|
|
@@ -34319,14 +34455,15 @@ var TTPChatWidget = /*#__PURE__*/function () {
|
|
|
34319
34455
|
fontSize: ((_userConfig$text0 = userConfig.text) === null || _userConfig$text0 === void 0 || (_userConfig$text0 = _userConfig$text0.sendButtonHint) === null || _userConfig$text0 === void 0 ? void 0 : _userConfig$text0.fontSize) || ((_userConfig$panel20 = userConfig.panel) === null || _userConfig$panel20 === void 0 || (_userConfig$panel20 = _userConfig$panel20.sendButtonHint) === null || _userConfig$panel20 === void 0 ? void 0 : _userConfig$panel20.fontSize) || '14px'
|
|
34320
34456
|
}, (_userConfig$text1 = userConfig.text) === null || _userConfig$text1 === void 0 ? void 0 : _userConfig$text1.sendButtonHint), (_userConfig$panel21 = userConfig.panel) === null || _userConfig$panel21 === void 0 ? void 0 : _userConfig$panel21.sendButtonHint),
|
|
34321
34457
|
// Input field configuration
|
|
34322
|
-
inputPlaceholder: ((_userConfig$text10 = userConfig.text) === null || _userConfig$text10 === void 0 ? void 0 : _userConfig$text10.inputPlaceholder) || ((_userConfig$panel22 = userConfig.panel) === null || _userConfig$panel22 === void 0 ? void 0 : _userConfig$panel22.inputPlaceholder)
|
|
34458
|
+
inputPlaceholder: ((_userConfig$text10 = userConfig.text) === null || _userConfig$text10 === void 0 ? void 0 : _userConfig$text10.inputPlaceholder) || userConfig.inputPlaceholder || ((_userConfig$panel22 = userConfig.panel) === null || _userConfig$panel22 === void 0 ? void 0 : _userConfig$panel22.inputPlaceholder),
|
|
34323
34459
|
inputBorderColor: ((_userConfig$text11 = userConfig.text) === null || _userConfig$text11 === void 0 ? void 0 : _userConfig$text11.inputBorderColor) || ((_userConfig$panel23 = userConfig.panel) === null || _userConfig$panel23 === void 0 ? void 0 : _userConfig$panel23.inputBorderColor) || '#E5E7EB',
|
|
34324
34460
|
inputFocusColor: ((_userConfig$text12 = userConfig.text) === null || _userConfig$text12 === void 0 ? void 0 : _userConfig$text12.inputFocusColor) || ((_userConfig$panel24 = userConfig.panel) === null || _userConfig$panel24 === void 0 ? void 0 : _userConfig$panel24.inputFocusColor) || textChatAccent,
|
|
34325
34461
|
inputBackgroundColor: ((_userConfig$text13 = userConfig.text) === null || _userConfig$text13 === void 0 ? void 0 : _userConfig$text13.inputBackgroundColor) || ((_userConfig$panel25 = userConfig.panel) === null || _userConfig$panel25 === void 0 ? void 0 : _userConfig$panel25.inputBackgroundColor) || '#FFFFFF',
|
|
34326
34462
|
inputTextColor: ((_userConfig$text14 = userConfig.text) === null || _userConfig$text14 === void 0 ? void 0 : _userConfig$text14.inputTextColor) || ((_userConfig$panel26 = userConfig.panel) === null || _userConfig$panel26 === void 0 ? void 0 : _userConfig$panel26.inputTextColor) || '#1F2937',
|
|
34463
|
+
// >= 16px so iOS Safari does not auto-zoom the host page when the composer is focused
|
|
34327
34464
|
inputFontSize: ((_userConfig$text15 = userConfig.text) === null || _userConfig$text15 === void 0 ? void 0 : _userConfig$text15.inputFontSize) || ((_userConfig$panel27 = userConfig.panel) === null || _userConfig$panel27 === void 0 ? void 0 : _userConfig$panel27.inputFontSize) || '16px',
|
|
34328
34465
|
inputBorderRadius: ((_userConfig$text16 = userConfig.text) === null || _userConfig$text16 === void 0 ? void 0 : _userConfig$text16.inputBorderRadius) || ((_userConfig$panel28 = userConfig.panel) === null || _userConfig$panel28 === void 0 ? void 0 : _userConfig$panel28.inputBorderRadius) || 20,
|
|
34329
|
-
inputPadding: ((_userConfig$text17 = userConfig.text) === null || _userConfig$text17 === void 0 ? void 0 : _userConfig$text17.inputPadding) || ((_userConfig$panel29 = userConfig.panel) === null || _userConfig$panel29 === void 0 ? void 0 : _userConfig$panel29.inputPadding) || '
|
|
34466
|
+
inputPadding: ((_userConfig$text17 = userConfig.text) === null || _userConfig$text17 === void 0 ? void 0 : _userConfig$text17.inputPadding) || ((_userConfig$panel29 = userConfig.panel) === null || _userConfig$panel29 === void 0 ? void 0 : _userConfig$panel29.inputPadding) || '9px 12px',
|
|
34330
34467
|
/** When true (default), text chat uses the same hero gradient, primary, and bubble treatment as the voice UI. Set false for a light, panel-solid transcript. */
|
|
34331
34468
|
useVoiceTheme: ((_userConfig$text18 = userConfig.text) === null || _userConfig$text18 === void 0 ? void 0 : _userConfig$text18.useVoiceTheme) !== false
|
|
34332
34469
|
}, userConfig.text)
|
|
@@ -34436,7 +34573,7 @@ var TTPChatWidget = /*#__PURE__*/function () {
|
|
|
34436
34573
|
agentTextColor: ((_userConfig$messages8 = userConfig.messages) === null || _userConfig$messages8 === void 0 ? void 0 : _userConfig$messages8.agentTextColor) || ((_userConfig$messages9 = userConfig.messages) === null || _userConfig$messages9 === void 0 ? void 0 : _userConfig$messages9.textColor) || '#1F2937',
|
|
34437
34574
|
userAvatarIcon: ((_userConfig$messages0 = userConfig.messages) === null || _userConfig$messages0 === void 0 ? void 0 : _userConfig$messages0.userAvatarIcon) || '👤',
|
|
34438
34575
|
agentAvatarIcon: ((_userConfig$messages1 = userConfig.messages) === null || _userConfig$messages1 === void 0 ? void 0 : _userConfig$messages1.agentAvatarIcon) || '🤖',
|
|
34439
|
-
fontSize: ((_userConfig$messages10 = userConfig.messages) === null || _userConfig$messages10 === void 0 ? void 0 : _userConfig$messages10.fontSize) || '
|
|
34576
|
+
fontSize: ((_userConfig$messages10 = userConfig.messages) === null || _userConfig$messages10 === void 0 ? void 0 : _userConfig$messages10.fontSize) || '12px',
|
|
34440
34577
|
borderRadius: ((_userConfig$messages11 = userConfig.messages) === null || _userConfig$messages11 === void 0 ? void 0 : _userConfig$messages11.borderRadius) || 16
|
|
34441
34578
|
}, userConfig.messages),
|
|
34442
34579
|
// Animation Configuration
|
|
@@ -34945,7 +35082,7 @@ var TTPChatWidget = /*#__PURE__*/function () {
|
|
|
34945
35082
|
return;
|
|
34946
35083
|
}
|
|
34947
35084
|
this._ensureAboutStyles();
|
|
34948
|
-
var version = true ? "2.
|
|
35085
|
+
var version = true ? "2.48.0" : 0;
|
|
34949
35086
|
var convId = this._getLastConversationId();
|
|
34950
35087
|
var t = function t(k, fb) {
|
|
34951
35088
|
try {
|
|
@@ -35392,9 +35529,9 @@ var TTPChatWidget = /*#__PURE__*/function () {
|
|
|
35392
35529
|
return _this0.showText();
|
|
35393
35530
|
};
|
|
35394
35531
|
}
|
|
35395
|
-
var
|
|
35396
|
-
if (
|
|
35397
|
-
|
|
35532
|
+
var textUnifiedHomeBtn = this.shadowRoot.getElementById('textUnifiedHomeBtn');
|
|
35533
|
+
if (textUnifiedHomeBtn) {
|
|
35534
|
+
textUnifiedHomeBtn.onclick = function () {
|
|
35398
35535
|
var _this0$config$behavio;
|
|
35399
35536
|
var widgetMode = ((_this0$config$behavio = _this0.config.behavior) === null || _this0$config$behavio === void 0 ? void 0 : _this0$config$behavio.mode) || 'unified';
|
|
35400
35537
|
if (widgetMode !== 'unified') return;
|
|
@@ -35402,6 +35539,12 @@ var TTPChatWidget = /*#__PURE__*/function () {
|
|
|
35402
35539
|
_this0._openMobileCallTextLanding();
|
|
35403
35540
|
};
|
|
35404
35541
|
}
|
|
35542
|
+
var textUnifiedCloseBtn = this.shadowRoot.getElementById('textUnifiedCloseBtn');
|
|
35543
|
+
if (textUnifiedCloseBtn) {
|
|
35544
|
+
textUnifiedCloseBtn.onclick = function () {
|
|
35545
|
+
return _this0._doTogglePanel();
|
|
35546
|
+
};
|
|
35547
|
+
}
|
|
35405
35548
|
|
|
35406
35549
|
// Build wave bars inside the orb (desktop active call)
|
|
35407
35550
|
var waveQueryRoot = this.config.useShadowDOM ? this.shadowRoot : document.getElementById('ttp-widget-container');
|
|
@@ -37313,12 +37456,22 @@ var TTPChatWidget = /*#__PURE__*/function () {
|
|
|
37313
37456
|
"use strict";
|
|
37314
37457
|
__webpack_require__.r(__webpack_exports__);
|
|
37315
37458
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
37316
|
-
/* harmony export */
|
|
37459
|
+
/* harmony export */ MESSAGE_COLLAPSE_THRESHOLD: () => (/* binding */ MESSAGE_COLLAPSE_THRESHOLD),
|
|
37460
|
+
/* harmony export */ TextInterface: () => (/* binding */ TextInterface),
|
|
37461
|
+
/* harmony export */ collapseMessageText: () => (/* binding */ collapseMessageText),
|
|
37462
|
+
/* harmony export */ messageInlineOrder: () => (/* binding */ messageInlineOrder),
|
|
37463
|
+
/* harmony export */ resolveInputTextDirection: () => (/* binding */ resolveInputTextDirection),
|
|
37464
|
+
/* harmony export */ resolveMessageTextDirection: () => (/* binding */ resolveMessageTextDirection)
|
|
37317
37465
|
/* harmony export */ });
|
|
37318
37466
|
/* harmony import */ var _galleryHandler_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./galleryHandler.js */ "./src/widget/galleryHandler.js");
|
|
37467
|
+
/* harmony import */ var _markdown_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./markdown.js */ "./src/widget/markdown.js");
|
|
37319
37468
|
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
37320
37469
|
function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n2 = 0, F = function F() {}; return { s: F, n: function n() { return _n2 >= r.length ? { done: !0 } : { done: !1, value: r[_n2++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
|
|
37470
|
+
function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); }
|
|
37471
|
+
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
37321
37472
|
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
|
|
37473
|
+
function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); }
|
|
37474
|
+
function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); }
|
|
37322
37475
|
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
37323
37476
|
function _regenerator() { /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/babel/babel/blob/main/packages/babel-helpers/LICENSE */ var e, t, r = "function" == typeof Symbol ? Symbol : {}, n = r.iterator || "@@iterator", o = r.toStringTag || "@@toStringTag"; function i(r, n, o, i) { var c = n && n.prototype instanceof Generator ? n : Generator, u = Object.create(c.prototype); return _regeneratorDefine2(u, "_invoke", function (r, n, o) { var i, c, u, f = 0, p = o || [], y = !1, G = { p: 0, n: 0, v: e, a: d, f: d.bind(e, 4), d: function d(t, r) { return i = t, c = 0, u = e, G.n = r, a; } }; function d(r, n) { for (c = r, u = n, t = 0; !y && f && !o && t < p.length; t++) { var o, i = p[t], d = G.p, l = i[2]; r > 3 ? (o = l === n) && (u = i[(c = i[4]) ? 5 : (c = 3, 3)], i[4] = i[5] = e) : i[0] <= d && ((o = r < 2 && d < i[1]) ? (c = 0, G.v = n, G.n = i[1]) : d < l && (o = r < 3 || i[0] > n || n > l) && (i[4] = r, i[5] = n, G.n = l, c = 0)); } if (o || r > 1) return a; throw y = !0, n; } return function (o, p, l) { if (f > 1) throw TypeError("Generator is already running"); for (y && 1 === p && d(p, l), c = p, u = l; (t = c < 2 ? e : u) || !y;) { i || (c ? c < 3 ? (c > 1 && (G.n = -1), d(c, u)) : G.n = u : G.v = u); try { if (f = 2, i) { if (c || (o = "next"), t = i[o]) { if (!(t = t.call(i, u))) throw TypeError("iterator result is not an object"); if (!t.done) return t; u = t.value, c < 2 && (c = 0); } else 1 === c && (t = i.return) && t.call(i), c < 2 && (u = TypeError("The iterator does not provide a '" + o + "' method"), c = 1); i = e; } else if ((t = (y = G.n < 0) ? u : r.call(n, G)) !== a) break; } catch (t) { i = e, c = 1, u = t; } finally { f = 1; } } return { value: t, done: y }; }; }(r, o, i), !0), u; } var a = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} t = Object.getPrototypeOf; var c = [][n] ? t(t([][n]())) : (_regeneratorDefine2(t = {}, n, function () { return this; }), t), u = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(c); function f(e) { return Object.setPrototypeOf ? Object.setPrototypeOf(e, GeneratorFunctionPrototype) : (e.__proto__ = GeneratorFunctionPrototype, _regeneratorDefine2(e, o, "GeneratorFunction")), e.prototype = Object.create(u), e; } return GeneratorFunction.prototype = GeneratorFunctionPrototype, _regeneratorDefine2(u, "constructor", GeneratorFunctionPrototype), _regeneratorDefine2(GeneratorFunctionPrototype, "constructor", GeneratorFunction), GeneratorFunction.displayName = "GeneratorFunction", _regeneratorDefine2(GeneratorFunctionPrototype, o, "GeneratorFunction"), _regeneratorDefine2(u), _regeneratorDefine2(u, o, "Generator"), _regeneratorDefine2(u, n, function () { return this; }), _regeneratorDefine2(u, "toString", function () { return "[object Generator]"; }), (_regenerator = function _regenerator() { return { w: i, m: f }; })(); }
|
|
37324
37477
|
function _regeneratorDefine2(e, r, n, t) { var i = Object.defineProperty; try { i({}, "", {}); } catch (e) { i = 0; } _regeneratorDefine2 = function _regeneratorDefine(e, r, n, t) { function o(r, n) { _regeneratorDefine2(e, r, function (e) { return this._invoke(r, n, e); }); } r ? i ? i(e, r, { value: n, enumerable: !t, configurable: !t, writable: !t }) : e[r] = n : (o("next", 0), o("throw", 1), o("return", 2)); }, _regeneratorDefine2(e, r, n, t); }
|
|
@@ -37335,6 +37488,7 @@ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e
|
|
|
37335
37488
|
*/
|
|
37336
37489
|
|
|
37337
37490
|
|
|
37491
|
+
|
|
37338
37492
|
function panelSolidBackground(panel) {
|
|
37339
37493
|
var bg = panel === null || panel === void 0 ? void 0 : panel.backgroundColor;
|
|
37340
37494
|
if (typeof bg !== 'string' || !bg.startsWith('#')) return '#FFFFFF';
|
|
@@ -37375,6 +37529,32 @@ function rgbTupleFromChromeColor(color, fallbackTuple) {
|
|
|
37375
37529
|
/** Textarea single-line height and max auto-grow (px); keep in sync with `.message-input` CSS. */
|
|
37376
37530
|
var TEXT_INPUT_MIN_HEIGHT_PX = 36;
|
|
37377
37531
|
var TEXT_INPUT_MAX_HEIGHT_PX = 132;
|
|
37532
|
+
var MESSAGE_COLLAPSE_THRESHOLD = 353;
|
|
37533
|
+
|
|
37534
|
+
/** How often a streaming agent bubble is re-rendered from its markdown buffer (ms). */
|
|
37535
|
+
var STREAM_RENDER_INTERVAL_MS = 40;
|
|
37536
|
+
function collapseMessageText(text) {
|
|
37537
|
+
if (text.length <= MESSAGE_COLLAPSE_THRESHOLD) return text;
|
|
37538
|
+
return "".concat(text.slice(0, MESSAGE_COLLAPSE_THRESHOLD).trimEnd(), "\u2026");
|
|
37539
|
+
}
|
|
37540
|
+
|
|
37541
|
+
/** Uses the first strong character so typed text can override the empty-field locale. */
|
|
37542
|
+
function resolveInputTextDirection(text) {
|
|
37543
|
+
var _String$match;
|
|
37544
|
+
var fallbackDirection = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'ltr';
|
|
37545
|
+
var firstLetter = (_String$match = String(text).match(/(?:[A-Za-z\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0560-\u0588\u05D0-\u05EA\u05EF-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u0860-\u086A\u0870-\u0887\u0889-\u088F\u08A0-\u08C9\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u09FC\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C5C\u0C5D\u0C60\u0C61\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDC-\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D04-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E86-\u0E8A\u0E8C-\u0EA3\u0EA5\u0EA7-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16F1-\u16F8\u1700-\u1711\u171F-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1878\u1880-\u1884\u1887-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4C\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1C80-\u1C8A\u1C90-\u1CBA\u1CBD-\u1CBF\u1CE9-\u1CEC\u1CEE-\u1CF3\u1CF5\u1CF6\u1CFA\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184\u2C00-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312F\u3131-\u318E\u31A0-\u31BF\u31F0-\u31FF\u3400-\u4DBF\u4E00-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788\uA78B-\uA7DC\uA7F1-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA8FE\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB69\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF2D-\uDF40\uDF42-\uDF49\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF]|\uD801[\uDC00-\uDC9D\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDD70-\uDD7A\uDD7C-\uDD8A\uDD8C-\uDD92\uDD94\uDD95\uDD97-\uDDA1\uDDA3-\uDDB1\uDDB3-\uDDB9\uDDBB\uDDBC\uDDC0-\uDDF3\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67\uDF80-\uDF85\uDF87-\uDFB0\uDFB2-\uDFBA]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD40-\uDD59\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE35\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2\uDD00-\uDD23\uDD4A-\uDD65\uDD6F-\uDD85\uDE80-\uDEA9\uDEB0\uDEB1\uDEC2-\uDEC7\uDF00-\uDF1C\uDF27\uDF30-\uDF45\uDF70-\uDF81\uDFB0-\uDFC4\uDFE0-\uDFF6]|\uD804[\uDC03-\uDC37\uDC71\uDC72\uDC75\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD44\uDD47\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE2B\uDE3F\uDE40\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61\uDF80-\uDF89\uDF8B\uDF8E\uDF90-\uDFB5\uDFB7\uDFD1\uDFD3]|\uD805[\uDC00-\uDC34\uDC47-\uDC4A\uDC5F-\uDC61\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE80-\uDEAA\uDEB8\uDF00-\uDF1A\uDF40-\uDF46]|\uD806[\uDC00-\uDC2B\uDCA0-\uDCDF\uDCFF-\uDD06\uDD09\uDD0C-\uDD13\uDD15\uDD16\uDD18-\uDD2F\uDD3F\uDD41\uDDA0-\uDDA7\uDDAA-\uDDD0\uDDE1\uDDE3\uDE00\uDE0B-\uDE32\uDE3A\uDE50\uDE5C-\uDE89\uDE9D\uDEB0-\uDEF8\uDFC0-\uDFE0]|\uD807[\uDC00-\uDC08\uDC0A-\uDC2E\uDC40\uDC72-\uDC8F\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD30\uDD46\uDD60-\uDD65\uDD67\uDD68\uDD6A-\uDD89\uDD98\uDDB0-\uDDDB\uDEE0-\uDEF2\uDF02\uDF04-\uDF10\uDF12-\uDF33\uDFB0]|\uD808[\uDC00-\uDF99]|\uD809[\uDC80-\uDD43]|\uD80B[\uDF90-\uDFF0]|[\uD80C\uD80E\uD80F\uD81C-\uD822\uD840-\uD868\uD86A-\uD86D\uD86F-\uD872\uD874-\uD879\uD880-\uD883\uD885-\uD88C][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2F\uDC41-\uDC46\uDC60-\uDFFF]|\uD810[\uDC00-\uDFFA]|\uD811[\uDC00-\uDE46]|\uD818[\uDD00-\uDD1D]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE70-\uDEBE\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDD40-\uDD6C\uDE40-\uDE7F\uDEA0-\uDEB8\uDEBB-\uDED3\uDF00-\uDF4A\uDF50\uDF93-\uDF9F\uDFE0\uDFE1\uDFE3\uDFF2\uDFF3]|\uD823[\uDC00-\uDCD5\uDCFF-\uDD1E\uDD80-\uDDF2]|\uD82B[\uDFF0-\uDFF3\uDFF5-\uDFFB\uDFFD\uDFFE]|\uD82C[\uDC00-\uDD22\uDD32\uDD50-\uDD52\uDD55\uDD64-\uDD67\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD837[\uDF00-\uDF1E\uDF25-\uDF2A]|\uD838[\uDC30-\uDC6D\uDD00-\uDD2C\uDD37-\uDD3D\uDD4E\uDE90-\uDEAD\uDEC0-\uDEEB]|\uD839[\uDCD0-\uDCEB\uDDD0-\uDDED\uDDF0\uDEC0-\uDEDE\uDEE0-\uDEE2\uDEE4\uDEE5\uDEE7-\uDEED\uDEF0-\uDEF4\uDEFE\uDEFF\uDFE0-\uDFE6\uDFE8-\uDFEB\uDFED\uDFEE\uDFF0-\uDFFE]|\uD83A[\uDC00-\uDCC4\uDD00-\uDD43\uDD4B]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDEDF\uDF00-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEAD\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0\uDFF0-\uDFFF]|\uD87B[\uDC00-\uDE5D]|\uD87E[\uDC00-\uDE1D]|\uD884[\uDC00-\uDF4A\uDF50-\uDFFF]|\uD88D[\uDC00-\uDC79])/)) === null || _String$match === void 0 ? void 0 : _String$match[0];
|
|
37546
|
+
if (!firstLetter) return fallbackDirection === 'rtl' ? 'rtl' : 'ltr';
|
|
37547
|
+
return /[\u0590-\u08FF]/.test(firstLetter) ? 'rtl' : 'ltr';
|
|
37548
|
+
}
|
|
37549
|
+
function resolveMessageTextDirection(text) {
|
|
37550
|
+
var fallbackDirection = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'ltr';
|
|
37551
|
+
return resolveInputTextDirection(text, fallbackDirection);
|
|
37552
|
+
}
|
|
37553
|
+
|
|
37554
|
+
/** Keeps the fixed, physical metadata area on the bubble's right edge. */
|
|
37555
|
+
function messageInlineOrder(direction) {
|
|
37556
|
+
return ['content', 'spacer'];
|
|
37557
|
+
}
|
|
37378
37558
|
|
|
37379
37559
|
/** Resolves voice primary / gradient strings to #rrggbb for CSS hex+alpha suffixes. */
|
|
37380
37560
|
function firstHexFromVoiceColor(c, fallback) {
|
|
@@ -37396,6 +37576,7 @@ var TextInterface = /*#__PURE__*/function () {
|
|
|
37396
37576
|
this.config = config;
|
|
37397
37577
|
this.sdk = sdk;
|
|
37398
37578
|
this.streamingEl = null;
|
|
37579
|
+
this.streamingBubble = null;
|
|
37399
37580
|
this.hasStartedStreaming = false;
|
|
37400
37581
|
this.isActive = false;
|
|
37401
37582
|
// Shadow root reference for DOM queries
|
|
@@ -37418,6 +37599,11 @@ var TextInterface = /*#__PURE__*/function () {
|
|
|
37418
37599
|
var translations = ((_this$config$translat = this.config.translations) === null || _this$config$translat === void 0 ? void 0 : _this$config$translat[lang]) || ((_this$config$translat2 = this.config.translations) === null || _this$config$translat2 === void 0 ? void 0 : _this$config$translat2.en) || {};
|
|
37419
37600
|
return translations[key] || key;
|
|
37420
37601
|
}
|
|
37602
|
+
}, {
|
|
37603
|
+
key: "textDirection",
|
|
37604
|
+
get: function get() {
|
|
37605
|
+
return this.config.direction === 'rtl' ? 'rtl' : 'ltr';
|
|
37606
|
+
}
|
|
37421
37607
|
|
|
37422
37608
|
/**
|
|
37423
37609
|
* Generate HTML for text interface
|
|
@@ -37425,13 +37611,18 @@ var TextInterface = /*#__PURE__*/function () {
|
|
|
37425
37611
|
}, {
|
|
37426
37612
|
key: "generateHTML",
|
|
37427
37613
|
value: function generateHTML() {
|
|
37428
|
-
var _this$config$panel, _this$config$
|
|
37614
|
+
var _this$config$panel, _this$config$header, _this$config$sendButt, _this$config$panel2, _this$config$sendButt2, _this$config$panel3, _this$config$sendButt3, _this$config$panel4, _this$config$sendButt4, _this$config$panel5;
|
|
37429
37615
|
// Use text config, fallback to panel config, then translation, then default
|
|
37430
37616
|
var inputPlaceholder = this.config.inputPlaceholder || ((_this$config$panel = this.config.panel) === null || _this$config$panel === void 0 ? void 0 : _this$config$panel.inputPlaceholder) || this.t('typeMessage') || 'Type your message...';
|
|
37431
|
-
var
|
|
37432
|
-
var
|
|
37433
|
-
var
|
|
37434
|
-
|
|
37617
|
+
var textDirection = this.textDirection;
|
|
37618
|
+
var agentName = this.config.agentName || ((_this$config$header = this.config.header) === null || _this$config$header === void 0 ? void 0 : _this$config$header.title) || 'Chat Assistant';
|
|
37619
|
+
var agentInitial = agentName.trim().charAt(0).toUpperCase();
|
|
37620
|
+
var footer = this.config.footer || {};
|
|
37621
|
+
var isSpeacart = footer.brand === 'speacart';
|
|
37622
|
+
var brandName = isSpeacart ? 'SpeaCart' : 'TalkToPC';
|
|
37623
|
+
var brandUrl = isSpeacart ? 'https://speacart.com' : 'https://talktopc.com';
|
|
37624
|
+
var backBar = "\n <div class=\"text-interface-top-bar\" dir=\"".concat(textDirection, "\">\n <div class=\"text-interface-agent-heading\">\n <span class=\"text-interface-agent-avatar\" aria-hidden=\"true\">\n <span class=\"text-interface-agent-initial\">").concat(agentInitial, "</span>\n </span>\n <span class=\"text-interface-agent-copy\" dir=\"").concat(textDirection, "\">\n <span class=\"text-interface-agent-name\">").concat(agentName, "</span>\n <span class=\"text-interface-agent-status\"><span aria-hidden=\"true\"></span>").concat(this.t('online'), "</span>\n </span>\n </div>\n <div class=\"text-interface-top-actions\">\n <button type=\"button\" class=\"text-interface-close-btn\" id=\"textUnifiedCloseBtn\" aria-label=\"").concat(this.t('close'), "\" title=\"").concat(this.t('close'), "\">\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\"><path d=\"m6 6 12 12M18 6 6 18\"/></svg>\n </button>\n </div>\n </div>");
|
|
37625
|
+
return "<div class=\"text-interface\" id=\"textInterface\" dir=\"".concat(textDirection, "\">\n ").concat(backBar, "\n <div class=\"messages-container\" id=\"messagesContainer\">\n <div class=\"empty-state\">\n <div class=\"empty-state-icon\" aria-hidden=\"true\">\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M20 11.5a7.5 7.5 0 0 1-7.75 7.5 8.9 8.9 0 0 1-3.5-.72L4 20l1.55-4.1A7.2 7.2 0 0 1 4.5 12 7.5 7.5 0 0 1 12.25 4.5 7.5 7.5 0 0 1 20 11.5Z\"/>\n <path d=\"M8.6 11.8h.01M12.1 11.8h.01M15.6 11.8h.01\" stroke-width=\"2.4\"/>\n </svg>\n </div>\n <div class=\"empty-state-title\">").concat(this.t('hello'), "</div>\n <div class=\"empty-state-text\">").concat(this.t('sendMessage'), "</div>\n </div>\n </div>\n <div class=\"input-container\">\n <button type=\"button\" class=\"text-interface-home-btn\" id=\"textUnifiedHomeBtn\" aria-label=\"").concat(this.t('home'), "\" title=\"").concat(this.t('home'), "\">\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\"><path d=\"M4.5 10.5 12 4l7.5 6.5v8.25a1.25 1.25 0 0 1-1.25 1.25h-4.5v-5.75h-3.5V20h-4.5a1.25 1.25 0 0 1-1.25-1.25V10.5Z\"/></svg>\n </button>\n <div class=\"input-wrapper\" style=\"flex:1;\">\n <textarea class=\"message-input\" id=\"messageInput\" placeholder=\"").concat(inputPlaceholder, "\" rows=\"1\" dir=\"").concat(textDirection, "\"></textarea>\n </div>\n <button class=\"send-button\" id=\"sendButton\" aria-label=\"").concat(this.t('sendMessageAria'), "\">\n <svg class=\"send-icon\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"><path d=\"m21 3-7.8 18-3.6-7.8L3 9.6 21 3Z\"/><path d=\"m9.6 13.2 4.2-3.6\"/></svg>\n </button>\n ").concat((_this$config$sendButt = this.config.sendButtonHint) !== null && _this$config$sendButt !== void 0 && _this$config$sendButt.text || (_this$config$panel2 = this.config.panel) !== null && _this$config$panel2 !== void 0 && (_this$config$panel2 = _this$config$panel2.sendButtonHint) !== null && _this$config$panel2 !== void 0 && _this$config$panel2.text ? "\n <div class=\"send-button-hint\" style=\"color: ".concat(((_this$config$sendButt2 = this.config.sendButtonHint) === null || _this$config$sendButt2 === void 0 ? void 0 : _this$config$sendButt2.color) || ((_this$config$panel3 = this.config.panel) === null || _this$config$panel3 === void 0 || (_this$config$panel3 = _this$config$panel3.sendButtonHint) === null || _this$config$panel3 === void 0 ? void 0 : _this$config$panel3.color) || '#6B7280', "; font-size: ").concat(((_this$config$sendButt3 = this.config.sendButtonHint) === null || _this$config$sendButt3 === void 0 ? void 0 : _this$config$sendButt3.fontSize) || ((_this$config$panel4 = this.config.panel) === null || _this$config$panel4 === void 0 || (_this$config$panel4 = _this$config$panel4.sendButtonHint) === null || _this$config$panel4 === void 0 ? void 0 : _this$config$panel4.fontSize) || '14px', "; text-align: center; margin-top: 4px;\">\n ").concat(((_this$config$sendButt4 = this.config.sendButtonHint) === null || _this$config$sendButt4 === void 0 ? void 0 : _this$config$sendButt4.text) || ((_this$config$panel5 = this.config.panel) === null || _this$config$panel5 === void 0 || (_this$config$panel5 = _this$config$panel5.sendButtonHint) === null || _this$config$panel5 === void 0 ? void 0 : _this$config$panel5.text), "\n </div>\n ") : '', "\n </div>\n <div class=\"text-interface-footer\">\n <span class=\"text-interface-powered\">Powered by <a href=\"").concat(brandUrl, "\" target=\"_blank\" rel=\"noopener noreferrer\"><b>").concat(brandName, "</b></a></span>\n <button type=\"button\" class=\"ttp-info-btn\" aria-label=\"").concat(this.t('aboutTitle') || 'About', "\" title=\"").concat(this.t('aboutTitle') || 'About', "\">\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <circle cx=\"12\" cy=\"12\" r=\"9\"/>\n <line x1=\"12\" y1=\"11\" x2=\"12\" y2=\"16\"/>\n <circle cx=\"12\" cy=\"7.7\" r=\"1.05\" fill=\"currentColor\" stroke=\"none\"/>\n </svg>\n </button>\n </div>\n </div>");
|
|
37435
37626
|
}
|
|
37436
37627
|
|
|
37437
37628
|
/**
|
|
@@ -37446,15 +37637,19 @@ var TextInterface = /*#__PURE__*/function () {
|
|
|
37446
37637
|
var anim = this.config.animation;
|
|
37447
37638
|
var useVoiceTheme = this.config.useVoiceTheme !== false;
|
|
37448
37639
|
var voice = this.config.voice || {};
|
|
37640
|
+
var textDirection = this.textDirection;
|
|
37449
37641
|
|
|
37450
37642
|
// Use text config, fallback to panel config for backward compatibility
|
|
37451
37643
|
var sendButtonColor = this.config.sendButtonColor || ((_this$config$panel6 = this.config.panel) === null || _this$config$panel6 === void 0 ? void 0 : _this$config$panel6.sendButtonColor) || '#7C3AED';
|
|
37452
37644
|
var sendButtonHoverColor = this.config.sendButtonHoverColor || ((_this$config$panel7 = this.config.panel) === null || _this$config$panel7 === void 0 ? void 0 : _this$config$panel7.sendButtonHoverColor) || '#6D28D9';
|
|
37453
37645
|
var sendButtonTextColor = this.config.sendButtonTextColor || ((_this$config$panel8 = this.config.panel) === null || _this$config$panel8 === void 0 ? void 0 : _this$config$panel8.sendButtonTextColor) || '#FFFFFF';
|
|
37454
37646
|
var inputPlaceholder = this.config.inputPlaceholder || ((_this$config$panel9 = this.config.panel) === null || _this$config$panel9 === void 0 ? void 0 : _this$config$panel9.inputPlaceholder) || 'Type your message...';
|
|
37455
|
-
|
|
37647
|
+
// Keep the composer at >= 16px: iOS Safari auto-zooms the host page whenever a
|
|
37648
|
+
// focused field is smaller, which shifts the whole embedding site on tap.
|
|
37649
|
+
var inputFontSize = this.config.inputFontSize || ((_this$config$panel0 = this.config.panel) === null || _this$config$panel0 === void 0 ? void 0 : _this$config$panel0.inputFontSize) || '16px';
|
|
37456
37650
|
var inputBorderRadius = this.config.inputBorderRadius || ((_this$config$panel1 = this.config.panel) === null || _this$config$panel1 === void 0 ? void 0 : _this$config$panel1.inputBorderRadius) || 20;
|
|
37457
|
-
var inputPadding = this.config.inputPadding || ((_this$config$panel10 = this.config.panel) === null || _this$config$panel10 === void 0 ? void 0 : _this$config$panel10.inputPadding) || '
|
|
37651
|
+
var inputPadding = this.config.inputPadding || ((_this$config$panel10 = this.config.panel) === null || _this$config$panel10 === void 0 ? void 0 : _this$config$panel10.inputPadding) || '9px 12px';
|
|
37652
|
+
var messageFontSize = messages.fontSize || '12px';
|
|
37458
37653
|
var panelLight;
|
|
37459
37654
|
var topBarBg;
|
|
37460
37655
|
var topBarBorder;
|
|
@@ -37489,31 +37684,31 @@ var TextInterface = /*#__PURE__*/function () {
|
|
|
37489
37684
|
if (useVoiceTheme) {
|
|
37490
37685
|
var p1 = firstHexFromVoiceColor(voice.primaryBtnGradient1 || voice.startCallButtonColor, '#6d56f5');
|
|
37491
37686
|
var p2 = firstHexFromVoiceColor(voice.primaryBtnGradient2 || voice.startCallButtonColor, '#9d8df8');
|
|
37492
|
-
var a1 = firstHexFromVoiceColor(voice.avatarGradient1,
|
|
37493
|
-
var a2 = firstHexFromVoiceColor(voice.avatarGradient2,
|
|
37687
|
+
var a1 = firstHexFromVoiceColor(voice.avatarGradient1, '#6d56f5');
|
|
37688
|
+
var a2 = firstHexFromVoiceColor(voice.avatarGradient2, '#a78bfa');
|
|
37494
37689
|
panelLight = false;
|
|
37495
|
-
topBarBg = '
|
|
37496
|
-
topBarBorder = 'rgba(
|
|
37497
|
-
messagesAreaBg = 'rgba(
|
|
37690
|
+
topBarBg = 'rgba(13, 8, 43, 0.9)';
|
|
37691
|
+
topBarBorder = 'rgba(219, 210, 255, 0.16)';
|
|
37692
|
+
messagesAreaBg = 'radial-gradient(circle at 22% 12%, rgba(116, 80, 255, 0.16), transparent 32%), linear-gradient(180deg, rgba(11, 7, 38, 0.4), rgba(8, 5, 29, 0.62))';
|
|
37498
37693
|
backBtnColor = 'rgba(255,255,255,0.92)';
|
|
37499
37694
|
backBtnHoverBg = 'rgba(255,255,255,0.14)';
|
|
37500
37695
|
backBtnHoverColor = '#ffffff';
|
|
37501
37696
|
emptyMuted = 'rgba(255,255,255,0.7)';
|
|
37502
37697
|
emptyTitle = '#ffffff';
|
|
37503
|
-
inputContainerBg = '
|
|
37504
|
-
inputContainerBorderTop = 'rgba(
|
|
37505
|
-
inputBorderColor = 'rgba(
|
|
37698
|
+
inputContainerBg = 'rgba(12, 8, 38, 0.9)';
|
|
37699
|
+
inputContainerBorderTop = 'rgba(225, 219, 255, 0.18)';
|
|
37700
|
+
inputBorderColor = 'rgba(225, 219, 255, 0.26)';
|
|
37506
37701
|
inputFocusColor = "".concat(p1, "e6");
|
|
37507
|
-
inputBackgroundColor = 'rgba(255,255,255,0.
|
|
37702
|
+
inputBackgroundColor = 'rgba(255,255,255,0.07)';
|
|
37508
37703
|
inputTextColor = '#f8fafc';
|
|
37509
|
-
inputFocusBg = 'rgba(255,255,255,0.
|
|
37704
|
+
inputFocusBg = 'rgba(255,255,255,0.12)';
|
|
37510
37705
|
inputFocusBoxShadow = "0 0 0 3px ".concat(p1, "59");
|
|
37511
37706
|
placeholderColor = 'rgba(255,255,255,0.55)';
|
|
37512
|
-
userBubbleBg =
|
|
37707
|
+
userBubbleBg = '#7354e6';
|
|
37513
37708
|
userBubbleTextColor = '#ffffff';
|
|
37514
|
-
agentBubbleBg = '
|
|
37709
|
+
agentBubbleBg = '#35394f';
|
|
37515
37710
|
agentBubbleTextColor = '#f8fafc';
|
|
37516
|
-
agentBubbleBorder = '1px solid rgba(
|
|
37711
|
+
agentBubbleBorder = '1px solid rgba(194, 201, 255, 0.22)';
|
|
37517
37712
|
avatarAgentBg = "linear-gradient(135deg, ".concat(a1, ", ").concat(a2, ")");
|
|
37518
37713
|
avatarUserBg = 'rgba(255,255,255,0.22)';
|
|
37519
37714
|
avatarUserColor = 'rgba(255,255,255,0.95)';
|
|
@@ -37560,9 +37755,21 @@ var TextInterface = /*#__PURE__*/function () {
|
|
|
37560
37755
|
}
|
|
37561
37756
|
var accentRgb = rgbTupleFromChromeColor(sendButtonColor);
|
|
37562
37757
|
|
|
37758
|
+
// Markdown tokens for the agent bubble. Derived from the two themes so the
|
|
37759
|
+
// rendered structure (code, tables, rules) reads correctly on both.
|
|
37760
|
+
var mdOnDark = useVoiceTheme || !panelLight;
|
|
37761
|
+
var mdSubtleBg = mdOnDark ? 'rgba(255,255,255,0.10)' : 'rgba(15,23,42,0.045)';
|
|
37762
|
+
var mdSubtlerBg = mdOnDark ? 'rgba(255,255,255,0.05)' : 'rgba(15,23,42,0.022)';
|
|
37763
|
+
var mdBorder = mdOnDark ? 'rgba(255,255,255,0.20)' : 'rgba(15,23,42,0.10)';
|
|
37764
|
+
var mdRule = mdOnDark ? 'rgba(255,255,255,0.16)' : 'rgba(15,23,42,0.08)';
|
|
37765
|
+
var mdMuted = mdOnDark ? 'rgba(255,255,255,0.62)' : 'rgba(15,23,42,0.55)';
|
|
37766
|
+
var mdLink = mdOnDark ? '#c7d2fe' : sendButtonColor;
|
|
37767
|
+
var mdAccent = mdOnDark ? 'rgba(255,255,255,0.45)' : "rgba(".concat(accentRgb[0], ", ").concat(accentRgb[1], ", ").concat(accentRgb[2], ", 0.55)");
|
|
37768
|
+
var mdMono = "ui-monospace, SFMono-Regular, Menlo, Consolas, 'Liberation Mono', monospace";
|
|
37769
|
+
|
|
37563
37770
|
// Add !important to display rules when not using Shadow DOM (to override theme CSS)
|
|
37564
37771
|
var important = this.config.useShadowDOM === false ? ' !important' : '';
|
|
37565
|
-
return "\n .text-interface-top-bar {\n flex-shrink: 0".concat(important, ";\n padding: 10px 12px 8px").concat(important, ";\n border-bottom: 1px solid ").concat(topBarBorder).concat(important, ";\n background: ").concat(topBarBg).concat(important, ";\n display: flex").concat(important, ";\n align-items: center").concat(important, ";\n justify-content: space-between").concat(important, ";\n }\n .text-interface-top-bar .ttp-info-btn {\n color: ").concat(backBtnColor).concat(important, ";\n }\n .text-interface-top-bar .ttp-info-btn:hover {\n background: ").concat(backBtnHoverBg).concat(important, ";\n color: ").concat(backBtnHoverColor).concat(important, ";\n }\n .text-interface-back-btn {\n display: inline-flex").concat(important, ";\n align-items: center").concat(important, ";\n gap: 6px").concat(important, ";\n padding: 6px 10px").concat(important, ";\n margin: 0").concat(important, ";\n border: none").concat(important, ";\n border-radius: 8px").concat(important, ";\n background: transparent").concat(important, ";\n color: ").concat(backBtnColor).concat(important, ";\n font-size: 16px").concat(important, ";\n font-weight: 600").concat(important, ";\n cursor: pointer").concat(important, ";\n font-family: inherit").concat(important, ";\n }\n .text-interface-back-btn:hover {\n background: ").concat(backBtnHoverBg).concat(important, ";\n color: ").concat(backBtnHoverColor).concat(important, ";\n }\n .text-interface-back-icon {\n font-size: 18px").concat(important, ";\n line-height: 1").concat(important, ";\n }\n .text-interface-back-label {\n line-height: 1.2").concat(important, ";\n }\n /* Messages container using new classes */\n #messagesContainer { \n flex: 1").concat(important, "; \n overflow-y: auto").concat(important, "; \n overflow-x: hidden").concat(important, "; \n padding: 20px").concat(important, "; \n background: ").concat(messagesAreaBg).concat(important, "; \n display: flex").concat(important, "; \n flex-direction: column").concat(important, "; \n gap: 16px").concat(important, "; \n min-height: 0").concat(important, "; \n }\n .empty-state { \n flex: 1").concat(important, "; \n display: flex").concat(important, "; \n flex-direction: column").concat(important, "; \n align-items: center").concat(important, "; \n justify-content: center").concat(important, "; \n gap: 12px").concat(important, "; \n color: ").concat(emptyMuted).concat(important, "; \n text-align: center").concat(important, "; \n padding: 20px").concat(important, "; \n }\n .empty-state-icon { font-size: 52px").concat(important, "; opacity: 0.3").concat(important, "; }\n .empty-state-title { font-size: 22px").concat(important, "; font-weight: 700").concat(important, "; color: ").concat(emptyTitle).concat(important, "; }\n .empty-state-text { font-size: 15px").concat(important, "; max-width: 300px").concat(important, "; line-height: 1.45").concat(important, "; }\n\n .text-interface { \n display: none").concat(important, "; \n flex: 1").concat(important, "; \n flex-direction: column").concat(important, "; \n min-height: 0").concat(important, "; \n overflow: hidden").concat(important, "; \n }\n .text-interface.active { display: flex").concat(important, "; }\n \n .message { \n display: flex").concat(important, "; \n gap: 8px").concat(important, "; \n padding: 4px 0").concat(important, "; \n max-width: 100%").concat(important, "; \n align-items: center").concat(important, "; \n }\n .message.edge-left { flex-direction: row").concat(important, "; }\n .message.edge-right { flex-direction: row-reverse").concat(important, "; }\n .message-bubble { \n padding: 14px 16px").concat(important, "; \n border-radius: ").concat(messages.borderRadius, "px").concat(important, "; \n max-width: 80%").concat(important, "; \n font-size: ").concat(messages.fontSize).concat(important, "; \n line-height: 1.45").concat(important, ";\n word-wrap: break-word").concat(important, "; \n text-align: ").concat(this.config.direction === 'rtl' ? 'right' : 'left').concat(important, "; \n direction: ").concat(this.config.direction || 'ltr', ";\n }\n .message.user .message-bubble { \n background: ").concat(userBubbleBg).concat(important, "; \n color: ").concat(userBubbleTextColor).concat(important, "; \n }\n .message.agent .message-bubble { \n background: ").concat(agentBubbleBg).concat(important, "; \n color: ").concat(agentBubbleTextColor).concat(important, "; \n border: ").concat(agentBubbleBorder).concat(important, "; \n }\n\n .message.user { \n align-self: ").concat(this.config.direction === 'rtl' ? 'flex-start' : 'flex-end').concat(important, "; \n }\n .message.agent { \n align-self: ").concat(this.config.direction === 'rtl' ? 'flex-end' : 'flex-start').concat(important, "; \n }\n .message .message-bubble { \n text-align: ").concat(this.config.direction === 'rtl' ? 'right' : 'left', " !important; \n }\n ").concat(this.config.direction === 'rtl' ? "\n .message-bubble {\n text-align: right !important;\n }\n " : '', "\n .message-avatar { \n width: ").concat(avatarSize).concat(important, "; \n height: ").concat(avatarSize).concat(important, "; \n min-width: ").concat(avatarSize).concat(important, "; \n border-radius: 50%").concat(important, "; \n display: flex").concat(important, "; \n align-items: center").concat(important, "; \n justify-content: center").concat(important, "; \n flex-shrink: 0").concat(important, "; \n color: inherit").concat(important, "; \n font-size: ").concat(useVoiceTheme ? '14' : '20', "px").concat(important, "; \n line-height: 1").concat(important, "; \n background: transparent").concat(important, "; \n border: none").concat(important, "; \n box-sizing: border-box").concat(important, "; \n }\n .message-avatar.user { background: ").concat(avatarUserBg).concat(important, "; color: ").concat(avatarUserColor).concat(important, "; }\n .message-avatar.agent { background: ").concat(avatarAgentBg).concat(important, "; }\n \n .message.system {\n background: ").concat(messages.systemBackgroundColor, ";\n align-self: flex-start").concat(important, ";\n }\n .message.error {\n background: ").concat(messages.errorBackgroundColor, ";\n align-self: flex-start").concat(important, ";\n }\n \n .input-container {\n display: flex").concat(important, ";\n gap: 8px").concat(important, ";\n padding: 12px 16px").concat(important, ";\n background: ").concat(inputContainerBg).concat(important, ";\n border-top: 1px solid ").concat(inputContainerBorderTop).concat(important, ";\n align-items: center").concat(important, ";\n flex-shrink: 0").concat(important, ";\n flex-direction: ").concat(this.config.direction === 'rtl' ? 'row-reverse' : 'row').concat(important, ";\n }\n \n .input-wrapper {\n position: relative").concat(important, ";\n display: flex").concat(important, ";\n align-items: center").concat(important, ";\n }\n \n .message-input {\n width: 100%").concat(important, ";\n min-height: ").concat(TEXT_INPUT_MIN_HEIGHT_PX, "px").concat(important, ";\n max-height: ").concat(TEXT_INPUT_MAX_HEIGHT_PX, "px").concat(important, ";\n padding: ").concat(inputPadding, ";\n border: 1px solid ").concat(inputBorderColor, ";\n border-radius: ").concat(inputBorderRadius, "px;\n font-size: ").concat(inputFontSize, ";\n font-family: inherit").concat(important, ";\n line-height: 1.4").concat(important, ";\n resize: none").concat(important, ";\n overflow-y: auto").concat(important, ";\n background: ").concat(inputBackgroundColor, ";\n color: ").concat(inputTextColor, ";\n vertical-align: top").concat(important, ";\n margin: 0").concat(important, ";\n display: block").concat(important, ";\n white-space: pre-wrap").concat(important, ";\n word-wrap: break-word").concat(important, ";\n text-align: ").concat(this.config.direction === 'rtl' ? 'right' : 'left').concat(important, ";\n direction: ").concat(this.config.direction || 'ltr', ";\n -webkit-appearance: none").concat(important, ";\n appearance: none").concat(important, ";\n box-sizing: border-box").concat(important, ";\n }\n \n .message-input:focus {\n outline: none").concat(important, ";\n border-color: ").concat(inputFocusColor, ";\n background: ").concat(inputFocusBg).concat(important, ";\n box-shadow: ").concat(inputFocusBoxShadow, ";\n }\n \n .message-input::placeholder {\n color: ").concat(placeholderColor).concat(important, ";\n text-align: ").concat(this.config.direction === 'rtl' ? 'right' : 'left').concat(important, ";\n }\n \n .send-button {\n width: 44px").concat(important, ";\n height: 44px").concat(important, ";\n border-radius: 50%").concat(important, ";\n border: none").concat(important, ";\n background: ").concat(sendButtonColor, ";\n color: ").concat(sendButtonTextColor, ";\n font-size: ").concat(this.config.sendButtonFontSize || ((_this$config$panel15 = this.config.panel) === null || _this$config$panel15 === void 0 ? void 0 : _this$config$panel15.sendButtonFontSize) || '20px', ";\n font-weight: ").concat(this.config.sendButtonFontWeight || ((_this$config$panel16 = this.config.panel) === null || _this$config$panel16 === void 0 ? void 0 : _this$config$panel16.sendButtonFontWeight) || '500', ";\n cursor: pointer").concat(important, ";\n display: flex").concat(important, ";\n align-items: center").concat(important, ";\n justify-content: center").concat(important, ";\n flex-shrink: 0").concat(important, ";\n transition: all 0.2s ease").concat(important, ";\n box-shadow: 0 4px 12px rgba(").concat(accentRgb[0], ", ").concat(accentRgb[1], ", ").concat(accentRgb[2], ", 0.32)").concat(important, ";\n }\n \n .send-button:hover:not(:disabled) {\n background: ").concat(sendButtonHoverColor, ";\n transform: scale(1.05)").concat(important, ";\n box-shadow: 0 6px 16px rgba(").concat(accentRgb[0], ", ").concat(accentRgb[1], ", ").concat(accentRgb[2], ", 0.42)").concat(important, ";\n }\n \n .send-button-hint {\n width: 100%").concat(important, ";\n text-align: center").concat(important, ";\n margin-top: 4px").concat(important, ";\n }\n \n .send-button:disabled {\n opacity: 0.5").concat(important, ";\n cursor: not-allowed").concat(important, ";\n }\n \n .typing-indicator {\n display: inline-flex").concat(important, ";\n gap: 4px").concat(important, ";\n align-items: center").concat(important, ";\n }\n \n .typing-dot {\n width: 6px").concat(important, ";\n height: 6px").concat(important, ";\n border-radius: 50%").concat(important, ";\n background: rgba(").concat(accentRgb[0], ", ").concat(accentRgb[1], ", ").concat(accentRgb[2], ", ").concat(typingDotAlpha, ")").concat(important, ";\n animation: typingDot 1.4s ease-in-out infinite").concat(important, ";\n }\n \n .typing-dot:nth-child(2) { animation-delay: 0.2s").concat(important, "; }\n .typing-dot:nth-child(3) { animation-delay: 0.4s").concat(important, "; }\n \n @keyframes typingDot {\n 0%, 60%, 100% { transform: translateY(0); opacity: 0.7; }\n 30% { transform: translateY(-8px); opacity: 1; }\n }\n \n .error-message {\n padding: 12px").concat(important, ";\n background: ").concat(errorBubbleBg, ";\n border-radius: ").concat(messages.borderRadius, "px;\n color: ").concat(errorBubbleColor).concat(important, ";\n border: ").concat(errorBubbleBorder).concat(important, ";\n font-size: ").concat(messages.fontSize).concat(important, ";\n margin: 8px 0").concat(important, ";\n }\n \n ").concat(useVoiceTheme ? "\n #textInterface.active .input-container .send-button-hint {\n color: rgba(255,255,255,0.72)".concat(important, ";\n }\n ") : '', "\n \n @media (max-width: 768px) {\n #messagesContainer {\n padding: 12px").concat(important, ";\n gap: 12px").concat(important, ";\n }\n \n .message-bubble {\n max-width: 85%").concat(important, ";\n font-size: ").concat(messages.fontSize).concat(important, ";\n padding: 12px 14px").concat(important, ";\n }\n \n .text-input-container {\n padding: 10px").concat(important, ";\n gap: 8px").concat(important, ";\n }\n \n #text-chat-input {\n font-size: 16px !important; /* Prevents iOS zoom on focus */\n padding: 10px 14px").concat(important, ";\n min-height: 44px").concat(important, ";\n }\n \n #text-chat-send {\n min-width: 56px").concat(important, ";\n min-height: 44px").concat(important, ";\n width: 56px").concat(important, ";\n height: 44px").concat(important, ";\n }\n \n .empty-state-icon {\n font-size: 44px").concat(important, ";\n }\n \n .empty-state-title {\n font-size: 20px").concat(important, ";\n }\n \n .empty-state-text {\n font-size: 14px").concat(important, ";\n }\n }\n \n @media (max-width: 480px) {\n #messagesContainer {\n padding: 10px").concat(important, ";\n gap: 10px").concat(important, ";\n }\n \n .message-bubble {\n max-width: 90%").concat(important, ";\n font-size: ").concat(messages.fontSize).concat(important, ";\n padding: 10px 12px").concat(important, ";\n }\n \n .text-input-container {\n padding: 8px").concat(important, ";\n }\n \n #text-chat-input {\n font-size: 16px !important;\n padding: 8px 12px").concat(important, ";\n }\n }\n ");
|
|
37772
|
+
return "\n .text-interface-top-bar {\n flex-shrink: 0".concat(important, ";\n padding: 12px 14px").concat(important, ";\n border-bottom: 1px solid ").concat(topBarBorder).concat(important, ";\n background: ").concat(topBarBg).concat(important, ";\n display: flex").concat(important, ";\n align-items: center").concat(important, ";\n justify-content: flex-start").concat(important, ";\n gap: 10px").concat(important, ";\n direction: ").concat(textDirection).concat(important, ";\n }\n .text-interface-agent-heading {\n display: flex").concat(important, ";\n flex-direction: row").concat(important, ";\n align-items: center").concat(important, ";\n gap: 9px").concat(important, ";\n min-width: 0").concat(important, ";\n flex: 1").concat(important, ";\n margin-right: 0").concat(important, ";\n }\n .text-interface-agent-avatar {\n width: 36px").concat(important, ";\n height: 36px").concat(important, ";\n display: flex").concat(important, ";\n align-items: center").concat(important, ";\n justify-content: center").concat(important, ";\n flex: 0 0 36px").concat(important, ";\n border-radius: 50%").concat(important, ";\n background: ").concat(useVoiceTheme ? avatarAgentBg : "linear-gradient(135deg, ".concat(sendButtonColor, ", ").concat(sendButtonHoverColor, ")")).concat(important, ";\n border: none").concat(important, ";\n box-shadow: none").concat(important, ";\n }\n .text-interface-agent-initial { color: #fff").concat(important, "; font-size: 14px").concat(important, "; font-weight: 500").concat(important, "; line-height: 1").concat(important, "; }\n .text-interface-agent-copy {\n display: flex").concat(important, ";\n flex-direction: column").concat(important, ";\n align-items: flex-start").concat(important, ";\n gap: 2px").concat(important, ";\n min-width: 0").concat(important, ";\n }\n .text-interface-agent-name {\n color: #f0eff8").concat(important, ";\n font-size: 14px").concat(important, ";\n font-weight: 500").concat(important, ";\n line-height: 1.15").concat(important, ";\n overflow: hidden").concat(important, ";\n text-overflow: ellipsis").concat(important, ";\n white-space: nowrap").concat(important, ";\n }\n .text-interface-agent-status {\n display: inline-flex").concat(important, ";\n align-items: center").concat(important, ";\n gap: 6px").concat(important, ";\n color: rgba(255,255,255,0.7)").concat(important, ";\n font-size: 10px").concat(important, ";\n }\n .text-interface-agent-status > span {\n width: 7px").concat(important, ";\n height: 7px").concat(important, ";\n border-radius: 50%").concat(important, ";\n background: #4ade80").concat(important, ";\n box-shadow: 0 0 10px rgba(74,222,128,0.75)").concat(important, ";\n }\n .text-interface-top-actions { display: flex").concat(important, "; align-items: center").concat(important, "; gap: 4px").concat(important, "; margin-inline-start: auto").concat(important, "; }\n .text-interface-close-btn:hover,\n .text-interface-home-btn:hover,\n .text-interface-footer .ttp-info-btn:hover {\n background: rgba(255,255,255,0.22)").concat(important, ";\n color: #ffffff").concat(important, ";\n box-shadow: inset 0 1px 0 rgba(255,255,255,0.26), 0 4px 14px rgba(0,0,0,0.22)").concat(important, ";\n }\n .text-interface-close-btn,\n .text-interface-home-btn,\n .text-interface-footer .ttp-info-btn {\n width: 32px").concat(important, ";\n height: 32px").concat(important, ";\n display: grid").concat(important, ";\n place-items: center").concat(important, ";\n padding: 0").concat(important, ";\n margin: 0").concat(important, ";\n border: 1px solid rgba(255,255,255,0.14)").concat(important, ";\n border-radius: 50%").concat(important, ";\n background: rgba(255,255,255,0.12)").concat(important, ";\n color: rgba(224,218,255,0.84)").concat(important, ";\n cursor: pointer").concat(important, ";\n font-family: inherit").concat(important, ";\n transition: background 0.18s ease, color 0.18s ease, box-shadow 0.18s ease").concat(important, ";\n box-shadow: inset 0 1px 0 rgba(255,255,255,0.14)").concat(important, ";\n }\n .text-interface-home-btn svg,\n .text-interface-close-btn svg,\n .text-interface-footer .ttp-info-btn svg { width: 18px").concat(important, "; height: 18px").concat(important, "; fill: none").concat(important, "; stroke: currentColor").concat(important, "; stroke-width: 1.9").concat(important, "; stroke-linecap: round").concat(important, "; stroke-linejoin: round").concat(important, "; }\n .text-interface-home-btn svg { fill: none").concat(important, "; stroke: currentColor").concat(important, "; width: 20px").concat(important, "; height: 20px").concat(important, "; stroke-width: 1.8").concat(important, "; }\n .input-container .text-interface-home-btn {\n width: 38px").concat(important, ";\n height: 38px").concat(important, ";\n color: rgba(224,218,255,0.84)").concat(important, ";\n background: rgba(255,255,255,0.12)").concat(important, ";\n flex-shrink: 0").concat(important, ";\n }\n /* Messages container using new classes */\n #messagesContainer { \n flex: 1").concat(important, "; \n overflow-y: auto").concat(important, "; \n overflow-x: hidden").concat(important, "; \n padding: 20px").concat(important, "; \n background: ").concat(messagesAreaBg).concat(important, "; \n display: flex").concat(important, "; \n flex-direction: column").concat(important, "; \n gap: 16px").concat(important, "; \n min-height: 0").concat(important, "; \n }\n .empty-state { \n flex: 1").concat(important, "; \n display: flex").concat(important, "; \n flex-direction: column").concat(important, "; \n align-items: center").concat(important, "; \n justify-content: center").concat(important, "; \n gap: 12px").concat(important, "; \n color: ").concat(emptyMuted).concat(important, "; \n text-align: center").concat(important, "; \n padding: 20px").concat(important, "; \n }\n .empty-state-icon { font-size: 52px").concat(important, "; opacity: 0.3").concat(important, "; }\n .empty-state-title { font-size: 22px").concat(important, "; font-weight: 700").concat(important, "; color: ").concat(emptyTitle).concat(important, "; }\n .empty-state-text { font-size: 15px").concat(important, "; max-width: 300px").concat(important, "; line-height: 1.45").concat(important, "; }\n .empty-state-icon {\n width: 48px").concat(important, "; height: 48px").concat(important, "; border-radius: 16px").concat(important, ";\n display: grid").concat(important, "; place-items: center").concat(important, "; color: rgba(230,225,255,0.9)").concat(important, ";\n background: rgba(255,255,255,0.1)").concat(important, ";\n border: 1px solid rgba(225,219,255,0.18)").concat(important, ";\n }\n .empty-state-icon svg { width: 24px").concat(important, "; height: 24px").concat(important, "; }\n\n .text-interface { \n display: none").concat(important, "; \n flex: 1").concat(important, "; \n flex-direction: column").concat(important, "; \n min-height: 0").concat(important, "; \n overflow: hidden").concat(important, "; \n direction: ").concat(textDirection).concat(important, ";\n }\n .text-interface.active { display: flex").concat(important, "; }\n \n .message { \n display: flex").concat(important, "; \n flex-direction: column").concat(important, ";\n gap: 4px").concat(important, ";\n padding: 4px 0").concat(important, "; \n width: 100%").concat(important, ";\n max-width: 100%").concat(important, "; \n align-items: stretch").concat(important, ";\n }\n .message-bubble { \n position: relative").concat(important, ";\n padding: 8px 62px 8px 11px").concat(important, ";\n padding-right: 62px").concat(important, ";\n border-radius: 12px").concat(important, ";\n max-width: min(72%, 420px)").concat(important, ";\n font-size: ").concat(messageFontSize).concat(important, ";\n line-height: 1.36").concat(important, ";\n word-wrap: break-word").concat(important, "; \n box-shadow: ").concat(useVoiceTheme ? 'inset 0 1px 0 rgba(255,255,255,0.36), inset 0 -1px 0 rgba(5, 3, 26, 0.18), 0 8px 20px rgba(4, 3, 22, 0.24)' : 'none').concat(important, ";\n }\n .message-bubble[dir=\"rtl\"] { text-align: right").concat(important, "; direction: rtl").concat(important, "; }\n .message-bubble[dir=\"ltr\"] { text-align: left").concat(important, "; direction: ltr").concat(important, "; }\n .message-bubble::before {\n content: ''").concat(important, ";\n position: absolute").concat(important, ";\n top: 1px").concat(important, ";\n right: 1px").concat(important, ";\n left: 1px").concat(important, ";\n height: 48%").concat(important, ";\n border-radius: 11px 11px 8px 8px").concat(important, ";\n background: linear-gradient(180deg, rgba(255,255,255,0.19), rgba(255,255,255,0))").concat(important, ";\n pointer-events: none").concat(important, ";\n }\n .message.user .message-bubble { \n background: ").concat(userBubbleBg).concat(important, "; \n color: ").concat(userBubbleTextColor).concat(important, "; \n border-top-right-radius: 4px").concat(important, ";\n }\n .message.agent .message-bubble {\n background: ").concat(agentBubbleBg).concat(important, ";\n color: ").concat(agentBubbleTextColor).concat(important, ";\n border: ").concat(agentBubbleBorder).concat(important, ";\n border-top-left-radius: 4px").concat(important, ";\n }\n\n /* ---------------------------------------------------------------\n Rendered markdown inside the agent bubble.\n Everything is scoped to .message-bubble so host-page styles can't\n reach in and the user bubble (plain text) is untouched.\n Logical properties (padding-inline-start, border-inline-start) keep\n the layout correct in RTL locales such as Hebrew.\n ---------------------------------------------------------------- */\n .message-bubble.md, .message-bubble .md-seg { line-height: 1.55").concat(important, "; }\n .message-bubble .md-seg { display: block").concat(important, "; }\n\n .message-bubble p {\n margin: 0 0 10px").concat(important, ";\n padding: 0").concat(important, ";\n }\n /* Deliberately gated on .md / .md-seg rather than a bare\n \".message-bubble > *\": the VOICE live-transcript row reuses the\n .message-bubble class in this same shadow root, and its children\n (.live-badge, .ttp-cursor) are not ours to restyle. */\n .message-bubble.md > *:last-child,\n .message-bubble .md-seg:last-child > *:last-child { margin-bottom: 0").concat(important, "; }\n .message-bubble.md > *:first-child,\n .message-bubble .md-seg:first-child > *:first-child { margin-top: 0").concat(important, "; }\n\n .message-bubble .md-h {\n margin: 16px 0 7px").concat(important, ";\n padding: 0").concat(important, ";\n font-weight: 700").concat(important, ";\n line-height: 1.3").concat(important, ";\n color: inherit").concat(important, ";\n }\n .message-bubble .md-h1 { font-size: 1.18em").concat(important, "; }\n .message-bubble .md-h2 { font-size: 1.09em").concat(important, "; }\n .message-bubble .md-h3 { font-size: 1.02em").concat(important, "; }\n .message-bubble .md-h4,\n .message-bubble .md-h5,\n .message-bubble .md-h6 {\n font-size: 0.95em").concat(important, ";\n letter-spacing: 0.02em").concat(important, ";\n color: ").concat(mdMuted).concat(important, ";\n }\n\n /* Logical properties only \u2014 a physical padding-left/border-left after\n these would resolve to the same property and silently win in LTR. */\n .message-bubble ul, .message-bubble ol {\n margin: 8px 0 11px").concat(important, ";\n padding-inline-start: 1.45em").concat(important, ";\n list-style-position: outside").concat(important, ";\n }\n .message-bubble ul { list-style-type: disc").concat(important, "; }\n .message-bubble ol { list-style-type: decimal").concat(important, "; }\n .message-bubble ul ul { list-style-type: circle").concat(important, "; }\n .message-bubble li {\n margin: 0 0 5px").concat(important, ";\n padding: 0").concat(important, ";\n line-height: 1.5").concat(important, ";\n }\n .message-bubble li:last-child { margin-bottom: 0").concat(important, "; }\n .message-bubble li::marker { color: ").concat(mdAccent).concat(important, "; }\n .message-bubble li > ul, .message-bubble li > ol { margin: 5px 0 2px").concat(important, "; }\n .message-bubble li > p { margin: 0 0 5px").concat(important, "; }\n\n .message-bubble strong, .message-bubble b { font-weight: 700").concat(important, "; }\n .message-bubble em, .message-bubble i { font-style: italic").concat(important, "; }\n .message-bubble del { text-decoration: line-through").concat(important, "; opacity: 0.7").concat(important, "; }\n\n .message-bubble a {\n color: ").concat(mdLink).concat(important, ";\n text-decoration: underline").concat(important, ";\n text-underline-offset: 2px").concat(important, ";\n word-break: break-word").concat(important, ";\n }\n .message-bubble a:hover { opacity: 0.82").concat(important, "; }\n\n .message-bubble code {\n font-family: ").concat(mdMono).concat(important, ";\n font-size: 0.88em").concat(important, ";\n background: ").concat(mdSubtleBg).concat(important, ";\n border: 1px solid ").concat(mdBorder).concat(important, ";\n border-radius: 5px").concat(important, ";\n padding: 1px 5px").concat(important, ";\n white-space: break-spaces").concat(important, ";\n word-break: break-word").concat(important, ";\n direction: ltr").concat(important, ";\n unicode-bidi: embed").concat(important, ";\n }\n .message-bubble pre {\n margin: 10px 0 11px").concat(important, ";\n padding: 10px 12px").concat(important, ";\n background: ").concat(mdSubtleBg).concat(important, ";\n border: 1px solid ").concat(mdBorder).concat(important, ";\n border-radius: 10px").concat(important, ";\n overflow-x: auto").concat(important, ";\n direction: ltr").concat(important, ";\n text-align: left").concat(important, ";\n }\n .message-bubble pre code {\n background: none").concat(important, ";\n border: none").concat(important, ";\n border-radius: 0").concat(important, ";\n padding: 0").concat(important, ";\n font-size: 0.85em").concat(important, ";\n line-height: 1.5").concat(important, ";\n white-space: pre").concat(important, ";\n word-break: normal").concat(important, ";\n }\n\n .message-bubble blockquote {\n margin: 10px 0").concat(important, ";\n padding-block: 2px").concat(important, ";\n padding-inline-start: 12px").concat(important, ";\n padding-inline-end: 0").concat(important, ";\n border-inline-start: 3px solid ").concat(mdAccent).concat(important, ";\n color: ").concat(mdMuted).concat(important, ";\n }\n .message-bubble blockquote > *:last-child { margin-bottom: 0").concat(important, "; }\n\n .message-bubble hr {\n border: none").concat(important, ";\n border-top: 1px solid ").concat(mdRule).concat(important, ";\n height: 0").concat(important, ";\n margin: 13px 0").concat(important, ";\n }\n\n .message-bubble .md-table-wrap {\n margin: 10px 0 11px").concat(important, ";\n overflow-x: auto").concat(important, ";\n border: 1px solid ").concat(mdBorder).concat(important, ";\n border-radius: 9px").concat(important, ";\n }\n .message-bubble table {\n border-collapse: collapse").concat(important, ";\n width: 100%").concat(important, ";\n font-size: 0.93em").concat(important, ";\n }\n .message-bubble th, .message-bubble td {\n padding: 7px 11px").concat(important, ";\n text-align: start").concat(important, ";\n border-bottom: 1px solid ").concat(mdBorder).concat(important, ";\n vertical-align: top").concat(important, ";\n }\n .message-bubble thead th {\n background: ").concat(mdSubtleBg).concat(important, ";\n font-weight: 700").concat(important, ";\n }\n .message-bubble tbody tr:nth-child(even) { background: ").concat(mdSubtlerBg).concat(important, "; }\n .message-bubble tbody tr:last-child td { border-bottom: none").concat(important, "; }\n\n .message-bubble .md-img {\n display: block").concat(important, ";\n max-width: 100%").concat(important, ";\n height: auto").concat(important, ";\n border-radius: 8px").concat(important, ";\n margin: 8px 0").concat(important, ";\n }\n\n .message.user { \n align-self: stretch").concat(important, ";\n align-items: stretch").concat(important, ";\n }\n .message.agent {\n align-self: stretch").concat(important, ";\n align-items: stretch").concat(important, ";\n }\n .message.user .message-bubble {\n margin-left: auto").concat(important, ";\n margin-right: 0").concat(important, ";\n }\n .message.agent .message-bubble {\n margin-left: 0").concat(important, ";\n margin-right: auto").concat(important, ";\n }\n .message-meta {\n position: absolute").concat(important, ";\n right: 11px").concat(important, ";\n bottom: 8px").concat(important, ";\n z-index: 2").concat(important, ";\n display: inline-flex").concat(important, ";\n align-items: center").concat(important, ";\n gap: 5px").concat(important, ";\n margin: 0").concat(important, ";\n color: rgba(255,255,255,0.55)").concat(important, ";\n font-size: 9px").concat(important, ";\n line-height: 1").concat(important, ";\n direction: ltr").concat(important, ";\n white-space: nowrap").concat(important, ";\n pointer-events: none").concat(important, ";\n }\n .message.user .message-meta {\n color: rgba(255,255,255,0.74)").concat(important, ";\n }\n .message-content { position: relative").concat(important, "; z-index: 1").concat(important, "; display: inline").concat(important, "; overflow-wrap: anywhere").concat(important, "; word-break: break-word").concat(important, "; direction: inherit").concat(important, "; }\n .message-meta-spacer { display: inline-block").concat(important, "; width: 0").concat(important, "; height: 1px").concat(important, "; }\n .message-delivery-checks { color: rgba(255,255,255,0.92)").concat(important, "; font-weight: 700").concat(important, "; letter-spacing: -2px").concat(important, "; }\n .message-expand-button {\n position: relative").concat(important, ";\n z-index: 3").concat(important, ";\n margin: 0 4px").concat(important, ";\n padding: 0").concat(important, ";\n border: 0").concat(important, ";\n background: transparent").concat(important, ";\n color: #c4b5fd").concat(important, ";\n font: inherit").concat(important, ";\n font-size: 0.78em").concat(important, ";\n font-weight: 600").concat(important, ";\n line-height: inherit").concat(important, ";\n text-decoration: underline").concat(important, ";\n text-underline-offset: 2px").concat(important, ";\n cursor: pointer").concat(important, ";\n }\n .message-expand-button:hover { color: #ede9fe").concat(important, "; }\n .message-avatar { \n width: ").concat(avatarSize).concat(important, "; \n height: ").concat(avatarSize).concat(important, "; \n min-width: ").concat(avatarSize).concat(important, "; \n border-radius: 50%").concat(important, "; \n display: flex").concat(important, "; \n align-items: center").concat(important, "; \n justify-content: center").concat(important, "; \n flex-shrink: 0").concat(important, "; \n color: inherit").concat(important, "; \n font-size: ").concat(useVoiceTheme ? '14' : '20', "px").concat(important, "; \n line-height: 1").concat(important, "; \n background: transparent").concat(important, "; \n border: none").concat(important, "; \n box-sizing: border-box").concat(important, "; \n }\n .message-avatar.user { background: ").concat(avatarUserBg).concat(important, "; color: ").concat(avatarUserColor).concat(important, "; }\n .message-avatar.agent { background: ").concat(avatarAgentBg).concat(important, "; }\n \n .message.system {\n background: ").concat(messages.systemBackgroundColor, ";\n align-self: flex-start").concat(important, ";\n }\n .message.error {\n background: ").concat(messages.errorBackgroundColor, ";\n align-self: flex-start").concat(important, ";\n }\n \n .input-container {\n display: flex").concat(important, ";\n gap: 8px").concat(important, ";\n padding: 12px 16px").concat(important, ";\n background: ").concat(inputContainerBg).concat(important, ";\n border-top: 1px solid ").concat(inputContainerBorderTop).concat(important, ";\n align-items: center").concat(important, ";\n flex-shrink: 0").concat(important, ";\n flex-direction: row").concat(important, ";\n direction: ltr").concat(important, ";\n }\n .text-interface-footer {\n position: relative").concat(important, ";\n flex-shrink: 0").concat(important, ";\n min-height: 28px").concat(important, ";\n padding: 4px 12px").concat(important, ";\n background: ").concat(topBarBg).concat(important, ";\n border-top: 1px solid ").concat(inputContainerBorderTop).concat(important, ";\n display: flex").concat(important, ";\n justify-content: center").concat(important, ";\n align-items: center").concat(important, ";\n gap: 8px").concat(important, ";\n direction: ltr").concat(important, ";\n }\n .text-interface-footer .ttp-info-btn {\n position: absolute").concat(important, ";\n right: 12px").concat(important, ";\n margin-left: auto").concat(important, ";\n }\n .text-interface-powered {\n color: rgba(255,255,255,0.46)").concat(important, ";\n font-size: 10px").concat(important, ";\n line-height: 1.2").concat(important, ";\n text-align: center").concat(important, ";\n white-space: nowrap").concat(important, ";\n }\n .text-interface-powered a {\n color: ").concat(sendButtonColor).concat(important, ";\n text-decoration: none").concat(important, ";\n }\n .text-interface.active ~ .ttp-footer {\n display: none").concat(important, ";\n }\n \n .input-wrapper {\n position: relative").concat(important, ";\n display: flex").concat(important, ";\n align-items: center").concat(important, ";\n }\n \n .message-input {\n width: 100%").concat(important, ";\n min-height: ").concat(TEXT_INPUT_MIN_HEIGHT_PX, "px").concat(important, ";\n max-height: ").concat(TEXT_INPUT_MAX_HEIGHT_PX, "px").concat(important, ";\n padding: ").concat(inputPadding, ";\n border: 1px solid ").concat(inputBorderColor, ";\n border-radius: ").concat(inputBorderRadius, "px;\n font-size: ").concat(inputFontSize, ";\n font-family: inherit").concat(important, ";\n line-height: 1.4").concat(important, ";\n resize: none").concat(important, ";\n overflow-y: auto").concat(important, ";\n background: ").concat(inputBackgroundColor, ";\n color: ").concat(inputTextColor, ";\n vertical-align: top").concat(important, ";\n margin: 0").concat(important, ";\n display: block").concat(important, ";\n white-space: pre-wrap").concat(important, ";\n word-wrap: break-word").concat(important, ";\n text-align: start").concat(important, ";\n direction: ").concat(textDirection).concat(important, ";\n unicode-bidi: plaintext").concat(important, ";\n -webkit-appearance: none").concat(important, ";\n appearance: none").concat(important, ";\n box-sizing: border-box").concat(important, ";\n }\n \n .message-input:focus {\n outline: none").concat(important, ";\n border-color: ").concat(inputFocusColor, ";\n background: ").concat(inputFocusBg).concat(important, ";\n box-shadow: ").concat(inputFocusBoxShadow, ";\n }\n \n .message-input::placeholder {\n color: ").concat(placeholderColor).concat(important, ";\n text-align: start").concat(important, ";\n direction: ").concat(textDirection).concat(important, ";\n }\n \n .send-button {\n width: 38px").concat(important, ";\n height: 38px").concat(important, ";\n border-radius: 50%").concat(important, ";\n border: none").concat(important, ";\n background: linear-gradient(135deg, ").concat(sendButtonColor, ", ").concat(sendButtonHoverColor, ")").concat(important, ";\n color: ").concat(sendButtonTextColor, ";\n font-size: ").concat(this.config.sendButtonFontSize || ((_this$config$panel15 = this.config.panel) === null || _this$config$panel15 === void 0 ? void 0 : _this$config$panel15.sendButtonFontSize) || '16px', ";\n font-weight: ").concat(this.config.sendButtonFontWeight || ((_this$config$panel16 = this.config.panel) === null || _this$config$panel16 === void 0 ? void 0 : _this$config$panel16.sendButtonFontWeight) || '500', ";\n cursor: pointer").concat(important, ";\n display: flex").concat(important, ";\n align-items: center").concat(important, ";\n justify-content: center").concat(important, ";\n flex-shrink: 0").concat(important, ";\n transition: all 0.2s ease").concat(important, ";\n box-shadow: 0 4px 12px rgba(").concat(accentRgb[0], ", ").concat(accentRgb[1], ", ").concat(accentRgb[2], ", 0.32)").concat(important, ";\n }\n .send-icon {\n width: 18px").concat(important, ";\n height: 18px").concat(important, ";\n fill: none").concat(important, ";\n stroke: currentColor").concat(important, ";\n stroke-width: 2.1").concat(important, ";\n stroke-linecap: round").concat(important, ";\n stroke-linejoin: round").concat(important, ";\n }\n \n .send-button:hover:not(:disabled) {\n background: ").concat(sendButtonHoverColor, ";\n transform: scale(1.05)").concat(important, ";\n box-shadow: 0 6px 16px rgba(").concat(accentRgb[0], ", ").concat(accentRgb[1], ", ").concat(accentRgb[2], ", 0.42)").concat(important, ";\n }\n \n .send-button-hint {\n width: 100%").concat(important, ";\n text-align: center").concat(important, ";\n margin-top: 4px").concat(important, ";\n }\n \n .send-button:disabled {\n opacity: 0.5").concat(important, ";\n cursor: not-allowed").concat(important, ";\n }\n \n .typing-indicator {\n display: inline-flex").concat(important, ";\n gap: 4px").concat(important, ";\n align-items: center").concat(important, ";\n }\n \n .typing-dot {\n width: 6px").concat(important, ";\n height: 6px").concat(important, ";\n border-radius: 50%").concat(important, ";\n background: rgba(").concat(accentRgb[0], ", ").concat(accentRgb[1], ", ").concat(accentRgb[2], ", ").concat(typingDotAlpha, ")").concat(important, ";\n animation: typingDot 1.4s ease-in-out infinite").concat(important, ";\n }\n \n .typing-dot:nth-child(2) { animation-delay: 0.2s").concat(important, "; }\n .typing-dot:nth-child(3) { animation-delay: 0.4s").concat(important, "; }\n \n @keyframes typingDot {\n 0%, 60%, 100% { transform: translateY(0); opacity: 0.7; }\n 30% { transform: translateY(-8px); opacity: 1; }\n }\n \n .error-message {\n padding: 12px").concat(important, ";\n background: ").concat(errorBubbleBg, ";\n border-radius: ").concat(messages.borderRadius, "px;\n color: ").concat(errorBubbleColor).concat(important, ";\n border: ").concat(errorBubbleBorder).concat(important, ";\n font-size: ").concat(messages.fontSize).concat(important, ";\n margin: 8px 0").concat(important, ";\n }\n \n ").concat(useVoiceTheme ? "\n #textInterface.active .input-container .send-button-hint {\n color: rgba(255,255,255,0.72)".concat(important, ";\n }\n ") : '', "\n \n @media (max-width: 768px) {\n #messagesContainer {\n padding: 12px").concat(important, ";\n gap: 12px").concat(important, ";\n }\n \n .message-bubble {\n max-width: 85%").concat(important, ";\n font-size: ").concat(messages.fontSize).concat(important, ";\n padding: 12px 62px 12px 14px").concat(important, ";\n padding-right: 62px").concat(important, ";\n }\n \n .text-input-container {\n padding: 10px").concat(important, ";\n gap: 8px").concat(important, ";\n }\n \n #text-chat-input {\n font-size: 16px !important; /* Prevents iOS zoom on focus */\n padding: 10px 14px").concat(important, ";\n min-height: 44px").concat(important, ";\n }\n \n #text-chat-send {\n min-width: 56px").concat(important, ";\n min-height: 44px").concat(important, ";\n width: 56px").concat(important, ";\n height: 44px").concat(important, ";\n }\n \n .empty-state-icon {\n font-size: 44px").concat(important, ";\n }\n \n .empty-state-title {\n font-size: 20px").concat(important, ";\n }\n \n .empty-state-text {\n font-size: 14px").concat(important, ";\n }\n }\n \n @media (max-width: 480px) {\n #messagesContainer {\n padding: 10px").concat(important, ";\n gap: 10px").concat(important, ";\n }\n \n .message-bubble {\n max-width: 90%").concat(important, ";\n font-size: ").concat(messages.fontSize).concat(important, ";\n padding: 10px 62px 10px 12px").concat(important, ";\n padding-right: 62px").concat(important, ";\n }\n \n .text-input-container {\n padding: 8px").concat(important, ";\n }\n \n #text-chat-input {\n font-size: 16px !important;\n padding: 8px 12px").concat(important, ";\n }\n }\n ");
|
|
37566
37773
|
}
|
|
37567
37774
|
|
|
37568
37775
|
/**
|
|
@@ -37606,7 +37813,10 @@ var TextInterface = /*#__PURE__*/function () {
|
|
|
37606
37813
|
}, 0);
|
|
37607
37814
|
}
|
|
37608
37815
|
};
|
|
37609
|
-
inputField.addEventListener('input',
|
|
37816
|
+
inputField.addEventListener('input', function () {
|
|
37817
|
+
_this.updateInputWritingDirection(inputField);
|
|
37818
|
+
autoResize();
|
|
37819
|
+
});
|
|
37610
37820
|
inputField.addEventListener('keydown', function (e) {
|
|
37611
37821
|
if (e.key === 'Enter' && !e.shiftKey) {
|
|
37612
37822
|
e.preventDefault();
|
|
@@ -37655,14 +37865,17 @@ var TextInterface = /*#__PURE__*/function () {
|
|
|
37655
37865
|
// Update placeholder based on current language
|
|
37656
37866
|
var inputPlaceholder = this.config.inputPlaceholder || ((_this$config$panel17 = this.config.panel) === null || _this$config$panel17 === void 0 ? void 0 : _this$config$panel17.inputPlaceholder) || this.t('typeMessage') || 'Type your message...';
|
|
37657
37867
|
inputField.placeholder = inputPlaceholder;
|
|
37658
|
-
|
|
37659
|
-
// Update direction
|
|
37660
|
-
inputField.dir = this.config.direction || 'ltr';
|
|
37661
|
-
|
|
37662
|
-
// Update text-align style
|
|
37663
|
-
inputField.style.textAlign = this.config.direction === 'rtl' ? 'right' : 'left';
|
|
37868
|
+
this.updateInputWritingDirection(inputField);
|
|
37664
37869
|
}
|
|
37665
37870
|
}
|
|
37871
|
+
}, {
|
|
37872
|
+
key: "updateInputWritingDirection",
|
|
37873
|
+
value: function updateInputWritingDirection(inputField) {
|
|
37874
|
+
var direction = resolveInputTextDirection(inputField.value, this.textDirection);
|
|
37875
|
+
inputField.dir = direction;
|
|
37876
|
+
inputField.style.setProperty('direction', direction, 'important');
|
|
37877
|
+
inputField.style.setProperty('text-align', direction === 'rtl' ? 'right' : 'left', 'important');
|
|
37878
|
+
}
|
|
37666
37879
|
|
|
37667
37880
|
/**
|
|
37668
37881
|
* Show text interface
|
|
@@ -37748,6 +37961,7 @@ var TextInterface = /*#__PURE__*/function () {
|
|
|
37748
37961
|
input.value = '';
|
|
37749
37962
|
input.style.height = "".concat(TEXT_INPUT_MIN_HEIGHT_PX, "px");
|
|
37750
37963
|
input.style.overflow = 'hidden';
|
|
37964
|
+
this.updateInputWritingDirection(input);
|
|
37751
37965
|
|
|
37752
37966
|
// Prepare streaming bubble and send via SDK
|
|
37753
37967
|
_context2.p = 3;
|
|
@@ -37794,10 +38008,38 @@ var TextInterface = /*#__PURE__*/function () {
|
|
|
37794
38008
|
/**
|
|
37795
38009
|
* Add message to UI
|
|
37796
38010
|
*/
|
|
38011
|
+
}, {
|
|
38012
|
+
key: "messageTime",
|
|
38013
|
+
value: function messageTime() {
|
|
38014
|
+
return new Intl.DateTimeFormat(undefined, {
|
|
38015
|
+
hour: '2-digit',
|
|
38016
|
+
minute: '2-digit',
|
|
38017
|
+
hour12: false
|
|
38018
|
+
}).format(new Date());
|
|
38019
|
+
}
|
|
38020
|
+
}, {
|
|
38021
|
+
key: "addMessageExpansion",
|
|
38022
|
+
value: function addMessageExpansion(content, text, spacer) {
|
|
38023
|
+
if (!spacer || text.length <= MESSAGE_COLLAPSE_THRESHOLD) return;
|
|
38024
|
+
var expanded = false;
|
|
38025
|
+
var button = document.createElement('button');
|
|
38026
|
+
button.type = 'button';
|
|
38027
|
+
button.className = 'message-expand-button';
|
|
38028
|
+
button.textContent = 'Read more';
|
|
38029
|
+
button.setAttribute('aria-expanded', 'false');
|
|
38030
|
+
content.textContent = collapseMessageText(text);
|
|
38031
|
+
button.addEventListener('click', function () {
|
|
38032
|
+
expanded = !expanded;
|
|
38033
|
+
content.textContent = expanded ? text : collapseMessageText(text);
|
|
38034
|
+
button.textContent = expanded ? 'Read less' : 'Read more';
|
|
38035
|
+
button.setAttribute('aria-expanded', String(expanded));
|
|
38036
|
+
});
|
|
38037
|
+
spacer.parentNode.insertBefore(button, spacer);
|
|
38038
|
+
}
|
|
37797
38039
|
}, {
|
|
37798
38040
|
key: "addMessage",
|
|
37799
38041
|
value: function addMessage(type, text) {
|
|
37800
|
-
var
|
|
38042
|
+
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
37801
38043
|
var messages = this.shadowRoot.getElementById('messagesContainer');
|
|
37802
38044
|
if (!messages) return;
|
|
37803
38045
|
|
|
@@ -37807,18 +38049,46 @@ var TextInterface = /*#__PURE__*/function () {
|
|
|
37807
38049
|
emptyState.remove();
|
|
37808
38050
|
}
|
|
37809
38051
|
var message = document.createElement('div');
|
|
37810
|
-
var edgeClass =
|
|
38052
|
+
var edgeClass = type === 'user' ? 'edge-right' : 'edge-left';
|
|
37811
38053
|
message.className = "message ".concat(type, " ").concat(edgeClass);
|
|
37812
|
-
var avatar = document.createElement('div');
|
|
37813
|
-
avatar.className = "message-avatar ".concat(type);
|
|
37814
|
-
var avatarIcon = type === 'user' ? ((_this$config$messages = this.config.messages) === null || _this$config$messages === void 0 ? void 0 : _this$config$messages.userAvatarIcon) || '👤' : ((_this$config$messages2 = this.config.messages) === null || _this$config$messages2 === void 0 ? void 0 : _this$config$messages2.agentAvatarIcon) || '🤖';
|
|
37815
|
-
avatar.textContent = avatarIcon;
|
|
37816
38054
|
var bubble = document.createElement('div');
|
|
37817
38055
|
bubble.className = 'message-bubble';
|
|
37818
|
-
|
|
37819
|
-
|
|
37820
|
-
|
|
37821
|
-
message
|
|
38056
|
+
var messageDirection = resolveMessageTextDirection(text, this.textDirection);
|
|
38057
|
+
bubble.dir = messageDirection;
|
|
38058
|
+
var content = document.createElement(type === 'agent' ? 'div' : 'bdi');
|
|
38059
|
+
content.className = type === 'agent' ? 'message-content md' : 'message-content';
|
|
38060
|
+
content.dir = messageDirection;
|
|
38061
|
+
if (type === 'agent') {
|
|
38062
|
+
// Agent copy is markdown — render it so lists/bold/tables look designed.
|
|
38063
|
+
(0,_markdown_js__WEBPACK_IMPORTED_MODULE_1__.renderMarkdownInto)(content, text);
|
|
38064
|
+
} else {
|
|
38065
|
+
content.textContent = text;
|
|
38066
|
+
}
|
|
38067
|
+
var metaSpacer = document.createElement('span');
|
|
38068
|
+
metaSpacer.className = 'message-meta-spacer';
|
|
38069
|
+
metaSpacer.setAttribute('aria-hidden', 'true');
|
|
38070
|
+
var inlineElements = {
|
|
38071
|
+
content: content,
|
|
38072
|
+
spacer: metaSpacer
|
|
38073
|
+
};
|
|
38074
|
+
bubble.append.apply(bubble, _toConsumableArray(messageInlineOrder(this.textDirection).map(function (key) {
|
|
38075
|
+
return inlineElements[key];
|
|
38076
|
+
})));
|
|
38077
|
+
if (type !== 'agent') {
|
|
38078
|
+
this.addMessageExpansion(content, text, metaSpacer);
|
|
38079
|
+
}
|
|
38080
|
+
var meta = document.createElement('div');
|
|
38081
|
+
meta.className = 'message-meta';
|
|
38082
|
+
var time = document.createElement('span');
|
|
38083
|
+
time.textContent = options.time || this.messageTime();
|
|
38084
|
+
meta.appendChild(time);
|
|
38085
|
+
if (type === 'user') {
|
|
38086
|
+
var checks = document.createElement('span');
|
|
38087
|
+
checks.className = 'message-delivery-checks';
|
|
38088
|
+
checks.textContent = options.deliveryChecks === 1 ? '✓' : '✓✓';
|
|
38089
|
+
meta.appendChild(checks);
|
|
38090
|
+
}
|
|
38091
|
+
bubble.appendChild(meta);
|
|
37822
38092
|
message.appendChild(bubble);
|
|
37823
38093
|
messages.appendChild(message);
|
|
37824
38094
|
messages.scrollTop = messages.scrollHeight;
|
|
@@ -37830,32 +38100,113 @@ var TextInterface = /*#__PURE__*/function () {
|
|
|
37830
38100
|
}, {
|
|
37831
38101
|
key: "beginStreaming",
|
|
37832
38102
|
value: function beginStreaming() {
|
|
37833
|
-
var _this$config$messages3;
|
|
37834
38103
|
var messages = this.shadowRoot.getElementById('messagesContainer');
|
|
37835
38104
|
if (!messages) return;
|
|
37836
38105
|
|
|
37837
38106
|
// Clean any previous indicator
|
|
37838
38107
|
this.stopStreamingState();
|
|
37839
38108
|
var el = document.createElement('div');
|
|
37840
|
-
var edgeClass =
|
|
38109
|
+
var edgeClass = 'edge-left';
|
|
37841
38110
|
el.className = "message agent ".concat(edgeClass);
|
|
37842
38111
|
el.id = 'agent-streaming';
|
|
37843
|
-
var avatar = document.createElement('div');
|
|
37844
|
-
avatar.className = 'message-avatar agent';
|
|
37845
|
-
avatar.textContent = ((_this$config$messages3 = this.config.messages) === null || _this$config$messages3 === void 0 ? void 0 : _this$config$messages3.agentAvatarIcon) || '🤖';
|
|
37846
38112
|
var bubble = document.createElement('div');
|
|
37847
38113
|
bubble.className = 'message-bubble';
|
|
38114
|
+
bubble.dir = this.textDirection;
|
|
37848
38115
|
// show typing dots until first chunk
|
|
37849
38116
|
bubble.innerHTML = '<span class="typing-indicator"><span class="typing-dot"></span><span class="typing-dot"></span><span class="typing-dot"></span></span>';
|
|
37850
|
-
|
|
38117
|
+
var meta = document.createElement('div');
|
|
38118
|
+
meta.className = 'message-meta';
|
|
38119
|
+
meta.textContent = this.messageTime();
|
|
38120
|
+
bubble.appendChild(meta);
|
|
37851
38121
|
el.appendChild(bubble);
|
|
37852
38122
|
messages.appendChild(el);
|
|
37853
38123
|
this.streamingEl = bubble;
|
|
38124
|
+
this.streamingBubble = bubble;
|
|
37854
38125
|
this.hasStartedStreaming = false;
|
|
37855
38126
|
this._pendingMedia = []; // Buffer for images that arrive before next text chunk
|
|
38127
|
+
this._streamBuffer = ''; // Raw markdown of the segment currently being written
|
|
38128
|
+
this._streamSegmentEl = null; // The .md-seg element that buffer renders into
|
|
37856
38129
|
messages.scrollTop = messages.scrollHeight;
|
|
37857
38130
|
}
|
|
37858
38131
|
|
|
38132
|
+
/** Drop the typing dots the first time real content arrives. */
|
|
38133
|
+
}, {
|
|
38134
|
+
key: "_clearTypingIndicator",
|
|
38135
|
+
value: function _clearTypingIndicator() {
|
|
38136
|
+
if (this.hasStartedStreaming) return;
|
|
38137
|
+
var dots = this.streamingEl && this.streamingEl.querySelector('.typing-indicator');
|
|
38138
|
+
if (dots) dots.remove();
|
|
38139
|
+
this.hasStartedStreaming = true;
|
|
38140
|
+
}
|
|
38141
|
+
|
|
38142
|
+
/**
|
|
38143
|
+
* The bubble is a sequence of text segments and image galleries. Text is kept
|
|
38144
|
+
* as raw markdown per segment and re-rendered in place as tokens arrive, so a
|
|
38145
|
+
* list or table only "snaps" into shape once its syntax is complete. A gallery
|
|
38146
|
+
* closes the current segment, and the text after it starts a fresh one.
|
|
38147
|
+
*/
|
|
38148
|
+
}, {
|
|
38149
|
+
key: "_ensureStreamSegment",
|
|
38150
|
+
value: function _ensureStreamSegment() {
|
|
38151
|
+
if (this._streamSegmentEl || !this.streamingEl) return this._streamSegmentEl;
|
|
38152
|
+
var seg = document.createElement('div');
|
|
38153
|
+
seg.className = 'md-seg md';
|
|
38154
|
+
seg.dir = this.streamingEl.dir || this.textDirection;
|
|
38155
|
+
var meta = this.streamingEl.querySelector('.message-meta');
|
|
38156
|
+
this.streamingEl.insertBefore(seg, meta || null);
|
|
38157
|
+
this._streamSegmentEl = seg;
|
|
38158
|
+
return seg;
|
|
38159
|
+
}
|
|
38160
|
+
}, {
|
|
38161
|
+
key: "_renderStreamSegment",
|
|
38162
|
+
value: function _renderStreamSegment() {
|
|
38163
|
+
this._cancelStreamRender();
|
|
38164
|
+
if (!this._streamBuffer) return;
|
|
38165
|
+
var seg = this._ensureStreamSegment();
|
|
38166
|
+
if (seg) (0,_markdown_js__WEBPACK_IMPORTED_MODULE_1__.renderMarkdownInto)(seg, this._streamBuffer);
|
|
38167
|
+
}
|
|
38168
|
+
|
|
38169
|
+
/**
|
|
38170
|
+
* Coalesce re-renders — tokens arrive faster than a person can read.
|
|
38171
|
+
* Deliberately a timer and not requestAnimationFrame: rAF is suspended in
|
|
38172
|
+
* background tabs, so a user who switches away mid-answer would come back to
|
|
38173
|
+
* a bubble that never grew. setTimeout is only throttled, not stopped.
|
|
38174
|
+
*/
|
|
38175
|
+
}, {
|
|
38176
|
+
key: "_scheduleStreamRender",
|
|
38177
|
+
value: function _scheduleStreamRender() {
|
|
38178
|
+
var _this3 = this;
|
|
38179
|
+
if (this._streamTimer) return;
|
|
38180
|
+
this._streamTimer = setTimeout(function () {
|
|
38181
|
+
_this3._streamTimer = null;
|
|
38182
|
+
if (!_this3.streamingEl) return;
|
|
38183
|
+
_this3._renderStreamSegment();
|
|
38184
|
+
_this3._scrollToBottom();
|
|
38185
|
+
}, STREAM_RENDER_INTERVAL_MS);
|
|
38186
|
+
}
|
|
38187
|
+
}, {
|
|
38188
|
+
key: "_cancelStreamRender",
|
|
38189
|
+
value: function _cancelStreamRender() {
|
|
38190
|
+
if (!this._streamTimer) return;
|
|
38191
|
+
clearTimeout(this._streamTimer);
|
|
38192
|
+
this._streamTimer = null;
|
|
38193
|
+
}
|
|
38194
|
+
|
|
38195
|
+
/** Final render of the open segment, then start a new one for later text. */
|
|
38196
|
+
}, {
|
|
38197
|
+
key: "_closeStreamSegment",
|
|
38198
|
+
value: function _closeStreamSegment() {
|
|
38199
|
+
this._renderStreamSegment();
|
|
38200
|
+
this._streamBuffer = '';
|
|
38201
|
+
this._streamSegmentEl = null;
|
|
38202
|
+
}
|
|
38203
|
+
}, {
|
|
38204
|
+
key: "_scrollToBottom",
|
|
38205
|
+
value: function _scrollToBottom() {
|
|
38206
|
+
var messages = this.shadowRoot.getElementById('messagesContainer');
|
|
38207
|
+
if (messages) messages.scrollTop = messages.scrollHeight;
|
|
38208
|
+
}
|
|
38209
|
+
|
|
37859
38210
|
/**
|
|
37860
38211
|
* Append chunk to streaming response.
|
|
37861
38212
|
* Does NOT flush buffered media here — media is flushed only when the
|
|
@@ -37865,24 +38216,12 @@ var TextInterface = /*#__PURE__*/function () {
|
|
|
37865
38216
|
}, {
|
|
37866
38217
|
key: "appendStreamingChunk",
|
|
37867
38218
|
value: function appendStreamingChunk(chunk) {
|
|
37868
|
-
if (!this.streamingEl) return;
|
|
37869
|
-
|
|
37870
|
-
|
|
37871
|
-
|
|
37872
|
-
|
|
37873
|
-
|
|
37874
|
-
|
|
37875
|
-
// Append text — use textNode if we have inline media DOM elements
|
|
37876
|
-
var hasInlineMedia = this.streamingEl.querySelector('.inline-media-gallery');
|
|
37877
|
-
if (hasInlineMedia) {
|
|
37878
|
-
this.streamingEl.appendChild(document.createTextNode(chunk));
|
|
37879
|
-
} else {
|
|
37880
|
-
this.streamingEl.textContent += chunk;
|
|
37881
|
-
}
|
|
37882
|
-
var messages = this.shadowRoot.getElementById('messagesContainer');
|
|
37883
|
-
if (messages) {
|
|
37884
|
-
messages.scrollTop = messages.scrollHeight;
|
|
37885
|
-
}
|
|
38219
|
+
if (!this.streamingEl || typeof chunk !== 'string' || chunk === '') return;
|
|
38220
|
+
this._clearTypingIndicator();
|
|
38221
|
+
var direction = resolveMessageTextDirection(this._streamBuffer + chunk, this.textDirection);
|
|
38222
|
+
if (this.streamingBubble) this.streamingBubble.dir = direction;
|
|
38223
|
+
this._streamBuffer += chunk;
|
|
38224
|
+
this._scheduleStreamRender();
|
|
37886
38225
|
}
|
|
37887
38226
|
|
|
37888
38227
|
/**
|
|
@@ -37903,10 +38242,7 @@ var TextInterface = /*#__PURE__*/function () {
|
|
|
37903
38242
|
key: "appendStreamingMedia",
|
|
37904
38243
|
value: function appendStreamingMedia(images, title) {
|
|
37905
38244
|
if (!this.streamingEl) return;
|
|
37906
|
-
|
|
37907
|
-
this.streamingEl.textContent = '';
|
|
37908
|
-
this.hasStartedStreaming = true;
|
|
37909
|
-
}
|
|
38245
|
+
this._clearTypingIndicator();
|
|
37910
38246
|
|
|
37911
38247
|
// Flush previous media — the text describing those images is complete
|
|
37912
38248
|
this._flushPendingMedia();
|
|
@@ -37927,6 +38263,10 @@ var TextInterface = /*#__PURE__*/function () {
|
|
|
37927
38263
|
value: function _flushPendingMedia() {
|
|
37928
38264
|
if (!this._pendingMedia || this._pendingMedia.length === 0) return;
|
|
37929
38265
|
if (!this.streamingEl) return;
|
|
38266
|
+
|
|
38267
|
+
// Commit the text written so far before the galleries land under it, so the
|
|
38268
|
+
// text that follows them renders as its own segment instead of being merged.
|
|
38269
|
+
this._closeStreamSegment();
|
|
37930
38270
|
var _iterator = _createForOfIteratorHelper(this._pendingMedia),
|
|
37931
38271
|
_step;
|
|
37932
38272
|
try {
|
|
@@ -37950,7 +38290,7 @@ var TextInterface = /*#__PURE__*/function () {
|
|
|
37950
38290
|
}, {
|
|
37951
38291
|
key: "_renderInlineMedia",
|
|
37952
38292
|
value: function _renderInlineMedia(images, title) {
|
|
37953
|
-
var
|
|
38293
|
+
var _this4 = this;
|
|
37954
38294
|
var gallery = document.createElement('div');
|
|
37955
38295
|
gallery.className = 'inline-media-gallery';
|
|
37956
38296
|
gallery.style.cssText = 'display:flex;gap:6px;flex-wrap:wrap;margin:8px 0;';
|
|
@@ -37969,10 +38309,10 @@ var TextInterface = /*#__PURE__*/function () {
|
|
|
37969
38309
|
|
|
37970
38310
|
// Open fullscreen gallery viewer on click (same as voice gallery)
|
|
37971
38311
|
imgEl.addEventListener('click', function () {
|
|
37972
|
-
if (!
|
|
37973
|
-
|
|
38312
|
+
if (!_this4._inlineGalleryHandler) {
|
|
38313
|
+
_this4._inlineGalleryHandler = (0,_galleryHandler_js__WEBPACK_IMPORTED_MODULE_0__.createGalleryHandler)(_this4._widget);
|
|
37974
38314
|
}
|
|
37975
|
-
|
|
38315
|
+
_this4._inlineGalleryHandler.handleShowMedia({
|
|
37976
38316
|
images: images,
|
|
37977
38317
|
title: title
|
|
37978
38318
|
});
|
|
@@ -38008,20 +38348,28 @@ var TextInterface = /*#__PURE__*/function () {
|
|
|
38008
38348
|
key: "finalizeStreaming",
|
|
38009
38349
|
value: function finalizeStreaming(fullText) {
|
|
38010
38350
|
if (this.streamingEl) {
|
|
38011
|
-
|
|
38351
|
+
this._cancelStreamRender();
|
|
38352
|
+
// An empty reply must not leave the typing dots spinning forever.
|
|
38353
|
+
this._clearTypingIndicator();
|
|
38354
|
+
var hasGalleries = !!this.streamingEl.querySelector('.inline-media-gallery') || this._pendingMedia && this._pendingMedia.length > 0;
|
|
38355
|
+
|
|
38356
|
+
// Without interleaved media the `done` payload is the authoritative text,
|
|
38357
|
+
// so re-render from it. With media, the bubble is a mix of segments and
|
|
38358
|
+
// galleries that fullText can't describe — keep what streaming produced.
|
|
38359
|
+
if (!hasGalleries && typeof fullText === 'string' && fullText) {
|
|
38360
|
+
var direction = resolveMessageTextDirection(fullText, this.textDirection);
|
|
38361
|
+
if (this.streamingBubble) this.streamingBubble.dir = direction;
|
|
38362
|
+
this._streamBuffer = fullText;
|
|
38363
|
+
}
|
|
38364
|
+
this._renderStreamSegment();
|
|
38365
|
+
|
|
38366
|
+
// Flush trailing galleries (also commits the segment above them)
|
|
38012
38367
|
this._flushPendingMedia();
|
|
38013
|
-
|
|
38014
|
-
// If we have inline media (child elements beyond text), don't overwrite with textContent
|
|
38015
|
-
// as that would destroy the gallery DOM elements.
|
|
38016
|
-
var hasInlineMedia = this.streamingEl.querySelector('.inline-media-gallery');
|
|
38017
|
-
if (!hasInlineMedia) {
|
|
38018
|
-
this.streamingEl.textContent = fullText || this.streamingEl.textContent;
|
|
38019
|
-
}
|
|
38020
|
-
// If hasInlineMedia, keep the DOM as-is — it already has text nodes + gallery elements
|
|
38021
|
-
|
|
38368
|
+
this._closeStreamSegment();
|
|
38022
38369
|
var container = this.shadowRoot.getElementById('agent-streaming');
|
|
38023
38370
|
if (container) container.id = '';
|
|
38024
38371
|
this.streamingEl = null;
|
|
38372
|
+
this.streamingBubble = null;
|
|
38025
38373
|
this._pendingMedia = [];
|
|
38026
38374
|
}
|
|
38027
38375
|
this.updateSendButtonState();
|
|
@@ -38033,10 +38381,14 @@ var TextInterface = /*#__PURE__*/function () {
|
|
|
38033
38381
|
}, {
|
|
38034
38382
|
key: "stopStreamingState",
|
|
38035
38383
|
value: function stopStreamingState() {
|
|
38384
|
+
this._cancelStreamRender();
|
|
38036
38385
|
var existing = this.shadowRoot.getElementById('agent-streaming');
|
|
38037
38386
|
if (existing) existing.remove();
|
|
38038
38387
|
this.streamingEl = null;
|
|
38388
|
+
this.streamingBubble = null;
|
|
38039
38389
|
this.hasStartedStreaming = false;
|
|
38390
|
+
this._streamBuffer = '';
|
|
38391
|
+
this._streamSegmentEl = null;
|
|
38040
38392
|
}
|
|
38041
38393
|
|
|
38042
38394
|
/**
|
|
@@ -38051,11 +38403,11 @@ var TextInterface = /*#__PURE__*/function () {
|
|
|
38051
38403
|
// Check if this is a domain validation error
|
|
38052
38404
|
var isDomainError = error && (error.message === 'DOMAIN_NOT_WHITELISTED' || typeof error === 'string' && error.includes('DOMAIN_NOT_WHITELISTED') || error.message && error.message.includes('Domain not whitelisted') || typeof error === 'string' && error.includes('Domain not whitelisted'));
|
|
38053
38405
|
if (isDomainError) {
|
|
38054
|
-
var _this$config$
|
|
38406
|
+
var _this$config$messages;
|
|
38055
38407
|
// Show domain error with title and message
|
|
38056
38408
|
var errorContainer = document.createElement('div');
|
|
38057
38409
|
errorContainer.className = 'error-message';
|
|
38058
|
-
errorContainer.style.cssText = 'padding: 16px; margin: 12px; border-radius: 8px; background: ' + (((_this$config$
|
|
38410
|
+
errorContainer.style.cssText = 'padding: 16px; margin: 12px; border-radius: 8px; background: ' + (((_this$config$messages = this.config.messages) === null || _this$config$messages === void 0 ? void 0 : _this$config$messages.errorBackgroundColor) || '#FEE2E2') + ';';
|
|
38059
38411
|
var title = document.createElement('div');
|
|
38060
38412
|
title.style.cssText = 'font-weight: 600; font-size: 17px; margin-bottom: 8px; color: #991B1B;';
|
|
38061
38413
|
title.textContent = this.t('domainNotValidated');
|
|
@@ -38908,7 +39260,7 @@ var VoiceInterface = /*#__PURE__*/function () {
|
|
|
38908
39260
|
value: function () {
|
|
38909
39261
|
var _proceedWithVoiceCall = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee4() {
|
|
38910
39262
|
var _this3 = this;
|
|
38911
|
-
var isResumeCall, panel, header, toggleText, originalSection, compactSection, idleState, _idleState, activeState, stripOnly, voiceInterface, connected, serverRejected, originalOnError, originalOnDisconnected, attempts, _vs, vs, hasDisclaimers, sendDisclaimerAckAfterMobileMicReady, _vs$lastDisclaimerPay, disclaimerTexts, _this$config$inputFor, _this$config$connecti,
|
|
39263
|
+
var isResumeCall, panel, header, toggleText, originalSection, compactSection, idleState, _idleState, activeState, stripOnly, voiceInterface, connected, serverRejected, originalOnError, originalOnDisconnected, attempts, _vs, vs, hasDisclaimers, sendDisclaimerAckAfterMobileMicReady, _vs$lastDisclaimerPay, disclaimerTexts, _this$config$inputFor, _this$config$connecti, primeSr, audioConstraints, micStream, floatingButton, mobileFab, delayConfig, streamToUse, _this$sdk$voiceSDK, error, existingBar, _existingBar, _idleState2, _floatingButton, updateTimer, isDisclaimerDeclined, deviceInfo, _t, _t2, _t3, _t4, _t5, _t6;
|
|
38912
39264
|
return _regenerator().w(function (_context4) {
|
|
38913
39265
|
while (1) switch (_context4.p = _context4.n) {
|
|
38914
39266
|
case 0:
|
|
@@ -39150,21 +39502,44 @@ var VoiceInterface = /*#__PURE__*/function () {
|
|
|
39150
39502
|
|
|
39151
39503
|
// On mobile: get getUserMedia stream once, pass to startListening to avoid double-call
|
|
39152
39504
|
if (!this.isMobile) {
|
|
39153
|
-
_context4.n =
|
|
39505
|
+
_context4.n = 24;
|
|
39154
39506
|
break;
|
|
39155
39507
|
}
|
|
39156
39508
|
_context4.p = 15;
|
|
39157
|
-
|
|
39509
|
+
// This preliminary stream is REUSED as the capture stream (iOS single-stream fix),
|
|
39510
|
+
// so it must carry the same AEC constraints as the desktop path — bare { audio: true }
|
|
39511
|
+
// leaves echoCancellation/noiseSuppression/autoGainControl (and iOS voiceIsolation) to
|
|
39512
|
+
// browser defaults, which can let speakerphone TTS echo cross VAD and trigger barge-in.
|
|
39513
|
+
primeSr = ((_this$config$inputFor = this.config.inputFormat) === null || _this$config$inputFor === void 0 ? void 0 : _this$config$inputFor.sampleRate) || this.config.sampleRate || 16000;
|
|
39514
|
+
audioConstraints = (0,_core_AudioRecorder_js__WEBPACK_IMPORTED_MODULE_1__.buildAudioConstraints)(primeSr, this.config.audioConstraints || {});
|
|
39515
|
+
_context4.p = 16;
|
|
39516
|
+
_context4.n = 17;
|
|
39517
|
+
return navigator.mediaDevices.getUserMedia({
|
|
39518
|
+
audio: audioConstraints
|
|
39519
|
+
});
|
|
39520
|
+
case 17:
|
|
39521
|
+
micStream = _context4.v;
|
|
39522
|
+
_context4.n = 20;
|
|
39523
|
+
break;
|
|
39524
|
+
case 18:
|
|
39525
|
+
_context4.p = 18;
|
|
39526
|
+
_t2 = _context4.v;
|
|
39527
|
+
// Some devices/webviews reject specific constraints (OverconstrainedError etc.).
|
|
39528
|
+
// Fall back to minimal so permission still succeeds, matching prior behavior.
|
|
39529
|
+
console.warn('⚠️ Mobile getUserMedia with AEC constraints failed, retrying minimal:', (_t2 === null || _t2 === void 0 ? void 0 : _t2.name) || _t2);
|
|
39530
|
+
_context4.n = 19;
|
|
39158
39531
|
return navigator.mediaDevices.getUserMedia({
|
|
39159
39532
|
audio: true
|
|
39160
39533
|
});
|
|
39161
|
-
case
|
|
39534
|
+
case 19:
|
|
39162
39535
|
micStream = _context4.v;
|
|
39536
|
+
// Flagged so client_audio_info telemetry reports the AEC constraints were NOT applied
|
|
39537
|
+
micStream._ttpConstraintsFallback = true;
|
|
39538
|
+
case 20:
|
|
39163
39539
|
this._preliminaryInputStream = micStream;
|
|
39164
|
-
|
|
39165
|
-
_context4.n = 17;
|
|
39540
|
+
_context4.n = 21;
|
|
39166
39541
|
return _core_AudioRecorder_js__WEBPACK_IMPORTED_MODULE_1__["default"].primeSharedContext(primeSr);
|
|
39167
|
-
case
|
|
39542
|
+
case 21:
|
|
39168
39543
|
// Hide floating button now that permission is granted
|
|
39169
39544
|
floatingButton = this.shadowRoot.getElementById('text-chat-button') || document.getElementById('text-chat-button');
|
|
39170
39545
|
if (floatingButton) floatingButton.style.display = 'none';
|
|
@@ -39177,51 +39552,51 @@ var VoiceInterface = /*#__PURE__*/function () {
|
|
|
39177
39552
|
android: 3000,
|
|
39178
39553
|
ios: 0
|
|
39179
39554
|
};
|
|
39180
|
-
_context4.n =
|
|
39555
|
+
_context4.n = 22;
|
|
39181
39556
|
return (0,_shared_applyDelay_js__WEBPACK_IMPORTED_MODULE_3__.applyDelay)(delayConfig);
|
|
39182
|
-
case
|
|
39557
|
+
case 22:
|
|
39183
39558
|
if (sendDisclaimerAckAfterMobileMicReady) {
|
|
39184
39559
|
vs.sendDisclaimerAck(true);
|
|
39185
39560
|
sendDisclaimerAckAfterMobileMicReady = false;
|
|
39186
39561
|
}
|
|
39187
|
-
_context4.n =
|
|
39562
|
+
_context4.n = 24;
|
|
39188
39563
|
break;
|
|
39189
|
-
case
|
|
39190
|
-
_context4.p =
|
|
39191
|
-
|
|
39192
|
-
console.error('❌ Microphone permission denied:',
|
|
39564
|
+
case 23:
|
|
39565
|
+
_context4.p = 23;
|
|
39566
|
+
_t3 = _context4.v;
|
|
39567
|
+
console.error('❌ Microphone permission denied:', _t3);
|
|
39193
39568
|
this._stopPreliminaryInputStream();
|
|
39194
|
-
throw
|
|
39195
|
-
case
|
|
39196
|
-
_context4.p =
|
|
39569
|
+
throw _t3;
|
|
39570
|
+
case 24:
|
|
39571
|
+
_context4.p = 24;
|
|
39197
39572
|
streamToUse = this._preliminaryInputStream || null;
|
|
39198
39573
|
if (streamToUse) this._preliminaryInputStream = null;
|
|
39199
|
-
_context4.n =
|
|
39574
|
+
_context4.n = 25;
|
|
39200
39575
|
return this.sdk.startListening(streamToUse);
|
|
39201
|
-
case
|
|
39576
|
+
case 25:
|
|
39202
39577
|
if (!(!this.sdk.isConnected || !this.sdk.voiceSDK || !this.sdk.voiceSDK.isConnected || !this.sdk.voiceSDK.websocket || this.sdk.voiceSDK.websocket.readyState !== WebSocket.OPEN)) {
|
|
39203
|
-
_context4.n =
|
|
39578
|
+
_context4.n = 30;
|
|
39204
39579
|
break;
|
|
39205
39580
|
}
|
|
39206
39581
|
if (!((_this$sdk$voiceSDK = this.sdk.voiceSDK) !== null && _this$sdk$voiceSDK !== void 0 && _this$sdk$voiceSDK.isRecording)) {
|
|
39207
|
-
_context4.n =
|
|
39582
|
+
_context4.n = 29;
|
|
39208
39583
|
break;
|
|
39209
39584
|
}
|
|
39210
|
-
_context4.p =
|
|
39211
|
-
_context4.n =
|
|
39585
|
+
_context4.p = 26;
|
|
39586
|
+
_context4.n = 27;
|
|
39212
39587
|
return this.sdk.voiceSDK.stopRecording();
|
|
39213
|
-
case
|
|
39214
|
-
_context4.n =
|
|
39588
|
+
case 27:
|
|
39589
|
+
_context4.n = 29;
|
|
39215
39590
|
break;
|
|
39216
|
-
case
|
|
39217
|
-
_context4.p =
|
|
39218
|
-
|
|
39219
|
-
case
|
|
39591
|
+
case 28:
|
|
39592
|
+
_context4.p = 28;
|
|
39593
|
+
_t4 = _context4.v;
|
|
39594
|
+
case 29:
|
|
39220
39595
|
error = new Error('Connection lost - server may have rejected the call');
|
|
39221
39596
|
error.name = 'ServerRejected';
|
|
39222
39597
|
error.isServerRejection = true;
|
|
39223
39598
|
throw error;
|
|
39224
|
-
case
|
|
39599
|
+
case 30:
|
|
39225
39600
|
console.log('🎤 Started listening - permission granted');
|
|
39226
39601
|
this._stopPreliminaryInputStream();
|
|
39227
39602
|
this.isActive = true;
|
|
@@ -39244,19 +39619,19 @@ var VoiceInterface = /*#__PURE__*/function () {
|
|
|
39244
39619
|
this.startDesktopWaveformAnimation();
|
|
39245
39620
|
this.desktop.startLiveWaveformInterval();
|
|
39246
39621
|
}
|
|
39247
|
-
_context4.n =
|
|
39622
|
+
_context4.n = 33;
|
|
39248
39623
|
break;
|
|
39249
|
-
case
|
|
39250
|
-
_context4.p =
|
|
39251
|
-
|
|
39252
|
-
if (!(
|
|
39253
|
-
_context4.n =
|
|
39624
|
+
case 31:
|
|
39625
|
+
_context4.p = 31;
|
|
39626
|
+
_t5 = _context4.v;
|
|
39627
|
+
if (!(_t5.isServerRejection || _t5.name === 'ServerRejected')) {
|
|
39628
|
+
_context4.n = 32;
|
|
39254
39629
|
break;
|
|
39255
39630
|
}
|
|
39256
39631
|
this.resetConnectingState();
|
|
39257
|
-
throw
|
|
39258
|
-
case
|
|
39259
|
-
console.error('❌ Failed to start listening:',
|
|
39632
|
+
throw _t5;
|
|
39633
|
+
case 32:
|
|
39634
|
+
console.error('❌ Failed to start listening:', _t5);
|
|
39260
39635
|
this.resetConnectingState();
|
|
39261
39636
|
if (this.isMobile) {
|
|
39262
39637
|
_existingBar = document.getElementById('mobile-voice-call-bar-container');
|
|
@@ -39271,8 +39646,8 @@ var VoiceInterface = /*#__PURE__*/function () {
|
|
|
39271
39646
|
this.config.onDesktopMinimizedStripLauncherRestore();
|
|
39272
39647
|
} catch (_) {}
|
|
39273
39648
|
}
|
|
39274
|
-
throw
|
|
39275
|
-
case
|
|
39649
|
+
throw _t5;
|
|
39650
|
+
case 33:
|
|
39276
39651
|
// Start timer (desktop only - mobile bar owns its own timer)
|
|
39277
39652
|
if (!this.isMobile && !this.callStartTime) {
|
|
39278
39653
|
this.callStartTime = Date.now();
|
|
@@ -39291,14 +39666,14 @@ var VoiceInterface = /*#__PURE__*/function () {
|
|
|
39291
39666
|
}, 100);
|
|
39292
39667
|
}
|
|
39293
39668
|
console.log('✅ Voice call started successfully');
|
|
39294
|
-
_context4.n =
|
|
39669
|
+
_context4.n = 40;
|
|
39295
39670
|
break;
|
|
39296
|
-
case
|
|
39297
|
-
_context4.p =
|
|
39298
|
-
|
|
39299
|
-
isDisclaimerDeclined =
|
|
39300
|
-
if (!(
|
|
39301
|
-
console.error('❌ Error starting voice call:',
|
|
39671
|
+
case 34:
|
|
39672
|
+
_context4.p = 34;
|
|
39673
|
+
_t6 = _context4.v;
|
|
39674
|
+
isDisclaimerDeclined = _t6 && _t6.message === 'DISCLAIMER_DECLINED'; // Handle server rejection gracefully (don't log as error)
|
|
39675
|
+
if (!(_t6.isServerRejection || _t6.name === 'ServerRejected') && !isDisclaimerDeclined) {
|
|
39676
|
+
console.error('❌ Error starting voice call:', _t6);
|
|
39302
39677
|
}
|
|
39303
39678
|
this._stopPreliminaryInputStream();
|
|
39304
39679
|
|
|
@@ -39330,7 +39705,7 @@ var VoiceInterface = /*#__PURE__*/function () {
|
|
|
39330
39705
|
// User declined server disclaimer: full idle reset (not just resetConnectingState —
|
|
39331
39706
|
// connect path shows voiceActiveState on desktop; without hiding it, call UI stays visible).
|
|
39332
39707
|
if (!isDisclaimerDeclined) {
|
|
39333
|
-
_context4.n =
|
|
39708
|
+
_context4.n = 35;
|
|
39334
39709
|
break;
|
|
39335
39710
|
}
|
|
39336
39711
|
this.resetUIState();
|
|
@@ -39340,12 +39715,12 @@ var VoiceInterface = /*#__PURE__*/function () {
|
|
|
39340
39715
|
this.config.onCallEnd();
|
|
39341
39716
|
}
|
|
39342
39717
|
return _context4.a(2);
|
|
39343
|
-
case
|
|
39718
|
+
case 35:
|
|
39344
39719
|
this.resetConnectingState();
|
|
39345
39720
|
|
|
39346
39721
|
// Handle specific error types with appropriate modals
|
|
39347
|
-
if (!(
|
|
39348
|
-
_context4.n =
|
|
39722
|
+
if (!(_t6.name === 'NotAllowedError' || _t6.name === 'PermissionDeniedError')) {
|
|
39723
|
+
_context4.n = 36;
|
|
39349
39724
|
break;
|
|
39350
39725
|
}
|
|
39351
39726
|
// Permission denied - show blocked modal
|
|
@@ -39357,37 +39732,37 @@ var VoiceInterface = /*#__PURE__*/function () {
|
|
|
39357
39732
|
// User clicked refresh
|
|
39358
39733
|
window.location.reload();
|
|
39359
39734
|
});
|
|
39360
|
-
_context4.n =
|
|
39735
|
+
_context4.n = 40;
|
|
39361
39736
|
break;
|
|
39362
|
-
case
|
|
39363
|
-
if (!(
|
|
39364
|
-
_context4.n =
|
|
39737
|
+
case 36:
|
|
39738
|
+
if (!(_t6.name === 'NotFoundError' || _t6.name === 'DevicesNotFoundError')) {
|
|
39739
|
+
_context4.n = 37;
|
|
39365
39740
|
break;
|
|
39366
39741
|
}
|
|
39367
39742
|
// No microphone found - show no mic modal
|
|
39368
39743
|
(0,_shared_MicPermissionModals_js__WEBPACK_IMPORTED_MODULE_4__.showNoMicrophoneModal)(function () {
|
|
39369
39744
|
_this3.resetUIState();
|
|
39370
39745
|
});
|
|
39371
|
-
_context4.n =
|
|
39746
|
+
_context4.n = 40;
|
|
39372
39747
|
break;
|
|
39373
|
-
case
|
|
39374
|
-
if (!(
|
|
39375
|
-
_context4.n =
|
|
39748
|
+
case 37:
|
|
39749
|
+
if (!(_t6 && (_t6.message === 'DOMAIN_NOT_WHITELISTED' || _t6.message && _t6.message.includes('Domain not whitelisted')))) {
|
|
39750
|
+
_context4.n = 39;
|
|
39376
39751
|
break;
|
|
39377
39752
|
}
|
|
39378
|
-
_context4.n =
|
|
39753
|
+
_context4.n = 38;
|
|
39379
39754
|
return this.endCallOnServerRejection();
|
|
39380
|
-
case
|
|
39381
|
-
_context4.n =
|
|
39755
|
+
case 38:
|
|
39756
|
+
_context4.n = 40;
|
|
39382
39757
|
break;
|
|
39383
|
-
case
|
|
39758
|
+
case 39:
|
|
39384
39759
|
// Other errors - show in transcript
|
|
39385
|
-
this.showError(
|
|
39760
|
+
this.showError(_t6.message || _t6);
|
|
39386
39761
|
this.resetUIState();
|
|
39387
|
-
case
|
|
39762
|
+
case 40:
|
|
39388
39763
|
return _context4.a(2);
|
|
39389
39764
|
}
|
|
39390
|
-
}, _callee4, this, [[
|
|
39765
|
+
}, _callee4, this, [[26, 28], [24, 31], [16, 18], [15, 23], [2, 4], [0, 34]]);
|
|
39391
39766
|
}));
|
|
39392
39767
|
function proceedWithVoiceCall() {
|
|
39393
39768
|
return _proceedWithVoiceCall.apply(this, arguments);
|
|
@@ -39451,7 +39826,7 @@ var VoiceInterface = /*#__PURE__*/function () {
|
|
|
39451
39826
|
key: "endCallOnServerRejection",
|
|
39452
39827
|
value: (function () {
|
|
39453
39828
|
var _endCallOnServerRejection = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee5() {
|
|
39454
|
-
var voiceInterfaceEl, landingScreen, _this$sdk$voiceSDK2, _this$sdk$voiceSDK3, audioRecorder, isRecording, _this$sdk$voiceSDK4, activeState, idleState, floatingButton, fallbackButton, mobileFabEnd, errorMsg,
|
|
39829
|
+
var voiceInterfaceEl, landingScreen, _this$sdk$voiceSDK2, _this$sdk$voiceSDK3, audioRecorder, isRecording, _this$sdk$voiceSDK4, activeState, idleState, floatingButton, fallbackButton, mobileFabEnd, errorMsg, _t7, _t8, _t9, _t0, _t1;
|
|
39455
39830
|
return _regenerator().w(function (_context5) {
|
|
39456
39831
|
while (1) switch (_context5.p = _context5.n) {
|
|
39457
39832
|
case 0:
|
|
@@ -39513,8 +39888,8 @@ var VoiceInterface = /*#__PURE__*/function () {
|
|
|
39513
39888
|
break;
|
|
39514
39889
|
case 4:
|
|
39515
39890
|
_context5.p = 4;
|
|
39516
|
-
|
|
39517
|
-
console.warn('Error sending stop message to AudioWorklet:',
|
|
39891
|
+
_t7 = _context5.v;
|
|
39892
|
+
console.warn('Error sending stop message to AudioWorklet:', _t7);
|
|
39518
39893
|
case 5:
|
|
39519
39894
|
if (!(this.sdk.voiceSDK && typeof this.sdk.voiceSDK.stopRecording === 'function')) {
|
|
39520
39895
|
_context5.n = 10;
|
|
@@ -39529,8 +39904,8 @@ var VoiceInterface = /*#__PURE__*/function () {
|
|
|
39529
39904
|
break;
|
|
39530
39905
|
case 8:
|
|
39531
39906
|
_context5.p = 8;
|
|
39532
|
-
|
|
39533
|
-
console.warn('Error calling stopRecording:',
|
|
39907
|
+
_t8 = _context5.v;
|
|
39908
|
+
console.warn('Error calling stopRecording:', _t8);
|
|
39534
39909
|
case 9:
|
|
39535
39910
|
_context5.n = 14;
|
|
39536
39911
|
break;
|
|
@@ -39550,8 +39925,8 @@ var VoiceInterface = /*#__PURE__*/function () {
|
|
|
39550
39925
|
break;
|
|
39551
39926
|
case 13:
|
|
39552
39927
|
_context5.p = 13;
|
|
39553
|
-
|
|
39554
|
-
console.warn('Error calling stopListening:',
|
|
39928
|
+
_t9 = _context5.v;
|
|
39929
|
+
console.warn('Error calling stopListening:', _t9);
|
|
39555
39930
|
case 14:
|
|
39556
39931
|
if (!(audioRecorder && typeof audioRecorder.stop === 'function')) {
|
|
39557
39932
|
_context5.n = 18;
|
|
@@ -39566,8 +39941,8 @@ var VoiceInterface = /*#__PURE__*/function () {
|
|
|
39566
39941
|
break;
|
|
39567
39942
|
case 17:
|
|
39568
39943
|
_context5.p = 17;
|
|
39569
|
-
|
|
39570
|
-
console.warn('Error calling AudioRecorder.stop():',
|
|
39944
|
+
_t0 = _context5.v;
|
|
39945
|
+
console.warn('Error calling AudioRecorder.stop():', _t0);
|
|
39571
39946
|
case 18:
|
|
39572
39947
|
console.log('✅ Audio capture/VAD stopped');
|
|
39573
39948
|
case 19:
|
|
@@ -39599,8 +39974,8 @@ var VoiceInterface = /*#__PURE__*/function () {
|
|
|
39599
39974
|
break;
|
|
39600
39975
|
case 20:
|
|
39601
39976
|
_context5.p = 20;
|
|
39602
|
-
|
|
39603
|
-
console.warn('Error stopping listening on server rejection:',
|
|
39977
|
+
_t1 = _context5.v;
|
|
39978
|
+
console.warn('Error stopping listening on server rejection:', _t1);
|
|
39604
39979
|
// Force stop media streams even if stopListening fails
|
|
39605
39980
|
try {
|
|
39606
39981
|
if ((_this$sdk$voiceSDK4 = this.sdk.voiceSDK) !== null && _this$sdk$voiceSDK4 !== void 0 && (_this$sdk$voiceSDK4 = _this$sdk$voiceSDK4.audioRecorder) !== null && _this$sdk$voiceSDK4 !== void 0 && _this$sdk$voiceSDK4.mediaStream) {
|
|
@@ -41037,6 +41412,829 @@ function createGalleryHandler(widget) {
|
|
|
41037
41412
|
|
|
41038
41413
|
/***/ }),
|
|
41039
41414
|
|
|
41415
|
+
/***/ "./src/widget/markdown.js":
|
|
41416
|
+
/*!********************************!*\
|
|
41417
|
+
!*** ./src/widget/markdown.js ***!
|
|
41418
|
+
\********************************/
|
|
41419
|
+
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
41420
|
+
|
|
41421
|
+
"use strict";
|
|
41422
|
+
__webpack_require__.r(__webpack_exports__);
|
|
41423
|
+
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
41424
|
+
/* harmony export */ parseInline: () => (/* binding */ parseInline),
|
|
41425
|
+
/* harmony export */ parseMarkdown: () => (/* binding */ parseMarkdown),
|
|
41426
|
+
/* harmony export */ renderMarkdownInto: () => (/* binding */ renderMarkdownInto),
|
|
41427
|
+
/* harmony export */ safeHref: () => (/* binding */ safeHref)
|
|
41428
|
+
/* harmony export */ });
|
|
41429
|
+
function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
|
|
41430
|
+
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
|
|
41431
|
+
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
41432
|
+
/**
|
|
41433
|
+
* markdown.js — tiny, dependency-free Markdown renderer for chat bubbles.
|
|
41434
|
+
*
|
|
41435
|
+
* Split in two halves on purpose:
|
|
41436
|
+
* parseMarkdown(text) -> block AST — pure JS, unit-tested in scripts/markdown.test.mjs
|
|
41437
|
+
* renderMarkdownInto(el, text) — walks the AST and builds real DOM nodes
|
|
41438
|
+
*
|
|
41439
|
+
* XSS: content is only ever placed with document.createTextNode / element
|
|
41440
|
+
* properties. Nothing is written through innerHTML, and link hrefs go through
|
|
41441
|
+
* a scheme allowlist (safeHref), so agent text can never inject markup.
|
|
41442
|
+
*
|
|
41443
|
+
* Streaming: the parser is total — an unterminated code fence, a half-written
|
|
41444
|
+
* bold run or a truncated table never throw, they just degrade to text. That
|
|
41445
|
+
* lets the caller re-render the whole accumulated buffer on every token.
|
|
41446
|
+
*/
|
|
41447
|
+
|
|
41448
|
+
/* ------------------------------------------------------------------ */
|
|
41449
|
+
/* Block parsing */
|
|
41450
|
+
/* ------------------------------------------------------------------ */
|
|
41451
|
+
|
|
41452
|
+
var FENCE_RE = /^(\s*)(`{3,}|~{3,})\s*([^\s`]*)\s*$/;
|
|
41453
|
+
var HEADING_RE = /^(\s{0,3})(#{1,6})\s+(.*)$/;
|
|
41454
|
+
var HR_RE = /^\s{0,3}([-*_])[ \t]*(?:\1[ \t]*){2,}$/;
|
|
41455
|
+
var QUOTE_RE = /^\s{0,3}>\s?(.*)$/;
|
|
41456
|
+
var LIST_RE = /^(\s*)(?:([-*+•])|(\d{1,9})[.)])([ \t]+)(.*)$/;
|
|
41457
|
+
var TABLE_SEP_RE = /^\s*\|?[\s:|-]*-[\s:|-]*\|?\s*$/;
|
|
41458
|
+
function isBlank(line) {
|
|
41459
|
+
return !line || /^\s*$/.test(line);
|
|
41460
|
+
}
|
|
41461
|
+
function indentOf(line) {
|
|
41462
|
+
var m = /^[ \t]*/.exec(line)[0];
|
|
41463
|
+
// treat a tab as two columns — LLMs mix tabs and spaces freely
|
|
41464
|
+
return m.replace(/\t/g, ' ').length;
|
|
41465
|
+
}
|
|
41466
|
+
function matchListItem(line) {
|
|
41467
|
+
var m = LIST_RE.exec(line);
|
|
41468
|
+
if (!m) return null;
|
|
41469
|
+
var indent = indentOf(line);
|
|
41470
|
+
var markerLen = m[2] ? 1 : m[3].length + 1;
|
|
41471
|
+
return {
|
|
41472
|
+
indent: indent,
|
|
41473
|
+
ordered: !!m[3],
|
|
41474
|
+
start: m[3] ? parseInt(m[3], 10) : null,
|
|
41475
|
+
contentIndent: indent + markerLen + m[4].replace(/\t/g, ' ').length,
|
|
41476
|
+
text: m[5]
|
|
41477
|
+
};
|
|
41478
|
+
}
|
|
41479
|
+
|
|
41480
|
+
/** True when the line opens a block that must interrupt an open paragraph. */
|
|
41481
|
+
function startsBlock(line) {
|
|
41482
|
+
return FENCE_RE.test(line) || HEADING_RE.test(line) || HR_RE.test(line) || QUOTE_RE.test(line) || matchListItem(line) !== null;
|
|
41483
|
+
}
|
|
41484
|
+
function dedent(line, columns) {
|
|
41485
|
+
var seen = 0;
|
|
41486
|
+
var i = 0;
|
|
41487
|
+
while (i < line.length && seen < columns) {
|
|
41488
|
+
var c = line[i];
|
|
41489
|
+
if (c === ' ') seen += 1;else if (c === '\t') seen += 2;else break;
|
|
41490
|
+
i++;
|
|
41491
|
+
}
|
|
41492
|
+
return line.slice(i);
|
|
41493
|
+
}
|
|
41494
|
+
function splitTableRow(line) {
|
|
41495
|
+
var s = line.trim();
|
|
41496
|
+
if (s.startsWith('|')) s = s.slice(1);
|
|
41497
|
+
if (s.endsWith('|') && !s.endsWith('\\|')) s = s.slice(0, -1);
|
|
41498
|
+
var cells = [];
|
|
41499
|
+
var cur = '';
|
|
41500
|
+
for (var i = 0; i < s.length; i++) {
|
|
41501
|
+
if (s[i] === '\\' && s[i + 1] === '|') {
|
|
41502
|
+
cur += '|';
|
|
41503
|
+
i++;
|
|
41504
|
+
} else if (s[i] === '|') {
|
|
41505
|
+
cells.push(cur.trim());
|
|
41506
|
+
cur = '';
|
|
41507
|
+
} else {
|
|
41508
|
+
cur += s[i];
|
|
41509
|
+
}
|
|
41510
|
+
}
|
|
41511
|
+
cells.push(cur.trim());
|
|
41512
|
+
return cells;
|
|
41513
|
+
}
|
|
41514
|
+
function parseAlignment(sepLine) {
|
|
41515
|
+
return splitTableRow(sepLine).map(function (c) {
|
|
41516
|
+
var left = c.startsWith(':');
|
|
41517
|
+
var right = c.endsWith(':');
|
|
41518
|
+
if (left && right) return 'center';
|
|
41519
|
+
if (right) return 'right';
|
|
41520
|
+
if (left) return 'left';
|
|
41521
|
+
return null;
|
|
41522
|
+
});
|
|
41523
|
+
}
|
|
41524
|
+
function parseFence(lines, i) {
|
|
41525
|
+
var m = FENCE_RE.exec(lines[i]);
|
|
41526
|
+
var marker = m[2][0];
|
|
41527
|
+
var minLen = m[2].length;
|
|
41528
|
+
var stripIndent = m[1].length;
|
|
41529
|
+
var body = [];
|
|
41530
|
+
var j = i + 1;
|
|
41531
|
+
for (; j < lines.length; j++) {
|
|
41532
|
+
var close = FENCE_RE.exec(lines[j]);
|
|
41533
|
+
if (close && close[2][0] === marker && close[2].length >= minLen && !close[3]) {
|
|
41534
|
+
j++;
|
|
41535
|
+
break;
|
|
41536
|
+
}
|
|
41537
|
+
body.push(dedent(lines[j], stripIndent));
|
|
41538
|
+
}
|
|
41539
|
+
// an unterminated fence (mid-stream) still yields a code block
|
|
41540
|
+
return {
|
|
41541
|
+
node: {
|
|
41542
|
+
type: 'code',
|
|
41543
|
+
lang: m[3] || '',
|
|
41544
|
+
text: body.join('\n')
|
|
41545
|
+
},
|
|
41546
|
+
next: j
|
|
41547
|
+
};
|
|
41548
|
+
}
|
|
41549
|
+
function parseQuote(lines, i) {
|
|
41550
|
+
var body = [];
|
|
41551
|
+
var j = i;
|
|
41552
|
+
for (; j < lines.length; j++) {
|
|
41553
|
+
var m = QUOTE_RE.exec(lines[j]);
|
|
41554
|
+
if (m) {
|
|
41555
|
+
body.push(m[1]);
|
|
41556
|
+
continue;
|
|
41557
|
+
}
|
|
41558
|
+
// lazy continuation: plain text directly under a quote line
|
|
41559
|
+
if (!isBlank(lines[j]) && !startsBlock(lines[j]) && body.length && !isBlank(body[body.length - 1])) {
|
|
41560
|
+
body.push(lines[j].trim());
|
|
41561
|
+
continue;
|
|
41562
|
+
}
|
|
41563
|
+
break;
|
|
41564
|
+
}
|
|
41565
|
+
return {
|
|
41566
|
+
node: {
|
|
41567
|
+
type: 'quote',
|
|
41568
|
+
blocks: parseBlocks(body)
|
|
41569
|
+
},
|
|
41570
|
+
next: j
|
|
41571
|
+
};
|
|
41572
|
+
}
|
|
41573
|
+
function parseTable(lines, i) {
|
|
41574
|
+
var head = splitTableRow(lines[i]);
|
|
41575
|
+
var align = parseAlignment(lines[i + 1]);
|
|
41576
|
+
var rows = [];
|
|
41577
|
+
var j = i + 2;
|
|
41578
|
+
for (; j < lines.length; j++) {
|
|
41579
|
+
if (isBlank(lines[j]) || lines[j].indexOf('|') === -1) break;
|
|
41580
|
+
var cells = splitTableRow(lines[j]);
|
|
41581
|
+
while (cells.length < head.length) cells.push('');
|
|
41582
|
+
rows.push(cells.slice(0, head.length).map(parseInline));
|
|
41583
|
+
}
|
|
41584
|
+
return {
|
|
41585
|
+
node: {
|
|
41586
|
+
type: 'table',
|
|
41587
|
+
align: align,
|
|
41588
|
+
head: head.map(parseInline),
|
|
41589
|
+
rows: rows
|
|
41590
|
+
},
|
|
41591
|
+
next: j
|
|
41592
|
+
};
|
|
41593
|
+
}
|
|
41594
|
+
function parseList(lines, i) {
|
|
41595
|
+
var first = matchListItem(lines[i]);
|
|
41596
|
+
var baseIndent = first.indent;
|
|
41597
|
+
var ordered = first.ordered;
|
|
41598
|
+
var items = [];
|
|
41599
|
+
var cur = null;
|
|
41600
|
+
var j = i;
|
|
41601
|
+
while (j < lines.length) {
|
|
41602
|
+
var line = lines[j];
|
|
41603
|
+
if (isBlank(line)) {
|
|
41604
|
+
var k = j + 1;
|
|
41605
|
+
while (k < lines.length && isBlank(lines[k])) k++;
|
|
41606
|
+
if (k >= lines.length) break;
|
|
41607
|
+
var nextItem = matchListItem(lines[k]);
|
|
41608
|
+
var belongs = nextItem && nextItem.indent >= baseIndent && nextItem.ordered === ordered || indentOf(lines[k]) > baseIndent;
|
|
41609
|
+
if (!belongs) break;
|
|
41610
|
+
if (cur) cur.lines.push('');
|
|
41611
|
+
j = k;
|
|
41612
|
+
continue;
|
|
41613
|
+
}
|
|
41614
|
+
var item = matchListItem(line);
|
|
41615
|
+
if (item && item.indent <= baseIndent) {
|
|
41616
|
+
// a sibling item — or a different list starting at the same level
|
|
41617
|
+
if (item.indent < baseIndent || item.ordered !== ordered) break;
|
|
41618
|
+
cur = {
|
|
41619
|
+
lines: [item.text],
|
|
41620
|
+
contentIndent: item.contentIndent
|
|
41621
|
+
};
|
|
41622
|
+
items.push(cur);
|
|
41623
|
+
j++;
|
|
41624
|
+
continue;
|
|
41625
|
+
}
|
|
41626
|
+
if (!cur) break;
|
|
41627
|
+
|
|
41628
|
+
// nested item or indented continuation
|
|
41629
|
+
if (indentOf(line) > baseIndent) {
|
|
41630
|
+
cur.lines.push(dedent(line, cur.contentIndent));
|
|
41631
|
+
j++;
|
|
41632
|
+
continue;
|
|
41633
|
+
}
|
|
41634
|
+
|
|
41635
|
+
// lazy continuation of the current item's paragraph
|
|
41636
|
+
if (startsBlock(line)) break;
|
|
41637
|
+
cur.lines.push(line.trim());
|
|
41638
|
+
j++;
|
|
41639
|
+
}
|
|
41640
|
+
return {
|
|
41641
|
+
node: {
|
|
41642
|
+
type: ordered ? 'ol' : 'ul',
|
|
41643
|
+
start: ordered && first.start !== 1 ? first.start : null,
|
|
41644
|
+
items: items.map(function (it) {
|
|
41645
|
+
return {
|
|
41646
|
+
blocks: parseBlocks(it.lines)
|
|
41647
|
+
};
|
|
41648
|
+
})
|
|
41649
|
+
},
|
|
41650
|
+
next: j
|
|
41651
|
+
};
|
|
41652
|
+
}
|
|
41653
|
+
function parseParagraph(lines, i) {
|
|
41654
|
+
var body = [];
|
|
41655
|
+
var j = i;
|
|
41656
|
+
for (; j < lines.length; j++) {
|
|
41657
|
+
if (isBlank(lines[j])) break;
|
|
41658
|
+
if (j > i && startsBlock(lines[j])) break;
|
|
41659
|
+
if (j > i && lines[j].indexOf('|') !== -1 && j + 1 < lines.length && TABLE_SEP_RE.test(lines[j + 1])) {
|
|
41660
|
+
break;
|
|
41661
|
+
}
|
|
41662
|
+
body.push(lines[j].trim());
|
|
41663
|
+
}
|
|
41664
|
+
return {
|
|
41665
|
+
node: {
|
|
41666
|
+
type: 'p',
|
|
41667
|
+
inline: parseInline(body.join('\n'))
|
|
41668
|
+
},
|
|
41669
|
+
next: j
|
|
41670
|
+
};
|
|
41671
|
+
}
|
|
41672
|
+
|
|
41673
|
+
/**
|
|
41674
|
+
* Parse markdown source into a block AST.
|
|
41675
|
+
* @param {string} src
|
|
41676
|
+
* @returns {Array<object>} block nodes
|
|
41677
|
+
*/
|
|
41678
|
+
function parseMarkdown(src) {
|
|
41679
|
+
if (typeof src !== 'string' || src === '') return [];
|
|
41680
|
+
return parseBlocks(src.replace(/\r\n?/g, '\n').split('\n'));
|
|
41681
|
+
}
|
|
41682
|
+
function parseBlocks(lines) {
|
|
41683
|
+
var blocks = [];
|
|
41684
|
+
var i = 0;
|
|
41685
|
+
while (i < lines.length) {
|
|
41686
|
+
var line = lines[i];
|
|
41687
|
+
if (isBlank(line)) {
|
|
41688
|
+
i++;
|
|
41689
|
+
continue;
|
|
41690
|
+
}
|
|
41691
|
+
if (FENCE_RE.test(line)) {
|
|
41692
|
+
var r = parseFence(lines, i);
|
|
41693
|
+
blocks.push(r.node);
|
|
41694
|
+
i = r.next;
|
|
41695
|
+
continue;
|
|
41696
|
+
}
|
|
41697
|
+
if (HR_RE.test(line)) {
|
|
41698
|
+
blocks.push({
|
|
41699
|
+
type: 'hr'
|
|
41700
|
+
});
|
|
41701
|
+
i++;
|
|
41702
|
+
continue;
|
|
41703
|
+
}
|
|
41704
|
+
var heading = HEADING_RE.exec(line);
|
|
41705
|
+
if (heading) {
|
|
41706
|
+
var text = heading[3].replace(/\s+#+\s*$/, '');
|
|
41707
|
+
blocks.push({
|
|
41708
|
+
type: 'h',
|
|
41709
|
+
level: heading[2].length,
|
|
41710
|
+
inline: parseInline(text)
|
|
41711
|
+
});
|
|
41712
|
+
i++;
|
|
41713
|
+
continue;
|
|
41714
|
+
}
|
|
41715
|
+
if (QUOTE_RE.test(line)) {
|
|
41716
|
+
var _r = parseQuote(lines, i);
|
|
41717
|
+
blocks.push(_r.node);
|
|
41718
|
+
i = _r.next;
|
|
41719
|
+
continue;
|
|
41720
|
+
}
|
|
41721
|
+
if (matchListItem(line)) {
|
|
41722
|
+
var _r2 = parseList(lines, i);
|
|
41723
|
+
// defensive: parseList always consumes at least one line
|
|
41724
|
+
if (_r2.next <= i) {
|
|
41725
|
+
blocks.push({
|
|
41726
|
+
type: 'p',
|
|
41727
|
+
inline: parseInline(line.trim())
|
|
41728
|
+
});
|
|
41729
|
+
i++;
|
|
41730
|
+
continue;
|
|
41731
|
+
}
|
|
41732
|
+
blocks.push(_r2.node);
|
|
41733
|
+
i = _r2.next;
|
|
41734
|
+
continue;
|
|
41735
|
+
}
|
|
41736
|
+
if (line.indexOf('|') !== -1 && i + 1 < lines.length && TABLE_SEP_RE.test(lines[i + 1])) {
|
|
41737
|
+
var _r3 = parseTable(lines, i);
|
|
41738
|
+
blocks.push(_r3.node);
|
|
41739
|
+
i = _r3.next;
|
|
41740
|
+
continue;
|
|
41741
|
+
}
|
|
41742
|
+
var p = parseParagraph(lines, i);
|
|
41743
|
+
if (p.next <= i) {
|
|
41744
|
+
i++;
|
|
41745
|
+
continue;
|
|
41746
|
+
}
|
|
41747
|
+
blocks.push(p.node);
|
|
41748
|
+
i = p.next;
|
|
41749
|
+
}
|
|
41750
|
+
return blocks;
|
|
41751
|
+
}
|
|
41752
|
+
|
|
41753
|
+
/* ------------------------------------------------------------------ */
|
|
41754
|
+
/* Inline parsing */
|
|
41755
|
+
/* ------------------------------------------------------------------ */
|
|
41756
|
+
|
|
41757
|
+
var ESCAPABLE = '\\`*_~[]()#+-.!>|';
|
|
41758
|
+
function matchLink(text, start) {
|
|
41759
|
+
var depth = 0;
|
|
41760
|
+
var j = start;
|
|
41761
|
+
for (; j < text.length; j++) {
|
|
41762
|
+
var ch = text[j];
|
|
41763
|
+
if (ch === '\\') {
|
|
41764
|
+
j++;
|
|
41765
|
+
continue;
|
|
41766
|
+
}
|
|
41767
|
+
if (ch === '\n') return null;
|
|
41768
|
+
if (ch === '[') depth++;else if (ch === ']') {
|
|
41769
|
+
depth--;
|
|
41770
|
+
if (depth === 0) break;
|
|
41771
|
+
}
|
|
41772
|
+
}
|
|
41773
|
+
if (j >= text.length || text[j] !== ']' || text[j + 1] !== '(') return null;
|
|
41774
|
+
var label = text.slice(start + 1, j);
|
|
41775
|
+
var k = j + 2;
|
|
41776
|
+
var pdepth = 1;
|
|
41777
|
+
var dest = '';
|
|
41778
|
+
for (; k < text.length; k++) {
|
|
41779
|
+
var _ch = text[k];
|
|
41780
|
+
if (_ch === '\\') {
|
|
41781
|
+
dest += text[k + 1] || '';
|
|
41782
|
+
k++;
|
|
41783
|
+
continue;
|
|
41784
|
+
}
|
|
41785
|
+
if (_ch === '\n') return null;
|
|
41786
|
+
if (_ch === '(') pdepth++;else if (_ch === ')') {
|
|
41787
|
+
pdepth--;
|
|
41788
|
+
if (pdepth === 0) break;
|
|
41789
|
+
}
|
|
41790
|
+
dest += _ch;
|
|
41791
|
+
}
|
|
41792
|
+
if (k >= text.length || pdepth !== 0) return null;
|
|
41793
|
+
dest = dest.trim();
|
|
41794
|
+
// strip an optional title: (/url "Title")
|
|
41795
|
+
var sp = dest.search(/\s/);
|
|
41796
|
+
var href = sp === -1 ? dest : dest.slice(0, sp);
|
|
41797
|
+
return {
|
|
41798
|
+
label: label,
|
|
41799
|
+
href: href,
|
|
41800
|
+
end: k + 1
|
|
41801
|
+
};
|
|
41802
|
+
}
|
|
41803
|
+
|
|
41804
|
+
/** Length of the run of identical delimiter chars starting at `i`. */
|
|
41805
|
+
function runLength(text, i) {
|
|
41806
|
+
var c = text[i];
|
|
41807
|
+
var n = 0;
|
|
41808
|
+
while (i + n < text.length && text[i + n] === c) n++;
|
|
41809
|
+
return n;
|
|
41810
|
+
}
|
|
41811
|
+
function matchEmphasis(text, start) {
|
|
41812
|
+
var c = text[start];
|
|
41813
|
+
var openRun = runLength(text, start);
|
|
41814
|
+
if (c === '~') {
|
|
41815
|
+
// only ~~strike~~
|
|
41816
|
+
if (openRun < 2) return null;
|
|
41817
|
+
return matchDelimited(text, start, '~~', 'del');
|
|
41818
|
+
}
|
|
41819
|
+
|
|
41820
|
+
// ***both*** — strong wrapping the inner single-delimiter run
|
|
41821
|
+
if (openRun >= 3) {
|
|
41822
|
+
var triple = c.repeat(3);
|
|
41823
|
+
var close = text.indexOf(triple, start + openRun);
|
|
41824
|
+
if (close === -1) return null;
|
|
41825
|
+
return {
|
|
41826
|
+
tag: 'strong',
|
|
41827
|
+
content: c + text.slice(start + 3, close) + c,
|
|
41828
|
+
end: close + 3
|
|
41829
|
+
};
|
|
41830
|
+
}
|
|
41831
|
+
if (c === '_') {
|
|
41832
|
+
var before = start > 0 ? text[start - 1] : '';
|
|
41833
|
+
if (before && /\w/.test(before)) return null; // snake_case
|
|
41834
|
+
}
|
|
41835
|
+
return openRun === 2 ? matchDelimited(text, start, c + c, 'strong') : matchDelimited(text, start, c, 'em');
|
|
41836
|
+
}
|
|
41837
|
+
function matchDelimited(text, start, delim, tag) {
|
|
41838
|
+
var c = delim[0];
|
|
41839
|
+
var single = delim.length === 1;
|
|
41840
|
+
var after = text[start + delim.length];
|
|
41841
|
+
if (after === undefined || /\s/.test(after)) return null;
|
|
41842
|
+
var j = start + delim.length;
|
|
41843
|
+
while (j < text.length) {
|
|
41844
|
+
var k = text.indexOf(delim, j);
|
|
41845
|
+
if (k === -1) return null;
|
|
41846
|
+
if (k === start + delim.length) return null; // empty content
|
|
41847
|
+
|
|
41848
|
+
if (/\s/.test(text[k - 1])) {
|
|
41849
|
+
j = k + delim.length;
|
|
41850
|
+
continue;
|
|
41851
|
+
}
|
|
41852
|
+
|
|
41853
|
+
// a single-char delimiter must not latch onto part of a longer run
|
|
41854
|
+
// ("*a **b** c*" — the closer is the final *, not the one in "**")
|
|
41855
|
+
if (single && (text[k - 1] === c || text[k + 1] === c)) {
|
|
41856
|
+
var end = k;
|
|
41857
|
+
while (end < text.length && text[end] === c) end++;
|
|
41858
|
+
j = end;
|
|
41859
|
+
continue;
|
|
41860
|
+
}
|
|
41861
|
+
if (c === '_') {
|
|
41862
|
+
var next = text[k + delim.length];
|
|
41863
|
+
if (next && /\w/.test(next)) {
|
|
41864
|
+
j = k + delim.length;
|
|
41865
|
+
continue;
|
|
41866
|
+
}
|
|
41867
|
+
}
|
|
41868
|
+
return {
|
|
41869
|
+
tag: tag,
|
|
41870
|
+
content: text.slice(start + delim.length, k),
|
|
41871
|
+
end: k + delim.length
|
|
41872
|
+
};
|
|
41873
|
+
}
|
|
41874
|
+
return null;
|
|
41875
|
+
}
|
|
41876
|
+
|
|
41877
|
+
/**
|
|
41878
|
+
* Parse a run of inline markdown into inline nodes.
|
|
41879
|
+
* @param {string} text
|
|
41880
|
+
* @returns {Array<object>}
|
|
41881
|
+
*/
|
|
41882
|
+
function parseInline(text) {
|
|
41883
|
+
var out = [];
|
|
41884
|
+
var buf = '';
|
|
41885
|
+
var flush = function flush() {
|
|
41886
|
+
if (buf) {
|
|
41887
|
+
out.push({
|
|
41888
|
+
type: 'text',
|
|
41889
|
+
value: buf
|
|
41890
|
+
});
|
|
41891
|
+
buf = '';
|
|
41892
|
+
}
|
|
41893
|
+
};
|
|
41894
|
+
var i = 0;
|
|
41895
|
+
while (i < text.length) {
|
|
41896
|
+
var c = text[i];
|
|
41897
|
+
if (c === '\\' && i + 1 < text.length && ESCAPABLE.indexOf(text[i + 1]) !== -1) {
|
|
41898
|
+
buf += text[i + 1];
|
|
41899
|
+
i += 2;
|
|
41900
|
+
continue;
|
|
41901
|
+
}
|
|
41902
|
+
if (c === '\n') {
|
|
41903
|
+
flush();
|
|
41904
|
+
out.push({
|
|
41905
|
+
type: 'br'
|
|
41906
|
+
});
|
|
41907
|
+
i++;
|
|
41908
|
+
continue;
|
|
41909
|
+
}
|
|
41910
|
+
if (c === '`') {
|
|
41911
|
+
var m = /^(`+)([\s\S]*?)\1(?!`)/.exec(text.slice(i));
|
|
41912
|
+
if (m && m[2].trim()) {
|
|
41913
|
+
flush();
|
|
41914
|
+
out.push({
|
|
41915
|
+
type: 'code',
|
|
41916
|
+
value: m[2].replace(/^ | $/g, '')
|
|
41917
|
+
});
|
|
41918
|
+
i += m[0].length;
|
|
41919
|
+
continue;
|
|
41920
|
+
}
|
|
41921
|
+
}
|
|
41922
|
+
if (c === '!' && text[i + 1] === '[') {
|
|
41923
|
+
var img = matchLink(text, i + 1);
|
|
41924
|
+
if (img) {
|
|
41925
|
+
flush();
|
|
41926
|
+
out.push({
|
|
41927
|
+
type: 'image',
|
|
41928
|
+
src: img.href,
|
|
41929
|
+
alt: img.label
|
|
41930
|
+
});
|
|
41931
|
+
i = img.end;
|
|
41932
|
+
continue;
|
|
41933
|
+
}
|
|
41934
|
+
}
|
|
41935
|
+
if (c === '[') {
|
|
41936
|
+
var link = matchLink(text, i);
|
|
41937
|
+
if (link) {
|
|
41938
|
+
flush();
|
|
41939
|
+
out.push({
|
|
41940
|
+
type: 'link',
|
|
41941
|
+
href: link.href,
|
|
41942
|
+
children: parseInline(link.label)
|
|
41943
|
+
});
|
|
41944
|
+
i = link.end;
|
|
41945
|
+
continue;
|
|
41946
|
+
}
|
|
41947
|
+
}
|
|
41948
|
+
if (c === '*' || c === '_' || c === '~') {
|
|
41949
|
+
var em = matchEmphasis(text, i);
|
|
41950
|
+
if (em) {
|
|
41951
|
+
flush();
|
|
41952
|
+
out.push({
|
|
41953
|
+
type: em.tag,
|
|
41954
|
+
children: parseInline(em.content)
|
|
41955
|
+
});
|
|
41956
|
+
i = em.end;
|
|
41957
|
+
continue;
|
|
41958
|
+
}
|
|
41959
|
+
}
|
|
41960
|
+
if ((c === 'h' || c === 'w') && /^(https?:\/\/|www\.)/.test(text.slice(i))) {
|
|
41961
|
+
var _m = /^(?:https?:\/\/|www\.)[^\s<>"'`\]]+/.exec(text.slice(i));
|
|
41962
|
+
if (_m) {
|
|
41963
|
+
var raw = _m[0].replace(/[.,;:!?)\]]+$/, '');
|
|
41964
|
+
flush();
|
|
41965
|
+
out.push({
|
|
41966
|
+
type: 'link',
|
|
41967
|
+
href: raw.startsWith('www.') ? "https://".concat(raw) : raw,
|
|
41968
|
+
children: [{
|
|
41969
|
+
type: 'text',
|
|
41970
|
+
value: raw
|
|
41971
|
+
}]
|
|
41972
|
+
});
|
|
41973
|
+
i += raw.length;
|
|
41974
|
+
continue;
|
|
41975
|
+
}
|
|
41976
|
+
}
|
|
41977
|
+
buf += c;
|
|
41978
|
+
i++;
|
|
41979
|
+
}
|
|
41980
|
+
flush();
|
|
41981
|
+
return out;
|
|
41982
|
+
}
|
|
41983
|
+
|
|
41984
|
+
/* ------------------------------------------------------------------ */
|
|
41985
|
+
/* URL safety */
|
|
41986
|
+
/* ------------------------------------------------------------------ */
|
|
41987
|
+
|
|
41988
|
+
var SAFE_SCHEME = /^(https?|mailto|tel):/i;
|
|
41989
|
+
|
|
41990
|
+
/**
|
|
41991
|
+
* Returns the href if it is safe to put on an anchor, otherwise null.
|
|
41992
|
+
* Blocks javascript:, data:, vbscript: and anything else exotic.
|
|
41993
|
+
*/
|
|
41994
|
+
function safeHref(href) {
|
|
41995
|
+
if (typeof href !== 'string') return null;
|
|
41996
|
+
var s = href.trim();
|
|
41997
|
+
if (!s) return null;
|
|
41998
|
+
// control characters are used to smuggle "java\nscript:"
|
|
41999
|
+
var clean = s.replace(/[-\s]/g, '');
|
|
42000
|
+
if (/^(\/|#|\.\/|\.\.\/)/.test(clean)) return s; // relative
|
|
42001
|
+
if (SAFE_SCHEME.test(clean)) return s;
|
|
42002
|
+
if (clean.indexOf(':') === -1) return s; // bare host / path
|
|
42003
|
+
return null;
|
|
42004
|
+
}
|
|
42005
|
+
|
|
42006
|
+
/* ------------------------------------------------------------------ */
|
|
42007
|
+
/* DOM rendering */
|
|
42008
|
+
/* ------------------------------------------------------------------ */
|
|
42009
|
+
|
|
42010
|
+
function renderInlineNodes(nodes, parent, doc) {
|
|
42011
|
+
var _iterator = _createForOfIteratorHelper(nodes),
|
|
42012
|
+
_step;
|
|
42013
|
+
try {
|
|
42014
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
42015
|
+
var node = _step.value;
|
|
42016
|
+
switch (node.type) {
|
|
42017
|
+
case 'text':
|
|
42018
|
+
parent.appendChild(doc.createTextNode(node.value));
|
|
42019
|
+
break;
|
|
42020
|
+
case 'br':
|
|
42021
|
+
parent.appendChild(doc.createElement('br'));
|
|
42022
|
+
break;
|
|
42023
|
+
case 'code':
|
|
42024
|
+
{
|
|
42025
|
+
var el = doc.createElement('code');
|
|
42026
|
+
el.textContent = node.value;
|
|
42027
|
+
parent.appendChild(el);
|
|
42028
|
+
break;
|
|
42029
|
+
}
|
|
42030
|
+
case 'strong':
|
|
42031
|
+
case 'em':
|
|
42032
|
+
case 'del':
|
|
42033
|
+
{
|
|
42034
|
+
var _el = doc.createElement(node.type);
|
|
42035
|
+
renderInlineNodes(node.children, _el, doc);
|
|
42036
|
+
parent.appendChild(_el);
|
|
42037
|
+
break;
|
|
42038
|
+
}
|
|
42039
|
+
case 'link':
|
|
42040
|
+
{
|
|
42041
|
+
var href = safeHref(node.href);
|
|
42042
|
+
if (!href) {
|
|
42043
|
+
renderInlineNodes(node.children, parent, doc);
|
|
42044
|
+
break;
|
|
42045
|
+
}
|
|
42046
|
+
var _el2 = doc.createElement('a');
|
|
42047
|
+
_el2.setAttribute('href', href);
|
|
42048
|
+
_el2.setAttribute('target', '_blank');
|
|
42049
|
+
_el2.setAttribute('rel', 'noopener noreferrer nofollow');
|
|
42050
|
+
renderInlineNodes(node.children, _el2, doc);
|
|
42051
|
+
parent.appendChild(_el2);
|
|
42052
|
+
break;
|
|
42053
|
+
}
|
|
42054
|
+
case 'image':
|
|
42055
|
+
{
|
|
42056
|
+
var src = safeHref(node.src);
|
|
42057
|
+
if (!src) {
|
|
42058
|
+
parent.appendChild(doc.createTextNode(node.alt || ''));
|
|
42059
|
+
break;
|
|
42060
|
+
}
|
|
42061
|
+
var _el3 = doc.createElement('img');
|
|
42062
|
+
_el3.setAttribute('src', src);
|
|
42063
|
+
_el3.setAttribute('alt', node.alt || '');
|
|
42064
|
+
_el3.setAttribute('loading', 'lazy');
|
|
42065
|
+
_el3.className = 'md-img';
|
|
42066
|
+
parent.appendChild(_el3);
|
|
42067
|
+
break;
|
|
42068
|
+
}
|
|
42069
|
+
default:
|
|
42070
|
+
break;
|
|
42071
|
+
}
|
|
42072
|
+
}
|
|
42073
|
+
} catch (err) {
|
|
42074
|
+
_iterator.e(err);
|
|
42075
|
+
} finally {
|
|
42076
|
+
_iterator.f();
|
|
42077
|
+
}
|
|
42078
|
+
}
|
|
42079
|
+
function renderBlockNodes(blocks, parent, doc) {
|
|
42080
|
+
var _iterator2 = _createForOfIteratorHelper(blocks),
|
|
42081
|
+
_step2;
|
|
42082
|
+
try {
|
|
42083
|
+
var _loop = function _loop() {
|
|
42084
|
+
var block = _step2.value;
|
|
42085
|
+
switch (block.type) {
|
|
42086
|
+
case 'p':
|
|
42087
|
+
{
|
|
42088
|
+
var el = doc.createElement('p');
|
|
42089
|
+
renderInlineNodes(block.inline, el, doc);
|
|
42090
|
+
parent.appendChild(el);
|
|
42091
|
+
break;
|
|
42092
|
+
}
|
|
42093
|
+
case 'h':
|
|
42094
|
+
{
|
|
42095
|
+
var _el4 = doc.createElement("h".concat(Math.min(block.level + 2, 6)));
|
|
42096
|
+
_el4.className = "md-h md-h".concat(block.level);
|
|
42097
|
+
renderInlineNodes(block.inline, _el4, doc);
|
|
42098
|
+
parent.appendChild(_el4);
|
|
42099
|
+
break;
|
|
42100
|
+
}
|
|
42101
|
+
case 'hr':
|
|
42102
|
+
parent.appendChild(doc.createElement('hr'));
|
|
42103
|
+
break;
|
|
42104
|
+
case 'code':
|
|
42105
|
+
{
|
|
42106
|
+
var pre = doc.createElement('pre');
|
|
42107
|
+
var code = doc.createElement('code');
|
|
42108
|
+
if (block.lang) code.className = "language-".concat(block.lang.replace(/[^\w+-]/g, ''));
|
|
42109
|
+
code.textContent = block.text;
|
|
42110
|
+
pre.appendChild(code);
|
|
42111
|
+
parent.appendChild(pre);
|
|
42112
|
+
break;
|
|
42113
|
+
}
|
|
42114
|
+
case 'quote':
|
|
42115
|
+
{
|
|
42116
|
+
var _el5 = doc.createElement('blockquote');
|
|
42117
|
+
renderBlockNodes(block.blocks, _el5, doc);
|
|
42118
|
+
parent.appendChild(_el5);
|
|
42119
|
+
break;
|
|
42120
|
+
}
|
|
42121
|
+
case 'ul':
|
|
42122
|
+
case 'ol':
|
|
42123
|
+
{
|
|
42124
|
+
var list = doc.createElement(block.type);
|
|
42125
|
+
if (block.type === 'ol' && block.start != null) list.setAttribute('start', String(block.start));
|
|
42126
|
+
var _iterator3 = _createForOfIteratorHelper(block.items),
|
|
42127
|
+
_step3;
|
|
42128
|
+
try {
|
|
42129
|
+
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
|
|
42130
|
+
var item = _step3.value;
|
|
42131
|
+
var li = doc.createElement('li');
|
|
42132
|
+
// tight item: a lone paragraph renders straight into the <li>
|
|
42133
|
+
if (item.blocks.length === 1 && item.blocks[0].type === 'p') {
|
|
42134
|
+
renderInlineNodes(item.blocks[0].inline, li, doc);
|
|
42135
|
+
} else {
|
|
42136
|
+
renderBlockNodes(item.blocks, li, doc);
|
|
42137
|
+
}
|
|
42138
|
+
list.appendChild(li);
|
|
42139
|
+
}
|
|
42140
|
+
} catch (err) {
|
|
42141
|
+
_iterator3.e(err);
|
|
42142
|
+
} finally {
|
|
42143
|
+
_iterator3.f();
|
|
42144
|
+
}
|
|
42145
|
+
parent.appendChild(list);
|
|
42146
|
+
break;
|
|
42147
|
+
}
|
|
42148
|
+
case 'table':
|
|
42149
|
+
{
|
|
42150
|
+
var wrap = doc.createElement('div');
|
|
42151
|
+
wrap.className = 'md-table-wrap';
|
|
42152
|
+
var table = doc.createElement('table');
|
|
42153
|
+
var thead = doc.createElement('thead');
|
|
42154
|
+
var hrow = doc.createElement('tr');
|
|
42155
|
+
block.head.forEach(function (cell, idx) {
|
|
42156
|
+
var th = doc.createElement('th');
|
|
42157
|
+
if (block.align[idx]) th.style.textAlign = block.align[idx];
|
|
42158
|
+
renderInlineNodes(cell, th, doc);
|
|
42159
|
+
hrow.appendChild(th);
|
|
42160
|
+
});
|
|
42161
|
+
thead.appendChild(hrow);
|
|
42162
|
+
table.appendChild(thead);
|
|
42163
|
+
var tbody = doc.createElement('tbody');
|
|
42164
|
+
var _iterator4 = _createForOfIteratorHelper(block.rows),
|
|
42165
|
+
_step4;
|
|
42166
|
+
try {
|
|
42167
|
+
var _loop2 = function _loop2() {
|
|
42168
|
+
var row = _step4.value;
|
|
42169
|
+
var tr = doc.createElement('tr');
|
|
42170
|
+
row.forEach(function (cell, idx) {
|
|
42171
|
+
var td = doc.createElement('td');
|
|
42172
|
+
if (block.align[idx]) td.style.textAlign = block.align[idx];
|
|
42173
|
+
renderInlineNodes(cell, td, doc);
|
|
42174
|
+
tr.appendChild(td);
|
|
42175
|
+
});
|
|
42176
|
+
tbody.appendChild(tr);
|
|
42177
|
+
};
|
|
42178
|
+
for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
|
|
42179
|
+
_loop2();
|
|
42180
|
+
}
|
|
42181
|
+
} catch (err) {
|
|
42182
|
+
_iterator4.e(err);
|
|
42183
|
+
} finally {
|
|
42184
|
+
_iterator4.f();
|
|
42185
|
+
}
|
|
42186
|
+
table.appendChild(tbody);
|
|
42187
|
+
wrap.appendChild(table);
|
|
42188
|
+
parent.appendChild(wrap);
|
|
42189
|
+
break;
|
|
42190
|
+
}
|
|
42191
|
+
default:
|
|
42192
|
+
break;
|
|
42193
|
+
}
|
|
42194
|
+
};
|
|
42195
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
42196
|
+
_loop();
|
|
42197
|
+
}
|
|
42198
|
+
} catch (err) {
|
|
42199
|
+
_iterator2.e(err);
|
|
42200
|
+
} finally {
|
|
42201
|
+
_iterator2.f();
|
|
42202
|
+
}
|
|
42203
|
+
}
|
|
42204
|
+
|
|
42205
|
+
/**
|
|
42206
|
+
* Replace the contents of `el` with the rendered markdown of `text`.
|
|
42207
|
+
* Safe to call repeatedly with a growing buffer (streaming).
|
|
42208
|
+
*
|
|
42209
|
+
* @param {Element} el target element (emptied first)
|
|
42210
|
+
* @param {string} text markdown source
|
|
42211
|
+
*/
|
|
42212
|
+
function renderMarkdownInto(el, text) {
|
|
42213
|
+
if (!el) return;
|
|
42214
|
+
var doc = el.ownerDocument || document;
|
|
42215
|
+
while (el.firstChild) el.removeChild(el.firstChild);
|
|
42216
|
+
if (typeof text !== 'string' || text === '') return;
|
|
42217
|
+
var blocks;
|
|
42218
|
+
try {
|
|
42219
|
+
blocks = parseMarkdown(text);
|
|
42220
|
+
} catch (err) {
|
|
42221
|
+
// never let a parser bug swallow the agent's answer
|
|
42222
|
+
el.textContent = text;
|
|
42223
|
+
return;
|
|
42224
|
+
}
|
|
42225
|
+
var frag = doc.createDocumentFragment();
|
|
42226
|
+
renderBlockNodes(blocks, frag, doc);
|
|
42227
|
+
|
|
42228
|
+
// A response with no renderable block (e.g. only whitespace) falls back to text.
|
|
42229
|
+
if (!frag.firstChild) {
|
|
42230
|
+
el.textContent = text;
|
|
42231
|
+
return;
|
|
42232
|
+
}
|
|
42233
|
+
el.appendChild(frag);
|
|
42234
|
+
}
|
|
42235
|
+
|
|
42236
|
+
/***/ }),
|
|
42237
|
+
|
|
41040
42238
|
/***/ "./src/widget/voice/desktop.js":
|
|
41041
42239
|
/*!*************************************!*\
|
|
41042
42240
|
!*** ./src/widget/voice/desktop.js ***!
|
|
@@ -43477,10 +44675,12 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
43477
44675
|
"hello": "Hello! How can I help?",
|
|
43478
44676
|
"sendMessage": "Send a message to get started",
|
|
43479
44677
|
"online": "Online",
|
|
44678
|
+
"chatAssistant": "Chat Assistant",
|
|
43480
44679
|
"newChat": "New Chat",
|
|
43481
44680
|
"back": "Back",
|
|
43482
44681
|
"backToModeChoice": "Voice or text",
|
|
43483
44682
|
"close": "Close",
|
|
44683
|
+
"home": "Home",
|
|
43484
44684
|
"error": "Error",
|
|
43485
44685
|
"typeMessage": "Type your message...",
|
|
43486
44686
|
"sendMessageAria": "Send message",
|
|
@@ -43521,10 +44721,12 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
43521
44721
|
"hello": "שלום! איך אפשר לעזור?",
|
|
43522
44722
|
"sendMessage": "שלח הודעה או עבור למצב קולי לשיחה בזמן אמת",
|
|
43523
44723
|
"online": "מקוון",
|
|
44724
|
+
"chatAssistant": "עוזר צ׳אט",
|
|
43524
44725
|
"newChat": "צ'אט חדש",
|
|
43525
44726
|
"back": "חזור",
|
|
43526
44727
|
"backToModeChoice": "קול או טקסט",
|
|
43527
44728
|
"close": "סגור",
|
|
44729
|
+
"home": "דף הבית",
|
|
43528
44730
|
"error": "שגיאה",
|
|
43529
44731
|
"typeMessage": "הקלד הודעה...",
|
|
43530
44732
|
"sendMessageAria": "שלח הודעה",
|
|
@@ -43565,10 +44767,12 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
43565
44767
|
"hello": "مرحبا! كيف يمكنني المساعدة؟",
|
|
43566
44768
|
"sendMessage": "أرسل رسالة للبدء",
|
|
43567
44769
|
"online": "متصل",
|
|
44770
|
+
"chatAssistant": "مساعد الدردشة",
|
|
43568
44771
|
"newChat": "محادثة جديدة",
|
|
43569
44772
|
"back": "رجوع",
|
|
43570
44773
|
"backToModeChoice": "صوت أو نص",
|
|
43571
44774
|
"close": "إغلاق",
|
|
44775
|
+
"home": "الرئيسية",
|
|
43572
44776
|
"error": "خطأ",
|
|
43573
44777
|
"typeMessage": "اكتب رسالة...",
|
|
43574
44778
|
"sendMessageAria": "إرسال رسالة",
|
|
@@ -43609,10 +44813,12 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
43609
44813
|
"hello": "Привет! Как я могу помочь?",
|
|
43610
44814
|
"sendMessage": "Отправьте сообщение для начала",
|
|
43611
44815
|
"online": "В сети",
|
|
44816
|
+
"chatAssistant": "Чат-ассистент",
|
|
43612
44817
|
"newChat": "Новый чат",
|
|
43613
44818
|
"back": "Назад",
|
|
43614
44819
|
"backToModeChoice": "Голос или текст",
|
|
43615
44820
|
"close": "Закрыть",
|
|
44821
|
+
"home": "Главная",
|
|
43616
44822
|
"error": "Ошибка",
|
|
43617
44823
|
"typeMessage": "Введите сообщение...",
|
|
43618
44824
|
"sendMessageAria": "Отправить сообщение",
|
|
@@ -43653,10 +44859,12 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
43653
44859
|
"hello": "¡Hola! ¿Cómo puedo ayudarte?",
|
|
43654
44860
|
"sendMessage": "Envía un mensaje para comenzar",
|
|
43655
44861
|
"online": "En línea",
|
|
44862
|
+
"chatAssistant": "Asistente de chat",
|
|
43656
44863
|
"newChat": "Nuevo chat",
|
|
43657
44864
|
"back": "Atrás",
|
|
43658
44865
|
"backToModeChoice": "Voz o texto",
|
|
43659
44866
|
"close": "Cerrar",
|
|
44867
|
+
"home": "Inicio",
|
|
43660
44868
|
"error": "Error",
|
|
43661
44869
|
"typeMessage": "Escribe un mensaje...",
|
|
43662
44870
|
"sendMessageAria": "Enviar mensaje",
|
|
@@ -43697,10 +44905,12 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
43697
44905
|
"hello": "Bonjour! Comment puis-je vous aider?",
|
|
43698
44906
|
"sendMessage": "Envoyez un message pour commencer",
|
|
43699
44907
|
"online": "En ligne",
|
|
44908
|
+
"chatAssistant": "Assistant de chat",
|
|
43700
44909
|
"newChat": "Nouveau chat",
|
|
43701
44910
|
"back": "Retour",
|
|
43702
44911
|
"backToModeChoice": "Voix ou texte",
|
|
43703
44912
|
"close": "Fermer",
|
|
44913
|
+
"home": "Accueil",
|
|
43704
44914
|
"error": "Erreur",
|
|
43705
44915
|
"typeMessage": "Tapez votre message...",
|
|
43706
44916
|
"sendMessageAria": "Envoyer un message",
|
|
@@ -43741,10 +44951,12 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
43741
44951
|
"hello": "Hallo! Wie kann ich helfen?",
|
|
43742
44952
|
"sendMessage": "Senden Sie eine Nachricht zum Starten",
|
|
43743
44953
|
"online": "Online",
|
|
44954
|
+
"chatAssistant": "Chat-Assistent",
|
|
43744
44955
|
"newChat": "Neuer Chat",
|
|
43745
44956
|
"back": "Zurück",
|
|
43746
44957
|
"backToModeChoice": "Sprache oder Text",
|
|
43747
44958
|
"close": "Schließen",
|
|
44959
|
+
"home": "Startseite",
|
|
43748
44960
|
"error": "Fehler",
|
|
43749
44961
|
"typeMessage": "Geben Sie eine Nachricht ein...",
|
|
43750
44962
|
"sendMessageAria": "Nachricht senden",
|