@norskvideo/norsk-studio-built-ins 1.27.0-2025-03-21-b19a3aff → 1.27.0-2025-03-25-1268af9f

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.
Files changed (59) hide show
  1. package/client/info.js +350 -149
  2. package/client/style.css +28 -0
  3. package/lib/info.js +17 -15
  4. package/lib/info.js.map +1 -1
  5. package/lib/output.srt-caller/info.js +102 -0
  6. package/lib/output.srt-caller/info.js.map +1 -0
  7. package/lib/output.srt-caller/inline-view.js +10 -0
  8. package/lib/output.srt-caller/inline-view.js.map +1 -0
  9. package/lib/{output.srt → output.srt-caller}/runtime.d.ts +12 -1
  10. package/lib/{output.srt → output.srt-caller}/runtime.js +18 -0
  11. package/lib/output.srt-caller/runtime.js.map +1 -0
  12. package/lib/output.srt-caller/srt-packet-metrics.d.ts +4 -0
  13. package/lib/output.srt-caller/srt-packet-metrics.js +10 -0
  14. package/lib/output.srt-caller/srt-packet-metrics.js.map +1 -0
  15. package/lib/output.srt-caller/summary-view.js.map +1 -0
  16. package/lib/{output.srt → output.srt-caller}/types.js.map +1 -1
  17. package/lib/output.srt-listener/info.d.ts +3 -0
  18. package/lib/{output.srt → output.srt-listener}/info.js +18 -20
  19. package/lib/output.srt-listener/info.js.map +1 -0
  20. package/lib/output.srt-listener/inline-view.d.ts +6 -0
  21. package/lib/output.srt-listener/inline-view.js +10 -0
  22. package/lib/output.srt-listener/inline-view.js.map +1 -0
  23. package/lib/output.srt-listener/runtime.d.ts +51 -0
  24. package/lib/output.srt-listener/runtime.js +160 -0
  25. package/lib/output.srt-listener/runtime.js.map +1 -0
  26. package/lib/output.srt-listener/srt-packet-metrics.d.ts +4 -0
  27. package/lib/output.srt-listener/srt-packet-metrics.js +12 -0
  28. package/lib/output.srt-listener/srt-packet-metrics.js.map +1 -0
  29. package/lib/output.srt-listener/summary-view.d.ts +4 -0
  30. package/lib/output.srt-listener/summary-view.js +24 -0
  31. package/lib/output.srt-listener/summary-view.js.map +1 -0
  32. package/lib/output.srt-listener/types.d.ts +101 -0
  33. package/lib/output.srt-listener/types.js +3 -0
  34. package/lib/output.srt-listener/types.js.map +1 -0
  35. package/lib/output.srt-listener/types.yaml +31 -0
  36. package/lib/processor.onscreenGraphic/image-selection.js +1 -1
  37. package/lib/processor.onscreenGraphic/image-selection.js.map +1 -1
  38. package/lib/processor.onscreenGraphic/summary-view.js +1 -1
  39. package/lib/processor.onscreenGraphic/summary-view.js.map +1 -1
  40. package/lib/test/srt-output-caller.js +176 -0
  41. package/lib/test/srt-output-caller.js.map +1 -0
  42. package/lib/test/srt-output-listener.d.ts +1 -0
  43. package/lib/test/{srt-output.js → srt-output-listener.js} +3 -4
  44. package/lib/test/srt-output-listener.js.map +1 -0
  45. package/package.json +3 -3
  46. package/lib/output.srt/info.js.map +0 -1
  47. package/lib/output.srt/inline-view.js +0 -8
  48. package/lib/output.srt/inline-view.js.map +0 -1
  49. package/lib/output.srt/runtime.js.map +0 -1
  50. package/lib/output.srt/summary-view.js.map +0 -1
  51. package/lib/test/srt-output.js.map +0 -1
  52. /package/lib/{output.srt → output.srt-caller}/info.d.ts +0 -0
  53. /package/lib/{output.srt → output.srt-caller}/inline-view.d.ts +0 -0
  54. /package/lib/{output.srt → output.srt-caller}/summary-view.d.ts +0 -0
  55. /package/lib/{output.srt → output.srt-caller}/summary-view.js +0 -0
  56. /package/lib/{output.srt → output.srt-caller}/types.d.ts +0 -0
  57. /package/lib/{output.srt → output.srt-caller}/types.js +0 -0
  58. /package/lib/{output.srt → output.srt-caller}/types.yaml +0 -0
  59. /package/lib/test/{srt-output.d.ts → srt-output-caller.d.ts} +0 -0
package/client/info.js CHANGED
@@ -4705,8 +4705,13 @@ var require_util2 = __commonJS({
4705
4705
  exports.getObjectByType = getObjectByType;
4706
4706
  exports.getObjectByPath = getObjectByPath;
4707
4707
  exports.displayNodeId = displayNodeId;
4708
- exports.assertUnreachable = assertUnreachable15;
4708
+ exports.assertUnreachable = assertUnreachable16;
4709
4709
  exports.waitForCondition = waitForCondition;
4710
+ exports.streamMatchesExpected = streamMatchesExpected;
4711
+ exports.shortStreamNameFromDefinition = shortStreamNameFromDefinition;
4712
+ exports.shortStreamNameFromFilter = shortStreamNameFromFilter;
4713
+ exports.streamNameFromDefinition = streamNameFromDefinition;
4714
+ exports.streamNameFromFilter = streamNameFromFilter;
4710
4715
  function baseUrl(env, websocket) {
4711
4716
  const guess = new URL(window.location.origin);
4712
4717
  const base = env.studioUrlPrefix ? new URL(env.studioUrlPrefix, guess) : guess;
@@ -4770,7 +4775,7 @@ var require_util2 = __commonJS({
4770
4775
  }
4771
4776
  return document2.components[id]?.config?.displayName ?? id;
4772
4777
  }
4773
- function assertUnreachable15(_) {
4778
+ function assertUnreachable16(_) {
4774
4779
  throw new Error("Didn't expect to get here");
4775
4780
  }
4776
4781
  async function waitForCondition(condition, timeout, interval) {
@@ -4789,6 +4794,70 @@ var require_util2 = __commonJS({
4789
4794
  }, timeout ?? 2e3);
4790
4795
  });
4791
4796
  }
4797
+ function streamMatchesExpected(s, expectedStreams) {
4798
+ const matchingStream = expectedStreams.find((expected) => {
4799
+ if (expected.media !== s.message.case)
4800
+ return false;
4801
+ if (expected.programNumber !== void 0 && s.streamKey.programNumber !== expected.programNumber)
4802
+ return false;
4803
+ if (expected.streamId !== void 0 && s.streamKey.streamId !== expected.streamId)
4804
+ return false;
4805
+ if (expected.renditionName !== void 0 && s.streamKey.renditionName !== expected.renditionName)
4806
+ return false;
4807
+ if (expected.sourceName !== void 0 && s.streamKey.sourceName !== expected.sourceName)
4808
+ return false;
4809
+ return true;
4810
+ });
4811
+ return !!matchingStream;
4812
+ }
4813
+ function shortStreamNameFromDefinition(s) {
4814
+ const components = [s.media];
4815
+ if (s.sourceName)
4816
+ components.push(s.sourceName.toString());
4817
+ else if (s.programNumber)
4818
+ components.push(s.programNumber.toString());
4819
+ else if (s.streamId)
4820
+ components.push(s.streamId.toString());
4821
+ else if (s.renditionName)
4822
+ components.push(s.renditionName.toString());
4823
+ return components.join("-");
4824
+ }
4825
+ function shortStreamNameFromFilter(s) {
4826
+ const components = [s.media];
4827
+ if (s.sourceName)
4828
+ components.push(s.sourceName.toString());
4829
+ else if (s.programNumber)
4830
+ components.push(s.programNumber.toString());
4831
+ else if (s.streamId)
4832
+ components.push(s.streamId.toString());
4833
+ else if (s.renditionName)
4834
+ components.push(s.renditionName.toString());
4835
+ return components.join("-");
4836
+ }
4837
+ function streamNameFromDefinition(s) {
4838
+ const components = [s.media];
4839
+ if (s.sourceName)
4840
+ components.push(s.sourceName.toString());
4841
+ if (s.programNumber)
4842
+ components.push(s.programNumber.toString());
4843
+ if (s.streamId)
4844
+ components.push(s.streamId.toString());
4845
+ if (s.renditionName)
4846
+ components.push(s.renditionName.toString());
4847
+ return components.join("-");
4848
+ }
4849
+ function streamNameFromFilter(s) {
4850
+ const components = [s.media];
4851
+ if (s.sourceName)
4852
+ components.push(s.sourceName.toString());
4853
+ if (s.programNumber)
4854
+ components.push(s.programNumber.toString());
4855
+ if (s.streamId)
4856
+ components.push(s.streamId.toString());
4857
+ if (s.renditionName)
4858
+ components.push(s.renditionName.toString());
4859
+ return components.join("-");
4860
+ }
4792
4861
  }
4793
4862
  });
4794
4863
 
@@ -6383,10 +6452,10 @@ function assertUnreachable5(_) {
6383
6452
  throw new Error("Didn't expect to get here");
6384
6453
  }
6385
6454
 
6386
- // build/output.srt/info.js
6455
+ // build/output.srt-caller/info.js
6387
6456
  var import_util = __toESM(require_util2());
6388
6457
 
6389
- // build/output.srt/summary-view.js
6458
+ // build/output.srt-caller/summary-view.js
6390
6459
  var import_jsx_runtime13 = __toESM(require_jsx_runtime());
6391
6460
  function SummaryView5({ state, sendCommand }) {
6392
6461
  const handleEnableOutput = () => {
@@ -6409,21 +6478,27 @@ function SummaryView5({ state, sendCommand }) {
6409
6478
  }
6410
6479
  var summary_view_default5 = SummaryView5;
6411
6480
 
6412
- // build/output.srt/inline-view.js
6481
+ // build/output.srt-caller/inline-view.js
6413
6482
  var import_jsx_runtime14 = __toESM(require_jsx_runtime());
6414
6483
  function InlineView6({ state }) {
6415
- return (0, import_jsx_runtime14.jsx)("div", { className: "srt-output", children: state.enabled ? (0, import_jsx_runtime14.jsx)("div", { className: "active text-green-500 dark:text-green-300", children: "Output enabled" }) : (0, import_jsx_runtime14.jsx)("div", { className: "disabled text-gray-500 dark:text-gray-400", children: "Output disabled" }) });
6484
+ return (0, import_jsx_runtime14.jsx)("div", { className: "srt-output", children: state.enabled ? (0, import_jsx_runtime14.jsx)("div", { children: state.metrics.connectionCount == 0 ? (0, import_jsx_runtime14.jsx)("div", { className: "active text-red-300 dark:text-red-300", children: "Not Connected" }) : (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [(0, import_jsx_runtime14.jsx)("div", { className: "active text-green-500 dark:text-green-300", children: "Output enabled" }), (0, import_jsx_runtime14.jsxs)("div", { children: ["Sent: ", state.metrics.packetsSent] }), (0, import_jsx_runtime14.jsxs)("div", { children: ["Lost/Resent: ", state.metrics.packetsLost, "/", state.metrics.packetsResent] })] }) }) : (0, import_jsx_runtime14.jsx)("div", { className: "disabled text-gray-500 dark:text-gray-400", children: "Output disabled" }) });
6416
6485
  }
6417
6486
  var inline_view_default6 = InlineView6;
6418
6487
 
6419
- // build/output.srt/info.js
6488
+ // build/output.srt-caller/srt-packet-metrics.js
6489
+ var import_jsx_runtime15 = __toESM(require_jsx_runtime());
6490
+ function MetricsView({ state }) {
6491
+ return (0, import_jsx_runtime15.jsx)("div", { className: "srt-output", children: state.enabled ? (0, import_jsx_runtime15.jsx)("div", { children: state.metrics.connectionCount == 0 ? (0, import_jsx_runtime15.jsx)("div", { className: "active text-red-300 dark:text-red-300", children: "Not Connected" }) : (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [(0, import_jsx_runtime15.jsx)("div", { className: "active text-green-500 dark:text-green-300", children: "Output enabled" }), (0, import_jsx_runtime15.jsxs)("div", { children: ["Sent: ", state.metrics.packetsSent] }), (0, import_jsx_runtime15.jsxs)("div", { children: ["Lost/Resent: ", state.metrics.packetsLost, "/", state.metrics.packetsResent] })] }) }) : (0, import_jsx_runtime15.jsx)("div", { className: "disabled text-gray-500 dark:text-gray-400", children: "Output disabled" }) });
6492
+ }
6493
+
6494
+ // build/output.srt-caller/info.js
6420
6495
  function info_default13(registration) {
6421
6496
  const { defineComponent, All, validation } = registration;
6422
6497
  const { Port, Hostname, JitterBuffer, SrtPassphrase, SrtStreamId } = validation;
6423
6498
  return defineComponent({
6424
- identifier: "output.srt",
6499
+ identifier: "output.srt-caller",
6425
6500
  category: "output",
6426
- name: "SRT Egest",
6501
+ name: "SRT Caller Egest",
6427
6502
  description: "This component manages the sending of SRT (Secure Reliable Transport) streams. It allows you to configure various settings to control how the SRT output is handled, including connection details, buffer settings, and delay options.",
6428
6503
  subscription: {
6429
6504
  accepts: {
@@ -6436,13 +6511,18 @@ function info_default13(registration) {
6436
6511
  return {
6437
6512
  port: desc.config.port?.toString() ?? "",
6438
6513
  host: desc.config.host,
6439
- mode: desc.config.mode,
6440
6514
  bufferDelayMs: desc.config.bufferDelayMs?.toString() ?? "none"
6441
6515
  };
6442
6516
  },
6443
6517
  runtime: {
6444
6518
  initialState: () => ({
6445
- enabled: true
6519
+ enabled: true,
6520
+ metrics: {
6521
+ connectionCount: 0,
6522
+ packetsLost: 0,
6523
+ packetsResent: 0,
6524
+ packetsSent: 0
6525
+ }
6446
6526
  }),
6447
6527
  handleEvent(ev, state) {
6448
6528
  const evType = ev.type;
@@ -6453,49 +6533,169 @@ function info_default13(registration) {
6453
6533
  case "output-disabled":
6454
6534
  state.enabled = false;
6455
6535
  break;
6536
+ case "metrics-updated":
6537
+ state.metrics = ev.metrics;
6538
+ break;
6456
6539
  default:
6457
6540
  (0, import_util.assertUnreachable)(evType);
6458
6541
  }
6459
6542
  return { ...state };
6460
6543
  },
6461
6544
  summary: summary_view_default5,
6462
- inline: inline_view_default6
6545
+ inline: inline_view_default6,
6546
+ metrics: [
6547
+ {
6548
+ title: "SRT Transmission",
6549
+ view: MetricsView
6550
+ }
6551
+ ]
6552
+ },
6553
+ configForm: {
6554
+ form: {
6555
+ port: {
6556
+ help: "The port this SRT output will connect to",
6557
+ hint: {
6558
+ type: "numeric",
6559
+ validation: Port,
6560
+ defaultValue: 5101
6561
+ }
6562
+ },
6563
+ host: { help: "The IP address/Hostname this SRT output will connect to", hint: { type: "text", validation: Hostname, defaultValue: "127.0.0.1" } },
6564
+ bufferDelayMs: { help: "How many milliseconds in the jitter buffer", hint: { type: "numeric", validation: JitterBuffer, defaultValue: 500 } },
6565
+ avDelayMs: { help: "How many milliseconds to delay A/V to account for subtitles/ancillary data", hint: { type: "numeric", validation: JitterBuffer, defaultValue: 50 } },
6566
+ passphrase: { help: "Optional: Authentication for this SRT output", hint: { type: "text", optional: true, validation: SrtPassphrase } },
6567
+ streamId: { help: "Optional: StreamId to use when calling a remote listener", hint: { type: "text", optional: true, validation: SrtStreamId } },
6568
+ socketOptions: {
6569
+ help: "Socket Options",
6570
+ hint: {
6571
+ type: "form-item",
6572
+ view: SocketConfiguration,
6573
+ form: srt_socket_options_default(validation)
6574
+ }
6575
+ },
6576
+ notes: {
6577
+ help: "Additional notes about this component",
6578
+ hint: { type: "text", optional: true }
6579
+ }
6580
+ }
6581
+ }
6582
+ });
6583
+ }
6584
+
6585
+ // build/output.srt-listener/info.js
6586
+ var import_util2 = __toESM(require_util2());
6587
+
6588
+ // build/output.srt-listener/summary-view.js
6589
+ var import_jsx_runtime16 = __toESM(require_jsx_runtime());
6590
+ function SummaryView6({ state, sendCommand }) {
6591
+ const handleEnableOutput = () => {
6592
+ void enableOutput();
6593
+ };
6594
+ const enableOutput = async () => {
6595
+ sendCommand({
6596
+ type: "enable-output"
6597
+ });
6598
+ };
6599
+ const handleDisableOutput = () => {
6600
+ void disableOutput();
6601
+ };
6602
+ const disableOutput = async () => {
6603
+ sendCommand({
6604
+ type: "disable-output"
6605
+ });
6606
+ };
6607
+ return (0, import_jsx_runtime16.jsx)("div", { className: "mb-5", children: (0, import_jsx_runtime16.jsxs)("div", { className: "flex items-center justify-between mb-3", children: [(0, import_jsx_runtime16.jsxs)("div", { className: "flex items-center space-x-2", children: [(0, import_jsx_runtime16.jsx)("span", { className: `inline-block w-2 h-2 rounded-full ${state.enabled ? "bg-green-500" : "bg-red-500"}` }), (0, import_jsx_runtime16.jsxs)("span", { className: "text-sm", children: ["Status: ", state.enabled ? "Enabled" : "Disabled"] })] }), (0, import_jsx_runtime16.jsx)("div", { children: state.enabled ? (0, import_jsx_runtime16.jsx)("button", { onClick: handleDisableOutput, className: "px-3 py-1 text-sm bg-red-600 hover:bg-red-700 text-white rounded", children: "Disable Output" }) : (0, import_jsx_runtime16.jsx)("button", { onClick: handleEnableOutput, className: "px-3 py-1 text-sm bg-blue-600 hover:bg-green-700 text-white rounded", children: "Enable Output" }) })] }) });
6608
+ }
6609
+ var summary_view_default6 = SummaryView6;
6610
+
6611
+ // build/output.srt-listener/inline-view.js
6612
+ var import_jsx_runtime17 = __toESM(require_jsx_runtime());
6613
+ function InlineView7({ state }) {
6614
+ return (0, import_jsx_runtime17.jsx)("div", { className: "srt-output", children: state.enabled ? state.metrics.connectionCount == 0 ? (0, import_jsx_runtime17.jsx)("div", { className: "active text-red-300 dark:text-red-300", children: "No connections" }) : (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [(0, import_jsx_runtime17.jsx)("div", { className: "active text-green-500 dark:text-green-300", children: "Output enabled" }), (0, import_jsx_runtime17.jsxs)("div", { children: ["Connections: ", state.metrics.connectionCount] }), (0, import_jsx_runtime17.jsxs)("div", { children: ["Sent: ", state.metrics.packetsSent.reduce((a, i) => a + i, 0)] }), (0, import_jsx_runtime17.jsxs)("div", { children: ["Lost/Resent: ", state.metrics.packetsLost.reduce((a, i) => a + i, 0), "/", state.metrics.packetsResent.reduce((a, i) => a + i, 0)] })] }) : (0, import_jsx_runtime17.jsx)("div", { className: "disabled text-gray-500 dark:text-gray-400", children: "Output disabled" }) });
6615
+ }
6616
+ var inline_view_default7 = InlineView7;
6617
+
6618
+ // build/output.srt-listener/srt-packet-metrics.js
6619
+ var import_jsx_runtime18 = __toESM(require_jsx_runtime());
6620
+ function MetricsView2({ state }) {
6621
+ return (0, import_jsx_runtime18.jsx)("div", { className: "srt-output", children: state.enabled ? state.metrics.connectionCount == 0 ? (0, import_jsx_runtime18.jsx)("div", { className: "active text-red-300 dark:text-red-300", children: "No connections" }) : (0, import_jsx_runtime18.jsxs)(import_jsx_runtime18.Fragment, { children: [(0, import_jsx_runtime18.jsx)("div", { className: "active text-green-500 dark:text-green-300", children: "Output enabled" }), (0, import_jsx_runtime18.jsx)("div", { className: "divide-y", children: state.metrics.packetsSent.map((p, i) => {
6622
+ return (0, import_jsx_runtime18.jsxs)("div", { className: "sm:grid sm:grid-cols-2 mt-2", children: [(0, import_jsx_runtime18.jsx)("dt", { className: "underline", children: "Connection" }), (0, import_jsx_runtime18.jsx)("dd", { className: "", children: i }), (0, import_jsx_runtime18.jsx)("dt", { className: "", children: "Sent" }), (0, import_jsx_runtime18.jsx)("dd", { className: "", children: p }), (0, import_jsx_runtime18.jsx)("dt", { className: "", children: "Resent" }), (0, import_jsx_runtime18.jsx)("dd", { className: "", children: state.metrics.packetsResent[i] }), (0, import_jsx_runtime18.jsx)("dt", { className: "", children: "Lost" }), (0, import_jsx_runtime18.jsx)("dd", { className: "", children: state.metrics.packetsLost[i] })] }, i);
6623
+ }) }), "."] }) : (0, import_jsx_runtime18.jsx)("div", { className: "disabled text-gray-500 dark:text-gray-400", children: "Output disabled" }) });
6624
+ }
6625
+
6626
+ // build/output.srt-listener/info.js
6627
+ function info_default14(registration) {
6628
+ const { defineComponent, All, validation } = registration;
6629
+ const { Port, Hostname, JitterBuffer, SrtPassphrase, SrtStreamId } = validation;
6630
+ return defineComponent({
6631
+ identifier: "output.srt-listener",
6632
+ category: "output",
6633
+ name: "SRT Listener Egest",
6634
+ description: "This component manages the sending of SRT (Secure Reliable Transport) streams. It allows you to configure various settings to control how the SRT output is handled, including connection details, buffer settings, and delay options.",
6635
+ subscription: {
6636
+ accepts: {
6637
+ type: "dynamic-streams",
6638
+ mode: "any",
6639
+ streams: () => All.map((media) => ({ media }))
6640
+ }
6641
+ },
6642
+ display: (desc) => {
6643
+ return {
6644
+ port: desc.config.port?.toString() ?? "",
6645
+ host: desc.config.host,
6646
+ bufferDelayMs: desc.config.bufferDelayMs?.toString() ?? "none"
6647
+ };
6648
+ },
6649
+ runtime: {
6650
+ initialState: () => ({
6651
+ enabled: true,
6652
+ metrics: {
6653
+ connectionCount: 0,
6654
+ packetsLost: [],
6655
+ packetsResent: [],
6656
+ packetsSent: []
6657
+ }
6658
+ }),
6659
+ handleEvent(ev, state) {
6660
+ const evType = ev.type;
6661
+ switch (evType) {
6662
+ case "output-enabled":
6663
+ state.enabled = true;
6664
+ break;
6665
+ case "output-disabled":
6666
+ state.enabled = false;
6667
+ break;
6668
+ case "metrics-updated":
6669
+ state.metrics = ev.metrics;
6670
+ break;
6671
+ default:
6672
+ (0, import_util2.assertUnreachable)(evType);
6673
+ }
6674
+ return { ...state };
6675
+ },
6676
+ summary: summary_view_default6,
6677
+ inline: inline_view_default7,
6678
+ metrics: [
6679
+ { title: "SRT Transmission", view: MetricsView2 }
6680
+ ]
6463
6681
  },
6464
6682
  configForm: {
6465
6683
  form: {
6466
6684
  port: {
6467
- help: "The port this SRT output will connect to or listen on",
6685
+ help: "The port this SRT output will listen on",
6468
6686
  hint: {
6469
6687
  type: "numeric",
6470
6688
  validation: Port,
6471
6689
  defaultValue: 5101,
6472
6690
  global: {
6473
6691
  constraint: "unique",
6474
- key: "port",
6475
- include: (cfg) => cfg.mode == "listener"
6692
+ key: "port"
6476
6693
  }
6477
6694
  }
6478
6695
  },
6479
- host: { help: "The IP address/Hostname this SRT output will connect to or listen on", hint: { type: "text", validation: Hostname, defaultValue: "0.0.0.0" } },
6696
+ host: { help: "The IP address/Hostname this SRT output will listen on", hint: { type: "text", validation: Hostname, defaultValue: "0.0.0.0" } },
6480
6697
  bufferDelayMs: { help: "How many milliseconds in the jitter buffer", hint: { type: "numeric", validation: JitterBuffer, defaultValue: 500 } },
6481
6698
  avDelayMs: { help: "How many milliseconds to delay A/V to account for subtitles/ancillary data", hint: { type: "numeric", validation: JitterBuffer, defaultValue: 50 } },
6482
- mode: {
6483
- help: "Whether this SRT Output is calling a remote host, or listening on this host",
6484
- hint: {
6485
- defaultValue: "listener",
6486
- type: "select",
6487
- options: [
6488
- {
6489
- value: "listener",
6490
- display: "Listener"
6491
- },
6492
- {
6493
- value: "caller",
6494
- display: "Caller"
6495
- }
6496
- ]
6497
- }
6498
- },
6499
6699
  passphrase: { help: "Optional: Authentication for this SRT output", hint: { type: "text", optional: true, validation: SrtPassphrase } },
6500
6700
  streamId: { help: "Optional: StreamId to use when calling a remote listener", hint: { type: "text", optional: true, validation: SrtStreamId } },
6501
6701
  socketOptions: {
@@ -6516,38 +6716,38 @@ function info_default13(registration) {
6516
6716
  }
6517
6717
 
6518
6718
  // build/output.statistics/inline-view.js
6519
- var import_jsx_runtime15 = __toESM(require_jsx_runtime());
6520
- function InlineView7({ state }) {
6719
+ var import_jsx_runtime19 = __toESM(require_jsx_runtime());
6720
+ function InlineView8({ state }) {
6521
6721
  if (!state.previous)
6522
- return (0, import_jsx_runtime15.jsx)(import_jsx_runtime15.Fragment, {});
6722
+ return (0, import_jsx_runtime19.jsx)(import_jsx_runtime19.Fragment, {});
6523
6723
  const format = (stat) => Math.floor(stat).toLocaleString("en-US", { maximumFractionDigits: 0 });
6524
- return (0, import_jsx_runtime15.jsx)(import_jsx_runtime15.Fragment, { children: state.previous.allStreams.map((s, i) => {
6724
+ return (0, import_jsx_runtime19.jsx)(import_jsx_runtime19.Fragment, { children: state.previous.allStreams.map((s, i) => {
6525
6725
  const metaCase = s.metadata.case;
6526
6726
  switch (metaCase) {
6527
6727
  case "audio":
6528
- return (0, import_jsx_runtime15.jsxs)("div", { children: [(0, import_jsx_runtime15.jsxs)("div", { children: ["StreamKey: ", streamKey(s.streamKey)] }), (0, import_jsx_runtime15.jsxs)("div", { children: ["Bitrate: ", format(s.bitrate), "bps"] })] }, i);
6728
+ return (0, import_jsx_runtime19.jsxs)("div", { children: [(0, import_jsx_runtime19.jsxs)("div", { children: ["StreamKey: ", streamKey(s.streamKey)] }), (0, import_jsx_runtime19.jsxs)("div", { children: ["Bitrate: ", format(s.bitrate), "bps"] })] }, i);
6529
6729
  case "video":
6530
- return (0, import_jsx_runtime15.jsxs)("div", { children: [(0, import_jsx_runtime15.jsxs)("div", { children: ["StreamKey: ", streamKey(s.streamKey)] }), (0, import_jsx_runtime15.jsxs)("div", { children: ["Bitrate: ", format(s.bitrate), "bps"] })] }, i);
6730
+ return (0, import_jsx_runtime19.jsxs)("div", { children: [(0, import_jsx_runtime19.jsxs)("div", { children: ["StreamKey: ", streamKey(s.streamKey)] }), (0, import_jsx_runtime19.jsxs)("div", { children: ["Bitrate: ", format(s.bitrate), "bps"] })] }, i);
6531
6731
  case "ancillary":
6532
- return (0, import_jsx_runtime15.jsx)(import_jsx_runtime15.Fragment, {});
6732
+ return (0, import_jsx_runtime19.jsx)(import_jsx_runtime19.Fragment, {});
6533
6733
  case "subtitle":
6534
- return (0, import_jsx_runtime15.jsx)(import_jsx_runtime15.Fragment, {});
6734
+ return (0, import_jsx_runtime19.jsx)(import_jsx_runtime19.Fragment, {});
6535
6735
  case "playlist":
6536
- return (0, import_jsx_runtime15.jsx)(import_jsx_runtime15.Fragment, {});
6736
+ return (0, import_jsx_runtime19.jsx)(import_jsx_runtime19.Fragment, {});
6537
6737
  case void 0:
6538
- return (0, import_jsx_runtime15.jsx)(import_jsx_runtime15.Fragment, {});
6738
+ return (0, import_jsx_runtime19.jsx)(import_jsx_runtime19.Fragment, {});
6539
6739
  default:
6540
- assertUnreachable7(metaCase);
6740
+ assertUnreachable8(metaCase);
6541
6741
  }
6542
6742
  }) });
6543
6743
  }
6544
6744
  function streamKey(streamKey2) {
6545
6745
  return streamKey2.streamId.toString();
6546
6746
  }
6547
- var inline_view_default7 = InlineView7;
6747
+ var inline_view_default8 = InlineView8;
6548
6748
 
6549
6749
  // build/output.statistics/info.js
6550
- function info_default14({ defineComponent, All }) {
6750
+ function info_default15({ defineComponent, All }) {
6551
6751
  return defineComponent({
6552
6752
  identifier: "output.statistics",
6553
6753
  category: "output",
@@ -6571,11 +6771,11 @@ function info_default14({ defineComponent, All }) {
6571
6771
  state.previous = ev.summary;
6572
6772
  break;
6573
6773
  default:
6574
- assertUnreachable7(evType);
6774
+ assertUnreachable8(evType);
6575
6775
  }
6576
6776
  return { ...state };
6577
6777
  },
6578
- inline: inline_view_default7
6778
+ inline: inline_view_default8
6579
6779
  },
6580
6780
  configForm: {
6581
6781
  form: {
@@ -6584,12 +6784,12 @@ function info_default14({ defineComponent, All }) {
6584
6784
  }
6585
6785
  });
6586
6786
  }
6587
- function assertUnreachable7(_) {
6787
+ function assertUnreachable8(_) {
6588
6788
  throw new Error("Didn't expect to get here");
6589
6789
  }
6590
6790
 
6591
6791
  // build/output.twitch/info.js
6592
- function info_default15(r) {
6792
+ function info_default16(r) {
6593
6793
  const { validation: { Z } } = r;
6594
6794
  return defineRtmpOutputComponent(r, {
6595
6795
  identifier: "output.twitch",
@@ -6617,7 +6817,7 @@ function info_default15(r) {
6617
6817
  }
6618
6818
 
6619
6819
  // build/output.udpTs/info.js
6620
- function info_default16({ defineComponent, All, validation: { Port, Hostname, JitterBuffer, Iface, Z } }) {
6820
+ function info_default17({ defineComponent, All, validation: { Port, Hostname, JitterBuffer, Iface, Z } }) {
6621
6821
  return defineComponent({
6622
6822
  identifier: "output.udpTs",
6623
6823
  category: "output",
@@ -6657,10 +6857,10 @@ function info_default16({ defineComponent, All, validation: { Port, Hostname, Ji
6657
6857
  var import_config3 = __toESM(require_config());
6658
6858
 
6659
6859
  // build/output.whep/inline-view.js
6660
- var import_jsx_runtime16 = __toESM(require_jsx_runtime());
6860
+ var import_jsx_runtime20 = __toESM(require_jsx_runtime());
6661
6861
  var import_react3 = __toESM(require_react());
6662
6862
  var import_webrtc_client2 = __toESM(require_webrtc_client());
6663
- function InlineView8({ state, config, raise }) {
6863
+ function InlineView9({ state, config, raise }) {
6664
6864
  const url = state.url;
6665
6865
  const id = config.id;
6666
6866
  const [showPreview, setShowPreview] = (0, import_react3.useState)(config.showPreview ?? true);
@@ -6702,19 +6902,19 @@ function InlineView8({ state, config, raise }) {
6702
6902
  }, [config.showPreview]);
6703
6903
  raise && (0, import_react3.useEffect)(raise, []);
6704
6904
  if (!url)
6705
- return (0, import_jsx_runtime16.jsx)(import_jsx_runtime16.Fragment, { children: "..." });
6905
+ return (0, import_jsx_runtime20.jsx)(import_jsx_runtime20.Fragment, { children: "..." });
6706
6906
  const videoStyles = `
6707
6907
  #whep-${id} video::-webkit-media-controls-play-button {
6708
6908
  display: none;
6709
6909
  }
6710
6910
  `;
6711
- return (0, import_jsx_runtime16.jsxs)("div", { className: "whep-container", children: [(0, import_jsx_runtime16.jsxs)("div", { className: "flex items-center gap-2 mb-2", children: [(0, import_jsx_runtime16.jsx)("input", { type: "checkbox", id: `video-toggle-${id}`, checked: showPreview, onChange: (e) => setShowPreview(e.target.checked), className: "h-4 w-4" }), (0, import_jsx_runtime16.jsx)("label", { htmlFor: `video-toggle-${id}`, className: "text-sm", children: "Show Preview" })] }), showPreview ? (0, import_jsx_runtime16.jsx)("div", { className: "whep-video", id: `whep-${id}`, children: (0, import_jsx_runtime16.jsx)("style", { children: videoStyles }) }) : (0, import_jsx_runtime16.jsx)("div", { className: "whep-video bg-black flex items-center justify-center text-white h-full", children: "Preview turned off" })] });
6911
+ return (0, import_jsx_runtime20.jsxs)("div", { className: "whep-container", children: [(0, import_jsx_runtime20.jsxs)("div", { className: "flex items-center gap-2 mb-2", children: [(0, import_jsx_runtime20.jsx)("input", { type: "checkbox", id: `video-toggle-${id}`, checked: showPreview, onChange: (e) => setShowPreview(e.target.checked), className: "h-4 w-4" }), (0, import_jsx_runtime20.jsx)("label", { htmlFor: `video-toggle-${id}`, className: "text-sm", children: "Show Preview" })] }), showPreview ? (0, import_jsx_runtime20.jsx)("div", { className: "whep-video", id: `whep-${id}`, children: (0, import_jsx_runtime20.jsx)("style", { children: videoStyles }) }) : (0, import_jsx_runtime20.jsx)("div", { className: "whep-video bg-black flex items-center justify-center text-white h-full", children: "Preview turned off" })] });
6712
6912
  }
6713
- var inline_view_default8 = InlineView8;
6913
+ var inline_view_default9 = InlineView9;
6714
6914
 
6715
6915
  // build/output.whep/summary-view.js
6716
- var import_jsx_runtime17 = __toESM(require_jsx_runtime());
6717
- function SummaryView6({ state, sendCommand }) {
6916
+ var import_jsx_runtime21 = __toESM(require_jsx_runtime());
6917
+ function SummaryView7({ state, sendCommand }) {
6718
6918
  const handleEnableOutput = () => {
6719
6919
  void enableOutput();
6720
6920
  };
@@ -6731,12 +6931,12 @@ function SummaryView6({ state, sendCommand }) {
6731
6931
  type: "disable-output"
6732
6932
  });
6733
6933
  };
6734
- return (0, import_jsx_runtime17.jsx)("div", { className: "mb-5", children: (0, import_jsx_runtime17.jsxs)("div", { className: "flex items-center justify-between mb-3", children: [(0, import_jsx_runtime17.jsxs)("div", { className: "flex items-center space-x-2", children: [(0, import_jsx_runtime17.jsx)("span", { className: `inline-block w-2 h-2 rounded-full ${state.enabled ? "bg-blue-500" : "bg-red-500"}` }), (0, import_jsx_runtime17.jsxs)("span", { className: "text-sm", children: ["Status: ", state.enabled ? "Enabled" : "Disabled"] })] }), (0, import_jsx_runtime17.jsx)("div", { children: state.enabled ? (0, import_jsx_runtime17.jsx)("button", { onClick: handleDisableOutput, className: "px-3 py-1 text-sm bg-red-600 hover:bg-red-700 text-white rounded", children: "Disable Output" }) : (0, import_jsx_runtime17.jsx)("button", { onClick: handleEnableOutput, className: "px-3 py-1 text-sm bg-blue-600 hover:bg-blue-700 text-white rounded", children: "Enable Output" }) })] }) });
6934
+ return (0, import_jsx_runtime21.jsx)("div", { className: "mb-5", children: (0, import_jsx_runtime21.jsxs)("div", { className: "flex items-center justify-between mb-3", children: [(0, import_jsx_runtime21.jsxs)("div", { className: "flex items-center space-x-2", children: [(0, import_jsx_runtime21.jsx)("span", { className: `inline-block w-2 h-2 rounded-full ${state.enabled ? "bg-blue-500" : "bg-red-500"}` }), (0, import_jsx_runtime21.jsxs)("span", { className: "text-sm", children: ["Status: ", state.enabled ? "Enabled" : "Disabled"] })] }), (0, import_jsx_runtime21.jsx)("div", { children: state.enabled ? (0, import_jsx_runtime21.jsx)("button", { onClick: handleDisableOutput, className: "px-3 py-1 text-sm bg-red-600 hover:bg-red-700 text-white rounded", children: "Disable Output" }) : (0, import_jsx_runtime21.jsx)("button", { onClick: handleEnableOutput, className: "px-3 py-1 text-sm bg-blue-600 hover:bg-blue-700 text-white rounded", children: "Enable Output" }) })] }) });
6735
6935
  }
6736
- var summary_view_default6 = SummaryView6;
6936
+ var summary_view_default7 = SummaryView7;
6737
6937
 
6738
6938
  // build/output.whep/info.js
6739
- function info_default17(R) {
6939
+ function info_default18(R) {
6740
6940
  const { defineComponent, validation: { JitterBuffer } } = R;
6741
6941
  return defineComponent({
6742
6942
  identifier: "output.whep",
@@ -6769,12 +6969,12 @@ function info_default17(R) {
6769
6969
  state.enabled = false;
6770
6970
  break;
6771
6971
  default:
6772
- assertUnreachable8(evType);
6972
+ assertUnreachable9(evType);
6773
6973
  }
6774
6974
  return { ...state };
6775
6975
  },
6776
- inline: inline_view_default8,
6777
- summary: summary_view_default6
6976
+ inline: inline_view_default9,
6977
+ summary: summary_view_default7
6778
6978
  },
6779
6979
  configForm: {
6780
6980
  global: {
@@ -6791,12 +6991,12 @@ function info_default17(R) {
6791
6991
  }
6792
6992
  });
6793
6993
  }
6794
- function assertUnreachable8(_) {
6994
+ function assertUnreachable9(_) {
6795
6995
  throw new Error("Didn't expect to get here");
6796
6996
  }
6797
6997
 
6798
6998
  // build/output.youtube/info.js
6799
- function info_default18(r) {
6999
+ function info_default19(r) {
6800
7000
  const { validation: { Z } } = r;
6801
7001
  return defineRtmpOutputComponent(r, {
6802
7002
  identifier: "output.youtube",
@@ -6827,13 +7027,13 @@ function info_default18(r) {
6827
7027
  var import_client_types2 = __toESM(require_client_types());
6828
7028
 
6829
7029
  // build/processor.audioEncoder/form-views.js
6830
- var import_jsx_runtime18 = __toESM(require_jsx_runtime());
7030
+ var import_jsx_runtime22 = __toESM(require_jsx_runtime());
6831
7031
  function CodecConfiguration(cfg) {
6832
- return (0, import_jsx_runtime18.jsxs)("div", { className: "grid grid-flow-row-dense grid-cols-3 text-sm", children: [(0, import_jsx_runtime18.jsx)("div", { className: "col-span-1", children: "Codec" }), (0, import_jsx_runtime18.jsx)("div", { className: "col-span-2", children: cfg.kind }), cfg.kind === "aac" ? (0, import_jsx_runtime18.jsxs)(import_jsx_runtime18.Fragment, { children: [(0, import_jsx_runtime18.jsx)("div", { className: "col-span-1", children: "Profile" }), (0, import_jsx_runtime18.jsx)("div", { className: "col-span-2", children: cfg.profile }), (0, import_jsx_runtime18.jsx)("div", { className: "col-span-1", children: "Sample Rate" }), (0, import_jsx_runtime18.jsx)("div", { className: "col-span-2", children: cfg.sampleRate })] }) : null] });
7032
+ return (0, import_jsx_runtime22.jsxs)("div", { className: "grid grid-flow-row-dense grid-cols-3 text-sm", children: [(0, import_jsx_runtime22.jsx)("div", { className: "col-span-1", children: "Codec" }), (0, import_jsx_runtime22.jsx)("div", { className: "col-span-2", children: cfg.kind }), cfg.kind === "aac" ? (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [(0, import_jsx_runtime22.jsx)("div", { className: "col-span-1", children: "Profile" }), (0, import_jsx_runtime22.jsx)("div", { className: "col-span-2", children: cfg.profile }), (0, import_jsx_runtime22.jsx)("div", { className: "col-span-1", children: "Sample Rate" }), (0, import_jsx_runtime22.jsx)("div", { className: "col-span-2", children: cfg.sampleRate })] }) : null] });
6833
7033
  }
6834
7034
 
6835
7035
  // build/processor.audioEncoder/info.js
6836
- function info_default19({ defineComponent, validation: { Z } }) {
7036
+ function info_default20({ defineComponent, validation: { Z } }) {
6837
7037
  const format = (stat) => Math.floor(stat).toLocaleString("en-US", { maximumFractionDigits: 0 });
6838
7038
  const Hz = (v) => ({ display: `${format(v)}Hz`, value: v });
6839
7039
  return defineComponent({
@@ -6966,16 +7166,16 @@ function info_default19({ defineComponent, validation: { Z } }) {
6966
7166
  var import_config4 = __toESM(require_config());
6967
7167
 
6968
7168
  // build/processor.browserOverlay/summary-view.js
6969
- var import_jsx_runtime19 = __toESM(require_jsx_runtime());
7169
+ var import_jsx_runtime23 = __toESM(require_jsx_runtime());
6970
7170
  var import_react4 = __toESM(require_react());
6971
- function SummaryView7({ state, sendCommand }) {
7171
+ function SummaryView8({ state, sendCommand }) {
6972
7172
  const [url, setUrl] = (0, import_react4.useState)(state.currentUrl);
6973
7173
  const [enabled, setEnabled] = (0, import_react4.useState)(state.enabled);
6974
7174
  const stateChanged = (0, import_react4.useMemo)(() => {
6975
7175
  return url !== state.currentUrl || enabled !== state.enabled;
6976
7176
  }, [url, enabled]);
6977
7177
  const buttonClass = "mt-2 mb-5 text-white w-full justify-center bg-primary-700 hover:bg-primary-800 focus:ring-4 focus:outline-none focus:ring-primary-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:bg-primary-600 dark:hover:bg-primary-700 dark:focus:ring-primary-800";
6978
- return (0, import_jsx_runtime19.jsxs)("div", { className: "space-y-3 mb-5", children: [(0, import_jsx_runtime19.jsx)("h2", { className: "text-xl font-bold text-gray-900 dark:text-white", children: "Controls" }), (0, import_jsx_runtime19.jsxs)("div", { className: "mb-5", children: [(0, import_jsx_runtime19.jsx)("label", { htmlFor: "url", className: "mb-2 mr-2 text-sm font-medium text-gray-900 dark:text-white", children: "URL" }), (0, import_jsx_runtime19.jsx)("input", { type: "email", id: "url", className: "bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500", value: url, onChange: (e) => setUrl(e.target.value), required: true })] }), (0, import_jsx_runtime19.jsx)("div", { className: "mb-5", children: (0, import_jsx_runtime19.jsxs)("label", { className: "inline-flex items-center cursor-pointer", children: [(0, import_jsx_runtime19.jsx)("span", { className: "me-3 text-sm font-medium text-gray-900 dark:text-gray-300", children: "Enabled" }), (0, import_jsx_runtime19.jsx)("input", { type: "checkbox", checked: enabled, onChange: (e) => setEnabled(e.target.checked), className: "sr-only peer" }), (0, import_jsx_runtime19.jsx)("div", { className: "relative w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-blue-300 dark:peer-focus:ring-blue-800 rounded-full peer dark:bg-gray-700 peer-checked:after:translate-x-full rtl:peer-checked:after:-translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:start-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all dark:border-gray-600 peer-checked:bg-blue-600" })] }) }), (0, import_jsx_runtime19.jsx)("button", { type: "button", className: `${buttonClass} ${!stateChanged ? "opacity-50 cursor-not-allowed" : ""}`, disabled: !stateChanged, onClick: () => {
7178
+ return (0, import_jsx_runtime23.jsxs)("div", { className: "space-y-3 mb-5", children: [(0, import_jsx_runtime23.jsx)("h2", { className: "text-xl font-bold text-gray-900 dark:text-white", children: "Controls" }), (0, import_jsx_runtime23.jsxs)("div", { className: "mb-5", children: [(0, import_jsx_runtime23.jsx)("label", { htmlFor: "url", className: "mb-2 mr-2 text-sm font-medium text-gray-900 dark:text-white", children: "URL" }), (0, import_jsx_runtime23.jsx)("input", { type: "email", id: "url", className: "bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500", value: url, onChange: (e) => setUrl(e.target.value), required: true })] }), (0, import_jsx_runtime23.jsx)("div", { className: "mb-5", children: (0, import_jsx_runtime23.jsxs)("label", { className: "inline-flex items-center cursor-pointer", children: [(0, import_jsx_runtime23.jsx)("span", { className: "me-3 text-sm font-medium text-gray-900 dark:text-gray-300", children: "Enabled" }), (0, import_jsx_runtime23.jsx)("input", { type: "checkbox", checked: enabled, onChange: (e) => setEnabled(e.target.checked), className: "sr-only peer" }), (0, import_jsx_runtime23.jsx)("div", { className: "relative w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-blue-300 dark:peer-focus:ring-blue-800 rounded-full peer dark:bg-gray-700 peer-checked:after:translate-x-full rtl:peer-checked:after:-translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:start-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all dark:border-gray-600 peer-checked:bg-blue-600" })] }) }), (0, import_jsx_runtime23.jsx)("button", { type: "button", className: `${buttonClass} ${!stateChanged ? "opacity-50 cursor-not-allowed" : ""}`, disabled: !stateChanged, onClick: () => {
6979
7179
  if (url !== state.currentUrl) {
6980
7180
  sendCommand({ type: "change-url", url });
6981
7181
  }
@@ -6988,17 +7188,17 @@ function SummaryView7({ state, sendCommand }) {
6988
7188
  }
6989
7189
  }, children: "Commit" })] });
6990
7190
  }
6991
- var summary_view_default7 = SummaryView7;
7191
+ var summary_view_default8 = SummaryView8;
6992
7192
 
6993
7193
  // build/processor.browserOverlay/inline-view.js
6994
- var import_jsx_runtime20 = __toESM(require_jsx_runtime());
6995
- function InlineView9({ state, config }) {
6996
- return (0, import_jsx_runtime20.jsx)("div", { id: `browser-overlay-${config.id}`, children: (0, import_jsx_runtime20.jsxs)("div", { className: "w-64 grid grid-cols-[min-content,1fr] gap-2", children: [(0, import_jsx_runtime20.jsx)("div", { children: "URL:" }), (0, import_jsx_runtime20.jsx)("div", { className: "truncate", children: state.currentUrl }), (0, import_jsx_runtime20.jsx)("div", { children: "Enabled:" }), (0, import_jsx_runtime20.jsx)("div", { children: (0, import_jsx_runtime20.jsxs)("label", { className: "inline-flex items-center cursor-pointer", children: [(0, import_jsx_runtime20.jsx)("input", { type: "checkbox", checked: state.enabled, disabled: true, className: "sr-only peer" }), (0, import_jsx_runtime20.jsx)("div", { className: "relative w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-blue-300 dark:peer-focus:ring-blue-800 rounded-full peer dark:bg-gray-700 peer-checked:after:translate-x-full rtl:peer-checked:after:-translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:start-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all dark:border-gray-600 peer-checked:bg-blue-600" })] }) })] }) });
7194
+ var import_jsx_runtime24 = __toESM(require_jsx_runtime());
7195
+ function InlineView10({ state, config }) {
7196
+ return (0, import_jsx_runtime24.jsx)("div", { id: `browser-overlay-${config.id}`, children: (0, import_jsx_runtime24.jsxs)("div", { className: "w-64 grid grid-cols-[min-content,1fr] gap-2", children: [(0, import_jsx_runtime24.jsx)("div", { children: "URL:" }), (0, import_jsx_runtime24.jsx)("div", { className: "truncate", children: state.currentUrl }), (0, import_jsx_runtime24.jsx)("div", { children: "Enabled:" }), (0, import_jsx_runtime24.jsx)("div", { children: (0, import_jsx_runtime24.jsxs)("label", { className: "inline-flex items-center cursor-pointer", children: [(0, import_jsx_runtime24.jsx)("input", { type: "checkbox", checked: state.enabled, disabled: true, className: "sr-only peer" }), (0, import_jsx_runtime24.jsx)("div", { className: "relative w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-blue-300 dark:peer-focus:ring-blue-800 rounded-full peer dark:bg-gray-700 peer-checked:after:translate-x-full rtl:peer-checked:after:-translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:start-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all dark:border-gray-600 peer-checked:bg-blue-600" })] }) })] }) });
6997
7197
  }
6998
- var inline_view_default9 = InlineView9;
7198
+ var inline_view_default10 = InlineView10;
6999
7199
 
7000
7200
  // build/processor.browserOverlay/info.js
7001
- function info_default20({ defineComponent, validation: { Z } }) {
7201
+ function info_default21({ defineComponent, validation: { Z } }) {
7002
7202
  return defineComponent({
7003
7203
  identifier: "processor.browserOverlay",
7004
7204
  category: "processor",
@@ -7024,8 +7224,8 @@ function info_default20({ defineComponent, validation: { Z } }) {
7024
7224
  };
7025
7225
  },
7026
7226
  runtime: {
7027
- summary: summary_view_default7,
7028
- inline: inline_view_default9,
7227
+ summary: summary_view_default8,
7228
+ inline: inline_view_default10,
7029
7229
  initialState: () => ({
7030
7230
  currentUrl: "",
7031
7231
  enabled: true
@@ -7040,7 +7240,7 @@ function info_default20({ defineComponent, validation: { Z } }) {
7040
7240
  case "disabled":
7041
7241
  return { ...state, enabled: false };
7042
7242
  default:
7043
- assertUnreachable9(evType);
7243
+ assertUnreachable10(evType);
7044
7244
  }
7045
7245
  }
7046
7246
  },
@@ -7055,12 +7255,12 @@ function info_default20({ defineComponent, validation: { Z } }) {
7055
7255
  }
7056
7256
  });
7057
7257
  }
7058
- function assertUnreachable9(_) {
7258
+ function assertUnreachable10(_) {
7059
7259
  throw new Error("Didn't expect to get here");
7060
7260
  }
7061
7261
 
7062
7262
  // build/processor.cascadingSwitch/source-selection.js
7063
- var import_jsx_runtime21 = __toESM(require_jsx_runtime());
7263
+ var import_jsx_runtime25 = __toESM(require_jsx_runtime());
7064
7264
  var import_react5 = __toESM(require_react());
7065
7265
  function OrderInput(props) {
7066
7266
  (0, import_react5.useEffect)(() => {
@@ -7068,10 +7268,10 @@ function OrderInput(props) {
7068
7268
  }, [props.defaultValue]);
7069
7269
  const [value, setValue] = (0, import_react5.useState)(props.defaultValue ?? []);
7070
7270
  if (value.length == 0) {
7071
- return (0, import_jsx_runtime21.jsx)("p", { className: "node-editor-helper-text", children: "Sources will appear here when subscriptions have been added to this node" });
7271
+ return (0, import_jsx_runtime25.jsx)("p", { className: "node-editor-helper-text", children: "Sources will appear here when subscriptions have been added to this node" });
7072
7272
  } else {
7073
- return (0, import_jsx_runtime21.jsx)("div", { id: props.id, children: (0, import_jsx_runtime21.jsx)("ul", { children: value.map((v, ix) => {
7074
- return (0, import_jsx_runtime21.jsxs)("li", { className: "flex", children: [(0, import_jsx_runtime21.jsx)("span", { className: "node-editor-label flex-grow", children: v }), ix == 0 ? (0, import_jsx_runtime21.jsx)(import_jsx_runtime21.Fragment, {}) : (0, import_jsx_runtime21.jsx)("svg", { onClick: moveUp(ix), xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", strokeWidth: 1.5, className: "w-4 h-6 shrink cursor-pointer stroke-gray-700 dark:stroke-gray-50", children: (0, import_jsx_runtime21.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M8.25 6.75L12 3m0 0l3.75 3.75M12 3v18" }) }), ix == value.length - 1 ? (0, import_jsx_runtime21.jsx)(import_jsx_runtime21.Fragment, {}) : (0, import_jsx_runtime21.jsx)("svg", { onClick: moveDown(ix), xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", strokeWidth: 1.5, className: "w-4 h-6 shrink cursor-pointer stroke-gray-700 dark:stroke-gray-50", children: (0, import_jsx_runtime21.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M15.75 17.25L12 21m0 0l-3.75-3.75M12 21V3" }) })] }, v);
7273
+ return (0, import_jsx_runtime25.jsx)("div", { id: props.id, children: (0, import_jsx_runtime25.jsx)("ul", { children: value.map((v, ix) => {
7274
+ return (0, import_jsx_runtime25.jsxs)("li", { className: "flex", children: [(0, import_jsx_runtime25.jsx)("span", { className: "node-editor-label flex-grow", children: v }), ix == 0 ? (0, import_jsx_runtime25.jsx)(import_jsx_runtime25.Fragment, {}) : (0, import_jsx_runtime25.jsx)("svg", { onClick: moveUp(ix), xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", strokeWidth: 1.5, className: "w-4 h-6 shrink cursor-pointer stroke-gray-700 dark:stroke-gray-50", children: (0, import_jsx_runtime25.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M8.25 6.75L12 3m0 0l3.75 3.75M12 3v18" }) }), ix == value.length - 1 ? (0, import_jsx_runtime25.jsx)(import_jsx_runtime25.Fragment, {}) : (0, import_jsx_runtime25.jsx)("svg", { onClick: moveDown(ix), xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", strokeWidth: 1.5, className: "w-4 h-6 shrink cursor-pointer stroke-gray-700 dark:stroke-gray-50", children: (0, import_jsx_runtime25.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M15.75 17.25L12 21m0 0l-3.75-3.75M12 21V3" }) })] }, v);
7075
7275
  }) }) });
7076
7276
  }
7077
7277
  function moveUp(ix) {
@@ -7096,17 +7296,17 @@ function OrderInput(props) {
7096
7296
  var source_selection_default = OrderInput;
7097
7297
 
7098
7298
  // build/processor.cascadingSwitch/inline-view.js
7099
- var import_jsx_runtime22 = __toESM(require_jsx_runtime());
7299
+ var import_jsx_runtime26 = __toESM(require_jsx_runtime());
7100
7300
  var activeClasses = "active text-green-500 dark:text-green-300";
7101
7301
  var availableClasses = "available text-green-500 dark:text-green-300";
7102
7302
  var inactiveClasses = "inactive text-orange-500 dark:text-orange-300";
7103
- function InlineView10({ state, config }) {
7104
- return (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [(0, import_jsx_runtime22.jsx)("h5", { children: "Sources" }), (0, import_jsx_runtime22.jsxs)("ul", { children: [config.sources.map((s, i) => state.activeSource == s ? (0, import_jsx_runtime22.jsxs)("li", { className: activeClasses, children: [s, " <--"] }, i) : state.availableSources.includes(s) ? (0, import_jsx_runtime22.jsxs)("li", { className: availableClasses, children: [s, " (available)"] }, i) : (0, import_jsx_runtime22.jsxs)("li", { className: inactiveClasses, children: [s, " (inactive)"] }, i)), (0, import_jsx_runtime22.jsx)("li", { className: state.activeSource == "fallback" ? activeClasses : availableClasses, children: "fallback" }, "fallback")] })] });
7303
+ function InlineView11({ state, config }) {
7304
+ return (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [(0, import_jsx_runtime26.jsx)("h5", { children: "Sources" }), (0, import_jsx_runtime26.jsxs)("ul", { children: [config.sources.map((s, i) => state.activeSource == s ? (0, import_jsx_runtime26.jsxs)("li", { className: activeClasses, children: [s, " <--"] }, i) : state.availableSources.includes(s) ? (0, import_jsx_runtime26.jsxs)("li", { className: availableClasses, children: [s, " (available)"] }, i) : (0, import_jsx_runtime26.jsxs)("li", { className: inactiveClasses, children: [s, " (inactive)"] }, i)), (0, import_jsx_runtime26.jsx)("li", { className: state.activeSource == "fallback" ? activeClasses : availableClasses, children: "fallback" }, "fallback")] })] });
7105
7305
  }
7106
- var inline_view_default10 = InlineView10;
7306
+ var inline_view_default11 = InlineView11;
7107
7307
 
7108
7308
  // build/processor.cascadingSwitch/info.js
7109
- function info_default21({ defineComponent, Av, common: { Resolutions, FrameRates } }) {
7309
+ function info_default22({ defineComponent, Av, common: { Resolutions, FrameRates } }) {
7110
7310
  return defineComponent({
7111
7311
  identifier: "processor.cascadingSwitch",
7112
7312
  category: "processor",
@@ -7185,12 +7385,12 @@ function info_default21({ defineComponent, Av, common: { Resolutions, FrameRates
7185
7385
  state.availableSources.splice(state.availableSources.indexOf(ev.source), 1);
7186
7386
  return { ...state };
7187
7387
  default:
7188
- assertUnreachable10(evType);
7388
+ assertUnreachable11(evType);
7189
7389
  }
7190
7390
  },
7191
- inline: inline_view_default10,
7192
- summary: inline_view_default10,
7193
- fullscreen: inline_view_default10
7391
+ inline: inline_view_default11,
7392
+ summary: inline_view_default11,
7393
+ fullscreen: inline_view_default11
7194
7394
  },
7195
7395
  configForm: {
7196
7396
  form: {
@@ -7237,7 +7437,7 @@ function info_default21({ defineComponent, Av, common: { Resolutions, FrameRates
7237
7437
  }
7238
7438
  });
7239
7439
  }
7240
- function assertUnreachable10(_) {
7440
+ function assertUnreachable11(_) {
7241
7441
  throw new Error("Didn't expect to get here");
7242
7442
  }
7243
7443
 
@@ -7245,13 +7445,13 @@ function assertUnreachable10(_) {
7245
7445
  var import_config5 = __toESM(require_config());
7246
7446
 
7247
7447
  // build/processor.fixedLadder/rung-view.js
7248
- var import_jsx_runtime23 = __toESM(require_jsx_runtime());
7448
+ var import_jsx_runtime27 = __toESM(require_jsx_runtime());
7249
7449
  function rung_view_default(rung) {
7250
- return (0, import_jsx_runtime23.jsx)("div", { className: "text-gray-900 dark:text-white", children: rung.name });
7450
+ return (0, import_jsx_runtime27.jsx)("div", { className: "text-gray-900 dark:text-white", children: rung.name });
7251
7451
  }
7252
7452
 
7253
7453
  // build/processor.fixedLadder/codec-editor.js
7254
- var import_jsx_runtime24 = __toESM(require_jsx_runtime());
7454
+ var import_jsx_runtime28 = __toESM(require_jsx_runtime());
7255
7455
  var import_react6 = __toESM(require_react());
7256
7456
  function CodecEditor(props) {
7257
7457
  (0, import_react6.useEffect)(() => {
@@ -7267,7 +7467,7 @@ function CodecEditor(props) {
7267
7467
  target.style.height = target.scrollHeight + "px";
7268
7468
  }
7269
7469
  }, []);
7270
- return (0, import_jsx_runtime24.jsx)("textarea", { ref: textAreaRef, className: "w-full min-h-fit bg-white text-gray-900 dark:text-white dark:bg-black", id: props.id, onChange: (e) => {
7470
+ return (0, import_jsx_runtime28.jsx)("textarea", { ref: textAreaRef, className: "w-full min-h-fit bg-white text-gray-900 dark:text-white dark:bg-black", id: props.id, onChange: (e) => {
7271
7471
  const target = e.currentTarget;
7272
7472
  try {
7273
7473
  const codec = JSON.parse(target.value);
@@ -7279,13 +7479,13 @@ function CodecEditor(props) {
7279
7479
  }
7280
7480
 
7281
7481
  // build/processor.fixedLadder/codec-view.js
7282
- var import_jsx_runtime25 = __toESM(require_jsx_runtime());
7482
+ var import_jsx_runtime29 = __toESM(require_jsx_runtime());
7283
7483
  function CodecEditor2(props) {
7284
- return (0, import_jsx_runtime25.jsxs)("div", { className: "text-gray-900 dark:text-white", children: [props?.width, "x", props?.height] });
7484
+ return (0, import_jsx_runtime29.jsxs)("div", { className: "text-gray-900 dark:text-white", children: [props?.width, "x", props?.height] });
7285
7485
  }
7286
7486
 
7287
7487
  // build/processor.fixedLadder/info.js
7288
- function info_default22({ defineComponent, common: { FrameRates } }) {
7488
+ function info_default23({ defineComponent, common: { FrameRates } }) {
7289
7489
  return defineComponent({
7290
7490
  identifier: "processor.fixedLadder",
7291
7491
  category: "processor",
@@ -7446,7 +7646,7 @@ function createSoftwareRung(rung) {
7446
7646
  case "h264_320x180":
7447
7647
  return createRungImpl({ name: rung, threads: 1, bitrate: 800 });
7448
7648
  default:
7449
- return assertUnreachable11(rung);
7649
+ return assertUnreachable12(rung);
7450
7650
  }
7451
7651
  }
7452
7652
  function createMa35dRung(rung) {
@@ -7460,7 +7660,7 @@ function createMa35dRung(rung) {
7460
7660
  case "h264_320x180":
7461
7661
  return createMa35DH264RungImpl({ name: rung, bitrate: 1e3 });
7462
7662
  default:
7463
- return assertUnreachable11(rung);
7663
+ return assertUnreachable12(rung);
7464
7664
  }
7465
7665
  }
7466
7666
  function createNvidiaRung(rung) {
@@ -7474,7 +7674,7 @@ function createNvidiaRung(rung) {
7474
7674
  case "h264_320x180":
7475
7675
  return createNvidiaRungImpl({ name: rung, bitrate: 8e5 });
7476
7676
  default:
7477
- return assertUnreachable11(rung);
7677
+ return assertUnreachable12(rung);
7478
7678
  }
7479
7679
  }
7480
7680
  function createQuadraRung(rung) {
@@ -7488,7 +7688,7 @@ function createQuadraRung(rung) {
7488
7688
  case "h264_320x180":
7489
7689
  return createQuadraRungImpl({ name: rung, bitrate: 8e5 });
7490
7690
  default:
7491
- return assertUnreachable11(rung);
7691
+ return assertUnreachable12(rung);
7492
7692
  }
7493
7693
  }
7494
7694
  function createLoganRung(rung) {
@@ -7502,7 +7702,7 @@ function createLoganRung(rung) {
7502
7702
  case "h264_320x180":
7503
7703
  return createLoganRungImpl({ name: rung, bitrate: 8e5 });
7504
7704
  default:
7505
- return assertUnreachable11(rung);
7705
+ return assertUnreachable12(rung);
7506
7706
  }
7507
7707
  }
7508
7708
  function createRungImpl({ name, threads, bitrate }) {
@@ -7603,12 +7803,12 @@ function rungWidth(rungName) {
7603
7803
  function rungHeight(rungName) {
7604
7804
  return parseInt(rungName.split("_")[1].split(`x`)[1]);
7605
7805
  }
7606
- function assertUnreachable11(_) {
7806
+ function assertUnreachable12(_) {
7607
7807
  throw new Error("Didn't expect to get here");
7608
7808
  }
7609
7809
 
7610
7810
  // build/processor.makeProgram/info.js
7611
- function info_default23({ defineComponent, All, validation: { Z } }) {
7811
+ function info_default24({ defineComponent, All, validation: { Z } }) {
7612
7812
  return defineComponent({
7613
7813
  identifier: "processor.makeProgram",
7614
7814
  category: "processor",
@@ -7689,7 +7889,7 @@ function info_default23({ defineComponent, All, validation: { Z } }) {
7689
7889
  var import_config6 = __toESM(require_config());
7690
7890
 
7691
7891
  // build/processor.onscreenGraphic/image-selection.js
7692
- var import_jsx_runtime26 = __toESM(require_jsx_runtime());
7892
+ var import_jsx_runtime30 = __toESM(require_jsx_runtime());
7693
7893
  var import_react7 = __toESM(require_react());
7694
7894
  function GraphicSelection(props) {
7695
7895
  const [loading, setLoading] = (0, import_react7.useState)(true);
@@ -7710,16 +7910,16 @@ function GraphicSelection(props) {
7710
7910
  }
7711
7911
  };
7712
7912
  fn().catch(console.error);
7713
- }, [props.urls?.staticUrl]);
7913
+ }, [props.urls?.staticUrl?.toString()]);
7714
7914
  const [graphcs, setGraphics] = (0, import_react7.useState)([]);
7715
7915
  if (loading) {
7716
- return (0, import_jsx_runtime26.jsx)("div", { children: "Loading.." });
7916
+ return (0, import_jsx_runtime30.jsx)("div", { children: "Loading.." });
7717
7917
  }
7718
7918
  if (graphcs.length == 0) {
7719
- return (0, import_jsx_runtime26.jsx)("div", { children: "No graphics loaded" });
7919
+ return (0, import_jsx_runtime30.jsx)("div", { children: "No graphics loaded" });
7720
7920
  }
7721
- return (0, import_jsx_runtime26.jsx)("div", { children: (0, import_jsx_runtime26.jsxs)("select", { defaultValue: props.defaultValue, className: `node-editor-select-input`, id: props.id, onChange: myOnChange, onBlur: myOnChange, children: [(0, import_jsx_runtime26.jsx)("option", { value: "", children: "---" }, "empty"), graphcs.map((o, i) => {
7722
- return (0, import_jsx_runtime26.jsx)("option", { value: o, children: o }, i);
7921
+ return (0, import_jsx_runtime30.jsx)("div", { children: (0, import_jsx_runtime30.jsxs)("select", { defaultValue: props.defaultValue, className: `node-editor-select-input`, id: props.id, onChange: myOnChange, onBlur: myOnChange, children: [(0, import_jsx_runtime30.jsx)("option", { value: "", children: "---" }, "empty"), graphcs.map((o, i) => {
7922
+ return (0, import_jsx_runtime30.jsx)("option", { value: o, children: o }, i);
7723
7923
  })] }) });
7724
7924
  function myOnChange(e) {
7725
7925
  props.onChanged(e.target.value);
@@ -7728,9 +7928,9 @@ function GraphicSelection(props) {
7728
7928
  var image_selection_default = GraphicSelection;
7729
7929
 
7730
7930
  // build/processor.onscreenGraphic/summary-view.js
7731
- var import_jsx_runtime27 = __toESM(require_jsx_runtime());
7931
+ var import_jsx_runtime31 = __toESM(require_jsx_runtime());
7732
7932
  var import_react8 = __toESM(require_react());
7733
- function SummaryView8({ state, sendCommand, urls }) {
7933
+ function SummaryView9({ state, sendCommand, urls }) {
7734
7934
  const [graphic, setGraphic] = (0, import_react8.useState)(state.activeGraphic?.file);
7735
7935
  const [position, setPosition] = (0, import_react8.useState)(state.activeGraphic?.position ?? { type: "named", position: "topleft" });
7736
7936
  const [graphics, setGraphics] = (0, import_react8.useState)([]);
@@ -7756,7 +7956,7 @@ function SummaryView8({ state, sendCommand, urls }) {
7756
7956
  message: "Failed to update graphic list."
7757
7957
  });
7758
7958
  }
7759
- }, [urls.staticUrl]);
7959
+ }, [urls.staticUrl.toString()]);
7760
7960
  (0, import_react8.useEffect)(() => {
7761
7961
  updateGraphics().catch(console.error);
7762
7962
  }, [updateGraphics]);
@@ -7865,7 +8065,7 @@ function SummaryView8({ state, sendCommand, urls }) {
7865
8065
  const buttonClass = "mt-2 mb-5 text-white w-full justify-center bg-primary-700 hover:bg-primary-800 focus:ring-4 focus:outline-none focus:ring-primary-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:bg-primary-600 dark:hover:bg-primary-700 dark:focus:ring-primary-800";
7866
8066
  const deleteButtonClass = "mt-2 text-white w-full justify-center bg-red-600 hover:bg-red-700 focus:ring-4 focus:outline-none focus:ring-red-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:bg-red-700 dark:hover:bg-red-800 dark:focus:ring-red-900";
7867
8067
  const fileInputClass = "block w-full text-gray-900 border border-gray-300 rounded-lg cursor-pointer bg-gray-50 dark:text-gray-400 focus:outline-none dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400";
7868
- return (0, import_jsx_runtime27.jsxs)("div", { className: "space-y-3", children: [(0, import_jsx_runtime27.jsx)("h2", { className: "text-xl font-bold text-gray-900 dark:text-white", children: "Controls" }), (0, import_jsx_runtime27.jsxs)("div", { children: [(0, import_jsx_runtime27.jsx)("label", { htmlFor: "select-graphic", className: "block text-gray-900 dark:text-white mb-1", children: "Source" }), (0, import_jsx_runtime27.jsxs)("select", { id: "select-graphic", className: "w-full node-editor-select-input", value: graphic || "", onChange: (e) => setGraphic(e.target.value || void 0), children: [(0, import_jsx_runtime27.jsx)("option", { value: "", children: "---" }), graphics.map((s) => (0, import_jsx_runtime27.jsx)("option", { value: s, children: s }, s))] })] }), graphic && (0, import_jsx_runtime27.jsxs)("div", { children: [(0, import_jsx_runtime27.jsx)("label", { htmlFor: "select-position", className: "block text-gray-900 dark:text-white mb-1", children: "Graphic position" }), (0, import_jsx_runtime27.jsx)(PositionSelector, { initialPosition: position, onChange: setPosition, graphicChanged, ...state })] }), (0, import_jsx_runtime27.jsx)("button", { type: "button", className: `${buttonClass} ${!stateChanged ? "opacity-50 cursor-not-allowed" : ""}`, onClick: () => sendCommand({ type: "change-graphic", file: graphic, position }), disabled: !stateChanged, children: "Commit" }), !showFileInput && !uploadStatus.success && (0, import_jsx_runtime27.jsx)("button", { type: "button", className: buttonClass, onClick: () => setShowFileInput(true), style: { marginBottom: "1rem" }, children: "Upload Graphic" }), showFileInput && (0, import_jsx_runtime27.jsxs)("form", { style: { display: "block", marginBottom: "1rem" }, children: [(0, import_jsx_runtime27.jsx)("input", { type: "file", id: "file", name: "filename", onChange: onFileChange, className: fileInputClass }), showUploadButton && (0, import_jsx_runtime27.jsx)("button", { type: "button", className: buttonClass, onClick: uploadFile, children: "Upload" })] }), (0, import_jsx_runtime27.jsx)("button", { type: "button", className: deleteButtonClass, onClick: () => setShowDeleteDropdown(!showDeleteDropdown), style: { marginBottom: "1rem" }, children: showDeleteDropdown ? "Hide Delete Options" : "Delete Graphics" }), showDeleteDropdown && (0, import_jsx_runtime27.jsxs)("div", { className: "mt-2 p-2 bg-gray-100 dark:bg-gray-800 rounded-lg", children: [(0, import_jsx_runtime27.jsx)("h3", { className: "text-lg font-semibold mb-2 text-gray-900 dark:text-white", children: "Select Graphic to Delete" }), (0, import_jsx_runtime27.jsxs)("select", { className: "w-full mb-2 node-editor-select-input", value: graphicToDelete, onChange: (e) => setGraphicToDelete(e.target.value), children: [(0, import_jsx_runtime27.jsx)("option", { value: "", children: " Select a graphic" }), graphics.map((graphicName) => (0, import_jsx_runtime27.jsx)("option", { value: graphicName, children: graphicName }, graphicName))] }), (0, import_jsx_runtime27.jsx)("button", { onClick: deleteBug, disabled: !graphicToDelete, className: `${deleteButtonClass} ${!graphicToDelete ? "opacity-50 cursor-not-allowed" : ""}`, children: "Delete Selected Graphic" })] }), uploadStatus.message && (0, import_jsx_runtime27.jsx)("div", { className: `mt-2 text-center ${uploadStatus.success ? "text-green-600" : "text-red-600"}`, children: uploadStatus.message })] });
8068
+ return (0, import_jsx_runtime31.jsxs)("div", { className: "space-y-3", children: [(0, import_jsx_runtime31.jsx)("h2", { className: "text-xl font-bold text-gray-900 dark:text-white", children: "Controls" }), (0, import_jsx_runtime31.jsxs)("div", { children: [(0, import_jsx_runtime31.jsx)("label", { htmlFor: "select-graphic", className: "block text-gray-900 dark:text-white mb-1", children: "Source" }), (0, import_jsx_runtime31.jsxs)("select", { id: "select-graphic", className: "w-full node-editor-select-input", value: graphic || "", onChange: (e) => setGraphic(e.target.value || void 0), children: [(0, import_jsx_runtime31.jsx)("option", { value: "", children: "---" }), graphics.map((s) => (0, import_jsx_runtime31.jsx)("option", { value: s, children: s }, s))] })] }), graphic && (0, import_jsx_runtime31.jsxs)("div", { children: [(0, import_jsx_runtime31.jsx)("label", { htmlFor: "select-position", className: "block text-gray-900 dark:text-white mb-1", children: "Graphic position" }), (0, import_jsx_runtime31.jsx)(PositionSelector, { initialPosition: position, onChange: setPosition, graphicChanged, ...state })] }), (0, import_jsx_runtime31.jsx)("button", { type: "button", className: `${buttonClass} ${!stateChanged ? "opacity-50 cursor-not-allowed" : ""}`, onClick: () => sendCommand({ type: "change-graphic", file: graphic, position }), disabled: !stateChanged, children: "Commit" }), !showFileInput && !uploadStatus.success && (0, import_jsx_runtime31.jsx)("button", { type: "button", className: buttonClass, onClick: () => setShowFileInput(true), style: { marginBottom: "1rem" }, children: "Upload Graphic" }), showFileInput && (0, import_jsx_runtime31.jsxs)("form", { style: { display: "block", marginBottom: "1rem" }, children: [(0, import_jsx_runtime31.jsx)("input", { type: "file", id: "file", name: "filename", onChange: onFileChange, className: fileInputClass }), showUploadButton && (0, import_jsx_runtime31.jsx)("button", { type: "button", className: buttonClass, onClick: uploadFile, children: "Upload" })] }), (0, import_jsx_runtime31.jsx)("button", { type: "button", className: deleteButtonClass, onClick: () => setShowDeleteDropdown(!showDeleteDropdown), style: { marginBottom: "1rem" }, children: showDeleteDropdown ? "Hide Delete Options" : "Delete Graphics" }), showDeleteDropdown && (0, import_jsx_runtime31.jsxs)("div", { className: "mt-2 p-2 bg-gray-100 dark:bg-gray-800 rounded-lg", children: [(0, import_jsx_runtime31.jsx)("h3", { className: "text-lg font-semibold mb-2 text-gray-900 dark:text-white", children: "Select Graphic to Delete" }), (0, import_jsx_runtime31.jsxs)("select", { className: "w-full mb-2 node-editor-select-input", value: graphicToDelete, onChange: (e) => setGraphicToDelete(e.target.value), children: [(0, import_jsx_runtime31.jsx)("option", { value: "", children: " Select a graphic" }), graphics.map((graphicName) => (0, import_jsx_runtime31.jsx)("option", { value: graphicName, children: graphicName }, graphicName))] }), (0, import_jsx_runtime31.jsx)("button", { onClick: deleteBug, disabled: !graphicToDelete, className: `${deleteButtonClass} ${!graphicToDelete ? "opacity-50 cursor-not-allowed" : ""}`, children: "Delete Selected Graphic" })] }), uploadStatus.message && (0, import_jsx_runtime31.jsx)("div", { className: `mt-2 text-center ${uploadStatus.success ? "text-green-600" : "text-red-600"}`, children: uploadStatus.message })] });
7869
8069
  }
7870
8070
  function fromLocalPosition(pos) {
7871
8071
  if (pos.type === "named")
@@ -7874,7 +8074,7 @@ function fromLocalPosition(pos) {
7874
8074
  return { type: pos.type, x: pos.x, y: pos.y };
7875
8075
  if (pos.type === "percentage")
7876
8076
  return { type: pos.type, x: pos.x, y: pos.y };
7877
- assertUnreachable12(pos);
8077
+ assertUnreachable13(pos);
7878
8078
  }
7879
8079
  function convertPosition(givenPosition, currentVideo, currentGraphic) {
7880
8080
  if (!givenPosition)
@@ -7892,7 +8092,7 @@ function convertPosition(givenPosition, currentVideo, currentGraphic) {
7892
8092
  } else if (givenPosition.position === "center") {
7893
8093
  xy = { x: 50, y: 50 };
7894
8094
  } else {
7895
- assertUnreachable12(givenPosition.position);
8095
+ assertUnreachable13(givenPosition.position);
7896
8096
  }
7897
8097
  return { ...givenPosition, ...xy, xPct: xy.x, yPct: xy.y };
7898
8098
  }
@@ -7980,7 +8180,7 @@ var PositionSelector = ({ initialPosition: givenPosition = { type: "named", posi
7980
8180
  window.removeEventListener("mouseup", handleMouseUp);
7981
8181
  };
7982
8182
  }, [isDragging]);
7983
- return (0, import_jsx_runtime27.jsxs)("div", { className: "relative w-full max-w-lg mx-auto mt-4 mb-8", children: [(0, import_jsx_runtime27.jsxs)("div", { className: "mb-4 flex items-center gap-2", children: [(0, import_jsx_runtime27.jsx)("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300", children: "Position Type:" }), (0, import_jsx_runtime27.jsxs)("select", { value: position.type, onChange: (e) => {
8183
+ return (0, import_jsx_runtime31.jsxs)("div", { className: "relative w-full max-w-lg mx-auto mt-4 mb-8", children: [(0, import_jsx_runtime31.jsxs)("div", { className: "mb-4 flex items-center gap-2", children: [(0, import_jsx_runtime31.jsx)("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300", children: "Position Type:" }), (0, import_jsx_runtime31.jsxs)("select", { value: position.type, onChange: (e) => {
7984
8184
  const newType = e.target.value;
7985
8185
  if (newType === "named") {
7986
8186
  setPosition(convertPos({ type: "named", position: "topleft" }));
@@ -7988,12 +8188,12 @@ var PositionSelector = ({ initialPosition: givenPosition = { type: "named", posi
7988
8188
  setPositionUnit("%");
7989
8189
  setPosition({ ...convertPos(position), type: "percentage" });
7990
8190
  }
7991
- }, className: "node-editor-select-input", children: [(0, import_jsx_runtime27.jsx)("option", { value: "coordinate", children: "Custom Position" }), (0, import_jsx_runtime27.jsx)("option", { value: "named", children: "Preset Position" })] })] }), position.type === "named" ? (0, import_jsx_runtime27.jsx)("div", { className: "mb-4", children: (0, import_jsx_runtime27.jsxs)("select", { value: position.position, onChange: (e) => {
8191
+ }, className: "node-editor-select-input", children: [(0, import_jsx_runtime31.jsx)("option", { value: "coordinate", children: "Custom Position" }), (0, import_jsx_runtime31.jsx)("option", { value: "named", children: "Preset Position" })] })] }), position.type === "named" ? (0, import_jsx_runtime31.jsx)("div", { className: "mb-4", children: (0, import_jsx_runtime31.jsxs)("select", { value: position.position, onChange: (e) => {
7992
8192
  setPosition(convertPos({
7993
8193
  type: "named",
7994
8194
  position: e.target.value
7995
8195
  }));
7996
- }, className: "w-full node-editor-select-input", children: [(0, import_jsx_runtime27.jsx)("option", { value: "topleft", children: "Top Left" }), (0, import_jsx_runtime27.jsx)("option", { value: "topright", children: "Top Right" }), (0, import_jsx_runtime27.jsx)("option", { value: "bottomleft", children: "Bottom Left" }), (0, import_jsx_runtime27.jsx)("option", { value: "bottomright", children: "Bottom Right" }), (0, import_jsx_runtime27.jsx)("option", { value: "center", children: "Centered" })] }) }) : (0, import_jsx_runtime27.jsxs)(import_jsx_runtime27.Fragment, { children: [(0, import_jsx_runtime27.jsxs)("div", { className: "mb-4 flex items-center gap-2", children: [(0, import_jsx_runtime27.jsx)("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300", children: "Position Unit:" }), (0, import_jsx_runtime27.jsxs)("select", { value: positionUnit, onChange: (e) => {
8196
+ }, className: "w-full node-editor-select-input", children: [(0, import_jsx_runtime31.jsx)("option", { value: "topleft", children: "Top Left" }), (0, import_jsx_runtime31.jsx)("option", { value: "topright", children: "Top Right" }), (0, import_jsx_runtime31.jsx)("option", { value: "bottomleft", children: "Bottom Left" }), (0, import_jsx_runtime31.jsx)("option", { value: "bottomright", children: "Bottom Right" }), (0, import_jsx_runtime31.jsx)("option", { value: "center", children: "Centered" })] }) }) : (0, import_jsx_runtime31.jsxs)(import_jsx_runtime31.Fragment, { children: [(0, import_jsx_runtime31.jsxs)("div", { className: "mb-4 flex items-center gap-2", children: [(0, import_jsx_runtime31.jsx)("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300", children: "Position Unit:" }), (0, import_jsx_runtime31.jsxs)("select", { value: positionUnit, onChange: (e) => {
7997
8197
  setPositionUnit(e.target.value);
7998
8198
  if (e.target.value === "px" && position.type !== "coordinate" && currentVideo && currentGraphic) {
7999
8199
  const { width: videoWidth, height: videoHeight } = currentVideo;
@@ -8018,18 +8218,18 @@ var PositionSelector = ({ initialPosition: givenPosition = { type: "named", posi
8018
8218
  yStr: void 0
8019
8219
  });
8020
8220
  }
8021
- }, className: "node-editor-select-input", children: [(0, import_jsx_runtime27.jsx)("option", { value: "px", children: "Pixels" }), (0, import_jsx_runtime27.jsx)("option", { value: "%", children: "Percentage" })] })] }), (0, import_jsx_runtime27.jsxs)("div", { className: "relative bg-gray-200 dark:bg-gray-700 rounded-lg", style: {
8221
+ }, className: "node-editor-select-input", children: [(0, import_jsx_runtime31.jsx)("option", { value: "px", children: "Pixels" }), (0, import_jsx_runtime31.jsx)("option", { value: "%", children: "Percentage" })] })] }), (0, import_jsx_runtime31.jsxs)("div", { className: "relative bg-gray-200 dark:bg-gray-700 rounded-lg", style: {
8022
8222
  width: "100%",
8023
8223
  userSelect: "none",
8024
8224
  aspectRatio: currentVideo ? `${currentVideo.width} / ${currentVideo.height}` : `3 / 2`
8025
- }, ref: previewAreaRef, children: [(0, import_jsx_runtime27.jsxs)("div", { className: "absolute inset-0 flex flex-col items-center justify-center text-gray-500 dark:text-gray-400", children: [(0, import_jsx_runtime27.jsx)("span", { children: currentVideo ? "Video Preview Area" : "Video Dimensions Unknown" }), " ", currentVideo ? (0, import_jsx_runtime27.jsxs)("span", { children: [currentVideo.width, "x", currentVideo.height, "px"] }) : ""] }), (0, import_jsx_runtime27.jsx)("div", { className: `absolute cursor-move ${currentGraphic && !graphicChanged ? "" : "p-2"} rounded-lg bg-primary-500 bg-opacity-50 hover:bg-opacity-75 transition-colors
8225
+ }, ref: previewAreaRef, children: [(0, import_jsx_runtime31.jsxs)("div", { className: "absolute inset-0 flex flex-col items-center justify-center text-gray-500 dark:text-gray-400", children: [(0, import_jsx_runtime31.jsx)("span", { children: currentVideo ? "Video Preview Area" : "Video Dimensions Unknown" }), " ", currentVideo ? (0, import_jsx_runtime31.jsxs)("span", { children: [currentVideo.width, "x", currentVideo.height, "px"] }) : ""] }), (0, import_jsx_runtime31.jsx)("div", { className: `absolute cursor-move ${currentGraphic && !graphicChanged ? "" : "p-2"} rounded-lg bg-primary-500 bg-opacity-50 hover:bg-opacity-75 transition-colors
8026
8226
  ${isDragging ? "bg-opacity-75" : ""}`, style: {
8027
8227
  left: `${position.xPct}%`,
8028
8228
  top: `${position.yPct}%`,
8029
8229
  transform: `translate(-${position.xPct}%, -${position.yPct}%)`,
8030
8230
  aspectRatio: currentGraphic && !graphicChanged ? `${currentGraphic.width} / ${currentGraphic.height}` : `1`,
8031
8231
  width: currentGraphic && currentVideo && !graphicChanged ? currentGraphic.width / currentVideo.width * 100 + "%" : void 0
8032
- }, onMouseDown: handleMouseDown, ref: previewTargetRef, children: (0, import_jsx_runtime27.jsx)("svg", { className: `${currentGraphic && !graphicChanged ? "w-full h-full" : "w-6 h-6"} text-white`, "aria-hidden": "true", xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", children: (0, import_jsx_runtime27.jsx)("path", { stroke: "currentColor", strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M12 6v12m-6-6h12m-6-6 1.5 1.5M12 6l-1.5 1.5m1.5 10.5L10.5 16.5M12 18l1.5-1.5M6 12l1.5-1.5M7.5 13.5 6 12m12 0-1.5-1.5M16.5 13.5 18 12" }) }) })] }), (0, import_jsx_runtime27.jsxs)("div", { className: "mt-2 text-sm text-gray-600 dark:text-gray-300 text-center", children: ["Position:", " ", position.type === "percentage" ? `${position.xPct.toFixed(1)}%, ${position.yPct.toFixed(1)}%` : `${Math.round(position.x)}px, ${Math.round(position.y)}px`] }), (0, import_jsx_runtime27.jsxs)("div", { className: "mt-2 flex gap-4", children: [(0, import_jsx_runtime27.jsxs)("div", { children: [(0, import_jsx_runtime27.jsxs)("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300", children: ["X Position ", positionUnit] }), (0, import_jsx_runtime27.jsx)("input", { type: "number", step: positionUnit === "%" ? "0.1" : "1", value: position.xStr ?? (positionUnit === "%" ? position.xPct.toFixed(1) : Math.round(position.x)), onChange: (e) => {
8232
+ }, onMouseDown: handleMouseDown, ref: previewTargetRef, children: (0, import_jsx_runtime31.jsx)("svg", { className: `${currentGraphic && !graphicChanged ? "w-full h-full" : "w-6 h-6"} text-white`, "aria-hidden": "true", xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", children: (0, import_jsx_runtime31.jsx)("path", { stroke: "currentColor", strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M12 6v12m-6-6h12m-6-6 1.5 1.5M12 6l-1.5 1.5m1.5 10.5L10.5 16.5M12 18l1.5-1.5M6 12l1.5-1.5M7.5 13.5 6 12m12 0-1.5-1.5M16.5 13.5 18 12" }) }) })] }), (0, import_jsx_runtime31.jsxs)("div", { className: "mt-2 text-sm text-gray-600 dark:text-gray-300 text-center", children: ["Position:", " ", position.type === "percentage" ? `${position.xPct.toFixed(1)}%, ${position.yPct.toFixed(1)}%` : `${Math.round(position.x)}px, ${Math.round(position.y)}px`] }), (0, import_jsx_runtime31.jsxs)("div", { className: "mt-2 flex gap-4", children: [(0, import_jsx_runtime31.jsxs)("div", { children: [(0, import_jsx_runtime31.jsxs)("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300", children: ["X Position ", positionUnit] }), (0, import_jsx_runtime31.jsx)("input", { type: "number", step: positionUnit === "%" ? "0.1" : "1", value: position.xStr ?? (positionUnit === "%" ? position.xPct.toFixed(1) : Math.round(position.x)), onChange: (e) => {
8033
8233
  const newX = Number(e.target.value);
8034
8234
  setPosition(convertPos({
8035
8235
  type: positionUnit === "%" ? "percentage" : "coordinate",
@@ -8038,7 +8238,7 @@ var PositionSelector = ({ initialPosition: givenPosition = { type: "named", posi
8038
8238
  y: position.y,
8039
8239
  yStr: position.yStr
8040
8240
  }));
8041
- }, className: "mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-primary-500 focus:ring-primary-500 sm:text-sm dark:bg-gray-700 dark:border-gray-600" })] }), (0, import_jsx_runtime27.jsxs)("div", { children: [(0, import_jsx_runtime27.jsxs)("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300", children: ["Y Position ", positionUnit] }), (0, import_jsx_runtime27.jsx)("input", { type: "number", step: positionUnit === "%" ? "0.1" : "1", value: position.yStr ?? (positionUnit === "%" ? position.yPct.toFixed(1) : Math.round(position.y)), onChange: (e) => {
8241
+ }, className: "mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-primary-500 focus:ring-primary-500 sm:text-sm dark:bg-gray-700 dark:border-gray-600" })] }), (0, import_jsx_runtime31.jsxs)("div", { children: [(0, import_jsx_runtime31.jsxs)("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300", children: ["Y Position ", positionUnit] }), (0, import_jsx_runtime31.jsx)("input", { type: "number", step: positionUnit === "%" ? "0.1" : "1", value: position.yStr ?? (positionUnit === "%" ? position.yPct.toFixed(1) : Math.round(position.y)), onChange: (e) => {
8042
8242
  const newY = Number(e.target.value);
8043
8243
  setPosition(convertPos({
8044
8244
  type: positionUnit === "%" ? "percentage" : "coordinate",
@@ -8052,13 +8252,13 @@ var PositionSelector = ({ initialPosition: givenPosition = { type: "named", posi
8052
8252
  function clamp(min, num, max) {
8053
8253
  return num < min ? min : num > max ? max : num;
8054
8254
  }
8055
- function assertUnreachable12(_) {
8255
+ function assertUnreachable13(_) {
8056
8256
  throw new Error("Didn't expect to get here");
8057
8257
  }
8058
- var summary_view_default8 = SummaryView8;
8258
+ var summary_view_default9 = SummaryView9;
8059
8259
 
8060
8260
  // build/processor.onscreenGraphic/info.js
8061
- function info_default24({ defineComponent }) {
8261
+ function info_default25({ defineComponent }) {
8062
8262
  return defineComponent({
8063
8263
  identifier: "processor.onscreenGraphic",
8064
8264
  category: "processor",
@@ -8084,7 +8284,7 @@ function info_default24({ defineComponent }) {
8084
8284
  };
8085
8285
  },
8086
8286
  runtime: {
8087
- summary: summary_view_default8,
8287
+ summary: summary_view_default9,
8088
8288
  initialState: () => ({}),
8089
8289
  handleEvent: (ev, state) => {
8090
8290
  const evType = ev.type;
@@ -8096,7 +8296,7 @@ function info_default24({ defineComponent }) {
8096
8296
  case "graphic-loaded":
8097
8297
  return { ...state, currentGraphic: ev.currentGraphic };
8098
8298
  default:
8099
- assertUnreachable13(evType);
8299
+ assertUnreachable14(evType);
8100
8300
  }
8101
8301
  }
8102
8302
  },
@@ -8132,12 +8332,12 @@ function info_default24({ defineComponent }) {
8132
8332
  }
8133
8333
  });
8134
8334
  }
8135
- function assertUnreachable13(_) {
8335
+ function assertUnreachable14(_) {
8136
8336
  throw new Error("Didn't expect to get here");
8137
8337
  }
8138
8338
 
8139
8339
  // build/processor.streamKeyOverride/info.js
8140
- function info_default25({ defineComponent, All, validation: { Z } }) {
8340
+ function info_default26({ defineComponent, All, validation: { Z } }) {
8141
8341
  return defineComponent({
8142
8342
  identifier: "processor.streamKeyOverride",
8143
8343
  category: "processor",
@@ -8229,7 +8429,7 @@ function info_default25({ defineComponent, All, validation: { Z } }) {
8229
8429
  }
8230
8430
 
8231
8431
  // build/processor.videoDecoder/info.js
8232
- function info_default26({ defineComponent }) {
8432
+ function info_default27({ defineComponent }) {
8233
8433
  return defineComponent({
8234
8434
  identifier: "processor.videoDecoder",
8235
8435
  category: "processor",
@@ -8275,7 +8475,7 @@ function info_default26({ defineComponent }) {
8275
8475
  }
8276
8476
 
8277
8477
  // build/util.stats.latency/inline-view.js
8278
- var import_jsx_runtime28 = __toESM(require_jsx_runtime());
8478
+ var import_jsx_runtime32 = __toESM(require_jsx_runtime());
8279
8479
  var import_react9 = __toESM(require_react());
8280
8480
 
8281
8481
  // ../../node_modules/@kurkle/color/dist/color.esm.js
@@ -22574,7 +22774,7 @@ Chart.register(...registerables);
22574
22774
  var auto_default = Chart;
22575
22775
 
22576
22776
  // build/util.stats.latency/inline-view.js
22577
- function InlineView11({ state, config: _2 }) {
22777
+ function InlineView12({ state, config: _2 }) {
22578
22778
  const chartContainer = (0, import_react9.useRef)(null);
22579
22779
  const [chartControl, setChartControl] = (0, import_react9.useState)(void 0);
22580
22780
  function makeDataSet(key, color2, values) {
@@ -22636,19 +22836,19 @@ function InlineView11({ state, config: _2 }) {
22636
22836
  return;
22637
22837
  chartControl.data = makeData(state);
22638
22838
  }, [state]);
22639
- return (0, import_jsx_runtime28.jsx)("div", { className: "bg-gray-50 dark:bg-gray-700 rounded", style: { width: "360px", height: "200px", padding: "10px" }, children: (0, import_jsx_runtime28.jsx)("canvas", { className: "bg-gray-50 dark:bg-gray-700 rounded", ref: chartContainer }) });
22839
+ return (0, import_jsx_runtime32.jsx)("div", { className: "bg-gray-50 dark:bg-gray-700 rounded", style: { width: "360px", height: "200px", padding: "10px" }, children: (0, import_jsx_runtime32.jsx)("canvas", { className: "bg-gray-50 dark:bg-gray-700 rounded", ref: chartContainer }) });
22640
22840
  }
22641
- var inline_view_default11 = InlineView11;
22841
+ var inline_view_default12 = InlineView12;
22642
22842
 
22643
22843
  // build/util.stats.latency/source-node-selection.js
22644
- var import_jsx_runtime29 = __toESM(require_jsx_runtime());
22844
+ var import_jsx_runtime33 = __toESM(require_jsx_runtime());
22645
22845
  function SourceNodeSelection(props) {
22646
- return (0, import_jsx_runtime29.jsx)("div", { children: (0, import_jsx_runtime29.jsxs)("select", { defaultValue: props.defaultValue, className: `node-editor-select-input`, id: props.id, onChange: myOnChange, onBlur: myOnChange, children: [(0, import_jsx_runtime29.jsx)("option", { value: "", children: "---" }, "empty"), Object.values(props.latestDocument.components).map((o, i) => {
22846
+ return (0, import_jsx_runtime33.jsx)("div", { children: (0, import_jsx_runtime33.jsxs)("select", { defaultValue: props.defaultValue, className: `node-editor-select-input`, id: props.id, onChange: myOnChange, onBlur: myOnChange, children: [(0, import_jsx_runtime33.jsx)("option", { value: "", children: "---" }, "empty"), Object.values(props.latestDocument.components).map((o, i) => {
22647
22847
  if (o.id == props.id)
22648
- return (0, import_jsx_runtime29.jsx)(import_jsx_runtime29.Fragment, {});
22848
+ return (0, import_jsx_runtime33.jsx)(import_jsx_runtime33.Fragment, {});
22649
22849
  if (o.info.category === "output")
22650
22850
  return;
22651
- return (0, import_jsx_runtime29.jsx)("option", { value: o.id, children: o.config.displayName }, i);
22851
+ return (0, import_jsx_runtime33.jsx)("option", { value: o.id, children: o.config.displayName }, i);
22652
22852
  })] }) });
22653
22853
  function myOnChange(e) {
22654
22854
  props.onChanged(e.target.value);
@@ -22657,7 +22857,7 @@ function SourceNodeSelection(props) {
22657
22857
  var source_node_selection_default = SourceNodeSelection;
22658
22858
 
22659
22859
  // build/util.stats.latency/info.js
22660
- function info_default27(R) {
22860
+ function info_default28(R) {
22661
22861
  const { defineComponent } = R;
22662
22862
  return defineComponent({
22663
22863
  identifier: "util.stats.latency",
@@ -22686,11 +22886,11 @@ function info_default27(R) {
22686
22886
  break;
22687
22887
  }
22688
22888
  default:
22689
- assertUnreachable14(evType);
22889
+ assertUnreachable15(evType);
22690
22890
  }
22691
22891
  return { ...state };
22692
22892
  },
22693
- inline: inline_view_default11
22893
+ inline: inline_view_default12
22694
22894
  },
22695
22895
  configForm: {
22696
22896
  form: {
@@ -22741,7 +22941,7 @@ function info_default27(R) {
22741
22941
  }
22742
22942
  });
22743
22943
  }
22744
- function assertUnreachable14(_) {
22944
+ function assertUnreachable15(_) {
22745
22945
  throw new Error("Didn't expect to get here");
22746
22946
  }
22747
22947
 
@@ -22786,6 +22986,7 @@ AllComponents.push((r) => info_default24(r));
22786
22986
  AllComponents.push((r) => info_default25(r));
22787
22987
  AllComponents.push((r) => info_default26(r));
22788
22988
  AllComponents.push((r) => info_default27(r));
22989
+ AllComponents.push((r) => info_default28(r));
22789
22990
  export {
22790
22991
  getNodeInfo as default
22791
22992
  };