@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
@@ -13982,7 +13982,7 @@ function cnd(condition, truthyClassName, falseyClassName) {
13982
13982
  return condition ? truthyClassName : falseyClassName;
13983
13983
  }
13984
13984
 
13985
- // ../../packages/sigil/dist/chunk-XAK7WC3D.js
13985
+ // ../../packages/sigil/dist/chunk-HF7IIHPE.js
13986
13986
  import {
13987
13987
  createContext as createContext6,
13988
13988
  forwardRef as forwardRef42,
@@ -14026,7 +14026,7 @@ var TRANSPARENCY_SVG = `
14026
14026
  `;
14027
14027
  var TRANSPARENCY_SVG_URI = `data:image/svg+xml,${encodeURIComponent(TRANSPARENCY_SVG)}`;
14028
14028
 
14029
- // ../../packages/sigil/dist/chunk-XAK7WC3D.js
14029
+ // ../../packages/sigil/dist/chunk-HF7IIHPE.js
14030
14030
  import {
14031
14031
  forwardRef as forwardRef15
14032
14032
  } from "react";
@@ -14098,7 +14098,8 @@ var clsControlButton = ({
14098
14098
  active,
14099
14099
  touching,
14100
14100
  position,
14101
- className
14101
+ className,
14102
+ primary
14102
14103
  }) => cn(
14103
14104
  `sigil-control-button`,
14104
14105
  cnd(variant === "border", `sigil-control-button-variant-border`),
@@ -14110,6 +14111,7 @@ var clsControlButton = ({
14110
14111
  cnd(touching, `sigil-control-button-touching`),
14111
14112
  cnd(active, `sigil-control-button-active`),
14112
14113
  cnd(touching && active, `sigil-control-button-active-touching`),
14114
+ cnd(primary, `sigil-control-button-primary`),
14113
14115
  clsControlPosition(position),
14114
14116
  className
14115
14117
  );
@@ -14126,6 +14128,7 @@ var ControlButtonFrame = forwardRef15(
14126
14128
  title,
14127
14129
  tooltipSide,
14128
14130
  position,
14131
+ primary,
14129
14132
  ...props
14130
14133
  }, ref) => {
14131
14134
  const btn = /* @__PURE__ */ jsx17(
@@ -14140,6 +14143,7 @@ var ControlButtonFrame = forwardRef15(
14140
14143
  active,
14141
14144
  touching,
14142
14145
  position,
14146
+ primary,
14143
14147
  className
14144
14148
  }),
14145
14149
  children: /* @__PURE__ */ jsxs4("span", { children: [
@@ -15911,7 +15915,12 @@ var OUTPUT_CONFIG = zod_default.object({
15911
15915
  var TOOLBOX_CONFIG = zod_default.object({
15912
15916
  inputs: zod_default.record(zod_default.string(), INPUT_CONFIG),
15913
15917
  generators: zod_default.record(zod_default.string(), GENERATOR_CONFIG),
15914
- outputs: zod_default.record(zod_default.string(), OUTPUT_CONFIG)
15918
+ outputs: zod_default.record(zod_default.string(), OUTPUT_CONFIG),
15919
+ /**
15920
+ * Hash of the license the user has agreed to.
15921
+ */
15922
+ agreedToLicense: zod_default.string().optional(),
15923
+ checkForUpdates: zod_default.boolean().optional().default(true)
15915
15924
  });
15916
15925
  var isTimecodeInstance = (instance) => instance !== null && "state" in instance && "metadata" in instance;
15917
15926
  var isTimecodeGroup = (instance) => instance !== null && "timecodes" in instance;
@@ -15920,89 +15929,13 @@ var isTimecodeToolboxComponent = (component) => component.namespace === NAMESPAC
15920
15929
 
15921
15930
  // src/components/frontend/toolbox/root.tsx
15922
15931
  import {
15923
- useCallback as useCallback18,
15924
- useContext as useContext13,
15925
- useEffect as useEffect30,
15932
+ useCallback as useCallback20,
15933
+ useContext as useContext16,
15934
+ useEffect as useEffect31,
15926
15935
  useMemo as useMemo15,
15927
- useState as useState29
15936
+ useState as useState31
15928
15937
  } from "react";
15929
15938
 
15930
- // src/components/frontend/toolbox/core/size-aware-div.tsx
15931
- import { useEffect as useEffect25, useState as useState23 } from "react";
15932
- import { jsx as jsx20 } from "react/jsx-runtime";
15933
- var SizeAwareDiv = ({
15934
- children,
15935
- style,
15936
- ...rest
15937
- }) => {
15938
- const [div, setDiv] = useState23(null);
15939
- const [rect, setRect] = useState23(null);
15940
- useEffect25(() => {
15941
- if (!div) {
15942
- return;
15943
- }
15944
- const resizeObserver = new ResizeObserver((entries) => {
15945
- for (const entry of entries) {
15946
- setRect(entry.contentRect);
15947
- }
15948
- });
15949
- resizeObserver.observe(div);
15950
- return () => {
15951
- resizeObserver.disconnect();
15952
- };
15953
- }, [div]);
15954
- return /* @__PURE__ */ jsx20(
15955
- "div",
15956
- {
15957
- ref: setDiv,
15958
- ...rest,
15959
- style: {
15960
- ...style,
15961
- ...rect && cssVariables({
15962
- "--size-aware-div-width": rect.width + "px",
15963
- "--size-aware-div-height": rect.height + "px"
15964
- })
15965
- },
15966
- children
15967
- }
15968
- );
15969
- };
15970
-
15971
- // src/components/frontend/toolbox/content.tsx
15972
- import { jsx as jsx21, jsxs as jsxs8 } from "react/jsx-runtime";
15973
- var ExternalLink = ({
15974
- href,
15975
- children
15976
- }) => {
15977
- const { openExternalLink } = useBrowserContext();
15978
- return /* @__PURE__ */ jsx21(
15979
- "a",
15980
- {
15981
- href,
15982
- target: "_blank",
15983
- rel: "noopener noreferrer",
15984
- onClick: (e) => {
15985
- e.preventDefault();
15986
- openExternalLink(href);
15987
- },
15988
- className: "\n text-sigil-usage-hint-foreground no-underline\n hover:underline\n ",
15989
- children
15990
- }
15991
- );
15992
- };
15993
- var NoToolboxChildren = ({ text }) => {
15994
- return /* @__PURE__ */ jsxs8(
15995
- SizeAwareDiv,
15996
- {
15997
- className: "\n flex grow flex-col items-center justify-center gap-1 bg-sigil-bg-light\n p-1 text-sigil-foreground-muted\n ",
15998
- children: [
15999
- /* @__PURE__ */ jsx21(Icon2, { icon: "handyman", className: "text-block-icon" }),
16000
- /* @__PURE__ */ jsx21("div", { className: "text-center", children: text })
16001
- ]
16002
- }
16003
- );
16004
- };
16005
-
16006
15939
  // ../../packages/artnet/dist/chunk-J2HDMITA.js
16007
15940
  var ARTNET_PORT = 6454;
16008
15941
  var TIMECODE_FPS = {
@@ -16018,6 +15951,7 @@ var MS_FORMAT = new Intl.NumberFormat(void 0, {
16018
15951
  unit: "millisecond",
16019
15952
  maximumFractionDigits: 0
16020
15953
  });
15954
+ var SOURCE_CODE_URL = "https://github.com/ArcaneWizards/open-source/tree/main/apps/timecode-toolbox";
16021
15955
  var STRINGS = {
16022
15956
  title: "Timecode Toolbox",
16023
15957
  debugger: "Debug Tools & Log",
@@ -16026,6 +15960,10 @@ var STRINGS = {
16026
15960
  openInNewWindow: "Open in new window",
16027
15961
  toggle: (text) => `Toggle ${text}`,
16028
15962
  close: (text) => `Close ${text}`,
15963
+ license: "License & About",
15964
+ acceptLicense: "Accept License",
15965
+ licensePrompt: "Please review and accept the license to use Timecode Toolbox",
15966
+ sourceCode: "Source Code",
16029
15967
  protocols: {
16030
15968
  artnet: {
16031
15969
  short: "ArtNet",
@@ -16085,6 +16023,17 @@ var STRINGS = {
16085
16023
  },
16086
16024
  errors: {
16087
16025
  unknownTimecodeID: "Unknown timecode ID, please close the window"
16026
+ },
16027
+ updates: {
16028
+ updateAvailable: (current, latest) => `Version ${latest} is available! You are currently on version ${current}.`,
16029
+ download: "Download",
16030
+ settingsLabel: "Automatically check for updates",
16031
+ settingsDetails: `When enabled, the app will automatically check for updates periodically and display a message when a new version is available.`,
16032
+ lastChecked: (time) => `Last checked: ${time}`
16033
+ },
16034
+ general: {
16035
+ enabled: "Enabled",
16036
+ disabled: "Disabled"
16088
16037
  }
16089
16038
  };
16090
16039
 
@@ -16098,23 +16047,23 @@ import {
16098
16047
  } from "react";
16099
16048
 
16100
16049
  // src/components/frontend/toolbox/util.tsx
16101
- import { jsx as jsx26, jsxs as jsxs9 } from "react/jsx-runtime";
16050
+ import { jsx as jsx20, jsxs as jsxs8 } from "react/jsx-runtime";
16102
16051
  var PrimaryToolboxSection = ({
16103
16052
  title,
16104
16053
  children,
16105
16054
  buttons
16106
16055
  }) => {
16107
- return /* @__PURE__ */ jsxs9("div", { className: "flex grow gap-px", children: [
16108
- /* @__PURE__ */ jsx26(
16056
+ return /* @__PURE__ */ jsxs8("div", { className: "flex grow gap-px", children: [
16057
+ /* @__PURE__ */ jsx20(
16109
16058
  "div",
16110
16059
  {
16111
16060
  className: "\n flex items-center justify-center bg-sigil-bg-light p-1\n writing-mode-vertical-rl\n ",
16112
16061
  children: title
16113
16062
  }
16114
16063
  ),
16115
- /* @__PURE__ */ jsxs9("div", { className: "flex grow flex-col gap-px", children: [
16116
- /* @__PURE__ */ jsx26("div", { className: "flex grow flex-col gap-px", children }),
16117
- /* @__PURE__ */ jsx26("div", { className: "flex w-full flex-wrap gap-1 bg-sigil-bg-light p-1", children: buttons })
16064
+ /* @__PURE__ */ jsxs8("div", { className: "flex grow flex-col gap-px", children: [
16065
+ /* @__PURE__ */ jsx20("div", { className: "flex grow flex-col gap-px", children }),
16066
+ /* @__PURE__ */ jsx20("div", { className: "flex w-full flex-wrap gap-1 bg-sigil-bg-light p-1", children: buttons })
16118
16067
  ] })
16119
16068
  ] });
16120
16069
  };
@@ -16175,6 +16124,47 @@ import {
16175
16124
  useState as useState24
16176
16125
  } from "react";
16177
16126
 
16127
+ // src/components/frontend/toolbox/core/size-aware-div.tsx
16128
+ import { useEffect as useEffect25, useState as useState23 } from "react";
16129
+ import { jsx as jsx21 } from "react/jsx-runtime";
16130
+ var SizeAwareDiv = ({
16131
+ children,
16132
+ style,
16133
+ ...rest
16134
+ }) => {
16135
+ const [div, setDiv] = useState23(null);
16136
+ const [rect, setRect] = useState23(null);
16137
+ useEffect25(() => {
16138
+ if (!div) {
16139
+ return;
16140
+ }
16141
+ const resizeObserver = new ResizeObserver((entries) => {
16142
+ for (const entry of entries) {
16143
+ setRect(entry.contentRect);
16144
+ }
16145
+ });
16146
+ resizeObserver.observe(div);
16147
+ return () => {
16148
+ resizeObserver.disconnect();
16149
+ };
16150
+ }, [div]);
16151
+ return /* @__PURE__ */ jsx21(
16152
+ "div",
16153
+ {
16154
+ ref: setDiv,
16155
+ ...rest,
16156
+ style: {
16157
+ ...style,
16158
+ ...rect && cssVariables({
16159
+ "--size-aware-div-width": rect.width + "px",
16160
+ "--size-aware-div-height": rect.height + "px"
16161
+ })
16162
+ },
16163
+ children
16164
+ }
16165
+ );
16166
+ };
16167
+
16178
16168
  // src/tree.ts
16179
16169
  var isTreeNode = (node) => "children" in node && typeof node.children === "object" && node.children !== null;
16180
16170
  var getTreeValue = (current, path) => {
@@ -16280,7 +16270,7 @@ var augmentUpstreamTimecodeWithOutputMetadata = (tc, config) => {
16280
16270
  };
16281
16271
 
16282
16272
  // src/components/frontend/toolbox/core/timecode-display.tsx
16283
- import { Fragment as Fragment8, jsx as jsx27, jsxs as jsxs10 } from "react/jsx-runtime";
16273
+ import { Fragment as Fragment8, jsx as jsx26, jsxs as jsxs9 } from "react/jsx-runtime";
16284
16274
  var ActiveTimecodeText = ({
16285
16275
  effectiveStartTimeMillis,
16286
16276
  speed
@@ -16328,7 +16318,7 @@ var Timeline2 = ({ state, totalTime }) => {
16328
16318
  }
16329
16319
  };
16330
16320
  }, [state, timeDifferenceMs]);
16331
- return /* @__PURE__ */ jsx27("div", { className: "w-full border border-timecode-usage-foreground p-px", children: /* @__PURE__ */ jsx27("div", { className: "relative h-1 w-full overflow-hidden", children: /* @__PURE__ */ jsx27(
16321
+ return /* @__PURE__ */ jsx26("div", { className: "w-full border border-timecode-usage-foreground p-px", children: /* @__PURE__ */ jsx26("div", { className: "relative h-1 w-full overflow-hidden", children: /* @__PURE__ */ jsx26(
16332
16322
  "div",
16333
16323
  {
16334
16324
  className: "absolute inset-y-0 left-0 bg-timecode-usage-foreground",
@@ -16380,8 +16370,8 @@ var TimecodeDisplay = ({
16380
16370
  }
16381
16371
  }
16382
16372
  }, [hooks, play, pause, state.state]);
16383
- return /* @__PURE__ */ jsxs10("div", { className: "flex grow flex-col gap-px", children: [
16384
- /* @__PURE__ */ jsxs10(
16373
+ return /* @__PURE__ */ jsxs9("div", { className: "flex grow flex-col gap-px", children: [
16374
+ /* @__PURE__ */ jsxs9(
16385
16375
  "div",
16386
16376
  {
16387
16377
  className: cn(
@@ -16393,8 +16383,8 @@ var TimecodeDisplay = ({
16393
16383
  )
16394
16384
  ),
16395
16385
  children: [
16396
- headerComponents && /* @__PURE__ */ jsx27("div", { className: "flex flex-wrap gap-0.25", children: headerComponents }),
16397
- /* @__PURE__ */ jsx27(
16386
+ headerComponents && /* @__PURE__ */ jsx26("div", { className: "flex flex-wrap gap-0.25", children: headerComponents }),
16387
+ /* @__PURE__ */ jsx26(
16398
16388
  SizeAwareDiv,
16399
16389
  {
16400
16390
  className: cn(
@@ -16409,7 +16399,7 @@ var TimecodeDisplay = ({
16409
16399
  )
16410
16400
  ),
16411
16401
  onClick: toggle,
16412
- children: /* @__PURE__ */ jsx27("div", { className: "absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ jsx27("span", { className: cn("font-mono text-timecode-adaptive"), children: state.state === "none" ? "--:--:--:---" : state.state === "stopped" ? displayMillis(state.positionMillis) : /* @__PURE__ */ jsx27(
16402
+ children: /* @__PURE__ */ jsx26("div", { className: "absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ jsx26("span", { className: cn("font-mono text-timecode-adaptive"), children: state.state === "none" ? "--:--:--:---" : state.state === "stopped" ? displayMillis(state.positionMillis) : /* @__PURE__ */ jsx26(
16413
16403
  ActiveTimecodeText,
16414
16404
  {
16415
16405
  effectiveStartTimeMillis: state.effectiveStartTimeMillis,
@@ -16418,8 +16408,8 @@ var TimecodeDisplay = ({
16418
16408
  ) }) })
16419
16409
  }
16420
16410
  ),
16421
- hooks?.pause || hooks?.play ? /* @__PURE__ */ jsxs10("div", { className: "flex justify-center gap-px", children: [
16422
- hooks.beginning && /* @__PURE__ */ jsx27(
16411
+ hooks?.pause || hooks?.play ? /* @__PURE__ */ jsxs9("div", { className: "flex justify-center gap-px", children: [
16412
+ hooks.beginning && /* @__PURE__ */ jsx26(
16423
16413
  ControlButton,
16424
16414
  {
16425
16415
  onClick: beginning,
@@ -16430,7 +16420,7 @@ var TimecodeDisplay = ({
16430
16420
  className: "text-timecode-usage-foreground!"
16431
16421
  }
16432
16422
  ),
16433
- hooks.seekRelative && /* @__PURE__ */ jsx27(
16423
+ hooks.seekRelative && /* @__PURE__ */ jsx26(
16434
16424
  ControlButton,
16435
16425
  {
16436
16426
  onClick: back5seconds,
@@ -16441,7 +16431,7 @@ var TimecodeDisplay = ({
16441
16431
  className: "text-timecode-usage-foreground!"
16442
16432
  }
16443
16433
  ),
16444
- state.state === "none" || state.state === "stopped" ? /* @__PURE__ */ jsx27(
16434
+ state.state === "none" || state.state === "stopped" ? /* @__PURE__ */ jsx26(
16445
16435
  ControlButton,
16446
16436
  {
16447
16437
  onClick: play,
@@ -16451,7 +16441,7 @@ var TimecodeDisplay = ({
16451
16441
  title: STRINGS.controls.play,
16452
16442
  className: "text-timecode-usage-foreground!"
16453
16443
  }
16454
- ) : /* @__PURE__ */ jsx27(
16444
+ ) : /* @__PURE__ */ jsx26(
16455
16445
  ControlButton,
16456
16446
  {
16457
16447
  onClick: pause,
@@ -16462,7 +16452,7 @@ var TimecodeDisplay = ({
16462
16452
  className: "text-timecode-usage-foreground!"
16463
16453
  }
16464
16454
  ),
16465
- hooks.seekRelative && /* @__PURE__ */ jsx27(
16455
+ hooks.seekRelative && /* @__PURE__ */ jsx26(
16466
16456
  ControlButton,
16467
16457
  {
16468
16458
  onClick: forward5seconds,
@@ -16474,33 +16464,33 @@ var TimecodeDisplay = ({
16474
16464
  }
16475
16465
  )
16476
16466
  ] }) : null,
16477
- metadata?.totalTime && /* @__PURE__ */ jsx27(Timeline2, { state, totalTime: metadata.totalTime })
16467
+ metadata?.totalTime && /* @__PURE__ */ jsx26(Timeline2, { state, totalTime: metadata.totalTime })
16478
16468
  ]
16479
16469
  }
16480
16470
  ),
16481
- (state.smpteMode !== null || state.accuracyMillis !== null || config.delayMs !== null) && /* @__PURE__ */ jsxs10("div", { className: "flex gap-px", children: [
16482
- config.delayMs !== null && /* @__PURE__ */ jsx27("div", { className: "grow basis-0 truncate bg-sigil-bg-light p-0.5", children: STRINGS.delay(config.delayMs) }),
16483
- state.smpteMode !== null && /* @__PURE__ */ jsx27("div", { className: "grow basis-0 truncate bg-sigil-bg-light p-0.5", children: STRINGS.smtpeModes[state.smpteMode] }),
16484
- state.accuracyMillis !== null && /* @__PURE__ */ jsx27("div", { className: "grow basis-0 truncate bg-sigil-bg-light p-0.5", children: STRINGS.accuracy(state.accuracyMillis) })
16471
+ (state.smpteMode !== null || state.accuracyMillis !== null || config.delayMs !== null) && /* @__PURE__ */ jsxs9("div", { className: "flex gap-px", children: [
16472
+ config.delayMs !== null && /* @__PURE__ */ jsx26("div", { className: "grow basis-0 truncate bg-sigil-bg-light p-0.5", children: STRINGS.delay(config.delayMs) }),
16473
+ state.smpteMode !== null && /* @__PURE__ */ jsx26("div", { className: "grow basis-0 truncate bg-sigil-bg-light p-0.5", children: STRINGS.smtpeModes[state.smpteMode] }),
16474
+ state.accuracyMillis !== null && /* @__PURE__ */ jsx26("div", { className: "grow basis-0 truncate bg-sigil-bg-light p-0.5", children: STRINGS.accuracy(state.accuracyMillis) })
16485
16475
  ] }),
16486
- metadata?.artist || metadata?.title ? /* @__PURE__ */ jsx27(
16476
+ metadata?.artist || metadata?.title ? /* @__PURE__ */ jsx26(
16487
16477
  TooltipWrapper,
16488
16478
  {
16489
- tooltip: /* @__PURE__ */ jsxs10(Fragment8, { children: [
16490
- metadata.title && /* @__PURE__ */ jsxs10("div", { children: [
16491
- /* @__PURE__ */ jsx27("span", { className: "font-bold", children: "Title:" }),
16479
+ tooltip: /* @__PURE__ */ jsxs9(Fragment8, { children: [
16480
+ metadata.title && /* @__PURE__ */ jsxs9("div", { children: [
16481
+ /* @__PURE__ */ jsx26("span", { className: "font-bold", children: "Title:" }),
16492
16482
  " ",
16493
16483
  metadata.title
16494
16484
  ] }),
16495
- metadata.artist && /* @__PURE__ */ jsxs10("div", { children: [
16496
- /* @__PURE__ */ jsx27("span", { className: "font-bold", children: "Artist:" }),
16485
+ metadata.artist && /* @__PURE__ */ jsxs9("div", { children: [
16486
+ /* @__PURE__ */ jsx26("span", { className: "font-bold", children: "Artist:" }),
16497
16487
  " ",
16498
16488
  metadata.artist
16499
16489
  ] })
16500
16490
  ] }),
16501
- children: /* @__PURE__ */ jsxs10("div", { className: "flex gap-px", children: [
16502
- metadata.title && /* @__PURE__ */ jsx27("div", { className: "grow truncate bg-sigil-bg-light p-0.5 font-bold", children: metadata.title }),
16503
- metadata.artist && /* @__PURE__ */ jsx27("div", { className: "grow truncate bg-sigil-bg-light p-0.5", children: metadata.artist })
16491
+ children: /* @__PURE__ */ jsxs9("div", { className: "flex gap-px", children: [
16492
+ metadata.title && /* @__PURE__ */ jsx26("div", { className: "grow truncate bg-sigil-bg-light p-0.5 font-bold", children: metadata.title }),
16493
+ metadata.artist && /* @__PURE__ */ jsx26("div", { className: "grow truncate bg-sigil-bg-light p-0.5", children: metadata.artist })
16504
16494
  ] })
16505
16495
  }
16506
16496
  ) : null
@@ -16541,7 +16531,7 @@ var TimecodeTreeDisplay = ({
16541
16531
  }, [id, openNewWidow]);
16542
16532
  name = timecode?.name ? [...name, timecode.name] : name;
16543
16533
  if (isTimecodeGroup(timecode) && Object.values(timecode.timecodes).length) {
16544
- return Object.entries(timecode.timecodes).map(([key, child]) => /* @__PURE__ */ jsx27(
16534
+ return Object.entries(timecode.timecodes).map(([key, child]) => /* @__PURE__ */ jsx26(
16545
16535
  TimecodeTreeDisplay,
16546
16536
  {
16547
16537
  config,
@@ -16557,28 +16547,28 @@ var TimecodeTreeDisplay = ({
16557
16547
  key
16558
16548
  ));
16559
16549
  }
16560
- return /* @__PURE__ */ jsxs10(
16550
+ return /* @__PURE__ */ jsxs9(
16561
16551
  "div",
16562
16552
  {
16563
16553
  className: "relative flex grow flex-col text-timecode-usage-foreground",
16564
16554
  style: color && cssSigilColorUsageVariables("timecode-usage", sigilColorUsage(color)),
16565
16555
  children: [
16566
- /* @__PURE__ */ jsx27(
16556
+ /* @__PURE__ */ jsx26(
16567
16557
  TimecodeDisplay,
16568
16558
  {
16569
16559
  id,
16570
16560
  timecode: isTimecodeInstance(timecode) ? timecode : EMPTY_TIMECODE,
16571
16561
  config,
16572
- headerComponents: /* @__PURE__ */ jsxs10(Fragment8, { children: [
16573
- /* @__PURE__ */ jsxs10("div", { className: "flex grow items-start gap-0.25", children: [
16574
- /* @__PURE__ */ jsx27(
16562
+ headerComponents: /* @__PURE__ */ jsxs9(Fragment8, { children: [
16563
+ /* @__PURE__ */ jsxs9("div", { className: "flex grow items-start gap-0.25", children: [
16564
+ /* @__PURE__ */ jsx26(
16575
16565
  "div",
16576
16566
  {
16577
16567
  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 ",
16578
16568
  children: type
16579
16569
  }
16580
16570
  ),
16581
- /* @__PURE__ */ jsx27(
16571
+ /* @__PURE__ */ jsx26(
16582
16572
  "div",
16583
16573
  {
16584
16574
  className: cn(
@@ -16589,8 +16579,8 @@ var TimecodeTreeDisplay = ({
16589
16579
  }
16590
16580
  )
16591
16581
  ] }),
16592
- /* @__PURE__ */ jsxs10(ControlButtonGroup, { className: "rounded-md bg-sigil-bg-light", children: [
16593
- /* @__PURE__ */ jsx27(
16582
+ /* @__PURE__ */ jsxs9(ControlButtonGroup, { className: "rounded-md bg-sigil-bg-light", children: [
16583
+ /* @__PURE__ */ jsx26(
16594
16584
  ControlButton,
16595
16585
  {
16596
16586
  variant: "toolbar",
@@ -16604,12 +16594,12 @@ var TimecodeTreeDisplay = ({
16604
16594
  ] })
16605
16595
  }
16606
16596
  ),
16607
- assignToOutput && id && !isOutputInstanceId(id) && /* @__PURE__ */ jsx27(
16597
+ assignToOutput && id && !isOutputInstanceId(id) && /* @__PURE__ */ jsx26(
16608
16598
  SizeAwareDiv,
16609
16599
  {
16610
16600
  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 ",
16611
16601
  onClick: () => assignToOutput(id),
16612
- children: /* @__PURE__ */ jsx27(Icon2, { icon: "link", className: "text-block-icon" })
16602
+ children: /* @__PURE__ */ jsx26(Icon2, { icon: "link", className: "text-block-icon" })
16613
16603
  }
16614
16604
  )
16615
16605
  ]
@@ -16675,22 +16665,22 @@ var FullscreenTimecodeDisplay = ({
16675
16665
  }
16676
16666
  }, [id, config]);
16677
16667
  if (!instanceConfig) {
16678
- return /* @__PURE__ */ jsxs10(
16668
+ return /* @__PURE__ */ jsxs9(
16679
16669
  SizeAwareDiv,
16680
16670
  {
16681
16671
  className: "\n flex grow flex-col items-center justify-center gap-1 bg-sigil-bg-light\n p-1 text-sigil-foreground-muted\n ",
16682
16672
  children: [
16683
- /* @__PURE__ */ jsx27(Icon2, { icon: "question_mark", className: "text-block-icon" }),
16684
- /* @__PURE__ */ jsx27("div", { className: "text-center", children: STRINGS.errors.unknownTimecodeID })
16673
+ /* @__PURE__ */ jsx26(Icon2, { icon: "question_mark", className: "text-block-icon" }),
16674
+ /* @__PURE__ */ jsx26("div", { className: "text-center", children: STRINGS.errors.unknownTimecodeID })
16685
16675
  ]
16686
16676
  }
16687
16677
  );
16688
16678
  }
16689
- return /* @__PURE__ */ jsx27(
16679
+ return /* @__PURE__ */ jsx26(
16690
16680
  "div",
16691
16681
  {
16692
16682
  className: "\n flex h-0 grow flex-col gap-px overflow-y-auto bg-sigil-border\n scrollbar-sigil\n ",
16693
- children: /* @__PURE__ */ jsx27(
16683
+ children: /* @__PURE__ */ jsx26(
16694
16684
  TimecodeTreeDisplay,
16695
16685
  {
16696
16686
  id,
@@ -16755,6 +16745,54 @@ function v4(options, buf, offset4) {
16755
16745
  }
16756
16746
  var v4_default = v4;
16757
16747
 
16748
+ // src/components/frontend/toolbox/content.tsx
16749
+ import { jsx as jsx27, jsxs as jsxs10 } from "react/jsx-runtime";
16750
+ var ExternalLink = ({
16751
+ href,
16752
+ children
16753
+ }) => {
16754
+ const { openExternalLink } = useBrowserContext();
16755
+ return /* @__PURE__ */ jsx27(
16756
+ "a",
16757
+ {
16758
+ href,
16759
+ target: "_blank",
16760
+ rel: "noopener noreferrer",
16761
+ onClick: (e) => {
16762
+ e.preventDefault();
16763
+ openExternalLink(href);
16764
+ },
16765
+ className: "\n text-sigil-usage-hint-foreground no-underline\n hover:underline\n ",
16766
+ children
16767
+ }
16768
+ );
16769
+ };
16770
+ var TextButton = ({
16771
+ onClick,
16772
+ children
16773
+ }) => {
16774
+ return /* @__PURE__ */ jsx27(
16775
+ "span",
16776
+ {
16777
+ onClick,
16778
+ className: "\n cursor-pointer text-sigil-usage-hint-foreground\n hover:underline\n ",
16779
+ children
16780
+ }
16781
+ );
16782
+ };
16783
+ var NoToolboxChildren = ({ text }) => {
16784
+ return /* @__PURE__ */ jsxs10(
16785
+ SizeAwareDiv,
16786
+ {
16787
+ className: "\n flex grow flex-col items-center justify-center gap-1 bg-sigil-bg-light\n p-1 text-sigil-foreground-muted\n ",
16788
+ children: [
16789
+ /* @__PURE__ */ jsx27(Icon2, { icon: "handyman", className: "text-block-icon" }),
16790
+ /* @__PURE__ */ jsx27("div", { className: "text-center", children: text })
16791
+ ]
16792
+ }
16793
+ );
16794
+ };
16795
+
16758
16796
  // src/components/frontend/toolbox/outputs.tsx
16759
16797
  import { Fragment as Fragment9, jsx as jsx28, jsxs as jsxs11 } from "react/jsx-runtime";
16760
16798
  var DmxConnectionSettings = ({
@@ -17946,6 +17984,9 @@ var diffJson = (a, b) => {
17946
17984
  return { type: "value", after: b };
17947
17985
  };
17948
17986
 
17987
+ // src/components/frontend/toolbox/settings.tsx
17988
+ import { useContext as useContext13 } from "react";
17989
+
17949
17990
  // ../../packages/sigil/dist/frontend/appearance.js
17950
17991
  import { useCallback as useCallback17 } from "react";
17951
17992
  import { jsx as jsx31, jsxs as jsxs14 } from "react/jsx-runtime";
@@ -18090,8 +18131,17 @@ var useBrowserPreferences = createBrowserPreferencesHook(TOOLBOX_PREFERENCES);
18090
18131
 
18091
18132
  // src/components/frontend/toolbox/settings.tsx
18092
18133
  import { jsx as jsx35, jsxs as jsxs15 } from "react/jsx-runtime";
18134
+ var ENABLED_DISABLED_OPTIONS = [
18135
+ { value: "enabled", label: STRINGS.general.enabled },
18136
+ { value: "disabled", label: STRINGS.general.disabled }
18137
+ ];
18138
+ var DATE_FORMATTER = new Intl.DateTimeFormat(void 0, {
18139
+ timeStyle: "medium"
18140
+ });
18093
18141
  var Settings = ({ setWindowMode }) => {
18094
18142
  const { preferences, updateBrowserPrefs } = useBrowserPreferences();
18143
+ const { config, updateConfig } = useContext13(ConfigContext);
18144
+ const { updates } = useApplicationState();
18095
18145
  return /* @__PURE__ */ jsxs15("div", { className: "flex grow flex-col", children: [
18096
18146
  /* @__PURE__ */ jsx35(ToolbarWrapper, { children: /* @__PURE__ */ jsxs15(ToolbarRow, { children: [
18097
18147
  /* @__PURE__ */ jsx35("span", { className: "grow p-1", children: STRINGS.settings.title }),
@@ -18118,26 +18168,595 @@ var Settings = ({ setWindowMode }) => {
18118
18168
  color: preferences.color,
18119
18169
  onColorChange: (color) => updateBrowserPrefs((current) => ({ ...current, color }))
18120
18170
  }
18121
- )
18171
+ ),
18172
+ /* @__PURE__ */ jsx35(ControlLabel, { children: STRINGS.updates.settingsLabel }),
18173
+ /* @__PURE__ */ jsx35(
18174
+ ControlSelect,
18175
+ {
18176
+ value: config.checkForUpdates ? "enabled" : "disabled",
18177
+ options: ENABLED_DISABLED_OPTIONS,
18178
+ onChange: (value) => updateConfig((current) => ({
18179
+ ...current,
18180
+ checkForUpdates: value === "enabled"
18181
+ })),
18182
+ variant: "large"
18183
+ }
18184
+ ),
18185
+ /* @__PURE__ */ jsx35(ControlDetails, { children: STRINGS.updates.settingsDetails }),
18186
+ updates && "lastCheckedMillis" in updates && /* @__PURE__ */ jsx35(ControlDetails, { children: STRINGS.updates.lastChecked(
18187
+ DATE_FORMATTER.format(updates.lastCheckedMillis)
18188
+ ) })
18122
18189
  ] })
18123
18190
  }
18124
18191
  )
18125
18192
  ] });
18126
18193
  };
18127
18194
 
18128
- // src/components/frontend/toolbox/root.tsx
18129
- import { Fragment as Fragment12, jsx as jsx36, jsxs as jsxs16 } from "react/jsx-runtime";
18130
- var ToolboxRoot = ({ info }) => {
18131
- const [windowMode, setWindowMode] = useState29(
18132
- null
18195
+ // src/components/frontend/toolbox/license.tsx
18196
+ import { useCallback as useCallback18, useContext as useContext15 } from "react";
18197
+
18198
+ // src/components/frontend/toolbox/logo.tsx
18199
+ import { jsx as jsx36, jsxs as jsxs16 } from "react/jsx-runtime";
18200
+ var TimecodeToolboxLogo = (props) => /* @__PURE__ */ jsxs16(
18201
+ "svg",
18202
+ {
18203
+ xmlns: "http://www.w3.org/2000/svg",
18204
+ viewBox: "0 0 1365.333 1365.333",
18205
+ ...props,
18206
+ children: [
18207
+ /* @__PURE__ */ jsxs16("defs", { children: [
18208
+ /* @__PURE__ */ jsx36("mask", { id: "b", maskUnits: "userSpaceOnUse", children: /* @__PURE__ */ jsx36(
18209
+ "path",
18210
+ {
18211
+ fill: "#fff",
18212
+ "stroke-linecap": "round",
18213
+ "stroke-linejoin": "round",
18214
+ "stroke-width": "50.12",
18215
+ 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"
18216
+ }
18217
+ ) }),
18218
+ /* @__PURE__ */ jsx36("mask", { id: "g", maskUnits: "userSpaceOnUse", children: /* @__PURE__ */ jsx36(
18219
+ "path",
18220
+ {
18221
+ fill: "#fff",
18222
+ "stroke-linecap": "round",
18223
+ "stroke-linejoin": "round",
18224
+ "stroke-width": "5.581",
18225
+ 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"
18226
+ }
18227
+ ) }),
18228
+ /* @__PURE__ */ jsx36("mask", { id: "f", maskUnits: "userSpaceOnUse", children: /* @__PURE__ */ jsx36(
18229
+ "path",
18230
+ {
18231
+ fill: "#fff",
18232
+ "stroke-linecap": "round",
18233
+ "stroke-linejoin": "round",
18234
+ "stroke-width": "5.581",
18235
+ 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"
18236
+ }
18237
+ ) }),
18238
+ /* @__PURE__ */ jsx36("mask", { id: "e", maskUnits: "userSpaceOnUse", children: /* @__PURE__ */ jsx36(
18239
+ "path",
18240
+ {
18241
+ fill: "#fff",
18242
+ "stroke-linecap": "round",
18243
+ "stroke-linejoin": "round",
18244
+ "stroke-width": "5.581",
18245
+ 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"
18246
+ }
18247
+ ) }),
18248
+ /* @__PURE__ */ jsx36("mask", { id: "d", maskUnits: "userSpaceOnUse", children: /* @__PURE__ */ jsx36(
18249
+ "path",
18250
+ {
18251
+ fill: "#fff",
18252
+ "stroke-linecap": "round",
18253
+ "stroke-linejoin": "round",
18254
+ "stroke-width": "5.581",
18255
+ 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"
18256
+ }
18257
+ ) }),
18258
+ /* @__PURE__ */ jsx36("mask", { id: "c", maskUnits: "userSpaceOnUse", children: /* @__PURE__ */ jsx36(
18259
+ "path",
18260
+ {
18261
+ fill: "#fff",
18262
+ "stroke-linecap": "round",
18263
+ "stroke-linejoin": "round",
18264
+ "stroke-width": "5.581",
18265
+ 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"
18266
+ }
18267
+ ) }),
18268
+ /* @__PURE__ */ jsx36("mask", { id: "k", maskUnits: "userSpaceOnUse", children: /* @__PURE__ */ jsx36(
18269
+ "path",
18270
+ {
18271
+ fill: "#fff",
18272
+ "stroke-linecap": "round",
18273
+ "stroke-linejoin": "round",
18274
+ "stroke-width": "7.033",
18275
+ 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"
18276
+ }
18277
+ ) }),
18278
+ /* @__PURE__ */ jsx36("mask", { id: "j", maskUnits: "userSpaceOnUse", children: /* @__PURE__ */ jsx36(
18279
+ "path",
18280
+ {
18281
+ fill: "#fff",
18282
+ "stroke-linecap": "round",
18283
+ "stroke-linejoin": "round",
18284
+ "stroke-width": "7.033",
18285
+ 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"
18286
+ }
18287
+ ) }),
18288
+ /* @__PURE__ */ jsx36("mask", { id: "i", maskUnits: "userSpaceOnUse", children: /* @__PURE__ */ jsx36(
18289
+ "path",
18290
+ {
18291
+ fill: "#fff",
18292
+ "stroke-linecap": "round",
18293
+ "stroke-linejoin": "round",
18294
+ "stroke-width": "7.033",
18295
+ 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"
18296
+ }
18297
+ ) }),
18298
+ /* @__PURE__ */ jsx36("mask", { id: "h", maskUnits: "userSpaceOnUse", children: /* @__PURE__ */ jsx36(
18299
+ "path",
18300
+ {
18301
+ fill: "#fff",
18302
+ "stroke-linecap": "round",
18303
+ "stroke-linejoin": "round",
18304
+ "stroke-width": "7.033",
18305
+ 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"
18306
+ }
18307
+ ) }),
18308
+ /* @__PURE__ */ jsx36(
18309
+ "filter",
18310
+ {
18311
+ id: "a",
18312
+ width: "1.201",
18313
+ height: "1.19",
18314
+ x: "-.101",
18315
+ y: "-.074",
18316
+ "color-interpolation-filters": "sRGB",
18317
+ children: /* @__PURE__ */ jsx36("feGaussianBlur", { stdDeviation: "10.298" })
18318
+ }
18319
+ )
18320
+ ] }),
18321
+ /* @__PURE__ */ jsxs16(
18322
+ "g",
18323
+ {
18324
+ stroke: "#000",
18325
+ "stroke-linecap": "round",
18326
+ "stroke-linejoin": "round",
18327
+ filter: "url(#a)",
18328
+ opacity: ".25",
18329
+ transform: "translate(-216.03 -84.295)scale(1.10099)",
18330
+ children: [
18331
+ /* @__PURE__ */ jsx36(
18332
+ "path",
18333
+ {
18334
+ "stroke-width": "153.76517303999998",
18335
+ 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",
18336
+ opacity: "1"
18337
+ }
18338
+ ),
18339
+ /* @__PURE__ */ jsx36(
18340
+ "path",
18341
+ {
18342
+ "stroke-width": "80.096",
18343
+ 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"
18344
+ }
18345
+ ),
18346
+ /* @__PURE__ */ jsx36(
18347
+ "path",
18348
+ {
18349
+ "stroke-width": "80.096",
18350
+ 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"
18351
+ }
18352
+ )
18353
+ ]
18354
+ }
18355
+ ),
18356
+ /* @__PURE__ */ jsxs16("g", { stroke: "#fff", "stroke-linecap": "round", "stroke-linejoin": "round", children: [
18357
+ /* @__PURE__ */ jsx36(
18358
+ "path",
18359
+ {
18360
+ fill: "#8c63d9",
18361
+ "stroke-width": "165.54595738999998",
18362
+ 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"
18363
+ }
18364
+ ),
18365
+ /* @__PURE__ */ jsx36(
18366
+ "path",
18367
+ {
18368
+ fill: "none",
18369
+ "stroke-width": "73.48667853999999",
18370
+ 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"
18371
+ }
18372
+ ),
18373
+ /* @__PURE__ */ jsx36(
18374
+ "path",
18375
+ {
18376
+ fill: "none",
18377
+ "stroke-width": "66.746",
18378
+ 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",
18379
+ transform: "translate(-216.03 -84.295)scale(1.10099)"
18380
+ }
18381
+ )
18382
+ ] }),
18383
+ /* @__PURE__ */ jsx36(
18384
+ "path",
18385
+ {
18386
+ fill: "#8c63d9",
18387
+ stroke: "#263238",
18388
+ "stroke-linecap": "round",
18389
+ "stroke-linejoin": "round",
18390
+ "stroke-width": "55.182",
18391
+ d: "m166.927 398.352 13.02 207.137-40.611 69.023v453.342h1086.661V674.512l-40.61-69.023 13.02-207.137z"
18392
+ }
18393
+ ),
18394
+ /* @__PURE__ */ jsx36(
18395
+ "path",
18396
+ {
18397
+ fill: "#cc7000",
18398
+ stroke: "#ffba66",
18399
+ "stroke-linecap": "round",
18400
+ "stroke-linejoin": "round",
18401
+ "stroke-width": "38.593",
18402
+ d: "M322.77 689.206h986.986l-36.885-62.693H359.655Z",
18403
+ mask: "url(#b)",
18404
+ transform: "translate(-216.03 -84.295)scale(1.10099)"
18405
+ }
18406
+ ),
18407
+ /* @__PURE__ */ jsx36(
18408
+ "path",
18409
+ {
18410
+ fill: "#ff8c00",
18411
+ d: "m1185.387 605.49 13.02-207.138H166.926l13.02 207.137z"
18412
+ }
18413
+ ),
18414
+ /* @__PURE__ */ jsx36(
18415
+ "path",
18416
+ {
18417
+ fill: "none",
18418
+ stroke: "#263238",
18419
+ "stroke-linecap": "round",
18420
+ "stroke-linejoin": "round",
18421
+ "stroke-width": "29.395",
18422
+ 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"
18423
+ }
18424
+ ),
18425
+ /* @__PURE__ */ jsx36(
18426
+ "path",
18427
+ {
18428
+ fill: "#eceff1",
18429
+ d: "m916.084 52.25 420.493 180.531-532.698 916.066-476.546-308.58Z",
18430
+ mask: "url(#c)"
18431
+ }
18432
+ ),
18433
+ /* @__PURE__ */ jsx36(
18434
+ "path",
18435
+ {
18436
+ fill: "#fff",
18437
+ 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",
18438
+ mask: "url(#d)"
18439
+ }
18440
+ ),
18441
+ /* @__PURE__ */ jsx36(
18442
+ "path",
18443
+ {
18444
+ fill: "#fff",
18445
+ 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",
18446
+ mask: "url(#e)"
18447
+ }
18448
+ ),
18449
+ /* @__PURE__ */ jsx36(
18450
+ "path",
18451
+ {
18452
+ fill: "#cfd8dc",
18453
+ 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",
18454
+ mask: "url(#f)"
18455
+ }
18456
+ ),
18457
+ /* @__PURE__ */ jsx36(
18458
+ "path",
18459
+ {
18460
+ fill: "#cfd8dc",
18461
+ 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",
18462
+ mask: "url(#g)"
18463
+ }
18464
+ ),
18465
+ /* @__PURE__ */ jsx36(
18466
+ "path",
18467
+ {
18468
+ fill: "none",
18469
+ stroke: "#263238",
18470
+ "stroke-linecap": "round",
18471
+ "stroke-linejoin": "round",
18472
+ "stroke-width": "29.395",
18473
+ 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"
18474
+ }
18475
+ ),
18476
+ /* @__PURE__ */ jsx36(
18477
+ "path",
18478
+ {
18479
+ fill: "#eceff1",
18480
+ d: "m105.922 257.574 152.745-109.918 438.66 518.005-348.484 67.536Z",
18481
+ mask: "url(#h)"
18482
+ }
18483
+ ),
18484
+ /* @__PURE__ */ jsx36(
18485
+ "path",
18486
+ {
18487
+ fill: "#fff",
18488
+ 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",
18489
+ mask: "url(#i)"
18490
+ }
18491
+ ),
18492
+ /* @__PURE__ */ jsx36(
18493
+ "path",
18494
+ {
18495
+ fill: "#cfd8dc",
18496
+ 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",
18497
+ mask: "url(#j)"
18498
+ }
18499
+ ),
18500
+ /* @__PURE__ */ jsx36(
18501
+ "path",
18502
+ {
18503
+ fill: "#cfd8dc",
18504
+ 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",
18505
+ mask: "url(#k)"
18506
+ }
18507
+ ),
18508
+ /* @__PURE__ */ jsx36("path", { fill: "#ffba66", d: "M170.482 652.84h1025.265v453.341H170.482Z" }),
18509
+ /* @__PURE__ */ jsx36("path", { fill: "#ff8c00", d: "M139.336 674.512h1086.662v453.342H139.336Z" }),
18510
+ /* @__PURE__ */ jsx36(
18511
+ "rect",
18512
+ {
18513
+ width: "875.482",
18514
+ height: "332.3",
18515
+ x: "244.926",
18516
+ y: "735.033",
18517
+ fill: "#cc7000",
18518
+ rx: "77.883",
18519
+ ry: "77.883"
18520
+ }
18521
+ ),
18522
+ /* @__PURE__ */ jsx36(
18523
+ "path",
18524
+ {
18525
+ fill: "#fff",
18526
+ 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",
18527
+ "aria-label": "00:00"
18528
+ }
18529
+ )
18530
+ ]
18531
+ }
18532
+ );
18533
+
18534
+ // src/components/frontend/toolbox/core/layout.tsx
18535
+ import { useContext as useContext14, useState as useState29 } from "react";
18536
+
18537
+ // src/components/frontend/toolbox/core/footer.tsx
18538
+ import { Fragment as Fragment12, jsx as jsx37, jsxs as jsxs17 } from "react/jsx-runtime";
18539
+ var Footer = ({ openLicenseDetails }) => {
18540
+ return /* @__PURE__ */ jsxs17(
18541
+ "div",
18542
+ {
18543
+ className: "\n flex items-center justify-center gap-1 border-t border-sigil-border\n bg-sigil-bg-dark p-1 text-[80%]\n ",
18544
+ children: [
18545
+ /* @__PURE__ */ jsxs17("span", { children: [
18546
+ "Created by",
18547
+ "\xA0",
18548
+ /* @__PURE__ */ jsx37(ExternalLink, { href: "https://arcanewizards.com", children: "Arcane Wizards" })
18549
+ ] }),
18550
+ /* @__PURE__ */ jsx37(ToolbarDivider, {}),
18551
+ /* @__PURE__ */ jsx37(ExternalLink, { href: SOURCE_CODE_URL, children: STRINGS.sourceCode }),
18552
+ openLicenseDetails && /* @__PURE__ */ jsxs17(Fragment12, { children: [
18553
+ /* @__PURE__ */ jsx37(ToolbarDivider, {}),
18554
+ /* @__PURE__ */ jsx37(TextButton, { onClick: openLicenseDetails, children: STRINGS.license })
18555
+ ] })
18556
+ ]
18557
+ }
18133
18558
  );
18134
- const { config } = info;
18135
- const { sendMessage, call, connection, reconnect } = useContext13(StageContext);
18136
- const [dialogMode, setDialogMode] = useState29(null);
18137
- const [assignToOutput, setAssignToOutput] = useState29(null);
18559
+ };
18560
+
18561
+ // src/components/frontend/toolbox/core/layout.tsx
18562
+ import { Fragment as Fragment13, jsx as jsx38, jsxs as jsxs18 } from "react/jsx-runtime";
18563
+ var Layout = ({
18564
+ modes,
18565
+ children,
18566
+ licenseMode,
18567
+ footer
18568
+ }) => {
18569
+ const [windowMode, setWindowMode] = useState29(null);
18570
+ const { connection, reconnect } = useContext14(StageContext);
18138
18571
  const { preferences } = useBrowserPreferences();
18139
18572
  useRootHintVariables(preferences.color);
18573
+ return /* @__PURE__ */ jsxs18("div", { className: "flex h-screen flex-col", children: [
18574
+ /* @__PURE__ */ jsx38(ToolbarWrapper, { children: /* @__PURE__ */ jsxs18(ToolbarRow, { children: [
18575
+ /* @__PURE__ */ jsx38(
18576
+ "div",
18577
+ {
18578
+ className: "\n flex h-full min-h-[36px] grow items-center justify-center px-1\n app-title-bar\n ",
18579
+ children: /* @__PURE__ */ jsx38("span", { className: "font-bold text-hint-gradient", children: STRINGS.title })
18580
+ }
18581
+ ),
18582
+ modes && /* @__PURE__ */ jsxs18(Fragment13, { children: [
18583
+ /* @__PURE__ */ jsx38(ToolbarDivider, {}),
18584
+ Object.entries(modes).map(([key, { icon, title }]) => /* @__PURE__ */ jsx38(
18585
+ ControlButton,
18586
+ {
18587
+ onClick: () => setWindowMode((mode) => mode === key ? null : key),
18588
+ variant: "titlebar",
18589
+ icon,
18590
+ active: windowMode === key,
18591
+ title: STRINGS.toggle(title)
18592
+ },
18593
+ key
18594
+ ))
18595
+ ] })
18596
+ ] }) }),
18597
+ /* @__PURE__ */ jsx38("div", { className: "relative flex h-0 grow flex-col", children: connection.state !== "connected" ? /* @__PURE__ */ jsxs18(
18598
+ SizeAwareDiv,
18599
+ {
18600
+ className: "\n flex grow flex-col items-center justify-center gap-1\n bg-sigil-bg-light p-1 text-sigil-foreground-muted\n ",
18601
+ children: [
18602
+ /* @__PURE__ */ jsx38(Icon2, { icon: "signal_disconnected", className: "text-block-icon" }),
18603
+ /* @__PURE__ */ jsx38("div", { className: "text-center", children: STRINGS.connectionError }),
18604
+ /* @__PURE__ */ jsx38(ControlButton, { onClick: reconnect, variant: "large", icon: "replay", children: STRINGS.reconnect })
18605
+ ]
18606
+ }
18607
+ ) : windowMode && modes?.[windowMode] ? modes[windowMode].child(setWindowMode) : children }),
18608
+ footer && /* @__PURE__ */ jsx38(
18609
+ Footer,
18610
+ {
18611
+ openLicenseDetails: licenseMode && (() => setWindowMode(
18612
+ (mode) => mode === licenseMode ? null : licenseMode
18613
+ ))
18614
+ }
18615
+ )
18616
+ ] });
18617
+ };
18618
+
18619
+ // src/components/frontend/toolbox/license.tsx
18620
+ import { jsx as jsx39, jsxs as jsxs19 } from "react/jsx-runtime";
18621
+ var LicenseContent = ({ license }) => {
18622
+ return /* @__PURE__ */ jsx39("div", { className: "flex flex-col gap-2 rounded-md bg-sigil-bg-light p-2", children: license.split("\n\n").map((paragraph, index2) => /* @__PURE__ */ jsx39("p", { className: "m-0", children: paragraph.replace(/\n/g, " ").trim() }, index2)) });
18623
+ };
18624
+ var License = ({ license, setWindowMode }) => {
18625
+ return /* @__PURE__ */ jsx39("div", { className: "flex grow flex-col", children: /* @__PURE__ */ jsxs19(
18626
+ "div",
18627
+ {
18628
+ className: "\n flex grow basis-0 flex-col overflow-y-auto px-2 pb-2 scrollbar-sigil\n ",
18629
+ children: [
18630
+ /* @__PURE__ */ jsx39(TimecodeToolboxLogo, { className: "h-[20%] max-h-[420px] min-h-[110px] w-full" }),
18631
+ /* @__PURE__ */ jsx39(LicenseContent, { license }),
18632
+ /* @__PURE__ */ jsx39("div", { className: "flex justify-center p-2", children: /* @__PURE__ */ jsx39(
18633
+ ControlButton,
18634
+ {
18635
+ onClick: () => setWindowMode(null),
18636
+ variant: "large",
18637
+ icon: "close",
18638
+ children: STRINGS.close(STRINGS.license)
18639
+ }
18640
+ ) })
18641
+ ]
18642
+ }
18643
+ ) });
18644
+ };
18645
+ var LicenseGate = ({ info }) => {
18646
+ const { sendMessage } = useContext15(StageContext);
18647
+ const acceptLicense = useCallback18(() => {
18648
+ sendMessage?.({
18649
+ type: "component-message",
18650
+ namespace: "timecode-toolbox",
18651
+ component: "license-gate",
18652
+ componentKey: info.key,
18653
+ action: "accept-license",
18654
+ hash: info.hash
18655
+ });
18656
+ }, [sendMessage, info.key, info.hash]);
18657
+ return /* @__PURE__ */ jsx39(
18658
+ Layout,
18659
+ {
18660
+ footer: true,
18661
+ modes: {
18662
+ debug: {
18663
+ child: () => /* @__PURE__ */ jsx39(Debugger, { title: STRINGS.debugger, className: "size-full" }),
18664
+ icon: "bug_report",
18665
+ title: STRINGS.debugger
18666
+ }
18667
+ },
18668
+ children: /* @__PURE__ */ jsxs19(
18669
+ "div",
18670
+ {
18671
+ className: "\n flex grow basis-0 flex-col overflow-y-auto px-2 pb-2 scrollbar-sigil\n ",
18672
+ children: [
18673
+ /* @__PURE__ */ jsx39(TimecodeToolboxLogo, { className: "h-[20%] max-h-[420px] min-h-[110px] w-full" }),
18674
+ /* @__PURE__ */ jsx39("h2", { className: "text-center text-sigil-usage-hint-foreground", children: STRINGS.licensePrompt }),
18675
+ /* @__PURE__ */ jsx39(LicenseContent, { license: info.license }),
18676
+ /* @__PURE__ */ jsx39("div", { className: "flex justify-center p-2", children: /* @__PURE__ */ jsx39(
18677
+ ControlButton,
18678
+ {
18679
+ onClick: acceptLicense,
18680
+ variant: "large",
18681
+ icon: "check",
18682
+ primary: true,
18683
+ children: STRINGS.acceptLicense
18684
+ }
18685
+ ) })
18686
+ ]
18687
+ }
18688
+ )
18689
+ }
18690
+ );
18691
+ };
18692
+
18693
+ // src/components/frontend/toolbox/core/updates.tsx
18694
+ import { useCallback as useCallback19, useEffect as useEffect30, useState as useState30 } from "react";
18695
+ import { jsx as jsx40, jsxs as jsxs20 } from "react/jsx-runtime";
18696
+ var UpdateBanner = () => {
18697
+ const { updates } = useApplicationState();
18698
+ const { version } = useSystemInformation();
18699
+ const { openExternalLink } = useBrowserContext();
18700
+ const [displayState, setDisplayState] = useState30();
18140
18701
  useEffect30(() => {
18702
+ if (updates?.type !== "loading") {
18703
+ setDisplayState(updates);
18704
+ }
18705
+ }, [updates]);
18706
+ const openDownloadLink = useCallback19(() => {
18707
+ if (displayState?.type === "updates-available" && displayState.response.downloadUrl) {
18708
+ openExternalLink(displayState.response.downloadUrl);
18709
+ }
18710
+ }, [displayState, openExternalLink]);
18711
+ if (displayState?.type === "error") {
18712
+ return /* @__PURE__ */ jsxs20(
18713
+ "div",
18714
+ {
18715
+ 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 ",
18716
+ children: [
18717
+ /* @__PURE__ */ jsx40(Icon2, { icon: "error" }),
18718
+ displayState.error
18719
+ ]
18720
+ }
18721
+ );
18722
+ }
18723
+ if (displayState?.type === "updates-available") {
18724
+ return /* @__PURE__ */ jsxs20(
18725
+ "div",
18726
+ {
18727
+ 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 ",
18728
+ children: [
18729
+ /* @__PURE__ */ jsx40(Icon2, { icon: "upgrade" }),
18730
+ STRINGS.updates.updateAvailable(
18731
+ version,
18732
+ displayState.response.latestVersion
18733
+ ),
18734
+ displayState.response.downloadUrl && /* @__PURE__ */ jsxs20(
18735
+ "button",
18736
+ {
18737
+ 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 ",
18738
+ onClick: openDownloadLink,
18739
+ children: [
18740
+ /* @__PURE__ */ jsx40(Icon2, { icon: "download" }),
18741
+ STRINGS.updates.download
18742
+ ]
18743
+ }
18744
+ )
18745
+ ]
18746
+ }
18747
+ );
18748
+ }
18749
+ return null;
18750
+ };
18751
+
18752
+ // src/components/frontend/toolbox/root.tsx
18753
+ import { Fragment as Fragment14, jsx as jsx41, jsxs as jsxs21 } from "react/jsx-runtime";
18754
+ var ToolboxRoot = ({ info }) => {
18755
+ const { config } = info;
18756
+ const { sendMessage, call } = useContext16(StageContext);
18757
+ const [dialogMode, setDialogMode] = useState31(null);
18758
+ const [assignToOutput, setAssignToOutput] = useState31(null);
18759
+ useEffect31(() => {
18141
18760
  if (assignToOutput) {
18142
18761
  const onEscape = (e) => {
18143
18762
  if (e.key === "Escape") {
@@ -18150,7 +18769,7 @@ var ToolboxRoot = ({ info }) => {
18150
18769
  };
18151
18770
  }
18152
18771
  }, [assignToOutput]);
18153
- const updateConfig = useCallback18(
18772
+ const updateConfig = useCallback20(
18154
18773
  (change) => {
18155
18774
  const diff = diffJson(config, change(config));
18156
18775
  sendMessage?.({
@@ -18171,8 +18790,8 @@ var ToolboxRoot = ({ info }) => {
18171
18790
  }),
18172
18791
  [config, updateConfig]
18173
18792
  );
18174
- const closeDialog = useCallback18(() => setDialogMode(null), []);
18175
- const getNetworkInterfaces = useCallback18(async () => {
18793
+ const closeDialog = useCallback20(() => setDialogMode(null), []);
18794
+ const getNetworkInterfaces = useCallback20(async () => {
18176
18795
  if (!call) {
18177
18796
  throw new Error("No call function available");
18178
18797
  }
@@ -18213,7 +18832,7 @@ var ToolboxRoot = ({ info }) => {
18213
18832
  setAssignToOutput(null);
18214
18833
  };
18215
18834
  }, [assignToOutput, updateConfig]);
18216
- const callHandler = useCallback18(
18835
+ const callHandler = useCallback20(
18217
18836
  async ({ path, handler, args }) => {
18218
18837
  if (!call) {
18219
18838
  throw new Error("No call function available");
@@ -18241,138 +18860,110 @@ var ToolboxRoot = ({ info }) => {
18241
18860
  () => getFragmentValue("tc", TIMECODE_INSTANCE_ID),
18242
18861
  []
18243
18862
  );
18244
- const isMainWindow = windowedTimecodeId === null;
18245
18863
  const root = useMemo15(
18246
- () => /* @__PURE__ */ jsxs16("div", { className: "flex h-screen flex-col", children: [
18247
- /* @__PURE__ */ jsx36(ToolbarWrapper, { children: /* @__PURE__ */ jsxs16(ToolbarRow, { children: [
18248
- /* @__PURE__ */ jsx36(
18249
- "div",
18250
- {
18251
- className: "\n flex h-full min-h-[36px] grow items-center justify-center px-1\n app-title-bar\n ",
18252
- children: /* @__PURE__ */ jsx36("span", { className: "font-bold text-hint-gradient", children: STRINGS.title })
18253
- }
18254
- ),
18255
- isMainWindow && /* @__PURE__ */ jsxs16(Fragment12, { children: [
18256
- /* @__PURE__ */ jsx36(ToolbarDivider, {}),
18257
- /* @__PURE__ */ jsx36(
18258
- ControlButton,
18259
- {
18260
- onClick: () => setWindowMode(
18261
- (mode) => mode === "settings" ? null : "settings"
18864
+ () => windowedTimecodeId ? /* @__PURE__ */ jsx41(Layout, { modes: null, children: /* @__PURE__ */ jsx41(FullscreenTimecodeDisplay, { id: windowedTimecodeId }) }) : /* @__PURE__ */ jsxs21(Fragment14, { children: [
18865
+ /* @__PURE__ */ jsx41(
18866
+ Layout,
18867
+ {
18868
+ footer: true,
18869
+ modes: {
18870
+ license: {
18871
+ child: (setWindowMode) => /* @__PURE__ */ jsx41(
18872
+ License,
18873
+ {
18874
+ license: info.license,
18875
+ setWindowMode
18876
+ }
18262
18877
  ),
18263
- variant: "titlebar",
18878
+ icon: "info",
18879
+ title: STRINGS.license
18880
+ },
18881
+ settings: {
18882
+ child: (setWindowMode) => /* @__PURE__ */ jsx41(Settings, { setWindowMode }),
18264
18883
  icon: "settings",
18265
- active: windowMode === "settings",
18266
- title: STRINGS.toggle(STRINGS.settings.title)
18267
- }
18268
- ),
18269
- /* @__PURE__ */ jsx36(
18270
- ControlButton,
18271
- {
18272
- onClick: () => setWindowMode((mode) => mode === "debug" ? null : "debug"),
18273
- variant: "titlebar",
18884
+ title: STRINGS.settings.title
18885
+ },
18886
+ debug: {
18887
+ child: () => /* @__PURE__ */ jsx41(Debugger, { title: STRINGS.debugger, className: "size-full" }),
18274
18888
  icon: "bug_report",
18275
- active: windowMode === "debug",
18276
- title: STRINGS.toggle(STRINGS.debugger)
18889
+ title: STRINGS.debugger
18277
18890
  }
18278
- )
18279
- ] })
18280
- ] }) }),
18281
- /* @__PURE__ */ jsxs16("div", { className: "relative flex h-0 grow flex-col", children: [
18282
- connection.state !== "connected" ? /* @__PURE__ */ jsxs16(
18283
- SizeAwareDiv,
18284
- {
18285
- className: "\n flex grow flex-col items-center justify-center gap-1\n bg-sigil-bg-light p-1 text-sigil-foreground-muted\n ",
18286
- children: [
18287
- /* @__PURE__ */ jsx36(Icon2, { icon: "signal_disconnected", className: "text-block-icon" }),
18288
- /* @__PURE__ */ jsx36("div", { className: "text-center", children: STRINGS.connectionError }),
18289
- /* @__PURE__ */ jsx36(ControlButton, { onClick: reconnect, variant: "large", icon: "replay", children: STRINGS.reconnect })
18290
- ]
18291
- }
18292
- ) : windowMode === "debug" ? /* @__PURE__ */ jsx36(Debugger, { title: STRINGS.debugger, className: "size-full" }) : windowMode === "settings" ? /* @__PURE__ */ jsx36(Settings, { setWindowMode }) : windowedTimecodeId ? /* @__PURE__ */ jsx36(FullscreenTimecodeDisplay, { id: windowedTimecodeId }) : /* @__PURE__ */ jsxs16(
18293
- "div",
18294
- {
18295
- className: "\n flex h-0 grow flex-col gap-px overflow-y-auto bg-sigil-border\n scrollbar-sigil\n ",
18296
- children: [
18297
- /* @__PURE__ */ jsx36(
18298
- InputsSection,
18299
- {
18300
- setDialogMode,
18301
- assignToOutput: assignToOutputCallback
18302
- }
18303
- ),
18304
- /* @__PURE__ */ jsx36(
18305
- GeneratorsSection,
18306
- {
18307
- setDialogMode,
18308
- assignToOutput: assignToOutputCallback
18309
- }
18310
- ),
18311
- /* @__PURE__ */ jsx36(
18312
- OutputsSection,
18313
- {
18314
- setDialogMode,
18315
- assignToOutput,
18316
- setAssignToOutput
18317
- }
18318
- )
18319
- ]
18320
- }
18321
- ),
18322
- dialogMode?.section.type === "inputs" && /* @__PURE__ */ jsx36(
18323
- InputSettingsDialog,
18324
- {
18325
- close: closeDialog,
18326
- input: dialogMode.section.input,
18327
- target: dialogMode.target
18328
- }
18329
- ),
18330
- dialogMode?.section.type === "generators" && /* @__PURE__ */ jsx36(
18331
- GeneratorSettingsDialog,
18332
- {
18333
- close: closeDialog,
18334
- generator: dialogMode.section.generator,
18335
- target: dialogMode.target
18336
- }
18337
- ),
18338
- dialogMode?.section.type === "outputs" && /* @__PURE__ */ jsx36(
18339
- OutputSettingsDialog,
18340
- {
18341
- close: closeDialog,
18342
- output: dialogMode.section.output,
18343
- target: dialogMode.target
18344
- }
18345
- )
18346
- ] }),
18347
- isMainWindow && /* @__PURE__ */ jsxs16(
18348
- "div",
18891
+ },
18892
+ licenseMode: "license",
18893
+ children: /* @__PURE__ */ jsxs21(Fragment14, { children: [
18894
+ /* @__PURE__ */ jsx41(UpdateBanner, {}),
18895
+ /* @__PURE__ */ jsxs21(
18896
+ "div",
18897
+ {
18898
+ className: "\n flex h-0 grow flex-col gap-px overflow-y-auto bg-sigil-border\n scrollbar-sigil\n ",
18899
+ children: [
18900
+ /* @__PURE__ */ jsx41(
18901
+ InputsSection,
18902
+ {
18903
+ setDialogMode,
18904
+ assignToOutput: assignToOutputCallback
18905
+ }
18906
+ ),
18907
+ /* @__PURE__ */ jsx41(
18908
+ GeneratorsSection,
18909
+ {
18910
+ setDialogMode,
18911
+ assignToOutput: assignToOutputCallback
18912
+ }
18913
+ ),
18914
+ /* @__PURE__ */ jsx41(
18915
+ OutputsSection,
18916
+ {
18917
+ setDialogMode,
18918
+ assignToOutput,
18919
+ setAssignToOutput
18920
+ }
18921
+ )
18922
+ ]
18923
+ }
18924
+ )
18925
+ ] })
18926
+ }
18927
+ ),
18928
+ dialogMode?.section.type === "inputs" && /* @__PURE__ */ jsx41(
18929
+ InputSettingsDialog,
18349
18930
  {
18350
- className: "\n flex justify-center border-t border-sigil-border bg-sigil-bg-dark\n p-1 text-[80%]\n ",
18351
- children: [
18352
- "Created by",
18353
- "\xA0",
18354
- /* @__PURE__ */ jsx36(ExternalLink, { href: "https://arcanewizards.com", children: "Arcane Wizards" })
18355
- ]
18931
+ close: closeDialog,
18932
+ input: dialogMode.section.input,
18933
+ target: dialogMode.target
18934
+ }
18935
+ ),
18936
+ dialogMode?.section.type === "generators" && /* @__PURE__ */ jsx41(
18937
+ GeneratorSettingsDialog,
18938
+ {
18939
+ close: closeDialog,
18940
+ generator: dialogMode.section.generator,
18941
+ target: dialogMode.target
18942
+ }
18943
+ ),
18944
+ dialogMode?.section.type === "outputs" && /* @__PURE__ */ jsx41(
18945
+ OutputSettingsDialog,
18946
+ {
18947
+ close: closeDialog,
18948
+ output: dialogMode.section.output,
18949
+ target: dialogMode.target
18356
18950
  }
18357
18951
  )
18358
18952
  ] }),
18359
18953
  [
18360
- connection,
18361
- reconnect,
18362
18954
  assignToOutput,
18363
18955
  assignToOutputCallback,
18364
18956
  closeDialog,
18365
18957
  dialogMode,
18366
- windowMode,
18367
- isMainWindow,
18368
- windowedTimecodeId
18958
+ windowedTimecodeId,
18959
+ info.license
18369
18960
  ]
18370
18961
  );
18371
- return /* @__PURE__ */ jsx36(ConfigContext.Provider, { value: configContext, children: /* @__PURE__ */ jsx36(NetworkContext.Provider, { value: networkContextValue, children: /* @__PURE__ */ jsx36(ApplicationStateContext.Provider, { value: info.state, children: /* @__PURE__ */ jsx36(ApplicationHandlersContext.Provider, { value: handlers, children: root }) }) }) });
18962
+ return /* @__PURE__ */ jsx41(ConfigContext.Provider, { value: configContext, children: /* @__PURE__ */ jsx41(NetworkContext.Provider, { value: networkContextValue, children: /* @__PURE__ */ jsx41(ApplicationStateContext.Provider, { value: info.state, children: /* @__PURE__ */ jsx41(ApplicationHandlersContext.Provider, { value: handlers, children: root }) }) }) });
18372
18963
  };
18373
18964
 
18374
18965
  // src/components/frontend/index.tsx
18375
- import { jsx as jsx37 } from "react/jsx-runtime";
18966
+ import { jsx as jsx45 } from "react/jsx-runtime";
18376
18967
  var timecodeToolboxFrontendComponents = () => ({
18377
18968
  namespace: NAMESPACE,
18378
18969
  render: (info) => {
@@ -18381,7 +18972,9 @@ var timecodeToolboxFrontendComponents = () => ({
18381
18972
  }
18382
18973
  switch (info.component) {
18383
18974
  case "toolbox-root":
18384
- return /* @__PURE__ */ jsx37(ToolboxRoot, { info });
18975
+ return /* @__PURE__ */ jsx45(ToolboxRoot, { info });
18976
+ case "license-gate":
18977
+ return /* @__PURE__ */ jsx45(LicenseGate, { info });
18385
18978
  }
18386
18979
  }
18387
18980
  });
@@ -18389,7 +18982,7 @@ var startTimecodeToolboxServerFrontend = (browser) => {
18389
18982
  startSigilFrontend({
18390
18983
  browser,
18391
18984
  appRenderers: [timecodeToolboxFrontendComponents()],
18392
- loadingState: () => /* @__PURE__ */ jsx37("div", { style: { width: "100%", textAlign: "center", padding: "2rem" }, children: "Loading Toolbox..." })
18985
+ loadingState: () => /* @__PURE__ */ jsx45("div", { style: { width: "100%", textAlign: "center", padding: "2rem" }, children: "Loading Toolbox..." })
18393
18986
  });
18394
18987
  };
18395
18988
  window.startTimecodeToolboxServerFrontend = startTimecodeToolboxServerFrontend;