@camstack/addon-provider-rademacher 0.2.6 → 0.2.7
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/addon.js +451 -76
- package/dist/addon.mjs +451 -76
- package/package.json +1 -1
package/dist/addon.js
CHANGED
|
@@ -984,7 +984,7 @@ var Rademacher = class {
|
|
|
984
984
|
}
|
|
985
985
|
};
|
|
986
986
|
//#endregion
|
|
987
|
-
//#region ../types/dist/event-category-
|
|
987
|
+
//#region ../types/dist/event-category-Bz24uP1U.mjs
|
|
988
988
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
989
989
|
EventCategory["SystemBoot"] = "system.boot";
|
|
990
990
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -1255,6 +1255,19 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
1255
1255
|
*/
|
|
1256
1256
|
EventCategory["DeviceStateChanged"] = "device.state-changed";
|
|
1257
1257
|
/**
|
|
1258
|
+
* Frame occupancy for a camera CHANGED — a tracked object was gained or
|
|
1259
|
+
* lost. Carries `{ deviceId, totalObjects, byClass, zones }`.
|
|
1260
|
+
*
|
|
1261
|
+
* Emitted only on a change, so a steady scene is silent. It exists so a
|
|
1262
|
+
* client can stop polling `zoneAnalytics.getCurrentSnapshot`: that was the
|
|
1263
|
+
* one live badge with no push signal at all, and it cost a request every
|
|
1264
|
+
* four seconds per visible camera.
|
|
1265
|
+
*
|
|
1266
|
+
* Like every event it is telemetry and may be dropped ([D8]) — a consumer
|
|
1267
|
+
* keeps a slow reconcile rather than trusting it alone.
|
|
1268
|
+
*/
|
|
1269
|
+
EventCategory["ZoneAnalyticsOccupancyChanged"] = "zone-analytics.occupancy-changed";
|
|
1270
|
+
/**
|
|
1258
1271
|
* Cap event fired by every device that registers the `battery`
|
|
1259
1272
|
* capability. Mirrors the cap definition's `onStatusChanged`. Carries
|
|
1260
1273
|
* `{ deviceId, status: BatteryStatus }`. Subscribers (alert center,
|
|
@@ -8198,35 +8211,22 @@ var ConvertResultSchema = object({
|
|
|
8198
8211
|
*/
|
|
8199
8212
|
var RecordingWeekdaySchema = number().int().min(0).max(6);
|
|
8200
8213
|
var HHMM = /^([01]\d|2[0-3]):[0-5]\d$/;
|
|
8201
|
-
var RecordingScheduleSchema = discriminatedUnion("kind", [object({ kind: literal("always") }), object({
|
|
8202
|
-
kind: literal("timeOfDay"),
|
|
8203
|
-
start: string().regex(HHMM),
|
|
8204
|
-
end: string().regex(HHMM),
|
|
8205
|
-
/** Restrict to these weekdays; omit = every day. */
|
|
8206
|
-
days: array(RecordingWeekdaySchema).optional()
|
|
8207
|
-
})]);
|
|
8208
|
-
var RecordingModeSchema = _enum([
|
|
8209
|
-
"continuous",
|
|
8210
|
-
"onMotion",
|
|
8211
|
-
"onAudioThreshold"
|
|
8212
|
-
]);
|
|
8213
8214
|
/**
|
|
8214
|
-
*
|
|
8215
|
-
*
|
|
8216
|
-
* - `off` —
|
|
8217
|
-
* - `events` —
|
|
8218
|
-
*
|
|
8219
|
-
* - `continuous` — record 24/7 within the schedule.
|
|
8215
|
+
* DERIVED per-camera storage summary — the single field cheap consumers read
|
|
8216
|
+
* (the viewer's status dot, the camera list) instead of walking `bands`:
|
|
8217
|
+
* - `off` — no band covers the camera (or it is disabled).
|
|
8218
|
+
* - `events` — every band records around triggers only.
|
|
8219
|
+
* - `continuous` — at least one band records continuously.
|
|
8220
8220
|
*
|
|
8221
|
-
*
|
|
8222
|
-
*
|
|
8221
|
+
* NEVER authored: the recorder stamps it from the authoritative `bands` on
|
|
8222
|
+
* every save (`activeModeForConfig`). Writing it has no effect.
|
|
8223
8223
|
*/
|
|
8224
8224
|
var RecordingStorageModeSchema = _enum([
|
|
8225
8225
|
"off",
|
|
8226
8226
|
"events",
|
|
8227
8227
|
"continuous"
|
|
8228
8228
|
]);
|
|
8229
|
-
/** Which detectors trigger an `events`-mode
|
|
8229
|
+
/** Which detectors trigger an `events`-mode band. */
|
|
8230
8230
|
var RecordingTriggersSchema = object({
|
|
8231
8231
|
motion: boolean().optional(),
|
|
8232
8232
|
audioThresholdDbfs: number().optional()
|
|
@@ -8262,18 +8262,6 @@ var RecordingBandSchema = object({
|
|
|
8262
8262
|
preBufferSec: number().min(0).optional(),
|
|
8263
8263
|
postBufferSec: number().min(0).optional()
|
|
8264
8264
|
});
|
|
8265
|
-
var RecordingRuleSchema = object({
|
|
8266
|
-
schedule: RecordingScheduleSchema,
|
|
8267
|
-
mode: RecordingModeSchema,
|
|
8268
|
-
/** Seconds of footage to retain BEFORE a trigger (applied at keep/discard). */
|
|
8269
|
-
preBufferSec: number().min(0).default(0),
|
|
8270
|
-
/** Keep recording until this many seconds after the last trigger. */
|
|
8271
|
-
postBufferSec: number().min(0).default(0),
|
|
8272
|
-
/** Each new trigger restarts the post-buffer window. */
|
|
8273
|
-
resetTimeoutOnNewEvent: boolean().default(true),
|
|
8274
|
-
/** onAudioThreshold only — dBFS level that counts as a trigger. */
|
|
8275
|
-
thresholdDbfs: number().optional()
|
|
8276
|
-
});
|
|
8277
8265
|
/**
|
|
8278
8266
|
* Per-device retention overrides. Every field is optional; an unset or `0`
|
|
8279
8267
|
* value inherits the node-wide recorder default. Only footage-lifetime limits
|
|
@@ -8307,40 +8295,28 @@ var ScrubThumbnailPresetSchema = _enum([
|
|
|
8307
8295
|
/**
|
|
8308
8296
|
* The full per-camera recording intent — the wire shape of a RecordingTarget.
|
|
8309
8297
|
*
|
|
8310
|
-
* `
|
|
8311
|
-
*
|
|
8312
|
-
*
|
|
8313
|
-
*
|
|
8298
|
+
* `bands` is the ONLY authored recording intent: what to record, when, and on
|
|
8299
|
+
* which trigger. `mode` is a derived summary the recorder stamps on save; every
|
|
8300
|
+
* other field is a storage knob (profiles, segment length, retention, scrub).
|
|
8301
|
+
*
|
|
8302
|
+
* STRICT on purpose: the legacy authoring surface (`schedule`/`schedules`/
|
|
8303
|
+
* `triggers`/`preBufferSec`/`postBufferSec`/`rules`) was retired 2026-07-30.
|
|
8304
|
+
* A stale caller must fail loudly — silently stripping its legacy intent would
|
|
8305
|
+
* persist a band-less config, i.e. silently stop recording the camera.
|
|
8314
8306
|
*/
|
|
8315
8307
|
var RecordingConfigSchema = object({
|
|
8316
8308
|
enabled: boolean(),
|
|
8317
|
-
/**
|
|
8318
|
-
*
|
|
8309
|
+
/** DERIVED summary of `bands`, stamped by the recorder on every save.
|
|
8310
|
+
* Authoring it has no effect — see {@link RecordingStorageModeSchema}. */
|
|
8319
8311
|
mode: RecordingStorageModeSchema.optional(),
|
|
8320
8312
|
profiles: array(CamProfileSchema).optional(),
|
|
8321
8313
|
segmentSeconds: number().int().positive().optional(),
|
|
8322
|
-
/** Shared recording time-bands for `events` & `continuous` — record only when
|
|
8323
|
-
* the wall-clock falls inside one of these windows. Omit or empty = always.
|
|
8324
|
-
* `continuous` compiles to one rule per band; `events` to band × trigger. */
|
|
8325
|
-
schedules: array(RecordingScheduleSchema).optional(),
|
|
8326
|
-
/** Legacy single-band predecessor of `schedules`. Read-compat only — it is
|
|
8327
|
-
* normalized into `schedules` on read and never written going forward. (Not
|
|
8328
|
-
* tagged `@deprecated`: the normalization paths must read it cast-free.) */
|
|
8329
|
-
schedule: RecordingScheduleSchema.optional(),
|
|
8330
|
-
/** `events`-mode only — which detectors trigger a recording. */
|
|
8331
|
-
triggers: RecordingTriggersSchema.optional(),
|
|
8332
|
-
/** `events`-mode only — seconds retained before / after a trigger. */
|
|
8333
|
-
preBufferSec: number().min(0).optional(),
|
|
8334
|
-
postBufferSec: number().min(0).optional(),
|
|
8335
|
-
/** DEPRECATED authoring input; retained for migration/transition. */
|
|
8336
|
-
rules: array(RecordingRuleSchema).optional(),
|
|
8337
8314
|
/**
|
|
8338
|
-
* AUTHORITATIVE mode-per-band recording model
|
|
8339
|
-
*
|
|
8340
|
-
*
|
|
8341
|
-
* derived into bands once via `migrateConfigToBands`.
|
|
8315
|
+
* AUTHORITATIVE mode-per-band recording model — the single source of truth
|
|
8316
|
+
* the recorder's band engine consumes. An empty array = record nothing;
|
|
8317
|
+
* "off" is the absence of a covering band, never a band value.
|
|
8342
8318
|
*/
|
|
8343
|
-
bands: array(RecordingBandSchema).
|
|
8319
|
+
bands: array(RecordingBandSchema).default([]),
|
|
8344
8320
|
retention: RecordingRetentionSchema.optional(),
|
|
8345
8321
|
/**
|
|
8346
8322
|
* Per-camera scrub-thumbnail fidelity preset (resolution + JPEG quality for
|
|
@@ -8348,8 +8324,15 @@ var RecordingConfigSchema = object({
|
|
|
8348
8324
|
* windows only — existing sheets are immutable, and each window's index
|
|
8349
8325
|
* carries its own tile dims so mixed-preset history renders correctly.
|
|
8350
8326
|
*/
|
|
8351
|
-
scrubThumbnails: ScrubThumbnailPresetSchema.optional()
|
|
8352
|
-
|
|
8327
|
+
scrubThumbnails: ScrubThumbnailPresetSchema.optional(),
|
|
8328
|
+
/**
|
|
8329
|
+
* OPT-IN thumbnail-strip generation for this camera: every keyframe of the
|
|
8330
|
+
* low recording saved as a JPEG (the fast-drag scrub depth), a derived
|
|
8331
|
+
* cache that eviction reclaims with the footage. Absent/false = no strips
|
|
8332
|
+
* are written and scrub reads exact keyframes at every velocity.
|
|
8333
|
+
*/
|
|
8334
|
+
stripsEnabled: boolean().optional()
|
|
8335
|
+
}).strict();
|
|
8353
8336
|
/**
|
|
8354
8337
|
* Ops-log — the durable, append-only operations audit shared by the
|
|
8355
8338
|
* recordings and events management surfaces.
|
|
@@ -8368,7 +8351,8 @@ var OpsLogOpSchema = _enum([
|
|
|
8368
8351
|
"prune",
|
|
8369
8352
|
"manual-delete",
|
|
8370
8353
|
"rescan",
|
|
8371
|
-
"retention-run"
|
|
8354
|
+
"retention-run",
|
|
8355
|
+
"relocate"
|
|
8372
8356
|
]);
|
|
8373
8357
|
/** Why the operation ran. */
|
|
8374
8358
|
var OpsLogReasonSchema = _enum([
|
|
@@ -8407,6 +8391,55 @@ var OpsLogQueryInputSchema = object({
|
|
|
8407
8391
|
limit: number().int().min(1).max(1e3).optional()
|
|
8408
8392
|
});
|
|
8409
8393
|
/**
|
|
8394
|
+
* Entity-relocation job state (storage entity-routing spec, Phase 4).
|
|
8395
|
+
*
|
|
8396
|
+
* One shape shared by the recorder's `relocateFootage` (segments + strips) and
|
|
8397
|
+
* pipeline-analytics' `relocateMedia` (event media blobs) so the admin Data
|
|
8398
|
+
* page renders both movers with one component. Jobs are in-RAM (a restart
|
|
8399
|
+
* forgets them — re-running is safe by construction: copy-if-absent, delete
|
|
8400
|
+
* after verify) and each completed/failed run also lands one durable ops-log
|
|
8401
|
+
* row on the owning addon's surface.
|
|
8402
|
+
*/
|
|
8403
|
+
var RelocateJobStateSchema = _enum([
|
|
8404
|
+
"running",
|
|
8405
|
+
"done",
|
|
8406
|
+
"failed",
|
|
8407
|
+
"cancelled"
|
|
8408
|
+
]);
|
|
8409
|
+
var RelocateJobSchema = object({
|
|
8410
|
+
jobId: string(),
|
|
8411
|
+
state: RelocateJobStateSchema,
|
|
8412
|
+
/** Source location — for media relocation this is informational ('*': rows
|
|
8413
|
+
* move from wherever they are to the target). */
|
|
8414
|
+
fromLocationId: string(),
|
|
8415
|
+
toLocationId: string(),
|
|
8416
|
+
/** Scoped device, or null = every device. */
|
|
8417
|
+
deviceId: number().nullable(),
|
|
8418
|
+
/** What the job moves (owner-addon specific: segments/strips or media). */
|
|
8419
|
+
entities: array(string()),
|
|
8420
|
+
filesMoved: number().int(),
|
|
8421
|
+
bytesMoved: number().int(),
|
|
8422
|
+
/** Total files discovered up front; null while (or when) unknown. */
|
|
8423
|
+
filesTotal: number().int().nullable(),
|
|
8424
|
+
startedAt: number(),
|
|
8425
|
+
finishedAt: number().nullable(),
|
|
8426
|
+
error: string().nullable()
|
|
8427
|
+
});
|
|
8428
|
+
var RelocateFootageInputSchema = object({
|
|
8429
|
+
deviceId: number().optional(),
|
|
8430
|
+
fromLocationId: string(),
|
|
8431
|
+
toLocationId: string(),
|
|
8432
|
+
entities: array(_enum(["segments", "strips"])).optional(),
|
|
8433
|
+
/** Copy throttle in MB/s (default 40) — the drain is a background chore,
|
|
8434
|
+
* never allowed to starve live writers. */
|
|
8435
|
+
throttleMbps: number().min(1).max(1e3).optional()
|
|
8436
|
+
});
|
|
8437
|
+
var RelocateMediaInputSchema = object({
|
|
8438
|
+
deviceId: number().optional(),
|
|
8439
|
+
toLocationId: string(),
|
|
8440
|
+
throttleMbps: number().min(1).max(1e3).optional()
|
|
8441
|
+
});
|
|
8442
|
+
/**
|
|
8410
8443
|
* `StorageLocationType` — an addon-declared id that identifies the *kind* of
|
|
8411
8444
|
* storage a location serves. Defined here (not in `capabilities/storage.cap.ts`)
|
|
8412
8445
|
* so the persisted record schema and the consumer-facing cap can both consume it
|
|
@@ -8456,6 +8489,13 @@ var StorageLocationSchema = object({
|
|
|
8456
8489
|
nodeId: string().optional(),
|
|
8457
8490
|
isDefault: boolean().default(false),
|
|
8458
8491
|
isSystem: boolean().default(false),
|
|
8492
|
+
/** COMPUTED at read time by the orchestrator (statfs of the backing volume
|
|
8493
|
+
* for node-local locations it can reach) — never persisted, absent when the
|
|
8494
|
+
* volume is remote/unreachable. The single capacity truth every UI reads. */
|
|
8495
|
+
capacity: object({
|
|
8496
|
+
totalBytes: number(),
|
|
8497
|
+
availableBytes: number()
|
|
8498
|
+
}).nullable().optional(),
|
|
8459
8499
|
createdAt: number(),
|
|
8460
8500
|
updatedAt: number()
|
|
8461
8501
|
});
|
|
@@ -9223,7 +9263,8 @@ var NcTaxonomyEntrySchema = object({
|
|
|
9223
9263
|
/** Macro/category parent for grouping ('car' → 'vehicle'); null for a top. */
|
|
9224
9264
|
parentKind: string().nullable()
|
|
9225
9265
|
});
|
|
9226
|
-
|
|
9266
|
+
/** The complete NC picker taxonomy — three grouped buckets. */
|
|
9267
|
+
var NcTaxonomySchema = object({
|
|
9227
9268
|
videoClasses: array(NcTaxonomyEntrySchema),
|
|
9228
9269
|
audioKinds: array(NcTaxonomyEntrySchema),
|
|
9229
9270
|
labels: array(NcTaxonomyEntrySchema)
|
|
@@ -10126,6 +10167,7 @@ function shallowEqual(a, b) {
|
|
|
10126
10167
|
for (const k of ak) if (a[k] !== b[k]) return false;
|
|
10127
10168
|
return true;
|
|
10128
10169
|
}
|
|
10170
|
+
new Set(["devices", "classes"]);
|
|
10129
10171
|
/**
|
|
10130
10172
|
* Shared geometry vocabulary for on-frame shape caps — privacy-mask,
|
|
10131
10173
|
* motion-zones, and the detection zones/lines editor all speak this one
|
|
@@ -10284,6 +10326,29 @@ var NcOccupancyConditionSchema = object({
|
|
|
10284
10326
|
count: number().int().min(0).default(1),
|
|
10285
10327
|
sustainSeconds: number().int().min(0).max(3600).default(15)
|
|
10286
10328
|
});
|
|
10329
|
+
/**
|
|
10330
|
+
* Which zone-crossing DIRECTION a rule accepts (`ObjectEvent.zoneCrossing`).
|
|
10331
|
+
*
|
|
10332
|
+
* The values are not symmetric, and deliberately so — the absent value has to
|
|
10333
|
+
* mean exactly what every rule authored before this condition existed already
|
|
10334
|
+
* does:
|
|
10335
|
+
* - `enter` — entries and every NON-crossing record (movement state,
|
|
10336
|
+
* package, sensor). Exits are rejected. **This is the absent behaviour**:
|
|
10337
|
+
* an operator who never asked for exits must not start receiving them.
|
|
10338
|
+
* - `exit` — ONLY an exit crossing. A record that is not a crossing at all
|
|
10339
|
+
* fails closed, because "the car left the drive" is a question about a
|
|
10340
|
+
* boundary, not about a detection.
|
|
10341
|
+
* - `any` — no direction filter; entries, exits and non-crossings alike.
|
|
10342
|
+
*
|
|
10343
|
+
* A rule asking for a direction should normally also scope `zones`, which the
|
|
10344
|
+
* engine evaluates against the crossed zone as well as the current membership
|
|
10345
|
+
* (an exit's membership no longer contains the zone it just left).
|
|
10346
|
+
*/
|
|
10347
|
+
var NcCrossingSchema = _enum([
|
|
10348
|
+
"enter",
|
|
10349
|
+
"exit",
|
|
10350
|
+
"any"
|
|
10351
|
+
]);
|
|
10287
10352
|
/** Admin-zone membership condition (zone IDs as stamped by the ZoneEngine). */
|
|
10288
10353
|
var NcZoneConditionSchema = object({
|
|
10289
10354
|
ids: array(string().min(1)).min(1),
|
|
@@ -10308,6 +10373,13 @@ var NcConditionsSchema = object({
|
|
|
10308
10373
|
/** Veto zones — any hit fails the rule. */
|
|
10309
10374
|
zonesExclude: array(string().min(1)).optional(),
|
|
10310
10375
|
/**
|
|
10376
|
+
* Zone-crossing direction. IMMEDIATE only — a crossing is a per-event fact
|
|
10377
|
+
* and a closed track carries none, so a `track-end` rule asking for one
|
|
10378
|
+
* fails closed (use `zones`, which tests `zonesVisited`). ABSENT = `enter`,
|
|
10379
|
+
* which is exactly today's behaviour. See {@link NcCrossingSchema}.
|
|
10380
|
+
*/
|
|
10381
|
+
crossing: NcCrossingSchema.optional(),
|
|
10382
|
+
/**
|
|
10311
10383
|
* Exact (case-insensitive) match on the record's collapsed `label`
|
|
10312
10384
|
* (identity name / plate text / subclass).
|
|
10313
10385
|
*/
|
|
@@ -10442,17 +10514,85 @@ var NcRuleTargetSchema = object({
|
|
|
10442
10514
|
* - `keyFrame` — the clean scene frame (no subject box).
|
|
10443
10515
|
* - `none` — no attachment.
|
|
10444
10516
|
*/
|
|
10445
|
-
|
|
10446
|
-
|
|
10447
|
-
|
|
10448
|
-
|
|
10449
|
-
|
|
10450
|
-
|
|
10517
|
+
/**
|
|
10518
|
+
* WHAT THE PICTURE SHOWS — chosen explicitly, because the implicit ladders
|
|
10519
|
+
* conflate it with the selection strategy and betray the request: asking for
|
|
10520
|
+
* the clean scene frame on an object-event owner used to start at
|
|
10521
|
+
* `fullFrameBoxed`, i.e. the annotated frame (2026-07-30).
|
|
10522
|
+
* - `cropped` — the subject, tight. What "who is at the door" wants.
|
|
10523
|
+
* - `full` — the clean scene, no annotation. What "what is going on" wants.
|
|
10524
|
+
* - `boxed` — the scene WITH the detection boxes drawn, for verifying what
|
|
10525
|
+
* the pipeline actually saw.
|
|
10526
|
+
*/
|
|
10527
|
+
var NcMediaFrameSchema = _enum([
|
|
10528
|
+
"cropped",
|
|
10529
|
+
"full",
|
|
10530
|
+
"boxed"
|
|
10531
|
+
]);
|
|
10532
|
+
var NcMediaPolicySchema = object({
|
|
10533
|
+
attach: _enum([
|
|
10534
|
+
"best",
|
|
10535
|
+
"best-matching",
|
|
10536
|
+
"keyFrame",
|
|
10537
|
+
"none"
|
|
10538
|
+
]).default("best"),
|
|
10539
|
+
/** What the still shows. Absent = `cropped` (the historical `best` shape). */
|
|
10540
|
+
frame: NcMediaFrameSchema.optional(),
|
|
10541
|
+
/** Crop the attached still to the rule's condition-zone bbox (padded) —
|
|
10542
|
+
* "show me the ZONE", not the whole scene or the subject crop. */
|
|
10543
|
+
zoneCrop: boolean().optional(),
|
|
10544
|
+
/**
|
|
10545
|
+
* Also attach a short GIF cut from the stream broker's clip ring around the
|
|
10546
|
+
* event — NOT from the recording, so the camera does not have to be
|
|
10547
|
+
* recording, and the window sits AROUND the moment instead of a segment
|
|
10548
|
+
* behind it. Fail-closed: a window the ring does not cover contributes no
|
|
10549
|
+
* gif, never a failed notification.
|
|
10550
|
+
*/
|
|
10551
|
+
gif: boolean().optional(),
|
|
10552
|
+
/**
|
|
10553
|
+
* Also attach a short MP4 CLIP of the same cut. Same source and the same
|
|
10554
|
+
* fail-closed rule as `gif`. Prefer it where the backend takes video
|
|
10555
|
+
* (telegram, discord, zentik, webhook); backends that do not are handled by
|
|
10556
|
+
* the degrade engine, which drops the video and keeps the still.
|
|
10557
|
+
*/
|
|
10558
|
+
clip: boolean().optional(),
|
|
10559
|
+
/** Seconds of footage BEFORE / AFTER the event instant. Defaults 3 / 7. */
|
|
10560
|
+
clipPreRollSec: number().int().min(0).max(30).optional(),
|
|
10561
|
+
clipPostRollSec: number().int().min(0).max(30).optional(),
|
|
10562
|
+
/**
|
|
10563
|
+
* Which stream profile the footage is cut from. Absent = the CHEAPEST
|
|
10564
|
+
* assigned profile: a notification is watched on a phone, so the 4K
|
|
10565
|
+
* rendition would burn CPU to produce a file the client downscales anyway.
|
|
10566
|
+
* A profile that is not assigned falls back to the cheapest, and the render
|
|
10567
|
+
* reports which one actually ran.
|
|
10568
|
+
*/
|
|
10569
|
+
profile: CamProfileSchema.optional()
|
|
10570
|
+
});
|
|
10571
|
+
/**
|
|
10572
|
+
* Cooldown GRANULARITY over the subject's class — how much a fired
|
|
10573
|
+
* notification suppresses.
|
|
10574
|
+
* - `shared` (default, and the absent value) — one window for the whole
|
|
10575
|
+
* rule/scope: a cat silences the next dog for `cooldownSec`.
|
|
10576
|
+
* - `per-class` — an independent window per detected class, so cat→dog fires
|
|
10577
|
+
* at once and cat→cat still waits.
|
|
10578
|
+
*
|
|
10579
|
+
* AUDIO subjects are ALWAYS per-class regardless of this setting: a scream
|
|
10580
|
+
* must not be swallowed by a bark's window (the precedent this generalizes —
|
|
10581
|
+
* see `cooldownKey` in the rule engine).
|
|
10582
|
+
*/
|
|
10583
|
+
var NcThrottleGranularitySchema = _enum(["shared", "per-class"]);
|
|
10451
10584
|
/** Throttle — cooldown survives restarts (rebuilt from the outbox on boot). */
|
|
10452
10585
|
var NcThrottleSchema = object({
|
|
10453
10586
|
cooldownSec: number().int().min(0).max(86400).default(60),
|
|
10454
10587
|
/** `rule` = one shared cooldown; `rule-device` = per-camera cooldown. */
|
|
10455
|
-
scope: _enum(["rule", "rule-device"]).default("rule-device")
|
|
10588
|
+
scope: _enum(["rule", "rule-device"]).default("rule-device"),
|
|
10589
|
+
/**
|
|
10590
|
+
* Class granularity of the cooldown key. Optional rather than defaulted:
|
|
10591
|
+
* a Zod default does NOT run on the addon→addon cap path, so a persisted
|
|
10592
|
+
* rule authored before this field simply carries none — and the engine
|
|
10593
|
+
* reads absent as `shared`, the pre-existing behaviour.
|
|
10594
|
+
*/
|
|
10595
|
+
granularity: NcThrottleGranularitySchema.optional()
|
|
10456
10596
|
});
|
|
10457
10597
|
/** Client-supplied rule fields (server stamps id/createdBy/createdAt/updatedAt). */
|
|
10458
10598
|
var NcRuleInputSchema = object({
|
|
@@ -10461,7 +10601,19 @@ var NcRuleInputSchema = object({
|
|
|
10461
10601
|
delivery: NcDeliverySchema,
|
|
10462
10602
|
conditions: NcConditionsSchema.default({}),
|
|
10463
10603
|
schedule: NcScheduleSchema.optional(),
|
|
10464
|
-
|
|
10604
|
+
/** May be empty when `targetUsers` addresses at least one user — the
|
|
10605
|
+
* "at least one addressee" invariant is enforced by the provider, because
|
|
10606
|
+
* a cross-field refine here would break `NcRulePatchSchema.partial()`. */
|
|
10607
|
+
targets: array(NcRuleTargetSchema),
|
|
10608
|
+
/**
|
|
10609
|
+
* USERS this rule addresses in addition to `targets` (Phase 4). At fire
|
|
10610
|
+
* time each user fans out to the personal targets they own
|
|
10611
|
+
* (`config.ownerUserId`), filtered by that user's `allowedDevices` for the
|
|
10612
|
+
* firing camera — a user is never notified about a device they cannot open.
|
|
10613
|
+
* Per-user opt-outs (`disabledTargetIds`) still apply to the fanned-out
|
|
10614
|
+
* targets.
|
|
10615
|
+
*/
|
|
10616
|
+
targetUsers: array(string()).optional(),
|
|
10465
10617
|
media: NcMediaPolicySchema.default({ attach: "best" }),
|
|
10466
10618
|
throttle: NcThrottleSchema.default({
|
|
10467
10619
|
cooldownSec: 60,
|
|
@@ -10548,6 +10700,7 @@ var NcConditionDescriptorSchema = object({
|
|
|
10548
10700
|
"schedule",
|
|
10549
10701
|
"plateMatcher",
|
|
10550
10702
|
"packagePhase",
|
|
10703
|
+
"crossingSelect",
|
|
10551
10704
|
"polygonDraw",
|
|
10552
10705
|
"occupancy"
|
|
10553
10706
|
]),
|
|
@@ -10674,7 +10827,10 @@ method(object({}), object({ rules: array(NcRuleSchema) }), { auth: "admin" }), m
|
|
|
10674
10827
|
}), object({ results: array(NcTestResultSchema) }), {
|
|
10675
10828
|
kind: "mutation",
|
|
10676
10829
|
auth: "admin"
|
|
10677
|
-
}), method(object({}), object({
|
|
10830
|
+
}), method(object({}), object({
|
|
10831
|
+
catalog: array(NcConditionDescriptorSchema),
|
|
10832
|
+
taxonomy: NcTaxonomySchema.optional()
|
|
10833
|
+
})), method(object({ filter: NcHistoryFilterSchema.default({ limit: 100 }) }), object({ entries: array(NcHistoryEntrySchema) }), { auth: "admin" });
|
|
10678
10834
|
/**
|
|
10679
10835
|
* TimelapseRule — the STANDALONE scheduled timelapse producer's rule model.
|
|
10680
10836
|
*
|
|
@@ -11683,6 +11839,28 @@ method(object({
|
|
|
11683
11839
|
}), object({ success: literal(true) }), {
|
|
11684
11840
|
kind: "mutation",
|
|
11685
11841
|
auth: "admin"
|
|
11842
|
+
}), method(object({
|
|
11843
|
+
deviceId: number(),
|
|
11844
|
+
/** Absent = the LOWEST assigned profile — a notification attachment is
|
|
11845
|
+
* watched on a phone, and the cheap rendition is the right default. */
|
|
11846
|
+
profile: CamProfileSchema.optional(),
|
|
11847
|
+
aroundMs: number(),
|
|
11848
|
+
preRollSec: number().min(0).max(20).default(3),
|
|
11849
|
+
postRollSec: number().min(0).max(20).default(5),
|
|
11850
|
+
format: _enum(["gif", "mp4"]).default("gif"),
|
|
11851
|
+
maxWidth: number().int().min(120).max(1920).default(480),
|
|
11852
|
+
/** GIF only — MP4 keeps the source cadence. */
|
|
11853
|
+
fps: number().int().min(1).max(15).default(5)
|
|
11854
|
+
}), object({
|
|
11855
|
+
base64: string(),
|
|
11856
|
+
mime: string(),
|
|
11857
|
+
bytes: number().int(),
|
|
11858
|
+
/** The profile actually rendered (what the default resolved to). */
|
|
11859
|
+
profile: CamProfileSchema,
|
|
11860
|
+
durationMs: number()
|
|
11861
|
+
}), {
|
|
11862
|
+
kind: "mutation",
|
|
11863
|
+
auth: "admin"
|
|
11686
11864
|
}), method(_void(), array(CameraStreamSchema).readonly()), method(_void(), array(ProfileSlotSchema).readonly()), method(object({ brokerId: string() }), BrokerStatsSchema), method(object({ brokerId: string() }), object({
|
|
11687
11865
|
probed: boolean(),
|
|
11688
11866
|
summary: string()
|
|
@@ -19745,7 +19923,10 @@ method(object({
|
|
|
19745
19923
|
}), method(object({
|
|
19746
19924
|
deviceId: number(),
|
|
19747
19925
|
caps: array(string()).readonly().optional()
|
|
19748
|
-
}), record(string(), unknown().nullable()))
|
|
19926
|
+
}), record(string(), unknown().nullable())), method(object({
|
|
19927
|
+
deviceIds: array(number()).readonly(),
|
|
19928
|
+
caps: array(string()).readonly().optional()
|
|
19929
|
+
}), record(string(), record(string(), unknown().nullable())));
|
|
19749
19930
|
method(object({ deviceId: number() }), record(string(), record(string(), unknown()))), method(object({
|
|
19750
19931
|
deviceId: number(),
|
|
19751
19932
|
capName: string()
|
|
@@ -20676,6 +20857,36 @@ var TargetKindSchema = object({
|
|
|
20676
20857
|
icon: string(),
|
|
20677
20858
|
/** Stamped by each provider so the concat-fanned catalog stays routable. */
|
|
20678
20859
|
addonId: string(),
|
|
20860
|
+
/**
|
|
20861
|
+
* URL of the kind's bundled BRAND icon, served by the providing addon over
|
|
20862
|
+
* its own `addon-routes` surface (`/addon/<addonId>/icons/<kind>`). Absent
|
|
20863
|
+
* when the addon bundles no icon for that kind — the client then falls back
|
|
20864
|
+
* to a neutral glyph rather than rendering the raw `icon` NAME as text.
|
|
20865
|
+
*
|
|
20866
|
+
* Root-relative on purpose: it resolves against whatever origin serves a web
|
|
20867
|
+
* client, and a native client joins it onto its own hub base.
|
|
20868
|
+
*
|
|
20869
|
+
* DECLARED here deliberately. It used to travel as an undeclared passthrough
|
|
20870
|
+
* field that survived only because the runtime cap-router forwards provider
|
|
20871
|
+
* output verbatim — so every consumer had to re-declare it by hand to stop
|
|
20872
|
+
* its own Zod parse from stripping it, and the whole arrangement would have
|
|
20873
|
+
* broken silently the moment output validation was tightened anywhere.
|
|
20874
|
+
*/
|
|
20875
|
+
iconUrl: string().optional(),
|
|
20876
|
+
/**
|
|
20877
|
+
* Media type of {@link iconUrl} (`image/svg+xml`, `image/png`, …).
|
|
20878
|
+
*
|
|
20879
|
+
* The server knows this and therefore says it, because the client cannot
|
|
20880
|
+
* safely guess: a React-Native client renders SVG and raster through two
|
|
20881
|
+
* DIFFERENT components (`react-native-svg` vs `expo-image` — expo-image does
|
|
20882
|
+
* not decode SVG on iOS/Android), so without this it silently fell back to a
|
|
20883
|
+
* placeholder glyph for every vector icon while the web build looked fine.
|
|
20884
|
+
*
|
|
20885
|
+
* Absent when {@link iconUrl} is absent, or for a legacy provider that has
|
|
20886
|
+
* not been updated — a client that cannot determine the type should prefer
|
|
20887
|
+
* its raster path, which is the safe default for an unknown image.
|
|
20888
|
+
*/
|
|
20889
|
+
iconMediaType: string().optional(),
|
|
20679
20890
|
configSchema: ConfigSchemaPassthrough,
|
|
20680
20891
|
supportsDiscovery: boolean(),
|
|
20681
20892
|
caps: TargetKindCapsSchema
|
|
@@ -21123,6 +21334,29 @@ var MotionEventSchema = object({
|
|
|
21123
21334
|
* Absent on legacy rows ⇒ treat as `pipeline`.
|
|
21124
21335
|
*/
|
|
21125
21336
|
var DetectionSourceSchema = _enum(["pipeline", "onboard"]);
|
|
21337
|
+
/**
|
|
21338
|
+
* The confirmed zone crossing that produced an object event. Present ONLY on
|
|
21339
|
+
* an event emitted BY a crossing (`zone.enter` / `zone.exit`); a movement-state
|
|
21340
|
+
* event (`object.entering` / `leaving` / `stationary` / `loitering`) and an
|
|
21341
|
+
* appearance event carry none, so a rule asking for a direction fails closed
|
|
21342
|
+
* on them.
|
|
21343
|
+
*
|
|
21344
|
+
* Exactly ONE crossing per event: the emitter turns each confirmed crossing
|
|
21345
|
+
* into its own event, so a frame in which a track enters A while leaving B
|
|
21346
|
+
* produces two events with two directions — never one ambiguous row.
|
|
21347
|
+
*
|
|
21348
|
+
* `zoneId` is load-bearing for an EXIT: the event's `zones` list is the
|
|
21349
|
+
* membership the box has NOW, and by definition it no longer contains the zone
|
|
21350
|
+
* that was just left. Without the id here, a zone-scoped rule could never match
|
|
21351
|
+
* the exit it asked for.
|
|
21352
|
+
*/
|
|
21353
|
+
var ZoneCrossingSchema = object({
|
|
21354
|
+
direction: _enum(["enter", "exit"]),
|
|
21355
|
+
/** Admin zone id crossed. */
|
|
21356
|
+
zoneId: string(),
|
|
21357
|
+
/** Zone display name at crossing time (falls back to the id). */
|
|
21358
|
+
zoneName: string().optional()
|
|
21359
|
+
});
|
|
21126
21360
|
var ObjectEventSchema = object({
|
|
21127
21361
|
...BaseEventFields,
|
|
21128
21362
|
kind: literal("object"),
|
|
@@ -21149,6 +21383,12 @@ var ObjectEventSchema = object({
|
|
|
21149
21383
|
zones: array(string()).readonly().optional(),
|
|
21150
21384
|
/** Omitted in slim projection. */
|
|
21151
21385
|
state: TrackStateSchema.optional(),
|
|
21386
|
+
/**
|
|
21387
|
+
* The zone crossing this event IS, when it is one. Absent on every other
|
|
21388
|
+
* event kind (movement state, appearance, package) — see
|
|
21389
|
+
* {@link ZoneCrossingSchema}. Omitted in slim projection.
|
|
21390
|
+
*/
|
|
21391
|
+
zoneCrossing: ZoneCrossingSchema.optional(),
|
|
21152
21392
|
/** Detection-frame dimensions in pixels — let consumers normalize the
|
|
21153
21393
|
* pixel-space `bbox` onto a displayed image. Omitted in slim projection. */
|
|
21154
21394
|
frameWidth: number().optional(),
|
|
@@ -21407,6 +21647,15 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
21407
21647
|
}), method(object({ deviceId: number() }), EventPruneCountsSchema, {
|
|
21408
21648
|
kind: "mutation",
|
|
21409
21649
|
auth: "admin"
|
|
21650
|
+
}), method(RelocateMediaInputSchema, object({ jobId: string() }), {
|
|
21651
|
+
kind: "mutation",
|
|
21652
|
+
auth: "admin"
|
|
21653
|
+
}), method(object({}), array(RelocateJobSchema).readonly(), {
|
|
21654
|
+
kind: "query",
|
|
21655
|
+
auth: "admin"
|
|
21656
|
+
}), method(object({ jobId: string() }), object({ cancelled: boolean() }), {
|
|
21657
|
+
kind: "mutation",
|
|
21658
|
+
auth: "admin"
|
|
21410
21659
|
}), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
|
|
21411
21660
|
kind: "query",
|
|
21412
21661
|
auth: "admin"
|
|
@@ -23886,6 +24135,17 @@ var GetConnectionEndpointsResultSchema = object({ endpoints: array(object({
|
|
|
23886
24135
|
*/
|
|
23887
24136
|
priority: number()
|
|
23888
24137
|
})).readonly() });
|
|
24138
|
+
/**
|
|
24139
|
+
* The chosen outbound endpoint for notification artifacts. `baseUrl: null` =
|
|
24140
|
+
* AUTO (resolved from the candidate ranking at send time); `resolved` reports
|
|
24141
|
+
* what AUTO currently picks, so the UI can show the effective value either way.
|
|
24142
|
+
*/
|
|
24143
|
+
var NotificationEndpointSchema = object({
|
|
24144
|
+
/** The operator's explicit choice, or null for AUTO. */
|
|
24145
|
+
baseUrl: string().nullable(),
|
|
24146
|
+
/** What the ranking currently resolves to (null when nothing is reachable). */
|
|
24147
|
+
resolved: string().nullable()
|
|
24148
|
+
});
|
|
23889
24149
|
var AllowedAddressesSchema = object({
|
|
23890
24150
|
/**
|
|
23891
24151
|
* Allowlist of interface addresses operators have explicitly opted
|
|
@@ -23908,7 +24168,7 @@ method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(obje
|
|
|
23908
24168
|
* to avoid mixed-content blocks in the browser. The public
|
|
23909
24169
|
* tunnel always emits `https://` regardless. */
|
|
23910
24170
|
scheme: _enum(["http", "https"]).optional()
|
|
23911
|
-
}), GetConnectionEndpointsResultSchema), method(_void(), AllowedAddressesSchema), method(AllowedAddressesSchema, object({ success: literal(true) }), { kind: "mutation" }), method(_void(), AllowedAddressesSchema, { kind: "mutation" });
|
|
24171
|
+
}), GetConnectionEndpointsResultSchema), method(_void(), NotificationEndpointSchema), method(object({ baseUrl: string().nullable() }), NotificationEndpointSchema, { kind: "mutation" }), method(_void(), AllowedAddressesSchema), method(AllowedAddressesSchema, object({ success: literal(true) }), { kind: "mutation" }), method(_void(), AllowedAddressesSchema, { kind: "mutation" });
|
|
23912
24172
|
/**
|
|
23913
24173
|
* mesh-network — collection cap for mesh-VPN providers.
|
|
23914
24174
|
*
|
|
@@ -24707,7 +24967,12 @@ var RecordingDeviceUsageSchema = object({
|
|
|
24707
24967
|
var RecordingLocationUsageSchema = object({
|
|
24708
24968
|
/** StorageLocation id; null for the legacy/degraded single-root fallback. */
|
|
24709
24969
|
locationId: string().nullable(),
|
|
24710
|
-
/**
|
|
24970
|
+
/** Every location id sharing this row's PHYSICAL volume (aliases). One row
|
|
24971
|
+
* is emitted per physical disk (2026-07-29): two locations on one root
|
|
24972
|
+
* previously rendered as two identical "disks" with a nonsensical used
|
|
24973
|
+
* split — hydrate attribution across aliases is arbitrary by nature. */
|
|
24974
|
+
locationIds: array(string()).optional(),
|
|
24975
|
+
/** Bytes of recordings stored on this PHYSICAL volume (all aliases). */
|
|
24711
24976
|
usedBytes: number(),
|
|
24712
24977
|
/** Free bytes on the location's volume; null when capacity is unknown (remote). */
|
|
24713
24978
|
availableBytes: number().nullable(),
|
|
@@ -24819,6 +25084,44 @@ method(object({
|
|
|
24819
25084
|
}), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
|
|
24820
25085
|
kind: "query",
|
|
24821
25086
|
auth: "admin"
|
|
25087
|
+
}), method(object({
|
|
25088
|
+
deviceId: number(),
|
|
25089
|
+
aroundMs: number(),
|
|
25090
|
+
preRollSec: number().min(0).max(30).default(2),
|
|
25091
|
+
postRollSec: number().min(0).max(30).default(5),
|
|
25092
|
+
maxWidth: number().int().min(120).max(1280).default(480),
|
|
25093
|
+
fps: number().int().min(1).max(15).default(5)
|
|
25094
|
+
}), object({
|
|
25095
|
+
gifBase64: string(),
|
|
25096
|
+
fromMs: number(),
|
|
25097
|
+
toMs: number()
|
|
25098
|
+
}), {
|
|
25099
|
+
kind: "mutation",
|
|
25100
|
+
auth: "admin"
|
|
25101
|
+
}), method(object({
|
|
25102
|
+
deviceId: number(),
|
|
25103
|
+
aroundMs: number(),
|
|
25104
|
+
preRollSec: number().min(0).max(30).default(3),
|
|
25105
|
+
postRollSec: number().min(0).max(30).default(7),
|
|
25106
|
+
maxWidth: number().int().min(160).max(1920).default(640)
|
|
25107
|
+
}), object({
|
|
25108
|
+
clipBase64: string(),
|
|
25109
|
+
mime: string(),
|
|
25110
|
+
fromMs: number(),
|
|
25111
|
+
toMs: number(),
|
|
25112
|
+
bytes: number().int()
|
|
25113
|
+
}), {
|
|
25114
|
+
kind: "mutation",
|
|
25115
|
+
auth: "admin"
|
|
25116
|
+
}), method(RelocateFootageInputSchema, object({ jobId: string() }), {
|
|
25117
|
+
kind: "mutation",
|
|
25118
|
+
auth: "admin"
|
|
25119
|
+
}), method(object({}), array(RelocateJobSchema).readonly(), {
|
|
25120
|
+
kind: "query",
|
|
25121
|
+
auth: "admin"
|
|
25122
|
+
}), method(object({ jobId: string() }), object({ cancelled: boolean() }), {
|
|
25123
|
+
kind: "mutation",
|
|
25124
|
+
auth: "admin"
|
|
24822
25125
|
});
|
|
24823
25126
|
/**
|
|
24824
25127
|
* `recordingExport` cap — render a footage time range into a single downloadable
|
|
@@ -26410,6 +26713,12 @@ Object.freeze({
|
|
|
26410
26713
|
addonId: null,
|
|
26411
26714
|
access: "view"
|
|
26412
26715
|
},
|
|
26716
|
+
"deviceManager.getDeviceStatusAggregateBatch": {
|
|
26717
|
+
capName: "device-manager",
|
|
26718
|
+
capScope: "system",
|
|
26719
|
+
addonId: null,
|
|
26720
|
+
access: "view"
|
|
26721
|
+
},
|
|
26413
26722
|
"deviceManager.getLinkedDevices": {
|
|
26414
26723
|
capName: "device-manager",
|
|
26415
26724
|
capScope: "system",
|
|
@@ -27304,6 +27613,12 @@ Object.freeze({
|
|
|
27304
27613
|
addonId: null,
|
|
27305
27614
|
access: "view"
|
|
27306
27615
|
},
|
|
27616
|
+
"localNetwork.getNotificationEndpoint": {
|
|
27617
|
+
capName: "local-network",
|
|
27618
|
+
capScope: "system",
|
|
27619
|
+
addonId: null,
|
|
27620
|
+
access: "view"
|
|
27621
|
+
},
|
|
27307
27622
|
"localNetwork.getPreferred": {
|
|
27308
27623
|
capName: "local-network",
|
|
27309
27624
|
capScope: "system",
|
|
@@ -27328,6 +27643,12 @@ Object.freeze({
|
|
|
27328
27643
|
addonId: null,
|
|
27329
27644
|
access: "create"
|
|
27330
27645
|
},
|
|
27646
|
+
"localNetwork.setNotificationEndpoint": {
|
|
27647
|
+
capName: "local-network",
|
|
27648
|
+
capScope: "system",
|
|
27649
|
+
addonId: null,
|
|
27650
|
+
access: "create"
|
|
27651
|
+
},
|
|
27331
27652
|
"lockControl.lock": {
|
|
27332
27653
|
capName: "lock-control",
|
|
27333
27654
|
capScope: "device",
|
|
@@ -27970,6 +28291,12 @@ Object.freeze({
|
|
|
27970
28291
|
addonId: null,
|
|
27971
28292
|
access: "create"
|
|
27972
28293
|
},
|
|
28294
|
+
"pipelineAnalytics.cancelMediaRelocate": {
|
|
28295
|
+
capName: "pipeline-analytics",
|
|
28296
|
+
capScope: "device",
|
|
28297
|
+
addonId: null,
|
|
28298
|
+
access: "create"
|
|
28299
|
+
},
|
|
27973
28300
|
"pipelineAnalytics.clearTracks": {
|
|
27974
28301
|
capName: "pipeline-analytics",
|
|
27975
28302
|
capScope: "device",
|
|
@@ -28024,6 +28351,12 @@ Object.freeze({
|
|
|
28024
28351
|
addonId: null,
|
|
28025
28352
|
access: "view"
|
|
28026
28353
|
},
|
|
28354
|
+
"pipelineAnalytics.getMediaRelocateStatus": {
|
|
28355
|
+
capName: "pipeline-analytics",
|
|
28356
|
+
capScope: "device",
|
|
28357
|
+
addonId: null,
|
|
28358
|
+
access: "view"
|
|
28359
|
+
},
|
|
28027
28360
|
"pipelineAnalytics.getMotionEvents": {
|
|
28028
28361
|
capName: "pipeline-analytics",
|
|
28029
28362
|
capScope: "device",
|
|
@@ -28096,6 +28429,12 @@ Object.freeze({
|
|
|
28096
28429
|
addonId: null,
|
|
28097
28430
|
access: "create"
|
|
28098
28431
|
},
|
|
28432
|
+
"pipelineAnalytics.relocateMedia": {
|
|
28433
|
+
capName: "pipeline-analytics",
|
|
28434
|
+
capScope: "device",
|
|
28435
|
+
addonId: null,
|
|
28436
|
+
access: "create"
|
|
28437
|
+
},
|
|
28099
28438
|
"pipelineAnalytics.searchObjectEvents": {
|
|
28100
28439
|
capName: "pipeline-analytics",
|
|
28101
28440
|
capScope: "device",
|
|
@@ -28858,6 +29197,12 @@ Object.freeze({
|
|
|
28858
29197
|
addonId: null,
|
|
28859
29198
|
access: "create"
|
|
28860
29199
|
},
|
|
29200
|
+
"recording.cancelRelocate": {
|
|
29201
|
+
capName: "recording",
|
|
29202
|
+
capScope: "system",
|
|
29203
|
+
addonId: null,
|
|
29204
|
+
access: "create"
|
|
29205
|
+
},
|
|
28861
29206
|
"recording.deleteFootprint": {
|
|
28862
29207
|
capName: "recording",
|
|
28863
29208
|
capScope: "system",
|
|
@@ -28888,6 +29233,12 @@ Object.freeze({
|
|
|
28888
29233
|
addonId: null,
|
|
28889
29234
|
access: "view"
|
|
28890
29235
|
},
|
|
29236
|
+
"recording.getRelocateStatus": {
|
|
29237
|
+
capName: "recording",
|
|
29238
|
+
capScope: "system",
|
|
29239
|
+
addonId: null,
|
|
29240
|
+
access: "view"
|
|
29241
|
+
},
|
|
28891
29242
|
"recording.getStorageUsage": {
|
|
28892
29243
|
capName: "recording",
|
|
28893
29244
|
capScope: "system",
|
|
@@ -28918,6 +29269,24 @@ Object.freeze({
|
|
|
28918
29269
|
addonId: null,
|
|
28919
29270
|
access: "view"
|
|
28920
29271
|
},
|
|
29272
|
+
"recording.relocateFootage": {
|
|
29273
|
+
capName: "recording",
|
|
29274
|
+
capScope: "system",
|
|
29275
|
+
addonId: null,
|
|
29276
|
+
access: "create"
|
|
29277
|
+
},
|
|
29278
|
+
"recording.renderClip": {
|
|
29279
|
+
capName: "recording",
|
|
29280
|
+
capScope: "system",
|
|
29281
|
+
addonId: null,
|
|
29282
|
+
access: "create"
|
|
29283
|
+
},
|
|
29284
|
+
"recording.renderGif": {
|
|
29285
|
+
capName: "recording",
|
|
29286
|
+
capScope: "system",
|
|
29287
|
+
addonId: null,
|
|
29288
|
+
access: "create"
|
|
29289
|
+
},
|
|
28921
29290
|
"recording.rescanStorage": {
|
|
28922
29291
|
capName: "recording",
|
|
28923
29292
|
capScope: "system",
|
|
@@ -29512,6 +29881,12 @@ Object.freeze({
|
|
|
29512
29881
|
addonId: null,
|
|
29513
29882
|
access: "create"
|
|
29514
29883
|
},
|
|
29884
|
+
"streamBroker.renderPreBufferClip": {
|
|
29885
|
+
capName: "stream-broker",
|
|
29886
|
+
capScope: "system",
|
|
29887
|
+
addonId: null,
|
|
29888
|
+
access: "create"
|
|
29889
|
+
},
|
|
29515
29890
|
"streamBroker.restartProfile": {
|
|
29516
29891
|
capName: "stream-broker",
|
|
29517
29892
|
capScope: "system",
|