camstack 1.2.201 → 1.2.203

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/cli.js CHANGED
@@ -37,7 +37,7 @@ async function runServe(args) {
37
37
  ...typeof values.data === "string" ? { data: values.data } : {}
38
38
  };
39
39
  Object.assign(process.env, buildServeEnv(opts));
40
- await import("./launcher-SOSAKLLX.js");
40
+ await import("./launcher-J5GG4YZB.js");
41
41
  }
42
42
 
43
43
  // src/commands/agent.ts
@@ -82,7 +82,7 @@ async function runAgent(args) {
82
82
  ...typeof values.port === "string" ? { port: values.port } : {}
83
83
  };
84
84
  Object.assign(process.env, buildAgentEnv(opts));
85
- await import("./launcher-SOSAKLLX.js");
85
+ await import("./launcher-J5GG4YZB.js");
86
86
  }
87
87
 
88
88
  // src/commands/setup.ts
@@ -91,7 +91,7 @@ import * as path from "path";
91
91
  import * as fs from "fs";
92
92
  import { parseArgs as parseArgs3 } from "util";
93
93
 
94
- // ../types/dist/event-category-DOl51-Ij.mjs
94
+ // ../types/dist/event-category-BfJwUd2S.mjs
95
95
  var EventCategory = /* @__PURE__ */ (function(EventCategory2) {
96
96
  EventCategory2["SystemBoot"] = "system.boot";
97
97
  EventCategory2["SystemAddonsReady"] = "system.addons-ready";
@@ -172,6 +172,8 @@ var EventCategory = /* @__PURE__ */ (function(EventCategory2) {
172
172
  EventCategory2["PipelineCameraUnassigned"] = "pipeline.camera-unassigned";
173
173
  EventCategory2["PipelineNodeInferenceUnavailable"] = "pipeline.node-inference-unavailable";
174
174
  EventCategory2["PipelineDetectionBlind"] = "pipeline.detection-blind";
175
+ EventCategory2["PipelineMotionNoisy"] = "pipeline.motion-noisy";
176
+ EventCategory2["PipelineMotionCalm"] = "pipeline.motion-calm";
175
177
  EventCategory2["PipelineCameraUpdated"] = "pipeline.camera-updated";
176
178
  EventCategory2["PipelineIngestOwnerChanged"] = "pipeline.ingest-owner-changed";
177
179
  EventCategory2["PipelineRunnerLoadSnapshot"] = "pipeline.runner-load-snapshot";
@@ -244,6 +246,8 @@ var EventCategory = /* @__PURE__ */ (function(EventCategory2) {
244
246
  EventCategory2["BackupRestored"] = "backup.restored";
245
247
  EventCategory2["NotificationDispatched"] = "notification.dispatched";
246
248
  EventCategory2["NotificationFailed"] = "notification.failed";
249
+ EventCategory2["NotificationRuleBroken"] = "notification.rule-broken";
250
+ EventCategory2["NotificationRuleRepaired"] = "notification.rule-repaired";
247
251
  EventCategory2["DeviceUpdated"] = "device.updated";
248
252
  EventCategory2["DeviceOnline"] = "device.online";
249
253
  EventCategory2["DeviceOffline"] = "device.offline";
@@ -14773,7 +14777,7 @@ function date4(params) {
14773
14777
  // ../../node_modules/zod/v4/classic/external.js
14774
14778
  config(en_default());
14775
14779
 
14776
- // ../types/dist/sleep-_sV1BE2f.mjs
14780
+ // ../types/dist/sleep-DJFUfKvA.mjs
14777
14781
  var AUDIO_CHUNK_FORMATS = [
14778
14782
  "f32le",
14779
14783
  "pcmu",
@@ -15030,7 +15034,7 @@ var EntryDescriptorSchema = external_exports.object({
15030
15034
  /** JSON Schema of the entry body; `secret: true` marks a password field. */
15031
15035
  fields: external_exports.record(external_exports.string(), external_exports.unknown())
15032
15036
  }).strict();
15033
- var RecordKindDeclarationSchema = external_exports.object({
15037
+ var RecordKindDeclarationShape = external_exports.object({
15034
15038
  database: external_exports.enum(RECORD_DATABASES).default("settings"),
15035
15039
  class: external_exports.enum(RECORD_CLASSES),
15036
15040
  writeTrigger: external_exports.string().min(1),
@@ -15048,18 +15052,11 @@ var RecordKindDeclarationSchema = external_exports.object({
15048
15052
  secretPaths: external_exports.array(external_exports.string().min(1)).default([]),
15049
15053
  /** The id key of each array that carries a secret (`{ headers: 'name' }`). */
15050
15054
  secretArrayKeys: external_exports.record(external_exports.string(), external_exports.string()).default({}),
15051
- /**
15052
- * RETIRED (D900): the legacy table a kind adopted from during the records
15053
- * migration. Nothing declares it any more and nothing reads it; the schema
15054
- * still ACCEPTS it because the catalog rows the migration wrote carry it
15055
- * (an orphaned kind is never redeclared) and an addon built before the
15056
- * removal still sends it. Never set it.
15057
- */
15058
- adoptsFrom: external_exports.string().min(1).optional(),
15059
15055
  /** Kinds that must agree through `transact` sit in one file under one family name. */
15060
15056
  transactFamily: external_exports.string().min(1).optional(),
15061
15057
  entry: EntryDescriptorSchema.optional()
15062
- }).strict();
15058
+ });
15059
+ var RecordKindDeclarationSchema = RecordKindDeclarationShape.strict();
15063
15060
  var RecordKindNameSchema = external_exports.string().regex(/^[a-z][a-z0-9-]{0,47}$/);
15064
15061
  var CamProfileSchema = external_exports.enum([
15065
15062
  "high",
@@ -18554,17 +18551,6 @@ var UserRecordSchema = external_exports.object({
18554
18551
  createdAt: external_exports.number(),
18555
18552
  updatedAt: external_exports.number()
18556
18553
  });
18557
- var ApiKeyRecordSchema = external_exports.object({
18558
- id: external_exports.string(),
18559
- label: external_exports.string(),
18560
- isAdmin: external_exports.boolean().default(false),
18561
- allowedProviders: AllowedProviderSchema,
18562
- allowedDevices: AllowedDevicesSchema,
18563
- tokenHash: external_exports.string(),
18564
- tokenPrefix: external_exports.string(),
18565
- createdAt: external_exports.number(),
18566
- lastUsedAt: external_exports.number().optional()
18567
- });
18568
18554
  var ScopedTokenSchema = external_exports.object({
18569
18555
  id: external_exports.string(),
18570
18556
  userId: external_exports.string(),
@@ -22954,15 +22940,31 @@ var RecordKindStateSchema = external_exports.enum([
22954
22940
  var DeclareKindResultSchema = external_exports.object({
22955
22941
  kindId: external_exports.number().int(),
22956
22942
  state: RecordKindStateSchema,
22957
- createdIndexes: external_exports.array(external_exports.string()),
22958
- /**
22959
- * RETIRED (D900): always `null`. It carried the records-migration boot guard;
22960
- * it stays on the wire, null, because an addon built before the removal reads
22961
- * an ABSENT field as "adoption pending" and refuses to start.
22962
- */
22963
- adoptionPending: external_exports.null()
22943
+ createdIndexes: external_exports.array(external_exports.string())
22964
22944
  });
22965
22945
  var SecretRefsList = external_exports.array(external_exports.string());
22946
+ var RecordTransactOpSchema = external_exports.discriminatedUnion("op", [
22947
+ external_exports.object({
22948
+ op: external_exports.literal("put"),
22949
+ kind: RecordKindNameSchema,
22950
+ record: RecordInputSchema,
22951
+ ifRev: external_exports.number().int().min(0).optional()
22952
+ }),
22953
+ external_exports.object({
22954
+ op: external_exports.literal("patch"),
22955
+ kind: RecordKindNameSchema,
22956
+ id: RecordIdSchema,
22957
+ data: RecordBodySchema,
22958
+ at: external_exports.number().int().nullable().optional(),
22959
+ expiresAt: external_exports.number().int().nullable().optional(),
22960
+ ifRev: external_exports.number().int().min(1).optional()
22961
+ }),
22962
+ external_exports.object({
22963
+ op: external_exports.literal("delete"),
22964
+ kind: RecordKindNameSchema,
22965
+ id: RecordIdSchema
22966
+ })
22967
+ ]);
22966
22968
  var RecordSecretRefsSchema = external_exports.record(external_exports.string(), external_exports.record(external_exports.string(), external_exports.string()));
22967
22969
  var recordsCapability = {
22968
22970
  name: "records",
@@ -23094,6 +23096,22 @@ var recordsCapability = {
23094
23096
  kind: "mutation",
23095
23097
  auth: "admin"
23096
23098
  }),
23099
+ /**
23100
+ * Several single-row writes (put / patch / delete) in ONE SQLite transaction:
23101
+ * all land or none does. Every op's kind must sit in one file and share one
23102
+ * `transactFamily` (`records/transact-refused` otherwise). Results are in op order.
23103
+ */
23104
+ transact: method(external_exports.object({ ops: external_exports.array(RecordTransactOpSchema).min(1).max(RECORD_BATCH_MAX) }), external_exports.object({
23105
+ results: external_exports.array(external_exports.object({
23106
+ rev: external_exports.number().int().nullable(),
23107
+ deleted: external_exports.boolean()
23108
+ })),
23109
+ releasedRefs: SecretRefsList,
23110
+ secretRefs: SecretRefsList
23111
+ }), {
23112
+ kind: "mutation",
23113
+ auth: "admin"
23114
+ }),
23097
23115
  /** The D865 hook body: every kind of this addon declared `deviceRemoval: 'delete'`. */
23098
23116
  deleteDevice: method(external_exports.object({
23099
23117
  deviceId: external_exports.number().int(),
@@ -48873,9 +48891,13 @@ var NcSystemEventKindSchema = external_exports.enum([
48873
48891
  "node-updating",
48874
48892
  "node-inference-unavailable",
48875
48893
  "detection-blind",
48894
+ "motion-noisy",
48895
+ "motion-calm",
48876
48896
  "recording-stalled",
48877
48897
  "recording-healthy",
48878
48898
  "recording-degraded",
48899
+ "device-attention-required",
48900
+ "device-attention-resolved",
48879
48901
  "storage-location-low",
48880
48902
  "storage-location-critical",
48881
48903
  "storage-location-ok",
@@ -48899,6 +48921,8 @@ var NcSystemEventKindSchema = external_exports.enum([
48899
48921
  "alert-critical",
48900
48922
  "alert-error",
48901
48923
  "alert-critical-resolved",
48924
+ "rule-broken",
48925
+ "rule-repaired",
48902
48926
  "camera-online",
48903
48927
  "camera-offline",
48904
48928
  "camera-disabled",
@@ -62479,6 +62503,16 @@ var DishwasherStatusSchema = external_exports.object({
62479
62503
  powerState: external_exports.string().nullable(),
62480
62504
  saltLevel: DishwasherConsumableLevelSchema.nullable(),
62481
62505
  rinseAidLevel: DishwasherConsumableLevelSchema.nullable(),
62506
+ /**
62507
+ * True while the appliance asks for its filter to be cleaned (smart-filter, filter-system or
62508
+ * combined care-and-filter reminder raised); false when every such reminder reads clear; null
62509
+ * when none is reported. A cleared reminder is not an unknown one.
62510
+ */
62511
+ filterCleaningDue: external_exports.boolean().nullable(),
62512
+ /** True while the machine-care (descaling / cleaning-program) reminder is raised; false when clear; null when not reported. */
62513
+ machineCareDue: external_exports.boolean().nullable(),
62514
+ /** Program runs left before the machine-care reminder is due; null when the appliance does not say. */
62515
+ machineCareRemainingRuns: external_exports.number().int().nonnegative().nullable(),
62482
62516
  /** Option states: null when the appliance does not expose the option or has not said. */
62483
62517
  halfLoad: external_exports.boolean().nullable(),
62484
62518
  hygienePlus: external_exports.boolean().nullable(),
@@ -70354,16 +70388,6 @@ var UpdateUserInputSchema = external_exports.object({
70354
70388
  allowedDevices: external_exports.record(external_exports.string(), external_exports.union([external_exports.array(external_exports.string()), external_exports.literal("*")])).optional(),
70355
70389
  scopes: external_exports.array(TokenScopeSchema).optional()
70356
70390
  });
70357
- var ApiKeySummarySchema = external_exports.object({
70358
- id: external_exports.string(),
70359
- label: external_exports.string(),
70360
- isAdmin: external_exports.boolean().default(false),
70361
- allowedProviders: external_exports.union([external_exports.array(external_exports.string()), external_exports.literal("*")]).optional(),
70362
- allowedDevices: external_exports.record(external_exports.string(), external_exports.union([external_exports.array(external_exports.string()), external_exports.literal("*")])).optional(),
70363
- tokenPrefix: external_exports.string(),
70364
- createdAt: external_exports.number(),
70365
- lastUsedAt: external_exports.number().optional()
70366
- });
70367
70391
  var OauthSessionSummarySchema = external_exports.object({
70368
70392
  id: external_exports.string(),
70369
70393
  userId: external_exports.string(),
@@ -70444,12 +70468,6 @@ var userManagementCapability = {
70444
70468
  kind: "mutation",
70445
70469
  access: "view"
70446
70470
  }),
70447
- listApiKeys: method(external_exports.void(), external_exports.array(ApiKeySummarySchema), { auth: "admin" }),
70448
- revokeApiKey: method(external_exports.object({ id: external_exports.string() }), external_exports.object({ success: external_exports.literal(true) }), {
70449
- kind: "mutation",
70450
- auth: "admin",
70451
- access: "delete"
70452
- }),
70453
70471
  setupTotp: method(external_exports.object({ userId: external_exports.string() }), TotpSetupResultSchema, {
70454
70472
  kind: "mutation",
70455
70473
  auth: "admin",
@@ -78483,6 +78501,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
78483
78501
  addonId: null,
78484
78502
  access: "view"
78485
78503
  },
78504
+ "records.transact": {
78505
+ capName: "records",
78506
+ capScope: "system",
78507
+ addonId: null,
78508
+ access: "create"
78509
+ },
78486
78510
  "sceneMonitor.captureReference": {
78487
78511
  capName: "scene-monitor",
78488
78512
  capScope: "device",
@@ -79815,12 +79839,6 @@ var METHOD_ACCESS_MAP = Object.freeze({
79815
79839
  addonId: null,
79816
79840
  access: "view"
79817
79841
  },
79818
- "userManagement.listApiKeys": {
79819
- capName: "user-management",
79820
- capScope: "system",
79821
- addonId: null,
79822
- access: "view"
79823
- },
79824
79842
  "userManagement.listExternalIdentities": {
79825
79843
  capName: "user-management",
79826
79844
  capScope: "system",
@@ -79875,12 +79893,6 @@ var METHOD_ACCESS_MAP = Object.freeze({
79875
79893
  addonId: null,
79876
79894
  access: "create"
79877
79895
  },
79878
- "userManagement.revokeApiKey": {
79879
- capName: "user-management",
79880
- capScope: "system",
79881
- addonId: null,
79882
- access: "delete"
79883
- },
79884
79896
  "userManagement.revokeOauthSession": {
79885
79897
  capName: "user-management",
79886
79898
  capScope: "system",
@@ -83584,9 +83596,13 @@ var NC_SYSTEM_EVENT_FAMILY = {
83584
83596
  "stream-online": "device-events",
83585
83597
  "stream-offline": "device-events",
83586
83598
  "detection-blind": "device-events",
83599
+ "motion-noisy": "device-events",
83600
+ "motion-calm": "device-events",
83587
83601
  "recording-stalled": "device-events",
83588
83602
  "recording-healthy": "device-events",
83589
83603
  "recording-degraded": "device-events",
83604
+ "device-attention-required": "device-events",
83605
+ "device-attention-resolved": "device-events",
83590
83606
  "node-online": "system",
83591
83607
  "node-offline": "system",
83592
83608
  "node-restarting": "system",
@@ -83603,6 +83619,8 @@ var NC_SYSTEM_EVENT_FAMILY = {
83603
83619
  "alert-critical": "system",
83604
83620
  "alert-error": "system",
83605
83621
  "alert-critical-resolved": "system",
83622
+ "rule-broken": "system",
83623
+ "rule-repaired": "system",
83606
83624
  "storage-location-low": "system",
83607
83625
  "storage-location-critical": "system",
83608
83626
  "storage-location-ok": "system",
@@ -83668,6 +83686,12 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
83668
83686
  label: "Detecting nothing",
83669
83687
  kinds: ["detection-blind"]
83670
83688
  },
83689
+ {
83690
+ id: "motion-noise",
83691
+ family: "device-events",
83692
+ label: "Motion without a subject",
83693
+ kinds: ["motion-noisy", "motion-calm"]
83694
+ },
83671
83695
  {
83672
83696
  id: "recording",
83673
83697
  family: "device-events",
@@ -83678,6 +83702,12 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
83678
83702
  "recording-degraded"
83679
83703
  ]
83680
83704
  },
83705
+ {
83706
+ id: "device-attention",
83707
+ family: "device-events",
83708
+ label: "Needs attention",
83709
+ kinds: ["device-attention-required", "device-attention-resolved"]
83710
+ },
83681
83711
  {
83682
83712
  id: "nodes",
83683
83713
  family: "system",
@@ -83738,6 +83768,12 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
83738
83768
  "alert-critical-resolved"
83739
83769
  ]
83740
83770
  },
83771
+ {
83772
+ id: "rule-health",
83773
+ family: "system",
83774
+ label: "Notification rules",
83775
+ kinds: ["rule-broken", "rule-repaired"]
83776
+ },
83741
83777
  {
83742
83778
  id: "alarm",
83743
83779
  family: "alarm",
@@ -83788,6 +83824,7 @@ var ALERT_EPISODE = [
83788
83824
  "alert-error",
83789
83825
  "alert-critical-resolved"
83790
83826
  ];
83827
+ var DEVICE_ATTENTION = ["device-attention-required", "device-attention-resolved"];
83791
83828
  var UPDATES = [
83792
83829
  "addon-update-available",
83793
83830
  "server-update-available",
@@ -83817,9 +83854,12 @@ var DEVICE_EVENTS = [
83817
83854
  "stream-online",
83818
83855
  "stream-offline",
83819
83856
  "detection-blind",
83857
+ "motion-noisy",
83858
+ "motion-calm",
83820
83859
  "recording-stalled",
83821
83860
  "recording-healthy",
83822
83861
  "recording-degraded",
83862
+ ...DEVICE_ATTENTION,
83823
83863
  ...ALARM
83824
83864
  ];
83825
83865
  var SUMMARISABLE = [...systemEventKindsOfFamily("device-events"), ...systemEventKindsOfFamily("system")];
@@ -84390,7 +84430,36 @@ var NC_TEMPLATE_VARS = [
84390
84430
  families: ["rule"],
84391
84431
  fields: [...RULE_TEXT],
84392
84432
  kinds: ["system"],
84393
- systemEventKinds: ["detection-blind", "recording-stalled"]
84433
+ systemEventKinds: [
84434
+ "detection-blind",
84435
+ "motion-noisy",
84436
+ "motion-calm",
84437
+ "recording-stalled"
84438
+ ]
84439
+ },
84440
+ {
84441
+ name: "duty",
84442
+ label: "Motion share (%)",
84443
+ example: "55",
84444
+ group: "system",
84445
+ families: ["rule"],
84446
+ fields: [...RULE_TEXT],
84447
+ kinds: ["system"],
84448
+ systemEventKinds: ["motion-noisy", "motion-calm"]
84449
+ },
84450
+ {
84451
+ name: "sessions",
84452
+ label: "Detection sessions",
84453
+ example: "96",
84454
+ group: "system",
84455
+ families: ["rule"],
84456
+ fields: [...RULE_TEXT],
84457
+ kinds: ["system"],
84458
+ systemEventKinds: [
84459
+ "detection-blind",
84460
+ "motion-noisy",
84461
+ "motion-calm"
84462
+ ]
84394
84463
  },
84395
84464
  {
84396
84465
  name: "message",
@@ -84400,7 +84469,52 @@ var NC_TEMPLATE_VARS = [
84400
84469
  families: ["rule"],
84401
84470
  fields: [...RULE_TEXT],
84402
84471
  kinds: ["system"],
84403
- systemEventKinds: ["recording-degraded", ...ALERT_EPISODE]
84472
+ systemEventKinds: [
84473
+ "recording-degraded",
84474
+ ...DEVICE_ATTENTION,
84475
+ ...ALERT_EPISODE
84476
+ ]
84477
+ },
84478
+ {
84479
+ name: "ruleName",
84480
+ label: "Rule name",
84481
+ example: "Robot",
84482
+ group: "system",
84483
+ families: ["rule"],
84484
+ fields: [...RULE_TEXT],
84485
+ kinds: ["system"],
84486
+ systemEventKinds: ["rule-broken", "rule-repaired"]
84487
+ },
84488
+ {
84489
+ name: "ruleId",
84490
+ label: "Rule id",
84491
+ example: "3db3e226-9b82-4681-a200-de13b260aa48",
84492
+ group: "system",
84493
+ families: ["rule"],
84494
+ fields: [...RULE_TEXT],
84495
+ kinds: ["system"],
84496
+ systemEventKinds: ["rule-broken", "rule-repaired"]
84497
+ },
84498
+ {
84499
+ name: "brokenReason",
84500
+ label: "Why the rule is broken",
84501
+ description: "unparseable, device-deleted or target-deleted",
84502
+ example: "device-deleted",
84503
+ group: "system",
84504
+ families: ["rule"],
84505
+ fields: [...RULE_TEXT],
84506
+ kinds: ["system"],
84507
+ systemEventKinds: ["rule-broken"]
84508
+ },
84509
+ {
84510
+ name: "offendingIds",
84511
+ label: "Deleted devices or destinations",
84512
+ example: "4483",
84513
+ group: "system",
84514
+ families: ["rule"],
84515
+ fields: [...RULE_TEXT],
84516
+ kinds: ["system"],
84517
+ systemEventKinds: ["rule-broken"]
84404
84518
  },
84405
84519
  {
84406
84520
  name: "locationName",
@@ -84603,7 +84717,11 @@ var NC_TEMPLATE_VARS = [
84603
84717
  families: ["rule"],
84604
84718
  fields: [...RULE_TEXT],
84605
84719
  kinds: ["system"],
84606
- systemEventKinds: ["export-completed", ...ALERT_EPISODE]
84720
+ systemEventKinds: [
84721
+ "export-completed",
84722
+ ...DEVICE_ATTENTION,
84723
+ ...ALERT_EPISODE
84724
+ ]
84607
84725
  },
84608
84726
  {
84609
84727
  name: "severity",
@@ -84623,7 +84741,7 @@ var NC_TEMPLATE_VARS = [
84623
84741
  families: ["rule"],
84624
84742
  fields: [...RULE_TEXT],
84625
84743
  kinds: ["system"],
84626
- systemEventKinds: [...ALERT_EPISODE]
84744
+ systemEventKinds: [...DEVICE_ATTENTION, ...ALERT_EPISODE]
84627
84745
  },
84628
84746
  {
84629
84747
  name: "source",
@@ -84643,7 +84761,7 @@ var NC_TEMPLATE_VARS = [
84643
84761
  families: ["rule"],
84644
84762
  fields: [...RULE_TEXT],
84645
84763
  kinds: ["system"],
84646
- systemEventKinds: [...ALERT_EPISODE]
84764
+ systemEventKinds: [...DEVICE_ATTENTION, ...ALERT_EPISODE]
84647
84765
  },
84648
84766
  {
84649
84767
  name: "exportId",
@@ -84834,6 +84952,126 @@ var NC_TEMPLATE_VARS = [
84834
84952
  },
84835
84953
  ...STATE_SUMMARY_VARS
84836
84954
  ];
84955
+ var NC_SYSTEM_EVENT_CLASS_SPECS = [
84956
+ {
84957
+ id: "device-connectivity",
84958
+ family: "device-events",
84959
+ label: "Device connectivity (offline / back online)",
84960
+ bad: ["device-offline"],
84961
+ recovery: ["device-online"],
84962
+ snapshotLabel: "Devices offline now",
84963
+ snapshotSection: "device-state"
84964
+ },
84965
+ {
84966
+ id: "device-switch",
84967
+ family: "device-events",
84968
+ label: "Device switched off / back on",
84969
+ bad: ["device-disabled"],
84970
+ recovery: ["device-enabled"],
84971
+ snapshotLabel: "Devices switched off now",
84972
+ snapshotSection: "device-state"
84973
+ },
84974
+ {
84975
+ id: "stream-connectivity",
84976
+ family: "device-events",
84977
+ label: "Stream connectivity (offline / back online)",
84978
+ bad: ["stream-offline"],
84979
+ recovery: ["stream-online"],
84980
+ snapshotLabel: "Streams offline now",
84981
+ snapshotSection: "streams"
84982
+ },
84983
+ {
84984
+ id: "battery",
84985
+ family: "device-events",
84986
+ label: "Battery (low / back to normal)",
84987
+ bad: ["device-battery-low"],
84988
+ recovery: ["device-battery-normal"],
84989
+ snapshotLabel: "Batteries low now",
84990
+ snapshotSection: "battery"
84991
+ },
84992
+ {
84993
+ id: "consumables",
84994
+ family: "device-events",
84995
+ label: "Consumables (low / replaced)",
84996
+ bad: ["device-consumable-low"],
84997
+ recovery: ["device-consumable-normal"],
84998
+ snapshotLabel: "Consumables low now",
84999
+ snapshotSection: "consumables"
85000
+ },
85001
+ {
85002
+ id: "tanks",
85003
+ family: "device-events",
85004
+ label: "Tanks (low or full / back to normal)",
85005
+ bad: ["device-tank-low", "device-tank-full"],
85006
+ recovery: ["device-tank-normal"],
85007
+ snapshotLabel: "Tanks low or full now",
85008
+ snapshotSection: "tanks"
85009
+ },
85010
+ {
85011
+ id: "motion-noise",
85012
+ family: "device-events",
85013
+ label: "Motion without a subject (constant / calm again)",
85014
+ bad: ["motion-noisy"],
85015
+ recovery: ["motion-calm"],
85016
+ snapshotLabel: "Cameras with constant motion now",
85017
+ snapshotSection: null
85018
+ },
85019
+ {
85020
+ id: "recording-health",
85021
+ family: "device-events",
85022
+ label: "Recording health (stalled or degraded / recording again)",
85023
+ bad: ["recording-stalled", "recording-degraded"],
85024
+ recovery: ["recording-healthy"],
85025
+ snapshotLabel: "Recordings stalled now",
85026
+ snapshotSection: null
85027
+ },
85028
+ {
85029
+ id: "device-attention",
85030
+ family: "device-events",
85031
+ label: "Device needs attention (raised / resolved)",
85032
+ bad: ["device-attention-required"],
85033
+ recovery: ["device-attention-resolved"],
85034
+ snapshotLabel: "Devices needing attention now",
85035
+ snapshotSection: null
85036
+ },
85037
+ {
85038
+ id: "node-connectivity",
85039
+ family: "system",
85040
+ label: "Node connectivity (offline / back online)",
85041
+ bad: ["node-offline"],
85042
+ recovery: ["node-online"],
85043
+ snapshotLabel: "Nodes offline now",
85044
+ snapshotSection: "nodes"
85045
+ },
85046
+ {
85047
+ id: "storage-space",
85048
+ family: "system",
85049
+ label: "Storage space (low or critical / ok again)",
85050
+ bad: ["storage-location-low", "storage-location-critical"],
85051
+ recovery: ["storage-location-ok"],
85052
+ snapshotLabel: "Storage locations low now",
85053
+ snapshotSection: null
85054
+ },
85055
+ {
85056
+ id: "critical-alerts",
85057
+ family: "system",
85058
+ label: "Critical alerts (raised / resolved)",
85059
+ bad: ["alert-critical"],
85060
+ recovery: ["alert-critical-resolved"],
85061
+ snapshotLabel: "Critical alerts open now",
85062
+ snapshotSection: null
85063
+ },
85064
+ {
85065
+ id: "rule-health",
85066
+ family: "system",
85067
+ label: "Rule health (broken / repaired)",
85068
+ bad: ["rule-broken"],
85069
+ recovery: ["rule-repaired"],
85070
+ snapshotLabel: "Notification rules broken now",
85071
+ snapshotSection: null
85072
+ }
85073
+ ];
85074
+ var CLASS_BY_KIND = new Map(NC_SYSTEM_EVENT_CLASS_SPECS.flatMap((spec) => [...spec.bad, ...spec.recovery].map((kind) => [kind, spec])));
84837
85075
  var STATE_LABEL_KEYS = [
84838
85076
  "disarmed",
84839
85077
  "armed_home",