@camstack/addon-pipeline 1.2.19 → 1.2.28
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/audio-analyzer/index.js +1 -1
- package/dist/audio-analyzer/index.mjs +3 -2
- package/dist/chunk-DnnnRqeS.mjs +26 -0
- package/dist/detection-pipeline/index.js +2 -2
- package/dist/detection-pipeline/index.mjs +4 -3
- package/dist/{dist-DZBePRjP.mjs → dist-CsKaXmP8.mjs} +415 -126
- package/dist/{dist-DKqOqH5j.js → dist-DUHlZcWd.js} +420 -131
- package/dist/{model-download-service-Cp9f4dk6-WO-foD7W.mjs → model-download-service-Cp9f4dk6-CwUb5v3Y.mjs} +1 -26
- package/dist/motion-wasm/index.js +1 -1
- package/dist/motion-wasm/index.mjs +1 -1
- package/dist/pipeline-runner/index.js +230 -28
- package/dist/pipeline-runner/index.mjs +230 -28
- package/dist/recorder/index.js +2604 -458
- package/dist/recorder/index.mjs +2599 -459
- package/dist/{step-definitions-zDq8cP8M.js → step-definitions-Bo1hJQQw.js} +1 -1
- package/dist/{step-definitions-BwB6TBMB.mjs → step-definitions-C8A78dBi.mjs} +1 -1
- package/dist/stream-broker/_stub.js +2 -2
- package/dist/stream-broker/{_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-Bwuv7iK_.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-tHahN-lK.mjs} +2 -2
- package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-D1zJmtUe.mjs +26 -0
- package/dist/stream-broker/{_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-DfnRAN5T.mjs → _virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-CSWUWZ8c.mjs} +1 -1
- package/dist/stream-broker/{hostInit-DC0aArn1.mjs → hostInit-CIwilJUZ.mjs} +2 -2
- package/dist/stream-broker/index.js +7374 -250
- package/dist/stream-broker/index.mjs +7371 -249
- package/dist/stream-broker/remoteEntry.js +1 -1
- package/embed-dist/assets/{MaskShapeCanvas-DI4BY7W2-C2hbIwzB.js → MaskShapeCanvas-DI4BY7W2-B7VdNJlO.js} +1 -1
- package/embed-dist/assets/{MotionZonesSettings-NcxxQN8r-BpJ-foJW.js → MotionZonesSettings-NcxxQN8r-YyB4uLdH.js} +1 -1
- package/embed-dist/assets/{PrivacyMaskSettings-APgPLF7p-BjLs9Z3w.js → PrivacyMaskSettings-APgPLF7p-DfqixEad.js} +1 -1
- package/embed-dist/assets/{index-Dv5H-32C.css → index-CAe6Dg-X.css} +1 -1
- package/embed-dist/assets/index-zVLLVdIS.js +343 -0
- package/embed-dist/index.html +2 -2
- package/package.json +5 -1
- package/dist/fmp4-keyframes-5s8T9Mng.js +0 -6711
- package/dist/fmp4-keyframes-CV0X1mGy.mjs +0 -6694
- package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-BDeEvhV5.mjs +0 -26
- package/embed-dist/assets/index-_BRQTmdE.js +0 -116
|
@@ -7371,35 +7371,22 @@ var EVENT_PAD_MS = {
|
|
|
7371
7371
|
*/
|
|
7372
7372
|
var RecordingWeekdaySchema = number().int().min(0).max(6);
|
|
7373
7373
|
var HHMM = /^([01]\d|2[0-3]):[0-5]\d$/;
|
|
7374
|
-
var RecordingScheduleSchema = discriminatedUnion("kind", [object({ kind: literal("always") }), object({
|
|
7375
|
-
kind: literal("timeOfDay"),
|
|
7376
|
-
start: string().regex(HHMM),
|
|
7377
|
-
end: string().regex(HHMM),
|
|
7378
|
-
/** Restrict to these weekdays; omit = every day. */
|
|
7379
|
-
days: array(RecordingWeekdaySchema).optional()
|
|
7380
|
-
})]);
|
|
7381
|
-
var RecordingModeSchema = _enum([
|
|
7382
|
-
"continuous",
|
|
7383
|
-
"onMotion",
|
|
7384
|
-
"onAudioThreshold"
|
|
7385
|
-
]);
|
|
7386
7374
|
/**
|
|
7387
|
-
*
|
|
7388
|
-
*
|
|
7389
|
-
* - `off` —
|
|
7390
|
-
* - `events` —
|
|
7391
|
-
*
|
|
7392
|
-
* - `continuous` — record 24/7 within the schedule.
|
|
7375
|
+
* DERIVED per-camera storage summary — the single field cheap consumers read
|
|
7376
|
+
* (the viewer's status dot, the camera list) instead of walking `bands`:
|
|
7377
|
+
* - `off` — no band covers the camera (or it is disabled).
|
|
7378
|
+
* - `events` — every band records around triggers only.
|
|
7379
|
+
* - `continuous` — at least one band records continuously.
|
|
7393
7380
|
*
|
|
7394
|
-
*
|
|
7395
|
-
*
|
|
7381
|
+
* NEVER authored: the recorder stamps it from the authoritative `bands` on
|
|
7382
|
+
* every save (`activeModeForConfig`). Writing it has no effect.
|
|
7396
7383
|
*/
|
|
7397
7384
|
var RecordingStorageModeSchema = _enum([
|
|
7398
7385
|
"off",
|
|
7399
7386
|
"events",
|
|
7400
7387
|
"continuous"
|
|
7401
7388
|
]);
|
|
7402
|
-
/** Which detectors trigger an `events`-mode
|
|
7389
|
+
/** Which detectors trigger an `events`-mode band. */
|
|
7403
7390
|
var RecordingTriggersSchema = object({
|
|
7404
7391
|
motion: boolean().optional(),
|
|
7405
7392
|
audioThresholdDbfs: number().optional()
|
|
@@ -7435,18 +7422,6 @@ var RecordingBandSchema = object({
|
|
|
7435
7422
|
preBufferSec: number().min(0).optional(),
|
|
7436
7423
|
postBufferSec: number().min(0).optional()
|
|
7437
7424
|
});
|
|
7438
|
-
var RecordingRuleSchema = object({
|
|
7439
|
-
schedule: RecordingScheduleSchema,
|
|
7440
|
-
mode: RecordingModeSchema,
|
|
7441
|
-
/** Seconds of footage to retain BEFORE a trigger (applied at keep/discard). */
|
|
7442
|
-
preBufferSec: number().min(0).default(0),
|
|
7443
|
-
/** Keep recording until this many seconds after the last trigger. */
|
|
7444
|
-
postBufferSec: number().min(0).default(0),
|
|
7445
|
-
/** Each new trigger restarts the post-buffer window. */
|
|
7446
|
-
resetTimeoutOnNewEvent: boolean().default(true),
|
|
7447
|
-
/** onAudioThreshold only — dBFS level that counts as a trigger. */
|
|
7448
|
-
thresholdDbfs: number().optional()
|
|
7449
|
-
});
|
|
7450
7425
|
/**
|
|
7451
7426
|
* Per-device retention overrides. Every field is optional; an unset or `0`
|
|
7452
7427
|
* value inherits the node-wide recorder default. Only footage-lifetime limits
|
|
@@ -7480,40 +7455,28 @@ var ScrubThumbnailPresetSchema = _enum([
|
|
|
7480
7455
|
/**
|
|
7481
7456
|
* The full per-camera recording intent — the wire shape of a RecordingTarget.
|
|
7482
7457
|
*
|
|
7483
|
-
* `
|
|
7484
|
-
*
|
|
7485
|
-
*
|
|
7486
|
-
*
|
|
7458
|
+
* `bands` is the ONLY authored recording intent: what to record, when, and on
|
|
7459
|
+
* which trigger. `mode` is a derived summary the recorder stamps on save; every
|
|
7460
|
+
* other field is a storage knob (profiles, segment length, retention, scrub).
|
|
7461
|
+
*
|
|
7462
|
+
* STRICT on purpose: the legacy authoring surface (`schedule`/`schedules`/
|
|
7463
|
+
* `triggers`/`preBufferSec`/`postBufferSec`/`rules`) was retired 2026-07-30.
|
|
7464
|
+
* A stale caller must fail loudly — silently stripping its legacy intent would
|
|
7465
|
+
* persist a band-less config, i.e. silently stop recording the camera.
|
|
7487
7466
|
*/
|
|
7488
7467
|
var RecordingConfigSchema = object({
|
|
7489
7468
|
enabled: boolean(),
|
|
7490
|
-
/**
|
|
7491
|
-
*
|
|
7469
|
+
/** DERIVED summary of `bands`, stamped by the recorder on every save.
|
|
7470
|
+
* Authoring it has no effect — see {@link RecordingStorageModeSchema}. */
|
|
7492
7471
|
mode: RecordingStorageModeSchema.optional(),
|
|
7493
7472
|
profiles: array(CamProfileSchema).optional(),
|
|
7494
7473
|
segmentSeconds: number().int().positive().optional(),
|
|
7495
|
-
/** Shared recording time-bands for `events` & `continuous` — record only when
|
|
7496
|
-
* the wall-clock falls inside one of these windows. Omit or empty = always.
|
|
7497
|
-
* `continuous` compiles to one rule per band; `events` to band × trigger. */
|
|
7498
|
-
schedules: array(RecordingScheduleSchema).optional(),
|
|
7499
|
-
/** Legacy single-band predecessor of `schedules`. Read-compat only — it is
|
|
7500
|
-
* normalized into `schedules` on read and never written going forward. (Not
|
|
7501
|
-
* tagged `@deprecated`: the normalization paths must read it cast-free.) */
|
|
7502
|
-
schedule: RecordingScheduleSchema.optional(),
|
|
7503
|
-
/** `events`-mode only — which detectors trigger a recording. */
|
|
7504
|
-
triggers: RecordingTriggersSchema.optional(),
|
|
7505
|
-
/** `events`-mode only — seconds retained before / after a trigger. */
|
|
7506
|
-
preBufferSec: number().min(0).optional(),
|
|
7507
|
-
postBufferSec: number().min(0).optional(),
|
|
7508
|
-
/** DEPRECATED authoring input; retained for migration/transition. */
|
|
7509
|
-
rules: array(RecordingRuleSchema).optional(),
|
|
7510
7474
|
/**
|
|
7511
|
-
* AUTHORITATIVE mode-per-band recording model
|
|
7512
|
-
*
|
|
7513
|
-
*
|
|
7514
|
-
* derived into bands once via `migrateConfigToBands`.
|
|
7475
|
+
* AUTHORITATIVE mode-per-band recording model — the single source of truth
|
|
7476
|
+
* the recorder's band engine consumes. An empty array = record nothing;
|
|
7477
|
+
* "off" is the absence of a covering band, never a band value.
|
|
7515
7478
|
*/
|
|
7516
|
-
bands: array(RecordingBandSchema).
|
|
7479
|
+
bands: array(RecordingBandSchema).default([]),
|
|
7517
7480
|
retention: RecordingRetentionSchema.optional(),
|
|
7518
7481
|
/**
|
|
7519
7482
|
* Per-camera scrub-thumbnail fidelity preset (resolution + JPEG quality for
|
|
@@ -7521,60 +7484,30 @@ var RecordingConfigSchema = object({
|
|
|
7521
7484
|
* windows only — existing sheets are immutable, and each window's index
|
|
7522
7485
|
* carries its own tile dims so mixed-preset history renders correctly.
|
|
7523
7486
|
*/
|
|
7524
|
-
scrubThumbnails: ScrubThumbnailPresetSchema.optional()
|
|
7525
|
-
|
|
7526
|
-
|
|
7527
|
-
*
|
|
7528
|
-
|
|
7529
|
-
|
|
7530
|
-
|
|
7531
|
-
|
|
7532
|
-
|
|
7533
|
-
|
|
7534
|
-
|
|
7535
|
-
|
|
7536
|
-
|
|
7537
|
-
|
|
7538
|
-
*
|
|
7539
|
-
*
|
|
7540
|
-
|
|
7541
|
-
|
|
7542
|
-
|
|
7543
|
-
|
|
7544
|
-
|
|
7545
|
-
|
|
7546
|
-
if (mode === "continuous") return
|
|
7547
|
-
|
|
7548
|
-
start,
|
|
7549
|
-
end,
|
|
7550
|
-
mode
|
|
7551
|
-
};
|
|
7552
|
-
return {
|
|
7553
|
-
days,
|
|
7554
|
-
start,
|
|
7555
|
-
end,
|
|
7556
|
-
mode,
|
|
7557
|
-
...config.triggers ? { triggers: config.triggers } : {},
|
|
7558
|
-
...config.preBufferSec !== void 0 ? { preBufferSec: config.preBufferSec } : {},
|
|
7559
|
-
...config.postBufferSec !== void 0 ? { postBufferSec: config.postBufferSec } : {}
|
|
7560
|
-
};
|
|
7561
|
-
}
|
|
7562
|
-
/**
|
|
7563
|
-
* One-way migration from the legacy recording-config shape to the authoritative
|
|
7564
|
-
* mode-per-band model. Pure (no clock access).
|
|
7565
|
-
*
|
|
7566
|
-
* - If `config.bands` is present, it is authoritative and returned as-is.
|
|
7567
|
-
* - Otherwise the result is derived from the legacy fields: a disabled config or
|
|
7568
|
-
* `mode: 'off'` yields no bands; every legacy schedule maps to one band whose
|
|
7569
|
-
* mode is `continuous` when `config.mode === 'continuous'`, else `events`
|
|
7570
|
-
* (carrying `triggers`/`preBufferSec`/`postBufferSec`).
|
|
7571
|
-
*/
|
|
7572
|
-
function migrateConfigToBands(config) {
|
|
7573
|
-
if (config.bands) return config.bands;
|
|
7574
|
-
if (!config.enabled || config.mode === "off") return [];
|
|
7575
|
-
const schedules = config.schedules ?? (config.schedule ? [config.schedule] : [{ kind: "always" }]);
|
|
7576
|
-
const bandMode = config.mode === "continuous" ? "continuous" : "events";
|
|
7577
|
-
return schedules.map((schedule) => bandFromSchedule(schedule, bandMode, config));
|
|
7487
|
+
scrubThumbnails: ScrubThumbnailPresetSchema.optional(),
|
|
7488
|
+
/**
|
|
7489
|
+
* OPT-IN thumbnail-strip generation for this camera: every keyframe of the
|
|
7490
|
+
* low recording saved as a JPEG (the fast-drag scrub depth), a derived
|
|
7491
|
+
* cache that eviction reclaims with the footage. Absent/false = no strips
|
|
7492
|
+
* are written and scrub reads exact keyframes at every velocity.
|
|
7493
|
+
*/
|
|
7494
|
+
stripsEnabled: boolean().optional()
|
|
7495
|
+
}).strict();
|
|
7496
|
+
/**
|
|
7497
|
+
* Derive the {@link RecordingStorageModeSchema} summary from the authoritative
|
|
7498
|
+
* bands: `continuous` when any band records continuously, `events` when a band
|
|
7499
|
+
* exists at all, else `off`. Pure.
|
|
7500
|
+
*
|
|
7501
|
+
* THE one definition: the recorder stamps `config.mode` with it on save and
|
|
7502
|
+
* reports it as the cap's `activeMode`, and the settings UI reads it back to
|
|
7503
|
+
* decide which authoring tab a config opens in. Two copies would drift, and the
|
|
7504
|
+
* symptom (a status dot disagreeing with what is being recorded) is exactly the
|
|
7505
|
+
* bug this field was added to fix.
|
|
7506
|
+
*/
|
|
7507
|
+
function deriveRecordingMode(config) {
|
|
7508
|
+
if (!config.enabled || config.bands.length === 0) return "off";
|
|
7509
|
+
if (config.bands.some((band) => band.mode === "continuous")) return "continuous";
|
|
7510
|
+
return "events";
|
|
7578
7511
|
}
|
|
7579
7512
|
/**
|
|
7580
7513
|
* Ops-log — the durable, append-only operations audit shared by the
|
|
@@ -7594,7 +7527,8 @@ var OpsLogOpSchema = _enum([
|
|
|
7594
7527
|
"prune",
|
|
7595
7528
|
"manual-delete",
|
|
7596
7529
|
"rescan",
|
|
7597
|
-
"retention-run"
|
|
7530
|
+
"retention-run",
|
|
7531
|
+
"relocate"
|
|
7598
7532
|
]);
|
|
7599
7533
|
/** Why the operation ran. */
|
|
7600
7534
|
var OpsLogReasonSchema = _enum([
|
|
@@ -7633,6 +7567,55 @@ var OpsLogQueryInputSchema = object({
|
|
|
7633
7567
|
limit: number().int().min(1).max(1e3).optional()
|
|
7634
7568
|
});
|
|
7635
7569
|
/**
|
|
7570
|
+
* Entity-relocation job state (storage entity-routing spec, Phase 4).
|
|
7571
|
+
*
|
|
7572
|
+
* One shape shared by the recorder's `relocateFootage` (segments + strips) and
|
|
7573
|
+
* pipeline-analytics' `relocateMedia` (event media blobs) so the admin Data
|
|
7574
|
+
* page renders both movers with one component. Jobs are in-RAM (a restart
|
|
7575
|
+
* forgets them — re-running is safe by construction: copy-if-absent, delete
|
|
7576
|
+
* after verify) and each completed/failed run also lands one durable ops-log
|
|
7577
|
+
* row on the owning addon's surface.
|
|
7578
|
+
*/
|
|
7579
|
+
var RelocateJobStateSchema = _enum([
|
|
7580
|
+
"running",
|
|
7581
|
+
"done",
|
|
7582
|
+
"failed",
|
|
7583
|
+
"cancelled"
|
|
7584
|
+
]);
|
|
7585
|
+
var RelocateJobSchema = object({
|
|
7586
|
+
jobId: string(),
|
|
7587
|
+
state: RelocateJobStateSchema,
|
|
7588
|
+
/** Source location — for media relocation this is informational ('*': rows
|
|
7589
|
+
* move from wherever they are to the target). */
|
|
7590
|
+
fromLocationId: string(),
|
|
7591
|
+
toLocationId: string(),
|
|
7592
|
+
/** Scoped device, or null = every device. */
|
|
7593
|
+
deviceId: number().nullable(),
|
|
7594
|
+
/** What the job moves (owner-addon specific: segments/strips or media). */
|
|
7595
|
+
entities: array(string()),
|
|
7596
|
+
filesMoved: number().int(),
|
|
7597
|
+
bytesMoved: number().int(),
|
|
7598
|
+
/** Total files discovered up front; null while (or when) unknown. */
|
|
7599
|
+
filesTotal: number().int().nullable(),
|
|
7600
|
+
startedAt: number(),
|
|
7601
|
+
finishedAt: number().nullable(),
|
|
7602
|
+
error: string().nullable()
|
|
7603
|
+
});
|
|
7604
|
+
var RelocateFootageInputSchema = object({
|
|
7605
|
+
deviceId: number().optional(),
|
|
7606
|
+
fromLocationId: string(),
|
|
7607
|
+
toLocationId: string(),
|
|
7608
|
+
entities: array(_enum(["segments", "strips"])).optional(),
|
|
7609
|
+
/** Copy throttle in MB/s (default 40) — the drain is a background chore,
|
|
7610
|
+
* never allowed to starve live writers. */
|
|
7611
|
+
throttleMbps: number().min(1).max(1e3).optional()
|
|
7612
|
+
});
|
|
7613
|
+
var RelocateMediaInputSchema = object({
|
|
7614
|
+
deviceId: number().optional(),
|
|
7615
|
+
toLocationId: string(),
|
|
7616
|
+
throttleMbps: number().min(1).max(1e3).optional()
|
|
7617
|
+
});
|
|
7618
|
+
/**
|
|
7636
7619
|
* `StorageLocationType` — an addon-declared id that identifies the *kind* of
|
|
7637
7620
|
* storage a location serves. Defined here (not in `capabilities/storage.cap.ts`)
|
|
7638
7621
|
* so the persisted record schema and the consumer-facing cap can both consume it
|
|
@@ -7682,6 +7665,13 @@ var StorageLocationSchema = object({
|
|
|
7682
7665
|
nodeId: string().optional(),
|
|
7683
7666
|
isDefault: boolean().default(false),
|
|
7684
7667
|
isSystem: boolean().default(false),
|
|
7668
|
+
/** COMPUTED at read time by the orchestrator (statfs of the backing volume
|
|
7669
|
+
* for node-local locations it can reach) — never persisted, absent when the
|
|
7670
|
+
* volume is remote/unreachable. The single capacity truth every UI reads. */
|
|
7671
|
+
capacity: object({
|
|
7672
|
+
totalBytes: number(),
|
|
7673
|
+
availableBytes: number()
|
|
7674
|
+
}).nullable().optional(),
|
|
7685
7675
|
createdAt: number(),
|
|
7686
7676
|
updatedAt: number()
|
|
7687
7677
|
});
|
|
@@ -8797,7 +8787,8 @@ var NcTaxonomyEntrySchema = object({
|
|
|
8797
8787
|
/** Macro/category parent for grouping ('car' → 'vehicle'); null for a top. */
|
|
8798
8788
|
parentKind: string().nullable()
|
|
8799
8789
|
});
|
|
8800
|
-
|
|
8790
|
+
/** The complete NC picker taxonomy — three grouped buckets. */
|
|
8791
|
+
var NcTaxonomySchema = object({
|
|
8801
8792
|
videoClasses: array(NcTaxonomyEntrySchema),
|
|
8802
8793
|
audioKinds: array(NcTaxonomyEntrySchema),
|
|
8803
8794
|
labels: array(NcTaxonomyEntrySchema)
|
|
@@ -9457,6 +9448,7 @@ var AccessoryKind = {
|
|
|
9457
9448
|
};
|
|
9458
9449
|
AccessoryKind.Siren, AccessoryKind.Floodlight, AccessoryKind.Spotlight, AccessoryKind.PirSensor, AccessoryKind.Chime, AccessoryKind.Autotrack, AccessoryKind.Nightvision, AccessoryKind.PrivacyMask;
|
|
9459
9450
|
DeviceFeature.BatteryOperated;
|
|
9451
|
+
new Set(["devices", "classes"]);
|
|
9460
9452
|
/**
|
|
9461
9453
|
* Shared geometry vocabulary for on-frame shape caps — privacy-mask,
|
|
9462
9454
|
* motion-zones, and the detection zones/lines editor all speak this one
|
|
@@ -9773,12 +9765,60 @@ var NcRuleTargetSchema = object({
|
|
|
9773
9765
|
* - `keyFrame` — the clean scene frame (no subject box).
|
|
9774
9766
|
* - `none` — no attachment.
|
|
9775
9767
|
*/
|
|
9776
|
-
|
|
9777
|
-
|
|
9778
|
-
|
|
9779
|
-
|
|
9780
|
-
|
|
9781
|
-
|
|
9768
|
+
/**
|
|
9769
|
+
* WHAT THE PICTURE SHOWS — chosen explicitly, because the implicit ladders
|
|
9770
|
+
* conflate it with the selection strategy and betray the request: asking for
|
|
9771
|
+
* the clean scene frame on an object-event owner used to start at
|
|
9772
|
+
* `fullFrameBoxed`, i.e. the annotated frame (2026-07-30).
|
|
9773
|
+
* - `cropped` — the subject, tight. What "who is at the door" wants.
|
|
9774
|
+
* - `full` — the clean scene, no annotation. What "what is going on" wants.
|
|
9775
|
+
* - `boxed` — the scene WITH the detection boxes drawn, for verifying what
|
|
9776
|
+
* the pipeline actually saw.
|
|
9777
|
+
*/
|
|
9778
|
+
var NcMediaFrameSchema = _enum([
|
|
9779
|
+
"cropped",
|
|
9780
|
+
"full",
|
|
9781
|
+
"boxed"
|
|
9782
|
+
]);
|
|
9783
|
+
var NcMediaPolicySchema = object({
|
|
9784
|
+
attach: _enum([
|
|
9785
|
+
"best",
|
|
9786
|
+
"best-matching",
|
|
9787
|
+
"keyFrame",
|
|
9788
|
+
"none"
|
|
9789
|
+
]).default("best"),
|
|
9790
|
+
/** What the still shows. Absent = `cropped` (the historical `best` shape). */
|
|
9791
|
+
frame: NcMediaFrameSchema.optional(),
|
|
9792
|
+
/** Crop the attached still to the rule's condition-zone bbox (padded) —
|
|
9793
|
+
* "show me the ZONE", not the whole scene or the subject crop. */
|
|
9794
|
+
zoneCrop: boolean().optional(),
|
|
9795
|
+
/**
|
|
9796
|
+
* Also attach a short GIF cut from the stream broker's clip ring around the
|
|
9797
|
+
* event — NOT from the recording, so the camera does not have to be
|
|
9798
|
+
* recording, and the window sits AROUND the moment instead of a segment
|
|
9799
|
+
* behind it. Fail-closed: a window the ring does not cover contributes no
|
|
9800
|
+
* gif, never a failed notification.
|
|
9801
|
+
*/
|
|
9802
|
+
gif: boolean().optional(),
|
|
9803
|
+
/**
|
|
9804
|
+
* Also attach a short MP4 CLIP of the same cut. Same source and the same
|
|
9805
|
+
* fail-closed rule as `gif`. Prefer it where the backend takes video
|
|
9806
|
+
* (telegram, discord, zentik, webhook); backends that do not are handled by
|
|
9807
|
+
* the degrade engine, which drops the video and keeps the still.
|
|
9808
|
+
*/
|
|
9809
|
+
clip: boolean().optional(),
|
|
9810
|
+
/** Seconds of footage BEFORE / AFTER the event instant. Defaults 3 / 7. */
|
|
9811
|
+
clipPreRollSec: number().int().min(0).max(30).optional(),
|
|
9812
|
+
clipPostRollSec: number().int().min(0).max(30).optional(),
|
|
9813
|
+
/**
|
|
9814
|
+
* Which stream profile the footage is cut from. Absent = the CHEAPEST
|
|
9815
|
+
* assigned profile: a notification is watched on a phone, so the 4K
|
|
9816
|
+
* rendition would burn CPU to produce a file the client downscales anyway.
|
|
9817
|
+
* A profile that is not assigned falls back to the cheapest, and the render
|
|
9818
|
+
* reports which one actually ran.
|
|
9819
|
+
*/
|
|
9820
|
+
profile: CamProfileSchema.optional()
|
|
9821
|
+
});
|
|
9782
9822
|
/** Throttle — cooldown survives restarts (rebuilt from the outbox on boot). */
|
|
9783
9823
|
var NcThrottleSchema = object({
|
|
9784
9824
|
cooldownSec: number().int().min(0).max(86400).default(60),
|
|
@@ -9792,7 +9832,19 @@ var NcRuleInputSchema = object({
|
|
|
9792
9832
|
delivery: NcDeliverySchema,
|
|
9793
9833
|
conditions: NcConditionsSchema.default({}),
|
|
9794
9834
|
schedule: NcScheduleSchema.optional(),
|
|
9795
|
-
|
|
9835
|
+
/** May be empty when `targetUsers` addresses at least one user — the
|
|
9836
|
+
* "at least one addressee" invariant is enforced by the provider, because
|
|
9837
|
+
* a cross-field refine here would break `NcRulePatchSchema.partial()`. */
|
|
9838
|
+
targets: array(NcRuleTargetSchema),
|
|
9839
|
+
/**
|
|
9840
|
+
* USERS this rule addresses in addition to `targets` (Phase 4). At fire
|
|
9841
|
+
* time each user fans out to the personal targets they own
|
|
9842
|
+
* (`config.ownerUserId`), filtered by that user's `allowedDevices` for the
|
|
9843
|
+
* firing camera — a user is never notified about a device they cannot open.
|
|
9844
|
+
* Per-user opt-outs (`disabledTargetIds`) still apply to the fanned-out
|
|
9845
|
+
* targets.
|
|
9846
|
+
*/
|
|
9847
|
+
targetUsers: array(string()).optional(),
|
|
9796
9848
|
media: NcMediaPolicySchema.default({ attach: "best" }),
|
|
9797
9849
|
throttle: NcThrottleSchema.default({
|
|
9798
9850
|
cooldownSec: 60,
|
|
@@ -10005,7 +10057,10 @@ method(object({}), object({ rules: array(NcRuleSchema) }), { auth: "admin" }), m
|
|
|
10005
10057
|
}), object({ results: array(NcTestResultSchema) }), {
|
|
10006
10058
|
kind: "mutation",
|
|
10007
10059
|
auth: "admin"
|
|
10008
|
-
}), method(object({}), object({
|
|
10060
|
+
}), method(object({}), object({
|
|
10061
|
+
catalog: array(NcConditionDescriptorSchema),
|
|
10062
|
+
taxonomy: NcTaxonomySchema.optional()
|
|
10063
|
+
})), method(object({ filter: NcHistoryFilterSchema.default({ limit: 100 }) }), object({ entries: array(NcHistoryEntrySchema) }), { auth: "admin" });
|
|
10009
10064
|
/**
|
|
10010
10065
|
* TimelapseRule — the STANDALONE scheduled timelapse producer's rule model.
|
|
10011
10066
|
*
|
|
@@ -10752,6 +10807,48 @@ var streamBrokerCapability = {
|
|
|
10752
10807
|
kind: "mutation",
|
|
10753
10808
|
auth: "admin"
|
|
10754
10809
|
}),
|
|
10810
|
+
/**
|
|
10811
|
+
* Render a short GIF or MP4 from the broker's PRE-BUFFER around an instant.
|
|
10812
|
+
*
|
|
10813
|
+
* The pre-buffer is the only source that already holds the seconds BEFORE
|
|
10814
|
+
* an event (it is what it exists for — "when an addon needs the last N
|
|
10815
|
+
* seconds of video for clip creation"). Cutting from recorded segments
|
|
10816
|
+
* cannot: only finalized segments are addressable and the one covering the
|
|
10817
|
+
* moment is still being written, so a segment-sourced clip is either
|
|
10818
|
+
* delayed or shows the approach instead of the event (operator,
|
|
10819
|
+
* 2026-07-30). It also means a camera does not have to be RECORDING to
|
|
10820
|
+
* produce a notification clip.
|
|
10821
|
+
*
|
|
10822
|
+
* Returns muxed BYTES, never packets: the frame plane never crosses a
|
|
10823
|
+
* process boundary at frame rate (D9/D18) — this is one compressed,
|
|
10824
|
+
* on-demand payload per notification.
|
|
10825
|
+
*
|
|
10826
|
+
* Waits up to `postRollSec` for the tail to accumulate, so the window is
|
|
10827
|
+
* CENTRED on `aroundMs`.
|
|
10828
|
+
*/
|
|
10829
|
+
renderPreBufferClip: method(object({
|
|
10830
|
+
deviceId: number(),
|
|
10831
|
+
/** Absent = the LOWEST assigned profile — a notification attachment is
|
|
10832
|
+
* watched on a phone, and the cheap rendition is the right default. */
|
|
10833
|
+
profile: CamProfileSchema.optional(),
|
|
10834
|
+
aroundMs: number(),
|
|
10835
|
+
preRollSec: number().min(0).max(20).default(3),
|
|
10836
|
+
postRollSec: number().min(0).max(20).default(5),
|
|
10837
|
+
format: _enum(["gif", "mp4"]).default("gif"),
|
|
10838
|
+
maxWidth: number().int().min(120).max(1920).default(480),
|
|
10839
|
+
/** GIF only — MP4 keeps the source cadence. */
|
|
10840
|
+
fps: number().int().min(1).max(15).default(5)
|
|
10841
|
+
}), object({
|
|
10842
|
+
base64: string(),
|
|
10843
|
+
mime: string(),
|
|
10844
|
+
bytes: number().int(),
|
|
10845
|
+
/** The profile actually rendered (what the default resolved to). */
|
|
10846
|
+
profile: CamProfileSchema,
|
|
10847
|
+
durationMs: number()
|
|
10848
|
+
}), {
|
|
10849
|
+
kind: "mutation",
|
|
10850
|
+
auth: "admin"
|
|
10851
|
+
}),
|
|
10755
10852
|
listAllCameraStreams: method(_void(), array(CameraStreamSchema).readonly()),
|
|
10756
10853
|
listAllProfileSlots: method(_void(), array(ProfileSlotSchema).readonly()),
|
|
10757
10854
|
getBrokerStats: method(object({ brokerId: string() }), BrokerStatsSchema),
|
|
@@ -17926,6 +18023,36 @@ var TargetKindSchema = object({
|
|
|
17926
18023
|
icon: string(),
|
|
17927
18024
|
/** Stamped by each provider so the concat-fanned catalog stays routable. */
|
|
17928
18025
|
addonId: string(),
|
|
18026
|
+
/**
|
|
18027
|
+
* URL of the kind's bundled BRAND icon, served by the providing addon over
|
|
18028
|
+
* its own `addon-routes` surface (`/addon/<addonId>/icons/<kind>`). Absent
|
|
18029
|
+
* when the addon bundles no icon for that kind — the client then falls back
|
|
18030
|
+
* to a neutral glyph rather than rendering the raw `icon` NAME as text.
|
|
18031
|
+
*
|
|
18032
|
+
* Root-relative on purpose: it resolves against whatever origin serves a web
|
|
18033
|
+
* client, and a native client joins it onto its own hub base.
|
|
18034
|
+
*
|
|
18035
|
+
* DECLARED here deliberately. It used to travel as an undeclared passthrough
|
|
18036
|
+
* field that survived only because the runtime cap-router forwards provider
|
|
18037
|
+
* output verbatim — so every consumer had to re-declare it by hand to stop
|
|
18038
|
+
* its own Zod parse from stripping it, and the whole arrangement would have
|
|
18039
|
+
* broken silently the moment output validation was tightened anywhere.
|
|
18040
|
+
*/
|
|
18041
|
+
iconUrl: string().optional(),
|
|
18042
|
+
/**
|
|
18043
|
+
* Media type of {@link iconUrl} (`image/svg+xml`, `image/png`, …).
|
|
18044
|
+
*
|
|
18045
|
+
* The server knows this and therefore says it, because the client cannot
|
|
18046
|
+
* safely guess: a React-Native client renders SVG and raster through two
|
|
18047
|
+
* DIFFERENT components (`react-native-svg` vs `expo-image` — expo-image does
|
|
18048
|
+
* not decode SVG on iOS/Android), so without this it silently fell back to a
|
|
18049
|
+
* placeholder glyph for every vector icon while the web build looked fine.
|
|
18050
|
+
*
|
|
18051
|
+
* Absent when {@link iconUrl} is absent, or for a legacy provider that has
|
|
18052
|
+
* not been updated — a client that cannot determine the type should prefer
|
|
18053
|
+
* its raster path, which is the safe default for an unknown image.
|
|
18054
|
+
*/
|
|
18055
|
+
iconMediaType: string().optional(),
|
|
17929
18056
|
configSchema: ConfigSchemaPassthrough,
|
|
17930
18057
|
supportsDiscovery: boolean(),
|
|
17931
18058
|
caps: TargetKindCapsSchema
|
|
@@ -18657,6 +18784,15 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
18657
18784
|
}), method(object({ deviceId: number() }), EventPruneCountsSchema, {
|
|
18658
18785
|
kind: "mutation",
|
|
18659
18786
|
auth: "admin"
|
|
18787
|
+
}), method(RelocateMediaInputSchema, object({ jobId: string() }), {
|
|
18788
|
+
kind: "mutation",
|
|
18789
|
+
auth: "admin"
|
|
18790
|
+
}), method(object({}), array(RelocateJobSchema).readonly(), {
|
|
18791
|
+
kind: "query",
|
|
18792
|
+
auth: "admin"
|
|
18793
|
+
}), method(object({ jobId: string() }), object({ cancelled: boolean() }), {
|
|
18794
|
+
kind: "mutation",
|
|
18795
|
+
auth: "admin"
|
|
18660
18796
|
}), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
|
|
18661
18797
|
kind: "query",
|
|
18662
18798
|
auth: "admin"
|
|
@@ -21231,6 +21367,17 @@ var GetConnectionEndpointsResultSchema = object({ endpoints: array(object({
|
|
|
21231
21367
|
*/
|
|
21232
21368
|
priority: number()
|
|
21233
21369
|
})).readonly() });
|
|
21370
|
+
/**
|
|
21371
|
+
* The chosen outbound endpoint for notification artifacts. `baseUrl: null` =
|
|
21372
|
+
* AUTO (resolved from the candidate ranking at send time); `resolved` reports
|
|
21373
|
+
* what AUTO currently picks, so the UI can show the effective value either way.
|
|
21374
|
+
*/
|
|
21375
|
+
var NotificationEndpointSchema = object({
|
|
21376
|
+
/** The operator's explicit choice, or null for AUTO. */
|
|
21377
|
+
baseUrl: string().nullable(),
|
|
21378
|
+
/** What the ranking currently resolves to (null when nothing is reachable). */
|
|
21379
|
+
resolved: string().nullable()
|
|
21380
|
+
});
|
|
21234
21381
|
var AllowedAddressesSchema = object({
|
|
21235
21382
|
/**
|
|
21236
21383
|
* Allowlist of interface addresses operators have explicitly opted
|
|
@@ -21253,7 +21400,7 @@ method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(obje
|
|
|
21253
21400
|
* to avoid mixed-content blocks in the browser. The public
|
|
21254
21401
|
* tunnel always emits `https://` regardless. */
|
|
21255
21402
|
scheme: _enum(["http", "https"]).optional()
|
|
21256
|
-
}), GetConnectionEndpointsResultSchema), method(_void(), AllowedAddressesSchema), method(AllowedAddressesSchema, object({ success: literal(true) }), { kind: "mutation" }), method(_void(), AllowedAddressesSchema, { kind: "mutation" });
|
|
21403
|
+
}), 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" });
|
|
21257
21404
|
/**
|
|
21258
21405
|
* mesh-network — collection cap for mesh-VPN providers.
|
|
21259
21406
|
*
|
|
@@ -22052,7 +22199,12 @@ var RecordingDeviceUsageSchema = object({
|
|
|
22052
22199
|
var RecordingLocationUsageSchema = object({
|
|
22053
22200
|
/** StorageLocation id; null for the legacy/degraded single-root fallback. */
|
|
22054
22201
|
locationId: string().nullable(),
|
|
22055
|
-
/**
|
|
22202
|
+
/** Every location id sharing this row's PHYSICAL volume (aliases). One row
|
|
22203
|
+
* is emitted per physical disk (2026-07-29): two locations on one root
|
|
22204
|
+
* previously rendered as two identical "disks" with a nonsensical used
|
|
22205
|
+
* split — hydrate attribution across aliases is arbitrary by nature. */
|
|
22206
|
+
locationIds: array(string()).optional(),
|
|
22207
|
+
/** Bytes of recordings stored on this PHYSICAL volume (all aliases). */
|
|
22056
22208
|
usedBytes: number(),
|
|
22057
22209
|
/** Free bytes on the location's volume; null when capacity is unknown (remote). */
|
|
22058
22210
|
availableBytes: number().nullable(),
|
|
@@ -22208,6 +22360,77 @@ var recordingCapability = {
|
|
|
22208
22360
|
listOpsLog: method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
|
|
22209
22361
|
kind: "query",
|
|
22210
22362
|
auth: "admin"
|
|
22363
|
+
}),
|
|
22364
|
+
/**
|
|
22365
|
+
* Move footage (segments and/or strips) from one recordings location to
|
|
22366
|
+
* another — the drain workflow's mover (entity-routing spec Phase 4).
|
|
22367
|
+
* Throttled copy → size-verify → delete source → index refresh; resumable
|
|
22368
|
+
* by construction (copy-if-absent). Single-flight: one job at a time.
|
|
22369
|
+
*/
|
|
22370
|
+
/**
|
|
22371
|
+
* Render a short GIF from recorded footage around `aroundMs` (low profile,
|
|
22372
|
+
* palette-free ffmpeg gif). Synchronous — the window is a few seconds of
|
|
22373
|
+
* `low`, rendering in ~1-2s. Built for notification attachments: the
|
|
22374
|
+
* caller gets bytes, nothing persists. Fails when no footage covers the
|
|
22375
|
+
* window (camera not recording → caller skips the attachment).
|
|
22376
|
+
*/
|
|
22377
|
+
renderGif: method(object({
|
|
22378
|
+
deviceId: number(),
|
|
22379
|
+
aroundMs: number(),
|
|
22380
|
+
preRollSec: number().min(0).max(30).default(2),
|
|
22381
|
+
postRollSec: number().min(0).max(30).default(5),
|
|
22382
|
+
maxWidth: number().int().min(120).max(1280).default(480),
|
|
22383
|
+
fps: number().int().min(1).max(15).default(5)
|
|
22384
|
+
}), object({
|
|
22385
|
+
gifBase64: string(),
|
|
22386
|
+
fromMs: number(),
|
|
22387
|
+
toMs: number()
|
|
22388
|
+
}), {
|
|
22389
|
+
kind: "mutation",
|
|
22390
|
+
auth: "admin"
|
|
22391
|
+
}),
|
|
22392
|
+
/**
|
|
22393
|
+
* Render a short MP4 clip from recorded footage around `aroundMs` — the
|
|
22394
|
+
* "send a clip, not a gif" notification attachment. Same window, source
|
|
22395
|
+
* and fail-closed contract as {@link renderGif}: no footage covering the
|
|
22396
|
+
* window ⇒ it throws and the caller ships no attachment. Re-encoded (never
|
|
22397
|
+
* stream-copied) so a concat across segments with different encoder
|
|
22398
|
+
* parameters still plays. Silent by contract.
|
|
22399
|
+
*
|
|
22400
|
+
* The returned window is SEGMENT-GRANULAR: the source playlist is built
|
|
22401
|
+
* from whole segments, so the clip starts at or before `fromMs` and ends
|
|
22402
|
+
* at or after `toMs` — overshoot bounded by one segment per side (an 8 s
|
|
22403
|
+
* ask over 4 s segments measured 12 s). `fromMs`/`toMs` report the window
|
|
22404
|
+
* ASKED for, not the encoded duration.
|
|
22405
|
+
*/
|
|
22406
|
+
renderClip: method(object({
|
|
22407
|
+
deviceId: number(),
|
|
22408
|
+
aroundMs: number(),
|
|
22409
|
+
preRollSec: number().min(0).max(30).default(3),
|
|
22410
|
+
postRollSec: number().min(0).max(30).default(7),
|
|
22411
|
+
maxWidth: number().int().min(160).max(1920).default(640)
|
|
22412
|
+
}), object({
|
|
22413
|
+
clipBase64: string(),
|
|
22414
|
+
mime: string(),
|
|
22415
|
+
fromMs: number(),
|
|
22416
|
+
toMs: number(),
|
|
22417
|
+
bytes: number().int()
|
|
22418
|
+
}), {
|
|
22419
|
+
kind: "mutation",
|
|
22420
|
+
auth: "admin"
|
|
22421
|
+
}),
|
|
22422
|
+
relocateFootage: method(RelocateFootageInputSchema, object({ jobId: string() }), {
|
|
22423
|
+
kind: "mutation",
|
|
22424
|
+
auth: "admin"
|
|
22425
|
+
}),
|
|
22426
|
+
/** Every known relocate job (in-RAM, newest-first). */
|
|
22427
|
+
getRelocateStatus: method(object({}), array(RelocateJobSchema).readonly(), {
|
|
22428
|
+
kind: "query",
|
|
22429
|
+
auth: "admin"
|
|
22430
|
+
}),
|
|
22431
|
+
cancelRelocate: method(object({ jobId: string() }), object({ cancelled: boolean() }), {
|
|
22432
|
+
kind: "mutation",
|
|
22433
|
+
auth: "admin"
|
|
22211
22434
|
})
|
|
22212
22435
|
}
|
|
22213
22436
|
};
|
|
@@ -24712,6 +24935,12 @@ Object.freeze({
|
|
|
24712
24935
|
addonId: null,
|
|
24713
24936
|
access: "view"
|
|
24714
24937
|
},
|
|
24938
|
+
"localNetwork.getNotificationEndpoint": {
|
|
24939
|
+
capName: "local-network",
|
|
24940
|
+
capScope: "system",
|
|
24941
|
+
addonId: null,
|
|
24942
|
+
access: "view"
|
|
24943
|
+
},
|
|
24715
24944
|
"localNetwork.getPreferred": {
|
|
24716
24945
|
capName: "local-network",
|
|
24717
24946
|
capScope: "system",
|
|
@@ -24736,6 +24965,12 @@ Object.freeze({
|
|
|
24736
24965
|
addonId: null,
|
|
24737
24966
|
access: "create"
|
|
24738
24967
|
},
|
|
24968
|
+
"localNetwork.setNotificationEndpoint": {
|
|
24969
|
+
capName: "local-network",
|
|
24970
|
+
capScope: "system",
|
|
24971
|
+
addonId: null,
|
|
24972
|
+
access: "create"
|
|
24973
|
+
},
|
|
24739
24974
|
"lockControl.lock": {
|
|
24740
24975
|
capName: "lock-control",
|
|
24741
24976
|
capScope: "device",
|
|
@@ -25378,6 +25613,12 @@ Object.freeze({
|
|
|
25378
25613
|
addonId: null,
|
|
25379
25614
|
access: "create"
|
|
25380
25615
|
},
|
|
25616
|
+
"pipelineAnalytics.cancelMediaRelocate": {
|
|
25617
|
+
capName: "pipeline-analytics",
|
|
25618
|
+
capScope: "device",
|
|
25619
|
+
addonId: null,
|
|
25620
|
+
access: "create"
|
|
25621
|
+
},
|
|
25381
25622
|
"pipelineAnalytics.clearTracks": {
|
|
25382
25623
|
capName: "pipeline-analytics",
|
|
25383
25624
|
capScope: "device",
|
|
@@ -25432,6 +25673,12 @@ Object.freeze({
|
|
|
25432
25673
|
addonId: null,
|
|
25433
25674
|
access: "view"
|
|
25434
25675
|
},
|
|
25676
|
+
"pipelineAnalytics.getMediaRelocateStatus": {
|
|
25677
|
+
capName: "pipeline-analytics",
|
|
25678
|
+
capScope: "device",
|
|
25679
|
+
addonId: null,
|
|
25680
|
+
access: "view"
|
|
25681
|
+
},
|
|
25435
25682
|
"pipelineAnalytics.getMotionEvents": {
|
|
25436
25683
|
capName: "pipeline-analytics",
|
|
25437
25684
|
capScope: "device",
|
|
@@ -25504,6 +25751,12 @@ Object.freeze({
|
|
|
25504
25751
|
addonId: null,
|
|
25505
25752
|
access: "create"
|
|
25506
25753
|
},
|
|
25754
|
+
"pipelineAnalytics.relocateMedia": {
|
|
25755
|
+
capName: "pipeline-analytics",
|
|
25756
|
+
capScope: "device",
|
|
25757
|
+
addonId: null,
|
|
25758
|
+
access: "create"
|
|
25759
|
+
},
|
|
25507
25760
|
"pipelineAnalytics.searchObjectEvents": {
|
|
25508
25761
|
capName: "pipeline-analytics",
|
|
25509
25762
|
capScope: "device",
|
|
@@ -26266,6 +26519,12 @@ Object.freeze({
|
|
|
26266
26519
|
addonId: null,
|
|
26267
26520
|
access: "create"
|
|
26268
26521
|
},
|
|
26522
|
+
"recording.cancelRelocate": {
|
|
26523
|
+
capName: "recording",
|
|
26524
|
+
capScope: "system",
|
|
26525
|
+
addonId: null,
|
|
26526
|
+
access: "create"
|
|
26527
|
+
},
|
|
26269
26528
|
"recording.deleteFootprint": {
|
|
26270
26529
|
capName: "recording",
|
|
26271
26530
|
capScope: "system",
|
|
@@ -26296,6 +26555,12 @@ Object.freeze({
|
|
|
26296
26555
|
addonId: null,
|
|
26297
26556
|
access: "view"
|
|
26298
26557
|
},
|
|
26558
|
+
"recording.getRelocateStatus": {
|
|
26559
|
+
capName: "recording",
|
|
26560
|
+
capScope: "system",
|
|
26561
|
+
addonId: null,
|
|
26562
|
+
access: "view"
|
|
26563
|
+
},
|
|
26299
26564
|
"recording.getStorageUsage": {
|
|
26300
26565
|
capName: "recording",
|
|
26301
26566
|
capScope: "system",
|
|
@@ -26326,6 +26591,24 @@ Object.freeze({
|
|
|
26326
26591
|
addonId: null,
|
|
26327
26592
|
access: "view"
|
|
26328
26593
|
},
|
|
26594
|
+
"recording.relocateFootage": {
|
|
26595
|
+
capName: "recording",
|
|
26596
|
+
capScope: "system",
|
|
26597
|
+
addonId: null,
|
|
26598
|
+
access: "create"
|
|
26599
|
+
},
|
|
26600
|
+
"recording.renderClip": {
|
|
26601
|
+
capName: "recording",
|
|
26602
|
+
capScope: "system",
|
|
26603
|
+
addonId: null,
|
|
26604
|
+
access: "create"
|
|
26605
|
+
},
|
|
26606
|
+
"recording.renderGif": {
|
|
26607
|
+
capName: "recording",
|
|
26608
|
+
capScope: "system",
|
|
26609
|
+
addonId: null,
|
|
26610
|
+
access: "create"
|
|
26611
|
+
},
|
|
26329
26612
|
"recording.rescanStorage": {
|
|
26330
26613
|
capName: "recording",
|
|
26331
26614
|
capScope: "system",
|
|
@@ -26920,6 +27203,12 @@ Object.freeze({
|
|
|
26920
27203
|
addonId: null,
|
|
26921
27204
|
access: "create"
|
|
26922
27205
|
},
|
|
27206
|
+
"streamBroker.renderPreBufferClip": {
|
|
27207
|
+
capName: "stream-broker",
|
|
27208
|
+
capScope: "system",
|
|
27209
|
+
addonId: null,
|
|
27210
|
+
access: "create"
|
|
27211
|
+
},
|
|
26923
27212
|
"streamBroker.restartProfile": {
|
|
26924
27213
|
capName: "stream-broker",
|
|
26925
27214
|
capScope: "system",
|
|
@@ -28038,6 +28327,12 @@ Object.defineProperty(exports, "defineCustomActions", {
|
|
|
28038
28327
|
return defineCustomActions;
|
|
28039
28328
|
}
|
|
28040
28329
|
});
|
|
28330
|
+
Object.defineProperty(exports, "deriveRecordingMode", {
|
|
28331
|
+
enumerable: true,
|
|
28332
|
+
get: function() {
|
|
28333
|
+
return deriveRecordingMode;
|
|
28334
|
+
}
|
|
28335
|
+
});
|
|
28041
28336
|
Object.defineProperty(exports, "detectionPipelineCapability", {
|
|
28042
28337
|
enumerable: true,
|
|
28043
28338
|
get: function() {
|
|
@@ -28122,12 +28417,6 @@ Object.defineProperty(exports, "maskUrlCredentials", {
|
|
|
28122
28417
|
return maskUrlCredentials;
|
|
28123
28418
|
}
|
|
28124
28419
|
});
|
|
28125
|
-
Object.defineProperty(exports, "migrateConfigToBands", {
|
|
28126
|
-
enumerable: true,
|
|
28127
|
-
get: function() {
|
|
28128
|
-
return migrateConfigToBands;
|
|
28129
|
-
}
|
|
28130
|
-
});
|
|
28131
28420
|
Object.defineProperty(exports, "motionDetectionCapability", {
|
|
28132
28421
|
enumerable: true,
|
|
28133
28422
|
get: function() {
|