@camstack/ui-library 1.2.191 → 1.2.192

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
@@ -13,7 +13,7 @@ import * as __mfHostReactDOMClient from "react-dom/client";
13
13
  import { createRoot } from "react-dom/client";
14
14
  import * as __mfHostTrpcClient from "@trpc/client";
15
15
  import { createTRPCClient, createWSClient, httpLink, splitLink, wsLink } from "@trpc/client";
16
- import { ALL_CAPABILITY_DEFINITIONS, CAM_PROFILE_ORDER, CONTAINER_CHILD_PRIORITY, DEFAULT_EVENTS_BAND_BUFFER_SEC, DEFAULT_EVENT_COLOR, DEVICE_TYPE_CONTROL_KIND, DeviceExportStatusSchema, DeviceFeature, DeviceRole, DeviceType, EVENT_TAXONOMY, EventCategory, ExposedDeviceSchema, FIRST_LEVEL_MACRO_CLASSES, KNOWN_CAP_NAMES, MAX_SENSOR_TRIGGER_DEVICES, MODEL_PROVIDER_IDS, NAVIGATION_LIGHT_LEVEL_MAX, NAVIGATION_LIGHT_LEVEL_MIN, PET_FEEDER_MANUAL_FEED_MAX, PET_FEEDER_MANUAL_FEED_MIN, RECORDING_AUDIO_TRIGGER_OFFERED_DBFS, RecordingConfigSchema, RecordingStatusSchema, SOURCE_CAP_ACTIVE_FIELD, STATIONARY_OVERLAY_STYLE, TIMEZONES, buildModelVariantGroups, canConvertUnit, clusterStepSettingFieldsFor, createDeviceProxy, createLazyTrpcSource, createSliceHandle, deriveRecordingMode, describeModelVariant, findTimezone, formatParkedFor, resolveContainerPrimaryChild, resolveDeviceControlKind, resolveRecordingProfiles, resolveVariantModelId, resolveViewableDeviceIds, selectAssignedProfileSlots, tryConvertUnit } from "@camstack/types";
16
+ import { ALL_CAPABILITY_DEFINITIONS, CAM_PROFILE_ORDER, CLIP_STILL_DISPOSITION_HEADER, CLIP_STILL_REASON_CODE_HEADER, CLIP_STILL_REASON_HEADER, CONTAINER_CHILD_PRIORITY, DEFAULT_EVENTS_BAND_BUFFER_SEC, DEFAULT_EVENT_COLOR, DEVICE_TYPE_CONTROL_KIND, DeviceExportStatusSchema, DeviceFeature, DeviceRole, DeviceType, EVENT_TAXONOMY, EventCategory, ExposedDeviceSchema, FIRST_LEVEL_MACRO_CLASSES, KNOWN_CAP_NAMES, MAX_SENSOR_TRIGGER_DEVICES, MODEL_PROVIDER_IDS, NAVIGATION_LIGHT_LEVEL_MAX, NAVIGATION_LIGHT_LEVEL_MIN, PET_FEEDER_MANUAL_FEED_MAX, PET_FEEDER_MANUAL_FEED_MIN, RECORDING_AUDIO_TRIGGER_OFFERED_DBFS, RecordingConfigSchema, RecordingStatusSchema, SOURCE_CAP_ACTIVE_FIELD, STATIONARY_OVERLAY_STYLE, TIMEZONES, buildModelVariantGroups, canConvertUnit, clusterStepSettingFieldsFor, createDeviceProxy, createLazyTrpcSource, createSliceHandle, deriveRecordingMode, describeModelVariant, findTimezone, formatParkedFor, resolveContainerPrimaryChild, resolveDeviceControlKind, resolveRecordingProfiles, resolveVariantModelId, resolveViewableDeviceIds, selectAssignedProfileSlots, tryConvertUnit } from "@camstack/types";
17
17
  import { createSystem } from "@camstack/sdk";
18
18
  import { z } from "zod";
19
19
  //#region ../../node_modules/lucide-react/dist/esm/shared/src/utils/mergeClasses.js
@@ -6383,6 +6383,8 @@ var usePipelineAnalyticsGetTrackMedia = trpc.pipelineAnalytics.getTrackMedia.use
6383
6383
  var usePipelineAnalyticsListTrackMedia = trpc.pipelineAnalytics.listTrackMedia.useQuery;
6384
6384
  /** Generated alias around `trpc.pipelineAnalytics.listEventMedia.useQuery`. */
6385
6385
  var usePipelineAnalyticsListEventMedia = trpc.pipelineAnalytics.listEventMedia.useQuery;
6386
+ /** Generated alias around `trpc.pipelineAnalytics.ownersWithMedia.useQuery`. */
6387
+ var usePipelineAnalyticsOwnersWithMedia = trpc.pipelineAnalytics.ownersWithMedia.useQuery;
6386
6388
  /** Generated alias around `trpc.pipelineAnalytics.searchObjectEvents.useQuery`. */
6387
6389
  var usePipelineAnalyticsSearchObjectEvents = trpc.pipelineAnalytics.searchObjectEvents.useQuery;
6388
6390
  /** Generated alias around `trpc.pipelineAnalytics.wipeObjectEmbeddings.useMutation`. */
@@ -17770,6 +17772,201 @@ var Skeleton = forwardRef(({ className, ...props }, ref) => {
17770
17772
  });
17771
17773
  Skeleton.displayName = "Skeleton";
17772
17774
  //#endregion
17775
+ //#region src/composites/cap-settings/recording-timeline-model.ts
17776
+ /** Tie-break precedence for a bucket's dominant kind (first wins on equal count). */
17777
+ var KIND_PRECEDENCE = [
17778
+ "object",
17779
+ "motion",
17780
+ "audio"
17781
+ ];
17782
+ /**
17783
+ * Convert server-side density rows into `DensityBucket[]` for the timeline
17784
+ * heatmap. Rows with total === 0 are skipped (defensive; server already omits
17785
+ * them). Returns a sparse, ascending-by-index array — EventHeatmap positions
17786
+ * each bar by `b.startMs` rather than array index, so gaps are fine.
17787
+ */
17788
+ function densityRowsToBuckets(rows, windowFrom, bucketMs) {
17789
+ const buckets = [];
17790
+ for (const row of rows) {
17791
+ const counts = {
17792
+ motion: row.motion,
17793
+ object: row.object,
17794
+ audio: row.audio
17795
+ };
17796
+ const total = counts.motion + counts.object + counts.audio;
17797
+ if (total === 0) continue;
17798
+ const index = Math.floor((row.bucketStart - windowFrom) / bucketMs);
17799
+ let dominant = null;
17800
+ let best = -1;
17801
+ for (const kind of KIND_PRECEDENCE) if (counts[kind] > best) {
17802
+ best = counts[kind];
17803
+ dominant = kind;
17804
+ }
17805
+ buckets.push({
17806
+ index,
17807
+ startMs: row.bucketStart,
17808
+ endMs: row.bucketStart + bucketMs,
17809
+ counts,
17810
+ total,
17811
+ dominant
17812
+ });
17813
+ }
17814
+ return buckets.toSorted((a, b) => a.index - b.index);
17815
+ }
17816
+ /** Distance from `ms` to the interval `[startMs, endMs]` (0 if inside). */
17817
+ function distanceToSpan(ms, span) {
17818
+ if (ms < span.startMs) return span.startMs - ms;
17819
+ if (ms > span.endMs) return ms - span.endMs;
17820
+ return 0;
17821
+ }
17822
+ /**
17823
+ * Resolve a playback window for a click at `clickMs` against recorded `spans`.
17824
+ * Inside a span → play from the click to that span's end. In a gap / outside →
17825
+ * snap to the WHOLE nearest span. No spans → null (nothing to play).
17826
+ * `spans` are expected ascending by start (as `mergeAvailabilitySpans` returns).
17827
+ */
17828
+ function seekTargetForSpans(clickMs, spans) {
17829
+ if (spans.length === 0) return null;
17830
+ const containing = spans.find((s) => clickMs >= s.startMs && clickMs <= s.endMs);
17831
+ if (containing) return {
17832
+ fromMs: clickMs,
17833
+ toMs: containing.endMs
17834
+ };
17835
+ let nearest = null;
17836
+ let bestDist = Infinity;
17837
+ for (const s of spans) {
17838
+ const d = distanceToSpan(clickMs, s);
17839
+ if (d < bestDist) {
17840
+ bestDist = d;
17841
+ nearest = s;
17842
+ }
17843
+ }
17844
+ return nearest ? {
17845
+ fromMs: nearest.startMs,
17846
+ toMs: nearest.endMs
17847
+ } : null;
17848
+ }
17849
+ /**
17850
+ * Position `ms` inside the window `[fromMs, toMs]` as a clamped percentage
17851
+ * (0–100). A zero/negative-width window yields 0. Callers use this for `left:`.
17852
+ */
17853
+ function pctForMs(ms, fromMs, toMs) {
17854
+ const span = toMs - fromMs;
17855
+ if (span <= 0) return 0;
17856
+ const pct = (ms - fromMs) / span * 100;
17857
+ if (pct < 0) return 0;
17858
+ if (pct > 100) return 100;
17859
+ return pct;
17860
+ }
17861
+ /**
17862
+ * Build a DayWindow for the given calendar `date` using local time.
17863
+ * For any day strictly in the past: `fromMs` = local midnight, `toMs` =
17864
+ * next local midnight (exactly 24 h).
17865
+ * For today (or any future day that contains `nowMs`): `toMs = nowMs` so the
17866
+ * window never extends into the future.
17867
+ */
17868
+ function dayWindow(date, nowMs) {
17869
+ const fromMs = new Date(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0, 0).getTime();
17870
+ const nextMidnight = new Date(date.getFullYear(), date.getMonth(), date.getDate() + 1, 0, 0, 0, 0).getTime();
17871
+ return {
17872
+ fromMs,
17873
+ toMs: Math.max(fromMs, Math.min(nextMidnight, nowMs))
17874
+ };
17875
+ }
17876
+ /** Available zoom levels in ms, from widest (24h) to narrowest (15 min). */
17877
+ var ZOOM_LEVELS = [
17878
+ 24 * 36e5,
17879
+ 12 * 36e5,
17880
+ 6 * 36e5,
17881
+ 36e5,
17882
+ 15 * 6e4
17883
+ ];
17884
+ /**
17885
+ * Produce a `levelMs`-wide window whose RIGHT edge stays anchored at
17886
+ * `rightEdgeMs` (clamped within `dayBounds`), rather than centring on the view
17887
+ * midpoint. On today's timeline the view's right edge is "now", so zooming this
17888
+ * way keeps the most recent footage pinned to the right instead of drifting to
17889
+ * a midday range that no longer contains now. Panning then moves back/forward.
17890
+ *
17891
+ * Falls back to `dayBounds` when `levelMs` meets or exceeds the day span (can't
17892
+ * show a wider window than the day holds — e.g. early morning with little
17893
+ * elapsed time).
17894
+ */
17895
+ function zoomWindowAnchoredRight(dayBounds, levelMs, rightEdgeMs) {
17896
+ if (levelMs >= dayBounds.toMs - dayBounds.fromMs) return dayBounds;
17897
+ const toMs = Math.min(Math.max(rightEdgeMs, dayBounds.fromMs + levelMs), dayBounds.toMs);
17898
+ return {
17899
+ fromMs: toMs - levelMs,
17900
+ toMs
17901
+ };
17902
+ }
17903
+ /**
17904
+ * Shift `win` by `deltaMs`, preserving width, clamped within `dayBounds`.
17905
+ */
17906
+ function panWindow(win, dayBounds, deltaMs) {
17907
+ const width = win.toMs - win.fromMs;
17908
+ let fromMs = win.fromMs + deltaMs;
17909
+ let toMs = win.toMs + deltaMs;
17910
+ if (fromMs < dayBounds.fromMs) {
17911
+ fromMs = dayBounds.fromMs;
17912
+ toMs = fromMs + width;
17913
+ }
17914
+ if (toMs > dayBounds.toMs) {
17915
+ toMs = dayBounds.toMs;
17916
+ fromMs = toMs - width;
17917
+ }
17918
+ return {
17919
+ fromMs,
17920
+ toMs
17921
+ };
17922
+ }
17923
+ /** Candidate bucket sizes in ms (coarsest first). */
17924
+ var BUCKET_CANDIDATES = [
17925
+ 15 * 6e4,
17926
+ 5 * 6e4,
17927
+ 6e4,
17928
+ 3e4,
17929
+ 15e3,
17930
+ 5e3
17931
+ ];
17932
+ /**
17933
+ * Choose a sensible heatmap bucket size for a visible span of `spanMs`,
17934
+ * targeting ~96-120 buckets. Always picks from `BUCKET_CANDIDATES`.
17935
+ */
17936
+ function bucketMsForSpan(spanMs) {
17937
+ const targetBucket = spanMs / 100;
17938
+ for (const candidate of BUCKET_CANDIDATES) if (candidate <= targetBucket) return candidate;
17939
+ return BUCKET_CANDIDATES[BUCKET_CANDIDATES.length - 1] ?? 5e3;
17940
+ }
17941
+ /**
17942
+ * Produce `count` evenly-spaced axis ticks spanning [fromMs, toMs].
17943
+ * - `pct` is via pctForMs (first=0, last=100).
17944
+ * - `label` is a localised HH:MM clock string.
17945
+ */
17946
+ function axisTicks(fromMs, toMs, count) {
17947
+ if (count <= 1) return [{
17948
+ pct: 0,
17949
+ label: new Date(fromMs).toLocaleTimeString(void 0, {
17950
+ hour: "2-digit",
17951
+ minute: "2-digit"
17952
+ })
17953
+ }];
17954
+ const ticks = [];
17955
+ for (let i = 0; i < count; i++) {
17956
+ const ms = fromMs + i / (count - 1) * (toMs - fromMs);
17957
+ const pct = pctForMs(ms, fromMs, toMs);
17958
+ const label = new Date(ms).toLocaleTimeString(void 0, {
17959
+ hour: "2-digit",
17960
+ minute: "2-digit"
17961
+ });
17962
+ ticks.push({
17963
+ pct,
17964
+ label
17965
+ });
17966
+ }
17967
+ return ticks;
17968
+ }
17969
+ //#endregion
17773
17970
  //#region src/hooks/use-is-mobile.ts
17774
17971
  var MOBILE_QUERY = "(max-width: 767px)";
17775
17972
  /**
@@ -18406,6 +18603,266 @@ function ErrorBox({ message, title, onRetry, action, variant = "danger", classNa
18406
18603
  });
18407
18604
  }
18408
18605
  //#endregion
18606
+ //#region src/composites/cap-settings/EventHeatmap.tsx
18607
+ var KIND_BG = {
18608
+ motion: "bg-emerald-500",
18609
+ object: "bg-violet-500",
18610
+ audio: "bg-orange-500"
18611
+ };
18612
+ function EventHeatmap({ windowFrom, windowTo, buckets, selectedIndex, onSelectBucket }) {
18613
+ const peak = buckets.reduce((m, b) => Math.max(m, b.total), 0);
18614
+ const firstBucket = buckets[0];
18615
+ const bucketWidthPct = firstBucket ? pctForMs(firstBucket.endMs, windowFrom, windowTo) - pctForMs(firstBucket.startMs, windowFrom, windowTo) : 0;
18616
+ return /* @__PURE__ */ jsx("div", {
18617
+ className: "relative h-6 rounded bg-background/40",
18618
+ children: buckets.map((b) => {
18619
+ if (b.total === 0 || b.dominant === null) return null;
18620
+ const heightPct = peak > 0 ? Math.max(15, b.total / peak * 100) : 0;
18621
+ const left = pctForMs(b.startMs, windowFrom, windowTo);
18622
+ const selected = b.index === selectedIndex;
18623
+ return /* @__PURE__ */ jsx("button", {
18624
+ type: "button",
18625
+ "data-testid": "heatmap-bar",
18626
+ title: `${new Date(b.startMs).toLocaleTimeString(void 0, {
18627
+ hour: "2-digit",
18628
+ minute: "2-digit"
18629
+ })} · motion ${b.counts.motion} · object ${b.counts.object}`,
18630
+ onClick: () => onSelectBucket(b.index),
18631
+ className: `absolute bottom-0 rounded-t-sm transition-opacity ${KIND_BG[b.dominant]} ${selected ? "opacity-100 ring-1 ring-amber-400" : "opacity-80 hover:opacity-100"}`,
18632
+ style: {
18633
+ left: `${left}%`,
18634
+ width: `${Math.max(.6, bucketWidthPct)}%`,
18635
+ height: `${heightPct}%`
18636
+ }
18637
+ }, b.index);
18638
+ })
18639
+ });
18640
+ }
18641
+ //#endregion
18642
+ //#region src/composites/cap-settings/TimelineControls.tsx
18643
+ /** Format a Date as "YYYY-MM-DD" for <input type="date">. */
18644
+ function formatDateInput(date) {
18645
+ return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, "0")}-${String(date.getDate()).padStart(2, "0")}`;
18646
+ }
18647
+ /** Parse "YYYY-MM-DD" from <input type="date"> into a local-midnight Date. */
18648
+ function parseDateInput(value) {
18649
+ const parts = value.split("-");
18650
+ const y = parts[0] !== void 0 ? parseInt(parts[0], 10) : NaN;
18651
+ const m = parts[1] !== void 0 ? parseInt(parts[1], 10) : NaN;
18652
+ const d = parts[2] !== void 0 ? parseInt(parts[2], 10) : NaN;
18653
+ if (isNaN(y) || isNaN(m) || isNaN(d)) return null;
18654
+ return new Date(y, m - 1, d);
18655
+ }
18656
+ /**
18657
+ * Date selector + prev/next pan + zoom-in / zoom-out buttons for the recording
18658
+ * timeline. Zoom cycles through ZOOM_LEVELS (widest → narrowest), anchored on
18659
+ * the view's RIGHT edge — so on today's timeline "now" stays pinned to the right
18660
+ * instead of drifting to a midday range. The ◀ / ▶ buttons step the visible
18661
+ * window earlier/later within the day (the discoverable equivalent of the
18662
+ * horizontal wheel-pan wired in RecordingTimeline), so a zoomed-in day can be
18663
+ * navigated back and forth without a mouse wheel.
18664
+ */
18665
+ function TimelineControls({ day, onDayChange, view, dayBounds, onViewChange }) {
18666
+ const handleDateChange = (e) => {
18667
+ const parsed = parseDateInput(e.target.value);
18668
+ if (parsed !== null) onDayChange(parsed);
18669
+ };
18670
+ const viewSpan = view.toMs - view.fromMs;
18671
+ const currentLevelIdx = (() => {
18672
+ let best = 0;
18673
+ let bestDiff = Infinity;
18674
+ for (let i = 0; i < ZOOM_LEVELS.length; i++) {
18675
+ const level = ZOOM_LEVELS[i];
18676
+ if (level === void 0) continue;
18677
+ const diff = Math.abs(level - viewSpan);
18678
+ if (diff < bestDiff) {
18679
+ bestDiff = diff;
18680
+ best = i;
18681
+ }
18682
+ }
18683
+ return best;
18684
+ })();
18685
+ const rightEdgeMs = view.toMs;
18686
+ const handleZoomIn = () => {
18687
+ const nextLevel = ZOOM_LEVELS[Math.min(currentLevelIdx + 1, ZOOM_LEVELS.length - 1)];
18688
+ if (nextLevel === void 0) return;
18689
+ onViewChange(zoomWindowAnchoredRight(dayBounds, nextLevel, rightEdgeMs));
18690
+ };
18691
+ const handleZoomOut = () => {
18692
+ const nextLevel = ZOOM_LEVELS[Math.max(currentLevelIdx - 1, 0)];
18693
+ if (nextLevel === void 0) return;
18694
+ onViewChange(zoomWindowAnchoredRight(dayBounds, nextLevel, rightEdgeMs));
18695
+ };
18696
+ const canZoomIn = currentLevelIdx < ZOOM_LEVELS.length - 1;
18697
+ const canZoomOut = currentLevelIdx > 0;
18698
+ const panStepMs = Math.max(1, Math.round(viewSpan * .9));
18699
+ const canPanPrev = view.fromMs > dayBounds.fromMs;
18700
+ const canPanNext = view.toMs < dayBounds.toMs;
18701
+ const handlePanPrev = () => {
18702
+ onViewChange(panWindow(view, dayBounds, -panStepMs));
18703
+ };
18704
+ const handlePanNext = () => {
18705
+ onViewChange(panWindow(view, dayBounds, panStepMs));
18706
+ };
18707
+ return /* @__PURE__ */ jsxs("div", {
18708
+ className: "flex items-center gap-2",
18709
+ children: [
18710
+ /* @__PURE__ */ jsx("input", {
18711
+ type: "date",
18712
+ value: formatDateInput(day),
18713
+ max: formatDateInput(/* @__PURE__ */ new Date()),
18714
+ onChange: handleDateChange,
18715
+ className: "rounded border border-border bg-background px-2 py-0.5 text-[11px] text-foreground focus:outline-none focus:ring-1 focus:ring-primary",
18716
+ "aria-label": "Select recording day"
18717
+ }),
18718
+ /* @__PURE__ */ jsxs("div", {
18719
+ className: "ml-auto flex items-center gap-1",
18720
+ children: [
18721
+ /* @__PURE__ */ jsx("button", {
18722
+ type: "button",
18723
+ onClick: handlePanPrev,
18724
+ disabled: !canPanPrev,
18725
+ title: "Earlier (pan back)",
18726
+ "aria-label": "Pan earlier",
18727
+ className: "rounded p-1 text-foreground-subtle transition-colors hover:bg-background/60 hover:text-foreground disabled:cursor-not-allowed disabled:opacity-40",
18728
+ children: /* @__PURE__ */ jsx(ChevronLeft, { size: 14 })
18729
+ }),
18730
+ /* @__PURE__ */ jsx("button", {
18731
+ type: "button",
18732
+ onClick: handlePanNext,
18733
+ disabled: !canPanNext,
18734
+ title: "Later (pan forward)",
18735
+ "aria-label": "Pan later",
18736
+ className: "rounded p-1 text-foreground-subtle transition-colors hover:bg-background/60 hover:text-foreground disabled:cursor-not-allowed disabled:opacity-40",
18737
+ children: /* @__PURE__ */ jsx(ChevronRight, { size: 14 })
18738
+ }),
18739
+ /* @__PURE__ */ jsx("span", {
18740
+ className: "mx-0.5 h-3 w-px bg-border",
18741
+ "aria-hidden": "true"
18742
+ }),
18743
+ /* @__PURE__ */ jsx("button", {
18744
+ type: "button",
18745
+ onClick: handleZoomOut,
18746
+ disabled: !canZoomOut,
18747
+ title: "Zoom out",
18748
+ "aria-label": "Zoom out",
18749
+ className: "rounded p-1 text-foreground-subtle transition-colors hover:bg-background/60 hover:text-foreground disabled:cursor-not-allowed disabled:opacity-40",
18750
+ children: /* @__PURE__ */ jsx(ZoomOut, { size: 13 })
18751
+ }),
18752
+ /* @__PURE__ */ jsx("button", {
18753
+ type: "button",
18754
+ onClick: handleZoomIn,
18755
+ disabled: !canZoomIn,
18756
+ title: "Zoom in",
18757
+ "aria-label": "Zoom in",
18758
+ className: "rounded p-1 text-foreground-subtle transition-colors hover:bg-background/60 hover:text-foreground disabled:cursor-not-allowed disabled:opacity-40",
18759
+ children: /* @__PURE__ */ jsx(ZoomIn, { size: 13 })
18760
+ })
18761
+ ]
18762
+ }),
18763
+ /* @__PURE__ */ jsx("span", {
18764
+ className: "text-[9px] text-foreground-subtle",
18765
+ children: zoomLabel(viewSpan)
18766
+ })
18767
+ ]
18768
+ });
18769
+ }
18770
+ function zoomLabel(spanMs) {
18771
+ const h = spanMs / 36e5;
18772
+ if (h >= 24) return "24h";
18773
+ if (h >= 1) return `${Math.round(h)}h`;
18774
+ const m = spanMs / 6e4;
18775
+ return `${Math.round(m)}m`;
18776
+ }
18777
+ //#endregion
18778
+ //#region src/composites/clips/ClipBandBar.tsx
18779
+ /**
18780
+ * The clips section's timebar — the recording section's own controls, driving
18781
+ * a clip list instead of a player (D564).
18782
+ *
18783
+ * *"Possiamo utilizzare lo stesso componente della sezione recording con la
18784
+ * timebar dove selezionare un periodo e mostrare le clip solo di quella banda
18785
+ * selezionata, espandibile."* — the operator, 2026-09-20. So this is not a
18786
+ * second timebar: it is `TimelineControls` and `EventHeatmap`, the two pieces
18787
+ * `RecordingTimeline` is itself built from, over the same
18788
+ * `recording-timeline-model` (`dayWindow`, `panWindow`,
18789
+ * `zoomWindowAnchoredRight`, `bucketMsForSpan`, `axisTicks`). One
18790
+ * implementation, one model, two surfaces.
18791
+ *
18792
+ * ## What it does NOT take from the recording timeline
18793
+ *
18794
+ * `CoverageTrack` stays behind. There it is the seek surface — a click drives
18795
+ * the hero player through the `camstack-control` channel or an HLS VOD
18796
+ * request. A copy here would either be a dead bar or a SECOND thing claiming
18797
+ * to move the playhead, and two components holding two ideas of the same
18798
+ * position is the defect this repo keeps paying for. The clips section plays a
18799
+ * clip through `ClipPanel`, which is its own, already-shipped path.
18800
+ *
18801
+ * ## This component is presentational
18802
+ *
18803
+ * It holds no state. The day, the visible window and the picked bucket all
18804
+ * live in `ClipsSection`, because that is where the band is turned into the
18805
+ * `listClips` argument — a bar that kept its own copy of the selection would
18806
+ * be the second authority again, one component down.
18807
+ */
18808
+ /**
18809
+ * How many ms one pixel of horizontal wheel delta pans.
18810
+ *
18811
+ * The same calibration `RecordingTimeline` uses — a standard wheel tick
18812
+ * (~100 px of `deltaX`) pans ~30 min. Two timebars that panned at different
18813
+ * rates would read as two different controls.
18814
+ */
18815
+ var PAN_MS_PER_PX$1 = 18e3 / 100;
18816
+ function ClipBandBar({ day, onDayChange, view, dayBounds, onViewChange, buckets, selectedBucketIndex, onSelectBucket, densityLoading }) {
18817
+ const trackAreaRef = useRef(null);
18818
+ const handleWheel = useCallback((e) => {
18819
+ const deltaX = Math.abs(e.deltaX) > Math.abs(e.deltaY) ? e.deltaX : e.shiftKey ? e.deltaY : 0;
18820
+ if (deltaX === 0) return;
18821
+ e.preventDefault();
18822
+ onViewChange(panWindow(view, dayBounds, deltaX * PAN_MS_PER_PX$1));
18823
+ }, [
18824
+ view,
18825
+ dayBounds,
18826
+ onViewChange
18827
+ ]);
18828
+ const ticks = axisTicks(view.fromMs, view.toMs, 5);
18829
+ return /* @__PURE__ */ jsxs("div", {
18830
+ className: "space-y-1",
18831
+ children: [/* @__PURE__ */ jsx(TimelineControls, {
18832
+ day,
18833
+ onDayChange,
18834
+ view,
18835
+ dayBounds,
18836
+ onViewChange
18837
+ }), /* @__PURE__ */ jsxs("div", {
18838
+ ref: trackAreaRef,
18839
+ onWheel: handleWheel,
18840
+ className: "space-y-1",
18841
+ children: [
18842
+ /* @__PURE__ */ jsx("div", {
18843
+ className: "text-[10px] font-semibold uppercase tracking-wider text-foreground-subtle",
18844
+ children: "Events · density"
18845
+ }),
18846
+ densityLoading ? /* @__PURE__ */ jsx("div", { className: "h-6 animate-pulse rounded bg-background/40" }) : /* @__PURE__ */ jsx(EventHeatmap, {
18847
+ windowFrom: view.fromMs,
18848
+ windowTo: view.toMs,
18849
+ buckets,
18850
+ selectedIndex: selectedBucketIndex,
18851
+ onSelectBucket
18852
+ }),
18853
+ /* @__PURE__ */ jsx("div", {
18854
+ className: "relative h-3",
18855
+ children: ticks.map((tick) => /* @__PURE__ */ jsx("span", {
18856
+ className: "absolute -translate-x-1/2 text-[9px] text-foreground-subtle",
18857
+ style: { left: `${String(tick.pct)}%` },
18858
+ children: tick.label
18859
+ }, tick.pct))
18860
+ })
18861
+ ]
18862
+ })]
18863
+ });
18864
+ }
18865
+ //#endregion
18409
18866
  //#region src/contexts/vod-playback.tsx
18410
18867
  /**
18411
18868
  * VodPlayback — shared context coordinating recorded (VOD) playback between a
@@ -18564,24 +19021,58 @@ function ClipPanel({ deviceId, clip, profile, onProfileChange }) {
18564
19021
  });
18565
19022
  }
18566
19023
  //#endregion
19024
+ //#region src/lib/format-duration.ts
19025
+ /**
19026
+ * How long something lasted, the way this product says it.
19027
+ *
19028
+ * Promoted verbatim from `composites/cap-settings/RecordingPanel.tsx`, which
19029
+ * had been the only place answering this question about MEDIA. It is now the
19030
+ * only place, so a clip's length and a recording's retention read the same.
19031
+ *
19032
+ * Two other private formatters stay where they are, on purpose:
19033
+ * `config-form-field.tsx` formats a config VALUE (sub-second `ms`, `—` for a
19034
+ * value that is not a number), and `scene-monitor-copy.ts`'s `humanDuration`
19035
+ * is deliberately single-unit and coarse for a sentence. Neither is a media
19036
+ * length, and folding them in here would change what they say.
19037
+ */
19038
+ function formatDurationMs(ms) {
19039
+ const totalSec = Math.round(ms / 1e3);
19040
+ const h = Math.floor(totalSec / 3600);
19041
+ const m = Math.floor(totalSec % 3600 / 60);
19042
+ const s = totalSec % 60;
19043
+ if (h > 0) return `${h}h ${m}m`;
19044
+ if (m > 0) return `${m}m ${s}s`;
19045
+ return `${s}s`;
19046
+ }
19047
+ //#endregion
18567
19048
  //#region src/composites/clips/clip-tile-media.ts
18568
19049
  /**
18569
- * Why no still exists, in words. Keyed by the provider's own vocabulary so a
18570
- * reason this table does not know still reaches the operator verbatim.
19050
+ * Why no still exists, in words, keyed by the refusal CODE.
19051
+ *
19052
+ * A code this table does not know falls back to the provider's own prose, so a
19053
+ * firmware inventing a refusal reaches the operator rather than becoming a
19054
+ * blank tile.
18571
19055
  */
18572
19056
  var REFUSAL_TEXT = {
18573
- sleeping: "The camera is asleep — a still would cost a wake",
18574
- "camera-refused": "The camera refused the still request",
18575
- "no-keyframe": "No decodable frame inside this window",
18576
- unsupported: "This source cannot produce stills",
18577
- "queue-full": "The camera is busy — its still queue is full",
18578
- "no-catalog-row": "This clip is no longer in the catalog"
19057
+ sleeping: () => "The camera is asleep — a still would cost a wake",
19058
+ "camera-refused": (reason) => `The camera refused — ${reason}`,
19059
+ "no-keyframe": () => "No decodable frame inside this window",
19060
+ unsupported: () => "This source cannot produce stills",
19061
+ "queue-full": () => "Waiting for the camera — its still queue is full",
19062
+ "camera-backoff": () => "The camera is resting after refusing — trying again shortly",
19063
+ "no-catalog-row": () => "This clip is no longer in the catalog",
19064
+ "unknown-device": () => "This camera is not served here",
19065
+ "uid-missing": () => "The camera’s id is not known yet"
18579
19066
  };
18580
- function refusal(reason) {
19067
+ function wordsFor(code, reason) {
19068
+ const known = code === void 0 ? void 0 : REFUSAL_TEXT[code];
19069
+ return known === void 0 ? reason : known(reason);
19070
+ }
19071
+ function refusal(reason, code) {
18581
19072
  return {
18582
19073
  kind: "unavailable",
18583
19074
  reason,
18584
- text: REFUSAL_TEXT[reason] ?? `Refused: ${reason}`
19075
+ text: wordsFor(code, reason)
18585
19076
  };
18586
19077
  }
18587
19078
  /** What to draw for one clip's tile. */
@@ -18590,7 +19081,7 @@ function resolveTileMedia(clip) {
18590
19081
  kind: "vouched",
18591
19082
  url: clip.thumbnail
18592
19083
  };
18593
- if (clip.thumbnailUnavailable !== void 0) return refusal(clip.thumbnailUnavailable.reason);
19084
+ if (clip.thumbnailUnavailable !== void 0) return refusal(clip.thumbnailUnavailable.reason, clip.thumbnailUnavailable.reason);
18594
19085
  if (clip.thumbnailMint !== void 0) return {
18595
19086
  kind: "mint",
18596
19087
  url: clip.thumbnailMint
@@ -18601,26 +19092,32 @@ function resolveTileMedia(clip) {
18601
19092
  };
18602
19093
  }
18603
19094
  /**
18604
- * A mint that answered 204 — latch its `x-camstack-reason` to this instant.
19095
+ * A 204, as something the tile can draw.
18605
19096
  *
18606
- * The refusal is about NOW (a full queue, a sleeping camera), so it replaces
18607
- * the offer for as long as the tile is mounted and is not retried behind the
18608
- * operator's back. An unknown reason is shown raw rather than dropped: a
18609
- * firmware inventing a refusal must not become a blank tile.
19097
+ * `deferred` is the ONLY answer that comes back, and only because the server
19098
+ * said so. Everything else — an unknown disposition, an absent one, a code
19099
+ * this build has never heard of — is final, so the failure mode of a
19100
+ * vocabulary that moves is a tile that stops early, never one that asks for
19101
+ * ever.
18610
19102
  */
18611
- function latchMintRefusal(reason) {
18612
- return refusal(reason);
19103
+ function describeRefusal(headers) {
19104
+ if (headers.disposition === "deferred") return {
19105
+ kind: "deferred",
19106
+ reason: headers.reason,
19107
+ text: wordsFor(headers.code, headers.reason),
19108
+ retryAfterMs: headers.retryAfterMs ?? null
19109
+ };
19110
+ return refusal(headers.reason, headers.code);
18613
19111
  }
18614
19112
  //#endregion
18615
19113
  //#region src/composites/clips/clip-thumbnail-fetch.ts
18616
19114
  /**
18617
- * Asking a `thumbnailMint` route for a still — and hearing its refusal.
19115
+ * Asking a `thumbnailMint` route for a still — and hearing what it says.
18618
19116
  *
18619
- * The route answers **200** with a JPEG or **204** with the reason in
18620
- * `x-camstack-reason` (`queue-full`, `sleeping`, `camera-refused`,
18621
- * `no-keyframe`, `no-catalog-row`). An `<img src>` cannot read that header:
18622
- * a 204 fires `onerror` with nothing to say, turning a named refusal into an
18623
- * anonymous broken tile. So a mint goes through `fetch`.
19117
+ * The route answers **200** with a JPEG or **204** with a refusal. An
19118
+ * `<img src>` cannot read a 204's headers: it fires `onerror` with nothing to
19119
+ * say, turning a named refusal into an anonymous broken tile. So a mint goes
19120
+ * through `fetch`.
18624
19121
  *
18625
19122
  * **Nothing is appended to the URL.** Both data-plane routes are registered
18626
19123
  * `access: 'authenticated'` and the hub's `/addon/<id>/<prefix>` proxy takes
@@ -18628,8 +19125,18 @@ function latchMintRefusal(reason) {
18628
19125
  * credential (D549 decision 22) — it may sit in history or a `Referer` and
18629
19126
  * open nothing.
18630
19127
  *
18631
- * The refusal is about NOW and is LATCHED by the caller: a camera that just
18632
- * said "busy" is not asked again behind the operator's back.
19128
+ * ## Three headers, one of which decides everything (D563)
19129
+ *
19130
+ * `x-camstack-reason-code` is the token the tile keys its words on,
19131
+ * `x-camstack-reason` is the camera's own prose, and
19132
+ * `x-camstack-disposition` says whether to come back. This module reads them;
19133
+ * it does not classify them. A response with no disposition — every
19134
+ * provider-reolink build before D563 — is FINAL, which is precisely the
19135
+ * behaviour that shipped.
19136
+ *
19137
+ * A thrown fetch is DEFERRED: nothing refused anything, one request lost a
19138
+ * race, and a tile that goes permanently blank for that is the same defect
19139
+ * with a different cause.
18633
19140
  */
18634
19141
  /**
18635
19142
  * Ask a mint route for one still.
@@ -18643,19 +19150,56 @@ async function fetchMintedThumbnail(url, fetcher) {
18643
19150
  try {
18644
19151
  response = await fetcher(url, { credentials: "same-origin" });
18645
19152
  } catch (err) {
18646
- return latchMintRefusal(err instanceof Error ? err.message : String(err));
19153
+ return deferredNetworkFailure(err);
18647
19154
  }
18648
- if (response.status === 204) return latchMintRefusal(response.headers.get("x-camstack-reason") ?? "no reason given");
18649
- if (!response.ok) return latchMintRefusal(`HTTP ${String(response.status)}`);
19155
+ if (response.status === 204) return describeRefusal(refusalHeadersOf(response));
19156
+ if (!response.ok) return describeRefusal({
19157
+ code: void 0,
19158
+ reason: `HTTP ${String(response.status)}`,
19159
+ disposition: void 0
19160
+ });
18650
19161
  try {
18651
19162
  return {
18652
19163
  kind: "image",
18653
19164
  blob: await response.blob()
18654
19165
  };
18655
19166
  } catch (err) {
18656
- return latchMintRefusal(err instanceof Error ? err.message : String(err));
19167
+ return deferredNetworkFailure(err);
18657
19168
  }
18658
19169
  }
19170
+ function refusalHeadersOf(response) {
19171
+ const retryAfter = response.headers.get("retry-after");
19172
+ const seconds = retryAfter === null ? NaN : Number(retryAfter);
19173
+ return {
19174
+ code: response.headers.get(CLIP_STILL_REASON_CODE_HEADER) ?? void 0,
19175
+ reason: response.headers.get(CLIP_STILL_REASON_HEADER) ?? "no reason given",
19176
+ disposition: response.headers.get(CLIP_STILL_DISPOSITION_HEADER) ?? void 0,
19177
+ retryAfterMs: Number.isFinite(seconds) && seconds > 0 ? seconds * 1e3 : null
19178
+ };
19179
+ }
19180
+ function deferredNetworkFailure(err) {
19181
+ return describeRefusal({
19182
+ code: void 0,
19183
+ reason: err instanceof Error ? err.message : String(err),
19184
+ disposition: "deferred"
19185
+ });
19186
+ }
19187
+ /** First wait, doubling from there. */
19188
+ var STILL_RETRY_BASE_MS = 4e3;
19189
+ /** No single wait is longer than this, whatever the server hints. */
19190
+ var STILL_RETRY_MAX_WAIT_MS = 3e4;
19191
+ /** ±25 %: enough to break a synchronised herd, not enough to stop being a
19192
+ * schedule. */
19193
+ var JITTER_FRACTION = .25;
19194
+ /** The next wait, or `null` when the budget is spent. */
19195
+ function planStillRetry(input) {
19196
+ if (input.attempt >= 4 || input.attempt < 0) return null;
19197
+ const curve = STILL_RETRY_BASE_MS * 2 ** input.attempt;
19198
+ const chosen = Math.max(curve, input.serverHintMs ?? 0);
19199
+ const bounded = Math.min(chosen, STILL_RETRY_MAX_WAIT_MS);
19200
+ const jitter = 1 + (input.random() * 2 - 1) * JITTER_FRACTION;
19201
+ return { waitMs: Math.round(bounded * jitter) };
19202
+ }
18659
19203
  //#endregion
18660
19204
  //#region src/composites/clips/ClipTile.tsx
18661
19205
  /**
@@ -18686,7 +19230,7 @@ function clockOf(ms) {
18686
19230
  });
18687
19231
  }
18688
19232
  /**
18689
- * Ask a mint route once, and LATCH whatever it says.
19233
+ * Ask a mint route, and come back only for the answers that say to.
18690
19234
  *
18691
19235
  * The offer is memoised on the three fields it is derived from, not rebuilt
18692
19236
  * per render: `resolveTileMedia` returns a fresh object every call, and an
@@ -18694,8 +19238,12 @@ function clockOf(ms) {
18694
19238
  * effect sets state, is an infinite render loop. It was one here, and it hung
18695
19239
  * the suite rather than failing it.
18696
19240
  *
18697
- * The refusal is latched for the life of the tile: a camera that just said
18698
- * "busy" is not asked again behind the operator's back (D549 decision 5).
19241
+ * A FINAL refusal is latched for the life of the tile: a camera that just said
19242
+ * "asleep" is not asked again behind the operator's back. A DEFERRED one is
19243
+ * not a refusal at all — the still is queued — so the tile keeps showing
19244
+ * loading and re-asks on `planStillRetry`'s bounded, jittered schedule. When
19245
+ * that budget runs out the deferred answer becomes what the tile SAYS, so the
19246
+ * end state is words, never a blank box and never another request (D563).
18699
19247
  */
18700
19248
  function useMintedStill(clip) {
18701
19249
  const offered = useMemo(() => resolveTileMedia(clip), [
@@ -18710,7 +19258,8 @@ function useMintedStill(clip) {
18710
19258
  if (mintUrl === null || typeof fetch !== "function") return void 0;
18711
19259
  let objectUrl = null;
18712
19260
  let cancelled = false;
18713
- (async () => {
19261
+ let timer;
19262
+ const ask = async (attempt) => {
18714
19263
  const answer = await fetchMintedThumbnail(hubPath(mintUrl), fetch);
18715
19264
  if (cancelled) return;
18716
19265
  if (answer.kind === "image") {
@@ -18721,10 +19270,31 @@ function useMintedStill(clip) {
18721
19270
  });
18722
19271
  return;
18723
19272
  }
18724
- setLatched(answer);
18725
- })();
19273
+ if (answer.kind !== "deferred") {
19274
+ setLatched(answer);
19275
+ return;
19276
+ }
19277
+ const plan = planStillRetry({
19278
+ attempt,
19279
+ serverHintMs: answer.retryAfterMs,
19280
+ random: Math.random
19281
+ });
19282
+ if (plan === null) {
19283
+ setLatched({
19284
+ kind: "unavailable",
19285
+ reason: answer.reason,
19286
+ text: answer.text
19287
+ });
19288
+ return;
19289
+ }
19290
+ timer = setTimeout(() => {
19291
+ ask(attempt + 1);
19292
+ }, plan.waitMs);
19293
+ };
19294
+ ask(0);
18726
19295
  return () => {
18727
19296
  cancelled = true;
19297
+ if (timer !== void 0) clearTimeout(timer);
18728
19298
  if (objectUrl !== null) URL.revokeObjectURL(objectUrl);
18729
19299
  };
18730
19300
  }, [mintUrl]);
@@ -18748,16 +19318,27 @@ function ClipTile({ clip, selected, onSelect }) {
18748
19318
  src: media.url,
18749
19319
  alt: "",
18750
19320
  className: "h-full w-full object-cover"
18751
- }) : media.kind === "mint" ? /* @__PURE__ */ jsx(Skeleton, { className: "h-full w-full rounded-none" }) : /* @__PURE__ */ jsx("span", {
19321
+ }) : media.kind === "mint" || media.kind === "deferred" ? /* @__PURE__ */ jsx("span", {
19322
+ role: "status",
19323
+ "aria-label": media.kind === "mint" ? "Loading the still" : media.text,
19324
+ className: "h-full w-full",
19325
+ children: /* @__PURE__ */ jsx(Skeleton, { className: "h-full w-full rounded-none" })
19326
+ }) : /* @__PURE__ */ jsx("span", {
18752
19327
  className: "px-1 text-center leading-tight",
18753
19328
  children: media.text
18754
19329
  })
18755
19330
  }), /* @__PURE__ */ jsxs("div", {
18756
19331
  className: "min-w-0 flex-1 space-y-1",
18757
19332
  children: [
18758
- /* @__PURE__ */ jsx("div", {
18759
- className: "text-sm font-medium text-foreground",
18760
- children: clockOf(clip.timeRange.startMs)
19333
+ /* @__PURE__ */ jsxs("div", {
19334
+ className: "flex items-baseline gap-2",
19335
+ children: [/* @__PURE__ */ jsx("span", {
19336
+ className: "text-sm font-medium text-foreground",
19337
+ children: clockOf(clip.timeRange.startMs)
19338
+ }), /* @__PURE__ */ jsx("span", {
19339
+ className: "text-[11px] text-foreground-subtle",
19340
+ children: clip.inProgress === true ? "Recording…" : formatDurationMs(clip.timeRange.endMs - clip.timeRange.startMs)
19341
+ })]
18761
19342
  }),
18762
19343
  /* @__PURE__ */ jsx("div", {
18763
19344
  className: "text-[10px] text-foreground-subtle",
@@ -18784,6 +19365,29 @@ function ClipTile({ clip, selected, onSelect }) {
18784
19365
  }
18785
19366
  //#endregion
18786
19367
  //#region src/composites/clips/clip-day-window.ts
19368
+ /**
19369
+ * LOCAL calendar-day arithmetic for the clips browser.
19370
+ *
19371
+ * The browser no longer NAVIGATES days — it follows a band selected on the
19372
+ * recording timebar (D564) — but the local day survived the move as the unit
19373
+ * the COST is counted in: a Reolink search is clamped to one camera-local day
19374
+ * per call, so `clip-band.ts` counts a band's local days to decide whether it
19375
+ * may be asked for. The window builder this file used to own went with the day
19376
+ * picker; `recording-timeline-model.ts`'s `dayWindow(date, nowMs)` is the one
19377
+ * that builds windows now, and one directory holding two functions of that
19378
+ * name was the confusion worth deleting.
19379
+ *
19380
+ * Two properties are pinned by spec because both are invisible until they are
19381
+ * wrong:
19382
+ *
19383
+ * - Deriving the day in UTC shifts every band by the browser's offset, and an
19384
+ * operator in Berlin would see a 22:00 clip filed under the next day.
19385
+ * - Walking days by adding 86 400 000 ms repeats or skips a calendar day
19386
+ * across a DST change. The walk goes through `Date`'s own day arithmetic.
19387
+ *
19388
+ * A day id is `YYYY-MM-DD` — it orders lexicographically, which is what lets
19389
+ * the band's day walk terminate on a comparison rather than on a count.
19390
+ */
18787
19391
  function pad2(value) {
18788
19392
  return value < 10 ? `0${String(value)}` : String(value);
18789
19393
  }
@@ -18796,16 +19400,6 @@ function startOfDay(dayId) {
18796
19400
  function toDayId(instant) {
18797
19401
  return `${String(instant.getFullYear())}-${pad2(instant.getMonth() + 1)}-${pad2(instant.getDate())}`;
18798
19402
  }
18799
- /** The half-open local-wall-clock window of one day. */
18800
- function dayWindow$1(dayId) {
18801
- const start = startOfDay(dayId);
18802
- const end = startOfDay(dayId);
18803
- end.setDate(end.getDate() + 1);
18804
- return {
18805
- since: start.getTime(),
18806
- until: end.getTime()
18807
- };
18808
- }
18809
19403
  /** Walk `days` calendar days from `dayId` — DST-safe, because `Date` does it. */
18810
19404
  function shiftDay(dayId, days) {
18811
19405
  const moved = startOfDay(dayId);
@@ -18813,11 +19407,12 @@ function shiftDay(dayId, days) {
18813
19407
  return toDayId(moved);
18814
19408
  }
18815
19409
  /**
18816
- * The day, spelled out for the header.
19410
+ * The day, spelled out — the calendar half of a band's label.
18817
19411
  *
18818
- * An empty list has to say WHICH day it is empty for — "no clips" with no date
18819
- * beside it is the ambiguity this surface exists to remove — so this label is
18820
- * rendered next to every state, not only the populated one.
19412
+ * An empty list has to say WHICH period it is empty for; "no clips" with no
19413
+ * date beside it is the ambiguity this surface exists to remove. `formatBandLabel`
19414
+ * puts the times around it, and every state renders the result, not only the
19415
+ * populated one.
18821
19416
  */
18822
19417
  function formatDayLabel(dayId) {
18823
19418
  return startOfDay(dayId).toLocaleDateString(void 0, {
@@ -18827,6 +19422,77 @@ function formatDayLabel(dayId) {
18827
19422
  day: "numeric"
18828
19423
  });
18829
19424
  }
19425
+ /** Defensive ceiling on the day walk so an inverted band can never loop. */
19426
+ var MAX_WALK_DAYS = 366;
19427
+ /**
19428
+ * How many LOCAL calendar days the half-open band touches.
19429
+ *
19430
+ * The end instant is exclusive, so a band that ends exactly at the next local
19431
+ * midnight is one day, not two — otherwise every whole-day band would report
19432
+ * double what it costs.
19433
+ */
19434
+ function localDaysInBand(band) {
19435
+ const lastInstant = Math.max(band.fromMs, band.toMs - 1);
19436
+ const endDay = toDayId(new Date(lastInstant));
19437
+ let cursor = toDayId(new Date(band.fromMs));
19438
+ let days = 0;
19439
+ while (cursor <= endDay && days < MAX_WALK_DAYS) {
19440
+ days += 1;
19441
+ cursor = shiftDay(cursor, 1);
19442
+ }
19443
+ return days;
19444
+ }
19445
+ /** Whether this band may be asked for, and what it costs, in one value. */
19446
+ function planClipBand(band) {
19447
+ const localDays = localDaysInBand(band);
19448
+ if (localDays > 2) return {
19449
+ kind: "too-wide",
19450
+ band,
19451
+ localDays,
19452
+ maxLocalDays: 2
19453
+ };
19454
+ return {
19455
+ kind: "askable",
19456
+ band,
19457
+ localDays
19458
+ };
19459
+ }
19460
+ /**
19461
+ * The band for the current selection: the picked bucket, or — when nothing is
19462
+ * picked — the whole visible window.
19463
+ *
19464
+ * "Nothing picked means everything visible" is safe here and only here,
19465
+ * because the visible window is itself bounded by the timebar. It is never
19466
+ * "everything the camera holds" (D382's unstated ask).
19467
+ */
19468
+ function bandForSelection(view, bucket) {
19469
+ if (bucket === null) return {
19470
+ fromMs: view.fromMs,
19471
+ toMs: view.toMs
19472
+ };
19473
+ return {
19474
+ fromMs: Math.max(bucket.startMs, view.fromMs),
19475
+ toMs: Math.min(bucket.endMs, view.toMs)
19476
+ };
19477
+ }
19478
+ function formatTime$2(instant) {
19479
+ return new Date(instant).toLocaleTimeString(void 0, {
19480
+ hour: "2-digit",
19481
+ minute: "2-digit"
19482
+ });
19483
+ }
19484
+ /**
19485
+ * The band, spelled out.
19486
+ *
19487
+ * Every state renders it — an empty list has to say WHICH period it is empty
19488
+ * for, the same rule the day label carried before the band replaced it.
19489
+ */
19490
+ function formatBandLabel(band) {
19491
+ const fromDay = toDayId(new Date(band.fromMs));
19492
+ const toDay = toDayId(new Date(Math.max(band.fromMs, band.toMs - 1)));
19493
+ if (fromDay === toDay) return `${formatDayLabel(fromDay)}, ${formatTime$2(band.fromMs)} – ${formatTime$2(band.toMs)}`;
19494
+ return `${formatDayLabel(fromDay)} ${formatTime$2(band.fromMs)} – ${formatDayLabel(toDay)} ${formatTime$2(band.toMs)}`;
19495
+ }
18830
19496
  //#endregion
18831
19497
  //#region src/composites/clips/clip-source-state.ts
18832
19498
  var STATE_COPY = {
@@ -18889,6 +19555,12 @@ function formatCatalogAge(catalogAsOf, now) {
18889
19555
  //#endregion
18890
19556
  //#region src/composites/clips/clip-view-state.ts
18891
19557
  function resolveClipsView(input) {
19558
+ if (input.plan.kind === "too-wide") return {
19559
+ kind: "refused",
19560
+ band: input.plan.band,
19561
+ localDays: input.plan.localDays,
19562
+ maxLocalDays: input.plan.maxLocalDays
19563
+ };
18892
19564
  if (input.clipsStatus === "error") return {
18893
19565
  kind: "failed",
18894
19566
  message: input.clipsError ?? "The clip list could not be read"
@@ -18904,7 +19576,7 @@ function resolveClipsView(input) {
18904
19576
  const clips = input.clips;
18905
19577
  if (clips.length === 0) return {
18906
19578
  kind: "empty",
18907
- dayId: input.dayId,
19579
+ band: input.plan.band,
18908
19580
  answered,
18909
19581
  silent,
18910
19582
  nobodyAnswered: answered.length === 0
@@ -18955,6 +19627,28 @@ function resolveClipsView(input) {
18955
19627
  * camera whose own index disagrees with its own calendar (618, 6–20
18956
19628
  * September) is not quiet either.
18957
19629
  *
19630
+ * ## The period comes from the recording section's timebar, not a day picker
19631
+ *
19632
+ * It shipped with its own `‹ day ›` pair and the operator replaced it the same
19633
+ * way he replaced the chrome: *"Possiamo utilizzare lo stesso componente della
19634
+ * sezione recording con la timebar dove selezionare un periodo e mostrare le
19635
+ * clip solo di quella banda selezionata, espandibile."* So the list follows a
19636
+ * BAND (D564) — `TimelineControls` for the day, the zoom and the pan,
19637
+ * `EventHeatmap` for picking a narrower window out of it, both of them the
19638
+ * pieces `RecordingTimeline` is itself built from, over the same
19639
+ * `recording-timeline-model`. Three things that are decisions, not details:
19640
+ *
19641
+ * - **The band lives HERE, once.** `ClipBandBar` is presentational. Two
19642
+ * components holding two ideas of the selected period is the defect this
19643
+ * repo keeps paying for, and the period is what the query is made of.
19644
+ * - **`CoverageTrack` stayed behind**, because there it is the seek surface
19645
+ * that moves the hero player's playhead. A copy here would be a dead bar or
19646
+ * a second claimant on that position.
19647
+ * - **A band is asked for only if it is affordable.** `clip-band.ts` counts
19648
+ * the LOCAL days it touches — the camera's own search is clamped to one per
19649
+ * call, and a day listing is 4.3–6.0 s on 592 — and refuses past the bound
19650
+ * by name rather than asking and rendering whichever days answered.
19651
+ *
18958
19652
  * ## The picker WRITES nothing, and there is nothing for it to write
18959
19653
  *
18960
19654
  * A clip source is not enabled or disabled — it EXISTS, because of a
@@ -19074,24 +19768,44 @@ function SilentSources({ silent }) {
19074
19768
  });
19075
19769
  }
19076
19770
  function ClipsSection({ deviceId }) {
19077
- const [dayId, setDayId] = useState(() => toDayId(/* @__PURE__ */ new Date()));
19771
+ const [day, setDay] = useState(() => /* @__PURE__ */ new Date());
19772
+ const [view, setView] = useState(() => dayWindow(/* @__PURE__ */ new Date(), Date.now()));
19773
+ const [selectedBucket, setSelectedBucket] = useState(null);
19078
19774
  const [provider, setProvider] = useState("");
19079
19775
  const [page, setPage] = useState(1);
19080
19776
  const [selectedClip, setSelectedClip] = useState(null);
19081
19777
  const [profile, setProfile] = useState("low");
19082
19778
  const presence = useCapabilityPresence("videoclips");
19083
- const window = useMemo(() => dayWindow$1(dayId), [dayId]);
19779
+ const dayBounds = useMemo(() => dayWindow(day, Date.now()), [day]);
19780
+ const bucketMs = bucketMsForSpan(view.toMs - view.fromMs);
19781
+ const density = usePipelineAnalyticsGetEventDensity({
19782
+ deviceId,
19783
+ since: view.fromMs,
19784
+ until: view.toMs,
19785
+ bucketMs
19786
+ });
19787
+ const buckets = useMemo(() => densityRowsToBuckets(density.data ?? [], view.fromMs, bucketMs), [
19788
+ density.data,
19789
+ view.fromMs,
19790
+ bucketMs
19791
+ ]);
19792
+ const selected = selectedBucket === null ? void 0 : buckets.find((b) => b.index === selectedBucket);
19793
+ const band = useMemo(() => bandForSelection(view, selected === void 0 ? null : {
19794
+ startMs: selected.startMs,
19795
+ endMs: selected.endMs
19796
+ }), [view, selected]);
19797
+ const plan = planClipBand(band);
19084
19798
  const sources = useVideoclipsListSources({ deviceId });
19085
19799
  const clips = useVideoclipsListClips({
19086
19800
  deviceId,
19087
- since: window.since,
19088
- until: window.until,
19801
+ since: band.fromMs,
19802
+ until: band.toMs,
19089
19803
  limit: CLIP_PAGE_LIMIT,
19090
19804
  ...provider === "" ? {} : { provider }
19091
- });
19805
+ }, { enabled: plan.kind === "askable" });
19092
19806
  const sourceRows = sources.data ?? [];
19093
- const view = resolveClipsView({
19094
- dayId,
19807
+ const clipsView = resolveClipsView({
19808
+ plan,
19095
19809
  clipsStatus: clips.status,
19096
19810
  clips: clips.data ?? [],
19097
19811
  sourcesStatus: sources.status,
@@ -19123,9 +19837,20 @@ function ClipsSection({ deviceId }) {
19123
19837
  notice: describeSource(row),
19124
19838
  catalogAge: formatCatalogAge(row.availability.catalogAsOf, now)
19125
19839
  })), [sourceRows]);
19126
- const goToDay = (next) => {
19127
- setDayId(next);
19840
+ useEffect(() => {
19128
19841
  setPage(1);
19842
+ }, [band.fromMs, band.toMs]);
19843
+ const handleDayChange = (next) => {
19844
+ setDay(next);
19845
+ setView(dayWindow(next, Date.now()));
19846
+ setSelectedBucket(null);
19847
+ };
19848
+ const handleViewChange = (next) => {
19849
+ setView(next);
19850
+ setSelectedBucket(null);
19851
+ };
19852
+ const handleSelectBucket = (index) => {
19853
+ setSelectedBucket((current) => current === index ? null : index);
19129
19854
  };
19130
19855
  const pick = (next) => {
19131
19856
  setProvider(next);
@@ -19152,18 +19877,25 @@ function ClipsSection({ deviceId }) {
19152
19877
  description: "Nothing is installed that could list a camera's stored clips."
19153
19878
  })
19154
19879
  });
19155
- const visible = view.kind === "listed" ? view.clips : [];
19880
+ const visible = clipsView.kind === "listed" ? clipsView.clips : [];
19156
19881
  const pageClips = visible.slice((page - 1) * TILES_PER_PAGE, page * TILES_PER_PAGE);
19157
19882
  return /* @__PURE__ */ jsxs("div", {
19158
19883
  className: "space-y-3",
19159
19884
  children: [
19160
- /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("h3", {
19161
- className: "text-sm font-semibold text-foreground",
19162
- children: "Clips"
19163
- }), /* @__PURE__ */ jsx("p", {
19164
- className: "mt-1 text-[11px] text-foreground-subtle",
19165
- children: "Every source this camera has, side by side — CamStack's own recordings and whatever the camera or an export keeps of its own. A source is listed because it exists, not because it was switched on here; pick sources to narrow the view."
19166
- })] }),
19885
+ /* @__PURE__ */ jsxs("div", { children: [
19886
+ /* @__PURE__ */ jsx("h3", {
19887
+ className: "text-sm font-semibold text-foreground",
19888
+ children: "Clips"
19889
+ }),
19890
+ /* @__PURE__ */ jsx("p", {
19891
+ className: "mt-1 text-[11px] text-foreground-subtle",
19892
+ children: "Every source this camera has, side by side — CamStack's own recordings and whatever the camera or an export keeps of its own. A source is listed because it exists, not because it was switched on here; pick sources to narrow the view."
19893
+ }),
19894
+ /* @__PURE__ */ jsx("p", {
19895
+ className: "mt-1 text-[11px] text-foreground-subtle",
19896
+ children: "The list follows the period selected on the timebar below — the recording section's own control. Zoom out to widen it, pan or pick a day to move it, click a density bar to narrow it to that window."
19897
+ })
19898
+ ] }),
19167
19899
  /* @__PURE__ */ jsxs("div", {
19168
19900
  className: "flex flex-wrap items-center gap-2",
19169
19901
  children: [
@@ -19188,32 +19920,28 @@ function ClipsSection({ deviceId }) {
19188
19920
  }) : null,
19189
19921
  /* @__PURE__ */ jsxs("div", {
19190
19922
  className: "ml-auto flex items-center gap-1",
19191
- children: [
19192
- /* @__PURE__ */ jsx(Button, {
19193
- variant: "ghost",
19194
- "aria-label": "Previous day",
19195
- onClick: () => goToDay(shiftDay(dayId, -1)),
19196
- children: "‹"
19197
- }),
19198
- /* @__PURE__ */ jsx("span", {
19199
- className: "px-1 text-xs font-medium text-foreground",
19200
- children: formatDayLabel(dayId)
19201
- }),
19202
- /* @__PURE__ */ jsx(Button, {
19203
- variant: "ghost",
19204
- "aria-label": "Next day",
19205
- onClick: () => goToDay(shiftDay(dayId, 1)),
19206
- children: "›"
19207
- }),
19208
- /* @__PURE__ */ jsx(Button, {
19209
- variant: "outline",
19210
- onClick: () => goToDay(toDayId(/* @__PURE__ */ new Date())),
19211
- children: "Today"
19212
- })
19213
- ]
19923
+ children: [/* @__PURE__ */ jsx("span", {
19924
+ className: "px-1 text-xs font-medium text-foreground",
19925
+ children: formatBandLabel(band)
19926
+ }), selectedBucket === null ? null : /* @__PURE__ */ jsx(Button, {
19927
+ variant: "outline",
19928
+ onClick: () => setSelectedBucket(null),
19929
+ children: "Expand to the visible window"
19930
+ })]
19214
19931
  })
19215
19932
  ]
19216
19933
  }),
19934
+ /* @__PURE__ */ jsx(ClipBandBar, {
19935
+ day,
19936
+ onDayChange: handleDayChange,
19937
+ view,
19938
+ dayBounds,
19939
+ onViewChange: handleViewChange,
19940
+ buckets,
19941
+ selectedBucketIndex: selectedBucket,
19942
+ onSelectBucket: handleSelectBucket,
19943
+ densityLoading: density.status === "pending"
19944
+ }),
19217
19945
  /* @__PURE__ */ jsx("section", {
19218
19946
  "aria-label": "Clip sources",
19219
19947
  className: "space-y-1",
@@ -19230,26 +19958,30 @@ function ClipsSection({ deviceId }) {
19230
19958
  /* @__PURE__ */ jsx("section", {
19231
19959
  "aria-label": "Clips",
19232
19960
  className: "space-y-2",
19233
- children: view.kind === "loading" ? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsxs("div", {
19961
+ children: clipsView.kind === "refused" ? /* @__PURE__ */ jsx(ErrorBox, {
19962
+ variant: "warning",
19963
+ title: "That period is too wide to list",
19964
+ message: `${formatBandLabel(clipsView.band)} covers ${String(clipsView.localDays)} local days, and a clip listing is asked one local day at a time — at most ${String(clipsView.maxLocalDays)}. Nothing was asked for; narrow the band and the list follows it.`
19965
+ }) : clipsView.kind === "loading" ? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsxs("div", {
19234
19966
  role: "status",
19235
19967
  className: "text-xs text-foreground-subtle",
19236
19968
  children: [
19237
19969
  "Loading clips for ",
19238
- formatDayLabel(dayId),
19970
+ formatBandLabel(band),
19239
19971
  "…"
19240
19972
  ]
19241
- }), /* @__PURE__ */ jsx(Skeleton, { className: "h-24 w-full" })] }) : view.kind === "failed" ? /* @__PURE__ */ jsx(ErrorBox, {
19973
+ }), /* @__PURE__ */ jsx(Skeleton, { className: "h-24 w-full" })] }) : clipsView.kind === "failed" ? /* @__PURE__ */ jsx(ErrorBox, {
19242
19974
  title: "The clip list could not be read",
19243
- message: view.message
19244
- }) : view.kind === "empty" ? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("div", {
19975
+ message: clipsView.message
19976
+ }) : clipsView.kind === "empty" ? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("div", {
19245
19977
  role: "status",
19246
19978
  children: /* @__PURE__ */ jsx(EmptyState, {
19247
19979
  icon: Film,
19248
- title: view.nobodyAnswered ? `No source could answer for ${formatDayLabel(dayId)}` : `No clips on ${formatDayLabel(dayId)}`,
19249
- ...view.nobodyAnswered ? {} : { description: `Asked ${view.answered.map((notice) => notice.label).join(", ")}.` }
19980
+ title: clipsView.nobodyAnswered ? `No source could answer for ${formatBandLabel(clipsView.band)}` : `No clips in ${formatBandLabel(clipsView.band)}`,
19981
+ ...clipsView.nobodyAnswered ? {} : { description: `Asked ${clipsView.answered.map((notice) => notice.label).join(", ")}.` }
19250
19982
  })
19251
- }), /* @__PURE__ */ jsx(SilentSources, { silent: view.silent })] }) : /* @__PURE__ */ jsxs(Fragment$1, { children: [
19252
- /* @__PURE__ */ jsx(SilentSources, { silent: view.silent }),
19983
+ }), /* @__PURE__ */ jsx(SilentSources, { silent: clipsView.silent })] }) : /* @__PURE__ */ jsxs(Fragment$1, { children: [
19984
+ /* @__PURE__ */ jsx(SilentSources, { silent: clipsView.silent }),
19253
19985
  /* @__PURE__ */ jsx("ul", {
19254
19986
  className: "grid grid-cols-1 gap-2 sm:grid-cols-2 xl:grid-cols-3",
19255
19987
  children: pageClips.map((clip) => /* @__PURE__ */ jsx(ClipTile, {
@@ -21445,201 +22177,6 @@ function formatBytes(bytes) {
21445
22177
  return `${value >= 100 ? Math.round(value).toString() : value.toFixed(1)} ${unit}`;
21446
22178
  }
21447
22179
  //#endregion
21448
- //#region src/composites/cap-settings/recording-timeline-model.ts
21449
- /** Tie-break precedence for a bucket's dominant kind (first wins on equal count). */
21450
- var KIND_PRECEDENCE = [
21451
- "object",
21452
- "motion",
21453
- "audio"
21454
- ];
21455
- /**
21456
- * Convert server-side density rows into `DensityBucket[]` for the timeline
21457
- * heatmap. Rows with total === 0 are skipped (defensive; server already omits
21458
- * them). Returns a sparse, ascending-by-index array — EventHeatmap positions
21459
- * each bar by `b.startMs` rather than array index, so gaps are fine.
21460
- */
21461
- function densityRowsToBuckets(rows, windowFrom, bucketMs) {
21462
- const buckets = [];
21463
- for (const row of rows) {
21464
- const counts = {
21465
- motion: row.motion,
21466
- object: row.object,
21467
- audio: row.audio
21468
- };
21469
- const total = counts.motion + counts.object + counts.audio;
21470
- if (total === 0) continue;
21471
- const index = Math.floor((row.bucketStart - windowFrom) / bucketMs);
21472
- let dominant = null;
21473
- let best = -1;
21474
- for (const kind of KIND_PRECEDENCE) if (counts[kind] > best) {
21475
- best = counts[kind];
21476
- dominant = kind;
21477
- }
21478
- buckets.push({
21479
- index,
21480
- startMs: row.bucketStart,
21481
- endMs: row.bucketStart + bucketMs,
21482
- counts,
21483
- total,
21484
- dominant
21485
- });
21486
- }
21487
- return buckets.toSorted((a, b) => a.index - b.index);
21488
- }
21489
- /** Distance from `ms` to the interval `[startMs, endMs]` (0 if inside). */
21490
- function distanceToSpan(ms, span) {
21491
- if (ms < span.startMs) return span.startMs - ms;
21492
- if (ms > span.endMs) return ms - span.endMs;
21493
- return 0;
21494
- }
21495
- /**
21496
- * Resolve a playback window for a click at `clickMs` against recorded `spans`.
21497
- * Inside a span → play from the click to that span's end. In a gap / outside →
21498
- * snap to the WHOLE nearest span. No spans → null (nothing to play).
21499
- * `spans` are expected ascending by start (as `mergeAvailabilitySpans` returns).
21500
- */
21501
- function seekTargetForSpans(clickMs, spans) {
21502
- if (spans.length === 0) return null;
21503
- const containing = spans.find((s) => clickMs >= s.startMs && clickMs <= s.endMs);
21504
- if (containing) return {
21505
- fromMs: clickMs,
21506
- toMs: containing.endMs
21507
- };
21508
- let nearest = null;
21509
- let bestDist = Infinity;
21510
- for (const s of spans) {
21511
- const d = distanceToSpan(clickMs, s);
21512
- if (d < bestDist) {
21513
- bestDist = d;
21514
- nearest = s;
21515
- }
21516
- }
21517
- return nearest ? {
21518
- fromMs: nearest.startMs,
21519
- toMs: nearest.endMs
21520
- } : null;
21521
- }
21522
- /**
21523
- * Position `ms` inside the window `[fromMs, toMs]` as a clamped percentage
21524
- * (0–100). A zero/negative-width window yields 0. Callers use this for `left:`.
21525
- */
21526
- function pctForMs(ms, fromMs, toMs) {
21527
- const span = toMs - fromMs;
21528
- if (span <= 0) return 0;
21529
- const pct = (ms - fromMs) / span * 100;
21530
- if (pct < 0) return 0;
21531
- if (pct > 100) return 100;
21532
- return pct;
21533
- }
21534
- /**
21535
- * Build a DayWindow for the given calendar `date` using local time.
21536
- * For any day strictly in the past: `fromMs` = local midnight, `toMs` =
21537
- * next local midnight (exactly 24 h).
21538
- * For today (or any future day that contains `nowMs`): `toMs = nowMs` so the
21539
- * window never extends into the future.
21540
- */
21541
- function dayWindow(date, nowMs) {
21542
- const fromMs = new Date(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0, 0).getTime();
21543
- const nextMidnight = new Date(date.getFullYear(), date.getMonth(), date.getDate() + 1, 0, 0, 0, 0).getTime();
21544
- return {
21545
- fromMs,
21546
- toMs: Math.max(fromMs, Math.min(nextMidnight, nowMs))
21547
- };
21548
- }
21549
- /** Available zoom levels in ms, from widest (24h) to narrowest (15 min). */
21550
- var ZOOM_LEVELS = [
21551
- 24 * 36e5,
21552
- 12 * 36e5,
21553
- 6 * 36e5,
21554
- 36e5,
21555
- 15 * 6e4
21556
- ];
21557
- /**
21558
- * Produce a `levelMs`-wide window whose RIGHT edge stays anchored at
21559
- * `rightEdgeMs` (clamped within `dayBounds`), rather than centring on the view
21560
- * midpoint. On today's timeline the view's right edge is "now", so zooming this
21561
- * way keeps the most recent footage pinned to the right instead of drifting to
21562
- * a midday range that no longer contains now. Panning then moves back/forward.
21563
- *
21564
- * Falls back to `dayBounds` when `levelMs` meets or exceeds the day span (can't
21565
- * show a wider window than the day holds — e.g. early morning with little
21566
- * elapsed time).
21567
- */
21568
- function zoomWindowAnchoredRight(dayBounds, levelMs, rightEdgeMs) {
21569
- if (levelMs >= dayBounds.toMs - dayBounds.fromMs) return dayBounds;
21570
- const toMs = Math.min(Math.max(rightEdgeMs, dayBounds.fromMs + levelMs), dayBounds.toMs);
21571
- return {
21572
- fromMs: toMs - levelMs,
21573
- toMs
21574
- };
21575
- }
21576
- /**
21577
- * Shift `win` by `deltaMs`, preserving width, clamped within `dayBounds`.
21578
- */
21579
- function panWindow(win, dayBounds, deltaMs) {
21580
- const width = win.toMs - win.fromMs;
21581
- let fromMs = win.fromMs + deltaMs;
21582
- let toMs = win.toMs + deltaMs;
21583
- if (fromMs < dayBounds.fromMs) {
21584
- fromMs = dayBounds.fromMs;
21585
- toMs = fromMs + width;
21586
- }
21587
- if (toMs > dayBounds.toMs) {
21588
- toMs = dayBounds.toMs;
21589
- fromMs = toMs - width;
21590
- }
21591
- return {
21592
- fromMs,
21593
- toMs
21594
- };
21595
- }
21596
- /** Candidate bucket sizes in ms (coarsest first). */
21597
- var BUCKET_CANDIDATES = [
21598
- 15 * 6e4,
21599
- 5 * 6e4,
21600
- 6e4,
21601
- 3e4,
21602
- 15e3,
21603
- 5e3
21604
- ];
21605
- /**
21606
- * Choose a sensible heatmap bucket size for a visible span of `spanMs`,
21607
- * targeting ~96-120 buckets. Always picks from `BUCKET_CANDIDATES`.
21608
- */
21609
- function bucketMsForSpan(spanMs) {
21610
- const targetBucket = spanMs / 100;
21611
- for (const candidate of BUCKET_CANDIDATES) if (candidate <= targetBucket) return candidate;
21612
- return BUCKET_CANDIDATES[BUCKET_CANDIDATES.length - 1] ?? 5e3;
21613
- }
21614
- /**
21615
- * Produce `count` evenly-spaced axis ticks spanning [fromMs, toMs].
21616
- * - `pct` is via pctForMs (first=0, last=100).
21617
- * - `label` is a localised HH:MM clock string.
21618
- */
21619
- function axisTicks(fromMs, toMs, count) {
21620
- if (count <= 1) return [{
21621
- pct: 0,
21622
- label: new Date(fromMs).toLocaleTimeString(void 0, {
21623
- hour: "2-digit",
21624
- minute: "2-digit"
21625
- })
21626
- }];
21627
- const ticks = [];
21628
- for (let i = 0; i < count; i++) {
21629
- const ms = fromMs + i / (count - 1) * (toMs - fromMs);
21630
- const pct = pctForMs(ms, fromMs, toMs);
21631
- const label = new Date(ms).toLocaleTimeString(void 0, {
21632
- hour: "2-digit",
21633
- minute: "2-digit"
21634
- });
21635
- ticks.push({
21636
- pct,
21637
- label
21638
- });
21639
- }
21640
- return ticks;
21641
- }
21642
- //#endregion
21643
22180
  //#region src/composites/cap-settings/CoverageTrack.tsx
21644
22181
  function CoverageTrack({ windowFrom, windowTo, spans, playheadMs, onSeek, onScrubStart, onScrubMove, onScrubEnd }) {
21645
22182
  const [hoverInfo, setHoverInfo] = useState(null);
@@ -21750,42 +22287,6 @@ function CoverageTrack({ windowFrom, windowTo, spans, playheadMs, onSeek, onScru
21750
22287
  });
21751
22288
  }
21752
22289
  //#endregion
21753
- //#region src/composites/cap-settings/EventHeatmap.tsx
21754
- var KIND_BG = {
21755
- motion: "bg-emerald-500",
21756
- object: "bg-violet-500",
21757
- audio: "bg-orange-500"
21758
- };
21759
- function EventHeatmap({ windowFrom, windowTo, buckets, selectedIndex, onSelectBucket }) {
21760
- const peak = buckets.reduce((m, b) => Math.max(m, b.total), 0);
21761
- const firstBucket = buckets[0];
21762
- const bucketWidthPct = firstBucket ? pctForMs(firstBucket.endMs, windowFrom, windowTo) - pctForMs(firstBucket.startMs, windowFrom, windowTo) : 0;
21763
- return /* @__PURE__ */ jsx("div", {
21764
- className: "relative h-6 rounded bg-background/40",
21765
- children: buckets.map((b) => {
21766
- if (b.total === 0 || b.dominant === null) return null;
21767
- const heightPct = peak > 0 ? Math.max(15, b.total / peak * 100) : 0;
21768
- const left = pctForMs(b.startMs, windowFrom, windowTo);
21769
- const selected = b.index === selectedIndex;
21770
- return /* @__PURE__ */ jsx("button", {
21771
- type: "button",
21772
- "data-testid": "heatmap-bar",
21773
- title: `${new Date(b.startMs).toLocaleTimeString(void 0, {
21774
- hour: "2-digit",
21775
- minute: "2-digit"
21776
- })} · motion ${b.counts.motion} · object ${b.counts.object}`,
21777
- onClick: () => onSelectBucket(b.index),
21778
- className: `absolute bottom-0 rounded-t-sm transition-opacity ${KIND_BG[b.dominant]} ${selected ? "opacity-100 ring-1 ring-amber-400" : "opacity-80 hover:opacity-100"}`,
21779
- style: {
21780
- left: `${left}%`,
21781
- width: `${Math.max(.6, bucketWidthPct)}%`,
21782
- height: `${heightPct}%`
21783
- }
21784
- }, b.index);
21785
- })
21786
- });
21787
- }
21788
- //#endregion
21789
22290
  //#region src/composites/cap-settings/event-thumb.tsx
21790
22291
  function EventThumb({ mediaUrl, kind }) {
21791
22292
  const [failed, setFailed] = useState(false);
@@ -21910,142 +22411,6 @@ function EventBucketStrip({ clips, loading, busyKey, onPlay, enabledKinds, onTog
21910
22411
  });
21911
22412
  }
21912
22413
  //#endregion
21913
- //#region src/composites/cap-settings/TimelineControls.tsx
21914
- /** Format a Date as "YYYY-MM-DD" for <input type="date">. */
21915
- function formatDateInput(date) {
21916
- return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, "0")}-${String(date.getDate()).padStart(2, "0")}`;
21917
- }
21918
- /** Parse "YYYY-MM-DD" from <input type="date"> into a local-midnight Date. */
21919
- function parseDateInput(value) {
21920
- const parts = value.split("-");
21921
- const y = parts[0] !== void 0 ? parseInt(parts[0], 10) : NaN;
21922
- const m = parts[1] !== void 0 ? parseInt(parts[1], 10) : NaN;
21923
- const d = parts[2] !== void 0 ? parseInt(parts[2], 10) : NaN;
21924
- if (isNaN(y) || isNaN(m) || isNaN(d)) return null;
21925
- return new Date(y, m - 1, d);
21926
- }
21927
- /**
21928
- * Date selector + prev/next pan + zoom-in / zoom-out buttons for the recording
21929
- * timeline. Zoom cycles through ZOOM_LEVELS (widest → narrowest), anchored on
21930
- * the view's RIGHT edge — so on today's timeline "now" stays pinned to the right
21931
- * instead of drifting to a midday range. The ◀ / ▶ buttons step the visible
21932
- * window earlier/later within the day (the discoverable equivalent of the
21933
- * horizontal wheel-pan wired in RecordingTimeline), so a zoomed-in day can be
21934
- * navigated back and forth without a mouse wheel.
21935
- */
21936
- function TimelineControls({ day, onDayChange, view, dayBounds, onViewChange }) {
21937
- const handleDateChange = (e) => {
21938
- const parsed = parseDateInput(e.target.value);
21939
- if (parsed !== null) onDayChange(parsed);
21940
- };
21941
- const viewSpan = view.toMs - view.fromMs;
21942
- const currentLevelIdx = (() => {
21943
- let best = 0;
21944
- let bestDiff = Infinity;
21945
- for (let i = 0; i < ZOOM_LEVELS.length; i++) {
21946
- const level = ZOOM_LEVELS[i];
21947
- if (level === void 0) continue;
21948
- const diff = Math.abs(level - viewSpan);
21949
- if (diff < bestDiff) {
21950
- bestDiff = diff;
21951
- best = i;
21952
- }
21953
- }
21954
- return best;
21955
- })();
21956
- const rightEdgeMs = view.toMs;
21957
- const handleZoomIn = () => {
21958
- const nextLevel = ZOOM_LEVELS[Math.min(currentLevelIdx + 1, ZOOM_LEVELS.length - 1)];
21959
- if (nextLevel === void 0) return;
21960
- onViewChange(zoomWindowAnchoredRight(dayBounds, nextLevel, rightEdgeMs));
21961
- };
21962
- const handleZoomOut = () => {
21963
- const nextLevel = ZOOM_LEVELS[Math.max(currentLevelIdx - 1, 0)];
21964
- if (nextLevel === void 0) return;
21965
- onViewChange(zoomWindowAnchoredRight(dayBounds, nextLevel, rightEdgeMs));
21966
- };
21967
- const canZoomIn = currentLevelIdx < ZOOM_LEVELS.length - 1;
21968
- const canZoomOut = currentLevelIdx > 0;
21969
- const panStepMs = Math.max(1, Math.round(viewSpan * .9));
21970
- const canPanPrev = view.fromMs > dayBounds.fromMs;
21971
- const canPanNext = view.toMs < dayBounds.toMs;
21972
- const handlePanPrev = () => {
21973
- onViewChange(panWindow(view, dayBounds, -panStepMs));
21974
- };
21975
- const handlePanNext = () => {
21976
- onViewChange(panWindow(view, dayBounds, panStepMs));
21977
- };
21978
- return /* @__PURE__ */ jsxs("div", {
21979
- className: "flex items-center gap-2",
21980
- children: [
21981
- /* @__PURE__ */ jsx("input", {
21982
- type: "date",
21983
- value: formatDateInput(day),
21984
- max: formatDateInput(/* @__PURE__ */ new Date()),
21985
- onChange: handleDateChange,
21986
- className: "rounded border border-border bg-background px-2 py-0.5 text-[11px] text-foreground focus:outline-none focus:ring-1 focus:ring-primary",
21987
- "aria-label": "Select recording day"
21988
- }),
21989
- /* @__PURE__ */ jsxs("div", {
21990
- className: "ml-auto flex items-center gap-1",
21991
- children: [
21992
- /* @__PURE__ */ jsx("button", {
21993
- type: "button",
21994
- onClick: handlePanPrev,
21995
- disabled: !canPanPrev,
21996
- title: "Earlier (pan back)",
21997
- "aria-label": "Pan earlier",
21998
- className: "rounded p-1 text-foreground-subtle transition-colors hover:bg-background/60 hover:text-foreground disabled:cursor-not-allowed disabled:opacity-40",
21999
- children: /* @__PURE__ */ jsx(ChevronLeft, { size: 14 })
22000
- }),
22001
- /* @__PURE__ */ jsx("button", {
22002
- type: "button",
22003
- onClick: handlePanNext,
22004
- disabled: !canPanNext,
22005
- title: "Later (pan forward)",
22006
- "aria-label": "Pan later",
22007
- className: "rounded p-1 text-foreground-subtle transition-colors hover:bg-background/60 hover:text-foreground disabled:cursor-not-allowed disabled:opacity-40",
22008
- children: /* @__PURE__ */ jsx(ChevronRight, { size: 14 })
22009
- }),
22010
- /* @__PURE__ */ jsx("span", {
22011
- className: "mx-0.5 h-3 w-px bg-border",
22012
- "aria-hidden": "true"
22013
- }),
22014
- /* @__PURE__ */ jsx("button", {
22015
- type: "button",
22016
- onClick: handleZoomOut,
22017
- disabled: !canZoomOut,
22018
- title: "Zoom out",
22019
- "aria-label": "Zoom out",
22020
- className: "rounded p-1 text-foreground-subtle transition-colors hover:bg-background/60 hover:text-foreground disabled:cursor-not-allowed disabled:opacity-40",
22021
- children: /* @__PURE__ */ jsx(ZoomOut, { size: 13 })
22022
- }),
22023
- /* @__PURE__ */ jsx("button", {
22024
- type: "button",
22025
- onClick: handleZoomIn,
22026
- disabled: !canZoomIn,
22027
- title: "Zoom in",
22028
- "aria-label": "Zoom in",
22029
- className: "rounded p-1 text-foreground-subtle transition-colors hover:bg-background/60 hover:text-foreground disabled:cursor-not-allowed disabled:opacity-40",
22030
- children: /* @__PURE__ */ jsx(ZoomIn, { size: 13 })
22031
- })
22032
- ]
22033
- }),
22034
- /* @__PURE__ */ jsx("span", {
22035
- className: "text-[9px] text-foreground-subtle",
22036
- children: zoomLabel(viewSpan)
22037
- })
22038
- ]
22039
- });
22040
- }
22041
- function zoomLabel(spanMs) {
22042
- const h = spanMs / 36e5;
22043
- if (h >= 24) return "24h";
22044
- if (h >= 1) return `${Math.round(h)}h`;
22045
- const m = spanMs / 6e4;
22046
- return `${Math.round(m)}m`;
22047
- }
22048
- //#endregion
22049
22414
  //#region src/composites/cap-settings/RecordingTimeline.tsx
22050
22415
  var ALL_KINDS = [
22051
22416
  "motion",
@@ -22441,15 +22806,6 @@ function RecordingTimeline({ deviceId }) {
22441
22806
  //#endregion
22442
22807
  //#region src/composites/cap-settings/RecordingPanel.tsx
22443
22808
  var DAY_MS$1 = 1440 * 60 * 1e3;
22444
- function formatDuration$1(ms) {
22445
- const totalSec = Math.round(ms / 1e3);
22446
- const h = Math.floor(totalSec / 3600);
22447
- const m = Math.floor(totalSec % 3600 / 60);
22448
- const s = totalSec % 60;
22449
- if (h > 0) return `${h}h ${m}m`;
22450
- if (m > 0) return `${m}m ${s}s`;
22451
- return `${s}s`;
22452
- }
22453
22809
  function RecordingPanel({ deviceId }) {
22454
22810
  const queryClient = useQueryClient();
22455
22811
  const statusQuery = useRecordingGetStatus({ deviceId });
@@ -22549,7 +22905,7 @@ function RecordingPanel({ deviceId }) {
22549
22905
  label: "Recorded (24h)",
22550
22906
  icon: /* @__PURE__ */ jsx(Clock, { className: "h-3.5 w-3.5" }),
22551
22907
  footer: `${ranges.length} segment range${ranges.length === 1 ? "" : "s"}`,
22552
- children: availabilityQuery.isLoading ? "…" : formatDuration$1(recordedMs)
22908
+ children: availabilityQuery.isLoading ? "…" : formatDurationMs(recordedMs)
22553
22909
  })
22554
22910
  ]
22555
22911
  }),
@@ -53370,4 +53726,4 @@ var SceneMonitorEditor = lazy(() => import("./SceneMonitorEditor-BvDy3x3k.js").t
53370
53726
  /** Lazy-wrapped `PrivacyMaskSettings` — code-split off the main bundle. */
53371
53727
  var PrivacyMaskSettings = lazy(() => import("./PrivacyMaskSettings-PkYs077O.js").then((m) => ({ default: m.PrivacyMaskSettings })));
53372
53728
  //#endregion
53373
- export { AddonGlobalSettingsForm, AgentStepEditor, AlarmHeroCard, AlarmInlineControl as AlarmPanelInlineControl, AppShell, ArcKnob, AudioClassificationList, AudioLevelWaveform, AudioWaveform, AutomationHeroCard, AutomationInlineControl, AutotrackSection, BTN_COMPACT, BTN_COMPACT_DANGER, BTN_COMPACT_PRIMARY, BTN_COMPACT_WARNING, Badge, BatteryBadge, BottomSheet, Breadcrumb, BrightnessPanel, Button, ButtonControl, ButtonHeroCard, CARD_MODE_MIN_COLUMNS, CENTER, CHIP_ACTIVE, CHIP_BASE, CHIP_INACTIVE, CLASS_COLORS, COLUMN_BREAKPOINT_CLASS, COLUMN_PRIORITY, COMMIT_DEDUPE_TOLERANCE_MS, COMMIT_DEDUPE_WINDOW_MS, CONTROL_CAP_NAMES, CONTROL_FILLS, CameraStreamPlayer, Card, Checkbox, ChildSectionAccordion, ClimatePanel, CodeBlock, CollapsibleCard, ConfigFormBuilder, FormField as ConfigFormField, ConfigSchemaField, ConfirmActionButton, ConfirmDialogProvider, ConsumablesPanel, ContainerChildrenProvider, ContainerPrimaryHero, ControlColumn, ControlHeroCard, ControlInlineControl, ControlPanel, CopyButton, CoverHeroCard, CoverInlineControl, CoverPanel, CustomFieldRenderersProvider, DEFAULT_COLOR, DEVICE_COLUMNS, DEVICE_LIST_PAGE_SIZE_KEY, DEVICE_LIST_PAGE_SIZE_OPTIONS, DEVICE_ROLE_META, DEVICE_TYPE_CONTROL, DEVICE_TYPE_META, DISPLAY_ICON_REGISTRY, DataTable, DetectionCanvas, DetectionOverlay, DetectionResultTree, DevShell, DeviceActivityPanel, DeviceBatchToolbar, DeviceCard, DeviceContextProvider, DeviceExportPanel, DeviceGrid, DeviceItem, DeviceList, DeviceMultiSelectField, DeviceSelectField, DeviceSelectorPicker, DeviceStepMatrix, Dialog, DialogBody, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, DiscoveryPanel, DoorbellRecentPanel, Dropdown, DropdownContent, DropdownItem, DropdownTrigger, DummyHeroCard, DummyInline, EVENT_KIND_ICONS, EmptyState, ErrorBox, EventKindGlyph, EventStream, FILL, FLEET_LIST_GC_TIME_MS, FLEET_LIST_QUERY_KEY, FLEET_LIST_STALE_TIME_MS, FanHeroCard, FanInlineControl, FanPanel, FilterBar, FloatingEventStream, FloatingLogStream, FloatingPanel, FormField$1 as FormField, GRID_GAP, GRID_PAIRED, GRID_QUICK_STATS, GripTrack, GroupedModelSelector, HOST_WIDGETS, HlsVideo, HoverZoomImage, HumidifierHeroCard, HumidifierInlineControl, INPUT_COMPACT, IconAction, IconButton, ImageHeroCard, ImageInlineControl, ImageSelector, InferenceConfigSelector, Input, KebabMenu, KeyValueList, LIST_ROW, Label, LawnMowerHeroCard, LawnMowerInlineControl, LightHeroCard, LightInlineControl, LockHeroCard, LockInlineControl, LockPanel, LogStream, LoginForm, MODE_COLOR, MaskShapeCanvas, MediaPlayerHeroCard, MediaPlayerInlineControl, MediaPlayerPanel, MobileDrawer, ModelPicker, MotionZonesSettings, NAVIGATION_DRIVE_INTERVAL_MS, NavigationPanel, NetworkLinkBadge, NodeMultiSelectField, NodePicker, NodeSelectField, OfflineBadge, PHASE_CONFIG, PRIORITY, PTZOverlay, PageHeader, PhaseIcon, PipelineBuilder, PipelineRuntimeSelector, PipelineStep, PipelineTreeMatrix, PlayerOverlaysProvider, Popover, PopoverContent, PopoverRowAction, PopoverTrigger, PrimaryChildPicker, PrivacyMaskSettings, ProviderBadge, PtzPanel, QrCode, RECONNECT_POLICY, RECORDED_PLAYBACK_MODES, RIGHT, ROI_AREA_WARN_FRACTION, ROLE_DESCRIPTOR, RadialGauge, RecordedPlaybackProvider, RecordingPanel, ResponseLog, SCENE_CAPTURE_VARIANTS, SECTION_BODY, SECTION_CARD, SECTION_HEADER, SETTING_ROW, SETTING_ROW_LABEL, SETTING_ROW_STACK_BREAKPOINT, SETTING_ROW_VALUE, SETTING_ROW_VALUE_TEXT, SNAPSHOT_MEDIA_PATH, SPLIT_PANEL_OUTER, SPLIT_PANEL_SIDE, STACK_GAP, STATE_COLOR, SceneMonitorEditor, ScopePicker, ScriptHeroCard, ScriptInlineControl, ScrollArea, Select, SemanticBadge, SensorHeroCard, SensorInlineControl, SensorValueAtom, Separator, SettingRow, Sidebar, SidebarItem, Skeleton, SlideOverPanel, SlideToggle, SnapshotButton, SortHeaderButton, StatCard, StateValuesStream, StatusBadge, StepTimings, StepTreeMaster, Stepper, StreamBrokerSelector, StreamDebugOverlay, StreamPanel, Switch, SwitchHeroCard, SwitchInlineControl, SwitchPanel, SystemProvider, TABLE_SCROLL_MAX_H, TEXT_FIELD_LABEL, TEXT_HINT, TEXT_METRIC, TEXT_SECTION_LABEL, TEXT_VALUE, TIMEZONES, Tabs, TabsContent, TabsList, TabsTrigger, TapToggle, ThemeProvider, ThermostatHeroCard, ThermostatInlineControl, TimezoneSelector, Tooltip, TooltipContent, TooltipTrigger, VacuumHeroCard, VacuumInlineControl, ValueReadout, ValveHeroCard, ValveInlineControl, VersionBadge, VodPlaybackProvider, WaterHeaterHeroCard, WaterHeaterInlineControl, WeatherHeroCard, WeatherInlineControl, WidgetMetricCard, WidgetPanel, WidgetRegistryProvider, WidgetSlot, ZoneEditingProvider, ImageOff as a, agentColumnKey, allDeviceTypeFilterOptions, applyFleetQueryDefaults, ariaSortForColumn, badgeFor, buildStepTreeFromSchema, Camera as c, childEntityId, childListName, classifyCapability, cn, columnsForContext, containerChildToRef, countableDevices, coverHighlight, coverageLine, createSharedContext, createTheme, cursorFractionFor, darkColors, defaultTheme, deriveDeviceKind, deriveWebrtcDebugStats, describeDeviceSelector, deviceMatchesFilter, deviceOptionLabel, deviceRoleMeta, deviceRoleMetaOf, deviceTypeLabel, deviceTypeMeta, deviceTypeMetaOf, devicesToOptions, ensureMfHostInit, eventKindLabel, filterDeviceOptions, findTimezone, formatControlDateTime, formatLastSeen, formatNumeric, freezeVerdict, fuzzyMatch, getClassColor, getPhaseVisual, groupAgentColumns, groupChildrenByLayout, hardwareLabel, hubOrigin, hubPath, hubUrl, hubWsUrl, humanDuration, humidifierTint, Mic as i, initialScrubState, isAbsentProvider, isFieldVisible, createLucideIcon as l, lawnMowerActivityMeta, lightColors, loadRemoteBundle, makeScrubBridge, metadataEntries, metadataString, mirror, mountAddonPage, mountPath, Square as n, nextReconnectAction, nextSort, nextSortDirection, nextTableSort, normalizeForSearch, Grid2x2 as o, openTopLayer, overrideEntityIdFromLink, parseRecordedServerMessage, providerIcons, RotateCcw as r, resetHubMountForTests, resolveContainerPrimary, resolveControlAlign, resolveDeviceControl, resolveDisplayIcon, resolveEffectiveDefaultModel, resolveEffectiveStepModel, resolveEventKindIcon, resolvePrimaryChild, resolveSensorDisplay, resolveStepDefaultModel, resolveTableLayout, roiTooLarge, routerBasename, EyeOff as s, scrubReducer, selectedDeviceOptions, serializeRecordedCommand, shouldCommit, shouldEmit, shouldUseSingleNode, sortRows, sortRowsByColumn, statusIcons, statusLine, stepHasModelForFormat, stepModelOptions, stripParentNamePrefix, Trash2 as t, tabForSelector, tankAlert, themeToCss, toStationaryOverlayBox, trpc, useAccessoriesGetStatus, useAccessoriesSetChildHidden, useAddonPagesListPages, useAddonSettingsGetDeviceSettings, useAddonSettingsGetGlobalSettings, useAddonSettingsGetIntegrationSettings, useAddonSettingsUpdateDeviceSettings, useAddonSettingsUpdateGlobalSettings, useAddonWidgetsListWidgets, useAddonsApplyAutoUpdateToAll, useAddonsCancelJob, useAddonsCustom, useAddonsForceRefresh, useAddonsGetAddonAutoUpdate, useAddonsGetAutoUpdateSettings, useAddonsGetJob, useAddonsGetLastRestart, useAddonsGetLogs, useAddonsGetVersions, useAddonsInstallFromWorkspace, useAddonsInstallPackage, useAddonsIsWorkspaceAvailable, useAddonsList, useAddonsListCapabilityProviders, useAddonsListFrameworkPackages, useAddonsListJobs, useAddonsListPackages, useAddonsListUpdates, useAddonsListWorkspacePackages, useAddonsOnAddonLogs, useAddonsReloadPackages, useAddonsRestartAddon, useAddonsRestartServer, useAddonsRetryLoad, useAddonsRollbackPackage, useAddonsSearchAvailable, useAddonsSetAddonAutoUpdate, useAddonsSetAutoUpdateSettings, useAddonsSetCapabilityProviderEnabled, useAddonsStartJob, useAddonsUninstallPackage, useAddonsUpdatePackage, useAirQualitySensorGetStatus, useAlarmPanelArm, useAlarmPanelDisarm, useAlarmPanelGetStatus, useAlarmPanelTrigger, useAlert, useAlertsDismiss, useAlertsEmit, useAlertsGetUnreadCount, useAlertsList, useAlertsMarkAllRead, useAlertsMarkRead, useAlertsUpdate, useAllWidgets, useAmbientLightSensorGetStatus, useAudioAnalysisApplyDeviceSettingsPatch, useAudioAnalysisGetDeviceLiveContribution, useAudioAnalysisGetDeviceSettingsContribution, useAudioAnalysisResolveDeviceSettings, useAudioAnalyzerAnalyseChunk, useAudioAnalyzerAttachDevice, useAudioAnalyzerClassify, useAudioAnalyzerDetachDevice, useAudioAnalyzerDispose, useAudioAnalyzerIsReady, useAudioAnalyzerReprobeAudioEngine, useAudioCodecCanHandle, useAudioCodecCloseSession, useAudioCodecCreateDecodeSession, useAudioCodecCreateEncodeSession, useAudioCodecFlushEncode, useAudioCodecListActiveSessions, useAudioCodecListSupportedCodecs, useAudioCodecPullEncoded, useAudioCodecPullPcm, useAudioCodecPushEncodedFrame, useAudioCodecPushPcm, useAudioMetricsGetCurrentSnapshot, useAudioMetricsGetHistory, useAutomationControlDisable, useAutomationControlEnable, useAutomationControlGetStatus, useAutomationControlTrigger, useBackupCancel, useBackupDelete, useBackupDeleteSchedule, useBackupGetEntries, useBackupList, useBackupListArchives, useBackupListDestinations, useBackupListLocations, useBackupListRuns, useBackupListSchedules, useBackupPreviewSchedule, useBackupRestore, useBackupTrigger, useBackupUpsertDestinationPolicy, useBackupUpsertSchedule, useBatteryGetStatus, useBatteryWakeForStream, useBinaryGetStatus, useBrightnessGetStatus, useBrightnessSetBrightness, useBrokerAdd, useBrokerGet, useBrokerGetBrokerConfig, useBrokerGetSettings, useBrokerGetSettingsSchema, useBrokerGetState, useBrokerGetStatus, useBrokerList, useBrokerListProviders, useBrokerPublish, useBrokerRemove, useBrokerSetSettings, useBrokerSubscribe, useBrokerTestConnection, useBrokerTestSettings, useBrokerUnsubscribe, useButtonPress, useCameraCredentialsGetCredentials, useCameraCredentialsGetStatus, useCameraGridLayoutApplyDeviceSettingsPatch, useCameraGridLayoutGetDeviceLiveContribution, useCameraGridLayoutGetDeviceSettingsContribution, useCameraGridLayoutGetLayout, useCameraGridLayoutSaveLayout, useCameraPipelineConfigApplyDeviceSettingsPatch, useCameraPipelineConfigGetDeviceLiveContribution, useCameraPipelineConfigGetDeviceSettingsContribution, useCameraStreamsGetBrokerStreams, useCameraStreamsGetCameraStreams, useCameraStreamsGetProfileRtspEntries, useCameraStreamsGetRtspEntries, useCameraStreamsPickStream, useCapabilityPresence, useCarbonMonoxideGetStatus, useClimateControlGetStatus, useClimateControlSetFanMode, useClimateControlSetMode, useClimateControlSetPreset, useClimateControlSetSwingHorizontal, useClimateControlSetSwingVertical, useClimateControlSetTarget, useClimateControlSetTargetHumidity, useClimateControlSetTargetRange, useClusterNodes, useClusterTopology, useColorGetStatus, useColorSetColor, useConfirm, useConnectionTestDescribeTest, useConnectionTestTestSettings, useConnectivityGetStatus, useConsumablesGetStatus, useConsumablesReset, useContactGetStatus, useContainerChildren, useControlGetStatus, useControlSetValue, useCoreBlocksCompile, useCoreBlocksCreate, useCoreBlocksDelete, useCoreBlocksGet, useCoreBlocksGetTypeDefs, useCoreBlocksList, useCoreBlocksRestart, useCoreBlocksSetEnabled, useCoreBlocksUpdate, useCoverClose, useCoverGetStatus, useCoverOpen, useCoverSetPosition, useCoverSetTiltPosition, useCoverStop, useCustomFieldRenderer, useDayNightGetOptions, useDayNightGetStatus, useDayNightSetSettings, useDebouncedString, useDecoderCreateSession, useDecoderDestroySession, useDecoderGetFrame, useDecoderGetInfo, useDecoderGetShmStats, useDecoderGetStats, useDecoderListActiveSessions, useDecoderOpenStream, useDecoderPullFrames, useDecoderPullHandles, useDecoderPushPacket, useDecoderReprobeHwaccel, useDecoderSupportsCodec, useDecoderUpdateConfig, useDetectionPipelineApplyDeviceSettingsPatch, useDetectionPipelineGetDeviceLiveContribution, useDetectionPipelineGetDeviceSettingsContribution, useDevShell, useDevice, useDeviceAdoptionAdopt, useDeviceAdoptionGetCandidate, useDeviceAdoptionGetStatus, useDeviceAdoptionListCandidateFilters, useDeviceAdoptionListCandidates, useDeviceAdoptionRefresh, useDeviceAdoptionRelease, useDeviceAdoptionResync, useDeviceAutotrack, useDeviceBattery, useDeviceCapSlice, useDeviceCapability, useDeviceDetections, useDeviceDiscoveryAdoptDevice, useDeviceDiscoveryGetStatus, useDeviceDiscoveryListDiscovered, useDeviceDiscoveryRefreshDiscovery, useDeviceDiscoveryReleaseDevice, useDeviceExportApplyDeviceSettingsPatch, useDeviceExportExposeDevice, useDeviceExportGetDeviceLiveContribution, useDeviceExportGetDeviceSettingsContribution, useDeviceExportGetStatus, useDeviceExportListExposedDevices, useDeviceExportListSupportedDeviceKinds, useDeviceExportUnexposeDevice, useDeviceId, useDeviceListPageSize, useDeviceManagerAddLocation, useDeviceManagerAdoptDevice, useDeviceManagerAdoptionAdopt, useDeviceManagerAdoptionCancelJob, useDeviceManagerAdoptionListCandidateFilters, useDeviceManagerAdoptionListCandidates, useDeviceManagerAdoptionListJobs, useDeviceManagerAdoptionRefresh, useDeviceManagerAdoptionRelease, useDeviceManagerAdoptionResync, useDeviceManagerAdoptionStartJob, useDeviceManagerAllocateDeviceId, useDeviceManagerApplyDeviceSettingsPatch, useDeviceManagerApplyInitialMeta, useDeviceManagerCreateDevice, useDeviceManagerDisable, useDeviceManagerDiscoverAllProviders, useDeviceManagerDiscoverDevices, useDeviceManagerDiscoverProvider, useDeviceManagerDiscoveryProviders, useDeviceManagerEnable, useDeviceManagerGetAllBindings, useDeviceManagerGetBindings, useDeviceManagerGetBindingsBatch, useDeviceManagerGetChildren, useDeviceManagerGetChildrenBatch, useDeviceManagerGetConfigSchema, useDeviceManagerGetCreationSchema, useDeviceManagerGetDevice, useDeviceManagerGetDeviceAggregate, useDeviceManagerGetDeviceLiveContribution, useDeviceManagerGetDeviceLiveInfoAggregate, useDeviceManagerGetDeviceSettingsAggregate, useDeviceManagerGetDeviceSettingsContribution, useDeviceManagerGetDeviceStatusAggregate, useDeviceManagerGetDeviceStatusAggregateBatch, useDeviceManagerGetLinkedDevices, useDeviceManagerGetLinkedDevicesBatch, useDeviceManagerGetRoleDisplayDefaults, useDeviceManagerGetSettingsSchema, useDeviceManagerGetStreamProfileMap, useDeviceManagerGetStreamSources, useDeviceManagerGetWireableFields, useDeviceManagerListAll, useDeviceManagerListBindableCapsForDeviceType, useDeviceManagerListLocationDescriptions, useDeviceManagerListLocationIcons, useDeviceManagerListLocations, useDeviceManagerListPersistedByAddon, useDeviceManagerListSiteZones, useDeviceManagerListWrappersForCap, useDeviceManagerLoadConfig, useDeviceManagerLoadMeta, useDeviceManagerLoadRuntimeState, useDeviceManagerMigrateDevice, useDeviceManagerPersistConfig, useDeviceManagerProbeStreams, useDeviceManagerProviderCreationType, useDeviceManagerProviderDiscoveryParamsSchema, useDeviceManagerRegisterDevice, useDeviceManagerRemove, useDeviceManagerRemoveByIntegration, useDeviceManagerRemoveDevice, useDeviceManagerRemoveLocation, useDeviceManagerRemoveSiteZone, useDeviceManagerRenameLocation, useDeviceManagerRenameSiteZone, useDeviceManagerRunDeviceAction, useDeviceManagerSetChildLayout, useDeviceManagerSetDisabled, useDeviceManagerSetDisplay, useDeviceManagerSetIntegrationId, useDeviceManagerSetLinkDeviceId, useDeviceManagerSetLocation, useDeviceManagerSetLocationDescription, useDeviceManagerSetLocationIcon, useDeviceManagerSetLocationZone, useDeviceManagerSetMetadata, useDeviceManagerSetName, useDeviceManagerSetPrimaryChildEntityId, useDeviceManagerSetRole, useDeviceManagerSetRoleDisplayDefaults, useDeviceManagerSetSiteZone, useDeviceManagerSetStreamProfileMap, useDeviceManagerSetType, useDeviceManagerSetWrapperActive, useDeviceManagerTestCreationField, useDeviceManagerTestField, useDeviceManagerUpdateConfig, useDeviceManagerUpdateDeviceField, useDeviceManagerUpdateDeviceFieldsBatch, useDeviceNetworkLink, useDeviceOpsGetConfigEntries, useDeviceOpsGetRawState, useDeviceOpsGetSettingsSchema, useDeviceOpsGetStreamSources, useDeviceOpsRemoveDevice, useDeviceOpsRunAction, useDeviceOpsSetConfig, useDeviceProviderAdoptDiscoveredDevice, useDeviceProviderCreateDevice, useDeviceProviderDiscoverDevices, useDeviceProviderGetChildCreationSchema, useDeviceProviderGetDevices, useDeviceProviderGetDiscoveryParamsSchema, useDeviceProviderGetManualCreationType, useDeviceProviderGetStatus, useDeviceProviderReloadDevice, useDeviceProviderStart, useDeviceProviderStop, useDeviceProviderSupportsDiscovery, useDeviceProviderSupportsManualCreation, useDeviceProviderTestCreationField, useDeviceProxy, useDeviceSnapshot, useDeviceSnapshotImage, useDeviceState, useDeviceStateGetAllSnapshots, useDeviceStateGetCapSlice, useDeviceStateGetSnapshot, useDeviceStateSetCapSlice, useDeviceStateSlice, useDeviceStatusGetStatus, useDeviceWebrtc, useDevices, useDoorbellApplyDeviceSettingsPatch, useDoorbellEvents, useDoorbellGetDeviceLiveContribution, useDoorbellGetDeviceSettingsContribution, useDoorbellGetStatus, useEnumSensorGetStatus, useEventEmitterGetStatus, useEventInvalidation, useEventStreamLatest, useEventStreamMap, useEventsGetEventClipUrl, useEventsGetEventThumbnail, useEventsGetEvents, useFaceGalleryAssignFace, useFaceGalleryAssignFaces, useFaceGalleryAuditIdentitySamples, useFaceGalleryCreateIdentity, useFaceGalleryDeleteFace, useFaceGalleryDeleteIdentity, useFaceGalleryGetFaceByTrack, useFaceGalleryGetFaceMedia, useFaceGalleryListIdentities, useFaceGalleryListIdentitySamples, useFaceGalleryListRecentFaces, useFaceGalleryRemoveSample, useFaceGalleryRenameIdentity, useFaceGallerySuggestFaceClusters, useFaceGalleryUnassignFace, useFaceGalleryUnassignFaces, useFanControlGetStatus, useFanControlSetDirection, useFanControlSetOscillating, useFanControlSetPercentage, useFanControlSetPreset, useFeatureProbeGetStatus, useFloodGetStatus, useGasGetStatus, useHumidifierGetStatus, useHumidifierSetMode, useHumidifierSetOn, useHumidifierSetTargetHumidity, useHumiditySensorGetStatus, useImageGetStatus, useImageSettingsGetOptions, useImageSettingsGetStatus, useImageSettingsSetSettings, useIntegrationsCreate, useIntegrationsDelete, useIntegrationsGet, useIntegrationsGetAvailableTypes, useIntegrationsGetByAddonId, useIntegrationsGetSettings, useIntegrationsList, useIntegrationsSetSettings, useIntegrationsTestConnection, useIntegrationsUpdate, useIntercomEndTalkSession, useIntercomGetStatus, useIntercomHandleAnswer, useIntercomPushTalkAudio, useIntercomStartSession, useIntercomStartTalkSession, useIntercomStopSession, useIsMidWidth, useIsMobile, useLawnMowerControlDock, useLawnMowerControlGetStatus, useLawnMowerControlPause, useLawnMowerControlStartMowing, useLiveBuffer, useLiveEvent, useLlmCancel, useLlmDeleteModel, useLlmDeleteProfile, useLlmGenerate, useLlmGenerateVision, useLlmGetDefaults, useLlmGetRuntimeStatus, useLlmGetUsage, useLlmInstallModel, useLlmListModelCatalog, useLlmListModels, useLlmListNodeModels, useLlmListProfileKinds, useLlmListProfiles, useLlmListRuntimeNodes, useLlmResolveModelRef, useLlmSetDefault, useLlmStartRuntime, useLlmStopRuntime, useLlmTestProfile, useLlmUpsertProfile, useLocalNetworkDownloadCa, useLocalNetworkGetAllowedAddresses, useLocalNetworkGetConnectionEndpoints, useLocalNetworkGetNotificationEndpoint, useLocalNetworkGetPreferred, useLocalNetworkGetTlsStatus, useLocalNetworkGetViewerEndpoints, useLocalNetworkList, useLocalNetworkRegenerateCertificate, useLocalNetworkResetAllowlistToBestMatch, useLocalNetworkRevertToGeneratedCertificate, useLocalNetworkSetAllowedAddresses, useLocalNetworkSetNotificationEndpoint, useLocalNetworkSetViewerEndpoints, useLocalNetworkUploadCertificate, useLockControlGetStatus, useLockControlLock, useLockControlOpen, useLockControlUnlock, useMediaPlayerGetStatus, useMediaPlayerNext, useMediaPlayerPause, useMediaPlayerPlay, useMediaPlayerPlayMedia, useMediaPlayerPrevious, useMediaPlayerSeek, useMediaPlayerSelectSource, useMediaPlayerSetMute, useMediaPlayerSetRepeat, useMediaPlayerSetShuffle, useMediaPlayerSetVolume, useMediaPlayerStop, useMeshNetworkGetStatus, useMeshNetworkJoin, useMeshNetworkLeave, useMeshNetworkListPeers, useMeshNetworkLogout, useMeshNetworkStartLogin, useMeshNetworkTestConnection, useMetricsProviderCollectSnapshot, useMetricsProviderGetAddonStats, useMetricsProviderGetCached, useMetricsProviderGetCpuTemperature, useMetricsProviderGetCurrent, useMetricsProviderGetDiskSpace, useMetricsProviderGetGpuInfo, useMetricsProviderGetLoadSeries, useMetricsProviderGetProcessStats, useMetricsProviderListAddonInstances, useMetricsProviderListNodeProcesses, useMotionDetectionAnalyze, useMotionDetectionApplyDeviceSettingsPatch, useMotionDetectionGetDeviceLiveContribution, useMotionDetectionGetDeviceSettingsContribution, useMotionDetectionRemoveCamera, useMotionDetectionReset, useMotionGetStatus, useMotionIsDetected, useMotionTriggerGetStatus, useMotionTriggerSetMotionTrigger, useMotionZonesGetOptions, useMotionZonesGetStatus, useMotionZonesSetZone, useMqttBrokerAddBroker, useMqttBrokerGetBrokerConfig, useMqttBrokerGetStatus, useMqttBrokerListBrokers, useMqttBrokerRemoveBroker, useMqttBrokerStartEmbeddedBroker, useMqttBrokerStopEmbeddedBroker, useMqttBrokerTestConnection, useNativeObjectDetectionGetOptions, useNativeObjectDetectionGetStatus, useNativeObjectDetectionSetEnabled, useNativeObjectDetectionSetSettings, useNavigation, useNavigationGetFeatures, useNavigationGetStatus, useNavigationGoToPoint, useNavigationListActions, useNavigationMove, useNavigationPlaySound, useNavigationRunAction, useNavigationSetLightLevel, useNavigationSetLightMode, useNavigationSetLightOn, useNavigationStop, useNetworkAccessGetEndpoint, useNetworkAccessGetStatus, useNetworkAccessListEndpoints, useNetworkAccessStart, useNetworkAccessStop, useNetworkLinkGetStatus, useNetworkQualityGetAllStats, useNetworkQualityGetDeviceStats, useNetworkQualityReportClientStats, useNodesClusterAddonStatus, useNodesDeployAddon, useNodesExecuteQuery, useNodesGetCapUsageGraph, useNodesGetNodeAddons, useNodesRenameNode, useNodesRestartAddon, useNodesRestartNode, useNodesRestartProcess, useNodesSetProcessLogLevel, useNodesShutdownNode, useNodesTopology, useNodesUndeployAddon, useNotificationOutputDeleteTarget, useNotificationOutputDiscoverTargets, useNotificationOutputListTargetKinds, useNotificationOutputListTargets, useNotificationOutputSend, useNotificationOutputSetTargetEnabled, useNotificationOutputTestTarget, useNotificationOutputUpsertTarget, useNotificationRulesCancelSnooze, useNotificationRulesCreateRule, useNotificationRulesCreateSnooze, useNotificationRulesDeleteRule, useNotificationRulesGetAlarmConfig, useNotificationRulesGetClipRetentionAsks, useNotificationRulesGetConditionCatalog, useNotificationRulesGetHistory, useNotificationRulesGetRule, useNotificationRulesListDeviceMutes, useNotificationRulesListRules, useNotificationRulesListSnoozes, useNotificationRulesResolveArtifactUrl, useNotificationRulesSetAlarmConfig, useNotificationRulesSetDeviceMuted, useNotificationRulesSetRuleEnabled, useNotificationRulesTestRule, useNotificationRulesUpdateRule, useNotifierCancel, useNotifierGetStatus, useNotifierSend, useNumericSensorGetStatus, useOptimisticSlice, useOptionalSystem, useOptionalWidgetRegistry, useOsdGetStatus, useOsdManagerClearSlotBinding, useOsdManagerCopyDeviceConfiguration, useOsdManagerGetConditionSupport, useOsdManagerGetDeviceOsd, useOsdManagerGetSourceCatalog, useOsdManagerPreviewSlot, useOsdManagerRenderDevice, useOsdManagerSetSlotBinding, useOsdSetOverlay, usePTZ, usePetFeederCallPet, usePetFeederCancelFeed, usePetFeederFeed, usePetFeederGetStatus, usePetFeederMarkFoodReplenished, usePetFeederPlaySound, usePetFeederResetDesiccant, usePetFeederSetChildLock, usePetFeederSetFeedSound, usePetFeederSetIndicatorLight, usePetFeederSetVolume, usePipelineAnalyticsApplyDeviceSettingsPatch, usePipelineAnalyticsCancelRelocateMedia, usePipelineAnalyticsCancelStorageMigrationMove, usePipelineAnalyticsClearTracks, usePipelineAnalyticsCompleteRetrainTrack, usePipelineAnalyticsCountRelocatableMedia, usePipelineAnalyticsCountUnstampedEventMedia, usePipelineAnalyticsDeleteDeviceEvents, usePipelineAnalyticsDeleteTracks, usePipelineAnalyticsDeselectRetrainFrame, usePipelineAnalyticsGetActiveTracks, usePipelineAnalyticsGetAudioEvents, usePipelineAnalyticsGetDeviceLiveContribution, usePipelineAnalyticsGetDeviceSettingsContribution, usePipelineAnalyticsGetEventDensity, usePipelineAnalyticsGetEventDensityBatch, usePipelineAnalyticsGetEventMedia, usePipelineAnalyticsGetEventMediaFootprintByKind, usePipelineAnalyticsGetEventStoreFootprint, usePipelineAnalyticsGetKeyEvents, usePipelineAnalyticsGetKeyEventsBatch, usePipelineAnalyticsGetMediaReclaimStatus, usePipelineAnalyticsGetMotionEvents, usePipelineAnalyticsGetObjectEmbeddingRebuildStatus, usePipelineAnalyticsGetObjectEvents, usePipelineAnalyticsGetRetrainExportUrl, usePipelineAnalyticsGetRetrainFrameImage, usePipelineAnalyticsGetSensorEvents, usePipelineAnalyticsGetStorageMigrationMoveStatus, usePipelineAnalyticsGetSummary, usePipelineAnalyticsGetTrack, usePipelineAnalyticsGetTrackMedia, usePipelineAnalyticsGetTrainingExportSummary, usePipelineAnalyticsGetTrainingExportUrl, usePipelineAnalyticsListArchivedDebugNotes, usePipelineAnalyticsListBirthDecisions, usePipelineAnalyticsListEventKinds, usePipelineAnalyticsListEventKindsBatch, usePipelineAnalyticsListEventMedia, usePipelineAnalyticsListOpsLog, usePipelineAnalyticsListRecentSummaries, usePipelineAnalyticsListRecentTracks, usePipelineAnalyticsListRelocateMediaJobs, usePipelineAnalyticsListRetrainAnnotations, usePipelineAnalyticsListRetrainFrames, usePipelineAnalyticsListRetrainStaging, usePipelineAnalyticsListSummaries, usePipelineAnalyticsListTrackMedia, usePipelineAnalyticsListTracks, usePipelineAnalyticsPauseForStorageMigration, usePipelineAnalyticsProposeRetrainAnnotations, usePipelineAnalyticsPruneEvents, usePipelineAnalyticsPruneEventsBefore, usePipelineAnalyticsPruneTracksBefore, usePipelineAnalyticsReadLongTermSeries, usePipelineAnalyticsRebuildObjectEmbeddings, usePipelineAnalyticsReclaimDebugMedia, usePipelineAnalyticsReconcileFromDisk, usePipelineAnalyticsRefreshStorageLocationsForMigration, usePipelineAnalyticsRelocateMedia, usePipelineAnalyticsRestageRetrainTrack, usePipelineAnalyticsResumeForStorageMigration, usePipelineAnalyticsRunReplayFrameProcessor, usePipelineAnalyticsSaveRetrainAnnotations, usePipelineAnalyticsSearchObjectEvents, usePipelineAnalyticsSelectRetrainFrames, usePipelineAnalyticsSetTrackFlags, usePipelineAnalyticsStartStorageMigrationMove, usePipelineAnalyticsWipeAllAnalytics, usePipelineAnalyticsWipeObjectEmbeddings, usePipelineExecutorCacheFrameInPool, usePipelineExecutorClearDeviceOverrides, usePipelineExecutorDeleteModel, usePipelineExecutorDeleteTemplate, usePipelineExecutorDownloadModel, usePipelineExecutorGetAddonModels, usePipelineExecutorGetAudioCapabilities, usePipelineExecutorGetAvailableEngines, usePipelineExecutorGetCapabilities, usePipelineExecutorGetDefaultSteps, usePipelineExecutorGetDetectionConfigSchema, usePipelineExecutorGetEffectiveTuning, usePipelineExecutorGetEngineProvisioning, usePipelineExecutorGetGlobalPipelineConfig, usePipelineExecutorGetGlobalSteps, usePipelineExecutorGetInferenceDeviceHealth, usePipelineExecutorGetOrchestratorConfigSchema, usePipelineExecutorGetReferenceAudio, usePipelineExecutorGetReferenceAudioFiles, usePipelineExecutorGetReferenceImage, usePipelineExecutorGetSchema, usePipelineExecutorGetSelectedEngine, usePipelineExecutorGetVideoPipelineSteps, usePipelineExecutorInferCached, usePipelineExecutorKillEngine, usePipelineExecutorListLoadedEngines, usePipelineExecutorListReferenceImages, usePipelineExecutorListTemplates, usePipelineExecutorRearmInferenceDevice, usePipelineExecutorRunAudioTest, usePipelineExecutorRunPipeline, usePipelineExecutorRunPipelineBatch, usePipelineExecutorSaveTemplate, usePipelineExecutorSetVideoPipelineSteps, usePipelineExecutorSpinEngine, usePipelineExecutorUncacheFrame, usePipelineExecutorUpdateTemplate, usePipelineExecutorValidatePipeline, usePipelineOrchestratorApplyDeviceSettingsPatch, usePipelineOrchestratorAssignAudio, usePipelineOrchestratorAssignPipeline, usePipelineOrchestratorDeleteTemplate, usePipelineOrchestratorGetAgentLoad, usePipelineOrchestratorGetAgentSettings, usePipelineOrchestratorGetAudioAssignment, usePipelineOrchestratorGetAudioAssignments, usePipelineOrchestratorGetAudioNodeLoad, usePipelineOrchestratorGetCameraMetrics, usePipelineOrchestratorGetCameraSettings, usePipelineOrchestratorGetCameraStatus, usePipelineOrchestratorGetCameraStatuses, usePipelineOrchestratorGetCameraStepOverrides, usePipelineOrchestratorGetCameraSwitches, usePipelineOrchestratorGetCapabilityBindings, usePipelineOrchestratorGetDeviceLiveContribution, usePipelineOrchestratorGetDeviceSettingsContribution, usePipelineOrchestratorGetGlobalMetrics, usePipelineOrchestratorGetIngestOwner, usePipelineOrchestratorGetNodeInferenceDevices, usePipelineOrchestratorGetPipelineAssignment, usePipelineOrchestratorGetPipelineAssignments, usePipelineOrchestratorGetPipelineDevicePin, usePipelineOrchestratorGetReconcileFromDiskStatus, usePipelineOrchestratorListAgentSettings, usePipelineOrchestratorListTemplates, usePipelineOrchestratorPauseForStorageMigration, usePipelineOrchestratorRebalance, usePipelineOrchestratorReconcileFromDisk, usePipelineOrchestratorRemoveAgentSettings, usePipelineOrchestratorResetNodePipelineDefaults, usePipelineOrchestratorResolvePipeline, usePipelineOrchestratorResumeForStorageMigration, usePipelineOrchestratorSaveTemplate, usePipelineOrchestratorSetAgentCapabilities, usePipelineOrchestratorSetAgentDecodeLimits, usePipelineOrchestratorSetAgentDetectWeight, usePipelineOrchestratorSetAgentInferenceDevices, usePipelineOrchestratorSetAgentMaxCameras, usePipelineOrchestratorSetAgentReachableHost, usePipelineOrchestratorSetCameraPipelineForAgent, usePipelineOrchestratorSetCameraStepOverride, usePipelineOrchestratorSetCameraStepToggle, usePipelineOrchestratorSetCameraSwitch, usePipelineOrchestratorSetCapabilityBinding, usePipelineOrchestratorSetPipelineDevicePin, usePipelineOrchestratorUnassignAudio, usePipelineOrchestratorUnassignPipeline, usePipelineOrchestratorUpdateTemplate, usePipelineRunnerAttachCamera, usePipelineRunnerDetachCamera, usePipelineRunnerGetAllCameraMetrics, usePipelineRunnerGetCameraMetrics, usePipelineRunnerGetLocalCameras, usePipelineRunnerGetLocalLoad, usePipelineRunnerGetLocalMetrics, usePipelineRunnerGetNativeCrop, usePipelineRunnerGetParkedTrackFrame, usePipelineRunnerParkTrackFrame, usePipelineRunnerReleaseParkedTrackFrames, usePipelineRunnerReportMotion, usePipelineRunnerRequestOccupancyBurst, usePipelineRunnerRunDetailSubtree, usePipelineRunnerRunStatelessStep, usePlateGalleryAssignPlate, usePlateGalleryAssignPlates, usePlateGalleryCorrectPlateText, usePlateGalleryCreateVehicle, usePlateGalleryDeletePlate, usePlateGalleryDeleteVehicle, usePlateGalleryGetPlateByTrack, usePlateGalleryGetPlateMedia, usePlateGalleryListPlates, usePlateGalleryListVehicleSamples, usePlateGalleryListVehicles, usePlateGalleryRemoveVehicleSample, usePlateGalleryRenameVehicle, usePlateGallerySearchPlates, usePlateGallerySuggestPlateClusters, usePlateGalleryUnassignPlate, usePlateGalleryUnassignPlates, usePlayerOverlayLayer, usePlayerOverlayLayers, usePlayerToolbarButton, usePlayerToolbarButtons, usePowerMeterGetStatus, usePresenceGetStatus, usePressureSensorGetStatus, usePrivacyMaskGetOptions, usePrivacyMaskGetStatus, usePrivacyMaskSetAudioEnabled, usePrivacyMaskSetMask, usePrompt, usePtzAutotrackGetSettings, usePtzAutotrackGetStatus, usePtzAutotrackSetEnabled, usePtzAutotrackSetSettings, usePtzCaptureHomeHere, usePtzContinuousMove, usePtzDeletePreset, usePtzGetHomePreset, usePtzGetHomeReturn, usePtzGetOptions, usePtzGetPosition, usePtzGetPresets, usePtzGetStatus, usePtzGoHome, usePtzGoToPreset, usePtzMove, usePtzSavePreset, usePtzSetAutofocus, usePtzSetHomePreset, usePtzSetHomeReturn, usePtzStop, useRebootReboot, useRecordedPlayback, useRecordingApplyDeviceSettingsPatch, useRecordingCancelRelocateJob, useRecordingCancelStorageMigrationMove, useRecordingDeleteFootprint, useRecordingExportCancelExport, useRecordingExportCreateExport, useRecordingExportDeleteExport, useRecordingExportGetDownloadUrl, useRecordingExportGetExport, useRecordingExportListExports, useRecordingExportReadExportBytes, useRecordingGetAvailability, useRecordingGetAvailabilityBatch, useRecordingGetDaysWithRecordings, useRecordingGetDaysWithRecordingsBatch, useRecordingGetDeviceConfig, useRecordingGetDeviceLiveContribution, useRecordingGetDeviceSettingsContribution, useRecordingGetPlacement, useRecordingGetPlaybackManifest, useRecordingGetRelocateResidue, useRecordingGetStatus, useRecordingGetStorageMigrationMoveStatus, useRecordingGetStorageUsage, useRecordingListOpsLog, useRecordingListRelocateJobs, useRecordingLocateSegment, useRecordingPauseForStorageMigration, useRecordingPlanStorageRebalance, useRecordingPruneFootage, useRecordingReadGopBytes, useRecordingReadSegmentBytes, useRecordingReadWindowBytes, useRecordingReconcileLedgerAgainstDisk, useRecordingRefreshStorageLocationsForMigration, useRecordingRelocateFootage, useRecordingRenderClip, useRecordingRenderGif, useRecordingRescanStorage, useRecordingResumeForStorageMigration, useRecordingSetDeviceConfig, useRecordingSetDevicePlacement, useRecordingSignalGetStatus, useRecordingStartStorageMigrationMove, useRecordingStartStorageRebalance, useRemoteComponent, useSceneMonitorCaptureReference, useSceneMonitorCreateScene, useSceneMonitorDeleteReference, useSceneMonitorDeleteScene, useSceneMonitorGetStatus, useSceneMonitorListScenes, useSceneMonitorListScenesBatch, useSceneMonitorRecheckNow, useSceneMonitorResetScene, useSceneMonitorUpdateScene, useScriptRunnerGetStatus, useScriptRunnerRun, useScriptRunnerStop, useScrubController, useServerManagementApplyServerUpdate, useServerManagementCheckServerUpdate, useServerManagementGetServerPackageStatus, useServerManagementRestartServer, useServerManagementRollbackServerUpdate, useSettingsStoreAggregate, useSettingsStoreCount, useSettingsStoreDeclareCollection, useSettingsStoreDelete, useSettingsStoreDeleteWhere, useSettingsStoreGet, useSettingsStoreHistogram, useSettingsStoreInsert, useSettingsStoreInsertMany, useSettingsStoreIsEmpty, useSettingsStoreQuery, useSettingsStoreSet, useSettingsStoreUpdate, useSettingsStoreUpdateWhere, useSettingsStoreUpsert, useSmokeGetStatus, useSnapshotApplyDeviceSettingsPatch, useSnapshotGetDebugState, useSnapshotGetDeviceLiveContribution, useSnapshotGetDeviceSettingsContribution, useSnapshotGetSnapshot, useSnapshotGetSnapshotLinks, useSnapshotGetSnapshotOverview, useSnapshotGetStatus, useSnapshotInvalidateCache, useStationaryOverlay, useStorageAbortUpload, useStorageBeginDownload, useStorageBeginUpload, useStorageDelete, useStorageDeleteLocation, useStorageEndDownload, useStorageExists, useStorageFinalizeUpload, useStorageGetAvailableSpace, useStorageList, useStorageListDrainProgress, useStorageListLocationDeclarations, useStorageListLocations, useStorageListProviders, useStorageMigrationCancel, useStorageMigrationCleanupCancel, useStorageMigrationCleanupStart, useStorageMigrationCleanupStatus, useStorageMigrationDrain, useStorageMigrationHistory, useStorageMigrationMovers, useStorageMigrationPlan, useStorageMigrationResidue, useStorageMigrationStart, useStorageMigrationStatus, useStorageRead, useStorageReadChunk, useStorageResolve, useStorageTestConfig, useStorageTestLocation, useStorageUpsertLocation, useStorageWrite, useStorageWriteChunk, useStreamBrokerAcquireEgressTranscode, useStreamBrokerApplyDeviceSettingsPatch, useStreamBrokerAssignProfile, useStreamBrokerFetchEventMedia, useStreamBrokerForgetDeviceHardware, useStreamBrokerGetAllRtspEntries, useStreamBrokerGetBrokerStats, useStreamBrokerGetDeviceAudioMute, useStreamBrokerGetDeviceLiveContribution, useStreamBrokerGetDeviceSettingsContribution, useStreamBrokerGetPreBufferInfo, useStreamBrokerGetRtspEntry, useStreamBrokerGetRtspPort, useStreamBrokerGetStreamUrl, useStreamBrokerGetStreamWithCodec, useStreamBrokerIsRtspEnabled, useStreamBrokerKillClient, useStreamBrokerListAllCameraStreams, useStreamBrokerListAllProfileSlots, useStreamBrokerListClients, useStreamBrokerProbeStream, useStreamBrokerProduceEventMedia, useStreamBrokerPublishCameraStream, useStreamBrokerPullAudioChunks, useStreamBrokerPullFrameHandles, useStreamBrokerRegenerateRtspToken, useStreamBrokerReleaseEgressTranscode, useStreamBrokerReleaseStreamWithCodec, useStreamBrokerRenderPreBufferClip, useStreamBrokerReportStreamSignal, useStreamBrokerRestartProfile, useStreamBrokerRetractCameraStream, useStreamBrokerSetDeviceAudioMute, useStreamBrokerSetPreBufferDuration, useStreamBrokerSetRtspEnabled, useStreamBrokerSubscribeAudioChunks, useStreamBrokerSubscribeFrames, useStreamBrokerUnassignProfile, useStreamBrokerUnsubscribeAudioChunks, useStreamBrokerUnsubscribeFrames, useStreamCatalogGetCatalog, useStreamParamsGetConfigSchema, useStreamParamsGetOptions, useStreamParamsGetStatus, useStreamParamsSetProfile, useStreamSignalsListSignals, useSwitchGetStatus, useSwitchSetState, useSystem, useSystemDetectSiteLocation, useSystemFeatureFlags, useSystemForceRetentionCleanup, useSystemGetFailureContributions, useSystemGetLoadContributions, useSystemGetLoggingSettings, useSystemGetRequestCensus, useSystemGetRetentionConfig, useSystemGetSiteLocation, useSystemHealth, useSystemInfo, useSystemMutation, useSystemNetworkAddresses, useSystemQuery, useSystemSetLoggingSettings, useSystemSetRetentionConfig, useSystemSetSiteLocation, useTamperGetStatus, useTemperatureSensorGetStatus, useTerminalSessionAdoptLegacyMonitor, useTerminalSessionClose, useTerminalSessionCreateInstance, useTerminalSessionDeleteInstance, useTerminalSessionListInstances, useTerminalSessionListLegacyCameras, useTerminalSessionListProfiles, useTerminalSessionListSessions, useTerminalSessionOpenSession, useTerminalSessionPullOutput, useTerminalSessionResize, useTerminalSessionSetInstanceEnabled, useTerminalSessionUpdateInstance, useTerminalSessionWriteInput, useThemeMode, useToastOnToast, useTurnProviderGetTurnServers, useUpdateGetStatus, useUpdateInstallUpdate, useUserManagementConfirmTotp, useUserManagementCreateApiKey, useUserManagementCreateScopedToken, useUserManagementCreateUser, useUserManagementDeleteUser, useUserManagementDisableTotp, useUserManagementGetTotpStatus, useUserManagementListApiKeys, useUserManagementListOauthSessions, useUserManagementListScopedTokens, useUserManagementListUsers, useUserManagementOauthExchangeCode, useUserManagementOauthIssueCode, useUserManagementOauthRefresh, useUserManagementOauthVerifyAccessToken, useUserManagementResetPassword, useUserManagementRevokeApiKey, useUserManagementRevokeOauthSession, useUserManagementRevokeScopedToken, useUserManagementSetUserScopes, useUserManagementSetupTotp, useUserManagementUpdateUser, useUserManagementValidateApiKey, useUserManagementValidateCredentials, useUserManagementValidateScopedToken, useUserManagementVerifyTotp, useVacuumControlGetStatus, useVacuumControlLocate, useVacuumControlPause, useVacuumControlReturnToBase, useVacuumControlSetFanSpeed, useVacuumControlStart, useVacuumControlStop, useValveClose, useValveGetStatus, useValveOpen, useValveSetPosition, useValveStop, useVibrationGetStatus, useVideoclipsGetClipPlayback, useVideoclipsListClips, useVideoclipsListSources, useVodPlayback, useWaterHeaterGetStatus, useWaterHeaterSetAway, useWaterHeaterSetOperationMode, useWaterHeaterSetTargetTemp, useWeatherGetStatus, useWebrtcSessionAddIceCandidate, useWebrtcSessionCloseSession, useWebrtcSessionCreateSession, useWebrtcSessionGetIceCandidates, useWebrtcSessionGetSessionDebug, useWebrtcSessionGetSessionState, useWebrtcSessionHandleAnswer, useWebrtcSessionHandleOffer, useWebrtcSessionHasAdaptiveBitrate, useWebrtcSessionListStreams, useWidget, useWidgetMetadata, useWidgetRegistry, useZoneAnalyticsGetCameraHistory, useZoneAnalyticsGetCurrentSnapshot, useZoneAnalyticsGetCurrentSnapshotBatch, useZoneAnalyticsGetUnzonedHistory, useZoneAnalyticsGetZoneHistory, useZoneEditing, useZoneRulesListRules, useZoneRulesSetRules, useZonesAddZone, useZonesListZones, useZonesRemoveZone, useZonesUpdateZone, vacuumStateMeta, validateScopes, valveStateMeta, variantLabel, waterHeaterPhase, waterHeaterTint, weatherConditionMeta, weatherTint };
53729
+ export { AddonGlobalSettingsForm, AgentStepEditor, AlarmHeroCard, AlarmInlineControl as AlarmPanelInlineControl, AppShell, ArcKnob, AudioClassificationList, AudioLevelWaveform, AudioWaveform, AutomationHeroCard, AutomationInlineControl, AutotrackSection, BTN_COMPACT, BTN_COMPACT_DANGER, BTN_COMPACT_PRIMARY, BTN_COMPACT_WARNING, Badge, BatteryBadge, BottomSheet, Breadcrumb, BrightnessPanel, Button, ButtonControl, ButtonHeroCard, CARD_MODE_MIN_COLUMNS, CENTER, CHIP_ACTIVE, CHIP_BASE, CHIP_INACTIVE, CLASS_COLORS, COLUMN_BREAKPOINT_CLASS, COLUMN_PRIORITY, COMMIT_DEDUPE_TOLERANCE_MS, COMMIT_DEDUPE_WINDOW_MS, CONTROL_CAP_NAMES, CONTROL_FILLS, CameraStreamPlayer, Card, Checkbox, ChildSectionAccordion, ClimatePanel, CodeBlock, CollapsibleCard, ConfigFormBuilder, FormField as ConfigFormField, ConfigSchemaField, ConfirmActionButton, ConfirmDialogProvider, ConsumablesPanel, ContainerChildrenProvider, ContainerPrimaryHero, ControlColumn, ControlHeroCard, ControlInlineControl, ControlPanel, CopyButton, CoverHeroCard, CoverInlineControl, CoverPanel, CustomFieldRenderersProvider, DEFAULT_COLOR, DEVICE_COLUMNS, DEVICE_LIST_PAGE_SIZE_KEY, DEVICE_LIST_PAGE_SIZE_OPTIONS, DEVICE_ROLE_META, DEVICE_TYPE_CONTROL, DEVICE_TYPE_META, DISPLAY_ICON_REGISTRY, DataTable, DetectionCanvas, DetectionOverlay, DetectionResultTree, DevShell, DeviceActivityPanel, DeviceBatchToolbar, DeviceCard, DeviceContextProvider, DeviceExportPanel, DeviceGrid, DeviceItem, DeviceList, DeviceMultiSelectField, DeviceSelectField, DeviceSelectorPicker, DeviceStepMatrix, Dialog, DialogBody, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, DiscoveryPanel, DoorbellRecentPanel, Dropdown, DropdownContent, DropdownItem, DropdownTrigger, DummyHeroCard, DummyInline, EVENT_KIND_ICONS, EmptyState, ErrorBox, EventKindGlyph, EventStream, FILL, FLEET_LIST_GC_TIME_MS, FLEET_LIST_QUERY_KEY, FLEET_LIST_STALE_TIME_MS, FanHeroCard, FanInlineControl, FanPanel, FilterBar, FloatingEventStream, FloatingLogStream, FloatingPanel, FormField$1 as FormField, GRID_GAP, GRID_PAIRED, GRID_QUICK_STATS, GripTrack, GroupedModelSelector, HOST_WIDGETS, HlsVideo, HoverZoomImage, HumidifierHeroCard, HumidifierInlineControl, INPUT_COMPACT, IconAction, IconButton, ImageHeroCard, ImageInlineControl, ImageSelector, InferenceConfigSelector, Input, KebabMenu, KeyValueList, LIST_ROW, Label, LawnMowerHeroCard, LawnMowerInlineControl, LightHeroCard, LightInlineControl, LockHeroCard, LockInlineControl, LockPanel, LogStream, LoginForm, MODE_COLOR, MaskShapeCanvas, MediaPlayerHeroCard, MediaPlayerInlineControl, MediaPlayerPanel, MobileDrawer, ModelPicker, MotionZonesSettings, NAVIGATION_DRIVE_INTERVAL_MS, NavigationPanel, NetworkLinkBadge, NodeMultiSelectField, NodePicker, NodeSelectField, OfflineBadge, PHASE_CONFIG, PRIORITY, PTZOverlay, PageHeader, PhaseIcon, PipelineBuilder, PipelineRuntimeSelector, PipelineStep, PipelineTreeMatrix, PlayerOverlaysProvider, Popover, PopoverContent, PopoverRowAction, PopoverTrigger, PrimaryChildPicker, PrivacyMaskSettings, ProviderBadge, PtzPanel, QrCode, RECONNECT_POLICY, RECORDED_PLAYBACK_MODES, RIGHT, ROI_AREA_WARN_FRACTION, ROLE_DESCRIPTOR, RadialGauge, RecordedPlaybackProvider, RecordingPanel, ResponseLog, SCENE_CAPTURE_VARIANTS, SECTION_BODY, SECTION_CARD, SECTION_HEADER, SETTING_ROW, SETTING_ROW_LABEL, SETTING_ROW_STACK_BREAKPOINT, SETTING_ROW_VALUE, SETTING_ROW_VALUE_TEXT, SNAPSHOT_MEDIA_PATH, SPLIT_PANEL_OUTER, SPLIT_PANEL_SIDE, STACK_GAP, STATE_COLOR, SceneMonitorEditor, ScopePicker, ScriptHeroCard, ScriptInlineControl, ScrollArea, Select, SemanticBadge, SensorHeroCard, SensorInlineControl, SensorValueAtom, Separator, SettingRow, Sidebar, SidebarItem, Skeleton, SlideOverPanel, SlideToggle, SnapshotButton, SortHeaderButton, StatCard, StateValuesStream, StatusBadge, StepTimings, StepTreeMaster, Stepper, StreamBrokerSelector, StreamDebugOverlay, StreamPanel, Switch, SwitchHeroCard, SwitchInlineControl, SwitchPanel, SystemProvider, TABLE_SCROLL_MAX_H, TEXT_FIELD_LABEL, TEXT_HINT, TEXT_METRIC, TEXT_SECTION_LABEL, TEXT_VALUE, TIMEZONES, Tabs, TabsContent, TabsList, TabsTrigger, TapToggle, ThemeProvider, ThermostatHeroCard, ThermostatInlineControl, TimezoneSelector, Tooltip, TooltipContent, TooltipTrigger, VacuumHeroCard, VacuumInlineControl, ValueReadout, ValveHeroCard, ValveInlineControl, VersionBadge, VodPlaybackProvider, WaterHeaterHeroCard, WaterHeaterInlineControl, WeatherHeroCard, WeatherInlineControl, WidgetMetricCard, WidgetPanel, WidgetRegistryProvider, WidgetSlot, ZoneEditingProvider, ImageOff as a, agentColumnKey, allDeviceTypeFilterOptions, applyFleetQueryDefaults, ariaSortForColumn, badgeFor, buildStepTreeFromSchema, Camera as c, childEntityId, childListName, classifyCapability, cn, columnsForContext, containerChildToRef, countableDevices, coverHighlight, coverageLine, createSharedContext, createTheme, cursorFractionFor, darkColors, defaultTheme, deriveDeviceKind, deriveWebrtcDebugStats, describeDeviceSelector, deviceMatchesFilter, deviceOptionLabel, deviceRoleMeta, deviceRoleMetaOf, deviceTypeLabel, deviceTypeMeta, deviceTypeMetaOf, devicesToOptions, ensureMfHostInit, eventKindLabel, filterDeviceOptions, findTimezone, formatControlDateTime, formatLastSeen, formatNumeric, freezeVerdict, fuzzyMatch, getClassColor, getPhaseVisual, groupAgentColumns, groupChildrenByLayout, hardwareLabel, hubOrigin, hubPath, hubUrl, hubWsUrl, humanDuration, humidifierTint, Mic as i, initialScrubState, isAbsentProvider, isFieldVisible, createLucideIcon as l, lawnMowerActivityMeta, lightColors, loadRemoteBundle, makeScrubBridge, metadataEntries, metadataString, mirror, mountAddonPage, mountPath, Square as n, nextReconnectAction, nextSort, nextSortDirection, nextTableSort, normalizeForSearch, Grid2x2 as o, openTopLayer, overrideEntityIdFromLink, parseRecordedServerMessage, providerIcons, RotateCcw as r, resetHubMountForTests, resolveContainerPrimary, resolveControlAlign, resolveDeviceControl, resolveDisplayIcon, resolveEffectiveDefaultModel, resolveEffectiveStepModel, resolveEventKindIcon, resolvePrimaryChild, resolveSensorDisplay, resolveStepDefaultModel, resolveTableLayout, roiTooLarge, routerBasename, EyeOff as s, scrubReducer, selectedDeviceOptions, serializeRecordedCommand, shouldCommit, shouldEmit, shouldUseSingleNode, sortRows, sortRowsByColumn, statusIcons, statusLine, stepHasModelForFormat, stepModelOptions, stripParentNamePrefix, Trash2 as t, tabForSelector, tankAlert, themeToCss, toStationaryOverlayBox, trpc, useAccessoriesGetStatus, useAccessoriesSetChildHidden, useAddonPagesListPages, useAddonSettingsGetDeviceSettings, useAddonSettingsGetGlobalSettings, useAddonSettingsGetIntegrationSettings, useAddonSettingsUpdateDeviceSettings, useAddonSettingsUpdateGlobalSettings, useAddonWidgetsListWidgets, useAddonsApplyAutoUpdateToAll, useAddonsCancelJob, useAddonsCustom, useAddonsForceRefresh, useAddonsGetAddonAutoUpdate, useAddonsGetAutoUpdateSettings, useAddonsGetJob, useAddonsGetLastRestart, useAddonsGetLogs, useAddonsGetVersions, useAddonsInstallFromWorkspace, useAddonsInstallPackage, useAddonsIsWorkspaceAvailable, useAddonsList, useAddonsListCapabilityProviders, useAddonsListFrameworkPackages, useAddonsListJobs, useAddonsListPackages, useAddonsListUpdates, useAddonsListWorkspacePackages, useAddonsOnAddonLogs, useAddonsReloadPackages, useAddonsRestartAddon, useAddonsRestartServer, useAddonsRetryLoad, useAddonsRollbackPackage, useAddonsSearchAvailable, useAddonsSetAddonAutoUpdate, useAddonsSetAutoUpdateSettings, useAddonsSetCapabilityProviderEnabled, useAddonsStartJob, useAddonsUninstallPackage, useAddonsUpdatePackage, useAirQualitySensorGetStatus, useAlarmPanelArm, useAlarmPanelDisarm, useAlarmPanelGetStatus, useAlarmPanelTrigger, useAlert, useAlertsDismiss, useAlertsEmit, useAlertsGetUnreadCount, useAlertsList, useAlertsMarkAllRead, useAlertsMarkRead, useAlertsUpdate, useAllWidgets, useAmbientLightSensorGetStatus, useAudioAnalysisApplyDeviceSettingsPatch, useAudioAnalysisGetDeviceLiveContribution, useAudioAnalysisGetDeviceSettingsContribution, useAudioAnalysisResolveDeviceSettings, useAudioAnalyzerAnalyseChunk, useAudioAnalyzerAttachDevice, useAudioAnalyzerClassify, useAudioAnalyzerDetachDevice, useAudioAnalyzerDispose, useAudioAnalyzerIsReady, useAudioAnalyzerReprobeAudioEngine, useAudioCodecCanHandle, useAudioCodecCloseSession, useAudioCodecCreateDecodeSession, useAudioCodecCreateEncodeSession, useAudioCodecFlushEncode, useAudioCodecListActiveSessions, useAudioCodecListSupportedCodecs, useAudioCodecPullEncoded, useAudioCodecPullPcm, useAudioCodecPushEncodedFrame, useAudioCodecPushPcm, useAudioMetricsGetCurrentSnapshot, useAudioMetricsGetHistory, useAutomationControlDisable, useAutomationControlEnable, useAutomationControlGetStatus, useAutomationControlTrigger, useBackupCancel, useBackupDelete, useBackupDeleteSchedule, useBackupGetEntries, useBackupList, useBackupListArchives, useBackupListDestinations, useBackupListLocations, useBackupListRuns, useBackupListSchedules, useBackupPreviewSchedule, useBackupRestore, useBackupTrigger, useBackupUpsertDestinationPolicy, useBackupUpsertSchedule, useBatteryGetStatus, useBatteryWakeForStream, useBinaryGetStatus, useBrightnessGetStatus, useBrightnessSetBrightness, useBrokerAdd, useBrokerGet, useBrokerGetBrokerConfig, useBrokerGetSettings, useBrokerGetSettingsSchema, useBrokerGetState, useBrokerGetStatus, useBrokerList, useBrokerListProviders, useBrokerPublish, useBrokerRemove, useBrokerSetSettings, useBrokerSubscribe, useBrokerTestConnection, useBrokerTestSettings, useBrokerUnsubscribe, useButtonPress, useCameraCredentialsGetCredentials, useCameraCredentialsGetStatus, useCameraGridLayoutApplyDeviceSettingsPatch, useCameraGridLayoutGetDeviceLiveContribution, useCameraGridLayoutGetDeviceSettingsContribution, useCameraGridLayoutGetLayout, useCameraGridLayoutSaveLayout, useCameraPipelineConfigApplyDeviceSettingsPatch, useCameraPipelineConfigGetDeviceLiveContribution, useCameraPipelineConfigGetDeviceSettingsContribution, useCameraStreamsGetBrokerStreams, useCameraStreamsGetCameraStreams, useCameraStreamsGetProfileRtspEntries, useCameraStreamsGetRtspEntries, useCameraStreamsPickStream, useCapabilityPresence, useCarbonMonoxideGetStatus, useClimateControlGetStatus, useClimateControlSetFanMode, useClimateControlSetMode, useClimateControlSetPreset, useClimateControlSetSwingHorizontal, useClimateControlSetSwingVertical, useClimateControlSetTarget, useClimateControlSetTargetHumidity, useClimateControlSetTargetRange, useClusterNodes, useClusterTopology, useColorGetStatus, useColorSetColor, useConfirm, useConnectionTestDescribeTest, useConnectionTestTestSettings, useConnectivityGetStatus, useConsumablesGetStatus, useConsumablesReset, useContactGetStatus, useContainerChildren, useControlGetStatus, useControlSetValue, useCoreBlocksCompile, useCoreBlocksCreate, useCoreBlocksDelete, useCoreBlocksGet, useCoreBlocksGetTypeDefs, useCoreBlocksList, useCoreBlocksRestart, useCoreBlocksSetEnabled, useCoreBlocksUpdate, useCoverClose, useCoverGetStatus, useCoverOpen, useCoverSetPosition, useCoverSetTiltPosition, useCoverStop, useCustomFieldRenderer, useDayNightGetOptions, useDayNightGetStatus, useDayNightSetSettings, useDebouncedString, useDecoderCreateSession, useDecoderDestroySession, useDecoderGetFrame, useDecoderGetInfo, useDecoderGetShmStats, useDecoderGetStats, useDecoderListActiveSessions, useDecoderOpenStream, useDecoderPullFrames, useDecoderPullHandles, useDecoderPushPacket, useDecoderReprobeHwaccel, useDecoderSupportsCodec, useDecoderUpdateConfig, useDetectionPipelineApplyDeviceSettingsPatch, useDetectionPipelineGetDeviceLiveContribution, useDetectionPipelineGetDeviceSettingsContribution, useDevShell, useDevice, useDeviceAdoptionAdopt, useDeviceAdoptionGetCandidate, useDeviceAdoptionGetStatus, useDeviceAdoptionListCandidateFilters, useDeviceAdoptionListCandidates, useDeviceAdoptionRefresh, useDeviceAdoptionRelease, useDeviceAdoptionResync, useDeviceAutotrack, useDeviceBattery, useDeviceCapSlice, useDeviceCapability, useDeviceDetections, useDeviceDiscoveryAdoptDevice, useDeviceDiscoveryGetStatus, useDeviceDiscoveryListDiscovered, useDeviceDiscoveryRefreshDiscovery, useDeviceDiscoveryReleaseDevice, useDeviceExportApplyDeviceSettingsPatch, useDeviceExportExposeDevice, useDeviceExportGetDeviceLiveContribution, useDeviceExportGetDeviceSettingsContribution, useDeviceExportGetStatus, useDeviceExportListExposedDevices, useDeviceExportListSupportedDeviceKinds, useDeviceExportUnexposeDevice, useDeviceId, useDeviceListPageSize, useDeviceManagerAddLocation, useDeviceManagerAdoptDevice, useDeviceManagerAdoptionAdopt, useDeviceManagerAdoptionCancelJob, useDeviceManagerAdoptionListCandidateFilters, useDeviceManagerAdoptionListCandidates, useDeviceManagerAdoptionListJobs, useDeviceManagerAdoptionRefresh, useDeviceManagerAdoptionRelease, useDeviceManagerAdoptionResync, useDeviceManagerAdoptionStartJob, useDeviceManagerAllocateDeviceId, useDeviceManagerApplyDeviceSettingsPatch, useDeviceManagerApplyInitialMeta, useDeviceManagerCreateDevice, useDeviceManagerDisable, useDeviceManagerDiscoverAllProviders, useDeviceManagerDiscoverDevices, useDeviceManagerDiscoverProvider, useDeviceManagerDiscoveryProviders, useDeviceManagerEnable, useDeviceManagerGetAllBindings, useDeviceManagerGetBindings, useDeviceManagerGetBindingsBatch, useDeviceManagerGetChildren, useDeviceManagerGetChildrenBatch, useDeviceManagerGetConfigSchema, useDeviceManagerGetCreationSchema, useDeviceManagerGetDevice, useDeviceManagerGetDeviceAggregate, useDeviceManagerGetDeviceLiveContribution, useDeviceManagerGetDeviceLiveInfoAggregate, useDeviceManagerGetDeviceSettingsAggregate, useDeviceManagerGetDeviceSettingsContribution, useDeviceManagerGetDeviceStatusAggregate, useDeviceManagerGetDeviceStatusAggregateBatch, useDeviceManagerGetLinkedDevices, useDeviceManagerGetLinkedDevicesBatch, useDeviceManagerGetRoleDisplayDefaults, useDeviceManagerGetSettingsSchema, useDeviceManagerGetStreamProfileMap, useDeviceManagerGetStreamSources, useDeviceManagerGetWireableFields, useDeviceManagerListAll, useDeviceManagerListBindableCapsForDeviceType, useDeviceManagerListLocationDescriptions, useDeviceManagerListLocationIcons, useDeviceManagerListLocations, useDeviceManagerListPersistedByAddon, useDeviceManagerListSiteZones, useDeviceManagerListWrappersForCap, useDeviceManagerLoadConfig, useDeviceManagerLoadMeta, useDeviceManagerLoadRuntimeState, useDeviceManagerMigrateDevice, useDeviceManagerPersistConfig, useDeviceManagerProbeStreams, useDeviceManagerProviderCreationType, useDeviceManagerProviderDiscoveryParamsSchema, useDeviceManagerRegisterDevice, useDeviceManagerRemove, useDeviceManagerRemoveByIntegration, useDeviceManagerRemoveDevice, useDeviceManagerRemoveLocation, useDeviceManagerRemoveSiteZone, useDeviceManagerRenameLocation, useDeviceManagerRenameSiteZone, useDeviceManagerRunDeviceAction, useDeviceManagerSetChildLayout, useDeviceManagerSetDisabled, useDeviceManagerSetDisplay, useDeviceManagerSetIntegrationId, useDeviceManagerSetLinkDeviceId, useDeviceManagerSetLocation, useDeviceManagerSetLocationDescription, useDeviceManagerSetLocationIcon, useDeviceManagerSetLocationZone, useDeviceManagerSetMetadata, useDeviceManagerSetName, useDeviceManagerSetPrimaryChildEntityId, useDeviceManagerSetRole, useDeviceManagerSetRoleDisplayDefaults, useDeviceManagerSetSiteZone, useDeviceManagerSetStreamProfileMap, useDeviceManagerSetType, useDeviceManagerSetWrapperActive, useDeviceManagerTestCreationField, useDeviceManagerTestField, useDeviceManagerUpdateConfig, useDeviceManagerUpdateDeviceField, useDeviceManagerUpdateDeviceFieldsBatch, useDeviceNetworkLink, useDeviceOpsGetConfigEntries, useDeviceOpsGetRawState, useDeviceOpsGetSettingsSchema, useDeviceOpsGetStreamSources, useDeviceOpsRemoveDevice, useDeviceOpsRunAction, useDeviceOpsSetConfig, useDeviceProviderAdoptDiscoveredDevice, useDeviceProviderCreateDevice, useDeviceProviderDiscoverDevices, useDeviceProviderGetChildCreationSchema, useDeviceProviderGetDevices, useDeviceProviderGetDiscoveryParamsSchema, useDeviceProviderGetManualCreationType, useDeviceProviderGetStatus, useDeviceProviderReloadDevice, useDeviceProviderStart, useDeviceProviderStop, useDeviceProviderSupportsDiscovery, useDeviceProviderSupportsManualCreation, useDeviceProviderTestCreationField, useDeviceProxy, useDeviceSnapshot, useDeviceSnapshotImage, useDeviceState, useDeviceStateGetAllSnapshots, useDeviceStateGetCapSlice, useDeviceStateGetSnapshot, useDeviceStateSetCapSlice, useDeviceStateSlice, useDeviceStatusGetStatus, useDeviceWebrtc, useDevices, useDoorbellApplyDeviceSettingsPatch, useDoorbellEvents, useDoorbellGetDeviceLiveContribution, useDoorbellGetDeviceSettingsContribution, useDoorbellGetStatus, useEnumSensorGetStatus, useEventEmitterGetStatus, useEventInvalidation, useEventStreamLatest, useEventStreamMap, useEventsGetEventClipUrl, useEventsGetEventThumbnail, useEventsGetEvents, useFaceGalleryAssignFace, useFaceGalleryAssignFaces, useFaceGalleryAuditIdentitySamples, useFaceGalleryCreateIdentity, useFaceGalleryDeleteFace, useFaceGalleryDeleteIdentity, useFaceGalleryGetFaceByTrack, useFaceGalleryGetFaceMedia, useFaceGalleryListIdentities, useFaceGalleryListIdentitySamples, useFaceGalleryListRecentFaces, useFaceGalleryRemoveSample, useFaceGalleryRenameIdentity, useFaceGallerySuggestFaceClusters, useFaceGalleryUnassignFace, useFaceGalleryUnassignFaces, useFanControlGetStatus, useFanControlSetDirection, useFanControlSetOscillating, useFanControlSetPercentage, useFanControlSetPreset, useFeatureProbeGetStatus, useFloodGetStatus, useGasGetStatus, useHumidifierGetStatus, useHumidifierSetMode, useHumidifierSetOn, useHumidifierSetTargetHumidity, useHumiditySensorGetStatus, useImageGetStatus, useImageSettingsGetOptions, useImageSettingsGetStatus, useImageSettingsSetSettings, useIntegrationsCreate, useIntegrationsDelete, useIntegrationsGet, useIntegrationsGetAvailableTypes, useIntegrationsGetByAddonId, useIntegrationsGetSettings, useIntegrationsList, useIntegrationsSetSettings, useIntegrationsTestConnection, useIntegrationsUpdate, useIntercomEndTalkSession, useIntercomGetStatus, useIntercomHandleAnswer, useIntercomPushTalkAudio, useIntercomStartSession, useIntercomStartTalkSession, useIntercomStopSession, useIsMidWidth, useIsMobile, useLawnMowerControlDock, useLawnMowerControlGetStatus, useLawnMowerControlPause, useLawnMowerControlStartMowing, useLiveBuffer, useLiveEvent, useLlmCancel, useLlmDeleteModel, useLlmDeleteProfile, useLlmGenerate, useLlmGenerateVision, useLlmGetDefaults, useLlmGetRuntimeStatus, useLlmGetUsage, useLlmInstallModel, useLlmListModelCatalog, useLlmListModels, useLlmListNodeModels, useLlmListProfileKinds, useLlmListProfiles, useLlmListRuntimeNodes, useLlmResolveModelRef, useLlmSetDefault, useLlmStartRuntime, useLlmStopRuntime, useLlmTestProfile, useLlmUpsertProfile, useLocalNetworkDownloadCa, useLocalNetworkGetAllowedAddresses, useLocalNetworkGetConnectionEndpoints, useLocalNetworkGetNotificationEndpoint, useLocalNetworkGetPreferred, useLocalNetworkGetTlsStatus, useLocalNetworkGetViewerEndpoints, useLocalNetworkList, useLocalNetworkRegenerateCertificate, useLocalNetworkResetAllowlistToBestMatch, useLocalNetworkRevertToGeneratedCertificate, useLocalNetworkSetAllowedAddresses, useLocalNetworkSetNotificationEndpoint, useLocalNetworkSetViewerEndpoints, useLocalNetworkUploadCertificate, useLockControlGetStatus, useLockControlLock, useLockControlOpen, useLockControlUnlock, useMediaPlayerGetStatus, useMediaPlayerNext, useMediaPlayerPause, useMediaPlayerPlay, useMediaPlayerPlayMedia, useMediaPlayerPrevious, useMediaPlayerSeek, useMediaPlayerSelectSource, useMediaPlayerSetMute, useMediaPlayerSetRepeat, useMediaPlayerSetShuffle, useMediaPlayerSetVolume, useMediaPlayerStop, useMeshNetworkGetStatus, useMeshNetworkJoin, useMeshNetworkLeave, useMeshNetworkListPeers, useMeshNetworkLogout, useMeshNetworkStartLogin, useMeshNetworkTestConnection, useMetricsProviderCollectSnapshot, useMetricsProviderGetAddonStats, useMetricsProviderGetCached, useMetricsProviderGetCpuTemperature, useMetricsProviderGetCurrent, useMetricsProviderGetDiskSpace, useMetricsProviderGetGpuInfo, useMetricsProviderGetLoadSeries, useMetricsProviderGetProcessStats, useMetricsProviderListAddonInstances, useMetricsProviderListNodeProcesses, useMotionDetectionAnalyze, useMotionDetectionApplyDeviceSettingsPatch, useMotionDetectionGetDeviceLiveContribution, useMotionDetectionGetDeviceSettingsContribution, useMotionDetectionRemoveCamera, useMotionDetectionReset, useMotionGetStatus, useMotionIsDetected, useMotionTriggerGetStatus, useMotionTriggerSetMotionTrigger, useMotionZonesGetOptions, useMotionZonesGetStatus, useMotionZonesSetZone, useMqttBrokerAddBroker, useMqttBrokerGetBrokerConfig, useMqttBrokerGetStatus, useMqttBrokerListBrokers, useMqttBrokerRemoveBroker, useMqttBrokerStartEmbeddedBroker, useMqttBrokerStopEmbeddedBroker, useMqttBrokerTestConnection, useNativeObjectDetectionGetOptions, useNativeObjectDetectionGetStatus, useNativeObjectDetectionSetEnabled, useNativeObjectDetectionSetSettings, useNavigation, useNavigationGetFeatures, useNavigationGetStatus, useNavigationGoToPoint, useNavigationListActions, useNavigationMove, useNavigationPlaySound, useNavigationRunAction, useNavigationSetLightLevel, useNavigationSetLightMode, useNavigationSetLightOn, useNavigationStop, useNetworkAccessGetEndpoint, useNetworkAccessGetStatus, useNetworkAccessListEndpoints, useNetworkAccessStart, useNetworkAccessStop, useNetworkLinkGetStatus, useNetworkQualityGetAllStats, useNetworkQualityGetDeviceStats, useNetworkQualityReportClientStats, useNodesClusterAddonStatus, useNodesDeployAddon, useNodesExecuteQuery, useNodesGetCapUsageGraph, useNodesGetNodeAddons, useNodesRenameNode, useNodesRestartAddon, useNodesRestartNode, useNodesRestartProcess, useNodesSetProcessLogLevel, useNodesShutdownNode, useNodesTopology, useNodesUndeployAddon, useNotificationOutputDeleteTarget, useNotificationOutputDiscoverTargets, useNotificationOutputListTargetKinds, useNotificationOutputListTargets, useNotificationOutputSend, useNotificationOutputSetTargetEnabled, useNotificationOutputTestTarget, useNotificationOutputUpsertTarget, useNotificationRulesCancelSnooze, useNotificationRulesCreateRule, useNotificationRulesCreateSnooze, useNotificationRulesDeleteRule, useNotificationRulesGetAlarmConfig, useNotificationRulesGetClipRetentionAsks, useNotificationRulesGetConditionCatalog, useNotificationRulesGetHistory, useNotificationRulesGetRule, useNotificationRulesListDeviceMutes, useNotificationRulesListRules, useNotificationRulesListSnoozes, useNotificationRulesResolveArtifactUrl, useNotificationRulesSetAlarmConfig, useNotificationRulesSetDeviceMuted, useNotificationRulesSetRuleEnabled, useNotificationRulesTestRule, useNotificationRulesUpdateRule, useNotifierCancel, useNotifierGetStatus, useNotifierSend, useNumericSensorGetStatus, useOptimisticSlice, useOptionalSystem, useOptionalWidgetRegistry, useOsdGetStatus, useOsdManagerClearSlotBinding, useOsdManagerCopyDeviceConfiguration, useOsdManagerGetConditionSupport, useOsdManagerGetDeviceOsd, useOsdManagerGetSourceCatalog, useOsdManagerPreviewSlot, useOsdManagerRenderDevice, useOsdManagerSetSlotBinding, useOsdSetOverlay, usePTZ, usePetFeederCallPet, usePetFeederCancelFeed, usePetFeederFeed, usePetFeederGetStatus, usePetFeederMarkFoodReplenished, usePetFeederPlaySound, usePetFeederResetDesiccant, usePetFeederSetChildLock, usePetFeederSetFeedSound, usePetFeederSetIndicatorLight, usePetFeederSetVolume, usePipelineAnalyticsApplyDeviceSettingsPatch, usePipelineAnalyticsCancelRelocateMedia, usePipelineAnalyticsCancelStorageMigrationMove, usePipelineAnalyticsClearTracks, usePipelineAnalyticsCompleteRetrainTrack, usePipelineAnalyticsCountRelocatableMedia, usePipelineAnalyticsCountUnstampedEventMedia, usePipelineAnalyticsDeleteDeviceEvents, usePipelineAnalyticsDeleteTracks, usePipelineAnalyticsDeselectRetrainFrame, usePipelineAnalyticsGetActiveTracks, usePipelineAnalyticsGetAudioEvents, usePipelineAnalyticsGetDeviceLiveContribution, usePipelineAnalyticsGetDeviceSettingsContribution, usePipelineAnalyticsGetEventDensity, usePipelineAnalyticsGetEventDensityBatch, usePipelineAnalyticsGetEventMedia, usePipelineAnalyticsGetEventMediaFootprintByKind, usePipelineAnalyticsGetEventStoreFootprint, usePipelineAnalyticsGetKeyEvents, usePipelineAnalyticsGetKeyEventsBatch, usePipelineAnalyticsGetMediaReclaimStatus, usePipelineAnalyticsGetMotionEvents, usePipelineAnalyticsGetObjectEmbeddingRebuildStatus, usePipelineAnalyticsGetObjectEvents, usePipelineAnalyticsGetRetrainExportUrl, usePipelineAnalyticsGetRetrainFrameImage, usePipelineAnalyticsGetSensorEvents, usePipelineAnalyticsGetStorageMigrationMoveStatus, usePipelineAnalyticsGetSummary, usePipelineAnalyticsGetTrack, usePipelineAnalyticsGetTrackMedia, usePipelineAnalyticsGetTrainingExportSummary, usePipelineAnalyticsGetTrainingExportUrl, usePipelineAnalyticsListArchivedDebugNotes, usePipelineAnalyticsListBirthDecisions, usePipelineAnalyticsListEventKinds, usePipelineAnalyticsListEventKindsBatch, usePipelineAnalyticsListEventMedia, usePipelineAnalyticsListOpsLog, usePipelineAnalyticsListRecentSummaries, usePipelineAnalyticsListRecentTracks, usePipelineAnalyticsListRelocateMediaJobs, usePipelineAnalyticsListRetrainAnnotations, usePipelineAnalyticsListRetrainFrames, usePipelineAnalyticsListRetrainStaging, usePipelineAnalyticsListSummaries, usePipelineAnalyticsListTrackMedia, usePipelineAnalyticsListTracks, usePipelineAnalyticsOwnersWithMedia, usePipelineAnalyticsPauseForStorageMigration, usePipelineAnalyticsProposeRetrainAnnotations, usePipelineAnalyticsPruneEvents, usePipelineAnalyticsPruneEventsBefore, usePipelineAnalyticsPruneTracksBefore, usePipelineAnalyticsReadLongTermSeries, usePipelineAnalyticsRebuildObjectEmbeddings, usePipelineAnalyticsReclaimDebugMedia, usePipelineAnalyticsReconcileFromDisk, usePipelineAnalyticsRefreshStorageLocationsForMigration, usePipelineAnalyticsRelocateMedia, usePipelineAnalyticsRestageRetrainTrack, usePipelineAnalyticsResumeForStorageMigration, usePipelineAnalyticsRunReplayFrameProcessor, usePipelineAnalyticsSaveRetrainAnnotations, usePipelineAnalyticsSearchObjectEvents, usePipelineAnalyticsSelectRetrainFrames, usePipelineAnalyticsSetTrackFlags, usePipelineAnalyticsStartStorageMigrationMove, usePipelineAnalyticsWipeAllAnalytics, usePipelineAnalyticsWipeObjectEmbeddings, usePipelineExecutorCacheFrameInPool, usePipelineExecutorClearDeviceOverrides, usePipelineExecutorDeleteModel, usePipelineExecutorDeleteTemplate, usePipelineExecutorDownloadModel, usePipelineExecutorGetAddonModels, usePipelineExecutorGetAudioCapabilities, usePipelineExecutorGetAvailableEngines, usePipelineExecutorGetCapabilities, usePipelineExecutorGetDefaultSteps, usePipelineExecutorGetDetectionConfigSchema, usePipelineExecutorGetEffectiveTuning, usePipelineExecutorGetEngineProvisioning, usePipelineExecutorGetGlobalPipelineConfig, usePipelineExecutorGetGlobalSteps, usePipelineExecutorGetInferenceDeviceHealth, usePipelineExecutorGetOrchestratorConfigSchema, usePipelineExecutorGetReferenceAudio, usePipelineExecutorGetReferenceAudioFiles, usePipelineExecutorGetReferenceImage, usePipelineExecutorGetSchema, usePipelineExecutorGetSelectedEngine, usePipelineExecutorGetVideoPipelineSteps, usePipelineExecutorInferCached, usePipelineExecutorKillEngine, usePipelineExecutorListLoadedEngines, usePipelineExecutorListReferenceImages, usePipelineExecutorListTemplates, usePipelineExecutorRearmInferenceDevice, usePipelineExecutorRunAudioTest, usePipelineExecutorRunPipeline, usePipelineExecutorRunPipelineBatch, usePipelineExecutorSaveTemplate, usePipelineExecutorSetVideoPipelineSteps, usePipelineExecutorSpinEngine, usePipelineExecutorUncacheFrame, usePipelineExecutorUpdateTemplate, usePipelineExecutorValidatePipeline, usePipelineOrchestratorApplyDeviceSettingsPatch, usePipelineOrchestratorAssignAudio, usePipelineOrchestratorAssignPipeline, usePipelineOrchestratorDeleteTemplate, usePipelineOrchestratorGetAgentLoad, usePipelineOrchestratorGetAgentSettings, usePipelineOrchestratorGetAudioAssignment, usePipelineOrchestratorGetAudioAssignments, usePipelineOrchestratorGetAudioNodeLoad, usePipelineOrchestratorGetCameraMetrics, usePipelineOrchestratorGetCameraSettings, usePipelineOrchestratorGetCameraStatus, usePipelineOrchestratorGetCameraStatuses, usePipelineOrchestratorGetCameraStepOverrides, usePipelineOrchestratorGetCameraSwitches, usePipelineOrchestratorGetCapabilityBindings, usePipelineOrchestratorGetDeviceLiveContribution, usePipelineOrchestratorGetDeviceSettingsContribution, usePipelineOrchestratorGetGlobalMetrics, usePipelineOrchestratorGetIngestOwner, usePipelineOrchestratorGetNodeInferenceDevices, usePipelineOrchestratorGetPipelineAssignment, usePipelineOrchestratorGetPipelineAssignments, usePipelineOrchestratorGetPipelineDevicePin, usePipelineOrchestratorGetReconcileFromDiskStatus, usePipelineOrchestratorListAgentSettings, usePipelineOrchestratorListTemplates, usePipelineOrchestratorPauseForStorageMigration, usePipelineOrchestratorRebalance, usePipelineOrchestratorReconcileFromDisk, usePipelineOrchestratorRemoveAgentSettings, usePipelineOrchestratorResetNodePipelineDefaults, usePipelineOrchestratorResolvePipeline, usePipelineOrchestratorResumeForStorageMigration, usePipelineOrchestratorSaveTemplate, usePipelineOrchestratorSetAgentCapabilities, usePipelineOrchestratorSetAgentDecodeLimits, usePipelineOrchestratorSetAgentDetectWeight, usePipelineOrchestratorSetAgentInferenceDevices, usePipelineOrchestratorSetAgentMaxCameras, usePipelineOrchestratorSetAgentReachableHost, usePipelineOrchestratorSetCameraPipelineForAgent, usePipelineOrchestratorSetCameraStepOverride, usePipelineOrchestratorSetCameraStepToggle, usePipelineOrchestratorSetCameraSwitch, usePipelineOrchestratorSetCapabilityBinding, usePipelineOrchestratorSetPipelineDevicePin, usePipelineOrchestratorUnassignAudio, usePipelineOrchestratorUnassignPipeline, usePipelineOrchestratorUpdateTemplate, usePipelineRunnerAttachCamera, usePipelineRunnerDetachCamera, usePipelineRunnerGetAllCameraMetrics, usePipelineRunnerGetCameraMetrics, usePipelineRunnerGetLocalCameras, usePipelineRunnerGetLocalLoad, usePipelineRunnerGetLocalMetrics, usePipelineRunnerGetNativeCrop, usePipelineRunnerGetParkedTrackFrame, usePipelineRunnerParkTrackFrame, usePipelineRunnerReleaseParkedTrackFrames, usePipelineRunnerReportMotion, usePipelineRunnerRequestOccupancyBurst, usePipelineRunnerRunDetailSubtree, usePipelineRunnerRunStatelessStep, usePlateGalleryAssignPlate, usePlateGalleryAssignPlates, usePlateGalleryCorrectPlateText, usePlateGalleryCreateVehicle, usePlateGalleryDeletePlate, usePlateGalleryDeleteVehicle, usePlateGalleryGetPlateByTrack, usePlateGalleryGetPlateMedia, usePlateGalleryListPlates, usePlateGalleryListVehicleSamples, usePlateGalleryListVehicles, usePlateGalleryRemoveVehicleSample, usePlateGalleryRenameVehicle, usePlateGallerySearchPlates, usePlateGallerySuggestPlateClusters, usePlateGalleryUnassignPlate, usePlateGalleryUnassignPlates, usePlayerOverlayLayer, usePlayerOverlayLayers, usePlayerToolbarButton, usePlayerToolbarButtons, usePowerMeterGetStatus, usePresenceGetStatus, usePressureSensorGetStatus, usePrivacyMaskGetOptions, usePrivacyMaskGetStatus, usePrivacyMaskSetAudioEnabled, usePrivacyMaskSetMask, usePrompt, usePtzAutotrackGetSettings, usePtzAutotrackGetStatus, usePtzAutotrackSetEnabled, usePtzAutotrackSetSettings, usePtzCaptureHomeHere, usePtzContinuousMove, usePtzDeletePreset, usePtzGetHomePreset, usePtzGetHomeReturn, usePtzGetOptions, usePtzGetPosition, usePtzGetPresets, usePtzGetStatus, usePtzGoHome, usePtzGoToPreset, usePtzMove, usePtzSavePreset, usePtzSetAutofocus, usePtzSetHomePreset, usePtzSetHomeReturn, usePtzStop, useRebootReboot, useRecordedPlayback, useRecordingApplyDeviceSettingsPatch, useRecordingCancelRelocateJob, useRecordingCancelStorageMigrationMove, useRecordingDeleteFootprint, useRecordingExportCancelExport, useRecordingExportCreateExport, useRecordingExportDeleteExport, useRecordingExportGetDownloadUrl, useRecordingExportGetExport, useRecordingExportListExports, useRecordingExportReadExportBytes, useRecordingGetAvailability, useRecordingGetAvailabilityBatch, useRecordingGetDaysWithRecordings, useRecordingGetDaysWithRecordingsBatch, useRecordingGetDeviceConfig, useRecordingGetDeviceLiveContribution, useRecordingGetDeviceSettingsContribution, useRecordingGetPlacement, useRecordingGetPlaybackManifest, useRecordingGetRelocateResidue, useRecordingGetStatus, useRecordingGetStorageMigrationMoveStatus, useRecordingGetStorageUsage, useRecordingListOpsLog, useRecordingListRelocateJobs, useRecordingLocateSegment, useRecordingPauseForStorageMigration, useRecordingPlanStorageRebalance, useRecordingPruneFootage, useRecordingReadGopBytes, useRecordingReadSegmentBytes, useRecordingReadWindowBytes, useRecordingReconcileLedgerAgainstDisk, useRecordingRefreshStorageLocationsForMigration, useRecordingRelocateFootage, useRecordingRenderClip, useRecordingRenderGif, useRecordingRescanStorage, useRecordingResumeForStorageMigration, useRecordingSetDeviceConfig, useRecordingSetDevicePlacement, useRecordingSignalGetStatus, useRecordingStartStorageMigrationMove, useRecordingStartStorageRebalance, useRemoteComponent, useSceneMonitorCaptureReference, useSceneMonitorCreateScene, useSceneMonitorDeleteReference, useSceneMonitorDeleteScene, useSceneMonitorGetStatus, useSceneMonitorListScenes, useSceneMonitorListScenesBatch, useSceneMonitorRecheckNow, useSceneMonitorResetScene, useSceneMonitorUpdateScene, useScriptRunnerGetStatus, useScriptRunnerRun, useScriptRunnerStop, useScrubController, useServerManagementApplyServerUpdate, useServerManagementCheckServerUpdate, useServerManagementGetServerPackageStatus, useServerManagementRestartServer, useServerManagementRollbackServerUpdate, useSettingsStoreAggregate, useSettingsStoreCount, useSettingsStoreDeclareCollection, useSettingsStoreDelete, useSettingsStoreDeleteWhere, useSettingsStoreGet, useSettingsStoreHistogram, useSettingsStoreInsert, useSettingsStoreInsertMany, useSettingsStoreIsEmpty, useSettingsStoreQuery, useSettingsStoreSet, useSettingsStoreUpdate, useSettingsStoreUpdateWhere, useSettingsStoreUpsert, useSmokeGetStatus, useSnapshotApplyDeviceSettingsPatch, useSnapshotGetDebugState, useSnapshotGetDeviceLiveContribution, useSnapshotGetDeviceSettingsContribution, useSnapshotGetSnapshot, useSnapshotGetSnapshotLinks, useSnapshotGetSnapshotOverview, useSnapshotGetStatus, useSnapshotInvalidateCache, useStationaryOverlay, useStorageAbortUpload, useStorageBeginDownload, useStorageBeginUpload, useStorageDelete, useStorageDeleteLocation, useStorageEndDownload, useStorageExists, useStorageFinalizeUpload, useStorageGetAvailableSpace, useStorageList, useStorageListDrainProgress, useStorageListLocationDeclarations, useStorageListLocations, useStorageListProviders, useStorageMigrationCancel, useStorageMigrationCleanupCancel, useStorageMigrationCleanupStart, useStorageMigrationCleanupStatus, useStorageMigrationDrain, useStorageMigrationHistory, useStorageMigrationMovers, useStorageMigrationPlan, useStorageMigrationResidue, useStorageMigrationStart, useStorageMigrationStatus, useStorageRead, useStorageReadChunk, useStorageResolve, useStorageTestConfig, useStorageTestLocation, useStorageUpsertLocation, useStorageWrite, useStorageWriteChunk, useStreamBrokerAcquireEgressTranscode, useStreamBrokerApplyDeviceSettingsPatch, useStreamBrokerAssignProfile, useStreamBrokerFetchEventMedia, useStreamBrokerForgetDeviceHardware, useStreamBrokerGetAllRtspEntries, useStreamBrokerGetBrokerStats, useStreamBrokerGetDeviceAudioMute, useStreamBrokerGetDeviceLiveContribution, useStreamBrokerGetDeviceSettingsContribution, useStreamBrokerGetPreBufferInfo, useStreamBrokerGetRtspEntry, useStreamBrokerGetRtspPort, useStreamBrokerGetStreamUrl, useStreamBrokerGetStreamWithCodec, useStreamBrokerIsRtspEnabled, useStreamBrokerKillClient, useStreamBrokerListAllCameraStreams, useStreamBrokerListAllProfileSlots, useStreamBrokerListClients, useStreamBrokerProbeStream, useStreamBrokerProduceEventMedia, useStreamBrokerPublishCameraStream, useStreamBrokerPullAudioChunks, useStreamBrokerPullFrameHandles, useStreamBrokerRegenerateRtspToken, useStreamBrokerReleaseEgressTranscode, useStreamBrokerReleaseStreamWithCodec, useStreamBrokerRenderPreBufferClip, useStreamBrokerReportStreamSignal, useStreamBrokerRestartProfile, useStreamBrokerRetractCameraStream, useStreamBrokerSetDeviceAudioMute, useStreamBrokerSetPreBufferDuration, useStreamBrokerSetRtspEnabled, useStreamBrokerSubscribeAudioChunks, useStreamBrokerSubscribeFrames, useStreamBrokerUnassignProfile, useStreamBrokerUnsubscribeAudioChunks, useStreamBrokerUnsubscribeFrames, useStreamCatalogGetCatalog, useStreamParamsGetConfigSchema, useStreamParamsGetOptions, useStreamParamsGetStatus, useStreamParamsSetProfile, useStreamSignalsListSignals, useSwitchGetStatus, useSwitchSetState, useSystem, useSystemDetectSiteLocation, useSystemFeatureFlags, useSystemForceRetentionCleanup, useSystemGetFailureContributions, useSystemGetLoadContributions, useSystemGetLoggingSettings, useSystemGetRequestCensus, useSystemGetRetentionConfig, useSystemGetSiteLocation, useSystemHealth, useSystemInfo, useSystemMutation, useSystemNetworkAddresses, useSystemQuery, useSystemSetLoggingSettings, useSystemSetRetentionConfig, useSystemSetSiteLocation, useTamperGetStatus, useTemperatureSensorGetStatus, useTerminalSessionAdoptLegacyMonitor, useTerminalSessionClose, useTerminalSessionCreateInstance, useTerminalSessionDeleteInstance, useTerminalSessionListInstances, useTerminalSessionListLegacyCameras, useTerminalSessionListProfiles, useTerminalSessionListSessions, useTerminalSessionOpenSession, useTerminalSessionPullOutput, useTerminalSessionResize, useTerminalSessionSetInstanceEnabled, useTerminalSessionUpdateInstance, useTerminalSessionWriteInput, useThemeMode, useToastOnToast, useTurnProviderGetTurnServers, useUpdateGetStatus, useUpdateInstallUpdate, useUserManagementConfirmTotp, useUserManagementCreateApiKey, useUserManagementCreateScopedToken, useUserManagementCreateUser, useUserManagementDeleteUser, useUserManagementDisableTotp, useUserManagementGetTotpStatus, useUserManagementListApiKeys, useUserManagementListOauthSessions, useUserManagementListScopedTokens, useUserManagementListUsers, useUserManagementOauthExchangeCode, useUserManagementOauthIssueCode, useUserManagementOauthRefresh, useUserManagementOauthVerifyAccessToken, useUserManagementResetPassword, useUserManagementRevokeApiKey, useUserManagementRevokeOauthSession, useUserManagementRevokeScopedToken, useUserManagementSetUserScopes, useUserManagementSetupTotp, useUserManagementUpdateUser, useUserManagementValidateApiKey, useUserManagementValidateCredentials, useUserManagementValidateScopedToken, useUserManagementVerifyTotp, useVacuumControlGetStatus, useVacuumControlLocate, useVacuumControlPause, useVacuumControlReturnToBase, useVacuumControlSetFanSpeed, useVacuumControlStart, useVacuumControlStop, useValveClose, useValveGetStatus, useValveOpen, useValveSetPosition, useValveStop, useVibrationGetStatus, useVideoclipsGetClipPlayback, useVideoclipsListClips, useVideoclipsListSources, useVodPlayback, useWaterHeaterGetStatus, useWaterHeaterSetAway, useWaterHeaterSetOperationMode, useWaterHeaterSetTargetTemp, useWeatherGetStatus, useWebrtcSessionAddIceCandidate, useWebrtcSessionCloseSession, useWebrtcSessionCreateSession, useWebrtcSessionGetIceCandidates, useWebrtcSessionGetSessionDebug, useWebrtcSessionGetSessionState, useWebrtcSessionHandleAnswer, useWebrtcSessionHandleOffer, useWebrtcSessionHasAdaptiveBitrate, useWebrtcSessionListStreams, useWidget, useWidgetMetadata, useWidgetRegistry, useZoneAnalyticsGetCameraHistory, useZoneAnalyticsGetCurrentSnapshot, useZoneAnalyticsGetCurrentSnapshotBatch, useZoneAnalyticsGetUnzonedHistory, useZoneAnalyticsGetZoneHistory, useZoneEditing, useZoneRulesListRules, useZoneRulesSetRules, useZonesAddZone, useZonesListZones, useZonesRemoveZone, useZonesUpdateZone, vacuumStateMeta, validateScopes, valveStateMeta, variantLabel, waterHeaterPhase, waterHeaterTint, weatherConditionMeta, weatherTint };