@camstack/ui-library 1.2.194 → 1.2.196
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{MotionZonesSettings-7c3yiT5E.js → MotionZonesSettings-DHDfnZyU.js} +1 -1
- package/dist/{PrivacyMaskSettings-DfZAFg32.cjs → PrivacyMaskSettings-BqjXsXZR.cjs} +1 -33
- package/dist/{PrivacyMaskSettings-PkYs077O.js → PrivacyMaskSettings-DMkchqO1.js} +1 -33
- package/dist/{SceneMonitorEditor-BvDy3x3k.js → SceneMonitorEditor-vfWTm6qv.js} +1 -1
- package/dist/composites/data-table-filter-bar.d.ts +23 -0
- package/dist/composites/data-table-filter.d.ts +36 -0
- package/dist/composites/device-item/helpers.d.ts +18 -2
- package/dist/composites/device-item/index.d.ts +1 -0
- package/dist/composites/device-item/role-display-defaults-context.d.ts +21 -0
- package/dist/composites/device-list/table-layout.d.ts +5 -2
- package/dist/composites/device-meta.d.ts +15 -5
- package/dist/composites/icon-picker.d.ts +55 -0
- package/dist/composites/index.d.ts +7 -0
- package/dist/composites/use-data-table-filter.d.ts +16 -0
- package/dist/generated/system-hooks.d.ts +2 -0
- package/dist/index.cjs +2810 -1021
- package/dist/index.js +2802 -1026
- package/dist/primitives/badge.d.ts +1 -1
- package/dist/primitives/button.d.ts +1 -1
- package/dist/primitives/icon-button.d.ts +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -13,7 +13,7 @@ import * as __mfHostReactDOMClient from "react-dom/client";
|
|
|
13
13
|
import { createRoot } from "react-dom/client";
|
|
14
14
|
import * as __mfHostTrpcClient from "@trpc/client";
|
|
15
15
|
import { createTRPCClient, createWSClient, httpLink, splitLink, wsLink } from "@trpc/client";
|
|
16
|
-
import { ALL_CAPABILITY_DEFINITIONS, CAM_PROFILE_ORDER, CLIP_STILL_DISPOSITION_HEADER, CLIP_STILL_REASON_CODE_HEADER, CLIP_STILL_REASON_HEADER, CONTAINER_CHILD_PRIORITY, DEFAULT_EVENTS_BAND_BUFFER_SEC, DEFAULT_EVENT_COLOR, DEVICE_TYPE_CONTROL_KIND, DeviceExportStatusSchema, DeviceFeature, DeviceRole, DeviceType, EVENT_TAXONOMY, EventCategory, ExposedDeviceSchema, FIRST_LEVEL_MACRO_CLASSES, KNOWN_CAP_NAMES, MAX_SENSOR_TRIGGER_DEVICES, MODEL_PROVIDER_IDS, NAVIGATION_LIGHT_LEVEL_MAX, NAVIGATION_LIGHT_LEVEL_MIN, PET_FEEDER_MANUAL_FEED_MAX, PET_FEEDER_MANUAL_FEED_MIN, RECORDING_AUDIO_TRIGGER_OFFERED_DBFS, RecordingConfigSchema, RecordingStatusSchema, SOURCE_CAP_ACTIVE_FIELD, STATIONARY_OVERLAY_STYLE, TIMEZONES, buildModelVariantGroups, canConvertUnit, clusterStepSettingFieldsFor, createDeviceProxy, createLazyTrpcSource, createSliceHandle, deriveRecordingMode, describeModelVariant, findTimezone, formatParkedFor, resolveContainerPrimaryChild, resolveDeviceControlKind, resolveRecordingProfiles, resolveVariantModelId, resolveViewableDeviceIds, selectAssignedProfileSlots, tryConvertUnit } from "@camstack/types";
|
|
16
|
+
import { ALL_CAPABILITY_DEFINITIONS, CAM_PROFILE_ORDER, CLIP_STILL_DISPOSITION_HEADER, CLIP_STILL_REASON_CODE_HEADER, CLIP_STILL_REASON_HEADER, CONTAINER_CHILD_PRIORITY, DEFAULT_EVENTS_BAND_BUFFER_SEC, DEFAULT_EVENT_COLOR, DEVICE_TYPE_CONTROL_KIND, DISPLAY_ICON_GROUPS, DeviceExportStatusSchema, DeviceFeature, DeviceRole, DeviceType, EVENT_TAXONOMY, EventCategory, ExposedDeviceSchema, FIRST_LEVEL_MACRO_CLASSES, KNOWN_CAP_NAMES, MAX_SENSOR_TRIGGER_DEVICES, MODEL_PROVIDER_IDS, NAVIGATION_LIGHT_LEVEL_MAX, NAVIGATION_LIGHT_LEVEL_MIN, PET_FEEDER_MANUAL_FEED_MAX, PET_FEEDER_MANUAL_FEED_MIN, RECORDING_AUDIO_TRIGGER_OFFERED_DBFS, RecordingConfigSchema, RecordingStatusSchema, SOURCE_CAP_ACTIVE_FIELD, STATIONARY_OVERLAY_STYLE, TIMEZONES, buildModelVariantGroups, canConvertUnit, clusterStepSettingFieldsFor, createDeviceProxy, createLazyTrpcSource, createSliceHandle, deriveRecordingMode, describeModelVariant, findTimezone, formatParkedFor, resolveContainerPrimaryChild, resolveDeviceControlKind, resolveRecordingProfiles, resolveVariantModelId, resolveViewableDeviceIds, searchDisplayIcons, selectAssignedProfileSlots, tryConvertUnit } from "@camstack/types";
|
|
17
17
|
import { createSystem } from "@camstack/sdk";
|
|
18
18
|
import { z } from "zod";
|
|
19
19
|
//#region ../../node_modules/lucide-react/dist/esm/shared/src/utils/mergeClasses.js
|
|
@@ -351,6 +351,30 @@ var Bath = createLucideIcon("bath", [
|
|
|
351
351
|
* This source code is licensed under the ISC license.
|
|
352
352
|
* See the LICENSE file in the root directory of this source tree.
|
|
353
353
|
*/
|
|
354
|
+
var BatteryCharging = createLucideIcon("battery-charging", [
|
|
355
|
+
["path", {
|
|
356
|
+
d: "m11 7-3 5h4l-3 5",
|
|
357
|
+
key: "b4a64w"
|
|
358
|
+
}],
|
|
359
|
+
["path", {
|
|
360
|
+
d: "M14.856 6H16a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2h-2.935",
|
|
361
|
+
key: "lre1cr"
|
|
362
|
+
}],
|
|
363
|
+
["path", {
|
|
364
|
+
d: "M22 14v-4",
|
|
365
|
+
key: "14q9d5"
|
|
366
|
+
}],
|
|
367
|
+
["path", {
|
|
368
|
+
d: "M5.14 18H4a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h2.936",
|
|
369
|
+
key: "13q5k0"
|
|
370
|
+
}]
|
|
371
|
+
]);
|
|
372
|
+
/**
|
|
373
|
+
* @license lucide-react v0.576.0 - ISC
|
|
374
|
+
*
|
|
375
|
+
* This source code is licensed under the ISC license.
|
|
376
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
377
|
+
*/
|
|
354
378
|
var BatteryFull = createLucideIcon("battery-full", [
|
|
355
379
|
["path", {
|
|
356
380
|
d: "M10 10v4",
|
|
@@ -480,6 +504,78 @@ var Battery = createLucideIcon("battery", [["path", {
|
|
|
480
504
|
* This source code is licensed under the ISC license.
|
|
481
505
|
* See the LICENSE file in the root directory of this source tree.
|
|
482
506
|
*/
|
|
507
|
+
var BedDouble = createLucideIcon("bed-double", [
|
|
508
|
+
["path", {
|
|
509
|
+
d: "M2 20v-8a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v8",
|
|
510
|
+
key: "1k78r4"
|
|
511
|
+
}],
|
|
512
|
+
["path", {
|
|
513
|
+
d: "M4 10V6a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v4",
|
|
514
|
+
key: "fb3tl2"
|
|
515
|
+
}],
|
|
516
|
+
["path", {
|
|
517
|
+
d: "M12 4v6",
|
|
518
|
+
key: "1dcgq2"
|
|
519
|
+
}],
|
|
520
|
+
["path", {
|
|
521
|
+
d: "M2 18h20",
|
|
522
|
+
key: "ajqnye"
|
|
523
|
+
}]
|
|
524
|
+
]);
|
|
525
|
+
/**
|
|
526
|
+
* @license lucide-react v0.576.0 - ISC
|
|
527
|
+
*
|
|
528
|
+
* This source code is licensed under the ISC license.
|
|
529
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
530
|
+
*/
|
|
531
|
+
var Bed = createLucideIcon("bed", [
|
|
532
|
+
["path", {
|
|
533
|
+
d: "M2 4v16",
|
|
534
|
+
key: "vw9hq8"
|
|
535
|
+
}],
|
|
536
|
+
["path", {
|
|
537
|
+
d: "M2 8h18a2 2 0 0 1 2 2v10",
|
|
538
|
+
key: "1dgv2r"
|
|
539
|
+
}],
|
|
540
|
+
["path", {
|
|
541
|
+
d: "M2 17h20",
|
|
542
|
+
key: "18nfp3"
|
|
543
|
+
}],
|
|
544
|
+
["path", {
|
|
545
|
+
d: "M6 8v9",
|
|
546
|
+
key: "1yriud"
|
|
547
|
+
}]
|
|
548
|
+
]);
|
|
549
|
+
/**
|
|
550
|
+
* @license lucide-react v0.576.0 - ISC
|
|
551
|
+
*
|
|
552
|
+
* This source code is licensed under the ISC license.
|
|
553
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
554
|
+
*/
|
|
555
|
+
var BellOff = createLucideIcon("bell-off", [
|
|
556
|
+
["path", {
|
|
557
|
+
d: "M10.268 21a2 2 0 0 0 3.464 0",
|
|
558
|
+
key: "vwvbt9"
|
|
559
|
+
}],
|
|
560
|
+
["path", {
|
|
561
|
+
d: "M17 17H4a1 1 0 0 1-.74-1.673C4.59 13.956 6 12.499 6 8a6 6 0 0 1 .258-1.742",
|
|
562
|
+
key: "178tsu"
|
|
563
|
+
}],
|
|
564
|
+
["path", {
|
|
565
|
+
d: "m2 2 20 20",
|
|
566
|
+
key: "1ooewy"
|
|
567
|
+
}],
|
|
568
|
+
["path", {
|
|
569
|
+
d: "M8.668 3.01A6 6 0 0 1 18 8c0 2.687.77 4.653 1.707 6.05",
|
|
570
|
+
key: "1hqiys"
|
|
571
|
+
}]
|
|
572
|
+
]);
|
|
573
|
+
/**
|
|
574
|
+
* @license lucide-react v0.576.0 - ISC
|
|
575
|
+
*
|
|
576
|
+
* This source code is licensed under the ISC license.
|
|
577
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
578
|
+
*/
|
|
483
579
|
var BellRing = createLucideIcon("bell-ring", [
|
|
484
580
|
["path", {
|
|
485
581
|
d: "M10.268 21a2 2 0 0 0 3.464 0",
|
|
@@ -617,6 +713,16 @@ var Blinds = createLucideIcon("blinds", [
|
|
|
617
713
|
* This source code is licensed under the ISC license.
|
|
618
714
|
* See the LICENSE file in the root directory of this source tree.
|
|
619
715
|
*/
|
|
716
|
+
var Bluetooth = createLucideIcon("bluetooth", [["path", {
|
|
717
|
+
d: "m7 7 10 10-5 5V2l5 5L7 17",
|
|
718
|
+
key: "1q5490"
|
|
719
|
+
}]]);
|
|
720
|
+
/**
|
|
721
|
+
* @license lucide-react v0.576.0 - ISC
|
|
722
|
+
*
|
|
723
|
+
* This source code is licensed under the ISC license.
|
|
724
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
725
|
+
*/
|
|
620
726
|
var Bone = createLucideIcon("bone", [["path", {
|
|
621
727
|
d: "M17 10c.7-.7 1.69 0 2.5 0a2.5 2.5 0 1 0 0-5 .5.5 0 0 1-.5-.5 2.5 2.5 0 1 0-5 0c0 .81.7 1.8 0 2.5l-7 7c-.7.7-1.69 0-2.5 0a2.5 2.5 0 0 0 0 5c.28 0 .5.22.5.5a2.5 2.5 0 1 0 5 0c0-.81-.7-1.8 0-2.5Z",
|
|
622
728
|
key: "w610uw"
|
|
@@ -683,6 +789,23 @@ var Box = createLucideIcon("box", [
|
|
|
683
789
|
* This source code is licensed under the ISC license.
|
|
684
790
|
* See the LICENSE file in the root directory of this source tree.
|
|
685
791
|
*/
|
|
792
|
+
var Briefcase = createLucideIcon("briefcase", [["path", {
|
|
793
|
+
d: "M16 20V4a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v16",
|
|
794
|
+
key: "jecpp"
|
|
795
|
+
}], ["rect", {
|
|
796
|
+
width: "20",
|
|
797
|
+
height: "14",
|
|
798
|
+
x: "2",
|
|
799
|
+
y: "6",
|
|
800
|
+
rx: "2",
|
|
801
|
+
key: "i6l2r4"
|
|
802
|
+
}]]);
|
|
803
|
+
/**
|
|
804
|
+
* @license lucide-react v0.576.0 - ISC
|
|
805
|
+
*
|
|
806
|
+
* This source code is licensed under the ISC license.
|
|
807
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
808
|
+
*/
|
|
686
809
|
var Bug = createLucideIcon("bug", [
|
|
687
810
|
["path", {
|
|
688
811
|
d: "M12 20v-9",
|
|
@@ -735,6 +858,90 @@ var Bug = createLucideIcon("bug", [
|
|
|
735
858
|
* This source code is licensed under the ISC license.
|
|
736
859
|
* See the LICENSE file in the root directory of this source tree.
|
|
737
860
|
*/
|
|
861
|
+
var Building2 = createLucideIcon("building-2", [
|
|
862
|
+
["path", {
|
|
863
|
+
d: "M10 12h4",
|
|
864
|
+
key: "a56b0p"
|
|
865
|
+
}],
|
|
866
|
+
["path", {
|
|
867
|
+
d: "M10 8h4",
|
|
868
|
+
key: "1sr2af"
|
|
869
|
+
}],
|
|
870
|
+
["path", {
|
|
871
|
+
d: "M14 21v-3a2 2 0 0 0-4 0v3",
|
|
872
|
+
key: "1rgiei"
|
|
873
|
+
}],
|
|
874
|
+
["path", {
|
|
875
|
+
d: "M6 10H4a2 2 0 0 0-2 2v7a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V9a2 2 0 0 0-2-2h-2",
|
|
876
|
+
key: "secmi2"
|
|
877
|
+
}],
|
|
878
|
+
["path", {
|
|
879
|
+
d: "M6 21V5a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v16",
|
|
880
|
+
key: "16ra0t"
|
|
881
|
+
}]
|
|
882
|
+
]);
|
|
883
|
+
/**
|
|
884
|
+
* @license lucide-react v0.576.0 - ISC
|
|
885
|
+
*
|
|
886
|
+
* This source code is licensed under the ISC license.
|
|
887
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
888
|
+
*/
|
|
889
|
+
var Building = createLucideIcon("building", [
|
|
890
|
+
["path", {
|
|
891
|
+
d: "M12 10h.01",
|
|
892
|
+
key: "1nrarc"
|
|
893
|
+
}],
|
|
894
|
+
["path", {
|
|
895
|
+
d: "M12 14h.01",
|
|
896
|
+
key: "1etili"
|
|
897
|
+
}],
|
|
898
|
+
["path", {
|
|
899
|
+
d: "M12 6h.01",
|
|
900
|
+
key: "1vi96p"
|
|
901
|
+
}],
|
|
902
|
+
["path", {
|
|
903
|
+
d: "M16 10h.01",
|
|
904
|
+
key: "1m94wz"
|
|
905
|
+
}],
|
|
906
|
+
["path", {
|
|
907
|
+
d: "M16 14h.01",
|
|
908
|
+
key: "1gbofw"
|
|
909
|
+
}],
|
|
910
|
+
["path", {
|
|
911
|
+
d: "M16 6h.01",
|
|
912
|
+
key: "1x0f13"
|
|
913
|
+
}],
|
|
914
|
+
["path", {
|
|
915
|
+
d: "M8 10h.01",
|
|
916
|
+
key: "19clt8"
|
|
917
|
+
}],
|
|
918
|
+
["path", {
|
|
919
|
+
d: "M8 14h.01",
|
|
920
|
+
key: "6423bh"
|
|
921
|
+
}],
|
|
922
|
+
["path", {
|
|
923
|
+
d: "M8 6h.01",
|
|
924
|
+
key: "1dz90k"
|
|
925
|
+
}],
|
|
926
|
+
["path", {
|
|
927
|
+
d: "M9 22v-3a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v3",
|
|
928
|
+
key: "cabbwy"
|
|
929
|
+
}],
|
|
930
|
+
["rect", {
|
|
931
|
+
x: "4",
|
|
932
|
+
y: "2",
|
|
933
|
+
width: "16",
|
|
934
|
+
height: "20",
|
|
935
|
+
rx: "2",
|
|
936
|
+
key: "1uxh74"
|
|
937
|
+
}]
|
|
938
|
+
]);
|
|
939
|
+
/**
|
|
940
|
+
* @license lucide-react v0.576.0 - ISC
|
|
941
|
+
*
|
|
942
|
+
* This source code is licensed under the ISC license.
|
|
943
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
944
|
+
*/
|
|
738
945
|
var Bus = createLucideIcon("bus", [
|
|
739
946
|
["path", {
|
|
740
947
|
d: "M8 6v6",
|
|
@@ -811,6 +1018,34 @@ var Cable = createLucideIcon("cable", [
|
|
|
811
1018
|
* This source code is licensed under the ISC license.
|
|
812
1019
|
* See the LICENSE file in the root directory of this source tree.
|
|
813
1020
|
*/
|
|
1021
|
+
var Calendar = createLucideIcon("calendar", [
|
|
1022
|
+
["path", {
|
|
1023
|
+
d: "M8 2v4",
|
|
1024
|
+
key: "1cmpym"
|
|
1025
|
+
}],
|
|
1026
|
+
["path", {
|
|
1027
|
+
d: "M16 2v4",
|
|
1028
|
+
key: "4m81vk"
|
|
1029
|
+
}],
|
|
1030
|
+
["rect", {
|
|
1031
|
+
width: "18",
|
|
1032
|
+
height: "18",
|
|
1033
|
+
x: "3",
|
|
1034
|
+
y: "4",
|
|
1035
|
+
rx: "2",
|
|
1036
|
+
key: "1hopcy"
|
|
1037
|
+
}],
|
|
1038
|
+
["path", {
|
|
1039
|
+
d: "M3 10h18",
|
|
1040
|
+
key: "8toen8"
|
|
1041
|
+
}]
|
|
1042
|
+
]);
|
|
1043
|
+
/**
|
|
1044
|
+
* @license lucide-react v0.576.0 - ISC
|
|
1045
|
+
*
|
|
1046
|
+
* This source code is licensed under the ISC license.
|
|
1047
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
1048
|
+
*/
|
|
814
1049
|
var Camera = createLucideIcon("camera", [["path", {
|
|
815
1050
|
d: "M13.997 4a2 2 0 0 1 1.76 1.05l.486.9A2 2 0 0 0 18.003 7H20a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V9a2 2 0 0 1 2-2h1.997a2 2 0 0 0 1.759-1.048l.489-.904A2 2 0 0 1 10.004 4z",
|
|
816
1051
|
key: "18u6gg"
|
|
@@ -1054,6 +1289,21 @@ var CircleDot = createLucideIcon("circle-dot", [["circle", {
|
|
|
1054
1289
|
* This source code is licensed under the ISC license.
|
|
1055
1290
|
* See the LICENSE file in the root directory of this source tree.
|
|
1056
1291
|
*/
|
|
1292
|
+
var CircleParking = createLucideIcon("circle-parking", [["circle", {
|
|
1293
|
+
cx: "12",
|
|
1294
|
+
cy: "12",
|
|
1295
|
+
r: "10",
|
|
1296
|
+
key: "1mglay"
|
|
1297
|
+
}], ["path", {
|
|
1298
|
+
d: "M9 17V7h4a3 3 0 0 1 0 6H9",
|
|
1299
|
+
key: "1dfk2c"
|
|
1300
|
+
}]]);
|
|
1301
|
+
/**
|
|
1302
|
+
* @license lucide-react v0.576.0 - ISC
|
|
1303
|
+
*
|
|
1304
|
+
* This source code is licensed under the ISC license.
|
|
1305
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
1306
|
+
*/
|
|
1057
1307
|
var CirclePause = createLucideIcon("circle-pause", [
|
|
1058
1308
|
["circle", {
|
|
1059
1309
|
cx: "12",
|
|
@@ -1409,6 +1659,30 @@ var Cog = createLucideIcon("cog", [
|
|
|
1409
1659
|
* This source code is licensed under the ISC license.
|
|
1410
1660
|
* See the LICENSE file in the root directory of this source tree.
|
|
1411
1661
|
*/
|
|
1662
|
+
var CookingPot = createLucideIcon("cooking-pot", [
|
|
1663
|
+
["path", {
|
|
1664
|
+
d: "M2 12h20",
|
|
1665
|
+
key: "9i4pu4"
|
|
1666
|
+
}],
|
|
1667
|
+
["path", {
|
|
1668
|
+
d: "M20 12v8a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2v-8",
|
|
1669
|
+
key: "u0tga0"
|
|
1670
|
+
}],
|
|
1671
|
+
["path", {
|
|
1672
|
+
d: "m4 8 16-4",
|
|
1673
|
+
key: "16g0ng"
|
|
1674
|
+
}],
|
|
1675
|
+
["path", {
|
|
1676
|
+
d: "m8.86 6.78-.45-1.81a2 2 0 0 1 1.45-2.43l1.94-.48a2 2 0 0 1 2.43 1.46l.45 1.8",
|
|
1677
|
+
key: "12cejc"
|
|
1678
|
+
}]
|
|
1679
|
+
]);
|
|
1680
|
+
/**
|
|
1681
|
+
* @license lucide-react v0.576.0 - ISC
|
|
1682
|
+
*
|
|
1683
|
+
* This source code is licensed under the ISC license.
|
|
1684
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
1685
|
+
*/
|
|
1412
1686
|
var CopyPlus = createLucideIcon("copy-plus", [
|
|
1413
1687
|
["line", {
|
|
1414
1688
|
x1: "15",
|
|
@@ -1695,6 +1969,38 @@ var Download = createLucideIcon("download", [
|
|
|
1695
1969
|
* This source code is licensed under the ISC license.
|
|
1696
1970
|
* See the LICENSE file in the root directory of this source tree.
|
|
1697
1971
|
*/
|
|
1972
|
+
var Drill = createLucideIcon("drill", [
|
|
1973
|
+
["path", {
|
|
1974
|
+
d: "M10 18a1 1 0 0 1 1 1v2a1 1 0 0 1-1 1H5a3 3 0 0 1-3-3 1 1 0 0 1 1-1z",
|
|
1975
|
+
key: "ioqxb1"
|
|
1976
|
+
}],
|
|
1977
|
+
["path", {
|
|
1978
|
+
d: "M13 10H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a1 1 0 0 1 1 1v6a1 1 0 0 1-1 1l-.81 3.242a1 1 0 0 1-.97.758H8",
|
|
1979
|
+
key: "1rs59n"
|
|
1980
|
+
}],
|
|
1981
|
+
["path", {
|
|
1982
|
+
d: "M14 4h3a1 1 0 0 1 1 1v2a1 1 0 0 1-1 1h-3",
|
|
1983
|
+
key: "105ega"
|
|
1984
|
+
}],
|
|
1985
|
+
["path", {
|
|
1986
|
+
d: "M18 6h4",
|
|
1987
|
+
key: "66u95g"
|
|
1988
|
+
}],
|
|
1989
|
+
["path", {
|
|
1990
|
+
d: "m5 10-2 8",
|
|
1991
|
+
key: "xt2lic"
|
|
1992
|
+
}],
|
|
1993
|
+
["path", {
|
|
1994
|
+
d: "m7 18 2-8",
|
|
1995
|
+
key: "1bzku2"
|
|
1996
|
+
}]
|
|
1997
|
+
]);
|
|
1998
|
+
/**
|
|
1999
|
+
* @license lucide-react v0.576.0 - ISC
|
|
2000
|
+
*
|
|
2001
|
+
* This source code is licensed under the ISC license.
|
|
2002
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
2003
|
+
*/
|
|
1698
2004
|
var Droplet = createLucideIcon("droplet", [["path", {
|
|
1699
2005
|
d: "M12 22a7 7 0 0 0 7-7c0-2-1-3.9-3-5.5s-3.5-4-4-6.5c-.5 2.5-2 4.9-4 6.5C6 11.1 5 13 5 15a7 7 0 0 0 7 7z",
|
|
1700
2006
|
key: "c7niix"
|
|
@@ -1718,6 +2024,34 @@ var Droplets = createLucideIcon("droplets", [["path", {
|
|
|
1718
2024
|
* This source code is licensed under the ISC license.
|
|
1719
2025
|
* See the LICENSE file in the root directory of this source tree.
|
|
1720
2026
|
*/
|
|
2027
|
+
var Dumbbell = createLucideIcon("dumbbell", [
|
|
2028
|
+
["path", {
|
|
2029
|
+
d: "M17.596 12.768a2 2 0 1 0 2.829-2.829l-1.768-1.767a2 2 0 0 0 2.828-2.829l-2.828-2.828a2 2 0 0 0-2.829 2.828l-1.767-1.768a2 2 0 1 0-2.829 2.829z",
|
|
2030
|
+
key: "9m4mmf"
|
|
2031
|
+
}],
|
|
2032
|
+
["path", {
|
|
2033
|
+
d: "m2.5 21.5 1.4-1.4",
|
|
2034
|
+
key: "17g3f0"
|
|
2035
|
+
}],
|
|
2036
|
+
["path", {
|
|
2037
|
+
d: "m20.1 3.9 1.4-1.4",
|
|
2038
|
+
key: "1qn309"
|
|
2039
|
+
}],
|
|
2040
|
+
["path", {
|
|
2041
|
+
d: "M5.343 21.485a2 2 0 1 0 2.829-2.828l1.767 1.768a2 2 0 1 0 2.829-2.829l-6.364-6.364a2 2 0 1 0-2.829 2.829l1.768 1.767a2 2 0 0 0-2.828 2.829z",
|
|
2042
|
+
key: "1t2c92"
|
|
2043
|
+
}],
|
|
2044
|
+
["path", {
|
|
2045
|
+
d: "m9.6 14.4 4.8-4.8",
|
|
2046
|
+
key: "6umqxw"
|
|
2047
|
+
}]
|
|
2048
|
+
]);
|
|
2049
|
+
/**
|
|
2050
|
+
* @license lucide-react v0.576.0 - ISC
|
|
2051
|
+
*
|
|
2052
|
+
* This source code is licensed under the ISC license.
|
|
2053
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
2054
|
+
*/
|
|
1721
2055
|
var EllipsisVertical = createLucideIcon("ellipsis-vertical", [
|
|
1722
2056
|
["circle", {
|
|
1723
2057
|
cx: "12",
|
|
@@ -1836,6 +2170,42 @@ var Feather = createLucideIcon("feather", [
|
|
|
1836
2170
|
* This source code is licensed under the ISC license.
|
|
1837
2171
|
* See the LICENSE file in the root directory of this source tree.
|
|
1838
2172
|
*/
|
|
2173
|
+
var Fence = createLucideIcon("fence", [
|
|
2174
|
+
["path", {
|
|
2175
|
+
d: "M4 3 2 5v15c0 .6.4 1 1 1h2c.6 0 1-.4 1-1V5Z",
|
|
2176
|
+
key: "1n2rgs"
|
|
2177
|
+
}],
|
|
2178
|
+
["path", {
|
|
2179
|
+
d: "M6 8h4",
|
|
2180
|
+
key: "utf9t1"
|
|
2181
|
+
}],
|
|
2182
|
+
["path", {
|
|
2183
|
+
d: "M6 18h4",
|
|
2184
|
+
key: "12yh4b"
|
|
2185
|
+
}],
|
|
2186
|
+
["path", {
|
|
2187
|
+
d: "m12 3-2 2v15c0 .6.4 1 1 1h2c.6 0 1-.4 1-1V5Z",
|
|
2188
|
+
key: "3ha7mj"
|
|
2189
|
+
}],
|
|
2190
|
+
["path", {
|
|
2191
|
+
d: "M14 8h4",
|
|
2192
|
+
key: "1r8wg2"
|
|
2193
|
+
}],
|
|
2194
|
+
["path", {
|
|
2195
|
+
d: "M14 18h4",
|
|
2196
|
+
key: "1t3kbu"
|
|
2197
|
+
}],
|
|
2198
|
+
["path", {
|
|
2199
|
+
d: "m20 3-2 2v15c0 .6.4 1 1 1h2c.6 0 1-.4 1-1V5Z",
|
|
2200
|
+
key: "dfd4e2"
|
|
2201
|
+
}]
|
|
2202
|
+
]);
|
|
2203
|
+
/**
|
|
2204
|
+
* @license lucide-react v0.576.0 - ISC
|
|
2205
|
+
*
|
|
2206
|
+
* This source code is licensed under the ISC license.
|
|
2207
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
2208
|
+
*/
|
|
1839
2209
|
var Film = createLucideIcon("film", [
|
|
1840
2210
|
["rect", {
|
|
1841
2211
|
width: "18",
|
|
@@ -1958,6 +2328,56 @@ var FlaskConical = createLucideIcon("flask-conical", [
|
|
|
1958
2328
|
* This source code is licensed under the ISC license.
|
|
1959
2329
|
* See the LICENSE file in the root directory of this source tree.
|
|
1960
2330
|
*/
|
|
2331
|
+
var Flower = createLucideIcon("flower", [
|
|
2332
|
+
["circle", {
|
|
2333
|
+
cx: "12",
|
|
2334
|
+
cy: "12",
|
|
2335
|
+
r: "3",
|
|
2336
|
+
key: "1v7zrd"
|
|
2337
|
+
}],
|
|
2338
|
+
["path", {
|
|
2339
|
+
d: "M12 16.5A4.5 4.5 0 1 1 7.5 12 4.5 4.5 0 1 1 12 7.5a4.5 4.5 0 1 1 4.5 4.5 4.5 4.5 0 1 1-4.5 4.5",
|
|
2340
|
+
key: "14wa3c"
|
|
2341
|
+
}],
|
|
2342
|
+
["path", {
|
|
2343
|
+
d: "M12 7.5V9",
|
|
2344
|
+
key: "1oy5b0"
|
|
2345
|
+
}],
|
|
2346
|
+
["path", {
|
|
2347
|
+
d: "M7.5 12H9",
|
|
2348
|
+
key: "eltsq1"
|
|
2349
|
+
}],
|
|
2350
|
+
["path", {
|
|
2351
|
+
d: "M16.5 12H15",
|
|
2352
|
+
key: "vk5kw4"
|
|
2353
|
+
}],
|
|
2354
|
+
["path", {
|
|
2355
|
+
d: "M12 16.5V15",
|
|
2356
|
+
key: "k7eayi"
|
|
2357
|
+
}],
|
|
2358
|
+
["path", {
|
|
2359
|
+
d: "m8 8 1.88 1.88",
|
|
2360
|
+
key: "nxy4qf"
|
|
2361
|
+
}],
|
|
2362
|
+
["path", {
|
|
2363
|
+
d: "M14.12 9.88 16 8",
|
|
2364
|
+
key: "1lst6k"
|
|
2365
|
+
}],
|
|
2366
|
+
["path", {
|
|
2367
|
+
d: "m8 16 1.88-1.88",
|
|
2368
|
+
key: "h2eex1"
|
|
2369
|
+
}],
|
|
2370
|
+
["path", {
|
|
2371
|
+
d: "M14.12 14.12 16 16",
|
|
2372
|
+
key: "uqkrx3"
|
|
2373
|
+
}]
|
|
2374
|
+
]);
|
|
2375
|
+
/**
|
|
2376
|
+
* @license lucide-react v0.576.0 - ISC
|
|
2377
|
+
*
|
|
2378
|
+
* This source code is licensed under the ISC license.
|
|
2379
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
2380
|
+
*/
|
|
1961
2381
|
var Footprints = createLucideIcon("footprints", [
|
|
1962
2382
|
["path", {
|
|
1963
2383
|
d: "M4 16v-2.38C4 11.5 2.97 10.5 3 8c.03-2.72 1.49-6 4.5-6C9.37 2 10 3.8 10 5.5c0 3.11-2 5.66-2 8.68V16a2 2 0 1 1-4 0Z",
|
|
@@ -2217,6 +2637,77 @@ var Hash = createLucideIcon("hash", [
|
|
|
2217
2637
|
* This source code is licensed under the ISC license.
|
|
2218
2638
|
* See the LICENSE file in the root directory of this source tree.
|
|
2219
2639
|
*/
|
|
2640
|
+
var HeartPulse = createLucideIcon("heart-pulse", [["path", {
|
|
2641
|
+
d: "M2 9.5a5.5 5.5 0 0 1 9.591-3.676.56.56 0 0 0 .818 0A5.49 5.49 0 0 1 22 9.5c0 2.29-1.5 4-3 5.5l-5.492 5.313a2 2 0 0 1-3 .019L5 15c-1.5-1.5-3-3.2-3-5.5",
|
|
2642
|
+
key: "mvr1a0"
|
|
2643
|
+
}], ["path", {
|
|
2644
|
+
d: "M3.22 13H9.5l.5-1 2 4.5 2-7 1.5 3.5h5.27",
|
|
2645
|
+
key: "auskq0"
|
|
2646
|
+
}]]);
|
|
2647
|
+
/**
|
|
2648
|
+
* @license lucide-react v0.576.0 - ISC
|
|
2649
|
+
*
|
|
2650
|
+
* This source code is licensed under the ISC license.
|
|
2651
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
2652
|
+
*/
|
|
2653
|
+
var Heart = createLucideIcon("heart", [["path", {
|
|
2654
|
+
d: "M2 9.5a5.5 5.5 0 0 1 9.591-3.676.56.56 0 0 0 .818 0A5.49 5.49 0 0 1 22 9.5c0 2.29-1.5 4-3 5.5l-5.492 5.313a2 2 0 0 1-3 .019L5 15c-1.5-1.5-3-3.2-3-5.5",
|
|
2655
|
+
key: "mvr1a0"
|
|
2656
|
+
}]]);
|
|
2657
|
+
/**
|
|
2658
|
+
* @license lucide-react v0.576.0 - ISC
|
|
2659
|
+
*
|
|
2660
|
+
* This source code is licensed under the ISC license.
|
|
2661
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
2662
|
+
*/
|
|
2663
|
+
var Heater = createLucideIcon("heater", [
|
|
2664
|
+
["path", {
|
|
2665
|
+
d: "M11 8c2-3-2-3 0-6",
|
|
2666
|
+
key: "1ldv5m"
|
|
2667
|
+
}],
|
|
2668
|
+
["path", {
|
|
2669
|
+
d: "M15.5 8c2-3-2-3 0-6",
|
|
2670
|
+
key: "1otqoz"
|
|
2671
|
+
}],
|
|
2672
|
+
["path", {
|
|
2673
|
+
d: "M6 10h.01",
|
|
2674
|
+
key: "1lbq93"
|
|
2675
|
+
}],
|
|
2676
|
+
["path", {
|
|
2677
|
+
d: "M6 14h.01",
|
|
2678
|
+
key: "zudwn7"
|
|
2679
|
+
}],
|
|
2680
|
+
["path", {
|
|
2681
|
+
d: "M10 16v-4",
|
|
2682
|
+
key: "1c25yv"
|
|
2683
|
+
}],
|
|
2684
|
+
["path", {
|
|
2685
|
+
d: "M14 16v-4",
|
|
2686
|
+
key: "1dkbt8"
|
|
2687
|
+
}],
|
|
2688
|
+
["path", {
|
|
2689
|
+
d: "M18 16v-4",
|
|
2690
|
+
key: "1yg9me"
|
|
2691
|
+
}],
|
|
2692
|
+
["path", {
|
|
2693
|
+
d: "M20 6a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h3",
|
|
2694
|
+
key: "1ubg90"
|
|
2695
|
+
}],
|
|
2696
|
+
["path", {
|
|
2697
|
+
d: "M5 20v2",
|
|
2698
|
+
key: "1abpe8"
|
|
2699
|
+
}],
|
|
2700
|
+
["path", {
|
|
2701
|
+
d: "M19 20v2",
|
|
2702
|
+
key: "kqn6ft"
|
|
2703
|
+
}]
|
|
2704
|
+
]);
|
|
2705
|
+
/**
|
|
2706
|
+
* @license lucide-react v0.576.0 - ISC
|
|
2707
|
+
*
|
|
2708
|
+
* This source code is licensed under the ISC license.
|
|
2709
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
2710
|
+
*/
|
|
2220
2711
|
var House = createLucideIcon("house", [["path", {
|
|
2221
2712
|
d: "M15 21v-8a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v8",
|
|
2222
2713
|
key: "5wwlr5"
|
|
@@ -2333,6 +2824,141 @@ var Info = createLucideIcon("info", [
|
|
|
2333
2824
|
* This source code is licensed under the ISC license.
|
|
2334
2825
|
* See the LICENSE file in the root directory of this source tree.
|
|
2335
2826
|
*/
|
|
2827
|
+
var KeyRound = createLucideIcon("key-round", [["path", {
|
|
2828
|
+
d: "M2.586 17.414A2 2 0 0 0 2 18.828V21a1 1 0 0 0 1 1h3a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h1a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h.172a2 2 0 0 0 1.414-.586l.814-.814a6.5 6.5 0 1 0-4-4z",
|
|
2829
|
+
key: "1s6t7t"
|
|
2830
|
+
}], ["circle", {
|
|
2831
|
+
cx: "16.5",
|
|
2832
|
+
cy: "7.5",
|
|
2833
|
+
r: ".5",
|
|
2834
|
+
fill: "currentColor",
|
|
2835
|
+
key: "w0ekpg"
|
|
2836
|
+
}]]);
|
|
2837
|
+
/**
|
|
2838
|
+
* @license lucide-react v0.576.0 - ISC
|
|
2839
|
+
*
|
|
2840
|
+
* This source code is licensed under the ISC license.
|
|
2841
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
2842
|
+
*/
|
|
2843
|
+
var Key = createLucideIcon("key", [
|
|
2844
|
+
["path", {
|
|
2845
|
+
d: "m15.5 7.5 2.3 2.3a1 1 0 0 0 1.4 0l2.1-2.1a1 1 0 0 0 0-1.4L19 4",
|
|
2846
|
+
key: "g0fldk"
|
|
2847
|
+
}],
|
|
2848
|
+
["path", {
|
|
2849
|
+
d: "m21 2-9.6 9.6",
|
|
2850
|
+
key: "1j0ho8"
|
|
2851
|
+
}],
|
|
2852
|
+
["circle", {
|
|
2853
|
+
cx: "7.5",
|
|
2854
|
+
cy: "15.5",
|
|
2855
|
+
r: "5.5",
|
|
2856
|
+
key: "yqb3hr"
|
|
2857
|
+
}]
|
|
2858
|
+
]);
|
|
2859
|
+
/**
|
|
2860
|
+
* @license lucide-react v0.576.0 - ISC
|
|
2861
|
+
*
|
|
2862
|
+
* This source code is licensed under the ISC license.
|
|
2863
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
2864
|
+
*/
|
|
2865
|
+
var LampCeiling = createLucideIcon("lamp-ceiling", [
|
|
2866
|
+
["path", {
|
|
2867
|
+
d: "M12 2v5",
|
|
2868
|
+
key: "nd4vlx"
|
|
2869
|
+
}],
|
|
2870
|
+
["path", {
|
|
2871
|
+
d: "M14.829 15.998a3 3 0 1 1-5.658 0",
|
|
2872
|
+
key: "1pybiy"
|
|
2873
|
+
}],
|
|
2874
|
+
["path", {
|
|
2875
|
+
d: "M20.92 14.606A1 1 0 0 1 20 16H4a1 1 0 0 1-.92-1.394l3-7A1 1 0 0 1 7 7h10a1 1 0 0 1 .92.606z",
|
|
2876
|
+
key: "ma1wor"
|
|
2877
|
+
}]
|
|
2878
|
+
]);
|
|
2879
|
+
/**
|
|
2880
|
+
* @license lucide-react v0.576.0 - ISC
|
|
2881
|
+
*
|
|
2882
|
+
* This source code is licensed under the ISC license.
|
|
2883
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
2884
|
+
*/
|
|
2885
|
+
var LampDesk = createLucideIcon("lamp-desk", [
|
|
2886
|
+
["path", {
|
|
2887
|
+
d: "M10.293 2.293a1 1 0 0 1 1.414 0l2.5 2.5 5.994 1.227a1 1 0 0 1 .506 1.687l-7 7a1 1 0 0 1-1.687-.506l-1.227-5.994-2.5-2.5a1 1 0 0 1 0-1.414z",
|
|
2888
|
+
key: "sb8slu"
|
|
2889
|
+
}],
|
|
2890
|
+
["path", {
|
|
2891
|
+
d: "m14.207 4.793-3.414 3.414",
|
|
2892
|
+
key: "m2x3oj"
|
|
2893
|
+
}],
|
|
2894
|
+
["path", {
|
|
2895
|
+
d: "M3 20a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v1a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1z",
|
|
2896
|
+
key: "8b3myj"
|
|
2897
|
+
}],
|
|
2898
|
+
["path", {
|
|
2899
|
+
d: "m9.086 6.5-4.793 4.793a1 1 0 0 0-.18 1.17L7 18",
|
|
2900
|
+
key: "43s6cu"
|
|
2901
|
+
}]
|
|
2902
|
+
]);
|
|
2903
|
+
/**
|
|
2904
|
+
* @license lucide-react v0.576.0 - ISC
|
|
2905
|
+
*
|
|
2906
|
+
* This source code is licensed under the ISC license.
|
|
2907
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
2908
|
+
*/
|
|
2909
|
+
var LampFloor = createLucideIcon("lamp-floor", [
|
|
2910
|
+
["path", {
|
|
2911
|
+
d: "M12 10v12",
|
|
2912
|
+
key: "6ubwww"
|
|
2913
|
+
}],
|
|
2914
|
+
["path", {
|
|
2915
|
+
d: "M17.929 7.629A1 1 0 0 1 17 9H7a1 1 0 0 1-.928-1.371l2-5A1 1 0 0 1 9 2h6a1 1 0 0 1 .928.629z",
|
|
2916
|
+
key: "1o95gh"
|
|
2917
|
+
}],
|
|
2918
|
+
["path", {
|
|
2919
|
+
d: "M9 22h6",
|
|
2920
|
+
key: "1rlq3v"
|
|
2921
|
+
}]
|
|
2922
|
+
]);
|
|
2923
|
+
/**
|
|
2924
|
+
* @license lucide-react v0.576.0 - ISC
|
|
2925
|
+
*
|
|
2926
|
+
* This source code is licensed under the ISC license.
|
|
2927
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
2928
|
+
*/
|
|
2929
|
+
var Lamp = createLucideIcon("lamp", [
|
|
2930
|
+
["path", {
|
|
2931
|
+
d: "M12 12v6",
|
|
2932
|
+
key: "3ahymv"
|
|
2933
|
+
}],
|
|
2934
|
+
["path", {
|
|
2935
|
+
d: "M4.077 10.615A1 1 0 0 0 5 12h14a1 1 0 0 0 .923-1.385l-3.077-7.384A2 2 0 0 0 15 2H9a2 2 0 0 0-1.846 1.23Z",
|
|
2936
|
+
key: "1l7kg2"
|
|
2937
|
+
}],
|
|
2938
|
+
["path", {
|
|
2939
|
+
d: "M8 20a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v1a1 1 0 0 1-1 1H9a1 1 0 0 1-1-1z",
|
|
2940
|
+
key: "1mmzpi"
|
|
2941
|
+
}]
|
|
2942
|
+
]);
|
|
2943
|
+
/**
|
|
2944
|
+
* @license lucide-react v0.576.0 - ISC
|
|
2945
|
+
*
|
|
2946
|
+
* This source code is licensed under the ISC license.
|
|
2947
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
2948
|
+
*/
|
|
2949
|
+
var Laptop = createLucideIcon("laptop", [["path", {
|
|
2950
|
+
d: "M18 5a2 2 0 0 1 2 2v8.526a2 2 0 0 0 .212.897l1.068 2.127a1 1 0 0 1-.9 1.45H3.62a1 1 0 0 1-.9-1.45l1.068-2.127A2 2 0 0 0 4 15.526V7a2 2 0 0 1 2-2z",
|
|
2951
|
+
key: "1pdavp"
|
|
2952
|
+
}], ["path", {
|
|
2953
|
+
d: "M20.054 15.987H3.946",
|
|
2954
|
+
key: "14rxg9"
|
|
2955
|
+
}]]);
|
|
2956
|
+
/**
|
|
2957
|
+
* @license lucide-react v0.576.0 - ISC
|
|
2958
|
+
*
|
|
2959
|
+
* This source code is licensed under the ISC license.
|
|
2960
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
2961
|
+
*/
|
|
2336
2962
|
var Laugh = createLucideIcon("laugh", [
|
|
2337
2963
|
["circle", {
|
|
2338
2964
|
cx: "12",
|
|
@@ -2632,6 +3258,33 @@ var Mail = createLucideIcon("mail", [["path", {
|
|
|
2632
3258
|
* This source code is licensed under the ISC license.
|
|
2633
3259
|
* See the LICENSE file in the root directory of this source tree.
|
|
2634
3260
|
*/
|
|
3261
|
+
var Mailbox = createLucideIcon("mailbox", [
|
|
3262
|
+
["path", {
|
|
3263
|
+
d: "M22 17a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V9.5C2 7 4 5 6.5 5H18c2.2 0 4 1.8 4 4v8Z",
|
|
3264
|
+
key: "1lbycx"
|
|
3265
|
+
}],
|
|
3266
|
+
["polyline", {
|
|
3267
|
+
points: "15,9 18,9 18,11",
|
|
3268
|
+
key: "1pm9c0"
|
|
3269
|
+
}],
|
|
3270
|
+
["path", {
|
|
3271
|
+
d: "M6.5 5C9 5 11 7 11 9.5V17a2 2 0 0 1-2 2",
|
|
3272
|
+
key: "15i455"
|
|
3273
|
+
}],
|
|
3274
|
+
["line", {
|
|
3275
|
+
x1: "6",
|
|
3276
|
+
x2: "7",
|
|
3277
|
+
y1: "10",
|
|
3278
|
+
y2: "10",
|
|
3279
|
+
key: "1e2scm"
|
|
3280
|
+
}]
|
|
3281
|
+
]);
|
|
3282
|
+
/**
|
|
3283
|
+
* @license lucide-react v0.576.0 - ISC
|
|
3284
|
+
*
|
|
3285
|
+
* This source code is licensed under the ISC license.
|
|
3286
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
3287
|
+
*/
|
|
2635
3288
|
var MapPin = createLucideIcon("map-pin", [["path", {
|
|
2636
3289
|
d: "M20 10c0 4.993-5.539 10.193-7.399 11.799a1 1 0 0 1-1.202 0C9.539 20.193 4 14.993 4 10a8 8 0 0 1 16 0",
|
|
2637
3290
|
key: "1r0f0z"
|
|
@@ -2721,6 +3374,38 @@ var MessageSquare = createLucideIcon("message-square", [["path", {
|
|
|
2721
3374
|
* This source code is licensed under the ISC license.
|
|
2722
3375
|
* See the LICENSE file in the root directory of this source tree.
|
|
2723
3376
|
*/
|
|
3377
|
+
var MicOff = createLucideIcon("mic-off", [
|
|
3378
|
+
["path", {
|
|
3379
|
+
d: "M12 19v3",
|
|
3380
|
+
key: "npa21l"
|
|
3381
|
+
}],
|
|
3382
|
+
["path", {
|
|
3383
|
+
d: "M15 9.34V5a3 3 0 0 0-5.68-1.33",
|
|
3384
|
+
key: "1gzdoj"
|
|
3385
|
+
}],
|
|
3386
|
+
["path", {
|
|
3387
|
+
d: "M16.95 16.95A7 7 0 0 1 5 12v-2",
|
|
3388
|
+
key: "cqa7eg"
|
|
3389
|
+
}],
|
|
3390
|
+
["path", {
|
|
3391
|
+
d: "M18.89 13.23A7 7 0 0 0 19 12v-2",
|
|
3392
|
+
key: "16hl24"
|
|
3393
|
+
}],
|
|
3394
|
+
["path", {
|
|
3395
|
+
d: "m2 2 20 20",
|
|
3396
|
+
key: "1ooewy"
|
|
3397
|
+
}],
|
|
3398
|
+
["path", {
|
|
3399
|
+
d: "M9 9v3a3 3 0 0 0 5.12 2.12",
|
|
3400
|
+
key: "r2i35w"
|
|
3401
|
+
}]
|
|
3402
|
+
]);
|
|
3403
|
+
/**
|
|
3404
|
+
* @license lucide-react v0.576.0 - ISC
|
|
3405
|
+
*
|
|
3406
|
+
* This source code is licensed under the ISC license.
|
|
3407
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
3408
|
+
*/
|
|
2724
3409
|
var Mic = createLucideIcon("mic", [
|
|
2725
3410
|
["path", {
|
|
2726
3411
|
d: "M12 19v3",
|
|
@@ -2745,6 +3430,42 @@ var Mic = createLucideIcon("mic", [
|
|
|
2745
3430
|
* This source code is licensed under the ISC license.
|
|
2746
3431
|
* See the LICENSE file in the root directory of this source tree.
|
|
2747
3432
|
*/
|
|
3433
|
+
var Microwave = createLucideIcon("microwave", [
|
|
3434
|
+
["rect", {
|
|
3435
|
+
width: "20",
|
|
3436
|
+
height: "15",
|
|
3437
|
+
x: "2",
|
|
3438
|
+
y: "4",
|
|
3439
|
+
rx: "2",
|
|
3440
|
+
key: "2no95f"
|
|
3441
|
+
}],
|
|
3442
|
+
["rect", {
|
|
3443
|
+
width: "8",
|
|
3444
|
+
height: "7",
|
|
3445
|
+
x: "6",
|
|
3446
|
+
y: "8",
|
|
3447
|
+
rx: "1",
|
|
3448
|
+
key: "zh9wx"
|
|
3449
|
+
}],
|
|
3450
|
+
["path", {
|
|
3451
|
+
d: "M18 8v7",
|
|
3452
|
+
key: "o5zi4n"
|
|
3453
|
+
}],
|
|
3454
|
+
["path", {
|
|
3455
|
+
d: "M6 19v2",
|
|
3456
|
+
key: "1loha6"
|
|
3457
|
+
}],
|
|
3458
|
+
["path", {
|
|
3459
|
+
d: "M18 19v2",
|
|
3460
|
+
key: "1dawf0"
|
|
3461
|
+
}]
|
|
3462
|
+
]);
|
|
3463
|
+
/**
|
|
3464
|
+
* @license lucide-react v0.576.0 - ISC
|
|
3465
|
+
*
|
|
3466
|
+
* This source code is licensed under the ISC license.
|
|
3467
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
3468
|
+
*/
|
|
2748
3469
|
var Minimize2 = createLucideIcon("minimize-2", [
|
|
2749
3470
|
["path", {
|
|
2750
3471
|
d: "m14 10 7-7",
|
|
@@ -2807,6 +3528,36 @@ var MonitorPlay = createLucideIcon("monitor-play", [
|
|
|
2807
3528
|
* This source code is licensed under the ISC license.
|
|
2808
3529
|
* See the LICENSE file in the root directory of this source tree.
|
|
2809
3530
|
*/
|
|
3531
|
+
var Monitor = createLucideIcon("monitor", [
|
|
3532
|
+
["rect", {
|
|
3533
|
+
width: "20",
|
|
3534
|
+
height: "14",
|
|
3535
|
+
x: "2",
|
|
3536
|
+
y: "3",
|
|
3537
|
+
rx: "2",
|
|
3538
|
+
key: "48i651"
|
|
3539
|
+
}],
|
|
3540
|
+
["line", {
|
|
3541
|
+
x1: "8",
|
|
3542
|
+
x2: "16",
|
|
3543
|
+
y1: "21",
|
|
3544
|
+
y2: "21",
|
|
3545
|
+
key: "1svkeh"
|
|
3546
|
+
}],
|
|
3547
|
+
["line", {
|
|
3548
|
+
x1: "12",
|
|
3549
|
+
x2: "12",
|
|
3550
|
+
y1: "17",
|
|
3551
|
+
y2: "21",
|
|
3552
|
+
key: "vw1qmm"
|
|
3553
|
+
}]
|
|
3554
|
+
]);
|
|
3555
|
+
/**
|
|
3556
|
+
* @license lucide-react v0.576.0 - ISC
|
|
3557
|
+
*
|
|
3558
|
+
* This source code is licensed under the ISC license.
|
|
3559
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
3560
|
+
*/
|
|
2810
3561
|
var Moon = createLucideIcon("moon", [["path", {
|
|
2811
3562
|
d: "M20.985 12.486a9 9 0 1 1-9.473-9.472c.405-.022.617.46.402.803a6 6 0 0 0 8.268 8.268c.344-.215.825-.004.803.401",
|
|
2812
3563
|
key: "kfwtm"
|
|
@@ -2817,6 +3568,16 @@ var Moon = createLucideIcon("moon", [["path", {
|
|
|
2817
3568
|
* This source code is licensed under the ISC license.
|
|
2818
3569
|
* See the LICENSE file in the root directory of this source tree.
|
|
2819
3570
|
*/
|
|
3571
|
+
var Mountain = createLucideIcon("mountain", [["path", {
|
|
3572
|
+
d: "m8 3 4 8 5-5 5 15H2L8 3z",
|
|
3573
|
+
key: "otkl63"
|
|
3574
|
+
}]]);
|
|
3575
|
+
/**
|
|
3576
|
+
* @license lucide-react v0.576.0 - ISC
|
|
3577
|
+
*
|
|
3578
|
+
* This source code is licensed under the ISC license.
|
|
3579
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
3580
|
+
*/
|
|
2820
3581
|
var MousePointerClick = createLucideIcon("mouse-pointer-click", [
|
|
2821
3582
|
["path", {
|
|
2822
3583
|
d: "M14 4.1 12 6",
|
|
@@ -3079,6 +3840,32 @@ var Pencil = createLucideIcon("pencil", [["path", {
|
|
|
3079
3840
|
* This source code is licensed under the ISC license.
|
|
3080
3841
|
* See the LICENSE file in the root directory of this source tree.
|
|
3081
3842
|
*/
|
|
3843
|
+
var PersonStanding = createLucideIcon("person-standing", [
|
|
3844
|
+
["circle", {
|
|
3845
|
+
cx: "12",
|
|
3846
|
+
cy: "5",
|
|
3847
|
+
r: "1",
|
|
3848
|
+
key: "gxeob9"
|
|
3849
|
+
}],
|
|
3850
|
+
["path", {
|
|
3851
|
+
d: "m9 20 3-6 3 6",
|
|
3852
|
+
key: "se2kox"
|
|
3853
|
+
}],
|
|
3854
|
+
["path", {
|
|
3855
|
+
d: "m6 8 6 2 6-2",
|
|
3856
|
+
key: "4o3us4"
|
|
3857
|
+
}],
|
|
3858
|
+
["path", {
|
|
3859
|
+
d: "M12 10v4",
|
|
3860
|
+
key: "1kjpxc"
|
|
3861
|
+
}]
|
|
3862
|
+
]);
|
|
3863
|
+
/**
|
|
3864
|
+
* @license lucide-react v0.576.0 - ISC
|
|
3865
|
+
*
|
|
3866
|
+
* This source code is licensed under the ISC license.
|
|
3867
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
3868
|
+
*/
|
|
3082
3869
|
var Phone = createLucideIcon("phone", [["path", {
|
|
3083
3870
|
d: "M13.832 16.568a1 1 0 0 0 1.213-.303l.355-.465A2 2 0 0 1 17 15h3a2 2 0 0 1 2 2v3a2 2 0 0 1-2 2A18 18 0 0 1 2 4a2 2 0 0 1 2-2h3a2 2 0 0 1 2 2v3a2 2 0 0 1-.8 1.6l-.468.351a1 1 0 0 0-.292 1.233 14 14 0 0 0 6.392 6.384",
|
|
3084
3871
|
key: "9njp5v"
|
|
@@ -3129,6 +3916,34 @@ var Play = createLucideIcon("play", [["path", {
|
|
|
3129
3916
|
* This source code is licensed under the ISC license.
|
|
3130
3917
|
* See the LICENSE file in the root directory of this source tree.
|
|
3131
3918
|
*/
|
|
3919
|
+
var PlugZap = createLucideIcon("plug-zap", [
|
|
3920
|
+
["path", {
|
|
3921
|
+
d: "M6.3 20.3a2.4 2.4 0 0 0 3.4 0L12 18l-6-6-2.3 2.3a2.4 2.4 0 0 0 0 3.4Z",
|
|
3922
|
+
key: "goz73y"
|
|
3923
|
+
}],
|
|
3924
|
+
["path", {
|
|
3925
|
+
d: "m2 22 3-3",
|
|
3926
|
+
key: "19mgm9"
|
|
3927
|
+
}],
|
|
3928
|
+
["path", {
|
|
3929
|
+
d: "M7.5 13.5 10 11",
|
|
3930
|
+
key: "7xgeeb"
|
|
3931
|
+
}],
|
|
3932
|
+
["path", {
|
|
3933
|
+
d: "M10.5 16.5 13 14",
|
|
3934
|
+
key: "10btkg"
|
|
3935
|
+
}],
|
|
3936
|
+
["path", {
|
|
3937
|
+
d: "m18 3-4 4h6l-4 4",
|
|
3938
|
+
key: "16psg9"
|
|
3939
|
+
}]
|
|
3940
|
+
]);
|
|
3941
|
+
/**
|
|
3942
|
+
* @license lucide-react v0.576.0 - ISC
|
|
3943
|
+
*
|
|
3944
|
+
* This source code is licensed under the ISC license.
|
|
3945
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
3946
|
+
*/
|
|
3132
3947
|
var Plus = createLucideIcon("plus", [["path", {
|
|
3133
3948
|
d: "M5 12h14",
|
|
3134
3949
|
key: "1ays0h"
|
|
@@ -3203,6 +4018,64 @@ var Power = createLucideIcon("power", [["path", {
|
|
|
3203
4018
|
* This source code is licensed under the ISC license.
|
|
3204
4019
|
* See the LICENSE file in the root directory of this source tree.
|
|
3205
4020
|
*/
|
|
4021
|
+
var Printer = createLucideIcon("printer", [
|
|
4022
|
+
["path", {
|
|
4023
|
+
d: "M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2",
|
|
4024
|
+
key: "143wyd"
|
|
4025
|
+
}],
|
|
4026
|
+
["path", {
|
|
4027
|
+
d: "M6 9V3a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v6",
|
|
4028
|
+
key: "1itne7"
|
|
4029
|
+
}],
|
|
4030
|
+
["rect", {
|
|
4031
|
+
x: "6",
|
|
4032
|
+
y: "14",
|
|
4033
|
+
width: "12",
|
|
4034
|
+
height: "8",
|
|
4035
|
+
rx: "1",
|
|
4036
|
+
key: "1ue0tg"
|
|
4037
|
+
}]
|
|
4038
|
+
]);
|
|
4039
|
+
/**
|
|
4040
|
+
* @license lucide-react v0.576.0 - ISC
|
|
4041
|
+
*
|
|
4042
|
+
* This source code is licensed under the ISC license.
|
|
4043
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
4044
|
+
*/
|
|
4045
|
+
var Projector = createLucideIcon("projector", [
|
|
4046
|
+
["path", {
|
|
4047
|
+
d: "M5 7 3 5",
|
|
4048
|
+
key: "1yys58"
|
|
4049
|
+
}],
|
|
4050
|
+
["path", {
|
|
4051
|
+
d: "M9 6V3",
|
|
4052
|
+
key: "1ptz9u"
|
|
4053
|
+
}],
|
|
4054
|
+
["path", {
|
|
4055
|
+
d: "m13 7 2-2",
|
|
4056
|
+
key: "1w3vmq"
|
|
4057
|
+
}],
|
|
4058
|
+
["circle", {
|
|
4059
|
+
cx: "9",
|
|
4060
|
+
cy: "13",
|
|
4061
|
+
r: "3",
|
|
4062
|
+
key: "1mma13"
|
|
4063
|
+
}],
|
|
4064
|
+
["path", {
|
|
4065
|
+
d: "M11.83 12H20a2 2 0 0 1 2 2v4a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2v-4a2 2 0 0 1 2-2h2.17",
|
|
4066
|
+
key: "2frwzc"
|
|
4067
|
+
}],
|
|
4068
|
+
["path", {
|
|
4069
|
+
d: "M16 16h2",
|
|
4070
|
+
key: "dnq2od"
|
|
4071
|
+
}]
|
|
4072
|
+
]);
|
|
4073
|
+
/**
|
|
4074
|
+
* @license lucide-react v0.576.0 - ISC
|
|
4075
|
+
*
|
|
4076
|
+
* This source code is licensed under the ISC license.
|
|
4077
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
4078
|
+
*/
|
|
3206
4079
|
var QrCode$1 = createLucideIcon("qr-code", [
|
|
3207
4080
|
["rect", {
|
|
3208
4081
|
width: "5",
|
|
@@ -3405,6 +4278,26 @@ var RefreshCw = createLucideIcon("refresh-cw", [
|
|
|
3405
4278
|
* This source code is licensed under the ISC license.
|
|
3406
4279
|
* See the LICENSE file in the root directory of this source tree.
|
|
3407
4280
|
*/
|
|
4281
|
+
var Refrigerator = createLucideIcon("refrigerator", [
|
|
4282
|
+
["path", {
|
|
4283
|
+
d: "M5 6a4 4 0 0 1 4-4h6a4 4 0 0 1 4 4v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6Z",
|
|
4284
|
+
key: "fpq118"
|
|
4285
|
+
}],
|
|
4286
|
+
["path", {
|
|
4287
|
+
d: "M5 10h14",
|
|
4288
|
+
key: "elsbfy"
|
|
4289
|
+
}],
|
|
4290
|
+
["path", {
|
|
4291
|
+
d: "M15 7v6",
|
|
4292
|
+
key: "1nx30x"
|
|
4293
|
+
}]
|
|
4294
|
+
]);
|
|
4295
|
+
/**
|
|
4296
|
+
* @license lucide-react v0.576.0 - ISC
|
|
4297
|
+
*
|
|
4298
|
+
* This source code is licensed under the ISC license.
|
|
4299
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
4300
|
+
*/
|
|
3408
4301
|
var RotateCcw = createLucideIcon("rotate-ccw", [["path", {
|
|
3409
4302
|
d: "M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8",
|
|
3410
4303
|
key: "1357e3"
|
|
@@ -3431,6 +4324,66 @@ var RotateCw = createLucideIcon("rotate-cw", [["path", {
|
|
|
3431
4324
|
* This source code is licensed under the ISC license.
|
|
3432
4325
|
* See the LICENSE file in the root directory of this source tree.
|
|
3433
4326
|
*/
|
|
4327
|
+
var Route = createLucideIcon("route", [
|
|
4328
|
+
["circle", {
|
|
4329
|
+
cx: "6",
|
|
4330
|
+
cy: "19",
|
|
4331
|
+
r: "3",
|
|
4332
|
+
key: "1kj8tv"
|
|
4333
|
+
}],
|
|
4334
|
+
["path", {
|
|
4335
|
+
d: "M9 19h8.5a3.5 3.5 0 0 0 0-7h-11a3.5 3.5 0 0 1 0-7H15",
|
|
4336
|
+
key: "1d8sl"
|
|
4337
|
+
}],
|
|
4338
|
+
["circle", {
|
|
4339
|
+
cx: "18",
|
|
4340
|
+
cy: "5",
|
|
4341
|
+
r: "3",
|
|
4342
|
+
key: "gq8acd"
|
|
4343
|
+
}]
|
|
4344
|
+
]);
|
|
4345
|
+
/**
|
|
4346
|
+
* @license lucide-react v0.576.0 - ISC
|
|
4347
|
+
*
|
|
4348
|
+
* This source code is licensed under the ISC license.
|
|
4349
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
4350
|
+
*/
|
|
4351
|
+
var Router = createLucideIcon("router", [
|
|
4352
|
+
["rect", {
|
|
4353
|
+
width: "20",
|
|
4354
|
+
height: "8",
|
|
4355
|
+
x: "2",
|
|
4356
|
+
y: "14",
|
|
4357
|
+
rx: "2",
|
|
4358
|
+
key: "w68u3i"
|
|
4359
|
+
}],
|
|
4360
|
+
["path", {
|
|
4361
|
+
d: "M6.01 18H6",
|
|
4362
|
+
key: "19vcac"
|
|
4363
|
+
}],
|
|
4364
|
+
["path", {
|
|
4365
|
+
d: "M10.01 18H10",
|
|
4366
|
+
key: "uamcmx"
|
|
4367
|
+
}],
|
|
4368
|
+
["path", {
|
|
4369
|
+
d: "M15 10v4",
|
|
4370
|
+
key: "qjz1xs"
|
|
4371
|
+
}],
|
|
4372
|
+
["path", {
|
|
4373
|
+
d: "M17.84 7.17a4 4 0 0 0-5.66 0",
|
|
4374
|
+
key: "1rif40"
|
|
4375
|
+
}],
|
|
4376
|
+
["path", {
|
|
4377
|
+
d: "M20.66 4.34a8 8 0 0 0-11.31 0",
|
|
4378
|
+
key: "6a5xfq"
|
|
4379
|
+
}]
|
|
4380
|
+
]);
|
|
4381
|
+
/**
|
|
4382
|
+
* @license lucide-react v0.576.0 - ISC
|
|
4383
|
+
*
|
|
4384
|
+
* This source code is licensed under the ISC license.
|
|
4385
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
4386
|
+
*/
|
|
3434
4387
|
var Sailboat = createLucideIcon("sailboat", [
|
|
3435
4388
|
["path", {
|
|
3436
4389
|
d: "M10 2v15",
|
|
@@ -3904,6 +4857,64 @@ var Snowflake = createLucideIcon("snowflake", [
|
|
|
3904
4857
|
* This source code is licensed under the ISC license.
|
|
3905
4858
|
* See the LICENSE file in the root directory of this source tree.
|
|
3906
4859
|
*/
|
|
4860
|
+
var Sofa = createLucideIcon("sofa", [
|
|
4861
|
+
["path", {
|
|
4862
|
+
d: "M20 9V6a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v3",
|
|
4863
|
+
key: "1dgpiv"
|
|
4864
|
+
}],
|
|
4865
|
+
["path", {
|
|
4866
|
+
d: "M2 16a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-5a2 2 0 0 0-4 0v1.5a.5.5 0 0 1-.5.5h-11a.5.5 0 0 1-.5-.5V11a2 2 0 0 0-4 0z",
|
|
4867
|
+
key: "xacw8m"
|
|
4868
|
+
}],
|
|
4869
|
+
["path", {
|
|
4870
|
+
d: "M4 18v2",
|
|
4871
|
+
key: "jwo5n2"
|
|
4872
|
+
}],
|
|
4873
|
+
["path", {
|
|
4874
|
+
d: "M20 18v2",
|
|
4875
|
+
key: "1ar1qi"
|
|
4876
|
+
}],
|
|
4877
|
+
["path", {
|
|
4878
|
+
d: "M12 4v9",
|
|
4879
|
+
key: "oqhhn3"
|
|
4880
|
+
}]
|
|
4881
|
+
]);
|
|
4882
|
+
/**
|
|
4883
|
+
* @license lucide-react v0.576.0 - ISC
|
|
4884
|
+
*
|
|
4885
|
+
* This source code is licensed under the ISC license.
|
|
4886
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
4887
|
+
*/
|
|
4888
|
+
var Speaker = createLucideIcon("speaker", [
|
|
4889
|
+
["rect", {
|
|
4890
|
+
width: "16",
|
|
4891
|
+
height: "20",
|
|
4892
|
+
x: "4",
|
|
4893
|
+
y: "2",
|
|
4894
|
+
rx: "2",
|
|
4895
|
+
key: "1nb95v"
|
|
4896
|
+
}],
|
|
4897
|
+
["path", {
|
|
4898
|
+
d: "M12 6h.01",
|
|
4899
|
+
key: "1vi96p"
|
|
4900
|
+
}],
|
|
4901
|
+
["circle", {
|
|
4902
|
+
cx: "12",
|
|
4903
|
+
cy: "14",
|
|
4904
|
+
r: "4",
|
|
4905
|
+
key: "1jruaj"
|
|
4906
|
+
}],
|
|
4907
|
+
["path", {
|
|
4908
|
+
d: "M12 14h.01",
|
|
4909
|
+
key: "1etili"
|
|
4910
|
+
}]
|
|
4911
|
+
]);
|
|
4912
|
+
/**
|
|
4913
|
+
* @license lucide-react v0.576.0 - ISC
|
|
4914
|
+
*
|
|
4915
|
+
* This source code is licensed under the ISC license.
|
|
4916
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
4917
|
+
*/
|
|
3907
4918
|
var Sparkles = createLucideIcon("sparkles", [
|
|
3908
4919
|
["path", {
|
|
3909
4920
|
d: "M11.017 2.814a1 1 0 0 1 1.966 0l1.051 5.558a2 2 0 0 0 1.594 1.594l5.558 1.051a1 1 0 0 1 0 1.966l-5.558 1.051a2 2 0 0 0-1.594 1.594l-1.051 5.558a1 1 0 0 1-1.966 0l-1.051-5.558a2 2 0 0 0-1.594-1.594l-5.558-1.051a1 1 0 0 1 0-1.966l5.558-1.051a2 2 0 0 0 1.594-1.594z",
|
|
@@ -3974,6 +4985,26 @@ var Star = createLucideIcon("star", [["path", {
|
|
|
3974
4985
|
* This source code is licensed under the ISC license.
|
|
3975
4986
|
* See the LICENSE file in the root directory of this source tree.
|
|
3976
4987
|
*/
|
|
4988
|
+
var Store = createLucideIcon("store", [
|
|
4989
|
+
["path", {
|
|
4990
|
+
d: "M15 21v-5a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v5",
|
|
4991
|
+
key: "slp6dd"
|
|
4992
|
+
}],
|
|
4993
|
+
["path", {
|
|
4994
|
+
d: "M17.774 10.31a1.12 1.12 0 0 0-1.549 0 2.5 2.5 0 0 1-3.451 0 1.12 1.12 0 0 0-1.548 0 2.5 2.5 0 0 1-3.452 0 1.12 1.12 0 0 0-1.549 0 2.5 2.5 0 0 1-3.77-3.248l2.889-4.184A2 2 0 0 1 7 2h10a2 2 0 0 1 1.653.873l2.895 4.192a2.5 2.5 0 0 1-3.774 3.244",
|
|
4995
|
+
key: "o0xfot"
|
|
4996
|
+
}],
|
|
4997
|
+
["path", {
|
|
4998
|
+
d: "M4 10.95V19a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8.05",
|
|
4999
|
+
key: "wn3emo"
|
|
5000
|
+
}]
|
|
5001
|
+
]);
|
|
5002
|
+
/**
|
|
5003
|
+
* @license lucide-react v0.576.0 - ISC
|
|
5004
|
+
*
|
|
5005
|
+
* This source code is licensed under the ISC license.
|
|
5006
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
5007
|
+
*/
|
|
3977
5008
|
var SunMedium = createLucideIcon("sun-medium", [
|
|
3978
5009
|
["circle", {
|
|
3979
5010
|
cx: "12",
|
|
@@ -4106,6 +5137,27 @@ var Sunrise = createLucideIcon("sunrise", [
|
|
|
4106
5137
|
* This source code is licensed under the ISC license.
|
|
4107
5138
|
* See the LICENSE file in the root directory of this source tree.
|
|
4108
5139
|
*/
|
|
5140
|
+
var Tablet = createLucideIcon("tablet", [["rect", {
|
|
5141
|
+
width: "16",
|
|
5142
|
+
height: "20",
|
|
5143
|
+
x: "4",
|
|
5144
|
+
y: "2",
|
|
5145
|
+
rx: "2",
|
|
5146
|
+
ry: "2",
|
|
5147
|
+
key: "76otgf"
|
|
5148
|
+
}], ["line", {
|
|
5149
|
+
x1: "12",
|
|
5150
|
+
x2: "12.01",
|
|
5151
|
+
y1: "18",
|
|
5152
|
+
y2: "18",
|
|
5153
|
+
key: "1dp563"
|
|
5154
|
+
}]]);
|
|
5155
|
+
/**
|
|
5156
|
+
* @license lucide-react v0.576.0 - ISC
|
|
5157
|
+
*
|
|
5158
|
+
* This source code is licensed under the ISC license.
|
|
5159
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
5160
|
+
*/
|
|
4109
5161
|
var Tag = createLucideIcon("tag", [["path", {
|
|
4110
5162
|
d: "M12.586 2.586A2 2 0 0 0 11.172 2H4a2 2 0 0 0-2 2v7.172a2 2 0 0 0 .586 1.414l8.704 8.704a2.426 2.426 0 0 0 3.42 0l6.58-6.58a2.426 2.426 0 0 0 0-3.42z",
|
|
4111
5163
|
key: "vktsd0"
|
|
@@ -4148,6 +5200,46 @@ var Target = createLucideIcon("target", [
|
|
|
4148
5200
|
* This source code is licensed under the ISC license.
|
|
4149
5201
|
* See the LICENSE file in the root directory of this source tree.
|
|
4150
5202
|
*/
|
|
5203
|
+
var ThermometerSnowflake = createLucideIcon("thermometer-snowflake", [
|
|
5204
|
+
["path", {
|
|
5205
|
+
d: "m10 20-1.25-2.5L6 18",
|
|
5206
|
+
key: "18frcb"
|
|
5207
|
+
}],
|
|
5208
|
+
["path", {
|
|
5209
|
+
d: "M10 4 8.75 6.5 6 6",
|
|
5210
|
+
key: "7mghy3"
|
|
5211
|
+
}],
|
|
5212
|
+
["path", {
|
|
5213
|
+
d: "M10.585 15H10",
|
|
5214
|
+
key: "4nqulp"
|
|
5215
|
+
}],
|
|
5216
|
+
["path", {
|
|
5217
|
+
d: "M2 12h6.5L10 9",
|
|
5218
|
+
key: "kv9z4n"
|
|
5219
|
+
}],
|
|
5220
|
+
["path", {
|
|
5221
|
+
d: "M20 14.54a4 4 0 1 1-4 0V4a2 2 0 0 1 4 0z",
|
|
5222
|
+
key: "yu0u2z"
|
|
5223
|
+
}],
|
|
5224
|
+
["path", {
|
|
5225
|
+
d: "m4 10 1.5 2L4 14",
|
|
5226
|
+
key: "k9enpj"
|
|
5227
|
+
}],
|
|
5228
|
+
["path", {
|
|
5229
|
+
d: "m7 21 3-6-1.5-3",
|
|
5230
|
+
key: "j8hb9u"
|
|
5231
|
+
}],
|
|
5232
|
+
["path", {
|
|
5233
|
+
d: "m7 3 3 6h2",
|
|
5234
|
+
key: "1bbqgq"
|
|
5235
|
+
}]
|
|
5236
|
+
]);
|
|
5237
|
+
/**
|
|
5238
|
+
* @license lucide-react v0.576.0 - ISC
|
|
5239
|
+
*
|
|
5240
|
+
* This source code is licensed under the ISC license.
|
|
5241
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
5242
|
+
*/
|
|
4151
5243
|
var Thermometer = createLucideIcon("thermometer", [["path", {
|
|
4152
5244
|
d: "M14 4v10.54a4 4 0 1 1-4 0V4a2 2 0 0 1 4 0Z",
|
|
4153
5245
|
key: "17jzev"
|
|
@@ -4158,6 +5250,66 @@ var Thermometer = createLucideIcon("thermometer", [["path", {
|
|
|
4158
5250
|
* This source code is licensed under the ISC license.
|
|
4159
5251
|
* See the LICENSE file in the root directory of this source tree.
|
|
4160
5252
|
*/
|
|
5253
|
+
var ThermometerSun = createLucideIcon("thermometer-sun", [
|
|
5254
|
+
["path", {
|
|
5255
|
+
d: "M12 2v2",
|
|
5256
|
+
key: "tus03m"
|
|
5257
|
+
}],
|
|
5258
|
+
["path", {
|
|
5259
|
+
d: "M12 8a4 4 0 0 0-1.645 7.647",
|
|
5260
|
+
key: "wz5p04"
|
|
5261
|
+
}],
|
|
5262
|
+
["path", {
|
|
5263
|
+
d: "M2 12h2",
|
|
5264
|
+
key: "1t8f8n"
|
|
5265
|
+
}],
|
|
5266
|
+
["path", {
|
|
5267
|
+
d: "M20 14.54a4 4 0 1 1-4 0V4a2 2 0 0 1 4 0z",
|
|
5268
|
+
key: "yu0u2z"
|
|
5269
|
+
}],
|
|
5270
|
+
["path", {
|
|
5271
|
+
d: "m4.93 4.93 1.41 1.41",
|
|
5272
|
+
key: "149t6j"
|
|
5273
|
+
}],
|
|
5274
|
+
["path", {
|
|
5275
|
+
d: "m6.34 17.66-1.41 1.41",
|
|
5276
|
+
key: "1m8zz5"
|
|
5277
|
+
}]
|
|
5278
|
+
]);
|
|
5279
|
+
/**
|
|
5280
|
+
* @license lucide-react v0.576.0 - ISC
|
|
5281
|
+
*
|
|
5282
|
+
* This source code is licensed under the ISC license.
|
|
5283
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
5284
|
+
*/
|
|
5285
|
+
var Timer = createLucideIcon("timer", [
|
|
5286
|
+
["line", {
|
|
5287
|
+
x1: "10",
|
|
5288
|
+
x2: "14",
|
|
5289
|
+
y1: "2",
|
|
5290
|
+
y2: "2",
|
|
5291
|
+
key: "14vaq8"
|
|
5292
|
+
}],
|
|
5293
|
+
["line", {
|
|
5294
|
+
x1: "12",
|
|
5295
|
+
x2: "15",
|
|
5296
|
+
y1: "14",
|
|
5297
|
+
y2: "11",
|
|
5298
|
+
key: "17fdiu"
|
|
5299
|
+
}],
|
|
5300
|
+
["circle", {
|
|
5301
|
+
cx: "12",
|
|
5302
|
+
cy: "14",
|
|
5303
|
+
r: "8",
|
|
5304
|
+
key: "1e1u0o"
|
|
5305
|
+
}]
|
|
5306
|
+
]);
|
|
5307
|
+
/**
|
|
5308
|
+
* @license lucide-react v0.576.0 - ISC
|
|
5309
|
+
*
|
|
5310
|
+
* This source code is licensed under the ISC license.
|
|
5311
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
5312
|
+
*/
|
|
4161
5313
|
var ToggleLeft = createLucideIcon("toggle-left", [["circle", {
|
|
4162
5314
|
cx: "9",
|
|
4163
5315
|
cy: "12",
|
|
@@ -4304,6 +5456,43 @@ var Trash2 = createLucideIcon("trash-2", [
|
|
|
4304
5456
|
* This source code is licensed under the ISC license.
|
|
4305
5457
|
* See the LICENSE file in the root directory of this source tree.
|
|
4306
5458
|
*/
|
|
5459
|
+
var TreePine = createLucideIcon("tree-pine", [["path", {
|
|
5460
|
+
d: "m17 14 3 3.3a1 1 0 0 1-.7 1.7H4.7a1 1 0 0 1-.7-1.7L7 14h-.3a1 1 0 0 1-.7-1.7L9 9h-.2A1 1 0 0 1 8 7.3L12 3l4 4.3a1 1 0 0 1-.8 1.7H15l3 3.3a1 1 0 0 1-.7 1.7H17Z",
|
|
5461
|
+
key: "cpyugq"
|
|
5462
|
+
}], ["path", {
|
|
5463
|
+
d: "M12 22v-3",
|
|
5464
|
+
key: "kmzjlo"
|
|
5465
|
+
}]]);
|
|
5466
|
+
/**
|
|
5467
|
+
* @license lucide-react v0.576.0 - ISC
|
|
5468
|
+
*
|
|
5469
|
+
* This source code is licensed under the ISC license.
|
|
5470
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
5471
|
+
*/
|
|
5472
|
+
var Trees = createLucideIcon("trees", [
|
|
5473
|
+
["path", {
|
|
5474
|
+
d: "M10 10v.2A3 3 0 0 1 8.9 16H5a3 3 0 0 1-1-5.8V10a3 3 0 0 1 6 0Z",
|
|
5475
|
+
key: "1l6gj6"
|
|
5476
|
+
}],
|
|
5477
|
+
["path", {
|
|
5478
|
+
d: "M7 16v6",
|
|
5479
|
+
key: "1a82de"
|
|
5480
|
+
}],
|
|
5481
|
+
["path", {
|
|
5482
|
+
d: "M13 19v3",
|
|
5483
|
+
key: "13sx9i"
|
|
5484
|
+
}],
|
|
5485
|
+
["path", {
|
|
5486
|
+
d: "M12 19h8.3a1 1 0 0 0 .7-1.7L18 14h.3a1 1 0 0 0 .7-1.7L16 9h.2a1 1 0 0 0 .8-1.7L13 3l-1.4 1.5",
|
|
5487
|
+
key: "1sj9kv"
|
|
5488
|
+
}]
|
|
5489
|
+
]);
|
|
5490
|
+
/**
|
|
5491
|
+
* @license lucide-react v0.576.0 - ISC
|
|
5492
|
+
*
|
|
5493
|
+
* This source code is licensed under the ISC license.
|
|
5494
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
5495
|
+
*/
|
|
4307
5496
|
var TrendingUp = createLucideIcon("trending-up", [["path", {
|
|
4308
5497
|
d: "M16 7h6v6",
|
|
4309
5498
|
key: "box55l"
|
|
@@ -4382,6 +5571,23 @@ var Truck = createLucideIcon("truck", [
|
|
|
4382
5571
|
* This source code is licensed under the ISC license.
|
|
4383
5572
|
* See the LICENSE file in the root directory of this source tree.
|
|
4384
5573
|
*/
|
|
5574
|
+
var Tv = createLucideIcon("tv", [["path", {
|
|
5575
|
+
d: "m17 2-5 5-5-5",
|
|
5576
|
+
key: "16satq"
|
|
5577
|
+
}], ["rect", {
|
|
5578
|
+
width: "20",
|
|
5579
|
+
height: "15",
|
|
5580
|
+
x: "2",
|
|
5581
|
+
y: "7",
|
|
5582
|
+
rx: "2",
|
|
5583
|
+
key: "1e6viu"
|
|
5584
|
+
}]]);
|
|
5585
|
+
/**
|
|
5586
|
+
* @license lucide-react v0.576.0 - ISC
|
|
5587
|
+
*
|
|
5588
|
+
* This source code is licensed under the ISC license.
|
|
5589
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
5590
|
+
*/
|
|
4385
5591
|
var Type = createLucideIcon("type", [
|
|
4386
5592
|
["path", {
|
|
4387
5593
|
d: "M12 4v16",
|
|
@@ -4402,6 +5608,26 @@ var Type = createLucideIcon("type", [
|
|
|
4402
5608
|
* This source code is licensed under the ISC license.
|
|
4403
5609
|
* See the LICENSE file in the root directory of this source tree.
|
|
4404
5610
|
*/
|
|
5611
|
+
var Umbrella = createLucideIcon("umbrella", [
|
|
5612
|
+
["path", {
|
|
5613
|
+
d: "M12 13v7a2 2 0 0 0 4 0",
|
|
5614
|
+
key: "rpgb42"
|
|
5615
|
+
}],
|
|
5616
|
+
["path", {
|
|
5617
|
+
d: "M12 2v2",
|
|
5618
|
+
key: "tus03m"
|
|
5619
|
+
}],
|
|
5620
|
+
["path", {
|
|
5621
|
+
d: "M20.992 13a1 1 0 0 0 .97-1.274 10.284 10.284 0 0 0-19.923 0A1 1 0 0 0 3 13z",
|
|
5622
|
+
key: "124nyo"
|
|
5623
|
+
}]
|
|
5624
|
+
]);
|
|
5625
|
+
/**
|
|
5626
|
+
* @license lucide-react v0.576.0 - ISC
|
|
5627
|
+
*
|
|
5628
|
+
* This source code is licensed under the ISC license.
|
|
5629
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
5630
|
+
*/
|
|
4405
5631
|
var Undo2 = createLucideIcon("undo-2", [["path", {
|
|
4406
5632
|
d: "M9 14 4 9l5-5",
|
|
4407
5633
|
key: "102s5s"
|
|
@@ -4532,6 +5758,26 @@ var UtensilsCrossed = createLucideIcon("utensils-crossed", [
|
|
|
4532
5758
|
* This source code is licensed under the ISC license.
|
|
4533
5759
|
* See the LICENSE file in the root directory of this source tree.
|
|
4534
5760
|
*/
|
|
5761
|
+
var Utensils = createLucideIcon("utensils", [
|
|
5762
|
+
["path", {
|
|
5763
|
+
d: "M3 2v7c0 1.1.9 2 2 2h4a2 2 0 0 0 2-2V2",
|
|
5764
|
+
key: "cjf0a3"
|
|
5765
|
+
}],
|
|
5766
|
+
["path", {
|
|
5767
|
+
d: "M7 2v20",
|
|
5768
|
+
key: "1473qp"
|
|
5769
|
+
}],
|
|
5770
|
+
["path", {
|
|
5771
|
+
d: "M21 15V2a5 5 0 0 0-5 5v6c0 1.1.9 2 2 2h3Zm0 0v7",
|
|
5772
|
+
key: "j28e5"
|
|
5773
|
+
}]
|
|
5774
|
+
]);
|
|
5775
|
+
/**
|
|
5776
|
+
* @license lucide-react v0.576.0 - ISC
|
|
5777
|
+
*
|
|
5778
|
+
* This source code is licensed under the ISC license.
|
|
5779
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
5780
|
+
*/
|
|
4535
5781
|
var Vibrate = createLucideIcon("vibrate", [
|
|
4536
5782
|
["path", {
|
|
4537
5783
|
d: "m2 8 2 2-2 2 2 2-2 2",
|
|
@@ -4556,6 +5802,43 @@ var Vibrate = createLucideIcon("vibrate", [
|
|
|
4556
5802
|
* This source code is licensed under the ISC license.
|
|
4557
5803
|
* See the LICENSE file in the root directory of this source tree.
|
|
4558
5804
|
*/
|
|
5805
|
+
var VideoOff = createLucideIcon("video-off", [
|
|
5806
|
+
["path", {
|
|
5807
|
+
d: "M10.66 6H14a2 2 0 0 1 2 2v2.5l5.248-3.062A.5.5 0 0 1 22 7.87v8.196",
|
|
5808
|
+
key: "w8jjjt"
|
|
5809
|
+
}],
|
|
5810
|
+
["path", {
|
|
5811
|
+
d: "M16 16a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h2",
|
|
5812
|
+
key: "1xawa7"
|
|
5813
|
+
}],
|
|
5814
|
+
["path", {
|
|
5815
|
+
d: "m2 2 20 20",
|
|
5816
|
+
key: "1ooewy"
|
|
5817
|
+
}]
|
|
5818
|
+
]);
|
|
5819
|
+
/**
|
|
5820
|
+
* @license lucide-react v0.576.0 - ISC
|
|
5821
|
+
*
|
|
5822
|
+
* This source code is licensed under the ISC license.
|
|
5823
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
5824
|
+
*/
|
|
5825
|
+
var Video = createLucideIcon("video", [["path", {
|
|
5826
|
+
d: "m16 13 5.223 3.482a.5.5 0 0 0 .777-.416V7.87a.5.5 0 0 0-.752-.432L16 10.5",
|
|
5827
|
+
key: "ftymec"
|
|
5828
|
+
}], ["rect", {
|
|
5829
|
+
x: "2",
|
|
5830
|
+
y: "6",
|
|
5831
|
+
width: "14",
|
|
5832
|
+
height: "12",
|
|
5833
|
+
rx: "2",
|
|
5834
|
+
key: "158x01"
|
|
5835
|
+
}]]);
|
|
5836
|
+
/**
|
|
5837
|
+
* @license lucide-react v0.576.0 - ISC
|
|
5838
|
+
*
|
|
5839
|
+
* This source code is licensed under the ISC license.
|
|
5840
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
5841
|
+
*/
|
|
4559
5842
|
var Volume2 = createLucideIcon("volume-2", [
|
|
4560
5843
|
["path", {
|
|
4561
5844
|
d: "M11 4.702a.705.705 0 0 0-1.203-.498L6.413 7.587A1.4 1.4 0 0 1 5.416 8H3a1 1 0 0 0-1 1v6a1 1 0 0 0 1 1h2.416a1.4 1.4 0 0 1 .997.413l3.383 3.384A.705.705 0 0 0 11 19.298z",
|
|
@@ -4602,6 +5885,92 @@ var VolumeX = createLucideIcon("volume-x", [
|
|
|
4602
5885
|
* This source code is licensed under the ISC license.
|
|
4603
5886
|
* See the LICENSE file in the root directory of this source tree.
|
|
4604
5887
|
*/
|
|
5888
|
+
var Warehouse = createLucideIcon("warehouse", [
|
|
5889
|
+
["path", {
|
|
5890
|
+
d: "M18 21V10a1 1 0 0 0-1-1H7a1 1 0 0 0-1 1v11",
|
|
5891
|
+
key: "pb2vm6"
|
|
5892
|
+
}],
|
|
5893
|
+
["path", {
|
|
5894
|
+
d: "M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V8a2 2 0 0 1 1.132-1.803l7.95-3.974a2 2 0 0 1 1.837 0l7.948 3.974A2 2 0 0 1 22 8z",
|
|
5895
|
+
key: "doq5xv"
|
|
5896
|
+
}],
|
|
5897
|
+
["path", {
|
|
5898
|
+
d: "M6 13h12",
|
|
5899
|
+
key: "yf64js"
|
|
5900
|
+
}],
|
|
5901
|
+
["path", {
|
|
5902
|
+
d: "M6 17h12",
|
|
5903
|
+
key: "1jwigz"
|
|
5904
|
+
}]
|
|
5905
|
+
]);
|
|
5906
|
+
/**
|
|
5907
|
+
* @license lucide-react v0.576.0 - ISC
|
|
5908
|
+
*
|
|
5909
|
+
* This source code is licensed under the ISC license.
|
|
5910
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
5911
|
+
*/
|
|
5912
|
+
var WashingMachine = createLucideIcon("washing-machine", [
|
|
5913
|
+
["path", {
|
|
5914
|
+
d: "M3 6h3",
|
|
5915
|
+
key: "155dbl"
|
|
5916
|
+
}],
|
|
5917
|
+
["path", {
|
|
5918
|
+
d: "M17 6h.01",
|
|
5919
|
+
key: "e2y6kg"
|
|
5920
|
+
}],
|
|
5921
|
+
["rect", {
|
|
5922
|
+
width: "18",
|
|
5923
|
+
height: "20",
|
|
5924
|
+
x: "3",
|
|
5925
|
+
y: "2",
|
|
5926
|
+
rx: "2",
|
|
5927
|
+
key: "od3kk9"
|
|
5928
|
+
}],
|
|
5929
|
+
["circle", {
|
|
5930
|
+
cx: "12",
|
|
5931
|
+
cy: "13",
|
|
5932
|
+
r: "5",
|
|
5933
|
+
key: "nlbqau"
|
|
5934
|
+
}],
|
|
5935
|
+
["path", {
|
|
5936
|
+
d: "M12 18a2.5 2.5 0 0 0 0-5 2.5 2.5 0 0 1 0-5",
|
|
5937
|
+
key: "17lach"
|
|
5938
|
+
}]
|
|
5939
|
+
]);
|
|
5940
|
+
/**
|
|
5941
|
+
* @license lucide-react v0.576.0 - ISC
|
|
5942
|
+
*
|
|
5943
|
+
* This source code is licensed under the ISC license.
|
|
5944
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
5945
|
+
*/
|
|
5946
|
+
var WavesLadder = createLucideIcon("waves-ladder", [
|
|
5947
|
+
["path", {
|
|
5948
|
+
d: "M19 5a2 2 0 0 0-2 2v11",
|
|
5949
|
+
key: "s41o68"
|
|
5950
|
+
}],
|
|
5951
|
+
["path", {
|
|
5952
|
+
d: "M2 18c.6.5 1.2 1 2.5 1 2.5 0 2.5-2 5-2 2.6 0 2.4 2 5 2 2.5 0 2.5-2 5-2 1.3 0 1.9.5 2.5 1",
|
|
5953
|
+
key: "rd2r6e"
|
|
5954
|
+
}],
|
|
5955
|
+
["path", {
|
|
5956
|
+
d: "M7 13h10",
|
|
5957
|
+
key: "1rwob1"
|
|
5958
|
+
}],
|
|
5959
|
+
["path", {
|
|
5960
|
+
d: "M7 9h10",
|
|
5961
|
+
key: "12czzb"
|
|
5962
|
+
}],
|
|
5963
|
+
["path", {
|
|
5964
|
+
d: "M9 5a2 2 0 0 0-2 2v11",
|
|
5965
|
+
key: "x0q4gh"
|
|
5966
|
+
}]
|
|
5967
|
+
]);
|
|
5968
|
+
/**
|
|
5969
|
+
* @license lucide-react v0.576.0 - ISC
|
|
5970
|
+
*
|
|
5971
|
+
* This source code is licensed under the ISC license.
|
|
5972
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
5973
|
+
*/
|
|
4605
5974
|
var Waves = createLucideIcon("waves", [
|
|
4606
5975
|
["path", {
|
|
4607
5976
|
d: "M2 6c.6.5 1.2 1 2.5 1C7 7 7 5 9.5 5c2.6 0 2.4 2 5 2 2.5 0 2.5-2 5-2 1.3 0 1.9.5 2.5 1",
|
|
@@ -7191,6 +8560,8 @@ var useVideoclipsListSources = trpc.videoclips.listSources.useQuery;
|
|
|
7191
8560
|
var useVideoclipsGetClipPlayback = trpc.videoclips.getClipPlayback.useQuery;
|
|
7192
8561
|
/** Generated alias around `trpc.videoclips.readClipBytes.useQuery`. */
|
|
7193
8562
|
var useVideoclipsReadClipBytes = trpc.videoclips.readClipBytes.useQuery;
|
|
8563
|
+
/** Generated alias around `trpc.videoclips.dialClipStream.useQuery`. */
|
|
8564
|
+
var useVideoclipsDialClipStream = trpc.videoclips.dialClipStream.useQuery;
|
|
7194
8565
|
/** Generated alias around `trpc.waterHeater.setTargetTemp.useMutation`. */
|
|
7195
8566
|
var useWaterHeaterSetTargetTemp = trpc.waterHeater.setTargetTemp.useMutation;
|
|
7196
8567
|
/** Generated alias around `trpc.waterHeater.setOperationMode.useMutation`. */
|
|
@@ -17662,38 +19033,6 @@ var cva = (base, config) => (props) => {
|
|
|
17662
19033
|
}, []), props === null || props === void 0 ? void 0 : props.class, props === null || props === void 0 ? void 0 : props.className);
|
|
17663
19034
|
};
|
|
17664
19035
|
//#endregion
|
|
17665
|
-
//#region src/primitives/badge.tsx
|
|
17666
|
-
var badgeVariants = cva("inline-flex items-center rounded-full text-xs font-medium px-2 py-0.5", {
|
|
17667
|
-
variants: {
|
|
17668
|
-
variant: {
|
|
17669
|
-
default: "bg-surface-hover text-foreground",
|
|
17670
|
-
success: "bg-success/15 text-success",
|
|
17671
|
-
warning: "bg-warning/15 text-warning",
|
|
17672
|
-
danger: "bg-danger/15 text-danger",
|
|
17673
|
-
info: "bg-info/15 text-info"
|
|
17674
|
-
},
|
|
17675
|
-
styleVariant: {
|
|
17676
|
-
solid: "",
|
|
17677
|
-
outline: "border bg-transparent"
|
|
17678
|
-
}
|
|
17679
|
-
},
|
|
17680
|
-
defaultVariants: {
|
|
17681
|
-
variant: "default",
|
|
17682
|
-
styleVariant: "solid"
|
|
17683
|
-
}
|
|
17684
|
-
});
|
|
17685
|
-
var Badge = forwardRef(({ className, variant, style, ...props }, ref) => {
|
|
17686
|
-
return /* @__PURE__ */ jsx("span", {
|
|
17687
|
-
ref,
|
|
17688
|
-
className: cn(badgeVariants({
|
|
17689
|
-
variant,
|
|
17690
|
-
styleVariant: style
|
|
17691
|
-
}), className),
|
|
17692
|
-
...props
|
|
17693
|
-
});
|
|
17694
|
-
});
|
|
17695
|
-
Badge.displayName = "Badge";
|
|
17696
|
-
//#endregion
|
|
17697
19036
|
//#region src/primitives/button.tsx
|
|
17698
19037
|
var buttonVariants = cva("inline-flex items-center justify-center rounded-md font-medium transition-colors cursor-pointer disabled:opacity-50 disabled:pointer-events-none", {
|
|
17699
19038
|
variants: {
|
|
@@ -17969,590 +19308,123 @@ function axisTicks(fromMs, toMs, count) {
|
|
|
17969
19308
|
return ticks;
|
|
17970
19309
|
}
|
|
17971
19310
|
//#endregion
|
|
17972
|
-
//#region src/
|
|
17973
|
-
var
|
|
17974
|
-
|
|
17975
|
-
|
|
17976
|
-
|
|
17977
|
-
|
|
17978
|
-
|
|
17979
|
-
|
|
17980
|
-
|
|
17981
|
-
|
|
17982
|
-
|
|
17983
|
-
|
|
17984
|
-
|
|
17985
|
-
|
|
17986
|
-
|
|
17987
|
-
|
|
17988
|
-
|
|
17989
|
-
|
|
17990
|
-
|
|
17991
|
-
|
|
17992
|
-
|
|
17993
|
-
|
|
17994
|
-
|
|
17995
|
-
|
|
17996
|
-
|
|
17997
|
-
|
|
17998
|
-
|
|
17999
|
-
|
|
18000
|
-
|
|
18001
|
-
|
|
18002
|
-
|
|
18003
|
-
|
|
18004
|
-
|
|
18005
|
-
}
|
|
18006
|
-
|
|
18007
|
-
|
|
18008
|
-
|
|
18009
|
-
|
|
18010
|
-
|
|
18011
|
-
* 768px ≤ width < 1024px. Use to drive layouts that should pack denser
|
|
18012
|
-
* than full-desktop but more legibly than mobile (e.g. icons-only
|
|
18013
|
-
* sidebar rail, narrower stat tiles).
|
|
18014
|
-
*/
|
|
18015
|
-
function useIsMidWidth() {
|
|
18016
|
-
return useSyncExternalStore(subscribeQuery(MID_QUERY), getSnapshot(MID_QUERY), getServerSnapshot);
|
|
18017
|
-
}
|
|
18018
|
-
//#endregion
|
|
18019
|
-
//#region src/composites/data-table-layout.ts
|
|
18020
|
-
/**
|
|
18021
|
-
* At this many columns and above, `auto` switches a narrow viewport to cards.
|
|
18022
|
-
* Three columns still fit a phone at a readable size; four do not.
|
|
18023
|
-
*/
|
|
18024
|
-
var CARD_MODE_MIN_COLUMNS = 4;
|
|
18025
|
-
function resolveTableLayout({ mode, columnCount, isNarrow }) {
|
|
18026
|
-
if (!isNarrow) return "table";
|
|
18027
|
-
if (mode === "scroll") return "table";
|
|
18028
|
-
if (mode === "cards") return "cards";
|
|
18029
|
-
if (columnCount === 0) return "table";
|
|
18030
|
-
return columnCount >= 4 ? "cards" : "table";
|
|
19311
|
+
//#region src/composites/device-list/pagination.tsx
|
|
19312
|
+
var NEIGHBORS = 2;
|
|
19313
|
+
function computePageButtons(currentPage, totalPages) {
|
|
19314
|
+
if (totalPages <= 1) return [{
|
|
19315
|
+
kind: "page",
|
|
19316
|
+
n: 1
|
|
19317
|
+
}];
|
|
19318
|
+
if (totalPages <= 7) {
|
|
19319
|
+
const all = [];
|
|
19320
|
+
for (let i = 1; i <= totalPages; i++) all.push({
|
|
19321
|
+
kind: "page",
|
|
19322
|
+
n: i
|
|
19323
|
+
});
|
|
19324
|
+
return all;
|
|
19325
|
+
}
|
|
19326
|
+
const result = [];
|
|
19327
|
+
const leftBound = Math.max(2, currentPage - NEIGHBORS);
|
|
19328
|
+
const rightBound = Math.min(totalPages - 1, currentPage + NEIGHBORS);
|
|
19329
|
+
result.push({
|
|
19330
|
+
kind: "page",
|
|
19331
|
+
n: 1
|
|
19332
|
+
});
|
|
19333
|
+
if (leftBound > 2) result.push({
|
|
19334
|
+
kind: "ellipsis",
|
|
19335
|
+
side: "left"
|
|
19336
|
+
});
|
|
19337
|
+
for (let i = leftBound; i <= rightBound; i++) result.push({
|
|
19338
|
+
kind: "page",
|
|
19339
|
+
n: i
|
|
19340
|
+
});
|
|
19341
|
+
if (rightBound < totalPages - 1) result.push({
|
|
19342
|
+
kind: "ellipsis",
|
|
19343
|
+
side: "right"
|
|
19344
|
+
});
|
|
19345
|
+
result.push({
|
|
19346
|
+
kind: "page",
|
|
19347
|
+
n: totalPages
|
|
19348
|
+
});
|
|
19349
|
+
return result;
|
|
18031
19350
|
}
|
|
18032
|
-
|
|
18033
|
-
|
|
18034
|
-
|
|
18035
|
-
|
|
18036
|
-
*
|
|
18037
|
-
|
|
18038
|
-
* the right token from this file instead of hand-coding breakpoints.
|
|
18039
|
-
* Adopting the tokens uniformly is what makes the app feel consistent
|
|
18040
|
-
* across operator devices (mobile / tablet / desktop) and what unlocks
|
|
18041
|
-
* targeted tuning (e.g. shrink every label by 1px in one place).
|
|
18042
|
-
*
|
|
18043
|
-
* Tier definitions (Tailwind breakpoints):
|
|
18044
|
-
*
|
|
18045
|
-
* • **L1 — Compact** (`< 640px`, default = mobile portrait)
|
|
18046
|
-
* Single column, tight padding, smallest text, icon-only buttons
|
|
18047
|
-
* where labels can be inferred. The operator can still see every
|
|
18048
|
-
* stat / action — no horizontal scroll, no clipped text. The user
|
|
18049
|
-
* directive: "molta informazione in poco spazio quando la width è
|
|
18050
|
-
* bassa."
|
|
18051
|
-
*
|
|
18052
|
-
* • **L2 — Standard** (`sm` — `640–1023px`, tablet + small laptop)
|
|
18053
|
-
* 2-column grids, side panels become visible, button labels return.
|
|
18054
|
-
* Targets ~768px–1024px viewports — the most common operator sizes.
|
|
18055
|
-
*
|
|
18056
|
-
* • **L3 — Spacious** (`lg+` — `≥ 1024px`, desktop)
|
|
18057
|
-
* 4-column grids, generous padding, full-width header text,
|
|
18058
|
-
* side-by-side composite layouts. The operator has elbow room.
|
|
18059
|
-
*
|
|
18060
|
-
* Conventions:
|
|
18061
|
-
* - **Always start from L1** — the bare class is always the compact
|
|
18062
|
-
* variant, then `sm:` adds room at 640px, `lg:` at 1024px. No
|
|
18063
|
-
* desktop-first breakpoints; no max-width queries.
|
|
18064
|
-
* - **Token strings are static** — kept as `as const` so callers can
|
|
18065
|
-
* compose them via `cn()` / template literals without running a
|
|
18066
|
-
* class generator at runtime.
|
|
18067
|
-
* - **Pair the token with a comment** — the comment in the file
|
|
18068
|
-
* names every breakpoint it crosses, so a reader can predict the
|
|
18069
|
-
* layout without going to Tailwind docs.
|
|
18070
|
-
*/
|
|
18071
|
-
/** Container padding for a card-style section (header + body). */
|
|
18072
|
-
var SECTION_CARD = "rounded-lg border border-border bg-surface overflow-hidden";
|
|
18073
|
-
/** Header strip inside a card (between border-b lines). */
|
|
18074
|
-
var SECTION_HEADER = "border-b border-border px-3 sm:px-4 py-1.5 sm:py-2";
|
|
18075
|
-
/** Body padding for a card-style section. */
|
|
18076
|
-
var SECTION_BODY = "p-2 sm:p-3 lg:p-4";
|
|
18077
|
-
/** Gap between cards in a vertical stack. */
|
|
18078
|
-
var STACK_GAP = "space-y-3 sm:space-y-4";
|
|
18079
|
-
/** Gap between cards in a grid (4 cells / row at lg). */
|
|
18080
|
-
var GRID_GAP = "gap-2 sm:gap-3";
|
|
18081
|
-
/** Row padding inside a divided list (e.g. InfoRow). */
|
|
18082
|
-
var LIST_ROW = "px-3 sm:px-4 py-1.5 sm:py-2";
|
|
18083
|
-
/** 1-up at L1, 2-up at L2, 4-up at L3 — quick-stat row. */
|
|
18084
|
-
var GRID_QUICK_STATS = "grid grid-cols-2 sm:grid-cols-2 lg:grid-cols-4";
|
|
18085
|
-
/** 1-up at L1, 2-up at L2+ — paired panels (motion + detection rules). */
|
|
18086
|
-
var GRID_PAIRED = "grid grid-cols-1 lg:grid-cols-2";
|
|
18087
|
-
/** Side-by-side layout that stacks below md (canvas + side panel). */
|
|
18088
|
-
var SPLIT_PANEL_OUTER = "flex flex-col-reverse md:flex-row";
|
|
18089
|
-
/** Sidebar narrow lane in a SPLIT_PANEL_OUTER layout. */
|
|
18090
|
-
var SPLIT_PANEL_SIDE = "w-full md:w-44 lg:w-52 md:flex-shrink-0 border-b md:border-b-0 md:border-l border-border";
|
|
18091
|
-
/**
|
|
18092
|
-
* The tier boundary at which a settings label/value row stops stacking.
|
|
18093
|
-
*
|
|
18094
|
-
* Below it (L1 — compact) the row is ONE column: label on its own line, value
|
|
18095
|
-
* on the next at full width. Above it the row is label-left / value-right as
|
|
18096
|
-
* before. The two-column form needs `SETTING_ROW_LABEL`'s lane plus a readable
|
|
18097
|
-
* value beside it; a phone has neither, and the failure mode is not "cramped"
|
|
18098
|
-
* but "the value is the part that gets cut" — the one thing the operator
|
|
18099
|
-
* opened the page to read.
|
|
18100
|
-
*/
|
|
18101
|
-
var SETTING_ROW_STACK_BREAKPOINT = "sm";
|
|
18102
|
-
/** Outer row: single column at L1, label/value columns from `sm` up. */
|
|
18103
|
-
var SETTING_ROW = "flex min-w-0 flex-col gap-0.5 py-1.5 sm:flex-row sm:items-center";
|
|
18104
|
-
/** Label lane. Full width (and free to wrap) at L1; a fixed lane from `sm` up. */
|
|
18105
|
-
var SETTING_ROW_LABEL = "min-w-0 text-[11px] leading-tight text-foreground-subtle sm:w-32 sm:shrink-0 sm:pr-2";
|
|
18106
|
-
/**
|
|
18107
|
-
* Value lane — the value text plus its trailing affordances (copy / reveal).
|
|
18108
|
-
* `w-full` at L1 so the value owns the whole row once the label is above it;
|
|
18109
|
-
* `sm:flex-1` makes it share the row again from `sm` up.
|
|
18110
|
-
*/
|
|
18111
|
-
var SETTING_ROW_VALUE = "flex w-full min-w-0 items-center gap-1 sm:flex-1";
|
|
18112
|
-
/**
|
|
18113
|
-
* The value text itself. `break-all` lets an opaque token (a key, a URL) wrap
|
|
18114
|
-
* at L1 instead of being cut mid-word; `sm:truncate` restores the single-line
|
|
18115
|
-
* desktop form, where the row is wide enough for truncation to be a choice
|
|
18116
|
-
* rather than data loss.
|
|
18117
|
-
*/
|
|
18118
|
-
var SETTING_ROW_VALUE_TEXT = "min-w-0 break-all text-xs text-foreground sm:truncate";
|
|
18119
|
-
/** Section header label (uppercase tracking-wider). */
|
|
18120
|
-
var TEXT_SECTION_LABEL = "text-[10px] sm:text-[11px] font-semibold text-foreground uppercase tracking-wider";
|
|
18121
|
-
/** Field label inside a row. */
|
|
18122
|
-
var TEXT_FIELD_LABEL = "text-[11px] sm:text-xs text-foreground";
|
|
18123
|
-
/** Sub-label / hint text. */
|
|
18124
|
-
var TEXT_HINT = "text-[10px] text-foreground-subtle";
|
|
18125
|
-
/** Primary value (a metric, badge, …). */
|
|
18126
|
-
var TEXT_VALUE = "text-[11px] sm:text-xs font-medium text-foreground";
|
|
18127
|
-
/** Big metric value (StatCard). */
|
|
18128
|
-
var TEXT_METRIC = "text-base sm:text-lg font-semibold leading-tight text-foreground";
|
|
18129
|
-
/** Default compact button. */
|
|
18130
|
-
var BTN_COMPACT = "inline-flex items-center justify-center gap-1 rounded border border-border bg-surface px-1.5 py-0.5 sm:px-2 sm:py-1 text-[10px] sm:text-[11px] font-medium text-foreground hover:bg-surface-hover transition-colors disabled:opacity-40";
|
|
18131
|
-
/** Primary compact button. */
|
|
18132
|
-
var BTN_COMPACT_PRIMARY = "inline-flex items-center justify-center gap-1 rounded border border-primary/40 bg-primary/15 px-1.5 py-0.5 sm:px-2 sm:py-1 text-[10px] sm:text-[11px] font-medium text-primary hover:bg-primary/25 transition-colors disabled:opacity-40";
|
|
18133
|
-
/** Danger compact button. */
|
|
18134
|
-
var BTN_COMPACT_DANGER = "inline-flex items-center justify-center gap-1 rounded border border-danger/40 bg-danger/10 px-1.5 py-0.5 sm:px-2 sm:py-1 text-[10px] sm:text-[11px] font-medium text-danger hover:bg-danger/20 transition-colors disabled:opacity-40";
|
|
18135
|
-
/** Warning compact button (e.g. cancel-drawing). */
|
|
18136
|
-
var BTN_COMPACT_WARNING = "inline-flex items-center justify-center gap-1 rounded border border-warning/40 bg-warning/10 px-1.5 py-0.5 sm:px-2 sm:py-1 text-[10px] sm:text-[11px] font-medium text-warning hover:bg-warning/20 transition-colors disabled:opacity-40";
|
|
18137
|
-
/** Compact text/select/number input. */
|
|
18138
|
-
var INPUT_COMPACT = "w-full rounded border border-border bg-background px-1.5 py-0.5 sm:px-2 sm:py-1 text-[11px] sm:text-xs text-foreground focus:border-primary focus:ring-1 focus:ring-primary/30 outline-none";
|
|
18139
|
-
/** Chip-style toggle (zone / class selectors in ZoneRulesEditor). */
|
|
18140
|
-
var CHIP_BASE = "inline-flex items-center gap-1 rounded-full border px-1.5 py-0.5 text-[10px] font-medium transition-colors";
|
|
18141
|
-
var CHIP_ACTIVE = "border-primary/50 bg-primary/15 text-primary";
|
|
18142
|
-
var CHIP_INACTIVE = "border-border bg-surface text-foreground-subtle hover:bg-surface-hover";
|
|
18143
|
-
//#endregion
|
|
18144
|
-
//#region src/composites/setting-row.tsx
|
|
18145
|
-
function SettingRow({ label, children, actions, elements = "plain", className, valueClassName }) {
|
|
18146
|
-
const LabelTag = elements === "description" ? "dt" : "span";
|
|
18147
|
-
const ValueTag = elements === "description" ? "dd" : "div";
|
|
19351
|
+
function Pagination({ currentPage, totalItems, pageSize, onPageChange, itemNoun = "devices" }) {
|
|
19352
|
+
if (totalItems <= pageSize) return null;
|
|
19353
|
+
const totalPages = Math.ceil(totalItems / pageSize);
|
|
19354
|
+
const startIdx = (currentPage - 1) * pageSize + 1;
|
|
19355
|
+
const endIdx = Math.min(currentPage * pageSize, totalItems);
|
|
19356
|
+
const buttons = computePageButtons(currentPage, totalPages);
|
|
18148
19357
|
return /* @__PURE__ */ jsxs("div", {
|
|
18149
|
-
"
|
|
18150
|
-
|
|
18151
|
-
|
|
18152
|
-
|
|
18153
|
-
|
|
18154
|
-
|
|
18155
|
-
|
|
18156
|
-
|
|
18157
|
-
|
|
18158
|
-
|
|
18159
|
-
|
|
18160
|
-
|
|
18161
|
-
|
|
18162
|
-
|
|
18163
|
-
|
|
18164
|
-
|
|
18165
|
-
|
|
19358
|
+
className: "flex items-center justify-between gap-4 flex-wrap pt-2 text-[11px] text-foreground-subtle",
|
|
19359
|
+
children: [/* @__PURE__ */ jsxs("span", { children: [
|
|
19360
|
+
"Showing ",
|
|
19361
|
+
startIdx,
|
|
19362
|
+
"–",
|
|
19363
|
+
endIdx,
|
|
19364
|
+
" of ",
|
|
19365
|
+
totalItems,
|
|
19366
|
+
" ",
|
|
19367
|
+
itemNoun
|
|
19368
|
+
] }), /* @__PURE__ */ jsxs("span", {
|
|
19369
|
+
className: "inline-flex items-center gap-1",
|
|
19370
|
+
children: [
|
|
19371
|
+
/* @__PURE__ */ jsx("button", {
|
|
19372
|
+
type: "button",
|
|
19373
|
+
"aria-label": "Previous page",
|
|
19374
|
+
disabled: currentPage === 1,
|
|
19375
|
+
onClick: () => onPageChange(currentPage - 1),
|
|
19376
|
+
className: cn("inline-flex items-center justify-center h-7 w-7 rounded border border-border bg-surface text-foreground-subtle", "hover:text-foreground hover:bg-surface-hover transition-colors", "disabled:opacity-40 disabled:cursor-not-allowed disabled:hover:bg-surface"),
|
|
19377
|
+
children: /* @__PURE__ */ jsx(ChevronLeft, { className: "h-3 w-3" })
|
|
19378
|
+
}),
|
|
19379
|
+
buttons.map((b, i) => {
|
|
19380
|
+
if (b.kind === "ellipsis") return /* @__PURE__ */ jsx("span", {
|
|
19381
|
+
className: "px-1 text-foreground-subtle/60 select-none",
|
|
19382
|
+
children: "…"
|
|
19383
|
+
}, `e-${i}`);
|
|
19384
|
+
return /* @__PURE__ */ jsx("button", {
|
|
19385
|
+
type: "button",
|
|
19386
|
+
onClick: () => onPageChange(b.n),
|
|
19387
|
+
className: cn("inline-flex items-center justify-center h-7 min-w-7 px-1.5 rounded border text-[10.5px] font-medium transition-colors", b.n === currentPage ? "border-primary/40 bg-primary/10 text-primary" : "border-border bg-surface text-foreground-subtle hover:text-foreground hover:bg-surface-hover"),
|
|
19388
|
+
children: b.n
|
|
19389
|
+
}, `p-${b.n}`);
|
|
19390
|
+
}),
|
|
19391
|
+
/* @__PURE__ */ jsx("button", {
|
|
19392
|
+
type: "button",
|
|
19393
|
+
"aria-label": "Next page",
|
|
19394
|
+
disabled: currentPage === totalPages,
|
|
19395
|
+
onClick: () => onPageChange(currentPage + 1),
|
|
19396
|
+
className: cn("inline-flex items-center justify-center h-7 w-7 rounded border border-border bg-surface text-foreground-subtle", "hover:text-foreground hover:bg-surface-hover transition-colors", "disabled:opacity-40 disabled:cursor-not-allowed disabled:hover:bg-surface"),
|
|
19397
|
+
children: /* @__PURE__ */ jsx(ChevronRight, { className: "h-3 w-3" })
|
|
19398
|
+
})
|
|
19399
|
+
]
|
|
18166
19400
|
})]
|
|
18167
19401
|
});
|
|
18168
19402
|
}
|
|
18169
19403
|
//#endregion
|
|
18170
|
-
//#region src/composites/
|
|
18171
|
-
function
|
|
18172
|
-
return /* @__PURE__ */ jsxs("
|
|
18173
|
-
|
|
18174
|
-
|
|
18175
|
-
|
|
18176
|
-
|
|
18177
|
-
|
|
18178
|
-
}
|
|
18179
|
-
|
|
18180
|
-
|
|
18181
|
-
|
|
18182
|
-
|
|
18183
|
-
|
|
18184
|
-
|
|
18185
|
-
|
|
18186
|
-
|
|
18187
|
-
|
|
18188
|
-
|
|
18189
|
-
|
|
18190
|
-
|
|
18191
|
-
|
|
18192
|
-
|
|
18193
|
-
|
|
18194
|
-
if (!sameColumn || currentDir === null) return "asc";
|
|
18195
|
-
return currentDir === "asc" ? "desc" : null;
|
|
18196
|
-
}
|
|
18197
|
-
/**
|
|
18198
|
-
* Toggle a column's sort on header click: none → asc → desc → none.
|
|
18199
|
-
* Clicking a DIFFERENT column starts it fresh at `asc`.
|
|
18200
|
-
*/
|
|
18201
|
-
function nextTableSort(current, columnKey) {
|
|
18202
|
-
const dir = nextSortDirection(current !== null && current.columnKey === columnKey, current === null ? null : current.dir);
|
|
18203
|
-
return dir === null ? null : {
|
|
18204
|
-
columnKey,
|
|
18205
|
-
dir
|
|
18206
|
-
};
|
|
18207
|
-
}
|
|
18208
|
-
/**
|
|
18209
|
-
* Ascending comparison of two cell values.
|
|
18210
|
-
*
|
|
18211
|
-
* Numbers compare numerically and strings compare with `localeCompare` — a
|
|
18212
|
-
* numeric column must never be ordered as text ("100" before "9"), and a text
|
|
18213
|
-
* column must respect the locale's collation. A mixed column (one row a
|
|
18214
|
-
* number, another a string) falls back to string comparison of both, which is
|
|
18215
|
-
* the only total order available; it is not a shape any caller should build on
|
|
18216
|
-
* purpose.
|
|
18217
|
-
*
|
|
18218
|
-
* `null` is NOT handled here — {@link sortRowsByColumn} pulls it out first,
|
|
18219
|
-
* because its placement is direction-independent and a comparator that is
|
|
18220
|
-
* multiplied by the direction factor cannot express that.
|
|
18221
|
-
*/
|
|
18222
|
-
function compareValues(a, b) {
|
|
18223
|
-
if (typeof a === "number" && typeof b === "number") return a - b;
|
|
18224
|
-
return String(a).localeCompare(String(b));
|
|
18225
|
-
}
|
|
18226
|
-
/**
|
|
18227
|
-
* Return a NEW array of `rows` ordered by `sort`.
|
|
18228
|
-
*
|
|
18229
|
-
* `valueOf` is the column's `sortValue` — it is called once per row per
|
|
18230
|
-
* comparison, so it must be cheap (read a field, do not format a string).
|
|
18231
|
-
* `sort === null` ⇒ a fresh shallow copy in the incoming order.
|
|
18232
|
-
*/
|
|
18233
|
-
function sortRowsByColumn(rows, sort, valueOf) {
|
|
18234
|
-
if (sort === null) return [...rows];
|
|
18235
|
-
const factor = sort.dir === "asc" ? 1 : -1;
|
|
18236
|
-
return rows.toSorted((a, b) => {
|
|
18237
|
-
const av = valueOf(a);
|
|
18238
|
-
const bv = valueOf(b);
|
|
18239
|
-
if (av === null || bv === null) {
|
|
18240
|
-
if (av === bv) return 0;
|
|
18241
|
-
return av === null ? 1 : -1;
|
|
18242
|
-
}
|
|
18243
|
-
return factor * compareValues(av, bv);
|
|
18244
|
-
});
|
|
18245
|
-
}
|
|
18246
|
-
/** Derive the `<th>` `aria-sort` for `columnKey` from the table's sort state. */
|
|
18247
|
-
function ariaSortForColumn(sort, columnKey) {
|
|
18248
|
-
if (sort === null || sort.columnKey !== columnKey) return "none";
|
|
18249
|
-
return sort.dir === "asc" ? "ascending" : "descending";
|
|
18250
|
-
}
|
|
18251
|
-
//#endregion
|
|
18252
|
-
//#region src/composites/data-table.tsx
|
|
18253
|
-
/**
|
|
18254
|
-
* DataTable — shared responsive table for admin pages.
|
|
18255
|
-
*
|
|
18256
|
-
* Recipes baked in:
|
|
18257
|
-
* - `overflow-x-auto` wrapper so narrow viewports don't clip the
|
|
18258
|
-
* right edge (the rounded border survives the scroll).
|
|
18259
|
-
* - `min-w-[Npx]` on the inner table so columns don't squash below
|
|
18260
|
-
* readable width before the scroll kicks in.
|
|
18261
|
-
* - `whitespace-nowrap` on headers — column titles never wrap to
|
|
18262
|
-
* two lines (`AUTO-KILL` was the regression that triggered this).
|
|
18263
|
-
* - Themed `bg-surface` + `border-border` so contrast works in both
|
|
18264
|
-
* light and dark themes.
|
|
18265
|
-
*
|
|
18266
|
-
* Column model: caller supplies `columns: DataColumn<T>[]` and
|
|
18267
|
-
* `rows: T[]`. Each column declares `header`, optional `align`,
|
|
18268
|
-
* optional `nowrap`, and a `render(row) => ReactNode` that produces
|
|
18269
|
-
* the cell content.
|
|
18270
|
-
*
|
|
18271
|
-
* <DataTable
|
|
18272
|
-
* columns={[
|
|
18273
|
-
* { key: 'username', header: 'Username', render: (u) => u.username },
|
|
18274
|
-
* { key: 'role', header: 'Role', render: (u) => <RoleBadge .../> },
|
|
18275
|
-
* { key: 'actions', header: '', align: 'right', render: (u) => <Actions .../> },
|
|
18276
|
-
* ]}
|
|
18277
|
-
* rows={users}
|
|
18278
|
-
* minWidthPx={560}
|
|
18279
|
-
* />
|
|
18280
|
-
*
|
|
18281
|
-
* If finer header markup is needed, pass `headerRender` instead of
|
|
18282
|
-
* `header` (e.g. for a sortable click affordance).
|
|
18283
|
-
*
|
|
18284
|
-
* ── Narrow viewports ──────────────────────────────────────────────────────
|
|
18285
|
-
* The table stays a table. The wrapper is `overflow-x-auto`, so a phone
|
|
18286
|
-
* scrolls the columns sideways INSIDE the table — the page body never moves
|
|
18287
|
-
* sideways, and the cells stay one line (`whitespace-nowrap`). That is the
|
|
18288
|
-
* default (`mobileMode="scroll"`). Cards are opt-in via `mobileMode="cards"`;
|
|
18289
|
-
* `auto` still applies the old column-count rule for a surface that wants it.
|
|
18290
|
-
* See `resolveTableLayout`.
|
|
18291
|
-
*
|
|
18292
|
-
* ── Scrolling the BODY, not the page ──────────────────────────────────────
|
|
18293
|
-
* `maxBodyHeight` caps the table and scrolls its rows INSIDE the container
|
|
18294
|
-
* with the column header pinned. It is ONE prop, not two, because "this list
|
|
18295
|
-
* scrolls internally" and "its header stays visible" are the same decision: a
|
|
18296
|
-
* capped table whose header scrolls away is a list of unlabelled cells.
|
|
18297
|
-
*
|
|
18298
|
-
* Use it wherever the row count is open-ended (rules, targets, delivery
|
|
18299
|
-
* history) so the page keeps its own header, filters and actions in view while
|
|
18300
|
-
* the operator moves through the rows.
|
|
18301
|
-
*/
|
|
18302
|
-
/**
|
|
18303
|
-
* The default cap for an internally-scrolling table.
|
|
18304
|
-
*
|
|
18305
|
-
* `60vh` leaves the page header, its filters and its actions on screen at
|
|
18306
|
-
* every viewport while still showing ~10 rows — and it is a fraction, so it
|
|
18307
|
-
* does not need a breakpoint of its own.
|
|
18308
|
-
*/
|
|
18309
|
-
var TABLE_SCROLL_MAX_H = "max-h-[60vh]";
|
|
18310
|
-
var ALIGN_CLASS = {
|
|
18311
|
-
left: "text-left",
|
|
18312
|
-
right: "text-right",
|
|
18313
|
-
center: "text-center"
|
|
18314
|
-
};
|
|
18315
|
-
function DataTable({ columns, rows, rowKey, onRowClick, minWidthPx = 480, emptyMessage, className, bordered = true, rowClassName, mobileMode = "scroll", maxBodyHeight, defaultSort }) {
|
|
18316
|
-
const isNarrow = useIsMobile();
|
|
18317
|
-
const [sort, setSort] = useState(defaultSort ?? null);
|
|
18318
|
-
const layout = resolveTableLayout({
|
|
18319
|
-
mode: mobileMode,
|
|
18320
|
-
columnCount: columns.length,
|
|
18321
|
-
isNarrow
|
|
18322
|
-
});
|
|
18323
|
-
const scrolls = maxBodyHeight !== void 0;
|
|
18324
|
-
const sortedColumn = useMemo(() => sort === null ? void 0 : columns.find((col) => col.key === sort.columnKey && col.sortValue !== void 0), [columns, sort]);
|
|
18325
|
-
const sortValue = sortedColumn?.sortValue;
|
|
18326
|
-
const displayRows = useMemo(() => sortValue === void 0 ? rows : sortRowsByColumn(rows, sort, sortValue), [
|
|
18327
|
-
rows,
|
|
18328
|
-
sort,
|
|
18329
|
-
sortValue
|
|
18330
|
-
]);
|
|
18331
|
-
const activeSort = sortedColumn === void 0 ? null : sort;
|
|
18332
|
-
if (rows.length === 0 && emptyMessage) return /* @__PURE__ */ jsx("div", {
|
|
18333
|
-
className: `rounded-lg ${bordered ? "border border-border" : ""} bg-surface px-3 py-4 text-xs text-foreground-subtle text-center ${className ?? ""}`,
|
|
18334
|
-
children: emptyMessage
|
|
18335
|
-
});
|
|
18336
|
-
if (rows.length === 0) return null;
|
|
18337
|
-
if (layout === "cards") return /* @__PURE__ */ jsx("div", {
|
|
18338
|
-
className: `space-y-2 ${scrolls ? `${maxBodyHeight} overflow-y-auto` : ""} ${className ?? ""}`,
|
|
18339
|
-
children: displayRows.map((row, rowIndex) => /* @__PURE__ */ jsx(DataTableCard, {
|
|
18340
|
-
row,
|
|
18341
|
-
rowIndex,
|
|
18342
|
-
columns,
|
|
18343
|
-
bordered,
|
|
18344
|
-
onRowClick,
|
|
18345
|
-
rowClassName
|
|
18346
|
-
}, rowKey ? rowKey(row, rowIndex) : rowIndex))
|
|
18347
|
-
});
|
|
18348
|
-
return /* @__PURE__ */ jsx("div", {
|
|
18349
|
-
className: [
|
|
18350
|
-
"rounded-lg",
|
|
18351
|
-
bordered ? "border border-border" : "",
|
|
18352
|
-
"bg-surface overflow-x-auto",
|
|
18353
|
-
scrolls ? `${maxBodyHeight} overflow-y-auto` : "",
|
|
18354
|
-
className ?? ""
|
|
18355
|
-
].filter(Boolean).join(" "),
|
|
18356
|
-
children: /* @__PURE__ */ jsxs("table", {
|
|
18357
|
-
className: `w-full text-xs ${scrolls ? "border-separate border-spacing-0" : ""}`,
|
|
18358
|
-
style: { minWidth: `${minWidthPx}px` },
|
|
18359
|
-
children: [/* @__PURE__ */ jsx("thead", {
|
|
18360
|
-
className: "bg-surface",
|
|
18361
|
-
children: /* @__PURE__ */ jsx("tr", { children: columns.map((col) => {
|
|
18362
|
-
const align = col.align ?? "left";
|
|
18363
|
-
const nowrap = col.nowrap ?? true;
|
|
18364
|
-
const sortable = col.sortValue !== void 0;
|
|
18365
|
-
const isSorted = activeSort !== null && activeSort.columnKey === col.key;
|
|
18366
|
-
return /* @__PURE__ */ jsx("th", {
|
|
18367
|
-
"aria-sort": sortable ? ariaSortForColumn(activeSort, col.key) : void 0,
|
|
18368
|
-
title: sortable ? void 0 : col.notSortableReason,
|
|
18369
|
-
className: [
|
|
18370
|
-
"px-3 py-2 text-foreground-subtle font-medium bg-surface border-b border-border",
|
|
18371
|
-
scrolls ? "sticky top-0 z-10" : "",
|
|
18372
|
-
ALIGN_CLASS[align],
|
|
18373
|
-
nowrap ? "whitespace-nowrap" : "",
|
|
18374
|
-
col.width ?? ""
|
|
18375
|
-
].filter(Boolean).join(" "),
|
|
18376
|
-
children: sortable ? /* @__PURE__ */ jsx(SortHeaderButton, {
|
|
18377
|
-
label: col.headerRender ? col.headerRender() : col.header,
|
|
18378
|
-
active: isSorted,
|
|
18379
|
-
dir: isSorted && activeSort !== null ? activeSort.dir : "asc",
|
|
18380
|
-
onSort: () => setSort((prev) => nextTableSort(prev, col.key))
|
|
18381
|
-
}) : col.headerRender ? col.headerRender() : col.header
|
|
18382
|
-
}, col.key);
|
|
18383
|
-
}) })
|
|
18384
|
-
}), /* @__PURE__ */ jsx("tbody", { children: displayRows.map((row, rowIndex) => {
|
|
18385
|
-
const key = rowKey ? rowKey(row, rowIndex) : rowIndex;
|
|
18386
|
-
const extra = rowClassName?.(row, rowIndex) ?? "";
|
|
18387
|
-
const interactive = onRowClick !== void 0;
|
|
18388
|
-
return /* @__PURE__ */ jsx("tr", {
|
|
18389
|
-
onClick: interactive ? () => onRowClick(row, rowIndex) : void 0,
|
|
18390
|
-
className: [interactive ? "cursor-pointer hover:bg-primary/5" : "hover:bg-primary/5", extra].filter(Boolean).join(" "),
|
|
18391
|
-
children: columns.map((col) => {
|
|
18392
|
-
const align = col.align ?? "left";
|
|
18393
|
-
const nowrap = col.nowrap ?? true;
|
|
18394
|
-
return /* @__PURE__ */ jsx("td", {
|
|
18395
|
-
className: [
|
|
18396
|
-
"px-3 py-2 text-foreground border-b border-border",
|
|
18397
|
-
ALIGN_CLASS[align],
|
|
18398
|
-
nowrap ? "whitespace-nowrap" : ""
|
|
18399
|
-
].filter(Boolean).join(" "),
|
|
18400
|
-
children: col.render(row, rowIndex)
|
|
18401
|
-
}, col.key);
|
|
18402
|
-
})
|
|
18403
|
-
}, key);
|
|
18404
|
-
}) })]
|
|
18405
|
-
})
|
|
18406
|
-
});
|
|
18407
|
-
}
|
|
18408
|
-
/**
|
|
18409
|
-
* One row as a card. Columns that carry a plain-text `header` become labelled
|
|
18410
|
-
* `SettingRow`s — the label is the column title and the value gets the full
|
|
18411
|
-
* card width. Columns with no text header (an actions column, a
|
|
18412
|
-
* `headerRender`-only column) have no label to show, so they render as a
|
|
18413
|
-
* full-width strip at the foot of the card.
|
|
18414
|
-
*/
|
|
18415
|
-
function DataTableCard({ row, rowIndex, columns, bordered, onRowClick, rowClassName }) {
|
|
18416
|
-
const labelled = columns.filter((col) => col.header !== void 0 && col.header !== "");
|
|
18417
|
-
const unlabelled = columns.filter((col) => col.header === void 0 || col.header === "");
|
|
18418
|
-
const interactive = onRowClick !== void 0;
|
|
18419
|
-
const extra = rowClassName?.(row, rowIndex) ?? "";
|
|
18420
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
18421
|
-
"data-data-table-card": "",
|
|
18422
|
-
onClick: interactive ? () => onRowClick(row, rowIndex) : void 0,
|
|
18423
|
-
className: [
|
|
18424
|
-
"rounded-lg bg-surface px-3 py-1.5 divide-y divide-border-subtle",
|
|
18425
|
-
bordered ? "border border-border" : "",
|
|
18426
|
-
interactive ? "cursor-pointer hover:bg-primary/5" : "",
|
|
18427
|
-
extra
|
|
18428
|
-
].filter(Boolean).join(" "),
|
|
18429
|
-
children: [labelled.map((col) => /* @__PURE__ */ jsx(SettingRow, {
|
|
18430
|
-
label: col.header,
|
|
18431
|
-
children: col.render(row, rowIndex)
|
|
18432
|
-
}, col.key)), unlabelled.length > 0 && /* @__PURE__ */ jsx("div", {
|
|
18433
|
-
className: "flex flex-wrap items-center justify-end gap-2 py-1.5",
|
|
18434
|
-
children: unlabelled.map((col) => /* @__PURE__ */ jsx("div", { children: col.render(row, rowIndex) }, col.key))
|
|
18435
|
-
})]
|
|
18436
|
-
});
|
|
18437
|
-
}
|
|
18438
|
-
//#endregion
|
|
18439
|
-
//#region src/composites/device-list/pagination.tsx
|
|
18440
|
-
var NEIGHBORS = 2;
|
|
18441
|
-
function computePageButtons(currentPage, totalPages) {
|
|
18442
|
-
if (totalPages <= 1) return [{
|
|
18443
|
-
kind: "page",
|
|
18444
|
-
n: 1
|
|
18445
|
-
}];
|
|
18446
|
-
if (totalPages <= 7) {
|
|
18447
|
-
const all = [];
|
|
18448
|
-
for (let i = 1; i <= totalPages; i++) all.push({
|
|
18449
|
-
kind: "page",
|
|
18450
|
-
n: i
|
|
18451
|
-
});
|
|
18452
|
-
return all;
|
|
18453
|
-
}
|
|
18454
|
-
const result = [];
|
|
18455
|
-
const leftBound = Math.max(2, currentPage - NEIGHBORS);
|
|
18456
|
-
const rightBound = Math.min(totalPages - 1, currentPage + NEIGHBORS);
|
|
18457
|
-
result.push({
|
|
18458
|
-
kind: "page",
|
|
18459
|
-
n: 1
|
|
18460
|
-
});
|
|
18461
|
-
if (leftBound > 2) result.push({
|
|
18462
|
-
kind: "ellipsis",
|
|
18463
|
-
side: "left"
|
|
18464
|
-
});
|
|
18465
|
-
for (let i = leftBound; i <= rightBound; i++) result.push({
|
|
18466
|
-
kind: "page",
|
|
18467
|
-
n: i
|
|
18468
|
-
});
|
|
18469
|
-
if (rightBound < totalPages - 1) result.push({
|
|
18470
|
-
kind: "ellipsis",
|
|
18471
|
-
side: "right"
|
|
18472
|
-
});
|
|
18473
|
-
result.push({
|
|
18474
|
-
kind: "page",
|
|
18475
|
-
n: totalPages
|
|
18476
|
-
});
|
|
18477
|
-
return result;
|
|
18478
|
-
}
|
|
18479
|
-
function Pagination({ currentPage, totalItems, pageSize, onPageChange, itemNoun = "devices" }) {
|
|
18480
|
-
if (totalItems <= pageSize) return null;
|
|
18481
|
-
const totalPages = Math.ceil(totalItems / pageSize);
|
|
18482
|
-
const startIdx = (currentPage - 1) * pageSize + 1;
|
|
18483
|
-
const endIdx = Math.min(currentPage * pageSize, totalItems);
|
|
18484
|
-
const buttons = computePageButtons(currentPage, totalPages);
|
|
18485
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
18486
|
-
className: "flex items-center justify-between gap-4 flex-wrap pt-2 text-[11px] text-foreground-subtle",
|
|
18487
|
-
children: [/* @__PURE__ */ jsxs("span", { children: [
|
|
18488
|
-
"Showing ",
|
|
18489
|
-
startIdx,
|
|
18490
|
-
"–",
|
|
18491
|
-
endIdx,
|
|
18492
|
-
" of ",
|
|
18493
|
-
totalItems,
|
|
18494
|
-
" ",
|
|
18495
|
-
itemNoun
|
|
18496
|
-
] }), /* @__PURE__ */ jsxs("span", {
|
|
18497
|
-
className: "inline-flex items-center gap-1",
|
|
18498
|
-
children: [
|
|
18499
|
-
/* @__PURE__ */ jsx("button", {
|
|
18500
|
-
type: "button",
|
|
18501
|
-
"aria-label": "Previous page",
|
|
18502
|
-
disabled: currentPage === 1,
|
|
18503
|
-
onClick: () => onPageChange(currentPage - 1),
|
|
18504
|
-
className: cn("inline-flex items-center justify-center h-7 w-7 rounded border border-border bg-surface text-foreground-subtle", "hover:text-foreground hover:bg-surface-hover transition-colors", "disabled:opacity-40 disabled:cursor-not-allowed disabled:hover:bg-surface"),
|
|
18505
|
-
children: /* @__PURE__ */ jsx(ChevronLeft, { className: "h-3 w-3" })
|
|
18506
|
-
}),
|
|
18507
|
-
buttons.map((b, i) => {
|
|
18508
|
-
if (b.kind === "ellipsis") return /* @__PURE__ */ jsx("span", {
|
|
18509
|
-
className: "px-1 text-foreground-subtle/60 select-none",
|
|
18510
|
-
children: "…"
|
|
18511
|
-
}, `e-${i}`);
|
|
18512
|
-
return /* @__PURE__ */ jsx("button", {
|
|
18513
|
-
type: "button",
|
|
18514
|
-
onClick: () => onPageChange(b.n),
|
|
18515
|
-
className: cn("inline-flex items-center justify-center h-7 min-w-7 px-1.5 rounded border text-[10.5px] font-medium transition-colors", b.n === currentPage ? "border-primary/40 bg-primary/10 text-primary" : "border-border bg-surface text-foreground-subtle hover:text-foreground hover:bg-surface-hover"),
|
|
18516
|
-
children: b.n
|
|
18517
|
-
}, `p-${b.n}`);
|
|
18518
|
-
}),
|
|
18519
|
-
/* @__PURE__ */ jsx("button", {
|
|
18520
|
-
type: "button",
|
|
18521
|
-
"aria-label": "Next page",
|
|
18522
|
-
disabled: currentPage === totalPages,
|
|
18523
|
-
onClick: () => onPageChange(currentPage + 1),
|
|
18524
|
-
className: cn("inline-flex items-center justify-center h-7 w-7 rounded border border-border bg-surface text-foreground-subtle", "hover:text-foreground hover:bg-surface-hover transition-colors", "disabled:opacity-40 disabled:cursor-not-allowed disabled:hover:bg-surface"),
|
|
18525
|
-
children: /* @__PURE__ */ jsx(ChevronRight, { className: "h-3 w-3" })
|
|
18526
|
-
})
|
|
18527
|
-
]
|
|
18528
|
-
})]
|
|
18529
|
-
});
|
|
18530
|
-
}
|
|
18531
|
-
//#endregion
|
|
18532
|
-
//#region src/composites/empty-state.tsx
|
|
18533
|
-
function EmptyState({ icon: Icon, title, description, action, className }) {
|
|
18534
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
18535
|
-
className: cn("flex flex-col items-center justify-center gap-3 py-12", className),
|
|
18536
|
-
children: [
|
|
18537
|
-
Icon && /* @__PURE__ */ jsx(Icon, {
|
|
18538
|
-
className: "h-12 w-12 text-foreground-subtle",
|
|
18539
|
-
"aria-hidden": "true"
|
|
18540
|
-
}),
|
|
18541
|
-
/* @__PURE__ */ jsxs("div", {
|
|
18542
|
-
className: "flex flex-col items-center gap-1 text-center",
|
|
18543
|
-
children: [/* @__PURE__ */ jsx("p", {
|
|
18544
|
-
className: "text-foreground-muted text-sm font-medium",
|
|
18545
|
-
children: title
|
|
18546
|
-
}), description && /* @__PURE__ */ jsx("p", {
|
|
18547
|
-
className: "text-foreground-subtle text-xs max-w-xs",
|
|
18548
|
-
children: description
|
|
18549
|
-
})]
|
|
18550
|
-
}),
|
|
18551
|
-
action && /* @__PURE__ */ jsx("div", {
|
|
18552
|
-
className: "mt-1",
|
|
18553
|
-
children: action
|
|
18554
|
-
})
|
|
18555
|
-
]
|
|
19404
|
+
//#region src/composites/empty-state.tsx
|
|
19405
|
+
function EmptyState({ icon: Icon, title, description, action, className }) {
|
|
19406
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
19407
|
+
className: cn("flex flex-col items-center justify-center gap-3 py-12", className),
|
|
19408
|
+
children: [
|
|
19409
|
+
Icon && /* @__PURE__ */ jsx(Icon, {
|
|
19410
|
+
className: "h-12 w-12 text-foreground-subtle",
|
|
19411
|
+
"aria-hidden": "true"
|
|
19412
|
+
}),
|
|
19413
|
+
/* @__PURE__ */ jsxs("div", {
|
|
19414
|
+
className: "flex flex-col items-center gap-1 text-center",
|
|
19415
|
+
children: [/* @__PURE__ */ jsx("p", {
|
|
19416
|
+
className: "text-foreground-muted text-sm font-medium",
|
|
19417
|
+
children: title
|
|
19418
|
+
}), description && /* @__PURE__ */ jsx("p", {
|
|
19419
|
+
className: "text-foreground-subtle text-xs max-w-xs",
|
|
19420
|
+
children: description
|
|
19421
|
+
})]
|
|
19422
|
+
}),
|
|
19423
|
+
action && /* @__PURE__ */ jsx("div", {
|
|
19424
|
+
className: "mt-1",
|
|
19425
|
+
children: action
|
|
19426
|
+
})
|
|
19427
|
+
]
|
|
18556
19428
|
});
|
|
18557
19429
|
}
|
|
18558
19430
|
//#endregion
|
|
@@ -19023,6 +19895,38 @@ function ClipPanel({ deviceId, clip, profile, onProfileChange }) {
|
|
|
19023
19895
|
});
|
|
19024
19896
|
}
|
|
19025
19897
|
//#endregion
|
|
19898
|
+
//#region src/primitives/badge.tsx
|
|
19899
|
+
var badgeVariants = cva("inline-flex items-center rounded-full text-xs font-medium px-2 py-0.5", {
|
|
19900
|
+
variants: {
|
|
19901
|
+
variant: {
|
|
19902
|
+
default: "bg-surface-hover text-foreground",
|
|
19903
|
+
success: "bg-success/15 text-success",
|
|
19904
|
+
warning: "bg-warning/15 text-warning",
|
|
19905
|
+
danger: "bg-danger/15 text-danger",
|
|
19906
|
+
info: "bg-info/15 text-info"
|
|
19907
|
+
},
|
|
19908
|
+
styleVariant: {
|
|
19909
|
+
solid: "",
|
|
19910
|
+
outline: "border bg-transparent"
|
|
19911
|
+
}
|
|
19912
|
+
},
|
|
19913
|
+
defaultVariants: {
|
|
19914
|
+
variant: "default",
|
|
19915
|
+
styleVariant: "solid"
|
|
19916
|
+
}
|
|
19917
|
+
});
|
|
19918
|
+
var Badge = forwardRef(({ className, variant, style, ...props }, ref) => {
|
|
19919
|
+
return /* @__PURE__ */ jsx("span", {
|
|
19920
|
+
ref,
|
|
19921
|
+
className: cn(badgeVariants({
|
|
19922
|
+
variant,
|
|
19923
|
+
styleVariant: style
|
|
19924
|
+
}), className),
|
|
19925
|
+
...props
|
|
19926
|
+
});
|
|
19927
|
+
});
|
|
19928
|
+
Badge.displayName = "Badge";
|
|
19929
|
+
//#endregion
|
|
19026
19930
|
//#region src/lib/format-duration.ts
|
|
19027
19931
|
/**
|
|
19028
19932
|
* How long something lasted, the way this product says it.
|
|
@@ -19536,24 +20440,6 @@ function describeSource(source) {
|
|
|
19536
20440
|
answered: copy.answered
|
|
19537
20441
|
};
|
|
19538
20442
|
}
|
|
19539
|
-
var MINUTE_MS$1 = 6e4;
|
|
19540
|
-
var HOUR_MS$1 = 36e5;
|
|
19541
|
-
var DAY_MS$2 = 864e5;
|
|
19542
|
-
/**
|
|
19543
|
-
* How old a source's catalog is, or null when it did not say.
|
|
19544
|
-
*
|
|
19545
|
-
* Null is NOT "now". A source that omits `catalogAsOf` was read live and has
|
|
19546
|
-
* no age to show; inventing "just now" for a source that never told us would
|
|
19547
|
-
* be the same lie as drawing a cached list as current (D549 decision 13).
|
|
19548
|
-
*/
|
|
19549
|
-
function formatCatalogAge(catalogAsOf, now) {
|
|
19550
|
-
if (catalogAsOf === void 0) return null;
|
|
19551
|
-
const age = Math.max(0, now - catalogAsOf);
|
|
19552
|
-
if (age < MINUTE_MS$1) return "under a minute ago";
|
|
19553
|
-
if (age < HOUR_MS$1) return `${String(Math.floor(age / MINUTE_MS$1))} min ago`;
|
|
19554
|
-
if (age < DAY_MS$2) return `${String(Math.floor(age / HOUR_MS$1))} h ago`;
|
|
19555
|
-
return `${String(Math.floor(age / DAY_MS$2))} d ago`;
|
|
19556
|
-
}
|
|
19557
20443
|
//#endregion
|
|
19558
20444
|
//#region src/composites/clips/clip-view-state.ts
|
|
19559
20445
|
function resolveClipsView(input) {
|
|
@@ -19707,56 +20593,6 @@ function resolveClipsView(input) {
|
|
|
19707
20593
|
var CLIP_PAGE_LIMIT = 500;
|
|
19708
20594
|
/** Tiles per page. The rest are a `Pagination` click away, never dropped. */
|
|
19709
20595
|
var TILES_PER_PAGE = 60;
|
|
19710
|
-
var TONE_BADGE = {
|
|
19711
|
-
ok: "success",
|
|
19712
|
-
warn: "warning",
|
|
19713
|
-
error: "danger"
|
|
19714
|
-
};
|
|
19715
|
-
var SOURCE_COLUMNS = [
|
|
19716
|
-
{
|
|
19717
|
-
key: "source",
|
|
19718
|
-
header: "Source",
|
|
19719
|
-
render: (row) => /* @__PURE__ */ jsxs("div", {
|
|
19720
|
-
className: "min-w-0",
|
|
19721
|
-
children: [/* @__PURE__ */ jsx("div", {
|
|
19722
|
-
className: "font-medium text-foreground",
|
|
19723
|
-
children: row.notice.label
|
|
19724
|
-
}), /* @__PURE__ */ jsx("div", {
|
|
19725
|
-
className: "text-[10px] text-foreground-subtle",
|
|
19726
|
-
children: row.notice.source
|
|
19727
|
-
})]
|
|
19728
|
-
})
|
|
19729
|
-
},
|
|
19730
|
-
{
|
|
19731
|
-
key: "state",
|
|
19732
|
-
header: "State",
|
|
19733
|
-
nowrap: false,
|
|
19734
|
-
render: (row) => /* @__PURE__ */ jsx(Badge, {
|
|
19735
|
-
variant: TONE_BADGE[row.notice.tone],
|
|
19736
|
-
children: row.notice.headline
|
|
19737
|
-
})
|
|
19738
|
-
},
|
|
19739
|
-
{
|
|
19740
|
-
key: "reason",
|
|
19741
|
-
header: "Reason",
|
|
19742
|
-
nowrap: false,
|
|
19743
|
-
render: (row) => row.notice.detail === null ? /* @__PURE__ */ jsx("span", {
|
|
19744
|
-
className: "text-foreground-subtle",
|
|
19745
|
-
children: "—"
|
|
19746
|
-
}) : /* @__PURE__ */ jsx("span", {
|
|
19747
|
-
className: "break-words",
|
|
19748
|
-
children: row.notice.detail
|
|
19749
|
-
})
|
|
19750
|
-
},
|
|
19751
|
-
{
|
|
19752
|
-
key: "read",
|
|
19753
|
-
header: "Catalog read",
|
|
19754
|
-
render: (row) => /* @__PURE__ */ jsx("span", {
|
|
19755
|
-
className: "text-foreground-subtle",
|
|
19756
|
-
children: row.catalogAge ?? "live"
|
|
19757
|
-
})
|
|
19758
|
-
}
|
|
19759
|
-
];
|
|
19760
20596
|
/** The sources that contributed NOTHING to what is on screen, and why. */
|
|
19761
20597
|
function SilentSources({ silent }) {
|
|
19762
20598
|
if (silent.length === 0) return null;
|
|
@@ -19843,7 +20679,6 @@ function ClipsSection({ deviceId }) {
|
|
|
19843
20679
|
...clips.error ? { clipsError: clips.error.message } : {},
|
|
19844
20680
|
...sources.error ? { sourcesError: sources.error.message } : {}
|
|
19845
20681
|
});
|
|
19846
|
-
const now = Date.now();
|
|
19847
20682
|
const options = useMemo(() => {
|
|
19848
20683
|
const byAddon = /* @__PURE__ */ new Map();
|
|
19849
20684
|
for (const row of sourceRows) {
|
|
@@ -19858,10 +20693,6 @@ function ClipsSection({ deviceId }) {
|
|
|
19858
20693
|
label: labels.join(" · ")
|
|
19859
20694
|
}));
|
|
19860
20695
|
}, [sourceRows]);
|
|
19861
|
-
const tableRows = useMemo(() => sourceRows.map((row) => ({
|
|
19862
|
-
notice: describeSource(row),
|
|
19863
|
-
catalogAge: formatCatalogAge(row.availability.catalogAsOf, now)
|
|
19864
|
-
})), [sourceRows]);
|
|
19865
20696
|
useEffect(() => {
|
|
19866
20697
|
setPage(1);
|
|
19867
20698
|
}, [band.fromMs, band.toMs]);
|
|
@@ -19967,19 +20798,6 @@ function ClipsSection({ deviceId }) {
|
|
|
19967
20798
|
onSelectBucket: handleSelectBucket,
|
|
19968
20799
|
densityLoading: density.status === "pending"
|
|
19969
20800
|
}),
|
|
19970
|
-
/* @__PURE__ */ jsx("section", {
|
|
19971
|
-
"aria-label": "Clip sources",
|
|
19972
|
-
className: "space-y-1",
|
|
19973
|
-
children: sources.status === "pending" ? /* @__PURE__ */ jsx(Skeleton, { className: "h-16 w-full" }) : tableRows.length === 0 ? /* @__PURE__ */ jsx(EmptyState, {
|
|
19974
|
-
icon: Film,
|
|
19975
|
-
title: "No provider answered for this camera",
|
|
19976
|
-
description: "Nothing claims to hold clips for it."
|
|
19977
|
-
}) : /* @__PURE__ */ jsx(DataTable, {
|
|
19978
|
-
columns: SOURCE_COLUMNS,
|
|
19979
|
-
rows: [...tableRows],
|
|
19980
|
-
minWidthPx: 520
|
|
19981
|
-
})
|
|
19982
|
-
}),
|
|
19983
20801
|
/* @__PURE__ */ jsx("section", {
|
|
19984
20802
|
"aria-label": "Clips",
|
|
19985
20803
|
className: "space-y-2",
|
|
@@ -22952,8 +23770,8 @@ function RecordingPanel({ deviceId }) {
|
|
|
22952
23770
|
* `type:'widget'` ConfigField. `WidgetSlot` resolves these BEFORE the
|
|
22953
23771
|
* Module-Federation `WidgetRegistry`. ids are namespaced `host/<name>`. */
|
|
22954
23772
|
var HOST_WIDGETS = {
|
|
22955
|
-
"host/motion-zones-grid": lazy(() => import("./MotionZonesSettings-
|
|
22956
|
-
"host/privacy-mask-grid": lazy(() => import("./PrivacyMaskSettings-
|
|
23773
|
+
"host/motion-zones-grid": lazy(() => import("./MotionZonesSettings-DHDfnZyU.js").then((m) => ({ default: m.MotionZonesSettings }))),
|
|
23774
|
+
"host/privacy-mask-grid": lazy(() => import("./PrivacyMaskSettings-DMkchqO1.js").then((m) => ({ default: m.PrivacyMaskSettings }))),
|
|
22957
23775
|
"host/ptz-panel": PtzPanel,
|
|
22958
23776
|
"host/navigation-panel": NavigationPanel,
|
|
22959
23777
|
"host/consumables-panel": ConsumablesPanel,
|
|
@@ -27658,6 +28476,53 @@ function TooltipContent({ className, children, ...props }) {
|
|
|
27658
28476
|
});
|
|
27659
28477
|
}
|
|
27660
28478
|
//#endregion
|
|
28479
|
+
//#region src/hooks/use-is-mobile.ts
|
|
28480
|
+
var MOBILE_QUERY = "(max-width: 767px)";
|
|
28481
|
+
/**
|
|
28482
|
+
* Mid breakpoint — below this width the sidebar collapses to an
|
|
28483
|
+
* icons-only rail to reclaim canvas space. Above it (and outside
|
|
28484
|
+
* mobile) the full sidebar renders. Threshold matches Tailwind `lg`
|
|
28485
|
+
* so sidebar fans out at the same point grids switch to multi-column.
|
|
28486
|
+
*/
|
|
28487
|
+
var MID_QUERY = "(min-width: 768px) and (max-width: 1023px)";
|
|
28488
|
+
/**
|
|
28489
|
+
* `matchMedia` is universal in browsers but absent in bare DOM environments.
|
|
28490
|
+
* These hooks are called from shared primitives (`DataTable` picks its narrow
|
|
28491
|
+
* layout with one), so throwing here takes down the whole page that merely
|
|
28492
|
+
* rendered a table. Where the capability is missing, report the desktop
|
|
28493
|
+
* layout — a widescreen rendering is wrong-looking; a crashed page is gone.
|
|
28494
|
+
*/
|
|
28495
|
+
function matchQuery(query) {
|
|
28496
|
+
if (typeof window.matchMedia !== "function") return null;
|
|
28497
|
+
return window.matchMedia(query);
|
|
28498
|
+
}
|
|
28499
|
+
function subscribeQuery(query) {
|
|
28500
|
+
return (callback) => {
|
|
28501
|
+
const mql = matchQuery(query);
|
|
28502
|
+
if (mql === null) return () => {};
|
|
28503
|
+
mql.addEventListener("change", callback);
|
|
28504
|
+
return () => mql.removeEventListener("change", callback);
|
|
28505
|
+
};
|
|
28506
|
+
}
|
|
28507
|
+
function getSnapshot(query) {
|
|
28508
|
+
return () => matchQuery(query)?.matches ?? false;
|
|
28509
|
+
}
|
|
28510
|
+
function getServerSnapshot() {
|
|
28511
|
+
return false;
|
|
28512
|
+
}
|
|
28513
|
+
function useIsMobile() {
|
|
28514
|
+
return useSyncExternalStore(subscribeQuery(MOBILE_QUERY), getSnapshot(MOBILE_QUERY), getServerSnapshot);
|
|
28515
|
+
}
|
|
28516
|
+
/**
|
|
28517
|
+
* True when the viewport is in the medium (`md`) Tailwind range —
|
|
28518
|
+
* 768px ≤ width < 1024px. Use to drive layouts that should pack denser
|
|
28519
|
+
* than full-desktop but more legibly than mobile (e.g. icons-only
|
|
28520
|
+
* sidebar rail, narrower stat tiles).
|
|
28521
|
+
*/
|
|
28522
|
+
function useIsMidWidth() {
|
|
28523
|
+
return useSyncExternalStore(subscribeQuery(MID_QUERY), getSnapshot(MID_QUERY), getServerSnapshot);
|
|
28524
|
+
}
|
|
28525
|
+
//#endregion
|
|
27661
28526
|
//#region src/primitives/bottom-sheet.tsx
|
|
27662
28527
|
function BottomSheet({ open, onClose, title, children, className }) {
|
|
27663
28528
|
useEffect(() => {
|
|
@@ -30806,290 +31671,916 @@ function ToolbarButton$1({ onClick, title, children }) {
|
|
|
30806
31671
|
children
|
|
30807
31672
|
});
|
|
30808
31673
|
}
|
|
30809
|
-
async function waitForIceGathering(pc) {
|
|
30810
|
-
if (pc.iceGatheringState === "complete") return;
|
|
30811
|
-
return new Promise((resolve) => {
|
|
30812
|
-
let settled = false;
|
|
30813
|
-
let poll;
|
|
30814
|
-
const finish = () => {
|
|
30815
|
-
if (settled) return;
|
|
30816
|
-
settled = true;
|
|
30817
|
-
if (poll) clearInterval(poll);
|
|
30818
|
-
pc.removeEventListener("icegatheringstatechange", handler);
|
|
30819
|
-
resolve();
|
|
30820
|
-
};
|
|
30821
|
-
const handler = () => {
|
|
30822
|
-
if (pc.iceGatheringState === "complete") finish();
|
|
30823
|
-
};
|
|
30824
|
-
pc.addEventListener("icegatheringstatechange", handler);
|
|
30825
|
-
const start = Date.now();
|
|
30826
|
-
poll = setInterval(() => {
|
|
30827
|
-
const sdp = pc.localDescription?.sdp ?? "";
|
|
30828
|
-
if (/ typ host/.test(sdp) && Date.now() - start >= 600) finish();
|
|
30829
|
-
}, 100);
|
|
30830
|
-
setTimeout(finish, 2500);
|
|
31674
|
+
async function waitForIceGathering(pc) {
|
|
31675
|
+
if (pc.iceGatheringState === "complete") return;
|
|
31676
|
+
return new Promise((resolve) => {
|
|
31677
|
+
let settled = false;
|
|
31678
|
+
let poll;
|
|
31679
|
+
const finish = () => {
|
|
31680
|
+
if (settled) return;
|
|
31681
|
+
settled = true;
|
|
31682
|
+
if (poll) clearInterval(poll);
|
|
31683
|
+
pc.removeEventListener("icegatheringstatechange", handler);
|
|
31684
|
+
resolve();
|
|
31685
|
+
};
|
|
31686
|
+
const handler = () => {
|
|
31687
|
+
if (pc.iceGatheringState === "complete") finish();
|
|
31688
|
+
};
|
|
31689
|
+
pc.addEventListener("icegatheringstatechange", handler);
|
|
31690
|
+
const start = Date.now();
|
|
31691
|
+
poll = setInterval(() => {
|
|
31692
|
+
const sdp = pc.localDescription?.sdp ?? "";
|
|
31693
|
+
if (/ typ host/.test(sdp) && Date.now() - start >= 600) finish();
|
|
31694
|
+
}, 100);
|
|
31695
|
+
setTimeout(finish, 2500);
|
|
31696
|
+
});
|
|
31697
|
+
}
|
|
31698
|
+
//#endregion
|
|
31699
|
+
//#region src/composites/cap-settings/scene-monitor-copy.ts
|
|
31700
|
+
/** The lighting variants an operator is OFFERED. The resolver can also report
|
|
31701
|
+
* `night`, `dawn` and `dusk`; those are shown when present but never demanded,
|
|
31702
|
+
* because most installs only ever see day and IR. */
|
|
31703
|
+
var SCENE_CAPTURE_VARIANTS = ["day", "ir"];
|
|
31704
|
+
var VARIANT_LABEL = {
|
|
31705
|
+
day: "Daylight",
|
|
31706
|
+
ir: "Night (IR)",
|
|
31707
|
+
night: "Night",
|
|
31708
|
+
dawn: "Dawn",
|
|
31709
|
+
dusk: "Dusk"
|
|
31710
|
+
};
|
|
31711
|
+
function variantLabel(condition) {
|
|
31712
|
+
return VARIANT_LABEL[condition] ?? condition;
|
|
31713
|
+
}
|
|
31714
|
+
/**
|
|
31715
|
+
* "Daylight ✓ · Night (IR) ✗ — optional; checks in night (ir) are skipped."
|
|
31716
|
+
*
|
|
31717
|
+
* Converts the silent cross-condition fallback this engine used to have into an
|
|
31718
|
+
* operator-visible fact. Without it, a scene with only a daylight reference
|
|
31719
|
+
* simply stops answering after sunset and nothing anywhere says why.
|
|
31720
|
+
*
|
|
31721
|
+
* It used to end *"reports 'can't tell' in night (ir)"*, which was accurate and
|
|
31722
|
+
* read as a defect: the operator saw a ✗ and a complaint for a scene that was
|
|
31723
|
+
* configured exactly as they meant it. The missing half is now named as what it
|
|
31724
|
+
* is — the part you do not have to do — and the sentence says what actually
|
|
31725
|
+
* happens instead, which differs by the scene's own policy.
|
|
31726
|
+
*/
|
|
31727
|
+
function coverageLine(monitor) {
|
|
31728
|
+
const covered = new Set(monitor.coveredConditions);
|
|
31729
|
+
const parts = SCENE_CAPTURE_VARIANTS.map((v) => `${variantLabel(v)} ${covered.has(v) ? "✓" : "✗"}`);
|
|
31730
|
+
const extra = [...covered].filter((c) => !SCENE_CAPTURE_VARIANTS.some((v) => v === c));
|
|
31731
|
+
for (const c of extra) parts.push(`${variantLabel(c)} ✓`);
|
|
31732
|
+
const missing = SCENE_CAPTURE_VARIANTS.filter((v) => !covered.has(v));
|
|
31733
|
+
if (missing.length === 0) return parts.join(" · ");
|
|
31734
|
+
if (covered.size === 0) return `${parts.join(" · ")} — nothing captured yet, so this scene is not watching.`;
|
|
31735
|
+
const names = missing.map((v) => variantLabel(v).toLowerCase()).join(" and ");
|
|
31736
|
+
return monitor.onUncoveredCondition === "judge-anyway" ? `${parts.join(" · ")} — ${names} judged against the references you do have.` : `${parts.join(" · ")} — optional; checks in ${names} are skipped.`;
|
|
31737
|
+
}
|
|
31738
|
+
/**
|
|
31739
|
+
* The calm sentence for a scene that is sitting the current light out — `null`
|
|
31740
|
+
* whenever it is checking normally.
|
|
31741
|
+
*
|
|
31742
|
+
* Separate from {@link statusLine} because it is not a verdict and must not
|
|
31743
|
+
* read like one. A paused scene has not failed, has not lost its flag, and
|
|
31744
|
+
* needs nothing from the operator; the only thing worth saying is which light
|
|
31745
|
+
* it is waiting out and that it will pick itself back up.
|
|
31746
|
+
*/
|
|
31747
|
+
function suspensionLine(monitor) {
|
|
31748
|
+
if (monitor.suspendedCondition === null) return null;
|
|
31749
|
+
const light = variantLabel(monitor.suspendedCondition).toLowerCase();
|
|
31750
|
+
return `Paused — nothing was captured in ${light}, so checks are on hold until the light changes back. Capture ${light} if you want it watched around the clock.`;
|
|
31751
|
+
}
|
|
31752
|
+
var UNAVAILABLE_SENTENCE = {
|
|
31753
|
+
"no-reference-for-condition": "can’t tell — nothing has been captured for this scene yet. Press “Capture daylight” to photograph what normal looks like.",
|
|
31754
|
+
"view-shifted": "can’t tell — the camera view has moved since the reference was captured. Re-capture it.",
|
|
31755
|
+
"no-vision-profile": "can’t tell — the vision model is unreachable, so the change is on hold.",
|
|
31756
|
+
"encoder-model-changed": "can’t tell — the embedding model changed, so the stored references are unreadable. Re-capture them.",
|
|
31757
|
+
"no-snapshot": "can’t tell — this camera did not return a frame."
|
|
31758
|
+
};
|
|
31759
|
+
/**
|
|
31760
|
+
* The one line under a scene's name. It answers, in order: can it judge, what
|
|
31761
|
+
* does it say, and how long has it said it.
|
|
31762
|
+
*/
|
|
31763
|
+
function statusLine(monitor, now) {
|
|
31764
|
+
if (monitor.states.length === 0) return "Not armed yet — capture the initial state to start watching.";
|
|
31765
|
+
if (monitor.verdict === "unknown") return monitor.unavailable !== null ? UNAVAILABLE_SENTENCE[monitor.unavailable] : "can’t tell right now.";
|
|
31766
|
+
const since = monitor.verdict === "diverged" ? monitor.divergedAt : monitor.armedAt;
|
|
31767
|
+
const held = since !== null ? ` for ${humanDuration(Math.max(0, now - since))}` : "";
|
|
31768
|
+
if (monitor.latched) return monitor.verdict === "diverged" ? `CHANGED${held} — press Reset when you have dealt with it.` : `Back to normal, but still flagged as changed${held}. Press Reset to clear it.`;
|
|
31769
|
+
const paused = suspensionLine(monitor);
|
|
31770
|
+
if (paused !== null) return paused;
|
|
31771
|
+
return monitor.verdict === "diverged" ? `CHANGED${held}` : `Normal${held}`;
|
|
31772
|
+
}
|
|
31773
|
+
/** The badge word. `latched` wins over `verdict`, because the latch is the
|
|
31774
|
+
* thing the operator asked to be told and it outlives the live state.
|
|
31775
|
+
*
|
|
31776
|
+
* A scene sitting out an uncovered light reads `Paused`, in the NEUTRAL tone —
|
|
31777
|
+
* never `alarm`, and never the `danger` variant the page maps that to. A
|
|
31778
|
+
* missing IR reference must not be able to paint a red badge on a scene that
|
|
31779
|
+
* is doing exactly what it was configured to do. */
|
|
31780
|
+
function badgeFor(monitor) {
|
|
31781
|
+
if (monitor.states.length === 0) return {
|
|
31782
|
+
text: "Not armed",
|
|
31783
|
+
tone: "unknown"
|
|
31784
|
+
};
|
|
31785
|
+
if (monitor.latched) return {
|
|
31786
|
+
text: "Changed",
|
|
31787
|
+
tone: "alarm"
|
|
31788
|
+
};
|
|
31789
|
+
if (monitor.suspendedCondition !== null) return {
|
|
31790
|
+
text: "Paused",
|
|
31791
|
+
tone: "unknown"
|
|
31792
|
+
};
|
|
31793
|
+
if (monitor.verdict === "unknown") return {
|
|
31794
|
+
text: "Can’t tell",
|
|
31795
|
+
tone: "unknown"
|
|
31796
|
+
};
|
|
31797
|
+
return monitor.verdict === "diverged" ? {
|
|
31798
|
+
text: "Changed",
|
|
31799
|
+
tone: "alarm"
|
|
31800
|
+
} : {
|
|
31801
|
+
text: "Normal",
|
|
31802
|
+
tone: "ok"
|
|
31803
|
+
};
|
|
31804
|
+
}
|
|
31805
|
+
/** A rect covering most of the frame is dominated by weather, sky and parked
|
|
31806
|
+
* cars: the bin is 2 % of the pixels and CLIP will not notice it leaving. The
|
|
31807
|
+
* failure is silent INSENSITIVITY, which is the worst kind — hence a warning
|
|
31808
|
+
* rather than a refusal. */
|
|
31809
|
+
var ROI_AREA_WARN_FRACTION = .4;
|
|
31810
|
+
function roiTooLarge(roi) {
|
|
31811
|
+
return roi.width * roi.height > ROI_AREA_WARN_FRACTION;
|
|
31812
|
+
}
|
|
31813
|
+
function humanDuration(ms) {
|
|
31814
|
+
const s = Math.floor(ms / 1e3);
|
|
31815
|
+
if (s < 60) return `${s}s`;
|
|
31816
|
+
const m = Math.floor(s / 60);
|
|
31817
|
+
if (m < 60) return `${m}m`;
|
|
31818
|
+
const h = Math.floor(m / 60);
|
|
31819
|
+
if (h < 48) return `${h}h`;
|
|
31820
|
+
return `${Math.floor(h / 24)}d`;
|
|
31821
|
+
}
|
|
31822
|
+
//#endregion
|
|
31823
|
+
//#region src/composites/code-block.tsx
|
|
31824
|
+
function CodeBlock({ children, maxHeight = 300, className }) {
|
|
31825
|
+
const [copied, setCopied] = useState(false);
|
|
31826
|
+
const handleCopy = useCallback(() => {
|
|
31827
|
+
navigator.clipboard.writeText(children).then(() => {
|
|
31828
|
+
setCopied(true);
|
|
31829
|
+
setTimeout(() => setCopied(false), 2e3);
|
|
31830
|
+
});
|
|
31831
|
+
}, [children]);
|
|
31832
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
31833
|
+
className: cn("relative group", className),
|
|
31834
|
+
children: [/* @__PURE__ */ jsx(ScrollArea, {
|
|
31835
|
+
style: { maxHeight },
|
|
31836
|
+
children: /* @__PURE__ */ jsx("pre", {
|
|
31837
|
+
className: "font-mono text-xs bg-surface p-3 rounded-md border border-border-subtle",
|
|
31838
|
+
children: /* @__PURE__ */ jsx("code", { children })
|
|
31839
|
+
})
|
|
31840
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
31841
|
+
className: "absolute top-2 right-2 opacity-0 group-hover:opacity-100 transition-opacity",
|
|
31842
|
+
children: /* @__PURE__ */ jsx(IconButton, {
|
|
31843
|
+
icon: copied ? Check : Copy,
|
|
31844
|
+
"aria-label": "Copy code",
|
|
31845
|
+
variant: "ghost",
|
|
31846
|
+
size: "sm",
|
|
31847
|
+
onClick: handleCopy
|
|
31848
|
+
})
|
|
31849
|
+
})]
|
|
31850
|
+
});
|
|
31851
|
+
}
|
|
31852
|
+
//#endregion
|
|
31853
|
+
//#region src/composites/confirm-action-button.tsx
|
|
31854
|
+
/**
|
|
31855
|
+
* ConfirmActionButton — destructive-action button with a modal confirm.
|
|
31856
|
+
*
|
|
31857
|
+
* Two-step UX for any operation operators shouldn't trigger by accident:
|
|
31858
|
+
* reboot device, restart addon, regenerate token, etc. The trigger is a
|
|
31859
|
+
* normal Button that opens a Dialog; confirming runs the async action,
|
|
31860
|
+
* the trigger spinner-disables itself for the duration, and the dialog
|
|
31861
|
+
* closes on success. Errors surface inline at the dialog's bottom.
|
|
31862
|
+
*
|
|
31863
|
+
* Generic on `TResult` so callers don't have to discard the return
|
|
31864
|
+
* value. Pass an `icon` to render it inside the trigger (e.g. RotateCw
|
|
31865
|
+
* for reboot, RefreshCw for restart).
|
|
31866
|
+
*/
|
|
31867
|
+
function ConfirmActionButton({ label, icon: Icon, title = "Confirm action", description, confirmLabel, triggerVariant = "outline", confirmVariant = "danger", size = "sm", disabled, className, action, onSuccess }) {
|
|
31868
|
+
const [open, setOpen] = useState(false);
|
|
31869
|
+
const [running, setRunning] = useState(false);
|
|
31870
|
+
const [error, setError] = useState(null);
|
|
31871
|
+
const handleConfirm = async () => {
|
|
31872
|
+
setError(null);
|
|
31873
|
+
setRunning(true);
|
|
31874
|
+
try {
|
|
31875
|
+
const result = await action();
|
|
31876
|
+
onSuccess?.(result);
|
|
31877
|
+
setOpen(false);
|
|
31878
|
+
} catch (err) {
|
|
31879
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
31880
|
+
} finally {
|
|
31881
|
+
setRunning(false);
|
|
31882
|
+
}
|
|
31883
|
+
};
|
|
31884
|
+
return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsxs(Button, {
|
|
31885
|
+
type: "button",
|
|
31886
|
+
variant: triggerVariant,
|
|
31887
|
+
size,
|
|
31888
|
+
disabled,
|
|
31889
|
+
onClick: () => {
|
|
31890
|
+
setError(null);
|
|
31891
|
+
setOpen(true);
|
|
31892
|
+
},
|
|
31893
|
+
className,
|
|
31894
|
+
children: [Icon && /* @__PURE__ */ jsx(Icon, { className: "h-3.5 w-3.5" }), label]
|
|
31895
|
+
}), /* @__PURE__ */ jsx(Dialog, {
|
|
31896
|
+
open,
|
|
31897
|
+
onOpenChange: (next) => !running && setOpen(next),
|
|
31898
|
+
children: /* @__PURE__ */ jsxs(DialogContent, { children: [
|
|
31899
|
+
/* @__PURE__ */ jsxs(DialogHeader, { children: [/* @__PURE__ */ jsxs(DialogTitle, {
|
|
31900
|
+
className: "flex items-center gap-2",
|
|
31901
|
+
children: [/* @__PURE__ */ jsx(TriangleAlert, { className: "h-4 w-4 text-amber-400" }), title]
|
|
31902
|
+
}), typeof description === "string" ? /* @__PURE__ */ jsx(DialogDescription, { children: description }) : description] }),
|
|
31903
|
+
error && /* @__PURE__ */ jsx("div", {
|
|
31904
|
+
className: cn("mt-2 px-3 py-2 rounded border border-danger/40 bg-danger/10", "text-xs text-danger"),
|
|
31905
|
+
children: error
|
|
31906
|
+
}),
|
|
31907
|
+
/* @__PURE__ */ jsxs(DialogFooter, { children: [/* @__PURE__ */ jsx(Button, {
|
|
31908
|
+
type: "button",
|
|
31909
|
+
variant: "ghost",
|
|
31910
|
+
size,
|
|
31911
|
+
disabled: running,
|
|
31912
|
+
onClick: () => setOpen(false),
|
|
31913
|
+
children: "Cancel"
|
|
31914
|
+
}), /* @__PURE__ */ jsxs(Button, {
|
|
31915
|
+
type: "button",
|
|
31916
|
+
variant: confirmVariant,
|
|
31917
|
+
size,
|
|
31918
|
+
disabled: running,
|
|
31919
|
+
onClick: () => {
|
|
31920
|
+
handleConfirm();
|
|
31921
|
+
},
|
|
31922
|
+
children: [running && /* @__PURE__ */ jsx(LoaderCircle, { className: "h-3.5 w-3.5 animate-spin" }), confirmLabel ?? label]
|
|
31923
|
+
})] })
|
|
31924
|
+
] })
|
|
31925
|
+
})] });
|
|
31926
|
+
}
|
|
31927
|
+
//#endregion
|
|
31928
|
+
//#region src/composites/copy-button.tsx
|
|
31929
|
+
/**
|
|
31930
|
+
* `CopyButton` — a compact button that copies a string `value` to the
|
|
31931
|
+
* clipboard via `navigator.clipboard.writeText`, showing a brief
|
|
31932
|
+
* "copied" check state. Addon-agnostic; used wherever a secret / URL
|
|
31933
|
+
* needs a one-click copy affordance (export setup panels, etc.).
|
|
31934
|
+
*/
|
|
31935
|
+
var COPIED_RESET_MS = 2e3;
|
|
31936
|
+
function CopyButton({ value, label, srLabel, className, disabled }) {
|
|
31937
|
+
const [copied, setCopied] = useState(false);
|
|
31938
|
+
const handleCopy = useCallback(() => {
|
|
31939
|
+
if (!value) return;
|
|
31940
|
+
navigator.clipboard.writeText(value).then(() => {
|
|
31941
|
+
setCopied(true);
|
|
31942
|
+
setTimeout(() => setCopied(false), COPIED_RESET_MS);
|
|
31943
|
+
});
|
|
31944
|
+
}, [value]);
|
|
31945
|
+
return /* @__PURE__ */ jsxs(Button, {
|
|
31946
|
+
size: "sm",
|
|
31947
|
+
variant: "ghost",
|
|
31948
|
+
type: "button",
|
|
31949
|
+
disabled: disabled || value.length === 0,
|
|
31950
|
+
onClick: handleCopy,
|
|
31951
|
+
className: cn(className),
|
|
31952
|
+
"aria-label": copied ? "Copied" : `Copy ${srLabel ?? label ?? "value"}`,
|
|
31953
|
+
children: [copied ? /* @__PURE__ */ jsx(Check, { className: "h-3.5 w-3.5 text-success" }) : /* @__PURE__ */ jsx(Copy, { className: "h-3.5 w-3.5" }), label ? /* @__PURE__ */ jsx("span", {
|
|
31954
|
+
className: "ml-1",
|
|
31955
|
+
children: copied ? "Copied" : label
|
|
31956
|
+
}) : null]
|
|
31957
|
+
});
|
|
31958
|
+
}
|
|
31959
|
+
//#endregion
|
|
31960
|
+
//#region src/composites/data-table-layout.ts
|
|
31961
|
+
/**
|
|
31962
|
+
* At this many columns and above, `auto` switches a narrow viewport to cards.
|
|
31963
|
+
* Three columns still fit a phone at a readable size; four do not.
|
|
31964
|
+
*/
|
|
31965
|
+
var CARD_MODE_MIN_COLUMNS = 4;
|
|
31966
|
+
function resolveTableLayout({ mode, columnCount, isNarrow }) {
|
|
31967
|
+
if (!isNarrow) return "table";
|
|
31968
|
+
if (mode === "scroll") return "table";
|
|
31969
|
+
if (mode === "cards") return "cards";
|
|
31970
|
+
if (columnCount === 0) return "table";
|
|
31971
|
+
return columnCount >= 4 ? "cards" : "table";
|
|
31972
|
+
}
|
|
31973
|
+
//#endregion
|
|
31974
|
+
//#region src/lib/responsive.ts
|
|
31975
|
+
/**
|
|
31976
|
+
* Responsive design tokens — three-tier system.
|
|
31977
|
+
*
|
|
31978
|
+
* The admin-ui targets three width tiers; every component should pick
|
|
31979
|
+
* the right token from this file instead of hand-coding breakpoints.
|
|
31980
|
+
* Adopting the tokens uniformly is what makes the app feel consistent
|
|
31981
|
+
* across operator devices (mobile / tablet / desktop) and what unlocks
|
|
31982
|
+
* targeted tuning (e.g. shrink every label by 1px in one place).
|
|
31983
|
+
*
|
|
31984
|
+
* Tier definitions (Tailwind breakpoints):
|
|
31985
|
+
*
|
|
31986
|
+
* • **L1 — Compact** (`< 640px`, default = mobile portrait)
|
|
31987
|
+
* Single column, tight padding, smallest text, icon-only buttons
|
|
31988
|
+
* where labels can be inferred. The operator can still see every
|
|
31989
|
+
* stat / action — no horizontal scroll, no clipped text. The user
|
|
31990
|
+
* directive: "molta informazione in poco spazio quando la width è
|
|
31991
|
+
* bassa."
|
|
31992
|
+
*
|
|
31993
|
+
* • **L2 — Standard** (`sm` — `640–1023px`, tablet + small laptop)
|
|
31994
|
+
* 2-column grids, side panels become visible, button labels return.
|
|
31995
|
+
* Targets ~768px–1024px viewports — the most common operator sizes.
|
|
31996
|
+
*
|
|
31997
|
+
* • **L3 — Spacious** (`lg+` — `≥ 1024px`, desktop)
|
|
31998
|
+
* 4-column grids, generous padding, full-width header text,
|
|
31999
|
+
* side-by-side composite layouts. The operator has elbow room.
|
|
32000
|
+
*
|
|
32001
|
+
* Conventions:
|
|
32002
|
+
* - **Always start from L1** — the bare class is always the compact
|
|
32003
|
+
* variant, then `sm:` adds room at 640px, `lg:` at 1024px. No
|
|
32004
|
+
* desktop-first breakpoints; no max-width queries.
|
|
32005
|
+
* - **Token strings are static** — kept as `as const` so callers can
|
|
32006
|
+
* compose them via `cn()` / template literals without running a
|
|
32007
|
+
* class generator at runtime.
|
|
32008
|
+
* - **Pair the token with a comment** — the comment in the file
|
|
32009
|
+
* names every breakpoint it crosses, so a reader can predict the
|
|
32010
|
+
* layout without going to Tailwind docs.
|
|
32011
|
+
*/
|
|
32012
|
+
/** Container padding for a card-style section (header + body). */
|
|
32013
|
+
var SECTION_CARD = "rounded-lg border border-border bg-surface overflow-hidden";
|
|
32014
|
+
/** Header strip inside a card (between border-b lines). */
|
|
32015
|
+
var SECTION_HEADER = "border-b border-border px-3 sm:px-4 py-1.5 sm:py-2";
|
|
32016
|
+
/** Body padding for a card-style section. */
|
|
32017
|
+
var SECTION_BODY = "p-2 sm:p-3 lg:p-4";
|
|
32018
|
+
/** Gap between cards in a vertical stack. */
|
|
32019
|
+
var STACK_GAP = "space-y-3 sm:space-y-4";
|
|
32020
|
+
/** Gap between cards in a grid (4 cells / row at lg). */
|
|
32021
|
+
var GRID_GAP = "gap-2 sm:gap-3";
|
|
32022
|
+
/** Row padding inside a divided list (e.g. InfoRow). */
|
|
32023
|
+
var LIST_ROW = "px-3 sm:px-4 py-1.5 sm:py-2";
|
|
32024
|
+
/** 1-up at L1, 2-up at L2, 4-up at L3 — quick-stat row. */
|
|
32025
|
+
var GRID_QUICK_STATS = "grid grid-cols-2 sm:grid-cols-2 lg:grid-cols-4";
|
|
32026
|
+
/** 1-up at L1, 2-up at L2+ — paired panels (motion + detection rules). */
|
|
32027
|
+
var GRID_PAIRED = "grid grid-cols-1 lg:grid-cols-2";
|
|
32028
|
+
/** Side-by-side layout that stacks below md (canvas + side panel). */
|
|
32029
|
+
var SPLIT_PANEL_OUTER = "flex flex-col-reverse md:flex-row";
|
|
32030
|
+
/** Sidebar narrow lane in a SPLIT_PANEL_OUTER layout. */
|
|
32031
|
+
var SPLIT_PANEL_SIDE = "w-full md:w-44 lg:w-52 md:flex-shrink-0 border-b md:border-b-0 md:border-l border-border";
|
|
32032
|
+
/**
|
|
32033
|
+
* The tier boundary at which a settings label/value row stops stacking.
|
|
32034
|
+
*
|
|
32035
|
+
* Below it (L1 — compact) the row is ONE column: label on its own line, value
|
|
32036
|
+
* on the next at full width. Above it the row is label-left / value-right as
|
|
32037
|
+
* before. The two-column form needs `SETTING_ROW_LABEL`'s lane plus a readable
|
|
32038
|
+
* value beside it; a phone has neither, and the failure mode is not "cramped"
|
|
32039
|
+
* but "the value is the part that gets cut" — the one thing the operator
|
|
32040
|
+
* opened the page to read.
|
|
32041
|
+
*/
|
|
32042
|
+
var SETTING_ROW_STACK_BREAKPOINT = "sm";
|
|
32043
|
+
/** Outer row: single column at L1, label/value columns from `sm` up. */
|
|
32044
|
+
var SETTING_ROW = "flex min-w-0 flex-col gap-0.5 py-1.5 sm:flex-row sm:items-center";
|
|
32045
|
+
/** Label lane. Full width (and free to wrap) at L1; a fixed lane from `sm` up. */
|
|
32046
|
+
var SETTING_ROW_LABEL = "min-w-0 text-[11px] leading-tight text-foreground-subtle sm:w-32 sm:shrink-0 sm:pr-2";
|
|
32047
|
+
/**
|
|
32048
|
+
* Value lane — the value text plus its trailing affordances (copy / reveal).
|
|
32049
|
+
* `w-full` at L1 so the value owns the whole row once the label is above it;
|
|
32050
|
+
* `sm:flex-1` makes it share the row again from `sm` up.
|
|
32051
|
+
*/
|
|
32052
|
+
var SETTING_ROW_VALUE = "flex w-full min-w-0 items-center gap-1 sm:flex-1";
|
|
32053
|
+
/**
|
|
32054
|
+
* The value text itself. `break-all` lets an opaque token (a key, a URL) wrap
|
|
32055
|
+
* at L1 instead of being cut mid-word; `sm:truncate` restores the single-line
|
|
32056
|
+
* desktop form, where the row is wide enough for truncation to be a choice
|
|
32057
|
+
* rather than data loss.
|
|
32058
|
+
*/
|
|
32059
|
+
var SETTING_ROW_VALUE_TEXT = "min-w-0 break-all text-xs text-foreground sm:truncate";
|
|
32060
|
+
/** Section header label (uppercase tracking-wider). */
|
|
32061
|
+
var TEXT_SECTION_LABEL = "text-[10px] sm:text-[11px] font-semibold text-foreground uppercase tracking-wider";
|
|
32062
|
+
/** Field label inside a row. */
|
|
32063
|
+
var TEXT_FIELD_LABEL = "text-[11px] sm:text-xs text-foreground";
|
|
32064
|
+
/** Sub-label / hint text. */
|
|
32065
|
+
var TEXT_HINT = "text-[10px] text-foreground-subtle";
|
|
32066
|
+
/** Primary value (a metric, badge, …). */
|
|
32067
|
+
var TEXT_VALUE = "text-[11px] sm:text-xs font-medium text-foreground";
|
|
32068
|
+
/** Big metric value (StatCard). */
|
|
32069
|
+
var TEXT_METRIC = "text-base sm:text-lg font-semibold leading-tight text-foreground";
|
|
32070
|
+
/** Default compact button. */
|
|
32071
|
+
var BTN_COMPACT = "inline-flex items-center justify-center gap-1 rounded border border-border bg-surface px-1.5 py-0.5 sm:px-2 sm:py-1 text-[10px] sm:text-[11px] font-medium text-foreground hover:bg-surface-hover transition-colors disabled:opacity-40";
|
|
32072
|
+
/** Primary compact button. */
|
|
32073
|
+
var BTN_COMPACT_PRIMARY = "inline-flex items-center justify-center gap-1 rounded border border-primary/40 bg-primary/15 px-1.5 py-0.5 sm:px-2 sm:py-1 text-[10px] sm:text-[11px] font-medium text-primary hover:bg-primary/25 transition-colors disabled:opacity-40";
|
|
32074
|
+
/** Danger compact button. */
|
|
32075
|
+
var BTN_COMPACT_DANGER = "inline-flex items-center justify-center gap-1 rounded border border-danger/40 bg-danger/10 px-1.5 py-0.5 sm:px-2 sm:py-1 text-[10px] sm:text-[11px] font-medium text-danger hover:bg-danger/20 transition-colors disabled:opacity-40";
|
|
32076
|
+
/** Warning compact button (e.g. cancel-drawing). */
|
|
32077
|
+
var BTN_COMPACT_WARNING = "inline-flex items-center justify-center gap-1 rounded border border-warning/40 bg-warning/10 px-1.5 py-0.5 sm:px-2 sm:py-1 text-[10px] sm:text-[11px] font-medium text-warning hover:bg-warning/20 transition-colors disabled:opacity-40";
|
|
32078
|
+
/** Compact text/select/number input. */
|
|
32079
|
+
var INPUT_COMPACT = "w-full rounded border border-border bg-background px-1.5 py-0.5 sm:px-2 sm:py-1 text-[11px] sm:text-xs text-foreground focus:border-primary focus:ring-1 focus:ring-primary/30 outline-none";
|
|
32080
|
+
/** Chip-style toggle (zone / class selectors in ZoneRulesEditor). */
|
|
32081
|
+
var CHIP_BASE = "inline-flex items-center gap-1 rounded-full border px-1.5 py-0.5 text-[10px] font-medium transition-colors";
|
|
32082
|
+
var CHIP_ACTIVE = "border-primary/50 bg-primary/15 text-primary";
|
|
32083
|
+
var CHIP_INACTIVE = "border-border bg-surface text-foreground-subtle hover:bg-surface-hover";
|
|
32084
|
+
//#endregion
|
|
32085
|
+
//#region src/composites/setting-row.tsx
|
|
32086
|
+
function SettingRow({ label, children, actions, elements = "plain", className, valueClassName }) {
|
|
32087
|
+
const LabelTag = elements === "description" ? "dt" : "span";
|
|
32088
|
+
const ValueTag = elements === "description" ? "dd" : "div";
|
|
32089
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
32090
|
+
"data-setting-row": "",
|
|
32091
|
+
className: cn(SETTING_ROW, className),
|
|
32092
|
+
children: [/* @__PURE__ */ jsx(LabelTag, {
|
|
32093
|
+
"data-setting-row-label": "",
|
|
32094
|
+
className: SETTING_ROW_LABEL,
|
|
32095
|
+
children: label
|
|
32096
|
+
}), /* @__PURE__ */ jsxs(ValueTag, {
|
|
32097
|
+
"data-setting-row-value": "",
|
|
32098
|
+
className: SETTING_ROW_VALUE,
|
|
32099
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
32100
|
+
"data-setting-row-value-text": "",
|
|
32101
|
+
className: cn(SETTING_ROW_VALUE_TEXT, valueClassName),
|
|
32102
|
+
children
|
|
32103
|
+
}), actions !== void 0 && /* @__PURE__ */ jsx("span", {
|
|
32104
|
+
className: "flex shrink-0 items-center gap-0.5",
|
|
32105
|
+
children: actions
|
|
32106
|
+
})]
|
|
32107
|
+
})]
|
|
32108
|
+
});
|
|
32109
|
+
}
|
|
32110
|
+
//#endregion
|
|
32111
|
+
//#region src/composites/sort-header-button.tsx
|
|
32112
|
+
function SortHeaderButton({ label, active, dir, onSort }) {
|
|
32113
|
+
return /* @__PURE__ */ jsxs("button", {
|
|
32114
|
+
type: "button",
|
|
32115
|
+
onClick: onSort,
|
|
32116
|
+
className: "group/sort inline-flex items-center gap-0.5 hover:text-foreground transition-colors",
|
|
32117
|
+
children: [/* @__PURE__ */ jsx("span", { children: label }), active ? dir === "asc" ? /* @__PURE__ */ jsx(ChevronUp, { className: "h-3 w-3 flex-shrink-0" }) : /* @__PURE__ */ jsx(ChevronDown, { className: "h-3 w-3 flex-shrink-0" }) : /* @__PURE__ */ jsx(ChevronUp, { className: cn("h-3 w-3 flex-shrink-0 opacity-0 transition-opacity", "group-hover/sort:opacity-30") })]
|
|
32118
|
+
});
|
|
32119
|
+
}
|
|
32120
|
+
//#endregion
|
|
32121
|
+
//#region src/composites/table-sort.ts
|
|
32122
|
+
/**
|
|
32123
|
+
* The toggle rule, and the only copy of it.
|
|
32124
|
+
*
|
|
32125
|
+
* none → asc → desc → none, and a click on a DIFFERENT column starts that
|
|
32126
|
+
* column fresh at `asc`. `sameColumn` says whether the clicked column is the
|
|
32127
|
+
* one currently sorted; `currentDir` is its direction (`null` when nothing is
|
|
32128
|
+
* sorted). Returns the next direction, or `null` for "unsorted".
|
|
32129
|
+
*
|
|
32130
|
+
* Split out from {@link nextTableSort} so the device list — whose sort state
|
|
32131
|
+
* keys columns by `columnId`, not `columnKey` — can reuse the rule without a
|
|
32132
|
+
* cast and without a second copy of it.
|
|
32133
|
+
*/
|
|
32134
|
+
function nextSortDirection(sameColumn, currentDir) {
|
|
32135
|
+
if (!sameColumn || currentDir === null) return "asc";
|
|
32136
|
+
return currentDir === "asc" ? "desc" : null;
|
|
32137
|
+
}
|
|
32138
|
+
/**
|
|
32139
|
+
* Toggle a column's sort on header click: none → asc → desc → none.
|
|
32140
|
+
* Clicking a DIFFERENT column starts it fresh at `asc`.
|
|
32141
|
+
*/
|
|
32142
|
+
function nextTableSort(current, columnKey) {
|
|
32143
|
+
const dir = nextSortDirection(current !== null && current.columnKey === columnKey, current === null ? null : current.dir);
|
|
32144
|
+
return dir === null ? null : {
|
|
32145
|
+
columnKey,
|
|
32146
|
+
dir
|
|
32147
|
+
};
|
|
32148
|
+
}
|
|
32149
|
+
/**
|
|
32150
|
+
* Ascending comparison of two cell values.
|
|
32151
|
+
*
|
|
32152
|
+
* Numbers compare numerically and strings compare with `localeCompare` — a
|
|
32153
|
+
* numeric column must never be ordered as text ("100" before "9"), and a text
|
|
32154
|
+
* column must respect the locale's collation. A mixed column (one row a
|
|
32155
|
+
* number, another a string) falls back to string comparison of both, which is
|
|
32156
|
+
* the only total order available; it is not a shape any caller should build on
|
|
32157
|
+
* purpose.
|
|
32158
|
+
*
|
|
32159
|
+
* `null` is NOT handled here — {@link sortRowsByColumn} pulls it out first,
|
|
32160
|
+
* because its placement is direction-independent and a comparator that is
|
|
32161
|
+
* multiplied by the direction factor cannot express that.
|
|
32162
|
+
*/
|
|
32163
|
+
function compareValues(a, b) {
|
|
32164
|
+
if (typeof a === "number" && typeof b === "number") return a - b;
|
|
32165
|
+
return String(a).localeCompare(String(b));
|
|
32166
|
+
}
|
|
32167
|
+
/**
|
|
32168
|
+
* Return a NEW array of `rows` ordered by `sort`.
|
|
32169
|
+
*
|
|
32170
|
+
* `valueOf` is the column's `sortValue` — it is called once per row per
|
|
32171
|
+
* comparison, so it must be cheap (read a field, do not format a string).
|
|
32172
|
+
* `sort === null` ⇒ a fresh shallow copy in the incoming order.
|
|
32173
|
+
*/
|
|
32174
|
+
function sortRowsByColumn(rows, sort, valueOf) {
|
|
32175
|
+
if (sort === null) return [...rows];
|
|
32176
|
+
const factor = sort.dir === "asc" ? 1 : -1;
|
|
32177
|
+
return rows.toSorted((a, b) => {
|
|
32178
|
+
const av = valueOf(a);
|
|
32179
|
+
const bv = valueOf(b);
|
|
32180
|
+
if (av === null || bv === null) {
|
|
32181
|
+
if (av === bv) return 0;
|
|
32182
|
+
return av === null ? 1 : -1;
|
|
32183
|
+
}
|
|
32184
|
+
return factor * compareValues(av, bv);
|
|
32185
|
+
});
|
|
32186
|
+
}
|
|
32187
|
+
/** Derive the `<th>` `aria-sort` for `columnKey` from the table's sort state. */
|
|
32188
|
+
function ariaSortForColumn(sort, columnKey) {
|
|
32189
|
+
if (sort === null || sort.columnKey !== columnKey) return "none";
|
|
32190
|
+
return sort.dir === "asc" ? "ascending" : "descending";
|
|
32191
|
+
}
|
|
32192
|
+
//#endregion
|
|
32193
|
+
//#region src/composites/data-table.tsx
|
|
32194
|
+
/**
|
|
32195
|
+
* DataTable — shared responsive table for admin pages.
|
|
32196
|
+
*
|
|
32197
|
+
* Recipes baked in:
|
|
32198
|
+
* - `overflow-x-auto` wrapper so narrow viewports don't clip the
|
|
32199
|
+
* right edge (the rounded border survives the scroll).
|
|
32200
|
+
* - `min-w-[Npx]` on the inner table so columns don't squash below
|
|
32201
|
+
* readable width before the scroll kicks in.
|
|
32202
|
+
* - `whitespace-nowrap` on headers — column titles never wrap to
|
|
32203
|
+
* two lines (`AUTO-KILL` was the regression that triggered this).
|
|
32204
|
+
* - Themed `bg-surface` + `border-border` so contrast works in both
|
|
32205
|
+
* light and dark themes.
|
|
32206
|
+
*
|
|
32207
|
+
* Column model: caller supplies `columns: DataColumn<T>[]` and
|
|
32208
|
+
* `rows: T[]`. Each column declares `header`, optional `align`,
|
|
32209
|
+
* optional `nowrap`, and a `render(row) => ReactNode` that produces
|
|
32210
|
+
* the cell content.
|
|
32211
|
+
*
|
|
32212
|
+
* <DataTable
|
|
32213
|
+
* columns={[
|
|
32214
|
+
* { key: 'username', header: 'Username', render: (u) => u.username },
|
|
32215
|
+
* { key: 'role', header: 'Role', render: (u) => <RoleBadge .../> },
|
|
32216
|
+
* { key: 'actions', header: '', align: 'right', render: (u) => <Actions .../> },
|
|
32217
|
+
* ]}
|
|
32218
|
+
* rows={users}
|
|
32219
|
+
* minWidthPx={560}
|
|
32220
|
+
* />
|
|
32221
|
+
*
|
|
32222
|
+
* If finer header markup is needed, pass `headerRender` instead of
|
|
32223
|
+
* `header` (e.g. for a sortable click affordance).
|
|
32224
|
+
*
|
|
32225
|
+
* ── Narrow viewports ──────────────────────────────────────────────────────
|
|
32226
|
+
* The table stays a table. The wrapper is `overflow-x-auto`, so a phone
|
|
32227
|
+
* scrolls the columns sideways INSIDE the table — the page body never moves
|
|
32228
|
+
* sideways, and the cells stay one line (`whitespace-nowrap`). That is the
|
|
32229
|
+
* default (`mobileMode="scroll"`). Cards are opt-in via `mobileMode="cards"`;
|
|
32230
|
+
* `auto` still applies the old column-count rule for a surface that wants it.
|
|
32231
|
+
* See `resolveTableLayout`.
|
|
32232
|
+
*
|
|
32233
|
+
* ── Scrolling the BODY, not the page ──────────────────────────────────────
|
|
32234
|
+
* `maxBodyHeight` caps the table and scrolls its rows INSIDE the container
|
|
32235
|
+
* with the column header pinned. It is ONE prop, not two, because "this list
|
|
32236
|
+
* scrolls internally" and "its header stays visible" are the same decision: a
|
|
32237
|
+
* capped table whose header scrolls away is a list of unlabelled cells.
|
|
32238
|
+
*
|
|
32239
|
+
* Use it wherever the row count is open-ended (rules, targets, delivery
|
|
32240
|
+
* history) so the page keeps its own header, filters and actions in view while
|
|
32241
|
+
* the operator moves through the rows.
|
|
32242
|
+
*/
|
|
32243
|
+
/**
|
|
32244
|
+
* The default cap for an internally-scrolling table.
|
|
32245
|
+
*
|
|
32246
|
+
* `60vh` leaves the page header, its filters and its actions on screen at
|
|
32247
|
+
* every viewport while still showing ~10 rows — and it is a fraction, so it
|
|
32248
|
+
* does not need a breakpoint of its own.
|
|
32249
|
+
*/
|
|
32250
|
+
var TABLE_SCROLL_MAX_H = "max-h-[60vh]";
|
|
32251
|
+
var ALIGN_CLASS = {
|
|
32252
|
+
left: "text-left",
|
|
32253
|
+
right: "text-right",
|
|
32254
|
+
center: "text-center"
|
|
32255
|
+
};
|
|
32256
|
+
function DataTable({ columns, rows, rowKey, onRowClick, minWidthPx = 480, emptyMessage, className, bordered = true, rowClassName, mobileMode = "scroll", maxBodyHeight, defaultSort }) {
|
|
32257
|
+
const isNarrow = useIsMobile();
|
|
32258
|
+
const [sort, setSort] = useState(defaultSort ?? null);
|
|
32259
|
+
const layout = resolveTableLayout({
|
|
32260
|
+
mode: mobileMode,
|
|
32261
|
+
columnCount: columns.length,
|
|
32262
|
+
isNarrow
|
|
32263
|
+
});
|
|
32264
|
+
const scrolls = maxBodyHeight !== void 0;
|
|
32265
|
+
const sortedColumn = useMemo(() => sort === null ? void 0 : columns.find((col) => col.key === sort.columnKey && col.sortValue !== void 0), [columns, sort]);
|
|
32266
|
+
const sortValue = sortedColumn?.sortValue;
|
|
32267
|
+
const displayRows = useMemo(() => sortValue === void 0 ? rows : sortRowsByColumn(rows, sort, sortValue), [
|
|
32268
|
+
rows,
|
|
32269
|
+
sort,
|
|
32270
|
+
sortValue
|
|
32271
|
+
]);
|
|
32272
|
+
const activeSort = sortedColumn === void 0 ? null : sort;
|
|
32273
|
+
if (rows.length === 0 && emptyMessage) return /* @__PURE__ */ jsx("div", {
|
|
32274
|
+
className: `rounded-lg ${bordered ? "border border-border" : ""} bg-surface px-3 py-4 text-xs text-foreground-subtle text-center ${className ?? ""}`,
|
|
32275
|
+
children: emptyMessage
|
|
32276
|
+
});
|
|
32277
|
+
if (rows.length === 0) return null;
|
|
32278
|
+
if (layout === "cards") return /* @__PURE__ */ jsx("div", {
|
|
32279
|
+
className: `space-y-2 ${scrolls ? `${maxBodyHeight} overflow-y-auto` : ""} ${className ?? ""}`,
|
|
32280
|
+
children: displayRows.map((row, rowIndex) => /* @__PURE__ */ jsx(DataTableCard, {
|
|
32281
|
+
row,
|
|
32282
|
+
rowIndex,
|
|
32283
|
+
columns,
|
|
32284
|
+
bordered,
|
|
32285
|
+
onRowClick,
|
|
32286
|
+
rowClassName
|
|
32287
|
+
}, rowKey ? rowKey(row, rowIndex) : rowIndex))
|
|
32288
|
+
});
|
|
32289
|
+
return /* @__PURE__ */ jsx("div", {
|
|
32290
|
+
className: [
|
|
32291
|
+
"rounded-lg",
|
|
32292
|
+
bordered ? "border border-border" : "",
|
|
32293
|
+
"bg-surface overflow-x-auto",
|
|
32294
|
+
scrolls ? `${maxBodyHeight} overflow-y-auto` : "",
|
|
32295
|
+
className ?? ""
|
|
32296
|
+
].filter(Boolean).join(" "),
|
|
32297
|
+
children: /* @__PURE__ */ jsxs("table", {
|
|
32298
|
+
className: `w-full text-xs ${scrolls ? "border-separate border-spacing-0" : ""}`,
|
|
32299
|
+
style: { minWidth: `${minWidthPx}px` },
|
|
32300
|
+
children: [/* @__PURE__ */ jsx("thead", {
|
|
32301
|
+
className: "bg-surface",
|
|
32302
|
+
children: /* @__PURE__ */ jsx("tr", { children: columns.map((col) => {
|
|
32303
|
+
const align = col.align ?? "left";
|
|
32304
|
+
const nowrap = col.nowrap ?? true;
|
|
32305
|
+
const sortable = col.sortValue !== void 0;
|
|
32306
|
+
const isSorted = activeSort !== null && activeSort.columnKey === col.key;
|
|
32307
|
+
return /* @__PURE__ */ jsx("th", {
|
|
32308
|
+
"aria-sort": sortable ? ariaSortForColumn(activeSort, col.key) : void 0,
|
|
32309
|
+
title: sortable ? void 0 : col.notSortableReason,
|
|
32310
|
+
className: [
|
|
32311
|
+
"px-3 py-2 text-foreground-subtle font-medium bg-surface border-b border-border",
|
|
32312
|
+
scrolls ? "sticky top-0 z-10" : "",
|
|
32313
|
+
ALIGN_CLASS[align],
|
|
32314
|
+
nowrap ? "whitespace-nowrap" : "",
|
|
32315
|
+
col.width ?? ""
|
|
32316
|
+
].filter(Boolean).join(" "),
|
|
32317
|
+
children: sortable ? /* @__PURE__ */ jsx(SortHeaderButton, {
|
|
32318
|
+
label: col.headerRender ? col.headerRender() : col.header,
|
|
32319
|
+
active: isSorted,
|
|
32320
|
+
dir: isSorted && activeSort !== null ? activeSort.dir : "asc",
|
|
32321
|
+
onSort: () => setSort((prev) => nextTableSort(prev, col.key))
|
|
32322
|
+
}) : col.headerRender ? col.headerRender() : col.header
|
|
32323
|
+
}, col.key);
|
|
32324
|
+
}) })
|
|
32325
|
+
}), /* @__PURE__ */ jsx("tbody", { children: displayRows.map((row, rowIndex) => {
|
|
32326
|
+
const key = rowKey ? rowKey(row, rowIndex) : rowIndex;
|
|
32327
|
+
const extra = rowClassName?.(row, rowIndex) ?? "";
|
|
32328
|
+
const interactive = onRowClick !== void 0;
|
|
32329
|
+
return /* @__PURE__ */ jsx("tr", {
|
|
32330
|
+
onClick: interactive ? () => onRowClick(row, rowIndex) : void 0,
|
|
32331
|
+
className: [interactive ? "cursor-pointer hover:bg-primary/5" : "hover:bg-primary/5", extra].filter(Boolean).join(" "),
|
|
32332
|
+
children: columns.map((col) => {
|
|
32333
|
+
const align = col.align ?? "left";
|
|
32334
|
+
const nowrap = col.nowrap ?? true;
|
|
32335
|
+
return /* @__PURE__ */ jsx("td", {
|
|
32336
|
+
className: [
|
|
32337
|
+
"px-3 py-2 text-foreground border-b border-border",
|
|
32338
|
+
ALIGN_CLASS[align],
|
|
32339
|
+
nowrap ? "whitespace-nowrap" : ""
|
|
32340
|
+
].filter(Boolean).join(" "),
|
|
32341
|
+
children: col.render(row, rowIndex)
|
|
32342
|
+
}, col.key);
|
|
32343
|
+
})
|
|
32344
|
+
}, key);
|
|
32345
|
+
}) })]
|
|
32346
|
+
})
|
|
32347
|
+
});
|
|
32348
|
+
}
|
|
32349
|
+
/**
|
|
32350
|
+
* One row as a card. Columns that carry a plain-text `header` become labelled
|
|
32351
|
+
* `SettingRow`s — the label is the column title and the value gets the full
|
|
32352
|
+
* card width. Columns with no text header (an actions column, a
|
|
32353
|
+
* `headerRender`-only column) have no label to show, so they render as a
|
|
32354
|
+
* full-width strip at the foot of the card.
|
|
32355
|
+
*/
|
|
32356
|
+
function DataTableCard({ row, rowIndex, columns, bordered, onRowClick, rowClassName }) {
|
|
32357
|
+
const labelled = columns.filter((col) => col.header !== void 0 && col.header !== "");
|
|
32358
|
+
const unlabelled = columns.filter((col) => col.header === void 0 || col.header === "");
|
|
32359
|
+
const interactive = onRowClick !== void 0;
|
|
32360
|
+
const extra = rowClassName?.(row, rowIndex) ?? "";
|
|
32361
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
32362
|
+
"data-data-table-card": "",
|
|
32363
|
+
onClick: interactive ? () => onRowClick(row, rowIndex) : void 0,
|
|
32364
|
+
className: [
|
|
32365
|
+
"rounded-lg bg-surface px-3 py-1.5 divide-y divide-border-subtle",
|
|
32366
|
+
bordered ? "border border-border" : "",
|
|
32367
|
+
interactive ? "cursor-pointer hover:bg-primary/5" : "",
|
|
32368
|
+
extra
|
|
32369
|
+
].filter(Boolean).join(" "),
|
|
32370
|
+
children: [labelled.map((col) => /* @__PURE__ */ jsx(SettingRow, {
|
|
32371
|
+
label: col.header,
|
|
32372
|
+
children: col.render(row, rowIndex)
|
|
32373
|
+
}, col.key)), unlabelled.length > 0 && /* @__PURE__ */ jsx("div", {
|
|
32374
|
+
className: "flex flex-wrap items-center justify-end gap-2 py-1.5",
|
|
32375
|
+
children: unlabelled.map((col) => /* @__PURE__ */ jsx("div", { children: col.render(row, rowIndex) }, col.key))
|
|
32376
|
+
})]
|
|
30831
32377
|
});
|
|
30832
32378
|
}
|
|
30833
32379
|
//#endregion
|
|
30834
|
-
//#region src/composites/
|
|
30835
|
-
/** The lighting variants an operator is OFFERED. The resolver can also report
|
|
30836
|
-
* `night`, `dawn` and `dusk`; those are shown when present but never demanded,
|
|
30837
|
-
* because most installs only ever see day and IR. */
|
|
30838
|
-
var SCENE_CAPTURE_VARIANTS = ["day", "ir"];
|
|
30839
|
-
var VARIANT_LABEL = {
|
|
30840
|
-
day: "Daylight",
|
|
30841
|
-
ir: "Night (IR)",
|
|
30842
|
-
night: "Night",
|
|
30843
|
-
dawn: "Dawn",
|
|
30844
|
-
dusk: "Dusk"
|
|
30845
|
-
};
|
|
30846
|
-
function variantLabel(condition) {
|
|
30847
|
-
return VARIANT_LABEL[condition] ?? condition;
|
|
30848
|
-
}
|
|
32380
|
+
//#region src/composites/device-list/fuzzy-match.ts
|
|
30849
32381
|
/**
|
|
30850
|
-
*
|
|
32382
|
+
* fuzzy-match — case and separator-insensitive text search helper.
|
|
30851
32383
|
*
|
|
30852
|
-
*
|
|
30853
|
-
*
|
|
30854
|
-
*
|
|
32384
|
+
* Normalization rule: lowercase + strip all runs of hyphens, underscores and
|
|
32385
|
+
* whitespace entirely. This makes `Tapparella cucina` and `tapparella-cucina`
|
|
32386
|
+
* both normalize to `tapparellacucina`, so a substring match succeeds in
|
|
32387
|
+
* either direction.
|
|
32388
|
+
*/
|
|
32389
|
+
/**
|
|
32390
|
+
* Strips hyphens, underscores and whitespace runs from `s` and lowercases it.
|
|
30855
32391
|
*
|
|
30856
|
-
*
|
|
30857
|
-
*
|
|
30858
|
-
*
|
|
30859
|
-
*
|
|
30860
|
-
* happens instead, which differs by the scene's own policy.
|
|
32392
|
+
* @example
|
|
32393
|
+
* normalizeForSearch('Tapparella cucina') // 'tapparellacucina'
|
|
32394
|
+
* normalizeForSearch('tapparella-cucina') // 'tapparellacucina'
|
|
32395
|
+
* normalizeForSearch('tapparella_cucina') // 'tapparellacucina'
|
|
30861
32396
|
*/
|
|
30862
|
-
function
|
|
30863
|
-
|
|
30864
|
-
const parts = SCENE_CAPTURE_VARIANTS.map((v) => `${variantLabel(v)} ${covered.has(v) ? "✓" : "✗"}`);
|
|
30865
|
-
const extra = [...covered].filter((c) => !SCENE_CAPTURE_VARIANTS.some((v) => v === c));
|
|
30866
|
-
for (const c of extra) parts.push(`${variantLabel(c)} ✓`);
|
|
30867
|
-
const missing = SCENE_CAPTURE_VARIANTS.filter((v) => !covered.has(v));
|
|
30868
|
-
if (missing.length === 0) return parts.join(" · ");
|
|
30869
|
-
if (covered.size === 0) return `${parts.join(" · ")} — nothing captured yet, so this scene is not watching.`;
|
|
30870
|
-
const names = missing.map((v) => variantLabel(v).toLowerCase()).join(" and ");
|
|
30871
|
-
return monitor.onUncoveredCondition === "judge-anyway" ? `${parts.join(" · ")} — ${names} judged against the references you do have.` : `${parts.join(" · ")} — optional; checks in ${names} are skipped.`;
|
|
32397
|
+
function normalizeForSearch(s) {
|
|
32398
|
+
return s.toLowerCase().replace(/[-_\s]+/g, "");
|
|
30872
32399
|
}
|
|
30873
32400
|
/**
|
|
30874
|
-
*
|
|
30875
|
-
*
|
|
32401
|
+
* Returns `true` when the normalized form of `target` contains the normalized
|
|
32402
|
+
* form of `query`. An empty query always matches.
|
|
30876
32403
|
*
|
|
30877
|
-
*
|
|
30878
|
-
*
|
|
30879
|
-
*
|
|
30880
|
-
*
|
|
32404
|
+
* @example
|
|
32405
|
+
* fuzzyMatch('Tapparella cucina', 'tapparella-cucina') // true
|
|
32406
|
+
* fuzzyMatch('tapparella cucina', 'Tapparella-Cucina') // true
|
|
32407
|
+
* fuzzyMatch('xyz', 'tapparella-cucina') // false
|
|
30881
32408
|
*/
|
|
30882
|
-
function
|
|
30883
|
-
|
|
30884
|
-
|
|
30885
|
-
return
|
|
32409
|
+
function fuzzyMatch(query, target) {
|
|
32410
|
+
const nq = normalizeForSearch(query);
|
|
32411
|
+
if (nq === "") return true;
|
|
32412
|
+
return normalizeForSearch(target).includes(nq);
|
|
30886
32413
|
}
|
|
30887
|
-
|
|
30888
|
-
|
|
30889
|
-
|
|
30890
|
-
|
|
30891
|
-
|
|
30892
|
-
|
|
32414
|
+
//#endregion
|
|
32415
|
+
//#region src/composites/data-table-filter.ts
|
|
32416
|
+
/**
|
|
32417
|
+
* Per-instance filtering for a `DataTable` (or any row list): a search box
|
|
32418
|
+
* and a set of facet chips, both DERIVED from the rows the instance renders.
|
|
32419
|
+
*
|
|
32420
|
+
* Pure — no React. The state lives with the caller (`useDataTableFilter`), so
|
|
32421
|
+
* two tables on one page each carry their own filter, and the caller keeps the
|
|
32422
|
+
* FILTERED set it renders: a table whose selection acts on "what is on
|
|
32423
|
+
* screen" has to know what that is, which a filter hidden inside the table
|
|
32424
|
+
* could not tell it.
|
|
32425
|
+
*
|
|
32426
|
+
* Two rules, both load-bearing:
|
|
32427
|
+
* - **Facets are derived from the rows present**, most common first. A
|
|
32428
|
+
* hand-listed set goes stale the day a provider adds a type and offers
|
|
32429
|
+
* chips that match nothing.
|
|
32430
|
+
* - **A selected facet no row carries is ignored**, not applied. The chip is
|
|
32431
|
+
* not drawn (there is no row to derive it from), and an invisible filter
|
|
32432
|
+
* that empties the table is a table that looks broken.
|
|
32433
|
+
*/
|
|
32434
|
+
var EMPTY_DATA_TABLE_FILTER = {
|
|
32435
|
+
search: "",
|
|
32436
|
+
facets: []
|
|
30893
32437
|
};
|
|
30894
32438
|
/**
|
|
30895
|
-
* The
|
|
30896
|
-
*
|
|
32439
|
+
* The facet chips for these rows: one per distinct value, most common first,
|
|
32440
|
+
* ties by value.
|
|
30897
32441
|
*/
|
|
30898
|
-
function
|
|
30899
|
-
if (
|
|
30900
|
-
|
|
30901
|
-
const
|
|
30902
|
-
|
|
30903
|
-
|
|
30904
|
-
|
|
30905
|
-
|
|
30906
|
-
|
|
30907
|
-
|
|
30908
|
-
|
|
30909
|
-
* thing the operator asked to be told and it outlives the live state.
|
|
30910
|
-
*
|
|
30911
|
-
* A scene sitting out an uncovered light reads `Paused`, in the NEUTRAL tone —
|
|
30912
|
-
* never `alarm`, and never the `danger` variant the page maps that to. A
|
|
30913
|
-
* missing IR reference must not be able to paint a red badge on a scene that
|
|
30914
|
-
* is doing exactly what it was configured to do. */
|
|
30915
|
-
function badgeFor(monitor) {
|
|
30916
|
-
if (monitor.states.length === 0) return {
|
|
30917
|
-
text: "Not armed",
|
|
30918
|
-
tone: "unknown"
|
|
30919
|
-
};
|
|
30920
|
-
if (monitor.latched) return {
|
|
30921
|
-
text: "Changed",
|
|
30922
|
-
tone: "alarm"
|
|
30923
|
-
};
|
|
30924
|
-
if (monitor.suspendedCondition !== null) return {
|
|
30925
|
-
text: "Paused",
|
|
30926
|
-
tone: "unknown"
|
|
30927
|
-
};
|
|
30928
|
-
if (monitor.verdict === "unknown") return {
|
|
30929
|
-
text: "Can’t tell",
|
|
30930
|
-
tone: "unknown"
|
|
30931
|
-
};
|
|
30932
|
-
return monitor.verdict === "diverged" ? {
|
|
30933
|
-
text: "Changed",
|
|
30934
|
-
tone: "alarm"
|
|
30935
|
-
} : {
|
|
30936
|
-
text: "Normal",
|
|
30937
|
-
tone: "ok"
|
|
30938
|
-
};
|
|
32442
|
+
function dataTableFacets(rows, facetValue) {
|
|
32443
|
+
if (facetValue === void 0) return [];
|
|
32444
|
+
const counts = /* @__PURE__ */ new Map();
|
|
32445
|
+
for (const row of rows) {
|
|
32446
|
+
const value = facetValue(row);
|
|
32447
|
+
counts.set(value, (counts.get(value) ?? 0) + 1);
|
|
32448
|
+
}
|
|
32449
|
+
return [...counts.entries()].map(([value, count]) => ({
|
|
32450
|
+
value,
|
|
32451
|
+
count
|
|
32452
|
+
})).toSorted((a, b) => b.count - a.count || a.value.localeCompare(b.value));
|
|
30939
32453
|
}
|
|
30940
|
-
|
|
30941
|
-
|
|
30942
|
-
* failure is silent INSENSITIVITY, which is the worst kind — hence a warning
|
|
30943
|
-
* rather than a refusal. */
|
|
30944
|
-
var ROI_AREA_WARN_FRACTION = .4;
|
|
30945
|
-
function roiTooLarge(roi) {
|
|
30946
|
-
return roi.width * roi.height > ROI_AREA_WARN_FRACTION;
|
|
32454
|
+
function isDataTableFilterActive(state) {
|
|
32455
|
+
return state.search.trim() !== "" || state.facets.length > 0;
|
|
30947
32456
|
}
|
|
30948
|
-
|
|
30949
|
-
|
|
30950
|
-
|
|
30951
|
-
|
|
30952
|
-
|
|
30953
|
-
|
|
30954
|
-
if (h < 48) return `${h}h`;
|
|
30955
|
-
return `${Math.floor(h / 24)}d`;
|
|
32457
|
+
/** A new state with `value` added to, or removed from, the selected facets. */
|
|
32458
|
+
function toggleDataTableFacet(state, value) {
|
|
32459
|
+
return {
|
|
32460
|
+
...state,
|
|
32461
|
+
facets: state.facets.includes(value) ? state.facets.filter((v) => v !== value) : [...state.facets, value]
|
|
32462
|
+
};
|
|
30956
32463
|
}
|
|
30957
|
-
|
|
30958
|
-
|
|
30959
|
-
|
|
30960
|
-
|
|
30961
|
-
|
|
30962
|
-
|
|
30963
|
-
|
|
30964
|
-
|
|
30965
|
-
|
|
30966
|
-
|
|
30967
|
-
|
|
30968
|
-
|
|
30969
|
-
|
|
30970
|
-
|
|
30971
|
-
|
|
30972
|
-
className: "font-mono text-xs bg-surface p-3 rounded-md border border-border-subtle",
|
|
30973
|
-
children: /* @__PURE__ */ jsx("code", { children })
|
|
30974
|
-
})
|
|
30975
|
-
}), /* @__PURE__ */ jsx("div", {
|
|
30976
|
-
className: "absolute top-2 right-2 opacity-0 group-hover:opacity-100 transition-opacity",
|
|
30977
|
-
children: /* @__PURE__ */ jsx(IconButton, {
|
|
30978
|
-
icon: copied ? Check : Copy,
|
|
30979
|
-
"aria-label": "Copy code",
|
|
30980
|
-
variant: "ghost",
|
|
30981
|
-
size: "sm",
|
|
30982
|
-
onClick: handleCopy
|
|
30983
|
-
})
|
|
30984
|
-
})]
|
|
32464
|
+
/**
|
|
32465
|
+
* The rows that survive the filter, in their incoming order.
|
|
32466
|
+
*
|
|
32467
|
+
* A selected facet that none of `rows` carries is dropped from the effective
|
|
32468
|
+
* selection (see the header), so a chip that is not on screen never filters.
|
|
32469
|
+
*/
|
|
32470
|
+
function filterDataTableRows(rows, state, config) {
|
|
32471
|
+
const needle = state.search.trim();
|
|
32472
|
+
const facetValue = config.facetValue;
|
|
32473
|
+
const present = new Set(dataTableFacets(rows, facetValue).map((f) => f.value));
|
|
32474
|
+
const selected = new Set(state.facets.filter((v) => present.has(v)));
|
|
32475
|
+
return rows.filter((row) => {
|
|
32476
|
+
if (selected.size > 0 && facetValue !== void 0 && !selected.has(facetValue(row))) return false;
|
|
32477
|
+
if (needle !== "" && !config.searchText(row).some((text) => fuzzyMatch(needle, text))) return false;
|
|
32478
|
+
return true;
|
|
30985
32479
|
});
|
|
30986
32480
|
}
|
|
30987
32481
|
//#endregion
|
|
30988
|
-
//#region src/composites/
|
|
32482
|
+
//#region src/composites/data-table-filter-bar.tsx
|
|
30989
32483
|
/**
|
|
30990
|
-
*
|
|
32484
|
+
* The controls of one table's filter: a search box and the facet chips.
|
|
30991
32485
|
*
|
|
30992
|
-
*
|
|
30993
|
-
*
|
|
30994
|
-
*
|
|
30995
|
-
* the trigger spinner-disables itself for the duration, and the dialog
|
|
30996
|
-
* closes on success. Errors surface inline at the dialog's bottom.
|
|
32486
|
+
* Controlled — the state comes from `useDataTableFilter` and goes back through
|
|
32487
|
+
* the two callbacks; this component owns nothing, so it can sit above a
|
|
32488
|
+
* `DataTable`, a card's list, or anything else that renders the filtered rows.
|
|
30997
32489
|
*
|
|
30998
|
-
*
|
|
30999
|
-
*
|
|
31000
|
-
* for reboot, RefreshCw for restart).
|
|
32490
|
+
* Every visible string is a prop: this library carries no translations, and
|
|
32491
|
+
* the caller's i18n does.
|
|
31001
32492
|
*/
|
|
31002
|
-
|
|
31003
|
-
|
|
31004
|
-
|
|
31005
|
-
const
|
|
31006
|
-
const
|
|
31007
|
-
|
|
31008
|
-
|
|
31009
|
-
|
|
31010
|
-
|
|
31011
|
-
|
|
31012
|
-
|
|
31013
|
-
|
|
31014
|
-
|
|
31015
|
-
|
|
31016
|
-
|
|
31017
|
-
|
|
31018
|
-
|
|
31019
|
-
|
|
31020
|
-
type: "button",
|
|
31021
|
-
variant: triggerVariant,
|
|
31022
|
-
size,
|
|
31023
|
-
disabled,
|
|
31024
|
-
onClick: () => {
|
|
31025
|
-
setError(null);
|
|
31026
|
-
setOpen(true);
|
|
31027
|
-
},
|
|
31028
|
-
className,
|
|
31029
|
-
children: [Icon && /* @__PURE__ */ jsx(Icon, { className: "h-3.5 w-3.5" }), label]
|
|
31030
|
-
}), /* @__PURE__ */ jsx(Dialog, {
|
|
31031
|
-
open,
|
|
31032
|
-
onOpenChange: (next) => !running && setOpen(next),
|
|
31033
|
-
children: /* @__PURE__ */ jsxs(DialogContent, { children: [
|
|
31034
|
-
/* @__PURE__ */ jsxs(DialogHeader, { children: [/* @__PURE__ */ jsxs(DialogTitle, {
|
|
31035
|
-
className: "flex items-center gap-2",
|
|
31036
|
-
children: [/* @__PURE__ */ jsx(TriangleAlert, { className: "h-4 w-4 text-amber-400" }), title]
|
|
31037
|
-
}), typeof description === "string" ? /* @__PURE__ */ jsx(DialogDescription, { children: description }) : description] }),
|
|
31038
|
-
error && /* @__PURE__ */ jsx("div", {
|
|
31039
|
-
className: cn("mt-2 px-3 py-2 rounded border border-danger/40 bg-danger/10", "text-xs text-danger"),
|
|
31040
|
-
children: error
|
|
32493
|
+
var CHIP_ON = "rounded-full border border-primary bg-primary/10 px-2 py-0.5 text-[10px] text-foreground";
|
|
32494
|
+
var CHIP_OFF = "rounded-full border border-border px-2 py-0.5 text-[10px] text-foreground-muted hover:bg-surface-hover";
|
|
32495
|
+
function DataTableFilterBar({ state, facets, labels, onSearch, onToggleFacet, onClear, facetLabel }) {
|
|
32496
|
+
const active = state.search.trim() !== "" || state.facets.length > 0;
|
|
32497
|
+
const showFacets = facets.length > 1;
|
|
32498
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
32499
|
+
className: "flex flex-wrap items-center gap-2",
|
|
32500
|
+
children: [
|
|
32501
|
+
/* @__PURE__ */ jsxs("label", {
|
|
32502
|
+
className: "relative min-w-[12rem] flex-1",
|
|
32503
|
+
children: [/* @__PURE__ */ jsx(Search, { className: "pointer-events-none absolute left-2 top-1/2 h-3.5 w-3.5 -translate-y-1/2 text-foreground-subtle" }), /* @__PURE__ */ jsx("input", {
|
|
32504
|
+
type: "search",
|
|
32505
|
+
value: state.search,
|
|
32506
|
+
onChange: (e) => onSearch(e.target.value),
|
|
32507
|
+
placeholder: labels.searchPlaceholder,
|
|
32508
|
+
"aria-label": labels.searchLabel,
|
|
32509
|
+
className: "w-full rounded border border-border bg-background py-1.5 pl-7 pr-2 text-xs text-foreground"
|
|
32510
|
+
})]
|
|
31041
32511
|
}),
|
|
31042
|
-
|
|
31043
|
-
|
|
31044
|
-
|
|
31045
|
-
|
|
31046
|
-
|
|
31047
|
-
|
|
31048
|
-
|
|
31049
|
-
|
|
32512
|
+
showFacets && /* @__PURE__ */ jsx("div", {
|
|
32513
|
+
role: "group",
|
|
32514
|
+
"aria-label": labels.facetsLabel,
|
|
32515
|
+
className: "flex flex-wrap gap-1",
|
|
32516
|
+
children: facets.map((facet) => {
|
|
32517
|
+
const pressed = state.facets.includes(facet.value);
|
|
32518
|
+
return /* @__PURE__ */ jsxs("button", {
|
|
32519
|
+
type: "button",
|
|
32520
|
+
onClick: () => onToggleFacet(facet.value),
|
|
32521
|
+
"aria-pressed": pressed,
|
|
32522
|
+
className: pressed ? CHIP_ON : CHIP_OFF,
|
|
32523
|
+
children: [
|
|
32524
|
+
facetLabel ? facetLabel(facet.value) : facet.value,
|
|
32525
|
+
" ",
|
|
32526
|
+
/* @__PURE__ */ jsx("span", {
|
|
32527
|
+
className: "text-foreground-subtle tabular-nums",
|
|
32528
|
+
children: facet.count
|
|
32529
|
+
})
|
|
32530
|
+
]
|
|
32531
|
+
}, facet.value);
|
|
32532
|
+
})
|
|
32533
|
+
}),
|
|
32534
|
+
active && /* @__PURE__ */ jsxs("button", {
|
|
31050
32535
|
type: "button",
|
|
31051
|
-
|
|
31052
|
-
|
|
31053
|
-
|
|
31054
|
-
|
|
31055
|
-
|
|
31056
|
-
|
|
31057
|
-
children: [running && /* @__PURE__ */ jsx(LoaderCircle, { className: "h-3.5 w-3.5 animate-spin" }), confirmLabel ?? label]
|
|
31058
|
-
})] })
|
|
31059
|
-
] })
|
|
31060
|
-
})] });
|
|
32536
|
+
onClick: onClear,
|
|
32537
|
+
className: "flex items-center gap-1 text-[11px] text-foreground-subtle hover:text-foreground",
|
|
32538
|
+
children: [/* @__PURE__ */ jsx(X, { className: "h-3 w-3" }), labels.clearLabel]
|
|
32539
|
+
})
|
|
32540
|
+
]
|
|
32541
|
+
});
|
|
31061
32542
|
}
|
|
31062
32543
|
//#endregion
|
|
31063
|
-
//#region src/composites/
|
|
32544
|
+
//#region src/composites/use-data-table-filter.ts
|
|
31064
32545
|
/**
|
|
31065
|
-
*
|
|
31066
|
-
*
|
|
31067
|
-
*
|
|
31068
|
-
*
|
|
32546
|
+
* The React half of `data-table-filter.ts`: one filter state per call site,
|
|
32547
|
+
* so every table on a page filters on its own.
|
|
32548
|
+
*
|
|
32549
|
+
* The caller renders `rows` (the filtered set) and hands `state` + the two
|
|
32550
|
+
* setters to a `DataTableFilterBar`. It keeps the filtered set because
|
|
32551
|
+
* anything that acts on "the rows on screen" — a select-all, a bulk action —
|
|
32552
|
+
* must act on exactly these and nothing the filter hid.
|
|
31069
32553
|
*/
|
|
31070
|
-
|
|
31071
|
-
|
|
31072
|
-
const
|
|
31073
|
-
|
|
31074
|
-
|
|
31075
|
-
|
|
31076
|
-
|
|
31077
|
-
|
|
31078
|
-
|
|
31079
|
-
|
|
31080
|
-
|
|
31081
|
-
|
|
31082
|
-
|
|
31083
|
-
|
|
31084
|
-
|
|
31085
|
-
|
|
31086
|
-
|
|
31087
|
-
|
|
31088
|
-
|
|
31089
|
-
|
|
31090
|
-
|
|
31091
|
-
|
|
31092
|
-
|
|
32554
|
+
function useDataTableFilter(rows, config) {
|
|
32555
|
+
const [state, setState] = useState(EMPTY_DATA_TABLE_FILTER);
|
|
32556
|
+
const setSearch = useCallback((search) => {
|
|
32557
|
+
setState((prev) => ({
|
|
32558
|
+
...prev,
|
|
32559
|
+
search
|
|
32560
|
+
}));
|
|
32561
|
+
}, []);
|
|
32562
|
+
const toggleFacet = useCallback((value) => {
|
|
32563
|
+
setState((prev) => toggleDataTableFacet(prev, value));
|
|
32564
|
+
}, []);
|
|
32565
|
+
const clear = useCallback(() => setState(EMPTY_DATA_TABLE_FILTER), []);
|
|
32566
|
+
const { searchText, facetValue } = config;
|
|
32567
|
+
return {
|
|
32568
|
+
state,
|
|
32569
|
+
setSearch,
|
|
32570
|
+
toggleFacet,
|
|
32571
|
+
clear,
|
|
32572
|
+
facets: useMemo(() => dataTableFacets(rows, facetValue), [rows, facetValue]),
|
|
32573
|
+
rows: useMemo(() => filterDataTableRows(rows, state, {
|
|
32574
|
+
searchText,
|
|
32575
|
+
facetValue
|
|
32576
|
+
}), [
|
|
32577
|
+
rows,
|
|
32578
|
+
state,
|
|
32579
|
+
searchText,
|
|
32580
|
+
facetValue
|
|
32581
|
+
]),
|
|
32582
|
+
active: isDataTableFilterActive(state)
|
|
32583
|
+
};
|
|
31093
32584
|
}
|
|
31094
32585
|
//#endregion
|
|
31095
32586
|
//#region src/composites/detection-colors.ts
|
|
@@ -44867,35 +46358,129 @@ function deviceRoleMetaOf(role) {
|
|
|
44867
46358
|
return DEVICE_ROLE_META[role] ?? FALLBACK_DEVICE_ROLE_META;
|
|
44868
46359
|
}
|
|
44869
46360
|
/**
|
|
44870
|
-
* Icons an operator may pick for a per-device `display.icon` override
|
|
44871
|
-
* a stable kebab-case name.
|
|
44872
|
-
*
|
|
44873
|
-
*
|
|
44874
|
-
*
|
|
46361
|
+
* Icons an operator may pick for a per-device `display.icon` override (and for
|
|
46362
|
+
* a per-role default), keyed by a stable kebab-case name. Named imports only —
|
|
46363
|
+
* no dynamic indexing into lucide, so the bundle carries exactly this set.
|
|
46364
|
+
* Unknown keys resolve to `undefined` (caller falls through to the next level).
|
|
46365
|
+
*
|
|
46366
|
+
* The vocabulary is the one the VIEWER draws from too (its own icon module,
|
|
46367
|
+
* keyed by these same strings): a key added here that the phone cannot draw
|
|
46368
|
+
* falls through to the next resolution level there, which reads as "my change
|
|
46369
|
+
* did nothing". So the KEY is the contract — a stable kebab-case string, never
|
|
46370
|
+
* a glyph identity — and `device-meta.test.ts` pins that every key resolves
|
|
46371
|
+
* and that the set never loses a key an operator may already have persisted.
|
|
46372
|
+
*
|
|
46373
|
+
* Grouped by what an operator is naming: a device, a light or appliance, a
|
|
46374
|
+
* sensor or the weather it reads, a room, or what moves through it. `gauge2`
|
|
46375
|
+
* is a legacy alias kept for rows that persisted it.
|
|
44875
46376
|
*/
|
|
44876
46377
|
var DISPLAY_ICON_REGISTRY = {
|
|
46378
|
+
camera: Camera,
|
|
46379
|
+
network: Network,
|
|
46380
|
+
"toggle-left": ToggleLeft,
|
|
46381
|
+
"toggle-right": ToggleRight,
|
|
46382
|
+
"circle-dot": CircleDot,
|
|
46383
|
+
"refresh-cw": RefreshCw,
|
|
46384
|
+
box: Box,
|
|
46385
|
+
"scroll-text": ScrollText,
|
|
46386
|
+
workflow: Workflow,
|
|
46387
|
+
lock: Lock,
|
|
46388
|
+
"lock-open": LockOpen,
|
|
46389
|
+
blinds: Blinds,
|
|
46390
|
+
"air-vent": AirVent,
|
|
46391
|
+
"monitor-play": MonitorPlay,
|
|
46392
|
+
"sliders-horizontal": SlidersHorizontal,
|
|
46393
|
+
"map-pin": MapPin,
|
|
46394
|
+
bot: Bot,
|
|
46395
|
+
tractor: Tractor,
|
|
46396
|
+
image: Image,
|
|
46397
|
+
bone: Bone,
|
|
46398
|
+
"door-closed": DoorClosed,
|
|
46399
|
+
"door-open": DoorOpen,
|
|
46400
|
+
crosshair: Crosshair,
|
|
46401
|
+
eye: Eye,
|
|
46402
|
+
"eye-off": EyeOff,
|
|
46403
|
+
smartphone: Smartphone,
|
|
46404
|
+
phone: Phone,
|
|
46405
|
+
tablet: Tablet,
|
|
46406
|
+
laptop: Laptop,
|
|
46407
|
+
monitor: Monitor,
|
|
46408
|
+
tv: Tv,
|
|
46409
|
+
speaker: Speaker,
|
|
46410
|
+
printer: Printer,
|
|
46411
|
+
projector: Projector,
|
|
46412
|
+
"gamepad-2": Gamepad2,
|
|
46413
|
+
radio: Radio,
|
|
46414
|
+
router: Router,
|
|
46415
|
+
bluetooth: Bluetooth,
|
|
46416
|
+
cpu: Cpu,
|
|
46417
|
+
"hard-drive": HardDrive,
|
|
46418
|
+
server: Server,
|
|
46419
|
+
mic: Mic,
|
|
46420
|
+
"mic-off": MicOff,
|
|
46421
|
+
video: Video,
|
|
46422
|
+
"video-off": VideoOff,
|
|
46423
|
+
music: Music,
|
|
46424
|
+
plug: Plug,
|
|
46425
|
+
"plug-zap": PlugZap,
|
|
46426
|
+
power: Power,
|
|
46427
|
+
"power-off": PowerOff,
|
|
46428
|
+
cable: Cable,
|
|
46429
|
+
battery: Battery,
|
|
46430
|
+
"battery-charging": BatteryCharging,
|
|
46431
|
+
"battery-full": BatteryFull,
|
|
46432
|
+
"battery-low": BatteryLow,
|
|
46433
|
+
key: Key,
|
|
46434
|
+
"key-round": KeyRound,
|
|
46435
|
+
mailbox: Mailbox,
|
|
46436
|
+
package: Package,
|
|
46437
|
+
shield: Shield,
|
|
46438
|
+
"shield-check": ShieldCheck,
|
|
46439
|
+
"shield-off": ShieldOff,
|
|
46440
|
+
lightbulb: Lightbulb,
|
|
46441
|
+
lamp: Lamp,
|
|
46442
|
+
"lamp-ceiling": LampCeiling,
|
|
46443
|
+
"lamp-desk": LampDesk,
|
|
46444
|
+
"lamp-floor": LampFloor,
|
|
46445
|
+
flashlight: Flashlight,
|
|
46446
|
+
heater: Heater,
|
|
46447
|
+
snowflake: Snowflake,
|
|
46448
|
+
"thermometer-sun": ThermometerSun,
|
|
46449
|
+
"thermometer-snowflake": ThermometerSnowflake,
|
|
46450
|
+
refrigerator: Refrigerator,
|
|
46451
|
+
microwave: Microwave,
|
|
46452
|
+
"washing-machine": WashingMachine,
|
|
46453
|
+
"cooking-pot": CookingPot,
|
|
46454
|
+
utensils: Utensils,
|
|
44877
46455
|
thermometer: Thermometer,
|
|
44878
46456
|
droplets: Droplets,
|
|
44879
46457
|
droplet: Droplet,
|
|
44880
46458
|
gauge: Gauge,
|
|
46459
|
+
gauge2: Gauge,
|
|
44881
46460
|
sun: Sun,
|
|
44882
46461
|
"sun-medium": SunMedium,
|
|
44883
46462
|
sunrise: Sunrise,
|
|
44884
46463
|
moon: Moon,
|
|
44885
46464
|
wind: Wind,
|
|
46465
|
+
cloud: Cloud,
|
|
44886
46466
|
"cloud-rain": CloudRain,
|
|
44887
46467
|
"cloud-sun": CloudSun,
|
|
44888
46468
|
waves: Waves,
|
|
44889
46469
|
sprout: Sprout,
|
|
46470
|
+
leaf: Leaf,
|
|
46471
|
+
flower: Flower,
|
|
44890
46472
|
zap: Zap,
|
|
44891
46473
|
flame: Flame,
|
|
44892
46474
|
bell: Bell,
|
|
46475
|
+
"bell-ring": BellRing,
|
|
46476
|
+
"bell-off": BellOff,
|
|
44893
46477
|
siren: Siren,
|
|
44894
46478
|
radar: Radar,
|
|
44895
46479
|
activity: Activity,
|
|
44896
46480
|
hash: Hash,
|
|
44897
46481
|
clock: Clock,
|
|
44898
|
-
|
|
46482
|
+
timer: Timer,
|
|
46483
|
+
calendar: Calendar,
|
|
44899
46484
|
pipette: Pipette,
|
|
44900
46485
|
fan: Fan,
|
|
44901
46486
|
bath: Bath,
|
|
@@ -44904,9 +46489,49 @@ var DISPLAY_ICON_REGISTRY = {
|
|
|
44904
46489
|
"shield-alert": ShieldAlert,
|
|
44905
46490
|
vibrate: Vibrate,
|
|
44906
46491
|
wifi: Wifi,
|
|
46492
|
+
"wifi-off": WifiOff,
|
|
44907
46493
|
"volume-2": Volume2,
|
|
44908
|
-
|
|
44909
|
-
|
|
46494
|
+
"volume-x": VolumeX,
|
|
46495
|
+
heart: Heart,
|
|
46496
|
+
"heart-pulse": HeartPulse,
|
|
46497
|
+
star: Star,
|
|
46498
|
+
sparkles: Sparkles,
|
|
46499
|
+
house: House,
|
|
46500
|
+
sofa: Sofa,
|
|
46501
|
+
"bed-double": BedDouble,
|
|
46502
|
+
bed: Bed,
|
|
46503
|
+
warehouse: Warehouse,
|
|
46504
|
+
trees: Trees,
|
|
46505
|
+
"tree-pine": TreePine,
|
|
46506
|
+
fence: Fence,
|
|
46507
|
+
store: Store,
|
|
46508
|
+
building: Building,
|
|
46509
|
+
"building-2": Building2,
|
|
46510
|
+
mountain: Mountain,
|
|
46511
|
+
umbrella: Umbrella,
|
|
46512
|
+
dumbbell: Dumbbell,
|
|
46513
|
+
wrench: Wrench,
|
|
46514
|
+
hammer: Hammer,
|
|
46515
|
+
drill: Drill,
|
|
46516
|
+
"waves-ladder": WavesLadder,
|
|
46517
|
+
"circle-parking": CircleParking,
|
|
46518
|
+
briefcase: Briefcase,
|
|
46519
|
+
route: Route,
|
|
46520
|
+
car: Car,
|
|
46521
|
+
bike: Bike,
|
|
46522
|
+
bus: Bus,
|
|
46523
|
+
truck: Truck,
|
|
46524
|
+
plane: Plane,
|
|
46525
|
+
"train-front": TrainFront,
|
|
46526
|
+
sailboat: Sailboat,
|
|
46527
|
+
dog: Dog,
|
|
46528
|
+
cat: Cat,
|
|
46529
|
+
bird: Bird,
|
|
46530
|
+
"paw-print": PawPrint,
|
|
46531
|
+
baby: Baby,
|
|
46532
|
+
user: User,
|
|
46533
|
+
users: Users,
|
|
46534
|
+
"person-standing": PersonStanding
|
|
44910
46535
|
};
|
|
44911
46536
|
/** Resolve a `display.icon` name to a lucide component, or `undefined` when the
|
|
44912
46537
|
* name is not in the curated `DISPLAY_ICON_REGISTRY`. */
|
|
@@ -45091,12 +46716,35 @@ function resolveFlags(props) {
|
|
|
45091
46716
|
showChildrenAccordion: props.showChildrenAccordion ?? d.showChildrenAccordion
|
|
45092
46717
|
};
|
|
45093
46718
|
}
|
|
45094
|
-
|
|
46719
|
+
/**
|
|
46720
|
+
* The row's lead icon — the ONE resolution order, the same one
|
|
46721
|
+
* `resolveSensorDisplay` applies to unit and precision:
|
|
46722
|
+
*
|
|
46723
|
+
* device override → operator role default → built-in role glyph → type glyph
|
|
46724
|
+
*
|
|
46725
|
+
* `roleDefaults` is what the nearest `RoleDisplayDefaultsProvider` publishes;
|
|
46726
|
+
* callers outside a provider pass nothing and the second level is skipped.
|
|
46727
|
+
* Each level FALLS THROUGH when it names a glyph the registry cannot draw —
|
|
46728
|
+
* an unknown key at any level must never leave the row without an icon, and
|
|
46729
|
+
* must never shadow a lower level that would have drawn one.
|
|
46730
|
+
*
|
|
46731
|
+
* "Set as default for all X sensors" writes the second level. It was written
|
|
46732
|
+
* for a year and read by nothing: this function went straight from the device
|
|
46733
|
+
* override to `DEVICE_ROLE_META`.
|
|
46734
|
+
*/
|
|
46735
|
+
function deviceLeadIcon(device, roleDefaults) {
|
|
45095
46736
|
if (device.display?.icon) {
|
|
45096
46737
|
const overridden = resolveDisplayIcon(device.display.icon);
|
|
45097
46738
|
if (overridden) return overridden;
|
|
45098
46739
|
}
|
|
45099
|
-
if (device.role)
|
|
46740
|
+
if (device.role) {
|
|
46741
|
+
const roleDefaultKey = roleDefaults?.[device.role]?.icon;
|
|
46742
|
+
if (roleDefaultKey !== void 0) {
|
|
46743
|
+
const fromRoleDefault = resolveDisplayIcon(roleDefaultKey);
|
|
46744
|
+
if (fromRoleDefault) return fromRoleDefault;
|
|
46745
|
+
}
|
|
46746
|
+
return deviceRoleMetaOf(device.role).icon;
|
|
46747
|
+
}
|
|
45100
46748
|
return deviceTypeMetaOf(device.type).icon;
|
|
45101
46749
|
}
|
|
45102
46750
|
/**
|
|
@@ -45253,6 +46901,7 @@ function effectiveType(device, containerChildren) {
|
|
|
45253
46901
|
*/
|
|
45254
46902
|
function effectiveIconDevice(device, containerChildren) {
|
|
45255
46903
|
if (device.type !== DeviceType.Container) return device;
|
|
46904
|
+
if (device.display?.icon !== void 0 && resolveDisplayIcon(device.display.icon) !== void 0) return device;
|
|
45256
46905
|
const children = containerChildren ?? [];
|
|
45257
46906
|
if (children.length === 0) return device;
|
|
45258
46907
|
const primary = resolveContainerPrimary(children, device.linkDeviceId, device.primaryChildEntityId);
|
|
@@ -45632,7 +47281,7 @@ function RebootQuickAction({ trpc, deviceId, deviceName }) {
|
|
|
45632
47281
|
* or a standalone test) the hook returns a stable empty array — the same
|
|
45633
47282
|
* graceful default the old optional prop had.
|
|
45634
47283
|
*/
|
|
45635
|
-
var EMPTY$
|
|
47284
|
+
var EMPTY$2 = [];
|
|
45636
47285
|
var ContainerChildrenContext = createContext(null);
|
|
45637
47286
|
function ContainerChildrenProvider({ value, children }) {
|
|
45638
47287
|
return /* @__PURE__ */ jsx(ContainerChildrenContext.Provider, {
|
|
@@ -45647,7 +47296,7 @@ function ContainerChildrenProvider({ value, children }) {
|
|
|
45647
47296
|
* rendered outside a list, degrades exactly like the old optional prop.
|
|
45648
47297
|
*/
|
|
45649
47298
|
function useContainerChildren(deviceId) {
|
|
45650
|
-
return useContext(ContainerChildrenContext)?.get(deviceId) ?? EMPTY$
|
|
47299
|
+
return useContext(ContainerChildrenContext)?.get(deviceId) ?? EMPTY$2;
|
|
45651
47300
|
}
|
|
45652
47301
|
//#endregion
|
|
45653
47302
|
//#region src/composites/device-item/actions.tsx
|
|
@@ -45873,6 +47522,33 @@ function PtzQuickAction({ trpc, deviceId }) {
|
|
|
45873
47522
|
}), document.body)] });
|
|
45874
47523
|
}
|
|
45875
47524
|
//#endregion
|
|
47525
|
+
//#region src/composites/device-item/role-display-defaults-context.tsx
|
|
47526
|
+
var EMPTY$1 = {};
|
|
47527
|
+
var RoleDisplayDefaultsContext = createContext(EMPTY$1);
|
|
47528
|
+
function RoleDisplayDefaultsProvider({ value, children }) {
|
|
47529
|
+
return /* @__PURE__ */ jsx(RoleDisplayDefaultsContext.Provider, {
|
|
47530
|
+
value,
|
|
47531
|
+
children
|
|
47532
|
+
});
|
|
47533
|
+
}
|
|
47534
|
+
/** The defaults published by the nearest provider — an empty record outside
|
|
47535
|
+
* one, never `undefined`, so a caller can index it without a guard. */
|
|
47536
|
+
function useRoleDisplayDefaults() {
|
|
47537
|
+
return useContext(RoleDisplayDefaultsContext);
|
|
47538
|
+
}
|
|
47539
|
+
/**
|
|
47540
|
+
* Reads the defaults from the hub and publishes them. Until the query lands
|
|
47541
|
+
* the children see no defaults — the built-in role glyph, which is what they
|
|
47542
|
+
* would see with no operator default at all, so nothing flashes wrong.
|
|
47543
|
+
*/
|
|
47544
|
+
function RoleDisplayDefaultsFromServer({ children }) {
|
|
47545
|
+
const { data } = useDeviceManagerGetRoleDisplayDefaults({}, { staleTime: 6e4 });
|
|
47546
|
+
return /* @__PURE__ */ jsx(RoleDisplayDefaultsProvider, {
|
|
47547
|
+
value: data?.defaults ?? EMPTY$1,
|
|
47548
|
+
children
|
|
47549
|
+
});
|
|
47550
|
+
}
|
|
47551
|
+
//#endregion
|
|
45876
47552
|
//#region src/composites/device-item/children-accordion.tsx
|
|
45877
47553
|
/**
|
|
45878
47554
|
* <ChildrenAccordion> — accessory + adopted children rows shown when
|
|
@@ -45925,7 +47601,7 @@ function ChildRow$1({ trpc, child, onNavigate, parentName }) {
|
|
|
45925
47601
|
},
|
|
45926
47602
|
className: "w-full flex items-center gap-2 px-3 py-1.5 text-left hover:bg-surface-hover transition-colors cursor-pointer",
|
|
45927
47603
|
children: [
|
|
45928
|
-
/* @__PURE__ */ jsx(deviceLeadIcon(child), { className: "h-3 w-3 text-foreground-subtle flex-shrink-0" }),
|
|
47604
|
+
/* @__PURE__ */ jsx(deviceLeadIcon(child, useRoleDisplayDefaults()), { className: "h-3 w-3 text-foreground-subtle flex-shrink-0" }),
|
|
45929
47605
|
/* @__PURE__ */ jsx("span", {
|
|
45930
47606
|
className: "text-[10.5px] text-foreground flex-1 truncate",
|
|
45931
47607
|
children: childListName(child, parentName)
|
|
@@ -46304,7 +47980,9 @@ var CHEVRON_SLOT_CLASS = {
|
|
|
46304
47980
|
stacked: "h-4 w-4 mt-0.5"
|
|
46305
47981
|
};
|
|
46306
47982
|
function DeviceItemHeader({ device, variant, flags, parent, integrationIcon, hasChildren, expanded, onToggleExpand, onNavigateToParent, stacked = false, nameOverflow = "truncate" }) {
|
|
46307
|
-
const
|
|
47983
|
+
const containerChildren = useContainerChildren(device.id);
|
|
47984
|
+
const roleDefaults = useRoleDisplayDefaults();
|
|
47985
|
+
const Icon = deviceLeadIcon(effectiveIconDevice(device, containerChildren), roleDefaults);
|
|
46308
47986
|
const slotClass = stacked ? CHEVRON_SLOT_CLASS.stacked : CHEVRON_SLOT_CLASS.horizontal;
|
|
46309
47987
|
const lineClass = nameOverflow === "scroll" ? NAME_TEXT_CLASS : "truncate";
|
|
46310
47988
|
return /* @__PURE__ */ jsxs("div", {
|
|
@@ -47111,41 +48789,6 @@ function groupTopLevelAndAccessories(devices, options) {
|
|
|
47111
48789
|
};
|
|
47112
48790
|
}
|
|
47113
48791
|
//#endregion
|
|
47114
|
-
//#region src/composites/device-list/fuzzy-match.ts
|
|
47115
|
-
/**
|
|
47116
|
-
* fuzzy-match — case and separator-insensitive text search helper.
|
|
47117
|
-
*
|
|
47118
|
-
* Normalization rule: lowercase + strip all runs of hyphens, underscores and
|
|
47119
|
-
* whitespace entirely. This makes `Tapparella cucina` and `tapparella-cucina`
|
|
47120
|
-
* both normalize to `tapparellacucina`, so a substring match succeeds in
|
|
47121
|
-
* either direction.
|
|
47122
|
-
*/
|
|
47123
|
-
/**
|
|
47124
|
-
* Strips hyphens, underscores and whitespace runs from `s` and lowercases it.
|
|
47125
|
-
*
|
|
47126
|
-
* @example
|
|
47127
|
-
* normalizeForSearch('Tapparella cucina') // 'tapparellacucina'
|
|
47128
|
-
* normalizeForSearch('tapparella-cucina') // 'tapparellacucina'
|
|
47129
|
-
* normalizeForSearch('tapparella_cucina') // 'tapparellacucina'
|
|
47130
|
-
*/
|
|
47131
|
-
function normalizeForSearch(s) {
|
|
47132
|
-
return s.toLowerCase().replace(/[-_\s]+/g, "");
|
|
47133
|
-
}
|
|
47134
|
-
/**
|
|
47135
|
-
* Returns `true` when the normalized form of `target` contains the normalized
|
|
47136
|
-
* form of `query`. An empty query always matches.
|
|
47137
|
-
*
|
|
47138
|
-
* @example
|
|
47139
|
-
* fuzzyMatch('Tapparella cucina', 'tapparella-cucina') // true
|
|
47140
|
-
* fuzzyMatch('tapparella cucina', 'Tapparella-Cucina') // true
|
|
47141
|
-
* fuzzyMatch('xyz', 'tapparella-cucina') // false
|
|
47142
|
-
*/
|
|
47143
|
-
function fuzzyMatch(query, target) {
|
|
47144
|
-
const nq = normalizeForSearch(query);
|
|
47145
|
-
if (nq === "") return true;
|
|
47146
|
-
return normalizeForSearch(target).includes(nq);
|
|
47147
|
-
}
|
|
47148
|
-
//#endregion
|
|
47149
48792
|
//#region src/composites/device-list/multi-select.tsx
|
|
47150
48793
|
/**
|
|
47151
48794
|
* Compact multi-select dropdown — a single chip-sized trigger ("Label · N")
|
|
@@ -47588,7 +49231,7 @@ function topLevelIndentLevel(device, parentType) {
|
|
|
47588
49231
|
if (HUB_LIKE_PARENT_TYPES.has(parentType.toLowerCase())) return 1;
|
|
47589
49232
|
return 0;
|
|
47590
49233
|
}
|
|
47591
|
-
function TableLayout({ rows, accessoriesByParent,
|
|
49234
|
+
function TableLayout({ rows, accessoriesByParent, expandedParents, onToggleExpand, devices, visibleColumns, trpc, resolveIntegrationIcon, resolveParent, onNavigate, renderRowAction, onDeleteDevice, selectable, rowClickSelects, activeSelected, onToggleSelection, sort, onSort }) {
|
|
47592
49235
|
const showType = visibleColumns.includes("type");
|
|
47593
49236
|
const showFeatures = visibleColumns.includes("features");
|
|
47594
49237
|
const showManufacturer = visibleColumns.includes("manufacturer");
|
|
@@ -47647,7 +49290,6 @@ function TableLayout({ rows, accessoriesByParent, autoExpandedParents, devices,
|
|
|
47647
49290
|
}) }), /* @__PURE__ */ jsx("tbody", { children: rows.map((d) => {
|
|
47648
49291
|
const accessories = accessoriesByParent.get(d.id) ?? [];
|
|
47649
49292
|
const hasAccessories = accessories.length > 0;
|
|
47650
|
-
const autoExpand = autoExpandedParents.has(d.id);
|
|
47651
49293
|
const parentRowParent = d.parentDeviceId !== null ? resolveParent?.(d.parentDeviceId) ?? null : null;
|
|
47652
49294
|
const parentType = d.parentDeviceId !== null ? parentTypeById.get(d.parentDeviceId) ?? null : null;
|
|
47653
49295
|
const selection = selectable ? {
|
|
@@ -47658,7 +49300,8 @@ function TableLayout({ rows, accessoriesByParent, autoExpandedParents, devices,
|
|
|
47658
49300
|
parent: d,
|
|
47659
49301
|
accessories,
|
|
47660
49302
|
hasAccessories,
|
|
47661
|
-
|
|
49303
|
+
expanded: expandedParents.has(d.id),
|
|
49304
|
+
onToggleExpand: () => onToggleExpand(d.id),
|
|
47662
49305
|
trpc,
|
|
47663
49306
|
integrationIcon: showIcon ? resolveIntegrationIcon?.(d.addonId) ?? null : null,
|
|
47664
49307
|
showType,
|
|
@@ -47676,16 +49319,7 @@ function TableLayout({ rows, accessoriesByParent, autoExpandedParents, devices,
|
|
|
47676
49319
|
})
|
|
47677
49320
|
});
|
|
47678
49321
|
}
|
|
47679
|
-
function TableRowGroup({ parent, accessories, hasAccessories,
|
|
47680
|
-
const [expanded, setExpanded] = useState(forceExpanded);
|
|
47681
|
-
const prevForce = useRef(forceExpanded);
|
|
47682
|
-
useEffect(() => {
|
|
47683
|
-
if (prevForce.current !== forceExpanded) {
|
|
47684
|
-
setExpanded(forceExpanded);
|
|
47685
|
-
prevForce.current = forceExpanded;
|
|
47686
|
-
}
|
|
47687
|
-
}, [forceExpanded]);
|
|
47688
|
-
const onToggleExpand = () => setExpanded((v) => !v);
|
|
49322
|
+
function TableRowGroup({ parent, accessories, hasAccessories, expanded, onToggleExpand, trpc, integrationIcon, showType, showManufacturer, showFeatures, parentRowParent, indentLevel, onNavigate, renderRowAction, onDeleteDevice, selection, rowClickSelects }) {
|
|
47689
49323
|
const showAccessoryRows = hasAccessories && expanded;
|
|
47690
49324
|
const grouped = useMemo(() => groupChildrenByLayout(parent.stableId, accessories, parent.childLayout), [
|
|
47691
49325
|
parent.stableId,
|
|
@@ -47952,13 +49586,15 @@ function DeviceModeList(props) {
|
|
|
47952
49586
|
]);
|
|
47953
49587
|
const grouped = useMemo(() => groupTopLevelAndAccessories(filtered), [filtered]);
|
|
47954
49588
|
const sortedTopLevel = useMemo(() => sortRows(grouped.topLevel, sort), [grouped.topLevel, sort]);
|
|
47955
|
-
const
|
|
47956
|
-
|
|
47957
|
-
|
|
47958
|
-
|
|
47959
|
-
|
|
47960
|
-
|
|
47961
|
-
|
|
49589
|
+
const [openParents, setOpenParents] = useState(() => /* @__PURE__ */ new Set());
|
|
49590
|
+
const toggleParent = useCallback((id) => {
|
|
49591
|
+
setOpenParents((prev) => {
|
|
49592
|
+
const next = new Set(prev);
|
|
49593
|
+
if (next.has(id)) next.delete(id);
|
|
49594
|
+
else next.add(id);
|
|
49595
|
+
return next;
|
|
49596
|
+
});
|
|
49597
|
+
}, []);
|
|
47962
49598
|
const totalItems = grouped.topLevel.length;
|
|
47963
49599
|
const totalPages = Math.max(1, Math.ceil(totalItems / currentPageSize));
|
|
47964
49600
|
const safePage = Math.min(url.state.page, totalPages);
|
|
@@ -48028,7 +49664,8 @@ function DeviceModeList(props) {
|
|
|
48028
49664
|
children: /* @__PURE__ */ jsx(TableLayout, {
|
|
48029
49665
|
rows: pageRows,
|
|
48030
49666
|
accessoriesByParent: grouped.accessoriesByParent,
|
|
48031
|
-
|
|
49667
|
+
expandedParents: openParents,
|
|
49668
|
+
onToggleExpand: toggleParent,
|
|
48032
49669
|
visibleColumns,
|
|
48033
49670
|
sort,
|
|
48034
49671
|
onSort,
|
|
@@ -48796,6 +50433,145 @@ function DeviceGrid({ children, minCardWidth = 220, gap = 3, className }) {
|
|
|
48796
50433
|
});
|
|
48797
50434
|
}
|
|
48798
50435
|
//#endregion
|
|
50436
|
+
//#region src/composites/icon-picker.tsx
|
|
50437
|
+
/**
|
|
50438
|
+
* icon-picker — the ONE control for choosing an icon, wherever admin-ui asks.
|
|
50439
|
+
*
|
|
50440
|
+
* There were two: a device one over `DISPLAY_ICON_REGISTRY` and a room one
|
|
50441
|
+
* over `LOCATION_ICON_IDS`, identical apart from the vocabulary they walked.
|
|
50442
|
+
* That was tolerable while the device set was 56 glyphs in a flat grid. It is
|
|
50443
|
+
* not at 157: a picker that only lets the operator HUNT is a picker they stop
|
|
50444
|
+
* using, and the two copies were already drifting — only one of them had an
|
|
50445
|
+
* i18n'd label.
|
|
50446
|
+
*
|
|
50447
|
+
* So the vocabulary, the grouping and the search all come from
|
|
50448
|
+
* `@camstack/types`' `display-icon-vocabulary`, which is the same module the
|
|
50449
|
+
* viewer's sheet searches. What is left here is the web half: a popover, a
|
|
50450
|
+
* grid, and a text field.
|
|
50451
|
+
*
|
|
50452
|
+
* ## What it does NOT own
|
|
50453
|
+
*
|
|
50454
|
+
* - **The glyphs.** `resolveGlyph` is a prop, because this package's table is
|
|
50455
|
+
* `lucide-react` and the viewer's is `lucide-react-native`. A key this build
|
|
50456
|
+
* cannot draw is SKIPPED rather than rendered as a hole — an empty tile
|
|
50457
|
+
* reads as a rendering bug, not as a missing choice.
|
|
50458
|
+
* - **The words.** Every string is a prop. This package has no i18n (one file
|
|
50459
|
+
* in it imports react-i18next, and that is the exception), and a control
|
|
50460
|
+
* that reached for a translation would force it on every consumer.
|
|
50461
|
+
* - **The write.** `onPick` is called and that is all; whether it is a form
|
|
50462
|
+
* value or an immediate mutation is the caller's business, as it already was
|
|
50463
|
+
* in both pickers this replaces.
|
|
50464
|
+
*
|
|
50465
|
+
* ## The clear tile is never filtered away
|
|
50466
|
+
*
|
|
50467
|
+
* The "inherit" / "no icon" choice sits above the sections and ignores the
|
|
50468
|
+
* search. A query that hid it would strand the operator on a glyph they picked
|
|
50469
|
+
* by accident with no way back to the default — the one action a picker must
|
|
50470
|
+
* always offer.
|
|
50471
|
+
*/
|
|
50472
|
+
function IconPicker({ value, onPick, resolveGlyph, fallbackGlyph, labels, only, extraWords, clearGlyph, labelFor, disabled = false }) {
|
|
50473
|
+
const [open, setOpen] = useState(false);
|
|
50474
|
+
const [query, setQuery] = useState("");
|
|
50475
|
+
const allowed = useMemo(() => only === void 0 ? null : new Set(only), [only]);
|
|
50476
|
+
const sections = useMemo(() => {
|
|
50477
|
+
const hits = searchDisplayIcons(query, extraWords);
|
|
50478
|
+
const byGroup = /* @__PURE__ */ new Map();
|
|
50479
|
+
for (const hit of hits) {
|
|
50480
|
+
const { key, group } = hit.entry;
|
|
50481
|
+
if (allowed !== null && !allowed.has(key)) continue;
|
|
50482
|
+
if (resolveGlyph(key) === void 0) continue;
|
|
50483
|
+
const bucket = byGroup.get(group);
|
|
50484
|
+
if (bucket === void 0) byGroup.set(group, [key]);
|
|
50485
|
+
else bucket.push(key);
|
|
50486
|
+
}
|
|
50487
|
+
return DISPLAY_ICON_GROUPS.flatMap((group) => {
|
|
50488
|
+
const keys = byGroup.get(group);
|
|
50489
|
+
return keys === void 0 || keys.length === 0 ? [] : [{
|
|
50490
|
+
group,
|
|
50491
|
+
keys
|
|
50492
|
+
}];
|
|
50493
|
+
});
|
|
50494
|
+
}, [
|
|
50495
|
+
query,
|
|
50496
|
+
extraWords,
|
|
50497
|
+
allowed,
|
|
50498
|
+
resolveGlyph
|
|
50499
|
+
]);
|
|
50500
|
+
const Current = (value === null ? void 0 : resolveGlyph(value)) ?? fallbackGlyph;
|
|
50501
|
+
const choose = async (next) => {
|
|
50502
|
+
setOpen(false);
|
|
50503
|
+
setQuery("");
|
|
50504
|
+
await onPick(next);
|
|
50505
|
+
};
|
|
50506
|
+
const Clear = clearGlyph ?? fallbackGlyph;
|
|
50507
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
50508
|
+
className: "relative flex shrink-0 items-center gap-2",
|
|
50509
|
+
children: [/* @__PURE__ */ jsx("button", {
|
|
50510
|
+
type: "button",
|
|
50511
|
+
disabled,
|
|
50512
|
+
onClick: () => setOpen((o) => !o),
|
|
50513
|
+
"aria-expanded": open,
|
|
50514
|
+
"aria-label": labels.trigger,
|
|
50515
|
+
title: labels.trigger,
|
|
50516
|
+
className: "rounded border border-border p-1 text-foreground-muted hover:bg-surface-hover disabled:opacity-50",
|
|
50517
|
+
children: /* @__PURE__ */ jsx(Current, { className: "h-4 w-4" })
|
|
50518
|
+
}), open && /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("button", {
|
|
50519
|
+
type: "button",
|
|
50520
|
+
"aria-label": labels.close,
|
|
50521
|
+
onClick: () => setOpen(false),
|
|
50522
|
+
className: "fixed inset-0 z-10 cursor-default"
|
|
50523
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
50524
|
+
role: "group",
|
|
50525
|
+
"aria-label": labels.panel,
|
|
50526
|
+
className: "absolute left-0 top-full z-20 mt-1 max-h-80 w-72 overflow-y-auto rounded-md border border-border bg-surface p-2 shadow-lg",
|
|
50527
|
+
children: [
|
|
50528
|
+
/* @__PURE__ */ jsx("input", {
|
|
50529
|
+
type: "search",
|
|
50530
|
+
value: query,
|
|
50531
|
+
autoFocus: true,
|
|
50532
|
+
onChange: (e) => setQuery(e.target.value),
|
|
50533
|
+
placeholder: labels.searchPlaceholder,
|
|
50534
|
+
"aria-label": labels.searchPlaceholder,
|
|
50535
|
+
className: "mb-2 w-full rounded border border-border bg-surface-raised px-2 py-1 text-xs text-foreground placeholder:text-foreground-subtle"
|
|
50536
|
+
}),
|
|
50537
|
+
/* @__PURE__ */ jsxs("button", {
|
|
50538
|
+
type: "button",
|
|
50539
|
+
onClick: () => void choose(null),
|
|
50540
|
+
"aria-pressed": value === null,
|
|
50541
|
+
className: "mb-2 flex w-full items-center gap-1.5 rounded px-1.5 py-1 text-[11px] text-foreground-subtle hover:bg-surface-hover",
|
|
50542
|
+
children: [/* @__PURE__ */ jsx(Clear, { className: "h-3.5 w-3.5" }), labels.clear]
|
|
50543
|
+
}),
|
|
50544
|
+
sections.length === 0 ? /* @__PURE__ */ jsx("p", {
|
|
50545
|
+
className: "px-1.5 py-2 text-[11px] text-foreground-subtle",
|
|
50546
|
+
children: labels.noMatches
|
|
50547
|
+
}) : sections.map(({ group, keys }) => /* @__PURE__ */ jsxs("section", {
|
|
50548
|
+
className: "mb-2 last:mb-0",
|
|
50549
|
+
children: [/* @__PURE__ */ jsx("h4", {
|
|
50550
|
+
className: "px-1.5 pb-1 text-[10px] uppercase tracking-wide text-foreground-subtle",
|
|
50551
|
+
children: labels.groups[group]
|
|
50552
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
50553
|
+
className: "grid grid-cols-7 gap-1",
|
|
50554
|
+
children: keys.map((key) => {
|
|
50555
|
+
const Glyph = resolveGlyph(key);
|
|
50556
|
+
if (Glyph === void 0) return null;
|
|
50557
|
+
const selected = value === key;
|
|
50558
|
+
return /* @__PURE__ */ jsx("button", {
|
|
50559
|
+
type: "button",
|
|
50560
|
+
onClick: () => void choose(key),
|
|
50561
|
+
"aria-pressed": selected,
|
|
50562
|
+
"aria-label": labelFor?.(key) ?? key,
|
|
50563
|
+
title: labelFor?.(key) ?? key,
|
|
50564
|
+
className: selected ? "flex items-center justify-center rounded border border-primary bg-primary/10 p-1.5 text-foreground" : "flex items-center justify-center rounded border border-transparent p-1.5 text-foreground-muted hover:bg-surface-hover",
|
|
50565
|
+
children: /* @__PURE__ */ jsx(Glyph, { className: "h-4 w-4" })
|
|
50566
|
+
}, key);
|
|
50567
|
+
})
|
|
50568
|
+
})]
|
|
50569
|
+
}, group))
|
|
50570
|
+
]
|
|
50571
|
+
})] })]
|
|
50572
|
+
});
|
|
50573
|
+
}
|
|
50574
|
+
//#endregion
|
|
48799
50575
|
//#region src/composites/device-selector-picker.tsx
|
|
48800
50576
|
/**
|
|
48801
50577
|
* <DeviceSelectorPicker> — the operator-facing editor for a v3
|
|
@@ -53743,12 +55519,12 @@ function mirror(input) {
|
|
|
53743
55519
|
* Render inside `<Suspense>` at all call sites. */
|
|
53744
55520
|
var MaskShapeCanvas = lazy(() => import("./MaskShapeCanvas-DI4BY7W2.js").then((m) => ({ default: m.MaskShapeCanvas })));
|
|
53745
55521
|
/** Lazy-wrapped `MotionZonesSettings` — code-split off the main bundle. */
|
|
53746
|
-
var MotionZonesSettings = lazy(() => import("./MotionZonesSettings-
|
|
55522
|
+
var MotionZonesSettings = lazy(() => import("./MotionZonesSettings-DHDfnZyU.js").then((m) => ({ default: m.MotionZonesSettings })));
|
|
53747
55523
|
/** Lazy-wrapped `SceneMonitorEditor` — code-split off the main bundle for the
|
|
53748
55524
|
* same reason: it mounts `MaskShapeCanvas`, which chains react-konva. Render
|
|
53749
55525
|
* inside `<Suspense>`; the admin-ui `/scenes` dialog is its only caller. */
|
|
53750
|
-
var SceneMonitorEditor = lazy(() => import("./SceneMonitorEditor-
|
|
55526
|
+
var SceneMonitorEditor = lazy(() => import("./SceneMonitorEditor-vfWTm6qv.js").then((m) => ({ default: m.SceneMonitorEditor })));
|
|
53751
55527
|
/** Lazy-wrapped `PrivacyMaskSettings` — code-split off the main bundle. */
|
|
53752
|
-
var PrivacyMaskSettings = lazy(() => import("./PrivacyMaskSettings-
|
|
55528
|
+
var PrivacyMaskSettings = lazy(() => import("./PrivacyMaskSettings-DMkchqO1.js").then((m) => ({ default: m.PrivacyMaskSettings })));
|
|
53753
55529
|
//#endregion
|
|
53754
|
-
export { AddonGlobalSettingsForm, AgentStepEditor, AlarmHeroCard, AlarmInlineControl as AlarmPanelInlineControl, AppShell, ArcKnob, AudioClassificationList, AudioLevelWaveform, AudioWaveform, AutomationHeroCard, AutomationInlineControl, AutotrackSection, BTN_COMPACT, BTN_COMPACT_DANGER, BTN_COMPACT_PRIMARY, BTN_COMPACT_WARNING, Badge, BatteryBadge, BottomSheet, Breadcrumb, BrightnessPanel, Button, ButtonControl, ButtonHeroCard, CARD_MODE_MIN_COLUMNS, CENTER, CHIP_ACTIVE, CHIP_BASE, CHIP_INACTIVE, CLASS_COLORS, COLUMN_BREAKPOINT_CLASS, COLUMN_PRIORITY, COMMIT_DEDUPE_TOLERANCE_MS, COMMIT_DEDUPE_WINDOW_MS, CONTROL_CAP_NAMES, CONTROL_FILLS, CameraStreamPlayer, Card, Checkbox, ChildSectionAccordion, ClimatePanel, CodeBlock, CollapsibleCard, ConfigFormBuilder, FormField as ConfigFormField, ConfigSchemaField, ConfirmActionButton, ConfirmDialogProvider, ConsumablesPanel, ContainerChildrenProvider, ContainerPrimaryHero, ControlColumn, ControlHeroCard, ControlInlineControl, ControlPanel, CopyButton, CoverHeroCard, CoverInlineControl, CoverPanel, CustomFieldRenderersProvider, DEFAULT_COLOR, DEVICE_COLUMNS, DEVICE_LIST_PAGE_SIZE_KEY, DEVICE_LIST_PAGE_SIZE_OPTIONS, DEVICE_ROLE_META, DEVICE_TYPE_CONTROL, DEVICE_TYPE_META, DISPLAY_ICON_REGISTRY, DataTable, DetectionCanvas, DetectionOverlay, DetectionResultTree, DevShell, DeviceActivityPanel, DeviceBatchToolbar, DeviceCard, DeviceContextProvider, DeviceExportPanel, DeviceGrid, DeviceItem, DeviceList, DeviceMultiSelectField, DeviceSelectField, DeviceSelectorPicker, DeviceStepMatrix, Dialog, DialogBody, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, DiscoveryPanel, DoorbellRecentPanel, Dropdown, DropdownContent, DropdownItem, DropdownTrigger, DummyHeroCard, DummyInline, EVENT_KIND_ICONS, EmptyState, ErrorBox, EventKindGlyph, EventStream, FILL, FLEET_LIST_GC_TIME_MS, FLEET_LIST_QUERY_KEY, FLEET_LIST_STALE_TIME_MS, FanHeroCard, FanInlineControl, FanPanel, FilterBar, FloatingEventStream, FloatingLogStream, FloatingPanel, FormField$1 as FormField, GRID_GAP, GRID_PAIRED, GRID_QUICK_STATS, GripTrack, GroupedModelSelector, HOST_WIDGETS, HlsVideo, HoverZoomImage, HumidifierHeroCard, HumidifierInlineControl, INPUT_COMPACT, IconAction, IconButton, ImageHeroCard, ImageInlineControl, ImageSelector, InferenceConfigSelector, Input, KebabMenu, KeyValueList, LIST_ROW, Label, LawnMowerHeroCard, LawnMowerInlineControl, LightHeroCard, LightInlineControl, LockHeroCard, LockInlineControl, LockPanel, LogStream, LoginForm, MODE_COLOR, MaskShapeCanvas, MediaPlayerHeroCard, MediaPlayerInlineControl, MediaPlayerPanel, MobileDrawer, ModelPicker, MotionZonesSettings, NAVIGATION_DRIVE_INTERVAL_MS, NavigationPanel, NetworkLinkBadge, NodeMultiSelectField, NodePicker, NodeSelectField, OfflineBadge, PHASE_CONFIG, PRIORITY, PTZOverlay, PageHeader, PhaseIcon, PipelineBuilder, PipelineRuntimeSelector, PipelineStep, PipelineTreeMatrix, PlayerOverlaysProvider, Popover, PopoverContent, PopoverRowAction, PopoverTrigger, PrimaryChildPicker, PrivacyMaskSettings, ProviderBadge, PtzPanel, QrCode, RECONNECT_POLICY, RECORDED_PLAYBACK_MODES, RIGHT, ROI_AREA_WARN_FRACTION, ROLE_DESCRIPTOR, RadialGauge, RecordedPlaybackProvider, RecordingPanel, ResponseLog, SCENE_CAPTURE_VARIANTS, SECTION_BODY, SECTION_CARD, SECTION_HEADER, SETTING_ROW, SETTING_ROW_LABEL, SETTING_ROW_STACK_BREAKPOINT, SETTING_ROW_VALUE, SETTING_ROW_VALUE_TEXT, SNAPSHOT_MEDIA_PATH, SPLIT_PANEL_OUTER, SPLIT_PANEL_SIDE, STACK_GAP, STATE_COLOR, SceneMonitorEditor, ScopePicker, ScriptHeroCard, ScriptInlineControl, ScrollArea, Select, SemanticBadge, SensorHeroCard, SensorInlineControl, SensorValueAtom, Separator, SettingRow, Sidebar, SidebarItem, Skeleton, SlideOverPanel, SlideToggle, SnapshotButton, SortHeaderButton, StatCard, StateValuesStream, StatusBadge, StepTimings, StepTreeMaster, Stepper, StreamBrokerSelector, StreamDebugOverlay, StreamPanel, Switch, SwitchHeroCard, SwitchInlineControl, SwitchPanel, SystemProvider, TABLE_SCROLL_MAX_H, TEXT_FIELD_LABEL, TEXT_HINT, TEXT_METRIC, TEXT_SECTION_LABEL, TEXT_VALUE, TIMEZONES, Tabs, TabsContent, TabsList, TabsTrigger, TapToggle, ThemeProvider, ThermostatHeroCard, ThermostatInlineControl, TimezoneSelector, Tooltip, TooltipContent, TooltipTrigger, VacuumHeroCard, VacuumInlineControl, ValueReadout, ValveHeroCard, ValveInlineControl, VersionBadge, VodPlaybackProvider, WaterHeaterHeroCard, WaterHeaterInlineControl, WeatherHeroCard, WeatherInlineControl, WidgetMetricCard, WidgetPanel, WidgetRegistryProvider, WidgetSlot, ZoneEditingProvider, ImageOff as a, agentColumnKey, allDeviceTypeFilterOptions, applyFleetQueryDefaults, ariaSortForColumn, badgeFor, buildStepTreeFromSchema, Camera as c, childEntityId, childListName, classifyCapability, cn, columnsForContext, containerChildToRef, countableDevices, coverHighlight, coverageLine, createSharedContext, createTheme, cursorFractionFor, darkColors, defaultTheme, deriveDeviceKind, deriveWebrtcDebugStats, describeDeviceSelector, deviceMatchesFilter, deviceOptionLabel, deviceRoleMeta, deviceRoleMetaOf, deviceTypeLabel, deviceTypeMeta, deviceTypeMetaOf, devicesToOptions, ensureMfHostInit, eventKindLabel, filterDeviceOptions, findTimezone, formatControlDateTime, formatLastSeen, formatNumeric, freezeVerdict, fuzzyMatch, getClassColor, getPhaseVisual, groupAgentColumns, groupChildrenByLayout, hardwareLabel, hubOrigin, hubPath, hubUrl, hubWsUrl, humanDuration, humidifierTint, Mic as i, initialScrubState, isAbsentProvider, isFieldVisible, createLucideIcon as l, lawnMowerActivityMeta, lightColors, loadRemoteBundle, makeScrubBridge, metadataEntries, metadataString, mirror, mountAddonPage, mountPath, Square as n, nextReconnectAction, nextSort, nextSortDirection, nextTableSort, normalizeForSearch, Grid2x2 as o, openTopLayer, overrideEntityIdFromLink, parseRecordedServerMessage, providerIcons, RotateCcw as r, resetHubMountForTests, resolveContainerPrimary, resolveControlAlign, resolveDeviceControl, resolveDisplayIcon, resolveEffectiveDefaultModel, resolveEffectiveStepModel, resolveEventKindIcon, resolvePrimaryChild, resolveSensorDisplay, resolveStepDefaultModel, resolveTableLayout, roiTooLarge, routerBasename, EyeOff as s, scrubReducer, selectedDeviceOptions, serializeRecordedCommand, shouldCommit, shouldEmit, shouldUseSingleNode, sortRows, sortRowsByColumn, statusIcons, statusLine, stepHasModelForFormat, stepModelOptions, stripParentNamePrefix, Trash2 as t, tabForSelector, tankAlert, themeToCss, toStationaryOverlayBox, trpc, useAccessoriesGetStatus, useAccessoriesSetChildHidden, useAddonPagesListPages, useAddonSettingsGetDeviceSettings, useAddonSettingsGetGlobalSettings, useAddonSettingsGetIntegrationSettings, useAddonSettingsUpdateDeviceSettings, useAddonSettingsUpdateGlobalSettings, useAddonWidgetsListWidgets, useAddonsApplyAutoUpdateToAll, useAddonsCancelJob, useAddonsCustom, useAddonsForceRefresh, useAddonsGetAddonAutoUpdate, useAddonsGetAutoUpdateSettings, useAddonsGetJob, useAddonsGetLastRestart, useAddonsGetLogs, useAddonsGetVersions, useAddonsInstallFromWorkspace, useAddonsInstallPackage, useAddonsIsWorkspaceAvailable, useAddonsList, useAddonsListCapabilityProviders, useAddonsListFrameworkPackages, useAddonsListJobs, useAddonsListPackages, useAddonsListUpdates, useAddonsListWorkspacePackages, useAddonsOnAddonLogs, useAddonsReloadPackages, useAddonsRestartAddon, useAddonsRestartServer, useAddonsRetryLoad, useAddonsRollbackPackage, useAddonsSearchAvailable, useAddonsSetAddonAutoUpdate, useAddonsSetAutoUpdateSettings, useAddonsSetCapabilityProviderEnabled, useAddonsStartJob, useAddonsUninstallPackage, useAddonsUpdatePackage, useAirQualitySensorGetStatus, useAlarmPanelArm, useAlarmPanelDisarm, useAlarmPanelGetStatus, useAlarmPanelTrigger, useAlert, useAlertsDismiss, useAlertsEmit, useAlertsGetUnreadCount, useAlertsList, useAlertsMarkAllRead, useAlertsMarkRead, useAlertsUpdate, useAllWidgets, useAmbientLightSensorGetStatus, useAudioAnalysisApplyDeviceSettingsPatch, useAudioAnalysisGetDeviceLiveContribution, useAudioAnalysisGetDeviceSettingsContribution, useAudioAnalysisResolveDeviceSettings, useAudioAnalyzerAnalyseChunk, useAudioAnalyzerAttachDevice, useAudioAnalyzerClassify, useAudioAnalyzerDetachDevice, useAudioAnalyzerDispose, useAudioAnalyzerIsReady, useAudioAnalyzerReprobeAudioEngine, useAudioCodecCanHandle, useAudioCodecCloseSession, useAudioCodecCreateDecodeSession, useAudioCodecCreateEncodeSession, useAudioCodecFlushEncode, useAudioCodecListActiveSessions, useAudioCodecListSupportedCodecs, useAudioCodecPullEncoded, useAudioCodecPullPcm, useAudioCodecPushEncodedFrame, useAudioCodecPushPcm, useAudioMetricsGetCurrentSnapshot, useAudioMetricsGetHistory, useAutomationControlDisable, useAutomationControlEnable, useAutomationControlGetStatus, useAutomationControlTrigger, useBackupCancel, useBackupDelete, useBackupDeleteSchedule, useBackupGetEntries, useBackupList, useBackupListArchives, useBackupListDestinations, useBackupListLocations, useBackupListRuns, useBackupListSchedules, useBackupPreviewSchedule, useBackupRestore, useBackupTrigger, useBackupUpsertDestinationPolicy, useBackupUpsertSchedule, useBatteryGetStatus, useBatteryWakeForStream, useBinaryGetStatus, useBrightnessGetStatus, useBrightnessSetBrightness, useBrokerAdd, useBrokerGet, useBrokerGetBrokerConfig, useBrokerGetSettings, useBrokerGetSettingsSchema, useBrokerGetState, useBrokerGetStatus, useBrokerList, useBrokerListProviders, useBrokerPublish, useBrokerRemove, useBrokerSetSettings, useBrokerSubscribe, useBrokerTestConnection, useBrokerTestSettings, useBrokerUnsubscribe, useButtonPress, useCameraCredentialsGetCredentials, useCameraCredentialsGetStatus, useCameraGridLayoutApplyDeviceSettingsPatch, useCameraGridLayoutGetDeviceLiveContribution, useCameraGridLayoutGetDeviceSettingsContribution, useCameraGridLayoutGetLayout, useCameraGridLayoutSaveLayout, useCameraPipelineConfigApplyDeviceSettingsPatch, useCameraPipelineConfigGetDeviceLiveContribution, useCameraPipelineConfigGetDeviceSettingsContribution, useCameraStreamsGetBrokerStreams, useCameraStreamsGetCameraStreams, useCameraStreamsGetProfileRtspEntries, useCameraStreamsGetRtspEntries, useCameraStreamsPickStream, useCapabilityPresence, useCarbonMonoxideGetStatus, useClimateControlGetStatus, useClimateControlSetFanMode, useClimateControlSetMode, useClimateControlSetPreset, useClimateControlSetSwingHorizontal, useClimateControlSetSwingVertical, useClimateControlSetTarget, useClimateControlSetTargetHumidity, useClimateControlSetTargetRange, useClusterNodes, useClusterTopology, useColorGetStatus, useColorSetColor, useConfirm, useConnectionTestDescribeTest, useConnectionTestTestSettings, useConnectivityGetStatus, useConsumablesGetStatus, useConsumablesReset, useContactGetStatus, useContainerChildren, useControlGetStatus, useControlSetValue, useCoreBlocksCompile, useCoreBlocksCreate, useCoreBlocksDelete, useCoreBlocksGet, useCoreBlocksGetTypeDefs, useCoreBlocksList, useCoreBlocksRestart, useCoreBlocksSetEnabled, useCoreBlocksUpdate, useCoverClose, useCoverGetStatus, useCoverOpen, useCoverSetPosition, useCoverSetTiltPosition, useCoverStop, useCustomFieldRenderer, useDayNightGetOptions, useDayNightGetStatus, useDayNightSetSettings, useDebouncedString, useDecoderCreateSession, useDecoderDestroySession, useDecoderGetFrame, useDecoderGetInfo, useDecoderGetShmStats, useDecoderGetStats, useDecoderListActiveSessions, useDecoderOpenStream, useDecoderPullFrames, useDecoderPullHandles, useDecoderPushPacket, useDecoderReprobeHwaccel, useDecoderSupportsCodec, useDecoderUpdateConfig, useDetectionPipelineApplyDeviceSettingsPatch, useDetectionPipelineGetDeviceLiveContribution, useDetectionPipelineGetDeviceSettingsContribution, useDevShell, useDevice, useDeviceAdoptionAdopt, useDeviceAdoptionGetCandidate, useDeviceAdoptionGetStatus, useDeviceAdoptionListCandidateFilters, useDeviceAdoptionListCandidates, useDeviceAdoptionRefresh, useDeviceAdoptionRelease, useDeviceAdoptionResync, useDeviceAutotrack, useDeviceBattery, useDeviceCapSlice, useDeviceCapability, useDeviceDetections, useDeviceDiscoveryAdoptDevice, useDeviceDiscoveryGetStatus, useDeviceDiscoveryListDiscovered, useDeviceDiscoveryRefreshDiscovery, useDeviceDiscoveryReleaseDevice, useDeviceExportApplyDeviceSettingsPatch, useDeviceExportExposeDevice, useDeviceExportGetDeviceLiveContribution, useDeviceExportGetDeviceSettingsContribution, useDeviceExportGetStatus, useDeviceExportListExposedDevices, useDeviceExportListSupportedDeviceKinds, useDeviceExportUnexposeDevice, useDeviceId, useDeviceListPageSize, useDeviceManagerAddLocation, useDeviceManagerAdoptDevice, useDeviceManagerAdoptionAdopt, useDeviceManagerAdoptionCancelJob, useDeviceManagerAdoptionListCandidateFilters, useDeviceManagerAdoptionListCandidates, useDeviceManagerAdoptionListJobs, useDeviceManagerAdoptionRefresh, useDeviceManagerAdoptionRelease, useDeviceManagerAdoptionResync, useDeviceManagerAdoptionStartJob, useDeviceManagerAllocateDeviceId, useDeviceManagerApplyDeviceSettingsPatch, useDeviceManagerApplyInitialMeta, useDeviceManagerCreateDevice, useDeviceManagerDisable, useDeviceManagerDiscoverAllProviders, useDeviceManagerDiscoverDevices, useDeviceManagerDiscoverProvider, useDeviceManagerDiscoveryProviders, useDeviceManagerEnable, useDeviceManagerGetAllBindings, useDeviceManagerGetBindings, useDeviceManagerGetBindingsBatch, useDeviceManagerGetChildren, useDeviceManagerGetChildrenBatch, useDeviceManagerGetConfigSchema, useDeviceManagerGetCreationSchema, useDeviceManagerGetDevice, useDeviceManagerGetDeviceAggregate, useDeviceManagerGetDeviceLiveContribution, useDeviceManagerGetDeviceLiveInfoAggregate, useDeviceManagerGetDeviceSettingsAggregate, useDeviceManagerGetDeviceSettingsContribution, useDeviceManagerGetDeviceStatusAggregate, useDeviceManagerGetDeviceStatusAggregateBatch, useDeviceManagerGetLinkedDevices, useDeviceManagerGetLinkedDevicesBatch, useDeviceManagerGetRoleDisplayDefaults, useDeviceManagerGetSettingsSchema, useDeviceManagerGetStreamProfileMap, useDeviceManagerGetStreamSources, useDeviceManagerGetWireableFields, useDeviceManagerListAll, useDeviceManagerListBindableCapsForDeviceType, useDeviceManagerListLocationDescriptions, useDeviceManagerListLocationIcons, useDeviceManagerListLocations, useDeviceManagerListPersistedByAddon, useDeviceManagerListSiteZones, useDeviceManagerListWrappersForCap, useDeviceManagerLoadConfig, useDeviceManagerLoadMeta, useDeviceManagerLoadRuntimeState, useDeviceManagerMigrateDevice, useDeviceManagerPersistConfig, useDeviceManagerProbeStreams, useDeviceManagerProviderCreationType, useDeviceManagerProviderDiscoveryParamsSchema, useDeviceManagerRegisterDevice, useDeviceManagerRemove, useDeviceManagerRemoveByIntegration, useDeviceManagerRemoveDevice, useDeviceManagerRemoveLocation, useDeviceManagerRemoveSiteZone, useDeviceManagerRenameLocation, useDeviceManagerRenameSiteZone, useDeviceManagerRunDeviceAction, useDeviceManagerSetChildLayout, useDeviceManagerSetDisabled, useDeviceManagerSetDisplay, useDeviceManagerSetIntegrationId, useDeviceManagerSetLinkDeviceId, useDeviceManagerSetLocation, useDeviceManagerSetLocationDescription, useDeviceManagerSetLocationIcon, useDeviceManagerSetLocationZone, useDeviceManagerSetMetadata, useDeviceManagerSetName, useDeviceManagerSetPrimaryChildEntityId, useDeviceManagerSetRole, useDeviceManagerSetRoleDisplayDefaults, useDeviceManagerSetSiteZone, useDeviceManagerSetStreamProfileMap, useDeviceManagerSetType, useDeviceManagerSetWrapperActive, useDeviceManagerTestCreationField, useDeviceManagerTestField, useDeviceManagerUpdateConfig, useDeviceManagerUpdateDeviceField, useDeviceManagerUpdateDeviceFieldsBatch, useDeviceNetworkLink, useDeviceOpsGetConfigEntries, useDeviceOpsGetRawState, useDeviceOpsGetSettingsSchema, useDeviceOpsGetStreamSources, useDeviceOpsRemoveDevice, useDeviceOpsRunAction, useDeviceOpsSetConfig, useDeviceProviderAdoptDiscoveredDevice, useDeviceProviderCreateDevice, useDeviceProviderDiscoverDevices, useDeviceProviderGetChildCreationSchema, useDeviceProviderGetDevices, useDeviceProviderGetDiscoveryParamsSchema, useDeviceProviderGetManualCreationType, useDeviceProviderGetStatus, useDeviceProviderReloadDevice, useDeviceProviderStart, useDeviceProviderStop, useDeviceProviderSupportsDiscovery, useDeviceProviderSupportsManualCreation, useDeviceProviderTestCreationField, useDeviceProxy, useDeviceSnapshot, useDeviceSnapshotImage, useDeviceState, useDeviceStateGetAllSnapshots, useDeviceStateGetCapSlice, useDeviceStateGetSnapshot, useDeviceStateSetCapSlice, useDeviceStateSlice, useDeviceStatusGetStatus, useDeviceWebrtc, useDevices, useDoorbellApplyDeviceSettingsPatch, useDoorbellEvents, useDoorbellGetDeviceLiveContribution, useDoorbellGetDeviceSettingsContribution, useDoorbellGetStatus, useEnumSensorGetStatus, useEventEmitterGetStatus, useEventInvalidation, useEventStreamLatest, useEventStreamMap, useEventsGetEventClipUrl, useEventsGetEventThumbnail, useEventsGetEvents, useFaceGalleryAssignFace, useFaceGalleryAssignFaces, useFaceGalleryAuditIdentitySamples, useFaceGalleryCreateIdentity, useFaceGalleryDeleteFace, useFaceGalleryDeleteIdentity, useFaceGalleryGetFaceByTrack, useFaceGalleryGetFaceMedia, useFaceGalleryListIdentities, useFaceGalleryListIdentitySamples, useFaceGalleryListRecentFaces, useFaceGalleryRemoveSample, useFaceGalleryRenameIdentity, useFaceGallerySuggestFaceClusters, useFaceGalleryUnassignFace, useFaceGalleryUnassignFaces, useFanControlGetStatus, useFanControlSetDirection, useFanControlSetOscillating, useFanControlSetPercentage, useFanControlSetPreset, useFeatureProbeGetStatus, useFloodGetStatus, useGasGetStatus, useHumidifierGetStatus, useHumidifierSetMode, useHumidifierSetOn, useHumidifierSetTargetHumidity, useHumiditySensorGetStatus, useImageGetStatus, useImageSettingsGetOptions, useImageSettingsGetStatus, useImageSettingsSetSettings, useIntegrationsCreate, useIntegrationsDelete, useIntegrationsGet, useIntegrationsGetAvailableTypes, useIntegrationsGetByAddonId, useIntegrationsGetSettings, useIntegrationsList, useIntegrationsSetSettings, useIntegrationsTestConnection, useIntegrationsUpdate, useIntercomEndTalkSession, useIntercomGetStatus, useIntercomHandleAnswer, useIntercomPushTalkAudio, useIntercomStartSession, useIntercomStartTalkSession, useIntercomStopSession, useIsMidWidth, useIsMobile, useLawnMowerControlDock, useLawnMowerControlGetStatus, useLawnMowerControlPause, useLawnMowerControlStartMowing, useLiveBuffer, useLiveEvent, useLlmCancel, useLlmDeleteModel, useLlmDeleteProfile, useLlmGenerate, useLlmGenerateVision, useLlmGetDefaults, useLlmGetRuntimeStatus, useLlmGetUsage, useLlmInstallModel, useLlmListModelCatalog, useLlmListModels, useLlmListNodeModels, useLlmListProfileKinds, useLlmListProfiles, useLlmListRuntimeNodes, useLlmResolveModelRef, useLlmSetDefault, useLlmStartRuntime, useLlmStopRuntime, useLlmTestProfile, useLlmUpsertProfile, useLocalNetworkDownloadCa, useLocalNetworkGetAllowedAddresses, useLocalNetworkGetConnectionEndpoints, useLocalNetworkGetNotificationEndpoint, useLocalNetworkGetPreferred, useLocalNetworkGetTlsStatus, useLocalNetworkGetViewerEndpoints, useLocalNetworkList, useLocalNetworkRegenerateCertificate, useLocalNetworkResetAllowlistToBestMatch, useLocalNetworkRevertToGeneratedCertificate, useLocalNetworkSetAllowedAddresses, useLocalNetworkSetNotificationEndpoint, useLocalNetworkSetViewerEndpoints, useLocalNetworkUploadCertificate, useLockControlGetStatus, useLockControlLock, useLockControlOpen, useLockControlUnlock, useMediaPlayerGetStatus, useMediaPlayerNext, useMediaPlayerPause, useMediaPlayerPlay, useMediaPlayerPlayMedia, useMediaPlayerPrevious, useMediaPlayerSeek, useMediaPlayerSelectSource, useMediaPlayerSetMute, useMediaPlayerSetRepeat, useMediaPlayerSetShuffle, useMediaPlayerSetVolume, useMediaPlayerStop, useMeshNetworkGetStatus, useMeshNetworkJoin, useMeshNetworkLeave, useMeshNetworkListPeers, useMeshNetworkLogout, useMeshNetworkStartLogin, useMeshNetworkTestConnection, useMetricsProviderCollectSnapshot, useMetricsProviderGetAddonStats, useMetricsProviderGetCached, useMetricsProviderGetCpuTemperature, useMetricsProviderGetCurrent, useMetricsProviderGetDiskSpace, useMetricsProviderGetGpuInfo, useMetricsProviderGetLoadSeries, useMetricsProviderGetProcessStats, useMetricsProviderListAddonInstances, useMetricsProviderListNodeProcesses, useMotionDetectionAnalyze, useMotionDetectionApplyDeviceSettingsPatch, useMotionDetectionGetDeviceLiveContribution, useMotionDetectionGetDeviceSettingsContribution, useMotionDetectionRemoveCamera, useMotionDetectionReset, useMotionGetStatus, useMotionIsDetected, useMotionTriggerGetStatus, useMotionTriggerSetMotionTrigger, useMotionZonesGetOptions, useMotionZonesGetStatus, useMotionZonesSetZone, useMqttBrokerAddBroker, useMqttBrokerGetBrokerConfig, useMqttBrokerGetStatus, useMqttBrokerListBrokers, useMqttBrokerRemoveBroker, useMqttBrokerStartEmbeddedBroker, useMqttBrokerStopEmbeddedBroker, useMqttBrokerTestConnection, useNativeObjectDetectionGetOptions, useNativeObjectDetectionGetStatus, useNativeObjectDetectionSetEnabled, useNativeObjectDetectionSetSettings, useNavigation, useNavigationGetFeatures, useNavigationGetStatus, useNavigationGoToPoint, useNavigationListActions, useNavigationMove, useNavigationPlaySound, useNavigationRunAction, useNavigationSetLightLevel, useNavigationSetLightMode, useNavigationSetLightOn, useNavigationStop, useNetworkAccessGetEndpoint, useNetworkAccessGetStatus, useNetworkAccessListEndpoints, useNetworkAccessStart, useNetworkAccessStop, useNetworkLinkGetStatus, useNetworkQualityGetAllStats, useNetworkQualityGetDeviceStats, useNetworkQualityReportClientStats, useNodesClusterAddonStatus, useNodesDeployAddon, useNodesExecuteQuery, useNodesGetCapUsageGraph, useNodesGetNodeAddons, useNodesRenameNode, useNodesRestartAddon, useNodesRestartNode, useNodesRestartProcess, useNodesSetProcessLogLevel, useNodesShutdownNode, useNodesTopology, useNodesUndeployAddon, useNotificationOutputDeleteTarget, useNotificationOutputDiscoverTargets, useNotificationOutputListTargetKinds, useNotificationOutputListTargets, useNotificationOutputSend, useNotificationOutputSetTargetEnabled, useNotificationOutputTestTarget, useNotificationOutputUpsertTarget, useNotificationRulesCancelSnooze, useNotificationRulesCreateRule, useNotificationRulesCreateSnooze, useNotificationRulesDeleteRule, useNotificationRulesGetAlarmConfig, useNotificationRulesGetClipRetentionAsks, useNotificationRulesGetConditionCatalog, useNotificationRulesGetHistory, useNotificationRulesGetRule, useNotificationRulesListDeviceMutes, useNotificationRulesListRules, useNotificationRulesListSnoozes, useNotificationRulesResolveArtifactUrl, useNotificationRulesSetAlarmConfig, useNotificationRulesSetDeviceMuted, useNotificationRulesSetRuleEnabled, useNotificationRulesTestRule, useNotificationRulesUpdateRule, useNotifierCancel, useNotifierGetStatus, useNotifierSend, useNumericSensorGetStatus, useOptimisticSlice, useOptionalSystem, useOptionalWidgetRegistry, useOsdGetStatus, useOsdManagerClearSlotBinding, useOsdManagerCopyDeviceConfiguration, useOsdManagerGetConditionSupport, useOsdManagerGetDeviceOsd, useOsdManagerGetSourceCatalog, useOsdManagerPreviewSlot, useOsdManagerRenderDevice, useOsdManagerSetSlotBinding, useOsdSetOverlay, usePTZ, usePetFeederCallPet, usePetFeederCancelFeed, usePetFeederFeed, usePetFeederGetStatus, usePetFeederMarkFoodReplenished, usePetFeederPlaySound, usePetFeederResetDesiccant, usePetFeederSetChildLock, usePetFeederSetFeedSound, usePetFeederSetIndicatorLight, usePetFeederSetVolume, usePipelineAnalyticsApplyDeviceSettingsPatch, usePipelineAnalyticsCancelRelocateMedia, usePipelineAnalyticsCancelStorageMigrationMove, usePipelineAnalyticsClearTracks, usePipelineAnalyticsCompleteRetrainTrack, usePipelineAnalyticsCountRelocatableMedia, usePipelineAnalyticsCountUnstampedEventMedia, usePipelineAnalyticsDeleteDeviceEvents, usePipelineAnalyticsDeleteTracks, usePipelineAnalyticsDeselectRetrainFrame, usePipelineAnalyticsGetActiveTracks, usePipelineAnalyticsGetAudioEvents, usePipelineAnalyticsGetDeviceLiveContribution, usePipelineAnalyticsGetDeviceSettingsContribution, usePipelineAnalyticsGetEventDensity, usePipelineAnalyticsGetEventDensityBatch, usePipelineAnalyticsGetEventMedia, usePipelineAnalyticsGetEventMediaFootprintByKind, usePipelineAnalyticsGetEventStoreFootprint, usePipelineAnalyticsGetKeyEvents, usePipelineAnalyticsGetKeyEventsBatch, usePipelineAnalyticsGetMediaReclaimStatus, usePipelineAnalyticsGetMotionEvents, usePipelineAnalyticsGetObjectEmbeddingRebuildStatus, usePipelineAnalyticsGetObjectEvents, usePipelineAnalyticsGetRetrainExportUrl, usePipelineAnalyticsGetRetrainFrameImage, usePipelineAnalyticsGetSensorEvents, usePipelineAnalyticsGetStorageMigrationMoveStatus, usePipelineAnalyticsGetSummary, usePipelineAnalyticsGetTrack, usePipelineAnalyticsGetTrackMedia, usePipelineAnalyticsGetTrainingExportSummary, usePipelineAnalyticsGetTrainingExportUrl, usePipelineAnalyticsListArchivedDebugNotes, usePipelineAnalyticsListBirthDecisions, usePipelineAnalyticsListEventKinds, usePipelineAnalyticsListEventKindsBatch, usePipelineAnalyticsListEventMedia, usePipelineAnalyticsListOpsLog, usePipelineAnalyticsListRecentSummaries, usePipelineAnalyticsListRecentTracks, usePipelineAnalyticsListRelocateMediaJobs, usePipelineAnalyticsListRetrainAnnotations, usePipelineAnalyticsListRetrainFrames, usePipelineAnalyticsListRetrainStaging, usePipelineAnalyticsListSummaries, usePipelineAnalyticsListTrackMedia, usePipelineAnalyticsListTracks, usePipelineAnalyticsOwnersWithMedia, usePipelineAnalyticsPauseForStorageMigration, usePipelineAnalyticsProposeRetrainAnnotations, usePipelineAnalyticsPruneEvents, usePipelineAnalyticsPruneEventsBefore, usePipelineAnalyticsPruneTracksBefore, usePipelineAnalyticsReadLongTermSeries, usePipelineAnalyticsRebuildObjectEmbeddings, usePipelineAnalyticsReclaimDebugMedia, usePipelineAnalyticsReconcileFromDisk, usePipelineAnalyticsRefreshStorageLocationsForMigration, usePipelineAnalyticsRelocateMedia, usePipelineAnalyticsRestageRetrainTrack, usePipelineAnalyticsResumeForStorageMigration, usePipelineAnalyticsRunReplayFrameProcessor, usePipelineAnalyticsSaveRetrainAnnotations, usePipelineAnalyticsSearchObjectEvents, usePipelineAnalyticsSelectRetrainFrames, usePipelineAnalyticsSetTrackFlags, usePipelineAnalyticsStartStorageMigrationMove, usePipelineAnalyticsWipeAllAnalytics, usePipelineAnalyticsWipeObjectEmbeddings, usePipelineExecutorCacheFrameInPool, usePipelineExecutorClearDeviceOverrides, usePipelineExecutorDeleteModel, usePipelineExecutorDeleteTemplate, usePipelineExecutorDownloadModel, usePipelineExecutorGetAddonModels, usePipelineExecutorGetAudioCapabilities, usePipelineExecutorGetAvailableEngines, usePipelineExecutorGetCapabilities, usePipelineExecutorGetDefaultSteps, usePipelineExecutorGetDetectionConfigSchema, usePipelineExecutorGetEffectiveTuning, usePipelineExecutorGetEngineProvisioning, usePipelineExecutorGetGlobalPipelineConfig, usePipelineExecutorGetGlobalSteps, usePipelineExecutorGetInferenceDeviceHealth, usePipelineExecutorGetOrchestratorConfigSchema, usePipelineExecutorGetReferenceAudio, usePipelineExecutorGetReferenceAudioFiles, usePipelineExecutorGetReferenceImage, usePipelineExecutorGetSchema, usePipelineExecutorGetSelectedEngine, usePipelineExecutorGetVideoPipelineSteps, usePipelineExecutorInferCached, usePipelineExecutorKillEngine, usePipelineExecutorListLoadedEngines, usePipelineExecutorListReferenceImages, usePipelineExecutorListTemplates, usePipelineExecutorRearmInferenceDevice, usePipelineExecutorRunAudioTest, usePipelineExecutorRunPipeline, usePipelineExecutorRunPipelineBatch, usePipelineExecutorSaveTemplate, usePipelineExecutorSetVideoPipelineSteps, usePipelineExecutorSpinEngine, usePipelineExecutorUncacheFrame, usePipelineExecutorUpdateTemplate, usePipelineExecutorValidatePipeline, usePipelineOrchestratorApplyDeviceSettingsPatch, usePipelineOrchestratorAssignAudio, usePipelineOrchestratorAssignPipeline, usePipelineOrchestratorDeleteTemplate, usePipelineOrchestratorGetAgentLoad, usePipelineOrchestratorGetAgentSettings, usePipelineOrchestratorGetAudioAssignment, usePipelineOrchestratorGetAudioAssignments, usePipelineOrchestratorGetAudioNodeLoad, usePipelineOrchestratorGetCameraMetrics, usePipelineOrchestratorGetCameraSettings, usePipelineOrchestratorGetCameraStatus, usePipelineOrchestratorGetCameraStatuses, usePipelineOrchestratorGetCameraStepOverrides, usePipelineOrchestratorGetCameraSwitches, usePipelineOrchestratorGetCapabilityBindings, usePipelineOrchestratorGetDeviceLiveContribution, usePipelineOrchestratorGetDeviceSettingsContribution, usePipelineOrchestratorGetGlobalMetrics, usePipelineOrchestratorGetIngestOwner, usePipelineOrchestratorGetNodeInferenceDevices, usePipelineOrchestratorGetPipelineAssignment, usePipelineOrchestratorGetPipelineAssignments, usePipelineOrchestratorGetPipelineDevicePin, usePipelineOrchestratorGetReconcileFromDiskStatus, usePipelineOrchestratorListAgentSettings, usePipelineOrchestratorListTemplates, usePipelineOrchestratorPauseForStorageMigration, usePipelineOrchestratorRebalance, usePipelineOrchestratorReconcileFromDisk, usePipelineOrchestratorRemoveAgentSettings, usePipelineOrchestratorResetNodePipelineDefaults, usePipelineOrchestratorResolvePipeline, usePipelineOrchestratorResumeForStorageMigration, usePipelineOrchestratorSaveTemplate, usePipelineOrchestratorSetAgentCapabilities, usePipelineOrchestratorSetAgentDecodeLimits, usePipelineOrchestratorSetAgentDetectWeight, usePipelineOrchestratorSetAgentInferenceDevices, usePipelineOrchestratorSetAgentMaxCameras, usePipelineOrchestratorSetAgentReachableHost, usePipelineOrchestratorSetCameraPipelineForAgent, usePipelineOrchestratorSetCameraStepOverride, usePipelineOrchestratorSetCameraStepToggle, usePipelineOrchestratorSetCameraSwitch, usePipelineOrchestratorSetCapabilityBinding, usePipelineOrchestratorSetPipelineDevicePin, usePipelineOrchestratorUnassignAudio, usePipelineOrchestratorUnassignPipeline, usePipelineOrchestratorUpdateTemplate, usePipelineRunnerAttachCamera, usePipelineRunnerDetachCamera, usePipelineRunnerGetAllCameraMetrics, usePipelineRunnerGetCameraMetrics, usePipelineRunnerGetLocalCameras, usePipelineRunnerGetLocalLoad, usePipelineRunnerGetLocalMetrics, usePipelineRunnerGetNativeCrop, usePipelineRunnerGetParkedTrackFrame, usePipelineRunnerParkTrackFrame, usePipelineRunnerReleaseParkedTrackFrames, usePipelineRunnerReportMotion, usePipelineRunnerRequestOccupancyBurst, usePipelineRunnerRunDetailSubtree, usePipelineRunnerRunStatelessStep, usePlateGalleryAssignPlate, usePlateGalleryAssignPlates, usePlateGalleryCorrectPlateText, usePlateGalleryCreateVehicle, usePlateGalleryDeletePlate, usePlateGalleryDeleteVehicle, usePlateGalleryGetPlateByTrack, usePlateGalleryGetPlateMedia, usePlateGalleryListPlates, usePlateGalleryListVehicleSamples, usePlateGalleryListVehicles, usePlateGalleryRemoveVehicleSample, usePlateGalleryRenameVehicle, usePlateGallerySearchPlates, usePlateGallerySuggestPlateClusters, usePlateGalleryUnassignPlate, usePlateGalleryUnassignPlates, usePlayerOverlayLayer, usePlayerOverlayLayers, usePlayerToolbarButton, usePlayerToolbarButtons, usePowerMeterGetStatus, usePresenceGetStatus, usePressureSensorGetStatus, usePrivacyMaskGetOptions, usePrivacyMaskGetStatus, usePrivacyMaskSetAudioEnabled, usePrivacyMaskSetMask, usePrompt, usePtzAutotrackGetSettings, usePtzAutotrackGetStatus, usePtzAutotrackSetEnabled, usePtzAutotrackSetSettings, usePtzCaptureHomeHere, usePtzContinuousMove, usePtzDeletePreset, usePtzGetHomePreset, usePtzGetHomeReturn, usePtzGetOptions, usePtzGetPosition, usePtzGetPresets, usePtzGetStatus, usePtzGoHome, usePtzGoToPreset, usePtzMove, usePtzSavePreset, usePtzSetAutofocus, usePtzSetHomePreset, usePtzSetHomeReturn, usePtzStop, useRebootReboot, useRecordedPlayback, useRecordingApplyDeviceSettingsPatch, useRecordingCancelRelocateJob, useRecordingCancelStorageMigrationMove, useRecordingDeleteFootprint, useRecordingExportCancelExport, useRecordingExportCreateExport, useRecordingExportDeleteExport, useRecordingExportGetDownloadUrl, useRecordingExportGetExport, useRecordingExportListExports, useRecordingExportReadExportBytes, useRecordingGetAvailability, useRecordingGetAvailabilityBatch, useRecordingGetDaysWithRecordings, useRecordingGetDaysWithRecordingsBatch, useRecordingGetDeviceConfig, useRecordingGetDeviceLiveContribution, useRecordingGetDeviceSettingsContribution, useRecordingGetPlacement, useRecordingGetPlaybackManifest, useRecordingGetRelocateResidue, useRecordingGetStatus, useRecordingGetStorageMigrationMoveStatus, useRecordingGetStorageUsage, useRecordingListOpsLog, useRecordingListRelocateJobs, useRecordingLocateSegment, useRecordingPauseForStorageMigration, useRecordingPlanStorageRebalance, useRecordingPruneFootage, useRecordingReadGopBytes, useRecordingReadSegmentBytes, useRecordingReadWindowBytes, useRecordingReconcileLedgerAgainstDisk, useRecordingRefreshStorageLocationsForMigration, useRecordingRelocateFootage, useRecordingRenderClip, useRecordingRenderGif, useRecordingRescanStorage, useRecordingResumeForStorageMigration, useRecordingSetDeviceConfig, useRecordingSetDevicePlacement, useRecordingSignalGetStatus, useRecordingStartStorageMigrationMove, useRecordingStartStorageRebalance, useRemoteComponent, useSceneMonitorCaptureReference, useSceneMonitorCreateScene, useSceneMonitorDeleteReference, useSceneMonitorDeleteScene, useSceneMonitorGetStatus, useSceneMonitorListScenes, useSceneMonitorListScenesBatch, useSceneMonitorRecheckNow, useSceneMonitorResetScene, useSceneMonitorUpdateScene, useScriptRunnerGetStatus, useScriptRunnerRun, useScriptRunnerStop, useScrubController, useServerManagementApplyServerUpdate, useServerManagementCheckServerUpdate, useServerManagementGetServerPackageStatus, useServerManagementRestartServer, useServerManagementRollbackServerUpdate, useSettingsStoreAggregate, useSettingsStoreCount, useSettingsStoreDeclareCollection, useSettingsStoreDelete, useSettingsStoreDeleteWhere, useSettingsStoreGet, useSettingsStoreHistogram, useSettingsStoreInsert, useSettingsStoreInsertMany, useSettingsStoreIsEmpty, useSettingsStoreQuery, useSettingsStoreSet, useSettingsStoreUpdate, useSettingsStoreUpdateWhere, useSettingsStoreUpsert, useSmokeGetStatus, useSnapshotApplyDeviceSettingsPatch, useSnapshotGetDebugState, useSnapshotGetDeviceLiveContribution, useSnapshotGetDeviceSettingsContribution, useSnapshotGetSnapshot, useSnapshotGetSnapshotLinks, useSnapshotGetSnapshotOverview, useSnapshotGetStatus, useSnapshotInvalidateCache, useStationaryOverlay, useStorageAbortUpload, useStorageBeginDownload, useStorageBeginUpload, useStorageDelete, useStorageDeleteLocation, useStorageEndDownload, useStorageExists, useStorageFinalizeUpload, useStorageGetAvailableSpace, useStorageList, useStorageListDrainProgress, useStorageListLocationDeclarations, useStorageListLocations, useStorageListProviders, useStorageMigrationCancel, useStorageMigrationCleanupCancel, useStorageMigrationCleanupStart, useStorageMigrationCleanupStatus, useStorageMigrationDrain, useStorageMigrationHistory, useStorageMigrationMovers, useStorageMigrationPlan, useStorageMigrationResidue, useStorageMigrationStart, useStorageMigrationStatus, useStorageRead, useStorageReadChunk, useStorageResolve, useStorageTestConfig, useStorageTestLocation, useStorageUpsertLocation, useStorageWrite, useStorageWriteChunk, useStreamBrokerAcquireEgressTranscode, useStreamBrokerApplyDeviceSettingsPatch, useStreamBrokerAssignProfile, useStreamBrokerFetchEventMedia, useStreamBrokerForgetDeviceHardware, useStreamBrokerGetAllRtspEntries, useStreamBrokerGetBrokerStats, useStreamBrokerGetDeviceAudioMute, useStreamBrokerGetDeviceLiveContribution, useStreamBrokerGetDeviceSettingsContribution, useStreamBrokerGetPreBufferInfo, useStreamBrokerGetRtspEntry, useStreamBrokerGetRtspPort, useStreamBrokerGetStreamUrl, useStreamBrokerGetStreamWithCodec, useStreamBrokerIsRtspEnabled, useStreamBrokerKillClient, useStreamBrokerListAllCameraStreams, useStreamBrokerListAllProfileSlots, useStreamBrokerListClients, useStreamBrokerProbeStream, useStreamBrokerProduceEventMedia, useStreamBrokerPublishCameraStream, useStreamBrokerPullAudioChunks, useStreamBrokerPullFrameHandles, useStreamBrokerRegenerateRtspToken, useStreamBrokerReleaseEgressTranscode, useStreamBrokerReleaseStreamWithCodec, useStreamBrokerRenderPreBufferClip, useStreamBrokerReportStreamSignal, useStreamBrokerRestartProfile, useStreamBrokerRetractCameraStream, useStreamBrokerSetDeviceAudioMute, useStreamBrokerSetPreBufferDuration, useStreamBrokerSetRtspEnabled, useStreamBrokerSubscribeAudioChunks, useStreamBrokerSubscribeFrames, useStreamBrokerUnassignProfile, useStreamBrokerUnsubscribeAudioChunks, useStreamBrokerUnsubscribeFrames, useStreamCatalogGetCatalog, useStreamParamsGetConfigSchema, useStreamParamsGetOptions, useStreamParamsGetStatus, useStreamParamsSetProfile, useStreamSignalsListSignals, useSwitchGetStatus, useSwitchSetState, useSystem, useSystemDetectSiteLocation, useSystemFeatureFlags, useSystemForceRetentionCleanup, useSystemGetFailureContributions, useSystemGetLoadContributions, useSystemGetLoggingSettings, useSystemGetRequestCensus, useSystemGetRetentionConfig, useSystemGetSiteLocation, useSystemHealth, useSystemInfo, useSystemMutation, useSystemNetworkAddresses, useSystemQuery, useSystemSetLoggingSettings, useSystemSetRetentionConfig, useSystemSetSiteLocation, useTamperGetStatus, useTemperatureSensorGetStatus, useTerminalSessionAdoptLegacyMonitor, useTerminalSessionClose, useTerminalSessionCreateInstance, useTerminalSessionDeleteInstance, useTerminalSessionListInstances, useTerminalSessionListLegacyCameras, useTerminalSessionListProfiles, useTerminalSessionListSessions, useTerminalSessionOpenSession, useTerminalSessionPullOutput, useTerminalSessionResize, useTerminalSessionSetInstanceEnabled, useTerminalSessionUpdateInstance, useTerminalSessionWriteInput, useThemeMode, useToastOnToast, useTurnProviderGetTurnServers, useUpdateGetStatus, useUpdateInstallUpdate, useUserManagementConfirmTotp, useUserManagementCreateApiKey, useUserManagementCreateScopedToken, useUserManagementCreateUser, useUserManagementDeleteUser, useUserManagementDisableTotp, useUserManagementGetTotpStatus, useUserManagementListApiKeys, useUserManagementListOauthSessions, useUserManagementListScopedTokens, useUserManagementListUsers, useUserManagementOauthExchangeCode, useUserManagementOauthIssueCode, useUserManagementOauthRefresh, useUserManagementOauthVerifyAccessToken, useUserManagementResetPassword, useUserManagementRevokeApiKey, useUserManagementRevokeOauthSession, useUserManagementRevokeScopedToken, useUserManagementSetUserScopes, useUserManagementSetupTotp, useUserManagementUpdateUser, useUserManagementValidateApiKey, useUserManagementValidateCredentials, useUserManagementValidateScopedToken, useUserManagementVerifyTotp, useVacuumControlGetStatus, useVacuumControlLocate, useVacuumControlPause, useVacuumControlReturnToBase, useVacuumControlSetFanSpeed, useVacuumControlStart, useVacuumControlStop, useValveClose, useValveGetStatus, useValveOpen, useValveSetPosition, useValveStop, useVibrationGetStatus, useVideoclipsGetClipPlayback, useVideoclipsListClips, useVideoclipsListSources, useVideoclipsReadClipBytes, useVodPlayback, useWaterHeaterGetStatus, useWaterHeaterSetAway, useWaterHeaterSetOperationMode, useWaterHeaterSetTargetTemp, useWeatherGetStatus, useWebrtcSessionAddIceCandidate, useWebrtcSessionCloseSession, useWebrtcSessionCreateSession, useWebrtcSessionGetIceCandidates, useWebrtcSessionGetSessionDebug, useWebrtcSessionGetSessionState, useWebrtcSessionHandleAnswer, useWebrtcSessionHandleOffer, useWebrtcSessionHasAdaptiveBitrate, useWebrtcSessionListStreams, useWidget, useWidgetMetadata, useWidgetRegistry, useZoneAnalyticsGetCameraHistory, useZoneAnalyticsGetCurrentSnapshot, useZoneAnalyticsGetCurrentSnapshotBatch, useZoneAnalyticsGetUnzonedHistory, useZoneAnalyticsGetZoneHistory, useZoneEditing, useZoneRulesListRules, useZoneRulesSetRules, useZonesAddZone, useZonesListZones, useZonesRemoveZone, useZonesUpdateZone, vacuumStateMeta, validateScopes, valveStateMeta, variantLabel, waterHeaterPhase, waterHeaterTint, weatherConditionMeta, weatherTint };
|
|
55530
|
+
export { AddonGlobalSettingsForm, AgentStepEditor, AlarmHeroCard, AlarmInlineControl as AlarmPanelInlineControl, AppShell, ArcKnob, AudioClassificationList, AudioLevelWaveform, AudioWaveform, AutomationHeroCard, AutomationInlineControl, AutotrackSection, BTN_COMPACT, BTN_COMPACT_DANGER, BTN_COMPACT_PRIMARY, BTN_COMPACT_WARNING, Badge, BatteryBadge, BottomSheet, Breadcrumb, BrightnessPanel, Button, ButtonControl, ButtonHeroCard, CARD_MODE_MIN_COLUMNS, CENTER, CHIP_ACTIVE, CHIP_BASE, CHIP_INACTIVE, CLASS_COLORS, COLUMN_BREAKPOINT_CLASS, COLUMN_PRIORITY, COMMIT_DEDUPE_TOLERANCE_MS, COMMIT_DEDUPE_WINDOW_MS, CONTROL_CAP_NAMES, CONTROL_FILLS, CameraStreamPlayer, Card, Checkbox, ChildSectionAccordion, ClimatePanel, CodeBlock, CollapsibleCard, ConfigFormBuilder, FormField as ConfigFormField, ConfigSchemaField, ConfirmActionButton, ConfirmDialogProvider, ConsumablesPanel, ContainerChildrenProvider, ContainerPrimaryHero, ControlColumn, ControlHeroCard, ControlInlineControl, ControlPanel, CopyButton, CoverHeroCard, CoverInlineControl, CoverPanel, CustomFieldRenderersProvider, DEFAULT_COLOR, DEVICE_COLUMNS, DEVICE_LIST_PAGE_SIZE_KEY, DEVICE_LIST_PAGE_SIZE_OPTIONS, DEVICE_ROLE_META, DEVICE_TYPE_CONTROL, DEVICE_TYPE_META, DISPLAY_ICON_REGISTRY, DataTable, DataTableFilterBar, DetectionCanvas, DetectionOverlay, DetectionResultTree, DevShell, DeviceActivityPanel, DeviceBatchToolbar, DeviceCard, DeviceContextProvider, DeviceExportPanel, DeviceGrid, DeviceItem, DeviceList, DeviceMultiSelectField, DeviceSelectField, DeviceSelectorPicker, DeviceStepMatrix, Dialog, DialogBody, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, DiscoveryPanel, DoorbellRecentPanel, Dropdown, DropdownContent, DropdownItem, DropdownTrigger, DummyHeroCard, DummyInline, EMPTY_DATA_TABLE_FILTER, EVENT_KIND_ICONS, EmptyState, ErrorBox, EventKindGlyph, EventStream, FILL, FLEET_LIST_GC_TIME_MS, FLEET_LIST_QUERY_KEY, FLEET_LIST_STALE_TIME_MS, FanHeroCard, FanInlineControl, FanPanel, FilterBar, FloatingEventStream, FloatingLogStream, FloatingPanel, FormField$1 as FormField, GRID_GAP, GRID_PAIRED, GRID_QUICK_STATS, GripTrack, GroupedModelSelector, HOST_WIDGETS, HlsVideo, HoverZoomImage, HumidifierHeroCard, HumidifierInlineControl, INPUT_COMPACT, IconAction, IconButton, IconPicker, ImageHeroCard, ImageInlineControl, ImageSelector, InferenceConfigSelector, Input, KebabMenu, KeyValueList, LIST_ROW, Label, LawnMowerHeroCard, LawnMowerInlineControl, LightHeroCard, LightInlineControl, LockHeroCard, LockInlineControl, LockPanel, LogStream, LoginForm, MODE_COLOR, MaskShapeCanvas, MediaPlayerHeroCard, MediaPlayerInlineControl, MediaPlayerPanel, MobileDrawer, ModelPicker, MotionZonesSettings, NAVIGATION_DRIVE_INTERVAL_MS, NavigationPanel, NetworkLinkBadge, NodeMultiSelectField, NodePicker, NodeSelectField, OfflineBadge, PHASE_CONFIG, PRIORITY, PTZOverlay, PageHeader, PhaseIcon, PipelineBuilder, PipelineRuntimeSelector, PipelineStep, PipelineTreeMatrix, PlayerOverlaysProvider, Popover, PopoverContent, PopoverRowAction, PopoverTrigger, PrimaryChildPicker, PrivacyMaskSettings, ProviderBadge, PtzPanel, QrCode, RECONNECT_POLICY, RECORDED_PLAYBACK_MODES, RIGHT, ROI_AREA_WARN_FRACTION, ROLE_DESCRIPTOR, RadialGauge, RecordedPlaybackProvider, RecordingPanel, ResponseLog, RoleDisplayDefaultsFromServer, RoleDisplayDefaultsProvider, SCENE_CAPTURE_VARIANTS, SECTION_BODY, SECTION_CARD, SECTION_HEADER, SETTING_ROW, SETTING_ROW_LABEL, SETTING_ROW_STACK_BREAKPOINT, SETTING_ROW_VALUE, SETTING_ROW_VALUE_TEXT, SNAPSHOT_MEDIA_PATH, SPLIT_PANEL_OUTER, SPLIT_PANEL_SIDE, STACK_GAP, STATE_COLOR, SceneMonitorEditor, ScopePicker, ScriptHeroCard, ScriptInlineControl, ScrollArea, Select, SemanticBadge, SensorHeroCard, SensorInlineControl, SensorValueAtom, Separator, SettingRow, Sidebar, SidebarItem, Skeleton, SlideOverPanel, SlideToggle, SnapshotButton, SortHeaderButton, StatCard, StateValuesStream, StatusBadge, StepTimings, StepTreeMaster, Stepper, StreamBrokerSelector, StreamDebugOverlay, StreamPanel, Switch, SwitchHeroCard, SwitchInlineControl, SwitchPanel, SystemProvider, TABLE_SCROLL_MAX_H, TEXT_FIELD_LABEL, TEXT_HINT, TEXT_METRIC, TEXT_SECTION_LABEL, TEXT_VALUE, TIMEZONES, Tabs, TabsContent, TabsList, TabsTrigger, TapToggle, ThemeProvider, ThermostatHeroCard, ThermostatInlineControl, TimezoneSelector, Tooltip, TooltipContent, TooltipTrigger, VacuumHeroCard, VacuumInlineControl, ValueReadout, ValveHeroCard, ValveInlineControl, VersionBadge, VodPlaybackProvider, WaterHeaterHeroCard, WaterHeaterInlineControl, WeatherHeroCard, WeatherInlineControl, WidgetMetricCard, WidgetPanel, WidgetRegistryProvider, WidgetSlot, ZoneEditingProvider, MicOff as a, agentColumnKey, allDeviceTypeFilterOptions, applyFleetQueryDefaults, ariaSortForColumn, badgeFor, buildStepTreeFromSchema, EyeOff as c, childEntityId, childListName, classifyCapability, cn, columnsForContext, containerChildToRef, countableDevices, coverHighlight, coverageLine, createSharedContext, createTheme, cursorFractionFor, darkColors, dataTableFacets, defaultTheme, deriveDeviceKind, deriveWebrtcDebugStats, describeDeviceSelector, deviceMatchesFilter, deviceOptionLabel, deviceRoleMeta, deviceRoleMetaOf, deviceTypeLabel, deviceTypeMeta, deviceTypeMetaOf, devicesToOptions, ensureMfHostInit, eventKindLabel, filterDataTableRows, filterDeviceOptions, findTimezone, formatControlDateTime, formatLastSeen, formatNumeric, freezeVerdict, fuzzyMatch, getClassColor, getPhaseVisual, groupAgentColumns, groupChildrenByLayout, hardwareLabel, hubOrigin, hubPath, hubUrl, hubWsUrl, humanDuration, humidifierTint, Mic as i, initialScrubState, isAbsentProvider, isDataTableFilterActive, isFieldVisible, Camera as l, lawnMowerActivityMeta, lightColors, loadRemoteBundle, makeScrubBridge, metadataEntries, metadataString, mirror, mountAddonPage, mountPath, Square as n, nextReconnectAction, nextSort, nextSortDirection, nextTableSort, normalizeForSearch, ImageOff as o, openTopLayer, overrideEntityIdFromLink, parseRecordedServerMessage, providerIcons, RotateCcw as r, resetHubMountForTests, resolveContainerPrimary, resolveControlAlign, resolveDeviceControl, resolveDisplayIcon, resolveEffectiveDefaultModel, resolveEffectiveStepModel, resolveEventKindIcon, resolvePrimaryChild, resolveSensorDisplay, resolveStepDefaultModel, resolveTableLayout, roiTooLarge, routerBasename, Grid2x2 as s, scrubReducer, selectedDeviceOptions, serializeRecordedCommand, shouldCommit, shouldEmit, shouldUseSingleNode, sortRows, sortRowsByColumn, statusIcons, statusLine, stepHasModelForFormat, stepModelOptions, stripParentNamePrefix, Trash2 as t, tabForSelector, tankAlert, themeToCss, toStationaryOverlayBox, toggleDataTableFacet, trpc, createLucideIcon as u, useAccessoriesGetStatus, useAccessoriesSetChildHidden, useAddonPagesListPages, useAddonSettingsGetDeviceSettings, useAddonSettingsGetGlobalSettings, useAddonSettingsGetIntegrationSettings, useAddonSettingsUpdateDeviceSettings, useAddonSettingsUpdateGlobalSettings, useAddonWidgetsListWidgets, useAddonsApplyAutoUpdateToAll, useAddonsCancelJob, useAddonsCustom, useAddonsForceRefresh, useAddonsGetAddonAutoUpdate, useAddonsGetAutoUpdateSettings, useAddonsGetJob, useAddonsGetLastRestart, useAddonsGetLogs, useAddonsGetVersions, useAddonsInstallFromWorkspace, useAddonsInstallPackage, useAddonsIsWorkspaceAvailable, useAddonsList, useAddonsListCapabilityProviders, useAddonsListFrameworkPackages, useAddonsListJobs, useAddonsListPackages, useAddonsListUpdates, useAddonsListWorkspacePackages, useAddonsOnAddonLogs, useAddonsReloadPackages, useAddonsRestartAddon, useAddonsRestartServer, useAddonsRetryLoad, useAddonsRollbackPackage, useAddonsSearchAvailable, useAddonsSetAddonAutoUpdate, useAddonsSetAutoUpdateSettings, useAddonsSetCapabilityProviderEnabled, useAddonsStartJob, useAddonsUninstallPackage, useAddonsUpdatePackage, useAirQualitySensorGetStatus, useAlarmPanelArm, useAlarmPanelDisarm, useAlarmPanelGetStatus, useAlarmPanelTrigger, useAlert, useAlertsDismiss, useAlertsEmit, useAlertsGetUnreadCount, useAlertsList, useAlertsMarkAllRead, useAlertsMarkRead, useAlertsUpdate, useAllWidgets, useAmbientLightSensorGetStatus, useAudioAnalysisApplyDeviceSettingsPatch, useAudioAnalysisGetDeviceLiveContribution, useAudioAnalysisGetDeviceSettingsContribution, useAudioAnalysisResolveDeviceSettings, useAudioAnalyzerAnalyseChunk, useAudioAnalyzerAttachDevice, useAudioAnalyzerClassify, useAudioAnalyzerDetachDevice, useAudioAnalyzerDispose, useAudioAnalyzerIsReady, useAudioAnalyzerReprobeAudioEngine, useAudioCodecCanHandle, useAudioCodecCloseSession, useAudioCodecCreateDecodeSession, useAudioCodecCreateEncodeSession, useAudioCodecFlushEncode, useAudioCodecListActiveSessions, useAudioCodecListSupportedCodecs, useAudioCodecPullEncoded, useAudioCodecPullPcm, useAudioCodecPushEncodedFrame, useAudioCodecPushPcm, useAudioMetricsGetCurrentSnapshot, useAudioMetricsGetHistory, useAutomationControlDisable, useAutomationControlEnable, useAutomationControlGetStatus, useAutomationControlTrigger, useBackupCancel, useBackupDelete, useBackupDeleteSchedule, useBackupGetEntries, useBackupList, useBackupListArchives, useBackupListDestinations, useBackupListLocations, useBackupListRuns, useBackupListSchedules, useBackupPreviewSchedule, useBackupRestore, useBackupTrigger, useBackupUpsertDestinationPolicy, useBackupUpsertSchedule, useBatteryGetStatus, useBatteryWakeForStream, useBinaryGetStatus, useBrightnessGetStatus, useBrightnessSetBrightness, useBrokerAdd, useBrokerGet, useBrokerGetBrokerConfig, useBrokerGetSettings, useBrokerGetSettingsSchema, useBrokerGetState, useBrokerGetStatus, useBrokerList, useBrokerListProviders, useBrokerPublish, useBrokerRemove, useBrokerSetSettings, useBrokerSubscribe, useBrokerTestConnection, useBrokerTestSettings, useBrokerUnsubscribe, useButtonPress, useCameraCredentialsGetCredentials, useCameraCredentialsGetStatus, useCameraGridLayoutApplyDeviceSettingsPatch, useCameraGridLayoutGetDeviceLiveContribution, useCameraGridLayoutGetDeviceSettingsContribution, useCameraGridLayoutGetLayout, useCameraGridLayoutSaveLayout, useCameraPipelineConfigApplyDeviceSettingsPatch, useCameraPipelineConfigGetDeviceLiveContribution, useCameraPipelineConfigGetDeviceSettingsContribution, useCameraStreamsGetBrokerStreams, useCameraStreamsGetCameraStreams, useCameraStreamsGetProfileRtspEntries, useCameraStreamsGetRtspEntries, useCameraStreamsPickStream, useCapabilityPresence, useCarbonMonoxideGetStatus, useClimateControlGetStatus, useClimateControlSetFanMode, useClimateControlSetMode, useClimateControlSetPreset, useClimateControlSetSwingHorizontal, useClimateControlSetSwingVertical, useClimateControlSetTarget, useClimateControlSetTargetHumidity, useClimateControlSetTargetRange, useClusterNodes, useClusterTopology, useColorGetStatus, useColorSetColor, useConfirm, useConnectionTestDescribeTest, useConnectionTestTestSettings, useConnectivityGetStatus, useConsumablesGetStatus, useConsumablesReset, useContactGetStatus, useContainerChildren, useControlGetStatus, useControlSetValue, useCoreBlocksCompile, useCoreBlocksCreate, useCoreBlocksDelete, useCoreBlocksGet, useCoreBlocksGetTypeDefs, useCoreBlocksList, useCoreBlocksRestart, useCoreBlocksSetEnabled, useCoreBlocksUpdate, useCoverClose, useCoverGetStatus, useCoverOpen, useCoverSetPosition, useCoverSetTiltPosition, useCoverStop, useCustomFieldRenderer, useDataTableFilter, useDayNightGetOptions, useDayNightGetStatus, useDayNightSetSettings, useDebouncedString, useDecoderCreateSession, useDecoderDestroySession, useDecoderGetFrame, useDecoderGetInfo, useDecoderGetShmStats, useDecoderGetStats, useDecoderListActiveSessions, useDecoderOpenStream, useDecoderPullFrames, useDecoderPullHandles, useDecoderPushPacket, useDecoderReprobeHwaccel, useDecoderSupportsCodec, useDecoderUpdateConfig, useDetectionPipelineApplyDeviceSettingsPatch, useDetectionPipelineGetDeviceLiveContribution, useDetectionPipelineGetDeviceSettingsContribution, useDevShell, useDevice, useDeviceAdoptionAdopt, useDeviceAdoptionGetCandidate, useDeviceAdoptionGetStatus, useDeviceAdoptionListCandidateFilters, useDeviceAdoptionListCandidates, useDeviceAdoptionRefresh, useDeviceAdoptionRelease, useDeviceAdoptionResync, useDeviceAutotrack, useDeviceBattery, useDeviceCapSlice, useDeviceCapability, useDeviceDetections, useDeviceDiscoveryAdoptDevice, useDeviceDiscoveryGetStatus, useDeviceDiscoveryListDiscovered, useDeviceDiscoveryRefreshDiscovery, useDeviceDiscoveryReleaseDevice, useDeviceExportApplyDeviceSettingsPatch, useDeviceExportExposeDevice, useDeviceExportGetDeviceLiveContribution, useDeviceExportGetDeviceSettingsContribution, useDeviceExportGetStatus, useDeviceExportListExposedDevices, useDeviceExportListSupportedDeviceKinds, useDeviceExportUnexposeDevice, useDeviceId, useDeviceListPageSize, useDeviceManagerAddLocation, useDeviceManagerAdoptDevice, useDeviceManagerAdoptionAdopt, useDeviceManagerAdoptionCancelJob, useDeviceManagerAdoptionListCandidateFilters, useDeviceManagerAdoptionListCandidates, useDeviceManagerAdoptionListJobs, useDeviceManagerAdoptionRefresh, useDeviceManagerAdoptionRelease, useDeviceManagerAdoptionResync, useDeviceManagerAdoptionStartJob, useDeviceManagerAllocateDeviceId, useDeviceManagerApplyDeviceSettingsPatch, useDeviceManagerApplyInitialMeta, useDeviceManagerCreateDevice, useDeviceManagerDisable, useDeviceManagerDiscoverAllProviders, useDeviceManagerDiscoverDevices, useDeviceManagerDiscoverProvider, useDeviceManagerDiscoveryProviders, useDeviceManagerEnable, useDeviceManagerGetAllBindings, useDeviceManagerGetBindings, useDeviceManagerGetBindingsBatch, useDeviceManagerGetChildren, useDeviceManagerGetChildrenBatch, useDeviceManagerGetConfigSchema, useDeviceManagerGetCreationSchema, useDeviceManagerGetDevice, useDeviceManagerGetDeviceAggregate, useDeviceManagerGetDeviceLiveContribution, useDeviceManagerGetDeviceLiveInfoAggregate, useDeviceManagerGetDeviceSettingsAggregate, useDeviceManagerGetDeviceSettingsContribution, useDeviceManagerGetDeviceStatusAggregate, useDeviceManagerGetDeviceStatusAggregateBatch, useDeviceManagerGetLinkedDevices, useDeviceManagerGetLinkedDevicesBatch, useDeviceManagerGetRoleDisplayDefaults, useDeviceManagerGetSettingsSchema, useDeviceManagerGetStreamProfileMap, useDeviceManagerGetStreamSources, useDeviceManagerGetWireableFields, useDeviceManagerListAll, useDeviceManagerListBindableCapsForDeviceType, useDeviceManagerListLocationDescriptions, useDeviceManagerListLocationIcons, useDeviceManagerListLocations, useDeviceManagerListPersistedByAddon, useDeviceManagerListSiteZones, useDeviceManagerListWrappersForCap, useDeviceManagerLoadConfig, useDeviceManagerLoadMeta, useDeviceManagerLoadRuntimeState, useDeviceManagerMigrateDevice, useDeviceManagerPersistConfig, useDeviceManagerProbeStreams, useDeviceManagerProviderCreationType, useDeviceManagerProviderDiscoveryParamsSchema, useDeviceManagerRegisterDevice, useDeviceManagerRemove, useDeviceManagerRemoveByIntegration, useDeviceManagerRemoveDevice, useDeviceManagerRemoveLocation, useDeviceManagerRemoveSiteZone, useDeviceManagerRenameLocation, useDeviceManagerRenameSiteZone, useDeviceManagerRunDeviceAction, useDeviceManagerSetChildLayout, useDeviceManagerSetDisabled, useDeviceManagerSetDisplay, useDeviceManagerSetIntegrationId, useDeviceManagerSetLinkDeviceId, useDeviceManagerSetLocation, useDeviceManagerSetLocationDescription, useDeviceManagerSetLocationIcon, useDeviceManagerSetLocationZone, useDeviceManagerSetMetadata, useDeviceManagerSetName, useDeviceManagerSetPrimaryChildEntityId, useDeviceManagerSetRole, useDeviceManagerSetRoleDisplayDefaults, useDeviceManagerSetSiteZone, useDeviceManagerSetStreamProfileMap, useDeviceManagerSetType, useDeviceManagerSetWrapperActive, useDeviceManagerTestCreationField, useDeviceManagerTestField, useDeviceManagerUpdateConfig, useDeviceManagerUpdateDeviceField, useDeviceManagerUpdateDeviceFieldsBatch, useDeviceNetworkLink, useDeviceOpsGetConfigEntries, useDeviceOpsGetRawState, useDeviceOpsGetSettingsSchema, useDeviceOpsGetStreamSources, useDeviceOpsRemoveDevice, useDeviceOpsRunAction, useDeviceOpsSetConfig, useDeviceProviderAdoptDiscoveredDevice, useDeviceProviderCreateDevice, useDeviceProviderDiscoverDevices, useDeviceProviderGetChildCreationSchema, useDeviceProviderGetDevices, useDeviceProviderGetDiscoveryParamsSchema, useDeviceProviderGetManualCreationType, useDeviceProviderGetStatus, useDeviceProviderReloadDevice, useDeviceProviderStart, useDeviceProviderStop, useDeviceProviderSupportsDiscovery, useDeviceProviderSupportsManualCreation, useDeviceProviderTestCreationField, useDeviceProxy, useDeviceSnapshot, useDeviceSnapshotImage, useDeviceState, useDeviceStateGetAllSnapshots, useDeviceStateGetCapSlice, useDeviceStateGetSnapshot, useDeviceStateSetCapSlice, useDeviceStateSlice, useDeviceStatusGetStatus, useDeviceWebrtc, useDevices, useDoorbellApplyDeviceSettingsPatch, useDoorbellEvents, useDoorbellGetDeviceLiveContribution, useDoorbellGetDeviceSettingsContribution, useDoorbellGetStatus, useEnumSensorGetStatus, useEventEmitterGetStatus, useEventInvalidation, useEventStreamLatest, useEventStreamMap, useEventsGetEventClipUrl, useEventsGetEventThumbnail, useEventsGetEvents, useFaceGalleryAssignFace, useFaceGalleryAssignFaces, useFaceGalleryAuditIdentitySamples, useFaceGalleryCreateIdentity, useFaceGalleryDeleteFace, useFaceGalleryDeleteIdentity, useFaceGalleryGetFaceByTrack, useFaceGalleryGetFaceMedia, useFaceGalleryListIdentities, useFaceGalleryListIdentitySamples, useFaceGalleryListRecentFaces, useFaceGalleryRemoveSample, useFaceGalleryRenameIdentity, useFaceGallerySuggestFaceClusters, useFaceGalleryUnassignFace, useFaceGalleryUnassignFaces, useFanControlGetStatus, useFanControlSetDirection, useFanControlSetOscillating, useFanControlSetPercentage, useFanControlSetPreset, useFeatureProbeGetStatus, useFloodGetStatus, useGasGetStatus, useHumidifierGetStatus, useHumidifierSetMode, useHumidifierSetOn, useHumidifierSetTargetHumidity, useHumiditySensorGetStatus, useImageGetStatus, useImageSettingsGetOptions, useImageSettingsGetStatus, useImageSettingsSetSettings, useIntegrationsCreate, useIntegrationsDelete, useIntegrationsGet, useIntegrationsGetAvailableTypes, useIntegrationsGetByAddonId, useIntegrationsGetSettings, useIntegrationsList, useIntegrationsSetSettings, useIntegrationsTestConnection, useIntegrationsUpdate, useIntercomEndTalkSession, useIntercomGetStatus, useIntercomHandleAnswer, useIntercomPushTalkAudio, useIntercomStartSession, useIntercomStartTalkSession, useIntercomStopSession, useIsMidWidth, useIsMobile, useLawnMowerControlDock, useLawnMowerControlGetStatus, useLawnMowerControlPause, useLawnMowerControlStartMowing, useLiveBuffer, useLiveEvent, useLlmCancel, useLlmDeleteModel, useLlmDeleteProfile, useLlmGenerate, useLlmGenerateVision, useLlmGetDefaults, useLlmGetRuntimeStatus, useLlmGetUsage, useLlmInstallModel, useLlmListModelCatalog, useLlmListModels, useLlmListNodeModels, useLlmListProfileKinds, useLlmListProfiles, useLlmListRuntimeNodes, useLlmResolveModelRef, useLlmSetDefault, useLlmStartRuntime, useLlmStopRuntime, useLlmTestProfile, useLlmUpsertProfile, useLocalNetworkDownloadCa, useLocalNetworkGetAllowedAddresses, useLocalNetworkGetConnectionEndpoints, useLocalNetworkGetNotificationEndpoint, useLocalNetworkGetPreferred, useLocalNetworkGetTlsStatus, useLocalNetworkGetViewerEndpoints, useLocalNetworkList, useLocalNetworkRegenerateCertificate, useLocalNetworkResetAllowlistToBestMatch, useLocalNetworkRevertToGeneratedCertificate, useLocalNetworkSetAllowedAddresses, useLocalNetworkSetNotificationEndpoint, useLocalNetworkSetViewerEndpoints, useLocalNetworkUploadCertificate, useLockControlGetStatus, useLockControlLock, useLockControlOpen, useLockControlUnlock, useMediaPlayerGetStatus, useMediaPlayerNext, useMediaPlayerPause, useMediaPlayerPlay, useMediaPlayerPlayMedia, useMediaPlayerPrevious, useMediaPlayerSeek, useMediaPlayerSelectSource, useMediaPlayerSetMute, useMediaPlayerSetRepeat, useMediaPlayerSetShuffle, useMediaPlayerSetVolume, useMediaPlayerStop, useMeshNetworkGetStatus, useMeshNetworkJoin, useMeshNetworkLeave, useMeshNetworkListPeers, useMeshNetworkLogout, useMeshNetworkStartLogin, useMeshNetworkTestConnection, useMetricsProviderCollectSnapshot, useMetricsProviderGetAddonStats, useMetricsProviderGetCached, useMetricsProviderGetCpuTemperature, useMetricsProviderGetCurrent, useMetricsProviderGetDiskSpace, useMetricsProviderGetGpuInfo, useMetricsProviderGetLoadSeries, useMetricsProviderGetProcessStats, useMetricsProviderListAddonInstances, useMetricsProviderListNodeProcesses, useMotionDetectionAnalyze, useMotionDetectionApplyDeviceSettingsPatch, useMotionDetectionGetDeviceLiveContribution, useMotionDetectionGetDeviceSettingsContribution, useMotionDetectionRemoveCamera, useMotionDetectionReset, useMotionGetStatus, useMotionIsDetected, useMotionTriggerGetStatus, useMotionTriggerSetMotionTrigger, useMotionZonesGetOptions, useMotionZonesGetStatus, useMotionZonesSetZone, useMqttBrokerAddBroker, useMqttBrokerGetBrokerConfig, useMqttBrokerGetStatus, useMqttBrokerListBrokers, useMqttBrokerRemoveBroker, useMqttBrokerStartEmbeddedBroker, useMqttBrokerStopEmbeddedBroker, useMqttBrokerTestConnection, useNativeObjectDetectionGetOptions, useNativeObjectDetectionGetStatus, useNativeObjectDetectionSetEnabled, useNativeObjectDetectionSetSettings, useNavigation, useNavigationGetFeatures, useNavigationGetStatus, useNavigationGoToPoint, useNavigationListActions, useNavigationMove, useNavigationPlaySound, useNavigationRunAction, useNavigationSetLightLevel, useNavigationSetLightMode, useNavigationSetLightOn, useNavigationStop, useNetworkAccessGetEndpoint, useNetworkAccessGetStatus, useNetworkAccessListEndpoints, useNetworkAccessStart, useNetworkAccessStop, useNetworkLinkGetStatus, useNetworkQualityGetAllStats, useNetworkQualityGetDeviceStats, useNetworkQualityReportClientStats, useNodesClusterAddonStatus, useNodesDeployAddon, useNodesExecuteQuery, useNodesGetCapUsageGraph, useNodesGetNodeAddons, useNodesRenameNode, useNodesRestartAddon, useNodesRestartNode, useNodesRestartProcess, useNodesSetProcessLogLevel, useNodesShutdownNode, useNodesTopology, useNodesUndeployAddon, useNotificationOutputDeleteTarget, useNotificationOutputDiscoverTargets, useNotificationOutputListTargetKinds, useNotificationOutputListTargets, useNotificationOutputSend, useNotificationOutputSetTargetEnabled, useNotificationOutputTestTarget, useNotificationOutputUpsertTarget, useNotificationRulesCancelSnooze, useNotificationRulesCreateRule, useNotificationRulesCreateSnooze, useNotificationRulesDeleteRule, useNotificationRulesGetAlarmConfig, useNotificationRulesGetClipRetentionAsks, useNotificationRulesGetConditionCatalog, useNotificationRulesGetHistory, useNotificationRulesGetRule, useNotificationRulesListDeviceMutes, useNotificationRulesListRules, useNotificationRulesListSnoozes, useNotificationRulesResolveArtifactUrl, useNotificationRulesSetAlarmConfig, useNotificationRulesSetDeviceMuted, useNotificationRulesSetRuleEnabled, useNotificationRulesTestRule, useNotificationRulesUpdateRule, useNotifierCancel, useNotifierGetStatus, useNotifierSend, useNumericSensorGetStatus, useOptimisticSlice, useOptionalSystem, useOptionalWidgetRegistry, useOsdGetStatus, useOsdManagerClearSlotBinding, useOsdManagerCopyDeviceConfiguration, useOsdManagerGetConditionSupport, useOsdManagerGetDeviceOsd, useOsdManagerGetSourceCatalog, useOsdManagerPreviewSlot, useOsdManagerRenderDevice, useOsdManagerSetSlotBinding, useOsdSetOverlay, usePTZ, usePetFeederCallPet, usePetFeederCancelFeed, usePetFeederFeed, usePetFeederGetStatus, usePetFeederMarkFoodReplenished, usePetFeederPlaySound, usePetFeederResetDesiccant, usePetFeederSetChildLock, usePetFeederSetFeedSound, usePetFeederSetIndicatorLight, usePetFeederSetVolume, usePipelineAnalyticsApplyDeviceSettingsPatch, usePipelineAnalyticsCancelRelocateMedia, usePipelineAnalyticsCancelStorageMigrationMove, usePipelineAnalyticsClearTracks, usePipelineAnalyticsCompleteRetrainTrack, usePipelineAnalyticsCountRelocatableMedia, usePipelineAnalyticsCountUnstampedEventMedia, usePipelineAnalyticsDeleteDeviceEvents, usePipelineAnalyticsDeleteTracks, usePipelineAnalyticsDeselectRetrainFrame, usePipelineAnalyticsGetActiveTracks, usePipelineAnalyticsGetAudioEvents, usePipelineAnalyticsGetDeviceLiveContribution, usePipelineAnalyticsGetDeviceSettingsContribution, usePipelineAnalyticsGetEventDensity, usePipelineAnalyticsGetEventDensityBatch, usePipelineAnalyticsGetEventMedia, usePipelineAnalyticsGetEventMediaFootprintByKind, usePipelineAnalyticsGetEventStoreFootprint, usePipelineAnalyticsGetKeyEvents, usePipelineAnalyticsGetKeyEventsBatch, usePipelineAnalyticsGetMediaReclaimStatus, usePipelineAnalyticsGetMotionEvents, usePipelineAnalyticsGetObjectEmbeddingRebuildStatus, usePipelineAnalyticsGetObjectEvents, usePipelineAnalyticsGetRetrainExportUrl, usePipelineAnalyticsGetRetrainFrameImage, usePipelineAnalyticsGetSensorEvents, usePipelineAnalyticsGetStorageMigrationMoveStatus, usePipelineAnalyticsGetSummary, usePipelineAnalyticsGetTrack, usePipelineAnalyticsGetTrackMedia, usePipelineAnalyticsGetTrainingExportSummary, usePipelineAnalyticsGetTrainingExportUrl, usePipelineAnalyticsListArchivedDebugNotes, usePipelineAnalyticsListBirthDecisions, usePipelineAnalyticsListEventKinds, usePipelineAnalyticsListEventKindsBatch, usePipelineAnalyticsListEventMedia, usePipelineAnalyticsListOpsLog, usePipelineAnalyticsListRecentSummaries, usePipelineAnalyticsListRecentTracks, usePipelineAnalyticsListRelocateMediaJobs, usePipelineAnalyticsListRetrainAnnotations, usePipelineAnalyticsListRetrainFrames, usePipelineAnalyticsListRetrainStaging, usePipelineAnalyticsListSummaries, usePipelineAnalyticsListTrackMedia, usePipelineAnalyticsListTracks, usePipelineAnalyticsOwnersWithMedia, usePipelineAnalyticsPauseForStorageMigration, usePipelineAnalyticsProposeRetrainAnnotations, usePipelineAnalyticsPruneEvents, usePipelineAnalyticsPruneEventsBefore, usePipelineAnalyticsPruneTracksBefore, usePipelineAnalyticsReadLongTermSeries, usePipelineAnalyticsRebuildObjectEmbeddings, usePipelineAnalyticsReclaimDebugMedia, usePipelineAnalyticsReconcileFromDisk, usePipelineAnalyticsRefreshStorageLocationsForMigration, usePipelineAnalyticsRelocateMedia, usePipelineAnalyticsRestageRetrainTrack, usePipelineAnalyticsResumeForStorageMigration, usePipelineAnalyticsRunReplayFrameProcessor, usePipelineAnalyticsSaveRetrainAnnotations, usePipelineAnalyticsSearchObjectEvents, usePipelineAnalyticsSelectRetrainFrames, usePipelineAnalyticsSetTrackFlags, usePipelineAnalyticsStartStorageMigrationMove, usePipelineAnalyticsWipeAllAnalytics, usePipelineAnalyticsWipeObjectEmbeddings, usePipelineExecutorCacheFrameInPool, usePipelineExecutorClearDeviceOverrides, usePipelineExecutorDeleteModel, usePipelineExecutorDeleteTemplate, usePipelineExecutorDownloadModel, usePipelineExecutorGetAddonModels, usePipelineExecutorGetAudioCapabilities, usePipelineExecutorGetAvailableEngines, usePipelineExecutorGetCapabilities, usePipelineExecutorGetDefaultSteps, usePipelineExecutorGetDetectionConfigSchema, usePipelineExecutorGetEffectiveTuning, usePipelineExecutorGetEngineProvisioning, usePipelineExecutorGetGlobalPipelineConfig, usePipelineExecutorGetGlobalSteps, usePipelineExecutorGetInferenceDeviceHealth, usePipelineExecutorGetOrchestratorConfigSchema, usePipelineExecutorGetReferenceAudio, usePipelineExecutorGetReferenceAudioFiles, usePipelineExecutorGetReferenceImage, usePipelineExecutorGetSchema, usePipelineExecutorGetSelectedEngine, usePipelineExecutorGetVideoPipelineSteps, usePipelineExecutorInferCached, usePipelineExecutorKillEngine, usePipelineExecutorListLoadedEngines, usePipelineExecutorListReferenceImages, usePipelineExecutorListTemplates, usePipelineExecutorRearmInferenceDevice, usePipelineExecutorRunAudioTest, usePipelineExecutorRunPipeline, usePipelineExecutorRunPipelineBatch, usePipelineExecutorSaveTemplate, usePipelineExecutorSetVideoPipelineSteps, usePipelineExecutorSpinEngine, usePipelineExecutorUncacheFrame, usePipelineExecutorUpdateTemplate, usePipelineExecutorValidatePipeline, usePipelineOrchestratorApplyDeviceSettingsPatch, usePipelineOrchestratorAssignAudio, usePipelineOrchestratorAssignPipeline, usePipelineOrchestratorDeleteTemplate, usePipelineOrchestratorGetAgentLoad, usePipelineOrchestratorGetAgentSettings, usePipelineOrchestratorGetAudioAssignment, usePipelineOrchestratorGetAudioAssignments, usePipelineOrchestratorGetAudioNodeLoad, usePipelineOrchestratorGetCameraMetrics, usePipelineOrchestratorGetCameraSettings, usePipelineOrchestratorGetCameraStatus, usePipelineOrchestratorGetCameraStatuses, usePipelineOrchestratorGetCameraStepOverrides, usePipelineOrchestratorGetCameraSwitches, usePipelineOrchestratorGetCapabilityBindings, usePipelineOrchestratorGetDeviceLiveContribution, usePipelineOrchestratorGetDeviceSettingsContribution, usePipelineOrchestratorGetGlobalMetrics, usePipelineOrchestratorGetIngestOwner, usePipelineOrchestratorGetNodeInferenceDevices, usePipelineOrchestratorGetPipelineAssignment, usePipelineOrchestratorGetPipelineAssignments, usePipelineOrchestratorGetPipelineDevicePin, usePipelineOrchestratorGetReconcileFromDiskStatus, usePipelineOrchestratorListAgentSettings, usePipelineOrchestratorListTemplates, usePipelineOrchestratorPauseForStorageMigration, usePipelineOrchestratorRebalance, usePipelineOrchestratorReconcileFromDisk, usePipelineOrchestratorRemoveAgentSettings, usePipelineOrchestratorResetNodePipelineDefaults, usePipelineOrchestratorResolvePipeline, usePipelineOrchestratorResumeForStorageMigration, usePipelineOrchestratorSaveTemplate, usePipelineOrchestratorSetAgentCapabilities, usePipelineOrchestratorSetAgentDecodeLimits, usePipelineOrchestratorSetAgentDetectWeight, usePipelineOrchestratorSetAgentInferenceDevices, usePipelineOrchestratorSetAgentMaxCameras, usePipelineOrchestratorSetAgentReachableHost, usePipelineOrchestratorSetCameraPipelineForAgent, usePipelineOrchestratorSetCameraStepOverride, usePipelineOrchestratorSetCameraStepToggle, usePipelineOrchestratorSetCameraSwitch, usePipelineOrchestratorSetCapabilityBinding, usePipelineOrchestratorSetPipelineDevicePin, usePipelineOrchestratorUnassignAudio, usePipelineOrchestratorUnassignPipeline, usePipelineOrchestratorUpdateTemplate, usePipelineRunnerAttachCamera, usePipelineRunnerDetachCamera, usePipelineRunnerGetAllCameraMetrics, usePipelineRunnerGetCameraMetrics, usePipelineRunnerGetLocalCameras, usePipelineRunnerGetLocalLoad, usePipelineRunnerGetLocalMetrics, usePipelineRunnerGetNativeCrop, usePipelineRunnerGetParkedTrackFrame, usePipelineRunnerParkTrackFrame, usePipelineRunnerReleaseParkedTrackFrames, usePipelineRunnerReportMotion, usePipelineRunnerRequestOccupancyBurst, usePipelineRunnerRunDetailSubtree, usePipelineRunnerRunStatelessStep, usePlateGalleryAssignPlate, usePlateGalleryAssignPlates, usePlateGalleryCorrectPlateText, usePlateGalleryCreateVehicle, usePlateGalleryDeletePlate, usePlateGalleryDeleteVehicle, usePlateGalleryGetPlateByTrack, usePlateGalleryGetPlateMedia, usePlateGalleryListPlates, usePlateGalleryListVehicleSamples, usePlateGalleryListVehicles, usePlateGalleryRemoveVehicleSample, usePlateGalleryRenameVehicle, usePlateGallerySearchPlates, usePlateGallerySuggestPlateClusters, usePlateGalleryUnassignPlate, usePlateGalleryUnassignPlates, usePlayerOverlayLayer, usePlayerOverlayLayers, usePlayerToolbarButton, usePlayerToolbarButtons, usePowerMeterGetStatus, usePresenceGetStatus, usePressureSensorGetStatus, usePrivacyMaskGetOptions, usePrivacyMaskGetStatus, usePrivacyMaskSetAudioEnabled, usePrivacyMaskSetMask, usePrompt, usePtzAutotrackGetSettings, usePtzAutotrackGetStatus, usePtzAutotrackSetEnabled, usePtzAutotrackSetSettings, usePtzCaptureHomeHere, usePtzContinuousMove, usePtzDeletePreset, usePtzGetHomePreset, usePtzGetHomeReturn, usePtzGetOptions, usePtzGetPosition, usePtzGetPresets, usePtzGetStatus, usePtzGoHome, usePtzGoToPreset, usePtzMove, usePtzSavePreset, usePtzSetAutofocus, usePtzSetHomePreset, usePtzSetHomeReturn, usePtzStop, useRebootReboot, useRecordedPlayback, useRecordingApplyDeviceSettingsPatch, useRecordingCancelRelocateJob, useRecordingCancelStorageMigrationMove, useRecordingDeleteFootprint, useRecordingExportCancelExport, useRecordingExportCreateExport, useRecordingExportDeleteExport, useRecordingExportGetDownloadUrl, useRecordingExportGetExport, useRecordingExportListExports, useRecordingExportReadExportBytes, useRecordingGetAvailability, useRecordingGetAvailabilityBatch, useRecordingGetDaysWithRecordings, useRecordingGetDaysWithRecordingsBatch, useRecordingGetDeviceConfig, useRecordingGetDeviceLiveContribution, useRecordingGetDeviceSettingsContribution, useRecordingGetPlacement, useRecordingGetPlaybackManifest, useRecordingGetRelocateResidue, useRecordingGetStatus, useRecordingGetStorageMigrationMoveStatus, useRecordingGetStorageUsage, useRecordingListOpsLog, useRecordingListRelocateJobs, useRecordingLocateSegment, useRecordingPauseForStorageMigration, useRecordingPlanStorageRebalance, useRecordingPruneFootage, useRecordingReadGopBytes, useRecordingReadSegmentBytes, useRecordingReadWindowBytes, useRecordingReconcileLedgerAgainstDisk, useRecordingRefreshStorageLocationsForMigration, useRecordingRelocateFootage, useRecordingRenderClip, useRecordingRenderGif, useRecordingRescanStorage, useRecordingResumeForStorageMigration, useRecordingSetDeviceConfig, useRecordingSetDevicePlacement, useRecordingSignalGetStatus, useRecordingStartStorageMigrationMove, useRecordingStartStorageRebalance, useRemoteComponent, useRoleDisplayDefaults, useSceneMonitorCaptureReference, useSceneMonitorCreateScene, useSceneMonitorDeleteReference, useSceneMonitorDeleteScene, useSceneMonitorGetStatus, useSceneMonitorListScenes, useSceneMonitorListScenesBatch, useSceneMonitorRecheckNow, useSceneMonitorResetScene, useSceneMonitorUpdateScene, useScriptRunnerGetStatus, useScriptRunnerRun, useScriptRunnerStop, useScrubController, useServerManagementApplyServerUpdate, useServerManagementCheckServerUpdate, useServerManagementGetServerPackageStatus, useServerManagementRestartServer, useServerManagementRollbackServerUpdate, useSettingsStoreAggregate, useSettingsStoreCount, useSettingsStoreDeclareCollection, useSettingsStoreDelete, useSettingsStoreDeleteWhere, useSettingsStoreGet, useSettingsStoreHistogram, useSettingsStoreInsert, useSettingsStoreInsertMany, useSettingsStoreIsEmpty, useSettingsStoreQuery, useSettingsStoreSet, useSettingsStoreUpdate, useSettingsStoreUpdateWhere, useSettingsStoreUpsert, useSmokeGetStatus, useSnapshotApplyDeviceSettingsPatch, useSnapshotGetDebugState, useSnapshotGetDeviceLiveContribution, useSnapshotGetDeviceSettingsContribution, useSnapshotGetSnapshot, useSnapshotGetSnapshotLinks, useSnapshotGetSnapshotOverview, useSnapshotGetStatus, useSnapshotInvalidateCache, useStationaryOverlay, useStorageAbortUpload, useStorageBeginDownload, useStorageBeginUpload, useStorageDelete, useStorageDeleteLocation, useStorageEndDownload, useStorageExists, useStorageFinalizeUpload, useStorageGetAvailableSpace, useStorageList, useStorageListDrainProgress, useStorageListLocationDeclarations, useStorageListLocations, useStorageListProviders, useStorageMigrationCancel, useStorageMigrationCleanupCancel, useStorageMigrationCleanupStart, useStorageMigrationCleanupStatus, useStorageMigrationDrain, useStorageMigrationHistory, useStorageMigrationMovers, useStorageMigrationPlan, useStorageMigrationResidue, useStorageMigrationStart, useStorageMigrationStatus, useStorageRead, useStorageReadChunk, useStorageResolve, useStorageTestConfig, useStorageTestLocation, useStorageUpsertLocation, useStorageWrite, useStorageWriteChunk, useStreamBrokerAcquireEgressTranscode, useStreamBrokerApplyDeviceSettingsPatch, useStreamBrokerAssignProfile, useStreamBrokerFetchEventMedia, useStreamBrokerForgetDeviceHardware, useStreamBrokerGetAllRtspEntries, useStreamBrokerGetBrokerStats, useStreamBrokerGetDeviceAudioMute, useStreamBrokerGetDeviceLiveContribution, useStreamBrokerGetDeviceSettingsContribution, useStreamBrokerGetPreBufferInfo, useStreamBrokerGetRtspEntry, useStreamBrokerGetRtspPort, useStreamBrokerGetStreamUrl, useStreamBrokerGetStreamWithCodec, useStreamBrokerIsRtspEnabled, useStreamBrokerKillClient, useStreamBrokerListAllCameraStreams, useStreamBrokerListAllProfileSlots, useStreamBrokerListClients, useStreamBrokerProbeStream, useStreamBrokerProduceEventMedia, useStreamBrokerPublishCameraStream, useStreamBrokerPullAudioChunks, useStreamBrokerPullFrameHandles, useStreamBrokerRegenerateRtspToken, useStreamBrokerReleaseEgressTranscode, useStreamBrokerReleaseStreamWithCodec, useStreamBrokerRenderPreBufferClip, useStreamBrokerReportStreamSignal, useStreamBrokerRestartProfile, useStreamBrokerRetractCameraStream, useStreamBrokerSetDeviceAudioMute, useStreamBrokerSetPreBufferDuration, useStreamBrokerSetRtspEnabled, useStreamBrokerSubscribeAudioChunks, useStreamBrokerSubscribeFrames, useStreamBrokerUnassignProfile, useStreamBrokerUnsubscribeAudioChunks, useStreamBrokerUnsubscribeFrames, useStreamCatalogGetCatalog, useStreamParamsGetConfigSchema, useStreamParamsGetOptions, useStreamParamsGetStatus, useStreamParamsSetProfile, useStreamSignalsListSignals, useSwitchGetStatus, useSwitchSetState, useSystem, useSystemDetectSiteLocation, useSystemFeatureFlags, useSystemForceRetentionCleanup, useSystemGetFailureContributions, useSystemGetLoadContributions, useSystemGetLoggingSettings, useSystemGetRequestCensus, useSystemGetRetentionConfig, useSystemGetSiteLocation, useSystemHealth, useSystemInfo, useSystemMutation, useSystemNetworkAddresses, useSystemQuery, useSystemSetLoggingSettings, useSystemSetRetentionConfig, useSystemSetSiteLocation, useTamperGetStatus, useTemperatureSensorGetStatus, useTerminalSessionAdoptLegacyMonitor, useTerminalSessionClose, useTerminalSessionCreateInstance, useTerminalSessionDeleteInstance, useTerminalSessionListInstances, useTerminalSessionListLegacyCameras, useTerminalSessionListProfiles, useTerminalSessionListSessions, useTerminalSessionOpenSession, useTerminalSessionPullOutput, useTerminalSessionResize, useTerminalSessionSetInstanceEnabled, useTerminalSessionUpdateInstance, useTerminalSessionWriteInput, useThemeMode, useToastOnToast, useTurnProviderGetTurnServers, useUpdateGetStatus, useUpdateInstallUpdate, useUserManagementConfirmTotp, useUserManagementCreateApiKey, useUserManagementCreateScopedToken, useUserManagementCreateUser, useUserManagementDeleteUser, useUserManagementDisableTotp, useUserManagementGetTotpStatus, useUserManagementListApiKeys, useUserManagementListOauthSessions, useUserManagementListScopedTokens, useUserManagementListUsers, useUserManagementOauthExchangeCode, useUserManagementOauthIssueCode, useUserManagementOauthRefresh, useUserManagementOauthVerifyAccessToken, useUserManagementResetPassword, useUserManagementRevokeApiKey, useUserManagementRevokeOauthSession, useUserManagementRevokeScopedToken, useUserManagementSetUserScopes, useUserManagementSetupTotp, useUserManagementUpdateUser, useUserManagementValidateApiKey, useUserManagementValidateCredentials, useUserManagementValidateScopedToken, useUserManagementVerifyTotp, useVacuumControlGetStatus, useVacuumControlLocate, useVacuumControlPause, useVacuumControlReturnToBase, useVacuumControlSetFanSpeed, useVacuumControlStart, useVacuumControlStop, useValveClose, useValveGetStatus, useValveOpen, useValveSetPosition, useValveStop, useVibrationGetStatus, useVideoclipsDialClipStream, useVideoclipsGetClipPlayback, useVideoclipsListClips, useVideoclipsListSources, useVideoclipsReadClipBytes, useVodPlayback, useWaterHeaterGetStatus, useWaterHeaterSetAway, useWaterHeaterSetOperationMode, useWaterHeaterSetTargetTemp, useWeatherGetStatus, useWebrtcSessionAddIceCandidate, useWebrtcSessionCloseSession, useWebrtcSessionCreateSession, useWebrtcSessionGetIceCandidates, useWebrtcSessionGetSessionDebug, useWebrtcSessionGetSessionState, useWebrtcSessionHandleAnswer, useWebrtcSessionHandleOffer, useWebrtcSessionHasAdaptiveBitrate, useWebrtcSessionListStreams, useWidget, useWidgetMetadata, useWidgetRegistry, useZoneAnalyticsGetCameraHistory, useZoneAnalyticsGetCurrentSnapshot, useZoneAnalyticsGetCurrentSnapshotBatch, useZoneAnalyticsGetUnzonedHistory, useZoneAnalyticsGetZoneHistory, useZoneEditing, useZoneRulesListRules, useZoneRulesSetRules, useZonesAddZone, useZonesListZones, useZonesRemoveZone, useZonesUpdateZone, vacuumStateMeta, validateScopes, valveStateMeta, variantLabel, waterHeaterPhase, waterHeaterTint, weatherConditionMeta, weatherTint };
|