@valbuild/ui 0.41.0 → 0.42.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -51480,7 +51480,7 @@ function isRichTextSchema(schema) {
51480
51480
  function isImageSchema(schema) {
51481
51481
  return schema instanceof ImageSchema || _typeof(schema) === "object" && "type" in schema && schema.type === "image";
51482
51482
  }
51483
- function resolvePath$2(path, valModule, schema) {
51483
+ function resolvePath$1(path, valModule, schema) {
51484
51484
  var parts = parsePath$1(path);
51485
51485
  var origParts = _toConsumableArray$1(parts);
51486
51486
  var resolvedSchema = schema;
@@ -52016,7 +52016,7 @@ var Internal = {
52016
52016
  getValPath,
52017
52017
  getVal,
52018
52018
  getSource,
52019
- resolvePath: resolvePath$2,
52019
+ resolvePath: resolvePath$1,
52020
52020
  splitModuleIdAndModulePath,
52021
52021
  isVal,
52022
52022
  createValPathOfItem: createValPathOfItem$1,
@@ -66577,106 +66577,419 @@ function useDrag({
66577
66577
  const isInitialized = !!((_b = (_a = ref == null ? void 0 : ref.current) == null ? void 0 : _a.getBoundingClientRect()) == null ? void 0 : _b.width);
66578
66578
  return [position, isInitialized, ref, handleMouseDown];
66579
66579
  }
66580
- function resolvePath$1(sourcePath, modules) {
66581
- const [moduleId, modulePath] = Internal.splitModuleIdAndModulePath(sourcePath);
66582
- const valModule = modules[moduleId];
66583
- if (!(valModule == null ? void 0 : valModule.source)) {
66584
- return result.err({
66585
- message: `Module "${moduleId}" has no source`
66580
+ function usePatch(paths, api, valStore, onSubmit, session) {
66581
+ const [state, setState] = useState({});
66582
+ const [error, setError] = useState(null);
66583
+ const [progress, setProgress] = useState("ready");
66584
+ const initPatchCallback = useCallback(
66585
+ (paths2) => {
66586
+ return (callback) => {
66587
+ setState((prev) => {
66588
+ const nextState = paths2.reduce((acc, path) => {
66589
+ const patchPath = Internal.createPatchJSONPath(
66590
+ Internal.splitModuleIdAndModulePath(path)[1]
66591
+ );
66592
+ return {
66593
+ ...acc,
66594
+ [path]: () => callback(patchPath)
66595
+ };
66596
+ }, {});
66597
+ return {
66598
+ ...prev,
66599
+ ...nextState
66600
+ };
66601
+ });
66602
+ };
66603
+ },
66604
+ []
66605
+ );
66606
+ useEffect(() => {
66607
+ setState((prev) => {
66608
+ const newState = {};
66609
+ for (const path of paths) {
66610
+ if (prev[path]) {
66611
+ newState[path] = prev[path];
66612
+ }
66613
+ }
66614
+ if (Object.keys(newState).length === Object.keys(prev).length) {
66615
+ return prev;
66616
+ }
66617
+ return newState;
66586
66618
  });
66587
- }
66588
- if (!(valModule == null ? void 0 : valModule.schema)) {
66589
- return result.err({
66590
- message: `Module "${moduleId}" has no schema`
66619
+ }, [paths]);
66620
+ const onSubmitPatch = useCallback(async () => {
66621
+ setError(null);
66622
+ setProgress("create_patch");
66623
+ const patches = {};
66624
+ for (const path in state) {
66625
+ const [moduleId] = Internal.splitModuleIdAndModulePath(
66626
+ path
66627
+ );
66628
+ const patch = await state[path]();
66629
+ patches[moduleId] = patch;
66630
+ }
66631
+ return maybeStartViewTransition(() => {
66632
+ setProgress("patching");
66633
+ return Promise.all(
66634
+ Object.entries(patches).map(
66635
+ ([moduleId, patch]) => api.postPatches(moduleId, patch).then((res) => {
66636
+ if (result.isErr(res)) {
66637
+ throw res.error;
66638
+ } else {
66639
+ res.value;
66640
+ }
66641
+ })
66642
+ )
66643
+ ).then(() => {
66644
+ setProgress("on_submit");
66645
+ const refreshRequired = session.status === "success" && session.data.mode === "proxy";
66646
+ return onSubmit(refreshRequired);
66647
+ }).then(() => {
66648
+ setProgress("update_store");
66649
+ return valStore.update(
66650
+ paths.map(
66651
+ (path) => Internal.splitModuleIdAndModulePath(path)[0]
66652
+ )
66653
+ );
66654
+ });
66655
+ }).catch((err2) => {
66656
+ setError(err2);
66657
+ }).finally(() => {
66658
+ setProgress("ready");
66591
66659
  });
66660
+ }, [state, session]);
66661
+ return { initPatchCallback, onSubmitPatch, error, progress };
66662
+ }
66663
+ async function maybeStartViewTransition(f) {
66664
+ if ("startViewTransition" in document && typeof document.startViewTransition === "function") {
66665
+ await document.startViewTransition(f);
66592
66666
  }
66593
- return result.ok(
66594
- Internal.resolvePath(modulePath, valModule.source, valModule.schema)
66595
- );
66667
+ await f();
66596
66668
  }
66597
- const falsyToString = (value) => typeof value === "boolean" ? "".concat(value) : value === 0 ? "0" : value;
66598
- const cx = clsx;
66599
- const cva = (base, config) => {
66600
- return (props) => {
66601
- var ref;
66602
- if ((config === null || config === void 0 ? void 0 : config.variants) == null)
66603
- return cx(base, props === null || props === void 0 ? void 0 : props.class, props === null || props === void 0 ? void 0 : props.className);
66604
- const { variants, defaultVariants } = config;
66605
- const getVariantClassNames = Object.keys(variants).map((variant) => {
66606
- const variantProp = props === null || props === void 0 ? void 0 : props[variant];
66607
- const defaultVariantProp = defaultVariants === null || defaultVariants === void 0 ? void 0 : defaultVariants[variant];
66608
- if (variantProp === null)
66609
- return null;
66610
- const variantKey = falsyToString(variantProp) || falsyToString(defaultVariantProp);
66611
- return variants[variant][variantKey];
66612
- });
66613
- const propsWithoutUndefined = props && Object.entries(props).reduce((acc, param) => {
66614
- let [key, value] = param;
66615
- if (value === void 0) {
66616
- return acc;
66669
+ function useTheme(defaultTheme = "dark") {
66670
+ const [theme2, setTheme] = useState(defaultTheme);
66671
+ useEffect(() => {
66672
+ if (localStorage.getItem("val-theme") === "light") {
66673
+ setTheme("light");
66674
+ } else if (localStorage.getItem("val-theme") === "dark") {
66675
+ setTheme("dark");
66676
+ } else if (window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches) {
66677
+ setTheme("dark");
66678
+ } else if (window.matchMedia && window.matchMedia("(prefers-color-scheme: light)").matches) {
66679
+ setTheme("light");
66680
+ }
66681
+ const themeListener = (e) => {
66682
+ if (!localStorage.getItem("val-theme")) {
66683
+ setTheme(e.matches ? "dark" : "light");
66617
66684
  }
66618
- acc[key] = value;
66619
- return acc;
66620
- }, {});
66621
- const getCompoundVariantClassNames = config === null || config === void 0 ? void 0 : (ref = config.compoundVariants) === null || ref === void 0 ? void 0 : ref.reduce((acc, param1) => {
66622
- let { class: cvClass, className: cvClassName, ...compoundVariantOptions } = param1;
66623
- return Object.entries(compoundVariantOptions).every((param) => {
66624
- let [key, value] = param;
66625
- return Array.isArray(value) ? value.includes({
66626
- ...defaultVariants,
66627
- ...propsWithoutUndefined
66628
- }[key]) : {
66629
- ...defaultVariants,
66630
- ...propsWithoutUndefined
66631
- }[key] === value;
66632
- }) ? [
66633
- ...acc,
66634
- cvClass,
66635
- cvClassName
66636
- ] : acc;
66637
- }, []);
66638
- return cx(base, getVariantClassNames, getCompoundVariantClassNames, props === null || props === void 0 ? void 0 : props.class, props === null || props === void 0 ? void 0 : props.className);
66685
+ };
66686
+ window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", themeListener);
66687
+ return () => {
66688
+ window.matchMedia("(prefers-color-scheme: dark)").removeEventListener("change", themeListener);
66689
+ };
66690
+ }, []);
66691
+ return [
66692
+ theme2,
66693
+ (theme22) => {
66694
+ localStorage.setItem("val-theme", theme22);
66695
+ setTheme(theme22);
66696
+ }
66697
+ ];
66698
+ }
66699
+ function Grid({ children }) {
66700
+ const leftColRef = useRef(null);
66701
+ const rightColRef = useRef(null);
66702
+ const isResizing = useRef(false);
66703
+ const x = useRef(0);
66704
+ const dragRef = useRef(null);
66705
+ const originalWidth = useRef(0);
66706
+ const handleMouseUp = () => {
66707
+ isResizing.current = false;
66708
+ dragRef.current = null;
66709
+ x.current = 0;
66710
+ originalWidth.current = 0;
66639
66711
  };
66640
- };
66641
- const buttonVariants = cva(
66642
- "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
66643
- {
66644
- variants: {
66645
- variant: {
66646
- default: "bg-primary text-primary-foreground hover:bg-primary/90",
66647
- destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
66648
- outline: "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
66649
- secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
66650
- ghost: "hover:bg-accent hover:text-accent-foreground",
66651
- link: "text-primary underline-offset-4 hover:underline"
66652
- },
66653
- size: {
66654
- default: "h-10 px-4 py-2",
66655
- sm: "h-9 rounded-md px-3",
66656
- lg: "h-11 rounded-md px-8",
66657
- icon: "h-10 w-10"
66712
+ const handleMouseMove = (event) => {
66713
+ event.preventDefault();
66714
+ const targetRef = dragRef.current === "left" ? leftColRef : rightColRef;
66715
+ if (targetRef.current && isResizing.current) {
66716
+ const dx = dragRef.current === "left" ? event.screenX - x.current : x.current - event.screenX;
66717
+ targetRef.current.style.width = `${Math.max(
66718
+ originalWidth.current + dx,
66719
+ 150
66720
+ )}px`;
66721
+ }
66722
+ };
66723
+ const handleMouseDown = (column) => (event) => {
66724
+ const target = event.target;
66725
+ if (target) {
66726
+ const columnRef = column === "left" ? leftColRef : column === "right" ? rightColRef : null;
66727
+ isResizing.current = true;
66728
+ if (columnRef && columnRef.current) {
66729
+ x.current = event.screenX;
66730
+ dragRef.current = column;
66731
+ if (columnRef.current) {
66732
+ originalWidth.current = columnRef.current.offsetWidth;
66733
+ }
66658
66734
  }
66659
- },
66660
- defaultVariants: {
66661
- variant: "default",
66662
- size: "default"
66663
66735
  }
66664
- }
66665
- );
66666
- const Button = React$3.forwardRef(
66667
- ({ className: className2, variant, size: size2, asChild = false, ...props }, ref) => {
66668
- const Comp = asChild ? $5e63c961fc1ce211$export$8c6ed5c666ac1360 : "button";
66669
- return /* @__PURE__ */ jsx(
66670
- Comp,
66736
+ };
66737
+ const [header1, body1, header2, body2, header3, body3] = Children.toArray(children);
66738
+ useEffect(() => {
66739
+ document.addEventListener("mouseup", handleMouseUp);
66740
+ document.addEventListener("mousemove", handleMouseMove);
66741
+ return () => {
66742
+ document.removeEventListener("mouseup", handleMouseUp);
66743
+ document.removeEventListener("mousemove", handleMouseMove);
66744
+ };
66745
+ }, []);
66746
+ return /* @__PURE__ */ jsxs("div", { className: "flex h-screen", children: [
66747
+ /* @__PURE__ */ jsxs(
66748
+ "div",
66671
66749
  {
66672
- className: cn(buttonVariants({ variant, size: size2, className: className2 })),
66673
- ref,
66674
- ...props
66750
+ ref: leftColRef,
66751
+ className: "relative border-r border-border",
66752
+ style: { width: 300 },
66753
+ children: [
66754
+ /* @__PURE__ */ jsxs(Grid.Column, { children: [
66755
+ header1,
66756
+ /* @__PURE__ */ jsx(ScrollArea, { style: { height: "calc(100vh - 50px)" }, children: body1 })
66757
+ ] }),
66758
+ /* @__PURE__ */ jsx(
66759
+ "div",
66760
+ {
66761
+ className: "absolute inset-y-0 right-0 cursor-col-resize w-[1px] hover:w-[3px] h-full hover:bg-border",
66762
+ onMouseDown: handleMouseDown("left")
66763
+ }
66764
+ )
66765
+ ]
66675
66766
  }
66676
- );
66677
- }
66678
- );
66679
- Button.displayName = "Button";
66767
+ ),
66768
+ /* @__PURE__ */ jsx(
66769
+ "div",
66770
+ {
66771
+ className: classNames("", {
66772
+ "w-full": !header3 && !body3
66773
+ }),
66774
+ children: /* @__PURE__ */ jsxs(Grid.Column, { children: [
66775
+ header2,
66776
+ /* @__PURE__ */ jsx(ScrollArea, { style: { height: "calc(100vh - 50px)" }, children: body2 })
66777
+ ] })
66778
+ }
66779
+ ),
66780
+ header3 || body3 && /* @__PURE__ */ jsxs(
66781
+ "div",
66782
+ {
66783
+ ref: rightColRef,
66784
+ className: "relative h-screen border-l border-border",
66785
+ style: { width: 300 },
66786
+ children: [
66787
+ /* @__PURE__ */ jsxs(Grid.Column, { children: [
66788
+ header3,
66789
+ /* @__PURE__ */ jsx(ScrollArea, { style: { height: "calc(100vh - 50px)" }, children: body3 })
66790
+ ] }),
66791
+ /* @__PURE__ */ jsx(
66792
+ "div",
66793
+ {
66794
+ onMouseDown: handleMouseDown("right"),
66795
+ className: "absolute inset-y-0 left-0 cursor-col-resize w-[1px] bg-border hover:w-[3px] hover:bg-border"
66796
+ }
66797
+ )
66798
+ ]
66799
+ }
66800
+ )
66801
+ ] });
66802
+ }
66803
+ Grid.Column = ({ children }) => {
66804
+ const [header, body] = Children.toArray(children);
66805
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
66806
+ /* @__PURE__ */ jsx("div", { className: "flex items-center border-b border-border", children: header }),
66807
+ body
66808
+ ] });
66809
+ };
66810
+ const Section = ({ className: className2 }) => {
66811
+ return /* @__PURE__ */ jsxs(
66812
+ "svg",
66813
+ {
66814
+ width: "9",
66815
+ height: "10",
66816
+ viewBox: "0 0 9 10",
66817
+ className: className2,
66818
+ fill: "currentColor",
66819
+ xmlns: "http://www.w3.org/2000/svg",
66820
+ children: [
66821
+ /* @__PURE__ */ jsxs("g", { clipPath: "url(#clip0_1222_1618)", children: [
66822
+ /* @__PURE__ */ jsx(
66823
+ "path",
66824
+ {
66825
+ fillRule: "evenodd",
66826
+ clipRule: "evenodd",
66827
+ d: "M9 1.5H0V0.5H9V1.5Z",
66828
+ fill: "currentColor"
66829
+ }
66830
+ ),
66831
+ /* @__PURE__ */ jsx(
66832
+ "path",
66833
+ {
66834
+ fillRule: "evenodd",
66835
+ clipRule: "evenodd",
66836
+ d: "M9 9.5H0V8.5H9V9.5Z",
66837
+ fill: "currentColor"
66838
+ }
66839
+ )
66840
+ ] }),
66841
+ /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsx("clipPath", { id: "clip0_1222_1618", children: /* @__PURE__ */ jsx(
66842
+ "rect",
66843
+ {
66844
+ width: "9",
66845
+ height: "9",
66846
+ fill: "white",
66847
+ transform: "translate(0 0.5)"
66848
+ }
66849
+ ) }) })
66850
+ ]
66851
+ }
66852
+ );
66853
+ };
66854
+ const Section$1 = Section;
66855
+ const TextIcon = ({ className: className2 }) => {
66856
+ return /* @__PURE__ */ jsx(
66857
+ "svg",
66858
+ {
66859
+ width: "9",
66860
+ height: "10",
66861
+ viewBox: "0 0 9 10",
66862
+ fill: "currentColor",
66863
+ xmlns: "http://www.w3.org/2000/svg",
66864
+ className: className2,
66865
+ children: /* @__PURE__ */ jsx("g", { clipPath: "url(#clip0_1229_1625)", children: /* @__PURE__ */ jsx("path", { d: "M0.0145513 0.5H8.98545L9 3.18569H8.57074C8.43007 2.2276 8.02749 1.57948 7.36298 1.24133C6.98949 1.05491 6.43169 0.953035 5.68957 0.935694V7.94581C5.68957 8.43569 5.78416 8.76084 5.97332 8.92124C6.16734 9.08165 6.5675 9.16185 7.17381 9.16185V9.5H1.86257V9.16185C2.44462 9.16185 2.83023 9.08165 3.0194 8.92124C3.21342 8.7565 3.31043 8.43136 3.31043 7.94581V0.935694C2.58286 0.953035 2.02506 1.05491 1.63703 1.24133C0.92401 1.58815 0.521423 2.23627 0.429264 3.18569H0L0.0145513 0.5Z" }) })
66866
+ }
66867
+ );
66868
+ };
66869
+ const TextIcon$1 = TextIcon;
66870
+ function Tree({ children, rootPath }) {
66871
+ return /* @__PURE__ */ jsx("div", { className: "flex flex-col w-full py-2 text-xs", children: Children.map(children, (child) => {
66872
+ return cloneElement$1(child, {
66873
+ paths: [rootPath]
66874
+ });
66875
+ }) });
66876
+ }
66877
+ Tree.Node = ({
66878
+ children,
66879
+ paths = [],
66880
+ path,
66881
+ level = 1,
66882
+ type,
66883
+ setActivePath
66884
+ }) => {
66885
+ const paddingLeft = level * 30;
66886
+ const logo = type === "string" ? /* @__PURE__ */ jsx(TextIcon$1, {}) : type === "image" ? /* @__PURE__ */ jsx(ImageIcon$1, { className: "h-[9px] w-[9px]" }) : /* @__PURE__ */ jsx(Section$1, {});
66887
+ return /* @__PURE__ */ jsxs("div", { className: "w-full", children: [
66888
+ /* @__PURE__ */ jsx(
66889
+ "button",
66890
+ {
66891
+ className: "flex justify-between w-full group py-2 text-xs font-[400] shrink-0",
66892
+ onClick: () => {
66893
+ setActivePath && setActivePath(path);
66894
+ },
66895
+ style: { paddingLeft },
66896
+ children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center gap-2", children: [
66897
+ logo,
66898
+ /* @__PURE__ */ jsx("p", { children: path })
66899
+ ] })
66900
+ }
66901
+ ),
66902
+ children && /* @__PURE__ */ jsx(Fragment$1, { children: Children.map(children, (child) => {
66903
+ return cloneElement$1(child, {
66904
+ level: level + 1,
66905
+ paths: [...paths, path]
66906
+ });
66907
+ }) })
66908
+ ] });
66909
+ };
66910
+ const falsyToString = (value) => typeof value === "boolean" ? "".concat(value) : value === 0 ? "0" : value;
66911
+ const cx = clsx;
66912
+ const cva = (base, config) => {
66913
+ return (props) => {
66914
+ var ref;
66915
+ if ((config === null || config === void 0 ? void 0 : config.variants) == null)
66916
+ return cx(base, props === null || props === void 0 ? void 0 : props.class, props === null || props === void 0 ? void 0 : props.className);
66917
+ const { variants, defaultVariants } = config;
66918
+ const getVariantClassNames = Object.keys(variants).map((variant) => {
66919
+ const variantProp = props === null || props === void 0 ? void 0 : props[variant];
66920
+ const defaultVariantProp = defaultVariants === null || defaultVariants === void 0 ? void 0 : defaultVariants[variant];
66921
+ if (variantProp === null)
66922
+ return null;
66923
+ const variantKey = falsyToString(variantProp) || falsyToString(defaultVariantProp);
66924
+ return variants[variant][variantKey];
66925
+ });
66926
+ const propsWithoutUndefined = props && Object.entries(props).reduce((acc, param) => {
66927
+ let [key, value] = param;
66928
+ if (value === void 0) {
66929
+ return acc;
66930
+ }
66931
+ acc[key] = value;
66932
+ return acc;
66933
+ }, {});
66934
+ const getCompoundVariantClassNames = config === null || config === void 0 ? void 0 : (ref = config.compoundVariants) === null || ref === void 0 ? void 0 : ref.reduce((acc, param1) => {
66935
+ let { class: cvClass, className: cvClassName, ...compoundVariantOptions } = param1;
66936
+ return Object.entries(compoundVariantOptions).every((param) => {
66937
+ let [key, value] = param;
66938
+ return Array.isArray(value) ? value.includes({
66939
+ ...defaultVariants,
66940
+ ...propsWithoutUndefined
66941
+ }[key]) : {
66942
+ ...defaultVariants,
66943
+ ...propsWithoutUndefined
66944
+ }[key] === value;
66945
+ }) ? [
66946
+ ...acc,
66947
+ cvClass,
66948
+ cvClassName
66949
+ ] : acc;
66950
+ }, []);
66951
+ return cx(base, getVariantClassNames, getCompoundVariantClassNames, props === null || props === void 0 ? void 0 : props.class, props === null || props === void 0 ? void 0 : props.className);
66952
+ };
66953
+ };
66954
+ const buttonVariants = cva(
66955
+ "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
66956
+ {
66957
+ variants: {
66958
+ variant: {
66959
+ default: "bg-primary text-primary-foreground hover:bg-primary/90",
66960
+ destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
66961
+ outline: "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
66962
+ secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
66963
+ ghost: "hover:bg-accent hover:text-accent-foreground",
66964
+ link: "text-primary underline-offset-4 hover:underline"
66965
+ },
66966
+ size: {
66967
+ default: "h-10 px-4 py-2",
66968
+ sm: "h-9 rounded-md px-3",
66969
+ lg: "h-11 rounded-md px-8",
66970
+ icon: "h-10 w-10"
66971
+ }
66972
+ },
66973
+ defaultVariants: {
66974
+ variant: "default",
66975
+ size: "default"
66976
+ }
66977
+ }
66978
+ );
66979
+ const Button = React$3.forwardRef(
66980
+ ({ className: className2, variant, size: size2, asChild = false, ...props }, ref) => {
66981
+ const Comp = asChild ? $5e63c961fc1ce211$export$8c6ed5c666ac1360 : "button";
66982
+ return /* @__PURE__ */ jsx(
66983
+ Comp,
66984
+ {
66985
+ className: cn(buttonVariants({ variant, size: size2, className: className2 })),
66986
+ ref,
66987
+ ...props
66988
+ }
66989
+ );
66990
+ }
66991
+ );
66992
+ Button.displayName = "Button";
66680
66993
  const Input = React$3.forwardRef(
66681
66994
  ({ className: className2, type, ...props }, ref) => {
66682
66995
  return /* @__PURE__ */ jsx(
@@ -71083,255 +71396,544 @@ const SelectSeparator = React$3.forwardRef(({ className: className2, ...props },
71083
71396
  }
71084
71397
  ));
71085
71398
  SelectSeparator.displayName = $cc7e05a45900e73f$export$1ff3c3f08ae963c0.displayName;
71086
- function Grid({ children }) {
71087
- const leftColRef = useRef(null);
71088
- const rightColRef = useRef(null);
71089
- const isResizing = useRef(false);
71090
- const x = useRef(0);
71091
- const dragRef = useRef(null);
71092
- const originalWidth = useRef(0);
71093
- const handleMouseUp = () => {
71094
- isResizing.current = false;
71095
- dragRef.current = null;
71096
- x.current = 0;
71097
- originalWidth.current = 0;
71098
- };
71099
- const handleMouseMove = (event) => {
71100
- event.preventDefault();
71101
- const targetRef = dragRef.current === "left" ? leftColRef : rightColRef;
71102
- if (targetRef.current && isResizing.current) {
71103
- const dx = dragRef.current === "left" ? event.screenX - x.current : x.current - event.screenX;
71104
- targetRef.current.style.width = `${Math.max(
71105
- originalWidth.current + dx,
71106
- 150
71107
- )}px`;
71108
- }
71109
- };
71110
- const handleMouseDown = (column) => (event) => {
71111
- const target = event.target;
71112
- if (target) {
71113
- const columnRef = column === "left" ? leftColRef : column === "right" ? rightColRef : null;
71114
- isResizing.current = true;
71115
- if (columnRef && columnRef.current) {
71116
- x.current = event.screenX;
71117
- dragRef.current = column;
71118
- if (columnRef.current) {
71119
- originalWidth.current = columnRef.current.offsetWidth;
71120
- }
71399
+ function ValFormField({
71400
+ path,
71401
+ disabled,
71402
+ source,
71403
+ schema,
71404
+ registerPatchCallback,
71405
+ onSubmit
71406
+ }) {
71407
+ if ((typeof source === "string" || source === null) && (schema == null ? void 0 : schema.type) === "string") {
71408
+ return /* @__PURE__ */ jsx(
71409
+ StringField,
71410
+ {
71411
+ defaultValue: source,
71412
+ disabled,
71413
+ registerPatchCallback,
71414
+ onSubmit
71121
71415
  }
71122
- }
71123
- };
71124
- const [header1, body1, header2, body2, header3, body3] = Children.toArray(children);
71125
- useEffect(() => {
71126
- document.addEventListener("mouseup", handleMouseUp);
71127
- document.addEventListener("mousemove", handleMouseMove);
71128
- return () => {
71129
- document.removeEventListener("mouseup", handleMouseUp);
71130
- document.removeEventListener("mousemove", handleMouseMove);
71131
- };
71132
- }, []);
71133
- return /* @__PURE__ */ jsxs("div", { className: "flex h-screen", children: [
71134
- /* @__PURE__ */ jsxs(
71135
- "div",
71416
+ );
71417
+ }
71418
+ if ((typeof source === "number" || source === null) && (schema == null ? void 0 : schema.type) === "number") {
71419
+ return /* @__PURE__ */ jsx(
71420
+ NumberField,
71136
71421
  {
71137
- ref: leftColRef,
71138
- className: "relative border-r border-border",
71139
- style: { width: 300 },
71140
- children: [
71141
- /* @__PURE__ */ jsxs(Grid.Column, { children: [
71142
- header1,
71143
- /* @__PURE__ */ jsx(ScrollArea, { style: { height: "calc(100vh - 50px)" }, children: body1 })
71144
- ] }),
71145
- /* @__PURE__ */ jsx(
71146
- "div",
71147
- {
71148
- className: "absolute inset-y-0 right-0 cursor-col-resize w-[1px] hover:w-[3px] h-full hover:bg-border",
71149
- onMouseDown: handleMouseDown("left")
71150
- }
71151
- )
71152
- ]
71422
+ defaultValue: source,
71423
+ disabled,
71424
+ registerPatchCallback,
71425
+ onSubmit
71153
71426
  }
71154
- ),
71155
- /* @__PURE__ */ jsx(
71156
- "div",
71427
+ );
71428
+ }
71429
+ if ((typeof source === "number" || typeof source === "string" || source === null) && (schema == null ? void 0 : schema.type) === "keyOf") {
71430
+ return /* @__PURE__ */ jsx(
71431
+ KeyOfField,
71157
71432
  {
71158
- className: classNames("", {
71159
- "w-full": !header3 && !body3
71160
- }),
71161
- children: /* @__PURE__ */ jsxs(Grid.Column, { children: [
71162
- header2,
71163
- /* @__PURE__ */ jsx(ScrollArea, { style: { height: "calc(100vh - 50px)" }, children: body2 })
71164
- ] })
71433
+ defaultValue: source,
71434
+ disabled,
71435
+ registerPatchCallback,
71436
+ onSubmit,
71437
+ selector: schema.selector
71165
71438
  }
71166
- ),
71167
- header3 || body3 && /* @__PURE__ */ jsxs(
71168
- "div",
71439
+ );
71440
+ }
71441
+ if ((typeof source === "number" || source === null) && (schema == null ? void 0 : schema.type) === "number") {
71442
+ return /* @__PURE__ */ jsx(
71443
+ NumberField,
71169
71444
  {
71170
- ref: rightColRef,
71171
- className: "relative h-screen border-l border-border",
71172
- style: { width: 300 },
71173
- children: [
71174
- /* @__PURE__ */ jsxs(Grid.Column, { children: [
71175
- header3,
71176
- /* @__PURE__ */ jsx(ScrollArea, { style: { height: "calc(100vh - 50px)" }, children: body3 })
71177
- ] }),
71178
- /* @__PURE__ */ jsx(
71179
- "div",
71180
- {
71181
- onMouseDown: handleMouseDown("right"),
71182
- className: "absolute inset-y-0 left-0 cursor-col-resize w-[1px] bg-border hover:w-[3px] hover:bg-border"
71183
- }
71184
- )
71185
- ]
71445
+ defaultValue: source,
71446
+ disabled,
71447
+ registerPatchCallback,
71448
+ onSubmit
71186
71449
  }
71187
- )
71450
+ );
71451
+ }
71452
+ if ((typeof source === "number" || typeof source === "string" || source === null) && (schema == null ? void 0 : schema.type) === "keyOf") {
71453
+ return /* @__PURE__ */ jsx(
71454
+ KeyOfField,
71455
+ {
71456
+ defaultValue: source,
71457
+ disabled,
71458
+ registerPatchCallback,
71459
+ onSubmit,
71460
+ selector: schema.selector
71461
+ }
71462
+ );
71463
+ }
71464
+ if ((typeof source === "object" || source === null) && (schema == null ? void 0 : schema.type) === "richtext") {
71465
+ return /* @__PURE__ */ jsx(
71466
+ RichTextField,
71467
+ {
71468
+ registerPatchCallback,
71469
+ onSubmit,
71470
+ defaultValue: source
71471
+ }
71472
+ );
71473
+ }
71474
+ if ((typeof source === "object" || source === null) && (schema == null ? void 0 : schema.type) === "image") {
71475
+ return /* @__PURE__ */ jsx(
71476
+ ImageField,
71477
+ {
71478
+ path,
71479
+ registerPatchCallback,
71480
+ onSubmit,
71481
+ defaultValue: source
71482
+ }
71483
+ );
71484
+ }
71485
+ return /* @__PURE__ */ jsxs("div", { children: [
71486
+ "Unsupported schema: ",
71487
+ schema.type
71188
71488
  ] });
71189
71489
  }
71190
- Grid.Column = ({ children }) => {
71191
- const [header, body] = Children.toArray(children);
71192
- return /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
71193
- /* @__PURE__ */ jsx("div", { className: "flex items-center border-b border-border", children: header }),
71194
- body
71195
- ] });
71196
- };
71197
- const Section = ({ className: className2 }) => {
71198
- return /* @__PURE__ */ jsxs(
71199
- "svg",
71200
- {
71201
- width: "9",
71202
- height: "10",
71203
- viewBox: "0 0 9 10",
71204
- className: className2,
71205
- fill: "currentColor",
71206
- xmlns: "http://www.w3.org/2000/svg",
71207
- children: [
71208
- /* @__PURE__ */ jsxs("g", { clipPath: "url(#clip0_1222_1618)", children: [
71209
- /* @__PURE__ */ jsx(
71210
- "path",
71211
- {
71212
- fillRule: "evenodd",
71213
- clipRule: "evenodd",
71214
- d: "M9 1.5H0V0.5H9V1.5Z",
71215
- fill: "currentColor"
71216
- }
71217
- ),
71218
- /* @__PURE__ */ jsx(
71219
- "path",
71220
- {
71221
- fillRule: "evenodd",
71222
- clipRule: "evenodd",
71223
- d: "M9 9.5H0V8.5H9V9.5Z",
71224
- fill: "currentColor"
71225
- }
71226
- )
71227
- ] }),
71228
- /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsx("clipPath", { id: "clip0_1222_1618", children: /* @__PURE__ */ jsx(
71229
- "rect",
71230
- {
71231
- width: "9",
71232
- height: "9",
71233
- fill: "white",
71234
- transform: "translate(0 0.5)"
71235
- }
71236
- ) }) })
71237
- ]
71490
+ function createImagePatch(path, data, filename, metadata) {
71491
+ if (!data || !metadata) {
71492
+ return [];
71493
+ }
71494
+ const shaSuffix = metadata.sha256.slice(0, 5);
71495
+ const newFilePath = function() {
71496
+ const mimeType = getMimeType(data) ?? "unknown";
71497
+ const newExt = mimeTypeToFileExt(mimeType);
71498
+ if (filename) {
71499
+ const filenameWithoutExt = filename.split(".").slice(0, -1).join(".") || filename;
71500
+ return `/public/${filenameWithoutExt}_${shaSuffix}.${newExt}`;
71238
71501
  }
71239
- );
71240
- };
71241
- const Section$1 = Section;
71242
- const TextIcon = ({ className: className2 }) => {
71243
- return /* @__PURE__ */ jsx(
71244
- "svg",
71502
+ return `/public/${metadata.sha256}.${newExt}`;
71503
+ }();
71504
+ return [
71245
71505
  {
71246
- width: "9",
71247
- height: "10",
71248
- viewBox: "0 0 9 10",
71249
- fill: "currentColor",
71250
- xmlns: "http://www.w3.org/2000/svg",
71251
- className: className2,
71252
- children: /* @__PURE__ */ jsx("g", { clipPath: "url(#clip0_1229_1625)", children: /* @__PURE__ */ jsx("path", { d: "M0.0145513 0.5H8.98545L9 3.18569H8.57074C8.43007 2.2276 8.02749 1.57948 7.36298 1.24133C6.98949 1.05491 6.43169 0.953035 5.68957 0.935694V7.94581C5.68957 8.43569 5.78416 8.76084 5.97332 8.92124C6.16734 9.08165 6.5675 9.16185 7.17381 9.16185V9.5H1.86257V9.16185C2.44462 9.16185 2.83023 9.08165 3.0194 8.92124C3.21342 8.7565 3.31043 8.43136 3.31043 7.94581V0.935694C2.58286 0.953035 2.02506 1.05491 1.63703 1.24133C0.92401 1.58815 0.521423 2.23627 0.429264 3.18569H0L0.0145513 0.5Z" }) })
71506
+ value: {
71507
+ [FILE_REF_PROP]: newFilePath,
71508
+ [VAL_EXTENSION]: "file",
71509
+ metadata
71510
+ },
71511
+ op: "replace",
71512
+ path
71513
+ },
71514
+ {
71515
+ value: data,
71516
+ op: "file",
71517
+ path,
71518
+ filePath: newFilePath
71253
71519
  }
71254
- );
71255
- };
71256
- const TextIcon$1 = TextIcon;
71257
- function Tree({ children, rootPath }) {
71258
- return /* @__PURE__ */ jsx("div", { className: "flex flex-col w-full py-2 text-xs", children: Children.map(children, (child) => {
71259
- return cloneElement$1(child, {
71260
- paths: [rootPath]
71261
- });
71262
- }) });
71520
+ ];
71263
71521
  }
71264
- Tree.Node = ({
71265
- children,
71266
- paths = [],
71522
+ function ImageField({
71267
71523
  path,
71268
- level = 1,
71269
- type,
71270
- setActivePath
71271
- }) => {
71272
- const paddingLeft = level * 30;
71273
- const logo = type === "string" ? /* @__PURE__ */ jsx(TextIcon$1, {}) : type === "image" ? /* @__PURE__ */ jsx(ImageIcon$1, { className: "h-[9px] w-[9px]" }) : /* @__PURE__ */ jsx(Section$1, {});
71274
- return /* @__PURE__ */ jsxs("div", { className: "w-full", children: [
71275
- /* @__PURE__ */ jsx(
71276
- "button",
71524
+ defaultValue,
71525
+ onSubmit,
71526
+ registerPatchCallback
71527
+ }) {
71528
+ const [data, setData] = useState(
71529
+ null
71530
+ );
71531
+ const [loading, setLoading] = useState(false);
71532
+ const [metadata, setMetadata] = useState();
71533
+ const [url, setUrl] = useState();
71534
+ useEffect(() => {
71535
+ setUrl(defaultValue && Internal.convertFileSource(defaultValue).url);
71536
+ }, [defaultValue]);
71537
+ useEffect(() => {
71538
+ if (registerPatchCallback) {
71539
+ registerPatchCallback(async (path2) => {
71540
+ return createImagePatch(
71541
+ path2,
71542
+ (data == null ? void 0 : data.src) ?? null,
71543
+ (data == null ? void 0 : data.filename) ?? null,
71544
+ metadata
71545
+ );
71546
+ });
71547
+ }
71548
+ }, [data, defaultValue]);
71549
+ return /* @__PURE__ */ jsxs("div", { className: "max-w-4xl p-4", children: [
71550
+ /* @__PURE__ */ jsxs("label", { htmlFor: `img_input:${path}`, className: "", children: [
71551
+ data || url ? /* @__PURE__ */ jsx("img", { src: (data == null ? void 0 : data.src) || url }) : /* @__PURE__ */ jsx("div", { children: "Empty" }),
71552
+ /* @__PURE__ */ jsx(
71553
+ "input",
71554
+ {
71555
+ id: `img_input:${path}`,
71556
+ type: "file",
71557
+ hidden: true,
71558
+ onChange: (ev) => {
71559
+ readImage(ev).then((res) => {
71560
+ setData({ src: res.src, filename: res.filename });
71561
+ if (res.width && res.height) {
71562
+ setMetadata({
71563
+ sha256: res.sha256,
71564
+ width: res.width,
71565
+ height: res.height
71566
+ });
71567
+ } else {
71568
+ setMetadata(void 0);
71569
+ }
71570
+ }).catch((err2) => {
71571
+ console.error(err2.message);
71572
+ setData(null);
71573
+ setMetadata(void 0);
71574
+ });
71575
+ }
71576
+ }
71577
+ )
71578
+ ] }),
71579
+ onSubmit && /* @__PURE__ */ jsx("div", { children: data && /* @__PURE__ */ jsx(
71580
+ Button,
71277
71581
  {
71278
- className: "flex justify-between w-full group py-2 text-xs font-[400] shrink-0",
71582
+ disabled: loading,
71279
71583
  onClick: () => {
71280
- setActivePath && setActivePath(path);
71584
+ setLoading(true);
71585
+ onSubmit(
71586
+ (path2) => Promise.resolve(
71587
+ createImagePatch(
71588
+ path2,
71589
+ data.src,
71590
+ data.filename ?? null,
71591
+ metadata
71592
+ )
71593
+ )
71594
+ ).finally(() => {
71595
+ setLoading(false);
71596
+ setData(null);
71597
+ setMetadata(void 0);
71598
+ });
71281
71599
  },
71282
- style: { paddingLeft },
71283
- children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center gap-2", children: [
71284
- logo,
71285
- /* @__PURE__ */ jsx("p", { children: path })
71286
- ] })
71600
+ children: loading ? "Saving..." : "Save"
71287
71601
  }
71288
- ),
71289
- children && /* @__PURE__ */ jsx(Fragment$1, { children: Children.map(children, (child) => {
71290
- return cloneElement$1(child, {
71291
- level: level + 1,
71292
- paths: [...paths, path]
71293
- });
71294
- }) })
71295
- ] });
71296
- };
71297
- const Logo = ({ className: className2 }) => {
71298
- return /* @__PURE__ */ jsxs(
71299
- "svg",
71602
+ ) })
71603
+ ] }, path);
71604
+ }
71605
+ async function createRichTextPatch(path, editor) {
71606
+ const { templateStrings, exprs, files } = editor ? await lexicalToRichTextSource(
71607
+ editor.getEditorState().toJSON().root
71608
+ ) : {
71609
+ [VAL_EXTENSION]: "richtext",
71610
+ templateStrings: [""],
71611
+ exprs: [],
71612
+ files: {}
71613
+ };
71614
+ return [
71300
71615
  {
71301
- width: "58",
71302
- height: "34",
71303
- viewBox: "0 0 58 34",
71304
- fill: "none",
71305
- xmlns: "http://www.w3.org/2000/svg",
71306
- className: className2,
71307
- children: [
71308
- /* @__PURE__ */ jsx("g", { filter: "url(#filter0_d_21_1677)", children: /* @__PURE__ */ jsx(
71309
- "path",
71310
- {
71311
- d: "M5 5.36426C5 5.16309 5.16309 5 5.36426 5H17.6581C17.8593 5 18.0223 5.16309 18.0223 5.36426V28.4949C18.0223 28.696 17.8593 28.8591 17.6581 28.8591H5.36426C5.16309 28.8591 5 28.696 5 28.4949V5.36426Z",
71312
- fill: "#38CD98"
71616
+ op: "replace",
71617
+ path,
71618
+ value: {
71619
+ templateStrings,
71620
+ exprs,
71621
+ [VAL_EXTENSION]: "richtext"
71622
+ }
71623
+ },
71624
+ ...Object.entries(files).map(([filePath, value]) => {
71625
+ return {
71626
+ op: "file",
71627
+ path,
71628
+ filePath,
71629
+ value
71630
+ };
71631
+ })
71632
+ ];
71633
+ }
71634
+ function RichTextField({
71635
+ defaultValue,
71636
+ onSubmit,
71637
+ registerPatchCallback
71638
+ }) {
71639
+ const [editor, setEditor] = useState(null);
71640
+ const [didChange, setDidChange] = useState(false);
71641
+ const [loading, setLoading] = useState(false);
71642
+ useEffect(() => {
71643
+ if (editor) {
71644
+ setDidChange(false);
71645
+ editor.registerTextContentListener(() => {
71646
+ setDidChange(true);
71647
+ });
71648
+ editor.registerDecoratorListener(() => {
71649
+ setDidChange(true);
71650
+ });
71651
+ }
71652
+ }, [editor]);
71653
+ useEffect(() => {
71654
+ if (editor && registerPatchCallback) {
71655
+ registerPatchCallback((path) => createRichTextPatch(path, editor));
71656
+ }
71657
+ }, [editor]);
71658
+ return /* @__PURE__ */ jsxs("div", { className: "p-4 border rounded border-card", children: [
71659
+ /* @__PURE__ */ jsx(
71660
+ RichTextEditor,
71661
+ {
71662
+ onEditor: (editor2) => {
71663
+ setEditor(editor2);
71664
+ },
71665
+ richtext: defaultValue || {
71666
+ children: [],
71667
+ [VAL_EXTENSION]: "root"
71668
+ }
71669
+ }
71670
+ ),
71671
+ onSubmit && /* @__PURE__ */ jsx("div", { children: didChange && /* @__PURE__ */ jsx(
71672
+ Button,
71673
+ {
71674
+ disabled: loading || !editor,
71675
+ onClick: () => {
71676
+ if (editor) {
71677
+ setLoading(true);
71678
+ onSubmit((path) => createRichTextPatch(path, editor)).finally(
71679
+ () => {
71680
+ setLoading(false);
71681
+ setDidChange(false);
71682
+ }
71683
+ );
71313
71684
  }
71314
- ) }),
71315
- /* @__PURE__ */ jsx("g", { filter: "url(#filter1_i_21_1677)", children: /* @__PURE__ */ jsx("circle", { cx: "11.4656", cy: "23.7595", r: "2.18557", fill: "currentColor" }) }),
71316
- /* @__PURE__ */ jsx(
71317
- "path",
71685
+ },
71686
+ children: loading ? "Saving..." : "Save"
71687
+ }
71688
+ ) })
71689
+ ] });
71690
+ }
71691
+ function KeyOfField({
71692
+ disabled,
71693
+ defaultValue,
71694
+ registerPatchCallback,
71695
+ onSubmit,
71696
+ selector
71697
+ }) {
71698
+ const valModule = useValModuleFromPath(selector);
71699
+ const getValuesFromModule = (module) => {
71700
+ if (Array.isArray(module.moduleSource)) {
71701
+ return {
71702
+ type: "number",
71703
+ values: Object.keys(module.moduleSource).map((key) => parseInt(key))
71704
+ };
71705
+ }
71706
+ return {
71707
+ type: "string",
71708
+ values: Object.keys(module.moduleSource ?? ["ERROR fetching source"])
71709
+ };
71710
+ };
71711
+ const typeAndValues = getValuesFromModule(valModule);
71712
+ const [value, setValue] = useState(defaultValue || typeAndValues.values[0]);
71713
+ const [loading, setLoading] = useState(false);
71714
+ useEffect(() => {
71715
+ setLoading(disabled);
71716
+ }, [disabled]);
71717
+ const parse2 = (value2) => {
71718
+ if (typeAndValues.type === "number") {
71719
+ if (value2 === "") {
71720
+ throw new Error("Value cannot be empty");
71721
+ }
71722
+ if (Number.isNaN(Number(value2))) {
71723
+ throw new Error("Value was not a number: " + JSON.stringify(value2));
71724
+ }
71725
+ return Number(value2);
71726
+ }
71727
+ return value2;
71728
+ };
71729
+ useEffect(() => {
71730
+ if (registerPatchCallback) {
71731
+ registerPatchCallback(async (path) => {
71732
+ return [
71318
71733
  {
71319
- fillRule: "evenodd",
71320
- clipRule: "evenodd",
71321
- d: "M52.8588 23.839H48.7257H48.537H48.1128C47.6715 23.839 47.4508 23.5942 47.4508 23.1044V13.7293C47.4508 13.5784 47.3285 13.4561 47.1777 13.4561H45.8118C45.6609 13.4561 45.5386 13.5784 45.5386 13.7293V15.1836C45.5386 15.2844 45.4569 15.3661 45.3561 15.3661C45.2876 15.3661 45.225 15.3275 45.1924 15.2672C44.805 14.5503 44.283 14.02 43.6264 13.6765C42.9563 13.301 42.2045 13.1132 41.3709 13.1132C40.6028 13.1132 39.8755 13.252 39.189 13.5295C38.5026 13.8071 37.8979 14.2152 37.3748 14.7539C36.8682 15.2764 36.4678 15.9212 36.1736 16.6885C35.8794 17.4558 35.7323 18.3374 35.7323 19.3332V19.725C35.7323 20.7372 35.8794 21.627 36.1736 22.3942C36.4678 23.1615 36.8682 23.8146 37.3748 24.3533C37.8979 24.8757 38.5026 25.2757 39.189 25.5532C39.8755 25.8144 40.6191 25.945 41.42 25.945C42.1881 25.945 42.9154 25.7491 43.6019 25.3573C44.2751 24.982 44.8058 24.4119 45.1941 23.6471C45.2255 23.5852 45.2886 23.5452 45.358 23.5452H45.3917C45.4728 23.5452 45.5386 23.611 45.5386 23.6921C45.5386 23.7904 45.544 23.8856 45.5547 23.9777V25.1392C45.5547 25.3904 45.7584 25.5941 46.0096 25.5941H47.2261C47.2914 25.5995 47.3581 25.6022 47.4263 25.6022H48.537H48.7257H57.7268C57.8777 25.6022 58 25.4799 58 25.329V24.1122C58 23.9614 57.8777 23.839 57.7268 23.839H55.3174C55.1665 23.839 55.0442 23.7167 55.0442 23.5659V8.73368C55.0442 8.58279 54.9219 8.46048 54.771 8.46048H50.5054C50.3545 8.46048 50.2322 8.58279 50.2322 8.73368V9.95043C50.2322 10.1013 50.3545 10.2236 50.5054 10.2236H52.8588C53.0097 10.2236 53.132 10.3459 53.132 10.4968V23.5659C53.132 23.7167 53.0097 23.839 52.8588 23.839ZM41.6161 24.1329C42.1881 24.1329 42.7111 24.0268 43.1851 23.8146C43.6754 23.6023 44.0922 23.3003 44.4354 22.9085C44.7786 22.5167 45.0483 22.0514 45.2444 21.5127C45.4406 20.9576 45.5386 20.3454 45.5386 19.6761V19.3822C45.5386 18.7292 45.4406 18.1333 45.2444 17.5946C45.0483 17.0395 44.7705 16.5661 44.4109 16.1743C44.0677 15.7824 43.6509 15.4804 43.1606 15.2682C42.6866 15.0396 42.1718 14.9254 41.6161 14.9254C41.044 14.9254 40.521 15.0315 40.0471 15.2437C39.5731 15.4559 39.1563 15.758 38.7968 16.1498C38.4535 16.5252 38.1839 16.9905 37.9877 17.5456C37.7916 18.0843 37.6936 18.6802 37.6936 19.3332V19.725C37.6936 21.1127 38.0531 22.1983 38.7722 22.982C39.5077 23.7493 40.4557 24.1329 41.6161 24.1329ZM31.1115 25.4191C31.0732 25.5287 30.9698 25.6022 30.8536 25.6022H27.4661C27.35 25.6022 27.2465 25.5287 27.2082 25.4191L23.1578 13.8193C23.0958 13.6417 23.2276 13.4561 23.4157 13.4561H25.089C25.2068 13.4561 25.3114 13.5316 25.3484 13.6435L28.9666 24.581C28.9942 24.6643 29.0721 24.7206 29.1599 24.7206C29.2477 24.7206 29.3256 24.6643 29.3532 24.581L32.9714 13.6435C33.0084 13.5316 33.1129 13.4561 33.2308 13.4561H34.9041C35.0922 13.4561 35.224 13.6417 35.162 13.8193L31.1115 25.4191Z",
71322
- fill: "currentColor"
71734
+ op: "replace",
71735
+ path,
71736
+ value
71323
71737
  }
71324
- ),
71325
- /* @__PURE__ */ jsxs("defs", { children: [
71326
- /* @__PURE__ */ jsxs(
71327
- "filter",
71328
- {
71329
- id: "filter0_d_21_1677",
71330
- x: "0.124722",
71331
- y: "0.124722",
71332
- width: "22.7729",
71333
- height: "33.6097",
71334
- filterUnits: "userSpaceOnUse",
71738
+ ];
71739
+ });
71740
+ }
71741
+ }, [value]);
71742
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-col justify-between h-full gap-y-4", children: [
71743
+ /* @__PURE__ */ jsxs(
71744
+ Select,
71745
+ {
71746
+ defaultValue: value.toString(),
71747
+ disabled: loading,
71748
+ onValueChange: (value2) => {
71749
+ setValue(parse2(value2));
71750
+ },
71751
+ children: [
71752
+ /* @__PURE__ */ jsx(SelectTrigger, { children: /* @__PURE__ */ jsx(SelectValue, { placeholder: "Select a value" }) }),
71753
+ /* @__PURE__ */ jsx(SelectContent, { children: typeAndValues.values.map((value2) => /* @__PURE__ */ jsx(SelectItem, { value: value2.toString(), children: value2.toString() }, value2)) })
71754
+ ]
71755
+ }
71756
+ ),
71757
+ onSubmit && /* @__PURE__ */ jsx("div", { children: defaultValue !== value && /* @__PURE__ */ jsx(
71758
+ Button,
71759
+ {
71760
+ disabled: loading,
71761
+ onClick: () => {
71762
+ setLoading(true);
71763
+ onSubmit(async (path) => [
71764
+ {
71765
+ op: "replace",
71766
+ path,
71767
+ value
71768
+ }
71769
+ ]).finally(() => {
71770
+ setLoading(false);
71771
+ });
71772
+ },
71773
+ children: loading ? "Saving..." : "Save"
71774
+ }
71775
+ ) })
71776
+ ] });
71777
+ }
71778
+ function NumberField({
71779
+ disabled,
71780
+ defaultValue,
71781
+ registerPatchCallback,
71782
+ onSubmit
71783
+ }) {
71784
+ const [value, setValue] = useState(defaultValue || 0);
71785
+ const [loading, setLoading] = useState(false);
71786
+ useEffect(() => {
71787
+ setLoading(disabled);
71788
+ }, [disabled]);
71789
+ const ref = useRef(null);
71790
+ useEffect(() => {
71791
+ if (registerPatchCallback) {
71792
+ registerPatchCallback(async (path) => {
71793
+ var _a;
71794
+ return [
71795
+ {
71796
+ op: "replace",
71797
+ path,
71798
+ value: Number((_a = ref.current) == null ? void 0 : _a.value) || 0
71799
+ }
71800
+ ];
71801
+ });
71802
+ }
71803
+ }, []);
71804
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-col justify-between h-full gap-y-4", children: [
71805
+ /* @__PURE__ */ jsx(
71806
+ Input,
71807
+ {
71808
+ ref,
71809
+ disabled: loading,
71810
+ defaultValue: value ?? 0,
71811
+ onChange: (e) => setValue(Number(e.target.value)),
71812
+ type: "number"
71813
+ }
71814
+ ),
71815
+ onSubmit && /* @__PURE__ */ jsx("div", { children: defaultValue !== value && /* @__PURE__ */ jsx(
71816
+ Button,
71817
+ {
71818
+ disabled: loading,
71819
+ onClick: () => {
71820
+ setLoading(true);
71821
+ onSubmit(async (path) => {
71822
+ var _a;
71823
+ return [
71824
+ {
71825
+ op: "replace",
71826
+ path,
71827
+ value: Number((_a = ref.current) == null ? void 0 : _a.value) || 0
71828
+ }
71829
+ ];
71830
+ }).finally(() => {
71831
+ setLoading(false);
71832
+ });
71833
+ },
71834
+ children: loading ? "Saving..." : "Save"
71835
+ }
71836
+ ) })
71837
+ ] });
71838
+ }
71839
+ function StringField({
71840
+ disabled,
71841
+ defaultValue,
71842
+ registerPatchCallback,
71843
+ onSubmit
71844
+ }) {
71845
+ const [value, setValue] = useState(defaultValue || "");
71846
+ const [loading, setLoading] = useState(false);
71847
+ useEffect(() => {
71848
+ setLoading(disabled);
71849
+ }, [disabled]);
71850
+ const ref = useRef(null);
71851
+ useEffect(() => {
71852
+ if (registerPatchCallback) {
71853
+ registerPatchCallback(async (path) => {
71854
+ var _a;
71855
+ return [
71856
+ {
71857
+ op: "replace",
71858
+ path,
71859
+ value: ((_a = ref.current) == null ? void 0 : _a.value) || ""
71860
+ }
71861
+ ];
71862
+ });
71863
+ }
71864
+ }, []);
71865
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-col justify-between h-full gap-y-4", children: [
71866
+ /* @__PURE__ */ jsx(
71867
+ Input,
71868
+ {
71869
+ ref,
71870
+ disabled: loading,
71871
+ defaultValue: value ?? "",
71872
+ onChange: (e) => setValue(e.target.value)
71873
+ }
71874
+ ),
71875
+ onSubmit && /* @__PURE__ */ jsx("div", { children: defaultValue !== value && /* @__PURE__ */ jsx(
71876
+ Button,
71877
+ {
71878
+ disabled: loading,
71879
+ onClick: () => {
71880
+ setLoading(true);
71881
+ onSubmit(async (path) => {
71882
+ var _a;
71883
+ return [
71884
+ {
71885
+ op: "replace",
71886
+ path,
71887
+ value: ((_a = ref.current) == null ? void 0 : _a.value) || ""
71888
+ }
71889
+ ];
71890
+ }).finally(() => {
71891
+ setLoading(false);
71892
+ });
71893
+ },
71894
+ children: loading ? "Saving..." : "Save"
71895
+ }
71896
+ ) })
71897
+ ] });
71898
+ }
71899
+ const Logo = ({ className: className2 }) => {
71900
+ return /* @__PURE__ */ jsxs(
71901
+ "svg",
71902
+ {
71903
+ width: "58",
71904
+ height: "34",
71905
+ viewBox: "0 0 58 34",
71906
+ fill: "none",
71907
+ xmlns: "http://www.w3.org/2000/svg",
71908
+ className: className2,
71909
+ children: [
71910
+ /* @__PURE__ */ jsx("g", { filter: "url(#filter0_d_21_1677)", children: /* @__PURE__ */ jsx(
71911
+ "path",
71912
+ {
71913
+ d: "M5 5.36426C5 5.16309 5.16309 5 5.36426 5H17.6581C17.8593 5 18.0223 5.16309 18.0223 5.36426V28.4949C18.0223 28.696 17.8593 28.8591 17.6581 28.8591H5.36426C5.16309 28.8591 5 28.696 5 28.4949V5.36426Z",
71914
+ fill: "#38CD98"
71915
+ }
71916
+ ) }),
71917
+ /* @__PURE__ */ jsx("g", { filter: "url(#filter1_i_21_1677)", children: /* @__PURE__ */ jsx("circle", { cx: "11.4656", cy: "23.7595", r: "2.18557", fill: "currentColor" }) }),
71918
+ /* @__PURE__ */ jsx(
71919
+ "path",
71920
+ {
71921
+ fillRule: "evenodd",
71922
+ clipRule: "evenodd",
71923
+ d: "M52.8588 23.839H48.7257H48.537H48.1128C47.6715 23.839 47.4508 23.5942 47.4508 23.1044V13.7293C47.4508 13.5784 47.3285 13.4561 47.1777 13.4561H45.8118C45.6609 13.4561 45.5386 13.5784 45.5386 13.7293V15.1836C45.5386 15.2844 45.4569 15.3661 45.3561 15.3661C45.2876 15.3661 45.225 15.3275 45.1924 15.2672C44.805 14.5503 44.283 14.02 43.6264 13.6765C42.9563 13.301 42.2045 13.1132 41.3709 13.1132C40.6028 13.1132 39.8755 13.252 39.189 13.5295C38.5026 13.8071 37.8979 14.2152 37.3748 14.7539C36.8682 15.2764 36.4678 15.9212 36.1736 16.6885C35.8794 17.4558 35.7323 18.3374 35.7323 19.3332V19.725C35.7323 20.7372 35.8794 21.627 36.1736 22.3942C36.4678 23.1615 36.8682 23.8146 37.3748 24.3533C37.8979 24.8757 38.5026 25.2757 39.189 25.5532C39.8755 25.8144 40.6191 25.945 41.42 25.945C42.1881 25.945 42.9154 25.7491 43.6019 25.3573C44.2751 24.982 44.8058 24.4119 45.1941 23.6471C45.2255 23.5852 45.2886 23.5452 45.358 23.5452H45.3917C45.4728 23.5452 45.5386 23.611 45.5386 23.6921C45.5386 23.7904 45.544 23.8856 45.5547 23.9777V25.1392C45.5547 25.3904 45.7584 25.5941 46.0096 25.5941H47.2261C47.2914 25.5995 47.3581 25.6022 47.4263 25.6022H48.537H48.7257H57.7268C57.8777 25.6022 58 25.4799 58 25.329V24.1122C58 23.9614 57.8777 23.839 57.7268 23.839H55.3174C55.1665 23.839 55.0442 23.7167 55.0442 23.5659V8.73368C55.0442 8.58279 54.9219 8.46048 54.771 8.46048H50.5054C50.3545 8.46048 50.2322 8.58279 50.2322 8.73368V9.95043C50.2322 10.1013 50.3545 10.2236 50.5054 10.2236H52.8588C53.0097 10.2236 53.132 10.3459 53.132 10.4968V23.5659C53.132 23.7167 53.0097 23.839 52.8588 23.839ZM41.6161 24.1329C42.1881 24.1329 42.7111 24.0268 43.1851 23.8146C43.6754 23.6023 44.0922 23.3003 44.4354 22.9085C44.7786 22.5167 45.0483 22.0514 45.2444 21.5127C45.4406 20.9576 45.5386 20.3454 45.5386 19.6761V19.3822C45.5386 18.7292 45.4406 18.1333 45.2444 17.5946C45.0483 17.0395 44.7705 16.5661 44.4109 16.1743C44.0677 15.7824 43.6509 15.4804 43.1606 15.2682C42.6866 15.0396 42.1718 14.9254 41.6161 14.9254C41.044 14.9254 40.521 15.0315 40.0471 15.2437C39.5731 15.4559 39.1563 15.758 38.7968 16.1498C38.4535 16.5252 38.1839 16.9905 37.9877 17.5456C37.7916 18.0843 37.6936 18.6802 37.6936 19.3332V19.725C37.6936 21.1127 38.0531 22.1983 38.7722 22.982C39.5077 23.7493 40.4557 24.1329 41.6161 24.1329ZM31.1115 25.4191C31.0732 25.5287 30.9698 25.6022 30.8536 25.6022H27.4661C27.35 25.6022 27.2465 25.5287 27.2082 25.4191L23.1578 13.8193C23.0958 13.6417 23.2276 13.4561 23.4157 13.4561H25.089C25.2068 13.4561 25.3114 13.5316 25.3484 13.6435L28.9666 24.581C28.9942 24.6643 29.0721 24.7206 29.1599 24.7206C29.2477 24.7206 29.3256 24.6643 29.3532 24.581L32.9714 13.6435C33.0084 13.5316 33.1129 13.4561 33.2308 13.4561H34.9041C35.0922 13.4561 35.224 13.6417 35.162 13.8193L31.1115 25.4191Z",
71924
+ fill: "currentColor"
71925
+ }
71926
+ ),
71927
+ /* @__PURE__ */ jsxs("defs", { children: [
71928
+ /* @__PURE__ */ jsxs(
71929
+ "filter",
71930
+ {
71931
+ id: "filter0_d_21_1677",
71932
+ x: "0.124722",
71933
+ y: "0.124722",
71934
+ width: "22.7729",
71935
+ height: "33.6097",
71936
+ filterUnits: "userSpaceOnUse",
71335
71937
  colorInterpolationFilters: "sRGB",
71336
71938
  children: [
71337
71939
  /* @__PURE__ */ jsx("feFlood", { floodOpacity: "0", result: "BackgroundImageFix" }),
@@ -71975,36 +72577,6 @@ function useNavigateStable() {
71975
72577
  }
71976
72578
  new Promise(() => {
71977
72579
  });
71978
- function useTheme(defaultTheme = "dark") {
71979
- const [theme2, setTheme] = useState(defaultTheme);
71980
- useEffect(() => {
71981
- if (localStorage.getItem("val-theme") === "light") {
71982
- setTheme("light");
71983
- } else if (localStorage.getItem("val-theme") === "dark") {
71984
- setTheme("dark");
71985
- } else if (window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches) {
71986
- setTheme("dark");
71987
- } else if (window.matchMedia && window.matchMedia("(prefers-color-scheme: light)").matches) {
71988
- setTheme("light");
71989
- }
71990
- const themeListener = (e) => {
71991
- if (!localStorage.getItem("val-theme")) {
71992
- setTheme(e.matches ? "dark" : "light");
71993
- }
71994
- };
71995
- window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", themeListener);
71996
- return () => {
71997
- window.matchMedia("(prefers-color-scheme: dark)").removeEventListener("change", themeListener);
71998
- };
71999
- }, []);
72000
- return [
72001
- theme2,
72002
- (theme22) => {
72003
- localStorage.setItem("val-theme", theme22);
72004
- setTheme(theme22);
72005
- }
72006
- ];
72007
- }
72008
72580
  const ValModulesContext = React__default.createContext(null);
72009
72581
  const useValModuleFromPath = (sourcePath) => {
72010
72582
  var _a, _b;
@@ -72194,1356 +72766,766 @@ Showing stack trace of: 0. ${fatalErrors[0].message}`;
72194
72766
  ] }),
72195
72767
  /* @__PURE__ */ jsxs("div", { className: "p-4", children: [
72196
72768
  error && /* @__PURE__ */ jsxs("div", { className: "text-lg text-destructive-foreground", children: [
72197
- "ERROR: ",
72198
- error
72199
- ] }),
72200
- modules && selectedPath && selectedModuleId && moduleSource !== void 0 && moduleSchema !== void 0 && /* @__PURE__ */ jsx(ValModulesContext.Provider, { value: modules, children: /* @__PURE__ */ jsx(
72201
- ValModule,
72202
- {
72203
- path: selectedPath,
72204
- source: moduleSource,
72205
- schema: moduleSchema,
72206
- setSelectedPath,
72207
- initOnSubmit
72208
- }
72209
- ) })
72210
- ] })
72211
- ] }) })
72212
- }
72213
- )
72214
- ]
72215
- }
72216
- )
72217
- }
72218
- );
72219
- };
72220
- const ValFullscreenHoverContext = React__default.createContext({
72221
- hoverElem: null
72222
- });
72223
- const useValFullscreenHover = () => {
72224
- return React__default.useContext(ValFullscreenHoverContext);
72225
- };
72226
- function ValModule({
72227
- path,
72228
- source: moduleSource,
72229
- schema: moduleSchema,
72230
- setSelectedPath,
72231
- initOnSubmit
72232
- }) {
72233
- const [, modulePath] = Internal.splitModuleIdAndModulePath(
72234
- path
72235
- );
72236
- const resolvedPath = Internal.resolvePath(
72237
- modulePath,
72238
- moduleSource,
72239
- moduleSchema
72240
- );
72241
- if (!resolvedPath) {
72242
- throw Error("Could not resolve module: " + path);
72243
- }
72244
- return /* @__PURE__ */ jsx(
72245
- AnyVal,
72246
- {
72247
- path,
72248
- source: resolvedPath.source,
72249
- schema: resolvedPath.schema,
72250
- setSelectedPath,
72251
- initOnSubmit,
72252
- top: true
72253
- }
72254
- );
72255
- }
72256
- function AnyVal({
72257
- path,
72258
- source,
72259
- schema,
72260
- setSelectedPath,
72261
- field,
72262
- initOnSubmit,
72263
- top
72264
- }) {
72265
- if (source === null || schema.opt) {
72266
- return /* @__PURE__ */ jsx(
72267
- ValOptional,
72268
- {
72269
- path,
72270
- source,
72271
- schema,
72272
- field,
72273
- initOnSubmit,
72274
- setSelectedPath
72275
- }
72276
- );
72277
- }
72278
- if (schema.type === "object") {
72279
- if (typeof source !== "object" || isJsonArray(source)) {
72280
- return /* @__PURE__ */ jsxs("div", { children: [
72281
- "ERROR: expected object, but found ",
72282
- typeof source
72283
- ] });
72284
- }
72285
- return /* @__PURE__ */ jsx(
72286
- ValObject,
72287
- {
72288
- source,
72289
- path,
72290
- schema,
72291
- initOnSubmit,
72292
- setSelectedPath,
72293
- top
72294
- }
72295
- );
72296
- } else if (schema.type === "array") {
72297
- if (typeof source !== "object" || !isJsonArray(source)) {
72298
- return /* @__PURE__ */ jsxs("div", { children: [
72299
- "ERROR: expected array, but found ",
72300
- typeof source
72301
- ] });
72302
- }
72303
- return /* @__PURE__ */ jsx(
72304
- ValList,
72305
- {
72306
- source,
72307
- path,
72308
- schema,
72309
- setSelectedPath
72310
- }
72311
- );
72312
- } else if (schema.type === "record") {
72313
- if (typeof source !== "object") {
72314
- return /* @__PURE__ */ jsxs("div", { children: [
72315
- "ERROR: expected object for ",
72316
- schema.type,
72317
- ", but found ",
72318
- typeof source
72319
- ] });
72320
- }
72321
- if (isJsonArray(source)) {
72322
- return /* @__PURE__ */ jsxs("div", { children: [
72323
- "ERROR: did not expect array for ",
72324
- schema.type
72325
- ] });
72326
- }
72327
- return /* @__PURE__ */ jsx(
72328
- ValRecord,
72329
- {
72330
- source,
72331
- path,
72332
- schema,
72333
- setSelectedPath
72334
- }
72335
- );
72336
- }
72337
- return /* @__PURE__ */ jsxs("div", { className: "py-2 gap-y-4", children: [
72338
- /* @__PURE__ */ jsx("div", { className: "text-left", children: field || path }),
72339
- /* @__PURE__ */ jsx(
72340
- ValFormField,
72341
- {
72342
- path,
72343
- disabled: false,
72344
- source,
72345
- schema,
72346
- onSubmit: initOnSubmit(path)
72347
- }
72348
- )
72349
- ] });
72350
- }
72351
- function ValObject({
72352
- path,
72353
- source,
72354
- schema,
72355
- setSelectedPath,
72356
- initOnSubmit,
72357
- top
72358
- }) {
72359
- return /* @__PURE__ */ jsx(
72360
- "div",
72361
- {
72362
- className: classNames("flex flex-col gap-y-8", {
72363
- "border-l-2 border-border pl-6": !top
72364
- }),
72365
- children: Object.entries(schema.items).map(([key, property]) => {
72366
- const subPath = createValPathOfItem(path, key);
72367
- return /* @__PURE__ */ jsx(
72368
- AnyVal,
72369
- {
72370
- path: subPath,
72371
- source: source[key],
72372
- schema: property,
72373
- setSelectedPath,
72374
- field: key,
72375
- initOnSubmit
72376
- },
72377
- subPath
72378
- );
72379
- })
72380
- },
72381
- path
72382
- );
72383
- }
72384
- function ValRecord({
72385
- path,
72386
- source,
72387
- schema,
72388
- setSelectedPath
72389
- }) {
72390
- const navigate = useNavigate();
72391
- return /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-4 p-2", children: Object.entries(source).map(([key, item]) => {
72392
- const subPath = createValPathOfItem(path, key);
72393
- return /* @__PURE__ */ jsx(
72394
- "button",
72395
- {
72396
- onClick: () => {
72397
- setSelectedPath(subPath);
72398
- navigate(subPath);
72399
- },
72400
- children: /* @__PURE__ */ jsx(
72401
- ValRecordItem,
72402
- {
72403
- recordKey: key,
72404
- path: subPath,
72405
- source: item,
72406
- schema: schema.item
72407
- }
72408
- )
72409
- },
72410
- subPath
72411
- );
72412
- }) }, path);
72413
- }
72414
- const RECORD_ITEM_MAX_HEIGHT = 170;
72415
- function ValRecordItem({
72416
- recordKey,
72417
- path,
72418
- source,
72419
- schema
72420
- }) {
72421
- const ref = React__default.useRef(null);
72422
- const [isTruncated, setIsTruncated] = useState(false);
72423
- useEffect(() => {
72424
- if (ref.current) {
72425
- const height2 = ref.current.getBoundingClientRect().height;
72426
- if (height2 >= RECORD_ITEM_MAX_HEIGHT) {
72427
- setIsTruncated(true);
72428
- }
72429
- }
72430
- }, []);
72431
- return /* @__PURE__ */ jsxs(
72432
- Card,
72433
- {
72434
- ref,
72435
- className: "relative px-4 pt-2 pb-4 overflow-hidden border gap-y-2",
72436
- style: {
72437
- maxHeight: RECORD_ITEM_MAX_HEIGHT
72438
- },
72439
- children: [
72440
- /* @__PURE__ */ jsx("div", { className: "pb-4 font-serif text-left text-accent", children: recordKey }),
72441
- /* @__PURE__ */ jsx("div", { className: "text-xs", children: /* @__PURE__ */ jsx(ValPreview, { path, source, schema }) }),
72442
- isTruncated && /* @__PURE__ */ jsx("div", { className: "absolute bottom-0 left-0 w-full h-[20px] bg-gradient-to-b from-transparent to-background" })
72443
- ]
72444
- },
72445
- path
72446
- );
72447
- }
72448
- function ValList({
72449
- path,
72450
- source,
72451
- schema,
72452
- setSelectedPath
72453
- }) {
72454
- const navigate = useNavigate();
72455
- return /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-4 p-2", children: source.map((item, index2) => {
72456
- const subPath = createValPathOfItem(path, index2);
72457
- return /* @__PURE__ */ jsx(
72458
- "button",
72459
- {
72460
- onClick: () => {
72461
- setSelectedPath(subPath);
72462
- navigate(subPath);
72463
- },
72464
- children: /* @__PURE__ */ jsx(
72465
- ValListItem,
72466
- {
72467
- index: index2,
72468
- path: subPath,
72469
- source: item,
72470
- schema: schema.item
72471
- },
72472
- subPath
72473
- )
72474
- },
72475
- subPath
72476
- );
72477
- }) }, path);
72478
- }
72479
- const LIST_ITEM_MAX_HEIGHT = RECORD_ITEM_MAX_HEIGHT;
72480
- function ValListItem({
72481
- index: index2,
72482
- path,
72483
- source,
72484
- schema
72485
- }) {
72486
- const ref = React__default.useRef(null);
72487
- const [isTruncated, setIsTruncated] = useState(false);
72488
- useEffect(() => {
72489
- if (ref.current) {
72490
- const height2 = ref.current.getBoundingClientRect().height;
72491
- if (height2 >= LIST_ITEM_MAX_HEIGHT) {
72492
- setIsTruncated(true);
72493
- }
72494
- }
72495
- }, []);
72496
- return /* @__PURE__ */ jsxs(
72497
- Card,
72498
- {
72499
- ref,
72500
- className: "relative px-4 pt-2 pb-4 overflow-hidden border gap-y-2",
72501
- style: {
72502
- maxHeight: LIST_ITEM_MAX_HEIGHT
72503
- },
72504
- children: [
72505
- /* @__PURE__ */ jsx("div", { className: "pb-4 font-serif text-left uppercase text-accent", children: index2 + 1 < 10 ? `0${index2 + 1}` : index2 + 1 }),
72506
- /* @__PURE__ */ jsx("div", { className: "text-xs", children: /* @__PURE__ */ jsx(ValPreview, { path, source, schema }) }),
72507
- isTruncated && /* @__PURE__ */ jsx("div", { className: "absolute bottom-0 left-0 w-full h-[20px] bg-gradient-to-b from-transparent to-background" })
72508
- ]
72509
- }
72510
- );
72511
- }
72512
- function createValPathOfItem(arrayPath, prop) {
72513
- const val = Internal.createValPathOfItem(arrayPath, prop);
72514
- if (!val) {
72515
- throw Error(
72516
- `Could not create val path: ${arrayPath} of ${prop == null ? void 0 : prop.toString()}`
72517
- );
72518
- }
72519
- return val;
72520
- }
72521
- function ValPreview({
72522
- path,
72523
- source,
72524
- schema
72525
- }) {
72526
- const [isMouseOver, setIsMouseOver] = useState(null);
72527
- const { hoverElem } = useValFullscreenHover();
72528
- if (schema.type === "object") {
72529
- return /* @__PURE__ */ jsx(
72530
- "div",
72531
- {
72532
- className: "grid grid-cols-[min-content_1fr] gap-2 text-left",
72533
- children: Object.entries(schema.items).map(([key]) => {
72534
- return /* @__PURE__ */ jsxs(Fragment, { children: [
72535
- /* @__PURE__ */ jsxs("span", { className: "text-muted", children: [
72536
- key,
72537
- ":"
72538
- ] }),
72539
- /* @__PURE__ */ jsx("span", { children: /* @__PURE__ */ jsx(
72540
- ValPreview,
72541
- {
72542
- source: (source == null ? void 0 : source[key]) ?? null,
72543
- schema: schema.items[key],
72544
- path: createValPathOfItem(path, key)
72545
- }
72546
- ) })
72547
- ] }, createValPathOfItem(path, key));
72548
- })
72549
- },
72550
- path
72551
- );
72552
- } else if (schema.type === "array") {
72553
- if (source === null) {
72554
- return /* @__PURE__ */ jsx("span", { className: "text-accent", children: "Empty" }, path);
72555
- }
72556
- if (Array.isArray(source)) {
72557
- return /* @__PURE__ */ jsxs("span", { children: [
72558
- /* @__PURE__ */ jsx("span", { className: "text-accent", children: source.length }),
72559
- /* @__PURE__ */ jsx("span", { children: source.length === 1 ? " item" : " items" })
72560
- ] }, path);
72561
- }
72562
- return /* @__PURE__ */ jsx(
72563
- "span",
72564
- {
72565
- className: "px-2 bg-destructive text-destructive-foreground",
72566
- children: "Unknown length"
72567
- },
72568
- path
72569
- );
72570
- } else if (schema.type === "richtext") {
72571
- if (source === null) {
72572
- return /* @__PURE__ */ jsx("span", { className: "text-accent", children: "Empty" }, path);
72573
- }
72574
- if (typeof source !== "object") {
72575
- return /* @__PURE__ */ jsxs(
72576
- "div",
72577
- {
72578
- className: "p-4 text-destructive-foreground bg-destructive",
72579
- children: [
72580
- "ERROR: ",
72581
- typeof source,
72582
- " not an object"
72583
- ]
72584
- },
72585
- path
72586
- );
72587
- }
72588
- if (!(VAL_EXTENSION in source) || source[VAL_EXTENSION] !== "richtext") {
72589
- return /* @__PURE__ */ jsx(
72590
- "div",
72591
- {
72592
- className: "p-4 text-destructive-foreground bg-destructive",
72593
- children: "ERROR: object is not richtext"
72594
- },
72595
- path
72596
- );
72597
- }
72598
- return /* @__PURE__ */ jsx(ValRichText, { children: parseRichTextSource(source) }, path);
72599
- } else if (schema.type === "string") {
72600
- if (source === null) {
72601
- return /* @__PURE__ */ jsx("span", { className: "text-accent", children: "Empty" }, path);
72602
- }
72603
- return /* @__PURE__ */ jsx("span", { children: source });
72604
- } else if (schema.type === "image") {
72605
- if (source === null) {
72606
- return /* @__PURE__ */ jsx("span", { className: "text-accent", children: "Empty" }, path);
72607
- }
72608
- if (typeof source !== "object") {
72609
- return /* @__PURE__ */ jsx(
72610
- "div",
72611
- {
72612
- className: "p-4 text-destructive-foreground bg-destructive",
72613
- children: "ERROR: not an object"
72614
- },
72615
- path
72616
- );
72617
- }
72618
- if (!(FILE_REF_PROP in source) || typeof source[FILE_REF_PROP] !== "string") {
72619
- return /* @__PURE__ */ jsx(
72620
- "div",
72621
- {
72622
- className: "p-4 text-destructive-foreground bg-destructive",
72623
- children: "ERROR: object is not an image"
72624
- },
72625
- path
72626
- );
72627
- }
72628
- const url = Internal.convertFileSource(
72629
- source
72630
- ).url;
72631
- return /* @__PURE__ */ jsxs(
72632
- "span",
72633
- {
72634
- onMouseOver: (ev) => {
72635
- setIsMouseOver({
72636
- x: ev.clientX,
72637
- y: ev.clientY
72638
- });
72639
- },
72640
- onMouseLeave: () => {
72641
- setIsMouseOver(null);
72642
- },
72643
- className: "relative flex items-center justify-start gap-1",
72644
- children: [
72645
- /* @__PURE__ */ jsx("a", { href: url, className: "overflow-hidden underline truncate ", children: source[FILE_REF_PROP] }),
72646
- isMouseOver && hoverElem && reactDomExports.createPortal(
72647
- /* @__PURE__ */ jsx(
72648
- "img",
72649
- {
72650
- className: "absolute z-[5] max-w-[10vw]",
72651
- style: {
72652
- left: isMouseOver.x + 10,
72653
- top: isMouseOver.y + 10
72654
- },
72655
- src: url
72656
- }
72657
- ),
72658
- hoverElem
72659
- )
72660
- ]
72661
- },
72662
- path
72663
- );
72664
- } else if (schema.type === "boolean") {
72665
- if (source === null) {
72666
- return /* @__PURE__ */ jsx("span", { className: "text-accent", children: "Empty" }, path);
72667
- }
72668
- return /* @__PURE__ */ jsx("span", { className: "text-accent", children: source ? "true" : "false" }, path);
72669
- } else if (schema.type === "number") {
72670
- if (source === null) {
72671
- return /* @__PURE__ */ jsx("span", { className: "text-accent", children: "Empty" }, path);
72672
- }
72673
- return /* @__PURE__ */ jsx("span", { className: "text-accent", children: source.toString() });
72674
- } else if (schema.type === "keyOf") {
72675
- if (source === null) {
72676
- return /* @__PURE__ */ jsx("span", { className: "text-accent", children: "Empty" }, path);
72677
- }
72678
- return /* @__PURE__ */ jsx("span", { className: "text-accent", children: source.toString() }, path);
72679
- }
72680
- return /* @__PURE__ */ jsxs("div", { children: [
72681
- "TODO: ",
72682
- schema.type
72683
- ] }, path);
72684
- }
72685
- function ValOptional({
72686
- path,
72687
- source,
72688
- schema,
72689
- setSelectedPath,
72690
- initOnSubmit,
72691
- field
72692
- }) {
72693
- const [enable, setEnable] = useState(source !== null);
72694
- return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-y-6", children: [
72695
- field ? /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-start gap-x-4", children: [
72696
- /* @__PURE__ */ jsx(
72697
- Switch,
72698
- {
72699
- checked: enable,
72700
- onClick: () => {
72701
- setEnable((prev) => !prev);
72702
- }
72703
- }
72704
- ),
72705
- /* @__PURE__ */ jsx("span", { children: field })
72706
- ] }) : /* @__PURE__ */ jsx(
72707
- Switch,
72708
- {
72709
- checked: enable,
72710
- onClick: () => {
72711
- setEnable((prev) => !prev);
72712
- }
72713
- }
72714
- ),
72715
- enable && /* @__PURE__ */ jsx(
72716
- ValDefaultOf,
72717
- {
72718
- source,
72719
- schema,
72720
- path,
72721
- setSelectedPath,
72722
- initOnSubmit
72723
- }
72724
- )
72725
- ] }, path);
72726
- }
72727
- function ValDefaultOf({
72728
- source,
72729
- path,
72730
- schema,
72731
- setSelectedPath,
72732
- initOnSubmit
72733
- }) {
72734
- if (schema.type === "array") {
72735
- if (typeof source === "object" && (source === null || isJsonArray(source))) {
72736
- return /* @__PURE__ */ jsx(
72737
- ValList,
72738
- {
72739
- source: source === null ? [] : source,
72740
- path,
72741
- schema,
72742
- setSelectedPath
72743
- }
72744
- );
72745
- }
72746
- } else if (schema.type === "object") {
72747
- if (typeof source === "object" && (source === null || !isJsonArray(source))) {
72748
- return /* @__PURE__ */ jsx(
72749
- ValObject,
72750
- {
72751
- source,
72752
- path,
72753
- schema,
72754
- setSelectedPath,
72755
- initOnSubmit
72756
- }
72757
- );
72758
- }
72759
- } else if (schema.type === "richtext" || schema.type === "string" || schema.type === "image" || schema.type === "number" || schema.type === "keyOf") {
72760
- return /* @__PURE__ */ jsx(
72761
- ValFormField,
72762
- {
72763
- path,
72764
- disabled: false,
72765
- source,
72766
- schema,
72767
- onSubmit: initOnSubmit(path)
72768
- },
72769
- path
72770
- );
72771
- }
72772
- return /* @__PURE__ */ jsxs("div", { className: "p-4 bg-destructive text-destructive-foreground", children: [
72773
- "ERROR: unexpected source type ",
72774
- typeof source,
72775
- " for schema type",
72776
- " ",
72777
- schema.type
72778
- ] });
72779
- }
72780
- function isJsonArray(source) {
72781
- return Array.isArray(source);
72782
- }
72783
- function pathsToTree(paths) {
72784
- const tree = {};
72785
- paths.forEach((path) => {
72786
- const parts = path.split("/").filter((part) => part !== "");
72787
- let current = tree;
72788
- parts.forEach((part) => {
72789
- if (!current[part]) {
72790
- current[part] = {};
72791
- }
72792
- current = current[part];
72793
- });
72794
- });
72795
- return tree;
72796
- }
72797
- function PathTree({
72798
- paths,
72799
- setSelectedModuleId
72800
- }) {
72801
- const tree = pathsToTree(paths);
72802
- return /* @__PURE__ */ jsx(Tree, { children: Object.entries(tree).map(([name, subTree]) => /* @__PURE__ */ jsx("div", { className: "px-4 py-2", children: /* @__PURE__ */ jsx(
72803
- PathNode,
72804
- {
72805
- name,
72806
- tree: subTree,
72807
- moduleId: `/${name}`,
72808
- setSelectedModuleId
72809
- }
72810
- ) }, `/${name}`)) });
72811
- }
72812
- function PathNode({
72813
- name,
72814
- tree,
72815
- moduleId,
72816
- setSelectedModuleId
72817
- }) {
72818
- return /* @__PURE__ */ jsxs("div", { children: [
72819
- /* @__PURE__ */ jsx(
72820
- "button",
72821
- {
72822
- onClick: () => {
72823
- setSelectedModuleId(moduleId);
72824
- },
72825
- children: name
72826
- }
72827
- ),
72828
- Object.entries(tree).map(([childName, childTree]) => /* @__PURE__ */ jsx("div", { className: "px-4 py-1", children: /* @__PURE__ */ jsx(
72829
- PathNode,
72830
- {
72831
- name: childName,
72832
- tree: childTree,
72833
- moduleId: `${moduleId}/${childName}`,
72834
- setSelectedModuleId
72835
- }
72836
- ) }, `${moduleId}/${childName}`))
72837
- ] });
72838
- }
72839
- const theme = {
72840
- tags: {
72841
- h1: "font-bold",
72842
- h2: "font-bold",
72843
- h3: "font-bold",
72844
- h4: "font-bold",
72845
- h5: "font-bold",
72846
- h6: "font-bold",
72847
- p: ""
72848
- },
72849
- classes: {
72850
- bold: "font-bold",
72851
- italic: "italic",
72852
- lineThrough: "line-through"
72853
- }
72854
- };
72855
- function ValRichText({
72856
- children
72857
- }) {
72858
- const root = children;
72859
- function withRenderTag(clazz, current) {
72860
- const renderClass = theme.tags[clazz];
72861
- if (renderClass && current) {
72862
- return [current, renderClass].join(" ");
72863
- }
72864
- if (renderClass) {
72865
- return renderClass;
72866
- }
72867
- return current;
72868
- }
72869
- function withRenderClass(clazz, current) {
72870
- const renderClass = theme.classes[clazz];
72871
- if (renderClass && current) {
72872
- return [current, renderClass].join(" ");
72873
- }
72874
- if (renderClass) {
72875
- return renderClass;
72876
- }
72877
- return current;
72878
- }
72879
- function toReact(node, key) {
72880
- var _a, _b;
72881
- if (typeof node === "string") {
72882
- return node;
72883
- }
72884
- if (node.tag === "p") {
72885
- return /* @__PURE__ */ jsx("p", { className: withRenderTag("p"), children: node.children.map((child, key2) => toReact(child, key2)) }, key);
72886
- }
72887
- if (node.tag === "img") {
72888
- return /* @__PURE__ */ jsx("img", { className: withRenderTag("img"), src: node.src }, key);
72889
- }
72890
- if (node.tag === "ul") {
72891
- return /* @__PURE__ */ jsx("ul", { className: withRenderTag("ul"), children: node.children.map((child, key2) => toReact(child, key2)) }, key);
72892
- }
72893
- if (node.tag === "ol") {
72894
- return /* @__PURE__ */ jsx("ol", { className: withRenderTag("ol"), children: node.children.map((child, key2) => toReact(child, key2)) }, key);
72895
- }
72896
- if (node.tag === "li") {
72897
- return /* @__PURE__ */ jsx("li", { className: withRenderTag("li"), children: node.children.map((child, key2) => toReact(child, key2)) }, key);
72898
- }
72899
- if (node.tag === "span") {
72900
- return /* @__PURE__ */ jsx(
72901
- "span",
72902
- {
72903
- className: node.classes.map((nodeClass) => {
72904
- switch (nodeClass) {
72905
- case "bold":
72906
- return withRenderClass("bold");
72907
- case "line-through":
72908
- return withRenderClass("lineThrough");
72909
- case "italic":
72910
- return withRenderClass("italic");
72911
- }
72912
- }).join(" "),
72913
- children: node.children.map((child, key2) => toReact(child, key2))
72914
- },
72915
- key
72916
- );
72917
- }
72918
- if (node.tag === "h1") {
72919
- return /* @__PURE__ */ jsx("h1", { className: withRenderTag("h1"), children: node.children.map((child, key2) => toReact(child, key2)) }, key);
72920
- }
72921
- if (node.tag === "h2") {
72922
- return /* @__PURE__ */ jsx("h2", { className: withRenderTag("h2"), children: node.children.map((child, key2) => toReact(child, key2)) }, key);
72923
- }
72924
- if (node.tag === "h3") {
72925
- return /* @__PURE__ */ jsx("h3", { className: withRenderTag("h3"), children: node.children.map((child, key2) => toReact(child, key2)) }, key);
72926
- }
72927
- if (node.tag === "h4") {
72928
- return /* @__PURE__ */ jsx("h4", { className: withRenderTag("h4"), children: node.children.map((child, key2) => toReact(child, key2)) }, key);
72929
- }
72930
- if (node.tag === "h5") {
72931
- return /* @__PURE__ */ jsx("h5", { className: withRenderTag("h5"), children: node.children.map((child, key2) => toReact(child, key2)) }, key);
72932
- }
72933
- if (node.tag === "h6") {
72934
- return /* @__PURE__ */ jsx("h6", { className: withRenderTag("h6"), children: node.children.map((child, key2) => toReact(child, key2)) }, key);
72935
- }
72936
- if (node.tag === "br") {
72937
- return /* @__PURE__ */ jsx("br", {}, key);
72938
- }
72939
- if (node.tag === "a") {
72940
- return /* @__PURE__ */ jsx("a", { href: node.href, children: node.children.map((child, key2) => toReact(child, key2)) }, key);
72941
- }
72942
- console.error("Unknown tag", node.tag);
72943
- const _exhaustiveCheck = node.tag;
72944
- const anyNode = _exhaustiveCheck;
72945
- if (!(anyNode == null ? void 0 : anyNode.tag)) {
72946
- return null;
72769
+ "ERROR: ",
72770
+ error
72771
+ ] }),
72772
+ modules && selectedPath && selectedModuleId && moduleSource !== void 0 && moduleSchema !== void 0 && /* @__PURE__ */ jsx(ValModulesContext.Provider, { value: modules, children: /* @__PURE__ */ jsx(
72773
+ ValModule,
72774
+ {
72775
+ path: selectedPath,
72776
+ source: moduleSource,
72777
+ schema: moduleSchema,
72778
+ setSelectedPath,
72779
+ initOnSubmit
72780
+ }
72781
+ ) })
72782
+ ] })
72783
+ ] }) })
72784
+ }
72785
+ )
72786
+ ]
72787
+ }
72788
+ )
72947
72789
  }
72948
- return React__default.createElement(anyNode.tag, {
72949
- key,
72950
- className: (_a = anyNode.class) == null ? void 0 : _a.join(" "),
72951
- children: (_b = anyNode.children) == null ? void 0 : _b.map(toReact)
72952
- });
72790
+ );
72791
+ };
72792
+ const ValFullscreenHoverContext = React__default.createContext({
72793
+ hoverElem: null
72794
+ });
72795
+ const useValFullscreenHover = () => {
72796
+ return React__default.useContext(ValFullscreenHoverContext);
72797
+ };
72798
+ function ValModule({
72799
+ path,
72800
+ source: moduleSource,
72801
+ schema: moduleSchema,
72802
+ setSelectedPath,
72803
+ initOnSubmit
72804
+ }) {
72805
+ const [, modulePath] = Internal.splitModuleIdAndModulePath(
72806
+ path
72807
+ );
72808
+ const resolvedPath = Internal.resolvePath(
72809
+ modulePath,
72810
+ moduleSource,
72811
+ moduleSchema
72812
+ );
72813
+ if (!resolvedPath) {
72814
+ throw Error("Could not resolve module: " + path);
72953
72815
  }
72954
- return /* @__PURE__ */ jsx("span", { "data-val-path": root.valPath, children: root.children.map((child, i) => {
72955
- return toReact(child, i);
72956
- }) });
72816
+ return /* @__PURE__ */ jsx(
72817
+ AnyVal,
72818
+ {
72819
+ path,
72820
+ source: resolvedPath.source,
72821
+ schema: resolvedPath.schema,
72822
+ setSelectedPath,
72823
+ initOnSubmit,
72824
+ top: true
72825
+ }
72826
+ );
72957
72827
  }
72958
- function ValFormField({
72828
+ function AnyVal({
72959
72829
  path,
72960
- disabled,
72961
72830
  source,
72962
72831
  schema,
72963
- registerPatchCallback,
72964
- onSubmit
72832
+ setSelectedPath,
72833
+ field,
72834
+ initOnSubmit,
72835
+ top
72965
72836
  }) {
72966
- if ((typeof source === "string" || source === null) && (schema == null ? void 0 : schema.type) === "string") {
72967
- return /* @__PURE__ */ jsx(
72968
- StringField,
72969
- {
72970
- defaultValue: source,
72971
- disabled,
72972
- registerPatchCallback,
72973
- onSubmit
72974
- }
72975
- );
72976
- }
72977
- if ((typeof source === "number" || source === null) && (schema == null ? void 0 : schema.type) === "number") {
72978
- return /* @__PURE__ */ jsx(
72979
- NumberField,
72980
- {
72981
- defaultValue: source,
72982
- disabled,
72983
- registerPatchCallback,
72984
- onSubmit
72985
- }
72986
- );
72987
- }
72988
- if ((typeof source === "number" || typeof source === "string" || source === null) && (schema == null ? void 0 : schema.type) === "keyOf") {
72837
+ if (source === null || schema.opt) {
72989
72838
  return /* @__PURE__ */ jsx(
72990
- KeyOfField,
72839
+ ValOptional,
72991
72840
  {
72992
- defaultValue: source,
72993
- disabled,
72994
- registerPatchCallback,
72995
- onSubmit,
72996
- selector: schema.selector
72841
+ path,
72842
+ source,
72843
+ schema,
72844
+ field,
72845
+ initOnSubmit,
72846
+ setSelectedPath
72997
72847
  }
72998
72848
  );
72999
72849
  }
73000
- if ((typeof source === "number" || source === null) && (schema == null ? void 0 : schema.type) === "number") {
72850
+ if (schema.type === "object") {
72851
+ if (typeof source !== "object" || isJsonArray(source)) {
72852
+ return /* @__PURE__ */ jsxs("div", { children: [
72853
+ "ERROR: expected object, but found ",
72854
+ typeof source
72855
+ ] });
72856
+ }
73001
72857
  return /* @__PURE__ */ jsx(
73002
- NumberField,
72858
+ ValObject,
73003
72859
  {
73004
- defaultValue: source,
73005
- disabled,
73006
- registerPatchCallback,
73007
- onSubmit
72860
+ source,
72861
+ path,
72862
+ schema,
72863
+ initOnSubmit,
72864
+ setSelectedPath,
72865
+ top
73008
72866
  }
73009
72867
  );
73010
- }
73011
- if ((typeof source === "number" || typeof source === "string" || source === null) && (schema == null ? void 0 : schema.type) === "keyOf") {
72868
+ } else if (schema.type === "array") {
72869
+ if (typeof source !== "object" || !isJsonArray(source)) {
72870
+ return /* @__PURE__ */ jsxs("div", { children: [
72871
+ "ERROR: expected array, but found ",
72872
+ typeof source
72873
+ ] });
72874
+ }
73012
72875
  return /* @__PURE__ */ jsx(
73013
- KeyOfField,
72876
+ ValList,
73014
72877
  {
73015
- defaultValue: source,
73016
- disabled,
73017
- registerPatchCallback,
73018
- onSubmit,
73019
- selector: schema.selector
72878
+ source,
72879
+ path,
72880
+ schema,
72881
+ setSelectedPath
73020
72882
  }
73021
72883
  );
73022
- }
73023
- if ((typeof source === "object" || source === null) && (schema == null ? void 0 : schema.type) === "richtext") {
72884
+ } else if (schema.type === "record") {
72885
+ if (typeof source !== "object") {
72886
+ return /* @__PURE__ */ jsxs("div", { children: [
72887
+ "ERROR: expected object for ",
72888
+ schema.type,
72889
+ ", but found ",
72890
+ typeof source
72891
+ ] });
72892
+ }
72893
+ if (isJsonArray(source)) {
72894
+ return /* @__PURE__ */ jsxs("div", { children: [
72895
+ "ERROR: did not expect array for ",
72896
+ schema.type
72897
+ ] });
72898
+ }
73024
72899
  return /* @__PURE__ */ jsx(
73025
- RichTextField,
72900
+ ValRecord,
73026
72901
  {
73027
- registerPatchCallback,
73028
- onSubmit,
73029
- defaultValue: source
72902
+ source,
72903
+ path,
72904
+ schema,
72905
+ setSelectedPath
73030
72906
  }
73031
72907
  );
73032
72908
  }
73033
- if ((typeof source === "object" || source === null) && (schema == null ? void 0 : schema.type) === "image") {
73034
- return /* @__PURE__ */ jsx(
73035
- ImageField,
72909
+ return /* @__PURE__ */ jsxs("div", { className: "py-2 gap-y-4", children: [
72910
+ /* @__PURE__ */ jsx("div", { className: "text-left", children: field || path }),
72911
+ /* @__PURE__ */ jsx(
72912
+ ValFormField,
73036
72913
  {
73037
72914
  path,
73038
- registerPatchCallback,
73039
- onSubmit,
73040
- defaultValue: source
72915
+ disabled: false,
72916
+ source,
72917
+ schema,
72918
+ onSubmit: initOnSubmit(path)
73041
72919
  }
73042
- );
73043
- }
73044
- return /* @__PURE__ */ jsxs("div", { children: [
73045
- "Unsupported schema: ",
73046
- schema.type
72920
+ )
73047
72921
  ] });
73048
72922
  }
73049
- function createImagePatch(path, data, filename, metadata) {
73050
- if (!data || !metadata) {
73051
- return [];
73052
- }
73053
- const shaSuffix = metadata.sha256.slice(0, 5);
73054
- const newFilePath = function() {
73055
- const mimeType = getMimeType(data) ?? "unknown";
73056
- const newExt = mimeTypeToFileExt(mimeType);
73057
- if (filename) {
73058
- const filenameWithoutExt = filename.split(".").slice(0, -1).join(".") || filename;
73059
- return `/public/${filenameWithoutExt}_${shaSuffix}.${newExt}`;
72923
+ function ValObject({
72924
+ path,
72925
+ source,
72926
+ schema,
72927
+ setSelectedPath,
72928
+ initOnSubmit,
72929
+ top
72930
+ }) {
72931
+ return /* @__PURE__ */ jsx(
72932
+ "div",
72933
+ {
72934
+ className: classNames("flex flex-col gap-y-8", {
72935
+ "border-l-2 border-border pl-6": !top
72936
+ }),
72937
+ children: Object.entries(schema.items).map(([key, property]) => {
72938
+ const subPath = createValPathOfItem(path, key);
72939
+ return /* @__PURE__ */ jsx(
72940
+ AnyVal,
72941
+ {
72942
+ path: subPath,
72943
+ source: source[key],
72944
+ schema: property,
72945
+ setSelectedPath,
72946
+ field: key,
72947
+ initOnSubmit
72948
+ },
72949
+ subPath
72950
+ );
72951
+ })
72952
+ },
72953
+ path
72954
+ );
72955
+ }
72956
+ function ValRecord({
72957
+ path,
72958
+ source,
72959
+ schema,
72960
+ setSelectedPath
72961
+ }) {
72962
+ const navigate = useNavigate();
72963
+ return /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-4 p-2", children: Object.entries(source).map(([key, item]) => {
72964
+ const subPath = createValPathOfItem(path, key);
72965
+ return /* @__PURE__ */ jsx(
72966
+ "button",
72967
+ {
72968
+ onClick: () => {
72969
+ setSelectedPath(subPath);
72970
+ navigate(subPath);
72971
+ },
72972
+ children: /* @__PURE__ */ jsx(
72973
+ ValRecordItem,
72974
+ {
72975
+ recordKey: key,
72976
+ path: subPath,
72977
+ source: item,
72978
+ schema: schema.item
72979
+ }
72980
+ )
72981
+ },
72982
+ subPath
72983
+ );
72984
+ }) }, path);
72985
+ }
72986
+ const RECORD_ITEM_MAX_HEIGHT = 170;
72987
+ function ValRecordItem({
72988
+ recordKey,
72989
+ path,
72990
+ source,
72991
+ schema
72992
+ }) {
72993
+ const ref = React__default.useRef(null);
72994
+ const [isTruncated, setIsTruncated] = useState(false);
72995
+ useEffect(() => {
72996
+ if (ref.current) {
72997
+ const height2 = ref.current.getBoundingClientRect().height;
72998
+ if (height2 >= RECORD_ITEM_MAX_HEIGHT) {
72999
+ setIsTruncated(true);
73000
+ }
73060
73001
  }
73061
- return `/public/${metadata.sha256}.${newExt}`;
73062
- }();
73063
- return [
73002
+ }, []);
73003
+ return /* @__PURE__ */ jsxs(
73004
+ Card,
73064
73005
  {
73065
- value: {
73066
- [FILE_REF_PROP]: newFilePath,
73067
- [VAL_EXTENSION]: "file",
73068
- metadata
73006
+ ref,
73007
+ className: "relative px-4 pt-2 pb-4 overflow-hidden border gap-y-2",
73008
+ style: {
73009
+ maxHeight: RECORD_ITEM_MAX_HEIGHT
73069
73010
  },
73070
- op: "replace",
73071
- path
73011
+ children: [
73012
+ /* @__PURE__ */ jsx("div", { className: "pb-4 font-serif text-left text-accent", children: recordKey }),
73013
+ /* @__PURE__ */ jsx("div", { className: "text-xs", children: /* @__PURE__ */ jsx(ValPreview, { path, source, schema }) }),
73014
+ isTruncated && /* @__PURE__ */ jsx("div", { className: "absolute bottom-0 left-0 w-full h-[20px] bg-gradient-to-b from-transparent to-background" })
73015
+ ]
73072
73016
  },
73073
- {
73074
- value: data,
73075
- op: "file",
73076
- path,
73077
- filePath: newFilePath
73078
- }
73079
- ];
73017
+ path
73018
+ );
73080
73019
  }
73081
- function ImageField({
73020
+ function ValList({
73082
73021
  path,
73083
- defaultValue,
73084
- onSubmit,
73085
- registerPatchCallback
73022
+ source,
73023
+ schema,
73024
+ setSelectedPath
73086
73025
  }) {
73087
- const [data, setData] = useState(
73088
- null
73089
- );
73090
- const [loading, setLoading] = useState(false);
73091
- const [metadata, setMetadata] = useState();
73092
- const [url, setUrl] = useState();
73093
- useEffect(() => {
73094
- setUrl(defaultValue && Internal.convertFileSource(defaultValue).url);
73095
- }, [defaultValue]);
73096
- useEffect(() => {
73097
- if (registerPatchCallback) {
73098
- registerPatchCallback(async (path2) => {
73099
- return createImagePatch(
73100
- path2,
73101
- (data == null ? void 0 : data.src) ?? null,
73102
- (data == null ? void 0 : data.filename) ?? null,
73103
- metadata
73104
- );
73105
- });
73106
- }
73107
- }, [data, defaultValue]);
73108
- return /* @__PURE__ */ jsxs("div", { className: "max-w-4xl p-4", children: [
73109
- /* @__PURE__ */ jsxs("label", { htmlFor: `img_input:${path}`, className: "", children: [
73110
- data || url ? /* @__PURE__ */ jsx("img", { src: (data == null ? void 0 : data.src) || url }) : /* @__PURE__ */ jsx("div", { children: "Empty" }),
73111
- /* @__PURE__ */ jsx(
73112
- "input",
73113
- {
73114
- id: `img_input:${path}`,
73115
- type: "file",
73116
- hidden: true,
73117
- onChange: (ev) => {
73118
- readImage(ev).then((res) => {
73119
- setData({ src: res.src, filename: res.filename });
73120
- if (res.width && res.height) {
73121
- setMetadata({
73122
- sha256: res.sha256,
73123
- width: res.width,
73124
- height: res.height
73125
- });
73126
- } else {
73127
- setMetadata(void 0);
73128
- }
73129
- }).catch((err2) => {
73130
- console.error(err2.message);
73131
- setData(null);
73132
- setMetadata(void 0);
73133
- });
73134
- }
73135
- }
73136
- )
73137
- ] }),
73138
- onSubmit && /* @__PURE__ */ jsx("div", { children: data && /* @__PURE__ */ jsx(
73139
- Button,
73026
+ const navigate = useNavigate();
73027
+ return /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-4 p-2", children: source.map((item, index2) => {
73028
+ const subPath = createValPathOfItem(path, index2);
73029
+ return /* @__PURE__ */ jsx(
73030
+ "button",
73140
73031
  {
73141
- disabled: loading,
73142
73032
  onClick: () => {
73143
- setLoading(true);
73144
- onSubmit(
73145
- (path2) => Promise.resolve(
73146
- createImagePatch(
73147
- path2,
73148
- data.src,
73149
- data.filename ?? null,
73150
- metadata
73151
- )
73152
- )
73153
- ).finally(() => {
73154
- setLoading(false);
73155
- setData(null);
73156
- setMetadata(void 0);
73157
- });
73033
+ setSelectedPath(subPath);
73034
+ navigate(subPath);
73158
73035
  },
73159
- children: loading ? "Saving..." : "Submit"
73160
- }
73161
- ) })
73162
- ] }, path);
73036
+ children: /* @__PURE__ */ jsx(
73037
+ ValListItem,
73038
+ {
73039
+ index: index2,
73040
+ path: subPath,
73041
+ source: item,
73042
+ schema: schema.item
73043
+ },
73044
+ subPath
73045
+ )
73046
+ },
73047
+ subPath
73048
+ );
73049
+ }) }, path);
73163
73050
  }
73164
- async function createRichTextPatch(path, editor) {
73165
- const { templateStrings, exprs, files } = editor ? await lexicalToRichTextSource(
73166
- editor.getEditorState().toJSON().root
73167
- ) : {
73168
- [VAL_EXTENSION]: "richtext",
73169
- templateStrings: [""],
73170
- exprs: [],
73171
- files: {}
73172
- };
73173
- return [
73174
- {
73175
- op: "replace",
73176
- path,
73177
- value: {
73178
- templateStrings,
73179
- exprs,
73180
- [VAL_EXTENSION]: "richtext"
73051
+ const LIST_ITEM_MAX_HEIGHT = RECORD_ITEM_MAX_HEIGHT;
73052
+ function ValListItem({
73053
+ index: index2,
73054
+ path,
73055
+ source,
73056
+ schema
73057
+ }) {
73058
+ const ref = React__default.useRef(null);
73059
+ const [isTruncated, setIsTruncated] = useState(false);
73060
+ useEffect(() => {
73061
+ if (ref.current) {
73062
+ const height2 = ref.current.getBoundingClientRect().height;
73063
+ if (height2 >= LIST_ITEM_MAX_HEIGHT) {
73064
+ setIsTruncated(true);
73181
73065
  }
73182
- },
73183
- ...Object.entries(files).map(([filePath, value]) => {
73184
- return {
73185
- op: "file",
73186
- path,
73187
- filePath,
73188
- value
73189
- };
73190
- })
73191
- ];
73066
+ }
73067
+ }, []);
73068
+ return /* @__PURE__ */ jsxs(
73069
+ Card,
73070
+ {
73071
+ ref,
73072
+ className: "relative px-4 pt-2 pb-4 overflow-hidden border gap-y-2",
73073
+ style: {
73074
+ maxHeight: LIST_ITEM_MAX_HEIGHT
73075
+ },
73076
+ children: [
73077
+ /* @__PURE__ */ jsx("div", { className: "pb-4 font-serif text-left uppercase text-accent", children: index2 + 1 < 10 ? `0${index2 + 1}` : index2 + 1 }),
73078
+ /* @__PURE__ */ jsx("div", { className: "text-xs", children: /* @__PURE__ */ jsx(ValPreview, { path, source, schema }) }),
73079
+ isTruncated && /* @__PURE__ */ jsx("div", { className: "absolute bottom-0 left-0 w-full h-[20px] bg-gradient-to-b from-transparent to-background" })
73080
+ ]
73081
+ }
73082
+ );
73192
73083
  }
73193
- function RichTextField({
73194
- defaultValue,
73195
- onSubmit,
73196
- registerPatchCallback
73084
+ function createValPathOfItem(arrayPath, prop) {
73085
+ const val = Internal.createValPathOfItem(arrayPath, prop);
73086
+ if (!val) {
73087
+ throw Error(
73088
+ `Could not create val path: ${arrayPath} of ${prop == null ? void 0 : prop.toString()}`
73089
+ );
73090
+ }
73091
+ return val;
73092
+ }
73093
+ function ValPreview({
73094
+ path,
73095
+ source,
73096
+ schema
73197
73097
  }) {
73198
- const [editor, setEditor] = useState(null);
73199
- const [didChange, setDidChange] = useState(false);
73200
- const [loading, setLoading] = useState(false);
73201
- useEffect(() => {
73202
- if (editor) {
73203
- setDidChange(false);
73204
- editor.registerTextContentListener(() => {
73205
- setDidChange(true);
73206
- });
73207
- editor.registerDecoratorListener(() => {
73208
- setDidChange(true);
73209
- });
73098
+ const [isMouseOver, setIsMouseOver] = useState(null);
73099
+ const { hoverElem } = useValFullscreenHover();
73100
+ if (schema.type === "object") {
73101
+ return /* @__PURE__ */ jsx(
73102
+ "div",
73103
+ {
73104
+ className: "grid grid-cols-[min-content_1fr] gap-2 text-left",
73105
+ children: Object.entries(schema.items).map(([key]) => {
73106
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
73107
+ /* @__PURE__ */ jsxs("span", { className: "text-muted", children: [
73108
+ key,
73109
+ ":"
73110
+ ] }),
73111
+ /* @__PURE__ */ jsx("span", { children: /* @__PURE__ */ jsx(
73112
+ ValPreview,
73113
+ {
73114
+ source: (source == null ? void 0 : source[key]) ?? null,
73115
+ schema: schema.items[key],
73116
+ path: createValPathOfItem(path, key)
73117
+ }
73118
+ ) })
73119
+ ] }, createValPathOfItem(path, key));
73120
+ })
73121
+ },
73122
+ path
73123
+ );
73124
+ } else if (schema.type === "array") {
73125
+ if (source === null) {
73126
+ return /* @__PURE__ */ jsx("span", { className: "text-accent", children: "Empty" }, path);
73210
73127
  }
73211
- }, [editor]);
73212
- useEffect(() => {
73213
- if (editor && registerPatchCallback) {
73214
- registerPatchCallback((path) => createRichTextPatch(path, editor));
73128
+ if (Array.isArray(source)) {
73129
+ return /* @__PURE__ */ jsxs("span", { children: [
73130
+ /* @__PURE__ */ jsx("span", { className: "text-accent", children: source.length }),
73131
+ /* @__PURE__ */ jsx("span", { children: source.length === 1 ? " item" : " items" })
73132
+ ] }, path);
73215
73133
  }
73216
- }, [editor]);
73217
- return /* @__PURE__ */ jsxs("div", { className: "p-4 border rounded border-card", children: [
73218
- /* @__PURE__ */ jsx(
73219
- RichTextEditor,
73134
+ return /* @__PURE__ */ jsx(
73135
+ "span",
73220
73136
  {
73221
- onEditor: (editor2) => {
73222
- setEditor(editor2);
73137
+ className: "px-2 bg-destructive text-destructive-foreground",
73138
+ children: "Unknown length"
73139
+ },
73140
+ path
73141
+ );
73142
+ } else if (schema.type === "richtext") {
73143
+ if (source === null) {
73144
+ return /* @__PURE__ */ jsx("span", { className: "text-accent", children: "Empty" }, path);
73145
+ }
73146
+ if (typeof source !== "object") {
73147
+ return /* @__PURE__ */ jsxs(
73148
+ "div",
73149
+ {
73150
+ className: "p-4 text-destructive-foreground bg-destructive",
73151
+ children: [
73152
+ "ERROR: ",
73153
+ typeof source,
73154
+ " not an object"
73155
+ ]
73223
73156
  },
73224
- richtext: defaultValue || {
73225
- children: [],
73226
- [VAL_EXTENSION]: "root"
73227
- }
73228
- }
73229
- ),
73230
- onSubmit && /* @__PURE__ */ jsx("div", { children: didChange && /* @__PURE__ */ jsx(
73231
- Button,
73232
- {
73233
- disabled: loading || !editor,
73234
- onClick: () => {
73235
- if (editor) {
73236
- setLoading(true);
73237
- onSubmit((path) => createRichTextPatch(path, editor)).finally(
73238
- () => {
73239
- setLoading(false);
73240
- setDidChange(false);
73241
- }
73242
- );
73243
- }
73157
+ path
73158
+ );
73159
+ }
73160
+ if (!(VAL_EXTENSION in source) || source[VAL_EXTENSION] !== "richtext") {
73161
+ return /* @__PURE__ */ jsx(
73162
+ "div",
73163
+ {
73164
+ className: "p-4 text-destructive-foreground bg-destructive",
73165
+ children: "ERROR: object is not richtext"
73244
73166
  },
73245
- children: loading ? "Saving..." : "Submit"
73246
- }
73247
- ) })
73248
- ] });
73249
- }
73250
- function KeyOfField({
73251
- disabled,
73252
- defaultValue,
73253
- registerPatchCallback,
73254
- onSubmit,
73255
- selector
73256
- }) {
73257
- const valModule = useValModuleFromPath(selector);
73258
- const getValuesFromModule = (module) => {
73259
- if (Array.isArray(module.moduleSource)) {
73260
- return {
73261
- type: "number",
73262
- values: Object.keys(module.moduleSource).map((key) => parseInt(key))
73263
- };
73167
+ path
73168
+ );
73264
73169
  }
73265
- return {
73266
- type: "string",
73267
- values: Object.keys(module.moduleSource ?? ["ERROR fetching source"])
73268
- };
73269
- };
73270
- const typeAndValues = getValuesFromModule(valModule);
73271
- const [value, setValue] = useState(defaultValue || typeAndValues.values[0]);
73272
- const [loading, setLoading] = useState(false);
73273
- useEffect(() => {
73274
- setLoading(disabled);
73275
- }, [disabled]);
73276
- const parse2 = (value2) => {
73277
- if (typeAndValues.type === "number") {
73278
- if (value2 === "") {
73279
- throw new Error("Value cannot be empty");
73280
- }
73281
- if (Number.isNaN(Number(value2))) {
73282
- throw new Error("Value was not a number: " + JSON.stringify(value2));
73283
- }
73284
- return Number(value2);
73170
+ return /* @__PURE__ */ jsx(ValRichText, { children: parseRichTextSource(source) }, path);
73171
+ } else if (schema.type === "string") {
73172
+ if (source === null) {
73173
+ return /* @__PURE__ */ jsx("span", { className: "text-accent", children: "Empty" }, path);
73285
73174
  }
73286
- return value2;
73287
- };
73288
- useEffect(() => {
73289
- if (registerPatchCallback) {
73290
- registerPatchCallback(async (path) => {
73291
- return [
73292
- {
73293
- op: "replace",
73294
- path,
73295
- value
73296
- }
73297
- ];
73298
- });
73175
+ return /* @__PURE__ */ jsx("span", { children: source });
73176
+ } else if (schema.type === "image") {
73177
+ if (source === null) {
73178
+ return /* @__PURE__ */ jsx("span", { className: "text-accent", children: "Empty" }, path);
73299
73179
  }
73300
- }, [value]);
73301
- return /* @__PURE__ */ jsxs("div", { className: "flex flex-col justify-between h-full gap-y-4", children: [
73302
- /* @__PURE__ */ jsxs(
73303
- Select,
73180
+ if (typeof source !== "object") {
73181
+ return /* @__PURE__ */ jsx(
73182
+ "div",
73183
+ {
73184
+ className: "p-4 text-destructive-foreground bg-destructive",
73185
+ children: "ERROR: not an object"
73186
+ },
73187
+ path
73188
+ );
73189
+ }
73190
+ if (!(FILE_REF_PROP in source) || typeof source[FILE_REF_PROP] !== "string") {
73191
+ return /* @__PURE__ */ jsx(
73192
+ "div",
73193
+ {
73194
+ className: "p-4 text-destructive-foreground bg-destructive",
73195
+ children: "ERROR: object is not an image"
73196
+ },
73197
+ path
73198
+ );
73199
+ }
73200
+ const url = Internal.convertFileSource(
73201
+ source
73202
+ ).url;
73203
+ return /* @__PURE__ */ jsxs(
73204
+ "span",
73304
73205
  {
73305
- defaultValue: value.toString(),
73306
- disabled: loading,
73307
- onValueChange: (value2) => {
73308
- setValue(parse2(value2));
73206
+ onMouseOver: (ev) => {
73207
+ setIsMouseOver({
73208
+ x: ev.clientX,
73209
+ y: ev.clientY
73210
+ });
73309
73211
  },
73212
+ onMouseLeave: () => {
73213
+ setIsMouseOver(null);
73214
+ },
73215
+ className: "relative flex items-center justify-start gap-1",
73310
73216
  children: [
73311
- /* @__PURE__ */ jsx(SelectTrigger, { children: /* @__PURE__ */ jsx(SelectValue, { placeholder: "Select a value" }) }),
73312
- /* @__PURE__ */ jsx(SelectContent, { children: typeAndValues.values.map((value2) => /* @__PURE__ */ jsx(SelectItem, { value: value2.toString(), children: value2.toString() }, value2)) })
73217
+ /* @__PURE__ */ jsx("a", { href: url, className: "overflow-hidden underline truncate ", children: source[FILE_REF_PROP] }),
73218
+ isMouseOver && hoverElem && reactDomExports.createPortal(
73219
+ /* @__PURE__ */ jsx(
73220
+ "img",
73221
+ {
73222
+ className: "absolute z-[5] max-w-[10vw]",
73223
+ style: {
73224
+ left: isMouseOver.x + 10,
73225
+ top: isMouseOver.y + 10
73226
+ },
73227
+ src: url
73228
+ }
73229
+ ),
73230
+ hoverElem
73231
+ )
73313
73232
  ]
73233
+ },
73234
+ path
73235
+ );
73236
+ } else if (schema.type === "boolean") {
73237
+ if (source === null) {
73238
+ return /* @__PURE__ */ jsx("span", { className: "text-accent", children: "Empty" }, path);
73239
+ }
73240
+ return /* @__PURE__ */ jsx("span", { className: "text-accent", children: source ? "true" : "false" }, path);
73241
+ } else if (schema.type === "number") {
73242
+ if (source === null) {
73243
+ return /* @__PURE__ */ jsx("span", { className: "text-accent", children: "Empty" }, path);
73244
+ }
73245
+ return /* @__PURE__ */ jsx("span", { className: "text-accent", children: source.toString() });
73246
+ } else if (schema.type === "keyOf") {
73247
+ if (source === null) {
73248
+ return /* @__PURE__ */ jsx("span", { className: "text-accent", children: "Empty" }, path);
73249
+ }
73250
+ return /* @__PURE__ */ jsx("span", { className: "text-accent", children: source.toString() }, path);
73251
+ }
73252
+ return /* @__PURE__ */ jsxs("div", { children: [
73253
+ "TODO: ",
73254
+ schema.type
73255
+ ] }, path);
73256
+ }
73257
+ function ValOptional({
73258
+ path,
73259
+ source,
73260
+ schema,
73261
+ setSelectedPath,
73262
+ initOnSubmit,
73263
+ field
73264
+ }) {
73265
+ const [enable, setEnable] = useState(source !== null);
73266
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-y-6", children: [
73267
+ field ? /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-start gap-x-4", children: [
73268
+ /* @__PURE__ */ jsx(
73269
+ Switch,
73270
+ {
73271
+ checked: enable,
73272
+ onClick: () => {
73273
+ setEnable((prev) => !prev);
73274
+ }
73275
+ }
73276
+ ),
73277
+ /* @__PURE__ */ jsx("span", { children: field })
73278
+ ] }) : /* @__PURE__ */ jsx(
73279
+ Switch,
73280
+ {
73281
+ checked: enable,
73282
+ onClick: () => {
73283
+ setEnable((prev) => !prev);
73284
+ }
73314
73285
  }
73315
73286
  ),
73316
- onSubmit && /* @__PURE__ */ jsx("div", { children: defaultValue !== value && /* @__PURE__ */ jsx(
73317
- Button,
73287
+ enable && /* @__PURE__ */ jsx(
73288
+ ValDefaultOf,
73318
73289
  {
73319
- disabled: loading,
73320
- onClick: () => {
73321
- setLoading(true);
73322
- onSubmit(async (path) => [
73323
- {
73324
- op: "replace",
73325
- path,
73326
- value
73327
- }
73328
- ]).finally(() => {
73329
- setLoading(false);
73330
- });
73331
- },
73332
- children: loading ? "Saving..." : "Submit"
73290
+ source,
73291
+ schema,
73292
+ path,
73293
+ setSelectedPath,
73294
+ initOnSubmit
73333
73295
  }
73334
- ) })
73296
+ )
73297
+ ] }, path);
73298
+ }
73299
+ function ValDefaultOf({
73300
+ source,
73301
+ path,
73302
+ schema,
73303
+ setSelectedPath,
73304
+ initOnSubmit
73305
+ }) {
73306
+ if (schema.type === "array") {
73307
+ if (typeof source === "object" && (source === null || isJsonArray(source))) {
73308
+ return /* @__PURE__ */ jsx(
73309
+ ValList,
73310
+ {
73311
+ source: source === null ? [] : source,
73312
+ path,
73313
+ schema,
73314
+ setSelectedPath
73315
+ }
73316
+ );
73317
+ }
73318
+ } else if (schema.type === "object") {
73319
+ if (typeof source === "object" && (source === null || !isJsonArray(source))) {
73320
+ return /* @__PURE__ */ jsx(
73321
+ ValObject,
73322
+ {
73323
+ source,
73324
+ path,
73325
+ schema,
73326
+ setSelectedPath,
73327
+ initOnSubmit
73328
+ }
73329
+ );
73330
+ }
73331
+ } else if (schema.type === "richtext" || schema.type === "string" || schema.type === "image" || schema.type === "number" || schema.type === "keyOf") {
73332
+ return /* @__PURE__ */ jsx(
73333
+ ValFormField,
73334
+ {
73335
+ path,
73336
+ disabled: false,
73337
+ source,
73338
+ schema,
73339
+ onSubmit: initOnSubmit(path)
73340
+ },
73341
+ path
73342
+ );
73343
+ }
73344
+ return /* @__PURE__ */ jsxs("div", { className: "p-4 bg-destructive text-destructive-foreground", children: [
73345
+ "ERROR: unexpected source type ",
73346
+ typeof source,
73347
+ " for schema type",
73348
+ " ",
73349
+ schema.type
73335
73350
  ] });
73336
73351
  }
73337
- function NumberField({
73338
- disabled,
73339
- defaultValue,
73340
- registerPatchCallback,
73341
- onSubmit
73352
+ function isJsonArray(source) {
73353
+ return Array.isArray(source);
73354
+ }
73355
+ function pathsToTree(paths) {
73356
+ const tree = {};
73357
+ paths.forEach((path) => {
73358
+ const parts = path.split("/").filter((part) => part !== "");
73359
+ let current = tree;
73360
+ parts.forEach((part) => {
73361
+ if (!current[part]) {
73362
+ current[part] = {};
73363
+ }
73364
+ current = current[part];
73365
+ });
73366
+ });
73367
+ return tree;
73368
+ }
73369
+ function PathTree({
73370
+ paths,
73371
+ setSelectedModuleId
73342
73372
  }) {
73343
- const [value, setValue] = useState(defaultValue || 0);
73344
- const [loading, setLoading] = useState(false);
73345
- useEffect(() => {
73346
- setLoading(disabled);
73347
- }, [disabled]);
73348
- const ref = useRef(null);
73349
- useEffect(() => {
73350
- if (registerPatchCallback) {
73351
- registerPatchCallback(async (path) => {
73352
- var _a;
73353
- return [
73354
- {
73355
- op: "replace",
73356
- path,
73357
- value: Number((_a = ref.current) == null ? void 0 : _a.value) || 0
73358
- }
73359
- ];
73360
- });
73373
+ const tree = pathsToTree(paths);
73374
+ return /* @__PURE__ */ jsx(Tree, { children: Object.entries(tree).map(([name, subTree]) => /* @__PURE__ */ jsx("div", { className: "px-4 py-2", children: /* @__PURE__ */ jsx(
73375
+ PathNode,
73376
+ {
73377
+ name,
73378
+ tree: subTree,
73379
+ moduleId: `/${name}`,
73380
+ setSelectedModuleId
73361
73381
  }
73362
- }, []);
73363
- return /* @__PURE__ */ jsxs("div", { className: "flex flex-col justify-between h-full gap-y-4", children: [
73382
+ ) }, `/${name}`)) });
73383
+ }
73384
+ function PathNode({
73385
+ name,
73386
+ tree,
73387
+ moduleId,
73388
+ setSelectedModuleId
73389
+ }) {
73390
+ return /* @__PURE__ */ jsxs("div", { children: [
73364
73391
  /* @__PURE__ */ jsx(
73365
- Input,
73392
+ "button",
73366
73393
  {
73367
- ref,
73368
- disabled: loading,
73369
- defaultValue: value ?? 0,
73370
- onChange: (e) => setValue(Number(e.target.value)),
73371
- type: "number"
73394
+ onClick: () => {
73395
+ setSelectedModuleId(moduleId);
73396
+ },
73397
+ children: name
73372
73398
  }
73373
73399
  ),
73374
- onSubmit && /* @__PURE__ */ jsx("div", { children: defaultValue !== value && /* @__PURE__ */ jsx(
73375
- Button,
73400
+ Object.entries(tree).map(([childName, childTree]) => /* @__PURE__ */ jsx("div", { className: "px-4 py-1", children: /* @__PURE__ */ jsx(
73401
+ PathNode,
73376
73402
  {
73377
- disabled: loading,
73378
- onClick: () => {
73379
- setLoading(true);
73380
- onSubmit(async (path) => {
73381
- var _a;
73382
- return [
73383
- {
73384
- op: "replace",
73385
- path,
73386
- value: Number((_a = ref.current) == null ? void 0 : _a.value) || 0
73387
- }
73388
- ];
73389
- }).finally(() => {
73390
- setLoading(false);
73391
- });
73392
- },
73393
- children: loading ? "Saving..." : "Submit"
73403
+ name: childName,
73404
+ tree: childTree,
73405
+ moduleId: `${moduleId}/${childName}`,
73406
+ setSelectedModuleId
73394
73407
  }
73395
- ) })
73408
+ ) }, `${moduleId}/${childName}`))
73396
73409
  ] });
73397
73410
  }
73398
- function StringField({
73399
- disabled,
73400
- defaultValue,
73401
- registerPatchCallback,
73402
- onSubmit
73411
+ const theme = {
73412
+ tags: {
73413
+ h1: "font-bold",
73414
+ h2: "font-bold",
73415
+ h3: "font-bold",
73416
+ h4: "font-bold",
73417
+ h5: "font-bold",
73418
+ h6: "font-bold",
73419
+ p: ""
73420
+ },
73421
+ classes: {
73422
+ bold: "font-bold",
73423
+ italic: "italic",
73424
+ lineThrough: "line-through"
73425
+ }
73426
+ };
73427
+ function ValRichText({
73428
+ children
73403
73429
  }) {
73404
- const [value, setValue] = useState(defaultValue || "");
73405
- const [loading, setLoading] = useState(false);
73406
- useEffect(() => {
73407
- setLoading(disabled);
73408
- }, [disabled]);
73409
- const ref = useRef(null);
73410
- useEffect(() => {
73411
- if (registerPatchCallback) {
73412
- registerPatchCallback(async (path) => {
73413
- var _a;
73414
- return [
73415
- {
73416
- op: "replace",
73417
- path,
73418
- value: ((_a = ref.current) == null ? void 0 : _a.value) || ""
73419
- }
73420
- ];
73421
- });
73430
+ const root = children;
73431
+ function withRenderTag(clazz, current) {
73432
+ const renderClass = theme.tags[clazz];
73433
+ if (renderClass && current) {
73434
+ return [current, renderClass].join(" ");
73435
+ }
73436
+ if (renderClass) {
73437
+ return renderClass;
73438
+ }
73439
+ return current;
73440
+ }
73441
+ function withRenderClass(clazz, current) {
73442
+ const renderClass = theme.classes[clazz];
73443
+ if (renderClass && current) {
73444
+ return [current, renderClass].join(" ");
73445
+ }
73446
+ if (renderClass) {
73447
+ return renderClass;
73448
+ }
73449
+ return current;
73450
+ }
73451
+ function toReact(node, key) {
73452
+ var _a, _b;
73453
+ if (typeof node === "string") {
73454
+ return node;
73455
+ }
73456
+ if (node.tag === "p") {
73457
+ return /* @__PURE__ */ jsx("p", { className: withRenderTag("p"), children: node.children.map((child, key2) => toReact(child, key2)) }, key);
73458
+ }
73459
+ if (node.tag === "img") {
73460
+ return /* @__PURE__ */ jsx("img", { className: withRenderTag("img"), src: node.src }, key);
73461
+ }
73462
+ if (node.tag === "ul") {
73463
+ return /* @__PURE__ */ jsx("ul", { className: withRenderTag("ul"), children: node.children.map((child, key2) => toReact(child, key2)) }, key);
73464
+ }
73465
+ if (node.tag === "ol") {
73466
+ return /* @__PURE__ */ jsx("ol", { className: withRenderTag("ol"), children: node.children.map((child, key2) => toReact(child, key2)) }, key);
73467
+ }
73468
+ if (node.tag === "li") {
73469
+ return /* @__PURE__ */ jsx("li", { className: withRenderTag("li"), children: node.children.map((child, key2) => toReact(child, key2)) }, key);
73422
73470
  }
73423
- }, []);
73424
- return /* @__PURE__ */ jsxs("div", { className: "flex flex-col justify-between h-full gap-y-4", children: [
73425
- /* @__PURE__ */ jsx(
73426
- Input,
73427
- {
73428
- ref,
73429
- disabled: loading,
73430
- defaultValue: value ?? "",
73431
- onChange: (e) => setValue(e.target.value)
73432
- }
73433
- ),
73434
- onSubmit && /* @__PURE__ */ jsx("div", { children: defaultValue !== value && /* @__PURE__ */ jsx(
73435
- Button,
73436
- {
73437
- disabled: loading,
73438
- onClick: () => {
73439
- setLoading(true);
73440
- onSubmit(async (path) => {
73441
- var _a;
73442
- return [
73443
- {
73444
- op: "replace",
73445
- path,
73446
- value: ((_a = ref.current) == null ? void 0 : _a.value) || ""
73447
- }
73448
- ];
73449
- }).finally(() => {
73450
- setLoading(false);
73451
- });
73471
+ if (node.tag === "span") {
73472
+ return /* @__PURE__ */ jsx(
73473
+ "span",
73474
+ {
73475
+ className: node.classes.map((nodeClass) => {
73476
+ switch (nodeClass) {
73477
+ case "bold":
73478
+ return withRenderClass("bold");
73479
+ case "line-through":
73480
+ return withRenderClass("lineThrough");
73481
+ case "italic":
73482
+ return withRenderClass("italic");
73483
+ }
73484
+ }).join(" "),
73485
+ children: node.children.map((child, key2) => toReact(child, key2))
73452
73486
  },
73453
- children: loading ? "Saving..." : "Submit"
73454
- }
73455
- ) })
73456
- ] });
73457
- }
73458
- function usePatch(paths, api, valStore, onSubmit, session) {
73459
- const [state, setState] = useState({});
73460
- const [error, setError] = useState(null);
73461
- const [progress, setProgress] = useState("ready");
73462
- const initPatchCallback = useCallback(
73463
- (pathsAttr) => {
73464
- return (callback) => {
73465
- setState((prev) => {
73466
- const paths2 = pathsAttr.split(",");
73467
- const nextState = paths2.reduce((acc, path) => {
73468
- const patchPath = Internal.createPatchJSONPath(
73469
- Internal.splitModuleIdAndModulePath(path)[1]
73470
- );
73471
- return {
73472
- ...acc,
73473
- [path]: () => callback(patchPath)
73474
- };
73475
- }, {});
73476
- return {
73477
- ...prev,
73478
- ...nextState
73479
- };
73480
- });
73481
- };
73482
- },
73483
- []
73484
- );
73485
- useEffect(() => {
73486
- setState((prev) => {
73487
- const newState = {};
73488
- for (const path of paths) {
73489
- if (prev[path]) {
73490
- newState[path] = prev[path];
73491
- }
73492
- }
73493
- if (Object.keys(newState).length === Object.keys(prev).length) {
73494
- return prev;
73495
- }
73496
- return newState;
73497
- });
73498
- }, [paths]);
73499
- const onSubmitPatch = useCallback(async () => {
73500
- setError(null);
73501
- setProgress("create_patch");
73502
- const patches = {};
73503
- for (const path in state) {
73504
- const [moduleId] = Internal.splitModuleIdAndModulePath(
73505
- path
73487
+ key
73506
73488
  );
73507
- const patch = await state[path]();
73508
- patches[moduleId] = patch;
73509
73489
  }
73510
- return maybeStartViewTransition(() => {
73511
- setProgress("patching");
73512
- return Promise.all(
73513
- Object.entries(patches).map(
73514
- ([moduleId, patch]) => api.postPatches(moduleId, patch).then((res) => {
73515
- if (result.isErr(res)) {
73516
- throw res.error;
73517
- } else {
73518
- res.value;
73519
- }
73520
- })
73521
- )
73522
- ).then(() => {
73523
- setProgress("on_submit");
73524
- const refreshRequired = session.status === "success" && session.data.mode === "proxy";
73525
- return onSubmit(refreshRequired);
73526
- }).then(() => {
73527
- setProgress("update_store");
73528
- return valStore.update(
73529
- paths.map(
73530
- (path) => Internal.splitModuleIdAndModulePath(path)[0]
73531
- )
73532
- );
73533
- });
73534
- }).catch((err2) => {
73535
- setError(err2);
73536
- }).finally(() => {
73537
- setProgress("ready");
73490
+ if (node.tag === "h1") {
73491
+ return /* @__PURE__ */ jsx("h1", { className: withRenderTag("h1"), children: node.children.map((child, key2) => toReact(child, key2)) }, key);
73492
+ }
73493
+ if (node.tag === "h2") {
73494
+ return /* @__PURE__ */ jsx("h2", { className: withRenderTag("h2"), children: node.children.map((child, key2) => toReact(child, key2)) }, key);
73495
+ }
73496
+ if (node.tag === "h3") {
73497
+ return /* @__PURE__ */ jsx("h3", { className: withRenderTag("h3"), children: node.children.map((child, key2) => toReact(child, key2)) }, key);
73498
+ }
73499
+ if (node.tag === "h4") {
73500
+ return /* @__PURE__ */ jsx("h4", { className: withRenderTag("h4"), children: node.children.map((child, key2) => toReact(child, key2)) }, key);
73501
+ }
73502
+ if (node.tag === "h5") {
73503
+ return /* @__PURE__ */ jsx("h5", { className: withRenderTag("h5"), children: node.children.map((child, key2) => toReact(child, key2)) }, key);
73504
+ }
73505
+ if (node.tag === "h6") {
73506
+ return /* @__PURE__ */ jsx("h6", { className: withRenderTag("h6"), children: node.children.map((child, key2) => toReact(child, key2)) }, key);
73507
+ }
73508
+ if (node.tag === "br") {
73509
+ return /* @__PURE__ */ jsx("br", {}, key);
73510
+ }
73511
+ if (node.tag === "a") {
73512
+ return /* @__PURE__ */ jsx("a", { href: node.href, children: node.children.map((child, key2) => toReact(child, key2)) }, key);
73513
+ }
73514
+ console.error("Unknown tag", node.tag);
73515
+ const _exhaustiveCheck = node.tag;
73516
+ const anyNode = _exhaustiveCheck;
73517
+ if (!(anyNode == null ? void 0 : anyNode.tag)) {
73518
+ return null;
73519
+ }
73520
+ return React__default.createElement(anyNode.tag, {
73521
+ key,
73522
+ className: (_a = anyNode.class) == null ? void 0 : _a.join(" "),
73523
+ children: (_b = anyNode.children) == null ? void 0 : _b.map(toReact)
73538
73524
  });
73539
- }, [state, session]);
73540
- return { initPatchCallback, onSubmitPatch, error, progress };
73541
- }
73542
- async function maybeStartViewTransition(f) {
73543
- if ("startViewTransition" in document && typeof document.startViewTransition === "function") {
73544
- await document.startViewTransition(f);
73545
73525
  }
73546
- await f();
73526
+ return /* @__PURE__ */ jsx("span", { "data-val-path": root.valPath, children: root.children.map((child, i) => {
73527
+ return toReact(child, i);
73528
+ }) });
73547
73529
  }
73548
73530
  function ValOverlay({
73549
73531
  defaultTheme,
@@ -73557,32 +73539,48 @@ function ValOverlay({
73557
73539
  const [hoverTarget, setHoverTarget] = useHoverTarget(editMode);
73558
73540
  const [windowTarget, setWindowTarget] = useState(null);
73559
73541
  const [highlight, setHighlight] = useState(false);
73560
- const { selectedSchema, selectedSource, moduleId, error, loading } = useValModules(api, windowTarget == null ? void 0 : windowTarget.path);
73542
+ const paths = (windowTarget == null ? void 0 : windowTarget.path) ? windowTarget.path.split(",") : [];
73543
+ const [formData, setFormData] = useState(
73544
+ Object.fromEntries(
73545
+ paths.map((path) => {
73546
+ return [path, { status: "not-asked" }];
73547
+ })
73548
+ )
73549
+ );
73550
+ useEffect(() => {
73551
+ setFormData(
73552
+ Object.fromEntries(paths.map((path) => [path, { status: "loading" }]))
73553
+ );
73554
+ for (const path of paths) {
73555
+ updateFormData(api, path, setFormData);
73556
+ }
73557
+ }, [paths.join(";")]);
73558
+ const selectedPaths = (windowTarget == null ? void 0 : windowTarget.path) ? paths : [];
73561
73559
  const {
73562
- initPatchCallback,
73563
73560
  onSubmitPatch,
73564
- progress: patchProgress,
73561
+ // progress: patchProgress,
73565
73562
  error: patchError
73566
- } = usePatch(
73567
- (windowTarget == null ? void 0 : windowTarget.path) ? [windowTarget.path] : [],
73568
- api,
73569
- store,
73570
- onSubmit,
73571
- session
73572
- );
73563
+ } = usePatch(selectedPaths, api, store, onSubmit, session);
73573
73564
  const [windowSize, setWindowSize] = useState();
73574
73565
  useEffect(() => {
73575
- if (moduleId) {
73576
- store.update([moduleId]);
73577
- } else {
73578
- store.updateAll();
73579
- }
73580
- }, [moduleId]);
73566
+ store.updateAll();
73567
+ }, []);
73581
73568
  useEffect(() => {
73582
73569
  if (patchError) {
73583
73570
  console.error(patchError);
73584
73571
  }
73585
73572
  }, [patchError]);
73573
+ const initOnSubmit = useCallback(
73574
+ (path) => async (callback) => {
73575
+ const [moduleId, modulePath] = Internal.splitModuleIdAndModulePath(path);
73576
+ const patch = await callback(Internal.createPatchJSONPath(modulePath));
73577
+ await api.postPatches(moduleId, patch);
73578
+ return onSubmitPatch().then(() => store.update([moduleId])).then(() => {
73579
+ updateFormData(api, path, setFormData);
73580
+ });
73581
+ },
73582
+ []
73583
+ );
73586
73584
  return /* @__PURE__ */ jsx(
73587
73585
  ValOverlayContext.Provider,
73588
73586
  {
@@ -73600,7 +73598,7 @@ function ValOverlay({
73600
73598
  },
73601
73599
  children: /* @__PURE__ */ jsxs("div", { "data-mode": theme2, className: "antialiased", children: [
73602
73600
  /* @__PURE__ */ jsx("div", { className: "fixed -translate-x-1/2 z-overlay left-1/2 bottom-4", children: /* @__PURE__ */ jsx(ValMenu, { api }) }),
73603
- editMode === "hover" && hoverTarget.path && /* @__PURE__ */ jsx(
73601
+ session.status === "success" && session.data.enabled && editMode === "hover" && hoverTarget.path && /* @__PURE__ */ jsx(
73604
73602
  ValHover,
73605
73603
  {
73606
73604
  hoverTarget,
@@ -73609,134 +73607,109 @@ function ValOverlay({
73609
73607
  setWindowTarget
73610
73608
  }
73611
73609
  ),
73612
- editMode === "window" && windowTarget && /* @__PURE__ */ jsxs(
73610
+ editMode === "window" && windowTarget && /* @__PURE__ */ jsx(
73613
73611
  ValWindow,
73614
73612
  {
73615
73613
  onClose: () => {
73616
73614
  setWindowTarget(null);
73617
73615
  setEditMode("hover");
73618
73616
  },
73619
- children: [
73620
- /* @__PURE__ */ jsx("div", { className: "max-w-full px-4 py-2 text-sm border-b border-highlight", children: /* @__PURE__ */ jsx(
73621
- WindowHeader,
73622
- {
73623
- path: windowTarget.path,
73624
- type: selectedSchema == null ? void 0 : selectedSchema.type
73625
- }
73626
- ) }),
73627
- loading && /* @__PURE__ */ jsx("div", { className: "text-primary", children: "Loading..." }),
73628
- error && /* @__PURE__ */ jsxs("div", { className: "px-4 py-2 text-red", children: [
73629
- /* @__PURE__ */ jsxs("div", { className: "font-bold", children: [
73630
- "Error: ",
73631
- error.message
73632
- ] }),
73633
- "details" in error && /* @__PURE__ */ jsx("pre", { className: "bg-card text-card-foreground", children: error.details })
73634
- ] }),
73635
- selectedSchema !== void 0 && selectedSource !== void 0 && /* @__PURE__ */ jsx(
73636
- ValFormField,
73637
- {
73638
- path: windowTarget.path,
73639
- disabled: loading,
73640
- source: selectedSource,
73641
- schema: selectedSchema,
73642
- registerPatchCallback: initPatchCallback(windowTarget.path)
73643
- }
73644
- ),
73645
- /* @__PURE__ */ jsx("div", { className: "flex items-end justify-end py-2", children: /* @__PURE__ */ jsx(
73646
- Button,
73647
- {
73648
- className: "px-4 py-2 border border-highlight disabled:border-border",
73649
- disabled: patchProgress !== "ready",
73650
- onClick: onSubmitPatch,
73651
- children: patchProgress === "patching" ? "Finalizing..." : patchProgress === "create_patch" ? "Patching..." : patchProgress === "on_submit" ? "Completing..." : patchProgress === "update_store" ? "Refreshing..." : "Submit"
73652
- }
73653
- ) })
73654
- ]
73617
+ children: /* @__PURE__ */ jsx(
73618
+ "div",
73619
+ {
73620
+ className: "p-4",
73621
+ style: {
73622
+ maxHeight: windowSize == null ? void 0 : windowSize.innerHeight
73623
+ },
73624
+ children: Object.entries(formData).map(([path, data]) => {
73625
+ if (data.status !== "success") {
73626
+ return /* @__PURE__ */ jsxs("div", { children: [
73627
+ path,
73628
+ ": ",
73629
+ data.status
73630
+ ] }, path);
73631
+ }
73632
+ const { source, schema } = data.data;
73633
+ if (!source || !schema) {
73634
+ return /* @__PURE__ */ jsxs("div", { children: [
73635
+ "Module: ",
73636
+ path,
73637
+ " is missing source or schema"
73638
+ ] });
73639
+ }
73640
+ return /* @__PURE__ */ jsx(
73641
+ AnyVal,
73642
+ {
73643
+ initOnSubmit,
73644
+ path,
73645
+ schema,
73646
+ source,
73647
+ setSelectedPath: () => {
73648
+ },
73649
+ field: path,
73650
+ top: true
73651
+ },
73652
+ path
73653
+ );
73654
+ })
73655
+ }
73656
+ )
73655
73657
  }
73656
73658
  )
73657
73659
  ] })
73658
73660
  }
73659
73661
  );
73660
73662
  }
73661
- function useValModules(api, path) {
73662
- const [modules, setModules] = useState();
73663
- const moduleId = path && Internal.splitModuleIdAndModulePath(path)[0];
73664
- useEffect(() => {
73665
- if (path) {
73666
- setModules({ status: "loading" });
73667
- api.getTree({
73668
- patch: true,
73669
- includeSchema: true,
73670
- includeSource: true,
73671
- treePath: moduleId
73672
- }).then((res) => {
73673
- if (result.isOk(res)) {
73674
- setModules({ status: "success", data: res.value.modules });
73675
- } else {
73676
- console.error({ status: "error", error: res.error });
73677
- setModules({ status: "error", error: res.error.message });
73663
+ function updateFormData(api, path, setData) {
73664
+ const [moduleId, modulePath] = Internal.splitModuleIdAndModulePath(
73665
+ path
73666
+ );
73667
+ api.getTree({
73668
+ patch: true,
73669
+ includeSchema: true,
73670
+ includeSource: true,
73671
+ treePath: moduleId
73672
+ }).then((res) => {
73673
+ if (result.isOk(res)) {
73674
+ const { schema, source } = res.value.modules[moduleId];
73675
+ if (!schema || !source) {
73676
+ return setData((prev) => ({
73677
+ ...prev,
73678
+ [path]: {
73679
+ status: "success",
73680
+ data: {
73681
+ source: res.value.modules[moduleId].source,
73682
+ schema: res.value.modules[moduleId].schema
73683
+ }
73684
+ }
73685
+ }));
73686
+ }
73687
+ const resolvedModulePath = Internal.resolvePath(
73688
+ modulePath,
73689
+ source,
73690
+ schema
73691
+ );
73692
+ setData((prev) => ({
73693
+ ...prev,
73694
+ [path]: {
73695
+ status: "success",
73696
+ data: {
73697
+ source: resolvedModulePath.source,
73698
+ schema: resolvedModulePath.schema
73699
+ }
73678
73700
  }
73679
- });
73701
+ }));
73702
+ } else {
73703
+ console.error({ status: "error", error: res.error });
73704
+ setData((prev) => ({
73705
+ ...prev,
73706
+ [path]: {
73707
+ status: "error",
73708
+ error: res.error.message
73709
+ }
73710
+ }));
73680
73711
  }
73681
- }, [path]);
73682
- if (!path || (modules == null ? void 0 : modules.status) === "not-asked") {
73683
- return {
73684
- moduleId,
73685
- error: null,
73686
- selectedSource: void 0,
73687
- selectedSchema: void 0,
73688
- loading: false
73689
- };
73690
- }
73691
- if ((modules == null ? void 0 : modules.status) === "loading") {
73692
- return {
73693
- moduleId,
73694
- error: null,
73695
- selectedSource: void 0,
73696
- selectedSchema: void 0,
73697
- loading: true
73698
- };
73699
- }
73700
- if ((modules == null ? void 0 : modules.status) === "error") {
73701
- return {
73702
- moduleId,
73703
- error: { message: modules.error },
73704
- selectedSource: void 0,
73705
- selectedSchema: void 0,
73706
- loading: false
73707
- };
73708
- }
73709
- if (!(modules == null ? void 0 : modules.data)) {
73710
- return {
73711
- error: {
73712
- message: "Val could not fetch data for this element.",
73713
- details: "Module data not found for: " + moduleId
73714
- },
73715
- selectedSource: void 0,
73716
- selectedSchema: void 0,
73717
- loading: false
73718
- };
73719
- }
73720
- const resolvedModulePath = resolvePath$1(path, modules.data);
73721
- const {
73722
- error,
73723
- source: selectedSource,
73724
- schema: selectedSchema
73725
- } = resolvedModulePath && result.isOk(resolvedModulePath) ? {
73726
- ...resolvedModulePath.value,
73727
- error: null
73728
- } : {
73729
- error: resolvedModulePath && result.isErr(resolvedModulePath) ? resolvedModulePath.error : null,
73730
- source: void 0,
73731
- schema: void 0
73732
- };
73733
- return {
73734
- moduleId,
73735
- error,
73736
- selectedSource,
73737
- selectedSchema,
73738
- loading: false
73739
- };
73712
+ });
73740
73713
  }
73741
73714
  function ValHover({
73742
73715
  hoverTarget,
@@ -73903,40 +73876,7 @@ function useSession(api) {
73903
73876
  }, [sessionResetId]);
73904
73877
  return session;
73905
73878
  }
73906
- function WindowHeader({
73907
- path,
73908
- type
73909
- }) {
73910
- const segments = path.split("/").slice(1);
73911
- return /* @__PURE__ */ jsxs("span", { className: "h-[20px] flex items-center justify-between", children: [
73912
- /* @__PURE__ */ jsx(ScrollArea, { className: "whitespace-nowrap", dir: "rtl", children: segments.map((segment, i) => {
73913
- if (i === segments.length - 1) {
73914
- return /* @__PURE__ */ jsx("span", { className: "text-primary", children: segment.split(".").map((s, i2) => {
73915
- let name = s;
73916
- if (i2 === 0) {
73917
- return /* @__PURE__ */ jsx("span", { children: /* @__PURE__ */ jsx("span", { children: name }) }, i2 + ".");
73918
- } else {
73919
- name = JSON.parse(s);
73920
- }
73921
- return /* @__PURE__ */ jsxs("span", { children: [
73922
- /* @__PURE__ */ jsx("span", { className: "px-1 text-xs text-highlight", children: "/" }),
73923
- /* @__PURE__ */ jsx("span", { children: name })
73924
- ] }, i2 + ".");
73925
- }) }, i);
73926
- }
73927
- return /* @__PURE__ */ jsxs("span", { children: [
73928
- /* @__PURE__ */ jsx("span", { children: segment }),
73929
- /* @__PURE__ */ jsx("span", { className: "px-1 text-xs opacity-50", children: "/" })
73930
- ] }, i);
73931
- }) }),
73932
- type && /* @__PURE__ */ jsxs("span", { className: "ml-4", children: [
73933
- "(",
73934
- type,
73935
- ")"
73936
- ] })
73937
- ] });
73938
- }
73939
- const styleCss = "/*\n Need to explicitly set config path, otherwise it may fail to resolve when\n built from outside packages/ui.\n*/\n\n/*\n ! tailwindcss v3.3.5 | MIT License | https://tailwindcss.com\n*/\n\n/*\n1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4)\n2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116)\n*/\n\n*,\n::before,\n::after {\n box-sizing: border-box; /* 1 */\n border-width: 0; /* 2 */\n border-style: solid; /* 2 */\n border-color: #e5e7eb; /* 2 */\n}\n\n::before,\n::after {\n --tw-content: '';\n}\n\n/*\n1. Use a consistent sensible line-height in all browsers.\n2. Prevent adjustments of font size after orientation changes in iOS.\n3. Use a more readable tab size.\n4. Use the user's configured `sans` font-family by default.\n5. Use the user's configured `sans` font-feature-settings by default.\n6. Use the user's configured `sans` font-variation-settings by default.\n*/\n\nhtml {\n line-height: 1.5; /* 1 */\n -webkit-text-size-adjust: 100%; /* 2 */\n -moz-tab-size: 4; /* 3 */\n -o-tab-size: 4;\n tab-size: 4; /* 3 */\n font-family: 'Roboto', sans-serif; /* 4 */\n font-feature-settings: normal; /* 5 */\n font-variation-settings: normal; /* 6 */\n}\n\n/*\n1. Remove the margin in all browsers.\n2. Inherit line-height from `html` so users can set them as a class directly on the `html` element.\n*/\n\nbody {\n margin: 0; /* 1 */\n line-height: inherit; /* 2 */\n}\n\n/*\n1. Add the correct height in Firefox.\n2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655)\n3. Ensure horizontal rules are visible by default.\n*/\n\nhr {\n height: 0; /* 1 */\n color: inherit; /* 2 */\n border-top-width: 1px; /* 3 */\n}\n\n/*\nAdd the correct text decoration in Chrome, Edge, and Safari.\n*/\n\nabbr:where([title]) {\n -webkit-text-decoration: underline dotted;\n text-decoration: underline dotted;\n}\n\n/*\nRemove the default font size and weight for headings.\n*/\n\nh1,\nh2,\nh3,\nh4,\nh5,\nh6 {\n font-size: inherit;\n font-weight: inherit;\n}\n\n/*\nReset links to optimize for opt-in styling instead of opt-out.\n*/\n\na {\n color: inherit;\n text-decoration: inherit;\n}\n\n/*\nAdd the correct font weight in Edge and Safari.\n*/\n\nb,\nstrong {\n font-weight: bolder;\n}\n\n/*\n1. Use the user's configured `mono` font family by default.\n2. Correct the odd `em` font sizing in all browsers.\n*/\n\ncode,\nkbd,\nsamp,\npre {\n font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace; /* 1 */\n font-size: 1em; /* 2 */\n}\n\n/*\nAdd the correct font size in all browsers.\n*/\n\nsmall {\n font-size: 80%;\n}\n\n/*\nPrevent `sub` and `sup` elements from affecting the line height in all browsers.\n*/\n\nsub,\nsup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n}\n\nsub {\n bottom: -0.25em;\n}\n\nsup {\n top: -0.5em;\n}\n\n/*\n1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297)\n2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016)\n3. Remove gaps between table borders by default.\n*/\n\ntable {\n text-indent: 0; /* 1 */\n border-color: inherit; /* 2 */\n border-collapse: collapse; /* 3 */\n}\n\n/*\n1. Change the font styles in all browsers.\n2. Remove the margin in Firefox and Safari.\n3. Remove default padding in all browsers.\n*/\n\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n font-family: inherit; /* 1 */\n font-feature-settings: inherit; /* 1 */\n font-variation-settings: inherit; /* 1 */\n font-size: 100%; /* 1 */\n font-weight: inherit; /* 1 */\n line-height: inherit; /* 1 */\n color: inherit; /* 1 */\n margin: 0; /* 2 */\n padding: 0; /* 3 */\n}\n\n/*\nRemove the inheritance of text transform in Edge and Firefox.\n*/\n\nbutton,\nselect {\n text-transform: none;\n}\n\n/*\n1. Correct the inability to style clickable types in iOS and Safari.\n2. Remove default button styles.\n*/\n\nbutton,\n[type='button'],\n[type='reset'],\n[type='submit'] {\n -webkit-appearance: button; /* 1 */\n background-color: transparent; /* 2 */\n background-image: none; /* 2 */\n}\n\n/*\nUse the modern Firefox focus style for all focusable elements.\n*/\n\n:-moz-focusring {\n outline: auto;\n}\n\n/*\nRemove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737)\n*/\n\n:-moz-ui-invalid {\n box-shadow: none;\n}\n\n/*\nAdd the correct vertical alignment in Chrome and Firefox.\n*/\n\nprogress {\n vertical-align: baseline;\n}\n\n/*\nCorrect the cursor style of increment and decrement buttons in Safari.\n*/\n\n::-webkit-inner-spin-button,\n::-webkit-outer-spin-button {\n height: auto;\n}\n\n/*\n1. Correct the odd appearance in Chrome and Safari.\n2. Correct the outline style in Safari.\n*/\n\n[type='search'] {\n -webkit-appearance: textfield; /* 1 */\n outline-offset: -2px; /* 2 */\n}\n\n/*\nRemove the inner padding in Chrome and Safari on macOS.\n*/\n\n::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n/*\n1. Correct the inability to style clickable types in iOS and Safari.\n2. Change font properties to `inherit` in Safari.\n*/\n\n::-webkit-file-upload-button {\n -webkit-appearance: button; /* 1 */\n font: inherit; /* 2 */\n}\n\n/*\nAdd the correct display in Chrome and Safari.\n*/\n\nsummary {\n display: list-item;\n}\n\n/*\nRemoves the default spacing and border for appropriate elements.\n*/\n\nblockquote,\ndl,\ndd,\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\nhr,\nfigure,\np,\npre {\n margin: 0;\n}\n\nfieldset {\n margin: 0;\n padding: 0;\n}\n\nlegend {\n padding: 0;\n}\n\nol,\nul,\nmenu {\n list-style: none;\n margin: 0;\n padding: 0;\n}\n\n/*\nReset default styling for dialogs.\n*/\n\ndialog {\n padding: 0;\n}\n\n/*\nPrevent resizing textareas horizontally by default.\n*/\n\ntextarea {\n resize: vertical;\n}\n\n/*\n1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300)\n2. Set the default placeholder color to the user's configured gray 400 color.\n*/\n\ninput::-moz-placeholder, textarea::-moz-placeholder {\n opacity: 1; /* 1 */\n color: #9ca3af; /* 2 */\n}\n\ninput::placeholder,\ntextarea::placeholder {\n opacity: 1; /* 1 */\n color: #9ca3af; /* 2 */\n}\n\n/*\nSet the default cursor for buttons.\n*/\n\nbutton,\n[role=\"button\"] {\n cursor: pointer;\n}\n\n/*\nMake sure disabled buttons don't get the pointer cursor.\n*/\n\n:disabled {\n cursor: default;\n}\n\n/*\n1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14)\n2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210)\n This can trigger a poorly considered lint error in some tools but is included by design.\n*/\n\nimg,\nsvg,\nvideo,\ncanvas,\naudio,\niframe,\nembed,\nobject {\n display: block; /* 1 */\n vertical-align: middle; /* 2 */\n}\n\n/*\nConstrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14)\n*/\n\nimg,\nvideo {\n max-width: 100%;\n height: auto;\n}\n\n/* Make elements with the HTML hidden attribute stay hidden by default */\n\n[hidden] {\n display: none;\n}\n\n/* :host for use with Shadow DOM, copied from the TailwindCSS prelude */\n\n:host {\n --background: 0 0% 100%;\n --foreground: 222.2 84% 4.9%;\n\n --card: 0 0% 100%;\n --card-foreground: 222.2 84% 4.9%;\n\n --popover: 0 0% 100%;\n --popover-foreground: 222.2 84% 4.9%;\n\n --primary: 222.2 47.4% 11.2%;\n --primary-foreground: 210 40% 98%;\n\n --secondary: 210 40% 96.1%;\n --secondary-foreground: 222.2 47.4% 11.2%;\n\n --muted: 0 0% 57.3%;\n --muted-foreground: 215.4 16.3% 46.9%;\n\n --accent: 159, 60%, 51%, 1;\n --accent-foreground: 222.2 47.4% 11.2%;\n\n --destructive: 0 84.2% 60.2%;\n --destructive-foreground: 210 40% 98%;\n\n --border: 214.3 31.8% 91.4%;\n --input: 214.3 31.8% 91.4%;\n --ring: 222.2 84% 4.9%;\n\n --radius: 0.5rem;\n }\n\n:root {\n --background: 0 0% 100%;\n --foreground: 222.2 84% 4.9%;\n\n --card: 0 0% 100%;\n --card-foreground: 222.2 84% 4.9%;\n\n --popover: 0 0% 100%;\n --popover-foreground: 222.2 84% 4.9%;\n\n --primary: 222.2 47.4% 11.2%;\n --primary-foreground: 210 40% 98%;\n\n --secondary: 210 40% 96.1%;\n --secondary-foreground: 222.2 47.4% 11.2%;\n\n --muted: 0 0% 57.3%;\n --muted-foreground: 215.4 16.3% 46.9%;\n\n --accent: 159, 60%, 51%, 1;\n --accent-foreground: 222.2 47.4% 11.2%;\n\n --destructive: 0 84.2% 60.2%;\n --destructive-foreground: 210 40% 98%;\n\n --border: 214.3 31.8% 91.4%;\n --input: 214.3 31.8% 91.4%;\n --ring: 222.2 84% 4.9%;\n\n --radius: 0.5rem;\n }\n\n/* dark theme */\n\n*[data-mode=\"dark\"] {\n --background: 0 0% 4%;\n --foreground: 210 40% 98%;\n\n --card: 222.2 84% 4.9%;\n --card-foreground: 210 40% 98%;\n\n --popover: 222.2 84% 4.9%;\n --popover-foreground: 210 40% 98%;\n\n --primary: 210 40% 98%;\n --primary-foreground: 222.2 47.4% 11.2%;\n\n --secondary: 217.2 32.6% 17.5%;\n --secondary-foreground: 210 40% 98%;\n\n --muted: 178, 23%, 76%, 1;\n --muted-foreground: 215 20.2% 65.1%;\n\n --accent: 159, 60%, 51%, 1;\n --accent-foreground: 210 40% 98%;\n\n --destructive: 0 62.8% 30.6%;\n --destructive-foreground: 210 40% 98%;\n\n --border: 217.2 32.6% 17.5%;\n --input: 217.2 32.6% 17.5%;\n --ring: 212.7 26.8% 83.9%;\n }\n\n* {\n border-color: hsl(var(--border));\n}\n\nbody {\n background-color: hsl(var(--background));\n color: hsl(var(--foreground));\n}\n\n*, ::before, ::after {\n --tw-border-spacing-x: 0;\n --tw-border-spacing-y: 0;\n --tw-translate-x: 0;\n --tw-translate-y: 0;\n --tw-rotate: 0;\n --tw-skew-x: 0;\n --tw-skew-y: 0;\n --tw-scale-x: 1;\n --tw-scale-y: 1;\n --tw-pan-x: ;\n --tw-pan-y: ;\n --tw-pinch-zoom: ;\n --tw-scroll-snap-strictness: proximity;\n --tw-gradient-from-position: ;\n --tw-gradient-via-position: ;\n --tw-gradient-to-position: ;\n --tw-ordinal: ;\n --tw-slashed-zero: ;\n --tw-numeric-figure: ;\n --tw-numeric-spacing: ;\n --tw-numeric-fraction: ;\n --tw-ring-inset: ;\n --tw-ring-offset-width: 0px;\n --tw-ring-offset-color: #fff;\n --tw-ring-color: rgb(59 130 246 / 0.5);\n --tw-ring-offset-shadow: 0 0 #0000;\n --tw-ring-shadow: 0 0 #0000;\n --tw-shadow: 0 0 #0000;\n --tw-shadow-colored: 0 0 #0000;\n --tw-blur: ;\n --tw-brightness: ;\n --tw-contrast: ;\n --tw-grayscale: ;\n --tw-hue-rotate: ;\n --tw-invert: ;\n --tw-saturate: ;\n --tw-sepia: ;\n --tw-drop-shadow: ;\n --tw-backdrop-blur: ;\n --tw-backdrop-brightness: ;\n --tw-backdrop-contrast: ;\n --tw-backdrop-grayscale: ;\n --tw-backdrop-hue-rotate: ;\n --tw-backdrop-invert: ;\n --tw-backdrop-opacity: ;\n --tw-backdrop-saturate: ;\n --tw-backdrop-sepia: ;\n}\n\n::backdrop {\n --tw-border-spacing-x: 0;\n --tw-border-spacing-y: 0;\n --tw-translate-x: 0;\n --tw-translate-y: 0;\n --tw-rotate: 0;\n --tw-skew-x: 0;\n --tw-skew-y: 0;\n --tw-scale-x: 1;\n --tw-scale-y: 1;\n --tw-pan-x: ;\n --tw-pan-y: ;\n --tw-pinch-zoom: ;\n --tw-scroll-snap-strictness: proximity;\n --tw-gradient-from-position: ;\n --tw-gradient-via-position: ;\n --tw-gradient-to-position: ;\n --tw-ordinal: ;\n --tw-slashed-zero: ;\n --tw-numeric-figure: ;\n --tw-numeric-spacing: ;\n --tw-numeric-fraction: ;\n --tw-ring-inset: ;\n --tw-ring-offset-width: 0px;\n --tw-ring-offset-color: #fff;\n --tw-ring-color: rgb(59 130 246 / 0.5);\n --tw-ring-offset-shadow: 0 0 #0000;\n --tw-ring-shadow: 0 0 #0000;\n --tw-shadow: 0 0 #0000;\n --tw-shadow-colored: 0 0 #0000;\n --tw-blur: ;\n --tw-brightness: ;\n --tw-contrast: ;\n --tw-grayscale: ;\n --tw-hue-rotate: ;\n --tw-invert: ;\n --tw-saturate: ;\n --tw-sepia: ;\n --tw-drop-shadow: ;\n --tw-backdrop-blur: ;\n --tw-backdrop-brightness: ;\n --tw-backdrop-contrast: ;\n --tw-backdrop-grayscale: ;\n --tw-backdrop-hue-rotate: ;\n --tw-backdrop-invert: ;\n --tw-backdrop-opacity: ;\n --tw-backdrop-saturate: ;\n --tw-backdrop-sepia: ;\n}\n.sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border-width: 0;\n}\n.pointer-events-none {\n pointer-events: none;\n}\n.invisible {\n visibility: hidden;\n}\n.static {\n position: static;\n}\n.fixed {\n position: fixed;\n}\n.absolute {\n position: absolute;\n}\n.relative {\n position: relative;\n}\n.sticky {\n position: sticky;\n}\n.inset-0 {\n inset: 0px;\n}\n.inset-y-0 {\n top: 0px;\n bottom: 0px;\n}\n.-left-2 {\n left: -0.5rem;\n}\n.-right-\\[10px\\] {\n right: -10px;\n}\n.-top-\\[10px\\] {\n top: -10px;\n}\n.-top-\\[4px\\] {\n top: -4px;\n}\n.bottom-0 {\n bottom: 0px;\n}\n.bottom-4 {\n bottom: 1rem;\n}\n.left-0 {\n left: 0px;\n}\n.left-1 {\n left: 0.25rem;\n}\n.left-1\\/2 {\n left: 50%;\n}\n.left-2 {\n left: 0.5rem;\n}\n.left-\\[50\\%\\] {\n left: 50%;\n}\n.right-0 {\n right: 0px;\n}\n.right-1 {\n right: 0.25rem;\n}\n.right-4 {\n right: 1rem;\n}\n.right-\\[16px\\] {\n right: 16px;\n}\n.top-0 {\n top: 0px;\n}\n.top-4 {\n top: 1rem;\n}\n.top-\\[50\\%\\] {\n top: 50%;\n}\n.z-50 {\n z-index: 50;\n}\n.z-\\[5\\] {\n z-index: 5;\n}\n.z-overlay {\n z-index: 4;\n}\n.-mx-1 {\n margin-left: -0.25rem;\n margin-right: -0.25rem;\n}\n.-my-2 {\n margin-top: -0.5rem;\n margin-bottom: -0.5rem;\n}\n.-my-\\[100px\\] {\n margin-top: -100px;\n margin-bottom: -100px;\n}\n.mx-2 {\n margin-left: 0.5rem;\n margin-right: 0.5rem;\n}\n.my-1 {\n margin-top: 0.25rem;\n margin-bottom: 0.25rem;\n}\n.mb-4 {\n margin-bottom: 1rem;\n}\n.ml-2 {\n margin-left: 0.5rem;\n}\n.ml-4 {\n margin-left: 1rem;\n}\n.ml-\\[20px\\] {\n margin-left: 20px;\n}\n.ml-auto {\n margin-left: auto;\n}\n.mr-2 {\n margin-right: 0.5rem;\n}\n.mt-2 {\n margin-top: 0.5rem;\n}\n.block {\n display: block;\n}\n.inline {\n display: inline;\n}\n.flex {\n display: flex;\n}\n.inline-flex {\n display: inline-flex;\n}\n.table {\n display: table;\n}\n.grid {\n display: grid;\n}\n.hidden {\n display: none;\n}\n.aspect-square {\n aspect-ratio: 1 / 1;\n}\n.h-10 {\n height: 2.5rem;\n}\n.h-11 {\n height: 2.75rem;\n}\n.h-2 {\n height: 0.5rem;\n}\n.h-2\\.5 {\n height: 0.625rem;\n}\n.h-3 {\n height: 0.75rem;\n}\n.h-3\\.5 {\n height: 0.875rem;\n}\n.h-4 {\n height: 1rem;\n}\n.h-7 {\n height: 1.75rem;\n}\n.h-9 {\n height: 2.25rem;\n}\n.h-\\[14px\\] {\n height: 14px;\n}\n.h-\\[18px\\] {\n height: 18px;\n}\n.h-\\[1px\\] {\n height: 1px;\n}\n.h-\\[20px\\] {\n height: 20px;\n}\n.h-\\[22px\\] {\n height: 22px;\n}\n.h-\\[24px\\] {\n height: 24px;\n}\n.h-\\[32px\\] {\n height: 32px;\n}\n.h-\\[50px\\] {\n height: 50px;\n}\n.h-\\[75px\\] {\n height: 75px;\n}\n.h-\\[9px\\] {\n height: 9px;\n}\n.h-\\[var\\(--radix-select-trigger-height\\)\\] {\n height: var(--radix-select-trigger-height);\n}\n.h-full {\n height: 100%;\n}\n.h-px {\n height: 1px;\n}\n.h-screen {\n height: 100vh;\n}\n.max-h-\\[300px\\] {\n max-height: 300px;\n}\n.min-h-\\[200px\\] {\n min-height: 200px;\n}\n.min-h-\\[300px\\] {\n min-height: 300px;\n}\n.min-h-screen {\n min-height: 100vh;\n}\n.w-1\\/3 {\n width: 33.333333%;\n}\n.w-10 {\n width: 2.5rem;\n}\n.w-2 {\n width: 0.5rem;\n}\n.w-2\\.5 {\n width: 0.625rem;\n}\n.w-3 {\n width: 0.75rem;\n}\n.w-3\\.5 {\n width: 0.875rem;\n}\n.w-4 {\n width: 1rem;\n}\n.w-5 {\n width: 1.25rem;\n}\n.w-7 {\n width: 1.75rem;\n}\n.w-72 {\n width: 18rem;\n}\n.w-9 {\n width: 2.25rem;\n}\n.w-\\[14px\\] {\n width: 14px;\n}\n.w-\\[1px\\] {\n width: 1px;\n}\n.w-\\[20px\\] {\n width: 20px;\n}\n.w-\\[24px\\] {\n width: 24px;\n}\n.w-\\[32px\\] {\n width: 32px;\n}\n.w-\\[44px\\] {\n width: 44px;\n}\n.w-\\[9px\\] {\n width: 9px;\n}\n.w-fit {\n width: -moz-fit-content;\n width: fit-content;\n}\n.w-full {\n width: 100%;\n}\n.w-screen {\n width: 100vw;\n}\n.min-w-0 {\n min-width: 0px;\n}\n.min-w-\\[320px\\] {\n min-width: 320px;\n}\n.min-w-\\[500px\\] {\n min-width: 500px;\n}\n.min-w-\\[8rem\\] {\n min-width: 8rem;\n}\n.min-w-\\[var\\(--radix-select-trigger-width\\)\\] {\n min-width: var(--radix-select-trigger-width);\n}\n.max-w-4xl {\n max-width: 56rem;\n}\n.max-w-\\[1000px\\] {\n max-width: 1000px;\n}\n.max-w-\\[10vw\\] {\n max-width: 10vw;\n}\n.max-w-\\[300px\\] {\n max-width: 300px;\n}\n.max-w-\\[90vw\\] {\n max-width: 90vw;\n}\n.max-w-full {\n max-width: 100%;\n}\n.max-w-lg {\n max-width: 32rem;\n}\n.flex-1 {\n flex: 1 1 0%;\n}\n.flex-auto {\n flex: 1 1 auto;\n}\n.flex-shrink-0 {\n flex-shrink: 0;\n}\n.shrink-0 {\n flex-shrink: 0;\n}\n.flex-grow {\n flex-grow: 1;\n}\n.border-collapse {\n border-collapse: collapse;\n}\n.-translate-x-1\\/2 {\n --tw-translate-x: -50%;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.translate-x-\\[-50\\%\\] {\n --tw-translate-x: -50%;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.translate-y-\\[-50\\%\\] {\n --tw-translate-y: -50%;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.-rotate-90 {\n --tw-rotate: -90deg;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.rotate-90 {\n --tw-rotate: 90deg;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.rotate-\\[-90deg\\] {\n --tw-rotate: -90deg;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.rotate-\\[90deg\\] {\n --tw-rotate: 90deg;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.transform {\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.cursor-col-resize {\n cursor: col-resize;\n}\n.cursor-default {\n cursor: default;\n}\n.cursor-grab {\n cursor: grab;\n}\n.cursor-pointer {\n cursor: pointer;\n}\n.cursor-se-resize {\n cursor: se-resize;\n}\n.touch-none {\n touch-action: none;\n}\n.select-none {\n -webkit-user-select: none;\n -moz-user-select: none;\n user-select: none;\n}\n.resize-none {\n resize: none;\n}\n.resize {\n resize: both;\n}\n.list-decimal {\n list-style-type: decimal;\n}\n.list-disc {\n list-style-type: disc;\n}\n.grid-cols-\\[min-content_1fr\\] {\n grid-template-columns: min-content 1fr;\n}\n.grid-rows-\\[1fr\\2c _min-content\\] {\n grid-template-rows: 1fr min-content;\n}\n.flex-row {\n flex-direction: row;\n}\n.flex-col {\n flex-direction: column;\n}\n.flex-col-reverse {\n flex-direction: column-reverse;\n}\n.items-start {\n align-items: flex-start;\n}\n.items-end {\n align-items: flex-end;\n}\n.items-center {\n align-items: center;\n}\n.justify-start {\n justify-content: flex-start;\n}\n.justify-end {\n justify-content: flex-end;\n}\n.justify-center {\n justify-content: center;\n}\n.justify-between {\n justify-content: space-between;\n}\n.gap-1 {\n gap: 0.25rem;\n}\n.gap-2 {\n gap: 0.5rem;\n}\n.gap-3 {\n gap: 0.75rem;\n}\n.gap-4 {\n gap: 1rem;\n}\n.gap-5 {\n gap: 1.25rem;\n}\n.gap-\\[0\\.5em\\] {\n gap: 0.5em;\n}\n.gap-\\[36px\\] {\n gap: 36px;\n}\n.gap-x-2 {\n -moz-column-gap: 0.5rem;\n column-gap: 0.5rem;\n}\n.gap-x-3 {\n -moz-column-gap: 0.75rem;\n column-gap: 0.75rem;\n}\n.gap-x-4 {\n -moz-column-gap: 1rem;\n column-gap: 1rem;\n}\n.gap-y-2 {\n row-gap: 0.5rem;\n}\n.gap-y-4 {\n row-gap: 1rem;\n}\n.gap-y-6 {\n row-gap: 1.5rem;\n}\n.gap-y-8 {\n row-gap: 2rem;\n}\n.space-x-1 > :not([hidden]) ~ :not([hidden]) {\n --tw-space-x-reverse: 0;\n margin-right: calc(0.25rem * var(--tw-space-x-reverse));\n margin-left: calc(0.25rem * calc(1 - var(--tw-space-x-reverse)));\n}\n.space-y-1 > :not([hidden]) ~ :not([hidden]) {\n --tw-space-y-reverse: 0;\n margin-top: calc(0.25rem * calc(1 - var(--tw-space-y-reverse)));\n margin-bottom: calc(0.25rem * var(--tw-space-y-reverse));\n}\n.space-y-1\\.5 > :not([hidden]) ~ :not([hidden]) {\n --tw-space-y-reverse: 0;\n margin-top: calc(0.375rem * calc(1 - var(--tw-space-y-reverse)));\n margin-bottom: calc(0.375rem * var(--tw-space-y-reverse));\n}\n.space-y-2 > :not([hidden]) ~ :not([hidden]) {\n --tw-space-y-reverse: 0;\n margin-top: calc(0.5rem * calc(1 - var(--tw-space-y-reverse)));\n margin-bottom: calc(0.5rem * var(--tw-space-y-reverse));\n}\n.space-y-4 > :not([hidden]) ~ :not([hidden]) {\n --tw-space-y-reverse: 0;\n margin-top: calc(1rem * calc(1 - var(--tw-space-y-reverse)));\n margin-bottom: calc(1rem * var(--tw-space-y-reverse));\n}\n.overflow-auto {\n overflow: auto;\n}\n.overflow-hidden {\n overflow: hidden;\n}\n.overflow-clip {\n overflow: clip;\n}\n.overflow-scroll {\n overflow: scroll;\n}\n.overflow-y-auto {\n overflow-y: auto;\n}\n.overflow-x-hidden {\n overflow-x: hidden;\n}\n.overflow-y-scroll {\n overflow-y: scroll;\n}\n.truncate {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.whitespace-nowrap {\n white-space: nowrap;\n}\n.rounded {\n border-radius: 0.25rem;\n}\n.rounded-\\[inherit\\] {\n border-radius: inherit;\n}\n.rounded-full {\n border-radius: 9999px;\n}\n.rounded-lg {\n border-radius: var(--radius);\n}\n.rounded-md {\n border-radius: calc(var(--radius) - 2px);\n}\n.rounded-sm {\n border-radius: calc(var(--radius) - 4px);\n}\n.border {\n border-width: 1px;\n}\n.border-2 {\n border-width: 2px;\n}\n.border-\\[2px\\] {\n border-width: 2px;\n}\n.border-y {\n border-top-width: 1px;\n border-bottom-width: 1px;\n}\n.border-b {\n border-bottom-width: 1px;\n}\n.border-l {\n border-left-width: 1px;\n}\n.border-l-2 {\n border-left-width: 2px;\n}\n.border-r {\n border-right-width: 1px;\n}\n.border-t {\n border-top-width: 1px;\n}\n.border-accent {\n border-color: hsl(var(--accent));\n}\n.border-border {\n border-color: hsl(var(--border));\n}\n.border-card {\n border-color: hsl(var(--card));\n}\n.border-gray-400 {\n --tw-border-opacity: 1;\n border-color: rgb(156 163 175 / var(--tw-border-opacity));\n}\n.border-input {\n border-color: hsl(var(--input));\n}\n.border-primary {\n border-color: hsl(var(--primary));\n}\n.border-transparent {\n border-color: transparent;\n}\n.border-l-transparent {\n border-left-color: transparent;\n}\n.border-t-transparent {\n border-top-color: transparent;\n}\n.bg-accent {\n background-color: hsl(var(--accent));\n}\n.bg-background {\n background-color: hsl(var(--background));\n}\n.bg-background\\/80 {\n background-color: hsl(var(--background) / 0.8);\n}\n.bg-border {\n background-color: hsl(var(--border));\n}\n.bg-card {\n background-color: hsl(var(--card));\n}\n.bg-card-foreground {\n background-color: hsl(var(--card-foreground));\n}\n.bg-destructive {\n background-color: hsl(var(--destructive));\n}\n.bg-gray-300 {\n --tw-bg-opacity: 1;\n background-color: rgb(209 213 219 / var(--tw-bg-opacity));\n}\n.bg-gray-500 {\n --tw-bg-opacity: 1;\n background-color: rgb(107 114 128 / var(--tw-bg-opacity));\n}\n.bg-muted {\n background-color: hsl(var(--muted));\n}\n.bg-popover {\n background-color: hsl(var(--popover));\n}\n.bg-primary {\n background-color: hsl(var(--primary));\n}\n.bg-red-500 {\n --tw-bg-opacity: 1;\n background-color: rgb(239 68 68 / var(--tw-bg-opacity));\n}\n.bg-secondary {\n background-color: hsl(var(--secondary));\n}\n.bg-transparent {\n background-color: transparent;\n}\n.bg-white {\n --tw-bg-opacity: 1;\n background-color: rgb(255 255 255 / var(--tw-bg-opacity));\n}\n.bg-gradient-to-b {\n background-image: linear-gradient(to bottom, var(--tw-gradient-stops));\n}\n.from-transparent {\n --tw-gradient-from: transparent var(--tw-gradient-from-position);\n --tw-gradient-to: rgb(0 0 0 / 0) var(--tw-gradient-to-position);\n --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);\n}\n.to-background {\n --tw-gradient-to: hsl(var(--background)) var(--tw-gradient-to-position);\n}\n.fill-current {\n fill: currentColor;\n}\n.fill-white {\n fill: #fff;\n}\n.stroke-\\[2px\\] {\n stroke-width: 2px;\n}\n.stroke-\\[3px\\] {\n stroke-width: 3px;\n}\n.object-contain {\n -o-object-fit: contain;\n object-fit: contain;\n}\n.p-0 {\n padding: 0px;\n}\n.p-1 {\n padding: 0.25rem;\n}\n.p-10 {\n padding: 2.5rem;\n}\n.p-2 {\n padding: 0.5rem;\n}\n.p-3 {\n padding: 0.75rem;\n}\n.p-4 {\n padding: 1rem;\n}\n.p-6 {\n padding: 1.5rem;\n}\n.p-\\[1px\\] {\n padding: 1px;\n}\n.px-1 {\n padding-left: 0.25rem;\n padding-right: 0.25rem;\n}\n.px-2 {\n padding-left: 0.5rem;\n padding-right: 0.5rem;\n}\n.px-2\\.5 {\n padding-left: 0.625rem;\n padding-right: 0.625rem;\n}\n.px-3 {\n padding-left: 0.75rem;\n padding-right: 0.75rem;\n}\n.px-4 {\n padding-left: 1rem;\n padding-right: 1rem;\n}\n.px-5 {\n padding-left: 1.25rem;\n padding-right: 1.25rem;\n}\n.px-8 {\n padding-left: 2rem;\n padding-right: 2rem;\n}\n.px-\\[24px\\] {\n padding-left: 24px;\n padding-right: 24px;\n}\n.py-1 {\n padding-top: 0.25rem;\n padding-bottom: 0.25rem;\n}\n.py-1\\.5 {\n padding-top: 0.375rem;\n padding-bottom: 0.375rem;\n}\n.py-2 {\n padding-top: 0.5rem;\n padding-bottom: 0.5rem;\n}\n.py-3 {\n padding-top: 0.75rem;\n padding-bottom: 0.75rem;\n}\n.py-4 {\n padding-top: 1rem;\n padding-bottom: 1rem;\n}\n.py-6 {\n padding-top: 1.5rem;\n padding-bottom: 1.5rem;\n}\n.py-7 {\n padding-top: 1.75rem;\n padding-bottom: 1.75rem;\n}\n.py-\\[2px\\] {\n padding-top: 2px;\n padding-bottom: 2px;\n}\n.pb-0 {\n padding-bottom: 0px;\n}\n.pb-20 {\n padding-bottom: 5rem;\n}\n.pb-4 {\n padding-bottom: 1rem;\n}\n.pl-6 {\n padding-left: 1.5rem;\n}\n.pl-8 {\n padding-left: 2rem;\n}\n.pr-2 {\n padding-right: 0.5rem;\n}\n.pt-0 {\n padding-top: 0px;\n}\n.pt-1 {\n padding-top: 0.25rem;\n}\n.pt-2 {\n padding-top: 0.5rem;\n}\n.pt-4 {\n padding-top: 1rem;\n}\n.text-left {\n text-align: left;\n}\n.text-center {\n text-align: center;\n}\n.text-start {\n text-align: start;\n}\n.font-sans {\n font-family: 'Roboto', sans-serif;\n}\n.font-serif {\n font-family: 'Space Mono', monospace;\n}\n.text-2xl {\n font-size: 1.5rem;\n line-height: 2rem;\n}\n.text-3xl {\n font-size: 1.875rem;\n line-height: 2.25rem;\n}\n.text-4xl {\n font-size: 2.25rem;\n line-height: 2.5rem;\n}\n.text-\\[0\\.8rem\\] {\n font-size: 0.8rem;\n}\n.text-\\[12px\\] {\n font-size: 12px;\n}\n.text-lg {\n font-size: 1.125rem;\n line-height: 1.75rem;\n}\n.text-sm {\n font-size: 0.875rem;\n line-height: 1.25rem;\n}\n.text-xl {\n font-size: 1.25rem;\n line-height: 1.75rem;\n}\n.text-xs {\n font-size: 0.75rem;\n line-height: 1rem;\n}\n.font-\\[12px\\] {\n font-weight: 12px;\n}\n.font-\\[400\\] {\n font-weight: 400;\n}\n.font-\\[500\\] {\n font-weight: 500;\n}\n.font-\\[550\\] {\n font-weight: 550;\n}\n.font-bold {\n font-weight: 700;\n}\n.font-extrabold {\n font-weight: 800;\n}\n.font-medium {\n font-weight: 500;\n}\n.font-normal {\n font-weight: 400;\n}\n.font-semibold {\n font-weight: 600;\n}\n.uppercase {\n text-transform: uppercase;\n}\n.italic {\n font-style: italic;\n}\n.leading-4 {\n line-height: 1rem;\n}\n.leading-none {\n line-height: 1;\n}\n.tracking-\\[0\\.04em\\] {\n letter-spacing: 0.04em;\n}\n.tracking-tight {\n letter-spacing: -0.025em;\n}\n.tracking-wider {\n letter-spacing: 0.05em;\n}\n.tracking-widest {\n letter-spacing: 0.1em;\n}\n.text-accent {\n color: hsl(var(--accent));\n}\n.text-accent-foreground {\n color: hsl(var(--accent-foreground));\n}\n.text-background {\n color: hsl(var(--background));\n}\n.text-card-foreground {\n color: hsl(var(--card-foreground));\n}\n.text-current {\n color: currentColor;\n}\n.text-destructive {\n color: hsl(var(--destructive));\n}\n.text-destructive-foreground {\n color: hsl(var(--destructive-foreground));\n}\n.text-foreground {\n color: hsl(var(--foreground));\n}\n.text-muted {\n color: hsl(var(--muted));\n}\n.text-muted-foreground {\n color: hsl(var(--muted-foreground));\n}\n.text-popover-foreground {\n color: hsl(var(--popover-foreground));\n}\n.text-primary {\n color: hsl(var(--primary));\n}\n.text-primary-foreground {\n color: hsl(var(--primary-foreground));\n}\n.text-secondary-foreground {\n color: hsl(var(--secondary-foreground));\n}\n.text-white {\n --tw-text-opacity: 1;\n color: rgb(255 255 255 / var(--tw-text-opacity));\n}\n.underline {\n text-decoration-line: underline;\n}\n.line-through {\n text-decoration-line: line-through;\n}\n.underline-offset-4 {\n text-underline-offset: 4px;\n}\n.antialiased {\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n.opacity-0 {\n opacity: 0;\n}\n.opacity-100 {\n opacity: 1;\n}\n.opacity-50 {\n opacity: 0.5;\n}\n.opacity-60 {\n opacity: 0.6;\n}\n.opacity-70 {\n opacity: 0.7;\n}\n.opacity-75 {\n opacity: 0.75;\n}\n.shadow {\n --tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);\n --tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);\n box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);\n}\n.shadow-lg {\n --tw-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);\n --tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);\n box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);\n}\n.shadow-md {\n --tw-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);\n --tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);\n box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);\n}\n.shadow-sm {\n --tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);\n --tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);\n box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);\n}\n.outline-none {\n outline: 2px solid transparent;\n outline-offset: 2px;\n}\n.outline {\n outline-style: solid;\n}\n.ring-0 {\n --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);\n --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color);\n box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);\n}\n.ring-offset-background {\n --tw-ring-offset-color: hsl(var(--background));\n}\n.drop-shadow-2xl {\n --tw-drop-shadow: drop-shadow(0 25px 25px rgb(0 0 0 / 0.15));\n filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);\n}\n.drop-shadow-\\[0px_0px_12px_rgba\\(56\\2c 205\\2c 152\\2c 0\\.60\\)\\] {\n --tw-drop-shadow: drop-shadow(0px 0px 12px rgba(56,205,152,0.60));\n filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);\n}\n.filter {\n filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);\n}\n.backdrop-blur-sm {\n --tw-backdrop-blur: blur(4px);\n -webkit-backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);\n backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);\n}\n.transition-all {\n transition-property: all;\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n transition-duration: 150ms;\n}\n.transition-colors {\n transition-property: color, background-color, border-color, text-decoration-color, fill, stroke;\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n transition-duration: 150ms;\n}\n.transition-opacity {\n transition-property: opacity;\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n transition-duration: 150ms;\n}\n.transition-transform {\n transition-property: transform;\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n transition-duration: 150ms;\n}\n.duration-150 {\n transition-duration: 150ms;\n}\n.duration-200 {\n transition-duration: 200ms;\n}\n.ease-in-out {\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n}\n@keyframes enter {\n\n from {\n opacity: var(--tw-enter-opacity, 1);\n transform: translate3d(var(--tw-enter-translate-x, 0), var(--tw-enter-translate-y, 0), 0) scale3d(var(--tw-enter-scale, 1), var(--tw-enter-scale, 1), var(--tw-enter-scale, 1)) rotate(var(--tw-enter-rotate, 0));\n }\n}\n@keyframes exit {\n\n to {\n opacity: var(--tw-exit-opacity, 1);\n transform: translate3d(var(--tw-exit-translate-x, 0), var(--tw-exit-translate-y, 0), 0) scale3d(var(--tw-exit-scale, 1), var(--tw-exit-scale, 1), var(--tw-exit-scale, 1)) rotate(var(--tw-exit-rotate, 0));\n }\n}\n.animate-in {\n animation-name: enter;\n animation-duration: 150ms;\n --tw-enter-opacity: initial;\n --tw-enter-scale: initial;\n --tw-enter-rotate: initial;\n --tw-enter-translate-x: initial;\n --tw-enter-translate-y: initial;\n}\n.fade-in-0 {\n --tw-enter-opacity: 0;\n}\n.zoom-in-95 {\n --tw-enter-scale: .95;\n}\n.duration-150 {\n animation-duration: 150ms;\n}\n.duration-200 {\n animation-duration: 200ms;\n}\n.ease-in-out {\n animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n}\n.file\\:border-0::file-selector-button {\n border-width: 0px;\n}\n.file\\:bg-transparent::file-selector-button {\n background-color: transparent;\n}\n.file\\:text-sm::file-selector-button {\n font-size: 0.875rem;\n line-height: 1.25rem;\n}\n.file\\:font-medium::file-selector-button {\n font-weight: 500;\n}\n.placeholder\\:text-muted-foreground::-moz-placeholder {\n color: hsl(var(--muted-foreground));\n}\n.placeholder\\:text-muted-foreground::placeholder {\n color: hsl(var(--muted-foreground));\n}\n.focus-within\\:relative:focus-within {\n position: relative;\n}\n.hover\\:w-\\[2px\\]:hover {\n width: 2px;\n}\n.hover\\:w-\\[3px\\]:hover {\n width: 3px;\n}\n.hover\\:cursor-pointer:hover {\n cursor: pointer;\n}\n.hover\\:rounded-lg:hover {\n border-radius: var(--radius);\n}\n.hover\\:bg-accent:hover {\n background-color: hsl(var(--accent));\n}\n.hover\\:bg-background:hover {\n background-color: hsl(var(--background));\n}\n.hover\\:bg-border:hover {\n background-color: hsl(var(--border));\n}\n.hover\\:bg-destructive\\/90:hover {\n background-color: hsl(var(--destructive) / 0.9);\n}\n.hover\\:bg-muted:hover {\n background-color: hsl(var(--muted));\n}\n.hover\\:bg-primary:hover {\n background-color: hsl(var(--primary));\n}\n.hover\\:bg-primary\\/90:hover {\n background-color: hsl(var(--primary) / 0.9);\n}\n.hover\\:bg-red-700:hover {\n --tw-bg-opacity: 1;\n background-color: rgb(185 28 28 / var(--tw-bg-opacity));\n}\n.hover\\:bg-secondary\\/80:hover {\n background-color: hsl(var(--secondary) / 0.8);\n}\n.hover\\:text-accent-foreground:hover {\n color: hsl(var(--accent-foreground));\n}\n.hover\\:text-muted-foreground:hover {\n color: hsl(var(--muted-foreground));\n}\n.hover\\:text-primary-foreground:hover {\n color: hsl(var(--primary-foreground));\n}\n.hover\\:text-white:hover {\n --tw-text-opacity: 1;\n color: rgb(255 255 255 / var(--tw-text-opacity));\n}\n.hover\\:underline:hover {\n text-decoration-line: underline;\n}\n.hover\\:opacity-100:hover {\n opacity: 1;\n}\n.focus\\:bg-accent:focus {\n background-color: hsl(var(--accent));\n}\n.focus\\:bg-primary:focus {\n background-color: hsl(var(--primary));\n}\n.focus\\:text-accent-foreground:focus {\n color: hsl(var(--accent-foreground));\n}\n.focus\\:text-primary-foreground:focus {\n color: hsl(var(--primary-foreground));\n}\n.focus\\:outline-none:focus {\n outline: 2px solid transparent;\n outline-offset: 2px;\n}\n.focus\\:ring-2:focus {\n --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);\n --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);\n box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);\n}\n.focus\\:ring-ring:focus {\n --tw-ring-color: hsl(var(--ring));\n}\n.focus\\:ring-offset-2:focus {\n --tw-ring-offset-width: 2px;\n}\n.focus-visible\\:outline-none:focus-visible {\n outline: 2px solid transparent;\n outline-offset: 2px;\n}\n.focus-visible\\:outline-accent:focus-visible {\n outline-color: hsl(var(--accent));\n}\n.focus-visible\\:ring-2:focus-visible {\n --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);\n --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);\n box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);\n}\n.focus-visible\\:ring-ring:focus-visible {\n --tw-ring-color: hsl(var(--ring));\n}\n.focus-visible\\:ring-offset-2:focus-visible {\n --tw-ring-offset-width: 2px;\n}\n.focus-visible\\:ring-offset-background:focus-visible {\n --tw-ring-offset-color: hsl(var(--background));\n}\n.disabled\\:pointer-events-none:disabled {\n pointer-events: none;\n}\n.disabled\\:cursor-not-allowed:disabled {\n cursor: not-allowed;\n}\n.disabled\\:border-border:disabled {\n border-color: hsl(var(--border));\n}\n.disabled\\:text-background:disabled {\n color: hsl(var(--background));\n}\n.disabled\\:opacity-50:disabled {\n opacity: 0.5;\n}\n.peer:disabled ~ .peer-disabled\\:cursor-not-allowed {\n cursor: not-allowed;\n}\n.peer:disabled ~ .peer-disabled\\:opacity-70 {\n opacity: 0.7;\n}\n.aria-selected\\:bg-accent[aria-selected=\"true\"] {\n background-color: hsl(var(--accent));\n}\n.aria-selected\\:text-accent-foreground[aria-selected=\"true\"] {\n color: hsl(var(--accent-foreground));\n}\n.aria-selected\\:opacity-100[aria-selected=\"true\"] {\n opacity: 1;\n}\n.data-\\[disabled\\]\\:pointer-events-none[data-disabled] {\n pointer-events: none;\n}\n.data-\\[side\\=bottom\\]\\:translate-y-1[data-side=bottom] {\n --tw-translate-y: 0.25rem;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.data-\\[side\\=left\\]\\:-translate-x-1[data-side=left] {\n --tw-translate-x: -0.25rem;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.data-\\[side\\=right\\]\\:translate-x-1[data-side=right] {\n --tw-translate-x: 0.25rem;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.data-\\[side\\=top\\]\\:-translate-y-1[data-side=top] {\n --tw-translate-y: -0.25rem;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.data-\\[state\\=checked\\]\\:translate-x-5[data-state=checked] {\n --tw-translate-x: 1.25rem;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.data-\\[state\\=unchecked\\]\\:translate-x-0[data-state=unchecked] {\n --tw-translate-x: 0px;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n@keyframes accordion-up {\n\n from {\n height: var(--radix-accordion-content-height);\n }\n\n to {\n height: 0;\n }\n}\n.data-\\[state\\=closed\\]\\:animate-accordion-up[data-state=closed] {\n animation: accordion-up 0.2s ease-out;\n}\n@keyframes accordion-down {\n\n from {\n height: 0;\n }\n\n to {\n height: var(--radix-accordion-content-height);\n }\n}\n.data-\\[state\\=open\\]\\:animate-accordion-down[data-state=open] {\n animation: accordion-down 0.2s ease-out;\n}\n.data-\\[state\\=active\\]\\:bg-background[data-state=active] {\n background-color: hsl(var(--background));\n}\n.data-\\[state\\=checked\\]\\:bg-accent[data-state=checked] {\n background-color: hsl(var(--accent));\n}\n.data-\\[state\\=checked\\]\\:bg-primary[data-state=checked] {\n background-color: hsl(var(--primary));\n}\n.data-\\[state\\=on\\]\\:bg-accent[data-state=on] {\n background-color: hsl(var(--accent));\n}\n.data-\\[state\\=open\\]\\:bg-accent[data-state=open] {\n background-color: hsl(var(--accent));\n}\n.data-\\[state\\=unchecked\\]\\:bg-primary[data-state=unchecked] {\n background-color: hsl(var(--primary));\n}\n.data-\\[state\\=active\\]\\:text-foreground[data-state=active] {\n color: hsl(var(--foreground));\n}\n.data-\\[state\\=checked\\]\\:text-primary-foreground[data-state=checked] {\n color: hsl(var(--primary-foreground));\n}\n.data-\\[state\\=on\\]\\:text-accent-foreground[data-state=on] {\n color: hsl(var(--accent-foreground));\n}\n.data-\\[state\\=open\\]\\:text-muted-foreground[data-state=open] {\n color: hsl(var(--muted-foreground));\n}\n.data-\\[disabled\\]\\:opacity-50[data-disabled] {\n opacity: 0.5;\n}\n.data-\\[state\\=active\\]\\:shadow-sm[data-state=active] {\n --tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);\n --tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);\n box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);\n}\n.data-\\[state\\=open\\]\\:animate-in[data-state=open] {\n animation-name: enter;\n animation-duration: 150ms;\n --tw-enter-opacity: initial;\n --tw-enter-scale: initial;\n --tw-enter-rotate: initial;\n --tw-enter-translate-x: initial;\n --tw-enter-translate-y: initial;\n}\n.data-\\[state\\=closed\\]\\:animate-out[data-state=closed] {\n animation-name: exit;\n animation-duration: 150ms;\n --tw-exit-opacity: initial;\n --tw-exit-scale: initial;\n --tw-exit-rotate: initial;\n --tw-exit-translate-x: initial;\n --tw-exit-translate-y: initial;\n}\n.data-\\[state\\=closed\\]\\:fade-out-0[data-state=closed] {\n --tw-exit-opacity: 0;\n}\n.data-\\[state\\=open\\]\\:fade-in-0[data-state=open] {\n --tw-enter-opacity: 0;\n}\n.data-\\[state\\=closed\\]\\:zoom-out-95[data-state=closed] {\n --tw-exit-scale: .95;\n}\n.data-\\[state\\=open\\]\\:zoom-in-95[data-state=open] {\n --tw-enter-scale: .95;\n}\n.data-\\[side\\=bottom\\]\\:slide-in-from-top-2[data-side=bottom] {\n --tw-enter-translate-y: -0.5rem;\n}\n.data-\\[side\\=left\\]\\:slide-in-from-right-2[data-side=left] {\n --tw-enter-translate-x: 0.5rem;\n}\n.data-\\[side\\=right\\]\\:slide-in-from-left-2[data-side=right] {\n --tw-enter-translate-x: -0.5rem;\n}\n.data-\\[side\\=top\\]\\:slide-in-from-bottom-2[data-side=top] {\n --tw-enter-translate-y: 0.5rem;\n}\n.data-\\[state\\=closed\\]\\:slide-out-to-left-1\\/2[data-state=closed] {\n --tw-exit-translate-x: -50%;\n}\n.data-\\[state\\=closed\\]\\:slide-out-to-top-\\[48\\%\\][data-state=closed] {\n --tw-exit-translate-y: -48%;\n}\n.data-\\[state\\=open\\]\\:slide-in-from-left-1\\/2[data-state=open] {\n --tw-enter-translate-x: -50%;\n}\n.data-\\[state\\=open\\]\\:slide-in-from-top-\\[48\\%\\][data-state=open] {\n --tw-enter-translate-y: -48%;\n}\n:is([data-mode=\"dark\"] .dark\\:border-white) {\n --tw-border-opacity: 1;\n border-color: rgb(255 255 255 / var(--tw-border-opacity));\n}\n@media (min-width: 640px) {\n\n .sm\\:mt-0 {\n margin-top: 0px;\n }\n\n .sm\\:block {\n display: block;\n }\n\n .sm\\:flex-row {\n flex-direction: row;\n }\n\n .sm\\:justify-end {\n justify-content: flex-end;\n }\n\n .sm\\:space-x-2 > :not([hidden]) ~ :not([hidden]) {\n --tw-space-x-reverse: 0;\n margin-right: calc(0.5rem * var(--tw-space-x-reverse));\n margin-left: calc(0.5rem * calc(1 - var(--tw-space-x-reverse)));\n }\n\n .sm\\:space-x-4 > :not([hidden]) ~ :not([hidden]) {\n --tw-space-x-reverse: 0;\n margin-right: calc(1rem * var(--tw-space-x-reverse));\n margin-left: calc(1rem * calc(1 - var(--tw-space-x-reverse)));\n }\n\n .sm\\:space-y-0 > :not([hidden]) ~ :not([hidden]) {\n --tw-space-y-reverse: 0;\n margin-top: calc(0px * calc(1 - var(--tw-space-y-reverse)));\n margin-bottom: calc(0px * var(--tw-space-y-reverse));\n }\n\n .sm\\:rounded-lg {\n border-radius: var(--radius);\n }\n\n .sm\\:p-0 {\n padding: 0px;\n }\n\n .sm\\:text-left {\n text-align: left;\n }\n}\n@media (min-width: 768px) {\n\n .md\\:w-full {\n width: 100%;\n }\n}\n.\\[\\&\\:has\\(\\[aria-selected\\]\\)\\]\\:bg-accent:has([aria-selected]) {\n background-color: hsl(var(--accent));\n}\n.first\\:\\[\\&\\:has\\(\\[aria-selected\\]\\)\\]\\:rounded-l-md:has([aria-selected]):first-child {\n border-top-left-radius: calc(var(--radius) - 2px);\n border-bottom-left-radius: calc(var(--radius) - 2px);\n}\n.last\\:\\[\\&\\:has\\(\\[aria-selected\\]\\)\\]\\:rounded-r-md:has([aria-selected]):last-child {\n border-top-right-radius: calc(var(--radius) - 2px);\n border-bottom-right-radius: calc(var(--radius) - 2px);\n}\n.\\[\\&\\[data-state\\=open\\]\\>svg\\]\\:rotate-180[data-state=open]>svg {\n --tw-rotate: 180deg;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.\\[\\&_\\[cmdk-group-heading\\]\\]\\:px-2 [cmdk-group-heading] {\n padding-left: 0.5rem;\n padding-right: 0.5rem;\n}\n.\\[\\&_\\[cmdk-group-heading\\]\\]\\:py-1\\.5 [cmdk-group-heading] {\n padding-top: 0.375rem;\n padding-bottom: 0.375rem;\n}\n.\\[\\&_\\[cmdk-group-heading\\]\\]\\:text-xs [cmdk-group-heading] {\n font-size: 0.75rem;\n line-height: 1rem;\n}\n.\\[\\&_\\[cmdk-group-heading\\]\\]\\:font-medium [cmdk-group-heading] {\n font-weight: 500;\n}\n.\\[\\&_\\[cmdk-group-heading\\]\\]\\:text-muted-foreground [cmdk-group-heading] {\n color: hsl(var(--muted-foreground));\n}\n.\\[\\&_\\[cmdk-group\\]\\:not\\(\\[hidden\\]\\)_\\~\\[cmdk-group\\]\\]\\:pt-0 [cmdk-group]:not([hidden]) ~[cmdk-group] {\n padding-top: 0px;\n}\n.\\[\\&_\\[cmdk-group\\]\\]\\:px-2 [cmdk-group] {\n padding-left: 0.5rem;\n padding-right: 0.5rem;\n}\n.\\[\\&_\\[cmdk-input-wrapper\\]_svg\\]\\:h-5 [cmdk-input-wrapper] svg {\n height: 1.25rem;\n}\n.\\[\\&_\\[cmdk-input-wrapper\\]_svg\\]\\:w-5 [cmdk-input-wrapper] svg {\n width: 1.25rem;\n}\n.\\[\\&_\\[cmdk-input\\]\\]\\:h-12 [cmdk-input] {\n height: 3rem;\n}\n.\\[\\&_\\[cmdk-item\\]\\]\\:px-2 [cmdk-item] {\n padding-left: 0.5rem;\n padding-right: 0.5rem;\n}\n.\\[\\&_\\[cmdk-item\\]\\]\\:py-3 [cmdk-item] {\n padding-top: 0.75rem;\n padding-bottom: 0.75rem;\n}\n.\\[\\&_\\[cmdk-item\\]_svg\\]\\:h-5 [cmdk-item] svg {\n height: 1.25rem;\n}\n.\\[\\&_\\[cmdk-item\\]_svg\\]\\:w-5 [cmdk-item] svg {\n width: 1.25rem;\n}\n";
73879
+ const styleCss = "/*\n Need to explicitly set config path, otherwise it may fail to resolve when\n built from outside packages/ui.\n*/\n\n/*\n ! tailwindcss v3.3.5 | MIT License | https://tailwindcss.com\n*/\n\n/*\n1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4)\n2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116)\n*/\n\n*,\n::before,\n::after {\n box-sizing: border-box; /* 1 */\n border-width: 0; /* 2 */\n border-style: solid; /* 2 */\n border-color: #e5e7eb; /* 2 */\n}\n\n::before,\n::after {\n --tw-content: '';\n}\n\n/*\n1. Use a consistent sensible line-height in all browsers.\n2. Prevent adjustments of font size after orientation changes in iOS.\n3. Use a more readable tab size.\n4. Use the user's configured `sans` font-family by default.\n5. Use the user's configured `sans` font-feature-settings by default.\n6. Use the user's configured `sans` font-variation-settings by default.\n*/\n\nhtml {\n line-height: 1.5; /* 1 */\n -webkit-text-size-adjust: 100%; /* 2 */\n -moz-tab-size: 4; /* 3 */\n -o-tab-size: 4;\n tab-size: 4; /* 3 */\n font-family: 'Roboto', sans-serif; /* 4 */\n font-feature-settings: normal; /* 5 */\n font-variation-settings: normal; /* 6 */\n}\n\n/*\n1. Remove the margin in all browsers.\n2. Inherit line-height from `html` so users can set them as a class directly on the `html` element.\n*/\n\nbody {\n margin: 0; /* 1 */\n line-height: inherit; /* 2 */\n}\n\n/*\n1. Add the correct height in Firefox.\n2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655)\n3. Ensure horizontal rules are visible by default.\n*/\n\nhr {\n height: 0; /* 1 */\n color: inherit; /* 2 */\n border-top-width: 1px; /* 3 */\n}\n\n/*\nAdd the correct text decoration in Chrome, Edge, and Safari.\n*/\n\nabbr:where([title]) {\n -webkit-text-decoration: underline dotted;\n text-decoration: underline dotted;\n}\n\n/*\nRemove the default font size and weight for headings.\n*/\n\nh1,\nh2,\nh3,\nh4,\nh5,\nh6 {\n font-size: inherit;\n font-weight: inherit;\n}\n\n/*\nReset links to optimize for opt-in styling instead of opt-out.\n*/\n\na {\n color: inherit;\n text-decoration: inherit;\n}\n\n/*\nAdd the correct font weight in Edge and Safari.\n*/\n\nb,\nstrong {\n font-weight: bolder;\n}\n\n/*\n1. Use the user's configured `mono` font family by default.\n2. Correct the odd `em` font sizing in all browsers.\n*/\n\ncode,\nkbd,\nsamp,\npre {\n font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace; /* 1 */\n font-size: 1em; /* 2 */\n}\n\n/*\nAdd the correct font size in all browsers.\n*/\n\nsmall {\n font-size: 80%;\n}\n\n/*\nPrevent `sub` and `sup` elements from affecting the line height in all browsers.\n*/\n\nsub,\nsup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n}\n\nsub {\n bottom: -0.25em;\n}\n\nsup {\n top: -0.5em;\n}\n\n/*\n1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297)\n2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016)\n3. Remove gaps between table borders by default.\n*/\n\ntable {\n text-indent: 0; /* 1 */\n border-color: inherit; /* 2 */\n border-collapse: collapse; /* 3 */\n}\n\n/*\n1. Change the font styles in all browsers.\n2. Remove the margin in Firefox and Safari.\n3. Remove default padding in all browsers.\n*/\n\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n font-family: inherit; /* 1 */\n font-feature-settings: inherit; /* 1 */\n font-variation-settings: inherit; /* 1 */\n font-size: 100%; /* 1 */\n font-weight: inherit; /* 1 */\n line-height: inherit; /* 1 */\n color: inherit; /* 1 */\n margin: 0; /* 2 */\n padding: 0; /* 3 */\n}\n\n/*\nRemove the inheritance of text transform in Edge and Firefox.\n*/\n\nbutton,\nselect {\n text-transform: none;\n}\n\n/*\n1. Correct the inability to style clickable types in iOS and Safari.\n2. Remove default button styles.\n*/\n\nbutton,\n[type='button'],\n[type='reset'],\n[type='submit'] {\n -webkit-appearance: button; /* 1 */\n background-color: transparent; /* 2 */\n background-image: none; /* 2 */\n}\n\n/*\nUse the modern Firefox focus style for all focusable elements.\n*/\n\n:-moz-focusring {\n outline: auto;\n}\n\n/*\nRemove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737)\n*/\n\n:-moz-ui-invalid {\n box-shadow: none;\n}\n\n/*\nAdd the correct vertical alignment in Chrome and Firefox.\n*/\n\nprogress {\n vertical-align: baseline;\n}\n\n/*\nCorrect the cursor style of increment and decrement buttons in Safari.\n*/\n\n::-webkit-inner-spin-button,\n::-webkit-outer-spin-button {\n height: auto;\n}\n\n/*\n1. Correct the odd appearance in Chrome and Safari.\n2. Correct the outline style in Safari.\n*/\n\n[type='search'] {\n -webkit-appearance: textfield; /* 1 */\n outline-offset: -2px; /* 2 */\n}\n\n/*\nRemove the inner padding in Chrome and Safari on macOS.\n*/\n\n::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n/*\n1. Correct the inability to style clickable types in iOS and Safari.\n2. Change font properties to `inherit` in Safari.\n*/\n\n::-webkit-file-upload-button {\n -webkit-appearance: button; /* 1 */\n font: inherit; /* 2 */\n}\n\n/*\nAdd the correct display in Chrome and Safari.\n*/\n\nsummary {\n display: list-item;\n}\n\n/*\nRemoves the default spacing and border for appropriate elements.\n*/\n\nblockquote,\ndl,\ndd,\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\nhr,\nfigure,\np,\npre {\n margin: 0;\n}\n\nfieldset {\n margin: 0;\n padding: 0;\n}\n\nlegend {\n padding: 0;\n}\n\nol,\nul,\nmenu {\n list-style: none;\n margin: 0;\n padding: 0;\n}\n\n/*\nReset default styling for dialogs.\n*/\n\ndialog {\n padding: 0;\n}\n\n/*\nPrevent resizing textareas horizontally by default.\n*/\n\ntextarea {\n resize: vertical;\n}\n\n/*\n1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300)\n2. Set the default placeholder color to the user's configured gray 400 color.\n*/\n\ninput::-moz-placeholder, textarea::-moz-placeholder {\n opacity: 1; /* 1 */\n color: #9ca3af; /* 2 */\n}\n\ninput::placeholder,\ntextarea::placeholder {\n opacity: 1; /* 1 */\n color: #9ca3af; /* 2 */\n}\n\n/*\nSet the default cursor for buttons.\n*/\n\nbutton,\n[role=\"button\"] {\n cursor: pointer;\n}\n\n/*\nMake sure disabled buttons don't get the pointer cursor.\n*/\n\n:disabled {\n cursor: default;\n}\n\n/*\n1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14)\n2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210)\n This can trigger a poorly considered lint error in some tools but is included by design.\n*/\n\nimg,\nsvg,\nvideo,\ncanvas,\naudio,\niframe,\nembed,\nobject {\n display: block; /* 1 */\n vertical-align: middle; /* 2 */\n}\n\n/*\nConstrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14)\n*/\n\nimg,\nvideo {\n max-width: 100%;\n height: auto;\n}\n\n/* Make elements with the HTML hidden attribute stay hidden by default */\n\n[hidden] {\n display: none;\n}\n\n/* :host for use with Shadow DOM, copied from the TailwindCSS prelude */\n\n:host {\n --background: 0 0% 100%;\n --foreground: 222.2 84% 4.9%;\n\n --card: 0 0% 100%;\n --card-foreground: 222.2 84% 4.9%;\n\n --popover: 0 0% 100%;\n --popover-foreground: 222.2 84% 4.9%;\n\n --primary: 222.2 47.4% 11.2%;\n --primary-foreground: 210 40% 98%;\n\n --secondary: 210 40% 96.1%;\n --secondary-foreground: 222.2 47.4% 11.2%;\n\n --muted: 0 0% 57.3%;\n --muted-foreground: 215.4 16.3% 46.9%;\n\n --accent: 159, 60%, 51%, 1;\n --accent-foreground: 222.2 47.4% 11.2%;\n\n --destructive: 0 84.2% 60.2%;\n --destructive-foreground: 210 40% 98%;\n\n --border: 214.3 31.8% 91.4%;\n --input: 214.3 31.8% 91.4%;\n --ring: 222.2 84% 4.9%;\n\n --radius: 0.5rem;\n }\n\n:root {\n --background: 0 0% 100%;\n --foreground: 222.2 84% 4.9%;\n\n --card: 0 0% 100%;\n --card-foreground: 222.2 84% 4.9%;\n\n --popover: 0 0% 100%;\n --popover-foreground: 222.2 84% 4.9%;\n\n --primary: 222.2 47.4% 11.2%;\n --primary-foreground: 210 40% 98%;\n\n --secondary: 210 40% 96.1%;\n --secondary-foreground: 222.2 47.4% 11.2%;\n\n --muted: 0 0% 57.3%;\n --muted-foreground: 215.4 16.3% 46.9%;\n\n --accent: 159, 60%, 51%, 1;\n --accent-foreground: 222.2 47.4% 11.2%;\n\n --destructive: 0 84.2% 60.2%;\n --destructive-foreground: 210 40% 98%;\n\n --border: 214.3 31.8% 91.4%;\n --input: 214.3 31.8% 91.4%;\n --ring: 222.2 84% 4.9%;\n\n --radius: 0.5rem;\n }\n\n/* dark theme */\n\n*[data-mode=\"dark\"] {\n --background: 0 0% 4%;\n --foreground: 210 40% 98%;\n\n --card: 222.2 84% 4.9%;\n --card-foreground: 210 40% 98%;\n\n --popover: 222.2 84% 4.9%;\n --popover-foreground: 210 40% 98%;\n\n --primary: 210 40% 98%;\n --primary-foreground: 222.2 47.4% 11.2%;\n\n --secondary: 217.2 32.6% 17.5%;\n --secondary-foreground: 210 40% 98%;\n\n --muted: 178, 23%, 76%, 1;\n --muted-foreground: 215 20.2% 65.1%;\n\n --accent: 159, 60%, 51%, 1;\n --accent-foreground: 210 40% 98%;\n\n --destructive: 0 62.8% 30.6%;\n --destructive-foreground: 210 40% 98%;\n\n --border: 217.2 32.6% 17.5%;\n --input: 217.2 32.6% 17.5%;\n --ring: 212.7 26.8% 83.9%;\n }\n\n* {\n border-color: hsl(var(--border));\n}\n\nbody {\n background-color: hsl(var(--background));\n color: hsl(var(--foreground));\n}\n\n*, ::before, ::after {\n --tw-border-spacing-x: 0;\n --tw-border-spacing-y: 0;\n --tw-translate-x: 0;\n --tw-translate-y: 0;\n --tw-rotate: 0;\n --tw-skew-x: 0;\n --tw-skew-y: 0;\n --tw-scale-x: 1;\n --tw-scale-y: 1;\n --tw-pan-x: ;\n --tw-pan-y: ;\n --tw-pinch-zoom: ;\n --tw-scroll-snap-strictness: proximity;\n --tw-gradient-from-position: ;\n --tw-gradient-via-position: ;\n --tw-gradient-to-position: ;\n --tw-ordinal: ;\n --tw-slashed-zero: ;\n --tw-numeric-figure: ;\n --tw-numeric-spacing: ;\n --tw-numeric-fraction: ;\n --tw-ring-inset: ;\n --tw-ring-offset-width: 0px;\n --tw-ring-offset-color: #fff;\n --tw-ring-color: rgb(59 130 246 / 0.5);\n --tw-ring-offset-shadow: 0 0 #0000;\n --tw-ring-shadow: 0 0 #0000;\n --tw-shadow: 0 0 #0000;\n --tw-shadow-colored: 0 0 #0000;\n --tw-blur: ;\n --tw-brightness: ;\n --tw-contrast: ;\n --tw-grayscale: ;\n --tw-hue-rotate: ;\n --tw-invert: ;\n --tw-saturate: ;\n --tw-sepia: ;\n --tw-drop-shadow: ;\n --tw-backdrop-blur: ;\n --tw-backdrop-brightness: ;\n --tw-backdrop-contrast: ;\n --tw-backdrop-grayscale: ;\n --tw-backdrop-hue-rotate: ;\n --tw-backdrop-invert: ;\n --tw-backdrop-opacity: ;\n --tw-backdrop-saturate: ;\n --tw-backdrop-sepia: ;\n}\n\n::backdrop {\n --tw-border-spacing-x: 0;\n --tw-border-spacing-y: 0;\n --tw-translate-x: 0;\n --tw-translate-y: 0;\n --tw-rotate: 0;\n --tw-skew-x: 0;\n --tw-skew-y: 0;\n --tw-scale-x: 1;\n --tw-scale-y: 1;\n --tw-pan-x: ;\n --tw-pan-y: ;\n --tw-pinch-zoom: ;\n --tw-scroll-snap-strictness: proximity;\n --tw-gradient-from-position: ;\n --tw-gradient-via-position: ;\n --tw-gradient-to-position: ;\n --tw-ordinal: ;\n --tw-slashed-zero: ;\n --tw-numeric-figure: ;\n --tw-numeric-spacing: ;\n --tw-numeric-fraction: ;\n --tw-ring-inset: ;\n --tw-ring-offset-width: 0px;\n --tw-ring-offset-color: #fff;\n --tw-ring-color: rgb(59 130 246 / 0.5);\n --tw-ring-offset-shadow: 0 0 #0000;\n --tw-ring-shadow: 0 0 #0000;\n --tw-shadow: 0 0 #0000;\n --tw-shadow-colored: 0 0 #0000;\n --tw-blur: ;\n --tw-brightness: ;\n --tw-contrast: ;\n --tw-grayscale: ;\n --tw-hue-rotate: ;\n --tw-invert: ;\n --tw-saturate: ;\n --tw-sepia: ;\n --tw-drop-shadow: ;\n --tw-backdrop-blur: ;\n --tw-backdrop-brightness: ;\n --tw-backdrop-contrast: ;\n --tw-backdrop-grayscale: ;\n --tw-backdrop-hue-rotate: ;\n --tw-backdrop-invert: ;\n --tw-backdrop-opacity: ;\n --tw-backdrop-saturate: ;\n --tw-backdrop-sepia: ;\n}\n.sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border-width: 0;\n}\n.pointer-events-none {\n pointer-events: none;\n}\n.invisible {\n visibility: hidden;\n}\n.static {\n position: static;\n}\n.fixed {\n position: fixed;\n}\n.absolute {\n position: absolute;\n}\n.relative {\n position: relative;\n}\n.sticky {\n position: sticky;\n}\n.inset-0 {\n inset: 0px;\n}\n.inset-y-0 {\n top: 0px;\n bottom: 0px;\n}\n.-left-2 {\n left: -0.5rem;\n}\n.-right-\\[10px\\] {\n right: -10px;\n}\n.-top-\\[10px\\] {\n top: -10px;\n}\n.-top-\\[4px\\] {\n top: -4px;\n}\n.bottom-0 {\n bottom: 0px;\n}\n.bottom-4 {\n bottom: 1rem;\n}\n.left-0 {\n left: 0px;\n}\n.left-1 {\n left: 0.25rem;\n}\n.left-1\\/2 {\n left: 50%;\n}\n.left-2 {\n left: 0.5rem;\n}\n.left-\\[50\\%\\] {\n left: 50%;\n}\n.right-0 {\n right: 0px;\n}\n.right-1 {\n right: 0.25rem;\n}\n.right-4 {\n right: 1rem;\n}\n.right-\\[16px\\] {\n right: 16px;\n}\n.top-0 {\n top: 0px;\n}\n.top-4 {\n top: 1rem;\n}\n.top-\\[50\\%\\] {\n top: 50%;\n}\n.z-50 {\n z-index: 50;\n}\n.z-\\[5\\] {\n z-index: 5;\n}\n.z-overlay {\n z-index: 4;\n}\n.-mx-1 {\n margin-left: -0.25rem;\n margin-right: -0.25rem;\n}\n.-my-2 {\n margin-top: -0.5rem;\n margin-bottom: -0.5rem;\n}\n.-my-\\[100px\\] {\n margin-top: -100px;\n margin-bottom: -100px;\n}\n.mx-2 {\n margin-left: 0.5rem;\n margin-right: 0.5rem;\n}\n.my-1 {\n margin-top: 0.25rem;\n margin-bottom: 0.25rem;\n}\n.mb-4 {\n margin-bottom: 1rem;\n}\n.ml-2 {\n margin-left: 0.5rem;\n}\n.ml-4 {\n margin-left: 1rem;\n}\n.ml-\\[20px\\] {\n margin-left: 20px;\n}\n.ml-auto {\n margin-left: auto;\n}\n.mr-2 {\n margin-right: 0.5rem;\n}\n.mt-2 {\n margin-top: 0.5rem;\n}\n.block {\n display: block;\n}\n.inline {\n display: inline;\n}\n.flex {\n display: flex;\n}\n.inline-flex {\n display: inline-flex;\n}\n.table {\n display: table;\n}\n.grid {\n display: grid;\n}\n.hidden {\n display: none;\n}\n.aspect-square {\n aspect-ratio: 1 / 1;\n}\n.h-10 {\n height: 2.5rem;\n}\n.h-11 {\n height: 2.75rem;\n}\n.h-2 {\n height: 0.5rem;\n}\n.h-2\\.5 {\n height: 0.625rem;\n}\n.h-3 {\n height: 0.75rem;\n}\n.h-3\\.5 {\n height: 0.875rem;\n}\n.h-4 {\n height: 1rem;\n}\n.h-7 {\n height: 1.75rem;\n}\n.h-9 {\n height: 2.25rem;\n}\n.h-\\[14px\\] {\n height: 14px;\n}\n.h-\\[18px\\] {\n height: 18px;\n}\n.h-\\[1px\\] {\n height: 1px;\n}\n.h-\\[20px\\] {\n height: 20px;\n}\n.h-\\[22px\\] {\n height: 22px;\n}\n.h-\\[24px\\] {\n height: 24px;\n}\n.h-\\[32px\\] {\n height: 32px;\n}\n.h-\\[50px\\] {\n height: 50px;\n}\n.h-\\[75px\\] {\n height: 75px;\n}\n.h-\\[9px\\] {\n height: 9px;\n}\n.h-\\[var\\(--radix-select-trigger-height\\)\\] {\n height: var(--radix-select-trigger-height);\n}\n.h-full {\n height: 100%;\n}\n.h-px {\n height: 1px;\n}\n.h-screen {\n height: 100vh;\n}\n.max-h-\\[300px\\] {\n max-height: 300px;\n}\n.min-h-\\[200px\\] {\n min-height: 200px;\n}\n.min-h-\\[300px\\] {\n min-height: 300px;\n}\n.min-h-screen {\n min-height: 100vh;\n}\n.w-1\\/3 {\n width: 33.333333%;\n}\n.w-10 {\n width: 2.5rem;\n}\n.w-2 {\n width: 0.5rem;\n}\n.w-2\\.5 {\n width: 0.625rem;\n}\n.w-3 {\n width: 0.75rem;\n}\n.w-3\\.5 {\n width: 0.875rem;\n}\n.w-4 {\n width: 1rem;\n}\n.w-5 {\n width: 1.25rem;\n}\n.w-7 {\n width: 1.75rem;\n}\n.w-72 {\n width: 18rem;\n}\n.w-9 {\n width: 2.25rem;\n}\n.w-\\[14px\\] {\n width: 14px;\n}\n.w-\\[1px\\] {\n width: 1px;\n}\n.w-\\[20px\\] {\n width: 20px;\n}\n.w-\\[24px\\] {\n width: 24px;\n}\n.w-\\[32px\\] {\n width: 32px;\n}\n.w-\\[44px\\] {\n width: 44px;\n}\n.w-\\[9px\\] {\n width: 9px;\n}\n.w-fit {\n width: -moz-fit-content;\n width: fit-content;\n}\n.w-full {\n width: 100%;\n}\n.w-screen {\n width: 100vw;\n}\n.min-w-0 {\n min-width: 0px;\n}\n.min-w-\\[320px\\] {\n min-width: 320px;\n}\n.min-w-\\[500px\\] {\n min-width: 500px;\n}\n.min-w-\\[8rem\\] {\n min-width: 8rem;\n}\n.min-w-\\[var\\(--radix-select-trigger-width\\)\\] {\n min-width: var(--radix-select-trigger-width);\n}\n.max-w-4xl {\n max-width: 56rem;\n}\n.max-w-\\[1000px\\] {\n max-width: 1000px;\n}\n.max-w-\\[10vw\\] {\n max-width: 10vw;\n}\n.max-w-\\[300px\\] {\n max-width: 300px;\n}\n.max-w-\\[90vw\\] {\n max-width: 90vw;\n}\n.max-w-lg {\n max-width: 32rem;\n}\n.flex-1 {\n flex: 1 1 0%;\n}\n.flex-auto {\n flex: 1 1 auto;\n}\n.flex-shrink-0 {\n flex-shrink: 0;\n}\n.shrink-0 {\n flex-shrink: 0;\n}\n.flex-grow {\n flex-grow: 1;\n}\n.border-collapse {\n border-collapse: collapse;\n}\n.-translate-x-1\\/2 {\n --tw-translate-x: -50%;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.translate-x-\\[-50\\%\\] {\n --tw-translate-x: -50%;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.translate-y-\\[-50\\%\\] {\n --tw-translate-y: -50%;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.-rotate-90 {\n --tw-rotate: -90deg;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.rotate-90 {\n --tw-rotate: 90deg;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.rotate-\\[-90deg\\] {\n --tw-rotate: -90deg;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.rotate-\\[90deg\\] {\n --tw-rotate: 90deg;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.transform {\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.cursor-col-resize {\n cursor: col-resize;\n}\n.cursor-default {\n cursor: default;\n}\n.cursor-grab {\n cursor: grab;\n}\n.cursor-pointer {\n cursor: pointer;\n}\n.cursor-se-resize {\n cursor: se-resize;\n}\n.touch-none {\n touch-action: none;\n}\n.select-none {\n -webkit-user-select: none;\n -moz-user-select: none;\n user-select: none;\n}\n.resize-none {\n resize: none;\n}\n.resize {\n resize: both;\n}\n.list-decimal {\n list-style-type: decimal;\n}\n.list-disc {\n list-style-type: disc;\n}\n.grid-cols-\\[min-content_1fr\\] {\n grid-template-columns: min-content 1fr;\n}\n.grid-rows-\\[1fr\\2c _min-content\\] {\n grid-template-rows: 1fr min-content;\n}\n.flex-row {\n flex-direction: row;\n}\n.flex-col {\n flex-direction: column;\n}\n.flex-col-reverse {\n flex-direction: column-reverse;\n}\n.items-start {\n align-items: flex-start;\n}\n.items-center {\n align-items: center;\n}\n.justify-start {\n justify-content: flex-start;\n}\n.justify-end {\n justify-content: flex-end;\n}\n.justify-center {\n justify-content: center;\n}\n.justify-between {\n justify-content: space-between;\n}\n.gap-1 {\n gap: 0.25rem;\n}\n.gap-2 {\n gap: 0.5rem;\n}\n.gap-3 {\n gap: 0.75rem;\n}\n.gap-4 {\n gap: 1rem;\n}\n.gap-5 {\n gap: 1.25rem;\n}\n.gap-\\[0\\.5em\\] {\n gap: 0.5em;\n}\n.gap-\\[36px\\] {\n gap: 36px;\n}\n.gap-x-2 {\n -moz-column-gap: 0.5rem;\n column-gap: 0.5rem;\n}\n.gap-x-3 {\n -moz-column-gap: 0.75rem;\n column-gap: 0.75rem;\n}\n.gap-x-4 {\n -moz-column-gap: 1rem;\n column-gap: 1rem;\n}\n.gap-y-2 {\n row-gap: 0.5rem;\n}\n.gap-y-4 {\n row-gap: 1rem;\n}\n.gap-y-6 {\n row-gap: 1.5rem;\n}\n.gap-y-8 {\n row-gap: 2rem;\n}\n.space-x-1 > :not([hidden]) ~ :not([hidden]) {\n --tw-space-x-reverse: 0;\n margin-right: calc(0.25rem * var(--tw-space-x-reverse));\n margin-left: calc(0.25rem * calc(1 - var(--tw-space-x-reverse)));\n}\n.space-y-1 > :not([hidden]) ~ :not([hidden]) {\n --tw-space-y-reverse: 0;\n margin-top: calc(0.25rem * calc(1 - var(--tw-space-y-reverse)));\n margin-bottom: calc(0.25rem * var(--tw-space-y-reverse));\n}\n.space-y-1\\.5 > :not([hidden]) ~ :not([hidden]) {\n --tw-space-y-reverse: 0;\n margin-top: calc(0.375rem * calc(1 - var(--tw-space-y-reverse)));\n margin-bottom: calc(0.375rem * var(--tw-space-y-reverse));\n}\n.space-y-2 > :not([hidden]) ~ :not([hidden]) {\n --tw-space-y-reverse: 0;\n margin-top: calc(0.5rem * calc(1 - var(--tw-space-y-reverse)));\n margin-bottom: calc(0.5rem * var(--tw-space-y-reverse));\n}\n.space-y-4 > :not([hidden]) ~ :not([hidden]) {\n --tw-space-y-reverse: 0;\n margin-top: calc(1rem * calc(1 - var(--tw-space-y-reverse)));\n margin-bottom: calc(1rem * var(--tw-space-y-reverse));\n}\n.overflow-auto {\n overflow: auto;\n}\n.overflow-hidden {\n overflow: hidden;\n}\n.overflow-clip {\n overflow: clip;\n}\n.overflow-scroll {\n overflow: scroll;\n}\n.overflow-y-auto {\n overflow-y: auto;\n}\n.overflow-x-hidden {\n overflow-x: hidden;\n}\n.overflow-y-scroll {\n overflow-y: scroll;\n}\n.truncate {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.whitespace-nowrap {\n white-space: nowrap;\n}\n.rounded {\n border-radius: 0.25rem;\n}\n.rounded-\\[inherit\\] {\n border-radius: inherit;\n}\n.rounded-full {\n border-radius: 9999px;\n}\n.rounded-lg {\n border-radius: var(--radius);\n}\n.rounded-md {\n border-radius: calc(var(--radius) - 2px);\n}\n.rounded-sm {\n border-radius: calc(var(--radius) - 4px);\n}\n.border {\n border-width: 1px;\n}\n.border-2 {\n border-width: 2px;\n}\n.border-\\[2px\\] {\n border-width: 2px;\n}\n.border-y {\n border-top-width: 1px;\n border-bottom-width: 1px;\n}\n.border-b {\n border-bottom-width: 1px;\n}\n.border-l {\n border-left-width: 1px;\n}\n.border-l-2 {\n border-left-width: 2px;\n}\n.border-r {\n border-right-width: 1px;\n}\n.border-t {\n border-top-width: 1px;\n}\n.border-accent {\n border-color: hsl(var(--accent));\n}\n.border-border {\n border-color: hsl(var(--border));\n}\n.border-card {\n border-color: hsl(var(--card));\n}\n.border-gray-400 {\n --tw-border-opacity: 1;\n border-color: rgb(156 163 175 / var(--tw-border-opacity));\n}\n.border-input {\n border-color: hsl(var(--input));\n}\n.border-primary {\n border-color: hsl(var(--primary));\n}\n.border-transparent {\n border-color: transparent;\n}\n.border-l-transparent {\n border-left-color: transparent;\n}\n.border-t-transparent {\n border-top-color: transparent;\n}\n.bg-accent {\n background-color: hsl(var(--accent));\n}\n.bg-background {\n background-color: hsl(var(--background));\n}\n.bg-background\\/80 {\n background-color: hsl(var(--background) / 0.8);\n}\n.bg-border {\n background-color: hsl(var(--border));\n}\n.bg-card {\n background-color: hsl(var(--card));\n}\n.bg-card-foreground {\n background-color: hsl(var(--card-foreground));\n}\n.bg-destructive {\n background-color: hsl(var(--destructive));\n}\n.bg-gray-300 {\n --tw-bg-opacity: 1;\n background-color: rgb(209 213 219 / var(--tw-bg-opacity));\n}\n.bg-gray-500 {\n --tw-bg-opacity: 1;\n background-color: rgb(107 114 128 / var(--tw-bg-opacity));\n}\n.bg-muted {\n background-color: hsl(var(--muted));\n}\n.bg-popover {\n background-color: hsl(var(--popover));\n}\n.bg-primary {\n background-color: hsl(var(--primary));\n}\n.bg-red-500 {\n --tw-bg-opacity: 1;\n background-color: rgb(239 68 68 / var(--tw-bg-opacity));\n}\n.bg-secondary {\n background-color: hsl(var(--secondary));\n}\n.bg-transparent {\n background-color: transparent;\n}\n.bg-white {\n --tw-bg-opacity: 1;\n background-color: rgb(255 255 255 / var(--tw-bg-opacity));\n}\n.bg-gradient-to-b {\n background-image: linear-gradient(to bottom, var(--tw-gradient-stops));\n}\n.from-transparent {\n --tw-gradient-from: transparent var(--tw-gradient-from-position);\n --tw-gradient-to: rgb(0 0 0 / 0) var(--tw-gradient-to-position);\n --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);\n}\n.to-background {\n --tw-gradient-to: hsl(var(--background)) var(--tw-gradient-to-position);\n}\n.fill-current {\n fill: currentColor;\n}\n.fill-white {\n fill: #fff;\n}\n.stroke-\\[2px\\] {\n stroke-width: 2px;\n}\n.stroke-\\[3px\\] {\n stroke-width: 3px;\n}\n.object-contain {\n -o-object-fit: contain;\n object-fit: contain;\n}\n.p-0 {\n padding: 0px;\n}\n.p-1 {\n padding: 0.25rem;\n}\n.p-10 {\n padding: 2.5rem;\n}\n.p-2 {\n padding: 0.5rem;\n}\n.p-3 {\n padding: 0.75rem;\n}\n.p-4 {\n padding: 1rem;\n}\n.p-6 {\n padding: 1.5rem;\n}\n.p-\\[1px\\] {\n padding: 1px;\n}\n.px-1 {\n padding-left: 0.25rem;\n padding-right: 0.25rem;\n}\n.px-2 {\n padding-left: 0.5rem;\n padding-right: 0.5rem;\n}\n.px-2\\.5 {\n padding-left: 0.625rem;\n padding-right: 0.625rem;\n}\n.px-3 {\n padding-left: 0.75rem;\n padding-right: 0.75rem;\n}\n.px-4 {\n padding-left: 1rem;\n padding-right: 1rem;\n}\n.px-5 {\n padding-left: 1.25rem;\n padding-right: 1.25rem;\n}\n.px-8 {\n padding-left: 2rem;\n padding-right: 2rem;\n}\n.px-\\[24px\\] {\n padding-left: 24px;\n padding-right: 24px;\n}\n.py-1 {\n padding-top: 0.25rem;\n padding-bottom: 0.25rem;\n}\n.py-1\\.5 {\n padding-top: 0.375rem;\n padding-bottom: 0.375rem;\n}\n.py-2 {\n padding-top: 0.5rem;\n padding-bottom: 0.5rem;\n}\n.py-3 {\n padding-top: 0.75rem;\n padding-bottom: 0.75rem;\n}\n.py-4 {\n padding-top: 1rem;\n padding-bottom: 1rem;\n}\n.py-6 {\n padding-top: 1.5rem;\n padding-bottom: 1.5rem;\n}\n.py-7 {\n padding-top: 1.75rem;\n padding-bottom: 1.75rem;\n}\n.py-\\[2px\\] {\n padding-top: 2px;\n padding-bottom: 2px;\n}\n.pb-0 {\n padding-bottom: 0px;\n}\n.pb-20 {\n padding-bottom: 5rem;\n}\n.pb-4 {\n padding-bottom: 1rem;\n}\n.pl-6 {\n padding-left: 1.5rem;\n}\n.pl-8 {\n padding-left: 2rem;\n}\n.pr-2 {\n padding-right: 0.5rem;\n}\n.pt-0 {\n padding-top: 0px;\n}\n.pt-1 {\n padding-top: 0.25rem;\n}\n.pt-2 {\n padding-top: 0.5rem;\n}\n.pt-4 {\n padding-top: 1rem;\n}\n.text-left {\n text-align: left;\n}\n.text-center {\n text-align: center;\n}\n.text-start {\n text-align: start;\n}\n.font-sans {\n font-family: 'Roboto', sans-serif;\n}\n.font-serif {\n font-family: 'Space Mono', monospace;\n}\n.text-2xl {\n font-size: 1.5rem;\n line-height: 2rem;\n}\n.text-3xl {\n font-size: 1.875rem;\n line-height: 2.25rem;\n}\n.text-4xl {\n font-size: 2.25rem;\n line-height: 2.5rem;\n}\n.text-\\[0\\.8rem\\] {\n font-size: 0.8rem;\n}\n.text-\\[12px\\] {\n font-size: 12px;\n}\n.text-lg {\n font-size: 1.125rem;\n line-height: 1.75rem;\n}\n.text-sm {\n font-size: 0.875rem;\n line-height: 1.25rem;\n}\n.text-xl {\n font-size: 1.25rem;\n line-height: 1.75rem;\n}\n.text-xs {\n font-size: 0.75rem;\n line-height: 1rem;\n}\n.font-\\[12px\\] {\n font-weight: 12px;\n}\n.font-\\[400\\] {\n font-weight: 400;\n}\n.font-\\[500\\] {\n font-weight: 500;\n}\n.font-\\[550\\] {\n font-weight: 550;\n}\n.font-bold {\n font-weight: 700;\n}\n.font-extrabold {\n font-weight: 800;\n}\n.font-medium {\n font-weight: 500;\n}\n.font-normal {\n font-weight: 400;\n}\n.font-semibold {\n font-weight: 600;\n}\n.uppercase {\n text-transform: uppercase;\n}\n.italic {\n font-style: italic;\n}\n.leading-4 {\n line-height: 1rem;\n}\n.leading-none {\n line-height: 1;\n}\n.tracking-\\[0\\.04em\\] {\n letter-spacing: 0.04em;\n}\n.tracking-tight {\n letter-spacing: -0.025em;\n}\n.tracking-wider {\n letter-spacing: 0.05em;\n}\n.tracking-widest {\n letter-spacing: 0.1em;\n}\n.text-accent {\n color: hsl(var(--accent));\n}\n.text-accent-foreground {\n color: hsl(var(--accent-foreground));\n}\n.text-background {\n color: hsl(var(--background));\n}\n.text-card-foreground {\n color: hsl(var(--card-foreground));\n}\n.text-current {\n color: currentColor;\n}\n.text-destructive {\n color: hsl(var(--destructive));\n}\n.text-destructive-foreground {\n color: hsl(var(--destructive-foreground));\n}\n.text-foreground {\n color: hsl(var(--foreground));\n}\n.text-muted {\n color: hsl(var(--muted));\n}\n.text-muted-foreground {\n color: hsl(var(--muted-foreground));\n}\n.text-popover-foreground {\n color: hsl(var(--popover-foreground));\n}\n.text-primary {\n color: hsl(var(--primary));\n}\n.text-primary-foreground {\n color: hsl(var(--primary-foreground));\n}\n.text-secondary-foreground {\n color: hsl(var(--secondary-foreground));\n}\n.text-white {\n --tw-text-opacity: 1;\n color: rgb(255 255 255 / var(--tw-text-opacity));\n}\n.underline {\n text-decoration-line: underline;\n}\n.line-through {\n text-decoration-line: line-through;\n}\n.underline-offset-4 {\n text-underline-offset: 4px;\n}\n.antialiased {\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n.opacity-0 {\n opacity: 0;\n}\n.opacity-100 {\n opacity: 1;\n}\n.opacity-50 {\n opacity: 0.5;\n}\n.opacity-60 {\n opacity: 0.6;\n}\n.opacity-70 {\n opacity: 0.7;\n}\n.opacity-75 {\n opacity: 0.75;\n}\n.shadow {\n --tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);\n --tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);\n box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);\n}\n.shadow-lg {\n --tw-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);\n --tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);\n box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);\n}\n.shadow-md {\n --tw-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);\n --tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);\n box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);\n}\n.shadow-sm {\n --tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);\n --tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);\n box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);\n}\n.outline-none {\n outline: 2px solid transparent;\n outline-offset: 2px;\n}\n.outline {\n outline-style: solid;\n}\n.ring-0 {\n --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);\n --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color);\n box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);\n}\n.ring-offset-background {\n --tw-ring-offset-color: hsl(var(--background));\n}\n.drop-shadow-2xl {\n --tw-drop-shadow: drop-shadow(0 25px 25px rgb(0 0 0 / 0.15));\n filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);\n}\n.drop-shadow-\\[0px_0px_12px_rgba\\(56\\2c 205\\2c 152\\2c 0\\.60\\)\\] {\n --tw-drop-shadow: drop-shadow(0px 0px 12px rgba(56,205,152,0.60));\n filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);\n}\n.filter {\n filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);\n}\n.backdrop-blur-sm {\n --tw-backdrop-blur: blur(4px);\n -webkit-backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);\n backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);\n}\n.transition-all {\n transition-property: all;\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n transition-duration: 150ms;\n}\n.transition-colors {\n transition-property: color, background-color, border-color, text-decoration-color, fill, stroke;\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n transition-duration: 150ms;\n}\n.transition-opacity {\n transition-property: opacity;\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n transition-duration: 150ms;\n}\n.transition-transform {\n transition-property: transform;\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n transition-duration: 150ms;\n}\n.duration-150 {\n transition-duration: 150ms;\n}\n.duration-200 {\n transition-duration: 200ms;\n}\n.ease-in-out {\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n}\n@keyframes enter {\n\n from {\n opacity: var(--tw-enter-opacity, 1);\n transform: translate3d(var(--tw-enter-translate-x, 0), var(--tw-enter-translate-y, 0), 0) scale3d(var(--tw-enter-scale, 1), var(--tw-enter-scale, 1), var(--tw-enter-scale, 1)) rotate(var(--tw-enter-rotate, 0));\n }\n}\n@keyframes exit {\n\n to {\n opacity: var(--tw-exit-opacity, 1);\n transform: translate3d(var(--tw-exit-translate-x, 0), var(--tw-exit-translate-y, 0), 0) scale3d(var(--tw-exit-scale, 1), var(--tw-exit-scale, 1), var(--tw-exit-scale, 1)) rotate(var(--tw-exit-rotate, 0));\n }\n}\n.animate-in {\n animation-name: enter;\n animation-duration: 150ms;\n --tw-enter-opacity: initial;\n --tw-enter-scale: initial;\n --tw-enter-rotate: initial;\n --tw-enter-translate-x: initial;\n --tw-enter-translate-y: initial;\n}\n.fade-in-0 {\n --tw-enter-opacity: 0;\n}\n.zoom-in-95 {\n --tw-enter-scale: .95;\n}\n.duration-150 {\n animation-duration: 150ms;\n}\n.duration-200 {\n animation-duration: 200ms;\n}\n.ease-in-out {\n animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n}\n.file\\:border-0::file-selector-button {\n border-width: 0px;\n}\n.file\\:bg-transparent::file-selector-button {\n background-color: transparent;\n}\n.file\\:text-sm::file-selector-button {\n font-size: 0.875rem;\n line-height: 1.25rem;\n}\n.file\\:font-medium::file-selector-button {\n font-weight: 500;\n}\n.placeholder\\:text-muted-foreground::-moz-placeholder {\n color: hsl(var(--muted-foreground));\n}\n.placeholder\\:text-muted-foreground::placeholder {\n color: hsl(var(--muted-foreground));\n}\n.focus-within\\:relative:focus-within {\n position: relative;\n}\n.hover\\:w-\\[2px\\]:hover {\n width: 2px;\n}\n.hover\\:w-\\[3px\\]:hover {\n width: 3px;\n}\n.hover\\:cursor-pointer:hover {\n cursor: pointer;\n}\n.hover\\:rounded-lg:hover {\n border-radius: var(--radius);\n}\n.hover\\:bg-accent:hover {\n background-color: hsl(var(--accent));\n}\n.hover\\:bg-background:hover {\n background-color: hsl(var(--background));\n}\n.hover\\:bg-border:hover {\n background-color: hsl(var(--border));\n}\n.hover\\:bg-destructive\\/90:hover {\n background-color: hsl(var(--destructive) / 0.9);\n}\n.hover\\:bg-muted:hover {\n background-color: hsl(var(--muted));\n}\n.hover\\:bg-primary:hover {\n background-color: hsl(var(--primary));\n}\n.hover\\:bg-primary\\/90:hover {\n background-color: hsl(var(--primary) / 0.9);\n}\n.hover\\:bg-red-700:hover {\n --tw-bg-opacity: 1;\n background-color: rgb(185 28 28 / var(--tw-bg-opacity));\n}\n.hover\\:bg-secondary\\/80:hover {\n background-color: hsl(var(--secondary) / 0.8);\n}\n.hover\\:text-accent-foreground:hover {\n color: hsl(var(--accent-foreground));\n}\n.hover\\:text-muted-foreground:hover {\n color: hsl(var(--muted-foreground));\n}\n.hover\\:text-primary-foreground:hover {\n color: hsl(var(--primary-foreground));\n}\n.hover\\:text-white:hover {\n --tw-text-opacity: 1;\n color: rgb(255 255 255 / var(--tw-text-opacity));\n}\n.hover\\:underline:hover {\n text-decoration-line: underline;\n}\n.hover\\:opacity-100:hover {\n opacity: 1;\n}\n.focus\\:bg-accent:focus {\n background-color: hsl(var(--accent));\n}\n.focus\\:bg-primary:focus {\n background-color: hsl(var(--primary));\n}\n.focus\\:text-accent-foreground:focus {\n color: hsl(var(--accent-foreground));\n}\n.focus\\:text-primary-foreground:focus {\n color: hsl(var(--primary-foreground));\n}\n.focus\\:outline-none:focus {\n outline: 2px solid transparent;\n outline-offset: 2px;\n}\n.focus\\:ring-2:focus {\n --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);\n --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);\n box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);\n}\n.focus\\:ring-ring:focus {\n --tw-ring-color: hsl(var(--ring));\n}\n.focus\\:ring-offset-2:focus {\n --tw-ring-offset-width: 2px;\n}\n.focus-visible\\:outline-none:focus-visible {\n outline: 2px solid transparent;\n outline-offset: 2px;\n}\n.focus-visible\\:outline-accent:focus-visible {\n outline-color: hsl(var(--accent));\n}\n.focus-visible\\:ring-2:focus-visible {\n --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);\n --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);\n box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);\n}\n.focus-visible\\:ring-ring:focus-visible {\n --tw-ring-color: hsl(var(--ring));\n}\n.focus-visible\\:ring-offset-2:focus-visible {\n --tw-ring-offset-width: 2px;\n}\n.focus-visible\\:ring-offset-background:focus-visible {\n --tw-ring-offset-color: hsl(var(--background));\n}\n.disabled\\:pointer-events-none:disabled {\n pointer-events: none;\n}\n.disabled\\:cursor-not-allowed:disabled {\n cursor: not-allowed;\n}\n.disabled\\:text-background:disabled {\n color: hsl(var(--background));\n}\n.disabled\\:opacity-50:disabled {\n opacity: 0.5;\n}\n.peer:disabled ~ .peer-disabled\\:cursor-not-allowed {\n cursor: not-allowed;\n}\n.peer:disabled ~ .peer-disabled\\:opacity-70 {\n opacity: 0.7;\n}\n.aria-selected\\:bg-accent[aria-selected=\"true\"] {\n background-color: hsl(var(--accent));\n}\n.aria-selected\\:text-accent-foreground[aria-selected=\"true\"] {\n color: hsl(var(--accent-foreground));\n}\n.aria-selected\\:opacity-100[aria-selected=\"true\"] {\n opacity: 1;\n}\n.data-\\[disabled\\]\\:pointer-events-none[data-disabled] {\n pointer-events: none;\n}\n.data-\\[side\\=bottom\\]\\:translate-y-1[data-side=bottom] {\n --tw-translate-y: 0.25rem;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.data-\\[side\\=left\\]\\:-translate-x-1[data-side=left] {\n --tw-translate-x: -0.25rem;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.data-\\[side\\=right\\]\\:translate-x-1[data-side=right] {\n --tw-translate-x: 0.25rem;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.data-\\[side\\=top\\]\\:-translate-y-1[data-side=top] {\n --tw-translate-y: -0.25rem;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.data-\\[state\\=checked\\]\\:translate-x-5[data-state=checked] {\n --tw-translate-x: 1.25rem;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.data-\\[state\\=unchecked\\]\\:translate-x-0[data-state=unchecked] {\n --tw-translate-x: 0px;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n@keyframes accordion-up {\n\n from {\n height: var(--radix-accordion-content-height);\n }\n\n to {\n height: 0;\n }\n}\n.data-\\[state\\=closed\\]\\:animate-accordion-up[data-state=closed] {\n animation: accordion-up 0.2s ease-out;\n}\n@keyframes accordion-down {\n\n from {\n height: 0;\n }\n\n to {\n height: var(--radix-accordion-content-height);\n }\n}\n.data-\\[state\\=open\\]\\:animate-accordion-down[data-state=open] {\n animation: accordion-down 0.2s ease-out;\n}\n.data-\\[state\\=active\\]\\:bg-background[data-state=active] {\n background-color: hsl(var(--background));\n}\n.data-\\[state\\=checked\\]\\:bg-accent[data-state=checked] {\n background-color: hsl(var(--accent));\n}\n.data-\\[state\\=checked\\]\\:bg-primary[data-state=checked] {\n background-color: hsl(var(--primary));\n}\n.data-\\[state\\=on\\]\\:bg-accent[data-state=on] {\n background-color: hsl(var(--accent));\n}\n.data-\\[state\\=open\\]\\:bg-accent[data-state=open] {\n background-color: hsl(var(--accent));\n}\n.data-\\[state\\=unchecked\\]\\:bg-primary[data-state=unchecked] {\n background-color: hsl(var(--primary));\n}\n.data-\\[state\\=active\\]\\:text-foreground[data-state=active] {\n color: hsl(var(--foreground));\n}\n.data-\\[state\\=checked\\]\\:text-primary-foreground[data-state=checked] {\n color: hsl(var(--primary-foreground));\n}\n.data-\\[state\\=on\\]\\:text-accent-foreground[data-state=on] {\n color: hsl(var(--accent-foreground));\n}\n.data-\\[state\\=open\\]\\:text-muted-foreground[data-state=open] {\n color: hsl(var(--muted-foreground));\n}\n.data-\\[disabled\\]\\:opacity-50[data-disabled] {\n opacity: 0.5;\n}\n.data-\\[state\\=active\\]\\:shadow-sm[data-state=active] {\n --tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);\n --tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);\n box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);\n}\n.data-\\[state\\=open\\]\\:animate-in[data-state=open] {\n animation-name: enter;\n animation-duration: 150ms;\n --tw-enter-opacity: initial;\n --tw-enter-scale: initial;\n --tw-enter-rotate: initial;\n --tw-enter-translate-x: initial;\n --tw-enter-translate-y: initial;\n}\n.data-\\[state\\=closed\\]\\:animate-out[data-state=closed] {\n animation-name: exit;\n animation-duration: 150ms;\n --tw-exit-opacity: initial;\n --tw-exit-scale: initial;\n --tw-exit-rotate: initial;\n --tw-exit-translate-x: initial;\n --tw-exit-translate-y: initial;\n}\n.data-\\[state\\=closed\\]\\:fade-out-0[data-state=closed] {\n --tw-exit-opacity: 0;\n}\n.data-\\[state\\=open\\]\\:fade-in-0[data-state=open] {\n --tw-enter-opacity: 0;\n}\n.data-\\[state\\=closed\\]\\:zoom-out-95[data-state=closed] {\n --tw-exit-scale: .95;\n}\n.data-\\[state\\=open\\]\\:zoom-in-95[data-state=open] {\n --tw-enter-scale: .95;\n}\n.data-\\[side\\=bottom\\]\\:slide-in-from-top-2[data-side=bottom] {\n --tw-enter-translate-y: -0.5rem;\n}\n.data-\\[side\\=left\\]\\:slide-in-from-right-2[data-side=left] {\n --tw-enter-translate-x: 0.5rem;\n}\n.data-\\[side\\=right\\]\\:slide-in-from-left-2[data-side=right] {\n --tw-enter-translate-x: -0.5rem;\n}\n.data-\\[side\\=top\\]\\:slide-in-from-bottom-2[data-side=top] {\n --tw-enter-translate-y: 0.5rem;\n}\n.data-\\[state\\=closed\\]\\:slide-out-to-left-1\\/2[data-state=closed] {\n --tw-exit-translate-x: -50%;\n}\n.data-\\[state\\=closed\\]\\:slide-out-to-top-\\[48\\%\\][data-state=closed] {\n --tw-exit-translate-y: -48%;\n}\n.data-\\[state\\=open\\]\\:slide-in-from-left-1\\/2[data-state=open] {\n --tw-enter-translate-x: -50%;\n}\n.data-\\[state\\=open\\]\\:slide-in-from-top-\\[48\\%\\][data-state=open] {\n --tw-enter-translate-y: -48%;\n}\n:is([data-mode=\"dark\"] .dark\\:border-white) {\n --tw-border-opacity: 1;\n border-color: rgb(255 255 255 / var(--tw-border-opacity));\n}\n@media (min-width: 640px) {\n\n .sm\\:mt-0 {\n margin-top: 0px;\n }\n\n .sm\\:block {\n display: block;\n }\n\n .sm\\:flex-row {\n flex-direction: row;\n }\n\n .sm\\:justify-end {\n justify-content: flex-end;\n }\n\n .sm\\:space-x-2 > :not([hidden]) ~ :not([hidden]) {\n --tw-space-x-reverse: 0;\n margin-right: calc(0.5rem * var(--tw-space-x-reverse));\n margin-left: calc(0.5rem * calc(1 - var(--tw-space-x-reverse)));\n }\n\n .sm\\:space-x-4 > :not([hidden]) ~ :not([hidden]) {\n --tw-space-x-reverse: 0;\n margin-right: calc(1rem * var(--tw-space-x-reverse));\n margin-left: calc(1rem * calc(1 - var(--tw-space-x-reverse)));\n }\n\n .sm\\:space-y-0 > :not([hidden]) ~ :not([hidden]) {\n --tw-space-y-reverse: 0;\n margin-top: calc(0px * calc(1 - var(--tw-space-y-reverse)));\n margin-bottom: calc(0px * var(--tw-space-y-reverse));\n }\n\n .sm\\:rounded-lg {\n border-radius: var(--radius);\n }\n\n .sm\\:p-0 {\n padding: 0px;\n }\n\n .sm\\:text-left {\n text-align: left;\n }\n}\n@media (min-width: 768px) {\n\n .md\\:w-full {\n width: 100%;\n }\n}\n.\\[\\&\\:has\\(\\[aria-selected\\]\\)\\]\\:bg-accent:has([aria-selected]) {\n background-color: hsl(var(--accent));\n}\n.first\\:\\[\\&\\:has\\(\\[aria-selected\\]\\)\\]\\:rounded-l-md:has([aria-selected]):first-child {\n border-top-left-radius: calc(var(--radius) - 2px);\n border-bottom-left-radius: calc(var(--radius) - 2px);\n}\n.last\\:\\[\\&\\:has\\(\\[aria-selected\\]\\)\\]\\:rounded-r-md:has([aria-selected]):last-child {\n border-top-right-radius: calc(var(--radius) - 2px);\n border-bottom-right-radius: calc(var(--radius) - 2px);\n}\n.\\[\\&\\[data-state\\=open\\]\\>svg\\]\\:rotate-180[data-state=open]>svg {\n --tw-rotate: 180deg;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.\\[\\&_\\[cmdk-group-heading\\]\\]\\:px-2 [cmdk-group-heading] {\n padding-left: 0.5rem;\n padding-right: 0.5rem;\n}\n.\\[\\&_\\[cmdk-group-heading\\]\\]\\:py-1\\.5 [cmdk-group-heading] {\n padding-top: 0.375rem;\n padding-bottom: 0.375rem;\n}\n.\\[\\&_\\[cmdk-group-heading\\]\\]\\:text-xs [cmdk-group-heading] {\n font-size: 0.75rem;\n line-height: 1rem;\n}\n.\\[\\&_\\[cmdk-group-heading\\]\\]\\:font-medium [cmdk-group-heading] {\n font-weight: 500;\n}\n.\\[\\&_\\[cmdk-group-heading\\]\\]\\:text-muted-foreground [cmdk-group-heading] {\n color: hsl(var(--muted-foreground));\n}\n.\\[\\&_\\[cmdk-group\\]\\:not\\(\\[hidden\\]\\)_\\~\\[cmdk-group\\]\\]\\:pt-0 [cmdk-group]:not([hidden]) ~[cmdk-group] {\n padding-top: 0px;\n}\n.\\[\\&_\\[cmdk-group\\]\\]\\:px-2 [cmdk-group] {\n padding-left: 0.5rem;\n padding-right: 0.5rem;\n}\n.\\[\\&_\\[cmdk-input-wrapper\\]_svg\\]\\:h-5 [cmdk-input-wrapper] svg {\n height: 1.25rem;\n}\n.\\[\\&_\\[cmdk-input-wrapper\\]_svg\\]\\:w-5 [cmdk-input-wrapper] svg {\n width: 1.25rem;\n}\n.\\[\\&_\\[cmdk-input\\]\\]\\:h-12 [cmdk-input] {\n height: 3rem;\n}\n.\\[\\&_\\[cmdk-item\\]\\]\\:px-2 [cmdk-item] {\n padding-left: 0.5rem;\n padding-right: 0.5rem;\n}\n.\\[\\&_\\[cmdk-item\\]\\]\\:py-3 [cmdk-item] {\n padding-top: 0.75rem;\n padding-bottom: 0.75rem;\n}\n.\\[\\&_\\[cmdk-item\\]_svg\\]\\:h-5 [cmdk-item] svg {\n height: 1.25rem;\n}\n.\\[\\&_\\[cmdk-item\\]_svg\\]\\:w-5 [cmdk-item] svg {\n width: 1.25rem;\n}\n";
73940
73880
  function Style() {
73941
73881
  return /* @__PURE__ */ jsx("style", { children: styleCss });
73942
73882
  }