@camstack/addon-model-studio 1.1.127 → 1.1.129
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/{MotionZonesSettings-Y4BOcwCT.mjs → MotionZonesSettings-C0ZZHN5q.mjs} +2 -2
- package/dist/{PrivacyMaskSettings-D0dMH34n.mjs → PrivacyMaskSettings-D4uGl7zT.mjs} +4 -4
- package/dist/{SceneMonitorEditor-iS9jtSJq.mjs → SceneMonitorEditor-BKYzMLFb.mjs} +258 -255
- package/dist/_stub.js +10 -10
- package/dist/{_virtual_mf-localSharedImportMap___mfe_internal__addon_model_studio_page-DSeCEWSZ.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_model_studio_page-CS5tkis3.mjs} +4 -4
- package/dist/_virtual_mf___mfe_internal__addon_model_studio_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-CXCz80XV.mjs +26 -0
- package/dist/{hostInit-B4e4wL55.mjs → hostInit-BtQKjmWv.mjs} +3 -3
- package/dist/model-studio.addon.js +131 -50
- package/dist/model-studio.addon.mjs +131 -50
- package/dist/{player-overlays-q0vtmqkn.mjs → player-overlays-CMrYqFCL.mjs} +1 -1
- package/dist/remoteEntry.js +1 -1
- package/dist/{responsive-DNXbYsNH.mjs → responsive-JVBuLbSa.mjs} +3 -3
- package/dist/{square-CvCVejCK.mjs → square-BCP4gOno.mjs} +1 -1
- package/dist/{trash-2-pcumgheo.mjs → trash-2-CeqN21XB.mjs} +1 -1
- package/dist/{use-device-snapshot-BKYQa7fa.mjs → use-device-snapshot-UOdeTQpP.mjs} +1 -1
- package/dist/{virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_model_studio_page__remoteEntry_js-CAO6nU0H.mjs → virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_model_studio_page__remoteEntry_js-C_r2F6t8.mjs} +1 -1
- package/package.json +1 -1
- package/dist/_virtual_mf___mfe_internal__addon_model_studio_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-CO-CV0SJ.mjs +0 -26
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { c as e, h as t, m as n, p as r, u as i, y as a } from "./_virtual_mf___mfe_internal__addon_model_studio_page__loadShare__react__loadShare__.js-DJDHChgO.mjs";
|
|
2
|
-
import { a as o, i as s, n as c, r as l, s as u, t as d } from "./responsive-
|
|
3
|
-
import { a as f, c as p, d as ee, i as m, l as
|
|
4
|
-
import { t as
|
|
5
|
-
import { n as
|
|
6
|
-
import { MaskShapeCanvas as
|
|
7
|
-
var
|
|
2
|
+
import { a as o, i as s, n as c, r as l, s as u, t as d } from "./responsive-JVBuLbSa.mjs";
|
|
3
|
+
import { a as f, c as p, d as ee, i as m, l as h, n as g, o as _, r as v, s as y, t as b, u as x } from "./use-device-snapshot-UOdeTQpP.mjs";
|
|
4
|
+
import { t as S } from "./trash-2-CeqN21XB.mjs";
|
|
5
|
+
import { n as C, r as w, t as T } from "./_virtual_mf___mfe_internal__addon_model_studio_page__loadShare__react_mf_1_jsx_mf_2_runtime__loadShare__.js-ds_Ehzaa.mjs";
|
|
6
|
+
import { MaskShapeCanvas as E } from "./MaskShapeCanvas-C4g96eMz.mjs";
|
|
7
|
+
var D = u("settings-2", [
|
|
8
8
|
["path", {
|
|
9
9
|
d: "M14 17H5",
|
|
10
10
|
key: "gfn3mx"
|
|
@@ -29,8 +29,11 @@ var ie = u("settings-2", [
|
|
|
29
29
|
//#endregion
|
|
30
30
|
//#region ../ui-library/src/composites/cap-settings/SceneReferenceGallery.tsx
|
|
31
31
|
a();
|
|
32
|
-
var
|
|
33
|
-
function
|
|
32
|
+
var O = p("/addon/pipeline-analytics/event-media");
|
|
33
|
+
function k(e) {
|
|
34
|
+
return `${O}/m/${e}`;
|
|
35
|
+
}
|
|
36
|
+
function A(e) {
|
|
34
37
|
let t = /* @__PURE__ */ new Map();
|
|
35
38
|
for (let n of e.states) n.references.forEach((e, r) => {
|
|
36
39
|
let i = t.get(e.condition) ?? [];
|
|
@@ -45,43 +48,43 @@ function T(e) {
|
|
|
45
48
|
tiles: [...t].sort((e, t) => t.reference.capturedAt - e.reference.capturedAt)
|
|
46
49
|
})).sort((e, t) => e.condition.localeCompare(t.condition));
|
|
47
50
|
}
|
|
48
|
-
function
|
|
51
|
+
function j(e) {
|
|
49
52
|
return e.states.reduce((e, t) => e + t.references.length, 0);
|
|
50
53
|
}
|
|
51
|
-
var
|
|
52
|
-
function
|
|
53
|
-
let i =
|
|
54
|
-
return i.length === 0 ? /* @__PURE__ */
|
|
54
|
+
var M = "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 te({ monitor: e, disabled: n, onDelete: r }) {
|
|
56
|
+
let i = A(e), a = j(e), [o, s] = t(null);
|
|
57
|
+
return i.length === 0 ? /* @__PURE__ */ C("p", {
|
|
55
58
|
className: `${d} leading-relaxed`,
|
|
56
59
|
children: "No photographs captured yet. Press “Capture daylight” to take the one this scene will judge everything against."
|
|
57
|
-
}) : /* @__PURE__ */
|
|
60
|
+
}) : /* @__PURE__ */ C("div", {
|
|
58
61
|
className: "flex flex-col gap-2",
|
|
59
|
-
children: i.map((e) => /* @__PURE__ */
|
|
62
|
+
children: i.map((e) => /* @__PURE__ */ w("div", {
|
|
60
63
|
className: "flex flex-col gap-1",
|
|
61
|
-
children: [/* @__PURE__ */
|
|
64
|
+
children: [/* @__PURE__ */ w("p", {
|
|
62
65
|
className: "text-[10px] font-semibold uppercase tracking-wide text-foreground-subtle",
|
|
63
66
|
children: [
|
|
64
|
-
|
|
67
|
+
y(e.condition),
|
|
65
68
|
" · ",
|
|
66
69
|
e.tiles.length
|
|
67
70
|
]
|
|
68
|
-
}), /* @__PURE__ */
|
|
71
|
+
}), /* @__PURE__ */ C("ul", {
|
|
69
72
|
className: "flex flex-wrap gap-1.5",
|
|
70
73
|
children: e.tiles.map((t) => {
|
|
71
74
|
let i = `${t.stateId}:${String(t.index)}`, c = a === 1, l = o === i;
|
|
72
|
-
return /* @__PURE__ */
|
|
75
|
+
return /* @__PURE__ */ w("li", {
|
|
73
76
|
className: "flex w-24 flex-col gap-1 rounded-md border border-border p-1",
|
|
74
77
|
children: [
|
|
75
|
-
/* @__PURE__ */
|
|
76
|
-
/* @__PURE__ */
|
|
78
|
+
/* @__PURE__ */ C(N, { reference: t.reference }),
|
|
79
|
+
/* @__PURE__ */ C("span", {
|
|
77
80
|
className: `${d} tabular-nums`,
|
|
78
|
-
children:
|
|
81
|
+
children: P(t.reference.capturedAt)
|
|
79
82
|
}),
|
|
80
|
-
/* @__PURE__ */
|
|
83
|
+
/* @__PURE__ */ w("button", {
|
|
81
84
|
type: "button",
|
|
82
|
-
className:
|
|
85
|
+
className: M,
|
|
83
86
|
disabled: n,
|
|
84
|
-
"aria-label": `Delete the ${
|
|
87
|
+
"aria-label": `Delete the ${y(e.condition).toLowerCase()} photograph from ${P(t.reference.capturedAt)}`,
|
|
85
88
|
onClick: () => {
|
|
86
89
|
if (c && !l) {
|
|
87
90
|
s(i);
|
|
@@ -92,9 +95,9 @@ function O({ monitor: e, disabled: n, onDelete: r }) {
|
|
|
92
95
|
index: t.index
|
|
93
96
|
});
|
|
94
97
|
},
|
|
95
|
-
children: [/* @__PURE__ */
|
|
98
|
+
children: [/* @__PURE__ */ C(S, { className: "mr-1 inline h-3 w-3" }), l ? "Confirm" : "Delete"]
|
|
96
99
|
}),
|
|
97
|
-
l && /* @__PURE__ */
|
|
100
|
+
l && /* @__PURE__ */ C("p", {
|
|
98
101
|
className: "text-[10px] leading-snug text-warning",
|
|
99
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."
|
|
100
103
|
})
|
|
@@ -105,24 +108,24 @@ function O({ monitor: e, disabled: n, onDelete: r }) {
|
|
|
105
108
|
}, e.condition))
|
|
106
109
|
});
|
|
107
110
|
}
|
|
108
|
-
function
|
|
111
|
+
function N({ reference: e }) {
|
|
109
112
|
let [n, r] = t(!1), i = e.thumbnailMediaId;
|
|
110
|
-
return i === void 0 || n ? /* @__PURE__ */
|
|
113
|
+
return i === void 0 || n ? /* @__PURE__ */ w("div", {
|
|
111
114
|
className: "flex h-16 w-full flex-col items-center justify-center gap-0.5 rounded bg-surface text-foreground-subtle",
|
|
112
115
|
title: "The picture for this reference is no longer stored. The reference itself is intact and still being scored against.",
|
|
113
|
-
children: [/* @__PURE__ */
|
|
116
|
+
children: [/* @__PURE__ */ C(x, { className: "h-4 w-4" }), /* @__PURE__ */ C("span", {
|
|
114
117
|
className: "text-[9px]",
|
|
115
118
|
children: "no picture"
|
|
116
119
|
})]
|
|
117
|
-
}) : /* @__PURE__ */
|
|
118
|
-
src:
|
|
120
|
+
}) : /* @__PURE__ */ C("img", {
|
|
121
|
+
src: k(i),
|
|
119
122
|
alt: "",
|
|
120
123
|
loading: "lazy",
|
|
121
124
|
className: "h-16 w-full rounded object-cover",
|
|
122
125
|
onError: () => r(!0)
|
|
123
126
|
});
|
|
124
127
|
}
|
|
125
|
-
function
|
|
128
|
+
function P(e) {
|
|
126
129
|
let t = new Date(e);
|
|
127
130
|
return `${t.toLocaleDateString()} ${t.toLocaleTimeString([], {
|
|
128
131
|
hour: "2-digit",
|
|
@@ -132,15 +135,15 @@ function A(e) {
|
|
|
132
135
|
//#endregion
|
|
133
136
|
//#region ../ui-library/src/composites/cap-settings/SceneSettingsForm.tsx
|
|
134
137
|
a();
|
|
135
|
-
var
|
|
138
|
+
var F = "rounded-md border border-border bg-surface px-2 py-1 text-[11px] text-foreground focus:border-primary focus:outline-none disabled:opacity-50", I = "text-[10px] font-medium text-foreground-subtle", L = "flex flex-col gap-2 rounded-md border border-border bg-surface/40 p-2", R = "text-[10px] font-semibold uppercase tracking-wide text-foreground-subtle", z = 5, B = 3600, V = {
|
|
136
139
|
periodic: "Only on the clock. Predictable, and it notices a change even on a camera nothing ever moves in front of.",
|
|
137
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.",
|
|
138
141
|
both: "Both — the clock is the safety net that lets the motion path miss. This is the right answer for almost every scene."
|
|
139
|
-
},
|
|
142
|
+
}, H = {
|
|
140
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.",
|
|
141
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."
|
|
142
145
|
};
|
|
143
|
-
function
|
|
146
|
+
function U(e) {
|
|
144
147
|
return {
|
|
145
148
|
label: e.label,
|
|
146
149
|
checkIntervalSec: e.checkIntervalSec ?? 60,
|
|
@@ -151,10 +154,10 @@ function z(e) {
|
|
|
151
154
|
confirmPrompt: e.confirm?.prompt ?? ""
|
|
152
155
|
};
|
|
153
156
|
}
|
|
154
|
-
function
|
|
155
|
-
let [a, o] = t(() =>
|
|
157
|
+
function W({ monitor: e, disabled: n, onPatch: r }) {
|
|
158
|
+
let [a, o] = t(() => U(e)), [s, c] = t(!1);
|
|
156
159
|
i(() => {
|
|
157
|
-
s || o(
|
|
160
|
+
s || o(U(e));
|
|
158
161
|
}, [e, s]);
|
|
159
162
|
let l = (e) => {
|
|
160
163
|
c(!1), r(e);
|
|
@@ -166,26 +169,26 @@ function B({ monitor: e, disabled: n, onPatch: r }) {
|
|
|
166
169
|
...e.check,
|
|
167
170
|
hysteresisCount: t.hysteresisCount ?? e.check.hysteresisCount
|
|
168
171
|
}, f = e.confirm?.enabled === !0, p = e.check.mode === "similarity" ? e.check.threshold : null;
|
|
169
|
-
return /* @__PURE__ */
|
|
172
|
+
return /* @__PURE__ */ w("div", {
|
|
170
173
|
className: "flex flex-col gap-2",
|
|
171
174
|
children: [
|
|
172
|
-
/* @__PURE__ */
|
|
173
|
-
className:
|
|
175
|
+
/* @__PURE__ */ w("div", {
|
|
176
|
+
className: L,
|
|
174
177
|
children: [
|
|
175
|
-
/* @__PURE__ */
|
|
176
|
-
className:
|
|
178
|
+
/* @__PURE__ */ C("p", {
|
|
179
|
+
className: R,
|
|
177
180
|
children: "What it watches"
|
|
178
181
|
}),
|
|
179
|
-
/* @__PURE__ */
|
|
182
|
+
/* @__PURE__ */ w("label", {
|
|
180
183
|
className: "flex flex-col gap-1",
|
|
181
|
-
children: [/* @__PURE__ */
|
|
182
|
-
className:
|
|
184
|
+
children: [/* @__PURE__ */ C("span", {
|
|
185
|
+
className: I,
|
|
183
186
|
children: "Name"
|
|
184
|
-
}), /* @__PURE__ */
|
|
187
|
+
}), /* @__PURE__ */ C("input", {
|
|
185
188
|
type: "text",
|
|
186
189
|
value: a.label,
|
|
187
190
|
disabled: n,
|
|
188
|
-
className:
|
|
191
|
+
className: F,
|
|
189
192
|
onFocus: () => c(!0),
|
|
190
193
|
onChange: (e) => o((t) => ({
|
|
191
194
|
...t,
|
|
@@ -197,100 +200,100 @@ function B({ monitor: e, disabled: n, onPatch: r }) {
|
|
|
197
200
|
}
|
|
198
201
|
})]
|
|
199
202
|
}),
|
|
200
|
-
/* @__PURE__ */
|
|
203
|
+
/* @__PURE__ */ w("label", {
|
|
201
204
|
className: "flex items-center gap-2",
|
|
202
|
-
children: [/* @__PURE__ */
|
|
205
|
+
children: [/* @__PURE__ */ C("input", {
|
|
203
206
|
type: "checkbox",
|
|
204
207
|
checked: e.enabled,
|
|
205
208
|
disabled: n,
|
|
206
209
|
onChange: (e) => l({ enabled: e.target.checked })
|
|
207
|
-
}), /* @__PURE__ */
|
|
208
|
-
className:
|
|
210
|
+
}), /* @__PURE__ */ C("span", {
|
|
211
|
+
className: I,
|
|
209
212
|
children: "Watching"
|
|
210
213
|
})]
|
|
211
214
|
}),
|
|
212
|
-
/* @__PURE__ */
|
|
215
|
+
/* @__PURE__ */ C("p", {
|
|
213
216
|
className: d,
|
|
214
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."
|
|
215
218
|
}),
|
|
216
|
-
/* @__PURE__ */
|
|
219
|
+
/* @__PURE__ */ w("label", {
|
|
217
220
|
className: "flex flex-col gap-1",
|
|
218
|
-
children: [/* @__PURE__ */
|
|
219
|
-
className:
|
|
221
|
+
children: [/* @__PURE__ */ C("span", {
|
|
222
|
+
className: I,
|
|
220
223
|
children: "When to look"
|
|
221
|
-
}), /* @__PURE__ */
|
|
224
|
+
}), /* @__PURE__ */ w("select", {
|
|
222
225
|
value: e.triggerMode,
|
|
223
226
|
disabled: n,
|
|
224
|
-
className:
|
|
227
|
+
className: F,
|
|
225
228
|
onChange: (e) => {
|
|
226
229
|
let t = e.target.value;
|
|
227
230
|
(t === "periodic" || t === "on-motion" || t === "both") && l({ triggerMode: t });
|
|
228
231
|
},
|
|
229
232
|
children: [
|
|
230
|
-
/* @__PURE__ */
|
|
233
|
+
/* @__PURE__ */ C("option", {
|
|
231
234
|
value: "both",
|
|
232
235
|
children: "On the clock and after motion settles"
|
|
233
236
|
}),
|
|
234
|
-
/* @__PURE__ */
|
|
237
|
+
/* @__PURE__ */ C("option", {
|
|
235
238
|
value: "periodic",
|
|
236
239
|
children: "On the clock only"
|
|
237
240
|
}),
|
|
238
|
-
/* @__PURE__ */
|
|
241
|
+
/* @__PURE__ */ C("option", {
|
|
239
242
|
value: "on-motion",
|
|
240
243
|
children: "After motion settles only"
|
|
241
244
|
})
|
|
242
245
|
]
|
|
243
246
|
})]
|
|
244
247
|
}),
|
|
245
|
-
/* @__PURE__ */
|
|
248
|
+
/* @__PURE__ */ C("p", {
|
|
246
249
|
className: d,
|
|
247
|
-
children:
|
|
250
|
+
children: V[e.triggerMode]
|
|
248
251
|
}),
|
|
249
|
-
/* @__PURE__ */
|
|
252
|
+
/* @__PURE__ */ w("label", {
|
|
250
253
|
className: "flex flex-col gap-1",
|
|
251
|
-
children: [/* @__PURE__ */
|
|
252
|
-
className:
|
|
254
|
+
children: [/* @__PURE__ */ C("span", {
|
|
255
|
+
className: I,
|
|
253
256
|
children: "Check every (seconds)"
|
|
254
|
-
}), /* @__PURE__ */
|
|
257
|
+
}), /* @__PURE__ */ C("input", {
|
|
255
258
|
type: "number",
|
|
256
|
-
min:
|
|
257
|
-
max:
|
|
259
|
+
min: z,
|
|
260
|
+
max: B,
|
|
258
261
|
value: a.checkIntervalSec,
|
|
259
262
|
disabled: n,
|
|
260
|
-
className:
|
|
263
|
+
className: F,
|
|
261
264
|
onFocus: () => c(!0),
|
|
262
265
|
onChange: (e) => o((t) => ({
|
|
263
266
|
...t,
|
|
264
267
|
checkIntervalSec: Number(e.target.value) || 0
|
|
265
268
|
})),
|
|
266
269
|
onBlur: () => {
|
|
267
|
-
let t =
|
|
270
|
+
let t = G(a.checkIntervalSec, z, B);
|
|
268
271
|
t === e.checkIntervalSec ? c(!1) : l({ checkIntervalSec: t });
|
|
269
272
|
}
|
|
270
273
|
})]
|
|
271
274
|
}),
|
|
272
|
-
/* @__PURE__ */
|
|
275
|
+
/* @__PURE__ */ C("p", {
|
|
273
276
|
className: d,
|
|
274
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."
|
|
275
278
|
})
|
|
276
279
|
]
|
|
277
280
|
}),
|
|
278
|
-
/* @__PURE__ */
|
|
279
|
-
className:
|
|
281
|
+
/* @__PURE__ */ w("div", {
|
|
282
|
+
className: L,
|
|
280
283
|
children: [
|
|
281
|
-
/* @__PURE__ */
|
|
282
|
-
className:
|
|
284
|
+
/* @__PURE__ */ C("p", {
|
|
285
|
+
className: R,
|
|
283
286
|
children: "How sure it has to be"
|
|
284
287
|
}),
|
|
285
|
-
e.check.mode === "similarity" && /* @__PURE__ */
|
|
288
|
+
e.check.mode === "similarity" && /* @__PURE__ */ w(T, { children: [/* @__PURE__ */ w("label", {
|
|
286
289
|
className: "flex flex-col gap-1",
|
|
287
|
-
children: [/* @__PURE__ */
|
|
288
|
-
className:
|
|
289
|
-
children: ["Match threshold — ", /* @__PURE__ */
|
|
290
|
+
children: [/* @__PURE__ */ w("span", {
|
|
291
|
+
className: I,
|
|
292
|
+
children: ["Match threshold — ", /* @__PURE__ */ C("span", {
|
|
290
293
|
className: "tabular-nums",
|
|
291
294
|
children: a.threshold.toFixed(2)
|
|
292
295
|
})]
|
|
293
|
-
}), /* @__PURE__ */
|
|
296
|
+
}), /* @__PURE__ */ C("input", {
|
|
294
297
|
type: "range",
|
|
295
298
|
min: .3,
|
|
296
299
|
max: .99,
|
|
@@ -309,212 +312,212 @@ function B({ monitor: e, disabled: n, onPatch: r }) {
|
|
|
309
312
|
a.threshold === p ? c(!1) : l({ check: u({ threshold: a.threshold }) });
|
|
310
313
|
}
|
|
311
314
|
})]
|
|
312
|
-
}), /* @__PURE__ */
|
|
315
|
+
}), /* @__PURE__ */ C("p", {
|
|
313
316
|
className: "text-[10px] text-foreground-subtle",
|
|
314
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."
|
|
315
318
|
})] }),
|
|
316
|
-
/* @__PURE__ */
|
|
319
|
+
/* @__PURE__ */ w("label", {
|
|
317
320
|
className: "flex flex-col gap-1",
|
|
318
|
-
children: [/* @__PURE__ */
|
|
319
|
-
className:
|
|
321
|
+
children: [/* @__PURE__ */ C("span", {
|
|
322
|
+
className: I,
|
|
320
323
|
children: "Agreeing checks before it changes its mind"
|
|
321
|
-
}), /* @__PURE__ */
|
|
324
|
+
}), /* @__PURE__ */ C("input", {
|
|
322
325
|
type: "number",
|
|
323
326
|
min: 1,
|
|
324
327
|
max: 10,
|
|
325
328
|
value: a.hysteresisCount,
|
|
326
329
|
disabled: n,
|
|
327
|
-
className:
|
|
330
|
+
className: F,
|
|
328
331
|
onFocus: () => c(!0),
|
|
329
332
|
onChange: (e) => o((t) => ({
|
|
330
333
|
...t,
|
|
331
334
|
hysteresisCount: Number(e.target.value) || 1
|
|
332
335
|
})),
|
|
333
336
|
onBlur: () => {
|
|
334
|
-
let t =
|
|
337
|
+
let t = G(a.hysteresisCount, 1, 10);
|
|
335
338
|
t === e.check.hysteresisCount ? c(!1) : l({ check: u({ hysteresisCount: t }) });
|
|
336
339
|
}
|
|
337
340
|
})]
|
|
338
341
|
}),
|
|
339
|
-
/* @__PURE__ */
|
|
342
|
+
/* @__PURE__ */ C("p", {
|
|
340
343
|
className: d,
|
|
341
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."
|
|
342
345
|
}),
|
|
343
|
-
/* @__PURE__ */
|
|
346
|
+
/* @__PURE__ */ w("label", {
|
|
344
347
|
className: "flex flex-col gap-1",
|
|
345
|
-
children: [/* @__PURE__ */
|
|
346
|
-
className:
|
|
348
|
+
children: [/* @__PURE__ */ C("span", {
|
|
349
|
+
className: I,
|
|
347
350
|
children: "Quiet for (seconds) before a check counts"
|
|
348
|
-
}), /* @__PURE__ */
|
|
351
|
+
}), /* @__PURE__ */ C("input", {
|
|
349
352
|
type: "number",
|
|
350
353
|
min: 0,
|
|
351
354
|
max: 3600,
|
|
352
355
|
value: a.quietSeconds,
|
|
353
356
|
disabled: n,
|
|
354
|
-
className:
|
|
357
|
+
className: F,
|
|
355
358
|
onFocus: () => c(!0),
|
|
356
359
|
onChange: (e) => o((t) => ({
|
|
357
360
|
...t,
|
|
358
361
|
quietSeconds: Number(e.target.value) || 0
|
|
359
362
|
})),
|
|
360
363
|
onBlur: () => {
|
|
361
|
-
let t =
|
|
364
|
+
let t = G(a.quietSeconds, 0, 3600);
|
|
362
365
|
t === e.quietSeconds ? c(!1) : l({ quietSeconds: t });
|
|
363
366
|
}
|
|
364
367
|
})]
|
|
365
368
|
}),
|
|
366
|
-
/* @__PURE__ */
|
|
369
|
+
/* @__PURE__ */ C("p", {
|
|
367
370
|
className: d,
|
|
368
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."
|
|
369
372
|
}),
|
|
370
|
-
/* @__PURE__ */
|
|
373
|
+
/* @__PURE__ */ w("label", {
|
|
371
374
|
className: "flex flex-col gap-1",
|
|
372
|
-
children: [/* @__PURE__ */
|
|
373
|
-
className:
|
|
375
|
+
children: [/* @__PURE__ */ C("span", {
|
|
376
|
+
className: I,
|
|
374
377
|
children: "Minimum gap between counted checks (seconds)"
|
|
375
|
-
}), /* @__PURE__ */
|
|
378
|
+
}), /* @__PURE__ */ C("input", {
|
|
376
379
|
type: "number",
|
|
377
380
|
min: 0,
|
|
378
381
|
max: 3600,
|
|
379
382
|
value: a.minObservationSpacingSec,
|
|
380
383
|
disabled: n,
|
|
381
|
-
className:
|
|
384
|
+
className: F,
|
|
382
385
|
onFocus: () => c(!0),
|
|
383
386
|
onChange: (e) => o((t) => ({
|
|
384
387
|
...t,
|
|
385
388
|
minObservationSpacingSec: Number(e.target.value) || 0
|
|
386
389
|
})),
|
|
387
390
|
onBlur: () => {
|
|
388
|
-
let t =
|
|
391
|
+
let t = G(a.minObservationSpacingSec, 0, 3600);
|
|
389
392
|
t === e.minObservationSpacingSec ? c(!1) : l({ minObservationSpacingSec: t });
|
|
390
393
|
}
|
|
391
394
|
})]
|
|
392
395
|
}),
|
|
393
|
-
/* @__PURE__ */
|
|
396
|
+
/* @__PURE__ */ C("p", {
|
|
394
397
|
className: d,
|
|
395
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."
|
|
396
399
|
})
|
|
397
400
|
]
|
|
398
401
|
}),
|
|
399
|
-
/* @__PURE__ */
|
|
400
|
-
className:
|
|
402
|
+
/* @__PURE__ */ w("div", {
|
|
403
|
+
className: L,
|
|
401
404
|
children: [
|
|
402
|
-
/* @__PURE__ */
|
|
403
|
-
className:
|
|
405
|
+
/* @__PURE__ */ C("p", {
|
|
406
|
+
className: R,
|
|
404
407
|
children: "Lighting"
|
|
405
408
|
}),
|
|
406
|
-
/* @__PURE__ */
|
|
409
|
+
/* @__PURE__ */ w("label", {
|
|
407
410
|
className: "flex flex-col gap-1",
|
|
408
|
-
children: [/* @__PURE__ */
|
|
409
|
-
className:
|
|
411
|
+
children: [/* @__PURE__ */ C("span", {
|
|
412
|
+
className: I,
|
|
410
413
|
children: "When a light has no reference of its own"
|
|
411
|
-
}), /* @__PURE__ */
|
|
414
|
+
}), /* @__PURE__ */ w("select", {
|
|
412
415
|
value: e.onUncoveredCondition,
|
|
413
416
|
disabled: n,
|
|
414
|
-
className:
|
|
417
|
+
className: F,
|
|
415
418
|
onChange: (e) => {
|
|
416
419
|
let t = e.target.value;
|
|
417
420
|
(t === "skip" || t === "judge-anyway") && l({ onUncoveredCondition: t });
|
|
418
421
|
},
|
|
419
|
-
children: [/* @__PURE__ */
|
|
422
|
+
children: [/* @__PURE__ */ C("option", {
|
|
420
423
|
value: "skip",
|
|
421
424
|
children: "Skip the check (recommended)"
|
|
422
|
-
}), /* @__PURE__ */
|
|
425
|
+
}), /* @__PURE__ */ C("option", {
|
|
423
426
|
value: "judge-anyway",
|
|
424
427
|
children: "Judge against the other light anyway"
|
|
425
428
|
})]
|
|
426
429
|
})]
|
|
427
430
|
}),
|
|
428
|
-
/* @__PURE__ */
|
|
431
|
+
/* @__PURE__ */ C("p", {
|
|
429
432
|
className: d,
|
|
430
|
-
children:
|
|
433
|
+
children: H[e.onUncoveredCondition]
|
|
431
434
|
})
|
|
432
435
|
]
|
|
433
436
|
}),
|
|
434
|
-
/* @__PURE__ */
|
|
435
|
-
className:
|
|
437
|
+
/* @__PURE__ */ w("div", {
|
|
438
|
+
className: L,
|
|
436
439
|
children: [
|
|
437
|
-
/* @__PURE__ */
|
|
438
|
-
className:
|
|
440
|
+
/* @__PURE__ */ C("p", {
|
|
441
|
+
className: R,
|
|
439
442
|
children: "What you get told"
|
|
440
443
|
}),
|
|
441
|
-
/* @__PURE__ */
|
|
444
|
+
/* @__PURE__ */ w("label", {
|
|
442
445
|
className: "flex flex-col gap-1",
|
|
443
|
-
children: [/* @__PURE__ */
|
|
444
|
-
className:
|
|
446
|
+
children: [/* @__PURE__ */ C("span", {
|
|
447
|
+
className: I,
|
|
445
448
|
children: "Notifications follow"
|
|
446
|
-
}), /* @__PURE__ */
|
|
449
|
+
}), /* @__PURE__ */ w("select", {
|
|
447
450
|
value: e.emit,
|
|
448
451
|
disabled: n,
|
|
449
|
-
className:
|
|
452
|
+
className: F,
|
|
450
453
|
onChange: (e) => {
|
|
451
454
|
let t = e.target.value;
|
|
452
455
|
(t === "latched" || t === "live") && l({ emit: t });
|
|
453
456
|
},
|
|
454
|
-
children: [/* @__PURE__ */
|
|
457
|
+
children: [/* @__PURE__ */ C("option", {
|
|
455
458
|
value: "latched",
|
|
456
459
|
children: "The flag — told once, still visible at breakfast"
|
|
457
|
-
}), /* @__PURE__ */
|
|
460
|
+
}), /* @__PURE__ */ C("option", {
|
|
458
461
|
value: "live",
|
|
459
462
|
children: "The live state — follows the region as it changes"
|
|
460
463
|
})]
|
|
461
464
|
})]
|
|
462
465
|
}),
|
|
463
|
-
/* @__PURE__ */
|
|
466
|
+
/* @__PURE__ */ C("p", {
|
|
464
467
|
className: d,
|
|
465
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."
|
|
466
469
|
}),
|
|
467
|
-
/* @__PURE__ */
|
|
470
|
+
/* @__PURE__ */ w("label", {
|
|
468
471
|
className: "flex items-center gap-2",
|
|
469
|
-
children: [/* @__PURE__ */
|
|
472
|
+
children: [/* @__PURE__ */ C("input", {
|
|
470
473
|
type: "checkbox",
|
|
471
474
|
checked: e.autoRestore,
|
|
472
475
|
disabled: n,
|
|
473
476
|
onChange: (e) => l({ autoRestore: e.target.checked })
|
|
474
|
-
}), /* @__PURE__ */
|
|
475
|
-
className:
|
|
477
|
+
}), /* @__PURE__ */ C("span", {
|
|
478
|
+
className: I,
|
|
476
479
|
children: "Clear the flag by itself when things look normal again"
|
|
477
480
|
})]
|
|
478
481
|
}),
|
|
479
|
-
/* @__PURE__ */
|
|
482
|
+
/* @__PURE__ */ C("p", {
|
|
480
483
|
className: d,
|
|
481
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."
|
|
482
485
|
})
|
|
483
486
|
]
|
|
484
487
|
}),
|
|
485
|
-
/* @__PURE__ */
|
|
486
|
-
className:
|
|
488
|
+
/* @__PURE__ */ w("div", {
|
|
489
|
+
className: L,
|
|
487
490
|
children: [
|
|
488
|
-
/* @__PURE__ */
|
|
489
|
-
className:
|
|
491
|
+
/* @__PURE__ */ C("p", {
|
|
492
|
+
className: R,
|
|
490
493
|
children: "AI double-check"
|
|
491
494
|
}),
|
|
492
|
-
/* @__PURE__ */
|
|
495
|
+
/* @__PURE__ */ w("label", {
|
|
493
496
|
className: "flex items-center gap-2",
|
|
494
|
-
children: [/* @__PURE__ */
|
|
497
|
+
children: [/* @__PURE__ */ C("input", {
|
|
495
498
|
type: "checkbox",
|
|
496
499
|
checked: f,
|
|
497
500
|
disabled: n || a.confirmPrompt.trim().length === 0,
|
|
498
501
|
onChange: (e) => l(e.target.checked ? { confirm: {
|
|
499
|
-
...
|
|
502
|
+
...K(a.confirmPrompt.trim()),
|
|
500
503
|
enabled: !0
|
|
501
504
|
} } : { confirm: null })
|
|
502
|
-
}), /* @__PURE__ */
|
|
503
|
-
className:
|
|
505
|
+
}), /* @__PURE__ */ C("span", {
|
|
506
|
+
className: I,
|
|
504
507
|
children: "Ask a vision model before changing the answer"
|
|
505
508
|
})]
|
|
506
509
|
}),
|
|
507
|
-
/* @__PURE__ */
|
|
510
|
+
/* @__PURE__ */ w("label", {
|
|
508
511
|
className: "flex flex-col gap-1",
|
|
509
|
-
children: [/* @__PURE__ */
|
|
510
|
-
className:
|
|
512
|
+
children: [/* @__PURE__ */ C("span", {
|
|
513
|
+
className: I,
|
|
511
514
|
children: "The question to ask"
|
|
512
|
-
}), /* @__PURE__ */
|
|
515
|
+
}), /* @__PURE__ */ C("input", {
|
|
513
516
|
type: "text",
|
|
514
517
|
value: a.confirmPrompt,
|
|
515
518
|
placeholder: "e.g. Is the wheelie bin still there?",
|
|
516
519
|
disabled: n,
|
|
517
|
-
className:
|
|
520
|
+
className: F,
|
|
518
521
|
onFocus: () => c(!0),
|
|
519
522
|
onChange: (e) => o((t) => ({
|
|
520
523
|
...t,
|
|
@@ -523,17 +526,17 @@ function B({ monitor: e, disabled: n, onPatch: r }) {
|
|
|
523
526
|
onBlur: () => {
|
|
524
527
|
let t = a.confirmPrompt.trim();
|
|
525
528
|
t.length > 0 && t !== e.confirm?.prompt ? l({ confirm: {
|
|
526
|
-
...
|
|
529
|
+
...K(t),
|
|
527
530
|
enabled: f
|
|
528
531
|
} }) : c(!1);
|
|
529
532
|
}
|
|
530
533
|
})]
|
|
531
534
|
}),
|
|
532
|
-
/* @__PURE__ */
|
|
535
|
+
/* @__PURE__ */ w("p", {
|
|
533
536
|
className: d,
|
|
534
537
|
children: [
|
|
535
538
|
"The model is asked ",
|
|
536
|
-
/* @__PURE__ */
|
|
539
|
+
/* @__PURE__ */ C("strong", { children: "only" }),
|
|
537
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."
|
|
538
541
|
]
|
|
539
542
|
})
|
|
@@ -542,10 +545,10 @@ function B({ monitor: e, disabled: n, onPatch: r }) {
|
|
|
542
545
|
]
|
|
543
546
|
});
|
|
544
547
|
}
|
|
545
|
-
function
|
|
548
|
+
function G(e, t, n) {
|
|
546
549
|
return Math.min(n, Math.max(t, e));
|
|
547
550
|
}
|
|
548
|
-
function
|
|
551
|
+
function K(e) {
|
|
549
552
|
return {
|
|
550
553
|
enabled: !1,
|
|
551
554
|
prompt: e,
|
|
@@ -557,13 +560,13 @@ function H(e) {
|
|
|
557
560
|
//#endregion
|
|
558
561
|
//#region ../ui-library/src/composites/cap-settings/SceneMonitorEditor.tsx
|
|
559
562
|
a();
|
|
560
|
-
var
|
|
563
|
+
var q = "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", J = "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", Y = "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 = {
|
|
561
564
|
alarm: "border-danger/50 bg-danger/15 text-danger",
|
|
562
565
|
ok: "border-success/50 bg-success/15 text-success",
|
|
563
566
|
unknown: "border-border bg-surface text-foreground-subtle"
|
|
564
|
-
},
|
|
565
|
-
function
|
|
566
|
-
let u = l(o().trpcClient, a), p = s(u?.state.sceneMonitor),
|
|
567
|
+
}, re = .8, ie = 3;
|
|
568
|
+
function X({ deviceId: a }) {
|
|
569
|
+
let u = l(o().trpcClient, a), p = s(u?.state.sceneMonitor), x = b(a, { width: 640 }), [O, k] = t(null), [A, j] = t(!1), [M, N] = t(null), [P, F] = t(null), [I, L] = t(null), [R, z] = t(null), [B, V] = t(!1), [H, U] = t(null), [G, K] = t(""), X = n(!0);
|
|
567
570
|
i(() => (X.current = !0, () => {
|
|
568
571
|
X.current = !1;
|
|
569
572
|
}), []);
|
|
@@ -571,23 +574,23 @@ function Y({ deviceId: a }) {
|
|
|
571
574
|
if (u) try {
|
|
572
575
|
let e = await u.sceneMonitor?.listScenes({});
|
|
573
576
|
if (!X.current) return;
|
|
574
|
-
e &&
|
|
577
|
+
e && k(e);
|
|
575
578
|
} catch (e) {
|
|
576
579
|
if (!X.current) return;
|
|
577
|
-
c(e) ?
|
|
580
|
+
c(e) ? j(!0) : F(e instanceof Error ? e.message : String(e));
|
|
578
581
|
}
|
|
579
582
|
}, [u]);
|
|
580
583
|
i(() => {
|
|
581
|
-
|
|
584
|
+
k(null), j(!1), F(null), Z();
|
|
582
585
|
}, [Z]);
|
|
583
|
-
let Q = p?.monitors ??
|
|
584
|
-
|
|
586
|
+
let Q = p?.monitors ?? O?.monitors ?? [], ae = Date.now(), $ = e(async (e, t) => {
|
|
587
|
+
N(e), F(null);
|
|
585
588
|
try {
|
|
586
589
|
await t(), await Z();
|
|
587
590
|
} catch (e) {
|
|
588
|
-
X.current &&
|
|
591
|
+
X.current && F(e instanceof Error ? e.message : String(e));
|
|
589
592
|
} finally {
|
|
590
|
-
X.current &&
|
|
593
|
+
X.current && N(null);
|
|
591
594
|
}
|
|
592
595
|
}, [Z]), oe = r(() => {
|
|
593
596
|
let e = Q.map((e) => ({
|
|
@@ -596,15 +599,15 @@ function Y({ deviceId: a }) {
|
|
|
596
599
|
label: e.label,
|
|
597
600
|
enabled: e.enabled
|
|
598
601
|
}));
|
|
599
|
-
return
|
|
602
|
+
return H === null ? e : [...e, {
|
|
600
603
|
id: "__draft__",
|
|
601
|
-
shape:
|
|
604
|
+
shape: H,
|
|
602
605
|
label: "New scene"
|
|
603
606
|
}];
|
|
604
|
-
}, [Q,
|
|
607
|
+
}, [Q, H]), se = e((e, t) => {
|
|
605
608
|
if (t.kind === "rect") {
|
|
606
609
|
if (e === "__draft__") {
|
|
607
|
-
|
|
610
|
+
U(t);
|
|
608
611
|
return;
|
|
609
612
|
}
|
|
610
613
|
$(`roi-${String(e)}`, async () => u?.sceneMonitor?.updateScene({
|
|
@@ -613,205 +616,205 @@ function Y({ deviceId: a }) {
|
|
|
613
616
|
}));
|
|
614
617
|
}
|
|
615
618
|
}, [u, $]), ce = e((e) => {
|
|
616
|
-
e.kind === "rect" &&
|
|
619
|
+
e.kind === "rect" && U(e);
|
|
617
620
|
}, []), le = e(async () => {
|
|
618
|
-
|
|
621
|
+
H === null || G.trim().length === 0 || (await $("create", async () => {
|
|
619
622
|
await u?.sceneMonitor?.createScene({
|
|
620
|
-
label:
|
|
621
|
-
roi:
|
|
623
|
+
label: G.trim(),
|
|
624
|
+
roi: H,
|
|
622
625
|
check: {
|
|
623
626
|
mode: "similarity",
|
|
624
|
-
threshold:
|
|
625
|
-
hysteresisCount:
|
|
627
|
+
threshold: re,
|
|
628
|
+
hysteresisCount: ie
|
|
626
629
|
}
|
|
627
630
|
});
|
|
628
|
-
}),
|
|
631
|
+
}), U(null), K(""), V(!1));
|
|
629
632
|
}, [
|
|
630
633
|
u,
|
|
631
|
-
z,
|
|
632
634
|
H,
|
|
635
|
+
G,
|
|
633
636
|
$
|
|
634
637
|
]);
|
|
635
|
-
return u ? /* @__PURE__ */
|
|
638
|
+
return u ? /* @__PURE__ */ C("div", {
|
|
636
639
|
className: "flex flex-col gap-3",
|
|
637
|
-
children:
|
|
640
|
+
children: A ? /* @__PURE__ */ C("p", {
|
|
638
641
|
className: `${d} leading-relaxed`,
|
|
639
642
|
children: "Scene monitoring is not available for this camera."
|
|
640
|
-
}) : /* @__PURE__ */
|
|
641
|
-
/* @__PURE__ */
|
|
643
|
+
}) : /* @__PURE__ */ w(T, { children: [
|
|
644
|
+
/* @__PURE__ */ C("p", {
|
|
642
645
|
className: `${d} leading-relaxed`,
|
|
643
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."
|
|
644
647
|
}),
|
|
645
|
-
/* @__PURE__ */
|
|
648
|
+
/* @__PURE__ */ C("div", {
|
|
646
649
|
className: "relative overflow-hidden rounded-md border border-border",
|
|
647
|
-
children: /* @__PURE__ */
|
|
650
|
+
children: /* @__PURE__ */ C(E, {
|
|
648
651
|
items: oe,
|
|
649
652
|
supportedShapes: ["rect"],
|
|
650
|
-
selectedId:
|
|
651
|
-
onSelect: (e) =>
|
|
653
|
+
selectedId: I ?? (H === null ? null : "__draft__"),
|
|
654
|
+
onSelect: (e) => L(e === null ? null : String(e)),
|
|
652
655
|
onShapeChange: se,
|
|
653
656
|
onDrawComplete: ce,
|
|
654
|
-
drawingKind:
|
|
655
|
-
backdrop:
|
|
656
|
-
src:
|
|
657
|
+
drawingKind: B && H === null ? "rect" : null,
|
|
658
|
+
backdrop: x.src === null ? null : /* @__PURE__ */ C("img", {
|
|
659
|
+
src: x.src,
|
|
657
660
|
alt: "",
|
|
658
661
|
className: "h-full w-full object-contain",
|
|
659
662
|
draggable: !1
|
|
660
663
|
})
|
|
661
664
|
})
|
|
662
665
|
}),
|
|
663
|
-
/* @__PURE__ */
|
|
666
|
+
/* @__PURE__ */ w("div", {
|
|
664
667
|
className: "flex flex-wrap items-center gap-2",
|
|
665
|
-
children: [/* @__PURE__ */
|
|
668
|
+
children: [/* @__PURE__ */ C("button", {
|
|
666
669
|
type: "button",
|
|
667
|
-
className:
|
|
668
|
-
"aria-pressed":
|
|
670
|
+
className: B ? J : q,
|
|
671
|
+
"aria-pressed": B,
|
|
669
672
|
onClick: () => {
|
|
670
|
-
|
|
673
|
+
V((e) => !e), U(null);
|
|
671
674
|
},
|
|
672
|
-
disabled:
|
|
673
|
-
children:
|
|
674
|
-
}), /* @__PURE__ */
|
|
675
|
+
disabled: M !== null,
|
|
676
|
+
children: B ? "Cancel" : "+ New scene"
|
|
677
|
+
}), /* @__PURE__ */ C("button", {
|
|
675
678
|
type: "button",
|
|
676
|
-
className:
|
|
677
|
-
onClick:
|
|
678
|
-
disabled:
|
|
679
|
+
className: q,
|
|
680
|
+
onClick: x.refresh,
|
|
681
|
+
disabled: M !== null,
|
|
679
682
|
children: "Refresh frame"
|
|
680
683
|
})]
|
|
681
684
|
}),
|
|
682
|
-
|
|
685
|
+
B && /* @__PURE__ */ w("div", {
|
|
683
686
|
className: "flex flex-col gap-2 rounded-md border border-border bg-surface p-2",
|
|
684
687
|
children: [
|
|
685
|
-
/* @__PURE__ */
|
|
688
|
+
/* @__PURE__ */ C("p", {
|
|
686
689
|
className: "text-[10px] text-foreground-subtle",
|
|
687
|
-
children:
|
|
690
|
+
children: H === 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."
|
|
688
691
|
}),
|
|
689
|
-
|
|
692
|
+
H !== null && f(H) && /* @__PURE__ */ C("p", {
|
|
690
693
|
className: "text-[11px] leading-relaxed text-warning",
|
|
691
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."
|
|
692
695
|
}),
|
|
693
|
-
/* @__PURE__ */
|
|
696
|
+
/* @__PURE__ */ w("div", {
|
|
694
697
|
className: "flex items-center gap-2",
|
|
695
|
-
children: [/* @__PURE__ */
|
|
698
|
+
children: [/* @__PURE__ */ C("input", {
|
|
696
699
|
type: "text",
|
|
697
|
-
value:
|
|
698
|
-
onChange: (e) =>
|
|
700
|
+
value: G,
|
|
701
|
+
onChange: (e) => K(e.target.value),
|
|
699
702
|
placeholder: "e.g. Immondizia prelevata",
|
|
700
703
|
className: "flex-1 rounded-md border border-border bg-surface px-2 py-1 text-[12px] text-foreground"
|
|
701
|
-
}), /* @__PURE__ */
|
|
704
|
+
}), /* @__PURE__ */ C("button", {
|
|
702
705
|
type: "button",
|
|
703
|
-
className:
|
|
706
|
+
className: J,
|
|
704
707
|
onClick: () => void le(),
|
|
705
|
-
disabled:
|
|
708
|
+
disabled: H === null || G.trim().length === 0 || M !== null,
|
|
706
709
|
children: "Create"
|
|
707
710
|
})]
|
|
708
711
|
})
|
|
709
712
|
]
|
|
710
713
|
}),
|
|
711
|
-
|
|
714
|
+
P !== null && /* @__PURE__ */ C("p", {
|
|
712
715
|
className: "text-[11px] leading-relaxed text-danger",
|
|
713
|
-
children:
|
|
716
|
+
children: P
|
|
714
717
|
}),
|
|
715
|
-
Q.length === 0 ? /* @__PURE__ */
|
|
718
|
+
Q.length === 0 ? /* @__PURE__ */ C("p", {
|
|
716
719
|
className: `${d} leading-relaxed`,
|
|
717
720
|
children: "No scenes on this camera yet."
|
|
718
|
-
}) : /* @__PURE__ */
|
|
721
|
+
}) : /* @__PURE__ */ C("ul", {
|
|
719
722
|
className: "flex flex-col gap-2",
|
|
720
723
|
children: Q.map((e) => {
|
|
721
|
-
let t =
|
|
722
|
-
return /* @__PURE__ */
|
|
723
|
-
className: `flex flex-col gap-1.5 rounded-md border p-2 ${
|
|
724
|
+
let t = v(e);
|
|
725
|
+
return /* @__PURE__ */ w("li", {
|
|
726
|
+
className: `flex flex-col gap-1.5 rounded-md border p-2 ${I === e.id ? "border-primary/50" : "border-border"}`,
|
|
724
727
|
children: [
|
|
725
|
-
/* @__PURE__ */
|
|
728
|
+
/* @__PURE__ */ w("div", {
|
|
726
729
|
className: "flex items-center gap-2",
|
|
727
|
-
children: [/* @__PURE__ */
|
|
730
|
+
children: [/* @__PURE__ */ C("button", {
|
|
728
731
|
type: "button",
|
|
729
732
|
className: "flex-1 text-left text-[12px] font-medium text-foreground",
|
|
730
|
-
onClick: () =>
|
|
733
|
+
onClick: () => L(e.id),
|
|
731
734
|
children: e.label
|
|
732
|
-
}), /* @__PURE__ */
|
|
733
|
-
className: `rounded border px-1.5 py-0.5 text-[10px] font-medium ${
|
|
735
|
+
}), /* @__PURE__ */ C("span", {
|
|
736
|
+
className: `rounded border px-1.5 py-0.5 text-[10px] font-medium ${ne[t.tone]}`,
|
|
734
737
|
children: t.text
|
|
735
738
|
})]
|
|
736
739
|
}),
|
|
737
|
-
/* @__PURE__ */
|
|
740
|
+
/* @__PURE__ */ C("p", {
|
|
738
741
|
className: `${d} leading-relaxed`,
|
|
739
|
-
children:
|
|
742
|
+
children: _(e, ae)
|
|
740
743
|
}),
|
|
741
|
-
/* @__PURE__ */
|
|
744
|
+
/* @__PURE__ */ C("p", {
|
|
742
745
|
className: `${d} tabular-nums`,
|
|
743
746
|
children: m(e)
|
|
744
747
|
}),
|
|
745
|
-
/* @__PURE__ */
|
|
748
|
+
/* @__PURE__ */ C(te, {
|
|
746
749
|
monitor: e,
|
|
747
|
-
disabled:
|
|
750
|
+
disabled: M !== null,
|
|
748
751
|
onDelete: ({ stateId: t, index: n }) => void $(`refdel-${e.id}-${t}-${String(n)}`, async () => u.sceneMonitor?.deleteReference({
|
|
749
752
|
monitorId: e.id,
|
|
750
753
|
stateId: t,
|
|
751
754
|
index: n
|
|
752
755
|
}))
|
|
753
756
|
}),
|
|
754
|
-
/* @__PURE__ */
|
|
757
|
+
/* @__PURE__ */ w("div", {
|
|
755
758
|
className: "flex flex-wrap items-center gap-1.5",
|
|
756
759
|
children: [
|
|
757
|
-
|
|
760
|
+
g.map((t) => {
|
|
758
761
|
let n = t === "ir";
|
|
759
|
-
return /* @__PURE__ */
|
|
762
|
+
return /* @__PURE__ */ w("button", {
|
|
760
763
|
type: "button",
|
|
761
|
-
className:
|
|
762
|
-
disabled:
|
|
763
|
-
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 ${
|
|
764
|
+
className: q,
|
|
765
|
+
disabled: M !== 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 ${y(t).toLowerCase()} reference`,
|
|
764
767
|
onClick: () => void $(`cap-${e.id}-${t}`, async () => u.sceneMonitor?.captureReference({
|
|
765
768
|
monitorId: e.id,
|
|
766
769
|
condition: t
|
|
767
770
|
})),
|
|
768
771
|
children: [
|
|
769
|
-
/* @__PURE__ */
|
|
772
|
+
/* @__PURE__ */ C(ee, { className: "mr-1 inline h-3 w-3" }),
|
|
770
773
|
"Capture ",
|
|
771
|
-
|
|
772
|
-
n && /* @__PURE__ */
|
|
774
|
+
y(t).toLowerCase(),
|
|
775
|
+
n && /* @__PURE__ */ C("span", {
|
|
773
776
|
className: "ml-1 text-foreground-subtle/70",
|
|
774
777
|
children: "(optional)"
|
|
775
778
|
})
|
|
776
779
|
]
|
|
777
780
|
}, t);
|
|
778
781
|
}),
|
|
779
|
-
/* @__PURE__ */
|
|
782
|
+
/* @__PURE__ */ w("button", {
|
|
780
783
|
type: "button",
|
|
781
|
-
className:
|
|
782
|
-
disabled:
|
|
784
|
+
className: J,
|
|
785
|
+
disabled: M !== null || e.states.length === 0,
|
|
783
786
|
title: "Clear the flag and re-photograph what normal looks like right now",
|
|
784
787
|
onClick: () => void $(`reset-${e.id}`, async () => u.sceneMonitor?.resetScene({ monitorId: e.id })),
|
|
785
|
-
children: [/* @__PURE__ */
|
|
788
|
+
children: [/* @__PURE__ */ C(h, { className: "mr-1 inline h-3 w-3" }), "Reset"]
|
|
786
789
|
}),
|
|
787
|
-
/* @__PURE__ */
|
|
790
|
+
/* @__PURE__ */ C("button", {
|
|
788
791
|
type: "button",
|
|
789
|
-
className:
|
|
790
|
-
disabled:
|
|
792
|
+
className: q,
|
|
793
|
+
disabled: M !== null,
|
|
791
794
|
onClick: () => void $(`check-${e.id}`, async () => u.sceneMonitor?.recheckNow({ monitorId: e.id })),
|
|
792
795
|
children: "Check now"
|
|
793
796
|
}),
|
|
794
|
-
/* @__PURE__ */
|
|
797
|
+
/* @__PURE__ */ w("button", {
|
|
795
798
|
type: "button",
|
|
796
|
-
className:
|
|
797
|
-
"aria-pressed":
|
|
799
|
+
className: R === e.id ? J : q,
|
|
800
|
+
"aria-pressed": R === e.id,
|
|
798
801
|
"aria-label": `Settings for ${e.label}`,
|
|
799
|
-
disabled:
|
|
800
|
-
onClick: () =>
|
|
801
|
-
children: [/* @__PURE__ */
|
|
802
|
+
disabled: M !== null,
|
|
803
|
+
onClick: () => z((t) => t === e.id ? null : e.id),
|
|
804
|
+
children: [/* @__PURE__ */ C(D, { className: "mr-1 inline h-3 w-3" }), "Settings"]
|
|
802
805
|
}),
|
|
803
|
-
/* @__PURE__ */
|
|
806
|
+
/* @__PURE__ */ C("button", {
|
|
804
807
|
type: "button",
|
|
805
|
-
className:
|
|
806
|
-
disabled:
|
|
808
|
+
className: Y,
|
|
809
|
+
disabled: M !== null,
|
|
807
810
|
onClick: () => void $(`del-${e.id}`, async () => u.sceneMonitor?.deleteScene({ monitorId: e.id })),
|
|
808
|
-
children: /* @__PURE__ */
|
|
811
|
+
children: /* @__PURE__ */ C(S, { className: "h-3 w-3" })
|
|
809
812
|
})
|
|
810
813
|
]
|
|
811
814
|
}),
|
|
812
|
-
|
|
815
|
+
R === e.id && /* @__PURE__ */ C(W, {
|
|
813
816
|
monitor: e,
|
|
814
|
-
disabled:
|
|
817
|
+
disabled: M !== null,
|
|
815
818
|
onPatch: (t) => void $(`tune-${e.id}`, async () => u.sceneMonitor?.updateScene({
|
|
816
819
|
monitorId: e.id,
|
|
817
820
|
patch: t
|
|
@@ -825,4 +828,4 @@ function Y({ deviceId: a }) {
|
|
|
825
828
|
}) : null;
|
|
826
829
|
}
|
|
827
830
|
//#endregion
|
|
828
|
-
export {
|
|
831
|
+
export { X as SceneMonitorEditor };
|