@camstack/addon-post-analysis 1.2.293 → 1.2.294

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.
@@ -5401,7 +5401,7 @@ var ZodIssueCode = {
5401
5401
  var ZodFirstPartyTypeKind;
5402
5402
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5403
5403
  //#endregion
5404
- //#region ../types/dist/sleep-jkRQgtSc.mjs
5404
+ //#region ../types/dist/sleep-E6eD4yQS.mjs
5405
5405
  /**
5406
5406
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5407
5407
  * window to float samples (D455).
@@ -7016,6 +7016,10 @@ function toNodeId(idOrRunnerId) {
7016
7016
  const head = idOrRunnerId.split("/")[0];
7017
7017
  return head === void 0 || head.length === 0 ? idOrRunnerId : head;
7018
7018
  }
7019
+ object({
7020
+ field: string().min(1),
7021
+ on: literal("advance")
7022
+ });
7019
7023
  /**
7020
7024
  * Output schema shared by the contribution + live methods.
7021
7025
  *
@@ -7656,7 +7660,7 @@ function errMsg(err) {
7656
7660
  return String(err);
7657
7661
  }
7658
7662
  //#endregion
7659
- //#region ../types/dist/composition-CPFIlFfw.mjs
7663
+ //#region ../types/dist/composition-D5BQywfe.mjs
7660
7664
  /**
7661
7665
  * Deterministic SHA-256 hash of an arbitrary serialisable value. The
7662
7666
  * canonical form sorts object keys alphabetically at every depth so two
@@ -7689,6 +7693,173 @@ function replaceWithSortedKeys(_key, value) {
7689
7693
  return value;
7690
7694
  }
7691
7695
  /**
7696
+ * LA tabella "quale booleano di questo tipo di device conta come ALTO", e il
7697
+ * valutatore puro del suo FRONTE.
7698
+ *
7699
+ * Viveva dentro il builtin virtual-doorbell
7700
+ * (`@camstack/system` — `builtins/doorbell/trigger-engine.ts`) e i suoi
7701
+ * predicati erano privati al modulo. Il recorder ne ha bisogno per il trigger
7702
+ * `RecordingTriggers.sensorDeviceIds`: copiarla avrebbe creato la SECONDA
7703
+ * tabella, che diverge alla prima cap aggiunta e il cui sintomo — "il sensore
7704
+ * fa suonare il campanello ma non registra" — è esattamente D62. Quindi si
7705
+ * SPOSTA qui e il doorbell la ri-esporta.
7706
+ *
7707
+ * ⚠ NON è `DEVICE_STATE_READERS` (`catalogs/device-state-vocabulary.ts`), e le
7708
+ * due non vanno unificate: quella risponde a "qual è la PAROLA di stato per una
7709
+ * regola" (e include `presence`, `cover`, `alarm-panel`), questa a "qual è il
7710
+ * booleano il cui FRONTE conta". Vocabolari deliberatamente diversi.
7711
+ */
7712
+ /**
7713
+ * Known binary / switch source caps → the boolean slice field whose
7714
+ * false→true rise counts as ACTIVE. Every entry is "fire on active".
7715
+ * Sensors whose "active" reading is not a plain boolean (presence's string
7716
+ * state, connectivity's connected flag) are deliberately excluded — a
7717
+ * reconnect is not a doorbell press, and it is not a recording either.
7718
+ */
7719
+ var SOURCE_CAP_ACTIVE_FIELD = {
7720
+ contact: "entryOpen",
7721
+ binary: "on",
7722
+ switch: "on",
7723
+ motion: "detected",
7724
+ flood: "flooded",
7725
+ gas: "detected",
7726
+ smoke: "detected",
7727
+ "carbon-monoxide": "detected",
7728
+ vibration: "detected",
7729
+ tamper: "tampered"
7730
+ };
7731
+ /**
7732
+ * The same caps → the slice field carrying the ms-epoch timestamp of the
7733
+ * last transition. Every source cap MUST appear here (guarded by a spec):
7734
+ * without a transition timestamp the evaluator cannot tell a genuine rise
7735
+ * from a boot-time hydration when the FIRST slice it ever sees is already
7736
+ * active, and errs towards silence — swallowing the rise.
7737
+ *
7738
+ * These timestamps are UPSTREAM ones, not ingest ones: the Home Assistant
7739
+ * provider derives them from `state.last_changed`, so they survive our own
7740
+ * restarts and correctly read as "hours ago" for a state that has been
7741
+ * active for hours. `motion` names its rise timestamp `lastDetectedAt`.
7742
+ */
7743
+ var SOURCE_CAP_CHANGED_AT_FIELD = {
7744
+ contact: "lastChangedAt",
7745
+ binary: "lastChangedAt",
7746
+ switch: "lastChangedAt",
7747
+ motion: "lastDetectedAt",
7748
+ flood: "lastChangedAt",
7749
+ gas: "lastChangedAt",
7750
+ smoke: "lastChangedAt",
7751
+ "carbon-monoxide": "lastChangedAt",
7752
+ vibration: "lastChangedAt",
7753
+ tamper: "lastChangedAt"
7754
+ };
7755
+ /** Cap names whose presence in a device's bindings qualify it as a source. */
7756
+ var SOURCE_CAPS = Object.keys(SOURCE_CAP_ACTIVE_FIELD);
7757
+ /** True when a cap is a recognised binary/switch source. */
7758
+ function isSourceCap(capName) {
7759
+ return Object.prototype.hasOwnProperty.call(SOURCE_CAP_ACTIVE_FIELD, capName);
7760
+ }
7761
+ /** Extract the "active" boolean a source cap's slice carries, or null when
7762
+ * the cap is unknown or the field is missing / non-boolean. */
7763
+ function sliceActiveValue(capName, slice) {
7764
+ const field = SOURCE_CAP_ACTIVE_FIELD[capName];
7765
+ if (field === void 0) return null;
7766
+ const raw = slice[field];
7767
+ return typeof raw === "boolean" ? raw : null;
7768
+ }
7769
+ /** Ms-epoch transition timestamp a source cap's slice carries, or null when
7770
+ * it is absent, non-numeric or the zero "never observed" sentinel. */
7771
+ function sliceChangedAt(capName, slice) {
7772
+ const field = SOURCE_CAP_CHANGED_AT_FIELD[capName];
7773
+ if (field === void 0) return null;
7774
+ const raw = slice[field];
7775
+ if (typeof raw !== "number" || !Number.isFinite(raw) || raw <= 0) return null;
7776
+ return raw;
7777
+ }
7778
+ /**
7779
+ * How recent a source's own transition timestamp must be for a FIRST
7780
+ * sighting that is already active to count as a genuine rise rather than a
7781
+ * hydration of long-standing state.
7782
+ */
7783
+ var DEFAULT_FIRST_SIGHTING_FRESHNESS_MS = 3e4;
7784
+ /**
7785
+ * The source-independent edge rule. The caller supplies an already extracted
7786
+ * boolean level and source timestamp; this function owns first-sighting
7787
+ * freshness and false-to-true detection.
7788
+ */
7789
+ function evaluateSensorLevelEdge(input) {
7790
+ const timestamp = input.changedAt;
7791
+ const freshFloor = Math.max(input.startedAtMs, input.nowMs - input.firstSightingFreshnessMs);
7792
+ const firstRise = input.priorLevel === void 0 && input.level && timestamp !== null && Number.isFinite(timestamp) && timestamp >= freshFloor;
7793
+ const transitionRise = input.priorLevel === false && input.level && timestamp !== null && Number.isFinite(timestamp);
7794
+ if ((firstRise || transitionRise) && timestamp !== null) return {
7795
+ kind: "rise",
7796
+ timestamp
7797
+ };
7798
+ return {
7799
+ kind: "none",
7800
+ nextPriorLevel: input.level
7801
+ };
7802
+ }
7803
+ /**
7804
+ * IL fronte. Puro: nessun orologio proprio, nessuna memoria — il chiamante
7805
+ * porta `prior`, `nowMs` e il proprio `startedAtMs`.
7806
+ *
7807
+ * Il caso della PRIMA slice già attiva è trattato esplicitamente e vale come
7808
+ * fronte solo se il timestamp UPSTREAM della transizione è posteriore a
7809
+ * `startedAtMs` **e** entro `firstSightingFreshnessMs`. Entrambe le metà
7810
+ * servono: la sola freschezza scatterebbe su un'idratazione al boot di uno
7811
+ * stato flippato pochi secondi prima del riavvio, e il solo "dopo che abbiamo
7812
+ * iniziato" scatterebbe, su un processo di lunga vita, per una sorgente
7813
+ * adottata oggi il cui stato è cambiato ieri. Il caso ambiguo ERRA VERSO IL
7814
+ * SILENZIO e lo dichiara (`baseline-seeded-stale-active`).
7815
+ */
7816
+ function evaluateSensorEdge(input) {
7817
+ const value = sliceActiveValue(input.capName, input.slice);
7818
+ if (value === null) return {
7819
+ edge: "none",
7820
+ value: null,
7821
+ reason: isSourceCap(input.capName) ? "non-boolean-value" : "unknown-cap"
7822
+ };
7823
+ if (evaluateSensorLevelEdge({
7824
+ level: value,
7825
+ changedAt: sliceChangedAt(input.capName, input.slice),
7826
+ priorLevel: input.prior,
7827
+ startedAtMs: input.startedAtMs,
7828
+ nowMs: input.nowMs,
7829
+ firstSightingFreshnessMs: input.firstSightingFreshnessMs
7830
+ }).kind === "rise") return {
7831
+ edge: "rising",
7832
+ value: true
7833
+ };
7834
+ if (input.prior === void 0) {
7835
+ if (!value) return {
7836
+ edge: "none",
7837
+ value,
7838
+ reason: "baseline-seeded-inactive"
7839
+ };
7840
+ return {
7841
+ edge: "none",
7842
+ value,
7843
+ reason: "baseline-seeded-stale-active"
7844
+ };
7845
+ }
7846
+ if (input.prior === value) return {
7847
+ edge: "none",
7848
+ value,
7849
+ reason: "no-change"
7850
+ };
7851
+ if (!value) return {
7852
+ edge: "none",
7853
+ value,
7854
+ reason: "falling-edge"
7855
+ };
7856
+ return {
7857
+ edge: "none",
7858
+ value,
7859
+ reason: "missing-timestamp"
7860
+ };
7861
+ }
7862
+ /**
7692
7863
  * Error types for the safe expression engine. Two distinct classes so callers
7693
7864
  * can tell a compile-time (grammar) failure from a runtime (evaluation)
7694
7865
  * failure — both are non-fatal to the host: read paths degrade to "skip link".
@@ -7885,6 +8056,20 @@ var table = {
7885
8056
  const present = args.flatMap((a, i) => a === null ? [] : [asFiniteNumber(a, "latest", i)]);
7886
8057
  return present.length === 0 ? null : finiteResult(Math.max(...present), "latest");
7887
8058
  }
8059
+ },
8060
+ rose: {
8061
+ minArgs: 2,
8062
+ maxArgs: 3,
8063
+ apply: () => {
8064
+ throw new ExpressionEvalError("rose: stateful evaluation context is required");
8065
+ }
8066
+ },
8067
+ count: {
8068
+ minArgs: 1,
8069
+ maxArgs: 1,
8070
+ apply: () => {
8071
+ throw new ExpressionEvalError("count: stateful evaluation context is required");
8072
+ }
7888
8073
  }
7889
8074
  };
7890
8075
  Object.freeze(Object.assign(Object.create(null), table));
@@ -8399,6 +8584,7 @@ var CompositionItemEntrySchema = object({
8399
8584
  var CompositionFeatureSchema = discriminatedUnion("kind", [object({
8400
8585
  kind: literal("fields"),
8401
8586
  cap: string().min(1),
8587
+ enabled: boolean().optional(),
8402
8588
  fields: record(string().min(1), CompositionFieldSourceSchema).refine((fields) => Object.keys(fields).length <= 32, { message: `at most 32 fields per capability` }),
8403
8589
  /**
8404
8590
  * Items of the cap's item array, keyed by item key (D663). Naming `items`
@@ -8410,6 +8596,7 @@ var CompositionFeatureSchema = discriminatedUnion("kind", [object({
8410
8596
  }), object({
8411
8597
  kind: literal("passthrough"),
8412
8598
  cap: string().min(1),
8599
+ enabled: boolean().optional(),
8413
8600
  source: CompositionSourceRefSchema
8414
8601
  })]);
8415
8602
  var CompositionSchema = object({
@@ -13530,6 +13717,15 @@ var cameraStreamsCapability = {
13530
13717
  function kebabToCamel(s) {
13531
13718
  return s.replace(/-([a-z])/g, (_, c) => c.toUpperCase());
13532
13719
  }
13720
+ EventCategory.DoorbellOnPressed;
13721
+ var CompositionEventPlanSchema = object({
13722
+ featureIndex: number().int().nonnegative(),
13723
+ cap: string(),
13724
+ eventName: string(),
13725
+ category: _enum(EventCategory),
13726
+ stateField: string(),
13727
+ fieldKey: string()
13728
+ });
13533
13729
  /** One refusal, named (D391). `path` points into the composition, e.g. `features[0].fields.celsius`. */
13534
13730
  var CompositionProblemSchema = object({
13535
13731
  code: _enum([
@@ -13579,12 +13775,14 @@ var CompositionUnavailableModeSchema = _enum([
13579
13775
  ]);
13580
13776
  /**
13581
13777
  * `derived` reads a source · `clock` reads only `now`, recomputed when a sibling
13582
- * field of its cap changes value · `constant` reads nothing, computed once.
13778
+ * field of its cap changes value · `constant` reads nothing, computed once ·
13779
+ * `accumulator` advances from the target's seed/current output.
13583
13780
  */
13584
13781
  var CompositionFieldRoleSchema = _enum([
13585
13782
  "derived",
13586
13783
  "clock",
13587
- "constant"
13784
+ "constant",
13785
+ "accumulator"
13588
13786
  ]);
13589
13787
  /** The item a planned field belongs to; its `path` is then the dotted path INSIDE the item. */
13590
13788
  var CompositionFieldItemSchema = object({
@@ -13620,6 +13818,7 @@ var CompositionFeatureModeSchema = _enum([
13620
13818
  "replace"
13621
13819
  ]);
13622
13820
  var CompositionFeaturePlanSchema = object({
13821
+ /** Index in the stored feature array; disabled features are omitted rather than re-indexed. */
13623
13822
  featureIndex: number().int().nonnegative(),
13624
13823
  cap: string(),
13625
13824
  mode: CompositionFeatureModeSchema
@@ -13628,7 +13827,8 @@ var CompositionValidationSchema = object({
13628
13827
  ok: boolean(),
13629
13828
  problems: array(CompositionProblemSchema),
13630
13829
  fields: array(CompositionFieldPlanSchema),
13631
- features: array(CompositionFeaturePlanSchema)
13830
+ features: array(CompositionFeaturePlanSchema),
13831
+ events: array(CompositionEventPlanSchema)
13632
13832
  });
13633
13833
  /**
13634
13834
  * Mirrors `CoreBlockStatus`, pinned by `core-blocks-source.spec.ts`. `degraded`:
@@ -28949,148 +29149,6 @@ DeviceType.Camera, method(object({
28949
29149
  auth: "protected"
28950
29150
  });
28951
29151
  /**
28952
- * LA tabella "quale booleano di questo tipo di device conta come ALTO", e il
28953
- * valutatore puro del suo FRONTE.
28954
- *
28955
- * Viveva dentro il builtin virtual-doorbell
28956
- * (`@camstack/system` — `builtins/doorbell/trigger-engine.ts`) e i suoi
28957
- * predicati erano privati al modulo. Il recorder ne ha bisogno per il trigger
28958
- * `RecordingTriggers.sensorDeviceIds`: copiarla avrebbe creato la SECONDA
28959
- * tabella, che diverge alla prima cap aggiunta e il cui sintomo — "il sensore
28960
- * fa suonare il campanello ma non registra" — è esattamente D62. Quindi si
28961
- * SPOSTA qui e il doorbell la ri-esporta.
28962
- *
28963
- * ⚠ NON è `DEVICE_STATE_READERS` (`catalogs/device-state-vocabulary.ts`), e le
28964
- * due non vanno unificate: quella risponde a "qual è la PAROLA di stato per una
28965
- * regola" (e include `presence`, `cover`, `alarm-panel`), questa a "qual è il
28966
- * booleano il cui FRONTE conta". Vocabolari deliberatamente diversi.
28967
- */
28968
- /**
28969
- * Known binary / switch source caps → the boolean slice field whose
28970
- * false→true rise counts as ACTIVE. Every entry is "fire on active".
28971
- * Sensors whose "active" reading is not a plain boolean (presence's string
28972
- * state, connectivity's connected flag) are deliberately excluded — a
28973
- * reconnect is not a doorbell press, and it is not a recording either.
28974
- */
28975
- var SOURCE_CAP_ACTIVE_FIELD = {
28976
- contact: "entryOpen",
28977
- binary: "on",
28978
- switch: "on",
28979
- motion: "detected",
28980
- flood: "flooded",
28981
- gas: "detected",
28982
- smoke: "detected",
28983
- "carbon-monoxide": "detected",
28984
- vibration: "detected",
28985
- tamper: "tampered"
28986
- };
28987
- /**
28988
- * The same caps → the slice field carrying the ms-epoch timestamp of the
28989
- * last transition. Every source cap MUST appear here (guarded by a spec):
28990
- * without a transition timestamp the evaluator cannot tell a genuine rise
28991
- * from a boot-time hydration when the FIRST slice it ever sees is already
28992
- * active, and errs towards silence — swallowing the rise.
28993
- *
28994
- * These timestamps are UPSTREAM ones, not ingest ones: the Home Assistant
28995
- * provider derives them from `state.last_changed`, so they survive our own
28996
- * restarts and correctly read as "hours ago" for a state that has been
28997
- * active for hours. `motion` names its rise timestamp `lastDetectedAt`.
28998
- */
28999
- var SOURCE_CAP_CHANGED_AT_FIELD = {
29000
- contact: "lastChangedAt",
29001
- binary: "lastChangedAt",
29002
- switch: "lastChangedAt",
29003
- motion: "lastDetectedAt",
29004
- flood: "lastChangedAt",
29005
- gas: "lastChangedAt",
29006
- smoke: "lastChangedAt",
29007
- "carbon-monoxide": "lastChangedAt",
29008
- vibration: "lastChangedAt",
29009
- tamper: "lastChangedAt"
29010
- };
29011
- /** Cap names whose presence in a device's bindings qualify it as a source. */
29012
- var SOURCE_CAPS = Object.keys(SOURCE_CAP_ACTIVE_FIELD);
29013
- /** True when a cap is a recognised binary/switch source. */
29014
- function isSourceCap(capName) {
29015
- return Object.prototype.hasOwnProperty.call(SOURCE_CAP_ACTIVE_FIELD, capName);
29016
- }
29017
- /** Extract the "active" boolean a source cap's slice carries, or null when
29018
- * the cap is unknown or the field is missing / non-boolean. */
29019
- function sliceActiveValue(capName, slice) {
29020
- const field = SOURCE_CAP_ACTIVE_FIELD[capName];
29021
- if (field === void 0) return null;
29022
- const raw = slice[field];
29023
- return typeof raw === "boolean" ? raw : null;
29024
- }
29025
- /** Ms-epoch transition timestamp a source cap's slice carries, or null when
29026
- * it is absent, non-numeric or the zero "never observed" sentinel. */
29027
- function sliceChangedAt(capName, slice) {
29028
- const field = SOURCE_CAP_CHANGED_AT_FIELD[capName];
29029
- if (field === void 0) return null;
29030
- const raw = slice[field];
29031
- if (typeof raw !== "number" || !Number.isFinite(raw) || raw <= 0) return null;
29032
- return raw;
29033
- }
29034
- /**
29035
- * How recent a source's own transition timestamp must be for a FIRST
29036
- * sighting that is already active to count as a genuine rise rather than a
29037
- * hydration of long-standing state.
29038
- */
29039
- var DEFAULT_FIRST_SIGHTING_FRESHNESS_MS = 3e4;
29040
- /**
29041
- * IL fronte. Puro: nessun orologio proprio, nessuna memoria — il chiamante
29042
- * porta `prior`, `nowMs` e il proprio `startedAtMs`.
29043
- *
29044
- * Il caso della PRIMA slice già attiva è trattato esplicitamente e vale come
29045
- * fronte solo se il timestamp UPSTREAM della transizione è posteriore a
29046
- * `startedAtMs` **e** entro `firstSightingFreshnessMs`. Entrambe le metà
29047
- * servono: la sola freschezza scatterebbe su un'idratazione al boot di uno
29048
- * stato flippato pochi secondi prima del riavvio, e il solo "dopo che abbiamo
29049
- * iniziato" scatterebbe, su un processo di lunga vita, per una sorgente
29050
- * adottata oggi il cui stato è cambiato ieri. Il caso ambiguo ERRA VERSO IL
29051
- * SILENZIO e lo dichiara (`baseline-seeded-stale-active`).
29052
- */
29053
- function evaluateSensorEdge(input) {
29054
- const value = sliceActiveValue(input.capName, input.slice);
29055
- if (value === null) return {
29056
- edge: "none",
29057
- value: null,
29058
- reason: isSourceCap(input.capName) ? "non-boolean-value" : "unknown-cap"
29059
- };
29060
- if (input.prior === void 0) {
29061
- if (!value) return {
29062
- edge: "none",
29063
- value,
29064
- reason: "baseline-seeded-inactive"
29065
- };
29066
- const changedAt = sliceChangedAt(input.capName, input.slice);
29067
- const floor = Math.max(input.startedAtMs, input.nowMs - input.firstSightingFreshnessMs);
29068
- if (changedAt === null || changedAt < floor) return {
29069
- edge: "none",
29070
- value,
29071
- reason: "baseline-seeded-stale-active"
29072
- };
29073
- return {
29074
- edge: "rising",
29075
- value: true
29076
- };
29077
- }
29078
- if (input.prior === value) return {
29079
- edge: "none",
29080
- value,
29081
- reason: "no-change"
29082
- };
29083
- if (!value) return {
29084
- edge: "none",
29085
- value,
29086
- reason: "falling-edge"
29087
- };
29088
- return {
29089
- edge: "rising",
29090
- value: true
29091
- };
29092
- }
29093
- /**
29094
29152
  * Doorbell button cap. Two kinds of providers coexist behind this cap
29095
29153
  * name (same pattern as `snapshot`):
29096
29154
  *
@@ -29163,7 +29221,13 @@ var doorbellCapability = {
29163
29221
  * push (`ReolinkSimpleEvent.type === 'doorbell'`). There is no
29164
29222
  * release/duration — it's a pulse.
29165
29223
  */
29166
- onPressed: { data: DoorbellPressEventSchema } },
29224
+ onPressed: {
29225
+ data: DoorbellPressEventSchema,
29226
+ fromState: {
29227
+ field: "lastPressedAt",
29228
+ on: "advance"
29229
+ }
29230
+ } },
29167
29231
  status: {
29168
29232
  schema: DoorbellStatusSchema,
29169
29233
  kind: "push"
@@ -37105,12 +37169,21 @@ var RecordingStorageUsageSchema = object({
37105
37169
  */
37106
37170
  devicesRead: _enum(["archive", "unavailable"]).optional(),
37107
37171
  /**
37172
+ * Is the `archive` answer WHOLE (D674): the hour ledger loaded without
37173
+ * hitting its row cap, and at least one location resolved? Only then may a
37174
+ * camera ABSENT from `devices[]` be read as "no footage" — and only then is a
37175
+ * row's `oldestMs` the archive's oldest rather than the oldest of a fraction.
37176
+ * OPTIONAL: a recorder predating D674 omits it, and a consumer must read the
37177
+ * absence as `false`. A retention floor is a delete; it never guesses.
37178
+ */
37179
+ complete: boolean().optional(),
37180
+ /**
37108
37181
  * Per-physical-volume capacity. OPTIONAL, and consumers must render the rest
37109
- * of the payload without it: the hub serves this method through a BAKED
37110
- * router, so a hub whose framework train predates a change to this array
37111
- * strips it out of an answer a newer recorder happily produced. A UI that
37112
- * dereferences it unconditionally crashes the whole Storage page over a
37113
- * missing disk bar.
37182
+ * of the payload without it: a recorder that could not build it omits it. A
37183
+ * UI that dereferences it unconditionally crashes the whole Storage page over
37184
+ * a missing disk bar. (The hub's cap routers pass output through unvalidated
37185
+ * since 2026-07-11 — `cap-router-builder.ts` — so a newer recorder's fields
37186
+ * are not stripped by an older hub.)
37114
37187
  */
37115
37188
  locations: array(RecordingLocationUsageSchema).optional()
37116
37189
  });
@@ -40654,7 +40727,12 @@ Object.freeze({
40654
40727
  number: {
40655
40728
  kind: "fixed",
40656
40729
  result: ["number", "null"]
40657
- }
40730
+ },
40731
+ rose: {
40732
+ kind: "fixed",
40733
+ result: ["number", "null"]
40734
+ },
40735
+ count: NUMBER
40658
40736
  });
40659
40737
  `${COMPOSED_DEVICE_STABLE_ID_PREFIX}`;
40660
40738
  /**