@camstack/ui-library 0.1.50 → 0.1.51
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/composites/copy-button.d.ts +12 -0
- package/dist/composites/device-export-panel.d.ts +16 -0
- package/dist/composites/error-box.d.ts +19 -0
- package/dist/composites/index.d.ts +7 -0
- package/dist/composites/qr-code.d.ts +12 -0
- package/dist/generated/system-hooks.d.ts +8 -0
- package/dist/index.cjs +2088 -448
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1635 -4
- package/dist/index.js.map +1 -1
- package/package.json +7 -1
package/dist/index.cjs
CHANGED
|
@@ -1,29 +1,30 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
//#region \0rolldown/runtime.js
|
|
3
3
|
var __create = Object.create;
|
|
4
|
-
var __defProp = Object.defineProperty;
|
|
4
|
+
var __defProp$1 = Object.defineProperty;
|
|
5
5
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
6
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
7
|
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __hasOwnProp$1 = Object.prototype.hasOwnProperty;
|
|
9
9
|
var __copyProps = (to, from, except, desc) => {
|
|
10
10
|
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
11
11
|
key = keys[i];
|
|
12
|
-
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
12
|
+
if (!__hasOwnProp$1.call(to, key) && key !== except) __defProp$1(to, key, {
|
|
13
13
|
get: ((k) => from[k]).bind(null, key),
|
|
14
14
|
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
15
15
|
});
|
|
16
16
|
}
|
|
17
17
|
return to;
|
|
18
18
|
};
|
|
19
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
19
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp$1(target, "default", {
|
|
20
20
|
value: mod,
|
|
21
21
|
enumerable: true
|
|
22
22
|
}) : target, mod));
|
|
23
23
|
//#endregion
|
|
24
24
|
const require_theme_index = require("./theme/index.cjs");
|
|
25
25
|
let react = require("react");
|
|
26
|
-
react = __toESM(react, 1);
|
|
26
|
+
let react$1 = __toESM(react, 1);
|
|
27
|
+
react = __toESM(react);
|
|
27
28
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
28
29
|
react_jsx_runtime = __toESM(react_jsx_runtime, 1);
|
|
29
30
|
let react_dom = require("react-dom");
|
|
@@ -38,6 +39,7 @@ let _trpc_react_query = require("@trpc/react-query");
|
|
|
38
39
|
_trpc_react_query = __toESM(_trpc_react_query, 1);
|
|
39
40
|
let _camstack_types = require("@camstack/types");
|
|
40
41
|
let _camstack_sdk = require("@camstack/sdk");
|
|
42
|
+
let zod = require("zod");
|
|
41
43
|
//#region ../../node_modules/clsx/dist/clsx.mjs
|
|
42
44
|
function r(e) {
|
|
43
45
|
var t, f, n = "";
|
|
@@ -3590,13 +3592,13 @@ function getPhaseVisual(phase) {
|
|
|
3590
3592
|
* the Map is typed as `Context<unknown>`).
|
|
3591
3593
|
*/
|
|
3592
3594
|
function createSharedContext(name, defaultValue) {
|
|
3593
|
-
if (typeof globalThis === "undefined") return (0, react.createContext)(defaultValue);
|
|
3595
|
+
if (typeof globalThis === "undefined") return (0, react$1.createContext)(defaultValue);
|
|
3594
3596
|
const existingMap = globalThis.__camstackSharedContexts;
|
|
3595
3597
|
const map = existingMap ?? /* @__PURE__ */ new Map();
|
|
3596
3598
|
if (!existingMap) globalThis.__camstackSharedContexts = map;
|
|
3597
3599
|
const existing = map.get(name);
|
|
3598
3600
|
if (existing) return existing;
|
|
3599
|
-
const ctx = (0, react.createContext)(defaultValue);
|
|
3601
|
+
const ctx = (0, react$1.createContext)(defaultValue);
|
|
3600
3602
|
map.set(name, ctx);
|
|
3601
3603
|
return ctx;
|
|
3602
3604
|
}
|
|
@@ -6866,7 +6868,7 @@ function getModuleCache() {
|
|
|
6866
6868
|
}
|
|
6867
6869
|
function populateShareCache() {
|
|
6868
6870
|
const cache = getModuleCache();
|
|
6869
|
-
cache.share["react"] ??= react;
|
|
6871
|
+
cache.share["react"] ??= react$1;
|
|
6870
6872
|
cache.share["react-dom"] ??= react_dom;
|
|
6871
6873
|
cache.share["react-dom/client"] ??= react_dom_client;
|
|
6872
6874
|
cache.share["react/jsx-runtime"] ??= react_jsx_runtime;
|
|
@@ -6884,7 +6886,7 @@ function ensureMfHostInit() {
|
|
|
6884
6886
|
name: "admin_ui_host",
|
|
6885
6887
|
remotes: [],
|
|
6886
6888
|
shared: {
|
|
6887
|
-
"react": npmShared(() => react),
|
|
6889
|
+
"react": npmShared(() => react$1),
|
|
6888
6890
|
"react-dom": npmShared(() => react_dom),
|
|
6889
6891
|
"react-dom/client": npmShared(() => react_dom_client),
|
|
6890
6892
|
"react/jsx-runtime": npmShared(() => react_jsx_runtime),
|
|
@@ -7991,6 +7993,68 @@ var PowerOff = createLucideIcon("power-off", [
|
|
|
7991
7993
|
key: "1ooewy"
|
|
7992
7994
|
}]
|
|
7993
7995
|
]);
|
|
7996
|
+
var QrCode$1 = createLucideIcon("qr-code", [
|
|
7997
|
+
["rect", {
|
|
7998
|
+
width: "5",
|
|
7999
|
+
height: "5",
|
|
8000
|
+
x: "3",
|
|
8001
|
+
y: "3",
|
|
8002
|
+
rx: "1",
|
|
8003
|
+
key: "1tu5fj"
|
|
8004
|
+
}],
|
|
8005
|
+
["rect", {
|
|
8006
|
+
width: "5",
|
|
8007
|
+
height: "5",
|
|
8008
|
+
x: "16",
|
|
8009
|
+
y: "3",
|
|
8010
|
+
rx: "1",
|
|
8011
|
+
key: "1v8r4q"
|
|
8012
|
+
}],
|
|
8013
|
+
["rect", {
|
|
8014
|
+
width: "5",
|
|
8015
|
+
height: "5",
|
|
8016
|
+
x: "3",
|
|
8017
|
+
y: "16",
|
|
8018
|
+
rx: "1",
|
|
8019
|
+
key: "1x03jg"
|
|
8020
|
+
}],
|
|
8021
|
+
["path", {
|
|
8022
|
+
d: "M21 16h-3a2 2 0 0 0-2 2v3",
|
|
8023
|
+
key: "177gqh"
|
|
8024
|
+
}],
|
|
8025
|
+
["path", {
|
|
8026
|
+
d: "M21 21v.01",
|
|
8027
|
+
key: "ents32"
|
|
8028
|
+
}],
|
|
8029
|
+
["path", {
|
|
8030
|
+
d: "M12 7v3a2 2 0 0 1-2 2H7",
|
|
8031
|
+
key: "8crl2c"
|
|
8032
|
+
}],
|
|
8033
|
+
["path", {
|
|
8034
|
+
d: "M3 12h.01",
|
|
8035
|
+
key: "nlz23k"
|
|
8036
|
+
}],
|
|
8037
|
+
["path", {
|
|
8038
|
+
d: "M12 3h.01",
|
|
8039
|
+
key: "n36tog"
|
|
8040
|
+
}],
|
|
8041
|
+
["path", {
|
|
8042
|
+
d: "M12 16v.01",
|
|
8043
|
+
key: "133mhm"
|
|
8044
|
+
}],
|
|
8045
|
+
["path", {
|
|
8046
|
+
d: "M16 12h1",
|
|
8047
|
+
key: "1slzba"
|
|
8048
|
+
}],
|
|
8049
|
+
["path", {
|
|
8050
|
+
d: "M21 12v.01",
|
|
8051
|
+
key: "1lwtk9"
|
|
8052
|
+
}],
|
|
8053
|
+
["path", {
|
|
8054
|
+
d: "M12 21v-1",
|
|
8055
|
+
key: "1880an"
|
|
8056
|
+
}]
|
|
8057
|
+
]);
|
|
7994
8058
|
var Radar = createLucideIcon("radar", [
|
|
7995
8059
|
["path", {
|
|
7996
8060
|
d: "M19.07 4.93A10 10 0 0 0 6.99 3.34",
|
|
@@ -8176,6 +8240,40 @@ var Server = createLucideIcon("server", [
|
|
|
8176
8240
|
key: "nzw8ys"
|
|
8177
8241
|
}]
|
|
8178
8242
|
]);
|
|
8243
|
+
var Share2 = createLucideIcon("share-2", [
|
|
8244
|
+
["circle", {
|
|
8245
|
+
cx: "18",
|
|
8246
|
+
cy: "5",
|
|
8247
|
+
r: "3",
|
|
8248
|
+
key: "gq8acd"
|
|
8249
|
+
}],
|
|
8250
|
+
["circle", {
|
|
8251
|
+
cx: "6",
|
|
8252
|
+
cy: "12",
|
|
8253
|
+
r: "3",
|
|
8254
|
+
key: "w7nqdw"
|
|
8255
|
+
}],
|
|
8256
|
+
["circle", {
|
|
8257
|
+
cx: "18",
|
|
8258
|
+
cy: "19",
|
|
8259
|
+
r: "3",
|
|
8260
|
+
key: "1xt0gg"
|
|
8261
|
+
}],
|
|
8262
|
+
["line", {
|
|
8263
|
+
x1: "8.59",
|
|
8264
|
+
x2: "15.42",
|
|
8265
|
+
y1: "13.51",
|
|
8266
|
+
y2: "17.49",
|
|
8267
|
+
key: "47mynk"
|
|
8268
|
+
}],
|
|
8269
|
+
["line", {
|
|
8270
|
+
x1: "15.41",
|
|
8271
|
+
x2: "8.59",
|
|
8272
|
+
y1: "6.51",
|
|
8273
|
+
y2: "10.49",
|
|
8274
|
+
key: "1n3mei"
|
|
8275
|
+
}]
|
|
8276
|
+
]);
|
|
8179
8277
|
var Shield = createLucideIcon("shield", [["path", {
|
|
8180
8278
|
d: "M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z",
|
|
8181
8279
|
key: "oel41y"
|
|
@@ -8383,6 +8481,10 @@ var TriangleAlert = createLucideIcon("triangle-alert", [
|
|
|
8383
8481
|
key: "p32p05"
|
|
8384
8482
|
}]
|
|
8385
8483
|
]);
|
|
8484
|
+
var Unlink2 = createLucideIcon("unlink-2", [["path", {
|
|
8485
|
+
d: "M15 7h2a5 5 0 0 1 0 10h-2m-6 0H7A5 5 0 0 1 7 7h2",
|
|
8486
|
+
key: "1re2ne"
|
|
8487
|
+
}]]);
|
|
8386
8488
|
var Upload = createLucideIcon("upload", [
|
|
8387
8489
|
["path", {
|
|
8388
8490
|
d: "M12 3v12",
|
|
@@ -8603,7 +8705,7 @@ var buttonVariants = cva("inline-flex items-center justify-center rounded-md fon
|
|
|
8603
8705
|
size: "sm"
|
|
8604
8706
|
}
|
|
8605
8707
|
});
|
|
8606
|
-
var Button = (0, react.forwardRef)(({ className, variant, size, ...props }, ref) => {
|
|
8708
|
+
var Button = (0, react$1.forwardRef)(({ className, variant, size, ...props }, ref) => {
|
|
8607
8709
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
8608
8710
|
ref,
|
|
8609
8711
|
className: cn(buttonVariants({
|
|
@@ -8636,7 +8738,7 @@ var iconButtonVariants = cva("inline-flex items-center justify-center rounded-md
|
|
|
8636
8738
|
size: "sm"
|
|
8637
8739
|
}
|
|
8638
8740
|
});
|
|
8639
|
-
var IconButton = (0, react.forwardRef)(({ className, variant, size, icon: Icon, ...props }, ref) => {
|
|
8741
|
+
var IconButton = (0, react$1.forwardRef)(({ className, variant, size, icon: Icon, ...props }, ref) => {
|
|
8640
8742
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
8641
8743
|
ref,
|
|
8642
8744
|
className: cn(iconButtonVariants({
|
|
@@ -8669,7 +8771,7 @@ var badgeVariants = cva("inline-flex items-center rounded-full text-xs font-medi
|
|
|
8669
8771
|
styleVariant: "solid"
|
|
8670
8772
|
}
|
|
8671
8773
|
});
|
|
8672
|
-
var Badge = (0, react.forwardRef)(({ className, variant, style, ...props }, ref) => {
|
|
8774
|
+
var Badge = (0, react$1.forwardRef)(({ className, variant, style, ...props }, ref) => {
|
|
8673
8775
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
8674
8776
|
ref,
|
|
8675
8777
|
className: cn(badgeVariants({
|
|
@@ -8689,7 +8791,7 @@ var cardVariants = cva("rounded-lg p-3", {
|
|
|
8689
8791
|
} },
|
|
8690
8792
|
defaultVariants: { variant: "bordered" }
|
|
8691
8793
|
});
|
|
8692
|
-
var Card = (0, react.forwardRef)(({ className, variant, ...props }, ref) => {
|
|
8794
|
+
var Card = (0, react$1.forwardRef)(({ className, variant, ...props }, ref) => {
|
|
8693
8795
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
8694
8796
|
ref,
|
|
8695
8797
|
className: cn(cardVariants({ variant }), className),
|
|
@@ -8725,7 +8827,7 @@ function CollapsibleCard({ expanded, onExpandedChange, header, children, dimmed
|
|
|
8725
8827
|
}
|
|
8726
8828
|
//#endregion
|
|
8727
8829
|
//#region src/primitives/label.tsx
|
|
8728
|
-
var Label = (0, react.forwardRef)(({ className, ...props }, ref) => {
|
|
8830
|
+
var Label = (0, react$1.forwardRef)(({ className, ...props }, ref) => {
|
|
8729
8831
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
8730
8832
|
ref,
|
|
8731
8833
|
className: cn("text-[10px] uppercase tracking-wider text-foreground-muted font-medium", className),
|
|
@@ -8742,7 +8844,7 @@ var separatorVariants = cva("", {
|
|
|
8742
8844
|
} },
|
|
8743
8845
|
defaultVariants: { orientation: "horizontal" }
|
|
8744
8846
|
});
|
|
8745
|
-
var Separator = (0, react.forwardRef)(({ className, orientation, ...props }, ref) => {
|
|
8847
|
+
var Separator = (0, react$1.forwardRef)(({ className, orientation, ...props }, ref) => {
|
|
8746
8848
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
8747
8849
|
ref,
|
|
8748
8850
|
role: "separator",
|
|
@@ -8753,7 +8855,7 @@ var Separator = (0, react.forwardRef)(({ className, orientation, ...props }, ref
|
|
|
8753
8855
|
Separator.displayName = "Separator";
|
|
8754
8856
|
//#endregion
|
|
8755
8857
|
//#region src/primitives/skeleton.tsx
|
|
8756
|
-
var Skeleton = (0, react.forwardRef)(({ className, ...props }, ref) => {
|
|
8858
|
+
var Skeleton = (0, react$1.forwardRef)(({ className, ...props }, ref) => {
|
|
8757
8859
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
8758
8860
|
ref,
|
|
8759
8861
|
className: cn("animate-pulse bg-surface-hover rounded-md h-4 w-full", className),
|
|
@@ -8770,7 +8872,7 @@ var inputVariants = cva("h-7 w-full px-2.5 text-xs bg-surface border rounded-md
|
|
|
8770
8872
|
} },
|
|
8771
8873
|
defaultVariants: { state: "default" }
|
|
8772
8874
|
});
|
|
8773
|
-
var Input = (0, react.forwardRef)(({ className, state, leftSlot, rightSlot, ...props }, ref) => {
|
|
8875
|
+
var Input = (0, react$1.forwardRef)(({ className, state, leftSlot, rightSlot, ...props }, ref) => {
|
|
8774
8876
|
if (leftSlot || rightSlot) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8775
8877
|
className: "relative flex items-center w-full",
|
|
8776
8878
|
children: [
|
|
@@ -8798,7 +8900,7 @@ var Input = (0, react.forwardRef)(({ className, state, leftSlot, rightSlot, ...p
|
|
|
8798
8900
|
Input.displayName = "Input";
|
|
8799
8901
|
//#endregion
|
|
8800
8902
|
//#region src/primitives/select.tsx
|
|
8801
|
-
var Select = (0, react.forwardRef)(({ className, options, ...props }, ref) => {
|
|
8903
|
+
var Select = (0, react$1.forwardRef)(({ className, options, ...props }, ref) => {
|
|
8802
8904
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8803
8905
|
className: "relative w-full",
|
|
8804
8906
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("select", {
|
|
@@ -8818,7 +8920,7 @@ var Select = (0, react.forwardRef)(({ className, options, ...props }, ref) => {
|
|
|
8818
8920
|
Select.displayName = "Select";
|
|
8819
8921
|
//#endregion
|
|
8820
8922
|
//#region src/primitives/checkbox.tsx
|
|
8821
|
-
var Checkbox = (0, react.forwardRef)(({ className, ...props }, ref) => {
|
|
8923
|
+
var Checkbox = (0, react$1.forwardRef)(({ className, ...props }, ref) => {
|
|
8822
8924
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
8823
8925
|
ref,
|
|
8824
8926
|
type: "checkbox",
|
|
@@ -8829,7 +8931,7 @@ var Checkbox = (0, react.forwardRef)(({ className, ...props }, ref) => {
|
|
|
8829
8931
|
Checkbox.displayName = "Checkbox";
|
|
8830
8932
|
//#endregion
|
|
8831
8933
|
//#region src/primitives/switch.tsx
|
|
8832
|
-
var Switch = (0, react.forwardRef)(({ className, checked, onCheckedChange, label, ...props }, ref) => {
|
|
8934
|
+
var Switch = (0, react$1.forwardRef)(({ className, checked, onCheckedChange, label, ...props }, ref) => {
|
|
8833
8935
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
8834
8936
|
ref,
|
|
8835
8937
|
role: "switch",
|
|
@@ -8850,17 +8952,17 @@ var Switch = (0, react.forwardRef)(({ className, checked, onCheckedChange, label
|
|
|
8850
8952
|
Switch.displayName = "Switch";
|
|
8851
8953
|
//#endregion
|
|
8852
8954
|
//#region src/primitives/dialog.tsx
|
|
8853
|
-
var DialogContext = (0, react.createContext)(null);
|
|
8955
|
+
var DialogContext = (0, react$1.createContext)(null);
|
|
8854
8956
|
function useDialogContext() {
|
|
8855
|
-
const ctx = (0, react.useContext)(DialogContext);
|
|
8957
|
+
const ctx = (0, react$1.useContext)(DialogContext);
|
|
8856
8958
|
if (!ctx) throw new Error("Dialog compound components must be used within <Dialog>");
|
|
8857
8959
|
return ctx;
|
|
8858
8960
|
}
|
|
8859
8961
|
function Dialog({ children, open: controlledOpen, onOpenChange }) {
|
|
8860
|
-
const [uncontrolledOpen, setUncontrolledOpen] = (0, react.useState)(false);
|
|
8962
|
+
const [uncontrolledOpen, setUncontrolledOpen] = (0, react$1.useState)(false);
|
|
8861
8963
|
const open = controlledOpen ?? uncontrolledOpen;
|
|
8862
|
-
const contentId = (0, react.useId)();
|
|
8863
|
-
const setOpen = (0, react.useCallback)((next) => {
|
|
8964
|
+
const contentId = (0, react$1.useId)();
|
|
8965
|
+
const setOpen = (0, react$1.useCallback)((next) => {
|
|
8864
8966
|
onOpenChange?.(next);
|
|
8865
8967
|
if (controlledOpen === void 0) setUncontrolledOpen(next);
|
|
8866
8968
|
}, [controlledOpen, onOpenChange]);
|
|
@@ -8890,11 +8992,11 @@ var contentVariants = cva("bg-background-elevated border border-border rounded-l
|
|
|
8890
8992
|
} },
|
|
8891
8993
|
defaultVariants: { width: "md" }
|
|
8892
8994
|
});
|
|
8893
|
-
var DialogContent = (0, react.forwardRef)(({ className, width, children, ...props }, ref) => {
|
|
8995
|
+
var DialogContent = (0, react$1.forwardRef)(({ className, width, children, ...props }, ref) => {
|
|
8894
8996
|
const { open, setOpen, contentId } = useDialogContext();
|
|
8895
|
-
const innerRef = (0, react.useRef)(null);
|
|
8997
|
+
const innerRef = (0, react$1.useRef)(null);
|
|
8896
8998
|
const dialogRef = ref ?? innerRef;
|
|
8897
|
-
(0, react.useEffect)(() => {
|
|
8999
|
+
(0, react$1.useEffect)(() => {
|
|
8898
9000
|
const el = dialogRef.current;
|
|
8899
9001
|
if (!el) return;
|
|
8900
9002
|
if (open && !el.open) el.showModal();
|
|
@@ -8940,17 +9042,17 @@ function DialogDescription({ className, ...props }) {
|
|
|
8940
9042
|
}
|
|
8941
9043
|
//#endregion
|
|
8942
9044
|
//#region src/primitives/dropdown.tsx
|
|
8943
|
-
var DropdownContext = (0, react.createContext)(null);
|
|
9045
|
+
var DropdownContext = (0, react$1.createContext)(null);
|
|
8944
9046
|
function useDropdownContext() {
|
|
8945
|
-
const ctx = (0, react.useContext)(DropdownContext);
|
|
9047
|
+
const ctx = (0, react$1.useContext)(DropdownContext);
|
|
8946
9048
|
if (!ctx) throw new Error("Dropdown compound components must be used within <Dropdown>");
|
|
8947
9049
|
return ctx;
|
|
8948
9050
|
}
|
|
8949
9051
|
function Dropdown({ children }) {
|
|
8950
|
-
const [open, setOpen] = (0, react.useState)(false);
|
|
8951
|
-
const triggerId = (0, react.useId)();
|
|
8952
|
-
const contentId = (0, react.useId)();
|
|
8953
|
-
const triggerRef = (0, react.useRef)(null);
|
|
9052
|
+
const [open, setOpen] = (0, react$1.useState)(false);
|
|
9053
|
+
const triggerId = (0, react$1.useId)();
|
|
9054
|
+
const contentId = (0, react$1.useId)();
|
|
9055
|
+
const triggerRef = (0, react$1.useRef)(null);
|
|
8954
9056
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DropdownContext.Provider, {
|
|
8955
9057
|
value: {
|
|
8956
9058
|
open,
|
|
@@ -8981,9 +9083,9 @@ function DropdownTrigger({ children, ...props }) {
|
|
|
8981
9083
|
}
|
|
8982
9084
|
function DropdownContent({ className, children, align = "start", offset = 4, ...props }) {
|
|
8983
9085
|
const { open, setOpen, contentId, triggerId, triggerRef } = useDropdownContext();
|
|
8984
|
-
const ref = (0, react.useRef)(null);
|
|
8985
|
-
const [coords, setCoords] = (0, react.useState)(null);
|
|
8986
|
-
(0, react.useLayoutEffect)(() => {
|
|
9086
|
+
const ref = (0, react$1.useRef)(null);
|
|
9087
|
+
const [coords, setCoords] = (0, react$1.useState)(null);
|
|
9088
|
+
(0, react$1.useLayoutEffect)(() => {
|
|
8987
9089
|
if (!open) {
|
|
8988
9090
|
setCoords(null);
|
|
8989
9091
|
return;
|
|
@@ -9012,7 +9114,7 @@ function DropdownContent({ className, children, align = "start", offset = 4, ...
|
|
|
9012
9114
|
offset,
|
|
9013
9115
|
triggerRef
|
|
9014
9116
|
]);
|
|
9015
|
-
(0, react.useEffect)(() => {
|
|
9117
|
+
(0, react$1.useEffect)(() => {
|
|
9016
9118
|
if (!open) return;
|
|
9017
9119
|
const handler = (e) => {
|
|
9018
9120
|
const el = ref.current;
|
|
@@ -9052,7 +9154,7 @@ function DropdownContent({ className, children, align = "start", offset = 4, ...
|
|
|
9052
9154
|
}
|
|
9053
9155
|
function DropdownItem({ className, icon: Icon, variant = "default", children, onClick, ...props }) {
|
|
9054
9156
|
const { setOpen } = useDropdownContext();
|
|
9055
|
-
const handleClick = (0, react.useCallback)((e) => {
|
|
9157
|
+
const handleClick = (0, react$1.useCallback)((e) => {
|
|
9056
9158
|
onClick?.(e);
|
|
9057
9159
|
setOpen(false);
|
|
9058
9160
|
}, [onClick, setOpen]);
|
|
@@ -9067,16 +9169,16 @@ function DropdownItem({ className, icon: Icon, variant = "default", children, on
|
|
|
9067
9169
|
}
|
|
9068
9170
|
//#endregion
|
|
9069
9171
|
//#region src/primitives/tooltip.tsx
|
|
9070
|
-
var TooltipContext = (0, react.createContext)(null);
|
|
9172
|
+
var TooltipContext = (0, react$1.createContext)(null);
|
|
9071
9173
|
function useTooltipContext() {
|
|
9072
|
-
const ctx = (0, react.useContext)(TooltipContext);
|
|
9174
|
+
const ctx = (0, react$1.useContext)(TooltipContext);
|
|
9073
9175
|
if (!ctx) throw new Error("Tooltip compound components must be used within <Tooltip>");
|
|
9074
9176
|
return ctx;
|
|
9075
9177
|
}
|
|
9076
9178
|
function Tooltip({ children }) {
|
|
9077
|
-
const [open, setOpen] = (0, react.useState)(false);
|
|
9078
|
-
const timerRef = (0, react.useRef)(null);
|
|
9079
|
-
const tooltipId = (0, react.useId)();
|
|
9179
|
+
const [open, setOpen] = (0, react$1.useState)(false);
|
|
9180
|
+
const timerRef = (0, react$1.useRef)(null);
|
|
9181
|
+
const tooltipId = (0, react$1.useId)();
|
|
9080
9182
|
const show = () => {
|
|
9081
9183
|
timerRef.current = setTimeout(() => setOpen(true), 300);
|
|
9082
9184
|
};
|
|
@@ -9143,7 +9245,7 @@ function getServerSnapshot() {
|
|
|
9143
9245
|
return false;
|
|
9144
9246
|
}
|
|
9145
9247
|
function useIsMobile() {
|
|
9146
|
-
return (0, react.useSyncExternalStore)(subscribeQuery(MOBILE_QUERY), getSnapshot(MOBILE_QUERY), getServerSnapshot);
|
|
9248
|
+
return (0, react$1.useSyncExternalStore)(subscribeQuery(MOBILE_QUERY), getSnapshot(MOBILE_QUERY), getServerSnapshot);
|
|
9147
9249
|
}
|
|
9148
9250
|
/**
|
|
9149
9251
|
* True when the viewport is in the medium (`md`) Tailwind range —
|
|
@@ -9152,12 +9254,12 @@ function useIsMobile() {
|
|
|
9152
9254
|
* sidebar rail, narrower stat tiles).
|
|
9153
9255
|
*/
|
|
9154
9256
|
function useIsMidWidth() {
|
|
9155
|
-
return (0, react.useSyncExternalStore)(subscribeQuery(MID_QUERY), getSnapshot(MID_QUERY), getServerSnapshot);
|
|
9257
|
+
return (0, react$1.useSyncExternalStore)(subscribeQuery(MID_QUERY), getSnapshot(MID_QUERY), getServerSnapshot);
|
|
9156
9258
|
}
|
|
9157
9259
|
//#endregion
|
|
9158
9260
|
//#region src/primitives/bottom-sheet.tsx
|
|
9159
9261
|
function BottomSheet({ open, onClose, title, children, className }) {
|
|
9160
|
-
(0, react.useEffect)(() => {
|
|
9262
|
+
(0, react$1.useEffect)(() => {
|
|
9161
9263
|
if (!open) return;
|
|
9162
9264
|
const handleKeyDown = (e) => {
|
|
9163
9265
|
if (e.key === "Escape") onClose();
|
|
@@ -9202,18 +9304,18 @@ function BottomSheet({ open, onClose, title, children, className }) {
|
|
|
9202
9304
|
}
|
|
9203
9305
|
//#endregion
|
|
9204
9306
|
//#region src/primitives/popover.tsx
|
|
9205
|
-
var PopoverContext = (0, react.createContext)(null);
|
|
9307
|
+
var PopoverContext = (0, react$1.createContext)(null);
|
|
9206
9308
|
function usePopoverContext() {
|
|
9207
|
-
const ctx = (0, react.useContext)(PopoverContext);
|
|
9309
|
+
const ctx = (0, react$1.useContext)(PopoverContext);
|
|
9208
9310
|
if (!ctx) throw new Error("Popover compound components must be used within <Popover>");
|
|
9209
9311
|
return ctx;
|
|
9210
9312
|
}
|
|
9211
9313
|
function Popover({ children, open: controlledOpen, onOpenChange }) {
|
|
9212
|
-
const [uncontrolledOpen, setUncontrolledOpen] = (0, react.useState)(false);
|
|
9314
|
+
const [uncontrolledOpen, setUncontrolledOpen] = (0, react$1.useState)(false);
|
|
9213
9315
|
const open = controlledOpen ?? uncontrolledOpen;
|
|
9214
|
-
const triggerId = (0, react.useId)();
|
|
9215
|
-
const contentId = (0, react.useId)();
|
|
9216
|
-
const setOpen = (0, react.useCallback)((next) => {
|
|
9316
|
+
const triggerId = (0, react$1.useId)();
|
|
9317
|
+
const contentId = (0, react$1.useId)();
|
|
9318
|
+
const setOpen = (0, react$1.useCallback)((next) => {
|
|
9217
9319
|
onOpenChange?.(next);
|
|
9218
9320
|
if (controlledOpen === void 0) setUncontrolledOpen(next);
|
|
9219
9321
|
}, [controlledOpen, onOpenChange]);
|
|
@@ -9246,8 +9348,8 @@ function PopoverTrigger({ children, ...props }) {
|
|
|
9246
9348
|
function PopoverContent({ className, children, ...props }) {
|
|
9247
9349
|
const { open, setOpen, contentId, triggerId } = usePopoverContext();
|
|
9248
9350
|
const isMobile = useIsMobile();
|
|
9249
|
-
const ref = (0, react.useRef)(null);
|
|
9250
|
-
(0, react.useEffect)(() => {
|
|
9351
|
+
const ref = (0, react$1.useRef)(null);
|
|
9352
|
+
(0, react$1.useEffect)(() => {
|
|
9251
9353
|
if (!open || isMobile) return;
|
|
9252
9354
|
const handler = (e) => {
|
|
9253
9355
|
const el = ref.current;
|
|
@@ -9287,16 +9389,16 @@ function PopoverContent({ className, children, ...props }) {
|
|
|
9287
9389
|
}
|
|
9288
9390
|
//#endregion
|
|
9289
9391
|
//#region src/primitives/tabs.tsx
|
|
9290
|
-
var TabsContext = (0, react.createContext)(null);
|
|
9392
|
+
var TabsContext = (0, react$1.createContext)(null);
|
|
9291
9393
|
function useTabsContext() {
|
|
9292
|
-
const ctx = (0, react.useContext)(TabsContext);
|
|
9394
|
+
const ctx = (0, react$1.useContext)(TabsContext);
|
|
9293
9395
|
if (!ctx) throw new Error("Tabs compound components must be used within <Tabs>");
|
|
9294
9396
|
return ctx;
|
|
9295
9397
|
}
|
|
9296
9398
|
function Tabs({ value: controlledValue, onValueChange, defaultValue = "", className, ...props }) {
|
|
9297
|
-
const [uncontrolledValue, setUncontrolledValue] = (0, react.useState)(defaultValue);
|
|
9399
|
+
const [uncontrolledValue, setUncontrolledValue] = (0, react$1.useState)(defaultValue);
|
|
9298
9400
|
const value = controlledValue ?? uncontrolledValue;
|
|
9299
|
-
const setValue = (0, react.useCallback)((next) => {
|
|
9401
|
+
const setValue = (0, react$1.useCallback)((next) => {
|
|
9300
9402
|
onValueChange?.(next);
|
|
9301
9403
|
if (controlledValue === void 0) setUncontrolledValue(next);
|
|
9302
9404
|
}, [controlledValue, onValueChange]);
|
|
@@ -9344,7 +9446,7 @@ function TabsContent({ value, className, ...props }) {
|
|
|
9344
9446
|
}
|
|
9345
9447
|
//#endregion
|
|
9346
9448
|
//#region src/primitives/scroll-area.tsx
|
|
9347
|
-
var ScrollArea = (0, react.forwardRef)(({ className, ...props }, ref) => {
|
|
9449
|
+
var ScrollArea = (0, react$1.forwardRef)(({ className, ...props }, ref) => {
|
|
9348
9450
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
9349
9451
|
ref,
|
|
9350
9452
|
className: cn("overflow-auto [&::-webkit-scrollbar]:w-1 [&::-webkit-scrollbar-track]:bg-transparent [&::-webkit-scrollbar-thumb]:bg-surface-hover [&::-webkit-scrollbar-thumb]:rounded-full", className),
|
|
@@ -9355,23 +9457,23 @@ ScrollArea.displayName = "ScrollArea";
|
|
|
9355
9457
|
//#endregion
|
|
9356
9458
|
//#region src/primitives/floating-panel.tsx
|
|
9357
9459
|
function FloatingPanel({ title, onClose, children, defaultWidth = 360, defaultHeight = 280, minWidth = 280, minHeight = 160, offsetIndex = 0, className }) {
|
|
9358
|
-
const [pos, setPos] = (0, react.useState)({
|
|
9460
|
+
const [pos, setPos] = (0, react$1.useState)({
|
|
9359
9461
|
x: 80 + offsetIndex * 30,
|
|
9360
9462
|
y: 80 + offsetIndex * 30
|
|
9361
9463
|
});
|
|
9362
|
-
const [size, setSize] = (0, react.useState)({
|
|
9464
|
+
const [size, setSize] = (0, react$1.useState)({
|
|
9363
9465
|
w: defaultWidth,
|
|
9364
9466
|
h: defaultHeight
|
|
9365
9467
|
});
|
|
9366
|
-
const [minimized, setMinimized] = (0, react.useState)(false);
|
|
9367
|
-
const dragging = (0, react.useRef)(false);
|
|
9368
|
-
const resizing = (0, react.useRef)(false);
|
|
9369
|
-
const offset = (0, react.useRef)({
|
|
9468
|
+
const [minimized, setMinimized] = (0, react$1.useState)(false);
|
|
9469
|
+
const dragging = (0, react$1.useRef)(false);
|
|
9470
|
+
const resizing = (0, react$1.useRef)(false);
|
|
9471
|
+
const offset = (0, react$1.useRef)({
|
|
9370
9472
|
x: 0,
|
|
9371
9473
|
y: 0
|
|
9372
9474
|
});
|
|
9373
9475
|
const isMobile = useIsMobile();
|
|
9374
|
-
const onDragStart = (0, react.useCallback)((e) => {
|
|
9476
|
+
const onDragStart = (0, react$1.useCallback)((e) => {
|
|
9375
9477
|
e.preventDefault();
|
|
9376
9478
|
dragging.current = true;
|
|
9377
9479
|
offset.current = {
|
|
@@ -9379,7 +9481,7 @@ function FloatingPanel({ title, onClose, children, defaultWidth = 360, defaultHe
|
|
|
9379
9481
|
y: e.clientY - pos.y
|
|
9380
9482
|
};
|
|
9381
9483
|
}, [pos]);
|
|
9382
|
-
const onResizeStart = (0, react.useCallback)((e) => {
|
|
9484
|
+
const onResizeStart = (0, react$1.useCallback)((e) => {
|
|
9383
9485
|
e.preventDefault();
|
|
9384
9486
|
e.stopPropagation();
|
|
9385
9487
|
resizing.current = true;
|
|
@@ -9388,7 +9490,7 @@ function FloatingPanel({ title, onClose, children, defaultWidth = 360, defaultHe
|
|
|
9388
9490
|
y: e.clientY
|
|
9389
9491
|
};
|
|
9390
9492
|
}, []);
|
|
9391
|
-
(0, react.useEffect)(() => {
|
|
9493
|
+
(0, react$1.useEffect)(() => {
|
|
9392
9494
|
const onMouseMove = (e) => {
|
|
9393
9495
|
if (dragging.current) setPos({
|
|
9394
9496
|
x: e.clientX - offset.current.x,
|
|
@@ -9493,8 +9595,8 @@ function FloatingPanel({ title, onClose, children, defaultWidth = 360, defaultHe
|
|
|
9493
9595
|
//#endregion
|
|
9494
9596
|
//#region src/primitives/mobile-drawer.tsx
|
|
9495
9597
|
function MobileDrawer({ open, onClose, children, className, width = "w-64" }) {
|
|
9496
|
-
const drawerRef = (0, react.useRef)(null);
|
|
9497
|
-
(0, react.useEffect)(() => {
|
|
9598
|
+
const drawerRef = (0, react$1.useRef)(null);
|
|
9599
|
+
(0, react$1.useEffect)(() => {
|
|
9498
9600
|
if (!open) return;
|
|
9499
9601
|
const handleKeyDown = (e) => {
|
|
9500
9602
|
if (e.key === "Escape") onClose();
|
|
@@ -9538,7 +9640,7 @@ function Breadcrumb({ items, className }) {
|
|
|
9538
9640
|
children: items.map((item, i) => {
|
|
9539
9641
|
const isLast = i === items.length - 1;
|
|
9540
9642
|
const isClickable = !isLast && (item.onClick || item.href);
|
|
9541
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react.default.Fragment, { children: [i > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ChevronRight, { className: "h-3 w-3 flex-shrink-0" }), isClickable ? item.onClick ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
9643
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react$1.default.Fragment, { children: [i > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ChevronRight, { className: "h-3 w-3 flex-shrink-0" }), isClickable ? item.onClick ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
9542
9644
|
type: "button",
|
|
9543
9645
|
onClick: item.onClick,
|
|
9544
9646
|
className: "hover:text-foreground transition-colors",
|
|
@@ -9614,7 +9716,7 @@ function DataTable({ columns, rows, rowKey, onRowClick, minWidthPx = 480, emptyM
|
|
|
9614
9716
|
//#endregion
|
|
9615
9717
|
//#region src/composites/slide-over-panel.tsx
|
|
9616
9718
|
function SlideOverPanel({ open, onClose, title, subtitle, footer, children, widthClass = "w-[360px]" }) {
|
|
9617
|
-
(0, react.useEffect)(() => {
|
|
9719
|
+
(0, react$1.useEffect)(() => {
|
|
9618
9720
|
if (!open) return;
|
|
9619
9721
|
const onEsc = (e) => {
|
|
9620
9722
|
if (e.key === "Escape") onClose();
|
|
@@ -9757,7 +9859,7 @@ function modelsForStep(schema) {
|
|
|
9757
9859
|
}));
|
|
9758
9860
|
}
|
|
9759
9861
|
function PipelineStep({ step, schema, allSchemas: _allSchemas, depth: _depth = 0, onChange, onDelete: _onDelete, readOnly = false, toggleMode = "simple", overrideState = null, onOverrideChange, inheritedEnabled, hideModelAndSettings = false }) {
|
|
9760
|
-
const [expanded, setExpanded] = (0, react.useState)(false);
|
|
9862
|
+
const [expanded, setExpanded] = (0, react$1.useState)(false);
|
|
9761
9863
|
const models = modelsForStep(schema);
|
|
9762
9864
|
if (models.length > 0 && !models.some((m) => m.id === step.modelId) && !readOnly) {
|
|
9763
9865
|
const fallback = (schema?.defaultModelId ? models.find((m) => m.id === schema.defaultModelId) : null) ?? models[0];
|
|
@@ -10308,7 +10410,7 @@ function DeviceModeEditor({ addon, agentDefault, agentNodeId, currentPatch, mode
|
|
|
10308
10410
|
}
|
|
10309
10411
|
function AgentStepEditor(props) {
|
|
10310
10412
|
const { mode, addon, agentDefault, agentNodeId, currentPatch, onChangeAgentConfig, onChangePatch, engineFormat } = props;
|
|
10311
|
-
const modelsForFormat = (0, react.useMemo)(() => addon.models.filter((m) => Boolean(m.formats[engineFormat])), [addon.models, engineFormat]);
|
|
10413
|
+
const modelsForFormat = (0, react$1.useMemo)(() => addon.models.filter((m) => Boolean(m.formats[engineFormat])), [addon.models, engineFormat]);
|
|
10312
10414
|
if (mode === "agent") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AgentModeEditor, {
|
|
10313
10415
|
addon,
|
|
10314
10416
|
agentDefault,
|
|
@@ -10458,7 +10560,7 @@ function Row({ node, depth, agents, getCellState, onCellClick, selectedCell, tog
|
|
|
10458
10560
|
})] });
|
|
10459
10561
|
}
|
|
10460
10562
|
function PipelineTreeMatrix({ tree, agents, getCellState, onCellClick, selectedCell, onToggleEnabled }) {
|
|
10461
|
-
const rows = (0, react.useMemo)(() => flattenTree(tree), [tree]);
|
|
10563
|
+
const rows = (0, react$1.useMemo)(() => flattenTree(tree), [tree]);
|
|
10462
10564
|
const gridTemplate = `minmax(320px, 1fr) repeat(${agents.length}, minmax(160px, 220px))`;
|
|
10463
10565
|
const showToggle = onToggleEnabled !== void 0 && agents.length === 1;
|
|
10464
10566
|
const onlyAgent = agents[0]?.agentNodeId;
|
|
@@ -10564,7 +10666,7 @@ function SystemProvider({ system, children }) {
|
|
|
10564
10666
|
* relies on the system, so a clear error beats a silent null.
|
|
10565
10667
|
*/
|
|
10566
10668
|
function useSystem() {
|
|
10567
|
-
const sys = (0, react.useContext)(SystemContext);
|
|
10669
|
+
const sys = (0, react$1.useContext)(SystemContext);
|
|
10568
10670
|
if (!sys) throw new Error("useSystem(): no <SystemProvider> in tree");
|
|
10569
10671
|
return sys;
|
|
10570
10672
|
}
|
|
@@ -10574,7 +10676,7 @@ function useSystem() {
|
|
|
10574
10676
|
* (boot-time splash screens etc.).
|
|
10575
10677
|
*/
|
|
10576
10678
|
function useOptionalSystem() {
|
|
10577
|
-
return (0, react.useContext)(SystemContext);
|
|
10679
|
+
return (0, react$1.useContext)(SystemContext);
|
|
10578
10680
|
}
|
|
10579
10681
|
//#endregion
|
|
10580
10682
|
//#region src/hooks/use-live-event.ts
|
|
@@ -10590,15 +10692,15 @@ function useOptionalSystem() {
|
|
|
10590
10692
|
*/
|
|
10591
10693
|
function useLiveEvent(category, cb) {
|
|
10592
10694
|
const system = useSystem();
|
|
10593
|
-
const cbRef = (0, react.useRef)(cb);
|
|
10695
|
+
const cbRef = (0, react$1.useRef)(cb);
|
|
10594
10696
|
cbRef.current = cb;
|
|
10595
|
-
const [tick, setTick] = (0, react.useState)(system.connectionVersion);
|
|
10596
|
-
(0, react.useEffect)(() => {
|
|
10697
|
+
const [tick, setTick] = (0, react$1.useState)(system.connectionVersion);
|
|
10698
|
+
(0, react$1.useEffect)(() => {
|
|
10597
10699
|
return system.subscribeConnectionEvents((state, version) => {
|
|
10598
10700
|
if (state === "connected") setTick(version);
|
|
10599
10701
|
});
|
|
10600
10702
|
}, [system]);
|
|
10601
|
-
(0, react.useEffect)(() => {
|
|
10703
|
+
(0, react$1.useEffect)(() => {
|
|
10602
10704
|
return system.subscribeEvent(category, (evt) => {
|
|
10603
10705
|
cbRef.current(evt);
|
|
10604
10706
|
});
|
|
@@ -10617,12 +10719,12 @@ function useLiveEvent(category, cb) {
|
|
|
10617
10719
|
* useEventStreamMap — same but accumulates per-key payloads into a map.
|
|
10618
10720
|
*/
|
|
10619
10721
|
function useFreshRef(value) {
|
|
10620
|
-
const ref = (0, react.useRef)(value);
|
|
10722
|
+
const ref = (0, react$1.useRef)(value);
|
|
10621
10723
|
ref.current = value;
|
|
10622
10724
|
return ref;
|
|
10623
10725
|
}
|
|
10624
10726
|
function useEventStreamLatest(category, filter) {
|
|
10625
|
-
const [data, setData] = (0, react.useState)(null);
|
|
10727
|
+
const [data, setData] = (0, react$1.useState)(null);
|
|
10626
10728
|
const filterRef = useFreshRef(filter);
|
|
10627
10729
|
useLiveEvent(category, (evt) => {
|
|
10628
10730
|
const payload = evt.data;
|
|
@@ -10633,7 +10735,7 @@ function useEventStreamLatest(category, filter) {
|
|
|
10633
10735
|
return data;
|
|
10634
10736
|
}
|
|
10635
10737
|
function useEventStreamMap(category, keyOf, filter) {
|
|
10636
|
-
const [map, setMap] = (0, react.useState)(() => /* @__PURE__ */ new Map());
|
|
10738
|
+
const [map, setMap] = (0, react$1.useState)(() => /* @__PURE__ */ new Map());
|
|
10637
10739
|
const keyOfRef = useFreshRef(keyOf);
|
|
10638
10740
|
const filterRef = useFreshRef(filter);
|
|
10639
10741
|
useLiveEvent(category, (evt) => {
|
|
@@ -10649,7 +10751,7 @@ function useEventStreamMap(category, keyOf, filter) {
|
|
|
10649
10751
|
});
|
|
10650
10752
|
return {
|
|
10651
10753
|
map,
|
|
10652
|
-
values: (0, react.useMemo)(() => Array.from(map.values()), [map])
|
|
10754
|
+
values: (0, react$1.useMemo)(() => Array.from(map.values()), [map])
|
|
10653
10755
|
};
|
|
10654
10756
|
}
|
|
10655
10757
|
//#endregion
|
|
@@ -10669,7 +10771,7 @@ function useClusterNodes() {
|
|
|
10669
10771
|
const { data: bootstrapTopology, isLoading } = trpc.nodes.topology.useQuery(void 0, { staleTime: 6e4 });
|
|
10670
10772
|
const sourceNodes = useEventStreamLatest("cluster.topology-snapshot")?.nodes ?? bootstrapTopology;
|
|
10671
10773
|
return {
|
|
10672
|
-
nodes: (0, react.useMemo)(() => {
|
|
10774
|
+
nodes: (0, react$1.useMemo)(() => {
|
|
10673
10775
|
const list = [];
|
|
10674
10776
|
for (const n of sourceNodes ?? []) list.push({
|
|
10675
10777
|
id: String(n.id ?? ""),
|
|
@@ -10803,7 +10905,7 @@ function ProviderBadge({ provider, showLabel = true, className }) {
|
|
|
10803
10905
|
}
|
|
10804
10906
|
//#endregion
|
|
10805
10907
|
//#region src/composites/version-badge.tsx
|
|
10806
|
-
var VARIANT_STYLES = {
|
|
10908
|
+
var VARIANT_STYLES$1 = {
|
|
10807
10909
|
success: "bg-emerald-400 text-emerald-950",
|
|
10808
10910
|
warning: "bg-amber-400 text-amber-950",
|
|
10809
10911
|
danger: "bg-red-400 text-red-950",
|
|
@@ -10816,7 +10918,7 @@ var VARIANT_STYLES = {
|
|
|
10816
10918
|
*/
|
|
10817
10919
|
function SemanticBadge({ children, variant = "neutral", mono, className }) {
|
|
10818
10920
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
10819
|
-
className: cn("inline-flex items-center rounded-md px-2 py-0.5 text-[11px] font-bold leading-tight", mono && "font-mono", VARIANT_STYLES[variant], className),
|
|
10921
|
+
className: cn("inline-flex items-center rounded-md px-2 py-0.5 text-[11px] font-bold leading-tight", mono && "font-mono", VARIANT_STYLES$1[variant], className),
|
|
10820
10922
|
children
|
|
10821
10923
|
});
|
|
10822
10924
|
}
|
|
@@ -10905,16 +11007,65 @@ function EmptyState({ icon: Icon, title, description, action, className }) {
|
|
|
10905
11007
|
});
|
|
10906
11008
|
}
|
|
10907
11009
|
//#endregion
|
|
11010
|
+
//#region src/composites/error-box.tsx
|
|
11011
|
+
var VARIANT_STYLES = {
|
|
11012
|
+
danger: {
|
|
11013
|
+
box: "border-danger/40 bg-danger/10",
|
|
11014
|
+
icon: "text-danger",
|
|
11015
|
+
title: "text-danger",
|
|
11016
|
+
message: "text-danger"
|
|
11017
|
+
},
|
|
11018
|
+
warning: {
|
|
11019
|
+
box: "border-amber-500/40 bg-amber-500/10",
|
|
11020
|
+
icon: "text-amber-600 dark:text-amber-400",
|
|
11021
|
+
title: "text-amber-700 dark:text-amber-300",
|
|
11022
|
+
message: "text-amber-700 dark:text-amber-300"
|
|
11023
|
+
}
|
|
11024
|
+
};
|
|
11025
|
+
function ErrorBox({ message, title, onRetry, action, variant = "danger", className }) {
|
|
11026
|
+
const styles = VARIANT_STYLES[variant];
|
|
11027
|
+
const Icon = variant === "warning" ? TriangleAlert : CircleAlert;
|
|
11028
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
11029
|
+
role: "alert",
|
|
11030
|
+
className: cn("flex items-start gap-2.5 rounded border px-3 py-2.5", styles.box, className),
|
|
11031
|
+
children: [
|
|
11032
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Icon, {
|
|
11033
|
+
className: cn("h-4 w-4 mt-0.5 shrink-0", styles.icon),
|
|
11034
|
+
"aria-hidden": "true"
|
|
11035
|
+
}),
|
|
11036
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
11037
|
+
className: "flex-1 min-w-0",
|
|
11038
|
+
children: [title && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
11039
|
+
className: cn("text-xs font-semibold", styles.title),
|
|
11040
|
+
children: title
|
|
11041
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
11042
|
+
className: cn("text-xs break-words", styles.message, title ? "mt-0.5" : ""),
|
|
11043
|
+
children: message
|
|
11044
|
+
})]
|
|
11045
|
+
}),
|
|
11046
|
+
action ?? (onRetry && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
11047
|
+
type: "button",
|
|
11048
|
+
onClick: onRetry,
|
|
11049
|
+
className: cn("shrink-0 inline-flex items-center gap-1 rounded px-2 py-1 text-[11px] font-medium", "border border-current/30 hover:bg-current/10 transition-colors", styles.message),
|
|
11050
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(RefreshCw, {
|
|
11051
|
+
className: "h-3 w-3",
|
|
11052
|
+
"aria-hidden": "true"
|
|
11053
|
+
}), "Retry"]
|
|
11054
|
+
}))
|
|
11055
|
+
]
|
|
11056
|
+
});
|
|
11057
|
+
}
|
|
11058
|
+
//#endregion
|
|
10908
11059
|
//#region src/composites/confirm-dialog.tsx
|
|
10909
11060
|
var ConfirmContext = createSharedContext("camstack:confirm-dialog", null);
|
|
10910
11061
|
function useConfirm() {
|
|
10911
|
-
const ctx = (0, react.useContext)(ConfirmContext);
|
|
11062
|
+
const ctx = (0, react$1.useContext)(ConfirmContext);
|
|
10912
11063
|
if (!ctx) throw new Error("useConfirm must be used within ConfirmDialogProvider");
|
|
10913
11064
|
return ctx.confirm;
|
|
10914
11065
|
}
|
|
10915
11066
|
function ConfirmDialogProvider({ children }) {
|
|
10916
|
-
const [dialog, setDialog] = (0, react.useState)(null);
|
|
10917
|
-
const confirm = (0, react.useCallback)((options) => {
|
|
11067
|
+
const [dialog, setDialog] = (0, react$1.useState)(null);
|
|
11068
|
+
const confirm = (0, react$1.useCallback)((options) => {
|
|
10918
11069
|
return new Promise((resolve) => {
|
|
10919
11070
|
setDialog({
|
|
10920
11071
|
...options,
|
|
@@ -11026,8 +11177,8 @@ function KeyValueList({ items, className }) {
|
|
|
11026
11177
|
//#endregion
|
|
11027
11178
|
//#region src/composites/code-block.tsx
|
|
11028
11179
|
function CodeBlock({ children, maxHeight = 300, className }) {
|
|
11029
|
-
const [copied, setCopied] = (0, react.useState)(false);
|
|
11030
|
-
const handleCopy = (0, react.useCallback)(() => {
|
|
11180
|
+
const [copied, setCopied] = (0, react$1.useState)(false);
|
|
11181
|
+
const handleCopy = (0, react$1.useCallback)(() => {
|
|
11031
11182
|
navigator.clipboard.writeText(children).then(() => {
|
|
11032
11183
|
setCopied(true);
|
|
11033
11184
|
setTimeout(() => setCopied(false), 2e3);
|
|
@@ -11057,7 +11208,7 @@ function CodeBlock({ children, maxHeight = 300, className }) {
|
|
|
11057
11208
|
//#region src/composites/filter-bar.tsx
|
|
11058
11209
|
function FilterBar({ filters, values, onChange, className }) {
|
|
11059
11210
|
const isMobile = useIsMobile();
|
|
11060
|
-
const [sheetOpen, setSheetOpen] = (0, react.useState)(false);
|
|
11211
|
+
const [sheetOpen, setSheetOpen] = (0, react$1.useState)(false);
|
|
11061
11212
|
const handleChange = (key, value) => {
|
|
11062
11213
|
onChange({
|
|
11063
11214
|
...values,
|
|
@@ -11222,7 +11373,7 @@ function Sidebar({ logo, sections, footer, onNavigate, className }) {
|
|
|
11222
11373
|
//#region src/composites/app-shell/app-shell.tsx
|
|
11223
11374
|
function AppShell({ sidebar, header, mobileLogo, mobileActions, children, className }) {
|
|
11224
11375
|
const isMobile = useIsMobile();
|
|
11225
|
-
const [drawerOpen, setDrawerOpen] = (0, react.useState)(false);
|
|
11376
|
+
const [drawerOpen, setDrawerOpen] = (0, react$1.useState)(false);
|
|
11226
11377
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
11227
11378
|
className: cn("flex h-screen", className),
|
|
11228
11379
|
children: [
|
|
@@ -11408,8 +11559,8 @@ var BINDING_CHANGED_CATEGORY = "capability.binding-changed";
|
|
|
11408
11559
|
* when `deviceId` is null. Re-rendered when bindings change.
|
|
11409
11560
|
*/
|
|
11410
11561
|
function useDeviceProxy(trpc, deviceId) {
|
|
11411
|
-
const [binding, setBinding] = (0, react.useState)(null);
|
|
11412
|
-
(0, react.useEffect)(() => {
|
|
11562
|
+
const [binding, setBinding] = (0, react$1.useState)(null);
|
|
11563
|
+
(0, react$1.useEffect)(() => {
|
|
11413
11564
|
if (deviceId === null) {
|
|
11414
11565
|
setBinding(null);
|
|
11415
11566
|
return;
|
|
@@ -11437,7 +11588,7 @@ function useDeviceProxy(trpc, deviceId) {
|
|
|
11437
11588
|
sub?.unsubscribe();
|
|
11438
11589
|
};
|
|
11439
11590
|
}, [trpc, deviceId]);
|
|
11440
|
-
return (0, react.useMemo)(() => {
|
|
11591
|
+
return (0, react$1.useMemo)(() => {
|
|
11441
11592
|
if (!binding) return null;
|
|
11442
11593
|
return (0, _camstack_types.createDeviceProxy)(trpc, binding);
|
|
11443
11594
|
}, [trpc, binding]);
|
|
@@ -11461,12 +11612,12 @@ function useDeviceProxy(trpc, deviceId) {
|
|
|
11461
11612
|
* de-dups identical pushes).
|
|
11462
11613
|
*/
|
|
11463
11614
|
function useDeviceStateSlice(handle) {
|
|
11464
|
-
const subscribe = (0, react.useCallback)((notify) => {
|
|
11615
|
+
const subscribe = (0, react$1.useCallback)((notify) => {
|
|
11465
11616
|
if (!handle) return () => void 0;
|
|
11466
11617
|
return handle.subscribe(() => notify());
|
|
11467
11618
|
}, [handle]);
|
|
11468
|
-
const getSnapshot = (0, react.useCallback)(() => handle?.value, [handle]);
|
|
11469
|
-
return (0, react.useSyncExternalStore)(subscribe, getSnapshot, getSnapshot);
|
|
11619
|
+
const getSnapshot = (0, react$1.useCallback)(() => handle?.value, [handle]);
|
|
11620
|
+
return (0, react$1.useSyncExternalStore)(subscribe, getSnapshot, getSnapshot);
|
|
11470
11621
|
}
|
|
11471
11622
|
/**
|
|
11472
11623
|
* One-line combinator — collapse the common
|
|
@@ -11751,7 +11902,7 @@ function ChildSwitchToggle({ trpc, deviceId }) {
|
|
|
11751
11902
|
cap: (d) => d.switch,
|
|
11752
11903
|
slice: (d) => d.state.switch
|
|
11753
11904
|
});
|
|
11754
|
-
const [pending, setPending] = (0, react.useState)(false);
|
|
11905
|
+
const [pending, setPending] = (0, react$1.useState)(false);
|
|
11755
11906
|
if (dev !== null && !cap) return null;
|
|
11756
11907
|
const on = slice?.on === true;
|
|
11757
11908
|
const knobStyle = { transform: on ? "translateX(14px)" : "translateX(2px)" };
|
|
@@ -11789,7 +11940,7 @@ function ChildMotionTriggerToggle({ trpc, deviceId, features }) {
|
|
|
11789
11940
|
requireFeature: "motion-trigger",
|
|
11790
11941
|
deviceFeatures: features
|
|
11791
11942
|
});
|
|
11792
|
-
const [pending, setPending] = (0, react.useState)(false);
|
|
11943
|
+
const [pending, setPending] = (0, react$1.useState)(false);
|
|
11793
11944
|
if (dev !== null && !cap) return null;
|
|
11794
11945
|
const on = slice?.enabled === true;
|
|
11795
11946
|
const handleClick = async (e) => {
|
|
@@ -11867,7 +12018,7 @@ function SwitchToggle({ trpc, deviceId }) {
|
|
|
11867
12018
|
cap: (d) => d.switch,
|
|
11868
12019
|
slice: (d) => d.state.switch
|
|
11869
12020
|
});
|
|
11870
|
-
const [pending, setPending] = (0, react.useState)(false);
|
|
12021
|
+
const [pending, setPending] = (0, react$1.useState)(false);
|
|
11871
12022
|
if (dev !== null && !cap) return null;
|
|
11872
12023
|
const on = slice?.on === true;
|
|
11873
12024
|
const knobStyle = { transform: on ? "translateX(14px)" : "translateX(2px)" };
|
|
@@ -11905,7 +12056,7 @@ function OnMotionToggle({ trpc, deviceId, features }) {
|
|
|
11905
12056
|
requireFeature: "motion-trigger",
|
|
11906
12057
|
deviceFeatures: features
|
|
11907
12058
|
});
|
|
11908
|
-
const [pending, setPending] = (0, react.useState)(false);
|
|
12059
|
+
const [pending, setPending] = (0, react$1.useState)(false);
|
|
11909
12060
|
if (dev !== null && !cap) return null;
|
|
11910
12061
|
const on = slice?.enabled === true;
|
|
11911
12062
|
const handleClick = async (e) => {
|
|
@@ -11939,10 +12090,10 @@ function MoreActionsMenu({ trpc, deviceId }) {
|
|
|
11939
12090
|
cap: (d) => d.reboot,
|
|
11940
12091
|
slice: () => void 0
|
|
11941
12092
|
});
|
|
11942
|
-
const triggerRef = (0, react.useRef)(null);
|
|
11943
|
-
const menuRef = (0, react.useRef)(null);
|
|
11944
|
-
const [position, setPosition] = (0, react.useState)(null);
|
|
11945
|
-
const [pending, setPending] = (0, react.useState)(false);
|
|
12093
|
+
const triggerRef = (0, react$1.useRef)(null);
|
|
12094
|
+
const menuRef = (0, react$1.useRef)(null);
|
|
12095
|
+
const [position, setPosition] = (0, react$1.useState)(null);
|
|
12096
|
+
const [pending, setPending] = (0, react$1.useState)(false);
|
|
11946
12097
|
const ready = dev !== null && cap !== void 0 && cap !== null;
|
|
11947
12098
|
const isOpen = position !== null;
|
|
11948
12099
|
const close = () => setPosition(null);
|
|
@@ -11957,7 +12108,7 @@ function MoreActionsMenu({ trpc, deviceId }) {
|
|
|
11957
12108
|
left
|
|
11958
12109
|
});
|
|
11959
12110
|
};
|
|
11960
|
-
(0, react.useEffect)(() => {
|
|
12111
|
+
(0, react$1.useEffect)(() => {
|
|
11961
12112
|
if (!isOpen) return;
|
|
11962
12113
|
const onMouseDown = (e) => {
|
|
11963
12114
|
const trg = triggerRef.current;
|
|
@@ -12095,10 +12246,10 @@ function buildResolved(rawFeatures, binding) {
|
|
|
12095
12246
|
return out;
|
|
12096
12247
|
}
|
|
12097
12248
|
function useDeviceFeatures(trpc, deviceId, rawFeatures) {
|
|
12098
|
-
const [binding, setBinding] = (0, react.useState)(null);
|
|
12099
|
-
const [errored, setErrored] = (0, react.useState)(false);
|
|
12100
|
-
const [loading, setLoading] = (0, react.useState)(true);
|
|
12101
|
-
(0, react.useEffect)(() => {
|
|
12249
|
+
const [binding, setBinding] = (0, react$1.useState)(null);
|
|
12250
|
+
const [errored, setErrored] = (0, react$1.useState)(false);
|
|
12251
|
+
const [loading, setLoading] = (0, react$1.useState)(true);
|
|
12252
|
+
(0, react$1.useEffect)(() => {
|
|
12102
12253
|
if (deviceId === null) {
|
|
12103
12254
|
setBinding(null);
|
|
12104
12255
|
setErrored(false);
|
|
@@ -12196,8 +12347,8 @@ function ChildrenCountBadge({ accessoryCount, adoptedCount }) {
|
|
|
12196
12347
|
var POPOVER_WIDTH$1 = 240;
|
|
12197
12348
|
var POPOVER_MIN_HEIGHT = 200;
|
|
12198
12349
|
function FeatureRow({ resolved }) {
|
|
12199
|
-
const triggerRef = (0, react.useRef)(null);
|
|
12200
|
-
const [position, setPosition] = (0, react.useState)(null);
|
|
12350
|
+
const triggerRef = (0, react$1.useRef)(null);
|
|
12351
|
+
const [position, setPosition] = (0, react$1.useState)(null);
|
|
12201
12352
|
const open = () => {
|
|
12202
12353
|
const el = triggerRef.current;
|
|
12203
12354
|
if (!el) return;
|
|
@@ -12390,7 +12541,7 @@ function useDeviceBattery(trpc, deviceId) {
|
|
|
12390
12541
|
*/
|
|
12391
12542
|
function useDeviceSnapshotImage(trpc, deviceId) {
|
|
12392
12543
|
const dev = useDeviceProxy(trpc, deviceId);
|
|
12393
|
-
const forceRef = (0, react.useRef)(false);
|
|
12544
|
+
const forceRef = (0, react$1.useRef)(false);
|
|
12394
12545
|
const { data, isLoading, isFetching, refetch } = (0, _tanstack_react_query.useQuery)({
|
|
12395
12546
|
queryKey: [
|
|
12396
12547
|
"device",
|
|
@@ -12507,8 +12658,8 @@ var POPOVER_WIDTH = 288;
|
|
|
12507
12658
|
var POPOVER_HEIGHT = 196;
|
|
12508
12659
|
var TRIGGER_GAP = 8;
|
|
12509
12660
|
function SnapshotPopoverInline({ deviceName, snapshotUrl, status }) {
|
|
12510
|
-
const triggerRef = (0, react.useRef)(null);
|
|
12511
|
-
const [position, setPosition] = (0, react.useState)(null);
|
|
12661
|
+
const triggerRef = (0, react$1.useRef)(null);
|
|
12662
|
+
const [position, setPosition] = (0, react$1.useState)(null);
|
|
12512
12663
|
const offline = status === "offline" || status === "disabled";
|
|
12513
12664
|
const open = () => {
|
|
12514
12665
|
const el = triggerRef.current;
|
|
@@ -12598,7 +12749,7 @@ function DeviceItem(props) {
|
|
|
12598
12749
|
const accessoryChildren = childrenList.filter(isAccessoryChild);
|
|
12599
12750
|
const adoptedChildren = childrenList.filter((c) => !isAccessoryChild(c));
|
|
12600
12751
|
const hasChildren = childrenList.length > 0;
|
|
12601
|
-
const [localExpanded, setLocalExpanded] = (0, react.useState)(false);
|
|
12752
|
+
const [localExpanded, setLocalExpanded] = (0, react$1.useState)(false);
|
|
12602
12753
|
const expanded = props.expanded ?? localExpanded;
|
|
12603
12754
|
const onToggleExpand = props.onToggleExpand ?? (() => setLocalExpanded((v) => !v));
|
|
12604
12755
|
const navigate = (id) => {
|
|
@@ -12748,8 +12899,8 @@ function DeviceItemTableRow(props) {
|
|
|
12748
12899
|
* (caller's `useState`); this hook produces a debounced derivation.
|
|
12749
12900
|
*/
|
|
12750
12901
|
function useDebouncedString(value, delayMs) {
|
|
12751
|
-
const [debounced, setDebounced] = (0, react.useState)(value);
|
|
12752
|
-
(0, react.useEffect)(() => {
|
|
12902
|
+
const [debounced, setDebounced] = (0, react$1.useState)(value);
|
|
12903
|
+
(0, react$1.useEffect)(() => {
|
|
12753
12904
|
const t = setTimeout(() => setDebounced(value), delayMs);
|
|
12754
12905
|
return () => clearTimeout(t);
|
|
12755
12906
|
}, [value, delayMs]);
|
|
@@ -13050,12 +13201,12 @@ function writeUrlState(scope, next, defaultView) {
|
|
|
13050
13201
|
}
|
|
13051
13202
|
function useDeviceListUrlState(options) {
|
|
13052
13203
|
const { scope, defaultView, lsKey } = options;
|
|
13053
|
-
const [state, setState] = (0, react.useState)(() => {
|
|
13204
|
+
const [state, setState] = (0, react$1.useState)(() => {
|
|
13054
13205
|
return readUrlState(scope, defaultView, readFromLS(lsKey));
|
|
13055
13206
|
});
|
|
13056
|
-
const stateRef = (0, react.useRef)(state);
|
|
13207
|
+
const stateRef = (0, react$1.useRef)(state);
|
|
13057
13208
|
stateRef.current = state;
|
|
13058
|
-
(0, react.useEffect)(() => {
|
|
13209
|
+
(0, react$1.useEffect)(() => {
|
|
13059
13210
|
const handler = () => {
|
|
13060
13211
|
const next = readUrlState(scope, defaultView, readFromLS(lsKey));
|
|
13061
13212
|
stateRef.current = next;
|
|
@@ -13068,7 +13219,7 @@ function useDeviceListUrlState(options) {
|
|
|
13068
13219
|
defaultView,
|
|
13069
13220
|
lsKey
|
|
13070
13221
|
]);
|
|
13071
|
-
const apply = (0, react.useCallback)((mutate) => {
|
|
13222
|
+
const apply = (0, react$1.useCallback)((mutate) => {
|
|
13072
13223
|
const next = mutate(stateRef.current);
|
|
13073
13224
|
stateRef.current = next;
|
|
13074
13225
|
setState(next);
|
|
@@ -13086,30 +13237,30 @@ function useDeviceListUrlState(options) {
|
|
|
13086
13237
|
]);
|
|
13087
13238
|
return {
|
|
13088
13239
|
state,
|
|
13089
|
-
setView: (0, react.useCallback)((view) => apply((s) => ({
|
|
13240
|
+
setView: (0, react$1.useCallback)((view) => apply((s) => ({
|
|
13090
13241
|
...s,
|
|
13091
13242
|
view
|
|
13092
13243
|
})), [apply]),
|
|
13093
|
-
setPage: (0, react.useCallback)((page) => apply((s) => ({
|
|
13244
|
+
setPage: (0, react$1.useCallback)((page) => apply((s) => ({
|
|
13094
13245
|
...s,
|
|
13095
13246
|
page
|
|
13096
13247
|
})), [apply]),
|
|
13097
|
-
setAddon: (0, react.useCallback)((addon) => apply((s) => ({
|
|
13248
|
+
setAddon: (0, react$1.useCallback)((addon) => apply((s) => ({
|
|
13098
13249
|
...s,
|
|
13099
13250
|
addon,
|
|
13100
13251
|
page: 1
|
|
13101
13252
|
})), [apply]),
|
|
13102
|
-
setType: (0, react.useCallback)((type) => apply((s) => ({
|
|
13253
|
+
setType: (0, react$1.useCallback)((type) => apply((s) => ({
|
|
13103
13254
|
...s,
|
|
13104
13255
|
type,
|
|
13105
13256
|
page: 1
|
|
13106
13257
|
})), [apply]),
|
|
13107
|
-
setQ: (0, react.useCallback)((q) => apply((s) => ({
|
|
13258
|
+
setQ: (0, react$1.useCallback)((q) => apply((s) => ({
|
|
13108
13259
|
...s,
|
|
13109
13260
|
q,
|
|
13110
13261
|
page: 1
|
|
13111
13262
|
})), [apply]),
|
|
13112
|
-
clearFilters: (0, react.useCallback)(() => apply((s) => ({
|
|
13263
|
+
clearFilters: (0, react$1.useCallback)(() => apply((s) => ({
|
|
13113
13264
|
...s,
|
|
13114
13265
|
addon: null,
|
|
13115
13266
|
type: null,
|
|
@@ -13149,13 +13300,13 @@ function DeviceList(props) {
|
|
|
13149
13300
|
});
|
|
13150
13301
|
const view = url.state.view;
|
|
13151
13302
|
const currentPageSize = view === "cards" ? pageSize.cards : pageSize.table;
|
|
13152
|
-
const [searchInput, setSearchInput] = (0, react.useState)(url.state.q);
|
|
13303
|
+
const [searchInput, setSearchInput] = (0, react$1.useState)(url.state.q);
|
|
13153
13304
|
const debouncedSearch = useDebouncedString(searchInput, 300);
|
|
13154
|
-
(0, react.useEffect)(() => {
|
|
13305
|
+
(0, react$1.useEffect)(() => {
|
|
13155
13306
|
if (debouncedSearch !== url.state.q) url.setQ(debouncedSearch);
|
|
13156
13307
|
}, [debouncedSearch]);
|
|
13157
13308
|
const effectiveAddon = forceAddon ?? url.state.addon;
|
|
13158
|
-
const filtered = (0, react.useMemo)(() => {
|
|
13309
|
+
const filtered = (0, react$1.useMemo)(() => {
|
|
13159
13310
|
const q = url.state.q.toLowerCase().trim();
|
|
13160
13311
|
return devices.filter((d) => {
|
|
13161
13312
|
if (effectiveAddon && d.addonId !== effectiveAddon) return false;
|
|
@@ -13169,8 +13320,8 @@ function DeviceList(props) {
|
|
|
13169
13320
|
url.state.type,
|
|
13170
13321
|
url.state.q
|
|
13171
13322
|
]);
|
|
13172
|
-
const grouped = (0, react.useMemo)(() => groupTopLevelAndAccessories(filtered), [filtered]);
|
|
13173
|
-
const autoExpandedParents = (0, react.useMemo)(() => {
|
|
13323
|
+
const grouped = (0, react$1.useMemo)(() => groupTopLevelAndAccessories(filtered), [filtered]);
|
|
13324
|
+
const autoExpandedParents = (0, react$1.useMemo)(() => {
|
|
13174
13325
|
if (url.state.q.trim() === "") return /* @__PURE__ */ new Set();
|
|
13175
13326
|
const q = url.state.q.toLowerCase().trim();
|
|
13176
13327
|
const matching = /* @__PURE__ */ new Set();
|
|
@@ -13182,7 +13333,7 @@ function DeviceList(props) {
|
|
|
13182
13333
|
const safePage = Math.min(url.state.page, totalPages);
|
|
13183
13334
|
const startIdx = (safePage - 1) * currentPageSize;
|
|
13184
13335
|
const pageRows = grouped.topLevel.slice(startIdx, startIdx + currentPageSize);
|
|
13185
|
-
(0, react.useEffect)(() => {
|
|
13336
|
+
(0, react$1.useEffect)(() => {
|
|
13186
13337
|
if (safePage !== url.state.page) url.setPage(safePage);
|
|
13187
13338
|
}, [safePage]);
|
|
13188
13339
|
useDeviceListRealtimeSync();
|
|
@@ -13287,7 +13438,7 @@ function topLevelIndentLevel(device, parentType) {
|
|
|
13287
13438
|
return 0;
|
|
13288
13439
|
}
|
|
13289
13440
|
function TableLayout({ rows, accessoriesByParent, autoExpandedParents, devices, trpc, resolveIntegrationIcon, resolveParent, onNavigate }) {
|
|
13290
|
-
const parentTypeById = (0, react.useMemo)(() => {
|
|
13441
|
+
const parentTypeById = (0, react$1.useMemo)(() => {
|
|
13291
13442
|
const m = /* @__PURE__ */ new Map();
|
|
13292
13443
|
for (const d of devices) m.set(d.id, d.type);
|
|
13293
13444
|
return m;
|
|
@@ -13342,9 +13493,9 @@ function TableLayout({ rows, accessoriesByParent, autoExpandedParents, devices,
|
|
|
13342
13493
|
});
|
|
13343
13494
|
}
|
|
13344
13495
|
function TableRowGroup({ parent, accessories, hasAccessories, forceExpanded, trpc, integrationIcon, parentRowParent, indentLevel, onNavigate }) {
|
|
13345
|
-
const [expanded, setExpanded] = (0, react.useState)(forceExpanded);
|
|
13346
|
-
const prevForce = (0, react.useRef)(forceExpanded);
|
|
13347
|
-
(0, react.useEffect)(() => {
|
|
13496
|
+
const [expanded, setExpanded] = (0, react$1.useState)(forceExpanded);
|
|
13497
|
+
const prevForce = (0, react$1.useRef)(forceExpanded);
|
|
13498
|
+
(0, react$1.useEffect)(() => {
|
|
13348
13499
|
if (prevForce.current !== forceExpanded) {
|
|
13349
13500
|
setExpanded(forceExpanded);
|
|
13350
13501
|
prevForce.current = forceExpanded;
|
|
@@ -13508,9 +13659,9 @@ function PipelineBuilder({ schema, steps, onChange, templates, selectedTemplateI
|
|
|
13508
13659
|
inheritedEnabled: inheritedEnabledByAddon[addonId]
|
|
13509
13660
|
} : {}
|
|
13510
13661
|
});
|
|
13511
|
-
const excluded = (0, react.useMemo)(() => new Set(excludeAddons), [excludeAddons]);
|
|
13512
|
-
const schemaMap = (0, react.useMemo)(() => buildSchemaMap(schema), [schema]);
|
|
13513
|
-
const [warnings, setWarnings] = (0, react.useState)([]);
|
|
13662
|
+
const excluded = (0, react$1.useMemo)(() => new Set(excludeAddons), [excludeAddons]);
|
|
13663
|
+
const schemaMap = (0, react$1.useMemo)(() => buildSchemaMap(schema), [schema]);
|
|
13664
|
+
const [warnings, setWarnings] = (0, react$1.useState)([]);
|
|
13514
13665
|
const dirty = selectedTemplateId ? JSON.stringify(steps) !== JSON.stringify(templates.find((t) => t.id === selectedTemplateId)?.steps) : false;
|
|
13515
13666
|
function handleSelectTemplate(e) {
|
|
13516
13667
|
const id = e.target.value || null;
|
|
@@ -13965,8 +14116,8 @@ function BoundingBox({ detection, imageWidth, imageHeight, color, showConfidence
|
|
|
13965
14116
|
}
|
|
13966
14117
|
/** Renders a segmentation mask as a semi-transparent colored canvas overlay */
|
|
13967
14118
|
function MaskOverlay({ mask, maskWidth, maskHeight, bbox, imageWidth, imageHeight, color }) {
|
|
13968
|
-
const canvasRef = (0, react.useRef)(null);
|
|
13969
|
-
(0, react.useEffect)(() => {
|
|
14119
|
+
const canvasRef = (0, react$1.useRef)(null);
|
|
14120
|
+
(0, react$1.useEffect)(() => {
|
|
13970
14121
|
const canvas = canvasRef.current;
|
|
13971
14122
|
if (!canvas) return;
|
|
13972
14123
|
const ctx = canvas.getContext("2d");
|
|
@@ -14278,7 +14429,7 @@ function ChildrenTree({ items, colors, hiddenKeys, onToggleVisibility }) {
|
|
|
14278
14429
|
});
|
|
14279
14430
|
}
|
|
14280
14431
|
function AlternateLabelsSection({ alternateLabels, colors }) {
|
|
14281
|
-
const [expanded, setExpanded] = (0, react.useState)(false);
|
|
14432
|
+
const [expanded, setExpanded] = (0, react$1.useState)(false);
|
|
14282
14433
|
const sources = Object.keys(alternateLabels);
|
|
14283
14434
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
14284
14435
|
className: "mt-1",
|
|
@@ -15184,11 +15335,11 @@ function SpinnerIcon({ className }) {
|
|
|
15184
15335
|
});
|
|
15185
15336
|
}
|
|
15186
15337
|
function LoginForm({ onLogin, serverUrl, logoSrc, error: externalError, className }) {
|
|
15187
|
-
const [username, setUsername] = (0, react.useState)("");
|
|
15188
|
-
const [password, setPassword] = (0, react.useState)("");
|
|
15189
|
-
const [showPassword, setShowPassword] = (0, react.useState)(false);
|
|
15190
|
-
const [submitting, setSubmitting] = (0, react.useState)(false);
|
|
15191
|
-
const [internalError, setInternalError] = (0, react.useState)(null);
|
|
15338
|
+
const [username, setUsername] = (0, react$1.useState)("");
|
|
15339
|
+
const [password, setPassword] = (0, react$1.useState)("");
|
|
15340
|
+
const [showPassword, setShowPassword] = (0, react$1.useState)(false);
|
|
15341
|
+
const [submitting, setSubmitting] = (0, react$1.useState)(false);
|
|
15342
|
+
const [internalError, setInternalError] = (0, react$1.useState)(null);
|
|
15192
15343
|
const error = externalError ?? internalError;
|
|
15193
15344
|
const handleSubmit = async (e) => {
|
|
15194
15345
|
e.preventDefault();
|
|
@@ -15280,9 +15431,9 @@ function LoginForm({ onLogin, serverUrl, logoSrc, error: externalError, classNam
|
|
|
15280
15431
|
//#endregion
|
|
15281
15432
|
//#region src/composites/dev-shell.tsx
|
|
15282
15433
|
var STORAGE_KEY = "camstack_dev_token";
|
|
15283
|
-
var DevShellContext = (0, react.createContext)(null);
|
|
15434
|
+
var DevShellContext = (0, react$1.createContext)(null);
|
|
15284
15435
|
function useDevShell() {
|
|
15285
|
-
const ctx = (0, react.useContext)(DevShellContext);
|
|
15436
|
+
const ctx = (0, react$1.useContext)(DevShellContext);
|
|
15286
15437
|
if (!ctx) throw new Error("useDevShell must be used within a DevShell");
|
|
15287
15438
|
return ctx;
|
|
15288
15439
|
}
|
|
@@ -15332,7 +15483,7 @@ function MoonIcon({ className }) {
|
|
|
15332
15483
|
}
|
|
15333
15484
|
function DevShellInner({ children, serverUrl, title, token, onLogout }) {
|
|
15334
15485
|
const theme = require_theme_index.useThemeMode$1();
|
|
15335
|
-
const links = (0, react.useMemo)(() => {
|
|
15486
|
+
const links = (0, react$1.useMemo)(() => {
|
|
15336
15487
|
return [(0, _trpc_client.splitLink)({
|
|
15337
15488
|
condition: (op) => op.type === "subscription",
|
|
15338
15489
|
true: (0, _trpc_client.wsLink)({
|
|
@@ -15349,20 +15500,20 @@ function DevShellInner({ children, serverUrl, title, token, onLogout }) {
|
|
|
15349
15500
|
})
|
|
15350
15501
|
})];
|
|
15351
15502
|
}, [serverUrl, token]);
|
|
15352
|
-
const trpc$1 = (0, react.useMemo)(() => (0, _trpc_client.createTRPCClient)({ links }), [links]);
|
|
15353
|
-
const trpcReactClient = (0, react.useMemo)(() => trpc.createClient({ links }), [links]);
|
|
15354
|
-
const system = (0, react.useMemo)(() => (0, _camstack_sdk.createSystem)({
|
|
15503
|
+
const trpc$1 = (0, react$1.useMemo)(() => (0, _trpc_client.createTRPCClient)({ links }), [links]);
|
|
15504
|
+
const trpcReactClient = (0, react$1.useMemo)(() => trpc.createClient({ links }), [links]);
|
|
15505
|
+
const system = (0, react$1.useMemo)(() => (0, _camstack_sdk.createSystem)({
|
|
15355
15506
|
serverUrl,
|
|
15356
15507
|
token
|
|
15357
15508
|
}), [serverUrl, token]);
|
|
15358
|
-
(0, react.useEffect)(() => {
|
|
15509
|
+
(0, react$1.useEffect)(() => {
|
|
15359
15510
|
system.init().catch(() => void 0);
|
|
15360
15511
|
return () => {
|
|
15361
15512
|
system.close();
|
|
15362
15513
|
};
|
|
15363
15514
|
}, [system]);
|
|
15364
|
-
const queryClient = (0, react.useMemo)(() => new _tanstack_react_query.QueryClient(), []);
|
|
15365
|
-
const contextValue = (0, react.useMemo)(() => ({
|
|
15515
|
+
const queryClient = (0, react$1.useMemo)(() => new _tanstack_react_query.QueryClient(), []);
|
|
15516
|
+
const contextValue = (0, react$1.useMemo)(() => ({
|
|
15366
15517
|
trpc: trpc$1,
|
|
15367
15518
|
token,
|
|
15368
15519
|
logout: onLogout
|
|
@@ -15429,8 +15580,8 @@ function DevShellInner({ children, serverUrl, title, token, onLogout }) {
|
|
|
15429
15580
|
});
|
|
15430
15581
|
}
|
|
15431
15582
|
function DevShell({ children, serverUrl = "https://localhost:4443", title }) {
|
|
15432
|
-
const [token, setToken] = (0, react.useState)(getStoredToken);
|
|
15433
|
-
const handleLogin = (0, react.useCallback)(async (username, password) => {
|
|
15583
|
+
const [token, setToken] = (0, react$1.useState)(getStoredToken);
|
|
15584
|
+
const handleLogin = (0, react$1.useCallback)(async (username, password) => {
|
|
15434
15585
|
const loginResult = await (0, _trpc_client.createTRPCClient)({ links: [(0, _trpc_client.httpLink)({
|
|
15435
15586
|
url: `${serverUrl}/trpc`,
|
|
15436
15587
|
transformer: SuperJSON
|
|
@@ -15442,7 +15593,7 @@ function DevShell({ children, serverUrl = "https://localhost:4443", title }) {
|
|
|
15442
15593
|
localStorage.setItem(STORAGE_KEY, loginResult.token);
|
|
15443
15594
|
setToken(loginResult.token);
|
|
15444
15595
|
}, [serverUrl]);
|
|
15445
|
-
const handleLogout = (0, react.useCallback)(() => {
|
|
15596
|
+
const handleLogout = (0, react$1.useCallback)(() => {
|
|
15446
15597
|
localStorage.removeItem(STORAGE_KEY);
|
|
15447
15598
|
setToken(null);
|
|
15448
15599
|
}, []);
|
|
@@ -15491,10 +15642,10 @@ function mountAddonPage(PageComponent, options = {}) {
|
|
|
15491
15642
|
console.error(`[mountAddonPage] Element #${rootId} not found`);
|
|
15492
15643
|
return;
|
|
15493
15644
|
}
|
|
15494
|
-
(0, react_dom_client.createRoot)(root).render((0, react.createElement)(DevShell, {
|
|
15645
|
+
(0, react_dom_client.createRoot)(root).render((0, react$1.createElement)(DevShell, {
|
|
15495
15646
|
serverUrl,
|
|
15496
15647
|
title,
|
|
15497
|
-
children: ({ trpc, theme }) => (0, react.createElement)(PageComponent, {
|
|
15648
|
+
children: ({ trpc, theme }) => (0, react$1.createElement)(PageComponent, {
|
|
15498
15649
|
trpc,
|
|
15499
15650
|
theme: { isDark: theme.resolvedMode === "dark" },
|
|
15500
15651
|
navigate: (path) => {
|
|
@@ -15554,7 +15705,7 @@ function CustomFieldRenderersProvider({ renderers, children }) {
|
|
|
15554
15705
|
* (or renders nothing).
|
|
15555
15706
|
*/
|
|
15556
15707
|
function useCustomFieldRenderer(type) {
|
|
15557
|
-
return (0, react.useContext)(CustomFieldRenderersContext)[type] ?? null;
|
|
15708
|
+
return (0, react$1.useContext)(CustomFieldRenderersContext)[type] ?? null;
|
|
15558
15709
|
}
|
|
15559
15710
|
//#endregion
|
|
15560
15711
|
//#region src/contexts/device-context.tsx
|
|
@@ -15591,11 +15742,11 @@ function DeviceContextProvider({ deviceId, device, children }) {
|
|
|
15591
15742
|
}
|
|
15592
15743
|
/** @returns the device id of the current page subtree, or null if outside any provider. */
|
|
15593
15744
|
function useDeviceId() {
|
|
15594
|
-
return (0, react.useContext)(DeviceContext)?.deviceId ?? null;
|
|
15745
|
+
return (0, react$1.useContext)(DeviceContext)?.deviceId ?? null;
|
|
15595
15746
|
}
|
|
15596
15747
|
/** @returns the cached device snapshot, or null when no snapshot is provided. */
|
|
15597
15748
|
function useDeviceSnapshot() {
|
|
15598
|
-
return (0, react.useContext)(DeviceContext)?.device ?? null;
|
|
15749
|
+
return (0, react$1.useContext)(DeviceContext)?.device ?? null;
|
|
15599
15750
|
}
|
|
15600
15751
|
//#endregion
|
|
15601
15752
|
//#region src/generated/system-hooks.ts
|
|
@@ -15649,6 +15800,14 @@ var useAddonsRollbackPackage = trpc.addons.rollbackPackage.useMutation;
|
|
|
15649
15800
|
var useAddonsForceRefresh = trpc.addons.forceRefresh.useMutation;
|
|
15650
15801
|
/** Generated alias around `trpc.addons.restartServer.useMutation`. */
|
|
15651
15802
|
var useAddonsRestartServer = trpc.addons.restartServer.useMutation;
|
|
15803
|
+
/** Generated alias around `trpc.addons.getLastRestart.useQuery`. */
|
|
15804
|
+
var useAddonsGetLastRestart = trpc.addons.getLastRestart.useQuery;
|
|
15805
|
+
/** Generated alias around `trpc.addons.listFrameworkPackages.useQuery`. */
|
|
15806
|
+
var useAddonsListFrameworkPackages = trpc.addons.listFrameworkPackages.useQuery;
|
|
15807
|
+
/** Generated alias around `trpc.addons.listCapabilityProviders.useQuery`. */
|
|
15808
|
+
var useAddonsListCapabilityProviders = trpc.addons.listCapabilityProviders.useQuery;
|
|
15809
|
+
/** Generated alias around `trpc.addons.updateFrameworkPackage.useMutation`. */
|
|
15810
|
+
var useAddonsUpdateFrameworkPackage = trpc.addons.updateFrameworkPackage.useMutation;
|
|
15652
15811
|
/** Generated alias around `trpc.addons.getVersions.useQuery`. */
|
|
15653
15812
|
var useAddonsGetVersions = trpc.addons.getVersions.useQuery;
|
|
15654
15813
|
/** Generated alias around `trpc.addons.restartAddon.useMutation`. */
|
|
@@ -16748,7 +16907,7 @@ var BOOT_WINDOW_MS = 3e4;
|
|
|
16748
16907
|
var POLL_INTERVAL_MS = 2e3;
|
|
16749
16908
|
function WidgetRegistryProvider({ children }) {
|
|
16750
16909
|
const queryClient = (0, _tanstack_react_query.useQueryClient)();
|
|
16751
|
-
const mountedAtRef = (0, react.useRef)(Date.now());
|
|
16910
|
+
const mountedAtRef = (0, react$1.useRef)(Date.now());
|
|
16752
16911
|
const { data: rawWidgets } = useAddonWidgetsListWidgets(void 0, {
|
|
16753
16912
|
staleTime: 0,
|
|
16754
16913
|
refetchOnMount: "always",
|
|
@@ -16762,8 +16921,8 @@ function WidgetRegistryProvider({ children }) {
|
|
|
16762
16921
|
useLiveEvent("addon.widget-ready", () => {
|
|
16763
16922
|
queryClient.invalidateQueries({ queryKey: [["addonWidgets", "listWidgets"]] });
|
|
16764
16923
|
});
|
|
16765
|
-
const [resolvedTick, setResolvedTick] = (0, react.useState)(0);
|
|
16766
|
-
(0, react.useEffect)(() => {
|
|
16924
|
+
const [resolvedTick, setResolvedTick] = (0, react$1.useState)(0);
|
|
16925
|
+
(0, react$1.useEffect)(() => {
|
|
16767
16926
|
if (!rawWidgets) return;
|
|
16768
16927
|
let cancelled = false;
|
|
16769
16928
|
const seenRemotes = /* @__PURE__ */ new Set();
|
|
@@ -16787,7 +16946,7 @@ function WidgetRegistryProvider({ children }) {
|
|
|
16787
16946
|
cancelled = true;
|
|
16788
16947
|
};
|
|
16789
16948
|
}, [rawWidgets]);
|
|
16790
|
-
const registry = (0, react.useMemo)(() => {
|
|
16949
|
+
const registry = (0, react$1.useMemo)(() => {
|
|
16791
16950
|
const widgets = rawWidgets ?? [];
|
|
16792
16951
|
const byId = /* @__PURE__ */ new Map();
|
|
16793
16952
|
for (const w of widgets) byId.set(`${w.addonId}/${w.stableId}`, w);
|
|
@@ -16859,7 +17018,7 @@ function useOptionalWidgetRegistry() {
|
|
|
16859
17018
|
return useContextSafe(WidgetRegistryContext);
|
|
16860
17019
|
}
|
|
16861
17020
|
function useContextSafe(ctx) {
|
|
16862
|
-
return (0, react.useContext)(ctx);
|
|
17021
|
+
return (0, react$1.useContext)(ctx);
|
|
16863
17022
|
}
|
|
16864
17023
|
//#endregion
|
|
16865
17024
|
//#region src/composites/widget-slot.tsx
|
|
@@ -16883,7 +17042,7 @@ function WidgetSlot(props) {
|
|
|
16883
17042
|
const { widgetId, host = "device-tab", config, deviceId, integrationId, instanceId, size, columns, rows } = props;
|
|
16884
17043
|
const Component = useWidget(widgetId);
|
|
16885
17044
|
const metadata = useWidgetMetadata(widgetId);
|
|
16886
|
-
const resolvedInstanceId = (0, react.useMemo)(() => instanceId ?? widgetId, [instanceId, widgetId]);
|
|
17045
|
+
const resolvedInstanceId = (0, react$1.useMemo)(() => instanceId ?? widgetId, [instanceId, widgetId]);
|
|
16887
17046
|
if (Component === void 0 && metadata === void 0) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(WidgetMissingError, {
|
|
16888
17047
|
widgetId,
|
|
16889
17048
|
reason: "unknown"
|
|
@@ -16977,9 +17136,9 @@ function TextField({ field, value, onChange, disabled, translationFn }) {
|
|
|
16977
17136
|
});
|
|
16978
17137
|
}
|
|
16979
17138
|
function NumberField({ field, value, onChange, disabled, translationFn }) {
|
|
16980
|
-
const [local, setLocal] = (0, react.useState)(value === void 0 || value === null ? "" : String(value));
|
|
16981
|
-
const focusedRef = (0, react.useRef)(false);
|
|
16982
|
-
(0, react.useEffect)(() => {
|
|
17139
|
+
const [local, setLocal] = (0, react$1.useState)(value === void 0 || value === null ? "" : String(value));
|
|
17140
|
+
const focusedRef = (0, react$1.useRef)(false);
|
|
17141
|
+
(0, react$1.useEffect)(() => {
|
|
16983
17142
|
if (focusedRef.current) return;
|
|
16984
17143
|
setLocal(value === void 0 || value === null ? "" : String(value));
|
|
16985
17144
|
}, [value]);
|
|
@@ -17145,7 +17304,7 @@ function MultiSelectField({ field, value, onChange, disabled, translationFn }) {
|
|
|
17145
17304
|
});
|
|
17146
17305
|
}
|
|
17147
17306
|
function PasswordField({ field, value, onChange, disabled, translationFn }) {
|
|
17148
|
-
const [show, setShow] = (0, react.useState)(false);
|
|
17307
|
+
const [show, setShow] = (0, react$1.useState)(false);
|
|
17149
17308
|
const showToggle = field.showToggle !== false;
|
|
17150
17309
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(FieldWrapper, {
|
|
17151
17310
|
label: field.label,
|
|
@@ -17312,9 +17471,9 @@ function SliderField({ field, value, onChange, disabled, translationFn }) {
|
|
|
17312
17471
|
}
|
|
17313
17472
|
function TagsField({ field, value, onChange, disabled, translationFn }) {
|
|
17314
17473
|
const tags = Array.isArray(value) ? value : [];
|
|
17315
|
-
const [input, setInput] = (0, react.useState)("");
|
|
17316
|
-
const inputRef = (0, react.useRef)(null);
|
|
17317
|
-
const addTag = (0, react.useCallback)((tag) => {
|
|
17474
|
+
const [input, setInput] = (0, react$1.useState)("");
|
|
17475
|
+
const inputRef = (0, react$1.useRef)(null);
|
|
17476
|
+
const addTag = (0, react$1.useCallback)((tag) => {
|
|
17318
17477
|
const trimmed = tag.trim();
|
|
17319
17478
|
if (!trimmed || tags.includes(trimmed)) return;
|
|
17320
17479
|
if (field.maxTags !== void 0 && tags.length >= field.maxTags) return;
|
|
@@ -17473,12 +17632,12 @@ function ColorField({ field, value, onChange, disabled, translationFn }) {
|
|
|
17473
17632
|
});
|
|
17474
17633
|
}
|
|
17475
17634
|
function ProbeField({ field, value, onChange, disabled, translationFn, onTestField, onAction, externalProbe }) {
|
|
17476
|
-
const [localStatus, setLocalStatus] = (0, react.useState)("idle");
|
|
17477
|
-
const [localResult, setLocalResult] = (0, react.useState)(null);
|
|
17635
|
+
const [localStatus, setLocalStatus] = (0, react$1.useState)("idle");
|
|
17636
|
+
const [localResult, setLocalResult] = (0, react$1.useState)(null);
|
|
17478
17637
|
const probeStatus = externalProbe?.status ?? localStatus;
|
|
17479
17638
|
const probeResult = externalProbe?.result ?? localResult;
|
|
17480
17639
|
const hasTestHandler = !!onTestField || !!onAction;
|
|
17481
|
-
const handleTest = (0, react.useCallback)(async () => {
|
|
17640
|
+
const handleTest = (0, react$1.useCallback)(async () => {
|
|
17482
17641
|
if (!hasTestHandler) return;
|
|
17483
17642
|
setLocalStatus("probing");
|
|
17484
17643
|
setLocalResult(null);
|
|
@@ -17557,7 +17716,7 @@ function ProbeField({ field, value, onChange, disabled, translationFn, onTestFie
|
|
|
17557
17716
|
});
|
|
17558
17717
|
}
|
|
17559
17718
|
function GroupField({ field, values, onChange, disabled, translationFn, onTestField }) {
|
|
17560
|
-
const [collapsed, setCollapsed] = (0, react.useState)(field.defaultCollapsed ?? false);
|
|
17719
|
+
const [collapsed, setCollapsed] = (0, react$1.useState)(field.defaultCollapsed ?? false);
|
|
17561
17720
|
const isAccordion = field.style === "accordion";
|
|
17562
17721
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
17563
17722
|
className: field.span === 2 ? "col-span-2" : field.span === 3 ? "col-span-3" : field.span === 4 ? "col-span-4" : "col-span-1",
|
|
@@ -17588,7 +17747,7 @@ function GroupField({ field, values, onChange, disabled, translationFn, onTestFi
|
|
|
17588
17747
|
});
|
|
17589
17748
|
}
|
|
17590
17749
|
function SubTabsField({ field, values, onChange, disabled, translationFn, onTestField, onAction }) {
|
|
17591
|
-
const [active, setActive] = (0, react.useState)(field.tabs[0]?.id ?? "");
|
|
17750
|
+
const [active, setActive] = (0, react$1.useState)(field.tabs[0]?.id ?? "");
|
|
17592
17751
|
const colSpanClass = field.span === 2 ? "col-span-2" : field.span === 3 ? "col-span-3" : field.span === 4 ? "col-span-4" : "col-span-1";
|
|
17593
17752
|
if (field.tabs.length === 0) return null;
|
|
17594
17753
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
@@ -17929,7 +18088,7 @@ function EditableArrayField({ field, value, onChange, disabled, translationFn, o
|
|
|
17929
18088
|
});
|
|
17930
18089
|
}
|
|
17931
18090
|
function ButtonField({ field, disabled, onAction }) {
|
|
17932
|
-
const [loading, setLoading] = (0, react.useState)(false);
|
|
18091
|
+
const [loading, setLoading] = (0, react$1.useState)(false);
|
|
17933
18092
|
const confirm = useConfirm();
|
|
17934
18093
|
const handleClick = async () => {
|
|
17935
18094
|
if (field.confirmMessage) {
|
|
@@ -17975,12 +18134,12 @@ function resolveActionParams(field, values) {
|
|
|
17975
18134
|
return params;
|
|
17976
18135
|
}
|
|
17977
18136
|
function AddonActionSelectField({ field, value, values, onChange, disabled, onAction }) {
|
|
17978
|
-
const [loading, setLoading] = (0, react.useState)(false);
|
|
17979
|
-
const [error, setError] = (0, react.useState)(null);
|
|
17980
|
-
const [options, setOptions] = (0, react.useState)(null);
|
|
18137
|
+
const [loading, setLoading] = (0, react$1.useState)(false);
|
|
18138
|
+
const [error, setError] = (0, react$1.useState)(null);
|
|
18139
|
+
const [options, setOptions] = (0, react$1.useState)(null);
|
|
17981
18140
|
const params = resolveActionParams(field, values);
|
|
17982
18141
|
const missingParam = Object.keys(field.paramsFromForm ?? {}).some((k) => params[k] === void 0);
|
|
17983
|
-
(0, react.useEffect)(() => {
|
|
18142
|
+
(0, react$1.useEffect)(() => {
|
|
17984
18143
|
if (!onAction || missingParam) {
|
|
17985
18144
|
setOptions(null);
|
|
17986
18145
|
setError(null);
|
|
@@ -18066,8 +18225,8 @@ function AddonActionSelectField({ field, value, values, onChange, disabled, onAc
|
|
|
18066
18225
|
});
|
|
18067
18226
|
}
|
|
18068
18227
|
function AddonActionButtonField({ field, values, disabled, onAction }) {
|
|
18069
|
-
const [loading, setLoading] = (0, react.useState)(false);
|
|
18070
|
-
const [status, setStatus] = (0, react.useState)(null);
|
|
18228
|
+
const [loading, setLoading] = (0, react$1.useState)(false);
|
|
18229
|
+
const [status, setStatus] = (0, react$1.useState)(null);
|
|
18071
18230
|
const confirm = useConfirm();
|
|
18072
18231
|
const handleClick = async () => {
|
|
18073
18232
|
if (field.confirmMessage) {
|
|
@@ -18212,7 +18371,7 @@ function InlineIconGlyph({ name }) {
|
|
|
18212
18371
|
*/
|
|
18213
18372
|
function InlineActionIcon({ action, fieldKey, value, onAction }) {
|
|
18214
18373
|
const confirm = useConfirm();
|
|
18215
|
-
const [loading, setLoading] = (0, react.useState)(false);
|
|
18374
|
+
const [loading, setLoading] = (0, react$1.useState)(false);
|
|
18216
18375
|
const variantClass = action.variant === "danger" ? "text-danger hover:bg-danger/10 border-danger/30" : action.variant === "primary" ? "text-primary hover:bg-primary/10 border-primary/30" : "text-foreground-subtle hover:text-foreground hover:bg-surface-hover border-border";
|
|
18217
18376
|
const handleClick = async () => {
|
|
18218
18377
|
if (action.confirmMessage) {
|
|
@@ -18560,7 +18719,7 @@ function resolveLabel(value, t) {
|
|
|
18560
18719
|
return value;
|
|
18561
18720
|
}
|
|
18562
18721
|
function SectionCard({ section, values, onChange, disabled, translationFn, onTestField, probeResults }) {
|
|
18563
|
-
const [collapsed, setCollapsed] = (0, react.useState)(section.defaultCollapsed ?? false);
|
|
18722
|
+
const [collapsed, setCollapsed] = (0, react$1.useState)(section.defaultCollapsed ?? false);
|
|
18564
18723
|
const isAccordion = section.style === "accordion";
|
|
18565
18724
|
const columns = section.columns ?? 2;
|
|
18566
18725
|
const gridClass = columns === 1 ? "grid-cols-1" : columns === 3 ? "grid-cols-1 @[480px]:grid-cols-2 @[880px]:grid-cols-3" : columns === 4 ? "grid-cols-1 @[480px]:grid-cols-2 @[1140px]:grid-cols-4" : "grid-cols-1 @[640px]:grid-cols-2";
|
|
@@ -18665,14 +18824,14 @@ function stripValues(schema) {
|
|
|
18665
18824
|
}
|
|
18666
18825
|
function AddonGlobalSettingsForm({ trpc, addonId, nodeId, title, disabled, onAfterChange, refreshToken, collapsible, defaultOpen, mode, onOverrideChange }) {
|
|
18667
18826
|
const effectiveMode = mode ?? "persist";
|
|
18668
|
-
const [hydrated, setHydrated] = (0, react.useState)(null);
|
|
18669
|
-
const [loading, setLoading] = (0, react.useState)(true);
|
|
18670
|
-
const [error, setError] = (0, react.useState)(null);
|
|
18671
|
-
const [saving, setSaving] = (0, react.useState)(false);
|
|
18672
|
-
const [open, setOpen] = (0, react.useState)(defaultOpen ?? false);
|
|
18673
|
-
const [overrideValues, setOverrideValues] = (0, react.useState)({});
|
|
18674
|
-
const [baseValues, setBaseValues] = (0, react.useState)(null);
|
|
18675
|
-
(0, react.useEffect)(() => {
|
|
18827
|
+
const [hydrated, setHydrated] = (0, react$1.useState)(null);
|
|
18828
|
+
const [loading, setLoading] = (0, react$1.useState)(true);
|
|
18829
|
+
const [error, setError] = (0, react$1.useState)(null);
|
|
18830
|
+
const [saving, setSaving] = (0, react$1.useState)(false);
|
|
18831
|
+
const [open, setOpen] = (0, react$1.useState)(defaultOpen ?? false);
|
|
18832
|
+
const [overrideValues, setOverrideValues] = (0, react$1.useState)({});
|
|
18833
|
+
const [baseValues, setBaseValues] = (0, react$1.useState)(null);
|
|
18834
|
+
(0, react$1.useEffect)(() => {
|
|
18676
18835
|
setBaseValues(null);
|
|
18677
18836
|
setOverrideValues({});
|
|
18678
18837
|
}, [
|
|
@@ -18682,7 +18841,7 @@ function AddonGlobalSettingsForm({ trpc, addonId, nodeId, title, disabled, onAft
|
|
|
18682
18841
|
refreshToken,
|
|
18683
18842
|
effectiveMode
|
|
18684
18843
|
]);
|
|
18685
|
-
(0, react.useEffect)(() => {
|
|
18844
|
+
(0, react$1.useEffect)(() => {
|
|
18686
18845
|
let cancelled = false;
|
|
18687
18846
|
setLoading(true);
|
|
18688
18847
|
setError(null);
|
|
@@ -18712,8 +18871,8 @@ function AddonGlobalSettingsForm({ trpc, addonId, nodeId, title, disabled, onAft
|
|
|
18712
18871
|
effectiveMode,
|
|
18713
18872
|
JSON.stringify(overrideValues)
|
|
18714
18873
|
]);
|
|
18715
|
-
const values = (0, react.useMemo)(() => extractValues(hydrated), [hydrated]);
|
|
18716
|
-
const schemaNoValues = (0, react.useMemo)(() => hydrated ? stripValues(hydrated) : null, [hydrated]);
|
|
18874
|
+
const values = (0, react$1.useMemo)(() => extractValues(hydrated), [hydrated]);
|
|
18875
|
+
const schemaNoValues = (0, react$1.useMemo)(() => hydrated ? stripValues(hydrated) : null, [hydrated]);
|
|
18717
18876
|
const handleChange = async (nextValues) => {
|
|
18718
18877
|
if (effectiveMode === "override") {
|
|
18719
18878
|
const ref = baseValues ?? values;
|
|
@@ -18960,30 +19119,30 @@ function computeClientHints(container) {
|
|
|
18960
19119
|
var RECONNECT_DELAY_MS = 3e3;
|
|
18961
19120
|
var MAX_RECONNECT_ATTEMPTS = 5;
|
|
18962
19121
|
function CameraStreamPlayer({ serverUrl, streamKey, label, autoPlay = true, muted: initialMuted = true, showControls = true, className = "", onStateChange, onError, overlay, createSession, sendAnswer, closeSession, hintsOverride }) {
|
|
18963
|
-
const videoRef = (0, react.useRef)(null);
|
|
18964
|
-
const containerRef = (0, react.useRef)(null);
|
|
18965
|
-
const pcRef = (0, react.useRef)(null);
|
|
19122
|
+
const videoRef = (0, react$1.useRef)(null);
|
|
19123
|
+
const containerRef = (0, react$1.useRef)(null);
|
|
19124
|
+
const pcRef = (0, react$1.useRef)(null);
|
|
18966
19125
|
/** All session IDs created during this player's lifetime — closed on cleanup */
|
|
18967
|
-
const sessionIdsRef = (0, react.useRef)(/* @__PURE__ */ new Set());
|
|
19126
|
+
const sessionIdsRef = (0, react$1.useRef)(/* @__PURE__ */ new Set());
|
|
18968
19127
|
/** Abort controller to cancel in-flight connection attempts on cleanup */
|
|
18969
|
-
const connectAbortRef = (0, react.useRef)(null);
|
|
18970
|
-
const reconnectTimerRef = (0, react.useRef)(null);
|
|
18971
|
-
const reconnectAttemptsRef = (0, react.useRef)(0);
|
|
18972
|
-
const mountedRef = (0, react.useRef)(true);
|
|
18973
|
-
const [state, setState] = (0, react.useState)("idle");
|
|
18974
|
-
const [errorMessage, setErrorMessage] = (0, react.useState)("");
|
|
18975
|
-
const [isMuted, setIsMuted] = (0, react.useState)(initialMuted);
|
|
18976
|
-
const [isFullscreen, setIsFullscreen] = (0, react.useState)(false);
|
|
18977
|
-
const [showToolbar, setShowToolbar] = (0, react.useState)(false);
|
|
18978
|
-
const hideTimerRef = (0, react.useRef)(null);
|
|
18979
|
-
const serverOfferModeRef = (0, react.useRef)(false);
|
|
19128
|
+
const connectAbortRef = (0, react$1.useRef)(null);
|
|
19129
|
+
const reconnectTimerRef = (0, react$1.useRef)(null);
|
|
19130
|
+
const reconnectAttemptsRef = (0, react$1.useRef)(0);
|
|
19131
|
+
const mountedRef = (0, react$1.useRef)(true);
|
|
19132
|
+
const [state, setState] = (0, react$1.useState)("idle");
|
|
19133
|
+
const [errorMessage, setErrorMessage] = (0, react$1.useState)("");
|
|
19134
|
+
const [isMuted, setIsMuted] = (0, react$1.useState)(initialMuted);
|
|
19135
|
+
const [isFullscreen, setIsFullscreen] = (0, react$1.useState)(false);
|
|
19136
|
+
const [showToolbar, setShowToolbar] = (0, react$1.useState)(false);
|
|
19137
|
+
const hideTimerRef = (0, react$1.useRef)(null);
|
|
19138
|
+
const serverOfferModeRef = (0, react$1.useRef)(false);
|
|
18980
19139
|
if (sendAnswer || createSession) serverOfferModeRef.current = true;
|
|
18981
19140
|
const useServerOffer = serverOfferModeRef.current;
|
|
18982
|
-
const updateState = (0, react.useCallback)((s) => {
|
|
19141
|
+
const updateState = (0, react$1.useCallback)((s) => {
|
|
18983
19142
|
setState(s);
|
|
18984
19143
|
onStateChange?.(s);
|
|
18985
19144
|
}, [onStateChange]);
|
|
18986
|
-
const cleanup = (0, react.useCallback)(() => {
|
|
19145
|
+
const cleanup = (0, react$1.useCallback)(() => {
|
|
18987
19146
|
connectAbortRef.current?.abort();
|
|
18988
19147
|
connectAbortRef.current = null;
|
|
18989
19148
|
if (reconnectTimerRef.current) {
|
|
@@ -19000,7 +19159,7 @@ function CameraStreamPlayer({ serverUrl, streamKey, label, autoPlay = true, mute
|
|
|
19000
19159
|
}
|
|
19001
19160
|
if (videoRef.current) videoRef.current.srcObject = null;
|
|
19002
19161
|
}, [closeSession]);
|
|
19003
|
-
const connectServerOffer = (0, react.useCallback)(async () => {
|
|
19162
|
+
const connectServerOffer = (0, react$1.useCallback)(async () => {
|
|
19004
19163
|
if (!mountedRef.current || !createSession || !sendAnswer) return;
|
|
19005
19164
|
cleanup();
|
|
19006
19165
|
updateState("connecting");
|
|
@@ -19091,7 +19250,7 @@ function CameraStreamPlayer({ serverUrl, streamKey, label, autoPlay = true, mute
|
|
|
19091
19250
|
onError,
|
|
19092
19251
|
hintsOverride
|
|
19093
19252
|
]);
|
|
19094
|
-
const connectWhep = (0, react.useCallback)(async () => {
|
|
19253
|
+
const connectWhep = (0, react$1.useCallback)(async () => {
|
|
19095
19254
|
if (!mountedRef.current) return;
|
|
19096
19255
|
cleanup();
|
|
19097
19256
|
updateState("connecting");
|
|
@@ -19152,9 +19311,9 @@ function CameraStreamPlayer({ serverUrl, streamKey, label, autoPlay = true, mute
|
|
|
19152
19311
|
onError
|
|
19153
19312
|
]);
|
|
19154
19313
|
const connect = useServerOffer ? connectServerOffer : connectWhep;
|
|
19155
|
-
const connectRef = (0, react.useRef)(() => {});
|
|
19314
|
+
const connectRef = (0, react$1.useRef)(() => {});
|
|
19156
19315
|
connectRef.current = connect;
|
|
19157
|
-
const scheduleReconnect = (0, react.useCallback)(() => {
|
|
19316
|
+
const scheduleReconnect = (0, react$1.useCallback)(() => {
|
|
19158
19317
|
if (!mountedRef.current) return;
|
|
19159
19318
|
if (reconnectAttemptsRef.current >= MAX_RECONNECT_ATTEMPTS) return;
|
|
19160
19319
|
reconnectAttemptsRef.current += 1;
|
|
@@ -19162,7 +19321,7 @@ function CameraStreamPlayer({ serverUrl, streamKey, label, autoPlay = true, mute
|
|
|
19162
19321
|
if (mountedRef.current) connectRef.current();
|
|
19163
19322
|
}, RECONNECT_DELAY_MS);
|
|
19164
19323
|
}, []);
|
|
19165
|
-
(0, react.useEffect)(() => {
|
|
19324
|
+
(0, react$1.useEffect)(() => {
|
|
19166
19325
|
mountedRef.current = true;
|
|
19167
19326
|
reconnectAttemptsRef.current = 0;
|
|
19168
19327
|
if (autoPlay) connect();
|
|
@@ -19171,8 +19330,8 @@ function CameraStreamPlayer({ serverUrl, streamKey, label, autoPlay = true, mute
|
|
|
19171
19330
|
cleanup();
|
|
19172
19331
|
};
|
|
19173
19332
|
}, [serverUrl, streamKey]);
|
|
19174
|
-
const hasSignaledRef = (0, react.useRef)(false);
|
|
19175
|
-
(0, react.useEffect)(() => {
|
|
19333
|
+
const hasSignaledRef = (0, react$1.useRef)(false);
|
|
19334
|
+
(0, react$1.useEffect)(() => {
|
|
19176
19335
|
if (!autoPlay || !useServerOffer) return;
|
|
19177
19336
|
if (!createSession || !sendAnswer) return;
|
|
19178
19337
|
if (hasSignaledRef.current) return;
|
|
@@ -19218,7 +19377,7 @@ function CameraStreamPlayer({ serverUrl, streamKey, label, autoPlay = true, mute
|
|
|
19218
19377
|
link.href = canvas.toDataURL("image/jpeg", .92);
|
|
19219
19378
|
link.click();
|
|
19220
19379
|
};
|
|
19221
|
-
(0, react.useEffect)(() => {
|
|
19380
|
+
(0, react$1.useEffect)(() => {
|
|
19222
19381
|
const handler = () => setIsFullscreen(!!document.fullscreenElement);
|
|
19223
19382
|
document.addEventListener("fullscreenchange", handler);
|
|
19224
19383
|
return () => document.removeEventListener("fullscreenchange", handler);
|
|
@@ -19442,16 +19601,16 @@ async function waitForIceGathering(pc) {
|
|
|
19442
19601
|
var PlayerOverlaysStateContext = createSharedContext("camstack:player-overlays-state", null);
|
|
19443
19602
|
var PlayerOverlaysActionsContext = createSharedContext("camstack:player-overlays-actions", null);
|
|
19444
19603
|
function PlayerOverlaysProvider({ children }) {
|
|
19445
|
-
const [layers, setLayers] = (0, react.useState)(() => /* @__PURE__ */ new Map());
|
|
19446
|
-
const [buttons, setButtons] = (0, react.useState)(() => /* @__PURE__ */ new Map());
|
|
19447
|
-
const setLayer = (0, react.useCallback)((layer) => {
|
|
19604
|
+
const [layers, setLayers] = (0, react$1.useState)(() => /* @__PURE__ */ new Map());
|
|
19605
|
+
const [buttons, setButtons] = (0, react$1.useState)(() => /* @__PURE__ */ new Map());
|
|
19606
|
+
const setLayer = (0, react$1.useCallback)((layer) => {
|
|
19448
19607
|
setLayers((prev) => {
|
|
19449
19608
|
const next = new Map(prev);
|
|
19450
19609
|
next.set(layer.id, layer);
|
|
19451
19610
|
return next;
|
|
19452
19611
|
});
|
|
19453
19612
|
}, []);
|
|
19454
|
-
const removeLayer = (0, react.useCallback)((id) => {
|
|
19613
|
+
const removeLayer = (0, react$1.useCallback)((id) => {
|
|
19455
19614
|
setLayers((prev) => {
|
|
19456
19615
|
if (!prev.has(id)) return prev;
|
|
19457
19616
|
const next = new Map(prev);
|
|
@@ -19459,14 +19618,14 @@ function PlayerOverlaysProvider({ children }) {
|
|
|
19459
19618
|
return next;
|
|
19460
19619
|
});
|
|
19461
19620
|
}, []);
|
|
19462
|
-
const setButton = (0, react.useCallback)((button) => {
|
|
19621
|
+
const setButton = (0, react$1.useCallback)((button) => {
|
|
19463
19622
|
setButtons((prev) => {
|
|
19464
19623
|
const next = new Map(prev);
|
|
19465
19624
|
next.set(button.id, button);
|
|
19466
19625
|
return next;
|
|
19467
19626
|
});
|
|
19468
19627
|
}, []);
|
|
19469
|
-
const removeButton = (0, react.useCallback)((id) => {
|
|
19628
|
+
const removeButton = (0, react$1.useCallback)((id) => {
|
|
19470
19629
|
setButtons((prev) => {
|
|
19471
19630
|
if (!prev.has(id)) return prev;
|
|
19472
19631
|
const next = new Map(prev);
|
|
@@ -19474,11 +19633,11 @@ function PlayerOverlaysProvider({ children }) {
|
|
|
19474
19633
|
return next;
|
|
19475
19634
|
});
|
|
19476
19635
|
}, []);
|
|
19477
|
-
const stateValue = (0, react.useMemo)(() => ({
|
|
19636
|
+
const stateValue = (0, react$1.useMemo)(() => ({
|
|
19478
19637
|
layers,
|
|
19479
19638
|
buttons
|
|
19480
19639
|
}), [layers, buttons]);
|
|
19481
|
-
const actionsValue = (0, react.useMemo)(() => ({
|
|
19640
|
+
const actionsValue = (0, react$1.useMemo)(() => ({
|
|
19482
19641
|
setLayer,
|
|
19483
19642
|
removeLayer,
|
|
19484
19643
|
setButton,
|
|
@@ -19501,16 +19660,16 @@ function PlayerOverlaysProvider({ children }) {
|
|
|
19501
19660
|
* by insertion order of the underlying Map). Returns `[]` outside a
|
|
19502
19661
|
* provider. */
|
|
19503
19662
|
function usePlayerOverlayLayers() {
|
|
19504
|
-
const state = (0, react.useContext)(PlayerOverlaysStateContext);
|
|
19505
|
-
return (0, react.useMemo)(() => {
|
|
19663
|
+
const state = (0, react$1.useContext)(PlayerOverlaysStateContext);
|
|
19664
|
+
return (0, react$1.useMemo)(() => {
|
|
19506
19665
|
if (!state) return [];
|
|
19507
19666
|
return [...state.layers.values()].sort((a, b) => a.order - b.order);
|
|
19508
19667
|
}, [state]);
|
|
19509
19668
|
}
|
|
19510
19669
|
/** Snapshot of registered toolbar buttons, ordered by `order` (asc). */
|
|
19511
19670
|
function usePlayerToolbarButtons() {
|
|
19512
|
-
const state = (0, react.useContext)(PlayerOverlaysStateContext);
|
|
19513
|
-
return (0, react.useMemo)(() => {
|
|
19671
|
+
const state = (0, react$1.useContext)(PlayerOverlaysStateContext);
|
|
19672
|
+
return (0, react$1.useMemo)(() => {
|
|
19514
19673
|
if (!state) return [];
|
|
19515
19674
|
return [...state.buttons.values()].sort((a, b) => a.order - b.order);
|
|
19516
19675
|
}, [state]);
|
|
@@ -19527,8 +19686,8 @@ function usePlayerToolbarButtons() {
|
|
|
19527
19686
|
* effects depend on referential equality of the spec object.
|
|
19528
19687
|
*/
|
|
19529
19688
|
function usePlayerOverlayLayer(spec) {
|
|
19530
|
-
const actions = (0, react.useContext)(PlayerOverlaysActionsContext);
|
|
19531
|
-
(0, react.useEffect)(() => {
|
|
19689
|
+
const actions = (0, react$1.useContext)(PlayerOverlaysActionsContext);
|
|
19690
|
+
(0, react$1.useEffect)(() => {
|
|
19532
19691
|
if (!actions || !spec) return void 0;
|
|
19533
19692
|
actions.setLayer(spec);
|
|
19534
19693
|
return () => actions.removeLayer(spec.id);
|
|
@@ -19536,8 +19695,8 @@ function usePlayerOverlayLayer(spec) {
|
|
|
19536
19695
|
}
|
|
19537
19696
|
/** Same shape as `usePlayerOverlayLayer`, scoped to toolbar buttons. */
|
|
19538
19697
|
function usePlayerToolbarButton(spec) {
|
|
19539
|
-
const actions = (0, react.useContext)(PlayerOverlaysActionsContext);
|
|
19540
|
-
(0, react.useEffect)(() => {
|
|
19698
|
+
const actions = (0, react$1.useContext)(PlayerOverlaysActionsContext);
|
|
19699
|
+
(0, react$1.useEffect)(() => {
|
|
19541
19700
|
if (!actions || !spec) return void 0;
|
|
19542
19701
|
actions.setButton(spec);
|
|
19543
19702
|
return () => actions.removeButton(spec.id);
|
|
@@ -19706,13 +19865,13 @@ function ImageOffIcon({ className }) {
|
|
|
19706
19865
|
}
|
|
19707
19866
|
function StreamPanel({ serverUrl, createSession, sendAnswer, closeSession, streams, activeStreamId: controlledStreamId, onStreamChange, deviceName, phase, pipelineMetrics, detections, defaultShowDetections = true, defaultShowMotion = false, streamStats, autoPlay = false, showPlayStop = false, snapshotSrc, snapshotLoading = false, onRefreshSnapshot, showStreamStats = false, children, extraOverlay, ptzAvailable = false, ptzShown = false, ptzOverlay, onPtzToggle, intercomAvailable = false, intercomShown = false, onIntercomToggle, chromeless = false, className }) {
|
|
19708
19867
|
const registeredButtons = usePlayerToolbarButtons();
|
|
19709
|
-
const [isPlaying, setIsPlaying] = (0, react.useState)(autoPlay);
|
|
19710
|
-
const [showDetections, setShowDetections] = (0, react.useState)(defaultShowDetections);
|
|
19711
|
-
const [showMotion, setShowMotion] = (0, react.useState)(defaultShowMotion);
|
|
19712
|
-
const [internalStreamId, setInternalStreamId] = (0, react.useState)(null);
|
|
19713
|
-
const [menuOpen, setMenuOpen] = (0, react.useState)(false);
|
|
19714
|
-
const menuRef = (0, react.useRef)(null);
|
|
19715
|
-
(0, react.useEffect)(() => {
|
|
19868
|
+
const [isPlaying, setIsPlaying] = (0, react$1.useState)(autoPlay);
|
|
19869
|
+
const [showDetections, setShowDetections] = (0, react$1.useState)(defaultShowDetections);
|
|
19870
|
+
const [showMotion, setShowMotion] = (0, react$1.useState)(defaultShowMotion);
|
|
19871
|
+
const [internalStreamId, setInternalStreamId] = (0, react$1.useState)(null);
|
|
19872
|
+
const [menuOpen, setMenuOpen] = (0, react$1.useState)(false);
|
|
19873
|
+
const menuRef = (0, react$1.useRef)(null);
|
|
19874
|
+
(0, react$1.useEffect)(() => {
|
|
19716
19875
|
if (!menuOpen) return;
|
|
19717
19876
|
function onClick(e) {
|
|
19718
19877
|
if (menuRef.current && !menuRef.current.contains(e.target)) setMenuOpen(false);
|
|
@@ -19735,7 +19894,7 @@ function StreamPanel({ serverUrl, createSession, sendAnswer, closeSession, strea
|
|
|
19735
19894
|
setTimeout(() => setIsPlaying(true), 50);
|
|
19736
19895
|
}
|
|
19737
19896
|
};
|
|
19738
|
-
const playerCreateSession = (0, react.useMemo)(() => {
|
|
19897
|
+
const playerCreateSession = (0, react$1.useMemo)(() => {
|
|
19739
19898
|
const target = selectedChoice?.target;
|
|
19740
19899
|
if (!target) return void 0;
|
|
19741
19900
|
return (hints) => createSession(target, hints);
|
|
@@ -20058,10 +20217,10 @@ function profileLabel(streamId) {
|
|
|
20058
20217
|
return streamId.charAt(0).toUpperCase() + streamId.slice(1);
|
|
20059
20218
|
}
|
|
20060
20219
|
function StreamBrokerSelector({ deviceId, value, onChange, disabled, label, className }) {
|
|
20061
|
-
const labelId = (0, react.useId)();
|
|
20220
|
+
const labelId = (0, react$1.useId)();
|
|
20062
20221
|
const query = useCameraStreamsGetRtspEntries({ deviceId }, { refetchOnWindowFocus: false });
|
|
20063
|
-
const [options, setOptions] = (0, react.useState)([AUTO_OPTION]);
|
|
20064
|
-
(0, react.useEffect)(() => {
|
|
20222
|
+
const [options, setOptions] = (0, react$1.useState)([AUTO_OPTION]);
|
|
20223
|
+
(0, react$1.useEffect)(() => {
|
|
20065
20224
|
if (!query.data) return;
|
|
20066
20225
|
const prefix = `${deviceId}/`;
|
|
20067
20226
|
const next = [AUTO_OPTION];
|
|
@@ -20100,6 +20259,1479 @@ function StreamBrokerSelector({ deviceId, value, onChange, disabled, label, clas
|
|
|
20100
20259
|
});
|
|
20101
20260
|
}
|
|
20102
20261
|
//#endregion
|
|
20262
|
+
//#region ../../node_modules/qrcode.react/lib/esm/index.js
|
|
20263
|
+
var __defProp = Object.defineProperty;
|
|
20264
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
20265
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
20266
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
20267
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, {
|
|
20268
|
+
enumerable: true,
|
|
20269
|
+
configurable: true,
|
|
20270
|
+
writable: true,
|
|
20271
|
+
value
|
|
20272
|
+
}) : obj[key] = value;
|
|
20273
|
+
var __spreadValues = (a, b) => {
|
|
20274
|
+
for (var prop in b || (b = {})) if (__hasOwnProp.call(b, prop)) __defNormalProp(a, prop, b[prop]);
|
|
20275
|
+
if (__getOwnPropSymbols) {
|
|
20276
|
+
for (var prop of __getOwnPropSymbols(b)) if (__propIsEnum.call(b, prop)) __defNormalProp(a, prop, b[prop]);
|
|
20277
|
+
}
|
|
20278
|
+
return a;
|
|
20279
|
+
};
|
|
20280
|
+
var __objRest = (source, exclude) => {
|
|
20281
|
+
var target = {};
|
|
20282
|
+
for (var prop in source) if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0) target[prop] = source[prop];
|
|
20283
|
+
if (source != null && __getOwnPropSymbols) {
|
|
20284
|
+
for (var prop of __getOwnPropSymbols(source)) if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop)) target[prop] = source[prop];
|
|
20285
|
+
}
|
|
20286
|
+
return target;
|
|
20287
|
+
};
|
|
20288
|
+
/**
|
|
20289
|
+
* @license QR Code generator library (TypeScript)
|
|
20290
|
+
* Copyright (c) Project Nayuki.
|
|
20291
|
+
* SPDX-License-Identifier: MIT
|
|
20292
|
+
*/
|
|
20293
|
+
var qrcodegen;
|
|
20294
|
+
((qrcodegen2) => {
|
|
20295
|
+
const _QrCode = class _QrCode {
|
|
20296
|
+
constructor(version, errorCorrectionLevel, dataCodewords, msk) {
|
|
20297
|
+
this.version = version;
|
|
20298
|
+
this.errorCorrectionLevel = errorCorrectionLevel;
|
|
20299
|
+
this.modules = [];
|
|
20300
|
+
this.isFunction = [];
|
|
20301
|
+
if (version < _QrCode.MIN_VERSION || version > _QrCode.MAX_VERSION) throw new RangeError("Version value out of range");
|
|
20302
|
+
if (msk < -1 || msk > 7) throw new RangeError("Mask value out of range");
|
|
20303
|
+
this.size = version * 4 + 17;
|
|
20304
|
+
let row = [];
|
|
20305
|
+
for (let i = 0; i < this.size; i++) row.push(false);
|
|
20306
|
+
for (let i = 0; i < this.size; i++) {
|
|
20307
|
+
this.modules.push(row.slice());
|
|
20308
|
+
this.isFunction.push(row.slice());
|
|
20309
|
+
}
|
|
20310
|
+
this.drawFunctionPatterns();
|
|
20311
|
+
const allCodewords = this.addEccAndInterleave(dataCodewords);
|
|
20312
|
+
this.drawCodewords(allCodewords);
|
|
20313
|
+
if (msk == -1) {
|
|
20314
|
+
let minPenalty = 1e9;
|
|
20315
|
+
for (let i = 0; i < 8; i++) {
|
|
20316
|
+
this.applyMask(i);
|
|
20317
|
+
this.drawFormatBits(i);
|
|
20318
|
+
const penalty = this.getPenaltyScore();
|
|
20319
|
+
if (penalty < minPenalty) {
|
|
20320
|
+
msk = i;
|
|
20321
|
+
minPenalty = penalty;
|
|
20322
|
+
}
|
|
20323
|
+
this.applyMask(i);
|
|
20324
|
+
}
|
|
20325
|
+
}
|
|
20326
|
+
assert(0 <= msk && msk <= 7);
|
|
20327
|
+
this.mask = msk;
|
|
20328
|
+
this.applyMask(msk);
|
|
20329
|
+
this.drawFormatBits(msk);
|
|
20330
|
+
this.isFunction = [];
|
|
20331
|
+
}
|
|
20332
|
+
static encodeText(text, ecl) {
|
|
20333
|
+
const segs = qrcodegen2.QrSegment.makeSegments(text);
|
|
20334
|
+
return _QrCode.encodeSegments(segs, ecl);
|
|
20335
|
+
}
|
|
20336
|
+
static encodeBinary(data, ecl) {
|
|
20337
|
+
const seg = qrcodegen2.QrSegment.makeBytes(data);
|
|
20338
|
+
return _QrCode.encodeSegments([seg], ecl);
|
|
20339
|
+
}
|
|
20340
|
+
static encodeSegments(segs, ecl, minVersion = 1, maxVersion = 40, mask = -1, boostEcl = true) {
|
|
20341
|
+
if (!(_QrCode.MIN_VERSION <= minVersion && minVersion <= maxVersion && maxVersion <= _QrCode.MAX_VERSION) || mask < -1 || mask > 7) throw new RangeError("Invalid value");
|
|
20342
|
+
let version;
|
|
20343
|
+
let dataUsedBits;
|
|
20344
|
+
for (version = minVersion;; version++) {
|
|
20345
|
+
const dataCapacityBits2 = _QrCode.getNumDataCodewords(version, ecl) * 8;
|
|
20346
|
+
const usedBits = QrSegment.getTotalBits(segs, version);
|
|
20347
|
+
if (usedBits <= dataCapacityBits2) {
|
|
20348
|
+
dataUsedBits = usedBits;
|
|
20349
|
+
break;
|
|
20350
|
+
}
|
|
20351
|
+
if (version >= maxVersion) throw new RangeError("Data too long");
|
|
20352
|
+
}
|
|
20353
|
+
for (const newEcl of [
|
|
20354
|
+
_QrCode.Ecc.MEDIUM,
|
|
20355
|
+
_QrCode.Ecc.QUARTILE,
|
|
20356
|
+
_QrCode.Ecc.HIGH
|
|
20357
|
+
]) if (boostEcl && dataUsedBits <= _QrCode.getNumDataCodewords(version, newEcl) * 8) ecl = newEcl;
|
|
20358
|
+
let bb = [];
|
|
20359
|
+
for (const seg of segs) {
|
|
20360
|
+
appendBits(seg.mode.modeBits, 4, bb);
|
|
20361
|
+
appendBits(seg.numChars, seg.mode.numCharCountBits(version), bb);
|
|
20362
|
+
for (const b of seg.getData()) bb.push(b);
|
|
20363
|
+
}
|
|
20364
|
+
assert(bb.length == dataUsedBits);
|
|
20365
|
+
const dataCapacityBits = _QrCode.getNumDataCodewords(version, ecl) * 8;
|
|
20366
|
+
assert(bb.length <= dataCapacityBits);
|
|
20367
|
+
appendBits(0, Math.min(4, dataCapacityBits - bb.length), bb);
|
|
20368
|
+
appendBits(0, (8 - bb.length % 8) % 8, bb);
|
|
20369
|
+
assert(bb.length % 8 == 0);
|
|
20370
|
+
for (let padByte = 236; bb.length < dataCapacityBits; padByte ^= 253) appendBits(padByte, 8, bb);
|
|
20371
|
+
let dataCodewords = [];
|
|
20372
|
+
while (dataCodewords.length * 8 < bb.length) dataCodewords.push(0);
|
|
20373
|
+
bb.forEach((b, i) => dataCodewords[i >>> 3] |= b << 7 - (i & 7));
|
|
20374
|
+
return new _QrCode(version, ecl, dataCodewords, mask);
|
|
20375
|
+
}
|
|
20376
|
+
getModule(x, y) {
|
|
20377
|
+
return 0 <= x && x < this.size && 0 <= y && y < this.size && this.modules[y][x];
|
|
20378
|
+
}
|
|
20379
|
+
getModules() {
|
|
20380
|
+
return this.modules;
|
|
20381
|
+
}
|
|
20382
|
+
drawFunctionPatterns() {
|
|
20383
|
+
for (let i = 0; i < this.size; i++) {
|
|
20384
|
+
this.setFunctionModule(6, i, i % 2 == 0);
|
|
20385
|
+
this.setFunctionModule(i, 6, i % 2 == 0);
|
|
20386
|
+
}
|
|
20387
|
+
this.drawFinderPattern(3, 3);
|
|
20388
|
+
this.drawFinderPattern(this.size - 4, 3);
|
|
20389
|
+
this.drawFinderPattern(3, this.size - 4);
|
|
20390
|
+
const alignPatPos = this.getAlignmentPatternPositions();
|
|
20391
|
+
const numAlign = alignPatPos.length;
|
|
20392
|
+
for (let i = 0; i < numAlign; i++) for (let j = 0; j < numAlign; j++) if (!(i == 0 && j == 0 || i == 0 && j == numAlign - 1 || i == numAlign - 1 && j == 0)) this.drawAlignmentPattern(alignPatPos[i], alignPatPos[j]);
|
|
20393
|
+
this.drawFormatBits(0);
|
|
20394
|
+
this.drawVersion();
|
|
20395
|
+
}
|
|
20396
|
+
drawFormatBits(mask) {
|
|
20397
|
+
const data = this.errorCorrectionLevel.formatBits << 3 | mask;
|
|
20398
|
+
let rem = data;
|
|
20399
|
+
for (let i = 0; i < 10; i++) rem = rem << 1 ^ (rem >>> 9) * 1335;
|
|
20400
|
+
const bits = (data << 10 | rem) ^ 21522;
|
|
20401
|
+
assert(bits >>> 15 == 0);
|
|
20402
|
+
for (let i = 0; i <= 5; i++) this.setFunctionModule(8, i, getBit(bits, i));
|
|
20403
|
+
this.setFunctionModule(8, 7, getBit(bits, 6));
|
|
20404
|
+
this.setFunctionModule(8, 8, getBit(bits, 7));
|
|
20405
|
+
this.setFunctionModule(7, 8, getBit(bits, 8));
|
|
20406
|
+
for (let i = 9; i < 15; i++) this.setFunctionModule(14 - i, 8, getBit(bits, i));
|
|
20407
|
+
for (let i = 0; i < 8; i++) this.setFunctionModule(this.size - 1 - i, 8, getBit(bits, i));
|
|
20408
|
+
for (let i = 8; i < 15; i++) this.setFunctionModule(8, this.size - 15 + i, getBit(bits, i));
|
|
20409
|
+
this.setFunctionModule(8, this.size - 8, true);
|
|
20410
|
+
}
|
|
20411
|
+
drawVersion() {
|
|
20412
|
+
if (this.version < 7) return;
|
|
20413
|
+
let rem = this.version;
|
|
20414
|
+
for (let i = 0; i < 12; i++) rem = rem << 1 ^ (rem >>> 11) * 7973;
|
|
20415
|
+
const bits = this.version << 12 | rem;
|
|
20416
|
+
assert(bits >>> 18 == 0);
|
|
20417
|
+
for (let i = 0; i < 18; i++) {
|
|
20418
|
+
const color = getBit(bits, i);
|
|
20419
|
+
const a = this.size - 11 + i % 3;
|
|
20420
|
+
const b = Math.floor(i / 3);
|
|
20421
|
+
this.setFunctionModule(a, b, color);
|
|
20422
|
+
this.setFunctionModule(b, a, color);
|
|
20423
|
+
}
|
|
20424
|
+
}
|
|
20425
|
+
drawFinderPattern(x, y) {
|
|
20426
|
+
for (let dy = -4; dy <= 4; dy++) for (let dx = -4; dx <= 4; dx++) {
|
|
20427
|
+
const dist = Math.max(Math.abs(dx), Math.abs(dy));
|
|
20428
|
+
const xx = x + dx;
|
|
20429
|
+
const yy = y + dy;
|
|
20430
|
+
if (0 <= xx && xx < this.size && 0 <= yy && yy < this.size) this.setFunctionModule(xx, yy, dist != 2 && dist != 4);
|
|
20431
|
+
}
|
|
20432
|
+
}
|
|
20433
|
+
drawAlignmentPattern(x, y) {
|
|
20434
|
+
for (let dy = -2; dy <= 2; dy++) for (let dx = -2; dx <= 2; dx++) this.setFunctionModule(x + dx, y + dy, Math.max(Math.abs(dx), Math.abs(dy)) != 1);
|
|
20435
|
+
}
|
|
20436
|
+
setFunctionModule(x, y, isDark) {
|
|
20437
|
+
this.modules[y][x] = isDark;
|
|
20438
|
+
this.isFunction[y][x] = true;
|
|
20439
|
+
}
|
|
20440
|
+
addEccAndInterleave(data) {
|
|
20441
|
+
const ver = this.version;
|
|
20442
|
+
const ecl = this.errorCorrectionLevel;
|
|
20443
|
+
if (data.length != _QrCode.getNumDataCodewords(ver, ecl)) throw new RangeError("Invalid argument");
|
|
20444
|
+
const numBlocks = _QrCode.NUM_ERROR_CORRECTION_BLOCKS[ecl.ordinal][ver];
|
|
20445
|
+
const blockEccLen = _QrCode.ECC_CODEWORDS_PER_BLOCK[ecl.ordinal][ver];
|
|
20446
|
+
const rawCodewords = Math.floor(_QrCode.getNumRawDataModules(ver) / 8);
|
|
20447
|
+
const numShortBlocks = numBlocks - rawCodewords % numBlocks;
|
|
20448
|
+
const shortBlockLen = Math.floor(rawCodewords / numBlocks);
|
|
20449
|
+
let blocks = [];
|
|
20450
|
+
const rsDiv = _QrCode.reedSolomonComputeDivisor(blockEccLen);
|
|
20451
|
+
for (let i = 0, k = 0; i < numBlocks; i++) {
|
|
20452
|
+
let dat = data.slice(k, k + shortBlockLen - blockEccLen + (i < numShortBlocks ? 0 : 1));
|
|
20453
|
+
k += dat.length;
|
|
20454
|
+
const ecc = _QrCode.reedSolomonComputeRemainder(dat, rsDiv);
|
|
20455
|
+
if (i < numShortBlocks) dat.push(0);
|
|
20456
|
+
blocks.push(dat.concat(ecc));
|
|
20457
|
+
}
|
|
20458
|
+
let result = [];
|
|
20459
|
+
for (let i = 0; i < blocks[0].length; i++) blocks.forEach((block, j) => {
|
|
20460
|
+
if (i != shortBlockLen - blockEccLen || j >= numShortBlocks) result.push(block[i]);
|
|
20461
|
+
});
|
|
20462
|
+
assert(result.length == rawCodewords);
|
|
20463
|
+
return result;
|
|
20464
|
+
}
|
|
20465
|
+
drawCodewords(data) {
|
|
20466
|
+
if (data.length != Math.floor(_QrCode.getNumRawDataModules(this.version) / 8)) throw new RangeError("Invalid argument");
|
|
20467
|
+
let i = 0;
|
|
20468
|
+
for (let right = this.size - 1; right >= 1; right -= 2) {
|
|
20469
|
+
if (right == 6) right = 5;
|
|
20470
|
+
for (let vert = 0; vert < this.size; vert++) for (let j = 0; j < 2; j++) {
|
|
20471
|
+
const x = right - j;
|
|
20472
|
+
const y = (right + 1 & 2) == 0 ? this.size - 1 - vert : vert;
|
|
20473
|
+
if (!this.isFunction[y][x] && i < data.length * 8) {
|
|
20474
|
+
this.modules[y][x] = getBit(data[i >>> 3], 7 - (i & 7));
|
|
20475
|
+
i++;
|
|
20476
|
+
}
|
|
20477
|
+
}
|
|
20478
|
+
}
|
|
20479
|
+
assert(i == data.length * 8);
|
|
20480
|
+
}
|
|
20481
|
+
applyMask(mask) {
|
|
20482
|
+
if (mask < 0 || mask > 7) throw new RangeError("Mask value out of range");
|
|
20483
|
+
for (let y = 0; y < this.size; y++) for (let x = 0; x < this.size; x++) {
|
|
20484
|
+
let invert;
|
|
20485
|
+
switch (mask) {
|
|
20486
|
+
case 0:
|
|
20487
|
+
invert = (x + y) % 2 == 0;
|
|
20488
|
+
break;
|
|
20489
|
+
case 1:
|
|
20490
|
+
invert = y % 2 == 0;
|
|
20491
|
+
break;
|
|
20492
|
+
case 2:
|
|
20493
|
+
invert = x % 3 == 0;
|
|
20494
|
+
break;
|
|
20495
|
+
case 3:
|
|
20496
|
+
invert = (x + y) % 3 == 0;
|
|
20497
|
+
break;
|
|
20498
|
+
case 4:
|
|
20499
|
+
invert = (Math.floor(x / 3) + Math.floor(y / 2)) % 2 == 0;
|
|
20500
|
+
break;
|
|
20501
|
+
case 5:
|
|
20502
|
+
invert = x * y % 2 + x * y % 3 == 0;
|
|
20503
|
+
break;
|
|
20504
|
+
case 6:
|
|
20505
|
+
invert = (x * y % 2 + x * y % 3) % 2 == 0;
|
|
20506
|
+
break;
|
|
20507
|
+
case 7:
|
|
20508
|
+
invert = ((x + y) % 2 + x * y % 3) % 2 == 0;
|
|
20509
|
+
break;
|
|
20510
|
+
default: throw new Error("Unreachable");
|
|
20511
|
+
}
|
|
20512
|
+
if (!this.isFunction[y][x] && invert) this.modules[y][x] = !this.modules[y][x];
|
|
20513
|
+
}
|
|
20514
|
+
}
|
|
20515
|
+
getPenaltyScore() {
|
|
20516
|
+
let result = 0;
|
|
20517
|
+
for (let y = 0; y < this.size; y++) {
|
|
20518
|
+
let runColor = false;
|
|
20519
|
+
let runX = 0;
|
|
20520
|
+
let runHistory = [
|
|
20521
|
+
0,
|
|
20522
|
+
0,
|
|
20523
|
+
0,
|
|
20524
|
+
0,
|
|
20525
|
+
0,
|
|
20526
|
+
0,
|
|
20527
|
+
0
|
|
20528
|
+
];
|
|
20529
|
+
for (let x = 0; x < this.size; x++) if (this.modules[y][x] == runColor) {
|
|
20530
|
+
runX++;
|
|
20531
|
+
if (runX == 5) result += _QrCode.PENALTY_N1;
|
|
20532
|
+
else if (runX > 5) result++;
|
|
20533
|
+
} else {
|
|
20534
|
+
this.finderPenaltyAddHistory(runX, runHistory);
|
|
20535
|
+
if (!runColor) result += this.finderPenaltyCountPatterns(runHistory) * _QrCode.PENALTY_N3;
|
|
20536
|
+
runColor = this.modules[y][x];
|
|
20537
|
+
runX = 1;
|
|
20538
|
+
}
|
|
20539
|
+
result += this.finderPenaltyTerminateAndCount(runColor, runX, runHistory) * _QrCode.PENALTY_N3;
|
|
20540
|
+
}
|
|
20541
|
+
for (let x = 0; x < this.size; x++) {
|
|
20542
|
+
let runColor = false;
|
|
20543
|
+
let runY = 0;
|
|
20544
|
+
let runHistory = [
|
|
20545
|
+
0,
|
|
20546
|
+
0,
|
|
20547
|
+
0,
|
|
20548
|
+
0,
|
|
20549
|
+
0,
|
|
20550
|
+
0,
|
|
20551
|
+
0
|
|
20552
|
+
];
|
|
20553
|
+
for (let y = 0; y < this.size; y++) if (this.modules[y][x] == runColor) {
|
|
20554
|
+
runY++;
|
|
20555
|
+
if (runY == 5) result += _QrCode.PENALTY_N1;
|
|
20556
|
+
else if (runY > 5) result++;
|
|
20557
|
+
} else {
|
|
20558
|
+
this.finderPenaltyAddHistory(runY, runHistory);
|
|
20559
|
+
if (!runColor) result += this.finderPenaltyCountPatterns(runHistory) * _QrCode.PENALTY_N3;
|
|
20560
|
+
runColor = this.modules[y][x];
|
|
20561
|
+
runY = 1;
|
|
20562
|
+
}
|
|
20563
|
+
result += this.finderPenaltyTerminateAndCount(runColor, runY, runHistory) * _QrCode.PENALTY_N3;
|
|
20564
|
+
}
|
|
20565
|
+
for (let y = 0; y < this.size - 1; y++) for (let x = 0; x < this.size - 1; x++) {
|
|
20566
|
+
const color = this.modules[y][x];
|
|
20567
|
+
if (color == this.modules[y][x + 1] && color == this.modules[y + 1][x] && color == this.modules[y + 1][x + 1]) result += _QrCode.PENALTY_N2;
|
|
20568
|
+
}
|
|
20569
|
+
let dark = 0;
|
|
20570
|
+
for (const row of this.modules) dark = row.reduce((sum, color) => sum + (color ? 1 : 0), dark);
|
|
20571
|
+
const total = this.size * this.size;
|
|
20572
|
+
const k = Math.ceil(Math.abs(dark * 20 - total * 10) / total) - 1;
|
|
20573
|
+
assert(0 <= k && k <= 9);
|
|
20574
|
+
result += k * _QrCode.PENALTY_N4;
|
|
20575
|
+
assert(0 <= result && result <= 2568888);
|
|
20576
|
+
return result;
|
|
20577
|
+
}
|
|
20578
|
+
getAlignmentPatternPositions() {
|
|
20579
|
+
if (this.version == 1) return [];
|
|
20580
|
+
else {
|
|
20581
|
+
const numAlign = Math.floor(this.version / 7) + 2;
|
|
20582
|
+
const step = this.version == 32 ? 26 : Math.ceil((this.version * 4 + 4) / (numAlign * 2 - 2)) * 2;
|
|
20583
|
+
let result = [6];
|
|
20584
|
+
for (let pos = this.size - 7; result.length < numAlign; pos -= step) result.splice(1, 0, pos);
|
|
20585
|
+
return result;
|
|
20586
|
+
}
|
|
20587
|
+
}
|
|
20588
|
+
static getNumRawDataModules(ver) {
|
|
20589
|
+
if (ver < _QrCode.MIN_VERSION || ver > _QrCode.MAX_VERSION) throw new RangeError("Version number out of range");
|
|
20590
|
+
let result = (16 * ver + 128) * ver + 64;
|
|
20591
|
+
if (ver >= 2) {
|
|
20592
|
+
const numAlign = Math.floor(ver / 7) + 2;
|
|
20593
|
+
result -= (25 * numAlign - 10) * numAlign - 55;
|
|
20594
|
+
if (ver >= 7) result -= 36;
|
|
20595
|
+
}
|
|
20596
|
+
assert(208 <= result && result <= 29648);
|
|
20597
|
+
return result;
|
|
20598
|
+
}
|
|
20599
|
+
static getNumDataCodewords(ver, ecl) {
|
|
20600
|
+
return Math.floor(_QrCode.getNumRawDataModules(ver) / 8) - _QrCode.ECC_CODEWORDS_PER_BLOCK[ecl.ordinal][ver] * _QrCode.NUM_ERROR_CORRECTION_BLOCKS[ecl.ordinal][ver];
|
|
20601
|
+
}
|
|
20602
|
+
static reedSolomonComputeDivisor(degree) {
|
|
20603
|
+
if (degree < 1 || degree > 255) throw new RangeError("Degree out of range");
|
|
20604
|
+
let result = [];
|
|
20605
|
+
for (let i = 0; i < degree - 1; i++) result.push(0);
|
|
20606
|
+
result.push(1);
|
|
20607
|
+
let root = 1;
|
|
20608
|
+
for (let i = 0; i < degree; i++) {
|
|
20609
|
+
for (let j = 0; j < result.length; j++) {
|
|
20610
|
+
result[j] = _QrCode.reedSolomonMultiply(result[j], root);
|
|
20611
|
+
if (j + 1 < result.length) result[j] ^= result[j + 1];
|
|
20612
|
+
}
|
|
20613
|
+
root = _QrCode.reedSolomonMultiply(root, 2);
|
|
20614
|
+
}
|
|
20615
|
+
return result;
|
|
20616
|
+
}
|
|
20617
|
+
static reedSolomonComputeRemainder(data, divisor) {
|
|
20618
|
+
let result = divisor.map((_) => 0);
|
|
20619
|
+
for (const b of data) {
|
|
20620
|
+
const factor = b ^ result.shift();
|
|
20621
|
+
result.push(0);
|
|
20622
|
+
divisor.forEach((coef, i) => result[i] ^= _QrCode.reedSolomonMultiply(coef, factor));
|
|
20623
|
+
}
|
|
20624
|
+
return result;
|
|
20625
|
+
}
|
|
20626
|
+
static reedSolomonMultiply(x, y) {
|
|
20627
|
+
if (x >>> 8 != 0 || y >>> 8 != 0) throw new RangeError("Byte out of range");
|
|
20628
|
+
let z = 0;
|
|
20629
|
+
for (let i = 7; i >= 0; i--) {
|
|
20630
|
+
z = z << 1 ^ (z >>> 7) * 285;
|
|
20631
|
+
z ^= (y >>> i & 1) * x;
|
|
20632
|
+
}
|
|
20633
|
+
assert(z >>> 8 == 0);
|
|
20634
|
+
return z;
|
|
20635
|
+
}
|
|
20636
|
+
finderPenaltyCountPatterns(runHistory) {
|
|
20637
|
+
const n = runHistory[1];
|
|
20638
|
+
assert(n <= this.size * 3);
|
|
20639
|
+
const core = n > 0 && runHistory[2] == n && runHistory[3] == n * 3 && runHistory[4] == n && runHistory[5] == n;
|
|
20640
|
+
return (core && runHistory[0] >= n * 4 && runHistory[6] >= n ? 1 : 0) + (core && runHistory[6] >= n * 4 && runHistory[0] >= n ? 1 : 0);
|
|
20641
|
+
}
|
|
20642
|
+
finderPenaltyTerminateAndCount(currentRunColor, currentRunLength, runHistory) {
|
|
20643
|
+
if (currentRunColor) {
|
|
20644
|
+
this.finderPenaltyAddHistory(currentRunLength, runHistory);
|
|
20645
|
+
currentRunLength = 0;
|
|
20646
|
+
}
|
|
20647
|
+
currentRunLength += this.size;
|
|
20648
|
+
this.finderPenaltyAddHistory(currentRunLength, runHistory);
|
|
20649
|
+
return this.finderPenaltyCountPatterns(runHistory);
|
|
20650
|
+
}
|
|
20651
|
+
finderPenaltyAddHistory(currentRunLength, runHistory) {
|
|
20652
|
+
if (runHistory[0] == 0) currentRunLength += this.size;
|
|
20653
|
+
runHistory.pop();
|
|
20654
|
+
runHistory.unshift(currentRunLength);
|
|
20655
|
+
}
|
|
20656
|
+
};
|
|
20657
|
+
_QrCode.MIN_VERSION = 1;
|
|
20658
|
+
_QrCode.MAX_VERSION = 40;
|
|
20659
|
+
_QrCode.PENALTY_N1 = 3;
|
|
20660
|
+
_QrCode.PENALTY_N2 = 3;
|
|
20661
|
+
_QrCode.PENALTY_N3 = 40;
|
|
20662
|
+
_QrCode.PENALTY_N4 = 10;
|
|
20663
|
+
_QrCode.ECC_CODEWORDS_PER_BLOCK = [
|
|
20664
|
+
[
|
|
20665
|
+
-1,
|
|
20666
|
+
7,
|
|
20667
|
+
10,
|
|
20668
|
+
15,
|
|
20669
|
+
20,
|
|
20670
|
+
26,
|
|
20671
|
+
18,
|
|
20672
|
+
20,
|
|
20673
|
+
24,
|
|
20674
|
+
30,
|
|
20675
|
+
18,
|
|
20676
|
+
20,
|
|
20677
|
+
24,
|
|
20678
|
+
26,
|
|
20679
|
+
30,
|
|
20680
|
+
22,
|
|
20681
|
+
24,
|
|
20682
|
+
28,
|
|
20683
|
+
30,
|
|
20684
|
+
28,
|
|
20685
|
+
28,
|
|
20686
|
+
28,
|
|
20687
|
+
28,
|
|
20688
|
+
30,
|
|
20689
|
+
30,
|
|
20690
|
+
26,
|
|
20691
|
+
28,
|
|
20692
|
+
30,
|
|
20693
|
+
30,
|
|
20694
|
+
30,
|
|
20695
|
+
30,
|
|
20696
|
+
30,
|
|
20697
|
+
30,
|
|
20698
|
+
30,
|
|
20699
|
+
30,
|
|
20700
|
+
30,
|
|
20701
|
+
30,
|
|
20702
|
+
30,
|
|
20703
|
+
30,
|
|
20704
|
+
30,
|
|
20705
|
+
30
|
|
20706
|
+
],
|
|
20707
|
+
[
|
|
20708
|
+
-1,
|
|
20709
|
+
10,
|
|
20710
|
+
16,
|
|
20711
|
+
26,
|
|
20712
|
+
18,
|
|
20713
|
+
24,
|
|
20714
|
+
16,
|
|
20715
|
+
18,
|
|
20716
|
+
22,
|
|
20717
|
+
22,
|
|
20718
|
+
26,
|
|
20719
|
+
30,
|
|
20720
|
+
22,
|
|
20721
|
+
22,
|
|
20722
|
+
24,
|
|
20723
|
+
24,
|
|
20724
|
+
28,
|
|
20725
|
+
28,
|
|
20726
|
+
26,
|
|
20727
|
+
26,
|
|
20728
|
+
26,
|
|
20729
|
+
26,
|
|
20730
|
+
28,
|
|
20731
|
+
28,
|
|
20732
|
+
28,
|
|
20733
|
+
28,
|
|
20734
|
+
28,
|
|
20735
|
+
28,
|
|
20736
|
+
28,
|
|
20737
|
+
28,
|
|
20738
|
+
28,
|
|
20739
|
+
28,
|
|
20740
|
+
28,
|
|
20741
|
+
28,
|
|
20742
|
+
28,
|
|
20743
|
+
28,
|
|
20744
|
+
28,
|
|
20745
|
+
28,
|
|
20746
|
+
28,
|
|
20747
|
+
28,
|
|
20748
|
+
28
|
|
20749
|
+
],
|
|
20750
|
+
[
|
|
20751
|
+
-1,
|
|
20752
|
+
13,
|
|
20753
|
+
22,
|
|
20754
|
+
18,
|
|
20755
|
+
26,
|
|
20756
|
+
18,
|
|
20757
|
+
24,
|
|
20758
|
+
18,
|
|
20759
|
+
22,
|
|
20760
|
+
20,
|
|
20761
|
+
24,
|
|
20762
|
+
28,
|
|
20763
|
+
26,
|
|
20764
|
+
24,
|
|
20765
|
+
20,
|
|
20766
|
+
30,
|
|
20767
|
+
24,
|
|
20768
|
+
28,
|
|
20769
|
+
28,
|
|
20770
|
+
26,
|
|
20771
|
+
30,
|
|
20772
|
+
28,
|
|
20773
|
+
30,
|
|
20774
|
+
30,
|
|
20775
|
+
30,
|
|
20776
|
+
30,
|
|
20777
|
+
28,
|
|
20778
|
+
30,
|
|
20779
|
+
30,
|
|
20780
|
+
30,
|
|
20781
|
+
30,
|
|
20782
|
+
30,
|
|
20783
|
+
30,
|
|
20784
|
+
30,
|
|
20785
|
+
30,
|
|
20786
|
+
30,
|
|
20787
|
+
30,
|
|
20788
|
+
30,
|
|
20789
|
+
30,
|
|
20790
|
+
30,
|
|
20791
|
+
30
|
|
20792
|
+
],
|
|
20793
|
+
[
|
|
20794
|
+
-1,
|
|
20795
|
+
17,
|
|
20796
|
+
28,
|
|
20797
|
+
22,
|
|
20798
|
+
16,
|
|
20799
|
+
22,
|
|
20800
|
+
28,
|
|
20801
|
+
26,
|
|
20802
|
+
26,
|
|
20803
|
+
24,
|
|
20804
|
+
28,
|
|
20805
|
+
24,
|
|
20806
|
+
28,
|
|
20807
|
+
22,
|
|
20808
|
+
24,
|
|
20809
|
+
24,
|
|
20810
|
+
30,
|
|
20811
|
+
28,
|
|
20812
|
+
28,
|
|
20813
|
+
26,
|
|
20814
|
+
28,
|
|
20815
|
+
30,
|
|
20816
|
+
24,
|
|
20817
|
+
30,
|
|
20818
|
+
30,
|
|
20819
|
+
30,
|
|
20820
|
+
30,
|
|
20821
|
+
30,
|
|
20822
|
+
30,
|
|
20823
|
+
30,
|
|
20824
|
+
30,
|
|
20825
|
+
30,
|
|
20826
|
+
30,
|
|
20827
|
+
30,
|
|
20828
|
+
30,
|
|
20829
|
+
30,
|
|
20830
|
+
30,
|
|
20831
|
+
30,
|
|
20832
|
+
30,
|
|
20833
|
+
30,
|
|
20834
|
+
30
|
|
20835
|
+
]
|
|
20836
|
+
];
|
|
20837
|
+
_QrCode.NUM_ERROR_CORRECTION_BLOCKS = [
|
|
20838
|
+
[
|
|
20839
|
+
-1,
|
|
20840
|
+
1,
|
|
20841
|
+
1,
|
|
20842
|
+
1,
|
|
20843
|
+
1,
|
|
20844
|
+
1,
|
|
20845
|
+
2,
|
|
20846
|
+
2,
|
|
20847
|
+
2,
|
|
20848
|
+
2,
|
|
20849
|
+
4,
|
|
20850
|
+
4,
|
|
20851
|
+
4,
|
|
20852
|
+
4,
|
|
20853
|
+
4,
|
|
20854
|
+
6,
|
|
20855
|
+
6,
|
|
20856
|
+
6,
|
|
20857
|
+
6,
|
|
20858
|
+
7,
|
|
20859
|
+
8,
|
|
20860
|
+
8,
|
|
20861
|
+
9,
|
|
20862
|
+
9,
|
|
20863
|
+
10,
|
|
20864
|
+
12,
|
|
20865
|
+
12,
|
|
20866
|
+
12,
|
|
20867
|
+
13,
|
|
20868
|
+
14,
|
|
20869
|
+
15,
|
|
20870
|
+
16,
|
|
20871
|
+
17,
|
|
20872
|
+
18,
|
|
20873
|
+
19,
|
|
20874
|
+
19,
|
|
20875
|
+
20,
|
|
20876
|
+
21,
|
|
20877
|
+
22,
|
|
20878
|
+
24,
|
|
20879
|
+
25
|
|
20880
|
+
],
|
|
20881
|
+
[
|
|
20882
|
+
-1,
|
|
20883
|
+
1,
|
|
20884
|
+
1,
|
|
20885
|
+
1,
|
|
20886
|
+
2,
|
|
20887
|
+
2,
|
|
20888
|
+
4,
|
|
20889
|
+
4,
|
|
20890
|
+
4,
|
|
20891
|
+
5,
|
|
20892
|
+
5,
|
|
20893
|
+
5,
|
|
20894
|
+
8,
|
|
20895
|
+
9,
|
|
20896
|
+
9,
|
|
20897
|
+
10,
|
|
20898
|
+
10,
|
|
20899
|
+
11,
|
|
20900
|
+
13,
|
|
20901
|
+
14,
|
|
20902
|
+
16,
|
|
20903
|
+
17,
|
|
20904
|
+
17,
|
|
20905
|
+
18,
|
|
20906
|
+
20,
|
|
20907
|
+
21,
|
|
20908
|
+
23,
|
|
20909
|
+
25,
|
|
20910
|
+
26,
|
|
20911
|
+
28,
|
|
20912
|
+
29,
|
|
20913
|
+
31,
|
|
20914
|
+
33,
|
|
20915
|
+
35,
|
|
20916
|
+
37,
|
|
20917
|
+
38,
|
|
20918
|
+
40,
|
|
20919
|
+
43,
|
|
20920
|
+
45,
|
|
20921
|
+
47,
|
|
20922
|
+
49
|
|
20923
|
+
],
|
|
20924
|
+
[
|
|
20925
|
+
-1,
|
|
20926
|
+
1,
|
|
20927
|
+
1,
|
|
20928
|
+
2,
|
|
20929
|
+
2,
|
|
20930
|
+
4,
|
|
20931
|
+
4,
|
|
20932
|
+
6,
|
|
20933
|
+
6,
|
|
20934
|
+
8,
|
|
20935
|
+
8,
|
|
20936
|
+
8,
|
|
20937
|
+
10,
|
|
20938
|
+
12,
|
|
20939
|
+
16,
|
|
20940
|
+
12,
|
|
20941
|
+
17,
|
|
20942
|
+
16,
|
|
20943
|
+
18,
|
|
20944
|
+
21,
|
|
20945
|
+
20,
|
|
20946
|
+
23,
|
|
20947
|
+
23,
|
|
20948
|
+
25,
|
|
20949
|
+
27,
|
|
20950
|
+
29,
|
|
20951
|
+
34,
|
|
20952
|
+
34,
|
|
20953
|
+
35,
|
|
20954
|
+
38,
|
|
20955
|
+
40,
|
|
20956
|
+
43,
|
|
20957
|
+
45,
|
|
20958
|
+
48,
|
|
20959
|
+
51,
|
|
20960
|
+
53,
|
|
20961
|
+
56,
|
|
20962
|
+
59,
|
|
20963
|
+
62,
|
|
20964
|
+
65,
|
|
20965
|
+
68
|
|
20966
|
+
],
|
|
20967
|
+
[
|
|
20968
|
+
-1,
|
|
20969
|
+
1,
|
|
20970
|
+
1,
|
|
20971
|
+
2,
|
|
20972
|
+
4,
|
|
20973
|
+
4,
|
|
20974
|
+
4,
|
|
20975
|
+
5,
|
|
20976
|
+
6,
|
|
20977
|
+
8,
|
|
20978
|
+
8,
|
|
20979
|
+
11,
|
|
20980
|
+
11,
|
|
20981
|
+
16,
|
|
20982
|
+
16,
|
|
20983
|
+
18,
|
|
20984
|
+
16,
|
|
20985
|
+
19,
|
|
20986
|
+
21,
|
|
20987
|
+
25,
|
|
20988
|
+
25,
|
|
20989
|
+
25,
|
|
20990
|
+
34,
|
|
20991
|
+
30,
|
|
20992
|
+
32,
|
|
20993
|
+
35,
|
|
20994
|
+
37,
|
|
20995
|
+
40,
|
|
20996
|
+
42,
|
|
20997
|
+
45,
|
|
20998
|
+
48,
|
|
20999
|
+
51,
|
|
21000
|
+
54,
|
|
21001
|
+
57,
|
|
21002
|
+
60,
|
|
21003
|
+
63,
|
|
21004
|
+
66,
|
|
21005
|
+
70,
|
|
21006
|
+
74,
|
|
21007
|
+
77,
|
|
21008
|
+
81
|
|
21009
|
+
]
|
|
21010
|
+
];
|
|
21011
|
+
qrcodegen2.QrCode = _QrCode;
|
|
21012
|
+
function appendBits(val, len, bb) {
|
|
21013
|
+
if (len < 0 || len > 31 || val >>> len != 0) throw new RangeError("Value out of range");
|
|
21014
|
+
for (let i = len - 1; i >= 0; i--) bb.push(val >>> i & 1);
|
|
21015
|
+
}
|
|
21016
|
+
function getBit(x, i) {
|
|
21017
|
+
return (x >>> i & 1) != 0;
|
|
21018
|
+
}
|
|
21019
|
+
function assert(cond) {
|
|
21020
|
+
if (!cond) throw new Error("Assertion error");
|
|
21021
|
+
}
|
|
21022
|
+
const _QrSegment = class _QrSegment {
|
|
21023
|
+
constructor(mode, numChars, bitData) {
|
|
21024
|
+
this.mode = mode;
|
|
21025
|
+
this.numChars = numChars;
|
|
21026
|
+
this.bitData = bitData;
|
|
21027
|
+
if (numChars < 0) throw new RangeError("Invalid argument");
|
|
21028
|
+
this.bitData = bitData.slice();
|
|
21029
|
+
}
|
|
21030
|
+
static makeBytes(data) {
|
|
21031
|
+
let bb = [];
|
|
21032
|
+
for (const b of data) appendBits(b, 8, bb);
|
|
21033
|
+
return new _QrSegment(_QrSegment.Mode.BYTE, data.length, bb);
|
|
21034
|
+
}
|
|
21035
|
+
static makeNumeric(digits) {
|
|
21036
|
+
if (!_QrSegment.isNumeric(digits)) throw new RangeError("String contains non-numeric characters");
|
|
21037
|
+
let bb = [];
|
|
21038
|
+
for (let i = 0; i < digits.length;) {
|
|
21039
|
+
const n = Math.min(digits.length - i, 3);
|
|
21040
|
+
appendBits(parseInt(digits.substring(i, i + n), 10), n * 3 + 1, bb);
|
|
21041
|
+
i += n;
|
|
21042
|
+
}
|
|
21043
|
+
return new _QrSegment(_QrSegment.Mode.NUMERIC, digits.length, bb);
|
|
21044
|
+
}
|
|
21045
|
+
static makeAlphanumeric(text) {
|
|
21046
|
+
if (!_QrSegment.isAlphanumeric(text)) throw new RangeError("String contains unencodable characters in alphanumeric mode");
|
|
21047
|
+
let bb = [];
|
|
21048
|
+
let i;
|
|
21049
|
+
for (i = 0; i + 2 <= text.length; i += 2) {
|
|
21050
|
+
let temp = _QrSegment.ALPHANUMERIC_CHARSET.indexOf(text.charAt(i)) * 45;
|
|
21051
|
+
temp += _QrSegment.ALPHANUMERIC_CHARSET.indexOf(text.charAt(i + 1));
|
|
21052
|
+
appendBits(temp, 11, bb);
|
|
21053
|
+
}
|
|
21054
|
+
if (i < text.length) appendBits(_QrSegment.ALPHANUMERIC_CHARSET.indexOf(text.charAt(i)), 6, bb);
|
|
21055
|
+
return new _QrSegment(_QrSegment.Mode.ALPHANUMERIC, text.length, bb);
|
|
21056
|
+
}
|
|
21057
|
+
static makeSegments(text) {
|
|
21058
|
+
if (text == "") return [];
|
|
21059
|
+
else if (_QrSegment.isNumeric(text)) return [_QrSegment.makeNumeric(text)];
|
|
21060
|
+
else if (_QrSegment.isAlphanumeric(text)) return [_QrSegment.makeAlphanumeric(text)];
|
|
21061
|
+
else return [_QrSegment.makeBytes(_QrSegment.toUtf8ByteArray(text))];
|
|
21062
|
+
}
|
|
21063
|
+
static makeEci(assignVal) {
|
|
21064
|
+
let bb = [];
|
|
21065
|
+
if (assignVal < 0) throw new RangeError("ECI assignment value out of range");
|
|
21066
|
+
else if (assignVal < 128) appendBits(assignVal, 8, bb);
|
|
21067
|
+
else if (assignVal < 16384) {
|
|
21068
|
+
appendBits(2, 2, bb);
|
|
21069
|
+
appendBits(assignVal, 14, bb);
|
|
21070
|
+
} else if (assignVal < 1e6) {
|
|
21071
|
+
appendBits(6, 3, bb);
|
|
21072
|
+
appendBits(assignVal, 21, bb);
|
|
21073
|
+
} else throw new RangeError("ECI assignment value out of range");
|
|
21074
|
+
return new _QrSegment(_QrSegment.Mode.ECI, 0, bb);
|
|
21075
|
+
}
|
|
21076
|
+
static isNumeric(text) {
|
|
21077
|
+
return _QrSegment.NUMERIC_REGEX.test(text);
|
|
21078
|
+
}
|
|
21079
|
+
static isAlphanumeric(text) {
|
|
21080
|
+
return _QrSegment.ALPHANUMERIC_REGEX.test(text);
|
|
21081
|
+
}
|
|
21082
|
+
getData() {
|
|
21083
|
+
return this.bitData.slice();
|
|
21084
|
+
}
|
|
21085
|
+
static getTotalBits(segs, version) {
|
|
21086
|
+
let result = 0;
|
|
21087
|
+
for (const seg of segs) {
|
|
21088
|
+
const ccbits = seg.mode.numCharCountBits(version);
|
|
21089
|
+
if (seg.numChars >= 1 << ccbits) return Infinity;
|
|
21090
|
+
result += 4 + ccbits + seg.bitData.length;
|
|
21091
|
+
}
|
|
21092
|
+
return result;
|
|
21093
|
+
}
|
|
21094
|
+
static toUtf8ByteArray(str) {
|
|
21095
|
+
str = encodeURI(str);
|
|
21096
|
+
let result = [];
|
|
21097
|
+
for (let i = 0; i < str.length; i++) if (str.charAt(i) != "%") result.push(str.charCodeAt(i));
|
|
21098
|
+
else {
|
|
21099
|
+
result.push(parseInt(str.substring(i + 1, i + 3), 16));
|
|
21100
|
+
i += 2;
|
|
21101
|
+
}
|
|
21102
|
+
return result;
|
|
21103
|
+
}
|
|
21104
|
+
};
|
|
21105
|
+
_QrSegment.NUMERIC_REGEX = /^[0-9]*$/;
|
|
21106
|
+
_QrSegment.ALPHANUMERIC_REGEX = /^[A-Z0-9 $%*+.\/:-]*$/;
|
|
21107
|
+
_QrSegment.ALPHANUMERIC_CHARSET = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:";
|
|
21108
|
+
let QrSegment = _QrSegment;
|
|
21109
|
+
qrcodegen2.QrSegment = _QrSegment;
|
|
21110
|
+
})(qrcodegen || (qrcodegen = {}));
|
|
21111
|
+
((qrcodegen2) => {
|
|
21112
|
+
((QrCode2) => {
|
|
21113
|
+
const _Ecc = class _Ecc {
|
|
21114
|
+
constructor(ordinal, formatBits) {
|
|
21115
|
+
this.ordinal = ordinal;
|
|
21116
|
+
this.formatBits = formatBits;
|
|
21117
|
+
}
|
|
21118
|
+
};
|
|
21119
|
+
_Ecc.LOW = new _Ecc(0, 1);
|
|
21120
|
+
_Ecc.MEDIUM = new _Ecc(1, 0);
|
|
21121
|
+
_Ecc.QUARTILE = new _Ecc(2, 3);
|
|
21122
|
+
_Ecc.HIGH = new _Ecc(3, 2);
|
|
21123
|
+
QrCode2.Ecc = _Ecc;
|
|
21124
|
+
})(qrcodegen2.QrCode || (qrcodegen2.QrCode = {}));
|
|
21125
|
+
})(qrcodegen || (qrcodegen = {}));
|
|
21126
|
+
((qrcodegen2) => {
|
|
21127
|
+
((QrSegment2) => {
|
|
21128
|
+
const _Mode = class _Mode {
|
|
21129
|
+
constructor(modeBits, numBitsCharCount) {
|
|
21130
|
+
this.modeBits = modeBits;
|
|
21131
|
+
this.numBitsCharCount = numBitsCharCount;
|
|
21132
|
+
}
|
|
21133
|
+
numCharCountBits(ver) {
|
|
21134
|
+
return this.numBitsCharCount[Math.floor((ver + 7) / 17)];
|
|
21135
|
+
}
|
|
21136
|
+
};
|
|
21137
|
+
_Mode.NUMERIC = new _Mode(1, [
|
|
21138
|
+
10,
|
|
21139
|
+
12,
|
|
21140
|
+
14
|
|
21141
|
+
]);
|
|
21142
|
+
_Mode.ALPHANUMERIC = new _Mode(2, [
|
|
21143
|
+
9,
|
|
21144
|
+
11,
|
|
21145
|
+
13
|
|
21146
|
+
]);
|
|
21147
|
+
_Mode.BYTE = new _Mode(4, [
|
|
21148
|
+
8,
|
|
21149
|
+
16,
|
|
21150
|
+
16
|
|
21151
|
+
]);
|
|
21152
|
+
_Mode.KANJI = new _Mode(8, [
|
|
21153
|
+
8,
|
|
21154
|
+
10,
|
|
21155
|
+
12
|
|
21156
|
+
]);
|
|
21157
|
+
_Mode.ECI = new _Mode(7, [
|
|
21158
|
+
0,
|
|
21159
|
+
0,
|
|
21160
|
+
0
|
|
21161
|
+
]);
|
|
21162
|
+
QrSegment2.Mode = _Mode;
|
|
21163
|
+
})(qrcodegen2.QrSegment || (qrcodegen2.QrSegment = {}));
|
|
21164
|
+
})(qrcodegen || (qrcodegen = {}));
|
|
21165
|
+
var qrcodegen_default = qrcodegen;
|
|
21166
|
+
/**
|
|
21167
|
+
* @license qrcode.react
|
|
21168
|
+
* Copyright (c) Paul O'Shannessy
|
|
21169
|
+
* SPDX-License-Identifier: ISC
|
|
21170
|
+
*/
|
|
21171
|
+
var ERROR_LEVEL_MAP = {
|
|
21172
|
+
L: qrcodegen_default.QrCode.Ecc.LOW,
|
|
21173
|
+
M: qrcodegen_default.QrCode.Ecc.MEDIUM,
|
|
21174
|
+
Q: qrcodegen_default.QrCode.Ecc.QUARTILE,
|
|
21175
|
+
H: qrcodegen_default.QrCode.Ecc.HIGH
|
|
21176
|
+
};
|
|
21177
|
+
var DEFAULT_SIZE$1 = 128;
|
|
21178
|
+
var DEFAULT_LEVEL = "L";
|
|
21179
|
+
var DEFAULT_BGCOLOR = "#FFFFFF";
|
|
21180
|
+
var DEFAULT_FGCOLOR = "#000000";
|
|
21181
|
+
var DEFAULT_INCLUDEMARGIN = false;
|
|
21182
|
+
var DEFAULT_MINVERSION = 1;
|
|
21183
|
+
var SPEC_MARGIN_SIZE = 4;
|
|
21184
|
+
var DEFAULT_MARGIN_SIZE = 0;
|
|
21185
|
+
var DEFAULT_IMG_SCALE = .1;
|
|
21186
|
+
function generatePath(modules, margin = 0) {
|
|
21187
|
+
const ops = [];
|
|
21188
|
+
modules.forEach(function(row, y) {
|
|
21189
|
+
let start = null;
|
|
21190
|
+
row.forEach(function(cell, x) {
|
|
21191
|
+
if (!cell && start !== null) {
|
|
21192
|
+
ops.push(`M${start + margin} ${y + margin}h${x - start}v1H${start + margin}z`);
|
|
21193
|
+
start = null;
|
|
21194
|
+
return;
|
|
21195
|
+
}
|
|
21196
|
+
if (x === row.length - 1) {
|
|
21197
|
+
if (!cell) return;
|
|
21198
|
+
if (start === null) ops.push(`M${x + margin},${y + margin} h1v1H${x + margin}z`);
|
|
21199
|
+
else ops.push(`M${start + margin},${y + margin} h${x + 1 - start}v1H${start + margin}z`);
|
|
21200
|
+
return;
|
|
21201
|
+
}
|
|
21202
|
+
if (cell && start === null) start = x;
|
|
21203
|
+
});
|
|
21204
|
+
});
|
|
21205
|
+
return ops.join("");
|
|
21206
|
+
}
|
|
21207
|
+
function excavateModules(modules, excavation) {
|
|
21208
|
+
return modules.slice().map((row, y) => {
|
|
21209
|
+
if (y < excavation.y || y >= excavation.y + excavation.h) return row;
|
|
21210
|
+
return row.map((cell, x) => {
|
|
21211
|
+
if (x < excavation.x || x >= excavation.x + excavation.w) return cell;
|
|
21212
|
+
return false;
|
|
21213
|
+
});
|
|
21214
|
+
});
|
|
21215
|
+
}
|
|
21216
|
+
function getImageSettings(cells, size, margin, imageSettings) {
|
|
21217
|
+
if (imageSettings == null) return null;
|
|
21218
|
+
const numCells = cells.length + margin * 2;
|
|
21219
|
+
const defaultSize = Math.floor(size * DEFAULT_IMG_SCALE);
|
|
21220
|
+
const scale = numCells / size;
|
|
21221
|
+
const w = (imageSettings.width || defaultSize) * scale;
|
|
21222
|
+
const h = (imageSettings.height || defaultSize) * scale;
|
|
21223
|
+
const x = imageSettings.x == null ? cells.length / 2 - w / 2 : imageSettings.x * scale;
|
|
21224
|
+
const y = imageSettings.y == null ? cells.length / 2 - h / 2 : imageSettings.y * scale;
|
|
21225
|
+
const opacity = imageSettings.opacity == null ? 1 : imageSettings.opacity;
|
|
21226
|
+
let excavation = null;
|
|
21227
|
+
if (imageSettings.excavate) {
|
|
21228
|
+
let floorX = Math.floor(x);
|
|
21229
|
+
let floorY = Math.floor(y);
|
|
21230
|
+
excavation = {
|
|
21231
|
+
x: floorX,
|
|
21232
|
+
y: floorY,
|
|
21233
|
+
w: Math.ceil(w + x - floorX),
|
|
21234
|
+
h: Math.ceil(h + y - floorY)
|
|
21235
|
+
};
|
|
21236
|
+
}
|
|
21237
|
+
const crossOrigin = imageSettings.crossOrigin;
|
|
21238
|
+
return {
|
|
21239
|
+
x,
|
|
21240
|
+
y,
|
|
21241
|
+
h,
|
|
21242
|
+
w,
|
|
21243
|
+
excavation,
|
|
21244
|
+
opacity,
|
|
21245
|
+
crossOrigin
|
|
21246
|
+
};
|
|
21247
|
+
}
|
|
21248
|
+
function getMarginSize(includeMargin, marginSize) {
|
|
21249
|
+
if (marginSize != null) return Math.max(Math.floor(marginSize), 0);
|
|
21250
|
+
return includeMargin ? SPEC_MARGIN_SIZE : DEFAULT_MARGIN_SIZE;
|
|
21251
|
+
}
|
|
21252
|
+
function useQRCode({ value, level, minVersion, includeMargin, marginSize, imageSettings, size, boostLevel }) {
|
|
21253
|
+
let qrcode = react.default.useMemo(() => {
|
|
21254
|
+
const segments = (Array.isArray(value) ? value : [value]).reduce((accum, v) => {
|
|
21255
|
+
accum.push(...qrcodegen_default.QrSegment.makeSegments(v));
|
|
21256
|
+
return accum;
|
|
21257
|
+
}, []);
|
|
21258
|
+
return qrcodegen_default.QrCode.encodeSegments(segments, ERROR_LEVEL_MAP[level], minVersion, void 0, void 0, boostLevel);
|
|
21259
|
+
}, [
|
|
21260
|
+
value,
|
|
21261
|
+
level,
|
|
21262
|
+
minVersion,
|
|
21263
|
+
boostLevel
|
|
21264
|
+
]);
|
|
21265
|
+
const { cells, margin, numCells, calculatedImageSettings } = react.default.useMemo(() => {
|
|
21266
|
+
let cells2 = qrcode.getModules();
|
|
21267
|
+
const margin2 = getMarginSize(includeMargin, marginSize);
|
|
21268
|
+
return {
|
|
21269
|
+
cells: cells2,
|
|
21270
|
+
margin: margin2,
|
|
21271
|
+
numCells: cells2.length + margin2 * 2,
|
|
21272
|
+
calculatedImageSettings: getImageSettings(cells2, size, margin2, imageSettings)
|
|
21273
|
+
};
|
|
21274
|
+
}, [
|
|
21275
|
+
qrcode,
|
|
21276
|
+
size,
|
|
21277
|
+
imageSettings,
|
|
21278
|
+
includeMargin,
|
|
21279
|
+
marginSize
|
|
21280
|
+
]);
|
|
21281
|
+
return {
|
|
21282
|
+
qrcode,
|
|
21283
|
+
margin,
|
|
21284
|
+
cells,
|
|
21285
|
+
numCells,
|
|
21286
|
+
calculatedImageSettings
|
|
21287
|
+
};
|
|
21288
|
+
}
|
|
21289
|
+
var SUPPORTS_PATH2D = function() {
|
|
21290
|
+
try {
|
|
21291
|
+
new Path2D().addPath(new Path2D());
|
|
21292
|
+
} catch (e) {
|
|
21293
|
+
return false;
|
|
21294
|
+
}
|
|
21295
|
+
return true;
|
|
21296
|
+
}();
|
|
21297
|
+
var QRCodeCanvas = react.default.forwardRef(function QRCodeCanvas2(props, forwardedRef) {
|
|
21298
|
+
const _a = props, { value, size = DEFAULT_SIZE$1, level = DEFAULT_LEVEL, bgColor = DEFAULT_BGCOLOR, fgColor = DEFAULT_FGCOLOR, includeMargin = DEFAULT_INCLUDEMARGIN, minVersion = DEFAULT_MINVERSION, boostLevel, marginSize, imageSettings } = _a;
|
|
21299
|
+
const _b = __objRest(_a, [
|
|
21300
|
+
"value",
|
|
21301
|
+
"size",
|
|
21302
|
+
"level",
|
|
21303
|
+
"bgColor",
|
|
21304
|
+
"fgColor",
|
|
21305
|
+
"includeMargin",
|
|
21306
|
+
"minVersion",
|
|
21307
|
+
"boostLevel",
|
|
21308
|
+
"marginSize",
|
|
21309
|
+
"imageSettings"
|
|
21310
|
+
]), { style } = _b, otherProps = __objRest(_b, ["style"]);
|
|
21311
|
+
const imgSrc = imageSettings == null ? void 0 : imageSettings.src;
|
|
21312
|
+
const _canvas = react.default.useRef(null);
|
|
21313
|
+
const _image = react.default.useRef(null);
|
|
21314
|
+
const setCanvasRef = react.default.useCallback((node) => {
|
|
21315
|
+
_canvas.current = node;
|
|
21316
|
+
if (typeof forwardedRef === "function") forwardedRef(node);
|
|
21317
|
+
else if (forwardedRef) forwardedRef.current = node;
|
|
21318
|
+
}, [forwardedRef]);
|
|
21319
|
+
const [isImgLoaded, setIsImageLoaded] = react.default.useState(false);
|
|
21320
|
+
const { margin, cells, numCells, calculatedImageSettings } = useQRCode({
|
|
21321
|
+
value,
|
|
21322
|
+
level,
|
|
21323
|
+
minVersion,
|
|
21324
|
+
boostLevel,
|
|
21325
|
+
includeMargin,
|
|
21326
|
+
marginSize,
|
|
21327
|
+
imageSettings,
|
|
21328
|
+
size
|
|
21329
|
+
});
|
|
21330
|
+
react.default.useEffect(() => {
|
|
21331
|
+
if (_canvas.current != null) {
|
|
21332
|
+
const canvas = _canvas.current;
|
|
21333
|
+
const ctx = canvas.getContext("2d");
|
|
21334
|
+
if (!ctx) return;
|
|
21335
|
+
let cellsToDraw = cells;
|
|
21336
|
+
const image = _image.current;
|
|
21337
|
+
const haveImageToRender = calculatedImageSettings != null && image !== null && image.complete && image.naturalHeight !== 0 && image.naturalWidth !== 0;
|
|
21338
|
+
if (haveImageToRender) {
|
|
21339
|
+
if (calculatedImageSettings.excavation != null) cellsToDraw = excavateModules(cells, calculatedImageSettings.excavation);
|
|
21340
|
+
}
|
|
21341
|
+
const pixelRatio = window.devicePixelRatio || 1;
|
|
21342
|
+
canvas.height = canvas.width = size * pixelRatio;
|
|
21343
|
+
const scale = size / numCells * pixelRatio;
|
|
21344
|
+
ctx.scale(scale, scale);
|
|
21345
|
+
ctx.fillStyle = bgColor;
|
|
21346
|
+
ctx.fillRect(0, 0, numCells, numCells);
|
|
21347
|
+
ctx.fillStyle = fgColor;
|
|
21348
|
+
if (SUPPORTS_PATH2D) ctx.fill(new Path2D(generatePath(cellsToDraw, margin)));
|
|
21349
|
+
else cells.forEach(function(row, rdx) {
|
|
21350
|
+
row.forEach(function(cell, cdx) {
|
|
21351
|
+
if (cell) ctx.fillRect(cdx + margin, rdx + margin, 1, 1);
|
|
21352
|
+
});
|
|
21353
|
+
});
|
|
21354
|
+
if (calculatedImageSettings) ctx.globalAlpha = calculatedImageSettings.opacity;
|
|
21355
|
+
if (haveImageToRender) ctx.drawImage(image, calculatedImageSettings.x + margin, calculatedImageSettings.y + margin, calculatedImageSettings.w, calculatedImageSettings.h);
|
|
21356
|
+
}
|
|
21357
|
+
});
|
|
21358
|
+
react.default.useEffect(() => {
|
|
21359
|
+
setIsImageLoaded(false);
|
|
21360
|
+
}, [imgSrc]);
|
|
21361
|
+
const canvasStyle = __spreadValues({
|
|
21362
|
+
height: size,
|
|
21363
|
+
width: size
|
|
21364
|
+
}, style);
|
|
21365
|
+
let img = null;
|
|
21366
|
+
if (imgSrc != null) img = /* @__PURE__ */ react.default.createElement("img", {
|
|
21367
|
+
src: imgSrc,
|
|
21368
|
+
key: imgSrc,
|
|
21369
|
+
style: { display: "none" },
|
|
21370
|
+
onLoad: () => {
|
|
21371
|
+
setIsImageLoaded(true);
|
|
21372
|
+
},
|
|
21373
|
+
ref: _image,
|
|
21374
|
+
crossOrigin: calculatedImageSettings == null ? void 0 : calculatedImageSettings.crossOrigin
|
|
21375
|
+
});
|
|
21376
|
+
return /* @__PURE__ */ react.default.createElement(react.default.Fragment, null, /* @__PURE__ */ react.default.createElement("canvas", __spreadValues({
|
|
21377
|
+
style: canvasStyle,
|
|
21378
|
+
height: size,
|
|
21379
|
+
width: size,
|
|
21380
|
+
ref: setCanvasRef,
|
|
21381
|
+
role: "img"
|
|
21382
|
+
}, otherProps)), img);
|
|
21383
|
+
});
|
|
21384
|
+
QRCodeCanvas.displayName = "QRCodeCanvas";
|
|
21385
|
+
var QRCodeSVG = react.default.forwardRef(function QRCodeSVG2(props, forwardedRef) {
|
|
21386
|
+
const _a = props, { value, size = DEFAULT_SIZE$1, level = DEFAULT_LEVEL, bgColor = DEFAULT_BGCOLOR, fgColor = DEFAULT_FGCOLOR, includeMargin = DEFAULT_INCLUDEMARGIN, minVersion = DEFAULT_MINVERSION, boostLevel, title, marginSize, imageSettings } = _a, otherProps = __objRest(_a, [
|
|
21387
|
+
"value",
|
|
21388
|
+
"size",
|
|
21389
|
+
"level",
|
|
21390
|
+
"bgColor",
|
|
21391
|
+
"fgColor",
|
|
21392
|
+
"includeMargin",
|
|
21393
|
+
"minVersion",
|
|
21394
|
+
"boostLevel",
|
|
21395
|
+
"title",
|
|
21396
|
+
"marginSize",
|
|
21397
|
+
"imageSettings"
|
|
21398
|
+
]);
|
|
21399
|
+
const { margin, cells, numCells, calculatedImageSettings } = useQRCode({
|
|
21400
|
+
value,
|
|
21401
|
+
level,
|
|
21402
|
+
minVersion,
|
|
21403
|
+
boostLevel,
|
|
21404
|
+
includeMargin,
|
|
21405
|
+
marginSize,
|
|
21406
|
+
imageSettings,
|
|
21407
|
+
size
|
|
21408
|
+
});
|
|
21409
|
+
let cellsToDraw = cells;
|
|
21410
|
+
let image = null;
|
|
21411
|
+
if (imageSettings != null && calculatedImageSettings != null) {
|
|
21412
|
+
if (calculatedImageSettings.excavation != null) cellsToDraw = excavateModules(cells, calculatedImageSettings.excavation);
|
|
21413
|
+
image = /* @__PURE__ */ react.default.createElement("image", {
|
|
21414
|
+
href: imageSettings.src,
|
|
21415
|
+
height: calculatedImageSettings.h,
|
|
21416
|
+
width: calculatedImageSettings.w,
|
|
21417
|
+
x: calculatedImageSettings.x + margin,
|
|
21418
|
+
y: calculatedImageSettings.y + margin,
|
|
21419
|
+
preserveAspectRatio: "none",
|
|
21420
|
+
opacity: calculatedImageSettings.opacity,
|
|
21421
|
+
crossOrigin: calculatedImageSettings.crossOrigin
|
|
21422
|
+
});
|
|
21423
|
+
}
|
|
21424
|
+
const fgPath = generatePath(cellsToDraw, margin);
|
|
21425
|
+
return /* @__PURE__ */ react.default.createElement("svg", __spreadValues({
|
|
21426
|
+
height: size,
|
|
21427
|
+
width: size,
|
|
21428
|
+
viewBox: `0 0 ${numCells} ${numCells}`,
|
|
21429
|
+
ref: forwardedRef,
|
|
21430
|
+
role: "img"
|
|
21431
|
+
}, otherProps), !!title && /* @__PURE__ */ react.default.createElement("title", null, title), /* @__PURE__ */ react.default.createElement("path", {
|
|
21432
|
+
fill: bgColor,
|
|
21433
|
+
d: `M0,0 h${numCells}v${numCells}H0z`,
|
|
21434
|
+
shapeRendering: "crispEdges"
|
|
21435
|
+
}), /* @__PURE__ */ react.default.createElement("path", {
|
|
21436
|
+
fill: fgColor,
|
|
21437
|
+
d: fgPath,
|
|
21438
|
+
shapeRendering: "crispEdges"
|
|
21439
|
+
}), image);
|
|
21440
|
+
});
|
|
21441
|
+
QRCodeSVG.displayName = "QRCodeSVG";
|
|
21442
|
+
//#endregion
|
|
21443
|
+
//#region src/composites/qr-code.tsx
|
|
21444
|
+
var DEFAULT_SIZE = 192;
|
|
21445
|
+
function QrCode({ value, size = DEFAULT_SIZE, className, alt }) {
|
|
21446
|
+
const trimmed = value.trim();
|
|
21447
|
+
if (trimmed.length === 0) return null;
|
|
21448
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
21449
|
+
className: cn("inline-flex rounded-md bg-white p-2", className),
|
|
21450
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(QRCodeSVG, {
|
|
21451
|
+
value: trimmed,
|
|
21452
|
+
size,
|
|
21453
|
+
marginSize: 1,
|
|
21454
|
+
title: alt ?? "QR code"
|
|
21455
|
+
})
|
|
21456
|
+
});
|
|
21457
|
+
}
|
|
21458
|
+
//#endregion
|
|
21459
|
+
//#region src/composites/copy-button.tsx
|
|
21460
|
+
/**
|
|
21461
|
+
* `CopyButton` — a compact button that copies a string `value` to the
|
|
21462
|
+
* clipboard via `navigator.clipboard.writeText`, showing a brief
|
|
21463
|
+
* "copied" check state. Addon-agnostic; used wherever a secret / URL
|
|
21464
|
+
* needs a one-click copy affordance (export setup panels, etc.).
|
|
21465
|
+
*/
|
|
21466
|
+
var COPIED_RESET_MS = 2e3;
|
|
21467
|
+
function CopyButton({ value, label, className, disabled }) {
|
|
21468
|
+
const [copied, setCopied] = (0, react$1.useState)(false);
|
|
21469
|
+
const handleCopy = (0, react$1.useCallback)(() => {
|
|
21470
|
+
if (!value) return;
|
|
21471
|
+
navigator.clipboard.writeText(value).then(() => {
|
|
21472
|
+
setCopied(true);
|
|
21473
|
+
setTimeout(() => setCopied(false), COPIED_RESET_MS);
|
|
21474
|
+
});
|
|
21475
|
+
}, [value]);
|
|
21476
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Button, {
|
|
21477
|
+
size: "sm",
|
|
21478
|
+
variant: "ghost",
|
|
21479
|
+
type: "button",
|
|
21480
|
+
disabled: disabled || value.length === 0,
|
|
21481
|
+
onClick: handleCopy,
|
|
21482
|
+
className: cn(className),
|
|
21483
|
+
"aria-label": copied ? "Copied" : `Copy ${label ?? "value"}`,
|
|
21484
|
+
children: [copied ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Check, { className: "h-3.5 w-3.5 text-success" }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Copy, { className: "h-3.5 w-3.5" }), label ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
21485
|
+
className: "ml-1",
|
|
21486
|
+
children: copied ? "Copied" : label
|
|
21487
|
+
}) : null]
|
|
21488
|
+
});
|
|
21489
|
+
}
|
|
21490
|
+
//#endregion
|
|
21491
|
+
//#region src/composites/device-export-panel.tsx
|
|
21492
|
+
/**
|
|
21493
|
+
* DeviceExportPanel — generic, addon-agnostic surface for the
|
|
21494
|
+
* `device-export` capability.
|
|
21495
|
+
*
|
|
21496
|
+
* Renders the COMMON device-export surface for a single export addon
|
|
21497
|
+
* (HomeAssistant via MQTT, HomeKit/HAP, Alexa Smart Home, …):
|
|
21498
|
+
*
|
|
21499
|
+
* - a link-state status badge + exposed-device count from `getStatus`,
|
|
21500
|
+
* - the exposed-devices table from `listExposedDevices` (device name,
|
|
21501
|
+
* status, stream preference) with a per-row unexpose action
|
|
21502
|
+
* (`unexposeDevice`),
|
|
21503
|
+
* - an empty state directing the operator to the device-details page.
|
|
21504
|
+
*
|
|
21505
|
+
* This composite is the reusable replacement for the per-addon
|
|
21506
|
+
* Module-Federation overview tables that each export addon used to
|
|
21507
|
+
* ship. It is driven entirely by the `device-export` cap — there are no
|
|
21508
|
+
* Alexa / HAP / MQTT specifics here. Mount it next to an export addon's
|
|
21509
|
+
* standard settings form (e.g. in the addon-settings modal).
|
|
21510
|
+
*
|
|
21511
|
+
* Routing note: `device-export` is a collection cap; the codegen'd
|
|
21512
|
+
* router resolves `{ nodeId }` to the first registered provider. Export
|
|
21513
|
+
* addons are all `hub-only`, so the panel queries `nodeId: 'hub'`. When
|
|
21514
|
+
* multiple device-export addons are co-installed the cap-router today
|
|
21515
|
+
* resolves to the first provider only (per-provider routing is a
|
|
21516
|
+
* separate follow-up) — identical behaviour to the pages it replaces.
|
|
21517
|
+
*/
|
|
21518
|
+
var ExposedDeviceArraySchema = zod.z.array(_camstack_types.ExposedDeviceSchema);
|
|
21519
|
+
var STATUS_POLL_INTERVAL_MS = 1e4;
|
|
21520
|
+
function statusVariant(state) {
|
|
21521
|
+
if (state === "linked") return "success";
|
|
21522
|
+
if (state === "error") return "danger";
|
|
21523
|
+
return "warning";
|
|
21524
|
+
}
|
|
21525
|
+
function capitaliseLinkState(state) {
|
|
21526
|
+
if (state === "linked") return "Linked";
|
|
21527
|
+
if (state === "unlinked") return "Unlinked";
|
|
21528
|
+
if (state === "error") return "Error";
|
|
21529
|
+
return state;
|
|
21530
|
+
}
|
|
21531
|
+
/**
|
|
21532
|
+
* A single label/value row in the Setup section. `secret` rows mask the
|
|
21533
|
+
* value behind a reveal toggle; every row gets a copy button.
|
|
21534
|
+
*/
|
|
21535
|
+
function SetupFieldRow({ field }) {
|
|
21536
|
+
const [revealed, setRevealed] = (0, react$1.useState)(false);
|
|
21537
|
+
const isSecret = field.secret === true;
|
|
21538
|
+
const displayValue = isSecret && !revealed ? "•".repeat(Math.min(field.value.length, 24)) : field.value;
|
|
21539
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
21540
|
+
className: "flex items-center gap-2 py-1.5",
|
|
21541
|
+
children: [
|
|
21542
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
21543
|
+
className: "text-[11px] text-foreground-subtle w-32 shrink-0",
|
|
21544
|
+
children: field.label
|
|
21545
|
+
}),
|
|
21546
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
21547
|
+
className: "flex-1 min-w-0 truncate font-mono text-xs text-foreground",
|
|
21548
|
+
children: displayValue || "—"
|
|
21549
|
+
}),
|
|
21550
|
+
isSecret && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
|
|
21551
|
+
size: "sm",
|
|
21552
|
+
variant: "ghost",
|
|
21553
|
+
type: "button",
|
|
21554
|
+
"aria-label": revealed ? "Hide value" : "Reveal value",
|
|
21555
|
+
onClick: () => setRevealed((v) => !v),
|
|
21556
|
+
children: revealed ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(EyeOff, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Eye, { className: "h-3.5 w-3.5" })
|
|
21557
|
+
}),
|
|
21558
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(CopyButton, {
|
|
21559
|
+
value: field.value,
|
|
21560
|
+
label: field.label
|
|
21561
|
+
})
|
|
21562
|
+
]
|
|
21563
|
+
});
|
|
21564
|
+
}
|
|
21565
|
+
/**
|
|
21566
|
+
* Generic "Setup" section — pairing QR + copyable label/value rows +
|
|
21567
|
+
* operator note. Driven entirely by the cap's `setup` block; renders
|
|
21568
|
+
* nothing addon-specific.
|
|
21569
|
+
*/
|
|
21570
|
+
function SetupSection({ setup }) {
|
|
21571
|
+
const fields = setup.fields ?? [];
|
|
21572
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
21573
|
+
className: "border-b border-border bg-surface-hover/10",
|
|
21574
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
21575
|
+
className: "flex items-center gap-2 px-4 py-2 border-b border-border",
|
|
21576
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(QrCode$1, { className: "h-3.5 w-3.5 text-foreground-subtle shrink-0" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
21577
|
+
className: "text-[11px] font-semibold text-foreground-subtle uppercase tracking-wide",
|
|
21578
|
+
children: "Setup"
|
|
21579
|
+
})]
|
|
21580
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
21581
|
+
className: "flex flex-col gap-3 p-4 sm:flex-row sm:items-start",
|
|
21582
|
+
children: [setup.qr && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
21583
|
+
className: "shrink-0",
|
|
21584
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(QrCode, {
|
|
21585
|
+
value: setup.qr,
|
|
21586
|
+
alt: "Pairing QR code"
|
|
21587
|
+
})
|
|
21588
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
21589
|
+
className: "flex-1 min-w-0",
|
|
21590
|
+
children: [setup.note && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
21591
|
+
className: "text-xs text-foreground-muted whitespace-pre-line mb-2",
|
|
21592
|
+
children: setup.note
|
|
21593
|
+
}), fields.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
21594
|
+
className: "divide-y divide-border-subtle",
|
|
21595
|
+
children: fields.map((field) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SetupFieldRow, { field }, field.label))
|
|
21596
|
+
})]
|
|
21597
|
+
})]
|
|
21598
|
+
})]
|
|
21599
|
+
});
|
|
21600
|
+
}
|
|
21601
|
+
/**
|
|
21602
|
+
* Generic device-export panel. Addon-agnostic — only the `device-export`
|
|
21603
|
+
* cap drives it.
|
|
21604
|
+
*/
|
|
21605
|
+
function DeviceExportPanel({ addonId, onOpenDevice }) {
|
|
21606
|
+
const queryClient = (0, _tanstack_react_query.useQueryClient)();
|
|
21607
|
+
const statusQuery = useDeviceExportGetStatus({ nodeId: "hub" }, {
|
|
21608
|
+
refetchInterval: STATUS_POLL_INTERVAL_MS,
|
|
21609
|
+
retry: false
|
|
21610
|
+
});
|
|
21611
|
+
const exposedQuery = useDeviceExportListExposedDevices({ nodeId: "hub" }, {
|
|
21612
|
+
refetchInterval: STATUS_POLL_INTERVAL_MS,
|
|
21613
|
+
retry: false
|
|
21614
|
+
});
|
|
21615
|
+
const unexposeMutation = useDeviceExportUnexposeDevice({ onSuccess: () => {
|
|
21616
|
+
queryClient.invalidateQueries({ queryKey: [["deviceExport"]] });
|
|
21617
|
+
} });
|
|
21618
|
+
const status = (0, react$1.useMemo)(() => {
|
|
21619
|
+
const parsed = _camstack_types.DeviceExportStatusSchema.safeParse(statusQuery.data);
|
|
21620
|
+
return parsed.success ? parsed.data : null;
|
|
21621
|
+
}, [statusQuery.data]);
|
|
21622
|
+
const exposed = (0, react$1.useMemo)(() => {
|
|
21623
|
+
const parsed = ExposedDeviceArraySchema.safeParse(exposedQuery.data);
|
|
21624
|
+
return parsed.success ? parsed.data : [];
|
|
21625
|
+
}, [exposedQuery.data]);
|
|
21626
|
+
const linkState = status?.linkState ?? "unlinked";
|
|
21627
|
+
const rows = (0, react$1.useMemo)(() => exposed.map((entry) => ({
|
|
21628
|
+
deviceId: entry.deviceId,
|
|
21629
|
+
displayName: entry.exposedAs ?? `Device ${entry.deviceId}`,
|
|
21630
|
+
streamPreference: "auto",
|
|
21631
|
+
linkState
|
|
21632
|
+
})), [exposed, linkState]);
|
|
21633
|
+
const loading = statusQuery.isLoading || exposedQuery.isLoading;
|
|
21634
|
+
const exposedCount = status?.exposedDeviceCount ?? rows.length;
|
|
21635
|
+
const columns = (0, react$1.useMemo)(() => [
|
|
21636
|
+
{
|
|
21637
|
+
key: "device",
|
|
21638
|
+
header: "Device",
|
|
21639
|
+
render: (row) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
21640
|
+
className: "flex flex-col",
|
|
21641
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
21642
|
+
className: "text-foreground font-medium",
|
|
21643
|
+
children: row.displayName
|
|
21644
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
21645
|
+
className: "text-foreground-subtle text-xs font-mono",
|
|
21646
|
+
children: ["#", row.deviceId]
|
|
21647
|
+
})]
|
|
21648
|
+
})
|
|
21649
|
+
},
|
|
21650
|
+
{
|
|
21651
|
+
key: "status",
|
|
21652
|
+
header: "Status",
|
|
21653
|
+
render: (row) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Badge, {
|
|
21654
|
+
variant: statusVariant(row.linkState),
|
|
21655
|
+
children: capitaliseLinkState(row.linkState)
|
|
21656
|
+
})
|
|
21657
|
+
},
|
|
21658
|
+
{
|
|
21659
|
+
key: "stream",
|
|
21660
|
+
header: "Stream",
|
|
21661
|
+
render: (row) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
21662
|
+
className: "text-xs text-foreground-subtle font-mono",
|
|
21663
|
+
children: row.streamPreference === "auto" ? "Auto" : row.streamPreference
|
|
21664
|
+
})
|
|
21665
|
+
},
|
|
21666
|
+
{
|
|
21667
|
+
key: "actions",
|
|
21668
|
+
header: "",
|
|
21669
|
+
align: "right",
|
|
21670
|
+
render: (row) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
21671
|
+
className: "flex items-center justify-end gap-2",
|
|
21672
|
+
children: [onOpenDevice && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Button, {
|
|
21673
|
+
size: "sm",
|
|
21674
|
+
variant: "ghost",
|
|
21675
|
+
onClick: () => onOpenDevice(row.deviceId),
|
|
21676
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ExternalLink, { className: "h-3.5 w-3.5 mr-1" }), "Open"]
|
|
21677
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Button, {
|
|
21678
|
+
size: "sm",
|
|
21679
|
+
variant: "ghost",
|
|
21680
|
+
disabled: unexposeMutation.isPending,
|
|
21681
|
+
onClick: () => unexposeMutation.mutate({
|
|
21682
|
+
deviceId: row.deviceId,
|
|
21683
|
+
nodeId: "hub"
|
|
21684
|
+
}),
|
|
21685
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Unlink2, { className: "h-3.5 w-3.5 mr-1" }), "Unexpose"]
|
|
21686
|
+
})]
|
|
21687
|
+
})
|
|
21688
|
+
}
|
|
21689
|
+
], [onOpenDevice, unexposeMutation]);
|
|
21690
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
21691
|
+
className: "rounded-lg border border-border bg-surface overflow-hidden",
|
|
21692
|
+
children: [
|
|
21693
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
21694
|
+
className: "flex items-center justify-between gap-3 px-4 py-2.5 border-b border-border bg-surface-hover/20",
|
|
21695
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
21696
|
+
className: "flex items-center gap-2 min-w-0",
|
|
21697
|
+
children: [
|
|
21698
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Share2, { className: "h-3.5 w-3.5 text-foreground-subtle shrink-0" }),
|
|
21699
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
21700
|
+
className: "text-[11px] font-semibold text-foreground-subtle uppercase tracking-wide",
|
|
21701
|
+
children: "Exported devices"
|
|
21702
|
+
}),
|
|
21703
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Badge, {
|
|
21704
|
+
variant: statusVariant(linkState),
|
|
21705
|
+
children: capitaliseLinkState(linkState)
|
|
21706
|
+
}),
|
|
21707
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
21708
|
+
className: "text-[11px] text-foreground-subtle",
|
|
21709
|
+
children: [exposedCount, " exposed"]
|
|
21710
|
+
})
|
|
21711
|
+
]
|
|
21712
|
+
}), loading && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LoaderCircle, { className: "h-3.5 w-3.5 animate-spin text-foreground-subtle" })]
|
|
21713
|
+
}),
|
|
21714
|
+
status?.error && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
21715
|
+
className: "px-4 py-3 border-b border-border",
|
|
21716
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ErrorBox, { message: status.error })
|
|
21717
|
+
}),
|
|
21718
|
+
status?.setup && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SetupSection, { setup: status.setup }),
|
|
21719
|
+
rows.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(EmptyState, {
|
|
21720
|
+
icon: Share2,
|
|
21721
|
+
title: "No devices exposed",
|
|
21722
|
+
description: `Expose a camera to "${addonId}" from its device-details page to surface it in the connected ecosystem.`
|
|
21723
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
21724
|
+
className: "p-3",
|
|
21725
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DataTable, {
|
|
21726
|
+
columns,
|
|
21727
|
+
rows,
|
|
21728
|
+
rowKey: (row) => row.deviceId
|
|
21729
|
+
})
|
|
21730
|
+
})
|
|
21731
|
+
]
|
|
21732
|
+
});
|
|
21733
|
+
}
|
|
21734
|
+
//#endregion
|
|
20103
21735
|
//#region src/composites/audio-waveform.tsx
|
|
20104
21736
|
/**
|
|
20105
21737
|
* Canvas-based audio waveform visualization.
|
|
@@ -20107,9 +21739,9 @@ function StreamBrokerSelector({ deviceId, value, onChange, disabled, label, clas
|
|
|
20107
21739
|
* Downsamples to pixel resolution for performance.
|
|
20108
21740
|
*/
|
|
20109
21741
|
function AudioWaveform({ samples, sampleRate = 16e3, height = 96, className = "", color = "#3b82f6", bgColor = "transparent" }) {
|
|
20110
|
-
const canvasRef = (0, react.useRef)(null);
|
|
20111
|
-
const containerRef = (0, react.useRef)(null);
|
|
20112
|
-
const draw = (0, react.useCallback)(() => {
|
|
21742
|
+
const canvasRef = (0, react$1.useRef)(null);
|
|
21743
|
+
const containerRef = (0, react$1.useRef)(null);
|
|
21744
|
+
const draw = (0, react$1.useCallback)(() => {
|
|
20113
21745
|
const canvas = canvasRef.current;
|
|
20114
21746
|
const container = containerRef.current;
|
|
20115
21747
|
if (!canvas || !container || !samples || samples.length === 0) return;
|
|
@@ -20161,10 +21793,10 @@ function AudioWaveform({ samples, sampleRate = 16e3, height = 96, className = ""
|
|
|
20161
21793
|
color,
|
|
20162
21794
|
bgColor
|
|
20163
21795
|
]);
|
|
20164
|
-
(0, react.useEffect)(() => {
|
|
21796
|
+
(0, react$1.useEffect)(() => {
|
|
20165
21797
|
draw();
|
|
20166
21798
|
}, [draw]);
|
|
20167
|
-
(0, react.useEffect)(() => {
|
|
21799
|
+
(0, react$1.useEffect)(() => {
|
|
20168
21800
|
const observer = new ResizeObserver(() => draw());
|
|
20169
21801
|
const el = containerRef.current;
|
|
20170
21802
|
if (el) observer.observe(el);
|
|
@@ -20203,10 +21835,10 @@ function AudioWaveform({ samples, sampleRate = 16e3, height = 96, className = ""
|
|
|
20203
21835
|
* (each chunk, ~0.5s, produces one sample via `frame.level.dbfs`).
|
|
20204
21836
|
*/
|
|
20205
21837
|
function AudioLevelWaveform({ currentDbfs, durationSec = 30, maxSamples = 120, height = 64, className = "", color = "#10b981", clipColor = "#ef4444", clipThreshold = -6, minDbfs = -96 }) {
|
|
20206
|
-
const canvasRef = (0, react.useRef)(null);
|
|
20207
|
-
const containerRef = (0, react.useRef)(null);
|
|
20208
|
-
const [samples, setSamples] = (0, react.useState)([]);
|
|
20209
|
-
(0, react.useEffect)(() => {
|
|
21838
|
+
const canvasRef = (0, react$1.useRef)(null);
|
|
21839
|
+
const containerRef = (0, react$1.useRef)(null);
|
|
21840
|
+
const [samples, setSamples] = (0, react$1.useState)([]);
|
|
21841
|
+
(0, react$1.useEffect)(() => {
|
|
20210
21842
|
if (currentDbfs === null) return;
|
|
20211
21843
|
setSamples((prev) => {
|
|
20212
21844
|
const next = [...prev, {
|
|
@@ -20216,7 +21848,7 @@ function AudioLevelWaveform({ currentDbfs, durationSec = 30, maxSamples = 120, h
|
|
|
20216
21848
|
return next.length > maxSamples ? next.slice(-maxSamples) : next;
|
|
20217
21849
|
});
|
|
20218
21850
|
}, [currentDbfs, maxSamples]);
|
|
20219
|
-
const draw = (0, react.useCallback)(() => {
|
|
21851
|
+
const draw = (0, react$1.useCallback)(() => {
|
|
20220
21852
|
const canvas = canvasRef.current;
|
|
20221
21853
|
const container = containerRef.current;
|
|
20222
21854
|
if (!canvas || !container) return;
|
|
@@ -20269,10 +21901,10 @@ function AudioLevelWaveform({ currentDbfs, durationSec = 30, maxSamples = 120, h
|
|
|
20269
21901
|
clipThreshold,
|
|
20270
21902
|
minDbfs
|
|
20271
21903
|
]);
|
|
20272
|
-
(0, react.useEffect)(() => {
|
|
21904
|
+
(0, react$1.useEffect)(() => {
|
|
20273
21905
|
draw();
|
|
20274
21906
|
}, [draw]);
|
|
20275
|
-
(0, react.useEffect)(() => {
|
|
21907
|
+
(0, react$1.useEffect)(() => {
|
|
20276
21908
|
const observer = new ResizeObserver(() => draw());
|
|
20277
21909
|
const el = containerRef.current;
|
|
20278
21910
|
if (el) observer.observe(el);
|
|
@@ -20394,7 +22026,7 @@ function AudioClassificationList({ classifications, processing = false, inferenc
|
|
|
20394
22026
|
* Expandable log box showing the raw JSON response from a pipeline run.
|
|
20395
22027
|
*/
|
|
20396
22028
|
function ResponseLog({ data, label = "Response", className = "" }) {
|
|
20397
|
-
const [expanded, setExpanded] = (0, react.useState)(false);
|
|
22029
|
+
const [expanded, setExpanded] = (0, react$1.useState)(false);
|
|
20398
22030
|
if (!data) return null;
|
|
20399
22031
|
const json = JSON.stringify(data, null, 2);
|
|
20400
22032
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
@@ -20466,17 +22098,17 @@ function PhaseIcon({ phase, ...props }) {
|
|
|
20466
22098
|
* keeping idle subscriptions alive.
|
|
20467
22099
|
*/
|
|
20468
22100
|
function useLiveBuffer(max) {
|
|
20469
|
-
const [entries, setEntries] = (0, react.useState)([]);
|
|
20470
|
-
const append = (0, react.useCallback)((entry) => {
|
|
22101
|
+
const [entries, setEntries] = (0, react$1.useState)([]);
|
|
22102
|
+
const append = (0, react$1.useCallback)((entry) => {
|
|
20471
22103
|
setEntries((prev) => {
|
|
20472
22104
|
const next = [...prev, entry];
|
|
20473
22105
|
return next.length > max ? next.slice(-max) : next;
|
|
20474
22106
|
});
|
|
20475
22107
|
}, [max]);
|
|
20476
|
-
const reset = (0, react.useCallback)(() => {
|
|
22108
|
+
const reset = (0, react$1.useCallback)(() => {
|
|
20477
22109
|
setEntries([]);
|
|
20478
22110
|
}, []);
|
|
20479
|
-
return (0, react.useMemo)(() => ({
|
|
22111
|
+
return (0, react$1.useMemo)(() => ({
|
|
20480
22112
|
entries,
|
|
20481
22113
|
append,
|
|
20482
22114
|
reset
|
|
@@ -20550,15 +22182,15 @@ function passesLevel(logLevel, filterLevel) {
|
|
|
20550
22182
|
return (LEVEL_SEVERITY[logLevel] ?? 0) >= (LEVEL_SEVERITY[filterLevel] ?? 0);
|
|
20551
22183
|
}
|
|
20552
22184
|
function LogStream({ agentId: propsAgentId, addonId: propsAddonId, deviceId: propsDeviceId, integrationId: propsIntegrationId, requestId: propsRequestId, level: initialLevel, maxHeight = "max-h-96", showScope = false, showFilters = true, limit = 100, liveBuffer: externalBuffer, onClose, className }) {
|
|
20553
|
-
const [localAddonId, setLocalAddonId] = (0, react.useState)("");
|
|
20554
|
-
const [localDeviceId, setLocalDeviceId] = (0, react.useState)("");
|
|
20555
|
-
const [levelFilter, setLevelFilter] = (0, react.useState)(initialLevel);
|
|
22185
|
+
const [localAddonId, setLocalAddonId] = (0, react$1.useState)("");
|
|
22186
|
+
const [localDeviceId, setLocalDeviceId] = (0, react$1.useState)("");
|
|
22187
|
+
const [levelFilter, setLevelFilter] = (0, react$1.useState)(initialLevel);
|
|
20556
22188
|
const agentId = propsAgentId;
|
|
20557
22189
|
const addonId = propsAddonId ?? (localAddonId || void 0);
|
|
20558
22190
|
const deviceId = propsDeviceId ?? (localDeviceId ? Number(localDeviceId) : void 0);
|
|
20559
22191
|
const integrationId = propsIntegrationId;
|
|
20560
22192
|
const requestId = propsRequestId;
|
|
20561
|
-
const tags = (0, react.useMemo)(() => {
|
|
22193
|
+
const tags = (0, react$1.useMemo)(() => {
|
|
20562
22194
|
const t = {};
|
|
20563
22195
|
if (agentId) t.agentId = agentId;
|
|
20564
22196
|
if (addonId) t.addonId = addonId;
|
|
@@ -20576,15 +22208,15 @@ function LogStream({ agentId: propsAgentId, addonId: propsAddonId, deviceId: pro
|
|
|
20576
22208
|
const fallbackBuffer = useLiveBuffer(MAX_LIVE_ENTRIES$2);
|
|
20577
22209
|
const buffer = externalBuffer ?? fallbackBuffer;
|
|
20578
22210
|
const liveLogs = buffer.entries;
|
|
20579
|
-
const [clearedAt, setClearedAt] = (0, react.useState)(0);
|
|
20580
|
-
const [autoScroll, setAutoScroll] = (0, react.useState)(false);
|
|
20581
|
-
const [copied, setCopied] = (0, react.useState)(false);
|
|
20582
|
-
const [expandedRows, setExpandedRows] = (0, react.useState)(/* @__PURE__ */ new Set());
|
|
20583
|
-
const [searchText, setSearchText] = (0, react.useState)("");
|
|
20584
|
-
const scrollRef = (0, react.useRef)(null);
|
|
22211
|
+
const [clearedAt, setClearedAt] = (0, react$1.useState)(0);
|
|
22212
|
+
const [autoScroll, setAutoScroll] = (0, react$1.useState)(false);
|
|
22213
|
+
const [copied, setCopied] = (0, react$1.useState)(false);
|
|
22214
|
+
const [expandedRows, setExpandedRows] = (0, react$1.useState)(/* @__PURE__ */ new Set());
|
|
22215
|
+
const [searchText, setSearchText] = (0, react$1.useState)("");
|
|
22216
|
+
const scrollRef = (0, react$1.useRef)(null);
|
|
20585
22217
|
const scopeKey = `${agentId ?? ""}:${addonId ?? ""}:${String(deviceId ?? "")}:${integrationId ?? ""}:${requestId ?? ""}`;
|
|
20586
|
-
const prevScopeRef = (0, react.useRef)(scopeKey);
|
|
20587
|
-
(0, react.useEffect)(() => {
|
|
22218
|
+
const prevScopeRef = (0, react$1.useRef)(scopeKey);
|
|
22219
|
+
(0, react$1.useEffect)(() => {
|
|
20588
22220
|
if (prevScopeRef.current !== scopeKey) {
|
|
20589
22221
|
prevScopeRef.current = scopeKey;
|
|
20590
22222
|
buffer.reset();
|
|
@@ -20599,8 +22231,8 @@ function LogStream({ agentId: propsAgentId, addonId: propsAddonId, deviceId: pro
|
|
|
20599
22231
|
trpc.logs.subscribe.useSubscription({ ...tags ? { tags } : {} }, { onData: (entry) => {
|
|
20600
22232
|
buffer.append(entry);
|
|
20601
22233
|
} });
|
|
20602
|
-
const prevLiveCountRef = (0, react.useRef)(liveLogs.length);
|
|
20603
|
-
(0, react.useEffect)(() => {
|
|
22234
|
+
const prevLiveCountRef = (0, react$1.useRef)(liveLogs.length);
|
|
22235
|
+
(0, react$1.useEffect)(() => {
|
|
20604
22236
|
const el = scrollRef.current;
|
|
20605
22237
|
if (!el) {
|
|
20606
22238
|
prevLiveCountRef.current = liveLogs.length;
|
|
@@ -20616,7 +22248,7 @@ function LogStream({ agentId: propsAgentId, addonId: propsAddonId, deviceId: pro
|
|
|
20616
22248
|
el.scrollTop += rowHeight * (liveLogs.length - prevCount);
|
|
20617
22249
|
}
|
|
20618
22250
|
}, [liveLogs.length, autoScroll]);
|
|
20619
|
-
const allLogs = (0, react.useMemo)(() => {
|
|
22251
|
+
const allLogs = (0, react$1.useMemo)(() => {
|
|
20620
22252
|
const initial = (initialLogs ?? []).map((log) => ({
|
|
20621
22253
|
timestamp: log.timestamp,
|
|
20622
22254
|
level: log.level,
|
|
@@ -20661,7 +22293,7 @@ function LogStream({ agentId: propsAgentId, addonId: propsAddonId, deviceId: pro
|
|
|
20661
22293
|
clearedAt,
|
|
20662
22294
|
searchText
|
|
20663
22295
|
]);
|
|
20664
|
-
const handleCopyAll = (0, react.useCallback)(() => {
|
|
22296
|
+
const handleCopyAll = (0, react$1.useCallback)(() => {
|
|
20665
22297
|
const lines = allLogs.map((log) => {
|
|
20666
22298
|
const time = new Date(log.timestamp).toLocaleTimeString();
|
|
20667
22299
|
const tagsStr = log.tags ? " " + Object.entries(log.tags).filter(([, v]) => v).map(([k, v]) => `${k}=${v}`).join(" ") : "";
|
|
@@ -20673,7 +22305,7 @@ function LogStream({ agentId: propsAgentId, addonId: propsAddonId, deviceId: pro
|
|
|
20673
22305
|
});
|
|
20674
22306
|
}, [allLogs]);
|
|
20675
22307
|
const clearMutation = trpc.logs.clear.useMutation();
|
|
20676
|
-
const handleClear = (0, react.useCallback)(() => {
|
|
22308
|
+
const handleClear = (0, react$1.useCallback)(() => {
|
|
20677
22309
|
setClearedAt(Date.now());
|
|
20678
22310
|
buffer.reset();
|
|
20679
22311
|
clearMutation.mutate({ ...tags ? { tags } : {} });
|
|
@@ -20682,7 +22314,7 @@ function LogStream({ agentId: propsAgentId, addonId: propsAddonId, deviceId: pro
|
|
|
20682
22314
|
clearMutation,
|
|
20683
22315
|
tags
|
|
20684
22316
|
]);
|
|
20685
|
-
const toggleRow = (0, react.useCallback)((rowKey) => {
|
|
22317
|
+
const toggleRow = (0, react$1.useCallback)((rowKey) => {
|
|
20686
22318
|
setExpandedRows((prev) => {
|
|
20687
22319
|
const next = new Set(prev);
|
|
20688
22320
|
if (next.has(rowKey)) next.delete(rowKey);
|
|
@@ -20690,8 +22322,8 @@ function LogStream({ agentId: propsAgentId, addonId: propsAddonId, deviceId: pro
|
|
|
20690
22322
|
return next;
|
|
20691
22323
|
});
|
|
20692
22324
|
}, []);
|
|
20693
|
-
const [copiedRowKey, setCopiedRowKey] = (0, react.useState)(null);
|
|
20694
|
-
const copyOne = (0, react.useCallback)((log, key) => {
|
|
22325
|
+
const [copiedRowKey, setCopiedRowKey] = (0, react$1.useState)(null);
|
|
22326
|
+
const copyOne = (0, react$1.useCallback)((log, key) => {
|
|
20695
22327
|
const time = new Date(log.timestamp).toISOString();
|
|
20696
22328
|
const tagsStr = log.tags ? " " + Object.entries(log.tags).filter(([, v]) => v).map(([k, v]) => `${k}=${v}`).join(" ") : "";
|
|
20697
22329
|
const metaStr = log.meta && Object.keys(log.meta).length > 0 ? ` meta=${JSON.stringify(log.meta)}` : "";
|
|
@@ -20701,7 +22333,7 @@ function LogStream({ agentId: propsAgentId, addonId: propsAddonId, deviceId: pro
|
|
|
20701
22333
|
setTimeout(() => setCopiedRowKey((prev) => prev === key ? null : prev), 1200);
|
|
20702
22334
|
});
|
|
20703
22335
|
}, []);
|
|
20704
|
-
const rowKey = (0, react.useCallback)((log) => `${log.timestamp}|${log.level}|${log.scope ?? ""}|${log.message}`, []);
|
|
22336
|
+
const rowKey = (0, react$1.useCallback)((log) => `${log.timestamp}|${log.level}|${log.scope ?? ""}|${log.message}`, []);
|
|
20705
22337
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
20706
22338
|
className: cn("h-full min-h-0 flex flex-col", className),
|
|
20707
22339
|
onClick: (e) => e.stopPropagation(),
|
|
@@ -21266,11 +22898,11 @@ function hasContent(entry) {
|
|
|
21266
22898
|
}
|
|
21267
22899
|
var MAX_LIVE_ENTRIES$1 = 300;
|
|
21268
22900
|
function EventStream({ agentId, addonId, deviceId, defaultCategories, categories: legacyCategories, category: propsCategory, maxHeight = "max-h-96", limit = 50, showCategoryFilter = true, showFilters: _showFilters = false, liveBuffer: externalBuffer, onClose, className }) {
|
|
21269
|
-
const defaultsArray = (0, react.useMemo)(() => defaultCategories ?? legacyCategories ?? DEFAULT_EVENT_CATEGORIES, [defaultCategories, legacyCategories]);
|
|
21270
|
-
const defaultsKey = (0, react.useMemo)(() => [...defaultsArray].sort().join(","), [defaultsArray]);
|
|
21271
|
-
const [activeCategories, setActiveCategories] = (0, react.useState)(() => new Set(defaultsArray));
|
|
21272
|
-
const prevDefaultsKey = (0, react.useRef)(defaultsKey);
|
|
21273
|
-
(0, react.useEffect)(() => {
|
|
22901
|
+
const defaultsArray = (0, react$1.useMemo)(() => defaultCategories ?? legacyCategories ?? DEFAULT_EVENT_CATEGORIES, [defaultCategories, legacyCategories]);
|
|
22902
|
+
const defaultsKey = (0, react$1.useMemo)(() => [...defaultsArray].sort().join(","), [defaultsArray]);
|
|
22903
|
+
const [activeCategories, setActiveCategories] = (0, react$1.useState)(() => new Set(defaultsArray));
|
|
22904
|
+
const prevDefaultsKey = (0, react$1.useRef)(defaultsKey);
|
|
22905
|
+
(0, react$1.useEffect)(() => {
|
|
21274
22906
|
if (prevDefaultsKey.current !== defaultsKey) {
|
|
21275
22907
|
prevDefaultsKey.current = defaultsKey;
|
|
21276
22908
|
setActiveCategories(new Set(defaultsArray));
|
|
@@ -21279,17 +22911,17 @@ function EventStream({ agentId, addonId, deviceId, defaultCategories, categories
|
|
|
21279
22911
|
const fallbackBuffer = useLiveBuffer(MAX_LIVE_ENTRIES$1);
|
|
21280
22912
|
const buffer = externalBuffer ?? fallbackBuffer;
|
|
21281
22913
|
const liveEvents = buffer.entries;
|
|
21282
|
-
const [autoScroll, setAutoScroll] = (0, react.useState)(true);
|
|
21283
|
-
const [expandedRows, setExpandedRows] = (0, react.useState)(/* @__PURE__ */ new Set());
|
|
21284
|
-
const [searchText, setSearchText] = (0, react.useState)("");
|
|
21285
|
-
const [filterOpen, setFilterOpen] = (0, react.useState)(false);
|
|
21286
|
-
const [categorySearch, setCategorySearch] = (0, react.useState)("");
|
|
21287
|
-
const [clearedAt, setClearedAt] = (0, react.useState)(0);
|
|
21288
|
-
const scrollRef = (0, react.useRef)(null);
|
|
21289
|
-
const filterRootRef = (0, react.useRef)(null);
|
|
22914
|
+
const [autoScroll, setAutoScroll] = (0, react$1.useState)(true);
|
|
22915
|
+
const [expandedRows, setExpandedRows] = (0, react$1.useState)(/* @__PURE__ */ new Set());
|
|
22916
|
+
const [searchText, setSearchText] = (0, react$1.useState)("");
|
|
22917
|
+
const [filterOpen, setFilterOpen] = (0, react$1.useState)(false);
|
|
22918
|
+
const [categorySearch, setCategorySearch] = (0, react$1.useState)("");
|
|
22919
|
+
const [clearedAt, setClearedAt] = (0, react$1.useState)(0);
|
|
22920
|
+
const scrollRef = (0, react$1.useRef)(null);
|
|
22921
|
+
const filterRootRef = (0, react$1.useRef)(null);
|
|
21290
22922
|
const scopeKey = `${agentId ?? ""}:${addonId ?? ""}:${String(deviceId ?? "")}:${propsCategory ?? ""}`;
|
|
21291
|
-
const prevScopeRef = (0, react.useRef)(scopeKey);
|
|
21292
|
-
(0, react.useEffect)(() => {
|
|
22923
|
+
const prevScopeRef = (0, react$1.useRef)(scopeKey);
|
|
22924
|
+
(0, react$1.useEffect)(() => {
|
|
21293
22925
|
if (prevScopeRef.current !== scopeKey) {
|
|
21294
22926
|
prevScopeRef.current = scopeKey;
|
|
21295
22927
|
buffer.reset();
|
|
@@ -21297,7 +22929,7 @@ function EventStream({ agentId, addonId, deviceId, defaultCategories, categories
|
|
|
21297
22929
|
setClearedAt(0);
|
|
21298
22930
|
}
|
|
21299
22931
|
}, [scopeKey, buffer]);
|
|
21300
|
-
(0, react.useEffect)(() => {
|
|
22932
|
+
(0, react$1.useEffect)(() => {
|
|
21301
22933
|
if (!filterOpen) return;
|
|
21302
22934
|
const onDocClick = (e) => {
|
|
21303
22935
|
const root = filterRootRef.current;
|
|
@@ -21308,7 +22940,7 @@ function EventStream({ agentId, addonId, deviceId, defaultCategories, categories
|
|
|
21308
22940
|
document.removeEventListener("mousedown", onDocClick);
|
|
21309
22941
|
};
|
|
21310
22942
|
}, [filterOpen]);
|
|
21311
|
-
const scopeInput = (0, react.useMemo)(() => {
|
|
22943
|
+
const scopeInput = (0, react$1.useMemo)(() => {
|
|
21312
22944
|
const s = {};
|
|
21313
22945
|
if (agentId) s.agentId = agentId;
|
|
21314
22946
|
if (addonId) s.addonId = addonId;
|
|
@@ -21321,8 +22953,8 @@ function EventStream({ agentId, addonId, deviceId, defaultCategories, categories
|
|
|
21321
22953
|
deviceId,
|
|
21322
22954
|
propsCategory
|
|
21323
22955
|
]);
|
|
21324
|
-
const activeArray = (0, react.useMemo)(() => [...activeCategories].sort(), [activeCategories]);
|
|
21325
|
-
const getRecentInput = (0, react.useMemo)(() => {
|
|
22956
|
+
const activeArray = (0, react$1.useMemo)(() => [...activeCategories].sort(), [activeCategories]);
|
|
22957
|
+
const getRecentInput = (0, react$1.useMemo)(() => {
|
|
21326
22958
|
const s = {
|
|
21327
22959
|
...scopeInput,
|
|
21328
22960
|
limit
|
|
@@ -21332,12 +22964,12 @@ function EventStream({ agentId, addonId, deviceId, defaultCategories, categories
|
|
|
21332
22964
|
}, [
|
|
21333
22965
|
scopeInput,
|
|
21334
22966
|
limit,
|
|
21335
|
-
(0, react.useMemo)(() => activeArray.join(","), [activeArray]),
|
|
22967
|
+
(0, react$1.useMemo)(() => activeArray.join(","), [activeArray]),
|
|
21336
22968
|
activeArray
|
|
21337
22969
|
]);
|
|
21338
22970
|
const { data: initialEvents, isLoading } = trpc.systemEvents.getRecent.useQuery(getRecentInput, { staleTime: 3e4 });
|
|
21339
|
-
const activeCategoriesRef = (0, react.useRef)(activeCategories);
|
|
21340
|
-
(0, react.useEffect)(() => {
|
|
22971
|
+
const activeCategoriesRef = (0, react$1.useRef)(activeCategories);
|
|
22972
|
+
(0, react$1.useEffect)(() => {
|
|
21341
22973
|
activeCategoriesRef.current = activeCategories;
|
|
21342
22974
|
}, [activeCategories]);
|
|
21343
22975
|
const subInput = scopeInput;
|
|
@@ -21348,8 +22980,8 @@ function EventStream({ agentId, addonId, deviceId, defaultCategories, categories
|
|
|
21348
22980
|
if (!activeCategoriesRef.current.has(entry.category)) return;
|
|
21349
22981
|
buffer.append(entry);
|
|
21350
22982
|
} });
|
|
21351
|
-
const prevLiveCountRef = (0, react.useRef)(liveEvents.length);
|
|
21352
|
-
(0, react.useEffect)(() => {
|
|
22983
|
+
const prevLiveCountRef = (0, react$1.useRef)(liveEvents.length);
|
|
22984
|
+
(0, react$1.useEffect)(() => {
|
|
21353
22985
|
const el = scrollRef.current;
|
|
21354
22986
|
if (!el) {
|
|
21355
22987
|
prevLiveCountRef.current = liveEvents.length;
|
|
@@ -21365,7 +22997,7 @@ function EventStream({ agentId, addonId, deviceId, defaultCategories, categories
|
|
|
21365
22997
|
el.scrollTop += rowHeight * (liveEvents.length - prevCount);
|
|
21366
22998
|
}
|
|
21367
22999
|
}, [liveEvents.length, autoScroll]);
|
|
21368
|
-
const allEvents = (0, react.useMemo)(() => {
|
|
23000
|
+
const allEvents = (0, react$1.useMemo)(() => {
|
|
21369
23001
|
const byId = /* @__PURE__ */ new Map();
|
|
21370
23002
|
for (const e of initialEvents ?? []) byId.set(e.id, e);
|
|
21371
23003
|
for (const e of liveEvents) byId.set(e.id, e);
|
|
@@ -21394,7 +23026,7 @@ function EventStream({ agentId, addonId, deviceId, defaultCategories, categories
|
|
|
21394
23026
|
searchText,
|
|
21395
23027
|
clearedAt
|
|
21396
23028
|
]);
|
|
21397
|
-
const toggleRow = (0, react.useCallback)((id) => {
|
|
23029
|
+
const toggleRow = (0, react$1.useCallback)((id) => {
|
|
21398
23030
|
setExpandedRows((prev) => {
|
|
21399
23031
|
const next = new Set(prev);
|
|
21400
23032
|
if (next.has(id)) next.delete(id);
|
|
@@ -21402,7 +23034,7 @@ function EventStream({ agentId, addonId, deviceId, defaultCategories, categories
|
|
|
21402
23034
|
return next;
|
|
21403
23035
|
});
|
|
21404
23036
|
}, []);
|
|
21405
|
-
const toggleCategory = (0, react.useCallback)((cat) => {
|
|
23037
|
+
const toggleCategory = (0, react$1.useCallback)((cat) => {
|
|
21406
23038
|
setActiveCategories((prev) => {
|
|
21407
23039
|
const next = new Set(prev);
|
|
21408
23040
|
if (next.has(cat)) next.delete(cat);
|
|
@@ -21410,43 +23042,43 @@ function EventStream({ agentId, addonId, deviceId, defaultCategories, categories
|
|
|
21410
23042
|
return next;
|
|
21411
23043
|
});
|
|
21412
23044
|
}, []);
|
|
21413
|
-
const handleReset = (0, react.useCallback)(() => {
|
|
23045
|
+
const handleReset = (0, react$1.useCallback)(() => {
|
|
21414
23046
|
setActiveCategories(new Set(defaultsArray));
|
|
21415
23047
|
setSearchText("");
|
|
21416
23048
|
setClearedAt(0);
|
|
21417
23049
|
}, [defaultsArray]);
|
|
21418
|
-
const handleClear = (0, react.useCallback)(() => {
|
|
23050
|
+
const handleClear = (0, react$1.useCallback)(() => {
|
|
21419
23051
|
setClearedAt(Date.now());
|
|
21420
23052
|
buffer.reset();
|
|
21421
23053
|
}, [buffer]);
|
|
21422
|
-
const [copiedAll, setCopiedAll] = (0, react.useState)(false);
|
|
21423
|
-
const [copiedRowId, setCopiedRowId] = (0, react.useState)(null);
|
|
21424
|
-
const formatEventForCopy = (0, react.useCallback)((event) => {
|
|
23054
|
+
const [copiedAll, setCopiedAll] = (0, react$1.useState)(false);
|
|
23055
|
+
const [copiedRowId, setCopiedRowId] = (0, react$1.useState)(null);
|
|
23056
|
+
const formatEventForCopy = (0, react$1.useCallback)((event) => {
|
|
21425
23057
|
const time = new Date(event.timestamp).toISOString();
|
|
21426
23058
|
const summary = summarizeEvent(event.category, event.data) ?? "";
|
|
21427
23059
|
const summaryStr = summary ? ` ${summary}` : "";
|
|
21428
23060
|
return `${time} [${event.category}]${summaryStr} data=${JSON.stringify(event.data)}`;
|
|
21429
23061
|
}, []);
|
|
21430
|
-
const handleCopyAll = (0, react.useCallback)(() => {
|
|
23062
|
+
const handleCopyAll = (0, react$1.useCallback)(() => {
|
|
21431
23063
|
const lines = allEvents.map(formatEventForCopy);
|
|
21432
23064
|
navigator.clipboard.writeText(lines.join("\n")).then(() => {
|
|
21433
23065
|
setCopiedAll(true);
|
|
21434
23066
|
setTimeout(() => setCopiedAll(false), 1500);
|
|
21435
23067
|
});
|
|
21436
23068
|
}, [allEvents, formatEventForCopy]);
|
|
21437
|
-
const copyOne = (0, react.useCallback)((event) => {
|
|
23069
|
+
const copyOne = (0, react$1.useCallback)((event) => {
|
|
21438
23070
|
navigator.clipboard.writeText(formatEventForCopy(event)).then(() => {
|
|
21439
23071
|
setCopiedRowId(event.id);
|
|
21440
23072
|
setTimeout(() => setCopiedRowId((prev) => prev === event.id ? null : prev), 1200);
|
|
21441
23073
|
});
|
|
21442
23074
|
}, [formatEventForCopy]);
|
|
21443
|
-
const handleSelectAll = (0, react.useCallback)(() => {
|
|
23075
|
+
const handleSelectAll = (0, react$1.useCallback)(() => {
|
|
21444
23076
|
setActiveCategories(new Set(ALL_EVENT_CATEGORIES));
|
|
21445
23077
|
}, []);
|
|
21446
|
-
const handleSelectNone = (0, react.useCallback)(() => {
|
|
23078
|
+
const handleSelectNone = (0, react$1.useCallback)(() => {
|
|
21447
23079
|
setActiveCategories(/* @__PURE__ */ new Set());
|
|
21448
23080
|
}, []);
|
|
21449
|
-
const filteredPopoverCategories = (0, react.useMemo)(() => {
|
|
23081
|
+
const filteredPopoverCategories = (0, react$1.useMemo)(() => {
|
|
21450
23082
|
const needle = categorySearch.trim().toLowerCase();
|
|
21451
23083
|
if (!needle) return ALL_EVENT_CATEGORIES;
|
|
21452
23084
|
return ALL_EVENT_CATEGORIES.filter((c) => c.toLowerCase().includes(needle));
|
|
@@ -21824,8 +23456,8 @@ function DiscoveryPanel({ deviceId, className = "", onOpenChild }) {
|
|
|
21824
23456
|
const releaseMutation = trpc.deviceDiscovery.releaseDevice.useMutation({ onSuccess: () => {
|
|
21825
23457
|
utils.deviceDiscovery.listDiscovered.invalidate({ deviceId });
|
|
21826
23458
|
} });
|
|
21827
|
-
const [busyChildId, setBusyChildId] = (0, react.useState)(null);
|
|
21828
|
-
const { available, adopted } = (0, react.useMemo)(() => {
|
|
23459
|
+
const [busyChildId, setBusyChildId] = (0, react$1.useState)(null);
|
|
23460
|
+
const { available, adopted } = (0, react$1.useMemo)(() => {
|
|
21829
23461
|
const list = listQuery.data ?? [];
|
|
21830
23462
|
const sortKey = (c) => typeof c.metadata.rtspChannel === "number" ? c.metadata.rtspChannel : Number.POSITIVE_INFINITY;
|
|
21831
23463
|
const byChannel = (a, b) => {
|
|
@@ -22104,20 +23736,20 @@ var MAX_LIVE_ENTRIES = 300;
|
|
|
22104
23736
|
*/
|
|
22105
23737
|
var ALL_DEVICE_CAP_NAMES = Object.freeze([...new Set(_camstack_types.ALL_CAPABILITY_DEFINITIONS.filter((c) => c.scope === "device").map((c) => c.name))].sort());
|
|
22106
23738
|
function StateValuesStream({ deviceId, defaultCaps, maxHeight = "max-h-96", limit = 50, liveBuffer: externalBuffer, onClose, className }) {
|
|
22107
|
-
const [activeCaps, setActiveCaps] = (0, react.useState)((0, react.useMemo)(() => new Set(defaultCaps ?? []), [defaultCaps]));
|
|
22108
|
-
const [searchText, setSearchText] = (0, react.useState)("");
|
|
22109
|
-
const [autoScroll, setAutoScroll] = (0, react.useState)(true);
|
|
22110
|
-
const [expandedRows, setExpandedRows] = (0, react.useState)(/* @__PURE__ */ new Set());
|
|
22111
|
-
const [clearedAt, setClearedAt] = (0, react.useState)(0);
|
|
22112
|
-
const [filterOpen, setFilterOpen] = (0, react.useState)(false);
|
|
22113
|
-
const [filterSearch, setFilterSearch] = (0, react.useState)("");
|
|
22114
|
-
const filterRootRef = (0, react.useRef)(null);
|
|
23739
|
+
const [activeCaps, setActiveCaps] = (0, react$1.useState)((0, react$1.useMemo)(() => new Set(defaultCaps ?? []), [defaultCaps]));
|
|
23740
|
+
const [searchText, setSearchText] = (0, react$1.useState)("");
|
|
23741
|
+
const [autoScroll, setAutoScroll] = (0, react$1.useState)(true);
|
|
23742
|
+
const [expandedRows, setExpandedRows] = (0, react$1.useState)(/* @__PURE__ */ new Set());
|
|
23743
|
+
const [clearedAt, setClearedAt] = (0, react$1.useState)(0);
|
|
23744
|
+
const [filterOpen, setFilterOpen] = (0, react$1.useState)(false);
|
|
23745
|
+
const [filterSearch, setFilterSearch] = (0, react$1.useState)("");
|
|
23746
|
+
const filterRootRef = (0, react$1.useRef)(null);
|
|
22115
23747
|
const fallbackBuffer = useLiveBuffer(MAX_LIVE_ENTRIES);
|
|
22116
23748
|
const buffer = externalBuffer ?? fallbackBuffer;
|
|
22117
23749
|
const liveEvents = buffer.entries;
|
|
22118
|
-
const scrollRef = (0, react.useRef)(null);
|
|
22119
|
-
const prevDeviceRef = (0, react.useRef)(deviceId);
|
|
22120
|
-
(0, react.useEffect)(() => {
|
|
23750
|
+
const scrollRef = (0, react$1.useRef)(null);
|
|
23751
|
+
const prevDeviceRef = (0, react$1.useRef)(deviceId);
|
|
23752
|
+
(0, react$1.useEffect)(() => {
|
|
22121
23753
|
if (prevDeviceRef.current !== deviceId) {
|
|
22122
23754
|
prevDeviceRef.current = deviceId;
|
|
22123
23755
|
buffer.reset();
|
|
@@ -22125,14 +23757,14 @@ function StateValuesStream({ deviceId, defaultCaps, maxHeight = "max-h-96", limi
|
|
|
22125
23757
|
setClearedAt(0);
|
|
22126
23758
|
}
|
|
22127
23759
|
}, [deviceId, buffer]);
|
|
22128
|
-
const recentInput = (0, react.useMemo)(() => ({
|
|
23760
|
+
const recentInput = (0, react$1.useMemo)(() => ({
|
|
22129
23761
|
deviceId,
|
|
22130
23762
|
category: _camstack_types.EventCategory.DeviceStateChanged,
|
|
22131
23763
|
limit
|
|
22132
23764
|
}), [deviceId, limit]);
|
|
22133
23765
|
const { data: initialEvents, isLoading } = trpc.systemEvents.getRecent.useQuery(recentInput, { staleTime: 3e4 });
|
|
22134
|
-
const activeCapsRef = (0, react.useRef)(activeCaps);
|
|
22135
|
-
(0, react.useEffect)(() => {
|
|
23766
|
+
const activeCapsRef = (0, react$1.useRef)(activeCaps);
|
|
23767
|
+
(0, react$1.useEffect)(() => {
|
|
22136
23768
|
activeCapsRef.current = activeCaps;
|
|
22137
23769
|
}, [activeCaps]);
|
|
22138
23770
|
trpc.systemEvents.subscribe.useSubscription({
|
|
@@ -22146,8 +23778,8 @@ function StateValuesStream({ deviceId, defaultCaps, maxHeight = "max-h-96", limi
|
|
|
22146
23778
|
if (active.size > 0 && !active.has(entry.capName)) return;
|
|
22147
23779
|
buffer.append(entry);
|
|
22148
23780
|
} });
|
|
22149
|
-
const prevLiveCountRef = (0, react.useRef)(liveEvents.length);
|
|
22150
|
-
(0, react.useEffect)(() => {
|
|
23781
|
+
const prevLiveCountRef = (0, react$1.useRef)(liveEvents.length);
|
|
23782
|
+
(0, react$1.useEffect)(() => {
|
|
22151
23783
|
const el = scrollRef.current;
|
|
22152
23784
|
if (!el) {
|
|
22153
23785
|
prevLiveCountRef.current = liveEvents.length;
|
|
@@ -22164,7 +23796,7 @@ function StateValuesStream({ deviceId, defaultCaps, maxHeight = "max-h-96", limi
|
|
|
22164
23796
|
el.scrollTop += rowHeight * newCount;
|
|
22165
23797
|
}
|
|
22166
23798
|
}, [liveEvents.length, autoScroll]);
|
|
22167
|
-
const allEntries = (0, react.useMemo)(() => {
|
|
23799
|
+
const allEntries = (0, react$1.useMemo)(() => {
|
|
22168
23800
|
const byId = /* @__PURE__ */ new Map();
|
|
22169
23801
|
for (const e of initialEvents ?? []) {
|
|
22170
23802
|
const entry = toEntry(e);
|
|
@@ -22196,7 +23828,7 @@ function StateValuesStream({ deviceId, defaultCaps, maxHeight = "max-h-96", limi
|
|
|
22196
23828
|
searchText,
|
|
22197
23829
|
clearedAt
|
|
22198
23830
|
]);
|
|
22199
|
-
const visibleCaps = (0, react.useMemo)(() => {
|
|
23831
|
+
const visibleCaps = (0, react$1.useMemo)(() => {
|
|
22200
23832
|
const caps = new Set(ALL_DEVICE_CAP_NAMES);
|
|
22201
23833
|
for (const e of initialEvents ?? []) {
|
|
22202
23834
|
const entry = toEntry(e);
|
|
@@ -22205,7 +23837,7 @@ function StateValuesStream({ deviceId, defaultCaps, maxHeight = "max-h-96", limi
|
|
|
22205
23837
|
for (const e of liveEvents) caps.add(e.capName);
|
|
22206
23838
|
return [...caps].sort();
|
|
22207
23839
|
}, [initialEvents, liveEvents]);
|
|
22208
|
-
const toggleRow = (0, react.useCallback)((id) => {
|
|
23840
|
+
const toggleRow = (0, react$1.useCallback)((id) => {
|
|
22209
23841
|
setExpandedRows((prev) => {
|
|
22210
23842
|
const next = new Set(prev);
|
|
22211
23843
|
if (next.has(id)) next.delete(id);
|
|
@@ -22213,7 +23845,7 @@ function StateValuesStream({ deviceId, defaultCaps, maxHeight = "max-h-96", limi
|
|
|
22213
23845
|
return next;
|
|
22214
23846
|
});
|
|
22215
23847
|
}, []);
|
|
22216
|
-
const toggleCap = (0, react.useCallback)((cap) => {
|
|
23848
|
+
const toggleCap = (0, react$1.useCallback)((cap) => {
|
|
22217
23849
|
setActiveCaps((prev) => {
|
|
22218
23850
|
const next = new Set(prev);
|
|
22219
23851
|
if (next.has(cap)) next.delete(cap);
|
|
@@ -22221,39 +23853,39 @@ function StateValuesStream({ deviceId, defaultCaps, maxHeight = "max-h-96", limi
|
|
|
22221
23853
|
return next;
|
|
22222
23854
|
});
|
|
22223
23855
|
}, []);
|
|
22224
|
-
const handleReset = (0, react.useCallback)(() => {
|
|
23856
|
+
const handleReset = (0, react$1.useCallback)(() => {
|
|
22225
23857
|
setActiveCaps(new Set(defaultCaps ?? []));
|
|
22226
23858
|
setSearchText("");
|
|
22227
23859
|
}, [defaultCaps]);
|
|
22228
|
-
const handleClear = (0, react.useCallback)(() => {
|
|
23860
|
+
const handleClear = (0, react$1.useCallback)(() => {
|
|
22229
23861
|
setClearedAt(Date.now());
|
|
22230
23862
|
buffer.reset();
|
|
22231
23863
|
}, [buffer]);
|
|
22232
|
-
const [copiedAll, setCopiedAll] = (0, react.useState)(false);
|
|
22233
|
-
const [copiedRowId, setCopiedRowId] = (0, react.useState)(null);
|
|
22234
|
-
const formatEntryForCopy = (0, react.useCallback)((entry) => {
|
|
23864
|
+
const [copiedAll, setCopiedAll] = (0, react$1.useState)(false);
|
|
23865
|
+
const [copiedRowId, setCopiedRowId] = (0, react$1.useState)(null);
|
|
23866
|
+
const formatEntryForCopy = (0, react$1.useCallback)((entry) => {
|
|
22235
23867
|
return `${new Date(entry.timestamp).toISOString()} [${entry.capName}] slice=${JSON.stringify(entry.slice)}`;
|
|
22236
23868
|
}, []);
|
|
22237
|
-
const handleCopyAll = (0, react.useCallback)(() => {
|
|
23869
|
+
const handleCopyAll = (0, react$1.useCallback)(() => {
|
|
22238
23870
|
const lines = allEntries.map(formatEntryForCopy);
|
|
22239
23871
|
navigator.clipboard.writeText(lines.join("\n")).then(() => {
|
|
22240
23872
|
setCopiedAll(true);
|
|
22241
23873
|
setTimeout(() => setCopiedAll(false), 1500);
|
|
22242
23874
|
});
|
|
22243
23875
|
}, [allEntries, formatEntryForCopy]);
|
|
22244
|
-
const copyOne = (0, react.useCallback)((entry) => {
|
|
23876
|
+
const copyOne = (0, react$1.useCallback)((entry) => {
|
|
22245
23877
|
navigator.clipboard.writeText(formatEntryForCopy(entry)).then(() => {
|
|
22246
23878
|
setCopiedRowId(entry.id);
|
|
22247
23879
|
setTimeout(() => setCopiedRowId((prev) => prev === entry.id ? null : prev), 1200);
|
|
22248
23880
|
});
|
|
22249
23881
|
}, [formatEntryForCopy]);
|
|
22250
|
-
const handleSelectAllCaps = (0, react.useCallback)(() => {
|
|
23882
|
+
const handleSelectAllCaps = (0, react$1.useCallback)(() => {
|
|
22251
23883
|
setActiveCaps(new Set(visibleCaps));
|
|
22252
23884
|
}, [visibleCaps]);
|
|
22253
|
-
const handleSelectNoCaps = (0, react.useCallback)(() => {
|
|
23885
|
+
const handleSelectNoCaps = (0, react$1.useCallback)(() => {
|
|
22254
23886
|
setActiveCaps(/* @__PURE__ */ new Set());
|
|
22255
23887
|
}, []);
|
|
22256
|
-
const filteredPopoverCaps = (0, react.useMemo)(() => {
|
|
23888
|
+
const filteredPopoverCaps = (0, react$1.useMemo)(() => {
|
|
22257
23889
|
const needle = filterSearch.trim().toLowerCase();
|
|
22258
23890
|
if (!needle) return visibleCaps;
|
|
22259
23891
|
return visibleCaps.filter((c) => c.toLowerCase().includes(needle));
|
|
@@ -22262,7 +23894,7 @@ function StateValuesStream({ deviceId, defaultCaps, maxHeight = "max-h-96", limi
|
|
|
22262
23894
|
const totalActive = activeCaps.size;
|
|
22263
23895
|
const allSelected = totalActive === 0 || totalActive === totalAvailable;
|
|
22264
23896
|
const filterLabel = allSelected ? "All" : `${totalActive}/${totalAvailable}`;
|
|
22265
|
-
(0, react.useEffect)(() => {
|
|
23897
|
+
(0, react$1.useEffect)(() => {
|
|
22266
23898
|
if (!filterOpen) return;
|
|
22267
23899
|
const onDocClick = (e) => {
|
|
22268
23900
|
const root = filterRootRef.current;
|
|
@@ -22622,14 +24254,14 @@ var TABS = [
|
|
|
22622
24254
|
}
|
|
22623
24255
|
];
|
|
22624
24256
|
function DeviceActivityPanel({ deviceId, defaultEventCategories, defaultStateCaps, initialTab = "events", className, maxHeight = "max-h-96" }) {
|
|
22625
|
-
const [tab, setTab] = (0, react.useState)(initialTab);
|
|
24257
|
+
const [tab, setTab] = (0, react$1.useState)(initialTab);
|
|
22626
24258
|
const logsBuffer = useLiveBuffer(PANEL_BUFFER_SIZE);
|
|
22627
24259
|
const eventsBuffer = useLiveBuffer(PANEL_BUFFER_SIZE);
|
|
22628
24260
|
const stateBuffer = useLiveBuffer(PANEL_BUFFER_SIZE);
|
|
22629
24261
|
const logsReset = logsBuffer.reset;
|
|
22630
24262
|
const eventsReset = eventsBuffer.reset;
|
|
22631
24263
|
const stateReset = stateBuffer.reset;
|
|
22632
|
-
(0, react.useEffect)(() => {
|
|
24264
|
+
(0, react$1.useEffect)(() => {
|
|
22633
24265
|
logsReset();
|
|
22634
24266
|
eventsReset();
|
|
22635
24267
|
stateReset();
|
|
@@ -22693,9 +24325,9 @@ function DeviceActivityPanel({ deviceId, defaultEventCategories, defaultStateCap
|
|
|
22693
24325
|
* for reboot, RefreshCw for restart).
|
|
22694
24326
|
*/
|
|
22695
24327
|
function ConfirmActionButton({ label, icon: Icon, title = "Confirm action", description, confirmLabel, triggerVariant = "outline", confirmVariant = "danger", size = "sm", disabled, className, action, onSuccess }) {
|
|
22696
|
-
const [open, setOpen] = (0, react.useState)(false);
|
|
22697
|
-
const [running, setRunning] = (0, react.useState)(false);
|
|
22698
|
-
const [error, setError] = (0, react.useState)(null);
|
|
24328
|
+
const [open, setOpen] = (0, react$1.useState)(false);
|
|
24329
|
+
const [running, setRunning] = (0, react$1.useState)(false);
|
|
24330
|
+
const [error, setError] = (0, react$1.useState)(null);
|
|
22699
24331
|
const handleConfirm = async () => {
|
|
22700
24332
|
setError(null);
|
|
22701
24333
|
setRunning(true);
|
|
@@ -22774,9 +24406,9 @@ function ConfirmActionButton({ label, icon: Icon, title = "Confirm action", desc
|
|
|
22774
24406
|
* release (`startContinuous` + `stopContinuous` on pointer up).
|
|
22775
24407
|
*/
|
|
22776
24408
|
function DPadButton({ direction, icon: Icon, disabled, className, variant, onMove, onStart, onStop }) {
|
|
22777
|
-
const [pressedAt, setPressedAt] = (0, react.useState)(null);
|
|
22778
|
-
const [continuous, setContinuous] = (0, react.useState)(false);
|
|
22779
|
-
const handlePointerDown = (0, react.useCallback)((e) => {
|
|
24409
|
+
const [pressedAt, setPressedAt] = (0, react$1.useState)(null);
|
|
24410
|
+
const [continuous, setContinuous] = (0, react$1.useState)(false);
|
|
24411
|
+
const handlePointerDown = (0, react$1.useCallback)((e) => {
|
|
22780
24412
|
if (disabled) return;
|
|
22781
24413
|
e.currentTarget.setPointerCapture(e.pointerId);
|
|
22782
24414
|
setPressedAt(Date.now());
|
|
@@ -22791,7 +24423,7 @@ function DPadButton({ direction, icon: Icon, disabled, className, variant, onMov
|
|
|
22791
24423
|
disabled,
|
|
22792
24424
|
onStart
|
|
22793
24425
|
]);
|
|
22794
|
-
const handlePointerUp = (0, react.useCallback)((e) => {
|
|
24426
|
+
const handlePointerUp = (0, react$1.useCallback)((e) => {
|
|
22795
24427
|
const timerId = Number(e.currentTarget.dataset.timer);
|
|
22796
24428
|
if (timerId) clearTimeout(timerId);
|
|
22797
24429
|
e.currentTarget.dataset.timer = "";
|
|
@@ -22806,7 +24438,7 @@ function DPadButton({ direction, icon: Icon, disabled, className, variant, onMov
|
|
|
22806
24438
|
onStop,
|
|
22807
24439
|
pressedAt
|
|
22808
24440
|
]);
|
|
22809
|
-
const handlePointerCancel = (0, react.useCallback)((e) => {
|
|
24441
|
+
const handlePointerCancel = (0, react$1.useCallback)((e) => {
|
|
22810
24442
|
const timerId = Number(e.currentTarget.dataset.timer);
|
|
22811
24443
|
if (timerId) clearTimeout(timerId);
|
|
22812
24444
|
e.currentTarget.dataset.timer = "";
|
|
@@ -22829,7 +24461,7 @@ function DPadButton({ direction, icon: Icon, disabled, className, variant, onMov
|
|
|
22829
24461
|
}
|
|
22830
24462
|
function PTZOverlay({ controls, mode = "overlay", showPresets, showZoom = true, showHome = true, className }) {
|
|
22831
24463
|
const { move, startContinuous, stopContinuous, zoom, goHome, goToPreset, presets, busy, error } = controls;
|
|
22832
|
-
const [presetsOpen, setPresetsOpen] = (0, react.useState)(false);
|
|
24464
|
+
const [presetsOpen, setPresetsOpen] = (0, react$1.useState)(false);
|
|
22833
24465
|
const presetsVisible = (showPresets ?? presets.length > 0) && presets.length > 0;
|
|
22834
24466
|
const isPanel = mode === "panel";
|
|
22835
24467
|
const containerClass = isPanel ? "flex flex-col items-stretch gap-2 w-full h-full p-3" : "pointer-events-auto absolute top-3 right-3 z-10 flex flex-col items-end gap-2";
|
|
@@ -22982,11 +24614,11 @@ function downloadDataUrl(filename, dataUrl) {
|
|
|
22982
24614
|
document.body.removeChild(link);
|
|
22983
24615
|
}
|
|
22984
24616
|
function SnapshotButton({ trpc, deviceId, deviceName, size = "sm", className }) {
|
|
22985
|
-
const [busy, setBusy] = (0, react.useState)(false);
|
|
22986
|
-
const [done, setDone] = (0, react.useState)(false);
|
|
22987
|
-
const [error, setError] = (0, react.useState)(null);
|
|
24617
|
+
const [busy, setBusy] = (0, react$1.useState)(false);
|
|
24618
|
+
const [done, setDone] = (0, react$1.useState)(false);
|
|
24619
|
+
const [error, setError] = (0, react$1.useState)(null);
|
|
22988
24620
|
const safeName = deviceName.replace(/[^a-zA-Z0-9_.-]+/g, "_");
|
|
22989
|
-
const fetchSnapshot = (0, react.useCallback)(async (action) => {
|
|
24621
|
+
const fetchSnapshot = (0, react$1.useCallback)(async (action) => {
|
|
22990
24622
|
setBusy(true);
|
|
22991
24623
|
setError(null);
|
|
22992
24624
|
setDone(false);
|
|
@@ -23019,8 +24651,8 @@ function SnapshotButton({ trpc, deviceId, deviceName, size = "sm", className })
|
|
|
23019
24651
|
safeName
|
|
23020
24652
|
]);
|
|
23021
24653
|
const sizeClasses = size === "md" ? "h-9 px-3 text-sm gap-2" : "h-7 px-2.5 text-[11px] gap-1.5";
|
|
23022
|
-
const [pressTimer, setPressTimer] = (0, react.useState)(null);
|
|
23023
|
-
const [longPressed, setLongPressed] = (0, react.useState)(false);
|
|
24654
|
+
const [pressTimer, setPressTimer] = (0, react$1.useState)(null);
|
|
24655
|
+
const [longPressed, setLongPressed] = (0, react$1.useState)(false);
|
|
23024
24656
|
const handlePointerDown = () => {
|
|
23025
24657
|
setLongPressed(false);
|
|
23026
24658
|
setPressTimer(setTimeout(() => {
|
|
@@ -23127,7 +24759,7 @@ function DoorbellRecentPanel({ history, limit = 5, latestIsFresh, className }) {
|
|
|
23127
24759
|
* touch devices, no extra wiring needed.
|
|
23128
24760
|
*/
|
|
23129
24761
|
function KebabMenu({ items, header, triggerClassName, title = "More actions" }) {
|
|
23130
|
-
const [open, setOpen] = (0, react.useState)(false);
|
|
24762
|
+
const [open, setOpen] = (0, react$1.useState)(false);
|
|
23131
24763
|
const visible = items.filter((i) => !i.hidden);
|
|
23132
24764
|
if (visible.length === 0) return null;
|
|
23133
24765
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Popover, {
|
|
@@ -23269,19 +24901,19 @@ function clampedAccessForRow(row, parent) {
|
|
|
23269
24901
|
function ScopePicker({ value, onChange, clampToParent, emptyHint }) {
|
|
23270
24902
|
const { data: addons } = useAddonsList();
|
|
23271
24903
|
const { data: devices } = useDeviceManagerListAll({});
|
|
23272
|
-
const addonChoices = (0, react.useMemo)(() => (addons ?? []).map((a) => ({
|
|
24904
|
+
const addonChoices = (0, react$1.useMemo)(() => (addons ?? []).map((a) => ({
|
|
23273
24905
|
value: a.manifest.id,
|
|
23274
24906
|
label: a.manifest.id
|
|
23275
24907
|
})).sort((a, b) => a.label.localeCompare(b.label)), [addons]);
|
|
23276
|
-
const capChoices = (0, react.useMemo)(() => [..._camstack_types.KNOWN_CAP_NAMES].sort().map((c) => ({
|
|
24908
|
+
const capChoices = (0, react$1.useMemo)(() => [..._camstack_types.KNOWN_CAP_NAMES].sort().map((c) => ({
|
|
23277
24909
|
value: c,
|
|
23278
24910
|
label: c
|
|
23279
24911
|
})), []);
|
|
23280
|
-
const deviceChoices = (0, react.useMemo)(() => (devices ?? []).map((d) => ({
|
|
24912
|
+
const deviceChoices = (0, react$1.useMemo)(() => (devices ?? []).map((d) => ({
|
|
23281
24913
|
value: String(d.id),
|
|
23282
24914
|
label: `${d.name} (#${d.id} · ${d.addonId})`
|
|
23283
24915
|
})).sort((a, b) => a.label.localeCompare(b.label)), [devices]);
|
|
23284
|
-
const parentDeviceClamp = (0, react.useMemo)(() => clampToParent == null ? null : parentDeviceTargets(clampToParent), [clampToParent]);
|
|
24916
|
+
const parentDeviceClamp = (0, react$1.useMemo)(() => clampToParent == null ? null : parentDeviceTargets(clampToParent), [clampToParent]);
|
|
23285
24917
|
/**
|
|
23286
24918
|
* Build a fresh scope row when `type` changes. The discriminated union
|
|
23287
24919
|
* forces us to re-construct the object per variant so the resulting
|
|
@@ -23448,8 +25080,8 @@ function ScopePicker({ value, onChange, clampToParent, emptyHint }) {
|
|
|
23448
25080
|
});
|
|
23449
25081
|
}
|
|
23450
25082
|
function DeviceTargetPicker({ value, choices, clampToParent, onChange }) {
|
|
23451
|
-
const [pendingAdd, setPendingAdd] = (0, react.useState)("");
|
|
23452
|
-
const visibleChoices = (0, react.useMemo)(() => {
|
|
25083
|
+
const [pendingAdd, setPendingAdd] = (0, react$1.useState)("");
|
|
25084
|
+
const visibleChoices = (0, react$1.useMemo)(() => {
|
|
23453
25085
|
const filtered = clampToParent == null ? choices : choices.filter((c) => clampToParent.includes(c.value));
|
|
23454
25086
|
const taken = new Set(value);
|
|
23455
25087
|
return filtered.filter((c) => !taken.has(c.value));
|
|
@@ -23545,11 +25177,11 @@ function validateScopes(scopes) {
|
|
|
23545
25177
|
*/
|
|
23546
25178
|
var ZoneEditingContext = createSharedContext("camstack:zone-editing", null);
|
|
23547
25179
|
function ZoneEditingProvider({ children }) {
|
|
23548
|
-
const [editing, setEditingRaw] = (0, react.useState)(false);
|
|
23549
|
-
const [drawingKind, setDrawingKindRaw] = (0, react.useState)(null);
|
|
23550
|
-
const [selectedZoneId, setSelectedZoneIdRaw] = (0, react.useState)(null);
|
|
23551
|
-
const [editingDraft, setEditingDraftRaw] = (0, react.useState)(null);
|
|
23552
|
-
const setEditing = (0, react.useCallback)((next) => {
|
|
25180
|
+
const [editing, setEditingRaw] = (0, react$1.useState)(false);
|
|
25181
|
+
const [drawingKind, setDrawingKindRaw] = (0, react$1.useState)(null);
|
|
25182
|
+
const [selectedZoneId, setSelectedZoneIdRaw] = (0, react$1.useState)(null);
|
|
25183
|
+
const [editingDraft, setEditingDraftRaw] = (0, react$1.useState)(null);
|
|
25184
|
+
const setEditing = (0, react$1.useCallback)((next) => {
|
|
23553
25185
|
setEditingRaw(next);
|
|
23554
25186
|
if (!next) {
|
|
23555
25187
|
setDrawingKindRaw(null);
|
|
@@ -23557,38 +25189,38 @@ function ZoneEditingProvider({ children }) {
|
|
|
23557
25189
|
setEditingDraftRaw(null);
|
|
23558
25190
|
}
|
|
23559
25191
|
}, []);
|
|
23560
|
-
const setDrawingKind = (0, react.useCallback)((kind) => {
|
|
25192
|
+
const setDrawingKind = (0, react$1.useCallback)((kind) => {
|
|
23561
25193
|
setDrawingKindRaw(kind);
|
|
23562
25194
|
}, []);
|
|
23563
|
-
const setSelectedZoneId = (0, react.useCallback)((id) => {
|
|
25195
|
+
const setSelectedZoneId = (0, react$1.useCallback)((id) => {
|
|
23564
25196
|
setSelectedZoneIdRaw(id);
|
|
23565
25197
|
}, []);
|
|
23566
|
-
const startDrawing = (0, react.useCallback)((kind) => {
|
|
25198
|
+
const startDrawing = (0, react$1.useCallback)((kind) => {
|
|
23567
25199
|
setEditingRaw(true);
|
|
23568
25200
|
setSelectedZoneIdRaw(null);
|
|
23569
25201
|
setDrawingKindRaw(kind);
|
|
23570
25202
|
setEditingDraftRaw(null);
|
|
23571
25203
|
}, []);
|
|
23572
|
-
const exitEditing = (0, react.useCallback)(() => {
|
|
25204
|
+
const exitEditing = (0, react$1.useCallback)(() => {
|
|
23573
25205
|
setEditingRaw(false);
|
|
23574
25206
|
setDrawingKindRaw(null);
|
|
23575
25207
|
setSelectedZoneIdRaw(null);
|
|
23576
25208
|
setEditingDraftRaw(null);
|
|
23577
25209
|
}, []);
|
|
23578
|
-
const enterDraft = (0, react.useCallback)((draft) => {
|
|
25210
|
+
const enterDraft = (0, react$1.useCallback)((draft) => {
|
|
23579
25211
|
setSelectedZoneIdRaw(draft.id);
|
|
23580
25212
|
setEditingDraftRaw(draft);
|
|
23581
25213
|
}, []);
|
|
23582
|
-
const updateDraft = (0, react.useCallback)((patch) => {
|
|
25214
|
+
const updateDraft = (0, react$1.useCallback)((patch) => {
|
|
23583
25215
|
setEditingDraftRaw((prev) => prev === null ? prev : {
|
|
23584
25216
|
...prev,
|
|
23585
25217
|
...patch
|
|
23586
25218
|
});
|
|
23587
25219
|
}, []);
|
|
23588
|
-
const discardDraft = (0, react.useCallback)(() => {
|
|
25220
|
+
const discardDraft = (0, react$1.useCallback)(() => {
|
|
23589
25221
|
setEditingDraftRaw(null);
|
|
23590
25222
|
}, []);
|
|
23591
|
-
const value = (0, react.useMemo)(() => ({
|
|
25223
|
+
const value = (0, react$1.useMemo)(() => ({
|
|
23592
25224
|
editing,
|
|
23593
25225
|
drawingKind,
|
|
23594
25226
|
selectedZoneId,
|
|
@@ -23624,7 +25256,7 @@ function ZoneEditingProvider({ children }) {
|
|
|
23624
25256
|
* provider so callers that mount in pages without zones (e.g. a
|
|
23625
25257
|
* shared hero on a non-camera device) can no-op gracefully. */
|
|
23626
25258
|
function useZoneEditing() {
|
|
23627
|
-
return (0, react.useContext)(ZoneEditingContext);
|
|
25259
|
+
return (0, react$1.useContext)(ZoneEditingContext);
|
|
23628
25260
|
}
|
|
23629
25261
|
//#endregion
|
|
23630
25262
|
//#region src/hooks/use-device-detections.ts
|
|
@@ -23652,14 +25284,14 @@ function matchesDevice(source, deviceId) {
|
|
|
23652
25284
|
return source?.id === deviceId;
|
|
23653
25285
|
}
|
|
23654
25286
|
function useDeviceDetections(trpc, deviceId) {
|
|
23655
|
-
const [motion, setMotion] = (0, react.useState)(null);
|
|
23656
|
-
const [motionRaw, setMotionRaw] = (0, react.useState)(null);
|
|
23657
|
-
const [detection, setDetection] = (0, react.useState)(null);
|
|
23658
|
-
const [phase, setPhase] = (0, react.useState)("watching");
|
|
23659
|
-
const motionTimer = (0, react.useRef)(void 0);
|
|
23660
|
-
const motionRawTimer = (0, react.useRef)(void 0);
|
|
23661
|
-
const detectionTimer = (0, react.useRef)(void 0);
|
|
23662
|
-
(0, react.useEffect)(() => {
|
|
25287
|
+
const [motion, setMotion] = (0, react$1.useState)(null);
|
|
25288
|
+
const [motionRaw, setMotionRaw] = (0, react$1.useState)(null);
|
|
25289
|
+
const [detection, setDetection] = (0, react$1.useState)(null);
|
|
25290
|
+
const [phase, setPhase] = (0, react$1.useState)("watching");
|
|
25291
|
+
const motionTimer = (0, react$1.useRef)(void 0);
|
|
25292
|
+
const motionRawTimer = (0, react$1.useRef)(void 0);
|
|
25293
|
+
const detectionTimer = (0, react$1.useRef)(void 0);
|
|
25294
|
+
(0, react$1.useEffect)(() => {
|
|
23663
25295
|
if (deviceId === null) return;
|
|
23664
25296
|
const sub = safeSubscribe(trpc, "detection.motion-analysis", (event) => {
|
|
23665
25297
|
const e = event;
|
|
@@ -23682,7 +25314,7 @@ function useDeviceDetections(trpc, deviceId) {
|
|
|
23682
25314
|
if (motionTimer.current) clearTimeout(motionTimer.current);
|
|
23683
25315
|
};
|
|
23684
25316
|
}, [trpc, deviceId]);
|
|
23685
|
-
(0, react.useEffect)(() => {
|
|
25317
|
+
(0, react$1.useEffect)(() => {
|
|
23686
25318
|
if (deviceId === null) return;
|
|
23687
25319
|
const sub = safeSubscribe(trpc, "detection.motion-zones-raw", (event) => {
|
|
23688
25320
|
const e = event;
|
|
@@ -23706,7 +25338,7 @@ function useDeviceDetections(trpc, deviceId) {
|
|
|
23706
25338
|
if (motionRawTimer.current) clearTimeout(motionRawTimer.current);
|
|
23707
25339
|
};
|
|
23708
25340
|
}, [trpc, deviceId]);
|
|
23709
|
-
(0, react.useEffect)(() => {
|
|
25341
|
+
(0, react$1.useEffect)(() => {
|
|
23710
25342
|
if (deviceId === null) return;
|
|
23711
25343
|
const sub = safeSubscribe(trpc, "detection.result", (event) => {
|
|
23712
25344
|
const e = event;
|
|
@@ -23726,7 +25358,7 @@ function useDeviceDetections(trpc, deviceId) {
|
|
|
23726
25358
|
if (detectionTimer.current) clearTimeout(detectionTimer.current);
|
|
23727
25359
|
};
|
|
23728
25360
|
}, [trpc, deviceId]);
|
|
23729
|
-
(0, react.useEffect)(() => {
|
|
25361
|
+
(0, react$1.useEffect)(() => {
|
|
23730
25362
|
if (deviceId === null) return;
|
|
23731
25363
|
const sub = safeSubscribe(trpc, "detection.phase-transition", (event) => {
|
|
23732
25364
|
const e = event;
|
|
@@ -23763,8 +25395,8 @@ function useDeviceDetections(trpc, deviceId) {
|
|
|
23763
25395
|
* @param pollIntervalMs - how often to refresh profile slots (default: 5000)
|
|
23764
25396
|
*/
|
|
23765
25397
|
function useDeviceWebrtc(trpc, deviceId, pollIntervalMs = 5e3) {
|
|
23766
|
-
const [remoteStreams, setRemoteStreams] = (0, react.useState)([]);
|
|
23767
|
-
(0, react.useEffect)(() => {
|
|
25398
|
+
const [remoteStreams, setRemoteStreams] = (0, react$1.useState)([]);
|
|
25399
|
+
(0, react$1.useEffect)(() => {
|
|
23768
25400
|
if (deviceId === null) return;
|
|
23769
25401
|
let cancelled = false;
|
|
23770
25402
|
const fetch = () => {
|
|
@@ -23783,8 +25415,8 @@ function useDeviceWebrtc(trpc, deviceId, pollIntervalMs = 5e3) {
|
|
|
23783
25415
|
deviceId,
|
|
23784
25416
|
pollIntervalMs
|
|
23785
25417
|
]);
|
|
23786
|
-
const [pipelineMetrics, setPipelineMetrics] = (0, react.useState)(null);
|
|
23787
|
-
(0, react.useEffect)(() => {
|
|
25418
|
+
const [pipelineMetrics, setPipelineMetrics] = (0, react$1.useState)(null);
|
|
25419
|
+
(0, react$1.useEffect)(() => {
|
|
23788
25420
|
if (deviceId === null) return;
|
|
23789
25421
|
let cancelled = false;
|
|
23790
25422
|
if (trpc.pipelineOrchestrator) trpc.pipelineOrchestrator.getCameraMetrics.query({ deviceId }).then((m) => {
|
|
@@ -23811,7 +25443,7 @@ function useDeviceWebrtc(trpc, deviceId, pollIntervalMs = 5e3) {
|
|
|
23811
25443
|
droppedFrames: payload.metrics.droppedFrames
|
|
23812
25444
|
});
|
|
23813
25445
|
});
|
|
23814
|
-
const { streams, hasWebrtc } = (0, react.useMemo)(() => {
|
|
25446
|
+
const { streams, hasWebrtc } = (0, react$1.useMemo)(() => {
|
|
23815
25447
|
if (deviceId === null || remoteStreams.length === 0) return {
|
|
23816
25448
|
streams: [],
|
|
23817
25449
|
hasWebrtc: false
|
|
@@ -23833,7 +25465,7 @@ function useDeviceWebrtc(trpc, deviceId, pollIntervalMs = 5e3) {
|
|
|
23833
25465
|
streams,
|
|
23834
25466
|
hasWebrtc,
|
|
23835
25467
|
pipelineMetrics,
|
|
23836
|
-
createSession: (0, react.useCallback)(async (target, hints) => {
|
|
25468
|
+
createSession: (0, react$1.useCallback)(async (target, hints) => {
|
|
23837
25469
|
if (deviceId === null) throw new Error("No device selected");
|
|
23838
25470
|
const res = await trpc.webrtcSession.createSession.mutate({
|
|
23839
25471
|
deviceId,
|
|
@@ -23845,7 +25477,7 @@ function useDeviceWebrtc(trpc, deviceId, pollIntervalMs = 5e3) {
|
|
|
23845
25477
|
sdpOffer: res.sdpOffer
|
|
23846
25478
|
};
|
|
23847
25479
|
}, [trpc, deviceId]),
|
|
23848
|
-
sendAnswer: (0, react.useCallback)(async (sessionId, sdpAnswer) => {
|
|
25480
|
+
sendAnswer: (0, react$1.useCallback)(async (sessionId, sdpAnswer) => {
|
|
23849
25481
|
if (deviceId === null) throw new Error("No device selected");
|
|
23850
25482
|
await trpc.webrtcSession.handleAnswer.mutate({
|
|
23851
25483
|
deviceId,
|
|
@@ -23853,7 +25485,7 @@ function useDeviceWebrtc(trpc, deviceId, pollIntervalMs = 5e3) {
|
|
|
23853
25485
|
sdpAnswer
|
|
23854
25486
|
});
|
|
23855
25487
|
}, [trpc, deviceId]),
|
|
23856
|
-
closeSession: (0, react.useCallback)(async (sessionId) => {
|
|
25488
|
+
closeSession: (0, react$1.useCallback)(async (sessionId) => {
|
|
23857
25489
|
if (deviceId === null) return;
|
|
23858
25490
|
await trpc.webrtcSession.closeSession.mutate({
|
|
23859
25491
|
deviceId,
|
|
@@ -23926,10 +25558,10 @@ function usePTZ(trpc, deviceId, options) {
|
|
|
23926
25558
|
const pulseMs = options?.pulseMs ?? 250;
|
|
23927
25559
|
const enabled = options?.enabled ?? true;
|
|
23928
25560
|
const ptz = useDeviceProxy(trpc, enabled ? deviceId : null)?.ptz;
|
|
23929
|
-
const [presets, setPresets] = (0, react.useState)([]);
|
|
23930
|
-
const [busy, setBusy] = (0, react.useState)(false);
|
|
23931
|
-
const [error, setError] = (0, react.useState)(null);
|
|
23932
|
-
const refreshPresets = (0, react.useCallback)(async () => {
|
|
25561
|
+
const [presets, setPresets] = (0, react$1.useState)([]);
|
|
25562
|
+
const [busy, setBusy] = (0, react$1.useState)(false);
|
|
25563
|
+
const [error, setError] = (0, react$1.useState)(null);
|
|
25564
|
+
const refreshPresets = (0, react$1.useCallback)(async () => {
|
|
23933
25565
|
if (!enabled || !ptz) return;
|
|
23934
25566
|
try {
|
|
23935
25567
|
setPresets(await ptz.getPresets({}));
|
|
@@ -23939,10 +25571,10 @@ function usePTZ(trpc, deviceId, options) {
|
|
|
23939
25571
|
setError(msg);
|
|
23940
25572
|
}
|
|
23941
25573
|
}, [ptz, enabled]);
|
|
23942
|
-
(0, react.useEffect)(() => {
|
|
25574
|
+
(0, react$1.useEffect)(() => {
|
|
23943
25575
|
refreshPresets();
|
|
23944
25576
|
}, [refreshPresets]);
|
|
23945
|
-
const wrap = (0, react.useCallback)(async (fn) => {
|
|
25577
|
+
const wrap = (0, react$1.useCallback)(async (fn) => {
|
|
23946
25578
|
if (!enabled || !ptz) return void 0;
|
|
23947
25579
|
setError(null);
|
|
23948
25580
|
setBusy(true);
|
|
@@ -23956,7 +25588,7 @@ function usePTZ(trpc, deviceId, options) {
|
|
|
23956
25588
|
}
|
|
23957
25589
|
}, [enabled, ptz]);
|
|
23958
25590
|
return {
|
|
23959
|
-
move: (0, react.useCallback)(async (direction, speed) => {
|
|
25591
|
+
move: (0, react$1.useCallback)(async (direction, speed) => {
|
|
23960
25592
|
if (!ptz) return;
|
|
23961
25593
|
const v = DIRECTION_VECTORS[direction];
|
|
23962
25594
|
const s = speed ?? defaultSpeed;
|
|
@@ -23975,7 +25607,7 @@ function usePTZ(trpc, deviceId, options) {
|
|
|
23975
25607
|
pulseMs,
|
|
23976
25608
|
wrap
|
|
23977
25609
|
]),
|
|
23978
|
-
startContinuous: (0, react.useCallback)(async (direction, speed) => {
|
|
25610
|
+
startContinuous: (0, react$1.useCallback)(async (direction, speed) => {
|
|
23979
25611
|
if (!ptz) return;
|
|
23980
25612
|
const v = DIRECTION_VECTORS[direction];
|
|
23981
25613
|
const s = speed ?? defaultSpeed;
|
|
@@ -23989,11 +25621,11 @@ function usePTZ(trpc, deviceId, options) {
|
|
|
23989
25621
|
defaultSpeed,
|
|
23990
25622
|
wrap
|
|
23991
25623
|
]),
|
|
23992
|
-
stopContinuous: (0, react.useCallback)(async () => {
|
|
25624
|
+
stopContinuous: (0, react$1.useCallback)(async () => {
|
|
23993
25625
|
if (!ptz) return;
|
|
23994
25626
|
await wrap(() => ptz.stop({}));
|
|
23995
25627
|
}, [ptz, wrap]),
|
|
23996
|
-
zoom: (0, react.useCallback)(async (direction, speed) => {
|
|
25628
|
+
zoom: (0, react$1.useCallback)(async (direction, speed) => {
|
|
23997
25629
|
if (!ptz) return;
|
|
23998
25630
|
const z = direction === "in" ? 1 : -1;
|
|
23999
25631
|
const s = speed ?? defaultSpeed;
|
|
@@ -24011,11 +25643,11 @@ function usePTZ(trpc, deviceId, options) {
|
|
|
24011
25643
|
pulseMs,
|
|
24012
25644
|
wrap
|
|
24013
25645
|
]),
|
|
24014
|
-
goHome: (0, react.useCallback)(async () => {
|
|
25646
|
+
goHome: (0, react$1.useCallback)(async () => {
|
|
24015
25647
|
if (!ptz) return;
|
|
24016
25648
|
await wrap(() => ptz.goHome({}));
|
|
24017
25649
|
}, [ptz, wrap]),
|
|
24018
|
-
goToPreset: (0, react.useCallback)(async (presetId) => {
|
|
25650
|
+
goToPreset: (0, react$1.useCallback)(async (presetId) => {
|
|
24019
25651
|
if (!ptz) return;
|
|
24020
25652
|
await wrap(() => ptz.goToPreset({ presetId }));
|
|
24021
25653
|
}, [ptz, wrap]),
|
|
@@ -24042,8 +25674,8 @@ function useDoorbellEvents(options) {
|
|
|
24042
25674
|
const deviceId = options?.deviceId ?? null;
|
|
24043
25675
|
const historyLimit = options?.historyLimit ?? 20;
|
|
24044
25676
|
const event = useEventStreamLatest("doorbell.onPressed", deviceId !== null ? (data) => data.deviceId === deviceId : void 0);
|
|
24045
|
-
const [history, setHistory] = (0, react.useState)([]);
|
|
24046
|
-
(0, react.useEffect)(() => {
|
|
25677
|
+
const [history, setHistory] = (0, react$1.useState)([]);
|
|
25678
|
+
(0, react$1.useEffect)(() => {
|
|
24047
25679
|
if (!event) return;
|
|
24048
25680
|
setHistory((prev) => {
|
|
24049
25681
|
if (prev.length > 0 && prev[0].deviceId === event.deviceId && prev[0].timestamp === event.timestamp) return prev;
|
|
@@ -24079,9 +25711,9 @@ function useDoorbellEvents(options) {
|
|
|
24079
25711
|
*/
|
|
24080
25712
|
function useDevices(filters) {
|
|
24081
25713
|
const system = useSystem();
|
|
24082
|
-
const filtersKey = (0, react.useMemo)(() => filters ? JSON.stringify(filters) : "", [filters]);
|
|
24083
|
-
const [devices, setDevices] = (0, react.useState)(() => system.listDevices(filters));
|
|
24084
|
-
(0, react.useEffect)(() => {
|
|
25714
|
+
const filtersKey = (0, react$1.useMemo)(() => filters ? JSON.stringify(filters) : "", [filters]);
|
|
25715
|
+
const [devices, setDevices] = (0, react$1.useState)(() => system.listDevices(filters));
|
|
25716
|
+
(0, react$1.useEffect)(() => {
|
|
24085
25717
|
const refresh = () => {
|
|
24086
25718
|
setDevices(system.listDevices(filters));
|
|
24087
25719
|
};
|
|
@@ -24114,8 +25746,8 @@ function useDevices(filters) {
|
|
|
24114
25746
|
*/
|
|
24115
25747
|
function useDevice(deviceId) {
|
|
24116
25748
|
const system = useSystem();
|
|
24117
|
-
const [device, setDevice] = (0, react.useState)(() => deviceId === null ? null : system.getDevice(deviceId));
|
|
24118
|
-
(0, react.useEffect)(() => {
|
|
25749
|
+
const [device, setDevice] = (0, react$1.useState)(() => deviceId === null ? null : system.getDevice(deviceId));
|
|
25750
|
+
(0, react$1.useEffect)(() => {
|
|
24119
25751
|
if (deviceId === null) {
|
|
24120
25752
|
setDevice(null);
|
|
24121
25753
|
return;
|
|
@@ -24213,15 +25845,15 @@ function useSystemMutation(select, opts) {
|
|
|
24213
25845
|
function useEventInvalidation(queryKey, categories) {
|
|
24214
25846
|
const system = useSystem();
|
|
24215
25847
|
const queryClient = (0, _tanstack_react_query.useQueryClient)();
|
|
24216
|
-
const [tick, setTick] = (0, react.useState)(system.connectionVersion);
|
|
24217
|
-
(0, react.useEffect)(() => {
|
|
25848
|
+
const [tick, setTick] = (0, react$1.useState)(system.connectionVersion);
|
|
25849
|
+
(0, react$1.useEffect)(() => {
|
|
24218
25850
|
return system.subscribeConnectionEvents((state, version) => {
|
|
24219
25851
|
if (state === "connected") setTick(version);
|
|
24220
25852
|
});
|
|
24221
25853
|
}, [system]);
|
|
24222
25854
|
const key = categories.join("|");
|
|
24223
25855
|
const keyJson = JSON.stringify(queryKey);
|
|
24224
|
-
(0, react.useEffect)(() => {
|
|
25856
|
+
(0, react$1.useEffect)(() => {
|
|
24225
25857
|
const subs = [];
|
|
24226
25858
|
const refresh = () => {
|
|
24227
25859
|
const raw = JSON.parse(keyJson);
|
|
@@ -24276,6 +25908,7 @@ exports.ConfigFormField = FormField;
|
|
|
24276
25908
|
exports.ConfigSchemaField = ConfigSchemaField;
|
|
24277
25909
|
exports.ConfirmActionButton = ConfirmActionButton;
|
|
24278
25910
|
exports.ConfirmDialogProvider = ConfirmDialogProvider;
|
|
25911
|
+
exports.CopyButton = CopyButton;
|
|
24279
25912
|
exports.CustomFieldRenderersProvider = CustomFieldRenderersProvider;
|
|
24280
25913
|
exports.DEFAULT_COLOR = DEFAULT_COLOR;
|
|
24281
25914
|
exports.DataTable = DataTable;
|
|
@@ -24286,6 +25919,7 @@ exports.DevShell = DevShell;
|
|
|
24286
25919
|
exports.DeviceActivityPanel = DeviceActivityPanel;
|
|
24287
25920
|
exports.DeviceCard = DeviceCard;
|
|
24288
25921
|
exports.DeviceContextProvider = DeviceContextProvider;
|
|
25922
|
+
exports.DeviceExportPanel = DeviceExportPanel;
|
|
24289
25923
|
exports.DeviceGrid = DeviceGrid;
|
|
24290
25924
|
exports.DeviceItem = DeviceItem;
|
|
24291
25925
|
exports.DeviceList = DeviceList;
|
|
@@ -24303,6 +25937,7 @@ exports.DropdownContent = DropdownContent;
|
|
|
24303
25937
|
exports.DropdownItem = DropdownItem;
|
|
24304
25938
|
exports.DropdownTrigger = DropdownTrigger;
|
|
24305
25939
|
exports.EmptyState = EmptyState;
|
|
25940
|
+
exports.ErrorBox = ErrorBox;
|
|
24306
25941
|
exports.EventStream = EventStream;
|
|
24307
25942
|
exports.FilterBar = FilterBar;
|
|
24308
25943
|
exports.FloatingEventStream = FloatingEventStream;
|
|
@@ -24340,6 +25975,7 @@ exports.Popover = Popover;
|
|
|
24340
25975
|
exports.PopoverContent = PopoverContent;
|
|
24341
25976
|
exports.PopoverTrigger = PopoverTrigger;
|
|
24342
25977
|
exports.ProviderBadge = ProviderBadge;
|
|
25978
|
+
exports.QrCode = QrCode;
|
|
24343
25979
|
exports.ResponseLog = ResponseLog;
|
|
24344
25980
|
exports.SECTION_BODY = SECTION_BODY;
|
|
24345
25981
|
exports.SECTION_CARD = SECTION_CARD;
|
|
@@ -24414,12 +26050,15 @@ exports.useAddonsCustom = useAddonsCustom;
|
|
|
24414
26050
|
exports.useAddonsForceRefresh = useAddonsForceRefresh;
|
|
24415
26051
|
exports.useAddonsGetAddonAutoUpdate = useAddonsGetAddonAutoUpdate;
|
|
24416
26052
|
exports.useAddonsGetAutoUpdateSettings = useAddonsGetAutoUpdateSettings;
|
|
26053
|
+
exports.useAddonsGetLastRestart = useAddonsGetLastRestart;
|
|
24417
26054
|
exports.useAddonsGetLogs = useAddonsGetLogs;
|
|
24418
26055
|
exports.useAddonsGetVersions = useAddonsGetVersions;
|
|
24419
26056
|
exports.useAddonsInstallFromWorkspace = useAddonsInstallFromWorkspace;
|
|
24420
26057
|
exports.useAddonsInstallPackage = useAddonsInstallPackage;
|
|
24421
26058
|
exports.useAddonsIsWorkspaceAvailable = useAddonsIsWorkspaceAvailable;
|
|
24422
26059
|
exports.useAddonsList = useAddonsList;
|
|
26060
|
+
exports.useAddonsListCapabilityProviders = useAddonsListCapabilityProviders;
|
|
26061
|
+
exports.useAddonsListFrameworkPackages = useAddonsListFrameworkPackages;
|
|
24423
26062
|
exports.useAddonsListPackages = useAddonsListPackages;
|
|
24424
26063
|
exports.useAddonsListUpdates = useAddonsListUpdates;
|
|
24425
26064
|
exports.useAddonsListWorkspacePackages = useAddonsListWorkspacePackages;
|
|
@@ -24433,6 +26072,7 @@ exports.useAddonsSearchAvailable = useAddonsSearchAvailable;
|
|
|
24433
26072
|
exports.useAddonsSetAddonAutoUpdate = useAddonsSetAddonAutoUpdate;
|
|
24434
26073
|
exports.useAddonsSetAutoUpdateSettings = useAddonsSetAutoUpdateSettings;
|
|
24435
26074
|
exports.useAddonsUninstallPackage = useAddonsUninstallPackage;
|
|
26075
|
+
exports.useAddonsUpdateFrameworkPackage = useAddonsUpdateFrameworkPackage;
|
|
24436
26076
|
exports.useAddonsUpdatePackage = useAddonsUpdatePackage;
|
|
24437
26077
|
exports.useAlertsDismiss = useAlertsDismiss;
|
|
24438
26078
|
exports.useAlertsEmit = useAlertsEmit;
|