@camstack/addon-model-studio 1.1.117 → 1.1.119
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/{MotionZonesSettings-ONStonmD.mjs → MotionZonesSettings-C1B7ek0q.mjs} +2 -2
- package/dist/{PrivacyMaskSettings-JjT72U5m.mjs → PrivacyMaskSettings-D5Bn4NKK.mjs} +4 -4
- package/dist/{SceneMonitorEditor-Bda9WHrf.mjs → SceneMonitorEditor-BhIufhCl.mjs} +3 -3
- package/dist/_stub.js +11 -11
- package/dist/{_virtual_mf-localSharedImportMap___mfe_internal__addon_model_studio_page-Cltoio54.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_model_studio_page-BBQxiWvp.mjs} +4 -4
- package/dist/_virtual_mf___mfe_internal__addon_model_studio_page__loadShare___mf_0_camstack_mf_1_sdk__loadShare__.js-CISC_XrP.mjs +25 -0
- package/dist/_virtual_mf___mfe_internal__addon_model_studio_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-B4jedMw4.mjs +26 -0
- package/dist/addon-model-studio.css +1 -1
- package/dist/{hostInit-BPHuEeIT.mjs → hostInit-DiV4K66F.mjs} +3 -3
- package/dist/model-studio.addon.js +201 -14
- package/dist/model-studio.addon.mjs +201 -14
- package/dist/{player-overlays-DdeySlRR.mjs → player-overlays-0xs1Erjz.mjs} +1 -1
- package/dist/remoteEntry.js +1 -1
- package/dist/{responsive-CbWjxAoZ.mjs → responsive-DPVjfYqA.mjs} +1 -1
- package/dist/{square-COPzuHgN.mjs → square-Bd-ghxRh.mjs} +1 -1
- package/dist/{trash-2-CL_ANR0b.mjs → trash-2-BVelhdRT.mjs} +1 -1
- package/dist/{use-device-snapshot-TQqx6JFy.mjs → use-device-snapshot-Bw55QpDD.mjs} +1 -1
- package/dist/{virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_model_studio_page__remoteEntry_js-BUgegvHa.mjs → virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_model_studio_page__remoteEntry_js-B-64r32q.mjs} +1 -1
- package/package.json +1 -1
- package/dist/_virtual_mf___mfe_internal__addon_model_studio_page__loadShare___mf_0_camstack_mf_1_sdk__loadShare__.js-ZNPquRb4.mjs +0 -25
- package/dist/_virtual_mf___mfe_internal__addon_model_studio_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-nsY-xdN2.mjs +0 -26
|
@@ -523,7 +523,7 @@ async function importScryptedCatalogModel(input, deps) {
|
|
|
523
523
|
}
|
|
524
524
|
}
|
|
525
525
|
//#endregion
|
|
526
|
-
//#region ../types/dist/event-category-
|
|
526
|
+
//#region ../types/dist/event-category-DAXzJeTX.mjs
|
|
527
527
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
528
528
|
EventCategory["SystemBoot"] = "system.boot";
|
|
529
529
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -1115,7 +1115,6 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
1115
1115
|
* issue. Payload `PipelineAnalyticsPlateGalleryChangedPayload`.
|
|
1116
1116
|
*/
|
|
1117
1117
|
EventCategory["PipelineAnalyticsPlateGalleryChanged"] = "pipeline-analytics.plate-gallery-changed";
|
|
1118
|
-
EventCategory["FrigateLiveEvent"] = "frigate.live-event";
|
|
1119
1118
|
EventCategory["CameraStreamsProfileSlotsChanged"] = "camera-streams.onProfileSlotsChanged";
|
|
1120
1119
|
/**
|
|
1121
1120
|
* Stream-broker health watchdog. Per-broker (deviceId/profile) emission.
|
|
@@ -13146,7 +13145,7 @@ DeviceType.Camera;
|
|
|
13146
13145
|
var SourceInfoSchema = object({
|
|
13147
13146
|
/** Live dispatch key — mutable when the source system allows rename. */
|
|
13148
13147
|
id: string(),
|
|
13149
|
-
/** Source system tag — e.g. 'homeassistant' | 'reolink' | '
|
|
13148
|
+
/** Source system tag — e.g. 'homeassistant' | 'reolink' | 'onvif'. */
|
|
13150
13149
|
system: string(),
|
|
13151
13150
|
/** Immutable upstream identifier when available (HA `unique_id`, … ).
|
|
13152
13151
|
* Used to detect rename when `id` changes. */
|
|
@@ -13633,7 +13632,7 @@ method(_void(), _void(), { kind: "mutation" }), method(_void(), _void(), { kind:
|
|
|
13633
13632
|
* - `device-management.router.ts` (deleted in Phase 2)
|
|
13634
13633
|
* - `device-ops.router.ts` (compat layer — deleted; device-provider ops absorbed here)
|
|
13635
13634
|
*
|
|
13636
|
-
* All device provider addons (rtsp, onvif,
|
|
13635
|
+
* All device provider addons (rtsp, onvif, …) are hub-local: they may
|
|
13637
13636
|
* fork into separate processes but never run on remote cluster agents. Therefore:
|
|
13638
13637
|
* - No nodeId routing needed — this is a pure hub singleton.
|
|
13639
13638
|
* - The hub's DeviceRegistry is the single source of truth for all live devices.
|
|
@@ -17649,7 +17648,7 @@ var NcRuleInputSchema = object({
|
|
|
17649
17648
|
* The measured seven-person arrival on device 590 spans 110 s with every
|
|
17650
17649
|
* internal gap under 30 s. A 12 s fixed window cuts it into three groups; an
|
|
17651
17650
|
* idle cutoff holds it as one and ends it when the arrival actually ends.
|
|
17652
|
-
* 30 is
|
|
17651
|
+
* 30 s is a widely shipped value for the same decision.
|
|
17653
17652
|
*
|
|
17654
17653
|
* ### What it replaces
|
|
17655
17654
|
*
|
|
@@ -19691,6 +19690,13 @@ var ZoneCrossingSchema = object({
|
|
|
19691
19690
|
/** Zone display name at crossing time (falls back to the id). */
|
|
19692
19691
|
zoneName: string().optional()
|
|
19693
19692
|
});
|
|
19693
|
+
/** One zone a box was stamped with, and how much of the BOX fell inside it. */
|
|
19694
|
+
var ZoneOverlapSchema = object({
|
|
19695
|
+
zoneId: string(),
|
|
19696
|
+
zoneName: string().optional(),
|
|
19697
|
+
/** Percentage of the BOX area inside the zone, 0–100. */
|
|
19698
|
+
overlapPct: number()
|
|
19699
|
+
});
|
|
19694
19700
|
var ObjectEventSchema = object({
|
|
19695
19701
|
...BaseEventFields,
|
|
19696
19702
|
kind: literal("object"),
|
|
@@ -19715,6 +19721,35 @@ var ObjectEventSchema = object({
|
|
|
19715
19721
|
bbox: BoundingBoxSchema.optional(),
|
|
19716
19722
|
/** Heavy JSON — omitted in slim projection. */
|
|
19717
19723
|
zones: array(string()).readonly().optional(),
|
|
19724
|
+
/**
|
|
19725
|
+
* How far inside each stamped zone the box actually was, as a percentage of
|
|
19726
|
+
* the BOX area.
|
|
19727
|
+
*
|
|
19728
|
+
* Membership alone cannot express "at least a third of it inside", which is
|
|
19729
|
+
* the bar an operator argues with — and the number already existed: the
|
|
19730
|
+
* engine computed it, the pipeline logged it, and then discarded it. It
|
|
19731
|
+
* matters most on the events that carry no track, where a rule has nothing
|
|
19732
|
+
* else to judge by.
|
|
19733
|
+
*/
|
|
19734
|
+
zoneOverlaps: array(ZoneOverlapSchema).readonly().optional(),
|
|
19735
|
+
/**
|
|
19736
|
+
* Present when this event describes a detection the TRACKER refused, so it
|
|
19737
|
+
* has no track and never will.
|
|
19738
|
+
*
|
|
19739
|
+
* A zone-scoped immediate rule asks "is there an animal in the flowerbed
|
|
19740
|
+
* NOW?"; tracking answers a different question ("is this the same subject as
|
|
19741
|
+
* before?") whose confirmation threshold presumes continuity. On 2026-09-09 a
|
|
19742
|
+
* dog at 0.7729, 100% inside a watched zone, was refused three times in six
|
|
19743
|
+
* seconds with three different candidate ids — seven analysed frames in the
|
|
19744
|
+
* window, the subject in a handful of them, metres apart — and produced no
|
|
19745
|
+
* event at all.
|
|
19746
|
+
*
|
|
19747
|
+
* It is NAMED rather than merely implied by a missing `trackId`: an event
|
|
19748
|
+
* with no track and no reason is indistinguishable from a track whose media
|
|
19749
|
+
* went missing, and a consumer that asks this one for a best shot or a
|
|
19750
|
+
* history is asking for something that never existed.
|
|
19751
|
+
*/
|
|
19752
|
+
spawnRefused: string().optional(),
|
|
19718
19753
|
/** Omitted in slim projection. */
|
|
19719
19754
|
state: TrackStateSchema.optional(),
|
|
19720
19755
|
/**
|
|
@@ -20788,6 +20823,60 @@ var NativeCropResultSchema = object({
|
|
|
20788
20823
|
*/
|
|
20789
20824
|
tier: _enum(["native", "ram-fullframe"]).optional()
|
|
20790
20825
|
});
|
|
20826
|
+
/**
|
|
20827
|
+
* What a PARKED frame is for — the `kind` half of the `(deviceId, trackId,
|
|
20828
|
+
* kind)` key ([D422](../../../docs/decisions/adr-0422-a-relevant-frame-is-parked-when-it-becomes-relevant.md)).
|
|
20829
|
+
*
|
|
20830
|
+
* - `keyFrame` — the track's clean best FULL frame at native width (capped by
|
|
20831
|
+
* the caller's `maxWidth`). What `keyFrame` + `keyFrameSmall` are written
|
|
20832
|
+
* from, and what the detail plane's full-frame rung cuts from.
|
|
20833
|
+
* - `thumbnail` — the best-shot subject slab: the caller's 16:9 central-square
|
|
20834
|
+
* window, cut by the runner at uncapped native resolution.
|
|
20835
|
+
*
|
|
20836
|
+
* The runner never interprets `trackId`; it is an opaque key the hub owns.
|
|
20837
|
+
*/
|
|
20838
|
+
var ParkedFrameKindSchema = _enum(["keyFrame", "thumbnail"]);
|
|
20839
|
+
/**
|
|
20840
|
+
* Why a park did NOT happen. Every one is logged on the runner with
|
|
20841
|
+
* `tags: { deviceId }` and the handle's measured age, because a handle already
|
|
20842
|
+
* gone at park time IS the defect the 150–500 ms window exists to prevent —
|
|
20843
|
+
* never a reason to retry in a loop.
|
|
20844
|
+
*
|
|
20845
|
+
* - `handle-gone` — the native surface no longer resolves this handle (never
|
|
20846
|
+
* registered, past the lease bound, or the worker released it). `detail`
|
|
20847
|
+
* carries the runner's own miss reason.
|
|
20848
|
+
* - `encode-failed` — pixels resolved and the JPEG encode threw.
|
|
20849
|
+
*/
|
|
20850
|
+
var ParkRefusalSchema = _enum(["handle-gone", "encode-failed"]);
|
|
20851
|
+
/** Answer to `parkTrackFrame` — a discriminated union, so "not parked" always names why. */
|
|
20852
|
+
var ParkTrackFrameResultSchema = discriminatedUnion("parked", [object({
|
|
20853
|
+
parked: literal(true),
|
|
20854
|
+
/** The node holding the parcel — what a later retrieval must be pinned to. */
|
|
20855
|
+
nodeId: string(),
|
|
20856
|
+
width: number().int().positive(),
|
|
20857
|
+
height: number().int().positive(),
|
|
20858
|
+
/** JPEG bytes the parcel costs on the node. */
|
|
20859
|
+
bytes: number().int().nonnegative(),
|
|
20860
|
+
/** Whether this park replaced a parcel already held for the key. */
|
|
20861
|
+
replaced: boolean()
|
|
20862
|
+
}), object({
|
|
20863
|
+
parked: literal(false),
|
|
20864
|
+
nodeId: string(),
|
|
20865
|
+
reason: ParkRefusalSchema,
|
|
20866
|
+
/** Age of the handle at the park, on the runner's clock; null if unknown. */
|
|
20867
|
+
handleAgeMs: number().nullable(),
|
|
20868
|
+
detail: string().optional()
|
|
20869
|
+
})]);
|
|
20870
|
+
/** A retrieved parcel — the runner's own JPEG, base64 for the wire. */
|
|
20871
|
+
var ParkedTrackFrameSchema = object({
|
|
20872
|
+
jpeg: string(),
|
|
20873
|
+
width: number().int().positive(),
|
|
20874
|
+
height: number().int().positive(),
|
|
20875
|
+
/** The frame instant the parcel shows (the caller's clock, echoed back). */
|
|
20876
|
+
timestamp: number(),
|
|
20877
|
+
/** When the node stored it (the node's clock). */
|
|
20878
|
+
parkedAt: number()
|
|
20879
|
+
});
|
|
20791
20880
|
/** Parent detection context passed to `runDetailSubtree` — the crop's
|
|
20792
20881
|
* originating detection, in FRAME-space coordinates. Reuses
|
|
20793
20882
|
* `NativeCropBboxSchema`'s `{x,y,w,h}` shape (same numeric fields; here
|
|
@@ -21177,7 +21266,7 @@ var RunnerCameraConfigSchema = object({
|
|
|
21177
21266
|
* - `analyzer`: ML/frame-diff motion detection (motion-wasm or other
|
|
21178
21267
|
* analyzer providers) running on decoded frames in this runner.
|
|
21179
21268
|
* - `onboard`: camera-native motion pushes (Reolink Baichuan, ONVIF
|
|
21180
|
-
* analytics
|
|
21269
|
+
* analytics). The provider emits ProviderMotion
|
|
21181
21270
|
* events; the orchestrator forwards to `reportMotion`.
|
|
21182
21271
|
*/
|
|
21183
21272
|
motionSources: MotionSourcesSchema.default(["analyzer"]),
|
|
@@ -21419,7 +21508,26 @@ method(RunnerCameraConfigSchema, object({ success: literal(true) }), { kind: "mu
|
|
|
21419
21508
|
className: string(),
|
|
21420
21509
|
/** Camera the pixels came from. Diagnostics + log tags ONLY — never routing. */
|
|
21421
21510
|
sourceDeviceId: number()
|
|
21422
|
-
}), RunStatelessStepResultSchema, { kind: "mutation" })
|
|
21511
|
+
}), RunStatelessStepResultSchema, { kind: "mutation" }), method(object({
|
|
21512
|
+
deviceId: number(),
|
|
21513
|
+
/** Opaque to the runner — the hub's track id. */
|
|
21514
|
+
trackId: string(),
|
|
21515
|
+
kind: ParkedFrameKindSchema,
|
|
21516
|
+
handle: FrameHandleSchema,
|
|
21517
|
+
/** Normalized [0,1] window to cut. `{0,0,1,1}` for a full frame. */
|
|
21518
|
+
bbox: NativeCropBboxSchema,
|
|
21519
|
+
/** Width cap for a full-frame park (the `keyFrame` native cap). */
|
|
21520
|
+
maxWidth: number().int().positive().optional(),
|
|
21521
|
+
/** The frame instant (caller's clock) — orders parks for one key. */
|
|
21522
|
+
timestamp: number()
|
|
21523
|
+
}), ParkTrackFrameResultSchema, { kind: "mutation" }), method(object({
|
|
21524
|
+
deviceId: number(),
|
|
21525
|
+
trackId: string(),
|
|
21526
|
+
kind: ParkedFrameKindSchema
|
|
21527
|
+
}), ParkedTrackFrameSchema.nullable()), method(object({
|
|
21528
|
+
deviceId: number(),
|
|
21529
|
+
trackId: string()
|
|
21530
|
+
}), object({ released: number().int().nonnegative() }), { kind: "mutation" });
|
|
21423
21531
|
var CameraPipelineConfigSchema = object({
|
|
21424
21532
|
engine: PipelineEngineChoiceSchema.optional(),
|
|
21425
21533
|
steps: array(PipelineStepInputSchema).readonly(),
|
|
@@ -24348,7 +24456,7 @@ DeviceType.Button, method(object({ deviceId: number().int().nonnegative() }), _v
|
|
|
24348
24456
|
*
|
|
24349
24457
|
* Implementations:
|
|
24350
24458
|
* - Each camera-providing addon registers this cap natively per
|
|
24351
|
-
* device (Reolink, Hikvision, RTSP,
|
|
24459
|
+
* device (Reolink, Hikvision, RTSP, ONVIF self).
|
|
24352
24460
|
* - Returns a snapshot from the persisted device config blob — no
|
|
24353
24461
|
* extra round-trip to the camera, no probing.
|
|
24354
24462
|
* - The cap is admin-only (`auth: 'admin'`) — credentials must not
|
|
@@ -25734,7 +25842,7 @@ var AvailableIntegrationTypeSchema = object({
|
|
|
25734
25842
|
* Which integration-marker cap the addon declared, so the wizard can
|
|
25735
25843
|
* branch on CAP — never on addon name. `device-adoption` integrations
|
|
25736
25844
|
* (Home Assistant, …) route through the broker step (Approach A);
|
|
25737
|
-
* `device-provider` integrations (Reolink/
|
|
25845
|
+
* `device-provider` integrations (Reolink/ONVIF) keep the
|
|
25738
25846
|
* legacy config → discovery flow.
|
|
25739
25847
|
*/
|
|
25740
25848
|
kind: _enum(["device-adoption", "device-provider"]),
|
|
@@ -28291,13 +28399,31 @@ var RecordingManifestSchema = object({
|
|
|
28291
28399
|
*/
|
|
28292
28400
|
playbackEndpoints: array(string())
|
|
28293
28401
|
});
|
|
28294
|
-
/**
|
|
28295
|
-
*
|
|
28402
|
+
/**
|
|
28403
|
+
* Recording storage usage for one camera — what the ARCHIVE holds for it,
|
|
28404
|
+
* across every profile and every resolvable location on this node.
|
|
28405
|
+
*
|
|
28406
|
+
* ## Archive vs residency, which is the whole point of this shape (D418)
|
|
28407
|
+
*
|
|
28408
|
+
* `usedBytes` / `oldestMs` / `segments` are the durable hour ledger's numbers:
|
|
28409
|
+
* the same quantity `RecordingLocationUsage.usedBytes` reports for the volume
|
|
28410
|
+
* this camera writes to, so the two can be added up and compared.
|
|
28411
|
+
*
|
|
28412
|
+
* They were not always. Until D418 this row came from the recorder's in-RAM
|
|
28413
|
+
* `RecordingIndex`, which since D287 holds only the live tail plus the hours
|
|
28414
|
+
* somebody hydrated — so a hub with 1.9 TB and 3.3 days of footage reported
|
|
28415
|
+
* 60.5 GB and "oldest: three hours ago" on the same page as the volume row
|
|
28416
|
+
* that said otherwise, and two people read it as retention eating recent
|
|
28417
|
+
* footage. Residency is still reported, under `residentBytes` /
|
|
28418
|
+
* `residentOldestMs`, which answer a different question and say so.
|
|
28419
|
+
*/
|
|
28296
28420
|
var RecordingDeviceUsageSchema = object({
|
|
28297
28421
|
deviceId: number(),
|
|
28422
|
+
/** Bytes the ARCHIVE holds for this camera on this node's resolvable
|
|
28423
|
+
* recordings locations. */
|
|
28298
28424
|
usedBytes: number(),
|
|
28299
28425
|
/**
|
|
28300
|
-
* Start of this camera's OLDEST
|
|
28426
|
+
* Start of this camera's OLDEST ARCHIVED segment, across every profile and
|
|
28301
28427
|
* location — the "Oldest footage" column in Recordings → Storage, and the
|
|
28302
28428
|
* only honest answer to "is retention actually holding?" per camera.
|
|
28303
28429
|
*
|
|
@@ -28307,7 +28433,24 @@ var RecordingDeviceUsageSchema = object({
|
|
|
28307
28433
|
* (types) and the addon ship on different trains, and the addon is usually
|
|
28308
28434
|
* the later of the two.
|
|
28309
28435
|
*/
|
|
28310
|
-
oldestMs: number().nullable().optional()
|
|
28436
|
+
oldestMs: number().nullable().optional(),
|
|
28437
|
+
/** Segments the archive holds for this camera — the "M" beside `usedBytes`.
|
|
28438
|
+
* OPTIONAL for the same train-skew reason as `oldestMs`. */
|
|
28439
|
+
segments: number().optional(),
|
|
28440
|
+
/**
|
|
28441
|
+
* RESIDENCY, not the archive: bytes the recorder process currently holds in
|
|
28442
|
+
* its RAM index — the live tail plus the hours a reader hydrated.
|
|
28443
|
+
*
|
|
28444
|
+
* It answers "what can be served without touching the disk", never "how much
|
|
28445
|
+
* footage this camera has". A UI that renders it must label it as such, and
|
|
28446
|
+
* must never total it as storage. OPTIONAL: a recorder predating D418 omits
|
|
28447
|
+
* it, and so does a node whose ledger could not answer.
|
|
28448
|
+
*/
|
|
28449
|
+
residentBytes: number().optional(),
|
|
28450
|
+
/** The residency counterpart of `oldestMs` — the oldest segment currently in
|
|
28451
|
+
* RAM, which on a healthy recorder is minutes ago and means nothing about
|
|
28452
|
+
* retention. `null` = nothing resident. */
|
|
28453
|
+
residentOldestMs: number().nullable().optional()
|
|
28311
28454
|
});
|
|
28312
28455
|
/** Recording storage usage + capacity for one storage location. */
|
|
28313
28456
|
var RecordingLocationUsageSchema = object({
|
|
@@ -28345,6 +28488,17 @@ var RecordingStorageUsageSchema = object({
|
|
|
28345
28488
|
totalUsedBytes: number(),
|
|
28346
28489
|
devices: array(RecordingDeviceUsageSchema),
|
|
28347
28490
|
/**
|
|
28491
|
+
* WHERE `devices[]` came from, so an empty table is never mistaken for empty
|
|
28492
|
+
* disks (D418).
|
|
28493
|
+
*
|
|
28494
|
+
* `archive` = the durable hour ledger answered. `unavailable` = this node
|
|
28495
|
+
* declared no ledger and the recorder REFUSED rather than answering the
|
|
28496
|
+
* question with the resident index (D295 rule 3) — the rows are UNKNOWN, not
|
|
28497
|
+
* zero, and a UI must say so. OPTIONAL: a recorder predating D418 omits it,
|
|
28498
|
+
* and its rows are residency.
|
|
28499
|
+
*/
|
|
28500
|
+
devicesRead: _enum(["archive", "unavailable"]).optional(),
|
|
28501
|
+
/**
|
|
28348
28502
|
* Per-physical-volume capacity. OPTIONAL, and consumers must render the rest
|
|
28349
28503
|
* of the payload without it: the hub serves this method through a BAKED
|
|
28350
28504
|
* router, so a hub whose framework train predates a change to this array
|
|
@@ -34732,6 +34886,24 @@ Object.freeze({
|
|
|
34732
34886
|
addonId: null,
|
|
34733
34887
|
access: "view"
|
|
34734
34888
|
},
|
|
34889
|
+
"pipelineRunner.getParkedTrackFrame": {
|
|
34890
|
+
capName: "pipeline-runner",
|
|
34891
|
+
capScope: "system",
|
|
34892
|
+
addonId: null,
|
|
34893
|
+
access: "view"
|
|
34894
|
+
},
|
|
34895
|
+
"pipelineRunner.parkTrackFrame": {
|
|
34896
|
+
capName: "pipeline-runner",
|
|
34897
|
+
capScope: "system",
|
|
34898
|
+
addonId: null,
|
|
34899
|
+
access: "create"
|
|
34900
|
+
},
|
|
34901
|
+
"pipelineRunner.releaseParkedTrackFrames": {
|
|
34902
|
+
capName: "pipeline-runner",
|
|
34903
|
+
capScope: "system",
|
|
34904
|
+
addonId: null,
|
|
34905
|
+
access: "create"
|
|
34906
|
+
},
|
|
34735
34907
|
"pipelineRunner.reportMotion": {
|
|
34736
34908
|
capName: "pipeline-runner",
|
|
34737
34909
|
capScope: "system",
|
|
@@ -38009,6 +38181,21 @@ Object.freeze({
|
|
|
38009
38181
|
form: "single",
|
|
38010
38182
|
optional: false
|
|
38011
38183
|
}],
|
|
38184
|
+
"pipelineRunner.getParkedTrackFrame": [{
|
|
38185
|
+
name: "deviceId",
|
|
38186
|
+
form: "single",
|
|
38187
|
+
optional: false
|
|
38188
|
+
}],
|
|
38189
|
+
"pipelineRunner.parkTrackFrame": [{
|
|
38190
|
+
name: "deviceId",
|
|
38191
|
+
form: "single",
|
|
38192
|
+
optional: false
|
|
38193
|
+
}],
|
|
38194
|
+
"pipelineRunner.releaseParkedTrackFrames": [{
|
|
38195
|
+
name: "deviceId",
|
|
38196
|
+
form: "single",
|
|
38197
|
+
optional: false
|
|
38198
|
+
}],
|
|
38012
38199
|
"pipelineRunner.reportMotion": [{
|
|
38013
38200
|
name: "deviceId",
|
|
38014
38201
|
form: "single",
|
|
@@ -38700,7 +38887,7 @@ var PreviewTextField = string().max(200);
|
|
|
38700
38887
|
* Whether the notification's preview is a STILL or a short animation.
|
|
38701
38888
|
*
|
|
38702
38889
|
* The operator's ask, verbatim: *"inviato come gif o video (come per le altre
|
|
38703
|
-
* rule)"* —
|
|
38890
|
+
* rule)"* — the other rules already offer an animated preview, and a ten-hour
|
|
38704
38891
|
* night reads better as three seconds of motion than as one frame of it. Both
|
|
38705
38892
|
* modes get the SAME treatment (blurred frame, large centred title); `'gif'`
|
|
38706
38893
|
* simply applies it to a dozen frames sampled across the render and assembles
|
|
@@ -502,7 +502,7 @@ async function importScryptedCatalogModel(input, deps) {
|
|
|
502
502
|
}
|
|
503
503
|
}
|
|
504
504
|
//#endregion
|
|
505
|
-
//#region ../types/dist/event-category-
|
|
505
|
+
//#region ../types/dist/event-category-DAXzJeTX.mjs
|
|
506
506
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
507
507
|
EventCategory["SystemBoot"] = "system.boot";
|
|
508
508
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -1094,7 +1094,6 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
1094
1094
|
* issue. Payload `PipelineAnalyticsPlateGalleryChangedPayload`.
|
|
1095
1095
|
*/
|
|
1096
1096
|
EventCategory["PipelineAnalyticsPlateGalleryChanged"] = "pipeline-analytics.plate-gallery-changed";
|
|
1097
|
-
EventCategory["FrigateLiveEvent"] = "frigate.live-event";
|
|
1098
1097
|
EventCategory["CameraStreamsProfileSlotsChanged"] = "camera-streams.onProfileSlotsChanged";
|
|
1099
1098
|
/**
|
|
1100
1099
|
* Stream-broker health watchdog. Per-broker (deviceId/profile) emission.
|
|
@@ -13125,7 +13124,7 @@ DeviceType.Camera;
|
|
|
13125
13124
|
var SourceInfoSchema = object({
|
|
13126
13125
|
/** Live dispatch key — mutable when the source system allows rename. */
|
|
13127
13126
|
id: string(),
|
|
13128
|
-
/** Source system tag — e.g. 'homeassistant' | 'reolink' | '
|
|
13127
|
+
/** Source system tag — e.g. 'homeassistant' | 'reolink' | 'onvif'. */
|
|
13129
13128
|
system: string(),
|
|
13130
13129
|
/** Immutable upstream identifier when available (HA `unique_id`, … ).
|
|
13131
13130
|
* Used to detect rename when `id` changes. */
|
|
@@ -13612,7 +13611,7 @@ method(_void(), _void(), { kind: "mutation" }), method(_void(), _void(), { kind:
|
|
|
13612
13611
|
* - `device-management.router.ts` (deleted in Phase 2)
|
|
13613
13612
|
* - `device-ops.router.ts` (compat layer — deleted; device-provider ops absorbed here)
|
|
13614
13613
|
*
|
|
13615
|
-
* All device provider addons (rtsp, onvif,
|
|
13614
|
+
* All device provider addons (rtsp, onvif, …) are hub-local: they may
|
|
13616
13615
|
* fork into separate processes but never run on remote cluster agents. Therefore:
|
|
13617
13616
|
* - No nodeId routing needed — this is a pure hub singleton.
|
|
13618
13617
|
* - The hub's DeviceRegistry is the single source of truth for all live devices.
|
|
@@ -17628,7 +17627,7 @@ var NcRuleInputSchema = object({
|
|
|
17628
17627
|
* The measured seven-person arrival on device 590 spans 110 s with every
|
|
17629
17628
|
* internal gap under 30 s. A 12 s fixed window cuts it into three groups; an
|
|
17630
17629
|
* idle cutoff holds it as one and ends it when the arrival actually ends.
|
|
17631
|
-
* 30 is
|
|
17630
|
+
* 30 s is a widely shipped value for the same decision.
|
|
17632
17631
|
*
|
|
17633
17632
|
* ### What it replaces
|
|
17634
17633
|
*
|
|
@@ -19670,6 +19669,13 @@ var ZoneCrossingSchema = object({
|
|
|
19670
19669
|
/** Zone display name at crossing time (falls back to the id). */
|
|
19671
19670
|
zoneName: string().optional()
|
|
19672
19671
|
});
|
|
19672
|
+
/** One zone a box was stamped with, and how much of the BOX fell inside it. */
|
|
19673
|
+
var ZoneOverlapSchema = object({
|
|
19674
|
+
zoneId: string(),
|
|
19675
|
+
zoneName: string().optional(),
|
|
19676
|
+
/** Percentage of the BOX area inside the zone, 0–100. */
|
|
19677
|
+
overlapPct: number()
|
|
19678
|
+
});
|
|
19673
19679
|
var ObjectEventSchema = object({
|
|
19674
19680
|
...BaseEventFields,
|
|
19675
19681
|
kind: literal("object"),
|
|
@@ -19694,6 +19700,35 @@ var ObjectEventSchema = object({
|
|
|
19694
19700
|
bbox: BoundingBoxSchema.optional(),
|
|
19695
19701
|
/** Heavy JSON — omitted in slim projection. */
|
|
19696
19702
|
zones: array(string()).readonly().optional(),
|
|
19703
|
+
/**
|
|
19704
|
+
* How far inside each stamped zone the box actually was, as a percentage of
|
|
19705
|
+
* the BOX area.
|
|
19706
|
+
*
|
|
19707
|
+
* Membership alone cannot express "at least a third of it inside", which is
|
|
19708
|
+
* the bar an operator argues with — and the number already existed: the
|
|
19709
|
+
* engine computed it, the pipeline logged it, and then discarded it. It
|
|
19710
|
+
* matters most on the events that carry no track, where a rule has nothing
|
|
19711
|
+
* else to judge by.
|
|
19712
|
+
*/
|
|
19713
|
+
zoneOverlaps: array(ZoneOverlapSchema).readonly().optional(),
|
|
19714
|
+
/**
|
|
19715
|
+
* Present when this event describes a detection the TRACKER refused, so it
|
|
19716
|
+
* has no track and never will.
|
|
19717
|
+
*
|
|
19718
|
+
* A zone-scoped immediate rule asks "is there an animal in the flowerbed
|
|
19719
|
+
* NOW?"; tracking answers a different question ("is this the same subject as
|
|
19720
|
+
* before?") whose confirmation threshold presumes continuity. On 2026-09-09 a
|
|
19721
|
+
* dog at 0.7729, 100% inside a watched zone, was refused three times in six
|
|
19722
|
+
* seconds with three different candidate ids — seven analysed frames in the
|
|
19723
|
+
* window, the subject in a handful of them, metres apart — and produced no
|
|
19724
|
+
* event at all.
|
|
19725
|
+
*
|
|
19726
|
+
* It is NAMED rather than merely implied by a missing `trackId`: an event
|
|
19727
|
+
* with no track and no reason is indistinguishable from a track whose media
|
|
19728
|
+
* went missing, and a consumer that asks this one for a best shot or a
|
|
19729
|
+
* history is asking for something that never existed.
|
|
19730
|
+
*/
|
|
19731
|
+
spawnRefused: string().optional(),
|
|
19697
19732
|
/** Omitted in slim projection. */
|
|
19698
19733
|
state: TrackStateSchema.optional(),
|
|
19699
19734
|
/**
|
|
@@ -20767,6 +20802,60 @@ var NativeCropResultSchema = object({
|
|
|
20767
20802
|
*/
|
|
20768
20803
|
tier: _enum(["native", "ram-fullframe"]).optional()
|
|
20769
20804
|
});
|
|
20805
|
+
/**
|
|
20806
|
+
* What a PARKED frame is for — the `kind` half of the `(deviceId, trackId,
|
|
20807
|
+
* kind)` key ([D422](../../../docs/decisions/adr-0422-a-relevant-frame-is-parked-when-it-becomes-relevant.md)).
|
|
20808
|
+
*
|
|
20809
|
+
* - `keyFrame` — the track's clean best FULL frame at native width (capped by
|
|
20810
|
+
* the caller's `maxWidth`). What `keyFrame` + `keyFrameSmall` are written
|
|
20811
|
+
* from, and what the detail plane's full-frame rung cuts from.
|
|
20812
|
+
* - `thumbnail` — the best-shot subject slab: the caller's 16:9 central-square
|
|
20813
|
+
* window, cut by the runner at uncapped native resolution.
|
|
20814
|
+
*
|
|
20815
|
+
* The runner never interprets `trackId`; it is an opaque key the hub owns.
|
|
20816
|
+
*/
|
|
20817
|
+
var ParkedFrameKindSchema = _enum(["keyFrame", "thumbnail"]);
|
|
20818
|
+
/**
|
|
20819
|
+
* Why a park did NOT happen. Every one is logged on the runner with
|
|
20820
|
+
* `tags: { deviceId }` and the handle's measured age, because a handle already
|
|
20821
|
+
* gone at park time IS the defect the 150–500 ms window exists to prevent —
|
|
20822
|
+
* never a reason to retry in a loop.
|
|
20823
|
+
*
|
|
20824
|
+
* - `handle-gone` — the native surface no longer resolves this handle (never
|
|
20825
|
+
* registered, past the lease bound, or the worker released it). `detail`
|
|
20826
|
+
* carries the runner's own miss reason.
|
|
20827
|
+
* - `encode-failed` — pixels resolved and the JPEG encode threw.
|
|
20828
|
+
*/
|
|
20829
|
+
var ParkRefusalSchema = _enum(["handle-gone", "encode-failed"]);
|
|
20830
|
+
/** Answer to `parkTrackFrame` — a discriminated union, so "not parked" always names why. */
|
|
20831
|
+
var ParkTrackFrameResultSchema = discriminatedUnion("parked", [object({
|
|
20832
|
+
parked: literal(true),
|
|
20833
|
+
/** The node holding the parcel — what a later retrieval must be pinned to. */
|
|
20834
|
+
nodeId: string(),
|
|
20835
|
+
width: number().int().positive(),
|
|
20836
|
+
height: number().int().positive(),
|
|
20837
|
+
/** JPEG bytes the parcel costs on the node. */
|
|
20838
|
+
bytes: number().int().nonnegative(),
|
|
20839
|
+
/** Whether this park replaced a parcel already held for the key. */
|
|
20840
|
+
replaced: boolean()
|
|
20841
|
+
}), object({
|
|
20842
|
+
parked: literal(false),
|
|
20843
|
+
nodeId: string(),
|
|
20844
|
+
reason: ParkRefusalSchema,
|
|
20845
|
+
/** Age of the handle at the park, on the runner's clock; null if unknown. */
|
|
20846
|
+
handleAgeMs: number().nullable(),
|
|
20847
|
+
detail: string().optional()
|
|
20848
|
+
})]);
|
|
20849
|
+
/** A retrieved parcel — the runner's own JPEG, base64 for the wire. */
|
|
20850
|
+
var ParkedTrackFrameSchema = object({
|
|
20851
|
+
jpeg: string(),
|
|
20852
|
+
width: number().int().positive(),
|
|
20853
|
+
height: number().int().positive(),
|
|
20854
|
+
/** The frame instant the parcel shows (the caller's clock, echoed back). */
|
|
20855
|
+
timestamp: number(),
|
|
20856
|
+
/** When the node stored it (the node's clock). */
|
|
20857
|
+
parkedAt: number()
|
|
20858
|
+
});
|
|
20770
20859
|
/** Parent detection context passed to `runDetailSubtree` — the crop's
|
|
20771
20860
|
* originating detection, in FRAME-space coordinates. Reuses
|
|
20772
20861
|
* `NativeCropBboxSchema`'s `{x,y,w,h}` shape (same numeric fields; here
|
|
@@ -21156,7 +21245,7 @@ var RunnerCameraConfigSchema = object({
|
|
|
21156
21245
|
* - `analyzer`: ML/frame-diff motion detection (motion-wasm or other
|
|
21157
21246
|
* analyzer providers) running on decoded frames in this runner.
|
|
21158
21247
|
* - `onboard`: camera-native motion pushes (Reolink Baichuan, ONVIF
|
|
21159
|
-
* analytics
|
|
21248
|
+
* analytics). The provider emits ProviderMotion
|
|
21160
21249
|
* events; the orchestrator forwards to `reportMotion`.
|
|
21161
21250
|
*/
|
|
21162
21251
|
motionSources: MotionSourcesSchema.default(["analyzer"]),
|
|
@@ -21398,7 +21487,26 @@ method(RunnerCameraConfigSchema, object({ success: literal(true) }), { kind: "mu
|
|
|
21398
21487
|
className: string(),
|
|
21399
21488
|
/** Camera the pixels came from. Diagnostics + log tags ONLY — never routing. */
|
|
21400
21489
|
sourceDeviceId: number()
|
|
21401
|
-
}), RunStatelessStepResultSchema, { kind: "mutation" })
|
|
21490
|
+
}), RunStatelessStepResultSchema, { kind: "mutation" }), method(object({
|
|
21491
|
+
deviceId: number(),
|
|
21492
|
+
/** Opaque to the runner — the hub's track id. */
|
|
21493
|
+
trackId: string(),
|
|
21494
|
+
kind: ParkedFrameKindSchema,
|
|
21495
|
+
handle: FrameHandleSchema,
|
|
21496
|
+
/** Normalized [0,1] window to cut. `{0,0,1,1}` for a full frame. */
|
|
21497
|
+
bbox: NativeCropBboxSchema,
|
|
21498
|
+
/** Width cap for a full-frame park (the `keyFrame` native cap). */
|
|
21499
|
+
maxWidth: number().int().positive().optional(),
|
|
21500
|
+
/** The frame instant (caller's clock) — orders parks for one key. */
|
|
21501
|
+
timestamp: number()
|
|
21502
|
+
}), ParkTrackFrameResultSchema, { kind: "mutation" }), method(object({
|
|
21503
|
+
deviceId: number(),
|
|
21504
|
+
trackId: string(),
|
|
21505
|
+
kind: ParkedFrameKindSchema
|
|
21506
|
+
}), ParkedTrackFrameSchema.nullable()), method(object({
|
|
21507
|
+
deviceId: number(),
|
|
21508
|
+
trackId: string()
|
|
21509
|
+
}), object({ released: number().int().nonnegative() }), { kind: "mutation" });
|
|
21402
21510
|
var CameraPipelineConfigSchema = object({
|
|
21403
21511
|
engine: PipelineEngineChoiceSchema.optional(),
|
|
21404
21512
|
steps: array(PipelineStepInputSchema).readonly(),
|
|
@@ -24327,7 +24435,7 @@ DeviceType.Button, method(object({ deviceId: number().int().nonnegative() }), _v
|
|
|
24327
24435
|
*
|
|
24328
24436
|
* Implementations:
|
|
24329
24437
|
* - Each camera-providing addon registers this cap natively per
|
|
24330
|
-
* device (Reolink, Hikvision, RTSP,
|
|
24438
|
+
* device (Reolink, Hikvision, RTSP, ONVIF self).
|
|
24331
24439
|
* - Returns a snapshot from the persisted device config blob — no
|
|
24332
24440
|
* extra round-trip to the camera, no probing.
|
|
24333
24441
|
* - The cap is admin-only (`auth: 'admin'`) — credentials must not
|
|
@@ -25713,7 +25821,7 @@ var AvailableIntegrationTypeSchema = object({
|
|
|
25713
25821
|
* Which integration-marker cap the addon declared, so the wizard can
|
|
25714
25822
|
* branch on CAP — never on addon name. `device-adoption` integrations
|
|
25715
25823
|
* (Home Assistant, …) route through the broker step (Approach A);
|
|
25716
|
-
* `device-provider` integrations (Reolink/
|
|
25824
|
+
* `device-provider` integrations (Reolink/ONVIF) keep the
|
|
25717
25825
|
* legacy config → discovery flow.
|
|
25718
25826
|
*/
|
|
25719
25827
|
kind: _enum(["device-adoption", "device-provider"]),
|
|
@@ -28270,13 +28378,31 @@ var RecordingManifestSchema = object({
|
|
|
28270
28378
|
*/
|
|
28271
28379
|
playbackEndpoints: array(string())
|
|
28272
28380
|
});
|
|
28273
|
-
/**
|
|
28274
|
-
*
|
|
28381
|
+
/**
|
|
28382
|
+
* Recording storage usage for one camera — what the ARCHIVE holds for it,
|
|
28383
|
+
* across every profile and every resolvable location on this node.
|
|
28384
|
+
*
|
|
28385
|
+
* ## Archive vs residency, which is the whole point of this shape (D418)
|
|
28386
|
+
*
|
|
28387
|
+
* `usedBytes` / `oldestMs` / `segments` are the durable hour ledger's numbers:
|
|
28388
|
+
* the same quantity `RecordingLocationUsage.usedBytes` reports for the volume
|
|
28389
|
+
* this camera writes to, so the two can be added up and compared.
|
|
28390
|
+
*
|
|
28391
|
+
* They were not always. Until D418 this row came from the recorder's in-RAM
|
|
28392
|
+
* `RecordingIndex`, which since D287 holds only the live tail plus the hours
|
|
28393
|
+
* somebody hydrated — so a hub with 1.9 TB and 3.3 days of footage reported
|
|
28394
|
+
* 60.5 GB and "oldest: three hours ago" on the same page as the volume row
|
|
28395
|
+
* that said otherwise, and two people read it as retention eating recent
|
|
28396
|
+
* footage. Residency is still reported, under `residentBytes` /
|
|
28397
|
+
* `residentOldestMs`, which answer a different question and say so.
|
|
28398
|
+
*/
|
|
28275
28399
|
var RecordingDeviceUsageSchema = object({
|
|
28276
28400
|
deviceId: number(),
|
|
28401
|
+
/** Bytes the ARCHIVE holds for this camera on this node's resolvable
|
|
28402
|
+
* recordings locations. */
|
|
28277
28403
|
usedBytes: number(),
|
|
28278
28404
|
/**
|
|
28279
|
-
* Start of this camera's OLDEST
|
|
28405
|
+
* Start of this camera's OLDEST ARCHIVED segment, across every profile and
|
|
28280
28406
|
* location — the "Oldest footage" column in Recordings → Storage, and the
|
|
28281
28407
|
* only honest answer to "is retention actually holding?" per camera.
|
|
28282
28408
|
*
|
|
@@ -28286,7 +28412,24 @@ var RecordingDeviceUsageSchema = object({
|
|
|
28286
28412
|
* (types) and the addon ship on different trains, and the addon is usually
|
|
28287
28413
|
* the later of the two.
|
|
28288
28414
|
*/
|
|
28289
|
-
oldestMs: number().nullable().optional()
|
|
28415
|
+
oldestMs: number().nullable().optional(),
|
|
28416
|
+
/** Segments the archive holds for this camera — the "M" beside `usedBytes`.
|
|
28417
|
+
* OPTIONAL for the same train-skew reason as `oldestMs`. */
|
|
28418
|
+
segments: number().optional(),
|
|
28419
|
+
/**
|
|
28420
|
+
* RESIDENCY, not the archive: bytes the recorder process currently holds in
|
|
28421
|
+
* its RAM index — the live tail plus the hours a reader hydrated.
|
|
28422
|
+
*
|
|
28423
|
+
* It answers "what can be served without touching the disk", never "how much
|
|
28424
|
+
* footage this camera has". A UI that renders it must label it as such, and
|
|
28425
|
+
* must never total it as storage. OPTIONAL: a recorder predating D418 omits
|
|
28426
|
+
* it, and so does a node whose ledger could not answer.
|
|
28427
|
+
*/
|
|
28428
|
+
residentBytes: number().optional(),
|
|
28429
|
+
/** The residency counterpart of `oldestMs` — the oldest segment currently in
|
|
28430
|
+
* RAM, which on a healthy recorder is minutes ago and means nothing about
|
|
28431
|
+
* retention. `null` = nothing resident. */
|
|
28432
|
+
residentOldestMs: number().nullable().optional()
|
|
28290
28433
|
});
|
|
28291
28434
|
/** Recording storage usage + capacity for one storage location. */
|
|
28292
28435
|
var RecordingLocationUsageSchema = object({
|
|
@@ -28324,6 +28467,17 @@ var RecordingStorageUsageSchema = object({
|
|
|
28324
28467
|
totalUsedBytes: number(),
|
|
28325
28468
|
devices: array(RecordingDeviceUsageSchema),
|
|
28326
28469
|
/**
|
|
28470
|
+
* WHERE `devices[]` came from, so an empty table is never mistaken for empty
|
|
28471
|
+
* disks (D418).
|
|
28472
|
+
*
|
|
28473
|
+
* `archive` = the durable hour ledger answered. `unavailable` = this node
|
|
28474
|
+
* declared no ledger and the recorder REFUSED rather than answering the
|
|
28475
|
+
* question with the resident index (D295 rule 3) — the rows are UNKNOWN, not
|
|
28476
|
+
* zero, and a UI must say so. OPTIONAL: a recorder predating D418 omits it,
|
|
28477
|
+
* and its rows are residency.
|
|
28478
|
+
*/
|
|
28479
|
+
devicesRead: _enum(["archive", "unavailable"]).optional(),
|
|
28480
|
+
/**
|
|
28327
28481
|
* Per-physical-volume capacity. OPTIONAL, and consumers must render the rest
|
|
28328
28482
|
* of the payload without it: the hub serves this method through a BAKED
|
|
28329
28483
|
* router, so a hub whose framework train predates a change to this array
|
|
@@ -34711,6 +34865,24 @@ Object.freeze({
|
|
|
34711
34865
|
addonId: null,
|
|
34712
34866
|
access: "view"
|
|
34713
34867
|
},
|
|
34868
|
+
"pipelineRunner.getParkedTrackFrame": {
|
|
34869
|
+
capName: "pipeline-runner",
|
|
34870
|
+
capScope: "system",
|
|
34871
|
+
addonId: null,
|
|
34872
|
+
access: "view"
|
|
34873
|
+
},
|
|
34874
|
+
"pipelineRunner.parkTrackFrame": {
|
|
34875
|
+
capName: "pipeline-runner",
|
|
34876
|
+
capScope: "system",
|
|
34877
|
+
addonId: null,
|
|
34878
|
+
access: "create"
|
|
34879
|
+
},
|
|
34880
|
+
"pipelineRunner.releaseParkedTrackFrames": {
|
|
34881
|
+
capName: "pipeline-runner",
|
|
34882
|
+
capScope: "system",
|
|
34883
|
+
addonId: null,
|
|
34884
|
+
access: "create"
|
|
34885
|
+
},
|
|
34714
34886
|
"pipelineRunner.reportMotion": {
|
|
34715
34887
|
capName: "pipeline-runner",
|
|
34716
34888
|
capScope: "system",
|
|
@@ -37988,6 +38160,21 @@ Object.freeze({
|
|
|
37988
38160
|
form: "single",
|
|
37989
38161
|
optional: false
|
|
37990
38162
|
}],
|
|
38163
|
+
"pipelineRunner.getParkedTrackFrame": [{
|
|
38164
|
+
name: "deviceId",
|
|
38165
|
+
form: "single",
|
|
38166
|
+
optional: false
|
|
38167
|
+
}],
|
|
38168
|
+
"pipelineRunner.parkTrackFrame": [{
|
|
38169
|
+
name: "deviceId",
|
|
38170
|
+
form: "single",
|
|
38171
|
+
optional: false
|
|
38172
|
+
}],
|
|
38173
|
+
"pipelineRunner.releaseParkedTrackFrames": [{
|
|
38174
|
+
name: "deviceId",
|
|
38175
|
+
form: "single",
|
|
38176
|
+
optional: false
|
|
38177
|
+
}],
|
|
37991
38178
|
"pipelineRunner.reportMotion": [{
|
|
37992
38179
|
name: "deviceId",
|
|
37993
38180
|
form: "single",
|
|
@@ -38679,7 +38866,7 @@ var PreviewTextField = string().max(200);
|
|
|
38679
38866
|
* Whether the notification's preview is a STILL or a short animation.
|
|
38680
38867
|
*
|
|
38681
38868
|
* The operator's ask, verbatim: *"inviato come gif o video (come per le altre
|
|
38682
|
-
* rule)"* —
|
|
38869
|
+
* rule)"* — the other rules already offer an animated preview, and a ten-hour
|
|
38683
38870
|
* night reads better as three seconds of motion than as one frame of it. Both
|
|
38684
38871
|
* modes get the SAME treatment (blurred frame, large centred title); `'gif'`
|
|
38685
38872
|
* simply applies it to a dozen frames sampled across the render and assembles
|