@camstack/addon-pipeline 1.2.200 → 1.2.201

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.
Files changed (37) hide show
  1. package/dist/audio-analyzer/index.js +2 -2
  2. package/dist/audio-analyzer/index.mjs +2 -2
  3. package/dist/{default-detection-model-c1LY6thP.mjs → default-detection-model-fUMLQHB2.mjs} +1 -1
  4. package/dist/{default-detection-model-BsmxtyZx.js → default-detection-model-nKgB-_mg.js} +1 -1
  5. package/dist/detection-pipeline/index.js +5 -5
  6. package/dist/detection-pipeline/index.mjs +4 -4
  7. package/dist/{dist-D2YTTkRf.js → dist-Bd875pfj.js} +540 -232
  8. package/dist/{dist-mEsrAAc3.mjs → dist-D2jcEuZD.mjs} +493 -233
  9. package/dist/{lazy-sharp-B5bW34uC.js → lazy-sharp-B4KrLp0u.js} +1 -1
  10. package/dist/motion-wasm/index.js +2 -2
  11. package/dist/motion-wasm/index.mjs +1 -1
  12. package/dist/{node-CUxep5tc.mjs → node-CmfXSgr3.mjs} +420 -381
  13. package/dist/{node-x3YokJkD.js → node-dwhLC9Fh.js} +423 -378
  14. package/dist/pipeline-runner/index.js +5 -5
  15. package/dist/pipeline-runner/index.mjs +4 -4
  16. package/dist/{process-memory-CFc4D9A2.js → process-memory-BDRJK5Vq.js} +1 -1
  17. package/dist/{process-memory-BCqpTruN.mjs → process-memory-CH5qO7AX.mjs} +1 -1
  18. package/dist/recorder/index.js +4455 -4097
  19. package/dist/recorder/index.mjs +6085 -5727
  20. package/dist/{segment-demux-js-xHtB450F.mjs → segment-demux-js-BHTuEBhC.mjs} +1 -1
  21. package/dist/{segment-demux-js-DUZVURQd.js → segment-demux-js-cmfLROII.js} +1 -1
  22. package/dist/session-decode/decode-worker-child.js +2 -2
  23. package/dist/session-decode/decode-worker-child.mjs +1 -1
  24. package/dist/stream-broker/_stub.js +2 -2
  25. package/dist/stream-broker/{_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-CLXImQ3R.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-DZcCQR5t.mjs} +3 -3
  26. package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-CrzkEz67.mjs +26 -0
  27. package/dist/stream-broker/{_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-D62O5bRa.mjs → _virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-cYr6Swud.mjs} +1 -1
  28. package/dist/stream-broker/demux-worker-child.js +1 -1
  29. package/dist/stream-broker/demux-worker-child.mjs +1 -1
  30. package/dist/stream-broker/{hostInit-D_cZQhBA.mjs → hostInit-CZt5Lq_M.mjs} +3 -3
  31. package/dist/stream-broker/index.js +3 -3
  32. package/dist/stream-broker/index.mjs +3 -3
  33. package/dist/stream-broker/remoteEntry.js +1 -1
  34. package/dist/{worker-protocol-CRDaBlJl.js → worker-protocol--PcFsRrE.js} +1 -1
  35. package/dist/{worker-protocol-oUamwZSn.mjs → worker-protocol-D4GyRNnY.mjs} +1 -1
  36. package/package.json +5 -1
  37. package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-NqqfpkYF.mjs +0 -26
@@ -22,7 +22,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
22
22
  }) : target, mod));
23
23
  //#endregion
24
24
  let node_crypto = require("node:crypto");
25
- //#region ../types/dist/event-category-zAv7pMUz.mjs
25
+ //#region ../types/dist/event-category-CnLqLOKs.mjs
26
26
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
27
27
  EventCategory["SystemBoot"] = "system.boot";
28
28
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -217,6 +217,19 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
217
217
  EventCategory["ProcessCrashed"] = "process.crashed";
218
218
  EventCategory["ProcessRestartScheduled"] = "process.restart_scheduled";
219
219
  EventCategory["ProcessRestarted"] = "process.restarted";
220
+ /**
221
+ * The SET of storage locations changed — one was created, edited, enabled,
222
+ * disabled or deleted through `storage.upsertLocation` / `deleteLocation`.
223
+ *
224
+ * Telemetry, not a transaction (D8/D11): every consumer that re-resolves on
225
+ * it must also converge on its own periodic path, because a dropped event
226
+ * must not leave a node writing to yesterday's disk set forever. It exists
227
+ * because there was NO signal at all — an operator who added a second
228
+ * recordings disk in the admin UI got nothing, and the recorder kept its
229
+ * resolved locations until something else happened to re-resolve them
230
+ * (D387). Payload `StorageLocationsChangedPayload`.
231
+ */
232
+ EventCategory["StorageLocationsChanged"] = "storage.locations-changed";
220
233
  EventCategory["RecordingStarted"] = "recording.started";
221
234
  EventCategory["RecordingStopped"] = "recording.stopped";
222
235
  EventCategory["RecordingError"] = "recording.error";
@@ -9731,6 +9744,110 @@ var StorageCleanupJobSchema = object({
9731
9744
  });
9732
9745
  var StorageCleanupStatusInputSchema = object({ jobId: string().optional() });
9733
9746
  /**
9747
+ * The storage-location STATE MODEL (D385) — one typed state, one policy module.
9748
+ *
9749
+ * A location's state used to be split across two authorities: the typed
9750
+ * `enabled` field (THE write switch since D383) and an untyped `config.readOnly`
9751
+ * key. They did not mean the same thing — `enabled: false` was still evicted
9752
+ * under disk pressure while `config.readOnly` was deliberately excluded — and
9753
+ * neither name said which. Every consumer re-derived the difference, and the
9754
+ * three questions that actually matter were answered in six places.
9755
+ *
9756
+ * This module is the ONLY place in the repo allowed to interpret the state. It
9757
+ * answers three questions and nothing else:
9758
+ *
9759
+ * - may this location be WRITTEN to? {@link modeMayWrite}
9760
+ * - may this location be READ? {@link modeMayRead}
9761
+ * - what is its eviction policy? {@link evictionPolicyForMode}
9762
+ *
9763
+ * | mode | write | read | eviction |
9764
+ * | ---------- | ----- | ---- | ------------------------------ |
9765
+ * | `active` | yes | yes | `normal` (pressure + usage cap) |
9766
+ * | `readonly` | no | yes | `never` |
9767
+ * | `drain` | no | yes | `drain` (paced, until empty) |
9768
+ * | `disabled` | no | no | `never` |
9769
+ *
9770
+ * `scripts/check-storage-location-mode-single-owner.ts` fails the build when
9771
+ * anything outside this module reads `config['readOnly']` or compares `enabled`
9772
+ * directly. A rule nothing checks has already been broken somewhere.
9773
+ */
9774
+ var STORAGE_LOCATION_MODES = [
9775
+ "active",
9776
+ "readonly",
9777
+ "drain",
9778
+ "disabled"
9779
+ ];
9780
+ /**
9781
+ * The one typed state of a storage location. Authoritative Zod schema — the TS
9782
+ * alias below is `z.infer<>` of it, never a second spelling.
9783
+ */
9784
+ var StorageLocationModeSchema = _enum(STORAGE_LOCATION_MODES);
9785
+ _enum([
9786
+ "normal",
9787
+ "never",
9788
+ "drain"
9789
+ ]);
9790
+ /** Is this mode a write target? Only `active` is. */
9791
+ function modeMayWrite(mode) {
9792
+ return mode === "active";
9793
+ }
9794
+ /** May this mode be read (playback, timeline, scrub, relocate source)? */
9795
+ function modeMayRead(mode) {
9796
+ return mode !== "disabled";
9797
+ }
9798
+ /** What eviction may do here. See {@link StorageEvictionPolicy}. */
9799
+ function evictionPolicyForMode(mode) {
9800
+ switch (mode) {
9801
+ case "active": return "normal";
9802
+ case "drain": return "drain";
9803
+ case "readonly":
9804
+ case "disabled": return "never";
9805
+ }
9806
+ }
9807
+ /**
9808
+ * The mode a LEGACY row implies, or `null` when it implies nothing — the row is
9809
+ * already stamped, or it carried neither flag.
9810
+ *
9811
+ * Both legacy flags fold to `readonly`, which is the CONSERVATIVE direction: a
9812
+ * state change must never start deleting footage on its own, and it must never
9813
+ * make footage that was still being served disappear. `enabled: false` used to
9814
+ * leave the location evictable under pressure; folding it to `readonly` stops
9815
+ * that, which is a strictly safer answer than the one it replaces.
9816
+ */
9817
+ function legacyModeOf(location) {
9818
+ if (location.mode !== void 0) return null;
9819
+ if (location.config["readOnly"] === true) return "readonly";
9820
+ if (location.enabled === false) return "readonly";
9821
+ return null;
9822
+ }
9823
+ /**
9824
+ * The state of a location, stamped or folded. THE one interpretation: a row
9825
+ * that predates D385 is never ambiguous, and a stamped `mode` always wins over
9826
+ * whatever the legacy pair still says.
9827
+ */
9828
+ function resolveLocationMode(location) {
9829
+ return (isStorageLocationMode(location.mode) ? location.mode : void 0) ?? legacyModeOf(location) ?? "active";
9830
+ }
9831
+ /** Is this one of the four states? The stamped value crosses a wire, and a
9832
+ * value nobody defined must not be rendered as if it were a state. */
9833
+ function isStorageLocationMode(value) {
9834
+ return STORAGE_LOCATION_MODES.some((mode) => mode === value);
9835
+ }
9836
+ /** May this location be written to? */
9837
+ function mayWriteToLocation(location) {
9838
+ return modeMayWrite(resolveLocationMode(location));
9839
+ }
9840
+ /** May this location be read? A `disabled` one may not — and that is an
9841
+ * operator CHOICE, which callers must report as unavailable rather than as an
9842
+ * unknown-location fault. */
9843
+ function mayReadLocation(location) {
9844
+ return modeMayRead(resolveLocationMode(location));
9845
+ }
9846
+ /** What eviction may do to this location. */
9847
+ function evictionPolicyOfLocation(location) {
9848
+ return evictionPolicyForMode(resolveLocationMode(location));
9849
+ }
9850
+ /**
9734
9851
  * `StorageLocationType` — an addon-declared id that identifies the *kind* of
9735
9852
  * storage a location serves. Defined here (not in `capabilities/storage.cap.ts`)
9736
9853
  * so the persisted record schema and the consumer-facing cap can both consume it
@@ -9796,6 +9913,21 @@ var StorageLocationSchema = object({
9796
9913
  * stops existing rather than being re-derived on every read.
9797
9914
  */
9798
9915
  enabled: boolean().optional(),
9916
+ /**
9917
+ * THE state of this location (D385), and the only authority on what may be
9918
+ * written, read or evicted here. Interpreted in exactly one place —
9919
+ * `storage-location-mode.ts` — which also folds the legacy
9920
+ * `enabled` / `config.readOnly` pair into a mode so an old row is never
9921
+ * ambiguous.
9922
+ *
9923
+ * OPTIONAL only for the wire and for rows written before D385: absence is
9924
+ * resolved by `resolveLocationMode`, and the orchestrator stamps every
9925
+ * unstamped row ONCE at hydrate so absence stops existing rather than being
9926
+ * re-derived on every read. `enabled` survives one release as a DERIVED
9927
+ * mirror (`mode === 'active'`); `withLocationMode` is the only writer of
9928
+ * either, so the two cannot disagree.
9929
+ */
9930
+ mode: StorageLocationModeSchema.optional(),
9799
9931
  /** COMPUTED at read time by the orchestrator (statfs of the backing volume
9800
9932
  * for node-local locations it can reach) — never persisted, absent when the
9801
9933
  * volume is remote/unreachable. The single capacity truth every UI reads. */
@@ -9803,11 +9935,62 @@ var StorageLocationSchema = object({
9803
9935
  totalBytes: number(),
9804
9936
  availableBytes: number()
9805
9937
  }).nullable().optional(),
9938
+ /**
9939
+ * How much of that volume CamStack ITSELF holds on this location (D388) —
9940
+ * COMPUTED at read time from the `storage-occupancy` providers' own figures,
9941
+ * never persisted, never a filesystem walk.
9942
+ *
9943
+ * **ABSENT MEANS UNKNOWN, never zero.** No provider has reported for this
9944
+ * location yet — nobody stores here, the owning addon is down, or the first
9945
+ * refresh has not completed. A UI must omit the segment rather than draw it
9946
+ * at zero, which would claim we occupy nothing (D315). It is an OBJECT and
9947
+ * not a bare number precisely so that a `?? 0` on the consuming side has to
9948
+ * be spelled out loud instead of appearing by accident.
9949
+ *
9950
+ * `measuredAtMs` is the OLDEST contributing measurement, so it is honest
9951
+ * about the whole figure rather than about its freshest part.
9952
+ */
9953
+ owned: object({
9954
+ bytes: number().int().nonnegative(),
9955
+ measuredAtMs: number().int().nonnegative()
9956
+ }).optional(),
9806
9957
  createdAt: number(),
9807
9958
  updatedAt: number()
9808
9959
  });
9809
9960
  object({ isDefault: boolean().optional() });
9810
9961
  /**
9962
+ * Bytes in one GB, for every storage figure an operator types.
9963
+ *
9964
+ * BINARY (1024³), everywhere. The repo had both: the orchestrator's
9965
+ * `maxUsedGb` → bytes conversion used 1024³ while the recorder's placement
9966
+ * headroom used 10⁹ for the SAME stored key, so a location with a cap set was
9967
+ * silently 7.4% off depending on which side of the pipe asked. The persisted
9968
+ * values were entered against the binary unit and the admin UI reads it, so
9969
+ * that is the one that stays. Every GB knob — `maxUsedGb`, `minFreeGb` —
9970
+ * converts through {@link gbToBytes} and nowhere else.
9971
+ */
9972
+ var STORAGE_BYTES_PER_GB = 1024 ** 3;
9973
+ /** GB → bytes, binary. Fractional GB is admitted and floored. */
9974
+ function gbToBytes(gb) {
9975
+ return Math.floor(gb * STORAGE_BYTES_PER_GB);
9976
+ }
9977
+ /**
9978
+ * How far a `drain` has got (D386) — the read a UI renders, and nothing more.
9979
+ *
9980
+ * `estimatedEmptyAtMs` is derived from the growth the ratchet has actually
9981
+ * OBSERVED and is `null` when it has observed none. Never a fabricated date: a
9982
+ * drain with no observed growth has no honest ETA, and inventing one is how an
9983
+ * operator learns not to believe the screen.
9984
+ */
9985
+ var StorageDrainProgressSchema = object({
9986
+ locationId: string(),
9987
+ startedAtMs: number(),
9988
+ startBytes: number(),
9989
+ bytesRemaining: number(),
9990
+ drained: boolean(),
9991
+ estimatedEmptyAtMs: number().nullable()
9992
+ });
9993
+ /**
9811
9994
  * Reference accepted by consumer-facing `api.storage.*` calls.
9812
9995
  * Either:
9813
9996
  * - a `StorageLocationType` (e.g. `'backups'`) → the sole location of that type
@@ -24347,7 +24530,7 @@ method(object({
24347
24530
  }), _void(), {
24348
24531
  kind: "mutation",
24349
24532
  auth: "admin"
24350
- }), method(object({ id: string() }), object({
24533
+ }), method(_void(), array(StorageDrainProgressSchema).readonly()), method(object({ id: string() }), object({
24351
24534
  ok: boolean(),
24352
24535
  error: string().optional()
24353
24536
  }), { auth: "admin" }), method(_void(), array(ProviderListEntrySchema).readonly()), method(object({
@@ -24439,6 +24622,71 @@ method(StorageMigrationInputSchema, StorageMigrationPlanSchema, { auth: "admin"
24439
24622
  kind: "mutation",
24440
24623
  auth: "admin"
24441
24624
  }), method(object({}), array(StorageMigrationJobSchema).readonly(), { auth: "admin" });
24625
+ /**
24626
+ * `storage-occupancy` — how many bytes an addon actually HOLDS on a storage
24627
+ * location (D388).
24628
+ *
24629
+ * ## Why this is not `storage-evictable`
24630
+ *
24631
+ * `storage-evictable.getEvictableUsage` looks like the same question and is
24632
+ * not, in two ways that both matter and both bite hardest on the locations an
24633
+ * operator most wants a figure for:
24634
+ *
24635
+ * - it reports the whole eviction DOMAIN, not the location. `recordings:default`
24636
+ * and `recordingsLow:default` deliberately share one root and evict as one
24637
+ * oldest-first pool, so both answer with the SAME combined total. As an
24638
+ * occupancy figure that double-counts the disk.
24639
+ * - it reports ZERO for a location whose eviction policy is `never` (D385) —
24640
+ * a `readonly` or `disabled` disk. Those are exactly the disks an operator
24641
+ * is retiring and staring at.
24642
+ *
24643
+ * So this is its own contract with its own quantity, and the quantity is
24644
+ * OCCUPIED: every byte the addon holds on that location, whether or not it
24645
+ * would ever be willing to delete it. A provider that can only answer
24646
+ * "evictable" must not register here — a number that silently means different
24647
+ * things per class is worse than no number.
24648
+ *
24649
+ * ## Absence is an answer
24650
+ *
24651
+ * A location nobody reports for is UNKNOWN, never zero (D315). The orchestrator
24652
+ * stamps `StorageLocation.owned` only for locations it has a report for, and
24653
+ * the field is an OBJECT rather than a bare number so that a `?? 0` on the
24654
+ * consuming side has to be written out loud instead of appearing by accident.
24655
+ *
24656
+ * `internal: true` — consumed by the orchestrator's `listLocations` stamp, never
24657
+ * a public client surface. Clients read the stamped `StorageLocation.owned`.
24658
+ */
24659
+ /** One provider's occupancy answer for one location. */
24660
+ var StorageOccupancyReportSchema = object({
24661
+ locationId: string(),
24662
+ /** Bytes this provider holds on THAT location — not its eviction domain, and
24663
+ * not net of what it is willing to delete. */
24664
+ ownedBytes: number().int().nonnegative(),
24665
+ /** When the provider last actually measured this. The orchestrator carries it
24666
+ * through so a UI can say how old the figure is instead of implying "now". */
24667
+ measuredAtMs: number().int().nonnegative()
24668
+ });
24669
+ var storageOccupancyCapability = {
24670
+ name: "storage-occupancy",
24671
+ scope: "system",
24672
+ mode: "collection",
24673
+ internal: true,
24674
+ methods: {
24675
+ /**
24676
+ * Occupancy for the given locations, in ONE round trip.
24677
+ *
24678
+ * A provider answers only for the locations it actually holds bytes on and
24679
+ * OMITS the rest — an omitted location is "I hold nothing measurable here",
24680
+ * which the orchestrator merges as a contribution of nothing rather than as
24681
+ * a claim that the location is empty. Only a location no provider reports
24682
+ * at all stays unknown.
24683
+ *
24684
+ * This must be CHEAP and must never walk a filesystem: it is on the admin
24685
+ * UI's `listLocations` path. The owner keeps its own figure fresh (D224) and
24686
+ * answers from what it already has.
24687
+ */
24688
+ getOccupancy: method(object({ locationIds: array(string()).readonly() }), array(StorageOccupancyReportSchema).readonly(), { auth: "admin" }) }
24689
+ };
24442
24690
  var ProviderInfoSchema = discriminatedUnion("shouldSaveDiskSpace", [object({
24443
24691
  providerId: string().min(1),
24444
24692
  displayName: string().min(1),
@@ -26221,39 +26469,6 @@ onStatusChanged: { data: object({
26221
26469
  * whether persisting is worth a SQLite commit. */
26222
26470
  volatileStateFields: ["lastUpdated"]
26223
26471
  };
26224
- /**
26225
- * Network-link snapshot. Same shape for every provider (a Reolink wifi
26226
- * camera, a Home Assistant device with a signal-strength sensor, a Tapo
26227
- * plug): one slice under `device.runtimeState['network-link']`, one badge,
26228
- * one Home Assistant projection.
26229
- */
26230
- var NetworkLinkStatusSchema = object({
26231
- /** The link the device is on. `'unknown'` = not read yet, not "no link". */
26232
- type: _enum([
26233
- "wifi",
26234
- "ethernet",
26235
- "cellular",
26236
- "unknown"
26237
- ]),
26238
- /**
26239
- * Link quality, 0..100 inclusive, normalised by the provider from whatever
26240
- * the firmware reports (bars, RSSI, a vendor scale). **`null` means NOT
26241
- * KNOWN or NOT APPLICABLE** — a wired link has no signal, and a wireless
26242
- * one whose reading has not landed must not be drawn at 0 %. Consumers
26243
- * SKIP a null rather than coerce it.
26244
- */
26245
- signalPercent: number().min(0).max(100).nullable(),
26246
- /** Raw received signal strength in dBm, when the firmware reports one. */
26247
- rssiDbm: number().optional(),
26248
- /** Network name of a wireless link, when the firmware reports it. */
26249
- ssid: string().optional(),
26250
- /** Ms epoch of the last observation. Lets consumers reason about freshness. */
26251
- lastUpdated: number()
26252
- });
26253
- DeviceType.Camera, DeviceType.Sensor, DeviceType.Button, DeviceType.Switch, DeviceType.Light, DeviceType.Lock, DeviceType.Siren, object({
26254
- deviceId: number(),
26255
- status: NetworkLinkStatusSchema
26256
- });
26257
26472
  object({
26258
26473
  on: boolean(),
26259
26474
  /** Ms epoch of the last transition. 0 if never observed. */
@@ -28607,6 +28822,236 @@ DeviceType.Camera, method(object({
28607
28822
  detection: NativeDetectionSchema
28608
28823
  });
28609
28824
  /**
28825
+ * `navigation` — a device-scoped capability that natively expresses the FULL
28826
+ * navigation / action surface of a robot that DRIVES ITSELF and carries an
28827
+ * on-board camera (the Dreame robot-vacuum camera is the first provider).
28828
+ *
28829
+ * Why a NEW cap rather than overloading `ptz`:
28830
+ * - `ptz` moves a *gimbal* on a fixed camera (pan/tilt/zoom of the lens). A
28831
+ * robot vacuum has no gimbal — the whole chassis drives, turns and spins.
28832
+ * The two are different physical models: PTZ is absolute-position + presets,
28833
+ * navigation is momentary drive nudges + discrete robot ACTIONS
28834
+ * (dock / spot-clean / follow-pet / go-to-point / …).
28835
+ * - This cap is the SOURCE OF TRUTH. Two consumers adapt from it rather than
28836
+ * the reverse:
28837
+ * 1. a native CamStack navigation panel (data-driven from `listActions`
28838
+ * / `getOptions`), and
28839
+ * 2. the PTZ surface — a thin adapter mimics `ptz` from `navigation` so a
28840
+ * robot camera shows up in the existing PTZ control path without every
28841
+ * PTZ provider learning about robots. The mapping lives in the adapter,
28842
+ * not here (see the addon design note):
28843
+ * ptz.continuousMove({pan,tilt}) → navigation.move({pan,tilt})
28844
+ * ptz.stop() → navigation.stop()
28845
+ * ptz.goHome() → navigation.runAction('goHome')
28846
+ * ptz.getPresets() → navigation.listActions() (id→preset)
28847
+ * ptz.goToPreset(id) → navigation.runAction(id)
28848
+ *
28849
+ * ## Continuous drive
28850
+ *
28851
+ * `move` is MOMENTARY. Fluid navigation comes from the UI (or the PTZ adapter)
28852
+ * sending `move({pan,tilt})` REPEATEDLY at ~1 Hz while a direction is held, and
28853
+ * one `stop()` on release — exactly like the robot app's remote-drive joystick.
28854
+ * The provider forwards EACH `move` to one drive write; it must NOT debounce or
28855
+ * coalesce them. The UI owns the cadence.
28856
+ *
28857
+ * ## The action dictionary
28858
+ *
28859
+ * The discrete controls (dock / locate / spot-clean / follow / flash / sounds)
28860
+ * are a DATA-DRIVEN dictionary the cap exposes via `listActions()`. Each entry
28861
+ * carries `{ id, kind, label, icon }` (plus `soundId` for sound entries) so the
28862
+ * native panel AND the PTZ mimic render buttons WITHOUT hardcoding a
28863
+ * vendor-specific list. `kind: 'action'` entries are triggered with
28864
+ * `runAction({ actionId })`; `kind: 'sound'` entries with `playSound({ soundId })`
28865
+ * (the entry carries the `soundId` to pass). The general primitives — `move`,
28866
+ * `stop`, `goToPoint` — stay as first-class methods, not dictionary entries.
28867
+ *
28868
+ * NOTE (provider wiring): the first provider (Dreame) drives this with the RAW
28869
+ * `callAction(siid,aiid,in)` / `setProperty({siid,piid,value})` MIoT primitives
28870
+ * that the currently-published `@apocaliss92/nodedreame` already exposes on
28871
+ * every device handle. A future nodedreame publish adds a typed
28872
+ * `DreameCameraController` (drive / playPetSound / spotClean / findPet / …); the
28873
+ * provider can then swap the raw calls for the typed methods with no change to
28874
+ * THIS contract.
28875
+ */
28876
+ /**
28877
+ * A momentary drive nudge. The robot MOVES (no gimbal) for as long as the caller
28878
+ * keeps sending nudges (~1 Hz); an explicit `stop` (or letting the nudges lapse)
28879
+ * halts it.
28880
+ *
28881
+ * - `pan` — turn: negative = left, positive = right, 0 = straight.
28882
+ * - `tilt` — throttle: positive = forward, negative = spin / turn-around.
28883
+ * - `speed` — optional intensity hint [0, 1]; the provider may scale the drive
28884
+ * vector by it (drivers without proportional drive ignore it).
28885
+ *
28886
+ * `pan` / `tilt` are normalized [-1, 1]. Both optional so a caller can nudge one
28887
+ * axis alone; an all-undefined nudge is a no-op.
28888
+ */
28889
+ var NavigationMoveCommandSchema = object({
28890
+ pan: number().min(-1).max(1).optional(),
28891
+ tilt: number().min(-1).max(1).optional(),
28892
+ speed: number().min(0).max(1).optional()
28893
+ });
28894
+ /**
28895
+ * The enumerated discrete actions a navigation-capable robot can perform via
28896
+ * `runAction`. This is the CLOSED vocabulary; a given device advertises the
28897
+ * subset it supports through `listActions`. Sounds are NOT here — they go through
28898
+ * `playSound` (see the `sound` dictionary entries).
28899
+ */
28900
+ var NavigationActionIdSchema = _enum([
28901
+ "goHome",
28902
+ "locate",
28903
+ "spotClean",
28904
+ "findPet",
28905
+ "personFollow",
28906
+ "stop",
28907
+ "startClean",
28908
+ "pauseClean",
28909
+ "dockWash",
28910
+ "autoEmpty",
28911
+ "flashOn",
28912
+ "flashOff"
28913
+ ]);
28914
+ /** Whether a dictionary entry is a `runAction` action or a `playSound` sound. */
28915
+ var NavigationEntryKindSchema = _enum(["action", "sound"]);
28916
+ /**
28917
+ * One entry in the navigation action dictionary — the DATA-DRIVEN unit both the
28918
+ * native panel and the PTZ mimic render as a button.
28919
+ *
28920
+ * - `id` — stable id. For `kind:'action'` it is a {@link NavigationActionId}
28921
+ * (pass to `runAction`); for `kind:'sound'` it is a namespaced id
28922
+ * (`sound:meow`) whose `soundId` is passed to `playSound`.
28923
+ * - `icon` — icon HINT (lucide-style name; the UI maps it to its own set).
28924
+ * - `label` — operator-facing English label.
28925
+ * - `soundId` — wire sound id, present only on `kind:'sound'` entries.
28926
+ * - `enabled` — per-device FEATURE FLAG. `listActions` reports it so the UI /
28927
+ * PTZ render ONLY enabled entries. Data-driven: the provider
28928
+ * flips it from config, never by editing code.
28929
+ */
28930
+ var NavigationActionEntrySchema = object({
28931
+ id: string(),
28932
+ kind: NavigationEntryKindSchema,
28933
+ label: string(),
28934
+ icon: string(),
28935
+ /** Present only on `kind:'sound'` entries — the id to pass to `playSound`. */
28936
+ soundId: number().int().optional(),
28937
+ /** Per-device feature flag — render this entry only when true. */
28938
+ enabled: boolean()
28939
+ });
28940
+ /** Coordinates for `goToPoint` — a point on the robot's live map. */
28941
+ var NavigationPointSchema = object({
28942
+ x: number(),
28943
+ y: number()
28944
+ });
28945
+ /**
28946
+ * Per-device FEATURE-FLAG report for the general (non-dictionary) primitives.
28947
+ * The cap reports which are enabled so the UI / PTZ render only the controls
28948
+ * that are turned on for THIS device. Data-driven: the provider derives these
28949
+ * from config + probe, never hardcoded in the UI. The per-DICTIONARY-entry flags
28950
+ * live on {@link NavigationActionEntrySchema.enabled}; these gate the primitives
28951
+ * that are not dictionary entries.
28952
+ *
28953
+ * - `move` / `stop` — the momentary drive joystick.
28954
+ * - `goToPoint` — send-to-map-coordinate. Ships OFF on Dreame until the
28955
+ * map-coordinate plumbing is wired.
28956
+ * - `runAction` — the discrete action buttons (dictionary `kind:'action'`).
28957
+ * - `playSound` — the sound buttons (dictionary `kind:'sound'`).
28958
+ * - `light` — the on/off fill-light toggle (works anytime).
28959
+ * - `lightMode` — the auto/manual selector + manual level slider (a
28960
+ * camera-service control; needs an active stream).
28961
+ */
28962
+ var NavigationFeaturesSchema = object({
28963
+ move: boolean(),
28964
+ stop: boolean(),
28965
+ goToPoint: boolean(),
28966
+ runAction: boolean(),
28967
+ playSound: boolean(),
28968
+ light: boolean(),
28969
+ lightMode: boolean()
28970
+ });
28971
+ /** Light mode: `auto` lets the camera choose brightness; `manual` uses `level`. */
28972
+ var NavigationLightModeSchema = _enum(["auto", "manual"]);
28973
+ /**
28974
+ * Live navigation state so the UI can reflect what the robot is doing:
28975
+ * - `mode` — coarse activity (idle / cleaning / following / …).
28976
+ * - `following` — person/pet follow is currently armed.
28977
+ * - `flash` — the on-camera fill light is on.
28978
+ * - `lightMode` — auto vs manual fill-light mode.
28979
+ * - `lightLevel` — manual fill-light level (40..100); meaningful when
28980
+ * `lightMode === 'manual'`.
28981
+ */
28982
+ var NavigationStatusSchema = object({
28983
+ mode: _enum([
28984
+ "idle",
28985
+ "cleaning",
28986
+ "spot",
28987
+ "following",
28988
+ "goto",
28989
+ "returning",
28990
+ "paused",
28991
+ "unknown"
28992
+ ]),
28993
+ following: boolean(),
28994
+ flash: boolean(),
28995
+ lightMode: NavigationLightModeSchema,
28996
+ lightLevel: number().min(40).max(100),
28997
+ /** Ms epoch when the slice was last updated. */
28998
+ lastChangedAt: number()
28999
+ });
29000
+ NavigationStatusSchema.extend({ lastFetchedAt: number() });
29001
+ DeviceType.Camera, method(NavigationMoveCommandSchema.extend({ deviceId: number() }), _void(), { kind: "mutation" }), method(object({ deviceId: number() }), _void(), { kind: "mutation" }), method(NavigationPointSchema.extend({ deviceId: number() }), _void(), { kind: "mutation" }), method(object({ deviceId: number() }), array(NavigationActionEntrySchema)), method(object({
29002
+ deviceId: number(),
29003
+ actionId: NavigationActionIdSchema
29004
+ }), _void(), { kind: "mutation" }), method(object({
29005
+ deviceId: number(),
29006
+ soundId: number().int()
29007
+ }), _void(), { kind: "mutation" }), method(object({
29008
+ deviceId: number(),
29009
+ on: boolean()
29010
+ }), _void(), { kind: "mutation" }), method(object({
29011
+ deviceId: number(),
29012
+ mode: NavigationLightModeSchema,
29013
+ level: number().min(40).max(100).optional()
29014
+ }), _void(), { kind: "mutation" }), method(object({
29015
+ deviceId: number(),
29016
+ level: number().min(40).max(100)
29017
+ }), _void(), { kind: "mutation" }), method(object({ deviceId: number() }), NavigationFeaturesSchema), object({
29018
+ deviceId: number(),
29019
+ status: NavigationStatusSchema
29020
+ });
29021
+ /**
29022
+ * Network-link snapshot. Same shape for every provider (a Reolink wifi
29023
+ * camera, a Home Assistant device with a signal-strength sensor, a Tapo
29024
+ * plug): one slice under `device.runtimeState['network-link']`, one badge,
29025
+ * one Home Assistant projection.
29026
+ */
29027
+ var NetworkLinkStatusSchema = object({
29028
+ /** The link the device is on. `'unknown'` = not read yet, not "no link". */
29029
+ type: _enum([
29030
+ "wifi",
29031
+ "ethernet",
29032
+ "cellular",
29033
+ "unknown"
29034
+ ]),
29035
+ /**
29036
+ * Link quality, 0..100 inclusive, normalised by the provider from whatever
29037
+ * the firmware reports (bars, RSSI, a vendor scale). **`null` means NOT
29038
+ * KNOWN or NOT APPLICABLE** — a wired link has no signal, and a wireless
29039
+ * one whose reading has not landed must not be drawn at 0 %. Consumers
29040
+ * SKIP a null rather than coerce it.
29041
+ */
29042
+ signalPercent: number().min(0).max(100).nullable(),
29043
+ /** Raw received signal strength in dBm, when the firmware reports one. */
29044
+ rssiDbm: number().optional(),
29045
+ /** Network name of a wireless link, when the firmware reports it. */
29046
+ ssid: string().optional(),
29047
+ /** Ms epoch of the last observation. Lets consumers reason about freshness. */
29048
+ lastUpdated: number()
29049
+ });
29050
+ DeviceType.Camera, DeviceType.Sensor, DeviceType.Button, DeviceType.Switch, DeviceType.Light, DeviceType.Lock, DeviceType.Siren, object({
29051
+ deviceId: number(),
29052
+ status: NetworkLinkStatusSchema
29053
+ });
29054
+ /**
28610
29055
  * network-quality — system-scoped singleton capability tracking RTT,
28611
29056
  * jitter, and observed/peak bandwidth per device + per client.
28612
29057
  *
@@ -29848,203 +30293,6 @@ DeviceType.Camera, method(object({ deviceId: number() }), PtzAutotrackStatusSche
29848
30293
  deviceId: number(),
29849
30294
  status: PtzAutotrackStatusSchema
29850
30295
  });
29851
- /**
29852
- * `navigation` — a device-scoped capability that natively expresses the FULL
29853
- * navigation / action surface of a robot that DRIVES ITSELF and carries an
29854
- * on-board camera (the Dreame robot-vacuum camera is the first provider).
29855
- *
29856
- * Why a NEW cap rather than overloading `ptz`:
29857
- * - `ptz` moves a *gimbal* on a fixed camera (pan/tilt/zoom of the lens). A
29858
- * robot vacuum has no gimbal — the whole chassis drives, turns and spins.
29859
- * The two are different physical models: PTZ is absolute-position + presets,
29860
- * navigation is momentary drive nudges + discrete robot ACTIONS
29861
- * (dock / spot-clean / follow-pet / go-to-point / …).
29862
- * - This cap is the SOURCE OF TRUTH. Two consumers adapt from it rather than
29863
- * the reverse:
29864
- * 1. a native CamStack navigation panel (data-driven from `listActions`
29865
- * / `getOptions`), and
29866
- * 2. the PTZ surface — a thin adapter mimics `ptz` from `navigation` so a
29867
- * robot camera shows up in the existing PTZ control path without every
29868
- * PTZ provider learning about robots. The mapping lives in the adapter,
29869
- * not here (see the addon design note):
29870
- * ptz.continuousMove({pan,tilt}) → navigation.move({pan,tilt})
29871
- * ptz.stop() → navigation.stop()
29872
- * ptz.goHome() → navigation.runAction('goHome')
29873
- * ptz.getPresets() → navigation.listActions() (id→preset)
29874
- * ptz.goToPreset(id) → navigation.runAction(id)
29875
- *
29876
- * ## Continuous drive
29877
- *
29878
- * `move` is MOMENTARY. Fluid navigation comes from the UI (or the PTZ adapter)
29879
- * sending `move({pan,tilt})` REPEATEDLY at ~1 Hz while a direction is held, and
29880
- * one `stop()` on release — exactly like the robot app's remote-drive joystick.
29881
- * The provider forwards EACH `move` to one drive write; it must NOT debounce or
29882
- * coalesce them. The UI owns the cadence.
29883
- *
29884
- * ## The action dictionary
29885
- *
29886
- * The discrete controls (dock / locate / spot-clean / follow / flash / sounds)
29887
- * are a DATA-DRIVEN dictionary the cap exposes via `listActions()`. Each entry
29888
- * carries `{ id, kind, label, icon }` (plus `soundId` for sound entries) so the
29889
- * native panel AND the PTZ mimic render buttons WITHOUT hardcoding a
29890
- * vendor-specific list. `kind: 'action'` entries are triggered with
29891
- * `runAction({ actionId })`; `kind: 'sound'` entries with `playSound({ soundId })`
29892
- * (the entry carries the `soundId` to pass). The general primitives — `move`,
29893
- * `stop`, `goToPoint` — stay as first-class methods, not dictionary entries.
29894
- *
29895
- * NOTE (provider wiring): the first provider (Dreame) drives this with the RAW
29896
- * `callAction(siid,aiid,in)` / `setProperty({siid,piid,value})` MIoT primitives
29897
- * that the currently-published `@apocaliss92/nodedreame` already exposes on
29898
- * every device handle. A future nodedreame publish adds a typed
29899
- * `DreameCameraController` (drive / playPetSound / spotClean / findPet / …); the
29900
- * provider can then swap the raw calls for the typed methods with no change to
29901
- * THIS contract.
29902
- */
29903
- /**
29904
- * A momentary drive nudge. The robot MOVES (no gimbal) for as long as the caller
29905
- * keeps sending nudges (~1 Hz); an explicit `stop` (or letting the nudges lapse)
29906
- * halts it.
29907
- *
29908
- * - `pan` — turn: negative = left, positive = right, 0 = straight.
29909
- * - `tilt` — throttle: positive = forward, negative = spin / turn-around.
29910
- * - `speed` — optional intensity hint [0, 1]; the provider may scale the drive
29911
- * vector by it (drivers without proportional drive ignore it).
29912
- *
29913
- * `pan` / `tilt` are normalized [-1, 1]. Both optional so a caller can nudge one
29914
- * axis alone; an all-undefined nudge is a no-op.
29915
- */
29916
- var NavigationMoveCommandSchema = object({
29917
- pan: number().min(-1).max(1).optional(),
29918
- tilt: number().min(-1).max(1).optional(),
29919
- speed: number().min(0).max(1).optional()
29920
- });
29921
- /**
29922
- * The enumerated discrete actions a navigation-capable robot can perform via
29923
- * `runAction`. This is the CLOSED vocabulary; a given device advertises the
29924
- * subset it supports through `listActions`. Sounds are NOT here — they go through
29925
- * `playSound` (see the `sound` dictionary entries).
29926
- */
29927
- var NavigationActionIdSchema = _enum([
29928
- "goHome",
29929
- "locate",
29930
- "spotClean",
29931
- "findPet",
29932
- "personFollow",
29933
- "stop",
29934
- "startClean",
29935
- "pauseClean",
29936
- "dockWash",
29937
- "autoEmpty",
29938
- "flashOn",
29939
- "flashOff"
29940
- ]);
29941
- /** Whether a dictionary entry is a `runAction` action or a `playSound` sound. */
29942
- var NavigationEntryKindSchema = _enum(["action", "sound"]);
29943
- /**
29944
- * One entry in the navigation action dictionary — the DATA-DRIVEN unit both the
29945
- * native panel and the PTZ mimic render as a button.
29946
- *
29947
- * - `id` — stable id. For `kind:'action'` it is a {@link NavigationActionId}
29948
- * (pass to `runAction`); for `kind:'sound'` it is a namespaced id
29949
- * (`sound:meow`) whose `soundId` is passed to `playSound`.
29950
- * - `icon` — icon HINT (lucide-style name; the UI maps it to its own set).
29951
- * - `label` — operator-facing English label.
29952
- * - `soundId` — wire sound id, present only on `kind:'sound'` entries.
29953
- * - `enabled` — per-device FEATURE FLAG. `listActions` reports it so the UI /
29954
- * PTZ render ONLY enabled entries. Data-driven: the provider
29955
- * flips it from config, never by editing code.
29956
- */
29957
- var NavigationActionEntrySchema = object({
29958
- id: string(),
29959
- kind: NavigationEntryKindSchema,
29960
- label: string(),
29961
- icon: string(),
29962
- /** Present only on `kind:'sound'` entries — the id to pass to `playSound`. */
29963
- soundId: number().int().optional(),
29964
- /** Per-device feature flag — render this entry only when true. */
29965
- enabled: boolean()
29966
- });
29967
- /** Coordinates for `goToPoint` — a point on the robot's live map. */
29968
- var NavigationPointSchema = object({
29969
- x: number(),
29970
- y: number()
29971
- });
29972
- /**
29973
- * Per-device FEATURE-FLAG report for the general (non-dictionary) primitives.
29974
- * The cap reports which are enabled so the UI / PTZ render only the controls
29975
- * that are turned on for THIS device. Data-driven: the provider derives these
29976
- * from config + probe, never hardcoded in the UI. The per-DICTIONARY-entry flags
29977
- * live on {@link NavigationActionEntrySchema.enabled}; these gate the primitives
29978
- * that are not dictionary entries.
29979
- *
29980
- * - `move` / `stop` — the momentary drive joystick.
29981
- * - `goToPoint` — send-to-map-coordinate. Ships OFF on Dreame until the
29982
- * map-coordinate plumbing is wired.
29983
- * - `runAction` — the discrete action buttons (dictionary `kind:'action'`).
29984
- * - `playSound` — the sound buttons (dictionary `kind:'sound'`).
29985
- * - `light` — the on/off fill-light toggle (works anytime).
29986
- * - `lightMode` — the auto/manual selector + manual level slider (a
29987
- * camera-service control; needs an active stream).
29988
- */
29989
- var NavigationFeaturesSchema = object({
29990
- move: boolean(),
29991
- stop: boolean(),
29992
- goToPoint: boolean(),
29993
- runAction: boolean(),
29994
- playSound: boolean(),
29995
- light: boolean(),
29996
- lightMode: boolean()
29997
- });
29998
- /** Light mode: `auto` lets the camera choose brightness; `manual` uses `level`. */
29999
- var NavigationLightModeSchema = _enum(["auto", "manual"]);
30000
- /**
30001
- * Live navigation state so the UI can reflect what the robot is doing:
30002
- * - `mode` — coarse activity (idle / cleaning / following / …).
30003
- * - `following` — person/pet follow is currently armed.
30004
- * - `flash` — the on-camera fill light is on.
30005
- * - `lightMode` — auto vs manual fill-light mode.
30006
- * - `lightLevel` — manual fill-light level (40..100); meaningful when
30007
- * `lightMode === 'manual'`.
30008
- */
30009
- var NavigationStatusSchema = object({
30010
- mode: _enum([
30011
- "idle",
30012
- "cleaning",
30013
- "spot",
30014
- "following",
30015
- "goto",
30016
- "returning",
30017
- "paused",
30018
- "unknown"
30019
- ]),
30020
- following: boolean(),
30021
- flash: boolean(),
30022
- lightMode: NavigationLightModeSchema,
30023
- lightLevel: number().min(40).max(100),
30024
- /** Ms epoch when the slice was last updated. */
30025
- lastChangedAt: number()
30026
- });
30027
- NavigationStatusSchema.extend({ lastFetchedAt: number() });
30028
- DeviceType.Camera, method(NavigationMoveCommandSchema.extend({ deviceId: number() }), _void(), { kind: "mutation" }), method(object({ deviceId: number() }), _void(), { kind: "mutation" }), method(NavigationPointSchema.extend({ deviceId: number() }), _void(), { kind: "mutation" }), method(object({ deviceId: number() }), array(NavigationActionEntrySchema)), method(object({
30029
- deviceId: number(),
30030
- actionId: NavigationActionIdSchema
30031
- }), _void(), { kind: "mutation" }), method(object({
30032
- deviceId: number(),
30033
- soundId: number().int()
30034
- }), _void(), { kind: "mutation" }), method(object({
30035
- deviceId: number(),
30036
- on: boolean()
30037
- }), _void(), { kind: "mutation" }), method(object({
30038
- deviceId: number(),
30039
- mode: NavigationLightModeSchema,
30040
- level: number().min(40).max(100).optional()
30041
- }), _void(), { kind: "mutation" }), method(object({
30042
- deviceId: number(),
30043
- level: number().min(40).max(100)
30044
- }), _void(), { kind: "mutation" }), method(object({ deviceId: number() }), NavigationFeaturesSchema), object({
30045
- deviceId: number(),
30046
- status: NavigationStatusSchema
30047
- });
30048
30296
  DeviceType.Camera, DeviceType.Sensor, DeviceType.Switch, method(object({ deviceId: number().int().nonnegative() }), object({ success: literal(true) }), {
30049
30297
  kind: "mutation",
30050
30298
  auth: "admin"
@@ -37773,6 +38021,12 @@ Object.freeze({
37773
38021
  addonId: null,
37774
38022
  access: "view"
37775
38023
  },
38024
+ "storage.listDrainProgress": {
38025
+ capName: "storage",
38026
+ capScope: "system",
38027
+ addonId: null,
38028
+ access: "view"
38029
+ },
37776
38030
  "storage.listLocationDeclarations": {
37777
38031
  capName: "storage",
37778
38032
  capScope: "system",
@@ -37917,6 +38171,12 @@ Object.freeze({
37917
38171
  addonId: null,
37918
38172
  access: "view"
37919
38173
  },
38174
+ "storageOccupancy.getOccupancy": {
38175
+ capName: "storage-occupancy",
38176
+ capScope: "system",
38177
+ addonId: null,
38178
+ access: "view"
38179
+ },
37920
38180
  "storageProvider.abortUpload": {
37921
38181
  capName: "storage-provider",
37922
38182
  capScope: "system",
@@ -42800,12 +43060,30 @@ Object.defineProperty(exports, "evaluateZoneRules", {
42800
43060
  return evaluateZoneRules;
42801
43061
  }
42802
43062
  });
43063
+ Object.defineProperty(exports, "evictionPolicyForMode", {
43064
+ enumerable: true,
43065
+ get: function() {
43066
+ return evictionPolicyForMode;
43067
+ }
43068
+ });
43069
+ Object.defineProperty(exports, "evictionPolicyOfLocation", {
43070
+ enumerable: true,
43071
+ get: function() {
43072
+ return evictionPolicyOfLocation;
43073
+ }
43074
+ });
42803
43075
  Object.defineProperty(exports, "failureContributionCapability", {
42804
43076
  enumerable: true,
42805
43077
  get: function() {
42806
43078
  return failureContributionCapability;
42807
43079
  }
42808
43080
  });
43081
+ Object.defineProperty(exports, "gbToBytes", {
43082
+ enumerable: true,
43083
+ get: function() {
43084
+ return gbToBytes;
43085
+ }
43086
+ });
42809
43087
  Object.defineProperty(exports, "hfModelUrl", {
42810
43088
  enumerable: true,
42811
43089
  get: function() {
@@ -42896,12 +43174,30 @@ Object.defineProperty(exports, "maskUrlCredentials", {
42896
43174
  return maskUrlCredentials;
42897
43175
  }
42898
43176
  });
43177
+ Object.defineProperty(exports, "mayReadLocation", {
43178
+ enumerable: true,
43179
+ get: function() {
43180
+ return mayReadLocation;
43181
+ }
43182
+ });
43183
+ Object.defineProperty(exports, "mayWriteToLocation", {
43184
+ enumerable: true,
43185
+ get: function() {
43186
+ return mayWriteToLocation;
43187
+ }
43188
+ });
42899
43189
  Object.defineProperty(exports, "migrateLegacyDeviceSignalConfig", {
42900
43190
  enumerable: true,
42901
43191
  get: function() {
42902
43192
  return migrateLegacyDeviceSignalConfig;
42903
43193
  }
42904
43194
  });
43195
+ Object.defineProperty(exports, "modeMayWrite", {
43196
+ enumerable: true,
43197
+ get: function() {
43198
+ return modeMayWrite;
43199
+ }
43200
+ });
42905
43201
  Object.defineProperty(exports, "motionDetectionCapability", {
42906
43202
  enumerable: true,
42907
43203
  get: function() {
@@ -43028,6 +43324,12 @@ Object.defineProperty(exports, "resolveEgressDecodeHwAccel", {
43028
43324
  return resolveEgressDecodeHwAccel;
43029
43325
  }
43030
43326
  });
43327
+ Object.defineProperty(exports, "resolveLocationMode", {
43328
+ enumerable: true,
43329
+ get: function() {
43330
+ return resolveLocationMode;
43331
+ }
43332
+ });
43031
43333
  Object.defineProperty(exports, "resolvePoolMemoryPolicy", {
43032
43334
  enumerable: true,
43033
43335
  get: function() {
@@ -43064,6 +43366,12 @@ Object.defineProperty(exports, "storageEvictableCapability", {
43064
43366
  return storageEvictableCapability;
43065
43367
  }
43066
43368
  });
43369
+ Object.defineProperty(exports, "storageOccupancyCapability", {
43370
+ enumerable: true,
43371
+ get: function() {
43372
+ return storageOccupancyCapability;
43373
+ }
43374
+ });
43067
43375
  Object.defineProperty(exports, "streamBrokerCapability", {
43068
43376
  enumerable: true,
43069
43377
  get: function() {