@camstack/addon-pipeline 1.2.305 → 1.2.307

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 (33) 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-BduwEjht.mjs → default-detection-model-BV9bIuOo.mjs} +1 -1
  4. package/dist/{default-detection-model-BsXfdMCG.js → default-detection-model-DgdiQtQb.js} +1 -1
  5. package/dist/detection-pipeline/index.js +4 -4
  6. package/dist/detection-pipeline/index.mjs +4 -4
  7. package/dist/{dist-D4lbkRUh.js → dist-CyJWk-_f.js} +298 -160
  8. package/dist/{dist-BdYgTuWJ.mjs → dist-DdVMFlJ6.mjs} +281 -161
  9. package/dist/motion-wasm/index.js +1 -1
  10. package/dist/motion-wasm/index.mjs +1 -1
  11. package/dist/{node-DTG5A-3e.mjs → node-COu_tHy4.mjs} +1 -1
  12. package/dist/{node-BMmRQfH_.js → node-HsWG5fGp.js} +1 -1
  13. package/dist/pipeline-runner/index.js +7 -6
  14. package/dist/pipeline-runner/index.mjs +7 -6
  15. package/dist/{process-memory-RnWS9Et5.mjs → process-memory-Bz3oIMzl.mjs} +1 -1
  16. package/dist/{process-memory-DJrgIn1c.js → process-memory-TQXG7qrJ.js} +1 -1
  17. package/dist/recorder/index.js +2 -4
  18. package/dist/recorder/index.mjs +2 -4
  19. package/dist/{segment-demux-js-BI9zEgk6.js → segment-demux-js-BrKa7tpr.js} +1 -1
  20. package/dist/{segment-demux-js-CsJMEslt.mjs → segment-demux-js-CEJn4BR0.mjs} +1 -1
  21. package/dist/stream-broker/_stub.js +2 -2
  22. package/dist/stream-broker/{_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-Vcuvgik_.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-DdYUVQSA.mjs} +2 -2
  23. package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-DPHv0v3Q.mjs +26 -0
  24. package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-CdKbuxqG.mjs +26 -0
  25. package/dist/stream-broker/demux-worker-child.js +1 -1
  26. package/dist/stream-broker/demux-worker-child.mjs +1 -1
  27. package/dist/stream-broker/{hostInit-C3s1ZFbg.mjs → hostInit-D--a9rVM.mjs} +2 -2
  28. package/dist/stream-broker/index.js +100 -151
  29. package/dist/stream-broker/index.mjs +97 -148
  30. package/dist/stream-broker/remoteEntry.js +1 -1
  31. package/package.json +1 -1
  32. package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-X_j7TiDp.mjs +0 -26
  33. package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-CR9IIPsz.mjs +0 -26
@@ -5370,7 +5370,7 @@ var ZodIssueCode = {
5370
5370
  var ZodFirstPartyTypeKind;
5371
5371
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5372
5372
  //#endregion
5373
- //#region ../types/dist/sleep-E6eD4yQS.mjs
5373
+ //#region ../types/dist/sleep-C-v96WpE.mjs
5374
5374
  /**
5375
5375
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5376
5376
  * window to float samples (D455).
@@ -7684,7 +7684,7 @@ function errMsg(err) {
7684
7684
  return String(err);
7685
7685
  }
7686
7686
  //#endregion
7687
- //#region ../types/dist/composition-D5BQywfe.mjs
7687
+ //#region ../types/dist/composition-BK-GTFYb.mjs
7688
7688
  var AUDIO_ENCODER_BY_CODEC = {
7689
7689
  opus: "libopus",
7690
7690
  aac: "aac",
@@ -9324,7 +9324,6 @@ var CompositionSchema = object({
9324
9324
  });
9325
9325
  new Set([
9326
9326
  "track",
9327
- "summary",
9328
9327
  "face",
9329
9328
  "identity",
9330
9329
  "plate",
@@ -9607,6 +9606,90 @@ async function resolveEgressDecodeHwAccel(deps) {
9607
9606
  return resolved;
9608
9607
  }
9609
9608
  /**
9609
+ * The notification GIF's filter chain and argv — ONE definition for every
9610
+ * process that derives a gif from a notification video.
9611
+ *
9612
+ * ## Why this lives in `@camstack/types`
9613
+ *
9614
+ * Two addons derive a notification gif from an mp4, and they may never import
9615
+ * each other:
9616
+ *
9617
+ * - the stream broker (`addon-pipeline`), from the clip it just cut out of its
9618
+ * own ring (`gif-from-mp4.ts`);
9619
+ * - the notification centre (`addon-post-analysis`), from a clip cut out of
9620
+ * the RECORDINGS when the moment is older than any ring holds
9621
+ * ([D682](../../../../docs/decisions/adr-0682-a-pick-ups-footage-is-cut-around-the-pick-up.md)).
9622
+ *
9623
+ * Two copies of this chain would be two gifs of the same kind of moment that
9624
+ * look different depending on how old the moment was — the class of defect
9625
+ * D85/D91 already paid for once. So the chain is here, pure and dependency
9626
+ * free, and each caller owns only its own process lifecycle.
9627
+ *
9628
+ * ## The palette was never the problem
9629
+ *
9630
+ * The `split` + `palettegen(stats_mode=diff)` + `paletteuse(bayer)` pair is
9631
+ * right and stays. The measured cause of "the gif looks de-pixellated" was a
9632
+ * 640×360 substream scaled DOWN to 480 px, upstream of the palette. The `split`
9633
+ * form is a single READ of the input, not a lesser two-pass.
9634
+ */
9635
+ /**
9636
+ * Format a frame rate for an ffmpeg filter argument.
9637
+ *
9638
+ * `12 / 4` must reach the filter as `3` and `15 / 4` as `3.75`, not as a float
9639
+ * tail that `av_parse_video_rate` then has to guess at.
9640
+ */
9641
+ function ffmpegRate(rate) {
9642
+ return String(Math.round(rate * 1e3) / 1e3);
9643
+ }
9644
+ /**
9645
+ * The factor the derive must apply ON TOP of the speed the mp4 already carries.
9646
+ *
9647
+ * The gif is derived from a muxed mp4, so if that mux already ran `setpts` at
9648
+ * the caller's `speed`, applying the absolute gif rate again would compound
9649
+ * them — a 4× gif beside a 2× video would come out at 8×. Discounting here is
9650
+ * what keeps the gif rate ABSOLUTE against real time whatever the video does.
9651
+ */
9652
+ function gifDeriveSpeed(gifSpeed, videoSpeed) {
9653
+ if (!Number.isFinite(videoSpeed) || videoSpeed <= 0) return gifSpeed;
9654
+ return gifSpeed / videoSpeed;
9655
+ }
9656
+ /**
9657
+ * The filter chain. Extracted so a test can assert the palette pair without
9658
+ * spawning ffmpeg — an argv test cannot see quality, but it can see a filter
9659
+ * that somebody deleted.
9660
+ *
9661
+ * `fps` BEFORE `setpts`: decimating an already sped-up timeline yields `speed`
9662
+ * times the frames asked for, and a gif pays for every one. So the decimation
9663
+ * runs at `fps / speed` in SOURCE time and `setpts` multiplies what survived.
9664
+ * The trailing `fps` re-declares the rate, which is NOT redundant: `setpts`
9665
+ * leaves the filter link advertising the sampled rate and the gif muxer
9666
+ * believes the link — measured on 615 as a 3.01 s gif of ten frames.
9667
+ */
9668
+ function gifFilterComplex(input) {
9669
+ const speed = input.speed > 0 ? input.speed : 1;
9670
+ if (speed === 1) return `[0:v]fps=${ffmpegRate(input.fps)},scale=${input.maxWidth}:-2:flags=lanczos,split[a][b];[a]palettegen=stats_mode=diff[p];[b][p]paletteuse=dither=bayer:bayer_scale=5:diff_mode=rectangle`;
9671
+ return `[0:v]fps=${ffmpegRate(input.fps / speed)},setpts=PTS/${speed},fps=${ffmpegRate(input.fps)},scale=${input.maxWidth}:-2:flags=lanczos,split[a][b];[a]palettegen=stats_mode=diff[p];[b][p]paletteuse=dither=bayer:bayer_scale=5:diff_mode=rectangle`;
9672
+ }
9673
+ /** The full argv: mp4 in, gif on stdout. */
9674
+ function gifFromMp4Args(input) {
9675
+ return [
9676
+ "-y",
9677
+ "-v",
9678
+ "error",
9679
+ "-f",
9680
+ "mp4",
9681
+ "-i",
9682
+ input.input ?? "pipe:0",
9683
+ "-filter_complex",
9684
+ gifFilterComplex(input),
9685
+ "-loop",
9686
+ "0",
9687
+ "-f",
9688
+ "gif",
9689
+ "pipe:1"
9690
+ ];
9691
+ }
9692
+ /**
9610
9693
  * The sharing key for `streamBroker.acquireEgressTranscode`.
9611
9694
  *
9612
9695
  * **Two requesters asking for exactly the same argument set reach the same
@@ -17066,6 +17149,34 @@ var DeviceBindingsForDeviceSchema = object({
17066
17149
  nativeAddonId: string()
17067
17150
  }))
17068
17151
  });
17152
+ /**
17153
+ * The STORED wrapper activation for one `(device, capability)` pair — the row
17154
+ * `setWrapperActive` writes, read back three-way (D675):
17155
+ *
17156
+ * - `value` — the store answered and holds an activation: the bound wrapper's
17157
+ * addon id, or `null`, the operator's explicit "off" marker (D62);
17158
+ * - `missing` — the store answered, its activation map exists, and it holds
17159
+ * nothing for this pair: the operator never activated or deactivated a
17160
+ * wrapper here;
17161
+ * - `failed` — the store could not be read, holds no activation map at all
17162
+ * (an empty or unready snapshot, D44), or holds something that is not an
17163
+ * activation. It carries NO information: a consumer must never read it as
17164
+ * `missing` (D315, D393).
17165
+ *
17166
+ * This is the persisted INPUT, not the derived `getBindings` view — no registry
17167
+ * resolution, no `defaultActive` auto-binding, no cluster native-cap folding.
17168
+ */
17169
+ var WrapperActivationReadSchema = discriminatedUnion("kind", [
17170
+ object({
17171
+ kind: literal("value"),
17172
+ wrapperAddonId: string().nullable()
17173
+ }),
17174
+ object({ kind: literal("missing") }),
17175
+ object({
17176
+ kind: literal("failed"),
17177
+ error: string()
17178
+ })
17179
+ ]);
17069
17180
  var SavedDeviceRowSchema = object({
17070
17181
  /** Numeric id reserved at allocateDeviceId time. */
17071
17182
  id: number(),
@@ -17416,7 +17527,10 @@ method(object({
17416
17527
  }), _void(), {
17417
17528
  kind: "mutation",
17418
17529
  auth: "admin"
17419
- }), method(object({ capName: string() }), array(string())), method(object({ deviceType: string() }), array(object({
17530
+ }), method(object({
17531
+ deviceId: number(),
17532
+ capName: string().min(1)
17533
+ }), WrapperActivationReadSchema), method(object({ capName: string() }), array(string())), method(object({ deviceType: string() }), array(object({
17420
17534
  capName: string(),
17421
17535
  wrappers: array(string())
17422
17536
  }))), method(object({ deviceId: number() }), SettingsSchemaWithValuesSchema.nullable()), method(object({ deviceId: number() }), SettingsSchemaWithValuesSchema.nullable()), method(object({ deviceId: number() }), object({
@@ -22924,6 +23038,102 @@ var OauthIntegrationDescriptorSchema = object({
22924
23038
  });
22925
23039
  method(_void(), OauthIntegrationDescriptorSchema, { auth: "admin" });
22926
23040
  /**
23041
+ * What started a camera's onboard motion (D672). `camera` is the camera's own
23042
+ * firmware; `sensor` is a device the operator ATTACHED to it. Absent on the
23043
+ * wire means the camera: only the camera-sensors bridge ever says `sensor`.
23044
+ */
23045
+ var MotionTriggeredBySchema = discriminatedUnion("kind", [object({ kind: literal("camera") }), object({
23046
+ kind: literal("sensor"),
23047
+ deviceId: number().int().positive()
23048
+ })]);
23049
+ Object.freeze({ kind: "camera" });
23050
+ var CameraSensorRefSchema = object({
23051
+ addonId: string().min(1),
23052
+ stableId: string().min(1)
23053
+ });
23054
+ function cameraSensorRefKey(ref) {
23055
+ return `${ref.addonId}/${ref.stableId}`;
23056
+ }
23057
+ /** CS-1 accepts exactly one mode; CS-2 (D673) widens it to confirm / replace. */
23058
+ var CameraSensorsModeSchema = _enum(["in-addition"]);
23059
+ object({
23060
+ mode: CameraSensorsModeSchema,
23061
+ sensors: array(CameraSensorRefSchema).min(1).max(8)
23062
+ }).superRefine((value, ctx) => {
23063
+ const seen = /* @__PURE__ */ new Set();
23064
+ value.sensors.forEach((ref, index) => {
23065
+ const key = cameraSensorRefKey(ref);
23066
+ if (seen.has(key)) ctx.addIssue({
23067
+ code: "custom",
23068
+ path: ["sensors", index],
23069
+ message: `duplicate camera sensor ${key}`
23070
+ });
23071
+ seen.add(key);
23072
+ });
23073
+ });
23074
+ var RefFields = {
23075
+ addonId: string(),
23076
+ stableId: string()
23077
+ };
23078
+ var CameraSensorAttachmentSchema = discriminatedUnion("state", [
23079
+ object({
23080
+ ...RefFields,
23081
+ state: literal("ready"),
23082
+ deviceId: number(),
23083
+ name: string(),
23084
+ caps: array(string()).readonly()
23085
+ }),
23086
+ object({
23087
+ ...RefFields,
23088
+ state: literal("offline"),
23089
+ deviceId: number(),
23090
+ name: string(),
23091
+ reason: _enum(["offline", "disabled"])
23092
+ }),
23093
+ object({
23094
+ ...RefFields,
23095
+ state: literal("missing"),
23096
+ reason: string()
23097
+ }),
23098
+ object({
23099
+ ...RefFields,
23100
+ state: literal("unsupported"),
23101
+ deviceId: number(),
23102
+ name: string(),
23103
+ reason: string()
23104
+ }),
23105
+ object({
23106
+ ...RefFields,
23107
+ state: literal("unreadable"),
23108
+ reason: string()
23109
+ })
23110
+ ]);
23111
+ /**
23112
+ * Why a configured camera forwards NOTHING from its sensors, however ready they
23113
+ * are (D672): it does not list `onboard` in `motionSources` (attaching a sensor
23114
+ * does not add it), or it has no active detection config at all (the bridge
23115
+ * reads the active config). Absent = forwarded, or an older node that does not
23116
+ * say.
23117
+ */
23118
+ var CameraSensorsNotForwardedSchema = _enum(["onboard-not-listed", "no-active-detection"]);
23119
+ var CameraSensorsStatusSchema = discriminatedUnion("state", [
23120
+ object({ state: literal("not-configured") }),
23121
+ object({
23122
+ state: literal("unreadable"),
23123
+ reason: string()
23124
+ }),
23125
+ object({
23126
+ state: literal("configured"),
23127
+ mode: CameraSensorsModeSchema,
23128
+ sensors: array(CameraSensorAttachmentSchema).readonly(),
23129
+ notForwarded: CameraSensorsNotForwardedSchema.optional()
23130
+ })
23131
+ ]);
23132
+ Object.freeze({
23133
+ state: "unreadable",
23134
+ reason: "camera sensor mappings not loaded"
23135
+ });
23136
+ /**
22927
23137
  * A model choice has a SCOPE, and a scope change has a workflow.
22928
23138
  *
22929
23139
  * ## The two scopes
@@ -23719,6 +23929,12 @@ var MotionEventSchema = object({
23719
23929
  /** Populated by B5 (recording playback URL for this event). */
23720
23930
  mediaUrl: string().optional(),
23721
23931
  /**
23932
+ * The FIRST trigger of an `onboard` episode, written once at open (D672).
23933
+ * Absent = not recorded (a row written before D672, or an analyzer /
23934
+ * device-activity episode) — never read as "the camera" (D393).
23935
+ */
23936
+ triggeredBy: MotionTriggeredBySchema.optional(),
23937
+ /**
23722
23938
  * One row per motion EPISODE, not one per push (D475). `null` while the
23723
23939
  * episode is still open — a further rising edge extends it in place rather
23724
23940
  * than inserting a new row. Set once, at close, to `lastOnAt - startedAt`
@@ -23877,6 +24093,21 @@ var ObjectEventSchema = object({
23877
24093
  keyFrameMediaId: number().int().optional(),
23878
24094
  /** Populated by B5 (recording playback URL for this event). */
23879
24095
  mediaUrl: string().optional(),
24096
+ /**
24097
+ * When the change this row records HAPPENED, epoch ms, when that is earlier
24098
+ * than {@link timestamp} and the producer could date it (D684).
24099
+ *
24100
+ * Set on a package PICK-UP row only: its `timestamp` is when the departure
24101
+ * was CONCLUDED — five minutes of unseen observed time after the parcel went
24102
+ * — and a notification's footage has to be cut around the pick-up, not the
24103
+ * empty doormat after it (D682). Stored so every path that rebuilds a
24104
+ * notification subject from the row (the boot reconcile, a dry-run) anchors
24105
+ * on the same instant the live hook did.
24106
+ *
24107
+ * `timestamp` keeps its meaning. Absent on every other row and on every
24108
+ * pick-up written before D684 — UNKNOWN, never 0 and never `timestamp`.
24109
+ */
24110
+ observedAt: number().optional(),
23880
24111
  /** The parent track's key-event importance [0,1], propagated to every object
23881
24112
  * event of the track (so an event row can be sorted by importance without a
23882
24113
  * track join). Absent on legacy rows / before the track was scored. */
@@ -24212,131 +24443,6 @@ var RecentTracksQueryInput = object({
24212
24443
  /** See {@link ExcludeSourcesDoc}. */
24213
24444
  excludeSources: array(TrackSourceSchema).optional()
24214
24445
  });
24215
- /**
24216
- * A Summary (D359): the per-camera session envelope that references tracks.
24217
- * `groupShotMediaId` is the media ROW id of its group shot (`ownerKind:
24218
- * 'summary'`, served by the event-media plane at `/m/<id>`), null until the
24219
- * first frame with a member visible has been materialised (D482 — it was the
24220
- * row's composite key, which embedded the owner and could name another table's
24221
- * row once event ids became per-table rowids).
24222
- */
24223
- var SummarySchema = object({
24224
- id: string(),
24225
- deviceId: number(),
24226
- openedAt: number(),
24227
- lastActiveAt: number(),
24228
- sealedAt: number().nullable(),
24229
- memberCount: number().int().nonnegative(),
24230
- groupShotMediaId: number().int().nullable()
24231
- });
24232
- var SummariesQueryInput = object({
24233
- deviceIds: array(number()).min(1),
24234
- since: number().optional(),
24235
- until: number().optional(),
24236
- limit: number().int().min(1).max(200).default(50),
24237
- /** The same member-wise filter {@link listRecentSummaries} takes — one
24238
- * meaning of "dog" on every summary surface. */
24239
- classes: array(string().min(1).max(60)).max(40).optional()
24240
- });
24241
- var SummaryDetailSchema = object({
24242
- summary: SummarySchema,
24243
- /** Members in absorption order, oldest join first. */
24244
- members: array(object({
24245
- trackId: string(),
24246
- /**
24247
- * The track's class at the time it JOINED, or `null` when it was unresolved
24248
- * and the track no longer exists to fill it.
24249
- *
24250
- * The join, not the latest opinion: class voting can re-decide a track's
24251
- * class afterwards, and a group's composition is the history of who came
24252
- * together. A consumer counts these to badge a thumbnail — "two people and a
24253
- * dog" — rather than being handed a second, denormalised tally that would
24254
- * drift from the members it claims to describe.
24255
- */
24256
- className: string().nullable(),
24257
- /** `primary` is the one member that carries the group's identity. */
24258
- role: _enum([
24259
- "primary",
24260
- "sibling",
24261
- "child"
24262
- ]).nullable(),
24263
- joinedAt: number(),
24264
- /** Tier 1 — the sub-class (`dog`, `van`), resolved from the member's track
24265
- * at read time. Absent when nothing resolved, never an empty string. */
24266
- label: string().optional(),
24267
- /** Tier 2 — the instance: a person's name, a plate. Absent when the pipeline
24268
- * recognised nobody, and absent for a member whose track has been pruned —
24269
- * a thumbnail that names the wrong person is worse than one naming nobody. */
24270
- subLabel: string().optional()
24271
- })).readonly()
24272
- });
24273
- /**
24274
- * What a LIST of groups carries: the envelope plus what it is MADE OF.
24275
- *
24276
- * Coarse on purpose — the operator's rule is "only the rough data on the list,
24277
- * we extend when we notice we need more". Enough to draw the card ("two people
24278
- * and a dog") and no more. The MEMBERS, their names and the per-member links
24279
- * are on {@link getSummary}: shipping every member of every group so a client
24280
- * can count them turns a page of two hundred groups into a thousand records to
24281
- * draw two hundred badges.
24282
- */
24283
- var SummaryListItemSchema = object({
24284
- summary: SummarySchema,
24285
- /** Class counts, most numerous first; `className: null` is a member whose
24286
- * class never resolved, counted so the counts add up to `memberCount`. */
24287
- classes: array(object({
24288
- className: string().nullable(),
24289
- count: number().int().positive()
24290
- })).readonly()
24291
- });
24292
- var SummariesPageSchema = object({ summaries: array(SummaryListItemSchema).readonly() });
24293
- /**
24294
- * The paged feed, deliberately the SAME shape as {@link RecentTracksQueryInput}.
24295
- *
24296
- * The reel on the cameras page and the Events gallery both ride a cursor, so a
24297
- * summaries feed that could only answer "the last N for these cameras"
24298
- * (`listSummaries`) would make groups available in the timeline and nowhere
24299
- * else. Two feeds with different ordering contracts would be two ideas of what
24300
- * "newest" means, on one screen.
24301
- */
24302
- var RecentSummariesQueryInput = object({
24303
- /** Devices to merge. An empty array yields an empty page. */
24304
- deviceIds: array(number()),
24305
- /** Window lower bound on `lastActiveAt` (inclusive). */
24306
- since: number().optional(),
24307
- /** Window upper bound on `lastActiveAt` (inclusive). */
24308
- until: number().optional(),
24309
- limit: number().int().min(1).max(500).default(100),
24310
- /** Opaque continuation cursor from a previous page's `nextCursor`. */
24311
- cursor: string().optional(),
24312
- /**
24313
- * Restrict to these classes — THE SAME FIELD `listRecentTracks` takes, and
24314
- * deliberately the same name: the events filter tree emits one list of ticked
24315
- * taxonomy nodes, and a summaries feed that called it something else would
24316
- * make the operator's one filter component produce two shapes.
24317
- *
24318
- * A question about the MEMBERS: a group matches when ANY of them does. "Show
24319
- * me the arrivals with a dog" has to return the group of four people who had
24320
- * one with them; a filter on the group's own fields could only ever answer
24321
- * about its primary.
24322
- *
24323
- * Matched against all THREE tiers of a member — the class (`animal`), the
24324
- * sub-class (`dog`) and the instance (a name, a plate) — because which tier a
24325
- * ticked node lives on is the taxonomy's business, not the caller's. `dog` is
24326
- * an event kind in the tree and a tier-1 label on an `animal` track; a filter
24327
- * that read only the class would answer "animal" and never "dog".
24328
- *
24329
- * ABSENT or EMPTY means no filter — absent is not a selection of none.
24330
- */
24331
- classes: array(string().min(1).max(60)).max(40).optional()
24332
- });
24333
- var RecentSummariesPageSchema = object({
24334
- /** Ordered by (`lastActiveAt` DESC, id DESC). Same light item as
24335
- * {@link listSummaries} — one list shape, so a card renders the same
24336
- * whichever feed drew it. */
24337
- summaries: array(SummaryListItemSchema).readonly(),
24338
- nextCursor: string().nullable()
24339
- });
24340
24446
  var RecentTracksPageSchema = object({
24341
24447
  /** Merged page, ordered by (`lastSeen` DESC, `trackId` DESC). */
24342
24448
  tracks: array(TrackSchema).readonly(),
@@ -24848,7 +24954,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
24848
24954
  classes: array(string()).optional(),
24849
24955
  /** See {@link ExcludeSourcesDoc}. */
24850
24956
  excludeSources: array(TrackSourceSchema).optional()
24851
- }), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(SummariesQueryInput, SummariesPageSchema), method(RecentSummariesQueryInput, RecentSummariesPageSchema), method(object({ id: string() }), SummaryDetailSchema.nullable()), method(object({ deviceId: number() }), _void(), {
24957
+ }), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(object({ deviceId: number() }), _void(), {
24852
24958
  kind: "mutation",
24853
24959
  auth: "admin"
24854
24960
  }), method(DeviceEventQueryInput, array(MotionEventSchema).readonly()), method(ObjectEventQueryInput, array(ObjectEventSchema).readonly()), method(DeviceEventQueryInput, array(AudioEventSchema).readonly()), method(object({ deviceId: number() }), array(EventKindDescriptorSchema).readonly()), method(object({ deviceIds: array(number()).min(1).max(200) }), array(EventKindsForDeviceSchema).readonly()), method(object({
@@ -26224,6 +26330,23 @@ var MotionSourceEnum = _enum([
26224
26330
  */
26225
26331
  var MotionSourcesSchema = array(MotionSourceEnum);
26226
26332
  /**
26333
+ * The operator-facing name of each MOTION source (D672: `onboard` = the
26334
+ * camera's sensors — its own motion plus any sensor attached to it). The wire
26335
+ * value stays `onboard`; only the label changed. `detectionSources: 'onboard'`
26336
+ * ("Camera onboard AI") and the notification source filter keep their labels.
26337
+ */
26338
+ var MOTION_SOURCE_LABELS = {
26339
+ analyzer: "Frame-diff Analyzer (motion addon)",
26340
+ onboard: "Camera sensors",
26341
+ "device-activity": "Device activity (the device says it is working)"
26342
+ };
26343
+ /** The order the motion-source picker offers them in (not the enum's order). */
26344
+ var MOTION_SOURCE_PICKER_ORDER = [
26345
+ "analyzer",
26346
+ "onboard",
26347
+ "device-activity"
26348
+ ];
26349
+ /**
26227
26350
  * Which root detector a camera runs — EXACTLY ONE.
26228
26351
  *
26229
26352
  * Deliberately the SAME vocabulary post-analysis already tags every detection
@@ -26570,7 +26693,14 @@ var RunnerCameraConfigSchema = object({
26570
26693
  */
26571
26694
  inferenceDevices: array(RunnerInferenceDeviceSchema).readonly().optional()
26572
26695
  });
26573
- motionFpsField.min, motionFpsField.max, motionFpsField.step, motionFpsField.default, detectionFpsField.min, detectionFpsField.max, detectionFpsField.step, detectionFpsField.default, motionCooldownMsField.min, motionCooldownMsField.max, motionCooldownMsField.step, motionCooldownMsField.default, maxSessionHoldMsField.min, maxSessionHoldMsField.max, maxSessionHoldMsField.step, maxSessionHoldMsField.default, audioMotionWindowMsField.min, audioMotionWindowMsField.max, audioMotionWindowMsField.step, audioMotionWindowMsField.default, preRollInferenceFramesField.min, preRollInferenceFramesField.max, preRollInferenceFramesField.step, preRollInferenceFramesField.default, occupancyRecheckSecField.min, occupancyRecheckSecField.max, occupancyRecheckSecField.step, occupancyRecheckSecField.default, occupancyRecheckFramesField.min, occupancyRecheckFramesField.max, occupancyRecheckFramesField.step, occupancyRecheckFramesField.default;
26696
+ MOTION_SOURCE_PICKER_ORDER.map((value) => value === "onboard" ? {
26697
+ value,
26698
+ label: MOTION_SOURCE_LABELS[value],
26699
+ description: "The camera's own motion, plus any sensor attached to it"
26700
+ } : {
26701
+ value,
26702
+ label: MOTION_SOURCE_LABELS[value]
26703
+ }), motionFpsField.min, motionFpsField.max, motionFpsField.step, motionFpsField.default, detectionFpsField.min, detectionFpsField.max, detectionFpsField.step, detectionFpsField.default, motionCooldownMsField.min, motionCooldownMsField.max, motionCooldownMsField.step, motionCooldownMsField.default, maxSessionHoldMsField.min, maxSessionHoldMsField.max, maxSessionHoldMsField.step, maxSessionHoldMsField.default, audioMotionWindowMsField.min, audioMotionWindowMsField.max, audioMotionWindowMsField.step, audioMotionWindowMsField.default, preRollInferenceFramesField.min, preRollInferenceFramesField.max, preRollInferenceFramesField.step, preRollInferenceFramesField.default, occupancyRecheckSecField.min, occupancyRecheckSecField.max, occupancyRecheckSecField.step, occupancyRecheckSecField.default, occupancyRecheckFramesField.min, occupancyRecheckFramesField.max, occupancyRecheckFramesField.step, occupancyRecheckFramesField.default;
26574
26704
  /**
26575
26705
  * Runtime load summary returned by `getLocalLoad`. Used by the orchestrator's
26576
26706
  * load-balancing levels (L2 capacity-based, L3 hardware-aware) to decide
@@ -27336,6 +27466,11 @@ var CameraStatusSchema = object({
27336
27466
  */
27337
27467
  switchedOff: array(CameraSwitchIdSchema).readonly(),
27338
27468
  /**
27469
+ * The camera's attached sensors (D672). Optional only for a status composed
27470
+ * by an orchestrator older than D672; this orchestrator always sets it.
27471
+ */
27472
+ cameraSensors: CameraSensorsStatusSchema.optional(),
27473
+ /**
27339
27474
  * Stages of the bounded fan-out that were CUT SHORT — a timeout or a
27340
27475
  * rejection — and whose block is therefore `null` because we could not
27341
27476
  * READ it, not because there is nothing there.
@@ -33907,7 +34042,9 @@ object({
33907
34042
  detected: boolean(),
33908
34043
  timestamp: number(),
33909
34044
  source: MotionSourceEnum,
33910
- regions: array(MotionRegionSchema).readonly().optional()
34045
+ regions: array(MotionRegionSchema).readonly().optional(),
34046
+ /** Who started it (D672). Absent = the camera itself. Only `onboard` carries `sensor`. */
34047
+ triggeredBy: MotionTriggeredBySchema.optional()
33911
34048
  });
33912
34049
  DeviceType.Camera, DeviceType.Sensor, method(object({ deviceId: number() }), boolean());
33913
34050
  object({
@@ -42673,6 +42810,12 @@ Object.freeze({
42673
42810
  addonId: null,
42674
42811
  access: "view"
42675
42812
  },
42813
+ "deviceManager.getWrapperActivation": {
42814
+ capName: "device-manager",
42815
+ capScope: "system",
42816
+ addonId: null,
42817
+ access: "view"
42818
+ },
42676
42819
  "deviceManager.listAll": {
42677
42820
  capName: "device-manager",
42678
42821
  capScope: "system",
@@ -44947,12 +45090,6 @@ Object.freeze({
44947
45090
  addonId: null,
44948
45091
  access: "view"
44949
45092
  },
44950
- "pipelineAnalytics.getSummary": {
44951
- capName: "pipeline-analytics",
44952
- capScope: "device",
44953
- addonId: null,
44954
- access: "view"
44955
- },
44956
45093
  "pipelineAnalytics.getTrack": {
44957
45094
  capName: "pipeline-analytics",
44958
45095
  capScope: "device",
@@ -45013,12 +45150,6 @@ Object.freeze({
45013
45150
  addonId: null,
45014
45151
  access: "view"
45015
45152
  },
45016
- "pipelineAnalytics.listRecentSummaries": {
45017
- capName: "pipeline-analytics",
45018
- capScope: "device",
45019
- addonId: null,
45020
- access: "view"
45021
- },
45022
45153
  "pipelineAnalytics.listRecentTracks": {
45023
45154
  capName: "pipeline-analytics",
45024
45155
  capScope: "device",
@@ -45049,12 +45180,6 @@ Object.freeze({
45049
45180
  addonId: null,
45050
45181
  access: "view"
45051
45182
  },
45052
- "pipelineAnalytics.listSummaries": {
45053
- capName: "pipeline-analytics",
45054
- capScope: "device",
45055
- addonId: null,
45056
- access: "view"
45057
- },
45058
45183
  "pipelineAnalytics.listTrackMedia": {
45059
45184
  capName: "pipeline-analytics",
45060
45185
  capScope: "device",
@@ -48482,6 +48607,11 @@ Object.freeze({
48482
48607
  form: "single",
48483
48608
  optional: false
48484
48609
  }],
48610
+ "deviceManager.getWrapperActivation": [{
48611
+ name: "deviceId",
48612
+ form: "single",
48613
+ optional: false
48614
+ }],
48485
48615
  "deviceManager.listAll": [{
48486
48616
  name: "deviceIds",
48487
48617
  form: "array",
@@ -49219,11 +49349,6 @@ Object.freeze({
49219
49349
  form: "single",
49220
49350
  optional: true
49221
49351
  }],
49222
- "pipelineAnalytics.listRecentSummaries": [{
49223
- name: "deviceIds",
49224
- form: "array",
49225
- optional: false
49226
- }],
49227
49352
  "pipelineAnalytics.listRecentTracks": [{
49228
49353
  name: "deviceIds",
49229
49354
  form: "array",
@@ -49234,11 +49359,6 @@ Object.freeze({
49234
49359
  form: "array",
49235
49360
  optional: true
49236
49361
  }],
49237
- "pipelineAnalytics.listSummaries": [{
49238
- name: "deviceIds",
49239
- form: "array",
49240
- optional: false
49241
- }],
49242
49362
  "pipelineAnalytics.listTrackMedia": [{
49243
49363
  name: "deviceId",
49244
49364
  form: "single",
@@ -52634,12 +52754,30 @@ Object.defineProperty(exports, "failureContributionCapability", {
52634
52754
  return failureContributionCapability;
52635
52755
  }
52636
52756
  });
52757
+ Object.defineProperty(exports, "ffmpegRate", {
52758
+ enumerable: true,
52759
+ get: function() {
52760
+ return ffmpegRate;
52761
+ }
52762
+ });
52637
52763
  Object.defineProperty(exports, "gbToBytes", {
52638
52764
  enumerable: true,
52639
52765
  get: function() {
52640
52766
  return gbToBytes;
52641
52767
  }
52642
52768
  });
52769
+ Object.defineProperty(exports, "gifDeriveSpeed", {
52770
+ enumerable: true,
52771
+ get: function() {
52772
+ return gifDeriveSpeed;
52773
+ }
52774
+ });
52775
+ Object.defineProperty(exports, "gifFromMp4Args", {
52776
+ enumerable: true,
52777
+ get: function() {
52778
+ return gifFromMp4Args;
52779
+ }
52780
+ });
52643
52781
  Object.defineProperty(exports, "hfModelUrl", {
52644
52782
  enumerable: true,
52645
52783
  get: function() {