@pollen-robotics/reachy-mini-sdk 1.12.0 → 1.13.0-dev.0.main.55a68f6

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.
@@ -1,19 +1,19 @@
1
- var re = Object.defineProperty, se = (s, e, t) => e in s ? re(s, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : s[e] = t, A = (s, e, t) => (se(s, typeof e != "symbol" ? e + "" : e, t), t), Z = "https://huggingface.co";
1
+ var ne = Object.defineProperty, se = (s, e, t) => e in s ? ne(s, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : s[e] = t, A = (s, e, t) => (se(s, typeof e != "symbol" ? e + "" : e, t), t), Z = "https://huggingface.co";
2
2
  async function D(s, e) {
3
- var t, n;
4
- const r = new ie(s.url, s.status, (t = s.headers.get("X-Request-Id")) != null ? t : void 0);
5
- r.message = `Api error with status ${r.statusCode}`;
6
- const i = [`URL: ${r.url}`, r.requestId ? `Request ID: ${r.requestId}` : void 0].filter(Boolean).join(". ");
7
- if ((n = s.headers.get("Content-Type")) != null && n.startsWith("application/json")) {
3
+ var t, r;
4
+ const n = new ie(s.url, s.status, (t = s.headers.get("X-Request-Id")) != null ? t : void 0);
5
+ n.message = `Api error with status ${n.statusCode}`;
6
+ const i = [`URL: ${n.url}`, n.requestId ? `Request ID: ${n.requestId}` : void 0].filter(Boolean).join(". ");
7
+ if ((r = s.headers.get("Content-Type")) != null && r.startsWith("application/json")) {
8
8
  const o = await s.json();
9
- r.message = o.error || o.message || r.message, r.data = o;
9
+ n.message = o.error || o.message || n.message, n.data = o;
10
10
  } else
11
- r.data = { message: await s.text() };
12
- throw r.message += `. ${i}`, r;
11
+ n.data = { message: await s.text() };
12
+ throw n.message += `. ${i}`, n;
13
13
  }
14
14
  var ie = class extends Error {
15
- constructor(s, e, t, n) {
16
- super(n), A(this, "statusCode"), A(this, "url"), A(this, "requestId"), A(this, "data"), this.statusCode = e, this.requestId = t, this.url = s;
15
+ constructor(s, e, t, r) {
16
+ super(r), A(this, "statusCode"), A(this, "url"), A(this, "requestId"), A(this, "data"), this.statusCode = e, this.requestId = t, this.url = s;
17
17
  }
18
18
  };
19
19
  new Promise((s) => {
@@ -32,10 +32,10 @@ async function B(s) {
32
32
  var e, t;
33
33
  if (typeof window > "u")
34
34
  throw new Error("oauthHandleRedirect is only available in the browser");
35
- const n = new URLSearchParams(window.location.search), [r, i] = [n.get("error"), n.get("error_description")];
36
- if (r)
37
- throw new Error(`${r}: ${i}`);
38
- const o = n.get("code"), a = localStorage.getItem("huggingface.co:oauth:nonce");
35
+ const r = new URLSearchParams(window.location.search), [n, i] = [r.get("error"), r.get("error_description")];
36
+ if (n)
37
+ throw new Error(`${n}: ${i}`);
38
+ const o = r.get("code"), a = localStorage.getItem("huggingface.co:oauth:nonce");
39
39
  if (!o)
40
40
  throw new Error("Missing oauth code from query parameters in redirected URL");
41
41
  if (!a)
@@ -43,7 +43,7 @@ async function B(s) {
43
43
  const c = localStorage.getItem("huggingface.co:oauth:code_verifier");
44
44
  if (!c)
45
45
  throw new Error("Missing oauth code_verifier from localStorage");
46
- const d = n.get("state");
46
+ const d = r.get("state");
47
47
  if (!d)
48
48
  throw new Error("Missing oauth state from query parameters in redirected URL");
49
49
  let u;
@@ -121,7 +121,7 @@ async function ce(s) {
121
121
  var e, t;
122
122
  if (typeof window > "u")
123
123
  throw new Error("oauthLogin is only available in the browser");
124
- const n = s?.hubUrl || Z, r = `${new URL(n).origin}/.well-known/openid-configuration`, i = await fetch(r, {
124
+ const r = s?.hubUrl || Z, n = `${new URL(r).origin}/.well-known/openid-configuration`, i = await fetch(n, {
125
125
  headers: {
126
126
  Accept: "application/json"
127
127
  }
@@ -166,7 +166,7 @@ function de() {
166
166
  return "info";
167
167
  }
168
168
  let C = de();
169
- function O(s) {
169
+ function $(s) {
170
170
  const e = `[reachy:${s}]`;
171
171
  return {
172
172
  debug: (...t) => {
@@ -183,11 +183,11 @@ function O(s) {
183
183
  }
184
184
  };
185
185
  }
186
- function I(s) {
186
+ function k(s) {
187
187
  return s * Math.PI / 180;
188
188
  }
189
189
  function ue(s, e, t) {
190
- const n = I(s), r = I(e), i = I(t), o = Math.cos(i), a = Math.sin(i), c = Math.cos(r), d = Math.sin(r), u = Math.cos(n), l = Math.sin(n);
190
+ const r = k(s), n = k(e), i = k(t), o = Math.cos(i), a = Math.sin(i), c = Math.cos(n), d = Math.sin(n), u = Math.cos(r), l = Math.sin(r);
191
191
  return [
192
192
  [o * c, o * d * l - a * u, o * d * u + a * l, 0],
193
193
  [a * c, a * d * l + o * u, a * d * u - o * l, 0],
@@ -205,11 +205,11 @@ class _e {
205
205
  */
206
206
  accept(e) {
207
207
  if (e.type !== "message_chunk") return e;
208
- const { id: t, index: n, count: r, data: i } = e;
209
- if (typeof t != "string" || typeof n != "number" || typeof r != "number" || typeof i != "string" || r < 1 || r > he)
208
+ const { id: t, index: r, count: n, data: i } = e;
209
+ if (typeof t != "string" || typeof r != "number" || typeof n != "number" || typeof i != "string" || n < 1 || n > he)
210
210
  return null;
211
211
  let o = this._partials.get(t);
212
- return n === 0 && (o = [], this._partials.set(t, o)), !o || n !== o.length ? (this._partials.delete(t), null) : (o.push(i), o.length < r ? null : (this._partials.delete(t), JSON.parse(o.join(""))));
212
+ return r === 0 && (o = [], this._partials.set(t, o)), !o || r !== o.length ? (this._partials.delete(t), null) : (o.push(i), o.length < n ? null : (this._partials.delete(t), JSON.parse(o.join(""))));
213
213
  }
214
214
  }
215
215
  const ee = 4e3;
@@ -232,12 +232,12 @@ class pe {
232
232
  * so its caller doesn't hang forever.
233
233
  */
234
234
  slotRoundtrip(e, t) {
235
- return new Promise((n) => {
236
- const r = this._replySlots.get(e);
237
- r && r(null);
235
+ return new Promise((r) => {
236
+ const n = this._replySlots.get(e);
237
+ n && n(null);
238
238
  let i;
239
239
  const o = (a) => {
240
- i !== void 0 && (clearTimeout(i), i = void 0), this._replySlots.get(e) === o && this._replySlots.delete(e), n(a);
240
+ i !== void 0 && (clearTimeout(i), i = void 0), this._replySlots.get(e) === o && this._replySlots.delete(e), r(a);
241
241
  };
242
242
  this._replySlots.set(e, o), i = setTimeout(() => o(null), ee), t();
243
243
  });
@@ -248,8 +248,8 @@ class pe {
248
248
  * branches use that to decide whether the message was theirs to swallow.
249
249
  */
250
250
  settleReplySlot(e, t) {
251
- const n = this._replySlots.get(e);
252
- return n ? (n(t), !0) : !1;
251
+ const r = this._replySlots.get(e);
252
+ return r ? (r(t), !0) : !1;
253
253
  }
254
254
  /* ─── JSON-RPC ───────────────────────────────────────────────────── */
255
255
  /**
@@ -258,13 +258,13 @@ class pe {
258
258
  * promise then rejects immediately), and await the matching
259
259
  * response; rejects on timeout. Same shape as `slotRoundtrip`.
260
260
  */
261
- rpcRoundtrip(e, t, n) {
262
- const r = `rpc-${++this._rpcCounter}`;
263
- return n(r) ? new Promise((i, o) => {
261
+ rpcRoundtrip(e, t, r) {
262
+ const n = `rpc-${++this._rpcCounter}`;
263
+ return r(n) ? new Promise((i, o) => {
264
264
  const a = setTimeout(() => {
265
- this._pendingRpc.delete(r), o(new Error(`rpcCall(${e}) timed out after ${t}ms`));
265
+ this._pendingRpc.delete(n), o(new Error(`rpcCall(${e}) timed out after ${t}ms`));
266
266
  }, t);
267
- this._pendingRpc.set(r, { resolve: i, reject: o, timer: a });
267
+ this._pendingRpc.set(n, { resolve: i, reject: o, timer: a });
268
268
  }) : Promise.reject(new Error(`rpcCall(${e}): data channel not open`));
269
269
  }
270
270
  /**
@@ -279,8 +279,8 @@ class pe {
279
279
  const t = this._pendingRpc.get(e.id);
280
280
  if (!t) return !0;
281
281
  if (this._pendingRpc.delete(e.id), clearTimeout(t.timer), "error" in e && e.error) {
282
- const n = e.error, r = new Error(n.message ?? "rpc error");
283
- r.reason = n.data?.reason, t.reject(r);
282
+ const r = e.error, n = new Error(r.message ?? "rpc error");
283
+ n.reason = r.data?.reason, t.reject(n);
284
284
  } else
285
285
  t.resolve(e.result);
286
286
  return !0;
@@ -288,13 +288,13 @@ class pe {
288
288
  /* ─── Motion completions (wake_up / goto_sleep) ──────────────────── */
289
289
  /** FIFO waiter for one `wake_up` / `goto_sleep` ack; rejects on timeout. */
290
290
  awaitMotion(e, t) {
291
- return new Promise((n, r) => {
291
+ return new Promise((r, n) => {
292
292
  const i = {
293
- resolve: n,
294
- reject: r,
293
+ resolve: r,
294
+ reject: n,
295
295
  timer: setTimeout(() => {
296
296
  const o = this._pendingMotion[e], a = o.indexOf(i);
297
- a !== -1 && o.splice(a, 1), r(new Error(`${e} timed out after ${t}ms`));
297
+ a !== -1 && o.splice(a, 1), n(new Error(`${e} timed out after ${t}ms`));
298
298
  }, t)
299
299
  };
300
300
  this._pendingMotion[e].push(i);
@@ -307,28 +307,28 @@ class pe {
307
307
  * message then falls through to the caller's other branches).
308
308
  */
309
309
  settleMotion(e, t) {
310
- const n = this._pendingMotion[e];
311
- if (t.completed === !0 && n.length > 0) {
312
- const r = n.shift();
313
- return clearTimeout(r.timer), r.resolve(), !0;
310
+ const r = this._pendingMotion[e];
311
+ if (t.completed === !0 && r.length > 0) {
312
+ const n = r.shift();
313
+ return clearTimeout(n.timer), n.resolve(), !0;
314
314
  }
315
- if (t.error && n.length > 0) {
316
- const r = n.shift();
317
- return clearTimeout(r.timer), r.reject(new Error(`${e}: ${t.error}`)), !0;
315
+ if (t.error && r.length > 0) {
316
+ const n = r.shift();
317
+ return clearTimeout(n.timer), n.reject(new Error(`${e}: ${t.error}`)), !0;
318
318
  }
319
319
  return !1;
320
320
  }
321
321
  /* ─── Broadcast waiters ──────────────────────────────────────────── */
322
322
  /** Await the first broadcast matching `predicate`; rejects on timeout. */
323
- awaitBroadcast(e, { timeoutMs: t = 5e3, debugLabel: n = "" } = {}) {
324
- return new Promise((r, i) => {
323
+ awaitBroadcast(e, { timeoutMs: t = 5e3, debugLabel: r = "" } = {}) {
324
+ return new Promise((n, i) => {
325
325
  const o = {
326
326
  predicate: e,
327
- resolve: r,
327
+ resolve: n,
328
328
  reject: i,
329
329
  timer: setTimeout(() => {
330
330
  const a = this._broadcastWaiters.indexOf(o);
331
- a !== -1 && this._broadcastWaiters.splice(a, 1), i(new P(`broadcast timeout (${t} ms): ${n}`));
331
+ a !== -1 && this._broadcastWaiters.splice(a, 1), i(new P(`broadcast timeout (${t} ms): ${r}`));
332
332
  }, t)
333
333
  };
334
334
  this._broadcastWaiters.push(o);
@@ -340,9 +340,9 @@ class pe {
340
340
  */
341
341
  matchBroadcast(e) {
342
342
  for (let t = this._broadcastWaiters.length - 1; t >= 0; t--) {
343
- const n = this._broadcastWaiters[t];
344
- if (n.predicate(e))
345
- return this._broadcastWaiters.splice(t, 1), clearTimeout(n.timer), n.resolve(e), !0;
343
+ const r = this._broadcastWaiters[t];
344
+ if (r.predicate(e))
345
+ return this._broadcastWaiters.splice(t, 1), clearTimeout(r.timer), r.resolve(e), !0;
346
346
  }
347
347
  return !1;
348
348
  }
@@ -362,10 +362,10 @@ class pe {
362
362
  clearTimeout(t.timer), t.reject(e);
363
363
  this._pendingRpc.clear();
364
364
  for (const t of Object.keys(this._pendingMotion)) {
365
- const n = this._pendingMotion[t];
366
- for (; n.length; ) {
367
- const r = n.shift();
368
- clearTimeout(r.timer), r.reject(e);
365
+ const r = this._pendingMotion[t];
366
+ for (; r.length; ) {
367
+ const n = r.shift();
368
+ clearTimeout(n.timer), n.reject(e);
369
369
  }
370
370
  }
371
371
  for (const t of this._broadcastWaiters)
@@ -373,7 +373,7 @@ class pe {
373
373
  this._broadcastWaiters = [];
374
374
  }
375
375
  }
376
- const M = O("session"), q = 3e3, G = 1e3, fe = 6e4, V = [0, 2e3, 4e3, 8e3, 8e3], me = 15e3, J = 1e3, ge = 2500, we = 8e3;
376
+ const M = $("session"), q = 3e3, G = 1e3, fe = 6e4, V = [0, 2e3, 4e3, 8e3, 8e3], me = 15e3, J = 1e3, ge = 2500, we = 8e3;
377
377
  class be {
378
378
  _deps;
379
379
  // ICE-blip debounce. All handler slots are scoped to the lifetime
@@ -470,16 +470,16 @@ class be {
470
470
  }
471
471
  this._iceGraceReason = t, this._iceGraceTimer = setTimeout(() => {
472
472
  this._iceGraceTimer = null;
473
- const n = this._iceGraceReason;
473
+ const r = this._iceGraceReason;
474
474
  this._iceGraceReason = null;
475
- const r = this._deps.iceState();
476
- if (!(r === "connected" || r === "completed")) {
477
- if (n === "disconnected" && r === "disconnected") {
475
+ const n = this._deps.iceState();
476
+ if (!(n === "connected" || n === "completed")) {
477
+ if (r === "disconnected" && n === "disconnected") {
478
478
  if (this.maybeBeginRedial(`ICE stuck in 'disconnected' for > ${e}ms`)) return;
479
479
  this._emitError(new Error(`ICE stuck in 'disconnected' for > ${e}ms`));
480
480
  return;
481
481
  }
482
- if (n === "failed" || r === "failed") {
482
+ if (r === "failed" || n === "failed") {
483
483
  const i = new Error("ICE connection failed");
484
484
  if (this._deps.rejectPendingSession(i)) {
485
485
  this._redialing || this._emitError(i);
@@ -502,19 +502,19 @@ class be {
502
502
  if (this._pendingVisibilityHandler) return;
503
503
  const e = Date.now(), t = () => {
504
504
  if (typeof document < "u" && document.hidden || (document.removeEventListener("visibilitychange", t), this._pendingVisibilityHandler = null, !this._deps.hasPc())) return;
505
- const n = this._deps.iceState();
506
- if (!(n === "connected" || n === "completed")) {
505
+ const r = this._deps.iceState();
506
+ if (!(r === "connected" || r === "completed")) {
507
507
  if (Date.now() - e > fe) {
508
- const r = new Error("Session expired while tab was backgrounded");
509
- if (this._deps.rejectPendingSession(r)) {
510
- this._redialing || this._emitError(r);
508
+ const n = new Error("Session expired while tab was backgrounded");
509
+ if (this._deps.rejectPendingSession(n)) {
510
+ this._redialing || this._emitError(n);
511
511
  return;
512
512
  }
513
513
  if (this.maybeBeginRedial("Session expired while tab was backgrounded")) return;
514
- this._emitError(r);
514
+ this._emitError(n);
515
515
  return;
516
516
  }
517
- if (n === "failed") {
517
+ if (r === "failed") {
518
518
  this._scheduleIceGrace(G, "failed");
519
519
  return;
520
520
  }
@@ -547,15 +547,15 @@ class be {
547
547
  if (this._onlineHandler || typeof window > "u") return;
548
548
  const e = () => this._deps.emit("networkOnline", {}), t = () => this._deps.emit("networkOffline", {});
549
549
  window.addEventListener("online", e), window.addEventListener("offline", t), this._onlineHandler = e, this._offlineHandler = t;
550
- const n = navigator.connection;
551
- if (n && typeof n.addEventListener == "function") {
552
- const r = () => this._deps.emit("networkChange", {
553
- effectiveType: n.effectiveType,
554
- downlink: n.downlink,
555
- rtt: n.rtt,
556
- saveData: n.saveData
550
+ const r = navigator.connection;
551
+ if (r && typeof r.addEventListener == "function") {
552
+ const n = () => this._deps.emit("networkChange", {
553
+ effectiveType: r.effectiveType,
554
+ downlink: r.downlink,
555
+ rtt: r.rtt,
556
+ saveData: r.saveData
557
557
  });
558
- n.addEventListener("change", r), this._connectionChangeHandler = r;
558
+ r.addEventListener("change", n), this._connectionChangeHandler = n;
559
559
  }
560
560
  }
561
561
  /** Counterpart to `installNetworkListeners`. */
@@ -592,10 +592,10 @@ class be {
592
592
  * which flip `_redialing` off via `cancelRedial`.
593
593
  */
594
594
  async _runRedialLoop(e, t) {
595
- const n = V.length;
595
+ const r = V.length;
596
596
  this._deps.teardownForRedial();
597
- for (let i = 1; i <= n; i++) {
598
- if (!this._redialing || (this._deps.emit("sessionReconnecting", { attempt: i, maxAttempts: n, cause: t }), await this._redialSleep(V[i - 1]), !this._redialing)) return;
597
+ for (let i = 1; i <= r; i++) {
598
+ if (!this._redialing || (this._deps.emit("sessionReconnecting", { attempt: i, maxAttempts: r, cause: t }), await this._redialSleep(V[i - 1]), !this._redialing)) return;
599
599
  try {
600
600
  if (this._deps.isSignalingDown() && await this._deps.reconnectSignaling(), !this._redialing || (await ye(
601
601
  this._deps.dial(e),
@@ -606,15 +606,15 @@ class be {
606
606
  return;
607
607
  } catch (o) {
608
608
  M.warn(
609
- `auto-reconnect attempt ${i}/${n} failed:`,
609
+ `auto-reconnect attempt ${i}/${r} failed:`,
610
610
  o
611
611
  ), this._redialing && this._deps.teardownForRedial();
612
612
  }
613
613
  }
614
614
  if (!this._redialing) return;
615
615
  this._redialing = !1;
616
- const r = `Auto-reconnect gave up after ${n} attempts (${t})`;
617
- M.warn(r), this._deps.emit("sessionStopped", { reason: "reconnect_failed", message: r }), this._emitError(new Error(r));
616
+ const n = `Auto-reconnect gave up after ${r} attempts (${t})`;
617
+ M.warn(n), this._deps.emit("sessionStopped", { reason: "reconnect_failed", message: n }), this._emitError(new Error(n));
618
618
  }
619
619
  /**
620
620
  * Cancellable backoff sleep — `cancelRedial` wakes it immediately.
@@ -667,25 +667,25 @@ class be {
667
667
  this._lastDcInboundAt = e, this._dcSilenceNudged = !1;
668
668
  return;
669
669
  }
670
- const n = e - this._lastDcInboundAt;
671
- if (n < ge) return;
670
+ const r = e - this._lastDcInboundAt;
671
+ if (r < ge) return;
672
672
  if (!this._dcSilenceNudged) {
673
673
  this._dcSilenceNudged = !0, this._deps.nudgeState();
674
674
  return;
675
675
  }
676
- if (n < we) return;
676
+ if (r < we) return;
677
677
  this._dcSilenceNudged = !1;
678
- const r = `No data-channel traffic for ${n}ms`;
679
- this.maybeBeginRedial(r) || (this.stopDcWatchdog(), this._emitError(new Error(r)));
678
+ const n = `No data-channel traffic for ${r}ms`;
679
+ this.maybeBeginRedial(n) || (this.stopDcWatchdog(), this._emitError(new Error(n)));
680
680
  }
681
681
  }
682
682
  function ye(s, e, t) {
683
683
  return Promise.race([
684
684
  s,
685
- new Promise((n, r) => setTimeout(() => r(new Error(t)), e))
685
+ new Promise((r, n) => setTimeout(() => n(new Error(t)), e))
686
686
  ]);
687
687
  }
688
- const z = "0.0.0-managed-by-ci", Se = O("sdk");
688
+ const z = "0.0.0-managed-by-ci", Se = $("sdk");
689
689
  function ve() {
690
690
  if (typeof window > "u" || !window.location.hash) return;
691
691
  const s = window.location.hash.startsWith("#") ? window.location.hash.slice(1) : window.location.hash;
@@ -697,9 +697,9 @@ function ve() {
697
697
  }
698
698
  const t = e.get("hf_token");
699
699
  if (!t) return;
700
- const n = e.get("hf_username") || "user", r = e.get("hf_token_expires"), i = r && !Number.isNaN(new Date(r).getTime()) ? r : new Date(Date.now() + 365 * 24 * 60 * 60 * 1e3).toISOString();
700
+ const r = e.get("hf_username") || "user", n = e.get("hf_token_expires"), i = n && !Number.isNaN(new Date(n).getTime()) ? n : new Date(Date.now() + 365 * 24 * 60 * 60 * 1e3).toISOString();
701
701
  try {
702
- sessionStorage.setItem("hf_token", t), sessionStorage.setItem("hf_username", n), sessionStorage.setItem("hf_token_expires", i);
702
+ sessionStorage.setItem("hf_token", t), sessionStorage.setItem("hf_username", r), sessionStorage.setItem("hf_token_expires", i);
703
703
  } catch (c) {
704
704
  Se.warn("could not persist pre-seeded HF credentials:", c);
705
705
  }
@@ -728,15 +728,15 @@ function Re() {
728
728
  }
729
729
  return null;
730
730
  }
731
- function Ie(s) {
731
+ function ke(s) {
732
732
  const e = s.split(`\r
733
733
  `);
734
734
  let t = !1;
735
- for (const n of e)
736
- if (n.startsWith("m=audio") ? t = !0 : n.startsWith("m=") && (t = !1), t && n === "a=sendrecv") return !0;
735
+ for (const r of e)
736
+ if (r.startsWith("m=audio") ? t = !0 : r.startsWith("m=") && (t = !1), t && r === "a=sendrecv") return !0;
737
737
  return !1;
738
738
  }
739
- const j = "hf_token", x = "hf_username", F = "hf_token_expires", U = "hf_token_last_seen", ke = 1440 * 60 * 1e3;
739
+ const j = "hf_token", x = "hf_username", F = "hf_token_expires", U = "hf_token_last_seen", Ie = 1440 * 60 * 1e3;
740
740
  function Ee(s) {
741
741
  try {
742
742
  sessionStorage.setItem(j, s.token), sessionStorage.setItem(x, s.username), sessionStorage.setItem(F, s.expires), sessionStorage.setItem(U, (/* @__PURE__ */ new Date()).toISOString());
@@ -745,22 +745,22 @@ function Ee(s) {
745
745
  }
746
746
  function Te(s = Date.now()) {
747
747
  try {
748
- const e = sessionStorage.getItem(j), t = sessionStorage.getItem(x), n = sessionStorage.getItem(F);
749
- if (!e || !n) return null;
750
- if (new Date(n).getTime() <= s)
751
- return N(), null;
752
- const r = sessionStorage.getItem(U);
753
- if (r !== null) {
754
- const i = new Date(r).getTime();
755
- if (!Number.isFinite(i) || s - i > ke)
756
- return N(), null;
748
+ const e = sessionStorage.getItem(j), t = sessionStorage.getItem(x), r = sessionStorage.getItem(F);
749
+ if (!e || !r) return null;
750
+ if (new Date(r).getTime() <= s)
751
+ return O(), null;
752
+ const n = sessionStorage.getItem(U);
753
+ if (n !== null) {
754
+ const i = new Date(n).getTime();
755
+ if (!Number.isFinite(i) || s - i > Ie)
756
+ return O(), null;
757
757
  }
758
- return sessionStorage.setItem(U, new Date(s).toISOString()), { token: e, username: t ?? "", expires: n };
758
+ return sessionStorage.setItem(U, new Date(s).toISOString()), { token: e, username: t ?? "", expires: r };
759
759
  } catch {
760
760
  return null;
761
761
  }
762
762
  }
763
- function N() {
763
+ function O() {
764
764
  try {
765
765
  sessionStorage.removeItem(j), sessionStorage.removeItem(x), sessionStorage.removeItem(F), sessionStorage.removeItem(U);
766
766
  } catch {
@@ -787,12 +787,12 @@ function De() {
787
787
  function K() {
788
788
  return "u" + Math.random().toString(36).slice(2, 11) + Date.now().toString(36);
789
789
  }
790
- function $(s) {
790
+ function N(s) {
791
791
  let e = "";
792
- for (let n = 0; n < s.length; n += 32768)
792
+ for (let r = 0; r < s.length; r += 32768)
793
793
  e += String.fromCharCode.apply(
794
794
  null,
795
- Array.from(s.subarray(n, n + 32768))
795
+ Array.from(s.subarray(r, r + 32768))
796
796
  );
797
797
  return btoa(e);
798
798
  }
@@ -800,7 +800,7 @@ async function Ue(s) {
800
800
  const e = new TextEncoder().encode(s), t = await new Response(
801
801
  new Blob([e]).stream().pipeThrough(new CompressionStream("gzip"))
802
802
  ).arrayBuffer();
803
- return $(new Uint8Array(t));
803
+ return N(new Uint8Array(t));
804
804
  }
805
805
  function Y(s) {
806
806
  const e = Math.round(Number(s) || 0);
@@ -829,7 +829,7 @@ function X(s) {
829
829
  return "wav-base64";
830
830
  }
831
831
  }
832
- const _ = O("sdk"), Q = 750, Le = 5e3;
832
+ const _ = $("sdk"), Q = 750, Le = 5e3;
833
833
  class Be extends EventTarget {
834
834
  // ─── Config ──────────────────────────────────────────────────────────
835
835
  _signalingUrl;
@@ -870,6 +870,8 @@ class Be extends EventTarget {
870
870
  _pendingRemoteIce = [];
871
871
  // ─── Audio ───────────────────────────────────────────────────────────
872
872
  _micStream = null;
873
+ _robotAudioTrack = null;
874
+ _outgoingAudioTrack = null;
873
875
  _micMuted = !0;
874
876
  _audioMuted = !0;
875
877
  _micSupported = !1;
@@ -913,8 +915,8 @@ class Be extends EventTarget {
913
915
  selectedRobotId: () => this._selectedRobotId,
914
916
  rejectPendingSession: (t) => {
915
917
  if (!this._sessionReject) return !1;
916
- const n = this._sessionReject;
917
- return this._sessionResolve = null, this._sessionReject = null, n(t), !0;
918
+ const r = this._sessionReject;
919
+ return this._sessionResolve = null, this._sessionReject = null, r(t), !0;
918
920
  },
919
921
  reconnectSignaling: () => this.connect(),
920
922
  // The private dial skips the public startSession()'s
@@ -924,7 +926,7 @@ class Be extends EventTarget {
924
926
  nudgeState: () => {
925
927
  this.requestState();
926
928
  },
927
- emit: (t, n) => this._emit(t, n)
929
+ emit: (t, r) => this._emit(t, r)
928
930
  }, { autoReconnect: e.autoReconnect !== !1 });
929
931
  }
930
932
  // ─── Read-only properties ────────────────────────────────────────────
@@ -967,6 +969,14 @@ class Be extends EventTarget {
967
969
  get peerConnection() {
968
970
  return this._pc;
969
971
  }
972
+ /**
973
+ * The robot's microphone as a live audio track, or `null` until the
974
+ * session's audio arrives (see the `audioTrack` event). Feed it to Web
975
+ * Audio, `MediaRecorder` or `SpeechRecognition.start(track)`.
976
+ */
977
+ get robotAudioTrack() {
978
+ return this._robotAudioTrack;
979
+ }
970
980
  /**
971
981
  * Build version of this SDK (npm package `version`), injected from
972
982
  * package.json at build time. This is the JS SDK's OWN version and is
@@ -989,12 +999,12 @@ class Be extends EventTarget {
989
999
  * SDK is already `connected` still triggers the auto-start.
990
1000
  */
991
1001
  _maybeAutoStart() {
992
- if (!this._autoStartFromUrl || this._autoStartAttempted || !this._preselectedRobotId || this._state !== "connected" || !this._robots.find((n) => n.id === this._preselectedRobotId)) return;
1002
+ if (!this._autoStartFromUrl || this._autoStartAttempted || !this._preselectedRobotId || this._state !== "connected" || !this._robots.find((r) => r.id === this._preselectedRobotId)) return;
993
1003
  this._autoStartAttempted = !0;
994
1004
  const t = this._preselectedRobotId;
995
1005
  setTimeout(() => {
996
- this._state === "connected" && this.startSession(t).catch((n) => {
997
- _.warn("autoStartFromUrl: startSession rejected:", n);
1006
+ this._state === "connected" && this.startSession(t).catch((r) => {
1007
+ _.warn("autoStartFromUrl: startSession rejected:", r);
998
1008
  });
999
1009
  }, 0);
1000
1010
  }
@@ -1011,8 +1021,8 @@ class Be extends EventTarget {
1011
1021
  username: this._username ?? "",
1012
1022
  expires: typeof this._tokenExpires == "string" ? this._tokenExpires : this._tokenExpires.toISOString()
1013
1023
  }), !0;
1014
- const n = Te();
1015
- return n && n.username ? (this._token = n.token, this._username = n.username, this._tokenExpires = n.expires, !0) : !1;
1024
+ const r = Te();
1025
+ return r && r.username ? (this._token = r.token, this._username = r.username, this._tokenExpires = r.expires, !0) : !1;
1016
1026
  } catch (e) {
1017
1027
  return _.error("authenticate failed:", e), !1;
1018
1028
  }
@@ -1020,15 +1030,15 @@ class Be extends EventTarget {
1020
1030
  async login(e) {
1021
1031
  const t = {};
1022
1032
  this._clientId && (t.clientId = this._clientId);
1023
- let n = await ce(t);
1033
+ let r = await ce(t);
1024
1034
  if (e?.prompt) {
1025
- const r = new URL(n);
1026
- r.searchParams.set("prompt", e.prompt), n = r.toString();
1035
+ const n = new URL(r);
1036
+ n.searchParams.set("prompt", e.prompt), r = n.toString();
1027
1037
  }
1028
- window.location.href = n;
1038
+ window.location.href = r;
1029
1039
  }
1030
1040
  logout() {
1031
- N(), this._username = null, this._tokenExpires = null, this.disconnect();
1041
+ O(), this._username = null, this._tokenExpires = null, this.disconnect();
1032
1042
  }
1033
1043
  // ─── Lifecycle ───────────────────────────────────────────────────────
1034
1044
  async connect(e) {
@@ -1044,12 +1054,12 @@ class Be extends EventTarget {
1044
1054
  headers: { Authorization: `Bearer ${this._token}` }
1045
1055
  }
1046
1056
  );
1047
- } catch (n) {
1048
- throw this._sseAbortController = null, n;
1057
+ } catch (r) {
1058
+ throw this._sseAbortController = null, r;
1049
1059
  }
1050
1060
  if (!t.ok)
1051
1061
  throw this._sseAbortController = null, new Error(`HTTP ${t.status}`);
1052
- return new Promise((n, r) => {
1062
+ return new Promise((r, n) => {
1053
1063
  let i = !1;
1054
1064
  const o = t.body.getReader(), a = new TextDecoder();
1055
1065
  let c = "";
@@ -1070,25 +1080,25 @@ class Be extends EventTarget {
1070
1080
  type: "setPeerStatus",
1071
1081
  roles: ["listener"],
1072
1082
  meta: { name: this._appName }
1073
- }), this._emit("connected", { peerId: f.peerId }), n()), this._handleSignalingMessage(f);
1083
+ }), this._emit("connected", { peerId: f.peerId }), r()), this._handleSignalingMessage(f);
1074
1084
  } catch {
1075
1085
  }
1076
1086
  }
1077
1087
  } catch (u) {
1078
1088
  if (u.name !== "AbortError" && this._emit("error", { source: "signaling", error: u }), !i) {
1079
- r(u);
1089
+ n(u);
1080
1090
  return;
1081
1091
  }
1082
1092
  }
1083
- this._state !== "disconnected" && (this._state = "disconnected", this._emit("disconnected", { reason: "SSE closed" })), i || r(new Error("Connection closed before welcome"));
1093
+ this._state !== "disconnected" && (this._state = "disconnected", this._emit("disconnected", { reason: "SSE closed" })), i || n(new Error("Connection closed before welcome"));
1084
1094
  })();
1085
1095
  });
1086
1096
  }
1087
1097
  async autoConnect(e = {}) {
1088
1098
  const {
1089
1099
  token: t,
1090
- pickRobot: n,
1091
- autoPickIfSingle: r = !0,
1100
+ pickRobot: r,
1101
+ autoPickIfSingle: n = !0,
1092
1102
  filterBusy: i = !0,
1093
1103
  wakeOnConnect: o = !0
1094
1104
  } = e;
@@ -1121,10 +1131,10 @@ class Be extends EventTarget {
1121
1131
  const u = await this._fetchOwnedRobots({ filterBusy: i });
1122
1132
  if (u.length === 0)
1123
1133
  throw new Error("No reachable robots");
1124
- if (r && u.length === 1 && !u[0].busy)
1134
+ if (n && u.length === 1 && !u[0].busy)
1125
1135
  c = u[0].id, d = u[0].name;
1126
- else if (n) {
1127
- const l = await n(u);
1136
+ else if (r) {
1137
+ const l = await r(u);
1128
1138
  if (!l) throw new Error("Robot selection cancelled");
1129
1139
  c = l, d = u.find((m) => m.id === l)?.name ?? null;
1130
1140
  } else
@@ -1149,11 +1159,11 @@ class Be extends EventTarget {
1149
1159
  headers: { Authorization: `Bearer ${this._token}` }
1150
1160
  });
1151
1161
  if (!t.ok) throw new Error(`HTTP ${t.status}`);
1152
- const n = await t.json(), r = /* @__PURE__ */ new Map();
1153
- for (const i of n.robots || []) {
1162
+ const r = await t.json(), n = /* @__PURE__ */ new Map();
1163
+ for (const i of r.robots || []) {
1154
1164
  if (e && i.busy) continue;
1155
1165
  const o = i.meta?.install_id ?? i.meta?.hardware_id ?? i.peerId;
1156
- r.set(o, {
1166
+ n.set(o, {
1157
1167
  id: i.peerId,
1158
1168
  name: i.robotName ?? i.meta?.name ?? null,
1159
1169
  busy: !!i.busy,
@@ -1162,26 +1172,26 @@ class Be extends EventTarget {
1162
1172
  lastSeenAgeSeconds: i.last_seen_age_seconds ?? null
1163
1173
  });
1164
1174
  }
1165
- return Array.from(r.values()).sort(
1175
+ return Array.from(n.values()).sort(
1166
1176
  (i, o) => (i.lastSeenAgeSeconds ?? 1 / 0) - (o.lastSeenAgeSeconds ?? 1 / 0)
1167
1177
  );
1168
1178
  } catch (t) {
1169
- return _.warn("/api/robot-status unavailable, using SSE list:", t), (this._robots || []).map((n) => ({
1170
- id: n.id,
1171
- name: n.meta?.name ?? null,
1179
+ return _.warn("/api/robot-status unavailable, using SSE list:", t), (this._robots || []).map((r) => ({
1180
+ id: r.id,
1181
+ name: r.meta?.name ?? null,
1172
1182
  busy: !1,
1173
1183
  activeApp: null,
1174
- meta: n.meta ?? {},
1184
+ meta: r.meta ?? {},
1175
1185
  lastSeenAgeSeconds: null
1176
1186
  }));
1177
1187
  }
1178
1188
  }
1179
1189
  _waitForRobotInList(e, t) {
1180
- return this._robots?.find((n) => n.id === e) ? Promise.resolve() : new Promise((n, r) => {
1190
+ return this._robots?.find((r) => r.id === e) ? Promise.resolve() : new Promise((r, n) => {
1181
1191
  const i = () => {
1182
- this._robots?.find((a) => a.id === e) && (this.removeEventListener("robotsChanged", i), clearTimeout(o), n());
1192
+ this._robots?.find((a) => a.id === e) && (this.removeEventListener("robotsChanged", i), clearTimeout(o), r());
1183
1193
  }, o = setTimeout(() => {
1184
- this.removeEventListener("robotsChanged", i), r(new Error(`Timeout waiting for robot ${e} in list`));
1194
+ this.removeEventListener("robotsChanged", i), n(new Error(`Timeout waiting for robot ${e} in list`));
1185
1195
  }, t);
1186
1196
  this.addEventListener("robotsChanged", i);
1187
1197
  });
@@ -1193,9 +1203,9 @@ class Be extends EventTarget {
1193
1203
  if (this._state !== "connected") throw new Error("Not connected");
1194
1204
  this._selectedRobotId = e, this._iceConnected = !1, this._dcOpen = !1, this._micSupported = !1, this._pendingRemoteIce = [];
1195
1205
  try {
1196
- const t = window, n = t.AudioContext ?? t.webkitAudioContext;
1197
- if (!n) throw new Error("AudioContext not supported");
1198
- const r = new n(), i = r.createMediaStreamDestination(), o = r.createOscillator(), a = r.createGain();
1206
+ const t = window, r = t.AudioContext ?? t.webkitAudioContext;
1207
+ if (!r) throw new Error("AudioContext not supported");
1208
+ const n = new r(), i = n.createMediaStreamDestination(), o = n.createOscillator(), a = n.createGain();
1199
1209
  a.gain.value = 0, o.connect(a).connect(i), o.start();
1200
1210
  const c = i.stream;
1201
1211
  c.getAudioTracks().forEach((d) => {
@@ -1206,48 +1216,48 @@ class Be extends EventTarget {
1206
1216
  }
1207
1217
  return this._pc = new RTCPeerConnection({
1208
1218
  iceServers: [{ urls: "stun:stun.l.google.com:19302" }]
1209
- }), this._supervisor.installNetworkListeners(), new Promise((t, n) => {
1210
- this._sessionResolve = t, this._sessionReject = n, this._pc.ontrack = (r) => {
1211
- if (r.track.kind === "video") {
1219
+ }), this._supervisor.installNetworkListeners(), new Promise((t, r) => {
1220
+ this._sessionResolve = t, this._sessionReject = r, this._pc.ontrack = (n) => {
1221
+ if (n.track.kind === "video") {
1212
1222
  const i = this._videoJitterBufferTargetMs;
1213
1223
  try {
1214
- r.receiver.jitterBufferTarget = i;
1224
+ n.receiver.jitterBufferTarget = i;
1215
1225
  } catch {
1216
1226
  }
1217
1227
  try {
1218
- r.receiver.playoutDelayHint = i / 1e3;
1228
+ n.receiver.playoutDelayHint = i / 1e3;
1219
1229
  } catch {
1220
1230
  }
1221
- this._emit("videoTrack", { track: r.track, stream: r.streams[0] });
1222
- }
1223
- }, this._pc.onicecandidate = async (r) => {
1224
- r.candidate && this._sessionId && await this._sendToServer({
1231
+ this._emit("videoTrack", { track: n.track, stream: n.streams[0] });
1232
+ } else n.track.kind === "audio" && (this._robotAudioTrack = n.track, this._emit("audioTrack", { track: n.track, stream: n.streams[0] }));
1233
+ }, this._pc.onicecandidate = async (n) => {
1234
+ n.candidate && this._sessionId && await this._sendToServer({
1225
1235
  type: "peer",
1226
1236
  sessionId: this._sessionId,
1227
1237
  ice: {
1228
- candidate: r.candidate.candidate,
1229
- sdpMLineIndex: r.candidate.sdpMLineIndex,
1230
- sdpMid: r.candidate.sdpMid
1238
+ candidate: n.candidate.candidate,
1239
+ sdpMLineIndex: n.candidate.sdpMLineIndex,
1240
+ sdpMid: n.candidate.sdpMid
1231
1241
  }
1232
1242
  });
1233
1243
  }, this._pc.oniceconnectionstatechange = () => {
1234
- const r = this._pc?.iceConnectionState;
1235
- if (r) {
1236
- if (this._emit("iceStateChange", { state: r }), r === "connected" || r === "completed") {
1244
+ const n = this._pc?.iceConnectionState;
1245
+ if (n) {
1246
+ if (this._emit("iceStateChange", { state: n }), n === "connected" || n === "completed") {
1237
1247
  this._supervisor.onIceHealed(), this._iceConnected = !0, this._checkSessionReady();
1238
1248
  return;
1239
1249
  }
1240
- if (r === "disconnected") {
1250
+ if (n === "disconnected") {
1241
1251
  this._supervisor.onIceDisconnected();
1242
1252
  return;
1243
1253
  }
1244
- if (r === "failed") {
1254
+ if (n === "failed") {
1245
1255
  this._supervisor.onIceFailed();
1246
1256
  return;
1247
1257
  }
1248
1258
  }
1249
- }, this._pc.ondatachannel = (r) => {
1250
- const i = r.channel;
1259
+ }, this._pc.ondatachannel = (n) => {
1260
+ const i = n.channel;
1251
1261
  if (i.label === "pose") {
1252
1262
  this._lastPoseSeq = null, i.onmessage = (a) => {
1253
1263
  const c = JSON.parse(a.data);
@@ -1267,12 +1277,12 @@ class Be extends EventTarget {
1267
1277
  const c = o.accept(JSON.parse(a.data));
1268
1278
  c && this._handleRobotMessage(c);
1269
1279
  };
1270
- }, this._sendToServer({ type: "startSession", peerId: e }).then((r) => {
1271
- if (r?.type === "sessionRejected") {
1272
- this._failSessionRejected(r);
1280
+ }, this._sendToServer({ type: "startSession", peerId: e }).then((n) => {
1281
+ if (n?.type === "sessionRejected") {
1282
+ this._failSessionRejected(n);
1273
1283
  return;
1274
1284
  }
1275
- r?.sessionId && (this._sessionId = r.sessionId);
1285
+ n?.sessionId && (this._sessionId = n.sessionId);
1276
1286
  });
1277
1287
  });
1278
1288
  }
@@ -1289,10 +1299,10 @@ class Be extends EventTarget {
1289
1299
  */
1290
1300
  _closeTransport(e) {
1291
1301
  if (this._pending.settleAll(e), this._sessionReject) {
1292
- const n = this._sessionReject;
1293
- this._sessionResolve = null, this._sessionReject = null, n(e);
1302
+ const r = this._sessionReject;
1303
+ this._sessionResolve = null, this._sessionReject = null, r(e);
1294
1304
  }
1295
- this._sessionResolve = null, this._supervisor.clearIceGrace(), this._supervisor.uninstallNetworkListeners(), this._supervisor.stopDcWatchdog(), this._stateRefreshInterval && (clearInterval(this._stateRefreshInterval), this._stateRefreshInterval = null), this._latencyMonitorId && (clearInterval(this._latencyMonitorId), this._latencyMonitorId = null), this._micStream && (this._micStream.getTracks().forEach((n) => n.stop()), this._micStream = null), this._micMuted = !0, this._micSupported = !1, this._pc && (this._pc.close(), this._pc = null), this._dc && (this._dc.close(), this._dc = null), this._iceConnected = !1, this._dcOpen = !1;
1305
+ this._sessionResolve = null, this._supervisor.clearIceGrace(), this._supervisor.uninstallNetworkListeners(), this._supervisor.stopDcWatchdog(), this._stateRefreshInterval && (clearInterval(this._stateRefreshInterval), this._stateRefreshInterval = null), this._latencyMonitorId && (clearInterval(this._latencyMonitorId), this._latencyMonitorId = null), this._micStream && (this._micStream.getTracks().forEach((r) => r.stop()), this._micStream = null), this._robotAudioTrack = null, this._micMuted = !0, this._micSupported = !1, this._pc && (this._pc.close(), this._pc = null), this._dc && (this._dc.close(), this._dc = null), this._iceConnected = !1, this._dcOpen = !1;
1296
1306
  const t = this._sessionId;
1297
1307
  return this._sessionId = null, t;
1298
1308
  }
@@ -1303,12 +1313,12 @@ class Be extends EventTarget {
1303
1313
  t.reason = e.reason ?? null, t.activeApp = e.activeApp ?? null, this._closeTransport(t), this._supervisor.redialing || this._emit("sessionRejected", { reason: e.reason, activeApp: e.activeApp });
1304
1314
  }
1305
1315
  async stopSession() {
1306
- this._supervisor.cancelRedial(), this._logSubscribers.clear(), this._updateProgressSubscribers.clear();
1316
+ this._supervisor.cancelRedial(), this._logSubscribers.clear(), this._updateProgressSubscribers.clear(), this._outgoingAudioTrack = null;
1307
1317
  const e = this._closeTransport(new Error("Session stopped"));
1308
1318
  e && await this._sendToServer({ type: "endSession", sessionId: e }), this._state === "streaming" && (this._state = "connected", this._emit("sessionStopped", { reason: "user" }));
1309
1319
  }
1310
1320
  disconnect() {
1311
- this._supervisor.cancelRedial(), this._sseAbortController && (this._sseAbortController.abort(), this._sseAbortController = null), this._logSubscribers.clear(), this._updateProgressSubscribers.clear();
1321
+ this._supervisor.cancelRedial(), this._sseAbortController && (this._sseAbortController.abort(), this._sseAbortController = null), this._logSubscribers.clear(), this._updateProgressSubscribers.clear(), this._outgoingAudioTrack = null;
1312
1322
  const e = this._closeTransport(new Error("Disconnected"));
1313
1323
  e && this._token && this._sendToServer({ type: "endSession", sessionId: e }), this._robots = [], this._state = "disconnected", this._emit("disconnected", { reason: "user" });
1314
1324
  }
@@ -1391,32 +1401,32 @@ class Be extends EventTarget {
1391
1401
  * @returns `true` if the command was queued on the data channel,
1392
1402
  * `false` if the channel is not open.
1393
1403
  */
1394
- setTarget({ head: e, antennas: t, body_yaw: n } = {}) {
1395
- const r = { type: "set_full_target" };
1404
+ setTarget({ head: e, antennas: t, body_yaw: r } = {}) {
1405
+ const n = { type: "set_full_target" };
1396
1406
  if (e !== void 0) {
1397
1407
  if (!Array.isArray(e) || e.length !== 16 || !e.every((i) => Number.isFinite(i)))
1398
1408
  throw new TypeError(
1399
1409
  `setTarget: head must be a 16-element flat row-major 4×4 matrix of finite numbers; got ${Array.isArray(e) ? `Array(${e.length})` : typeof e}`
1400
1410
  );
1401
- r.head = e;
1411
+ n.head = e;
1402
1412
  }
1403
1413
  if (t !== void 0) {
1404
1414
  if (!Array.isArray(t) || t.length !== 2 || !t.every((i) => Number.isFinite(i)))
1405
1415
  throw new TypeError(
1406
1416
  `setTarget: antennas must be [rightRad, leftRad] (2 finite numbers); got ${Array.isArray(t) ? `Array(${t.length})` : typeof t}`
1407
1417
  );
1408
- r.antennas = t;
1418
+ n.antennas = t;
1409
1419
  }
1410
- if (n !== void 0) {
1411
- if (!Number.isFinite(n))
1420
+ if (r !== void 0) {
1421
+ if (!Number.isFinite(r))
1412
1422
  throw new TypeError(
1413
- `setTarget: body_yaw must be a finite number (radians); got ${n}`
1423
+ `setTarget: body_yaw must be a finite number (radians); got ${r}`
1414
1424
  );
1415
- r.body_yaw = n;
1425
+ n.body_yaw = r;
1416
1426
  }
1417
- return this._sendCommand(r);
1427
+ return this._sendCommand(n);
1418
1428
  }
1419
- gotoTarget({ head: e, antennas: t, body_yaw: n, duration: r }) {
1429
+ gotoTarget({ head: e, antennas: t, body_yaw: r, duration: n }) {
1420
1430
  const i = { type: "goto_target" };
1421
1431
  if (e !== void 0) {
1422
1432
  if (!Array.isArray(e) || e.length !== 16 || !e.every((o) => Number.isFinite(o)))
@@ -1432,40 +1442,40 @@ class Be extends EventTarget {
1432
1442
  );
1433
1443
  i.antennas = t;
1434
1444
  }
1435
- if (n !== void 0) {
1436
- if (!Number.isFinite(n))
1445
+ if (r !== void 0) {
1446
+ if (!Number.isFinite(r))
1437
1447
  throw new TypeError(
1438
- `gotoTarget: body_yaw must be a finite number (radians); got ${n}`
1448
+ `gotoTarget: body_yaw must be a finite number (radians); got ${r}`
1439
1449
  );
1440
- i.body_yaw = n;
1450
+ i.body_yaw = r;
1441
1451
  }
1442
- if (!Number.isFinite(r) || r <= 0)
1452
+ if (!Number.isFinite(n) || n <= 0)
1443
1453
  throw new TypeError(
1444
- `gotoTarget: duration must be a positive finite number (seconds); got ${r}`
1454
+ `gotoTarget: duration must be a positive finite number (seconds); got ${n}`
1445
1455
  );
1446
- return i.duration = r, this._sendCommand(i);
1456
+ return i.duration = n, this._sendCommand(i);
1447
1457
  }
1448
- setHeadRpyDeg(e, t, n) {
1449
- return this.setTarget({ head: ue(e, t, n).flat() });
1458
+ setHeadRpyDeg(e, t, r) {
1459
+ return this.setTarget({ head: ue(e, t, r).flat() });
1450
1460
  }
1451
1461
  setAntennasDeg(e, t) {
1452
- return this.setTarget({ antennas: [I(e), I(t)] });
1462
+ return this.setTarget({ antennas: [k(e), k(t)] });
1453
1463
  }
1454
1464
  setBodyYawDeg(e) {
1455
- return this.setTarget({ body_yaw: I(e) });
1465
+ return this.setTarget({ body_yaw: k(e) });
1456
1466
  }
1457
1467
  playSound(e) {
1458
1468
  return this._sendCommand({ type: "play_sound", file: e });
1459
1469
  }
1460
1470
  playRecordedMove(e, {
1461
1471
  dataset: t,
1462
- initialGotoDuration: n
1472
+ initialGotoDuration: r
1463
1473
  } = {}) {
1464
1474
  return this._sendCommand({
1465
1475
  type: "play_recorded_move",
1466
1476
  move_name: e,
1467
1477
  ...t ? { dataset_name: t } : {},
1468
- ...n && n > 0 ? { initial_goto_duration: n } : {}
1478
+ ...r && r > 0 ? { initial_goto_duration: r } : {}
1469
1479
  });
1470
1480
  }
1471
1481
  /**
@@ -1492,11 +1502,11 @@ class Be extends EventTarget {
1492
1502
  */
1493
1503
  preloadDatasetAndWait(e, { timeoutMs: t = 12e4 } = {}) {
1494
1504
  return this.preloadDataset(e) ? this._pending.awaitBroadcast(
1495
- (n) => n.command === "preload_dataset" && n.dataset_name === e,
1505
+ (r) => r.command === "preload_dataset" && r.dataset_name === e,
1496
1506
  { timeoutMs: t, debugLabel: `preload_dataset(${e})` }
1497
- ).then((n) => n.status === "ok").catch((n) => {
1498
- if (n instanceof P) return null;
1499
- throw n;
1507
+ ).then((r) => r.status === "ok").catch((r) => {
1508
+ if (r instanceof P) return null;
1509
+ throw r;
1500
1510
  }) : Promise.reject(new Error("Data channel not open"));
1501
1511
  }
1502
1512
  clearIncomingAudio() {
@@ -1555,11 +1565,11 @@ class Be extends EventTarget {
1555
1565
  return e === "enabled" || e === "gravity_compensation";
1556
1566
  }
1557
1567
  async ensureAwake(e = 1e3) {
1558
- if (this._robotState?.motor_mode === void 0 && await new Promise((n) => {
1559
- const r = () => {
1560
- this.removeEventListener("state", r), clearTimeout(i), n();
1561
- }, i = setTimeout(r, e);
1562
- this.addEventListener("state", r), this.requestState();
1568
+ if (this._robotState?.motor_mode === void 0 && await new Promise((r) => {
1569
+ const n = () => {
1570
+ this.removeEventListener("state", n), clearTimeout(i), r();
1571
+ }, i = setTimeout(n, e);
1572
+ this.addEventListener("state", n), this.requestState();
1563
1573
  }), this._robotState?.motor_mode === "gravity_compensation")
1564
1574
  return _.info("ensureAwake: gravity compensation inherited, flipping to enabled (no emote)"), this.setMotorMode("enabled"), this.requestState(), !0;
1565
1575
  if (this.isAwake())
@@ -1568,8 +1578,8 @@ class Be extends EventTarget {
1568
1578
  const t = Date.now();
1569
1579
  try {
1570
1580
  await this.wakeUp({ timeoutMs: Le }), _.info(`ensureAwake: wake-up trajectory done in ${Date.now() - t}ms`);
1571
- } catch (n) {
1572
- _.warn(`ensureAwake: wake-up not confirmed after ${Date.now() - t}ms (continuing):`, n);
1581
+ } catch (r) {
1582
+ _.warn(`ensureAwake: wake-up not confirmed after ${Date.now() - t}ms (continuing):`, r);
1573
1583
  }
1574
1584
  return !0;
1575
1585
  }
@@ -1659,7 +1669,7 @@ class Be extends EventTarget {
1659
1669
  return this._slotRoundtrip("delete_hf_token", { type: "delete_hf_token" });
1660
1670
  }
1661
1671
  applyAudioConfig(e, { verify: t = !0 } = {}) {
1662
- return this._slotRoundtrip("apply_audio_config", { type: "apply_audio_config", config: e, verify: t }).then((n) => n === !0);
1672
+ return this._slotRoundtrip("apply_audio_config", { type: "apply_audio_config", config: e, verify: t }).then((r) => r === !0);
1663
1673
  }
1664
1674
  readAudioParameter(e) {
1665
1675
  return this._slotRoundtrip("read_audio_parameter", { type: "read_audio_parameter", name: e });
@@ -1695,11 +1705,11 @@ class Be extends EventTarget {
1695
1705
  * reach this matcher - use the typed wrappers for those. Pass `match`
1696
1706
  * for replies that don't follow the `command` echo convention.
1697
1707
  */
1698
- request(e, { timeoutMs: t = ee, match: n } = {}) {
1708
+ request(e, { timeoutMs: t = ee, match: r } = {}) {
1699
1709
  if (!this._sendCommand(e))
1700
1710
  return Promise.reject(new Error("Data channel not open"));
1701
- const r = n ?? ((i) => i.command === e.type);
1702
- return this._pending.awaitBroadcast(r, { timeoutMs: t, debugLabel: `request(${e.type})` }).catch((i) => {
1711
+ const n = r ?? ((i) => i.command === e.type);
1712
+ return this._pending.awaitBroadcast(n, { timeoutMs: t, debugLabel: `request(${e.type})` }).catch((i) => {
1703
1713
  if (i instanceof P) return null;
1704
1714
  throw i;
1705
1715
  });
@@ -1707,11 +1717,11 @@ class Be extends EventTarget {
1707
1717
  subscribeLogs({ onLine: e, onError: t }) {
1708
1718
  if (typeof e != "function")
1709
1719
  throw new TypeError("subscribeLogs: onLine callback is required");
1710
- const n = { onLine: e, onError: t }, r = this._logSubscribers.size === 0;
1711
- this._logSubscribers.add(n), r && this._sendCommand({ type: "subscribe_logs" });
1720
+ const r = { onLine: e, onError: t }, n = this._logSubscribers.size === 0;
1721
+ this._logSubscribers.add(r), n && this._sendCommand({ type: "subscribe_logs" });
1712
1722
  let i = !1;
1713
1723
  return () => {
1714
- i || (i = !0, this._logSubscribers.delete(n), this._logSubscribers.size === 0 && this._sendCommand({ type: "unsubscribe_logs" }));
1724
+ i || (i = !0, this._logSubscribers.delete(r), this._logSubscribers.size === 0 && this._sendCommand({ type: "unsubscribe_logs" }));
1715
1725
  };
1716
1726
  }
1717
1727
  requestState() {
@@ -1745,24 +1755,49 @@ class Be extends EventTarget {
1745
1755
  t.enabled = !e;
1746
1756
  });
1747
1757
  }
1758
+ /**
1759
+ * Stream an audio track to the robot's speaker in real time (TTS output,
1760
+ * a WebAudio graph, the user's own mic for teleop…). Pass `null` to go
1761
+ * back to silence. The track survives auto-reconnects; the app keeps
1762
+ * ownership of it (the SDK never stops it).
1763
+ *
1764
+ * Resolves `true` once the track is on the wire, `false` when there is
1765
+ * no live session yet (it is then applied as soon as one starts) or when
1766
+ * the robot didn't offer two-way audio. Cleared by `stopSession()` /
1767
+ * `disconnect()`. `setMicMuted()` only mutes the SDK's placeholder, not
1768
+ * this track — stop or disable the track itself to go quiet.
1769
+ * For clips that must stay in sync with motion, prefer
1770
+ * `playMove(motion, { audioBlob })` or `uploadAudio` + `playUploadedAudio`.
1771
+ */
1772
+ async setOutgoingAudioTrack(e) {
1773
+ if (e && e.kind !== "audio")
1774
+ throw new TypeError(`setOutgoingAudioTrack: expected an audio track, got "${e.kind}"`);
1775
+ return this._outgoingAudioTrack = e, this._applyOutgoingAudioTrack();
1776
+ }
1777
+ async _applyOutgoingAudioTrack() {
1778
+ const e = this._pc?.getTransceivers().find((r) => r.receiver.track.kind === "audio")?.sender;
1779
+ if (!e || !this._micSupported) return !1;
1780
+ const t = this._micStream?.getAudioTracks()[0] ?? null;
1781
+ return await e.replaceTrack(this._outgoingAudioTrack ?? t), !0;
1782
+ }
1748
1783
  // ─── Video helper ────────────────────────────────────────────────────
1749
1784
  attachVideo(e) {
1750
1785
  this._videoElement = e, e.muted = this._audioMuted;
1751
- const t = (r) => {
1752
- const i = r;
1786
+ const t = (n) => {
1787
+ const i = n;
1753
1788
  e.srcObject = i.detail.stream, e.playsInline = !0, "requestVideoFrameCallback" in e && this._startLatencyMonitor(e);
1754
- }, n = () => {
1789
+ }, r = () => {
1755
1790
  e.srcObject = null;
1756
1791
  };
1757
- return this.addEventListener("videoTrack", t), this.addEventListener("sessionStopped", n), () => {
1758
- this.removeEventListener("videoTrack", t), this.removeEventListener("sessionStopped", n), this._latencyMonitorId && (clearInterval(this._latencyMonitorId), this._latencyMonitorId = null), e.srcObject = null, this._videoElement = null;
1792
+ return this.addEventListener("videoTrack", t), this.addEventListener("sessionStopped", r), () => {
1793
+ this.removeEventListener("videoTrack", t), this.removeEventListener("sessionStopped", r), this._latencyMonitorId && (clearInterval(this._latencyMonitorId), this._latencyMonitorId = null), e.srcObject = null, this._videoElement = null;
1759
1794
  };
1760
1795
  }
1761
1796
  // ─── Daemon-side recorded-move playback ──────────────────────────────
1762
1797
  async playMove(e, {
1763
1798
  audioBlob: t = null,
1764
- audioLeadMs: n = -100,
1765
- description: r = "move",
1799
+ audioLeadMs: r = -100,
1800
+ description: n = "move",
1766
1801
  encoding: i = "gzip+base64",
1767
1802
  playFrequency: o = 100,
1768
1803
  initialGotoDuration: a = 0,
@@ -1779,7 +1814,7 @@ class Be extends EventTarget {
1779
1814
  const l = K();
1780
1815
  this._activeMoveUploadId = l;
1781
1816
  const m = {
1782
- description: r,
1817
+ description: n,
1783
1818
  time: e.time,
1784
1819
  set_target_data: e.set_target_data
1785
1820
  }, g = JSON.stringify(m);
@@ -1796,7 +1831,7 @@ class Be extends EventTarget {
1796
1831
  type: "upload_move_start",
1797
1832
  upload_id: l,
1798
1833
  total_chunks: w,
1799
- description: r,
1834
+ description: n,
1800
1835
  encoding: v
1801
1836
  });
1802
1837
  for (let h = 0; h < w; h++) {
@@ -1810,7 +1845,7 @@ class Be extends EventTarget {
1810
1845
  }), d({ phase: "upload", sent: h + 1, total: w });
1811
1846
  }
1812
1847
  if (this._sendCommand({ type: "upload_move_finish", upload_id: l }), d({ phase: "uploaded", sent: w, total: w }), t) {
1813
- const h = new Uint8Array(await t.arrayBuffer()), p = $(h), R = Math.ceil(p.length / y) || 1;
1848
+ const h = new Uint8Array(await t.arrayBuffer()), p = N(h), R = Math.ceil(p.length / y) || 1;
1814
1849
  d({
1815
1850
  phase: "audio-starting",
1816
1851
  sent: 0,
@@ -1821,7 +1856,7 @@ class Be extends EventTarget {
1821
1856
  upload_id: l,
1822
1857
  total_chunks: R,
1823
1858
  encoding: X(t),
1824
- description: r
1859
+ description: n
1825
1860
  });
1826
1861
  for (let T = 0; T < R; T++) {
1827
1862
  this._dc.bufferedAmount > L && await this._awaitDataChannelDrain();
@@ -1840,7 +1875,7 @@ class Be extends EventTarget {
1840
1875
  upload_id: l,
1841
1876
  play_frequency: o,
1842
1877
  initial_goto_duration: a,
1843
- audio_lead_ms: n
1878
+ audio_lead_ms: r
1844
1879
  });
1845
1880
  let b;
1846
1881
  try {
@@ -1877,16 +1912,16 @@ class Be extends EventTarget {
1877
1912
  const t = e ?? this._activeMoveUploadId;
1878
1913
  return t ? this._sendCommand({ type: "cancel_move", upload_id: t }) : !1;
1879
1914
  }
1880
- async uploadAudio(e, { description: t = "audio", onProgress: n = () => {
1915
+ async uploadAudio(e, { description: t = "audio", onProgress: r = () => {
1881
1916
  } } = {}) {
1882
1917
  if (!this._dc || this._dc.readyState !== "open")
1883
1918
  throw new Error("data channel not open");
1884
1919
  if (!(e instanceof Blob))
1885
1920
  throw new TypeError("uploadAudio: expected a Blob");
1886
- const r = K(), i = new Uint8Array(await e.arrayBuffer()), o = $(i), a = Math.ceil(o.length / y) || 1;
1887
- n({ phase: "audio-starting", sent: 0, total: a, bytes: o.length }), this._sendCommand({
1921
+ const n = K(), i = new Uint8Array(await e.arrayBuffer()), o = N(i), a = Math.ceil(o.length / y) || 1;
1922
+ r({ phase: "audio-starting", sent: 0, total: a, bytes: o.length }), this._sendCommand({
1888
1923
  type: "upload_audio_start",
1889
- upload_id: r,
1924
+ upload_id: n,
1890
1925
  total_chunks: a,
1891
1926
  encoding: X(e),
1892
1927
  description: t
@@ -1896,24 +1931,24 @@ class Be extends EventTarget {
1896
1931
  const d = c * y;
1897
1932
  this._sendCommand({
1898
1933
  type: "upload_audio_chunk",
1899
- upload_id: r,
1934
+ upload_id: n,
1900
1935
  chunk_index: c,
1901
1936
  chunk: o.slice(d, d + y)
1902
- }), n({ phase: "audio-upload", sent: c + 1, total: a });
1937
+ }), r({ phase: "audio-upload", sent: c + 1, total: a });
1903
1938
  }
1904
- return this._sendCommand({ type: "upload_audio_finish", upload_id: r }), n({ phase: "audio-uploaded", sent: a, total: a }), r;
1939
+ return this._sendCommand({ type: "upload_audio_finish", upload_id: n }), r({ phase: "audio-uploaded", sent: a, total: a }), n;
1905
1940
  }
1906
1941
  async playUploadedAudio(e, { timeoutMs: t = 8e3 } = {}) {
1907
1942
  if (!this._dc || this._dc.readyState !== "open")
1908
1943
  throw new Error("data channel not open");
1909
- const n = this._waitForBroadcast(
1944
+ const r = this._waitForBroadcast(
1910
1945
  (i) => i?.type === "play_uploaded_audio" && i?.upload_id === e && (i.started === !0 || typeof i.error == "string"),
1911
1946
  { timeoutMs: t, debugLabel: "play_uploaded_audio started" }
1912
1947
  );
1913
1948
  this._sendCommand({ type: "play_uploaded_audio", upload_id: e });
1914
- const r = await n;
1915
- if (typeof r.error == "string") throw new Error(r.error);
1916
- return this._activeAudioUploadId = e, r;
1949
+ const n = await r;
1950
+ if (typeof n.error == "string") throw new Error(n.error);
1951
+ return this._activeAudioUploadId = e, n;
1917
1952
  }
1918
1953
  cancelAudio(e = null) {
1919
1954
  const t = e ?? this._activeAudioUploadId;
@@ -1943,13 +1978,13 @@ class Be extends EventTarget {
1943
1978
  body: JSON.stringify(e)
1944
1979
  });
1945
1980
  if (!t.ok) {
1946
- let n = "";
1981
+ let r = "";
1947
1982
  try {
1948
- n = await t.text();
1983
+ r = await t.text();
1949
1984
  } catch {
1950
1985
  }
1951
1986
  return _.warn(
1952
- `/send rejected (${t.status}) for type=${e?.type}; body=${n || "<empty>"}`
1987
+ `/send rejected (${t.status}) for type=${e?.type}; body=${r || "<empty>"}`
1953
1988
  ), null;
1954
1989
  }
1955
1990
  return await t.json();
@@ -1967,11 +2002,11 @@ class Be extends EventTarget {
1967
2002
  * `conversation.say`). Rejects on the JSON-RPC error, a closed channel, or
1968
2003
  * timeout.
1969
2004
  */
1970
- rpcCall(e, t = {}, n = {}) {
1971
- const r = n.timeoutMs ?? 2e4;
2005
+ rpcCall(e, t = {}, r = {}) {
2006
+ const n = r.timeoutMs ?? 2e4;
1972
2007
  return this._pending.rpcRoundtrip(
1973
2008
  e,
1974
- r,
2009
+ n,
1975
2010
  (i) => this._sendCommand({ jsonrpc: "2.0", id: i, method: e, params: t })
1976
2011
  );
1977
2012
  }
@@ -1980,19 +2015,19 @@ class Be extends EventTarget {
1980
2015
  * robot/app, e.g. `conversation.turn`. Returns an unsubscribe function.
1981
2016
  */
1982
2017
  onNotification(e, t) {
1983
- let n = this._rpcListeners.get(e);
1984
- return n || (n = /* @__PURE__ */ new Set(), this._rpcListeners.set(e, n)), n.add(t), () => {
2018
+ let r = this._rpcListeners.get(e);
2019
+ return r || (r = /* @__PURE__ */ new Set(), this._rpcListeners.set(e, r)), r.add(t), () => {
1985
2020
  this._rpcListeners.get(e)?.delete(t);
1986
2021
  };
1987
2022
  }
1988
2023
  _handleRpcMessage(e) {
1989
2024
  if (!this._pending.settleRpcResponse(e) && typeof e.method == "string") {
1990
2025
  const t = e.params ?? {};
1991
- for (const n of this._rpcListeners.get(e.method) ?? [])
2026
+ for (const r of this._rpcListeners.get(e.method) ?? [])
1992
2027
  try {
1993
- n(t);
1994
- } catch (r) {
1995
- _.error(`onNotification(${e.method}) threw:`, r);
2028
+ r(t);
2029
+ } catch (n) {
2030
+ _.error(`onNotification(${e.method}) threw:`, n);
1996
2031
  }
1997
2032
  }
1998
2033
  }
@@ -2028,19 +2063,19 @@ class Be extends EventTarget {
2028
2063
  }
2029
2064
  }
2030
2065
  _handleEndSession(e) {
2031
- const t = e.reason, n = t === "robot_busy_local_app" ? "Robot is busy: a local Python app is running" : t === "local_app_started" ? "Disconnected: a local Python app started on the robot" : t === "robot_busy_local" ? "Robot is busy: another session is already active" : null;
2066
+ const t = e.reason, r = t === "robot_busy_local_app" ? "Robot is busy: a local Python app is running" : t === "local_app_started" ? "Disconnected: a local Python app started on the robot" : t === "robot_busy_local" ? "Robot is busy: another session is already active" : null;
2032
2067
  if (this._sessionReject) {
2033
- const r = new Error(
2034
- n || `Session ended before it could start: ${t || "unknown reason"}`
2068
+ const n = new Error(
2069
+ r || `Session ended before it could start: ${t || "unknown reason"}`
2035
2070
  );
2036
- r.reason = t ?? null, this._supervisor.redialing || this._emit("sessionRejected", { reason: t, activeApp: null }), this._supervisor.clearIceGrace(), this._supervisor.uninstallNetworkListeners(), this._pc && (this._pc.close(), this._pc = null), this._micStream && (this._micStream.getTracks().forEach((o) => o.stop()), this._micStream = null), this._iceConnected = !1, this._dcOpen = !1, this._micMuted = !0, this._micSupported = !1;
2071
+ n.reason = t ?? null, this._supervisor.redialing || this._emit("sessionRejected", { reason: t, activeApp: null }), this._supervisor.clearIceGrace(), this._supervisor.uninstallNetworkListeners(), this._pc && (this._pc.close(), this._pc = null), this._micStream && (this._micStream.getTracks().forEach((o) => o.stop()), this._micStream = null), this._robotAudioTrack = null, this._iceConnected = !1, this._dcOpen = !1, this._micMuted = !0, this._micSupported = !1;
2037
2072
  const i = this._sessionReject;
2038
- this._sessionResolve = null, this._sessionReject = null, i(r);
2073
+ this._sessionResolve = null, this._sessionReject = null, i(n);
2039
2074
  return;
2040
2075
  }
2041
2076
  this._state === "streaming" && (this._emit("sessionStopped", {
2042
2077
  reason: t || "remote_end",
2043
- message: n
2078
+ message: r
2044
2079
  }), this.stopSession().catch(() => {
2045
2080
  }));
2046
2081
  }
@@ -2050,25 +2085,25 @@ class Be extends EventTarget {
2050
2085
  if (e.sdp) {
2051
2086
  const t = e.sdp;
2052
2087
  if (t.type === "offer") {
2053
- const r = Ie(t.sdp);
2054
- if (this._micSupported = r, this._emit("micSupported", { supported: r }), r && this._micStream)
2088
+ const n = ke(t.sdp);
2089
+ if (this._micSupported = n, this._emit("micSupported", { supported: n }), n && this._micStream)
2055
2090
  for (const o of this._micStream.getAudioTracks())
2056
2091
  this._pc.addTrack(o, this._micStream);
2057
2092
  await this._pc.setRemoteDescription(new RTCSessionDescription(t));
2058
2093
  const i = await this._pc.createAnswer();
2059
- await this._pc.setLocalDescription(i), await this._sendToServer({
2094
+ await this._pc.setLocalDescription(i), this._outgoingAudioTrack && await this._applyOutgoingAudioTrack().catch((o) => _.warn("re-applying outgoing audio failed:", o)), await this._sendToServer({
2060
2095
  type: "peer",
2061
2096
  sessionId: this._sessionId,
2062
2097
  sdp: { type: "answer", sdp: i.sdp }
2063
2098
  });
2064
2099
  } else
2065
2100
  await this._pc.setRemoteDescription(new RTCSessionDescription(t));
2066
- const n = this._pendingRemoteIce;
2067
- if (n && n.length) {
2101
+ const r = this._pendingRemoteIce;
2102
+ if (r && r.length) {
2068
2103
  this._pendingRemoteIce = [];
2069
- for (const r of n)
2104
+ for (const n of r)
2070
2105
  try {
2071
- await this._pc.addIceCandidate(new RTCIceCandidate(r));
2106
+ await this._pc.addIceCandidate(new RTCIceCandidate(n));
2072
2107
  } catch (i) {
2073
2108
  _.warn("buffered ICE candidate rejected:", i);
2074
2109
  }
@@ -2140,30 +2175,30 @@ class Be extends EventTarget {
2140
2175
  }
2141
2176
  if (!((e.command === "wake_up" || e.command === "goto_sleep") && this._pending.settleMotion(e.command, e))) {
2142
2177
  if (e.type === "log_line") {
2143
- for (const n of this._logSubscribers)
2178
+ for (const r of this._logSubscribers)
2144
2179
  try {
2145
- n.onLine({ timestamp: e.timestamp, line: e.line });
2146
- } catch (r) {
2147
- _.error("subscribeLogs onLine threw:", r);
2180
+ r.onLine({ timestamp: e.timestamp, line: e.line });
2181
+ } catch (n) {
2182
+ _.error("subscribeLogs onLine threw:", n);
2148
2183
  }
2149
2184
  return;
2150
2185
  }
2151
2186
  if (e.type === "log_stream_error") {
2152
- for (const n of this._logSubscribers)
2153
- if (typeof n.onError == "function")
2187
+ for (const r of this._logSubscribers)
2188
+ if (typeof r.onError == "function")
2154
2189
  try {
2155
- n.onError(e.error);
2156
- } catch (r) {
2157
- _.error("subscribeLogs onError threw:", r);
2190
+ r.onError(e.error);
2191
+ } catch (n) {
2192
+ _.error("subscribeLogs onError threw:", n);
2158
2193
  }
2159
2194
  return;
2160
2195
  }
2161
2196
  if (e.command === "start_update") {
2162
2197
  if (typeof e.error == "string") {
2163
- const n = { status: "failed", error: e.error };
2164
- for (const r of this._updateProgressSubscribers)
2198
+ const r = { status: "failed", error: e.error };
2199
+ for (const n of this._updateProgressSubscribers)
2165
2200
  try {
2166
- r(n);
2201
+ n(r);
2167
2202
  } catch (i) {
2168
2203
  _.error("startDaemonUpdate onProgress threw:", i);
2169
2204
  }
@@ -2171,22 +2206,22 @@ class Be extends EventTarget {
2171
2206
  return;
2172
2207
  }
2173
2208
  if (e.type === "update_progress") {
2174
- const n = {
2209
+ const r = {
2175
2210
  status: e.status,
2176
2211
  line: typeof e.line == "string" ? e.line : void 0,
2177
2212
  error: typeof e.error == "string" ? e.error : void 0
2178
2213
  };
2179
- for (const r of this._updateProgressSubscribers)
2214
+ for (const n of this._updateProgressSubscribers)
2180
2215
  try {
2181
- r(n);
2216
+ n(r);
2182
2217
  } catch (i) {
2183
2218
  _.error("startDaemonUpdate onProgress threw:", i);
2184
2219
  }
2185
2220
  return;
2186
2221
  }
2187
2222
  if (e.state && (t || Date.now() - this._lastPoseFrameAt >= Q)) {
2188
- const n = e.state;
2189
- n.head_pose && (this._robotState.head = n.head_pose.flat()), n.antennas && (this._robotState.antennas = [n.antennas[0], n.antennas[1]]), n.head_joint_positions && (this._robotState.head_joint_positions = n.head_joint_positions), typeof n.body_yaw == "number" && (this._robotState.body_yaw = n.body_yaw), n.motor_mode && (this._robotState.motor_mode = n.motor_mode), typeof n.is_move_running == "boolean" && (this._robotState.is_move_running = n.is_move_running), n.face_target && (this._robotState.face_target = n.face_target), "doa" in n && (this._robotState.doa = n.doa ?? void 0), "imu" in n && (this._robotState.imu = n.imu ?? void 0), this._emit("state", { ...this._robotState });
2223
+ const r = e.state;
2224
+ r.head_pose && (this._robotState.head = r.head_pose.flat()), r.antennas && (this._robotState.antennas = [r.antennas[0], r.antennas[1]]), r.head_joint_positions && (this._robotState.head_joint_positions = r.head_joint_positions), typeof r.body_yaw == "number" && (this._robotState.body_yaw = r.body_yaw), r.motor_mode && (this._robotState.motor_mode = r.motor_mode), typeof r.is_move_running == "boolean" && (this._robotState.is_move_running = r.is_move_running), r.face_target && (this._robotState.face_target = r.face_target), "doa" in r && (this._robotState.doa = r.doa ?? void 0), "imu" in r && (this._robotState.imu = r.imu ?? void 0), this._emit("state", { ...this._robotState });
2190
2225
  }
2191
2226
  e.error && this._emit("error", { source: "robot", error: e.error }), this._pending.matchBroadcast(e);
2192
2227
  }
@@ -2198,14 +2233,14 @@ class Be extends EventTarget {
2198
2233
  if (!e.srcObject || e.paused) return;
2199
2234
  const t = e.buffered;
2200
2235
  if (t.length > 0) {
2201
- const n = t.end(t.length - 1), r = n - e.currentTime;
2202
- r > 0.5 && (_.debug(`video latency correction: was ${r.toFixed(2)}s behind`), e.currentTime = n - 0.1);
2236
+ const r = t.end(t.length - 1), n = r - e.currentTime;
2237
+ n > 0.5 && (_.debug(`video latency correction: was ${n.toFixed(2)}s behind`), e.currentTime = r - 0.1);
2203
2238
  }
2204
2239
  }, 2e3);
2205
2240
  }
2206
2241
  }
2207
- const Pe = "pollen-robotics/reachy_mini", Ne = `https://api.github.com/repos/${Pe}/releases/latest`, te = "reachy.daemonLatestRelease.v1", $e = 360 * 60 * 1e3, ne = "1.8.2";
2208
- function k(s) {
2242
+ const Pe = "pollen-robotics/reachy_mini", Oe = `https://api.github.com/repos/${Pe}/releases/latest`, te = "reachy.daemonLatestRelease.v1", Ne = 360 * 60 * 1e3, re = "1.8.2";
2243
+ function I(s) {
2209
2244
  if (typeof s != "string") return null;
2210
2245
  const e = s.trim().replace(/^v/i, "").match(/^(\d+)\.(\d+)\.(\d+)/);
2211
2246
  return e ? {
@@ -2217,18 +2252,18 @@ function k(s) {
2217
2252
  function H(s, e) {
2218
2253
  return s.major - e.major || s.minor - e.minor || s.patch - e.patch;
2219
2254
  }
2220
- function Oe(s, e) {
2221
- const t = k(s), n = k(e);
2222
- return !t || !n ? !1 : H(t, n) < 0;
2255
+ function $e(s, e) {
2256
+ const t = I(s), r = I(e);
2257
+ return !t || !r ? !1 : H(t, r) < 0;
2223
2258
  }
2224
2259
  function qe(s, e) {
2225
- const t = k(s);
2260
+ const t = I(s);
2226
2261
  if (!t) return null;
2227
- const n = k(ne);
2228
- return n && H(t, n) < 0 ? "block" : Oe(s, e) ? "notice" : null;
2262
+ const r = I(re);
2263
+ return r && H(t, r) < 0 ? "block" : $e(s, e) ? "notice" : null;
2229
2264
  }
2230
2265
  function Ge(s) {
2231
- const e = k(s), t = k(ne);
2266
+ const e = I(s), t = I(re);
2232
2267
  return !!e && !!t && H(e, t) >= 0;
2233
2268
  }
2234
2269
  function je() {
@@ -2246,19 +2281,19 @@ function je() {
2246
2281
  }
2247
2282
  async function Ve() {
2248
2283
  const s = je();
2249
- if (s && Date.now() - s.at < $e) return s.value;
2284
+ if (s && Date.now() - s.at < Ne) return s.value;
2250
2285
  try {
2251
- const e = await fetch(Ne, {
2286
+ const e = await fetch(Oe, {
2252
2287
  headers: { Accept: "application/vnd.github+json" }
2253
2288
  });
2254
2289
  if (!e.ok)
2255
2290
  return s?.value ?? null;
2256
- const t = await e.json(), n = typeof t.tag_name == "string" ? t.tag_name : null, r = n ? n.replace(/^v/i, "") : null;
2291
+ const t = await e.json(), r = typeof t.tag_name == "string" ? t.tag_name : null, n = r ? r.replace(/^v/i, "") : null;
2257
2292
  try {
2258
- localStorage.setItem(te, JSON.stringify({ value: r, at: Date.now() }));
2293
+ localStorage.setItem(te, JSON.stringify({ value: n, at: Date.now() }));
2259
2294
  } catch {
2260
2295
  }
2261
- return r;
2296
+ return n;
2262
2297
  } catch {
2263
2298
  return s?.value ?? null;
2264
2299
  }
@@ -2272,14 +2307,14 @@ function Fe(s) {
2272
2307
  function He(s) {
2273
2308
  const e = Fe(s);
2274
2309
  if (!e) return null;
2275
- const t = s.meta?.name ?? s.name, n = typeof s.meta?.transport == "string" && s.meta.transport.length > 0 ? s.meta.transport : null, r = typeof s.meta?.hardware_id == "string" && s.meta.hardware_id.length > 0 ? s.meta.hardware_id : null;
2310
+ const t = s.meta?.name ?? s.name, r = typeof s.meta?.transport == "string" && s.meta.transport.length > 0 ? s.meta.transport : null, n = typeof s.meta?.hardware_id == "string" && s.meta.hardware_id.length > 0 ? s.meta.hardware_id : null;
2276
2311
  return {
2277
2312
  id: e,
2278
2313
  meta: t ? { name: t } : void 0,
2279
2314
  busy: s.busy === !0,
2280
2315
  activeApp: typeof s.activeApp == "string" && s.activeApp.trim().length > 0 ? s.activeApp : null,
2281
- transport: n,
2282
- hardwareId: r
2316
+ transport: r,
2317
+ hardwareId: n
2283
2318
  };
2284
2319
  }
2285
2320
  async function Je(s) {
@@ -2287,9 +2322,9 @@ async function Je(s) {
2287
2322
  if (!t) return { ok: !1, robots: [], reason: "No HF token" };
2288
2323
  if (!e)
2289
2324
  return { ok: !1, robots: [], reason: "No signaling URL" };
2290
- const n = `${e.replace(/\/$/, "")}/api/robot-status`, r = new AbortController(), i = setTimeout(() => r.abort(), xe), o = s.signal ? We([r.signal, s.signal]) : r.signal;
2325
+ const r = `${e.replace(/\/$/, "")}/api/robot-status`, n = new AbortController(), i = setTimeout(() => n.abort(), xe), o = s.signal ? We([n.signal, s.signal]) : n.signal;
2291
2326
  try {
2292
- const a = await fetch(n, {
2327
+ const a = await fetch(r, {
2293
2328
  method: "GET",
2294
2329
  headers: {
2295
2330
  Authorization: `Bearer ${t}`,
@@ -2326,12 +2361,12 @@ function We(s) {
2326
2361
  return e.signal;
2327
2362
  }
2328
2363
  export {
2329
- ne as M,
2364
+ re as M,
2330
2365
  Be as R,
2331
2366
  Je as a,
2332
- O as c,
2367
+ $ as c,
2333
2368
  qe as d,
2334
2369
  Ve as f,
2335
- k as p,
2370
+ I as p,
2336
2371
  Ge as s
2337
2372
  };