@camstack/addon-post-analysis 1.2.280 → 1.2.282
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{dist-Z6AO1MsY.mjs → dist-C3zTKShG.mjs} +552 -25
- package/dist/{dist-VeiAavYR.js → dist-D0zzdvSd.js} +599 -24
- package/dist/embedding-encoder/index.js +1 -1
- package/dist/embedding-encoder/index.mjs +1 -1
- package/dist/pipeline-analytics/_stub.js +2 -2
- package/dist/pipeline-analytics/{_virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_analytics_widgets-C_C1P6Bk.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_analytics_widgets-B9WQ8rry.mjs} +2 -2
- package/dist/pipeline-analytics/_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-DT-cQNv-.mjs +26 -0
- package/dist/pipeline-analytics/{_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-B62fofgN.mjs → _virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-DWPDYuJS.mjs} +1 -1
- package/dist/pipeline-analytics/{hostInit-B5__n3rE.mjs → hostInit-lUAYfFf-.mjs} +2 -2
- package/dist/pipeline-analytics/index.js +592 -26
- package/dist/pipeline-analytics/index.mjs +592 -26
- package/dist/pipeline-analytics/remoteEntry.js +1 -1
- package/package.json +1 -1
- package/dist/pipeline-analytics/_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-DBnj0lb3.mjs +0 -26
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
1
2
|
//#region ../types/dist/event-category-BVDXG4tB.mjs
|
|
2
3
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
3
4
|
EventCategory["SystemBoot"] = "system.boot";
|
|
@@ -5359,7 +5360,7 @@ var ZodIssueCode = {
|
|
|
5359
5360
|
var ZodFirstPartyTypeKind;
|
|
5360
5361
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5361
5362
|
//#endregion
|
|
5362
|
-
//#region ../types/dist/sleep-
|
|
5363
|
+
//#region ../types/dist/sleep-DU7mu4wb.mjs
|
|
5363
5364
|
/**
|
|
5364
5365
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5365
5366
|
* window to float samples (D455).
|
|
@@ -7567,6 +7568,39 @@ function sleep(ms) {
|
|
|
7567
7568
|
return new Promise((resolve) => setTimeout(resolve, Math.max(0, ms)));
|
|
7568
7569
|
}
|
|
7569
7570
|
//#endregion
|
|
7571
|
+
//#region ../types/dist/canonical-hash-CPK2Dy60.mjs
|
|
7572
|
+
/**
|
|
7573
|
+
* Deterministic SHA-256 hash of an arbitrary serialisable value. The
|
|
7574
|
+
* canonical form sorts object keys alphabetically at every depth so two
|
|
7575
|
+
* structurally-equal inputs with different key insertion orders produce
|
|
7576
|
+
* the same hash. Returns a 64-char lowercase hex digest.
|
|
7577
|
+
*
|
|
7578
|
+
* Used by export adapters (Alexa, HAP) to short-circuit re-discovery /
|
|
7579
|
+
* accessory-rebuild work when the upstream shape is byte-identical to
|
|
7580
|
+
* the last applied state — preventing user-visible "re-discovery"
|
|
7581
|
+
* notifications on every addon-runner respawn. Each respawn re-fires
|
|
7582
|
+
* `DeviceBindingsChanged` for every cap registration, which without
|
|
7583
|
+
* this guard would propagate redundant pushes.
|
|
7584
|
+
*
|
|
7585
|
+
* Note: this is a SYMPTOMATIC fix layered on top of the binding-change
|
|
7586
|
+
* subscription. The proper fix is a single "device ready" lifecycle
|
|
7587
|
+
* barrier so exports react only when the full cap set has landed —
|
|
7588
|
+
* tracked separately for post-HA-integration work.
|
|
7589
|
+
*/
|
|
7590
|
+
function canonicalHash(value) {
|
|
7591
|
+
const canonical = JSON.stringify(value, replaceWithSortedKeys);
|
|
7592
|
+
return createHash("sha256").update(canonical ?? "").digest("hex");
|
|
7593
|
+
}
|
|
7594
|
+
function replaceWithSortedKeys(_key, value) {
|
|
7595
|
+
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
7596
|
+
const obj = value;
|
|
7597
|
+
const out = {};
|
|
7598
|
+
for (const k of Object.keys(obj).toSorted()) out[k] = obj[k];
|
|
7599
|
+
return out;
|
|
7600
|
+
}
|
|
7601
|
+
return value;
|
|
7602
|
+
}
|
|
7603
|
+
//#endregion
|
|
7570
7604
|
//#region ../types/dist/err-msg-IQTHeDzc.mjs
|
|
7571
7605
|
/**
|
|
7572
7606
|
import { errMsg } from '@camstack/types'
|
|
@@ -18144,6 +18178,16 @@ var NcCrossingSchema = _enum([
|
|
|
18144
18178
|
"exit",
|
|
18145
18179
|
"any"
|
|
18146
18180
|
]);
|
|
18181
|
+
/**
|
|
18182
|
+
* Which edge of a BOOLEAN sensor fires a device-event rule (D640).
|
|
18183
|
+
* - `raised` — the sensor went high: water detected, smoke, open, tampered.
|
|
18184
|
+
* - `cleared` — it went back: dry, clear, closed.
|
|
18185
|
+
* - absent — both edges, which is what every rule authored before this did.
|
|
18186
|
+
*
|
|
18187
|
+
* There is no third member for "both": absence already says it, and a value
|
|
18188
|
+
* that means the same as absence is a second way to write one rule.
|
|
18189
|
+
*/
|
|
18190
|
+
var NcSensorTransitionSchema = _enum(["raised", "cleared"]);
|
|
18147
18191
|
/** Admin-zone membership condition (zone IDs as stamped by the ZoneEngine). */
|
|
18148
18192
|
var NcZoneConditionSchema = object({
|
|
18149
18193
|
ids: array(string().min(1)).min(1),
|
|
@@ -18333,6 +18377,20 @@ var NcConditionsSchema = object({
|
|
|
18333
18377
|
scene: NcSceneConditionSchema.optional(),
|
|
18334
18378
|
/** Device scope — absent = all devices. */
|
|
18335
18379
|
devices: array(number()).optional(),
|
|
18380
|
+
/**
|
|
18381
|
+
* Device EXCLUSION (D641) — "every device except these". Judged on the SAME
|
|
18382
|
+
* subject ids {@link devices} is judged on (the camera, the sensor that
|
|
18383
|
+
* fired, a linked set's sensor and row cameras), so a sensor fanned out per
|
|
18384
|
+
* linked camera is excluded exactly where an include would have tested it.
|
|
18385
|
+
* `min(1)`: an empty exclusion excludes nothing and is written as absent.
|
|
18386
|
+
*
|
|
18387
|
+
* Not for `system-event` rules — those carry their own
|
|
18388
|
+
* `systemEvent.excludeDeviceIds` (D636), and the hub refuses this key there.
|
|
18389
|
+
* Editors present the two lists as ONE field (All | Only these | All except
|
|
18390
|
+
* these); the engine evaluates each independently, so a legacy rule
|
|
18391
|
+
* carrying both still means "these, minus those".
|
|
18392
|
+
*/
|
|
18393
|
+
devicesExclude: array(number()).min(1).optional(),
|
|
18336
18394
|
/** Detector class names (any overlap with the record's class set). */
|
|
18337
18395
|
classes: array(string().min(1)).optional(),
|
|
18338
18396
|
/** Veto classes — any overlap fails the rule. */
|
|
@@ -18466,6 +18524,16 @@ var NcConditionsSchema = object({
|
|
|
18466
18524
|
*/
|
|
18467
18525
|
sensorKinds: array(string().min(1)).optional(),
|
|
18468
18526
|
/**
|
|
18527
|
+
* DEVICE-EVENT only (D640). Fire on one edge of a boolean sensor —
|
|
18528
|
+
* {@link NcSensorTransitionSchema}. Which field of the slice means "raised"
|
|
18529
|
+
* is `@camstack/types` → `notification/sensor-raised.ts`. A reading the
|
|
18530
|
+
* engine cannot place (a kind with no raise, an unreadable slice) PASSES:
|
|
18531
|
+
* the condition fails open towards notifying, never towards silence. Editors
|
|
18532
|
+
* offer it only when every chosen {@link sensorKinds} member has a raise
|
|
18533
|
+
* (`sensorTransitionOffered`), and the hub refuses it on any other delivery.
|
|
18534
|
+
*/
|
|
18535
|
+
sensorTransition: NcSensorTransitionSchema.optional(),
|
|
18536
|
+
/**
|
|
18469
18537
|
* PACKAGE-EVENT only. Which package phase fires the rule — `delivered`
|
|
18470
18538
|
* (a parked parcel appeared), `picked-up` (it departed), or `both`. Fails
|
|
18471
18539
|
* when the subject's phase does not match (a subject always carries a phase
|
|
@@ -18965,9 +19033,29 @@ var NcTestResultSchema = object({
|
|
|
18965
19033
|
className: string().optional(),
|
|
18966
19034
|
label: string().optional()
|
|
18967
19035
|
});
|
|
18968
|
-
/** The
|
|
18969
|
-
*
|
|
19036
|
+
/** The rule kinds, as data. `NcRuleKind` in `notification/rule-kinds.ts` is the
|
|
19037
|
+
* same union; the template-vars spec pins the two together. `mixed` is DERIVED
|
|
19038
|
+
* (a stored system rule whose kinds span families, D637) and never authored. */
|
|
18970
19039
|
var NcRuleKindSchema = _enum([
|
|
19040
|
+
"detection",
|
|
19041
|
+
"sensor",
|
|
19042
|
+
"occupancy",
|
|
19043
|
+
"sound",
|
|
19044
|
+
"device-events",
|
|
19045
|
+
"system",
|
|
19046
|
+
"alarm",
|
|
19047
|
+
"mixed"
|
|
19048
|
+
]);
|
|
19049
|
+
/**
|
|
19050
|
+
* The kinds a SERVED template-variable descriptor may name: the five that
|
|
19051
|
+
* existed before D637, frozen. `getTemplateCatalog` ships `kinds` to every
|
|
19052
|
+
* installed viewer, and a viewer at `@camstack/types` 1.2.25x parses them with a
|
|
19053
|
+
* strict five-member enum — one `device-events` in one descriptor fails the
|
|
19054
|
+
* whole catalog parse. So the WIRE says `system`, and the MATCH widens it:
|
|
19055
|
+
* `templateVarKindApplies` reads a `system` descriptor as applying to every
|
|
19056
|
+
* system rule kind (`device-events`, `system`, `alarm`, `mixed`).
|
|
19057
|
+
*/
|
|
19058
|
+
var NcTemplateVarKindSchema = _enum([
|
|
18971
19059
|
"detection",
|
|
18972
19060
|
"sensor",
|
|
18973
19061
|
"occupancy",
|
|
@@ -19005,7 +19093,7 @@ var NcTemplateVarGroupSchema = _enum([
|
|
|
19005
19093
|
*
|
|
19006
19094
|
* `families` / `fields` / `kinds` / `deliveries` / `systemEventKinds` say WHERE
|
|
19007
19095
|
* it has a value; absent = no restriction on that axis. `systemEventKinds` is
|
|
19008
|
-
* read only for a
|
|
19096
|
+
* read only for a system-event rule (any family, or `mixed`). `dynamic` declares a FAMILY of names
|
|
19009
19097
|
* (`count_<class>`): the descriptor's `name` is the example member.
|
|
19010
19098
|
*/
|
|
19011
19099
|
var NcTemplateVarDescriptorSchema = object({
|
|
@@ -19016,7 +19104,7 @@ var NcTemplateVarDescriptorSchema = object({
|
|
|
19016
19104
|
group: NcTemplateVarGroupSchema,
|
|
19017
19105
|
families: array(NcTemplateFamilySchema).min(1),
|
|
19018
19106
|
fields: array(NcTemplateFieldSchema).optional(),
|
|
19019
|
-
kinds: array(
|
|
19107
|
+
kinds: array(NcTemplateVarKindSchema).optional(),
|
|
19020
19108
|
deliveries: array(NcDeliverySchema).optional(),
|
|
19021
19109
|
systemEventKinds: array(NcSystemEventKindSchema).optional(),
|
|
19022
19110
|
dynamic: object({
|
|
@@ -19064,6 +19152,7 @@ var NcConditionDescriptorSchema = object({
|
|
|
19064
19152
|
/** Editor widget the UI renders — never hardcode per-condition forms. */
|
|
19065
19153
|
valueType: _enum([
|
|
19066
19154
|
"deviceIdList",
|
|
19155
|
+
"deviceIdExcludeList",
|
|
19067
19156
|
"stringList",
|
|
19068
19157
|
"number01",
|
|
19069
19158
|
"number",
|
|
@@ -19074,6 +19163,7 @@ var NcConditionDescriptorSchema = object({
|
|
|
19074
19163
|
"plateMatcher",
|
|
19075
19164
|
"packagePhase",
|
|
19076
19165
|
"crossingSelect",
|
|
19166
|
+
"sensorTransition",
|
|
19077
19167
|
"polygonDraw",
|
|
19078
19168
|
"occupancy",
|
|
19079
19169
|
"audio",
|
|
@@ -19272,6 +19362,21 @@ var NC_CONDITION_CATALOG = [
|
|
|
19272
19362
|
phase: "P1",
|
|
19273
19363
|
description: "Restrict the rule to these devices; absent = all devices. A sensor event matches either the SENSOR that fired or the camera it is attributed to, so a rule may name either one."
|
|
19274
19364
|
},
|
|
19365
|
+
{
|
|
19366
|
+
id: "devicesExclude",
|
|
19367
|
+
group: "scope",
|
|
19368
|
+
label: "Excluded devices",
|
|
19369
|
+
valueType: "deviceIdExcludeList",
|
|
19370
|
+
operator: "notIn",
|
|
19371
|
+
appliesTo: [
|
|
19372
|
+
"immediate",
|
|
19373
|
+
"track-end",
|
|
19374
|
+
"device-event",
|
|
19375
|
+
"package-event"
|
|
19376
|
+
],
|
|
19377
|
+
phase: "P1",
|
|
19378
|
+
description: "Every device except these. Judged on the same device ids as Devices: a sensor event is excluded by the SENSOR that fired or by the camera it is attributed to."
|
|
19379
|
+
},
|
|
19275
19380
|
{
|
|
19276
19381
|
id: "classes",
|
|
19277
19382
|
group: "class",
|
|
@@ -19528,6 +19633,33 @@ var NC_CONDITION_CATALOG = [
|
|
|
19528
19633
|
phase: "P1",
|
|
19529
19634
|
description: "Raw device event-type tokens (e.g. doorbell press / press_long) from the event-emitter slice; absent on doorbell-pulse / passive sensors."
|
|
19530
19635
|
},
|
|
19636
|
+
{
|
|
19637
|
+
id: "sensorTransition",
|
|
19638
|
+
group: "device",
|
|
19639
|
+
label: "Notify when",
|
|
19640
|
+
valueType: "sensorTransition",
|
|
19641
|
+
options: [
|
|
19642
|
+
{
|
|
19643
|
+
value: "",
|
|
19644
|
+
label: "It triggers and when it clears",
|
|
19645
|
+
hint: "Every change: water detected, and back to dry."
|
|
19646
|
+
},
|
|
19647
|
+
{
|
|
19648
|
+
value: "raised",
|
|
19649
|
+
label: "Only when it triggers",
|
|
19650
|
+
hint: "Water detected, smoke, a contact opening — never the return to normal."
|
|
19651
|
+
},
|
|
19652
|
+
{
|
|
19653
|
+
value: "cleared",
|
|
19654
|
+
label: "Only when it clears",
|
|
19655
|
+
hint: "Back to dry, smoke gone, a contact closing — never the alert itself."
|
|
19656
|
+
}
|
|
19657
|
+
],
|
|
19658
|
+
operator: "in",
|
|
19659
|
+
appliesTo: ["device-event"],
|
|
19660
|
+
phase: "P2",
|
|
19661
|
+
description: "Fire on one edge of a boolean sensor. Offered only when every chosen sensor kind raises and clears; a reading that cannot be placed still notifies."
|
|
19662
|
+
},
|
|
19531
19663
|
{
|
|
19532
19664
|
id: "packagePhase",
|
|
19533
19665
|
group: "package",
|
|
@@ -19711,6 +19843,28 @@ var NcHistoryFilterSchema = object({
|
|
|
19711
19843
|
limit: number().int().min(1).max(500).default(100)
|
|
19712
19844
|
});
|
|
19713
19845
|
/**
|
|
19846
|
+
* Every rule's last run, in one answer.
|
|
19847
|
+
*
|
|
19848
|
+
* A rule ABSENT from `runs` produced no delivery inside `horizonMs` — how far
|
|
19849
|
+
* back this answer looked, in ms before the hub's now. It is the outbox prune
|
|
19850
|
+
* window (7 days by default, operator-configurable), NARROWED when the read hit
|
|
19851
|
+
* its row bound: the answer never claims a window it did not read. `null` means
|
|
19852
|
+
* the operator keeps the outbox forever AND the read reached its end, so absent
|
|
19853
|
+
* means "never on record". A UI derives its "not in the last N days" from this
|
|
19854
|
+
* value, never from a constant — and only when the call ANSWERED (D315).
|
|
19855
|
+
*/
|
|
19856
|
+
var NcRuleLastRunsSchema = object({
|
|
19857
|
+
runs: array(object({
|
|
19858
|
+
ruleId: string(),
|
|
19859
|
+
/** Fire time of the newest row (`createdAt`, epoch ms). */
|
|
19860
|
+
lastAt: number(),
|
|
19861
|
+
status: NcHistoryStatusSchema,
|
|
19862
|
+
/** The camera/device of that row (a digest row files under its first camera). */
|
|
19863
|
+
deviceId: number()
|
|
19864
|
+
})),
|
|
19865
|
+
horizonMs: number().nonnegative().nullable()
|
|
19866
|
+
});
|
|
19867
|
+
/**
|
|
19714
19868
|
* What a snooze covers. Broader scopes win when several overlap, so one window
|
|
19715
19869
|
* leaves ONE digest rather than a rule snooze and a whole-feed snooze both
|
|
19716
19870
|
* summarising the same silence.
|
|
@@ -19892,6 +20046,14 @@ var NcAlarmModeCoverageSchema = object({
|
|
|
19892
20046
|
/** Ids named by the covering rules. A SUBSET when `allDevices` is true. */
|
|
19893
20047
|
deviceIds: array(number().int()),
|
|
19894
20048
|
/**
|
|
20049
|
+
* D641: the ids NOT covered although `allDevices` is true — every unscoped
|
|
20050
|
+
* covering rule EXCLUDES them (`conditions.devicesExclude`) and no named rule
|
|
20051
|
+
* covers them. Always `[]` when `allDevices` is false. Excluded by the rules,
|
|
20052
|
+
* which is not the same as skipped by a switch: never in `skippedDevices`.
|
|
20053
|
+
* Defaulted so an answer computed before this field parses as "none".
|
|
20054
|
+
*/
|
|
20055
|
+
allDevicesExcept: array(number().int()).default([]),
|
|
20056
|
+
/**
|
|
19895
20057
|
* Devices this mode NAMES but cannot actually arm, each with the switch that
|
|
19896
20058
|
* excludes it.
|
|
19897
20059
|
*
|
|
@@ -20115,6 +20277,15 @@ var notificationRulesCapability = {
|
|
|
20115
20277
|
*/
|
|
20116
20278
|
getHistory: method(object({ filter: NcHistoryFilterSchema.default({ limit: 100 }) }), object({ entries: array(NcHistoryEntrySchema) }), { auth: "admin" }),
|
|
20117
20279
|
/**
|
|
20280
|
+
* The newest delivery of every rule, in ONE bounded read of the outbox —
|
|
20281
|
+
* the "Last run" column. Never a `getHistory` per rule. A rule with no
|
|
20282
|
+
* delivery inside `horizonMs` is absent from `runs`; see
|
|
20283
|
+
* {@link NcRuleLastRunsSchema} for what absent means. A store that cannot
|
|
20284
|
+
* answer FAILS the call rather than answering "nothing ran". Admin-only,
|
|
20285
|
+
* like `getHistory`, of which it is a projection.
|
|
20286
|
+
*/
|
|
20287
|
+
getRuleLastRuns: method(object({}), NcRuleLastRunsSchema, { auth: "admin" }),
|
|
20288
|
+
/**
|
|
20118
20289
|
* Mint a fresh, externally-reachable URL for one artefact a history row
|
|
20119
20290
|
* named in {@link NcHistoryEntrySchema.shape.artifactIds} — the SAME
|
|
20120
20291
|
* signed-link mechanism the dispatcher uses to attach media to an
|
|
@@ -33169,7 +33340,30 @@ var RenameNodeResultSchema = object({
|
|
|
33169
33340
|
nodeId: string(),
|
|
33170
33341
|
name: string()
|
|
33171
33342
|
});
|
|
33172
|
-
|
|
33343
|
+
/**
|
|
33344
|
+
* The cheap node list. A consumer's rule for a STORED node id (a rule's
|
|
33345
|
+
* `nodeIds`) that is missing from `nodes`, whatever `complete` says: render it
|
|
33346
|
+
* as a removable chip labelled unknown, never drop it (D49). Even a complete
|
|
33347
|
+
* list omits a node that joined and left between two history captures, so a
|
|
33348
|
+
* missing id means "not known to the hub", never "removed". Only the operator
|
|
33349
|
+
* removes it.
|
|
33350
|
+
*
|
|
33351
|
+
* `complete` changes only the WORDING: `false` = no history read has ever
|
|
33352
|
+
* answered, so the list may be missing offline nodes the hub does know (D315).
|
|
33353
|
+
*
|
|
33354
|
+
* `name` is the history row's name (≤ 30 s behind a rename), or the id when
|
|
33355
|
+
* the history has none.
|
|
33356
|
+
*/
|
|
33357
|
+
var NodeDirectorySchema = object({
|
|
33358
|
+
nodes: array(object({
|
|
33359
|
+
id: string(),
|
|
33360
|
+
name: string(),
|
|
33361
|
+
isHub: boolean(),
|
|
33362
|
+
isOnline: boolean()
|
|
33363
|
+
})).readonly(),
|
|
33364
|
+
complete: boolean()
|
|
33365
|
+
});
|
|
33366
|
+
method(_void(), array(TopologyNodeSchema).readonly(), { auth: "admin" }), method(_void(), NodeDirectorySchema, { auth: "admin" }), method(NodeAddonInputSchema, SuccessSchema, {
|
|
33173
33367
|
kind: "mutation",
|
|
33174
33368
|
auth: "admin"
|
|
33175
33369
|
}), method(NodeAddonInputSchema, SuccessSchema, {
|
|
@@ -44695,6 +44889,12 @@ Object.freeze({
|
|
|
44695
44889
|
addonId: null,
|
|
44696
44890
|
access: "create"
|
|
44697
44891
|
},
|
|
44892
|
+
"nodes.directory": {
|
|
44893
|
+
capName: "nodes",
|
|
44894
|
+
capScope: "system",
|
|
44895
|
+
addonId: null,
|
|
44896
|
+
access: "view"
|
|
44897
|
+
},
|
|
44698
44898
|
"nodes.executeQuery": {
|
|
44699
44899
|
capName: "nodes",
|
|
44700
44900
|
capScope: "system",
|
|
@@ -44863,6 +45063,12 @@ Object.freeze({
|
|
|
44863
45063
|
addonId: null,
|
|
44864
45064
|
access: "view"
|
|
44865
45065
|
},
|
|
45066
|
+
"notificationRules.getRuleLastRuns": {
|
|
45067
|
+
capName: "notification-rules",
|
|
45068
|
+
capScope: "system",
|
|
45069
|
+
addonId: null,
|
|
45070
|
+
access: "view"
|
|
45071
|
+
},
|
|
44866
45072
|
"notificationRules.getTemplateCatalog": {
|
|
44867
45073
|
capName: "notification-rules",
|
|
44868
45074
|
capScope: "system",
|
|
@@ -50479,6 +50685,253 @@ function audioModeOf(value) {
|
|
|
50479
50685
|
return null;
|
|
50480
50686
|
}
|
|
50481
50687
|
new Set(["devices", "classes"]);
|
|
50688
|
+
/** Every filter, for the callers that must cover all four (guards, tests). */
|
|
50689
|
+
var NC_SYSTEM_EVENT_FILTER_KEYS = [
|
|
50690
|
+
"deviceIds",
|
|
50691
|
+
"deviceTypes",
|
|
50692
|
+
"nodeIds",
|
|
50693
|
+
"packageNames"
|
|
50694
|
+
];
|
|
50695
|
+
/**
|
|
50696
|
+
* Does `filter` say anything about `kind`?
|
|
50697
|
+
*
|
|
50698
|
+
* `false` means the filter is not part of this kind's vocabulary: the engine
|
|
50699
|
+
* ignores it and an editor hides its input. It never means "excluded".
|
|
50700
|
+
*/
|
|
50701
|
+
function systemEventFilterApplies(kind, filter) {
|
|
50702
|
+
switch (filter) {
|
|
50703
|
+
case "deviceIds": return kind.startsWith("device-") || kind.startsWith("stream-") || kind === "detection-blind" || kind === "alarm-triggered";
|
|
50704
|
+
case "deviceTypes": return kind.startsWith("device-") || kind === "detection-blind";
|
|
50705
|
+
case "nodeIds": return kind.startsWith("node-") || kind === "addon-crash-loop" || kind === "addon-update-available" || kind === "addon-updated" || kind === "server-update-available" || kind === "wrapper-update-available" || kind === "server-updated";
|
|
50706
|
+
case "packageNames": return kind.endsWith("update-available") || kind === "addon-updated" || kind === "server-updated";
|
|
50707
|
+
}
|
|
50708
|
+
}
|
|
50709
|
+
/**
|
|
50710
|
+
* WHICH FAMILY every system-event kind belongs to, and which narrowing filters
|
|
50711
|
+
* each family may carry: one table, read by the hub validator, by `ruleKindOf`
|
|
50712
|
+
* and by both rule editors (D637).
|
|
50713
|
+
*
|
|
50714
|
+
* A system rule used to be one editor for thirty-one kinds and five filters.
|
|
50715
|
+
* "Eventi di sistema" carried battery kinds under a liveness `deviceTypes` filter
|
|
50716
|
+
* and went silent for two weeks (D636). The three families are three questions:
|
|
50717
|
+
* about devices, about the installation, and about the alarm panel. A rule
|
|
50718
|
+
* answers one of them. The engine never needed to know, and it still does not:
|
|
50719
|
+
* a mixed stored rule keeps firing. Only AUTHORING is strict.
|
|
50720
|
+
*
|
|
50721
|
+
* The legacy `camera-*` tail has no family (`null`). It is parsed, never produced,
|
|
50722
|
+
* never offered.
|
|
50723
|
+
*/
|
|
50724
|
+
var NC_SYSTEM_EVENT_FAMILIES = [
|
|
50725
|
+
"device-events",
|
|
50726
|
+
"system",
|
|
50727
|
+
"alarm"
|
|
50728
|
+
];
|
|
50729
|
+
function isSystemEventFamily(value) {
|
|
50730
|
+
return NC_SYSTEM_EVENT_FAMILIES.some((family) => family === value);
|
|
50731
|
+
}
|
|
50732
|
+
/** Total over the enum: a kind added to the cap without a family fails tsc here. */
|
|
50733
|
+
var NC_SYSTEM_EVENT_FAMILY = {
|
|
50734
|
+
"device-online": "device-events",
|
|
50735
|
+
"device-offline": "device-events",
|
|
50736
|
+
"device-disabled": "device-events",
|
|
50737
|
+
"device-enabled": "device-events",
|
|
50738
|
+
"device-battery-low": "device-events",
|
|
50739
|
+
"device-battery-normal": "device-events",
|
|
50740
|
+
"device-consumable-low": "device-events",
|
|
50741
|
+
"device-consumable-normal": "device-events",
|
|
50742
|
+
"stream-online": "device-events",
|
|
50743
|
+
"stream-offline": "device-events",
|
|
50744
|
+
"detection-blind": "device-events",
|
|
50745
|
+
"node-online": "system",
|
|
50746
|
+
"node-offline": "system",
|
|
50747
|
+
"node-inference-unavailable": "system",
|
|
50748
|
+
"addon-crash-loop": "system",
|
|
50749
|
+
"addon-update-available": "system",
|
|
50750
|
+
"addon-updated": "system",
|
|
50751
|
+
"server-update-available": "system",
|
|
50752
|
+
"server-updated": "system",
|
|
50753
|
+
"wrapper-update-available": "system",
|
|
50754
|
+
"backup-completed": "system",
|
|
50755
|
+
"export-completed": "system",
|
|
50756
|
+
"alarm-triggered": "alarm",
|
|
50757
|
+
"alarm-armed": "alarm",
|
|
50758
|
+
"alarm-disarmed": "alarm",
|
|
50759
|
+
"alarm-arming": "alarm",
|
|
50760
|
+
"alarm-arm-refused": "alarm",
|
|
50761
|
+
"alarm-pending": "alarm",
|
|
50762
|
+
"alarm-rearmed": "alarm",
|
|
50763
|
+
"alarm-sensor-bypass": "alarm",
|
|
50764
|
+
"alarm-check-failed": "alarm",
|
|
50765
|
+
"camera-online": null,
|
|
50766
|
+
"camera-offline": null,
|
|
50767
|
+
"camera-disabled": null,
|
|
50768
|
+
"camera-enabled": null
|
|
50769
|
+
};
|
|
50770
|
+
new Map(Object.entries(NC_SYSTEM_EVENT_FAMILY));
|
|
50771
|
+
var NC_SYSTEM_EVENT_CONDITION_FILTER_KEYS = [...NC_SYSTEM_EVENT_FILTER_KEYS, "excludeDeviceIds"];
|
|
50772
|
+
/**
|
|
50773
|
+
* The filters a family may carry. The four base filters are the union of
|
|
50774
|
+
* `systemEventFilterApplies` over the family's kinds (the spec pins that
|
|
50775
|
+
* equality). `excludeDeviceIds` is a device-events filter only: an alarm is
|
|
50776
|
+
* narrowed to the camera that triggered it and excludes nothing.
|
|
50777
|
+
*/
|
|
50778
|
+
var NC_SYSTEM_EVENT_FAMILY_FILTERS = {
|
|
50779
|
+
"device-events": [
|
|
50780
|
+
"deviceIds",
|
|
50781
|
+
"excludeDeviceIds",
|
|
50782
|
+
"deviceTypes"
|
|
50783
|
+
],
|
|
50784
|
+
system: ["nodeIds", "packageNames"],
|
|
50785
|
+
alarm: ["deviceIds"]
|
|
50786
|
+
};
|
|
50787
|
+
var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
|
|
50788
|
+
{
|
|
50789
|
+
id: "device-state",
|
|
50790
|
+
family: "device-events",
|
|
50791
|
+
label: "Device state",
|
|
50792
|
+
kinds: [
|
|
50793
|
+
"device-offline",
|
|
50794
|
+
"device-online",
|
|
50795
|
+
"device-disabled",
|
|
50796
|
+
"device-enabled"
|
|
50797
|
+
]
|
|
50798
|
+
},
|
|
50799
|
+
{
|
|
50800
|
+
id: "streams",
|
|
50801
|
+
family: "device-events",
|
|
50802
|
+
label: "Streams",
|
|
50803
|
+
kinds: ["stream-offline", "stream-online"]
|
|
50804
|
+
},
|
|
50805
|
+
{
|
|
50806
|
+
id: "battery",
|
|
50807
|
+
family: "device-events",
|
|
50808
|
+
label: "Battery",
|
|
50809
|
+
kinds: ["device-battery-low", "device-battery-normal"]
|
|
50810
|
+
},
|
|
50811
|
+
{
|
|
50812
|
+
id: "consumables",
|
|
50813
|
+
family: "device-events",
|
|
50814
|
+
label: "Consumables",
|
|
50815
|
+
kinds: ["device-consumable-low", "device-consumable-normal"]
|
|
50816
|
+
},
|
|
50817
|
+
{
|
|
50818
|
+
id: "detection-blind",
|
|
50819
|
+
family: "device-events",
|
|
50820
|
+
label: "Detecting nothing",
|
|
50821
|
+
kinds: ["detection-blind"]
|
|
50822
|
+
},
|
|
50823
|
+
{
|
|
50824
|
+
id: "nodes",
|
|
50825
|
+
family: "system",
|
|
50826
|
+
label: "Nodes",
|
|
50827
|
+
kinds: [
|
|
50828
|
+
"node-offline",
|
|
50829
|
+
"node-online",
|
|
50830
|
+
"node-inference-unavailable"
|
|
50831
|
+
]
|
|
50832
|
+
},
|
|
50833
|
+
{
|
|
50834
|
+
id: "addons",
|
|
50835
|
+
family: "system",
|
|
50836
|
+
label: "Addons",
|
|
50837
|
+
kinds: [
|
|
50838
|
+
"addon-crash-loop",
|
|
50839
|
+
"addon-update-available",
|
|
50840
|
+
"addon-updated"
|
|
50841
|
+
]
|
|
50842
|
+
},
|
|
50843
|
+
{
|
|
50844
|
+
id: "updates",
|
|
50845
|
+
family: "system",
|
|
50846
|
+
label: "Server & container updates",
|
|
50847
|
+
kinds: [
|
|
50848
|
+
"server-update-available",
|
|
50849
|
+
"server-updated",
|
|
50850
|
+
"wrapper-update-available"
|
|
50851
|
+
]
|
|
50852
|
+
},
|
|
50853
|
+
{
|
|
50854
|
+
id: "backups-exports",
|
|
50855
|
+
family: "system",
|
|
50856
|
+
label: "Backups & exports",
|
|
50857
|
+
kinds: ["backup-completed", "export-completed"]
|
|
50858
|
+
},
|
|
50859
|
+
{
|
|
50860
|
+
id: "alarm",
|
|
50861
|
+
family: "alarm",
|
|
50862
|
+
label: "Alarm",
|
|
50863
|
+
kinds: NC_ALARM_SYSTEM_EVENT_KINDS
|
|
50864
|
+
}
|
|
50865
|
+
];
|
|
50866
|
+
function systemEventKindsOfFamily(family) {
|
|
50867
|
+
return NC_SYSTEM_EVENT_KIND_GROUP_SPECS.filter((g) => g.family === family).flatMap((g) => g.kinds);
|
|
50868
|
+
}
|
|
50869
|
+
/**
|
|
50870
|
+
* Why the hub refuses this condition on a new or updated rule. Empty = accepted.
|
|
50871
|
+
* Families are reported in `NC_SYSTEM_EVENT_FAMILIES` order, and filters in
|
|
50872
|
+
* `NC_SYSTEM_EVENT_CONDITION_FILTER_KEYS` order, so a refusal reads the same
|
|
50873
|
+
* every time.
|
|
50874
|
+
*/
|
|
50875
|
+
function systemEventFamilyProblems(condition) {
|
|
50876
|
+
if (condition === void 0 || condition.kinds.length === 0) return [{ code: "no-kinds" }];
|
|
50877
|
+
const problems = [];
|
|
50878
|
+
const present = /* @__PURE__ */ new Set();
|
|
50879
|
+
for (const kind of condition.kinds) {
|
|
50880
|
+
const family = NC_SYSTEM_EVENT_FAMILY[kind];
|
|
50881
|
+
if (family === null) problems.push({
|
|
50882
|
+
code: "legacy-kind",
|
|
50883
|
+
kind
|
|
50884
|
+
});
|
|
50885
|
+
else present.add(family);
|
|
50886
|
+
}
|
|
50887
|
+
const families = NC_SYSTEM_EVENT_FAMILIES.filter((f) => present.has(f));
|
|
50888
|
+
if (families.length > 1) problems.push({
|
|
50889
|
+
code: "mixed-families",
|
|
50890
|
+
families
|
|
50891
|
+
});
|
|
50892
|
+
const [family] = families;
|
|
50893
|
+
if (families.length !== 1 || family === void 0) return problems;
|
|
50894
|
+
const allowed = NC_SYSTEM_EVENT_FAMILY_FILTERS[family];
|
|
50895
|
+
for (const filter of NC_SYSTEM_EVENT_CONDITION_FILTER_KEYS) if (condition[filter] !== void 0 && !allowed.includes(filter)) problems.push({
|
|
50896
|
+
code: "filter-outside-family",
|
|
50897
|
+
filter,
|
|
50898
|
+
family
|
|
50899
|
+
});
|
|
50900
|
+
return problems;
|
|
50901
|
+
}
|
|
50902
|
+
function describeSystemEventFamilyProblem(problem) {
|
|
50903
|
+
switch (problem.code) {
|
|
50904
|
+
case "no-kinds": return "a system-event rule needs at least one event kind";
|
|
50905
|
+
case "legacy-kind": return `'${problem.kind}' is a legacy kind and cannot be authored`;
|
|
50906
|
+
case "mixed-families": return `event kinds span ${problem.families.join(" + ")} — one rule per family`;
|
|
50907
|
+
case "filter-outside-family": return `filter '${problem.filter}' is not allowed on a ${problem.family} rule`;
|
|
50908
|
+
}
|
|
50909
|
+
}
|
|
50910
|
+
/** Every kind a `system-event` rule can derive — the three families and `mixed`. */
|
|
50911
|
+
var NC_SYSTEM_RULE_KINDS = [
|
|
50912
|
+
"device-events",
|
|
50913
|
+
"system",
|
|
50914
|
+
"alarm",
|
|
50915
|
+
"mixed"
|
|
50916
|
+
];
|
|
50917
|
+
/** Is this a kind a `system-event` rule derives (any family, or `mixed`)? */
|
|
50918
|
+
function isSystemRuleKind(kind) {
|
|
50919
|
+
return NC_SYSTEM_RULE_KINDS.some((k) => k === kind);
|
|
50920
|
+
}
|
|
50921
|
+
/** The family a kind authors, or undefined (a camera kind, or `mixed`). */
|
|
50922
|
+
function systemFamilyOfKind(kind) {
|
|
50923
|
+
return isSystemEventFamily(kind) ? kind : void 0;
|
|
50924
|
+
}
|
|
50925
|
+
/** The delivery a system rule rides — named once, compared everywhere. */
|
|
50926
|
+
var NC_SYSTEM_DELIVERY = "system-event";
|
|
50927
|
+
/**
|
|
50928
|
+
* Is this a SYSTEM rule — one about the installation rather than about anything
|
|
50929
|
+
* a camera saw? Takes a plain `string` so a rule carrying a delivery this build
|
|
50930
|
+
* has never heard of still gets an answer instead of a type error.
|
|
50931
|
+
*/
|
|
50932
|
+
function isSystemDelivery(delivery) {
|
|
50933
|
+
return delivery === NC_SYSTEM_DELIVERY;
|
|
50934
|
+
}
|
|
50482
50935
|
NC_AUDIO_DEFAULTS.hitPercent, NC_AUDIO_DEFAULTS.samplingSeconds;
|
|
50483
50936
|
var WEEKDAY_TO_DAY = {
|
|
50484
50937
|
Sun: 0,
|
|
@@ -50540,6 +50993,66 @@ function isScheduleActive(schedule, atMs) {
|
|
|
50540
50993
|
}
|
|
50541
50994
|
return schedule.invert === true ? !inside : inside;
|
|
50542
50995
|
}
|
|
50996
|
+
var ARMED_WORD_PREFIX = "armed_";
|
|
50997
|
+
var ALARM_PANEL_CAP = "alarm-panel";
|
|
50998
|
+
var ALARM_PANEL_TRIGGER_METHOD = "trigger";
|
|
50999
|
+
/**
|
|
51000
|
+
* A rule belongs to the alarm when its `deviceState` gate names ANY device's
|
|
51001
|
+
* `armed_*` word, or an ENABLED `onTrigger` sequence pulls the alarm panel's
|
|
51002
|
+
* trigger (D630).
|
|
51003
|
+
*/
|
|
51004
|
+
function ruleBelongsToAlarm(rule) {
|
|
51005
|
+
if ((rule.conditions.deviceState?.states ?? []).some((s) => s.trim().toLowerCase().startsWith(ARMED_WORD_PREFIX))) return true;
|
|
51006
|
+
return (rule.onTrigger ?? []).some((sequence) => sequence.enabled && sequence.actions.some((step) => step.kind === "cap" && step.cap === ALARM_PANEL_CAP && step.method === ALARM_PANEL_TRIGGER_METHOD));
|
|
51007
|
+
}
|
|
51008
|
+
/**
|
|
51009
|
+
* WHICH WAY A BOOLEAN SENSOR MOVED — read off the one slice a sensor event
|
|
51010
|
+
* persists (D640 "a sensor rule fires on the raise, the clear, or both").
|
|
51011
|
+
*
|
|
51012
|
+
* A device-event rule over a flood sensor notified on BOTH edges: water
|
|
51013
|
+
* detected, and back to dry. `NcConditions.sensorTransition` lets the rule
|
|
51014
|
+
* name one edge; this file answers, for one `SensorEvent`, which edge it is.
|
|
51015
|
+
*
|
|
51016
|
+
* NOT A SECOND TABLE. The "which boolean of this cap counts as HIGH" question
|
|
51017
|
+
* already has one answer, `SOURCE_CAP_ACTIVE_FIELD`
|
|
51018
|
+
* (`catalogs/sensor-active-state.ts`, the doorbell's and the recorder's edge
|
|
51019
|
+
* table), and a sensor event names its kind, not its cap. So the table here is
|
|
51020
|
+
* DERIVED: event kind → cap (`EVENT_KIND_BY_CAP`) → that cap's active field.
|
|
51021
|
+
* Only kinds whose taxonomy category is `sensor` take part — a switch has an
|
|
51022
|
+
* `on` boolean too, but "it triggers / it clears" is not a sentence about a
|
|
51023
|
+
* light, and offering it there would be a knob with a misleading label.
|
|
51024
|
+
* `presence` is a WORD (`home` / `not_home` / a zone), not a boolean, and is
|
|
51025
|
+
* absent from the source table, so it is absent here.
|
|
51026
|
+
*
|
|
51027
|
+
* `undefined` = never guessed: a kind with no raise (a doorbell press, a
|
|
51028
|
+
* button, a cover), or a slice whose field is missing or not a boolean. The
|
|
51029
|
+
* engine then does NOT filter — a flood alert must not go silent because one
|
|
51030
|
+
* read came back unreadable (the same stance as the alarm's `sensorEdgeOf`).
|
|
51031
|
+
*
|
|
51032
|
+
* Pure, RN-safe: the viewer imports the support rule from here.
|
|
51033
|
+
*/
|
|
51034
|
+
/** Event kind → the boolean field of its cap slice that means "raised". */
|
|
51035
|
+
var NC_SENSOR_RAISED_FIELD_BY_KIND = Object.freeze(Object.fromEntries(Object.entries(EVENT_KIND_BY_CAP).flatMap(([capName, descriptor]) => {
|
|
51036
|
+
const field = SOURCE_CAP_ACTIVE_FIELD[capName];
|
|
51037
|
+
if (field === void 0 || descriptor.category !== "sensor") return [];
|
|
51038
|
+
return [[descriptor.kind, field]];
|
|
51039
|
+
})));
|
|
51040
|
+
/** The sensor kinds `sensorTransition` means something for. */
|
|
51041
|
+
var NC_SENSOR_TRANSITION_KINDS = Object.freeze(Object.keys(NC_SENSOR_RAISED_FIELD_BY_KIND));
|
|
51042
|
+
function normaliseKind(kind) {
|
|
51043
|
+
return kind.trim().toLowerCase();
|
|
51044
|
+
}
|
|
51045
|
+
/**
|
|
51046
|
+
* true = the sensor is raised (water, smoke, open, tampered…), false = it
|
|
51047
|
+
* cleared, undefined = this kind has no raise or the slice cannot say.
|
|
51048
|
+
*/
|
|
51049
|
+
function sensorRaisedOf(kind, value) {
|
|
51050
|
+
if (value === null) return void 0;
|
|
51051
|
+
const field = NC_SENSOR_RAISED_FIELD_BY_KIND[normaliseKind(kind)];
|
|
51052
|
+
if (field === void 0) return void 0;
|
|
51053
|
+
const raw = Object.entries(value).find(([key]) => key === field)?.[1];
|
|
51054
|
+
return typeof raw === "boolean" ? raw : void 0;
|
|
51055
|
+
}
|
|
50543
51056
|
var RULE_BODY_ONLY = ["body"];
|
|
50544
51057
|
var RULE_TEXT = ["title", "body"];
|
|
50545
51058
|
var BATTERY = ["device-battery-low", "device-battery-normal"];
|
|
@@ -51277,10 +51790,38 @@ var CAPTION_VARS = {
|
|
|
51277
51790
|
function onAxis(declared, asked) {
|
|
51278
51791
|
return declared === void 0 || asked === void 0 || declared.includes(asked);
|
|
51279
51792
|
}
|
|
51280
|
-
|
|
51281
|
-
|
|
51793
|
+
/**
|
|
51794
|
+
* Does a descriptor declared for `declared` kinds have a value for a rule of
|
|
51795
|
+
* `kind`?
|
|
51796
|
+
*
|
|
51797
|
+
* `system` on the WIRE stands for every system rule kind (D637): the served
|
|
51798
|
+
* catalog keeps the five pre-D637 tokens so installed viewers still parse it
|
|
51799
|
+
* (`NcTemplateVarKindSchema`), and the family split lives here, in the match.
|
|
51800
|
+
* Exported so the admin's local interpreter of the served catalog asks the
|
|
51801
|
+
* same question instead of restating it.
|
|
51802
|
+
*/
|
|
51803
|
+
function templateVarKindApplies(declared, kind) {
|
|
51804
|
+
if (declared === void 0 || kind === void 0) return true;
|
|
51805
|
+
if (declared.some((k) => k === kind)) return true;
|
|
51806
|
+
return isSystemRuleKind(kind) && declared.includes("system");
|
|
51807
|
+
}
|
|
51808
|
+
/**
|
|
51809
|
+
* Is a descriptor that names `systemEventKinds` on the event-kind axis of a
|
|
51810
|
+
* system rule? Read only for a system rule kind; any other kind ignores it.
|
|
51811
|
+
*
|
|
51812
|
+
* Event kinds chosen: the descriptor must speak about one of them. None chosen
|
|
51813
|
+
* yet: a FAMILY kind watches its own family's event kinds (a device-events rule
|
|
51814
|
+
* is never offered the alarm's `{{mode}}`), and `mixed` watches all of them.
|
|
51815
|
+
*/
|
|
51816
|
+
function templateVarSystemEventApplies(d, ctx) {
|
|
51817
|
+
if (!isSystemRuleKind(ctx.kind) || d.systemEventKinds === void 0) return true;
|
|
51818
|
+
const declared = d.systemEventKinds;
|
|
51282
51819
|
const asked = ctx.systemEventKinds ?? [];
|
|
51283
|
-
|
|
51820
|
+
if (asked.length > 0) return asked.some((k) => declared.includes(k));
|
|
51821
|
+
const family = ctx.kind === void 0 ? void 0 : systemFamilyOfKind(ctx.kind);
|
|
51822
|
+
if (family === void 0) return true;
|
|
51823
|
+
const own = systemEventKindsOfFamily(family);
|
|
51824
|
+
return declared.some((k) => own.includes(k));
|
|
51284
51825
|
}
|
|
51285
51826
|
/**
|
|
51286
51827
|
* The variables that have a value in `ctx`, in catalog order. Pure.
|
|
@@ -51294,27 +51835,13 @@ function templateVarsFor(ctx) {
|
|
|
51294
51835
|
const allowed = CAPTION_VARS[ctx.field];
|
|
51295
51836
|
return NC_TEMPLATE_VARS.filter((d) => d.families.includes(ctx.family) && allowed.includes(d.name) && d.dynamic === void 0);
|
|
51296
51837
|
}
|
|
51297
|
-
return NC_TEMPLATE_VARS.filter((d) => d.families.includes(ctx.family) && onAxis(d.fields, ctx.field) &&
|
|
51838
|
+
return NC_TEMPLATE_VARS.filter((d) => d.families.includes(ctx.family) && onAxis(d.fields, ctx.field) && templateVarKindApplies(d.kinds, ctx.kind) && onAxis(d.deliveries, ctx.delivery) && templateVarSystemEventApplies(d, ctx));
|
|
51298
51839
|
}
|
|
51299
51840
|
/** True when `name` is supplied in `ctx`, dynamic families (`count_<class>`) included. */
|
|
51300
51841
|
function isKnownTemplateVar(name, ctx) {
|
|
51301
51842
|
return templateVarsFor(ctx).some((d) => d.dynamic !== void 0 ? name.startsWith(d.dynamic.prefix) && name.length > d.dynamic.prefix.length : d.name === name);
|
|
51302
51843
|
}
|
|
51303
51844
|
/**
|
|
51304
|
-
* Does `filter` say anything about `kind`?
|
|
51305
|
-
*
|
|
51306
|
-
* `false` means the filter is not part of this kind's vocabulary: the engine
|
|
51307
|
-
* ignores it and an editor hides its input. It never means "excluded".
|
|
51308
|
-
*/
|
|
51309
|
-
function systemEventFilterApplies(kind, filter) {
|
|
51310
|
-
switch (filter) {
|
|
51311
|
-
case "deviceIds": return kind.startsWith("device-") || kind.startsWith("stream-") || kind === "detection-blind" || kind === "alarm-triggered" || kind === "export-completed";
|
|
51312
|
-
case "deviceTypes": return kind.startsWith("device-") || kind === "detection-blind";
|
|
51313
|
-
case "nodeIds": return kind.startsWith("node-") || kind === "addon-crash-loop" || kind === "addon-update-available" || kind === "addon-updated" || kind === "server-update-available" || kind === "wrapper-update-available" || kind === "server-updated";
|
|
51314
|
-
case "packageNames": return kind.endsWith("update-available") || kind === "addon-updated" || kind === "server-updated";
|
|
51315
|
-
}
|
|
51316
|
-
}
|
|
51317
|
-
/**
|
|
51318
51845
|
* TimelapseRule — the STANDALONE scheduled timelapse producer's rule model.
|
|
51319
51846
|
*
|
|
51320
51847
|
* Spec: `docs/superpowers/specs/2026-07-24-nc-occupancy-timelapse-design.md`
|
|
@@ -52318,4 +52845,4 @@ function vectorDimFromBase64(encoded) {
|
|
|
52318
52845
|
return Math.floor(Buffer.from(encoded, "base64").byteLength / 4);
|
|
52319
52846
|
}
|
|
52320
52847
|
//#endregion
|
|
52321
|
-
export {
|
|
52848
|
+
export { PoolMemoryWatchdog as $, systemEventFamilyProblems as $t, NC_SENSOR_TRANSITION_KINDS as A, isEventOwnerType as At, NcRuleSchema as B, parseProcStatus as Bt, MAX_BIRTH_DECISION_RECORDS as C, partialRecord as Cn, encodeVectorBase64 as Ct, NC_ALARM_SYSTEM_EVENT_KINDS as D, EventCategory as Dn, failureContributionCapability as Dt, MediaFileKindEnum as E, unknown as En, faceGalleryCapability as Et, NcAlarmSettingsPatchSchema as F, isSystemDelivery as Ft, NcSnoozeSchema as G, readTimelapseGeneratedAt as Gt, NcRuleUpdateInputSchema as H, pipelineAnalyticsCapability as Ht, NcConditionDescriptorSchema as I, kebabToCamel as It, NcTaxonomySchema as J, ruleBelongsToAlarm as Jt, NcSnoozeSuppressedSchema as K, resolveLocationMode as Kt, NcConditionsSchema as L, mayWriteToLocation as Lt, NC_TAXONOMY as M, isMediaOwnerType as Mt, NC_TEMPLATE_VARS as N, isScheduleActive as Nt, NC_CONDITION_CATALOG as O, hfModelUrl as Ot, NcAlarmConfigSchema as P, isSourceCap as Pt, OpsLogEntrySchema as Q, subKindsOf as Qt, NcRuleInputSchema as R, notificationRulesCapability as Rt, MAX_ARCHIVED_DEBUG_NOTES as S, object as Sn, embeddingEncoderCapability as St, MOTION_CLOSE_AFTER_MS as T, string as Tn, evictionPolicyOfLocation as Tt, NcScheduleSchema as U, plateGalleryCapability as Ut, NcRuleTargetSchema as V, pickClusterStepModels as Vt, NcSnoozeInputSchema as W, readDeviceStateFrom as Wt, NcTemplatePreviewSchema as X, sensorRaisedOf as Xt, NcTemplatePreviewInputSchema as Y, sceneMonitorCapability as Yt, NcTemplateVarDescriptorSchema as Z, storageOccupancyCapability as Zt, FIRST_LEVEL_MACRO_CLASSES as _, array as _n, audioModeOf as _t, BirthDecisionRecordSchema as a, canonicalHash as an, SCENE_DEFAULT_UNCOVERED_POLICY as at, LabelAttributionSchema as b, literal as bn, deriveRecordingMode as bt, CoverStateSchema as c, DeviceType as cn, TIMELAPSE_DENSE_FLOOR_SEC as ct, DEFAULT_TIMELAPSE_PREVIEW_TEXT as d, defineCustomActions as dn, TimelapseRuleSchema as dt, systemEventFilterApplies as en, RECORDING_EXPORT_MAX_READ_BYTES as et, DETECTION_MACRO_CLASSES as f, hydrateSchema as fn, TrackSourceSchema as ft, EVENT_OWNER_TYPES as g, _enum as gn, audioMetricsCapability as gt, EVENT_KIND_BY_CAP as h, sleep as hn, assertTimelapseCadences as ht, BaseDevice as i, errMsg as in, SCENE_DEFAULT_ANCHOR_THRESHOLD as it, NC_SNOOZE_MAX_MINUTES as j, isKnownTemplateVar as jt, NC_DEFAULT_SNOOZE_MINUTES as k, isDetectionMacroClass as kt, DEFAULT_EVENT_COLOR as l, createEvent as ln, TimelapseRuleInputSchema as lt, DeclaredDevices as m, nodePin as mn, alarmPanelCapability as mt, AlarmArmModeSchema as n, vectorDimFromBase64 as nn, RetrainStatusSchema as nt, CLUSTER_MODEL_SCOPED_STEPS as o, BaseAddon as on, SCENE_DIVERGED as ot, DETECTION_PIPELINE_CAP_NAME as p, isDeviceScopedCap as pn, addonWidgetsSourceCapability as pt, NcSystemEventKindSchema as q, resolvePoolMemoryPolicy as qt, ArchivedDebugNoteSchema as r, zoneAnalyticsCapability as rn, SCENE_CONFIRM_DEFAULT_TIMEOUT_MS as rt, COCO_TO_MACRO as s, CamProfileSchema as sn, SceneMonitorSchema as st, AUDIO_MACRO_LABELS as t, templateVarsFor as tn, RECORDING_SOURCE_CAMSTACK_ADDON as tt, DEFAULT_FIRST_SIGHTING_FRESHNESS_MS as u, customAction as un, TimelapseRulePatchSchema as ut, FULL_IMAGE_BBOX as v, boolean as vn, buildEventKindDescriptor as vt, MAX_BIRTH_LATENCY_PROXY_MS as w, record as wn, evaluateSensorEdge as wt, LockStateSchema as x, number as xn, describeSystemEventFamilyProblem as xt, FailureCounters as y, discriminatedUnion as yn, cosineSimilarity as yt, NcRulePatchSchema as z, occupancyScope as zt };
|