@imperosoft/cris-webui-components 1.2.1 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -2340,6 +2340,9 @@ function CrisViewComm({ comm, classes, icons, className }) {
2340
2340
 
2341
2341
  // src/components/dsp/CrisViewDspFull.tsx
2342
2342
  import { useState as useState6 } from "react";
2343
+ import { useCustomObject as useCustomObject7, useCustomObjectSend as useCustomObjectSend7 } from "@imperosoft/cris-webui-ch5-core";
2344
+
2345
+ // src/components/dsp/CrisViewDspInputs.tsx
2343
2346
  import { useCustomObject as useCustomObject4, useCustomObjectSend as useCustomObjectSend4 } from "@imperosoft/cris-webui-ch5-core";
2344
2347
 
2345
2348
  // src/components/dsp/DspIoPage.tsx
@@ -2391,6 +2394,127 @@ function collapseStrips(channels, links) {
2391
2394
  function linksFor(ln, io) {
2392
2395
  return io === "in" ? ln?.ip : ln?.op;
2393
2396
  }
2397
+ function groupsFor(dg, io) {
2398
+ return io === "in" ? dg?.ip : dg?.op;
2399
+ }
2400
+ function buildLinkIndex(links) {
2401
+ const idx = /* @__PURE__ */ new Map();
2402
+ for (const raw of links ?? []) {
2403
+ const { label, channels } = normalizeLinked(raw);
2404
+ if (channels.length === 0) continue;
2405
+ const info = { label, channels };
2406
+ for (const id of channels) idx.set(id, info);
2407
+ }
2408
+ return idx;
2409
+ }
2410
+ function collapseWithin(ids, byId, linkIdx, idSet, usedLink, consumed) {
2411
+ const strips = [];
2412
+ for (const id of ids) {
2413
+ if (consumed.has(id)) continue;
2414
+ const link = linkIdx.get(id);
2415
+ const contained = !!link && link.channels.every((m) => idSet.has(m));
2416
+ if (link && contained && !usedLink.has(link)) {
2417
+ usedLink.add(link);
2418
+ link.channels.forEach((m) => consumed.add(m));
2419
+ const primary = link.channels.find((m) => byId.has(m));
2420
+ const ref = primary !== void 0 ? byId.get(primary) : void 0;
2421
+ strips.push({
2422
+ kind: "group",
2423
+ key: `g:${link.channels.join("-")}`,
2424
+ label: link.label || ref?.lb || `Grupo ${link.channels[0]}`,
2425
+ channels: link.channels,
2426
+ lv: clampLevel(ref?.lv),
2427
+ mt: ref?.mt ?? false
2428
+ });
2429
+ } else {
2430
+ consumed.add(id);
2431
+ const c = byId.get(id);
2432
+ if (!c) continue;
2433
+ strips.push({
2434
+ kind: "single",
2435
+ key: `c:${c.id}`,
2436
+ label: c.lb ?? `Canal ${c.id}`,
2437
+ channels: [c.id],
2438
+ lv: clampLevel(c.lv),
2439
+ mt: c.mt
2440
+ });
2441
+ }
2442
+ }
2443
+ return strips;
2444
+ }
2445
+ function buildIoSections(channels, links, groups) {
2446
+ if (!groups || groups.length === 0) {
2447
+ return [{ strips: collapseStrips(channels, links) }];
2448
+ }
2449
+ const byId = new Map(channels.map((c) => [c.id, c]));
2450
+ const linkIdx = buildLinkIndex(links);
2451
+ const usedLink = /* @__PURE__ */ new Set();
2452
+ const consumed = /* @__PURE__ */ new Set();
2453
+ const assigned = /* @__PURE__ */ new Set();
2454
+ const sections = [];
2455
+ for (const g of groups) {
2456
+ g.ch.forEach((id) => assigned.add(id));
2457
+ const present = g.ch.filter((id) => byId.has(id));
2458
+ if (present.length === 0) continue;
2459
+ const strips = collapseWithin(present, byId, linkIdx, new Set(g.ch), usedLink, consumed);
2460
+ if (strips.length) sections.push({ groupName: g.id, strips });
2461
+ }
2462
+ const restIds = channels.filter((c) => !assigned.has(c.id)).map((c) => c.id);
2463
+ if (restIds.length) {
2464
+ const strips = collapseWithin(restIds, byId, linkIdx, new Set(restIds), usedLink, consumed);
2465
+ if (strips.length) sections.push({ strips });
2466
+ }
2467
+ return sections;
2468
+ }
2469
+ function buildMixerAxisGrouped(channels, links, groups) {
2470
+ const byId = new Map(channels.map((c) => [c.id, c]));
2471
+ const ordered = [];
2472
+ const groupOf = /* @__PURE__ */ new Map();
2473
+ const assigned = /* @__PURE__ */ new Set();
2474
+ for (const g of groups ?? []) {
2475
+ for (const id of g.ch) {
2476
+ assigned.add(id);
2477
+ const c = byId.get(id);
2478
+ if (c && !groupOf.has(id)) {
2479
+ ordered.push(c);
2480
+ groupOf.set(id, g.id);
2481
+ }
2482
+ }
2483
+ }
2484
+ for (const c of channels) if (!assigned.has(c.id)) ordered.push(c);
2485
+ const items = ordered.map((c) => ({
2486
+ id: c.id,
2487
+ channelLabel: c.lb ?? `${c.id}`,
2488
+ groupName: groupOf.get(c.id)
2489
+ }));
2490
+ const indexById = new Map(ordered.map((c, idx) => [c.id, idx]));
2491
+ let i = 0;
2492
+ while (i < items.length) {
2493
+ const g = items[i].groupName;
2494
+ if (g === void 0) {
2495
+ i++;
2496
+ continue;
2497
+ }
2498
+ let j = i;
2499
+ while (j < items.length && items[j].groupName === g) j++;
2500
+ items[i].groupStart = true;
2501
+ items[i].groupSpan = j - i;
2502
+ i = j;
2503
+ }
2504
+ for (const raw of links ?? []) {
2505
+ const { label, channels: members } = normalizeLinked(raw);
2506
+ if (members.length < 2) continue;
2507
+ const idxs = members.map((n) => indexById.get(n));
2508
+ if (idxs.some((x) => x === void 0)) continue;
2509
+ const indices = idxs.slice().sort((a, b) => a - b);
2510
+ const consecutive = indices.every((x, k) => k === 0 || x === indices[k - 1] + 1);
2511
+ if (!consecutive) continue;
2512
+ items[indices[0]].linkStart = true;
2513
+ items[indices[0]].linkSpan = indices.length;
2514
+ for (const idx of indices) items[idx].linkCommon = label;
2515
+ }
2516
+ return items;
2517
+ }
2394
2518
  function buildMixerAxis(channels, links) {
2395
2519
  const items = channels.map((c) => ({
2396
2520
  id: c.id,
@@ -2489,53 +2613,205 @@ function useHorizontalWheel(ref) {
2489
2613
  }
2490
2614
 
2491
2615
  // src/components/dsp/DspIoPage.tsx
2492
- import { jsx as jsx13 } from "react/jsx-runtime";
2493
- function DspIoPage({ status, io, oid, send, skip, cls, icons, emptyLabel }) {
2616
+ import { jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
2617
+ function DspIoPage({
2618
+ status,
2619
+ io,
2620
+ oid,
2621
+ send,
2622
+ show,
2623
+ skip,
2624
+ cls,
2625
+ icons,
2626
+ emptyLabel,
2627
+ bare = false,
2628
+ suppressEmpty = false
2629
+ }) {
2494
2630
  const scrollRef = useRef4(null);
2495
2631
  useHorizontalWheel(scrollRef);
2632
+ const showSet = show ? new Set(show) : null;
2496
2633
  const skipSet = new Set(skip ?? []);
2634
+ const keep = (id) => (!showSet || showSet.has(id)) && !skipSet.has(id);
2497
2635
  const raw = (io === "in" ? status?.ip : status?.op) ?? [];
2498
- const channels = skipSet.size ? raw.filter((c) => !skipSet.has(c.id)) : raw;
2636
+ const channels = raw.filter((c) => keep(c.id));
2499
2637
  const allLinks = linksFor(status?.ln, io);
2500
- const links = skipSet.size ? allLinks?.filter((g) => (g.ch ?? []).some((id) => !skipSet.has(id))) : allLinks;
2501
- const strips = collapseStrips(channels, links);
2502
- if (strips.length === 0) {
2503
- return /* @__PURE__ */ jsx13("div", { className: cls.message, children: emptyLabel });
2638
+ const links = allLinks?.filter((g) => (g.ch ?? []).some((id) => keep(id)));
2639
+ const groups = groupsFor(status?.dg, io)?.filter((g) => (g.ch ?? []).some((id) => keep(id)));
2640
+ const sections = buildIoSections(channels, links, groups);
2641
+ const hasHeaders = sections.some((s) => s.groupName);
2642
+ const totalStrips = sections.reduce((n, s) => n + s.strips.length, 0);
2643
+ if (totalStrips === 0) {
2644
+ return suppressEmpty ? null : /* @__PURE__ */ jsx13("div", { className: cls.message, children: emptyLabel });
2504
2645
  }
2505
- return /* @__PURE__ */ jsx13("div", { ref: scrollRef, className: "w-full h-full overflow-x-auto no-scrollbar", children: /* @__PURE__ */ jsx13(
2646
+ const row = /* @__PURE__ */ jsx13(
2506
2647
  "div",
2507
2648
  {
2508
2649
  className: "flex h-full items-stretch gap-[0.3em] px-[0.5em] py-[0.5em]",
2509
2650
  style: { minWidth: "min-content" },
2510
- children: strips.map((strip) => /* @__PURE__ */ jsx13(
2511
- DspChannelStrip,
2512
- {
2513
- strip,
2514
- io,
2515
- oid,
2516
- send,
2517
- cls,
2518
- icons
2519
- },
2520
- strip.key
2521
- ))
2651
+ children: sections.map((sec, i) => /* @__PURE__ */ jsxs11("div", { className: "flex flex-col h-full", children: [
2652
+ hasHeaders && // Header band: spans this group's strips. The 1px separator lives only
2653
+ // here (between groups), never down the full channel height.
2654
+ /* @__PURE__ */ jsx13(
2655
+ "div",
2656
+ {
2657
+ className: "flex items-center justify-center shrink-0 h-[2.2em]",
2658
+ style: { borderLeft: i > 0 ? "1px solid rgba(0,0,0,0.4)" : void 0 },
2659
+ children: sec.groupName && /* @__PURE__ */ jsx13("span", { className: cls.groupHeader, title: sec.groupName, children: sec.groupName })
2660
+ }
2661
+ ),
2662
+ /* @__PURE__ */ jsx13("div", { className: "flex flex-1 min-h-0 items-stretch gap-[0.3em]", children: sec.strips.map((strip) => /* @__PURE__ */ jsx13(
2663
+ DspChannelStrip,
2664
+ {
2665
+ strip,
2666
+ io,
2667
+ oid,
2668
+ send,
2669
+ cls,
2670
+ icons
2671
+ },
2672
+ strip.key
2673
+ )) })
2674
+ ] }, sec.groupName ?? `rest:${i}`))
2675
+ }
2676
+ );
2677
+ if (bare) return row;
2678
+ return /* @__PURE__ */ jsx13("div", { ref: scrollRef, className: "w-full h-full overflow-x-auto no-scrollbar", children: row });
2679
+ }
2680
+
2681
+ // src/components/dsp/dspClasses.ts
2682
+ var DSP_CLASS_DEFAULTS = {
2683
+ root: "w-full h-full flex flex-col",
2684
+ header: "relative w-full flex items-end justify-center gap-[0.3em] px-[1em] pt-[0.5em]",
2685
+ content: "w-full flex-1 min-h-0",
2686
+ tab: "w-[10.5em] h-[3.25em] rounded-b-none rounded-lg flex items-center justify-center transition-colors bg-[#4f5152] text-white text-[1.4em] font-bold",
2687
+ tabActive: "bg-[#007ca0]",
2688
+ message: "w-full h-full flex items-center justify-center text-gray-400 text-[2em]",
2689
+ presetWrap: "absolute left-[1em] bottom-[0.3em] h-[4.5em] flex flex-col items-center",
2690
+ presetLabel: "text-[#4f5152] text-[1.4em] leading-none",
2691
+ preset: "w-[8em] h-full rounded-lg flex items-center justify-center transition-colors bg-[#4f5152] text-white",
2692
+ presetActive: "bg-[#007ca0]",
2693
+ presetPressed: "bg-[#006080]",
2694
+ savedFlash: "absolute inset-0 flex items-center justify-center rounded bg-[#22c55e] text-white text-[1.2em] font-bold pointer-events-none",
2695
+ groupHeader: "text-[#4f5152] text-center font-semibold leading-tight text-[1.1em] line-clamp-2 px-[0.3em]",
2696
+ // NOTE: no font-size on the mixer chrome/group cells — their `em` sticky
2697
+ // offsets must match the grid's `em` track widths. Text size lives on the
2698
+ // inner label spans (text-[1.1em]) instead.
2699
+ mixerGroup: "sticky flex items-center justify-center text-center bg-[#282C34] text-white font-semibold leading-tight border border-black/30",
2700
+ mixerGroupV: "sticky flex items-center justify-center bg-[#282C34] text-white font-semibold leading-tight border border-black/30",
2701
+ strip: "flex flex-col items-center gap-[0.4em] h-full w-[9em] flex-none px-[0.3em]",
2702
+ stripLabel: "text-[#4f5152] text-center leading-tight text-[1.1em] line-clamp-3",
2703
+ levelReadout: "text-[1.1em] text-[#4f5152] leading-none opacity-70 mt-[0.5em]",
2704
+ faderBar: "bg-[#c0c0c0] rounded",
2705
+ faderFill: "bg-[#007ca0] rounded",
2706
+ faderThumb: "bg-[#4f5152] rounded",
2707
+ mute: "w-full h-full rounded-lg flex items-center justify-center transition-colors bg-[#4f5152] text-white",
2708
+ muteActive: "bg-[#dc2626] text-white",
2709
+ mixerCorner: "sticky z-30 flex items-center justify-center bg-[#282C34] text-[#4f5152] text-[1.1em] font-bold border border-black/30",
2710
+ mixerChrome: "sticky flex items-center justify-center text-center bg-[#282C34] text-white leading-tight border border-black/30",
2711
+ cell: "z-10 flex items-center justify-center border border-black/30",
2712
+ cellOn: "bg-[#22c55e]",
2713
+ cellOff: "bg-[#4f5152]"
2714
+ };
2715
+ var DSP_ICON_DEFAULTS = {
2716
+ crosspointOn: "audio-volume-ok",
2717
+ muteOff: "audio-volume-high",
2718
+ muteOn: "audio-volume-mute",
2719
+ muteOffFilter: "invert(65%) sepia(70%) saturate(500%) hue-rotate(80deg) brightness(110%) contrast(95%)",
2720
+ muteOnFilter: "brightness(0) invert(1)"
2721
+ };
2722
+ function mergeDefined(defaults4, overrides) {
2723
+ if (!overrides) return { ...defaults4 };
2724
+ const out = { ...defaults4 };
2725
+ Object.keys(overrides).forEach((k) => {
2726
+ const v = overrides[k];
2727
+ if (v !== void 0) out[k] = v;
2728
+ });
2729
+ return out;
2730
+ }
2731
+ function resolveDspClasses(classes) {
2732
+ return mergeDefined(DSP_CLASS_DEFAULTS, classes);
2733
+ }
2734
+ function resolveDspIcons(icons) {
2735
+ return mergeDefined(DSP_ICON_DEFAULTS, icons);
2736
+ }
2737
+
2738
+ // src/components/dsp/CrisViewDspInputs.tsx
2739
+ import { jsx as jsx14 } from "react/jsx-runtime";
2740
+ function CrisViewDspInputs({
2741
+ oid,
2742
+ skip,
2743
+ emptyLabel = "Sin entradas",
2744
+ classes,
2745
+ icons,
2746
+ className
2747
+ }) {
2748
+ const status = useCustomObject4(oid, { subscribe: true });
2749
+ const send = useCustomObjectSend4();
2750
+ const cls = resolveDspClasses(classes);
2751
+ const ic = resolveDspIcons(icons);
2752
+ return /* @__PURE__ */ jsx14("div", { className: `w-full h-full ${className ?? ""}`, children: status === void 0 ? /* @__PURE__ */ jsx14("div", { className: cls.message, children: "Conectando\u2026" }) : /* @__PURE__ */ jsx14(
2753
+ DspIoPage,
2754
+ {
2755
+ status,
2756
+ io: "in",
2757
+ oid,
2758
+ send,
2759
+ skip,
2760
+ cls,
2761
+ icons: ic,
2762
+ emptyLabel
2522
2763
  }
2523
2764
  ) });
2524
2765
  }
2525
2766
 
2767
+ // src/components/dsp/CrisViewDspOutputs.tsx
2768
+ import { useCustomObject as useCustomObject5, useCustomObjectSend as useCustomObjectSend5 } from "@imperosoft/cris-webui-ch5-core";
2769
+ import { jsx as jsx15 } from "react/jsx-runtime";
2770
+ function CrisViewDspOutputs({
2771
+ oid,
2772
+ skip,
2773
+ emptyLabel = "Sin salidas",
2774
+ classes,
2775
+ icons,
2776
+ className
2777
+ }) {
2778
+ const status = useCustomObject5(oid, { subscribe: true });
2779
+ const send = useCustomObjectSend5();
2780
+ const cls = resolveDspClasses(classes);
2781
+ const ic = resolveDspIcons(icons);
2782
+ return /* @__PURE__ */ jsx15("div", { className: `w-full h-full ${className ?? ""}`, children: status === void 0 ? /* @__PURE__ */ jsx15("div", { className: cls.message, children: "Conectando\u2026" }) : /* @__PURE__ */ jsx15(
2783
+ DspIoPage,
2784
+ {
2785
+ status,
2786
+ io: "out",
2787
+ oid,
2788
+ send,
2789
+ skip,
2790
+ cls,
2791
+ icons: ic,
2792
+ emptyLabel
2793
+ }
2794
+ ) });
2795
+ }
2796
+
2797
+ // src/components/dsp/CrisViewDspMixer.tsx
2798
+ import { useCustomObject as useCustomObject6, useCustomObjectSend as useCustomObjectSend6 } from "@imperosoft/cris-webui-ch5-core";
2799
+
2526
2800
  // src/components/dsp/DspMixer.tsx
2527
2801
  import { useRef as useRef5 } from "react";
2528
- import { Fragment as Fragment3, jsx as jsx14, jsxs as jsxs11 } from "react/jsx-runtime";
2802
+ import { Fragment as Fragment3, jsx as jsx16, jsxs as jsxs12 } from "react/jsx-runtime";
2803
+ var GROUP_W = "2.6em";
2529
2804
  var COMMON_W = "9em";
2530
2805
  var CHAN_W = "3em";
2806
+ var GROUP_H = "2.2em";
2531
2807
  var COMMON_H = "2.4em";
2532
2808
  var CHAN_H = "2.1em";
2533
2809
  var CELL_W = "7.5em";
2534
2810
  var ROW_H = "4.5em";
2535
2811
  var DRAG_FACTOR = 0.6;
2536
2812
  function CrosspointOnIcon({ icon }) {
2537
- if (typeof icon !== "string") return /* @__PURE__ */ jsx14(Fragment3, { children: icon });
2538
- return /* @__PURE__ */ jsx14(
2813
+ if (typeof icon !== "string") return /* @__PURE__ */ jsx16(Fragment3, { children: icon });
2814
+ return /* @__PURE__ */ jsx16(
2539
2815
  "img",
2540
2816
  {
2541
2817
  src: getIconUrl(icon),
@@ -2594,11 +2870,16 @@ function DspMixer({ status, oid, send, cls, icons }) {
2594
2870
  pendingRef.current = null;
2595
2871
  };
2596
2872
  if (inputs.length === 0 || outputs.length === 0) {
2597
- return /* @__PURE__ */ jsx14("div", { className: cls.message, children: "Sin crosspoints" });
2873
+ return /* @__PURE__ */ jsx16("div", { className: cls.message, children: "Sin crosspoints" });
2598
2874
  }
2599
- const inAxis = buildMixerAxis(inputs, linksFor(status?.ln, "in"));
2600
- const outAxis = buildMixerAxis(outputs, linksFor(status?.ln, "out"));
2601
- return /* @__PURE__ */ jsx14(
2875
+ const inAxis = buildMixerAxisGrouped(inputs, linksFor(status?.ln, "in"), groupsFor(status?.dg, "in"));
2876
+ const outAxis = buildMixerAxisGrouped(outputs, linksFor(status?.ln, "out"), groupsFor(status?.dg, "out"));
2877
+ const topLink = GROUP_H;
2878
+ const topChan = `calc(${GROUP_H} + ${COMMON_H})`;
2879
+ const leftLink = GROUP_W;
2880
+ const leftChan = `calc(${GROUP_W} + ${COMMON_W})`;
2881
+ const Z = { corner: 40, group: 30, link: 25, chan: 20 };
2882
+ return /* @__PURE__ */ jsx16(
2602
2883
  "div",
2603
2884
  {
2604
2885
  ref: scrollRef,
@@ -2607,125 +2888,212 @@ function DspMixer({ status, oid, send, cls, icons }) {
2607
2888
  onPointerUp,
2608
2889
  onPointerCancel: onPointerUp,
2609
2890
  className: "w-full h-full overflow-auto no-scrollbar relative touch-none select-none cursor-grab",
2610
- children: /* @__PURE__ */ jsxs11(
2891
+ children: /* @__PURE__ */ jsxs12(
2611
2892
  "div",
2612
2893
  {
2613
2894
  className: "grid",
2614
2895
  style: {
2615
- // cols: [output common][output channel][inputs…] rows: [in common][in channel][outputs…]
2616
- gridTemplateColumns: `${COMMON_W} ${CHAN_W} repeat(${inputs.length}, ${CELL_W})`,
2617
- gridTemplateRows: `${COMMON_H} ${CHAN_H} repeat(${outputs.length}, ${ROW_H})`,
2896
+ // cols: [out group][out link][out channel][inputs…] rows: [in group][in link][in channel][outputs…]
2897
+ gridTemplateColumns: `${GROUP_W} ${COMMON_W} ${CHAN_W} repeat(${inputs.length}, ${CELL_W})`,
2898
+ gridTemplateRows: `${GROUP_H} ${COMMON_H} ${CHAN_H} repeat(${outputs.length}, ${ROW_H})`,
2618
2899
  minWidth: "min-content"
2619
2900
  },
2620
2901
  children: [
2621
- /* @__PURE__ */ jsx14(
2902
+ /* @__PURE__ */ jsx16(
2903
+ "div",
2904
+ {
2905
+ "aria-hidden": true,
2906
+ className: "sticky bg-[#282C34]",
2907
+ style: { top: 0, zIndex: 15, gridColumn: "1 / -1", gridRow: "1 / span 3" }
2908
+ }
2909
+ ),
2910
+ /* @__PURE__ */ jsx16(
2911
+ "div",
2912
+ {
2913
+ "aria-hidden": true,
2914
+ className: "sticky bg-[#282C34]",
2915
+ style: { left: 0, zIndex: 15, gridColumn: "1 / span 3", gridRow: "1 / -1" }
2916
+ }
2917
+ ),
2918
+ /* @__PURE__ */ jsx16(
2622
2919
  "div",
2623
2920
  {
2624
2921
  className: cls.mixerCorner,
2625
- style: { top: 0, left: 0, gridColumn: "1 / span 2", gridRow: "1 / span 2" },
2922
+ style: { top: 0, left: 0, zIndex: Z.corner, gridColumn: "1 / span 3", gridRow: "1 / span 3" },
2626
2923
  children: "OUT \\ IN"
2627
2924
  }
2628
2925
  ),
2629
2926
  inAxis.flatMap((it, ii) => {
2630
- const col = 3 + ii;
2631
- if (it.groupCommon !== void 0) {
2632
- const nodes = [
2633
- /* @__PURE__ */ jsx14(
2927
+ const col = 4 + ii;
2928
+ const nodes = [];
2929
+ if (it.groupStart) {
2930
+ nodes.push(
2931
+ /* @__PURE__ */ jsx16(
2634
2932
  "div",
2635
2933
  {
2636
- className: `${cls.mixerChrome} z-20 px-[0.2em]`,
2637
- style: { top: 0, gridRow: "1 / span 2", gridColumn: col, alignItems: "flex-end", paddingBottom: "0.3em" },
2638
- children: /* @__PURE__ */ jsx14("span", { className: "line-clamp-1", children: it.channelLabel })
2934
+ className: cls.mixerGroup,
2935
+ style: { top: 0, zIndex: Z.group, gridRow: 1, gridColumn: `${col} / span ${it.groupSpan}` },
2936
+ title: it.groupName,
2937
+ children: /* @__PURE__ */ jsx16("span", { className: "text-[1.1em] line-clamp-2 px-[0.2em]", children: it.groupName })
2639
2938
  },
2640
- `ich:${it.id}`
2939
+ `igrp:${it.id}`
2641
2940
  )
2642
- ];
2643
- if (it.groupStart) {
2644
- nodes.unshift(
2645
- /* @__PURE__ */ jsx14(
2941
+ );
2942
+ } else if (it.groupName === void 0) {
2943
+ nodes.push(
2944
+ /* @__PURE__ */ jsx16(
2945
+ "div",
2946
+ {
2947
+ className: cls.mixerChrome,
2948
+ style: { top: 0, zIndex: Z.group, gridRow: 1, gridColumn: col }
2949
+ },
2950
+ `ifill:${it.id}`
2951
+ )
2952
+ );
2953
+ }
2954
+ if (it.linkCommon !== void 0) {
2955
+ if (it.linkStart) {
2956
+ nodes.push(
2957
+ /* @__PURE__ */ jsx16(
2646
2958
  "div",
2647
2959
  {
2648
- className: `${cls.mixerChrome} z-25 px-[0.2em] font-semibold`,
2649
- style: { top: 0, gridRow: 1, gridColumn: `${col} / span ${it.groupSpan}` },
2650
- title: it.groupCommon,
2651
- children: /* @__PURE__ */ jsx14("span", { className: "line-clamp-2", children: it.groupCommon })
2960
+ className: `${cls.mixerChrome} px-[0.2em] font-semibold`,
2961
+ style: { top: topLink, zIndex: Z.link, gridRow: 2, gridColumn: `${col} / span ${it.linkSpan}` },
2962
+ title: it.linkCommon,
2963
+ children: /* @__PURE__ */ jsx16("span", { className: "text-[1.1em] line-clamp-2", children: it.linkCommon })
2652
2964
  },
2653
- `icc:${it.id}`
2965
+ `ilnk:${it.id}`
2654
2966
  )
2655
2967
  );
2656
2968
  }
2657
- return nodes;
2969
+ nodes.push(
2970
+ /* @__PURE__ */ jsx16(
2971
+ "div",
2972
+ {
2973
+ className: `${cls.mixerChrome} px-[0.2em]`,
2974
+ style: { top: topChan, zIndex: Z.chan, gridRow: 3, gridColumn: col },
2975
+ title: it.channelLabel,
2976
+ children: /* @__PURE__ */ jsx16("span", { className: "text-[1.1em] line-clamp-1", children: it.channelLabel })
2977
+ },
2978
+ `ichn:${it.id}`
2979
+ )
2980
+ );
2981
+ } else {
2982
+ nodes.push(
2983
+ /* @__PURE__ */ jsx16(
2984
+ "div",
2985
+ {
2986
+ className: cls.mixerChrome,
2987
+ style: { top: topLink, zIndex: Z.link, gridRow: 2, gridColumn: col }
2988
+ },
2989
+ `ilf:${it.id}`
2990
+ ),
2991
+ /* @__PURE__ */ jsx16(
2992
+ "div",
2993
+ {
2994
+ className: `${cls.mixerChrome} px-[0.2em]`,
2995
+ style: { top: topChan, zIndex: Z.chan, gridRow: 3, gridColumn: col },
2996
+ title: it.channelLabel,
2997
+ children: /* @__PURE__ */ jsx16("span", { className: "text-[1.1em] line-clamp-2", children: it.channelLabel })
2998
+ },
2999
+ `ichn:${it.id}`
3000
+ )
3001
+ );
2658
3002
  }
2659
- return [
2660
- /* @__PURE__ */ jsx14(
2661
- "div",
2662
- {
2663
- className: `${cls.mixerChrome} z-20 px-[0.2em]`,
2664
- style: { top: 0, gridRow: "1 / span 2", gridColumn: col, alignItems: "center" },
2665
- title: it.channelLabel,
2666
- children: /* @__PURE__ */ jsx14("span", { className: "line-clamp-3", children: it.channelLabel })
2667
- },
2668
- `is:${it.id}`
2669
- )
2670
- ];
3003
+ return nodes;
2671
3004
  }),
2672
3005
  outAxis.flatMap((it, oo) => {
2673
- const row = 3 + oo;
2674
- if (it.groupCommon !== void 0) {
2675
- const nodes = [
2676
- /* @__PURE__ */ jsx14(
3006
+ const row = 4 + oo;
3007
+ const nodes = [];
3008
+ if (it.groupStart) {
3009
+ nodes.push(
3010
+ /* @__PURE__ */ jsx16(
3011
+ "div",
3012
+ {
3013
+ className: cls.mixerGroupV,
3014
+ style: {
3015
+ left: 0,
3016
+ zIndex: Z.group,
3017
+ gridColumn: 1,
3018
+ gridRow: `${row} / span ${it.groupSpan}`,
3019
+ writingMode: "vertical-rl",
3020
+ transform: "rotate(180deg)"
3021
+ },
3022
+ title: it.groupName,
3023
+ children: /* @__PURE__ */ jsx16("span", { className: "text-[1.1em] line-clamp-2", children: it.groupName })
3024
+ },
3025
+ `ogrp:${it.id}`
3026
+ )
3027
+ );
3028
+ } else if (it.groupName === void 0) {
3029
+ nodes.push(
3030
+ /* @__PURE__ */ jsx16(
2677
3031
  "div",
2678
3032
  {
2679
- className: `${cls.mixerChrome} z-20`,
2680
- style: { left: 0, gridColumn: "1 / span 2", gridRow: row, justifyContent: "flex-end", paddingRight: "0.6em" },
2681
- children: /* @__PURE__ */ jsx14("span", { className: "line-clamp-1", children: it.channelLabel })
3033
+ className: cls.mixerChrome,
3034
+ style: { left: 0, zIndex: Z.group, gridColumn: 1, gridRow: row }
2682
3035
  },
2683
- `och:${it.id}`
3036
+ `ofill:${it.id}`
2684
3037
  )
2685
- ];
2686
- if (it.groupStart) {
2687
- nodes.unshift(
2688
- /* @__PURE__ */ jsx14(
3038
+ );
3039
+ }
3040
+ if (it.linkCommon !== void 0) {
3041
+ if (it.linkStart) {
3042
+ nodes.push(
3043
+ /* @__PURE__ */ jsx16(
2689
3044
  "div",
2690
3045
  {
2691
- className: `${cls.mixerChrome} z-25 justify-start px-[0.4em] font-semibold`,
2692
- style: { left: 0, gridColumn: 1, gridRow: `${row} / span ${it.groupSpan}` },
2693
- title: it.groupCommon,
2694
- children: /* @__PURE__ */ jsx14("span", { className: "line-clamp-2 text-left", children: it.groupCommon })
3046
+ className: `${cls.mixerChrome} justify-start px-[0.4em] font-semibold`,
3047
+ style: { left: leftLink, zIndex: Z.link, gridColumn: 2, gridRow: `${row} / span ${it.linkSpan}` },
3048
+ title: it.linkCommon,
3049
+ children: /* @__PURE__ */ jsx16("span", { className: "text-[1.1em] line-clamp-2 text-left", children: it.linkCommon })
2695
3050
  },
2696
- `occ:${it.id}`
3051
+ `olnk:${it.id}`
2697
3052
  )
2698
3053
  );
2699
3054
  }
2700
- return nodes;
3055
+ nodes.push(
3056
+ /* @__PURE__ */ jsx16(
3057
+ "div",
3058
+ {
3059
+ className: cls.mixerChrome,
3060
+ style: { left: leftChan, zIndex: Z.chan, gridColumn: 3, gridRow: row },
3061
+ title: it.channelLabel,
3062
+ children: /* @__PURE__ */ jsx16("span", { className: "text-[1.1em] line-clamp-1", children: it.channelLabel })
3063
+ },
3064
+ `ochn:${it.id}`
3065
+ )
3066
+ );
3067
+ } else {
3068
+ nodes.push(
3069
+ /* @__PURE__ */ jsx16(
3070
+ "div",
3071
+ {
3072
+ className: `${cls.mixerChrome} justify-start px-[0.4em]`,
3073
+ style: { left: leftLink, zIndex: Z.chan, gridColumn: "2 / span 2", gridRow: row },
3074
+ title: it.channelLabel,
3075
+ children: /* @__PURE__ */ jsx16("span", { className: "text-[1.1em] line-clamp-2 text-left", children: it.channelLabel })
3076
+ },
3077
+ `ochn:${it.id}`
3078
+ )
3079
+ );
2701
3080
  }
2702
- return [
2703
- /* @__PURE__ */ jsx14(
2704
- "div",
2705
- {
2706
- className: `${cls.mixerChrome} z-20 justify-start px-[0.4em]`,
2707
- style: { left: 0, gridColumn: "1 / span 2", gridRow: row },
2708
- title: it.channelLabel,
2709
- children: /* @__PURE__ */ jsx14("span", { className: "line-clamp-2 text-left", children: it.channelLabel })
2710
- },
2711
- `os:${it.id}`
2712
- )
2713
- ];
3081
+ return nodes;
2714
3082
  }),
2715
- outputs.map(
2716
- (o, oo) => inputs.map((i, ii) => {
2717
- const on = isOn(o.id, i.id);
2718
- return /* @__PURE__ */ jsx14(
3083
+ outAxis.map(
3084
+ (orow, oo) => inAxis.map((icol, ii) => {
3085
+ const on = isOn(orow.id, icol.id);
3086
+ return /* @__PURE__ */ jsx16(
2719
3087
  "div",
2720
3088
  {
2721
3089
  "data-cell": true,
2722
- "data-in": i.id,
2723
- "data-out": o.id,
3090
+ "data-in": icol.id,
3091
+ "data-out": orow.id,
2724
3092
  className: `${cls.cell} ${on ? cls.cellOn : cls.cellOff}`,
2725
- style: { gridColumn: 3 + ii, gridRow: 3 + oo },
2726
- children: on && /* @__PURE__ */ jsx14(CrosspointOnIcon, { icon: icons.crosspointOn })
3093
+ style: { gridColumn: 4 + ii, gridRow: 4 + oo },
3094
+ children: on && /* @__PURE__ */ jsx16(CrosspointOnIcon, { icon: icons.crosspointOn })
2727
3095
  },
2728
- `x:${i.id}:${o.id}`
3096
+ `x:${icol.id}:${orow.id}`
2729
3097
  );
2730
3098
  })
2731
3099
  )
@@ -2736,13 +3104,23 @@ function DspMixer({ status, oid, send, cls, icons }) {
2736
3104
  );
2737
3105
  }
2738
3106
 
3107
+ // src/components/dsp/CrisViewDspMixer.tsx
3108
+ import { jsx as jsx17 } from "react/jsx-runtime";
3109
+ function CrisViewDspMixer({ oid, classes, icons, className }) {
3110
+ const status = useCustomObject6(oid, { subscribe: true });
3111
+ const send = useCustomObjectSend6();
3112
+ const cls = resolveDspClasses(classes);
3113
+ const ic = resolveDspIcons(icons);
3114
+ return /* @__PURE__ */ jsx17("div", { className: `w-full h-full ${className ?? ""}`, children: status === void 0 ? /* @__PURE__ */ jsx17("div", { className: cls.message, children: "Conectando\u2026" }) : /* @__PURE__ */ jsx17(DspMixer, { status, oid, send, cls, icons: ic }) });
3115
+ }
3116
+
2739
3117
  // src/components/dsp/DspPresets.tsx
2740
3118
  import { useRef as useRef6, useState as useState5 } from "react";
2741
- import { jsx as jsx15, jsxs as jsxs12 } from "react/jsx-runtime";
3119
+ import { jsx as jsx18, jsxs as jsxs13 } from "react/jsx-runtime";
2742
3120
  var HOLD_MS = 2e3;
2743
3121
  var SAVED_MS = 1e3;
2744
3122
  function PresetButton({ num, name, active, onCall, onSave, cls }) {
2745
- return /* @__PURE__ */ jsx15(
3123
+ return /* @__PURE__ */ jsx18(
2746
3124
  CrisButton,
2747
3125
  {
2748
3126
  onTap: onCall,
@@ -2752,9 +3130,9 @@ function PresetButton({ num, name, active, onCall, onSave, cls }) {
2752
3130
  className: cls.preset,
2753
3131
  classActive: cls.presetActive,
2754
3132
  classPressed: cls.presetPressed,
2755
- children: /* @__PURE__ */ jsxs12("span", { className: "flex items-center justify-center gap-[0.5em]", children: [
2756
- /* @__PURE__ */ jsx15("span", { className: "text-[1.6em] font-bold leading-none", children: num }),
2757
- /* @__PURE__ */ jsx15("span", { className: "text-[1.2em] leading-none", children: name })
3133
+ children: /* @__PURE__ */ jsxs13("span", { className: "flex items-center justify-center gap-[0.5em]", children: [
3134
+ /* @__PURE__ */ jsx18("span", { className: "text-[1.6em] font-bold leading-none", children: num }),
3135
+ /* @__PURE__ */ jsx18("span", { className: "text-[1.2em] leading-none", children: name })
2758
3136
  ] })
2759
3137
  }
2760
3138
  );
@@ -2781,10 +3159,10 @@ function DspPresets({
2781
3159
  if (!sustainedFeedback) return false;
2782
3160
  return p.kind === "local" ? activeLocal === p.id : activeDevice === p.id;
2783
3161
  };
2784
- return /* @__PURE__ */ jsxs12("div", { className: cls.presetWrap, children: [
2785
- /* @__PURE__ */ jsx15("span", { className: cls.presetLabel, children: "Preset" }),
2786
- /* @__PURE__ */ jsxs12("div", { className: "relative flex-1 flex items-stretch gap-[0.3em] mt-[0.25em]", children: [
2787
- presets.map((p) => /* @__PURE__ */ jsx15(
3162
+ return /* @__PURE__ */ jsxs13("div", { className: cls.presetWrap, children: [
3163
+ /* @__PURE__ */ jsx18("span", { className: cls.presetLabel, children: "Preset" }),
3164
+ /* @__PURE__ */ jsxs13("div", { className: "relative flex-1 flex items-stretch gap-[0.3em] mt-[0.25em]", children: [
3165
+ presets.map((p) => /* @__PURE__ */ jsx18(
2788
3166
  PresetButton,
2789
3167
  {
2790
3168
  num: p.id,
@@ -2796,64 +3174,13 @@ function DspPresets({
2796
3174
  },
2797
3175
  p.id
2798
3176
  )),
2799
- saved && /* @__PURE__ */ jsx15("div", { className: cls.savedFlash, children: "Saved" })
3177
+ saved && /* @__PURE__ */ jsx18("div", { className: cls.savedFlash, children: "Saved" })
2800
3178
  ] })
2801
3179
  ] });
2802
3180
  }
2803
3181
 
2804
- // src/components/dsp/dspClasses.ts
2805
- var DSP_CLASS_DEFAULTS = {
2806
- root: "w-full h-full flex flex-col",
2807
- header: "relative w-full flex items-end justify-center gap-[0.3em] px-[1em] pt-[0.5em]",
2808
- content: "w-full flex-1 min-h-0",
2809
- tab: "w-[10.5em] h-[3.25em] rounded-b-none rounded-lg flex items-center justify-center transition-colors bg-[#4f5152] text-white text-[1.4em] font-bold",
2810
- tabActive: "bg-[#007ca0]",
2811
- message: "w-full h-full flex items-center justify-center text-gray-400 text-[2em]",
2812
- presetWrap: "absolute left-[1em] bottom-[0.3em] h-[4.5em] flex flex-col items-center",
2813
- presetLabel: "text-[#4f5152] text-[1.4em] leading-none",
2814
- preset: "w-[8em] h-full rounded-lg flex items-center justify-center transition-colors bg-[#4f5152] text-white",
2815
- presetActive: "bg-[#007ca0]",
2816
- presetPressed: "bg-[#006080]",
2817
- savedFlash: "absolute inset-0 flex items-center justify-center rounded bg-[#22c55e] text-white text-[1.2em] font-bold pointer-events-none",
2818
- strip: "flex flex-col items-center gap-[0.4em] h-full w-[9em] flex-none px-[0.3em]",
2819
- stripLabel: "text-[#4f5152] text-center leading-tight text-[1.1em] line-clamp-3",
2820
- levelReadout: "text-[1.1em] text-[#4f5152] leading-none opacity-70 mt-[0.5em]",
2821
- faderBar: "bg-[#c0c0c0] rounded",
2822
- faderFill: "bg-[#007ca0] rounded",
2823
- faderThumb: "bg-[#4f5152] rounded",
2824
- mute: "w-full h-full rounded-lg flex items-center justify-center transition-colors bg-[#4f5152] text-white",
2825
- muteActive: "bg-[#dc2626] text-white",
2826
- mixerCorner: "sticky z-30 flex items-center justify-center bg-[#282C34] text-[#4f5152] text-[1.1em] font-bold border border-black/30",
2827
- mixerChrome: "sticky flex items-center justify-center text-center bg-[#282C34] text-white text-[1.1em] leading-tight border border-black/30",
2828
- cell: "z-10 flex items-center justify-center border border-black/30",
2829
- cellOn: "bg-[#22c55e]",
2830
- cellOff: "bg-[#4f5152]"
2831
- };
2832
- var DSP_ICON_DEFAULTS = {
2833
- crosspointOn: "audio-volume-ok",
2834
- muteOff: "audio-volume-high",
2835
- muteOn: "audio-volume-mute",
2836
- muteOffFilter: "invert(65%) sepia(70%) saturate(500%) hue-rotate(80deg) brightness(110%) contrast(95%)",
2837
- muteOnFilter: "brightness(0) invert(1)"
2838
- };
2839
- function mergeDefined(defaults4, overrides) {
2840
- if (!overrides) return { ...defaults4 };
2841
- const out = { ...defaults4 };
2842
- Object.keys(overrides).forEach((k) => {
2843
- const v = overrides[k];
2844
- if (v !== void 0) out[k] = v;
2845
- });
2846
- return out;
2847
- }
2848
- function resolveDspClasses(classes) {
2849
- return mergeDefined(DSP_CLASS_DEFAULTS, classes);
2850
- }
2851
- function resolveDspIcons(icons) {
2852
- return mergeDefined(DSP_ICON_DEFAULTS, icons);
2853
- }
2854
-
2855
3182
  // src/components/dsp/CrisViewDspFull.tsx
2856
- import { Fragment as Fragment4, jsx as jsx16, jsxs as jsxs13 } from "react/jsx-runtime";
3183
+ import { Fragment as Fragment4, jsx as jsx19, jsxs as jsxs14 } from "react/jsx-runtime";
2857
3184
  function CrisViewDspFull({
2858
3185
  oid,
2859
3186
  presets,
@@ -2868,10 +3195,9 @@ function CrisViewDspFull({
2868
3195
  }) {
2869
3196
  const safeInitial = initialTab === "mix" && skipCrosspoints ? "in" : initialTab;
2870
3197
  const [tab, setTab] = useState6(safeInitial);
2871
- const status = useCustomObject4(oid, { subscribe: true });
2872
- const send = useCustomObjectSend4();
3198
+ const status = useCustomObject7(oid, { subscribe: true });
3199
+ const send = useCustomObjectSend7();
2873
3200
  const cls = resolveDspClasses(classes);
2874
- const ic = resolveDspIcons(icons);
2875
3201
  const tabs = [
2876
3202
  { id: "in", label: "Inputs" },
2877
3203
  ...skipCrosspoints ? [] : [{ id: "mix", label: "Mixer" }],
@@ -2880,9 +3206,9 @@ function CrisViewDspFull({
2880
3206
  const hasPresets = !!presets && presets.length > 0;
2881
3207
  const activeDevice = status?.pr?.dv ?? status?.ps?.dv;
2882
3208
  const activeLocal = status?.pr?.lc ?? status?.ps?.lc;
2883
- return /* @__PURE__ */ jsxs13("div", { className: `${cls.root} ${className ?? ""}`, children: [
2884
- /* @__PURE__ */ jsxs13("div", { className: cls.header, children: [
2885
- hasPresets && /* @__PURE__ */ jsx16(
3209
+ return /* @__PURE__ */ jsxs14("div", { className: `${cls.root} ${className ?? ""}`, children: [
3210
+ /* @__PURE__ */ jsxs14("div", { className: cls.header, children: [
3211
+ hasPresets && /* @__PURE__ */ jsx19(
2886
3212
  DspPresets,
2887
3213
  {
2888
3214
  oid,
@@ -2894,7 +3220,7 @@ function CrisViewDspFull({
2894
3220
  cls
2895
3221
  }
2896
3222
  ),
2897
- tabs.map((t) => /* @__PURE__ */ jsx16(
3223
+ tabs.map((t) => /* @__PURE__ */ jsx19(
2898
3224
  CrisButton,
2899
3225
  {
2900
3226
  text: t.label,
@@ -2905,39 +3231,82 @@ function CrisViewDspFull({
2905
3231
  },
2906
3232
  t.id
2907
3233
  )),
2908
- /* @__PURE__ */ jsx16(CrisViewComm, { comm: status?.cm, className: "absolute right-[1em] bottom-[0.3em] text-[1.25em]" })
3234
+ /* @__PURE__ */ jsx19(CrisViewComm, { comm: status?.cm, className: "absolute right-[1em] bottom-[0.3em] text-[1.25em]" })
2909
3235
  ] }),
2910
- /* @__PURE__ */ jsx16("div", { className: cls.content, children: status === void 0 ? /* @__PURE__ */ jsx16("div", { className: cls.message, children: "Conectando\u2026" }) : /* @__PURE__ */ jsxs13(Fragment4, { children: [
2911
- tab === "in" && /* @__PURE__ */ jsx16(
2912
- DspIoPage,
2913
- {
2914
- status,
2915
- io: "in",
2916
- oid,
2917
- send,
2918
- skip: skipShowInput,
2919
- cls,
2920
- icons: ic,
2921
- emptyLabel: "Sin entradas"
2922
- }
2923
- ),
2924
- tab === "mix" && !skipCrosspoints && /* @__PURE__ */ jsx16(DspMixer, { status, oid, send, cls, icons: ic }),
2925
- tab === "out" && /* @__PURE__ */ jsx16(
2926
- DspIoPage,
2927
- {
2928
- status,
2929
- io: "out",
2930
- oid,
2931
- send,
2932
- skip: skipShowOutput,
2933
- cls,
2934
- icons: ic,
2935
- emptyLabel: "Sin salidas"
2936
- }
2937
- )
3236
+ /* @__PURE__ */ jsx19("div", { className: cls.content, children: status === void 0 ? /* @__PURE__ */ jsx19("div", { className: cls.message, children: "Conectando\u2026" }) : /* @__PURE__ */ jsxs14(Fragment4, { children: [
3237
+ tab === "in" && /* @__PURE__ */ jsx19(CrisViewDspInputs, { oid, skip: skipShowInput, classes, icons }),
3238
+ tab === "mix" && !skipCrosspoints && /* @__PURE__ */ jsx19(CrisViewDspMixer, { oid, classes, icons }),
3239
+ tab === "out" && /* @__PURE__ */ jsx19(CrisViewDspOutputs, { oid, skip: skipShowOutput, classes, icons })
2938
3240
  ] }) })
2939
3241
  ] });
2940
3242
  }
3243
+
3244
+ // src/components/dsp/CrisViewDspPresets.tsx
3245
+ import { useCustomObject as useCustomObject8, useCustomObjectSend as useCustomObjectSend8 } from "@imperosoft/cris-webui-ch5-core";
3246
+ import { jsx as jsx20 } from "react/jsx-runtime";
3247
+ function CrisViewDspPresets({
3248
+ oid,
3249
+ presets,
3250
+ sustainedPresetFeedback = true,
3251
+ classes,
3252
+ className
3253
+ }) {
3254
+ const status = useCustomObject8(oid, { subscribe: true });
3255
+ const send = useCustomObjectSend8();
3256
+ const cls = resolveDspClasses({ presetWrap: "flex flex-col items-center", ...classes });
3257
+ const activeDevice = status?.pr?.dv ?? status?.ps?.dv;
3258
+ const activeLocal = status?.pr?.lc ?? status?.ps?.lc;
3259
+ return /* @__PURE__ */ jsx20("div", { className, children: /* @__PURE__ */ jsx20(
3260
+ DspPresets,
3261
+ {
3262
+ oid,
3263
+ send,
3264
+ presets,
3265
+ activeDevice,
3266
+ activeLocal,
3267
+ sustainedFeedback: sustainedPresetFeedback,
3268
+ cls
3269
+ }
3270
+ ) });
3271
+ }
3272
+
3273
+ // src/components/dsp/CrisViewDspChannels.tsx
3274
+ import { useCustomObject as useCustomObject9, useCustomObjectSend as useCustomObjectSend9 } from "@imperosoft/cris-webui-ch5-core";
3275
+ import { jsx as jsx21 } from "react/jsx-runtime";
3276
+ function CrisViewDspChannels({
3277
+ oid,
3278
+ io,
3279
+ show,
3280
+ scroll = false,
3281
+ showEmpty = false,
3282
+ emptyLabel = "",
3283
+ classes,
3284
+ icons,
3285
+ className
3286
+ }) {
3287
+ const status = useCustomObject9(oid, { subscribe: true });
3288
+ const send = useCustomObjectSend9();
3289
+ const cls = resolveDspClasses(classes);
3290
+ const ic = resolveDspIcons(icons);
3291
+ if (status === void 0) {
3292
+ return showEmpty ? /* @__PURE__ */ jsx21("div", { className: cls.message, children: "Conectando\u2026" }) : null;
3293
+ }
3294
+ return /* @__PURE__ */ jsx21("div", { className, children: /* @__PURE__ */ jsx21(
3295
+ DspIoPage,
3296
+ {
3297
+ status,
3298
+ io,
3299
+ oid,
3300
+ send,
3301
+ show,
3302
+ cls,
3303
+ icons: ic,
3304
+ emptyLabel,
3305
+ bare: !scroll,
3306
+ suppressEmpty: !showEmpty
3307
+ }
3308
+ ) });
3309
+ }
2941
3310
  export {
2942
3311
  CrisButton,
2943
3312
  CrisCoDebug,
@@ -2950,8 +3319,15 @@ export {
2950
3319
  CrisText,
2951
3320
  CrisTextInput,
2952
3321
  CrisViewComm,
3322
+ CrisViewDspChannels,
2953
3323
  CrisViewDspFull,
3324
+ CrisViewDspInputs,
3325
+ CrisViewDspMixer,
3326
+ CrisViewDspOutputs,
3327
+ CrisViewDspPresets,
3328
+ buildIoSections,
2954
3329
  buildMixerAxis,
3330
+ buildMixerAxisGrouped,
2955
3331
  clampLevel,
2956
3332
  collapseStrips,
2957
3333
  commIndicators,
@@ -2959,6 +3335,7 @@ export {
2959
3335
  getIconConfig,
2960
3336
  getIconFilter,
2961
3337
  getIconUrl,
3338
+ groupsFor,
2962
3339
  levelToPercent,
2963
3340
  linksFor,
2964
3341
  normalizeLinked