@camstack/addon-osd-manager 0.1.147 → 0.1.149

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 (18) hide show
  1. package/dist/{MotionZonesSettings-Cl9gZOV7.mjs → MotionZonesSettings-B4cQcURa.mjs} +2 -2
  2. package/dist/{PrivacyMaskSettings-CmjVGh1h.mjs → PrivacyMaskSettings-Dv7f5TJH.mjs} +4 -4
  3. package/dist/{SceneMonitorEditor-Dax82W7l.mjs → SceneMonitorEditor-BH5IfvJF.mjs} +3 -3
  4. package/dist/_stub.js +11 -11
  5. package/dist/{_virtual_mf-localSharedImportMap___mfe_internal__addon_osd_manager_page-DCyAXIPW.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_osd_manager_page-CH1D8Zk8.mjs} +3 -3
  6. package/dist/_virtual_mf___mfe_internal__addon_osd_manager_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-BiGqIvMa.mjs +26 -0
  7. package/dist/{hostInit-DxFYPF2F.mjs → hostInit-Casu61cJ.mjs} +2 -2
  8. package/dist/index.js +315 -208
  9. package/dist/index.mjs +315 -208
  10. package/dist/{player-overlays-BuQ-2VK8.mjs → player-overlays-DUvUqw-5.mjs} +1 -1
  11. package/dist/remoteEntry.js +1 -1
  12. package/dist/{responsive-BichBHK9.mjs → responsive-BjVZKLm9.mjs} +1 -1
  13. package/dist/{scene-monitor-copy-QX-VgNUL.mjs → scene-monitor-copy-B3JnndNE.mjs} +1 -1
  14. package/dist/{square-DMng_M2f.mjs → square-Cl2KchnS.mjs} +1 -1
  15. package/dist/{trash-2-DNfdpYqK.mjs → trash-2-DTiky27H.mjs} +1 -1
  16. package/dist/{virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_osd_manager_page__remoteEntry_js-BNtu7hef.mjs → virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_osd_manager_page__remoteEntry_js-D8jQU_Fl.mjs} +1 -1
  17. package/package.json +1 -1
  18. package/dist/_virtual_mf___mfe_internal__addon_osd_manager_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-Dmev7UC0.mjs +0 -26
package/dist/index.mjs CHANGED
@@ -5369,7 +5369,7 @@ var ZodIssueCode = {
5369
5369
  var ZodFirstPartyTypeKind;
5370
5370
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5371
5371
  //#endregion
5372
- //#region ../types/dist/sleep-DlrgY4Qb.mjs
5372
+ //#region ../types/dist/sleep-C-v96WpE.mjs
5373
5373
  /**
5374
5374
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5375
5375
  * window to float samples (D455).
@@ -7510,7 +7510,59 @@ var DeviceRole = /* @__PURE__ */ function(DeviceRole) {
7510
7510
  return DeviceRole;
7511
7511
  }({});
7512
7512
  //#endregion
7513
- //#region ../types/dist/composition-BK-GTFYb.mjs
7513
+ //#region ../types/dist/composition-Dq42XWp0.mjs
7514
+ /**
7515
+ * The ffmpeg build every CamStack node downloads, per platform and arch.
7516
+ *
7517
+ * ## Why a download, on every node, including the container
7518
+ *
7519
+ * The version of ffmpeg used to be CODE: baked into the image, changeable only
7520
+ * by rebuilding and rolling it. Now it is DATA — this file states the release,
7521
+ * and a node that boots with a different one downloads it. Changing ffmpeg is a
7522
+ * framework bump, not an image rebuild.
7523
+ *
7524
+ * It also settles the licence question by removing it. FFmpeg's licence is
7525
+ * chosen at compile time: the core is LGPL 2.1+, `--enable-gpl` makes it GPL
7526
+ * (for x264/x265), `--enable-version3` makes that v3, and `--enable-nonfree`
7527
+ * makes the result undistributable. These are GPL v3 builds, and we do not
7528
+ * distribute them: the user's own node fetches the archive from the project
7529
+ * that publishes it, so we convey no GPL work and inherit none of the
7530
+ * obligations that come with conveying one. That is the whole reason the image
7531
+ * no longer installs ffmpeg at all — not a technical preference.
7532
+ *
7533
+ * ## Why jellyfin-ffmpeg
7534
+ *
7535
+ * One vendor covering linux-amd64, linux-arm64, darwin-arm64 and darwin-x64
7536
+ * from one release, with the widest hardware surface of anything maintained:
7537
+ * VAAPI, QSV, NVENC/NVDEC, AMF, Vulkan, OpenCL and DRM on amd64, plus Rockchip
7538
+ * MPP on arm64. It reaches the vendor libraries through dlopen trampolines,
7539
+ * so the binary is not linked against a driver stack it may not find.
7540
+ *
7541
+ * **What it still needs from the host, measured 2026-09-19.** On the Unraid
7542
+ * HOST, which has no libva, `-vaapi_device` aborts the process outright —
7543
+ * `implib-gen: libva-drm.so.2: failed to load library ... Assertion '0 &&
7544
+ * "Assertion in generated code"' failed`. Inside our container, which installs
7545
+ * libva plus the iHD driver, the same command encodes: verified end to end with
7546
+ * `testsrc → format=nv12,hwupload → h264_vaapi`. So the image drops ffmpeg and
7547
+ * KEEPS the Intel media stack; the drivers are the part a binary cannot bring.
7548
+ *
7549
+ * ## Why each artifact carries a checksum and a claim
7550
+ *
7551
+ * The download is now the only source, so `sha256` is verified before anything
7552
+ * is extracted — jellyfin publishes no checksums on its release assets, so
7553
+ * these are ours, taken at the version bump. And `expectedHwaccels` is what the
7554
+ * build is supposed to be able to do: a binary that probes short of its own
7555
+ * claim is a source that changed under us, which is precisely what went
7556
+ * unnoticed for months when a static build turned out to carry no VAAPI at all
7557
+ * (D536).
7558
+ */
7559
+ /** The pinned jellyfin-ffmpeg release. Changing this is the version change. */
7560
+ var FFMPEG_RELEASE = "8.1.2-5";
7561
+ var BASE = `https://github.com/jellyfin/jellyfin-ffmpeg/releases/download/v${FFMPEG_RELEASE}`;
7562
+ function portable(target) {
7563
+ return `${BASE}/jellyfin-ffmpeg_${FFMPEG_RELEASE}_portable_${target}-gpl.tar.xz`;
7564
+ }
7565
+ portable("linux64"), portable("linuxarm64"), portable("macarm64"), portable("mac64");
7514
7566
  /**
7515
7567
  * LA tabella "quale booleano di questo tipo di device conta come ALTO", e il
7516
7568
  * valutatore puro del suo FRONTE.
@@ -8316,7 +8368,6 @@ var CompositionSchema = object({
8316
8368
  });
8317
8369
  new Set([
8318
8370
  "track",
8319
- "summary",
8320
8371
  "face",
8321
8372
  "identity",
8322
8373
  "plate",
@@ -13848,6 +13899,70 @@ var CompositionBlockStateSchema = object({
13848
13899
  reason: string().optional(),
13849
13900
  fields: array(CompositionFieldStateSchema)
13850
13901
  });
13902
+ var NUMBER = {
13903
+ kind: "fixed",
13904
+ result: ["number"]
13905
+ };
13906
+ var BOOLEAN = {
13907
+ kind: "fixed",
13908
+ result: ["boolean"]
13909
+ };
13910
+ Object.freeze({
13911
+ min: NUMBER,
13912
+ max: NUMBER,
13913
+ abs: NUMBER,
13914
+ floor: NUMBER,
13915
+ ceil: NUMBER,
13916
+ sqrt: NUMBER,
13917
+ round: NUMBER,
13918
+ pow: NUMBER,
13919
+ clamp: NUMBER,
13920
+ avg: NUMBER,
13921
+ sum: NUMBER,
13922
+ age: NUMBER,
13923
+ convert: NUMBER,
13924
+ coalesce: { kind: "coalesce" },
13925
+ any: BOOLEAN,
13926
+ all: BOOLEAN,
13927
+ within: BOOLEAN,
13928
+ latest: {
13929
+ kind: "fixed",
13930
+ result: ["number", "null"]
13931
+ },
13932
+ number: {
13933
+ kind: "fixed",
13934
+ result: ["number", "null"]
13935
+ },
13936
+ rose: {
13937
+ kind: "fixed",
13938
+ result: ["number", "null"]
13939
+ },
13940
+ count: NUMBER
13941
+ });
13942
+ `${COMPOSED_DEVICE_STABLE_ID_PREFIX}`;
13943
+ /**
13944
+ * What a composition may BUILD on a device type (G2, D676): the caps a new
13945
+ * device of that type, or an existing one that lacks them, can be given. The
13946
+ * blockers are the validator's own refusal codes, and a spec compares this
13947
+ * listing with `planComposition` for every capability — the editor can never
13948
+ * offer a feature the save would refuse for the same reason.
13949
+ */
13950
+ var ComposableFieldSchema = object({
13951
+ path: string(),
13952
+ kind: CompositionFieldKindSchema,
13953
+ nullable: boolean(),
13954
+ required: boolean(),
13955
+ enumValues: array(string()).optional()
13956
+ });
13957
+ var ComposableCapabilitiesSchema = object({ caps: array(object({
13958
+ cap: string(),
13959
+ fields: array(ComposableFieldSchema),
13960
+ /** Present for an item-array cap (`consumables.items`). */
13961
+ itemArray: object({
13962
+ path: string(),
13963
+ keyField: string()
13964
+ }).optional()
13965
+ })) });
13851
13966
  /** Where a block runs. The operator chooses — a block driving a device on an
13852
13967
  * agent is the reason placement is not fixed to the hub. */
13853
13968
  var CoreBlockPlacementSchema = union([literal("hub"), string().min(1)]);
@@ -14078,6 +14193,14 @@ var coreBlocksCapability = {
14078
14193
  stableId: string().min(1)
14079
14194
  }), CompositionCustomizationReadSchema, { auth: "admin" }),
14080
14195
  /**
14196
+ * The capabilities a composition may BUILD on a device of `deviceType`
14197
+ * (a new device, or added to an existing one), with their fields — the
14198
+ * editor's feature list and the presets' availability (G2, D676). Built
14199
+ * from the validator's own blockers; a replace of a BOUND cap is not
14200
+ * listed here (the device's bindings say what it has).
14201
+ */
14202
+ listComposableCaps: method(object({ deviceType: _enum(DeviceType) }), ComposableCapabilitiesSchema, { auth: "admin" }),
14203
+ /**
14081
14204
  * Validate without saving — the same verdict the save reaches. A mutation
14082
14205
  * for its body size; it writes nothing, so its access is `view`.
14083
14206
  */
@@ -23400,6 +23523,102 @@ var oauthIntegrationCapability = {
23400
23523
  getDescriptor: method(_void(), OauthIntegrationDescriptorSchema, { auth: "admin" }) }
23401
23524
  };
23402
23525
  /**
23526
+ * What started a camera's onboard motion (D672). `camera` is the camera's own
23527
+ * firmware; `sensor` is a device the operator ATTACHED to it. Absent on the
23528
+ * wire means the camera: only the camera-sensors bridge ever says `sensor`.
23529
+ */
23530
+ var MotionTriggeredBySchema = discriminatedUnion("kind", [object({ kind: literal("camera") }), object({
23531
+ kind: literal("sensor"),
23532
+ deviceId: number().int().positive()
23533
+ })]);
23534
+ Object.freeze({ kind: "camera" });
23535
+ var CameraSensorRefSchema = object({
23536
+ addonId: string().min(1),
23537
+ stableId: string().min(1)
23538
+ });
23539
+ function cameraSensorRefKey(ref) {
23540
+ return `${ref.addonId}/${ref.stableId}`;
23541
+ }
23542
+ /** CS-1 accepts exactly one mode; CS-2 (D673) widens it to confirm / replace. */
23543
+ var CameraSensorsModeSchema = _enum(["in-addition"]);
23544
+ var CameraSensorsConfigSchema = object({
23545
+ mode: CameraSensorsModeSchema,
23546
+ sensors: array(CameraSensorRefSchema).min(1).max(8)
23547
+ }).superRefine((value, ctx) => {
23548
+ const seen = /* @__PURE__ */ new Set();
23549
+ value.sensors.forEach((ref, index) => {
23550
+ const key = cameraSensorRefKey(ref);
23551
+ if (seen.has(key)) ctx.addIssue({
23552
+ code: "custom",
23553
+ path: ["sensors", index],
23554
+ message: `duplicate camera sensor ${key}`
23555
+ });
23556
+ seen.add(key);
23557
+ });
23558
+ });
23559
+ var RefFields = {
23560
+ addonId: string(),
23561
+ stableId: string()
23562
+ };
23563
+ var CameraSensorAttachmentSchema = discriminatedUnion("state", [
23564
+ object({
23565
+ ...RefFields,
23566
+ state: literal("ready"),
23567
+ deviceId: number(),
23568
+ name: string(),
23569
+ caps: array(string()).readonly()
23570
+ }),
23571
+ object({
23572
+ ...RefFields,
23573
+ state: literal("offline"),
23574
+ deviceId: number(),
23575
+ name: string(),
23576
+ reason: _enum(["offline", "disabled"])
23577
+ }),
23578
+ object({
23579
+ ...RefFields,
23580
+ state: literal("missing"),
23581
+ reason: string()
23582
+ }),
23583
+ object({
23584
+ ...RefFields,
23585
+ state: literal("unsupported"),
23586
+ deviceId: number(),
23587
+ name: string(),
23588
+ reason: string()
23589
+ }),
23590
+ object({
23591
+ ...RefFields,
23592
+ state: literal("unreadable"),
23593
+ reason: string()
23594
+ })
23595
+ ]);
23596
+ /**
23597
+ * Why a configured camera forwards NOTHING from its sensors, however ready they
23598
+ * are (D672): it does not list `onboard` in `motionSources` (attaching a sensor
23599
+ * does not add it), or it has no active detection config at all (the bridge
23600
+ * reads the active config). Absent = forwarded, or an older node that does not
23601
+ * say.
23602
+ */
23603
+ var CameraSensorsNotForwardedSchema = _enum(["onboard-not-listed", "no-active-detection"]);
23604
+ var CameraSensorsStatusSchema = discriminatedUnion("state", [
23605
+ object({ state: literal("not-configured") }),
23606
+ object({
23607
+ state: literal("unreadable"),
23608
+ reason: string()
23609
+ }),
23610
+ object({
23611
+ state: literal("configured"),
23612
+ mode: CameraSensorsModeSchema,
23613
+ sensors: array(CameraSensorAttachmentSchema).readonly(),
23614
+ notForwarded: CameraSensorsNotForwardedSchema.optional()
23615
+ })
23616
+ ]);
23617
+ Object.freeze({
23618
+ state: "unreadable",
23619
+ reason: "camera sensor mappings not loaded"
23620
+ });
23621
+ /**
23403
23622
  * A model choice has a SCOPE, and a scope change has a workflow.
23404
23623
  *
23405
23624
  * ## The two scopes
@@ -24148,6 +24367,12 @@ var MotionEventSchema = object({
24148
24367
  /** Populated by B5 (recording playback URL for this event). */
24149
24368
  mediaUrl: string().optional(),
24150
24369
  /**
24370
+ * The FIRST trigger of an `onboard` episode, written once at open (D672).
24371
+ * Absent = not recorded (a row written before D672, or an analyzer /
24372
+ * device-activity episode) — never read as "the camera" (D393).
24373
+ */
24374
+ triggeredBy: MotionTriggeredBySchema.optional(),
24375
+ /**
24151
24376
  * One row per motion EPISODE, not one per push (D475). `null` while the
24152
24377
  * episode is still open — a further rising edge extends it in place rather
24153
24378
  * than inserting a new row. Set once, at close, to `lastOnAt - startedAt`
@@ -24306,6 +24531,21 @@ var ObjectEventSchema = object({
24306
24531
  keyFrameMediaId: number().int().optional(),
24307
24532
  /** Populated by B5 (recording playback URL for this event). */
24308
24533
  mediaUrl: string().optional(),
24534
+ /**
24535
+ * When the change this row records HAPPENED, epoch ms, when that is earlier
24536
+ * than {@link timestamp} and the producer could date it (D684).
24537
+ *
24538
+ * Set on a package PICK-UP row only: its `timestamp` is when the departure
24539
+ * was CONCLUDED — five minutes of unseen observed time after the parcel went
24540
+ * — and a notification's footage has to be cut around the pick-up, not the
24541
+ * empty doormat after it (D682). Stored so every path that rebuilds a
24542
+ * notification subject from the row (the boot reconcile, a dry-run) anchors
24543
+ * on the same instant the live hook did.
24544
+ *
24545
+ * `timestamp` keeps its meaning. Absent on every other row and on every
24546
+ * pick-up written before D684 — UNKNOWN, never 0 and never `timestamp`.
24547
+ */
24548
+ observedAt: number().optional(),
24309
24549
  /** The parent track's key-event importance [0,1], propagated to every object
24310
24550
  * event of the track (so an event row can be sorted by importance without a
24311
24551
  * track join). Absent on legacy rows / before the track was scored. */
@@ -24641,131 +24881,6 @@ var RecentTracksQueryInput = object({
24641
24881
  /** See {@link ExcludeSourcesDoc}. */
24642
24882
  excludeSources: array(TrackSourceSchema).optional()
24643
24883
  });
24644
- /**
24645
- * A Summary (D359): the per-camera session envelope that references tracks.
24646
- * `groupShotMediaId` is the media ROW id of its group shot (`ownerKind:
24647
- * 'summary'`, served by the event-media plane at `/m/<id>`), null until the
24648
- * first frame with a member visible has been materialised (D482 — it was the
24649
- * row's composite key, which embedded the owner and could name another table's
24650
- * row once event ids became per-table rowids).
24651
- */
24652
- var SummarySchema = object({
24653
- id: string(),
24654
- deviceId: number(),
24655
- openedAt: number(),
24656
- lastActiveAt: number(),
24657
- sealedAt: number().nullable(),
24658
- memberCount: number().int().nonnegative(),
24659
- groupShotMediaId: number().int().nullable()
24660
- });
24661
- var SummariesQueryInput = object({
24662
- deviceIds: array(number()).min(1),
24663
- since: number().optional(),
24664
- until: number().optional(),
24665
- limit: number().int().min(1).max(200).default(50),
24666
- /** The same member-wise filter {@link listRecentSummaries} takes — one
24667
- * meaning of "dog" on every summary surface. */
24668
- classes: array(string().min(1).max(60)).max(40).optional()
24669
- });
24670
- var SummaryDetailSchema = object({
24671
- summary: SummarySchema,
24672
- /** Members in absorption order, oldest join first. */
24673
- members: array(object({
24674
- trackId: string(),
24675
- /**
24676
- * The track's class at the time it JOINED, or `null` when it was unresolved
24677
- * and the track no longer exists to fill it.
24678
- *
24679
- * The join, not the latest opinion: class voting can re-decide a track's
24680
- * class afterwards, and a group's composition is the history of who came
24681
- * together. A consumer counts these to badge a thumbnail — "two people and a
24682
- * dog" — rather than being handed a second, denormalised tally that would
24683
- * drift from the members it claims to describe.
24684
- */
24685
- className: string().nullable(),
24686
- /** `primary` is the one member that carries the group's identity. */
24687
- role: _enum([
24688
- "primary",
24689
- "sibling",
24690
- "child"
24691
- ]).nullable(),
24692
- joinedAt: number(),
24693
- /** Tier 1 — the sub-class (`dog`, `van`), resolved from the member's track
24694
- * at read time. Absent when nothing resolved, never an empty string. */
24695
- label: string().optional(),
24696
- /** Tier 2 — the instance: a person's name, a plate. Absent when the pipeline
24697
- * recognised nobody, and absent for a member whose track has been pruned —
24698
- * a thumbnail that names the wrong person is worse than one naming nobody. */
24699
- subLabel: string().optional()
24700
- })).readonly()
24701
- });
24702
- /**
24703
- * What a LIST of groups carries: the envelope plus what it is MADE OF.
24704
- *
24705
- * Coarse on purpose — the operator's rule is "only the rough data on the list,
24706
- * we extend when we notice we need more". Enough to draw the card ("two people
24707
- * and a dog") and no more. The MEMBERS, their names and the per-member links
24708
- * are on {@link getSummary}: shipping every member of every group so a client
24709
- * can count them turns a page of two hundred groups into a thousand records to
24710
- * draw two hundred badges.
24711
- */
24712
- var SummaryListItemSchema = object({
24713
- summary: SummarySchema,
24714
- /** Class counts, most numerous first; `className: null` is a member whose
24715
- * class never resolved, counted so the counts add up to `memberCount`. */
24716
- classes: array(object({
24717
- className: string().nullable(),
24718
- count: number().int().positive()
24719
- })).readonly()
24720
- });
24721
- var SummariesPageSchema = object({ summaries: array(SummaryListItemSchema).readonly() });
24722
- /**
24723
- * The paged feed, deliberately the SAME shape as {@link RecentTracksQueryInput}.
24724
- *
24725
- * The reel on the cameras page and the Events gallery both ride a cursor, so a
24726
- * summaries feed that could only answer "the last N for these cameras"
24727
- * (`listSummaries`) would make groups available in the timeline and nowhere
24728
- * else. Two feeds with different ordering contracts would be two ideas of what
24729
- * "newest" means, on one screen.
24730
- */
24731
- var RecentSummariesQueryInput = object({
24732
- /** Devices to merge. An empty array yields an empty page. */
24733
- deviceIds: array(number()),
24734
- /** Window lower bound on `lastActiveAt` (inclusive). */
24735
- since: number().optional(),
24736
- /** Window upper bound on `lastActiveAt` (inclusive). */
24737
- until: number().optional(),
24738
- limit: number().int().min(1).max(500).default(100),
24739
- /** Opaque continuation cursor from a previous page's `nextCursor`. */
24740
- cursor: string().optional(),
24741
- /**
24742
- * Restrict to these classes — THE SAME FIELD `listRecentTracks` takes, and
24743
- * deliberately the same name: the events filter tree emits one list of ticked
24744
- * taxonomy nodes, and a summaries feed that called it something else would
24745
- * make the operator's one filter component produce two shapes.
24746
- *
24747
- * A question about the MEMBERS: a group matches when ANY of them does. "Show
24748
- * me the arrivals with a dog" has to return the group of four people who had
24749
- * one with them; a filter on the group's own fields could only ever answer
24750
- * about its primary.
24751
- *
24752
- * Matched against all THREE tiers of a member — the class (`animal`), the
24753
- * sub-class (`dog`) and the instance (a name, a plate) — because which tier a
24754
- * ticked node lives on is the taxonomy's business, not the caller's. `dog` is
24755
- * an event kind in the tree and a tier-1 label on an `animal` track; a filter
24756
- * that read only the class would answer "animal" and never "dog".
24757
- *
24758
- * ABSENT or EMPTY means no filter — absent is not a selection of none.
24759
- */
24760
- classes: array(string().min(1).max(60)).max(40).optional()
24761
- });
24762
- var RecentSummariesPageSchema = object({
24763
- /** Ordered by (`lastActiveAt` DESC, id DESC). Same light item as
24764
- * {@link listSummaries} — one list shape, so a card renders the same
24765
- * whichever feed drew it. */
24766
- summaries: array(SummaryListItemSchema).readonly(),
24767
- nextCursor: string().nullable()
24768
- });
24769
24884
  var RecentTracksPageSchema = object({
24770
24885
  /** Merged page, ordered by (`lastSeen` DESC, `trackId` DESC). */
24771
24886
  tracks: array(TrackSchema).readonly(),
@@ -25303,15 +25418,6 @@ var pipelineAnalyticsCapability = {
25303
25418
  * are not included (same contract as `listTracks`).
25304
25419
  */
25305
25420
  listRecentTracks: method(RecentTracksQueryInput, RecentTracksPageSchema),
25306
- /** Newest first by `openedAt`, for a camera set, inside an optional window. */
25307
- listSummaries: method(SummariesQueryInput, SummariesPageSchema),
25308
- /**
25309
- * The PAGED feed — the reel and the Events gallery. Same cursor contract as
25310
- * {@link listRecentTracks}, so one screen cannot hold two ideas of newest.
25311
- */
25312
- listRecentSummaries: method(RecentSummariesQueryInput, RecentSummariesPageSchema),
25313
- /** One summary with its member track ids; `null` for an id nobody wrote. */
25314
- getSummary: method(object({ id: string() }), SummaryDetailSchema.nullable()),
25315
25421
  clearTracks: method(object({ deviceId: number() }), _void(), {
25316
25422
  kind: "mutation",
25317
25423
  auth: "admin"
@@ -27338,6 +27444,23 @@ var MotionSourceEnum = _enum([
27338
27444
  */
27339
27445
  var MotionSourcesSchema = array(MotionSourceEnum);
27340
27446
  /**
27447
+ * The operator-facing name of each MOTION source (D672: `onboard` = the
27448
+ * camera's sensors — its own motion plus any sensor attached to it). The wire
27449
+ * value stays `onboard`; only the label changed. `detectionSources: 'onboard'`
27450
+ * ("Camera onboard AI") and the notification source filter keep their labels.
27451
+ */
27452
+ var MOTION_SOURCE_LABELS = {
27453
+ analyzer: "Frame-diff Analyzer (motion addon)",
27454
+ onboard: "Camera sensors",
27455
+ "device-activity": "Device activity (the device says it is working)"
27456
+ };
27457
+ /** The order the motion-source picker offers them in (not the enum's order). */
27458
+ var MOTION_SOURCE_PICKER_ORDER = [
27459
+ "analyzer",
27460
+ "onboard",
27461
+ "device-activity"
27462
+ ];
27463
+ /**
27341
27464
  * Which root detector a camera runs — EXACTLY ONE.
27342
27465
  *
27343
27466
  * Deliberately the SAME vocabulary post-analysis already tags every detection
@@ -27684,7 +27807,14 @@ var RunnerCameraConfigSchema = object({
27684
27807
  */
27685
27808
  inferenceDevices: array(RunnerInferenceDeviceSchema).readonly().optional()
27686
27809
  });
27687
- 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;
27810
+ MOTION_SOURCE_PICKER_ORDER.map((value) => value === "onboard" ? {
27811
+ value,
27812
+ label: MOTION_SOURCE_LABELS[value],
27813
+ description: "The camera's own motion, plus any sensor attached to it"
27814
+ } : {
27815
+ value,
27816
+ label: MOTION_SOURCE_LABELS[value]
27817
+ }), 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;
27688
27818
  /**
27689
27819
  * Runtime load summary returned by `getLocalLoad`. Used by the orchestrator's
27690
27820
  * load-balancing levels (L2 capacity-based, L3 hardware-aware) to decide
@@ -28450,6 +28580,11 @@ var CameraStatusSchema = object({
28450
28580
  */
28451
28581
  switchedOff: array(CameraSwitchIdSchema).readonly(),
28452
28582
  /**
28583
+ * The camera's attached sensors (D672). Optional only for a status composed
28584
+ * by an orchestrator older than D672; this orchestrator always sets it.
28585
+ */
28586
+ cameraSensors: CameraSensorsStatusSchema.optional(),
28587
+ /**
28453
28588
  * Stages of the bounded fan-out that were CUT SHORT — a timeout or a
28454
28589
  * rejection — and whose block is therefore `null` because we could not
28455
28590
  * READ it, not because there is nothing there.
@@ -28554,6 +28689,16 @@ var NodeInferenceDevicesSchema = object({
28554
28689
  * Strictly the control plane: never sees a frame, never calls inference,
28555
28690
  * never drains queues. The runner does that work locally on each agent.
28556
28691
  */
28692
+ /**
28693
+ * The input of `setCameraSensors` (G5, D676): the ONE typed write path of a
28694
+ * camera's attached sensors (D672). `config: null` removes the attachment —
28695
+ * the camera reads `not-configured` again, never `unreadable`.
28696
+ */
28697
+ var SetCameraSensorsInputSchema = object({
28698
+ deviceId: number().int().nonnegative(),
28699
+ /** `null` removes the attachment: the camera goes back to `not-configured`. */
28700
+ config: CameraSensorsConfigSchema.nullable()
28701
+ });
28557
28702
  var pipelineOrchestratorCapability = {
28558
28703
  name: "pipeline-orchestrator",
28559
28704
  scope: "system",
@@ -29019,6 +29164,18 @@ var pipelineOrchestratorCapability = {
29019
29164
  */
29020
29165
  getCameraStatuses: method(object({ deviceIds: array(number()).optional() }), array(CameraStatusSchema).readonly()),
29021
29166
  /**
29167
+ * Attach sensors to a camera, or detach them with `config: null` (D672
29168
+ * configuration, G5/D676). Written to the orchestrator's per-device store
29169
+ * under the same key `applyDeviceSettingsPatch` writes, and announced as a
29170
+ * settings change so the camera-sensors bridge refreshes. Refused by name
29171
+ * — nothing written — for a device that cannot be read, does not exist,
29172
+ * is not a camera, or names itself as its own sensor.
29173
+ */
29174
+ setCameraSensors: method(SetCameraSensorsInputSchema, object({ success: literal(true) }), {
29175
+ kind: "mutation",
29176
+ auth: "admin"
29177
+ }),
29178
+ /**
29022
29179
  * Disk-wins fleet reconcile after a recordings wipe. Starts the walk in
29023
29180
  * the addon process and returns immediately with the job snapshot — the
29024
29181
  * work outlives the tRPC/UDS 60s timeout. Poll `getReconcileFromDiskStatus`.
@@ -37492,7 +37649,9 @@ var MotionOnMotionChangedDataSchema = object({
37492
37649
  detected: boolean(),
37493
37650
  timestamp: number(),
37494
37651
  source: MotionSourceEnum,
37495
- regions: array(MotionRegionSchema).readonly().optional()
37652
+ regions: array(MotionRegionSchema).readonly().optional(),
37653
+ /** Who started it (D672). Absent = the camera itself. Only `onboard` carries `sensor`. */
37654
+ triggeredBy: MotionTriggeredBySchema.optional()
37496
37655
  });
37497
37656
  var motionCapability = {
37498
37657
  name: "motion",
@@ -44759,47 +44918,6 @@ var zoneRulesCapability = {
44759
44918
  */
44760
44919
  durability: "restored"
44761
44920
  };
44762
- var NUMBER = {
44763
- kind: "fixed",
44764
- result: ["number"]
44765
- };
44766
- var BOOLEAN = {
44767
- kind: "fixed",
44768
- result: ["boolean"]
44769
- };
44770
- Object.freeze({
44771
- min: NUMBER,
44772
- max: NUMBER,
44773
- abs: NUMBER,
44774
- floor: NUMBER,
44775
- ceil: NUMBER,
44776
- sqrt: NUMBER,
44777
- round: NUMBER,
44778
- pow: NUMBER,
44779
- clamp: NUMBER,
44780
- avg: NUMBER,
44781
- sum: NUMBER,
44782
- age: NUMBER,
44783
- convert: NUMBER,
44784
- coalesce: { kind: "coalesce" },
44785
- any: BOOLEAN,
44786
- all: BOOLEAN,
44787
- within: BOOLEAN,
44788
- latest: {
44789
- kind: "fixed",
44790
- result: ["number", "null"]
44791
- },
44792
- number: {
44793
- kind: "fixed",
44794
- result: ["number", "null"]
44795
- },
44796
- rose: {
44797
- kind: "fixed",
44798
- result: ["number", "null"]
44799
- },
44800
- count: NUMBER
44801
- });
44802
- `${COMPOSED_DEVICE_STABLE_ID_PREFIX}`;
44803
44921
  /**
44804
44922
  * Most specific first. Extending this list is how a new device kind becomes
44805
44923
  * gateable; nothing else needs to change.
@@ -47448,6 +47566,12 @@ Object.freeze({
47448
47566
  addonId: null,
47449
47567
  access: "view"
47450
47568
  },
47569
+ "coreBlocks.listComposableCaps": {
47570
+ capName: "core-blocks",
47571
+ capScope: "system",
47572
+ addonId: null,
47573
+ access: "view"
47574
+ },
47451
47575
  "coreBlocks.listCompositions": {
47452
47576
  capName: "core-blocks",
47453
47577
  capScope: "system",
@@ -50418,12 +50542,6 @@ Object.freeze({
50418
50542
  addonId: null,
50419
50543
  access: "view"
50420
50544
  },
50421
- "pipelineAnalytics.getSummary": {
50422
- capName: "pipeline-analytics",
50423
- capScope: "device",
50424
- addonId: null,
50425
- access: "view"
50426
- },
50427
50545
  "pipelineAnalytics.getTrack": {
50428
50546
  capName: "pipeline-analytics",
50429
50547
  capScope: "device",
@@ -50484,12 +50602,6 @@ Object.freeze({
50484
50602
  addonId: null,
50485
50603
  access: "view"
50486
50604
  },
50487
- "pipelineAnalytics.listRecentSummaries": {
50488
- capName: "pipeline-analytics",
50489
- capScope: "device",
50490
- addonId: null,
50491
- access: "view"
50492
- },
50493
50605
  "pipelineAnalytics.listRecentTracks": {
50494
50606
  capName: "pipeline-analytics",
50495
50607
  capScope: "device",
@@ -50520,12 +50632,6 @@ Object.freeze({
50520
50632
  addonId: null,
50521
50633
  access: "view"
50522
50634
  },
50523
- "pipelineAnalytics.listSummaries": {
50524
- capName: "pipeline-analytics",
50525
- capScope: "device",
50526
- addonId: null,
50527
- access: "view"
50528
- },
50529
50635
  "pipelineAnalytics.listTrackMedia": {
50530
50636
  capName: "pipeline-analytics",
50531
50637
  capScope: "device",
@@ -51150,6 +51256,12 @@ Object.freeze({
51150
51256
  addonId: null,
51151
51257
  access: "create"
51152
51258
  },
51259
+ "pipelineOrchestrator.setCameraSensors": {
51260
+ capName: "pipeline-orchestrator",
51261
+ capScope: "system",
51262
+ addonId: null,
51263
+ access: "create"
51264
+ },
51153
51265
  "pipelineOrchestrator.setCameraStepOverride": {
51154
51266
  capName: "pipeline-orchestrator",
51155
51267
  capScope: "system",
@@ -54695,11 +54807,6 @@ Object.freeze({
54695
54807
  form: "single",
54696
54808
  optional: true
54697
54809
  }],
54698
- "pipelineAnalytics.listRecentSummaries": [{
54699
- name: "deviceIds",
54700
- form: "array",
54701
- optional: false
54702
- }],
54703
54810
  "pipelineAnalytics.listRecentTracks": [{
54704
54811
  name: "deviceIds",
54705
54812
  form: "array",
@@ -54710,11 +54817,6 @@ Object.freeze({
54710
54817
  form: "array",
54711
54818
  optional: true
54712
54819
  }],
54713
- "pipelineAnalytics.listSummaries": [{
54714
- name: "deviceIds",
54715
- form: "array",
54716
- optional: false
54717
- }],
54718
54820
  "pipelineAnalytics.listTrackMedia": [{
54719
54821
  name: "deviceId",
54720
54822
  form: "single",
@@ -54870,6 +54972,11 @@ Object.freeze({
54870
54972
  form: "single",
54871
54973
  optional: false
54872
54974
  }],
54975
+ "pipelineOrchestrator.setCameraSensors": [{
54976
+ name: "deviceId",
54977
+ form: "single",
54978
+ optional: false
54979
+ }],
54873
54980
  "pipelineOrchestrator.setCameraStepOverride": [{
54874
54981
  name: "deviceId",
54875
54982
  form: "single",
@@ -1,5 +1,5 @@
1
1
  import { h as e, l as t, u as n, y as r } from "./_virtual_mf___mfe_internal__addon_osd_manager_page__loadShare__react__loadShare__.js-Bs1t18EM.mjs";
2
- import { o as i, s as a } from "./responsive-BichBHK9.mjs";
2
+ import { o as i, s as a } from "./responsive-BjVZKLm9.mjs";
3
3
  import { n as o, r as s, t as c } from "./_virtual_mf___mfe_internal__addon_osd_manager_page__loadShare__react_mf_1_jsx_mf_2_runtime__loadShare__.js-DalfdIDw.mjs";
4
4
  var l = a("chevron-down", [["path", {
5
5
  d: "m6 9 6 6 6-6",