@camstack/ui-library 1.2.245 → 1.2.247
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/accelerator-label.d.ts +17 -0
- package/dist/composites/agent-step-editor.d.ts +3 -3
- package/dist/composites/device-step-matrix.d.ts +25 -2
- package/dist/composites/index.d.ts +3 -2
- package/dist/composites/pipeline-builder.d.ts +2 -10
- package/dist/composites/pipeline-matrix-shared.d.ts +10 -0
- package/dist/composites/step-inspector/index.d.ts +2 -5
- package/dist/composites/step-inspector/step-detail-dock.d.ts +33 -0
- package/dist/composites/step-inspector/step-inspector-panel.d.ts +7 -1
- package/dist/composites/step-inspector/step-search.d.ts +18 -0
- package/dist/composites/stream-panel.d.ts +0 -3
- package/dist/generated/system-hooks.d.ts +0 -46
- package/dist/hooks/use-device-webrtc.d.ts +0 -1
- package/dist/index.cjs +485 -822
- package/dist/index.js +480 -793
- package/package.json +1 -1
- package/dist/composites/step-inspector/accelerator-tabs.d.ts +0 -12
- package/dist/composites/step-inspector/step-chips.d.ts +0 -11
- package/dist/composites/step-inspector/step-inspector-layout.d.ts +0 -23
- package/dist/composites/step-inspector/step-list.d.ts +0 -39
- package/dist/composites/step-inspector/step-model-list.d.ts +0 -9
- package/dist/lib/validate-template.d.ts +0 -2
package/dist/index.cjs
CHANGED
|
@@ -1707,41 +1707,6 @@ var CookingPot = createLucideIcon("cooking-pot", [
|
|
|
1707
1707
|
* This source code is licensed under the ISC license.
|
|
1708
1708
|
* See the LICENSE file in the root directory of this source tree.
|
|
1709
1709
|
*/
|
|
1710
|
-
var CopyPlus = createLucideIcon("copy-plus", [
|
|
1711
|
-
["line", {
|
|
1712
|
-
x1: "15",
|
|
1713
|
-
x2: "15",
|
|
1714
|
-
y1: "12",
|
|
1715
|
-
y2: "18",
|
|
1716
|
-
key: "1p7wdc"
|
|
1717
|
-
}],
|
|
1718
|
-
["line", {
|
|
1719
|
-
x1: "12",
|
|
1720
|
-
x2: "18",
|
|
1721
|
-
y1: "15",
|
|
1722
|
-
y2: "15",
|
|
1723
|
-
key: "1nscbv"
|
|
1724
|
-
}],
|
|
1725
|
-
["rect", {
|
|
1726
|
-
width: "14",
|
|
1727
|
-
height: "14",
|
|
1728
|
-
x: "8",
|
|
1729
|
-
y: "8",
|
|
1730
|
-
rx: "2",
|
|
1731
|
-
ry: "2",
|
|
1732
|
-
key: "17jyea"
|
|
1733
|
-
}],
|
|
1734
|
-
["path", {
|
|
1735
|
-
d: "M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2",
|
|
1736
|
-
key: "zix9uf"
|
|
1737
|
-
}]
|
|
1738
|
-
]);
|
|
1739
|
-
/**
|
|
1740
|
-
* @license lucide-react v0.576.0 - ISC
|
|
1741
|
-
*
|
|
1742
|
-
* This source code is licensed under the ISC license.
|
|
1743
|
-
* See the LICENSE file in the root directory of this source tree.
|
|
1744
|
-
*/
|
|
1745
1710
|
var Copy = createLucideIcon("copy", [["rect", {
|
|
1746
1711
|
width: "14",
|
|
1747
1712
|
height: "14",
|
|
@@ -6890,32 +6855,8 @@ var useDayNightGetOptions = trpc.dayNight.getOptions.useQuery;
|
|
|
6890
6855
|
var useDayNightSetSettings = trpc.dayNight.setSettings.useMutation;
|
|
6891
6856
|
/** Generated alias around `trpc.dayNight.getStatus.useQuery`. */
|
|
6892
6857
|
var useDayNightGetStatus = trpc.dayNight.getStatus.useQuery;
|
|
6893
|
-
/** Generated alias around `trpc.decoder.supportsCodec.useQuery`. */
|
|
6894
|
-
var useDecoderSupportsCodec = trpc.decoder.supportsCodec.useQuery;
|
|
6895
6858
|
/** Generated alias around `trpc.decoder.getInfo.useQuery`. */
|
|
6896
6859
|
var useDecoderGetInfo = trpc.decoder.getInfo.useQuery;
|
|
6897
|
-
/** Generated alias around `trpc.decoder.createSession.useQuery`. */
|
|
6898
|
-
var useDecoderCreateSession = trpc.decoder.createSession.useQuery;
|
|
6899
|
-
/** Generated alias around `trpc.decoder.destroySession.useQuery`. */
|
|
6900
|
-
var useDecoderDestroySession = trpc.decoder.destroySession.useQuery;
|
|
6901
|
-
/** Generated alias around `trpc.decoder.pushPacket.useQuery`. */
|
|
6902
|
-
var useDecoderPushPacket = trpc.decoder.pushPacket.useQuery;
|
|
6903
|
-
/** Generated alias around `trpc.decoder.openStream.useQuery`. */
|
|
6904
|
-
var useDecoderOpenStream = trpc.decoder.openStream.useQuery;
|
|
6905
|
-
/** Generated alias around `trpc.decoder.pullFrames.useQuery`. */
|
|
6906
|
-
var useDecoderPullFrames = trpc.decoder.pullFrames.useQuery;
|
|
6907
|
-
/** Generated alias around `trpc.decoder.pullHandles.useQuery`. */
|
|
6908
|
-
var useDecoderPullHandles = trpc.decoder.pullHandles.useQuery;
|
|
6909
|
-
/** Generated alias around `trpc.decoder.getFrame.useQuery`. */
|
|
6910
|
-
var useDecoderGetFrame = trpc.decoder.getFrame.useQuery;
|
|
6911
|
-
/** Generated alias around `trpc.decoder.getShmStats.useQuery`. */
|
|
6912
|
-
var useDecoderGetShmStats = trpc.decoder.getShmStats.useQuery;
|
|
6913
|
-
/** Generated alias around `trpc.decoder.updateConfig.useQuery`. */
|
|
6914
|
-
var useDecoderUpdateConfig = trpc.decoder.updateConfig.useQuery;
|
|
6915
|
-
/** Generated alias around `trpc.decoder.getStats.useQuery`. */
|
|
6916
|
-
var useDecoderGetStats = trpc.decoder.getStats.useQuery;
|
|
6917
|
-
/** Generated alias around `trpc.decoder.listActiveSessions.useQuery`. */
|
|
6918
|
-
var useDecoderListActiveSessions = trpc.decoder.listActiveSessions.useQuery;
|
|
6919
6860
|
/** Generated alias around `trpc.decoder.reprobeHwaccel.useMutation`. */
|
|
6920
6861
|
var useDecoderReprobeHwaccel = trpc.decoder.reprobeHwaccel.useMutation;
|
|
6921
6862
|
/** Generated alias around `trpc.detectionPipeline.getDeviceSettingsContribution.useQuery`. */
|
|
@@ -7914,14 +7855,6 @@ var usePipelineExecutorGetGlobalPipelineConfig = trpc.pipelineExecutor.getGlobal
|
|
|
7914
7855
|
var usePipelineExecutorGetOrchestratorConfigSchema = trpc.pipelineExecutor.getOrchestratorConfigSchema.useQuery;
|
|
7915
7856
|
/** Generated alias around `trpc.pipelineExecutor.validatePipeline.useQuery`. */
|
|
7916
7857
|
var usePipelineExecutorValidatePipeline = trpc.pipelineExecutor.validatePipeline.useQuery;
|
|
7917
|
-
/** Generated alias around `trpc.pipelineExecutor.listTemplates.useQuery`. */
|
|
7918
|
-
var usePipelineExecutorListTemplates = trpc.pipelineExecutor.listTemplates.useQuery;
|
|
7919
|
-
/** Generated alias around `trpc.pipelineExecutor.saveTemplate.useMutation`. */
|
|
7920
|
-
var usePipelineExecutorSaveTemplate = trpc.pipelineExecutor.saveTemplate.useMutation;
|
|
7921
|
-
/** Generated alias around `trpc.pipelineExecutor.updateTemplate.useMutation`. */
|
|
7922
|
-
var usePipelineExecutorUpdateTemplate = trpc.pipelineExecutor.updateTemplate.useMutation;
|
|
7923
|
-
/** Generated alias around `trpc.pipelineExecutor.deleteTemplate.useMutation`. */
|
|
7924
|
-
var usePipelineExecutorDeleteTemplate = trpc.pipelineExecutor.deleteTemplate.useMutation;
|
|
7925
7858
|
/** Generated alias around `trpc.pipelineExecutor.getCapabilities.useQuery`. */
|
|
7926
7859
|
var usePipelineExecutorGetCapabilities = trpc.pipelineExecutor.getCapabilities.useQuery;
|
|
7927
7860
|
/** Generated alias around `trpc.pipelineExecutor.getAddonModels.useQuery`. */
|
|
@@ -8068,14 +8001,6 @@ var usePipelineOrchestratorSetCameraSensors = trpc.pipelineOrchestrator.setCamer
|
|
|
8068
8001
|
var usePipelineOrchestratorReconcileFromDisk = trpc.pipelineOrchestrator.reconcileFromDisk.useMutation;
|
|
8069
8002
|
/** Generated alias around `trpc.pipelineOrchestrator.getReconcileFromDiskStatus.useQuery`. */
|
|
8070
8003
|
var usePipelineOrchestratorGetReconcileFromDiskStatus = trpc.pipelineOrchestrator.getReconcileFromDiskStatus.useQuery;
|
|
8071
|
-
/** Generated alias around `trpc.pipelineOrchestrator.listTemplates.useQuery`. */
|
|
8072
|
-
var usePipelineOrchestratorListTemplates = trpc.pipelineOrchestrator.listTemplates.useQuery;
|
|
8073
|
-
/** Generated alias around `trpc.pipelineOrchestrator.saveTemplate.useMutation`. */
|
|
8074
|
-
var usePipelineOrchestratorSaveTemplate = trpc.pipelineOrchestrator.saveTemplate.useMutation;
|
|
8075
|
-
/** Generated alias around `trpc.pipelineOrchestrator.updateTemplate.useMutation`. */
|
|
8076
|
-
var usePipelineOrchestratorUpdateTemplate = trpc.pipelineOrchestrator.updateTemplate.useMutation;
|
|
8077
|
-
/** Generated alias around `trpc.pipelineOrchestrator.deleteTemplate.useMutation`. */
|
|
8078
|
-
var usePipelineOrchestratorDeleteTemplate = trpc.pipelineOrchestrator.deleteTemplate.useMutation;
|
|
8079
8004
|
/** Generated alias around `trpc.pipelineOrchestrator.getDeviceSettingsContribution.useQuery`. */
|
|
8080
8005
|
var usePipelineOrchestratorGetDeviceSettingsContribution = trpc.pipelineOrchestrator.getDeviceSettingsContribution.useQuery;
|
|
8081
8006
|
/** Generated alias around `trpc.pipelineOrchestrator.getDeviceLiveContribution.useQuery`. */
|
|
@@ -8504,12 +8429,6 @@ var useStreamBrokerSubscribeAudioChunks = trpc.streamBroker.subscribeAudioChunks
|
|
|
8504
8429
|
var useStreamBrokerPullAudioChunks = trpc.streamBroker.pullAudioChunks.useQuery;
|
|
8505
8430
|
/** Generated alias around `trpc.streamBroker.unsubscribeAudioChunks.useMutation`. */
|
|
8506
8431
|
var useStreamBrokerUnsubscribeAudioChunks = trpc.streamBroker.unsubscribeAudioChunks.useMutation;
|
|
8507
|
-
/** Generated alias around `trpc.streamBroker.subscribeFrames.useMutation`. */
|
|
8508
|
-
var useStreamBrokerSubscribeFrames = trpc.streamBroker.subscribeFrames.useMutation;
|
|
8509
|
-
/** Generated alias around `trpc.streamBroker.pullFrameHandles.useQuery`. */
|
|
8510
|
-
var useStreamBrokerPullFrameHandles = trpc.streamBroker.pullFrameHandles.useQuery;
|
|
8511
|
-
/** Generated alias around `trpc.streamBroker.unsubscribeFrames.useMutation`. */
|
|
8512
|
-
var useStreamBrokerUnsubscribeFrames = trpc.streamBroker.unsubscribeFrames.useMutation;
|
|
8513
8432
|
/** Generated alias around `trpc.streamBroker.setPreBufferDuration.useMutation`. */
|
|
8514
8433
|
var useStreamBrokerSetPreBufferDuration = trpc.streamBroker.setPreBufferDuration.useMutation;
|
|
8515
8434
|
/** Generated alias around `trpc.streamBroker.getPreBufferInfo.useQuery`. */
|
|
@@ -28746,6 +28665,45 @@ function AddonGlobalSettingsForm({ trpc, addonId, nodeId, title, disabled, onAft
|
|
|
28746
28665
|
});
|
|
28747
28666
|
}
|
|
28748
28667
|
//#endregion
|
|
28668
|
+
//#region src/composites/accelerator-label.ts
|
|
28669
|
+
function names(device) {
|
|
28670
|
+
const backend = device.backend.toLowerCase();
|
|
28671
|
+
const dev = device.device.toLowerCase();
|
|
28672
|
+
if (device.key === "cpu" || dev === "cpu" || backend === "cpu") return {
|
|
28673
|
+
label: "CPU",
|
|
28674
|
+
short: "CPU"
|
|
28675
|
+
};
|
|
28676
|
+
if (dev === "npu") return {
|
|
28677
|
+
label: "Intel NPU",
|
|
28678
|
+
short: "NPU"
|
|
28679
|
+
};
|
|
28680
|
+
if (dev === "gpu" || dev === "igpu") return {
|
|
28681
|
+
label: "Intel iGPU",
|
|
28682
|
+
short: "iGPU"
|
|
28683
|
+
};
|
|
28684
|
+
if (backend === "edgetpu") return {
|
|
28685
|
+
label: "Coral Edge TPU",
|
|
28686
|
+
short: "Coral"
|
|
28687
|
+
};
|
|
28688
|
+
if (backend === "coreml") return {
|
|
28689
|
+
label: "Apple Neural Engine",
|
|
28690
|
+
short: "ANE"
|
|
28691
|
+
};
|
|
28692
|
+
const pretty = `${device.backend} ${device.device}`.trim().replace(/\b\w/g, (c) => c.toUpperCase());
|
|
28693
|
+
return {
|
|
28694
|
+
label: pretty.length > 0 ? pretty : device.key,
|
|
28695
|
+
short: device.backend || device.key
|
|
28696
|
+
};
|
|
28697
|
+
}
|
|
28698
|
+
/** "Intel NPU", "Apple Neural Engine", "Coral Edge TPU", "CPU" — Auto tune's names too. */
|
|
28699
|
+
function acceleratorLabel(device) {
|
|
28700
|
+
return names(device).label;
|
|
28701
|
+
}
|
|
28702
|
+
/** "NPU", "ANE", "Coral", "CPU" — chips and tabs. */
|
|
28703
|
+
function acceleratorShortLabel(device) {
|
|
28704
|
+
return names(device).short;
|
|
28705
|
+
}
|
|
28706
|
+
//#endregion
|
|
28749
28707
|
//#region src/composites/grouped-model-selector.tsx
|
|
28750
28708
|
/**
|
|
28751
28709
|
* GroupedModelSelector — the shared Family → Tier → Variant model picker.
|
|
@@ -29973,9 +29931,9 @@ function RootSuppliedModelNote({ rootModel, stepModelId }) {
|
|
|
29973
29931
|
/**
|
|
29974
29932
|
* AgentStepEditor — one step on ONE accelerator: its model and its settings,
|
|
29975
29933
|
* as a single node-level layer. Model Studio's "settings for this installed
|
|
29976
|
-
* model" dialog uses it. The pipeline pages use the step
|
|
29977
|
-
* the same parts out across accelerators and layers (D754/
|
|
29978
|
-
* form here is that
|
|
29934
|
+
* model" dialog uses it. The pipeline pages use the step matrix's panel, which lays
|
|
29935
|
+
* the same parts out across accelerators and layers (D754/D757); the settings
|
|
29936
|
+
* form here is that panel's `LayeredSettingsForm` with one layer.
|
|
29979
29937
|
*/
|
|
29980
29938
|
function AgentStepEditor({ addon, agentDefault, onChangeAgentConfig, engineFormat, effectiveModelId, rootModel }) {
|
|
29981
29939
|
const modelsForFormat = (0, react$1.useMemo)(() => stepModelOptions(addon.models, engineFormat), [addon.models, engineFormat]);
|
|
@@ -35294,7 +35252,6 @@ function useDeviceWebrtc(trpc, deviceId, pollIntervalMs = 5e3) {
|
|
|
35294
35252
|
target: r.target,
|
|
35295
35253
|
status: r.status,
|
|
35296
35254
|
inputFps: r.inputFps,
|
|
35297
|
-
decodeFps: r.decodeFps,
|
|
35298
35255
|
bitrateKbps: r.bitrateKbps
|
|
35299
35256
|
})),
|
|
35300
35257
|
hasWebrtc: true
|
|
@@ -55405,25 +55362,46 @@ function ClassChips({ inputs, outputs }) {
|
|
|
55405
55362
|
* the first column; each device's real format is shown per sub-column instead
|
|
55406
55363
|
* ("Coral Edge TPU · tflite").
|
|
55407
55364
|
*/
|
|
55365
|
+
/** The per-accelerator lines of a column header: name, format, model, off. */
|
|
55366
|
+
function AgentColumnLines({ column }) {
|
|
55367
|
+
const name = column.deviceLabel ?? column.deviceKey;
|
|
55368
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
55369
|
+
(name !== void 0 || column.disabled === true) && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
55370
|
+
className: "flex min-w-0 items-center gap-1",
|
|
55371
|
+
children: [name !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
55372
|
+
className: "truncate text-[10px] font-medium text-foreground/90",
|
|
55373
|
+
children: name
|
|
55374
|
+
}), column.disabled === true && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
55375
|
+
className: "shrink-0 rounded bg-muted px-1 text-[8px] font-semibold uppercase text-foreground-subtle",
|
|
55376
|
+
children: "off"
|
|
55377
|
+
})]
|
|
55378
|
+
}),
|
|
55379
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
55380
|
+
className: "truncate text-[9px] text-foreground-subtle",
|
|
55381
|
+
children: column.engineLabel
|
|
55382
|
+
}),
|
|
55383
|
+
column.detail !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
55384
|
+
className: "truncate font-mono text-[9px] text-foreground-subtle",
|
|
55385
|
+
title: column.detail,
|
|
55386
|
+
children: column.detail
|
|
55387
|
+
})
|
|
55388
|
+
] });
|
|
55389
|
+
}
|
|
55408
55390
|
function GroupedAgentHeader({ group }) {
|
|
55391
|
+
const nodeLabel = group.columns[0]?.nodeLabel ?? group.agentNodeId;
|
|
55409
55392
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
55393
|
+
role: "columnheader",
|
|
55410
55394
|
className: "sticky top-0 z-10 min-w-0 border-b border-l border-border bg-muted/60",
|
|
55411
55395
|
style: { gridColumn: `span ${group.columns.length}` },
|
|
55412
55396
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
55413
55397
|
className: "truncate px-3 pt-2 pb-1 text-xs font-semibold text-foreground",
|
|
55414
|
-
children:
|
|
55398
|
+
children: nodeLabel
|
|
55415
55399
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
55416
55400
|
className: "mt-1 flex border-t border-border/50",
|
|
55417
|
-
children: group.columns.map((c, i) => /* @__PURE__ */ (0, react_jsx_runtime.
|
|
55418
|
-
className: cn("min-w-0 flex-1 px-3 py-1", i > 0 && "border-l border-border/50"),
|
|
55419
|
-
title: `${c.deviceLabel ?? c.deviceKey} · ${c.engineLabel}`,
|
|
55420
|
-
children:
|
|
55421
|
-
className: "truncate text-[10px] font-medium text-foreground/90",
|
|
55422
|
-
children: c.deviceLabel ?? c.deviceKey
|
|
55423
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
55424
|
-
className: "truncate text-[9px] text-foreground-subtle",
|
|
55425
|
-
children: c.engineLabel
|
|
55426
|
-
})]
|
|
55401
|
+
children: group.columns.map((c, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
55402
|
+
className: cn("min-w-0 flex-1 px-3 py-1", i > 0 && "border-l border-border/50", c.disabled === true && "opacity-70"),
|
|
55403
|
+
title: `${c.deviceLabel ?? c.deviceKey} · ${c.engineLabel}${c.detail ? ` · ${c.detail}` : ""}`,
|
|
55404
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AgentColumnLines, { column: c })
|
|
55427
55405
|
}, agentColumnKey(c)))
|
|
55428
55406
|
})]
|
|
55429
55407
|
});
|
|
@@ -55527,25 +55505,30 @@ function cellButtonClass(state, isSelected, extra) {
|
|
|
55527
55505
|
//#endregion
|
|
55528
55506
|
//#region src/composites/device-step-matrix.tsx
|
|
55529
55507
|
/**
|
|
55530
|
-
* DeviceStepMatrix — the
|
|
55531
|
-
* (
|
|
55532
|
-
*
|
|
55533
|
-
*
|
|
55534
|
-
*
|
|
55535
|
-
*
|
|
55536
|
-
*
|
|
55537
|
-
*
|
|
55538
|
-
*
|
|
55539
|
-
*
|
|
55540
|
-
*
|
|
55541
|
-
*
|
|
55542
|
-
*
|
|
55543
|
-
*
|
|
55544
|
-
*
|
|
55545
|
-
*
|
|
55546
|
-
*
|
|
55547
|
-
*
|
|
55548
|
-
*
|
|
55508
|
+
* DeviceStepMatrix — the step × accelerator TABLE of a detection pipeline
|
|
55509
|
+
* (D757): the node's Pipeline tab and the camera's Detection pipeline → Steps
|
|
55510
|
+
* are this matrix, and a click on a cell (or a step's header) opens that step's
|
|
55511
|
+
* settings in a docked panel (`StepDetailDock`) that overlays the page instead
|
|
55512
|
+
* of reflowing the matrix.
|
|
55513
|
+
*
|
|
55514
|
+
* Column 1 (STICKY): the indented step tree — slot, name, class-flow chips,
|
|
55515
|
+
* and an optional badge (the camera's gate). The header is a button: it
|
|
55516
|
+
* opens the step on the selected accelerator.
|
|
55517
|
+
* Columns 2..N: one per accelerator, grouped under their node; the header
|
|
55518
|
+
* names the accelerator, its format, the model it elects, and "off" for a
|
|
55519
|
+
* switched-off one. A cell shows the model that runs there, or "⚠ skip",
|
|
55520
|
+
* "→ iGPU", "root", "cluster", "ovr", "—".
|
|
55521
|
+
*
|
|
55522
|
+
* Keyboard: ONE Tab stop (a roving tabindex over the step headers and cells);
|
|
55523
|
+
* arrows move, Home / End go to the row's ends, Enter or Space opens.
|
|
55524
|
+
*
|
|
55525
|
+
* `reserveRightPx`: the width a docked panel covers at the right of the
|
|
55526
|
+
* viewport. The matrix adds a trailing spacer that wide (so any column can
|
|
55527
|
+
* scroll clear of it) and scrolls the selected cell into the uncovered part —
|
|
55528
|
+
* it never shrinks, so nothing reflows when the panel opens.
|
|
55529
|
+
*
|
|
55530
|
+
* Responsive, container-measured: narrower than the step column plus two
|
|
55531
|
+
* columns, the matrix shows ONE node at a time with a node selector.
|
|
55549
55532
|
*/
|
|
55550
55533
|
/** The sticky step column. */
|
|
55551
55534
|
var STEP_COL_REM = 18;
|
|
@@ -55556,11 +55539,41 @@ var STEP_COL_PX = STEP_COL_REM * 16;
|
|
|
55556
55539
|
* step column and lets the device columns scroll horizontally beside it.
|
|
55557
55540
|
*/
|
|
55558
55541
|
var STEP_COL_SINGLE_REM = 11;
|
|
55559
|
-
|
|
55542
|
+
/** Where a key press moves the roving focus in a `rows × cols` grid. */
|
|
55543
|
+
function nextGridPosition(key, pos, rows, cols) {
|
|
55544
|
+
const clamp = (r, c) => ({
|
|
55545
|
+
r: Math.max(0, Math.min(rows - 1, r)),
|
|
55546
|
+
c: Math.max(0, Math.min(cols - 1, c))
|
|
55547
|
+
});
|
|
55548
|
+
switch (key) {
|
|
55549
|
+
case "ArrowRight": return clamp(pos.r, pos.c + 1);
|
|
55550
|
+
case "ArrowLeft": return clamp(pos.r, pos.c - 1);
|
|
55551
|
+
case "ArrowDown": return clamp(pos.r + 1, pos.c);
|
|
55552
|
+
case "ArrowUp": return clamp(pos.r - 1, pos.c);
|
|
55553
|
+
case "Home": return clamp(pos.r, 0);
|
|
55554
|
+
case "End": return clamp(pos.r, cols - 1);
|
|
55555
|
+
case "PageDown": return clamp(rows - 1, pos.c);
|
|
55556
|
+
case "PageUp": return clamp(0, pos.c);
|
|
55557
|
+
default: return null;
|
|
55558
|
+
}
|
|
55559
|
+
}
|
|
55560
|
+
function StepCell({ node, depth, r, tabbable, selected, badge, onClick, sticky }) {
|
|
55560
55561
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
55561
|
-
|
|
55562
|
-
|
|
55563
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.
|
|
55562
|
+
role: "rowheader",
|
|
55563
|
+
className: cn("min-w-0 border-b border-border bg-surface", sticky && "sticky left-0 z-10"),
|
|
55564
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
55565
|
+
type: "button",
|
|
55566
|
+
"data-r": r,
|
|
55567
|
+
"data-c": 0,
|
|
55568
|
+
"data-step": node.addonId,
|
|
55569
|
+
"data-col": "",
|
|
55570
|
+
tabIndex: tabbable ? 0 : -1,
|
|
55571
|
+
"aria-current": selected ? "true" : void 0,
|
|
55572
|
+
onClick: onClick ? (e) => onClick(e.detail === 0) : void 0,
|
|
55573
|
+
className: cn("flex h-full w-full min-w-0 items-start gap-2 px-3 py-2 text-left text-xs outline-none", "hover:bg-muted/40 focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-primary", selected && "bg-primary/10 shadow-[inset_3px_0_0_var(--color-primary)]"),
|
|
55574
|
+
style: { paddingLeft: `${12 + depth * 14}px` },
|
|
55575
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(StepLabel, { node }), badge]
|
|
55576
|
+
})
|
|
55564
55577
|
});
|
|
55565
55578
|
}
|
|
55566
55579
|
/**
|
|
@@ -55590,68 +55603,179 @@ function NodeSelectorBar({ nodes, selected, onSelect }) {
|
|
|
55590
55603
|
role: "tab",
|
|
55591
55604
|
"aria-selected": isSelected,
|
|
55592
55605
|
onClick: () => onSelect(a.agentNodeId),
|
|
55593
|
-
title: `${a.agentNodeId} · ${a.engineLabel}`,
|
|
55606
|
+
title: `${a.columns[0]?.nodeLabel ?? a.agentNodeId} · ${a.engineLabel}`,
|
|
55594
55607
|
className: cn("px-2.5 py-1 transition-colors", isSelected ? "bg-primary/15 text-primary" : "bg-transparent text-foreground-subtle hover:bg-surface-hover hover:text-foreground", idx > 0 && "border-l border-border"),
|
|
55595
|
-
children: a.agentNodeId
|
|
55608
|
+
children: a.columns[0]?.nodeLabel ?? a.agentNodeId
|
|
55596
55609
|
}, a.agentNodeId);
|
|
55597
55610
|
})
|
|
55598
55611
|
})
|
|
55599
55612
|
]
|
|
55600
55613
|
});
|
|
55601
55614
|
}
|
|
55602
|
-
function MatrixGrid({ tree, agents, getCellState, onCellClick, selectedCell, single }) {
|
|
55615
|
+
var MatrixGrid = (0, react$1.forwardRef)(function MatrixGrid({ tree, agents, getCellState, onCellClick, onStepClick, stepBadge, selectedCell, single, reserveRightPx, label }, ref) {
|
|
55603
55616
|
const rows = (0, react$1.useMemo)(() => flattenTree(tree), [tree]);
|
|
55604
55617
|
const groups = (0, react$1.useMemo)(() => groupAgentColumns(agents), [agents]);
|
|
55618
|
+
const boxRef = (0, react$1.useRef)(null);
|
|
55619
|
+
const stepColRem = single ? STEP_COL_SINGLE_REM : STEP_COL_REM;
|
|
55620
|
+
const gridTemplate = `${stepColRem}rem repeat(${agents.length}, 13rem)`;
|
|
55621
|
+
const cols = agents.length + 1;
|
|
55622
|
+
const [stickySteps, setStickySteps] = (0, react$1.useState)(true);
|
|
55623
|
+
(0, react$1.useLayoutEffect)(() => {
|
|
55624
|
+
const box = boxRef.current;
|
|
55625
|
+
if (!box || reserveRightPx <= 0) {
|
|
55626
|
+
setStickySteps(true);
|
|
55627
|
+
return;
|
|
55628
|
+
}
|
|
55629
|
+
const measure = () => {
|
|
55630
|
+
const left = box.getBoundingClientRect().left;
|
|
55631
|
+
setStickySteps(window.innerWidth - reserveRightPx - left >= stepColRem * 16 + 208 + 24);
|
|
55632
|
+
};
|
|
55633
|
+
measure();
|
|
55634
|
+
window.addEventListener("resize", measure);
|
|
55635
|
+
return () => window.removeEventListener("resize", measure);
|
|
55636
|
+
}, [reserveRightPx, stepColRem]);
|
|
55637
|
+
const selectedPos = (0, react$1.useMemo)(() => {
|
|
55638
|
+
if (selectedCell === null) return null;
|
|
55639
|
+
const r = rows.findIndex((row) => row.node.addonId === selectedCell.addonId);
|
|
55640
|
+
if (r < 0) return null;
|
|
55641
|
+
const c = agents.findIndex((a) => agentColumnKey(a) === agentColumnKey(selectedCell));
|
|
55642
|
+
return {
|
|
55643
|
+
r,
|
|
55644
|
+
c: c < 0 ? 0 : c + 1
|
|
55645
|
+
};
|
|
55646
|
+
}, [
|
|
55647
|
+
selectedCell,
|
|
55648
|
+
rows,
|
|
55649
|
+
agents
|
|
55650
|
+
]);
|
|
55651
|
+
const [focusPos, setFocusPos] = (0, react$1.useState)({
|
|
55652
|
+
r: 0,
|
|
55653
|
+
c: 0
|
|
55654
|
+
});
|
|
55655
|
+
(0, react$1.useEffect)(() => {
|
|
55656
|
+
if (selectedPos !== null) setFocusPos(selectedPos);
|
|
55657
|
+
}, [selectedPos]);
|
|
55658
|
+
const tab = focusPos.r < rows.length && focusPos.c < cols ? focusPos : {
|
|
55659
|
+
r: 0,
|
|
55660
|
+
c: 0
|
|
55661
|
+
};
|
|
55662
|
+
const focusAt = (r, c) => {
|
|
55663
|
+
boxRef.current?.querySelector(`[data-r="${r}"][data-c="${c}"]`)?.focus();
|
|
55664
|
+
};
|
|
55665
|
+
(0, react$1.useImperativeHandle)(ref, () => ({ focusCell: (addonId, columnKey) => {
|
|
55666
|
+
const r = rows.findIndex((row) => row.node.addonId === addonId);
|
|
55667
|
+
if (r < 0) return;
|
|
55668
|
+
const index = columnKey === null ? -1 : agents.findIndex((a) => agentColumnKey(a) === columnKey);
|
|
55669
|
+
const c = index < 0 ? 0 : index + 1;
|
|
55670
|
+
setFocusPos({
|
|
55671
|
+
r,
|
|
55672
|
+
c
|
|
55673
|
+
});
|
|
55674
|
+
focusAt(r, c);
|
|
55675
|
+
} }), [rows, agents]);
|
|
55676
|
+
(0, react$1.useLayoutEffect)(() => {
|
|
55677
|
+
if (selectedPos === null) return;
|
|
55678
|
+
const box = boxRef.current;
|
|
55679
|
+
const el = box?.querySelector(`[data-r="${selectedPos.r}"][data-c="${selectedPos.c}"]`);
|
|
55680
|
+
if (!box || !el) return;
|
|
55681
|
+
if (typeof el.scrollIntoView === "function") el.scrollIntoView({
|
|
55682
|
+
block: "nearest",
|
|
55683
|
+
inline: "nearest"
|
|
55684
|
+
});
|
|
55685
|
+
if (reserveRightPx <= 0) return;
|
|
55686
|
+
const limit = window.innerWidth - reserveRightPx - 12;
|
|
55687
|
+
const right = el.getBoundingClientRect().right;
|
|
55688
|
+
if (right > limit) box.scrollLeft += right - limit;
|
|
55689
|
+
}, [
|
|
55690
|
+
selectedPos,
|
|
55691
|
+
reserveRightPx,
|
|
55692
|
+
stickySteps
|
|
55693
|
+
]);
|
|
55694
|
+
const onKeyDown = (e) => {
|
|
55695
|
+
if (!(e.target instanceof HTMLElement) || e.target.dataset.r === void 0) return;
|
|
55696
|
+
const pos = {
|
|
55697
|
+
r: Number(e.target.dataset.r),
|
|
55698
|
+
c: Number(e.target.dataset.c)
|
|
55699
|
+
};
|
|
55700
|
+
const next = nextGridPosition(e.key, pos, rows.length, cols);
|
|
55701
|
+
if (next === null) return;
|
|
55702
|
+
e.preventDefault();
|
|
55703
|
+
setFocusPos(next);
|
|
55704
|
+
focusAt(next.r, next.c);
|
|
55705
|
+
};
|
|
55605
55706
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
55707
|
+
ref: boxRef,
|
|
55606
55708
|
className: "overflow-auto rounded border border-border",
|
|
55607
55709
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
55608
|
-
className: "
|
|
55609
|
-
|
|
55610
|
-
|
|
55611
|
-
|
|
55612
|
-
|
|
55613
|
-
|
|
55614
|
-
}
|
|
55615
|
-
|
|
55616
|
-
|
|
55710
|
+
className: "flex w-max",
|
|
55711
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
55712
|
+
role: "grid",
|
|
55713
|
+
"aria-label": label,
|
|
55714
|
+
"aria-rowcount": rows.length + 1,
|
|
55715
|
+
className: "grid w-max",
|
|
55716
|
+
style: { gridTemplateColumns: gridTemplate },
|
|
55717
|
+
onKeyDown,
|
|
55718
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
55719
|
+
role: "row",
|
|
55720
|
+
className: "contents",
|
|
55617
55721
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
55618
|
-
|
|
55619
|
-
|
|
55620
|
-
|
|
55621
|
-
|
|
55622
|
-
|
|
55722
|
+
role: "columnheader",
|
|
55723
|
+
className: cn("top-0 z-20 border-b border-border bg-muted/60 px-3 py-2 text-[10px] uppercase tracking-widest text-foreground-subtle", stickySteps ? "sticky left-0" : "sticky"),
|
|
55724
|
+
children: "Step"
|
|
55725
|
+
}), groups.map((group) => group.grouped ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(GroupedAgentHeader, { group }, group.agentNodeId) : group.columns.map((col) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
55726
|
+
role: "columnheader",
|
|
55727
|
+
className: cn("sticky top-0 z-10 min-w-0 border-b border-l border-border bg-muted/60 px-3 py-2", col.disabled === true && "opacity-70"),
|
|
55728
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
55729
|
+
className: "truncate text-xs font-semibold text-foreground",
|
|
55730
|
+
children: col.nodeLabel ?? col.agentNodeId
|
|
55731
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AgentColumnLines, { column: col })]
|
|
55732
|
+
}, agentColumnKey(col))))]
|
|
55733
|
+
}), rows.map(({ node, depth }, r) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
55734
|
+
role: "row",
|
|
55735
|
+
className: "contents",
|
|
55736
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(StepCell, {
|
|
55737
|
+
node,
|
|
55738
|
+
depth,
|
|
55739
|
+
r,
|
|
55740
|
+
tabbable: tab.r === r && tab.c === 0,
|
|
55741
|
+
selected: selectedCell?.addonId === node.addonId,
|
|
55742
|
+
badge: stepBadge?.(node.addonId),
|
|
55743
|
+
onClick: onStepClick ? (kb) => onStepClick(node.addonId, kb) : void 0,
|
|
55744
|
+
sticky: stickySteps
|
|
55745
|
+
}), agents.map((a, i) => {
|
|
55746
|
+
const state = getCellState(node.addonId, a);
|
|
55747
|
+
const isSelected = selectedCell !== null && selectedCell.addonId === node.addonId && agentColumnKey(selectedCell) === agentColumnKey(a);
|
|
55748
|
+
const actionable = state.kind === "enabled" || state.kind === "skip";
|
|
55749
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
55750
|
+
role: "gridcell",
|
|
55751
|
+
className: "min-w-0 border-b border-l border-border",
|
|
55752
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
55753
|
+
type: "button",
|
|
55754
|
+
"data-r": r,
|
|
55755
|
+
"data-c": i + 1,
|
|
55756
|
+
"data-step": node.addonId,
|
|
55757
|
+
"data-col": agentColumnKey(a),
|
|
55758
|
+
tabIndex: tab.r === r && tab.c === i + 1 ? 0 : -1,
|
|
55759
|
+
"aria-disabled": !actionable,
|
|
55760
|
+
"aria-selected": isSelected,
|
|
55761
|
+
onClick: (e) => {
|
|
55762
|
+
if (actionable) onCellClick(node.addonId, a, e.detail === 0);
|
|
55763
|
+
},
|
|
55764
|
+
className: cellButtonClass(state, isSelected, cn("h-full w-full min-w-0 overflow-hidden px-3 py-2 outline-none", "focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-primary", !actionable && "cursor-default hover:bg-transparent", a.disabled === true && "opacity-70")),
|
|
55765
|
+
children: renderCellContent(state)
|
|
55766
|
+
})
|
|
55767
|
+
}, agentColumnKey(a));
|
|
55623
55768
|
})]
|
|
55624
|
-
},
|
|
55625
|
-
|
|
55626
|
-
|
|
55627
|
-
|
|
55628
|
-
|
|
55629
|
-
|
|
55630
|
-
onCellClick,
|
|
55631
|
-
selectedCell
|
|
55632
|
-
}, node.addonId))
|
|
55633
|
-
]
|
|
55769
|
+
}, node.addonId))]
|
|
55770
|
+
}), reserveRightPx > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
55771
|
+
"aria-hidden": true,
|
|
55772
|
+
style: { width: reserveRightPx },
|
|
55773
|
+
className: "shrink-0"
|
|
55774
|
+
})]
|
|
55634
55775
|
})
|
|
55635
55776
|
});
|
|
55636
|
-
}
|
|
55637
|
-
function
|
|
55638
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(StepCell, {
|
|
55639
|
-
node,
|
|
55640
|
-
depth
|
|
55641
|
-
}), agents.map((a) => {
|
|
55642
|
-
const state = getCellState(node.addonId, a);
|
|
55643
|
-
const isSelected = selectedCell !== null && selectedCell.addonId === node.addonId && agentColumnKey(selectedCell) === agentColumnKey(a);
|
|
55644
|
-
const actionable = state.kind === "enabled" || state.kind === "skip";
|
|
55645
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
55646
|
-
type: "button",
|
|
55647
|
-
disabled: !actionable,
|
|
55648
|
-
onClick: () => onCellClick(node.addonId, a),
|
|
55649
|
-
className: cellButtonClass(state, isSelected, cn("min-w-0 overflow-hidden border-b border-l border-border px-3 py-2", !actionable && "cursor-default hover:bg-transparent")),
|
|
55650
|
-
children: renderCellContent(state)
|
|
55651
|
-
}, agentColumnKey(a));
|
|
55652
|
-
})] });
|
|
55653
|
-
}
|
|
55654
|
-
function DeviceStepMatrix({ tree, agents, getCellState, onCellClick, selectedCell, fallbackNodeId, onFallbackNodeChange }) {
|
|
55777
|
+
});
|
|
55778
|
+
var DeviceStepMatrix = (0, react$1.forwardRef)(function DeviceStepMatrix({ tree, agents, getCellState, onCellClick, selectedCell, fallbackNodeId, onFallbackNodeChange, onStepClick, stepBadge, reserveRightPx = 0, label = "Detection steps" }, ref) {
|
|
55655
55779
|
const containerRef = (0, react$1.useRef)(null);
|
|
55656
55780
|
const [width, setWidth] = (0, react$1.useState)(0);
|
|
55657
55781
|
(0, react$1.useLayoutEffect)(() => {
|
|
@@ -55669,6 +55793,15 @@ function DeviceStepMatrix({ tree, agents, getCellState, onCellClick, selectedCel
|
|
|
55669
55793
|
if (nodes.length === 0) return null;
|
|
55670
55794
|
return nodes.find((n) => n.agentNodeId === fallbackNodeId) ?? nodes[0] ?? null;
|
|
55671
55795
|
}, [nodes, fallbackNodeId]);
|
|
55796
|
+
const selectedNodeId = selectedCell?.agentNodeId;
|
|
55797
|
+
(0, react$1.useEffect)(() => {
|
|
55798
|
+
if (single && selectedNodeId !== void 0 && selectedNodeId !== fallbackNodeId) onFallbackNodeChange(selectedNodeId);
|
|
55799
|
+
}, [
|
|
55800
|
+
single,
|
|
55801
|
+
selectedNodeId,
|
|
55802
|
+
fallbackNodeId,
|
|
55803
|
+
onFallbackNodeChange
|
|
55804
|
+
]);
|
|
55672
55805
|
const shownAgents = single && selectedNode ? selectedNode.columns : agents;
|
|
55673
55806
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
55674
55807
|
ref: containerRef,
|
|
@@ -55678,15 +55811,20 @@ function DeviceStepMatrix({ tree, agents, getCellState, onCellClick, selectedCel
|
|
|
55678
55811
|
selected: selectedNode.agentNodeId,
|
|
55679
55812
|
onSelect: onFallbackNodeChange
|
|
55680
55813
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MatrixGrid, {
|
|
55814
|
+
ref,
|
|
55681
55815
|
tree,
|
|
55682
55816
|
agents: shownAgents,
|
|
55683
55817
|
getCellState,
|
|
55684
55818
|
onCellClick,
|
|
55819
|
+
onStepClick,
|
|
55820
|
+
stepBadge,
|
|
55685
55821
|
selectedCell,
|
|
55686
|
-
single: single && selectedNode !== null
|
|
55822
|
+
single: single && selectedNode !== null,
|
|
55823
|
+
reserveRightPx,
|
|
55824
|
+
label
|
|
55687
55825
|
})]
|
|
55688
55826
|
});
|
|
55689
|
-
}
|
|
55827
|
+
});
|
|
55690
55828
|
//#endregion
|
|
55691
55829
|
//#region src/composites/discovery-panel.tsx
|
|
55692
55830
|
function DiscoveryPanel({ deviceId, className = "", onOpenChild }) {
|
|
@@ -56625,43 +56763,13 @@ function PhaseIcon({ phase, ...props }) {
|
|
|
56625
56763
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Icon, { ...props });
|
|
56626
56764
|
}
|
|
56627
56765
|
//#endregion
|
|
56628
|
-
//#region src/lib/validate-template.ts
|
|
56629
|
-
function validateTemplate(steps, schema) {
|
|
56630
|
-
const availableAddonIds = new Set(schema.slots.flatMap((s) => s.addons.map((a) => a.id)));
|
|
56631
|
-
const warnings = [];
|
|
56632
|
-
function validateStep(step) {
|
|
56633
|
-
if (!availableAddonIds.has(step.addonId)) {
|
|
56634
|
-
warnings.push(`Addon "${step.addonId}" is no longer available — step removed`);
|
|
56635
|
-
return null;
|
|
56636
|
-
}
|
|
56637
|
-
const addon = schema.slots.flatMap((s) => s.addons).find((a) => a.id === step.addonId);
|
|
56638
|
-
let modelId = step.modelId;
|
|
56639
|
-
if (addon && !addon.models.some((m) => m.id === modelId)) {
|
|
56640
|
-
const fallback = addon.defaultModelId;
|
|
56641
|
-
warnings.push(`Model "${modelId}" not available for ${step.addonId} — using "${fallback}"`);
|
|
56642
|
-
modelId = fallback;
|
|
56643
|
-
}
|
|
56644
|
-
const validChildren = step.children.map((c) => validateStep(c)).filter((c) => c !== null);
|
|
56645
|
-
return {
|
|
56646
|
-
...step,
|
|
56647
|
-
modelId,
|
|
56648
|
-
children: validChildren
|
|
56649
|
-
};
|
|
56650
|
-
}
|
|
56651
|
-
const validSteps = steps.map((s) => validateStep(s)).filter((s) => s !== null);
|
|
56652
|
-
return {
|
|
56653
|
-
valid: warnings.length === 0,
|
|
56654
|
-
steps: validSteps,
|
|
56655
|
-
warnings
|
|
56656
|
-
};
|
|
56657
|
-
}
|
|
56658
|
-
//#endregion
|
|
56659
56766
|
//#region src/composites/pipeline-builder.tsx
|
|
56660
56767
|
/**
|
|
56661
|
-
* PipelineBuilder — orchestrates the pipeline step tree
|
|
56768
|
+
* PipelineBuilder — orchestrates the pipeline step tree.
|
|
56662
56769
|
*
|
|
56663
|
-
* Renders
|
|
56664
|
-
*
|
|
56770
|
+
* Renders the step tree from schema with nested children and placeholder steps
|
|
56771
|
+
* for disabled addons, all driven by API schema. There are no saved pipeline
|
|
56772
|
+
* templates (D759): the tree is the caller's state.
|
|
56665
56773
|
*/
|
|
56666
56774
|
function buildSchemaMap(schema) {
|
|
56667
56775
|
const map = /* @__PURE__ */ new Map();
|
|
@@ -56713,31 +56821,9 @@ function PlaceholderStep({ addon, onClick }) {
|
|
|
56713
56821
|
})
|
|
56714
56822
|
});
|
|
56715
56823
|
}
|
|
56716
|
-
function PipelineBuilder({ schema, steps, onChange,
|
|
56824
|
+
function PipelineBuilder({ schema, steps, onChange, readOnly = false, excludeAddons = [], showOnlyEnabled = false, showSlotLabels = false }) {
|
|
56717
56825
|
const excluded = (0, react$1.useMemo)(() => new Set(excludeAddons), [excludeAddons]);
|
|
56718
56826
|
const schemaMap = (0, react$1.useMemo)(() => buildSchemaMap(schema), [schema]);
|
|
56719
|
-
const [warnings, setWarnings] = (0, react$1.useState)([]);
|
|
56720
|
-
const dirty = selectedTemplateId ? JSON.stringify(steps) !== JSON.stringify(templates.find((t) => t.id === selectedTemplateId)?.steps) : false;
|
|
56721
|
-
function handleSelectTemplate(e) {
|
|
56722
|
-
const id = e.target.value || null;
|
|
56723
|
-
if (id) {
|
|
56724
|
-
const tpl = templates.find((t) => t.id === id);
|
|
56725
|
-
if (tpl) setWarnings([...validateTemplate(tpl.steps, schema).warnings]);
|
|
56726
|
-
} else setWarnings([]);
|
|
56727
|
-
onSelectTemplate(id);
|
|
56728
|
-
}
|
|
56729
|
-
function handleSave() {
|
|
56730
|
-
if (selectedTemplateId) onUpdateTemplate(selectedTemplateId, steps);
|
|
56731
|
-
}
|
|
56732
|
-
function handleSaveAs() {
|
|
56733
|
-
const name = window.prompt("Template name:");
|
|
56734
|
-
if (name?.trim()) onSaveTemplate(name.trim(), steps);
|
|
56735
|
-
}
|
|
56736
|
-
function handleDelete() {
|
|
56737
|
-
if (!selectedTemplateId) return;
|
|
56738
|
-
const tpl = templates.find((t) => t.id === selectedTemplateId);
|
|
56739
|
-
if (tpl && window.confirm(`Delete template "${tpl.name}"?`)) onDeleteTemplate(selectedTemplateId);
|
|
56740
|
-
}
|
|
56741
56827
|
/**
|
|
56742
56828
|
* When a step is updated, auto-enable the entire ancestor chain if a
|
|
56743
56829
|
* child/grandchild was just enabled. This ensures enabling face-recognition
|
|
@@ -56907,104 +56993,42 @@ function PipelineBuilder({ schema, steps, onChange, templates, selectedTemplateI
|
|
|
56907
56993
|
})]
|
|
56908
56994
|
}, step.addonId);
|
|
56909
56995
|
}
|
|
56910
|
-
|
|
56911
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
56996
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
56912
56997
|
className: "space-y-4",
|
|
56913
|
-
children:
|
|
56914
|
-
|
|
56915
|
-
|
|
56916
|
-
|
|
56917
|
-
|
|
56918
|
-
|
|
56919
|
-
|
|
56920
|
-
|
|
56921
|
-
|
|
56922
|
-
|
|
56923
|
-
|
|
56924
|
-
|
|
56925
|
-
|
|
56926
|
-
|
|
56927
|
-
|
|
56928
|
-
|
|
56929
|
-
|
|
56930
|
-
|
|
56931
|
-
|
|
56932
|
-
|
|
56933
|
-
|
|
56934
|
-
|
|
56935
|
-
|
|
56936
|
-
|
|
56937
|
-
|
|
56938
|
-
|
|
56939
|
-
|
|
56940
|
-
|
|
56941
|
-
|
|
56942
|
-
|
|
56943
|
-
|
|
56944
|
-
|
|
56945
|
-
|
|
56946
|
-
|
|
56947
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CopyPlus, { className: "h-4 w-4" })
|
|
56948
|
-
}),
|
|
56949
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
56950
|
-
onClick: handleDelete,
|
|
56951
|
-
disabled: !selectedTemplateId || readOnly,
|
|
56952
|
-
title: "Delete",
|
|
56953
|
-
className: cn("p-2 rounded-lg border border-border transition-colors", selectedTemplateId && !readOnly ? "text-foreground-subtle hover:text-danger" : "text-foreground-subtle/30 cursor-not-allowed"),
|
|
56954
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Trash2, { className: "h-4 w-4" })
|
|
56955
|
-
})
|
|
56956
|
-
]
|
|
56957
|
-
})
|
|
56958
|
-
}),
|
|
56959
|
-
warnings.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
56960
|
-
className: "rounded-lg border border-amber-500/30 bg-amber-500/5 p-3 text-xs text-amber-400 space-y-1",
|
|
56961
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
56962
|
-
className: "flex items-center justify-between",
|
|
56963
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
56964
|
-
className: "font-medium",
|
|
56965
|
-
children: "Template loaded with warnings:"
|
|
56966
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
56967
|
-
onClick: () => setWarnings([]),
|
|
56968
|
-
className: "text-amber-400/60 hover:text-amber-400",
|
|
56969
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(X, { className: "h-3.5 w-3.5" })
|
|
56970
|
-
})]
|
|
56971
|
-
}), warnings.map((w, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: ["• ", w] }, i))]
|
|
56972
|
-
}),
|
|
56973
|
-
rootSlots.map((slot) => {
|
|
56974
|
-
const allSlotSteps = steps.filter((s) => s.slot === slot.id && !excluded.has(s.addonId));
|
|
56975
|
-
const slotSteps = showOnlyEnabled ? allSlotSteps.filter((s) => s.enabled) : allSlotSteps;
|
|
56976
|
-
const missingRootAddons = showOnlyEnabled ? [] : slot.addons.filter((a) => !existingIds.has(a.id) && !excluded.has(a.id));
|
|
56977
|
-
const groups = /* @__PURE__ */ new Map();
|
|
56978
|
-
const ungrouped = [];
|
|
56979
|
-
for (const step of slotSteps) if (step.group) {
|
|
56980
|
-
if (!groups.has(step.group)) groups.set(step.group, []);
|
|
56981
|
-
groups.get(step.group).push(step);
|
|
56982
|
-
} else ungrouped.push(step);
|
|
56983
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
56984
|
-
className: "space-y-2",
|
|
56985
|
-
children: [
|
|
56986
|
-
showSlotLabels && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
56987
|
-
className: "text-[10px] font-semibold uppercase tracking-widest text-foreground-subtle/50",
|
|
56988
|
-
children: ["Slot: ", slot.label]
|
|
56989
|
-
}),
|
|
56990
|
-
ungrouped.map((step) => renderStep(step)),
|
|
56991
|
-
[...groups.entries()].map(([groupName, groupSteps]) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
56992
|
-
className: "space-y-2 rounded-lg border border-border/40 p-2",
|
|
56993
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
56994
|
-
className: "text-[10px] font-semibold uppercase tracking-widest text-foreground-subtle/50 px-1",
|
|
56995
|
-
children: groupName
|
|
56996
|
-
}), groupSteps.map((step) => renderStep(step))]
|
|
56997
|
-
}, groupName)),
|
|
56998
|
-
!readOnly && missingRootAddons.map((addon) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PlaceholderStep, {
|
|
56999
|
-
addon,
|
|
57000
|
-
onClick: () => {
|
|
57001
|
-
onChange([...steps, createDefaultStep(addon)]);
|
|
57002
|
-
}
|
|
57003
|
-
}, addon.id))
|
|
57004
|
-
]
|
|
57005
|
-
}, slot.id);
|
|
57006
|
-
})
|
|
57007
|
-
]
|
|
56998
|
+
children: schema.slots.filter((s) => s.parentSlot === null).toSorted((a, b) => a.priority - b.priority).map((slot) => {
|
|
56999
|
+
const allSlotSteps = steps.filter((s) => s.slot === slot.id && !excluded.has(s.addonId));
|
|
57000
|
+
const slotSteps = showOnlyEnabled ? allSlotSteps.filter((s) => s.enabled) : allSlotSteps;
|
|
57001
|
+
const missingRootAddons = showOnlyEnabled ? [] : slot.addons.filter((a) => !existingIds.has(a.id) && !excluded.has(a.id));
|
|
57002
|
+
const groups = /* @__PURE__ */ new Map();
|
|
57003
|
+
const ungrouped = [];
|
|
57004
|
+
for (const step of slotSteps) if (step.group) {
|
|
57005
|
+
if (!groups.has(step.group)) groups.set(step.group, []);
|
|
57006
|
+
groups.get(step.group).push(step);
|
|
57007
|
+
} else ungrouped.push(step);
|
|
57008
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
57009
|
+
className: "space-y-2",
|
|
57010
|
+
children: [
|
|
57011
|
+
showSlotLabels && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
57012
|
+
className: "text-[10px] font-semibold uppercase tracking-widest text-foreground-subtle/50",
|
|
57013
|
+
children: ["Slot: ", slot.label]
|
|
57014
|
+
}),
|
|
57015
|
+
ungrouped.map((step) => renderStep(step)),
|
|
57016
|
+
[...groups.entries()].map(([groupName, groupSteps]) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
57017
|
+
className: "space-y-2 rounded-lg border border-border/40 p-2",
|
|
57018
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
57019
|
+
className: "text-[10px] font-semibold uppercase tracking-widest text-foreground-subtle/50 px-1",
|
|
57020
|
+
children: groupName
|
|
57021
|
+
}), groupSteps.map((step) => renderStep(step))]
|
|
57022
|
+
}, groupName)),
|
|
57023
|
+
!readOnly && missingRootAddons.map((addon) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PlaceholderStep, {
|
|
57024
|
+
addon,
|
|
57025
|
+
onClick: () => {
|
|
57026
|
+
onChange([...steps, createDefaultStep(addon)]);
|
|
57027
|
+
}
|
|
57028
|
+
}, addon.id))
|
|
57029
|
+
]
|
|
57030
|
+
}, slot.id);
|
|
57031
|
+
})
|
|
57008
57032
|
});
|
|
57009
57033
|
}
|
|
57010
57034
|
//#endregion
|
|
@@ -57668,39 +57692,6 @@ function StepTimings({ timings, totalMs, className }) {
|
|
|
57668
57692
|
});
|
|
57669
57693
|
}
|
|
57670
57694
|
//#endregion
|
|
57671
|
-
//#region src/composites/step-inspector/accelerator-tabs.tsx
|
|
57672
|
-
function AcceleratorTabs({ items, selectedId, onSelect }) {
|
|
57673
|
-
const onKeyDown = (e, index) => {
|
|
57674
|
-
const delta = e.key === "ArrowRight" ? 1 : e.key === "ArrowLeft" ? -1 : 0;
|
|
57675
|
-
if (delta === 0) return;
|
|
57676
|
-
e.preventDefault();
|
|
57677
|
-
const next = items[(index + delta + items.length) % items.length];
|
|
57678
|
-
if (next !== void 0) onSelect(next.id);
|
|
57679
|
-
};
|
|
57680
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
57681
|
-
role: "tablist",
|
|
57682
|
-
"aria-label": "Accelerator",
|
|
57683
|
-
className: "-mx-1 flex min-w-0 flex-nowrap gap-1 overflow-x-auto px-1 pb-0.5",
|
|
57684
|
-
children: items.map((item, index) => {
|
|
57685
|
-
const selected = item.id === selectedId;
|
|
57686
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
57687
|
-
type: "button",
|
|
57688
|
-
role: "tab",
|
|
57689
|
-
"aria-selected": selected,
|
|
57690
|
-
"aria-label": item.marked ? `${item.label} (camera override)` : item.label,
|
|
57691
|
-
tabIndex: selected ? 0 : -1,
|
|
57692
|
-
onClick: () => onSelect(item.id),
|
|
57693
|
-
onKeyDown: (e) => onKeyDown(e, index),
|
|
57694
|
-
className: cn("inline-flex h-9 shrink-0 items-center gap-1 whitespace-nowrap rounded-md border px-2.5 text-[11px] font-medium transition-colors md:h-7", selected ? "border-primary/50 bg-primary/15 text-primary" : "border-border text-foreground-subtle hover:bg-surface-hover hover:text-foreground"),
|
|
57695
|
-
children: [item.label, item.marked && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
57696
|
-
className: "h-1.5 w-1.5 rounded-full bg-amber-500",
|
|
57697
|
-
"aria-hidden": true
|
|
57698
|
-
})]
|
|
57699
|
-
}, item.id);
|
|
57700
|
-
})
|
|
57701
|
-
});
|
|
57702
|
-
}
|
|
57703
|
-
//#endregion
|
|
57704
57695
|
//#region src/composites/step-inspector/gate-control.tsx
|
|
57705
57696
|
/**
|
|
57706
57697
|
* GateControl — whether ONE camera runs a step: Auto (the catalog default) /
|
|
@@ -57793,166 +57784,104 @@ function SegmentedChoice({ label, options, value, onChange }) {
|
|
|
57793
57784
|
});
|
|
57794
57785
|
}
|
|
57795
57786
|
//#endregion
|
|
57796
|
-
//#region src/composites/step-inspector/step-
|
|
57797
|
-
function chipText(state) {
|
|
57798
|
-
switch (state.kind) {
|
|
57799
|
-
case "enabled":
|
|
57800
|
-
if (state.suppliedByRoot !== void 0) return "root";
|
|
57801
|
-
return state.jumpTo !== void 0 ? `→ ${state.jumpTo}` : state.modelId;
|
|
57802
|
-
case "skip": return state.jumpTo !== void 0 ? `→ ${state.jumpTo}` : "skip";
|
|
57803
|
-
case "disabled": return "off";
|
|
57804
|
-
case "na": return "—";
|
|
57805
|
-
}
|
|
57806
|
-
}
|
|
57807
|
-
/** What a chip MEANS — the full model id, not its shortened text. */
|
|
57808
|
-
function chipKey(state) {
|
|
57809
|
-
return state.kind === "enabled" ? `${state.modelId}|${chipText(state)}` : chipText(state);
|
|
57810
|
-
}
|
|
57811
|
-
function chipTone(state, selected) {
|
|
57812
|
-
if (selected) return "border-primary/60 text-primary";
|
|
57813
|
-
if (state.kind === "skip" && state.jumpTo === void 0) return "border-amber-500/40 text-amber-500";
|
|
57814
|
-
if (state.kind === "na" || state.kind === "disabled") return "border-border/60 text-foreground-subtle/70";
|
|
57815
|
-
return "border-border text-foreground-subtle";
|
|
57816
|
-
}
|
|
57817
|
-
function StepChips({ chips, selectedId }) {
|
|
57818
|
-
const first = chips[0];
|
|
57819
|
-
if (first !== void 0 && chips.length > 1 && chips.every((c) => chipKey(c.state) === chipKey(first.state) && !(c.state.kind === "enabled" && c.state.overridden === true) && chipTone(c.state, c.id === selectedId) === chipTone(first.state, first.id === selectedId)) && first !== void 0) {
|
|
57820
|
-
const text = chipText(first.state);
|
|
57821
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
57822
|
-
className: "flex flex-wrap gap-1",
|
|
57823
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
57824
|
-
title: `${text} on ${chips.map((c) => c.label).join(", ")}`,
|
|
57825
|
-
className: cn("inline-flex max-w-[12rem] items-center gap-1 truncate rounded border px-1 font-mono text-[9px] leading-4", chipTone(first.state, first.id === selectedId)),
|
|
57826
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
57827
|
-
className: "truncate",
|
|
57828
|
-
children: text
|
|
57829
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
57830
|
-
className: "shrink-0 font-sans text-foreground-subtle/80",
|
|
57831
|
-
children: ["×", chips.length]
|
|
57832
|
-
})]
|
|
57833
|
-
})
|
|
57834
|
-
});
|
|
57835
|
-
}
|
|
57836
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
57837
|
-
className: "flex flex-wrap gap-1",
|
|
57838
|
-
children: chips.map((chip) => {
|
|
57839
|
-
const overridden = chip.state.kind === "enabled" && chip.state.overridden === true;
|
|
57840
|
-
const text = chipText(chip.state);
|
|
57841
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
57842
|
-
title: `${chip.label}: ${chip.state.kind === "enabled" ? chip.state.modelId : text}${overridden ? " (camera override)" : ""}`,
|
|
57843
|
-
className: cn("inline-flex max-w-[9rem] items-center gap-0.5 truncate rounded border px-1 font-mono text-[9px] leading-4", chipTone(chip.state, chip.id === selectedId)),
|
|
57844
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
57845
|
-
className: "truncate",
|
|
57846
|
-
children: text
|
|
57847
|
-
}), overridden && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
57848
|
-
className: "text-amber-500",
|
|
57849
|
-
"aria-hidden": true,
|
|
57850
|
-
children: "•"
|
|
57851
|
-
})]
|
|
57852
|
-
}, chip.id);
|
|
57853
|
-
})
|
|
57854
|
-
});
|
|
57855
|
-
}
|
|
57856
|
-
//#endregion
|
|
57857
|
-
//#region src/composites/step-inspector/step-inspector-layout.tsx
|
|
57787
|
+
//#region src/composites/step-inspector/step-detail-dock.tsx
|
|
57858
57788
|
/**
|
|
57859
|
-
*
|
|
57789
|
+
* StepDetailDock — where a step's settings open from the step matrix
|
|
57790
|
+
* (D757): docked to the page's scroll container, never inside the scrolling
|
|
57791
|
+
* content.
|
|
57860
57792
|
*
|
|
57861
|
-
* Desktop:
|
|
57862
|
-
*
|
|
57863
|
-
*
|
|
57864
|
-
* save bar are always on screen
|
|
57865
|
-
*
|
|
57866
|
-
* matrix
|
|
57867
|
-
*
|
|
57868
|
-
*
|
|
57793
|
+
* Desktop: a side panel `position: fixed` over the RIGHT edge of the nearest
|
|
57794
|
+
* scroll container (its top, bottom and right are measured from that box), so
|
|
57795
|
+
* it stays where it is while the matrix scrolls under it, and its header and
|
|
57796
|
+
* save bar are always on screen. It overlays — it never reserves width, so the
|
|
57797
|
+
* matrix does not reflow (the slide-over before D756 reserved 360 px, the
|
|
57798
|
+
* matrix re-measured into a single-node layout, and the clicked cell slid
|
|
57799
|
+
* under the panel). The matrix uses {@link STEP_DOCK_WIDTH_PX} to scroll the
|
|
57800
|
+
* selected column clear of it.
|
|
57869
57801
|
*
|
|
57870
|
-
* Phone:
|
|
57871
|
-
* sheet with "‹ Steps" to go back.
|
|
57802
|
+
* Phone: a full-screen `Dialog` sheet.
|
|
57872
57803
|
*/
|
|
57873
|
-
/**
|
|
57874
|
-
|
|
57875
|
-
|
|
57876
|
-
|
|
57804
|
+
/** Width of the desktop dock — what the matrix keeps clear of it. */
|
|
57805
|
+
var STEP_DOCK_WIDTH_PX = 432;
|
|
57806
|
+
/** The dock's viewport box, from its scroll container's box. */
|
|
57807
|
+
function dockBox(input) {
|
|
57808
|
+
const right = Math.max(0, input.viewportWidth - input.scroller.right);
|
|
57809
|
+
const width = Math.min(input.widthPx, input.scroller.right);
|
|
57810
|
+
return {
|
|
57811
|
+
top: Math.max(0, input.scroller.top),
|
|
57812
|
+
height: Math.max(0, input.scroller.bottom - Math.max(0, input.scroller.top)),
|
|
57813
|
+
right,
|
|
57814
|
+
width
|
|
57815
|
+
};
|
|
57877
57816
|
}
|
|
57878
57817
|
function scrollParentOf(el) {
|
|
57879
|
-
for (let p = el
|
|
57818
|
+
for (let p = el?.parentElement ?? null; p !== null; p = p.parentElement) {
|
|
57880
57819
|
const { overflowY } = getComputedStyle(p);
|
|
57881
57820
|
if (overflowY === "auto" || overflowY === "scroll") return p;
|
|
57882
57821
|
}
|
|
57883
57822
|
return null;
|
|
57884
57823
|
}
|
|
57885
|
-
|
|
57886
|
-
|
|
57887
|
-
const ref = (0, react$1.useRef)(null);
|
|
57888
|
-
const [height, setHeight] = (0, react$1.useState)(null);
|
|
57824
|
+
function useDockBox(anchor, enabled) {
|
|
57825
|
+
const [box, setBox] = (0, react$1.useState)(null);
|
|
57889
57826
|
(0, react$1.useLayoutEffect)(() => {
|
|
57890
|
-
|
|
57891
|
-
|
|
57892
|
-
const scroller = scrollParentOf(el);
|
|
57827
|
+
if (!enabled) return;
|
|
57828
|
+
const scroller = scrollParentOf(anchor.current);
|
|
57893
57829
|
const measure = () => {
|
|
57894
|
-
|
|
57895
|
-
|
|
57896
|
-
|
|
57897
|
-
|
|
57898
|
-
|
|
57899
|
-
|
|
57900
|
-
|
|
57901
|
-
|
|
57902
|
-
minPx
|
|
57830
|
+
setBox(dockBox({
|
|
57831
|
+
scroller: scroller?.getBoundingClientRect() ?? {
|
|
57832
|
+
top: 0,
|
|
57833
|
+
bottom: window.innerHeight,
|
|
57834
|
+
right: window.innerWidth
|
|
57835
|
+
},
|
|
57836
|
+
viewportWidth: window.innerWidth,
|
|
57837
|
+
widthPx: 432
|
|
57903
57838
|
}));
|
|
57904
57839
|
};
|
|
57905
57840
|
measure();
|
|
57906
57841
|
const RO = typeof ResizeObserver === "undefined" ? null : new ResizeObserver(measure);
|
|
57907
57842
|
if (scroller) RO?.observe(scroller);
|
|
57908
|
-
if (el.parentElement) RO?.observe(el.parentElement);
|
|
57909
57843
|
window.addEventListener("resize", measure);
|
|
57910
57844
|
return () => {
|
|
57911
57845
|
RO?.disconnect();
|
|
57912
57846
|
window.removeEventListener("resize", measure);
|
|
57913
57847
|
};
|
|
57914
|
-
}, [
|
|
57915
|
-
return
|
|
57916
|
-
ref,
|
|
57917
|
-
height
|
|
57918
|
-
};
|
|
57848
|
+
}, [anchor, enabled]);
|
|
57849
|
+
return box;
|
|
57919
57850
|
}
|
|
57920
|
-
function
|
|
57851
|
+
function StepDetailDock({ open, anchor, onClose, label, children }) {
|
|
57921
57852
|
const isMobile = useIsMobile();
|
|
57922
|
-
const
|
|
57923
|
-
if (isMobile) return /* @__PURE__ */ (0, react_jsx_runtime.
|
|
57924
|
-
|
|
57925
|
-
|
|
57926
|
-
|
|
57927
|
-
|
|
57928
|
-
|
|
57929
|
-
|
|
57930
|
-
|
|
57931
|
-
children:
|
|
57932
|
-
placement: "sheet-on-mobile",
|
|
57933
|
-
scroll: "body",
|
|
57934
|
-
className: "h-[100dvh] max-h-none w-full max-w-full rounded-none border-0 p-0 pt-[env(safe-area-inset-top)] pb-[env(safe-area-inset-bottom)]",
|
|
57935
|
-
children: mobileDetailOpen && detail
|
|
57936
|
-
})
|
|
57937
|
-
})]
|
|
57938
|
-
});
|
|
57939
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
57940
|
-
ref,
|
|
57941
|
-
className: cn("@container/inspector", className),
|
|
57942
|
-
style: height !== null ? { height } : void 0,
|
|
57943
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
57944
|
-
className: cn("grid h-full min-h-0 gap-3", "grid-cols-1 grid-rows-[minmax(9rem,32%)_minmax(0,1fr)]", "@xl/inspector:grid-cols-[minmax(14rem,19rem)_minmax(0,1fr)] @xl/inspector:grid-rows-1"),
|
|
57945
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
57946
|
-
className: cn(SECTION_CARD, "flex min-h-0 flex-col"),
|
|
57947
|
-
children: list
|
|
57948
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
57949
|
-
className: cn(SECTION_CARD, "flex min-h-0 flex-col"),
|
|
57950
|
-
children: detail
|
|
57951
|
-
})]
|
|
57853
|
+
const box = useDockBox(anchor, open && !isMobile);
|
|
57854
|
+
if (isMobile) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Dialog, {
|
|
57855
|
+
open,
|
|
57856
|
+
onOpenChange: (next) => !next && onClose(),
|
|
57857
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DialogContent, {
|
|
57858
|
+
placement: "sheet-on-mobile",
|
|
57859
|
+
scroll: "body",
|
|
57860
|
+
"aria-label": label,
|
|
57861
|
+
className: "h-[100dvh] max-h-none w-full max-w-full rounded-none border-0 p-0 pt-[env(safe-area-inset-top)] pb-[env(safe-area-inset-bottom)]",
|
|
57862
|
+
children: open && children
|
|
57952
57863
|
})
|
|
57953
57864
|
});
|
|
57865
|
+
if (!open) return null;
|
|
57866
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("aside", {
|
|
57867
|
+
"aria-label": label,
|
|
57868
|
+
"data-step-dock": true,
|
|
57869
|
+
className: "fixed z-30 flex flex-col border-l border-border bg-surface shadow-2xl",
|
|
57870
|
+
style: box !== null ? {
|
|
57871
|
+
top: box.top,
|
|
57872
|
+
height: box.height,
|
|
57873
|
+
right: box.right,
|
|
57874
|
+
width: box.width
|
|
57875
|
+
} : {
|
|
57876
|
+
top: 0,
|
|
57877
|
+
bottom: 0,
|
|
57878
|
+
right: 0,
|
|
57879
|
+
width: 432
|
|
57880
|
+
},
|
|
57881
|
+
children
|
|
57882
|
+
});
|
|
57954
57883
|
}
|
|
57955
|
-
/** "‹ Steps" — the phone sheet's way back to the
|
|
57884
|
+
/** "‹ Steps" — the phone sheet's way back to the matrix. */
|
|
57956
57885
|
function BackToStepsButton({ onClick }) {
|
|
57957
57886
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
57958
57887
|
type: "button",
|
|
@@ -57968,36 +57897,42 @@ function BackToStepsButton({ onClick }) {
|
|
|
57968
57897
|
//#region src/composites/step-inspector/step-inspector-panel.tsx
|
|
57969
57898
|
/**
|
|
57970
57899
|
* StepInspectorPanel — the detail pane of the step inspector: a pinned header
|
|
57971
|
-
* (the step
|
|
57972
|
-
* save bar. Nothing in it depends on the page's scroll position — the slide-over
|
|
57900
|
+
* (the clicked step and accelerator, the gate), ONE scrolling body, and a
|
|
57901
|
+
* pinned save bar (with the "applies to" choice, when there is one). Nothing in it depends on the page's scroll position — the slide-over
|
|
57973
57902
|
* it replaced was anchored to the matrix block and scrolled away with it.
|
|
57974
57903
|
*/
|
|
57975
|
-
function SaveBar({ dirtyCount, saving, status, error, onSave, onDiscard }) {
|
|
57904
|
+
function SaveBar({ dirtyCount, saving, status, error, onSave, onDiscard, scope }) {
|
|
57976
57905
|
const dirty = dirtyCount > 0;
|
|
57977
57906
|
const message = saving ? "Saving…" : dirty ? `${dirtyCount} unsaved change${dirtyCount === 1 ? "" : "s"}` : status === "saved" ? "Saved" : status === "error" ? error ?? "Save failed" : "No unsaved changes";
|
|
57978
57907
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("footer", {
|
|
57979
|
-
className: "
|
|
57980
|
-
children: [
|
|
57981
|
-
|
|
57982
|
-
|
|
57983
|
-
|
|
57984
|
-
|
|
57985
|
-
|
|
57986
|
-
|
|
57987
|
-
|
|
57988
|
-
|
|
57989
|
-
|
|
57990
|
-
|
|
57991
|
-
|
|
57992
|
-
|
|
57993
|
-
|
|
57994
|
-
|
|
57995
|
-
|
|
57996
|
-
|
|
57997
|
-
|
|
57998
|
-
|
|
57999
|
-
|
|
58000
|
-
|
|
57908
|
+
className: "shrink-0 space-y-2 border-t border-border bg-surface px-4 py-2 pb-[max(0.5rem,env(safe-area-inset-bottom))] md:pb-2",
|
|
57909
|
+
children: [scope !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
57910
|
+
"data-save-scope": true,
|
|
57911
|
+
children: scope
|
|
57912
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
57913
|
+
className: "flex items-center gap-2",
|
|
57914
|
+
children: [
|
|
57915
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
57916
|
+
role: "status",
|
|
57917
|
+
className: cn("min-w-0 flex-1 truncate text-[11px]", status === "error" && !dirty ? "text-danger" : dirty ? "text-amber-500" : "text-foreground-subtle"),
|
|
57918
|
+
children: message
|
|
57919
|
+
}),
|
|
57920
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
|
|
57921
|
+
variant: "outline",
|
|
57922
|
+
size: "md",
|
|
57923
|
+
disabled: !dirty || saving,
|
|
57924
|
+
onClick: onDiscard,
|
|
57925
|
+
children: "Discard"
|
|
57926
|
+
}),
|
|
57927
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
|
|
57928
|
+
variant: "primary",
|
|
57929
|
+
size: "md",
|
|
57930
|
+
disabled: !dirty || saving,
|
|
57931
|
+
onClick: onSave,
|
|
57932
|
+
children: "Save"
|
|
57933
|
+
})
|
|
57934
|
+
]
|
|
57935
|
+
})]
|
|
58001
57936
|
});
|
|
58002
57937
|
}
|
|
58003
57938
|
var StepInspectorPanel = (0, react$1.forwardRef)(function StepInspectorPanel({ title, subtitle, headerActions, headerExtra, leading, saveBar, onEscape, children, className }, headingRef) {
|
|
@@ -58024,7 +57959,8 @@ var StepInspectorPanel = (0, react$1.forwardRef)(function StepInspectorPanel({ t
|
|
|
58024
57959
|
id: headingId,
|
|
58025
57960
|
ref: headingRef,
|
|
58026
57961
|
tabIndex: -1,
|
|
58027
|
-
|
|
57962
|
+
title,
|
|
57963
|
+
className: "line-clamp-2 break-words text-sm font-semibold leading-snug text-foreground outline-none focus-visible:ring-2 focus-visible:ring-primary rounded",
|
|
58028
57964
|
children: title
|
|
58029
57965
|
}), subtitle !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
58030
57966
|
className: "mt-0.5 text-[11px] text-foreground-subtle",
|
|
@@ -58045,192 +57981,6 @@ var StepInspectorPanel = (0, react$1.forwardRef)(function StepInspectorPanel({ t
|
|
|
58045
57981
|
});
|
|
58046
57982
|
});
|
|
58047
57983
|
//#endregion
|
|
58048
|
-
//#region src/composites/step-inspector/step-list.tsx
|
|
58049
|
-
/**
|
|
58050
|
-
* StepList — the master pane of the step inspector: every detection step of the
|
|
58051
|
-
* tree, one compact row each, as ONE tab stop.
|
|
58052
|
-
*
|
|
58053
|
-
* Keyboard (a listbox with a roving tabindex): ↑/↓/Home/End move the selection,
|
|
58054
|
-
* Enter or → hands focus to the inspector, `/` jumps to the search box. The
|
|
58055
|
-
* search matches a step's name or any of its field labels, so a question about
|
|
58056
|
-
* a knob ("face size", "person") finds the step that owns it; Enter in the box
|
|
58057
|
-
* selects the first hit and says which field it matched.
|
|
58058
|
-
*/
|
|
58059
|
-
function matches(text, tokens) {
|
|
58060
|
-
const lower = text.toLowerCase();
|
|
58061
|
-
return tokens.every((t) => lower.includes(t));
|
|
58062
|
-
}
|
|
58063
|
-
/** Rows matching `query` (all tokens in the name, or all in one field label). */
|
|
58064
|
-
function searchSteps(rows, query) {
|
|
58065
|
-
const tokens = query.trim().toLowerCase().split(/\s+/).filter(Boolean);
|
|
58066
|
-
if (tokens.length === 0) return rows.map((row) => ({ row }));
|
|
58067
|
-
const hits = [];
|
|
58068
|
-
for (const row of rows) {
|
|
58069
|
-
if (matches(row.name, tokens)) {
|
|
58070
|
-
hits.push({ row });
|
|
58071
|
-
continue;
|
|
58072
|
-
}
|
|
58073
|
-
const field = row.fieldLabels.find((l) => matches(l, tokens));
|
|
58074
|
-
if (field !== void 0) hits.push({
|
|
58075
|
-
row,
|
|
58076
|
-
matchedField: field
|
|
58077
|
-
});
|
|
58078
|
-
}
|
|
58079
|
-
return hits;
|
|
58080
|
-
}
|
|
58081
|
-
var StepList = (0, react$1.forwardRef)(function StepList({ rows, selectedId, onSelect, onActivate, onPick, label, className }, ref) {
|
|
58082
|
-
const [query, setQuery] = (0, react$1.useState)("");
|
|
58083
|
-
const listRef = (0, react$1.useRef)(null);
|
|
58084
|
-
const searchRef = (0, react$1.useRef)(null);
|
|
58085
|
-
const hits = (0, react$1.useMemo)(() => searchSteps(rows, query), [rows, query]);
|
|
58086
|
-
const tabStopId = hits.some((h) => h.row.addonId === selectedId) ? selectedId : hits[0]?.row.addonId ?? null;
|
|
58087
|
-
const pendingFocus = (0, react$1.useRef)(null);
|
|
58088
|
-
const tryFocus = (addonId) => {
|
|
58089
|
-
const el = listRef.current?.querySelector(`[data-step-id="${addonId}"]`);
|
|
58090
|
-
if (!el) return false;
|
|
58091
|
-
el.focus();
|
|
58092
|
-
return true;
|
|
58093
|
-
};
|
|
58094
|
-
const focusRow = (addonId) => {
|
|
58095
|
-
if (addonId === null) return;
|
|
58096
|
-
pendingFocus.current = tryFocus(addonId) ? null : addonId;
|
|
58097
|
-
};
|
|
58098
|
-
(0, react$1.useLayoutEffect)(() => {
|
|
58099
|
-
if (pendingFocus.current !== null && tryFocus(pendingFocus.current)) pendingFocus.current = null;
|
|
58100
|
-
});
|
|
58101
|
-
(0, react$1.useImperativeHandle)(ref, () => ({ focusSelected: () => focusRow(selectedId) }), [selectedId]);
|
|
58102
|
-
const move = (index) => {
|
|
58103
|
-
const target = hits[Math.max(0, Math.min(hits.length - 1, index))];
|
|
58104
|
-
if (target === void 0) return;
|
|
58105
|
-
onSelect(target.row.addonId, target.matchedField);
|
|
58106
|
-
focusRow(target.row.addonId);
|
|
58107
|
-
};
|
|
58108
|
-
const onRowKeyDown = (e, index, hit) => {
|
|
58109
|
-
switch (e.key) {
|
|
58110
|
-
case "ArrowDown":
|
|
58111
|
-
e.preventDefault();
|
|
58112
|
-
move(index + 1);
|
|
58113
|
-
return;
|
|
58114
|
-
case "ArrowUp":
|
|
58115
|
-
e.preventDefault();
|
|
58116
|
-
move(index - 1);
|
|
58117
|
-
return;
|
|
58118
|
-
case "Home":
|
|
58119
|
-
e.preventDefault();
|
|
58120
|
-
move(0);
|
|
58121
|
-
return;
|
|
58122
|
-
case "End":
|
|
58123
|
-
e.preventDefault();
|
|
58124
|
-
move(hits.length - 1);
|
|
58125
|
-
return;
|
|
58126
|
-
case "Enter":
|
|
58127
|
-
case "ArrowRight":
|
|
58128
|
-
e.preventDefault();
|
|
58129
|
-
onActivate(hit.row.addonId);
|
|
58130
|
-
return;
|
|
58131
|
-
case "/":
|
|
58132
|
-
e.preventDefault();
|
|
58133
|
-
searchRef.current?.focus();
|
|
58134
|
-
return;
|
|
58135
|
-
default:
|
|
58136
|
-
}
|
|
58137
|
-
};
|
|
58138
|
-
const onSearchKeyDown = (e) => {
|
|
58139
|
-
if (e.key === "Enter") {
|
|
58140
|
-
e.preventDefault();
|
|
58141
|
-
const first = hits[0];
|
|
58142
|
-
if (first !== void 0) {
|
|
58143
|
-
onSelect(first.row.addonId, first.matchedField);
|
|
58144
|
-
onPick?.(first.row.addonId);
|
|
58145
|
-
focusRow(first.row.addonId);
|
|
58146
|
-
}
|
|
58147
|
-
} else if (e.key === "Escape") {
|
|
58148
|
-
e.preventDefault();
|
|
58149
|
-
setQuery("");
|
|
58150
|
-
focusRow(selectedId);
|
|
58151
|
-
} else if (e.key === "ArrowDown") {
|
|
58152
|
-
e.preventDefault();
|
|
58153
|
-
focusRow(tabStopId);
|
|
58154
|
-
}
|
|
58155
|
-
};
|
|
58156
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
58157
|
-
className: cn("flex min-h-0 flex-col", className),
|
|
58158
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
58159
|
-
className: "relative shrink-0 border-b border-border p-1.5",
|
|
58160
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Search, {
|
|
58161
|
-
className: "pointer-events-none absolute left-3.5 top-1/2 h-3.5 w-3.5 -translate-y-1/2 text-foreground-subtle",
|
|
58162
|
-
"aria-hidden": true
|
|
58163
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
58164
|
-
ref: searchRef,
|
|
58165
|
-
type: "search",
|
|
58166
|
-
value: query,
|
|
58167
|
-
onChange: (e) => setQuery(e.target.value),
|
|
58168
|
-
onKeyDown: onSearchKeyDown,
|
|
58169
|
-
placeholder: "Find a step or setting /",
|
|
58170
|
-
"aria-label": "Find a step or setting",
|
|
58171
|
-
className: "h-9 w-full rounded-md border border-border bg-background pl-8 pr-2 text-xs text-foreground outline-none focus:border-primary focus:ring-1 focus:ring-primary/30 md:h-8"
|
|
58172
|
-
})]
|
|
58173
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("ul", {
|
|
58174
|
-
ref: listRef,
|
|
58175
|
-
role: "listbox",
|
|
58176
|
-
"aria-label": label,
|
|
58177
|
-
className: "min-h-0 flex-1 overflow-y-auto py-1",
|
|
58178
|
-
children: [hits.map((hit, index) => {
|
|
58179
|
-
const { row } = hit;
|
|
58180
|
-
const selected = row.addonId === selectedId;
|
|
58181
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
|
|
58182
|
-
role: "option",
|
|
58183
|
-
"aria-selected": selected,
|
|
58184
|
-
tabIndex: row.addonId === tabStopId ? 0 : -1,
|
|
58185
|
-
"data-step-id": row.addonId,
|
|
58186
|
-
onClick: () => {
|
|
58187
|
-
onSelect(row.addonId, hit.matchedField);
|
|
58188
|
-
onPick?.(row.addonId);
|
|
58189
|
-
},
|
|
58190
|
-
onKeyDown: (e) => onRowKeyDown(e, index, hit),
|
|
58191
|
-
className: cn("cursor-pointer border-l-2 py-1 pl-2.5 pr-3 outline-none transition-colors", "focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-primary", selected ? "border-primary bg-primary/10" : "border-transparent hover:bg-muted/40"),
|
|
58192
|
-
children: [
|
|
58193
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
58194
|
-
className: "flex min-w-0 items-baseline gap-2",
|
|
58195
|
-
children: [
|
|
58196
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
58197
|
-
className: "w-[4.5rem] shrink-0 truncate",
|
|
58198
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SlotHeading, { slot: row.slot })
|
|
58199
|
-
}),
|
|
58200
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
58201
|
-
className: cn("min-w-0 flex-1 truncate text-xs font-medium", selected ? "text-foreground" : "text-foreground/90"),
|
|
58202
|
-
style: { paddingLeft: `${row.depth * 12}px` },
|
|
58203
|
-
children: [row.depth > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
58204
|
-
className: "mr-1 text-foreground-subtle/60",
|
|
58205
|
-
"aria-hidden": true,
|
|
58206
|
-
children: "└"
|
|
58207
|
-
}), row.name]
|
|
58208
|
-
}),
|
|
58209
|
-
row.status
|
|
58210
|
-
]
|
|
58211
|
-
}),
|
|
58212
|
-
hit.matchedField !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
58213
|
-
className: "mt-0.5 truncate pl-[5rem] text-[10px] text-primary",
|
|
58214
|
-
children: ["↳ ", hit.matchedField]
|
|
58215
|
-
}),
|
|
58216
|
-
row.detail !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
58217
|
-
className: "mt-0.5 pl-[5rem]",
|
|
58218
|
-
children: row.detail
|
|
58219
|
-
})
|
|
58220
|
-
]
|
|
58221
|
-
}, row.addonId);
|
|
58222
|
-
}), hits.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
|
|
58223
|
-
className: "px-3 py-4 text-center text-[11px] text-foreground-subtle",
|
|
58224
|
-
children: [
|
|
58225
|
-
"No step matches “",
|
|
58226
|
-
query,
|
|
58227
|
-
"”."
|
|
58228
|
-
]
|
|
58229
|
-
})]
|
|
58230
|
-
})]
|
|
58231
|
-
});
|
|
58232
|
-
});
|
|
58233
|
-
//#endregion
|
|
58234
57984
|
//#region src/composites/step-inspector/step-model-row.tsx
|
|
58235
57985
|
var SOURCE_TONE = {
|
|
58236
57986
|
camera: "border-primary/40 bg-primary/10 text-primary",
|
|
@@ -58309,81 +58059,28 @@ function StepModelRow({ label, format, modelId, source, sourceLabel, models, def
|
|
|
58309
58059
|
});
|
|
58310
58060
|
}
|
|
58311
58061
|
//#endregion
|
|
58312
|
-
//#region src/composites/step-inspector/step-
|
|
58313
|
-
|
|
58314
|
-
|
|
58315
|
-
|
|
58316
|
-
* While nothing is pinned, edited or worth a note, the accelerators are
|
|
58317
|
-
* summarised by model — one line per distinct model, naming the accelerators
|
|
58318
|
-
* that run it ("yolov9m-320-int8 · hub iGPU, hub NPU, little-unraid iGPU") —
|
|
58319
|
-
* with "Per accelerator" to open one `StepModelRow` each. Four near-identical
|
|
58320
|
-
* rows pushed the settings, the thing most edits are about, below the fold.
|
|
58321
|
-
* A pin, a pending change or a note (no build here, root-supplied) shows every
|
|
58322
|
-
* row, so nothing that differs from the default is ever folded away.
|
|
58323
|
-
*/
|
|
58324
|
-
/** True when the rows can be summarised: nothing pinned here, edited, or noted. */
|
|
58325
|
-
function modelRowsAreFoldable(rows) {
|
|
58326
|
-
return rows.length >= 2 && rows.every((r) => r.note === void 0 && r.onReset === void 0 && r.changed !== true && !r.expanded);
|
|
58062
|
+
//#region src/composites/step-inspector/step-search.ts
|
|
58063
|
+
function matches(text, tokens) {
|
|
58064
|
+
const lower = text.toLowerCase();
|
|
58065
|
+
return tokens.every((t) => lower.includes(t));
|
|
58327
58066
|
}
|
|
58328
|
-
|
|
58329
|
-
|
|
58067
|
+
/** Steps matching `query` (all tokens in the name, or all in one field label). Empty query = all. */
|
|
58068
|
+
function searchSteps(rows, query) {
|
|
58069
|
+
const tokens = query.trim().toLowerCase().split(/\s+/).filter(Boolean);
|
|
58070
|
+
if (tokens.length === 0) return rows.map((row) => ({ addonId: row.addonId }));
|
|
58071
|
+
const hits = [];
|
|
58330
58072
|
for (const row of rows) {
|
|
58331
|
-
|
|
58332
|
-
|
|
58333
|
-
|
|
58334
|
-
|
|
58335
|
-
|
|
58336
|
-
|
|
58337
|
-
|
|
58338
|
-
|
|
58339
|
-
modelId,
|
|
58340
|
-
labels: [row.label],
|
|
58341
|
-
sourceLabel: row.sourceLabel
|
|
58342
|
-
});
|
|
58343
|
-
}
|
|
58344
|
-
return groups;
|
|
58345
|
-
}
|
|
58346
|
-
function StepModelList({ rows }) {
|
|
58347
|
-
const [open, setOpen] = (0, react$1.useState)(false);
|
|
58348
|
-
if (!open && modelRowsAreFoldable(rows)) {
|
|
58349
|
-
const groups = groupByModel(rows);
|
|
58350
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
58351
|
-
className: cn("rounded-md border border-border", LIST_ROW),
|
|
58352
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
|
|
58353
|
-
className: "space-y-1",
|
|
58354
|
-
children: groups.map((g) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
|
|
58355
|
-
className: "flex flex-wrap items-baseline gap-x-2 text-xs",
|
|
58356
|
-
children: [
|
|
58357
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
58358
|
-
className: "font-mono text-foreground",
|
|
58359
|
-
children: g.modelId
|
|
58360
|
-
}),
|
|
58361
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
58362
|
-
className: "min-w-0 flex-1 text-[11px] text-foreground-subtle",
|
|
58363
|
-
children: g.labels.length === rows.length ? `all ${rows.length} accelerators` : g.labels.join(", ")
|
|
58364
|
-
}),
|
|
58365
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
58366
|
-
className: "rounded border border-border px-1.5 py-px text-[10px] font-medium text-foreground-subtle",
|
|
58367
|
-
children: g.sourceLabel
|
|
58368
|
-
})
|
|
58369
|
-
]
|
|
58370
|
-
}, `${g.modelId}|${g.sourceLabel}`))
|
|
58371
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
58372
|
-
className: "mt-1.5 flex justify-end",
|
|
58373
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
58374
|
-
type: "button",
|
|
58375
|
-
className: cn(BTN_COMPACT, "min-h-9 md:min-h-0"),
|
|
58376
|
-
"aria-expanded": false,
|
|
58377
|
-
onClick: () => setOpen(true),
|
|
58378
|
-
children: "Per accelerator"
|
|
58379
|
-
})
|
|
58380
|
-
})]
|
|
58073
|
+
if (matches(row.name, tokens)) {
|
|
58074
|
+
hits.push({ addonId: row.addonId });
|
|
58075
|
+
continue;
|
|
58076
|
+
}
|
|
58077
|
+
const field = row.fieldLabels.find((l) => matches(l, tokens));
|
|
58078
|
+
if (field !== void 0) hits.push({
|
|
58079
|
+
addonId: row.addonId,
|
|
58080
|
+
matchedField: field
|
|
58381
58081
|
});
|
|
58382
58082
|
}
|
|
58383
|
-
return
|
|
58384
|
-
className: "space-y-2",
|
|
58385
|
-
children: rows.map(({ id, ...row }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(StepModelRow, { ...row }, id))
|
|
58386
|
-
});
|
|
58083
|
+
return hits;
|
|
58387
58084
|
}
|
|
58388
58085
|
//#endregion
|
|
58389
58086
|
//#region src/composites/step-tree.ts
|
|
@@ -59016,29 +58713,19 @@ function StreamPanel({ serverUrl, createSession, sendAnswer, handleOffer, getIce
|
|
|
59016
58713
|
children: [
|
|
59017
58714
|
showStreamStats && streamStats && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
59018
58715
|
className: "px-3 py-1.5 text-[10px] text-foreground-subtle border-b border-border-subtle",
|
|
59019
|
-
children: [
|
|
59020
|
-
|
|
59021
|
-
|
|
59022
|
-
|
|
59023
|
-
|
|
59024
|
-
|
|
59025
|
-
|
|
59026
|
-
|
|
59027
|
-
/* @__PURE__ */ (0, react_jsx_runtime.
|
|
59028
|
-
className: "
|
|
59029
|
-
children:
|
|
59030
|
-
|
|
59031
|
-
|
|
59032
|
-
})]
|
|
59033
|
-
}),
|
|
59034
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
59035
|
-
className: "flex justify-between gap-3",
|
|
59036
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "Uptime" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
59037
|
-
className: "tabular-nums text-foreground",
|
|
59038
|
-
children: fmtUptime(streamStats.uptimeMs)
|
|
59039
|
-
})]
|
|
59040
|
-
})
|
|
59041
|
-
]
|
|
58716
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
58717
|
+
className: "flex justify-between gap-3",
|
|
58718
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "Input" }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
58719
|
+
className: "tabular-nums text-foreground",
|
|
58720
|
+
children: [streamStats.inputFps.toFixed(1), " fps"]
|
|
58721
|
+
})]
|
|
58722
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
58723
|
+
className: "flex justify-between gap-3",
|
|
58724
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "Uptime" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
58725
|
+
className: "tabular-nums text-foreground",
|
|
58726
|
+
children: fmtUptime(streamStats.uptimeMs)
|
|
58727
|
+
})]
|
|
58728
|
+
})]
|
|
59042
58729
|
}),
|
|
59043
58730
|
!showStreamStats && choiceStats && choiceStats.inputFps > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
59044
58731
|
className: "px-3 py-1.5 text-[10px] text-foreground-subtle border-b border-border-subtle",
|
|
@@ -61331,7 +61018,6 @@ var SceneMonitorEditor = (0, react$1.lazy)(() => Promise.resolve().then(() => re
|
|
|
61331
61018
|
/** Lazy-wrapped `PrivacyMaskSettings` — code-split off the main bundle. */
|
|
61332
61019
|
var PrivacyMaskSettings = (0, react$1.lazy)(() => Promise.resolve().then(() => require("./PrivacyMaskSettings-BqjXsXZR.cjs")).then((m) => ({ default: m.PrivacyMaskSettings })));
|
|
61333
61020
|
//#endregion
|
|
61334
|
-
exports.AcceleratorTabs = AcceleratorTabs;
|
|
61335
61021
|
exports.AddonGlobalSettingsForm = AddonGlobalSettingsForm;
|
|
61336
61022
|
exports.AdminLinkQuickAction = AdminLinkQuickAction;
|
|
61337
61023
|
exports.AgentStepEditor = AgentStepEditor;
|
|
@@ -61589,6 +61275,7 @@ exports.SPLIT_PANEL_OUTER = SPLIT_PANEL_OUTER;
|
|
|
61589
61275
|
exports.SPLIT_PANEL_SIDE = SPLIT_PANEL_SIDE;
|
|
61590
61276
|
exports.STACK_GAP = STACK_GAP;
|
|
61591
61277
|
exports.STATE_COLOR = STATE_COLOR;
|
|
61278
|
+
exports.STEP_DOCK_WIDTH_PX = STEP_DOCK_WIDTH_PX;
|
|
61592
61279
|
exports.SceneMonitorEditor = SceneMonitorEditor;
|
|
61593
61280
|
exports.ScopePicker = ScopePicker;
|
|
61594
61281
|
exports.ScriptHeroCard = ScriptHeroCard;
|
|
@@ -61614,11 +61301,8 @@ exports.Square = Square;
|
|
|
61614
61301
|
exports.StatCard = StatCard;
|
|
61615
61302
|
exports.StateValuesStream = StateValuesStream;
|
|
61616
61303
|
exports.StatusBadge = StatusBadge;
|
|
61617
|
-
exports.
|
|
61618
|
-
exports.StepInspectorLayout = StepInspectorLayout;
|
|
61304
|
+
exports.StepDetailDock = StepDetailDock;
|
|
61619
61305
|
exports.StepInspectorPanel = StepInspectorPanel;
|
|
61620
|
-
exports.StepList = StepList;
|
|
61621
|
-
exports.StepModelList = StepModelList;
|
|
61622
61306
|
exports.StepModelRow = StepModelRow;
|
|
61623
61307
|
exports.StepTimings = StepTimings;
|
|
61624
61308
|
exports.Stepper = Stepper;
|
|
@@ -61667,6 +61351,8 @@ exports.WidgetPanel = WidgetPanel;
|
|
|
61667
61351
|
exports.WidgetRegistryProvider = WidgetRegistryProvider;
|
|
61668
61352
|
exports.WidgetSlot = WidgetSlot;
|
|
61669
61353
|
exports.ZoneEditingProvider = ZoneEditingProvider;
|
|
61354
|
+
exports.acceleratorLabel = acceleratorLabel;
|
|
61355
|
+
exports.acceleratorShortLabel = acceleratorShortLabel;
|
|
61670
61356
|
exports.agentColumnKey = agentColumnKey;
|
|
61671
61357
|
exports.allDeviceTypeFilterOptions = allDeviceTypeFilterOptions;
|
|
61672
61358
|
exports.applyFleetQueryDefaults = applyFleetQueryDefaults;
|
|
@@ -61714,12 +61400,12 @@ exports.deviceTypeLabel = deviceTypeLabel;
|
|
|
61714
61400
|
exports.deviceTypeMeta = deviceTypeMeta;
|
|
61715
61401
|
exports.deviceTypeMetaOf = deviceTypeMetaOf;
|
|
61716
61402
|
exports.devicesToOptions = devicesToOptions;
|
|
61403
|
+
exports.dockBox = dockBox;
|
|
61717
61404
|
exports.draftFromQuery = draftFromQuery;
|
|
61718
61405
|
exports.emptyDevicesWidens = emptyDevicesWidens;
|
|
61719
61406
|
exports.emptySessionRun = emptySessionRun;
|
|
61720
61407
|
exports.ensureMfHostInit = ensureMfHostInit;
|
|
61721
61408
|
exports.eventKindLabel = eventKindLabel;
|
|
61722
|
-
exports.fillHeightPx = fillHeightPx;
|
|
61723
61409
|
exports.filterDataTableRows = filterDataTableRows;
|
|
61724
61410
|
exports.filterDeviceOptions = filterDeviceOptions;
|
|
61725
61411
|
exports.filterOptionSelectOptions = filterOptions;
|
|
@@ -61764,9 +61450,9 @@ exports.makeScrubBridge = makeScrubBridge;
|
|
|
61764
61450
|
exports.metadataEntries = metadataEntries;
|
|
61765
61451
|
exports.metadataString = metadataString;
|
|
61766
61452
|
exports.mirror = mirror;
|
|
61767
|
-
exports.modelRowsAreFoldable = modelRowsAreFoldable;
|
|
61768
61453
|
exports.mountAddonPage = mountAddonPage;
|
|
61769
61454
|
exports.mountPath = mountPath;
|
|
61455
|
+
exports.nextGridPosition = nextGridPosition;
|
|
61770
61456
|
exports.nextReconnectAction = nextReconnectAction;
|
|
61771
61457
|
exports.nextSort = nextSort;
|
|
61772
61458
|
exports.nextSortDirection = nextSortDirection;
|
|
@@ -62049,20 +61735,8 @@ exports.useDayNightGetOptions = useDayNightGetOptions;
|
|
|
62049
61735
|
exports.useDayNightGetStatus = useDayNightGetStatus;
|
|
62050
61736
|
exports.useDayNightSetSettings = useDayNightSetSettings;
|
|
62051
61737
|
exports.useDebouncedString = useDebouncedString;
|
|
62052
|
-
exports.useDecoderCreateSession = useDecoderCreateSession;
|
|
62053
|
-
exports.useDecoderDestroySession = useDecoderDestroySession;
|
|
62054
|
-
exports.useDecoderGetFrame = useDecoderGetFrame;
|
|
62055
61738
|
exports.useDecoderGetInfo = useDecoderGetInfo;
|
|
62056
|
-
exports.useDecoderGetShmStats = useDecoderGetShmStats;
|
|
62057
|
-
exports.useDecoderGetStats = useDecoderGetStats;
|
|
62058
|
-
exports.useDecoderListActiveSessions = useDecoderListActiveSessions;
|
|
62059
|
-
exports.useDecoderOpenStream = useDecoderOpenStream;
|
|
62060
|
-
exports.useDecoderPullFrames = useDecoderPullFrames;
|
|
62061
|
-
exports.useDecoderPullHandles = useDecoderPullHandles;
|
|
62062
|
-
exports.useDecoderPushPacket = useDecoderPushPacket;
|
|
62063
61739
|
exports.useDecoderReprobeHwaccel = useDecoderReprobeHwaccel;
|
|
62064
|
-
exports.useDecoderSupportsCodec = useDecoderSupportsCodec;
|
|
62065
|
-
exports.useDecoderUpdateConfig = useDecoderUpdateConfig;
|
|
62066
61740
|
exports.useDetectionPipelineApplyDeviceSettingsPatch = useDetectionPipelineApplyDeviceSettingsPatch;
|
|
62067
61741
|
exports.useDetectionPipelineGetDeviceLiveContribution = useDetectionPipelineGetDeviceLiveContribution;
|
|
62068
61742
|
exports.useDetectionPipelineGetDeviceSettingsContribution = useDetectionPipelineGetDeviceSettingsContribution;
|
|
@@ -62586,7 +62260,6 @@ exports.usePipelineExecutorCacheFrameInPool = usePipelineExecutorCacheFrameInPoo
|
|
|
62586
62260
|
exports.usePipelineExecutorClearDeviceOverrides = usePipelineExecutorClearDeviceOverrides;
|
|
62587
62261
|
exports.usePipelineExecutorClearModelBoundDeviceOverrides = usePipelineExecutorClearModelBoundDeviceOverrides;
|
|
62588
62262
|
exports.usePipelineExecutorDeleteModel = usePipelineExecutorDeleteModel;
|
|
62589
|
-
exports.usePipelineExecutorDeleteTemplate = usePipelineExecutorDeleteTemplate;
|
|
62590
62263
|
exports.usePipelineExecutorDownloadModel = usePipelineExecutorDownloadModel;
|
|
62591
62264
|
exports.usePipelineExecutorGetAddonModels = usePipelineExecutorGetAddonModels;
|
|
62592
62265
|
exports.usePipelineExecutorGetAudioCapabilities = usePipelineExecutorGetAudioCapabilities;
|
|
@@ -62610,22 +62283,18 @@ exports.usePipelineExecutorInferCached = usePipelineExecutorInferCached;
|
|
|
62610
62283
|
exports.usePipelineExecutorKillEngine = usePipelineExecutorKillEngine;
|
|
62611
62284
|
exports.usePipelineExecutorListLoadedEngines = usePipelineExecutorListLoadedEngines;
|
|
62612
62285
|
exports.usePipelineExecutorListReferenceImages = usePipelineExecutorListReferenceImages;
|
|
62613
|
-
exports.usePipelineExecutorListTemplates = usePipelineExecutorListTemplates;
|
|
62614
62286
|
exports.usePipelineExecutorRearmInferenceDevice = usePipelineExecutorRearmInferenceDevice;
|
|
62615
62287
|
exports.usePipelineExecutorRunAudioTest = usePipelineExecutorRunAudioTest;
|
|
62616
62288
|
exports.usePipelineExecutorRunPipeline = usePipelineExecutorRunPipeline;
|
|
62617
62289
|
exports.usePipelineExecutorRunPipelineBatch = usePipelineExecutorRunPipelineBatch;
|
|
62618
|
-
exports.usePipelineExecutorSaveTemplate = usePipelineExecutorSaveTemplate;
|
|
62619
62290
|
exports.usePipelineExecutorSetVideoPipelineSteps = usePipelineExecutorSetVideoPipelineSteps;
|
|
62620
62291
|
exports.usePipelineExecutorSpinEngine = usePipelineExecutorSpinEngine;
|
|
62621
62292
|
exports.usePipelineExecutorUncacheFrame = usePipelineExecutorUncacheFrame;
|
|
62622
|
-
exports.usePipelineExecutorUpdateTemplate = usePipelineExecutorUpdateTemplate;
|
|
62623
62293
|
exports.usePipelineExecutorValidatePipeline = usePipelineExecutorValidatePipeline;
|
|
62624
62294
|
exports.usePipelineOrchestratorApplyAutoTune = usePipelineOrchestratorApplyAutoTune;
|
|
62625
62295
|
exports.usePipelineOrchestratorApplyDeviceSettingsPatch = usePipelineOrchestratorApplyDeviceSettingsPatch;
|
|
62626
62296
|
exports.usePipelineOrchestratorAssignAudio = usePipelineOrchestratorAssignAudio;
|
|
62627
62297
|
exports.usePipelineOrchestratorAssignPipeline = usePipelineOrchestratorAssignPipeline;
|
|
62628
|
-
exports.usePipelineOrchestratorDeleteTemplate = usePipelineOrchestratorDeleteTemplate;
|
|
62629
62298
|
exports.usePipelineOrchestratorGetAgentLoad = usePipelineOrchestratorGetAgentLoad;
|
|
62630
62299
|
exports.usePipelineOrchestratorGetAgentSettings = usePipelineOrchestratorGetAgentSettings;
|
|
62631
62300
|
exports.usePipelineOrchestratorGetAudioAssignment = usePipelineOrchestratorGetAudioAssignment;
|
|
@@ -62651,7 +62320,6 @@ exports.usePipelineOrchestratorGetPipelineDevicePin = usePipelineOrchestratorGet
|
|
|
62651
62320
|
exports.usePipelineOrchestratorGetPlacementStats = usePipelineOrchestratorGetPlacementStats;
|
|
62652
62321
|
exports.usePipelineOrchestratorGetReconcileFromDiskStatus = usePipelineOrchestratorGetReconcileFromDiskStatus;
|
|
62653
62322
|
exports.usePipelineOrchestratorListAgentSettings = usePipelineOrchestratorListAgentSettings;
|
|
62654
|
-
exports.usePipelineOrchestratorListTemplates = usePipelineOrchestratorListTemplates;
|
|
62655
62323
|
exports.usePipelineOrchestratorPauseForStorageMigration = usePipelineOrchestratorPauseForStorageMigration;
|
|
62656
62324
|
exports.usePipelineOrchestratorPlanAutoTune = usePipelineOrchestratorPlanAutoTune;
|
|
62657
62325
|
exports.usePipelineOrchestratorRebalance = usePipelineOrchestratorRebalance;
|
|
@@ -62661,7 +62329,6 @@ exports.usePipelineOrchestratorRequestOccupancyLook = usePipelineOrchestratorReq
|
|
|
62661
62329
|
exports.usePipelineOrchestratorResetNodePipelineDefaults = usePipelineOrchestratorResetNodePipelineDefaults;
|
|
62662
62330
|
exports.usePipelineOrchestratorResolvePipeline = usePipelineOrchestratorResolvePipeline;
|
|
62663
62331
|
exports.usePipelineOrchestratorResumeForStorageMigration = usePipelineOrchestratorResumeForStorageMigration;
|
|
62664
|
-
exports.usePipelineOrchestratorSaveTemplate = usePipelineOrchestratorSaveTemplate;
|
|
62665
62332
|
exports.usePipelineOrchestratorSetAgentCapabilities = usePipelineOrchestratorSetAgentCapabilities;
|
|
62666
62333
|
exports.usePipelineOrchestratorSetAgentDecodeLimits = usePipelineOrchestratorSetAgentDecodeLimits;
|
|
62667
62334
|
exports.usePipelineOrchestratorSetAgentInferenceDevices = usePipelineOrchestratorSetAgentInferenceDevices;
|
|
@@ -62680,7 +62347,6 @@ exports.usePipelineOrchestratorSetShareSource = usePipelineOrchestratorSetShareS
|
|
|
62680
62347
|
exports.usePipelineOrchestratorSuggestShares = usePipelineOrchestratorSuggestShares;
|
|
62681
62348
|
exports.usePipelineOrchestratorUnassignAudio = usePipelineOrchestratorUnassignAudio;
|
|
62682
62349
|
exports.usePipelineOrchestratorUnassignPipeline = usePipelineOrchestratorUnassignPipeline;
|
|
62683
|
-
exports.usePipelineOrchestratorUpdateTemplate = usePipelineOrchestratorUpdateTemplate;
|
|
62684
62350
|
exports.usePipelineRunnerAttachCamera = usePipelineRunnerAttachCamera;
|
|
62685
62351
|
exports.usePipelineRunnerDetachCamera = usePipelineRunnerDetachCamera;
|
|
62686
62352
|
exports.usePipelineRunnerGetAllCameraMetrics = usePipelineRunnerGetAllCameraMetrics;
|
|
@@ -62903,7 +62569,6 @@ exports.useStreamBrokerProbeStream = useStreamBrokerProbeStream;
|
|
|
62903
62569
|
exports.useStreamBrokerProduceEventMedia = useStreamBrokerProduceEventMedia;
|
|
62904
62570
|
exports.useStreamBrokerPublishCameraStream = useStreamBrokerPublishCameraStream;
|
|
62905
62571
|
exports.useStreamBrokerPullAudioChunks = useStreamBrokerPullAudioChunks;
|
|
62906
|
-
exports.useStreamBrokerPullFrameHandles = useStreamBrokerPullFrameHandles;
|
|
62907
62572
|
exports.useStreamBrokerRegenerateRtspToken = useStreamBrokerRegenerateRtspToken;
|
|
62908
62573
|
exports.useStreamBrokerReleaseEgressTranscode = useStreamBrokerReleaseEgressTranscode;
|
|
62909
62574
|
exports.useStreamBrokerReleaseStreamWithCodec = useStreamBrokerReleaseStreamWithCodec;
|
|
@@ -62915,10 +62580,8 @@ exports.useStreamBrokerSetDeviceAudioMute = useStreamBrokerSetDeviceAudioMute;
|
|
|
62915
62580
|
exports.useStreamBrokerSetPreBufferDuration = useStreamBrokerSetPreBufferDuration;
|
|
62916
62581
|
exports.useStreamBrokerSetRtspEnabled = useStreamBrokerSetRtspEnabled;
|
|
62917
62582
|
exports.useStreamBrokerSubscribeAudioChunks = useStreamBrokerSubscribeAudioChunks;
|
|
62918
|
-
exports.useStreamBrokerSubscribeFrames = useStreamBrokerSubscribeFrames;
|
|
62919
62583
|
exports.useStreamBrokerUnassignProfile = useStreamBrokerUnassignProfile;
|
|
62920
62584
|
exports.useStreamBrokerUnsubscribeAudioChunks = useStreamBrokerUnsubscribeAudioChunks;
|
|
62921
|
-
exports.useStreamBrokerUnsubscribeFrames = useStreamBrokerUnsubscribeFrames;
|
|
62922
62585
|
exports.useStreamCatalogGetCatalog = useStreamCatalogGetCatalog;
|
|
62923
62586
|
exports.useStreamParamsGetConfigSchema = useStreamParamsGetConfigSchema;
|
|
62924
62587
|
exports.useStreamParamsGetOptions = useStreamParamsGetOptions;
|