@camstack/ui-library 1.2.368 → 1.2.369
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/CHANGELOG.md +7 -0
- package/dist/{MotionZonesSettings-dx3wObgK.js → MotionZonesSettings-Zcfa5c9l.js} +1 -1
- package/dist/{PrivacyMaskSettings-BM2C_xWz.js → PrivacyMaskSettings-B_X42yzN.js} +1 -1
- package/dist/{SceneMonitorEditor-CI72S4eN.js → SceneMonitorEditor-C8YXVzYI.js} +1 -1
- package/dist/composites/device-controls/ac-panel.d.ts +18 -0
- package/dist/composites/device-controls/heater-control.d.ts +4 -0
- package/dist/composites/device-controls/timed-run-control.d.ts +13 -0
- package/dist/generated/system-hooks.d.ts +14 -0
- package/dist/{icons-jbAtRNh8.cjs → icons-DXwPEKdJ.cjs} +1 -29
- package/dist/{icons-CZwJd50b.js → icons-e-xohmFb.js} +1 -29
- package/dist/index.cjs +1430 -1080
- package/dist/index.js +1429 -1087
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import * as __mfHostReact from "react";
|
|
|
5
5
|
import React, { Fragment, Suspense, cloneElement, createContext, createElement, forwardRef, lazy, useCallback, useContext, useEffect, useId, useImperativeHandle, useLayoutEffect, useMemo, useReducer, useRef, useState, useSyncExternalStore } from "react";
|
|
6
6
|
import * as __mfHostReactJsxRuntime from "react/jsx-runtime";
|
|
7
7
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
8
|
-
import { ALL_CAPABILITY_DEFINITIONS, CAM_PROFILE_ORDER, CLIP_STILL_DISPOSITION_HEADER, CLIP_STILL_REASON_CODE_HEADER, CLIP_STILL_REASON_HEADER, COMPOSER_ADDON_ID, CONTAINER_CHILD_PRIORITY, ConsumableLevelSchema, DEFAULT_DISPLAY_PREFERENCE, DEFAULT_EVENTS_BAND_BUFFER_SEC, DEVICE_HISTORY_ENERGY_KEY, DEVICE_HISTORY_QUERY_MANY_MAX_ITEMS, DEVICE_TYPE_CONTROL_KIND, DISPLAY_PREFERENCES, DeviceExportStatusSchema, DeviceFeature, DeviceRole, DeviceType, EXTENSION_SLOTS, EXTENSION_SLOT_IDS, EventCategory, ExportEntityKindSchema, ExposedDeviceSchema, ExposedEntitySchema, FIRST_LEVEL_MACRO_CLASSES, HISTORY_CATALOG, ICON_CATEGORIES, KNOWN_CAP_NAMES, MAX_SENSOR_TRIGGER_DEVICES, MODEL_PROVIDER_IDS, NAVIGATION_LIGHT_LEVEL_MAX, NAVIGATION_LIGHT_LEVEL_MIN, NODE_COLOR_IDS, NodeColorIdSchema, PALETTE_ENTRY_IDS, PET_FEEDER_MANUAL_FEED_MAX, PET_FEEDER_MANUAL_FEED_MIN, QUANTITY_BASE, RECORDING_AUDIO_TRIGGER_OFFERED_DBFS, RECORDING_SOURCE_CAMSTACK_ADDON, REDACTED_SECRET, RecordingConfigSchema, RecordingStatusSchema, SECRET_CLEAR, SOURCE_CAP_ACTIVE_FIELD, STATIONARY_OVERLAY_STYLE, SUBJECT_PATH_DWELL_EPS, SUBJECT_PATH_FULL_FRAME_COVERAGE, SUBJECT_PATH_MAX_POINTS, TIMEZONES, USE_ROOT_MODEL_SETTING_KEY, assignNodeColorId, assignNodeColorId as assignNodeColorId$1, baseUnitForQuantity, baseUnitOf, buildModelVariantGroups, buildSubjectPath, bundledCamstack, canConvertUnit, canonicalIconKey, clearModelBoundOverrides, clearModelBoundSetting, clusterStepSettingFieldsFor, collectModelBoundKeys, consumableFormOf, consumableKindOf, convertQuantityInput, coreBlockComposition, createDeviceProxy, createLazyTrpcSource, createSliceHandle, dehydrateSchema, deriveRecordingMode, describeModelVariant, displayUnitFor, effectiveStepSettings, findTimezone, formatParkedFor, formatReading, hasModelBoundOverrides, iconCategoryLabel, iconsInCategory, isDrawableSubjectPath, isKeychainStoredField, isModelScopedStepSettingKey, isReadingQuantity, isRootSuppliableStepId, isSecretClear, isSecretFieldView, isSecretMarker, lockDoorLinkOfComposition, modelBindingKey, normalizeUnit, paintHex, parseOccupancyScope, projectSubjectPath, publicEventCategories, resolveContainerPrimaryChild, resolveDeviceControlKind, resolveIconKey, resolveModelBoundSetting, resolveRecordingProfiles, resolveRootSupply, resolveVariantModelId, resolveViewableDeviceIds, searchIcons, selectAssignedProfileSlots, stepSettingSource, subjectPathSampleFromBox, subjectPathSvgPoints, tryConvertUnit, unitDimension, unitsForDimension, unitsForQuantity, withFieldFrom, withoutField, writeModelBoundSetting } from "@camstack/types";
|
|
8
|
+
import { ALL_CAPABILITY_DEFINITIONS, CAM_PROFILE_ORDER, CLIP_STILL_DISPOSITION_HEADER, CLIP_STILL_REASON_CODE_HEADER, CLIP_STILL_REASON_HEADER, COMPOSER_ADDON_ID, CONTAINER_CHILD_PRIORITY, ConsumableLevelSchema, DEFAULT_DISPLAY_PREFERENCE, DEFAULT_EVENTS_BAND_BUFFER_SEC, DEVICE_HISTORY_ENERGY_KEY, DEVICE_HISTORY_QUERY_MANY_MAX_ITEMS, DEVICE_TYPE_CONTROL_KIND, DISPLAY_PREFERENCES, DeviceExportStatusSchema, DeviceFeature, DeviceRole, DeviceType, EXTENSION_SLOTS, EXTENSION_SLOT_IDS, EventCategory, ExportEntityKindSchema, ExposedDeviceSchema, ExposedEntitySchema, FIRST_LEVEL_MACRO_CLASSES, HISTORY_CATALOG, ICON_CATEGORIES, KNOWN_CAP_NAMES, MAX_SENSOR_TRIGGER_DEVICES, MODEL_PROVIDER_IDS, NAVIGATION_LIGHT_LEVEL_MAX, NAVIGATION_LIGHT_LEVEL_MIN, NODE_COLOR_IDS, NodeColorIdSchema, PALETTE_ENTRY_IDS, PET_FEEDER_MANUAL_FEED_MAX, PET_FEEDER_MANUAL_FEED_MIN, QUANTITY_BASE, RECORDING_AUDIO_TRIGGER_OFFERED_DBFS, RECORDING_SOURCE_CAMSTACK_ADDON, REDACTED_SECRET, RecordingConfigSchema, RecordingStatusSchema, SECRET_CLEAR, SOURCE_CAP_ACTIVE_FIELD, STATIONARY_OVERLAY_STYLE, SUBJECT_PATH_DWELL_EPS, SUBJECT_PATH_FULL_FRAME_COVERAGE, SUBJECT_PATH_MAX_POINTS, TIMED_RUN_LIMITS, TIMEZONES, USE_ROOT_MODEL_SETTING_KEY, assignNodeColorId, assignNodeColorId as assignNodeColorId$1, baseUnitForQuantity, baseUnitOf, buildModelVariantGroups, buildSubjectPath, bundledCamstack, canConvertUnit, canonicalIconKey, clearModelBoundOverrides, clearModelBoundSetting, clusterStepSettingFieldsFor, collectModelBoundKeys, consumableFormOf, consumableKindOf, convertQuantityInput, coreBlockComposition, createDeviceProxy, createLazyTrpcSource, createSliceHandle, dehydrateSchema, deriveRecordingMode, describeModelVariant, displayUnitFor, effectiveStepSettings, findTimezone, formatParkedFor, formatReading, hasModelBoundOverrides, iconCategoryLabel, iconsInCategory, isDrawableSubjectPath, isKeychainStoredField, isModelScopedStepSettingKey, isReadingQuantity, isRootSuppliableStepId, isSecretClear, isSecretFieldView, isSecretMarker, lockDoorLinkOfComposition, modelBindingKey, normalizeUnit, paintHex, parseOccupancyScope, projectSubjectPath, publicEventCategories, resolveContainerPrimaryChild, resolveDeviceControlKind, resolveIconKey, resolveModelBoundSetting, resolveRecordingProfiles, resolveRootSupply, resolveVariantModelId, resolveViewableDeviceIds, searchIcons, selectAssignedProfileSlots, stepSettingSource, subjectPathSampleFromBox, subjectPathSvgPoints, tryConvertUnit, unitDimension, unitsForDimension, unitsForQuantity, withFieldFrom, withoutField, writeModelBoundSetting } from "@camstack/types";
|
|
9
9
|
import * as __mfHostTrpcReactQuery from "@trpc/react-query";
|
|
10
10
|
import { createTRPCReact } from "@trpc/react-query";
|
|
11
11
|
import * as __mfHostReactDOM from "react-dom";
|
|
@@ -4260,6 +4260,34 @@ var Thermometer = createLucideIcon("thermometer", [["path", {
|
|
|
4260
4260
|
* This source code is licensed under the ISC license.
|
|
4261
4261
|
* See the LICENSE file in the root directory of this source tree.
|
|
4262
4262
|
*/
|
|
4263
|
+
var TimerOff = createLucideIcon("timer-off", [
|
|
4264
|
+
["path", {
|
|
4265
|
+
d: "M10 2h4",
|
|
4266
|
+
key: "n1abiw"
|
|
4267
|
+
}],
|
|
4268
|
+
["path", {
|
|
4269
|
+
d: "M4.6 11a8 8 0 0 0 1.7 8.7 8 8 0 0 0 8.7 1.7",
|
|
4270
|
+
key: "10he05"
|
|
4271
|
+
}],
|
|
4272
|
+
["path", {
|
|
4273
|
+
d: "M7.4 7.4a8 8 0 0 1 10.3 1 8 8 0 0 1 .9 10.2",
|
|
4274
|
+
key: "15f7sh"
|
|
4275
|
+
}],
|
|
4276
|
+
["path", {
|
|
4277
|
+
d: "m2 2 20 20",
|
|
4278
|
+
key: "1ooewy"
|
|
4279
|
+
}],
|
|
4280
|
+
["path", {
|
|
4281
|
+
d: "M12 12v-2",
|
|
4282
|
+
key: "fwoke6"
|
|
4283
|
+
}]
|
|
4284
|
+
]);
|
|
4285
|
+
/**
|
|
4286
|
+
* @license lucide-react v0.576.0 - ISC
|
|
4287
|
+
*
|
|
4288
|
+
* This source code is licensed under the ISC license.
|
|
4289
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
4290
|
+
*/
|
|
4263
4291
|
var Timer = createLucideIcon("timer", [
|
|
4264
4292
|
["line", {
|
|
4265
4293
|
x1: "10",
|
|
@@ -5432,6 +5460,11 @@ var DEVICE_TYPE_META = {
|
|
|
5432
5460
|
labelKey: "uiLibrary.deviceMeta.type.petFountain",
|
|
5433
5461
|
labelFallback: "Pet fountain"
|
|
5434
5462
|
},
|
|
5463
|
+
[DeviceType.Heater]: {
|
|
5464
|
+
icon: Flame,
|
|
5465
|
+
labelKey: "uiLibrary.deviceMeta.type.heater",
|
|
5466
|
+
labelFallback: "Heater"
|
|
5467
|
+
},
|
|
5435
5468
|
[DeviceType.Dishwasher]: {
|
|
5436
5469
|
icon: Waves,
|
|
5437
5470
|
labelKey: "uiLibrary.deviceMeta.type.dishwasher",
|
|
@@ -5937,7 +5970,7 @@ function lucideExportName(key) {
|
|
|
5937
5970
|
function loadIconGlyphs() {
|
|
5938
5971
|
if (fullTable !== void 0) return Promise.resolve();
|
|
5939
5972
|
if (failure$1 !== void 0) return Promise.reject(failure$1);
|
|
5940
|
-
pending ??= import("./icons-
|
|
5973
|
+
pending ??= import("./icons-e-xohmFb.js").then((module) => {
|
|
5941
5974
|
fullTable = module;
|
|
5942
5975
|
publish();
|
|
5943
5976
|
}, (error) => {
|
|
@@ -11502,6 +11535,14 @@ var useFanControlSetDirection = /*#__PURE__*/ alias(() => trpc.fanControl.setDir
|
|
|
11502
11535
|
var useFanControlSetOscillating = /*#__PURE__*/ alias(() => trpc.fanControl.setOscillating.useMutation);
|
|
11503
11536
|
/** Generated alias around `trpc.fanControl.getStatus.useQuery`. */
|
|
11504
11537
|
var useFanControlGetStatus = /*#__PURE__*/ alias(() => trpc.fanControl.getStatus.useQuery);
|
|
11538
|
+
/** Generated alias around `trpc.fanPresets.getPresets.useQuery`. */
|
|
11539
|
+
var useFanPresetsGetPresets = /*#__PURE__*/ alias(() => trpc.fanPresets.getPresets.useQuery);
|
|
11540
|
+
/** Generated alias around `trpc.fanPresets.setPresets.useMutation`. */
|
|
11541
|
+
var useFanPresetsSetPresets = /*#__PURE__*/ alias(() => trpc.fanPresets.setPresets.useMutation);
|
|
11542
|
+
/** Generated alias around `trpc.fanPresets.applyPreset.useMutation`. */
|
|
11543
|
+
var useFanPresetsApplyPreset = /*#__PURE__*/ alias(() => trpc.fanPresets.applyPreset.useMutation);
|
|
11544
|
+
/** Generated alias around `trpc.fanPresets.capturePreset.useQuery`. */
|
|
11545
|
+
var useFanPresetsCapturePreset = /*#__PURE__*/ alias(() => trpc.fanPresets.capturePreset.useQuery);
|
|
11505
11546
|
/** Generated alias around `trpc.featureProbe.getStatus.useQuery`. */
|
|
11506
11547
|
var useFeatureProbeGetStatus = /*#__PURE__*/ alias(() => trpc.featureProbe.getStatus.useQuery);
|
|
11507
11548
|
/** Generated alias around `trpc.flood.getStatus.useQuery`. */
|
|
@@ -13032,6 +13073,12 @@ var useTerminalSessionPullOutput = /*#__PURE__*/ alias(() => trpc.terminalSessio
|
|
|
13032
13073
|
var useTerminalSessionWriteInput = /*#__PURE__*/ alias(() => trpc.terminalSession.writeInput.useMutation);
|
|
13033
13074
|
/** Generated alias around `trpc.terminalSession.close.useMutation`. */
|
|
13034
13075
|
var useTerminalSessionClose = /*#__PURE__*/ alias(() => trpc.terminalSession.close.useMutation);
|
|
13076
|
+
/** Generated alias around `trpc.timedRun.runFor.useMutation`. */
|
|
13077
|
+
var useTimedRunRunFor = /*#__PURE__*/ alias(() => trpc.timedRun.runFor.useMutation);
|
|
13078
|
+
/** Generated alias around `trpc.timedRun.cancel.useMutation`. */
|
|
13079
|
+
var useTimedRunCancel = /*#__PURE__*/ alias(() => trpc.timedRun.cancel.useMutation);
|
|
13080
|
+
/** Generated alias around `trpc.timedRun.getStatus.useQuery`. */
|
|
13081
|
+
var useTimedRunGetStatus = /*#__PURE__*/ alias(() => trpc.timedRun.getStatus.useQuery);
|
|
13035
13082
|
/** Generated alias around `trpc.toast.onToast.useSubscription`. */
|
|
13036
13083
|
var useToastOnToast = /*#__PURE__*/ alias(() => trpc.toast.onToast.useSubscription);
|
|
13037
13084
|
/** Generated alias around `trpc.training.listBaseModels.useQuery`. */
|
|
@@ -30560,8 +30607,8 @@ function RecordingPanel({ deviceId }) {
|
|
|
30560
30607
|
* `type:'widget'` ConfigField. `WidgetSlot` resolves these BEFORE the
|
|
30561
30608
|
* Module-Federation `WidgetRegistry`. ids are namespaced `host/<name>`. */
|
|
30562
30609
|
var HOST_WIDGETS = {
|
|
30563
|
-
"host/motion-zones-grid": lazy(() => import("./MotionZonesSettings-
|
|
30564
|
-
"host/privacy-mask-grid": lazy(() => import("./PrivacyMaskSettings-
|
|
30610
|
+
"host/motion-zones-grid": lazy(() => import("./MotionZonesSettings-Zcfa5c9l.js").then((m) => ({ default: m.MotionZonesSettings }))),
|
|
30611
|
+
"host/privacy-mask-grid": lazy(() => import("./PrivacyMaskSettings-B_X42yzN.js").then((m) => ({ default: m.PrivacyMaskSettings }))),
|
|
30565
30612
|
"host/ptz-panel": PtzPanel,
|
|
30566
30613
|
"host/navigation-panel": NavigationPanel,
|
|
30567
30614
|
"host/consumables-panel": ConsumablesPanel,
|
|
@@ -54120,6 +54167,137 @@ function PetFeederHeroCard({ trpc, deviceId, features, optimistic }) {
|
|
|
54120
54167
|
});
|
|
54121
54168
|
}
|
|
54122
54169
|
//#endregion
|
|
54170
|
+
//#region src/composites/device-controls/timed-run-control.tsx
|
|
54171
|
+
/**
|
|
54172
|
+
* "Run for N" - the inline control of the `timed-run` cap (D993).
|
|
54173
|
+
*
|
|
54174
|
+
* A number, the unit it is in, and a Run button: the hub turns the device on and
|
|
54175
|
+
* switches it off again after that long. While a run is armed the control shows
|
|
54176
|
+
* the time left (counted down from the slice's `activeUntil`) and a Cancel. The
|
|
54177
|
+
* maximum is the device type's own bound (`TIMED_RUN_LIMITS`); a value above it
|
|
54178
|
+
* is refused by the hub with a typed reason, which this control says in words.
|
|
54179
|
+
*
|
|
54180
|
+
* Rendered only when the device binds `timed-run`. An unknown slice is "nothing
|
|
54181
|
+
* armed", never a running timer.
|
|
54182
|
+
*/
|
|
54183
|
+
var TICK_MS = 1e3;
|
|
54184
|
+
var SECONDS_PER_MINUTE$1 = 60;
|
|
54185
|
+
var MS_PER_SECOND = 1e3;
|
|
54186
|
+
var DEFAULT_MINUTES = 30;
|
|
54187
|
+
var DEFAULT_SECONDS = 60;
|
|
54188
|
+
/** `m:ss` for a countdown; a started run never shows a negative time. */
|
|
54189
|
+
function formatCountdown(remainingMs) {
|
|
54190
|
+
const total = Math.max(0, Math.ceil(remainingMs / MS_PER_SECOND));
|
|
54191
|
+
const minutes = Math.floor(total / SECONDS_PER_MINUTE$1);
|
|
54192
|
+
const seconds = total % SECONDS_PER_MINUTE$1;
|
|
54193
|
+
return `${minutes}:${String(seconds).padStart(2, "0")}`;
|
|
54194
|
+
}
|
|
54195
|
+
/** The largest value the field accepts, in the limit's unit. */
|
|
54196
|
+
function maxInUnit(limit) {
|
|
54197
|
+
return limit.unit === "min" ? limit.maxSeconds / SECONDS_PER_MINUTE$1 : limit.maxSeconds;
|
|
54198
|
+
}
|
|
54199
|
+
function useNow(active) {
|
|
54200
|
+
const [now, setNow] = useState(() => Date.now());
|
|
54201
|
+
useEffect(() => {
|
|
54202
|
+
if (!active) return void 0;
|
|
54203
|
+
setNow(Date.now());
|
|
54204
|
+
const handle = setInterval(() => setNow(Date.now()), TICK_MS);
|
|
54205
|
+
return () => clearInterval(handle);
|
|
54206
|
+
}, [active]);
|
|
54207
|
+
return now;
|
|
54208
|
+
}
|
|
54209
|
+
function TimedRunControl({ trpc, deviceId, limit }) {
|
|
54210
|
+
const t = useUiText();
|
|
54211
|
+
const { cap, slice, online } = useDeviceCapability({
|
|
54212
|
+
trpc,
|
|
54213
|
+
deviceId,
|
|
54214
|
+
cap: (d) => d.timedRun,
|
|
54215
|
+
slice: (d) => d.state.timedRun
|
|
54216
|
+
});
|
|
54217
|
+
const max = maxInUnit(limit);
|
|
54218
|
+
const [draft, setDraft] = useState(Math.min(max, limit.unit === "min" ? DEFAULT_MINUTES : DEFAULT_SECONDS));
|
|
54219
|
+
const [refusal, setRefusal] = useState(null);
|
|
54220
|
+
const activeUntil = slice?.activeUntil ?? null;
|
|
54221
|
+
const now = useNow(activeUntil !== null);
|
|
54222
|
+
if (cap === void 0) return null;
|
|
54223
|
+
const unitLabel = limit.unit === "min" ? t("uiLibrary.timedRun.minutes", "min") : t("uiLibrary.timedRun.seconds", "s");
|
|
54224
|
+
const valid = Number.isFinite(draft) && draft > 0 && draft <= max;
|
|
54225
|
+
const armed = activeUntil !== null && activeUntil > now;
|
|
54226
|
+
const run = () => {
|
|
54227
|
+
if (!valid) return;
|
|
54228
|
+
setRefusal(null);
|
|
54229
|
+
cap.runFor({
|
|
54230
|
+
duration: draft,
|
|
54231
|
+
unit: limit.unit
|
|
54232
|
+
}).then((result) => {
|
|
54233
|
+
if (!result.ok) setRefusal(result.reason);
|
|
54234
|
+
});
|
|
54235
|
+
};
|
|
54236
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
54237
|
+
className: "flex flex-col gap-1.5",
|
|
54238
|
+
"data-testid": "timed-run-control",
|
|
54239
|
+
children: [
|
|
54240
|
+
/* @__PURE__ */ jsxs("div", {
|
|
54241
|
+
className: "flex items-center gap-2",
|
|
54242
|
+
children: [
|
|
54243
|
+
/* @__PURE__ */ jsx(Input, {
|
|
54244
|
+
type: "number",
|
|
54245
|
+
inputMode: "numeric",
|
|
54246
|
+
min: 1,
|
|
54247
|
+
max,
|
|
54248
|
+
step: 1,
|
|
54249
|
+
value: Number.isFinite(draft) ? draft : "",
|
|
54250
|
+
disabled: !online,
|
|
54251
|
+
"aria-label": t("uiLibrary.timedRun.duration", "Run for"),
|
|
54252
|
+
className: "w-20 tabular-nums",
|
|
54253
|
+
onChange: (event) => setDraft(event.target.valueAsNumber)
|
|
54254
|
+
}),
|
|
54255
|
+
/* @__PURE__ */ jsx("span", {
|
|
54256
|
+
className: "text-xs text-foreground-muted",
|
|
54257
|
+
children: unitLabel
|
|
54258
|
+
}),
|
|
54259
|
+
/* @__PURE__ */ jsxs(Button, {
|
|
54260
|
+
size: "sm",
|
|
54261
|
+
disabled: !online || !valid,
|
|
54262
|
+
onClick: run,
|
|
54263
|
+
children: [/* @__PURE__ */ jsx(Timer, {
|
|
54264
|
+
className: "h-4 w-4",
|
|
54265
|
+
"aria-hidden": true
|
|
54266
|
+
}), t("uiLibrary.timedRun.run", "Run")]
|
|
54267
|
+
}),
|
|
54268
|
+
armed && /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("span", {
|
|
54269
|
+
className: "text-xs font-medium tabular-nums text-foreground",
|
|
54270
|
+
"data-testid": "timed-run-countdown",
|
|
54271
|
+
children: t("uiLibrary.timedRun.remaining", "{{time}} left", { time: formatCountdown(activeUntil - now) })
|
|
54272
|
+
}), /* @__PURE__ */ jsx(Button, {
|
|
54273
|
+
size: "sm",
|
|
54274
|
+
variant: "outline",
|
|
54275
|
+
disabled: !online,
|
|
54276
|
+
"aria-label": t("uiLibrary.timedRun.cancel", "Cancel the timer"),
|
|
54277
|
+
onClick: () => void cap.cancel({}),
|
|
54278
|
+
children: /* @__PURE__ */ jsx(TimerOff, {
|
|
54279
|
+
className: "h-4 w-4",
|
|
54280
|
+
"aria-hidden": true
|
|
54281
|
+
})
|
|
54282
|
+
})] })
|
|
54283
|
+
]
|
|
54284
|
+
}),
|
|
54285
|
+
!valid && /* @__PURE__ */ jsx("span", {
|
|
54286
|
+
className: "text-xs text-danger",
|
|
54287
|
+
children: t("uiLibrary.timedRun.range", "Enter 1 to {{max}} {{unit}}", {
|
|
54288
|
+
max,
|
|
54289
|
+
unit: unitLabel
|
|
54290
|
+
})
|
|
54291
|
+
}),
|
|
54292
|
+
refusal !== null && /* @__PURE__ */ jsx("span", {
|
|
54293
|
+
className: "text-xs text-danger",
|
|
54294
|
+
role: "alert",
|
|
54295
|
+
children: refusal === "over-max" ? t("uiLibrary.timedRun.overMax", "That is longer than this device may run.") : refusal === "command-failed" ? t("uiLibrary.timedRun.commandFailed", "The device did not turn on.") : t("uiLibrary.timedRun.unsupported", "This device cannot run on a timer.")
|
|
54296
|
+
})
|
|
54297
|
+
]
|
|
54298
|
+
});
|
|
54299
|
+
}
|
|
54300
|
+
//#endregion
|
|
54123
54301
|
//#region src/composites/device-controls/pet-fountain-panel.tsx
|
|
54124
54302
|
/**
|
|
54125
54303
|
* Pet-fountain controls for a `DeviceType.PetFountain` device.
|
|
@@ -54148,6 +54326,7 @@ var KEYFRAMES$2 = `
|
|
|
54148
54326
|
.pfn-ripple, .pfn-bubble { animation: none !important; opacity: 0; }
|
|
54149
54327
|
}
|
|
54150
54328
|
`;
|
|
54329
|
+
var PUMP_LIMIT = TIMED_RUN_LIMITS[DeviceType.PetFountain];
|
|
54151
54330
|
var LITRES_TO_ML = 1e3;
|
|
54152
54331
|
var SECONDS_PER_MINUTE = 60;
|
|
54153
54332
|
var MAX_PUMP_MINUTES = 240;
|
|
@@ -54312,6 +54491,11 @@ function PetFountainPanel({ trpc, deviceId, layout, optimistic }) {
|
|
|
54312
54491
|
]
|
|
54313
54492
|
})
|
|
54314
54493
|
}),
|
|
54494
|
+
PUMP_LIMIT !== void 0 && /* @__PURE__ */ jsx(TimedRunControl, {
|
|
54495
|
+
trpc,
|
|
54496
|
+
deviceId,
|
|
54497
|
+
limit: PUMP_LIMIT
|
|
54498
|
+
}),
|
|
54315
54499
|
/* @__PURE__ */ jsxs(Button, {
|
|
54316
54500
|
variant: "outline",
|
|
54317
54501
|
size: "sm",
|
|
@@ -54536,795 +54720,215 @@ function PetFountainHeroCard({ trpc, deviceId, features, optimistic }) {
|
|
|
54536
54720
|
});
|
|
54537
54721
|
}
|
|
54538
54722
|
//#endregion
|
|
54539
|
-
//#region src/composites/device-controls/
|
|
54540
|
-
/**
|
|
54541
|
-
|
|
54542
|
-
|
|
54543
|
-
|
|
54544
|
-
|
|
54545
|
-
|
|
54546
|
-
|
|
54547
|
-
|
|
54548
|
-
|
|
54549
|
-
|
|
54550
|
-
* reported, and this view renders that as "—" / a disabled control, never as an unchecked
|
|
54551
|
-
* box or a zero. It also does not echo a command before the appliance confirms it: the
|
|
54552
|
-
* slice moves when the appliance says so.
|
|
54553
|
-
*/
|
|
54554
|
-
/** What the operation state is called to a person, and how it is toned. */
|
|
54555
|
-
function dishwasherOperationMeta(operationState, t = defaultUiText) {
|
|
54556
|
-
switch (operationState) {
|
|
54557
|
-
case "Run": return {
|
|
54558
|
-
label: t("uiLibrary.dishwasher.op.run", "Running"),
|
|
54559
|
-
tone: "text-primary"
|
|
54560
|
-
};
|
|
54561
|
-
case "Pause": return {
|
|
54562
|
-
label: t("uiLibrary.dishwasher.op.pause", "Paused"),
|
|
54563
|
-
tone: "text-warning"
|
|
54564
|
-
};
|
|
54565
|
-
case "Finished": return {
|
|
54566
|
-
label: t("uiLibrary.dishwasher.op.finished", "Finished"),
|
|
54567
|
-
tone: "text-success"
|
|
54568
|
-
};
|
|
54569
|
-
case "Error": return {
|
|
54570
|
-
label: t("uiLibrary.dishwasher.op.error", "Error"),
|
|
54571
|
-
tone: "text-danger"
|
|
54572
|
-
};
|
|
54573
|
-
case "Aborting": return {
|
|
54574
|
-
label: t("uiLibrary.dishwasher.op.aborting", "Stopping"),
|
|
54575
|
-
tone: "text-warning"
|
|
54576
|
-
};
|
|
54577
|
-
case "ActionRequired": return {
|
|
54578
|
-
label: t("uiLibrary.dishwasher.op.actionRequired", "Action required"),
|
|
54579
|
-
tone: "text-warning"
|
|
54580
|
-
};
|
|
54581
|
-
case "DelayedStart": return {
|
|
54582
|
-
label: t("uiLibrary.dishwasher.op.delayedStart", "Delayed start"),
|
|
54583
|
-
tone: "text-primary"
|
|
54584
|
-
};
|
|
54585
|
-
case "Ready": return {
|
|
54586
|
-
label: t("uiLibrary.dishwasher.op.ready", "Ready"),
|
|
54587
|
-
tone: "text-foreground"
|
|
54588
|
-
};
|
|
54589
|
-
case "Inactive": return {
|
|
54590
|
-
label: t("uiLibrary.dishwasher.op.inactive", "Inactive"),
|
|
54591
|
-
tone: "text-foreground-subtle"
|
|
54592
|
-
};
|
|
54593
|
-
case null: return {
|
|
54594
|
-
label: t("uiLibrary.dishwasher.unknown", "Unknown"),
|
|
54595
|
-
tone: "text-foreground-subtle"
|
|
54596
|
-
};
|
|
54597
|
-
}
|
|
54723
|
+
//#region src/composites/device-controls/ac-panel.tsx
|
|
54724
|
+
/** Modes that mean the device can cool, dry, or move air — an air conditioner. */
|
|
54725
|
+
var COOLING_MODES = new Set([
|
|
54726
|
+
"cool",
|
|
54727
|
+
"heat_cool",
|
|
54728
|
+
"dry",
|
|
54729
|
+
"fan_only"
|
|
54730
|
+
]);
|
|
54731
|
+
/** A heater offers heat (and maybe auto/off) and none of the cooling modes. */
|
|
54732
|
+
function climateOffersCooling(modes) {
|
|
54733
|
+
return modes.some((mode) => COOLING_MODES.has(mode));
|
|
54598
54734
|
}
|
|
54599
|
-
/**
|
|
54600
|
-
function
|
|
54601
|
-
|
|
54602
|
-
|
|
54603
|
-
|
|
54604
|
-
|
|
54605
|
-
|
|
54606
|
-
|
|
54607
|
-
|
|
54608
|
-
|
|
54609
|
-
|
|
54610
|
-
|
|
54735
|
+
/** Setpoint track bounds. Absent when the integration did not report both ends. */
|
|
54736
|
+
function climateSetpointBounds(status) {
|
|
54737
|
+
const min = status.minTemp;
|
|
54738
|
+
const max = status.maxTemp;
|
|
54739
|
+
if (typeof min !== "number" || typeof max !== "number") return null;
|
|
54740
|
+
if (!Number.isFinite(min) || !Number.isFinite(max) || max <= min) return null;
|
|
54741
|
+
return {
|
|
54742
|
+
min,
|
|
54743
|
+
max
|
|
54744
|
+
};
|
|
54745
|
+
}
|
|
54746
|
+
/** Map a 0–1 drag fraction onto the setpoint, snapped to `tempStep`. */
|
|
54747
|
+
function climateTargetFromFraction(fraction, bounds, tempStep) {
|
|
54748
|
+
const step = resolveClimateTempStep(tempStep);
|
|
54749
|
+
const clamped = Math.min(1, Math.max(0, fraction));
|
|
54750
|
+
const raw = bounds.min + clamped * (bounds.max - bounds.min);
|
|
54751
|
+
const steps = Math.round((raw - bounds.min) / step);
|
|
54752
|
+
const snapped = bounds.min + steps * step;
|
|
54753
|
+
const rounded = Math.round(snapped * 1e3) / 1e3;
|
|
54754
|
+
return Math.min(bounds.max, Math.max(bounds.min, rounded));
|
|
54755
|
+
}
|
|
54756
|
+
/** AC-appropriate short mode labels. Exhaustive over HvacMode. */
|
|
54757
|
+
function modeLabel(t, mode) {
|
|
54758
|
+
switch (mode) {
|
|
54759
|
+
case "cool": return t("uiLibrary.acPanel.modeCool", "Cool");
|
|
54760
|
+
case "heat": return t("uiLibrary.acPanel.modeHeat", "Heat");
|
|
54761
|
+
case "auto": return t("uiLibrary.acPanel.modeAuto", "Auto");
|
|
54762
|
+
case "heat_cool": return t("uiLibrary.acPanel.modeHeatCool", "Heat·Cool");
|
|
54763
|
+
case "fan_only": return t("uiLibrary.acPanel.modeFan", "Fan");
|
|
54764
|
+
case "dry": return t("uiLibrary.acPanel.modeDry", "Dry");
|
|
54765
|
+
case "off": return t("uiLibrary.acPanel.modeOff", "Off");
|
|
54611
54766
|
}
|
|
54612
54767
|
}
|
|
54613
|
-
/**
|
|
54614
|
-
|
|
54615
|
-
|
|
54768
|
+
/** Per-mode icon (lucide). Exhaustive over HvacMode. */
|
|
54769
|
+
var MODE_ICON = {
|
|
54770
|
+
cool: Snowflake,
|
|
54771
|
+
heat: Flame,
|
|
54772
|
+
auto: Sparkles,
|
|
54773
|
+
heat_cool: Thermometer,
|
|
54774
|
+
fan_only: Fan,
|
|
54775
|
+
dry: Droplets,
|
|
54776
|
+
off: Power
|
|
54777
|
+
};
|
|
54778
|
+
/** Mode accent hex — drives the airflow particles, the glow, and the target
|
|
54779
|
+
* value colour. Mirrors the thermostat gauge palette. Exhaustive. */
|
|
54780
|
+
var MODE_ACCENT = {
|
|
54781
|
+
heat: "#f59e0b",
|
|
54782
|
+
cool: "#60a5fa",
|
|
54783
|
+
auto: "#c084fc",
|
|
54784
|
+
heat_cool: "#e879f9",
|
|
54785
|
+
fan_only: "#94a3b8",
|
|
54786
|
+
dry: "#22d3ee",
|
|
54787
|
+
off: "#a1a1aa"
|
|
54788
|
+
};
|
|
54789
|
+
/** Title-case a snake/lower token for a selector option ('medium_low' → 'Medium
|
|
54790
|
+
* low', 'turbo' → 'Turbo'). Shared by the fan + preset selectors. */
|
|
54791
|
+
function fanLabel(token) {
|
|
54792
|
+
const spaced = token.replace(/_/g, " ");
|
|
54793
|
+
return spaced.charAt(0).toUpperCase() + spaced.slice(1);
|
|
54794
|
+
}
|
|
54795
|
+
/** Preset → icon. Unknown presets fall back to a neutral sparkle. */
|
|
54796
|
+
function presetIcon(preset) {
|
|
54797
|
+
switch (preset) {
|
|
54798
|
+
case "turbo": return Zap;
|
|
54799
|
+
case "quiet": return Feather;
|
|
54800
|
+
case "sleep": return Moon;
|
|
54801
|
+
case "eco": return Leaf;
|
|
54802
|
+
case "8c_heat": return Snowflake;
|
|
54803
|
+
case "none": return Ban;
|
|
54804
|
+
default: return Sparkles;
|
|
54805
|
+
}
|
|
54616
54806
|
}
|
|
54617
54807
|
/**
|
|
54618
|
-
*
|
|
54619
|
-
*
|
|
54808
|
+
* Fan level → airflow animation period. Higher speed ⇒ shorter period. Unknown
|
|
54809
|
+
* strings fall back to a medium pace. Turbo (a preset) shortens it further.
|
|
54620
54810
|
*/
|
|
54621
|
-
function
|
|
54622
|
-
|
|
54623
|
-
|
|
54624
|
-
|
|
54625
|
-
|
|
54626
|
-
|
|
54627
|
-
|
|
54811
|
+
function airflowPeriodSec(fanMode) {
|
|
54812
|
+
switch (fanMode) {
|
|
54813
|
+
case "high": return 1;
|
|
54814
|
+
case "medium_high": return 1.3;
|
|
54815
|
+
case "medium": return 1.6;
|
|
54816
|
+
case "medium_low": return 1.9;
|
|
54817
|
+
case "low": return 2.2;
|
|
54818
|
+
default: return 1.8;
|
|
54819
|
+
}
|
|
54628
54820
|
}
|
|
54629
|
-
|
|
54630
|
-
|
|
54631
|
-
|
|
54632
|
-
|
|
54633
|
-
|
|
54634
|
-
|
|
54635
|
-
|
|
54636
|
-
|
|
54637
|
-
|
|
54638
|
-
|
|
54639
|
-
});
|
|
54821
|
+
var KEYFRAMES$1 = `
|
|
54822
|
+
@keyframes acv-fall { 0%{transform:translateY(-1.75rem);opacity:0} 18%{opacity:.7} 82%{opacity:.7} 100%{transform:translateY(7.5rem);opacity:0} }
|
|
54823
|
+
@keyframes acv-rise { 0%{transform:translateY(7.5rem);opacity:0} 18%{opacity:.7} 82%{opacity:.7} 100%{transform:translateY(-1.75rem);opacity:0} }
|
|
54824
|
+
@keyframes acv-sway { 0%,100%{transform:translateX(-9%)} 50%{transform:translateX(9%)} }
|
|
54825
|
+
@keyframes acv-swing-h { 0%,100%{transform:translateX(-22%)} 50%{transform:translateX(22%)} }
|
|
54826
|
+
@keyframes acv-swing-v { 0%,100%{transform:translateY(-22%)} 50%{transform:translateY(22%)} }
|
|
54827
|
+
@keyframes acv-spin { to { transform:rotate(360deg) } }
|
|
54828
|
+
@keyframes acv-glow { 0%,100%{opacity:.35;transform:scale(1)} 50%{opacity:.6;transform:scale(1.06)} }
|
|
54829
|
+
@media (prefers-reduced-motion: reduce) {
|
|
54830
|
+
.acv-streak, .acv-fan, .acv-sway-wrap, .acv-glow, .acv-swing { animation: none !important; }
|
|
54640
54831
|
}
|
|
54641
|
-
|
|
54642
|
-
|
|
54832
|
+
`;
|
|
54833
|
+
function AcPanel({ trpc, deviceId, layout, optimistic }) {
|
|
54834
|
+
const t = useUiText();
|
|
54835
|
+
const { cap, slice, available } = useDeviceCapability({
|
|
54643
54836
|
trpc,
|
|
54644
54837
|
deviceId,
|
|
54645
|
-
cap: (d) => d.
|
|
54646
|
-
slice: (d) => d.state.
|
|
54647
|
-
});
|
|
54648
|
-
}
|
|
54649
|
-
function DishwasherIconButton({ label, busy, active, onClick, children }) {
|
|
54650
|
-
return /* @__PURE__ */ jsx("button", {
|
|
54651
|
-
type: "button",
|
|
54652
|
-
"aria-label": label,
|
|
54653
|
-
title: label,
|
|
54654
|
-
disabled: busy,
|
|
54655
|
-
onClick: (e) => {
|
|
54656
|
-
e.stopPropagation();
|
|
54657
|
-
onClick();
|
|
54658
|
-
},
|
|
54659
|
-
className: cn("inline-flex h-5 w-5 items-center justify-center rounded text-foreground-subtle hover:text-foreground hover:bg-surface-hover transition-colors", active && "bg-primary text-primary-foreground", busy && "opacity-40 cursor-not-allowed"),
|
|
54660
|
-
children
|
|
54661
|
-
});
|
|
54662
|
-
}
|
|
54663
|
-
function DishwasherGraphic({ running, progressPercent }) {
|
|
54664
|
-
const pct = progressPercent != null ? Math.max(0, Math.min(100, progressPercent)) : running ? 40 : 0;
|
|
54665
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
54666
|
-
"aria-hidden": "true",
|
|
54667
|
-
className: "relative w-28 h-36 rounded border-2 border-border bg-gradient-to-b from-surface-hover to-surface overflow-hidden flex-shrink-0",
|
|
54668
|
-
children: [/* @__PURE__ */ jsx("div", {
|
|
54669
|
-
className: cn("absolute inset-x-0 bottom-0 bg-primary/25 transition-[height] duration-500", running && "animate-pulse"),
|
|
54670
|
-
style: { height: `${pct}%` }
|
|
54671
|
-
}), /* @__PURE__ */ jsx("div", {
|
|
54672
|
-
className: "absolute inset-0 flex items-center justify-center text-foreground-subtle",
|
|
54673
|
-
children: /* @__PURE__ */ jsx(Waves, { className: "h-10 w-10 opacity-70" })
|
|
54674
|
-
})]
|
|
54838
|
+
cap: (d) => d.climateControl,
|
|
54839
|
+
slice: (d) => d.state.climateControl
|
|
54675
54840
|
});
|
|
54676
|
-
}
|
|
54677
|
-
function DishwasherPanel({ trpc, deviceId, layout }) {
|
|
54678
|
-
const t = useUiText();
|
|
54679
|
-
const { cap, slice, available } = useDishwasher(trpc, deviceId);
|
|
54841
|
+
const { display, applyOptimistic } = useOptimisticSlice(slice, { enabled: optimistic ?? true });
|
|
54680
54842
|
if (cap === void 0) return null;
|
|
54681
|
-
if (
|
|
54682
|
-
const
|
|
54683
|
-
const link = display.availability === "available";
|
|
54684
|
-
const busy = !available || !link;
|
|
54685
|
-
const optionTogglesLocked = display.childLock === true;
|
|
54686
|
-
const meta = dishwasherHeadline(display, t);
|
|
54687
|
-
const running = display.operationState === "Run";
|
|
54688
|
-
const paused = display.operationState === "Pause";
|
|
54689
|
-
const startable = display.remoteStartAllowed === true && display.selectedProgram !== null;
|
|
54690
|
-
const press = (fn) => {
|
|
54691
|
-
if (busy) return;
|
|
54692
|
-
fn();
|
|
54693
|
-
};
|
|
54843
|
+
if (display === void 0) return null;
|
|
54844
|
+
const busy = !available;
|
|
54694
54845
|
if (layout === "compact") return /* @__PURE__ */ jsxs("div", {
|
|
54695
|
-
|
|
54846
|
+
"data-mode": display.mode,
|
|
54847
|
+
className: "inline-flex items-center gap-1",
|
|
54696
54848
|
children: [
|
|
54697
|
-
display.doorOpen === true && /* @__PURE__ */ jsx("span", {
|
|
54698
|
-
className: "inline-flex text-warning shrink-0",
|
|
54699
|
-
title: t("uiLibrary.dishwasher.doorOpen", "Door open"),
|
|
54700
|
-
"aria-label": t("uiLibrary.dishwasher.doorOpen", "Door open"),
|
|
54701
|
-
children: /* @__PURE__ */ jsx(DoorOpen, { className: "h-3.5 w-3.5" })
|
|
54702
|
-
}),
|
|
54703
54849
|
/* @__PURE__ */ jsx("span", {
|
|
54704
|
-
className: cn("text-xs
|
|
54705
|
-
children:
|
|
54706
|
-
|
|
54707
|
-
|
|
54708
|
-
|
|
54709
|
-
|
|
54710
|
-
|
|
54711
|
-
|
|
54712
|
-
|
|
54713
|
-
|
|
54714
|
-
|
|
54715
|
-
|
|
54716
|
-
|
|
54717
|
-
|
|
54718
|
-
|
|
54719
|
-
|
|
54720
|
-
|
|
54721
|
-
children: /* @__PURE__ */ jsx(Play, { className: "h-3 w-3" })
|
|
54850
|
+
className: cn("text-xs tabular-nums font-medium", MODE_TEXT_COLOR[display.mode]),
|
|
54851
|
+
children: display.target !== null ? /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
54852
|
+
display.target,
|
|
54853
|
+
"°",
|
|
54854
|
+
display.currentTemp !== null && /* @__PURE__ */ jsxs("span", {
|
|
54855
|
+
className: "text-foreground-subtle font-normal",
|
|
54856
|
+
children: [
|
|
54857
|
+
" ",
|
|
54858
|
+
"(",
|
|
54859
|
+
display.currentTemp,
|
|
54860
|
+
"°)"
|
|
54861
|
+
]
|
|
54862
|
+
})
|
|
54863
|
+
] }) : display.currentTemp !== null ? /* @__PURE__ */ jsxs("span", {
|
|
54864
|
+
className: "text-foreground-subtle",
|
|
54865
|
+
children: [display.currentTemp, "°"]
|
|
54866
|
+
}) : null
|
|
54722
54867
|
}),
|
|
54723
|
-
/* @__PURE__ */ jsx(
|
|
54724
|
-
|
|
54725
|
-
|
|
54726
|
-
|
|
54727
|
-
onClick: () =>
|
|
54728
|
-
|
|
54868
|
+
display.target !== null && /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("button", {
|
|
54869
|
+
type: "button",
|
|
54870
|
+
"aria-label": t("uiLibrary.acPanel.decrease", "Decrease target"),
|
|
54871
|
+
disabled: busy,
|
|
54872
|
+
onClick: (e) => {
|
|
54873
|
+
e.stopPropagation();
|
|
54874
|
+
if (!busy && display.target !== null) {
|
|
54875
|
+
const next = nextClimateTarget(display.target, -1, display);
|
|
54876
|
+
applyOptimistic({ target: next });
|
|
54877
|
+
cap.setTarget({ target: next });
|
|
54878
|
+
}
|
|
54879
|
+
},
|
|
54880
|
+
className: cn("inline-flex h-5 w-5 items-center justify-center rounded text-foreground-subtle hover:text-foreground hover:bg-surface-hover transition-colors text-xs", busy && "opacity-40 cursor-not-allowed"),
|
|
54881
|
+
children: "−"
|
|
54882
|
+
}), /* @__PURE__ */ jsx("button", {
|
|
54883
|
+
type: "button",
|
|
54884
|
+
"aria-label": t("uiLibrary.acPanel.increase", "Increase target"),
|
|
54885
|
+
disabled: busy,
|
|
54886
|
+
onClick: (e) => {
|
|
54887
|
+
e.stopPropagation();
|
|
54888
|
+
if (!busy && display.target !== null) {
|
|
54889
|
+
const next = nextClimateTarget(display.target, 1, display);
|
|
54890
|
+
applyOptimistic({ target: next });
|
|
54891
|
+
cap.setTarget({ target: next });
|
|
54892
|
+
}
|
|
54893
|
+
},
|
|
54894
|
+
className: cn("inline-flex h-5 w-5 items-center justify-center rounded text-foreground-subtle hover:text-foreground hover:bg-surface-hover transition-colors text-xs", busy && "opacity-40 cursor-not-allowed"),
|
|
54895
|
+
children: "+"
|
|
54896
|
+
})] }),
|
|
54897
|
+
/* @__PURE__ */ jsx("select", {
|
|
54898
|
+
"aria-label": t("uiLibrary.acPanel.mode", "Mode"),
|
|
54899
|
+
value: display.mode,
|
|
54900
|
+
disabled: busy,
|
|
54901
|
+
onChange: (e) => {
|
|
54902
|
+
e.stopPropagation();
|
|
54903
|
+
const mode = display.availableModes.find((m) => m === e.target.value);
|
|
54904
|
+
if (!busy && mode) {
|
|
54905
|
+
applyOptimistic({ mode });
|
|
54906
|
+
cap.setMode({ mode });
|
|
54907
|
+
}
|
|
54908
|
+
},
|
|
54909
|
+
className: cn("bg-transparent px-0.5 text-xs text-foreground-subtle hover:text-foreground cursor-pointer", busy && "opacity-40 cursor-not-allowed"),
|
|
54910
|
+
children: display.availableModes.map((m) => /* @__PURE__ */ jsx("option", {
|
|
54911
|
+
value: m,
|
|
54912
|
+
children: modeLabel(t, m)
|
|
54913
|
+
}, m))
|
|
54729
54914
|
})
|
|
54730
54915
|
]
|
|
54731
54916
|
});
|
|
54732
|
-
const
|
|
54917
|
+
const accent = MODE_ACCENT[display.mode];
|
|
54918
|
+
const on = display.mode !== "off";
|
|
54919
|
+
const heatingOnly = !climateOffersCooling(display.availableModes);
|
|
54920
|
+
const setpointBounds = climateSetpointBounds(display);
|
|
54921
|
+
const CurrentPresetIcon = presetIcon(display.preset);
|
|
54922
|
+
const boost = display.preset === "turbo";
|
|
54923
|
+
const period = Math.max(.55, airflowPeriodSec(display.fanMode) * (boost ? .6 : 1));
|
|
54924
|
+
const showVSwing = display.swingVertical !== null;
|
|
54925
|
+
const showHSwing = display.swingHorizontal !== null;
|
|
54926
|
+
const swaying = on && (display.swingVertical === true || display.swingHorizontal === true);
|
|
54733
54927
|
return /* @__PURE__ */ jsxs("div", {
|
|
54734
|
-
|
|
54928
|
+
"data-mode": display.mode,
|
|
54929
|
+
className: cn("relative flex flex-col items-stretch gap-2.5 overflow-hidden rounded-lg border p-3 transition-colors", MODE_COLOR[display.mode]),
|
|
54735
54930
|
children: [
|
|
54736
|
-
/* @__PURE__ */
|
|
54737
|
-
className: "flex items-start gap-4",
|
|
54738
|
-
children: [/* @__PURE__ */ jsx(DishwasherGraphic, {
|
|
54739
|
-
running,
|
|
54740
|
-
progressPercent: display.progress
|
|
54741
|
-
}), /* @__PURE__ */ jsxs("div", {
|
|
54742
|
-
className: "flex min-w-0 flex-1 flex-col gap-2",
|
|
54743
|
-
children: [
|
|
54744
|
-
/* @__PURE__ */ jsxs("div", {
|
|
54745
|
-
className: "flex flex-wrap items-center gap-2",
|
|
54746
|
-
children: [/* @__PURE__ */ jsx("span", {
|
|
54747
|
-
className: cn("text-3xl font-semibold", meta.tone),
|
|
54748
|
-
children: meta.label
|
|
54749
|
-
}), display.powerOn === false && /* @__PURE__ */ jsx("span", {
|
|
54750
|
-
className: "text-xs font-medium text-foreground-subtle",
|
|
54751
|
-
children: t("uiLibrary.dishwasher.powerOff", "Power off")
|
|
54752
|
-
})]
|
|
54753
|
-
}),
|
|
54754
|
-
display.program != null && /* @__PURE__ */ jsx("span", {
|
|
54755
|
-
className: "text-sm text-foreground-subtle",
|
|
54756
|
-
title: display.program,
|
|
54757
|
-
children: featureLabel(display.program)
|
|
54758
|
-
}),
|
|
54759
|
-
display.remaining != null && /* @__PURE__ */ jsxs("span", {
|
|
54760
|
-
className: "inline-flex items-center gap-1 text-sm text-foreground-subtle tabular-nums",
|
|
54761
|
-
children: [/* @__PURE__ */ jsx(Timer, { className: "h-3.5 w-3.5" }), t("uiLibrary.dishwasher.remaining", "{{time}} left", { time: formatDuration(display.remaining, t) })]
|
|
54762
|
-
}),
|
|
54763
|
-
display.delayedStart != null && display.delayedStart > 0 && /* @__PURE__ */ jsx("span", {
|
|
54764
|
-
className: "text-xs text-foreground-subtle tabular-nums",
|
|
54765
|
-
children: t("uiLibrary.dishwasher.startsIn", "Starts in {{time}}", { time: formatDuration(display.delayedStart, t) })
|
|
54766
|
-
}),
|
|
54767
|
-
display.progress != null && /* @__PURE__ */ jsxs("div", {
|
|
54768
|
-
className: "flex items-center gap-2",
|
|
54769
|
-
children: [/* @__PURE__ */ jsx("div", {
|
|
54770
|
-
className: "h-1.5 flex-1 rounded bg-surface-hover overflow-hidden",
|
|
54771
|
-
children: /* @__PURE__ */ jsx("div", {
|
|
54772
|
-
className: "h-full bg-primary transition-[width] duration-500",
|
|
54773
|
-
style: { width: `${Math.max(0, Math.min(100, display.progress))}%` }
|
|
54774
|
-
})
|
|
54775
|
-
}), /* @__PURE__ */ jsxs("span", {
|
|
54776
|
-
className: "tabular-nums text-xs text-foreground-subtle",
|
|
54777
|
-
children: [Math.round(display.progress), "%"]
|
|
54778
|
-
})]
|
|
54779
|
-
}),
|
|
54780
|
-
/* @__PURE__ */ jsxs("div", {
|
|
54781
|
-
className: "flex flex-wrap items-center gap-x-3 gap-y-1.5",
|
|
54782
|
-
children: [display.doorOpen === true && /* @__PURE__ */ jsxs("span", {
|
|
54783
|
-
className: "inline-flex items-center gap-1 text-xs text-warning",
|
|
54784
|
-
children: [/* @__PURE__ */ jsx(DoorOpen, { className: "h-3.5 w-3.5" }), t("uiLibrary.dishwasher.doorOpen", "Door open")]
|
|
54785
|
-
}), visibleDishwasherEvents(display.activeEvents).map((event) => /* @__PURE__ */ jsx("span", {
|
|
54786
|
-
className: "text-xs text-warning",
|
|
54787
|
-
title: event,
|
|
54788
|
-
children: featureLabel(event)
|
|
54789
|
-
}, event))]
|
|
54790
|
-
}),
|
|
54791
|
-
display.operationState === "Error" && /* @__PURE__ */ jsxs("div", {
|
|
54792
|
-
className: "inline-flex items-center gap-1 text-xs text-danger",
|
|
54793
|
-
children: [/* @__PURE__ */ jsx(TriangleAlert, { className: "h-3.5 w-3.5" }), /* @__PURE__ */ jsx("span", { children: display.errorLabel != null ? featureLabel(display.errorLabel) : display.errorCode != null ? t("uiLibrary.dishwasher.errorCode", "Error {{code}}", { code: display.errorCode }) : t("uiLibrary.dishwasher.op.error", "Error") })]
|
|
54794
|
-
}),
|
|
54795
|
-
/* @__PURE__ */ jsxs("div", {
|
|
54796
|
-
className: "flex flex-wrap items-center gap-2",
|
|
54797
|
-
children: [
|
|
54798
|
-
/* @__PURE__ */ jsx(DishwasherIconButton, {
|
|
54799
|
-
label: t("uiLibrary.dishwasher.start", "Start"),
|
|
54800
|
-
busy: busy || !startable,
|
|
54801
|
-
active: running,
|
|
54802
|
-
onClick: () => press(() => cap.start({})),
|
|
54803
|
-
children: /* @__PURE__ */ jsx(Play, { className: "h-4 w-4" })
|
|
54804
|
-
}),
|
|
54805
|
-
/* @__PURE__ */ jsx(DishwasherIconButton, {
|
|
54806
|
-
label: paused ? t("uiLibrary.dishwasher.resume", "Resume") : t("uiLibrary.dishwasher.pause", "Pause"),
|
|
54807
|
-
busy: busy || !(running || paused),
|
|
54808
|
-
active: paused,
|
|
54809
|
-
onClick: () => press(() => paused ? cap.resume({}) : cap.pause({})),
|
|
54810
|
-
children: /* @__PURE__ */ jsx(Pause, { className: "h-4 w-4" })
|
|
54811
|
-
}),
|
|
54812
|
-
/* @__PURE__ */ jsx(DishwasherIconButton, {
|
|
54813
|
-
label: t("uiLibrary.dishwasher.stop", "Stop"),
|
|
54814
|
-
busy: busy || !(running || paused),
|
|
54815
|
-
active: false,
|
|
54816
|
-
onClick: () => press(() => cap.stop({})),
|
|
54817
|
-
children: /* @__PURE__ */ jsx(Square, { className: "h-3.5 w-3.5" })
|
|
54818
|
-
}),
|
|
54819
|
-
/* @__PURE__ */ jsx(DishwasherIconButton, {
|
|
54820
|
-
label: t("uiLibrary.dishwasher.power", "Power"),
|
|
54821
|
-
busy: busy || display.powerOn === null,
|
|
54822
|
-
active: display.powerOn === true,
|
|
54823
|
-
onClick: () => {
|
|
54824
|
-
const next = display.powerOn !== true;
|
|
54825
|
-
press(() => cap.setPower({ on: next }));
|
|
54826
|
-
},
|
|
54827
|
-
children: /* @__PURE__ */ jsx(Power, { className: "h-4 w-4" })
|
|
54828
|
-
})
|
|
54829
|
-
]
|
|
54830
|
-
})
|
|
54831
|
-
]
|
|
54832
|
-
})]
|
|
54833
|
-
}),
|
|
54834
|
-
programs.length > 0 && /* @__PURE__ */ jsxs("label", {
|
|
54835
|
-
className: "flex items-center gap-2 text-xs text-foreground-subtle",
|
|
54836
|
-
children: [/* @__PURE__ */ jsx("span", {
|
|
54837
|
-
className: "w-16 shrink-0",
|
|
54838
|
-
children: t("uiLibrary.dishwasher.program", "Program")
|
|
54839
|
-
}), /* @__PURE__ */ jsxs("select", {
|
|
54840
|
-
"aria-label": t("uiLibrary.dishwasher.program", "Program"),
|
|
54841
|
-
value: display.selectedProgram ?? "",
|
|
54842
|
-
disabled: busy,
|
|
54843
|
-
onChange: (e) => {
|
|
54844
|
-
const program = e.target.value;
|
|
54845
|
-
if (!program) return;
|
|
54846
|
-
cap.setProgram({ program });
|
|
54847
|
-
},
|
|
54848
|
-
onClick: (e) => {
|
|
54849
|
-
e.stopPropagation();
|
|
54850
|
-
},
|
|
54851
|
-
className: "flex-1 rounded border border-border bg-surface px-2 py-1 text-foreground disabled:opacity-50",
|
|
54852
|
-
children: [display.selectedProgram == null && /* @__PURE__ */ jsx("option", {
|
|
54853
|
-
value: "",
|
|
54854
|
-
children: "—"
|
|
54855
|
-
}), programs.map((p) => /* @__PURE__ */ jsx("option", {
|
|
54856
|
-
value: p,
|
|
54857
|
-
children: featureLabel(p)
|
|
54858
|
-
}, p))]
|
|
54859
|
-
})]
|
|
54860
|
-
}),
|
|
54861
|
-
/* @__PURE__ */ jsxs("div", {
|
|
54862
|
-
className: "flex flex-wrap gap-4 text-xs",
|
|
54863
|
-
children: [
|
|
54864
|
-
/* @__PURE__ */ jsx(ToggleRow, {
|
|
54865
|
-
label: t("uiLibrary.dishwasher.halfLoad", "Half load"),
|
|
54866
|
-
checked: display.halfLoad,
|
|
54867
|
-
shown: link,
|
|
54868
|
-
busy: busy || optionTogglesLocked,
|
|
54869
|
-
onChange: (on) => void cap.setHalfLoad({ on })
|
|
54870
|
-
}),
|
|
54871
|
-
/* @__PURE__ */ jsx(ToggleRow, {
|
|
54872
|
-
label: t("uiLibrary.dishwasher.hygienePlus", "Hygiene plus"),
|
|
54873
|
-
checked: display.hygienePlus,
|
|
54874
|
-
shown: link,
|
|
54875
|
-
busy: busy || optionTogglesLocked,
|
|
54876
|
-
onChange: (on) => void cap.setHygienePlus({ on })
|
|
54877
|
-
}),
|
|
54878
|
-
/* @__PURE__ */ jsx(ToggleRow, {
|
|
54879
|
-
label: t("uiLibrary.dishwasher.extraDry", "Extra dry"),
|
|
54880
|
-
checked: display.extraDry,
|
|
54881
|
-
shown: link,
|
|
54882
|
-
busy: busy || optionTogglesLocked,
|
|
54883
|
-
onChange: (on) => void cap.setExtraDry({ on })
|
|
54884
|
-
}),
|
|
54885
|
-
/* @__PURE__ */ jsx(ToggleRow, {
|
|
54886
|
-
label: t("uiLibrary.dishwasher.intensiveZone", "Intensive zone"),
|
|
54887
|
-
checked: display.intensiveZone,
|
|
54888
|
-
shown: link,
|
|
54889
|
-
busy: busy || optionTogglesLocked,
|
|
54890
|
-
onChange: (on) => void cap.setIntensiveZone({ on })
|
|
54891
|
-
}),
|
|
54892
|
-
/* @__PURE__ */ jsx(ToggleRow, {
|
|
54893
|
-
label: t("uiLibrary.dishwasher.varioSpeedPlus", "VarioSpeed+"),
|
|
54894
|
-
checked: display.varioSpeedPlus,
|
|
54895
|
-
shown: link,
|
|
54896
|
-
busy: busy || optionTogglesLocked,
|
|
54897
|
-
onChange: (on) => void cap.setVarioSpeedPlus({ on })
|
|
54898
|
-
}),
|
|
54899
|
-
/* @__PURE__ */ jsx(ToggleRow, {
|
|
54900
|
-
label: t("uiLibrary.dishwasher.childLock", "Child lock"),
|
|
54901
|
-
checked: display.childLock,
|
|
54902
|
-
shown: link,
|
|
54903
|
-
busy,
|
|
54904
|
-
onChange: (on) => void cap.setChildLock({ on })
|
|
54905
|
-
})
|
|
54906
|
-
]
|
|
54907
|
-
})
|
|
54908
|
-
]
|
|
54909
|
-
});
|
|
54910
|
-
}
|
|
54911
|
-
/**
|
|
54912
|
-
* One boolean setting. `checked === null` is "the appliance has not said": on a reachable
|
|
54913
|
-
* appliance that means it does not offer the setting (hidden); on an unreachable one the
|
|
54914
|
-
* setting is shown but disabled and marked unknown — never as an unchecked box.
|
|
54915
|
-
*/
|
|
54916
|
-
function ToggleRow({ label, checked, shown, busy, onChange }) {
|
|
54917
|
-
const t = useUiText();
|
|
54918
|
-
if (checked === null && shown) return null;
|
|
54919
|
-
return /* @__PURE__ */ jsxs("label", {
|
|
54920
|
-
className: "inline-flex items-center gap-2 cursor-pointer",
|
|
54921
|
-
children: [
|
|
54922
|
-
/* @__PURE__ */ jsx("input", {
|
|
54923
|
-
type: "checkbox",
|
|
54924
|
-
checked: checked === true,
|
|
54925
|
-
"aria-checked": checked === null ? "mixed" : checked,
|
|
54926
|
-
disabled: busy || checked === null,
|
|
54927
|
-
onChange: (e) => {
|
|
54928
|
-
onChange(e.target.checked);
|
|
54929
|
-
},
|
|
54930
|
-
onClick: (e) => {
|
|
54931
|
-
e.stopPropagation();
|
|
54932
|
-
},
|
|
54933
|
-
className: "rounded border-border"
|
|
54934
|
-
}),
|
|
54935
|
-
/* @__PURE__ */ jsx("span", { children: label }),
|
|
54936
|
-
checked === null && /* @__PURE__ */ jsx("span", {
|
|
54937
|
-
className: "text-foreground-subtle",
|
|
54938
|
-
children: t("uiLibrary.dishwasher.unknownValue", "—")
|
|
54939
|
-
})
|
|
54940
|
-
]
|
|
54941
|
-
});
|
|
54942
|
-
}
|
|
54943
|
-
function DishwasherInlineControl(props) {
|
|
54944
|
-
return /* @__PURE__ */ jsx(DishwasherPanel, {
|
|
54945
|
-
...props,
|
|
54946
|
-
layout: "compact"
|
|
54947
|
-
});
|
|
54948
|
-
}
|
|
54949
|
-
function DishwasherHeroCard(props) {
|
|
54950
|
-
return /* @__PURE__ */ jsx(DishwasherPanel, {
|
|
54951
|
-
...props,
|
|
54952
|
-
layout: "full"
|
|
54953
|
-
});
|
|
54954
|
-
}
|
|
54955
|
-
//#endregion
|
|
54956
|
-
//#region src/composites/device-controls/appliance-control.tsx
|
|
54957
|
-
/**
|
|
54958
|
-
* Appliance card for a `DeviceType.Washer` / `DeviceType.Dryer` device.
|
|
54959
|
-
*
|
|
54960
|
-
* These appliances have no program surface: what is worth showing is whether
|
|
54961
|
-
* the cycle is running (the `running-state` cap), for how long, and what the
|
|
54962
|
-
* appliance draws right now (the `power-meter` cap). Both slices are read
|
|
54963
|
-
* straight from the device; neither is required.
|
|
54964
|
-
* - ApplianceInlineControl (device-list row): the running badge round the
|
|
54965
|
-
* drum icon, plus the live watts when there are any.
|
|
54966
|
-
* - ApplianceHeroCard (device-detail hero): the drum (turning only while a
|
|
54967
|
-
* cycle runs), the state, the phase, the dwell and the power.
|
|
54968
|
-
*
|
|
54969
|
-
* UNKNOWN IS NOT OFF (D393). `running: null` is drawn as "Unknown" and the
|
|
54970
|
-
* drum stays still and unbadged; a missing watt reading is a dash, never
|
|
54971
|
-
* "0 W". A slice that has not landed hides its row instead of faking a value.
|
|
54972
|
-
*/
|
|
54973
|
-
var KEYFRAMES$1 = `
|
|
54974
|
-
@keyframes apl-tumble { to { transform: rotate(360deg) } }
|
|
54975
|
-
.apl-drum-run { animation: apl-tumble 3s linear infinite; }
|
|
54976
|
-
@media (prefers-reduced-motion: reduce) {
|
|
54977
|
-
.apl-drum-run { animation: none !important; }
|
|
54978
|
-
}
|
|
54979
|
-
`;
|
|
54980
|
-
/** Whole watts, or a dash when the appliance has not reported a reading. */
|
|
54981
|
-
function formatWatts(power) {
|
|
54982
|
-
return power === void 0 || !Number.isFinite(power) ? "—" : `${Math.round(power)} W`;
|
|
54983
|
-
}
|
|
54984
|
-
/** The state to a person: running / idle, or why there is none (unknown). */
|
|
54985
|
-
function applianceStateLabel(running, t) {
|
|
54986
|
-
if (running === true) return {
|
|
54987
|
-
label: t("uiLibrary.appliance.running", "Running"),
|
|
54988
|
-
tone: "text-primary"
|
|
54989
|
-
};
|
|
54990
|
-
if (running === false) return {
|
|
54991
|
-
label: t("uiLibrary.appliance.idle", "Idle"),
|
|
54992
|
-
tone: "text-foreground"
|
|
54993
|
-
};
|
|
54994
|
-
return {
|
|
54995
|
-
label: t("uiLibrary.appliance.unknown", "Unknown"),
|
|
54996
|
-
tone: "text-foreground-subtle"
|
|
54997
|
-
};
|
|
54998
|
-
}
|
|
54999
|
-
function dwellText(running, since, now, t) {
|
|
55000
|
-
if (running !== true) return null;
|
|
55001
|
-
const { duration } = runningStatusParts(running, since, null, now);
|
|
55002
|
-
if (duration === void 0) return null;
|
|
55003
|
-
return "minutes" in duration ? t("uiLibrary.appliance.forMinutes", "for {{count}} min", { count: duration.minutes }) : t("uiLibrary.appliance.forHours", "for {{count}} h", { count: duration.hours });
|
|
55004
|
-
}
|
|
55005
|
-
function useApplianceState(props) {
|
|
55006
|
-
return {
|
|
55007
|
-
running: useDeviceState(props.trpc, props.deviceId, (s) => s.runningState),
|
|
55008
|
-
power: useDeviceState(props.trpc, props.deviceId, (s) => s.powerMeter)
|
|
55009
|
-
};
|
|
55010
|
-
}
|
|
55011
|
-
/** The drum: a ring with a few items in it, turning only while a cycle runs. */
|
|
55012
|
-
function Drum({ running }) {
|
|
55013
|
-
return /* @__PURE__ */ jsx("div", {
|
|
55014
|
-
"aria-hidden": "true",
|
|
55015
|
-
"data-testid": "appliance-drum",
|
|
55016
|
-
"data-running": running === true ? "running" : running === false ? "idle" : "unknown",
|
|
55017
|
-
className: "relative flex h-28 w-28 shrink-0 items-center justify-center rounded-full border-2 border-border bg-surface-hover",
|
|
55018
|
-
children: /* @__PURE__ */ jsxs("div", {
|
|
55019
|
-
className: cn("relative h-20 w-20 rounded-full border-2", running === true ? "apl-drum-run border-primary" : "border-border"),
|
|
55020
|
-
"data-testid": "appliance-drum-ring",
|
|
55021
|
-
children: [
|
|
55022
|
-
/* @__PURE__ */ jsx("span", { className: "absolute left-2 top-4 h-3 w-3 rounded-full bg-primary/40" }),
|
|
55023
|
-
/* @__PURE__ */ jsx("span", { className: "absolute bottom-3 right-3 h-4 w-4 rounded-full bg-info/40" }),
|
|
55024
|
-
/* @__PURE__ */ jsx("span", { className: "absolute bottom-4 left-4 h-2.5 w-2.5 rounded-full bg-foreground-subtle/40" })
|
|
55025
|
-
]
|
|
55026
|
-
})
|
|
55027
|
-
});
|
|
55028
|
-
}
|
|
55029
|
-
function ApplianceHeroCard(props) {
|
|
55030
|
-
const t = useUiText();
|
|
55031
|
-
const { running, power } = useApplianceState(props);
|
|
55032
|
-
const state = running?.running ?? null;
|
|
55033
|
-
const meta = applianceStateLabel(state, t);
|
|
55034
|
-
const phase = running?.phase?.trim() ?? "";
|
|
55035
|
-
const dwell = running === void 0 ? null : dwellText(state, running.since, Date.now(), t);
|
|
55036
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
55037
|
-
className: "flex items-center gap-4 rounded-lg border border-border bg-surface p-4",
|
|
55038
|
-
children: [
|
|
55039
|
-
/* @__PURE__ */ jsx("style", { children: KEYFRAMES$1 }),
|
|
55040
|
-
/* @__PURE__ */ jsx(Drum, { running: state }),
|
|
55041
|
-
/* @__PURE__ */ jsxs("div", {
|
|
55042
|
-
className: "flex min-w-0 flex-1 flex-col gap-2",
|
|
55043
|
-
children: [
|
|
55044
|
-
/* @__PURE__ */ jsxs("div", {
|
|
55045
|
-
className: "flex flex-wrap items-baseline gap-x-2",
|
|
55046
|
-
children: [/* @__PURE__ */ jsx("span", {
|
|
55047
|
-
"data-testid": "appliance-state",
|
|
55048
|
-
className: cn("text-3xl font-semibold", meta.tone),
|
|
55049
|
-
children: meta.label
|
|
55050
|
-
}), dwell !== null && /* @__PURE__ */ jsx("span", {
|
|
55051
|
-
className: "text-sm tabular-nums text-foreground-subtle",
|
|
55052
|
-
children: dwell
|
|
55053
|
-
})]
|
|
55054
|
-
}),
|
|
55055
|
-
phase !== "" && state !== null && /* @__PURE__ */ jsx("span", {
|
|
55056
|
-
className: "text-sm text-foreground-subtle",
|
|
55057
|
-
children: phase
|
|
55058
|
-
}),
|
|
55059
|
-
power !== void 0 && /* @__PURE__ */ jsxs("span", {
|
|
55060
|
-
"data-testid": "appliance-power",
|
|
55061
|
-
className: "inline-flex items-center gap-1 text-sm tabular-nums text-foreground-muted",
|
|
55062
|
-
title: power.power === void 0 ? t("uiLibrary.appliance.powerUnknown", "Power unknown") : void 0,
|
|
55063
|
-
children: [/* @__PURE__ */ jsx(Zap, {
|
|
55064
|
-
className: "h-3.5 w-3.5",
|
|
55065
|
-
"aria-hidden": true
|
|
55066
|
-
}), formatWatts(power.power)]
|
|
55067
|
-
})
|
|
55068
|
-
]
|
|
55069
|
-
})
|
|
55070
|
-
]
|
|
55071
|
-
});
|
|
55072
|
-
}
|
|
55073
|
-
function ApplianceInlineControl(props) {
|
|
55074
|
-
const { running, power } = useApplianceState(props);
|
|
55075
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
55076
|
-
className: "inline-flex items-center gap-1.5 max-w-full",
|
|
55077
|
-
children: [/* @__PURE__ */ jsx(RunningBadge, {
|
|
55078
|
-
running: running?.running ?? null,
|
|
55079
|
-
children: /* @__PURE__ */ jsx(WashingMachine, {
|
|
55080
|
-
className: "h-4 w-4 text-foreground-muted",
|
|
55081
|
-
"aria-hidden": true
|
|
55082
|
-
})
|
|
55083
|
-
}), power !== void 0 && /* @__PURE__ */ jsx("span", {
|
|
55084
|
-
className: "text-xs tabular-nums text-foreground-subtle",
|
|
55085
|
-
children: formatWatts(power.power)
|
|
55086
|
-
})]
|
|
55087
|
-
});
|
|
55088
|
-
}
|
|
55089
|
-
//#endregion
|
|
55090
|
-
//#region src/composites/device-controls/heating-valve-readout.tsx
|
|
55091
|
-
function formatHeatingValvePosition(position) {
|
|
55092
|
-
return position !== null ? `${position}%` : "—";
|
|
55093
|
-
}
|
|
55094
|
-
function HeatingValveReadout({ trpc, deviceId, layout }) {
|
|
55095
|
-
const t = useUiText();
|
|
55096
|
-
const { cap, slice } = useDeviceCapability({
|
|
55097
|
-
trpc,
|
|
55098
|
-
deviceId,
|
|
55099
|
-
cap: (d) => d.heatingValve,
|
|
55100
|
-
slice: (d) => d.state.heatingValve
|
|
55101
|
-
});
|
|
55102
|
-
if (cap === void 0 || slice === void 0) return null;
|
|
55103
|
-
const label = t("uiLibrary.heatingValveReadout.valve", "Valve");
|
|
55104
|
-
const value = formatHeatingValvePosition(slice.position);
|
|
55105
|
-
if (layout === "compact") return /* @__PURE__ */ jsx("span", {
|
|
55106
|
-
className: "inline-flex items-center text-xs tabular-nums text-foreground-subtle",
|
|
55107
|
-
"aria-label": `${label} ${value}`,
|
|
55108
|
-
children: value
|
|
55109
|
-
});
|
|
55110
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
55111
|
-
className: "flex items-center gap-2 text-xs tabular-nums text-foreground-subtle",
|
|
55112
|
-
children: [/* @__PURE__ */ jsx("span", { children: label }), /* @__PURE__ */ jsx("span", {
|
|
55113
|
-
className: "font-medium text-foreground",
|
|
55114
|
-
children: value
|
|
55115
|
-
})]
|
|
55116
|
-
});
|
|
55117
|
-
}
|
|
55118
|
-
//#endregion
|
|
55119
|
-
//#region src/composites/device-controls/ac-panel.tsx
|
|
55120
|
-
/** Modes that mean the device can cool, dry, or move air — an air conditioner. */
|
|
55121
|
-
var COOLING_MODES = new Set([
|
|
55122
|
-
"cool",
|
|
55123
|
-
"heat_cool",
|
|
55124
|
-
"dry",
|
|
55125
|
-
"fan_only"
|
|
55126
|
-
]);
|
|
55127
|
-
/** A heater offers heat (and maybe auto/off) and none of the cooling modes. */
|
|
55128
|
-
function climateOffersCooling(modes) {
|
|
55129
|
-
return modes.some((mode) => COOLING_MODES.has(mode));
|
|
55130
|
-
}
|
|
55131
|
-
/** Setpoint track bounds. Absent when the integration did not report both ends. */
|
|
55132
|
-
function climateSetpointBounds(status) {
|
|
55133
|
-
const min = status.minTemp;
|
|
55134
|
-
const max = status.maxTemp;
|
|
55135
|
-
if (typeof min !== "number" || typeof max !== "number") return null;
|
|
55136
|
-
if (!Number.isFinite(min) || !Number.isFinite(max) || max <= min) return null;
|
|
55137
|
-
return {
|
|
55138
|
-
min,
|
|
55139
|
-
max
|
|
55140
|
-
};
|
|
55141
|
-
}
|
|
55142
|
-
/** Map a 0–1 drag fraction onto the setpoint, snapped to `tempStep`. */
|
|
55143
|
-
function climateTargetFromFraction(fraction, bounds, tempStep) {
|
|
55144
|
-
const step = resolveClimateTempStep(tempStep);
|
|
55145
|
-
const clamped = Math.min(1, Math.max(0, fraction));
|
|
55146
|
-
const raw = bounds.min + clamped * (bounds.max - bounds.min);
|
|
55147
|
-
const steps = Math.round((raw - bounds.min) / step);
|
|
55148
|
-
const snapped = bounds.min + steps * step;
|
|
55149
|
-
const rounded = Math.round(snapped * 1e3) / 1e3;
|
|
55150
|
-
return Math.min(bounds.max, Math.max(bounds.min, rounded));
|
|
55151
|
-
}
|
|
55152
|
-
/** AC-appropriate short mode labels. Exhaustive over HvacMode. */
|
|
55153
|
-
function modeLabel(t, mode) {
|
|
55154
|
-
switch (mode) {
|
|
55155
|
-
case "cool": return t("uiLibrary.acPanel.modeCool", "Cool");
|
|
55156
|
-
case "heat": return t("uiLibrary.acPanel.modeHeat", "Heat");
|
|
55157
|
-
case "auto": return t("uiLibrary.acPanel.modeAuto", "Auto");
|
|
55158
|
-
case "heat_cool": return t("uiLibrary.acPanel.modeHeatCool", "Heat·Cool");
|
|
55159
|
-
case "fan_only": return t("uiLibrary.acPanel.modeFan", "Fan");
|
|
55160
|
-
case "dry": return t("uiLibrary.acPanel.modeDry", "Dry");
|
|
55161
|
-
case "off": return t("uiLibrary.acPanel.modeOff", "Off");
|
|
55162
|
-
}
|
|
55163
|
-
}
|
|
55164
|
-
/** Per-mode icon (lucide). Exhaustive over HvacMode. */
|
|
55165
|
-
var MODE_ICON = {
|
|
55166
|
-
cool: Snowflake,
|
|
55167
|
-
heat: Flame,
|
|
55168
|
-
auto: Sparkles,
|
|
55169
|
-
heat_cool: Thermometer,
|
|
55170
|
-
fan_only: Fan,
|
|
55171
|
-
dry: Droplets,
|
|
55172
|
-
off: Power
|
|
55173
|
-
};
|
|
55174
|
-
/** Mode accent hex — drives the airflow particles, the glow, and the target
|
|
55175
|
-
* value colour. Mirrors the thermostat gauge palette. Exhaustive. */
|
|
55176
|
-
var MODE_ACCENT = {
|
|
55177
|
-
heat: "#f59e0b",
|
|
55178
|
-
cool: "#60a5fa",
|
|
55179
|
-
auto: "#c084fc",
|
|
55180
|
-
heat_cool: "#e879f9",
|
|
55181
|
-
fan_only: "#94a3b8",
|
|
55182
|
-
dry: "#22d3ee",
|
|
55183
|
-
off: "#a1a1aa"
|
|
55184
|
-
};
|
|
55185
|
-
/** Title-case a snake/lower token for a selector option ('medium_low' → 'Medium
|
|
55186
|
-
* low', 'turbo' → 'Turbo'). Shared by the fan + preset selectors. */
|
|
55187
|
-
function fanLabel(token) {
|
|
55188
|
-
const spaced = token.replace(/_/g, " ");
|
|
55189
|
-
return spaced.charAt(0).toUpperCase() + spaced.slice(1);
|
|
55190
|
-
}
|
|
55191
|
-
/** Preset → icon. Unknown presets fall back to a neutral sparkle. */
|
|
55192
|
-
function presetIcon(preset) {
|
|
55193
|
-
switch (preset) {
|
|
55194
|
-
case "turbo": return Zap;
|
|
55195
|
-
case "quiet": return Feather;
|
|
55196
|
-
case "sleep": return Moon;
|
|
55197
|
-
case "eco": return Leaf;
|
|
55198
|
-
case "8c_heat": return Snowflake;
|
|
55199
|
-
case "none": return Ban;
|
|
55200
|
-
default: return Sparkles;
|
|
55201
|
-
}
|
|
55202
|
-
}
|
|
55203
|
-
/**
|
|
55204
|
-
* Fan level → airflow animation period. Higher speed ⇒ shorter period. Unknown
|
|
55205
|
-
* strings fall back to a medium pace. Turbo (a preset) shortens it further.
|
|
55206
|
-
*/
|
|
55207
|
-
function airflowPeriodSec(fanMode) {
|
|
55208
|
-
switch (fanMode) {
|
|
55209
|
-
case "high": return 1;
|
|
55210
|
-
case "medium_high": return 1.3;
|
|
55211
|
-
case "medium": return 1.6;
|
|
55212
|
-
case "medium_low": return 1.9;
|
|
55213
|
-
case "low": return 2.2;
|
|
55214
|
-
default: return 1.8;
|
|
55215
|
-
}
|
|
55216
|
-
}
|
|
55217
|
-
var KEYFRAMES = `
|
|
55218
|
-
@keyframes acv-fall { 0%{transform:translateY(-1.75rem);opacity:0} 18%{opacity:.7} 82%{opacity:.7} 100%{transform:translateY(7.5rem);opacity:0} }
|
|
55219
|
-
@keyframes acv-rise { 0%{transform:translateY(7.5rem);opacity:0} 18%{opacity:.7} 82%{opacity:.7} 100%{transform:translateY(-1.75rem);opacity:0} }
|
|
55220
|
-
@keyframes acv-sway { 0%,100%{transform:translateX(-9%)} 50%{transform:translateX(9%)} }
|
|
55221
|
-
@keyframes acv-swing-h { 0%,100%{transform:translateX(-22%)} 50%{transform:translateX(22%)} }
|
|
55222
|
-
@keyframes acv-swing-v { 0%,100%{transform:translateY(-22%)} 50%{transform:translateY(22%)} }
|
|
55223
|
-
@keyframes acv-spin { to { transform:rotate(360deg) } }
|
|
55224
|
-
@keyframes acv-glow { 0%,100%{opacity:.35;transform:scale(1)} 50%{opacity:.6;transform:scale(1.06)} }
|
|
55225
|
-
@media (prefers-reduced-motion: reduce) {
|
|
55226
|
-
.acv-streak, .acv-fan, .acv-sway-wrap, .acv-glow, .acv-swing { animation: none !important; }
|
|
55227
|
-
}
|
|
55228
|
-
`;
|
|
55229
|
-
function AcPanel({ trpc, deviceId, layout, optimistic }) {
|
|
55230
|
-
const t = useUiText();
|
|
55231
|
-
const { cap, slice, available } = useDeviceCapability({
|
|
55232
|
-
trpc,
|
|
55233
|
-
deviceId,
|
|
55234
|
-
cap: (d) => d.climateControl,
|
|
55235
|
-
slice: (d) => d.state.climateControl
|
|
55236
|
-
});
|
|
55237
|
-
const { display, applyOptimistic } = useOptimisticSlice(slice, { enabled: optimistic ?? true });
|
|
55238
|
-
if (cap === void 0) return null;
|
|
55239
|
-
if (display === void 0) return null;
|
|
55240
|
-
const busy = !available;
|
|
55241
|
-
if (layout === "compact") return /* @__PURE__ */ jsxs("div", {
|
|
55242
|
-
"data-mode": display.mode,
|
|
55243
|
-
className: "inline-flex items-center gap-1",
|
|
55244
|
-
children: [
|
|
55245
|
-
/* @__PURE__ */ jsx("span", {
|
|
55246
|
-
className: cn("text-xs tabular-nums font-medium", MODE_TEXT_COLOR[display.mode]),
|
|
55247
|
-
children: display.target !== null ? /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
55248
|
-
display.target,
|
|
55249
|
-
"°",
|
|
55250
|
-
display.currentTemp !== null && /* @__PURE__ */ jsxs("span", {
|
|
55251
|
-
className: "text-foreground-subtle font-normal",
|
|
55252
|
-
children: [
|
|
55253
|
-
" ",
|
|
55254
|
-
"(",
|
|
55255
|
-
display.currentTemp,
|
|
55256
|
-
"°)"
|
|
55257
|
-
]
|
|
55258
|
-
})
|
|
55259
|
-
] }) : display.currentTemp !== null ? /* @__PURE__ */ jsxs("span", {
|
|
55260
|
-
className: "text-foreground-subtle",
|
|
55261
|
-
children: [display.currentTemp, "°"]
|
|
55262
|
-
}) : null
|
|
55263
|
-
}),
|
|
55264
|
-
display.target !== null && /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("button", {
|
|
55265
|
-
type: "button",
|
|
55266
|
-
"aria-label": t("uiLibrary.acPanel.decrease", "Decrease target"),
|
|
55267
|
-
disabled: busy,
|
|
55268
|
-
onClick: (e) => {
|
|
55269
|
-
e.stopPropagation();
|
|
55270
|
-
if (!busy && display.target !== null) {
|
|
55271
|
-
const next = nextClimateTarget(display.target, -1, display);
|
|
55272
|
-
applyOptimistic({ target: next });
|
|
55273
|
-
cap.setTarget({ target: next });
|
|
55274
|
-
}
|
|
55275
|
-
},
|
|
55276
|
-
className: cn("inline-flex h-5 w-5 items-center justify-center rounded text-foreground-subtle hover:text-foreground hover:bg-surface-hover transition-colors text-xs", busy && "opacity-40 cursor-not-allowed"),
|
|
55277
|
-
children: "−"
|
|
55278
|
-
}), /* @__PURE__ */ jsx("button", {
|
|
55279
|
-
type: "button",
|
|
55280
|
-
"aria-label": t("uiLibrary.acPanel.increase", "Increase target"),
|
|
55281
|
-
disabled: busy,
|
|
55282
|
-
onClick: (e) => {
|
|
55283
|
-
e.stopPropagation();
|
|
55284
|
-
if (!busy && display.target !== null) {
|
|
55285
|
-
const next = nextClimateTarget(display.target, 1, display);
|
|
55286
|
-
applyOptimistic({ target: next });
|
|
55287
|
-
cap.setTarget({ target: next });
|
|
55288
|
-
}
|
|
55289
|
-
},
|
|
55290
|
-
className: cn("inline-flex h-5 w-5 items-center justify-center rounded text-foreground-subtle hover:text-foreground hover:bg-surface-hover transition-colors text-xs", busy && "opacity-40 cursor-not-allowed"),
|
|
55291
|
-
children: "+"
|
|
55292
|
-
})] }),
|
|
55293
|
-
/* @__PURE__ */ jsx("select", {
|
|
55294
|
-
"aria-label": t("uiLibrary.acPanel.mode", "Mode"),
|
|
55295
|
-
value: display.mode,
|
|
55296
|
-
disabled: busy,
|
|
55297
|
-
onChange: (e) => {
|
|
55298
|
-
e.stopPropagation();
|
|
55299
|
-
const mode = display.availableModes.find((m) => m === e.target.value);
|
|
55300
|
-
if (!busy && mode) {
|
|
55301
|
-
applyOptimistic({ mode });
|
|
55302
|
-
cap.setMode({ mode });
|
|
55303
|
-
}
|
|
55304
|
-
},
|
|
55305
|
-
className: cn("bg-transparent px-0.5 text-xs text-foreground-subtle hover:text-foreground cursor-pointer", busy && "opacity-40 cursor-not-allowed"),
|
|
55306
|
-
children: display.availableModes.map((m) => /* @__PURE__ */ jsx("option", {
|
|
55307
|
-
value: m,
|
|
55308
|
-
children: modeLabel(t, m)
|
|
55309
|
-
}, m))
|
|
55310
|
-
})
|
|
55311
|
-
]
|
|
55312
|
-
});
|
|
55313
|
-
const accent = MODE_ACCENT[display.mode];
|
|
55314
|
-
const on = display.mode !== "off";
|
|
55315
|
-
const heatingOnly = !climateOffersCooling(display.availableModes);
|
|
55316
|
-
const setpointBounds = climateSetpointBounds(display);
|
|
55317
|
-
const CurrentPresetIcon = presetIcon(display.preset);
|
|
55318
|
-
const boost = display.preset === "turbo";
|
|
55319
|
-
const period = Math.max(.55, airflowPeriodSec(display.fanMode) * (boost ? .6 : 1));
|
|
55320
|
-
const showVSwing = display.swingVertical !== null;
|
|
55321
|
-
const showHSwing = display.swingHorizontal !== null;
|
|
55322
|
-
const swaying = on && (display.swingVertical === true || display.swingHorizontal === true);
|
|
55323
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
55324
|
-
"data-mode": display.mode,
|
|
55325
|
-
className: cn("relative flex flex-col items-stretch gap-2.5 overflow-hidden rounded-lg border p-3 transition-colors", MODE_COLOR[display.mode]),
|
|
55326
|
-
children: [
|
|
55327
|
-
/* @__PURE__ */ jsx("style", { children: KEYFRAMES }),
|
|
54931
|
+
/* @__PURE__ */ jsx("style", { children: KEYFRAMES$1 }),
|
|
55328
54932
|
/* @__PURE__ */ jsxs("div", {
|
|
55329
54933
|
className: "relative z-10 flex flex-col items-center justify-center gap-1 overflow-hidden rounded-lg border border-border/50 bg-surface/30 px-3 py-3",
|
|
55330
54934
|
children: [
|
|
@@ -55466,347 +55070,1080 @@ function AcPanel({ trpc, deviceId, layout, optimistic }) {
|
|
|
55466
55070
|
}
|
|
55467
55071
|
}
|
|
55468
55072
|
}),
|
|
55469
|
-
display.availableFanModes.length > 0 && /* @__PURE__ */ jsx(CompactSelect, {
|
|
55470
|
-
label: t("uiLibrary.acPanel.fan", "Fan"),
|
|
55471
|
-
icon: /* @__PURE__ */ jsx(Wind, { className: "h-4 w-4 text-sky-500" }),
|
|
55472
|
-
value: display.fanMode,
|
|
55473
|
-
options: display.availableFanModes.map((f) => ({
|
|
55474
|
-
value: f,
|
|
55475
|
-
label: fanLabel(f)
|
|
55476
|
-
})),
|
|
55477
|
-
disabled: busy,
|
|
55478
|
-
onChange: (v) => {
|
|
55479
|
-
applyOptimistic({ fanMode: v });
|
|
55480
|
-
cap.setFanMode({ fanMode: v });
|
|
55481
|
-
}
|
|
55073
|
+
display.availableFanModes.length > 0 && /* @__PURE__ */ jsx(CompactSelect, {
|
|
55074
|
+
label: t("uiLibrary.acPanel.fan", "Fan"),
|
|
55075
|
+
icon: /* @__PURE__ */ jsx(Wind, { className: "h-4 w-4 text-sky-500" }),
|
|
55076
|
+
value: display.fanMode,
|
|
55077
|
+
options: display.availableFanModes.map((f) => ({
|
|
55078
|
+
value: f,
|
|
55079
|
+
label: fanLabel(f)
|
|
55080
|
+
})),
|
|
55081
|
+
disabled: busy,
|
|
55082
|
+
onChange: (v) => {
|
|
55083
|
+
applyOptimistic({ fanMode: v });
|
|
55084
|
+
cap.setFanMode({ fanMode: v });
|
|
55085
|
+
}
|
|
55086
|
+
}),
|
|
55087
|
+
display.availablePresets.length > 0 && /* @__PURE__ */ jsx(CompactSelect, {
|
|
55088
|
+
label: t("uiLibrary.acPanel.preset", "Preset"),
|
|
55089
|
+
icon: /* @__PURE__ */ jsx(CurrentPresetIcon, { className: "h-4 w-4 text-emerald-500" }),
|
|
55090
|
+
value: display.preset,
|
|
55091
|
+
options: display.availablePresets.map((p) => ({
|
|
55092
|
+
value: p,
|
|
55093
|
+
label: fanLabel(p)
|
|
55094
|
+
})),
|
|
55095
|
+
disabled: busy,
|
|
55096
|
+
onChange: (v) => {
|
|
55097
|
+
applyOptimistic({ preset: v });
|
|
55098
|
+
cap.setPreset({ preset: v });
|
|
55099
|
+
}
|
|
55100
|
+
})
|
|
55101
|
+
]
|
|
55102
|
+
}),
|
|
55103
|
+
(showVSwing || showHSwing) && /* @__PURE__ */ jsx(Field, {
|
|
55104
|
+
label: t("uiLibrary.acPanel.swing", "Swing"),
|
|
55105
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
55106
|
+
className: "grid grid-cols-2 gap-1",
|
|
55107
|
+
children: [showVSwing && /* @__PURE__ */ jsx(SwingToggle, {
|
|
55108
|
+
axis: "vertical",
|
|
55109
|
+
on: display.swingVertical ?? false,
|
|
55110
|
+
busy,
|
|
55111
|
+
onToggle: (next) => {
|
|
55112
|
+
applyOptimistic({ swingVertical: next });
|
|
55113
|
+
cap.setSwingVertical({ on: next });
|
|
55114
|
+
}
|
|
55115
|
+
}), showHSwing && /* @__PURE__ */ jsx(SwingToggle, {
|
|
55116
|
+
axis: "horizontal",
|
|
55117
|
+
on: display.swingHorizontal ?? false,
|
|
55118
|
+
busy,
|
|
55119
|
+
onToggle: (next) => {
|
|
55120
|
+
applyOptimistic({ swingHorizontal: next });
|
|
55121
|
+
cap.setSwingHorizontal({ on: next });
|
|
55122
|
+
}
|
|
55123
|
+
})]
|
|
55124
|
+
})
|
|
55125
|
+
})
|
|
55126
|
+
]
|
|
55127
|
+
});
|
|
55128
|
+
}
|
|
55129
|
+
/** Labelled control group — a small uppercase header above its control. */
|
|
55130
|
+
function Field({ label, children }) {
|
|
55131
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
55132
|
+
className: "relative z-10 flex flex-col gap-1",
|
|
55133
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
55134
|
+
className: "text-[10px] font-semibold uppercase tracking-wider text-foreground-subtle",
|
|
55135
|
+
children: label
|
|
55136
|
+
}), children]
|
|
55137
|
+
});
|
|
55138
|
+
}
|
|
55139
|
+
function ModeIcon({ mode, heatingOnly = false, className }) {
|
|
55140
|
+
return /* @__PURE__ */ jsx(heatingOnly && mode === "heat" ? Heater : MODE_ICON[mode], {
|
|
55141
|
+
className,
|
|
55142
|
+
"aria-hidden": true
|
|
55143
|
+
});
|
|
55144
|
+
}
|
|
55145
|
+
/** Compact labelled dropdown — a leading icon + native `<select>` + chevron,
|
|
55146
|
+
* used for the Mode / Fan / Preset selectors so all three fit in one row. */
|
|
55147
|
+
function CompactSelect({ label, icon, value, options, disabled, onChange }) {
|
|
55148
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
55149
|
+
className: "flex min-w-0 flex-col gap-1",
|
|
55150
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
55151
|
+
className: "text-[10px] font-semibold uppercase tracking-wider text-foreground-subtle",
|
|
55152
|
+
children: label
|
|
55153
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
55154
|
+
className: cn("flex items-center gap-1 overflow-hidden rounded-lg border border-border/60 bg-surface-subtle px-1.5 py-1.5 has-[:focus-visible]:border-primary", disabled && "opacity-40"),
|
|
55155
|
+
children: [
|
|
55156
|
+
/* @__PURE__ */ jsx("span", {
|
|
55157
|
+
className: "flex shrink-0",
|
|
55158
|
+
children: icon
|
|
55159
|
+
}),
|
|
55160
|
+
/* @__PURE__ */ jsx("select", {
|
|
55161
|
+
"aria-label": label,
|
|
55162
|
+
value,
|
|
55163
|
+
disabled,
|
|
55164
|
+
onChange: (e) => {
|
|
55165
|
+
e.stopPropagation();
|
|
55166
|
+
if (!disabled) onChange(e.target.value);
|
|
55167
|
+
},
|
|
55168
|
+
className: "min-w-0 flex-1 cursor-pointer appearance-none truncate bg-transparent text-xs font-medium text-foreground outline-none",
|
|
55169
|
+
children: options.map((o) => /* @__PURE__ */ jsx("option", {
|
|
55170
|
+
value: o.value,
|
|
55171
|
+
children: o.label
|
|
55172
|
+
}, o.value))
|
|
55173
|
+
}),
|
|
55174
|
+
/* @__PURE__ */ jsx(ChevronDown, { className: "h-3 w-3 shrink-0 text-foreground-subtle" })
|
|
55175
|
+
]
|
|
55176
|
+
})]
|
|
55177
|
+
});
|
|
55178
|
+
}
|
|
55179
|
+
/** Circular ± button for the target. */
|
|
55180
|
+
function RoundStep({ label, symbol, disabled, onClick }) {
|
|
55181
|
+
return /* @__PURE__ */ jsx("button", {
|
|
55182
|
+
type: "button",
|
|
55183
|
+
"aria-label": label,
|
|
55184
|
+
disabled,
|
|
55185
|
+
onClick,
|
|
55186
|
+
className: cn("flex h-8 w-8 shrink-0 items-center justify-center rounded-full border border-border bg-surface text-lg leading-none text-foreground-subtle transition-colors hover:bg-surface-hover hover:text-foreground active:scale-95", disabled && "opacity-40 cursor-not-allowed"),
|
|
55187
|
+
children: symbol
|
|
55188
|
+
});
|
|
55189
|
+
}
|
|
55190
|
+
/** Setpoint track. Drag previews; the command is sent when the pointer is released. */
|
|
55191
|
+
function RangeTrack({ value, min, max, step, accent, disabled, label, onPreview, onCommit }) {
|
|
55192
|
+
const trackRef = useRef(null);
|
|
55193
|
+
const draggingRef = useRef(false);
|
|
55194
|
+
const [draft, setDraft] = useState(null);
|
|
55195
|
+
const shown = draft ?? value;
|
|
55196
|
+
const pct = `${Math.min(1, Math.max(0, (shown - min) / (max - min))) * 100}%`;
|
|
55197
|
+
const tempAt = (clientX) => {
|
|
55198
|
+
const el = trackRef.current;
|
|
55199
|
+
if (el === null) return value;
|
|
55200
|
+
const rect = el.getBoundingClientRect();
|
|
55201
|
+
if (rect.width <= 0) return value;
|
|
55202
|
+
return climateTargetFromFraction((clientX - rect.left) / rect.width, {
|
|
55203
|
+
min,
|
|
55204
|
+
max
|
|
55205
|
+
}, step);
|
|
55206
|
+
};
|
|
55207
|
+
const onPointerDown = (event) => {
|
|
55208
|
+
if (disabled) return;
|
|
55209
|
+
event.stopPropagation();
|
|
55210
|
+
event.preventDefault();
|
|
55211
|
+
draggingRef.current = true;
|
|
55212
|
+
if (typeof event.currentTarget.setPointerCapture === "function") event.currentTarget.setPointerCapture(event.pointerId);
|
|
55213
|
+
const next = tempAt(event.clientX);
|
|
55214
|
+
setDraft(next);
|
|
55215
|
+
onPreview(next);
|
|
55216
|
+
};
|
|
55217
|
+
const onPointerMove = (event) => {
|
|
55218
|
+
if (disabled || !draggingRef.current) return;
|
|
55219
|
+
event.stopPropagation();
|
|
55220
|
+
const next = tempAt(event.clientX);
|
|
55221
|
+
setDraft(next);
|
|
55222
|
+
onPreview(next);
|
|
55223
|
+
};
|
|
55224
|
+
const endDrag = (event) => {
|
|
55225
|
+
if (!draggingRef.current) return;
|
|
55226
|
+
event.stopPropagation();
|
|
55227
|
+
draggingRef.current = false;
|
|
55228
|
+
const next = tempAt(event.clientX);
|
|
55229
|
+
setDraft(null);
|
|
55230
|
+
if (event.currentTarget.hasPointerCapture?.(event.pointerId) === true) event.currentTarget.releasePointerCapture(event.pointerId);
|
|
55231
|
+
onCommit(next);
|
|
55232
|
+
};
|
|
55233
|
+
const onKeyDown = (event) => {
|
|
55234
|
+
if (disabled) return;
|
|
55235
|
+
const current = draft ?? value;
|
|
55236
|
+
if (event.key === "ArrowRight" || event.key === "ArrowUp") {
|
|
55237
|
+
event.preventDefault();
|
|
55238
|
+
onCommit(nextClimateTarget(current, 1, {
|
|
55239
|
+
tempStep: step,
|
|
55240
|
+
minTemp: min,
|
|
55241
|
+
maxTemp: max
|
|
55242
|
+
}));
|
|
55243
|
+
} else if (event.key === "ArrowLeft" || event.key === "ArrowDown") {
|
|
55244
|
+
event.preventDefault();
|
|
55245
|
+
onCommit(nextClimateTarget(current, -1, {
|
|
55246
|
+
tempStep: step,
|
|
55247
|
+
minTemp: min,
|
|
55248
|
+
maxTemp: max
|
|
55249
|
+
}));
|
|
55250
|
+
} else if (event.key === "Home") {
|
|
55251
|
+
event.preventDefault();
|
|
55252
|
+
onCommit(min);
|
|
55253
|
+
} else if (event.key === "End") {
|
|
55254
|
+
event.preventDefault();
|
|
55255
|
+
onCommit(max);
|
|
55256
|
+
}
|
|
55257
|
+
};
|
|
55258
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
55259
|
+
ref: trackRef,
|
|
55260
|
+
role: "slider",
|
|
55261
|
+
"aria-label": label,
|
|
55262
|
+
"aria-valuemin": min,
|
|
55263
|
+
"aria-valuemax": max,
|
|
55264
|
+
"aria-valuenow": shown,
|
|
55265
|
+
"aria-disabled": disabled,
|
|
55266
|
+
tabIndex: disabled ? -1 : 0,
|
|
55267
|
+
onPointerDown,
|
|
55268
|
+
onPointerMove,
|
|
55269
|
+
onPointerUp: endDrag,
|
|
55270
|
+
onPointerCancel: endDrag,
|
|
55271
|
+
onKeyDown,
|
|
55272
|
+
className: cn("mt-1 w-full touch-none select-none py-2", disabled ? "cursor-not-allowed opacity-40" : "cursor-ew-resize"),
|
|
55273
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
55274
|
+
className: "relative h-1.5 w-full rounded-full bg-surface-subtle",
|
|
55275
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
55276
|
+
className: "absolute inset-y-0 left-0 rounded-full",
|
|
55277
|
+
style: {
|
|
55278
|
+
width: pct,
|
|
55279
|
+
background: accent
|
|
55280
|
+
}
|
|
55281
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
55282
|
+
className: "absolute top-1/2 h-3.5 w-3.5 -translate-x-1/2 -translate-y-1/2 rounded-full border-2 border-surface shadow",
|
|
55283
|
+
style: {
|
|
55284
|
+
left: pct,
|
|
55285
|
+
background: accent
|
|
55286
|
+
}
|
|
55287
|
+
})]
|
|
55288
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
55289
|
+
className: "mt-0.5 flex justify-between text-[9px] tabular-nums text-foreground-subtle",
|
|
55290
|
+
children: [/* @__PURE__ */ jsxs("span", { children: [min, "°"] }), /* @__PURE__ */ jsxs("span", { children: [max, "°"] })]
|
|
55291
|
+
})]
|
|
55292
|
+
});
|
|
55293
|
+
}
|
|
55294
|
+
/**
|
|
55295
|
+
* Animated centerpiece. `fan_only` renders a spinning fan; `off` a dim static
|
|
55296
|
+
* vent; every active mode renders drifting particles that FALL (cool/dry/auto)
|
|
55297
|
+
* or RISE (heat), with a horizontal sweep overlaid when a swing axis is active.
|
|
55298
|
+
*/
|
|
55299
|
+
function AirflowViz({ mode, accent, periodSec, swaying, forceRising = false }) {
|
|
55300
|
+
const columns = [
|
|
55301
|
+
0,
|
|
55302
|
+
1,
|
|
55303
|
+
2,
|
|
55304
|
+
3,
|
|
55305
|
+
4,
|
|
55306
|
+
5
|
|
55307
|
+
];
|
|
55308
|
+
const rising = forceRising || mode === "heat";
|
|
55309
|
+
const isDroplet = mode === "dry";
|
|
55310
|
+
return /* @__PURE__ */ jsx("div", {
|
|
55311
|
+
"aria-hidden": true,
|
|
55312
|
+
className: "absolute inset-0 overflow-hidden",
|
|
55313
|
+
children: mode === "off" ? /* @__PURE__ */ jsx("div", {
|
|
55314
|
+
className: "flex h-full items-center justify-center gap-2 opacity-30",
|
|
55315
|
+
children: columns.map((i) => /* @__PURE__ */ jsx("span", { className: "h-8 w-1 rounded-full bg-foreground-subtle opacity-40" }, i))
|
|
55316
|
+
}) : mode === "fan_only" ? /* @__PURE__ */ jsx("div", {
|
|
55317
|
+
className: "flex h-full items-center justify-center",
|
|
55318
|
+
children: /* @__PURE__ */ jsx(FanBlades, {
|
|
55319
|
+
color: accent,
|
|
55320
|
+
periodSec: Math.max(.5, periodSec * .7),
|
|
55321
|
+
size: 56
|
|
55322
|
+
})
|
|
55323
|
+
}) : /* @__PURE__ */ jsx("div", {
|
|
55324
|
+
"data-testid": forceRising ? "climate-heat-rise" : void 0,
|
|
55325
|
+
className: cn("acv-sway-wrap absolute inset-0", swaying && "acv-sway"),
|
|
55326
|
+
style: swaying ? { animation: "acv-sway 2.6s ease-in-out infinite" } : void 0,
|
|
55327
|
+
children: columns.map((i) => {
|
|
55328
|
+
return /* @__PURE__ */ jsx("span", {
|
|
55329
|
+
className: "acv-streak absolute rounded-full",
|
|
55330
|
+
style: {
|
|
55331
|
+
left: `${8 + i * 15}%`,
|
|
55332
|
+
width: isDroplet ? "0.4rem" : "0.3rem",
|
|
55333
|
+
height: isDroplet ? "0.4rem" : "1.9rem",
|
|
55334
|
+
background: accent,
|
|
55335
|
+
boxShadow: `0 0 6px ${accent}`,
|
|
55336
|
+
animationName: rising ? "acv-rise" : "acv-fall",
|
|
55337
|
+
animationTimingFunction: "linear",
|
|
55338
|
+
animationIterationCount: "infinite",
|
|
55339
|
+
animationDuration: `${periodSec}s`,
|
|
55340
|
+
animationDelay: `${i % 3 * (periodSec / 3) + i * .05}s`
|
|
55341
|
+
}
|
|
55342
|
+
}, i);
|
|
55343
|
+
})
|
|
55344
|
+
})
|
|
55345
|
+
});
|
|
55346
|
+
}
|
|
55347
|
+
/** Still radiator fins — the off state of a heating-only climate. */
|
|
55348
|
+
function RadiatorFins() {
|
|
55349
|
+
return /* @__PURE__ */ jsx("div", {
|
|
55350
|
+
"data-testid": "climate-radiator",
|
|
55351
|
+
"aria-hidden": true,
|
|
55352
|
+
className: "flex h-full items-end justify-center gap-1.5 px-8 pb-3 opacity-40",
|
|
55353
|
+
children: [
|
|
55354
|
+
0,
|
|
55355
|
+
1,
|
|
55356
|
+
2,
|
|
55357
|
+
3,
|
|
55358
|
+
4,
|
|
55359
|
+
5,
|
|
55360
|
+
6
|
|
55361
|
+
].map((i) => /* @__PURE__ */ jsx("span", { className: "h-10 w-1.5 rounded-t-full bg-foreground-subtle" }, i))
|
|
55362
|
+
});
|
|
55363
|
+
}
|
|
55364
|
+
/** Big spinning fan for `fan_only` mode. */
|
|
55365
|
+
function FanBlades({ color, periodSec, size }) {
|
|
55366
|
+
return /* @__PURE__ */ jsxs("svg", {
|
|
55367
|
+
width: size,
|
|
55368
|
+
height: size,
|
|
55369
|
+
viewBox: "0 0 100 100",
|
|
55370
|
+
className: "acv-fan",
|
|
55371
|
+
style: {
|
|
55372
|
+
animation: `acv-spin ${periodSec}s linear infinite`,
|
|
55373
|
+
transformOrigin: "50% 50%"
|
|
55374
|
+
},
|
|
55375
|
+
"aria-hidden": true,
|
|
55376
|
+
children: [[
|
|
55377
|
+
0,
|
|
55378
|
+
120,
|
|
55379
|
+
240
|
|
55380
|
+
].map((deg) => /* @__PURE__ */ jsx("path", {
|
|
55381
|
+
d: "M50 50 C 58 30, 78 26, 84 12 C 66 20, 54 34, 50 50 Z",
|
|
55382
|
+
fill: color,
|
|
55383
|
+
opacity: .85,
|
|
55384
|
+
transform: `rotate(${deg} 50 50)`
|
|
55385
|
+
}, deg)), /* @__PURE__ */ jsx("circle", {
|
|
55386
|
+
cx: "50",
|
|
55387
|
+
cy: "50",
|
|
55388
|
+
r: "7",
|
|
55389
|
+
fill: color
|
|
55390
|
+
})]
|
|
55391
|
+
});
|
|
55392
|
+
}
|
|
55393
|
+
/** Swing axis toggle — a card with a MoveVertical/Horizontal glyph that
|
|
55394
|
+
* oscillates along its axis when on. On/off is non-destructive → plain tap. */
|
|
55395
|
+
function SwingToggle({ axis, on, busy, onToggle }) {
|
|
55396
|
+
const t = useUiText();
|
|
55397
|
+
const label = axis === "vertical" ? t("uiLibrary.acPanel.vertical", "Vertical") : t("uiLibrary.acPanel.horizontal", "Horizontal");
|
|
55398
|
+
const Icon = axis === "vertical" ? MoveVertical : MoveHorizontal;
|
|
55399
|
+
const anim = axis === "vertical" ? "acv-swing-v" : "acv-swing-h";
|
|
55400
|
+
return /* @__PURE__ */ jsxs("button", {
|
|
55401
|
+
type: "button",
|
|
55402
|
+
"aria-label": t("uiLibrary.acPanel.swingAxis", "{{axis}} swing", { axis: label }),
|
|
55403
|
+
"aria-pressed": on,
|
|
55404
|
+
disabled: busy,
|
|
55405
|
+
onClick: () => {
|
|
55406
|
+
if (!busy) onToggle(!on);
|
|
55407
|
+
},
|
|
55408
|
+
className: cn("flex items-center justify-center gap-2 rounded-lg border px-2 py-1.5 text-xs font-medium transition-colors", on ? "border-transparent bg-indigo-400 text-indigo-950 shadow-sm" : "border-border/60 bg-surface-subtle text-foreground-subtle hover:bg-surface-hover hover:text-foreground", busy && "opacity-40 cursor-not-allowed"),
|
|
55409
|
+
children: [/* @__PURE__ */ jsx(Icon, {
|
|
55410
|
+
className: "acv-swing h-4 w-4",
|
|
55411
|
+
"aria-hidden": true,
|
|
55412
|
+
style: on ? { animation: `${anim} 1.4s ease-in-out infinite` } : void 0
|
|
55413
|
+
}), label]
|
|
55414
|
+
});
|
|
55415
|
+
}
|
|
55416
|
+
//#endregion
|
|
55417
|
+
//#region src/composites/device-controls/heater-control.tsx
|
|
55418
|
+
/**
|
|
55419
|
+
* Heater controls for a `DeviceType.Heater` device (a dumb plug-in stove).
|
|
55420
|
+
*
|
|
55421
|
+
* A heater is a switch that heats while it is on, and the hub can switch it off
|
|
55422
|
+
* again after a chosen time (`timed-run`, D993):
|
|
55423
|
+
* - HeaterInlineControl (device-list row): the on/off switch and a one-tap
|
|
55424
|
+
* "Run N min".
|
|
55425
|
+
* - HeaterHeroCard (device-detail hero): the glowing heat backdrop (the same
|
|
55426
|
+
* rising streaks a heating air conditioner draws) while it is on, the
|
|
55427
|
+
* on/off switch, the power draw when the plug measures one, and the timed
|
|
55428
|
+
* run (number, unit, Run, countdown, Cancel).
|
|
55429
|
+
*
|
|
55430
|
+
* Every reading may be unknown (`null`) and is drawn as a dash, never as zero.
|
|
55431
|
+
*/
|
|
55432
|
+
var HEATER_LIMIT = TIMED_RUN_LIMITS[DeviceType.Heater];
|
|
55433
|
+
var QUICK_RUN_MINUTES = 30;
|
|
55434
|
+
var HEAT_ACCENT = "var(--color-warning)";
|
|
55435
|
+
var HEAT_PERIOD_SEC = 1.8;
|
|
55436
|
+
function useHeater({ trpc, deviceId, optimistic }) {
|
|
55437
|
+
const { cap, slice, available } = useDeviceCapability({
|
|
55438
|
+
trpc,
|
|
55439
|
+
deviceId,
|
|
55440
|
+
cap: (d) => d.switch,
|
|
55441
|
+
slice: (d) => d.state.switch
|
|
55442
|
+
});
|
|
55443
|
+
const running = useDeviceCapability({
|
|
55444
|
+
trpc,
|
|
55445
|
+
deviceId,
|
|
55446
|
+
cap: (d) => d.runningState,
|
|
55447
|
+
slice: (d) => d.state.runningState
|
|
55448
|
+
});
|
|
55449
|
+
const power = useDeviceCapability({
|
|
55450
|
+
trpc,
|
|
55451
|
+
deviceId,
|
|
55452
|
+
cap: (d) => d.powerMeter,
|
|
55453
|
+
slice: (d) => d.state.powerMeter
|
|
55454
|
+
});
|
|
55455
|
+
const timer = useDeviceCapability({
|
|
55456
|
+
trpc,
|
|
55457
|
+
deviceId,
|
|
55458
|
+
cap: (d) => d.timedRun,
|
|
55459
|
+
slice: (d) => d.state.timedRun
|
|
55460
|
+
});
|
|
55461
|
+
const { display, applyOptimistic } = useOptimisticSlice(slice, { enabled: optimistic ?? true });
|
|
55462
|
+
return {
|
|
55463
|
+
cap,
|
|
55464
|
+
display,
|
|
55465
|
+
available,
|
|
55466
|
+
applyOptimistic,
|
|
55467
|
+
running: running.slice,
|
|
55468
|
+
power: power.slice,
|
|
55469
|
+
timer
|
|
55470
|
+
};
|
|
55471
|
+
}
|
|
55472
|
+
function HeaterInlineControl(props) {
|
|
55473
|
+
const t = useUiText();
|
|
55474
|
+
const { cap, display, available, applyOptimistic, timer } = useHeater(props);
|
|
55475
|
+
if (cap === void 0 || display === void 0) return null;
|
|
55476
|
+
const on = display.on === true;
|
|
55477
|
+
const quickMinutes = HEATER_LIMIT === void 0 ? QUICK_RUN_MINUTES : Math.min(QUICK_RUN_MINUTES, maxInUnit(HEATER_LIMIT));
|
|
55478
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
55479
|
+
className: "inline-flex items-center gap-2",
|
|
55480
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
55481
|
+
onClick: (e) => e.stopPropagation(),
|
|
55482
|
+
children: /* @__PURE__ */ jsx(Switch, {
|
|
55483
|
+
checked: on,
|
|
55484
|
+
disabled: !available,
|
|
55485
|
+
"aria-label": t("uiLibrary.heater.power", "Heater"),
|
|
55486
|
+
onCheckedChange: (next) => {
|
|
55487
|
+
applyOptimistic({ on: next });
|
|
55488
|
+
cap.setState({ on: next });
|
|
55489
|
+
}
|
|
55490
|
+
})
|
|
55491
|
+
}), timer.cap !== void 0 && /* @__PURE__ */ jsx("span", {
|
|
55492
|
+
onClick: (e) => e.stopPropagation(),
|
|
55493
|
+
children: /* @__PURE__ */ jsxs(Button, {
|
|
55494
|
+
size: "sm",
|
|
55495
|
+
variant: "outline",
|
|
55496
|
+
disabled: !timer.online,
|
|
55497
|
+
onClick: () => void timer.cap?.runFor({
|
|
55498
|
+
duration: quickMinutes,
|
|
55499
|
+
unit: "min"
|
|
55500
|
+
}),
|
|
55501
|
+
children: [/* @__PURE__ */ jsx(Timer, {
|
|
55502
|
+
className: "h-3.5 w-3.5",
|
|
55503
|
+
"aria-hidden": true
|
|
55504
|
+
}), t("uiLibrary.heater.quickRun", "Run {{minutes}} min", { minutes: quickMinutes })]
|
|
55505
|
+
})
|
|
55506
|
+
})]
|
|
55507
|
+
});
|
|
55508
|
+
}
|
|
55509
|
+
function HeaterHeroCard(props) {
|
|
55510
|
+
const t = useUiText();
|
|
55511
|
+
const { cap, display, available, applyOptimistic, running, power, timer } = useHeater(props);
|
|
55512
|
+
if (cap === void 0 || display === void 0) return null;
|
|
55513
|
+
const on = display.on === true;
|
|
55514
|
+
const heating = running?.running ?? on;
|
|
55515
|
+
const watts = power?.power ?? null;
|
|
55516
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
55517
|
+
className: "relative flex flex-col items-stretch gap-3 overflow-hidden rounded-lg border border-border bg-surface p-4",
|
|
55518
|
+
children: [
|
|
55519
|
+
/* @__PURE__ */ jsx("style", { children: KEYFRAMES$1 }),
|
|
55520
|
+
/* @__PURE__ */ jsxs("div", {
|
|
55521
|
+
className: "relative flex h-32 items-center justify-center overflow-hidden rounded-lg border border-border-subtle bg-background-elevated",
|
|
55522
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
55523
|
+
className: cn("pointer-events-none absolute inset-0", heating ? "opacity-60" : "opacity-20"),
|
|
55524
|
+
children: /* @__PURE__ */ jsx(AirflowViz, {
|
|
55525
|
+
mode: heating ? "heat" : "off",
|
|
55526
|
+
accent: HEAT_ACCENT,
|
|
55527
|
+
periodSec: HEAT_PERIOD_SEC,
|
|
55528
|
+
swaying: false,
|
|
55529
|
+
forceRising: true
|
|
55530
|
+
})
|
|
55531
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
55532
|
+
className: "relative z-10 flex flex-col items-center gap-1",
|
|
55533
|
+
children: [
|
|
55534
|
+
/* @__PURE__ */ jsx(Flame, {
|
|
55535
|
+
className: cn("h-8 w-8", heating ? "text-warning" : "text-foreground-subtle"),
|
|
55536
|
+
"aria-hidden": true
|
|
55537
|
+
}),
|
|
55538
|
+
/* @__PURE__ */ jsx("span", {
|
|
55539
|
+
className: "text-sm font-medium text-foreground",
|
|
55540
|
+
children: heating ? t("uiLibrary.heater.heating", "Heating") : t("uiLibrary.heater.off", "Off")
|
|
55541
|
+
}),
|
|
55542
|
+
/* @__PURE__ */ jsx("span", {
|
|
55543
|
+
className: "text-xs tabular-nums text-foreground-muted",
|
|
55544
|
+
"data-testid": "heater-watts",
|
|
55545
|
+
children: watts === null ? "—" : `${Math.round(watts)} W`
|
|
55546
|
+
})
|
|
55547
|
+
]
|
|
55548
|
+
})]
|
|
55549
|
+
}),
|
|
55550
|
+
/* @__PURE__ */ jsxs("label", {
|
|
55551
|
+
className: "flex items-center justify-between gap-3 text-sm text-foreground",
|
|
55552
|
+
children: [t("uiLibrary.heater.power", "Heater"), /* @__PURE__ */ jsx(Switch, {
|
|
55553
|
+
checked: on,
|
|
55554
|
+
disabled: !available,
|
|
55555
|
+
onCheckedChange: (next) => {
|
|
55556
|
+
applyOptimistic({ on: next });
|
|
55557
|
+
cap.setState({ on: next });
|
|
55558
|
+
}
|
|
55559
|
+
})]
|
|
55560
|
+
}),
|
|
55561
|
+
timer.cap !== void 0 && HEATER_LIMIT !== void 0 && /* @__PURE__ */ jsx(TimedRunControl, {
|
|
55562
|
+
trpc: props.trpc,
|
|
55563
|
+
deviceId: props.deviceId,
|
|
55564
|
+
limit: HEATER_LIMIT
|
|
55565
|
+
})
|
|
55566
|
+
]
|
|
55567
|
+
});
|
|
55568
|
+
}
|
|
55569
|
+
//#endregion
|
|
55570
|
+
//#region src/composites/device-controls/dishwasher-control.tsx
|
|
55571
|
+
/**
|
|
55572
|
+
* Dishwasher controls for a `DeviceType.Dishwasher` device.
|
|
55573
|
+
*
|
|
55574
|
+
* Reads the `dishwasher` cap status slice and renders inline + hero surfaces
|
|
55575
|
+
* mirroring vacuum-control / pet-feeder patterns.
|
|
55576
|
+
*
|
|
55577
|
+
* Salt and rinse aid are not here: they are items of the device's `consumables`
|
|
55578
|
+
* cap, shown by the page's Consumables section like every device's (D915).
|
|
55579
|
+
*
|
|
55580
|
+
* UNKNOWN IS NOT OFF. The slice carries `null` for everything the appliance has not
|
|
55581
|
+
* reported, and this view renders that as "—" / a disabled control, never as an unchecked
|
|
55582
|
+
* box or a zero. It also does not echo a command before the appliance confirms it: the
|
|
55583
|
+
* slice moves when the appliance says so.
|
|
55584
|
+
*/
|
|
55585
|
+
/** What the operation state is called to a person, and how it is toned. */
|
|
55586
|
+
function dishwasherOperationMeta(operationState, t = defaultUiText) {
|
|
55587
|
+
switch (operationState) {
|
|
55588
|
+
case "Run": return {
|
|
55589
|
+
label: t("uiLibrary.dishwasher.op.run", "Running"),
|
|
55590
|
+
tone: "text-primary"
|
|
55591
|
+
};
|
|
55592
|
+
case "Pause": return {
|
|
55593
|
+
label: t("uiLibrary.dishwasher.op.pause", "Paused"),
|
|
55594
|
+
tone: "text-warning"
|
|
55595
|
+
};
|
|
55596
|
+
case "Finished": return {
|
|
55597
|
+
label: t("uiLibrary.dishwasher.op.finished", "Finished"),
|
|
55598
|
+
tone: "text-success"
|
|
55599
|
+
};
|
|
55600
|
+
case "Error": return {
|
|
55601
|
+
label: t("uiLibrary.dishwasher.op.error", "Error"),
|
|
55602
|
+
tone: "text-danger"
|
|
55603
|
+
};
|
|
55604
|
+
case "Aborting": return {
|
|
55605
|
+
label: t("uiLibrary.dishwasher.op.aborting", "Stopping"),
|
|
55606
|
+
tone: "text-warning"
|
|
55607
|
+
};
|
|
55608
|
+
case "ActionRequired": return {
|
|
55609
|
+
label: t("uiLibrary.dishwasher.op.actionRequired", "Action required"),
|
|
55610
|
+
tone: "text-warning"
|
|
55611
|
+
};
|
|
55612
|
+
case "DelayedStart": return {
|
|
55613
|
+
label: t("uiLibrary.dishwasher.op.delayedStart", "Delayed start"),
|
|
55614
|
+
tone: "text-primary"
|
|
55615
|
+
};
|
|
55616
|
+
case "Ready": return {
|
|
55617
|
+
label: t("uiLibrary.dishwasher.op.ready", "Ready"),
|
|
55618
|
+
tone: "text-foreground"
|
|
55619
|
+
};
|
|
55620
|
+
case "Inactive": return {
|
|
55621
|
+
label: t("uiLibrary.dishwasher.op.inactive", "Inactive"),
|
|
55622
|
+
tone: "text-foreground-subtle"
|
|
55623
|
+
};
|
|
55624
|
+
case null: return {
|
|
55625
|
+
label: t("uiLibrary.dishwasher.unknown", "Unknown"),
|
|
55626
|
+
tone: "text-foreground-subtle"
|
|
55627
|
+
};
|
|
55628
|
+
}
|
|
55629
|
+
}
|
|
55630
|
+
/** The headline for the whole slice: the appliance's state, or why there is none. */
|
|
55631
|
+
function dishwasherHeadline(status, t = defaultUiText) {
|
|
55632
|
+
switch (status.availability) {
|
|
55633
|
+
case "offline": return {
|
|
55634
|
+
label: t("uiLibrary.dishwasher.offline", "Offline"),
|
|
55635
|
+
tone: "text-foreground-subtle"
|
|
55636
|
+
};
|
|
55637
|
+
case "description-missing": return {
|
|
55638
|
+
label: t("uiLibrary.dishwasher.descriptionMissing", "Waiting for the appliance profile"),
|
|
55639
|
+
tone: "text-warning"
|
|
55640
|
+
};
|
|
55641
|
+
case "available": return dishwasherOperationMeta(status.operationState, t);
|
|
55642
|
+
}
|
|
55643
|
+
}
|
|
55644
|
+
/** Last segment of a feature key, spaced out: `Dishcare.Dishwasher.Program.Eco50` -> `Eco50`. */
|
|
55645
|
+
function featureLabel(key) {
|
|
55646
|
+
return (key.split(".").pop() ?? key).replace(/([a-z0-9])([A-Z])/g, "$1 $2");
|
|
55647
|
+
}
|
|
55648
|
+
/**
|
|
55649
|
+
* Salt and rinse aid are consumable items (D915). Their events must not
|
|
55650
|
+
* reappear on the hero — the Consumables section is the only surface.
|
|
55651
|
+
*/
|
|
55652
|
+
function isConsumableDishwasherEvent(event) {
|
|
55653
|
+
const short = (event.split(".").pop() ?? event).toLowerCase();
|
|
55654
|
+
return short.includes("salt") || short.includes("rinse");
|
|
55655
|
+
}
|
|
55656
|
+
/** Raised events the hero may name. Consumable events are dropped. */
|
|
55657
|
+
function visibleDishwasherEvents(events) {
|
|
55658
|
+
return events.filter((event) => !isConsumableDishwasherEvent(event));
|
|
55659
|
+
}
|
|
55660
|
+
/** Whole seconds as a short duration: `1 h 24 min`, `42 min`, `30 s`. */
|
|
55661
|
+
function formatDuration(seconds, t = defaultUiText) {
|
|
55662
|
+
if (seconds < 60) return t("uiLibrary.dishwasher.durationSeconds", "{{n}} s", { n: seconds });
|
|
55663
|
+
const minutes = Math.round(seconds / 60);
|
|
55664
|
+
if (minutes < 60) return t("uiLibrary.dishwasher.durationMinutes", "{{n}} min", { n: minutes });
|
|
55665
|
+
const hours = Math.floor(minutes / 60);
|
|
55666
|
+
const rest = minutes % 60;
|
|
55667
|
+
return rest === 0 ? t("uiLibrary.dishwasher.durationHours", "{{n}} h", { n: hours }) : t("uiLibrary.dishwasher.durationHoursMinutes", "{{h}} h {{m}} min", {
|
|
55668
|
+
h: hours,
|
|
55669
|
+
m: rest
|
|
55670
|
+
});
|
|
55671
|
+
}
|
|
55672
|
+
function useDishwasher(trpc, deviceId) {
|
|
55673
|
+
return useDeviceCapability({
|
|
55674
|
+
trpc,
|
|
55675
|
+
deviceId,
|
|
55676
|
+
cap: (d) => d.dishwasher,
|
|
55677
|
+
slice: (d) => d.state.dishwasher
|
|
55678
|
+
});
|
|
55679
|
+
}
|
|
55680
|
+
function DishwasherIconButton({ label, busy, active, onClick, children }) {
|
|
55681
|
+
return /* @__PURE__ */ jsx("button", {
|
|
55682
|
+
type: "button",
|
|
55683
|
+
"aria-label": label,
|
|
55684
|
+
title: label,
|
|
55685
|
+
disabled: busy,
|
|
55686
|
+
onClick: (e) => {
|
|
55687
|
+
e.stopPropagation();
|
|
55688
|
+
onClick();
|
|
55689
|
+
},
|
|
55690
|
+
className: cn("inline-flex h-5 w-5 items-center justify-center rounded text-foreground-subtle hover:text-foreground hover:bg-surface-hover transition-colors", active && "bg-primary text-primary-foreground", busy && "opacity-40 cursor-not-allowed"),
|
|
55691
|
+
children
|
|
55692
|
+
});
|
|
55693
|
+
}
|
|
55694
|
+
function DishwasherGraphic({ running, progressPercent }) {
|
|
55695
|
+
const pct = progressPercent != null ? Math.max(0, Math.min(100, progressPercent)) : running ? 40 : 0;
|
|
55696
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
55697
|
+
"aria-hidden": "true",
|
|
55698
|
+
className: "relative w-28 h-36 rounded border-2 border-border bg-gradient-to-b from-surface-hover to-surface overflow-hidden flex-shrink-0",
|
|
55699
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
55700
|
+
className: cn("absolute inset-x-0 bottom-0 bg-primary/25 transition-[height] duration-500", running && "animate-pulse"),
|
|
55701
|
+
style: { height: `${pct}%` }
|
|
55702
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
55703
|
+
className: "absolute inset-0 flex items-center justify-center text-foreground-subtle",
|
|
55704
|
+
children: /* @__PURE__ */ jsx(Waves, { className: "h-10 w-10 opacity-70" })
|
|
55705
|
+
})]
|
|
55706
|
+
});
|
|
55707
|
+
}
|
|
55708
|
+
function DishwasherPanel({ trpc, deviceId, layout }) {
|
|
55709
|
+
const t = useUiText();
|
|
55710
|
+
const { cap, slice, available } = useDishwasher(trpc, deviceId);
|
|
55711
|
+
if (cap === void 0) return null;
|
|
55712
|
+
if (slice === void 0) return null;
|
|
55713
|
+
const display = slice;
|
|
55714
|
+
const link = display.availability === "available";
|
|
55715
|
+
const busy = !available || !link;
|
|
55716
|
+
const optionTogglesLocked = display.childLock === true;
|
|
55717
|
+
const meta = dishwasherHeadline(display, t);
|
|
55718
|
+
const running = display.operationState === "Run";
|
|
55719
|
+
const paused = display.operationState === "Pause";
|
|
55720
|
+
const startable = display.remoteStartAllowed === true && display.selectedProgram !== null;
|
|
55721
|
+
const press = (fn) => {
|
|
55722
|
+
if (busy) return;
|
|
55723
|
+
fn();
|
|
55724
|
+
};
|
|
55725
|
+
if (layout === "compact") return /* @__PURE__ */ jsxs("div", {
|
|
55726
|
+
className: "inline-flex items-center gap-1.5 max-w-full",
|
|
55727
|
+
children: [
|
|
55728
|
+
display.doorOpen === true && /* @__PURE__ */ jsx("span", {
|
|
55729
|
+
className: "inline-flex text-warning shrink-0",
|
|
55730
|
+
title: t("uiLibrary.dishwasher.doorOpen", "Door open"),
|
|
55731
|
+
"aria-label": t("uiLibrary.dishwasher.doorOpen", "Door open"),
|
|
55732
|
+
children: /* @__PURE__ */ jsx(DoorOpen, { className: "h-3.5 w-3.5" })
|
|
55733
|
+
}),
|
|
55734
|
+
/* @__PURE__ */ jsx("span", {
|
|
55735
|
+
className: cn("text-xs font-medium tabular-nums shrink-0", meta.tone),
|
|
55736
|
+
children: meta.label
|
|
55737
|
+
}),
|
|
55738
|
+
display.program != null && /* @__PURE__ */ jsx("span", {
|
|
55739
|
+
className: "text-xs text-foreground-subtle truncate max-w-[7rem]",
|
|
55740
|
+
title: display.program,
|
|
55741
|
+
children: featureLabel(display.program)
|
|
55742
|
+
}),
|
|
55743
|
+
display.remaining != null && /* @__PURE__ */ jsxs("span", {
|
|
55744
|
+
className: "inline-flex items-center gap-0.5 text-xs text-foreground-subtle tabular-nums shrink-0",
|
|
55745
|
+
children: [/* @__PURE__ */ jsx(Timer, { className: "h-3 w-3" }), formatDuration(display.remaining, t)]
|
|
55746
|
+
}),
|
|
55747
|
+
/* @__PURE__ */ jsx(DishwasherIconButton, {
|
|
55748
|
+
label: t("uiLibrary.dishwasher.start", "Start"),
|
|
55749
|
+
busy: busy || !startable,
|
|
55750
|
+
active: running,
|
|
55751
|
+
onClick: () => press(() => cap.start({})),
|
|
55752
|
+
children: /* @__PURE__ */ jsx(Play, { className: "h-3 w-3" })
|
|
55753
|
+
}),
|
|
55754
|
+
/* @__PURE__ */ jsx(DishwasherIconButton, {
|
|
55755
|
+
label: paused ? t("uiLibrary.dishwasher.resume", "Resume") : t("uiLibrary.dishwasher.pause", "Pause"),
|
|
55756
|
+
busy: busy || !(running || paused),
|
|
55757
|
+
active: paused,
|
|
55758
|
+
onClick: () => press(() => paused ? cap.resume({}) : cap.pause({})),
|
|
55759
|
+
children: /* @__PURE__ */ jsx(Pause, { className: "h-3 w-3" })
|
|
55760
|
+
})
|
|
55761
|
+
]
|
|
55762
|
+
});
|
|
55763
|
+
const programs = display.availablePrograms;
|
|
55764
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
55765
|
+
className: "flex flex-col gap-3 rounded-lg border border-border bg-surface p-4",
|
|
55766
|
+
children: [
|
|
55767
|
+
/* @__PURE__ */ jsxs("div", {
|
|
55768
|
+
className: "flex items-start gap-4",
|
|
55769
|
+
children: [/* @__PURE__ */ jsx(DishwasherGraphic, {
|
|
55770
|
+
running,
|
|
55771
|
+
progressPercent: display.progress
|
|
55772
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
55773
|
+
className: "flex min-w-0 flex-1 flex-col gap-2",
|
|
55774
|
+
children: [
|
|
55775
|
+
/* @__PURE__ */ jsxs("div", {
|
|
55776
|
+
className: "flex flex-wrap items-center gap-2",
|
|
55777
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
55778
|
+
className: cn("text-3xl font-semibold", meta.tone),
|
|
55779
|
+
children: meta.label
|
|
55780
|
+
}), display.powerOn === false && /* @__PURE__ */ jsx("span", {
|
|
55781
|
+
className: "text-xs font-medium text-foreground-subtle",
|
|
55782
|
+
children: t("uiLibrary.dishwasher.powerOff", "Power off")
|
|
55783
|
+
})]
|
|
55784
|
+
}),
|
|
55785
|
+
display.program != null && /* @__PURE__ */ jsx("span", {
|
|
55786
|
+
className: "text-sm text-foreground-subtle",
|
|
55787
|
+
title: display.program,
|
|
55788
|
+
children: featureLabel(display.program)
|
|
55789
|
+
}),
|
|
55790
|
+
display.remaining != null && /* @__PURE__ */ jsxs("span", {
|
|
55791
|
+
className: "inline-flex items-center gap-1 text-sm text-foreground-subtle tabular-nums",
|
|
55792
|
+
children: [/* @__PURE__ */ jsx(Timer, { className: "h-3.5 w-3.5" }), t("uiLibrary.dishwasher.remaining", "{{time}} left", { time: formatDuration(display.remaining, t) })]
|
|
55793
|
+
}),
|
|
55794
|
+
display.delayedStart != null && display.delayedStart > 0 && /* @__PURE__ */ jsx("span", {
|
|
55795
|
+
className: "text-xs text-foreground-subtle tabular-nums",
|
|
55796
|
+
children: t("uiLibrary.dishwasher.startsIn", "Starts in {{time}}", { time: formatDuration(display.delayedStart, t) })
|
|
55797
|
+
}),
|
|
55798
|
+
display.progress != null && /* @__PURE__ */ jsxs("div", {
|
|
55799
|
+
className: "flex items-center gap-2",
|
|
55800
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
55801
|
+
className: "h-1.5 flex-1 rounded bg-surface-hover overflow-hidden",
|
|
55802
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
55803
|
+
className: "h-full bg-primary transition-[width] duration-500",
|
|
55804
|
+
style: { width: `${Math.max(0, Math.min(100, display.progress))}%` }
|
|
55805
|
+
})
|
|
55806
|
+
}), /* @__PURE__ */ jsxs("span", {
|
|
55807
|
+
className: "tabular-nums text-xs text-foreground-subtle",
|
|
55808
|
+
children: [Math.round(display.progress), "%"]
|
|
55809
|
+
})]
|
|
55810
|
+
}),
|
|
55811
|
+
/* @__PURE__ */ jsxs("div", {
|
|
55812
|
+
className: "flex flex-wrap items-center gap-x-3 gap-y-1.5",
|
|
55813
|
+
children: [display.doorOpen === true && /* @__PURE__ */ jsxs("span", {
|
|
55814
|
+
className: "inline-flex items-center gap-1 text-xs text-warning",
|
|
55815
|
+
children: [/* @__PURE__ */ jsx(DoorOpen, { className: "h-3.5 w-3.5" }), t("uiLibrary.dishwasher.doorOpen", "Door open")]
|
|
55816
|
+
}), visibleDishwasherEvents(display.activeEvents).map((event) => /* @__PURE__ */ jsx("span", {
|
|
55817
|
+
className: "text-xs text-warning",
|
|
55818
|
+
title: event,
|
|
55819
|
+
children: featureLabel(event)
|
|
55820
|
+
}, event))]
|
|
55821
|
+
}),
|
|
55822
|
+
display.operationState === "Error" && /* @__PURE__ */ jsxs("div", {
|
|
55823
|
+
className: "inline-flex items-center gap-1 text-xs text-danger",
|
|
55824
|
+
children: [/* @__PURE__ */ jsx(TriangleAlert, { className: "h-3.5 w-3.5" }), /* @__PURE__ */ jsx("span", { children: display.errorLabel != null ? featureLabel(display.errorLabel) : display.errorCode != null ? t("uiLibrary.dishwasher.errorCode", "Error {{code}}", { code: display.errorCode }) : t("uiLibrary.dishwasher.op.error", "Error") })]
|
|
55825
|
+
}),
|
|
55826
|
+
/* @__PURE__ */ jsxs("div", {
|
|
55827
|
+
className: "flex flex-wrap items-center gap-2",
|
|
55828
|
+
children: [
|
|
55829
|
+
/* @__PURE__ */ jsx(DishwasherIconButton, {
|
|
55830
|
+
label: t("uiLibrary.dishwasher.start", "Start"),
|
|
55831
|
+
busy: busy || !startable,
|
|
55832
|
+
active: running,
|
|
55833
|
+
onClick: () => press(() => cap.start({})),
|
|
55834
|
+
children: /* @__PURE__ */ jsx(Play, { className: "h-4 w-4" })
|
|
55835
|
+
}),
|
|
55836
|
+
/* @__PURE__ */ jsx(DishwasherIconButton, {
|
|
55837
|
+
label: paused ? t("uiLibrary.dishwasher.resume", "Resume") : t("uiLibrary.dishwasher.pause", "Pause"),
|
|
55838
|
+
busy: busy || !(running || paused),
|
|
55839
|
+
active: paused,
|
|
55840
|
+
onClick: () => press(() => paused ? cap.resume({}) : cap.pause({})),
|
|
55841
|
+
children: /* @__PURE__ */ jsx(Pause, { className: "h-4 w-4" })
|
|
55842
|
+
}),
|
|
55843
|
+
/* @__PURE__ */ jsx(DishwasherIconButton, {
|
|
55844
|
+
label: t("uiLibrary.dishwasher.stop", "Stop"),
|
|
55845
|
+
busy: busy || !(running || paused),
|
|
55846
|
+
active: false,
|
|
55847
|
+
onClick: () => press(() => cap.stop({})),
|
|
55848
|
+
children: /* @__PURE__ */ jsx(Square, { className: "h-3.5 w-3.5" })
|
|
55849
|
+
}),
|
|
55850
|
+
/* @__PURE__ */ jsx(DishwasherIconButton, {
|
|
55851
|
+
label: t("uiLibrary.dishwasher.power", "Power"),
|
|
55852
|
+
busy: busy || display.powerOn === null,
|
|
55853
|
+
active: display.powerOn === true,
|
|
55854
|
+
onClick: () => {
|
|
55855
|
+
const next = display.powerOn !== true;
|
|
55856
|
+
press(() => cap.setPower({ on: next }));
|
|
55857
|
+
},
|
|
55858
|
+
children: /* @__PURE__ */ jsx(Power, { className: "h-4 w-4" })
|
|
55859
|
+
})
|
|
55860
|
+
]
|
|
55861
|
+
})
|
|
55862
|
+
]
|
|
55863
|
+
})]
|
|
55864
|
+
}),
|
|
55865
|
+
programs.length > 0 && /* @__PURE__ */ jsxs("label", {
|
|
55866
|
+
className: "flex items-center gap-2 text-xs text-foreground-subtle",
|
|
55867
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
55868
|
+
className: "w-16 shrink-0",
|
|
55869
|
+
children: t("uiLibrary.dishwasher.program", "Program")
|
|
55870
|
+
}), /* @__PURE__ */ jsxs("select", {
|
|
55871
|
+
"aria-label": t("uiLibrary.dishwasher.program", "Program"),
|
|
55872
|
+
value: display.selectedProgram ?? "",
|
|
55873
|
+
disabled: busy,
|
|
55874
|
+
onChange: (e) => {
|
|
55875
|
+
const program = e.target.value;
|
|
55876
|
+
if (!program) return;
|
|
55877
|
+
cap.setProgram({ program });
|
|
55878
|
+
},
|
|
55879
|
+
onClick: (e) => {
|
|
55880
|
+
e.stopPropagation();
|
|
55881
|
+
},
|
|
55882
|
+
className: "flex-1 rounded border border-border bg-surface px-2 py-1 text-foreground disabled:opacity-50",
|
|
55883
|
+
children: [display.selectedProgram == null && /* @__PURE__ */ jsx("option", {
|
|
55884
|
+
value: "",
|
|
55885
|
+
children: "—"
|
|
55886
|
+
}), programs.map((p) => /* @__PURE__ */ jsx("option", {
|
|
55887
|
+
value: p,
|
|
55888
|
+
children: featureLabel(p)
|
|
55889
|
+
}, p))]
|
|
55890
|
+
})]
|
|
55891
|
+
}),
|
|
55892
|
+
/* @__PURE__ */ jsxs("div", {
|
|
55893
|
+
className: "flex flex-wrap gap-4 text-xs",
|
|
55894
|
+
children: [
|
|
55895
|
+
/* @__PURE__ */ jsx(ToggleRow, {
|
|
55896
|
+
label: t("uiLibrary.dishwasher.halfLoad", "Half load"),
|
|
55897
|
+
checked: display.halfLoad,
|
|
55898
|
+
shown: link,
|
|
55899
|
+
busy: busy || optionTogglesLocked,
|
|
55900
|
+
onChange: (on) => void cap.setHalfLoad({ on })
|
|
55901
|
+
}),
|
|
55902
|
+
/* @__PURE__ */ jsx(ToggleRow, {
|
|
55903
|
+
label: t("uiLibrary.dishwasher.hygienePlus", "Hygiene plus"),
|
|
55904
|
+
checked: display.hygienePlus,
|
|
55905
|
+
shown: link,
|
|
55906
|
+
busy: busy || optionTogglesLocked,
|
|
55907
|
+
onChange: (on) => void cap.setHygienePlus({ on })
|
|
55908
|
+
}),
|
|
55909
|
+
/* @__PURE__ */ jsx(ToggleRow, {
|
|
55910
|
+
label: t("uiLibrary.dishwasher.extraDry", "Extra dry"),
|
|
55911
|
+
checked: display.extraDry,
|
|
55912
|
+
shown: link,
|
|
55913
|
+
busy: busy || optionTogglesLocked,
|
|
55914
|
+
onChange: (on) => void cap.setExtraDry({ on })
|
|
55915
|
+
}),
|
|
55916
|
+
/* @__PURE__ */ jsx(ToggleRow, {
|
|
55917
|
+
label: t("uiLibrary.dishwasher.intensiveZone", "Intensive zone"),
|
|
55918
|
+
checked: display.intensiveZone,
|
|
55919
|
+
shown: link,
|
|
55920
|
+
busy: busy || optionTogglesLocked,
|
|
55921
|
+
onChange: (on) => void cap.setIntensiveZone({ on })
|
|
55922
|
+
}),
|
|
55923
|
+
/* @__PURE__ */ jsx(ToggleRow, {
|
|
55924
|
+
label: t("uiLibrary.dishwasher.varioSpeedPlus", "VarioSpeed+"),
|
|
55925
|
+
checked: display.varioSpeedPlus,
|
|
55926
|
+
shown: link,
|
|
55927
|
+
busy: busy || optionTogglesLocked,
|
|
55928
|
+
onChange: (on) => void cap.setVarioSpeedPlus({ on })
|
|
55482
55929
|
}),
|
|
55483
|
-
|
|
55484
|
-
label: t("uiLibrary.
|
|
55485
|
-
|
|
55486
|
-
|
|
55487
|
-
|
|
55488
|
-
|
|
55489
|
-
label: fanLabel(p)
|
|
55490
|
-
})),
|
|
55491
|
-
disabled: busy,
|
|
55492
|
-
onChange: (v) => {
|
|
55493
|
-
applyOptimistic({ preset: v });
|
|
55494
|
-
cap.setPreset({ preset: v });
|
|
55495
|
-
}
|
|
55930
|
+
/* @__PURE__ */ jsx(ToggleRow, {
|
|
55931
|
+
label: t("uiLibrary.dishwasher.childLock", "Child lock"),
|
|
55932
|
+
checked: display.childLock,
|
|
55933
|
+
shown: link,
|
|
55934
|
+
busy,
|
|
55935
|
+
onChange: (on) => void cap.setChildLock({ on })
|
|
55496
55936
|
})
|
|
55497
55937
|
]
|
|
55498
|
-
}),
|
|
55499
|
-
(showVSwing || showHSwing) && /* @__PURE__ */ jsx(Field, {
|
|
55500
|
-
label: t("uiLibrary.acPanel.swing", "Swing"),
|
|
55501
|
-
children: /* @__PURE__ */ jsxs("div", {
|
|
55502
|
-
className: "grid grid-cols-2 gap-1",
|
|
55503
|
-
children: [showVSwing && /* @__PURE__ */ jsx(SwingToggle, {
|
|
55504
|
-
axis: "vertical",
|
|
55505
|
-
on: display.swingVertical ?? false,
|
|
55506
|
-
busy,
|
|
55507
|
-
onToggle: (next) => {
|
|
55508
|
-
applyOptimistic({ swingVertical: next });
|
|
55509
|
-
cap.setSwingVertical({ on: next });
|
|
55510
|
-
}
|
|
55511
|
-
}), showHSwing && /* @__PURE__ */ jsx(SwingToggle, {
|
|
55512
|
-
axis: "horizontal",
|
|
55513
|
-
on: display.swingHorizontal ?? false,
|
|
55514
|
-
busy,
|
|
55515
|
-
onToggle: (next) => {
|
|
55516
|
-
applyOptimistic({ swingHorizontal: next });
|
|
55517
|
-
cap.setSwingHorizontal({ on: next });
|
|
55518
|
-
}
|
|
55519
|
-
})]
|
|
55520
|
-
})
|
|
55521
55938
|
})
|
|
55522
55939
|
]
|
|
55523
55940
|
});
|
|
55524
55941
|
}
|
|
55525
|
-
/**
|
|
55526
|
-
|
|
55527
|
-
|
|
55528
|
-
|
|
55529
|
-
|
|
55530
|
-
|
|
55531
|
-
|
|
55532
|
-
|
|
55942
|
+
/**
|
|
55943
|
+
* One boolean setting. `checked === null` is "the appliance has not said": on a reachable
|
|
55944
|
+
* appliance that means it does not offer the setting (hidden); on an unreachable one the
|
|
55945
|
+
* setting is shown but disabled and marked unknown — never as an unchecked box.
|
|
55946
|
+
*/
|
|
55947
|
+
function ToggleRow({ label, checked, shown, busy, onChange }) {
|
|
55948
|
+
const t = useUiText();
|
|
55949
|
+
if (checked === null && shown) return null;
|
|
55950
|
+
return /* @__PURE__ */ jsxs("label", {
|
|
55951
|
+
className: "inline-flex items-center gap-2 cursor-pointer",
|
|
55952
|
+
children: [
|
|
55953
|
+
/* @__PURE__ */ jsx("input", {
|
|
55954
|
+
type: "checkbox",
|
|
55955
|
+
checked: checked === true,
|
|
55956
|
+
"aria-checked": checked === null ? "mixed" : checked,
|
|
55957
|
+
disabled: busy || checked === null,
|
|
55958
|
+
onChange: (e) => {
|
|
55959
|
+
onChange(e.target.checked);
|
|
55960
|
+
},
|
|
55961
|
+
onClick: (e) => {
|
|
55962
|
+
e.stopPropagation();
|
|
55963
|
+
},
|
|
55964
|
+
className: "rounded border-border"
|
|
55965
|
+
}),
|
|
55966
|
+
/* @__PURE__ */ jsx("span", { children: label }),
|
|
55967
|
+
checked === null && /* @__PURE__ */ jsx("span", {
|
|
55968
|
+
className: "text-foreground-subtle",
|
|
55969
|
+
children: t("uiLibrary.dishwasher.unknownValue", "—")
|
|
55970
|
+
})
|
|
55971
|
+
]
|
|
55533
55972
|
});
|
|
55534
55973
|
}
|
|
55535
|
-
function
|
|
55536
|
-
return /* @__PURE__ */ jsx(
|
|
55537
|
-
|
|
55538
|
-
"
|
|
55974
|
+
function DishwasherInlineControl(props) {
|
|
55975
|
+
return /* @__PURE__ */ jsx(DishwasherPanel, {
|
|
55976
|
+
...props,
|
|
55977
|
+
layout: "compact"
|
|
55539
55978
|
});
|
|
55540
55979
|
}
|
|
55541
|
-
|
|
55542
|
-
|
|
55543
|
-
|
|
55544
|
-
|
|
55545
|
-
className: "flex min-w-0 flex-col gap-1",
|
|
55546
|
-
children: [/* @__PURE__ */ jsx("span", {
|
|
55547
|
-
className: "text-[10px] font-semibold uppercase tracking-wider text-foreground-subtle",
|
|
55548
|
-
children: label
|
|
55549
|
-
}), /* @__PURE__ */ jsxs("div", {
|
|
55550
|
-
className: cn("flex items-center gap-1 overflow-hidden rounded-lg border border-border/60 bg-surface-subtle px-1.5 py-1.5 has-[:focus-visible]:border-primary", disabled && "opacity-40"),
|
|
55551
|
-
children: [
|
|
55552
|
-
/* @__PURE__ */ jsx("span", {
|
|
55553
|
-
className: "flex shrink-0",
|
|
55554
|
-
children: icon
|
|
55555
|
-
}),
|
|
55556
|
-
/* @__PURE__ */ jsx("select", {
|
|
55557
|
-
"aria-label": label,
|
|
55558
|
-
value,
|
|
55559
|
-
disabled,
|
|
55560
|
-
onChange: (e) => {
|
|
55561
|
-
e.stopPropagation();
|
|
55562
|
-
if (!disabled) onChange(e.target.value);
|
|
55563
|
-
},
|
|
55564
|
-
className: "min-w-0 flex-1 cursor-pointer appearance-none truncate bg-transparent text-xs font-medium text-foreground outline-none",
|
|
55565
|
-
children: options.map((o) => /* @__PURE__ */ jsx("option", {
|
|
55566
|
-
value: o.value,
|
|
55567
|
-
children: o.label
|
|
55568
|
-
}, o.value))
|
|
55569
|
-
}),
|
|
55570
|
-
/* @__PURE__ */ jsx(ChevronDown, { className: "h-3 w-3 shrink-0 text-foreground-subtle" })
|
|
55571
|
-
]
|
|
55572
|
-
})]
|
|
55980
|
+
function DishwasherHeroCard(props) {
|
|
55981
|
+
return /* @__PURE__ */ jsx(DishwasherPanel, {
|
|
55982
|
+
...props,
|
|
55983
|
+
layout: "full"
|
|
55573
55984
|
});
|
|
55574
55985
|
}
|
|
55575
|
-
|
|
55576
|
-
|
|
55577
|
-
|
|
55578
|
-
|
|
55579
|
-
|
|
55580
|
-
|
|
55581
|
-
|
|
55582
|
-
|
|
55583
|
-
|
|
55584
|
-
|
|
55986
|
+
//#endregion
|
|
55987
|
+
//#region src/composites/device-controls/appliance-control.tsx
|
|
55988
|
+
/**
|
|
55989
|
+
* Appliance card for a `DeviceType.Washer` / `DeviceType.Dryer` device.
|
|
55990
|
+
*
|
|
55991
|
+
* These appliances have no program surface: what is worth showing is whether
|
|
55992
|
+
* the cycle is running (the `running-state` cap), for how long, and what the
|
|
55993
|
+
* appliance draws right now (the `power-meter` cap). Both slices are read
|
|
55994
|
+
* straight from the device; neither is required.
|
|
55995
|
+
* - ApplianceInlineControl (device-list row): the running badge round the
|
|
55996
|
+
* drum icon, plus the live watts when there are any.
|
|
55997
|
+
* - ApplianceHeroCard (device-detail hero): the drum (turning only while a
|
|
55998
|
+
* cycle runs), the state, the phase, the dwell and the power.
|
|
55999
|
+
*
|
|
56000
|
+
* UNKNOWN IS NOT OFF (D393). `running: null` is drawn as "Unknown" and the
|
|
56001
|
+
* drum stays still and unbadged; a missing watt reading is a dash, never
|
|
56002
|
+
* "0 W". A slice that has not landed hides its row instead of faking a value.
|
|
56003
|
+
*/
|
|
56004
|
+
var KEYFRAMES = `
|
|
56005
|
+
@keyframes apl-tumble { to { transform: rotate(360deg) } }
|
|
56006
|
+
.apl-drum-run { animation: apl-tumble 3s linear infinite; }
|
|
56007
|
+
@media (prefers-reduced-motion: reduce) {
|
|
56008
|
+
.apl-drum-run { animation: none !important; }
|
|
55585
56009
|
}
|
|
55586
|
-
|
|
55587
|
-
|
|
55588
|
-
|
|
55589
|
-
|
|
55590
|
-
|
|
55591
|
-
|
|
55592
|
-
|
|
55593
|
-
|
|
55594
|
-
|
|
55595
|
-
|
|
55596
|
-
const rect = el.getBoundingClientRect();
|
|
55597
|
-
if (rect.width <= 0) return value;
|
|
55598
|
-
return climateTargetFromFraction((clientX - rect.left) / rect.width, {
|
|
55599
|
-
min,
|
|
55600
|
-
max
|
|
55601
|
-
}, step);
|
|
55602
|
-
};
|
|
55603
|
-
const onPointerDown = (event) => {
|
|
55604
|
-
if (disabled) return;
|
|
55605
|
-
event.stopPropagation();
|
|
55606
|
-
event.preventDefault();
|
|
55607
|
-
draggingRef.current = true;
|
|
55608
|
-
if (typeof event.currentTarget.setPointerCapture === "function") event.currentTarget.setPointerCapture(event.pointerId);
|
|
55609
|
-
const next = tempAt(event.clientX);
|
|
55610
|
-
setDraft(next);
|
|
55611
|
-
onPreview(next);
|
|
56010
|
+
`;
|
|
56011
|
+
/** Whole watts, or a dash when the appliance has not reported a reading. */
|
|
56012
|
+
function formatWatts(power) {
|
|
56013
|
+
return power === void 0 || !Number.isFinite(power) ? "—" : `${Math.round(power)} W`;
|
|
56014
|
+
}
|
|
56015
|
+
/** The state to a person: running / idle, or why there is none (unknown). */
|
|
56016
|
+
function applianceStateLabel(running, t) {
|
|
56017
|
+
if (running === true) return {
|
|
56018
|
+
label: t("uiLibrary.appliance.running", "Running"),
|
|
56019
|
+
tone: "text-primary"
|
|
55612
56020
|
};
|
|
55613
|
-
|
|
55614
|
-
|
|
55615
|
-
|
|
55616
|
-
const next = tempAt(event.clientX);
|
|
55617
|
-
setDraft(next);
|
|
55618
|
-
onPreview(next);
|
|
56021
|
+
if (running === false) return {
|
|
56022
|
+
label: t("uiLibrary.appliance.idle", "Idle"),
|
|
56023
|
+
tone: "text-foreground"
|
|
55619
56024
|
};
|
|
55620
|
-
|
|
55621
|
-
|
|
55622
|
-
|
|
55623
|
-
draggingRef.current = false;
|
|
55624
|
-
const next = tempAt(event.clientX);
|
|
55625
|
-
setDraft(null);
|
|
55626
|
-
if (event.currentTarget.hasPointerCapture?.(event.pointerId) === true) event.currentTarget.releasePointerCapture(event.pointerId);
|
|
55627
|
-
onCommit(next);
|
|
56025
|
+
return {
|
|
56026
|
+
label: t("uiLibrary.appliance.unknown", "Unknown"),
|
|
56027
|
+
tone: "text-foreground-subtle"
|
|
55628
56028
|
};
|
|
55629
|
-
|
|
55630
|
-
|
|
55631
|
-
|
|
55632
|
-
|
|
55633
|
-
|
|
55634
|
-
|
|
55635
|
-
|
|
55636
|
-
|
|
55637
|
-
|
|
55638
|
-
|
|
55639
|
-
|
|
55640
|
-
event.preventDefault();
|
|
55641
|
-
onCommit(nextClimateTarget(current, -1, {
|
|
55642
|
-
tempStep: step,
|
|
55643
|
-
minTemp: min,
|
|
55644
|
-
maxTemp: max
|
|
55645
|
-
}));
|
|
55646
|
-
} else if (event.key === "Home") {
|
|
55647
|
-
event.preventDefault();
|
|
55648
|
-
onCommit(min);
|
|
55649
|
-
} else if (event.key === "End") {
|
|
55650
|
-
event.preventDefault();
|
|
55651
|
-
onCommit(max);
|
|
55652
|
-
}
|
|
56029
|
+
}
|
|
56030
|
+
function dwellText(running, since, now, t) {
|
|
56031
|
+
if (running !== true) return null;
|
|
56032
|
+
const { duration } = runningStatusParts(running, since, null, now);
|
|
56033
|
+
if (duration === void 0) return null;
|
|
56034
|
+
return "minutes" in duration ? t("uiLibrary.appliance.forMinutes", "for {{count}} min", { count: duration.minutes }) : t("uiLibrary.appliance.forHours", "for {{count}} h", { count: duration.hours });
|
|
56035
|
+
}
|
|
56036
|
+
function useApplianceState(props) {
|
|
56037
|
+
return {
|
|
56038
|
+
running: useDeviceState(props.trpc, props.deviceId, (s) => s.runningState),
|
|
56039
|
+
power: useDeviceState(props.trpc, props.deviceId, (s) => s.powerMeter)
|
|
55653
56040
|
};
|
|
55654
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
55655
|
-
ref: trackRef,
|
|
55656
|
-
role: "slider",
|
|
55657
|
-
"aria-label": label,
|
|
55658
|
-
"aria-valuemin": min,
|
|
55659
|
-
"aria-valuemax": max,
|
|
55660
|
-
"aria-valuenow": shown,
|
|
55661
|
-
"aria-disabled": disabled,
|
|
55662
|
-
tabIndex: disabled ? -1 : 0,
|
|
55663
|
-
onPointerDown,
|
|
55664
|
-
onPointerMove,
|
|
55665
|
-
onPointerUp: endDrag,
|
|
55666
|
-
onPointerCancel: endDrag,
|
|
55667
|
-
onKeyDown,
|
|
55668
|
-
className: cn("mt-1 w-full touch-none select-none py-2", disabled ? "cursor-not-allowed opacity-40" : "cursor-ew-resize"),
|
|
55669
|
-
children: [/* @__PURE__ */ jsxs("div", {
|
|
55670
|
-
className: "relative h-1.5 w-full rounded-full bg-surface-subtle",
|
|
55671
|
-
children: [/* @__PURE__ */ jsx("div", {
|
|
55672
|
-
className: "absolute inset-y-0 left-0 rounded-full",
|
|
55673
|
-
style: {
|
|
55674
|
-
width: pct,
|
|
55675
|
-
background: accent
|
|
55676
|
-
}
|
|
55677
|
-
}), /* @__PURE__ */ jsx("div", {
|
|
55678
|
-
className: "absolute top-1/2 h-3.5 w-3.5 -translate-x-1/2 -translate-y-1/2 rounded-full border-2 border-surface shadow",
|
|
55679
|
-
style: {
|
|
55680
|
-
left: pct,
|
|
55681
|
-
background: accent
|
|
55682
|
-
}
|
|
55683
|
-
})]
|
|
55684
|
-
}), /* @__PURE__ */ jsxs("div", {
|
|
55685
|
-
className: "mt-0.5 flex justify-between text-[9px] tabular-nums text-foreground-subtle",
|
|
55686
|
-
children: [/* @__PURE__ */ jsxs("span", { children: [min, "°"] }), /* @__PURE__ */ jsxs("span", { children: [max, "°"] })]
|
|
55687
|
-
})]
|
|
55688
|
-
});
|
|
55689
56041
|
}
|
|
55690
|
-
/**
|
|
55691
|
-
|
|
55692
|
-
* vent; every active mode renders drifting particles that FALL (cool/dry/auto)
|
|
55693
|
-
* or RISE (heat), with a horizontal sweep overlaid when a swing axis is active.
|
|
55694
|
-
*/
|
|
55695
|
-
function AirflowViz({ mode, accent, periodSec, swaying, forceRising = false }) {
|
|
55696
|
-
const columns = [
|
|
55697
|
-
0,
|
|
55698
|
-
1,
|
|
55699
|
-
2,
|
|
55700
|
-
3,
|
|
55701
|
-
4,
|
|
55702
|
-
5
|
|
55703
|
-
];
|
|
55704
|
-
const rising = forceRising || mode === "heat";
|
|
55705
|
-
const isDroplet = mode === "dry";
|
|
56042
|
+
/** The drum: a ring with a few items in it, turning only while a cycle runs. */
|
|
56043
|
+
function Drum({ running }) {
|
|
55706
56044
|
return /* @__PURE__ */ jsx("div", {
|
|
55707
|
-
"aria-hidden": true,
|
|
55708
|
-
|
|
55709
|
-
|
|
55710
|
-
|
|
55711
|
-
|
|
55712
|
-
|
|
55713
|
-
|
|
55714
|
-
children:
|
|
55715
|
-
|
|
55716
|
-
|
|
55717
|
-
|
|
55718
|
-
|
|
55719
|
-
}) : /* @__PURE__ */ jsx("div", {
|
|
55720
|
-
"data-testid": forceRising ? "climate-heat-rise" : void 0,
|
|
55721
|
-
className: cn("acv-sway-wrap absolute inset-0", swaying && "acv-sway"),
|
|
55722
|
-
style: swaying ? { animation: "acv-sway 2.6s ease-in-out infinite" } : void 0,
|
|
55723
|
-
children: columns.map((i) => {
|
|
55724
|
-
return /* @__PURE__ */ jsx("span", {
|
|
55725
|
-
className: "acv-streak absolute rounded-full",
|
|
55726
|
-
style: {
|
|
55727
|
-
left: `${8 + i * 15}%`,
|
|
55728
|
-
width: isDroplet ? "0.4rem" : "0.3rem",
|
|
55729
|
-
height: isDroplet ? "0.4rem" : "1.9rem",
|
|
55730
|
-
background: accent,
|
|
55731
|
-
boxShadow: `0 0 6px ${accent}`,
|
|
55732
|
-
animationName: rising ? "acv-rise" : "acv-fall",
|
|
55733
|
-
animationTimingFunction: "linear",
|
|
55734
|
-
animationIterationCount: "infinite",
|
|
55735
|
-
animationDuration: `${periodSec}s`,
|
|
55736
|
-
animationDelay: `${i % 3 * (periodSec / 3) + i * .05}s`
|
|
55737
|
-
}
|
|
55738
|
-
}, i);
|
|
55739
|
-
})
|
|
56045
|
+
"aria-hidden": "true",
|
|
56046
|
+
"data-testid": "appliance-drum",
|
|
56047
|
+
"data-running": running === true ? "running" : running === false ? "idle" : "unknown",
|
|
56048
|
+
className: "relative flex h-28 w-28 shrink-0 items-center justify-center rounded-full border-2 border-border bg-surface-hover",
|
|
56049
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
56050
|
+
className: cn("relative h-20 w-20 rounded-full border-2", running === true ? "apl-drum-run border-primary" : "border-border"),
|
|
56051
|
+
"data-testid": "appliance-drum-ring",
|
|
56052
|
+
children: [
|
|
56053
|
+
/* @__PURE__ */ jsx("span", { className: "absolute left-2 top-4 h-3 w-3 rounded-full bg-primary/40" }),
|
|
56054
|
+
/* @__PURE__ */ jsx("span", { className: "absolute bottom-3 right-3 h-4 w-4 rounded-full bg-info/40" }),
|
|
56055
|
+
/* @__PURE__ */ jsx("span", { className: "absolute bottom-4 left-4 h-2.5 w-2.5 rounded-full bg-foreground-subtle/40" })
|
|
56056
|
+
]
|
|
55740
56057
|
})
|
|
55741
56058
|
});
|
|
55742
56059
|
}
|
|
55743
|
-
|
|
55744
|
-
|
|
55745
|
-
|
|
55746
|
-
|
|
55747
|
-
|
|
55748
|
-
|
|
56060
|
+
function ApplianceHeroCard(props) {
|
|
56061
|
+
const t = useUiText();
|
|
56062
|
+
const { running, power } = useApplianceState(props);
|
|
56063
|
+
const state = running?.running ?? null;
|
|
56064
|
+
const meta = applianceStateLabel(state, t);
|
|
56065
|
+
const phase = running?.phase?.trim() ?? "";
|
|
56066
|
+
const dwell = running === void 0 ? null : dwellText(state, running.since, Date.now(), t);
|
|
56067
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
56068
|
+
className: "flex items-center gap-4 rounded-lg border border-border bg-surface p-4",
|
|
55749
56069
|
children: [
|
|
55750
|
-
|
|
55751
|
-
|
|
55752
|
-
|
|
55753
|
-
|
|
55754
|
-
|
|
55755
|
-
|
|
55756
|
-
|
|
55757
|
-
|
|
56070
|
+
/* @__PURE__ */ jsx("style", { children: KEYFRAMES }),
|
|
56071
|
+
/* @__PURE__ */ jsx(Drum, { running: state }),
|
|
56072
|
+
/* @__PURE__ */ jsxs("div", {
|
|
56073
|
+
className: "flex min-w-0 flex-1 flex-col gap-2",
|
|
56074
|
+
children: [
|
|
56075
|
+
/* @__PURE__ */ jsxs("div", {
|
|
56076
|
+
className: "flex flex-wrap items-baseline gap-x-2",
|
|
56077
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
56078
|
+
"data-testid": "appliance-state",
|
|
56079
|
+
className: cn("text-3xl font-semibold", meta.tone),
|
|
56080
|
+
children: meta.label
|
|
56081
|
+
}), dwell !== null && /* @__PURE__ */ jsx("span", {
|
|
56082
|
+
className: "text-sm tabular-nums text-foreground-subtle",
|
|
56083
|
+
children: dwell
|
|
56084
|
+
})]
|
|
56085
|
+
}),
|
|
56086
|
+
phase !== "" && state !== null && /* @__PURE__ */ jsx("span", {
|
|
56087
|
+
className: "text-sm text-foreground-subtle",
|
|
56088
|
+
children: phase
|
|
56089
|
+
}),
|
|
56090
|
+
power !== void 0 && /* @__PURE__ */ jsxs("span", {
|
|
56091
|
+
"data-testid": "appliance-power",
|
|
56092
|
+
className: "inline-flex items-center gap-1 text-sm tabular-nums text-foreground-muted",
|
|
56093
|
+
title: power.power === void 0 ? t("uiLibrary.appliance.powerUnknown", "Power unknown") : void 0,
|
|
56094
|
+
children: [/* @__PURE__ */ jsx(Zap, {
|
|
56095
|
+
className: "h-3.5 w-3.5",
|
|
56096
|
+
"aria-hidden": true
|
|
56097
|
+
}), formatWatts(power.power)]
|
|
56098
|
+
})
|
|
56099
|
+
]
|
|
56100
|
+
})
|
|
56101
|
+
]
|
|
55758
56102
|
});
|
|
55759
56103
|
}
|
|
55760
|
-
|
|
55761
|
-
|
|
55762
|
-
return /* @__PURE__ */ jsxs("
|
|
55763
|
-
|
|
55764
|
-
|
|
55765
|
-
|
|
55766
|
-
|
|
55767
|
-
|
|
55768
|
-
|
|
55769
|
-
|
|
55770
|
-
},
|
|
55771
|
-
|
|
55772
|
-
|
|
55773
|
-
0,
|
|
55774
|
-
120,
|
|
55775
|
-
240
|
|
55776
|
-
].map((deg) => /* @__PURE__ */ jsx("path", {
|
|
55777
|
-
d: "M50 50 C 58 30, 78 26, 84 12 C 66 20, 54 34, 50 50 Z",
|
|
55778
|
-
fill: color,
|
|
55779
|
-
opacity: .85,
|
|
55780
|
-
transform: `rotate(${deg} 50 50)`
|
|
55781
|
-
}, deg)), /* @__PURE__ */ jsx("circle", {
|
|
55782
|
-
cx: "50",
|
|
55783
|
-
cy: "50",
|
|
55784
|
-
r: "7",
|
|
55785
|
-
fill: color
|
|
56104
|
+
function ApplianceInlineControl(props) {
|
|
56105
|
+
const { running, power } = useApplianceState(props);
|
|
56106
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
56107
|
+
className: "inline-flex items-center gap-1.5 max-w-full",
|
|
56108
|
+
children: [/* @__PURE__ */ jsx(RunningBadge, {
|
|
56109
|
+
running: running?.running ?? null,
|
|
56110
|
+
children: /* @__PURE__ */ jsx(WashingMachine, {
|
|
56111
|
+
className: "h-4 w-4 text-foreground-muted",
|
|
56112
|
+
"aria-hidden": true
|
|
56113
|
+
})
|
|
56114
|
+
}), power !== void 0 && /* @__PURE__ */ jsx("span", {
|
|
56115
|
+
className: "text-xs tabular-nums text-foreground-subtle",
|
|
56116
|
+
children: formatWatts(power.power)
|
|
55786
56117
|
})]
|
|
55787
56118
|
});
|
|
55788
56119
|
}
|
|
55789
|
-
|
|
55790
|
-
|
|
55791
|
-
function
|
|
56120
|
+
//#endregion
|
|
56121
|
+
//#region src/composites/device-controls/heating-valve-readout.tsx
|
|
56122
|
+
function formatHeatingValvePosition(position) {
|
|
56123
|
+
return position !== null ? `${position}%` : "—";
|
|
56124
|
+
}
|
|
56125
|
+
function HeatingValveReadout({ trpc, deviceId, layout }) {
|
|
55792
56126
|
const t = useUiText();
|
|
55793
|
-
const
|
|
55794
|
-
|
|
55795
|
-
|
|
55796
|
-
|
|
55797
|
-
|
|
55798
|
-
|
|
55799
|
-
|
|
55800
|
-
|
|
55801
|
-
|
|
55802
|
-
|
|
55803
|
-
|
|
55804
|
-
|
|
55805
|
-
children:
|
|
55806
|
-
|
|
55807
|
-
|
|
55808
|
-
|
|
55809
|
-
}),
|
|
56127
|
+
const { cap, slice } = useDeviceCapability({
|
|
56128
|
+
trpc,
|
|
56129
|
+
deviceId,
|
|
56130
|
+
cap: (d) => d.heatingValve,
|
|
56131
|
+
slice: (d) => d.state.heatingValve
|
|
56132
|
+
});
|
|
56133
|
+
if (cap === void 0 || slice === void 0) return null;
|
|
56134
|
+
const label = t("uiLibrary.heatingValveReadout.valve", "Valve");
|
|
56135
|
+
const value = formatHeatingValvePosition(slice.position);
|
|
56136
|
+
if (layout === "compact") return /* @__PURE__ */ jsx("span", {
|
|
56137
|
+
className: "inline-flex items-center text-xs tabular-nums text-foreground-subtle",
|
|
56138
|
+
"aria-label": `${label} ${value}`,
|
|
56139
|
+
children: value
|
|
56140
|
+
});
|
|
56141
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
56142
|
+
className: "flex items-center gap-2 text-xs tabular-nums text-foreground-subtle",
|
|
56143
|
+
children: [/* @__PURE__ */ jsx("span", { children: label }), /* @__PURE__ */ jsx("span", {
|
|
56144
|
+
className: "font-medium text-foreground",
|
|
56145
|
+
children: value
|
|
56146
|
+
})]
|
|
55810
56147
|
});
|
|
55811
56148
|
}
|
|
55812
56149
|
//#endregion
|
|
@@ -57898,6 +58235,10 @@ var CONTROL_KIND_COMPONENTS = {
|
|
|
57898
58235
|
InlineControl: PetFountainInlineControl,
|
|
57899
58236
|
HeroCard: PetFountainHeroCard
|
|
57900
58237
|
},
|
|
58238
|
+
heater: {
|
|
58239
|
+
InlineControl: HeaterInlineControl,
|
|
58240
|
+
HeroCard: HeaterHeroCard
|
|
58241
|
+
},
|
|
57901
58242
|
dishwasher: {
|
|
57902
58243
|
InlineControl: DishwasherInlineControl,
|
|
57903
58244
|
HeroCard: DishwasherHeroCard
|
|
@@ -57985,6 +58326,7 @@ var CONTROL_FILLS = {
|
|
|
57985
58326
|
[DeviceType.Image]: false,
|
|
57986
58327
|
[DeviceType.PetFeeder]: false,
|
|
57987
58328
|
[DeviceType.PetFountain]: false,
|
|
58329
|
+
[DeviceType.Heater]: false,
|
|
57988
58330
|
[DeviceType.Dishwasher]: false,
|
|
57989
58331
|
[DeviceType.Washer]: false,
|
|
57990
58332
|
[DeviceType.Dryer]: false
|
|
@@ -73399,12 +73741,12 @@ var statusIcons = {
|
|
|
73399
73741
|
* Render inside `<Suspense>` at all call sites. */
|
|
73400
73742
|
var MaskShapeCanvas = lazy(() => import("./MaskShapeCanvas-C9cJlxvG.js").then((m) => ({ default: m.MaskShapeCanvas })));
|
|
73401
73743
|
/** Lazy-wrapped `MotionZonesSettings` — code-split off the main bundle. */
|
|
73402
|
-
var MotionZonesSettings = lazy(() => import("./MotionZonesSettings-
|
|
73744
|
+
var MotionZonesSettings = lazy(() => import("./MotionZonesSettings-Zcfa5c9l.js").then((m) => ({ default: m.MotionZonesSettings })));
|
|
73403
73745
|
/** Lazy-wrapped `SceneMonitorEditor` — code-split off the main bundle for the
|
|
73404
73746
|
* same reason: it mounts `MaskShapeCanvas`, which chains react-konva. Render
|
|
73405
73747
|
* inside `<Suspense>`; the admin-ui `/scenes` dialog is its only caller. */
|
|
73406
|
-
var SceneMonitorEditor = lazy(() => import("./SceneMonitorEditor-
|
|
73748
|
+
var SceneMonitorEditor = lazy(() => import("./SceneMonitorEditor-C8YXVzYI.js").then((m) => ({ default: m.SceneMonitorEditor })));
|
|
73407
73749
|
/** Lazy-wrapped `PrivacyMaskSettings` — code-split off the main bundle. */
|
|
73408
|
-
var PrivacyMaskSettings = lazy(() => import("./PrivacyMaskSettings-
|
|
73750
|
+
var PrivacyMaskSettings = lazy(() => import("./PrivacyMaskSettings-B_X42yzN.js").then((m) => ({ default: m.PrivacyMaskSettings })));
|
|
73409
73751
|
//#endregion
|
|
73410
|
-
export { Shield as $, CloudRain as $n, LockOpen as $t, Trash2 as A, AddProviderEntryDialog, AddonGlobalSettingsForm, AdminLinkQuickAction, AgentStepEditor, AlarmHeroCard, AlarmInlineControl as AlarmPanelInlineControl, Flame as An, AppShell, Bone as Ar, ArcKnob, Pencil as At, AudioClassificationList, AudioLevelWaveform, AudioWaveform, AutomationHeroCard, AutomationInlineControl, AutotrackSection, Sun as B, BATTERY_BADGE_LOW_KEY, BATTERY_BADGE_NORMAL_KEY, BINARY_BATTERY_LOW_BELOW, BOOLEAN_STATES, BTN_COMPACT, BTN_COMPACT_DANGER, BTN_COMPACT_PRIMARY, BTN_COMPACT_WARNING, BackToStepsButton, Badge, BarSeries, BatteryBadge, Droplet as Bn, BottomSheet, BatteryFull as Br, Breadcrumb, BrightnessPanel, BrokerPickerSlotProvider, MousePointerClick as Bt, Button, ButtonControl, ButtonHeroCard, Unlink2 as C, CENTER, CHART_SERIES_TOKENS, CHIP_ACTIVE, CHIP_BASE, CHIP_INACTIVE, CLASS_COLORS, COLUMN_BREAKPOINT_CLASS, COLUMN_PRIORITY, COMMIT_DEDUPE_TOLERANCE_MS, COMMIT_DEDUPE_WINDOW_MS, CONSUMABLE_LOW_PERCENT, CONTROL_CAP_NAMES, CONTROL_FILLS, CameraStreamPlayer, Card, ChartFrame, ChartPlaceholder, ChartSwatch, ChartWindowToggle, Checkbox, ChildSectionAccordion, ClimatePanel, GraduationCap as Cn, CodeBlock, CollapsibleCard, ConfigFormBuilder, FormField as ConfigFormField, ConfigNotificationTargetMultiSelectFieldView, ConfigNotificationTargetSelectFieldView, ConfigSchemaField, ConfirmActionButton, ConfirmDialogProvider, ConsumableLevelBadge, ConsumablesPanel, ContainerChildrenProvider, ContainerPrimaryHero, ControlColumn, ControlHeroCard, ControlInlineControl, ControlPanel, CopyButton, CoverHeroCard, CoverInlineControl, CoverPanel, Car as Cr, Plug as Ct, CustomFieldRenderersProvider, TriangleAlert as D, DATA_RECORDS_KIND_PARAM, DATA_RECORDS_OWNER_PARAM, DATA_RECORD_FACET_GROUPS, DEFAULT_COLOR, DEFAULT_PAGINATION_LABELS, DEFAULT_UNIT_PREFERENCES, DEVICE_COLUMNS, DEVICE_EXPORT_PAGE_SIZE_KEY, DEVICE_LIST_PAGE_SIZE_KEY, DEVICE_LIST_PAGE_SIZE_OPTIONS, DEVICE_NAME_FORMS, DEVICE_NAME_JOIN, DEVICE_PICKER_GROUP_STORAGE_KEY, DEVICE_ROLE_META, DEVICE_ROLE_NOUNS, DEVICE_TYPE_CONTROL, DEVICE_TYPE_META, DEVICE_TYPE_NOUNS, DataRecordsHub, DataTable, DataTableFilterBar, DataTablePager, DetectionCanvas, DetectionOverlay, DetectionResultTree, DevShell, DeviceActivityPanel, DeviceBatchToolbar, DeviceCard, DeviceContextProvider, DeviceExportPanel, DeviceExportSetup, DeviceFilterBar, DeviceFleetFromServer, DeviceFleetProvider, DeviceGrid, DeviceHistoryView, DeviceItem, DeviceList, DeviceMultiSelectField, DeviceName, DevicePicker, DeviceQuickDetailProvider, DeviceSelectField, DeviceSelectorPicker, DeviceStepMatrix, DevicesFailedLine, DevicesLoadingLine, DevicesWidenWarning, Dialog, DialogBody, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, DisclosureChevron, DiscoveryPanel, DisplayPaletteProvider, Footprints as Dn, DoorbellRecentPanel, Bug as Dr, Dropdown, DropdownContent, DropdownItem, DropdownTrigger, Pipette as Dt, DummyHeroCard, DummyInline, Truck as E, EMPTY_DATA_TABLE_FILTER, EMPTY_HISTORY_PANELS, EVENT_KIND_ICONS, EmptyState, Funnel as En, EndpointResultsCard, EndpointTestCard, EntryJsonSchemaForm, Bus as Er, ErrorBox, Plane as Et, EventKindGlyph, EventStream, ExtensionsPanel, Timer as F, FALLBACK_SCOPE, FAST_ICON_GLYPHS, FILL, FLEET_LIST_GC_TIME_MS, FLEET_LIST_QUERY_KEY, FLEET_LIST_STALE_TIME_MS, FanHeroCard, FanInlineControl, FanPanel, FileInput, FilterBar, FloatingEventStream, FloatingLogStream, FloatingPanel, EyeOff as Fn, FormField$1 as FormField, BellRing as Fr, Navigation as Ft, Sparkles as G, GAP_INTERVAL_FACTOR, GRID_GAP, GRID_PAIRED, GRID_QUICK_STATS, GateBadge, GateControl, Database as Gn, ArrowUpToLine as Gr, GripTrack, GroupedModelSelector, GroupedTilePicker, Mic as Gt, Star as H, HISTORY_PAGE_PATH, HISTORY_PANELS_NAMESPACE, HISTORY_SELECTION_MAX, HISTORY_WINDOW_IDS, HISTORY_WINDOW_MS, HOST_WIDGETS, HUB_SESSION_RUN_MS, HistoryChart, HistoryWindowBar, HlsVideo, DoorOpen as Hn, HotkeyProvider, HotkeyScope, HoverZoomImage, Ban as Hr, MonitorPlay as Ht, HubSessionTestCard, HumidifierHeroCard, HumidifierInlineControl, Thermometer as I, INPUT_COMPACT, INPUT_SHELL, IconAction, IconButton, IconPicker, ImageHeroCard, ImageInlineControl, ImageSelector, ExternalLink as In, InferenceConfigSelector, Input, Battery as Ir, Music as It, ItemFormDialog, SlidersHorizontal as J, Copy as Jn, ArrowDown as Jr, Megaphone as Jt, Snowflake as K, KebabMenu, KeyValueList, Crosshair as Kn, ArrowRight as Kr, MessageSquare as Kt, Target as L, LIST_ROW, Label, LawnMowerHeroCard, LawnMowerInlineControl, LayeredSettingsForm, LightHeroCard, LightInlineControl, Eraser as Ln, LockHeroCard, LockInlineControl, LockPanel, LogStream, LoginForm, BatteryWarning as Lr, Move as Lt, Tractor as M, MEDIA_GRID, MINUTES_PER_DAY, MODE_COLOR, MaskShapeCanvas, MediaCard, MediaGrid, MediaPlayerHeroCard, MediaPlayerInlineControl, MediaPlayerPanel, Feather as Mn, MobileDrawer, ModelPicker, MotionZonesSettings, Bird as Mr, Pause as Mt, ToggleRight as N, NAVIGATION_DRIVE_INTERVAL_MS, NODE_COLOR_IDS, NatResultCard, NavigationPanel, NetworkLinkBadge, Fan as Nn, NodeMultiSelectField, NodePicker, NodeSelectField, NotificationTargetSelectField, NotificationTargetsField, Bike as Nr, Package as Nt, TrendingDown as O, OCCUPANCY_KEY, OPTION_SELECT_SEARCH_MIN_OPTIONS, OfflineBadge, Flashlight as On, OptionSelect, Box as Or, Pin as Ot, ToggleLeft as P, PAGE_SIZE_ALL, PHASE_CONFIG, PICKER_CHIP_LIMIT, PICKER_DEFAULT_GROUP_BY, PICKER_GROUP_BY_MODES, PICKER_GROUP_COLLAPSE_AT, PICKER_NONE_KEY, PICKER_NOUN_PLURAL, PICKER_NO_FILTERS, PICKER_PAGE_SIZE, PICKER_SEARCH_DEBOUNCE_MS, PICKER_WINDOW, PRIORITY, PTZOverlay, PageHeader, PageShell, PageSizeSelect, Pagination, PasswordInput, PhaseIcon, PipelineBuilder, PipelineRuntimeSelector, PipelineStep, PlaceholderChipField, PlayerOverlaysProvider, Eye as Pn, Popover, PopoverContent, PopoverRowAction, PopoverTrigger, Bell as Pr, PrimaryChildPicker, PrivacyMaskSettings, ProviderBadge, ProviderEntryPills, Network as Pt, PtzPanel, Ship as Q, CloudSnow as Qn, Activity as Qr, QrCode, Lock as Qt, QuantityValueInput, Tag as R, RECONNECT_POLICY, RECORDED_PLAYBACK_MODES, RESOLUTION_BUCKET_MS, RIGHT, ROI_AREA_WARN_FRACTION, ROLE_DESCRIPTOR, ROOT_DETECTOR_STEP_ID, RadialGauge, Radio, RecordEntriesPanel, RecordedPlaybackProvider, RecordingPanel, ResponseLog, RetrainReviewBadge, EllipsisVertical as Rn, RoleDisplayDefaultsFromServer, RoleDisplayDefaultsProvider, RoleNodePill, RootModelSourceControl, RootSuppliedModelNote, BatteryMedium as Rr, MoveVertical as Rt, RunReport, RunningBadge, RunningStatusLine, Upload as S, SCENE_CAPTURE_VARIANTS, SECRET_MASK_PLACEHOLDER, SECRET_REVEAL_MS, 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, STEP_DOCK_WIDTH_PX, SUBJECT_PATH_DWELL_EPS, SUBJECT_PATH_FULL_FRAME_COVERAGE, SUBJECT_PATH_MAX_POINTS, SceneMonitorEditor, ScopePicker, ScriptHeroCard, ScriptInlineControl, ScrollArea, SecretFieldControl, SecretRevealProvider, SectionCard, SectionToolbar, SectionedPage, SegmentedChoice, Select, SelectedChip, SemanticBadge, SendFrameToTrainingButton, SensorHeroCard, SensorInlineControl, SensorValueAtom, Separator, SettingRow, Sidebar, SidebarItem, Skeleton, SlideToggle, Slider, Grid2x2 as Sn, SnapshotButton, SortHeaderButton, Sparkline, Cast as Sr, PowerOff as St, StableTabPanel, StatCard, StateTimeline, StateValuesStream, StatusBadge, StepDetailDock, StepInspectorPanel, StepModelRow, StepTimings, Stepper, StorageRecordsPanel, StreamBrokerSelector, StreamDebugOverlay, StreamPanel, Switch, SwitchHeroCard, SwitchInlineControl, SwitchPanel, SystemProvider, Type as T, TABLE_SCROLL_MAX_H, TEMPERATURE_SCALES, TEXT_FIELD_LABEL, TEXT_HINT, TEXT_METRIC, TEXT_SECTION_LABEL, TEXT_VALUE, TIMEZONES, Tabs, TabsContent, TabsList, TabsTrigger, TapToggle, Textarea, ThemeProvider, ThermostatHeroCard, ThermostatInlineControl, TimeSeriesChart, TimelineSlider, TimezoneSelector, Gamepad2 as Tn, Tooltip, TooltipContent, TooltipTrigger, Cable as Tr, TrainingBaseModelPicker, TrainingCollectionPicker, Play as Tt, Square as U, UNIT_PREFERENCES_NAMESPACE, UiTextProvider, UiTrans, DoorClosed as Un, UnitPicker, UnitPreferencesFromServer, UnitPreferencesProvider, Baby as Ur, Minus as Ut, SunMedium as V, VacuumHeroCard, VacuumInlineControl, ValueReadout, ValveHeroCard, ValveInlineControl, VersionBadge, ViewSwitch, Download as Vn, VodPlaybackProvider, Bath as Vr, Moon as Vt, Sprout as W, WaterHeaterHeroCard, WaterHeaterInlineControl, WeatherHeroCard, WeatherInlineControl, WidgetMetricCard, WidgetPanel, WidgetRegistryProvider, WidgetSlot, Dog as Wn, ArrowUp as Wr, Minimize2 as Wt, SkipBack as X, Cloud as Xn, AlarmSmoke as Xr, MapPin as Xt, SkipForward as Y, Cog as Yn, ArrowDownToLine as Yr, Maximize2 as Yt, Siren as Z, CloudSun as Zn, ZoneEditingProvider, AirVent as Zr, Mail as Zt, Vibrate as _, Hash as _n, ChevronLeft as _r, RadioTower as _t, Wrench as a, acceleratorLabel, acceleratorShortLabel, agentColumnKey, alignSeries, allDeviceTypeFilterOptions, Lightbulb as an, anchorNow, applyFleetQueryDefaults, applyPickerFilters, CircleStop as ar, ariaSortForColumn, assignNodeColorId, Server as at, axisTicks, User as b, badgeFor, binaryBatteryIsLow, bindsToModel, Hammer as bn, booleanLabels, boundsInPicked, ChartLine as br, Puzzle as bt, bucketTotals, buildColorByNodeId, buildDataRecordRows, buildPeerConnectionConfig, buildStepTreeFromSchema, buildSubjectPath, buildTimeSeriesModel, Wifi as c, catalogHasDraft, chartKeys, chartSeriesStyle, childEntityId, childListName, chipOverflow, chunk, clampMinute, classifyAddressScope, classifyCapability, classifySessionVerdict, clearPickerGroup, clusterRootModelIds, cn, colorIdForNode, columnsForContext, compareSrflxMappings, computePageButtons, consumableItemLevel, consumableLevelBarClass, consumableLevelLabel, consumableLevelVariant, containerChildToRef, countableDevices, coverHighlight, coverageLine, CirclePause as cr, createAddonI18n, createSharedContext, createTheme, Scan as ct, currentAddonLanguage, cursorFractionFor, WifiLow as d, darkColors, dataRecordContents, dataRecordKey, dataRecordSearchText, dataRecordType, dataTableFacetGroups, dataTableFacets, decodeCustomWindow, decodeSeriesRef, defaultAxisSpec, defaultOfField, defaultSelectClusterRoots, defaultSingleClusterRoot, defaultTheme, defaultUiText, deriveDeviceKind, deriveWebrtcDebugStats, describeDeviceSelector, detectPlatform, deviceIntegrationResolver, deviceListStateOf, deviceMatchesFilter, deviceNameNouns, deviceOptionLabel, deviceRoleMeta, deviceRoleMetaOf, deviceTypeLabel, deviceTypeMeta, deviceTypeMetaOf, devicesToOptions, Inbox as dn, dockBox, CircleCheckBig as dr, draftFromQuery, Router as dt, effectivePageSize, emptyDevicesWidens, emptySessionRun, LocateFixed as en, encodeCustomWindow, encodeSeriesRef, energyBuckets, ensureMfHostInit, CloudLightning as er, ShieldOff as et, eventKindLabel, WifiHigh as f, filterDataTableRows, filterDeviceOptions, filterOccupancyLines, filterOptions as filterOptionSelectOptions, filterPickerDevices, finalizeSessionRun, findTimezone, flattenPickerGrouping, flattenPickerRows, fleetViewOf, Image as fn, foldDeviceName, formatChartBytes, formatChartNumber, formatChartValue, formatControlDateTime, formatDeviceName, formatLastSeen, formatNumeric, formatSettingValue, formatSpan, formatTimeLabel, CircleAlert as fr, freezeVerdict, Route as ft, fuzzyMatch, Volume2 as g, gapThresholdMs, getClassColor, getPhaseVisual, Heater as gn, ChevronRight as gr, groupAgentColumns, groupChildrenByLayout, groupDeviceSeries, groupPickerDevices, groupPickerDevicesBy, Radio$1 as gt, VolumeX as h, hardwareLabel, historyPageHref, History as hn, ChevronUp as hr, RefreshCw as ht, hubOrigin, hubPath, hubUrl, hubWsUrl, humanDuration, humanizeName, humidifierTint, X as i, iconGlyphsFailed, iconGlyphsLoaded, Link2 as in, indexDeviceNames, initialScrubState, insertAtSelection, CircleX as ir, isAbsentProvider, isByteUnit, isConsumableLevelField, isDataTableFilterActive, isDeviceNameStock, isDrawableSubjectPath, isFieldVisible, isGroupExpanded, isHistoryWindowId, isKeychainFieldValue, isModelScopedField, isPickableUnit, isRedactedSecret, isRefusal, isSecretField, isValueField, Settings as it, TrainFront as j, Film as jn, Blinds as jr, PawPrint as jt, TrendingUp as k, FlashlightOff as kn, Bot as kr, Phone as kt, WifiZero as l, lawnMowerActivityMeta, lightColors, linePoints, Laugh as ln, loadIconGlyphs, loadRemoteBundle, CircleDot as lr, Save as lt, lucideExportName, WashingMachine as m, makeScrubBridge, mapRootDetectorPlacements, matchesCombo, mergeSecretForSubmit, metadataEntries, metadataString, minuteFromPointer, House as mn, mountAddonPage, mountPath, ChevronsDownUp as mr, RotateCcw as mt, ZoomIn as n, nextGridPosition, nextReconnectAction, nextSort, nextSortDirection, nextTableSort, niceMax, niceRange, List as nn, nodeColorClass, nodeSoftBgClass, nodeTextColorClass, normalizeForSearch, normalizeLanguage, normalizeSelection, nounSpecFor, Clock as nr, ShieldAlert as nt, Workflow as o, occupancyFacets, occupancyLines, offListSelections, Leaf as on, openTopLayer, optionSearchText as optionSelectSearchText, CircleQuestionMark as or, orphanDeviceLabel, Search as ot, outsideBounds, overrideEntityIdFromLink, Waves as p, pageRows, pageSizeLabel, paginateRows, parentDetailOf, parseCapKey, parseCombo, parseConsumableLevel, parseIceCandidate, parsePickerGroupBy, parseProducerKey, parseRecordedServerMessage, partitionSelected as partitionOptionSelectSelected, partitionSuggested, pickerFacetFilterShown, pickerFacetKey, pickerFacetOptions, pickerFiltersActive, pickerGroupKey, pickerHiddenSelectedCount, pickerLocationKey, pickerQueryTokens, pickerRowFacts, pickerSearchText, pickerZoneFilterSuspended, pinnedStreamChoices, placePopover, ImageOff as pn, ChevronsUpDown as pr, preferenceForQuantity, previousWindow, projectSubjectPath, providerIcons, RotateCw as pt, Smartphone as q, Cpu as qn, ArrowLeft as qr, Menu as qt, quantityStoredUnit, quantityUnitChoices, Zap as r, readHistory, readHistoryPanels, readItemId, readStoredGroupBy, readUnitPreferences, reduceSessionRun, registerAddonBundle, renderMarkup, renderTagged, resetHubMountForTests, resetPickerFilters, resolveContainerPrimary, resolveControlAlign, resolveDeviceControl, resolveDeviceIntegration, resolveDeviceLabel, resolveDisplayIcon, resolveEffectiveDefaultModel, resolveEffectiveStepModel, resolveEventKindIcon, resolveHistoryWindow, resolveSearchable as resolveOptionSelectSearchable, resolveParentNames, resolvePrimaryChild, resolveSelectedDevices, resolveSensorDisplay, resolveStepDefaultModel, retrainReviewBadgeLook, ListChecks as rn, roiTooLarge, rootSourceState, routerBasename, Clapperboard as rr, Share2 as rt, runningDurationSince, runningStatusParts, Wind as s, sameDeviceName, sameLocationSuggestions, scrubReducer, searchSteps, secretDisplayValue, secretSubmitValue, segmentsFromChanges, selectPickerGroup, selectedDeviceOptions, serializeRecordedCommand, seriesRefId, settingsModelIdFor, sharedGapSpans, shiftPoints, shouldCommit, shouldEmit, shouldShowAddNewFooter, shouldShowUseQueryRow, shouldUseSingleNode, showsNoCamerasHint, LayoutGrid as sn, snapMinute, sortRows, sortRowsByColumn, CirclePlus as sr, ScrollText as st, stackBuckets, stackSeries, stateAt, stateRow, stateStyle, statusIcons, statusLine, stepFieldDomId, stepHasModelForFormat, stepLocalFields, stepModelOptions, storedToPicked, stripDeviceParentPrefix, stripParentNamePrefix, subjectPathSampleFromBox, subjectPathSvgPoints, summarizeHubCandidates, swatchFillClass, swatchLineClass, ZoomOut as t, tabForSelector, themeToCss, themeToRootCss, timeInState, LoaderCircle as tn, toStationaryOverlayBox, toggleDataTableFacet, toggleDataTableGroupFacet, togglePickerDevice, togglePickerKey, CloudFog as tr, trainingRefusalText, translateAddonKey, trpc, ShieldCheck as tt, typeLabel, typedToStored, WifiOff as u, Info as un, unitAxes, CircleCheck as ur, useAccessoriesGetStatus, useAccessoriesSetChildHidden, useAccountUnitPreferences, useActionSourceListActions, useActionSourceRunAction, useActionSourceStopAction, useActionsCreate, useActionsDelete, useActionsGet, useActionsGetLinks, useActionsGetTraces, useActionsList, useActionsListForCamera, useActionsRun, useActionsSetLinks, useActionsStop, useActionsUpdate, useAddonPagesListPages, useAddonSettingsGetDeclaredSettingsKeys, useAddonSettingsGetDeviceSettings, useAddonSettingsGetGlobalSettings, useAddonSettingsGetIntegrationFormSchema, useAddonSettingsGetIntegrationSettings, useAddonSettingsUnsetStoredSettingsKeys, useAddonSettingsUpdateDeviceSettings, useAddonSettingsUpdateGlobalSettings, useAddonT, useAddonWidgetsListWidgets, useAddonsApplyAutoUpdateToAll, useAddonsCancelJob, useAddonsCustom, useAddonsForceRefresh, useAddonsGetAddonAutoUpdate, useAddonsGetAutoUpdateSettings, useAddonsGetJob, useAddonsGetLastRestart, useAddonsGetLogs, useAddonsGetPackageDocs, useAddonsGetVersions, useAddonsInstallPackage, useAddonsList, useAddonsListCapabilityProviders, useAddonsListFrameworkPackages, useAddonsListInstallations, useAddonsListJobs, useAddonsListPackages, useAddonsListUpdates, 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, useBackupCheckBackupKey, useBackupDelete, useBackupDeleteSchedule, useBackupDisableEncryption, useBackupGetEncryption, useBackupGetEntries, useBackupList, useBackupListArchives, useBackupListAvailableDatabases, useBackupListDestinations, useBackupListLocations, useBackupListRuns, useBackupListSchedules, useBackupPreviewSchedule, useBackupRestore, useBackupSetupEncryption, useBackupTrigger, useBackupUpsertDestinationPolicy, useBackupUpsertSchedule, useBatteryGetStatus, useBatteryWakeForStream, useBinaryGetStatus, useBrightnessGetStatus, useBrightnessSetBrightness, useBrokerAdd, useBrokerGet, useBrokerGetBrokerConfig, useBrokerGetSettings, useBrokerGetSettingsSchema, useBrokerGetState, useBrokerGetStatus, useBrokerList, useBrokerListProviders, useBrokerPickerSlot, useBrokerPublish, useBrokerRemove, useBrokerSetSettings, useBrokerSubscribe, useBrokerTestConnection, useBrokerTestSettings, useBrokerUnsubscribe, useButtonPress, useCalendarsGetPreferences, useCalendarsListCalendars, useCalendarsListEvents, useCalendarsSetCalendarPreference, useCameraCredentialsGetCredentials, useCameraCredentialsGetStatus, useCameraGridLayoutApplyDeviceSettingsPatch, useCameraGridLayoutGetDeviceLiveContribution, useCameraGridLayoutGetDeviceSettingsContribution, useCameraGridLayoutGetLayout, useCameraGridLayoutSaveLayout, useCameraPipelineConfigApplyDeviceSettingsPatch, useCameraPipelineConfigGetDeviceLiveContribution, useCameraPipelineConfigGetDeviceSettingsContribution, useCameraStreamsGetBrokerStreams, useCameraStreamsGetCameraStreams, useCameraStreamsGetProfileRtspEntries, useCameraStreamsGetRtspEntries, useCameraStreamsPickStream, useCapabilityPresence, useCarbonMonoxideGetStatus, useClassPainter, 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, useCoreBlocksCreateComposition, useCoreBlocksDelete, useCoreBlocksGet, useCoreBlocksGetAutomationRunState, useCoreBlocksGetBlockSettings, useCoreBlocksGetComposition, useCoreBlocksGetCustomization, useCoreBlocksGetTraces, useCoreBlocksGetTypeDefs, useCoreBlocksList, useCoreBlocksListComposableCaps, useCoreBlocksListCompositions, useCoreBlocksMigrateRawSecrets, useCoreBlocksReportAutomationRun, useCoreBlocksRestart, useCoreBlocksSetEnabled, useCoreBlocksUpdate, useCoreBlocksUpdateBlockSettings, useCoreBlocksUpdateComposition, useCoreBlocksValidateComposition, useCoverClose, useCoverGetStatus, useCoverOpen, useCoverSetPosition, useCoverSetTiltPosition, useCoverStop, useCustomFieldRenderer, useDataTableFilter, useDayNightGetOptions, useDayNightGetStatus, useDayNightSetSettings, useDebouncedString, useDecoderGetInfo, useDecoderReprobeHwaccel, useDetectionPipelineApplyDeviceSettingsPatch, useDetectionPipelineGetDeviceLiveContribution, useDetectionPipelineGetDeviceSettingsContribution, useDevShell, useDevice, useDeviceAdminLink, useDeviceAdminLinkGetAdminLink, useDeviceAdoptionAdopt, useDeviceAdoptionGetCandidate, useDeviceAdoptionGetStatus, useDeviceAdoptionListCandidateFilters, useDeviceAdoptionListCandidates, useDeviceAdoptionRefresh, useDeviceAdoptionRelease, useDeviceAdoptionResync, useDeviceAutotrack, useDeviceBattery, useDeviceCapSlice, useDeviceCapability, useDeviceCredentialsDeleteDeviceCredential, useDeviceCredentialsGetDeviceCaStatus, useDeviceCredentialsGetDeviceCertificateSettings, useDeviceCredentialsListDeviceCredentials, useDeviceCredentialsRenameDeviceCredential, useDeviceCredentialsRevokeDeviceCredential, useDeviceCredentialsSetDeviceCertificateSettings, useDeviceCredentialsStartEnrollment, useDeviceDetections, useDeviceDiscoveryAdoptDevice, useDeviceDiscoveryGetStatus, useDeviceDiscoveryListDiscovered, useDeviceDiscoveryRefreshDiscovery, useDeviceDiscoveryReleaseDevice, useDeviceExportApplyDeviceSettingsPatch, useDeviceExportExposeDevice, useDeviceExportExposeEntity, useDeviceExportGetDeviceLiveContribution, useDeviceExportGetDeviceSettingsContribution, useDeviceExportGetStatus, useDeviceExportListExposedDevices, useDeviceExportListExposedEntities, useDeviceExportListSupportedDeviceKinds, useDeviceExportListSupportedEntityKinds, useDeviceExportUnexposeDevice, useDeviceExportUnexposeEntity, useDeviceExtensionListCandidates, useDeviceExtensionListSlots, useDeviceExtensionListSources, useDeviceExtensionSetSlot, useDeviceHistoryDeclareSeries, useDeviceHistoryDeleteOrphanSeries, useDeviceHistoryGetDeviceEnabled, useDeviceHistoryGetStatus, useDeviceHistoryListNodeSeries, useDeviceHistoryListOrphanSeries, useDeviceHistoryListSeries, useDeviceHistoryQuery, useDeviceHistoryQueryMany, useDeviceHistoryQueryNode, useDeviceHistoryRecord, useDeviceHistoryRecordBuckets, useDeviceHistorySetDeviceEnabled, useDeviceId, useDeviceLabel, useDeviceLabelById, useDeviceListPageSize, useDeviceManagerAddLocation, useDeviceManagerAdoptDevice, useDeviceManagerAdoptionAdopt, useDeviceManagerAdoptionCancelJob, useDeviceManagerAdoptionListCandidateFilters, useDeviceManagerAdoptionListCandidates, useDeviceManagerAdoptionListJobs, useDeviceManagerAdoptionRefresh, useDeviceManagerAdoptionRelease, useDeviceManagerAdoptionResync, useDeviceManagerAdoptionStartJob, useDeviceManagerAllocateDeviceId, useDeviceManagerApplyInitialMeta, useDeviceManagerCleanupDeletedDevicesData, useDeviceManagerCreateDevice, useDeviceManagerDisable, useDeviceManagerDiscoverAllProviders, useDeviceManagerDiscoverDevices, useDeviceManagerDiscoverProvider, useDeviceManagerDiscoveryProviders, useDeviceManagerEnable, useDeviceManagerGetAllBindings, useDeviceManagerGetBindings, useDeviceManagerGetBindingsBatch, useDeviceManagerGetChildren, useDeviceManagerGetChildrenBatch, useDeviceManagerGetConfigSchema, useDeviceManagerGetCreationSchema, useDeviceManagerGetDevice, useDeviceManagerGetDeviceAggregate, useDeviceManagerGetDeviceLiveInfoAggregate, useDeviceManagerGetDeviceSettingsAggregate, useDeviceManagerGetDeviceStatusAggregate, useDeviceManagerGetDeviceStatusAggregateBatch, useDeviceManagerGetLinkedDevices, useDeviceManagerGetLinkedDevicesBatch, useDeviceManagerGetRoleDisplayDefaults, useDeviceManagerGetSettingsSchema, useDeviceManagerGetStreamProfileMap, useDeviceManagerGetStreamSources, useDeviceManagerGetWireableFields, useDeviceManagerGetWrapperActivation, useDeviceManagerListAll, useDeviceManagerListBindableCapsForDeviceType, useDeviceManagerListDeletedSince, useDeviceManagerListDeviceIdsByCaps, 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, useDeviceNameIndex, useDeviceNameNouns, useDeviceNetworkLink, useDeviceOpsGetConfigEntries, useDeviceOpsGetRawState, useDeviceOpsGetSettingsSchema, useDeviceOpsGetStreamSources, useDeviceOpsRemoveDevice, useDeviceOpsRunAction, useDeviceOpsSetConfig, useDeviceProviderAdoptDiscoveredDevice, useDeviceProviderClassifyDiscoveryHits, useDeviceProviderCreateDevice, useDeviceProviderDiscoverDevices, useDeviceProviderGetChildCreationSchema, useDeviceProviderGetDevices, useDeviceProviderGetDiscoveryModes, useDeviceProviderGetDiscoveryParamsSchema, useDeviceProviderGetManualCreationType, useDeviceProviderGetStatus, useDeviceProviderReloadDevice, useDeviceProviderStart, useDeviceProviderStop, useDeviceProviderSupportsDiscovery, useDeviceProviderSupportsManualCreation, useDeviceProviderTestCreationField, useDeviceProxy, useDeviceQuickDetailOpen, useDeviceRunsGetCurrentRun, useDeviceRunsGetRun, useDeviceRunsListRuns, useDeviceSeriesList, useDeviceSnapshot, useDeviceSnapshotImage, useDeviceState, useDeviceStateClaimFields, useDeviceStateGetAllSnapshots, useDeviceStateGetCapSlice, useDeviceStateGetNativeCapSlice, useDeviceStateGetSnapshot, useDeviceStateListClaims, useDeviceStatePatchOwnedFields, useDeviceStateReleaseClaim, useDeviceStateSetCapSlice, useDeviceStateSlice, useDeviceStatusGetStatus, useDeviceWebrtc, useDevices, useDiscoveredOptions, useDishwasherGetOptions, useDishwasherGetStatus, useDishwasherPause, useDishwasherResume, useDishwasherSetChildLock, useDishwasherSetExtraDry, useDishwasherSetHalfLoad, useDishwasherSetHygienePlus, useDishwasherSetIntensiveZone, useDishwasherSetOption, useDishwasherSetPower, useDishwasherSetProgram, useDishwasherSetVarioSpeedPlus, useDishwasherStart, useDishwasherStop, useDisplayIconResolver, useDisplayPaletteGetPalette, useDisplayPaletteListPresets, useDisplayPaletteSetPalette, useDisplayPaletteView, useDoorbellEvents, useDoorbellGetStatus, useEnumSensorGetStatus, useEventEmitterGetStatus, useEventInvalidation, useEventStreamLatest, useEventStreamMap, useFaceGalleryAssignFace, useFaceGalleryAssignFaces, useFaceGalleryAuditIdentitySamples, useFaceGalleryCreateIdentity, useFaceGalleryDeleteFace, useFaceGalleryDeleteIdentity, useFaceGalleryGetFaceByTrack, useFaceGalleryGetFaceMedia, useFaceGalleryListIdentities, useFaceGalleryListIdentitySamples, useFaceGalleryListRecentFaces, useFaceGalleryRemoveSample, useFaceGalleryRenameIdentity, useFaceGallerySuggestFaceClusters, useFaceGalleryUnassignFace, useFaceGalleryUnassignFaces, useFanControlGetStatus, useFanControlSetDirection, useFanControlSetOscillating, useFanControlSetPercentage, useFanControlSetPreset, useFeatureProbeGetStatus, useFloodGetStatus, useGasGetStatus, useGroupActiveGetStatus, useGroupCommandsGetStatus, useGroupStatusGetStatus, useHeatingValveGetStatus, useHistoryPanels, useHistoryReader, useHistoryReads, useHotkey, useHumidifierGetStatus, useHumidifierSetMode, useHumidifierSetOn, useHumidifierSetTargetHumidity, useHumiditySensorGetStatus, useIconGlyphsVersion, useImageGetStatus, useImageSettingsGetOptions, useImageSettingsGetStatus, useImageSettingsSetSettings, useIntegrationsCreate, useIntegrationsDelete, useIntegrationsGet, useIntegrationsGetAvailableTypes, useIntegrationsGetByAddonId, useIntegrationsGetSettings, useIntegrationsList, useIntegrationsSetSettings, useIntegrationsTestConnection, useIntegrationsUpdate, useIntercomEndTalkSession, useIntercomGetStatus, useIntercomHandleAnswer, useIntercomPushTalkAudio, useIntercomStartSession, useIntercomStartTalkSession, useIntercomStopSession, useIrTransmitterGetInfo, useIrTransmitterSend, useIsMidWidth, useIsMobile, useItemFormUrl, useKeychainAdminAcknowledgeReset, useKeychainAdminDeleteOrphans, useKeychainAdminDownloadRecoveryKey, useKeychainAdminImportSecret, useKeychainAdminListAudit, useKeychainAdminListSecrets, useKeychainAdminPurgeRetiredKeys, useKeychainAdminResetKeychain, useKeychainAdminResetReport, useKeychainAdminReveal, useKeychainAdminRotateMasterKey, useKeychainAdminSetSystemSecret, useKeychainAdminStatus, useLawnMowerControlDock, useLawnMowerControlGetStatus, useLawnMowerControlPause, useLawnMowerControlStartMowing, useLiveBuffer, useLiveEvent, useLlmCancel, useLlmDeleteModel, useLlmDeleteProfile, useLlmGenerate, useLlmGenerateVision, useLlmGetDefaults, useLlmGetRuntimeStatus, useLlmGetUsage, useLlmInstallModel, useLlmListModelCatalog, useLlmListModels, useLlmListNodeModels, useLlmListProfileKinds, useLlmListProfiles, useLlmListRuntimeNodes, useLlmMigrateRawSecrets, useLlmResolveModelRef, useLlmSetDefault, useLlmStartRuntime, useLlmStopRuntime, useLlmTestProfile, useLlmUpsertProfile, useLocalNetworkAddCustomAddress, useLocalNetworkDownloadCa, useLocalNetworkGetAddresses, useLocalNetworkGetAllowedAddresses, useLocalNetworkGetConnectionEndpoints, useLocalNetworkGetHubAddresses, useLocalNetworkGetNotificationEndpoint, useLocalNetworkGetPreferred, useLocalNetworkGetScanSubnets, useLocalNetworkGetTlsStatus, useLocalNetworkGetViewerEndpoints, useLocalNetworkList, useLocalNetworkRegenerateCertificate, useLocalNetworkRemoveCustomAddress, useLocalNetworkResetAllowlistToBestMatch, useLocalNetworkRevertToGeneratedCertificate, useLocalNetworkScanNetwork, useLocalNetworkSetAddressRole, useLocalNetworkSetAllowedAddresses, useLocalNetworkSetNotificationEndpoint, useLocalNetworkSetScanSubnets, useLocalNetworkSetViewerEndpoints, useLocalNetworkUploadCertificate, useLocalNetworkUseStoredUploadedCertificate, useLockControlGetStatus, useLockControlLock, useLockControlOpen, useLockControlUnlock, useLockDoorSensor, useMediaPlayerGetStatus, useMediaPlayerNext, useMediaPlayerPause, useMediaPlayerPlay, useMediaPlayerPlayMedia, useMediaPlayerPrevious, useMediaPlayerSeek, useMediaPlayerSelectSource, useMediaPlayerSetMute, useMediaPlayerSetRepeat, useMediaPlayerSetShuffle, useMediaPlayerSetVolume, useMediaPlayerStop, useMeshNetworkGetStatus, useMeshNetworkJoin, useMeshNetworkLeave, useMeshNetworkListPeers, useMeshNetworkLogout, useMeshNetworkStartLogin, useMeshNetworkTestConnection, useMeterGetStatus, 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, useNodesDirectory, useNodesExecuteQuery, useNodesGetCapUsageGraph, useNodesGetNodeAddons, useNodesRenameNode, useNodesRestartAddon, useNodesRestartNode, useNodesRestartProcess, useNodesSetProcessLogLevel, useNodesShutdownNode, useNodesTopology, useNodesUndeployAddon, useNotificationOutputDeleteTarget, useNotificationOutputDiscoverTargets, useNotificationOutputGetTarget, useNotificationOutputListTargetKinds, useNotificationOutputListTargets, useNotificationOutputProbeTargetConfig, useNotificationOutputSend, useNotificationOutputSetTargetEnabled, useNotificationOutputTestTarget, useNotificationOutputUpsertTarget, useNotificationRulesActivateAlarmProfile, useNotificationRulesCancelSnooze, useNotificationRulesCreateAlarmProfile, useNotificationRulesCreateRule, useNotificationRulesCreateSequence, useNotificationRulesCreateSnooze, useNotificationRulesDeleteAlarmProfile, useNotificationRulesDeleteRule, useNotificationRulesDeleteSequence, useNotificationRulesGetAlarmConfig, useNotificationRulesGetAlarmSensors, useNotificationRulesGetClipRetentionAsks, useNotificationRulesGetConditionCatalog, useNotificationRulesGetHistory, useNotificationRulesGetRule, useNotificationRulesGetRuleLastRuns, useNotificationRulesGetSequence, useNotificationRulesGetTemplateCatalog, useNotificationRulesListDeviceMutes, useNotificationRulesListRules, useNotificationRulesListSequences, useNotificationRulesListSnoozes, useNotificationRulesPreviewStateSummary, useNotificationRulesPreviewTemplate, useNotificationRulesRenameAlarmProfile, useNotificationRulesResolveArtifactUrl, useNotificationRulesSetAlarmConfig, useNotificationRulesSetDeviceMuted, useNotificationRulesSetRuleEnabled, useNotificationRulesTestRule, useNotificationRulesUpdateRule, useNotificationRulesUpdateSequence, useNotifierCancel, useNotifierGetStatus, useNotifierSend, useNumericSensorGetStatus, useOidcConnectionsConnectionFormSchema, useOidcConnectionsCreateConnection, useOidcConnectionsDeleteConnection, useOidcConnectionsListConnections, useOidcConnectionsUpdateConnection, useOptimisticSlice, useOptionalSystem, useOptionalWidgetRegistry, useOsdGetStatus, useOsdManagerClearSlotBinding, useOsdManagerCopyDeviceConfiguration, useOsdManagerDeleteTemplate, useOsdManagerGetConditionSupport, useOsdManagerGetDeviceOsd, useOsdManagerGetSourceCatalog, useOsdManagerListTemplates, useOsdManagerPreviewSlot, useOsdManagerRenderDevice, useOsdManagerSetSlotBinding, useOsdManagerSetSlotCameraEnabled, useOsdManagerUpsertTemplate, useOsdSetOverlay, usePTZ, usePersistedDisclosure, usePersistedPageSize, usePetFeederCallPet, usePetFeederCancelFeed, usePetFeederFeed, usePetFeederGetStatus, usePetFeederMarkFoodReplenished, usePetFeederPlaySound, usePetFeederResetDesiccant, usePetFeederSetChildLock, usePetFeederSetFeedSound, usePetFeederSetIndicatorLight, usePetFeederSetVolume, usePetFountainGetStatus, usePetFountainResetDailyConsumption, usePetFountainSetPump, usePetFountainSetPumpInterval, usePetFountainSetPumpOffMinutes, usePetFountainSetPumpOnMinutes, usePickerSiteZones, usePipelineAnalyticsAddRetrainFrameFromRecording, usePipelineAnalyticsAddRetrainFramesToCollection, usePipelineAnalyticsApplyDeviceSettingsPatch, usePipelineAnalyticsBackfillRetrainOrigins, usePipelineAnalyticsCancelRelocateMedia, usePipelineAnalyticsCancelStorageMigrationMove, usePipelineAnalyticsClearTrackRelation, usePipelineAnalyticsClearTracks, usePipelineAnalyticsCompleteRetrainTrack, usePipelineAnalyticsCountRelocatableMedia, usePipelineAnalyticsCountUnstampedEventMedia, usePipelineAnalyticsCreateRetrainCollection, usePipelineAnalyticsDeleteDeviceEvents, usePipelineAnalyticsDeleteRetrainCollection, usePipelineAnalyticsDeleteTracks, usePipelineAnalyticsDeselectRetrainFrame, usePipelineAnalyticsGetActiveTracks, usePipelineAnalyticsGetAudioEvents, usePipelineAnalyticsGetDeviceLiveContribution, usePipelineAnalyticsGetDeviceSettingsContribution, usePipelineAnalyticsGetEventDensity, usePipelineAnalyticsGetEventDensityBatch, usePipelineAnalyticsGetEventMedia, usePipelineAnalyticsGetEventMediaFootprintByKind, usePipelineAnalyticsGetEventStoreFootprint, usePipelineAnalyticsGetKeyEvents, usePipelineAnalyticsGetKeyEventsBatch, usePipelineAnalyticsGetMediaReclaimStatus, usePipelineAnalyticsGetMotionEvents, usePipelineAnalyticsGetObjectEmbeddingRebuildStatus, usePipelineAnalyticsGetObjectEvents, usePipelineAnalyticsGetRetrainCorpusKpi, usePipelineAnalyticsGetRetrainExportUrl, usePipelineAnalyticsGetRetrainFrameImage, usePipelineAnalyticsGetSensorEvents, usePipelineAnalyticsGetStorageMigrationMoveStatus, usePipelineAnalyticsGetTrack, usePipelineAnalyticsGetTrackMedia, usePipelineAnalyticsGetTrainingExportSummary, usePipelineAnalyticsGetTrainingExportUrl, usePipelineAnalyticsListArchivedDebugNotes, usePipelineAnalyticsListBirthDecisions, usePipelineAnalyticsListEventKinds, usePipelineAnalyticsListEventKindsBatch, usePipelineAnalyticsListEventMedia, usePipelineAnalyticsListOpsLog, usePipelineAnalyticsListRecentTracks, usePipelineAnalyticsListRelocateMediaJobs, usePipelineAnalyticsListRetrainAnnotations, usePipelineAnalyticsListRetrainAssistProfiles, usePipelineAnalyticsListRetrainCollectionFrames, usePipelineAnalyticsListRetrainCollections, usePipelineAnalyticsListRetrainCorpusPage, usePipelineAnalyticsListRetrainFrames, usePipelineAnalyticsListRetrainStaging, usePipelineAnalyticsListTrackMedia, usePipelineAnalyticsListTrackRelations, usePipelineAnalyticsListTracks, usePipelineAnalyticsOfferRetrainArchive, usePipelineAnalyticsOwnersWithMedia, usePipelineAnalyticsPauseForStorageMigration, usePipelineAnalyticsProposeRetrainAnnotations, usePipelineAnalyticsProposeRetrainAnnotationsWithLlm, usePipelineAnalyticsPruneEvents, usePipelineAnalyticsPruneEventsBefore, usePipelineAnalyticsPruneTracksBefore, usePipelineAnalyticsReadLongTermSeries, usePipelineAnalyticsRebuildObjectEmbeddings, usePipelineAnalyticsReclaimDebugMedia, usePipelineAnalyticsReconcileFromDisk, usePipelineAnalyticsRefreshStorageLocationsForMigration, usePipelineAnalyticsRelocateMedia, usePipelineAnalyticsRemoveRetrainFrameFromCollection, usePipelineAnalyticsRenameRetrainCollection, usePipelineAnalyticsResolveRetrainTrainingCorpus, usePipelineAnalyticsRestageRetrainTrack, usePipelineAnalyticsResumeForStorageMigration, usePipelineAnalyticsSaveRetrainAnnotations, usePipelineAnalyticsSearchObjectEvents, usePipelineAnalyticsSelectRetrainFrames, usePipelineAnalyticsSetRetrainFrameComplete, usePipelineAnalyticsSetTrackFlags, usePipelineAnalyticsSetTrackPurity, usePipelineAnalyticsSetTrackRelation, usePipelineAnalyticsStartStorageMigrationMove, usePipelineAnalyticsWipeAllAnalytics, usePipelineAnalyticsWipeObjectEmbeddings, usePipelineAnalyticsWriteRetrainArchive, usePipelineExecutorCacheFrameInPool, usePipelineExecutorDeleteModel, usePipelineExecutorDownloadModel, usePipelineExecutorGetAddonModels, usePipelineExecutorGetAudioCapabilities, usePipelineExecutorGetAvailableEngines, usePipelineExecutorGetCapabilities, usePipelineExecutorGetDetectionConfigSchema, usePipelineExecutorGetEffectiveTuning, usePipelineExecutorGetEngineProvisioning, usePipelineExecutorGetInferenceDeviceHealth, usePipelineExecutorGetOrchestratorConfigSchema, usePipelineExecutorGetReferenceAudio, usePipelineExecutorGetReferenceAudioFiles, usePipelineExecutorGetReferenceImage, usePipelineExecutorGetSchema, usePipelineExecutorGetSelectedEngine, usePipelineExecutorGetVideoPipelineSteps, usePipelineExecutorInferCached, usePipelineExecutorKillEngine, usePipelineExecutorListLoadedEngines, usePipelineExecutorListReferenceImages, usePipelineExecutorRearmInferenceDevice, usePipelineExecutorRunAudioTest, usePipelineExecutorRunPipeline, usePipelineExecutorRunPipelineBatch, usePipelineExecutorSetVideoPipelineSteps, usePipelineExecutorSpinEngine, usePipelineExecutorUncacheFrame, usePipelineExecutorValidatePipeline, usePipelineOrchestratorAbortNodeBenchmark, usePipelineOrchestratorApplyAutoTune, usePipelineOrchestratorApplyDeviceSettingsPatch, usePipelineOrchestratorAssignAudio, usePipelineOrchestratorAssignPipeline, usePipelineOrchestratorDeleteNodeBenchmarkResult, usePipelineOrchestratorForgetInferenceDevice, usePipelineOrchestratorGetAgentLoad, usePipelineOrchestratorGetAgentSettings, usePipelineOrchestratorGetAudioAssignment, usePipelineOrchestratorGetAudioAssignments, usePipelineOrchestratorGetAudioNodeLoad, usePipelineOrchestratorGetCameraDetectionSource, usePipelineOrchestratorGetCameraMetrics, usePipelineOrchestratorGetCameraSettings, usePipelineOrchestratorGetCameraStatus, usePipelineOrchestratorGetCameraStatuses, usePipelineOrchestratorGetCameraSwitches, usePipelineOrchestratorGetCapabilityBindings, usePipelineOrchestratorGetClusterModelChoice, usePipelineOrchestratorGetDeviceLiveContribution, usePipelineOrchestratorGetDeviceSettingsContribution, usePipelineOrchestratorGetEffectiveShares, usePipelineOrchestratorGetGlobalMetrics, usePipelineOrchestratorGetIngestOwner, usePipelineOrchestratorGetNodeBenchmarkCandidates, usePipelineOrchestratorGetNodeBenchmarkPreflight, usePipelineOrchestratorGetNodeBenchmarkStatus, usePipelineOrchestratorGetNodeInferenceDevices, usePipelineOrchestratorGetPipelineAssignment, usePipelineOrchestratorGetPipelineAssignments, usePipelineOrchestratorGetPipelineDevicePin, usePipelineOrchestratorGetPlacementStats, usePipelineOrchestratorGetReconcileFromDiskStatus, usePipelineOrchestratorListAgentSettings, usePipelineOrchestratorListNodeBenchmarkResults, usePipelineOrchestratorPauseForStorageMigration, usePipelineOrchestratorPlanAutoTune, usePipelineOrchestratorRebalance, usePipelineOrchestratorReconcileFromDisk, usePipelineOrchestratorRemoveAgentSettings, usePipelineOrchestratorRequestOccupancyLook, usePipelineOrchestratorResetNodePipelineDefaults, usePipelineOrchestratorResolvePipeline, usePipelineOrchestratorResumeForStorageMigration, usePipelineOrchestratorSetAgentCapabilities, usePipelineOrchestratorSetAgentDecodeLimits, usePipelineOrchestratorSetAgentInferenceDevices, usePipelineOrchestratorSetAgentMaxCameras, usePipelineOrchestratorSetAgentReachableHost, usePipelineOrchestratorSetCameraDetectionSource, usePipelineOrchestratorSetCameraSensors, usePipelineOrchestratorSetCameraStepSettings, usePipelineOrchestratorSetCameraStepToggle, usePipelineOrchestratorSetCameraSwitch, usePipelineOrchestratorSetCapabilityBinding, usePipelineOrchestratorSetLoadBalancingShares, usePipelineOrchestratorSetNodeStepSettings, usePipelineOrchestratorSetPipelineDevicePin, usePipelineOrchestratorSetShareSource, usePipelineOrchestratorStartNodeBenchmark, usePipelineOrchestratorSuggestShares, usePipelineOrchestratorUnassignAudio, usePipelineOrchestratorUnassignPipeline, usePipelineRunnerAbortNodeBench, usePipelineRunnerAttachCamera, usePipelineRunnerDetachCamera, usePipelineRunnerGetAllCameraMetrics, usePipelineRunnerGetCameraMetrics, usePipelineRunnerGetLocalCameras, usePipelineRunnerGetLocalLoad, usePipelineRunnerGetLocalMetrics, usePipelineRunnerGetNativeCrop, usePipelineRunnerGetNodeBenchStatus, usePipelineRunnerGetParkedTrackFrame, usePipelineRunnerParkTrackFrame, usePipelineRunnerReleaseParkedTrackFrames, usePipelineRunnerReportMotion, usePipelineRunnerRequestOccupancyBurst, usePipelineRunnerRunDetailSubtree, usePipelineRunnerRunStatelessStep, usePipelineRunnerStartNodeBench, usePlateGalleryAssignPlate, usePlateGalleryAssignPlates, usePlateGalleryCorrectPlateText, usePlateGalleryCreateVehicle, usePlateGalleryDeletePlate, usePlateGalleryDeleteVehicle, usePlateGalleryGetPlateByTrack, usePlateGalleryGetPlateMedia, usePlateGalleryListPlates, usePlateGalleryListVehicleSamples, usePlateGalleryListVehicles, usePlateGalleryRemoveVehicleSample, usePlateGalleryRenameVehicle, usePlateGallerySearchPlates, usePlateGallerySuggestPlateClusters, usePlateGalleryUnassignPlate, usePlateGalleryUnassignPlates, usePlatformProbeGetCapabilities, usePlatformProbeGetHardware, usePlatformProbeRescanAccelerators, usePlatformProbeResolveHwAccel, usePlatformProbeResolveInferenceConfig, usePlayerOverlayLayer, usePlayerOverlayLayers, usePlayerToolbarButton, usePlayerToolbarButtons, usePowerMeterGetStatus, usePowerSourceForceRestart, usePowerSourceGetStatus, usePowerSourcePowerOff, usePowerSourcePowerOn, 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, useRecordEntriesDeleteEntry, useRecordEntriesListEntries, useRecordEntriesListEntryKinds, useRecordEntriesPutEntry, useRecordedPlayback, useRecordingArchiveApplyDeviceSettingsPatch, useRecordingArchiveCancelRelocateJob, useRecordingArchiveCancelStorageMigrationMove, useRecordingArchiveDeleteFootprint, useRecordingArchiveGetAvailabilityBatch, useRecordingArchiveGetDaysWithRecordingsBatch, useRecordingArchiveGetDeviceConfig, useRecordingArchiveGetDeviceLiveContribution, useRecordingArchiveGetDeviceSettingsContribution, useRecordingArchiveGetPlacement, useRecordingArchiveGetRelocateResidue, useRecordingArchiveGetStatus, useRecordingArchiveGetStorageMigrationMoveStatus, useRecordingArchiveGetStorageUsage, useRecordingArchiveListOpsLog, useRecordingArchiveListRelocateJobs, useRecordingArchiveLocateSegment, useRecordingArchivePauseForStorageMigration, useRecordingArchivePlanStorageRebalance, useRecordingArchivePruneFootage, useRecordingArchiveReadGopBytes, useRecordingArchiveReadSegmentBytes, useRecordingArchiveReadWindowBytes, useRecordingArchiveReconcileLedgerAgainstDisk, useRecordingArchiveRefreshStorageLocationsForMigration, useRecordingArchiveRelocateFootage, useRecordingArchiveRenderClip, useRecordingArchiveRenderGif, useRecordingArchiveRescanStorage, useRecordingArchiveResumeForStorageMigration, useRecordingArchiveSetDeviceConfig, useRecordingArchiveSetDevicePlacement, useRecordingArchiveStartStorageMigrationMove, useRecordingArchiveStartStorageRebalance, useRecordingExportCancelExport, useRecordingExportCreateExport, useRecordingExportDeleteExport, useRecordingExportGetDownloadUrl, useRecordingExportGetExport, useRecordingExportListExports, useRecordingExportReadExportBytes, useRecordingGetAvailability, useRecordingGetDaysWithRecordings, useRecordingGetPlayback, useRecordingGetPlaybackOptions, useRecordingListSources, useRecordingOnboardGetOptions, useRecordingOnboardGetStatus, useRecordingOnboardSetSettings, useRecordingSignalGetStatus, useRemoteComponent, useRemoteGetConfig, useRemoteLayoutComponentsListComponents, useRemoteListCommands, useRemoteSendCommand, useRemoteSendMediaCommand, useRemoteSetConfig, useRoleDisplayDefaults, useRunningStateGetStatus, useSceneMonitorCaptureReference, useSceneMonitorCreateScene, useSceneMonitorDeleteReference, useSceneMonitorDeleteScene, useSceneMonitorGetStatus, useSceneMonitorListScenes, useSceneMonitorListScenesBatch, useSceneMonitorRecheckNow, useSceneMonitorResetScene, useSceneMonitorUpdateScene, useSchedulersConflicts, useSchedulersCreate, useSchedulersDelete, useSchedulersGet, useSchedulersGetStatus, useSchedulersGetTraces, useSchedulersList, useSchedulersPreview, useSchedulersSetEnabled, useSchedulersUpdate, useScriptRunnerGetStatus, useScriptRunnerRun, useScriptRunnerStop, useScrubController, useSearchFieldHotkey, useServerManagementApplyServerUpdate, useServerManagementCheckServerUpdate, useServerManagementGetLaunchOverrides, useServerManagementGetServerPackageStatus, useServerManagementInstallDesktopUpdate, useServerManagementRestartServer, useServerManagementRollbackServerUpdate, useServerManagementSetLaunchOverrides, useSettingsStoreAggregate, useSettingsStoreCount, useSettingsStoreDeclareCollection, useSettingsStoreDelete, useSettingsStoreDeleteWhere, useSettingsStoreGet, useSettingsStoreHistogram, useSettingsStoreInsert, useSettingsStoreInsertMany, useSettingsStoreIsEmpty, useSettingsStoreQuery, useSettingsStoreSet, useSettingsStoreTransact, useSettingsStoreUpdate, useSettingsStoreUpdateWhere, useSettingsStoreUpsert, useSettingsStoreUpsertMany, 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, useStorageMigrationMoverClearance, useStorageMigrationMovers, useStorageMigrationPlan, useStorageMigrationResidue, useStorageMigrationStart, useStorageMigrationStatus, useStorageRead, useStorageReadChunk, useStorageResolve, useStorageTestConfig, useStorageTestLocation, useStorageUpsertLocation, useStorageWrite, useStorageWriteChunk, useStoredGroupBy, useStreamBrokerAcquireEgressTranscode, useStreamBrokerApplyDeviceSettingsPatch, useStreamBrokerAssignProfile, useStreamBrokerFetchEventMedia, useStreamBrokerForgetDeviceHardware, useStreamBrokerGetAllRtspEntries, useStreamBrokerGetBrokerStats, useStreamBrokerGetDeviceAudioMute, useStreamBrokerGetDeviceLiveContribution, useStreamBrokerGetDeviceSettingsContribution, useStreamBrokerGetLiveViewerCounts, useStreamBrokerGetPreBufferInfo, useStreamBrokerGetRtspEntry, useStreamBrokerGetRtspPort, useStreamBrokerGetStreamUrl, useStreamBrokerGetStreamWithCodec, useStreamBrokerIsRtspEnabled, useStreamBrokerKillClient, useStreamBrokerListAllCameraStreams, useStreamBrokerListAllProfileSlots, useStreamBrokerListClients, useStreamBrokerProbeStream, useStreamBrokerProduceEventMedia, useStreamBrokerPublishCameraStream, useStreamBrokerPullAudioChunks, useStreamBrokerRegenerateRtspToken, useStreamBrokerReleaseEgressTranscode, useStreamBrokerReleaseStreamWithCodec, useStreamBrokerRenderPreBufferClip, useStreamBrokerReportStreamSignal, useStreamBrokerRestartProfile, useStreamBrokerRetractCameraStream, useStreamBrokerSetDeviceAudioMute, useStreamBrokerSetPreBufferDuration, useStreamBrokerSetRtspEnabled, useStreamBrokerSubscribeAudioChunks, useStreamBrokerUnassignProfile, useStreamBrokerUnsubscribeAudioChunks, 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, useTemplateCreate, useTemplateDelete, useTemplateGet, useTemplateList, useTemplateUpdate, useTerminalSessionAdoptLegacyMonitor, useTerminalSessionClose, useTerminalSessionCreateInstance, useTerminalSessionDeleteInstance, useTerminalSessionListInstances, useTerminalSessionListLegacyCameras, useTerminalSessionListProfiles, useTerminalSessionListSessions, useTerminalSessionOpenSession, useTerminalSessionPullOutput, useTerminalSessionResize, useTerminalSessionSetInstanceEnabled, useTerminalSessionUpdateInstance, useTerminalSessionWriteInput, useThemeMode, useToastOnToast, useTrainingCanaryResult, useTrainingCancelJob, useTrainingDiscardResult, useTrainingGetJob, useTrainingGetJobResult, useTrainingListBaseModels, useTrainingListCanaryTargets, useTrainingListJobs, useTrainingPlanJob, useTrainingRegisterResult, useTrainingRollbackCanary, useTrainingStartJob, useTrainingStartJobBatch, useTurnProviderGetTurnServers, useUiText, useUnitPreferences, useUpdateGetStatus, useUpdateInstallUpdate, useUrlQueryParam, useUserManagementConfirmTotp, useUserManagementCreateUser, useUserManagementDeleteUser, useUserManagementDisableTotp, useUserManagementFindUserByExternalIdentity, useUserManagementGetAdminBootstrapStatus, useUserManagementGetTotpStatus, useUserManagementListExternalIdentities, useUserManagementListOauthSessions, useUserManagementListUsers, useUserManagementMigrateRawSecrets, useUserManagementOauthExchangeCode, useUserManagementOauthIssueCode, useUserManagementOauthRefresh, useUserManagementOauthVerifyAccessToken, useUserManagementResetPassword, useUserManagementRevokeOauthSession, useUserManagementSetUserScopes, useUserManagementSetupTotp, useUserManagementUnlinkExternalIdentity, useUserManagementUpdateUser, useUserManagementValidateCredentials, useUserManagementVerifyTotp, useVacuumControlGetStatus, useVacuumControlLocate, useVacuumControlPause, useVacuumControlReturnToBase, useVacuumControlSetFanSpeed, useVacuumControlStart, useVacuumControlStop, useValveClose, useValveGetStatus, useValveOpen, useValveSetPosition, useValveStop, useVibrationGetStatus, useVideoclipsDialClipStream, useVideoclipsGetClipPlayback, useVideoclipsGetPlaybackOptions, useVideoclipsListClips, useVideoclipsListSources, useVideoclipsOfferClipBytes, useVideoclipsReadClipBytes, useVodPlayback, useWaterHeaterGetStatus, useWaterHeaterSetAway, useWaterHeaterSetOperationMode, useWaterHeaterSetTargetTemp, useWeatherGetStatus, useWebrtcSessionAddIceCandidate, useWebrtcSessionApplyDownlinkProbe, useWebrtcSessionCloseSession, useWebrtcSessionCreateSession, useWebrtcSessionGetIceCandidates, useWebrtcSessionGetSessionDebug, useWebrtcSessionGetSessionState, useWebrtcSessionHandleAnswer, useWebrtcSessionHandleOffer, useWebrtcSessionHasAdaptiveBitrate, useWebrtcSessionListStreams, useWidget, useWidgetMetadata, useWidgetRegistry, useZoneAnalyticsGetCameraHistory, useZoneAnalyticsGetCurrentSnapshot, useZoneAnalyticsGetCurrentSnapshotBatch, useZoneAnalyticsGetUnzonedHistory, useZoneAnalyticsGetZoneHistory, useZoneEditing, useZoneRulesListRules, useZoneRulesSetRules, useZonesAddZone, useZonesListZones, useZonesRemoveZone, useZonesUpdateZone, Sailboat as ut, UtensilsCrossed as v, vacuumStateMeta, validateScopes, valveStateMeta, variantLabel, HardDrive as vn, ChevronDown as vr, Radar as vt, Undo2 as w, waterHeaterPhase, waterHeaterTint, weatherConditionMeta, weatherTint, withHiddenChart, withPanel, withResolvedParentDetail, withUseRootModel, withoutModelScopedFields, withoutPanel, Gauge as wn, Camera as wr, writeStoredGroupBy, Plus as wt, UserCheck as x, GripHorizontal as xn, Cat as xr, Power as xt, Users as y, Hand as yn, Check as yr, QrCode$1 as yt, Sunrise as z, Droplets as zn, BatteryLow as zr, MoveHorizontal as zt };
|
|
73752
|
+
export { Ship as $, CloudSnow as $n, Activity as $r, Lock as $t, Trash2 as A, AddProviderEntryDialog, AddonGlobalSettingsForm, AdminLinkQuickAction, AgentStepEditor, AlarmHeroCard, AlarmInlineControl as AlarmPanelInlineControl, FlashlightOff as An, AppShell, Bot as Ar, ArcKnob, Phone as At, AudioClassificationList, AudioLevelWaveform, AudioWaveform, AutomationHeroCard, AutomationInlineControl, AutotrackSection, Sunrise as B, BATTERY_BADGE_LOW_KEY, BATTERY_BADGE_NORMAL_KEY, BINARY_BATTERY_LOW_BELOW, BOOLEAN_STATES, BTN_COMPACT, BTN_COMPACT_DANGER, BTN_COMPACT_PRIMARY, BTN_COMPACT_WARNING, BackToStepsButton, Badge, BarSeries, BatteryBadge, Droplets as Bn, BottomSheet, BatteryLow as Br, Breadcrumb, BrightnessPanel, BrokerPickerSlotProvider, MoveHorizontal as Bt, Button, ButtonControl, ButtonHeroCard, Unlink2 as C, CENTER, CHART_SERIES_TOKENS, CHIP_ACTIVE, CHIP_BASE, CHIP_INACTIVE, CLASS_COLORS, COLUMN_BREAKPOINT_CLASS, COLUMN_PRIORITY, COMMIT_DEDUPE_TOLERANCE_MS, COMMIT_DEDUPE_WINDOW_MS, CONSUMABLE_LOW_PERCENT, CONTROL_CAP_NAMES, CONTROL_FILLS, CameraStreamPlayer, Card, ChartFrame, ChartPlaceholder, ChartSwatch, ChartWindowToggle, Checkbox, ChildSectionAccordion, ClimatePanel, Grid2x2 as Cn, CodeBlock, CollapsibleCard, ConfigFormBuilder, FormField as ConfigFormField, ConfigNotificationTargetMultiSelectFieldView, ConfigNotificationTargetSelectFieldView, ConfigSchemaField, ConfirmActionButton, ConfirmDialogProvider, ConsumableLevelBadge, ConsumablesPanel, ContainerChildrenProvider, ContainerPrimaryHero, ControlColumn, ControlHeroCard, ControlInlineControl, ControlPanel, CopyButton, CoverHeroCard, CoverInlineControl, CoverPanel, Cast as Cr, PowerOff as Ct, CustomFieldRenderersProvider, TriangleAlert as D, DATA_RECORDS_KIND_PARAM, DATA_RECORDS_OWNER_PARAM, DATA_RECORD_FACET_GROUPS, DEFAULT_COLOR, DEFAULT_PAGINATION_LABELS, DEFAULT_UNIT_PREFERENCES, DEVICE_COLUMNS, DEVICE_EXPORT_PAGE_SIZE_KEY, DEVICE_LIST_PAGE_SIZE_KEY, DEVICE_LIST_PAGE_SIZE_OPTIONS, DEVICE_NAME_FORMS, DEVICE_NAME_JOIN, DEVICE_PICKER_GROUP_STORAGE_KEY, DEVICE_ROLE_META, DEVICE_ROLE_NOUNS, DEVICE_TYPE_CONTROL, DEVICE_TYPE_META, DEVICE_TYPE_NOUNS, DataRecordsHub, DataTable, DataTableFilterBar, DataTablePager, DetectionCanvas, DetectionOverlay, DetectionResultTree, DevShell, DeviceActivityPanel, DeviceBatchToolbar, DeviceCard, DeviceContextProvider, DeviceExportPanel, DeviceExportSetup, DeviceFilterBar, DeviceFleetFromServer, DeviceFleetProvider, DeviceGrid, DeviceHistoryView, DeviceItem, DeviceList, DeviceMultiSelectField, DeviceName, DevicePicker, DeviceQuickDetailProvider, DeviceSelectField, DeviceSelectorPicker, DeviceStepMatrix, DevicesFailedLine, DevicesLoadingLine, DevicesWidenWarning, Dialog, DialogBody, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, DisclosureChevron, DiscoveryPanel, DisplayPaletteProvider, Funnel as Dn, DoorbellRecentPanel, Bus as Dr, Dropdown, DropdownContent, DropdownItem, DropdownTrigger, Plane as Dt, DummyHeroCard, DummyInline, Truck as E, EMPTY_DATA_TABLE_FILTER, EMPTY_HISTORY_PANELS, EVENT_KIND_ICONS, EmptyState, Gamepad2 as En, EndpointResultsCard, EndpointTestCard, EntryJsonSchemaForm, Cable as Er, ErrorBox, Play as Et, EventKindGlyph, EventStream, ExtensionsPanel, Timer as F, FALLBACK_SCOPE, FAST_ICON_GLYPHS, FILL, FLEET_LIST_GC_TIME_MS, FLEET_LIST_QUERY_KEY, FLEET_LIST_STALE_TIME_MS, FanHeroCard, FanInlineControl, FanPanel, FileInput, FilterBar, FloatingEventStream, FloatingLogStream, FloatingPanel, Eye as Fn, FormField$1 as FormField, Bell as Fr, Network as Ft, Sprout as G, GAP_INTERVAL_FACTOR, GRID_GAP, GRID_PAIRED, GRID_QUICK_STATS, GateBadge, GateControl, Dog as Gn, ArrowUp as Gr, GripTrack, GroupedModelSelector, GroupedTilePicker, Minimize2 as Gt, SunMedium as H, HISTORY_PAGE_PATH, HISTORY_PANELS_NAMESPACE, HISTORY_SELECTION_MAX, HISTORY_WINDOW_IDS, HISTORY_WINDOW_MS, HOST_WIDGETS, HUB_SESSION_RUN_MS, HistoryChart, HistoryWindowBar, HlsVideo, Download as Hn, HotkeyProvider, HotkeyScope, HoverZoomImage, Bath as Hr, Moon as Ht, HubSessionTestCard, HumidifierHeroCard, HumidifierInlineControl, TimerOff as I, INPUT_COMPACT, INPUT_SHELL, IconAction, IconButton, IconPicker, ImageHeroCard, ImageInlineControl, ImageSelector, EyeOff as In, InferenceConfigSelector, Input, BellRing as Ir, Navigation as It, ItemFormDialog, Smartphone as J, Cpu as Jn, ArrowLeft as Jr, Menu as Jt, Sparkles as K, KebabMenu, KeyValueList, Database as Kn, ArrowUpToLine as Kr, Mic as Kt, Thermometer as L, LIST_ROW, Label, LawnMowerHeroCard, LawnMowerInlineControl, LayeredSettingsForm, LightHeroCard, LightInlineControl, ExternalLink as Ln, LockHeroCard, LockInlineControl, LockPanel, LogStream, LoginForm, Battery as Lr, Music as Lt, Tractor as M, MEDIA_GRID, MINUTES_PER_DAY, MODE_COLOR, MaskShapeCanvas, MediaCard, MediaGrid, MediaPlayerHeroCard, MediaPlayerInlineControl, MediaPlayerPanel, Film as Mn, MobileDrawer, ModelPicker, MotionZonesSettings, Blinds as Mr, PawPrint as Mt, ToggleRight as N, NAVIGATION_DRIVE_INTERVAL_MS, NODE_COLOR_IDS, NatResultCard, NavigationPanel, NetworkLinkBadge, Feather as Nn, NodeMultiSelectField, NodePicker, NodeSelectField, NotificationTargetSelectField, NotificationTargetsField, Bird as Nr, Pause as Nt, TrendingDown as O, OCCUPANCY_KEY, OPTION_SELECT_SEARCH_MIN_OPTIONS, OfflineBadge, Footprints as On, OptionSelect, Bug as Or, Pipette as Ot, ToggleLeft as P, PAGE_SIZE_ALL, PHASE_CONFIG, PICKER_CHIP_LIMIT, PICKER_DEFAULT_GROUP_BY, PICKER_GROUP_BY_MODES, PICKER_GROUP_COLLAPSE_AT, PICKER_NONE_KEY, PICKER_NOUN_PLURAL, PICKER_NO_FILTERS, PICKER_PAGE_SIZE, PICKER_SEARCH_DEBOUNCE_MS, PICKER_WINDOW, PRIORITY, PTZOverlay, PageHeader, PageShell, PageSizeSelect, Pagination, PasswordInput, PhaseIcon, PipelineBuilder, PipelineRuntimeSelector, PipelineStep, PlaceholderChipField, PlayerOverlaysProvider, Fan as Pn, Popover, PopoverContent, PopoverRowAction, PopoverTrigger, Bike as Pr, PrimaryChildPicker, PrivacyMaskSettings, ProviderBadge, ProviderEntryPills, Package as Pt, PtzPanel, Siren as Q, CloudSun as Qn, AirVent as Qr, QrCode, Mail as Qt, QuantityValueInput, Target as R, RECONNECT_POLICY, RECORDED_PLAYBACK_MODES, RESOLUTION_BUCKET_MS, RIGHT, ROI_AREA_WARN_FRACTION, ROLE_DESCRIPTOR, ROOT_DETECTOR_STEP_ID, RadialGauge, Radio, RecordEntriesPanel, RecordedPlaybackProvider, RecordingPanel, ResponseLog, RetrainReviewBadge, Eraser as Rn, RoleDisplayDefaultsFromServer, RoleDisplayDefaultsProvider, RoleNodePill, RootModelSourceControl, RootSuppliedModelNote, BatteryWarning as Rr, Move as Rt, RunReport, RunningBadge, RunningStatusLine, Upload as S, SCENE_CAPTURE_VARIANTS, SECRET_MASK_PLACEHOLDER, SECRET_REVEAL_MS, 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, STEP_DOCK_WIDTH_PX, SUBJECT_PATH_DWELL_EPS, SUBJECT_PATH_FULL_FRAME_COVERAGE, SUBJECT_PATH_MAX_POINTS, SceneMonitorEditor, ScopePicker, ScriptHeroCard, ScriptInlineControl, ScrollArea, SecretFieldControl, SecretRevealProvider, SectionCard, SectionToolbar, SectionedPage, SegmentedChoice, Select, SelectedChip, SemanticBadge, SendFrameToTrainingButton, SensorHeroCard, SensorInlineControl, SensorValueAtom, Separator, SettingRow, Sidebar, SidebarItem, Skeleton, SlideToggle, Slider, GripHorizontal as Sn, SnapshotButton, SortHeaderButton, Sparkline, Cat as Sr, Power as St, StableTabPanel, StatCard, StateTimeline, StateValuesStream, StatusBadge, StepDetailDock, StepInspectorPanel, StepModelRow, StepTimings, Stepper, StorageRecordsPanel, StreamBrokerSelector, StreamDebugOverlay, StreamPanel, Switch, SwitchHeroCard, SwitchInlineControl, SwitchPanel, SystemProvider, Type as T, TABLE_SCROLL_MAX_H, TEMPERATURE_SCALES, TEXT_FIELD_LABEL, TEXT_HINT, TEXT_METRIC, TEXT_SECTION_LABEL, TEXT_VALUE, TIMEZONES, Tabs, TabsContent, TabsList, TabsTrigger, TapToggle, Textarea, ThemeProvider, ThermostatHeroCard, ThermostatInlineControl, TimeSeriesChart, TimelineSlider, TimezoneSelector, Gauge as Tn, Tooltip, TooltipContent, TooltipTrigger, Camera as Tr, TrainingBaseModelPicker, TrainingCollectionPicker, Plus as Tt, Star as U, UNIT_PREFERENCES_NAMESPACE, UiTextProvider, UiTrans, DoorOpen as Un, UnitPicker, UnitPreferencesFromServer, UnitPreferencesProvider, Ban as Ur, MonitorPlay as Ut, Sun as V, VacuumHeroCard, VacuumInlineControl, ValueReadout, ValveHeroCard, ValveInlineControl, VersionBadge, ViewSwitch, Droplet as Vn, VodPlaybackProvider, BatteryFull as Vr, MousePointerClick as Vt, Square as W, WaterHeaterHeroCard, WaterHeaterInlineControl, WeatherHeroCard, WeatherInlineControl, WidgetMetricCard, WidgetPanel, WidgetRegistryProvider, WidgetSlot, DoorClosed as Wn, Baby as Wr, Minus as Wt, SkipForward as X, Cog as Xn, ArrowDownToLine as Xr, Maximize2 as Xt, SlidersHorizontal as Y, Copy as Yn, ArrowDown as Yr, Megaphone as Yt, SkipBack as Z, Cloud as Zn, ZoneEditingProvider, AlarmSmoke as Zr, MapPin as Zt, Vibrate as _, Heater as _n, ChevronRight as _r, Radio$1 as _t, Wrench as a, acceleratorLabel, acceleratorShortLabel, agentColumnKey, alignSeries, allDeviceTypeFilterOptions, Link2 as an, anchorNow, applyFleetQueryDefaults, applyPickerFilters, CircleX as ar, ariaSortForColumn, assignNodeColorId, Settings as at, axisTicks, User as b, badgeFor, binaryBatteryIsLow, bindsToModel, Hand as bn, booleanLabels, boundsInPicked, Check as br, QrCode$1 as bt, bucketTotals, buildColorByNodeId, buildDataRecordRows, buildPeerConnectionConfig, buildStepTreeFromSchema, buildSubjectPath, buildTimeSeriesModel, Wifi as c, catalogHasDraft, chartKeys, chartSeriesStyle, childEntityId, childListName, chipOverflow, chunk, clampMinute, classifyAddressScope, classifyCapability, classifySessionVerdict, clearPickerGroup, clusterRootModelIds, cn, colorIdForNode, columnsForContext, compareSrflxMappings, computePageButtons, consumableItemLevel, consumableLevelBarClass, consumableLevelLabel, consumableLevelVariant, containerChildToRef, countableDevices, coverHighlight, coverageLine, CirclePlus as cr, createAddonI18n, createSharedContext, createTheme, ScrollText as ct, currentAddonLanguage, cursorFractionFor, WifiLow as d, darkColors, dataRecordContents, dataRecordKey, dataRecordSearchText, dataRecordType, dataTableFacetGroups, dataTableFacets, decodeCustomWindow, decodeSeriesRef, defaultAxisSpec, defaultOfField, defaultSelectClusterRoots, defaultSingleClusterRoot, defaultTheme, defaultUiText, deriveDeviceKind, deriveWebrtcDebugStats, describeDeviceSelector, detectPlatform, deviceIntegrationResolver, deviceListStateOf, deviceMatchesFilter, deviceNameNouns, deviceOptionLabel, deviceRoleMeta, deviceRoleMetaOf, deviceTypeLabel, deviceTypeMeta, deviceTypeMetaOf, devicesToOptions, Info as dn, dockBox, CircleCheck as dr, draftFromQuery, Sailboat as dt, effectivePageSize, emptyDevicesWidens, emptySessionRun, LockOpen as en, encodeCustomWindow, encodeSeriesRef, energyBuckets, ensureMfHostInit, CloudRain as er, Shield as et, eventKindLabel, WifiHigh as f, filterDataTableRows, filterDeviceOptions, filterOccupancyLines, filterOptions as filterOptionSelectOptions, filterPickerDevices, finalizeSessionRun, findTimezone, flattenPickerGrouping, flattenPickerRows, fleetViewOf, Inbox as fn, foldDeviceName, formatChartBytes, formatChartNumber, formatChartValue, formatControlDateTime, formatDeviceName, formatLastSeen, formatNumeric, formatSettingValue, formatSpan, formatTimeLabel, CircleCheckBig as fr, freezeVerdict, Router as ft, fuzzyMatch, Volume2 as g, gapThresholdMs, getClassColor, getPhaseVisual, History as gn, ChevronUp as gr, groupAgentColumns, groupChildrenByLayout, groupDeviceSeries, groupPickerDevices, groupPickerDevicesBy, RefreshCw as gt, VolumeX as h, hardwareLabel, historyPageHref, House as hn, ChevronsDownUp as hr, RotateCcw as ht, hubOrigin, hubPath, hubUrl, hubWsUrl, humanDuration, humanizeName, humidifierTint, X as i, iconGlyphsFailed, iconGlyphsLoaded, ListChecks as in, indexDeviceNames, initialScrubState, insertAtSelection, Clapperboard as ir, isAbsentProvider, isByteUnit, isConsumableLevelField, isDataTableFilterActive, isDeviceNameStock, isDrawableSubjectPath, isFieldVisible, isGroupExpanded, isHistoryWindowId, isKeychainFieldValue, isModelScopedField, isPickableUnit, isRedactedSecret, isRefusal, isSecretField, isValueField, Share2 as it, TrainFront as j, Flame as jn, Bone as jr, Pencil as jt, TrendingUp as k, Flashlight as kn, Box as kr, Pin as kt, WifiZero as l, lawnMowerActivityMeta, lightColors, linePoints, LayoutGrid as ln, loadIconGlyphs, loadRemoteBundle, CirclePause as lr, Scan as lt, lucideExportName, WashingMachine as m, makeScrubBridge, mapRootDetectorPlacements, matchesCombo, mergeSecretForSubmit, metadataEntries, metadataString, minuteFromPointer, ImageOff as mn, mountAddonPage, mountPath, ChevronsUpDown as mr, RotateCw as mt, ZoomIn as n, nextGridPosition, nextReconnectAction, nextSort, nextSortDirection, nextTableSort, niceMax, niceRange, LoaderCircle as nn, nodeColorClass, nodeSoftBgClass, nodeTextColorClass, normalizeForSearch, normalizeLanguage, normalizeSelection, nounSpecFor, CloudFog as nr, ShieldCheck as nt, Workflow as o, occupancyFacets, occupancyLines, offListSelections, Lightbulb as on, openTopLayer, optionSearchText as optionSelectSearchText, CircleStop as or, orphanDeviceLabel, Server as ot, outsideBounds, overrideEntityIdFromLink, Waves as p, pageRows, pageSizeLabel, paginateRows, parentDetailOf, parseCapKey, parseCombo, parseConsumableLevel, parseIceCandidate, parsePickerGroupBy, parseProducerKey, parseRecordedServerMessage, partitionSelected as partitionOptionSelectSelected, partitionSuggested, pickerFacetFilterShown, pickerFacetKey, pickerFacetOptions, pickerFiltersActive, pickerGroupKey, pickerHiddenSelectedCount, pickerLocationKey, pickerQueryTokens, pickerRowFacts, pickerSearchText, pickerZoneFilterSuspended, pinnedStreamChoices, placePopover, Image as pn, CircleAlert as pr, preferenceForQuantity, previousWindow, projectSubjectPath, providerIcons, Route as pt, Snowflake as q, Crosshair as qn, ArrowRight as qr, MessageSquare as qt, quantityStoredUnit, quantityUnitChoices, Zap as r, readHistory, readHistoryPanels, readItemId, readStoredGroupBy, readUnitPreferences, reduceSessionRun, registerAddonBundle, renderMarkup, renderTagged, resetHubMountForTests, resetPickerFilters, resolveContainerPrimary, resolveControlAlign, resolveDeviceControl, resolveDeviceIntegration, resolveDeviceLabel, resolveDisplayIcon, resolveEffectiveDefaultModel, resolveEffectiveStepModel, resolveEventKindIcon, resolveHistoryWindow, resolveSearchable as resolveOptionSelectSearchable, resolveParentNames, resolvePrimaryChild, resolveSelectedDevices, resolveSensorDisplay, resolveStepDefaultModel, retrainReviewBadgeLook, List as rn, roiTooLarge, rootSourceState, routerBasename, Clock as rr, ShieldAlert as rt, runningDurationSince, runningStatusParts, Wind as s, sameDeviceName, sameLocationSuggestions, scrubReducer, searchSteps, secretDisplayValue, secretSubmitValue, segmentsFromChanges, selectPickerGroup, selectedDeviceOptions, serializeRecordedCommand, seriesRefId, settingsModelIdFor, sharedGapSpans, shiftPoints, shouldCommit, shouldEmit, shouldShowAddNewFooter, shouldShowUseQueryRow, shouldUseSingleNode, showsNoCamerasHint, Leaf as sn, snapMinute, sortRows, sortRowsByColumn, CircleQuestionMark as sr, Search as st, stackBuckets, stackSeries, stateAt, stateRow, stateStyle, statusIcons, statusLine, stepFieldDomId, stepHasModelForFormat, stepLocalFields, stepModelOptions, storedToPicked, stripDeviceParentPrefix, stripParentNamePrefix, subjectPathSampleFromBox, subjectPathSvgPoints, summarizeHubCandidates, swatchFillClass, swatchLineClass, ZoomOut as t, tabForSelector, themeToCss, themeToRootCss, timeInState, LocateFixed as tn, toStationaryOverlayBox, toggleDataTableFacet, toggleDataTableGroupFacet, togglePickerDevice, togglePickerKey, CloudLightning as tr, trainingRefusalText, translateAddonKey, trpc, ShieldOff as tt, typeLabel, typedToStored, WifiOff as u, Laugh as un, unitAxes, CircleDot as ur, useAccessoriesGetStatus, useAccessoriesSetChildHidden, useAccountUnitPreferences, useActionSourceListActions, useActionSourceRunAction, useActionSourceStopAction, useActionsCreate, useActionsDelete, useActionsGet, useActionsGetLinks, useActionsGetTraces, useActionsList, useActionsListForCamera, useActionsRun, useActionsSetLinks, useActionsStop, useActionsUpdate, useAddonPagesListPages, useAddonSettingsGetDeclaredSettingsKeys, useAddonSettingsGetDeviceSettings, useAddonSettingsGetGlobalSettings, useAddonSettingsGetIntegrationFormSchema, useAddonSettingsGetIntegrationSettings, useAddonSettingsUnsetStoredSettingsKeys, useAddonSettingsUpdateDeviceSettings, useAddonSettingsUpdateGlobalSettings, useAddonT, useAddonWidgetsListWidgets, useAddonsApplyAutoUpdateToAll, useAddonsCancelJob, useAddonsCustom, useAddonsForceRefresh, useAddonsGetAddonAutoUpdate, useAddonsGetAutoUpdateSettings, useAddonsGetJob, useAddonsGetLastRestart, useAddonsGetLogs, useAddonsGetPackageDocs, useAddonsGetVersions, useAddonsInstallPackage, useAddonsList, useAddonsListCapabilityProviders, useAddonsListFrameworkPackages, useAddonsListInstallations, useAddonsListJobs, useAddonsListPackages, useAddonsListUpdates, 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, useBackupCheckBackupKey, useBackupDelete, useBackupDeleteSchedule, useBackupDisableEncryption, useBackupGetEncryption, useBackupGetEntries, useBackupList, useBackupListArchives, useBackupListAvailableDatabases, useBackupListDestinations, useBackupListLocations, useBackupListRuns, useBackupListSchedules, useBackupPreviewSchedule, useBackupRestore, useBackupSetupEncryption, useBackupTrigger, useBackupUpsertDestinationPolicy, useBackupUpsertSchedule, useBatteryGetStatus, useBatteryWakeForStream, useBinaryGetStatus, useBrightnessGetStatus, useBrightnessSetBrightness, useBrokerAdd, useBrokerGet, useBrokerGetBrokerConfig, useBrokerGetSettings, useBrokerGetSettingsSchema, useBrokerGetState, useBrokerGetStatus, useBrokerList, useBrokerListProviders, useBrokerPickerSlot, useBrokerPublish, useBrokerRemove, useBrokerSetSettings, useBrokerSubscribe, useBrokerTestConnection, useBrokerTestSettings, useBrokerUnsubscribe, useButtonPress, useCalendarsGetPreferences, useCalendarsListCalendars, useCalendarsListEvents, useCalendarsSetCalendarPreference, useCameraCredentialsGetCredentials, useCameraCredentialsGetStatus, useCameraGridLayoutApplyDeviceSettingsPatch, useCameraGridLayoutGetDeviceLiveContribution, useCameraGridLayoutGetDeviceSettingsContribution, useCameraGridLayoutGetLayout, useCameraGridLayoutSaveLayout, useCameraPipelineConfigApplyDeviceSettingsPatch, useCameraPipelineConfigGetDeviceLiveContribution, useCameraPipelineConfigGetDeviceSettingsContribution, useCameraStreamsGetBrokerStreams, useCameraStreamsGetCameraStreams, useCameraStreamsGetProfileRtspEntries, useCameraStreamsGetRtspEntries, useCameraStreamsPickStream, useCapabilityPresence, useCarbonMonoxideGetStatus, useClassPainter, 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, useCoreBlocksCreateComposition, useCoreBlocksDelete, useCoreBlocksGet, useCoreBlocksGetAutomationRunState, useCoreBlocksGetBlockSettings, useCoreBlocksGetComposition, useCoreBlocksGetCustomization, useCoreBlocksGetTraces, useCoreBlocksGetTypeDefs, useCoreBlocksList, useCoreBlocksListComposableCaps, useCoreBlocksListCompositions, useCoreBlocksMigrateRawSecrets, useCoreBlocksReportAutomationRun, useCoreBlocksRestart, useCoreBlocksSetEnabled, useCoreBlocksUpdate, useCoreBlocksUpdateBlockSettings, useCoreBlocksUpdateComposition, useCoreBlocksValidateComposition, useCoverClose, useCoverGetStatus, useCoverOpen, useCoverSetPosition, useCoverSetTiltPosition, useCoverStop, useCustomFieldRenderer, useDataTableFilter, useDayNightGetOptions, useDayNightGetStatus, useDayNightSetSettings, useDebouncedString, useDecoderGetInfo, useDecoderReprobeHwaccel, useDetectionPipelineApplyDeviceSettingsPatch, useDetectionPipelineGetDeviceLiveContribution, useDetectionPipelineGetDeviceSettingsContribution, useDevShell, useDevice, useDeviceAdminLink, useDeviceAdminLinkGetAdminLink, useDeviceAdoptionAdopt, useDeviceAdoptionGetCandidate, useDeviceAdoptionGetStatus, useDeviceAdoptionListCandidateFilters, useDeviceAdoptionListCandidates, useDeviceAdoptionRefresh, useDeviceAdoptionRelease, useDeviceAdoptionResync, useDeviceAutotrack, useDeviceBattery, useDeviceCapSlice, useDeviceCapability, useDeviceCredentialsDeleteDeviceCredential, useDeviceCredentialsGetDeviceCaStatus, useDeviceCredentialsGetDeviceCertificateSettings, useDeviceCredentialsListDeviceCredentials, useDeviceCredentialsRenameDeviceCredential, useDeviceCredentialsRevokeDeviceCredential, useDeviceCredentialsSetDeviceCertificateSettings, useDeviceCredentialsStartEnrollment, useDeviceDetections, useDeviceDiscoveryAdoptDevice, useDeviceDiscoveryGetStatus, useDeviceDiscoveryListDiscovered, useDeviceDiscoveryRefreshDiscovery, useDeviceDiscoveryReleaseDevice, useDeviceExportApplyDeviceSettingsPatch, useDeviceExportExposeDevice, useDeviceExportExposeEntity, useDeviceExportGetDeviceLiveContribution, useDeviceExportGetDeviceSettingsContribution, useDeviceExportGetStatus, useDeviceExportListExposedDevices, useDeviceExportListExposedEntities, useDeviceExportListSupportedDeviceKinds, useDeviceExportListSupportedEntityKinds, useDeviceExportUnexposeDevice, useDeviceExportUnexposeEntity, useDeviceExtensionListCandidates, useDeviceExtensionListSlots, useDeviceExtensionListSources, useDeviceExtensionSetSlot, useDeviceHistoryDeclareSeries, useDeviceHistoryDeleteOrphanSeries, useDeviceHistoryGetDeviceEnabled, useDeviceHistoryGetStatus, useDeviceHistoryListNodeSeries, useDeviceHistoryListOrphanSeries, useDeviceHistoryListSeries, useDeviceHistoryQuery, useDeviceHistoryQueryMany, useDeviceHistoryQueryNode, useDeviceHistoryRecord, useDeviceHistoryRecordBuckets, useDeviceHistorySetDeviceEnabled, useDeviceId, useDeviceLabel, useDeviceLabelById, useDeviceListPageSize, useDeviceManagerAddLocation, useDeviceManagerAdoptDevice, useDeviceManagerAdoptionAdopt, useDeviceManagerAdoptionCancelJob, useDeviceManagerAdoptionListCandidateFilters, useDeviceManagerAdoptionListCandidates, useDeviceManagerAdoptionListJobs, useDeviceManagerAdoptionRefresh, useDeviceManagerAdoptionRelease, useDeviceManagerAdoptionResync, useDeviceManagerAdoptionStartJob, useDeviceManagerAllocateDeviceId, useDeviceManagerApplyInitialMeta, useDeviceManagerCleanupDeletedDevicesData, useDeviceManagerCreateDevice, useDeviceManagerDisable, useDeviceManagerDiscoverAllProviders, useDeviceManagerDiscoverDevices, useDeviceManagerDiscoverProvider, useDeviceManagerDiscoveryProviders, useDeviceManagerEnable, useDeviceManagerGetAllBindings, useDeviceManagerGetBindings, useDeviceManagerGetBindingsBatch, useDeviceManagerGetChildren, useDeviceManagerGetChildrenBatch, useDeviceManagerGetConfigSchema, useDeviceManagerGetCreationSchema, useDeviceManagerGetDevice, useDeviceManagerGetDeviceAggregate, useDeviceManagerGetDeviceLiveInfoAggregate, useDeviceManagerGetDeviceSettingsAggregate, useDeviceManagerGetDeviceStatusAggregate, useDeviceManagerGetDeviceStatusAggregateBatch, useDeviceManagerGetLinkedDevices, useDeviceManagerGetLinkedDevicesBatch, useDeviceManagerGetRoleDisplayDefaults, useDeviceManagerGetSettingsSchema, useDeviceManagerGetStreamProfileMap, useDeviceManagerGetStreamSources, useDeviceManagerGetWireableFields, useDeviceManagerGetWrapperActivation, useDeviceManagerListAll, useDeviceManagerListBindableCapsForDeviceType, useDeviceManagerListDeletedSince, useDeviceManagerListDeviceIdsByCaps, 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, useDeviceNameIndex, useDeviceNameNouns, useDeviceNetworkLink, useDeviceOpsGetConfigEntries, useDeviceOpsGetRawState, useDeviceOpsGetSettingsSchema, useDeviceOpsGetStreamSources, useDeviceOpsRemoveDevice, useDeviceOpsRunAction, useDeviceOpsSetConfig, useDeviceProviderAdoptDiscoveredDevice, useDeviceProviderClassifyDiscoveryHits, useDeviceProviderCreateDevice, useDeviceProviderDiscoverDevices, useDeviceProviderGetChildCreationSchema, useDeviceProviderGetDevices, useDeviceProviderGetDiscoveryModes, useDeviceProviderGetDiscoveryParamsSchema, useDeviceProviderGetManualCreationType, useDeviceProviderGetStatus, useDeviceProviderReloadDevice, useDeviceProviderStart, useDeviceProviderStop, useDeviceProviderSupportsDiscovery, useDeviceProviderSupportsManualCreation, useDeviceProviderTestCreationField, useDeviceProxy, useDeviceQuickDetailOpen, useDeviceRunsGetCurrentRun, useDeviceRunsGetRun, useDeviceRunsListRuns, useDeviceSeriesList, useDeviceSnapshot, useDeviceSnapshotImage, useDeviceState, useDeviceStateClaimFields, useDeviceStateGetAllSnapshots, useDeviceStateGetCapSlice, useDeviceStateGetNativeCapSlice, useDeviceStateGetSnapshot, useDeviceStateListClaims, useDeviceStatePatchOwnedFields, useDeviceStateReleaseClaim, useDeviceStateSetCapSlice, useDeviceStateSlice, useDeviceStatusGetStatus, useDeviceWebrtc, useDevices, useDiscoveredOptions, useDishwasherGetOptions, useDishwasherGetStatus, useDishwasherPause, useDishwasherResume, useDishwasherSetChildLock, useDishwasherSetExtraDry, useDishwasherSetHalfLoad, useDishwasherSetHygienePlus, useDishwasherSetIntensiveZone, useDishwasherSetOption, useDishwasherSetPower, useDishwasherSetProgram, useDishwasherSetVarioSpeedPlus, useDishwasherStart, useDishwasherStop, useDisplayIconResolver, useDisplayPaletteGetPalette, useDisplayPaletteListPresets, useDisplayPaletteSetPalette, useDisplayPaletteView, useDoorbellEvents, useDoorbellGetStatus, useEnumSensorGetStatus, useEventEmitterGetStatus, useEventInvalidation, useEventStreamLatest, useEventStreamMap, useFaceGalleryAssignFace, useFaceGalleryAssignFaces, useFaceGalleryAuditIdentitySamples, useFaceGalleryCreateIdentity, useFaceGalleryDeleteFace, useFaceGalleryDeleteIdentity, useFaceGalleryGetFaceByTrack, useFaceGalleryGetFaceMedia, useFaceGalleryListIdentities, useFaceGalleryListIdentitySamples, useFaceGalleryListRecentFaces, useFaceGalleryRemoveSample, useFaceGalleryRenameIdentity, useFaceGallerySuggestFaceClusters, useFaceGalleryUnassignFace, useFaceGalleryUnassignFaces, useFanControlGetStatus, useFanControlSetDirection, useFanControlSetOscillating, useFanControlSetPercentage, useFanControlSetPreset, useFanPresetsApplyPreset, useFanPresetsCapturePreset, useFanPresetsGetPresets, useFanPresetsSetPresets, useFeatureProbeGetStatus, useFloodGetStatus, useGasGetStatus, useGroupActiveGetStatus, useGroupCommandsGetStatus, useGroupStatusGetStatus, useHeatingValveGetStatus, useHistoryPanels, useHistoryReader, useHistoryReads, useHotkey, useHumidifierGetStatus, useHumidifierSetMode, useHumidifierSetOn, useHumidifierSetTargetHumidity, useHumiditySensorGetStatus, useIconGlyphsVersion, useImageGetStatus, useImageSettingsGetOptions, useImageSettingsGetStatus, useImageSettingsSetSettings, useIntegrationsCreate, useIntegrationsDelete, useIntegrationsGet, useIntegrationsGetAvailableTypes, useIntegrationsGetByAddonId, useIntegrationsGetSettings, useIntegrationsList, useIntegrationsSetSettings, useIntegrationsTestConnection, useIntegrationsUpdate, useIntercomEndTalkSession, useIntercomGetStatus, useIntercomHandleAnswer, useIntercomPushTalkAudio, useIntercomStartSession, useIntercomStartTalkSession, useIntercomStopSession, useIrTransmitterGetInfo, useIrTransmitterSend, useIsMidWidth, useIsMobile, useItemFormUrl, useKeychainAdminAcknowledgeReset, useKeychainAdminDeleteOrphans, useKeychainAdminDownloadRecoveryKey, useKeychainAdminImportSecret, useKeychainAdminListAudit, useKeychainAdminListSecrets, useKeychainAdminPurgeRetiredKeys, useKeychainAdminResetKeychain, useKeychainAdminResetReport, useKeychainAdminReveal, useKeychainAdminRotateMasterKey, useKeychainAdminSetSystemSecret, useKeychainAdminStatus, useLawnMowerControlDock, useLawnMowerControlGetStatus, useLawnMowerControlPause, useLawnMowerControlStartMowing, useLiveBuffer, useLiveEvent, useLlmCancel, useLlmDeleteModel, useLlmDeleteProfile, useLlmGenerate, useLlmGenerateVision, useLlmGetDefaults, useLlmGetRuntimeStatus, useLlmGetUsage, useLlmInstallModel, useLlmListModelCatalog, useLlmListModels, useLlmListNodeModels, useLlmListProfileKinds, useLlmListProfiles, useLlmListRuntimeNodes, useLlmMigrateRawSecrets, useLlmResolveModelRef, useLlmSetDefault, useLlmStartRuntime, useLlmStopRuntime, useLlmTestProfile, useLlmUpsertProfile, useLocalNetworkAddCustomAddress, useLocalNetworkDownloadCa, useLocalNetworkGetAddresses, useLocalNetworkGetAllowedAddresses, useLocalNetworkGetConnectionEndpoints, useLocalNetworkGetHubAddresses, useLocalNetworkGetNotificationEndpoint, useLocalNetworkGetPreferred, useLocalNetworkGetScanSubnets, useLocalNetworkGetTlsStatus, useLocalNetworkGetViewerEndpoints, useLocalNetworkList, useLocalNetworkRegenerateCertificate, useLocalNetworkRemoveCustomAddress, useLocalNetworkResetAllowlistToBestMatch, useLocalNetworkRevertToGeneratedCertificate, useLocalNetworkScanNetwork, useLocalNetworkSetAddressRole, useLocalNetworkSetAllowedAddresses, useLocalNetworkSetNotificationEndpoint, useLocalNetworkSetScanSubnets, useLocalNetworkSetViewerEndpoints, useLocalNetworkUploadCertificate, useLocalNetworkUseStoredUploadedCertificate, useLockControlGetStatus, useLockControlLock, useLockControlOpen, useLockControlUnlock, useLockDoorSensor, useMediaPlayerGetStatus, useMediaPlayerNext, useMediaPlayerPause, useMediaPlayerPlay, useMediaPlayerPlayMedia, useMediaPlayerPrevious, useMediaPlayerSeek, useMediaPlayerSelectSource, useMediaPlayerSetMute, useMediaPlayerSetRepeat, useMediaPlayerSetShuffle, useMediaPlayerSetVolume, useMediaPlayerStop, useMeshNetworkGetStatus, useMeshNetworkJoin, useMeshNetworkLeave, useMeshNetworkListPeers, useMeshNetworkLogout, useMeshNetworkStartLogin, useMeshNetworkTestConnection, useMeterGetStatus, 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, useNodesDirectory, useNodesExecuteQuery, useNodesGetCapUsageGraph, useNodesGetNodeAddons, useNodesRenameNode, useNodesRestartAddon, useNodesRestartNode, useNodesRestartProcess, useNodesSetProcessLogLevel, useNodesShutdownNode, useNodesTopology, useNodesUndeployAddon, useNotificationOutputDeleteTarget, useNotificationOutputDiscoverTargets, useNotificationOutputGetTarget, useNotificationOutputListTargetKinds, useNotificationOutputListTargets, useNotificationOutputProbeTargetConfig, useNotificationOutputSend, useNotificationOutputSetTargetEnabled, useNotificationOutputTestTarget, useNotificationOutputUpsertTarget, useNotificationRulesActivateAlarmProfile, useNotificationRulesCancelSnooze, useNotificationRulesCreateAlarmProfile, useNotificationRulesCreateRule, useNotificationRulesCreateSequence, useNotificationRulesCreateSnooze, useNotificationRulesDeleteAlarmProfile, useNotificationRulesDeleteRule, useNotificationRulesDeleteSequence, useNotificationRulesGetAlarmConfig, useNotificationRulesGetAlarmSensors, useNotificationRulesGetClipRetentionAsks, useNotificationRulesGetConditionCatalog, useNotificationRulesGetHistory, useNotificationRulesGetRule, useNotificationRulesGetRuleLastRuns, useNotificationRulesGetSequence, useNotificationRulesGetTemplateCatalog, useNotificationRulesListDeviceMutes, useNotificationRulesListRules, useNotificationRulesListSequences, useNotificationRulesListSnoozes, useNotificationRulesPreviewStateSummary, useNotificationRulesPreviewTemplate, useNotificationRulesRenameAlarmProfile, useNotificationRulesResolveArtifactUrl, useNotificationRulesSetAlarmConfig, useNotificationRulesSetDeviceMuted, useNotificationRulesSetRuleEnabled, useNotificationRulesTestRule, useNotificationRulesUpdateRule, useNotificationRulesUpdateSequence, useNotifierCancel, useNotifierGetStatus, useNotifierSend, useNumericSensorGetStatus, useOidcConnectionsConnectionFormSchema, useOidcConnectionsCreateConnection, useOidcConnectionsDeleteConnection, useOidcConnectionsListConnections, useOidcConnectionsUpdateConnection, useOptimisticSlice, useOptionalSystem, useOptionalWidgetRegistry, useOsdGetStatus, useOsdManagerClearSlotBinding, useOsdManagerCopyDeviceConfiguration, useOsdManagerDeleteTemplate, useOsdManagerGetConditionSupport, useOsdManagerGetDeviceOsd, useOsdManagerGetSourceCatalog, useOsdManagerListTemplates, useOsdManagerPreviewSlot, useOsdManagerRenderDevice, useOsdManagerSetSlotBinding, useOsdManagerSetSlotCameraEnabled, useOsdManagerUpsertTemplate, useOsdSetOverlay, usePTZ, usePersistedDisclosure, usePersistedPageSize, usePetFeederCallPet, usePetFeederCancelFeed, usePetFeederFeed, usePetFeederGetStatus, usePetFeederMarkFoodReplenished, usePetFeederPlaySound, usePetFeederResetDesiccant, usePetFeederSetChildLock, usePetFeederSetFeedSound, usePetFeederSetIndicatorLight, usePetFeederSetVolume, usePetFountainGetStatus, usePetFountainResetDailyConsumption, usePetFountainSetPump, usePetFountainSetPumpInterval, usePetFountainSetPumpOffMinutes, usePetFountainSetPumpOnMinutes, usePickerSiteZones, usePipelineAnalyticsAddRetrainFrameFromRecording, usePipelineAnalyticsAddRetrainFramesToCollection, usePipelineAnalyticsApplyDeviceSettingsPatch, usePipelineAnalyticsBackfillRetrainOrigins, usePipelineAnalyticsCancelRelocateMedia, usePipelineAnalyticsCancelStorageMigrationMove, usePipelineAnalyticsClearTrackRelation, usePipelineAnalyticsClearTracks, usePipelineAnalyticsCompleteRetrainTrack, usePipelineAnalyticsCountRelocatableMedia, usePipelineAnalyticsCountUnstampedEventMedia, usePipelineAnalyticsCreateRetrainCollection, usePipelineAnalyticsDeleteDeviceEvents, usePipelineAnalyticsDeleteRetrainCollection, usePipelineAnalyticsDeleteTracks, usePipelineAnalyticsDeselectRetrainFrame, usePipelineAnalyticsGetActiveTracks, usePipelineAnalyticsGetAudioEvents, usePipelineAnalyticsGetDeviceLiveContribution, usePipelineAnalyticsGetDeviceSettingsContribution, usePipelineAnalyticsGetEventDensity, usePipelineAnalyticsGetEventDensityBatch, usePipelineAnalyticsGetEventMedia, usePipelineAnalyticsGetEventMediaFootprintByKind, usePipelineAnalyticsGetEventStoreFootprint, usePipelineAnalyticsGetKeyEvents, usePipelineAnalyticsGetKeyEventsBatch, usePipelineAnalyticsGetMediaReclaimStatus, usePipelineAnalyticsGetMotionEvents, usePipelineAnalyticsGetObjectEmbeddingRebuildStatus, usePipelineAnalyticsGetObjectEvents, usePipelineAnalyticsGetRetrainCorpusKpi, usePipelineAnalyticsGetRetrainExportUrl, usePipelineAnalyticsGetRetrainFrameImage, usePipelineAnalyticsGetSensorEvents, usePipelineAnalyticsGetStorageMigrationMoveStatus, usePipelineAnalyticsGetTrack, usePipelineAnalyticsGetTrackMedia, usePipelineAnalyticsGetTrainingExportSummary, usePipelineAnalyticsGetTrainingExportUrl, usePipelineAnalyticsListArchivedDebugNotes, usePipelineAnalyticsListBirthDecisions, usePipelineAnalyticsListEventKinds, usePipelineAnalyticsListEventKindsBatch, usePipelineAnalyticsListEventMedia, usePipelineAnalyticsListOpsLog, usePipelineAnalyticsListRecentTracks, usePipelineAnalyticsListRelocateMediaJobs, usePipelineAnalyticsListRetrainAnnotations, usePipelineAnalyticsListRetrainAssistProfiles, usePipelineAnalyticsListRetrainCollectionFrames, usePipelineAnalyticsListRetrainCollections, usePipelineAnalyticsListRetrainCorpusPage, usePipelineAnalyticsListRetrainFrames, usePipelineAnalyticsListRetrainStaging, usePipelineAnalyticsListTrackMedia, usePipelineAnalyticsListTrackRelations, usePipelineAnalyticsListTracks, usePipelineAnalyticsOfferRetrainArchive, usePipelineAnalyticsOwnersWithMedia, usePipelineAnalyticsPauseForStorageMigration, usePipelineAnalyticsProposeRetrainAnnotations, usePipelineAnalyticsProposeRetrainAnnotationsWithLlm, usePipelineAnalyticsPruneEvents, usePipelineAnalyticsPruneEventsBefore, usePipelineAnalyticsPruneTracksBefore, usePipelineAnalyticsReadLongTermSeries, usePipelineAnalyticsRebuildObjectEmbeddings, usePipelineAnalyticsReclaimDebugMedia, usePipelineAnalyticsReconcileFromDisk, usePipelineAnalyticsRefreshStorageLocationsForMigration, usePipelineAnalyticsRelocateMedia, usePipelineAnalyticsRemoveRetrainFrameFromCollection, usePipelineAnalyticsRenameRetrainCollection, usePipelineAnalyticsResolveRetrainTrainingCorpus, usePipelineAnalyticsRestageRetrainTrack, usePipelineAnalyticsResumeForStorageMigration, usePipelineAnalyticsSaveRetrainAnnotations, usePipelineAnalyticsSearchObjectEvents, usePipelineAnalyticsSelectRetrainFrames, usePipelineAnalyticsSetRetrainFrameComplete, usePipelineAnalyticsSetTrackFlags, usePipelineAnalyticsSetTrackPurity, usePipelineAnalyticsSetTrackRelation, usePipelineAnalyticsStartStorageMigrationMove, usePipelineAnalyticsWipeAllAnalytics, usePipelineAnalyticsWipeObjectEmbeddings, usePipelineAnalyticsWriteRetrainArchive, usePipelineExecutorCacheFrameInPool, usePipelineExecutorDeleteModel, usePipelineExecutorDownloadModel, usePipelineExecutorGetAddonModels, usePipelineExecutorGetAudioCapabilities, usePipelineExecutorGetAvailableEngines, usePipelineExecutorGetCapabilities, usePipelineExecutorGetDetectionConfigSchema, usePipelineExecutorGetEffectiveTuning, usePipelineExecutorGetEngineProvisioning, usePipelineExecutorGetInferenceDeviceHealth, usePipelineExecutorGetOrchestratorConfigSchema, usePipelineExecutorGetReferenceAudio, usePipelineExecutorGetReferenceAudioFiles, usePipelineExecutorGetReferenceImage, usePipelineExecutorGetSchema, usePipelineExecutorGetSelectedEngine, usePipelineExecutorGetVideoPipelineSteps, usePipelineExecutorInferCached, usePipelineExecutorKillEngine, usePipelineExecutorListLoadedEngines, usePipelineExecutorListReferenceImages, usePipelineExecutorRearmInferenceDevice, usePipelineExecutorRunAudioTest, usePipelineExecutorRunPipeline, usePipelineExecutorRunPipelineBatch, usePipelineExecutorSetVideoPipelineSteps, usePipelineExecutorSpinEngine, usePipelineExecutorUncacheFrame, usePipelineExecutorValidatePipeline, usePipelineOrchestratorAbortNodeBenchmark, usePipelineOrchestratorApplyAutoTune, usePipelineOrchestratorApplyDeviceSettingsPatch, usePipelineOrchestratorAssignAudio, usePipelineOrchestratorAssignPipeline, usePipelineOrchestratorDeleteNodeBenchmarkResult, usePipelineOrchestratorForgetInferenceDevice, usePipelineOrchestratorGetAgentLoad, usePipelineOrchestratorGetAgentSettings, usePipelineOrchestratorGetAudioAssignment, usePipelineOrchestratorGetAudioAssignments, usePipelineOrchestratorGetAudioNodeLoad, usePipelineOrchestratorGetCameraDetectionSource, usePipelineOrchestratorGetCameraMetrics, usePipelineOrchestratorGetCameraSettings, usePipelineOrchestratorGetCameraStatus, usePipelineOrchestratorGetCameraStatuses, usePipelineOrchestratorGetCameraSwitches, usePipelineOrchestratorGetCapabilityBindings, usePipelineOrchestratorGetClusterModelChoice, usePipelineOrchestratorGetDeviceLiveContribution, usePipelineOrchestratorGetDeviceSettingsContribution, usePipelineOrchestratorGetEffectiveShares, usePipelineOrchestratorGetGlobalMetrics, usePipelineOrchestratorGetIngestOwner, usePipelineOrchestratorGetNodeBenchmarkCandidates, usePipelineOrchestratorGetNodeBenchmarkPreflight, usePipelineOrchestratorGetNodeBenchmarkStatus, usePipelineOrchestratorGetNodeInferenceDevices, usePipelineOrchestratorGetPipelineAssignment, usePipelineOrchestratorGetPipelineAssignments, usePipelineOrchestratorGetPipelineDevicePin, usePipelineOrchestratorGetPlacementStats, usePipelineOrchestratorGetReconcileFromDiskStatus, usePipelineOrchestratorListAgentSettings, usePipelineOrchestratorListNodeBenchmarkResults, usePipelineOrchestratorPauseForStorageMigration, usePipelineOrchestratorPlanAutoTune, usePipelineOrchestratorRebalance, usePipelineOrchestratorReconcileFromDisk, usePipelineOrchestratorRemoveAgentSettings, usePipelineOrchestratorRequestOccupancyLook, usePipelineOrchestratorResetNodePipelineDefaults, usePipelineOrchestratorResolvePipeline, usePipelineOrchestratorResumeForStorageMigration, usePipelineOrchestratorSetAgentCapabilities, usePipelineOrchestratorSetAgentDecodeLimits, usePipelineOrchestratorSetAgentInferenceDevices, usePipelineOrchestratorSetAgentMaxCameras, usePipelineOrchestratorSetAgentReachableHost, usePipelineOrchestratorSetCameraDetectionSource, usePipelineOrchestratorSetCameraSensors, usePipelineOrchestratorSetCameraStepSettings, usePipelineOrchestratorSetCameraStepToggle, usePipelineOrchestratorSetCameraSwitch, usePipelineOrchestratorSetCapabilityBinding, usePipelineOrchestratorSetLoadBalancingShares, usePipelineOrchestratorSetNodeStepSettings, usePipelineOrchestratorSetPipelineDevicePin, usePipelineOrchestratorSetShareSource, usePipelineOrchestratorStartNodeBenchmark, usePipelineOrchestratorSuggestShares, usePipelineOrchestratorUnassignAudio, usePipelineOrchestratorUnassignPipeline, usePipelineRunnerAbortNodeBench, usePipelineRunnerAttachCamera, usePipelineRunnerDetachCamera, usePipelineRunnerGetAllCameraMetrics, usePipelineRunnerGetCameraMetrics, usePipelineRunnerGetLocalCameras, usePipelineRunnerGetLocalLoad, usePipelineRunnerGetLocalMetrics, usePipelineRunnerGetNativeCrop, usePipelineRunnerGetNodeBenchStatus, usePipelineRunnerGetParkedTrackFrame, usePipelineRunnerParkTrackFrame, usePipelineRunnerReleaseParkedTrackFrames, usePipelineRunnerReportMotion, usePipelineRunnerRequestOccupancyBurst, usePipelineRunnerRunDetailSubtree, usePipelineRunnerRunStatelessStep, usePipelineRunnerStartNodeBench, usePlateGalleryAssignPlate, usePlateGalleryAssignPlates, usePlateGalleryCorrectPlateText, usePlateGalleryCreateVehicle, usePlateGalleryDeletePlate, usePlateGalleryDeleteVehicle, usePlateGalleryGetPlateByTrack, usePlateGalleryGetPlateMedia, usePlateGalleryListPlates, usePlateGalleryListVehicleSamples, usePlateGalleryListVehicles, usePlateGalleryRemoveVehicleSample, usePlateGalleryRenameVehicle, usePlateGallerySearchPlates, usePlateGallerySuggestPlateClusters, usePlateGalleryUnassignPlate, usePlateGalleryUnassignPlates, usePlatformProbeGetCapabilities, usePlatformProbeGetHardware, usePlatformProbeRescanAccelerators, usePlatformProbeResolveHwAccel, usePlatformProbeResolveInferenceConfig, usePlayerOverlayLayer, usePlayerOverlayLayers, usePlayerToolbarButton, usePlayerToolbarButtons, usePowerMeterGetStatus, usePowerSourceForceRestart, usePowerSourceGetStatus, usePowerSourcePowerOff, usePowerSourcePowerOn, 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, useRecordEntriesDeleteEntry, useRecordEntriesListEntries, useRecordEntriesListEntryKinds, useRecordEntriesPutEntry, useRecordedPlayback, useRecordingArchiveApplyDeviceSettingsPatch, useRecordingArchiveCancelRelocateJob, useRecordingArchiveCancelStorageMigrationMove, useRecordingArchiveDeleteFootprint, useRecordingArchiveGetAvailabilityBatch, useRecordingArchiveGetDaysWithRecordingsBatch, useRecordingArchiveGetDeviceConfig, useRecordingArchiveGetDeviceLiveContribution, useRecordingArchiveGetDeviceSettingsContribution, useRecordingArchiveGetPlacement, useRecordingArchiveGetRelocateResidue, useRecordingArchiveGetStatus, useRecordingArchiveGetStorageMigrationMoveStatus, useRecordingArchiveGetStorageUsage, useRecordingArchiveListOpsLog, useRecordingArchiveListRelocateJobs, useRecordingArchiveLocateSegment, useRecordingArchivePauseForStorageMigration, useRecordingArchivePlanStorageRebalance, useRecordingArchivePruneFootage, useRecordingArchiveReadGopBytes, useRecordingArchiveReadSegmentBytes, useRecordingArchiveReadWindowBytes, useRecordingArchiveReconcileLedgerAgainstDisk, useRecordingArchiveRefreshStorageLocationsForMigration, useRecordingArchiveRelocateFootage, useRecordingArchiveRenderClip, useRecordingArchiveRenderGif, useRecordingArchiveRescanStorage, useRecordingArchiveResumeForStorageMigration, useRecordingArchiveSetDeviceConfig, useRecordingArchiveSetDevicePlacement, useRecordingArchiveStartStorageMigrationMove, useRecordingArchiveStartStorageRebalance, useRecordingExportCancelExport, useRecordingExportCreateExport, useRecordingExportDeleteExport, useRecordingExportGetDownloadUrl, useRecordingExportGetExport, useRecordingExportListExports, useRecordingExportReadExportBytes, useRecordingGetAvailability, useRecordingGetDaysWithRecordings, useRecordingGetPlayback, useRecordingGetPlaybackOptions, useRecordingListSources, useRecordingOnboardGetOptions, useRecordingOnboardGetStatus, useRecordingOnboardSetSettings, useRecordingSignalGetStatus, useRemoteComponent, useRemoteGetConfig, useRemoteLayoutComponentsListComponents, useRemoteListCommands, useRemoteSendCommand, useRemoteSendMediaCommand, useRemoteSetConfig, useRoleDisplayDefaults, useRunningStateGetStatus, useSceneMonitorCaptureReference, useSceneMonitorCreateScene, useSceneMonitorDeleteReference, useSceneMonitorDeleteScene, useSceneMonitorGetStatus, useSceneMonitorListScenes, useSceneMonitorListScenesBatch, useSceneMonitorRecheckNow, useSceneMonitorResetScene, useSceneMonitorUpdateScene, useSchedulersConflicts, useSchedulersCreate, useSchedulersDelete, useSchedulersGet, useSchedulersGetStatus, useSchedulersGetTraces, useSchedulersList, useSchedulersPreview, useSchedulersSetEnabled, useSchedulersUpdate, useScriptRunnerGetStatus, useScriptRunnerRun, useScriptRunnerStop, useScrubController, useSearchFieldHotkey, useServerManagementApplyServerUpdate, useServerManagementCheckServerUpdate, useServerManagementGetLaunchOverrides, useServerManagementGetServerPackageStatus, useServerManagementInstallDesktopUpdate, useServerManagementRestartServer, useServerManagementRollbackServerUpdate, useServerManagementSetLaunchOverrides, useSettingsStoreAggregate, useSettingsStoreCount, useSettingsStoreDeclareCollection, useSettingsStoreDelete, useSettingsStoreDeleteWhere, useSettingsStoreGet, useSettingsStoreHistogram, useSettingsStoreInsert, useSettingsStoreInsertMany, useSettingsStoreIsEmpty, useSettingsStoreQuery, useSettingsStoreSet, useSettingsStoreTransact, useSettingsStoreUpdate, useSettingsStoreUpdateWhere, useSettingsStoreUpsert, useSettingsStoreUpsertMany, 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, useStorageMigrationMoverClearance, useStorageMigrationMovers, useStorageMigrationPlan, useStorageMigrationResidue, useStorageMigrationStart, useStorageMigrationStatus, useStorageRead, useStorageReadChunk, useStorageResolve, useStorageTestConfig, useStorageTestLocation, useStorageUpsertLocation, useStorageWrite, useStorageWriteChunk, useStoredGroupBy, useStreamBrokerAcquireEgressTranscode, useStreamBrokerApplyDeviceSettingsPatch, useStreamBrokerAssignProfile, useStreamBrokerFetchEventMedia, useStreamBrokerForgetDeviceHardware, useStreamBrokerGetAllRtspEntries, useStreamBrokerGetBrokerStats, useStreamBrokerGetDeviceAudioMute, useStreamBrokerGetDeviceLiveContribution, useStreamBrokerGetDeviceSettingsContribution, useStreamBrokerGetLiveViewerCounts, useStreamBrokerGetPreBufferInfo, useStreamBrokerGetRtspEntry, useStreamBrokerGetRtspPort, useStreamBrokerGetStreamUrl, useStreamBrokerGetStreamWithCodec, useStreamBrokerIsRtspEnabled, useStreamBrokerKillClient, useStreamBrokerListAllCameraStreams, useStreamBrokerListAllProfileSlots, useStreamBrokerListClients, useStreamBrokerProbeStream, useStreamBrokerProduceEventMedia, useStreamBrokerPublishCameraStream, useStreamBrokerPullAudioChunks, useStreamBrokerRegenerateRtspToken, useStreamBrokerReleaseEgressTranscode, useStreamBrokerReleaseStreamWithCodec, useStreamBrokerRenderPreBufferClip, useStreamBrokerReportStreamSignal, useStreamBrokerRestartProfile, useStreamBrokerRetractCameraStream, useStreamBrokerSetDeviceAudioMute, useStreamBrokerSetPreBufferDuration, useStreamBrokerSetRtspEnabled, useStreamBrokerSubscribeAudioChunks, useStreamBrokerUnassignProfile, useStreamBrokerUnsubscribeAudioChunks, 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, useTemplateCreate, useTemplateDelete, useTemplateGet, useTemplateList, useTemplateUpdate, useTerminalSessionAdoptLegacyMonitor, useTerminalSessionClose, useTerminalSessionCreateInstance, useTerminalSessionDeleteInstance, useTerminalSessionListInstances, useTerminalSessionListLegacyCameras, useTerminalSessionListProfiles, useTerminalSessionListSessions, useTerminalSessionOpenSession, useTerminalSessionPullOutput, useTerminalSessionResize, useTerminalSessionSetInstanceEnabled, useTerminalSessionUpdateInstance, useTerminalSessionWriteInput, useThemeMode, useTimedRunCancel, useTimedRunGetStatus, useTimedRunRunFor, useToastOnToast, useTrainingCanaryResult, useTrainingCancelJob, useTrainingDiscardResult, useTrainingGetJob, useTrainingGetJobResult, useTrainingListBaseModels, useTrainingListCanaryTargets, useTrainingListJobs, useTrainingPlanJob, useTrainingRegisterResult, useTrainingRollbackCanary, useTrainingStartJob, useTrainingStartJobBatch, useTurnProviderGetTurnServers, useUiText, useUnitPreferences, useUpdateGetStatus, useUpdateInstallUpdate, useUrlQueryParam, useUserManagementConfirmTotp, useUserManagementCreateUser, useUserManagementDeleteUser, useUserManagementDisableTotp, useUserManagementFindUserByExternalIdentity, useUserManagementGetAdminBootstrapStatus, useUserManagementGetTotpStatus, useUserManagementListExternalIdentities, useUserManagementListOauthSessions, useUserManagementListUsers, useUserManagementMigrateRawSecrets, useUserManagementOauthExchangeCode, useUserManagementOauthIssueCode, useUserManagementOauthRefresh, useUserManagementOauthVerifyAccessToken, useUserManagementResetPassword, useUserManagementRevokeOauthSession, useUserManagementSetUserScopes, useUserManagementSetupTotp, useUserManagementUnlinkExternalIdentity, useUserManagementUpdateUser, useUserManagementValidateCredentials, useUserManagementVerifyTotp, useVacuumControlGetStatus, useVacuumControlLocate, useVacuumControlPause, useVacuumControlReturnToBase, useVacuumControlSetFanSpeed, useVacuumControlStart, useVacuumControlStop, useValveClose, useValveGetStatus, useValveOpen, useValveSetPosition, useValveStop, useVibrationGetStatus, useVideoclipsDialClipStream, useVideoclipsGetClipPlayback, useVideoclipsGetPlaybackOptions, useVideoclipsListClips, useVideoclipsListSources, useVideoclipsOfferClipBytes, useVideoclipsReadClipBytes, useVodPlayback, useWaterHeaterGetStatus, useWaterHeaterSetAway, useWaterHeaterSetOperationMode, useWaterHeaterSetTargetTemp, useWeatherGetStatus, useWebrtcSessionAddIceCandidate, useWebrtcSessionApplyDownlinkProbe, useWebrtcSessionCloseSession, useWebrtcSessionCreateSession, useWebrtcSessionGetIceCandidates, useWebrtcSessionGetSessionDebug, useWebrtcSessionGetSessionState, useWebrtcSessionHandleAnswer, useWebrtcSessionHandleOffer, useWebrtcSessionHasAdaptiveBitrate, useWebrtcSessionListStreams, useWidget, useWidgetMetadata, useWidgetRegistry, useZoneAnalyticsGetCameraHistory, useZoneAnalyticsGetCurrentSnapshot, useZoneAnalyticsGetCurrentSnapshotBatch, useZoneAnalyticsGetUnzonedHistory, useZoneAnalyticsGetZoneHistory, useZoneEditing, useZoneRulesListRules, useZoneRulesSetRules, useZonesAddZone, useZonesListZones, useZonesRemoveZone, useZonesUpdateZone, Save as ut, UtensilsCrossed as v, vacuumStateMeta, validateScopes, valveStateMeta, variantLabel, Hash as vn, ChevronLeft as vr, RadioTower as vt, Undo2 as w, waterHeaterPhase, waterHeaterTint, weatherConditionMeta, weatherTint, withHiddenChart, withPanel, withResolvedParentDetail, withUseRootModel, withoutModelScopedFields, withoutPanel, GraduationCap as wn, Car as wr, writeStoredGroupBy, Plug as wt, UserCheck as x, Hammer as xn, ChartLine as xr, Puzzle as xt, Users as y, HardDrive as yn, ChevronDown as yr, Radar as yt, Tag as z, EllipsisVertical as zn, BatteryMedium as zr, MoveVertical as zt };
|