@camstack/addon-agent-ui 1.2.256 → 1.2.258

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/addon.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import path from "node:path";
2
2
  import { fileURLToPath } from "node:url";
3
- //#region ../types/dist/event-category-DOl51-Ij.mjs
3
+ //#region ../types/dist/event-category-BfJwUd2S.mjs
4
4
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
5
5
  EventCategory["SystemBoot"] = "system.boot";
6
6
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -317,6 +317,15 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
317
317
  */
318
318
  EventCategory["PipelineDetectionBlind"] = "pipeline.detection-blind";
319
319
  /**
320
+ * A camera's motion source has fired constantly with no subject for an hour
321
+ * (motion duty or session count over the bar, zero detections) — it is not
322
+ * blind, its motion zones or sensitivity want tuning (D907). Paired with
323
+ * {@link PipelineMotionCalm}.
324
+ */
325
+ EventCategory["PipelineMotionNoisy"] = "pipeline.motion-noisy";
326
+ /** The recovery edge of {@link PipelineMotionNoisy}: the motion fell back, or a detection arrived. */
327
+ EventCategory["PipelineMotionCalm"] = "pipeline.motion-calm";
328
+ /**
320
329
  * Per-camera pipeline config was mutated by the orchestrator
321
330
  * (3-level settings change via `setAgentAddonDefaults` /
322
331
  * `setCameraStepToggle` / `setCameraPipelineForAgent` or a
@@ -688,6 +697,14 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
688
697
  EventCategory["BackupRestored"] = "backup.restored";
689
698
  EventCategory["NotificationDispatched"] = "notification.dispatched";
690
699
  EventCategory["NotificationFailed"] = "notification.failed";
700
+ /**
701
+ * A notification rule that cannot work (D905): its stored row does not load,
702
+ * or it still names a device / delivery target the prune CONFIRMED deleted.
703
+ * One edge per rule per distinct set of reasons; never on an unanswered read.
704
+ */
705
+ EventCategory["NotificationRuleBroken"] = "notification.rule-broken";
706
+ /** The clear of {@link NotificationRuleBroken}: the rule loads and names nothing deleted. */
707
+ EventCategory["NotificationRuleRepaired"] = "notification.rule-repaired";
691
708
  EventCategory["DeviceUpdated"] = "device.updated";
692
709
  /**
693
710
  * Transport-level connectivity. Emitted by the device driver when
@@ -5415,7 +5432,7 @@ var ZodIssueCode = {
5415
5432
  var ZodFirstPartyTypeKind;
5416
5433
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5417
5434
  //#endregion
5418
- //#region ../types/dist/sleep-_sV1BE2f.mjs
5435
+ //#region ../types/dist/sleep-DJFUfKvA.mjs
5419
5436
  /**
5420
5437
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5421
5438
  * window to float samples (D455).
@@ -7877,7 +7894,7 @@ var EntryDescriptorSchema = object({
7877
7894
  /** JSON Schema of the entry body; `secret: true` marks a password field. */
7878
7895
  fields: record(string(), unknown())
7879
7896
  }).strict();
7880
- /** What crosses the wire and sits in the engine's catalog: JSON only, no Zod. */
7897
+ /** What crosses the wire from an addon: JSON only, no Zod. An unknown key is refused. */
7881
7898
  var RecordKindDeclarationSchema = object({
7882
7899
  database: _enum(RECORD_DATABASES).default("settings"),
7883
7900
  class: _enum(RECORD_CLASSES),
@@ -7896,14 +7913,6 @@ var RecordKindDeclarationSchema = object({
7896
7913
  secretPaths: array(string().min(1)).default([]),
7897
7914
  /** The id key of each array that carries a secret (`{ headers: 'name' }`). */
7898
7915
  secretArrayKeys: record(string(), string()).default({}),
7899
- /**
7900
- * RETIRED (D900): the legacy table a kind adopted from during the records
7901
- * migration. Nothing declares it any more and nothing reads it; the schema
7902
- * still ACCEPTS it because the catalog rows the migration wrote carry it
7903
- * (an orphaned kind is never redeclared) and an addon built before the
7904
- * removal still sends it. Never set it.
7905
- */
7906
- adoptsFrom: string().min(1).optional(),
7907
7916
  /** Kinds that must agree through `transact` sit in one file under one family name. */
7908
7917
  transactFamily: string().min(1).optional(),
7909
7918
  entry: EntryDescriptorSchema.optional()
@@ -12585,17 +12594,6 @@ object({
12585
12594
  createdAt: number(),
12586
12595
  updatedAt: number()
12587
12596
  });
12588
- object({
12589
- id: string(),
12590
- label: string(),
12591
- isAdmin: boolean().default(false),
12592
- allowedProviders: AllowedProviderSchema,
12593
- allowedDevices: AllowedDevicesSchema,
12594
- tokenHash: string(),
12595
- tokenPrefix: string(),
12596
- createdAt: number(),
12597
- lastUsedAt: number().optional()
12598
- });
12599
12597
  object({
12600
12598
  id: string(),
12601
12599
  userId: string(),
@@ -16471,16 +16469,36 @@ var RecordKindStateSchema = _enum([
16471
16469
  var DeclareKindResultSchema = object({
16472
16470
  kindId: number().int(),
16473
16471
  state: RecordKindStateSchema,
16474
- createdIndexes: array(string()),
16475
- /**
16476
- * RETIRED (D900): always `null`. It carried the records-migration boot guard;
16477
- * it stays on the wire, null, because an addon built before the removal reads
16478
- * an ABSENT field as "adoption pending" and refuses to start.
16479
- */
16480
- adoptionPending: _null()
16472
+ createdIndexes: array(string())
16481
16473
  });
16482
16474
  /** Keychain refs a write released (the old marker is gone from the row): the owner deletes the values. */
16483
16475
  var SecretRefsList = array(string());
16476
+ /**
16477
+ * One op of a `transact`: the single-row writes, each on a kind of the caller.
16478
+ * All ops of one call share ONE database file and ONE `transactFamily`.
16479
+ */
16480
+ var RecordTransactOpSchema = discriminatedUnion("op", [
16481
+ object({
16482
+ op: literal("put"),
16483
+ kind: RecordKindNameSchema,
16484
+ record: RecordInputSchema,
16485
+ ifRev: number().int().min(0).optional()
16486
+ }),
16487
+ object({
16488
+ op: literal("patch"),
16489
+ kind: RecordKindNameSchema,
16490
+ id: RecordIdSchema,
16491
+ data: RecordBodySchema,
16492
+ at: number().int().nullable().optional(),
16493
+ expiresAt: number().int().nullable().optional(),
16494
+ ifRev: number().int().min(1).optional()
16495
+ }),
16496
+ object({
16497
+ op: literal("delete"),
16498
+ kind: RecordKindNameSchema,
16499
+ id: RecordIdSchema
16500
+ })
16501
+ ]);
16484
16502
  var RecordSecretRefsSchema = record(string(), record(string(), string()));
16485
16503
  method(object({ kinds: record(RecordKindNameSchema, RecordKindDeclarationSchema) }), object({ kinds: record(string(), DeclareKindResultSchema) }), {
16486
16504
  kind: "mutation",
@@ -16587,6 +16605,16 @@ method(object({ kinds: record(RecordKindNameSchema, RecordKindDeclarationSchema)
16587
16605
  }), {
16588
16606
  kind: "mutation",
16589
16607
  auth: "admin"
16608
+ }), method(object({ ops: array(RecordTransactOpSchema).min(1).max(RECORD_BATCH_MAX) }), object({
16609
+ results: array(object({
16610
+ rev: number().int().nullable(),
16611
+ deleted: boolean()
16612
+ })),
16613
+ releasedRefs: SecretRefsList,
16614
+ secretRefs: SecretRefsList
16615
+ }), {
16616
+ kind: "mutation",
16617
+ auth: "admin"
16590
16618
  }), method(object({
16591
16619
  deviceId: number().int(),
16592
16620
  kinds: array(RecordKindNameSchema).optional()
@@ -41945,9 +41973,13 @@ var NcSystemEventKindSchema = _enum([
41945
41973
  "node-updating",
41946
41974
  "node-inference-unavailable",
41947
41975
  "detection-blind",
41976
+ "motion-noisy",
41977
+ "motion-calm",
41948
41978
  "recording-stalled",
41949
41979
  "recording-healthy",
41950
41980
  "recording-degraded",
41981
+ "device-attention-required",
41982
+ "device-attention-resolved",
41951
41983
  "storage-location-low",
41952
41984
  "storage-location-critical",
41953
41985
  "storage-location-ok",
@@ -41971,6 +42003,8 @@ var NcSystemEventKindSchema = _enum([
41971
42003
  "alert-critical",
41972
42004
  "alert-error",
41973
42005
  "alert-critical-resolved",
42006
+ "rule-broken",
42007
+ "rule-repaired",
41974
42008
  "camera-online",
41975
42009
  "camera-offline",
41976
42010
  "camera-disabled",
@@ -54402,6 +54436,16 @@ object({
54402
54436
  powerState: string().nullable(),
54403
54437
  saltLevel: DishwasherConsumableLevelSchema.nullable(),
54404
54438
  rinseAidLevel: DishwasherConsumableLevelSchema.nullable(),
54439
+ /**
54440
+ * True while the appliance asks for its filter to be cleaned (smart-filter, filter-system or
54441
+ * combined care-and-filter reminder raised); false when every such reminder reads clear; null
54442
+ * when none is reported. A cleared reminder is not an unknown one.
54443
+ */
54444
+ filterCleaningDue: boolean().nullable(),
54445
+ /** True while the machine-care (descaling / cleaning-program) reminder is raised; false when clear; null when not reported. */
54446
+ machineCareDue: boolean().nullable(),
54447
+ /** Program runs left before the machine-care reminder is due; null when the appliance does not say. */
54448
+ machineCareRemainingRuns: number().int().nonnegative().nullable(),
54405
54449
  /** Option states: null when the appliance does not expose the option or has not said. */
54406
54450
  halfLoad: boolean().nullable(),
54407
54451
  hygienePlus: boolean().nullable(),
@@ -61019,16 +61063,6 @@ var UpdateUserInputSchema = object({
61019
61063
  allowedDevices: record(string(), union([array(string()), literal("*")])).optional(),
61020
61064
  scopes: array(TokenScopeSchema).optional()
61021
61065
  });
61022
- var ApiKeySummarySchema = object({
61023
- id: string(),
61024
- label: string(),
61025
- isAdmin: boolean().default(false),
61026
- allowedProviders: union([array(string()), literal("*")]).optional(),
61027
- allowedDevices: record(string(), union([array(string()), literal("*")])).optional(),
61028
- tokenPrefix: string(),
61029
- createdAt: number(),
61030
- lastUsedAt: number().optional()
61031
- });
61032
61066
  var OauthSessionSummarySchema = object({
61033
61067
  id: string(),
61034
61068
  userId: string(),
@@ -61050,8 +61084,7 @@ var TotpStatusSchema = object({
61050
61084
  confirmedAt: number().nullable()
61051
61085
  });
61052
61086
  /**
61053
- * user-management — singleton capability for user accounts and the
61054
- * legacy API-key rows.
61087
+ * user-management — singleton capability for user accounts.
61055
61088
  *
61056
61089
  * v2 model: every method gated by `auth: 'admin'`. Admin-only delegation
61057
61090
  * — the subset check on `setUserScopes` is moot
@@ -61107,10 +61140,6 @@ method(_void(), array(UserSummarySchema), { auth: "admin" }), method(CreateUserI
61107
61140
  }), UserSummarySchema.extend({ passwordHash: string() }).nullable(), {
61108
61141
  kind: "mutation",
61109
61142
  access: "view"
61110
- }), method(_void(), array(ApiKeySummarySchema), { auth: "admin" }), method(object({ id: string() }), object({ success: literal(true) }), {
61111
- kind: "mutation",
61112
- auth: "admin",
61113
- access: "delete"
61114
61143
  }), method(object({ userId: string() }), TotpSetupResultSchema, {
61115
61144
  kind: "mutation",
61116
61145
  auth: "admin",
@@ -68623,6 +68652,12 @@ Object.freeze({
68623
68652
  addonId: null,
68624
68653
  access: "view"
68625
68654
  },
68655
+ "records.transact": {
68656
+ capName: "records",
68657
+ capScope: "system",
68658
+ addonId: null,
68659
+ access: "create"
68660
+ },
68626
68661
  "sceneMonitor.captureReference": {
68627
68662
  capName: "scene-monitor",
68628
68663
  capScope: "device",
@@ -69955,12 +69990,6 @@ Object.freeze({
69955
69990
  addonId: null,
69956
69991
  access: "view"
69957
69992
  },
69958
- "userManagement.listApiKeys": {
69959
- capName: "user-management",
69960
- capScope: "system",
69961
- addonId: null,
69962
- access: "view"
69963
- },
69964
69993
  "userManagement.listExternalIdentities": {
69965
69994
  capName: "user-management",
69966
69995
  capScope: "system",
@@ -70015,12 +70044,6 @@ Object.freeze({
70015
70044
  addonId: null,
70016
70045
  access: "create"
70017
70046
  },
70018
- "userManagement.revokeApiKey": {
70019
- capName: "user-management",
70020
- capScope: "system",
70021
- addonId: null,
70022
- access: "delete"
70023
- },
70024
70047
  "userManagement.revokeOauthSession": {
70025
70048
  capName: "user-management",
70026
70049
  capScope: "system",
@@ -73385,9 +73408,13 @@ new Map(Object.entries({
73385
73408
  "stream-online": "device-events",
73386
73409
  "stream-offline": "device-events",
73387
73410
  "detection-blind": "device-events",
73411
+ "motion-noisy": "device-events",
73412
+ "motion-calm": "device-events",
73388
73413
  "recording-stalled": "device-events",
73389
73414
  "recording-healthy": "device-events",
73390
73415
  "recording-degraded": "device-events",
73416
+ "device-attention-required": "device-events",
73417
+ "device-attention-resolved": "device-events",
73391
73418
  "node-online": "system",
73392
73419
  "node-offline": "system",
73393
73420
  "node-restarting": "system",
@@ -73404,6 +73431,8 @@ new Map(Object.entries({
73404
73431
  "alert-critical": "system",
73405
73432
  "alert-error": "system",
73406
73433
  "alert-critical-resolved": "system",
73434
+ "rule-broken": "system",
73435
+ "rule-repaired": "system",
73407
73436
  "storage-location-low": "system",
73408
73437
  "storage-location-critical": "system",
73409
73438
  "storage-location-ok": "system",
@@ -73468,6 +73497,12 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
73468
73497
  label: "Detecting nothing",
73469
73498
  kinds: ["detection-blind"]
73470
73499
  },
73500
+ {
73501
+ id: "motion-noise",
73502
+ family: "device-events",
73503
+ label: "Motion without a subject",
73504
+ kinds: ["motion-noisy", "motion-calm"]
73505
+ },
73471
73506
  {
73472
73507
  id: "recording",
73473
73508
  family: "device-events",
@@ -73478,6 +73513,12 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
73478
73513
  "recording-degraded"
73479
73514
  ]
73480
73515
  },
73516
+ {
73517
+ id: "device-attention",
73518
+ family: "device-events",
73519
+ label: "Needs attention",
73520
+ kinds: ["device-attention-required", "device-attention-resolved"]
73521
+ },
73481
73522
  {
73482
73523
  id: "nodes",
73483
73524
  family: "system",
@@ -73538,6 +73579,12 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
73538
73579
  "alert-critical-resolved"
73539
73580
  ]
73540
73581
  },
73582
+ {
73583
+ id: "rule-health",
73584
+ family: "system",
73585
+ label: "Notification rules",
73586
+ kinds: ["rule-broken", "rule-repaired"]
73587
+ },
73541
73588
  {
73542
73589
  id: "alarm",
73543
73590
  family: "alarm",
@@ -73611,6 +73658,7 @@ var ALERT_EPISODE = [
73611
73658
  "alert-error",
73612
73659
  "alert-critical-resolved"
73613
73660
  ];
73661
+ var DEVICE_ATTENTION = ["device-attention-required", "device-attention-resolved"];
73614
73662
  var UPDATES = [
73615
73663
  "addon-update-available",
73616
73664
  "server-update-available",
@@ -73640,9 +73688,12 @@ var DEVICE_EVENTS = [
73640
73688
  "stream-online",
73641
73689
  "stream-offline",
73642
73690
  "detection-blind",
73691
+ "motion-noisy",
73692
+ "motion-calm",
73643
73693
  "recording-stalled",
73644
73694
  "recording-healthy",
73645
73695
  "recording-degraded",
73696
+ ...DEVICE_ATTENTION,
73646
73697
  ...ALARM
73647
73698
  ];
73648
73699
  /** Every kind a summary may speak about — the two summarisable families. */
@@ -73810,7 +73861,13 @@ var STATE_SUMMARY_VARS = [
73810
73861
  [...RULE_TEXT],
73811
73862
  [...RULE_TEXT],
73812
73863
  [...RULE_TEXT],
73813
- ([...RULE_TEXT], [...ALERT_EPISODE]),
73864
+ [...RULE_TEXT],
73865
+ [...RULE_TEXT],
73866
+ ([...RULE_TEXT], [...DEVICE_ATTENTION, ...ALERT_EPISODE]),
73867
+ [...RULE_TEXT],
73868
+ [...RULE_TEXT],
73869
+ [...RULE_TEXT],
73870
+ [...RULE_TEXT],
73814
73871
  [...RULE_TEXT],
73815
73872
  [...RULE_TEXT],
73816
73873
  [...RULE_TEXT],
@@ -73828,11 +73885,11 @@ var STATE_SUMMARY_VARS = [
73828
73885
  [...RULE_TEXT],
73829
73886
  [...RULE_TEXT],
73830
73887
  [...RULE_TEXT],
73888
+ ([...RULE_TEXT], [...DEVICE_ATTENTION, ...ALERT_EPISODE]),
73831
73889
  ([...RULE_TEXT], [...ALERT_EPISODE]),
73890
+ ([...RULE_TEXT], [...DEVICE_ATTENTION, ...ALERT_EPISODE]),
73832
73891
  ([...RULE_TEXT], [...ALERT_EPISODE]),
73833
- ([...RULE_TEXT], [...ALERT_EPISODE]),
73834
- ([...RULE_TEXT], [...ALERT_EPISODE]),
73835
- ([...RULE_TEXT], [...ALERT_EPISODE]),
73892
+ ([...RULE_TEXT], [...DEVICE_ATTENTION, ...ALERT_EPISODE]),
73836
73893
  [...RULE_TEXT],
73837
73894
  [...RULE_TEXT],
73838
73895
  [...RULE_TEXT],
@@ -73853,6 +73910,125 @@ var STATE_SUMMARY_VARS = [
73853
73910
  [...RULE_TEXT],
73854
73911
  ...STATE_SUMMARY_VARS
73855
73912
  ];
73913
+ new Map([
73914
+ {
73915
+ id: "device-connectivity",
73916
+ family: "device-events",
73917
+ label: "Device connectivity (offline / back online)",
73918
+ bad: ["device-offline"],
73919
+ recovery: ["device-online"],
73920
+ snapshotLabel: "Devices offline now",
73921
+ snapshotSection: "device-state"
73922
+ },
73923
+ {
73924
+ id: "device-switch",
73925
+ family: "device-events",
73926
+ label: "Device switched off / back on",
73927
+ bad: ["device-disabled"],
73928
+ recovery: ["device-enabled"],
73929
+ snapshotLabel: "Devices switched off now",
73930
+ snapshotSection: "device-state"
73931
+ },
73932
+ {
73933
+ id: "stream-connectivity",
73934
+ family: "device-events",
73935
+ label: "Stream connectivity (offline / back online)",
73936
+ bad: ["stream-offline"],
73937
+ recovery: ["stream-online"],
73938
+ snapshotLabel: "Streams offline now",
73939
+ snapshotSection: "streams"
73940
+ },
73941
+ {
73942
+ id: "battery",
73943
+ family: "device-events",
73944
+ label: "Battery (low / back to normal)",
73945
+ bad: ["device-battery-low"],
73946
+ recovery: ["device-battery-normal"],
73947
+ snapshotLabel: "Batteries low now",
73948
+ snapshotSection: "battery"
73949
+ },
73950
+ {
73951
+ id: "consumables",
73952
+ family: "device-events",
73953
+ label: "Consumables (low / replaced)",
73954
+ bad: ["device-consumable-low"],
73955
+ recovery: ["device-consumable-normal"],
73956
+ snapshotLabel: "Consumables low now",
73957
+ snapshotSection: "consumables"
73958
+ },
73959
+ {
73960
+ id: "tanks",
73961
+ family: "device-events",
73962
+ label: "Tanks (low or full / back to normal)",
73963
+ bad: ["device-tank-low", "device-tank-full"],
73964
+ recovery: ["device-tank-normal"],
73965
+ snapshotLabel: "Tanks low or full now",
73966
+ snapshotSection: "tanks"
73967
+ },
73968
+ {
73969
+ id: "motion-noise",
73970
+ family: "device-events",
73971
+ label: "Motion without a subject (constant / calm again)",
73972
+ bad: ["motion-noisy"],
73973
+ recovery: ["motion-calm"],
73974
+ snapshotLabel: "Cameras with constant motion now",
73975
+ snapshotSection: null
73976
+ },
73977
+ {
73978
+ id: "recording-health",
73979
+ family: "device-events",
73980
+ label: "Recording health (stalled or degraded / recording again)",
73981
+ bad: ["recording-stalled", "recording-degraded"],
73982
+ recovery: ["recording-healthy"],
73983
+ snapshotLabel: "Recordings stalled now",
73984
+ snapshotSection: null
73985
+ },
73986
+ {
73987
+ id: "device-attention",
73988
+ family: "device-events",
73989
+ label: "Device needs attention (raised / resolved)",
73990
+ bad: ["device-attention-required"],
73991
+ recovery: ["device-attention-resolved"],
73992
+ snapshotLabel: "Devices needing attention now",
73993
+ snapshotSection: null
73994
+ },
73995
+ {
73996
+ id: "node-connectivity",
73997
+ family: "system",
73998
+ label: "Node connectivity (offline / back online)",
73999
+ bad: ["node-offline"],
74000
+ recovery: ["node-online"],
74001
+ snapshotLabel: "Nodes offline now",
74002
+ snapshotSection: "nodes"
74003
+ },
74004
+ {
74005
+ id: "storage-space",
74006
+ family: "system",
74007
+ label: "Storage space (low or critical / ok again)",
74008
+ bad: ["storage-location-low", "storage-location-critical"],
74009
+ recovery: ["storage-location-ok"],
74010
+ snapshotLabel: "Storage locations low now",
74011
+ snapshotSection: null
74012
+ },
74013
+ {
74014
+ id: "critical-alerts",
74015
+ family: "system",
74016
+ label: "Critical alerts (raised / resolved)",
74017
+ bad: ["alert-critical"],
74018
+ recovery: ["alert-critical-resolved"],
74019
+ snapshotLabel: "Critical alerts open now",
74020
+ snapshotSection: null
74021
+ },
74022
+ {
74023
+ id: "rule-health",
74024
+ family: "system",
74025
+ label: "Rule health (broken / repaired)",
74026
+ bad: ["rule-broken"],
74027
+ recovery: ["rule-repaired"],
74028
+ snapshotLabel: "Notification rules broken now",
74029
+ snapshotSection: null
74030
+ }
74031
+ ].flatMap((spec) => [...spec.bad, ...spec.recovery].map((kind) => [kind, spec])));
73856
74032
  new Set([
73857
74033
  "disarmed",
73858
74034
  "armed_home",
@@ -74393,7 +74569,7 @@ var AgentUIAddon = class extends BaseAddon {
74393
74569
  capability: adminUiCapability,
74394
74570
  provider: {
74395
74571
  getStaticDir: async () => ({ staticDir: path.resolve(__dirname) }),
74396
- getVersion: async () => ({ version: "1.2.256" })
74572
+ getVersion: async () => ({ version: "1.2.258" })
74397
74573
  }
74398
74574
  }];
74399
74575
  }
@@ -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,c as o,d as s,h as c,l,p as u,t as ee}from"./index-C2EQHp3p.js";import{MaskShapeCanvas as d}from"./MaskShapeCanvas-BTvl6Rin.js";var f=a(`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`}]]),p=n(i(),1),m=n(e(),1),h=110,g=`motion-zones`,_=0,te=[1,2,3],v=1,y=`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`,b=`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 x(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 S(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 C(e,t){return Math.ceil(e/t)}function w(e,t,n){return Math.min(n-1,Math.floor((e+.5)/t*n))}function T(e,t,n,r){let i=C(t,r),a=C(n,r),o=Array.from({length:i*a},()=>!1);for(let r=0;r<n;r+=1){let s=w(r,n,a);for(let n=0;n<t;n+=1)e[r*t+n]===!0&&(o[s*i+w(n,t,i)]=!0)}return o}function E(e,t,n,r){let i=C(t,r),a=C(n,r),o=Array.from({length:t*n},()=>!1);for(let r=0;r<n;r+=1){let s=w(r,n,a);for(let n=0;n<t;n+=1)o[r*t+n]=e[s*i+w(n,t,i)]===!0}return o}function D({deviceId:e}){let n=t(),i=s(c().trpcClient,e),[a,w]=(0,p.useState)(null),[D,O]=(0,p.useState)(!1),[k,A]=(0,p.useState)(null),[j,M]=(0,p.useState)(null),[N,P]=(0,p.useState)(v),[F,I]=(0,p.useState)(!1),[L,R]=(0,p.useState)(!1),z=(0,p.useRef)(!1);(0,p.useEffect)(()=>{if(!i)return;let e=!1;return z.current=!1,w(null),O(!1),A(null),M(null),P(v),R(!1),(async()=>{try{let t=await i.motionZones?.getOptions({});if(e)return;if(!t)throw Error(`device proxy not ready`);if(w(t),z.current)return;let n=await i.motionZones?.getStatus({});if(e)return;if(!n)throw Error(`device proxy not ready`);z.current=!0;let r=n.regions.find(e=>e.shape.kind===`grid`),a=x(r?r.shape.cells:[],t.grid.width,t.grid.height);M(a),A(T(a,t.grid.width,t.grid.height,v))}catch(t){if(e)return;l(t)?O(!0):console.error(`Motion Zones load failed`,t)}})(),()=>{e=!0}},[i]);let B=a?a.grid.width:0,V=a?a.grid.height:0,H=C(B,N),U=C(V,N),W=(0,p.useMemo)(()=>k&&a?E(k,B,V,N):null,[k,a,B,V,N]),G=(0,p.useMemo)(()=>W!==null&&j!==null&&!S(W,j),[W,j]),K=(0,p.useMemo)(()=>W?W.reduce((e,t)=>t?e+1:e,0):0,[W]),q=B*V,J=H*U,Y=(0,p.useCallback)(e=>{J>0&&A(Array.from({length:J},()=>e))},[J]),X=(0,p.useCallback)(()=>{A(e=>e&&e.map(e=>!e))},[]),Z=(0,p.useCallback)(()=>{j&&a&&A(T(j,B,V,N))},[j,a,B,V,N]),ne=(0,p.useCallback)(e=>{e===N||!a||A(t=>{if(!t)return P(e),t;let n=T(E(t,B,V,N),B,V,e);return P(e),n})},[N,a,B,V]),Q=(0,p.useMemo)(()=>a&&k?[{id:_,shape:{kind:`grid`,gridWidth:H,gridHeight:U,cells:[...k]}}]:[],[a,k,H,U]),$=(0,p.useCallback)((e,t)=>{t.kind===`grid`&&A(t.cells)},[]),re=(0,p.useCallback)(async()=>{if(!(!i||!k||!a)){I(!0);try{let e=E(k,a.grid.width,a.grid.height,N),t={kind:`grid`,gridWidth:a.grid.width,gridHeight:a.grid.height,cells:e};await i.motionZones?.setZone({patch:{regions:[{id:_,enabled:!0,shape:t}]}});let n=await i.motionZones?.getStatus({});if(n){let e=n.regions.find(e=>e.shape.kind===`grid`),t=x(e?e.shape.cells:[],a.grid.width,a.grid.height);M(t),A(T(t,a.grid.width,a.grid.height,N))}}catch(e){console.error(`Motion Zones save failed`,e)}finally{I(!1)}}},[i,k,a,N]);ee((0,p.useMemo)(()=>L&&!D&&a&&k?{id:g,order:h,node:(0,m.jsx)(d,{transparent:!0,items:Q,supportedShapes:[`grid`],grid:{width:H,height:U},selectedId:_,onSelect:()=>{},onShapeChange:$,onDrawComplete:()=>{},drawingKind:null})}:null,[L,D,a,k,Q,$,H,U]));let ie=!D&&a!==null&&k!==null;return i?(0,m.jsx)(u,{title:n(`uiLibrary.motionZones.title`,`Motion Zones`),icon:(0,m.jsx)(f,{className:`h-3.5 w-3.5 text-foreground-subtle`}),children:(0,m.jsx)(`div`,{className:`flex flex-col gap-3`,children:D?(0,m.jsx)(`p`,{className:`${o} leading-relaxed`,children:n(`uiLibrary.motionZones.unsupported`,`This camera doesn't expose an on-board motion zones grid.`)}):ie?(0,m.jsxs)(m.Fragment,{children:[(0,m.jsx)(`p`,{className:`${o} leading-relaxed`,children:(0,m.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,m.jsx)(`strong`,{className:`text-foreground`},`e`),(0,m.jsx)(`strong`,{className:`text-foreground`},`s`),(0,m.jsx)(`strong`,{className:`text-foreground`},`c`)],values:{width:a.grid.width,height:a.grid.height}})}),(0,m.jsxs)(`div`,{className:`flex items-center gap-2 flex-wrap`,children:[(0,m.jsx)(`button`,{type:`button`,onClick:()=>R(e=>!e),disabled:F,"aria-pressed":L,className:L?b:y,children:L?n(`uiLibrary.motionZones.doneEditing`,`Done editing`):n(`uiLibrary.motionZones.editGrid`,`Edit grid`)}),(0,m.jsx)(`button`,{type:`button`,onClick:()=>Y(!0),disabled:F,className:y,children:n(`uiLibrary.motionZones.allOn`,`All on`)}),(0,m.jsx)(`button`,{type:`button`,onClick:()=>Y(!1),disabled:F,className:y,children:n(`uiLibrary.motionZones.allOff`,`All off`)}),(0,m.jsx)(`button`,{type:`button`,onClick:X,disabled:F,className:y,children:n(`uiLibrary.motionZones.invert`,`Invert`)}),(0,m.jsxs)(`div`,{className:`flex items-center gap-1 ml-1`,role:`group`,"aria-label":n(`uiLibrary.motionZones.cellSize`,`Cell size`),children:[(0,m.jsx)(`span`,{className:`${o} mr-0.5`,children:n(`uiLibrary.motionZones.cellSize`,`Cell size`)}),te.map(e=>(0,m.jsxs)(`button`,{type:`button`,onClick:()=>ne(e),disabled:F,"aria-pressed":N===e,title:e===1?n(`uiLibrary.motionZones.cameraGrid`,`Camera grid {{width}}×{{height}} (finest)`,{width:B,height:V}):n(`uiLibrary.motionZones.paintingGrid`,`{{width}}×{{height}} painting grid · cells ×{{factor}} bigger`,{width:C(B,e),height:C(V,e),factor:e}),className:N===e?b:y,children:[`×`,e]},e))]}),(0,m.jsxs)(`span`,{className:`${o} ml-1 tabular-nums`,children:[n(`uiLibrary.motionZones.cells`,`{{active}} / {{total}} cells · {{width}}×{{height}}`,{active:K,total:q,width:a.grid.width,height:a.grid.height}),N===1?``:n(`uiLibrary.motionZones.paintSuffix`,` · paint {{width}}×{{height}}`,{width:H,height:U})]}),(0,m.jsx)(`span`,{className:`flex-1`}),(0,m.jsx)(`button`,{type:`button`,onClick:Z,disabled:F||!G,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,m.jsx)(`button`,{type:`button`,onClick:()=>void re(),disabled:F||!G,className:b,children:F?n(`uiLibrary.motionZones.saving`,`Saving…`):n(`uiLibrary.motionZones.save`,`Save`)})]})]}):(0,m.jsx)(`p`,{className:`${o} leading-relaxed`,children:n(`uiLibrary.motionZones.loading`,`Loading the camera's grid…`)})})}):null}export{D 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,c as o,d as s,h as c,l,p as u,t as ee}from"./index-_DGBR6-x.js";import{MaskShapeCanvas as d}from"./MaskShapeCanvas-BTvl6Rin.js";var f=a(`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`}]]),p=n(i(),1),m=n(e(),1),h=110,g=`motion-zones`,_=0,te=[1,2,3],v=1,y=`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`,b=`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 x(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 S(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 C(e,t){return Math.ceil(e/t)}function w(e,t,n){return Math.min(n-1,Math.floor((e+.5)/t*n))}function T(e,t,n,r){let i=C(t,r),a=C(n,r),o=Array.from({length:i*a},()=>!1);for(let r=0;r<n;r+=1){let s=w(r,n,a);for(let n=0;n<t;n+=1)e[r*t+n]===!0&&(o[s*i+w(n,t,i)]=!0)}return o}function E(e,t,n,r){let i=C(t,r),a=C(n,r),o=Array.from({length:t*n},()=>!1);for(let r=0;r<n;r+=1){let s=w(r,n,a);for(let n=0;n<t;n+=1)o[r*t+n]=e[s*i+w(n,t,i)]===!0}return o}function D({deviceId:e}){let n=t(),i=s(c().trpcClient,e),[a,w]=(0,p.useState)(null),[D,O]=(0,p.useState)(!1),[k,A]=(0,p.useState)(null),[j,M]=(0,p.useState)(null),[N,P]=(0,p.useState)(v),[F,I]=(0,p.useState)(!1),[L,R]=(0,p.useState)(!1),z=(0,p.useRef)(!1);(0,p.useEffect)(()=>{if(!i)return;let e=!1;return z.current=!1,w(null),O(!1),A(null),M(null),P(v),R(!1),(async()=>{try{let t=await i.motionZones?.getOptions({});if(e)return;if(!t)throw Error(`device proxy not ready`);if(w(t),z.current)return;let n=await i.motionZones?.getStatus({});if(e)return;if(!n)throw Error(`device proxy not ready`);z.current=!0;let r=n.regions.find(e=>e.shape.kind===`grid`),a=x(r?r.shape.cells:[],t.grid.width,t.grid.height);M(a),A(T(a,t.grid.width,t.grid.height,v))}catch(t){if(e)return;l(t)?O(!0):console.error(`Motion Zones load failed`,t)}})(),()=>{e=!0}},[i]);let B=a?a.grid.width:0,V=a?a.grid.height:0,H=C(B,N),U=C(V,N),W=(0,p.useMemo)(()=>k&&a?E(k,B,V,N):null,[k,a,B,V,N]),G=(0,p.useMemo)(()=>W!==null&&j!==null&&!S(W,j),[W,j]),K=(0,p.useMemo)(()=>W?W.reduce((e,t)=>t?e+1:e,0):0,[W]),q=B*V,J=H*U,Y=(0,p.useCallback)(e=>{J>0&&A(Array.from({length:J},()=>e))},[J]),X=(0,p.useCallback)(()=>{A(e=>e&&e.map(e=>!e))},[]),Z=(0,p.useCallback)(()=>{j&&a&&A(T(j,B,V,N))},[j,a,B,V,N]),ne=(0,p.useCallback)(e=>{e===N||!a||A(t=>{if(!t)return P(e),t;let n=T(E(t,B,V,N),B,V,e);return P(e),n})},[N,a,B,V]),Q=(0,p.useMemo)(()=>a&&k?[{id:_,shape:{kind:`grid`,gridWidth:H,gridHeight:U,cells:[...k]}}]:[],[a,k,H,U]),$=(0,p.useCallback)((e,t)=>{t.kind===`grid`&&A(t.cells)},[]),re=(0,p.useCallback)(async()=>{if(!(!i||!k||!a)){I(!0);try{let e=E(k,a.grid.width,a.grid.height,N),t={kind:`grid`,gridWidth:a.grid.width,gridHeight:a.grid.height,cells:e};await i.motionZones?.setZone({patch:{regions:[{id:_,enabled:!0,shape:t}]}});let n=await i.motionZones?.getStatus({});if(n){let e=n.regions.find(e=>e.shape.kind===`grid`),t=x(e?e.shape.cells:[],a.grid.width,a.grid.height);M(t),A(T(t,a.grid.width,a.grid.height,N))}}catch(e){console.error(`Motion Zones save failed`,e)}finally{I(!1)}}},[i,k,a,N]);ee((0,p.useMemo)(()=>L&&!D&&a&&k?{id:g,order:h,node:(0,m.jsx)(d,{transparent:!0,items:Q,supportedShapes:[`grid`],grid:{width:H,height:U},selectedId:_,onSelect:()=>{},onShapeChange:$,onDrawComplete:()=>{},drawingKind:null})}:null,[L,D,a,k,Q,$,H,U]));let ie=!D&&a!==null&&k!==null;return i?(0,m.jsx)(u,{title:n(`uiLibrary.motionZones.title`,`Motion Zones`),icon:(0,m.jsx)(f,{className:`h-3.5 w-3.5 text-foreground-subtle`}),children:(0,m.jsx)(`div`,{className:`flex flex-col gap-3`,children:D?(0,m.jsx)(`p`,{className:`${o} leading-relaxed`,children:n(`uiLibrary.motionZones.unsupported`,`This camera doesn't expose an on-board motion zones grid.`)}):ie?(0,m.jsxs)(m.Fragment,{children:[(0,m.jsx)(`p`,{className:`${o} leading-relaxed`,children:(0,m.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,m.jsx)(`strong`,{className:`text-foreground`},`e`),(0,m.jsx)(`strong`,{className:`text-foreground`},`s`),(0,m.jsx)(`strong`,{className:`text-foreground`},`c`)],values:{width:a.grid.width,height:a.grid.height}})}),(0,m.jsxs)(`div`,{className:`flex items-center gap-2 flex-wrap`,children:[(0,m.jsx)(`button`,{type:`button`,onClick:()=>R(e=>!e),disabled:F,"aria-pressed":L,className:L?b:y,children:L?n(`uiLibrary.motionZones.doneEditing`,`Done editing`):n(`uiLibrary.motionZones.editGrid`,`Edit grid`)}),(0,m.jsx)(`button`,{type:`button`,onClick:()=>Y(!0),disabled:F,className:y,children:n(`uiLibrary.motionZones.allOn`,`All on`)}),(0,m.jsx)(`button`,{type:`button`,onClick:()=>Y(!1),disabled:F,className:y,children:n(`uiLibrary.motionZones.allOff`,`All off`)}),(0,m.jsx)(`button`,{type:`button`,onClick:X,disabled:F,className:y,children:n(`uiLibrary.motionZones.invert`,`Invert`)}),(0,m.jsxs)(`div`,{className:`flex items-center gap-1 ml-1`,role:`group`,"aria-label":n(`uiLibrary.motionZones.cellSize`,`Cell size`),children:[(0,m.jsx)(`span`,{className:`${o} mr-0.5`,children:n(`uiLibrary.motionZones.cellSize`,`Cell size`)}),te.map(e=>(0,m.jsxs)(`button`,{type:`button`,onClick:()=>ne(e),disabled:F,"aria-pressed":N===e,title:e===1?n(`uiLibrary.motionZones.cameraGrid`,`Camera grid {{width}}×{{height}} (finest)`,{width:B,height:V}):n(`uiLibrary.motionZones.paintingGrid`,`{{width}}×{{height}} painting grid · cells ×{{factor}} bigger`,{width:C(B,e),height:C(V,e),factor:e}),className:N===e?b:y,children:[`×`,e]},e))]}),(0,m.jsxs)(`span`,{className:`${o} ml-1 tabular-nums`,children:[n(`uiLibrary.motionZones.cells`,`{{active}} / {{total}} cells · {{width}}×{{height}}`,{active:K,total:q,width:a.grid.width,height:a.grid.height}),N===1?``:n(`uiLibrary.motionZones.paintSuffix`,` · paint {{width}}×{{height}}`,{width:H,height:U})]}),(0,m.jsx)(`span`,{className:`flex-1`}),(0,m.jsx)(`button`,{type:`button`,onClick:Z,disabled:F||!G,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,m.jsx)(`button`,{type:`button`,onClick:()=>void re(),disabled:F||!G,className:b,children:F?n(`uiLibrary.motionZones.saving`,`Saving…`):n(`uiLibrary.motionZones.save`,`Save`)})]})]}):(0,m.jsx)(`p`,{className:`${o} leading-relaxed`,children:n(`uiLibrary.motionZones.loading`,`Loading the camera's grid…`)})})}):null}export{D 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{C as a,_ as ee,c as o,d as te,g as ne,h as s,l as c,p as re,t as l,x as u,y as d}from"./index-C2EQHp3p.js";import{MaskShapeCanvas as ie}from"./MaskShapeCanvas-BTvl6Rin.js";var ae=a(`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=a(`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=te(s().trpcClient,e),[a,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=a?a.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:a===null?null:a.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=a?.supportedShapes??[];l((0,f.useMemo)(()=>O&&!m&&a&&S?{id:ue,order:le,node:(0,h.jsx)(ie,{transparent:!0,items:K,supportedShapes:Q,polygonVertices:a.polygonVertices,selectedId:A,onSelect:G,onShapeChange:q,onDrawComplete:J,drawingKind:M})}:null,[O,m,a,S,K,Q,A,G,q,J,M]));let be=a?.supportedShapes.includes(`rect`)??!1,xe=a?.supportedShapes.includes(`polygon`)??!1,$=a!==null&&(a.maxRegions<=0||a.supportedShapes.length===0),Se=!m&&!$&&!b&&a!==null&&S!==null;return i?(0,h.jsx)(re,{title:n(`uiLibrary.privacyMaskSettings.title`,`Privacy Mask`),icon:(0,h.jsx)(u,{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:ee;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)(ne,{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)(d,{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{C as a,_ as ee,c as o,d as te,g as ne,h as s,l as c,p as re,t as l,x as u,y as d}from"./index-_DGBR6-x.js";import{MaskShapeCanvas as ie}from"./MaskShapeCanvas-BTvl6Rin.js";var ae=a(`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=a(`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=te(s().trpcClient,e),[a,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=a?a.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:a===null?null:a.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=a?.supportedShapes??[];l((0,f.useMemo)(()=>O&&!m&&a&&S?{id:ue,order:le,node:(0,h.jsx)(ie,{transparent:!0,items:K,supportedShapes:Q,polygonVertices:a.polygonVertices,selectedId:A,onSelect:G,onShapeChange:q,onDrawComplete:J,drawingKind:M})}:null,[O,m,a,S,K,Q,A,G,q,J,M]));let be=a?.supportedShapes.includes(`rect`)??!1,xe=a?.supportedShapes.includes(`polygon`)??!1,$=a!==null&&(a.maxRegions<=0||a.supportedShapes.length===0),Se=!m&&!$&&!b&&a!==null&&S!==null;return i?(0,h.jsx)(re,{title:n(`uiLibrary.privacyMaskSettings.title`,`Privacy Mask`),icon:(0,h.jsx)(u,{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:ee;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)(ne,{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)(d,{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};