@norskvideo/norsk-studio-built-ins 1.12.0-2025-02-02-6cada821 → 1.12.0-2025-02-04-9551fc82

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 (90) hide show
  1. package/client/info.js +180 -81
  2. package/client/style.css +64 -0
  3. package/lib/input.rtmp/info.js +7 -0
  4. package/lib/input.rtmp/info.js.map +1 -1
  5. package/lib/input.rtmp/runtime.d.ts +1 -0
  6. package/lib/input.rtmp/runtime.js.map +1 -1
  7. package/lib/input.silence/info.js +7 -0
  8. package/lib/input.silence/info.js.map +1 -1
  9. package/lib/input.silence/runtime.d.ts +1 -0
  10. package/lib/input.silence/runtime.js.map +1 -1
  11. package/lib/input.srt-caller/info.js +7 -0
  12. package/lib/input.srt-caller/info.js.map +1 -1
  13. package/lib/input.srt-caller/runtime.d.ts +1 -0
  14. package/lib/input.srt-caller/runtime.js.map +1 -1
  15. package/lib/input.srt-listener/info.js +8 -1
  16. package/lib/input.srt-listener/info.js.map +1 -1
  17. package/lib/input.srt-listener/runtime.d.ts +1 -1
  18. package/lib/input.srt-listener/runtime.js +0 -1
  19. package/lib/input.srt-listener/runtime.js.map +1 -1
  20. package/lib/input.srt-listener/summary-view.js +1 -8
  21. package/lib/input.srt-listener/summary-view.js.map +1 -1
  22. package/lib/input.udp-ts/info.js +1 -0
  23. package/lib/input.udp-ts/info.js.map +1 -1
  24. package/lib/input.udp-ts/runtime.d.ts +1 -0
  25. package/lib/input.udp-ts/runtime.js.map +1 -1
  26. package/lib/input.videoTestCard/info.js +7 -0
  27. package/lib/input.videoTestCard/info.js.map +1 -1
  28. package/lib/input.videoTestCard/runtime.d.ts +1 -0
  29. package/lib/output.autoCmaf/info.js +7 -0
  30. package/lib/output.autoCmaf/info.js.map +1 -1
  31. package/lib/output.autoCmaf/runtime.d.ts +1 -0
  32. package/lib/output.autoCmaf/runtime.js.map +1 -1
  33. package/lib/output.preview/info.js +7 -0
  34. package/lib/output.preview/info.js.map +1 -1
  35. package/lib/output.preview/runtime.d.ts +1 -0
  36. package/lib/output.rtmp/info.js +1 -0
  37. package/lib/output.rtmp/info.js.map +1 -1
  38. package/lib/output.rtmp/runtime.d.ts +1 -0
  39. package/lib/output.rtmp/runtime.js.map +1 -1
  40. package/lib/output.srt/info.js +1 -0
  41. package/lib/output.srt/info.js.map +1 -1
  42. package/lib/output.srt/runtime.d.ts +1 -2
  43. package/lib/output.srt/runtime.js +1 -6
  44. package/lib/output.srt/runtime.js.map +1 -1
  45. package/lib/output.statistics/info.js +3 -1
  46. package/lib/output.statistics/info.js.map +1 -1
  47. package/lib/output.statistics/runtime.d.ts +1 -0
  48. package/lib/output.statistics/runtime.js.map +1 -1
  49. package/lib/output.udpTs/info.js +1 -0
  50. package/lib/output.udpTs/info.js.map +1 -1
  51. package/lib/output.udpTs/runtime.d.ts +1 -0
  52. package/lib/output.udpTs/runtime.js.map +1 -1
  53. package/lib/output.whep/info.d.ts +2 -2
  54. package/lib/output.whep/info.js +11 -2
  55. package/lib/output.whep/info.js.map +1 -1
  56. package/lib/output.whep/inline-view.d.ts +2 -2
  57. package/lib/output.whep/inline-view.js.map +1 -1
  58. package/lib/output.whep/runtime.d.ts +25 -10
  59. package/lib/output.whep/runtime.js +143 -10
  60. package/lib/output.whep/runtime.js.map +1 -1
  61. package/lib/output.whep/summary-view.d.ts +4 -0
  62. package/lib/output.whep/summary-view.js +24 -0
  63. package/lib/output.whep/summary-view.js.map +1 -0
  64. package/lib/processor.browserOverlay/info.js +1 -0
  65. package/lib/processor.browserOverlay/info.js.map +1 -1
  66. package/lib/processor.browserOverlay/runtime.d.ts +1 -0
  67. package/lib/processor.browserOverlay/runtime.js.map +1 -1
  68. package/lib/processor.cascadingSwitch/info.js +1 -0
  69. package/lib/processor.cascadingSwitch/info.js.map +1 -1
  70. package/lib/processor.cascadingSwitch/runtime.d.ts +1 -0
  71. package/lib/processor.cascadingSwitch/runtime.js.map +1 -1
  72. package/lib/processor.fixedLadder/info.js +2 -1
  73. package/lib/processor.fixedLadder/info.js.map +1 -1
  74. package/lib/processor.fixedLadder/runtime.d.ts +1 -0
  75. package/lib/processor.fixedLadder/runtime.js.map +1 -1
  76. package/lib/processor.onscreenGraphic/info.js +2 -1
  77. package/lib/processor.onscreenGraphic/info.js.map +1 -1
  78. package/lib/processor.onscreenGraphic/runtime.d.ts +1 -0
  79. package/lib/processor.onscreenGraphic/runtime.js.map +1 -1
  80. package/lib/processor.streamKeyOverride/info.js +1 -0
  81. package/lib/processor.streamKeyOverride/info.js.map +1 -1
  82. package/lib/processor.streamKeyOverride/runtime.d.ts +1 -0
  83. package/lib/processor.streamKeyOverride/runtime.js.map +1 -1
  84. package/lib/test/whep-output.js +184 -3
  85. package/lib/test/whep-output.js.map +1 -1
  86. package/lib/util.stats.latency/info.js +1 -0
  87. package/lib/util.stats.latency/info.js.map +1 -1
  88. package/lib/util.stats.latency/runtime.d.ts +1 -0
  89. package/lib/util.stats.latency/runtime.js.map +1 -1
  90. package/package.json +3 -3
package/client/info.js CHANGED
@@ -236,11 +236,7 @@ function SummaryView3({ state, config, sendCommand }) {
236
236
  disconnectedSources.push(streamId);
237
237
  }
238
238
  });
239
- return (0, import_jsx_runtime5.jsxs)("div", { className: "dark:text-white text-black mb-3 w-60", children: [(0, import_jsx_runtime5.jsxs)("div", { id: "srt-sources-connected", children: [(0, import_jsx_runtime5.jsx)("span", { children: "Connected Sources" }), (0, import_jsx_runtime5.jsx)("ul", { children: connectedSources.map((streamId) => {
240
- return (0, import_jsx_runtime5.jsxs)("li", { className: "text-green-300", children: [streamId, (0, import_jsx_runtime5.jsx)("button", { onClick: () => handleResetStream(streamId), className: "ml-2 px-2 py-1 text-xs bg-red-600 hover:bg-red-700 text-white rounded", children: "Reset" }), (0, import_jsx_runtime5.jsx)("button", { onClick: () => handleDisableStream(streamId), className: "ml-2 px-2 py-1 text-xs bg-red-600 hover:bg-red-700 text-white rounded", children: "Disable" })] }, streamId);
241
- }) })] }), (0, import_jsx_runtime5.jsxs)("div", { id: "srt-sources-disconnected", className: "mt-3", children: [(0, import_jsx_runtime5.jsx)("span", { children: "Disconnected Sources" }), (0, import_jsx_runtime5.jsx)("ul", { children: disconnectedSources.map((streamId) => {
242
- return (0, import_jsx_runtime5.jsxs)("li", { className: "text-orange-300", children: [streamId, state.disabledStreams.includes(streamId) ? (0, import_jsx_runtime5.jsx)("button", { onClick: () => handleEnableStream(streamId), className: "ml-2 px-2 py-1 text-xs bg-blue-600 hover:bg-blue-700 text-white rounded", children: "Enable" }) : (0, import_jsx_runtime5.jsx)("button", { onClick: () => handleDisableStream(streamId), className: "ml-2 px-2 py-1 text-xs bg-red-600 hover:bg-red-700 text-white rounded", children: "Disable" })] }, streamId);
243
- }) })] })] });
239
+ return (0, import_jsx_runtime5.jsxs)("div", { className: "dark:text-white text-black w-60", children: [(0, import_jsx_runtime5.jsxs)("div", { className: "mb-6", children: [(0, import_jsx_runtime5.jsx)("h3", { className: "text-sm font-semibold mb-2 dark:text-gray-300", children: "Connected Sources" }), (0, import_jsx_runtime5.jsxs)("ul", { className: "space-y-2", children: [connectedSources.map((streamId) => (0, import_jsx_runtime5.jsxs)("li", { className: "flex items-center justify-between group", children: [(0, import_jsx_runtime5.jsx)("span", { className: "text-green-400 font-medium", children: streamId }), (0, import_jsx_runtime5.jsxs)("div", { className: "flex space-x-2", children: [(0, import_jsx_runtime5.jsx)("button", { onClick: () => handleResetStream(streamId), className: "opacity-80 group-hover:opacity-100 px-3 py-1 text-xs bg-red-600 hover:bg-red-700 text-white rounded transition-colors", children: "Reset" }), (0, import_jsx_runtime5.jsx)("button", { onClick: () => handleDisableStream(streamId), className: "opacity-80 group-hover:opacity-100 px-3 py-1 text-xs bg-red-600 hover:bg-red-700 text-white rounded transition-colors", children: "Disable" })] })] }, streamId)), connectedSources.length === 0 && (0, import_jsx_runtime5.jsx)("li", { className: "text-sm text-gray-500 dark:text-gray-400 italic", children: "No connected sources" })] })] }), (0, import_jsx_runtime5.jsxs)("div", { children: [(0, import_jsx_runtime5.jsx)("h3", { className: "text-sm font-semibold mb-2 dark:text-gray-300", children: "Disconnected Sources" }), (0, import_jsx_runtime5.jsxs)("ul", { className: "space-y-2", children: [disconnectedSources.map((streamId) => (0, import_jsx_runtime5.jsxs)("li", { className: "flex items-center justify-between group", children: [(0, import_jsx_runtime5.jsx)("span", { className: "text-orange-300 font-medium", children: streamId }), state.disabledStreams.includes(streamId) ? (0, import_jsx_runtime5.jsx)("button", { onClick: () => handleEnableStream(streamId), className: "opacity-80 group-hover:opacity-100 px-3 py-1 text-xs bg-blue-600 hover:bg-blue-700 text-white rounded transition-colors", children: "Enable" }) : (0, import_jsx_runtime5.jsx)("button", { onClick: () => handleDisableStream(streamId), className: "opacity-80 group-hover:opacity-100 px-3 py-1 text-xs bg-red-600 hover:bg-red-700 text-white rounded transition-colors", children: "Disable" })] }, streamId)), disconnectedSources.length === 0 && (0, import_jsx_runtime5.jsx)("li", { className: "text-sm text-gray-500 dark:text-gray-400 italic", children: "No disconnected sources" })] })] })] });
244
240
  }
245
241
  var import_jsx_runtime5, summary_view_default2;
246
242
  var init_summary_view2 = __esm({
@@ -810,7 +806,9 @@ function info_default11({ defineComponent, All }) {
810
806
  inline: InlineView13
811
807
  },
812
808
  configForm: {
813
- form: {}
809
+ form: {
810
+ notes: { help: "Notes about this component", hint: { type: "text", optional: true } }
811
+ }
814
812
  }
815
813
  });
816
814
  }
@@ -825,6 +823,39 @@ var init_info = __esm({
825
823
  }
826
824
  });
827
825
 
826
+ // build/output.whep/summary-view.js
827
+ var summary_view_exports3 = {};
828
+ __export(summary_view_exports3, {
829
+ default: () => summary_view_default3
830
+ });
831
+ function SummaryView5({ state, sendCommand }) {
832
+ const handleEnableOutput = () => {
833
+ void enableOutput();
834
+ };
835
+ const enableOutput = async () => {
836
+ sendCommand({
837
+ type: "enable-output"
838
+ });
839
+ };
840
+ const handleDisableOutput = () => {
841
+ void disableOutput();
842
+ };
843
+ const disableOutput = async () => {
844
+ sendCommand({
845
+ type: "disable-output"
846
+ });
847
+ };
848
+ return (0, import_jsx_runtime11.jsx)("div", { className: "mb-5", children: (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center justify-between mb-3", children: [(0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center space-x-2", children: [(0, import_jsx_runtime11.jsx)("span", { className: `inline-block w-2 h-2 rounded-full ${state.enabled ? "bg-blue-500" : "bg-red-500"}` }), (0, import_jsx_runtime11.jsxs)("span", { className: "text-sm", children: ["Status: ", state.enabled ? "Enabled" : "Disabled"] })] }), (0, import_jsx_runtime11.jsx)("div", { children: state.enabled ? (0, import_jsx_runtime11.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_runtime11.jsx)("button", { onClick: handleEnableOutput, className: "px-3 py-1 text-sm bg-blue-600 hover:bg-blue-700 text-white rounded", children: "Enable Output" }) })] }) });
849
+ }
850
+ var import_jsx_runtime11, summary_view_default3;
851
+ var init_summary_view3 = __esm({
852
+ "build/output.whep/summary-view.js"() {
853
+ "use strict";
854
+ import_jsx_runtime11 = __toESM(require_jsx_runtime());
855
+ summary_view_default3 = SummaryView5;
856
+ }
857
+ });
858
+
828
859
  // build/output.whep/inline-view.js
829
860
  var inline_view_exports6 = {};
830
861
  __export(inline_view_exports6, {
@@ -872,19 +903,19 @@ function InlineView8({ state, config, raise }) {
872
903
  }, [config.showPreview]);
873
904
  raise && (0, import_react11.useEffect)(raise, []);
874
905
  if (!url)
875
- return (0, import_jsx_runtime11.jsx)(import_jsx_runtime11.Fragment, { children: "..." });
906
+ return (0, import_jsx_runtime12.jsx)(import_jsx_runtime12.Fragment, { children: "..." });
876
907
  const videoStyles = `
877
908
  #whep-${id} video::-webkit-media-controls-play-button {
878
909
  display: none;
879
910
  }
880
911
  `;
881
- return (0, import_jsx_runtime11.jsxs)("div", { className: "whep-container", children: [(0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center gap-2 mb-2", children: [(0, import_jsx_runtime11.jsx)("input", { type: "checkbox", id: `video-toggle-${id}`, checked: showPreview, onChange: (e) => setShowPreview(e.target.checked), className: "h-4 w-4" }), (0, import_jsx_runtime11.jsx)("label", { htmlFor: `video-toggle-${id}`, className: "text-sm", children: "Show Preview" })] }), showPreview ? (0, import_jsx_runtime11.jsx)("div", { className: "whep-video", id: `whep-${id}`, children: (0, import_jsx_runtime11.jsx)("style", { children: videoStyles }) }) : (0, import_jsx_runtime11.jsx)("div", { className: "whep-video bg-black flex items-center justify-center text-white h-full", children: "Preview turned off" })] });
912
+ return (0, import_jsx_runtime12.jsxs)("div", { className: "whep-container", children: [(0, import_jsx_runtime12.jsxs)("div", { className: "flex items-center gap-2 mb-2", children: [(0, import_jsx_runtime12.jsx)("input", { type: "checkbox", id: `video-toggle-${id}`, checked: showPreview, onChange: (e) => setShowPreview(e.target.checked), className: "h-4 w-4" }), (0, import_jsx_runtime12.jsx)("label", { htmlFor: `video-toggle-${id}`, className: "text-sm", children: "Show Preview" })] }), showPreview ? (0, import_jsx_runtime12.jsx)("div", { className: "whep-video", id: `whep-${id}`, children: (0, import_jsx_runtime12.jsx)("style", { children: videoStyles }) }) : (0, import_jsx_runtime12.jsx)("div", { className: "whep-video bg-black flex items-center justify-center text-white h-full", children: "Preview turned off" })] });
882
913
  }
883
- var import_jsx_runtime11, import_react11, import_webrtc_client2, inline_view_default6;
914
+ var import_jsx_runtime12, import_react11, import_webrtc_client2, inline_view_default6;
884
915
  var init_inline_view6 = __esm({
885
916
  "build/output.whep/inline-view.js"() {
886
917
  "use strict";
887
- import_jsx_runtime11 = __toESM(require_jsx_runtime());
918
+ import_jsx_runtime12 = __toESM(require_jsx_runtime());
888
919
  import_react11 = __toESM(require_react());
889
920
  import_webrtc_client2 = __toESM(require_webrtc_client());
890
921
  inline_view_default6 = InlineView8;
@@ -892,18 +923,18 @@ var init_inline_view6 = __esm({
892
923
  });
893
924
 
894
925
  // build/processor.browserOverlay/summary-view.js
895
- var summary_view_exports3 = {};
896
- __export(summary_view_exports3, {
897
- default: () => summary_view_default3
926
+ var summary_view_exports4 = {};
927
+ __export(summary_view_exports4, {
928
+ default: () => summary_view_default4
898
929
  });
899
- function SummaryView5({ state, sendCommand }) {
930
+ function SummaryView7({ state, sendCommand }) {
900
931
  const [url, setUrl] = (0, import_react13.useState)(state.currentUrl);
901
932
  const [enabled, setEnabled] = (0, import_react13.useState)(state.enabled);
902
933
  const stateChanged = (0, import_react13.useMemo)(() => {
903
934
  return url !== state.currentUrl || enabled !== state.enabled;
904
935
  }, [url, enabled]);
905
936
  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";
906
- return (0, import_jsx_runtime12.jsxs)("div", { className: "space-y-3 mb-5", children: [(0, import_jsx_runtime12.jsx)("h2", { className: "text-xl font-bold text-gray-900 dark:text-white", children: "Controls" }), (0, import_jsx_runtime12.jsxs)("div", { className: "mb-5", children: [(0, import_jsx_runtime12.jsx)("label", { htmlFor: "url", className: "mb-2 mr-2 text-sm font-medium text-gray-900 dark:text-white", children: "URL" }), (0, import_jsx_runtime12.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_runtime12.jsx)("div", { className: "mb-5", children: (0, import_jsx_runtime12.jsxs)("label", { className: "inline-flex items-center cursor-pointer", children: [(0, import_jsx_runtime12.jsx)("span", { className: "me-3 text-sm font-medium text-gray-900 dark:text-gray-300", children: "Enabled" }), (0, import_jsx_runtime12.jsx)("input", { type: "checkbox", checked: enabled, onChange: (e) => setEnabled(e.target.checked), className: "sr-only peer" }), (0, import_jsx_runtime12.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_runtime12.jsx)("button", { type: "button", className: `${buttonClass} ${!stateChanged ? "opacity-50 cursor-not-allowed" : ""}`, disabled: !stateChanged, onClick: () => {
937
+ return (0, import_jsx_runtime13.jsxs)("div", { className: "space-y-3 mb-5", children: [(0, import_jsx_runtime13.jsx)("h2", { className: "text-xl font-bold text-gray-900 dark:text-white", children: "Controls" }), (0, import_jsx_runtime13.jsxs)("div", { className: "mb-5", children: [(0, import_jsx_runtime13.jsx)("label", { htmlFor: "url", className: "mb-2 mr-2 text-sm font-medium text-gray-900 dark:text-white", children: "URL" }), (0, import_jsx_runtime13.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_runtime13.jsx)("div", { className: "mb-5", children: (0, import_jsx_runtime13.jsxs)("label", { className: "inline-flex items-center cursor-pointer", children: [(0, import_jsx_runtime13.jsx)("span", { className: "me-3 text-sm font-medium text-gray-900 dark:text-gray-300", children: "Enabled" }), (0, import_jsx_runtime13.jsx)("input", { type: "checkbox", checked: enabled, onChange: (e) => setEnabled(e.target.checked), className: "sr-only peer" }), (0, import_jsx_runtime13.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_runtime13.jsx)("button", { type: "button", className: `${buttonClass} ${!stateChanged ? "opacity-50 cursor-not-allowed" : ""}`, disabled: !stateChanged, onClick: () => {
907
938
  if (url !== state.currentUrl) {
908
939
  sendCommand({ type: "change-url", url });
909
940
  }
@@ -916,13 +947,13 @@ function SummaryView5({ state, sendCommand }) {
916
947
  }
917
948
  }, children: "Commit" })] });
918
949
  }
919
- var import_jsx_runtime12, import_react13, summary_view_default3;
920
- var init_summary_view3 = __esm({
950
+ var import_jsx_runtime13, import_react13, summary_view_default4;
951
+ var init_summary_view4 = __esm({
921
952
  "build/processor.browserOverlay/summary-view.js"() {
922
953
  "use strict";
923
- import_jsx_runtime12 = __toESM(require_jsx_runtime());
954
+ import_jsx_runtime13 = __toESM(require_jsx_runtime());
924
955
  import_react13 = __toESM(require_react());
925
- summary_view_default3 = SummaryView5;
956
+ summary_view_default4 = SummaryView7;
926
957
  }
927
958
  });
928
959
 
@@ -932,13 +963,13 @@ __export(inline_view_exports7, {
932
963
  default: () => inline_view_default7
933
964
  });
934
965
  function InlineView9({ state, config }) {
935
- return (0, import_jsx_runtime13.jsx)("div", { id: `browser-overlay-${config.id}`, children: (0, import_jsx_runtime13.jsxs)("div", { className: "w-64 grid grid-cols-[min-content,1fr] gap-2", children: [(0, import_jsx_runtime13.jsx)("div", { children: "URL:" }), (0, import_jsx_runtime13.jsx)("div", { className: "truncate", children: state.currentUrl }), (0, import_jsx_runtime13.jsx)("div", { children: "Enabled:" }), (0, import_jsx_runtime13.jsx)("div", { children: (0, import_jsx_runtime13.jsxs)("label", { className: "inline-flex items-center cursor-pointer", children: [(0, import_jsx_runtime13.jsx)("input", { type: "checkbox", checked: state.enabled, disabled: true, className: "sr-only peer" }), (0, import_jsx_runtime13.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" })] }) })] }) });
966
+ return (0, import_jsx_runtime14.jsx)("div", { id: `browser-overlay-${config.id}`, children: (0, import_jsx_runtime14.jsxs)("div", { className: "w-64 grid grid-cols-[min-content,1fr] gap-2", children: [(0, import_jsx_runtime14.jsx)("div", { children: "URL:" }), (0, import_jsx_runtime14.jsx)("div", { className: "truncate", children: state.currentUrl }), (0, import_jsx_runtime14.jsx)("div", { children: "Enabled:" }), (0, import_jsx_runtime14.jsx)("div", { children: (0, import_jsx_runtime14.jsxs)("label", { className: "inline-flex items-center cursor-pointer", children: [(0, import_jsx_runtime14.jsx)("input", { type: "checkbox", checked: state.enabled, disabled: true, className: "sr-only peer" }), (0, import_jsx_runtime14.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" })] }) })] }) });
936
967
  }
937
- var import_jsx_runtime13, inline_view_default7;
968
+ var import_jsx_runtime14, inline_view_default7;
938
969
  var init_inline_view7 = __esm({
939
970
  "build/processor.browserOverlay/inline-view.js"() {
940
971
  "use strict";
941
- import_jsx_runtime13 = __toESM(require_jsx_runtime());
972
+ import_jsx_runtime14 = __toESM(require_jsx_runtime());
942
973
  inline_view_default7 = InlineView9;
943
974
  }
944
975
  });
@@ -954,10 +985,10 @@ function OrderInput(props) {
954
985
  }, [props.defaultValue]);
955
986
  const [value, setValue] = (0, import_react15.useState)(props.defaultValue ?? []);
956
987
  if (value.length == 0) {
957
- return (0, import_jsx_runtime14.jsx)("p", { className: "node-editor-helper-text", children: "Sources will appear here when subscriptions have been added to this node" });
988
+ return (0, import_jsx_runtime15.jsx)("p", { className: "node-editor-helper-text", children: "Sources will appear here when subscriptions have been added to this node" });
958
989
  } else {
959
- return (0, import_jsx_runtime14.jsx)("div", { id: props.id, children: (0, import_jsx_runtime14.jsx)("ul", { children: value.map((v, ix) => {
960
- return (0, import_jsx_runtime14.jsxs)("li", { className: "flex", children: [(0, import_jsx_runtime14.jsx)("span", { className: "node-editor-label flex-grow", children: v }), ix == 0 ? (0, import_jsx_runtime14.jsx)(import_jsx_runtime14.Fragment, {}) : (0, import_jsx_runtime14.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_runtime14.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M8.25 6.75L12 3m0 0l3.75 3.75M12 3v18" }) }), ix == value.length - 1 ? (0, import_jsx_runtime14.jsx)(import_jsx_runtime14.Fragment, {}) : (0, import_jsx_runtime14.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_runtime14.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M15.75 17.25L12 21m0 0l-3.75-3.75M12 21V3" }) })] }, v);
990
+ return (0, import_jsx_runtime15.jsx)("div", { id: props.id, children: (0, import_jsx_runtime15.jsx)("ul", { children: value.map((v, ix) => {
991
+ return (0, import_jsx_runtime15.jsxs)("li", { className: "flex", children: [(0, import_jsx_runtime15.jsx)("span", { className: "node-editor-label flex-grow", children: v }), ix == 0 ? (0, import_jsx_runtime15.jsx)(import_jsx_runtime15.Fragment, {}) : (0, import_jsx_runtime15.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_runtime15.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M8.25 6.75L12 3m0 0l3.75 3.75M12 3v18" }) }), ix == value.length - 1 ? (0, import_jsx_runtime15.jsx)(import_jsx_runtime15.Fragment, {}) : (0, import_jsx_runtime15.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_runtime15.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M15.75 17.25L12 21m0 0l-3.75-3.75M12 21V3" }) })] }, v);
961
992
  }) }) });
962
993
  }
963
994
  function moveUp(ix) {
@@ -979,11 +1010,11 @@ function OrderInput(props) {
979
1010
  };
980
1011
  }
981
1012
  }
982
- var import_jsx_runtime14, import_react15, source_selection_default;
1013
+ var import_jsx_runtime15, import_react15, source_selection_default;
983
1014
  var init_source_selection = __esm({
984
1015
  "build/processor.cascadingSwitch/source-selection.js"() {
985
1016
  "use strict";
986
- import_jsx_runtime14 = __toESM(require_jsx_runtime());
1017
+ import_jsx_runtime15 = __toESM(require_jsx_runtime());
987
1018
  import_react15 = __toESM(require_react());
988
1019
  source_selection_default = OrderInput;
989
1020
  }
@@ -995,13 +1026,13 @@ __export(inline_view_exports8, {
995
1026
  default: () => inline_view_default8
996
1027
  });
997
1028
  function InlineView11({ state, config }) {
998
- return (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [(0, import_jsx_runtime15.jsx)("h5", { children: "Sources" }), (0, import_jsx_runtime15.jsxs)("ul", { children: [config.sources.map((s, i) => state.activeSource == s ? (0, import_jsx_runtime15.jsxs)("li", { className: activeClasses, children: [s, " <--"] }, i) : state.availableSources.includes(s) ? (0, import_jsx_runtime15.jsxs)("li", { className: availableClasses, children: [s, " (available)"] }, i) : (0, import_jsx_runtime15.jsxs)("li", { className: inactiveClasses, children: [s, " (inactive)"] }, i)), (0, import_jsx_runtime15.jsx)("li", { className: state.activeSource == "fallback" ? activeClasses : availableClasses, children: "fallback" }, "fallback")] })] });
1029
+ return (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [(0, import_jsx_runtime16.jsx)("h5", { children: "Sources" }), (0, import_jsx_runtime16.jsxs)("ul", { children: [config.sources.map((s, i) => state.activeSource == s ? (0, import_jsx_runtime16.jsxs)("li", { className: activeClasses, children: [s, " <--"] }, i) : state.availableSources.includes(s) ? (0, import_jsx_runtime16.jsxs)("li", { className: availableClasses, children: [s, " (available)"] }, i) : (0, import_jsx_runtime16.jsxs)("li", { className: inactiveClasses, children: [s, " (inactive)"] }, i)), (0, import_jsx_runtime16.jsx)("li", { className: state.activeSource == "fallback" ? activeClasses : availableClasses, children: "fallback" }, "fallback")] })] });
999
1030
  }
1000
- var import_jsx_runtime15, activeClasses, availableClasses, inactiveClasses, inline_view_default8;
1031
+ var import_jsx_runtime16, activeClasses, availableClasses, inactiveClasses, inline_view_default8;
1001
1032
  var init_inline_view8 = __esm({
1002
1033
  "build/processor.cascadingSwitch/inline-view.js"() {
1003
1034
  "use strict";
1004
- import_jsx_runtime15 = __toESM(require_jsx_runtime());
1035
+ import_jsx_runtime16 = __toESM(require_jsx_runtime());
1005
1036
  activeClasses = "active text-green-500 dark:text-green-300";
1006
1037
  availableClasses = "available text-green-500 dark:text-green-300";
1007
1038
  inactiveClasses = "inactive text-orange-500 dark:text-orange-300";
@@ -1015,13 +1046,13 @@ __export(rung_view_exports, {
1015
1046
  default: () => rung_view_default
1016
1047
  });
1017
1048
  function rung_view_default(rung) {
1018
- return (0, import_jsx_runtime16.jsx)("div", { className: "text-gray-900 dark:text-white", children: rung.name });
1049
+ return (0, import_jsx_runtime17.jsx)("div", { className: "text-gray-900 dark:text-white", children: rung.name });
1019
1050
  }
1020
- var import_jsx_runtime16;
1051
+ var import_jsx_runtime17;
1021
1052
  var init_rung_view = __esm({
1022
1053
  "build/processor.fixedLadder/rung-view.js"() {
1023
1054
  "use strict";
1024
- import_jsx_runtime16 = __toESM(require_jsx_runtime());
1055
+ import_jsx_runtime17 = __toESM(require_jsx_runtime());
1025
1056
  }
1026
1057
  });
1027
1058
 
@@ -1044,7 +1075,7 @@ function CodecEditor(props) {
1044
1075
  target.style.height = target.scrollHeight + "px";
1045
1076
  }
1046
1077
  }, []);
1047
- return (0, import_jsx_runtime17.jsx)("textarea", { ref: textAreaRef, className: "w-full min-h-fit bg-white text-gray-900 dark:text-white dark:bg-black", onChange: (e) => {
1078
+ return (0, import_jsx_runtime18.jsx)("textarea", { ref: textAreaRef, className: "w-full min-h-fit bg-white text-gray-900 dark:text-white dark:bg-black", onChange: (e) => {
1048
1079
  const target = e.currentTarget;
1049
1080
  try {
1050
1081
  const codec = JSON.parse(target.value);
@@ -1054,11 +1085,11 @@ function CodecEditor(props) {
1054
1085
  }
1055
1086
  }, defaultValue: JSON.stringify(value, void 0, 2) });
1056
1087
  }
1057
- var import_jsx_runtime17, import_react16;
1088
+ var import_jsx_runtime18, import_react16;
1058
1089
  var init_codec_editor = __esm({
1059
1090
  "build/processor.fixedLadder/codec-editor.js"() {
1060
1091
  "use strict";
1061
- import_jsx_runtime17 = __toESM(require_jsx_runtime());
1092
+ import_jsx_runtime18 = __toESM(require_jsx_runtime());
1062
1093
  import_react16 = __toESM(require_react());
1063
1094
  }
1064
1095
  });
@@ -1069,13 +1100,13 @@ __export(codec_view_exports, {
1069
1100
  default: () => CodecEditor2
1070
1101
  });
1071
1102
  function CodecEditor2(props) {
1072
- return (0, import_jsx_runtime18.jsxs)("div", { className: "text-gray-900 dark:text-white", children: [props.width, "x", props.height] });
1103
+ return (0, import_jsx_runtime19.jsxs)("div", { className: "text-gray-900 dark:text-white", children: [props.width, "x", props.height] });
1073
1104
  }
1074
- var import_jsx_runtime18;
1105
+ var import_jsx_runtime19;
1075
1106
  var init_codec_view = __esm({
1076
1107
  "build/processor.fixedLadder/codec-view.js"() {
1077
1108
  "use strict";
1078
- import_jsx_runtime18 = __toESM(require_jsx_runtime());
1109
+ import_jsx_runtime19 = __toESM(require_jsx_runtime());
1079
1110
  }
1080
1111
  });
1081
1112
 
@@ -1104,34 +1135,34 @@ function GraphicSelection(props) {
1104
1135
  }, []);
1105
1136
  const [graphcs, setGraphics] = (0, import_react18.useState)([]);
1106
1137
  if (loading) {
1107
- return (0, import_jsx_runtime19.jsx)("div", { children: "Loading.." });
1138
+ return (0, import_jsx_runtime20.jsx)("div", { children: "Loading.." });
1108
1139
  }
1109
1140
  if (graphcs.length == 0) {
1110
- return (0, import_jsx_runtime19.jsx)("div", { children: "No graphics loaded" });
1141
+ return (0, import_jsx_runtime20.jsx)("div", { children: "No graphics loaded" });
1111
1142
  }
1112
- return (0, import_jsx_runtime19.jsx)("div", { children: (0, import_jsx_runtime19.jsxs)("select", { defaultValue: props.defaultValue, className: `node-editor-select-input`, id: props.id, onChange: myOnChange, onBlur: myOnChange, children: [(0, import_jsx_runtime19.jsx)("option", { value: "", children: "---" }, "empty"), graphcs.map((o, i) => {
1113
- return (0, import_jsx_runtime19.jsx)("option", { value: o, children: o }, i);
1143
+ return (0, import_jsx_runtime20.jsx)("div", { children: (0, import_jsx_runtime20.jsxs)("select", { defaultValue: props.defaultValue, className: `node-editor-select-input`, id: props.id, onChange: myOnChange, onBlur: myOnChange, children: [(0, import_jsx_runtime20.jsx)("option", { value: "", children: "---" }, "empty"), graphcs.map((o, i) => {
1144
+ return (0, import_jsx_runtime20.jsx)("option", { value: o, children: o }, i);
1114
1145
  })] }) });
1115
1146
  function myOnChange(e) {
1116
1147
  props.onChanged(e.target.value);
1117
1148
  }
1118
1149
  }
1119
- var import_jsx_runtime19, import_react18, image_selection_default;
1150
+ var import_jsx_runtime20, import_react18, image_selection_default;
1120
1151
  var init_image_selection = __esm({
1121
1152
  "build/processor.onscreenGraphic/image-selection.js"() {
1122
1153
  "use strict";
1123
- import_jsx_runtime19 = __toESM(require_jsx_runtime());
1154
+ import_jsx_runtime20 = __toESM(require_jsx_runtime());
1124
1155
  import_react18 = __toESM(require_react());
1125
1156
  image_selection_default = GraphicSelection;
1126
1157
  }
1127
1158
  });
1128
1159
 
1129
1160
  // build/processor.onscreenGraphic/summary-view.js
1130
- var summary_view_exports4 = {};
1131
- __export(summary_view_exports4, {
1132
- default: () => summary_view_default4
1161
+ var summary_view_exports5 = {};
1162
+ __export(summary_view_exports5, {
1163
+ default: () => summary_view_default5
1133
1164
  });
1134
- function SummaryView7({ state, sendCommand, urls }) {
1165
+ function SummaryView9({ state, sendCommand, urls }) {
1135
1166
  const [graphic, setGraphic] = (0, import_react19.useState)(state.activeGraphic?.file);
1136
1167
  const [position, setPosition] = (0, import_react19.useState)(state.activeGraphic?.position ?? { type: "named", position: "topleft" });
1137
1168
  const [graphics, setGraphics] = (0, import_react19.useState)([]);
@@ -1266,7 +1297,7 @@ function SummaryView7({ state, sendCommand, urls }) {
1266
1297
  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";
1267
1298
  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";
1268
1299
  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";
1269
- return (0, import_jsx_runtime20.jsxs)("div", { className: "space-y-3", children: [(0, import_jsx_runtime20.jsx)("h2", { className: "text-xl font-bold text-gray-900 dark:text-white", children: "Controls" }), (0, import_jsx_runtime20.jsxs)("div", { children: [(0, import_jsx_runtime20.jsx)("label", { htmlFor: "select-graphic", className: "block text-gray-900 dark:text-white mb-1", children: "Source" }), (0, import_jsx_runtime20.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_runtime20.jsx)("option", { value: "", children: "---" }), graphics.map((s) => (0, import_jsx_runtime20.jsx)("option", { value: s, children: s }, s))] })] }), graphic && (0, import_jsx_runtime20.jsxs)("div", { children: [(0, import_jsx_runtime20.jsx)("label", { htmlFor: "select-position", className: "block text-gray-900 dark:text-white mb-1", children: "Graphic position" }), (0, import_jsx_runtime20.jsx)(PositionSelector, { initialPosition: position, onChange: setPosition, graphicChanged, ...state })] }), (0, import_jsx_runtime20.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_runtime20.jsx)("button", { type: "button", className: buttonClass, onClick: () => setShowFileInput(true), style: { marginBottom: "1rem" }, children: "Upload Graphic" }), showFileInput && (0, import_jsx_runtime20.jsxs)("form", { style: { display: "block", marginBottom: "1rem" }, children: [(0, import_jsx_runtime20.jsx)("input", { type: "file", id: "file", name: "filename", onChange: onFileChange, className: fileInputClass }), showUploadButton && (0, import_jsx_runtime20.jsx)("button", { type: "button", className: buttonClass, onClick: uploadFile, children: "Upload" })] }), (0, import_jsx_runtime20.jsx)("button", { type: "button", className: deleteButtonClass, onClick: () => setShowDeleteDropdown(!showDeleteDropdown), style: { marginBottom: "1rem" }, children: showDeleteDropdown ? "Hide Delete Options" : "Delete Graphics" }), showDeleteDropdown && (0, import_jsx_runtime20.jsxs)("div", { className: "mt-2 p-2 bg-gray-100 dark:bg-gray-800 rounded-lg", children: [(0, import_jsx_runtime20.jsx)("h3", { className: "text-lg font-semibold mb-2 text-gray-900 dark:text-white", children: "Select Graphic to Delete" }), (0, import_jsx_runtime20.jsxs)("select", { className: "w-full mb-2 node-editor-select-input", value: graphicToDelete, onChange: (e) => setGraphicToDelete(e.target.value), children: [(0, import_jsx_runtime20.jsx)("option", { value: "", children: " Select a graphic" }), graphics.map((graphicName) => (0, import_jsx_runtime20.jsx)("option", { value: graphicName, children: graphicName }, graphicName))] }), (0, import_jsx_runtime20.jsx)("button", { onClick: deleteBug, disabled: !graphicToDelete, className: `${deleteButtonClass} ${!graphicToDelete ? "opacity-50 cursor-not-allowed" : ""}`, children: "Delete Selected Graphic" })] }), uploadStatus.message && (0, import_jsx_runtime20.jsx)("div", { className: `mt-2 text-center ${uploadStatus.success ? "text-green-600" : "text-red-600"}`, children: uploadStatus.message })] });
1300
+ return (0, import_jsx_runtime21.jsxs)("div", { className: "space-y-3", children: [(0, import_jsx_runtime21.jsx)("h2", { className: "text-xl font-bold text-gray-900 dark:text-white", children: "Controls" }), (0, import_jsx_runtime21.jsxs)("div", { children: [(0, import_jsx_runtime21.jsx)("label", { htmlFor: "select-graphic", className: "block text-gray-900 dark:text-white mb-1", children: "Source" }), (0, import_jsx_runtime21.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_runtime21.jsx)("option", { value: "", children: "---" }), graphics.map((s) => (0, import_jsx_runtime21.jsx)("option", { value: s, children: s }, s))] })] }), graphic && (0, import_jsx_runtime21.jsxs)("div", { children: [(0, import_jsx_runtime21.jsx)("label", { htmlFor: "select-position", className: "block text-gray-900 dark:text-white mb-1", children: "Graphic position" }), (0, import_jsx_runtime21.jsx)(PositionSelector, { initialPosition: position, onChange: setPosition, graphicChanged, ...state })] }), (0, import_jsx_runtime21.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_runtime21.jsx)("button", { type: "button", className: buttonClass, onClick: () => setShowFileInput(true), style: { marginBottom: "1rem" }, children: "Upload Graphic" }), showFileInput && (0, import_jsx_runtime21.jsxs)("form", { style: { display: "block", marginBottom: "1rem" }, children: [(0, import_jsx_runtime21.jsx)("input", { type: "file", id: "file", name: "filename", onChange: onFileChange, className: fileInputClass }), showUploadButton && (0, import_jsx_runtime21.jsx)("button", { type: "button", className: buttonClass, onClick: uploadFile, children: "Upload" })] }), (0, import_jsx_runtime21.jsx)("button", { type: "button", className: deleteButtonClass, onClick: () => setShowDeleteDropdown(!showDeleteDropdown), style: { marginBottom: "1rem" }, children: showDeleteDropdown ? "Hide Delete Options" : "Delete Graphics" }), showDeleteDropdown && (0, import_jsx_runtime21.jsxs)("div", { className: "mt-2 p-2 bg-gray-100 dark:bg-gray-800 rounded-lg", children: [(0, import_jsx_runtime21.jsx)("h3", { className: "text-lg font-semibold mb-2 text-gray-900 dark:text-white", children: "Select Graphic to Delete" }), (0, import_jsx_runtime21.jsxs)("select", { className: "w-full mb-2 node-editor-select-input", value: graphicToDelete, onChange: (e) => setGraphicToDelete(e.target.value), children: [(0, import_jsx_runtime21.jsx)("option", { value: "", children: " Select a graphic" }), graphics.map((graphicName) => (0, import_jsx_runtime21.jsx)("option", { value: graphicName, children: graphicName }, graphicName))] }), (0, import_jsx_runtime21.jsx)("button", { onClick: deleteBug, disabled: !graphicToDelete, className: `${deleteButtonClass} ${!graphicToDelete ? "opacity-50 cursor-not-allowed" : ""}`, children: "Delete Selected Graphic" })] }), uploadStatus.message && (0, import_jsx_runtime21.jsx)("div", { className: `mt-2 text-center ${uploadStatus.success ? "text-green-600" : "text-red-600"}`, children: uploadStatus.message })] });
1270
1301
  }
1271
1302
  function convertPosition(givenPosition, currentVideo, currentGraphic) {
1272
1303
  if (!givenPosition)
@@ -1312,11 +1343,11 @@ function clamp(min, num, max) {
1312
1343
  function assertUnreachable12(_) {
1313
1344
  throw new Error("Didn't expect to get here");
1314
1345
  }
1315
- var import_jsx_runtime20, import_react19, PositionSelector, summary_view_default4;
1316
- var init_summary_view4 = __esm({
1346
+ var import_jsx_runtime21, import_react19, PositionSelector, summary_view_default5;
1347
+ var init_summary_view5 = __esm({
1317
1348
  "build/processor.onscreenGraphic/summary-view.js"() {
1318
1349
  "use strict";
1319
- import_jsx_runtime20 = __toESM(require_jsx_runtime());
1350
+ import_jsx_runtime21 = __toESM(require_jsx_runtime());
1320
1351
  import_react19 = __toESM(require_react());
1321
1352
  PositionSelector = ({ initialPosition: givenPosition = { type: "named", position: "topleft" }, onChange, currentVideo, currentGraphic, graphicChanged }) => {
1322
1353
  const convertPos = (pos) => convertPosition(pos, currentVideo, currentGraphic);
@@ -1384,7 +1415,7 @@ var init_summary_view4 = __esm({
1384
1415
  window.removeEventListener("mouseup", handleMouseUp);
1385
1416
  };
1386
1417
  }, [isDragging]);
1387
- return (0, import_jsx_runtime20.jsxs)("div", { className: "relative w-full max-w-lg mx-auto mt-4 mb-8", children: [(0, import_jsx_runtime20.jsxs)("div", { className: "mb-4 flex items-center gap-2", children: [(0, import_jsx_runtime20.jsx)("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300", children: "Position Type:" }), (0, import_jsx_runtime20.jsxs)("select", { value: position.type, onChange: (e) => {
1418
+ return (0, import_jsx_runtime21.jsxs)("div", { className: "relative w-full max-w-lg mx-auto mt-4 mb-8", children: [(0, import_jsx_runtime21.jsxs)("div", { className: "mb-4 flex items-center gap-2", children: [(0, import_jsx_runtime21.jsx)("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300", children: "Position Type:" }), (0, import_jsx_runtime21.jsxs)("select", { value: position.type, onChange: (e) => {
1388
1419
  const newType = e.target.value;
1389
1420
  if (newType === "named") {
1390
1421
  setPosition(convertPos({ type: "named", position: "topleft" }));
@@ -1392,12 +1423,12 @@ var init_summary_view4 = __esm({
1392
1423
  setPositionUnit("%");
1393
1424
  setPosition({ ...convertPos(position), type: "percentage" });
1394
1425
  }
1395
- }, className: "node-editor-select-input", children: [(0, import_jsx_runtime20.jsx)("option", { value: "coordinate", children: "Custom Position" }), (0, import_jsx_runtime20.jsx)("option", { value: "named", children: "Preset Position" })] })] }), position.type === "named" ? (0, import_jsx_runtime20.jsx)("div", { className: "mb-4", children: (0, import_jsx_runtime20.jsxs)("select", { value: position.position, onChange: (e) => {
1426
+ }, className: "node-editor-select-input", children: [(0, import_jsx_runtime21.jsx)("option", { value: "coordinate", children: "Custom Position" }), (0, import_jsx_runtime21.jsx)("option", { value: "named", children: "Preset Position" })] })] }), position.type === "named" ? (0, import_jsx_runtime21.jsx)("div", { className: "mb-4", children: (0, import_jsx_runtime21.jsxs)("select", { value: position.position, onChange: (e) => {
1396
1427
  setPosition(convertPos({
1397
1428
  type: "named",
1398
1429
  position: e.target.value
1399
1430
  }));
1400
- }, className: "w-full node-editor-select-input", children: [(0, import_jsx_runtime20.jsx)("option", { value: "topleft", children: "Top Left" }), (0, import_jsx_runtime20.jsx)("option", { value: "topright", children: "Top Right" }), (0, import_jsx_runtime20.jsx)("option", { value: "bottomleft", children: "Bottom Left" }), (0, import_jsx_runtime20.jsx)("option", { value: "bottomright", children: "Bottom Right" }), (0, import_jsx_runtime20.jsx)("option", { value: "center", children: "Centered" })] }) }) : (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [(0, import_jsx_runtime20.jsxs)("div", { className: "mb-4 flex items-center gap-2", children: [(0, import_jsx_runtime20.jsx)("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300", children: "Position Unit:" }), (0, import_jsx_runtime20.jsxs)("select", { value: positionUnit, onChange: (e) => {
1431
+ }, className: "w-full node-editor-select-input", children: [(0, import_jsx_runtime21.jsx)("option", { value: "topleft", children: "Top Left" }), (0, import_jsx_runtime21.jsx)("option", { value: "topright", children: "Top Right" }), (0, import_jsx_runtime21.jsx)("option", { value: "bottomleft", children: "Bottom Left" }), (0, import_jsx_runtime21.jsx)("option", { value: "bottomright", children: "Bottom Right" }), (0, import_jsx_runtime21.jsx)("option", { value: "center", children: "Centered" })] }) }) : (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [(0, import_jsx_runtime21.jsxs)("div", { className: "mb-4 flex items-center gap-2", children: [(0, import_jsx_runtime21.jsx)("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300", children: "Position Unit:" }), (0, import_jsx_runtime21.jsxs)("select", { value: positionUnit, onChange: (e) => {
1401
1432
  setPositionUnit(e.target.value);
1402
1433
  if (e.target.value === "px" && position.type !== "coordinate" && currentVideo && currentGraphic) {
1403
1434
  const { width: videoWidth, height: videoHeight } = currentVideo;
@@ -1422,18 +1453,18 @@ var init_summary_view4 = __esm({
1422
1453
  yStr: void 0
1423
1454
  });
1424
1455
  }
1425
- }, className: "node-editor-select-input", children: [(0, import_jsx_runtime20.jsx)("option", { value: "px", children: "Pixels" }), (0, import_jsx_runtime20.jsx)("option", { value: "%", children: "Percentage" })] })] }), (0, import_jsx_runtime20.jsxs)("div", { className: "relative bg-gray-200 dark:bg-gray-700 rounded-lg", style: {
1456
+ }, className: "node-editor-select-input", children: [(0, import_jsx_runtime21.jsx)("option", { value: "px", children: "Pixels" }), (0, import_jsx_runtime21.jsx)("option", { value: "%", children: "Percentage" })] })] }), (0, import_jsx_runtime21.jsxs)("div", { className: "relative bg-gray-200 dark:bg-gray-700 rounded-lg", style: {
1426
1457
  width: "100%",
1427
1458
  userSelect: "none",
1428
1459
  aspectRatio: currentVideo ? `${currentVideo.width} / ${currentVideo.height}` : `3 / 2`
1429
- }, ref: previewAreaRef, children: [(0, import_jsx_runtime20.jsxs)("div", { className: "absolute inset-0 flex flex-col items-center justify-center text-gray-500 dark:text-gray-400", children: [(0, import_jsx_runtime20.jsx)("span", { children: currentVideo ? "Video Preview Area" : "Video Dimensions Unknown" }), " ", currentVideo ? (0, import_jsx_runtime20.jsxs)("span", { children: [currentVideo.width, "x", currentVideo.height, "px"] }) : ""] }), (0, import_jsx_runtime20.jsx)("div", { className: `absolute cursor-move ${currentGraphic && !graphicChanged ? "" : "p-2"} rounded-lg bg-primary-500 bg-opacity-50 hover:bg-opacity-75 transition-colors
1460
+ }, ref: previewAreaRef, children: [(0, import_jsx_runtime21.jsxs)("div", { className: "absolute inset-0 flex flex-col items-center justify-center text-gray-500 dark:text-gray-400", children: [(0, import_jsx_runtime21.jsx)("span", { children: currentVideo ? "Video Preview Area" : "Video Dimensions Unknown" }), " ", currentVideo ? (0, import_jsx_runtime21.jsxs)("span", { children: [currentVideo.width, "x", currentVideo.height, "px"] }) : ""] }), (0, import_jsx_runtime21.jsx)("div", { className: `absolute cursor-move ${currentGraphic && !graphicChanged ? "" : "p-2"} rounded-lg bg-primary-500 bg-opacity-50 hover:bg-opacity-75 transition-colors
1430
1461
  ${isDragging ? "bg-opacity-75" : ""}`, style: {
1431
1462
  left: `${position.xPct}%`,
1432
1463
  top: `${position.yPct}%`,
1433
1464
  transform: `translate(-${position.xPct}%, -${position.yPct}%)`,
1434
1465
  aspectRatio: currentGraphic && !graphicChanged ? `${currentGraphic.width} / ${currentGraphic.height}` : `1`,
1435
1466
  width: currentGraphic && currentVideo && !graphicChanged ? currentGraphic.width / currentVideo.width * 100 + "%" : void 0
1436
- }, onMouseDown: handleMouseDown, ref: previewTargetRef, children: (0, import_jsx_runtime20.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_runtime20.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_runtime20.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_runtime20.jsxs)("div", { className: "mt-2 flex gap-4", children: [(0, import_jsx_runtime20.jsxs)("div", { children: [(0, import_jsx_runtime20.jsxs)("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300", children: ["X Position ", positionUnit] }), (0, import_jsx_runtime20.jsx)("input", { type: "number", step: positionUnit === "%" ? "0.1" : "1", value: position.xStr ?? (positionUnit === "%" ? position.xPct.toFixed(1) : Math.round(position.x)), onChange: (e) => {
1467
+ }, onMouseDown: handleMouseDown, ref: previewTargetRef, children: (0, import_jsx_runtime21.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_runtime21.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_runtime21.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_runtime21.jsxs)("div", { className: "mt-2 flex gap-4", children: [(0, import_jsx_runtime21.jsxs)("div", { children: [(0, import_jsx_runtime21.jsxs)("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300", children: ["X Position ", positionUnit] }), (0, import_jsx_runtime21.jsx)("input", { type: "number", step: positionUnit === "%" ? "0.1" : "1", value: position.xStr ?? (positionUnit === "%" ? position.xPct.toFixed(1) : Math.round(position.x)), onChange: (e) => {
1437
1468
  const newX = Number(e.target.value);
1438
1469
  setPosition(convertPos({
1439
1470
  type: positionUnit === "%" ? "percentage" : "coordinate",
@@ -1442,7 +1473,7 @@ var init_summary_view4 = __esm({
1442
1473
  y: position.y,
1443
1474
  yStr: position.yStr
1444
1475
  }));
1445
- }, 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_runtime20.jsxs)("div", { children: [(0, import_jsx_runtime20.jsxs)("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300", children: ["Y Position ", positionUnit] }), (0, import_jsx_runtime20.jsx)("input", { type: "number", step: positionUnit === "%" ? "0.1" : "1", value: position.yStr ?? (positionUnit === "%" ? position.yPct.toFixed(1) : Math.round(position.y)), onChange: (e) => {
1476
+ }, 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_runtime21.jsxs)("div", { children: [(0, import_jsx_runtime21.jsxs)("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300", children: ["Y Position ", positionUnit] }), (0, import_jsx_runtime21.jsx)("input", { type: "number", step: positionUnit === "%" ? "0.1" : "1", value: position.yStr ?? (positionUnit === "%" ? position.yPct.toFixed(1) : Math.round(position.y)), onChange: (e) => {
1446
1477
  const newY = Number(e.target.value);
1447
1478
  setPosition(convertPos({
1448
1479
  type: positionUnit === "%" ? "percentage" : "coordinate",
@@ -1453,7 +1484,7 @@ var init_summary_view4 = __esm({
1453
1484
  }));
1454
1485
  }, 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" })] })] })] })] });
1455
1486
  };
1456
- summary_view_default4 = SummaryView7;
1487
+ summary_view_default5 = SummaryView9;
1457
1488
  }
1458
1489
  });
1459
1490
 
@@ -15842,13 +15873,13 @@ function InlineView12({ state, config: _2 }) {
15842
15873
  return;
15843
15874
  chartControl.data = makeData(state);
15844
15875
  }, [state]);
15845
- return (0, import_jsx_runtime21.jsx)("div", { className: "bg-gray-50 dark:bg-gray-700 rounded", style: { width: "360px", height: "200px", padding: "10px" }, children: (0, import_jsx_runtime21.jsx)("canvas", { className: "bg-gray-50 dark:bg-gray-700 rounded", ref: chartContainer }) });
15876
+ return (0, import_jsx_runtime22.jsx)("div", { className: "bg-gray-50 dark:bg-gray-700 rounded", style: { width: "360px", height: "200px", padding: "10px" }, children: (0, import_jsx_runtime22.jsx)("canvas", { className: "bg-gray-50 dark:bg-gray-700 rounded", ref: chartContainer }) });
15846
15877
  }
15847
- var import_jsx_runtime21, import_react21, inline_view_default9;
15878
+ var import_jsx_runtime22, import_react21, inline_view_default9;
15848
15879
  var init_inline_view9 = __esm({
15849
15880
  "build/util.stats.latency/inline-view.js"() {
15850
15881
  "use strict";
15851
- import_jsx_runtime21 = __toESM(require_jsx_runtime());
15882
+ import_jsx_runtime22 = __toESM(require_jsx_runtime());
15852
15883
  import_react21 = __toESM(require_react());
15853
15884
  init_auto();
15854
15885
  inline_view_default9 = InlineView12;
@@ -15861,22 +15892,22 @@ __export(source_node_selection_exports, {
15861
15892
  default: () => source_node_selection_default
15862
15893
  });
15863
15894
  function SourceNodeSelection(props) {
15864
- return (0, import_jsx_runtime22.jsx)("div", { children: (0, import_jsx_runtime22.jsxs)("select", { defaultValue: props.defaultValue, className: `node-editor-select-input`, id: props.id, onChange: myOnChange, onBlur: myOnChange, children: [(0, import_jsx_runtime22.jsx)("option", { value: "", children: "---" }, "empty"), Object.values(props.latestDocument.components).map((o, i) => {
15895
+ return (0, import_jsx_runtime23.jsx)("div", { children: (0, import_jsx_runtime23.jsxs)("select", { defaultValue: props.defaultValue, className: `node-editor-select-input`, id: props.id, onChange: myOnChange, onBlur: myOnChange, children: [(0, import_jsx_runtime23.jsx)("option", { value: "", children: "---" }, "empty"), Object.values(props.latestDocument.components).map((o, i) => {
15865
15896
  if (o.id == props.id)
15866
- return (0, import_jsx_runtime22.jsx)(import_jsx_runtime22.Fragment, {});
15897
+ return (0, import_jsx_runtime23.jsx)(import_jsx_runtime23.Fragment, {});
15867
15898
  if (o.info.category === "output")
15868
15899
  return;
15869
- return (0, import_jsx_runtime22.jsx)("option", { value: o.id, children: o.config.displayName }, i);
15900
+ return (0, import_jsx_runtime23.jsx)("option", { value: o.id, children: o.config.displayName }, i);
15870
15901
  })] }) });
15871
15902
  function myOnChange(e) {
15872
15903
  props.onChanged(e.target.value);
15873
15904
  }
15874
15905
  }
15875
- var import_jsx_runtime22, source_node_selection_default;
15906
+ var import_jsx_runtime23, source_node_selection_default;
15876
15907
  var init_source_node_selection = __esm({
15877
15908
  "build/util.stats.latency/source-node-selection.js"() {
15878
15909
  "use strict";
15879
- import_jsx_runtime22 = __toESM(require_jsx_runtime());
15910
+ import_jsx_runtime23 = __toESM(require_jsx_runtime());
15880
15911
  source_node_selection_default = SourceNodeSelection;
15881
15912
  }
15882
15913
  });
@@ -15941,6 +15972,13 @@ function info_default({ defineComponent, Av, validation: { Z, Port, SourceName,
15941
15972
  },
15942
15973
  configForm: {
15943
15974
  form: {
15975
+ notes: {
15976
+ help: "Notes about this component",
15977
+ hint: {
15978
+ type: "text",
15979
+ optional: true
15980
+ }
15981
+ },
15944
15982
  port: { help: "The port this RTMP input will listen on", hint: { type: "numeric", validation: Port, defaultValue: defaultPort, global: unique("port") } },
15945
15983
  ssl: { help: "Optional: SSL", hint: { type: "boolean", optional: true } },
15946
15984
  appName: { help: "Name of the app", hint: { type: "text", validation: Z.string().min(1), defaultValue: "norsk" } },
@@ -15982,6 +16020,13 @@ function info_default2({ defineComponent, Audio }) {
15982
16020
  },
15983
16021
  configForm: {
15984
16022
  form: {
16023
+ notes: {
16024
+ help: "Notes about this component",
16025
+ hint: {
16026
+ type: "text",
16027
+ optional: true
16028
+ }
16029
+ },
15985
16030
  sampleRate: {
15986
16031
  help: "Samplerate in Hz of the generated audio",
15987
16032
  hint: {
@@ -16082,6 +16127,13 @@ function info_default3({ defineComponent, Av, validation }) {
16082
16127
  },
16083
16128
  configForm: {
16084
16129
  form: {
16130
+ notes: {
16131
+ help: "Notes about this component",
16132
+ hint: {
16133
+ type: "text",
16134
+ optional: true
16135
+ }
16136
+ },
16085
16137
  port: { help: "The port this SRT input will connect to", hint: { type: "numeric", validation: Port, defaultValue: 5001 } },
16086
16138
  host: { help: "The IP address/hostname this SRT input will connect to", hint: { type: "text", validation: Hostname, defaultValue: "0.0.0.0" } },
16087
16139
  sourceName: { help: "Source name to identify this by", hint: { type: "text", validation: SourceName, defaultValue: "camera1" } },
@@ -16165,6 +16217,13 @@ function info_default4({ defineComponent, Av, validation }) {
16165
16217
  },
16166
16218
  configForm: {
16167
16219
  form: {
16220
+ notes: {
16221
+ help: "Notes about this component",
16222
+ hint: {
16223
+ type: "text",
16224
+ optional: true
16225
+ }
16226
+ },
16168
16227
  port: {
16169
16228
  help: "The port this SRT input will listen on",
16170
16229
  hint: {
@@ -16251,6 +16310,7 @@ function info_default5({ defineComponent, Av, validation: { Z, Port, Hostname, S
16251
16310
  },
16252
16311
  configForm: {
16253
16312
  form: {
16313
+ notes: { help: "Notes about this component", hint: { type: "text", optional: true } },
16254
16314
  port: { help: "The receiving port", hint: { type: "numeric", validation: Port, defaultValue: 5001, global: unique("port") } },
16255
16315
  host: { help: "The receiving IP address/hostname", hint: { type: "text", validation: Hostname, defaultValue: "127.0.0.1" } },
16256
16316
  sourceName: { help: "Source name to identify this by", hint: { type: "text", validation: SourceName, defaultValue: "udp-ts", global: unique("sourceName") } },
@@ -16285,6 +16345,13 @@ function info_default6({ defineComponent, Video, validation: { SourceName, uniqu
16285
16345
  },
16286
16346
  configForm: {
16287
16347
  form: {
16348
+ notes: {
16349
+ help: "Notes about this component",
16350
+ hint: {
16351
+ type: "text",
16352
+ optional: true
16353
+ }
16354
+ },
16288
16355
  resolution: {
16289
16356
  help: "The resolution of the test card stream",
16290
16357
  hint: { type: "select", options: Resolutions, defaultValue: { width: 1280, height: 720 } }
@@ -16418,6 +16485,13 @@ function info_default7(R) {
16418
16485
  validation: Z.string().min(5).max(15)
16419
16486
  }
16420
16487
  },
16488
+ notes: {
16489
+ help: "Notes about this component",
16490
+ hint: {
16491
+ type: "text",
16492
+ optional: true
16493
+ }
16494
+ },
16421
16495
  sessionId: {
16422
16496
  help: "Generate a unique session id per run to avoid cache collisions",
16423
16497
  hint: {
@@ -16611,6 +16685,13 @@ function info_default8(R) {
16611
16685
  hardware: (0, import_config2.HardwareSelection)()
16612
16686
  },
16613
16687
  form: {
16688
+ notes: {
16689
+ help: "Notes about this component",
16690
+ hint: {
16691
+ type: "text",
16692
+ optional: true
16693
+ }
16694
+ },
16614
16695
  bufferDelayMs: { help: "How many milliseconds in the jitter buffer", hint: { type: "numeric", validation: JitterBuffer, defaultValue: 500 } },
16615
16696
  skipTranscode: { help: "Skip transcoding for WebRTC-ready streams", hint: { type: "boolean", defaultValue: false } },
16616
16697
  showPreview: { help: "Show video preview", hint: { type: "boolean", defaultValue: true } }
@@ -16668,6 +16749,7 @@ function info_default9({ defineComponent, Av, validation: { Z, JitterBuffer } })
16668
16749
  },
16669
16750
  configForm: {
16670
16751
  form: {
16752
+ notes: { help: "Notes about this component", hint: { type: "text", optional: true } },
16671
16753
  url: { help: "The URL of the remote RTMP server to connect to, including the full stream path and credentials", hint: { type: "text", validation: Z.string().min(5) } },
16672
16754
  bufferDelayMs: { help: "How many milliseconds in the jitter buffer", hint: { type: "numeric", validation: JitterBuffer, defaultValue: 500 } },
16673
16755
  avDelayMs: { help: "How many milliseconds to delay A/V to account for subtitles", hint: { type: "numeric", validation: JitterBuffer, defaultValue: 50 } },
@@ -16732,6 +16814,7 @@ function info_default10(registration) {
16732
16814
  },
16733
16815
  configForm: {
16734
16816
  form: {
16817
+ notes: { help: "Notes about this component", hint: { type: "text", optional: true } },
16735
16818
  port: {
16736
16819
  help: "The port this SRT output will connect to or listen on",
16737
16820
  hint: {
@@ -16808,6 +16891,7 @@ function info_default12({ defineComponent, All, validation: { Port, Hostname, Ji
16808
16891
  },
16809
16892
  configForm: {
16810
16893
  form: {
16894
+ notes: { help: "Notes about this component", hint: { type: "text", optional: true } },
16811
16895
  port: { help: "The port this UDP TS output will send to", hint: { type: "numeric", validation: Port, defaultValue: 8001 } },
16812
16896
  destinationHost: { help: "The IP address/Hostname this UDP TS output will send to", hint: { type: "text", validation: Hostname, defaultValue: "127.0.0.1" } },
16813
16897
  bufferDelayMs: { help: "How many milliseconds in the jitter buffer", hint: { type: "numeric", validation: JitterBuffer, defaultValue: 500 } },
@@ -16820,6 +16904,7 @@ function info_default12({ defineComponent, All, validation: { Port, Hostname, Ji
16820
16904
  // build/output.whep/info.js
16821
16905
  var import_config3 = __toESM(require_config());
16822
16906
  var import_react12 = __toESM(require_react());
16907
+ var SummaryView6 = import_react12.default.lazy(async () => Promise.resolve().then(() => (init_summary_view3(), summary_view_exports3)));
16823
16908
  function info_default13(R) {
16824
16909
  const { defineComponent, Av, validation: { JitterBuffer } } = R;
16825
16910
  const InlineView13 = import_react12.default.lazy(async () => Promise.resolve().then(() => (init_inline_view6(), inline_view_exports6)));
@@ -16844,25 +16929,33 @@ function info_default13(R) {
16844
16929
  },
16845
16930
  css: ["styles.css"],
16846
16931
  runtime: {
16847
- initialState: () => ({}),
16932
+ initialState: () => ({ enabled: true }),
16848
16933
  handleEvent(ev, state) {
16849
16934
  const evType = ev.type;
16850
16935
  switch (evType) {
16851
16936
  case "url-published":
16852
16937
  state.url = ev.url;
16853
16938
  break;
16939
+ case "output-enabled":
16940
+ state.enabled = true;
16941
+ break;
16942
+ case "output-disabled":
16943
+ state.enabled = false;
16944
+ break;
16854
16945
  default:
16855
16946
  assertUnreachable8(evType);
16856
16947
  }
16857
16948
  return { ...state };
16858
16949
  },
16859
- inline: InlineView13
16950
+ inline: InlineView13,
16951
+ summary: SummaryView6
16860
16952
  },
16861
16953
  configForm: {
16862
16954
  global: {
16863
16955
  iceServers: (0, import_config3.GlobalIceServers)(R)
16864
16956
  },
16865
16957
  form: {
16958
+ notes: { help: "Notes about this component", hint: { type: "text", optional: true } },
16866
16959
  bufferDelayMs: { help: "How many milliseconds in the jitter buffer", hint: { type: "numeric", validation: JitterBuffer, defaultValue: 500 } },
16867
16960
  showPreview: { help: "Show video preview", hint: { type: "boolean", defaultValue: true } }
16868
16961
  }
@@ -16876,7 +16969,7 @@ function assertUnreachable8(_) {
16876
16969
  // build/processor.browserOverlay/info.js
16877
16970
  var import_config4 = __toESM(require_config());
16878
16971
  var import_react14 = __toESM(require_react());
16879
- var SummaryView6 = import_react14.default.lazy(async () => Promise.resolve().then(() => (init_summary_view3(), summary_view_exports3)));
16972
+ var SummaryView8 = import_react14.default.lazy(async () => Promise.resolve().then(() => (init_summary_view4(), summary_view_exports4)));
16880
16973
  var InlineView10 = import_react14.default.lazy(async () => Promise.resolve().then(() => (init_inline_view7(), inline_view_exports7)));
16881
16974
  function info_default14({ defineComponent, Video, validation: { Z } }) {
16882
16975
  return defineComponent({
@@ -16904,7 +16997,7 @@ function info_default14({ defineComponent, Video, validation: { Z } }) {
16904
16997
  };
16905
16998
  },
16906
16999
  runtime: {
16907
- summary: SummaryView6,
17000
+ summary: SummaryView8,
16908
17001
  inline: InlineView10,
16909
17002
  initialState: () => ({
16910
17003
  currentUrl: "",
@@ -16929,7 +17022,8 @@ function info_default14({ defineComponent, Video, validation: { Z } }) {
16929
17022
  hardware: (0, import_config4.HardwareSelection)()
16930
17023
  },
16931
17024
  form: {
16932
- url: { help: "URL to render on top of the video", hint: { type: "text", validation: Z.string().url(), defaultValue: "" } }
17025
+ url: { help: "URL to render on top of the video", hint: { type: "text", validation: Z.string().url(), defaultValue: "" } },
17026
+ notes: { help: "Notes about this component", hint: { type: "text", optional: true } }
16933
17027
  }
16934
17028
  }
16935
17029
  });
@@ -17066,7 +17160,8 @@ function info_default15({ defineComponent, Av, React: React14, common: { Resolut
17066
17160
  component: SourceSelection,
17067
17161
  defaultValue: []
17068
17162
  }
17069
- }
17163
+ },
17164
+ notes: { help: "Notes about this component", hint: { type: "text", optional: true } }
17070
17165
  }
17071
17166
  }
17072
17167
  });
@@ -17189,7 +17284,8 @@ function info_default16({ defineComponent, Video }) {
17189
17284
  };
17190
17285
  })
17191
17286
  }
17192
- }
17287
+ },
17288
+ notes: { help: "Notes about this component", hint: { type: "text", optional: true } }
17193
17289
  }
17194
17290
  }
17195
17291
  });
@@ -17408,7 +17504,7 @@ var import_config6 = __toESM(require_config());
17408
17504
  var import_react20 = __toESM(require_react());
17409
17505
  function info_default17({ defineComponent, Video }) {
17410
17506
  const GraphicSelection2 = import_react20.default.lazy(async () => Promise.resolve().then(() => (init_image_selection(), image_selection_exports)));
17411
- const SummaryView8 = import_react20.default.lazy(async () => Promise.resolve().then(() => (init_summary_view4(), summary_view_exports4)));
17507
+ const SummaryView10 = import_react20.default.lazy(async () => Promise.resolve().then(() => (init_summary_view5(), summary_view_exports5)));
17412
17508
  return defineComponent({
17413
17509
  identifier: "processor.onscreenGraphic",
17414
17510
  category: "processor",
@@ -17434,7 +17530,7 @@ function info_default17({ defineComponent, Video }) {
17434
17530
  };
17435
17531
  },
17436
17532
  runtime: {
17437
- summary: SummaryView8,
17533
+ summary: SummaryView10,
17438
17534
  initialState: () => ({}),
17439
17535
  handleEvent: (ev, state) => {
17440
17536
  const evType = ev.type;
@@ -17476,7 +17572,8 @@ function info_default17({ defineComponent, Video }) {
17476
17572
  { value: { type: "named", position: "center" }, display: "Centered" }
17477
17573
  ]
17478
17574
  }
17479
- }
17575
+ },
17576
+ notes: { help: "Notes about this component", hint: { type: "text", optional: true } }
17480
17577
  }
17481
17578
  }
17482
17579
  });
@@ -17624,7 +17721,8 @@ function info_default18({ defineComponent, All, validation: { Z } }) {
17624
17721
  type: "text",
17625
17722
  optional: true
17626
17723
  }
17627
- }
17724
+ },
17725
+ notes: { help: "Notes about this component", hint: { type: "text", optional: true } }
17628
17726
  }
17629
17727
  }
17630
17728
  });
@@ -17700,7 +17798,8 @@ function info_default19(R) {
17700
17798
  }
17701
17799
  }
17702
17800
  }
17703
- }
17801
+ },
17802
+ notes: { help: "Additional notes about this component", hint: { type: "text", optional: true } }
17704
17803
  }
17705
17804
  },
17706
17805
  designtime: {