ttp-agent-sdk 2.48.1 → 2.48.5

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.
@@ -12047,7 +12047,7 @@ var TextChatSDK = /*#__PURE__*/function (_EventEmitter) {
12047
12047
 
12048
12048
  // SDK build time for debugging
12049
12049
  if (true) {
12050
- helloMessage.lastBuildTime = "2026-08-20T12:21:14.185Z";
12050
+ helloMessage.lastBuildTime = "2026-08-20T16:29:04.205Z";
12051
12051
  }
12052
12052
  try {
12053
12053
  this.ws.send(JSON.stringify(helloMessage));
@@ -21357,8 +21357,8 @@ var VoiceSDK = _v2_VoiceSDK_js__WEBPACK_IMPORTED_MODULE_0__["default"];
21357
21357
 
21358
21358
 
21359
21359
  // Version - injected at build time from package.json via webpack DefinePlugin
21360
- var VERSION = "2.48.0";
21361
- var BUILD_TIME = "2026-08-20T12:21:14.185Z";
21360
+ var VERSION = "2.48.5";
21361
+ var BUILD_TIME = "2026-08-20T16:29:04.205Z";
21362
21362
  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;');
21363
21363
 
21364
21364
  // Named exports
@@ -25620,6 +25620,10 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
25620
25620
  _this._mediaStreamDest = null;
25621
25621
  _this._htmlAudioRouteActive = false;
25622
25622
  _this._htmlAudioPlayOk = false;
25623
+ // Greeting (and other bursts) fire many playChunk()s without await.
25624
+ // Serialize context creation so they cannot open two AudioContexts
25625
+ // at different rates in the middle of a sentence.
25626
+ _this._audioContextInitPromise = null;
25623
25627
 
25624
25628
  // Track temporary listener in waitForAudioContextReady() for cleanup
25625
25629
  _this._waitForReadyStateHandler = null;
@@ -25727,9 +25731,10 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
25727
25731
  this.outputFormat = format;
25728
25732
  console.log('✅ AudioPlayer v2: Format set:', format);
25729
25733
 
25730
- // CRITICAL: If AudioContext already exists and sample rate changed, recreate it
25734
+ // Destination path matches AudioContext to the TTS rate. The HTML last-hop
25735
+ // keeps the context at hardware rate (48 kHz); only createBuffer() follows TTS.
25731
25736
 
25732
- if (this.audioContext && oldSampleRate && oldSampleRate !== newSampleRate) {
25737
+ if (this.audioContext && oldSampleRate && oldSampleRate !== newSampleRate && !this._htmlHopNeedsHardwareRate()) {
25733
25738
  console.warn('⚠️ AudioPlayer: Sample rate changed, recreating AudioContext');
25734
25739
  console.warn(" Old: ".concat(oldSampleRate, "Hz \u2192 New: ").concat(newSampleRate, "Hz"));
25735
25740
 
@@ -25910,7 +25915,7 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
25910
25915
  key: "prepareChunk",
25911
25916
  value: (function () {
25912
25917
  var _prepareChunk = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee2(pcmData) {
25913
- var _this$outputFormat2, processedData, padded, int16Array, float32Array, NORMALIZATION, length, i, audioDataSampleRate, contextSampleRate, audioBuffer, chunkDuration, sampleCount, actualDuration, _t;
25918
+ var _this$outputFormat2, processedData, padded, int16Array, float32Array, NORMALIZATION, length, i, audioDataSampleRate, audioBuffer, actualDuration, _t;
25914
25919
  return _regenerator().w(function (_context2) {
25915
25920
  while (1) switch (_context2.p = _context2.n) {
25916
25921
  case 0:
@@ -25959,27 +25964,21 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
25959
25964
 
25960
25965
  // Create audio buffer with the ACTUAL sample rate of the audio data
25961
25966
  audioDataSampleRate = ((_this$outputFormat2 = this.outputFormat) === null || _this$outputFormat2 === void 0 ? void 0 : _this$outputFormat2.sampleRate) || this.audioContext.sampleRate;
25962
- contextSampleRate = this.audioContext.sampleRate;
25963
25967
  audioBuffer = this.audioContext.createBuffer(1,
25964
25968
  // mono
25965
25969
 
25966
25970
  float32Array.length, audioDataSampleRate);
25967
25971
  audioBuffer.getChannelData(0).set(float32Array);
25968
25972
 
25969
- // Calculate duration (handle browser resampling)
25970
- chunkDuration = audioBuffer.duration;
25971
- sampleCount = float32Array.length;
25972
- actualDuration = chunkDuration;
25973
- if (contextSampleRate !== audioDataSampleRate) {
25974
- actualDuration = sampleCount / contextSampleRate;
25975
- }
25976
-
25977
- // Return prepared frame
25973
+ // Wall-clock duration is sampleCount / TTS rate (audioBuffer.duration).
25974
+ // Dividing by contextSampleRate when the context is 48 kHz and TTS is
25975
+ // 24 kHz halves the schedule step and overlaps chunks.
25976
+ actualDuration = audioBuffer.duration; // Return prepared frame
25978
25977
  return _context2.a(2, {
25979
25978
  buffer: audioBuffer,
25980
25979
  duration: actualDuration,
25981
25980
  sampleRate: audioDataSampleRate,
25982
- contextSampleRate: contextSampleRate
25981
+ contextSampleRate: this.audioContext.sampleRate
25983
25982
  });
25984
25983
  case 4:
25985
25984
  _context2.p = 4;
@@ -26336,7 +26335,7 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
26336
26335
  value: (function () {
26337
26336
  var _processPcmQueue = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee4() {
26338
26337
  var _this5 = this;
26339
- var _this$outputFormat3, _this$outputFormat4, pcmData, processedData, padded, int16Array, float32Array, NORMALIZATION, length, i, audioDataSampleRate, contextSampleRate, audioBuffer, source, currentTime, chunkDuration, sampleCount, actualDuration, startTime, _t3;
26338
+ var _this$outputFormat3, _this$outputFormat4, pcmData, processedData, padded, int16Array, float32Array, NORMALIZATION, length, i, audioDataSampleRate, contextSampleRate, audioBuffer, source, currentTime, actualDuration, startTime, _t3;
26340
26339
  return _regenerator().w(function (_context5) {
26341
26340
  while (1) switch (_context5.p = _context5.n) {
26342
26341
  case 0:
@@ -26423,16 +26422,11 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
26423
26422
  }
26424
26423
  }
26425
26424
 
26426
- // Calculate frame duration - handle browser resampling correctly
26427
- chunkDuration = audioBuffer.duration;
26428
- sampleCount = float32Array.length;
26429
- actualDuration = chunkDuration;
26430
- if (contextSampleRate !== audioDataSampleRate) {
26431
- actualDuration = sampleCount / contextSampleRate;
26432
- if (this.scheduledBuffers < 3) {
26433
- console.log("\uD83D\uDD04 Resampling detected: ".concat(audioDataSampleRate, "Hz \u2192 ").concat(contextSampleRate, "Hz"));
26434
- console.log(" Buffer duration: ".concat(chunkDuration.toFixed(4), "s, Calculated: ").concat(actualDuration.toFixed(4), "s"));
26435
- }
26425
+ // Wall-clock duration is always sampleCount / TTS rate. Web Audio
26426
+ // resamples into the context; do not divide by contextSampleRate.
26427
+ actualDuration = audioBuffer.duration;
26428
+ if (contextSampleRate !== audioDataSampleRate && this.scheduledBuffers < 3) {
26429
+ console.log("\uD83D\uDD04 AudioPlayer: Buffer ".concat(audioDataSampleRate, "Hz in ").concat(contextSampleRate, "Hz context, duration ").concat(actualDuration.toFixed(4), "s"));
26436
26430
  }
26437
26431
 
26438
26432
  // Schedule this chunk to start at nextStartTime
@@ -27044,6 +27038,29 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
27044
27038
  value: function wantsHtmlAudioPlayback() {
27045
27039
  return this.config.htmlAudioPlayback !== false;
27046
27040
  }
27041
+ }, {
27042
+ key: "_ttsSampleRate",
27043
+ value: function _ttsSampleRate() {
27044
+ var _this$outputFormat5;
27045
+ return ((_this$outputFormat5 = this.outputFormat) === null || _this$outputFormat5 === void 0 ? void 0 : _this$outputFormat5.sampleRate) || 24000;
27046
+ }
27047
+
27048
+ /**
27049
+ * Hidden <audio srcObject> clocks a MediaStream at the device rate
27050
+ * (typically 48 kHz). Forcing the AudioContext to the TTS rate (24 kHz)
27051
+ * makes Chrome play that hop ~2×. Destination-only playback can still
27052
+ * match the TTS rate.
27053
+ */
27054
+ }, {
27055
+ key: "_htmlHopNeedsHardwareRate",
27056
+ value: function _htmlHopNeedsHardwareRate() {
27057
+ return this.wantsHtmlAudioPlayback();
27058
+ }
27059
+ }, {
27060
+ key: "_isHardwarePlaybackRate",
27061
+ value: function _isHardwarePlaybackRate(rate) {
27062
+ return typeof rate === 'number' && rate >= 44100;
27063
+ }
27047
27064
  }, {
27048
27065
  key: "getHtmlAudioPlaybackInfo",
27049
27066
  value: function getHtmlAudioPlaybackInfo() {
@@ -27093,6 +27110,7 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
27093
27110
  el.autoplay = true;
27094
27111
  el.controls = false;
27095
27112
  el.preload = 'auto';
27113
+ el.playbackRate = 1;
27096
27114
  el.style.display = 'none';
27097
27115
  el.srcObject = this._mediaStreamDest.stream;
27098
27116
  document.body.appendChild(el);
@@ -27164,16 +27182,42 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
27164
27182
  key: "initializeAudioContext",
27165
27183
  value: (function () {
27166
27184
  var _initializeAudioContext = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee7() {
27167
- var _this$outputFormat5,
27168
- _this8 = this,
27169
- _this$outputFormat6;
27170
- var desiredSampleRate, currentSampleRate, canReuseShared, setupAfterResume, _t4;
27185
+ var _this8 = this;
27171
27186
  return _regenerator().w(function (_context8) {
27172
- while (1) switch (_context8.p = _context8.n) {
27187
+ while (1) switch (_context8.n) {
27173
27188
  case 0:
27174
- // Use negotiated sample rate, default to 24kHz to match typical server/TTS output
27175
- desiredSampleRate = ((_this$outputFormat5 = this.outputFormat) === null || _this$outputFormat5 === void 0 ? void 0 : _this$outputFormat5.sampleRate) || 24000;
27176
- if (![24000, 44100, 48000].includes(desiredSampleRate)) {
27189
+ if (!this._audioContextInitPromise) {
27190
+ _context8.n = 1;
27191
+ break;
27192
+ }
27193
+ return _context8.a(2, this._audioContextInitPromise);
27194
+ case 1:
27195
+ this._audioContextInitPromise = this._initializeAudioContextImpl().finally(function () {
27196
+ _this8._audioContextInitPromise = null;
27197
+ });
27198
+ return _context8.a(2, this._audioContextInitPromise);
27199
+ }
27200
+ }, _callee7, this);
27201
+ }));
27202
+ function initializeAudioContext() {
27203
+ return _initializeAudioContext.apply(this, arguments);
27204
+ }
27205
+ return initializeAudioContext;
27206
+ }())
27207
+ }, {
27208
+ key: "_initializeAudioContextImpl",
27209
+ value: function () {
27210
+ var _initializeAudioContextImpl2 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee8() {
27211
+ var _this9 = this;
27212
+ var ttsSampleRate, useHardwareRate, desiredSampleRate, contextFits, canReuseShared, setupAfterResume, ctxOpts, _t4;
27213
+ return _regenerator().w(function (_context9) {
27214
+ while (1) switch (_context9.p = _context9.n) {
27215
+ case 0:
27216
+ ttsSampleRate = this._ttsSampleRate();
27217
+ useHardwareRate = this._htmlHopNeedsHardwareRate(); // Destination path: match TTS (24 kHz). HTML last-hop: omit so the
27218
+ // context (and MediaStream) run at the device rate — usually 48 kHz.
27219
+ desiredSampleRate = useHardwareRate ? null : ttsSampleRate;
27220
+ if (!useHardwareRate && ![24000, 44100, 48000].includes(desiredSampleRate)) {
27177
27221
  console.log("\u2139\uFE0F AudioPlayer: Backend requested ".concat(desiredSampleRate, "Hz, but browser may resample"));
27178
27222
  console.log(" Consider requesting 24000Hz, 44100Hz, or 48000Hz from backend to reduce resampling");
27179
27223
  }
@@ -27181,79 +27225,78 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
27181
27225
  _sharedPlayerContext = null;
27182
27226
  _sharedPlayerSampleRate = null;
27183
27227
  }
27184
-
27185
- // Check if current instance AudioContext exists and matches
27228
+ contextFits = function contextFits(rate) {
27229
+ if (useHardwareRate) return _this9._isHardwarePlaybackRate(rate);
27230
+ return Math.abs(rate - desiredSampleRate) <= 100;
27231
+ }; // Check if current instance AudioContext exists and matches
27186
27232
  if (!this.audioContext) {
27187
- _context8.n = 3;
27233
+ _context9.n = 3;
27188
27234
  break;
27189
27235
  }
27190
27236
  if (!(this.audioContext.state === 'closed')) {
27191
- _context8.n = 1;
27237
+ _context9.n = 1;
27192
27238
  break;
27193
27239
  }
27194
27240
  this._invalidateClosedAudioContext();
27195
- _context8.n = 3;
27241
+ _context9.n = 3;
27196
27242
  break;
27197
27243
  case 1:
27198
- currentSampleRate = this.audioContext.sampleRate;
27199
- if (!(Math.abs(currentSampleRate - desiredSampleRate) > 100)) {
27200
- _context8.n = 2;
27244
+ if (!contextFits(this.audioContext.sampleRate)) {
27245
+ _context9.n = 2;
27201
27246
  break;
27202
27247
  }
27203
- console.warn("\u26A0\uFE0F AudioPlayer: AudioContext sample rate (".concat(currentSampleRate, "Hz) doesn't match format (").concat(desiredSampleRate, "Hz), recreating..."));
27248
+ this._ensureHtmlAudioPlaying();
27249
+ return _context9.a(2);
27250
+ case 2:
27251
+ console.warn("\u26A0\uFE0F AudioPlayer: AudioContext sample rate (".concat(this.audioContext.sampleRate, "Hz) doesn't match playback hop, recreating..."));
27204
27252
  this.stopImmediate();
27205
27253
  this._cleanupAudioContext();
27206
- _context8.n = 3;
27207
- break;
27208
- case 2:
27209
- this._ensureHtmlAudioPlaying();
27210
- return _context8.a(2);
27211
27254
  case 3:
27212
27255
  // iOS FIX: Reuse shared AudioContext if available and compatible.
27213
27256
  // iOS WebKit doesn't release audio hardware synchronously on AudioContext.close(),
27214
27257
  // causing newly created AudioContexts to fail silently.
27215
- canReuseShared = _sharedPlayerContext && _sharedPlayerContext.state !== 'closed' && _sharedPlayerSampleRate === desiredSampleRate;
27258
+ canReuseShared = _sharedPlayerContext && _sharedPlayerContext.state !== 'closed' && contextFits(_sharedPlayerContext.sampleRate);
27216
27259
  if (!canReuseShared) {
27217
- _context8.n = 8;
27260
+ _context9.n = 8;
27218
27261
  break;
27219
27262
  }
27220
- console.log("\u267B\uFE0F AudioPlayer: Reusing shared AudioContext at ".concat(desiredSampleRate, "Hz (iOS-safe)"));
27263
+ console.log("\u267B\uFE0F AudioPlayer: Reusing shared AudioContext at ".concat(_sharedPlayerContext.sampleRate, "Hz (iOS-safe)"));
27221
27264
  this.audioContext = _sharedPlayerContext;
27222
27265
  setupAfterResume = function setupAfterResume() {
27223
- _this8.setupAudioContextStateMonitoring();
27224
- if (_this8.gainNode) {
27266
+ _this9.setupAudioContextStateMonitoring();
27267
+ if (_this9.gainNode) {
27225
27268
  try {
27226
- _this8.gainNode.disconnect();
27269
+ _this9.gainNode.disconnect();
27227
27270
  } catch (e) {
27228
27271
  console.warn('⚠️ AudioPlayer: Error disconnecting old GainNode:', e);
27229
27272
  }
27230
27273
  }
27231
- _this8.gainNode = _this8.audioContext.createGain();
27232
- _this8.gainNode.gain.value = 1.0;
27233
- _this8._connectGainToOutput();
27234
- if (!_this8._audioContextPrimed) {
27235
- _this8._primeAudioContext();
27274
+ _this9.gainNode = _this9.audioContext.createGain();
27275
+ _this9.gainNode.gain.value = 1.0;
27276
+ _this9._connectGainToOutput();
27277
+ if (!_this9._audioContextPrimed) {
27278
+ _this9._primeAudioContext();
27236
27279
  }
27237
27280
  };
27238
27281
  if (!(this.audioContext.state === 'suspended')) {
27239
- _context8.n = 7;
27282
+ _context9.n = 7;
27240
27283
  break;
27241
27284
  }
27242
- _context8.p = 4;
27243
- _context8.n = 5;
27285
+ _context9.p = 4;
27286
+ _context9.n = 5;
27244
27287
  return this.audioContext.resume();
27245
27288
  case 5:
27246
- _context8.n = 7;
27289
+ _context9.n = 7;
27247
27290
  break;
27248
27291
  case 6:
27249
- _context8.p = 6;
27250
- _t4 = _context8.v;
27292
+ _context9.p = 6;
27293
+ _t4 = _context9.v;
27251
27294
  console.warn('⚠️ AudioPlayer: Error resuming shared context:', _t4);
27252
27295
  case 7:
27253
27296
  setupAfterResume();
27254
- return _context8.a(2);
27297
+ return _context9.a(2);
27255
27298
  case 8:
27256
- console.log("\uD83C\uDFB5 AudioPlayer: Creating AudioContext at ".concat(desiredSampleRate, "Hz (from outputFormat: ").concat(((_this$outputFormat6 = this.outputFormat) === null || _this$outputFormat6 === void 0 ? void 0 : _this$outputFormat6.sampleRate) || 'not set', ")"));
27299
+ console.log("\uD83C\uDFB5 AudioPlayer: Creating AudioContext (tts=".concat(ttsSampleRate, "Hz, htmlHop=").concat(useHardwareRate, ", requested=").concat(desiredSampleRate || 'hardware default', ")"));
27257
27300
 
27258
27301
  // Close old shared context if sample rate changed
27259
27302
  if (_sharedPlayerContext && _sharedPlayerContext.state !== 'closed') {
@@ -27265,24 +27308,22 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
27265
27308
  }
27266
27309
  }
27267
27310
  try {
27268
- this.audioContext = new (window.AudioContext || window.webkitAudioContext)({
27269
- sampleRate: desiredSampleRate,
27311
+ ctxOpts = {
27270
27312
  latencyHint: 'playback'
27271
- });
27313
+ };
27314
+ if (desiredSampleRate) {
27315
+ ctxOpts.sampleRate = desiredSampleRate;
27316
+ }
27317
+ this.audioContext = new (window.AudioContext || window.webkitAudioContext)(ctxOpts);
27272
27318
 
27273
27319
  // Store as shared context
27274
27320
  _sharedPlayerContext = this.audioContext;
27275
- _sharedPlayerSampleRate = desiredSampleRate;
27276
- console.log("\u2705 AudioContext created at ".concat(this.audioContext.sampleRate, "Hz (requested: ").concat(desiredSampleRate, "Hz)"));
27277
- if (Math.abs(this.audioContext.sampleRate - desiredSampleRate) > 100) {
27278
- console.error("\u274C CRITICAL: Browser sample rate mismatch!");
27279
- console.error(" Requested: ".concat(desiredSampleRate, "Hz"));
27280
- console.error(" Got: ".concat(this.audioContext.sampleRate, "Hz"));
27281
- console.error(" This WILL cause audio distortion/noise!");
27282
- console.error(" Solution: Backend should send ".concat(this.audioContext.sampleRate, "Hz audio instead"));
27283
- } else if (this.audioContext.sampleRate !== desiredSampleRate) {
27284
- console.warn("\u26A0\uFE0F Browser adjusted sample rate: ".concat(desiredSampleRate, "Hz \u2192 ").concat(this.audioContext.sampleRate, "Hz"));
27285
- console.warn(" Browser will automatically resample audio.");
27321
+ _sharedPlayerSampleRate = this.audioContext.sampleRate;
27322
+ console.log("\u2705 AudioContext created at ".concat(this.audioContext.sampleRate, "Hz (tts=").concat(ttsSampleRate, "Hz, htmlHop=").concat(useHardwareRate, ")"));
27323
+ if (useHardwareRate && !this._isHardwarePlaybackRate(this.audioContext.sampleRate)) {
27324
+ console.warn("\u26A0\uFE0F AudioPlayer: HTML hop expected \u226544.1 kHz context, got ".concat(this.audioContext.sampleRate, "Hz"));
27325
+ } else if (!useHardwareRate && Math.abs(this.audioContext.sampleRate - desiredSampleRate) > 100) {
27326
+ console.warn("\u26A0\uFE0F AudioPlayer: Browser sample rate ".concat(this.audioContext.sampleRate, "Hz \u2260 requested ").concat(desiredSampleRate, "Hz; Web Audio will resample"));
27286
27327
  }
27287
27328
  this.setupAudioContextStateMonitoring();
27288
27329
  this.gainNode = this.audioContext.createGain();
@@ -27304,34 +27345,33 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
27304
27345
  this._primeAudioContext();
27305
27346
  }
27306
27347
  case 9:
27307
- return _context8.a(2);
27348
+ return _context9.a(2);
27308
27349
  }
27309
- }, _callee7, this, [[4, 6]]);
27350
+ }, _callee8, this, [[4, 6]]);
27310
27351
  }));
27311
- function initializeAudioContext() {
27312
- return _initializeAudioContext.apply(this, arguments);
27352
+ function _initializeAudioContextImpl() {
27353
+ return _initializeAudioContextImpl2.apply(this, arguments);
27313
27354
  }
27314
- return initializeAudioContext;
27355
+ return _initializeAudioContextImpl;
27315
27356
  }()
27316
27357
  /**
27317
27358
  * Prime AudioContext with silent buffer to initialize Android hardware
27318
27359
  * This prevents the first audio frame from being cut off on Android devices
27319
27360
  */
27320
- )
27321
27361
  }, {
27322
27362
  key: "_primeAudioContext",
27323
27363
  value: (function () {
27324
- var _primeAudioContext2 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee8() {
27364
+ var _primeAudioContext2 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee9() {
27325
27365
  var sampleRate, silentBuffer, source, _t5;
27326
- return _regenerator().w(function (_context9) {
27327
- while (1) switch (_context9.p = _context9.n) {
27366
+ return _regenerator().w(function (_context0) {
27367
+ while (1) switch (_context0.p = _context0.n) {
27328
27368
  case 0:
27329
- _context9.p = 0;
27369
+ _context0.p = 0;
27330
27370
  if (!(!this.audioContext || this._audioContextPrimed)) {
27331
- _context9.n = 1;
27371
+ _context0.n = 1;
27332
27372
  break;
27333
27373
  }
27334
- return _context9.a(2);
27374
+ return _context0.a(2);
27335
27375
  case 1:
27336
27376
  sampleRate = this.audioContext.sampleRate;
27337
27377
  silentBuffer = this.audioContext.createBuffer(1, sampleRate * 0.15, sampleRate);
@@ -27342,23 +27382,23 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
27342
27382
  source.connect(this.gainNode || this.audioContext.destination);
27343
27383
  source.start();
27344
27384
  this._ensureHtmlAudioPlaying();
27345
- _context9.n = 2;
27385
+ _context0.n = 2;
27346
27386
  return new Promise(function (resolve) {
27347
27387
  return setTimeout(resolve, 150);
27348
27388
  });
27349
27389
  case 2:
27350
27390
  this._audioContextPrimed = true;
27351
27391
  console.log('✅ AudioPlayer: Audio hardware primed with silent buffer');
27352
- _context9.n = 4;
27392
+ _context0.n = 4;
27353
27393
  break;
27354
27394
  case 3:
27355
- _context9.p = 3;
27356
- _t5 = _context9.v;
27395
+ _context0.p = 3;
27396
+ _t5 = _context0.v;
27357
27397
  console.error('❌ AudioPlayer: Audio priming failed:', _t5);
27358
27398
  case 4:
27359
- return _context9.a(2);
27399
+ return _context0.a(2);
27360
27400
  }
27361
- }, _callee8, this, [[0, 3]]);
27401
+ }, _callee9, this, [[0, 3]]);
27362
27402
  }));
27363
27403
  function _primeAudioContext() {
27364
27404
  return _primeAudioContext2.apply(this, arguments);
@@ -27425,7 +27465,7 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
27425
27465
  * Handles mic permission grants, tab switching, browser suspension, etc.
27426
27466
  */
27427
27467
  function setupAudioContextStateMonitoring() {
27428
- var _this9 = this;
27468
+ var _this0 = this;
27429
27469
  if (!this.audioContext) {
27430
27470
  return;
27431
27471
  }
@@ -27438,38 +27478,38 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
27438
27478
  // Create handler that references this.audioContext dynamically
27439
27479
  this._audioContextStateChangeHandler = function () {
27440
27480
  // Null check required because audioContext may be cleaned up while handler is queued
27441
- if (!_this9.audioContext) {
27481
+ if (!_this0.audioContext) {
27442
27482
  console.warn('⚠️ AudioPlayer: State change handler fired but AudioContext is null');
27443
27483
  return;
27444
27484
  }
27445
- console.log("\uD83C\uDFB5 AudioPlayer: AudioContext state changed to: ".concat(_this9.audioContext.state));
27446
- if (_this9.audioContext.state === 'running') {
27447
- _this9._ensureHtmlAudioPlaying();
27485
+ console.log("\uD83C\uDFB5 AudioPlayer: AudioContext state changed to: ".concat(_this0.audioContext.state));
27486
+ if (_this0.audioContext.state === 'running') {
27487
+ _this0._ensureHtmlAudioPlaying();
27448
27488
  }
27449
- if (_this9.audioContext.state === 'suspended' && _this9.isPlaying) {
27489
+ if (_this0.audioContext.state === 'suspended' && _this0.isPlaying) {
27450
27490
  // AudioContext was suspended during playback (tab switch, mic permission, etc.)
27451
27491
  console.warn('⚠️ AudioPlayer: AudioContext suspended during playback');
27452
27492
  // Note: Playback will pause automatically, but we should handle queue processing
27453
27493
  // The state change will be handled when we try to process next frame
27454
- } else if (_this9.audioContext.state === 'running' && !_this9.isPlaying && (_this9.audioQueue.length > 0 || _this9.pcmChunkQueue.length > 0 || _this9.preparedBuffer.length > 0)) {
27494
+ } else if (_this0.audioContext.state === 'running' && !_this0.isPlaying && (_this0.audioQueue.length > 0 || _this0.pcmChunkQueue.length > 0 || _this0.preparedBuffer.length > 0)) {
27455
27495
  // AudioContext resumed and we have queued frames
27456
27496
  // This handles: mic permission grant, tab switching back, browser resume, etc.
27457
27497
  console.log('✅ AudioPlayer: AudioContext resumed - resuming queue processing');
27458
27498
 
27459
27499
  // Resume queue processing if we have frames
27460
- if (_this9.audioQueue.length > 0 && !_this9.isProcessingQueue) {
27500
+ if (_this0.audioQueue.length > 0 && !_this0.isProcessingQueue) {
27461
27501
  setTimeout(function () {
27462
- return _this9.processQueue();
27502
+ return _this0.processQueue();
27463
27503
  }, 50);
27464
27504
  }
27465
- if (_this9.pcmChunkQueue.length > 0 && !_this9.isProcessingPcmQueue) {
27505
+ if (_this0.pcmChunkQueue.length > 0 && !_this0.isProcessingPcmQueue) {
27466
27506
  setTimeout(function () {
27467
- return _this9.processPcmQueue();
27507
+ return _this0.processPcmQueue();
27468
27508
  }, 50);
27469
27509
  }
27470
- if (_this9.preparedBuffer.length > 0 && !_this9.isSchedulingFrames) {
27510
+ if (_this0.preparedBuffer.length > 0 && !_this0.isSchedulingFrames) {
27471
27511
  setTimeout(function () {
27472
- return _this9.scheduleFrames();
27512
+ return _this0.scheduleFrames();
27473
27513
  }, 50);
27474
27514
  }
27475
27515
  }
@@ -27487,49 +27527,49 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
27487
27527
  }, {
27488
27528
  key: "processQueue",
27489
27529
  value: (function () {
27490
- var _processQueue = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee9() {
27491
- var _this0 = this;
27530
+ var _processQueue = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee0() {
27531
+ var _this1 = this;
27492
27532
  var audioBlob, wasFirstPlay, audioContext, arrayBuffer, audioBuffer, shouldEmitStart, source, _t6;
27493
- return _regenerator().w(function (_context0) {
27494
- while (1) switch (_context0.p = _context0.n) {
27533
+ return _regenerator().w(function (_context1) {
27534
+ while (1) switch (_context1.p = _context1.n) {
27495
27535
  case 0:
27496
27536
  if (!this._isStopped) {
27497
- _context0.n = 1;
27537
+ _context1.n = 1;
27498
27538
  break;
27499
27539
  }
27500
27540
  console.log('🛑 AudioPlayer: Not processing queue - playback was stopped (barge-in)');
27501
- return _context0.a(2);
27541
+ return _context1.a(2);
27502
27542
  case 1:
27503
27543
  if (!(this.isProcessingQueue || this.audioQueue.length === 0)) {
27504
- _context0.n = 2;
27544
+ _context1.n = 2;
27505
27545
  break;
27506
27546
  }
27507
- return _context0.a(2);
27547
+ return _context1.a(2);
27508
27548
  case 2:
27509
27549
  this.isProcessingQueue = true;
27510
27550
  this._ensureHtmlAudioPlaying();
27511
27551
  audioBlob = this.audioQueue.shift();
27512
27552
  if (audioBlob) {
27513
- _context0.n = 3;
27553
+ _context1.n = 3;
27514
27554
  break;
27515
27555
  }
27516
27556
  this.isProcessingQueue = false;
27517
- return _context0.a(2);
27557
+ return _context1.a(2);
27518
27558
  case 3:
27519
- _context0.p = 3;
27559
+ _context1.p = 3;
27520
27560
  wasFirstPlay = !this.isPlaying && this.currentSource === null; // Ensure context exists and is running (handles lazy init + suspended shared context)
27521
- _context0.n = 4;
27561
+ _context1.n = 4;
27522
27562
  return this.waitForAudioContextReady();
27523
27563
  case 4:
27524
27564
  audioContext = this.audioContext; // Decode audio
27525
- _context0.n = 5;
27565
+ _context1.n = 5;
27526
27566
  return audioBlob.arrayBuffer();
27527
27567
  case 5:
27528
- arrayBuffer = _context0.v;
27529
- _context0.n = 6;
27568
+ arrayBuffer = _context1.v;
27569
+ _context1.n = 6;
27530
27570
  return audioContext.decodeAudioData(arrayBuffer);
27531
27571
  case 6:
27532
- audioBuffer = _context0.v;
27572
+ audioBuffer = _context1.v;
27533
27573
  shouldEmitStart = wasFirstPlay && !this.isPlaying && this.currentSource === null; // Create source
27534
27574
  source = audioContext.createBufferSource();
27535
27575
  source.buffer = audioBuffer;
@@ -27548,22 +27588,22 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
27548
27588
  // Handle end
27549
27589
 
27550
27590
  source.onended = function () {
27551
- _this0.currentSource = null;
27552
- _this0.isProcessingQueue = false;
27591
+ _this1.currentSource = null;
27592
+ _this1.isProcessingQueue = false;
27553
27593
 
27554
27594
  // Process next chunk
27555
27595
 
27556
- if (_this0.audioQueue.length > 0) {
27596
+ if (_this1.audioQueue.length > 0) {
27557
27597
  setTimeout(function () {
27558
- return _this0.processQueue();
27598
+ return _this1.processQueue();
27559
27599
  }, 50);
27560
27600
  } else {
27561
27601
  // No more chunks - stop after delay
27562
27602
 
27563
27603
  setTimeout(function () {
27564
- if (_this0.audioQueue.length === 0 && !_this0.currentSource) {
27565
- _this0.isPlaying = false;
27566
- _this0.emit('playbackStopped');
27604
+ if (_this1.audioQueue.length === 0 && !_this1.currentSource) {
27605
+ _this1.isPlaying = false;
27606
+ _this1.emit('playbackStopped');
27567
27607
  }
27568
27608
  }, 100);
27569
27609
  }
@@ -27572,11 +27612,11 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
27572
27612
  // Start playback - AudioContext should now be fully ready
27573
27613
 
27574
27614
  source.start();
27575
- _context0.n = 8;
27615
+ _context1.n = 8;
27576
27616
  break;
27577
27617
  case 7:
27578
- _context0.p = 7;
27579
- _t6 = _context0.v;
27618
+ _context1.p = 7;
27619
+ _t6 = _context1.v;
27580
27620
  console.error('❌ AudioPlayer v2: Error processing queue:', _t6);
27581
27621
  this.currentSource = null;
27582
27622
  this.emit('playbackError', _t6);
@@ -27586,7 +27626,7 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
27586
27626
  if (this.audioQueue.length > 0) {
27587
27627
  this.isProcessingQueue = false;
27588
27628
  setTimeout(function () {
27589
- return _this0.processQueue();
27629
+ return _this1.processQueue();
27590
27630
  }, 100);
27591
27631
  } else {
27592
27632
  this.isPlaying = false;
@@ -27594,9 +27634,9 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
27594
27634
  this.emit('playbackStopped');
27595
27635
  }
27596
27636
  case 8:
27597
- return _context0.a(2);
27637
+ return _context1.a(2);
27598
27638
  }
27599
- }, _callee9, this, [[3, 7]]);
27639
+ }, _callee0, this, [[3, 7]]);
27600
27640
  }));
27601
27641
  function processQueue() {
27602
27642
  return _processQueue.apply(this, arguments);
@@ -27809,7 +27849,7 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
27809
27849
  }, {
27810
27850
  key: "markNewSentence",
27811
27851
  value: function markNewSentence(text, synced, segmentId) {
27812
- var _this1 = this;
27852
+ var _this10 = this;
27813
27853
  var wasStopped = this._isStopped;
27814
27854
  var isCurrentlyPlaying = this.isPlaying || this.scheduledSources.size > 0;
27815
27855
 
@@ -27868,34 +27908,34 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
27868
27908
  var sentenceText = text; // Capture for timeout callback
27869
27909
  this._emptySentenceTimeout = setTimeout(function () {
27870
27910
  // Check if this sentence still has no chunks after timeout
27871
- if (_this1.pendingSentenceText === sentenceText && _this1.scheduledBuffers === 0 && _this1.preparedBuffer.length === 0 && _this1.pcmChunkQueue.length === 0 && !_this1._isStopped) {
27911
+ if (_this10.pendingSentenceText === sentenceText && _this10.scheduledBuffers === 0 && _this10.preparedBuffer.length === 0 && _this10.pcmChunkQueue.length === 0 && !_this10._isStopped) {
27872
27912
  console.warn("\u26A0\uFE0F AudioPlayer: Empty sentence detected after 5s timeout - no chunks received for: \"".concat(sentenceText.substring(0, 40), "...\""));
27873
27913
  // If this empty sentence carried a segment id, report it done (nothing was heard) and
27874
27914
  // adopt it as current so the coarse stop below matches the backend's last-sent id.
27875
- if (_this1.pendingSegmentId != null) {
27876
- var emptySegId = _this1.pendingSegmentId;
27877
- _this1.currentSegmentId = emptySegId;
27878
- _this1.pendingSegmentId = null;
27879
- _this1.emit('segmentDone', {
27915
+ if (_this10.pendingSegmentId != null) {
27916
+ var emptySegId = _this10.pendingSegmentId;
27917
+ _this10.currentSegmentId = emptySegId;
27918
+ _this10.pendingSegmentId = null;
27919
+ _this10.emit('segmentDone', {
27880
27920
  segmentId: emptySegId,
27881
27921
  status: 'finished',
27882
27922
  playedMs: 0
27883
27923
  });
27884
27924
  }
27885
27925
  // Clear pending sentence to unblock next sentence
27886
- if (_this1.pendingSentenceText === sentenceText) {
27887
- _this1.pendingSentenceText = null;
27926
+ if (_this10.pendingSentenceText === sentenceText) {
27927
+ _this10.pendingSentenceText = null;
27888
27928
  }
27889
27929
  // Emit playbackStopped to allow next sentence to start
27890
27930
  // Only if we're not currently playing (to avoid interrupting real playback)
27891
- if (!_this1.isPlaying && _this1.scheduledSources.size === 0) {
27931
+ if (!_this10.isPlaying && _this10.scheduledSources.size === 0) {
27892
27932
  console.log('🛑 AudioPlayer: Emitting playbackStopped for empty sentence timeout');
27893
- _this1.emit('playbackStopped', {
27894
- segmentId: _this1.currentSegmentId
27933
+ _this10.emit('playbackStopped', {
27934
+ segmentId: _this10.currentSegmentId
27895
27935
  });
27896
27936
  }
27897
27937
  }
27898
- _this1._emptySentenceTimeout = null;
27938
+ _this10._emptySentenceTimeout = null;
27899
27939
  }, 5000); // 5 second timeout - adjust based on expected chunk arrival rate
27900
27940
  }
27901
27941
 
@@ -27905,14 +27945,14 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
27905
27945
  }, {
27906
27946
  key: "startTranscriptChecker",
27907
27947
  value: function startTranscriptChecker() {
27908
- var _this10 = this;
27948
+ var _this11 = this;
27909
27949
  if (this.isCheckingTranscripts) return;
27910
27950
  this.isCheckingTranscripts = true;
27911
27951
  console.log('📝 AudioPlayer: Transcript checker started');
27912
27952
  var _checkLoop = function checkLoop() {
27913
- if (!_this10.isCheckingTranscripts || !_this10.audioContext) return;
27914
- var currentTime = _this10.audioContext.currentTime;
27915
- var _iterator2 = _createForOfIteratorHelper(_this10.sentenceTimings),
27953
+ if (!_this11.isCheckingTranscripts || !_this11.audioContext) return;
27954
+ var currentTime = _this11.audioContext.currentTime;
27955
+ var _iterator2 = _createForOfIteratorHelper(_this11.sentenceTimings),
27916
27956
  _step2;
27917
27957
  try {
27918
27958
  for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
@@ -27926,13 +27966,13 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
27926
27966
  eventData.synced = _timing.synced;
27927
27967
  }
27928
27968
  console.log("\uD83D\uDCDD AudioPlayer: Display transcript at ".concat(currentTime.toFixed(3), "s: \"").concat(_timing.text.substring(0, 40), "...\" (synced: ").concat(_timing.synced ? _timing.synced.length : 0, ")"));
27929
- _this10.emit('transcriptDisplay', eventData);
27969
+ _this11.emit('transcriptDisplay', eventData);
27930
27970
  }
27931
27971
  // Per-segment natural finish: this segment's audio window has fully elapsed.
27932
27972
  if (!_timing.doneReported && _timing.endTime != null && currentTime >= _timing.endTime) {
27933
27973
  _timing.doneReported = true;
27934
27974
  var _playedMs = Math.round((_timing.endTime - _timing.startTime) * 1000);
27935
- _this10.emit('segmentDone', {
27975
+ _this11.emit('segmentDone', {
27936
27976
  segmentId: _timing.segmentId,
27937
27977
  status: 'finished',
27938
27978
  playedMs: _playedMs
@@ -27944,12 +27984,12 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
27944
27984
  } finally {
27945
27985
  _iterator2.f();
27946
27986
  }
27947
- if (_this10.isPlaying || _this10.scheduledBuffers > 0) {
27987
+ if (_this11.isPlaying || _this11.scheduledBuffers > 0) {
27948
27988
  requestAnimationFrame(_checkLoop);
27949
27989
  } else {
27950
27990
  // Playback drained naturally — flush any segment whose finish tick we may have missed
27951
27991
  // (the last buffer's onended can flip isPlaying=false before this loop's next tick).
27952
- var _iterator3 = _createForOfIteratorHelper(_this10.sentenceTimings),
27992
+ var _iterator3 = _createForOfIteratorHelper(_this11.sentenceTimings),
27953
27993
  _step3;
27954
27994
  try {
27955
27995
  for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
@@ -27958,7 +27998,7 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
27958
27998
  timing.doneReported = true;
27959
27999
  var end = timing.endTime != null ? timing.endTime : timing.startTime;
27960
28000
  var playedMs = Math.round((end - timing.startTime) * 1000);
27961
- _this10.emit('segmentDone', {
28001
+ _this11.emit('segmentDone', {
27962
28002
  segmentId: timing.segmentId,
27963
28003
  status: 'finished',
27964
28004
  playedMs: playedMs
@@ -27970,7 +28010,7 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
27970
28010
  } finally {
27971
28011
  _iterator3.f();
27972
28012
  }
27973
- _this10.isCheckingTranscripts = false;
28013
+ _this11.isCheckingTranscripts = false;
27974
28014
  console.log('📝 AudioPlayer: Transcript checker stopped');
27975
28015
  }
27976
28016
  };
@@ -28001,43 +28041,43 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
28001
28041
  }, {
28002
28042
  key: "resumeAudioContext",
28003
28043
  value: (function () {
28004
- var _resumeAudioContext = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee0() {
28044
+ var _resumeAudioContext = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee1() {
28005
28045
  var _t7;
28006
- return _regenerator().w(function (_context1) {
28007
- while (1) switch (_context1.p = _context1.n) {
28046
+ return _regenerator().w(function (_context10) {
28047
+ while (1) switch (_context10.p = _context10.n) {
28008
28048
  case 0:
28009
28049
  if (!(!this.audioContext || this.audioContext.state === 'closed')) {
28010
- _context1.n = 2;
28050
+ _context10.n = 2;
28011
28051
  break;
28012
28052
  }
28013
- _context1.n = 1;
28053
+ _context10.n = 1;
28014
28054
  return this.initializeAudioContext();
28015
28055
  case 1:
28016
- _context1.n = 6;
28056
+ _context10.n = 6;
28017
28057
  break;
28018
28058
  case 2:
28019
28059
  if (!(this.audioContext.state === 'suspended')) {
28020
- _context1.n = 6;
28060
+ _context10.n = 6;
28021
28061
  break;
28022
28062
  }
28023
- _context1.p = 3;
28024
- _context1.n = 4;
28063
+ _context10.p = 3;
28064
+ _context10.n = 4;
28025
28065
  return this.audioContext.resume();
28026
28066
  case 4:
28027
28067
  console.log('✅ AudioPlayer v2: AudioContext resumed after mic permission');
28028
- _context1.n = 6;
28068
+ _context10.n = 6;
28029
28069
  break;
28030
28070
  case 5:
28031
- _context1.p = 5;
28032
- _t7 = _context1.v;
28071
+ _context10.p = 5;
28072
+ _t7 = _context10.v;
28033
28073
  console.warn('⚠️ AudioPlayer v2: Failed to resume AudioContext:', _t7);
28034
28074
  case 6:
28035
- _context1.n = 7;
28075
+ _context10.n = 7;
28036
28076
  return this.waitForAudioContextReady();
28037
28077
  case 7:
28038
- return _context1.a(2);
28078
+ return _context10.a(2);
28039
28079
  }
28040
- }, _callee0, this, [[3, 5]]);
28080
+ }, _callee1, this, [[3, 5]]);
28041
28081
  }));
28042
28082
  function resumeAudioContext() {
28043
28083
  return _resumeAudioContext.apply(this, arguments);
@@ -29130,7 +29170,7 @@ var VoiceSDK_v2 = /*#__PURE__*/function (_EventEmitter) {
29130
29170
  // iOS in-app webviews lack "Safari" in the UA (real Safari always has it).
29131
29171
  var webview = isAndroid && (/\bwv\b/.test(ua) || /Version\/[\d.]+.*Chrome/.test(ua)) || isIos && !/Safari/i.test(ua) || false;
29132
29172
  var env = {
29133
- sdkVersion: true ? "2.48.0" : 0,
29173
+ sdkVersion: true ? "2.48.5" : 0,
29134
29174
  ua: ua,
29135
29175
  platform: (uaData === null || uaData === void 0 ? void 0 : uaData.platform) || navigator.platform || '',
29136
29176
  mobile: (_uaData$mobile = uaData === null || uaData === void 0 ? void 0 : uaData.mobile) !== null && _uaData$mobile !== void 0 ? _uaData$mobile : isAndroid || isIos,
@@ -29145,7 +29185,7 @@ var VoiceSDK_v2 = /*#__PURE__*/function (_EventEmitter) {
29145
29185
  } catch (e) {
29146
29186
  console.warn('⚠️ VoiceSDK v2: Failed to build client env:', e);
29147
29187
  return {
29148
- sdkVersion: true ? "2.48.0" : 0
29188
+ sdkVersion: true ? "2.48.5" : 0
29149
29189
  };
29150
29190
  }
29151
29191
  }
@@ -29287,7 +29327,7 @@ var VoiceSDK_v2 = /*#__PURE__*/function (_EventEmitter) {
29287
29327
 
29288
29328
  // Include SDK build time for debugging
29289
29329
  if (true) {
29290
- helloMessage.lastBuildTime = "2026-08-20T12:21:14.185Z";
29330
+ helloMessage.lastBuildTime = "2026-08-20T16:29:04.205Z";
29291
29331
  }
29292
29332
 
29293
29333
  // Client environment (device/browser/webview) for backend logs + Langfuse metadata
@@ -35337,7 +35377,7 @@ var TTPChatWidget = /*#__PURE__*/function () {
35337
35377
  return;
35338
35378
  }
35339
35379
  this._ensureAboutStyles();
35340
- var version = true ? "2.48.0" : 0;
35380
+ var version = true ? "2.48.5" : 0;
35341
35381
  var convId = this._getLastConversationId();
35342
35382
  var t = function t(k, fb) {
35343
35383
  try {