@camstack/ui-library 1.1.41 → 1.1.43

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -8249,6 +8249,30 @@ var ArrowUp = createLucideIcon("arrow-up", [["path", {
8249
8249
  * This source code is licensed under the ISC license.
8250
8250
  * See the LICENSE file in the root directory of this source tree.
8251
8251
  */
8252
+ var Baby = createLucideIcon("baby", [
8253
+ ["path", {
8254
+ d: "M10 16c.5.3 1.2.5 2 .5s1.5-.2 2-.5",
8255
+ key: "1u7htd"
8256
+ }],
8257
+ ["path", {
8258
+ d: "M15 12h.01",
8259
+ key: "1k8ypt"
8260
+ }],
8261
+ ["path", {
8262
+ d: "M19.38 6.813A9 9 0 0 1 20.8 10.2a2 2 0 0 1 0 3.6 9 9 0 0 1-17.6 0 2 2 0 0 1 0-3.6A9 9 0 0 1 12 3c2 0 3.5 1.1 3.5 2.5s-.9 2.5-2 2.5c-.8 0-1.5-.4-1.5-1",
8263
+ key: "11xh7x"
8264
+ }],
8265
+ ["path", {
8266
+ d: "M9 12h.01",
8267
+ key: "157uk2"
8268
+ }]
8269
+ ]);
8270
+ /**
8271
+ * @license lucide-react v0.576.0 - ISC
8272
+ *
8273
+ * This source code is licensed under the ISC license.
8274
+ * See the LICENSE file in the root directory of this source tree.
8275
+ */
8252
8276
  var Ban = createLucideIcon("ban", [["circle", {
8253
8277
  cx: "12",
8254
8278
  cy: "12",
@@ -8458,6 +8482,68 @@ var Bell = createLucideIcon("bell", [["path", {
8458
8482
  * This source code is licensed under the ISC license.
8459
8483
  * See the LICENSE file in the root directory of this source tree.
8460
8484
  */
8485
+ var Bike = createLucideIcon("bike", [
8486
+ ["circle", {
8487
+ cx: "18.5",
8488
+ cy: "17.5",
8489
+ r: "3.5",
8490
+ key: "15x4ox"
8491
+ }],
8492
+ ["circle", {
8493
+ cx: "5.5",
8494
+ cy: "17.5",
8495
+ r: "3.5",
8496
+ key: "1noe27"
8497
+ }],
8498
+ ["circle", {
8499
+ cx: "15",
8500
+ cy: "5",
8501
+ r: "1",
8502
+ key: "19l28e"
8503
+ }],
8504
+ ["path", {
8505
+ d: "M12 17.5V14l-3-3 4-3 2 3h2",
8506
+ key: "1npguv"
8507
+ }]
8508
+ ]);
8509
+ /**
8510
+ * @license lucide-react v0.576.0 - ISC
8511
+ *
8512
+ * This source code is licensed under the ISC license.
8513
+ * See the LICENSE file in the root directory of this source tree.
8514
+ */
8515
+ var Bird = createLucideIcon("bird", [
8516
+ ["path", {
8517
+ d: "M16 7h.01",
8518
+ key: "1kdx03"
8519
+ }],
8520
+ ["path", {
8521
+ d: "M3.4 18H12a8 8 0 0 0 8-8V7a4 4 0 0 0-7.28-2.3L2 20",
8522
+ key: "oj1oa8"
8523
+ }],
8524
+ ["path", {
8525
+ d: "m20 7 2 .5-2 .5",
8526
+ key: "12nv4d"
8527
+ }],
8528
+ ["path", {
8529
+ d: "M10 18v3",
8530
+ key: "1yea0a"
8531
+ }],
8532
+ ["path", {
8533
+ d: "M14 17.75V21",
8534
+ key: "1pymcb"
8535
+ }],
8536
+ ["path", {
8537
+ d: "M7 18a6 6 0 0 0 3.84-10.61",
8538
+ key: "1npnn0"
8539
+ }]
8540
+ ]);
8541
+ /**
8542
+ * @license lucide-react v0.576.0 - ISC
8543
+ *
8544
+ * This source code is licensed under the ISC license.
8545
+ * See the LICENSE file in the root directory of this source tree.
8546
+ */
8461
8547
  var Blinds = createLucideIcon("blinds", [
8462
8548
  ["path", {
8463
8549
  d: "M3 3h18",
@@ -8614,6 +8700,46 @@ var Bug = createLucideIcon("bug", [
8614
8700
  * This source code is licensed under the ISC license.
8615
8701
  * See the LICENSE file in the root directory of this source tree.
8616
8702
  */
8703
+ var Bus = createLucideIcon("bus", [
8704
+ ["path", {
8705
+ d: "M8 6v6",
8706
+ key: "18i7km"
8707
+ }],
8708
+ ["path", {
8709
+ d: "M15 6v6",
8710
+ key: "1sg6z9"
8711
+ }],
8712
+ ["path", {
8713
+ d: "M2 12h19.6",
8714
+ key: "de5uta"
8715
+ }],
8716
+ ["path", {
8717
+ d: "M18 18h3s.5-1.7.8-2.8c.1-.4.2-.8.2-1.2 0-.4-.1-.8-.2-1.2l-1.4-5C20.1 6.8 19.1 6 18 6H4a2 2 0 0 0-2 2v10h3",
8718
+ key: "1wwztk"
8719
+ }],
8720
+ ["circle", {
8721
+ cx: "7",
8722
+ cy: "18",
8723
+ r: "2",
8724
+ key: "19iecd"
8725
+ }],
8726
+ ["path", {
8727
+ d: "M9 18h5",
8728
+ key: "lrx6i"
8729
+ }],
8730
+ ["circle", {
8731
+ cx: "16",
8732
+ cy: "18",
8733
+ r: "2",
8734
+ key: "1v4tcr"
8735
+ }]
8736
+ ]);
8737
+ /**
8738
+ * @license lucide-react v0.576.0 - ISC
8739
+ *
8740
+ * This source code is licensed under the ISC license.
8741
+ * See the LICENSE file in the root directory of this source tree.
8742
+ */
8617
8743
  var Camera = createLucideIcon("camera", [["path", {
8618
8744
  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",
8619
8745
  key: "18u6gg"
@@ -8629,6 +8755,34 @@ var Camera = createLucideIcon("camera", [["path", {
8629
8755
  * This source code is licensed under the ISC license.
8630
8756
  * See the LICENSE file in the root directory of this source tree.
8631
8757
  */
8758
+ var Car = createLucideIcon("car", [
8759
+ ["path", {
8760
+ d: "M19 17h2c.6 0 1-.4 1-1v-3c0-.9-.7-1.7-1.5-1.9C18.7 10.6 16 10 16 10s-1.3-1.4-2.2-2.3c-.5-.4-1.1-.7-1.8-.7H5c-.6 0-1.1.4-1.4.9l-1.4 2.9A3.7 3.7 0 0 0 2 12v4c0 .6.4 1 1 1h2",
8761
+ key: "5owen"
8762
+ }],
8763
+ ["circle", {
8764
+ cx: "7",
8765
+ cy: "17",
8766
+ r: "2",
8767
+ key: "u2ysq9"
8768
+ }],
8769
+ ["path", {
8770
+ d: "M9 17h6",
8771
+ key: "r8uit2"
8772
+ }],
8773
+ ["circle", {
8774
+ cx: "17",
8775
+ cy: "17",
8776
+ r: "2",
8777
+ key: "axvx0g"
8778
+ }]
8779
+ ]);
8780
+ /**
8781
+ * @license lucide-react v0.576.0 - ISC
8782
+ *
8783
+ * This source code is licensed under the ISC license.
8784
+ * See the LICENSE file in the root directory of this source tree.
8785
+ */
8632
8786
  var Cast = createLucideIcon("cast", [
8633
8787
  ["path", {
8634
8788
  d: "M2 8V6a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2h-6",
@@ -8656,6 +8810,30 @@ var Cast = createLucideIcon("cast", [
8656
8810
  * This source code is licensed under the ISC license.
8657
8811
  * See the LICENSE file in the root directory of this source tree.
8658
8812
  */
8813
+ var Cat = createLucideIcon("cat", [
8814
+ ["path", {
8815
+ d: "M12 5c.67 0 1.35.09 2 .26 1.78-2 5.03-2.84 6.42-2.26 1.4.58-.42 7-.42 7 .57 1.07 1 2.24 1 3.44C21 17.9 16.97 21 12 21s-9-3-9-7.56c0-1.25.5-2.4 1-3.44 0 0-1.89-6.42-.5-7 1.39-.58 4.72.23 6.5 2.23A9.04 9.04 0 0 1 12 5Z",
8816
+ key: "x6xyqk"
8817
+ }],
8818
+ ["path", {
8819
+ d: "M8 14v.5",
8820
+ key: "1nzgdb"
8821
+ }],
8822
+ ["path", {
8823
+ d: "M16 14v.5",
8824
+ key: "1lajdz"
8825
+ }],
8826
+ ["path", {
8827
+ d: "M11.25 16.25h1.5L12 17l-.75-.75Z",
8828
+ key: "12kq1m"
8829
+ }]
8830
+ ]);
8831
+ /**
8832
+ * @license lucide-react v0.576.0 - ISC
8833
+ *
8834
+ * This source code is licensed under the ISC license.
8835
+ * See the LICENSE file in the root directory of this source tree.
8836
+ */
8659
8837
  var Check = createLucideIcon("check", [["path", {
8660
8838
  d: "M20 6 9 17l-5-5",
8661
8839
  key: "1gmf2c"
@@ -9049,6 +9227,74 @@ var Cloud = createLucideIcon("cloud", [["path", {
9049
9227
  * This source code is licensed under the ISC license.
9050
9228
  * See the LICENSE file in the root directory of this source tree.
9051
9229
  */
9230
+ var Cog = createLucideIcon("cog", [
9231
+ ["path", {
9232
+ d: "M11 10.27 7 3.34",
9233
+ key: "16pf9h"
9234
+ }],
9235
+ ["path", {
9236
+ d: "m11 13.73-4 6.93",
9237
+ key: "794ttg"
9238
+ }],
9239
+ ["path", {
9240
+ d: "M12 22v-2",
9241
+ key: "1osdcq"
9242
+ }],
9243
+ ["path", {
9244
+ d: "M12 2v2",
9245
+ key: "tus03m"
9246
+ }],
9247
+ ["path", {
9248
+ d: "M14 12h8",
9249
+ key: "4f43i9"
9250
+ }],
9251
+ ["path", {
9252
+ d: "m17 20.66-1-1.73",
9253
+ key: "eq3orb"
9254
+ }],
9255
+ ["path", {
9256
+ d: "m17 3.34-1 1.73",
9257
+ key: "2wel8s"
9258
+ }],
9259
+ ["path", {
9260
+ d: "M2 12h2",
9261
+ key: "1t8f8n"
9262
+ }],
9263
+ ["path", {
9264
+ d: "m20.66 17-1.73-1",
9265
+ key: "sg0v6f"
9266
+ }],
9267
+ ["path", {
9268
+ d: "m20.66 7-1.73 1",
9269
+ key: "1ow05n"
9270
+ }],
9271
+ ["path", {
9272
+ d: "m3.34 17 1.73-1",
9273
+ key: "nuk764"
9274
+ }],
9275
+ ["path", {
9276
+ d: "m3.34 7 1.73 1",
9277
+ key: "1ulond"
9278
+ }],
9279
+ ["circle", {
9280
+ cx: "12",
9281
+ cy: "12",
9282
+ r: "2",
9283
+ key: "1c9p78"
9284
+ }],
9285
+ ["circle", {
9286
+ cx: "12",
9287
+ cy: "12",
9288
+ r: "8",
9289
+ key: "46899m"
9290
+ }]
9291
+ ]);
9292
+ /**
9293
+ * @license lucide-react v0.576.0 - ISC
9294
+ *
9295
+ * This source code is licensed under the ISC license.
9296
+ * See the LICENSE file in the root directory of this source tree.
9297
+ */
9052
9298
  var CopyPlus = createLucideIcon("copy-plus", [
9053
9299
  ["line", {
9054
9300
  x1: "15",
@@ -9239,6 +9485,34 @@ var Database = createLucideIcon("database", [
9239
9485
  * This source code is licensed under the ISC license.
9240
9486
  * See the LICENSE file in the root directory of this source tree.
9241
9487
  */
9488
+ var Dog = createLucideIcon("dog", [
9489
+ ["path", {
9490
+ d: "M11.25 16.25h1.5L12 17z",
9491
+ key: "w7jh35"
9492
+ }],
9493
+ ["path", {
9494
+ d: "M16 14v.5",
9495
+ key: "1lajdz"
9496
+ }],
9497
+ ["path", {
9498
+ d: "M4.42 11.247A13.152 13.152 0 0 0 4 14.556C4 18.728 7.582 21 12 21s8-2.272 8-6.444a11.702 11.702 0 0 0-.493-3.309",
9499
+ key: "u7s9ue"
9500
+ }],
9501
+ ["path", {
9502
+ d: "M8 14v.5",
9503
+ key: "1nzgdb"
9504
+ }],
9505
+ ["path", {
9506
+ d: "M8.5 8.5c-.384 1.05-1.083 2.028-2.344 2.5-1.931.722-3.576-.297-3.656-1-.113-.994 1.177-6.53 4-7 1.923-.321 3.651.845 3.651 2.235A7.497 7.497 0 0 1 14 5.277c0-1.39 1.844-2.598 3.767-2.277 2.823.47 4.113 6.006 4 7-.08.703-1.725 1.722-3.656 1-1.261-.472-1.855-1.45-2.239-2.5",
9507
+ key: "v8hric"
9508
+ }]
9509
+ ]);
9510
+ /**
9511
+ * @license lucide-react v0.576.0 - ISC
9512
+ *
9513
+ * This source code is licensed under the ISC license.
9514
+ * See the LICENSE file in the root directory of this source tree.
9515
+ */
9242
9516
  var DoorClosed = createLucideIcon("door-closed", [
9243
9517
  ["path", {
9244
9518
  d: "M10 12h.01",
@@ -9673,6 +9947,26 @@ var GripHorizontal = createLucideIcon("grip-horizontal", [
9673
9947
  * This source code is licensed under the ISC license.
9674
9948
  * See the LICENSE file in the root directory of this source tree.
9675
9949
  */
9950
+ var Hammer = createLucideIcon("hammer", [
9951
+ ["path", {
9952
+ d: "m15 12-9.373 9.373a1 1 0 0 1-3.001-3L12 9",
9953
+ key: "1hayfq"
9954
+ }],
9955
+ ["path", {
9956
+ d: "m18 15 4-4",
9957
+ key: "16gjal"
9958
+ }],
9959
+ ["path", {
9960
+ d: "m21.5 11.5-1.914-1.914A2 2 0 0 1 19 8.172v-.344a2 2 0 0 0-.586-1.414l-1.657-1.657A6 6 0 0 0 12.516 3H9l1.243 1.243A6 6 0 0 1 12 8.485V10l2 2h1.172a2 2 0 0 1 1.414.586L18.5 14.5",
9961
+ key: "15ts47"
9962
+ }]
9963
+ ]);
9964
+ /**
9965
+ * @license lucide-react v0.576.0 - ISC
9966
+ *
9967
+ * This source code is licensed under the ISC license.
9968
+ * See the LICENSE file in the root directory of this source tree.
9969
+ */
9676
9970
  var HardDrive = createLucideIcon("hard-drive", [
9677
9971
  ["path", {
9678
9972
  d: "M10 16h.01",
@@ -9849,6 +10143,38 @@ var Info = createLucideIcon("info", [
9849
10143
  * This source code is licensed under the ISC license.
9850
10144
  * See the LICENSE file in the root directory of this source tree.
9851
10145
  */
10146
+ var Laugh = createLucideIcon("laugh", [
10147
+ ["circle", {
10148
+ cx: "12",
10149
+ cy: "12",
10150
+ r: "10",
10151
+ key: "1mglay"
10152
+ }],
10153
+ ["path", {
10154
+ d: "M18 13a6 6 0 0 1-6 5 6 6 0 0 1-6-5h12Z",
10155
+ key: "b2q4dd"
10156
+ }],
10157
+ ["line", {
10158
+ x1: "9",
10159
+ x2: "9.01",
10160
+ y1: "9",
10161
+ y2: "9",
10162
+ key: "yxxnd0"
10163
+ }],
10164
+ ["line", {
10165
+ x1: "15",
10166
+ x2: "15.01",
10167
+ y1: "9",
10168
+ y2: "9",
10169
+ key: "1p4y9e"
10170
+ }]
10171
+ ]);
10172
+ /**
10173
+ * @license lucide-react v0.576.0 - ISC
10174
+ *
10175
+ * This source code is licensed under the ISC license.
10176
+ * See the LICENSE file in the root directory of this source tree.
10177
+ */
9852
10178
  var LayoutGrid = createLucideIcon("layout-grid", [
9853
10179
  ["rect", {
9854
10180
  width: "7",
@@ -10452,6 +10778,30 @@ var Network = createLucideIcon("network", [
10452
10778
  * This source code is licensed under the ISC license.
10453
10779
  * See the LICENSE file in the root directory of this source tree.
10454
10780
  */
10781
+ var Package = createLucideIcon("package", [
10782
+ ["path", {
10783
+ d: "M11 21.73a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73z",
10784
+ key: "1a0edw"
10785
+ }],
10786
+ ["path", {
10787
+ d: "M12 22V12",
10788
+ key: "d0xqtd"
10789
+ }],
10790
+ ["polyline", {
10791
+ points: "3.29 7 12 12 20.71 7",
10792
+ key: "ousv84"
10793
+ }],
10794
+ ["path", {
10795
+ d: "m7.5 4.27 9 5.15",
10796
+ key: "1c824w"
10797
+ }]
10798
+ ]);
10799
+ /**
10800
+ * @license lucide-react v0.576.0 - ISC
10801
+ *
10802
+ * This source code is licensed under the ISC license.
10803
+ * See the LICENSE file in the root directory of this source tree.
10804
+ */
10455
10805
  var Pause = createLucideIcon("pause", [["rect", {
10456
10806
  x: "14",
10457
10807
  y: "3",
@@ -10516,6 +10866,16 @@ var Pencil = createLucideIcon("pencil", [["path", {
10516
10866
  * This source code is licensed under the ISC license.
10517
10867
  * See the LICENSE file in the root directory of this source tree.
10518
10868
  */
10869
+ var Phone = createLucideIcon("phone", [["path", {
10870
+ 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",
10871
+ key: "9njp5v"
10872
+ }]]);
10873
+ /**
10874
+ * @license lucide-react v0.576.0 - ISC
10875
+ *
10876
+ * This source code is licensed under the ISC license.
10877
+ * See the LICENSE file in the root directory of this source tree.
10878
+ */
10519
10879
  var Pipette = createLucideIcon("pipette", [
10520
10880
  ["path", {
10521
10881
  d: "m12 9-8.414 8.414A2 2 0 0 0 3 18.828v1.344a2 2 0 0 1-.586 1.414A2 2 0 0 1 3.828 21h1.344a2 2 0 0 0 1.414-.586L15 12",
@@ -10536,6 +10896,16 @@ var Pipette = createLucideIcon("pipette", [
10536
10896
  * This source code is licensed under the ISC license.
10537
10897
  * See the LICENSE file in the root directory of this source tree.
10538
10898
  */
10899
+ var Plane = createLucideIcon("plane", [["path", {
10900
+ d: "M17.8 19.2 16 11l3.5-3.5C21 6 21.5 4 21 3c-1-.5-3 0-4.5 1.5L13 8 4.8 6.2c-.5-.1-.9.1-1.1.5l-.3.5c-.2.5-.1 1 .3 1.3L9 12l-2 3H4l-1 1 3 2 2 3 1-1v-3l3-2 3.5 5.3c.3.4.8.5 1.3.3l.5-.2c.4-.3.6-.7.5-1.2z",
10901
+ key: "1v9wt8"
10902
+ }]]);
10903
+ /**
10904
+ * @license lucide-react v0.576.0 - ISC
10905
+ *
10906
+ * This source code is licensed under the ISC license.
10907
+ * See the LICENSE file in the root directory of this source tree.
10908
+ */
10539
10909
  var Play = createLucideIcon("play", [["path", {
10540
10910
  d: "M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z",
10541
10911
  key: "10ikf1"
@@ -10810,6 +11180,26 @@ var RotateCw = createLucideIcon("rotate-cw", [["path", {
10810
11180
  * This source code is licensed under the ISC license.
10811
11181
  * See the LICENSE file in the root directory of this source tree.
10812
11182
  */
11183
+ var Sailboat = createLucideIcon("sailboat", [
11184
+ ["path", {
11185
+ d: "M10 2v15",
11186
+ key: "1qf71f"
11187
+ }],
11188
+ ["path", {
11189
+ d: "M7 22a4 4 0 0 1-4-4 1 1 0 0 1 1-1h16a1 1 0 0 1 1 1 4 4 0 0 1-4 4z",
11190
+ key: "1pxcvx"
11191
+ }],
11192
+ ["path", {
11193
+ d: "M9.159 2.46a1 1 0 0 1 1.521-.193l9.977 8.98A1 1 0 0 1 20 13H4a1 1 0 0 1-.824-1.567z",
11194
+ key: "5oog16"
11195
+ }]
11196
+ ]);
11197
+ /**
11198
+ * @license lucide-react v0.576.0 - ISC
11199
+ *
11200
+ * This source code is licensed under the ISC license.
11201
+ * See the LICENSE file in the root directory of this source tree.
11202
+ */
10813
11203
  var Save = createLucideIcon("save", [
10814
11204
  ["path", {
10815
11205
  d: "M15.2 3a2 2 0 0 1 1.4.6l3.8 3.8a2 2 0 0 1 .6 1.4V19a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2z",
@@ -11475,6 +11865,22 @@ var Table2 = createLucideIcon("table-2", [["path", {
11475
11865
  * This source code is licensed under the ISC license.
11476
11866
  * See the LICENSE file in the root directory of this source tree.
11477
11867
  */
11868
+ var Tag = createLucideIcon("tag", [["path", {
11869
+ 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",
11870
+ key: "vktsd0"
11871
+ }], ["circle", {
11872
+ cx: "7.5",
11873
+ cy: "7.5",
11874
+ r: ".5",
11875
+ fill: "currentColor",
11876
+ key: "kqv944"
11877
+ }]]);
11878
+ /**
11879
+ * @license lucide-react v0.576.0 - ISC
11880
+ *
11881
+ * This source code is licensed under the ISC license.
11882
+ * See the LICENSE file in the root directory of this source tree.
11883
+ */
11478
11884
  var Target = createLucideIcon("target", [
11479
11885
  ["circle", {
11480
11886
  cx: "12",
@@ -11530,6 +11936,25 @@ var ToggleLeft = createLucideIcon("toggle-left", [["circle", {
11530
11936
  * This source code is licensed under the ISC license.
11531
11937
  * See the LICENSE file in the root directory of this source tree.
11532
11938
  */
11939
+ var ToggleRight = createLucideIcon("toggle-right", [["circle", {
11940
+ cx: "15",
11941
+ cy: "12",
11942
+ r: "3",
11943
+ key: "1afu0r"
11944
+ }], ["rect", {
11945
+ width: "20",
11946
+ height: "14",
11947
+ x: "2",
11948
+ y: "5",
11949
+ rx: "7",
11950
+ key: "g7kal2"
11951
+ }]]);
11952
+ /**
11953
+ * @license lucide-react v0.576.0 - ISC
11954
+ *
11955
+ * This source code is licensed under the ISC license.
11956
+ * See the LICENSE file in the root directory of this source tree.
11957
+ */
11533
11958
  var Tractor = createLucideIcon("tractor", [
11534
11959
  ["path", {
11535
11960
  d: "m10 11 11 .9a1 1 0 0 1 .8 1.1l-.665 4.158a1 1 0 0 1-.988.842H20",
@@ -11578,6 +12003,38 @@ var Tractor = createLucideIcon("tractor", [
11578
12003
  * This source code is licensed under the ISC license.
11579
12004
  * See the LICENSE file in the root directory of this source tree.
11580
12005
  */
12006
+ var TrainFront = createLucideIcon("train-front", [
12007
+ ["path", {
12008
+ d: "M8 3.1V7a4 4 0 0 0 8 0V3.1",
12009
+ key: "1v71zp"
12010
+ }],
12011
+ ["path", {
12012
+ d: "m9 15-1-1",
12013
+ key: "1yrq24"
12014
+ }],
12015
+ ["path", {
12016
+ d: "m15 15 1-1",
12017
+ key: "1t0d6s"
12018
+ }],
12019
+ ["path", {
12020
+ d: "M9 19c-2.8 0-5-2.2-5-5v-4a8 8 0 0 1 16 0v4c0 2.8-2.2 5-5 5Z",
12021
+ key: "1p0hjs"
12022
+ }],
12023
+ ["path", {
12024
+ d: "m8 19-2 3",
12025
+ key: "13i0xs"
12026
+ }],
12027
+ ["path", {
12028
+ d: "m16 19 2 3",
12029
+ key: "xo31yx"
12030
+ }]
12031
+ ]);
12032
+ /**
12033
+ * @license lucide-react v0.576.0 - ISC
12034
+ *
12035
+ * This source code is licensed under the ISC license.
12036
+ * See the LICENSE file in the root directory of this source tree.
12037
+ */
11581
12038
  var Trash2 = createLucideIcon("trash-2", [
11582
12039
  ["path", {
11583
12040
  d: "M10 11v6",
@@ -11652,6 +12109,38 @@ var TriangleAlert = createLucideIcon("triangle-alert", [
11652
12109
  * This source code is licensed under the ISC license.
11653
12110
  * See the LICENSE file in the root directory of this source tree.
11654
12111
  */
12112
+ var Truck = createLucideIcon("truck", [
12113
+ ["path", {
12114
+ d: "M14 18V6a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2v11a1 1 0 0 0 1 1h2",
12115
+ key: "wrbu53"
12116
+ }],
12117
+ ["path", {
12118
+ d: "M15 18H9",
12119
+ key: "1lyqi6"
12120
+ }],
12121
+ ["path", {
12122
+ d: "M19 18h2a1 1 0 0 0 1-1v-3.65a1 1 0 0 0-.22-.624l-3.48-4.35A1 1 0 0 0 17.52 8H14",
12123
+ key: "lysw3i"
12124
+ }],
12125
+ ["circle", {
12126
+ cx: "17",
12127
+ cy: "18",
12128
+ r: "2",
12129
+ key: "332jqn"
12130
+ }],
12131
+ ["circle", {
12132
+ cx: "7",
12133
+ cy: "18",
12134
+ r: "2",
12135
+ key: "19iecd"
12136
+ }]
12137
+ ]);
12138
+ /**
12139
+ * @license lucide-react v0.576.0 - ISC
12140
+ *
12141
+ * This source code is licensed under the ISC license.
12142
+ * See the LICENSE file in the root directory of this source tree.
12143
+ */
11655
12144
  var Type = createLucideIcon("type", [
11656
12145
  ["path", {
11657
12146
  d: "M12 4v16",
@@ -11702,6 +12191,69 @@ var Upload = createLucideIcon("upload", [
11702
12191
  * This source code is licensed under the ISC license.
11703
12192
  * See the LICENSE file in the root directory of this source tree.
11704
12193
  */
12194
+ var UserCheck = createLucideIcon("user-check", [
12195
+ ["path", {
12196
+ d: "m16 11 2 2 4-4",
12197
+ key: "9rsbq5"
12198
+ }],
12199
+ ["path", {
12200
+ d: "M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2",
12201
+ key: "1yyitq"
12202
+ }],
12203
+ ["circle", {
12204
+ cx: "9",
12205
+ cy: "7",
12206
+ r: "4",
12207
+ key: "nufk8"
12208
+ }]
12209
+ ]);
12210
+ /**
12211
+ * @license lucide-react v0.576.0 - ISC
12212
+ *
12213
+ * This source code is licensed under the ISC license.
12214
+ * See the LICENSE file in the root directory of this source tree.
12215
+ */
12216
+ var User = createLucideIcon("user", [["path", {
12217
+ d: "M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2",
12218
+ key: "975kel"
12219
+ }], ["circle", {
12220
+ cx: "12",
12221
+ cy: "7",
12222
+ r: "4",
12223
+ key: "17ys0d"
12224
+ }]]);
12225
+ /**
12226
+ * @license lucide-react v0.576.0 - ISC
12227
+ *
12228
+ * This source code is licensed under the ISC license.
12229
+ * See the LICENSE file in the root directory of this source tree.
12230
+ */
12231
+ var Users = createLucideIcon("users", [
12232
+ ["path", {
12233
+ d: "M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2",
12234
+ key: "1yyitq"
12235
+ }],
12236
+ ["path", {
12237
+ d: "M16 3.128a4 4 0 0 1 0 7.744",
12238
+ key: "16gr8j"
12239
+ }],
12240
+ ["path", {
12241
+ d: "M22 21v-2a4 4 0 0 0-3-3.87",
12242
+ key: "kshegd"
12243
+ }],
12244
+ ["circle", {
12245
+ cx: "9",
12246
+ cy: "7",
12247
+ r: "4",
12248
+ key: "nufk8"
12249
+ }]
12250
+ ]);
12251
+ /**
12252
+ * @license lucide-react v0.576.0 - ISC
12253
+ *
12254
+ * This source code is licensed under the ISC license.
12255
+ * See the LICENSE file in the root directory of this source tree.
12256
+ */
11705
12257
  var UtensilsCrossed = createLucideIcon("utensils-crossed", [
11706
12258
  ["path", {
11707
12259
  d: "m16 2-2.3 2.3a3 3 0 0 0 0 4.2l1.8 1.8a3 3 0 0 0 4.2 0L22 8",
@@ -17135,8 +17687,6 @@ var useAddonsListFrameworkPackages = trpc.addons.listFrameworkPackages.useQuery;
17135
17687
  var useAddonsListCapabilityProviders = trpc.addons.listCapabilityProviders.useQuery;
17136
17688
  /** Generated alias around `trpc.addons.setCapabilityProviderEnabled.useMutation`. */
17137
17689
  var useAddonsSetCapabilityProviderEnabled = trpc.addons.setCapabilityProviderEnabled.useMutation;
17138
- /** Generated alias around `trpc.addons.updateFrameworkPackage.useMutation`. */
17139
- var useAddonsUpdateFrameworkPackage = trpc.addons.updateFrameworkPackage.useMutation;
17140
17690
  /** Generated alias around `trpc.addons.getVersions.useQuery`. */
17141
17691
  var useAddonsGetVersions = trpc.addons.getVersions.useQuery;
17142
17692
  /** Generated alias around `trpc.addons.restartAddon.useMutation`. */
@@ -30827,28 +31377,28 @@ function PipelineBuilder({ schema, steps, onChange, templates, selectedTemplateI
30827
31377
  //#endregion
30828
31378
  //#region src/composites/detection-colors.ts
30829
31379
  /**
30830
- * Detection class colors — single source of truth.
31380
+ * Detection class colors — a thin adapter over the SINGLE event-kind
31381
+ * taxonomy dictionary in `@camstack/types` (`EVENT_TAXONOMY`). Colors are no
31382
+ * longer duplicated here; this module only adds the UI-only classes the
31383
+ * taxonomy doesn't model (face / plate) and the deterministic hash fallback.
30831
31384
  *
30832
- * Used by: DetectionCanvas (UI), result-annotator (server-side SVG),
30833
- * admin-ui event viewer, and any other place that visualizes detections.
31385
+ * Used by: DetectionCanvas / DetectionResultTree / DetectionOverlay (UI),
31386
+ * and any other place that visualizes detection classes.
30834
31387
  */
30835
- /** Fixed colors for known detection classes */
30836
- var CLASS_COLORS = {
30837
- person: "#3b82f6",
30838
- vehicle: "#f59e0b",
30839
- animal: "#22c55e",
31388
+ /** UI-only classes not modelled in the event taxonomy (sub-detections). */
31389
+ var UI_ONLY_COLORS = {
30840
31390
  face: "#a855f7",
30841
- plate: "#ec4899",
30842
- bird: "#14b8a6",
30843
- dog: "#84cc16",
30844
- cat: "#f97316",
30845
- car: "#f59e0b",
30846
- truck: "#d97706",
30847
- bus: "#b45309",
30848
- motorcycle: "#eab308",
30849
- bicycle: "#ca8a04",
30850
- motion: "#facc15"
31391
+ plate: "#ec4899"
30851
31392
  };
31393
+ /**
31394
+ * Fixed colors for known detection classes — derived from the taxonomy
31395
+ * (every detection/motion kind) plus the UI-only face/plate classes. Kept as
31396
+ * a named export for back-compat with existing consumers.
31397
+ */
31398
+ var CLASS_COLORS = Object.freeze({
31399
+ ...Object.fromEntries(Object.values(_camstack_types.EVENT_TAXONOMY).filter((e) => e.category === "detection" || e.kind === "motion").map((e) => [e.kind, e.color])),
31400
+ ...UI_ONLY_COLORS
31401
+ });
30852
31402
  /** Fallback color palette for unknown classes (deterministic hash-based) */
30853
31403
  var FALLBACK_PALETTE = [
30854
31404
  "#ef4444",
@@ -30863,19 +31413,131 @@ var FALLBACK_PALETTE = [
30863
31413
  "#059669"
30864
31414
  ];
30865
31415
  /** Primary/default color when nothing else matches */
30866
- var DEFAULT_COLOR = "#f59e42";
31416
+ var DEFAULT_COLOR = _camstack_types.DEFAULT_EVENT_COLOR;
30867
31417
  /**
30868
31418
  * Get the color for a detection class name.
30869
- * Returns a fixed color for known classes, or a deterministic hash-based color for unknown ones.
31419
+ * Resolves: custom override taxonomy/UI-only fixed color deterministic
31420
+ * hash-based color for unknown classes.
30870
31421
  */
30871
31422
  function getClassColor(className, customColors) {
30872
31423
  if (customColors?.[className]) return customColors[className];
30873
31424
  if (customColors?.[className.toLowerCase()]) return customColors[className.toLowerCase()];
31425
+ const fromTaxonomy = _camstack_types.EVENT_TAXONOMY[className] ?? _camstack_types.EVENT_TAXONOMY[className.toLowerCase()];
31426
+ if (fromTaxonomy !== void 0) return fromTaxonomy.color;
30874
31427
  if (CLASS_COLORS[className]) return CLASS_COLORS[className];
30875
31428
  if (CLASS_COLORS[className.toLowerCase()]) return CLASS_COLORS[className.toLowerCase()];
30876
31429
  let hash = 0;
30877
31430
  for (let i = 0; i < className.length; i++) hash = hash * 31 + (className.codePointAt(i) ?? 0) >>> 0;
30878
- return FALLBACK_PALETTE[hash % FALLBACK_PALETTE.length] ?? "#f59e42";
31431
+ return FALLBACK_PALETTE[hash % FALLBACK_PALETTE.length] ?? DEFAULT_COLOR;
31432
+ }
31433
+ //#endregion
31434
+ //#region src/composites/event-kind-visuals.tsx
31435
+ /**
31436
+ * Event-kind VISUALS — the UI-side half of the unified taxonomy dictionary
31437
+ * (`@camstack/types` `EVENT_TAXONOMY` owns the serializable data:
31438
+ * color / iconId / labelKey; this owns `iconId → lucide component` and
31439
+ * `labelKey → t()`).
31440
+ *
31441
+ * Every UI that renders an event kind (timeline, events tree, chips,
31442
+ * detection canvas/tree) resolves its glyph + translated label here — no
31443
+ * per-component hardcoded icon or label.
31444
+ */
31445
+ /**
31446
+ * `iconId` → lucide component. Built ONLY from statically-imported icons
31447
+ * (bundle-safe). Unknown ids resolve to the neutral `Tag` fallback.
31448
+ */
31449
+ var EVENT_KIND_ICONS = {
31450
+ motion: Activity,
31451
+ audio: Volume2,
31452
+ person: User,
31453
+ vehicle: Car,
31454
+ animal: PawPrint,
31455
+ package: Package,
31456
+ sensor: Radio,
31457
+ control: SlidersHorizontal,
31458
+ car: Car,
31459
+ truck: Truck,
31460
+ bus: Bus,
31461
+ motorcycle: Bike,
31462
+ bicycle: Bike,
31463
+ airplane: Plane,
31464
+ boat: Sailboat,
31465
+ train: TrainFront,
31466
+ bird: Bird,
31467
+ cat: Cat,
31468
+ dog: Dog,
31469
+ horse: PawPrint,
31470
+ sheep: PawPrint,
31471
+ cow: PawPrint,
31472
+ elephant: PawPrint,
31473
+ bear: PawPrint,
31474
+ zebra: PawPrint,
31475
+ giraffe: PawPrint,
31476
+ door: DoorOpen,
31477
+ pir: Radar,
31478
+ smoke: Flame,
31479
+ water: Droplet,
31480
+ gas: Wind,
31481
+ vibration: Vibrate,
31482
+ tamper: ShieldAlert,
31483
+ presence: UserCheck,
31484
+ generic: Tag,
31485
+ lock: Lock,
31486
+ siren: Siren,
31487
+ switch: ToggleRight,
31488
+ doorbell: BellRing,
31489
+ button: CircleDot,
31490
+ "audio-speech": MessageSquare,
31491
+ "audio-scream": Megaphone,
31492
+ "audio-crying": Baby,
31493
+ "audio-laughter": Laugh,
31494
+ "audio-music": Music,
31495
+ "audio-dog": Dog,
31496
+ "audio-cat": Cat,
31497
+ "audio-bird": Bird,
31498
+ "audio-animal": PawPrint,
31499
+ "audio-alarm": BellRing,
31500
+ "audio-doorbell": BellRing,
31501
+ "audio-glass_breaking": TriangleAlert,
31502
+ "audio-gunshot": Crosshair,
31503
+ "audio-vehicle": Car,
31504
+ "audio-siren": Siren,
31505
+ "audio-fire": Flame,
31506
+ "audio-water": Droplets,
31507
+ "audio-wind": Wind,
31508
+ "audio-door": DoorOpen,
31509
+ "audio-footsteps": Footprints,
31510
+ "audio-crowd": Users,
31511
+ "audio-telephone": Phone,
31512
+ "audio-engine": Cog,
31513
+ "audio-tools": Hammer,
31514
+ "audio-silence": VolumeX
31515
+ };
31516
+ /** Resolve an `iconId` to a lucide component (falls back to `Tag`). */
31517
+ function resolveEventKindIcon(iconId) {
31518
+ if (Object.hasOwn(EVENT_KIND_ICONS, iconId)) return EVENT_KIND_ICONS[iconId];
31519
+ if (iconId.startsWith("audio-")) return Volume2;
31520
+ return Tag;
31521
+ }
31522
+ /**
31523
+ * Translated label for an event kind — `t(labelKey)` when a translation
31524
+ * exists, else the English `label` fallback. Robust to a missing key: an
31525
+ * i18n backend that echoes the key unchanged (react-i18next default) is
31526
+ * treated as "no translation" and the fallback label is returned, so the UI
31527
+ * never renders a raw `eventKind.*` key.
31528
+ */
31529
+ function eventKindLabel(descriptor, t) {
31530
+ if (t === void 0) return descriptor.label;
31531
+ const translated = t(descriptor.labelKey);
31532
+ return translated === descriptor.labelKey || translated.length === 0 ? descriptor.label : translated;
31533
+ }
31534
+ /** Small convenience component: renders the lucide glyph for an `iconId`. */
31535
+ function EventKindGlyph({ iconId, size = 16, color, className }) {
31536
+ return (0, react$1.createElement)(resolveEventKindIcon(iconId), {
31537
+ size,
31538
+ color,
31539
+ className
31540
+ });
30879
31541
  }
30880
31542
  //#endregion
30881
31543
  //#region src/composites/detection-canvas.tsx
@@ -32524,6 +33186,294 @@ function mountAddonPage(PageComponent, options = {}) {
32524
33186
  }));
32525
33187
  }
32526
33188
  //#endregion
33189
+ //#region src/composites/device-select-filter.ts
33190
+ /** True when two string lists share at least one member. */
33191
+ function intersects(a, b) {
33192
+ if (a.length === 0 || b.length === 0) return false;
33193
+ const set = new Set(a);
33194
+ return b.some((v) => set.has(v));
33195
+ }
33196
+ /**
33197
+ * Does a device satisfy the filter?
33198
+ *
33199
+ * Union match: with an empty/absent filter every device passes; otherwise the
33200
+ * device passes when ANY provided clause matches — its `features` intersect
33201
+ * `caps`, OR its `type` is in `types`. `excludeDeviceId` is subtracted last
33202
+ * (it always drops the device regardless of the other clauses).
33203
+ */
33204
+ function deviceMatchesFilter(device, filter) {
33205
+ if (filter?.excludeDeviceId !== void 0 && device.id === filter.excludeDeviceId) return false;
33206
+ const hasCaps = filter?.caps !== void 0 && filter.caps.length > 0;
33207
+ const hasTypes = filter?.types !== void 0 && filter.types.length > 0;
33208
+ if (!hasCaps && !hasTypes) return true;
33209
+ if (hasCaps && intersects(device.features ?? [], filter.caps)) return true;
33210
+ if (hasTypes && filter.types.includes(device.type)) return true;
33211
+ return false;
33212
+ }
33213
+ /** Human label for a device option: `Name (Location)` when a location is set. */
33214
+ function deviceOptionLabel(device) {
33215
+ return typeof device.location === "string" && device.location.length > 0 ? `${device.name} (${device.location})` : device.name;
33216
+ }
33217
+ /**
33218
+ * Filter a device list and project it into sorted `{ value, label }` options
33219
+ * (value = the device id as a string). Sorted case-insensitively by label so
33220
+ * the picker order is stable.
33221
+ */
33222
+ function devicesToOptions(devices, filter) {
33223
+ return devices.filter((d) => deviceMatchesFilter(d, filter)).map((d) => ({
33224
+ value: String(d.id),
33225
+ label: deviceOptionLabel(d)
33226
+ })).toSorted((a, b) => a.label.localeCompare(b.label));
33227
+ }
33228
+ /**
33229
+ * Free-text option filter — case-insensitive AND over whitespace tokens, each
33230
+ * matched against the option's `value` + `label` (so a device is found by name,
33231
+ * id, or location). An empty query returns every option in order.
33232
+ */
33233
+ function filterDeviceOptions(options, query) {
33234
+ const tokens = query.trim().toLowerCase().split(/\s+/).filter(Boolean);
33235
+ if (tokens.length === 0) return [...options];
33236
+ return options.filter((opt) => {
33237
+ const hay = `${opt.value} ${opt.label}`.toLowerCase();
33238
+ return tokens.every((t) => hay.includes(t));
33239
+ });
33240
+ }
33241
+ /**
33242
+ * Resolve the currently-selected values into options IN SELECTION ORDER (so
33243
+ * chips stay stable while searching). A selected value with no matching option
33244
+ * becomes a synthetic `{ value, label: value }` — a stale id still shows as a
33245
+ * removable chip rather than silently vanishing.
33246
+ */
33247
+ function selectedDeviceOptions(options, selected) {
33248
+ const byValue = new Map(options.map((o) => [o.value, o]));
33249
+ return selected.map((v) => byValue.get(v) ?? {
33250
+ value: v,
33251
+ label: v
33252
+ });
33253
+ }
33254
+ //#endregion
33255
+ //#region src/composites/device-select-field.tsx
33256
+ /**
33257
+ * `device-select` / `device-multiselect` renderers.
33258
+ *
33259
+ * Both fetch EVERY system device via `deviceManager.listAll` and narrow the
33260
+ * options CLIENT-SIDE with the field's declarative `deviceFilter` (see
33261
+ * `device-select-filter.ts`). No server-computed option list is involved —
33262
+ * the form field carries only the filter. Value(s) are device ids as strings.
33263
+ *
33264
+ * The multi variant mirrors the "Linked devices" searchable combobox UX
33265
+ * (removable chips + typeahead dropdown); the single variant is a native
33266
+ * select. Both are inline in ui-library (like `node-select`) so any host that
33267
+ * renders the shared form field gets them without extra registration.
33268
+ */
33269
+ var INPUT_CLASS$1 = "w-full rounded-md border border-border bg-background px-2.5 py-1.5 text-xs text-foreground focus:border-primary focus:ring-1 focus:ring-primary/30 outline-none disabled:opacity-50 disabled:cursor-not-allowed";
33270
+ var INPUT_SHELL = "flex items-center gap-1.5 rounded-md border border-border bg-background px-2 py-1.5 focus-within:border-primary focus-within:ring-1 focus-within:ring-primary/30";
33271
+ var LABEL_CLASS$1 = "block text-[11px] font-medium text-foreground mb-1 break-words";
33272
+ var DESC_CLASS$1 = "text-[10px] text-foreground-subtle mt-0.5 break-words";
33273
+ /** The compact projection of the listAll rows the device fields consume. */
33274
+ function toCandidates(rows) {
33275
+ if (!Array.isArray(rows)) return [];
33276
+ const out = [];
33277
+ for (const row of rows) {
33278
+ if (typeof row !== "object" || row === null) continue;
33279
+ const r = row;
33280
+ if (typeof r.id !== "number" || typeof r.type !== "string" || typeof r.name !== "string") continue;
33281
+ out.push({
33282
+ id: r.id,
33283
+ type: r.type,
33284
+ name: r.name,
33285
+ location: typeof r.location === "string" ? r.location : null,
33286
+ features: Array.isArray(r.features) ? r.features.filter((f) => typeof f === "string") : []
33287
+ });
33288
+ }
33289
+ return out;
33290
+ }
33291
+ function FieldShell({ label, description, required, translationFn, children }) {
33292
+ const resolvedLabel = resolveLabel(label, translationFn);
33293
+ const resolvedDescription = resolveLabel(description, translationFn);
33294
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
33295
+ className: "min-w-0",
33296
+ children: [
33297
+ resolvedLabel !== void 0 && resolvedLabel !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
33298
+ className: LABEL_CLASS$1,
33299
+ children: [resolvedLabel, required && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
33300
+ className: "text-danger ml-0.5",
33301
+ children: "*"
33302
+ })]
33303
+ }),
33304
+ children,
33305
+ resolvedDescription && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
33306
+ className: DESC_CLASS$1,
33307
+ children: resolvedDescription
33308
+ })
33309
+ ]
33310
+ });
33311
+ }
33312
+ function DeviceSelectField({ field, value, onChange, disabled, translationFn }) {
33313
+ const { data } = useDeviceManagerListAll({});
33314
+ const options = (0, react$1.useMemo)(() => devicesToOptions(toCandidates(data), field.deviceFilter), [data, field.deviceFilter]);
33315
+ const current = value === void 0 || value === null ? "" : String(value);
33316
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(FieldShell, {
33317
+ label: field.label,
33318
+ description: field.description,
33319
+ required: field.required,
33320
+ translationFn,
33321
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
33322
+ className: INPUT_CLASS$1,
33323
+ value: current,
33324
+ disabled: disabled || field.disabled,
33325
+ onChange: (e) => onChange(e.target.value),
33326
+ children: [!field.required && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
33327
+ value: "",
33328
+ children: "— Select device —"
33329
+ }), options.map((opt) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
33330
+ value: opt.value,
33331
+ children: opt.label
33332
+ }, opt.value))]
33333
+ })
33334
+ });
33335
+ }
33336
+ function DeviceMultiSelectField({ field, value, onChange, disabled, translationFn }) {
33337
+ const { data } = useDeviceManagerListAll({});
33338
+ const options = (0, react$1.useMemo)(() => devicesToOptions(toCandidates(data), field.deviceFilter), [data, field.deviceFilter]);
33339
+ const selected = Array.isArray(value) ? value.map(String) : [];
33340
+ const isDisabled = disabled === true || field.disabled === true;
33341
+ const atMax = field.maxItems !== void 0 && selected.length >= field.maxItems;
33342
+ const [query, setQuery] = (0, react$1.useState)("");
33343
+ const [open, setOpen] = (0, react$1.useState)(false);
33344
+ const [highlight, setHighlight] = (0, react$1.useState)(0);
33345
+ const inputRef = (0, react$1.useRef)(null);
33346
+ const blurTimer = (0, react$1.useRef)(null);
33347
+ const selectedOptions = (0, react$1.useMemo)(() => selectedDeviceOptions(options, selected), [options, selected]);
33348
+ const filtered = (0, react$1.useMemo)(() => filterDeviceOptions(options, query), [options, query]);
33349
+ const toggle = (optValue) => {
33350
+ if (isDisabled) return;
33351
+ if (selected.includes(optValue)) onChange(selected.filter((v) => v !== optValue));
33352
+ else {
33353
+ if (field.maxItems !== void 0 && selected.length >= field.maxItems) return;
33354
+ onChange([...selected, optValue]);
33355
+ }
33356
+ };
33357
+ const handleKeyDown = (e) => {
33358
+ if (e.key === "ArrowDown") {
33359
+ e.preventDefault();
33360
+ setOpen(true);
33361
+ setHighlight((h) => filtered.length === 0 ? 0 : (h + 1) % filtered.length);
33362
+ } else if (e.key === "ArrowUp") {
33363
+ e.preventDefault();
33364
+ setOpen(true);
33365
+ setHighlight((h) => filtered.length === 0 ? 0 : (h - 1 + filtered.length) % filtered.length);
33366
+ } else if (e.key === "Enter") {
33367
+ e.preventDefault();
33368
+ const opt = filtered[highlight];
33369
+ if (opt) toggle(opt.value);
33370
+ } else if (e.key === "Escape") setOpen(false);
33371
+ else if (e.key === "Backspace" && query === "" && selected.length > 0) onChange(selected.slice(0, -1));
33372
+ };
33373
+ const label = resolveLabel(field.label, translationFn);
33374
+ const description = resolveLabel(field.description, translationFn);
33375
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
33376
+ className: "min-w-0",
33377
+ children: [
33378
+ label !== void 0 && label !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
33379
+ className: LABEL_CLASS$1,
33380
+ children: label
33381
+ }),
33382
+ selectedOptions.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
33383
+ className: "flex flex-wrap gap-1 mb-1.5",
33384
+ children: selectedOptions.map((opt) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
33385
+ className: "inline-flex items-center gap-1 rounded-md bg-primary/10 px-1.5 py-0.5 text-[11px] text-primary max-w-full",
33386
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
33387
+ className: "truncate",
33388
+ children: opt.label
33389
+ }), !isDisabled && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
33390
+ type: "button",
33391
+ className: "shrink-0 hover:text-danger",
33392
+ "aria-label": `Remove ${opt.label}`,
33393
+ onClick: () => toggle(opt.value),
33394
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(X, { className: "h-2.5 w-2.5" })
33395
+ })]
33396
+ }, opt.value))
33397
+ }),
33398
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
33399
+ className: INPUT_SHELL + (isDisabled ? " opacity-50" : ""),
33400
+ children: [
33401
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Search, { className: "h-3.5 w-3.5 shrink-0 text-foreground-subtle" }),
33402
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
33403
+ ref: inputRef,
33404
+ type: "text",
33405
+ role: "combobox",
33406
+ "aria-expanded": open,
33407
+ "aria-controls": `dsel-${field.key}`,
33408
+ className: "min-w-0 flex-1 bg-transparent text-xs text-foreground outline-none placeholder:text-foreground-disabled",
33409
+ value: query,
33410
+ placeholder: atMax ? `Max ${field.maxItems} selected` : field.placeholder ?? "Search devices…",
33411
+ disabled: isDisabled,
33412
+ onChange: (e) => {
33413
+ setQuery(e.target.value);
33414
+ setOpen(true);
33415
+ setHighlight(0);
33416
+ },
33417
+ onFocus: () => setOpen(true),
33418
+ onBlur: () => {
33419
+ blurTimer.current = setTimeout(() => setOpen(false), 120);
33420
+ },
33421
+ onKeyDown: handleKeyDown
33422
+ }),
33423
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ChevronDown, {
33424
+ className: "h-3.5 w-3.5 shrink-0 cursor-pointer text-foreground-subtle",
33425
+ onMouseDown: (e) => {
33426
+ e.preventDefault();
33427
+ if (blurTimer.current) clearTimeout(blurTimer.current);
33428
+ setOpen((o) => !o);
33429
+ inputRef.current?.focus();
33430
+ }
33431
+ })
33432
+ ]
33433
+ }),
33434
+ open && !isDisabled && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
33435
+ id: `dsel-${field.key}`,
33436
+ role: "listbox",
33437
+ className: "mt-1 max-h-56 overflow-y-auto rounded-md border border-border bg-surface shadow-lg",
33438
+ onMouseDown: (e) => {
33439
+ e.preventDefault();
33440
+ },
33441
+ children: filtered.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
33442
+ className: "px-2.5 py-2 text-[11px] text-foreground-subtle italic",
33443
+ children: options.length === 0 ? "No matching devices" : `No matches for “${query}”`
33444
+ }) : filtered.map((opt, i) => {
33445
+ const checked = selected.includes(opt.value);
33446
+ const blockedByMax = !checked && atMax;
33447
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
33448
+ type: "button",
33449
+ role: "option",
33450
+ "aria-selected": checked,
33451
+ disabled: blockedByMax,
33452
+ className: [
33453
+ "flex w-full items-center gap-2 px-2.5 py-1.5 text-left text-xs transition-colors",
33454
+ i === highlight ? "bg-primary/10" : "hover:bg-surface-hover",
33455
+ blockedByMax ? "opacity-40 cursor-not-allowed" : "cursor-pointer"
33456
+ ].join(" "),
33457
+ onMouseEnter: () => setHighlight(i),
33458
+ onClick: () => toggle(opt.value),
33459
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
33460
+ className: ["flex h-3.5 w-3.5 shrink-0 items-center justify-center rounded border", checked ? "border-primary bg-primary text-white" : "border-border"].join(" "),
33461
+ children: checked && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Check, { className: "h-2.5 w-2.5" })
33462
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
33463
+ className: "truncate text-foreground",
33464
+ children: opt.label
33465
+ })]
33466
+ }, opt.value);
33467
+ })
33468
+ }),
33469
+ description && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
33470
+ className: DESC_CLASS$1,
33471
+ children: description
33472
+ })
33473
+ ]
33474
+ });
33475
+ }
33476
+ //#endregion
32527
33477
  //#region src/contexts/custom-field-renderers.tsx
32528
33478
  /**
32529
33479
  * Custom field renderer registry.
@@ -38506,6 +39456,20 @@ function FormField({ field, values, onChange, disabled, translationFn, onTestFie
38506
39456
  disabled,
38507
39457
  translationFn
38508
39458
  });
39459
+ case "device-select": return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DeviceSelectField, {
39460
+ field,
39461
+ value,
39462
+ onChange: handleChange,
39463
+ disabled,
39464
+ translationFn
39465
+ });
39466
+ case "device-multiselect": return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DeviceMultiSelectField, {
39467
+ field,
39468
+ value,
39469
+ onChange: handleChange,
39470
+ disabled,
39471
+ translationFn
39472
+ });
38509
39473
  case "probe": return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ProbeField, {
38510
39474
  field,
38511
39475
  value,
@@ -39015,6 +39979,7 @@ function computeClientHints(container) {
39015
39979
  var RECONNECT_BASE_DELAY_MS = 1500;
39016
39980
  var RECONNECT_MAX_DELAY_MS = 15e3;
39017
39981
  var MAX_RECONNECT_ATTEMPTS = 40;
39982
+ var FIRST_FRAME_TIMEOUT_MS = 8e3;
39018
39983
  function CameraStreamPlayer({ serverUrl, streamKey, label, autoPlay = true, muted: initialMuted = true, showControls = true, showStats = false, onPlaybackStats, onClientNetworkSample, onConnectTiming, className = "", onStateChange, onError, overlay, createSession, sendAnswer, handleOffer, getIceServers, addIceCandidate, getIceCandidates, closeSession, getSessionState, reoffer, posterUrl, hintsOverride, reconnectSignal, onControlChannel }) {
39019
39984
  const videoRef = (0, react$1.useRef)(null);
39020
39985
  const containerRef = (0, react$1.useRef)(null);
@@ -39391,14 +40356,26 @@ function CameraStreamPlayer({ serverUrl, streamKey, label, autoPlay = true, mute
39391
40356
  });
39392
40357
  onConnectTiming?.({ ...timing });
39393
40358
  const v = videoRef.current;
39394
- if (v && "requestVideoFrameCallback" in v) v.requestVideoFrameCallback(() => {
39395
- timing.firstFrameMs = ms();
39396
- console.info("[WebRTC timing] first decoded frame", {
39397
- streamKey,
39398
- firstFrameMs: timing.firstFrameMs
40359
+ if (v && "requestVideoFrameCallback" in v) {
40360
+ v.requestVideoFrameCallback(() => {
40361
+ timing.firstFrameMs = ms();
40362
+ console.info("[WebRTC timing] first decoded frame", {
40363
+ streamKey,
40364
+ firstFrameMs: timing.firstFrameMs
40365
+ });
40366
+ onConnectTiming?.({ ...timing });
39399
40367
  });
39400
- onConnectTiming?.({ ...timing });
39401
- });
40368
+ setTimeout(() => {
40369
+ if (!mountedRef.current) return;
40370
+ if (timing.firstFrameMs !== void 0) return;
40371
+ console.warn("[WebRTC timing] NO decoded frame (stalled)", {
40372
+ streamKey,
40373
+ sinceIceConnectedMs: ms() - (timing.iceConnectedMs ?? 0),
40374
+ iceConnectedMs: timing.iceConnectedMs,
40375
+ firstTrackMs: timing.firstTrackMs
40376
+ });
40377
+ }, FIRST_FRAME_TIMEOUT_MS);
40378
+ }
39402
40379
  }
39403
40380
  reconnectAttemptsRef.current = 0;
39404
40381
  if (seamless) swapInOnce();
@@ -39431,8 +40408,12 @@ function CameraStreamPlayer({ serverUrl, streamKey, label, autoPlay = true, mute
39431
40408
  await pc.setLocalDescription(offer);
39432
40409
  timing.localSetMs = ms();
39433
40410
  if (!mountedRef.current || abort.signal.aborted) return;
40411
+ const clientOfferHints = {
40412
+ ...computeClientHints(containerRef.current),
40413
+ ...hintsOverride
40414
+ };
39434
40415
  const signalingStart = ms();
39435
- const { sessionId: sid, sdpAnswer } = await handleOffer(pc.localDescription?.sdp ?? offer.sdp ?? "");
40416
+ const { sessionId: sid, sdpAnswer } = await handleOffer(pc.localDescription?.sdp ?? offer.sdp ?? "", void 0, clientOfferHints);
39436
40417
  timing.signalingRttMs = ms() - signalingStart;
39437
40418
  sessionId = sid;
39438
40419
  sessionIdsRef.current.add(sid);
@@ -39493,7 +40474,8 @@ function CameraStreamPlayer({ serverUrl, streamKey, label, autoPlay = true, mute
39493
40474
  partialReconnectReset,
39494
40475
  updateState,
39495
40476
  onError,
39496
- startSessionStatePoll
40477
+ startSessionStatePoll,
40478
+ hintsOverride
39497
40479
  ]);
39498
40480
  renegotiateRef.current = (0, react$1.useCallback)(async (sessionId, target) => {
39499
40481
  const reofferFn = reoffer;
@@ -39556,7 +40538,11 @@ function CameraStreamPlayer({ serverUrl, streamKey, label, autoPlay = true, mute
39556
40538
  pc.close();
39557
40539
  return;
39558
40540
  }
39559
- const { sessionId: sid, sdpAnswer } = await reofferFn(sessionId, pc.localDescription?.sdp ?? offer.sdp ?? "", target);
40541
+ const reofferHints = {
40542
+ ...computeClientHints(containerRef.current),
40543
+ ...hintsOverride
40544
+ };
40545
+ const { sessionId: sid, sdpAnswer } = await reofferFn(sessionId, pc.localDescription?.sdp ?? offer.sdp ?? "", target, reofferHints);
39560
40546
  if (!mountedRef.current) {
39561
40547
  pc.close();
39562
40548
  return;
@@ -39607,7 +40593,8 @@ function CameraStreamPlayer({ serverUrl, streamKey, label, autoPlay = true, mute
39607
40593
  addIceCandidate,
39608
40594
  getIceCandidates,
39609
40595
  updateState,
39610
- startSessionStatePoll
40596
+ startSessionStatePoll,
40597
+ hintsOverride
39611
40598
  ]);
39612
40599
  const connect = useClientOffer ? connectClientOffer : useServerOffer ? connectServerOffer : connectWhep;
39613
40600
  const connectRef = (0, react$1.useRef)(() => {});
@@ -45320,13 +46307,14 @@ function useDeviceWebrtc(trpc, deviceId, pollIntervalMs = 5e3) {
45320
46307
  deviceId,
45321
46308
  getIceServers
45322
46309
  ]);
45323
- const handleOffer = (0, react$1.useCallback)(async (target, sdpOffer, sessionId) => {
46310
+ const handleOffer = (0, react$1.useCallback)(async (target, sdpOffer, sessionId, hints) => {
45324
46311
  if (deviceId === null) throw new Error("No device selected");
45325
46312
  return trpc.webrtcSession.handleOffer.mutate({
45326
46313
  deviceId,
45327
46314
  target,
45328
46315
  sdpOffer,
45329
- ...sessionId !== void 0 ? { sessionId } : {}
46316
+ ...sessionId !== void 0 ? { sessionId } : {},
46317
+ ...hints !== void 0 ? { hints } : {}
45330
46318
  });
45331
46319
  }, [trpc, deviceId]);
45332
46320
  const sendAnswer = (0, react$1.useCallback)(async (sessionId, sdpAnswer) => {
@@ -45748,6 +46736,8 @@ exports.DeviceExportPanel = DeviceExportPanel;
45748
46736
  exports.DeviceGrid = DeviceGrid;
45749
46737
  exports.DeviceItem = DeviceItem;
45750
46738
  exports.DeviceList = DeviceList;
46739
+ exports.DeviceMultiSelectField = DeviceMultiSelectField;
46740
+ exports.DeviceSelectField = DeviceSelectField;
45751
46741
  exports.Dialog = Dialog;
45752
46742
  exports.DialogContent = DialogContent;
45753
46743
  exports.DialogDescription = DialogDescription;
@@ -45763,8 +46753,10 @@ exports.DropdownItem = DropdownItem;
45763
46753
  exports.DropdownTrigger = DropdownTrigger;
45764
46754
  exports.DummyHeroCard = DummyHeroCard;
45765
46755
  exports.DummyInline = DummyInline;
46756
+ exports.EVENT_KIND_ICONS = EVENT_KIND_ICONS;
45766
46757
  exports.EmptyState = EmptyState;
45767
46758
  exports.ErrorBox = ErrorBox;
46759
+ exports.EventKindGlyph = EventKindGlyph;
45768
46760
  exports.EventStream = EventStream;
45769
46761
  exports.EyeOff = EyeOff;
45770
46762
  exports.FILL = FILL;
@@ -45930,11 +46922,16 @@ exports.cursorFractionFor = cursorFractionFor;
45930
46922
  exports.darkColors = require_theme_index.darkColors$1;
45931
46923
  exports.defaultTheme = require_theme_index.defaultTheme$1;
45932
46924
  exports.deriveDeviceKind = deriveDeviceKind;
46925
+ exports.deviceMatchesFilter = deviceMatchesFilter;
46926
+ exports.deviceOptionLabel = deviceOptionLabel;
45933
46927
  exports.deviceRoleMeta = deviceRoleMeta;
45934
46928
  exports.deviceRoleMetaOf = deviceRoleMetaOf;
45935
46929
  exports.deviceTypeMeta = deviceTypeMeta;
45936
46930
  exports.deviceTypeMetaOf = deviceTypeMetaOf;
46931
+ exports.devicesToOptions = devicesToOptions;
45937
46932
  exports.ensureMfHostInit = ensureMfHostInit;
46933
+ exports.eventKindLabel = eventKindLabel;
46934
+ exports.filterDeviceOptions = filterDeviceOptions;
45938
46935
  exports.findTimezone = _camstack_types.findTimezone;
45939
46936
  exports.formatControlDateTime = formatControlDateTime;
45940
46937
  exports.formatLastSeen = formatLastSeen;
@@ -45966,9 +46963,11 @@ exports.resolveContainerPrimary = resolveContainerPrimary;
45966
46963
  exports.resolveControlAlign = resolveControlAlign;
45967
46964
  exports.resolveDeviceControl = resolveDeviceControl;
45968
46965
  exports.resolveDisplayIcon = resolveDisplayIcon;
46966
+ exports.resolveEventKindIcon = resolveEventKindIcon;
45969
46967
  exports.resolvePrimaryChild = resolvePrimaryChild;
45970
46968
  exports.resolveSensorDisplay = resolveSensorDisplay;
45971
46969
  exports.scrubReducer = scrubReducer;
46970
+ exports.selectedDeviceOptions = selectedDeviceOptions;
45972
46971
  exports.serializeRecordedCommand = serializeRecordedCommand;
45973
46972
  exports.shouldCommit = shouldCommit;
45974
46973
  exports.shouldEmit = shouldEmit;
@@ -46018,7 +47017,6 @@ exports.useAddonsSetAutoUpdateSettings = useAddonsSetAutoUpdateSettings;
46018
47017
  exports.useAddonsSetCapabilityProviderEnabled = useAddonsSetCapabilityProviderEnabled;
46019
47018
  exports.useAddonsStartJob = useAddonsStartJob;
46020
47019
  exports.useAddonsUninstallPackage = useAddonsUninstallPackage;
46021
- exports.useAddonsUpdateFrameworkPackage = useAddonsUpdateFrameworkPackage;
46022
47020
  exports.useAddonsUpdatePackage = useAddonsUpdatePackage;
46023
47021
  exports.useAirQualitySensorGetStatus = useAirQualitySensorGetStatus;
46024
47022
  exports.useAlarmPanelArm = useAlarmPanelArm;