@camstack/addon-pipeline 0.1.19 → 0.1.20

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.
Files changed (66) hide show
  1. package/dist/audio-analyzer/index.js +5 -2
  2. package/dist/audio-analyzer/index.js.map +1 -1
  3. package/dist/audio-analyzer/index.mjs +5 -2
  4. package/dist/audio-analyzer/index.mjs.map +1 -1
  5. package/dist/audio-codec-nodeav/index.js +1 -1
  6. package/dist/audio-codec-nodeav/index.mjs +1 -1
  7. package/dist/decoder-nodeav/index.js +2 -2
  8. package/dist/decoder-nodeav/index.mjs +2 -2
  9. package/dist/detection-pipeline/index.js +25 -25
  10. package/dist/detection-pipeline/index.js.map +1 -1
  11. package/dist/detection-pipeline/index.mjs +25 -25
  12. package/dist/detection-pipeline/index.mjs.map +1 -1
  13. package/dist/{index-Bmlkm0Fd.mjs → index-5aYef068.mjs} +3601 -770
  14. package/dist/index-5aYef068.mjs.map +1 -0
  15. package/dist/{index-BbPPvoCx.js → index-B36NMAdu.js} +3577 -746
  16. package/dist/index-B36NMAdu.js.map +1 -0
  17. package/dist/{index-D_cl0Qqb.js → index-CMcx_k6Y.js} +48 -48
  18. package/dist/{index-D_cl0Qqb.js.map → index-CMcx_k6Y.js.map} +1 -1
  19. package/dist/{index-UbcdLS7a.mjs → index-CYb7cFrv.mjs} +46 -46
  20. package/dist/{index-UbcdLS7a.mjs.map → index-CYb7cFrv.mjs.map} +1 -1
  21. package/dist/motion-wasm/index.js +1 -1
  22. package/dist/motion-wasm/index.mjs +1 -1
  23. package/dist/pipeline-runner/index.js +74 -77
  24. package/dist/pipeline-runner/index.js.map +1 -1
  25. package/dist/pipeline-runner/index.mjs +74 -77
  26. package/dist/pipeline-runner/index.mjs.map +1 -1
  27. package/dist/recorder/index.js +2209 -0
  28. package/dist/recorder/index.js.map +1 -0
  29. package/dist/recorder/index.mjs +2209 -0
  30. package/dist/recorder/index.mjs.map +1 -0
  31. package/dist/stream-broker/@mf-types/compiled-types/stream-broker/widgets/FfmpegParamsField.d.ts +41 -0
  32. package/dist/stream-broker/@mf-types/compiled-types/stream-broker/widgets/GeometryBuilder.d.ts +54 -0
  33. package/dist/stream-broker/@mf-types/compiled-types/stream-broker/widgets/format-ua.d.ts +13 -0
  34. package/dist/stream-broker/@mf-types/compiled-types/stream-broker/widgets/index.d.ts +2 -0
  35. package/dist/stream-broker/@mf-types.zip +0 -0
  36. package/dist/stream-broker/{__mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_sdk__loadShare__.mjs-h5aXOPSA.mjs → __mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_sdk__loadShare__.mjs-lantnv8e.mjs} +1 -1
  37. package/dist/stream-broker/__mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.mjs-DJ3UNg7O.mjs +30 -0
  38. package/dist/stream-broker/__mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.mjs-CYXy_bhS.mjs +21 -0
  39. package/dist/stream-broker/{__mfe_internal__addon_stream_broker_widgets__loadShare__react__loadShare__.mjs-BsB2G7oY.mjs → __mfe_internal__addon_stream_broker_widgets__loadShare__react__loadShare__.mjs-CaDEYBIU.mjs} +8 -7
  40. package/dist/stream-broker/{__mfe_internal__addon_stream_broker_widgets__loadShare__react__loadShare__.mjs_commonjs-proxy-xrRiPUpA.mjs → __mfe_internal__addon_stream_broker_widgets__loadShare__react__loadShare__.mjs_commonjs-proxy-D6EROtlA.mjs} +1 -1
  41. package/dist/stream-broker/{__mfe_internal__addon_stream_broker_widgets__loadShare__react_mf_1_jsx_mf_2_runtime__loadShare__.mjs-gBEZsQrp.mjs → __mfe_internal__addon_stream_broker_widgets__loadShare__react_mf_1_jsx_mf_2_runtime__loadShare__.mjs-x6pP3Ghk.mjs} +2 -2
  42. package/dist/stream-broker/{__mfe_internal__addon_stream_broker_widgets__loadShare__react_mf_2_dom__loadShare__.mjs_commonjs-proxy-C0E2yCzO.mjs → __mfe_internal__addon_stream_broker_widgets__loadShare__react_mf_2_dom__loadShare__.mjs_commonjs-proxy-CcnN6sbA.mjs} +1 -1
  43. package/dist/stream-broker/_stub.js +963 -333
  44. package/dist/stream-broker/{_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-CupRlwqG.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-CL9DR49k.mjs} +6 -6
  45. package/dist/stream-broker/{client-NPZqorv9.mjs → client-BvTmMOQu.mjs} +2 -2
  46. package/dist/stream-broker/{hostInit-Bh4w7o5_.mjs → hostInit-ChmiMPS0.mjs} +12 -12
  47. package/dist/stream-broker/{index-D_1p2K9B.mjs → index-BxsFuFmE.mjs} +24 -24
  48. package/dist/stream-broker/{index-mX3Kgiv1.mjs → index-C-248uOU.mjs} +2 -2
  49. package/dist/stream-broker/{index-2Qp8vT3w.mjs → index-C05B6jqp.mjs} +1 -1
  50. package/dist/stream-broker/index-DOJoSShD.mjs +67784 -0
  51. package/dist/stream-broker/{index-Dy2V7VOm.mjs → index-DtOI1aTU.mjs} +10112 -5987
  52. package/dist/stream-broker/{index-Cc6QBqMk.mjs → index-oMq6ilgR.mjs} +253 -267
  53. package/dist/stream-broker/{index-BBcZvb5t.mjs → index-vIWZQBIL.mjs} +1 -1
  54. package/dist/stream-broker/index.js +3168 -543
  55. package/dist/stream-broker/index.js.map +1 -1
  56. package/dist/stream-broker/index.mjs +3172 -546
  57. package/dist/stream-broker/index.mjs.map +1 -1
  58. package/dist/stream-broker/{jsx-runtime-lb0mH5st.mjs → jsx-runtime-BRT_HL0A.mjs} +1 -1
  59. package/dist/stream-broker/remoteEntry.js +1 -1
  60. package/dist/stream-broker/{schemas-ClCuS4qa.mjs → schemas-B7L0qZtq.mjs} +411 -406
  61. package/package.json +51 -3
  62. package/dist/index-BbPPvoCx.js.map +0 -1
  63. package/dist/index-Bmlkm0Fd.mjs.map +0 -1
  64. package/dist/stream-broker/__mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.mjs-NjF4kxzW.mjs +0 -19
  65. package/dist/stream-broker/__mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.mjs-BAv_5ISf.mjs +0 -20
  66. package/dist/stream-broker/index-CIJue-4t.mjs +0 -37880
@@ -1,22 +1,23 @@
1
- import { _ as e, a as r, b as B } from "./__mfe_internal__addon_stream_broker_widgets__loadShare__react_mf_1_jsx_mf_2_runtime__loadShare__.mjs-gBEZsQrp.mjs";
2
- import { _ as z, a as G } from "./__mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_tanstack_mf_1_react_mf_2_query__loadShare__.mjs-U1EUeEPs.mjs";
3
- import { a as R, b as S, c as k, d as y, e as I } from "./__mfe_internal__addon_stream_broker_widgets__loadShare__react__loadShare__.mjs-BsB2G7oY.mjs";
4
- import { _ as E, a as Q, b as W, c as X, d as T, e as Z, f as V, g as J, h as Y } from "./__mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.mjs-BAv_5ISf.mjs";
1
+ import { _ as r, a as e, b as $ } from "./__mfe_internal__addon_stream_broker_widgets__loadShare__react_mf_1_jsx_mf_2_runtime__loadShare__.mjs-x6pP3Ghk.mjs";
2
+ import { a as oe, b as V, c as x, d as R, e as W, f as me } from "./__mfe_internal__addon_stream_broker_widgets__loadShare__react__loadShare__.mjs-CaDEYBIU.mjs";
3
+ import { _ as he, a as ie, b as fe, c as ge, d as be, e as le, f as xe, g as ve, h as Ne, i as we } from "./__mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.mjs-CYXy_bhS.mjs";
4
+ import { _ as ye, a as ke } from "./__mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_tanstack_mf_1_react_mf_2_query__loadShare__.mjs-U1EUeEPs.mjs";
5
+ import { _ as Ce } from "./__mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.mjs-DJ3UNg7O.mjs";
5
6
  /**
6
7
  * @license lucide-react v0.511.0 - ISC
7
8
  *
8
9
  * This source code is licensed under the ISC license.
9
10
  * See the LICENSE file in the root directory of this source tree.
10
11
  */
11
- const ee = (s) => s.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase(), te = (s) => s.replace(
12
+ const _e = (t) => t.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase(), $e = (t) => t.replace(
12
13
  /^([A-Z])|[\s-_]+(\w)/g,
13
- (n, o, i) => i ? i.toUpperCase() : o.toLowerCase()
14
- ), A = (s) => {
15
- const n = te(s);
16
- return n.charAt(0).toUpperCase() + n.slice(1);
17
- }, L = (...s) => s.filter((n, o, i) => !!n && n.trim() !== "" && i.indexOf(n) === o).join(" ").trim(), se = (s) => {
18
- for (const n in s)
19
- if (n.startsWith("aria-") || n === "role" || n === "title")
14
+ (a, n, o) => o ? o.toUpperCase() : n.toLowerCase()
15
+ ), Y = (t) => {
16
+ const a = $e(t);
17
+ return a.charAt(0).toUpperCase() + a.slice(1);
18
+ }, ce = (...t) => t.filter((a, n, o) => !!a && a.trim() !== "" && o.indexOf(a) === n).join(" ").trim(), Ae = (t) => {
19
+ for (const a in t)
20
+ if (a.startsWith("aria-") || a === "role" || a === "title")
20
21
  return !0;
21
22
  };
22
23
  /**
@@ -25,7 +26,7 @@ const ee = (s) => s.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase(), te = (
25
26
  * This source code is licensed under the ISC license.
26
27
  * See the LICENSE file in the root directory of this source tree.
27
28
  */
28
- var re = {
29
+ var Se = {
29
30
  xmlns: "http://www.w3.org/2000/svg",
30
31
  width: 24,
31
32
  height: 24,
@@ -42,32 +43,32 @@ var re = {
42
43
  * This source code is licensed under the ISC license.
43
44
  * See the LICENSE file in the root directory of this source tree.
44
45
  */
45
- const ne = R(
46
+ const Ie = oe(
46
47
  ({
47
- color: s = "currentColor",
48
- size: n = 24,
49
- strokeWidth: o = 2,
50
- absoluteStrokeWidth: i,
48
+ color: t = "currentColor",
49
+ size: a = 24,
50
+ strokeWidth: n = 2,
51
+ absoluteStrokeWidth: o,
51
52
  className: c = "",
52
- children: t,
53
- iconNode: l,
54
- ...d
55
- }, u) => S(
53
+ children: s,
54
+ iconNode: m,
55
+ ...l
56
+ }, f) => V(
56
57
  "svg",
57
58
  {
58
- ref: u,
59
- ...re,
60
- width: n,
61
- height: n,
62
- stroke: s,
63
- strokeWidth: i ? Number(o) * 24 / Number(n) : o,
64
- className: L("lucide", c),
65
- ...!t && !se(d) && { "aria-hidden": "true" },
66
- ...d
59
+ ref: f,
60
+ ...Se,
61
+ width: a,
62
+ height: a,
63
+ stroke: t,
64
+ strokeWidth: o ? Number(n) * 24 / Number(a) : n,
65
+ className: ce("lucide", c),
66
+ ...!s && !Ae(l) && { "aria-hidden": "true" },
67
+ ...l
67
68
  },
68
69
  [
69
- ...l.map(([a, m]) => S(a, m)),
70
- ...Array.isArray(t) ? t : [t]
70
+ ...m.map(([u, d]) => V(u, d)),
71
+ ...Array.isArray(s) ? s : [s]
71
72
  ]
72
73
  )
73
74
  );
@@ -77,20 +78,20 @@ const ne = R(
77
78
  * This source code is licensed under the ISC license.
78
79
  * See the LICENSE file in the root directory of this source tree.
79
80
  */
80
- const _ = (s, n) => {
81
- const o = R(
82
- ({ className: i, ...c }, t) => S(ne, {
83
- ref: t,
84
- iconNode: n,
85
- className: L(
86
- `lucide-${ee(A(s))}`,
87
- `lucide-${s}`,
88
- i
81
+ const T = (t, a) => {
82
+ const n = oe(
83
+ ({ className: o, ...c }, s) => V(Ie, {
84
+ ref: s,
85
+ iconNode: a,
86
+ className: ce(
87
+ `lucide-${_e(Y(t))}`,
88
+ `lucide-${t}`,
89
+ o
89
90
  ),
90
91
  ...c
91
92
  })
92
93
  );
93
- return o.displayName = A(s), o;
94
+ return n.displayName = Y(t), n;
94
95
  };
95
96
  /**
96
97
  * @license lucide-react v0.511.0 - ISC
@@ -98,67 +99,679 @@ const _ = (s, n) => {
98
99
  * This source code is licensed under the ISC license.
99
100
  * See the LICENSE file in the root directory of this source tree.
100
101
  */
101
- const ae = [["path", { d: "m6 9 6 6 6-6", key: "qrunsl" }]], O = _("chevron-down", ae);
102
+ const Fe = [["path", { d: "m6 9 6 6 6-6", key: "qrunsl" }]], X = T("chevron-down", Fe);
102
103
  /**
103
104
  * @license lucide-react v0.511.0 - ISC
104
105
  *
105
106
  * This source code is licensed under the ISC license.
106
107
  * See the LICENSE file in the root directory of this source tree.
107
108
  */
108
- const oe = [["path", { d: "m9 18 6-6-6-6", key: "mthhwq" }]], j = _("chevron-right", oe);
109
+ const Pe = [["path", { d: "m9 18 6-6-6-6", key: "mthhwq" }]], Q = T("chevron-right", Pe);
109
110
  /**
110
111
  * @license lucide-react v0.511.0 - ISC
111
112
  *
112
113
  * This source code is licensed under the ISC license.
113
114
  * See the LICENSE file in the root directory of this source tree.
114
115
  */
115
- const ie = [
116
+ const Be = [
117
+ ["path", { d: "M5 12h14", key: "1ays0h" }],
118
+ ["path", { d: "M12 5v14", key: "s699le" }]
119
+ ], Oe = T("plus", Be);
120
+ /**
121
+ * @license lucide-react v0.511.0 - ISC
122
+ *
123
+ * This source code is licensed under the ISC license.
124
+ * See the LICENSE file in the root directory of this source tree.
125
+ */
126
+ const De = [
116
127
  ["path", { d: "M4.9 19.1C1 15.2 1 8.8 4.9 4.9", key: "1vaf9d" }],
117
128
  ["path", { d: "M7.8 16.2c-2.3-2.3-2.3-6.1 0-8.5", key: "u1ii0m" }],
118
129
  ["circle", { cx: "12", cy: "12", r: "2", key: "1c9p78" }],
119
130
  ["path", { d: "M16.2 7.8c2.3 2.3 2.3 6.1 0 8.5", key: "1j5fej" }],
120
131
  ["path", { d: "M19.1 4.9C23 8.8 23 15.1 19.1 19", key: "10b0cb" }]
121
- ], ce = _("radio", ie);
132
+ ], Me = T("radio", De);
122
133
  /**
123
134
  * @license lucide-react v0.511.0 - ISC
124
135
  *
125
136
  * This source code is licensed under the ISC license.
126
137
  * See the LICENSE file in the root directory of this source tree.
127
138
  */
128
- const de = [
139
+ const Ee = [
129
140
  ["path", { d: "M18 6 6 18", key: "1bl5f8" }],
130
141
  ["path", { d: "m6 6 12 12", key: "d8bk6v" }]
131
- ], le = _("x", de);
132
- function pe(s) {
133
- const n = Math.floor(s / 1e3);
134
- if (n < 60) return `${n}s`;
135
- const o = Math.floor(n / 60);
136
- return o < 60 ? `${o}m` : `${Math.floor(o / 60)}h ${o % 60}m`;
142
+ ], Ke = T("x", Ee);
143
+ function Re(t) {
144
+ const a = [];
145
+ if (t.crop && a.push(`crop=${t.crop.w}:${t.crop.h}:${t.crop.x}:${t.crop.y}`), t.targetAspect && t.width !== void 0 && t.height !== void 0) {
146
+ const n = t.targetAspect.replace(":", "/");
147
+ t.mode === "pad" ? (a.push(`scale=${t.width}:${t.height}:force_original_aspect_ratio=decrease`), a.push(`pad=${t.width}:${t.height}:(ow-iw)/2:(oh-ih)/2`)) : (a.push(`scale=${t.width}:${t.height}:force_original_aspect_ratio=increase`), a.push(`crop=${t.width}:${t.height}`)), a.push(`setdar=${n}`);
148
+ }
149
+ return t.rotate === 90 ? a.push("transpose=1") : t.rotate === 270 ? a.push("transpose=2") : t.rotate === 180 && a.push("hflip", "vflip"), t.hflip && t.rotate !== 180 && a.push("hflip"), t.vflip && t.rotate !== 180 && a.push("vflip"), a.join(",");
150
+ }
151
+ function Te(t, a) {
152
+ const n = [];
153
+ for (let o = 0; o < t.length; o++) {
154
+ if (t[o] === "-vf") {
155
+ o++;
156
+ continue;
157
+ }
158
+ const c = t[o];
159
+ c !== void 0 && n.push(c);
160
+ }
161
+ return a.length > 0 && n.push("-vf", a), n;
162
+ }
163
+ const F = "rounded border border-border bg-surface-2 px-2 py-1 text-xs text-foreground focus:outline-none focus:ring-1 focus:ring-accent disabled:opacity-50 disabled:cursor-not-allowed", q = F + " appearance-none pr-6", B = "text-[11px] uppercase tracking-wider text-foreground-subtle font-medium";
164
+ function je({ outputArgs: t, onChange: a }) {
165
+ const [n, o] = x(""), [c, s] = x("pad"), [m, l] = x("1920"), [f, u] = x("1080"), [d, p] = x(!1), [v, N] = x("0"), [h, C] = x("0"), [w, A] = x("0"), [S, M] = x("0"), [k, E] = x(0), [K, i] = x(!1), [g, y] = x(!1), z = Re((() => {
166
+ const b = { rotate: k, hflip: K, vflip: g };
167
+ return n !== "" && (b.targetAspect = n, b.mode = c, b.width = Number(m), b.height = Number(f)), d && (b.crop = { x: Number(v), y: Number(h), w: Number(w), h: Number(S) }), b;
168
+ })());
169
+ return /* @__PURE__ */ r("div", { className: "space-y-2 rounded border border-border/50 bg-surface-2/30 px-3 py-2", children: [
170
+ /* @__PURE__ */ r("div", { className: "flex items-center justify-between", children: [
171
+ /* @__PURE__ */ r("span", { className: B, children: [
172
+ "Geometry / zoom",
173
+ /* @__PURE__ */ e("span", { className: "ml-2 text-[10px] normal-case text-foreground-subtle italic", children: "composes a single -vf into output args" })
174
+ ] }),
175
+ /* @__PURE__ */ e(
176
+ "button",
177
+ {
178
+ type: "button",
179
+ onClick: () => a(Te(t, z)),
180
+ className: "rounded-md border border-border bg-surface-hover px-2 py-0.5 text-[10px] font-medium text-foreground hover:bg-surface-hover/70 transition-colors",
181
+ children: "Apply geometry"
182
+ }
183
+ )
184
+ ] }),
185
+ /* @__PURE__ */ r("div", { className: "flex flex-wrap items-center gap-2", children: [
186
+ /* @__PURE__ */ e("label", { className: B, htmlFor: "geom-aspect", children: "Aspect" }),
187
+ /* @__PURE__ */ r(
188
+ "select",
189
+ {
190
+ id: "geom-aspect",
191
+ value: n,
192
+ onChange: (b) => o(b.target.value),
193
+ className: q + " min-w-[90px]",
194
+ children: [
195
+ /* @__PURE__ */ e("option", { value: "", children: "none" }),
196
+ /* @__PURE__ */ e("option", { value: "16:9", children: "16:9" }),
197
+ /* @__PURE__ */ e("option", { value: "4:3", children: "4:3" }),
198
+ /* @__PURE__ */ e("option", { value: "1:1", children: "1:1" })
199
+ ]
200
+ }
201
+ ),
202
+ n !== "" && /* @__PURE__ */ r($, { children: [
203
+ /* @__PURE__ */ r(
204
+ "select",
205
+ {
206
+ "aria-label": "Aspect mode",
207
+ value: c,
208
+ onChange: (b) => s(b.target.value),
209
+ className: q + " min-w-[80px]",
210
+ children: [
211
+ /* @__PURE__ */ e("option", { value: "pad", children: "pad" }),
212
+ /* @__PURE__ */ e("option", { value: "crop", children: "crop" })
213
+ ]
214
+ }
215
+ ),
216
+ /* @__PURE__ */ e(
217
+ "input",
218
+ {
219
+ type: "number",
220
+ "aria-label": "Aspect width",
221
+ value: m,
222
+ onChange: (b) => l(b.target.value),
223
+ className: F + " w-20 text-right"
224
+ }
225
+ ),
226
+ /* @__PURE__ */ e("span", { className: "text-[11px] text-foreground-subtle", children: "×" }),
227
+ /* @__PURE__ */ e(
228
+ "input",
229
+ {
230
+ type: "number",
231
+ "aria-label": "Aspect height",
232
+ value: f,
233
+ onChange: (b) => u(b.target.value),
234
+ className: F + " w-20 text-right"
235
+ }
236
+ )
237
+ ] })
238
+ ] }),
239
+ /* @__PURE__ */ r("div", { className: "flex flex-wrap items-center gap-2", children: [
240
+ /* @__PURE__ */ r("label", { className: B + " inline-flex items-center gap-1", children: [
241
+ /* @__PURE__ */ e("input", { type: "checkbox", checked: d, onChange: (b) => p(b.target.checked) }),
242
+ "Crop / zoom"
243
+ ] }),
244
+ d && /* @__PURE__ */ r($, { children: [
245
+ /* @__PURE__ */ e("input", { type: "number", "aria-label": "Crop x", value: v, onChange: (b) => N(b.target.value), className: F + " w-16 text-right", placeholder: "x" }),
246
+ /* @__PURE__ */ e("input", { type: "number", "aria-label": "Crop y", value: h, onChange: (b) => C(b.target.value), className: F + " w-16 text-right", placeholder: "y" }),
247
+ /* @__PURE__ */ e("input", { type: "number", "aria-label": "Crop width", value: w, onChange: (b) => A(b.target.value), className: F + " w-20 text-right", placeholder: "w" }),
248
+ /* @__PURE__ */ e("input", { type: "number", "aria-label": "Crop height", value: S, onChange: (b) => M(b.target.value), className: F + " w-20 text-right", placeholder: "h" })
249
+ ] })
250
+ ] }),
251
+ /* @__PURE__ */ r("div", { className: "flex flex-wrap items-center gap-2", children: [
252
+ /* @__PURE__ */ e("label", { className: B, htmlFor: "geom-rotate", children: "Rotate" }),
253
+ /* @__PURE__ */ r(
254
+ "select",
255
+ {
256
+ id: "geom-rotate",
257
+ value: String(k),
258
+ onChange: (b) => E(Number(b.target.value)),
259
+ className: q + " min-w-[80px]",
260
+ children: [
261
+ /* @__PURE__ */ e("option", { value: "0", children: "0°" }),
262
+ /* @__PURE__ */ e("option", { value: "90", children: "90°" }),
263
+ /* @__PURE__ */ e("option", { value: "180", children: "180°" }),
264
+ /* @__PURE__ */ e("option", { value: "270", children: "270°" })
265
+ ]
266
+ }
267
+ ),
268
+ /* @__PURE__ */ r("label", { className: B + " inline-flex items-center gap-1", children: [
269
+ /* @__PURE__ */ e("input", { type: "checkbox", checked: K, onChange: (b) => i(b.target.checked) }),
270
+ "hflip"
271
+ ] }),
272
+ /* @__PURE__ */ r("label", { className: B + " inline-flex items-center gap-1", children: [
273
+ /* @__PURE__ */ e("input", { type: "checkbox", checked: g, onChange: (b) => y(b.target.checked) }),
274
+ "vflip"
275
+ ] })
276
+ ] }),
277
+ /* @__PURE__ */ r("div", { className: "font-mono text-[10px] text-foreground-subtle break-all", children: [
278
+ "-vf ",
279
+ z.length > 0 ? z : /* @__PURE__ */ e("span", { className: "italic", children: "(empty)" })
280
+ ] })
281
+ ] });
282
+ }
283
+ const Le = [
284
+ { group: "Demuxer", label: "-thread_queue_size 1024", args: ["-thread_queue_size", "1024"], description: "Larger input packet queue (helps with high-bitrate sources)" },
285
+ { group: "Demuxer", label: "-fflags +genpts", args: ["-fflags", "+genpts"], description: "Generate PTS when the source lacks them" },
286
+ { group: "Demuxer", label: "-re", args: ["-re"], description: "Read input at native frame rate (file replay)" },
287
+ { group: "Demuxer", label: "-probesize 32", args: ["-probesize", "32"], description: "Minimal probe size — faster start" },
288
+ { group: "Demuxer", label: "-analyzeduration 0", args: ["-analyzeduration", "0"], description: "Skip stream analysis — faster start" },
289
+ { group: "RTSP", label: "-rtsp_transport tcp", args: ["-rtsp_transport", "tcp"], description: "Force TCP transport for RTSP source" },
290
+ { group: "RTSP", label: "-stimeout 5000000", args: ["-stimeout", "5000000"], description: "Socket I/O timeout (microseconds, 5s)" }
291
+ ], He = [
292
+ { group: "Muxer", label: "-flush_packets 1", args: ["-flush_packets", "1"], description: "Flush each packet immediately" },
293
+ { group: "Muxer", label: "-movflags +faststart", args: ["-movflags", "+faststart"], description: "Move MOOV atom to front (MP4)" },
294
+ { group: "Bitstream", label: "-bsf:v h264_mp4toannexb", args: ["-bsf:v", "h264_mp4toannexb"], description: "Convert MP4-format H.264 to Annex-B" },
295
+ { group: "Bitstream", label: "-bsf:v hevc_mp4toannexb", args: ["-bsf:v", "hevc_mp4toannexb"], description: "Convert MP4-format HEVC to Annex-B" },
296
+ { group: "x264", label: "-x264-params keyint_min=15", args: ["-x264-params", "keyint_min=15"], description: "Force minimum keyframe interval to 15 frames" },
297
+ { group: "x264", label: "-x264-params scenecut=0", args: ["-x264-params", "scenecut=0"], description: "Disable scene-change keyframes (predictable GOP)" },
298
+ { group: "x264", label: "-x264-params nal-hrd=cbr", args: ["-x264-params", "nal-hrd=cbr"], description: "Force CBR HRD signalling (HomeKit-friendly)" },
299
+ { group: "x264", label: "-aq-mode 3", args: ["-aq-mode", "3"], description: "Auto-variance adaptive quantisation (mode 3)" },
300
+ { group: "x265", label: "-x265-params keyint=30", args: ["-x265-params", "keyint=30"], description: "Force maximum keyframe interval to 30 frames" },
301
+ { group: "x265", label: "-x265-params no-scenecut=1", args: ["-x265-params", "no-scenecut=1"], description: "Disable scene-change keyframes" },
302
+ { group: "Global", label: "-fps_mode passthrough", args: ["-fps_mode", "passthrough"], description: "Preserve source framerate exactly" },
303
+ { group: "Global", label: "-copyts", args: ["-copyts"], description: "Preserve source timestamps" }
304
+ ], Ue = { video: { codec: "copy" }, audio: "passthrough" }, O = "rounded border border-border bg-surface-2 px-2 py-1 text-xs text-foreground focus:outline-none focus:ring-1 focus:ring-accent disabled:opacity-50 disabled:cursor-not-allowed read-only:opacity-60 read-only:cursor-not-allowed", Z = O + " appearance-none pr-6", J = "w-full rounded border border-border bg-surface-2 px-2 py-1.5 text-[11px] font-mono text-foreground focus:outline-none focus:ring-1 focus:ring-accent disabled:opacity-50 read-only:opacity-60 min-h-[60px] resize-y", I = "flex items-center justify-between gap-3 py-1.5", _ = "text-[11px] uppercase tracking-wider text-foreground-subtle font-medium", j = "rounded-lg border border-border bg-surface overflow-hidden", G = "border-b border-border px-3 py-1.5 flex items-center justify-between bg-surface-hover/30", L = "text-[11px] font-semibold text-foreground uppercase tracking-wider";
305
+ function ze({ config: t, value: a, onSave: n }) {
306
+ const [o, c] = x(!1), s = a ?? Ue, [m, l] = x(() => (s.inputArgs ?? []).join(`
307
+ `)), [f, u] = x(() => (s.outputArgs ?? []).join(`
308
+ `)), d = W(s);
309
+ d.current !== s && (d.current = s, l((s.inputArgs ?? []).join(`
310
+ `)), u((s.outputArgs ?? []).join(`
311
+ `)));
312
+ const p = (i) => {
313
+ n(i(s));
314
+ }, v = (i) => p((g) => ({ ...g, video: { ...g.video, codec: i } })), N = (i) => p((g) => ({ ...g, video: { ...g.video, width: i } })), h = (i) => p((g) => ({ ...g, video: { ...g.video, height: i } })), C = (i) => p((g) => ({ ...g, video: { ...g.video, fps: i } })), w = (i) => p((g) => ({ ...g, video: { ...g.video, bitrateKbps: i } })), A = () => p((i) => ({ ...i, audio: "passthrough" })), S = (i) => p((g) => ({
315
+ ...g,
316
+ audio: typeof g.audio == "object" ? { ...g.audio, codec: i } : { codec: i }
317
+ })), M = (i) => p((g) => ({
318
+ ...g,
319
+ audio: typeof g.audio == "object" ? { ...g.audio, bitrateKbps: i } : { codec: "opus", bitrateKbps: i }
320
+ })), k = (i) => p((g) => ({ ...g, inputArgs: i.split(`
321
+ `).map((y) => y.trim()).filter((y) => y.length > 0) })), E = (i) => p((g) => ({ ...g, outputArgs: i.split(`
322
+ `).map((y) => y.trim()).filter((y) => y.length > 0) })), K = (i, g) => {
323
+ const y = g.args.join(" ");
324
+ if (i === "input") {
325
+ const P = m.length === 0 ? y : `${m}
326
+ ${y}`;
327
+ l(P), k(P);
328
+ } else {
329
+ const P = f.length === 0 ? y : `${f}
330
+ ${y}`;
331
+ u(P), E(P);
332
+ }
333
+ };
334
+ return /* @__PURE__ */ r("div", { className: "space-y-3", children: [
335
+ t.sourceParams !== void 0 && /* @__PURE__ */ r("div", { className: j, children: [
336
+ /* @__PURE__ */ r("div", { className: G, children: [
337
+ /* @__PURE__ */ e("h3", { className: L, children: "Source (probed)" }),
338
+ /* @__PURE__ */ e("span", { className: "text-[10px] text-foreground-subtle italic", children: "From the publisher" })
339
+ ] }),
340
+ /* @__PURE__ */ e("div", { className: "px-3 py-2 flex flex-wrap gap-1.5", children: /* @__PURE__ */ e(qe, { profile: t.sourceParams }) })
341
+ ] }),
342
+ /* @__PURE__ */ e("div", { className: "@container", children: /* @__PURE__ */ r("div", { className: "grid grid-cols-1 @[480px]:grid-cols-2 gap-3", children: [
343
+ /* @__PURE__ */ r("div", { className: j, children: [
344
+ /* @__PURE__ */ e("div", { className: G, children: /* @__PURE__ */ e("h3", { className: L, children: "Video" }) }),
345
+ /* @__PURE__ */ r("div", { className: "px-3 py-2 divide-y divide-border/30", children: [
346
+ /* @__PURE__ */ r("div", { className: I, children: [
347
+ /* @__PURE__ */ e("label", { htmlFor: `${t.fieldKey}-video-codec`, className: _, children: "Codec" }),
348
+ /* @__PURE__ */ r(
349
+ "select",
350
+ {
351
+ id: `${t.fieldKey}-video-codec`,
352
+ value: s.video.codec,
353
+ onChange: (i) => v(i.target.value),
354
+ className: Z + " min-w-[120px]",
355
+ children: [
356
+ /* @__PURE__ */ e("option", { value: "h264", children: "h264" }),
357
+ /* @__PURE__ */ e("option", { value: "h265", children: "h265" }),
358
+ /* @__PURE__ */ e("option", { value: "copy", children: "copy (passthrough)" })
359
+ ]
360
+ }
361
+ )
362
+ ] }),
363
+ s.video.codec !== "copy" && /* @__PURE__ */ r($, { children: [
364
+ /* @__PURE__ */ r("div", { className: I, children: [
365
+ /* @__PURE__ */ e("label", { htmlFor: `${t.fieldKey}-video-width`, className: _, children: "Width" }),
366
+ /* @__PURE__ */ e(
367
+ "input",
368
+ {
369
+ id: `${t.fieldKey}-video-width`,
370
+ type: "number",
371
+ "aria-label": "Width",
372
+ value: s.video.width ?? "",
373
+ onChange: (i) => N(Number(i.target.value)),
374
+ className: O + " w-24 text-right"
375
+ }
376
+ )
377
+ ] }),
378
+ /* @__PURE__ */ r("div", { className: I, children: [
379
+ /* @__PURE__ */ e("label", { htmlFor: `${t.fieldKey}-video-height`, className: _, children: "Height" }),
380
+ /* @__PURE__ */ e(
381
+ "input",
382
+ {
383
+ id: `${t.fieldKey}-video-height`,
384
+ type: "number",
385
+ value: s.video.height ?? "",
386
+ onChange: (i) => h(Number(i.target.value)),
387
+ className: O + " w-24 text-right"
388
+ }
389
+ )
390
+ ] }),
391
+ /* @__PURE__ */ r("div", { className: I, children: [
392
+ /* @__PURE__ */ e("label", { htmlFor: `${t.fieldKey}-video-fps`, className: _, children: "FPS" }),
393
+ /* @__PURE__ */ e(
394
+ "input",
395
+ {
396
+ id: `${t.fieldKey}-video-fps`,
397
+ type: "number",
398
+ value: s.video.fps ?? "",
399
+ onChange: (i) => C(Number(i.target.value)),
400
+ className: O + " w-24 text-right"
401
+ }
402
+ )
403
+ ] }),
404
+ /* @__PURE__ */ r("div", { className: I, children: [
405
+ /* @__PURE__ */ e("label", { htmlFor: `${t.fieldKey}-video-bitrate`, className: _, children: "Bitrate (kbps)" }),
406
+ /* @__PURE__ */ e(
407
+ "input",
408
+ {
409
+ id: `${t.fieldKey}-video-bitrate`,
410
+ type: "number",
411
+ value: s.video.bitrateKbps ?? "",
412
+ onChange: (i) => w(Number(i.target.value)),
413
+ className: O + " w-24 text-right"
414
+ }
415
+ )
416
+ ] })
417
+ ] })
418
+ ] })
419
+ ] }),
420
+ /* @__PURE__ */ r("div", { className: j, children: [
421
+ /* @__PURE__ */ e("div", { className: G, children: /* @__PURE__ */ e("h3", { className: L, children: "Audio" }) }),
422
+ /* @__PURE__ */ e("div", { className: "px-3 py-2", children: s.audio === "passthrough" ? /* @__PURE__ */ r("div", { className: "flex items-center justify-between gap-3", children: [
423
+ /* @__PURE__ */ e("span", { className: "text-[11px] text-foreground-subtle italic", children: "Source audio forwarded without re-encode." }),
424
+ /* @__PURE__ */ e(
425
+ "button",
426
+ {
427
+ type: "button",
428
+ onClick: () => S("opus"),
429
+ className: "rounded-md border border-border bg-surface-hover px-2 py-1 text-[11px] text-foreground hover:bg-surface-hover/70 transition-colors",
430
+ children: "Switch to custom encode"
431
+ }
432
+ )
433
+ ] }) : /* @__PURE__ */ r("div", { className: "divide-y divide-border/30", children: [
434
+ /* @__PURE__ */ r("div", { className: I, children: [
435
+ /* @__PURE__ */ e("label", { htmlFor: `${t.fieldKey}-audio-codec`, className: _, children: "Codec" }),
436
+ /* @__PURE__ */ r(
437
+ "select",
438
+ {
439
+ id: `${t.fieldKey}-audio-codec`,
440
+ value: s.audio.codec,
441
+ onChange: (i) => S(i.target.value),
442
+ className: Z + " min-w-[120px]",
443
+ children: [
444
+ /* @__PURE__ */ e("option", { value: "opus", children: "opus" }),
445
+ /* @__PURE__ */ e("option", { value: "aac", children: "aac" }),
446
+ /* @__PURE__ */ e("option", { value: "pcmu", children: "pcmu" }),
447
+ /* @__PURE__ */ e("option", { value: "pcma", children: "pcma" }),
448
+ /* @__PURE__ */ e("option", { value: "copy", children: "copy (passthrough)" })
449
+ ]
450
+ }
451
+ )
452
+ ] }),
453
+ /* @__PURE__ */ r("div", { className: I, children: [
454
+ /* @__PURE__ */ e("label", { htmlFor: `${t.fieldKey}-audio-bitrate`, className: _, children: "Bitrate (kbps)" }),
455
+ /* @__PURE__ */ e(
456
+ "input",
457
+ {
458
+ id: `${t.fieldKey}-audio-bitrate`,
459
+ type: "number",
460
+ value: s.audio.bitrateKbps ?? "",
461
+ onChange: (i) => M(Number(i.target.value)),
462
+ className: O + " w-24 text-right"
463
+ }
464
+ )
465
+ ] }),
466
+ /* @__PURE__ */ e("div", { className: "pt-2", children: /* @__PURE__ */ e(
467
+ "button",
468
+ {
469
+ type: "button",
470
+ onClick: A,
471
+ className: "text-[11px] text-foreground-subtle hover:text-foreground underline-offset-2 hover:underline",
472
+ children: "Switch back to passthrough"
473
+ }
474
+ ) })
475
+ ] }) })
476
+ ] })
477
+ ] }) }),
478
+ /* @__PURE__ */ r("div", { className: j, children: [
479
+ /* @__PURE__ */ r(
480
+ "button",
481
+ {
482
+ type: "button",
483
+ onClick: () => c((i) => !i),
484
+ className: "w-full px-3 py-1.5 flex items-center justify-between bg-surface-hover/30 hover:bg-surface-hover transition-colors",
485
+ children: [
486
+ /* @__PURE__ */ r("span", { className: "inline-flex items-center gap-1.5 " + L, children: [
487
+ o ? /* @__PURE__ */ e(X, { className: "h-3 w-3" }) : /* @__PURE__ */ e(Q, { className: "h-3 w-3" }),
488
+ "Advanced — raw ffmpeg args"
489
+ ] }),
490
+ /* @__PURE__ */ r("span", { className: "text-[10px] text-foreground-subtle italic", children: [
491
+ (s.inputArgs?.length ?? 0) + (s.outputArgs?.length ?? 0),
492
+ " args"
493
+ ] })
494
+ ]
495
+ }
496
+ ),
497
+ o && /* @__PURE__ */ r("div", { className: "px-3 py-2 space-y-3 border-t border-border/50", children: [
498
+ /* @__PURE__ */ r("div", { className: "space-y-1.5", children: [
499
+ /* @__PURE__ */ r("div", { className: "flex items-center justify-between", children: [
500
+ /* @__PURE__ */ r("label", { htmlFor: `${t.fieldKey}-input-args`, className: _, children: [
501
+ "Input args",
502
+ /* @__PURE__ */ e("span", { className: "ml-2 text-[10px] normal-case text-foreground-subtle italic", children: "one per line · inserted between globals and -i" })
503
+ ] }),
504
+ /* @__PURE__ */ e(
505
+ ee,
506
+ {
507
+ id: `${t.fieldKey}-input-picker`,
508
+ disabled: !1,
509
+ catalogue: Le,
510
+ onPick: (i) => K("input", i)
511
+ }
512
+ )
513
+ ] }),
514
+ /* @__PURE__ */ e(
515
+ "textarea",
516
+ {
517
+ id: `${t.fieldKey}-input-args`,
518
+ value: m,
519
+ onChange: (i) => l(i.target.value),
520
+ onBlur: (i) => k(i.target.value),
521
+ placeholder: "-thread_queue_size 1024",
522
+ className: J
523
+ }
524
+ )
525
+ ] }),
526
+ /* @__PURE__ */ e(
527
+ je,
528
+ {
529
+ outputArgs: s.outputArgs ?? [],
530
+ onChange: (i) => {
531
+ u(i.join(`
532
+ `)), E(i.join(`
533
+ `));
534
+ }
535
+ }
536
+ ),
537
+ /* @__PURE__ */ r("div", { className: "space-y-1.5", children: [
538
+ /* @__PURE__ */ r("div", { className: "flex items-center justify-between", children: [
539
+ /* @__PURE__ */ r("label", { htmlFor: `${t.fieldKey}-output-args`, className: _, children: [
540
+ "Output args",
541
+ /* @__PURE__ */ e("span", { className: "ml-2 text-[10px] normal-case text-foreground-subtle italic", children: "one per line · inserted before the final muxer" })
542
+ ] }),
543
+ /* @__PURE__ */ e(
544
+ ee,
545
+ {
546
+ id: `${t.fieldKey}-output-picker`,
547
+ disabled: !1,
548
+ catalogue: He,
549
+ onPick: (i) => K("output", i)
550
+ }
551
+ )
552
+ ] }),
553
+ /* @__PURE__ */ e(
554
+ "textarea",
555
+ {
556
+ id: `${t.fieldKey}-output-args`,
557
+ value: f,
558
+ onChange: (i) => u(i.target.value),
559
+ onBlur: (i) => E(i.target.value),
560
+ placeholder: "-bsf:v h264_mp4toannexb",
561
+ className: J
562
+ }
563
+ )
564
+ ] })
565
+ ] })
566
+ ] })
567
+ ] });
568
+ }
569
+ function qe({ profile: t }) {
570
+ const a = "inline-flex items-center gap-1 rounded-full bg-foreground-subtle/10 border border-border px-2 py-0.5 text-[11px] font-mono text-foreground-subtle", { video: n, audio: o } = t, c = n.width !== void 0 && n.height !== void 0 ? `${n.width}×${n.height}` : void 0;
571
+ return /* @__PURE__ */ r($, { children: [
572
+ /* @__PURE__ */ r("span", { className: a, children: [
573
+ /* @__PURE__ */ e("span", { className: "opacity-60", children: "codec" }),
574
+ n.codec
575
+ ] }),
576
+ c !== void 0 && /* @__PURE__ */ r("span", { className: a, children: [
577
+ /* @__PURE__ */ e("span", { className: "opacity-60", children: "res" }),
578
+ c
579
+ ] }),
580
+ n.fps !== void 0 && /* @__PURE__ */ r("span", { className: a, children: [
581
+ /* @__PURE__ */ e("span", { className: "opacity-60", children: "fps" }),
582
+ n.fps
583
+ ] }),
584
+ n.bitrateKbps !== void 0 && /* @__PURE__ */ r("span", { className: a, children: [
585
+ /* @__PURE__ */ e("span", { className: "opacity-60", children: "bitrate" }),
586
+ n.bitrateKbps,
587
+ "k"
588
+ ] }),
589
+ o === "passthrough" ? /* @__PURE__ */ r("span", { className: a, children: [
590
+ /* @__PURE__ */ e("span", { className: "opacity-60", children: "audio" }),
591
+ "passthrough"
592
+ ] }) : /* @__PURE__ */ r($, { children: [
593
+ /* @__PURE__ */ r("span", { className: a, children: [
594
+ /* @__PURE__ */ e("span", { className: "opacity-60", children: "audio" }),
595
+ o.codec
596
+ ] }),
597
+ o.bitrateKbps !== void 0 && /* @__PURE__ */ r("span", { className: a, children: [
598
+ /* @__PURE__ */ e("span", { className: "opacity-60", children: "a-bitrate" }),
599
+ o.bitrateKbps,
600
+ "k"
601
+ ] }),
602
+ o.sampleRateHz !== void 0 && /* @__PURE__ */ r("span", { className: a, children: [
603
+ /* @__PURE__ */ e("span", { className: "opacity-60", children: "a-sr" }),
604
+ o.sampleRateHz,
605
+ "Hz"
606
+ ] }),
607
+ o.channels !== void 0 && /* @__PURE__ */ r("span", { className: a, children: [
608
+ /* @__PURE__ */ e("span", { className: "opacity-60", children: "a-ch" }),
609
+ o.channels
610
+ ] })
611
+ ] })
612
+ ] });
137
613
  }
138
- const F = {
614
+ function Ge(t) {
615
+ const a = t.config ?? {}, n = he(), [o, c] = x(() => a.initialValue), s = R((f) => {
616
+ if (c(f), t.deviceId === void 0) return;
617
+ const u = a.writerCapName, d = a.writerAddonId, p = a.fieldKey;
618
+ if (u === void 0 || d === void 0 || p === void 0) {
619
+ console.warn(
620
+ `[ffmpeg-params] widgetConfig is missing writerCapName/writerAddonId/fieldKey — field ${p ?? "(unknown)"} cannot be saved. Fix the contribution builder.`
621
+ );
622
+ return;
623
+ }
624
+ n.mutate({
625
+ deviceId: t.deviceId,
626
+ writerCapName: u,
627
+ writerAddonId: d,
628
+ key: p,
629
+ value: f ?? null
630
+ });
631
+ }, [
632
+ t.deviceId,
633
+ a.fieldKey,
634
+ a.writerCapName,
635
+ a.writerAddonId,
636
+ n
637
+ ]);
638
+ if (t.deviceId === void 0)
639
+ return /* @__PURE__ */ e("div", { className: "rounded-lg border border-warning/30 bg-warning/10 px-3 py-2 text-xs text-warning", children: "ffmpeg-params: no deviceId in widget context — this widget only renders inside a device tab." });
640
+ const m = a.fieldKey;
641
+ if (m === void 0 || m.length === 0)
642
+ return /* @__PURE__ */ e("div", { className: "rounded-lg border border-warning/30 bg-warning/10 px-3 py-2 text-xs text-warning", children: "ffmpeg-params: widgetConfig.fieldKey is required — fix the contribution builder." });
643
+ const l = { ...a, fieldKey: m };
644
+ return /* @__PURE__ */ e(ze, { config: l, value: o, onSave: s });
645
+ }
646
+ function ee({ id: t, disabled: a, catalogue: n, onPick: o }) {
647
+ const [c, s] = x(!1), m = me(() => {
648
+ const l = /* @__PURE__ */ new Map();
649
+ for (const f of n) {
650
+ const u = l.get(f.group) ?? [];
651
+ u.push(f), l.set(f.group, u);
652
+ }
653
+ return l;
654
+ }, [n]);
655
+ return /* @__PURE__ */ r("div", { className: "relative", children: [
656
+ /* @__PURE__ */ r(
657
+ "button",
658
+ {
659
+ id: t,
660
+ type: "button",
661
+ disabled: a,
662
+ onClick: () => s((l) => !l),
663
+ className: "inline-flex items-center gap-1 rounded-md border border-border bg-surface-hover px-2 py-0.5 text-[10px] font-medium text-foreground-subtle hover:bg-surface-hover/70 disabled:opacity-40 disabled:cursor-not-allowed transition-colors",
664
+ children: [
665
+ /* @__PURE__ */ e(Oe, { className: "h-3 w-3" }),
666
+ "Add flag…"
667
+ ]
668
+ }
669
+ ),
670
+ c && !a && /* @__PURE__ */ r($, { children: [
671
+ /* @__PURE__ */ e("div", { className: "fixed inset-0 z-40", onClick: () => s(!1), "aria-hidden": "true" }),
672
+ /* @__PURE__ */ e(
673
+ "div",
674
+ {
675
+ className: "absolute right-0 top-full z-50 mt-1 max-h-72 w-72 overflow-y-auto rounded-lg border border-border bg-surface shadow-lg",
676
+ role: "menu",
677
+ children: Array.from(m.entries()).map(([l, f]) => /* @__PURE__ */ r("div", { className: "border-b border-border/30 last:border-b-0", children: [
678
+ /* @__PURE__ */ e("div", { className: "sticky top-0 bg-surface-hover/80 backdrop-blur px-2 py-1 text-[9px] font-semibold uppercase tracking-wider text-foreground-subtle", children: l }),
679
+ f.map((u) => /* @__PURE__ */ r(
680
+ "button",
681
+ {
682
+ type: "button",
683
+ onClick: () => {
684
+ o(u), s(!1);
685
+ },
686
+ className: "w-full text-left px-2 py-1.5 hover:bg-surface-hover transition-colors group",
687
+ children: [
688
+ /* @__PURE__ */ e("div", { className: "font-mono text-[11px] text-foreground", children: u.label }),
689
+ u.description !== void 0 && /* @__PURE__ */ e("div", { className: "text-[10px] text-foreground-subtle leading-snug mt-0.5", children: u.description })
690
+ ]
691
+ },
692
+ u.label
693
+ ))
694
+ ] }, l))
695
+ }
696
+ )
697
+ ] })
698
+ ] });
699
+ }
700
+ const te = 24;
701
+ function Ve(t) {
702
+ return /\bEdg\b|\bEdgA\b|\bEdgiOS\b|Edge\//.test(t) ? "Edge" : /\bOPR\b|Opera/.test(t) ? "Opera" : /Firefox\/|\bFxiOS\b/.test(t) ? "Firefox" : /Chrome\/|\bCriOS\b/.test(t) ? "Chrome" : /Safari\//.test(t) ? "Safari" : null;
703
+ }
704
+ function We(t) {
705
+ return /iPhone|iPad|iPod|\biOS\b|CriOS|FxiOS/.test(t) ? "iOS" : /Mac OS X|Macintosh/.test(t) ? "macOS" : /Windows/.test(t) ? "Windows" : /Android/.test(t) ? "Android" : /Linux/.test(t) ? "Linux" : null;
706
+ }
707
+ function Xe(t) {
708
+ const a = t.trim();
709
+ if (a.length === 0) return "";
710
+ const n = Ve(a), o = We(a);
711
+ return n && o ? `${n}/${o}` : n || o || (a.length > te ? `${a.slice(0, te)}…` : a);
712
+ }
713
+ function Qe(t) {
714
+ const a = Math.floor(t / 1e3);
715
+ if (a < 60) return `${a}s`;
716
+ const n = Math.floor(a / 60);
717
+ return n < 60 ? `${n}m` : `${Math.floor(n / 60)}h ${n % 60}m`;
718
+ }
719
+ const re = {
139
720
  high: "High",
140
721
  mid: "Mid",
141
722
  low: "Low"
142
- }, D = ["high", "mid", "low"];
143
- function ue(s) {
144
- const n = s.config ?? {};
145
- return s.deviceId === void 0 ? /* @__PURE__ */ e("div", { className: "rounded-lg border border-warning/30 bg-warning/10 px-3 py-2 text-xs text-warning", children: "StreamBrokerPanel requires a deviceId" }) : /* @__PURE__ */ e(
146
- me,
723
+ }, se = ["high", "mid", "low"], Ye = {
724
+ alexa: "bg-blue-500/15 text-blue-400",
725
+ homekit: "bg-purple-500/15 text-purple-400",
726
+ "webrtc-browser": "bg-emerald-500/15 text-emerald-400",
727
+ "webrtc-mobile": "bg-emerald-500/15 text-emerald-400",
728
+ "webrtc-whep": "bg-emerald-500/15 text-emerald-400",
729
+ "rtsp-listen": "bg-warning/15 text-warning",
730
+ "derived-broker": "bg-amber-500/15 text-amber-400",
731
+ recording: "bg-rose-500/15 text-rose-400",
732
+ pipeline: "bg-cyan-500/15 text-cyan-400",
733
+ snapshot: "bg-cyan-500/15 text-cyan-400",
734
+ warmup: "bg-foreground-subtle/10 text-foreground-subtle",
735
+ unknown: "bg-foreground-subtle/10 text-foreground-subtle"
736
+ }, de = {
737
+ alexa: "ALEXA",
738
+ homekit: "HOMEKIT",
739
+ "webrtc-browser": "BROWSER",
740
+ "webrtc-mobile": "MOBILE",
741
+ "webrtc-whep": "WHEP",
742
+ "rtsp-listen": "RTSP",
743
+ "derived-broker": "DERIVED",
744
+ recording: "RECORD",
745
+ pipeline: "PIPELINE",
746
+ snapshot: "SNAP",
747
+ warmup: "WARMUP",
748
+ unknown: "—"
749
+ };
750
+ function Ze(t) {
751
+ return de[t] ?? t.toUpperCase().slice(0, 8);
752
+ }
753
+ function Je(t) {
754
+ return de[t] ?? t;
755
+ }
756
+ function et(t) {
757
+ const a = t.config ?? {};
758
+ return t.deviceId === void 0 ? /* @__PURE__ */ e("div", { className: "rounded-lg border border-warning/30 bg-warning/10 px-3 py-2 text-xs text-warning", children: "StreamBrokerPanel requires a deviceId" }) : /* @__PURE__ */ e(
759
+ tt,
147
760
  {
148
- deviceId: s.deviceId,
149
- title: n.title,
150
- variant: n.variant,
151
- hideEmpty: n.hideEmpty
761
+ deviceId: t.deviceId,
762
+ title: a.title,
763
+ variant: a.variant,
764
+ hideEmpty: a.hideEmpty
152
765
  }
153
766
  );
154
767
  }
155
- function me({
156
- deviceId: s,
157
- title: n = "Stream Brokers",
158
- variant: o = "full",
159
- hideEmpty: i = !1
768
+ function tt({
769
+ deviceId: t,
770
+ title: a = "Stream Brokers",
771
+ variant: n = "full",
772
+ hideEmpty: o = !1
160
773
  }) {
161
- E(
774
+ ie(
162
775
  ["streamBroker", "listAllProfileSlots"],
163
776
  [
164
777
  "device.streams-registered",
@@ -167,188 +780,188 @@ function me({
167
780
  "device.unregistered"
168
781
  ]
169
782
  );
170
- const { data: c } = Q(
783
+ const { data: c } = fe(
171
784
  void 0,
172
785
  { staleTime: 3e4 }
173
- ), t = (c ?? []).filter((p) => p.deviceId === s && p.sourceCamStreamId !== null).slice().sort((p, N) => D.indexOf(p.profile) - D.indexOf(N.profile)), l = W(), d = X(l.trpcClient, s), { data: u } = z({
174
- queryKey: ["device", s, "cameraStreams.getCameraStreams"],
175
- queryFn: () => d?.cameraStreams?.getCameraStreams({}) ?? [],
176
- enabled: !!d,
786
+ ), s = (c ?? []).filter((h) => h.deviceId === t && h.sourceCamStreamId !== null).slice().sort((h, C) => se.indexOf(h.profile) - se.indexOf(C.profile)), m = ge(), l = be(m.trpcClient, t), { data: f } = ye({
787
+ queryKey: ["device", t, "cameraStreams.getCameraStreams"],
788
+ queryFn: () => l?.cameraStreams?.getCameraStreams({}) ?? [],
789
+ enabled: !!l,
177
790
  staleTime: 3e4
178
- }), a = /* @__PURE__ */ new Map();
179
- for (const p of u ?? []) a.set(p.camStreamId, p);
180
- const m = new Set(
181
- t.map((p) => p.sourceCamStreamId).filter((p) => p !== null)
182
- ), f = (u ?? []).filter(
183
- (p) => !m.has(p.camStreamId)
184
- ), x = t.length > 0, h = f.length > 0;
185
- return i && !x && !h ? null : o === "compact" ? x ? /* @__PURE__ */ e("div", { className: "divide-y divide-border/30", children: t.map((p) => /* @__PURE__ */ e(
186
- P,
791
+ }), u = /* @__PURE__ */ new Map();
792
+ for (const h of f ?? []) u.set(h.camStreamId, h);
793
+ const d = new Set(
794
+ s.map((h) => h.sourceCamStreamId).filter((h) => h !== null)
795
+ ), p = (f ?? []).filter(
796
+ (h) => !d.has(h.camStreamId)
797
+ ), v = s.length > 0, N = p.length > 0;
798
+ return o && !v && !N ? null : n === "compact" ? v ? /* @__PURE__ */ e("div", { className: "divide-y divide-border/30", children: s.map((h) => /* @__PURE__ */ e(
799
+ ne,
187
800
  {
188
- slot: p,
189
- camStreams: a,
801
+ slot: h,
802
+ camStreams: u,
190
803
  compact: !0
191
804
  },
192
- p.brokerId
805
+ h.brokerId
193
806
  )) }) : /* @__PURE__ */ e("div", { className: "text-[11px] text-foreground-subtle italic px-2 py-1", children: "No active profile slots" }) : /* @__PURE__ */ r("div", { className: "rounded-lg border border-border bg-surface overflow-hidden", children: [
194
807
  /* @__PURE__ */ r("div", { className: "border-b border-border px-4 py-2 flex items-center justify-between", children: [
195
- /* @__PURE__ */ e("h2", { className: "text-xs font-semibold text-foreground uppercase tracking-wider", children: n }),
196
- x && /* @__PURE__ */ r("span", { className: "inline-flex items-center gap-1.5 rounded-full px-2 py-0.5 text-[10px] font-medium bg-foreground-subtle/10 text-foreground-subtle border border-border", children: [
197
- t.length,
808
+ /* @__PURE__ */ e("h2", { className: "text-xs font-semibold text-foreground uppercase tracking-wider", children: a }),
809
+ v && /* @__PURE__ */ r("span", { className: "inline-flex items-center gap-1.5 rounded-full px-2 py-0.5 text-[10px] font-medium bg-foreground-subtle/10 text-foreground-subtle border border-border", children: [
810
+ s.length,
198
811
  " assigned"
199
812
  ] })
200
813
  ] }),
201
- x ? /* @__PURE__ */ e("div", { className: "divide-y divide-border/30", children: t.map((p) => /* @__PURE__ */ e(
202
- P,
814
+ v ? /* @__PURE__ */ e("div", { className: "divide-y divide-border/30", children: s.map((h) => /* @__PURE__ */ e(
815
+ ne,
203
816
  {
204
- slot: p,
205
- camStreams: a,
817
+ slot: h,
818
+ camStreams: u,
206
819
  compact: !1
207
820
  },
208
- p.brokerId
821
+ h.brokerId
209
822
  )) }) : /* @__PURE__ */ r("div", { className: "px-4 py-6 flex flex-col items-center text-center text-foreground-subtle", children: [
210
- /* @__PURE__ */ e(ce, { className: "h-5 w-5 mb-2 opacity-30" }),
823
+ /* @__PURE__ */ e(Me, { className: "h-5 w-5 mb-2 opacity-30" }),
211
824
  /* @__PURE__ */ e("p", { className: "text-xs", children: "No profile slots assigned for this device" })
212
825
  ] }),
213
- h && /* @__PURE__ */ e(
214
- fe,
826
+ N && /* @__PURE__ */ e(
827
+ rt,
215
828
  {
216
- deviceId: s,
217
- camStreamIds: f.map((p) => p.camStreamId),
218
- camStreams: a
829
+ deviceId: t,
830
+ camStreamIds: p.map((h) => h.camStreamId),
831
+ camStreams: u
219
832
  }
220
833
  )
221
834
  ] });
222
835
  }
223
- function fe({
224
- deviceId: s,
225
- camStreamIds: n,
226
- camStreams: o
836
+ function rt({
837
+ deviceId: t,
838
+ camStreamIds: a,
839
+ camStreams: n
227
840
  }) {
228
- const [i, c] = y(!1);
841
+ const [o, c] = x(!1);
229
842
  return /* @__PURE__ */ r("div", { className: "border-t border-border/50", children: [
230
843
  /* @__PURE__ */ r(
231
844
  "button",
232
845
  {
233
846
  type: "button",
234
- onClick: () => c((t) => !t),
847
+ onClick: () => c((s) => !s),
235
848
  className: "w-full px-4 py-1.5 flex items-center justify-between bg-surface-hover/30 hover:bg-surface-hover transition-colors",
236
849
  children: [
237
850
  /* @__PURE__ */ r("span", { className: "inline-flex items-center gap-1.5 text-[11px] uppercase tracking-wider text-foreground-subtle", children: [
238
- i ? /* @__PURE__ */ e(O, { className: "h-3 w-3" }) : /* @__PURE__ */ e(j, { className: "h-3 w-3" }),
851
+ o ? /* @__PURE__ */ e(X, { className: "h-3 w-3" }) : /* @__PURE__ */ e(Q, { className: "h-3 w-3" }),
239
852
  "Other active streams"
240
853
  ] }),
241
- /* @__PURE__ */ e("span", { className: "rounded-full px-2 py-0.5 text-[10px] font-medium bg-foreground-subtle/10 text-foreground-subtle border border-border", children: n.length })
854
+ /* @__PURE__ */ e("span", { className: "rounded-full px-2 py-0.5 text-[10px] font-medium bg-foreground-subtle/10 text-foreground-subtle border border-border", children: a.length })
242
855
  ]
243
856
  }
244
857
  ),
245
- i && /* @__PURE__ */ e("div", { className: "divide-y divide-border/30", children: n.map((t) => /* @__PURE__ */ e(
246
- he,
858
+ o && /* @__PURE__ */ e("div", { className: "divide-y divide-border/30", children: a.map((s) => /* @__PURE__ */ e(
859
+ st,
247
860
  {
248
- deviceId: s,
249
- camStreamId: t,
250
- camStreams: o
861
+ deviceId: t,
862
+ camStreamId: s,
863
+ camStreams: n
251
864
  },
252
- t
865
+ s
253
866
  )) })
254
867
  ] });
255
868
  }
256
- function he({ deviceId: s, camStreamId: n, camStreams: o }) {
257
- const i = `${s}/${n}`, t = T("stream-broker.metrics-snapshot", (u) => u.brokerId === i)?.stats, l = o.get(n), d = t?.status === "streaming";
869
+ function st({ deviceId: t, camStreamId: a, camStreams: n }) {
870
+ const o = Ce(t, a), s = le("stream-broker.metrics-snapshot", (f) => f.brokerId === o)?.stats, m = n.get(a), l = s?.status === "streaming";
258
871
  return /* @__PURE__ */ r("div", { className: "px-4 py-2", children: [
259
872
  /* @__PURE__ */ e("div", { className: "flex items-center justify-between mb-1", children: /* @__PURE__ */ r("div", { className: "flex items-center gap-1.5", children: [
260
873
  /* @__PURE__ */ e(
261
874
  "span",
262
875
  {
263
- className: `h-1.5 w-1.5 rounded-full ${d ? "bg-success" : "bg-foreground-subtle/40"}`
876
+ className: `h-1.5 w-1.5 rounded-full ${l ? "bg-success" : "bg-foreground-subtle/40"}`
264
877
  }
265
878
  ),
266
- /* @__PURE__ */ e("span", { className: "text-[11px] font-medium text-foreground", children: l?.label ?? n }),
267
- l?.resolution && /* @__PURE__ */ r("span", { className: "text-[10px] text-foreground-subtle", children: [
268
- l.resolution.width,
879
+ /* @__PURE__ */ e("span", { className: "text-[11px] font-medium text-foreground", children: m?.label ?? a }),
880
+ m?.resolution && /* @__PURE__ */ r("span", { className: "text-[10px] text-foreground-subtle", children: [
881
+ m.resolution.width,
269
882
  "×",
270
- l.resolution.height
883
+ m.resolution.height
271
884
  ] }),
272
- /* @__PURE__ */ e("span", { className: `text-[10px] ${d ? "text-success" : "text-foreground-subtle"}`, children: t?.status ?? "idle" })
885
+ /* @__PURE__ */ e("span", { className: `text-[10px] ${l ? "text-success" : "text-foreground-subtle"}`, children: s?.status ?? "idle" })
273
886
  ] }) }),
274
- t && d && /* @__PURE__ */ r("div", { className: "flex flex-wrap gap-x-3 gap-y-1 text-[10px]", children: [
887
+ s && l && /* @__PURE__ */ r("div", { className: "flex flex-wrap gap-x-3 gap-y-1 text-[10px]", children: [
275
888
  /* @__PURE__ */ r("span", { className: "inline-flex whitespace-nowrap gap-1", children: [
276
889
  /* @__PURE__ */ e("span", { className: "text-foreground-subtle", children: "FPS:" }),
277
- /* @__PURE__ */ e("span", { className: "text-foreground", children: t.inputFps.toFixed(1) })
890
+ /* @__PURE__ */ e("span", { className: "text-foreground", children: s.inputFps.toFixed(1) })
278
891
  ] }),
279
892
  /* @__PURE__ */ r("span", { className: "inline-flex whitespace-nowrap gap-1", children: [
280
893
  /* @__PURE__ */ e("span", { className: "text-foreground-subtle", children: "Bitrate:" }),
281
- /* @__PURE__ */ e("span", { className: "text-foreground", children: t.bitrateKbps >= 1e3 ? `${(t.bitrateKbps / 1e3).toFixed(1)} Mbps` : `${t.bitrateKbps} kbps` })
894
+ /* @__PURE__ */ e("span", { className: "text-foreground", children: s.bitrateKbps >= 1e3 ? `${(s.bitrateKbps / 1e3).toFixed(1)} Mbps` : `${s.bitrateKbps} kbps` })
282
895
  ] }),
283
896
  /* @__PURE__ */ r("span", { className: "inline-flex whitespace-nowrap gap-1", children: [
284
897
  /* @__PURE__ */ e("span", { className: "text-foreground-subtle", children: "Codec:" }),
285
- /* @__PURE__ */ e("span", { className: "text-foreground", children: t.codec?.toUpperCase() ?? "—" })
898
+ /* @__PURE__ */ e("span", { className: "text-foreground", children: s.codec?.toUpperCase() ?? "—" })
286
899
  ] }),
287
900
  /* @__PURE__ */ r("span", { className: "inline-flex whitespace-nowrap gap-1", children: [
288
901
  /* @__PURE__ */ e("span", { className: "text-foreground-subtle", children: "Pkts:" }),
289
- /* @__PURE__ */ e("span", { className: "text-foreground", children: t.packetCount > 1e3 ? `${(t.packetCount / 1e3).toFixed(1)}k` : t.packetCount })
902
+ /* @__PURE__ */ e("span", { className: "text-foreground", children: s.packetCount > 1e3 ? `${(s.packetCount / 1e3).toFixed(1)}k` : s.packetCount })
290
903
  ] })
291
904
  ] })
292
905
  ] });
293
906
  }
294
- function M(s, n) {
295
- const o = (i) => {
296
- if (!i || typeof i != "object") return;
297
- const c = i;
298
- if (typeof c.key == "string" && c.key === n && "value" in c) return c.value;
907
+ function ae(t, a) {
908
+ const n = (o) => {
909
+ if (!o || typeof o != "object") return;
910
+ const c = o;
911
+ if (typeof c.key == "string" && c.key === a && "value" in c) return c.value;
299
912
  if (c.type === "group" && Array.isArray(c.fields))
300
- for (const t of c.fields) {
301
- const l = o(t);
302
- if (l !== void 0) return l;
913
+ for (const s of c.fields) {
914
+ const m = n(s);
915
+ if (m !== void 0) return m;
303
916
  }
304
917
  else if (c.type === "sub-tabs" && Array.isArray(c.tabs)) {
305
- for (const t of c.tabs)
306
- if (Array.isArray(t.fields))
307
- for (const l of t.fields) {
308
- const d = o(l);
309
- if (d !== void 0) return d;
918
+ for (const s of c.tabs)
919
+ if (Array.isArray(s.fields))
920
+ for (const m of s.fields) {
921
+ const l = n(m);
922
+ if (l !== void 0) return l;
310
923
  }
311
924
  }
312
925
  };
313
- for (const i of s?.sections ?? [])
314
- if (Array.isArray(i.fields))
315
- for (const c of i.fields) {
316
- const t = o(c);
317
- if (t !== void 0) return t;
926
+ for (const o of t?.sections ?? [])
927
+ if (Array.isArray(o.fields))
928
+ for (const c of o.fields) {
929
+ const s = n(c);
930
+ if (s !== void 0) return s;
318
931
  }
319
932
  }
320
- function P({ slot: s, camStreams: n, compact: o }) {
321
- const i = G(), t = T("stream-broker.metrics-snapshot", (b) => b.brokerId === s.brokerId)?.stats;
322
- E(["streamBroker", "listClients"], ["stream-broker.metrics-snapshot"]);
323
- const { data: l } = Z(
324
- { brokerId: s.brokerId },
325
- { enabled: t?.status === "streaming", staleTime: 2e3 }
326
- ), { data: d } = V(
327
- { deviceId: s.deviceId },
933
+ function ne({ slot: t, camStreams: a, compact: n }) {
934
+ const o = ke(), s = le("stream-broker.metrics-snapshot", (k) => k.brokerId === t.brokerId)?.stats;
935
+ ie(["streamBroker", "listClients"], ["stream-broker.metrics-snapshot"]);
936
+ const { data: m } = xe(
937
+ { brokerId: t.brokerId },
938
+ { enabled: s?.status === "streaming", staleTime: 2e3 }
939
+ ), { data: l } = ve(
940
+ { deviceId: t.deviceId },
328
941
  { staleTime: 15e3 }
329
- ), u = s.sourceCamStreamId ?? s.profile, a = !!(M(d, `preBufferEnabled:${u}`) ?? !0), m = M(d, `preBufferSec:${u}`), f = J({
942
+ ), f = t.sourceCamStreamId ?? t.profile, u = !!(ae(l, `preBufferEnabled:${f}`) ?? !0), d = ae(l, `preBufferSec:${f}`), p = Ne({
330
943
  onSuccess: () => {
331
- i.invalidateQueries({ queryKey: [["streamBroker", "getDeviceSettingsContribution"]] });
944
+ o.invalidateQueries({ queryKey: [["streamBroker", "getDeviceSettingsContribution"]] });
332
945
  }
333
- }), x = (b) => {
334
- f.mutate({
335
- deviceId: s.deviceId,
336
- patch: { [`preBufferEnabled:${u}`]: b }
946
+ }), v = (k) => {
947
+ p.mutate({
948
+ deviceId: t.deviceId,
949
+ patch: { [`preBufferEnabled:${f}`]: k }
337
950
  });
338
- }, h = Y({
951
+ }, N = we({
339
952
  onSuccess: () => {
340
- i.invalidateQueries({ queryKey: [["streamBroker", "listClients"]] });
953
+ o.invalidateQueries({ queryKey: [["streamBroker", "listClients"]] });
341
954
  }
342
- }), p = k(
343
- (b) => {
344
- h.mutate({ brokerId: s.brokerId, ...b });
955
+ }), h = R(
956
+ (k) => {
957
+ N.mutate({ brokerId: t.brokerId, ...k });
345
958
  },
346
- [h, s.brokerId]
347
- ), w = (s.sourceCamStreamId ? n.get(s.sourceCamStreamId) : void 0)?.resolution ?? s.resolution, v = t?.status === "streaming", q = w ? `${F[s.profile]} (${w.width}×${w.height})` : F[s.profile], H = t ? t.encodedSubscribers + t.decodedSubscribers + (t.rtspClients ?? 0) + (t.pipeClients ?? 0) : 0;
959
+ [N, t.brokerId]
960
+ ), w = (t.sourceCamStreamId ? a.get(t.sourceCamStreamId) : void 0)?.resolution ?? t.resolution, A = s?.status === "streaming", S = w ? `${re[t.profile]} (${w.width}×${w.height})` : re[t.profile], M = s ? s.encodedSubscribers + s.decodedSubscribers + (s.rtspClients ?? 0) + (s.pipeClients ?? 0) : 0;
348
961
  return /* @__PURE__ */ r(
349
962
  "div",
350
963
  {
351
- className: `@container ${o ? "px-3 py-1.5" : "px-4 py-2"}`,
964
+ className: `@container ${n ? "px-3 py-1.5" : "px-4 py-2"}`,
352
965
  style: { containerType: "inline-size" },
353
966
  children: [
354
967
  /* @__PURE__ */ r("div", { className: "flex items-center justify-between mb-1.5", children: [
@@ -356,184 +969,184 @@ function P({ slot: s, camStreams: n, compact: o }) {
356
969
  /* @__PURE__ */ e(
357
970
  "span",
358
971
  {
359
- className: `h-1.5 w-1.5 rounded-full ${v ? s.profile === "high" ? "bg-success" : s.profile === "mid" ? "bg-warning" : "bg-foreground-subtle" : "bg-foreground-subtle/40"}`
972
+ className: `h-1.5 w-1.5 rounded-full ${A ? t.profile === "high" ? "bg-success" : t.profile === "mid" ? "bg-warning" : "bg-foreground-subtle" : "bg-foreground-subtle/40"}`
360
973
  }
361
974
  ),
362
- /* @__PURE__ */ e("span", { className: "text-[11px] font-medium text-foreground", children: q }),
363
- /* @__PURE__ */ e("span", { className: `text-[10px] ${v ? "text-success" : "text-foreground-subtle"}`, children: t?.status ?? "loading" }),
364
- s.sourceCamStreamId && /* @__PURE__ */ r("span", { className: "text-[10px] text-foreground-subtle", children: [
975
+ /* @__PURE__ */ e("span", { className: "text-[11px] font-medium text-foreground", children: S }),
976
+ /* @__PURE__ */ e("span", { className: `text-[10px] ${A ? "text-success" : "text-foreground-subtle"}`, children: s?.status ?? "loading" }),
977
+ t.sourceCamStreamId && /* @__PURE__ */ r("span", { className: "text-[10px] text-foreground-subtle", children: [
365
978
  "← ",
366
- s.sourceCamStreamId
979
+ t.sourceCamStreamId
367
980
  ] })
368
981
  ] }),
369
- /* @__PURE__ */ e("span", { className: "text-[10px] text-foreground-subtle", children: t && t.uptimeMs > 0 ? pe(t.uptimeMs) : "—" })
982
+ /* @__PURE__ */ e("span", { className: "text-[10px] text-foreground-subtle", children: s && s.uptimeMs > 0 ? Qe(s.uptimeMs) : "—" })
370
983
  ] }),
371
- t && v ? o ? /* @__PURE__ */ r("div", { className: "flex flex-wrap gap-x-3 gap-y-0.5 text-[10px]", children: [
984
+ s && A ? n ? /* @__PURE__ */ r("div", { className: "flex flex-wrap gap-x-3 gap-y-0.5 text-[10px]", children: [
372
985
  /* @__PURE__ */ r("span", { className: "inline-flex whitespace-nowrap gap-1", children: [
373
986
  /* @__PURE__ */ e("span", { className: "text-foreground-subtle", children: "FPS:" }),
374
987
  /* @__PURE__ */ r("span", { className: "text-foreground", children: [
375
- t.inputFps.toFixed(1),
988
+ s.inputFps.toFixed(1),
376
989
  "/",
377
- t.decodeFps.toFixed(1)
990
+ s.decodeFps.toFixed(1)
378
991
  ] })
379
992
  ] }),
380
993
  /* @__PURE__ */ r("span", { className: "inline-flex whitespace-nowrap gap-1", children: [
381
994
  /* @__PURE__ */ e("span", { className: "text-foreground-subtle", children: "Bitrate:" }),
382
- /* @__PURE__ */ e("span", { className: "text-foreground", children: t.bitrateKbps >= 1e3 ? `${(t.bitrateKbps / 1e3).toFixed(1)} Mbps` : `${t.bitrateKbps} kbps` })
995
+ /* @__PURE__ */ e("span", { className: "text-foreground", children: s.bitrateKbps >= 1e3 ? `${(s.bitrateKbps / 1e3).toFixed(1)} Mbps` : `${s.bitrateKbps} kbps` })
383
996
  ] }),
384
997
  /* @__PURE__ */ r("span", { className: "inline-flex whitespace-nowrap gap-1", children: [
385
998
  /* @__PURE__ */ e("span", { className: "text-foreground-subtle", children: "Codec:" }),
386
- /* @__PURE__ */ e("span", { className: "text-foreground", children: t.codec?.toUpperCase() ?? "—" })
999
+ /* @__PURE__ */ e("span", { className: "text-foreground", children: s.codec?.toUpperCase() ?? "—" })
387
1000
  ] }),
388
1001
  /* @__PURE__ */ r("span", { className: "inline-flex items-center whitespace-nowrap gap-1", children: [
389
1002
  /* @__PURE__ */ e("span", { className: "text-foreground-subtle", children: "Clients:" }),
390
- /* @__PURE__ */ e("span", { className: "text-foreground font-semibold", children: H }),
1003
+ /* @__PURE__ */ e("span", { className: "text-foreground font-semibold", children: M }),
391
1004
  /* @__PURE__ */ e("span", { className: "text-foreground-subtle/70", children: "(" }),
392
- /* @__PURE__ */ e(Ne, { count: t.encodedSubscribers + t.decodedSubscribers, clients: l, onKill: p }),
1005
+ /* @__PURE__ */ e(it, { count: s.encodedSubscribers + s.decodedSubscribers, clients: m, onKill: h }),
393
1006
  /* @__PURE__ */ e("span", { className: "text-foreground-subtle/70", children: "·" }),
394
- /* @__PURE__ */ e(ve, { count: t.rtspClients ?? 0, clients: l, onKill: p }),
1007
+ /* @__PURE__ */ e(ct, { count: s.rtspClients ?? 0, clients: m, onKill: h }),
395
1008
  /* @__PURE__ */ r("span", { className: "text-foreground-subtle/70", children: [
396
1009
  "· pipe ",
397
- t.pipeClients ?? 0,
1010
+ s.pipeClients ?? 0,
398
1011
  ")"
399
1012
  ] })
400
1013
  ] })
401
- ] }) : /* @__PURE__ */ r(B, { children: [
1014
+ ] }) : /* @__PURE__ */ r($, { children: [
402
1015
  /* @__PURE__ */ r("div", { className: "flex flex-wrap gap-x-3 gap-y-1 text-[10px]", children: [
403
1016
  /* @__PURE__ */ r("span", { className: "inline-flex whitespace-nowrap gap-1", children: [
404
1017
  /* @__PURE__ */ e("span", { className: "text-foreground-subtle", children: "In:" }),
405
1018
  /* @__PURE__ */ r("span", { className: "text-foreground", children: [
406
- t.inputFps.toFixed(1),
1019
+ s.inputFps.toFixed(1),
407
1020
  " fps"
408
1021
  ] })
409
1022
  ] }),
410
1023
  /* @__PURE__ */ r("span", { className: "inline-flex whitespace-nowrap gap-1", children: [
411
1024
  /* @__PURE__ */ e("span", { className: "text-foreground-subtle", children: "Dec:" }),
412
1025
  /* @__PURE__ */ r("span", { className: "text-foreground", children: [
413
- t.decodeFps.toFixed(1),
1026
+ s.decodeFps.toFixed(1),
414
1027
  " fps"
415
1028
  ] })
416
1029
  ] }),
417
1030
  /* @__PURE__ */ r("span", { className: "inline-flex whitespace-nowrap gap-1", children: [
418
1031
  /* @__PURE__ */ e("span", { className: "text-foreground-subtle", children: "Bitrate:" }),
419
- /* @__PURE__ */ e("span", { className: "text-foreground", children: t.bitrateKbps >= 1e3 ? `${(t.bitrateKbps / 1e3).toFixed(1)} Mbps` : `${t.bitrateKbps} kbps` })
1032
+ /* @__PURE__ */ e("span", { className: "text-foreground", children: s.bitrateKbps >= 1e3 ? `${(s.bitrateKbps / 1e3).toFixed(1)} Mbps` : `${s.bitrateKbps} kbps` })
420
1033
  ] }),
421
1034
  /* @__PURE__ */ r("span", { className: "hidden @[480px]:inline-flex whitespace-nowrap gap-1", children: [
422
1035
  /* @__PURE__ */ e("span", { className: "text-foreground-subtle", children: "IDR:" }),
423
- /* @__PURE__ */ e("span", { className: "text-foreground", children: t.idrIntervalMs > 0 ? `${(t.idrIntervalMs / 1e3).toFixed(1)}s` : "—" })
1036
+ /* @__PURE__ */ e("span", { className: "text-foreground", children: s.idrIntervalMs > 0 ? `${(s.idrIntervalMs / 1e3).toFixed(1)}s` : "—" })
424
1037
  ] }),
425
1038
  /* @__PURE__ */ r("span", { className: "inline-flex whitespace-nowrap gap-1", children: [
426
1039
  /* @__PURE__ */ e("span", { className: "text-foreground-subtle", children: "Codec:" }),
427
- /* @__PURE__ */ e("span", { className: "text-foreground", children: t.codec?.toUpperCase() ?? "—" })
1040
+ /* @__PURE__ */ e("span", { className: "text-foreground", children: s.codec?.toUpperCase() ?? "—" })
428
1041
  ] }),
429
1042
  /* @__PURE__ */ r("span", { className: "hidden @[480px]:inline-flex whitespace-nowrap gap-1 max-w-full overflow-hidden", children: [
430
1043
  /* @__PURE__ */ e("span", { className: "text-foreground-subtle", children: "Decoder:" }),
431
- /* @__PURE__ */ e("span", { className: "text-foreground font-mono truncate", children: t.decoderNodeId ?? /* @__PURE__ */ e("span", { className: "text-foreground-subtle italic", children: "deferred" }) })
1044
+ /* @__PURE__ */ e("span", { className: "text-foreground font-mono truncate", children: s.decoderNodeId ?? /* @__PURE__ */ e("span", { className: "text-foreground-subtle italic", children: "deferred" }) })
432
1045
  ] }),
433
1046
  /* @__PURE__ */ r("span", { className: "hidden @[640px]:inline-flex whitespace-nowrap gap-1", children: [
434
1047
  /* @__PURE__ */ e("span", { className: "text-foreground-subtle", children: "Pipe:" }),
435
- /* @__PURE__ */ e("span", { className: "text-foreground", children: t.pipeClients ?? 0 })
1048
+ /* @__PURE__ */ e("span", { className: "text-foreground", children: s.pipeClients ?? 0 })
436
1049
  ] }),
437
1050
  /* @__PURE__ */ r("span", { className: "hidden @[640px]:inline-flex whitespace-nowrap gap-1", children: [
438
1051
  /* @__PURE__ */ e("span", { className: "text-foreground-subtle", children: "Packets:" }),
439
- /* @__PURE__ */ e("span", { className: "text-foreground", children: t.packetCount > 1e3 ? `${(t.packetCount / 1e3).toFixed(1)}k` : t.packetCount })
1052
+ /* @__PURE__ */ e("span", { className: "text-foreground", children: s.packetCount > 1e3 ? `${(s.packetCount / 1e3).toFixed(1)}k` : s.packetCount })
440
1053
  ] }),
441
1054
  /* @__PURE__ */ r("span", { className: "hidden @[640px]:inline-flex whitespace-nowrap gap-1", children: [
442
1055
  /* @__PURE__ */ e("span", { className: "text-foreground-subtle", children: "Data:" }),
443
- /* @__PURE__ */ e("span", { className: "text-foreground", children: t.totalBytes > 1048576 ? `${(t.totalBytes / 1048576).toFixed(1)} MB` : `${(t.totalBytes / 1024).toFixed(0)} KB` })
1056
+ /* @__PURE__ */ e("span", { className: "text-foreground", children: s.totalBytes > 1048576 ? `${(s.totalBytes / 1048576).toFixed(1)} MB` : `${(s.totalBytes / 1024).toFixed(0)} KB` })
444
1057
  ] }),
445
- t.audio && /* @__PURE__ */ r("div", { className: "basis-full flex flex-wrap items-center gap-x-1.5 gap-y-0.5", children: [
1058
+ s.audio && /* @__PURE__ */ r("div", { className: "basis-full flex flex-wrap items-center gap-x-1.5 gap-y-0.5", children: [
446
1059
  /* @__PURE__ */ e("span", { className: "text-foreground-subtle whitespace-nowrap", children: "Audio:" }),
447
1060
  /* @__PURE__ */ r("span", { className: "inline-flex whitespace-nowrap items-center gap-1.5", children: [
448
- /* @__PURE__ */ e("span", { className: "text-foreground", children: t.audio.codec.toUpperCase() }),
1061
+ /* @__PURE__ */ e("span", { className: "text-foreground", children: s.audio.codec.toUpperCase() }),
449
1062
  /* @__PURE__ */ e("span", { className: "text-foreground-subtle", children: "·" }),
450
- /* @__PURE__ */ e("span", { className: "text-foreground", children: t.audio.sampleRate >= 1e3 ? `${(t.audio.sampleRate / 1e3).toFixed(t.audio.sampleRate % 1e3 === 0 ? 0 : 1)}kHz` : `${t.audio.sampleRate}Hz` }),
1063
+ /* @__PURE__ */ e("span", { className: "text-foreground", children: s.audio.sampleRate >= 1e3 ? `${(s.audio.sampleRate / 1e3).toFixed(s.audio.sampleRate % 1e3 === 0 ? 0 : 1)}kHz` : `${s.audio.sampleRate}Hz` }),
451
1064
  /* @__PURE__ */ e("span", { className: "text-foreground-subtle", children: "·" }),
452
- /* @__PURE__ */ e("span", { className: "text-foreground", children: t.audio.channels === 1 ? "mono" : t.audio.channels === 2 ? "stereo" : `${t.audio.channels}ch` })
1065
+ /* @__PURE__ */ e("span", { className: "text-foreground", children: s.audio.channels === 1 ? "mono" : s.audio.channels === 2 ? "stereo" : `${s.audio.channels}ch` })
453
1066
  ] }),
454
- /* @__PURE__ */ e("span", { className: `px-1 py-px rounded text-[8px] font-medium whitespace-nowrap ${t.audio.supported ? "bg-success/15 text-success" : "bg-amber-500/15 text-amber-500"}`, children: t.audio.supported ? "decoded" : "no decoder" })
1067
+ /* @__PURE__ */ e("span", { className: `px-1 py-px rounded text-[8px] font-medium whitespace-nowrap ${s.audio.supported ? "bg-success/15 text-success" : "bg-amber-500/15 text-amber-500"}`, children: s.audio.supported ? "decoded" : "no decoder" })
455
1068
  ] })
456
1069
  ] }),
457
- /* @__PURE__ */ e(ge, { clients: l, encodedCount: t.encodedSubscribers, onKill: p })
1070
+ /* @__PURE__ */ e(ot, { clients: m, encodedCount: s.encodedSubscribers, onKill: h })
458
1071
  ] }) : /* @__PURE__ */ e("p", { className: "text-[10px] text-foreground-subtle italic", children: "No demand — stream suspended" }),
459
1072
  /* @__PURE__ */ r("div", { className: "mt-1.5 flex items-center gap-1.5 text-[10px]", children: [
460
1073
  /* @__PURE__ */ e("span", { className: "text-foreground-subtle", children: "Buffer:" }),
461
1074
  /* @__PURE__ */ e(
462
- we,
1075
+ lt,
463
1076
  {
464
- enabled: a,
465
- onToggle: (b) => x(b),
466
- disabled: f.isPending
1077
+ enabled: u,
1078
+ onToggle: (k) => v(k),
1079
+ disabled: p.isPending
467
1080
  }
468
1081
  ),
469
1082
  /* @__PURE__ */ r("span", { className: "text-foreground", children: [
470
- m ?? t?.preBufferSec ?? 0,
1083
+ d ?? s?.preBufferSec ?? 0,
471
1084
  "s",
472
- t && v ? ` (${t.preBufferPackets}p)` : ""
1085
+ s && A ? ` (${s.preBufferPackets}p)` : ""
473
1086
  ] })
474
1087
  ] })
475
1088
  ]
476
1089
  }
477
1090
  );
478
1091
  }
479
- const xe = 280, be = 120;
480
- function K({ trigger: s, content: n, widthClass: o }) {
481
- const i = I(null), c = I(null), [t, l] = y(!1), [d, u] = y(!1), a = k(() => {
1092
+ const at = 280, nt = 120;
1093
+ function ue({ trigger: t, content: a, widthClass: n }) {
1094
+ const o = W(null), c = W(null), [s, m] = x(!1), [l, f] = x(!1), u = R(() => {
482
1095
  c.current && (clearTimeout(c.current), c.current = null);
483
- }, []), m = k(() => {
484
- a(), c.current = setTimeout(() => l(!1), be);
485
- }, [a]), f = k(() => {
486
- a();
487
- const h = i.current;
488
- if (h) {
489
- const p = h.getBoundingClientRect(), N = window.innerHeight - p.bottom, w = p.top;
490
- u(N < xe && w > N);
1096
+ }, []), d = R(() => {
1097
+ u(), c.current = setTimeout(() => m(!1), nt);
1098
+ }, [u]), p = R(() => {
1099
+ u();
1100
+ const N = o.current;
1101
+ if (N) {
1102
+ const h = N.getBoundingClientRect(), C = window.innerHeight - h.bottom, w = h.top;
1103
+ f(C < at && w > C);
491
1104
  }
492
- l(!0);
493
- }, [a]);
1105
+ m(!0);
1106
+ }, [u]);
494
1107
  return /* @__PURE__ */ r(
495
1108
  "span",
496
1109
  {
497
- ref: i,
1110
+ ref: o,
498
1111
  className: "relative inline-block",
499
- onMouseEnter: f,
500
- onMouseLeave: m,
1112
+ onMouseEnter: p,
1113
+ onMouseLeave: d,
501
1114
  children: [
502
- s,
503
- t && /* @__PURE__ */ e(
1115
+ t,
1116
+ s && /* @__PURE__ */ e(
504
1117
  "div",
505
1118
  {
506
- className: `absolute left-0 ${d ? "bottom-full mb-1" : "top-full mt-1"} z-50 ${o} rounded-md border border-border bg-surface shadow-xl p-2 text-[10px] normal-case`,
507
- onMouseEnter: a,
508
- onMouseLeave: m,
509
- children: n
1119
+ className: `absolute left-0 ${l ? "bottom-full mb-1" : "top-full mt-1"} z-50 ${n} rounded-md border border-border bg-surface shadow-xl p-2 text-[10px] normal-case`,
1120
+ onMouseEnter: u,
1121
+ onMouseLeave: d,
1122
+ children: a
510
1123
  }
511
1124
  )
512
1125
  ]
513
1126
  }
514
1127
  );
515
1128
  }
516
- function g(s) {
517
- if (s < 1e3) return `${s}ms`;
518
- const n = Math.floor(s / 1e3);
519
- if (n < 60) return `${n}s`;
520
- const o = Math.floor(n / 60);
521
- return o < 60 ? `${o}m ${n % 60}s` : `${Math.floor(o / 60)}h ${o % 60}m`;
1129
+ function D(t) {
1130
+ if (t < 1e3) return `${t}ms`;
1131
+ const a = Math.floor(t / 1e3);
1132
+ if (a < 60) return `${a}s`;
1133
+ const n = Math.floor(a / 60);
1134
+ return n < 60 ? `${n}m ${a % 60}s` : `${Math.floor(n / 60)}h ${n % 60}m`;
522
1135
  }
523
- function U(s) {
524
- return s < 1024 ? `${s} B` : s < 1048576 ? `${(s / 1024).toFixed(1)} KB` : s < 1073741824 ? `${(s / 1048576).toFixed(1)} MB` : `${(s / 1073741824).toFixed(2)} GB`;
1136
+ function pe(t) {
1137
+ return t < 1024 ? `${t} B` : t < 1048576 ? `${(t / 1024).toFixed(1)} KB` : t < 1073741824 ? `${(t / 1048576).toFixed(1)} MB` : `${(t / 1073741824).toFixed(2)} GB`;
525
1138
  }
526
- function ge({ clients: s, encodedCount: n, onKill: o }) {
527
- const i = s?.decoded ?? [], c = s?.audio ?? [], t = s?.rtsp ?? [], l = i.length + c.length + t.length + n, [d, u] = y(!0);
1139
+ function ot({ clients: t, encodedCount: a, onKill: n }) {
1140
+ const o = t?.decoded ?? [], c = t?.audio ?? [], s = t?.rtsp ?? [], m = t?.encoded ?? [], l = o.length + c.length + s.length + m.length, [f, u] = x(!0);
528
1141
  return l === 0 ? /* @__PURE__ */ e("div", { className: "mt-1.5 text-[10px] text-foreground-subtle italic", children: "No active subscribers" }) : /* @__PURE__ */ r("div", { className: "mt-1.5 border-t border-border/30 pt-1.5", children: [
529
1142
  /* @__PURE__ */ r(
530
1143
  "button",
531
1144
  {
532
1145
  type: "button",
533
- onClick: () => u((a) => !a),
1146
+ onClick: () => u((d) => !d),
534
1147
  className: "flex items-center gap-1 text-[10px] text-foreground-subtle hover:text-foreground transition-colors",
535
1148
  children: [
536
- d ? /* @__PURE__ */ e(O, { className: "h-3 w-3" }) : /* @__PURE__ */ e(j, { className: "h-3 w-3" }),
1149
+ f ? /* @__PURE__ */ e(X, { className: "h-3 w-3" }) : /* @__PURE__ */ e(Q, { className: "h-3 w-3" }),
537
1150
  /* @__PURE__ */ r("span", { className: "uppercase tracking-wider", children: [
538
1151
  "Subscribers (",
539
1152
  l,
@@ -542,211 +1155,228 @@ function ge({ clients: s, encodedCount: n, onKill: o }) {
542
1155
  ]
543
1156
  }
544
1157
  ),
545
- d && /* @__PURE__ */ r("div", { className: "mt-1 divide-y divide-border/20", children: [
546
- i.map((a, m) => /* @__PURE__ */ e(
547
- $,
1158
+ f && /* @__PURE__ */ r("div", { className: "mt-1 divide-y divide-border/20", children: [
1159
+ o.map((d, p) => /* @__PURE__ */ e(
1160
+ H,
548
1161
  {
549
1162
  kind: "DECODED",
550
1163
  kindClass: "bg-success/10 text-success",
551
- tag: a.tag || "unknown",
1164
+ tag: d.tag || "unknown",
552
1165
  metrics: [
553
- `${a.maxFps.toFixed(0)}fps`,
554
- `${a.framesDelivered} del`,
555
- ...a.framesDropped > 0 ? [{ text: `${a.framesDropped} drop`, warn: !0 }] : []
1166
+ `${d.maxFps.toFixed(0)}fps`,
1167
+ `${d.framesDelivered} del`,
1168
+ ...d.framesDropped > 0 ? [{ text: `${d.framesDropped} drop`, warn: !0 }] : []
556
1169
  ],
557
- age: Date.now() - a.subscribedAt,
558
- onKill: o && a.tag ? () => o({ channel: "decoded", handle: a.tag }) : void 0
1170
+ age: Date.now() - d.subscribedAt,
1171
+ onKill: n && d.tag ? () => n({ channel: "decoded", handle: d.tag }) : void 0
559
1172
  },
560
- `d-${m}`
1173
+ `d-${p}`
561
1174
  )),
562
- c.map((a, m) => /* @__PURE__ */ e(
563
- $,
1175
+ c.map((d, p) => /* @__PURE__ */ e(
1176
+ H,
564
1177
  {
565
1178
  kind: "AUDIO",
566
1179
  kindClass: "bg-info/10 text-info",
567
- tag: a.tag || "unknown",
568
- metrics: [`${a.chunksDelivered} chunks`],
569
- age: Date.now() - a.subscribedAt,
570
- onKill: o && a.tag ? () => o({ channel: "audio", handle: a.tag }) : void 0
1180
+ tag: d.tag || "unknown",
1181
+ metrics: [`${d.chunksDelivered} chunks`],
1182
+ age: Date.now() - d.subscribedAt,
1183
+ onKill: n && d.tag ? () => n({ channel: "audio", handle: d.tag }) : void 0
571
1184
  },
572
- `a-${m}`
1185
+ `a-${p}`
573
1186
  )),
574
- t.map((a) => {
575
- const m = Date.now() - a.lastRtpAt, f = m > 5e3, x = a.playing ? f ? "stalled" : "playing" : "paused", h = a.playing ? f ? "bg-amber-400/10 text-amber-400" : "bg-success/10 text-success" : "bg-foreground-subtle/10 text-foreground-subtle";
1187
+ s.map((d) => {
1188
+ const p = Date.now() - d.lastRtpAt, v = p > 5e3, N = d.playing ? v ? "stalled" : "playing" : "paused", h = d.playing ? v ? "bg-amber-400/10 text-amber-400" : "bg-success/10 text-success" : "bg-foreground-subtle/10 text-foreground-subtle";
576
1189
  return /* @__PURE__ */ e(
577
- $,
1190
+ H,
578
1191
  {
579
1192
  kind: "RTSP",
580
1193
  kindClass: "bg-warning/10 text-warning",
581
- tag: a.remoteAddr,
582
- state: { text: x + (a.muted ? " · muted" : ""), className: h },
583
- metrics: [U(a.bytesSent), `last rtp ${g(m)} ago`],
584
- age: Date.now() - a.connectedAt,
585
- onKill: o ? () => o({ channel: "rtsp", handle: a.sessionId }) : void 0
1194
+ tag: d.remoteAddr,
1195
+ state: { text: N + (d.muted ? " · muted" : ""), className: h },
1196
+ metrics: [pe(d.bytesSent), `last rtp ${D(p)} ago`],
1197
+ age: Date.now() - d.connectedAt,
1198
+ onKill: n ? () => n({ channel: "rtsp", handle: d.sessionId }) : void 0
1199
+ },
1200
+ `r-${d.sessionId}`
1201
+ );
1202
+ }),
1203
+ m.map((d) => {
1204
+ const p = d.attribution, v = Ye[p.kind] ?? "bg-foreground-subtle/10 text-foreground-subtle", N = p.sessionId ? p.sessionId.slice(0, 8) : null, h = [];
1205
+ p.label && h.push(p.label), N && h.push(`sess ${N}`), p.userId && h.push(`user ${p.userId.slice(0, 8)}`), p.remoteAddr && h.push(`@${p.remoteAddr}`), p.userAgent && h.push(Xe(p.userAgent));
1206
+ const C = h.length > 0 ? h.join(" · ") : Je(p.kind), w = [];
1207
+ return p.media && w.push({ text: p.media }), p.targetCodec && w.push(p.targetCodec), p.transport && w.push(p.transport), w.push(`${d.packetsDelivered} pkts`), /* @__PURE__ */ e(
1208
+ H,
1209
+ {
1210
+ kind: Ze(p.kind),
1211
+ kindClass: v,
1212
+ tag: C,
1213
+ metrics: w,
1214
+ age: Date.now() - d.subscribedAt
586
1215
  },
587
- `r-${a.sessionId}`
1216
+ d.id
588
1217
  );
589
1218
  }),
590
- n > 0 && /* @__PURE__ */ r("div", { className: "py-0.5 text-[10px] text-foreground-subtle", children: [
1219
+ m.length === 0 && a > 0 && /* @__PURE__ */ r("div", { className: "py-0.5 text-[10px] text-foreground-subtle", children: [
591
1220
  /* @__PURE__ */ e("span", { className: "inline-block px-1 rounded text-[9px] font-bold bg-foreground-subtle/10 text-foreground-subtle mr-2", children: "ENCODED" }),
592
- n,
1221
+ a,
593
1222
  " callback subscriber(s)"
594
1223
  ] })
595
1224
  ] })
596
1225
  ] });
597
1226
  }
598
- function $({ kind: s, kindClass: n, tag: o, state: i, metrics: c, age: t, onKill: l }) {
1227
+ function H({ kind: t, kindClass: a, tag: n, state: o, metrics: c, age: s, onKill: m }) {
599
1228
  return /* @__PURE__ */ r("div", { className: "flex items-center gap-2 py-0.5 text-[10px]", children: [
600
- /* @__PURE__ */ e("span", { className: `inline-block px-1 rounded text-[9px] font-bold shrink-0 w-14 text-center ${n}`, children: s }),
601
- /* @__PURE__ */ e("span", { className: "text-foreground font-medium truncate flex-1", children: o }),
602
- i && /* @__PURE__ */ e("span", { className: `text-[9px] px-1 rounded shrink-0 ${i.className}`, children: i.text }),
1229
+ /* @__PURE__ */ e("span", { className: `inline-block px-1 rounded text-[9px] font-bold shrink-0 w-14 text-center ${a}`, children: t }),
1230
+ /* @__PURE__ */ e("span", { className: "text-foreground font-medium truncate flex-1", children: n }),
1231
+ o && /* @__PURE__ */ e("span", { className: `text-[9px] px-1 rounded shrink-0 ${o.className}`, children: o.text }),
603
1232
  /* @__PURE__ */ r("span", { className: "text-foreground-subtle flex items-center gap-1.5 shrink-0", children: [
604
- c.map((d, u) => /* @__PURE__ */ r("span", { children: [
605
- u > 0 && /* @__PURE__ */ e("span", { className: "mr-1.5 text-foreground-subtle/50", children: "·" }),
606
- typeof d == "string" ? d : /* @__PURE__ */ e("span", { className: d.warn ? "text-amber-400" : "", children: d.text })
607
- ] }, u)),
1233
+ c.map((l, f) => /* @__PURE__ */ r("span", { children: [
1234
+ f > 0 && /* @__PURE__ */ e("span", { className: "mr-1.5 text-foreground-subtle/50", children: "·" }),
1235
+ typeof l == "string" ? l : /* @__PURE__ */ e("span", { className: l.warn ? "text-amber-400" : "", children: l.text })
1236
+ ] }, f)),
608
1237
  /* @__PURE__ */ r("span", { className: "text-foreground-subtle/70", children: [
609
1238
  "· ",
610
- g(t)
1239
+ D(s)
611
1240
  ] })
612
1241
  ] }),
613
- /* @__PURE__ */ e("div", { className: "w-5 flex-shrink-0 flex items-center justify-end", children: l ? /* @__PURE__ */ e(C, { onClick: l }) : null })
1242
+ /* @__PURE__ */ e("div", { className: "w-5 flex-shrink-0 flex items-center justify-end", children: m ? /* @__PURE__ */ e(U, { onClick: m }) : null })
614
1243
  ] });
615
1244
  }
616
- function Ne({ count: s, clients: n, onKill: o }) {
617
- const i = n?.decoded ?? [], c = n?.audio ?? [], t = n ? n.encodedSubscribers : 0, l = i.length > 0 || c.length > 0 || t > 0, d = /* @__PURE__ */ e("span", { className: `text-foreground ${l ? "underline decoration-dotted decoration-foreground-subtle/50 underline-offset-2 cursor-help" : ""}`, children: s });
618
- if (!l) return d;
619
- const u = /* @__PURE__ */ r(B, { children: [
620
- i.length > 0 && /* @__PURE__ */ r("div", { className: "mb-2", children: [
1245
+ function it({ count: t, clients: a, onKill: n }) {
1246
+ const o = a?.decoded ?? [], c = a?.audio ?? [], s = a ? a.encodedSubscribers : 0, m = o.length > 0 || c.length > 0 || s > 0, l = /* @__PURE__ */ e("span", { className: `text-foreground ${m ? "underline decoration-dotted decoration-foreground-subtle/50 underline-offset-2 cursor-help" : ""}`, children: t });
1247
+ if (!m) return l;
1248
+ const f = /* @__PURE__ */ r($, { children: [
1249
+ o.length > 0 && /* @__PURE__ */ r("div", { className: "mb-2", children: [
621
1250
  /* @__PURE__ */ e("div", { className: "text-foreground-subtle uppercase text-[9px] tracking-wider mb-1", children: "Decoded subscribers" }),
622
- i.map((a, m) => /* @__PURE__ */ r("div", { className: "flex items-center justify-between gap-2 py-0.5", children: [
623
- /* @__PURE__ */ e("span", { className: "text-foreground font-medium truncate", children: a.tag || "unknown" }),
1251
+ o.map((u, d) => /* @__PURE__ */ r("div", { className: "flex items-center justify-between gap-2 py-0.5", children: [
1252
+ /* @__PURE__ */ e("span", { className: "text-foreground font-medium truncate", children: u.tag || "unknown" }),
624
1253
  /* @__PURE__ */ r("span", { className: "text-foreground-subtle text-[9px] flex items-center gap-1.5 shrink-0", children: [
625
1254
  /* @__PURE__ */ r("span", { children: [
626
- a.maxFps.toFixed(0),
1255
+ u.maxFps.toFixed(0),
627
1256
  "fps"
628
1257
  ] }),
629
1258
  /* @__PURE__ */ e("span", { children: "·" }),
630
1259
  /* @__PURE__ */ r("span", { children: [
631
- a.framesDelivered,
1260
+ u.framesDelivered,
632
1261
  " del"
633
1262
  ] }),
634
- a.framesDropped > 0 && /* @__PURE__ */ r("span", { className: "text-amber-400", children: [
1263
+ u.framesDropped > 0 && /* @__PURE__ */ r("span", { className: "text-amber-400", children: [
635
1264
  "· ",
636
- a.framesDropped,
1265
+ u.framesDropped,
637
1266
  " drop"
638
1267
  ] }),
639
1268
  /* @__PURE__ */ e("span", { children: "·" }),
640
- /* @__PURE__ */ e("span", { children: g(Date.now() - a.subscribedAt) }),
641
- o && a.tag && /* @__PURE__ */ e(C, { onClick: () => o({ channel: "decoded", handle: a.tag }) })
1269
+ /* @__PURE__ */ e("span", { children: D(Date.now() - u.subscribedAt) }),
1270
+ n && u.tag && /* @__PURE__ */ e(U, { onClick: () => n({ channel: "decoded", handle: u.tag }) })
642
1271
  ] })
643
- ] }, `d-${m}`))
1272
+ ] }, `d-${d}`))
644
1273
  ] }),
645
1274
  c.length > 0 && /* @__PURE__ */ r("div", { className: "mb-2", children: [
646
1275
  /* @__PURE__ */ e("div", { className: "text-foreground-subtle uppercase text-[9px] tracking-wider mb-1", children: "Audio subscribers" }),
647
- c.map((a, m) => /* @__PURE__ */ r("div", { className: "flex items-center justify-between gap-2 py-0.5", children: [
648
- /* @__PURE__ */ e("span", { className: "text-foreground font-medium truncate", children: a.tag || "unknown" }),
1276
+ c.map((u, d) => /* @__PURE__ */ r("div", { className: "flex items-center justify-between gap-2 py-0.5", children: [
1277
+ /* @__PURE__ */ e("span", { className: "text-foreground font-medium truncate", children: u.tag || "unknown" }),
649
1278
  /* @__PURE__ */ r("span", { className: "text-foreground-subtle text-[9px] flex items-center gap-1.5 shrink-0", children: [
650
1279
  /* @__PURE__ */ r("span", { children: [
651
- a.chunksDelivered,
1280
+ u.chunksDelivered,
652
1281
  " chunks"
653
1282
  ] }),
654
1283
  /* @__PURE__ */ e("span", { children: "·" }),
655
- /* @__PURE__ */ e("span", { children: g(Date.now() - a.subscribedAt) }),
656
- o && a.tag && /* @__PURE__ */ e(C, { onClick: () => o({ channel: "audio", handle: a.tag }) })
1284
+ /* @__PURE__ */ e("span", { children: D(Date.now() - u.subscribedAt) }),
1285
+ n && u.tag && /* @__PURE__ */ e(U, { onClick: () => n({ channel: "audio", handle: u.tag }) })
657
1286
  ] })
658
- ] }, `a-${m}`))
1287
+ ] }, `a-${d}`))
659
1288
  ] }),
660
- t > 0 && /* @__PURE__ */ r("div", { children: [
1289
+ s > 0 && /* @__PURE__ */ r("div", { children: [
661
1290
  /* @__PURE__ */ e("div", { className: "text-foreground-subtle uppercase text-[9px] tracking-wider mb-1", children: "Encoded" }),
662
1291
  /* @__PURE__ */ r("div", { className: "text-foreground", children: [
663
- t,
1292
+ s,
664
1293
  " callback subscriber(s)"
665
1294
  ] })
666
1295
  ] })
667
1296
  ] });
668
- return /* @__PURE__ */ e(K, { trigger: d, content: u, widthClass: "min-w-[260px] max-w-[360px]" });
1297
+ return /* @__PURE__ */ e(ue, { trigger: l, content: f, widthClass: "min-w-[260px] max-w-[360px]" });
669
1298
  }
670
- function we({
671
- enabled: s,
672
- onToggle: n,
673
- disabled: o
1299
+ function lt({
1300
+ enabled: t,
1301
+ onToggle: a,
1302
+ disabled: n
674
1303
  }) {
675
1304
  return /* @__PURE__ */ e(
676
1305
  "button",
677
1306
  {
678
1307
  type: "button",
679
1308
  role: "switch",
680
- "aria-checked": s,
681
- disabled: o,
682
- onClick: () => n(!s),
683
- className: `relative inline-flex h-3 w-6 shrink-0 items-center rounded-full transition-colors ${s ? "bg-success/60" : "bg-foreground-subtle/30"} ${o ? "opacity-50 cursor-wait" : "cursor-pointer"}`,
684
- title: s ? "Pre-buffer enabled — click to disable" : "Pre-buffer disabled — click to enable",
1309
+ "aria-checked": t,
1310
+ disabled: n,
1311
+ onClick: () => a(!t),
1312
+ className: `relative inline-flex h-3 w-6 shrink-0 items-center rounded-full transition-colors ${t ? "bg-success/60" : "bg-foreground-subtle/30"} ${n ? "opacity-50 cursor-wait" : "cursor-pointer"}`,
1313
+ title: t ? "Pre-buffer enabled — click to disable" : "Pre-buffer disabled — click to enable",
685
1314
  children: /* @__PURE__ */ e(
686
1315
  "span",
687
1316
  {
688
- className: `inline-block h-2.5 w-2.5 rounded-full bg-white shadow transition-transform ${s ? "translate-x-3" : "translate-x-0.5"}`
1317
+ className: `inline-block h-2.5 w-2.5 rounded-full bg-white shadow transition-transform ${t ? "translate-x-3" : "translate-x-0.5"}`
689
1318
  }
690
1319
  )
691
1320
  }
692
1321
  );
693
1322
  }
694
- function C({ onClick: s }) {
1323
+ function U({ onClick: t }) {
695
1324
  return /* @__PURE__ */ e(
696
1325
  "button",
697
1326
  {
698
1327
  type: "button",
699
1328
  title: "Force-disconnect this client",
700
- onClick: (n) => {
701
- n.stopPropagation(), s();
1329
+ onClick: (a) => {
1330
+ a.stopPropagation(), t();
702
1331
  },
703
1332
  className: "inline-flex items-center justify-center h-4 w-4 rounded-sm border border-border/60 text-foreground-subtle hover:bg-red-500/10 hover:text-red-400 hover:border-red-500/40 transition-colors",
704
- children: /* @__PURE__ */ e(le, { className: "h-2.5 w-2.5" })
1333
+ children: /* @__PURE__ */ e(Ke, { className: "h-2.5 w-2.5" })
705
1334
  }
706
1335
  );
707
1336
  }
708
- function ve({ count: s, clients: n, onKill: o }) {
709
- const i = n?.rtsp ?? [], c = i.length > 0, t = /* @__PURE__ */ e("span", { className: `text-foreground ${c ? "underline decoration-dotted decoration-foreground-subtle/50 underline-offset-2 cursor-help" : ""}`, children: s });
710
- if (!c) return t;
711
- const l = /* @__PURE__ */ r(B, { children: [
1337
+ function ct({ count: t, clients: a, onKill: n }) {
1338
+ const o = a?.rtsp ?? [], c = o.length > 0, s = /* @__PURE__ */ e("span", { className: `text-foreground ${c ? "underline decoration-dotted decoration-foreground-subtle/50 underline-offset-2 cursor-help" : ""}`, children: t });
1339
+ if (!c) return s;
1340
+ const m = /* @__PURE__ */ r($, { children: [
712
1341
  /* @__PURE__ */ e("div", { className: "text-foreground-subtle uppercase text-[9px] tracking-wider mb-1", children: "RTSP sessions" }),
713
- i.map((d) => {
714
- const u = Date.now() - d.lastRtpAt, a = u > 5e3;
1342
+ o.map((l) => {
1343
+ const f = Date.now() - l.lastRtpAt, u = f > 5e3;
715
1344
  return /* @__PURE__ */ r("div", { className: "py-1 border-b border-border/40 last:border-b-0", children: [
716
1345
  /* @__PURE__ */ r("div", { className: "flex items-center justify-between gap-2", children: [
717
- /* @__PURE__ */ e("span", { className: "text-foreground font-mono", children: d.remoteAddr }),
1346
+ /* @__PURE__ */ e("span", { className: "text-foreground font-mono", children: l.remoteAddr }),
718
1347
  /* @__PURE__ */ r("span", { className: "flex items-center gap-1 shrink-0", children: [
719
- /* @__PURE__ */ r("span", { className: `text-[9px] px-1 rounded ${d.playing ? a ? "bg-amber-400/10 text-amber-400" : "bg-success/10 text-success" : "bg-foreground-subtle/10 text-foreground-subtle"}`, children: [
720
- d.playing ? a ? "stalled" : "playing" : "paused",
721
- d.muted && " · muted"
1348
+ /* @__PURE__ */ r("span", { className: `text-[9px] px-1 rounded ${l.playing ? u ? "bg-amber-400/10 text-amber-400" : "bg-success/10 text-success" : "bg-foreground-subtle/10 text-foreground-subtle"}`, children: [
1349
+ l.playing ? u ? "stalled" : "playing" : "paused",
1350
+ l.muted && " · muted"
722
1351
  ] }),
723
- o && /* @__PURE__ */ e(C, { onClick: () => o({ channel: "rtsp", handle: d.sessionId }) })
1352
+ n && /* @__PURE__ */ e(U, { onClick: () => n({ channel: "rtsp", handle: l.sessionId }) })
724
1353
  ] })
725
1354
  ] }),
726
1355
  /* @__PURE__ */ r("div", { className: "flex items-center justify-between gap-2 text-foreground-subtle text-[9px] mt-0.5", children: [
727
1356
  /* @__PURE__ */ r("span", { children: [
728
- U(d.bytesSent),
1357
+ pe(l.bytesSent),
729
1358
  " sent"
730
1359
  ] }),
731
1360
  /* @__PURE__ */ r("span", { children: [
732
1361
  "connected ",
733
- g(Date.now() - d.connectedAt),
1362
+ D(Date.now() - l.connectedAt),
734
1363
  " ago"
735
1364
  ] }),
736
1365
  /* @__PURE__ */ r("span", { children: [
737
1366
  "last rtp ",
738
- g(u),
1367
+ D(f),
739
1368
  " ago"
740
1369
  ] })
741
1370
  ] })
742
- ] }, d.sessionId);
1371
+ ] }, l.sessionId);
743
1372
  })
744
1373
  ] });
745
- return /* @__PURE__ */ e(K, { trigger: t, content: l, widthClass: "min-w-[300px] max-w-[420px]" });
1374
+ return /* @__PURE__ */ e(ue, { trigger: s, content: m, widthClass: "min-w-[300px] max-w-[420px]" });
746
1375
  }
747
- const $e = {
748
- "stream-broker-panel": ue
1376
+ const gt = {
1377
+ "stream-broker-panel": et,
1378
+ "ffmpeg-params": Ge
749
1379
  };
750
1380
  export {
751
- $e as default
1381
+ gt as default
752
1382
  };