@camstack/addon-agent-ui 1.2.311 → 1.2.313

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/CHANGELOG.md CHANGED
@@ -7,6 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [1.2.313] - 2026-11-02
11
+
12
+ ### Changed
13
+
14
+ - Rebuilt against updated dependencies.
15
+
16
+ ## [1.2.312] - 2026-11-02
17
+
18
+ ### Changed
19
+
20
+ - Rebuilt against updated dependencies.
21
+
10
22
  ## [1.2.311] - 2026-11-01
11
23
 
12
24
  ### Changed
@@ -362,13 +362,13 @@
362
362
  "server/server/packages/addon-agent-ui/src/updates-panel.tsx": "ec6b5b3701322bbb68dbe581703409cd373418cf9227ce829ea0945e70e60d54",
363
363
  "server/server/packages/addon-agent-ui/src/use-pairing-status.ts": "46193a1e83a64250dfff75d417448d74ba0159465e710861b996e903b03e427a",
364
364
  "server/server/packages/sdk/dist/index.js": "89409bfb9632c46ed63ee4882c70b7994c1ff90c67d27a5d4b86b0990c41a131",
365
- "server/server/packages/types/dist/client.mjs": "c6397c4dda3853a15c463fe2a5671ad9521b06d4ea51a9b4408854d81a79774f",
365
+ "server/server/packages/types/dist/client.mjs": "8d2722a6a47194ba322fc16d1536e6ba4e5fef7739789a08c90c6c4d2c7aa30a",
366
366
  "server/server/packages/types/dist/composition-kKKOdFIG.mjs": "8884b661df300b88fba5ad861a6cb0096cee1a1c1ca8058bea94907caaff28e6",
367
367
  "server/server/packages/types/dist/device-type-BOWLtoOt.mjs": "cc8447229f79743a89db50f17befd0674934b4c79bc905aa1a7f4e8667453b2c",
368
368
  "server/server/packages/types/dist/event-category-BmPm98n0.mjs": "3617fc3941b34f1dcc8ebd3c1360e8c302747400d43e3ab694388496c2bb568d",
369
- "server/server/packages/types/dist/index.mjs": "e81fca6537a93e44582dbb1675fbe15b0ef2087b4ae7bbe85819f9110bcb5ae9",
369
+ "server/server/packages/types/dist/index.mjs": "b4c9c734fcd0204d4ddf52cb2495840dcc2552d850f0cdea1120a2d93422782c",
370
370
  "server/server/packages/types/dist/node-color.mjs": "942e663074f0a4ed2f8643848ec139eba4b5fd16d0d01c8a23e08a4819a8843b",
371
- "server/server/packages/types/dist/sleep-_4vKNWxb.mjs": "f0eab5fb04aad9cda8a2bb2e606f607b7123b3b28849bdb4d670ca69850b0e78",
371
+ "server/server/packages/types/dist/sleep-B-vp7x15.mjs": "26814958a629c9c04f1b47301254025974b7b9ad9d093523348469d4cd03d2ac",
372
372
  "server/server/packages/ui-library/src/composites/adaptive-downlink.ts": "6e9698e97721461b72a3750f930dd7214d049be865491bfb5a64b87c032b0e22",
373
373
  "server/server/packages/ui-library/src/composites/camera-stream-player.tsx": "c04809229b4e091fed09e2bcfe643d6b36cb3a39e294229b49f8a095e4e6ebd3",
374
374
  "server/server/packages/ui-library/src/composites/cap-settings/CameraGridLayoutEditor.tsx": "bfe36ccad931ef0981fe24fa315f136d35dbc3164df221346806173447178324",
@@ -479,7 +479,7 @@
479
479
  "server/server/packages/ui-library/src/contexts/vod-playback.tsx": "c07bc3ecc786182ef2f27d13bec3f520288e0b47367edd7ddf1c2e7b4a2bbaee",
480
480
  "server/server/packages/ui-library/src/contexts/widget-registry.tsx": "71a2815c645abe96821a9e9e5668e321187527d569414f5ca197d615856cc17a",
481
481
  "server/server/packages/ui-library/src/contexts/zone-editing.tsx": "275f680304ab09dd747fd9e859dc5aa0535df33eb2d33eb669a6de66bdd848d0",
482
- "server/server/packages/ui-library/src/generated/system-hooks.ts": "c199b3766df3184f66688cf3ac2c4bf2373fed729f0f52f29012645d6d0c5c1f",
482
+ "server/server/packages/ui-library/src/generated/system-hooks.ts": "0c3e5118d73f77cc0f49c451fb38f6530ddb2e9c4af0d4a4c201320d447c0074",
483
483
  "server/server/packages/ui-library/src/hooks/turn-server-cache.ts": "fab22f069c3761e0d268449e056d9c499b6ea63b879684a40023735b34bad061",
484
484
  "server/server/packages/ui-library/src/hooks/use-device-capability.ts": "b74ede60be8039c45f6c712a407ee838ab208610435870ddabaa8598cb7cd7f3",
485
485
  "server/server/packages/ui-library/src/hooks/use-device-detections.ts": "61cc54cf2e7f53864e5aa533c05679e4c204c4004a0296f63ab169b003888611",
@@ -490,11 +490,11 @@
490
490
  "server/server/packages/ui-library/src/hooks/use-lock-door-sensor.ts": "737595d117aeac981cc5d1bc2c340098862dfabce559125cfe62b889c56a6bfb",
491
491
  "server/server/packages/ui-library/src/hooks/use-optimistic-slice.ts": "d7b29f4af17a64b77f2b3d53001caa7cc2f98c495aec226752d3f40a5066ba68",
492
492
  "server/server/packages/ui-library/src/hotkeys/combo.ts": "579eca126011621836a84f6b6347fbed4128a4878ce32e2b2196206af1198233",
493
- "server/server/packages/ui-library/src/hotkeys/hotkey-provider.tsx": "3711452537a64f88a99de1cf3aea6be9d93e1b31a2189bd150c1a27b4c13e2ae",
494
- "server/server/packages/ui-library/src/hotkeys/use-search-field-hotkey.ts": "9ec26930f93ffa786c1cea6b98cb61919410c309a22a888dadd42259511f10d8",
493
+ "server/server/packages/ui-library/src/hotkeys/hotkey-provider.tsx": "d9a05285344e284a3e38e016e5b1b73473d99ca5184ddd4584c551ec999224e3",
494
+ "server/server/packages/ui-library/src/hotkeys/use-search-field-hotkey.ts": "d2deeecffc7402ae83fd3542fb169defd06d12d13c18461a7c35ffefc3e298ac",
495
495
  "server/server/packages/ui-library/src/i18n/addon-i18n.ts": "5d3374f9f8d0e4b520fbd06786095f95162b743943565f22db406838a9b7dd2f",
496
496
  "server/server/packages/ui-library/src/i18n/use-addon-t.tsx": "a8b3579aefc61c0ff745a3ddd4dfa55c81281e39cdae96bfadb39442a3e495e8",
497
- "server/server/packages/ui-library/src/index.ts": "188bd443c751a2487346222b4d368fdd017e7eface967cd995d3c862d8fe2ef7",
497
+ "server/server/packages/ui-library/src/index.ts": "6021decaaa9138996de7244c41aebf3c5741d4261ff3d972476dec0d7e01205d",
498
498
  "server/server/packages/ui-library/src/lib/cap-error.ts": "46460f0e064b8c8afbe90d40cc545aac7e827807edfd7b9ef21091c9a01479d4",
499
499
  "server/server/packages/ui-library/src/lib/cn.ts": "fbb81bc6c329349f06f975433215ef934111f77372e8902e2d1d347fc29cfde1",
500
500
  "server/server/packages/ui-library/src/lib/format-control-datetime.ts": "5483aaeb1900d9a08dba79fe049f2f848b3ea303272facd65211e28a90f30034",
package/dist/addon.js CHANGED
@@ -5840,7 +5840,7 @@ var ZodIssueCode = {
5840
5840
  var ZodFirstPartyTypeKind;
5841
5841
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5842
5842
  //#endregion
5843
- //#region ../types/dist/sleep-_4vKNWxb.mjs
5843
+ //#region ../types/dist/sleep-B-vp7x15.mjs
5844
5844
  /**
5845
5845
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5846
5846
  * window to float samples (D455).
@@ -9283,6 +9283,7 @@ var CAP_NAMES = Object.freeze([
9283
9283
  "device-status",
9284
9284
  "dishwasher",
9285
9285
  "display-palette",
9286
+ "do-not-disturb",
9286
9287
  "doorbell",
9287
9288
  "embedding-encoder",
9288
9289
  "enum-sensor",
@@ -10042,6 +10043,10 @@ Object.freeze({
10042
10043
  "valueType": "string"
10043
10044
  }
10044
10045
  ],
10046
+ "do-not-disturb": [{
10047
+ "path": "enabled",
10048
+ "valueType": "boolean"
10049
+ }],
10045
10050
  "doorbell": [{
10046
10051
  "path": "lastPressedAt",
10047
10052
  "valueType": "number"
@@ -15488,8 +15493,18 @@ var LogChannelDescriptorSchema = object({
15488
15493
  * the operator narrows to one camera, sees nothing, and concludes the code
15489
15494
  * path was never taken.
15490
15495
  */
15491
- perDevice: boolean()
15492
- });
15496
+ perDevice: boolean(),
15497
+ /**
15498
+ * What the channel is FOR, so the UI can list the channels an addon offers.
15499
+ *
15500
+ * - `diagnostic` (the default): a per-component diagnostic armed from the
15501
+ * Levels page, emitted at its declared level.
15502
+ * - `debug`: a `debug.<channel>` dump watched live for a short window
15503
+ * (`ctx.debug`). Always per-device, and its lines are denied by the log
15504
+ * ring unless somebody is watching that device.
15505
+ */
15506
+ kind: _enum(["diagnostic", "debug"]).default("diagnostic")
15507
+ }).refine((d) => d.kind !== "debug" || d.name.startsWith("debug.") && d.perDevice, { message: "a debug channel is named debug.<channel> and is per-device" });
15493
15508
  /**
15494
15509
  * An armed window over one channel, as the document hands it to a mirror.
15495
15510
  *
@@ -19464,6 +19479,33 @@ var APPLIANCE_CAP_VOCABULARY = {
19464
19479
  }
19465
19480
  ]
19466
19481
  },
19482
+ "do-not-disturb": {
19483
+ scope: "device",
19484
+ noun: t("Do not disturb", "Non disturbare"),
19485
+ actions: [{
19486
+ id: "dnd.on",
19487
+ method: "setEnabled",
19488
+ label: t("Do not disturb on", "Attiva Non disturbare"),
19489
+ phrase: t("Turn on Do not disturb on {device}", "Attiva Non disturbare su {device}"),
19490
+ icon: "bell-off",
19491
+ args: { enabled: true }
19492
+ }, {
19493
+ id: "dnd.off",
19494
+ method: "setEnabled",
19495
+ label: t("Do not disturb off", "Disattiva Non disturbare"),
19496
+ phrase: t("Turn off Do not disturb on {device}", "Disattiva Non disturbare su {device}"),
19497
+ icon: "bell",
19498
+ args: { enabled: false }
19499
+ }],
19500
+ state: [{
19501
+ kind: "boolean",
19502
+ field: "enabled",
19503
+ label: t("Do not disturb", "Non disturbare"),
19504
+ whenTrue: t("When Do not disturb turns on on {device}", "Quando {device} attiva Non disturbare"),
19505
+ whenFalse: t("When Do not disturb turns off on {device}", "Quando {device} disattiva Non disturbare"),
19506
+ icon: "bell-off"
19507
+ }]
19508
+ },
19467
19509
  update: {
19468
19510
  scope: "device",
19469
19511
  noun: t("Firmware update", "Aggiornamento firmware"),
@@ -41520,14 +41562,16 @@ var DeviceIsLeafSchema = object({
41520
41562
  });
41521
41563
  /**
41522
41564
  * True when the camera currently has a PARKED object matching `subjects` in at
41523
- * least one of `zones`. Reads the zone-analytics snapshot through the same
41565
+ * least one of `zones` (`minCount` of them, default one). Reads the zone-analytics snapshot through the same
41524
41566
  * mirror as every other state leaf, so a dropped event never decides it (D49).
41525
41567
  */
41526
41568
  var StationaryPresentLeafSchema = object({
41527
41569
  kind: literal("stationary-present"),
41528
41570
  deviceId: number().int().nonnegative(),
41529
41571
  subjects: array(StationarySubjectSchema).min(1).optional(),
41530
- zones: array(string().min(1)).min(1).optional()
41572
+ zones: array(string().min(1)).min(1).optional(),
41573
+ /** How many matching parked objects must be there; absent means one. */
41574
+ minCount: number().int().positive().optional()
41531
41575
  });
41532
41576
  /**
41533
41577
  * The escape hatch: the bounded expression engine over named device bindings.
@@ -42039,6 +42083,28 @@ function convertLegacyRecipe(legacy) {
42039
42083
  * it. The output type is always the new one.
42040
42084
  */
42041
42085
  var AutomationRecipeSchema = union([CurrentAutomationRecipeSchema, LegacyAutomationRecipeSchema.transform(convertLegacyRecipe)]);
42086
+ var DETECTION_DESCRIPTIONS = {
42087
+ deviceId: "the camera that saw it",
42088
+ className: "what it saw",
42089
+ trackId: "the track",
42090
+ score: "how sure the detector was",
42091
+ label: "the label it matched (a name, a plate), empty when none"
42092
+ };
42093
+ var STATIONARY_DESCRIPTIONS = {
42094
+ deviceId: "the camera that saw it",
42095
+ className: "what it saw",
42096
+ zones: "the zones it is in",
42097
+ phase: "appeared or departed",
42098
+ entryId: "the stopped object"
42099
+ };
42100
+ function describe$1(descriptions) {
42101
+ return Object.entries(descriptions).map(([name, description]) => ({
42102
+ name,
42103
+ description
42104
+ }));
42105
+ }
42106
+ describe$1(DETECTION_DESCRIPTIONS);
42107
+ describe$1(STATIONARY_DESCRIPTIONS);
42042
42108
  new Set(Object.values(COCO_TO_MACRO.mapping));
42043
42109
  /**
42044
42110
  * Schedulers (D983) — an entity that performs actions over the day.
@@ -49117,6 +49183,45 @@ method(_void(), _void(), { kind: "mutation" }), method(_void(), _void(), { kind:
49117
49183
  auth: "admin"
49118
49184
  });
49119
49185
  /**
49186
+ * What the passive listener of `local-network` saw on the wire, before any
49187
+ * provider classified it. Device-manager turns an observation into the hits
49188
+ * of the providers whose declared discovery modes it matches.
49189
+ */
49190
+ var DiscoveryObservationSchema = discriminatedUnion("kind", [object({
49191
+ kind: literal("mdns"),
49192
+ /** Normalised DNS-SD service type, e.g. `_esphomelib._tcp`. */
49193
+ serviceType: string(),
49194
+ instance: string(),
49195
+ host: string(),
49196
+ /** The A record address when the announcement carried one. */
49197
+ address: string().nullable(),
49198
+ port: number().int(),
49199
+ txt: record(string(), string())
49200
+ }), object({
49201
+ kind: literal("ssdp"),
49202
+ /** Sender address of the datagram. */
49203
+ host: string(),
49204
+ port: number().int(),
49205
+ /** `NT` of a NOTIFY, `ST` of a search response. */
49206
+ target: string(),
49207
+ headers: record(string(), string())
49208
+ })]);
49209
+ object({
49210
+ addonId: string(),
49211
+ candidate: DiscoveryCandidateSchema,
49212
+ firstSeenAt: number(),
49213
+ lastSeenAt: number(),
49214
+ dismissed: boolean()
49215
+ });
49216
+ var DiscoveryProposalSchema = object({
49217
+ id: string(),
49218
+ addonId: string(),
49219
+ candidate: DiscoveryCandidateSchema,
49220
+ firstSeenAt: number(),
49221
+ lastSeenAt: number(),
49222
+ dismissed: boolean()
49223
+ });
49224
+ /**
49120
49225
  * Device Manager capability — hub-side singleton that unifies device persistence,
49121
49226
  * live registry access, and all management operations into a single tRPC surface.
49122
49227
  *
@@ -49845,6 +49950,19 @@ method(object({
49845
49950
  }), object({ candidates: array(DiscoveryCandidateSchema).readonly() }), {
49846
49951
  kind: "mutation",
49847
49952
  auth: "admin"
49953
+ }), method(object({}), object({ proposals: array(DiscoveryProposalSchema).readonly() }), { auth: "admin" }), method(object({ id: string() }), object({ dismissed: boolean() }), {
49954
+ kind: "mutation",
49955
+ auth: "admin"
49956
+ }), method(object({ observations: array(DiscoveryObservationSchema).max(512) }), object({ proposed: number().int() }), {
49957
+ kind: "mutation",
49958
+ auth: "admin"
49959
+ }), method(object({}), object({
49960
+ providers: number().int(),
49961
+ proposed: number().int()
49962
+ }), {
49963
+ kind: "mutation",
49964
+ auth: "admin",
49965
+ timeoutMs: 12e4
49848
49966
  }), method(object({ addonId: string() }), object({ deviceType: _enum(DeviceType).nullable() }), { auth: "admin" }), method(object({ addonId: string() }), unknown(), { auth: "admin" }), method(object({
49849
49967
  deviceId: number(),
49850
49968
  key: string(),
@@ -51210,6 +51328,19 @@ method(_void(), paletteResultSchema, {
51210
51328
  kind: "mutation",
51211
51329
  auth: "admin"
51212
51330
  });
51331
+ object({
51332
+ /** True while Do Not Disturb is on; null when unknown. */
51333
+ enabled: boolean().nullable().meta({ label: "Do not disturb" }),
51334
+ /** Ms epoch of the last read or write that set `enabled`. */
51335
+ lastChangedAt: number()
51336
+ });
51337
+ DeviceType.MediaPlayer, method(object({
51338
+ deviceId: number().int(),
51339
+ enabled: boolean()
51340
+ }), _void(), {
51341
+ kind: "mutation",
51342
+ auth: "protected"
51343
+ });
51213
51344
  DeviceType.Camera;
51214
51345
  object({
51215
51346
  /** Ms epoch of the last press. null = never observed since this provider started. */
@@ -53080,6 +53211,14 @@ var LlmGenerateBaseInputSchema = object({
53080
53211
  topP: number().min(0).max(1).optional(),
53081
53212
  /** Per-call override of the profile default (top-k sampling). */
53082
53213
  topK: number().int().positive().optional(),
53214
+ /** Per-call override of `profile.reasoningEffort`. Sent only to a kind whose
53215
+ * descriptor offers the field; a kind that does not never sends it. */
53216
+ reasoningEffort: _enum([
53217
+ "off",
53218
+ "low",
53219
+ "medium",
53220
+ "high"
53221
+ ]).optional(),
53083
53222
  /** Per-call override of `profile.timeoutMs` — the total generation bound. */
53084
53223
  timeoutMs: number().int().positive().optional(),
53085
53224
  /** Per-call override; beats both the consumer table and the profile. */
@@ -53371,7 +53510,10 @@ var LlmProfileKindSchema = string().regex(/^[a-z0-9][a-z0-9-]{0,63}$/, "a kind i
53371
53510
  var LlmModelFeaturesSchema = object({
53372
53511
  vision: boolean(),
53373
53512
  tools: boolean(),
53374
- streaming: boolean()
53513
+ streaming: boolean(),
53514
+ /** Whether the model thinks before it answers. `null` = the endpoint does not
53515
+ * say; an editor then still offers the switch (unknown is not "no"). */
53516
+ reasoning: boolean().nullable().optional()
53375
53517
  });
53376
53518
  /** One model a provider offers. `features` overrides the kind's defaults, per field. */
53377
53519
  var LlmModelInfoSchema = object({
@@ -70119,9 +70261,17 @@ var ServerUpdateActionResultSchema = object({
70119
70261
  */
70120
70262
  requiredAddonUpdates: array(RequiredAddonUpdateSchema).optional()
70121
70263
  });
70122
- var LaunchOverridesSchema = object({
70123
- /** The persisted heap ceiling in MB, or `null` when none is set. */
70124
- heapMb: number().int().nullable() });
70264
+ var LaunchOverridesSchema = object({
70265
+ /** The persisted heap ceiling in MB, or `null` when none is set. */
70266
+ heapMb: number().int().nullable(),
70267
+ /** The persisted hub-main RSS budget in MB, or `null` when none is set. */
70268
+ rssBudgetMb: number().int().nullable()
70269
+ });
70270
+ var SetLaunchOverridesInputSchema = object({
70271
+ heapMb: number().int().min(512).max(65536).nullable(),
70272
+ /** Omitted keeps the stored budget; `null` clears it. */
70273
+ rssBudgetMb: number().int().min(512).max(65536).nullable().optional()
70274
+ });
70125
70275
  var SetLaunchOverridesResultSchema = LaunchOverridesSchema.extend({
70126
70276
  /** Always true: the override is read at launch, not by the running process. */
70127
70277
  restartRequired: boolean() });
@@ -70150,7 +70300,7 @@ method(_void(), ServerPackageStatusSchema, { auth: "admin" }), method(_void(), S
70150
70300
  }), method(_void(), ServerUpdateActionResultSchema, {
70151
70301
  kind: "mutation",
70152
70302
  auth: "admin"
70153
- }), method(_void(), LaunchOverridesSchema, { auth: "admin" }), method(object({ heapMb: number().int().min(512).max(65536).nullable() }), SetLaunchOverridesResultSchema, {
70303
+ }), method(_void(), LaunchOverridesSchema, { auth: "admin" }), method(SetLaunchOverridesInputSchema, SetLaunchOverridesResultSchema, {
70154
70304
  kind: "mutation",
70155
70305
  auth: "admin"
70156
70306
  });
@@ -71599,6 +71749,40 @@ var LoggingSettingsStateSchema = object({
71599
71749
  opsLogRetentionDays: number().int().min(0),
71600
71750
  persisted: boolean()
71601
71751
  });
71752
+ /**
71753
+ * Debug WATCH — a short, per-device window over `debug.<channel>` lines.
71754
+ *
71755
+ * `start` opens (or re-arms) a 10 minute window; `rearm` extends a LIVE one
71756
+ * and never revives a lapsed one; `stop` closes it; `list` only reads. No
71757
+ * chain of re-arms outlives 60 minutes from the first start. The hub holds the
71758
+ * watches in memory and pushes the interest to every node, so a watch lapses
71759
+ * by itself and survives nothing — a restart is a stop.
71760
+ */
71761
+ var DebugWatchInputSchema = object({
71762
+ action: _enum([
71763
+ "list",
71764
+ "start",
71765
+ "rearm",
71766
+ "stop"
71767
+ ]),
71768
+ /** Full channel names, `debug.<channel>`, each declared with `kind: 'debug'`. */
71769
+ channels: array(string().min(1)).readonly().default([]),
71770
+ /** Numeric device ids. Required (non-empty) for `start`. */
71771
+ deviceIds: array(number().int()).readonly().default([])
71772
+ });
71773
+ var DebugWatchStateSchema = object({
71774
+ channel: string(),
71775
+ deviceIds: array(number().int()).readonly(),
71776
+ startedAtMs: number(),
71777
+ untilMs: number(),
71778
+ capAtMs: number()
71779
+ });
71780
+ var DebugWatchResultSchema = object({
71781
+ nowMs: number(),
71782
+ watches: array(DebugWatchStateSchema).readonly(),
71783
+ /** Channels a `rearm` found already lapsed: nothing was revived. */
71784
+ lapsed: array(string()).readonly()
71785
+ });
71602
71786
  method(_void(), SystemInfoSchema), method(_void(), HealthStatusSchema), method(_void(), FeatureManifestSchema), method(_void(), array(NetworkAddressSchema).readonly()), method(_void(), unknown().nullable(), { auth: "admin" }), method(record(string(), unknown()), _null(), {
71603
71787
  kind: "mutation",
71604
71788
  auth: "admin"
@@ -71614,6 +71798,9 @@ method(_void(), SystemInfoSchema), method(_void(), HealthStatusSchema), method(_
71614
71798
  }), method(_void(), RequestCensusStatusSchema, { auth: "admin" }), method(_void(), array(ReportedLoadContributionSchema).readonly(), { auth: "admin" }), method(_void(), array(ReportedFailureContributionSchema).readonly(), { auth: "admin" }), method(GetLoggingSettingsInputSchema, LoggingSettingsStateSchema, { auth: "admin" }), method(SetLoggingSettingsInputSchema, LoggingSettingsStateSchema, {
71615
71799
  kind: "mutation",
71616
71800
  auth: "admin"
71801
+ }), method(DebugWatchInputSchema, DebugWatchResultSchema, {
71802
+ kind: "mutation",
71803
+ auth: "admin"
71617
71804
  });
71618
71805
  object({
71619
71806
  /** True when the device's tamper switch / case-open contact is
@@ -76487,6 +76674,13 @@ Object.freeze({
76487
76674
  access: "view",
76488
76675
  role: "admin"
76489
76676
  },
76677
+ "deviceManager.dismissDiscoveryProposal": {
76678
+ capName: "device-manager",
76679
+ capScope: "system",
76680
+ addonId: null,
76681
+ access: "create",
76682
+ role: "admin"
76683
+ },
76490
76684
  "deviceManager.enable": {
76491
76685
  capName: "device-manager",
76492
76686
  capScope: "system",
@@ -76669,6 +76863,13 @@ Object.freeze({
76669
76863
  access: "view",
76670
76864
  role: "viewer"
76671
76865
  },
76866
+ "deviceManager.listDiscoveryProposals": {
76867
+ capName: "device-manager",
76868
+ capScope: "system",
76869
+ addonId: null,
76870
+ access: "view",
76871
+ role: "admin"
76872
+ },
76672
76873
  "deviceManager.listLocationDescriptions": {
76673
76874
  capName: "device-manager",
76674
76875
  capScope: "system",
@@ -76823,6 +77024,13 @@ Object.freeze({
76823
77024
  access: "create",
76824
77025
  role: "admin"
76825
77026
  },
77027
+ "deviceManager.reportDiscoveryObservations": {
77028
+ capName: "device-manager",
77029
+ capScope: "system",
77030
+ addonId: null,
77031
+ access: "create",
77032
+ role: "admin"
77033
+ },
76826
77034
  "deviceManager.runDeviceAction": {
76827
77035
  capName: "device-manager",
76828
77036
  capScope: "system",
@@ -76830,6 +77038,13 @@ Object.freeze({
76830
77038
  access: "create",
76831
77039
  role: "admin"
76832
77040
  },
77041
+ "deviceManager.runDiscoverySweep": {
77042
+ capName: "device-manager",
77043
+ capScope: "system",
77044
+ addonId: null,
77045
+ access: "create",
77046
+ role: "admin"
77047
+ },
76833
77048
  "deviceManager.setChildLayout": {
76834
77049
  capName: "device-manager",
76835
77050
  capScope: "system",
@@ -77383,6 +77598,20 @@ Object.freeze({
77383
77598
  access: "create",
77384
77599
  role: "admin"
77385
77600
  },
77601
+ "doNotDisturb.getStatus": {
77602
+ capName: "do-not-disturb",
77603
+ capScope: "device",
77604
+ addonId: null,
77605
+ access: "view",
77606
+ role: "viewer"
77607
+ },
77608
+ "doNotDisturb.setEnabled": {
77609
+ capName: "do-not-disturb",
77610
+ capScope: "device",
77611
+ addonId: null,
77612
+ access: "create",
77613
+ role: "viewer"
77614
+ },
77386
77615
  "doorbell.getStatus": {
77387
77616
  capName: "doorbell",
77388
77617
  capScope: "device",
@@ -83403,6 +83632,13 @@ Object.freeze({
83403
83632
  access: "create",
83404
83633
  role: "viewer"
83405
83634
  },
83635
+ "system.debugWatch": {
83636
+ capName: "system",
83637
+ capScope: "system",
83638
+ addonId: null,
83639
+ access: "create",
83640
+ role: "admin"
83641
+ },
83406
83642
  "system.detectSiteLocation": {
83407
83643
  capName: "system",
83408
83644
  capScope: "system",
@@ -85571,6 +85807,16 @@ Object.freeze({
85571
85807
  form: "single",
85572
85808
  optional: false
85573
85809
  }],
85810
+ "doNotDisturb.getStatus": [{
85811
+ name: "deviceId",
85812
+ form: "single",
85813
+ optional: false
85814
+ }],
85815
+ "doNotDisturb.setEnabled": [{
85816
+ name: "deviceId",
85817
+ form: "single",
85818
+ optional: false
85819
+ }],
85574
85820
  "doorbell.getStatus": [{
85575
85821
  name: "deviceId",
85576
85822
  form: "single",
@@ -87311,6 +87557,11 @@ Object.freeze({
87311
87557
  form: "single",
87312
87558
  optional: false
87313
87559
  }],
87560
+ "system.debugWatch": [{
87561
+ name: "deviceIds",
87562
+ form: "array",
87563
+ optional: true
87564
+ }],
87314
87565
  "tamper.getStatus": [{
87315
87566
  name: "deviceId",
87316
87567
  form: "single",
@@ -89030,7 +89281,7 @@ var AgentUIAddon = class extends BaseAddon {
89030
89281
  capability: adminUiCapability,
89031
89282
  provider: {
89032
89283
  getStaticDir: async () => ({ staticDir: path.resolve(__dirname) }),
89033
- getVersion: async () => ({ version: "1.2.311" })
89284
+ getVersion: async () => ({ version: "1.2.313" })
89034
89285
  }
89035
89286
  }];
89036
89287
  }
@@ -1 +1 @@
1
- import{a as e,i as t,l as n,n as r,o as i}from"./scheduler-0XZJE03d.js";import{c as a,d as o,g as s,l as c,p as l,t as u,w as d}from"./index-Bgj6iIN6.js";import{MaskShapeCanvas as f}from"./MaskShapeCanvas-BTvl6Rin.js";var p=d(`grid-2x2`,[[`path`,{d:`M12 3v18`,key:`108xh3`}],[`path`,{d:`M3 12h18`,key:`1i2n21`}],[`rect`,{x:`3`,y:`3`,width:`18`,height:`18`,rx:`2`,key:`h1oib`}]]),m=n(i(),1),h=n(e(),1),g=110,_=`motion-zones`,v=0,y=[1,2,3],b=1,x=`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`,S=`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`;function C(e,t,n){let r=t*n,i=Array.from({length:r});for(let t=0;t<r;t+=1)i[t]=e[t]===!0;return i}function w(e,t){if(e.length!==t.length)return!1;for(let n=0;n<e.length;n+=1)if(e[n]!==t[n])return!1;return!0}function T(e,t){return Math.ceil(e/t)}function E(e,t,n){return Math.min(n-1,Math.floor((e+.5)/t*n))}function D(e,t,n,r){let i=T(t,r),a=T(n,r),o=Array.from({length:i*a},()=>!1);for(let r=0;r<n;r+=1){let s=E(r,n,a);for(let n=0;n<t;n+=1)e[r*t+n]===!0&&(o[s*i+E(n,t,i)]=!0)}return o}function O(e,t,n,r){let i=T(t,r),a=T(n,r),o=Array.from({length:t*n},()=>!1);for(let r=0;r<n;r+=1){let s=E(r,n,a);for(let n=0;n<t;n+=1)o[r*t+n]=e[s*i+E(n,t,i)]===!0}return o}function k({deviceId:e}){let n=t(),i=o(s().trpcClient,e),[d,E]=(0,m.useState)(null),[k,A]=(0,m.useState)(!1),[j,M]=(0,m.useState)(null),[N,P]=(0,m.useState)(null),[F,I]=(0,m.useState)(b),[L,R]=(0,m.useState)(!1),[z,B]=(0,m.useState)(!1),V=(0,m.useRef)(!1);(0,m.useEffect)(()=>{if(!i)return;let e=!1;return V.current=!1,E(null),A(!1),M(null),P(null),I(b),B(!1),(async()=>{try{let t=await i.motionZones?.getOptions({});if(e)return;if(!t)throw Error(`device proxy not ready`);if(E(t),V.current)return;let n=await i.motionZones?.getStatus({});if(e)return;if(!n)throw Error(`device proxy not ready`);V.current=!0;let r=n.regions.find(e=>e.shape.kind===`grid`),a=C(r?r.shape.cells:[],t.grid.width,t.grid.height);P(a),M(D(a,t.grid.width,t.grid.height,b))}catch(t){if(e)return;c(t)?A(!0):console.error(`Motion Zones load failed`,t)}})(),()=>{e=!0}},[i]);let H=d?d.grid.width:0,U=d?d.grid.height:0,W=T(H,F),G=T(U,F),K=(0,m.useMemo)(()=>j&&d?O(j,H,U,F):null,[j,d,H,U,F]),q=(0,m.useMemo)(()=>K!==null&&N!==null&&!w(K,N),[K,N]),J=(0,m.useMemo)(()=>K?K.reduce((e,t)=>t?e+1:e,0):0,[K]),Y=H*U,X=W*G,Z=(0,m.useCallback)(e=>{X>0&&M(Array.from({length:X},()=>e))},[X]),ee=(0,m.useCallback)(()=>{M(e=>e&&e.map(e=>!e))},[]),te=(0,m.useCallback)(()=>{N&&d&&M(D(N,H,U,F))},[N,d,H,U,F]),ne=(0,m.useCallback)(e=>{e===F||!d||M(t=>{if(!t)return I(e),t;let n=D(O(t,H,U,F),H,U,e);return I(e),n})},[F,d,H,U]),Q=(0,m.useMemo)(()=>d&&j?[{id:v,shape:{kind:`grid`,gridWidth:W,gridHeight:G,cells:[...j]}}]:[],[d,j,W,G]),$=(0,m.useCallback)((e,t)=>{t.kind===`grid`&&M(t.cells)},[]),re=(0,m.useCallback)(async()=>{if(!(!i||!j||!d)){R(!0);try{let e=O(j,d.grid.width,d.grid.height,F),t={kind:`grid`,gridWidth:d.grid.width,gridHeight:d.grid.height,cells:e};await i.motionZones?.setZone({patch:{regions:[{id:v,enabled:!0,shape:t}]}});let n=await i.motionZones?.getStatus({});if(n){let e=n.regions.find(e=>e.shape.kind===`grid`),t=C(e?e.shape.cells:[],d.grid.width,d.grid.height);P(t),M(D(t,d.grid.width,d.grid.height,F))}}catch(e){console.error(`Motion Zones save failed`,e)}finally{R(!1)}}},[i,j,d,F]);u((0,m.useMemo)(()=>z&&!k&&d&&j?{id:_,order:g,node:(0,h.jsx)(f,{transparent:!0,items:Q,supportedShapes:[`grid`],grid:{width:W,height:G},selectedId:v,onSelect:()=>{},onShapeChange:$,onDrawComplete:()=>{},drawingKind:null})}:null,[z,k,d,j,Q,$,W,G]));let ie=!k&&d!==null&&j!==null;return i?(0,h.jsx)(l,{title:n(`uiLibrary.motionZones.title`,`Motion Zones`),icon:(0,h.jsx)(p,{className:`h-3.5 w-3.5 text-foreground-subtle`}),children:(0,h.jsx)(`div`,{className:`flex flex-col gap-3`,children:k?(0,h.jsx)(`p`,{className:`${a} leading-relaxed`,children:n(`uiLibrary.motionZones.unsupported`,`This camera doesn't expose an on-board motion zones grid.`)}):ie?(0,h.jsxs)(h.Fragment,{children:[(0,h.jsx)(`p`,{className:`${a} leading-relaxed`,children:(0,h.jsx)(r,{uiKey:`uiLibrary.motionZones.intro`,fallback:`Toggle <0>Edit grid</0> to paint the region directly on the live frame, then <1>Save</1> to push the mask to the camera. Pick a bigger <2>Cell size</2> for quicker, broad-stroke painting — it's resampled to the camera's native {{width}}×{{height}} grid on save (×1 is the finest).`,components:[(0,h.jsx)(`strong`,{className:`text-foreground`},`e`),(0,h.jsx)(`strong`,{className:`text-foreground`},`s`),(0,h.jsx)(`strong`,{className:`text-foreground`},`c`)],values:{width:d.grid.width,height:d.grid.height}})}),(0,h.jsxs)(`div`,{className:`flex items-center gap-2 flex-wrap`,children:[(0,h.jsx)(`button`,{type:`button`,onClick:()=>B(e=>!e),disabled:L,"aria-pressed":z,className:z?S:x,children:z?n(`uiLibrary.motionZones.doneEditing`,`Done editing`):n(`uiLibrary.motionZones.editGrid`,`Edit grid`)}),(0,h.jsx)(`button`,{type:`button`,onClick:()=>Z(!0),disabled:L,className:x,children:n(`uiLibrary.motionZones.allOn`,`All on`)}),(0,h.jsx)(`button`,{type:`button`,onClick:()=>Z(!1),disabled:L,className:x,children:n(`uiLibrary.motionZones.allOff`,`All off`)}),(0,h.jsx)(`button`,{type:`button`,onClick:ee,disabled:L,className:x,children:n(`uiLibrary.motionZones.invert`,`Invert`)}),(0,h.jsxs)(`div`,{className:`flex items-center gap-1 ml-1`,role:`group`,"aria-label":n(`uiLibrary.motionZones.cellSize`,`Cell size`),children:[(0,h.jsx)(`span`,{className:`${a} mr-0.5`,children:n(`uiLibrary.motionZones.cellSize`,`Cell size`)}),y.map(e=>(0,h.jsxs)(`button`,{type:`button`,onClick:()=>ne(e),disabled:L,"aria-pressed":F===e,title:e===1?n(`uiLibrary.motionZones.cameraGrid`,`Camera grid {{width}}×{{height}} (finest)`,{width:H,height:U}):n(`uiLibrary.motionZones.paintingGrid`,`{{width}}×{{height}} painting grid · cells ×{{factor}} bigger`,{width:T(H,e),height:T(U,e),factor:e}),className:F===e?S:x,children:[`×`,e]},e))]}),(0,h.jsxs)(`span`,{className:`${a} ml-1 tabular-nums`,children:[n(`uiLibrary.motionZones.cells`,`{{active}} / {{total}} cells · {{width}}×{{height}}`,{active:J,total:Y,width:d.grid.width,height:d.grid.height}),F===1?``:n(`uiLibrary.motionZones.paintSuffix`,` · paint {{width}}×{{height}}`,{width:W,height:G})]}),(0,h.jsx)(`span`,{className:`flex-1`}),(0,h.jsx)(`button`,{type:`button`,onClick:te,disabled:L||!q,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`,children:n(`uiLibrary.motionZones.revert`,`Revert`)}),(0,h.jsx)(`button`,{type:`button`,onClick:()=>void re(),disabled:L||!q,className:S,children:L?n(`uiLibrary.motionZones.saving`,`Saving…`):n(`uiLibrary.motionZones.save`,`Save`)})]})]}):(0,h.jsx)(`p`,{className:`${a} leading-relaxed`,children:n(`uiLibrary.motionZones.loading`,`Loading the camera's grid…`)})})}):null}export{k as MotionZonesSettings};
1
+ import{a as e,i as t,l as n,n as r,o as i}from"./scheduler-0XZJE03d.js";import{c as a,d as o,g as s,l as c,p as l,t as u,w as d}from"./index-D5vO_ttL.js";import{MaskShapeCanvas as f}from"./MaskShapeCanvas-BTvl6Rin.js";var p=d(`grid-2x2`,[[`path`,{d:`M12 3v18`,key:`108xh3`}],[`path`,{d:`M3 12h18`,key:`1i2n21`}],[`rect`,{x:`3`,y:`3`,width:`18`,height:`18`,rx:`2`,key:`h1oib`}]]),m=n(i(),1),h=n(e(),1),g=110,_=`motion-zones`,v=0,y=[1,2,3],b=1,x=`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`,S=`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`;function C(e,t,n){let r=t*n,i=Array.from({length:r});for(let t=0;t<r;t+=1)i[t]=e[t]===!0;return i}function w(e,t){if(e.length!==t.length)return!1;for(let n=0;n<e.length;n+=1)if(e[n]!==t[n])return!1;return!0}function T(e,t){return Math.ceil(e/t)}function E(e,t,n){return Math.min(n-1,Math.floor((e+.5)/t*n))}function D(e,t,n,r){let i=T(t,r),a=T(n,r),o=Array.from({length:i*a},()=>!1);for(let r=0;r<n;r+=1){let s=E(r,n,a);for(let n=0;n<t;n+=1)e[r*t+n]===!0&&(o[s*i+E(n,t,i)]=!0)}return o}function O(e,t,n,r){let i=T(t,r),a=T(n,r),o=Array.from({length:t*n},()=>!1);for(let r=0;r<n;r+=1){let s=E(r,n,a);for(let n=0;n<t;n+=1)o[r*t+n]=e[s*i+E(n,t,i)]===!0}return o}function k({deviceId:e}){let n=t(),i=o(s().trpcClient,e),[d,E]=(0,m.useState)(null),[k,A]=(0,m.useState)(!1),[j,M]=(0,m.useState)(null),[N,P]=(0,m.useState)(null),[F,I]=(0,m.useState)(b),[L,R]=(0,m.useState)(!1),[z,B]=(0,m.useState)(!1),V=(0,m.useRef)(!1);(0,m.useEffect)(()=>{if(!i)return;let e=!1;return V.current=!1,E(null),A(!1),M(null),P(null),I(b),B(!1),(async()=>{try{let t=await i.motionZones?.getOptions({});if(e)return;if(!t)throw Error(`device proxy not ready`);if(E(t),V.current)return;let n=await i.motionZones?.getStatus({});if(e)return;if(!n)throw Error(`device proxy not ready`);V.current=!0;let r=n.regions.find(e=>e.shape.kind===`grid`),a=C(r?r.shape.cells:[],t.grid.width,t.grid.height);P(a),M(D(a,t.grid.width,t.grid.height,b))}catch(t){if(e)return;c(t)?A(!0):console.error(`Motion Zones load failed`,t)}})(),()=>{e=!0}},[i]);let H=d?d.grid.width:0,U=d?d.grid.height:0,W=T(H,F),G=T(U,F),K=(0,m.useMemo)(()=>j&&d?O(j,H,U,F):null,[j,d,H,U,F]),q=(0,m.useMemo)(()=>K!==null&&N!==null&&!w(K,N),[K,N]),J=(0,m.useMemo)(()=>K?K.reduce((e,t)=>t?e+1:e,0):0,[K]),Y=H*U,X=W*G,Z=(0,m.useCallback)(e=>{X>0&&M(Array.from({length:X},()=>e))},[X]),ee=(0,m.useCallback)(()=>{M(e=>e&&e.map(e=>!e))},[]),te=(0,m.useCallback)(()=>{N&&d&&M(D(N,H,U,F))},[N,d,H,U,F]),ne=(0,m.useCallback)(e=>{e===F||!d||M(t=>{if(!t)return I(e),t;let n=D(O(t,H,U,F),H,U,e);return I(e),n})},[F,d,H,U]),Q=(0,m.useMemo)(()=>d&&j?[{id:v,shape:{kind:`grid`,gridWidth:W,gridHeight:G,cells:[...j]}}]:[],[d,j,W,G]),$=(0,m.useCallback)((e,t)=>{t.kind===`grid`&&M(t.cells)},[]),re=(0,m.useCallback)(async()=>{if(!(!i||!j||!d)){R(!0);try{let e=O(j,d.grid.width,d.grid.height,F),t={kind:`grid`,gridWidth:d.grid.width,gridHeight:d.grid.height,cells:e};await i.motionZones?.setZone({patch:{regions:[{id:v,enabled:!0,shape:t}]}});let n=await i.motionZones?.getStatus({});if(n){let e=n.regions.find(e=>e.shape.kind===`grid`),t=C(e?e.shape.cells:[],d.grid.width,d.grid.height);P(t),M(D(t,d.grid.width,d.grid.height,F))}}catch(e){console.error(`Motion Zones save failed`,e)}finally{R(!1)}}},[i,j,d,F]);u((0,m.useMemo)(()=>z&&!k&&d&&j?{id:_,order:g,node:(0,h.jsx)(f,{transparent:!0,items:Q,supportedShapes:[`grid`],grid:{width:W,height:G},selectedId:v,onSelect:()=>{},onShapeChange:$,onDrawComplete:()=>{},drawingKind:null})}:null,[z,k,d,j,Q,$,W,G]));let ie=!k&&d!==null&&j!==null;return i?(0,h.jsx)(l,{title:n(`uiLibrary.motionZones.title`,`Motion Zones`),icon:(0,h.jsx)(p,{className:`h-3.5 w-3.5 text-foreground-subtle`}),children:(0,h.jsx)(`div`,{className:`flex flex-col gap-3`,children:k?(0,h.jsx)(`p`,{className:`${a} leading-relaxed`,children:n(`uiLibrary.motionZones.unsupported`,`This camera doesn't expose an on-board motion zones grid.`)}):ie?(0,h.jsxs)(h.Fragment,{children:[(0,h.jsx)(`p`,{className:`${a} leading-relaxed`,children:(0,h.jsx)(r,{uiKey:`uiLibrary.motionZones.intro`,fallback:`Toggle <0>Edit grid</0> to paint the region directly on the live frame, then <1>Save</1> to push the mask to the camera. Pick a bigger <2>Cell size</2> for quicker, broad-stroke painting — it's resampled to the camera's native {{width}}×{{height}} grid on save (×1 is the finest).`,components:[(0,h.jsx)(`strong`,{className:`text-foreground`},`e`),(0,h.jsx)(`strong`,{className:`text-foreground`},`s`),(0,h.jsx)(`strong`,{className:`text-foreground`},`c`)],values:{width:d.grid.width,height:d.grid.height}})}),(0,h.jsxs)(`div`,{className:`flex items-center gap-2 flex-wrap`,children:[(0,h.jsx)(`button`,{type:`button`,onClick:()=>B(e=>!e),disabled:L,"aria-pressed":z,className:z?S:x,children:z?n(`uiLibrary.motionZones.doneEditing`,`Done editing`):n(`uiLibrary.motionZones.editGrid`,`Edit grid`)}),(0,h.jsx)(`button`,{type:`button`,onClick:()=>Z(!0),disabled:L,className:x,children:n(`uiLibrary.motionZones.allOn`,`All on`)}),(0,h.jsx)(`button`,{type:`button`,onClick:()=>Z(!1),disabled:L,className:x,children:n(`uiLibrary.motionZones.allOff`,`All off`)}),(0,h.jsx)(`button`,{type:`button`,onClick:ee,disabled:L,className:x,children:n(`uiLibrary.motionZones.invert`,`Invert`)}),(0,h.jsxs)(`div`,{className:`flex items-center gap-1 ml-1`,role:`group`,"aria-label":n(`uiLibrary.motionZones.cellSize`,`Cell size`),children:[(0,h.jsx)(`span`,{className:`${a} mr-0.5`,children:n(`uiLibrary.motionZones.cellSize`,`Cell size`)}),y.map(e=>(0,h.jsxs)(`button`,{type:`button`,onClick:()=>ne(e),disabled:L,"aria-pressed":F===e,title:e===1?n(`uiLibrary.motionZones.cameraGrid`,`Camera grid {{width}}×{{height}} (finest)`,{width:H,height:U}):n(`uiLibrary.motionZones.paintingGrid`,`{{width}}×{{height}} painting grid · cells ×{{factor}} bigger`,{width:T(H,e),height:T(U,e),factor:e}),className:F===e?S:x,children:[`×`,e]},e))]}),(0,h.jsxs)(`span`,{className:`${a} ml-1 tabular-nums`,children:[n(`uiLibrary.motionZones.cells`,`{{active}} / {{total}} cells · {{width}}×{{height}}`,{active:J,total:Y,width:d.grid.width,height:d.grid.height}),F===1?``:n(`uiLibrary.motionZones.paintSuffix`,` · paint {{width}}×{{height}}`,{width:W,height:G})]}),(0,h.jsx)(`span`,{className:`flex-1`}),(0,h.jsx)(`button`,{type:`button`,onClick:te,disabled:L||!q,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`,children:n(`uiLibrary.motionZones.revert`,`Revert`)}),(0,h.jsx)(`button`,{type:`button`,onClick:()=>void re(),disabled:L||!q,className:S,children:L?n(`uiLibrary.motionZones.saving`,`Saving…`):n(`uiLibrary.motionZones.save`,`Save`)})]})]}):(0,h.jsx)(`p`,{className:`${a} leading-relaxed`,children:n(`uiLibrary.motionZones.loading`,`Loading the camera's grid…`)})})}):null}export{k as MotionZonesSettings};
@@ -1 +1 @@
1
- import{a as e,i as t,l as n,n as r,o as i}from"./scheduler-0XZJE03d.js";import{S as ee,_ as a,b as te,c as o,d as ne,g as s,l as c,p as re,t as l,v as u,w as d}from"./index-Bgj6iIN6.js";import{MaskShapeCanvas as ie}from"./MaskShapeCanvas-BTvl6Rin.js";var ae=d(`hexagon`,[[`path`,{d:`M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z`,key:`yt0hxn`}]]),oe=d(`mic-off`,[[`path`,{d:`M12 19v3`,key:`npa21l`}],[`path`,{d:`M15 9.34V5a3 3 0 0 0-5.68-1.33`,key:`1gzdoj`}],[`path`,{d:`M16.95 16.95A7 7 0 0 1 5 12v-2`,key:`cqa7eg`}],[`path`,{d:`M18.89 13.23A7 7 0 0 0 19 12v-2`,key:`16hl24`}],[`path`,{d:`m2 2 20 20`,key:`1ooewy`}],[`path`,{d:`M9 9v3a3 3 0 0 0 5.12 2.12`,key:`r2i35w`}]]),f=n(i(),1),p=`Microphone`,m=`The camera encodes no audio at all — live view, recordings, exports and the audio analyzer are all silent.`;function se(e){let t=e.supportsAudioMute===!0,n=t?e.audioEnabled:null,r=e.pendingOn??null;return{label:p,supported:t,on:n===null?null:r??n,available:t&&n!==null,costWhenOff:m}}function ce(e){return!e.available||e.on===null?null:{enabled:!e.on}}var h=n(e(),1),le=120,ue=`privacy-mask`,g=`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`,_=`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`;function v(e){return e.kind===`rect`||e.kind===`polygon`?e:null}function de(e){let t=new Set(e.map(e=>e.id)),n=0;for(;t.has(n);)n+=1;return n}function fe(e,t){if(e.length!==t.length)return!1;for(let n=0;n<e.length;n+=1)if(JSON.stringify(e[n])!==JSON.stringify(t[n]))return!1;return!0}function y({deviceId:e}){let n=t(),i=ne(s().trpcClient,e),[d,p]=(0,f.useState)(null),[m,y]=(0,f.useState)(!1),[b,x]=(0,f.useState)(!1),[S,C]=(0,f.useState)(null),[w,T]=(0,f.useState)(null),[E,D]=(0,f.useState)(!1),[O,k]=(0,f.useState)(!1),[A,j]=(0,f.useState)(null),[M,N]=(0,f.useState)(null),[pe,P]=(0,f.useState)(null),[F,I]=(0,f.useState)(null),[L,R]=(0,f.useState)(null),z=(0,f.useRef)(!1);(0,f.useEffect)(()=>{if(!i)return;let e=!1;return z.current=!1,p(null),y(!1),x(!1),C(null),T(null),k(!1),j(null),N(null),P(null),I(null),R(null),(async()=>{try{let t=await i.privacyMask?.getOptions({});if(e)return;if(!t)throw Error(`device proxy not ready`);if(p(t),z.current)return;let n=await i.privacyMask?.getStatus({});if(e)return;if(!n)throw Error(`device proxy not ready`);if(n.regions===null){x(!0),P(n.audioEnabled);return}z.current=!0;let r={enabled:n.enabled,regions:n.regions};T(r),C(r),P(n.audioEnabled)}catch(t){if(e)return;c(t)?y(!0):console.error(`Privacy Mask load failed`,t)}})(),()=>{e=!0}},[i]);let B=(0,f.useMemo)(()=>S!==null&&w!==null&&(S.enabled!==w.enabled||!fe(S.regions,w.regions)),[S,w]),V=S?S.regions.length:0,H=d?d.maxRegions:0,U=(0,f.useRef)(0);(0,f.useEffect)(()=>{U.current=H},[H]);let W=H>0&&V>=H,me=(0,f.useCallback)(()=>{C(e=>e&&{...e,enabled:!e.enabled})},[]),G=(0,f.useCallback)(e=>{j(typeof e==`number`?e:null)},[]),K=(0,f.useMemo)(()=>S?S.regions.map(e=>({id:e.id,shape:e.shape,enabled:e.enabled,label:n(`uiLibrary.privacyMaskSettings.zoneN`,`Zone {{id}}`,{id:e.id})})):[],[S,n]),q=(0,f.useCallback)((e,t)=>{let n=v(t);n&&C(t=>t&&{...t,regions:t.regions.map(t=>t.id===e?{...t,shape:n}:t)})},[]),J=(0,f.useCallback)(e=>{let t=v(e);t&&(N(null),C(e=>{if(!e)return e;let n=U.current;if(n>0&&e.regions.length>=n)return e;let r=de(e.regions),i={id:r,enabled:!0,shape:t};return j(r),{...e,regions:[...e.regions,i]}}))},[]),Y=(0,f.useCallback)(e=>{k(!0),j(null),N(e)},[]),he=(0,f.useCallback)(e=>{k(!0),N(null),j(e)},[]),ge=(0,f.useCallback)(e=>{j(t=>t===e?null:t),C(t=>t&&{...t,regions:t.regions.filter(t=>t.id!==e)})},[]),_e=(0,f.useCallback)(()=>{N(null),j(null),w&&C({enabled:w.enabled,regions:w.regions})},[w]),X=(0,f.useCallback)(async()=>{if(!(!i||!S)){D(!0);try{await i.privacyMask?.setMask({patch:{enabled:S.enabled,regions:[...S.regions]}});let e=await i.privacyMask?.getStatus({});if(e&&e.regions!==null){let t={enabled:e.enabled,regions:e.regions};T(t),C(t)}}catch(e){console.error(`Privacy Mask save failed`,e)}finally{D(!1)}}},[i,S]),Z=se({supportsAudioMute:d===null?null:d.supportsAudioMute,audioEnabled:pe,pendingOn:F}),ve=(0,f.useCallback)(async()=>{let e=ce(Z);if(!(!i||e===null)){I(e.enabled),R(null);try{await i.privacyMask?.setAudioEnabled(e);let t=await i.privacyMask?.getStatus({});t&&P(t.audioEnabled)}catch(e){console.error(`Privacy microphone write failed — reverting`,e),R(e instanceof Error?e.message:String(e))}finally{I(null)}}},[i,Z]),ye=(0,f.useCallback)(()=>{k(e=>(e&&(N(null),j(null)),!e))},[]),Q=d?.supportedShapes??[];l((0,f.useMemo)(()=>O&&!m&&d&&S?{id:ue,order:le,node:(0,h.jsx)(ie,{transparent:!0,items:K,supportedShapes:Q,polygonVertices:d.polygonVertices,selectedId:A,onSelect:G,onShapeChange:q,onDrawComplete:J,drawingKind:M})}:null,[O,m,d,S,K,Q,A,G,q,J,M]));let be=d?.supportedShapes.includes(`rect`)??!1,xe=d?.supportedShapes.includes(`polygon`)??!1,$=d!==null&&(d.maxRegions<=0||d.supportedShapes.length===0),Se=!m&&!$&&!b&&d!==null&&S!==null;return i?(0,h.jsx)(re,{title:n(`uiLibrary.privacyMaskSettings.title`,`Privacy Mask`),icon:(0,h.jsx)(ee,{className:`h-3.5 w-3.5 text-foreground-subtle`}),children:(0,h.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[m||$?(0,h.jsx)(`p`,{className:`${o} leading-relaxed`,children:n(`uiLibrary.privacyMaskSettings.unsupported`,`This camera doesn't support an on-board privacy mask.`)}):b?(0,h.jsx)(`p`,{className:`${o} leading-relaxed`,children:n(`uiLibrary.privacyMaskSettings.unreadable`,`This camera hasn't answered, so what it currently masks is unknown — the editor stays closed rather than showing an empty frame you could save over. A battery camera answers once it wakes; otherwise check that it is reachable.`)}):Se?(0,h.jsxs)(h.Fragment,{children:[(0,h.jsx)(`p`,{className:`${o} leading-relaxed`,children:(0,h.jsx)(r,{uiKey:`uiLibrary.privacyMaskSettings.help`,fallback:`Toggle <0>Edit mask</0> to draw blanked-out zones on the live frame, then <1>Save</1> to push them to the camera. Drag a rectangle to move, its corner to resize; drag polygon vertices, click an edge midpoint to add one, or right-click a vertex to remove it.`,components:[(0,h.jsx)(`strong`,{className:`text-foreground`},`edit`),(0,h.jsx)(`strong`,{className:`text-foreground`},`save`)]})}),(0,h.jsxs)(`div`,{className:`flex items-center gap-2 flex-wrap`,children:[(0,h.jsx)(`button`,{type:`button`,onClick:ye,disabled:E,"aria-pressed":O,className:O?_:g,children:O?n(`uiLibrary.privacyMaskSettings.doneEditing`,`Done editing`):n(`uiLibrary.privacyMaskSettings.editMask`,`Edit mask`)}),(0,h.jsx)(`button`,{type:`button`,onClick:me,disabled:E,"aria-pressed":S.enabled,className:S.enabled?_:g,children:S.enabled?n(`uiLibrary.privacyMaskSettings.maskOn`,`Mask on`):n(`uiLibrary.privacyMaskSettings.maskOff`,`Mask off`)}),be&&(0,h.jsx)(`button`,{type:`button`,onClick:()=>Y(`rect`),disabled:E||W,"aria-pressed":M===`rect`,className:M===`rect`?_:g,title:W?n(`uiLibrary.privacyMaskSettings.maxZones`,`Maximum zones reached`):n(`uiLibrary.privacyMaskSettings.addRect`,`Add a rectangle zone`),children:n(`uiLibrary.privacyMaskSettings.rectButton`,`+ Rect`)}),xe&&(0,h.jsx)(`button`,{type:`button`,onClick:()=>Y(`polygon`),disabled:E||W,"aria-pressed":M===`polygon`,className:M===`polygon`?_:g,title:W?n(`uiLibrary.privacyMaskSettings.maxZones`,`Maximum zones reached`):n(`uiLibrary.privacyMaskSettings.addPolygon`,`Add a polygon zone`),children:n(`uiLibrary.privacyMaskSettings.polygonButton`,`+ Polygon`)}),(0,h.jsx)(`span`,{className:`${o} ml-1 tabular-nums`,children:n(`uiLibrary.privacyMaskSettings.zoneCount`,`{{active}} / {{max}} zones`,{active:V,max:H})}),(0,h.jsx)(`span`,{className:`flex-1`}),(0,h.jsx)(`button`,{type:`button`,onClick:_e,disabled:E||!B,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`,children:n(`uiLibrary.privacyMaskSettings.revert`,`Revert`)}),(0,h.jsx)(`button`,{type:`button`,onClick:()=>void X(),disabled:E||!B,className:_,children:E?n(`uiLibrary.privacyMaskSettings.saving`,`Saving…`):n(`uiLibrary.privacyMaskSettings.save`,`Save`)})]}),V>0?(0,h.jsx)(`div`,{className:`flex flex-col gap-1`,children:S.regions.map(e=>{let t=A===e.id,r=e.shape.kind===`polygon`?ae:u;return(0,h.jsxs)(`div`,{className:`flex items-center gap-2 rounded-md border px-2 py-1 transition-colors ${t?`border-primary/50 bg-primary/10`:`border-border bg-surface`}`,children:[(0,h.jsxs)(`button`,{type:`button`,onClick:()=>he(e.id),disabled:E,className:`flex flex-1 items-center gap-2 text-left text-[11px] font-medium text-foreground-subtle hover:text-foreground disabled:opacity-40 transition-colors`,children:[(0,h.jsx)(r,{className:`h-3.5 w-3.5 shrink-0`}),(0,h.jsx)(`span`,{children:n(`uiLibrary.privacyMaskSettings.zoneN`,`Zone {{id}}`,{id:e.id})}),(0,h.jsx)(`span`,{className:`text-foreground-faint capitalize`,children:e.shape.kind})]}),(0,h.jsx)(`button`,{type:`button`,onClick:()=>ge(e.id),disabled:E,"aria-label":n(`uiLibrary.privacyMaskSettings.deleteZoneN`,`Delete zone {{id}}`,{id:e.id}),title:n(`uiLibrary.privacyMaskSettings.deleteZone`,`Delete zone`),className:`inline-flex h-6 w-6 items-center justify-center rounded border border-border bg-surface text-foreground-subtle hover:border-red-400/40 hover:bg-red-500/10 hover:text-red-400 disabled:opacity-40 transition-colors`,children:(0,h.jsx)(a,{className:`h-3.5 w-3.5`})})]},e.id)})}):null]}):(0,h.jsx)(`p`,{className:`${o} leading-relaxed`,children:n(`uiLibrary.privacyMaskSettings.loading`,`Loading the camera's privacy mask…`)}),Z.supported&&(0,h.jsxs)(`div`,{className:`flex items-start gap-3 rounded-md border border-border bg-surface px-2 py-2`,children:[(0,h.jsx)(`button`,{type:`button`,role:`switch`,"aria-label":Z.label,"aria-checked":Z.on===!0,disabled:!Z.available||F!==null,onClick:()=>void ve(),title:Z.on===null?n(`uiLibrary.privacyMaskSettings.micTitleUnknown`,`Microphone — state unknown; the camera did not answer.`):Z.on?n(`uiLibrary.privacyMaskSettings.micTitleOn`,`The camera is capturing sound. Turning it off: {{cost}}`,{cost:Z.costWhenOff}):n(`uiLibrary.privacyMaskSettings.micTitleOff`,`The camera is silent. {{cost}}`,{cost:Z.costWhenOff}),className:Z.on===!1||Z.on===null?g:_,children:(0,h.jsxs)(`span`,{className:`inline-flex items-center gap-1.5`,children:[Z.on===!1?(0,h.jsx)(oe,{className:`h-3.5 w-3.5`}):(0,h.jsx)(te,{className:`h-3.5 w-3.5`}),Z.on===null?n(`uiLibrary.privacyMaskSettings.micUnknown`,`Microphone unknown`):Z.on?n(`uiLibrary.privacyMaskSettings.micOn`,`Microphone on`):n(`uiLibrary.privacyMaskSettings.micOff`,`Microphone off`)]})}),(0,h.jsx)(`p`,{className:`text-[10px] text-foreground-subtle flex-1 leading-relaxed`,children:L===null?Z.on===null?n(`uiLibrary.privacyMaskSettings.micNotReported`,`The camera did not report its microphone, so this state is unknown.`):Z.costWhenOff:n(`uiLibrary.privacyMaskSettings.writeFailed`,`Write failed: {{reason}}`,{reason:L})})]})]})}):null}export{y as PrivacyMaskSettings};
1
+ import{a as e,i as t,l as n,n as r,o as i}from"./scheduler-0XZJE03d.js";import{S as ee,_ as a,b as te,c as o,d as ne,g as s,l as c,p as re,t as l,v as u,w as d}from"./index-D5vO_ttL.js";import{MaskShapeCanvas as ie}from"./MaskShapeCanvas-BTvl6Rin.js";var ae=d(`hexagon`,[[`path`,{d:`M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z`,key:`yt0hxn`}]]),oe=d(`mic-off`,[[`path`,{d:`M12 19v3`,key:`npa21l`}],[`path`,{d:`M15 9.34V5a3 3 0 0 0-5.68-1.33`,key:`1gzdoj`}],[`path`,{d:`M16.95 16.95A7 7 0 0 1 5 12v-2`,key:`cqa7eg`}],[`path`,{d:`M18.89 13.23A7 7 0 0 0 19 12v-2`,key:`16hl24`}],[`path`,{d:`m2 2 20 20`,key:`1ooewy`}],[`path`,{d:`M9 9v3a3 3 0 0 0 5.12 2.12`,key:`r2i35w`}]]),f=n(i(),1),p=`Microphone`,m=`The camera encodes no audio at all — live view, recordings, exports and the audio analyzer are all silent.`;function se(e){let t=e.supportsAudioMute===!0,n=t?e.audioEnabled:null,r=e.pendingOn??null;return{label:p,supported:t,on:n===null?null:r??n,available:t&&n!==null,costWhenOff:m}}function ce(e){return!e.available||e.on===null?null:{enabled:!e.on}}var h=n(e(),1),le=120,ue=`privacy-mask`,g=`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`,_=`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`;function v(e){return e.kind===`rect`||e.kind===`polygon`?e:null}function de(e){let t=new Set(e.map(e=>e.id)),n=0;for(;t.has(n);)n+=1;return n}function fe(e,t){if(e.length!==t.length)return!1;for(let n=0;n<e.length;n+=1)if(JSON.stringify(e[n])!==JSON.stringify(t[n]))return!1;return!0}function y({deviceId:e}){let n=t(),i=ne(s().trpcClient,e),[d,p]=(0,f.useState)(null),[m,y]=(0,f.useState)(!1),[b,x]=(0,f.useState)(!1),[S,C]=(0,f.useState)(null),[w,T]=(0,f.useState)(null),[E,D]=(0,f.useState)(!1),[O,k]=(0,f.useState)(!1),[A,j]=(0,f.useState)(null),[M,N]=(0,f.useState)(null),[pe,P]=(0,f.useState)(null),[F,I]=(0,f.useState)(null),[L,R]=(0,f.useState)(null),z=(0,f.useRef)(!1);(0,f.useEffect)(()=>{if(!i)return;let e=!1;return z.current=!1,p(null),y(!1),x(!1),C(null),T(null),k(!1),j(null),N(null),P(null),I(null),R(null),(async()=>{try{let t=await i.privacyMask?.getOptions({});if(e)return;if(!t)throw Error(`device proxy not ready`);if(p(t),z.current)return;let n=await i.privacyMask?.getStatus({});if(e)return;if(!n)throw Error(`device proxy not ready`);if(n.regions===null){x(!0),P(n.audioEnabled);return}z.current=!0;let r={enabled:n.enabled,regions:n.regions};T(r),C(r),P(n.audioEnabled)}catch(t){if(e)return;c(t)?y(!0):console.error(`Privacy Mask load failed`,t)}})(),()=>{e=!0}},[i]);let B=(0,f.useMemo)(()=>S!==null&&w!==null&&(S.enabled!==w.enabled||!fe(S.regions,w.regions)),[S,w]),V=S?S.regions.length:0,H=d?d.maxRegions:0,U=(0,f.useRef)(0);(0,f.useEffect)(()=>{U.current=H},[H]);let W=H>0&&V>=H,me=(0,f.useCallback)(()=>{C(e=>e&&{...e,enabled:!e.enabled})},[]),G=(0,f.useCallback)(e=>{j(typeof e==`number`?e:null)},[]),K=(0,f.useMemo)(()=>S?S.regions.map(e=>({id:e.id,shape:e.shape,enabled:e.enabled,label:n(`uiLibrary.privacyMaskSettings.zoneN`,`Zone {{id}}`,{id:e.id})})):[],[S,n]),q=(0,f.useCallback)((e,t)=>{let n=v(t);n&&C(t=>t&&{...t,regions:t.regions.map(t=>t.id===e?{...t,shape:n}:t)})},[]),J=(0,f.useCallback)(e=>{let t=v(e);t&&(N(null),C(e=>{if(!e)return e;let n=U.current;if(n>0&&e.regions.length>=n)return e;let r=de(e.regions),i={id:r,enabled:!0,shape:t};return j(r),{...e,regions:[...e.regions,i]}}))},[]),Y=(0,f.useCallback)(e=>{k(!0),j(null),N(e)},[]),he=(0,f.useCallback)(e=>{k(!0),N(null),j(e)},[]),ge=(0,f.useCallback)(e=>{j(t=>t===e?null:t),C(t=>t&&{...t,regions:t.regions.filter(t=>t.id!==e)})},[]),_e=(0,f.useCallback)(()=>{N(null),j(null),w&&C({enabled:w.enabled,regions:w.regions})},[w]),X=(0,f.useCallback)(async()=>{if(!(!i||!S)){D(!0);try{await i.privacyMask?.setMask({patch:{enabled:S.enabled,regions:[...S.regions]}});let e=await i.privacyMask?.getStatus({});if(e&&e.regions!==null){let t={enabled:e.enabled,regions:e.regions};T(t),C(t)}}catch(e){console.error(`Privacy Mask save failed`,e)}finally{D(!1)}}},[i,S]),Z=se({supportsAudioMute:d===null?null:d.supportsAudioMute,audioEnabled:pe,pendingOn:F}),ve=(0,f.useCallback)(async()=>{let e=ce(Z);if(!(!i||e===null)){I(e.enabled),R(null);try{await i.privacyMask?.setAudioEnabled(e);let t=await i.privacyMask?.getStatus({});t&&P(t.audioEnabled)}catch(e){console.error(`Privacy microphone write failed — reverting`,e),R(e instanceof Error?e.message:String(e))}finally{I(null)}}},[i,Z]),ye=(0,f.useCallback)(()=>{k(e=>(e&&(N(null),j(null)),!e))},[]),Q=d?.supportedShapes??[];l((0,f.useMemo)(()=>O&&!m&&d&&S?{id:ue,order:le,node:(0,h.jsx)(ie,{transparent:!0,items:K,supportedShapes:Q,polygonVertices:d.polygonVertices,selectedId:A,onSelect:G,onShapeChange:q,onDrawComplete:J,drawingKind:M})}:null,[O,m,d,S,K,Q,A,G,q,J,M]));let be=d?.supportedShapes.includes(`rect`)??!1,xe=d?.supportedShapes.includes(`polygon`)??!1,$=d!==null&&(d.maxRegions<=0||d.supportedShapes.length===0),Se=!m&&!$&&!b&&d!==null&&S!==null;return i?(0,h.jsx)(re,{title:n(`uiLibrary.privacyMaskSettings.title`,`Privacy Mask`),icon:(0,h.jsx)(ee,{className:`h-3.5 w-3.5 text-foreground-subtle`}),children:(0,h.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[m||$?(0,h.jsx)(`p`,{className:`${o} leading-relaxed`,children:n(`uiLibrary.privacyMaskSettings.unsupported`,`This camera doesn't support an on-board privacy mask.`)}):b?(0,h.jsx)(`p`,{className:`${o} leading-relaxed`,children:n(`uiLibrary.privacyMaskSettings.unreadable`,`This camera hasn't answered, so what it currently masks is unknown — the editor stays closed rather than showing an empty frame you could save over. A battery camera answers once it wakes; otherwise check that it is reachable.`)}):Se?(0,h.jsxs)(h.Fragment,{children:[(0,h.jsx)(`p`,{className:`${o} leading-relaxed`,children:(0,h.jsx)(r,{uiKey:`uiLibrary.privacyMaskSettings.help`,fallback:`Toggle <0>Edit mask</0> to draw blanked-out zones on the live frame, then <1>Save</1> to push them to the camera. Drag a rectangle to move, its corner to resize; drag polygon vertices, click an edge midpoint to add one, or right-click a vertex to remove it.`,components:[(0,h.jsx)(`strong`,{className:`text-foreground`},`edit`),(0,h.jsx)(`strong`,{className:`text-foreground`},`save`)]})}),(0,h.jsxs)(`div`,{className:`flex items-center gap-2 flex-wrap`,children:[(0,h.jsx)(`button`,{type:`button`,onClick:ye,disabled:E,"aria-pressed":O,className:O?_:g,children:O?n(`uiLibrary.privacyMaskSettings.doneEditing`,`Done editing`):n(`uiLibrary.privacyMaskSettings.editMask`,`Edit mask`)}),(0,h.jsx)(`button`,{type:`button`,onClick:me,disabled:E,"aria-pressed":S.enabled,className:S.enabled?_:g,children:S.enabled?n(`uiLibrary.privacyMaskSettings.maskOn`,`Mask on`):n(`uiLibrary.privacyMaskSettings.maskOff`,`Mask off`)}),be&&(0,h.jsx)(`button`,{type:`button`,onClick:()=>Y(`rect`),disabled:E||W,"aria-pressed":M===`rect`,className:M===`rect`?_:g,title:W?n(`uiLibrary.privacyMaskSettings.maxZones`,`Maximum zones reached`):n(`uiLibrary.privacyMaskSettings.addRect`,`Add a rectangle zone`),children:n(`uiLibrary.privacyMaskSettings.rectButton`,`+ Rect`)}),xe&&(0,h.jsx)(`button`,{type:`button`,onClick:()=>Y(`polygon`),disabled:E||W,"aria-pressed":M===`polygon`,className:M===`polygon`?_:g,title:W?n(`uiLibrary.privacyMaskSettings.maxZones`,`Maximum zones reached`):n(`uiLibrary.privacyMaskSettings.addPolygon`,`Add a polygon zone`),children:n(`uiLibrary.privacyMaskSettings.polygonButton`,`+ Polygon`)}),(0,h.jsx)(`span`,{className:`${o} ml-1 tabular-nums`,children:n(`uiLibrary.privacyMaskSettings.zoneCount`,`{{active}} / {{max}} zones`,{active:V,max:H})}),(0,h.jsx)(`span`,{className:`flex-1`}),(0,h.jsx)(`button`,{type:`button`,onClick:_e,disabled:E||!B,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`,children:n(`uiLibrary.privacyMaskSettings.revert`,`Revert`)}),(0,h.jsx)(`button`,{type:`button`,onClick:()=>void X(),disabled:E||!B,className:_,children:E?n(`uiLibrary.privacyMaskSettings.saving`,`Saving…`):n(`uiLibrary.privacyMaskSettings.save`,`Save`)})]}),V>0?(0,h.jsx)(`div`,{className:`flex flex-col gap-1`,children:S.regions.map(e=>{let t=A===e.id,r=e.shape.kind===`polygon`?ae:u;return(0,h.jsxs)(`div`,{className:`flex items-center gap-2 rounded-md border px-2 py-1 transition-colors ${t?`border-primary/50 bg-primary/10`:`border-border bg-surface`}`,children:[(0,h.jsxs)(`button`,{type:`button`,onClick:()=>he(e.id),disabled:E,className:`flex flex-1 items-center gap-2 text-left text-[11px] font-medium text-foreground-subtle hover:text-foreground disabled:opacity-40 transition-colors`,children:[(0,h.jsx)(r,{className:`h-3.5 w-3.5 shrink-0`}),(0,h.jsx)(`span`,{children:n(`uiLibrary.privacyMaskSettings.zoneN`,`Zone {{id}}`,{id:e.id})}),(0,h.jsx)(`span`,{className:`text-foreground-faint capitalize`,children:e.shape.kind})]}),(0,h.jsx)(`button`,{type:`button`,onClick:()=>ge(e.id),disabled:E,"aria-label":n(`uiLibrary.privacyMaskSettings.deleteZoneN`,`Delete zone {{id}}`,{id:e.id}),title:n(`uiLibrary.privacyMaskSettings.deleteZone`,`Delete zone`),className:`inline-flex h-6 w-6 items-center justify-center rounded border border-border bg-surface text-foreground-subtle hover:border-red-400/40 hover:bg-red-500/10 hover:text-red-400 disabled:opacity-40 transition-colors`,children:(0,h.jsx)(a,{className:`h-3.5 w-3.5`})})]},e.id)})}):null]}):(0,h.jsx)(`p`,{className:`${o} leading-relaxed`,children:n(`uiLibrary.privacyMaskSettings.loading`,`Loading the camera's privacy mask…`)}),Z.supported&&(0,h.jsxs)(`div`,{className:`flex items-start gap-3 rounded-md border border-border bg-surface px-2 py-2`,children:[(0,h.jsx)(`button`,{type:`button`,role:`switch`,"aria-label":Z.label,"aria-checked":Z.on===!0,disabled:!Z.available||F!==null,onClick:()=>void ve(),title:Z.on===null?n(`uiLibrary.privacyMaskSettings.micTitleUnknown`,`Microphone — state unknown; the camera did not answer.`):Z.on?n(`uiLibrary.privacyMaskSettings.micTitleOn`,`The camera is capturing sound. Turning it off: {{cost}}`,{cost:Z.costWhenOff}):n(`uiLibrary.privacyMaskSettings.micTitleOff`,`The camera is silent. {{cost}}`,{cost:Z.costWhenOff}),className:Z.on===!1||Z.on===null?g:_,children:(0,h.jsxs)(`span`,{className:`inline-flex items-center gap-1.5`,children:[Z.on===!1?(0,h.jsx)(oe,{className:`h-3.5 w-3.5`}):(0,h.jsx)(te,{className:`h-3.5 w-3.5`}),Z.on===null?n(`uiLibrary.privacyMaskSettings.micUnknown`,`Microphone unknown`):Z.on?n(`uiLibrary.privacyMaskSettings.micOn`,`Microphone on`):n(`uiLibrary.privacyMaskSettings.micOff`,`Microphone off`)]})}),(0,h.jsx)(`p`,{className:`text-[10px] text-foreground-subtle flex-1 leading-relaxed`,children:L===null?Z.on===null?n(`uiLibrary.privacyMaskSettings.micNotReported`,`The camera did not report its microphone, so this state is unknown.`):Z.costWhenOff:n(`uiLibrary.privacyMaskSettings.writeFailed`,`Write failed: {{reason}}`,{reason:L})})]})]})}):null}export{y as PrivacyMaskSettings};