@camstack/addon-post-analysis 1.2.323 → 1.2.324

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,
@@ -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.",
@@ -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.",
@@ -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,
@@ -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.",
@@ -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.",
@@ -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.324",
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",