@camstack/addon-osd-manager 0.1.155 → 0.1.157
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{MaskShapeCanvas-BEVxAjNq.mjs → MaskShapeCanvas-BT714ljC.mjs} +113 -113
- package/dist/MotionZonesSettings-vYt4dibj.mjs +310 -0
- package/dist/{PrivacyMaskSettings-D7EH_wl3.mjs → PrivacyMaskSettings-BiQ78hst.mjs} +35 -60
- package/dist/{SceneMonitorEditor-CO6VwdkE.mjs → SceneMonitorEditor-CJtJIyMf.mjs} +307 -307
- package/dist/_stub.js +11763 -4481
- package/dist/{_virtual_mf-localSharedImportMap___mfe_internal__addon_osd_manager_page-B3v0K7b1.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_osd_manager_page-DdAtpC7z.mjs} +3 -3
- package/dist/_virtual_mf___mfe_internal__addon_osd_manager_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-BtgV-Ym5.mjs +26 -0
- package/dist/_virtual_mf___mfe_internal__addon_osd_manager_page__loadShare___mf_0_tanstack_mf_1_react_mf_2_query__loadShare__.js-CHxDN0gE.mjs +26 -0
- package/dist/{_virtual_mf___mfe_internal__addon_osd_manager_page__loadShare__react__loadShare__.js-Bs1t18EM.mjs → _virtual_mf___mfe_internal__addon_osd_manager_page__loadShare__react__loadShare__.js-C5jUMd7X.mjs} +1 -1
- package/dist/{_virtual_mf___mfe_internal__addon_osd_manager_page__loadShare__react_mf_2_dom__loadShare__.js-C0K4h_0e.mjs → _virtual_mf___mfe_internal__addon_osd_manager_page__loadShare__react_mf_2_dom__loadShare__.js-qB5uHZAd.mjs} +8 -7
- package/dist/addon-osd-manager.css +1 -1
- package/dist/{hostInit-B3sHUn3j.mjs → hostInit-0Mc7Fm1R.mjs} +2 -2
- package/dist/index.js +1077 -112
- package/dist/index.mjs +1077 -112
- package/dist/{player-overlays-CTsQBdl8.mjs → player-overlays-BPyna-eI.mjs} +14 -14
- package/dist/remoteEntry.js +1 -1
- package/dist/{responsive-BPw6Y2I0.mjs → responsive-B0yDP9vf.mjs} +31 -27
- package/dist/{scene-monitor-copy-DNkKk6vF.mjs → scene-monitor-copy-BzX20O6q.mjs} +13 -13
- package/dist/{square-BPzhX8Pc.mjs → square-BOMOn_6j.mjs} +29 -4
- package/dist/{trash-2-DemFUbcB.mjs → trash-2-BolGRl2P.mjs} +1 -1
- package/dist/{virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_osd_manager_page__remoteEntry_js-BUQgSy9b.mjs → virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_osd_manager_page__remoteEntry_js-UY9P_4V2.mjs} +1 -1
- package/package.json +1 -3
- package/dist/MotionZonesSettings-DHyaxzBi.mjs +0 -310
- package/dist/_virtual_mf___mfe_internal__addon_osd_manager_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-1qxETV_o.mjs +0 -26
- package/dist/_virtual_mf___mfe_internal__addon_osd_manager_page__loadShare___mf_0_tanstack_mf_1_react_mf_2_query__loadShare__.js-DmzTg7Gl.mjs +0 -25
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { a as o,
|
|
3
|
-
import { a as f, c as p, d as
|
|
4
|
-
import { t as
|
|
5
|
-
import { n as
|
|
6
|
-
import { MaskShapeCanvas as
|
|
7
|
-
var
|
|
1
|
+
import { b as e, c as t, g as n, h as r, m as i, u as a } from "./_virtual_mf___mfe_internal__addon_osd_manager_page__loadShare__react__loadShare__.js-C5jUMd7X.mjs";
|
|
2
|
+
import { a as o, c as s, n as c, o as l, r as u, t as d } from "./responsive-B0yDP9vf.mjs";
|
|
3
|
+
import { a as f, c as p, d as m, i as h, l as g, n as _, o as v, r as y, s as b, t as x, u as S } from "./scene-monitor-copy-BzX20O6q.mjs";
|
|
4
|
+
import { t as C } from "./trash-2-BolGRl2P.mjs";
|
|
5
|
+
import { n as w, r as T, t as E } from "./_virtual_mf___mfe_internal__addon_osd_manager_page__loadShare__react_mf_1_jsx_mf_2_runtime__loadShare__.js-DalfdIDw.mjs";
|
|
6
|
+
import { MaskShapeCanvas as D } from "./MaskShapeCanvas-BT714ljC.mjs";
|
|
7
|
+
var O = s("settings-2", [
|
|
8
8
|
["path", {
|
|
9
9
|
d: "M14 17H5",
|
|
10
10
|
key: "gfn3mx"
|
|
@@ -28,12 +28,12 @@ var D = u("settings-2", [
|
|
|
28
28
|
]);
|
|
29
29
|
//#endregion
|
|
30
30
|
//#region ../ui-library/src/composites/cap-settings/SceneReferenceGallery.tsx
|
|
31
|
-
|
|
32
|
-
var
|
|
33
|
-
function k(e) {
|
|
34
|
-
return `${O}/m/${e}`;
|
|
35
|
-
}
|
|
31
|
+
e();
|
|
32
|
+
var k = p("/addon/pipeline-analytics/event-media");
|
|
36
33
|
function A(e) {
|
|
34
|
+
return `${k}/m/${e}`;
|
|
35
|
+
}
|
|
36
|
+
function j(e) {
|
|
37
37
|
let t = /* @__PURE__ */ new Map();
|
|
38
38
|
for (let n of e.states) n.references.forEach((e, r) => {
|
|
39
39
|
let i = t.get(e.condition) ?? [];
|
|
@@ -48,56 +48,56 @@ function A(e) {
|
|
|
48
48
|
tiles: [...t].sort((e, t) => t.reference.capturedAt - e.reference.capturedAt)
|
|
49
49
|
})).sort((e, t) => e.condition.localeCompare(t.condition));
|
|
50
50
|
}
|
|
51
|
-
function
|
|
51
|
+
function M(e) {
|
|
52
52
|
return e.states.reduce((e, t) => e + t.references.length, 0);
|
|
53
53
|
}
|
|
54
|
-
var
|
|
55
|
-
function
|
|
56
|
-
let i =
|
|
57
|
-
return i.length === 0 ? /* @__PURE__ */
|
|
54
|
+
var N = "rounded border border-danger/50 bg-danger/10 px-1 py-0.5 text-[10px] font-medium text-danger hover:bg-danger/20 disabled:opacity-40 transition-colors";
|
|
55
|
+
function ee({ monitor: e, disabled: t, onDelete: r }) {
|
|
56
|
+
let i = j(e), a = M(e), [o, s] = n(null);
|
|
57
|
+
return i.length === 0 ? /* @__PURE__ */ w("p", {
|
|
58
58
|
className: `${d} leading-relaxed`,
|
|
59
59
|
children: "No photographs captured yet. Press “Capture daylight” to take the one this scene will judge everything against."
|
|
60
|
-
}) : /* @__PURE__ */
|
|
60
|
+
}) : /* @__PURE__ */ w("div", {
|
|
61
61
|
className: "flex flex-col gap-2",
|
|
62
|
-
children: i.map((e) => /* @__PURE__ */
|
|
62
|
+
children: i.map((e) => /* @__PURE__ */ T("div", {
|
|
63
63
|
className: "flex flex-col gap-1",
|
|
64
|
-
children: [/* @__PURE__ */
|
|
64
|
+
children: [/* @__PURE__ */ T("p", {
|
|
65
65
|
className: "text-[10px] font-semibold uppercase tracking-wide text-foreground-subtle",
|
|
66
66
|
children: [
|
|
67
|
-
|
|
67
|
+
v(e.condition),
|
|
68
68
|
" · ",
|
|
69
69
|
e.tiles.length
|
|
70
70
|
]
|
|
71
|
-
}), /* @__PURE__ */
|
|
71
|
+
}), /* @__PURE__ */ w("ul", {
|
|
72
72
|
className: "flex flex-wrap gap-1.5",
|
|
73
|
-
children: e.tiles.map((
|
|
74
|
-
let i = `${
|
|
75
|
-
return /* @__PURE__ */
|
|
73
|
+
children: e.tiles.map((n) => {
|
|
74
|
+
let i = `${n.stateId}:${String(n.index)}`, c = a === 1, l = o === i;
|
|
75
|
+
return /* @__PURE__ */ T("li", {
|
|
76
76
|
className: "flex w-24 flex-col gap-1 rounded-md border border-border p-1",
|
|
77
77
|
children: [
|
|
78
|
-
/* @__PURE__ */
|
|
79
|
-
/* @__PURE__ */
|
|
78
|
+
/* @__PURE__ */ w(P, { reference: n.reference }),
|
|
79
|
+
/* @__PURE__ */ w("span", {
|
|
80
80
|
className: `${d} tabular-nums`,
|
|
81
|
-
children:
|
|
81
|
+
children: F(n.reference.capturedAt)
|
|
82
82
|
}),
|
|
83
|
-
/* @__PURE__ */
|
|
83
|
+
/* @__PURE__ */ T("button", {
|
|
84
84
|
type: "button",
|
|
85
|
-
className:
|
|
86
|
-
disabled:
|
|
87
|
-
"aria-label": `Delete the ${
|
|
85
|
+
className: N,
|
|
86
|
+
disabled: t,
|
|
87
|
+
"aria-label": `Delete the ${v(e.condition).toLowerCase()} photograph from ${F(n.reference.capturedAt)}`,
|
|
88
88
|
onClick: () => {
|
|
89
89
|
if (c && !l) {
|
|
90
90
|
s(i);
|
|
91
91
|
return;
|
|
92
92
|
}
|
|
93
93
|
s(null), r({
|
|
94
|
-
stateId:
|
|
95
|
-
index:
|
|
94
|
+
stateId: n.stateId,
|
|
95
|
+
index: n.index
|
|
96
96
|
});
|
|
97
97
|
},
|
|
98
|
-
children: [/* @__PURE__ */ C
|
|
98
|
+
children: [/* @__PURE__ */ w(C, { className: "mr-1 inline h-3 w-3" }), l ? "Confirm" : "Delete"]
|
|
99
99
|
}),
|
|
100
|
-
l && /* @__PURE__ */
|
|
100
|
+
l && /* @__PURE__ */ w("p", {
|
|
101
101
|
className: "text-[10px] leading-snug text-warning",
|
|
102
102
|
children: "This is the only photograph this scene has. Delete it and the scene no longer knows what normal looks like — it stops judging until you capture again."
|
|
103
103
|
})
|
|
@@ -108,24 +108,24 @@ function te({ monitor: e, disabled: n, onDelete: r }) {
|
|
|
108
108
|
}, e.condition))
|
|
109
109
|
});
|
|
110
110
|
}
|
|
111
|
-
function
|
|
112
|
-
let [
|
|
113
|
-
return i === void 0 ||
|
|
111
|
+
function P({ reference: e }) {
|
|
112
|
+
let [t, r] = n(!1), i = e.thumbnailMediaId;
|
|
113
|
+
return i === void 0 || t ? /* @__PURE__ */ T("div", {
|
|
114
114
|
className: "flex h-16 w-full flex-col items-center justify-center gap-0.5 rounded bg-surface text-foreground-subtle",
|
|
115
115
|
title: "The picture for this reference is no longer stored. The reference itself is intact and still being scored against.",
|
|
116
|
-
children: [/* @__PURE__ */
|
|
116
|
+
children: [/* @__PURE__ */ w(S, { className: "h-4 w-4" }), /* @__PURE__ */ w("span", {
|
|
117
117
|
className: "text-[9px]",
|
|
118
118
|
children: "no picture"
|
|
119
119
|
})]
|
|
120
|
-
}) : /* @__PURE__ */
|
|
121
|
-
src:
|
|
120
|
+
}) : /* @__PURE__ */ w("img", {
|
|
121
|
+
src: A(i),
|
|
122
122
|
alt: "",
|
|
123
123
|
loading: "lazy",
|
|
124
124
|
className: "h-16 w-full rounded object-cover",
|
|
125
125
|
onError: () => r(!0)
|
|
126
126
|
});
|
|
127
127
|
}
|
|
128
|
-
function
|
|
128
|
+
function F(e) {
|
|
129
129
|
let t = new Date(e);
|
|
130
130
|
return `${t.toLocaleDateString()} ${t.toLocaleTimeString([], {
|
|
131
131
|
hour: "2-digit",
|
|
@@ -134,16 +134,16 @@ function P(e) {
|
|
|
134
134
|
}
|
|
135
135
|
//#endregion
|
|
136
136
|
//#region ../ui-library/src/composites/cap-settings/SceneSettingsForm.tsx
|
|
137
|
-
|
|
138
|
-
var
|
|
137
|
+
e();
|
|
138
|
+
var I = "rounded-md border border-border bg-surface px-2 py-1 text-[11px] text-foreground focus:border-primary focus:outline-none disabled:opacity-50", L = "text-[10px] font-medium text-foreground-subtle", R = "flex flex-col gap-2 rounded-md border border-border bg-surface/40 p-2", z = "text-[10px] font-semibold uppercase tracking-wide text-foreground-subtle", B = 5, V = 3600, H = {
|
|
139
139
|
periodic: "Only on the clock. Predictable, and it notices a change even on a camera nothing ever moves in front of.",
|
|
140
140
|
"on-motion": "Only after the camera has been still again for the quiet window below. Cheapest, but a change nobody walks past is never seen.",
|
|
141
141
|
both: "Both — the clock is the safety net that lets the motion path miss. This is the right answer for almost every scene."
|
|
142
|
-
},
|
|
142
|
+
}, U = {
|
|
143
143
|
skip: "Sit that light out. No verdict, no alarm, no flag touched — it picks itself back up when a light it knows returns. This is why the night capture is optional.",
|
|
144
144
|
"judge-anyway": "Compare against the references you do have. Only correct when the two lights genuinely look alike (a floodlit driveway, an indoor lamp) — against a real infrared frame it will report a change that did not happen."
|
|
145
145
|
};
|
|
146
|
-
function
|
|
146
|
+
function W(e) {
|
|
147
147
|
return {
|
|
148
148
|
label: e.label,
|
|
149
149
|
checkIntervalSec: e.checkIntervalSec ?? 60,
|
|
@@ -154,10 +154,10 @@ function U(e) {
|
|
|
154
154
|
confirmPrompt: e.confirm?.prompt ?? ""
|
|
155
155
|
};
|
|
156
156
|
}
|
|
157
|
-
function
|
|
158
|
-
let [
|
|
159
|
-
|
|
160
|
-
s || o(
|
|
157
|
+
function G({ monitor: e, disabled: t, onPatch: r }) {
|
|
158
|
+
let [i, o] = n(() => W(e)), [s, c] = n(!1);
|
|
159
|
+
a(() => {
|
|
160
|
+
s || o(W(e));
|
|
161
161
|
}, [e, s]);
|
|
162
162
|
let l = (e) => {
|
|
163
163
|
c(!1), r(e);
|
|
@@ -169,374 +169,374 @@ function W({ monitor: e, disabled: n, onPatch: r }) {
|
|
|
169
169
|
...e.check,
|
|
170
170
|
hysteresisCount: t.hysteresisCount ?? e.check.hysteresisCount
|
|
171
171
|
}, f = e.confirm?.enabled === !0, p = e.check.mode === "similarity" ? e.check.threshold : null;
|
|
172
|
-
return /* @__PURE__ */
|
|
172
|
+
return /* @__PURE__ */ T("div", {
|
|
173
173
|
className: "flex flex-col gap-2",
|
|
174
174
|
children: [
|
|
175
|
-
/* @__PURE__ */
|
|
176
|
-
className:
|
|
175
|
+
/* @__PURE__ */ T("div", {
|
|
176
|
+
className: R,
|
|
177
177
|
children: [
|
|
178
|
-
/* @__PURE__ */
|
|
179
|
-
className:
|
|
178
|
+
/* @__PURE__ */ w("p", {
|
|
179
|
+
className: z,
|
|
180
180
|
children: "What it watches"
|
|
181
181
|
}),
|
|
182
|
-
/* @__PURE__ */
|
|
182
|
+
/* @__PURE__ */ T("label", {
|
|
183
183
|
className: "flex flex-col gap-1",
|
|
184
|
-
children: [/* @__PURE__ */
|
|
185
|
-
className:
|
|
184
|
+
children: [/* @__PURE__ */ w("span", {
|
|
185
|
+
className: L,
|
|
186
186
|
children: "Name"
|
|
187
|
-
}), /* @__PURE__ */
|
|
187
|
+
}), /* @__PURE__ */ w("input", {
|
|
188
188
|
type: "text",
|
|
189
|
-
value:
|
|
190
|
-
disabled:
|
|
191
|
-
className:
|
|
189
|
+
value: i.label,
|
|
190
|
+
disabled: t,
|
|
191
|
+
className: I,
|
|
192
192
|
onFocus: () => c(!0),
|
|
193
193
|
onChange: (e) => o((t) => ({
|
|
194
194
|
...t,
|
|
195
195
|
label: e.target.value
|
|
196
196
|
})),
|
|
197
197
|
onBlur: () => {
|
|
198
|
-
let t =
|
|
198
|
+
let t = i.label.trim();
|
|
199
199
|
t.length > 0 && t !== e.label ? l({ label: t }) : c(!1);
|
|
200
200
|
}
|
|
201
201
|
})]
|
|
202
202
|
}),
|
|
203
|
-
/* @__PURE__ */
|
|
203
|
+
/* @__PURE__ */ T("label", {
|
|
204
204
|
className: "flex items-center gap-2",
|
|
205
|
-
children: [/* @__PURE__ */
|
|
205
|
+
children: [/* @__PURE__ */ w("input", {
|
|
206
206
|
type: "checkbox",
|
|
207
207
|
checked: e.enabled,
|
|
208
|
-
disabled:
|
|
208
|
+
disabled: t,
|
|
209
209
|
onChange: (e) => l({ enabled: e.target.checked })
|
|
210
|
-
}), /* @__PURE__ */
|
|
211
|
-
className:
|
|
210
|
+
}), /* @__PURE__ */ w("span", {
|
|
211
|
+
className: L,
|
|
212
212
|
children: "Watching"
|
|
213
213
|
})]
|
|
214
214
|
}),
|
|
215
|
-
/* @__PURE__ */
|
|
215
|
+
/* @__PURE__ */ w("p", {
|
|
216
216
|
className: d,
|
|
217
217
|
children: "Turned off, the scene keeps its region, its references and its flag — it simply stops checking. Nothing is lost by pausing one for a while."
|
|
218
218
|
}),
|
|
219
|
-
/* @__PURE__ */
|
|
219
|
+
/* @__PURE__ */ T("label", {
|
|
220
220
|
className: "flex flex-col gap-1",
|
|
221
|
-
children: [/* @__PURE__ */
|
|
222
|
-
className:
|
|
221
|
+
children: [/* @__PURE__ */ w("span", {
|
|
222
|
+
className: L,
|
|
223
223
|
children: "When to look"
|
|
224
|
-
}), /* @__PURE__ */
|
|
224
|
+
}), /* @__PURE__ */ T("select", {
|
|
225
225
|
value: e.triggerMode,
|
|
226
|
-
disabled:
|
|
227
|
-
className:
|
|
226
|
+
disabled: t,
|
|
227
|
+
className: I,
|
|
228
228
|
onChange: (e) => {
|
|
229
229
|
let t = e.target.value;
|
|
230
230
|
(t === "periodic" || t === "on-motion" || t === "both") && l({ triggerMode: t });
|
|
231
231
|
},
|
|
232
232
|
children: [
|
|
233
|
-
/* @__PURE__ */
|
|
233
|
+
/* @__PURE__ */ w("option", {
|
|
234
234
|
value: "both",
|
|
235
235
|
children: "On the clock and after motion settles"
|
|
236
236
|
}),
|
|
237
|
-
/* @__PURE__ */
|
|
237
|
+
/* @__PURE__ */ w("option", {
|
|
238
238
|
value: "periodic",
|
|
239
239
|
children: "On the clock only"
|
|
240
240
|
}),
|
|
241
|
-
/* @__PURE__ */
|
|
241
|
+
/* @__PURE__ */ w("option", {
|
|
242
242
|
value: "on-motion",
|
|
243
243
|
children: "After motion settles only"
|
|
244
244
|
})
|
|
245
245
|
]
|
|
246
246
|
})]
|
|
247
247
|
}),
|
|
248
|
-
/* @__PURE__ */
|
|
248
|
+
/* @__PURE__ */ w("p", {
|
|
249
249
|
className: d,
|
|
250
|
-
children:
|
|
250
|
+
children: H[e.triggerMode]
|
|
251
251
|
}),
|
|
252
|
-
/* @__PURE__ */
|
|
252
|
+
/* @__PURE__ */ T("label", {
|
|
253
253
|
className: "flex flex-col gap-1",
|
|
254
|
-
children: [/* @__PURE__ */
|
|
255
|
-
className:
|
|
254
|
+
children: [/* @__PURE__ */ w("span", {
|
|
255
|
+
className: L,
|
|
256
256
|
children: "Check every (seconds)"
|
|
257
|
-
}), /* @__PURE__ */
|
|
257
|
+
}), /* @__PURE__ */ w("input", {
|
|
258
258
|
type: "number",
|
|
259
|
-
min:
|
|
260
|
-
max:
|
|
261
|
-
value:
|
|
262
|
-
disabled:
|
|
263
|
-
className:
|
|
259
|
+
min: B,
|
|
260
|
+
max: V,
|
|
261
|
+
value: i.checkIntervalSec,
|
|
262
|
+
disabled: t,
|
|
263
|
+
className: I,
|
|
264
264
|
onFocus: () => c(!0),
|
|
265
265
|
onChange: (e) => o((t) => ({
|
|
266
266
|
...t,
|
|
267
267
|
checkIntervalSec: Number(e.target.value) || 0
|
|
268
268
|
})),
|
|
269
269
|
onBlur: () => {
|
|
270
|
-
let t =
|
|
270
|
+
let t = K(i.checkIntervalSec, B, V);
|
|
271
271
|
t === e.checkIntervalSec ? c(!1) : l({ checkIntervalSec: t });
|
|
272
272
|
}
|
|
273
273
|
})]
|
|
274
274
|
}),
|
|
275
|
-
/* @__PURE__ */
|
|
275
|
+
/* @__PURE__ */ w("p", {
|
|
276
276
|
className: d,
|
|
277
277
|
children: "60 s suits “is the bin still out”. Every check costs one photograph and one encode, so going below about 30 s buys latency you almost never need and multiplies the cost by the number of scenes you own."
|
|
278
278
|
})
|
|
279
279
|
]
|
|
280
280
|
}),
|
|
281
|
-
/* @__PURE__ */
|
|
282
|
-
className:
|
|
281
|
+
/* @__PURE__ */ T("div", {
|
|
282
|
+
className: R,
|
|
283
283
|
children: [
|
|
284
|
-
/* @__PURE__ */
|
|
285
|
-
className:
|
|
284
|
+
/* @__PURE__ */ w("p", {
|
|
285
|
+
className: z,
|
|
286
286
|
children: "How sure it has to be"
|
|
287
287
|
}),
|
|
288
|
-
e.check.mode === "similarity" && /* @__PURE__ */
|
|
288
|
+
e.check.mode === "similarity" && /* @__PURE__ */ T(E, { children: [/* @__PURE__ */ T("label", {
|
|
289
289
|
className: "flex flex-col gap-1",
|
|
290
|
-
children: [/* @__PURE__ */
|
|
291
|
-
className:
|
|
292
|
-
children: ["Match threshold — ", /* @__PURE__ */
|
|
290
|
+
children: [/* @__PURE__ */ T("span", {
|
|
291
|
+
className: L,
|
|
292
|
+
children: ["Match threshold — ", /* @__PURE__ */ w("span", {
|
|
293
293
|
className: "tabular-nums",
|
|
294
|
-
children:
|
|
294
|
+
children: i.threshold.toFixed(2)
|
|
295
295
|
})]
|
|
296
|
-
}), /* @__PURE__ */
|
|
296
|
+
}), /* @__PURE__ */ w("input", {
|
|
297
297
|
type: "range",
|
|
298
298
|
min: .3,
|
|
299
299
|
max: .99,
|
|
300
300
|
step: .01,
|
|
301
|
-
value:
|
|
302
|
-
disabled:
|
|
301
|
+
value: i.threshold,
|
|
302
|
+
disabled: t,
|
|
303
303
|
onFocus: () => c(!0),
|
|
304
304
|
onChange: (e) => o((t) => ({
|
|
305
305
|
...t,
|
|
306
306
|
threshold: Number(e.target.value)
|
|
307
307
|
})),
|
|
308
308
|
onMouseUp: () => {
|
|
309
|
-
|
|
309
|
+
i.threshold === p ? c(!1) : l({ check: u({ threshold: i.threshold }) });
|
|
310
310
|
},
|
|
311
311
|
onBlur: () => {
|
|
312
|
-
|
|
312
|
+
i.threshold === p ? c(!1) : l({ check: u({ threshold: i.threshold }) });
|
|
313
313
|
}
|
|
314
314
|
})]
|
|
315
|
-
}), /* @__PURE__ */
|
|
315
|
+
}), /* @__PURE__ */ w("p", {
|
|
316
316
|
className: "text-[10px] text-foreground-subtle",
|
|
317
317
|
children: "How closely the region still has to resemble the photograph to count as unchanged. Higher means fussier: at 0.95 a passing cloud can read as a change; at 0.60 the bin can be taken and the scene will shrug. 0.80 is a sensible start — if it cries wolf, lower it; if it misses the thing you care about, raise it."
|
|
318
318
|
})] }),
|
|
319
|
-
/* @__PURE__ */
|
|
319
|
+
/* @__PURE__ */ T("label", {
|
|
320
320
|
className: "flex flex-col gap-1",
|
|
321
|
-
children: [/* @__PURE__ */
|
|
322
|
-
className:
|
|
321
|
+
children: [/* @__PURE__ */ w("span", {
|
|
322
|
+
className: L,
|
|
323
323
|
children: "Agreeing checks before it changes its mind"
|
|
324
|
-
}), /* @__PURE__ */
|
|
324
|
+
}), /* @__PURE__ */ w("input", {
|
|
325
325
|
type: "number",
|
|
326
326
|
min: 1,
|
|
327
327
|
max: 10,
|
|
328
|
-
value:
|
|
329
|
-
disabled:
|
|
330
|
-
className:
|
|
328
|
+
value: i.hysteresisCount,
|
|
329
|
+
disabled: t,
|
|
330
|
+
className: I,
|
|
331
331
|
onFocus: () => c(!0),
|
|
332
332
|
onChange: (e) => o((t) => ({
|
|
333
333
|
...t,
|
|
334
334
|
hysteresisCount: Number(e.target.value) || 1
|
|
335
335
|
})),
|
|
336
336
|
onBlur: () => {
|
|
337
|
-
let t =
|
|
337
|
+
let t = K(i.hysteresisCount, 1, 10);
|
|
338
338
|
t === e.check.hysteresisCount ? c(!1) : l({ check: u({ hysteresisCount: t }) });
|
|
339
339
|
}
|
|
340
340
|
})]
|
|
341
341
|
}),
|
|
342
|
-
/* @__PURE__ */
|
|
342
|
+
/* @__PURE__ */ w("p", {
|
|
343
343
|
className: d,
|
|
344
344
|
children: "One bad photograph must never be able to flip a scene. 3 agreeing checks at 60 s is about four minutes of latency and is what makes the answer trustworthy — leaving a state costs exactly the same as entering one."
|
|
345
345
|
}),
|
|
346
|
-
/* @__PURE__ */
|
|
346
|
+
/* @__PURE__ */ T("label", {
|
|
347
347
|
className: "flex flex-col gap-1",
|
|
348
|
-
children: [/* @__PURE__ */
|
|
349
|
-
className:
|
|
348
|
+
children: [/* @__PURE__ */ w("span", {
|
|
349
|
+
className: L,
|
|
350
350
|
children: "Quiet for (seconds) before a check counts"
|
|
351
|
-
}), /* @__PURE__ */
|
|
351
|
+
}), /* @__PURE__ */ w("input", {
|
|
352
352
|
type: "number",
|
|
353
353
|
min: 0,
|
|
354
354
|
max: 3600,
|
|
355
|
-
value:
|
|
356
|
-
disabled:
|
|
357
|
-
className:
|
|
355
|
+
value: i.quietSeconds,
|
|
356
|
+
disabled: t,
|
|
357
|
+
className: I,
|
|
358
358
|
onFocus: () => c(!0),
|
|
359
359
|
onChange: (e) => o((t) => ({
|
|
360
360
|
...t,
|
|
361
361
|
quietSeconds: Number(e.target.value) || 0
|
|
362
362
|
})),
|
|
363
363
|
onBlur: () => {
|
|
364
|
-
let t =
|
|
364
|
+
let t = K(i.quietSeconds, 0, 3600);
|
|
365
365
|
t === e.quietSeconds ? c(!1) : l({ quietSeconds: t });
|
|
366
366
|
}
|
|
367
367
|
})]
|
|
368
368
|
}),
|
|
369
|
-
/* @__PURE__ */
|
|
369
|
+
/* @__PURE__ */ w("p", {
|
|
370
370
|
className: d,
|
|
371
371
|
children: "A check taken while something is moving is a photograph of the van parked in front of the bin, so it is discarded rather than merely delayed. 0 disables the gate."
|
|
372
372
|
}),
|
|
373
|
-
/* @__PURE__ */
|
|
373
|
+
/* @__PURE__ */ T("label", {
|
|
374
374
|
className: "flex flex-col gap-1",
|
|
375
|
-
children: [/* @__PURE__ */
|
|
376
|
-
className:
|
|
375
|
+
children: [/* @__PURE__ */ w("span", {
|
|
376
|
+
className: L,
|
|
377
377
|
children: "Minimum gap between counted checks (seconds)"
|
|
378
|
-
}), /* @__PURE__ */
|
|
378
|
+
}), /* @__PURE__ */ w("input", {
|
|
379
379
|
type: "number",
|
|
380
380
|
min: 0,
|
|
381
381
|
max: 3600,
|
|
382
|
-
value:
|
|
383
|
-
disabled:
|
|
384
|
-
className:
|
|
382
|
+
value: i.minObservationSpacingSec,
|
|
383
|
+
disabled: t,
|
|
384
|
+
className: I,
|
|
385
385
|
onFocus: () => c(!0),
|
|
386
386
|
onChange: (e) => o((t) => ({
|
|
387
387
|
...t,
|
|
388
388
|
minObservationSpacingSec: Number(e.target.value) || 0
|
|
389
389
|
})),
|
|
390
390
|
onBlur: () => {
|
|
391
|
-
let t =
|
|
391
|
+
let t = K(i.minObservationSpacingSec, 0, 3600);
|
|
392
392
|
t === e.minObservationSpacingSec ? c(!1) : l({ minObservationSpacingSec: t });
|
|
393
393
|
}
|
|
394
394
|
})]
|
|
395
395
|
}),
|
|
396
|
-
/* @__PURE__ */
|
|
396
|
+
/* @__PURE__ */ w("p", {
|
|
397
397
|
className: d,
|
|
398
398
|
children: "Spreads the agreeing checks over real time instead of letting three adjacent polls inside one long occlusion be mistaken for three independent opinions."
|
|
399
399
|
})
|
|
400
400
|
]
|
|
401
401
|
}),
|
|
402
|
-
/* @__PURE__ */
|
|
403
|
-
className:
|
|
402
|
+
/* @__PURE__ */ T("div", {
|
|
403
|
+
className: R,
|
|
404
404
|
children: [
|
|
405
|
-
/* @__PURE__ */
|
|
406
|
-
className:
|
|
405
|
+
/* @__PURE__ */ w("p", {
|
|
406
|
+
className: z,
|
|
407
407
|
children: "Lighting"
|
|
408
408
|
}),
|
|
409
|
-
/* @__PURE__ */
|
|
409
|
+
/* @__PURE__ */ T("label", {
|
|
410
410
|
className: "flex flex-col gap-1",
|
|
411
|
-
children: [/* @__PURE__ */
|
|
412
|
-
className:
|
|
411
|
+
children: [/* @__PURE__ */ w("span", {
|
|
412
|
+
className: L,
|
|
413
413
|
children: "When a light has no reference of its own"
|
|
414
|
-
}), /* @__PURE__ */
|
|
414
|
+
}), /* @__PURE__ */ T("select", {
|
|
415
415
|
value: e.onUncoveredCondition,
|
|
416
|
-
disabled:
|
|
417
|
-
className:
|
|
416
|
+
disabled: t,
|
|
417
|
+
className: I,
|
|
418
418
|
onChange: (e) => {
|
|
419
419
|
let t = e.target.value;
|
|
420
420
|
(t === "skip" || t === "judge-anyway") && l({ onUncoveredCondition: t });
|
|
421
421
|
},
|
|
422
|
-
children: [/* @__PURE__ */
|
|
422
|
+
children: [/* @__PURE__ */ w("option", {
|
|
423
423
|
value: "skip",
|
|
424
424
|
children: "Skip the check (recommended)"
|
|
425
|
-
}), /* @__PURE__ */
|
|
425
|
+
}), /* @__PURE__ */ w("option", {
|
|
426
426
|
value: "judge-anyway",
|
|
427
427
|
children: "Judge against the other light anyway"
|
|
428
428
|
})]
|
|
429
429
|
})]
|
|
430
430
|
}),
|
|
431
|
-
/* @__PURE__ */
|
|
431
|
+
/* @__PURE__ */ w("p", {
|
|
432
432
|
className: d,
|
|
433
|
-
children:
|
|
433
|
+
children: U[e.onUncoveredCondition]
|
|
434
434
|
})
|
|
435
435
|
]
|
|
436
436
|
}),
|
|
437
|
-
/* @__PURE__ */
|
|
438
|
-
className:
|
|
437
|
+
/* @__PURE__ */ T("div", {
|
|
438
|
+
className: R,
|
|
439
439
|
children: [
|
|
440
|
-
/* @__PURE__ */
|
|
441
|
-
className:
|
|
440
|
+
/* @__PURE__ */ w("p", {
|
|
441
|
+
className: z,
|
|
442
442
|
children: "What you get told"
|
|
443
443
|
}),
|
|
444
|
-
/* @__PURE__ */
|
|
444
|
+
/* @__PURE__ */ T("label", {
|
|
445
445
|
className: "flex flex-col gap-1",
|
|
446
|
-
children: [/* @__PURE__ */
|
|
447
|
-
className:
|
|
446
|
+
children: [/* @__PURE__ */ w("span", {
|
|
447
|
+
className: L,
|
|
448
448
|
children: "Notifications follow"
|
|
449
|
-
}), /* @__PURE__ */
|
|
449
|
+
}), /* @__PURE__ */ T("select", {
|
|
450
450
|
value: e.emit,
|
|
451
|
-
disabled:
|
|
452
|
-
className:
|
|
451
|
+
disabled: t,
|
|
452
|
+
className: I,
|
|
453
453
|
onChange: (e) => {
|
|
454
454
|
let t = e.target.value;
|
|
455
455
|
(t === "latched" || t === "live") && l({ emit: t });
|
|
456
456
|
},
|
|
457
|
-
children: [/* @__PURE__ */
|
|
457
|
+
children: [/* @__PURE__ */ w("option", {
|
|
458
458
|
value: "latched",
|
|
459
459
|
children: "The flag — told once, still visible at breakfast"
|
|
460
|
-
}), /* @__PURE__ */
|
|
460
|
+
}), /* @__PURE__ */ w("option", {
|
|
461
461
|
value: "live",
|
|
462
462
|
children: "The live state — follows the region as it changes"
|
|
463
463
|
})]
|
|
464
464
|
})]
|
|
465
465
|
}),
|
|
466
|
-
/* @__PURE__ */
|
|
466
|
+
/* @__PURE__ */ w("p", {
|
|
467
467
|
className: d,
|
|
468
468
|
children: "“Is the bin gone” is a flag: you want to be told once and still see it later. “Is the gate open” is a live state."
|
|
469
469
|
}),
|
|
470
|
-
/* @__PURE__ */
|
|
470
|
+
/* @__PURE__ */ T("label", {
|
|
471
471
|
className: "flex items-center gap-2",
|
|
472
|
-
children: [/* @__PURE__ */
|
|
472
|
+
children: [/* @__PURE__ */ w("input", {
|
|
473
473
|
type: "checkbox",
|
|
474
474
|
checked: e.autoRestore,
|
|
475
|
-
disabled:
|
|
475
|
+
disabled: t,
|
|
476
476
|
onChange: (e) => l({ autoRestore: e.target.checked })
|
|
477
|
-
}), /* @__PURE__ */
|
|
478
|
-
className:
|
|
477
|
+
}), /* @__PURE__ */ w("span", {
|
|
478
|
+
className: L,
|
|
479
479
|
children: "Clear the flag by itself when things look normal again"
|
|
480
480
|
})]
|
|
481
481
|
}),
|
|
482
|
-
/* @__PURE__ */
|
|
482
|
+
/* @__PURE__ */ w("p", {
|
|
483
483
|
className: d,
|
|
484
484
|
children: "Off by default, so an alarm never silently clears itself. The “back to normal” moment is recorded either way, so an automation can still react to it."
|
|
485
485
|
})
|
|
486
486
|
]
|
|
487
487
|
}),
|
|
488
|
-
/* @__PURE__ */
|
|
489
|
-
className:
|
|
488
|
+
/* @__PURE__ */ T("div", {
|
|
489
|
+
className: R,
|
|
490
490
|
children: [
|
|
491
|
-
/* @__PURE__ */
|
|
492
|
-
className:
|
|
491
|
+
/* @__PURE__ */ w("p", {
|
|
492
|
+
className: z,
|
|
493
493
|
children: "AI double-check"
|
|
494
494
|
}),
|
|
495
|
-
/* @__PURE__ */
|
|
495
|
+
/* @__PURE__ */ T("label", {
|
|
496
496
|
className: "flex items-center gap-2",
|
|
497
|
-
children: [/* @__PURE__ */
|
|
497
|
+
children: [/* @__PURE__ */ w("input", {
|
|
498
498
|
type: "checkbox",
|
|
499
499
|
checked: f,
|
|
500
|
-
disabled:
|
|
500
|
+
disabled: t || i.confirmPrompt.trim().length === 0,
|
|
501
501
|
onChange: (e) => l(e.target.checked ? { confirm: {
|
|
502
|
-
...
|
|
502
|
+
...q(i.confirmPrompt.trim()),
|
|
503
503
|
enabled: !0
|
|
504
504
|
} } : { confirm: null })
|
|
505
|
-
}), /* @__PURE__ */
|
|
506
|
-
className:
|
|
505
|
+
}), /* @__PURE__ */ w("span", {
|
|
506
|
+
className: L,
|
|
507
507
|
children: "Ask a vision model before changing the answer"
|
|
508
508
|
})]
|
|
509
509
|
}),
|
|
510
|
-
/* @__PURE__ */
|
|
510
|
+
/* @__PURE__ */ T("label", {
|
|
511
511
|
className: "flex flex-col gap-1",
|
|
512
|
-
children: [/* @__PURE__ */
|
|
513
|
-
className:
|
|
512
|
+
children: [/* @__PURE__ */ w("span", {
|
|
513
|
+
className: L,
|
|
514
514
|
children: "The question to ask"
|
|
515
|
-
}), /* @__PURE__ */
|
|
515
|
+
}), /* @__PURE__ */ w("input", {
|
|
516
516
|
type: "text",
|
|
517
|
-
value:
|
|
517
|
+
value: i.confirmPrompt,
|
|
518
518
|
placeholder: "e.g. Is the wheelie bin still there?",
|
|
519
|
-
disabled:
|
|
520
|
-
className:
|
|
519
|
+
disabled: t,
|
|
520
|
+
className: I,
|
|
521
521
|
onFocus: () => c(!0),
|
|
522
522
|
onChange: (e) => o((t) => ({
|
|
523
523
|
...t,
|
|
524
524
|
confirmPrompt: e.target.value
|
|
525
525
|
})),
|
|
526
526
|
onBlur: () => {
|
|
527
|
-
let t =
|
|
527
|
+
let t = i.confirmPrompt.trim();
|
|
528
528
|
t.length > 0 && t !== e.confirm?.prompt ? l({ confirm: {
|
|
529
|
-
...
|
|
529
|
+
...q(t),
|
|
530
530
|
enabled: f
|
|
531
531
|
} }) : c(!1);
|
|
532
532
|
}
|
|
533
533
|
})]
|
|
534
534
|
}),
|
|
535
|
-
/* @__PURE__ */
|
|
535
|
+
/* @__PURE__ */ T("p", {
|
|
536
536
|
className: d,
|
|
537
537
|
children: [
|
|
538
538
|
"The model is asked ",
|
|
539
|
-
/* @__PURE__ */
|
|
539
|
+
/* @__PURE__ */ w("strong", { children: "only" }),
|
|
540
540
|
" when the region has already changed enough to flip the answer — roughly twice a week for a bin, not once a minute. It reasons about the object rather than the pixels, so rain, shadows and a repositioned bin stop counting as the thing being taken. If it cannot be reached, the change is held rather than announced."
|
|
541
541
|
]
|
|
542
542
|
})
|
|
@@ -545,10 +545,10 @@ function W({ monitor: e, disabled: n, onPatch: r }) {
|
|
|
545
545
|
]
|
|
546
546
|
});
|
|
547
547
|
}
|
|
548
|
-
function
|
|
548
|
+
function K(e, t, n) {
|
|
549
549
|
return Math.min(n, Math.max(t, e));
|
|
550
550
|
}
|
|
551
|
-
function
|
|
551
|
+
function q(e) {
|
|
552
552
|
return {
|
|
553
553
|
enabled: !1,
|
|
554
554
|
prompt: e,
|
|
@@ -559,263 +559,263 @@ function K(e) {
|
|
|
559
559
|
}
|
|
560
560
|
//#endregion
|
|
561
561
|
//#region ../ui-library/src/composites/cap-settings/SceneMonitorEditor.tsx
|
|
562
|
-
|
|
563
|
-
var
|
|
562
|
+
e();
|
|
563
|
+
var J = "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", Y = "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", te = "rounded-md border border-danger/50 bg-danger/10 px-2 py-1 text-[11px] font-medium text-danger hover:bg-danger/20 disabled:opacity-40 transition-colors", ne = {
|
|
564
564
|
alarm: "border-danger/50 bg-danger/15 text-danger",
|
|
565
565
|
ok: "border-success/50 bg-success/15 text-success",
|
|
566
566
|
unknown: "border-border bg-surface text-foreground-subtle"
|
|
567
567
|
}, re = .8, ie = 3;
|
|
568
|
-
function X({ deviceId:
|
|
569
|
-
let
|
|
570
|
-
|
|
568
|
+
function X({ deviceId: e }) {
|
|
569
|
+
let s = u(l().trpcClient, e), p = o(s?.state.sceneMonitor), S = b(e, { width: 640 }), [k, A] = n(null), [j, M] = n(!1), [N, P] = n(null), [F, I] = n(null), [L, R] = n(null), [z, B] = n(null), [V, H] = n(!1), [U, W] = n(null), [K, q] = n(""), X = r(!0);
|
|
570
|
+
a(() => (X.current = !0, () => {
|
|
571
571
|
X.current = !1;
|
|
572
572
|
}), []);
|
|
573
|
-
let Z =
|
|
574
|
-
if (
|
|
575
|
-
let e = await
|
|
573
|
+
let Z = t(async () => {
|
|
574
|
+
if (s) try {
|
|
575
|
+
let e = await s.sceneMonitor?.listScenes({});
|
|
576
576
|
if (!X.current) return;
|
|
577
|
-
e &&
|
|
577
|
+
e && A(e);
|
|
578
578
|
} catch (e) {
|
|
579
579
|
if (!X.current) return;
|
|
580
|
-
c(e) ?
|
|
580
|
+
c(e) ? M(!0) : I(e instanceof Error ? e.message : String(e));
|
|
581
581
|
}
|
|
582
|
-
}, [
|
|
583
|
-
|
|
584
|
-
|
|
582
|
+
}, [s]);
|
|
583
|
+
a(() => {
|
|
584
|
+
A(null), M(!1), I(null), Z();
|
|
585
585
|
}, [Z]);
|
|
586
|
-
let Q = p?.monitors ??
|
|
587
|
-
|
|
586
|
+
let Q = p?.monitors ?? k?.monitors ?? [], ae = Date.now(), $ = t(async (e, t) => {
|
|
587
|
+
P(e), I(null);
|
|
588
588
|
try {
|
|
589
589
|
await t(), await Z();
|
|
590
590
|
} catch (e) {
|
|
591
|
-
X.current &&
|
|
591
|
+
X.current && I(e instanceof Error ? e.message : String(e));
|
|
592
592
|
} finally {
|
|
593
|
-
X.current &&
|
|
593
|
+
X.current && P(null);
|
|
594
594
|
}
|
|
595
|
-
}, [Z]), oe =
|
|
595
|
+
}, [Z]), oe = i(() => {
|
|
596
596
|
let e = Q.map((e) => ({
|
|
597
597
|
id: e.id,
|
|
598
598
|
shape: e.roi,
|
|
599
599
|
label: e.label,
|
|
600
600
|
enabled: e.enabled
|
|
601
601
|
}));
|
|
602
|
-
return
|
|
602
|
+
return U === null ? e : [...e, {
|
|
603
603
|
id: "__draft__",
|
|
604
|
-
shape:
|
|
604
|
+
shape: U,
|
|
605
605
|
label: "New scene"
|
|
606
606
|
}];
|
|
607
|
-
}, [Q,
|
|
607
|
+
}, [Q, U]), se = t((e, t) => {
|
|
608
608
|
if (t.kind === "rect") {
|
|
609
609
|
if (e === "__draft__") {
|
|
610
|
-
|
|
610
|
+
W(t);
|
|
611
611
|
return;
|
|
612
612
|
}
|
|
613
|
-
$(`roi-${String(e)}`, async () =>
|
|
613
|
+
$(`roi-${String(e)}`, async () => s?.sceneMonitor?.updateScene({
|
|
614
614
|
monitorId: String(e),
|
|
615
615
|
patch: { roi: t }
|
|
616
616
|
}));
|
|
617
617
|
}
|
|
618
|
-
}, [
|
|
619
|
-
e.kind === "rect" &&
|
|
620
|
-
}, []), le =
|
|
621
|
-
|
|
622
|
-
await
|
|
623
|
-
label:
|
|
624
|
-
roi:
|
|
618
|
+
}, [s, $]), ce = t((e) => {
|
|
619
|
+
e.kind === "rect" && W(e);
|
|
620
|
+
}, []), le = t(async () => {
|
|
621
|
+
U === null || K.trim().length === 0 || (await $("create", async () => {
|
|
622
|
+
await s?.sceneMonitor?.createScene({
|
|
623
|
+
label: K.trim(),
|
|
624
|
+
roi: U,
|
|
625
625
|
check: {
|
|
626
626
|
mode: "similarity",
|
|
627
627
|
threshold: re,
|
|
628
628
|
hysteresisCount: ie
|
|
629
629
|
}
|
|
630
630
|
});
|
|
631
|
-
}),
|
|
631
|
+
}), W(null), q(""), H(!1));
|
|
632
632
|
}, [
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
633
|
+
s,
|
|
634
|
+
U,
|
|
635
|
+
K,
|
|
636
636
|
$
|
|
637
637
|
]);
|
|
638
|
-
return
|
|
638
|
+
return s ? /* @__PURE__ */ w("div", {
|
|
639
639
|
className: "flex flex-col gap-3",
|
|
640
|
-
children:
|
|
640
|
+
children: j ? /* @__PURE__ */ w("p", {
|
|
641
641
|
className: `${d} leading-relaxed`,
|
|
642
642
|
children: "Scene monitoring is not available for this camera."
|
|
643
|
-
}) : /* @__PURE__ */
|
|
644
|
-
/* @__PURE__ */
|
|
643
|
+
}) : /* @__PURE__ */ T(E, { children: [
|
|
644
|
+
/* @__PURE__ */ w("p", {
|
|
645
645
|
className: `${d} leading-relaxed`,
|
|
646
646
|
children: "A scene watches one region of this camera and tells you when it stops looking like the picture you captured. Draw a box around the thing you care about — a wheelie bin, a gate, a parking space — then capture what “normal” looks like. Daylight is enough to start: the night reference is optional, and without it the scene simply sits the infrared hours out instead of reporting a problem."
|
|
647
647
|
}),
|
|
648
|
-
/* @__PURE__ */
|
|
648
|
+
/* @__PURE__ */ w("div", {
|
|
649
649
|
className: "relative overflow-hidden rounded-md border border-border",
|
|
650
|
-
children: /* @__PURE__ */
|
|
650
|
+
children: /* @__PURE__ */ w(D, {
|
|
651
651
|
items: oe,
|
|
652
652
|
supportedShapes: ["rect"],
|
|
653
|
-
selectedId:
|
|
654
|
-
onSelect: (e) =>
|
|
653
|
+
selectedId: L ?? (U === null ? null : "__draft__"),
|
|
654
|
+
onSelect: (e) => R(e === null ? null : String(e)),
|
|
655
655
|
onShapeChange: se,
|
|
656
656
|
onDrawComplete: ce,
|
|
657
|
-
drawingKind:
|
|
658
|
-
backdrop:
|
|
659
|
-
src:
|
|
657
|
+
drawingKind: V && U === null ? "rect" : null,
|
|
658
|
+
backdrop: S.src === null ? null : /* @__PURE__ */ w("img", {
|
|
659
|
+
src: S.src,
|
|
660
660
|
alt: "",
|
|
661
661
|
className: "h-full w-full object-contain",
|
|
662
662
|
draggable: !1
|
|
663
663
|
})
|
|
664
664
|
})
|
|
665
665
|
}),
|
|
666
|
-
/* @__PURE__ */
|
|
666
|
+
/* @__PURE__ */ T("div", {
|
|
667
667
|
className: "flex flex-wrap items-center gap-2",
|
|
668
|
-
children: [/* @__PURE__ */
|
|
668
|
+
children: [/* @__PURE__ */ w("button", {
|
|
669
669
|
type: "button",
|
|
670
|
-
className:
|
|
671
|
-
"aria-pressed":
|
|
670
|
+
className: V ? Y : J,
|
|
671
|
+
"aria-pressed": V,
|
|
672
672
|
onClick: () => {
|
|
673
|
-
|
|
673
|
+
H((e) => !e), W(null);
|
|
674
674
|
},
|
|
675
|
-
disabled:
|
|
676
|
-
children:
|
|
677
|
-
}), /* @__PURE__ */
|
|
675
|
+
disabled: N !== null,
|
|
676
|
+
children: V ? "Cancel" : "+ New scene"
|
|
677
|
+
}), /* @__PURE__ */ w("button", {
|
|
678
678
|
type: "button",
|
|
679
|
-
className:
|
|
680
|
-
onClick:
|
|
681
|
-
disabled:
|
|
679
|
+
className: J,
|
|
680
|
+
onClick: S.refresh,
|
|
681
|
+
disabled: N !== null,
|
|
682
682
|
children: "Refresh frame"
|
|
683
683
|
})]
|
|
684
684
|
}),
|
|
685
|
-
|
|
685
|
+
V && /* @__PURE__ */ T("div", {
|
|
686
686
|
className: "flex flex-col gap-2 rounded-md border border-border bg-surface p-2",
|
|
687
687
|
children: [
|
|
688
|
-
/* @__PURE__ */
|
|
688
|
+
/* @__PURE__ */ w("p", {
|
|
689
689
|
className: "text-[10px] text-foreground-subtle",
|
|
690
|
-
children:
|
|
690
|
+
children: U === null ? "Click on the frame to drop a box, then drag its corner to fit it around the thing you want watched." : "Name it, then create. You capture what “normal” looks like next."
|
|
691
691
|
}),
|
|
692
|
-
|
|
692
|
+
U !== null && h(U) && /* @__PURE__ */ w("p", {
|
|
693
693
|
className: "text-[11px] leading-relaxed text-warning",
|
|
694
694
|
children: "That box covers most of the frame. A scene that big is dominated by the weather, the sky and passing cars — it will quietly stop noticing the thing you actually care about. Draw it tighter."
|
|
695
695
|
}),
|
|
696
|
-
/* @__PURE__ */
|
|
696
|
+
/* @__PURE__ */ T("div", {
|
|
697
697
|
className: "flex items-center gap-2",
|
|
698
|
-
children: [/* @__PURE__ */
|
|
698
|
+
children: [/* @__PURE__ */ w("input", {
|
|
699
699
|
type: "text",
|
|
700
|
-
value:
|
|
701
|
-
onChange: (e) =>
|
|
700
|
+
value: K,
|
|
701
|
+
onChange: (e) => q(e.target.value),
|
|
702
702
|
placeholder: "e.g. Immondizia prelevata",
|
|
703
703
|
className: "flex-1 rounded-md border border-border bg-surface px-2 py-1 text-[12px] text-foreground"
|
|
704
|
-
}), /* @__PURE__ */
|
|
704
|
+
}), /* @__PURE__ */ w("button", {
|
|
705
705
|
type: "button",
|
|
706
|
-
className:
|
|
706
|
+
className: Y,
|
|
707
707
|
onClick: () => void le(),
|
|
708
|
-
disabled:
|
|
708
|
+
disabled: U === null || K.trim().length === 0 || N !== null,
|
|
709
709
|
children: "Create"
|
|
710
710
|
})]
|
|
711
711
|
})
|
|
712
712
|
]
|
|
713
713
|
}),
|
|
714
|
-
|
|
714
|
+
F !== null && /* @__PURE__ */ w("p", {
|
|
715
715
|
className: "text-[11px] leading-relaxed text-danger",
|
|
716
|
-
children:
|
|
716
|
+
children: F
|
|
717
717
|
}),
|
|
718
|
-
Q.length === 0 ? /* @__PURE__ */
|
|
718
|
+
Q.length === 0 ? /* @__PURE__ */ w("p", {
|
|
719
719
|
className: `${d} leading-relaxed`,
|
|
720
720
|
children: "No scenes on this camera yet."
|
|
721
|
-
}) : /* @__PURE__ */
|
|
721
|
+
}) : /* @__PURE__ */ w("ul", {
|
|
722
722
|
className: "flex flex-col gap-2",
|
|
723
723
|
children: Q.map((e) => {
|
|
724
|
-
let t =
|
|
725
|
-
return /* @__PURE__ */
|
|
726
|
-
className: `flex flex-col gap-1.5 rounded-md border p-2 ${
|
|
724
|
+
let t = _(e);
|
|
725
|
+
return /* @__PURE__ */ T("li", {
|
|
726
|
+
className: `flex flex-col gap-1.5 rounded-md border p-2 ${L === e.id ? "border-primary/50" : "border-border"}`,
|
|
727
727
|
children: [
|
|
728
|
-
/* @__PURE__ */
|
|
728
|
+
/* @__PURE__ */ T("div", {
|
|
729
729
|
className: "flex items-center gap-2",
|
|
730
|
-
children: [/* @__PURE__ */
|
|
730
|
+
children: [/* @__PURE__ */ w("button", {
|
|
731
731
|
type: "button",
|
|
732
732
|
className: "flex-1 text-left text-[12px] font-medium text-foreground",
|
|
733
|
-
onClick: () =>
|
|
733
|
+
onClick: () => R(e.id),
|
|
734
734
|
children: e.label
|
|
735
|
-
}), /* @__PURE__ */
|
|
735
|
+
}), /* @__PURE__ */ w("span", {
|
|
736
736
|
className: `rounded border px-1.5 py-0.5 text-[10px] font-medium ${ne[t.tone]}`,
|
|
737
737
|
children: t.text
|
|
738
738
|
})]
|
|
739
739
|
}),
|
|
740
|
-
/* @__PURE__ */
|
|
740
|
+
/* @__PURE__ */ w("p", {
|
|
741
741
|
className: `${d} leading-relaxed`,
|
|
742
742
|
children: f(e, ae)
|
|
743
743
|
}),
|
|
744
|
-
/* @__PURE__ */
|
|
744
|
+
/* @__PURE__ */ w("p", {
|
|
745
745
|
className: `${d} tabular-nums`,
|
|
746
|
-
children:
|
|
746
|
+
children: y(e)
|
|
747
747
|
}),
|
|
748
|
-
/* @__PURE__ */
|
|
748
|
+
/* @__PURE__ */ w(ee, {
|
|
749
749
|
monitor: e,
|
|
750
|
-
disabled:
|
|
751
|
-
onDelete: ({ stateId: t, index: n }) => void $(`refdel-${e.id}-${t}-${String(n)}`, async () =>
|
|
750
|
+
disabled: N !== null,
|
|
751
|
+
onDelete: ({ stateId: t, index: n }) => void $(`refdel-${e.id}-${t}-${String(n)}`, async () => s.sceneMonitor?.deleteReference({
|
|
752
752
|
monitorId: e.id,
|
|
753
753
|
stateId: t,
|
|
754
754
|
index: n
|
|
755
755
|
}))
|
|
756
756
|
}),
|
|
757
|
-
/* @__PURE__ */
|
|
757
|
+
/* @__PURE__ */ T("div", {
|
|
758
758
|
className: "flex flex-wrap items-center gap-1.5",
|
|
759
759
|
children: [
|
|
760
|
-
|
|
760
|
+
x.map((t) => {
|
|
761
761
|
let n = t === "ir";
|
|
762
|
-
return /* @__PURE__ */
|
|
762
|
+
return /* @__PURE__ */ T("button", {
|
|
763
763
|
type: "button",
|
|
764
|
-
className:
|
|
765
|
-
disabled:
|
|
766
|
-
title: n ? "Optional. Without a night reference the checks in infrared are simply skipped — the scene keeps working in daylight and nothing is reported as broken." : `Take a fresh photo now and store it as the ${
|
|
767
|
-
onClick: () => void $(`cap-${e.id}-${t}`, async () =>
|
|
764
|
+
className: J,
|
|
765
|
+
disabled: N !== null,
|
|
766
|
+
title: n ? "Optional. Without a night reference the checks in infrared are simply skipped — the scene keeps working in daylight and nothing is reported as broken." : `Take a fresh photo now and store it as the ${v(t).toLowerCase()} reference`,
|
|
767
|
+
onClick: () => void $(`cap-${e.id}-${t}`, async () => s.sceneMonitor?.captureReference({
|
|
768
768
|
monitorId: e.id,
|
|
769
769
|
condition: t
|
|
770
770
|
})),
|
|
771
771
|
children: [
|
|
772
|
-
/* @__PURE__ */
|
|
772
|
+
/* @__PURE__ */ w(m, { className: "mr-1 inline h-3 w-3" }),
|
|
773
773
|
"Capture ",
|
|
774
|
-
|
|
775
|
-
n && /* @__PURE__ */
|
|
774
|
+
v(t).toLowerCase(),
|
|
775
|
+
n && /* @__PURE__ */ w("span", {
|
|
776
776
|
className: "ml-1 text-foreground-subtle/70",
|
|
777
777
|
children: "(optional)"
|
|
778
778
|
})
|
|
779
779
|
]
|
|
780
780
|
}, t);
|
|
781
781
|
}),
|
|
782
|
-
/* @__PURE__ */
|
|
782
|
+
/* @__PURE__ */ T("button", {
|
|
783
783
|
type: "button",
|
|
784
|
-
className:
|
|
785
|
-
disabled:
|
|
784
|
+
className: Y,
|
|
785
|
+
disabled: N !== null || e.states.length === 0,
|
|
786
786
|
title: "Clear the flag and re-photograph what normal looks like right now",
|
|
787
|
-
onClick: () => void $(`reset-${e.id}`, async () =>
|
|
788
|
-
children: [/* @__PURE__ */
|
|
787
|
+
onClick: () => void $(`reset-${e.id}`, async () => s.sceneMonitor?.resetScene({ monitorId: e.id })),
|
|
788
|
+
children: [/* @__PURE__ */ w(g, { className: "mr-1 inline h-3 w-3" }), "Reset"]
|
|
789
789
|
}),
|
|
790
|
-
/* @__PURE__ */
|
|
790
|
+
/* @__PURE__ */ w("button", {
|
|
791
791
|
type: "button",
|
|
792
|
-
className:
|
|
793
|
-
disabled:
|
|
794
|
-
onClick: () => void $(`check-${e.id}`, async () =>
|
|
792
|
+
className: J,
|
|
793
|
+
disabled: N !== null,
|
|
794
|
+
onClick: () => void $(`check-${e.id}`, async () => s.sceneMonitor?.recheckNow({ monitorId: e.id })),
|
|
795
795
|
children: "Check now"
|
|
796
796
|
}),
|
|
797
|
-
/* @__PURE__ */
|
|
797
|
+
/* @__PURE__ */ T("button", {
|
|
798
798
|
type: "button",
|
|
799
|
-
className:
|
|
800
|
-
"aria-pressed":
|
|
799
|
+
className: z === e.id ? Y : J,
|
|
800
|
+
"aria-pressed": z === e.id,
|
|
801
801
|
"aria-label": `Settings for ${e.label}`,
|
|
802
|
-
disabled:
|
|
803
|
-
onClick: () =>
|
|
804
|
-
children: [/* @__PURE__ */
|
|
802
|
+
disabled: N !== null,
|
|
803
|
+
onClick: () => B((t) => t === e.id ? null : e.id),
|
|
804
|
+
children: [/* @__PURE__ */ w(O, { className: "mr-1 inline h-3 w-3" }), "Settings"]
|
|
805
805
|
}),
|
|
806
|
-
/* @__PURE__ */
|
|
806
|
+
/* @__PURE__ */ w("button", {
|
|
807
807
|
type: "button",
|
|
808
|
-
className:
|
|
809
|
-
disabled:
|
|
810
|
-
onClick: () => void $(`del-${e.id}`, async () =>
|
|
811
|
-
children: /* @__PURE__ */ C
|
|
808
|
+
className: te,
|
|
809
|
+
disabled: N !== null,
|
|
810
|
+
onClick: () => void $(`del-${e.id}`, async () => s.sceneMonitor?.deleteScene({ monitorId: e.id })),
|
|
811
|
+
children: /* @__PURE__ */ w(C, { className: "h-3 w-3" })
|
|
812
812
|
})
|
|
813
813
|
]
|
|
814
814
|
}),
|
|
815
|
-
|
|
815
|
+
z === e.id && /* @__PURE__ */ w(G, {
|
|
816
816
|
monitor: e,
|
|
817
|
-
disabled:
|
|
818
|
-
onPatch: (t) => void $(`tune-${e.id}`, async () =>
|
|
817
|
+
disabled: N !== null,
|
|
818
|
+
onPatch: (t) => void $(`tune-${e.id}`, async () => s.sceneMonitor?.updateScene({
|
|
819
819
|
monitorId: e.id,
|
|
820
820
|
patch: t
|
|
821
821
|
}))
|