@camstack/addon-post-analysis 1.2.323 → 1.2.325

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.
@@ -19526,6 +19526,15 @@ var AlarmArmModeSchema = _enum([
19526
19526
  var AlarmPanelStatusSchema = object({
19527
19527
  /** Current lifecycle state. */
19528
19528
  state: AlarmStateSchema,
19529
+ /**
19530
+ * The arm mode the machine belongs to under transitional words
19531
+ * (`arming` / `pending` / `triggered` / `disarming`). `null` when
19532
+ * disarmed or when a provider cannot name one. Exporters MUST prefer
19533
+ * this over an in-process memo — a HomeKit accessory that missed the
19534
+ * settled `armed_*` slice used to map `pending` to DISARMED and hide
19535
+ * an entry delay.
19536
+ */
19537
+ targetMode: AlarmArmModeSchema.nullable().optional(),
19529
19538
  /** Subset of arm modes the panel accepts. UI renders one button per
19530
19539
  * mode in this list. */
19531
19540
  availableModes: array(AlarmArmModeSchema),
@@ -19495,6 +19495,15 @@ var AlarmArmModeSchema = _enum([
19495
19495
  var AlarmPanelStatusSchema = object({
19496
19496
  /** Current lifecycle state. */
19497
19497
  state: AlarmStateSchema,
19498
+ /**
19499
+ * The arm mode the machine belongs to under transitional words
19500
+ * (`arming` / `pending` / `triggered` / `disarming`). `null` when
19501
+ * disarmed or when a provider cannot name one. Exporters MUST prefer
19502
+ * this over an in-process memo — a HomeKit accessory that missed the
19503
+ * settled `armed_*` slice used to map `pending` to DISARMED and hide
19504
+ * an entry delay.
19505
+ */
19506
+ targetMode: AlarmArmModeSchema.nullable().optional(),
19498
19507
  /** Subset of arm modes the panel accepts. UI renders one button per
19499
19508
  * mode in this list. */
19500
19509
  availableModes: array(AlarmArmModeSchema),
@@ -2,7 +2,7 @@ Object.defineProperties(exports, {
2
2
  __esModule: { value: true },
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
- const require_clip_model_registry = require("../clip-model-registry-8IMzj7jJ.js");
5
+ const require_clip_model_registry = require("../clip-model-registry-BFLeI0dr.js");
6
6
  let node_fs = require("node:fs");
7
7
  node_fs = require_clip_model_registry.__toESM(node_fs);
8
8
  let node_path = require("node:path");
@@ -1,4 +1,4 @@
1
- import { Gn as embeddingRequirementsUnavailableError, Hn as embeddingModelFailedError, Or as resolvePoolMemoryPolicy, Vn as embeddingEncoderCapability, Wn as embeddingRequirementsFailedError, a as CLIP_EMBEDDING_STEP_ID, c as resolveClusterModelPin, i as CLIP_TEXT_MODELS, li as normalizeNodeId, n as DEFAULT_CLIP_MODEL, qt as PoolMemoryWatchdog, r as CLIP_IMAGE_MODELS, t as BUILTIN_CLIP_MODELS, ti as BaseAddon, vr as parseProcStatus } from "../clip-model-registry-BENGs4rw.mjs";
1
+ import { Gn as embeddingRequirementsUnavailableError, Hn as embeddingModelFailedError, Or as resolvePoolMemoryPolicy, Vn as embeddingEncoderCapability, Wn as embeddingRequirementsFailedError, a as CLIP_EMBEDDING_STEP_ID, c as resolveClusterModelPin, i as CLIP_TEXT_MODELS, li as normalizeNodeId, n as DEFAULT_CLIP_MODEL, qt as PoolMemoryWatchdog, r as CLIP_IMAGE_MODELS, t as BUILTIN_CLIP_MODELS, ti as BaseAddon, vr as parseProcStatus } from "../clip-model-registry-CshjlVTF.mjs";
2
2
  import { createRequire } from "node:module";
3
3
  import * as fs from "node:fs";
4
4
  import * as path$1 from "node:path";
@@ -18,7 +18,7 @@ var e = {
18
18
  },
19
19
  "@camstack/types": {
20
20
  name: "@camstack/types",
21
- version: "1.2.299",
21
+ version: "1.2.300",
22
22
  scope: ["default"],
23
23
  loaded: !1,
24
24
  from: "addon_pipeline_analytics_widgets",
@@ -36,7 +36,7 @@ async function r() {
36
36
  }
37
37
  },
38
38
  "@camstack/types": {
39
- version: "1.2.299",
39
+ version: "1.2.300",
40
40
  scope: "default",
41
41
  shareConfig: {
42
42
  singleton: !0,
@@ -2,7 +2,7 @@ Object.defineProperties(exports, {
2
2
  __esModule: { value: true },
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
- const require_clip_model_registry = require("../clip-model-registry-8IMzj7jJ.js");
5
+ const require_clip_model_registry = require("../clip-model-registry-BFLeI0dr.js");
6
6
  let node_fs = require("node:fs");
7
7
  node_fs = require_clip_model_registry.__toESM(node_fs, 1);
8
8
  let node_path = require("node:path");
@@ -484,26 +484,37 @@ function buildArmAnnouncement(coverage, deviceName, bypassed = []) {
484
484
  };
485
485
  }
486
486
  /**
487
- * "Attivi: 2 — Bypassati: Finestra veranda."
487
+ * "Attivi: Porta retro, Cancello — Bypassati: Finestra veranda."
488
488
  *
489
- * The bypassed sensors are named and the armed ones are COUNTED, not listed:
490
- * this sentence's subject is the exception, and burying it under thirteen
491
- * camera names is how an operator stops reading the arm notification. The
492
- * count pluralises on what IS armed, like every other arm variant.
489
+ * Both halves are named: the bypassed sensors are why the operator pressed
490
+ * Arm anyway, and the remaining ones are what is still promised. An
491
+ * all-devices mode has no finite list to name — it uses a dedicated key.
493
492
  */
494
493
  function armedWithBypass(coverage, bypassed, deviceName) {
495
494
  const skipped = new Set(coverage.skippedDevices.map((s) => s.deviceId));
496
495
  const excluded = new Set(bypassed);
497
- const armed = coverage.allDevices ? coverage.ruleCount : coverage.deviceIds.filter((id) => !skipped.has(id) && !excluded.has(id)).length;
496
+ const bypassedNames = bypassed.map(deviceName).join(", ");
497
+ if (coverage.allDevices) return {
498
+ bodyKey: "alarm.arm.body.bypassedAll",
499
+ textParams: {
500
+ rules: `${coverage.ruleCount}`,
501
+ mode: coverage.mode,
502
+ bypassedNames
503
+ },
504
+ textCount: coverage.ruleCount
505
+ };
506
+ const armedIds = coverage.deviceIds.filter((id) => !skipped.has(id) && !excluded.has(id));
507
+ const names = armedIds.map(deviceName).join(", ");
498
508
  return {
499
509
  bodyKey: "alarm.arm.body.bypassed",
500
510
  textParams: {
501
511
  rules: `${coverage.ruleCount}`,
502
512
  mode: coverage.mode,
503
- devices: `${armed}`,
504
- bypassedNames: bypassed.map(deviceName).join(", ")
513
+ devices: `${armedIds.length}`,
514
+ names,
515
+ bypassedNames
505
516
  },
506
- textCount: armed
517
+ textCount: armedIds.length
507
518
  };
508
519
  }
509
520
  /**
@@ -1098,10 +1109,11 @@ var NcActionPlane = class {
1098
1109
  * Anything short of fully secure is open: a cover stopped half-way, a lock that
1099
1110
  * jammed, a cover still closing when the arm is decided, a switch that is on.
1100
1111
  *
1101
- * PRECEDENCE, when one device carries more than one opening slice: `contact`
1102
- * first, then `cover`, then `lock-control`, then `switch`. The contact is the
1103
- * physical truth about the opening — a reed switch on the frame says the window
1104
- * is open even when the motor's last reported word says `closed`.
1112
+ * PRECEDENCE, when one device carries more than one opening slice: any OPEN
1113
+ * reading wins over a secure one (a reed that says open beats a motor that
1114
+ * still says `closed`). Among opens, a controllable cap (`cover` / `lock-control`
1115
+ * / `switch`) wins so secure-on-arm knows what to actuate; among secures the
1116
+ * contact wins as the physical "closed" when the motor has not moved yet.
1105
1117
  */
1106
1118
  /** The one state word, per cap, that counts as secure. Everything else is open. */
1107
1119
  var COVER_SECURE = "closed";
@@ -1214,6 +1226,11 @@ function readSwitch(runtime) {
1214
1226
  }
1215
1227
  /** D630's table over one device's runtime slices — see the header for the three answers. */
1216
1228
  function alarmOpeningFrom(runtime) {
1229
+ let openControllable = null;
1230
+ let openAny = null;
1231
+ let secureContact = null;
1232
+ let secureControllable = null;
1233
+ let secureAny = null;
1217
1234
  let firstUnknown = null;
1218
1235
  for (const read of [
1219
1236
  readContact(runtime),
@@ -1221,10 +1238,21 @@ function alarmOpeningFrom(runtime) {
1221
1238
  readLock(runtime),
1222
1239
  readSwitch(runtime)
1223
1240
  ]) {
1224
- if (read.kind === "reading") return read;
1225
- if (read.kind === "unknown" && firstUnknown === null) firstUnknown = read;
1241
+ if (read.kind === "unknown") {
1242
+ if (firstUnknown === null) firstUnknown = read;
1243
+ continue;
1244
+ }
1245
+ if (read.kind !== "reading") continue;
1246
+ if (read.reading === "open") {
1247
+ if (require_clip_model_registry.isAlarmControllableCap(read.cap) && openControllable === null) openControllable = read;
1248
+ if (openAny === null) openAny = read;
1249
+ continue;
1250
+ }
1251
+ if (read.cap === "contact" && secureContact === null) secureContact = read;
1252
+ if (require_clip_model_registry.isAlarmControllableCap(read.cap) && secureControllable === null) secureControllable = read;
1253
+ if (secureAny === null) secureAny = read;
1226
1254
  }
1227
- return firstUnknown ?? NOT_OPENING;
1255
+ return openControllable ?? openAny ?? secureContact ?? secureControllable ?? secureAny ?? firstUnknown ?? NOT_OPENING;
1228
1256
  }
1229
1257
  /**
1230
1258
  * The sensor-event kind (`CAP_TO_KIND` in `@camstack/types`) → the cap whose
@@ -2750,12 +2778,6 @@ var NcAlarmPanelDevice = class extends require_clip_model_registry.BaseDevice {
2750
2778
  error: String(err)
2751
2779
  };
2752
2780
  }
2753
- const toSecure = openings.open.filter((d) => require_clip_model_registry.alarmDeviceSecureOnArm({
2754
- controllable: d.controllable,
2755
- deviceId: d.deviceId,
2756
- secureOnArmOff: this.secureOnArmOffFor(mode)
2757
- }));
2758
- if (toSecure.length > 0) this.armGuard?.secureOnArm(toSecure);
2759
2781
  const verdict = decideArm({
2760
2782
  mode,
2761
2783
  open: openings.open,
@@ -2763,6 +2785,14 @@ var NcAlarmPanelDevice = class extends require_clip_model_registry.BaseDevice {
2763
2785
  blocking: this.blockingFor(mode),
2764
2786
  ...acknowledged !== void 0 ? { acknowledged } : {}
2765
2787
  });
2788
+ if (verdict.kind === "arm") {
2789
+ const toSecure = openings.open.filter((d) => require_clip_model_registry.alarmDeviceSecureOnArm({
2790
+ controllable: d.controllable,
2791
+ deviceId: d.deviceId,
2792
+ secureOnArmOff: this.secureOnArmOffFor(mode)
2793
+ }));
2794
+ if (toSecure.length > 0) this.armGuard?.secureOnArm(toSecure);
2795
+ }
2766
2796
  return {
2767
2797
  kind: "read",
2768
2798
  openings,
@@ -2971,6 +3001,7 @@ var NcAlarmPanelDevice = class extends require_clip_model_registry.BaseDevice {
2971
3001
  status(now = Date.now()) {
2972
3002
  return {
2973
3003
  state: stateAt(this.machine, now),
3004
+ targetMode: armModeOf(this.machine.target, NC_ALARM_MODES),
2974
3005
  availableModes: [...NC_ALARM_MODES],
2975
3006
  requiresCode: false,
2976
3007
  lastChangedAt: this.machine.changedAt
@@ -12911,7 +12942,7 @@ function incomingFromAlarmTransition(input) {
12911
12942
  const kind = transition.kind;
12912
12943
  const keys = alarmTextKeys(transition, input.body);
12913
12944
  const sensor = transition.sensor;
12914
- const alarmSource = kind === "alarm-triggered" ? source : void 0;
12945
+ const alarmSource = (kind === "alarm-triggered" || kind === "alarm-pending") && source !== void 0 ? source : void 0;
12915
12946
  const facts = {
12916
12947
  eventId: `alarm:${kind}:${String(transition.at)}${sensor !== void 0 ? `:${String(sensor.deviceId)}` : ""}${transition.refusalId !== void 0 ? `:${transition.refusalId}` : ""}`,
12917
12948
  timestamp: transition.at,
@@ -14446,35 +14477,35 @@ var en_default = {
14446
14477
  "occupancy.body": "{{scope}} {{op}} ({{count}}/{{capacity}})",
14447
14478
  "occupancy.op.occupied": "occupied",
14448
14479
  "occupancy.op.free": "free",
14449
- "system.device-online.title": "Device online",
14480
+ "system.device-online.title": "Online — {{deviceName}}",
14450
14481
  "system.device-online.body": "Device {{deviceName}} is online",
14451
- "system.device-offline.title": "Device offline",
14482
+ "system.device-offline.title": "Offline — {{deviceName}}",
14452
14483
  "system.device-offline.body": "Device {{deviceName}} is offline",
14453
- "system.device-disabled.title": "Device switched off",
14484
+ "system.device-disabled.title": "Switched off — {{deviceName}}",
14454
14485
  "system.device-disabled.body": "Device {{deviceName}} was switched off",
14455
- "system.device-enabled.title": "Device switched on",
14486
+ "system.device-enabled.title": "Switched on — {{deviceName}}",
14456
14487
  "system.device-enabled.body": "Device {{deviceName}} was switched back on",
14457
- "system.device-battery-low.title": "Battery low",
14488
+ "system.device-battery-low.title": "Battery low — {{deviceName}}",
14458
14489
  "system.device-battery-low.body": "{{deviceName}} is down to {{percentage}}% battery",
14459
14490
  "system.device-battery-low.body.binary": "{{deviceName}} reports a low battery",
14460
- "system.device-battery-normal.title": "Battery back to normal",
14491
+ "system.device-battery-normal.title": "Battery back to normal — {{deviceName}}",
14461
14492
  "system.device-battery-normal.body": "{{deviceName}} is back to {{percentage}}% battery",
14462
14493
  "system.device-battery-normal.body.binary": "{{deviceName}} no longer reports a low battery",
14463
- "system.stream-online.title": "Stream online",
14494
+ "system.stream-online.title": "Stream online — {{deviceName}}",
14464
14495
  "system.stream-online.body": "Stream for camera {{deviceName}} is online",
14465
14496
  "system.stream-online.body.profiled": "{{profile}} stream for camera {{deviceName}} is online",
14466
- "system.stream-offline.title": "Stream offline",
14497
+ "system.stream-offline.title": "Stream offline — {{deviceName}}",
14467
14498
  "system.stream-offline.body": "Stream for camera {{deviceName}} is offline",
14468
14499
  "system.stream-offline.body.profiled": "{{profile}} stream for camera {{deviceName}} is offline",
14469
- "system.node-online.title": "Node online",
14500
+ "system.node-online.title": "Node online — {{nodeId}}",
14470
14501
  "system.node-online.body.agent": "Agent {{nodeId}} is online",
14471
- "system.node-offline.title": "Node offline",
14502
+ "system.node-offline.title": "Node offline — {{nodeId}}",
14472
14503
  "system.node-offline.body.agent": "Agent {{nodeId}} is offline",
14473
- "system.node-inference-unavailable.title": "Node has no usable inference device",
14504
+ "system.node-inference-unavailable.title": "Node cannot infer — {{nodeId}}",
14474
14505
  "system.node-inference-unavailable.body": "Node {{nodeId}} can no longer run inference — every enabled device is unavailable ({{devices}}). It will not receive cameras until one returns.",
14475
- "system.addon-crash-loop.title": "Addon stopped after repeated crashes",
14506
+ "system.addon-crash-loop.title": "Addon crash-loop — {{nodeId}}",
14476
14507
  "system.addon-crash-loop.body": "The {{addons}} addon on node {{nodeId}} crashed {{count}} times in a row and will NOT be restarted. Everything it provides is offline until it is repaired.",
14477
- "system.detection-blind.title": "Camera detecting nothing",
14508
+ "system.detection-blind.title": "Detecting nothing — {{deviceName}}",
14478
14509
  "system.detection-blind.body": {
14479
14510
  "one": "Camera {{deviceName}} has been analysed for {{minutes}} minute with no detection at all",
14480
14511
  "other": "Camera {{deviceName}} has been analysed for {{minutes}} minutes with no detection at all"
@@ -14515,15 +14546,15 @@ var en_default = {
14515
14546
  "system.backup-completed.title": "Backup completed",
14516
14547
  "system.backup-completed.body": "Backup saved to {{destinationsOk}} of {{destinationsTotal}} destinations ({{sizeMB}} MB)",
14517
14548
  "system.backup-completed.body.partial": "Backup saved to {{destinationsOk}} of {{destinationsTotal}} destinations — {{destinationsFailed}} failed",
14518
- "system.device-consumable-low.title": "Consumable low",
14549
+ "system.device-consumable-low.title": "Consumable low — {{deviceName}}",
14519
14550
  "system.device-consumable-low.body": "{{item}} on {{deviceName}} is at {{percentage}}%",
14520
14551
  "system.device-consumable-low.body.unmeasured": "{{item}} on {{deviceName}} needs replacing",
14521
- "system.device-consumable-normal.title": "Consumable replaced",
14552
+ "system.device-consumable-normal.title": "Consumable replaced — {{deviceName}}",
14522
14553
  "system.device-consumable-normal.body": "{{item}} on {{deviceName}} is back to {{percentage}}%",
14523
14554
  "system.device-consumable-normal.body.unmeasured": "{{item}} on {{deviceName}} is OK again",
14524
- "system.device-tank-low.title": "Tank low",
14525
- "system.device-tank-full.title": "Tank full",
14526
- "system.device-tank-normal.title": "Tank OK",
14555
+ "system.device-tank-low.title": "Tank low — {{deviceName}}",
14556
+ "system.device-tank-full.title": "Tank full — {{deviceName}}",
14557
+ "system.device-tank-normal.title": "Tank OK — {{deviceName}}",
14527
14558
  "system.device-tank-low.body.cleanWater": "The clean water tank on {{deviceName}} is running low",
14528
14559
  "system.device-tank-full.body.cleanWater": "The clean water tank on {{deviceName}} is full",
14529
14560
  "system.device-tank-normal.body.cleanWater": "The clean water tank on {{deviceName}} is OK again",
@@ -14565,7 +14596,7 @@ var en_default = {
14565
14596
  "snooze.scope.anyRule": "A rule",
14566
14597
  "snooze.scope.rule": "“{{rule}}”",
14567
14598
  "alarm.arm.body.allDevices": "Active: all devices",
14568
- "alarm.arm.body.allDevicesExcept": "Active: all devices except {{count}}: {{names}}",
14599
+ "alarm.arm.body.allDevicesExcept": "Active: all devices except {{names}}",
14569
14600
  "alarm.arm.body.noDevices": "Active: no device restriction",
14570
14601
  "alarm.arm.body.devices": "Active: {{names}}",
14571
14602
  "alarm.arm.body.devicesSkipped": "Active: {{names}}\nExcluded: {{skippedNames}}",
@@ -14575,7 +14606,8 @@ var en_default = {
14575
14606
  "alarm.arming.body.uncovered": "Active: none — no rule uses this mode",
14576
14607
  "alarm.arming.body.allSkipped": "Active: none\nExcluded: {{names}}",
14577
14608
  "alarm.arming.body.skipped": "Excluded: {{names}}",
14578
- "alarm.arm.body.bypassed": "Active: {{devices}}\nBypassed: {{bypassedNames}}",
14609
+ "alarm.arm.body.bypassed": "Active: {{names}}\nBypassed: {{bypassedNames}}",
14610
+ "alarm.arm.body.bypassedAll": "Active: all devices\nBypassed: {{bypassedNames}}",
14579
14611
  "alarm.arming.body.bypassed": "Bypassed: {{bypassedNames}}",
14580
14612
  "alarm.armRefused.body": "Open: {{names}}",
14581
14613
  "alarm.armRefused.body.hint": "Open: {{names}}\nTap “Arm anyway” to arm with them excluded.",
@@ -14663,19 +14695,19 @@ var en_default = {
14663
14695
  "summary.body.detections": "{{detectionSummary}}",
14664
14696
  "summary.body.truncated": "showing the {{shown}} most relevant of {{total}}",
14665
14697
  "summary.body.empty": "nothing was seen in this window",
14666
- "system.state-summary.title": "{{rule}}",
14698
+ "system.state-summary.title": "{{rule}}: {{summaryCount}}",
14667
14699
  "system.state-summary.body": "{{summaryText}}",
14668
- "system.state-summary.section.title": "{{rule}} — {{summarySection}}",
14700
+ "system.state-summary.section.title": "{{summarySection}}: {{summaryCount}}",
14669
14701
  "system.state-summary.section.body": "{{summaryText}}",
14670
- "summary.section.device-state": "Devices offline or switched off",
14702
+ "summary.section.device-state": "Offline or off",
14671
14703
  "summary.section.streams": "Streams offline",
14672
14704
  "summary.section.battery": "Low batteries",
14673
14705
  "summary.section.consumables": "Consumables to replace",
14674
- "summary.section.tanks": "Tanks",
14675
- "summary.section.detection-blind": "Cameras detecting nothing",
14706
+ "summary.section.tanks": "Tanks low",
14707
+ "summary.section.detection-blind": "Detecting nothing",
14676
14708
  "summary.section.nodes": "Nodes",
14677
14709
  "summary.section.addons": "Addons",
14678
- "summary.section.updates": "Server and container updates",
14710
+ "summary.section.updates": "Updates",
14679
14711
  "summary.section.unavailable": "{{section}}: unavailable — the state could not be read",
14680
14712
  "summary.line.device-offline": "{{deviceName}} — offline (since {{since}})",
14681
14713
  "summary.line.device-disabled": "{{deviceName}} — switched off (since {{since}})",
@@ -14773,35 +14805,35 @@ var it_default = {
14773
14805
  "occupancy.body": "{{scope}} {{op}} ({{count}}/{{capacity}})",
14774
14806
  "occupancy.op.occupied": "occupata",
14775
14807
  "occupancy.op.free": "libera",
14776
- "system.device-online.title": "Dispositivo online",
14808
+ "system.device-online.title": "Online — {{deviceName}}",
14777
14809
  "system.device-online.body": "Il dispositivo {{deviceName}} è online",
14778
- "system.device-offline.title": "Dispositivo offline",
14810
+ "system.device-offline.title": "Offline — {{deviceName}}",
14779
14811
  "system.device-offline.body": "Il dispositivo {{deviceName}} è offline",
14780
- "system.device-disabled.title": "Dispositivo spento",
14812
+ "system.device-disabled.title": "Spento — {{deviceName}}",
14781
14813
  "system.device-disabled.body": "Il dispositivo {{deviceName}} è stato spento",
14782
- "system.device-enabled.title": "Dispositivo riacceso",
14814
+ "system.device-enabled.title": "Riacceso — {{deviceName}}",
14783
14815
  "system.device-enabled.body": "Il dispositivo {{deviceName}} è stato riacceso",
14784
- "system.device-battery-low.title": "Batteria scarica",
14816
+ "system.device-battery-low.title": "Batteria scarica — {{deviceName}}",
14785
14817
  "system.device-battery-low.body": "{{deviceName}} è al {{percentage}}% di batteria",
14786
14818
  "system.device-battery-low.body.binary": "{{deviceName}} segnala la batteria scarica",
14787
- "system.device-battery-normal.title": "Batteria rientrata",
14819
+ "system.device-battery-normal.title": "Batteria rientrata — {{deviceName}}",
14788
14820
  "system.device-battery-normal.body": "{{deviceName}} è risalito al {{percentage}}% di batteria",
14789
14821
  "system.device-battery-normal.body.binary": "{{deviceName}} non segnala più la batteria scarica",
14790
- "system.stream-online.title": "Stream online",
14822
+ "system.stream-online.title": "Stream online — {{deviceName}}",
14791
14823
  "system.stream-online.body": "Lo stream della camera {{deviceName}} è online",
14792
14824
  "system.stream-online.body.profiled": "Lo stream {{profile}} della camera {{deviceName}} è online",
14793
- "system.stream-offline.title": "Stream offline",
14825
+ "system.stream-offline.title": "Stream offline — {{deviceName}}",
14794
14826
  "system.stream-offline.body": "Lo stream della camera {{deviceName}} è offline",
14795
14827
  "system.stream-offline.body.profiled": "Lo stream {{profile}} della camera {{deviceName}} è offline",
14796
- "system.node-online.title": "Nodo online",
14828
+ "system.node-online.title": "Nodo online — {{nodeId}}",
14797
14829
  "system.node-online.body.agent": "L'agent {{nodeId}} è online",
14798
- "system.node-offline.title": "Nodo offline",
14830
+ "system.node-offline.title": "Nodo offline — {{nodeId}}",
14799
14831
  "system.node-offline.body.agent": "L'agent {{nodeId}} è offline",
14800
- "system.node-inference-unavailable.title": "Nodo senza dispositivi di inferenza utilizzabili",
14832
+ "system.node-inference-unavailable.title": "Nodo senza inferenza — {{nodeId}}",
14801
14833
  "system.node-inference-unavailable.body": "Il nodo {{nodeId}} non può più eseguire inferenza — tutti i dispositivi abilitati non sono disponibili ({{devices}}). Non riceverà camere finché uno non torna disponibile.",
14802
- "system.addon-crash-loop.title": "Addon fermato dopo ripetuti crash",
14834
+ "system.addon-crash-loop.title": "Crash-loop addon — {{nodeId}}",
14803
14835
  "system.addon-crash-loop.body": "L'addon {{addons}} sul nodo {{nodeId}} è andato in crash {{count}} volte di seguito e NON verrà riavviato. Tutto ciò che fornisce resta offline finché non viene riparato.",
14804
- "system.detection-blind.title": "Camera che non rileva nulla",
14836
+ "system.detection-blind.title": "Senza detection — {{deviceName}}",
14805
14837
  "system.detection-blind.body": {
14806
14838
  "one": "La camera {{deviceName}} è analizzata da {{minutes}} minuto senza alcun rilevamento",
14807
14839
  "other": "La camera {{deviceName}} è analizzata da {{minutes}} minuti senza alcun rilevamento"
@@ -14842,15 +14874,15 @@ var it_default = {
14842
14874
  "system.backup-completed.title": "Backup completato",
14843
14875
  "system.backup-completed.body": "Backup salvato su {{destinationsOk}} destinazioni su {{destinationsTotal}} ({{sizeMB}} MB)",
14844
14876
  "system.backup-completed.body.partial": "Backup salvato su {{destinationsOk}} destinazioni su {{destinationsTotal}} — {{destinationsFailed}} fallite",
14845
- "system.device-consumable-low.title": "Consumabile quasi esaurito",
14877
+ "system.device-consumable-low.title": "Consumabile basso — {{deviceName}}",
14846
14878
  "system.device-consumable-low.body": "{{item}} su {{deviceName}} è al {{percentage}}%",
14847
14879
  "system.device-consumable-low.body.unmeasured": "{{item}} su {{deviceName}} va sostituito",
14848
- "system.device-consumable-normal.title": "Consumabile sostituito",
14880
+ "system.device-consumable-normal.title": "Consumabile sostituito — {{deviceName}}",
14849
14881
  "system.device-consumable-normal.body": "{{item}} su {{deviceName}} è tornato al {{percentage}}%",
14850
14882
  "system.device-consumable-normal.body.unmeasured": "{{item}} su {{deviceName}} è di nuovo a posto",
14851
- "system.device-tank-low.title": "Serbatoio quasi vuoto",
14852
- "system.device-tank-full.title": "Serbatoio pieno",
14853
- "system.device-tank-normal.title": "Serbatoio a posto",
14883
+ "system.device-tank-low.title": "Serbatoio quasi vuoto — {{deviceName}}",
14884
+ "system.device-tank-full.title": "Serbatoio pieno — {{deviceName}}",
14885
+ "system.device-tank-normal.title": "Serbatoio a posto — {{deviceName}}",
14854
14886
  "system.device-tank-low.body.cleanWater": "Il serbatoio dell'acqua pulita di {{deviceName}} è quasi vuoto",
14855
14887
  "system.device-tank-full.body.cleanWater": "Il serbatoio dell'acqua pulita di {{deviceName}} è pieno",
14856
14888
  "system.device-tank-normal.body.cleanWater": "Il serbatoio dell'acqua pulita di {{deviceName}} è di nuovo a posto",
@@ -14892,7 +14924,7 @@ var it_default = {
14892
14924
  "snooze.scope.anyRule": "Una regola",
14893
14925
  "snooze.scope.rule": "“{{rule}}”",
14894
14926
  "alarm.arm.body.allDevices": "Attivi: tutti i dispositivi",
14895
- "alarm.arm.body.allDevicesExcept": "Attivi: tutti i dispositivi tranne {{count}}: {{names}}",
14927
+ "alarm.arm.body.allDevicesExcept": "Attivi: tutti i dispositivi tranne {{names}}",
14896
14928
  "alarm.arm.body.noDevices": "Attivi: nessuna restrizione",
14897
14929
  "alarm.arm.body.devices": "Attivi: {{names}}",
14898
14930
  "alarm.arm.body.devicesSkipped": "Attivi: {{names}}\nEsclusi: {{skippedNames}}",
@@ -14902,7 +14934,8 @@ var it_default = {
14902
14934
  "alarm.arming.body.uncovered": "Attivi: nessuno — nessuna regola usa questa modalità",
14903
14935
  "alarm.arming.body.allSkipped": "Attivi: nessuno\nEsclusi: {{names}}",
14904
14936
  "alarm.arming.body.skipped": "Esclusi: {{names}}",
14905
- "alarm.arm.body.bypassed": "Attivi: {{devices}}\nBypassati: {{bypassedNames}}",
14937
+ "alarm.arm.body.bypassed": "Attivi: {{names}}\nBypassati: {{bypassedNames}}",
14938
+ "alarm.arm.body.bypassedAll": "Attivi: tutti i dispositivi\nBypassati: {{bypassedNames}}",
14906
14939
  "alarm.arming.body.bypassed": "Bypassati: {{bypassedNames}}",
14907
14940
  "alarm.armRefused.body": "Aperti: {{names}}",
14908
14941
  "alarm.armRefused.body.hint": "Aperti: {{names}}\nTocca “Arma comunque” per armare escludendoli.",
@@ -14990,19 +15023,19 @@ var it_default = {
14990
15023
  "summary.body.detections": "{{detectionSummary}}",
14991
15024
  "summary.body.truncated": "mostrati i {{shown}} più rilevanti su {{total}}",
14992
15025
  "summary.body.empty": "nessun evento in questa finestra",
14993
- "system.state-summary.title": "{{rule}}",
15026
+ "system.state-summary.title": "{{rule}}: {{summaryCount}}",
14994
15027
  "system.state-summary.body": "{{summaryText}}",
14995
- "system.state-summary.section.title": "{{rule}} — {{summarySection}}",
15028
+ "system.state-summary.section.title": "{{summarySection}}: {{summaryCount}}",
14996
15029
  "system.state-summary.section.body": "{{summaryText}}",
14997
- "summary.section.device-state": "Dispositivi offline o spenti",
15030
+ "summary.section.device-state": "Offline o spenti",
14998
15031
  "summary.section.streams": "Stream offline",
14999
15032
  "summary.section.battery": "Batterie scariche",
15000
15033
  "summary.section.consumables": "Consumabili da sostituire",
15001
- "summary.section.tanks": "Serbatoi",
15002
- "summary.section.detection-blind": "Camere che non rilevano nulla",
15034
+ "summary.section.tanks": "Serbatoi bassi",
15035
+ "summary.section.detection-blind": "Senza detection",
15003
15036
  "summary.section.nodes": "Nodi",
15004
15037
  "summary.section.addons": "Addon",
15005
- "summary.section.updates": "Aggiornamenti di server e container",
15038
+ "summary.section.updates": "Aggiornamenti",
15006
15039
  "summary.section.unavailable": "{{section}}: non disponibile — lo stato non è leggibile",
15007
15040
  "summary.line.device-offline": "{{deviceName}} — offline (da {{since}})",
15008
15041
  "summary.line.device-disabled": "{{deviceName}} — spento (da {{since}})",
@@ -37097,13 +37130,16 @@ function frozenOccupancy(rule, occ) {
37097
37130
  function fireRefFor(rule, subject, kind) {
37098
37131
  const hasEventMedia = kind === "object-event" || kind === "package-event";
37099
37132
  const className = subject.classNames[0];
37133
+ const linkedOwners = subject.trackId === void 0 && subject.linkedStills !== void 0 ? linkedMediaOwners(subject.linkedStills, linkedCameraMode(rule.media)) : void 0;
37134
+ const trackId = subject.trackId ?? linkedOwners?.trackId;
37100
37135
  return {
37101
37136
  ruleId: rule.id,
37102
37137
  ruleName: rule.name,
37103
37138
  deviceId: subject.deviceId,
37104
37139
  ...subject.sourceDeviceId !== void 0 ? { sourceDeviceId: subject.sourceDeviceId } : {},
37105
37140
  recordId: subject.recordId,
37106
- ...subject.trackId !== void 0 ? { trackId: subject.trackId } : {},
37141
+ ...trackId !== void 0 ? { trackId } : {},
37142
+ ...linkedOwners !== void 0 && linkedOwners.extraStills.length > 0 ? { extraStills: linkedOwners.extraStills.map((x) => ({ ...x })) } : {},
37107
37143
  ...hasEventMedia ? { eventId: subject.recordId } : {},
37108
37144
  timestamp: subject.timestamp,
37109
37145
  ...className !== void 0 ? { className } : {},
@@ -40729,10 +40765,11 @@ var NotificationCenter = class {
40729
40765
  const alarmSource = subject.systemEvent?.alarmSource;
40730
40766
  const sourceRule = alarmSource !== void 0 ? this.rules.get(alarmSource.ruleId) : null;
40731
40767
  const media = sourceRule !== null ? mediaPolicyFields(sourceRule, void 0) : { media: "none" };
40768
+ const mediaDeviceId = alarmSource?.deviceId ?? panel.deviceId;
40732
40769
  const entries = targets.map((targetId) => ({
40733
40770
  ruleId: NC_ALARM_ANNOUNCE_RULE_ID,
40734
40771
  targetId,
40735
- deviceId: panel.deviceId,
40772
+ deviceId: mediaDeviceId,
40736
40773
  recordKind: "system-event",
40737
40774
  recordId: subject.recordId,
40738
40775
  payload: {
@@ -40741,8 +40778,9 @@ var NotificationCenter = class {
40741
40778
  priority: 2,
40742
40779
  ...media,
40743
40780
  subject: {
40744
- deviceId: panel.deviceId,
40781
+ deviceId: mediaDeviceId,
40745
40782
  ...alarmSource?.trackId !== void 0 ? { trackId: alarmSource.trackId } : {},
40783
+ ...alarmSource?.extraStills !== void 0 && alarmSource.extraStills.length > 0 ? { extraStills: alarmSource.extraStills.map((x) => ({ ...x })) } : {},
40746
40784
  ...alarmSource?.eventId !== void 0 ? { eventId: alarmSource.eventId } : {},
40747
40785
  className: "alarm",
40748
40786
  zones: [],
@@ -41827,7 +41865,10 @@ var NotificationCenter = class {
41827
41865
  ...target.params !== void 0 ? { params: target.params } : {},
41828
41866
  subject: {
41829
41867
  deviceId: subject.deviceId,
41830
- ...alarmSource?.trackId !== void 0 ? { trackId: alarmSource.trackId } : linkedOwners !== void 0 ? {
41868
+ ...alarmSource?.trackId !== void 0 ? {
41869
+ trackId: alarmSource.trackId,
41870
+ ...alarmSource.extraStills !== void 0 && alarmSource.extraStills.length > 0 ? { extraStills: alarmSource.extraStills.map((x) => ({ ...x })) } : {}
41871
+ } : linkedOwners !== void 0 ? {
41831
41872
  trackId: linkedOwners.trackId,
41832
41873
  ...linkedOwners.extraStills.length > 0 ? { extraStills: linkedOwners.extraStills.map((x) => ({ ...x })) } : {},
41833
41874
  analysisTiles: linkedOwners.analysisTiles.map((x) => ({ ...x }))
@@ -1,4 +1,4 @@
1
- import { $ as NC_ALARM_DELAY_MAX_SEC, $n as gifFromMp4Args, $r as DeviceType, $t as SCENE_CONFIRM_DEFAULT_TIMEOUT_MS, A as EMBEDDING_REQUIREMENTS_FAILED, An as audioMetricsCapability, Ar as ruleDeviceCompatCapQueries, At as NcRulePatchSchema, B as ListTrackRelationsInputSchema, Bn as describeSystemEventFamilyProblem, Br as systemEventDeliveryProblems, Bt as NcSystemEventKindSchema, C as DEFAULT_EVENT_COLOR, Ci as string, Cn as alarmDeviceSecureOnArm, Cr as readTimelapseGeneratedAt, Ct as NcAlarmSettingsPatchSchema, D as DeclaredDevices, Di as unknown, Dn as applyNonBlockingEdit, Dr as resolveModeDelays, Dt as NcRuleActionSchema, E as DETECTION_PIPELINE_CAP_NAME, Ei as union, En as applyModeDelaysEdits, Er as resolveLocationMode, Et as NcLegacyRuleActionSequenceSchema, F as EXPORT_DENSE_MAX_RANGES, Fn as cosineSimilarity$1, Fr as sensorRaisedOf, Ft as NcSharedSequenceSchema, G as MAX_BIRTH_LATENCY_PROXY_MS, Gr as templateCarriesSummary, Gt as OPS_LOG_DEFAULT_LIMIT, H as LockStateSchema, Hr as systemEventFilterApplies, Ht as NcTemplatePreviewInputSchema, I as FIRST_LEVEL_MACRO_CLASSES, In as createAlarmProfile, Ir as servedTemplateVars, It as NcSnoozeInputSchema, J as MOTION_CLOSE_AFTER_MS, Jn as eventKindLabel, Jr as zoneAnalyticsCapability, Jt as RECORDING_EXPORT_MAX_READ_BYTES, K as MAX_TRACK_PURITIES, Kn as encodeVectorBase64, Kr as templateVarsFor, Kt as OpsLogEntrySchema, L as FULL_IMAGE_BBOX, Ln as deleteAlarmProfile, Lr as storageOccupancyCapability, Lt as NcSnoozeSchema, M as EVENT_DENSITY_BATCH_MAX, Mn as buildEventKindDescriptor, Mr as ruleKindOf, Mt as NcRuleTargetSchema, N as EVENT_KIND_BY_CAP, Nn as cloneAlarmSettings, Nr as sceneMonitorCapability, Nt as NcRuleUpdateInputSchema, O as DetectionSourceSchema, Oi as EventCategory, On as applySecureOnArmEdit, Ot as NcRuleActionsSchema, P as EVENT_OWNER_TYPES, Pn as consumableLowPercentOf, Pr as secureActuationFor, Pt as NcScheduleSchema, Q as NC_ALARM_DELAY_FIELDS, Qn as gifDeriveSpeed, Qr as isSourceCap, Qt as SCENE_CONFIRM_DEFAULT_MAX_IMAGE_PX, R as FailureCounters, Rn as deriveRecordingMode, Rr as subKindsOf, Rt as NcSnoozeSuppressedSchema, S as CoverStateSchema, Si as strictObject, Sn as addonWidgetsSourceCapability, Sr as readMotionTriggeredBy, St as NcAlarmSensorsSchema, T as DETECTION_MACRO_CLASSES, Ti as tuple, Tn as applyBlockingEdit, Tr as resolveClipSearchMinScore, Tt as NcConditionsSchema, U as MAX_ARCHIVED_DEBUG_NOTES, Un as embeddingRefusalOf, Ur as systemEventSummaryScheduleOf, Ut as NcTemplatePreviewSchema, V as ListTrackRelationsResultSchema, Vr as systemEventFamilyProblems, Vt as NcTaxonomySchema, W as MAX_BIRTH_DECISION_RECORDS, Wr as systemEventSummarySplitOf, Wt as NcTemplateVarDescriptorSchema, X as MotionTriggeredBySchema, Xn as faceGalleryCapability, Xr as canonicalHash, Xt as RebuildObjectEmbeddingsRefusalSchema, Y as MediaFileKindEnum, Yn as evictionPolicyOfLocation, Yr as DEFAULT_FIRST_SIGHTING_FRESHNESS_MS, Yt as RECORDING_SOURCE_CAMSTACK_ADDON, Z as NC_ALARM_DEFAULT_PROFILE_ID, Zn as failureContributionCapability, Zr as evaluateSensorEdge, Zt as RetrainStatusSchema, _ as BaseDevice, _i as looseObject, _n as TrackRelationKindSchema, _r as occupancyScope, _t as NC_TANK_SYSTEM_EVENT_KINDS, a as CLIP_EMBEDDING_STEP_ID, ai as defineCustomActions, an as SCENE_DIVERGED, ar as isEventOwnerType, at as NC_CLIP_PRE_ROLL_DEFAULT_SEC, b as ClearTrackRelationInputSchema, bi as partialRecord, bn as TrackSourceSchema, br as plateGalleryCapability, bt as NcAlarmConfigSchema, c as resolveClusterModelPin, ci as nodePin, cn as SetTrackPurityInputSchema, cr as isRetiredClearKey, ct as NC_CONSUMABLE_LOW_PERCENT_DEFAULT, d as APPEARANCE_RESOLVES_AMBIGUITY_DEFAULT, di as ZodObject, dn as TIMELAPSE_DENSE_FLOOR_SEC, dr as isSystemEventSummaryRule, dt as NC_GROUPING_DEFAULT_SEC, ei as errMsg, en as SCENE_DEFAULT_ANCHOR_THRESHOLD, er as isAlarmControllableCap, et as NC_ALARM_SYSTEM_EVENT_KINDS, f as ARCHIVED_DEBUG_NOTES_DEFAULT_LIMIT, fi as _enum, fn as TRACK_RELATIONS_DEFAULT_LIMIT, fr as isVectorIndexDimConflict, ft as NC_GROUPING_MAX_SEC, g as BIRTH_DECISION_DEFAULT_LIMIT, gi as literal, gn as TrackPuritySchema, gr as notificationRulesCapability, gt as NC_SYSTEM_EVENT_KIND_GROUP_SPECS, h as ArchivedDebugNoteSchema, hi as discriminatedUnion, hn as TimelapseRuleSchema, hr as memoizePinnedFfmpeg, ht as NC_SNOOZE_MAX_MINUTES, ii as customAction, in as SCENE_DEFAULT_UNCOVERED_POLICY, ir as isEventKindLabelKey, it as NC_CLIP_POST_ROLL_DEFAULT_SEC, j as EMBEDDING_REQUIREMENTS_UNAVAILABLE, jn as audioModeOf, jr as ruleGroupingApplies, jt as NcRuleSchema, k as EMBEDDING_MODEL_FAILED, kn as assertTimelapseCadences, kr as ruleBelongsToAlarm$1, kt as NcRuleInputSchema, l as APPEARANCE_BIN_COUNT, ln as SetTrackPurityResultSchema, lr as isScheduleActive, lt as NC_CONSUMABLE_SYSTEM_EVENT_KINDS, m as AlarmArmModeSchema, mi as boolean, mn as TimelapseRulePatchSchema, mr as mayWriteToLocation, mt as NC_SENSOR_TRANSITION_KINDS, ni as CamProfileSchema, nn as SCENE_DEFAULT_OBSERVATION_SPACING_SEC, nr as isDefaultAlarmProfileId, nt as NC_AUDIO_CONFIRM_HITS_DEFAULT, o as FACE_EMBEDDING_STEP_ID, oi as hydrateSchema, on as SCENE_RESET_RECAPTURES, or as isKnownTemplateVar, ot as NC_CLIP_RETENTION_MAX_SEC, p as AUDIO_MACRO_LABELS, pi as array, pn as TimelapseRuleInputSchema, pr as kebabToCamel, pt as NC_GROUPING_MIN_SEC, q as MAX_TRACK_RELATIONS, qn as ensureAlarmProfiles, qr as vectorDimFromBase64, ri as createEvent, rn as SCENE_DEFAULT_QUIET_SECONDS, rr as isDetectionMacroClass, rt as NC_AUDIO_CONFIRM_WINDOW_SEC_DEFAULT, s as readClusterModelPinStrict, si as isDeviceScopedCap, sn as SceneMonitorSchema, sr as isMediaOwnerType, st as NC_CONDITION_CATALOG, t as BUILTIN_CLIP_MODELS, ti as BaseAddon, tn as SCENE_DEFAULT_CHECK_INTERVAL_SEC, tr as isAudioClassName, tt as NC_ALARM_TRIGGERED_MAX_SEC, u as APPEARANCE_BLOCKS, ui as sleep$1, un as SetTrackRelationInputSchema, ur as isSystemDelivery, ut as NC_DEFAULT_SNOOZE_MINUTES, v as BirthDecisionRecordSchema, vi as number, vn as TrackRelationSchema, vt as NC_TAXONOMY, w as DEFAULT_TIMELAPSE_PREVIEW_TEXT, wi as templateLiteral, wn as alarmPanelCapability, wr as renameAlarmProfile, wt as NcConditionDescriptorSchema, x as ClearTrackRelationResultSchema, xi as record, xn as activateAlarmProfile, xr as readDeviceStateFrom, xt as NcAlarmSensorsInputSchema, y as COCO_TO_MACRO, yi as object, yn as TrackSideSchema, yr as pipelineAnalyticsCapability, yt as NC_TEMPLATE_VARS, z as LabelAttributionSchema, zn as describeSystemEventDeliveryProblem, zr as syncActiveAlarmProfileSettings, zt as NcStateSummarySectionIdSchema } from "../clip-model-registry-BENGs4rw.mjs";
1
+ import { $ as NC_ALARM_DELAY_MAX_SEC, $n as gifFromMp4Args, $r as DeviceType, $t as SCENE_CONFIRM_DEFAULT_TIMEOUT_MS, A as EMBEDDING_REQUIREMENTS_FAILED, An as audioMetricsCapability, Ar as ruleDeviceCompatCapQueries, At as NcRulePatchSchema, B as ListTrackRelationsInputSchema, Bn as describeSystemEventFamilyProblem, Br as systemEventDeliveryProblems, Bt as NcSystemEventKindSchema, C as DEFAULT_EVENT_COLOR, Ci as string, Cn as alarmDeviceSecureOnArm, Cr as readTimelapseGeneratedAt, Ct as NcAlarmSettingsPatchSchema, D as DeclaredDevices, Di as unknown, Dn as applyNonBlockingEdit, Dr as resolveModeDelays, Dt as NcRuleActionSchema, E as DETECTION_PIPELINE_CAP_NAME, Ei as union, En as applyModeDelaysEdits, Er as resolveLocationMode, Et as NcLegacyRuleActionSequenceSchema, F as EXPORT_DENSE_MAX_RANGES, Fn as cosineSimilarity$1, Fr as sensorRaisedOf, Ft as NcSharedSequenceSchema, G as MAX_BIRTH_LATENCY_PROXY_MS, Gr as templateCarriesSummary, Gt as OPS_LOG_DEFAULT_LIMIT, H as LockStateSchema, Hr as systemEventFilterApplies, Ht as NcTemplatePreviewInputSchema, I as FIRST_LEVEL_MACRO_CLASSES, In as createAlarmProfile, Ir as servedTemplateVars, It as NcSnoozeInputSchema, J as MOTION_CLOSE_AFTER_MS, Jn as eventKindLabel, Jr as zoneAnalyticsCapability, Jt as RECORDING_EXPORT_MAX_READ_BYTES, K as MAX_TRACK_PURITIES, Kn as encodeVectorBase64, Kr as templateVarsFor, Kt as OpsLogEntrySchema, L as FULL_IMAGE_BBOX, Ln as deleteAlarmProfile, Lr as storageOccupancyCapability, Lt as NcSnoozeSchema, M as EVENT_DENSITY_BATCH_MAX, Mn as buildEventKindDescriptor, Mr as ruleKindOf, Mt as NcRuleTargetSchema, N as EVENT_KIND_BY_CAP, Nn as cloneAlarmSettings, Nr as sceneMonitorCapability, Nt as NcRuleUpdateInputSchema, O as DetectionSourceSchema, Oi as EventCategory, On as applySecureOnArmEdit, Ot as NcRuleActionsSchema, P as EVENT_OWNER_TYPES, Pn as consumableLowPercentOf, Pr as secureActuationFor, Pt as NcScheduleSchema, Q as NC_ALARM_DELAY_FIELDS, Qn as gifDeriveSpeed, Qr as isSourceCap, Qt as SCENE_CONFIRM_DEFAULT_MAX_IMAGE_PX, R as FailureCounters, Rn as deriveRecordingMode, Rr as subKindsOf, Rt as NcSnoozeSuppressedSchema, S as CoverStateSchema, Si as strictObject, Sn as addonWidgetsSourceCapability, Sr as readMotionTriggeredBy, St as NcAlarmSensorsSchema, T as DETECTION_MACRO_CLASSES, Ti as tuple, Tn as applyBlockingEdit, Tr as resolveClipSearchMinScore, Tt as NcConditionsSchema, U as MAX_ARCHIVED_DEBUG_NOTES, Un as embeddingRefusalOf, Ur as systemEventSummaryScheduleOf, Ut as NcTemplatePreviewSchema, V as ListTrackRelationsResultSchema, Vr as systemEventFamilyProblems, Vt as NcTaxonomySchema, W as MAX_BIRTH_DECISION_RECORDS, Wr as systemEventSummarySplitOf, Wt as NcTemplateVarDescriptorSchema, X as MotionTriggeredBySchema, Xn as faceGalleryCapability, Xr as canonicalHash, Xt as RebuildObjectEmbeddingsRefusalSchema, Y as MediaFileKindEnum, Yn as evictionPolicyOfLocation, Yr as DEFAULT_FIRST_SIGHTING_FRESHNESS_MS, Yt as RECORDING_SOURCE_CAMSTACK_ADDON, Z as NC_ALARM_DEFAULT_PROFILE_ID, Zn as failureContributionCapability, Zr as evaluateSensorEdge, Zt as RetrainStatusSchema, _ as BaseDevice, _i as looseObject, _n as TrackRelationKindSchema, _r as occupancyScope, _t as NC_TANK_SYSTEM_EVENT_KINDS, a as CLIP_EMBEDDING_STEP_ID, ai as defineCustomActions, an as SCENE_DIVERGED, ar as isEventOwnerType, at as NC_CLIP_PRE_ROLL_DEFAULT_SEC, b as ClearTrackRelationInputSchema, bi as partialRecord, bn as TrackSourceSchema, br as plateGalleryCapability, bt as NcAlarmConfigSchema, c as resolveClusterModelPin, ci as nodePin, cn as SetTrackPurityInputSchema, cr as isRetiredClearKey, ct as NC_CONSUMABLE_LOW_PERCENT_DEFAULT, d as APPEARANCE_RESOLVES_AMBIGUITY_DEFAULT, di as ZodObject, dn as TIMELAPSE_DENSE_FLOOR_SEC, dr as isSystemEventSummaryRule, dt as NC_GROUPING_DEFAULT_SEC, ei as errMsg, en as SCENE_DEFAULT_ANCHOR_THRESHOLD, er as isAlarmControllableCap, et as NC_ALARM_SYSTEM_EVENT_KINDS, f as ARCHIVED_DEBUG_NOTES_DEFAULT_LIMIT, fi as _enum, fn as TRACK_RELATIONS_DEFAULT_LIMIT, fr as isVectorIndexDimConflict, ft as NC_GROUPING_MAX_SEC, g as BIRTH_DECISION_DEFAULT_LIMIT, gi as literal, gn as TrackPuritySchema, gr as notificationRulesCapability, gt as NC_SYSTEM_EVENT_KIND_GROUP_SPECS, h as ArchivedDebugNoteSchema, hi as discriminatedUnion, hn as TimelapseRuleSchema, hr as memoizePinnedFfmpeg, ht as NC_SNOOZE_MAX_MINUTES, ii as customAction, in as SCENE_DEFAULT_UNCOVERED_POLICY, ir as isEventKindLabelKey, it as NC_CLIP_POST_ROLL_DEFAULT_SEC, j as EMBEDDING_REQUIREMENTS_UNAVAILABLE, jn as audioModeOf, jr as ruleGroupingApplies, jt as NcRuleSchema, k as EMBEDDING_MODEL_FAILED, kn as assertTimelapseCadences, kr as ruleBelongsToAlarm$1, kt as NcRuleInputSchema, l as APPEARANCE_BIN_COUNT, ln as SetTrackPurityResultSchema, lr as isScheduleActive, lt as NC_CONSUMABLE_SYSTEM_EVENT_KINDS, m as AlarmArmModeSchema, mi as boolean, mn as TimelapseRulePatchSchema, mr as mayWriteToLocation, mt as NC_SENSOR_TRANSITION_KINDS, ni as CamProfileSchema, nn as SCENE_DEFAULT_OBSERVATION_SPACING_SEC, nr as isDefaultAlarmProfileId, nt as NC_AUDIO_CONFIRM_HITS_DEFAULT, o as FACE_EMBEDDING_STEP_ID, oi as hydrateSchema, on as SCENE_RESET_RECAPTURES, or as isKnownTemplateVar, ot as NC_CLIP_RETENTION_MAX_SEC, p as AUDIO_MACRO_LABELS, pi as array, pn as TimelapseRuleInputSchema, pr as kebabToCamel, pt as NC_GROUPING_MIN_SEC, q as MAX_TRACK_RELATIONS, qn as ensureAlarmProfiles, qr as vectorDimFromBase64, ri as createEvent, rn as SCENE_DEFAULT_QUIET_SECONDS, rr as isDetectionMacroClass, rt as NC_AUDIO_CONFIRM_WINDOW_SEC_DEFAULT, s as readClusterModelPinStrict, si as isDeviceScopedCap, sn as SceneMonitorSchema, sr as isMediaOwnerType, st as NC_CONDITION_CATALOG, t as BUILTIN_CLIP_MODELS, ti as BaseAddon, tn as SCENE_DEFAULT_CHECK_INTERVAL_SEC, tr as isAudioClassName, tt as NC_ALARM_TRIGGERED_MAX_SEC, u as APPEARANCE_BLOCKS, ui as sleep$1, un as SetTrackRelationInputSchema, ur as isSystemDelivery, ut as NC_DEFAULT_SNOOZE_MINUTES, v as BirthDecisionRecordSchema, vi as number, vn as TrackRelationSchema, vt as NC_TAXONOMY, w as DEFAULT_TIMELAPSE_PREVIEW_TEXT, wi as templateLiteral, wn as alarmPanelCapability, wr as renameAlarmProfile, wt as NcConditionDescriptorSchema, x as ClearTrackRelationResultSchema, xi as record, xn as activateAlarmProfile, xr as readDeviceStateFrom, xt as NcAlarmSensorsInputSchema, y as COCO_TO_MACRO, yi as object, yn as TrackSideSchema, yr as pipelineAnalyticsCapability, yt as NC_TEMPLATE_VARS, z as LabelAttributionSchema, zn as describeSystemEventDeliveryProblem, zr as syncActiveAlarmProfileSettings, zt as NcStateSummarySectionIdSchema } from "../clip-model-registry-CshjlVTF.mjs";
2
2
  import { t as __exportAll } from "../embedding-encoder/index.mjs";
3
3
  import * as fs$1 from "node:fs";
4
4
  import { createWriteStream, promises } from "node:fs";
@@ -477,26 +477,37 @@ function buildArmAnnouncement(coverage, deviceName, bypassed = []) {
477
477
  };
478
478
  }
479
479
  /**
480
- * "Attivi: 2 — Bypassati: Finestra veranda."
480
+ * "Attivi: Porta retro, Cancello — Bypassati: Finestra veranda."
481
481
  *
482
- * The bypassed sensors are named and the armed ones are COUNTED, not listed:
483
- * this sentence's subject is the exception, and burying it under thirteen
484
- * camera names is how an operator stops reading the arm notification. The
485
- * count pluralises on what IS armed, like every other arm variant.
482
+ * Both halves are named: the bypassed sensors are why the operator pressed
483
+ * Arm anyway, and the remaining ones are what is still promised. An
484
+ * all-devices mode has no finite list to name — it uses a dedicated key.
486
485
  */
487
486
  function armedWithBypass(coverage, bypassed, deviceName) {
488
487
  const skipped = new Set(coverage.skippedDevices.map((s) => s.deviceId));
489
488
  const excluded = new Set(bypassed);
490
- const armed = coverage.allDevices ? coverage.ruleCount : coverage.deviceIds.filter((id) => !skipped.has(id) && !excluded.has(id)).length;
489
+ const bypassedNames = bypassed.map(deviceName).join(", ");
490
+ if (coverage.allDevices) return {
491
+ bodyKey: "alarm.arm.body.bypassedAll",
492
+ textParams: {
493
+ rules: `${coverage.ruleCount}`,
494
+ mode: coverage.mode,
495
+ bypassedNames
496
+ },
497
+ textCount: coverage.ruleCount
498
+ };
499
+ const armedIds = coverage.deviceIds.filter((id) => !skipped.has(id) && !excluded.has(id));
500
+ const names = armedIds.map(deviceName).join(", ");
491
501
  return {
492
502
  bodyKey: "alarm.arm.body.bypassed",
493
503
  textParams: {
494
504
  rules: `${coverage.ruleCount}`,
495
505
  mode: coverage.mode,
496
- devices: `${armed}`,
497
- bypassedNames: bypassed.map(deviceName).join(", ")
506
+ devices: `${armedIds.length}`,
507
+ names,
508
+ bypassedNames
498
509
  },
499
- textCount: armed
510
+ textCount: armedIds.length
500
511
  };
501
512
  }
502
513
  /**
@@ -1091,10 +1102,11 @@ var NcActionPlane = class {
1091
1102
  * Anything short of fully secure is open: a cover stopped half-way, a lock that
1092
1103
  * jammed, a cover still closing when the arm is decided, a switch that is on.
1093
1104
  *
1094
- * PRECEDENCE, when one device carries more than one opening slice: `contact`
1095
- * first, then `cover`, then `lock-control`, then `switch`. The contact is the
1096
- * physical truth about the opening — a reed switch on the frame says the window
1097
- * is open even when the motor's last reported word says `closed`.
1105
+ * PRECEDENCE, when one device carries more than one opening slice: any OPEN
1106
+ * reading wins over a secure one (a reed that says open beats a motor that
1107
+ * still says `closed`). Among opens, a controllable cap (`cover` / `lock-control`
1108
+ * / `switch`) wins so secure-on-arm knows what to actuate; among secures the
1109
+ * contact wins as the physical "closed" when the motor has not moved yet.
1098
1110
  */
1099
1111
  /** The one state word, per cap, that counts as secure. Everything else is open. */
1100
1112
  var COVER_SECURE = "closed";
@@ -1207,6 +1219,11 @@ function readSwitch(runtime) {
1207
1219
  }
1208
1220
  /** D630's table over one device's runtime slices — see the header for the three answers. */
1209
1221
  function alarmOpeningFrom(runtime) {
1222
+ let openControllable = null;
1223
+ let openAny = null;
1224
+ let secureContact = null;
1225
+ let secureControllable = null;
1226
+ let secureAny = null;
1210
1227
  let firstUnknown = null;
1211
1228
  for (const read of [
1212
1229
  readContact(runtime),
@@ -1214,10 +1231,21 @@ function alarmOpeningFrom(runtime) {
1214
1231
  readLock(runtime),
1215
1232
  readSwitch(runtime)
1216
1233
  ]) {
1217
- if (read.kind === "reading") return read;
1218
- if (read.kind === "unknown" && firstUnknown === null) firstUnknown = read;
1234
+ if (read.kind === "unknown") {
1235
+ if (firstUnknown === null) firstUnknown = read;
1236
+ continue;
1237
+ }
1238
+ if (read.kind !== "reading") continue;
1239
+ if (read.reading === "open") {
1240
+ if (isAlarmControllableCap(read.cap) && openControllable === null) openControllable = read;
1241
+ if (openAny === null) openAny = read;
1242
+ continue;
1243
+ }
1244
+ if (read.cap === "contact" && secureContact === null) secureContact = read;
1245
+ if (isAlarmControllableCap(read.cap) && secureControllable === null) secureControllable = read;
1246
+ if (secureAny === null) secureAny = read;
1219
1247
  }
1220
- return firstUnknown ?? NOT_OPENING;
1248
+ return openControllable ?? openAny ?? secureContact ?? secureControllable ?? secureAny ?? firstUnknown ?? NOT_OPENING;
1221
1249
  }
1222
1250
  /**
1223
1251
  * The sensor-event kind (`CAP_TO_KIND` in `@camstack/types`) → the cap whose
@@ -2743,12 +2771,6 @@ var NcAlarmPanelDevice = class extends BaseDevice {
2743
2771
  error: String(err)
2744
2772
  };
2745
2773
  }
2746
- const toSecure = openings.open.filter((d) => alarmDeviceSecureOnArm({
2747
- controllable: d.controllable,
2748
- deviceId: d.deviceId,
2749
- secureOnArmOff: this.secureOnArmOffFor(mode)
2750
- }));
2751
- if (toSecure.length > 0) this.armGuard?.secureOnArm(toSecure);
2752
2774
  const verdict = decideArm({
2753
2775
  mode,
2754
2776
  open: openings.open,
@@ -2756,6 +2778,14 @@ var NcAlarmPanelDevice = class extends BaseDevice {
2756
2778
  blocking: this.blockingFor(mode),
2757
2779
  ...acknowledged !== void 0 ? { acknowledged } : {}
2758
2780
  });
2781
+ if (verdict.kind === "arm") {
2782
+ const toSecure = openings.open.filter((d) => alarmDeviceSecureOnArm({
2783
+ controllable: d.controllable,
2784
+ deviceId: d.deviceId,
2785
+ secureOnArmOff: this.secureOnArmOffFor(mode)
2786
+ }));
2787
+ if (toSecure.length > 0) this.armGuard?.secureOnArm(toSecure);
2788
+ }
2759
2789
  return {
2760
2790
  kind: "read",
2761
2791
  openings,
@@ -2964,6 +2994,7 @@ var NcAlarmPanelDevice = class extends BaseDevice {
2964
2994
  status(now = Date.now()) {
2965
2995
  return {
2966
2996
  state: stateAt(this.machine, now),
2997
+ targetMode: armModeOf(this.machine.target, NC_ALARM_MODES),
2967
2998
  availableModes: [...NC_ALARM_MODES],
2968
2999
  requiresCode: false,
2969
3000
  lastChangedAt: this.machine.changedAt
@@ -12903,7 +12934,7 @@ function incomingFromAlarmTransition(input) {
12903
12934
  const kind = transition.kind;
12904
12935
  const keys = alarmTextKeys(transition, input.body);
12905
12936
  const sensor = transition.sensor;
12906
- const alarmSource = kind === "alarm-triggered" ? source : void 0;
12937
+ const alarmSource = (kind === "alarm-triggered" || kind === "alarm-pending") && source !== void 0 ? source : void 0;
12907
12938
  const facts = {
12908
12939
  eventId: `alarm:${kind}:${String(transition.at)}${sensor !== void 0 ? `:${String(sensor.deviceId)}` : ""}${transition.refusalId !== void 0 ? `:${transition.refusalId}` : ""}`,
12909
12940
  timestamp: transition.at,
@@ -14438,35 +14469,35 @@ var en_default = {
14438
14469
  "occupancy.body": "{{scope}} {{op}} ({{count}}/{{capacity}})",
14439
14470
  "occupancy.op.occupied": "occupied",
14440
14471
  "occupancy.op.free": "free",
14441
- "system.device-online.title": "Device online",
14472
+ "system.device-online.title": "Online — {{deviceName}}",
14442
14473
  "system.device-online.body": "Device {{deviceName}} is online",
14443
- "system.device-offline.title": "Device offline",
14474
+ "system.device-offline.title": "Offline — {{deviceName}}",
14444
14475
  "system.device-offline.body": "Device {{deviceName}} is offline",
14445
- "system.device-disabled.title": "Device switched off",
14476
+ "system.device-disabled.title": "Switched off — {{deviceName}}",
14446
14477
  "system.device-disabled.body": "Device {{deviceName}} was switched off",
14447
- "system.device-enabled.title": "Device switched on",
14478
+ "system.device-enabled.title": "Switched on — {{deviceName}}",
14448
14479
  "system.device-enabled.body": "Device {{deviceName}} was switched back on",
14449
- "system.device-battery-low.title": "Battery low",
14480
+ "system.device-battery-low.title": "Battery low — {{deviceName}}",
14450
14481
  "system.device-battery-low.body": "{{deviceName}} is down to {{percentage}}% battery",
14451
14482
  "system.device-battery-low.body.binary": "{{deviceName}} reports a low battery",
14452
- "system.device-battery-normal.title": "Battery back to normal",
14483
+ "system.device-battery-normal.title": "Battery back to normal — {{deviceName}}",
14453
14484
  "system.device-battery-normal.body": "{{deviceName}} is back to {{percentage}}% battery",
14454
14485
  "system.device-battery-normal.body.binary": "{{deviceName}} no longer reports a low battery",
14455
- "system.stream-online.title": "Stream online",
14486
+ "system.stream-online.title": "Stream online — {{deviceName}}",
14456
14487
  "system.stream-online.body": "Stream for camera {{deviceName}} is online",
14457
14488
  "system.stream-online.body.profiled": "{{profile}} stream for camera {{deviceName}} is online",
14458
- "system.stream-offline.title": "Stream offline",
14489
+ "system.stream-offline.title": "Stream offline — {{deviceName}}",
14459
14490
  "system.stream-offline.body": "Stream for camera {{deviceName}} is offline",
14460
14491
  "system.stream-offline.body.profiled": "{{profile}} stream for camera {{deviceName}} is offline",
14461
- "system.node-online.title": "Node online",
14492
+ "system.node-online.title": "Node online — {{nodeId}}",
14462
14493
  "system.node-online.body.agent": "Agent {{nodeId}} is online",
14463
- "system.node-offline.title": "Node offline",
14494
+ "system.node-offline.title": "Node offline — {{nodeId}}",
14464
14495
  "system.node-offline.body.agent": "Agent {{nodeId}} is offline",
14465
- "system.node-inference-unavailable.title": "Node has no usable inference device",
14496
+ "system.node-inference-unavailable.title": "Node cannot infer — {{nodeId}}",
14466
14497
  "system.node-inference-unavailable.body": "Node {{nodeId}} can no longer run inference — every enabled device is unavailable ({{devices}}). It will not receive cameras until one returns.",
14467
- "system.addon-crash-loop.title": "Addon stopped after repeated crashes",
14498
+ "system.addon-crash-loop.title": "Addon crash-loop — {{nodeId}}",
14468
14499
  "system.addon-crash-loop.body": "The {{addons}} addon on node {{nodeId}} crashed {{count}} times in a row and will NOT be restarted. Everything it provides is offline until it is repaired.",
14469
- "system.detection-blind.title": "Camera detecting nothing",
14500
+ "system.detection-blind.title": "Detecting nothing — {{deviceName}}",
14470
14501
  "system.detection-blind.body": {
14471
14502
  "one": "Camera {{deviceName}} has been analysed for {{minutes}} minute with no detection at all",
14472
14503
  "other": "Camera {{deviceName}} has been analysed for {{minutes}} minutes with no detection at all"
@@ -14507,15 +14538,15 @@ var en_default = {
14507
14538
  "system.backup-completed.title": "Backup completed",
14508
14539
  "system.backup-completed.body": "Backup saved to {{destinationsOk}} of {{destinationsTotal}} destinations ({{sizeMB}} MB)",
14509
14540
  "system.backup-completed.body.partial": "Backup saved to {{destinationsOk}} of {{destinationsTotal}} destinations — {{destinationsFailed}} failed",
14510
- "system.device-consumable-low.title": "Consumable low",
14541
+ "system.device-consumable-low.title": "Consumable low — {{deviceName}}",
14511
14542
  "system.device-consumable-low.body": "{{item}} on {{deviceName}} is at {{percentage}}%",
14512
14543
  "system.device-consumable-low.body.unmeasured": "{{item}} on {{deviceName}} needs replacing",
14513
- "system.device-consumable-normal.title": "Consumable replaced",
14544
+ "system.device-consumable-normal.title": "Consumable replaced — {{deviceName}}",
14514
14545
  "system.device-consumable-normal.body": "{{item}} on {{deviceName}} is back to {{percentage}}%",
14515
14546
  "system.device-consumable-normal.body.unmeasured": "{{item}} on {{deviceName}} is OK again",
14516
- "system.device-tank-low.title": "Tank low",
14517
- "system.device-tank-full.title": "Tank full",
14518
- "system.device-tank-normal.title": "Tank OK",
14547
+ "system.device-tank-low.title": "Tank low — {{deviceName}}",
14548
+ "system.device-tank-full.title": "Tank full — {{deviceName}}",
14549
+ "system.device-tank-normal.title": "Tank OK — {{deviceName}}",
14519
14550
  "system.device-tank-low.body.cleanWater": "The clean water tank on {{deviceName}} is running low",
14520
14551
  "system.device-tank-full.body.cleanWater": "The clean water tank on {{deviceName}} is full",
14521
14552
  "system.device-tank-normal.body.cleanWater": "The clean water tank on {{deviceName}} is OK again",
@@ -14557,7 +14588,7 @@ var en_default = {
14557
14588
  "snooze.scope.anyRule": "A rule",
14558
14589
  "snooze.scope.rule": "“{{rule}}”",
14559
14590
  "alarm.arm.body.allDevices": "Active: all devices",
14560
- "alarm.arm.body.allDevicesExcept": "Active: all devices except {{count}}: {{names}}",
14591
+ "alarm.arm.body.allDevicesExcept": "Active: all devices except {{names}}",
14561
14592
  "alarm.arm.body.noDevices": "Active: no device restriction",
14562
14593
  "alarm.arm.body.devices": "Active: {{names}}",
14563
14594
  "alarm.arm.body.devicesSkipped": "Active: {{names}}\nExcluded: {{skippedNames}}",
@@ -14567,7 +14598,8 @@ var en_default = {
14567
14598
  "alarm.arming.body.uncovered": "Active: none — no rule uses this mode",
14568
14599
  "alarm.arming.body.allSkipped": "Active: none\nExcluded: {{names}}",
14569
14600
  "alarm.arming.body.skipped": "Excluded: {{names}}",
14570
- "alarm.arm.body.bypassed": "Active: {{devices}}\nBypassed: {{bypassedNames}}",
14601
+ "alarm.arm.body.bypassed": "Active: {{names}}\nBypassed: {{bypassedNames}}",
14602
+ "alarm.arm.body.bypassedAll": "Active: all devices\nBypassed: {{bypassedNames}}",
14571
14603
  "alarm.arming.body.bypassed": "Bypassed: {{bypassedNames}}",
14572
14604
  "alarm.armRefused.body": "Open: {{names}}",
14573
14605
  "alarm.armRefused.body.hint": "Open: {{names}}\nTap “Arm anyway” to arm with them excluded.",
@@ -14655,19 +14687,19 @@ var en_default = {
14655
14687
  "summary.body.detections": "{{detectionSummary}}",
14656
14688
  "summary.body.truncated": "showing the {{shown}} most relevant of {{total}}",
14657
14689
  "summary.body.empty": "nothing was seen in this window",
14658
- "system.state-summary.title": "{{rule}}",
14690
+ "system.state-summary.title": "{{rule}}: {{summaryCount}}",
14659
14691
  "system.state-summary.body": "{{summaryText}}",
14660
- "system.state-summary.section.title": "{{rule}} — {{summarySection}}",
14692
+ "system.state-summary.section.title": "{{summarySection}}: {{summaryCount}}",
14661
14693
  "system.state-summary.section.body": "{{summaryText}}",
14662
- "summary.section.device-state": "Devices offline or switched off",
14694
+ "summary.section.device-state": "Offline or off",
14663
14695
  "summary.section.streams": "Streams offline",
14664
14696
  "summary.section.battery": "Low batteries",
14665
14697
  "summary.section.consumables": "Consumables to replace",
14666
- "summary.section.tanks": "Tanks",
14667
- "summary.section.detection-blind": "Cameras detecting nothing",
14698
+ "summary.section.tanks": "Tanks low",
14699
+ "summary.section.detection-blind": "Detecting nothing",
14668
14700
  "summary.section.nodes": "Nodes",
14669
14701
  "summary.section.addons": "Addons",
14670
- "summary.section.updates": "Server and container updates",
14702
+ "summary.section.updates": "Updates",
14671
14703
  "summary.section.unavailable": "{{section}}: unavailable — the state could not be read",
14672
14704
  "summary.line.device-offline": "{{deviceName}} — offline (since {{since}})",
14673
14705
  "summary.line.device-disabled": "{{deviceName}} — switched off (since {{since}})",
@@ -14765,35 +14797,35 @@ var it_default = {
14765
14797
  "occupancy.body": "{{scope}} {{op}} ({{count}}/{{capacity}})",
14766
14798
  "occupancy.op.occupied": "occupata",
14767
14799
  "occupancy.op.free": "libera",
14768
- "system.device-online.title": "Dispositivo online",
14800
+ "system.device-online.title": "Online — {{deviceName}}",
14769
14801
  "system.device-online.body": "Il dispositivo {{deviceName}} è online",
14770
- "system.device-offline.title": "Dispositivo offline",
14802
+ "system.device-offline.title": "Offline — {{deviceName}}",
14771
14803
  "system.device-offline.body": "Il dispositivo {{deviceName}} è offline",
14772
- "system.device-disabled.title": "Dispositivo spento",
14804
+ "system.device-disabled.title": "Spento — {{deviceName}}",
14773
14805
  "system.device-disabled.body": "Il dispositivo {{deviceName}} è stato spento",
14774
- "system.device-enabled.title": "Dispositivo riacceso",
14806
+ "system.device-enabled.title": "Riacceso — {{deviceName}}",
14775
14807
  "system.device-enabled.body": "Il dispositivo {{deviceName}} è stato riacceso",
14776
- "system.device-battery-low.title": "Batteria scarica",
14808
+ "system.device-battery-low.title": "Batteria scarica — {{deviceName}}",
14777
14809
  "system.device-battery-low.body": "{{deviceName}} è al {{percentage}}% di batteria",
14778
14810
  "system.device-battery-low.body.binary": "{{deviceName}} segnala la batteria scarica",
14779
- "system.device-battery-normal.title": "Batteria rientrata",
14811
+ "system.device-battery-normal.title": "Batteria rientrata — {{deviceName}}",
14780
14812
  "system.device-battery-normal.body": "{{deviceName}} è risalito al {{percentage}}% di batteria",
14781
14813
  "system.device-battery-normal.body.binary": "{{deviceName}} non segnala più la batteria scarica",
14782
- "system.stream-online.title": "Stream online",
14814
+ "system.stream-online.title": "Stream online — {{deviceName}}",
14783
14815
  "system.stream-online.body": "Lo stream della camera {{deviceName}} è online",
14784
14816
  "system.stream-online.body.profiled": "Lo stream {{profile}} della camera {{deviceName}} è online",
14785
- "system.stream-offline.title": "Stream offline",
14817
+ "system.stream-offline.title": "Stream offline — {{deviceName}}",
14786
14818
  "system.stream-offline.body": "Lo stream della camera {{deviceName}} è offline",
14787
14819
  "system.stream-offline.body.profiled": "Lo stream {{profile}} della camera {{deviceName}} è offline",
14788
- "system.node-online.title": "Nodo online",
14820
+ "system.node-online.title": "Nodo online — {{nodeId}}",
14789
14821
  "system.node-online.body.agent": "L'agent {{nodeId}} è online",
14790
- "system.node-offline.title": "Nodo offline",
14822
+ "system.node-offline.title": "Nodo offline — {{nodeId}}",
14791
14823
  "system.node-offline.body.agent": "L'agent {{nodeId}} è offline",
14792
- "system.node-inference-unavailable.title": "Nodo senza dispositivi di inferenza utilizzabili",
14824
+ "system.node-inference-unavailable.title": "Nodo senza inferenza — {{nodeId}}",
14793
14825
  "system.node-inference-unavailable.body": "Il nodo {{nodeId}} non può più eseguire inferenza — tutti i dispositivi abilitati non sono disponibili ({{devices}}). Non riceverà camere finché uno non torna disponibile.",
14794
- "system.addon-crash-loop.title": "Addon fermato dopo ripetuti crash",
14826
+ "system.addon-crash-loop.title": "Crash-loop addon — {{nodeId}}",
14795
14827
  "system.addon-crash-loop.body": "L'addon {{addons}} sul nodo {{nodeId}} è andato in crash {{count}} volte di seguito e NON verrà riavviato. Tutto ciò che fornisce resta offline finché non viene riparato.",
14796
- "system.detection-blind.title": "Camera che non rileva nulla",
14828
+ "system.detection-blind.title": "Senza detection — {{deviceName}}",
14797
14829
  "system.detection-blind.body": {
14798
14830
  "one": "La camera {{deviceName}} è analizzata da {{minutes}} minuto senza alcun rilevamento",
14799
14831
  "other": "La camera {{deviceName}} è analizzata da {{minutes}} minuti senza alcun rilevamento"
@@ -14834,15 +14866,15 @@ var it_default = {
14834
14866
  "system.backup-completed.title": "Backup completato",
14835
14867
  "system.backup-completed.body": "Backup salvato su {{destinationsOk}} destinazioni su {{destinationsTotal}} ({{sizeMB}} MB)",
14836
14868
  "system.backup-completed.body.partial": "Backup salvato su {{destinationsOk}} destinazioni su {{destinationsTotal}} — {{destinationsFailed}} fallite",
14837
- "system.device-consumable-low.title": "Consumabile quasi esaurito",
14869
+ "system.device-consumable-low.title": "Consumabile basso — {{deviceName}}",
14838
14870
  "system.device-consumable-low.body": "{{item}} su {{deviceName}} è al {{percentage}}%",
14839
14871
  "system.device-consumable-low.body.unmeasured": "{{item}} su {{deviceName}} va sostituito",
14840
- "system.device-consumable-normal.title": "Consumabile sostituito",
14872
+ "system.device-consumable-normal.title": "Consumabile sostituito — {{deviceName}}",
14841
14873
  "system.device-consumable-normal.body": "{{item}} su {{deviceName}} è tornato al {{percentage}}%",
14842
14874
  "system.device-consumable-normal.body.unmeasured": "{{item}} su {{deviceName}} è di nuovo a posto",
14843
- "system.device-tank-low.title": "Serbatoio quasi vuoto",
14844
- "system.device-tank-full.title": "Serbatoio pieno",
14845
- "system.device-tank-normal.title": "Serbatoio a posto",
14875
+ "system.device-tank-low.title": "Serbatoio quasi vuoto — {{deviceName}}",
14876
+ "system.device-tank-full.title": "Serbatoio pieno — {{deviceName}}",
14877
+ "system.device-tank-normal.title": "Serbatoio a posto — {{deviceName}}",
14846
14878
  "system.device-tank-low.body.cleanWater": "Il serbatoio dell'acqua pulita di {{deviceName}} è quasi vuoto",
14847
14879
  "system.device-tank-full.body.cleanWater": "Il serbatoio dell'acqua pulita di {{deviceName}} è pieno",
14848
14880
  "system.device-tank-normal.body.cleanWater": "Il serbatoio dell'acqua pulita di {{deviceName}} è di nuovo a posto",
@@ -14884,7 +14916,7 @@ var it_default = {
14884
14916
  "snooze.scope.anyRule": "Una regola",
14885
14917
  "snooze.scope.rule": "“{{rule}}”",
14886
14918
  "alarm.arm.body.allDevices": "Attivi: tutti i dispositivi",
14887
- "alarm.arm.body.allDevicesExcept": "Attivi: tutti i dispositivi tranne {{count}}: {{names}}",
14919
+ "alarm.arm.body.allDevicesExcept": "Attivi: tutti i dispositivi tranne {{names}}",
14888
14920
  "alarm.arm.body.noDevices": "Attivi: nessuna restrizione",
14889
14921
  "alarm.arm.body.devices": "Attivi: {{names}}",
14890
14922
  "alarm.arm.body.devicesSkipped": "Attivi: {{names}}\nEsclusi: {{skippedNames}}",
@@ -14894,7 +14926,8 @@ var it_default = {
14894
14926
  "alarm.arming.body.uncovered": "Attivi: nessuno — nessuna regola usa questa modalità",
14895
14927
  "alarm.arming.body.allSkipped": "Attivi: nessuno\nEsclusi: {{names}}",
14896
14928
  "alarm.arming.body.skipped": "Esclusi: {{names}}",
14897
- "alarm.arm.body.bypassed": "Attivi: {{devices}}\nBypassati: {{bypassedNames}}",
14929
+ "alarm.arm.body.bypassed": "Attivi: {{names}}\nBypassati: {{bypassedNames}}",
14930
+ "alarm.arm.body.bypassedAll": "Attivi: tutti i dispositivi\nBypassati: {{bypassedNames}}",
14898
14931
  "alarm.arming.body.bypassed": "Bypassati: {{bypassedNames}}",
14899
14932
  "alarm.armRefused.body": "Aperti: {{names}}",
14900
14933
  "alarm.armRefused.body.hint": "Aperti: {{names}}\nTocca “Arma comunque” per armare escludendoli.",
@@ -14982,19 +15015,19 @@ var it_default = {
14982
15015
  "summary.body.detections": "{{detectionSummary}}",
14983
15016
  "summary.body.truncated": "mostrati i {{shown}} più rilevanti su {{total}}",
14984
15017
  "summary.body.empty": "nessun evento in questa finestra",
14985
- "system.state-summary.title": "{{rule}}",
15018
+ "system.state-summary.title": "{{rule}}: {{summaryCount}}",
14986
15019
  "system.state-summary.body": "{{summaryText}}",
14987
- "system.state-summary.section.title": "{{rule}} — {{summarySection}}",
15020
+ "system.state-summary.section.title": "{{summarySection}}: {{summaryCount}}",
14988
15021
  "system.state-summary.section.body": "{{summaryText}}",
14989
- "summary.section.device-state": "Dispositivi offline o spenti",
15022
+ "summary.section.device-state": "Offline o spenti",
14990
15023
  "summary.section.streams": "Stream offline",
14991
15024
  "summary.section.battery": "Batterie scariche",
14992
15025
  "summary.section.consumables": "Consumabili da sostituire",
14993
- "summary.section.tanks": "Serbatoi",
14994
- "summary.section.detection-blind": "Camere che non rilevano nulla",
15026
+ "summary.section.tanks": "Serbatoi bassi",
15027
+ "summary.section.detection-blind": "Senza detection",
14995
15028
  "summary.section.nodes": "Nodi",
14996
15029
  "summary.section.addons": "Addon",
14997
- "summary.section.updates": "Aggiornamenti di server e container",
15030
+ "summary.section.updates": "Aggiornamenti",
14998
15031
  "summary.section.unavailable": "{{section}}: non disponibile — lo stato non è leggibile",
14999
15032
  "summary.line.device-offline": "{{deviceName}} — offline (da {{since}})",
15000
15033
  "summary.line.device-disabled": "{{deviceName}} — spento (da {{since}})",
@@ -37074,13 +37107,16 @@ function frozenOccupancy(rule, occ) {
37074
37107
  function fireRefFor(rule, subject, kind) {
37075
37108
  const hasEventMedia = kind === "object-event" || kind === "package-event";
37076
37109
  const className = subject.classNames[0];
37110
+ const linkedOwners = subject.trackId === void 0 && subject.linkedStills !== void 0 ? linkedMediaOwners(subject.linkedStills, linkedCameraMode(rule.media)) : void 0;
37111
+ const trackId = subject.trackId ?? linkedOwners?.trackId;
37077
37112
  return {
37078
37113
  ruleId: rule.id,
37079
37114
  ruleName: rule.name,
37080
37115
  deviceId: subject.deviceId,
37081
37116
  ...subject.sourceDeviceId !== void 0 ? { sourceDeviceId: subject.sourceDeviceId } : {},
37082
37117
  recordId: subject.recordId,
37083
- ...subject.trackId !== void 0 ? { trackId: subject.trackId } : {},
37118
+ ...trackId !== void 0 ? { trackId } : {},
37119
+ ...linkedOwners !== void 0 && linkedOwners.extraStills.length > 0 ? { extraStills: linkedOwners.extraStills.map((x) => ({ ...x })) } : {},
37084
37120
  ...hasEventMedia ? { eventId: subject.recordId } : {},
37085
37121
  timestamp: subject.timestamp,
37086
37122
  ...className !== void 0 ? { className } : {},
@@ -40706,10 +40742,11 @@ var NotificationCenter = class {
40706
40742
  const alarmSource = subject.systemEvent?.alarmSource;
40707
40743
  const sourceRule = alarmSource !== void 0 ? this.rules.get(alarmSource.ruleId) : null;
40708
40744
  const media = sourceRule !== null ? mediaPolicyFields(sourceRule, void 0) : { media: "none" };
40745
+ const mediaDeviceId = alarmSource?.deviceId ?? panel.deviceId;
40709
40746
  const entries = targets.map((targetId) => ({
40710
40747
  ruleId: NC_ALARM_ANNOUNCE_RULE_ID,
40711
40748
  targetId,
40712
- deviceId: panel.deviceId,
40749
+ deviceId: mediaDeviceId,
40713
40750
  recordKind: "system-event",
40714
40751
  recordId: subject.recordId,
40715
40752
  payload: {
@@ -40718,8 +40755,9 @@ var NotificationCenter = class {
40718
40755
  priority: 2,
40719
40756
  ...media,
40720
40757
  subject: {
40721
- deviceId: panel.deviceId,
40758
+ deviceId: mediaDeviceId,
40722
40759
  ...alarmSource?.trackId !== void 0 ? { trackId: alarmSource.trackId } : {},
40760
+ ...alarmSource?.extraStills !== void 0 && alarmSource.extraStills.length > 0 ? { extraStills: alarmSource.extraStills.map((x) => ({ ...x })) } : {},
40723
40761
  ...alarmSource?.eventId !== void 0 ? { eventId: alarmSource.eventId } : {},
40724
40762
  className: "alarm",
40725
40763
  zones: [],
@@ -41804,7 +41842,10 @@ var NotificationCenter = class {
41804
41842
  ...target.params !== void 0 ? { params: target.params } : {},
41805
41843
  subject: {
41806
41844
  deviceId: subject.deviceId,
41807
- ...alarmSource?.trackId !== void 0 ? { trackId: alarmSource.trackId } : linkedOwners !== void 0 ? {
41845
+ ...alarmSource?.trackId !== void 0 ? {
41846
+ trackId: alarmSource.trackId,
41847
+ ...alarmSource.extraStills !== void 0 && alarmSource.extraStills.length > 0 ? { extraStills: alarmSource.extraStills.map((x) => ({ ...x })) } : {}
41848
+ } : linkedOwners !== void 0 ? {
41808
41849
  trackId: linkedOwners.trackId,
41809
41850
  ...linkedOwners.extraStills.length > 0 ? { extraStills: linkedOwners.extraStills.map((x) => ({ ...x })) } : {},
41810
41851
  analysisTiles: linkedOwners.analysisTiles.map((x) => ({ ...x }))
@@ -30,7 +30,7 @@ async function d(e) {
30
30
  }
31
31
  }
32
32
  async function f() {
33
- return l ||= d(() => import("./_virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_analytics_widgets-CGo6RmK3.mjs")).catch((e) => {
33
+ return l ||= d(() => import("./_virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_analytics_widgets-BiD7k7AM.mjs")).catch((e) => {
34
34
  throw l = void 0, e;
35
35
  }), l;
36
36
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-post-analysis",
3
- "version": "1.2.323",
3
+ "version": "1.2.325",
4
4
  "description": "Post-Analysis bundle — enrichment, embedding-encoder, pipeline-analytics. Multi-entry npm package shipping addons that consume pipeline output.",
5
5
  "keywords": [
6
6
  "camstack",