@arcanewizards/timecode-toolbox 0.1.0 → 0.1.1

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 (58) hide show
  1. package/LICENSE +21 -0
  2. package/dist/components/frontend/index.js +865 -272
  3. package/dist/components/frontend/index.mjs +855 -262
  4. package/dist/entrypoint.css +163 -53
  5. package/dist/entrypoint.js +1474 -493
  6. package/dist/entrypoint.js.map +4 -4
  7. package/dist/frontend.js +1474 -493
  8. package/dist/frontend.js.map +4 -4
  9. package/dist/index.d.mts +3 -1
  10. package/dist/index.d.ts +3 -1
  11. package/dist/index.js +308 -37
  12. package/dist/index.mjs +329 -49
  13. package/dist/start.d.mts +1 -2
  14. package/dist/start.d.ts +1 -2
  15. package/dist/start.js +311 -38
  16. package/dist/start.mjs +332 -50
  17. package/package.json +12 -6
  18. package/.turbo/turbo-build.log +0 -58
  19. package/.turbo/turbo-lint.log +0 -4
  20. package/CHANGELOG.md +0 -40
  21. package/eslint.config.mjs +0 -49
  22. package/src/app.tsx +0 -147
  23. package/src/components/backend/index.ts +0 -6
  24. package/src/components/backend/toolbox-root.ts +0 -119
  25. package/src/components/frontend/constants.ts +0 -81
  26. package/src/components/frontend/entrypoint.ts +0 -12
  27. package/src/components/frontend/frontend.css +0 -108
  28. package/src/components/frontend/index.tsx +0 -46
  29. package/src/components/frontend/toolbox/content.tsx +0 -45
  30. package/src/components/frontend/toolbox/context.tsx +0 -63
  31. package/src/components/frontend/toolbox/core/size-aware-div.tsx +0 -51
  32. package/src/components/frontend/toolbox/core/timecode-display.tsx +0 -592
  33. package/src/components/frontend/toolbox/generators.tsx +0 -318
  34. package/src/components/frontend/toolbox/inputs.tsx +0 -484
  35. package/src/components/frontend/toolbox/outputs.tsx +0 -581
  36. package/src/components/frontend/toolbox/preferences.ts +0 -25
  37. package/src/components/frontend/toolbox/root.tsx +0 -335
  38. package/src/components/frontend/toolbox/settings.tsx +0 -54
  39. package/src/components/frontend/toolbox/types.ts +0 -28
  40. package/src/components/frontend/toolbox/util.tsx +0 -61
  41. package/src/components/proto.ts +0 -420
  42. package/src/config.ts +0 -7
  43. package/src/generators/clock.tsx +0 -206
  44. package/src/generators/index.tsx +0 -15
  45. package/src/index.ts +0 -38
  46. package/src/inputs/artnet.tsx +0 -305
  47. package/src/inputs/index.tsx +0 -13
  48. package/src/inputs/tcnet.tsx +0 -272
  49. package/src/outputs/artnet.tsx +0 -170
  50. package/src/outputs/index.tsx +0 -11
  51. package/src/start.ts +0 -47
  52. package/src/tree.ts +0 -133
  53. package/src/types.ts +0 -12
  54. package/src/urls.ts +0 -49
  55. package/src/util.ts +0 -82
  56. package/tailwind.config.cjs +0 -7
  57. package/tsconfig.json +0 -10
  58. package/tsup.config.ts +0 -10
@@ -13975,7 +13975,7 @@ function cnd(condition, truthyClassName, falseyClassName) {
13975
13975
  return condition ? truthyClassName : falseyClassName;
13976
13976
  }
13977
13977
 
13978
- // ../../packages/sigil/dist/chunk-XAK7WC3D.js
13978
+ // ../../packages/sigil/dist/chunk-HF7IIHPE.js
13979
13979
  var import_react12 = require("react");
13980
13980
 
13981
13981
  // ../../node_modules/.pnpm/@arcanejs+toolkit-frontend@0.11.0/node_modules/@arcanejs/toolkit-frontend/dist/chunk-DK4BAXVE.mjs
@@ -14014,7 +14014,7 @@ var TRANSPARENCY_SVG = `
14014
14014
  `;
14015
14015
  var TRANSPARENCY_SVG_URI = `data:image/svg+xml,${encodeURIComponent(TRANSPARENCY_SVG)}`;
14016
14016
 
14017
- // ../../packages/sigil/dist/chunk-XAK7WC3D.js
14017
+ // ../../packages/sigil/dist/chunk-HF7IIHPE.js
14018
14018
  var import_react13 = require("react");
14019
14019
  var import_jsx_runtime18 = require("react/jsx-runtime");
14020
14020
  var import_react14 = require("react");
@@ -14080,7 +14080,8 @@ var clsControlButton = ({
14080
14080
  active,
14081
14081
  touching,
14082
14082
  position,
14083
- className
14083
+ className,
14084
+ primary
14084
14085
  }) => cn(
14085
14086
  `sigil-control-button`,
14086
14087
  cnd(variant === "border", `sigil-control-button-variant-border`),
@@ -14092,6 +14093,7 @@ var clsControlButton = ({
14092
14093
  cnd(touching, `sigil-control-button-touching`),
14093
14094
  cnd(active, `sigil-control-button-active`),
14094
14095
  cnd(touching && active, `sigil-control-button-active-touching`),
14096
+ cnd(primary, `sigil-control-button-primary`),
14095
14097
  clsControlPosition(position),
14096
14098
  className
14097
14099
  );
@@ -14108,6 +14110,7 @@ var ControlButtonFrame = (0, import_react13.forwardRef)(
14108
14110
  title,
14109
14111
  tooltipSide,
14110
14112
  position,
14113
+ primary,
14111
14114
  ...props
14112
14115
  }, ref) => {
14113
14116
  const btn = /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
@@ -14122,6 +14125,7 @@ var ControlButtonFrame = (0, import_react13.forwardRef)(
14122
14125
  active,
14123
14126
  touching,
14124
14127
  position,
14128
+ primary,
14125
14129
  className
14126
14130
  }),
14127
14131
  children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("span", { children: [
@@ -15890,7 +15894,12 @@ var OUTPUT_CONFIG = zod_default.object({
15890
15894
  var TOOLBOX_CONFIG = zod_default.object({
15891
15895
  inputs: zod_default.record(zod_default.string(), INPUT_CONFIG),
15892
15896
  generators: zod_default.record(zod_default.string(), GENERATOR_CONFIG),
15893
- outputs: zod_default.record(zod_default.string(), OUTPUT_CONFIG)
15897
+ outputs: zod_default.record(zod_default.string(), OUTPUT_CONFIG),
15898
+ /**
15899
+ * Hash of the license the user has agreed to.
15900
+ */
15901
+ agreedToLicense: zod_default.string().optional(),
15902
+ checkForUpdates: zod_default.boolean().optional().default(true)
15894
15903
  });
15895
15904
  var isTimecodeInstance = (instance) => instance !== null && "state" in instance && "metadata" in instance;
15896
15905
  var isTimecodeGroup = (instance) => instance !== null && "timecodes" in instance;
@@ -15898,83 +15907,7 @@ var NAMESPACE = "timecode-toolbox";
15898
15907
  var isTimecodeToolboxComponent = (component) => component.namespace === NAMESPACE;
15899
15908
 
15900
15909
  // src/components/frontend/toolbox/root.tsx
15901
- var import_react38 = require("react");
15902
-
15903
- // src/components/frontend/toolbox/core/size-aware-div.tsx
15904
- var import_react30 = require("react");
15905
- var import_jsx_runtime39 = require("react/jsx-runtime");
15906
- var SizeAwareDiv = ({
15907
- children,
15908
- style,
15909
- ...rest
15910
- }) => {
15911
- const [div, setDiv] = (0, import_react30.useState)(null);
15912
- const [rect, setRect] = (0, import_react30.useState)(null);
15913
- (0, import_react30.useEffect)(() => {
15914
- if (!div) {
15915
- return;
15916
- }
15917
- const resizeObserver = new ResizeObserver((entries) => {
15918
- for (const entry of entries) {
15919
- setRect(entry.contentRect);
15920
- }
15921
- });
15922
- resizeObserver.observe(div);
15923
- return () => {
15924
- resizeObserver.disconnect();
15925
- };
15926
- }, [div]);
15927
- return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
15928
- "div",
15929
- {
15930
- ref: setDiv,
15931
- ...rest,
15932
- style: {
15933
- ...style,
15934
- ...rect && cssVariables({
15935
- "--size-aware-div-width": rect.width + "px",
15936
- "--size-aware-div-height": rect.height + "px"
15937
- })
15938
- },
15939
- children
15940
- }
15941
- );
15942
- };
15943
-
15944
- // src/components/frontend/toolbox/content.tsx
15945
- var import_jsx_runtime40 = require("react/jsx-runtime");
15946
- var ExternalLink = ({
15947
- href,
15948
- children
15949
- }) => {
15950
- const { openExternalLink } = useBrowserContext();
15951
- return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
15952
- "a",
15953
- {
15954
- href,
15955
- target: "_blank",
15956
- rel: "noopener noreferrer",
15957
- onClick: (e) => {
15958
- e.preventDefault();
15959
- openExternalLink(href);
15960
- },
15961
- className: "\n text-sigil-usage-hint-foreground no-underline\n hover:underline\n ",
15962
- children
15963
- }
15964
- );
15965
- };
15966
- var NoToolboxChildren = ({ text }) => {
15967
- return /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
15968
- SizeAwareDiv,
15969
- {
15970
- className: "\n flex grow flex-col items-center justify-center gap-1 bg-sigil-bg-light\n p-1 text-sigil-foreground-muted\n ",
15971
- children: [
15972
- /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Icon2, { icon: "handyman", className: "text-block-icon" }),
15973
- /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: "text-center", children: text })
15974
- ]
15975
- }
15976
- );
15977
- };
15910
+ var import_react42 = require("react");
15978
15911
 
15979
15912
  // ../../packages/artnet/dist/chunk-J2HDMITA.js
15980
15913
  var ARTNET_PORT = 6454;
@@ -15991,6 +15924,7 @@ var MS_FORMAT = new Intl.NumberFormat(void 0, {
15991
15924
  unit: "millisecond",
15992
15925
  maximumFractionDigits: 0
15993
15926
  });
15927
+ var SOURCE_CODE_URL = "https://github.com/ArcaneWizards/open-source/tree/main/apps/timecode-toolbox";
15994
15928
  var STRINGS = {
15995
15929
  title: "Timecode Toolbox",
15996
15930
  debugger: "Debug Tools & Log",
@@ -15999,6 +15933,10 @@ var STRINGS = {
15999
15933
  openInNewWindow: "Open in new window",
16000
15934
  toggle: (text) => `Toggle ${text}`,
16001
15935
  close: (text) => `Close ${text}`,
15936
+ license: "License & About",
15937
+ acceptLicense: "Accept License",
15938
+ licensePrompt: "Please review and accept the license to use Timecode Toolbox",
15939
+ sourceCode: "Source Code",
16002
15940
  protocols: {
16003
15941
  artnet: {
16004
15942
  short: "ArtNet",
@@ -16058,6 +15996,17 @@ var STRINGS = {
16058
15996
  },
16059
15997
  errors: {
16060
15998
  unknownTimecodeID: "Unknown timecode ID, please close the window"
15999
+ },
16000
+ updates: {
16001
+ updateAvailable: (current, latest) => `Version ${latest} is available! You are currently on version ${current}.`,
16002
+ download: "Download",
16003
+ settingsLabel: "Automatically check for updates",
16004
+ settingsDetails: `When enabled, the app will automatically check for updates periodically and display a message when a new version is available.`,
16005
+ lastChecked: (time) => `Last checked: ${time}`
16006
+ },
16007
+ general: {
16008
+ enabled: "Enabled",
16009
+ disabled: "Disabled"
16061
16010
  }
16062
16011
  };
16063
16012
 
@@ -16065,23 +16014,23 @@ var STRINGS = {
16065
16014
  var import_react33 = require("react");
16066
16015
 
16067
16016
  // src/components/frontend/toolbox/util.tsx
16068
- var import_jsx_runtime41 = require("react/jsx-runtime");
16017
+ var import_jsx_runtime39 = require("react/jsx-runtime");
16069
16018
  var PrimaryToolboxSection = ({
16070
16019
  title,
16071
16020
  children,
16072
16021
  buttons
16073
16022
  }) => {
16074
- return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "flex grow gap-px", children: [
16075
- /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
16023
+ return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "flex grow gap-px", children: [
16024
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
16076
16025
  "div",
16077
16026
  {
16078
16027
  className: "\n flex items-center justify-center bg-sigil-bg-light p-1\n writing-mode-vertical-rl\n ",
16079
16028
  children: title
16080
16029
  }
16081
16030
  ),
16082
- /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "flex grow flex-col gap-px", children: [
16083
- /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "flex grow flex-col gap-px", children }),
16084
- /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "flex w-full flex-wrap gap-1 bg-sigil-bg-light p-1", children: buttons })
16031
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "flex grow flex-col gap-px", children: [
16032
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "flex grow flex-col gap-px", children }),
16033
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "flex w-full flex-wrap gap-1 bg-sigil-bg-light p-1", children: buttons })
16085
16034
  ] })
16086
16035
  ] });
16087
16036
  };
@@ -16101,31 +16050,31 @@ function displayMillis(totalMilliseconds) {
16101
16050
  }
16102
16051
 
16103
16052
  // src/components/frontend/toolbox/context.tsx
16104
- var import_react31 = require("react");
16105
- var ConfigContext = (0, import_react31.createContext)(
16053
+ var import_react30 = require("react");
16054
+ var ConfigContext = (0, import_react30.createContext)(
16106
16055
  new Proxy({}, {
16107
16056
  get() {
16108
16057
  throw new Error("ConfigContext not initialized");
16109
16058
  }
16110
16059
  })
16111
16060
  );
16112
- var ApplicationStateContext = (0, import_react31.createContext)(
16061
+ var ApplicationStateContext = (0, import_react30.createContext)(
16113
16062
  new Proxy({}, {
16114
16063
  get() {
16115
16064
  throw new Error("ApplicationStateContext not initialized");
16116
16065
  }
16117
16066
  })
16118
16067
  );
16119
- var useApplicationState = () => (0, import_react31.useContext)(ApplicationStateContext);
16120
- var ApplicationHandlersContext = (0, import_react31.createContext)(
16068
+ var useApplicationState = () => (0, import_react30.useContext)(ApplicationStateContext);
16069
+ var ApplicationHandlersContext = (0, import_react30.createContext)(
16121
16070
  new Proxy({}, {
16122
16071
  get() {
16123
16072
  throw new Error("ApplicationHandlersContext not initialized");
16124
16073
  }
16125
16074
  })
16126
16075
  );
16127
- var useApplicationHandlers = () => (0, import_react31.useContext)(ApplicationHandlersContext);
16128
- var NetworkContext = (0, import_react31.createContext)(
16076
+ var useApplicationHandlers = () => (0, import_react30.useContext)(ApplicationHandlersContext);
16077
+ var NetworkContext = (0, import_react30.createContext)(
16129
16078
  new Proxy({}, {
16130
16079
  get() {
16131
16080
  throw new Error("NetworkContext not initialized");
@@ -16136,6 +16085,47 @@ var NetworkContext = (0, import_react31.createContext)(
16136
16085
  // src/components/frontend/toolbox/core/timecode-display.tsx
16137
16086
  var import_react32 = require("react");
16138
16087
 
16088
+ // src/components/frontend/toolbox/core/size-aware-div.tsx
16089
+ var import_react31 = require("react");
16090
+ var import_jsx_runtime40 = require("react/jsx-runtime");
16091
+ var SizeAwareDiv = ({
16092
+ children,
16093
+ style,
16094
+ ...rest
16095
+ }) => {
16096
+ const [div, setDiv] = (0, import_react31.useState)(null);
16097
+ const [rect, setRect] = (0, import_react31.useState)(null);
16098
+ (0, import_react31.useEffect)(() => {
16099
+ if (!div) {
16100
+ return;
16101
+ }
16102
+ const resizeObserver = new ResizeObserver((entries) => {
16103
+ for (const entry of entries) {
16104
+ setRect(entry.contentRect);
16105
+ }
16106
+ });
16107
+ resizeObserver.observe(div);
16108
+ return () => {
16109
+ resizeObserver.disconnect();
16110
+ };
16111
+ }, [div]);
16112
+ return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
16113
+ "div",
16114
+ {
16115
+ ref: setDiv,
16116
+ ...rest,
16117
+ style: {
16118
+ ...style,
16119
+ ...rect && cssVariables({
16120
+ "--size-aware-div-width": rect.width + "px",
16121
+ "--size-aware-div-height": rect.height + "px"
16122
+ })
16123
+ },
16124
+ children
16125
+ }
16126
+ );
16127
+ };
16128
+
16139
16129
  // src/tree.ts
16140
16130
  var isTreeNode = (node) => "children" in node && typeof node.children === "object" && node.children !== null;
16141
16131
  var getTreeValue = (current, path) => {
@@ -16241,7 +16231,7 @@ var augmentUpstreamTimecodeWithOutputMetadata = (tc, config) => {
16241
16231
  };
16242
16232
 
16243
16233
  // src/components/frontend/toolbox/core/timecode-display.tsx
16244
- var import_jsx_runtime42 = require("react/jsx-runtime");
16234
+ var import_jsx_runtime41 = require("react/jsx-runtime");
16245
16235
  var ActiveTimecodeText = ({
16246
16236
  effectiveStartTimeMillis,
16247
16237
  speed
@@ -16289,7 +16279,7 @@ var Timeline2 = ({ state, totalTime }) => {
16289
16279
  }
16290
16280
  };
16291
16281
  }, [state, timeDifferenceMs]);
16292
- return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { className: "w-full border border-timecode-usage-foreground p-px", children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { className: "relative h-1 w-full overflow-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
16282
+ return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "w-full border border-timecode-usage-foreground p-px", children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "relative h-1 w-full overflow-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
16293
16283
  "div",
16294
16284
  {
16295
16285
  className: "absolute inset-y-0 left-0 bg-timecode-usage-foreground",
@@ -16341,8 +16331,8 @@ var TimecodeDisplay = ({
16341
16331
  }
16342
16332
  }
16343
16333
  }, [hooks, play, pause, state.state]);
16344
- return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "flex grow flex-col gap-px", children: [
16345
- /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
16334
+ return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "flex grow flex-col gap-px", children: [
16335
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(
16346
16336
  "div",
16347
16337
  {
16348
16338
  className: cn(
@@ -16354,8 +16344,8 @@ var TimecodeDisplay = ({
16354
16344
  )
16355
16345
  ),
16356
16346
  children: [
16357
- headerComponents && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { className: "flex flex-wrap gap-0.25", children: headerComponents }),
16358
- /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
16347
+ headerComponents && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "flex flex-wrap gap-0.25", children: headerComponents }),
16348
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
16359
16349
  SizeAwareDiv,
16360
16350
  {
16361
16351
  className: cn(
@@ -16370,7 +16360,7 @@ var TimecodeDisplay = ({
16370
16360
  )
16371
16361
  ),
16372
16362
  onClick: toggle,
16373
- children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { className: "absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: cn("font-mono text-timecode-adaptive"), children: state.state === "none" ? "--:--:--:---" : state.state === "stopped" ? displayMillis(state.positionMillis) : /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
16363
+ children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { className: cn("font-mono text-timecode-adaptive"), children: state.state === "none" ? "--:--:--:---" : state.state === "stopped" ? displayMillis(state.positionMillis) : /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
16374
16364
  ActiveTimecodeText,
16375
16365
  {
16376
16366
  effectiveStartTimeMillis: state.effectiveStartTimeMillis,
@@ -16379,8 +16369,8 @@ var TimecodeDisplay = ({
16379
16369
  ) }) })
16380
16370
  }
16381
16371
  ),
16382
- hooks?.pause || hooks?.play ? /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "flex justify-center gap-px", children: [
16383
- hooks.beginning && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
16372
+ hooks?.pause || hooks?.play ? /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "flex justify-center gap-px", children: [
16373
+ hooks.beginning && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
16384
16374
  ControlButton,
16385
16375
  {
16386
16376
  onClick: beginning,
@@ -16391,7 +16381,7 @@ var TimecodeDisplay = ({
16391
16381
  className: "text-timecode-usage-foreground!"
16392
16382
  }
16393
16383
  ),
16394
- hooks.seekRelative && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
16384
+ hooks.seekRelative && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
16395
16385
  ControlButton,
16396
16386
  {
16397
16387
  onClick: back5seconds,
@@ -16402,7 +16392,7 @@ var TimecodeDisplay = ({
16402
16392
  className: "text-timecode-usage-foreground!"
16403
16393
  }
16404
16394
  ),
16405
- state.state === "none" || state.state === "stopped" ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
16395
+ state.state === "none" || state.state === "stopped" ? /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
16406
16396
  ControlButton,
16407
16397
  {
16408
16398
  onClick: play,
@@ -16412,7 +16402,7 @@ var TimecodeDisplay = ({
16412
16402
  title: STRINGS.controls.play,
16413
16403
  className: "text-timecode-usage-foreground!"
16414
16404
  }
16415
- ) : /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
16405
+ ) : /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
16416
16406
  ControlButton,
16417
16407
  {
16418
16408
  onClick: pause,
@@ -16423,7 +16413,7 @@ var TimecodeDisplay = ({
16423
16413
  className: "text-timecode-usage-foreground!"
16424
16414
  }
16425
16415
  ),
16426
- hooks.seekRelative && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
16416
+ hooks.seekRelative && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
16427
16417
  ControlButton,
16428
16418
  {
16429
16419
  onClick: forward5seconds,
@@ -16435,33 +16425,33 @@ var TimecodeDisplay = ({
16435
16425
  }
16436
16426
  )
16437
16427
  ] }) : null,
16438
- metadata?.totalTime && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(Timeline2, { state, totalTime: metadata.totalTime })
16428
+ metadata?.totalTime && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(Timeline2, { state, totalTime: metadata.totalTime })
16439
16429
  ]
16440
16430
  }
16441
16431
  ),
16442
- (state.smpteMode !== null || state.accuracyMillis !== null || config.delayMs !== null) && /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "flex gap-px", children: [
16443
- config.delayMs !== null && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { className: "grow basis-0 truncate bg-sigil-bg-light p-0.5", children: STRINGS.delay(config.delayMs) }),
16444
- state.smpteMode !== null && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { className: "grow basis-0 truncate bg-sigil-bg-light p-0.5", children: STRINGS.smtpeModes[state.smpteMode] }),
16445
- state.accuracyMillis !== null && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { className: "grow basis-0 truncate bg-sigil-bg-light p-0.5", children: STRINGS.accuracy(state.accuracyMillis) })
16432
+ (state.smpteMode !== null || state.accuracyMillis !== null || config.delayMs !== null) && /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "flex gap-px", children: [
16433
+ config.delayMs !== null && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "grow basis-0 truncate bg-sigil-bg-light p-0.5", children: STRINGS.delay(config.delayMs) }),
16434
+ state.smpteMode !== null && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "grow basis-0 truncate bg-sigil-bg-light p-0.5", children: STRINGS.smtpeModes[state.smpteMode] }),
16435
+ state.accuracyMillis !== null && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "grow basis-0 truncate bg-sigil-bg-light p-0.5", children: STRINGS.accuracy(state.accuracyMillis) })
16446
16436
  ] }),
16447
- metadata?.artist || metadata?.title ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
16437
+ metadata?.artist || metadata?.title ? /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
16448
16438
  TooltipWrapper,
16449
16439
  {
16450
- tooltip: /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(import_jsx_runtime42.Fragment, { children: [
16451
- metadata.title && /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { children: [
16452
- /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "font-bold", children: "Title:" }),
16440
+ tooltip: /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(import_jsx_runtime41.Fragment, { children: [
16441
+ metadata.title && /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { children: [
16442
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { className: "font-bold", children: "Title:" }),
16453
16443
  " ",
16454
16444
  metadata.title
16455
16445
  ] }),
16456
- metadata.artist && /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { children: [
16457
- /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "font-bold", children: "Artist:" }),
16446
+ metadata.artist && /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { children: [
16447
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { className: "font-bold", children: "Artist:" }),
16458
16448
  " ",
16459
16449
  metadata.artist
16460
16450
  ] })
16461
16451
  ] }),
16462
- children: /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "flex gap-px", children: [
16463
- metadata.title && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { className: "grow truncate bg-sigil-bg-light p-0.5 font-bold", children: metadata.title }),
16464
- metadata.artist && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { className: "grow truncate bg-sigil-bg-light p-0.5", children: metadata.artist })
16452
+ children: /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "flex gap-px", children: [
16453
+ metadata.title && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "grow truncate bg-sigil-bg-light p-0.5 font-bold", children: metadata.title }),
16454
+ metadata.artist && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "grow truncate bg-sigil-bg-light p-0.5", children: metadata.artist })
16465
16455
  ] })
16466
16456
  }
16467
16457
  ) : null
@@ -16502,7 +16492,7 @@ var TimecodeTreeDisplay = ({
16502
16492
  }, [id, openNewWidow]);
16503
16493
  name = timecode?.name ? [...name, timecode.name] : name;
16504
16494
  if (isTimecodeGroup(timecode) && Object.values(timecode.timecodes).length) {
16505
- return Object.entries(timecode.timecodes).map(([key, child]) => /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
16495
+ return Object.entries(timecode.timecodes).map(([key, child]) => /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
16506
16496
  TimecodeTreeDisplay,
16507
16497
  {
16508
16498
  config,
@@ -16518,28 +16508,28 @@ var TimecodeTreeDisplay = ({
16518
16508
  key
16519
16509
  ));
16520
16510
  }
16521
- return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
16511
+ return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(
16522
16512
  "div",
16523
16513
  {
16524
16514
  className: "relative flex grow flex-col text-timecode-usage-foreground",
16525
16515
  style: color && cssSigilColorUsageVariables("timecode-usage", sigilColorUsage(color)),
16526
16516
  children: [
16527
- /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
16517
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
16528
16518
  TimecodeDisplay,
16529
16519
  {
16530
16520
  id,
16531
16521
  timecode: isTimecodeInstance(timecode) ? timecode : EMPTY_TIMECODE,
16532
16522
  config,
16533
- headerComponents: /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(import_jsx_runtime42.Fragment, { children: [
16534
- /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "flex grow items-start gap-0.25", children: [
16535
- /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
16523
+ headerComponents: /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(import_jsx_runtime41.Fragment, { children: [
16524
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "flex grow items-start gap-0.25", children: [
16525
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
16536
16526
  "div",
16537
16527
  {
16538
16528
  className: "\n m-0.25 rounded-md border border-sigil-bg-light\n bg-timecode-usage-foreground px-1 py-0.25 text-sigil-control\n text-timecode-usage-text\n ",
16539
16529
  children: type
16540
16530
  }
16541
16531
  ),
16542
- /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
16532
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
16543
16533
  "div",
16544
16534
  {
16545
16535
  className: cn(
@@ -16550,8 +16540,8 @@ var TimecodeTreeDisplay = ({
16550
16540
  }
16551
16541
  )
16552
16542
  ] }),
16553
- /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(ControlButtonGroup, { className: "rounded-md bg-sigil-bg-light", children: [
16554
- /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
16543
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(ControlButtonGroup, { className: "rounded-md bg-sigil-bg-light", children: [
16544
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
16555
16545
  ControlButton,
16556
16546
  {
16557
16547
  variant: "toolbar",
@@ -16565,12 +16555,12 @@ var TimecodeTreeDisplay = ({
16565
16555
  ] })
16566
16556
  }
16567
16557
  ),
16568
- assignToOutput && id && !isOutputInstanceId(id) && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
16558
+ assignToOutput && id && !isOutputInstanceId(id) && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
16569
16559
  SizeAwareDiv,
16570
16560
  {
16571
16561
  className: "\n absolute inset-0 flex cursor-pointer items-center justify-center\n bg-timecode-backdrop text-timecode-usage-text\n hover:bg-timecode-backdrop-hover\n ",
16572
16562
  onClick: () => assignToOutput(id),
16573
- children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(Icon2, { icon: "link", className: "text-block-icon" })
16563
+ children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(Icon2, { icon: "link", className: "text-block-icon" })
16574
16564
  }
16575
16565
  )
16576
16566
  ]
@@ -16636,22 +16626,22 @@ var FullscreenTimecodeDisplay = ({
16636
16626
  }
16637
16627
  }, [id, config]);
16638
16628
  if (!instanceConfig) {
16639
- return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
16629
+ return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(
16640
16630
  SizeAwareDiv,
16641
16631
  {
16642
16632
  className: "\n flex grow flex-col items-center justify-center gap-1 bg-sigil-bg-light\n p-1 text-sigil-foreground-muted\n ",
16643
16633
  children: [
16644
- /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(Icon2, { icon: "question_mark", className: "text-block-icon" }),
16645
- /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { className: "text-center", children: STRINGS.errors.unknownTimecodeID })
16634
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(Icon2, { icon: "question_mark", className: "text-block-icon" }),
16635
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "text-center", children: STRINGS.errors.unknownTimecodeID })
16646
16636
  ]
16647
16637
  }
16648
16638
  );
16649
16639
  }
16650
- return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
16640
+ return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
16651
16641
  "div",
16652
16642
  {
16653
16643
  className: "\n flex h-0 grow flex-col gap-px overflow-y-auto bg-sigil-border\n scrollbar-sigil\n ",
16654
- children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
16644
+ children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
16655
16645
  TimecodeTreeDisplay,
16656
16646
  {
16657
16647
  id,
@@ -16716,6 +16706,54 @@ function v4(options, buf, offset4) {
16716
16706
  }
16717
16707
  var v4_default = v4;
16718
16708
 
16709
+ // src/components/frontend/toolbox/content.tsx
16710
+ var import_jsx_runtime42 = require("react/jsx-runtime");
16711
+ var ExternalLink = ({
16712
+ href,
16713
+ children
16714
+ }) => {
16715
+ const { openExternalLink } = useBrowserContext();
16716
+ return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
16717
+ "a",
16718
+ {
16719
+ href,
16720
+ target: "_blank",
16721
+ rel: "noopener noreferrer",
16722
+ onClick: (e) => {
16723
+ e.preventDefault();
16724
+ openExternalLink(href);
16725
+ },
16726
+ className: "\n text-sigil-usage-hint-foreground no-underline\n hover:underline\n ",
16727
+ children
16728
+ }
16729
+ );
16730
+ };
16731
+ var TextButton = ({
16732
+ onClick,
16733
+ children
16734
+ }) => {
16735
+ return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
16736
+ "span",
16737
+ {
16738
+ onClick,
16739
+ className: "\n cursor-pointer text-sigil-usage-hint-foreground\n hover:underline\n ",
16740
+ children
16741
+ }
16742
+ );
16743
+ };
16744
+ var NoToolboxChildren = ({ text }) => {
16745
+ return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
16746
+ SizeAwareDiv,
16747
+ {
16748
+ className: "\n flex grow flex-col items-center justify-center gap-1 bg-sigil-bg-light\n p-1 text-sigil-foreground-muted\n ",
16749
+ children: [
16750
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(Icon2, { icon: "handyman", className: "text-block-icon" }),
16751
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { className: "text-center", children: text })
16752
+ ]
16753
+ }
16754
+ );
16755
+ };
16756
+
16719
16757
  // src/components/frontend/toolbox/outputs.tsx
16720
16758
  var import_jsx_runtime43 = require("react/jsx-runtime");
16721
16759
  var DmxConnectionSettings = ({
@@ -17907,6 +17945,9 @@ var diffJson = (a, b) => {
17907
17945
  return { type: "value", after: b };
17908
17946
  };
17909
17947
 
17948
+ // src/components/frontend/toolbox/settings.tsx
17949
+ var import_react38 = require("react");
17950
+
17910
17951
  // ../../packages/sigil/dist/frontend/appearance.js
17911
17952
  var import_react36 = require("react");
17912
17953
  var import_jsx_runtime46 = require("react/jsx-runtime");
@@ -18051,8 +18092,17 @@ var useBrowserPreferences = createBrowserPreferencesHook(TOOLBOX_PREFERENCES);
18051
18092
 
18052
18093
  // src/components/frontend/toolbox/settings.tsx
18053
18094
  var import_jsx_runtime47 = require("react/jsx-runtime");
18095
+ var ENABLED_DISABLED_OPTIONS = [
18096
+ { value: "enabled", label: STRINGS.general.enabled },
18097
+ { value: "disabled", label: STRINGS.general.disabled }
18098
+ ];
18099
+ var DATE_FORMATTER = new Intl.DateTimeFormat(void 0, {
18100
+ timeStyle: "medium"
18101
+ });
18054
18102
  var Settings = ({ setWindowMode }) => {
18055
18103
  const { preferences, updateBrowserPrefs } = useBrowserPreferences();
18104
+ const { config, updateConfig } = (0, import_react38.useContext)(ConfigContext);
18105
+ const { updates } = useApplicationState();
18056
18106
  return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex grow flex-col", children: [
18057
18107
  /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(ToolbarWrapper, { children: /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(ToolbarRow, { children: [
18058
18108
  /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "grow p-1", children: STRINGS.settings.title }),
@@ -18079,26 +18129,595 @@ var Settings = ({ setWindowMode }) => {
18079
18129
  color: preferences.color,
18080
18130
  onColorChange: (color) => updateBrowserPrefs((current) => ({ ...current, color }))
18081
18131
  }
18082
- )
18132
+ ),
18133
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(ControlLabel, { children: STRINGS.updates.settingsLabel }),
18134
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
18135
+ ControlSelect,
18136
+ {
18137
+ value: config.checkForUpdates ? "enabled" : "disabled",
18138
+ options: ENABLED_DISABLED_OPTIONS,
18139
+ onChange: (value) => updateConfig((current) => ({
18140
+ ...current,
18141
+ checkForUpdates: value === "enabled"
18142
+ })),
18143
+ variant: "large"
18144
+ }
18145
+ ),
18146
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(ControlDetails, { children: STRINGS.updates.settingsDetails }),
18147
+ updates && "lastCheckedMillis" in updates && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(ControlDetails, { children: STRINGS.updates.lastChecked(
18148
+ DATE_FORMATTER.format(updates.lastCheckedMillis)
18149
+ ) })
18083
18150
  ] })
18084
18151
  }
18085
18152
  )
18086
18153
  ] });
18087
18154
  };
18088
18155
 
18089
- // src/components/frontend/toolbox/root.tsx
18156
+ // src/components/frontend/toolbox/license.tsx
18157
+ var import_react40 = require("react");
18158
+
18159
+ // src/components/frontend/toolbox/logo.tsx
18090
18160
  var import_jsx_runtime48 = require("react/jsx-runtime");
18091
- var ToolboxRoot = ({ info }) => {
18092
- const [windowMode, setWindowMode] = (0, import_react38.useState)(
18093
- null
18161
+ var TimecodeToolboxLogo = (props) => /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(
18162
+ "svg",
18163
+ {
18164
+ xmlns: "http://www.w3.org/2000/svg",
18165
+ viewBox: "0 0 1365.333 1365.333",
18166
+ ...props,
18167
+ children: [
18168
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("defs", { children: [
18169
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("mask", { id: "b", maskUnits: "userSpaceOnUse", children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
18170
+ "path",
18171
+ {
18172
+ fill: "#fff",
18173
+ "stroke-linecap": "round",
18174
+ "stroke-linejoin": "round",
18175
+ "stroke-width": "50.12",
18176
+ d: "m347.83 438.376 11.825 188.138-36.885 62.692v411.759h986.987v-411.76l-36.886-62.691 11.825-188.138z"
18177
+ }
18178
+ ) }),
18179
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("mask", { id: "g", maskUnits: "userSpaceOnUse", children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
18180
+ "path",
18181
+ {
18182
+ fill: "#fff",
18183
+ "stroke-linecap": "round",
18184
+ "stroke-linejoin": "round",
18185
+ "stroke-width": "5.581",
18186
+ d: "m523.18 899.13 300.24-394.065s34.365-35.915 46.091-69.549c11.727-33.634.988-72.204-2.46-104.403-5.358-50.016 59.283-109.877 59.283-109.877s69.906-48.692 76.993-40.385-46.397 95.284-39.707 122.272c10.605 42.782 80.61 74.691 115.162 58.516s54.191-119.781 68.45-123.27c14.259-3.49 31.217 85.629 29.104 137.042s-52.322 83.478-83.625 93.094-71.227 10.846-102.507 35.2-361.42 471.203-361.42 471.203z"
18187
+ }
18188
+ ) }),
18189
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("mask", { id: "f", maskUnits: "userSpaceOnUse", children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
18190
+ "path",
18191
+ {
18192
+ fill: "#fff",
18193
+ "stroke-linecap": "round",
18194
+ "stroke-linejoin": "round",
18195
+ "stroke-width": "5.581",
18196
+ d: "m523.18 899.13 300.24-394.065s34.365-35.915 46.091-69.549c11.727-33.634.988-72.204-2.46-104.403-5.358-50.016 59.283-109.877 59.283-109.877s69.906-48.692 76.993-40.385-46.397 95.284-39.707 122.272c10.605 42.782 80.61 74.691 115.162 58.516s54.191-119.781 68.45-123.27c14.259-3.49 31.217 85.629 29.104 137.042s-52.322 83.478-83.625 93.094-71.227 10.846-102.507 35.2-361.42 471.203-361.42 471.203z"
18197
+ }
18198
+ ) }),
18199
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("mask", { id: "e", maskUnits: "userSpaceOnUse", children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
18200
+ "path",
18201
+ {
18202
+ fill: "#fff",
18203
+ "stroke-linecap": "round",
18204
+ "stroke-linejoin": "round",
18205
+ "stroke-width": "5.581",
18206
+ d: "m523.18 899.13 300.24-394.065s34.365-35.915 46.091-69.549c11.727-33.634.988-72.204-2.46-104.403-5.358-50.016 59.283-109.877 59.283-109.877s69.906-48.692 76.993-40.385-46.397 95.284-39.707 122.272c10.605 42.782 80.61 74.691 115.162 58.516s54.191-119.781 68.45-123.27c14.259-3.49 31.217 85.629 29.104 137.042s-52.322 83.478-83.625 93.094-71.227 10.846-102.507 35.2-361.42 471.203-361.42 471.203z"
18207
+ }
18208
+ ) }),
18209
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("mask", { id: "d", maskUnits: "userSpaceOnUse", children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
18210
+ "path",
18211
+ {
18212
+ fill: "#fff",
18213
+ "stroke-linecap": "round",
18214
+ "stroke-linejoin": "round",
18215
+ "stroke-width": "5.581",
18216
+ d: "m523.18 899.13 300.24-394.065s34.365-35.915 46.091-69.549c11.727-33.634.988-72.204-2.46-104.403-5.358-50.016 59.283-109.877 59.283-109.877s69.906-48.692 76.993-40.385-46.397 95.284-39.707 122.272c10.605 42.782 80.61 74.691 115.162 58.516s54.191-119.781 68.45-123.27c14.259-3.49 31.217 85.629 29.104 137.042s-52.322 83.478-83.625 93.094-71.227 10.846-102.507 35.2-361.42 471.203-361.42 471.203z"
18217
+ }
18218
+ ) }),
18219
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("mask", { id: "c", maskUnits: "userSpaceOnUse", children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
18220
+ "path",
18221
+ {
18222
+ fill: "#fff",
18223
+ "stroke-linecap": "round",
18224
+ "stroke-linejoin": "round",
18225
+ "stroke-width": "5.581",
18226
+ d: "m523.18 899.13 300.24-394.065s34.365-35.915 46.091-69.549c11.727-33.634.988-72.204-2.46-104.403-5.358-50.016 59.283-109.877 59.283-109.877s69.906-48.692 76.993-40.385-46.397 95.284-39.707 122.272c10.605 42.782 80.61 74.691 115.162 58.516s54.191-119.781 68.45-123.27c14.259-3.49 31.217 85.629 29.104 137.042s-52.322 83.478-83.625 93.094-71.227 10.846-102.507 35.2-361.42 471.203-361.42 471.203z"
18227
+ }
18228
+ ) }),
18229
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("mask", { id: "k", maskUnits: "userSpaceOnUse", children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
18230
+ "path",
18231
+ {
18232
+ fill: "#fff",
18233
+ "stroke-linecap": "round",
18234
+ "stroke-linejoin": "round",
18235
+ "stroke-width": "7.033",
18236
+ d: "m209.947 266.846 76.909 154.59 31.315-12.212 281.763 384.488 39.973-29.294-281.646-384.327 21.561-26.783-124.246-119.9Z"
18237
+ }
18238
+ ) }),
18239
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("mask", { id: "j", maskUnits: "userSpaceOnUse", children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
18240
+ "path",
18241
+ {
18242
+ fill: "#fff",
18243
+ "stroke-linecap": "round",
18244
+ "stroke-linejoin": "round",
18245
+ "stroke-width": "7.033",
18246
+ d: "m209.947 266.846 76.909 154.59 31.315-12.212 281.763 384.488 39.973-29.294-281.646-384.327 21.561-26.783-124.246-119.9Z"
18247
+ }
18248
+ ) }),
18249
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("mask", { id: "i", maskUnits: "userSpaceOnUse", children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
18250
+ "path",
18251
+ {
18252
+ fill: "#fff",
18253
+ "stroke-linecap": "round",
18254
+ "stroke-linejoin": "round",
18255
+ "stroke-width": "7.033",
18256
+ d: "m209.947 266.846 76.909 154.59 31.315-12.212 281.763 384.488 39.973-29.294-281.646-384.327 21.561-26.783-124.246-119.9Z"
18257
+ }
18258
+ ) }),
18259
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("mask", { id: "h", maskUnits: "userSpaceOnUse", children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
18260
+ "path",
18261
+ {
18262
+ fill: "#fff",
18263
+ "stroke-linecap": "round",
18264
+ "stroke-linejoin": "round",
18265
+ "stroke-width": "7.033",
18266
+ d: "m209.947 266.846 76.909 154.59 31.315-12.212 281.763 384.488 39.973-29.294-281.646-384.327 21.561-26.783-124.246-119.9Z"
18267
+ }
18268
+ ) }),
18269
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
18270
+ "filter",
18271
+ {
18272
+ id: "a",
18273
+ width: "1.201",
18274
+ height: "1.19",
18275
+ x: "-.101",
18276
+ y: "-.074",
18277
+ "color-interpolation-filters": "sRGB",
18278
+ children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("feGaussianBlur", { stdDeviation: "10.298" })
18279
+ }
18280
+ )
18281
+ ] }),
18282
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(
18283
+ "g",
18284
+ {
18285
+ stroke: "#000",
18286
+ "stroke-linecap": "round",
18287
+ "stroke-linejoin": "round",
18288
+ filter: "url(#a)",
18289
+ opacity: ".25",
18290
+ transform: "translate(-216.03 -84.295)scale(1.10099)",
18291
+ children: [
18292
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
18293
+ "path",
18294
+ {
18295
+ "stroke-width": "153.76517303999998",
18296
+ d: "m337.226 438.886 12.093 192.397-37.72 64.11v421.08h1009.328v-421.08l-37.72-64.11 12.093-192.397z",
18297
+ opacity: "1"
18298
+ }
18299
+ ),
18300
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
18301
+ "path",
18302
+ {
18303
+ "stroke-width": "80.096",
18304
+ d: "m671.405 893.22 272.7-357.92s31.213-32.62 41.864-63.169.898-65.581-2.235-94.827c-4.866-45.427 53.846-99.798 53.846-99.798s63.494-44.226 69.93-36.68-42.14 86.544-36.064 111.056c9.632 38.858 73.216 67.84 104.599 53.149 31.382-14.691 49.22-108.795 62.171-111.964s28.353 77.775 26.435 124.473-47.523 75.82-75.955 84.554-64.694 9.851-93.104 31.972c-28.41 22.12-328.269 427.981-328.269 427.981z"
18305
+ }
18306
+ ),
18307
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
18308
+ "path",
18309
+ {
18310
+ "stroke-width": "80.096",
18311
+ d: "m386.903 318.933 69.855 140.41 28.443-11.092 255.918 349.22 36.307-26.606L521.614 421.79l19.583-24.326-112.85-108.903z"
18312
+ }
18313
+ )
18314
+ ]
18315
+ }
18316
+ ),
18317
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("g", { stroke: "#fff", "stroke-linecap": "round", "stroke-linejoin": "round", children: [
18318
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
18319
+ "path",
18320
+ {
18321
+ fill: "#8c63d9",
18322
+ "stroke-width": "165.54595738999998",
18323
+ d: "m166.927 398.352 13.02 207.137-40.611 69.024v453.341h1086.661V674.513l-40.61-69.024 13.02-207.137H424.595Z"
18324
+ }
18325
+ ),
18326
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
18327
+ "path",
18328
+ {
18329
+ fill: "none",
18330
+ "stroke-width": "73.48667853999999",
18331
+ d: "m209.947 266.846 76.909 154.59 31.315-12.212 281.763 384.488 39.973-29.294-281.646-384.327 21.561-26.783-124.246-119.9z"
18332
+ }
18333
+ ),
18334
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
18335
+ "path",
18336
+ {
18337
+ fill: "none",
18338
+ "stroke-width": "66.746",
18339
+ d: "m671.405 893.22 272.7-357.92s31.213-32.62 41.864-63.169.898-65.581-2.235-94.827c-4.866-45.427 53.846-99.798 53.846-99.798s63.494-44.226 69.93-36.68-42.14 86.544-36.064 111.056c9.632 38.858 73.216 67.84 104.599 53.149 31.382-14.691 49.22-108.795 62.171-111.964s28.353 77.775 26.435 124.473-47.523 75.82-75.955 84.554-64.694 9.851-93.104 31.972c-28.41 22.12-328.269 427.981-328.269 427.981z",
18340
+ transform: "translate(-216.03 -84.295)scale(1.10099)"
18341
+ }
18342
+ )
18343
+ ] }),
18344
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
18345
+ "path",
18346
+ {
18347
+ fill: "#8c63d9",
18348
+ stroke: "#263238",
18349
+ "stroke-linecap": "round",
18350
+ "stroke-linejoin": "round",
18351
+ "stroke-width": "55.182",
18352
+ d: "m166.927 398.352 13.02 207.137-40.611 69.023v453.342h1086.661V674.512l-40.61-69.023 13.02-207.137z"
18353
+ }
18354
+ ),
18355
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
18356
+ "path",
18357
+ {
18358
+ fill: "#cc7000",
18359
+ stroke: "#ffba66",
18360
+ "stroke-linecap": "round",
18361
+ "stroke-linejoin": "round",
18362
+ "stroke-width": "38.593",
18363
+ d: "M322.77 689.206h986.986l-36.885-62.693H359.655Z",
18364
+ mask: "url(#b)",
18365
+ transform: "translate(-216.03 -84.295)scale(1.10099)"
18366
+ }
18367
+ ),
18368
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
18369
+ "path",
18370
+ {
18371
+ fill: "#ff8c00",
18372
+ d: "m1185.387 605.49 13.02-207.138H166.926l13.02 207.137z"
18373
+ }
18374
+ ),
18375
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
18376
+ "path",
18377
+ {
18378
+ fill: "none",
18379
+ stroke: "#263238",
18380
+ "stroke-linecap": "round",
18381
+ "stroke-linejoin": "round",
18382
+ "stroke-width": "29.395",
18383
+ d: "m523.18 899.13 300.24-394.065s34.365-35.915 46.091-69.549c11.727-33.634.988-72.204-2.46-104.403-5.358-50.016 59.283-109.877 59.283-109.877s69.906-48.692 76.993-40.385-46.397 95.284-39.707 122.272c10.605 42.782 80.61 74.691 115.162 58.516s54.191-119.781 68.45-123.27c14.259-3.49 31.217 85.629 29.104 137.042s-52.322 83.478-83.625 93.094-71.227 10.846-102.507 35.2-361.42 471.203-361.42 471.203z"
18384
+ }
18385
+ ),
18386
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
18387
+ "path",
18388
+ {
18389
+ fill: "#eceff1",
18390
+ d: "m916.084 52.25 420.493 180.531-532.698 916.066-476.546-308.58Z",
18391
+ mask: "url(#c)"
18392
+ }
18393
+ ),
18394
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
18395
+ "path",
18396
+ {
18397
+ fill: "#fff",
18398
+ d: "M856.06 362.55s35.273 37.417 44.671 47.481 30.133 23.878 30.133 23.878-19.577-12.395-133.162 132.35c-113.586 144.744-274.29 356.33-274.29 356.33l-74.43-62.208z",
18399
+ mask: "url(#d)"
18400
+ }
18401
+ ),
18402
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
18403
+ "path",
18404
+ {
18405
+ fill: "#fff",
18406
+ d: "M1003.804 214.75s-61.324 47.811-85.42 85.1c-24.096 37.29-8.4 134.552-8.4 134.552l-119.375-94.095 193.083-235.652 92.963 84.914z",
18407
+ mask: "url(#e)"
18408
+ }
18409
+ ),
18410
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
18411
+ "path",
18412
+ {
18413
+ fill: "#cfd8dc",
18414
+ d: "M1128.958 213.086s18.838 96.946 18.548 125.56c-.29 28.612-8.26 73.801-33.74 89.024s-63.802 38.756-115.38 20.88-172.024-84.115-172.024-84.115S981.864 470.314 1006.22 474.08s112.252 10.05 112.252 10.05l90.662-46.814 21.129-221.796z",
18415
+ mask: "url(#f)"
18416
+ }
18417
+ ),
18418
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
18419
+ "path",
18420
+ {
18421
+ fill: "#cfd8dc",
18422
+ d: "M1041.552 459.425s-36.954 8.644-65.379 28.54-170.117 214.54-170.117 214.54L582.36 996.25l52.042 26.094 450.026-523.432z",
18423
+ mask: "url(#g)"
18424
+ }
18425
+ ),
18426
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
18427
+ "path",
18428
+ {
18429
+ fill: "none",
18430
+ stroke: "#263238",
18431
+ "stroke-linecap": "round",
18432
+ "stroke-linejoin": "round",
18433
+ "stroke-width": "29.395",
18434
+ d: "m209.947 266.846 76.909 154.59 31.315-12.212 281.763 384.488 39.973-29.294-281.646-384.327 21.561-26.783-124.246-119.9Z"
18435
+ }
18436
+ ),
18437
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
18438
+ "path",
18439
+ {
18440
+ fill: "#eceff1",
18441
+ d: "m105.922 257.574 152.745-109.918 438.66 518.005-348.484 67.536Z",
18442
+ mask: "url(#h)"
18443
+ }
18444
+ ),
18445
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
18446
+ "path",
18447
+ {
18448
+ fill: "#fff",
18449
+ d: "M326.613 211.828s-59.58 39.097-77.947 64.605C232.303 299.16 204.56 380.52 204.56 380.52l-48.272-119.485 119.003-77.722z",
18450
+ mask: "url(#i)"
18451
+ }
18452
+ ),
18453
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
18454
+ "path",
18455
+ {
18456
+ fill: "#cfd8dc",
18457
+ d: "M248.625 369.326s24.346 28.663 44.076 34.332c15.33 4.405 30.118-5.584 30.118-5.584l212.415 286.577-185.65 5.65z",
18458
+ mask: "url(#j)"
18459
+ }
18460
+ ),
18461
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
18462
+ "path",
18463
+ {
18464
+ fill: "#cfd8dc",
18465
+ d: "M355.22 375.68s11.46-16.196 12.454-25.01c3.052-27.043-32.344-49.296-32.344-49.296l77.092 54.069-53.634 24.84z",
18466
+ mask: "url(#k)"
18467
+ }
18468
+ ),
18469
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("path", { fill: "#ffba66", d: "M170.482 652.84h1025.265v453.341H170.482Z" }),
18470
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("path", { fill: "#ff8c00", d: "M139.336 674.512h1086.662v453.342H139.336Z" }),
18471
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
18472
+ "rect",
18473
+ {
18474
+ width: "875.482",
18475
+ height: "332.3",
18476
+ x: "244.926",
18477
+ y: "735.033",
18478
+ fill: "#cc7000",
18479
+ rx: "77.883",
18480
+ ry: "77.883"
18481
+ }
18482
+ ),
18483
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
18484
+ "path",
18485
+ {
18486
+ fill: "#fff",
18487
+ d: "M316.789 901.245q0-47.968 15.206-71.828 15.206-23.984 45.743-23.984 30.66 0 45.866 23.86t15.206 71.952q0 47.968-15.206 71.828-15.207 23.86-45.866 23.86-30.537 0-45.743-23.86-15.206-23.984-15.206-71.828m42.528 49.328q5.81 15.453 18.42 15.453 12.734 0 18.545-15.453 5.81-15.454 5.81-49.328 0-12.857-.865-22.995l-43.146 68.737q.618 1.978 1.236 3.586m18.42-114.233q-12.61 0-18.42 15.453-5.81 15.454-5.81 49.452 0 10.508.494 19.162l42.528-67.872-.247-.742q-5.81-15.453-18.544-15.453m91.486 64.905q0-47.968 15.206-71.828 15.206-23.984 45.742-23.984 30.66 0 45.867 23.86t15.206 71.952q0 47.968-15.206 71.828-15.207 23.86-45.867 23.86-30.536 0-45.742-23.86-15.206-23.984-15.206-71.828m42.528 49.328q5.81 15.453 18.42 15.453 12.734 0 18.545-15.453 5.81-15.454 5.81-49.328 0-12.858-.865-22.995l-43.147 68.737q.619 1.978 1.237 3.586m18.42-114.233q-12.61 0-18.42 15.453-5.81 15.454-5.81 49.452 0 10.508.494 19.162l42.528-67.872-.247-.742q-5.81-15.453-18.545-15.453M661.96 861.93h41.169v45.124h-41.169Zm0 86.045h41.169v45.372h-41.169Zm112.131-46.731q0-47.968 15.207-71.828 15.206-23.984 45.742-23.984 30.66 0 45.866 23.86 15.207 23.86 15.207 71.952 0 47.968-15.207 71.828-15.206 23.86-45.866 23.86-30.536 0-45.742-23.86-15.207-23.984-15.207-71.828m42.528 49.328q5.811 15.453 18.421 15.453 12.734 0 18.544-15.453 5.81-15.454 5.81-49.328 0-12.858-.865-22.995l-43.146 68.737q.618 1.978 1.236 3.586M835.04 836.34q-12.61 0-18.42 15.453-5.811 15.454-5.811 49.452 0 10.508.494 19.162l42.529-67.872-.248-.742q-5.81-15.453-18.544-15.453m91.485 64.905q0-47.968 15.206-71.828 15.207-23.984 45.743-23.984 30.66 0 45.866 23.86t15.206 71.952q0 47.968-15.206 71.828t-45.866 23.86q-30.536 0-45.743-23.86-15.206-23.984-15.206-71.828m42.528 49.328q5.81 15.453 18.42 15.453 12.735 0 18.545-15.453 5.81-15.454 5.81-49.328 0-12.858-.865-22.995l-43.146 68.737q.618 1.978 1.236 3.586m18.42-114.233q-12.61 0-18.42 15.453-5.81 15.454-5.81 49.452 0 10.508.494 19.162l42.528-67.872-.247-.742q-5.81-15.453-18.544-15.453",
18488
+ "aria-label": "00:00"
18489
+ }
18490
+ )
18491
+ ]
18492
+ }
18493
+ );
18494
+
18495
+ // src/components/frontend/toolbox/core/layout.tsx
18496
+ var import_react39 = require("react");
18497
+
18498
+ // src/components/frontend/toolbox/core/footer.tsx
18499
+ var import_jsx_runtime49 = require("react/jsx-runtime");
18500
+ var Footer = ({ openLicenseDetails }) => {
18501
+ return /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(
18502
+ "div",
18503
+ {
18504
+ className: "\n flex items-center justify-center gap-1 border-t border-sigil-border\n bg-sigil-bg-dark p-1 text-[80%]\n ",
18505
+ children: [
18506
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("span", { children: [
18507
+ "Created by",
18508
+ "\xA0",
18509
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(ExternalLink, { href: "https://arcanewizards.com", children: "Arcane Wizards" })
18510
+ ] }),
18511
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(ToolbarDivider, {}),
18512
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(ExternalLink, { href: SOURCE_CODE_URL, children: STRINGS.sourceCode }),
18513
+ openLicenseDetails && /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(import_jsx_runtime49.Fragment, { children: [
18514
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(ToolbarDivider, {}),
18515
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(TextButton, { onClick: openLicenseDetails, children: STRINGS.license })
18516
+ ] })
18517
+ ]
18518
+ }
18094
18519
  );
18095
- const { config } = info;
18096
- const { sendMessage, call, connection, reconnect } = (0, import_react38.useContext)(StageContext);
18097
- const [dialogMode, setDialogMode] = (0, import_react38.useState)(null);
18098
- const [assignToOutput, setAssignToOutput] = (0, import_react38.useState)(null);
18520
+ };
18521
+
18522
+ // src/components/frontend/toolbox/core/layout.tsx
18523
+ var import_jsx_runtime50 = require("react/jsx-runtime");
18524
+ var Layout = ({
18525
+ modes,
18526
+ children,
18527
+ licenseMode,
18528
+ footer
18529
+ }) => {
18530
+ const [windowMode, setWindowMode] = (0, import_react39.useState)(null);
18531
+ const { connection, reconnect } = (0, import_react39.useContext)(StageContext);
18099
18532
  const { preferences } = useBrowserPreferences();
18100
18533
  useRootHintVariables(preferences.color);
18101
- (0, import_react38.useEffect)(() => {
18534
+ return /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("div", { className: "flex h-screen flex-col", children: [
18535
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(ToolbarWrapper, { children: /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(ToolbarRow, { children: [
18536
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
18537
+ "div",
18538
+ {
18539
+ className: "\n flex h-full min-h-[36px] grow items-center justify-center px-1\n app-title-bar\n ",
18540
+ children: /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("span", { className: "font-bold text-hint-gradient", children: STRINGS.title })
18541
+ }
18542
+ ),
18543
+ modes && /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(import_jsx_runtime50.Fragment, { children: [
18544
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(ToolbarDivider, {}),
18545
+ Object.entries(modes).map(([key, { icon, title }]) => /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
18546
+ ControlButton,
18547
+ {
18548
+ onClick: () => setWindowMode((mode) => mode === key ? null : key),
18549
+ variant: "titlebar",
18550
+ icon,
18551
+ active: windowMode === key,
18552
+ title: STRINGS.toggle(title)
18553
+ },
18554
+ key
18555
+ ))
18556
+ ] })
18557
+ ] }) }),
18558
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("div", { className: "relative flex h-0 grow flex-col", children: connection.state !== "connected" ? /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(
18559
+ SizeAwareDiv,
18560
+ {
18561
+ className: "\n flex grow flex-col items-center justify-center gap-1\n bg-sigil-bg-light p-1 text-sigil-foreground-muted\n ",
18562
+ children: [
18563
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(Icon2, { icon: "signal_disconnected", className: "text-block-icon" }),
18564
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("div", { className: "text-center", children: STRINGS.connectionError }),
18565
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(ControlButton, { onClick: reconnect, variant: "large", icon: "replay", children: STRINGS.reconnect })
18566
+ ]
18567
+ }
18568
+ ) : windowMode && modes?.[windowMode] ? modes[windowMode].child(setWindowMode) : children }),
18569
+ footer && /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
18570
+ Footer,
18571
+ {
18572
+ openLicenseDetails: licenseMode && (() => setWindowMode(
18573
+ (mode) => mode === licenseMode ? null : licenseMode
18574
+ ))
18575
+ }
18576
+ )
18577
+ ] });
18578
+ };
18579
+
18580
+ // src/components/frontend/toolbox/license.tsx
18581
+ var import_jsx_runtime51 = require("react/jsx-runtime");
18582
+ var LicenseContent = ({ license }) => {
18583
+ return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("div", { className: "flex flex-col gap-2 rounded-md bg-sigil-bg-light p-2", children: license.split("\n\n").map((paragraph, index2) => /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("p", { className: "m-0", children: paragraph.replace(/\n/g, " ").trim() }, index2)) });
18584
+ };
18585
+ var License = ({ license, setWindowMode }) => {
18586
+ return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("div", { className: "flex grow flex-col", children: /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(
18587
+ "div",
18588
+ {
18589
+ className: "\n flex grow basis-0 flex-col overflow-y-auto px-2 pb-2 scrollbar-sigil\n ",
18590
+ children: [
18591
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(TimecodeToolboxLogo, { className: "h-[20%] max-h-[420px] min-h-[110px] w-full" }),
18592
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(LicenseContent, { license }),
18593
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("div", { className: "flex justify-center p-2", children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
18594
+ ControlButton,
18595
+ {
18596
+ onClick: () => setWindowMode(null),
18597
+ variant: "large",
18598
+ icon: "close",
18599
+ children: STRINGS.close(STRINGS.license)
18600
+ }
18601
+ ) })
18602
+ ]
18603
+ }
18604
+ ) });
18605
+ };
18606
+ var LicenseGate = ({ info }) => {
18607
+ const { sendMessage } = (0, import_react40.useContext)(StageContext);
18608
+ const acceptLicense = (0, import_react40.useCallback)(() => {
18609
+ sendMessage?.({
18610
+ type: "component-message",
18611
+ namespace: "timecode-toolbox",
18612
+ component: "license-gate",
18613
+ componentKey: info.key,
18614
+ action: "accept-license",
18615
+ hash: info.hash
18616
+ });
18617
+ }, [sendMessage, info.key, info.hash]);
18618
+ return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
18619
+ Layout,
18620
+ {
18621
+ footer: true,
18622
+ modes: {
18623
+ debug: {
18624
+ child: () => /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(Debugger, { title: STRINGS.debugger, className: "size-full" }),
18625
+ icon: "bug_report",
18626
+ title: STRINGS.debugger
18627
+ }
18628
+ },
18629
+ children: /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(
18630
+ "div",
18631
+ {
18632
+ className: "\n flex grow basis-0 flex-col overflow-y-auto px-2 pb-2 scrollbar-sigil\n ",
18633
+ children: [
18634
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(TimecodeToolboxLogo, { className: "h-[20%] max-h-[420px] min-h-[110px] w-full" }),
18635
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("h2", { className: "text-center text-sigil-usage-hint-foreground", children: STRINGS.licensePrompt }),
18636
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(LicenseContent, { license: info.license }),
18637
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("div", { className: "flex justify-center p-2", children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
18638
+ ControlButton,
18639
+ {
18640
+ onClick: acceptLicense,
18641
+ variant: "large",
18642
+ icon: "check",
18643
+ primary: true,
18644
+ children: STRINGS.acceptLicense
18645
+ }
18646
+ ) })
18647
+ ]
18648
+ }
18649
+ )
18650
+ }
18651
+ );
18652
+ };
18653
+
18654
+ // src/components/frontend/toolbox/core/updates.tsx
18655
+ var import_react41 = require("react");
18656
+ var import_jsx_runtime52 = require("react/jsx-runtime");
18657
+ var UpdateBanner = () => {
18658
+ const { updates } = useApplicationState();
18659
+ const { version } = useSystemInformation();
18660
+ const { openExternalLink } = useBrowserContext();
18661
+ const [displayState, setDisplayState] = (0, import_react41.useState)();
18662
+ (0, import_react41.useEffect)(() => {
18663
+ if (updates?.type !== "loading") {
18664
+ setDisplayState(updates);
18665
+ }
18666
+ }, [updates]);
18667
+ const openDownloadLink = (0, import_react41.useCallback)(() => {
18668
+ if (displayState?.type === "updates-available" && displayState.response.downloadUrl) {
18669
+ openExternalLink(displayState.response.downloadUrl);
18670
+ }
18671
+ }, [displayState, openExternalLink]);
18672
+ if (displayState?.type === "error") {
18673
+ return /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(
18674
+ "div",
18675
+ {
18676
+ className: "\n flex items-center justify-center gap-2 border-b\n border-sigil-usage-orange-border bg-sigil-usage-orange-background p-1\n text-sigil-usage-orange-text\n ",
18677
+ children: [
18678
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(Icon2, { icon: "error" }),
18679
+ displayState.error
18680
+ ]
18681
+ }
18682
+ );
18683
+ }
18684
+ if (displayState?.type === "updates-available") {
18685
+ return /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(
18686
+ "div",
18687
+ {
18688
+ className: "\n flex items-center justify-center gap-2 border-b\n border-sigil-usage-blue-border bg-sigil-usage-blue-background p-1\n text-sigil-usage-blue-text\n ",
18689
+ children: [
18690
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(Icon2, { icon: "upgrade" }),
18691
+ STRINGS.updates.updateAvailable(
18692
+ version,
18693
+ displayState.response.latestVersion
18694
+ ),
18695
+ displayState.response.downloadUrl && /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(
18696
+ "button",
18697
+ {
18698
+ className: "\n flex cursor-pointer items-center gap-0.5 rounded-md border\n border-sigil-usage-blue-selected-border\n bg-sigil-usage-blue-selected-background px-1 py-0.5\n text-sigil-usage-blue-text\n hover:bg-sigil-usage-blue-selected-border\n ",
18699
+ onClick: openDownloadLink,
18700
+ children: [
18701
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(Icon2, { icon: "download" }),
18702
+ STRINGS.updates.download
18703
+ ]
18704
+ }
18705
+ )
18706
+ ]
18707
+ }
18708
+ );
18709
+ }
18710
+ return null;
18711
+ };
18712
+
18713
+ // src/components/frontend/toolbox/root.tsx
18714
+ var import_jsx_runtime53 = require("react/jsx-runtime");
18715
+ var ToolboxRoot = ({ info }) => {
18716
+ const { config } = info;
18717
+ const { sendMessage, call } = (0, import_react42.useContext)(StageContext);
18718
+ const [dialogMode, setDialogMode] = (0, import_react42.useState)(null);
18719
+ const [assignToOutput, setAssignToOutput] = (0, import_react42.useState)(null);
18720
+ (0, import_react42.useEffect)(() => {
18102
18721
  if (assignToOutput) {
18103
18722
  const onEscape = (e) => {
18104
18723
  if (e.key === "Escape") {
@@ -18111,7 +18730,7 @@ var ToolboxRoot = ({ info }) => {
18111
18730
  };
18112
18731
  }
18113
18732
  }, [assignToOutput]);
18114
- const updateConfig = (0, import_react38.useCallback)(
18733
+ const updateConfig = (0, import_react42.useCallback)(
18115
18734
  (change) => {
18116
18735
  const diff = diffJson(config, change(config));
18117
18736
  sendMessage?.({
@@ -18125,15 +18744,15 @@ var ToolboxRoot = ({ info }) => {
18125
18744
  },
18126
18745
  [sendMessage, info.key, config]
18127
18746
  );
18128
- const configContext = (0, import_react38.useMemo)(
18747
+ const configContext = (0, import_react42.useMemo)(
18129
18748
  () => ({
18130
18749
  config,
18131
18750
  updateConfig
18132
18751
  }),
18133
18752
  [config, updateConfig]
18134
18753
  );
18135
- const closeDialog = (0, import_react38.useCallback)(() => setDialogMode(null), []);
18136
- const getNetworkInterfaces = (0, import_react38.useCallback)(async () => {
18754
+ const closeDialog = (0, import_react42.useCallback)(() => setDialogMode(null), []);
18755
+ const getNetworkInterfaces = (0, import_react42.useCallback)(async () => {
18137
18756
  if (!call) {
18138
18757
  throw new Error("No call function available");
18139
18758
  }
@@ -18144,12 +18763,12 @@ var ToolboxRoot = ({ info }) => {
18144
18763
  action: "toolbox-root-get-network-interfaces"
18145
18764
  });
18146
18765
  }, [call, info.key]);
18147
- const networkContextValue = (0, import_react38.useMemo)(() => {
18766
+ const networkContextValue = (0, import_react42.useMemo)(() => {
18148
18767
  return {
18149
18768
  getNetworkInterfaces
18150
18769
  };
18151
18770
  }, [getNetworkInterfaces]);
18152
- const assignToOutputCallback = (0, import_react38.useMemo)(() => {
18771
+ const assignToOutputCallback = (0, import_react42.useMemo)(() => {
18153
18772
  if (!assignToOutput) {
18154
18773
  return null;
18155
18774
  }
@@ -18174,7 +18793,7 @@ var ToolboxRoot = ({ info }) => {
18174
18793
  setAssignToOutput(null);
18175
18794
  };
18176
18795
  }, [assignToOutput, updateConfig]);
18177
- const callHandler = (0, import_react38.useCallback)(
18796
+ const callHandler = (0, import_react42.useCallback)(
18178
18797
  async ({ path, handler, args }) => {
18179
18798
  if (!call) {
18180
18799
  throw new Error("No call function available");
@@ -18191,149 +18810,121 @@ var ToolboxRoot = ({ info }) => {
18191
18810
  },
18192
18811
  [call, info.key]
18193
18812
  );
18194
- const handlers = (0, import_react38.useMemo)(
18813
+ const handlers = (0, import_react42.useMemo)(
18195
18814
  () => ({
18196
18815
  handlers: info.handlers,
18197
18816
  callHandler
18198
18817
  }),
18199
18818
  [info.handlers, callHandler]
18200
18819
  );
18201
- const windowedTimecodeId = (0, import_react38.useMemo)(
18820
+ const windowedTimecodeId = (0, import_react42.useMemo)(
18202
18821
  () => getFragmentValue("tc", TIMECODE_INSTANCE_ID),
18203
18822
  []
18204
18823
  );
18205
- const isMainWindow = windowedTimecodeId === null;
18206
- const root = (0, import_react38.useMemo)(
18207
- () => /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "flex h-screen flex-col", children: [
18208
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(ToolbarWrapper, { children: /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(ToolbarRow, { children: [
18209
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
18210
- "div",
18211
- {
18212
- className: "\n flex h-full min-h-[36px] grow items-center justify-center px-1\n app-title-bar\n ",
18213
- children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { className: "font-bold text-hint-gradient", children: STRINGS.title })
18214
- }
18215
- ),
18216
- isMainWindow && /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(import_jsx_runtime48.Fragment, { children: [
18217
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(ToolbarDivider, {}),
18218
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
18219
- ControlButton,
18220
- {
18221
- onClick: () => setWindowMode(
18222
- (mode) => mode === "settings" ? null : "settings"
18824
+ const root = (0, import_react42.useMemo)(
18825
+ () => windowedTimecodeId ? /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(Layout, { modes: null, children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(FullscreenTimecodeDisplay, { id: windowedTimecodeId }) }) : /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(import_jsx_runtime53.Fragment, { children: [
18826
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
18827
+ Layout,
18828
+ {
18829
+ footer: true,
18830
+ modes: {
18831
+ license: {
18832
+ child: (setWindowMode) => /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
18833
+ License,
18834
+ {
18835
+ license: info.license,
18836
+ setWindowMode
18837
+ }
18223
18838
  ),
18224
- variant: "titlebar",
18839
+ icon: "info",
18840
+ title: STRINGS.license
18841
+ },
18842
+ settings: {
18843
+ child: (setWindowMode) => /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(Settings, { setWindowMode }),
18225
18844
  icon: "settings",
18226
- active: windowMode === "settings",
18227
- title: STRINGS.toggle(STRINGS.settings.title)
18228
- }
18229
- ),
18230
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
18231
- ControlButton,
18232
- {
18233
- onClick: () => setWindowMode((mode) => mode === "debug" ? null : "debug"),
18234
- variant: "titlebar",
18845
+ title: STRINGS.settings.title
18846
+ },
18847
+ debug: {
18848
+ child: () => /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(Debugger, { title: STRINGS.debugger, className: "size-full" }),
18235
18849
  icon: "bug_report",
18236
- active: windowMode === "debug",
18237
- title: STRINGS.toggle(STRINGS.debugger)
18850
+ title: STRINGS.debugger
18238
18851
  }
18239
- )
18240
- ] })
18241
- ] }) }),
18242
- /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "relative flex h-0 grow flex-col", children: [
18243
- connection.state !== "connected" ? /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(
18244
- SizeAwareDiv,
18245
- {
18246
- className: "\n flex grow flex-col items-center justify-center gap-1\n bg-sigil-bg-light p-1 text-sigil-foreground-muted\n ",
18247
- children: [
18248
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(Icon2, { icon: "signal_disconnected", className: "text-block-icon" }),
18249
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { className: "text-center", children: STRINGS.connectionError }),
18250
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(ControlButton, { onClick: reconnect, variant: "large", icon: "replay", children: STRINGS.reconnect })
18251
- ]
18252
- }
18253
- ) : windowMode === "debug" ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(Debugger, { title: STRINGS.debugger, className: "size-full" }) : windowMode === "settings" ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(Settings, { setWindowMode }) : windowedTimecodeId ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(FullscreenTimecodeDisplay, { id: windowedTimecodeId }) : /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(
18254
- "div",
18255
- {
18256
- className: "\n flex h-0 grow flex-col gap-px overflow-y-auto bg-sigil-border\n scrollbar-sigil\n ",
18257
- children: [
18258
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
18259
- InputsSection,
18260
- {
18261
- setDialogMode,
18262
- assignToOutput: assignToOutputCallback
18263
- }
18264
- ),
18265
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
18266
- GeneratorsSection,
18267
- {
18268
- setDialogMode,
18269
- assignToOutput: assignToOutputCallback
18270
- }
18271
- ),
18272
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
18273
- OutputsSection,
18274
- {
18275
- setDialogMode,
18276
- assignToOutput,
18277
- setAssignToOutput
18278
- }
18279
- )
18280
- ]
18281
- }
18282
- ),
18283
- dialogMode?.section.type === "inputs" && /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
18284
- InputSettingsDialog,
18285
- {
18286
- close: closeDialog,
18287
- input: dialogMode.section.input,
18288
- target: dialogMode.target
18289
- }
18290
- ),
18291
- dialogMode?.section.type === "generators" && /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
18292
- GeneratorSettingsDialog,
18293
- {
18294
- close: closeDialog,
18295
- generator: dialogMode.section.generator,
18296
- target: dialogMode.target
18297
- }
18298
- ),
18299
- dialogMode?.section.type === "outputs" && /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
18300
- OutputSettingsDialog,
18301
- {
18302
- close: closeDialog,
18303
- output: dialogMode.section.output,
18304
- target: dialogMode.target
18305
- }
18306
- )
18307
- ] }),
18308
- isMainWindow && /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(
18309
- "div",
18852
+ },
18853
+ licenseMode: "license",
18854
+ children: /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(import_jsx_runtime53.Fragment, { children: [
18855
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(UpdateBanner, {}),
18856
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(
18857
+ "div",
18858
+ {
18859
+ className: "\n flex h-0 grow flex-col gap-px overflow-y-auto bg-sigil-border\n scrollbar-sigil\n ",
18860
+ children: [
18861
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
18862
+ InputsSection,
18863
+ {
18864
+ setDialogMode,
18865
+ assignToOutput: assignToOutputCallback
18866
+ }
18867
+ ),
18868
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
18869
+ GeneratorsSection,
18870
+ {
18871
+ setDialogMode,
18872
+ assignToOutput: assignToOutputCallback
18873
+ }
18874
+ ),
18875
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
18876
+ OutputsSection,
18877
+ {
18878
+ setDialogMode,
18879
+ assignToOutput,
18880
+ setAssignToOutput
18881
+ }
18882
+ )
18883
+ ]
18884
+ }
18885
+ )
18886
+ ] })
18887
+ }
18888
+ ),
18889
+ dialogMode?.section.type === "inputs" && /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
18890
+ InputSettingsDialog,
18310
18891
  {
18311
- className: "\n flex justify-center border-t border-sigil-border bg-sigil-bg-dark\n p-1 text-[80%]\n ",
18312
- children: [
18313
- "Created by",
18314
- "\xA0",
18315
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(ExternalLink, { href: "https://arcanewizards.com", children: "Arcane Wizards" })
18316
- ]
18892
+ close: closeDialog,
18893
+ input: dialogMode.section.input,
18894
+ target: dialogMode.target
18895
+ }
18896
+ ),
18897
+ dialogMode?.section.type === "generators" && /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
18898
+ GeneratorSettingsDialog,
18899
+ {
18900
+ close: closeDialog,
18901
+ generator: dialogMode.section.generator,
18902
+ target: dialogMode.target
18903
+ }
18904
+ ),
18905
+ dialogMode?.section.type === "outputs" && /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
18906
+ OutputSettingsDialog,
18907
+ {
18908
+ close: closeDialog,
18909
+ output: dialogMode.section.output,
18910
+ target: dialogMode.target
18317
18911
  }
18318
18912
  )
18319
18913
  ] }),
18320
18914
  [
18321
- connection,
18322
- reconnect,
18323
18915
  assignToOutput,
18324
18916
  assignToOutputCallback,
18325
18917
  closeDialog,
18326
18918
  dialogMode,
18327
- windowMode,
18328
- isMainWindow,
18329
- windowedTimecodeId
18919
+ windowedTimecodeId,
18920
+ info.license
18330
18921
  ]
18331
18922
  );
18332
- return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(ConfigContext.Provider, { value: configContext, children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(NetworkContext.Provider, { value: networkContextValue, children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(ApplicationStateContext.Provider, { value: info.state, children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(ApplicationHandlersContext.Provider, { value: handlers, children: root }) }) }) });
18923
+ return /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(ConfigContext.Provider, { value: configContext, children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(NetworkContext.Provider, { value: networkContextValue, children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(ApplicationStateContext.Provider, { value: info.state, children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(ApplicationHandlersContext.Provider, { value: handlers, children: root }) }) }) });
18333
18924
  };
18334
18925
 
18335
18926
  // src/components/frontend/index.tsx
18336
- var import_jsx_runtime49 = require("react/jsx-runtime");
18927
+ var import_jsx_runtime54 = require("react/jsx-runtime");
18337
18928
  var timecodeToolboxFrontendComponents = () => ({
18338
18929
  namespace: NAMESPACE,
18339
18930
  render: (info) => {
@@ -18342,7 +18933,9 @@ var timecodeToolboxFrontendComponents = () => ({
18342
18933
  }
18343
18934
  switch (info.component) {
18344
18935
  case "toolbox-root":
18345
- return /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(ToolboxRoot, { info });
18936
+ return /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(ToolboxRoot, { info });
18937
+ case "license-gate":
18938
+ return /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(LicenseGate, { info });
18346
18939
  }
18347
18940
  }
18348
18941
  });
@@ -18350,7 +18943,7 @@ var startTimecodeToolboxServerFrontend = (browser) => {
18350
18943
  startSigilFrontend({
18351
18944
  browser,
18352
18945
  appRenderers: [timecodeToolboxFrontendComponents()],
18353
- loadingState: () => /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { style: { width: "100%", textAlign: "center", padding: "2rem" }, children: "Loading Toolbox..." })
18946
+ loadingState: () => /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("div", { style: { width: "100%", textAlign: "center", padding: "2rem" }, children: "Loading Toolbox..." })
18354
18947
  });
18355
18948
  };
18356
18949
  window.startTimecodeToolboxServerFrontend = startTimecodeToolboxServerFrontend;