@camstack/addon-pipeline-orchestrator 0.1.18 → 0.1.21

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 (21) hide show
  1. package/dist/@mf-types/compiled-types/widgets/motion-zones/MotionGridCanvas.d.ts +2 -12
  2. package/dist/@mf-types/compiled-types/widgets/motion-zones/MotionGridCanvas.d.ts.map +1 -1
  3. package/dist/@mf-types/compiled-types/widgets/motion-zones/MotionZonesTab.d.ts.map +1 -1
  4. package/dist/@mf-types.zip +0 -0
  5. package/dist/{ReactKonva-JXCACcqD.mjs → ReactKonva--rywLr1Y.mjs} +1 -1
  6. package/dist/__mfe_internal__addon_pipeline_orchestrator_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.mjs-DPoup41Y.mjs +34 -0
  7. package/dist/__mfe_internal__addon_pipeline_orchestrator_widgets__loadShare__konva__loadShare__.mjs-C4PYo-VP.mjs +30 -0
  8. package/dist/__mfe_internal__addon_pipeline_orchestrator_widgets__loadShare__react_mf_2_konva__loadShare__.mjs-DSZIXeAx.mjs +64 -0
  9. package/dist/_stub.js +597 -637
  10. package/dist/{hostInit-B0XiFU2K.mjs → hostInit-s8NZVmrk.mjs} +2 -2
  11. package/dist/{index-BD2XShwZ.mjs → index-CMke0KpS.mjs} +3241 -3234
  12. package/dist/index.js +4 -2
  13. package/dist/index.js.map +1 -1
  14. package/dist/index.mjs +4 -2
  15. package/dist/index.mjs.map +1 -1
  16. package/package.json +1 -1
  17. package/dist/@mf-types/compiled-types/widgets/motion-zones/MotionZonesOverlay.d.ts +0 -14
  18. package/dist/@mf-types/compiled-types/widgets/motion-zones/MotionZonesOverlay.d.ts.map +0 -1
  19. package/dist/__mfe_internal__addon_pipeline_orchestrator_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.mjs-XtEtGou1.mjs +0 -34
  20. package/dist/__mfe_internal__addon_pipeline_orchestrator_widgets__loadShare__konva__loadShare__.mjs-F783v1sm.mjs +0 -8
  21. package/dist/__mfe_internal__addon_pipeline_orchestrator_widgets__loadShare__react_mf_2_konva__loadShare__.mjs-CJUQOcTE.mjs +0 -18
package/dist/_stub.js CHANGED
@@ -1,9 +1,9 @@
1
- import { _ as t, a as u, b as Ze } from "./__mfe_internal__addon_pipeline_orchestrator_widgets__loadShare__react_mf_1_jsx_mf_2_runtime__loadShare__.mjs-Cg6QsnjR.mjs";
2
- import { _ as He } from "./__mfe_internal__addon_pipeline_orchestrator_widgets__loadShare___mf_0_tanstack_mf_1_react_mf_2_query__loadShare__.mjs-DoWbefqS.mjs";
3
- import { _ as _e, a as ze, b as Ve, c as ie, d as ae, e as Ge, f as ye, g as ge, h as Ye, i as le, j as xe, k as Xe, l as Ke, m as ne, n as re, o as oe, p as Ie, q as $e, r as Pe, s as Ae, t as Ee, u as Re, v as Qe } from "./__mfe_internal__addon_pipeline_orchestrator_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.mjs-XtEtGou1.mjs";
4
- import { a as Fe, b as be, c as V, d as L, e as K, f as ve, g as X, h as A } from "./__mfe_internal__addon_pipeline_orchestrator_widgets__loadShare__react__loadShare__.mjs-0qpbQxoV.mjs";
1
+ import { _ as t, a as u, b as be } from "./__mfe_internal__addon_pipeline_orchestrator_widgets__loadShare__react_mf_1_jsx_mf_2_runtime__loadShare__.mjs-Cg6QsnjR.mjs";
2
+ import { _ as je } from "./__mfe_internal__addon_pipeline_orchestrator_widgets__loadShare___mf_0_tanstack_mf_1_react_mf_2_query__loadShare__.mjs-DoWbefqS.mjs";
3
+ import { _ as _e, a as Be, b as qe, c as ae, d as le, e as Ue, f as ye, g as he, h as He, i as xe, j as Ie, k as ze, l as Ve, m as re, n as oe, o as se, p as Ze, q as Ge, r as Ye, s as Xe, t as J, u as Ke, v as Qe } from "./__mfe_internal__addon_pipeline_orchestrator_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.mjs-DPoup41Y.mjs";
4
+ import { a as $e, b as ge, c as U, d as L, e as X, f as Ae, g as Y, h as P } from "./__mfe_internal__addon_pipeline_orchestrator_widgets__loadShare__react__loadShare__.mjs-0qpbQxoV.mjs";
5
5
  import { _ as Je } from "./__mfe_internal__addon_pipeline_orchestrator_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.mjs-UNj4rttw.mjs";
6
- import { _ as Y, a as et, b as de, c as ue, d as tt, e as nt, f as fe } from "./__mfe_internal__addon_pipeline_orchestrator_widgets__loadShare__react_mf_2_konva__loadShare__.mjs-CJUQOcTE.mjs";
6
+ import { _ as G, a as et, b as de, c as ue, d as tt, e as nt, f as fe } from "./__mfe_internal__addon_pipeline_orchestrator_widgets__loadShare__react_mf_2_konva__loadShare__.mjs-DSZIXeAx.mjs";
7
7
  /**
8
8
  * @license lucide-react v0.511.0 - ISC
9
9
  *
@@ -13,10 +13,10 @@ import { _ as Y, a as et, b as de, c as ue, d as tt, e as nt, f as fe } from "./
13
13
  const rt = (e) => e.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase(), ot = (e) => e.replace(
14
14
  /^([A-Z])|[\s-_]+(\w)/g,
15
15
  (o, r, l) => l ? l.toUpperCase() : r.toLowerCase()
16
- ), we = (e) => {
16
+ ), ke = (e) => {
17
17
  const o = ot(e);
18
18
  return o.charAt(0).toUpperCase() + o.slice(1);
19
- }, Le = (...e) => e.filter((o, r, l) => !!o && o.trim() !== "" && l.indexOf(o) === r).join(" ").trim(), st = (e) => {
19
+ }, Pe = (...e) => e.filter((o, r, l) => !!o && o.trim() !== "" && l.indexOf(o) === r).join(" ").trim(), st = (e) => {
20
20
  for (const o in e)
21
21
  if (o.startsWith("aria-") || o === "role" || o === "title")
22
22
  return !0;
@@ -44,31 +44,31 @@ var it = {
44
44
  * This source code is licensed under the ISC license.
45
45
  * See the LICENSE file in the root directory of this source tree.
46
46
  */
47
- const at = Fe(
47
+ const at = $e(
48
48
  ({
49
49
  color: e = "currentColor",
50
50
  size: o = 24,
51
51
  strokeWidth: r = 2,
52
52
  absoluteStrokeWidth: l,
53
- className: c = "",
53
+ className: p = "",
54
54
  children: i,
55
- iconNode: d,
56
- ...a
57
- }, f) => be(
55
+ iconNode: c,
56
+ ...s
57
+ }, h) => ge(
58
58
  "svg",
59
59
  {
60
- ref: f,
60
+ ref: h,
61
61
  ...it,
62
62
  width: o,
63
63
  height: o,
64
64
  stroke: e,
65
65
  strokeWidth: l ? Number(r) * 24 / Number(o) : r,
66
- className: Le("lucide", c),
67
- ...!i && !st(a) && { "aria-hidden": "true" },
68
- ...a
66
+ className: Pe("lucide", p),
67
+ ...!i && !st(s) && { "aria-hidden": "true" },
68
+ ...s
69
69
  },
70
70
  [
71
- ...d.map(([n, E]) => be(n, E)),
71
+ ...c.map(([n, S]) => ge(n, S)),
72
72
  ...Array.isArray(i) ? i : [i]
73
73
  ]
74
74
  )
@@ -79,20 +79,20 @@ const at = Fe(
79
79
  * This source code is licensed under the ISC license.
80
80
  * See the LICENSE file in the root directory of this source tree.
81
81
  */
82
- const B = (e, o) => {
83
- const r = Fe(
84
- ({ className: l, ...c }, i) => be(at, {
82
+ const j = (e, o) => {
83
+ const r = $e(
84
+ ({ className: l, ...p }, i) => ge(at, {
85
85
  ref: i,
86
86
  iconNode: o,
87
- className: Le(
88
- `lucide-${rt(we(e))}`,
87
+ className: Pe(
88
+ `lucide-${rt(ke(e))}`,
89
89
  `lucide-${e}`,
90
90
  l
91
91
  ),
92
- ...c
92
+ ...p
93
93
  })
94
94
  );
95
- return r.displayName = we(e), r;
95
+ return r.displayName = ke(e), r;
96
96
  };
97
97
  /**
98
98
  * @license lucide-react v0.511.0 - ISC
@@ -108,14 +108,14 @@ const lt = [
108
108
  key: "169zse"
109
109
  }
110
110
  ]
111
- ], ct = B("activity", lt);
111
+ ], ct = j("activity", lt);
112
112
  /**
113
113
  * @license lucide-react v0.511.0 - ISC
114
114
  *
115
115
  * This source code is licensed under the ISC license.
116
116
  * See the LICENSE file in the root directory of this source tree.
117
117
  */
118
- const dt = [["path", { d: "M20 6 9 17l-5-5", key: "1gmf2c" }]], ut = B("check", dt);
118
+ const dt = [["path", { d: "M20 6 9 17l-5-5", key: "1gmf2c" }]], ut = j("check", dt);
119
119
  /**
120
120
  * @license lucide-react v0.511.0 - ISC
121
121
  *
@@ -137,14 +137,14 @@ const ft = [
137
137
  ["path", { d: "M7 2v2", key: "1i4yhu" }],
138
138
  ["rect", { x: "4", y: "4", width: "16", height: "16", rx: "2", key: "1vbyd7" }],
139
139
  ["rect", { x: "8", y: "8", width: "8", height: "8", rx: "1", key: "z9xiuo" }]
140
- ], pt = B("cpu", ft);
140
+ ], pt = j("cpu", ft);
141
141
  /**
142
142
  * @license lucide-react v0.511.0 - ISC
143
143
  *
144
144
  * This source code is licensed under the ISC license.
145
145
  * See the LICENSE file in the root directory of this source tree.
146
146
  */
147
- const ht = [
147
+ const mt = [
148
148
  [
149
149
  "path",
150
150
  {
@@ -153,7 +153,7 @@ const ht = [
153
153
  }
154
154
  ],
155
155
  ["circle", { cx: "12", cy: "12", r: "3", key: "1v7zrd" }]
156
- ], mt = B("eye", ht);
156
+ ], ht = j("eye", mt);
157
157
  /**
158
158
  * @license lucide-react v0.511.0 - ISC
159
159
  *
@@ -163,7 +163,7 @@ const ht = [
163
163
  const gt = [
164
164
  ["path", { d: "m12 14 4-4", key: "9kzdfg" }],
165
165
  ["path", { d: "M3.34 19a10 10 0 1 1 17.32 0", key: "19p75a" }]
166
- ], bt = B("gauge", gt);
166
+ ], bt = j("gauge", gt);
167
167
  /**
168
168
  * @license lucide-react v0.511.0 - ISC
169
169
  *
@@ -178,24 +178,24 @@ const yt = [
178
178
  key: "yt0hxn"
179
179
  }
180
180
  ]
181
- ], xt = B("hexagon", yt);
181
+ ], xt = j("hexagon", yt);
182
182
  /**
183
183
  * @license lucide-react v0.511.0 - ISC
184
184
  *
185
185
  * This source code is licensed under the ISC license.
186
186
  * See the LICENSE file in the root directory of this source tree.
187
187
  */
188
- const vt = [["path", { d: "M5 12h14", key: "1ays0h" }]], kt = B("minus", vt);
188
+ const vt = [["path", { d: "M5 12h14", key: "1ays0h" }]], _t = j("minus", vt);
189
189
  /**
190
190
  * @license lucide-react v0.511.0 - ISC
191
191
  *
192
192
  * This source code is licensed under the ISC license.
193
193
  * See the LICENSE file in the root directory of this source tree.
194
194
  */
195
- const _t = [
195
+ const kt = [
196
196
  ["path", { d: "M5 12h14", key: "1ays0h" }],
197
197
  ["path", { d: "M12 5v14", key: "s699le" }]
198
- ], wt = B("plus", _t);
198
+ ], wt = j("plus", kt);
199
199
  /**
200
200
  * @license lucide-react v0.511.0 - ISC
201
201
  *
@@ -212,7 +212,7 @@ const Nt = [
212
212
  ],
213
213
  ["path", { d: "M17 21v-7a1 1 0 0 0-1-1H8a1 1 0 0 0-1 1v7", key: "1ydtos" }],
214
214
  ["path", { d: "M7 3v4a1 1 0 0 0 1 1h7", key: "t51u73" }]
215
- ], Ct = B("save", Nt);
215
+ ], Ct = j("save", Nt);
216
216
  /**
217
217
  * @license lucide-react v0.511.0 - ISC
218
218
  *
@@ -225,7 +225,7 @@ const Dt = [
225
225
  ["path", { d: "M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2", key: "v07s0e" }],
226
226
  ["line", { x1: "10", x2: "10", y1: "11", y2: "17", key: "1uufr5" }],
227
227
  ["line", { x1: "14", x2: "14", y1: "11", y2: "17", key: "xtxkd" }]
228
- ], ke = B("trash-2", Dt);
228
+ ], ve = j("trash-2", Dt);
229
229
  /**
230
230
  * @license lucide-react v0.511.0 - ISC
231
231
  *
@@ -235,11 +235,11 @@ const Dt = [
235
235
  const St = [
236
236
  ["path", { d: "M18 6 6 18", key: "1bl5f8" }],
237
237
  ["path", { d: "m6 6 12 12", key: "d8bk6v" }]
238
- ], Te = B("x", St);
238
+ ], Ee = j("x", St);
239
239
  function Mt(e) {
240
- return e.deviceId === void 0 ? /* @__PURE__ */ t("div", { className: "rounded-lg border border-warning/30 bg-warning/10 px-3 py-2 text-xs text-warning", children: "PipelineQuickStats requires a deviceId" }) : /* @__PURE__ */ t(Zt, { deviceId: e.deviceId });
240
+ return e.deviceId === void 0 ? /* @__PURE__ */ t("div", { className: "rounded-lg border border-warning/30 bg-warning/10 px-3 py-2 text-xs text-warning", children: "PipelineQuickStats requires a deviceId" }) : /* @__PURE__ */ t(It, { deviceId: e.deviceId });
241
241
  }
242
- function Zt({ deviceId: e }) {
242
+ function It({ deviceId: e }) {
243
243
  _e(
244
244
  ["pipelineOrchestrator", "getPipelineAssignment"],
245
245
  ["pipeline.camera-assigned", "pipeline.camera-unassigned", "pipeline.camera-updated"]
@@ -247,63 +247,63 @@ function Zt({ deviceId: e }) {
247
247
  ["pipelineRunner", "getCameraMetrics"],
248
248
  ["pipeline.camera-metrics-snapshot"]
249
249
  );
250
- const { data: o } = ze(
250
+ const { data: o } = Be(
251
251
  { deviceId: e },
252
252
  { staleTime: 3e4 }
253
- ), r = o?.agentNodeId ?? null, c = typeof r == "string" && r.length > 0 && !r.startsWith("addon:") ? r : void 0, { data: i } = Ve(
253
+ ), r = o?.agentNodeId ?? null, p = typeof r == "string" && r.length > 0 && !r.startsWith("addon:") ? r : void 0, { data: i } = qe(
254
254
  {
255
255
  deviceId: e,
256
- ...c ? { nodeId: c } : {}
256
+ ...p ? { nodeId: p } : {}
257
257
  },
258
258
  { staleTime: 2e3, retry: !1 }
259
- ), d = ie(), a = ae(d.trpcClient, e), { data: f } = He({
259
+ ), c = ae(), s = le(c.trpcClient, e), { data: h } = je({
260
260
  queryKey: ["device", e, "pipelineAnalytics.getActiveTracks"],
261
- queryFn: () => a?.pipelineAnalytics?.getActiveTracks({}) ?? [],
262
- enabled: !!a,
261
+ queryFn: () => s?.pipelineAnalytics?.getActiveTracks({}) ?? [],
262
+ enabled: !!s,
263
263
  refetchInterval: 5e3,
264
264
  retry: !1
265
- }), n = i?.phase ?? null, E = i?.detectionMode ?? null, p = Number(i?.actualFps ?? 0), M = Number(i?.configuredFps ?? 0), b = Number(i?.avgInferenceTimeMs ?? 0), k = Number(i?.queueDepth ?? 0), I = Number(i?.droppedFrames ?? 0), g = Ge(n ?? "watching"), h = f?.length ?? 0;
265
+ }), n = i?.phase ?? null, S = i?.detectionMode ?? null, d = Number(i?.actualFps ?? 0), Z = Number(i?.configuredFps ?? 0), b = Number(i?.avgInferenceTimeMs ?? 0), m = Number(i?.queueDepth ?? 0), w = Number(i?.droppedFrames ?? 0), _ = Ue(n ?? "watching"), M = h?.length ?? 0;
266
266
  return /* @__PURE__ */ t("div", { className: "@container", style: { containerType: "inline-size" }, children: /* @__PURE__ */ u("div", { className: "grid grid-cols-1 @[360px]:grid-cols-2 @[720px]:grid-cols-4 gap-3", children: [
267
267
  /* @__PURE__ */ t(
268
- se,
268
+ ie,
269
269
  {
270
270
  icon: ct,
271
271
  label: "Phase",
272
- value: g.label,
273
- color: g.textColor,
274
- subtext: E ?? void 0
272
+ value: _.label,
273
+ color: _.textColor,
274
+ subtext: S ?? void 0
275
275
  }
276
276
  ),
277
277
  /* @__PURE__ */ t(
278
- se,
278
+ ie,
279
279
  {
280
280
  icon: bt,
281
281
  label: "Detection FPS",
282
- value: `${p.toFixed(1)}`,
283
- subtext: M > 0 ? `target: ${M}` : void 0
282
+ value: `${d.toFixed(1)}`,
283
+ subtext: Z > 0 ? `target: ${Z}` : void 0
284
284
  }
285
285
  ),
286
286
  /* @__PURE__ */ t(
287
- se,
287
+ ie,
288
288
  {
289
289
  icon: pt,
290
290
  label: "Inference",
291
291
  value: `${b.toFixed(1)} ms`,
292
- subtext: k > 0 ? `queue: ${k}` : void 0
292
+ subtext: m > 0 ? `queue: ${m}` : void 0
293
293
  }
294
294
  ),
295
295
  /* @__PURE__ */ t(
296
- se,
296
+ ie,
297
297
  {
298
- icon: mt,
298
+ icon: ht,
299
299
  label: "Active Tracks",
300
- value: String(h),
301
- subtext: I > 0 ? `dropped: ${I}` : void 0
300
+ value: String(M),
301
+ subtext: w > 0 ? `dropped: ${w}` : void 0
302
302
  }
303
303
  )
304
304
  ] }) });
305
305
  }
306
- function se({ icon: e, label: o, value: r, subtext: l, color: c }) {
306
+ function ie({ icon: e, label: o, value: r, subtext: l, color: p }) {
307
307
  return /* @__PURE__ */ u("div", { className: "rounded-lg border border-border bg-surface p-3 min-w-0", children: [
308
308
  /* @__PURE__ */ u("div", { className: "flex items-center gap-1.5 mb-1 min-w-0", children: [
309
309
  /* @__PURE__ */ t(e, { className: "h-3.5 w-3.5 text-foreground-subtle flex-shrink-0" }),
@@ -319,7 +319,7 @@ function se({ icon: e, label: o, value: r, subtext: l, color: c }) {
319
319
  /* @__PURE__ */ t(
320
320
  "p",
321
321
  {
322
- className: `text-lg font-semibold leading-tight truncate ${c ?? "text-foreground"}`,
322
+ className: `text-lg font-semibold leading-tight truncate ${p ?? "text-foreground"}`,
323
323
  title: r,
324
324
  children: r
325
325
  }
@@ -327,36 +327,36 @@ function se({ icon: e, label: o, value: r, subtext: l, color: c }) {
327
327
  l && /* @__PURE__ */ t("p", { className: "text-[10px] text-foreground-subtle mt-0.5 truncate", title: l, children: l })
328
328
  ] });
329
329
  }
330
- const It = {
330
+ const Zt = {
331
331
  polygon: "Polygon",
332
332
  tripwire: "Tripwire"
333
333
  }, $t = {
334
334
  polygon: "bg-info/10 text-info",
335
335
  tripwire: "bg-warning/10 text-warning"
336
336
  };
337
- function Pt({
337
+ function At({
338
338
  zones: e,
339
339
  selectedZoneId: o,
340
340
  drawingKind: r,
341
341
  onSelectZone: l,
342
- onDeleteZone: c,
342
+ onDeleteZone: p,
343
343
  onStartDraw: i,
344
- onCancelDraw: d
344
+ onCancelDraw: c
345
345
  }) {
346
346
  return /* @__PURE__ */ u("div", { className: "flex flex-col gap-2", children: [
347
347
  /* @__PURE__ */ t("div", { className: "flex items-center gap-1", children: r ? /* @__PURE__ */ u(
348
348
  "button",
349
349
  {
350
350
  type: "button",
351
- onClick: d,
351
+ onClick: c,
352
352
  className: "inline-flex items-center justify-center gap-1 rounded border border-amber-500/30 bg-amber-500/10 text-amber-400 hover:bg-amber-500/20 transition-colors h-8 px-3 text-[11px] font-medium",
353
353
  title: "Cancel drawing",
354
354
  children: [
355
- /* @__PURE__ */ t(Te, { className: "h-3.5 w-3.5" }),
355
+ /* @__PURE__ */ t(Ee, { className: "h-3.5 w-3.5" }),
356
356
  /* @__PURE__ */ t("span", { children: "Cancel" })
357
357
  ]
358
358
  }
359
- ) : /* @__PURE__ */ u(Ze, { children: [
359
+ ) : /* @__PURE__ */ u(be, { children: [
360
360
  /* @__PURE__ */ t(
361
361
  "button",
362
362
  {
@@ -376,34 +376,34 @@ function Pt({
376
376
  className: "inline-flex items-center justify-center rounded border border-border bg-surface text-foreground-subtle hover:text-primary hover:border-primary/40 hover:bg-primary/5 transition-colors h-8 w-8",
377
377
  title: "Add tripwire",
378
378
  "aria-label": "Add tripwire",
379
- children: /* @__PURE__ */ t(kt, { className: "h-5 w-5 stroke-[2.5]" })
379
+ children: /* @__PURE__ */ t(_t, { className: "h-5 w-5 stroke-[2.5]" })
380
380
  }
381
381
  )
382
382
  ] }) }),
383
- e.length === 0 ? /* @__PURE__ */ t("p", { className: "text-center text-[10px] text-foreground-subtle py-3 leading-tight", children: 'No zones yet — pick "Zone" or "Tripwire" to draw.' }) : /* @__PURE__ */ t("div", { className: "flex flex-col gap-1", children: e.map((a) => {
384
- const f = a.id === o;
383
+ e.length === 0 ? /* @__PURE__ */ t("p", { className: "text-center text-[10px] text-foreground-subtle py-3 leading-tight", children: 'No zones yet — pick "Zone" or "Tripwire" to draw.' }) : /* @__PURE__ */ t("div", { className: "flex flex-col gap-1", children: e.map((s) => {
384
+ const h = s.id === o;
385
385
  return /* @__PURE__ */ u(
386
386
  "div",
387
387
  {
388
388
  className: [
389
389
  "flex items-center gap-1.5 rounded border px-1.5 py-1 cursor-pointer transition-colors",
390
- f ? "border-primary/50 bg-primary/10" : "border-border bg-surface hover:bg-surface-hover"
390
+ h ? "border-primary/50 bg-primary/10" : "border-border bg-surface hover:bg-surface-hover"
391
391
  ].join(" "),
392
- onClick: () => l(f ? null : a.id),
392
+ onClick: () => l(h ? null : s.id),
393
393
  children: [
394
394
  /* @__PURE__ */ t(
395
395
  "div",
396
396
  {
397
397
  className: "h-2.5 w-2.5 rounded-sm flex-shrink-0",
398
- style: { backgroundColor: a.color }
398
+ style: { backgroundColor: s.color }
399
399
  }
400
400
  ),
401
- /* @__PURE__ */ t("span", { className: "flex-1 truncate text-[11px] font-medium text-foreground", children: a.name }),
401
+ /* @__PURE__ */ t("span", { className: "flex-1 truncate text-[11px] font-medium text-foreground", children: s.name }),
402
402
  /* @__PURE__ */ t(
403
403
  "span",
404
404
  {
405
- className: `inline-flex items-center rounded-full px-1.5 py-0.5 text-[9px] font-medium flex-shrink-0 ${$t[a.kind]}`,
406
- children: It[a.kind]
405
+ className: `inline-flex items-center rounded-full px-1.5 py-0.5 text-[9px] font-medium flex-shrink-0 ${$t[s.kind]}`,
406
+ children: Zt[s.kind]
407
407
  }
408
408
  ),
409
409
  /* @__PURE__ */ t(
@@ -413,19 +413,19 @@ function Pt({
413
413
  title: "Delete zone",
414
414
  className: "p-0.5 text-foreground-subtle hover:text-danger rounded transition-colors flex-shrink-0",
415
415
  onClick: (n) => {
416
- n.stopPropagation(), c(a.id);
416
+ n.stopPropagation(), p(s.id);
417
417
  },
418
- children: /* @__PURE__ */ t(ke, { className: "h-3 w-3" })
418
+ children: /* @__PURE__ */ t(ve, { className: "h-3 w-3" })
419
419
  }
420
420
  )
421
421
  ]
422
422
  },
423
- a.id
423
+ s.id
424
424
  );
425
425
  }) })
426
426
  ] });
427
427
  }
428
- const At = [
428
+ const Pt = [
429
429
  "#3b82f6",
430
430
  // blue
431
431
  "#10b981",
@@ -444,7 +444,7 @@ const At = [
444
444
  // pink
445
445
  ];
446
446
  function Et({ zone: e, onSave: o, onDiscard: r, onDelete: l }) {
447
- const c = ye(), i = (a) => c?.updateDraft({ name: a }), d = (a) => c?.updateDraft({ color: a });
447
+ const p = ye(), i = (s) => p?.updateDraft({ name: s }), c = (s) => p?.updateDraft({ color: s });
448
448
  return /* @__PURE__ */ u("div", { className: "flex flex-col gap-2", children: [
449
449
  /* @__PURE__ */ u("div", { className: "flex items-center justify-between", children: [
450
450
  /* @__PURE__ */ t("h3", { className: "text-[10px] font-semibold text-foreground-subtle uppercase tracking-wider", children: "Editing" }),
@@ -454,29 +454,29 @@ function Et({ zone: e, onSave: o, onDiscard: r, onDelete: l }) {
454
454
  "input",
455
455
  {
456
456
  type: "text",
457
- className: ge,
457
+ className: he,
458
458
  value: e.name,
459
459
  autoFocus: !0,
460
- onChange: (a) => i(a.target.value),
461
- onKeyDown: (a) => {
462
- a.key === "Enter" ? (a.preventDefault(), o()) : a.key === "Escape" && (a.preventDefault(), r());
460
+ onChange: (s) => i(s.target.value),
461
+ onKeyDown: (s) => {
462
+ s.key === "Enter" ? (s.preventDefault(), o()) : s.key === "Escape" && (s.preventDefault(), r());
463
463
  },
464
464
  placeholder: "Zone name"
465
465
  }
466
466
  ),
467
- /* @__PURE__ */ t("div", { className: "flex flex-wrap gap-1", children: At.map((a) => /* @__PURE__ */ t(
467
+ /* @__PURE__ */ t("div", { className: "flex flex-wrap gap-1", children: Pt.map((s) => /* @__PURE__ */ t(
468
468
  "button",
469
469
  {
470
470
  type: "button",
471
- title: a,
471
+ title: s,
472
472
  className: [
473
473
  "h-4 w-4 rounded border-2 cursor-pointer transition-transform hover:scale-110",
474
- e.color === a ? "border-white scale-110" : "border-transparent"
474
+ e.color === s ? "border-white scale-110" : "border-transparent"
475
475
  ].join(" "),
476
- style: { backgroundColor: a },
477
- onClick: () => d(a)
476
+ style: { backgroundColor: s },
477
+ onClick: () => c(s)
478
478
  },
479
- a
479
+ s
480
480
  )) }),
481
481
  /* @__PURE__ */ u("div", { className: "flex items-center gap-1.5", children: [
482
482
  /* @__PURE__ */ t(
@@ -485,17 +485,17 @@ function Et({ zone: e, onSave: o, onDiscard: r, onDelete: l }) {
485
485
  type: "color",
486
486
  className: "h-6 w-6 rounded border border-border bg-background cursor-pointer p-0.5",
487
487
  value: e.color,
488
- onChange: (a) => d(a.target.value)
488
+ onChange: (s) => c(s.target.value)
489
489
  }
490
490
  ),
491
491
  /* @__PURE__ */ t(
492
492
  "input",
493
493
  {
494
494
  type: "text",
495
- className: `${ge} font-mono`,
495
+ className: `${he} font-mono`,
496
496
  value: e.color,
497
497
  placeholder: "#000000",
498
- onChange: (a) => d(a.target.value)
498
+ onChange: (s) => c(s.target.value)
499
499
  }
500
500
  )
501
501
  ] }),
@@ -525,7 +525,7 @@ function Et({ zone: e, onSave: o, onDiscard: r, onDelete: l }) {
525
525
  className: "inline-flex items-center justify-center gap-1 rounded border border-border bg-surface text-foreground-subtle hover:text-foreground hover:bg-surface-hover transition-colors h-7 px-3 text-[11px] font-medium",
526
526
  title: "Discard changes (Esc)",
527
527
  children: [
528
- /* @__PURE__ */ t(Te, { className: "h-3 w-3" }),
528
+ /* @__PURE__ */ t(Ee, { className: "h-3 w-3" }),
529
529
  "Discard"
530
530
  ]
531
531
  }
@@ -536,9 +536,9 @@ function Et({ zone: e, onSave: o, onDiscard: r, onDelete: l }) {
536
536
  {
537
537
  type: "button",
538
538
  onClick: l,
539
- className: `${Ye} w-full`,
539
+ className: `${He} w-full`,
540
540
  children: [
541
- /* @__PURE__ */ t(ke, { className: "h-3 w-3" }),
541
+ /* @__PURE__ */ t(ve, { className: "h-3 w-3" }),
542
542
  "Delete"
543
543
  ]
544
544
  }
@@ -548,7 +548,7 @@ function Et({ zone: e, onSave: o, onDiscard: r, onDelete: l }) {
548
548
  const Rt = Je.map(
549
549
  (e) => ({ id: e.id, label: e.name })
550
550
  );
551
- function Ft(e) {
551
+ function Lt(e) {
552
552
  return {
553
553
  id: e.id,
554
554
  name: e.name ?? "",
@@ -558,7 +558,7 @@ function Ft(e) {
558
558
  enabled: e.enabled !== !1
559
559
  };
560
560
  }
561
- function Lt(e) {
561
+ function Ft(e) {
562
562
  const o = {
563
563
  id: e.id,
564
564
  zoneIds: e.zoneIds,
@@ -567,16 +567,16 @@ function Lt(e) {
567
567
  };
568
568
  return e.name && (o.name = e.name), e.classFilter.length > 0 && (o.classFilter = e.classFilter), o;
569
569
  }
570
- function Ne({ dev: e, stage: o, zones: r, title: l }) {
571
- const c = le(e?.state.zoneRules), i = V(
572
- () => c?.[o] ?? [],
573
- [c, o]
574
- ), [d, a] = L([]), [f, n] = L(!1), [E, p] = L(!1), [M, b] = L(null);
575
- K(() => {
576
- f || a(i.map(Ft));
577
- }, [i, f]);
578
- const k = () => {
579
- a((v) => [
570
+ function we({ dev: e, stage: o, zones: r, title: l }) {
571
+ const p = xe(e?.state.zoneRules), i = U(
572
+ () => p?.[o] ?? [],
573
+ [p, o]
574
+ ), [c, s] = L([]), [h, n] = L(!1), [S, d] = L(!1), [Z, b] = L(null);
575
+ X(() => {
576
+ h || s(i.map(Lt));
577
+ }, [i, h]);
578
+ const m = () => {
579
+ s((v) => [
580
580
  ...v,
581
581
  {
582
582
  id: crypto.randomUUID(),
@@ -587,49 +587,49 @@ function Ne({ dev: e, stage: o, zones: r, title: l }) {
587
587
  enabled: !0
588
588
  }
589
589
  ]), n(!0);
590
- }, I = (v, w) => {
591
- a(
592
- (C) => C.map((D, _) => {
593
- if (_ !== v) return D;
594
- const s = D.classFilter.includes(w) ? D.classFilter.filter((y) => y !== w) : [...D.classFilter, w];
595
- return { ...D, classFilter: s };
590
+ }, w = (v, N) => {
591
+ s(
592
+ (f) => f.map((g, F) => {
593
+ if (F !== v) return g;
594
+ const a = g.classFilter.includes(N) ? g.classFilter.filter((y) => y !== N) : [...g.classFilter, N];
595
+ return { ...g, classFilter: a };
596
596
  })
597
597
  ), n(!0);
598
- }, g = (v, w) => {
599
- a(
600
- (C) => C.map((D, _) => {
601
- if (_ !== v) return D;
602
- const s = D.zoneIds.includes(w) ? D.zoneIds.filter((y) => y !== w) : [...D.zoneIds, w];
603
- return { ...D, zoneIds: s };
598
+ }, _ = (v, N) => {
599
+ s(
600
+ (f) => f.map((g, F) => {
601
+ if (F !== v) return g;
602
+ const a = g.zoneIds.includes(N) ? g.zoneIds.filter((y) => y !== N) : [...g.zoneIds, N];
603
+ return { ...g, zoneIds: a };
604
604
  })
605
605
  ), n(!0);
606
- }, h = (v) => {
607
- a((w) => w.filter((C, D) => D !== v)), n(!0);
608
- }, m = (v, w) => {
609
- a((C) => C.map((D, _) => _ === v ? { ...D, ...w } : D)), n(!0);
606
+ }, M = (v) => {
607
+ s((N) => N.filter((f, g) => g !== v)), n(!0);
608
+ }, k = (v, N) => {
609
+ s((f) => f.map((g, F) => F === v ? { ...g, ...N } : g)), n(!0);
610
610
  }, x = async () => {
611
611
  if (e?.zoneRules) {
612
- p(!0), b(null);
612
+ d(!0), b(null);
613
613
  try {
614
- await e.zoneRules.setRules({ stage: o, rules: d.map(Lt) }), n(!1);
614
+ await e.zoneRules.setRules({ stage: o, rules: c.map(Ft) }), n(!1);
615
615
  } catch (v) {
616
616
  b(v instanceof Error ? v.message : String(v));
617
617
  } finally {
618
- p(!1);
618
+ d(!1);
619
619
  }
620
620
  }
621
- }, G = f && !!e?.zoneRules && !E;
621
+ }, V = h && !!e?.zoneRules && !S;
622
622
  return /* @__PURE__ */ u("div", { className: "rounded-md border border-border bg-surface/40 p-2.5", children: [
623
623
  /* @__PURE__ */ u("div", { className: "flex items-center justify-between mb-2 gap-2", children: [
624
- /* @__PURE__ */ t("h3", { className: `${xe} truncate`, children: l ?? `${o === "motion" ? "Motion" : "Detection"} Rules` }),
624
+ /* @__PURE__ */ t("h3", { className: `${Ie} truncate`, children: l ?? `${o === "motion" ? "Motion" : "Detection"} Rules` }),
625
625
  /* @__PURE__ */ u("div", { className: "flex items-center gap-1 flex-shrink-0", children: [
626
626
  /* @__PURE__ */ u(
627
627
  "button",
628
628
  {
629
629
  type: "button",
630
- onClick: k,
630
+ onClick: m,
631
631
  disabled: r.length === 0 || !e,
632
- className: Xe,
632
+ className: ze,
633
633
  title: "Add rule",
634
634
  children: [
635
635
  /* @__PURE__ */ t(wt, { className: "h-2.5 w-2.5" }),
@@ -644,17 +644,17 @@ function Ne({ dev: e, stage: o, zones: r, title: l }) {
644
644
  onClick: () => {
645
645
  x();
646
646
  },
647
- disabled: !G,
648
- className: Ke,
647
+ disabled: !V,
648
+ className: Ve,
649
649
  children: [
650
650
  /* @__PURE__ */ t(Ct, { className: "h-2.5 w-2.5" }),
651
- E ? "…" : "Save"
651
+ S ? "…" : "Save"
652
652
  ]
653
653
  }
654
654
  )
655
655
  ] })
656
656
  ] }),
657
- d.length === 0 ? /* @__PURE__ */ t("p", { className: "text-[10px] text-foreground-subtle italic px-1 py-1.5 leading-tight", children: r.length === 0 ? "Define a zone first — rules reference zone ids." : "No rules — every detection at this stage passes through." }) : /* @__PURE__ */ t("div", { className: "flex flex-col gap-1.5", children: d.map((v, w) => /* @__PURE__ */ u(
657
+ c.length === 0 ? /* @__PURE__ */ t("p", { className: "text-[10px] text-foreground-subtle italic px-1 py-1.5 leading-tight", children: r.length === 0 ? "Define a zone first — rules reference zone ids." : "No rules — every detection at this stage passes through." }) : /* @__PURE__ */ t("div", { className: "flex flex-col gap-1.5", children: c.map((v, N) => /* @__PURE__ */ u(
658
658
  "div",
659
659
  {
660
660
  className: "rounded border border-border/50 bg-background/40 px-2 py-1.5 flex flex-col gap-1.5 overflow-hidden",
@@ -668,7 +668,7 @@ function Ne({ dev: e, stage: o, zones: r, title: l }) {
668
668
  "aria-checked": v.enabled,
669
669
  "aria-label": v.enabled ? "Disable rule" : "Enable rule",
670
670
  title: v.enabled ? "Rule is active — click to disable" : "Rule is disabled — click to enable",
671
- onClick: () => m(w, { enabled: !v.enabled }),
671
+ onClick: () => k(N, { enabled: !v.enabled }),
672
672
  className: [
673
673
  "inline-flex items-center justify-center h-5 w-9 rounded-full border transition-colors flex-shrink-0",
674
674
  v.enabled ? "border-primary/50 bg-primary/20 text-primary" : "border-border bg-surface text-foreground-subtle"
@@ -687,10 +687,10 @@ function Ne({ dev: e, stage: o, zones: r, title: l }) {
687
687
  /* @__PURE__ */ t(
688
688
  "input",
689
689
  {
690
- className: `${ge} min-w-0`,
690
+ className: `${he} min-w-0`,
691
691
  placeholder: "Rule name (optional)",
692
692
  value: v.name,
693
- onChange: (C) => m(w, { name: C.target.value })
693
+ onChange: (f) => k(N, { name: f.target.value })
694
694
  }
695
695
  ),
696
696
  /* @__PURE__ */ t(
@@ -699,9 +699,9 @@ function Ne({ dev: e, stage: o, zones: r, title: l }) {
699
699
  type: "button",
700
700
  title: "Remove rule",
701
701
  "aria-label": "Remove rule",
702
- onClick: () => h(w),
702
+ onClick: () => M(N),
703
703
  className: "flex items-center justify-center h-6 w-6 rounded text-foreground-subtle hover:text-danger hover:bg-danger/10 transition-colors flex-shrink-0",
704
- children: /* @__PURE__ */ t(ke, { className: "h-3.5 w-3.5" })
704
+ children: /* @__PURE__ */ t(ve, { className: "h-3.5 w-3.5" })
705
705
  }
706
706
  )
707
707
  ] }),
@@ -711,8 +711,8 @@ function Ne({ dev: e, stage: o, zones: r, title: l }) {
711
711
  "button",
712
712
  {
713
713
  type: "button",
714
- onClick: () => m(w, { mode: "include" }),
715
- className: `${ne} ${v.mode === "include" ? re : oe}`,
714
+ onClick: () => k(N, { mode: "include" }),
715
+ className: `${re} ${v.mode === "include" ? oe : se}`,
716
716
  children: "Include"
717
717
  }
718
718
  ),
@@ -720,50 +720,50 @@ function Ne({ dev: e, stage: o, zones: r, title: l }) {
720
720
  "button",
721
721
  {
722
722
  type: "button",
723
- onClick: () => m(w, { mode: "exclude" }),
724
- className: `${ne} ${v.mode === "exclude" ? re : oe}`,
723
+ onClick: () => k(N, { mode: "exclude" }),
724
+ className: `${re} ${v.mode === "exclude" ? oe : se}`,
725
725
  children: "Exclude"
726
726
  }
727
727
  )
728
728
  ] }),
729
729
  /* @__PURE__ */ u("div", { className: "flex items-center gap-1.5 flex-wrap", children: [
730
730
  /* @__PURE__ */ t("span", { className: "text-[9px] uppercase tracking-wider text-foreground-subtle w-12 sm:w-14 flex-shrink-0", children: "Zones" }),
731
- r.length === 0 ? /* @__PURE__ */ t("span", { className: "text-[10px] text-foreground-subtle italic", children: "none" }) : r.map((C) => {
732
- const D = v.zoneIds.includes(C.id);
731
+ r.length === 0 ? /* @__PURE__ */ t("span", { className: "text-[10px] text-foreground-subtle italic", children: "none" }) : r.map((f) => {
732
+ const g = v.zoneIds.includes(f.id);
733
733
  return /* @__PURE__ */ u(
734
734
  "button",
735
735
  {
736
736
  type: "button",
737
- onClick: () => g(w, C.id),
738
- className: `${ne} ${D ? re : oe}`,
737
+ onClick: () => _(N, f.id),
738
+ className: `${re} ${g ? oe : se}`,
739
739
  children: [
740
740
  /* @__PURE__ */ t(
741
741
  "span",
742
742
  {
743
743
  className: "h-2 w-2 rounded-sm",
744
- style: { backgroundColor: C.color || "#3b82f6" }
744
+ style: { backgroundColor: f.color || "#3b82f6" }
745
745
  }
746
746
  ),
747
- /* @__PURE__ */ t("span", { className: "truncate max-w-[7rem]", children: C.name || C.id })
747
+ /* @__PURE__ */ t("span", { className: "truncate max-w-[7rem]", children: f.name || f.id })
748
748
  ]
749
749
  },
750
- C.id
750
+ f.id
751
751
  );
752
752
  })
753
753
  ] }),
754
754
  /* @__PURE__ */ u("div", { className: "flex items-center gap-1.5 flex-wrap", children: [
755
755
  /* @__PURE__ */ t("span", { className: "text-[9px] uppercase tracking-wider text-foreground-subtle w-12 sm:w-14 flex-shrink-0", children: "Class" }),
756
- Rt.map((C) => {
757
- const D = v.classFilter.includes(C.id);
756
+ Rt.map((f) => {
757
+ const g = v.classFilter.includes(f.id);
758
758
  return /* @__PURE__ */ t(
759
759
  "button",
760
760
  {
761
761
  type: "button",
762
- onClick: () => I(w, C.id),
763
- className: `${ne} ${D ? re : oe}`,
764
- children: C.label
762
+ onClick: () => w(N, f.id),
763
+ className: `${re} ${g ? oe : se}`,
764
+ children: f.label
765
765
  },
766
- C.id
766
+ f.id
767
767
  );
768
768
  }),
769
769
  v.classFilter.length === 0 && /* @__PURE__ */ t("span", { className: "text-[10px] text-foreground-subtle italic ml-1", children: "any" })
@@ -772,7 +772,7 @@ function Ne({ dev: e, stage: o, zones: r, title: l }) {
772
772
  },
773
773
  v.id
774
774
  )) }),
775
- M && /* @__PURE__ */ t("p", { className: "mt-2 text-[10px] text-danger", children: M })
775
+ Z && /* @__PURE__ */ t("p", { className: "mt-2 text-[10px] text-danger", children: Z })
776
776
  ] });
777
777
  }
778
778
  function Q(e, o, r) {
@@ -781,152 +781,152 @@ function Q(e, o, r) {
781
781
  function pe(e, o, r) {
782
782
  return { x: e.x / o, y: e.y / r };
783
783
  }
784
- function Ce(e, o, r) {
784
+ function Ne(e, o, r) {
785
785
  return e.flatMap((l) => [l.x * o, l.y * r]);
786
786
  }
787
787
  function Tt(e, o) {
788
788
  return e.color;
789
789
  }
790
- const Ot = "33", jt = "66", De = 16, Se = 9;
791
- function Wt({
790
+ const Ot = "33", Wt = "66", Ce = 16, De = 9;
791
+ function jt({
792
792
  zones: e,
793
793
  selectedZoneId: o,
794
794
  onSelectZone: r,
795
795
  onZonePointsChange: l,
796
- onZoneComplete: c,
796
+ onZoneComplete: p,
797
797
  drawingKind: i,
798
- backdrop: d,
799
- transparent: a = !1
798
+ backdrop: c,
799
+ transparent: s = !1
800
800
  }) {
801
- const f = X(null), [n, E] = L({ w: 800, h: 450 }), [p, M] = L([]), [b, k] = L(null), [I, g] = L(null), [h, m] = L(null);
802
- K(() => {
803
- if (!h) return;
804
- const s = e.find((S) => S.id === h.zoneId);
805
- if (!s) {
806
- m(null);
801
+ const h = Y(null), [n, S] = L({ w: 800, h: 450 }), [d, Z] = L([]), [b, m] = L(null), [w, _] = L(null), [M, k] = L(null);
802
+ X(() => {
803
+ if (!M) return;
804
+ const a = e.find((D) => D.id === M.zoneId);
805
+ if (!a) {
806
+ k(null);
807
807
  return;
808
808
  }
809
- if (s.points.length !== h.points.length) return;
810
- s.points.every((S, N) => {
811
- const O = h.points[N];
812
- return Math.abs(S.x - O.x) < 1e-6 && Math.abs(S.y - O.y) < 1e-6;
813
- }) && m(null);
814
- }, [e, h]), K(() => {
815
- const s = f.current;
816
- if (!s) return;
817
- const y = new ResizeObserver((S) => {
818
- const N = S[0];
819
- if (N) {
820
- const { width: O, height: j } = N.contentRect;
821
- E(a ? { w: O, h: j } : { w: O, h: O * 9 / 16 });
809
+ if (a.points.length !== M.points.length) return;
810
+ a.points.every((D, C) => {
811
+ const T = M.points[C];
812
+ return Math.abs(D.x - T.x) < 1e-6 && Math.abs(D.y - T.y) < 1e-6;
813
+ }) && k(null);
814
+ }, [e, M]), X(() => {
815
+ const a = h.current;
816
+ if (!a) return;
817
+ const y = new ResizeObserver((D) => {
818
+ const C = D[0];
819
+ if (C) {
820
+ const { width: T, height: O } = C.contentRect;
821
+ S(s ? { w: T, h: O } : { w: T, h: T * 9 / 16 });
822
822
  }
823
823
  });
824
- return y.observe(s), () => y.disconnect();
825
- }, [a]);
824
+ return y.observe(a), () => y.disconnect();
825
+ }, [s]);
826
826
  const x = i !== null;
827
- K(() => {
828
- !x && b !== null && k(null);
827
+ X(() => {
828
+ !x && b !== null && m(null);
829
829
  }, [x, b]);
830
- const G = A(
831
- (s) => {
830
+ const V = P(
831
+ (a) => {
832
832
  if (!x) {
833
833
  r(null);
834
834
  return;
835
835
  }
836
- const y = s.target.getStage();
836
+ const y = a.target.getStage();
837
837
  if (!y) return;
838
- const S = y.getPointerPosition();
839
- if (!S) return;
840
- const N = pe(S, n.w, n.h), O = i === "tripwire";
841
- if (p.length === 0) {
842
- M([N]);
838
+ const D = y.getPointerPosition();
839
+ if (!D) return;
840
+ const C = pe(D, n.w, n.h), T = i === "tripwire";
841
+ if (d.length === 0) {
842
+ Z([C]);
843
843
  return;
844
844
  }
845
- if (O && p.length === 1) {
846
- const j = [...p, N], H = {
845
+ if (T && d.length === 1) {
846
+ const O = [...d, C], H = {
847
847
  id: crypto.randomUUID(),
848
848
  name: "Tripwire",
849
849
  kind: "tripwire",
850
850
  color: "#f59e0b",
851
- points: j
851
+ points: O
852
852
  };
853
- c(H), M([]);
853
+ p(H), Z([]);
854
854
  return;
855
855
  }
856
- if (p.length >= 3 && !O) {
857
- const j = Q(p[0], n.w, n.h);
858
- if (Math.hypot(S.x - j.x, S.y - j.y) < 12) {
859
- const J = {
856
+ if (d.length >= 3 && !T) {
857
+ const O = Q(d[0], n.w, n.h);
858
+ if (Math.hypot(D.x - O.x, D.y - O.y) < 12) {
859
+ const ee = {
860
860
  id: crypto.randomUUID(),
861
861
  name: "Zone",
862
862
  kind: "polygon",
863
863
  color: "#3b82f6",
864
- points: p
864
+ points: d
865
865
  };
866
- c(J), M([]);
866
+ p(ee), Z([]);
867
867
  return;
868
868
  }
869
869
  }
870
- M((j) => [...j, N]);
870
+ Z((O) => [...O, C]);
871
871
  },
872
- [x, p, n, i, c, r]
873
- ), v = A(
874
- (s) => {
875
- if (!x || i === "tripwire" || p.length < 3) return;
876
- s.cancelBubble = !0;
872
+ [x, d, n, i, p, r]
873
+ ), v = P(
874
+ (a) => {
875
+ if (!x || i === "tripwire" || d.length < 3) return;
876
+ a.cancelBubble = !0;
877
877
  const y = {
878
878
  id: crypto.randomUUID(),
879
879
  name: "Zone",
880
880
  kind: "polygon",
881
881
  color: "#3b82f6",
882
- points: p
882
+ points: d
883
883
  };
884
- c(y), M([]);
884
+ p(y), Z([]);
885
885
  },
886
- [x, i, p, c]
887
- ), w = X(null), C = X(null);
888
- K(() => () => {
889
- w.current !== null && cancelAnimationFrame(w.current);
886
+ [x, i, d, p]
887
+ ), N = Y(null), f = Y(null);
888
+ X(() => () => {
889
+ N.current !== null && cancelAnimationFrame(N.current);
890
890
  }, []);
891
- const D = A(
892
- (s) => {
891
+ const g = P(
892
+ (a) => {
893
893
  if (!x) return;
894
- const y = s.target.getStage();
894
+ const y = a.target.getStage();
895
895
  if (!y) return;
896
- const S = y.getPointerPosition();
897
- C.current = S ?? null, w.current === null && (w.current = requestAnimationFrame(() => {
898
- w.current = null, k(C.current);
896
+ const D = y.getPointerPosition();
897
+ f.current = D ?? null, N.current === null && (N.current = requestAnimationFrame(() => {
898
+ N.current = null, m(f.current);
899
899
  }));
900
900
  },
901
901
  [x]
902
- ), _ = [];
903
- if (!a) {
904
- for (let s = 1; s < De; s++) {
905
- const y = n.w / De * s;
906
- _.push(
907
- /* @__PURE__ */ t(Y, { points: [y, 0, y, n.h], stroke: "#ffffff", strokeWidth: 0.5, opacity: 0.08 }, `gv-${s}`)
902
+ ), F = [];
903
+ if (!s) {
904
+ for (let a = 1; a < Ce; a++) {
905
+ const y = n.w / Ce * a;
906
+ F.push(
907
+ /* @__PURE__ */ t(G, { points: [y, 0, y, n.h], stroke: "#ffffff", strokeWidth: 0.5, opacity: 0.08 }, `gv-${a}`)
908
908
  );
909
909
  }
910
- for (let s = 1; s < Se; s++) {
911
- const y = n.h / Se * s;
912
- _.push(
913
- /* @__PURE__ */ t(Y, { points: [0, y, n.w, y], stroke: "#ffffff", strokeWidth: 0.5, opacity: 0.08 }, `gh-${s}`)
910
+ for (let a = 1; a < De; a++) {
911
+ const y = n.h / De * a;
912
+ F.push(
913
+ /* @__PURE__ */ t(G, { points: [0, y, n.w, y], stroke: "#ffffff", strokeWidth: 0.5, opacity: 0.08 }, `gh-${a}`)
914
914
  );
915
915
  }
916
916
  }
917
917
  return /* @__PURE__ */ u(
918
918
  "div",
919
919
  {
920
- ref: f,
921
- className: a ? "absolute inset-0" : "relative w-full bg-zinc-900 rounded-lg overflow-hidden",
920
+ ref: h,
921
+ className: s ? "absolute inset-0" : "relative w-full bg-zinc-900 rounded-lg overflow-hidden",
922
922
  style: { cursor: x ? "crosshair" : "default" },
923
923
  children: [
924
- d && !a ? /* @__PURE__ */ t(
924
+ c && !s ? /* @__PURE__ */ t(
925
925
  "div",
926
926
  {
927
927
  className: "absolute inset-0 pointer-events-none [&>*]:w-full [&>*]:h-full [&>img]:object-cover [&>video]:object-cover",
928
928
  style: { width: n.w, height: n.h },
929
- children: d
929
+ children: c
930
930
  }
931
931
  ) : null,
932
932
  /* @__PURE__ */ u(
@@ -934,85 +934,85 @@ function Wt({
934
934
  {
935
935
  width: n.w,
936
936
  height: n.h,
937
- onClick: G,
937
+ onClick: V,
938
938
  onDblClick: v,
939
- onMouseMove: D,
939
+ onMouseMove: g,
940
940
  children: [
941
941
  /* @__PURE__ */ u(de, { listening: !1, children: [
942
- /* @__PURE__ */ t(Y, { points: [0, 0, n.w, 0, n.w, n.h, 0, n.h, 0, 0], stroke: "transparent", strokeWidth: 0 }),
943
- _
942
+ /* @__PURE__ */ t(G, { points: [0, 0, n.w, 0, n.w, n.h, 0, n.h, 0, 0], stroke: "transparent", strokeWidth: 0 }),
943
+ F
944
944
  ] }),
945
- /* @__PURE__ */ t(de, { children: e.map((s) => {
946
- const y = s.id === o, S = Tt(s), N = h && h.zoneId === s.id ? h.points : s.points, O = Ce(N, n.w, n.h), j = s.kind === "tripwire", H = y && !x, J = I === s.id, ee = N.map((Z) => Z.x * n.w), te = N.map((Z) => Z.y * n.h), Oe = ee.length > 0 ? Math.min(...ee) : 0, je = ee.length > 0 ? Math.max(...ee) : 0, We = te.length > 0 ? Math.min(...te) : 0, Be = te.length > 0 ? Math.max(...te) : 0;
945
+ /* @__PURE__ */ t(de, { children: e.map((a) => {
946
+ const y = a.id === o, D = Tt(a), C = M && M.zoneId === a.id ? M.points : a.points, T = Ne(C, n.w, n.h), O = a.kind === "tripwire", H = y && !x, ee = w === a.id, te = C.map((I) => I.x * n.w), ne = C.map((I) => I.y * n.h), Re = te.length > 0 ? Math.min(...te) : 0, Le = te.length > 0 ? Math.max(...te) : 0, Fe = ne.length > 0 ? Math.min(...ne) : 0, Te = ne.length > 0 ? Math.max(...ne) : 0;
947
947
  return /* @__PURE__ */ u(
948
948
  ue,
949
949
  {
950
- onClick: (Z) => {
951
- Z.cancelBubble = !0, x || r(s.id);
950
+ onClick: (I) => {
951
+ I.cancelBubble = !0, x || r(a.id);
952
952
  },
953
953
  children: [
954
954
  /* @__PURE__ */ u(
955
955
  ue,
956
956
  {
957
957
  draggable: H,
958
- dragBoundFunc: H ? (Z) => ({
959
- x: Math.max(-Oe, Math.min(n.w - je, Z.x)),
960
- y: Math.max(-We, Math.min(n.h - Be, Z.y))
958
+ dragBoundFunc: H ? (I) => ({
959
+ x: Math.max(-Re, Math.min(n.w - Le, I.x)),
960
+ y: Math.max(-Fe, Math.min(n.h - Te, I.y))
961
961
  }) : void 0,
962
962
  onDragStart: H ? () => {
963
- g(s.id);
963
+ _(a.id);
964
964
  } : void 0,
965
- onDragEnd: H ? (Z) => {
966
- const $ = Z.target, q = $.x() / n.w, z = $.y() / n.h;
967
- if ($.position({ x: 0, y: 0 }), g(null), q === 0 && z === 0) return;
968
- const U = s.points.map((R) => ({ x: R.x + q, y: R.y + z }));
969
- m({ zoneId: s.id, points: U }), l(s.id, U);
965
+ onDragEnd: H ? (I) => {
966
+ const $ = I.target, B = $.x() / n.w, z = $.y() / n.h;
967
+ if ($.position({ x: 0, y: 0 }), _(null), B === 0 && z === 0) return;
968
+ const q = a.points.map((E) => ({ x: E.x + B, y: E.y + z }));
969
+ k({ zoneId: a.id, points: q }), l(a.id, q);
970
970
  } : void 0,
971
- onMouseEnter: (Z) => {
971
+ onMouseEnter: (I) => {
972
972
  if (!H) return;
973
- const $ = Z.target.getStage();
973
+ const $ = I.target.getStage();
974
974
  $ && ($.container().style.cursor = "move");
975
975
  },
976
- onMouseLeave: (Z) => {
976
+ onMouseLeave: (I) => {
977
977
  if (!H) return;
978
- const $ = Z.target.getStage();
978
+ const $ = I.target.getStage();
979
979
  $ && ($.container().style.cursor = x ? "crosshair" : "default");
980
980
  },
981
981
  children: [
982
- j ? /* @__PURE__ */ t(
982
+ O ? /* @__PURE__ */ t(
983
983
  tt,
984
984
  {
985
- points: O,
986
- stroke: S,
985
+ points: T,
986
+ stroke: D,
987
987
  strokeWidth: y ? 3 : 2,
988
- fill: S,
988
+ fill: D,
989
989
  pointerLength: 10,
990
990
  pointerWidth: 8,
991
991
  opacity: y ? 1 : 0.8
992
992
  }
993
993
  ) : /* @__PURE__ */ t(
994
- Y,
994
+ G,
995
995
  {
996
- points: O,
996
+ points: T,
997
997
  closed: !0,
998
- fill: S + (y ? jt : Ot),
999
- stroke: S,
998
+ fill: D + (y ? Wt : Ot),
999
+ stroke: D,
1000
1000
  strokeWidth: y ? 2.5 : 1.5,
1001
1001
  opacity: y ? 1 : 0.85
1002
1002
  }
1003
1003
  ),
1004
- N.length > 0 && (() => {
1005
- const Z = N.reduce((F, P) => F + P.x, 0), $ = N.reduce((F, P) => F + P.y, 0), q = Z / N.length, z = $ / N.length, U = Q({ x: q, y: z }, n.w, n.h), R = Math.max(40, s.name.length * 11 * 0.62);
1004
+ C.length > 0 && (() => {
1005
+ const I = C.reduce((R, A) => R + A.x, 0), $ = C.reduce((R, A) => R + A.y, 0), B = I / C.length, z = $ / C.length, q = Q({ x: B, y: z }, n.w, n.h), E = Math.max(40, a.name.length * 11 * 0.62);
1006
1006
  return /* @__PURE__ */ t(
1007
1007
  nt,
1008
1008
  {
1009
- x: U.x - R / 2,
1010
- y: U.y - 7,
1011
- width: R,
1009
+ x: q.x - E / 2,
1010
+ y: q.y - 7,
1011
+ width: E,
1012
1012
  align: "center",
1013
- text: s.name,
1013
+ text: a.name,
1014
1014
  fontSize: 12,
1015
- fill: S,
1015
+ fill: D,
1016
1016
  stroke: "#000000",
1017
1017
  strokeWidth: 3,
1018
1018
  fillAfterStrokeEnabled: !0,
@@ -1024,70 +1024,70 @@ function Wt({
1024
1024
  ]
1025
1025
  }
1026
1026
  ),
1027
- y && !J && N.map((Z, $) => {
1028
- const q = Q(Z, n.w, n.h), z = j ? 2 : 3, U = N.length > z;
1027
+ y && !ee && C.map((I, $) => {
1028
+ const B = Q(I, n.w, n.h), z = O ? 2 : 3, q = C.length > z;
1029
1029
  return /* @__PURE__ */ t(
1030
1030
  fe,
1031
1031
  {
1032
- x: q.x,
1033
- y: q.y,
1032
+ x: B.x,
1033
+ y: B.y,
1034
1034
  radius: 5,
1035
- fill: S,
1035
+ fill: D,
1036
1036
  stroke: "#ffffff",
1037
1037
  strokeWidth: 1.5,
1038
1038
  draggable: !0,
1039
- onDragMove: (R) => {
1040
- const F = pe({ x: R.target.x(), y: R.target.y() }, n.w, n.h);
1041
- m((P) => {
1042
- const ce = (P && P.zoneId === s.id ? P.points : s.points).map((qe, Ue) => Ue === $ ? F : qe);
1043
- return { zoneId: s.id, points: ce };
1039
+ onDragMove: (E) => {
1040
+ const R = pe({ x: E.target.x(), y: E.target.y() }, n.w, n.h);
1041
+ k((A) => {
1042
+ const ce = (A && A.zoneId === a.id ? A.points : a.points).map((Oe, We) => We === $ ? R : Oe);
1043
+ return { zoneId: a.id, points: ce };
1044
1044
  });
1045
1045
  },
1046
- onDragEnd: (R) => {
1047
- const F = pe({ x: R.target.x(), y: R.target.y() }, n.w, n.h), P = s.points.map((W, ce) => ce === $ ? F : W);
1048
- m({ zoneId: s.id, points: P }), l(s.id, P);
1046
+ onDragEnd: (E) => {
1047
+ const R = pe({ x: E.target.x(), y: E.target.y() }, n.w, n.h), A = a.points.map((W, ce) => ce === $ ? R : W);
1048
+ k({ zoneId: a.id, points: A }), l(a.id, A);
1049
1049
  },
1050
- onContextMenu: (R) => {
1051
- if (R.evt.preventDefault(), R.cancelBubble = !0, !U) return;
1052
- const F = s.points.filter((P, W) => W !== $);
1053
- l(s.id, F);
1050
+ onContextMenu: (E) => {
1051
+ if (E.evt.preventDefault(), E.cancelBubble = !0, !q) return;
1052
+ const R = a.points.filter((A, W) => W !== $);
1053
+ l(a.id, R);
1054
1054
  }
1055
1055
  },
1056
1056
  `pt-${$}`
1057
1057
  );
1058
1058
  }),
1059
- y && !J && !j && N.length >= 2 && N.map((Z, $) => {
1060
- const q = N[($ + 1) % N.length], z = (Z.x + q.x) / 2, U = (Z.y + q.y) / 2, R = Q({ x: z, y: U }, n.w, n.h);
1059
+ y && !ee && !O && C.length >= 2 && C.map((I, $) => {
1060
+ const B = C[($ + 1) % C.length], z = (I.x + B.x) / 2, q = (I.y + B.y) / 2, E = Q({ x: z, y: q }, n.w, n.h);
1061
1061
  return /* @__PURE__ */ t(
1062
1062
  fe,
1063
1063
  {
1064
- x: R.x,
1065
- y: R.y,
1064
+ x: E.x,
1065
+ y: E.y,
1066
1066
  radius: 4,
1067
1067
  fill: "#ffffff",
1068
- stroke: S,
1068
+ stroke: D,
1069
1069
  strokeWidth: 1.5,
1070
1070
  opacity: 0.6,
1071
- onMouseEnter: (F) => {
1072
- const P = F.target;
1073
- P.to({ radius: 6, opacity: 1, duration: 0.1 });
1074
- const W = P.getStage();
1071
+ onMouseEnter: (R) => {
1072
+ const A = R.target;
1073
+ A.to({ radius: 6, opacity: 1, duration: 0.1 });
1074
+ const W = A.getStage();
1075
1075
  W && (W.container().style.cursor = "copy");
1076
1076
  },
1077
- onMouseLeave: (F) => {
1078
- const P = F.target;
1079
- P.to({ radius: 4, opacity: 0.6, duration: 0.1 });
1080
- const W = P.getStage();
1077
+ onMouseLeave: (R) => {
1078
+ const A = R.target;
1079
+ A.to({ radius: 4, opacity: 0.6, duration: 0.1 });
1080
+ const W = A.getStage();
1081
1081
  W && (W.container().style.cursor = x ? "crosshair" : "default");
1082
1082
  },
1083
- onClick: (F) => {
1084
- F.cancelBubble = !0;
1085
- const P = $ + 1, W = [
1086
- ...s.points.slice(0, P),
1087
- { x: z, y: U },
1088
- ...s.points.slice(P)
1083
+ onClick: (R) => {
1084
+ R.cancelBubble = !0;
1085
+ const A = $ + 1, W = [
1086
+ ...a.points.slice(0, A),
1087
+ { x: z, y: q },
1088
+ ...a.points.slice(A)
1089
1089
  ];
1090
- l(s.id, W);
1090
+ l(a.id, W);
1091
1091
  }
1092
1092
  },
1093
1093
  `mid-${$}`
@@ -1095,26 +1095,26 @@ function Wt({
1095
1095
  })
1096
1096
  ]
1097
1097
  },
1098
- s.id
1098
+ a.id
1099
1099
  );
1100
1100
  }) }),
1101
- /* @__PURE__ */ t(de, { listening: !1, children: x && p.length > 0 && /* @__PURE__ */ u(ue, { children: [
1102
- p.length >= 2 && i !== "tripwire" && /* @__PURE__ */ t(
1103
- Y,
1101
+ /* @__PURE__ */ t(de, { listening: !1, children: x && d.length > 0 && /* @__PURE__ */ u(ue, { children: [
1102
+ d.length >= 2 && i !== "tripwire" && /* @__PURE__ */ t(
1103
+ G,
1104
1104
  {
1105
- points: Ce(p, n.w, n.h),
1105
+ points: Ne(d, n.w, n.h),
1106
1106
  stroke: "#6366f1",
1107
1107
  strokeWidth: 1.5,
1108
1108
  dash: [6, 3],
1109
1109
  opacity: 0.8
1110
1110
  }
1111
1111
  ),
1112
- p.length === 1 && i === "tripwire" && b && /* @__PURE__ */ t(
1113
- Y,
1112
+ d.length === 1 && i === "tripwire" && b && /* @__PURE__ */ t(
1113
+ G,
1114
1114
  {
1115
1115
  points: [
1116
- p[0].x * n.w,
1117
- p[0].y * n.h,
1116
+ d[0].x * n.w,
1117
+ d[0].y * n.h,
1118
1118
  b.x,
1119
1119
  b.y
1120
1120
  ],
@@ -1124,12 +1124,12 @@ function Wt({
1124
1124
  opacity: 0.7
1125
1125
  }
1126
1126
  ),
1127
- b && p.length >= 1 && i !== "tripwire" && /* @__PURE__ */ t(
1128
- Y,
1127
+ b && d.length >= 1 && i !== "tripwire" && /* @__PURE__ */ t(
1128
+ G,
1129
1129
  {
1130
1130
  points: [
1131
- p[p.length - 1].x * n.w,
1132
- p[p.length - 1].y * n.h,
1131
+ d[d.length - 1].x * n.w,
1132
+ d[d.length - 1].y * n.h,
1133
1133
  b.x,
1134
1134
  b.y
1135
1135
  ],
@@ -1139,15 +1139,15 @@ function Wt({
1139
1139
  opacity: 0.5
1140
1140
  }
1141
1141
  ),
1142
- p.map((s, y) => {
1143
- const S = Q(s, n.w, n.h), N = y === 0;
1142
+ d.map((a, y) => {
1143
+ const D = Q(a, n.w, n.h), C = y === 0;
1144
1144
  return /* @__PURE__ */ t(
1145
1145
  fe,
1146
1146
  {
1147
- x: S.x,
1148
- y: S.y,
1149
- radius: N && p.length >= 3 ? 7 : 4,
1150
- fill: N && p.length >= 3 ? "#6366f1" : "#ffffff",
1147
+ x: D.x,
1148
+ y: D.y,
1149
+ radius: C && d.length >= 3 ? 7 : 4,
1150
+ fill: C && d.length >= 3 ? "#6366f1" : "#ffffff",
1151
1151
  stroke: "#6366f1",
1152
1152
  strokeWidth: 1.5,
1153
1153
  opacity: 0.9
@@ -1159,12 +1159,12 @@ function Wt({
1159
1159
  ]
1160
1160
  }
1161
1161
  ),
1162
- x ? /* @__PURE__ */ t("div", { className: "px-3 py-1.5 bg-zinc-800/80 text-[11px] text-zinc-400 border-t border-zinc-700", children: i === "tripwire" ? "Click to set start point, click again to complete the tripwire" : p.length < 3 ? "Click to add points (min 3). Double-click or click first point to close." : "Continue adding points. Double-click or click first point to close." }) : null
1162
+ x ? /* @__PURE__ */ t("div", { className: "px-3 py-1.5 bg-zinc-800/80 text-[11px] text-zinc-400 border-t border-zinc-700", children: i === "tripwire" ? "Click to set start point, click again to complete the tripwire" : d.length < 3 ? "Click to add points (min 3). Double-click or click first point to close." : "Continue adding points. Double-click or click first point to close." }) : null
1163
1163
  ]
1164
1164
  }
1165
1165
  );
1166
1166
  }
1167
- const Bt = ve(Wt), qt = "#3b82f6", he = [
1167
+ const Bt = Ae(jt), qt = "#3b82f6", me = [
1168
1168
  "#3b82f6",
1169
1169
  "#10b981",
1170
1170
  "#f59e0b",
@@ -1178,9 +1178,9 @@ const Bt = ve(Wt), qt = "#3b82f6", he = [
1178
1178
  ];
1179
1179
  function Ut(e) {
1180
1180
  const o = new Set(e.map((r) => (r.color ?? "").toLowerCase()));
1181
- for (const r of he)
1181
+ for (const r of me)
1182
1182
  if (!o.has(r.toLowerCase())) return r;
1183
- return he[e.length % he.length];
1183
+ return me[e.length % me.length];
1184
1184
  }
1185
1185
  function Ht(e) {
1186
1186
  return {
@@ -1191,7 +1191,7 @@ function Ht(e) {
1191
1191
  points: [...e.polygon]
1192
1192
  };
1193
1193
  }
1194
- function Me(e) {
1194
+ function Se(e) {
1195
1195
  return {
1196
1196
  id: e.id,
1197
1197
  name: e.name,
@@ -1201,73 +1201,73 @@ function Me(e) {
1201
1201
  };
1202
1202
  }
1203
1203
  function zt({ deviceId: e }) {
1204
- const o = ie(), r = ae(o.trpcClient, e), l = le(r?.state.zones), c = V(() => l?.zones ?? [], [l]), i = ye(), d = i?.drawingKind ?? null, a = i?.selectedZoneId ?? null, f = i?.editingDraft ?? null, n = V(() => c.map((b) => f && f.id === b.id ? {
1205
- id: f.id,
1206
- name: f.name,
1207
- kind: f.kind,
1208
- color: f.color,
1209
- points: [...f.points]
1210
- } : Ht(b)), [c, f]), E = A(
1204
+ const o = ae(), r = le(o.trpcClient, e), l = xe(r?.state.zones), p = U(() => l?.zones ?? [], [l]), i = ye(), c = i?.drawingKind ?? null, s = i?.selectedZoneId ?? null, h = i?.editingDraft ?? null, n = U(() => p.map((b) => h && h.id === b.id ? {
1205
+ id: h.id,
1206
+ name: h.name,
1207
+ kind: h.kind,
1208
+ color: h.color,
1209
+ points: [...h.points]
1210
+ } : Ht(b)), [p, h]), S = P(
1211
1211
  async (b) => {
1212
- const k = { ...b, color: Ut(n) };
1212
+ const m = { ...b, color: Ut(n) };
1213
1213
  try {
1214
- await r?.zones?.addZone({ zone: Me(k) });
1215
- } catch (I) {
1216
- console.error("zones.addZone failed", I);
1214
+ await r?.zones?.addZone({ zone: Se(m) });
1215
+ } catch (w) {
1216
+ console.error("zones.addZone failed", w);
1217
1217
  }
1218
- i?.setSelectedZoneId(k.id), i?.setDrawingKind(null);
1218
+ i?.setSelectedZoneId(m.id), i?.setDrawingKind(null);
1219
1219
  },
1220
1220
  [r, n, i]
1221
- ), p = A(
1222
- async (b, k) => {
1223
- if (f && f.id === b) {
1224
- i?.updateDraft({ points: k });
1221
+ ), d = P(
1222
+ async (b, m) => {
1223
+ if (h && h.id === b) {
1224
+ i?.updateDraft({ points: m });
1225
1225
  return;
1226
1226
  }
1227
- const I = n.find((g) => g.id === b);
1228
- if (I)
1227
+ const w = n.find((_) => _.id === b);
1228
+ if (w)
1229
1229
  try {
1230
- await r?.zones?.updateZone({ zone: Me({ ...I, points: k }) });
1231
- } catch (g) {
1232
- console.error("zones.updateZone failed", g);
1230
+ await r?.zones?.updateZone({ zone: Se({ ...w, points: m }) });
1231
+ } catch (_) {
1232
+ console.error("zones.updateZone failed", _);
1233
1233
  }
1234
1234
  },
1235
- [r, n, f, i]
1236
- ), M = A(
1235
+ [r, n, h, i]
1236
+ ), Z = P(
1237
1237
  (b) => {
1238
1238
  if (b === null) {
1239
1239
  i?.discardDraft(), i?.setSelectedZoneId(null);
1240
1240
  return;
1241
1241
  }
1242
- const k = n.find((I) => I.id === b);
1243
- if (!k) {
1242
+ const m = n.find((w) => w.id === b);
1243
+ if (!m) {
1244
1244
  i?.setSelectedZoneId(b);
1245
1245
  return;
1246
1246
  }
1247
1247
  i?.enterDraft({
1248
- id: k.id,
1249
- kind: k.kind,
1250
- name: k.name,
1251
- color: k.color,
1252
- points: k.points
1248
+ id: m.id,
1249
+ kind: m.kind,
1250
+ name: m.name,
1251
+ color: m.color,
1252
+ points: m.points
1253
1253
  });
1254
1254
  },
1255
1255
  [n, i]
1256
1256
  );
1257
- return n.length === 0 && d === null ? null : /* @__PURE__ */ t(
1257
+ return n.length === 0 && c === null ? null : /* @__PURE__ */ t(
1258
1258
  Bt,
1259
1259
  {
1260
1260
  zones: n,
1261
- selectedZoneId: a,
1262
- onSelectZone: M,
1263
- onZonePointsChange: p,
1264
- onZoneComplete: E,
1265
- drawingKind: d,
1261
+ selectedZoneId: s,
1262
+ onSelectZone: Z,
1263
+ onZonePointsChange: d,
1264
+ onZoneComplete: S,
1265
+ drawingKind: c,
1266
1266
  transparent: !0
1267
1267
  }
1268
1268
  );
1269
1269
  }
1270
- const Vt = ve(zt), Gt = "#3b82f6";
1270
+ const Vt = Ae(zt), Gt = "#3b82f6";
1271
1271
  function Yt(e) {
1272
1272
  return {
1273
1273
  id: e.id,
@@ -1287,7 +1287,7 @@ function Xt(e) {
1287
1287
  };
1288
1288
  }
1289
1289
  function Kt({ deviceId: e }) {
1290
- const o = ie(), r = ae(o.trpcClient, e), l = le(r?.state.zones), c = V(() => l?.zones ?? [], [l]), i = V(() => c.map(Yt), [c]), d = ye(), a = d?.drawingKind ?? null, f = d?.selectedZoneId ?? null, n = d?.editingDraft ?? null, E = V(
1290
+ const o = ae(), r = le(o.trpcClient, e), l = xe(r?.state.zones), p = U(() => l?.zones ?? [], [l]), i = U(() => p.map(Yt), [p]), c = ye(), s = c?.drawingKind ?? null, h = c?.selectedZoneId ?? null, n = c?.editingDraft ?? null, S = U(
1291
1291
  () => ({
1292
1292
  id: "zones",
1293
1293
  order: 100,
@@ -1296,15 +1296,15 @@ function Kt({ deviceId: e }) {
1296
1296
  }),
1297
1297
  [e]
1298
1298
  );
1299
- Ie(E);
1300
- const p = A(
1301
- (m) => {
1302
- if (m === null) {
1303
- d?.discardDraft(), d?.setSelectedZoneId(null);
1299
+ Ze(S);
1300
+ const d = P(
1301
+ (k) => {
1302
+ if (k === null) {
1303
+ c?.discardDraft(), c?.setSelectedZoneId(null);
1304
1304
  return;
1305
1305
  }
1306
- const x = i.find((G) => G.id === m);
1307
- x && d?.enterDraft({
1306
+ const x = i.find((V) => V.id === k);
1307
+ x && c?.enterDraft({
1308
1308
  id: x.id,
1309
1309
  kind: x.kind,
1310
1310
  name: x.name,
@@ -1312,226 +1312,146 @@ function Kt({ deviceId: e }) {
1312
1312
  points: x.points
1313
1313
  });
1314
1314
  },
1315
- [i, d]
1316
- ), M = A(async () => {
1317
- const m = d?.editingDraft;
1318
- if (m) {
1315
+ [i, c]
1316
+ ), Z = P(async () => {
1317
+ const k = c?.editingDraft;
1318
+ if (k) {
1319
1319
  try {
1320
1320
  await r?.zones?.updateZone({
1321
1321
  zone: Xt({
1322
- id: m.id,
1323
- kind: m.kind,
1324
- name: m.name,
1325
- color: m.color,
1326
- points: [...m.points]
1322
+ id: k.id,
1323
+ kind: k.kind,
1324
+ name: k.name,
1325
+ color: k.color,
1326
+ points: [...k.points]
1327
1327
  })
1328
1328
  });
1329
1329
  } catch (x) {
1330
1330
  console.error("zones.updateZone failed", x);
1331
1331
  }
1332
- d?.discardDraft(), d?.setSelectedZoneId(null);
1332
+ c?.discardDraft(), c?.setSelectedZoneId(null);
1333
1333
  }
1334
- }, [r, d]), b = A(() => {
1335
- d?.discardDraft(), d?.setSelectedZoneId(null);
1336
- }, [d]), k = A(
1337
- async (m) => {
1334
+ }, [r, c]), b = P(() => {
1335
+ c?.discardDraft(), c?.setSelectedZoneId(null);
1336
+ }, [c]), m = P(
1337
+ async (k) => {
1338
1338
  try {
1339
- await r?.zones?.removeZone({ zoneId: m });
1339
+ await r?.zones?.removeZone({ zoneId: k });
1340
1340
  } catch (x) {
1341
1341
  console.error("zones.removeZone failed", x);
1342
1342
  }
1343
- d?.selectedZoneId === m && d.setSelectedZoneId(null), d?.editingDraft?.id === m && d.discardDraft();
1343
+ c?.selectedZoneId === k && c.setSelectedZoneId(null), c?.editingDraft?.id === k && c.discardDraft();
1344
1344
  },
1345
- [r, d]
1346
- ), I = A(
1347
- (m) => {
1348
- d?.startDrawing(m);
1345
+ [r, c]
1346
+ ), w = P(
1347
+ (k) => {
1348
+ c?.startDrawing(k);
1349
1349
  },
1350
- [d]
1351
- ), g = A(() => {
1352
- d?.setDrawingKind(null);
1353
- }, [d]), h = V(() => !n || !i.find((x) => x.id === n.id) ? null : {
1350
+ [c]
1351
+ ), _ = P(() => {
1352
+ c?.setDrawingKind(null);
1353
+ }, [c]), M = U(() => !n || !i.find((x) => x.id === n.id) ? null : {
1354
1354
  id: n.id,
1355
1355
  kind: n.kind,
1356
1356
  name: n.name,
1357
1357
  color: n.color,
1358
1358
  points: [...n.points]
1359
1359
  }, [i, n]);
1360
- return /* @__PURE__ */ u("div", { className: $e, children: [
1361
- /* @__PURE__ */ u("div", { className: Pe, children: [
1362
- /* @__PURE__ */ t("div", { className: Ae, children: /* @__PURE__ */ u("div", { className: "min-w-0", children: [
1363
- /* @__PURE__ */ t("h2", { className: xe, children: "Detection Zones" }),
1364
- /* @__PURE__ */ u("p", { className: `${Ee} mt-0.5 leading-tight`, children: [
1360
+ return /* @__PURE__ */ u("div", { className: Ge, children: [
1361
+ /* @__PURE__ */ u("div", { className: Ye, children: [
1362
+ /* @__PURE__ */ t("div", { className: Xe, children: /* @__PURE__ */ u("div", { className: "min-w-0", children: [
1363
+ /* @__PURE__ */ t("h2", { className: Ie, children: "Detection Zones" }),
1364
+ /* @__PURE__ */ u("p", { className: `${J} mt-0.5 leading-tight`, children: [
1365
1365
  "Pick a shape below or use the ",
1366
1366
  /* @__PURE__ */ t("strong", { className: "text-foreground", children: "Zones" }),
1367
1367
  " button on the live frame to draw new polygons or tripwires. Behaviour is set per-stage in the rules editors below — a zone with no rule is observed by analytics but never filters."
1368
1368
  ] })
1369
1369
  ] }) }),
1370
- /* @__PURE__ */ u("div", { className: `${Re} flex flex-col gap-3`, children: [
1370
+ /* @__PURE__ */ u("div", { className: `${Ke} flex flex-col gap-3`, children: [
1371
1371
  /* @__PURE__ */ t(
1372
- Pt,
1372
+ At,
1373
1373
  {
1374
1374
  zones: i,
1375
- selectedZoneId: f,
1376
- drawingKind: a,
1377
- onSelectZone: p,
1378
- onDeleteZone: k,
1379
- onStartDraw: I,
1380
- onCancelDraw: g
1375
+ selectedZoneId: h,
1376
+ drawingKind: s,
1377
+ onSelectZone: d,
1378
+ onDeleteZone: m,
1379
+ onStartDraw: w,
1380
+ onCancelDraw: _
1381
1381
  }
1382
1382
  ),
1383
- h && /* @__PURE__ */ u(Ze, { children: [
1383
+ M && /* @__PURE__ */ u(be, { children: [
1384
1384
  /* @__PURE__ */ t("div", { className: "border-t border-border" }),
1385
1385
  /* @__PURE__ */ t(
1386
1386
  Et,
1387
1387
  {
1388
- zone: h,
1389
- onSave: M,
1388
+ zone: M,
1389
+ onSave: Z,
1390
1390
  onDiscard: b,
1391
- onDelete: () => k(h.id)
1391
+ onDelete: () => m(M.id)
1392
1392
  }
1393
1393
  )
1394
1394
  ] })
1395
1395
  ] })
1396
1396
  ] }),
1397
1397
  /* @__PURE__ */ u("div", { className: `grid grid-cols-1 2xl:grid-cols-2 ${Qe}`, children: [
1398
- /* @__PURE__ */ t(Ne, { dev: r, stage: "motion", zones: c }),
1399
- /* @__PURE__ */ t(Ne, { dev: r, stage: "detection", zones: c })
1398
+ /* @__PURE__ */ t(we, { dev: r, stage: "motion", zones: p }),
1399
+ /* @__PURE__ */ t(we, { dev: r, stage: "detection", zones: p })
1400
1400
  ] })
1401
1401
  ] });
1402
1402
  }
1403
1403
  function Qt(e) {
1404
1404
  return e.deviceId === void 0 ? /* @__PURE__ */ t("div", { className: "rounded-lg border border-warning/30 bg-warning/10 px-3 py-2 text-xs text-warning", children: "ZoneEditor requires a deviceId" }) : /* @__PURE__ */ t(Kt, { deviceId: e.deviceId });
1405
1405
  }
1406
- function Jt({
1407
- options: e,
1408
- cells: o,
1409
- enabled: r,
1410
- sensitivity: l,
1411
- saving: c,
1412
- dirty: i,
1413
- onCellsChange: d,
1414
- onEnabledChange: a,
1415
- onSensitivityChange: f,
1416
- onSave: n,
1417
- onCancel: E
1418
- }) {
1419
- const { gridWidth: p, gridHeight: M } = e, b = p * M, k = X(!1), I = X(!0), g = X(/* @__PURE__ */ new Set()), [, h] = L(0), m = A(
1420
- (_, T) => {
1421
- if (_ < 0 || _ >= b || o[_] === T) return;
1422
- const s = [...o];
1423
- for (; s.length < b; ) s.push(!1);
1424
- s.length = b, s[_] = T, d(s);
1406
+ function Jt({ options: e, cells: o, onCellsChange: r }) {
1407
+ const { gridWidth: l, gridHeight: p } = e, i = l * p, c = Y(!1), s = Y(!0), h = Y(/* @__PURE__ */ new Set()), [, n] = L(0), S = P(
1408
+ (m, w) => {
1409
+ if (m < 0 || m >= i || o[m] === w) return;
1410
+ const _ = [...o];
1411
+ for (; _.length < i; ) _.push(!1);
1412
+ _.length = i, _[m] = w, r(_);
1425
1413
  },
1426
- [o, b, d]
1427
- ), x = A(
1428
- (_) => (T) => {
1429
- T.preventDefault();
1430
- const s = !o[_];
1431
- k.current = !0, I.current = s, g.current = /* @__PURE__ */ new Set([_]), m(_, s), h((y) => y + 1);
1414
+ [o, i, r]
1415
+ ), d = P(
1416
+ (m) => (w) => {
1417
+ w.preventDefault();
1418
+ const _ = !o[m];
1419
+ c.current = !0, s.current = _, h.current = /* @__PURE__ */ new Set([m]), S(m, _), n((M) => M + 1);
1432
1420
  },
1433
- [o, m]
1434
- ), G = A(
1435
- (_) => () => {
1436
- k.current && (g.current.has(_) || (g.current.add(_), m(_, I.current)));
1421
+ [o, S]
1422
+ ), Z = P(
1423
+ (m) => () => {
1424
+ c.current && (h.current.has(m) || (h.current.add(m), S(m, s.current)));
1437
1425
  },
1438
- [m]
1439
- ), v = A(() => {
1440
- k.current && (k.current = !1, g.current = /* @__PURE__ */ new Set());
1441
- }, []), { min: w, max: C, step: D } = e.sensitivity;
1442
- return /* @__PURE__ */ u(
1426
+ [S]
1427
+ ), b = P(() => {
1428
+ c.current && (c.current = !1, h.current = /* @__PURE__ */ new Set());
1429
+ }, []);
1430
+ return /* @__PURE__ */ t(
1443
1431
  "div",
1444
1432
  {
1445
- className: "absolute inset-0 select-none",
1446
- onPointerUp: v,
1447
- onPointerLeave: v,
1448
- children: [
1449
- /* @__PURE__ */ t(
1450
- "div",
1451
- {
1452
- className: "absolute inset-0 grid",
1453
- style: {
1454
- gridTemplateColumns: `repeat(${String(p)}, 1fr)`,
1455
- gridTemplateRows: `repeat(${String(M)}, 1fr)`
1456
- },
1457
- children: Array.from({ length: b }, (_, T) => {
1458
- const s = o[T] === !0;
1459
- return /* @__PURE__ */ t(
1460
- "button",
1461
- {
1462
- type: "button",
1463
- "aria-label": `motion cell ${String(T)}`,
1464
- "aria-pressed": s,
1465
- onPointerDown: x(T),
1466
- onPointerEnter: G(T),
1467
- className: s ? "border border-primary/40 bg-primary/30 hover:bg-primary/40 transition-colors" : "border border-white/15 bg-transparent hover:bg-white/10 transition-colors"
1468
- },
1469
- T
1470
- );
1471
- })
1472
- }
1473
- ),
1474
- /* @__PURE__ */ u(
1475
- "div",
1433
+ className: "absolute inset-0 select-none grid",
1434
+ style: {
1435
+ gridTemplateColumns: `repeat(${String(l)}, 1fr)`,
1436
+ gridTemplateRows: `repeat(${String(p)}, 1fr)`
1437
+ },
1438
+ onPointerUp: b,
1439
+ onPointerLeave: b,
1440
+ children: Array.from({ length: i }, (m, w) => {
1441
+ const _ = o[w] === !0;
1442
+ return /* @__PURE__ */ t(
1443
+ "button",
1476
1444
  {
1477
- className: "absolute bottom-2 left-2 flex flex-col gap-2 rounded-md border border-border bg-surface/95 px-3 py-2 shadow-lg backdrop-blur",
1478
- onPointerDown: (_) => _.stopPropagation(),
1479
- children: [
1480
- /* @__PURE__ */ u("label", { className: "flex items-center gap-2 text-[11px] text-foreground", children: [
1481
- /* @__PURE__ */ t(
1482
- "input",
1483
- {
1484
- type: "checkbox",
1485
- checked: r,
1486
- onChange: (_) => a(_.target.checked),
1487
- className: "h-3 w-3 accent-primary"
1488
- }
1489
- ),
1490
- /* @__PURE__ */ t("span", { className: "font-medium", children: "Motion detection enabled" })
1491
- ] }),
1492
- /* @__PURE__ */ u("label", { className: "flex items-center gap-2 text-[11px] text-foreground", children: [
1493
- /* @__PURE__ */ t("span", { className: "w-20 shrink-0", children: "Sensitivity" }),
1494
- /* @__PURE__ */ t(
1495
- "input",
1496
- {
1497
- type: "range",
1498
- min: w,
1499
- max: C,
1500
- step: D,
1501
- value: l,
1502
- onChange: (_) => f(Number(_.target.value)),
1503
- className: "h-1 w-32 accent-primary"
1504
- }
1505
- ),
1506
- /* @__PURE__ */ t("span", { className: "w-8 shrink-0 text-right tabular-nums text-foreground-subtle", children: l })
1507
- ] }),
1508
- /* @__PURE__ */ u("div", { className: "flex items-center gap-2 pt-0.5", children: [
1509
- /* @__PURE__ */ t(
1510
- "button",
1511
- {
1512
- type: "button",
1513
- onClick: n,
1514
- disabled: c || !i,
1515
- className: "rounded border border-primary/50 bg-primary/15 px-2 py-1 text-[11px] font-medium text-primary hover:bg-primary/25 disabled:opacity-40 transition-colors",
1516
- children: c ? "Saving…" : "Save"
1517
- }
1518
- ),
1519
- /* @__PURE__ */ t(
1520
- "button",
1521
- {
1522
- type: "button",
1523
- onClick: E,
1524
- disabled: c,
1525
- className: "rounded border border-border bg-surface px-2 py-1 text-[11px] text-foreground-subtle hover:bg-surface-hover disabled:opacity-40 transition-colors",
1526
- children: "Cancel"
1527
- }
1528
- ),
1529
- /* @__PURE__ */ t("span", { className: "text-[10px] text-foreground-subtle", children: "Click or drag cells to paint the motion mask." })
1530
- ] })
1531
- ]
1532
- }
1533
- )
1534
- ]
1445
+ type: "button",
1446
+ "aria-label": `motion cell ${String(w)}`,
1447
+ "aria-pressed": _,
1448
+ onPointerDown: d(w),
1449
+ onPointerEnter: Z(w),
1450
+ className: _ ? "border border-primary/40 bg-primary/30 hover:bg-primary/40 transition-colors" : "border border-white/15 bg-transparent hover:bg-white/10 transition-colors"
1451
+ },
1452
+ w
1453
+ );
1454
+ })
1535
1455
  }
1536
1456
  );
1537
1457
  }
@@ -1539,117 +1459,157 @@ function en(e) {
1539
1459
  const o = e instanceof Error ? e.message : String(e);
1540
1460
  return o.includes("provider not available") || o.includes("motion-zones");
1541
1461
  }
1542
- function tn({ deviceId: e }) {
1543
- const o = ie(), r = ae(o.trpcClient, e), l = le(r?.state.motionZones), [c, i] = L(null), [d, a] = L(!1), [f, n] = L(null), [E, p] = L(!1), M = X(!1);
1544
- K(() => {
1462
+ function Me(e, o) {
1463
+ const r = o.gridWidth * o.gridHeight, l = new Array(r);
1464
+ for (let p = 0; p < r; p += 1) l[p] = e[p] === !0;
1465
+ return l;
1466
+ }
1467
+ function tn(e, o) {
1468
+ if (e.length !== o.length) return !1;
1469
+ for (let r = 0; r < e.length; r += 1) if (e[r] !== o[r]) return !1;
1470
+ return !0;
1471
+ }
1472
+ function nn({ deviceId: e }) {
1473
+ const o = ae(), r = le(o.trpcClient, e), [l, p] = L(null), [i, c] = L(!1), [s, h] = L(null), [n, S] = L(null), [d, Z] = L(!1), b = Y(!1);
1474
+ X(() => {
1545
1475
  if (!r) return;
1546
- let g = !1;
1476
+ let f = !1;
1547
1477
  return (async () => {
1548
1478
  try {
1549
- const h = await r.motionZones?.getOptions({});
1550
- if (g || !h || (i(h), M.current)) return;
1551
- const m = await r.motionZones?.getStatus({});
1552
- if (g || !m) return;
1553
- M.current = !0, n({
1554
- enabled: m.enabled,
1555
- sensitivity: m.sensitivity,
1556
- cells: me(m.cells, h)
1557
- });
1558
- } catch (h) {
1559
- if (g) return;
1560
- en(h) ? a(!0) : console.error("motion-zones load failed", h);
1479
+ const g = await r.motionZones?.getOptions({});
1480
+ if (f || !g || (p(g), b.current)) return;
1481
+ const F = await r.motionZones?.getStatus({});
1482
+ if (f || !F) return;
1483
+ b.current = !0;
1484
+ const K = Me(F.cells, g);
1485
+ S(K), h(K);
1486
+ } catch (g) {
1487
+ if (f) return;
1488
+ en(g) ? c(!0) : console.error("motion-zones load failed", g);
1561
1489
  }
1562
1490
  })(), () => {
1563
- g = !0;
1491
+ f = !0;
1564
1492
  };
1565
1493
  }, [r]);
1566
- const b = V(() => !f || !l ? !1 : f.enabled !== l.enabled || f.sensitivity !== l.sensitivity || !nn(f.cells, l.cells), [f, l]), k = A(async () => {
1567
- if (!(!f || !r?.motionZones)) {
1568
- p(!0);
1494
+ const m = U(
1495
+ () => s !== null && n !== null && !tn(s, n),
1496
+ [s, n]
1497
+ ), w = U(
1498
+ () => s ? s.reduce((f, g) => g ? f + 1 : f, 0) : 0,
1499
+ [s]
1500
+ ), _ = l ? l.gridWidth * l.gridHeight : 0, M = P((f) => {
1501
+ _ > 0 && h(new Array(_).fill(f));
1502
+ }, [_]), k = P(() => {
1503
+ h((f) => f && f.map((g) => !g));
1504
+ }, []), x = P(() => {
1505
+ n && h([...n]);
1506
+ }, [n]), V = P(async () => {
1507
+ if (!(!s || !r?.motionZones || !l)) {
1508
+ Z(!0);
1569
1509
  try {
1570
- await r.motionZones.setZone({
1571
- patch: {
1572
- enabled: f.enabled,
1573
- sensitivity: f.sensitivity,
1574
- cells: [...f.cells]
1575
- }
1576
- });
1577
- const g = await r.motionZones.getStatus({});
1578
- g && c && n({
1579
- enabled: g.enabled,
1580
- sensitivity: g.sensitivity,
1581
- cells: me(g.cells, c)
1582
- });
1583
- } catch (g) {
1584
- console.error("motion-zones.setZone failed", g);
1510
+ await r.motionZones.setZone({ patch: { cells: [...s] } });
1511
+ const f = await r.motionZones.getStatus({});
1512
+ if (f) {
1513
+ const g = Me(f.cells, l);
1514
+ S(g), h(g);
1515
+ }
1516
+ } catch (f) {
1517
+ console.error("motion-zones.setZone failed", f);
1585
1518
  } finally {
1586
- p(!1);
1519
+ Z(!1);
1587
1520
  }
1588
1521
  }
1589
- }, [f, r, c]), I = A(() => {
1590
- !l || !c || n({
1591
- enabled: l.enabled,
1592
- sensitivity: l.sensitivity,
1593
- cells: me(l.cells, c)
1594
- });
1595
- }, [l, c]);
1596
- return d || !c || !f ? null : /* @__PURE__ */ t(
1597
- Jt,
1598
- {
1599
- options: c,
1600
- cells: f.cells,
1601
- enabled: f.enabled,
1602
- sensitivity: f.sensitivity,
1603
- saving: E,
1604
- dirty: b,
1605
- onCellsChange: (g) => n((h) => h && { ...h, cells: g }),
1606
- onEnabledChange: (g) => n((h) => h && { ...h, enabled: g }),
1607
- onSensitivityChange: (g) => n((h) => h && { ...h, sensitivity: g }),
1608
- onSave: k,
1609
- onCancel: I
1610
- }
1611
- );
1612
- }
1613
- function me(e, o) {
1614
- const r = o.gridWidth * o.gridHeight, l = new Array(r);
1615
- for (let c = 0; c < r; c += 1) l[c] = e[c] === !0;
1616
- return l;
1617
- }
1618
- function nn(e, o) {
1619
- if (e.length !== o.length) return !1;
1620
- for (let r = 0; r < e.length; r += 1)
1621
- if (e[r] !== o[r]) return !1;
1622
- return !0;
1623
- }
1624
- const rn = ve(tn);
1625
- function on({ deviceId: e }) {
1626
- const o = V(
1627
- () => ({
1522
+ }, [s, r, l]), v = U(
1523
+ () => !i && l && s ? {
1628
1524
  id: "motion-zones",
1629
1525
  order: 110,
1630
1526
  // above the analytics zones overlay (order 100)
1631
- node: /* @__PURE__ */ t(rn, { deviceId: e })
1632
- }),
1633
- [e]
1527
+ node: /* @__PURE__ */ t(Jt, { options: l, cells: s, onCellsChange: h })
1528
+ } : null,
1529
+ [i, l, s]
1634
1530
  );
1635
- return Ie(o), /* @__PURE__ */ t("div", { className: $e, children: /* @__PURE__ */ u("div", { className: Pe, children: [
1636
- /* @__PURE__ */ t("div", { className: Ae, children: /* @__PURE__ */ t("h2", { className: xe, children: "Motion Zones" }) }),
1637
- /* @__PURE__ */ t("div", { className: Re, children: /* @__PURE__ */ u("p", { className: `${Ee} leading-relaxed`, children: [
1638
- "The on-camera motion-detection grid is shown on the live frame while this section is open. Click or drag cells to paint the region the camera watches, toggle detection on or off, and tune sensitivity — then ",
1531
+ return Ze(v), /* @__PURE__ */ t("div", { className: "flex flex-col gap-3", children: i ? /* @__PURE__ */ t("p", { className: `${J} leading-relaxed`, children: "This camera doesn't expose an on-board motion-detection grid." }) : !i && l !== null && s !== null ? /* @__PURE__ */ u(be, { children: [
1532
+ /* @__PURE__ */ u("p", { className: `${J} leading-relaxed`, children: [
1533
+ "Click or drag cells on the live frame to paint the region the camera watches for motion, then",
1534
+ " ",
1639
1535
  /* @__PURE__ */ t("strong", { className: "text-foreground", children: "Save" }),
1536
+ " to push the mask to the camera. Detection on/off and sensitivity are set in the",
1640
1537
  " ",
1641
- "to push the mask to the camera. Cameras without an on-board motion grid show no overlay."
1642
- ] }) })
1643
- ] }) });
1538
+ /* @__PURE__ */ t("strong", { className: "text-foreground", children: "On-camera motion" }),
1539
+ " section."
1540
+ ] }),
1541
+ /* @__PURE__ */ u("div", { className: "flex items-center gap-2 flex-wrap", children: [
1542
+ /* @__PURE__ */ t(
1543
+ "button",
1544
+ {
1545
+ type: "button",
1546
+ onClick: () => M(!0),
1547
+ disabled: d,
1548
+ className: "rounded-md border border-border bg-surface px-2 py-1 text-[11px] font-medium text-foreground-subtle hover:bg-surface-hover disabled:opacity-40 transition-colors",
1549
+ children: "All on"
1550
+ }
1551
+ ),
1552
+ /* @__PURE__ */ t(
1553
+ "button",
1554
+ {
1555
+ type: "button",
1556
+ onClick: () => M(!1),
1557
+ disabled: d,
1558
+ className: "rounded-md border border-border bg-surface px-2 py-1 text-[11px] font-medium text-foreground-subtle hover:bg-surface-hover disabled:opacity-40 transition-colors",
1559
+ children: "All off"
1560
+ }
1561
+ ),
1562
+ /* @__PURE__ */ t(
1563
+ "button",
1564
+ {
1565
+ type: "button",
1566
+ onClick: k,
1567
+ disabled: d,
1568
+ className: "rounded-md border border-border bg-surface px-2 py-1 text-[11px] font-medium text-foreground-subtle hover:bg-surface-hover disabled:opacity-40 transition-colors",
1569
+ children: "Invert"
1570
+ }
1571
+ ),
1572
+ /* @__PURE__ */ u("span", { className: `${J} ml-1 tabular-nums`, children: [
1573
+ w,
1574
+ " / ",
1575
+ _,
1576
+ " cells · ",
1577
+ l.gridWidth,
1578
+ "×",
1579
+ l.gridHeight
1580
+ ] }),
1581
+ /* @__PURE__ */ t("span", { className: "flex-1" }),
1582
+ /* @__PURE__ */ t(
1583
+ "button",
1584
+ {
1585
+ type: "button",
1586
+ onClick: x,
1587
+ disabled: d || !m,
1588
+ className: "rounded-md border border-border bg-surface px-2 py-1 text-[11px] text-foreground-subtle hover:bg-surface-hover disabled:opacity-40 transition-colors",
1589
+ children: "Revert"
1590
+ }
1591
+ ),
1592
+ /* @__PURE__ */ t(
1593
+ "button",
1594
+ {
1595
+ type: "button",
1596
+ onClick: () => void V(),
1597
+ disabled: d || !m,
1598
+ className: "rounded-md border border-primary/50 bg-primary/15 px-2.5 py-1 text-[11px] font-medium text-primary hover:bg-primary/25 disabled:opacity-40 transition-colors",
1599
+ children: d ? "Saving…" : "Save"
1600
+ }
1601
+ )
1602
+ ] })
1603
+ ] }) : /* @__PURE__ */ t("p", { className: `${J} leading-relaxed`, children: "Loading the camera's motion grid…" }) });
1644
1604
  }
1645
- function sn(e) {
1646
- return e.deviceId === void 0 ? /* @__PURE__ */ t("div", { className: "rounded-lg border border-warning/30 bg-warning/10 px-3 py-2 text-xs text-warning", children: "MotionZonesEditor requires a deviceId" }) : /* @__PURE__ */ t(on, { deviceId: e.deviceId });
1605
+ function rn(e) {
1606
+ return e.deviceId === void 0 ? /* @__PURE__ */ t("div", { className: "rounded-lg border border-warning/30 bg-warning/10 px-3 py-2 text-xs text-warning", children: "MotionZonesEditor requires a deviceId" }) : /* @__PURE__ */ t(nn, { deviceId: e.deviceId });
1647
1607
  }
1648
- const gn = {
1608
+ const mn = {
1649
1609
  "pipeline-quick-stats": Mt,
1650
1610
  "zone-editor": Qt,
1651
- "motion-zones-editor": sn
1611
+ "motion-zones-editor": rn
1652
1612
  };
1653
1613
  export {
1654
- gn as default
1614
+ mn as default
1655
1615
  };