@camstack/ui-library 0.1.50 → 0.1.52
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 +20 -28
- package/dist/index.cjs +2116 -490
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1657 -32
- 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,16 @@ 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.setCapabilityProviderEnabled.useMutation`. */
|
|
15810
|
+
var useAddonsSetCapabilityProviderEnabled = trpc.addons.setCapabilityProviderEnabled.useMutation;
|
|
15811
|
+
/** Generated alias around `trpc.addons.updateFrameworkPackage.useMutation`. */
|
|
15812
|
+
var useAddonsUpdateFrameworkPackage = trpc.addons.updateFrameworkPackage.useMutation;
|
|
15652
15813
|
/** Generated alias around `trpc.addons.getVersions.useQuery`. */
|
|
15653
15814
|
var useAddonsGetVersions = trpc.addons.getVersions.useQuery;
|
|
15654
15815
|
/** Generated alias around `trpc.addons.restartAddon.useMutation`. */
|
|
@@ -15737,10 +15898,6 @@ var useAudioCodecListActiveSessions = trpc.audioCodec.listActiveSessions.useQuer
|
|
|
15737
15898
|
var useAudioMetricsGetCurrentSnapshot = trpc.audioMetrics.getCurrentSnapshot.useQuery;
|
|
15738
15899
|
/** Generated alias around `trpc.audioMetrics.getHistory.useQuery`. */
|
|
15739
15900
|
var useAudioMetricsGetHistory = trpc.audioMetrics.getHistory.useQuery;
|
|
15740
|
-
/** Generated alias around `trpc.authentication.listProviders.useQuery`. */
|
|
15741
|
-
var useAuthenticationListProviders = trpc.authentication.listProviders.useQuery;
|
|
15742
|
-
/** Generated alias around `trpc.authentication.setProviderEnabled.useMutation`. */
|
|
15743
|
-
var useAuthenticationSetProviderEnabled = trpc.authentication.setProviderEnabled.useMutation;
|
|
15744
15901
|
/** Generated alias around `trpc.backup.listDestinations.useQuery`. */
|
|
15745
15902
|
var useBackupListDestinations = trpc.backup.listDestinations.useQuery;
|
|
15746
15903
|
/** Generated alias around `trpc.backup.trigger.useMutation`. */
|
|
@@ -16033,18 +16190,6 @@ var useMeshNetworkLogout = trpc.meshNetwork.logout.useMutation;
|
|
|
16033
16190
|
var useMeshNetworkListPeers = trpc.meshNetwork.listPeers.useQuery;
|
|
16034
16191
|
/** Generated alias around `trpc.meshNetwork.testConnection.useMutation`. */
|
|
16035
16192
|
var useMeshNetworkTestConnection = trpc.meshNetwork.testConnection.useMutation;
|
|
16036
|
-
/** Generated alias around `trpc.meshOrchestrator.listProviders.useQuery`. */
|
|
16037
|
-
var useMeshOrchestratorListProviders = trpc.meshOrchestrator.listProviders.useQuery;
|
|
16038
|
-
/** Generated alias around `trpc.meshOrchestrator.joinProvider.useMutation`. */
|
|
16039
|
-
var useMeshOrchestratorJoinProvider = trpc.meshOrchestrator.joinProvider.useMutation;
|
|
16040
|
-
/** Generated alias around `trpc.meshOrchestrator.leaveProvider.useMutation`. */
|
|
16041
|
-
var useMeshOrchestratorLeaveProvider = trpc.meshOrchestrator.leaveProvider.useMutation;
|
|
16042
|
-
/** Generated alias around `trpc.meshOrchestrator.startLoginProvider.useMutation`. */
|
|
16043
|
-
var useMeshOrchestratorStartLoginProvider = trpc.meshOrchestrator.startLoginProvider.useMutation;
|
|
16044
|
-
/** Generated alias around `trpc.meshOrchestrator.logoutProvider.useMutation`. */
|
|
16045
|
-
var useMeshOrchestratorLogoutProvider = trpc.meshOrchestrator.logoutProvider.useMutation;
|
|
16046
|
-
/** Generated alias around `trpc.meshOrchestrator.listProviderPeers.useQuery`. */
|
|
16047
|
-
var useMeshOrchestratorListProviderPeers = trpc.meshOrchestrator.listProviderPeers.useQuery;
|
|
16048
16193
|
/** Generated alias around `trpc.metricsProvider.collectSnapshot.useQuery`. */
|
|
16049
16194
|
var useMetricsProviderCollectSnapshot = trpc.metricsProvider.collectSnapshot.useQuery;
|
|
16050
16195
|
/** Generated alias around `trpc.metricsProvider.getCached.useQuery`. */
|
|
@@ -16105,6 +16250,16 @@ var useMqttBrokerStopEmbeddedBroker = trpc.mqttBroker.stopEmbeddedBroker.useMuta
|
|
|
16105
16250
|
var useMqttBrokerGetStatus = trpc.mqttBroker.getStatus.useQuery;
|
|
16106
16251
|
/** Generated alias around `trpc.nativeObjectDetection.getStatus.useQuery`. */
|
|
16107
16252
|
var useNativeObjectDetectionGetStatus = trpc.nativeObjectDetection.getStatus.useQuery;
|
|
16253
|
+
/** Generated alias around `trpc.networkAccess.start.useMutation`. */
|
|
16254
|
+
var useNetworkAccessStart = trpc.networkAccess.start.useMutation;
|
|
16255
|
+
/** Generated alias around `trpc.networkAccess.stop.useMutation`. */
|
|
16256
|
+
var useNetworkAccessStop = trpc.networkAccess.stop.useMutation;
|
|
16257
|
+
/** Generated alias around `trpc.networkAccess.getEndpoint.useQuery`. */
|
|
16258
|
+
var useNetworkAccessGetEndpoint = trpc.networkAccess.getEndpoint.useQuery;
|
|
16259
|
+
/** Generated alias around `trpc.networkAccess.getStatus.useQuery`. */
|
|
16260
|
+
var useNetworkAccessGetStatus = trpc.networkAccess.getStatus.useQuery;
|
|
16261
|
+
/** Generated alias around `trpc.networkAccess.listEndpoints.useQuery`. */
|
|
16262
|
+
var useNetworkAccessListEndpoints = trpc.networkAccess.listEndpoints.useQuery;
|
|
16108
16263
|
/** Generated alias around `trpc.networkQuality.getDeviceStats.useQuery`. */
|
|
16109
16264
|
var useNetworkQualityGetDeviceStats = trpc.networkQuality.getDeviceStats.useQuery;
|
|
16110
16265
|
/** Generated alias around `trpc.networkQuality.getAllStats.useQuery`. */
|
|
@@ -16405,12 +16560,6 @@ var useRecordingEngineGetRetentionConfig = trpc.recordingEngine.getRetentionConf
|
|
|
16405
16560
|
var useRecordingEngineUpdateRetentionConfig = trpc.recordingEngine.updateRetentionConfig.useMutation;
|
|
16406
16561
|
/** Generated alias around `trpc.recordingEngine.getMotionStats.useQuery`. */
|
|
16407
16562
|
var useRecordingEngineGetMotionStats = trpc.recordingEngine.getMotionStats.useQuery;
|
|
16408
|
-
/** Generated alias around `trpc.remoteAccess.listProviders.useQuery`. */
|
|
16409
|
-
var useRemoteAccessListProviders = trpc.remoteAccess.listProviders.useQuery;
|
|
16410
|
-
/** Generated alias around `trpc.remoteAccess.startProvider.useMutation`. */
|
|
16411
|
-
var useRemoteAccessStartProvider = trpc.remoteAccess.startProvider.useMutation;
|
|
16412
|
-
/** Generated alias around `trpc.remoteAccess.stopProvider.useMutation`. */
|
|
16413
|
-
var useRemoteAccessStopProvider = trpc.remoteAccess.stopProvider.useMutation;
|
|
16414
16563
|
/** Generated alias around `trpc.settingsStore.get.useQuery`. */
|
|
16415
16564
|
var useSettingsStoreGet = trpc.settingsStore.get.useQuery;
|
|
16416
16565
|
/** Generated alias around `trpc.settingsStore.set.useMutation`. */
|
|
@@ -16557,12 +16706,6 @@ var useSystemSetRetentionConfig = trpc.system.setRetentionConfig.useMutation;
|
|
|
16557
16706
|
var useSystemForceRetentionCleanup = trpc.system.forceRetentionCleanup.useMutation;
|
|
16558
16707
|
/** Generated alias around `trpc.toast.onToast.useSubscription`. */
|
|
16559
16708
|
var useToastOnToast = trpc.toast.onToast.useSubscription;
|
|
16560
|
-
/** Generated alias around `trpc.turnOrchestrator.listProviders.useQuery`. */
|
|
16561
|
-
var useTurnOrchestratorListProviders = trpc.turnOrchestrator.listProviders.useQuery;
|
|
16562
|
-
/** Generated alias around `trpc.turnOrchestrator.getAllServers.useQuery`. */
|
|
16563
|
-
var useTurnOrchestratorGetAllServers = trpc.turnOrchestrator.getAllServers.useQuery;
|
|
16564
|
-
/** Generated alias around `trpc.turnOrchestrator.setProviderEnabled.useMutation`. */
|
|
16565
|
-
var useTurnOrchestratorSetProviderEnabled = trpc.turnOrchestrator.setProviderEnabled.useMutation;
|
|
16566
16709
|
/** Generated alias around `trpc.turnProvider.getTurnServers.useQuery`. */
|
|
16567
16710
|
var useTurnProviderGetTurnServers = trpc.turnProvider.getTurnServers.useQuery;
|
|
16568
16711
|
/** Generated alias around `trpc.userManagement.listUsers.useQuery`. */
|
|
@@ -16748,7 +16891,7 @@ var BOOT_WINDOW_MS = 3e4;
|
|
|
16748
16891
|
var POLL_INTERVAL_MS = 2e3;
|
|
16749
16892
|
function WidgetRegistryProvider({ children }) {
|
|
16750
16893
|
const queryClient = (0, _tanstack_react_query.useQueryClient)();
|
|
16751
|
-
const mountedAtRef = (0, react.useRef)(Date.now());
|
|
16894
|
+
const mountedAtRef = (0, react$1.useRef)(Date.now());
|
|
16752
16895
|
const { data: rawWidgets } = useAddonWidgetsListWidgets(void 0, {
|
|
16753
16896
|
staleTime: 0,
|
|
16754
16897
|
refetchOnMount: "always",
|
|
@@ -16762,8 +16905,8 @@ function WidgetRegistryProvider({ children }) {
|
|
|
16762
16905
|
useLiveEvent("addon.widget-ready", () => {
|
|
16763
16906
|
queryClient.invalidateQueries({ queryKey: [["addonWidgets", "listWidgets"]] });
|
|
16764
16907
|
});
|
|
16765
|
-
const [resolvedTick, setResolvedTick] = (0, react.useState)(0);
|
|
16766
|
-
(0, react.useEffect)(() => {
|
|
16908
|
+
const [resolvedTick, setResolvedTick] = (0, react$1.useState)(0);
|
|
16909
|
+
(0, react$1.useEffect)(() => {
|
|
16767
16910
|
if (!rawWidgets) return;
|
|
16768
16911
|
let cancelled = false;
|
|
16769
16912
|
const seenRemotes = /* @__PURE__ */ new Set();
|
|
@@ -16787,7 +16930,7 @@ function WidgetRegistryProvider({ children }) {
|
|
|
16787
16930
|
cancelled = true;
|
|
16788
16931
|
};
|
|
16789
16932
|
}, [rawWidgets]);
|
|
16790
|
-
const registry = (0, react.useMemo)(() => {
|
|
16933
|
+
const registry = (0, react$1.useMemo)(() => {
|
|
16791
16934
|
const widgets = rawWidgets ?? [];
|
|
16792
16935
|
const byId = /* @__PURE__ */ new Map();
|
|
16793
16936
|
for (const w of widgets) byId.set(`${w.addonId}/${w.stableId}`, w);
|
|
@@ -16859,7 +17002,7 @@ function useOptionalWidgetRegistry() {
|
|
|
16859
17002
|
return useContextSafe(WidgetRegistryContext);
|
|
16860
17003
|
}
|
|
16861
17004
|
function useContextSafe(ctx) {
|
|
16862
|
-
return (0, react.useContext)(ctx);
|
|
17005
|
+
return (0, react$1.useContext)(ctx);
|
|
16863
17006
|
}
|
|
16864
17007
|
//#endregion
|
|
16865
17008
|
//#region src/composites/widget-slot.tsx
|
|
@@ -16883,7 +17026,7 @@ function WidgetSlot(props) {
|
|
|
16883
17026
|
const { widgetId, host = "device-tab", config, deviceId, integrationId, instanceId, size, columns, rows } = props;
|
|
16884
17027
|
const Component = useWidget(widgetId);
|
|
16885
17028
|
const metadata = useWidgetMetadata(widgetId);
|
|
16886
|
-
const resolvedInstanceId = (0, react.useMemo)(() => instanceId ?? widgetId, [instanceId, widgetId]);
|
|
17029
|
+
const resolvedInstanceId = (0, react$1.useMemo)(() => instanceId ?? widgetId, [instanceId, widgetId]);
|
|
16887
17030
|
if (Component === void 0 && metadata === void 0) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(WidgetMissingError, {
|
|
16888
17031
|
widgetId,
|
|
16889
17032
|
reason: "unknown"
|
|
@@ -16977,9 +17120,9 @@ function TextField({ field, value, onChange, disabled, translationFn }) {
|
|
|
16977
17120
|
});
|
|
16978
17121
|
}
|
|
16979
17122
|
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)(() => {
|
|
17123
|
+
const [local, setLocal] = (0, react$1.useState)(value === void 0 || value === null ? "" : String(value));
|
|
17124
|
+
const focusedRef = (0, react$1.useRef)(false);
|
|
17125
|
+
(0, react$1.useEffect)(() => {
|
|
16983
17126
|
if (focusedRef.current) return;
|
|
16984
17127
|
setLocal(value === void 0 || value === null ? "" : String(value));
|
|
16985
17128
|
}, [value]);
|
|
@@ -17145,7 +17288,7 @@ function MultiSelectField({ field, value, onChange, disabled, translationFn }) {
|
|
|
17145
17288
|
});
|
|
17146
17289
|
}
|
|
17147
17290
|
function PasswordField({ field, value, onChange, disabled, translationFn }) {
|
|
17148
|
-
const [show, setShow] = (0, react.useState)(false);
|
|
17291
|
+
const [show, setShow] = (0, react$1.useState)(false);
|
|
17149
17292
|
const showToggle = field.showToggle !== false;
|
|
17150
17293
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(FieldWrapper, {
|
|
17151
17294
|
label: field.label,
|
|
@@ -17312,9 +17455,9 @@ function SliderField({ field, value, onChange, disabled, translationFn }) {
|
|
|
17312
17455
|
}
|
|
17313
17456
|
function TagsField({ field, value, onChange, disabled, translationFn }) {
|
|
17314
17457
|
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) => {
|
|
17458
|
+
const [input, setInput] = (0, react$1.useState)("");
|
|
17459
|
+
const inputRef = (0, react$1.useRef)(null);
|
|
17460
|
+
const addTag = (0, react$1.useCallback)((tag) => {
|
|
17318
17461
|
const trimmed = tag.trim();
|
|
17319
17462
|
if (!trimmed || tags.includes(trimmed)) return;
|
|
17320
17463
|
if (field.maxTags !== void 0 && tags.length >= field.maxTags) return;
|
|
@@ -17473,12 +17616,12 @@ function ColorField({ field, value, onChange, disabled, translationFn }) {
|
|
|
17473
17616
|
});
|
|
17474
17617
|
}
|
|
17475
17618
|
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);
|
|
17619
|
+
const [localStatus, setLocalStatus] = (0, react$1.useState)("idle");
|
|
17620
|
+
const [localResult, setLocalResult] = (0, react$1.useState)(null);
|
|
17478
17621
|
const probeStatus = externalProbe?.status ?? localStatus;
|
|
17479
17622
|
const probeResult = externalProbe?.result ?? localResult;
|
|
17480
17623
|
const hasTestHandler = !!onTestField || !!onAction;
|
|
17481
|
-
const handleTest = (0, react.useCallback)(async () => {
|
|
17624
|
+
const handleTest = (0, react$1.useCallback)(async () => {
|
|
17482
17625
|
if (!hasTestHandler) return;
|
|
17483
17626
|
setLocalStatus("probing");
|
|
17484
17627
|
setLocalResult(null);
|
|
@@ -17557,7 +17700,7 @@ function ProbeField({ field, value, onChange, disabled, translationFn, onTestFie
|
|
|
17557
17700
|
});
|
|
17558
17701
|
}
|
|
17559
17702
|
function GroupField({ field, values, onChange, disabled, translationFn, onTestField }) {
|
|
17560
|
-
const [collapsed, setCollapsed] = (0, react.useState)(field.defaultCollapsed ?? false);
|
|
17703
|
+
const [collapsed, setCollapsed] = (0, react$1.useState)(field.defaultCollapsed ?? false);
|
|
17561
17704
|
const isAccordion = field.style === "accordion";
|
|
17562
17705
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
17563
17706
|
className: field.span === 2 ? "col-span-2" : field.span === 3 ? "col-span-3" : field.span === 4 ? "col-span-4" : "col-span-1",
|
|
@@ -17588,7 +17731,7 @@ function GroupField({ field, values, onChange, disabled, translationFn, onTestFi
|
|
|
17588
17731
|
});
|
|
17589
17732
|
}
|
|
17590
17733
|
function SubTabsField({ field, values, onChange, disabled, translationFn, onTestField, onAction }) {
|
|
17591
|
-
const [active, setActive] = (0, react.useState)(field.tabs[0]?.id ?? "");
|
|
17734
|
+
const [active, setActive] = (0, react$1.useState)(field.tabs[0]?.id ?? "");
|
|
17592
17735
|
const colSpanClass = field.span === 2 ? "col-span-2" : field.span === 3 ? "col-span-3" : field.span === 4 ? "col-span-4" : "col-span-1";
|
|
17593
17736
|
if (field.tabs.length === 0) return null;
|
|
17594
17737
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
@@ -17929,7 +18072,7 @@ function EditableArrayField({ field, value, onChange, disabled, translationFn, o
|
|
|
17929
18072
|
});
|
|
17930
18073
|
}
|
|
17931
18074
|
function ButtonField({ field, disabled, onAction }) {
|
|
17932
|
-
const [loading, setLoading] = (0, react.useState)(false);
|
|
18075
|
+
const [loading, setLoading] = (0, react$1.useState)(false);
|
|
17933
18076
|
const confirm = useConfirm();
|
|
17934
18077
|
const handleClick = async () => {
|
|
17935
18078
|
if (field.confirmMessage) {
|
|
@@ -17975,12 +18118,12 @@ function resolveActionParams(field, values) {
|
|
|
17975
18118
|
return params;
|
|
17976
18119
|
}
|
|
17977
18120
|
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);
|
|
18121
|
+
const [loading, setLoading] = (0, react$1.useState)(false);
|
|
18122
|
+
const [error, setError] = (0, react$1.useState)(null);
|
|
18123
|
+
const [options, setOptions] = (0, react$1.useState)(null);
|
|
17981
18124
|
const params = resolveActionParams(field, values);
|
|
17982
18125
|
const missingParam = Object.keys(field.paramsFromForm ?? {}).some((k) => params[k] === void 0);
|
|
17983
|
-
(0, react.useEffect)(() => {
|
|
18126
|
+
(0, react$1.useEffect)(() => {
|
|
17984
18127
|
if (!onAction || missingParam) {
|
|
17985
18128
|
setOptions(null);
|
|
17986
18129
|
setError(null);
|
|
@@ -18066,8 +18209,8 @@ function AddonActionSelectField({ field, value, values, onChange, disabled, onAc
|
|
|
18066
18209
|
});
|
|
18067
18210
|
}
|
|
18068
18211
|
function AddonActionButtonField({ field, values, disabled, onAction }) {
|
|
18069
|
-
const [loading, setLoading] = (0, react.useState)(false);
|
|
18070
|
-
const [status, setStatus] = (0, react.useState)(null);
|
|
18212
|
+
const [loading, setLoading] = (0, react$1.useState)(false);
|
|
18213
|
+
const [status, setStatus] = (0, react$1.useState)(null);
|
|
18071
18214
|
const confirm = useConfirm();
|
|
18072
18215
|
const handleClick = async () => {
|
|
18073
18216
|
if (field.confirmMessage) {
|
|
@@ -18212,7 +18355,7 @@ function InlineIconGlyph({ name }) {
|
|
|
18212
18355
|
*/
|
|
18213
18356
|
function InlineActionIcon({ action, fieldKey, value, onAction }) {
|
|
18214
18357
|
const confirm = useConfirm();
|
|
18215
|
-
const [loading, setLoading] = (0, react.useState)(false);
|
|
18358
|
+
const [loading, setLoading] = (0, react$1.useState)(false);
|
|
18216
18359
|
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
18360
|
const handleClick = async () => {
|
|
18218
18361
|
if (action.confirmMessage) {
|
|
@@ -18560,7 +18703,7 @@ function resolveLabel(value, t) {
|
|
|
18560
18703
|
return value;
|
|
18561
18704
|
}
|
|
18562
18705
|
function SectionCard({ section, values, onChange, disabled, translationFn, onTestField, probeResults }) {
|
|
18563
|
-
const [collapsed, setCollapsed] = (0, react.useState)(section.defaultCollapsed ?? false);
|
|
18706
|
+
const [collapsed, setCollapsed] = (0, react$1.useState)(section.defaultCollapsed ?? false);
|
|
18564
18707
|
const isAccordion = section.style === "accordion";
|
|
18565
18708
|
const columns = section.columns ?? 2;
|
|
18566
18709
|
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 +18808,14 @@ function stripValues(schema) {
|
|
|
18665
18808
|
}
|
|
18666
18809
|
function AddonGlobalSettingsForm({ trpc, addonId, nodeId, title, disabled, onAfterChange, refreshToken, collapsible, defaultOpen, mode, onOverrideChange }) {
|
|
18667
18810
|
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)(() => {
|
|
18811
|
+
const [hydrated, setHydrated] = (0, react$1.useState)(null);
|
|
18812
|
+
const [loading, setLoading] = (0, react$1.useState)(true);
|
|
18813
|
+
const [error, setError] = (0, react$1.useState)(null);
|
|
18814
|
+
const [saving, setSaving] = (0, react$1.useState)(false);
|
|
18815
|
+
const [open, setOpen] = (0, react$1.useState)(defaultOpen ?? false);
|
|
18816
|
+
const [overrideValues, setOverrideValues] = (0, react$1.useState)({});
|
|
18817
|
+
const [baseValues, setBaseValues] = (0, react$1.useState)(null);
|
|
18818
|
+
(0, react$1.useEffect)(() => {
|
|
18676
18819
|
setBaseValues(null);
|
|
18677
18820
|
setOverrideValues({});
|
|
18678
18821
|
}, [
|
|
@@ -18682,7 +18825,7 @@ function AddonGlobalSettingsForm({ trpc, addonId, nodeId, title, disabled, onAft
|
|
|
18682
18825
|
refreshToken,
|
|
18683
18826
|
effectiveMode
|
|
18684
18827
|
]);
|
|
18685
|
-
(0, react.useEffect)(() => {
|
|
18828
|
+
(0, react$1.useEffect)(() => {
|
|
18686
18829
|
let cancelled = false;
|
|
18687
18830
|
setLoading(true);
|
|
18688
18831
|
setError(null);
|
|
@@ -18712,8 +18855,8 @@ function AddonGlobalSettingsForm({ trpc, addonId, nodeId, title, disabled, onAft
|
|
|
18712
18855
|
effectiveMode,
|
|
18713
18856
|
JSON.stringify(overrideValues)
|
|
18714
18857
|
]);
|
|
18715
|
-
const values = (0, react.useMemo)(() => extractValues(hydrated), [hydrated]);
|
|
18716
|
-
const schemaNoValues = (0, react.useMemo)(() => hydrated ? stripValues(hydrated) : null, [hydrated]);
|
|
18858
|
+
const values = (0, react$1.useMemo)(() => extractValues(hydrated), [hydrated]);
|
|
18859
|
+
const schemaNoValues = (0, react$1.useMemo)(() => hydrated ? stripValues(hydrated) : null, [hydrated]);
|
|
18717
18860
|
const handleChange = async (nextValues) => {
|
|
18718
18861
|
if (effectiveMode === "override") {
|
|
18719
18862
|
const ref = baseValues ?? values;
|
|
@@ -18960,30 +19103,30 @@ function computeClientHints(container) {
|
|
|
18960
19103
|
var RECONNECT_DELAY_MS = 3e3;
|
|
18961
19104
|
var MAX_RECONNECT_ATTEMPTS = 5;
|
|
18962
19105
|
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);
|
|
19106
|
+
const videoRef = (0, react$1.useRef)(null);
|
|
19107
|
+
const containerRef = (0, react$1.useRef)(null);
|
|
19108
|
+
const pcRef = (0, react$1.useRef)(null);
|
|
18966
19109
|
/** All session IDs created during this player's lifetime — closed on cleanup */
|
|
18967
|
-
const sessionIdsRef = (0, react.useRef)(/* @__PURE__ */ new Set());
|
|
19110
|
+
const sessionIdsRef = (0, react$1.useRef)(/* @__PURE__ */ new Set());
|
|
18968
19111
|
/** 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);
|
|
19112
|
+
const connectAbortRef = (0, react$1.useRef)(null);
|
|
19113
|
+
const reconnectTimerRef = (0, react$1.useRef)(null);
|
|
19114
|
+
const reconnectAttemptsRef = (0, react$1.useRef)(0);
|
|
19115
|
+
const mountedRef = (0, react$1.useRef)(true);
|
|
19116
|
+
const [state, setState] = (0, react$1.useState)("idle");
|
|
19117
|
+
const [errorMessage, setErrorMessage] = (0, react$1.useState)("");
|
|
19118
|
+
const [isMuted, setIsMuted] = (0, react$1.useState)(initialMuted);
|
|
19119
|
+
const [isFullscreen, setIsFullscreen] = (0, react$1.useState)(false);
|
|
19120
|
+
const [showToolbar, setShowToolbar] = (0, react$1.useState)(false);
|
|
19121
|
+
const hideTimerRef = (0, react$1.useRef)(null);
|
|
19122
|
+
const serverOfferModeRef = (0, react$1.useRef)(false);
|
|
18980
19123
|
if (sendAnswer || createSession) serverOfferModeRef.current = true;
|
|
18981
19124
|
const useServerOffer = serverOfferModeRef.current;
|
|
18982
|
-
const updateState = (0, react.useCallback)((s) => {
|
|
19125
|
+
const updateState = (0, react$1.useCallback)((s) => {
|
|
18983
19126
|
setState(s);
|
|
18984
19127
|
onStateChange?.(s);
|
|
18985
19128
|
}, [onStateChange]);
|
|
18986
|
-
const cleanup = (0, react.useCallback)(() => {
|
|
19129
|
+
const cleanup = (0, react$1.useCallback)(() => {
|
|
18987
19130
|
connectAbortRef.current?.abort();
|
|
18988
19131
|
connectAbortRef.current = null;
|
|
18989
19132
|
if (reconnectTimerRef.current) {
|
|
@@ -19000,7 +19143,7 @@ function CameraStreamPlayer({ serverUrl, streamKey, label, autoPlay = true, mute
|
|
|
19000
19143
|
}
|
|
19001
19144
|
if (videoRef.current) videoRef.current.srcObject = null;
|
|
19002
19145
|
}, [closeSession]);
|
|
19003
|
-
const connectServerOffer = (0, react.useCallback)(async () => {
|
|
19146
|
+
const connectServerOffer = (0, react$1.useCallback)(async () => {
|
|
19004
19147
|
if (!mountedRef.current || !createSession || !sendAnswer) return;
|
|
19005
19148
|
cleanup();
|
|
19006
19149
|
updateState("connecting");
|
|
@@ -19091,7 +19234,7 @@ function CameraStreamPlayer({ serverUrl, streamKey, label, autoPlay = true, mute
|
|
|
19091
19234
|
onError,
|
|
19092
19235
|
hintsOverride
|
|
19093
19236
|
]);
|
|
19094
|
-
const connectWhep = (0, react.useCallback)(async () => {
|
|
19237
|
+
const connectWhep = (0, react$1.useCallback)(async () => {
|
|
19095
19238
|
if (!mountedRef.current) return;
|
|
19096
19239
|
cleanup();
|
|
19097
19240
|
updateState("connecting");
|
|
@@ -19152,9 +19295,9 @@ function CameraStreamPlayer({ serverUrl, streamKey, label, autoPlay = true, mute
|
|
|
19152
19295
|
onError
|
|
19153
19296
|
]);
|
|
19154
19297
|
const connect = useServerOffer ? connectServerOffer : connectWhep;
|
|
19155
|
-
const connectRef = (0, react.useRef)(() => {});
|
|
19298
|
+
const connectRef = (0, react$1.useRef)(() => {});
|
|
19156
19299
|
connectRef.current = connect;
|
|
19157
|
-
const scheduleReconnect = (0, react.useCallback)(() => {
|
|
19300
|
+
const scheduleReconnect = (0, react$1.useCallback)(() => {
|
|
19158
19301
|
if (!mountedRef.current) return;
|
|
19159
19302
|
if (reconnectAttemptsRef.current >= MAX_RECONNECT_ATTEMPTS) return;
|
|
19160
19303
|
reconnectAttemptsRef.current += 1;
|
|
@@ -19162,7 +19305,7 @@ function CameraStreamPlayer({ serverUrl, streamKey, label, autoPlay = true, mute
|
|
|
19162
19305
|
if (mountedRef.current) connectRef.current();
|
|
19163
19306
|
}, RECONNECT_DELAY_MS);
|
|
19164
19307
|
}, []);
|
|
19165
|
-
(0, react.useEffect)(() => {
|
|
19308
|
+
(0, react$1.useEffect)(() => {
|
|
19166
19309
|
mountedRef.current = true;
|
|
19167
19310
|
reconnectAttemptsRef.current = 0;
|
|
19168
19311
|
if (autoPlay) connect();
|
|
@@ -19171,8 +19314,8 @@ function CameraStreamPlayer({ serverUrl, streamKey, label, autoPlay = true, mute
|
|
|
19171
19314
|
cleanup();
|
|
19172
19315
|
};
|
|
19173
19316
|
}, [serverUrl, streamKey]);
|
|
19174
|
-
const hasSignaledRef = (0, react.useRef)(false);
|
|
19175
|
-
(0, react.useEffect)(() => {
|
|
19317
|
+
const hasSignaledRef = (0, react$1.useRef)(false);
|
|
19318
|
+
(0, react$1.useEffect)(() => {
|
|
19176
19319
|
if (!autoPlay || !useServerOffer) return;
|
|
19177
19320
|
if (!createSession || !sendAnswer) return;
|
|
19178
19321
|
if (hasSignaledRef.current) return;
|
|
@@ -19218,7 +19361,7 @@ function CameraStreamPlayer({ serverUrl, streamKey, label, autoPlay = true, mute
|
|
|
19218
19361
|
link.href = canvas.toDataURL("image/jpeg", .92);
|
|
19219
19362
|
link.click();
|
|
19220
19363
|
};
|
|
19221
|
-
(0, react.useEffect)(() => {
|
|
19364
|
+
(0, react$1.useEffect)(() => {
|
|
19222
19365
|
const handler = () => setIsFullscreen(!!document.fullscreenElement);
|
|
19223
19366
|
document.addEventListener("fullscreenchange", handler);
|
|
19224
19367
|
return () => document.removeEventListener("fullscreenchange", handler);
|
|
@@ -19442,16 +19585,16 @@ async function waitForIceGathering(pc) {
|
|
|
19442
19585
|
var PlayerOverlaysStateContext = createSharedContext("camstack:player-overlays-state", null);
|
|
19443
19586
|
var PlayerOverlaysActionsContext = createSharedContext("camstack:player-overlays-actions", null);
|
|
19444
19587
|
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) => {
|
|
19588
|
+
const [layers, setLayers] = (0, react$1.useState)(() => /* @__PURE__ */ new Map());
|
|
19589
|
+
const [buttons, setButtons] = (0, react$1.useState)(() => /* @__PURE__ */ new Map());
|
|
19590
|
+
const setLayer = (0, react$1.useCallback)((layer) => {
|
|
19448
19591
|
setLayers((prev) => {
|
|
19449
19592
|
const next = new Map(prev);
|
|
19450
19593
|
next.set(layer.id, layer);
|
|
19451
19594
|
return next;
|
|
19452
19595
|
});
|
|
19453
19596
|
}, []);
|
|
19454
|
-
const removeLayer = (0, react.useCallback)((id) => {
|
|
19597
|
+
const removeLayer = (0, react$1.useCallback)((id) => {
|
|
19455
19598
|
setLayers((prev) => {
|
|
19456
19599
|
if (!prev.has(id)) return prev;
|
|
19457
19600
|
const next = new Map(prev);
|
|
@@ -19459,14 +19602,14 @@ function PlayerOverlaysProvider({ children }) {
|
|
|
19459
19602
|
return next;
|
|
19460
19603
|
});
|
|
19461
19604
|
}, []);
|
|
19462
|
-
const setButton = (0, react.useCallback)((button) => {
|
|
19605
|
+
const setButton = (0, react$1.useCallback)((button) => {
|
|
19463
19606
|
setButtons((prev) => {
|
|
19464
19607
|
const next = new Map(prev);
|
|
19465
19608
|
next.set(button.id, button);
|
|
19466
19609
|
return next;
|
|
19467
19610
|
});
|
|
19468
19611
|
}, []);
|
|
19469
|
-
const removeButton = (0, react.useCallback)((id) => {
|
|
19612
|
+
const removeButton = (0, react$1.useCallback)((id) => {
|
|
19470
19613
|
setButtons((prev) => {
|
|
19471
19614
|
if (!prev.has(id)) return prev;
|
|
19472
19615
|
const next = new Map(prev);
|
|
@@ -19474,11 +19617,11 @@ function PlayerOverlaysProvider({ children }) {
|
|
|
19474
19617
|
return next;
|
|
19475
19618
|
});
|
|
19476
19619
|
}, []);
|
|
19477
|
-
const stateValue = (0, react.useMemo)(() => ({
|
|
19620
|
+
const stateValue = (0, react$1.useMemo)(() => ({
|
|
19478
19621
|
layers,
|
|
19479
19622
|
buttons
|
|
19480
19623
|
}), [layers, buttons]);
|
|
19481
|
-
const actionsValue = (0, react.useMemo)(() => ({
|
|
19624
|
+
const actionsValue = (0, react$1.useMemo)(() => ({
|
|
19482
19625
|
setLayer,
|
|
19483
19626
|
removeLayer,
|
|
19484
19627
|
setButton,
|
|
@@ -19501,16 +19644,16 @@ function PlayerOverlaysProvider({ children }) {
|
|
|
19501
19644
|
* by insertion order of the underlying Map). Returns `[]` outside a
|
|
19502
19645
|
* provider. */
|
|
19503
19646
|
function usePlayerOverlayLayers() {
|
|
19504
|
-
const state = (0, react.useContext)(PlayerOverlaysStateContext);
|
|
19505
|
-
return (0, react.useMemo)(() => {
|
|
19647
|
+
const state = (0, react$1.useContext)(PlayerOverlaysStateContext);
|
|
19648
|
+
return (0, react$1.useMemo)(() => {
|
|
19506
19649
|
if (!state) return [];
|
|
19507
19650
|
return [...state.layers.values()].sort((a, b) => a.order - b.order);
|
|
19508
19651
|
}, [state]);
|
|
19509
19652
|
}
|
|
19510
19653
|
/** Snapshot of registered toolbar buttons, ordered by `order` (asc). */
|
|
19511
19654
|
function usePlayerToolbarButtons() {
|
|
19512
|
-
const state = (0, react.useContext)(PlayerOverlaysStateContext);
|
|
19513
|
-
return (0, react.useMemo)(() => {
|
|
19655
|
+
const state = (0, react$1.useContext)(PlayerOverlaysStateContext);
|
|
19656
|
+
return (0, react$1.useMemo)(() => {
|
|
19514
19657
|
if (!state) return [];
|
|
19515
19658
|
return [...state.buttons.values()].sort((a, b) => a.order - b.order);
|
|
19516
19659
|
}, [state]);
|
|
@@ -19527,8 +19670,8 @@ function usePlayerToolbarButtons() {
|
|
|
19527
19670
|
* effects depend on referential equality of the spec object.
|
|
19528
19671
|
*/
|
|
19529
19672
|
function usePlayerOverlayLayer(spec) {
|
|
19530
|
-
const actions = (0, react.useContext)(PlayerOverlaysActionsContext);
|
|
19531
|
-
(0, react.useEffect)(() => {
|
|
19673
|
+
const actions = (0, react$1.useContext)(PlayerOverlaysActionsContext);
|
|
19674
|
+
(0, react$1.useEffect)(() => {
|
|
19532
19675
|
if (!actions || !spec) return void 0;
|
|
19533
19676
|
actions.setLayer(spec);
|
|
19534
19677
|
return () => actions.removeLayer(spec.id);
|
|
@@ -19536,8 +19679,8 @@ function usePlayerOverlayLayer(spec) {
|
|
|
19536
19679
|
}
|
|
19537
19680
|
/** Same shape as `usePlayerOverlayLayer`, scoped to toolbar buttons. */
|
|
19538
19681
|
function usePlayerToolbarButton(spec) {
|
|
19539
|
-
const actions = (0, react.useContext)(PlayerOverlaysActionsContext);
|
|
19540
|
-
(0, react.useEffect)(() => {
|
|
19682
|
+
const actions = (0, react$1.useContext)(PlayerOverlaysActionsContext);
|
|
19683
|
+
(0, react$1.useEffect)(() => {
|
|
19541
19684
|
if (!actions || !spec) return void 0;
|
|
19542
19685
|
actions.setButton(spec);
|
|
19543
19686
|
return () => actions.removeButton(spec.id);
|
|
@@ -19706,13 +19849,13 @@ function ImageOffIcon({ className }) {
|
|
|
19706
19849
|
}
|
|
19707
19850
|
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
19851
|
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)(() => {
|
|
19852
|
+
const [isPlaying, setIsPlaying] = (0, react$1.useState)(autoPlay);
|
|
19853
|
+
const [showDetections, setShowDetections] = (0, react$1.useState)(defaultShowDetections);
|
|
19854
|
+
const [showMotion, setShowMotion] = (0, react$1.useState)(defaultShowMotion);
|
|
19855
|
+
const [internalStreamId, setInternalStreamId] = (0, react$1.useState)(null);
|
|
19856
|
+
const [menuOpen, setMenuOpen] = (0, react$1.useState)(false);
|
|
19857
|
+
const menuRef = (0, react$1.useRef)(null);
|
|
19858
|
+
(0, react$1.useEffect)(() => {
|
|
19716
19859
|
if (!menuOpen) return;
|
|
19717
19860
|
function onClick(e) {
|
|
19718
19861
|
if (menuRef.current && !menuRef.current.contains(e.target)) setMenuOpen(false);
|
|
@@ -19735,7 +19878,7 @@ function StreamPanel({ serverUrl, createSession, sendAnswer, closeSession, strea
|
|
|
19735
19878
|
setTimeout(() => setIsPlaying(true), 50);
|
|
19736
19879
|
}
|
|
19737
19880
|
};
|
|
19738
|
-
const playerCreateSession = (0, react.useMemo)(() => {
|
|
19881
|
+
const playerCreateSession = (0, react$1.useMemo)(() => {
|
|
19739
19882
|
const target = selectedChoice?.target;
|
|
19740
19883
|
if (!target) return void 0;
|
|
19741
19884
|
return (hints) => createSession(target, hints);
|
|
@@ -20058,10 +20201,10 @@ function profileLabel(streamId) {
|
|
|
20058
20201
|
return streamId.charAt(0).toUpperCase() + streamId.slice(1);
|
|
20059
20202
|
}
|
|
20060
20203
|
function StreamBrokerSelector({ deviceId, value, onChange, disabled, label, className }) {
|
|
20061
|
-
const labelId = (0, react.useId)();
|
|
20204
|
+
const labelId = (0, react$1.useId)();
|
|
20062
20205
|
const query = useCameraStreamsGetRtspEntries({ deviceId }, { refetchOnWindowFocus: false });
|
|
20063
|
-
const [options, setOptions] = (0, react.useState)([AUTO_OPTION]);
|
|
20064
|
-
(0, react.useEffect)(() => {
|
|
20206
|
+
const [options, setOptions] = (0, react$1.useState)([AUTO_OPTION]);
|
|
20207
|
+
(0, react$1.useEffect)(() => {
|
|
20065
20208
|
if (!query.data) return;
|
|
20066
20209
|
const prefix = `${deviceId}/`;
|
|
20067
20210
|
const next = [AUTO_OPTION];
|
|
@@ -20100,6 +20243,1489 @@ function StreamBrokerSelector({ deviceId, value, onChange, disabled, label, clas
|
|
|
20100
20243
|
});
|
|
20101
20244
|
}
|
|
20102
20245
|
//#endregion
|
|
20246
|
+
//#region ../../node_modules/qrcode.react/lib/esm/index.js
|
|
20247
|
+
var __defProp = Object.defineProperty;
|
|
20248
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
20249
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
20250
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
20251
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, {
|
|
20252
|
+
enumerable: true,
|
|
20253
|
+
configurable: true,
|
|
20254
|
+
writable: true,
|
|
20255
|
+
value
|
|
20256
|
+
}) : obj[key] = value;
|
|
20257
|
+
var __spreadValues = (a, b) => {
|
|
20258
|
+
for (var prop in b || (b = {})) if (__hasOwnProp.call(b, prop)) __defNormalProp(a, prop, b[prop]);
|
|
20259
|
+
if (__getOwnPropSymbols) {
|
|
20260
|
+
for (var prop of __getOwnPropSymbols(b)) if (__propIsEnum.call(b, prop)) __defNormalProp(a, prop, b[prop]);
|
|
20261
|
+
}
|
|
20262
|
+
return a;
|
|
20263
|
+
};
|
|
20264
|
+
var __objRest = (source, exclude) => {
|
|
20265
|
+
var target = {};
|
|
20266
|
+
for (var prop in source) if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0) target[prop] = source[prop];
|
|
20267
|
+
if (source != null && __getOwnPropSymbols) {
|
|
20268
|
+
for (var prop of __getOwnPropSymbols(source)) if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop)) target[prop] = source[prop];
|
|
20269
|
+
}
|
|
20270
|
+
return target;
|
|
20271
|
+
};
|
|
20272
|
+
/**
|
|
20273
|
+
* @license QR Code generator library (TypeScript)
|
|
20274
|
+
* Copyright (c) Project Nayuki.
|
|
20275
|
+
* SPDX-License-Identifier: MIT
|
|
20276
|
+
*/
|
|
20277
|
+
var qrcodegen;
|
|
20278
|
+
((qrcodegen2) => {
|
|
20279
|
+
const _QrCode = class _QrCode {
|
|
20280
|
+
constructor(version, errorCorrectionLevel, dataCodewords, msk) {
|
|
20281
|
+
this.version = version;
|
|
20282
|
+
this.errorCorrectionLevel = errorCorrectionLevel;
|
|
20283
|
+
this.modules = [];
|
|
20284
|
+
this.isFunction = [];
|
|
20285
|
+
if (version < _QrCode.MIN_VERSION || version > _QrCode.MAX_VERSION) throw new RangeError("Version value out of range");
|
|
20286
|
+
if (msk < -1 || msk > 7) throw new RangeError("Mask value out of range");
|
|
20287
|
+
this.size = version * 4 + 17;
|
|
20288
|
+
let row = [];
|
|
20289
|
+
for (let i = 0; i < this.size; i++) row.push(false);
|
|
20290
|
+
for (let i = 0; i < this.size; i++) {
|
|
20291
|
+
this.modules.push(row.slice());
|
|
20292
|
+
this.isFunction.push(row.slice());
|
|
20293
|
+
}
|
|
20294
|
+
this.drawFunctionPatterns();
|
|
20295
|
+
const allCodewords = this.addEccAndInterleave(dataCodewords);
|
|
20296
|
+
this.drawCodewords(allCodewords);
|
|
20297
|
+
if (msk == -1) {
|
|
20298
|
+
let minPenalty = 1e9;
|
|
20299
|
+
for (let i = 0; i < 8; i++) {
|
|
20300
|
+
this.applyMask(i);
|
|
20301
|
+
this.drawFormatBits(i);
|
|
20302
|
+
const penalty = this.getPenaltyScore();
|
|
20303
|
+
if (penalty < minPenalty) {
|
|
20304
|
+
msk = i;
|
|
20305
|
+
minPenalty = penalty;
|
|
20306
|
+
}
|
|
20307
|
+
this.applyMask(i);
|
|
20308
|
+
}
|
|
20309
|
+
}
|
|
20310
|
+
assert(0 <= msk && msk <= 7);
|
|
20311
|
+
this.mask = msk;
|
|
20312
|
+
this.applyMask(msk);
|
|
20313
|
+
this.drawFormatBits(msk);
|
|
20314
|
+
this.isFunction = [];
|
|
20315
|
+
}
|
|
20316
|
+
static encodeText(text, ecl) {
|
|
20317
|
+
const segs = qrcodegen2.QrSegment.makeSegments(text);
|
|
20318
|
+
return _QrCode.encodeSegments(segs, ecl);
|
|
20319
|
+
}
|
|
20320
|
+
static encodeBinary(data, ecl) {
|
|
20321
|
+
const seg = qrcodegen2.QrSegment.makeBytes(data);
|
|
20322
|
+
return _QrCode.encodeSegments([seg], ecl);
|
|
20323
|
+
}
|
|
20324
|
+
static encodeSegments(segs, ecl, minVersion = 1, maxVersion = 40, mask = -1, boostEcl = true) {
|
|
20325
|
+
if (!(_QrCode.MIN_VERSION <= minVersion && minVersion <= maxVersion && maxVersion <= _QrCode.MAX_VERSION) || mask < -1 || mask > 7) throw new RangeError("Invalid value");
|
|
20326
|
+
let version;
|
|
20327
|
+
let dataUsedBits;
|
|
20328
|
+
for (version = minVersion;; version++) {
|
|
20329
|
+
const dataCapacityBits2 = _QrCode.getNumDataCodewords(version, ecl) * 8;
|
|
20330
|
+
const usedBits = QrSegment.getTotalBits(segs, version);
|
|
20331
|
+
if (usedBits <= dataCapacityBits2) {
|
|
20332
|
+
dataUsedBits = usedBits;
|
|
20333
|
+
break;
|
|
20334
|
+
}
|
|
20335
|
+
if (version >= maxVersion) throw new RangeError("Data too long");
|
|
20336
|
+
}
|
|
20337
|
+
for (const newEcl of [
|
|
20338
|
+
_QrCode.Ecc.MEDIUM,
|
|
20339
|
+
_QrCode.Ecc.QUARTILE,
|
|
20340
|
+
_QrCode.Ecc.HIGH
|
|
20341
|
+
]) if (boostEcl && dataUsedBits <= _QrCode.getNumDataCodewords(version, newEcl) * 8) ecl = newEcl;
|
|
20342
|
+
let bb = [];
|
|
20343
|
+
for (const seg of segs) {
|
|
20344
|
+
appendBits(seg.mode.modeBits, 4, bb);
|
|
20345
|
+
appendBits(seg.numChars, seg.mode.numCharCountBits(version), bb);
|
|
20346
|
+
for (const b of seg.getData()) bb.push(b);
|
|
20347
|
+
}
|
|
20348
|
+
assert(bb.length == dataUsedBits);
|
|
20349
|
+
const dataCapacityBits = _QrCode.getNumDataCodewords(version, ecl) * 8;
|
|
20350
|
+
assert(bb.length <= dataCapacityBits);
|
|
20351
|
+
appendBits(0, Math.min(4, dataCapacityBits - bb.length), bb);
|
|
20352
|
+
appendBits(0, (8 - bb.length % 8) % 8, bb);
|
|
20353
|
+
assert(bb.length % 8 == 0);
|
|
20354
|
+
for (let padByte = 236; bb.length < dataCapacityBits; padByte ^= 253) appendBits(padByte, 8, bb);
|
|
20355
|
+
let dataCodewords = [];
|
|
20356
|
+
while (dataCodewords.length * 8 < bb.length) dataCodewords.push(0);
|
|
20357
|
+
bb.forEach((b, i) => dataCodewords[i >>> 3] |= b << 7 - (i & 7));
|
|
20358
|
+
return new _QrCode(version, ecl, dataCodewords, mask);
|
|
20359
|
+
}
|
|
20360
|
+
getModule(x, y) {
|
|
20361
|
+
return 0 <= x && x < this.size && 0 <= y && y < this.size && this.modules[y][x];
|
|
20362
|
+
}
|
|
20363
|
+
getModules() {
|
|
20364
|
+
return this.modules;
|
|
20365
|
+
}
|
|
20366
|
+
drawFunctionPatterns() {
|
|
20367
|
+
for (let i = 0; i < this.size; i++) {
|
|
20368
|
+
this.setFunctionModule(6, i, i % 2 == 0);
|
|
20369
|
+
this.setFunctionModule(i, 6, i % 2 == 0);
|
|
20370
|
+
}
|
|
20371
|
+
this.drawFinderPattern(3, 3);
|
|
20372
|
+
this.drawFinderPattern(this.size - 4, 3);
|
|
20373
|
+
this.drawFinderPattern(3, this.size - 4);
|
|
20374
|
+
const alignPatPos = this.getAlignmentPatternPositions();
|
|
20375
|
+
const numAlign = alignPatPos.length;
|
|
20376
|
+
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]);
|
|
20377
|
+
this.drawFormatBits(0);
|
|
20378
|
+
this.drawVersion();
|
|
20379
|
+
}
|
|
20380
|
+
drawFormatBits(mask) {
|
|
20381
|
+
const data = this.errorCorrectionLevel.formatBits << 3 | mask;
|
|
20382
|
+
let rem = data;
|
|
20383
|
+
for (let i = 0; i < 10; i++) rem = rem << 1 ^ (rem >>> 9) * 1335;
|
|
20384
|
+
const bits = (data << 10 | rem) ^ 21522;
|
|
20385
|
+
assert(bits >>> 15 == 0);
|
|
20386
|
+
for (let i = 0; i <= 5; i++) this.setFunctionModule(8, i, getBit(bits, i));
|
|
20387
|
+
this.setFunctionModule(8, 7, getBit(bits, 6));
|
|
20388
|
+
this.setFunctionModule(8, 8, getBit(bits, 7));
|
|
20389
|
+
this.setFunctionModule(7, 8, getBit(bits, 8));
|
|
20390
|
+
for (let i = 9; i < 15; i++) this.setFunctionModule(14 - i, 8, getBit(bits, i));
|
|
20391
|
+
for (let i = 0; i < 8; i++) this.setFunctionModule(this.size - 1 - i, 8, getBit(bits, i));
|
|
20392
|
+
for (let i = 8; i < 15; i++) this.setFunctionModule(8, this.size - 15 + i, getBit(bits, i));
|
|
20393
|
+
this.setFunctionModule(8, this.size - 8, true);
|
|
20394
|
+
}
|
|
20395
|
+
drawVersion() {
|
|
20396
|
+
if (this.version < 7) return;
|
|
20397
|
+
let rem = this.version;
|
|
20398
|
+
for (let i = 0; i < 12; i++) rem = rem << 1 ^ (rem >>> 11) * 7973;
|
|
20399
|
+
const bits = this.version << 12 | rem;
|
|
20400
|
+
assert(bits >>> 18 == 0);
|
|
20401
|
+
for (let i = 0; i < 18; i++) {
|
|
20402
|
+
const color = getBit(bits, i);
|
|
20403
|
+
const a = this.size - 11 + i % 3;
|
|
20404
|
+
const b = Math.floor(i / 3);
|
|
20405
|
+
this.setFunctionModule(a, b, color);
|
|
20406
|
+
this.setFunctionModule(b, a, color);
|
|
20407
|
+
}
|
|
20408
|
+
}
|
|
20409
|
+
drawFinderPattern(x, y) {
|
|
20410
|
+
for (let dy = -4; dy <= 4; dy++) for (let dx = -4; dx <= 4; dx++) {
|
|
20411
|
+
const dist = Math.max(Math.abs(dx), Math.abs(dy));
|
|
20412
|
+
const xx = x + dx;
|
|
20413
|
+
const yy = y + dy;
|
|
20414
|
+
if (0 <= xx && xx < this.size && 0 <= yy && yy < this.size) this.setFunctionModule(xx, yy, dist != 2 && dist != 4);
|
|
20415
|
+
}
|
|
20416
|
+
}
|
|
20417
|
+
drawAlignmentPattern(x, y) {
|
|
20418
|
+
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);
|
|
20419
|
+
}
|
|
20420
|
+
setFunctionModule(x, y, isDark) {
|
|
20421
|
+
this.modules[y][x] = isDark;
|
|
20422
|
+
this.isFunction[y][x] = true;
|
|
20423
|
+
}
|
|
20424
|
+
addEccAndInterleave(data) {
|
|
20425
|
+
const ver = this.version;
|
|
20426
|
+
const ecl = this.errorCorrectionLevel;
|
|
20427
|
+
if (data.length != _QrCode.getNumDataCodewords(ver, ecl)) throw new RangeError("Invalid argument");
|
|
20428
|
+
const numBlocks = _QrCode.NUM_ERROR_CORRECTION_BLOCKS[ecl.ordinal][ver];
|
|
20429
|
+
const blockEccLen = _QrCode.ECC_CODEWORDS_PER_BLOCK[ecl.ordinal][ver];
|
|
20430
|
+
const rawCodewords = Math.floor(_QrCode.getNumRawDataModules(ver) / 8);
|
|
20431
|
+
const numShortBlocks = numBlocks - rawCodewords % numBlocks;
|
|
20432
|
+
const shortBlockLen = Math.floor(rawCodewords / numBlocks);
|
|
20433
|
+
let blocks = [];
|
|
20434
|
+
const rsDiv = _QrCode.reedSolomonComputeDivisor(blockEccLen);
|
|
20435
|
+
for (let i = 0, k = 0; i < numBlocks; i++) {
|
|
20436
|
+
let dat = data.slice(k, k + shortBlockLen - blockEccLen + (i < numShortBlocks ? 0 : 1));
|
|
20437
|
+
k += dat.length;
|
|
20438
|
+
const ecc = _QrCode.reedSolomonComputeRemainder(dat, rsDiv);
|
|
20439
|
+
if (i < numShortBlocks) dat.push(0);
|
|
20440
|
+
blocks.push(dat.concat(ecc));
|
|
20441
|
+
}
|
|
20442
|
+
let result = [];
|
|
20443
|
+
for (let i = 0; i < blocks[0].length; i++) blocks.forEach((block, j) => {
|
|
20444
|
+
if (i != shortBlockLen - blockEccLen || j >= numShortBlocks) result.push(block[i]);
|
|
20445
|
+
});
|
|
20446
|
+
assert(result.length == rawCodewords);
|
|
20447
|
+
return result;
|
|
20448
|
+
}
|
|
20449
|
+
drawCodewords(data) {
|
|
20450
|
+
if (data.length != Math.floor(_QrCode.getNumRawDataModules(this.version) / 8)) throw new RangeError("Invalid argument");
|
|
20451
|
+
let i = 0;
|
|
20452
|
+
for (let right = this.size - 1; right >= 1; right -= 2) {
|
|
20453
|
+
if (right == 6) right = 5;
|
|
20454
|
+
for (let vert = 0; vert < this.size; vert++) for (let j = 0; j < 2; j++) {
|
|
20455
|
+
const x = right - j;
|
|
20456
|
+
const y = (right + 1 & 2) == 0 ? this.size - 1 - vert : vert;
|
|
20457
|
+
if (!this.isFunction[y][x] && i < data.length * 8) {
|
|
20458
|
+
this.modules[y][x] = getBit(data[i >>> 3], 7 - (i & 7));
|
|
20459
|
+
i++;
|
|
20460
|
+
}
|
|
20461
|
+
}
|
|
20462
|
+
}
|
|
20463
|
+
assert(i == data.length * 8);
|
|
20464
|
+
}
|
|
20465
|
+
applyMask(mask) {
|
|
20466
|
+
if (mask < 0 || mask > 7) throw new RangeError("Mask value out of range");
|
|
20467
|
+
for (let y = 0; y < this.size; y++) for (let x = 0; x < this.size; x++) {
|
|
20468
|
+
let invert;
|
|
20469
|
+
switch (mask) {
|
|
20470
|
+
case 0:
|
|
20471
|
+
invert = (x + y) % 2 == 0;
|
|
20472
|
+
break;
|
|
20473
|
+
case 1:
|
|
20474
|
+
invert = y % 2 == 0;
|
|
20475
|
+
break;
|
|
20476
|
+
case 2:
|
|
20477
|
+
invert = x % 3 == 0;
|
|
20478
|
+
break;
|
|
20479
|
+
case 3:
|
|
20480
|
+
invert = (x + y) % 3 == 0;
|
|
20481
|
+
break;
|
|
20482
|
+
case 4:
|
|
20483
|
+
invert = (Math.floor(x / 3) + Math.floor(y / 2)) % 2 == 0;
|
|
20484
|
+
break;
|
|
20485
|
+
case 5:
|
|
20486
|
+
invert = x * y % 2 + x * y % 3 == 0;
|
|
20487
|
+
break;
|
|
20488
|
+
case 6:
|
|
20489
|
+
invert = (x * y % 2 + x * y % 3) % 2 == 0;
|
|
20490
|
+
break;
|
|
20491
|
+
case 7:
|
|
20492
|
+
invert = ((x + y) % 2 + x * y % 3) % 2 == 0;
|
|
20493
|
+
break;
|
|
20494
|
+
default: throw new Error("Unreachable");
|
|
20495
|
+
}
|
|
20496
|
+
if (!this.isFunction[y][x] && invert) this.modules[y][x] = !this.modules[y][x];
|
|
20497
|
+
}
|
|
20498
|
+
}
|
|
20499
|
+
getPenaltyScore() {
|
|
20500
|
+
let result = 0;
|
|
20501
|
+
for (let y = 0; y < this.size; y++) {
|
|
20502
|
+
let runColor = false;
|
|
20503
|
+
let runX = 0;
|
|
20504
|
+
let runHistory = [
|
|
20505
|
+
0,
|
|
20506
|
+
0,
|
|
20507
|
+
0,
|
|
20508
|
+
0,
|
|
20509
|
+
0,
|
|
20510
|
+
0,
|
|
20511
|
+
0
|
|
20512
|
+
];
|
|
20513
|
+
for (let x = 0; x < this.size; x++) if (this.modules[y][x] == runColor) {
|
|
20514
|
+
runX++;
|
|
20515
|
+
if (runX == 5) result += _QrCode.PENALTY_N1;
|
|
20516
|
+
else if (runX > 5) result++;
|
|
20517
|
+
} else {
|
|
20518
|
+
this.finderPenaltyAddHistory(runX, runHistory);
|
|
20519
|
+
if (!runColor) result += this.finderPenaltyCountPatterns(runHistory) * _QrCode.PENALTY_N3;
|
|
20520
|
+
runColor = this.modules[y][x];
|
|
20521
|
+
runX = 1;
|
|
20522
|
+
}
|
|
20523
|
+
result += this.finderPenaltyTerminateAndCount(runColor, runX, runHistory) * _QrCode.PENALTY_N3;
|
|
20524
|
+
}
|
|
20525
|
+
for (let x = 0; x < this.size; x++) {
|
|
20526
|
+
let runColor = false;
|
|
20527
|
+
let runY = 0;
|
|
20528
|
+
let runHistory = [
|
|
20529
|
+
0,
|
|
20530
|
+
0,
|
|
20531
|
+
0,
|
|
20532
|
+
0,
|
|
20533
|
+
0,
|
|
20534
|
+
0,
|
|
20535
|
+
0
|
|
20536
|
+
];
|
|
20537
|
+
for (let y = 0; y < this.size; y++) if (this.modules[y][x] == runColor) {
|
|
20538
|
+
runY++;
|
|
20539
|
+
if (runY == 5) result += _QrCode.PENALTY_N1;
|
|
20540
|
+
else if (runY > 5) result++;
|
|
20541
|
+
} else {
|
|
20542
|
+
this.finderPenaltyAddHistory(runY, runHistory);
|
|
20543
|
+
if (!runColor) result += this.finderPenaltyCountPatterns(runHistory) * _QrCode.PENALTY_N3;
|
|
20544
|
+
runColor = this.modules[y][x];
|
|
20545
|
+
runY = 1;
|
|
20546
|
+
}
|
|
20547
|
+
result += this.finderPenaltyTerminateAndCount(runColor, runY, runHistory) * _QrCode.PENALTY_N3;
|
|
20548
|
+
}
|
|
20549
|
+
for (let y = 0; y < this.size - 1; y++) for (let x = 0; x < this.size - 1; x++) {
|
|
20550
|
+
const color = this.modules[y][x];
|
|
20551
|
+
if (color == this.modules[y][x + 1] && color == this.modules[y + 1][x] && color == this.modules[y + 1][x + 1]) result += _QrCode.PENALTY_N2;
|
|
20552
|
+
}
|
|
20553
|
+
let dark = 0;
|
|
20554
|
+
for (const row of this.modules) dark = row.reduce((sum, color) => sum + (color ? 1 : 0), dark);
|
|
20555
|
+
const total = this.size * this.size;
|
|
20556
|
+
const k = Math.ceil(Math.abs(dark * 20 - total * 10) / total) - 1;
|
|
20557
|
+
assert(0 <= k && k <= 9);
|
|
20558
|
+
result += k * _QrCode.PENALTY_N4;
|
|
20559
|
+
assert(0 <= result && result <= 2568888);
|
|
20560
|
+
return result;
|
|
20561
|
+
}
|
|
20562
|
+
getAlignmentPatternPositions() {
|
|
20563
|
+
if (this.version == 1) return [];
|
|
20564
|
+
else {
|
|
20565
|
+
const numAlign = Math.floor(this.version / 7) + 2;
|
|
20566
|
+
const step = this.version == 32 ? 26 : Math.ceil((this.version * 4 + 4) / (numAlign * 2 - 2)) * 2;
|
|
20567
|
+
let result = [6];
|
|
20568
|
+
for (let pos = this.size - 7; result.length < numAlign; pos -= step) result.splice(1, 0, pos);
|
|
20569
|
+
return result;
|
|
20570
|
+
}
|
|
20571
|
+
}
|
|
20572
|
+
static getNumRawDataModules(ver) {
|
|
20573
|
+
if (ver < _QrCode.MIN_VERSION || ver > _QrCode.MAX_VERSION) throw new RangeError("Version number out of range");
|
|
20574
|
+
let result = (16 * ver + 128) * ver + 64;
|
|
20575
|
+
if (ver >= 2) {
|
|
20576
|
+
const numAlign = Math.floor(ver / 7) + 2;
|
|
20577
|
+
result -= (25 * numAlign - 10) * numAlign - 55;
|
|
20578
|
+
if (ver >= 7) result -= 36;
|
|
20579
|
+
}
|
|
20580
|
+
assert(208 <= result && result <= 29648);
|
|
20581
|
+
return result;
|
|
20582
|
+
}
|
|
20583
|
+
static getNumDataCodewords(ver, ecl) {
|
|
20584
|
+
return Math.floor(_QrCode.getNumRawDataModules(ver) / 8) - _QrCode.ECC_CODEWORDS_PER_BLOCK[ecl.ordinal][ver] * _QrCode.NUM_ERROR_CORRECTION_BLOCKS[ecl.ordinal][ver];
|
|
20585
|
+
}
|
|
20586
|
+
static reedSolomonComputeDivisor(degree) {
|
|
20587
|
+
if (degree < 1 || degree > 255) throw new RangeError("Degree out of range");
|
|
20588
|
+
let result = [];
|
|
20589
|
+
for (let i = 0; i < degree - 1; i++) result.push(0);
|
|
20590
|
+
result.push(1);
|
|
20591
|
+
let root = 1;
|
|
20592
|
+
for (let i = 0; i < degree; i++) {
|
|
20593
|
+
for (let j = 0; j < result.length; j++) {
|
|
20594
|
+
result[j] = _QrCode.reedSolomonMultiply(result[j], root);
|
|
20595
|
+
if (j + 1 < result.length) result[j] ^= result[j + 1];
|
|
20596
|
+
}
|
|
20597
|
+
root = _QrCode.reedSolomonMultiply(root, 2);
|
|
20598
|
+
}
|
|
20599
|
+
return result;
|
|
20600
|
+
}
|
|
20601
|
+
static reedSolomonComputeRemainder(data, divisor) {
|
|
20602
|
+
let result = divisor.map((_) => 0);
|
|
20603
|
+
for (const b of data) {
|
|
20604
|
+
const factor = b ^ result.shift();
|
|
20605
|
+
result.push(0);
|
|
20606
|
+
divisor.forEach((coef, i) => result[i] ^= _QrCode.reedSolomonMultiply(coef, factor));
|
|
20607
|
+
}
|
|
20608
|
+
return result;
|
|
20609
|
+
}
|
|
20610
|
+
static reedSolomonMultiply(x, y) {
|
|
20611
|
+
if (x >>> 8 != 0 || y >>> 8 != 0) throw new RangeError("Byte out of range");
|
|
20612
|
+
let z = 0;
|
|
20613
|
+
for (let i = 7; i >= 0; i--) {
|
|
20614
|
+
z = z << 1 ^ (z >>> 7) * 285;
|
|
20615
|
+
z ^= (y >>> i & 1) * x;
|
|
20616
|
+
}
|
|
20617
|
+
assert(z >>> 8 == 0);
|
|
20618
|
+
return z;
|
|
20619
|
+
}
|
|
20620
|
+
finderPenaltyCountPatterns(runHistory) {
|
|
20621
|
+
const n = runHistory[1];
|
|
20622
|
+
assert(n <= this.size * 3);
|
|
20623
|
+
const core = n > 0 && runHistory[2] == n && runHistory[3] == n * 3 && runHistory[4] == n && runHistory[5] == n;
|
|
20624
|
+
return (core && runHistory[0] >= n * 4 && runHistory[6] >= n ? 1 : 0) + (core && runHistory[6] >= n * 4 && runHistory[0] >= n ? 1 : 0);
|
|
20625
|
+
}
|
|
20626
|
+
finderPenaltyTerminateAndCount(currentRunColor, currentRunLength, runHistory) {
|
|
20627
|
+
if (currentRunColor) {
|
|
20628
|
+
this.finderPenaltyAddHistory(currentRunLength, runHistory);
|
|
20629
|
+
currentRunLength = 0;
|
|
20630
|
+
}
|
|
20631
|
+
currentRunLength += this.size;
|
|
20632
|
+
this.finderPenaltyAddHistory(currentRunLength, runHistory);
|
|
20633
|
+
return this.finderPenaltyCountPatterns(runHistory);
|
|
20634
|
+
}
|
|
20635
|
+
finderPenaltyAddHistory(currentRunLength, runHistory) {
|
|
20636
|
+
if (runHistory[0] == 0) currentRunLength += this.size;
|
|
20637
|
+
runHistory.pop();
|
|
20638
|
+
runHistory.unshift(currentRunLength);
|
|
20639
|
+
}
|
|
20640
|
+
};
|
|
20641
|
+
_QrCode.MIN_VERSION = 1;
|
|
20642
|
+
_QrCode.MAX_VERSION = 40;
|
|
20643
|
+
_QrCode.PENALTY_N1 = 3;
|
|
20644
|
+
_QrCode.PENALTY_N2 = 3;
|
|
20645
|
+
_QrCode.PENALTY_N3 = 40;
|
|
20646
|
+
_QrCode.PENALTY_N4 = 10;
|
|
20647
|
+
_QrCode.ECC_CODEWORDS_PER_BLOCK = [
|
|
20648
|
+
[
|
|
20649
|
+
-1,
|
|
20650
|
+
7,
|
|
20651
|
+
10,
|
|
20652
|
+
15,
|
|
20653
|
+
20,
|
|
20654
|
+
26,
|
|
20655
|
+
18,
|
|
20656
|
+
20,
|
|
20657
|
+
24,
|
|
20658
|
+
30,
|
|
20659
|
+
18,
|
|
20660
|
+
20,
|
|
20661
|
+
24,
|
|
20662
|
+
26,
|
|
20663
|
+
30,
|
|
20664
|
+
22,
|
|
20665
|
+
24,
|
|
20666
|
+
28,
|
|
20667
|
+
30,
|
|
20668
|
+
28,
|
|
20669
|
+
28,
|
|
20670
|
+
28,
|
|
20671
|
+
28,
|
|
20672
|
+
30,
|
|
20673
|
+
30,
|
|
20674
|
+
26,
|
|
20675
|
+
28,
|
|
20676
|
+
30,
|
|
20677
|
+
30,
|
|
20678
|
+
30,
|
|
20679
|
+
30,
|
|
20680
|
+
30,
|
|
20681
|
+
30,
|
|
20682
|
+
30,
|
|
20683
|
+
30,
|
|
20684
|
+
30,
|
|
20685
|
+
30,
|
|
20686
|
+
30,
|
|
20687
|
+
30,
|
|
20688
|
+
30,
|
|
20689
|
+
30
|
|
20690
|
+
],
|
|
20691
|
+
[
|
|
20692
|
+
-1,
|
|
20693
|
+
10,
|
|
20694
|
+
16,
|
|
20695
|
+
26,
|
|
20696
|
+
18,
|
|
20697
|
+
24,
|
|
20698
|
+
16,
|
|
20699
|
+
18,
|
|
20700
|
+
22,
|
|
20701
|
+
22,
|
|
20702
|
+
26,
|
|
20703
|
+
30,
|
|
20704
|
+
22,
|
|
20705
|
+
22,
|
|
20706
|
+
24,
|
|
20707
|
+
24,
|
|
20708
|
+
28,
|
|
20709
|
+
28,
|
|
20710
|
+
26,
|
|
20711
|
+
26,
|
|
20712
|
+
26,
|
|
20713
|
+
26,
|
|
20714
|
+
28,
|
|
20715
|
+
28,
|
|
20716
|
+
28,
|
|
20717
|
+
28,
|
|
20718
|
+
28,
|
|
20719
|
+
28,
|
|
20720
|
+
28,
|
|
20721
|
+
28,
|
|
20722
|
+
28,
|
|
20723
|
+
28,
|
|
20724
|
+
28,
|
|
20725
|
+
28,
|
|
20726
|
+
28,
|
|
20727
|
+
28,
|
|
20728
|
+
28,
|
|
20729
|
+
28,
|
|
20730
|
+
28,
|
|
20731
|
+
28,
|
|
20732
|
+
28
|
|
20733
|
+
],
|
|
20734
|
+
[
|
|
20735
|
+
-1,
|
|
20736
|
+
13,
|
|
20737
|
+
22,
|
|
20738
|
+
18,
|
|
20739
|
+
26,
|
|
20740
|
+
18,
|
|
20741
|
+
24,
|
|
20742
|
+
18,
|
|
20743
|
+
22,
|
|
20744
|
+
20,
|
|
20745
|
+
24,
|
|
20746
|
+
28,
|
|
20747
|
+
26,
|
|
20748
|
+
24,
|
|
20749
|
+
20,
|
|
20750
|
+
30,
|
|
20751
|
+
24,
|
|
20752
|
+
28,
|
|
20753
|
+
28,
|
|
20754
|
+
26,
|
|
20755
|
+
30,
|
|
20756
|
+
28,
|
|
20757
|
+
30,
|
|
20758
|
+
30,
|
|
20759
|
+
30,
|
|
20760
|
+
30,
|
|
20761
|
+
28,
|
|
20762
|
+
30,
|
|
20763
|
+
30,
|
|
20764
|
+
30,
|
|
20765
|
+
30,
|
|
20766
|
+
30,
|
|
20767
|
+
30,
|
|
20768
|
+
30,
|
|
20769
|
+
30,
|
|
20770
|
+
30,
|
|
20771
|
+
30,
|
|
20772
|
+
30,
|
|
20773
|
+
30,
|
|
20774
|
+
30,
|
|
20775
|
+
30
|
|
20776
|
+
],
|
|
20777
|
+
[
|
|
20778
|
+
-1,
|
|
20779
|
+
17,
|
|
20780
|
+
28,
|
|
20781
|
+
22,
|
|
20782
|
+
16,
|
|
20783
|
+
22,
|
|
20784
|
+
28,
|
|
20785
|
+
26,
|
|
20786
|
+
26,
|
|
20787
|
+
24,
|
|
20788
|
+
28,
|
|
20789
|
+
24,
|
|
20790
|
+
28,
|
|
20791
|
+
22,
|
|
20792
|
+
24,
|
|
20793
|
+
24,
|
|
20794
|
+
30,
|
|
20795
|
+
28,
|
|
20796
|
+
28,
|
|
20797
|
+
26,
|
|
20798
|
+
28,
|
|
20799
|
+
30,
|
|
20800
|
+
24,
|
|
20801
|
+
30,
|
|
20802
|
+
30,
|
|
20803
|
+
30,
|
|
20804
|
+
30,
|
|
20805
|
+
30,
|
|
20806
|
+
30,
|
|
20807
|
+
30,
|
|
20808
|
+
30,
|
|
20809
|
+
30,
|
|
20810
|
+
30,
|
|
20811
|
+
30,
|
|
20812
|
+
30,
|
|
20813
|
+
30,
|
|
20814
|
+
30,
|
|
20815
|
+
30,
|
|
20816
|
+
30,
|
|
20817
|
+
30,
|
|
20818
|
+
30
|
|
20819
|
+
]
|
|
20820
|
+
];
|
|
20821
|
+
_QrCode.NUM_ERROR_CORRECTION_BLOCKS = [
|
|
20822
|
+
[
|
|
20823
|
+
-1,
|
|
20824
|
+
1,
|
|
20825
|
+
1,
|
|
20826
|
+
1,
|
|
20827
|
+
1,
|
|
20828
|
+
1,
|
|
20829
|
+
2,
|
|
20830
|
+
2,
|
|
20831
|
+
2,
|
|
20832
|
+
2,
|
|
20833
|
+
4,
|
|
20834
|
+
4,
|
|
20835
|
+
4,
|
|
20836
|
+
4,
|
|
20837
|
+
4,
|
|
20838
|
+
6,
|
|
20839
|
+
6,
|
|
20840
|
+
6,
|
|
20841
|
+
6,
|
|
20842
|
+
7,
|
|
20843
|
+
8,
|
|
20844
|
+
8,
|
|
20845
|
+
9,
|
|
20846
|
+
9,
|
|
20847
|
+
10,
|
|
20848
|
+
12,
|
|
20849
|
+
12,
|
|
20850
|
+
12,
|
|
20851
|
+
13,
|
|
20852
|
+
14,
|
|
20853
|
+
15,
|
|
20854
|
+
16,
|
|
20855
|
+
17,
|
|
20856
|
+
18,
|
|
20857
|
+
19,
|
|
20858
|
+
19,
|
|
20859
|
+
20,
|
|
20860
|
+
21,
|
|
20861
|
+
22,
|
|
20862
|
+
24,
|
|
20863
|
+
25
|
|
20864
|
+
],
|
|
20865
|
+
[
|
|
20866
|
+
-1,
|
|
20867
|
+
1,
|
|
20868
|
+
1,
|
|
20869
|
+
1,
|
|
20870
|
+
2,
|
|
20871
|
+
2,
|
|
20872
|
+
4,
|
|
20873
|
+
4,
|
|
20874
|
+
4,
|
|
20875
|
+
5,
|
|
20876
|
+
5,
|
|
20877
|
+
5,
|
|
20878
|
+
8,
|
|
20879
|
+
9,
|
|
20880
|
+
9,
|
|
20881
|
+
10,
|
|
20882
|
+
10,
|
|
20883
|
+
11,
|
|
20884
|
+
13,
|
|
20885
|
+
14,
|
|
20886
|
+
16,
|
|
20887
|
+
17,
|
|
20888
|
+
17,
|
|
20889
|
+
18,
|
|
20890
|
+
20,
|
|
20891
|
+
21,
|
|
20892
|
+
23,
|
|
20893
|
+
25,
|
|
20894
|
+
26,
|
|
20895
|
+
28,
|
|
20896
|
+
29,
|
|
20897
|
+
31,
|
|
20898
|
+
33,
|
|
20899
|
+
35,
|
|
20900
|
+
37,
|
|
20901
|
+
38,
|
|
20902
|
+
40,
|
|
20903
|
+
43,
|
|
20904
|
+
45,
|
|
20905
|
+
47,
|
|
20906
|
+
49
|
|
20907
|
+
],
|
|
20908
|
+
[
|
|
20909
|
+
-1,
|
|
20910
|
+
1,
|
|
20911
|
+
1,
|
|
20912
|
+
2,
|
|
20913
|
+
2,
|
|
20914
|
+
4,
|
|
20915
|
+
4,
|
|
20916
|
+
6,
|
|
20917
|
+
6,
|
|
20918
|
+
8,
|
|
20919
|
+
8,
|
|
20920
|
+
8,
|
|
20921
|
+
10,
|
|
20922
|
+
12,
|
|
20923
|
+
16,
|
|
20924
|
+
12,
|
|
20925
|
+
17,
|
|
20926
|
+
16,
|
|
20927
|
+
18,
|
|
20928
|
+
21,
|
|
20929
|
+
20,
|
|
20930
|
+
23,
|
|
20931
|
+
23,
|
|
20932
|
+
25,
|
|
20933
|
+
27,
|
|
20934
|
+
29,
|
|
20935
|
+
34,
|
|
20936
|
+
34,
|
|
20937
|
+
35,
|
|
20938
|
+
38,
|
|
20939
|
+
40,
|
|
20940
|
+
43,
|
|
20941
|
+
45,
|
|
20942
|
+
48,
|
|
20943
|
+
51,
|
|
20944
|
+
53,
|
|
20945
|
+
56,
|
|
20946
|
+
59,
|
|
20947
|
+
62,
|
|
20948
|
+
65,
|
|
20949
|
+
68
|
|
20950
|
+
],
|
|
20951
|
+
[
|
|
20952
|
+
-1,
|
|
20953
|
+
1,
|
|
20954
|
+
1,
|
|
20955
|
+
2,
|
|
20956
|
+
4,
|
|
20957
|
+
4,
|
|
20958
|
+
4,
|
|
20959
|
+
5,
|
|
20960
|
+
6,
|
|
20961
|
+
8,
|
|
20962
|
+
8,
|
|
20963
|
+
11,
|
|
20964
|
+
11,
|
|
20965
|
+
16,
|
|
20966
|
+
16,
|
|
20967
|
+
18,
|
|
20968
|
+
16,
|
|
20969
|
+
19,
|
|
20970
|
+
21,
|
|
20971
|
+
25,
|
|
20972
|
+
25,
|
|
20973
|
+
25,
|
|
20974
|
+
34,
|
|
20975
|
+
30,
|
|
20976
|
+
32,
|
|
20977
|
+
35,
|
|
20978
|
+
37,
|
|
20979
|
+
40,
|
|
20980
|
+
42,
|
|
20981
|
+
45,
|
|
20982
|
+
48,
|
|
20983
|
+
51,
|
|
20984
|
+
54,
|
|
20985
|
+
57,
|
|
20986
|
+
60,
|
|
20987
|
+
63,
|
|
20988
|
+
66,
|
|
20989
|
+
70,
|
|
20990
|
+
74,
|
|
20991
|
+
77,
|
|
20992
|
+
81
|
|
20993
|
+
]
|
|
20994
|
+
];
|
|
20995
|
+
qrcodegen2.QrCode = _QrCode;
|
|
20996
|
+
function appendBits(val, len, bb) {
|
|
20997
|
+
if (len < 0 || len > 31 || val >>> len != 0) throw new RangeError("Value out of range");
|
|
20998
|
+
for (let i = len - 1; i >= 0; i--) bb.push(val >>> i & 1);
|
|
20999
|
+
}
|
|
21000
|
+
function getBit(x, i) {
|
|
21001
|
+
return (x >>> i & 1) != 0;
|
|
21002
|
+
}
|
|
21003
|
+
function assert(cond) {
|
|
21004
|
+
if (!cond) throw new Error("Assertion error");
|
|
21005
|
+
}
|
|
21006
|
+
const _QrSegment = class _QrSegment {
|
|
21007
|
+
constructor(mode, numChars, bitData) {
|
|
21008
|
+
this.mode = mode;
|
|
21009
|
+
this.numChars = numChars;
|
|
21010
|
+
this.bitData = bitData;
|
|
21011
|
+
if (numChars < 0) throw new RangeError("Invalid argument");
|
|
21012
|
+
this.bitData = bitData.slice();
|
|
21013
|
+
}
|
|
21014
|
+
static makeBytes(data) {
|
|
21015
|
+
let bb = [];
|
|
21016
|
+
for (const b of data) appendBits(b, 8, bb);
|
|
21017
|
+
return new _QrSegment(_QrSegment.Mode.BYTE, data.length, bb);
|
|
21018
|
+
}
|
|
21019
|
+
static makeNumeric(digits) {
|
|
21020
|
+
if (!_QrSegment.isNumeric(digits)) throw new RangeError("String contains non-numeric characters");
|
|
21021
|
+
let bb = [];
|
|
21022
|
+
for (let i = 0; i < digits.length;) {
|
|
21023
|
+
const n = Math.min(digits.length - i, 3);
|
|
21024
|
+
appendBits(parseInt(digits.substring(i, i + n), 10), n * 3 + 1, bb);
|
|
21025
|
+
i += n;
|
|
21026
|
+
}
|
|
21027
|
+
return new _QrSegment(_QrSegment.Mode.NUMERIC, digits.length, bb);
|
|
21028
|
+
}
|
|
21029
|
+
static makeAlphanumeric(text) {
|
|
21030
|
+
if (!_QrSegment.isAlphanumeric(text)) throw new RangeError("String contains unencodable characters in alphanumeric mode");
|
|
21031
|
+
let bb = [];
|
|
21032
|
+
let i;
|
|
21033
|
+
for (i = 0; i + 2 <= text.length; i += 2) {
|
|
21034
|
+
let temp = _QrSegment.ALPHANUMERIC_CHARSET.indexOf(text.charAt(i)) * 45;
|
|
21035
|
+
temp += _QrSegment.ALPHANUMERIC_CHARSET.indexOf(text.charAt(i + 1));
|
|
21036
|
+
appendBits(temp, 11, bb);
|
|
21037
|
+
}
|
|
21038
|
+
if (i < text.length) appendBits(_QrSegment.ALPHANUMERIC_CHARSET.indexOf(text.charAt(i)), 6, bb);
|
|
21039
|
+
return new _QrSegment(_QrSegment.Mode.ALPHANUMERIC, text.length, bb);
|
|
21040
|
+
}
|
|
21041
|
+
static makeSegments(text) {
|
|
21042
|
+
if (text == "") return [];
|
|
21043
|
+
else if (_QrSegment.isNumeric(text)) return [_QrSegment.makeNumeric(text)];
|
|
21044
|
+
else if (_QrSegment.isAlphanumeric(text)) return [_QrSegment.makeAlphanumeric(text)];
|
|
21045
|
+
else return [_QrSegment.makeBytes(_QrSegment.toUtf8ByteArray(text))];
|
|
21046
|
+
}
|
|
21047
|
+
static makeEci(assignVal) {
|
|
21048
|
+
let bb = [];
|
|
21049
|
+
if (assignVal < 0) throw new RangeError("ECI assignment value out of range");
|
|
21050
|
+
else if (assignVal < 128) appendBits(assignVal, 8, bb);
|
|
21051
|
+
else if (assignVal < 16384) {
|
|
21052
|
+
appendBits(2, 2, bb);
|
|
21053
|
+
appendBits(assignVal, 14, bb);
|
|
21054
|
+
} else if (assignVal < 1e6) {
|
|
21055
|
+
appendBits(6, 3, bb);
|
|
21056
|
+
appendBits(assignVal, 21, bb);
|
|
21057
|
+
} else throw new RangeError("ECI assignment value out of range");
|
|
21058
|
+
return new _QrSegment(_QrSegment.Mode.ECI, 0, bb);
|
|
21059
|
+
}
|
|
21060
|
+
static isNumeric(text) {
|
|
21061
|
+
return _QrSegment.NUMERIC_REGEX.test(text);
|
|
21062
|
+
}
|
|
21063
|
+
static isAlphanumeric(text) {
|
|
21064
|
+
return _QrSegment.ALPHANUMERIC_REGEX.test(text);
|
|
21065
|
+
}
|
|
21066
|
+
getData() {
|
|
21067
|
+
return this.bitData.slice();
|
|
21068
|
+
}
|
|
21069
|
+
static getTotalBits(segs, version) {
|
|
21070
|
+
let result = 0;
|
|
21071
|
+
for (const seg of segs) {
|
|
21072
|
+
const ccbits = seg.mode.numCharCountBits(version);
|
|
21073
|
+
if (seg.numChars >= 1 << ccbits) return Infinity;
|
|
21074
|
+
result += 4 + ccbits + seg.bitData.length;
|
|
21075
|
+
}
|
|
21076
|
+
return result;
|
|
21077
|
+
}
|
|
21078
|
+
static toUtf8ByteArray(str) {
|
|
21079
|
+
str = encodeURI(str);
|
|
21080
|
+
let result = [];
|
|
21081
|
+
for (let i = 0; i < str.length; i++) if (str.charAt(i) != "%") result.push(str.charCodeAt(i));
|
|
21082
|
+
else {
|
|
21083
|
+
result.push(parseInt(str.substring(i + 1, i + 3), 16));
|
|
21084
|
+
i += 2;
|
|
21085
|
+
}
|
|
21086
|
+
return result;
|
|
21087
|
+
}
|
|
21088
|
+
};
|
|
21089
|
+
_QrSegment.NUMERIC_REGEX = /^[0-9]*$/;
|
|
21090
|
+
_QrSegment.ALPHANUMERIC_REGEX = /^[A-Z0-9 $%*+.\/:-]*$/;
|
|
21091
|
+
_QrSegment.ALPHANUMERIC_CHARSET = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:";
|
|
21092
|
+
let QrSegment = _QrSegment;
|
|
21093
|
+
qrcodegen2.QrSegment = _QrSegment;
|
|
21094
|
+
})(qrcodegen || (qrcodegen = {}));
|
|
21095
|
+
((qrcodegen2) => {
|
|
21096
|
+
((QrCode2) => {
|
|
21097
|
+
const _Ecc = class _Ecc {
|
|
21098
|
+
constructor(ordinal, formatBits) {
|
|
21099
|
+
this.ordinal = ordinal;
|
|
21100
|
+
this.formatBits = formatBits;
|
|
21101
|
+
}
|
|
21102
|
+
};
|
|
21103
|
+
_Ecc.LOW = new _Ecc(0, 1);
|
|
21104
|
+
_Ecc.MEDIUM = new _Ecc(1, 0);
|
|
21105
|
+
_Ecc.QUARTILE = new _Ecc(2, 3);
|
|
21106
|
+
_Ecc.HIGH = new _Ecc(3, 2);
|
|
21107
|
+
QrCode2.Ecc = _Ecc;
|
|
21108
|
+
})(qrcodegen2.QrCode || (qrcodegen2.QrCode = {}));
|
|
21109
|
+
})(qrcodegen || (qrcodegen = {}));
|
|
21110
|
+
((qrcodegen2) => {
|
|
21111
|
+
((QrSegment2) => {
|
|
21112
|
+
const _Mode = class _Mode {
|
|
21113
|
+
constructor(modeBits, numBitsCharCount) {
|
|
21114
|
+
this.modeBits = modeBits;
|
|
21115
|
+
this.numBitsCharCount = numBitsCharCount;
|
|
21116
|
+
}
|
|
21117
|
+
numCharCountBits(ver) {
|
|
21118
|
+
return this.numBitsCharCount[Math.floor((ver + 7) / 17)];
|
|
21119
|
+
}
|
|
21120
|
+
};
|
|
21121
|
+
_Mode.NUMERIC = new _Mode(1, [
|
|
21122
|
+
10,
|
|
21123
|
+
12,
|
|
21124
|
+
14
|
|
21125
|
+
]);
|
|
21126
|
+
_Mode.ALPHANUMERIC = new _Mode(2, [
|
|
21127
|
+
9,
|
|
21128
|
+
11,
|
|
21129
|
+
13
|
|
21130
|
+
]);
|
|
21131
|
+
_Mode.BYTE = new _Mode(4, [
|
|
21132
|
+
8,
|
|
21133
|
+
16,
|
|
21134
|
+
16
|
|
21135
|
+
]);
|
|
21136
|
+
_Mode.KANJI = new _Mode(8, [
|
|
21137
|
+
8,
|
|
21138
|
+
10,
|
|
21139
|
+
12
|
|
21140
|
+
]);
|
|
21141
|
+
_Mode.ECI = new _Mode(7, [
|
|
21142
|
+
0,
|
|
21143
|
+
0,
|
|
21144
|
+
0
|
|
21145
|
+
]);
|
|
21146
|
+
QrSegment2.Mode = _Mode;
|
|
21147
|
+
})(qrcodegen2.QrSegment || (qrcodegen2.QrSegment = {}));
|
|
21148
|
+
})(qrcodegen || (qrcodegen = {}));
|
|
21149
|
+
var qrcodegen_default = qrcodegen;
|
|
21150
|
+
/**
|
|
21151
|
+
* @license qrcode.react
|
|
21152
|
+
* Copyright (c) Paul O'Shannessy
|
|
21153
|
+
* SPDX-License-Identifier: ISC
|
|
21154
|
+
*/
|
|
21155
|
+
var ERROR_LEVEL_MAP = {
|
|
21156
|
+
L: qrcodegen_default.QrCode.Ecc.LOW,
|
|
21157
|
+
M: qrcodegen_default.QrCode.Ecc.MEDIUM,
|
|
21158
|
+
Q: qrcodegen_default.QrCode.Ecc.QUARTILE,
|
|
21159
|
+
H: qrcodegen_default.QrCode.Ecc.HIGH
|
|
21160
|
+
};
|
|
21161
|
+
var DEFAULT_SIZE$1 = 128;
|
|
21162
|
+
var DEFAULT_LEVEL = "L";
|
|
21163
|
+
var DEFAULT_BGCOLOR = "#FFFFFF";
|
|
21164
|
+
var DEFAULT_FGCOLOR = "#000000";
|
|
21165
|
+
var DEFAULT_INCLUDEMARGIN = false;
|
|
21166
|
+
var DEFAULT_MINVERSION = 1;
|
|
21167
|
+
var SPEC_MARGIN_SIZE = 4;
|
|
21168
|
+
var DEFAULT_MARGIN_SIZE = 0;
|
|
21169
|
+
var DEFAULT_IMG_SCALE = .1;
|
|
21170
|
+
function generatePath(modules, margin = 0) {
|
|
21171
|
+
const ops = [];
|
|
21172
|
+
modules.forEach(function(row, y) {
|
|
21173
|
+
let start = null;
|
|
21174
|
+
row.forEach(function(cell, x) {
|
|
21175
|
+
if (!cell && start !== null) {
|
|
21176
|
+
ops.push(`M${start + margin} ${y + margin}h${x - start}v1H${start + margin}z`);
|
|
21177
|
+
start = null;
|
|
21178
|
+
return;
|
|
21179
|
+
}
|
|
21180
|
+
if (x === row.length - 1) {
|
|
21181
|
+
if (!cell) return;
|
|
21182
|
+
if (start === null) ops.push(`M${x + margin},${y + margin} h1v1H${x + margin}z`);
|
|
21183
|
+
else ops.push(`M${start + margin},${y + margin} h${x + 1 - start}v1H${start + margin}z`);
|
|
21184
|
+
return;
|
|
21185
|
+
}
|
|
21186
|
+
if (cell && start === null) start = x;
|
|
21187
|
+
});
|
|
21188
|
+
});
|
|
21189
|
+
return ops.join("");
|
|
21190
|
+
}
|
|
21191
|
+
function excavateModules(modules, excavation) {
|
|
21192
|
+
return modules.slice().map((row, y) => {
|
|
21193
|
+
if (y < excavation.y || y >= excavation.y + excavation.h) return row;
|
|
21194
|
+
return row.map((cell, x) => {
|
|
21195
|
+
if (x < excavation.x || x >= excavation.x + excavation.w) return cell;
|
|
21196
|
+
return false;
|
|
21197
|
+
});
|
|
21198
|
+
});
|
|
21199
|
+
}
|
|
21200
|
+
function getImageSettings(cells, size, margin, imageSettings) {
|
|
21201
|
+
if (imageSettings == null) return null;
|
|
21202
|
+
const numCells = cells.length + margin * 2;
|
|
21203
|
+
const defaultSize = Math.floor(size * DEFAULT_IMG_SCALE);
|
|
21204
|
+
const scale = numCells / size;
|
|
21205
|
+
const w = (imageSettings.width || defaultSize) * scale;
|
|
21206
|
+
const h = (imageSettings.height || defaultSize) * scale;
|
|
21207
|
+
const x = imageSettings.x == null ? cells.length / 2 - w / 2 : imageSettings.x * scale;
|
|
21208
|
+
const y = imageSettings.y == null ? cells.length / 2 - h / 2 : imageSettings.y * scale;
|
|
21209
|
+
const opacity = imageSettings.opacity == null ? 1 : imageSettings.opacity;
|
|
21210
|
+
let excavation = null;
|
|
21211
|
+
if (imageSettings.excavate) {
|
|
21212
|
+
let floorX = Math.floor(x);
|
|
21213
|
+
let floorY = Math.floor(y);
|
|
21214
|
+
excavation = {
|
|
21215
|
+
x: floorX,
|
|
21216
|
+
y: floorY,
|
|
21217
|
+
w: Math.ceil(w + x - floorX),
|
|
21218
|
+
h: Math.ceil(h + y - floorY)
|
|
21219
|
+
};
|
|
21220
|
+
}
|
|
21221
|
+
const crossOrigin = imageSettings.crossOrigin;
|
|
21222
|
+
return {
|
|
21223
|
+
x,
|
|
21224
|
+
y,
|
|
21225
|
+
h,
|
|
21226
|
+
w,
|
|
21227
|
+
excavation,
|
|
21228
|
+
opacity,
|
|
21229
|
+
crossOrigin
|
|
21230
|
+
};
|
|
21231
|
+
}
|
|
21232
|
+
function getMarginSize(includeMargin, marginSize) {
|
|
21233
|
+
if (marginSize != null) return Math.max(Math.floor(marginSize), 0);
|
|
21234
|
+
return includeMargin ? SPEC_MARGIN_SIZE : DEFAULT_MARGIN_SIZE;
|
|
21235
|
+
}
|
|
21236
|
+
function useQRCode({ value, level, minVersion, includeMargin, marginSize, imageSettings, size, boostLevel }) {
|
|
21237
|
+
let qrcode = react.default.useMemo(() => {
|
|
21238
|
+
const segments = (Array.isArray(value) ? value : [value]).reduce((accum, v) => {
|
|
21239
|
+
accum.push(...qrcodegen_default.QrSegment.makeSegments(v));
|
|
21240
|
+
return accum;
|
|
21241
|
+
}, []);
|
|
21242
|
+
return qrcodegen_default.QrCode.encodeSegments(segments, ERROR_LEVEL_MAP[level], minVersion, void 0, void 0, boostLevel);
|
|
21243
|
+
}, [
|
|
21244
|
+
value,
|
|
21245
|
+
level,
|
|
21246
|
+
minVersion,
|
|
21247
|
+
boostLevel
|
|
21248
|
+
]);
|
|
21249
|
+
const { cells, margin, numCells, calculatedImageSettings } = react.default.useMemo(() => {
|
|
21250
|
+
let cells2 = qrcode.getModules();
|
|
21251
|
+
const margin2 = getMarginSize(includeMargin, marginSize);
|
|
21252
|
+
return {
|
|
21253
|
+
cells: cells2,
|
|
21254
|
+
margin: margin2,
|
|
21255
|
+
numCells: cells2.length + margin2 * 2,
|
|
21256
|
+
calculatedImageSettings: getImageSettings(cells2, size, margin2, imageSettings)
|
|
21257
|
+
};
|
|
21258
|
+
}, [
|
|
21259
|
+
qrcode,
|
|
21260
|
+
size,
|
|
21261
|
+
imageSettings,
|
|
21262
|
+
includeMargin,
|
|
21263
|
+
marginSize
|
|
21264
|
+
]);
|
|
21265
|
+
return {
|
|
21266
|
+
qrcode,
|
|
21267
|
+
margin,
|
|
21268
|
+
cells,
|
|
21269
|
+
numCells,
|
|
21270
|
+
calculatedImageSettings
|
|
21271
|
+
};
|
|
21272
|
+
}
|
|
21273
|
+
var SUPPORTS_PATH2D = function() {
|
|
21274
|
+
try {
|
|
21275
|
+
new Path2D().addPath(new Path2D());
|
|
21276
|
+
} catch (e) {
|
|
21277
|
+
return false;
|
|
21278
|
+
}
|
|
21279
|
+
return true;
|
|
21280
|
+
}();
|
|
21281
|
+
var QRCodeCanvas = react.default.forwardRef(function QRCodeCanvas2(props, forwardedRef) {
|
|
21282
|
+
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;
|
|
21283
|
+
const _b = __objRest(_a, [
|
|
21284
|
+
"value",
|
|
21285
|
+
"size",
|
|
21286
|
+
"level",
|
|
21287
|
+
"bgColor",
|
|
21288
|
+
"fgColor",
|
|
21289
|
+
"includeMargin",
|
|
21290
|
+
"minVersion",
|
|
21291
|
+
"boostLevel",
|
|
21292
|
+
"marginSize",
|
|
21293
|
+
"imageSettings"
|
|
21294
|
+
]), { style } = _b, otherProps = __objRest(_b, ["style"]);
|
|
21295
|
+
const imgSrc = imageSettings == null ? void 0 : imageSettings.src;
|
|
21296
|
+
const _canvas = react.default.useRef(null);
|
|
21297
|
+
const _image = react.default.useRef(null);
|
|
21298
|
+
const setCanvasRef = react.default.useCallback((node) => {
|
|
21299
|
+
_canvas.current = node;
|
|
21300
|
+
if (typeof forwardedRef === "function") forwardedRef(node);
|
|
21301
|
+
else if (forwardedRef) forwardedRef.current = node;
|
|
21302
|
+
}, [forwardedRef]);
|
|
21303
|
+
const [isImgLoaded, setIsImageLoaded] = react.default.useState(false);
|
|
21304
|
+
const { margin, cells, numCells, calculatedImageSettings } = useQRCode({
|
|
21305
|
+
value,
|
|
21306
|
+
level,
|
|
21307
|
+
minVersion,
|
|
21308
|
+
boostLevel,
|
|
21309
|
+
includeMargin,
|
|
21310
|
+
marginSize,
|
|
21311
|
+
imageSettings,
|
|
21312
|
+
size
|
|
21313
|
+
});
|
|
21314
|
+
react.default.useEffect(() => {
|
|
21315
|
+
if (_canvas.current != null) {
|
|
21316
|
+
const canvas = _canvas.current;
|
|
21317
|
+
const ctx = canvas.getContext("2d");
|
|
21318
|
+
if (!ctx) return;
|
|
21319
|
+
let cellsToDraw = cells;
|
|
21320
|
+
const image = _image.current;
|
|
21321
|
+
const haveImageToRender = calculatedImageSettings != null && image !== null && image.complete && image.naturalHeight !== 0 && image.naturalWidth !== 0;
|
|
21322
|
+
if (haveImageToRender) {
|
|
21323
|
+
if (calculatedImageSettings.excavation != null) cellsToDraw = excavateModules(cells, calculatedImageSettings.excavation);
|
|
21324
|
+
}
|
|
21325
|
+
const pixelRatio = window.devicePixelRatio || 1;
|
|
21326
|
+
canvas.height = canvas.width = size * pixelRatio;
|
|
21327
|
+
const scale = size / numCells * pixelRatio;
|
|
21328
|
+
ctx.scale(scale, scale);
|
|
21329
|
+
ctx.fillStyle = bgColor;
|
|
21330
|
+
ctx.fillRect(0, 0, numCells, numCells);
|
|
21331
|
+
ctx.fillStyle = fgColor;
|
|
21332
|
+
if (SUPPORTS_PATH2D) ctx.fill(new Path2D(generatePath(cellsToDraw, margin)));
|
|
21333
|
+
else cells.forEach(function(row, rdx) {
|
|
21334
|
+
row.forEach(function(cell, cdx) {
|
|
21335
|
+
if (cell) ctx.fillRect(cdx + margin, rdx + margin, 1, 1);
|
|
21336
|
+
});
|
|
21337
|
+
});
|
|
21338
|
+
if (calculatedImageSettings) ctx.globalAlpha = calculatedImageSettings.opacity;
|
|
21339
|
+
if (haveImageToRender) ctx.drawImage(image, calculatedImageSettings.x + margin, calculatedImageSettings.y + margin, calculatedImageSettings.w, calculatedImageSettings.h);
|
|
21340
|
+
}
|
|
21341
|
+
});
|
|
21342
|
+
react.default.useEffect(() => {
|
|
21343
|
+
setIsImageLoaded(false);
|
|
21344
|
+
}, [imgSrc]);
|
|
21345
|
+
const canvasStyle = __spreadValues({
|
|
21346
|
+
height: size,
|
|
21347
|
+
width: size
|
|
21348
|
+
}, style);
|
|
21349
|
+
let img = null;
|
|
21350
|
+
if (imgSrc != null) img = /* @__PURE__ */ react.default.createElement("img", {
|
|
21351
|
+
src: imgSrc,
|
|
21352
|
+
key: imgSrc,
|
|
21353
|
+
style: { display: "none" },
|
|
21354
|
+
onLoad: () => {
|
|
21355
|
+
setIsImageLoaded(true);
|
|
21356
|
+
},
|
|
21357
|
+
ref: _image,
|
|
21358
|
+
crossOrigin: calculatedImageSettings == null ? void 0 : calculatedImageSettings.crossOrigin
|
|
21359
|
+
});
|
|
21360
|
+
return /* @__PURE__ */ react.default.createElement(react.default.Fragment, null, /* @__PURE__ */ react.default.createElement("canvas", __spreadValues({
|
|
21361
|
+
style: canvasStyle,
|
|
21362
|
+
height: size,
|
|
21363
|
+
width: size,
|
|
21364
|
+
ref: setCanvasRef,
|
|
21365
|
+
role: "img"
|
|
21366
|
+
}, otherProps)), img);
|
|
21367
|
+
});
|
|
21368
|
+
QRCodeCanvas.displayName = "QRCodeCanvas";
|
|
21369
|
+
var QRCodeSVG = react.default.forwardRef(function QRCodeSVG2(props, forwardedRef) {
|
|
21370
|
+
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, [
|
|
21371
|
+
"value",
|
|
21372
|
+
"size",
|
|
21373
|
+
"level",
|
|
21374
|
+
"bgColor",
|
|
21375
|
+
"fgColor",
|
|
21376
|
+
"includeMargin",
|
|
21377
|
+
"minVersion",
|
|
21378
|
+
"boostLevel",
|
|
21379
|
+
"title",
|
|
21380
|
+
"marginSize",
|
|
21381
|
+
"imageSettings"
|
|
21382
|
+
]);
|
|
21383
|
+
const { margin, cells, numCells, calculatedImageSettings } = useQRCode({
|
|
21384
|
+
value,
|
|
21385
|
+
level,
|
|
21386
|
+
minVersion,
|
|
21387
|
+
boostLevel,
|
|
21388
|
+
includeMargin,
|
|
21389
|
+
marginSize,
|
|
21390
|
+
imageSettings,
|
|
21391
|
+
size
|
|
21392
|
+
});
|
|
21393
|
+
let cellsToDraw = cells;
|
|
21394
|
+
let image = null;
|
|
21395
|
+
if (imageSettings != null && calculatedImageSettings != null) {
|
|
21396
|
+
if (calculatedImageSettings.excavation != null) cellsToDraw = excavateModules(cells, calculatedImageSettings.excavation);
|
|
21397
|
+
image = /* @__PURE__ */ react.default.createElement("image", {
|
|
21398
|
+
href: imageSettings.src,
|
|
21399
|
+
height: calculatedImageSettings.h,
|
|
21400
|
+
width: calculatedImageSettings.w,
|
|
21401
|
+
x: calculatedImageSettings.x + margin,
|
|
21402
|
+
y: calculatedImageSettings.y + margin,
|
|
21403
|
+
preserveAspectRatio: "none",
|
|
21404
|
+
opacity: calculatedImageSettings.opacity,
|
|
21405
|
+
crossOrigin: calculatedImageSettings.crossOrigin
|
|
21406
|
+
});
|
|
21407
|
+
}
|
|
21408
|
+
const fgPath = generatePath(cellsToDraw, margin);
|
|
21409
|
+
return /* @__PURE__ */ react.default.createElement("svg", __spreadValues({
|
|
21410
|
+
height: size,
|
|
21411
|
+
width: size,
|
|
21412
|
+
viewBox: `0 0 ${numCells} ${numCells}`,
|
|
21413
|
+
ref: forwardedRef,
|
|
21414
|
+
role: "img"
|
|
21415
|
+
}, otherProps), !!title && /* @__PURE__ */ react.default.createElement("title", null, title), /* @__PURE__ */ react.default.createElement("path", {
|
|
21416
|
+
fill: bgColor,
|
|
21417
|
+
d: `M0,0 h${numCells}v${numCells}H0z`,
|
|
21418
|
+
shapeRendering: "crispEdges"
|
|
21419
|
+
}), /* @__PURE__ */ react.default.createElement("path", {
|
|
21420
|
+
fill: fgColor,
|
|
21421
|
+
d: fgPath,
|
|
21422
|
+
shapeRendering: "crispEdges"
|
|
21423
|
+
}), image);
|
|
21424
|
+
});
|
|
21425
|
+
QRCodeSVG.displayName = "QRCodeSVG";
|
|
21426
|
+
//#endregion
|
|
21427
|
+
//#region src/composites/qr-code.tsx
|
|
21428
|
+
var DEFAULT_SIZE = 192;
|
|
21429
|
+
function QrCode({ value, size = DEFAULT_SIZE, className, alt }) {
|
|
21430
|
+
const trimmed = value.trim();
|
|
21431
|
+
if (trimmed.length === 0) return null;
|
|
21432
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
21433
|
+
className: cn("inline-flex rounded-md bg-white p-2", className),
|
|
21434
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(QRCodeSVG, {
|
|
21435
|
+
value: trimmed,
|
|
21436
|
+
size,
|
|
21437
|
+
marginSize: 1,
|
|
21438
|
+
title: alt ?? "QR code"
|
|
21439
|
+
})
|
|
21440
|
+
});
|
|
21441
|
+
}
|
|
21442
|
+
//#endregion
|
|
21443
|
+
//#region src/composites/copy-button.tsx
|
|
21444
|
+
/**
|
|
21445
|
+
* `CopyButton` — a compact button that copies a string `value` to the
|
|
21446
|
+
* clipboard via `navigator.clipboard.writeText`, showing a brief
|
|
21447
|
+
* "copied" check state. Addon-agnostic; used wherever a secret / URL
|
|
21448
|
+
* needs a one-click copy affordance (export setup panels, etc.).
|
|
21449
|
+
*/
|
|
21450
|
+
var COPIED_RESET_MS = 2e3;
|
|
21451
|
+
function CopyButton({ value, label, className, disabled }) {
|
|
21452
|
+
const [copied, setCopied] = (0, react$1.useState)(false);
|
|
21453
|
+
const handleCopy = (0, react$1.useCallback)(() => {
|
|
21454
|
+
if (!value) return;
|
|
21455
|
+
navigator.clipboard.writeText(value).then(() => {
|
|
21456
|
+
setCopied(true);
|
|
21457
|
+
setTimeout(() => setCopied(false), COPIED_RESET_MS);
|
|
21458
|
+
});
|
|
21459
|
+
}, [value]);
|
|
21460
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Button, {
|
|
21461
|
+
size: "sm",
|
|
21462
|
+
variant: "ghost",
|
|
21463
|
+
type: "button",
|
|
21464
|
+
disabled: disabled || value.length === 0,
|
|
21465
|
+
onClick: handleCopy,
|
|
21466
|
+
className: cn(className),
|
|
21467
|
+
"aria-label": copied ? "Copied" : `Copy ${label ?? "value"}`,
|
|
21468
|
+
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", {
|
|
21469
|
+
className: "ml-1",
|
|
21470
|
+
children: copied ? "Copied" : label
|
|
21471
|
+
}) : null]
|
|
21472
|
+
});
|
|
21473
|
+
}
|
|
21474
|
+
//#endregion
|
|
21475
|
+
//#region src/composites/device-export-panel.tsx
|
|
21476
|
+
/**
|
|
21477
|
+
* DeviceExportPanel — generic, addon-agnostic surface for the
|
|
21478
|
+
* `device-export` capability.
|
|
21479
|
+
*
|
|
21480
|
+
* Renders the COMMON device-export surface for a single export addon
|
|
21481
|
+
* (HomeAssistant via MQTT, HomeKit/HAP, Alexa Smart Home, …):
|
|
21482
|
+
*
|
|
21483
|
+
* - a link-state status badge + exposed-device count from `getStatus`,
|
|
21484
|
+
* - the exposed-devices table from `listExposedDevices` (device name,
|
|
21485
|
+
* status, stream preference) with a per-row unexpose action
|
|
21486
|
+
* (`unexposeDevice`),
|
|
21487
|
+
* - an empty state directing the operator to the device-details page.
|
|
21488
|
+
*
|
|
21489
|
+
* This composite is the reusable replacement for the per-addon
|
|
21490
|
+
* Module-Federation overview tables that each export addon used to
|
|
21491
|
+
* ship. It is driven entirely by the `device-export` cap — there are no
|
|
21492
|
+
* Alexa / HAP / MQTT specifics here. Mount it next to an export addon's
|
|
21493
|
+
* standard settings form (e.g. in the addon-settings modal).
|
|
21494
|
+
*
|
|
21495
|
+
* Routing note: `device-export` is a collection cap. Export addons are
|
|
21496
|
+
* all `hub-only`, so the panel queries `nodeId: 'hub'`. It also passes
|
|
21497
|
+
* `addonId` so the codegen'd cap-router resolves THIS addon's provider
|
|
21498
|
+
* within the local collection — when multiple device-export addons are
|
|
21499
|
+
* co-installed each panel shows its own provider, not provider[0].
|
|
21500
|
+
*/
|
|
21501
|
+
var ExposedDeviceArraySchema = zod.z.array(_camstack_types.ExposedDeviceSchema);
|
|
21502
|
+
var STATUS_POLL_INTERVAL_MS = 1e4;
|
|
21503
|
+
function statusVariant(state) {
|
|
21504
|
+
if (state === "linked") return "success";
|
|
21505
|
+
if (state === "error") return "danger";
|
|
21506
|
+
return "warning";
|
|
21507
|
+
}
|
|
21508
|
+
function capitaliseLinkState(state) {
|
|
21509
|
+
if (state === "linked") return "Linked";
|
|
21510
|
+
if (state === "unlinked") return "Unlinked";
|
|
21511
|
+
if (state === "error") return "Error";
|
|
21512
|
+
return state;
|
|
21513
|
+
}
|
|
21514
|
+
/**
|
|
21515
|
+
* A single label/value row in the Setup section. `secret` rows mask the
|
|
21516
|
+
* value behind a reveal toggle; every row gets a copy button.
|
|
21517
|
+
*/
|
|
21518
|
+
function SetupFieldRow({ field }) {
|
|
21519
|
+
const [revealed, setRevealed] = (0, react$1.useState)(false);
|
|
21520
|
+
const isSecret = field.secret === true;
|
|
21521
|
+
const displayValue = isSecret && !revealed ? "•".repeat(Math.min(field.value.length, 24)) : field.value;
|
|
21522
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
21523
|
+
className: "flex items-center gap-2 py-1.5",
|
|
21524
|
+
children: [
|
|
21525
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
21526
|
+
className: "text-[11px] text-foreground-subtle w-32 shrink-0",
|
|
21527
|
+
children: field.label
|
|
21528
|
+
}),
|
|
21529
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
21530
|
+
className: "flex-1 min-w-0 truncate font-mono text-xs text-foreground",
|
|
21531
|
+
children: displayValue || "—"
|
|
21532
|
+
}),
|
|
21533
|
+
isSecret && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
|
|
21534
|
+
size: "sm",
|
|
21535
|
+
variant: "ghost",
|
|
21536
|
+
type: "button",
|
|
21537
|
+
"aria-label": revealed ? "Hide value" : "Reveal value",
|
|
21538
|
+
onClick: () => setRevealed((v) => !v),
|
|
21539
|
+
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" })
|
|
21540
|
+
}),
|
|
21541
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(CopyButton, {
|
|
21542
|
+
value: field.value,
|
|
21543
|
+
label: field.label
|
|
21544
|
+
})
|
|
21545
|
+
]
|
|
21546
|
+
});
|
|
21547
|
+
}
|
|
21548
|
+
/**
|
|
21549
|
+
* Generic "Setup" section — pairing QR + copyable label/value rows +
|
|
21550
|
+
* operator note. Driven entirely by the cap's `setup` block; renders
|
|
21551
|
+
* nothing addon-specific.
|
|
21552
|
+
*/
|
|
21553
|
+
function SetupSection({ setup }) {
|
|
21554
|
+
const fields = setup.fields ?? [];
|
|
21555
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
21556
|
+
className: "border-b border-border bg-surface-hover/10",
|
|
21557
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
21558
|
+
className: "flex items-center gap-2 px-4 py-2 border-b border-border",
|
|
21559
|
+
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", {
|
|
21560
|
+
className: "text-[11px] font-semibold text-foreground-subtle uppercase tracking-wide",
|
|
21561
|
+
children: "Setup"
|
|
21562
|
+
})]
|
|
21563
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
21564
|
+
className: "flex flex-col gap-3 p-4 sm:flex-row sm:items-start",
|
|
21565
|
+
children: [setup.qr && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
21566
|
+
className: "shrink-0",
|
|
21567
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(QrCode, {
|
|
21568
|
+
value: setup.qr,
|
|
21569
|
+
alt: "Pairing QR code"
|
|
21570
|
+
})
|
|
21571
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
21572
|
+
className: "flex-1 min-w-0",
|
|
21573
|
+
children: [setup.note && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
21574
|
+
className: "text-xs text-foreground-muted whitespace-pre-line mb-2",
|
|
21575
|
+
children: setup.note
|
|
21576
|
+
}), fields.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
21577
|
+
className: "divide-y divide-border-subtle",
|
|
21578
|
+
children: fields.map((field) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SetupFieldRow, { field }, field.label))
|
|
21579
|
+
})]
|
|
21580
|
+
})]
|
|
21581
|
+
})]
|
|
21582
|
+
});
|
|
21583
|
+
}
|
|
21584
|
+
/**
|
|
21585
|
+
* Generic device-export panel. Addon-agnostic — only the `device-export`
|
|
21586
|
+
* cap drives it.
|
|
21587
|
+
*/
|
|
21588
|
+
function DeviceExportPanel({ addonId, onOpenDevice }) {
|
|
21589
|
+
const queryClient = (0, _tanstack_react_query.useQueryClient)();
|
|
21590
|
+
const statusQuery = useDeviceExportGetStatus({
|
|
21591
|
+
nodeId: "hub",
|
|
21592
|
+
addonId
|
|
21593
|
+
}, {
|
|
21594
|
+
refetchInterval: STATUS_POLL_INTERVAL_MS,
|
|
21595
|
+
retry: false
|
|
21596
|
+
});
|
|
21597
|
+
const exposedQuery = useDeviceExportListExposedDevices({
|
|
21598
|
+
nodeId: "hub",
|
|
21599
|
+
addonId
|
|
21600
|
+
}, {
|
|
21601
|
+
refetchInterval: STATUS_POLL_INTERVAL_MS,
|
|
21602
|
+
retry: false
|
|
21603
|
+
});
|
|
21604
|
+
const unexposeMutation = useDeviceExportUnexposeDevice({ onSuccess: () => {
|
|
21605
|
+
queryClient.invalidateQueries({ queryKey: [["deviceExport"]] });
|
|
21606
|
+
} });
|
|
21607
|
+
const status = (0, react$1.useMemo)(() => {
|
|
21608
|
+
const parsed = _camstack_types.DeviceExportStatusSchema.safeParse(statusQuery.data);
|
|
21609
|
+
return parsed.success ? parsed.data : null;
|
|
21610
|
+
}, [statusQuery.data]);
|
|
21611
|
+
const exposed = (0, react$1.useMemo)(() => {
|
|
21612
|
+
const parsed = ExposedDeviceArraySchema.safeParse(exposedQuery.data);
|
|
21613
|
+
return parsed.success ? parsed.data : [];
|
|
21614
|
+
}, [exposedQuery.data]);
|
|
21615
|
+
const linkState = status?.linkState ?? "unlinked";
|
|
21616
|
+
const rows = (0, react$1.useMemo)(() => exposed.map((entry) => ({
|
|
21617
|
+
deviceId: entry.deviceId,
|
|
21618
|
+
displayName: entry.exposedAs ?? `Device ${entry.deviceId}`,
|
|
21619
|
+
streamPreference: "auto",
|
|
21620
|
+
linkState
|
|
21621
|
+
})), [exposed, linkState]);
|
|
21622
|
+
const loading = statusQuery.isLoading || exposedQuery.isLoading;
|
|
21623
|
+
const exposedCount = status?.exposedDeviceCount ?? rows.length;
|
|
21624
|
+
const columns = (0, react$1.useMemo)(() => [
|
|
21625
|
+
{
|
|
21626
|
+
key: "device",
|
|
21627
|
+
header: "Device",
|
|
21628
|
+
render: (row) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
21629
|
+
className: "flex flex-col",
|
|
21630
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
21631
|
+
className: "text-foreground font-medium",
|
|
21632
|
+
children: row.displayName
|
|
21633
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
21634
|
+
className: "text-foreground-subtle text-xs font-mono",
|
|
21635
|
+
children: ["#", row.deviceId]
|
|
21636
|
+
})]
|
|
21637
|
+
})
|
|
21638
|
+
},
|
|
21639
|
+
{
|
|
21640
|
+
key: "status",
|
|
21641
|
+
header: "Status",
|
|
21642
|
+
render: (row) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Badge, {
|
|
21643
|
+
variant: statusVariant(row.linkState),
|
|
21644
|
+
children: capitaliseLinkState(row.linkState)
|
|
21645
|
+
})
|
|
21646
|
+
},
|
|
21647
|
+
{
|
|
21648
|
+
key: "stream",
|
|
21649
|
+
header: "Stream",
|
|
21650
|
+
render: (row) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
21651
|
+
className: "text-xs text-foreground-subtle font-mono",
|
|
21652
|
+
children: row.streamPreference === "auto" ? "Auto" : row.streamPreference
|
|
21653
|
+
})
|
|
21654
|
+
},
|
|
21655
|
+
{
|
|
21656
|
+
key: "actions",
|
|
21657
|
+
header: "",
|
|
21658
|
+
align: "right",
|
|
21659
|
+
render: (row) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
21660
|
+
className: "flex items-center justify-end gap-2",
|
|
21661
|
+
children: [onOpenDevice && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Button, {
|
|
21662
|
+
size: "sm",
|
|
21663
|
+
variant: "ghost",
|
|
21664
|
+
onClick: () => onOpenDevice(row.deviceId),
|
|
21665
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ExternalLink, { className: "h-3.5 w-3.5 mr-1" }), "Open"]
|
|
21666
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Button, {
|
|
21667
|
+
size: "sm",
|
|
21668
|
+
variant: "ghost",
|
|
21669
|
+
disabled: unexposeMutation.isPending,
|
|
21670
|
+
onClick: () => unexposeMutation.mutate({
|
|
21671
|
+
deviceId: row.deviceId,
|
|
21672
|
+
nodeId: "hub",
|
|
21673
|
+
addonId
|
|
21674
|
+
}),
|
|
21675
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Unlink2, { className: "h-3.5 w-3.5 mr-1" }), "Unexpose"]
|
|
21676
|
+
})]
|
|
21677
|
+
})
|
|
21678
|
+
}
|
|
21679
|
+
], [
|
|
21680
|
+
onOpenDevice,
|
|
21681
|
+
unexposeMutation,
|
|
21682
|
+
addonId
|
|
21683
|
+
]);
|
|
21684
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
21685
|
+
className: "rounded-lg border border-border bg-surface overflow-hidden",
|
|
21686
|
+
children: [
|
|
21687
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
21688
|
+
className: "flex items-center justify-between gap-3 px-4 py-2.5 border-b border-border bg-surface-hover/20",
|
|
21689
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
21690
|
+
className: "flex items-center gap-2 min-w-0",
|
|
21691
|
+
children: [
|
|
21692
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Share2, { className: "h-3.5 w-3.5 text-foreground-subtle shrink-0" }),
|
|
21693
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
21694
|
+
className: "text-[11px] font-semibold text-foreground-subtle uppercase tracking-wide",
|
|
21695
|
+
children: "Exported devices"
|
|
21696
|
+
}),
|
|
21697
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Badge, {
|
|
21698
|
+
variant: statusVariant(linkState),
|
|
21699
|
+
children: capitaliseLinkState(linkState)
|
|
21700
|
+
}),
|
|
21701
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
21702
|
+
className: "text-[11px] text-foreground-subtle",
|
|
21703
|
+
children: [exposedCount, " exposed"]
|
|
21704
|
+
})
|
|
21705
|
+
]
|
|
21706
|
+
}), loading && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LoaderCircle, { className: "h-3.5 w-3.5 animate-spin text-foreground-subtle" })]
|
|
21707
|
+
}),
|
|
21708
|
+
status?.error && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
21709
|
+
className: "px-4 py-3 border-b border-border",
|
|
21710
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ErrorBox, { message: status.error })
|
|
21711
|
+
}),
|
|
21712
|
+
status?.setup && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SetupSection, { setup: status.setup }),
|
|
21713
|
+
rows.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(EmptyState, {
|
|
21714
|
+
icon: Share2,
|
|
21715
|
+
title: "No devices exposed",
|
|
21716
|
+
description: `Expose a camera to "${addonId}" from its device-details page to surface it in the connected ecosystem.`
|
|
21717
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
21718
|
+
className: "p-3",
|
|
21719
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DataTable, {
|
|
21720
|
+
columns,
|
|
21721
|
+
rows,
|
|
21722
|
+
rowKey: (row) => row.deviceId
|
|
21723
|
+
})
|
|
21724
|
+
})
|
|
21725
|
+
]
|
|
21726
|
+
});
|
|
21727
|
+
}
|
|
21728
|
+
//#endregion
|
|
20103
21729
|
//#region src/composites/audio-waveform.tsx
|
|
20104
21730
|
/**
|
|
20105
21731
|
* Canvas-based audio waveform visualization.
|
|
@@ -20107,9 +21733,9 @@ function StreamBrokerSelector({ deviceId, value, onChange, disabled, label, clas
|
|
|
20107
21733
|
* Downsamples to pixel resolution for performance.
|
|
20108
21734
|
*/
|
|
20109
21735
|
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)(() => {
|
|
21736
|
+
const canvasRef = (0, react$1.useRef)(null);
|
|
21737
|
+
const containerRef = (0, react$1.useRef)(null);
|
|
21738
|
+
const draw = (0, react$1.useCallback)(() => {
|
|
20113
21739
|
const canvas = canvasRef.current;
|
|
20114
21740
|
const container = containerRef.current;
|
|
20115
21741
|
if (!canvas || !container || !samples || samples.length === 0) return;
|
|
@@ -20161,10 +21787,10 @@ function AudioWaveform({ samples, sampleRate = 16e3, height = 96, className = ""
|
|
|
20161
21787
|
color,
|
|
20162
21788
|
bgColor
|
|
20163
21789
|
]);
|
|
20164
|
-
(0, react.useEffect)(() => {
|
|
21790
|
+
(0, react$1.useEffect)(() => {
|
|
20165
21791
|
draw();
|
|
20166
21792
|
}, [draw]);
|
|
20167
|
-
(0, react.useEffect)(() => {
|
|
21793
|
+
(0, react$1.useEffect)(() => {
|
|
20168
21794
|
const observer = new ResizeObserver(() => draw());
|
|
20169
21795
|
const el = containerRef.current;
|
|
20170
21796
|
if (el) observer.observe(el);
|
|
@@ -20203,10 +21829,10 @@ function AudioWaveform({ samples, sampleRate = 16e3, height = 96, className = ""
|
|
|
20203
21829
|
* (each chunk, ~0.5s, produces one sample via `frame.level.dbfs`).
|
|
20204
21830
|
*/
|
|
20205
21831
|
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)(() => {
|
|
21832
|
+
const canvasRef = (0, react$1.useRef)(null);
|
|
21833
|
+
const containerRef = (0, react$1.useRef)(null);
|
|
21834
|
+
const [samples, setSamples] = (0, react$1.useState)([]);
|
|
21835
|
+
(0, react$1.useEffect)(() => {
|
|
20210
21836
|
if (currentDbfs === null) return;
|
|
20211
21837
|
setSamples((prev) => {
|
|
20212
21838
|
const next = [...prev, {
|
|
@@ -20216,7 +21842,7 @@ function AudioLevelWaveform({ currentDbfs, durationSec = 30, maxSamples = 120, h
|
|
|
20216
21842
|
return next.length > maxSamples ? next.slice(-maxSamples) : next;
|
|
20217
21843
|
});
|
|
20218
21844
|
}, [currentDbfs, maxSamples]);
|
|
20219
|
-
const draw = (0, react.useCallback)(() => {
|
|
21845
|
+
const draw = (0, react$1.useCallback)(() => {
|
|
20220
21846
|
const canvas = canvasRef.current;
|
|
20221
21847
|
const container = containerRef.current;
|
|
20222
21848
|
if (!canvas || !container) return;
|
|
@@ -20269,10 +21895,10 @@ function AudioLevelWaveform({ currentDbfs, durationSec = 30, maxSamples = 120, h
|
|
|
20269
21895
|
clipThreshold,
|
|
20270
21896
|
minDbfs
|
|
20271
21897
|
]);
|
|
20272
|
-
(0, react.useEffect)(() => {
|
|
21898
|
+
(0, react$1.useEffect)(() => {
|
|
20273
21899
|
draw();
|
|
20274
21900
|
}, [draw]);
|
|
20275
|
-
(0, react.useEffect)(() => {
|
|
21901
|
+
(0, react$1.useEffect)(() => {
|
|
20276
21902
|
const observer = new ResizeObserver(() => draw());
|
|
20277
21903
|
const el = containerRef.current;
|
|
20278
21904
|
if (el) observer.observe(el);
|
|
@@ -20394,7 +22020,7 @@ function AudioClassificationList({ classifications, processing = false, inferenc
|
|
|
20394
22020
|
* Expandable log box showing the raw JSON response from a pipeline run.
|
|
20395
22021
|
*/
|
|
20396
22022
|
function ResponseLog({ data, label = "Response", className = "" }) {
|
|
20397
|
-
const [expanded, setExpanded] = (0, react.useState)(false);
|
|
22023
|
+
const [expanded, setExpanded] = (0, react$1.useState)(false);
|
|
20398
22024
|
if (!data) return null;
|
|
20399
22025
|
const json = JSON.stringify(data, null, 2);
|
|
20400
22026
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
@@ -20466,17 +22092,17 @@ function PhaseIcon({ phase, ...props }) {
|
|
|
20466
22092
|
* keeping idle subscriptions alive.
|
|
20467
22093
|
*/
|
|
20468
22094
|
function useLiveBuffer(max) {
|
|
20469
|
-
const [entries, setEntries] = (0, react.useState)([]);
|
|
20470
|
-
const append = (0, react.useCallback)((entry) => {
|
|
22095
|
+
const [entries, setEntries] = (0, react$1.useState)([]);
|
|
22096
|
+
const append = (0, react$1.useCallback)((entry) => {
|
|
20471
22097
|
setEntries((prev) => {
|
|
20472
22098
|
const next = [...prev, entry];
|
|
20473
22099
|
return next.length > max ? next.slice(-max) : next;
|
|
20474
22100
|
});
|
|
20475
22101
|
}, [max]);
|
|
20476
|
-
const reset = (0, react.useCallback)(() => {
|
|
22102
|
+
const reset = (0, react$1.useCallback)(() => {
|
|
20477
22103
|
setEntries([]);
|
|
20478
22104
|
}, []);
|
|
20479
|
-
return (0, react.useMemo)(() => ({
|
|
22105
|
+
return (0, react$1.useMemo)(() => ({
|
|
20480
22106
|
entries,
|
|
20481
22107
|
append,
|
|
20482
22108
|
reset
|
|
@@ -20550,15 +22176,15 @@ function passesLevel(logLevel, filterLevel) {
|
|
|
20550
22176
|
return (LEVEL_SEVERITY[logLevel] ?? 0) >= (LEVEL_SEVERITY[filterLevel] ?? 0);
|
|
20551
22177
|
}
|
|
20552
22178
|
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);
|
|
22179
|
+
const [localAddonId, setLocalAddonId] = (0, react$1.useState)("");
|
|
22180
|
+
const [localDeviceId, setLocalDeviceId] = (0, react$1.useState)("");
|
|
22181
|
+
const [levelFilter, setLevelFilter] = (0, react$1.useState)(initialLevel);
|
|
20556
22182
|
const agentId = propsAgentId;
|
|
20557
22183
|
const addonId = propsAddonId ?? (localAddonId || void 0);
|
|
20558
22184
|
const deviceId = propsDeviceId ?? (localDeviceId ? Number(localDeviceId) : void 0);
|
|
20559
22185
|
const integrationId = propsIntegrationId;
|
|
20560
22186
|
const requestId = propsRequestId;
|
|
20561
|
-
const tags = (0, react.useMemo)(() => {
|
|
22187
|
+
const tags = (0, react$1.useMemo)(() => {
|
|
20562
22188
|
const t = {};
|
|
20563
22189
|
if (agentId) t.agentId = agentId;
|
|
20564
22190
|
if (addonId) t.addonId = addonId;
|
|
@@ -20576,15 +22202,15 @@ function LogStream({ agentId: propsAgentId, addonId: propsAddonId, deviceId: pro
|
|
|
20576
22202
|
const fallbackBuffer = useLiveBuffer(MAX_LIVE_ENTRIES$2);
|
|
20577
22203
|
const buffer = externalBuffer ?? fallbackBuffer;
|
|
20578
22204
|
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);
|
|
22205
|
+
const [clearedAt, setClearedAt] = (0, react$1.useState)(0);
|
|
22206
|
+
const [autoScroll, setAutoScroll] = (0, react$1.useState)(false);
|
|
22207
|
+
const [copied, setCopied] = (0, react$1.useState)(false);
|
|
22208
|
+
const [expandedRows, setExpandedRows] = (0, react$1.useState)(/* @__PURE__ */ new Set());
|
|
22209
|
+
const [searchText, setSearchText] = (0, react$1.useState)("");
|
|
22210
|
+
const scrollRef = (0, react$1.useRef)(null);
|
|
20585
22211
|
const scopeKey = `${agentId ?? ""}:${addonId ?? ""}:${String(deviceId ?? "")}:${integrationId ?? ""}:${requestId ?? ""}`;
|
|
20586
|
-
const prevScopeRef = (0, react.useRef)(scopeKey);
|
|
20587
|
-
(0, react.useEffect)(() => {
|
|
22212
|
+
const prevScopeRef = (0, react$1.useRef)(scopeKey);
|
|
22213
|
+
(0, react$1.useEffect)(() => {
|
|
20588
22214
|
if (prevScopeRef.current !== scopeKey) {
|
|
20589
22215
|
prevScopeRef.current = scopeKey;
|
|
20590
22216
|
buffer.reset();
|
|
@@ -20599,8 +22225,8 @@ function LogStream({ agentId: propsAgentId, addonId: propsAddonId, deviceId: pro
|
|
|
20599
22225
|
trpc.logs.subscribe.useSubscription({ ...tags ? { tags } : {} }, { onData: (entry) => {
|
|
20600
22226
|
buffer.append(entry);
|
|
20601
22227
|
} });
|
|
20602
|
-
const prevLiveCountRef = (0, react.useRef)(liveLogs.length);
|
|
20603
|
-
(0, react.useEffect)(() => {
|
|
22228
|
+
const prevLiveCountRef = (0, react$1.useRef)(liveLogs.length);
|
|
22229
|
+
(0, react$1.useEffect)(() => {
|
|
20604
22230
|
const el = scrollRef.current;
|
|
20605
22231
|
if (!el) {
|
|
20606
22232
|
prevLiveCountRef.current = liveLogs.length;
|
|
@@ -20616,7 +22242,7 @@ function LogStream({ agentId: propsAgentId, addonId: propsAddonId, deviceId: pro
|
|
|
20616
22242
|
el.scrollTop += rowHeight * (liveLogs.length - prevCount);
|
|
20617
22243
|
}
|
|
20618
22244
|
}, [liveLogs.length, autoScroll]);
|
|
20619
|
-
const allLogs = (0, react.useMemo)(() => {
|
|
22245
|
+
const allLogs = (0, react$1.useMemo)(() => {
|
|
20620
22246
|
const initial = (initialLogs ?? []).map((log) => ({
|
|
20621
22247
|
timestamp: log.timestamp,
|
|
20622
22248
|
level: log.level,
|
|
@@ -20661,7 +22287,7 @@ function LogStream({ agentId: propsAgentId, addonId: propsAddonId, deviceId: pro
|
|
|
20661
22287
|
clearedAt,
|
|
20662
22288
|
searchText
|
|
20663
22289
|
]);
|
|
20664
|
-
const handleCopyAll = (0, react.useCallback)(() => {
|
|
22290
|
+
const handleCopyAll = (0, react$1.useCallback)(() => {
|
|
20665
22291
|
const lines = allLogs.map((log) => {
|
|
20666
22292
|
const time = new Date(log.timestamp).toLocaleTimeString();
|
|
20667
22293
|
const tagsStr = log.tags ? " " + Object.entries(log.tags).filter(([, v]) => v).map(([k, v]) => `${k}=${v}`).join(" ") : "";
|
|
@@ -20673,7 +22299,7 @@ function LogStream({ agentId: propsAgentId, addonId: propsAddonId, deviceId: pro
|
|
|
20673
22299
|
});
|
|
20674
22300
|
}, [allLogs]);
|
|
20675
22301
|
const clearMutation = trpc.logs.clear.useMutation();
|
|
20676
|
-
const handleClear = (0, react.useCallback)(() => {
|
|
22302
|
+
const handleClear = (0, react$1.useCallback)(() => {
|
|
20677
22303
|
setClearedAt(Date.now());
|
|
20678
22304
|
buffer.reset();
|
|
20679
22305
|
clearMutation.mutate({ ...tags ? { tags } : {} });
|
|
@@ -20682,7 +22308,7 @@ function LogStream({ agentId: propsAgentId, addonId: propsAddonId, deviceId: pro
|
|
|
20682
22308
|
clearMutation,
|
|
20683
22309
|
tags
|
|
20684
22310
|
]);
|
|
20685
|
-
const toggleRow = (0, react.useCallback)((rowKey) => {
|
|
22311
|
+
const toggleRow = (0, react$1.useCallback)((rowKey) => {
|
|
20686
22312
|
setExpandedRows((prev) => {
|
|
20687
22313
|
const next = new Set(prev);
|
|
20688
22314
|
if (next.has(rowKey)) next.delete(rowKey);
|
|
@@ -20690,8 +22316,8 @@ function LogStream({ agentId: propsAgentId, addonId: propsAddonId, deviceId: pro
|
|
|
20690
22316
|
return next;
|
|
20691
22317
|
});
|
|
20692
22318
|
}, []);
|
|
20693
|
-
const [copiedRowKey, setCopiedRowKey] = (0, react.useState)(null);
|
|
20694
|
-
const copyOne = (0, react.useCallback)((log, key) => {
|
|
22319
|
+
const [copiedRowKey, setCopiedRowKey] = (0, react$1.useState)(null);
|
|
22320
|
+
const copyOne = (0, react$1.useCallback)((log, key) => {
|
|
20695
22321
|
const time = new Date(log.timestamp).toISOString();
|
|
20696
22322
|
const tagsStr = log.tags ? " " + Object.entries(log.tags).filter(([, v]) => v).map(([k, v]) => `${k}=${v}`).join(" ") : "";
|
|
20697
22323
|
const metaStr = log.meta && Object.keys(log.meta).length > 0 ? ` meta=${JSON.stringify(log.meta)}` : "";
|
|
@@ -20701,7 +22327,7 @@ function LogStream({ agentId: propsAgentId, addonId: propsAddonId, deviceId: pro
|
|
|
20701
22327
|
setTimeout(() => setCopiedRowKey((prev) => prev === key ? null : prev), 1200);
|
|
20702
22328
|
});
|
|
20703
22329
|
}, []);
|
|
20704
|
-
const rowKey = (0, react.useCallback)((log) => `${log.timestamp}|${log.level}|${log.scope ?? ""}|${log.message}`, []);
|
|
22330
|
+
const rowKey = (0, react$1.useCallback)((log) => `${log.timestamp}|${log.level}|${log.scope ?? ""}|${log.message}`, []);
|
|
20705
22331
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
20706
22332
|
className: cn("h-full min-h-0 flex flex-col", className),
|
|
20707
22333
|
onClick: (e) => e.stopPropagation(),
|
|
@@ -21266,11 +22892,11 @@ function hasContent(entry) {
|
|
|
21266
22892
|
}
|
|
21267
22893
|
var MAX_LIVE_ENTRIES$1 = 300;
|
|
21268
22894
|
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)(() => {
|
|
22895
|
+
const defaultsArray = (0, react$1.useMemo)(() => defaultCategories ?? legacyCategories ?? DEFAULT_EVENT_CATEGORIES, [defaultCategories, legacyCategories]);
|
|
22896
|
+
const defaultsKey = (0, react$1.useMemo)(() => [...defaultsArray].sort().join(","), [defaultsArray]);
|
|
22897
|
+
const [activeCategories, setActiveCategories] = (0, react$1.useState)(() => new Set(defaultsArray));
|
|
22898
|
+
const prevDefaultsKey = (0, react$1.useRef)(defaultsKey);
|
|
22899
|
+
(0, react$1.useEffect)(() => {
|
|
21274
22900
|
if (prevDefaultsKey.current !== defaultsKey) {
|
|
21275
22901
|
prevDefaultsKey.current = defaultsKey;
|
|
21276
22902
|
setActiveCategories(new Set(defaultsArray));
|
|
@@ -21279,17 +22905,17 @@ function EventStream({ agentId, addonId, deviceId, defaultCategories, categories
|
|
|
21279
22905
|
const fallbackBuffer = useLiveBuffer(MAX_LIVE_ENTRIES$1);
|
|
21280
22906
|
const buffer = externalBuffer ?? fallbackBuffer;
|
|
21281
22907
|
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);
|
|
22908
|
+
const [autoScroll, setAutoScroll] = (0, react$1.useState)(true);
|
|
22909
|
+
const [expandedRows, setExpandedRows] = (0, react$1.useState)(/* @__PURE__ */ new Set());
|
|
22910
|
+
const [searchText, setSearchText] = (0, react$1.useState)("");
|
|
22911
|
+
const [filterOpen, setFilterOpen] = (0, react$1.useState)(false);
|
|
22912
|
+
const [categorySearch, setCategorySearch] = (0, react$1.useState)("");
|
|
22913
|
+
const [clearedAt, setClearedAt] = (0, react$1.useState)(0);
|
|
22914
|
+
const scrollRef = (0, react$1.useRef)(null);
|
|
22915
|
+
const filterRootRef = (0, react$1.useRef)(null);
|
|
21290
22916
|
const scopeKey = `${agentId ?? ""}:${addonId ?? ""}:${String(deviceId ?? "")}:${propsCategory ?? ""}`;
|
|
21291
|
-
const prevScopeRef = (0, react.useRef)(scopeKey);
|
|
21292
|
-
(0, react.useEffect)(() => {
|
|
22917
|
+
const prevScopeRef = (0, react$1.useRef)(scopeKey);
|
|
22918
|
+
(0, react$1.useEffect)(() => {
|
|
21293
22919
|
if (prevScopeRef.current !== scopeKey) {
|
|
21294
22920
|
prevScopeRef.current = scopeKey;
|
|
21295
22921
|
buffer.reset();
|
|
@@ -21297,7 +22923,7 @@ function EventStream({ agentId, addonId, deviceId, defaultCategories, categories
|
|
|
21297
22923
|
setClearedAt(0);
|
|
21298
22924
|
}
|
|
21299
22925
|
}, [scopeKey, buffer]);
|
|
21300
|
-
(0, react.useEffect)(() => {
|
|
22926
|
+
(0, react$1.useEffect)(() => {
|
|
21301
22927
|
if (!filterOpen) return;
|
|
21302
22928
|
const onDocClick = (e) => {
|
|
21303
22929
|
const root = filterRootRef.current;
|
|
@@ -21308,7 +22934,7 @@ function EventStream({ agentId, addonId, deviceId, defaultCategories, categories
|
|
|
21308
22934
|
document.removeEventListener("mousedown", onDocClick);
|
|
21309
22935
|
};
|
|
21310
22936
|
}, [filterOpen]);
|
|
21311
|
-
const scopeInput = (0, react.useMemo)(() => {
|
|
22937
|
+
const scopeInput = (0, react$1.useMemo)(() => {
|
|
21312
22938
|
const s = {};
|
|
21313
22939
|
if (agentId) s.agentId = agentId;
|
|
21314
22940
|
if (addonId) s.addonId = addonId;
|
|
@@ -21321,8 +22947,8 @@ function EventStream({ agentId, addonId, deviceId, defaultCategories, categories
|
|
|
21321
22947
|
deviceId,
|
|
21322
22948
|
propsCategory
|
|
21323
22949
|
]);
|
|
21324
|
-
const activeArray = (0, react.useMemo)(() => [...activeCategories].sort(), [activeCategories]);
|
|
21325
|
-
const getRecentInput = (0, react.useMemo)(() => {
|
|
22950
|
+
const activeArray = (0, react$1.useMemo)(() => [...activeCategories].sort(), [activeCategories]);
|
|
22951
|
+
const getRecentInput = (0, react$1.useMemo)(() => {
|
|
21326
22952
|
const s = {
|
|
21327
22953
|
...scopeInput,
|
|
21328
22954
|
limit
|
|
@@ -21332,12 +22958,12 @@ function EventStream({ agentId, addonId, deviceId, defaultCategories, categories
|
|
|
21332
22958
|
}, [
|
|
21333
22959
|
scopeInput,
|
|
21334
22960
|
limit,
|
|
21335
|
-
(0, react.useMemo)(() => activeArray.join(","), [activeArray]),
|
|
22961
|
+
(0, react$1.useMemo)(() => activeArray.join(","), [activeArray]),
|
|
21336
22962
|
activeArray
|
|
21337
22963
|
]);
|
|
21338
22964
|
const { data: initialEvents, isLoading } = trpc.systemEvents.getRecent.useQuery(getRecentInput, { staleTime: 3e4 });
|
|
21339
|
-
const activeCategoriesRef = (0, react.useRef)(activeCategories);
|
|
21340
|
-
(0, react.useEffect)(() => {
|
|
22965
|
+
const activeCategoriesRef = (0, react$1.useRef)(activeCategories);
|
|
22966
|
+
(0, react$1.useEffect)(() => {
|
|
21341
22967
|
activeCategoriesRef.current = activeCategories;
|
|
21342
22968
|
}, [activeCategories]);
|
|
21343
22969
|
const subInput = scopeInput;
|
|
@@ -21348,8 +22974,8 @@ function EventStream({ agentId, addonId, deviceId, defaultCategories, categories
|
|
|
21348
22974
|
if (!activeCategoriesRef.current.has(entry.category)) return;
|
|
21349
22975
|
buffer.append(entry);
|
|
21350
22976
|
} });
|
|
21351
|
-
const prevLiveCountRef = (0, react.useRef)(liveEvents.length);
|
|
21352
|
-
(0, react.useEffect)(() => {
|
|
22977
|
+
const prevLiveCountRef = (0, react$1.useRef)(liveEvents.length);
|
|
22978
|
+
(0, react$1.useEffect)(() => {
|
|
21353
22979
|
const el = scrollRef.current;
|
|
21354
22980
|
if (!el) {
|
|
21355
22981
|
prevLiveCountRef.current = liveEvents.length;
|
|
@@ -21365,7 +22991,7 @@ function EventStream({ agentId, addonId, deviceId, defaultCategories, categories
|
|
|
21365
22991
|
el.scrollTop += rowHeight * (liveEvents.length - prevCount);
|
|
21366
22992
|
}
|
|
21367
22993
|
}, [liveEvents.length, autoScroll]);
|
|
21368
|
-
const allEvents = (0, react.useMemo)(() => {
|
|
22994
|
+
const allEvents = (0, react$1.useMemo)(() => {
|
|
21369
22995
|
const byId = /* @__PURE__ */ new Map();
|
|
21370
22996
|
for (const e of initialEvents ?? []) byId.set(e.id, e);
|
|
21371
22997
|
for (const e of liveEvents) byId.set(e.id, e);
|
|
@@ -21394,7 +23020,7 @@ function EventStream({ agentId, addonId, deviceId, defaultCategories, categories
|
|
|
21394
23020
|
searchText,
|
|
21395
23021
|
clearedAt
|
|
21396
23022
|
]);
|
|
21397
|
-
const toggleRow = (0, react.useCallback)((id) => {
|
|
23023
|
+
const toggleRow = (0, react$1.useCallback)((id) => {
|
|
21398
23024
|
setExpandedRows((prev) => {
|
|
21399
23025
|
const next = new Set(prev);
|
|
21400
23026
|
if (next.has(id)) next.delete(id);
|
|
@@ -21402,7 +23028,7 @@ function EventStream({ agentId, addonId, deviceId, defaultCategories, categories
|
|
|
21402
23028
|
return next;
|
|
21403
23029
|
});
|
|
21404
23030
|
}, []);
|
|
21405
|
-
const toggleCategory = (0, react.useCallback)((cat) => {
|
|
23031
|
+
const toggleCategory = (0, react$1.useCallback)((cat) => {
|
|
21406
23032
|
setActiveCategories((prev) => {
|
|
21407
23033
|
const next = new Set(prev);
|
|
21408
23034
|
if (next.has(cat)) next.delete(cat);
|
|
@@ -21410,43 +23036,43 @@ function EventStream({ agentId, addonId, deviceId, defaultCategories, categories
|
|
|
21410
23036
|
return next;
|
|
21411
23037
|
});
|
|
21412
23038
|
}, []);
|
|
21413
|
-
const handleReset = (0, react.useCallback)(() => {
|
|
23039
|
+
const handleReset = (0, react$1.useCallback)(() => {
|
|
21414
23040
|
setActiveCategories(new Set(defaultsArray));
|
|
21415
23041
|
setSearchText("");
|
|
21416
23042
|
setClearedAt(0);
|
|
21417
23043
|
}, [defaultsArray]);
|
|
21418
|
-
const handleClear = (0, react.useCallback)(() => {
|
|
23044
|
+
const handleClear = (0, react$1.useCallback)(() => {
|
|
21419
23045
|
setClearedAt(Date.now());
|
|
21420
23046
|
buffer.reset();
|
|
21421
23047
|
}, [buffer]);
|
|
21422
|
-
const [copiedAll, setCopiedAll] = (0, react.useState)(false);
|
|
21423
|
-
const [copiedRowId, setCopiedRowId] = (0, react.useState)(null);
|
|
21424
|
-
const formatEventForCopy = (0, react.useCallback)((event) => {
|
|
23048
|
+
const [copiedAll, setCopiedAll] = (0, react$1.useState)(false);
|
|
23049
|
+
const [copiedRowId, setCopiedRowId] = (0, react$1.useState)(null);
|
|
23050
|
+
const formatEventForCopy = (0, react$1.useCallback)((event) => {
|
|
21425
23051
|
const time = new Date(event.timestamp).toISOString();
|
|
21426
23052
|
const summary = summarizeEvent(event.category, event.data) ?? "";
|
|
21427
23053
|
const summaryStr = summary ? ` ${summary}` : "";
|
|
21428
23054
|
return `${time} [${event.category}]${summaryStr} data=${JSON.stringify(event.data)}`;
|
|
21429
23055
|
}, []);
|
|
21430
|
-
const handleCopyAll = (0, react.useCallback)(() => {
|
|
23056
|
+
const handleCopyAll = (0, react$1.useCallback)(() => {
|
|
21431
23057
|
const lines = allEvents.map(formatEventForCopy);
|
|
21432
23058
|
navigator.clipboard.writeText(lines.join("\n")).then(() => {
|
|
21433
23059
|
setCopiedAll(true);
|
|
21434
23060
|
setTimeout(() => setCopiedAll(false), 1500);
|
|
21435
23061
|
});
|
|
21436
23062
|
}, [allEvents, formatEventForCopy]);
|
|
21437
|
-
const copyOne = (0, react.useCallback)((event) => {
|
|
23063
|
+
const copyOne = (0, react$1.useCallback)((event) => {
|
|
21438
23064
|
navigator.clipboard.writeText(formatEventForCopy(event)).then(() => {
|
|
21439
23065
|
setCopiedRowId(event.id);
|
|
21440
23066
|
setTimeout(() => setCopiedRowId((prev) => prev === event.id ? null : prev), 1200);
|
|
21441
23067
|
});
|
|
21442
23068
|
}, [formatEventForCopy]);
|
|
21443
|
-
const handleSelectAll = (0, react.useCallback)(() => {
|
|
23069
|
+
const handleSelectAll = (0, react$1.useCallback)(() => {
|
|
21444
23070
|
setActiveCategories(new Set(ALL_EVENT_CATEGORIES));
|
|
21445
23071
|
}, []);
|
|
21446
|
-
const handleSelectNone = (0, react.useCallback)(() => {
|
|
23072
|
+
const handleSelectNone = (0, react$1.useCallback)(() => {
|
|
21447
23073
|
setActiveCategories(/* @__PURE__ */ new Set());
|
|
21448
23074
|
}, []);
|
|
21449
|
-
const filteredPopoverCategories = (0, react.useMemo)(() => {
|
|
23075
|
+
const filteredPopoverCategories = (0, react$1.useMemo)(() => {
|
|
21450
23076
|
const needle = categorySearch.trim().toLowerCase();
|
|
21451
23077
|
if (!needle) return ALL_EVENT_CATEGORIES;
|
|
21452
23078
|
return ALL_EVENT_CATEGORIES.filter((c) => c.toLowerCase().includes(needle));
|
|
@@ -21824,8 +23450,8 @@ function DiscoveryPanel({ deviceId, className = "", onOpenChild }) {
|
|
|
21824
23450
|
const releaseMutation = trpc.deviceDiscovery.releaseDevice.useMutation({ onSuccess: () => {
|
|
21825
23451
|
utils.deviceDiscovery.listDiscovered.invalidate({ deviceId });
|
|
21826
23452
|
} });
|
|
21827
|
-
const [busyChildId, setBusyChildId] = (0, react.useState)(null);
|
|
21828
|
-
const { available, adopted } = (0, react.useMemo)(() => {
|
|
23453
|
+
const [busyChildId, setBusyChildId] = (0, react$1.useState)(null);
|
|
23454
|
+
const { available, adopted } = (0, react$1.useMemo)(() => {
|
|
21829
23455
|
const list = listQuery.data ?? [];
|
|
21830
23456
|
const sortKey = (c) => typeof c.metadata.rtspChannel === "number" ? c.metadata.rtspChannel : Number.POSITIVE_INFINITY;
|
|
21831
23457
|
const byChannel = (a, b) => {
|
|
@@ -22104,20 +23730,20 @@ var MAX_LIVE_ENTRIES = 300;
|
|
|
22104
23730
|
*/
|
|
22105
23731
|
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
23732
|
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);
|
|
23733
|
+
const [activeCaps, setActiveCaps] = (0, react$1.useState)((0, react$1.useMemo)(() => new Set(defaultCaps ?? []), [defaultCaps]));
|
|
23734
|
+
const [searchText, setSearchText] = (0, react$1.useState)("");
|
|
23735
|
+
const [autoScroll, setAutoScroll] = (0, react$1.useState)(true);
|
|
23736
|
+
const [expandedRows, setExpandedRows] = (0, react$1.useState)(/* @__PURE__ */ new Set());
|
|
23737
|
+
const [clearedAt, setClearedAt] = (0, react$1.useState)(0);
|
|
23738
|
+
const [filterOpen, setFilterOpen] = (0, react$1.useState)(false);
|
|
23739
|
+
const [filterSearch, setFilterSearch] = (0, react$1.useState)("");
|
|
23740
|
+
const filterRootRef = (0, react$1.useRef)(null);
|
|
22115
23741
|
const fallbackBuffer = useLiveBuffer(MAX_LIVE_ENTRIES);
|
|
22116
23742
|
const buffer = externalBuffer ?? fallbackBuffer;
|
|
22117
23743
|
const liveEvents = buffer.entries;
|
|
22118
|
-
const scrollRef = (0, react.useRef)(null);
|
|
22119
|
-
const prevDeviceRef = (0, react.useRef)(deviceId);
|
|
22120
|
-
(0, react.useEffect)(() => {
|
|
23744
|
+
const scrollRef = (0, react$1.useRef)(null);
|
|
23745
|
+
const prevDeviceRef = (0, react$1.useRef)(deviceId);
|
|
23746
|
+
(0, react$1.useEffect)(() => {
|
|
22121
23747
|
if (prevDeviceRef.current !== deviceId) {
|
|
22122
23748
|
prevDeviceRef.current = deviceId;
|
|
22123
23749
|
buffer.reset();
|
|
@@ -22125,14 +23751,14 @@ function StateValuesStream({ deviceId, defaultCaps, maxHeight = "max-h-96", limi
|
|
|
22125
23751
|
setClearedAt(0);
|
|
22126
23752
|
}
|
|
22127
23753
|
}, [deviceId, buffer]);
|
|
22128
|
-
const recentInput = (0, react.useMemo)(() => ({
|
|
23754
|
+
const recentInput = (0, react$1.useMemo)(() => ({
|
|
22129
23755
|
deviceId,
|
|
22130
23756
|
category: _camstack_types.EventCategory.DeviceStateChanged,
|
|
22131
23757
|
limit
|
|
22132
23758
|
}), [deviceId, limit]);
|
|
22133
23759
|
const { data: initialEvents, isLoading } = trpc.systemEvents.getRecent.useQuery(recentInput, { staleTime: 3e4 });
|
|
22134
|
-
const activeCapsRef = (0, react.useRef)(activeCaps);
|
|
22135
|
-
(0, react.useEffect)(() => {
|
|
23760
|
+
const activeCapsRef = (0, react$1.useRef)(activeCaps);
|
|
23761
|
+
(0, react$1.useEffect)(() => {
|
|
22136
23762
|
activeCapsRef.current = activeCaps;
|
|
22137
23763
|
}, [activeCaps]);
|
|
22138
23764
|
trpc.systemEvents.subscribe.useSubscription({
|
|
@@ -22146,8 +23772,8 @@ function StateValuesStream({ deviceId, defaultCaps, maxHeight = "max-h-96", limi
|
|
|
22146
23772
|
if (active.size > 0 && !active.has(entry.capName)) return;
|
|
22147
23773
|
buffer.append(entry);
|
|
22148
23774
|
} });
|
|
22149
|
-
const prevLiveCountRef = (0, react.useRef)(liveEvents.length);
|
|
22150
|
-
(0, react.useEffect)(() => {
|
|
23775
|
+
const prevLiveCountRef = (0, react$1.useRef)(liveEvents.length);
|
|
23776
|
+
(0, react$1.useEffect)(() => {
|
|
22151
23777
|
const el = scrollRef.current;
|
|
22152
23778
|
if (!el) {
|
|
22153
23779
|
prevLiveCountRef.current = liveEvents.length;
|
|
@@ -22164,7 +23790,7 @@ function StateValuesStream({ deviceId, defaultCaps, maxHeight = "max-h-96", limi
|
|
|
22164
23790
|
el.scrollTop += rowHeight * newCount;
|
|
22165
23791
|
}
|
|
22166
23792
|
}, [liveEvents.length, autoScroll]);
|
|
22167
|
-
const allEntries = (0, react.useMemo)(() => {
|
|
23793
|
+
const allEntries = (0, react$1.useMemo)(() => {
|
|
22168
23794
|
const byId = /* @__PURE__ */ new Map();
|
|
22169
23795
|
for (const e of initialEvents ?? []) {
|
|
22170
23796
|
const entry = toEntry(e);
|
|
@@ -22196,7 +23822,7 @@ function StateValuesStream({ deviceId, defaultCaps, maxHeight = "max-h-96", limi
|
|
|
22196
23822
|
searchText,
|
|
22197
23823
|
clearedAt
|
|
22198
23824
|
]);
|
|
22199
|
-
const visibleCaps = (0, react.useMemo)(() => {
|
|
23825
|
+
const visibleCaps = (0, react$1.useMemo)(() => {
|
|
22200
23826
|
const caps = new Set(ALL_DEVICE_CAP_NAMES);
|
|
22201
23827
|
for (const e of initialEvents ?? []) {
|
|
22202
23828
|
const entry = toEntry(e);
|
|
@@ -22205,7 +23831,7 @@ function StateValuesStream({ deviceId, defaultCaps, maxHeight = "max-h-96", limi
|
|
|
22205
23831
|
for (const e of liveEvents) caps.add(e.capName);
|
|
22206
23832
|
return [...caps].sort();
|
|
22207
23833
|
}, [initialEvents, liveEvents]);
|
|
22208
|
-
const toggleRow = (0, react.useCallback)((id) => {
|
|
23834
|
+
const toggleRow = (0, react$1.useCallback)((id) => {
|
|
22209
23835
|
setExpandedRows((prev) => {
|
|
22210
23836
|
const next = new Set(prev);
|
|
22211
23837
|
if (next.has(id)) next.delete(id);
|
|
@@ -22213,7 +23839,7 @@ function StateValuesStream({ deviceId, defaultCaps, maxHeight = "max-h-96", limi
|
|
|
22213
23839
|
return next;
|
|
22214
23840
|
});
|
|
22215
23841
|
}, []);
|
|
22216
|
-
const toggleCap = (0, react.useCallback)((cap) => {
|
|
23842
|
+
const toggleCap = (0, react$1.useCallback)((cap) => {
|
|
22217
23843
|
setActiveCaps((prev) => {
|
|
22218
23844
|
const next = new Set(prev);
|
|
22219
23845
|
if (next.has(cap)) next.delete(cap);
|
|
@@ -22221,39 +23847,39 @@ function StateValuesStream({ deviceId, defaultCaps, maxHeight = "max-h-96", limi
|
|
|
22221
23847
|
return next;
|
|
22222
23848
|
});
|
|
22223
23849
|
}, []);
|
|
22224
|
-
const handleReset = (0, react.useCallback)(() => {
|
|
23850
|
+
const handleReset = (0, react$1.useCallback)(() => {
|
|
22225
23851
|
setActiveCaps(new Set(defaultCaps ?? []));
|
|
22226
23852
|
setSearchText("");
|
|
22227
23853
|
}, [defaultCaps]);
|
|
22228
|
-
const handleClear = (0, react.useCallback)(() => {
|
|
23854
|
+
const handleClear = (0, react$1.useCallback)(() => {
|
|
22229
23855
|
setClearedAt(Date.now());
|
|
22230
23856
|
buffer.reset();
|
|
22231
23857
|
}, [buffer]);
|
|
22232
|
-
const [copiedAll, setCopiedAll] = (0, react.useState)(false);
|
|
22233
|
-
const [copiedRowId, setCopiedRowId] = (0, react.useState)(null);
|
|
22234
|
-
const formatEntryForCopy = (0, react.useCallback)((entry) => {
|
|
23858
|
+
const [copiedAll, setCopiedAll] = (0, react$1.useState)(false);
|
|
23859
|
+
const [copiedRowId, setCopiedRowId] = (0, react$1.useState)(null);
|
|
23860
|
+
const formatEntryForCopy = (0, react$1.useCallback)((entry) => {
|
|
22235
23861
|
return `${new Date(entry.timestamp).toISOString()} [${entry.capName}] slice=${JSON.stringify(entry.slice)}`;
|
|
22236
23862
|
}, []);
|
|
22237
|
-
const handleCopyAll = (0, react.useCallback)(() => {
|
|
23863
|
+
const handleCopyAll = (0, react$1.useCallback)(() => {
|
|
22238
23864
|
const lines = allEntries.map(formatEntryForCopy);
|
|
22239
23865
|
navigator.clipboard.writeText(lines.join("\n")).then(() => {
|
|
22240
23866
|
setCopiedAll(true);
|
|
22241
23867
|
setTimeout(() => setCopiedAll(false), 1500);
|
|
22242
23868
|
});
|
|
22243
23869
|
}, [allEntries, formatEntryForCopy]);
|
|
22244
|
-
const copyOne = (0, react.useCallback)((entry) => {
|
|
23870
|
+
const copyOne = (0, react$1.useCallback)((entry) => {
|
|
22245
23871
|
navigator.clipboard.writeText(formatEntryForCopy(entry)).then(() => {
|
|
22246
23872
|
setCopiedRowId(entry.id);
|
|
22247
23873
|
setTimeout(() => setCopiedRowId((prev) => prev === entry.id ? null : prev), 1200);
|
|
22248
23874
|
});
|
|
22249
23875
|
}, [formatEntryForCopy]);
|
|
22250
|
-
const handleSelectAllCaps = (0, react.useCallback)(() => {
|
|
23876
|
+
const handleSelectAllCaps = (0, react$1.useCallback)(() => {
|
|
22251
23877
|
setActiveCaps(new Set(visibleCaps));
|
|
22252
23878
|
}, [visibleCaps]);
|
|
22253
|
-
const handleSelectNoCaps = (0, react.useCallback)(() => {
|
|
23879
|
+
const handleSelectNoCaps = (0, react$1.useCallback)(() => {
|
|
22254
23880
|
setActiveCaps(/* @__PURE__ */ new Set());
|
|
22255
23881
|
}, []);
|
|
22256
|
-
const filteredPopoverCaps = (0, react.useMemo)(() => {
|
|
23882
|
+
const filteredPopoverCaps = (0, react$1.useMemo)(() => {
|
|
22257
23883
|
const needle = filterSearch.trim().toLowerCase();
|
|
22258
23884
|
if (!needle) return visibleCaps;
|
|
22259
23885
|
return visibleCaps.filter((c) => c.toLowerCase().includes(needle));
|
|
@@ -22262,7 +23888,7 @@ function StateValuesStream({ deviceId, defaultCaps, maxHeight = "max-h-96", limi
|
|
|
22262
23888
|
const totalActive = activeCaps.size;
|
|
22263
23889
|
const allSelected = totalActive === 0 || totalActive === totalAvailable;
|
|
22264
23890
|
const filterLabel = allSelected ? "All" : `${totalActive}/${totalAvailable}`;
|
|
22265
|
-
(0, react.useEffect)(() => {
|
|
23891
|
+
(0, react$1.useEffect)(() => {
|
|
22266
23892
|
if (!filterOpen) return;
|
|
22267
23893
|
const onDocClick = (e) => {
|
|
22268
23894
|
const root = filterRootRef.current;
|
|
@@ -22622,14 +24248,14 @@ var TABS = [
|
|
|
22622
24248
|
}
|
|
22623
24249
|
];
|
|
22624
24250
|
function DeviceActivityPanel({ deviceId, defaultEventCategories, defaultStateCaps, initialTab = "events", className, maxHeight = "max-h-96" }) {
|
|
22625
|
-
const [tab, setTab] = (0, react.useState)(initialTab);
|
|
24251
|
+
const [tab, setTab] = (0, react$1.useState)(initialTab);
|
|
22626
24252
|
const logsBuffer = useLiveBuffer(PANEL_BUFFER_SIZE);
|
|
22627
24253
|
const eventsBuffer = useLiveBuffer(PANEL_BUFFER_SIZE);
|
|
22628
24254
|
const stateBuffer = useLiveBuffer(PANEL_BUFFER_SIZE);
|
|
22629
24255
|
const logsReset = logsBuffer.reset;
|
|
22630
24256
|
const eventsReset = eventsBuffer.reset;
|
|
22631
24257
|
const stateReset = stateBuffer.reset;
|
|
22632
|
-
(0, react.useEffect)(() => {
|
|
24258
|
+
(0, react$1.useEffect)(() => {
|
|
22633
24259
|
logsReset();
|
|
22634
24260
|
eventsReset();
|
|
22635
24261
|
stateReset();
|
|
@@ -22693,9 +24319,9 @@ function DeviceActivityPanel({ deviceId, defaultEventCategories, defaultStateCap
|
|
|
22693
24319
|
* for reboot, RefreshCw for restart).
|
|
22694
24320
|
*/
|
|
22695
24321
|
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);
|
|
24322
|
+
const [open, setOpen] = (0, react$1.useState)(false);
|
|
24323
|
+
const [running, setRunning] = (0, react$1.useState)(false);
|
|
24324
|
+
const [error, setError] = (0, react$1.useState)(null);
|
|
22699
24325
|
const handleConfirm = async () => {
|
|
22700
24326
|
setError(null);
|
|
22701
24327
|
setRunning(true);
|
|
@@ -22774,9 +24400,9 @@ function ConfirmActionButton({ label, icon: Icon, title = "Confirm action", desc
|
|
|
22774
24400
|
* release (`startContinuous` + `stopContinuous` on pointer up).
|
|
22775
24401
|
*/
|
|
22776
24402
|
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) => {
|
|
24403
|
+
const [pressedAt, setPressedAt] = (0, react$1.useState)(null);
|
|
24404
|
+
const [continuous, setContinuous] = (0, react$1.useState)(false);
|
|
24405
|
+
const handlePointerDown = (0, react$1.useCallback)((e) => {
|
|
22780
24406
|
if (disabled) return;
|
|
22781
24407
|
e.currentTarget.setPointerCapture(e.pointerId);
|
|
22782
24408
|
setPressedAt(Date.now());
|
|
@@ -22791,7 +24417,7 @@ function DPadButton({ direction, icon: Icon, disabled, className, variant, onMov
|
|
|
22791
24417
|
disabled,
|
|
22792
24418
|
onStart
|
|
22793
24419
|
]);
|
|
22794
|
-
const handlePointerUp = (0, react.useCallback)((e) => {
|
|
24420
|
+
const handlePointerUp = (0, react$1.useCallback)((e) => {
|
|
22795
24421
|
const timerId = Number(e.currentTarget.dataset.timer);
|
|
22796
24422
|
if (timerId) clearTimeout(timerId);
|
|
22797
24423
|
e.currentTarget.dataset.timer = "";
|
|
@@ -22806,7 +24432,7 @@ function DPadButton({ direction, icon: Icon, disabled, className, variant, onMov
|
|
|
22806
24432
|
onStop,
|
|
22807
24433
|
pressedAt
|
|
22808
24434
|
]);
|
|
22809
|
-
const handlePointerCancel = (0, react.useCallback)((e) => {
|
|
24435
|
+
const handlePointerCancel = (0, react$1.useCallback)((e) => {
|
|
22810
24436
|
const timerId = Number(e.currentTarget.dataset.timer);
|
|
22811
24437
|
if (timerId) clearTimeout(timerId);
|
|
22812
24438
|
e.currentTarget.dataset.timer = "";
|
|
@@ -22829,7 +24455,7 @@ function DPadButton({ direction, icon: Icon, disabled, className, variant, onMov
|
|
|
22829
24455
|
}
|
|
22830
24456
|
function PTZOverlay({ controls, mode = "overlay", showPresets, showZoom = true, showHome = true, className }) {
|
|
22831
24457
|
const { move, startContinuous, stopContinuous, zoom, goHome, goToPreset, presets, busy, error } = controls;
|
|
22832
|
-
const [presetsOpen, setPresetsOpen] = (0, react.useState)(false);
|
|
24458
|
+
const [presetsOpen, setPresetsOpen] = (0, react$1.useState)(false);
|
|
22833
24459
|
const presetsVisible = (showPresets ?? presets.length > 0) && presets.length > 0;
|
|
22834
24460
|
const isPanel = mode === "panel";
|
|
22835
24461
|
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 +24608,11 @@ function downloadDataUrl(filename, dataUrl) {
|
|
|
22982
24608
|
document.body.removeChild(link);
|
|
22983
24609
|
}
|
|
22984
24610
|
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);
|
|
24611
|
+
const [busy, setBusy] = (0, react$1.useState)(false);
|
|
24612
|
+
const [done, setDone] = (0, react$1.useState)(false);
|
|
24613
|
+
const [error, setError] = (0, react$1.useState)(null);
|
|
22988
24614
|
const safeName = deviceName.replace(/[^a-zA-Z0-9_.-]+/g, "_");
|
|
22989
|
-
const fetchSnapshot = (0, react.useCallback)(async (action) => {
|
|
24615
|
+
const fetchSnapshot = (0, react$1.useCallback)(async (action) => {
|
|
22990
24616
|
setBusy(true);
|
|
22991
24617
|
setError(null);
|
|
22992
24618
|
setDone(false);
|
|
@@ -23019,8 +24645,8 @@ function SnapshotButton({ trpc, deviceId, deviceName, size = "sm", className })
|
|
|
23019
24645
|
safeName
|
|
23020
24646
|
]);
|
|
23021
24647
|
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);
|
|
24648
|
+
const [pressTimer, setPressTimer] = (0, react$1.useState)(null);
|
|
24649
|
+
const [longPressed, setLongPressed] = (0, react$1.useState)(false);
|
|
23024
24650
|
const handlePointerDown = () => {
|
|
23025
24651
|
setLongPressed(false);
|
|
23026
24652
|
setPressTimer(setTimeout(() => {
|
|
@@ -23127,7 +24753,7 @@ function DoorbellRecentPanel({ history, limit = 5, latestIsFresh, className }) {
|
|
|
23127
24753
|
* touch devices, no extra wiring needed.
|
|
23128
24754
|
*/
|
|
23129
24755
|
function KebabMenu({ items, header, triggerClassName, title = "More actions" }) {
|
|
23130
|
-
const [open, setOpen] = (0, react.useState)(false);
|
|
24756
|
+
const [open, setOpen] = (0, react$1.useState)(false);
|
|
23131
24757
|
const visible = items.filter((i) => !i.hidden);
|
|
23132
24758
|
if (visible.length === 0) return null;
|
|
23133
24759
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Popover, {
|
|
@@ -23269,19 +24895,19 @@ function clampedAccessForRow(row, parent) {
|
|
|
23269
24895
|
function ScopePicker({ value, onChange, clampToParent, emptyHint }) {
|
|
23270
24896
|
const { data: addons } = useAddonsList();
|
|
23271
24897
|
const { data: devices } = useDeviceManagerListAll({});
|
|
23272
|
-
const addonChoices = (0, react.useMemo)(() => (addons ?? []).map((a) => ({
|
|
24898
|
+
const addonChoices = (0, react$1.useMemo)(() => (addons ?? []).map((a) => ({
|
|
23273
24899
|
value: a.manifest.id,
|
|
23274
24900
|
label: a.manifest.id
|
|
23275
24901
|
})).sort((a, b) => a.label.localeCompare(b.label)), [addons]);
|
|
23276
|
-
const capChoices = (0, react.useMemo)(() => [..._camstack_types.KNOWN_CAP_NAMES].sort().map((c) => ({
|
|
24902
|
+
const capChoices = (0, react$1.useMemo)(() => [..._camstack_types.KNOWN_CAP_NAMES].sort().map((c) => ({
|
|
23277
24903
|
value: c,
|
|
23278
24904
|
label: c
|
|
23279
24905
|
})), []);
|
|
23280
|
-
const deviceChoices = (0, react.useMemo)(() => (devices ?? []).map((d) => ({
|
|
24906
|
+
const deviceChoices = (0, react$1.useMemo)(() => (devices ?? []).map((d) => ({
|
|
23281
24907
|
value: String(d.id),
|
|
23282
24908
|
label: `${d.name} (#${d.id} · ${d.addonId})`
|
|
23283
24909
|
})).sort((a, b) => a.label.localeCompare(b.label)), [devices]);
|
|
23284
|
-
const parentDeviceClamp = (0, react.useMemo)(() => clampToParent == null ? null : parentDeviceTargets(clampToParent), [clampToParent]);
|
|
24910
|
+
const parentDeviceClamp = (0, react$1.useMemo)(() => clampToParent == null ? null : parentDeviceTargets(clampToParent), [clampToParent]);
|
|
23285
24911
|
/**
|
|
23286
24912
|
* Build a fresh scope row when `type` changes. The discriminated union
|
|
23287
24913
|
* forces us to re-construct the object per variant so the resulting
|
|
@@ -23448,8 +25074,8 @@ function ScopePicker({ value, onChange, clampToParent, emptyHint }) {
|
|
|
23448
25074
|
});
|
|
23449
25075
|
}
|
|
23450
25076
|
function DeviceTargetPicker({ value, choices, clampToParent, onChange }) {
|
|
23451
|
-
const [pendingAdd, setPendingAdd] = (0, react.useState)("");
|
|
23452
|
-
const visibleChoices = (0, react.useMemo)(() => {
|
|
25077
|
+
const [pendingAdd, setPendingAdd] = (0, react$1.useState)("");
|
|
25078
|
+
const visibleChoices = (0, react$1.useMemo)(() => {
|
|
23453
25079
|
const filtered = clampToParent == null ? choices : choices.filter((c) => clampToParent.includes(c.value));
|
|
23454
25080
|
const taken = new Set(value);
|
|
23455
25081
|
return filtered.filter((c) => !taken.has(c.value));
|
|
@@ -23545,11 +25171,11 @@ function validateScopes(scopes) {
|
|
|
23545
25171
|
*/
|
|
23546
25172
|
var ZoneEditingContext = createSharedContext("camstack:zone-editing", null);
|
|
23547
25173
|
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) => {
|
|
25174
|
+
const [editing, setEditingRaw] = (0, react$1.useState)(false);
|
|
25175
|
+
const [drawingKind, setDrawingKindRaw] = (0, react$1.useState)(null);
|
|
25176
|
+
const [selectedZoneId, setSelectedZoneIdRaw] = (0, react$1.useState)(null);
|
|
25177
|
+
const [editingDraft, setEditingDraftRaw] = (0, react$1.useState)(null);
|
|
25178
|
+
const setEditing = (0, react$1.useCallback)((next) => {
|
|
23553
25179
|
setEditingRaw(next);
|
|
23554
25180
|
if (!next) {
|
|
23555
25181
|
setDrawingKindRaw(null);
|
|
@@ -23557,38 +25183,38 @@ function ZoneEditingProvider({ children }) {
|
|
|
23557
25183
|
setEditingDraftRaw(null);
|
|
23558
25184
|
}
|
|
23559
25185
|
}, []);
|
|
23560
|
-
const setDrawingKind = (0, react.useCallback)((kind) => {
|
|
25186
|
+
const setDrawingKind = (0, react$1.useCallback)((kind) => {
|
|
23561
25187
|
setDrawingKindRaw(kind);
|
|
23562
25188
|
}, []);
|
|
23563
|
-
const setSelectedZoneId = (0, react.useCallback)((id) => {
|
|
25189
|
+
const setSelectedZoneId = (0, react$1.useCallback)((id) => {
|
|
23564
25190
|
setSelectedZoneIdRaw(id);
|
|
23565
25191
|
}, []);
|
|
23566
|
-
const startDrawing = (0, react.useCallback)((kind) => {
|
|
25192
|
+
const startDrawing = (0, react$1.useCallback)((kind) => {
|
|
23567
25193
|
setEditingRaw(true);
|
|
23568
25194
|
setSelectedZoneIdRaw(null);
|
|
23569
25195
|
setDrawingKindRaw(kind);
|
|
23570
25196
|
setEditingDraftRaw(null);
|
|
23571
25197
|
}, []);
|
|
23572
|
-
const exitEditing = (0, react.useCallback)(() => {
|
|
25198
|
+
const exitEditing = (0, react$1.useCallback)(() => {
|
|
23573
25199
|
setEditingRaw(false);
|
|
23574
25200
|
setDrawingKindRaw(null);
|
|
23575
25201
|
setSelectedZoneIdRaw(null);
|
|
23576
25202
|
setEditingDraftRaw(null);
|
|
23577
25203
|
}, []);
|
|
23578
|
-
const enterDraft = (0, react.useCallback)((draft) => {
|
|
25204
|
+
const enterDraft = (0, react$1.useCallback)((draft) => {
|
|
23579
25205
|
setSelectedZoneIdRaw(draft.id);
|
|
23580
25206
|
setEditingDraftRaw(draft);
|
|
23581
25207
|
}, []);
|
|
23582
|
-
const updateDraft = (0, react.useCallback)((patch) => {
|
|
25208
|
+
const updateDraft = (0, react$1.useCallback)((patch) => {
|
|
23583
25209
|
setEditingDraftRaw((prev) => prev === null ? prev : {
|
|
23584
25210
|
...prev,
|
|
23585
25211
|
...patch
|
|
23586
25212
|
});
|
|
23587
25213
|
}, []);
|
|
23588
|
-
const discardDraft = (0, react.useCallback)(() => {
|
|
25214
|
+
const discardDraft = (0, react$1.useCallback)(() => {
|
|
23589
25215
|
setEditingDraftRaw(null);
|
|
23590
25216
|
}, []);
|
|
23591
|
-
const value = (0, react.useMemo)(() => ({
|
|
25217
|
+
const value = (0, react$1.useMemo)(() => ({
|
|
23592
25218
|
editing,
|
|
23593
25219
|
drawingKind,
|
|
23594
25220
|
selectedZoneId,
|
|
@@ -23624,7 +25250,7 @@ function ZoneEditingProvider({ children }) {
|
|
|
23624
25250
|
* provider so callers that mount in pages without zones (e.g. a
|
|
23625
25251
|
* shared hero on a non-camera device) can no-op gracefully. */
|
|
23626
25252
|
function useZoneEditing() {
|
|
23627
|
-
return (0, react.useContext)(ZoneEditingContext);
|
|
25253
|
+
return (0, react$1.useContext)(ZoneEditingContext);
|
|
23628
25254
|
}
|
|
23629
25255
|
//#endregion
|
|
23630
25256
|
//#region src/hooks/use-device-detections.ts
|
|
@@ -23652,14 +25278,14 @@ function matchesDevice(source, deviceId) {
|
|
|
23652
25278
|
return source?.id === deviceId;
|
|
23653
25279
|
}
|
|
23654
25280
|
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)(() => {
|
|
25281
|
+
const [motion, setMotion] = (0, react$1.useState)(null);
|
|
25282
|
+
const [motionRaw, setMotionRaw] = (0, react$1.useState)(null);
|
|
25283
|
+
const [detection, setDetection] = (0, react$1.useState)(null);
|
|
25284
|
+
const [phase, setPhase] = (0, react$1.useState)("watching");
|
|
25285
|
+
const motionTimer = (0, react$1.useRef)(void 0);
|
|
25286
|
+
const motionRawTimer = (0, react$1.useRef)(void 0);
|
|
25287
|
+
const detectionTimer = (0, react$1.useRef)(void 0);
|
|
25288
|
+
(0, react$1.useEffect)(() => {
|
|
23663
25289
|
if (deviceId === null) return;
|
|
23664
25290
|
const sub = safeSubscribe(trpc, "detection.motion-analysis", (event) => {
|
|
23665
25291
|
const e = event;
|
|
@@ -23682,7 +25308,7 @@ function useDeviceDetections(trpc, deviceId) {
|
|
|
23682
25308
|
if (motionTimer.current) clearTimeout(motionTimer.current);
|
|
23683
25309
|
};
|
|
23684
25310
|
}, [trpc, deviceId]);
|
|
23685
|
-
(0, react.useEffect)(() => {
|
|
25311
|
+
(0, react$1.useEffect)(() => {
|
|
23686
25312
|
if (deviceId === null) return;
|
|
23687
25313
|
const sub = safeSubscribe(trpc, "detection.motion-zones-raw", (event) => {
|
|
23688
25314
|
const e = event;
|
|
@@ -23706,7 +25332,7 @@ function useDeviceDetections(trpc, deviceId) {
|
|
|
23706
25332
|
if (motionRawTimer.current) clearTimeout(motionRawTimer.current);
|
|
23707
25333
|
};
|
|
23708
25334
|
}, [trpc, deviceId]);
|
|
23709
|
-
(0, react.useEffect)(() => {
|
|
25335
|
+
(0, react$1.useEffect)(() => {
|
|
23710
25336
|
if (deviceId === null) return;
|
|
23711
25337
|
const sub = safeSubscribe(trpc, "detection.result", (event) => {
|
|
23712
25338
|
const e = event;
|
|
@@ -23726,7 +25352,7 @@ function useDeviceDetections(trpc, deviceId) {
|
|
|
23726
25352
|
if (detectionTimer.current) clearTimeout(detectionTimer.current);
|
|
23727
25353
|
};
|
|
23728
25354
|
}, [trpc, deviceId]);
|
|
23729
|
-
(0, react.useEffect)(() => {
|
|
25355
|
+
(0, react$1.useEffect)(() => {
|
|
23730
25356
|
if (deviceId === null) return;
|
|
23731
25357
|
const sub = safeSubscribe(trpc, "detection.phase-transition", (event) => {
|
|
23732
25358
|
const e = event;
|
|
@@ -23763,8 +25389,8 @@ function useDeviceDetections(trpc, deviceId) {
|
|
|
23763
25389
|
* @param pollIntervalMs - how often to refresh profile slots (default: 5000)
|
|
23764
25390
|
*/
|
|
23765
25391
|
function useDeviceWebrtc(trpc, deviceId, pollIntervalMs = 5e3) {
|
|
23766
|
-
const [remoteStreams, setRemoteStreams] = (0, react.useState)([]);
|
|
23767
|
-
(0, react.useEffect)(() => {
|
|
25392
|
+
const [remoteStreams, setRemoteStreams] = (0, react$1.useState)([]);
|
|
25393
|
+
(0, react$1.useEffect)(() => {
|
|
23768
25394
|
if (deviceId === null) return;
|
|
23769
25395
|
let cancelled = false;
|
|
23770
25396
|
const fetch = () => {
|
|
@@ -23783,8 +25409,8 @@ function useDeviceWebrtc(trpc, deviceId, pollIntervalMs = 5e3) {
|
|
|
23783
25409
|
deviceId,
|
|
23784
25410
|
pollIntervalMs
|
|
23785
25411
|
]);
|
|
23786
|
-
const [pipelineMetrics, setPipelineMetrics] = (0, react.useState)(null);
|
|
23787
|
-
(0, react.useEffect)(() => {
|
|
25412
|
+
const [pipelineMetrics, setPipelineMetrics] = (0, react$1.useState)(null);
|
|
25413
|
+
(0, react$1.useEffect)(() => {
|
|
23788
25414
|
if (deviceId === null) return;
|
|
23789
25415
|
let cancelled = false;
|
|
23790
25416
|
if (trpc.pipelineOrchestrator) trpc.pipelineOrchestrator.getCameraMetrics.query({ deviceId }).then((m) => {
|
|
@@ -23811,7 +25437,7 @@ function useDeviceWebrtc(trpc, deviceId, pollIntervalMs = 5e3) {
|
|
|
23811
25437
|
droppedFrames: payload.metrics.droppedFrames
|
|
23812
25438
|
});
|
|
23813
25439
|
});
|
|
23814
|
-
const { streams, hasWebrtc } = (0, react.useMemo)(() => {
|
|
25440
|
+
const { streams, hasWebrtc } = (0, react$1.useMemo)(() => {
|
|
23815
25441
|
if (deviceId === null || remoteStreams.length === 0) return {
|
|
23816
25442
|
streams: [],
|
|
23817
25443
|
hasWebrtc: false
|
|
@@ -23833,7 +25459,7 @@ function useDeviceWebrtc(trpc, deviceId, pollIntervalMs = 5e3) {
|
|
|
23833
25459
|
streams,
|
|
23834
25460
|
hasWebrtc,
|
|
23835
25461
|
pipelineMetrics,
|
|
23836
|
-
createSession: (0, react.useCallback)(async (target, hints) => {
|
|
25462
|
+
createSession: (0, react$1.useCallback)(async (target, hints) => {
|
|
23837
25463
|
if (deviceId === null) throw new Error("No device selected");
|
|
23838
25464
|
const res = await trpc.webrtcSession.createSession.mutate({
|
|
23839
25465
|
deviceId,
|
|
@@ -23845,7 +25471,7 @@ function useDeviceWebrtc(trpc, deviceId, pollIntervalMs = 5e3) {
|
|
|
23845
25471
|
sdpOffer: res.sdpOffer
|
|
23846
25472
|
};
|
|
23847
25473
|
}, [trpc, deviceId]),
|
|
23848
|
-
sendAnswer: (0, react.useCallback)(async (sessionId, sdpAnswer) => {
|
|
25474
|
+
sendAnswer: (0, react$1.useCallback)(async (sessionId, sdpAnswer) => {
|
|
23849
25475
|
if (deviceId === null) throw new Error("No device selected");
|
|
23850
25476
|
await trpc.webrtcSession.handleAnswer.mutate({
|
|
23851
25477
|
deviceId,
|
|
@@ -23853,7 +25479,7 @@ function useDeviceWebrtc(trpc, deviceId, pollIntervalMs = 5e3) {
|
|
|
23853
25479
|
sdpAnswer
|
|
23854
25480
|
});
|
|
23855
25481
|
}, [trpc, deviceId]),
|
|
23856
|
-
closeSession: (0, react.useCallback)(async (sessionId) => {
|
|
25482
|
+
closeSession: (0, react$1.useCallback)(async (sessionId) => {
|
|
23857
25483
|
if (deviceId === null) return;
|
|
23858
25484
|
await trpc.webrtcSession.closeSession.mutate({
|
|
23859
25485
|
deviceId,
|
|
@@ -23926,10 +25552,10 @@ function usePTZ(trpc, deviceId, options) {
|
|
|
23926
25552
|
const pulseMs = options?.pulseMs ?? 250;
|
|
23927
25553
|
const enabled = options?.enabled ?? true;
|
|
23928
25554
|
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 () => {
|
|
25555
|
+
const [presets, setPresets] = (0, react$1.useState)([]);
|
|
25556
|
+
const [busy, setBusy] = (0, react$1.useState)(false);
|
|
25557
|
+
const [error, setError] = (0, react$1.useState)(null);
|
|
25558
|
+
const refreshPresets = (0, react$1.useCallback)(async () => {
|
|
23933
25559
|
if (!enabled || !ptz) return;
|
|
23934
25560
|
try {
|
|
23935
25561
|
setPresets(await ptz.getPresets({}));
|
|
@@ -23939,10 +25565,10 @@ function usePTZ(trpc, deviceId, options) {
|
|
|
23939
25565
|
setError(msg);
|
|
23940
25566
|
}
|
|
23941
25567
|
}, [ptz, enabled]);
|
|
23942
|
-
(0, react.useEffect)(() => {
|
|
25568
|
+
(0, react$1.useEffect)(() => {
|
|
23943
25569
|
refreshPresets();
|
|
23944
25570
|
}, [refreshPresets]);
|
|
23945
|
-
const wrap = (0, react.useCallback)(async (fn) => {
|
|
25571
|
+
const wrap = (0, react$1.useCallback)(async (fn) => {
|
|
23946
25572
|
if (!enabled || !ptz) return void 0;
|
|
23947
25573
|
setError(null);
|
|
23948
25574
|
setBusy(true);
|
|
@@ -23956,7 +25582,7 @@ function usePTZ(trpc, deviceId, options) {
|
|
|
23956
25582
|
}
|
|
23957
25583
|
}, [enabled, ptz]);
|
|
23958
25584
|
return {
|
|
23959
|
-
move: (0, react.useCallback)(async (direction, speed) => {
|
|
25585
|
+
move: (0, react$1.useCallback)(async (direction, speed) => {
|
|
23960
25586
|
if (!ptz) return;
|
|
23961
25587
|
const v = DIRECTION_VECTORS[direction];
|
|
23962
25588
|
const s = speed ?? defaultSpeed;
|
|
@@ -23975,7 +25601,7 @@ function usePTZ(trpc, deviceId, options) {
|
|
|
23975
25601
|
pulseMs,
|
|
23976
25602
|
wrap
|
|
23977
25603
|
]),
|
|
23978
|
-
startContinuous: (0, react.useCallback)(async (direction, speed) => {
|
|
25604
|
+
startContinuous: (0, react$1.useCallback)(async (direction, speed) => {
|
|
23979
25605
|
if (!ptz) return;
|
|
23980
25606
|
const v = DIRECTION_VECTORS[direction];
|
|
23981
25607
|
const s = speed ?? defaultSpeed;
|
|
@@ -23989,11 +25615,11 @@ function usePTZ(trpc, deviceId, options) {
|
|
|
23989
25615
|
defaultSpeed,
|
|
23990
25616
|
wrap
|
|
23991
25617
|
]),
|
|
23992
|
-
stopContinuous: (0, react.useCallback)(async () => {
|
|
25618
|
+
stopContinuous: (0, react$1.useCallback)(async () => {
|
|
23993
25619
|
if (!ptz) return;
|
|
23994
25620
|
await wrap(() => ptz.stop({}));
|
|
23995
25621
|
}, [ptz, wrap]),
|
|
23996
|
-
zoom: (0, react.useCallback)(async (direction, speed) => {
|
|
25622
|
+
zoom: (0, react$1.useCallback)(async (direction, speed) => {
|
|
23997
25623
|
if (!ptz) return;
|
|
23998
25624
|
const z = direction === "in" ? 1 : -1;
|
|
23999
25625
|
const s = speed ?? defaultSpeed;
|
|
@@ -24011,11 +25637,11 @@ function usePTZ(trpc, deviceId, options) {
|
|
|
24011
25637
|
pulseMs,
|
|
24012
25638
|
wrap
|
|
24013
25639
|
]),
|
|
24014
|
-
goHome: (0, react.useCallback)(async () => {
|
|
25640
|
+
goHome: (0, react$1.useCallback)(async () => {
|
|
24015
25641
|
if (!ptz) return;
|
|
24016
25642
|
await wrap(() => ptz.goHome({}));
|
|
24017
25643
|
}, [ptz, wrap]),
|
|
24018
|
-
goToPreset: (0, react.useCallback)(async (presetId) => {
|
|
25644
|
+
goToPreset: (0, react$1.useCallback)(async (presetId) => {
|
|
24019
25645
|
if (!ptz) return;
|
|
24020
25646
|
await wrap(() => ptz.goToPreset({ presetId }));
|
|
24021
25647
|
}, [ptz, wrap]),
|
|
@@ -24042,8 +25668,8 @@ function useDoorbellEvents(options) {
|
|
|
24042
25668
|
const deviceId = options?.deviceId ?? null;
|
|
24043
25669
|
const historyLimit = options?.historyLimit ?? 20;
|
|
24044
25670
|
const event = useEventStreamLatest("doorbell.onPressed", deviceId !== null ? (data) => data.deviceId === deviceId : void 0);
|
|
24045
|
-
const [history, setHistory] = (0, react.useState)([]);
|
|
24046
|
-
(0, react.useEffect)(() => {
|
|
25671
|
+
const [history, setHistory] = (0, react$1.useState)([]);
|
|
25672
|
+
(0, react$1.useEffect)(() => {
|
|
24047
25673
|
if (!event) return;
|
|
24048
25674
|
setHistory((prev) => {
|
|
24049
25675
|
if (prev.length > 0 && prev[0].deviceId === event.deviceId && prev[0].timestamp === event.timestamp) return prev;
|
|
@@ -24079,9 +25705,9 @@ function useDoorbellEvents(options) {
|
|
|
24079
25705
|
*/
|
|
24080
25706
|
function useDevices(filters) {
|
|
24081
25707
|
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)(() => {
|
|
25708
|
+
const filtersKey = (0, react$1.useMemo)(() => filters ? JSON.stringify(filters) : "", [filters]);
|
|
25709
|
+
const [devices, setDevices] = (0, react$1.useState)(() => system.listDevices(filters));
|
|
25710
|
+
(0, react$1.useEffect)(() => {
|
|
24085
25711
|
const refresh = () => {
|
|
24086
25712
|
setDevices(system.listDevices(filters));
|
|
24087
25713
|
};
|
|
@@ -24114,8 +25740,8 @@ function useDevices(filters) {
|
|
|
24114
25740
|
*/
|
|
24115
25741
|
function useDevice(deviceId) {
|
|
24116
25742
|
const system = useSystem();
|
|
24117
|
-
const [device, setDevice] = (0, react.useState)(() => deviceId === null ? null : system.getDevice(deviceId));
|
|
24118
|
-
(0, react.useEffect)(() => {
|
|
25743
|
+
const [device, setDevice] = (0, react$1.useState)(() => deviceId === null ? null : system.getDevice(deviceId));
|
|
25744
|
+
(0, react$1.useEffect)(() => {
|
|
24119
25745
|
if (deviceId === null) {
|
|
24120
25746
|
setDevice(null);
|
|
24121
25747
|
return;
|
|
@@ -24213,15 +25839,15 @@ function useSystemMutation(select, opts) {
|
|
|
24213
25839
|
function useEventInvalidation(queryKey, categories) {
|
|
24214
25840
|
const system = useSystem();
|
|
24215
25841
|
const queryClient = (0, _tanstack_react_query.useQueryClient)();
|
|
24216
|
-
const [tick, setTick] = (0, react.useState)(system.connectionVersion);
|
|
24217
|
-
(0, react.useEffect)(() => {
|
|
25842
|
+
const [tick, setTick] = (0, react$1.useState)(system.connectionVersion);
|
|
25843
|
+
(0, react$1.useEffect)(() => {
|
|
24218
25844
|
return system.subscribeConnectionEvents((state, version) => {
|
|
24219
25845
|
if (state === "connected") setTick(version);
|
|
24220
25846
|
});
|
|
24221
25847
|
}, [system]);
|
|
24222
25848
|
const key = categories.join("|");
|
|
24223
25849
|
const keyJson = JSON.stringify(queryKey);
|
|
24224
|
-
(0, react.useEffect)(() => {
|
|
25850
|
+
(0, react$1.useEffect)(() => {
|
|
24225
25851
|
const subs = [];
|
|
24226
25852
|
const refresh = () => {
|
|
24227
25853
|
const raw = JSON.parse(keyJson);
|
|
@@ -24276,6 +25902,7 @@ exports.ConfigFormField = FormField;
|
|
|
24276
25902
|
exports.ConfigSchemaField = ConfigSchemaField;
|
|
24277
25903
|
exports.ConfirmActionButton = ConfirmActionButton;
|
|
24278
25904
|
exports.ConfirmDialogProvider = ConfirmDialogProvider;
|
|
25905
|
+
exports.CopyButton = CopyButton;
|
|
24279
25906
|
exports.CustomFieldRenderersProvider = CustomFieldRenderersProvider;
|
|
24280
25907
|
exports.DEFAULT_COLOR = DEFAULT_COLOR;
|
|
24281
25908
|
exports.DataTable = DataTable;
|
|
@@ -24286,6 +25913,7 @@ exports.DevShell = DevShell;
|
|
|
24286
25913
|
exports.DeviceActivityPanel = DeviceActivityPanel;
|
|
24287
25914
|
exports.DeviceCard = DeviceCard;
|
|
24288
25915
|
exports.DeviceContextProvider = DeviceContextProvider;
|
|
25916
|
+
exports.DeviceExportPanel = DeviceExportPanel;
|
|
24289
25917
|
exports.DeviceGrid = DeviceGrid;
|
|
24290
25918
|
exports.DeviceItem = DeviceItem;
|
|
24291
25919
|
exports.DeviceList = DeviceList;
|
|
@@ -24303,6 +25931,7 @@ exports.DropdownContent = DropdownContent;
|
|
|
24303
25931
|
exports.DropdownItem = DropdownItem;
|
|
24304
25932
|
exports.DropdownTrigger = DropdownTrigger;
|
|
24305
25933
|
exports.EmptyState = EmptyState;
|
|
25934
|
+
exports.ErrorBox = ErrorBox;
|
|
24306
25935
|
exports.EventStream = EventStream;
|
|
24307
25936
|
exports.FilterBar = FilterBar;
|
|
24308
25937
|
exports.FloatingEventStream = FloatingEventStream;
|
|
@@ -24340,6 +25969,7 @@ exports.Popover = Popover;
|
|
|
24340
25969
|
exports.PopoverContent = PopoverContent;
|
|
24341
25970
|
exports.PopoverTrigger = PopoverTrigger;
|
|
24342
25971
|
exports.ProviderBadge = ProviderBadge;
|
|
25972
|
+
exports.QrCode = QrCode;
|
|
24343
25973
|
exports.ResponseLog = ResponseLog;
|
|
24344
25974
|
exports.SECTION_BODY = SECTION_BODY;
|
|
24345
25975
|
exports.SECTION_CARD = SECTION_CARD;
|
|
@@ -24414,12 +26044,15 @@ exports.useAddonsCustom = useAddonsCustom;
|
|
|
24414
26044
|
exports.useAddonsForceRefresh = useAddonsForceRefresh;
|
|
24415
26045
|
exports.useAddonsGetAddonAutoUpdate = useAddonsGetAddonAutoUpdate;
|
|
24416
26046
|
exports.useAddonsGetAutoUpdateSettings = useAddonsGetAutoUpdateSettings;
|
|
26047
|
+
exports.useAddonsGetLastRestart = useAddonsGetLastRestart;
|
|
24417
26048
|
exports.useAddonsGetLogs = useAddonsGetLogs;
|
|
24418
26049
|
exports.useAddonsGetVersions = useAddonsGetVersions;
|
|
24419
26050
|
exports.useAddonsInstallFromWorkspace = useAddonsInstallFromWorkspace;
|
|
24420
26051
|
exports.useAddonsInstallPackage = useAddonsInstallPackage;
|
|
24421
26052
|
exports.useAddonsIsWorkspaceAvailable = useAddonsIsWorkspaceAvailable;
|
|
24422
26053
|
exports.useAddonsList = useAddonsList;
|
|
26054
|
+
exports.useAddonsListCapabilityProviders = useAddonsListCapabilityProviders;
|
|
26055
|
+
exports.useAddonsListFrameworkPackages = useAddonsListFrameworkPackages;
|
|
24423
26056
|
exports.useAddonsListPackages = useAddonsListPackages;
|
|
24424
26057
|
exports.useAddonsListUpdates = useAddonsListUpdates;
|
|
24425
26058
|
exports.useAddonsListWorkspacePackages = useAddonsListWorkspacePackages;
|
|
@@ -24432,7 +26065,9 @@ exports.useAddonsRollbackPackage = useAddonsRollbackPackage;
|
|
|
24432
26065
|
exports.useAddonsSearchAvailable = useAddonsSearchAvailable;
|
|
24433
26066
|
exports.useAddonsSetAddonAutoUpdate = useAddonsSetAddonAutoUpdate;
|
|
24434
26067
|
exports.useAddonsSetAutoUpdateSettings = useAddonsSetAutoUpdateSettings;
|
|
26068
|
+
exports.useAddonsSetCapabilityProviderEnabled = useAddonsSetCapabilityProviderEnabled;
|
|
24435
26069
|
exports.useAddonsUninstallPackage = useAddonsUninstallPackage;
|
|
26070
|
+
exports.useAddonsUpdateFrameworkPackage = useAddonsUpdateFrameworkPackage;
|
|
24436
26071
|
exports.useAddonsUpdatePackage = useAddonsUpdatePackage;
|
|
24437
26072
|
exports.useAlertsDismiss = useAlertsDismiss;
|
|
24438
26073
|
exports.useAlertsEmit = useAlertsEmit;
|
|
@@ -24464,8 +26099,6 @@ exports.useAudioCodecPushEncodedFrame = useAudioCodecPushEncodedFrame;
|
|
|
24464
26099
|
exports.useAudioCodecPushPcm = useAudioCodecPushPcm;
|
|
24465
26100
|
exports.useAudioMetricsGetCurrentSnapshot = useAudioMetricsGetCurrentSnapshot;
|
|
24466
26101
|
exports.useAudioMetricsGetHistory = useAudioMetricsGetHistory;
|
|
24467
|
-
exports.useAuthenticationListProviders = useAuthenticationListProviders;
|
|
24468
|
-
exports.useAuthenticationSetProviderEnabled = useAuthenticationSetProviderEnabled;
|
|
24469
26102
|
exports.useBackupDelete = useBackupDelete;
|
|
24470
26103
|
exports.useBackupGetEntries = useBackupGetEntries;
|
|
24471
26104
|
exports.useBackupList = useBackupList;
|
|
@@ -24637,12 +26270,6 @@ exports.useMeshNetworkListPeers = useMeshNetworkListPeers;
|
|
|
24637
26270
|
exports.useMeshNetworkLogout = useMeshNetworkLogout;
|
|
24638
26271
|
exports.useMeshNetworkStartLogin = useMeshNetworkStartLogin;
|
|
24639
26272
|
exports.useMeshNetworkTestConnection = useMeshNetworkTestConnection;
|
|
24640
|
-
exports.useMeshOrchestratorJoinProvider = useMeshOrchestratorJoinProvider;
|
|
24641
|
-
exports.useMeshOrchestratorLeaveProvider = useMeshOrchestratorLeaveProvider;
|
|
24642
|
-
exports.useMeshOrchestratorListProviderPeers = useMeshOrchestratorListProviderPeers;
|
|
24643
|
-
exports.useMeshOrchestratorListProviders = useMeshOrchestratorListProviders;
|
|
24644
|
-
exports.useMeshOrchestratorLogoutProvider = useMeshOrchestratorLogoutProvider;
|
|
24645
|
-
exports.useMeshOrchestratorStartLoginProvider = useMeshOrchestratorStartLoginProvider;
|
|
24646
26273
|
exports.useMetricsProviderCollectSnapshot = useMetricsProviderCollectSnapshot;
|
|
24647
26274
|
exports.useMetricsProviderGetAddonStats = useMetricsProviderGetAddonStats;
|
|
24648
26275
|
exports.useMetricsProviderGetCached = useMetricsProviderGetCached;
|
|
@@ -24673,6 +26300,11 @@ exports.useMqttBrokerStartEmbeddedBroker = useMqttBrokerStartEmbeddedBroker;
|
|
|
24673
26300
|
exports.useMqttBrokerStopEmbeddedBroker = useMqttBrokerStopEmbeddedBroker;
|
|
24674
26301
|
exports.useMqttBrokerTestConnection = useMqttBrokerTestConnection;
|
|
24675
26302
|
exports.useNativeObjectDetectionGetStatus = useNativeObjectDetectionGetStatus;
|
|
26303
|
+
exports.useNetworkAccessGetEndpoint = useNetworkAccessGetEndpoint;
|
|
26304
|
+
exports.useNetworkAccessGetStatus = useNetworkAccessGetStatus;
|
|
26305
|
+
exports.useNetworkAccessListEndpoints = useNetworkAccessListEndpoints;
|
|
26306
|
+
exports.useNetworkAccessStart = useNetworkAccessStart;
|
|
26307
|
+
exports.useNetworkAccessStop = useNetworkAccessStop;
|
|
24676
26308
|
exports.useNetworkQualityGetAllStats = useNetworkQualityGetAllStats;
|
|
24677
26309
|
exports.useNetworkQualityGetDeviceStats = useNetworkQualityGetDeviceStats;
|
|
24678
26310
|
exports.useNetworkQualityReportClientStats = useNetworkQualityReportClientStats;
|
|
@@ -24830,9 +26462,6 @@ exports.useRecordingEngineUpdateRetentionConfig = useRecordingEngineUpdateRetent
|
|
|
24830
26462
|
exports.useRecordingGetPlaybackUrl = useRecordingGetPlaybackUrl;
|
|
24831
26463
|
exports.useRecordingGetSegments = useRecordingGetSegments;
|
|
24832
26464
|
exports.useRecordingGetThumbnailAt = useRecordingGetThumbnailAt;
|
|
24833
|
-
exports.useRemoteAccessListProviders = useRemoteAccessListProviders;
|
|
24834
|
-
exports.useRemoteAccessStartProvider = useRemoteAccessStartProvider;
|
|
24835
|
-
exports.useRemoteAccessStopProvider = useRemoteAccessStopProvider;
|
|
24836
26465
|
exports.useSettingsStoreCount = useSettingsStoreCount;
|
|
24837
26466
|
exports.useSettingsStoreDeclareCollection = useSettingsStoreDeclareCollection;
|
|
24838
26467
|
exports.useSettingsStoreDelete = useSettingsStoreDelete;
|
|
@@ -24910,9 +26539,6 @@ exports.useSystemQuery = useSystemQuery;
|
|
|
24910
26539
|
exports.useSystemSetRetentionConfig = useSystemSetRetentionConfig;
|
|
24911
26540
|
exports.useThemeMode = require_theme_index.useThemeMode$1;
|
|
24912
26541
|
exports.useToastOnToast = useToastOnToast;
|
|
24913
|
-
exports.useTurnOrchestratorGetAllServers = useTurnOrchestratorGetAllServers;
|
|
24914
|
-
exports.useTurnOrchestratorListProviders = useTurnOrchestratorListProviders;
|
|
24915
|
-
exports.useTurnOrchestratorSetProviderEnabled = useTurnOrchestratorSetProviderEnabled;
|
|
24916
26542
|
exports.useTurnProviderGetTurnServers = useTurnProviderGetTurnServers;
|
|
24917
26543
|
exports.useUserManagementConfirmTotp = useUserManagementConfirmTotp;
|
|
24918
26544
|
exports.useUserManagementCreateApiKey = useUserManagementCreateApiKey;
|