@camstack/types 1.2.179 → 1.2.181

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/index.js CHANGED
@@ -5,6 +5,124 @@ const require_canonical_hash = require("./canonical-hash-DNV8S5ET.js");
5
5
  const require_enums = require("./enums.js");
6
6
  const require_err_msg = require("./err-msg-COpsHMw2.js");
7
7
  let zod = require("zod");
8
+ //#region src/media/media-owner-key.ts
9
+ /**
10
+ * The one place a media key is built and read.
11
+ *
12
+ * A media key addresses a file by its OWNER, in one grammar:
13
+ *
14
+ * ```
15
+ * <ownerType>:<ownerId>:<fileKind>[:<timestampMs>]
16
+ * ```
17
+ *
18
+ * The owner type is a TABLE. That is already true of every owner on the live
19
+ * hub - `track`, `summary`, `face`, `identity`, `plate` - and the exception was
20
+ * `event`, which covered three tables at once. While event ids were UUIDs the
21
+ * ambiguity cost nothing, because a UUID is unique across tables. D474 made an
22
+ * event id a SQLite rowid alias, so each table numbers from 1 and `event:5`
23
+ * stopped naming one row. Splitting `event` into `motion` / `object` / `audio`
24
+ * restores uniqueness without a fifth segment and without a magic numbering
25
+ * offset, which would have hidden the same invariant somewhere nobody reads.
26
+ *
27
+ * Why this module exists at all, rather than a `split(':')` at each call site:
28
+ * the key is built in the addon, in `ui-library` and in the notification
29
+ * dispatcher, and read positionally in admin-ui (`split(':')[1]` for an owner
30
+ * id). Positional reads are silently wrong the moment a segment moves, and
31
+ * there is no compiler that notices. It lives in `@camstack/types` because both
32
+ * an addon and the UI packages must reach it, and addons may not import each
33
+ * other.
34
+ *
35
+ * `parseMediaOwnerKey` returns `null` for anything it cannot read, and never
36
+ * throws: it sits on the media READ path, where an exception takes out every
37
+ * thumbnail and a guess puts the wrong image on screen. A legacy `event:` key
38
+ * is therefore unreadable BY DESIGN - on this hub the 299 883 resolvable ones
39
+ * are rewritten by the D474 data migration, and the 676 that remain were
40
+ * already orphaned, their event having aged out before it.
41
+ */
42
+ /**
43
+ * Owner types, i.e. the tables that own media.
44
+ *
45
+ * `motion` / `object` / `audio` are the three event tables; `event` is
46
+ * deliberately absent and must not be re-added - it is the ambiguity this
47
+ * module exists to remove.
48
+ *
49
+ * This list must cover `OWNER_KINDS` in
50
+ * `addon-post-analysis/src/pipeline-analytics/store/media-store.ts`, which is
51
+ * the AUTHORITY on what may own media. I first derived it from the prefixes
52
+ * actually present on the live hub and so omitted `vehicle` and `scene`: both
53
+ * are declared owner kinds with no rows today, and the parser would have
54
+ * rejected their keys the day one appeared. A list derived from data is a list
55
+ * that is correct until the data changes.
56
+ */
57
+ var MEDIA_OWNER_TYPES = [
58
+ "track",
59
+ "summary",
60
+ "face",
61
+ "identity",
62
+ "plate",
63
+ "vehicle",
64
+ "scene",
65
+ "motion",
66
+ "object",
67
+ "audio"
68
+ ];
69
+ var OWNER_TYPES = new Set(MEDIA_OWNER_TYPES);
70
+ /** Digits only. `Number('')` is 0 and `Number(' ')` is 0, so neither is used. */
71
+ var DIGITS = /^\d+$/;
72
+ function isOwnerType(value) {
73
+ return OWNER_TYPES.has(value);
74
+ }
75
+ /**
76
+ * Read a media key. `null` when it is not one - an unknown owner type, a legacy
77
+ * `event:` key, a missing segment, or a fourth segment that is not a timestamp.
78
+ *
79
+ * `fileKind` is returned as a plain string rather than validated against
80
+ * `MediaFileKindEnum`: kinds have been RETIRED over time (`crop`,
81
+ * `fullFrameBoxed`) and rows carrying them still exist, so a parser that
82
+ * rejected them would make historical media unreadable while claiming the key
83
+ * was malformed.
84
+ */
85
+ function parseMediaOwnerKey(key) {
86
+ const parts = key.split(":");
87
+ if (parts.length !== 3 && parts.length !== 4) return null;
88
+ const [ownerType, ownerId, fileKind, timestamp] = parts;
89
+ if (ownerType === void 0 || !isOwnerType(ownerType)) return null;
90
+ if (ownerId === void 0 || ownerId.length === 0) return null;
91
+ if (fileKind === void 0 || fileKind.length === 0) return null;
92
+ if (timestamp === void 0) return {
93
+ ownerType,
94
+ ownerId,
95
+ fileKind
96
+ };
97
+ if (!DIGITS.test(timestamp)) return null;
98
+ return {
99
+ ownerType,
100
+ ownerId,
101
+ fileKind,
102
+ timestampMs: Number(timestamp)
103
+ };
104
+ }
105
+ /** Build a media key. The timestamp segment is omitted when there is none. */
106
+ function formatMediaOwnerKey(key) {
107
+ const head = `${key.ownerType}:${key.ownerId}:${key.fileKind}`;
108
+ return key.timestampMs === void 0 ? head : `${head}:${key.timestampMs}`;
109
+ }
110
+ /**
111
+ * The owner types that are event tables, in the order the event-media resolver
112
+ * should consider them. Exported so a consumer asking "is this key an event?"
113
+ * does not re-spell the list and drift from it.
114
+ */
115
+ var EVENT_OWNER_TYPES = [
116
+ "motion",
117
+ "object",
118
+ "audio"
119
+ ];
120
+ var EVENT_OWNER_TYPE_SET = new Set(EVENT_OWNER_TYPES);
121
+ /** True when this key's owner is one of the three event tables. */
122
+ function isEventOwnerType(ownerType) {
123
+ return EVENT_OWNER_TYPE_SET.has(ownerType);
124
+ }
125
+ //#endregion
8
126
  //#region src/addon/build-addon-route-provider.ts
9
127
  /**
10
128
  * Build an `IAddonRouteProvider` from a list of routes. Implements
@@ -9723,8 +9841,17 @@ var settingsStoreCapability = {
9723
9841
  insert: require_sleep.method(zod.z.object({
9724
9842
  namespace: zod.z.string().optional(),
9725
9843
  collection: zod.z.string(),
9726
- record: SettingsRecordSchema
9727
- }), zod.z.void(), { kind: "mutation" }),
9844
+ record: zod.z.object({
9845
+ id: zod.z.string().optional(),
9846
+ data: zod.z.record(zod.z.string(), zod.z.unknown())
9847
+ })
9848
+ }), zod.z.object({
9849
+ /**
9850
+ * The id the row ACTUALLY got (D473): the one supplied, the UUID minted
9851
+ * for an absent one, or the ROWID SQLite assigned on an `INTEGER`
9852
+ * primary key — which is the only place an auto key is knowable.
9853
+ */
9854
+ id: zod.z.union([zod.z.string(), zod.z.number()]) }), { kind: "mutation" }),
9728
9855
  /**
9729
9856
  * Insert MANY records in ONE transaction, returning how many landed.
9730
9857
  *
@@ -9987,8 +10114,17 @@ var dataStoreProviderCapability = {
9987
10114
  insert: require_sleep.method(zod.z.object({
9988
10115
  namespace: zod.z.string().optional(),
9989
10116
  collection: zod.z.string(),
9990
- record: SettingsRecordSchema
9991
- }), zod.z.void(), {
10117
+ record: zod.z.object({
10118
+ id: zod.z.string().optional(),
10119
+ data: zod.z.record(zod.z.string(), zod.z.unknown())
10120
+ })
10121
+ }), zod.z.object({
10122
+ /**
10123
+ * The id the row ACTUALLY got (D473): the one supplied, the UUID minted
10124
+ * for an absent one, or the ROWID SQLite assigned on an `INTEGER`
10125
+ * primary key — which is the only place an auto key is knowable.
10126
+ */
10127
+ id: zod.z.union([zod.z.string(), zod.z.number()]) }), {
9992
10128
  kind: "mutation",
9993
10129
  auth: "admin"
9994
10130
  }),
@@ -19459,7 +19595,20 @@ var TrackSchema = zod.z.object({
19459
19595
  ...TrackRetrainFields
19460
19596
  });
19461
19597
  var BaseEventFields = {
19462
- id: zod.z.string(),
19598
+ /**
19599
+ * A SQLite ROWID, assigned by the database (D474).
19600
+ *
19601
+ * Was a 36-character UUID and cost 263 MB of a 1 117 MB database — paid
19602
+ * TWICE per row, in the row and in the primary-key index, across 2.1 million
19603
+ * motion, audio and object events. An `INTEGER PRIMARY KEY` in SQLite **is**
19604
+ * the rowid: the table itself is that B-tree, so the index stops existing
19605
+ * rather than getting smaller. No shorter string does that.
19606
+ *
19607
+ * Defined once here for all three event kinds, which is why they move
19608
+ * together: a per-table migration would have forked this and
19609
+ * `COMMON_BASE_COLUMNS` and reunited them two stages later.
19610
+ */
19611
+ id: zod.z.number().int(),
19463
19612
  deviceId: zod.z.number(),
19464
19613
  timestamp: zod.z.number()
19465
19614
  };
@@ -19478,7 +19627,34 @@ var MotionEventSchema = zod.z.object({
19478
19627
  /** Omitted in slim projection. */
19479
19628
  frameHeight: zod.z.number().optional(),
19480
19629
  /** Populated by B5 (recording playback URL for this event). */
19481
- mediaUrl: zod.z.string().optional()
19630
+ mediaUrl: zod.z.string().optional(),
19631
+ /**
19632
+ * One row per motion EPISODE, not one per push (D475). `null` while the
19633
+ * episode is still open — a further rising edge extends it in place rather
19634
+ * than inserting a new row. Set once, at close, to `lastOnAt - startedAt`
19635
+ * (the span from the first rising edge to the LAST one, deliberately NOT
19636
+ * `closedAt - startedAt` — the close delay is a quiet CONFIRMATION, not
19637
+ * movement, and folding it in would report `MOTION_CLOSE_AFTER_MS` of
19638
+ * motion for an instantaneous trigger).
19639
+ *
19640
+ * **Absent** (not merely `null`) on a row written before D475 — that means
19641
+ * "closed the old way, before this column existed", never "still open".
19642
+ * Nothing in this codebase may read an absent `durationMs` as an open
19643
+ * episode; only `null` means open.
19644
+ */
19645
+ durationMs: zod.z.number().nullable().optional(),
19646
+ /**
19647
+ * Ms offsets from `timestamp` (the episode's own first rising edge, so the
19648
+ * first entry is always `0`) of every genuine off→on transition the
19649
+ * episode saw — "ogni evento on si deve salvare" (D475). NOT one entry per
19650
+ * push: a firmware source that keepalives at ~1 Hz for the whole burst
19651
+ * (Reolink, Hikvision) produces exactly one edge; a source that reports an
19652
+ * explicit `false` mid-episode and then resumes before the quiet window
19653
+ * elapses produces another. Stored compactly — see `motion-edge-codec.ts`
19654
+ * — and decoded back to this shape on read. Absent/empty on a legacy row,
19655
+ * which must never be read as "no episode happened here".
19656
+ */
19657
+ edges: zod.z.array(zod.z.number()).readonly().optional()
19482
19658
  });
19483
19659
  /**
19484
19660
  * Which detection SOURCE produced an object event. `pipeline` = the ML
@@ -19541,6 +19717,23 @@ var ObjectEventSchema = zod.z.object({
19541
19717
  * includes it (it is light). Absent on rows written before this field.
19542
19718
  */
19543
19719
  frameId: zod.z.string().optional(),
19720
+ /**
19721
+ * A PRODUCER-chosen key that makes a synthetic event's emission idempotent
19722
+ * (D474).
19723
+ *
19724
+ * Only the package detector writes it, and it exists because the event id
19725
+ * stopped being choosable: the delivery and pick-up rows used to BE their
19726
+ * dedupe key (`pa-pkg-<entryId>-delivered`), which is how "never emit a
19727
+ * second delivery for this entry" survived a restart. An `INTEGER` rowid is
19728
+ * assigned by SQLite, so that key had to move off the primary key rather
19729
+ * than be dropped — a detector that cannot recognise its own row re-delivers
19730
+ * every parcel on every boot.
19731
+ *
19732
+ * Absent on every other object event, and on every row written before this
19733
+ * field. Never a substitute for `id`: it is unique per (producer, occasion),
19734
+ * not per row, and nothing addresses a row by it.
19735
+ */
19736
+ idempotencyKey: zod.z.string().optional(),
19544
19737
  /** Omitted in slim projection. */
19545
19738
  trackId: zod.z.string().optional(),
19546
19739
  className: zod.z.string(),
@@ -21271,6 +21464,14 @@ var NativeCropResultSchema = zod.z.object({
21271
21464
  * set `encodeJpeg: true`; `bytes` is then absent.
21272
21465
  */
21273
21466
  jpeg: zod.z.string().optional(),
21467
+ /**
21468
+ * The SAME compressed JPEG as `jpeg`, as bytes (D462). Present instead of
21469
+ * `jpeg` when the request set `acceptJpegBytes`; a request that did not gets
21470
+ * `jpeg` exactly as before. MsgPack and the mesh leg both carry binary —
21471
+ * `bytes` above has crossed this boundary as a `Uint8Array` all along — so
21472
+ * base64 was buying nothing but a multi-megabyte string in the relay's heap.
21473
+ */
21474
+ jpegBytes: zod.z.instanceof(Uint8Array).optional(),
21274
21475
  width: zod.z.number().int().positive(),
21275
21476
  height: zod.z.number().int().positive(),
21276
21477
  /**
@@ -21337,7 +21538,14 @@ var ParkTrackFrameResultSchema = zod.z.discriminatedUnion("parked", [zod.z.objec
21337
21538
  })]);
21338
21539
  /** A retrieved parcel — the runner's own JPEG, base64 for the wire. */
21339
21540
  var ParkedTrackFrameSchema = zod.z.object({
21340
- jpeg: zod.z.string(),
21541
+ /**
21542
+ * Base64 JPEG — the pre-D462 wire. OPTIONAL since D462: a request that set
21543
+ * `acceptJpegBytes` is answered in `jpegBytes` and this is then absent.
21544
+ * Exactly one of the two is present.
21545
+ */
21546
+ jpeg: zod.z.string().optional(),
21547
+ /** The same JPEG as bytes, for a caller that declared it reads them (D462). */
21548
+ jpegBytes: zod.z.instanceof(Uint8Array).optional(),
21341
21549
  width: zod.z.number().int().positive(),
21342
21550
  height: zod.z.number().int().positive(),
21343
21551
  /** The frame instant the parcel shows (the caller's clock, echoed back). */
@@ -22176,6 +22384,13 @@ var pipelineRunnerCapability = {
22176
22384
  bbox: NativeCropBboxSchema,
22177
22385
  maxWidth: zod.z.number().int().positive().optional(),
22178
22386
  /**
22387
+ * The caller reads a `Uint8Array` (D462). When set, a JPEG answer comes
22388
+ * back in `jpegBytes` instead of base64 `jpeg`. Absent means the old
22389
+ * wire — never assume consent: a pre-D462 caller parses the field as
22390
+ * base64 and bytes would decode to garbage rather than fail.
22391
+ */
22392
+ acceptJpegBytes: zod.z.boolean().optional(),
22393
+ /**
22179
22394
  * When `true`, the runner encodes the resolved crop to JPEG ON THE
22180
22395
  * OWNING NODE and returns it in `jpeg` (base64) INSTEAD of raw `bytes`.
22181
22396
  * Callers set this for CROSS-NODE fetches (`handle.nodeId` is a remote
@@ -22348,7 +22563,14 @@ var pipelineRunnerCapability = {
22348
22563
  getParkedTrackFrame: require_sleep.method(zod.z.object({
22349
22564
  deviceId: zod.z.number(),
22350
22565
  trackId: zod.z.string(),
22351
- kind: ParkedFrameKindSchema
22566
+ kind: ParkedFrameKindSchema,
22567
+ /**
22568
+ * The caller reads a `Uint8Array` (D462). When set, a JPEG answer comes
22569
+ * back in `jpegBytes` instead of base64 `jpeg`. Absent means the old
22570
+ * wire — never assume consent: a pre-D462 caller parses the field as
22571
+ * base64 and bytes would decode to garbage rather than fail.
22572
+ */
22573
+ acceptJpegBytes: zod.z.boolean().optional()
22352
22574
  }), ParkedTrackFrameSchema.nullable()),
22353
22575
  /**
22354
22576
  * Drop every parcel of a track — the hub closed it. Idempotent. A track
@@ -30644,14 +30866,72 @@ authKey: zod.z.string().optional() }), zod.z.object({
30644
30866
  * (alert-center, advanced-notifier) can subscribe once and receive
30645
30867
  * motion from every camera.
30646
30868
  */
30869
+ /**
30870
+ * How long after a camera's last rising edge `pipeline-analytics` closes the
30871
+ * motion EPISODE row it kept open for it (D475) — "il delay della cap", in
30872
+ * the operator's words. One authority for the whole system: every provider
30873
+ * that seeds `autoClearAfterMs` on a `Camera` device writes this SAME
30874
+ * constant while `detected: true` (never its own number — Hikvision used to
30875
+ * seed its internal 3 s inactivity timer here, which is a different clock for
30876
+ * a different purpose), and `MotionEpisodeTracker` imports it directly rather
30877
+ * than reading the live cap value on the hot path. A `Sensor` device (HA
30878
+ * binary sensor, Homematic) gets a genuine push both ways and has no episode
30879
+ * to close on a timer, so it writes `null`, never this constant.
30880
+ */
30881
+ var MOTION_CLOSE_AFTER_MS = 15e3;
30647
30882
  var MotionStatusSchema = zod.z.object({
30648
30883
  detected: zod.z.boolean(),
30649
30884
  /** Ms epoch of the last detected-true observation. Null if never detected. */
30650
30885
  lastDetectedAt: zod.z.number().nullable(),
30651
30886
  /**
30652
- * Ms after which `detected` auto-reverts to false if no fresh push
30653
- * arrives. Null means the provider leaves detected state until a
30654
- * native "clear" event.
30887
+ * `MOTION_CLOSE_AFTER_MS` while `detected: true` on a `Camera` device,
30888
+ * `null` while false and on every `Sensor` device (D475) — see that
30889
+ * constant's doc for the one-authority rule.
30890
+ *
30891
+ * ## Reading this field still arms nothing
30892
+ *
30893
+ * It reads like an instruction to the consumer ("revert after N ms if
30894
+ * no fresh push arrives") and it is not one: nothing in this repo reads
30895
+ * the LIVE cap value to drive a timer. `pipeline-analytics`'s motion-episode
30896
+ * close DOES now use the same number — `MOTION_CLOSE_AFTER_MS` — but as an
30897
+ * imported constant, not as a read of `device.state.motion.value`, so this
30898
+ * field stays what it always was: DESCRIPTIVE output, mirroring an answer
30899
+ * computed elsewhere. Building a self-clear timer out of a READ of this
30900
+ * field would add a second falling-edge authority beside whichever one
30901
+ * already owns the device, and two that can disagree are worse than one.
30902
+ * Consumers that need a falling edge SHAPED differently — held open across
30903
+ * a flapping source — debounce on their own side and say so, as
30904
+ * `addon-export-alexa/src/motion-clear-hold.ts` and
30905
+ * `addon-export-hap`'s `RESET_DEBOUNCE_MS` both do.
30906
+ *
30907
+ * ## Who writes it
30908
+ *
30909
+ * - **Cameras** — the runner's phase machine, `active → watching` on
30910
+ * `cooldown_expired`, which then writes this slice with
30911
+ * `detected: false` (`handlePhaseChanged` in
30912
+ * `pipeline-runner/index.ts`). It produces the FALLING edge, which
30913
+ * matters most for the sources that only ever push a rising one:
30914
+ * Reolink emits `MotionOnMotionChanged { detected: true }` and never
30915
+ * a false.
30916
+ * - **Sensors** (Home Assistant binary sensors, Homematic) — the
30917
+ * provider pushes the false itself, from the upstream system's own
30918
+ * state change. No phase machine is involved.
30919
+ *
30920
+ * ### The phase machine is CANONICAL, not sole — and that is a defect
30921
+ *
30922
+ * An earlier revision of this docblock (mine, 2026-09-12) claimed the
30923
+ * phase machine is the sole writer for a camera. It is not.
30924
+ * `hikvision-camera.ts:3464` and `amcrest-camera.ts:445` both call
30925
+ * `setCapSlice(motionCapability, …)` on their own rising edge, and
30926
+ * Hikvision's comment says why: it read THIS docblock, agreed the
30927
+ * runner is canonical, and wrote anyway to avoid per-tick churn. So
30928
+ * two authorities can disagree about one slice, which this repo
30929
+ * forbids, and the doc said otherwise — which is worse than saying
30930
+ * nothing, because it reads as verification.
30931
+ *
30932
+ * This predates D475 and is not fixed there: the fix touches every
30933
+ * camera provider. Recorded in D475's Consequences. Do not restore the
30934
+ * "sole writer" wording without also removing the other writers.
30655
30935
  */
30656
30936
  autoClearAfterMs: zod.z.number().nullable()
30657
30937
  });
@@ -30721,7 +31001,11 @@ onMotionChanged: { data: MotionOnMotionChangedDataSchema } },
30721
31001
  */
30722
31002
  runtimeState: MotionStatusSchema,
30723
31003
  /**
30724
- * Runtime-state durability: **session** — self-clearing by construction (`autoClearAfterMs`); a restored `detected: true` is a frozen event, and the next frame re-publishes the real one.
31004
+ * Runtime-state durability: **session** — every writer of this slice
31005
+ * writes only on an EDGE, so a restored `detected: true` would stay
31006
+ * frozen until the next one instead of being corrected. The next edge
31007
+ * re-publishes the real state. (On who the writers are, and why there
31008
+ * is more than one, see `autoClearAfterMs` above.)
30725
31009
  *
30726
31010
  * See `RuntimeStateDurability`. Enforced by
30727
31011
  * `scripts/check-runtime-state-durability.ts`.
@@ -56003,6 +56287,7 @@ exports.DoorbellStatusSchema = DoorbellStatusSchema;
56003
56287
  exports.EVENTFUL_CAP_NAMES = EVENTFUL_CAP_NAMES;
56004
56288
  exports.EVENT_DENSITY_BATCH_MAX = EVENT_DENSITY_BATCH_MAX;
56005
56289
  exports.EVENT_KIND_BY_CAP = EVENT_KIND_BY_CAP;
56290
+ exports.EVENT_OWNER_TYPES = EVENT_OWNER_TYPES;
56006
56291
  exports.EVENT_PAD_MS = EVENT_PAD_MS;
56007
56292
  exports.EVENT_TAXONOMY = EVENT_TAXONOMY;
56008
56293
  exports.EXPORT_DENSE_MAX_RANGES = EXPORT_DENSE_MAX_RANGES;
@@ -56193,10 +56478,12 @@ exports.MAX_KEYS = MAX_KEYS;
56193
56478
  exports.MAX_REASONS_PER_KEY = MAX_REASONS_PER_KEY;
56194
56479
  exports.MAX_SENSOR_TRIGGER_DEVICES = MAX_SENSOR_TRIGGER_DEVICES;
56195
56480
  exports.MAX_TRACK_DEBUG_NOTE_LEN = MAX_TRACK_DEBUG_NOTE_LEN;
56481
+ exports.MEDIA_OWNER_TYPES = MEDIA_OWNER_TYPES;
56196
56482
  exports.METHOD_ACCESS_MAP = METHOD_ACCESS_MAP;
56197
56483
  exports.METHOD_DEVICE_SELECTORS = METHOD_DEVICE_SELECTORS;
56198
56484
  exports.MODEL_FORMATS = MODEL_FORMATS;
56199
56485
  exports.MODEL_PROVIDER_IDS = MODEL_PROVIDER_IDS;
56486
+ exports.MOTION_CLOSE_AFTER_MS = MOTION_CLOSE_AFTER_MS;
56200
56487
  exports.MOTION_TRIGGER_FEATURE = MOTION_TRIGGER_FEATURE;
56201
56488
  exports.ManagedModelCatalogEntrySchema = ManagedModelCatalogEntrySchema;
56202
56489
  exports.ManagedModelExtraFileSchema = ManagedModelExtraFileSchema;
@@ -56968,6 +57255,7 @@ exports.floodCapability = floodCapability;
56968
57255
  exports.foldSnapshotByFunction = foldSnapshotByFunction;
56969
57256
  exports.formatForBackend = formatForBackend;
56970
57257
  exports.formatForRuntime = formatForRuntime;
57258
+ exports.formatMediaOwnerKey = formatMediaOwnerKey;
56971
57259
  exports.gasCapability = gasCapability;
56972
57260
  exports.gbToBytes = gbToBytes;
56973
57261
  exports.generateAutomationBlock = generateAutomationBlock;
@@ -57003,6 +57291,7 @@ exports.isDetectionMacroClass = isDetectionMacroClass;
57003
57291
  exports.isDeviceConfigCap = require_sleep.isDeviceConfigCap;
57004
57292
  exports.isDeviceScopedCap = require_sleep.isDeviceScopedCap;
57005
57293
  exports.isEvent = require_sleep.isEvent;
57294
+ exports.isEventOwnerType = isEventOwnerType;
57006
57295
  exports.isFirstLevelMacroClass = isFirstLevelMacroClass;
57007
57296
  exports.isIsolatedBuiltin = isIsolatedBuiltin;
57008
57297
  exports.isLocationEnabled = isLocationEnabled;
@@ -57090,6 +57379,7 @@ exports.parseExpression = parseExpression;
57090
57379
  exports.parseJsonArray = require_sleep.parseJsonArray;
57091
57380
  exports.parseJsonObject = require_sleep.parseJsonObject;
57092
57381
  exports.parseJsonUnknown = require_sleep.parseJsonUnknown;
57382
+ exports.parseMediaOwnerKey = parseMediaOwnerKey;
57093
57383
  exports.parseProcStatus = parseProcStatus;
57094
57384
  exports.parseProfileBrokerId = require_sleep.parseProfileBrokerId;
57095
57385
  exports.parseRuleSection = parseRuleSection;