@lax-wp/design-system 0.13.40 → 0.13.42

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.
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),p=require("react"),i=require("../../../_virtual/index.cjs.js"),l=require("../../data-display/banner/Banner.cjs.js"),o=require("../../../constants/layout.cjs.js"),M=require("../../../hooks/useScrollToTop.cjs.js"),g=require("../../layout/Helmet.cjs.js"),c=({title:s,children:u,noPadding:d,className:x,noBanner:a,noScrollbar:m,mode:t,displayId:n})=>{const r=t===o.MODES.EDIT||t===o.MODES.FOCUS_EDIT?"edit":t===o.MODES.COMPARISON?"compare":null,b=p.useMemo(()=>r==="edit"&&n&&!a||r==="compare",[r,n,a]);return M.useScrollToTop(),e.jsxs(e.Fragment,{children:[s?e.jsx(g.Helmet,{title:s}):null,e.jsxs("div",{style:{marginLeft:"var(--sidebar-ml, 0px)"},className:i(" relative h-[calc(100vh-56px)] overflow-y-auto flex flex-col bg-primary-800 dark:bg-black-800",`ease-in-out duration-${o.OPEN_DURATION_MS}`,x),children:[r==="edit"&&n&&!a?e.jsx(l.Banner,{status:"warning",children:`You're currently editing ${n||""}`}):r==="compare"?e.jsx(l.Banner,{status:"success",children:"You are now in Comparison Mode"}):null,e.jsx("div",{className:i(`flex-1 overflow-y-auto overflow-x-hidden bg-gray-50 dark:bg-black-700 ${m?"hide-scrollbar":""}`,d?"p-0":"p-base",b?"rounded-tl-none":"!rounded-tl-xl"),id:"app-body-container",children:u})]})]})};c.displayName="CardMain";exports.CardMain=c;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),g=require("react"),s=require("../../../_virtual/index.cjs.js"),l=require("../../data-display/banner/Banner.cjs.js"),o=require("../../../constants/layout.cjs.js"),p=require("../../../hooks/useScrollToTop.cjs.js"),M=require("../../layout/Helmet.cjs.js"),c=({title:i,children:u,noPadding:d,className:m,noBanner:a,noScrollbar:x,mode:t,displayId:n})=>{const r=t===o.MODES.EDIT||t===o.MODES.FOCUS_EDIT?"edit":t===o.MODES.COMPARISON?"compare":null,b=g.useMemo(()=>r==="edit"&&n&&!a||r==="compare",[r,n,a]);return p.useScrollToTop(),e.jsxs(e.Fragment,{children:[i?e.jsx(M.Helmet,{title:i}):null,e.jsxs("div",{style:{marginLeft:"var(--sidebar-ml, 0px)"},className:s(" relative h-[calc(100vh-56px)] overflow-y-auto flex flex-col bg-primary-800 dark:bg-black-800",`transition-[margin-left] ease-in-out duration-${o.OPEN_DURATION_MS}`,m),children:[r==="edit"&&n&&!a?e.jsx(l.Banner,{status:"warning",children:`You're currently editing ${n||""}`}):r==="compare"?e.jsx(l.Banner,{status:"success",children:"You are now in Comparison Mode"}):null,e.jsx("div",{className:s(`flex-1 overflow-y-auto overflow-x-hidden bg-gray-50 dark:bg-black-700 ${x?"hide-scrollbar":""}`,d?"p-0":"p-base",b?"rounded-tl-none":"!rounded-tl-xl"),id:"app-body-container",children:u})]})]})};c.displayName="CardMain";exports.CardMain=c;
2
2
  //# sourceMappingURL=CardMain.cjs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"CardMain.cjs.js","sources":["../../../../src/components/cards/card-main/CardMain.tsx"],"sourcesContent":["import type { FC, ReactNode } from 'react';\nimport { useMemo } from 'react';\nimport cn from 'classnames';\nimport { Banner } from '../../data-display/banner/Banner';\nimport { MODES, OPEN_DURATION_MS } from '../../../constants/layout';\nimport { useScrollToTop } from '../../../hooks/useScrollToTop';\nimport { Helmet } from '../../layout';\n\nexport type CardMainProps = {\n title?: string;\n children: ReactNode;\n noPadding?: boolean;\n className?: string;\n noHeight?: boolean;\n noBanner?: boolean;\n noScrollbar?: boolean;\n /** Current mode - can be 'edit', 'focusEdit', 'comparison' */\n mode?: string | null;\n /** Display ID to show in banner */\n displayId?: string | null;\n /** Whether the main sidebar is expanded */\n isMainSideBarOpen?: boolean;\n};\n\n/**\n * CardMain component for main content areas with optional edit/comparison banners\n *\n * @example\n * ```tsx\n * <CardMain title=\"Page Title\" mode=\"edit\" displayId=\"DOC-001\">\n * <div>Page content</div>\n * </CardMain>\n * ```\n */\nexport const CardMain: FC<CardMainProps> = ({\n title,\n children,\n noPadding,\n className,\n noBanner,\n noScrollbar,\n mode,\n displayId,\n}) => {\n const currentMode = mode === MODES.EDIT || mode === MODES.FOCUS_EDIT ? 'edit' : mode === MODES.COMPARISON ? 'compare' : null;\n\n const isBannerVisible = useMemo(() => {\n return (currentMode === 'edit' && displayId && !noBanner) || currentMode === 'compare';\n }, [currentMode, displayId, noBanner]);\n\n\n useScrollToTop()\n return (\n <>\n {!!title ? <Helmet title={title} /> : null}\n <div\n style={{\n marginLeft: 'var(--sidebar-ml, 0px)'\n }}\n className={cn(\n ` relative h-[calc(100vh-56px)] overflow-y-auto flex flex-col bg-primary-800 dark:bg-black-800`,\n `ease-in-out duration-${OPEN_DURATION_MS}`,\n className,\n )}\n >\n {currentMode === 'edit' && displayId && !noBanner ? (\n <Banner status='warning'>{`You're currently editing ${displayId || ''}`}</Banner>\n ) : currentMode === 'compare' ? (\n <Banner status='success'>{`You are now in Comparison Mode`}</Banner>\n ) : null}\n\n <div\n className={cn(\n `flex-1 overflow-y-auto overflow-x-hidden bg-gray-50 dark:bg-black-700 ${noScrollbar ? 'hide-scrollbar' : ''}`,\n noPadding ? 'p-0' : 'p-base',\n isBannerVisible ? 'rounded-tl-none' : '!rounded-tl-xl',\n )}\n id='app-body-container'\n >\n {children}\n </div>\n </div>\n </>\n );\n};\n\nCardMain.displayName = 'CardMain';\n\n\n\n"],"names":["CardMain","title","children","noPadding","className","noBanner","noScrollbar","mode","displayId","currentMode","MODES","isBannerVisible","useMemo","useScrollToTop","jsxs","Fragment","jsx","Helmet","cn","OPEN_DURATION_MS","Banner"],"mappings":"iXAkCaA,EAA8B,CAAC,CAC1C,MAAAC,EACA,SAAAC,EACA,UAAAC,EACA,UAAAC,EACA,SAAAC,EACA,YAAAC,EACA,KAAAC,EACA,UAAAC,CACF,IAAM,CACJ,MAAMC,EAAcF,IAASG,QAAM,MAAQH,IAASG,EAAAA,MAAM,WAAa,OAASH,IAASG,EAAAA,MAAM,WAAa,UAAY,KAElHC,EAAkBC,EAAAA,QAAQ,IACtBH,IAAgB,QAAUD,GAAa,CAACH,GAAaI,IAAgB,UAC5E,CAACA,EAAaD,EAAWH,CAAQ,CAAC,EAGrCQ,OAAAA,iBAAA,EAEEC,EAAAA,KAAAC,WAAA,CACG,SAAA,CAAEd,EAAQe,EAAAA,IAACC,EAAAA,OAAA,CAAO,MAAAhB,EAAc,EAAK,KACtCa,EAAAA,KAAC,MAAA,CACD,MAAO,CACL,WAAY,wBAAA,EAEZ,UAAWI,EACT,gGACA,wBAAwBC,EAAAA,gBAAgB,GACxCf,CAAA,EAGD,SAAA,CAAAK,IAAgB,QAAUD,GAAa,CAACH,QACtCe,EAAAA,OAAA,CAAO,OAAO,UAAW,SAAA,4BAA4BZ,GAAa,EAAE,EAAA,CAAG,EACtEC,IAAgB,UAClBO,EAAAA,IAACI,EAAAA,QAAO,OAAO,UAAW,0CAAiC,EACzD,KAEJJ,EAAAA,IAAC,MAAA,CACC,UAAWE,EACT,yEAAyEZ,EAAc,iBAAmB,EAAE,GAC5GH,EAAY,MAAQ,SACpBQ,EAAkB,kBAAoB,gBAAA,EAExC,GAAG,qBAEF,SAAAT,CAAA,CAAA,CACH,CAAA,CAAA,CACF,EACF,CAEJ,EAEAF,EAAS,YAAc"}
1
+ {"version":3,"file":"CardMain.cjs.js","sources":["../../../../src/components/cards/card-main/CardMain.tsx"],"sourcesContent":["import type { FC, ReactNode } from 'react';\nimport { useMemo } from 'react';\nimport cn from 'classnames';\nimport { Banner } from '../../data-display/banner/Banner';\nimport { MODES, OPEN_DURATION_MS } from '../../../constants/layout';\nimport { useScrollToTop } from '../../../hooks/useScrollToTop';\nimport { Helmet } from '../../layout';\n\nexport type CardMainProps = {\n title?: string;\n children: ReactNode;\n noPadding?: boolean;\n className?: string;\n noHeight?: boolean;\n noBanner?: boolean;\n noScrollbar?: boolean;\n /** Current mode - can be 'edit', 'focusEdit', 'comparison' */\n mode?: string | null;\n /** Display ID to show in banner */\n displayId?: string | null;\n /** Whether the main sidebar is expanded */\n isMainSideBarOpen?: boolean;\n};\n\n/**\n * CardMain component for main content areas with optional edit/comparison banners\n *\n * @example\n * ```tsx\n * <CardMain title=\"Page Title\" mode=\"edit\" displayId=\"DOC-001\">\n * <div>Page content</div>\n * </CardMain>\n * ```\n */\nexport const CardMain: FC<CardMainProps> = ({\n title,\n children,\n noPadding,\n className,\n noBanner,\n noScrollbar,\n mode,\n displayId,\n}) => {\n const currentMode = mode === MODES.EDIT || mode === MODES.FOCUS_EDIT ? 'edit' : mode === MODES.COMPARISON ? 'compare' : null;\n\n const isBannerVisible = useMemo(() => {\n return (currentMode === 'edit' && displayId && !noBanner) || currentMode === 'compare';\n }, [currentMode, displayId, noBanner]);\n\n\n useScrollToTop()\n return (\n <>\n {!!title ? <Helmet title={title} /> : null}\n <div\n style={{\n marginLeft: 'var(--sidebar-ml, 0px)'\n }}\n className={cn(\n ` relative h-[calc(100vh-56px)] overflow-y-auto flex flex-col bg-primary-800 dark:bg-black-800`,\n // Scope the transition to margin-left (the sidebar push). Without an explicit\n // transition-property, `duration-*` falls back to CSS's default `all`, which\n // also animates background-color over 500ms — that made the rounded-tl corner\n // flash a mismatched triangle on theme toggle. The background now flips with\n // the `dark` class and is handled by the view transition.\n `transition-[margin-left] ease-in-out duration-${OPEN_DURATION_MS}`,\n className,\n )}\n >\n {currentMode === 'edit' && displayId && !noBanner ? (\n <Banner status='warning'>{`You're currently editing ${displayId || ''}`}</Banner>\n ) : currentMode === 'compare' ? (\n <Banner status='success'>{`You are now in Comparison Mode`}</Banner>\n ) : null}\n\n <div\n className={cn(\n `flex-1 overflow-y-auto overflow-x-hidden bg-gray-50 dark:bg-black-700 ${noScrollbar ? 'hide-scrollbar' : ''}`,\n noPadding ? 'p-0' : 'p-base',\n isBannerVisible ? 'rounded-tl-none' : '!rounded-tl-xl',\n )}\n id='app-body-container'\n >\n {children}\n </div>\n </div>\n </>\n );\n};\n\nCardMain.displayName = 'CardMain';\n\n\n\n"],"names":["CardMain","title","children","noPadding","className","noBanner","noScrollbar","mode","displayId","currentMode","MODES","isBannerVisible","useMemo","useScrollToTop","jsxs","Fragment","jsx","Helmet","cn","OPEN_DURATION_MS","Banner"],"mappings":"iXAkCaA,EAA8B,CAAC,CAC1C,MAAAC,EACA,SAAAC,EACA,UAAAC,EACA,UAAAC,EACA,SAAAC,EACA,YAAAC,EACA,KAAAC,EACA,UAAAC,CACF,IAAM,CACJ,MAAMC,EAAcF,IAASG,QAAM,MAAQH,IAASG,EAAAA,MAAM,WAAa,OAASH,IAASG,EAAAA,MAAM,WAAa,UAAY,KAElHC,EAAkBC,EAAAA,QAAQ,IACtBH,IAAgB,QAAUD,GAAa,CAACH,GAAaI,IAAgB,UAC5E,CAACA,EAAaD,EAAWH,CAAQ,CAAC,EAGrCQ,OAAAA,iBAAA,EAEEC,EAAAA,KAAAC,WAAA,CACG,SAAA,CAAEd,EAAQe,EAAAA,IAACC,EAAAA,OAAA,CAAO,MAAAhB,EAAc,EAAK,KACtCa,EAAAA,KAAC,MAAA,CACD,MAAO,CACL,WAAY,wBAAA,EAEZ,UAAWI,EACT,gGAMA,iDAAiDC,EAAAA,gBAAgB,GACjEf,CAAA,EAGD,SAAA,CAAAK,IAAgB,QAAUD,GAAa,CAACH,QACtCe,EAAAA,OAAA,CAAO,OAAO,UAAW,SAAA,4BAA4BZ,GAAa,EAAE,EAAA,CAAG,EACtEC,IAAgB,UAClBO,EAAAA,IAACI,EAAAA,QAAO,OAAO,UAAW,0CAAiC,EACzD,KAEJJ,EAAAA,IAAC,MAAA,CACC,UAAWE,EACT,yEAAyEZ,EAAc,iBAAmB,EAAE,GAC5GH,EAAY,MAAQ,SACpBQ,EAAkB,kBAAoB,gBAAA,EAExC,GAAG,qBAEF,SAAAT,CAAA,CAAA,CACH,CAAA,CAAA,CACF,EACF,CAEJ,EAEAF,EAAS,YAAc"}
@@ -1,13 +1,13 @@
1
- import { jsxs as n, Fragment as b, jsx as o } from "react/jsx-runtime";
2
- import { useMemo as x } from "react";
3
- import c from "../../../_virtual/index.es.js";
4
- import { Banner as m } from "../../data-display/banner/Banner.es.js";
5
- import { MODES as t, OPEN_DURATION_MS as g } from "../../../constants/layout.es.js";
1
+ import { jsxs as l, Fragment as b, jsx as o } from "react/jsx-runtime";
2
+ import { useMemo as g } from "react";
3
+ import m from "../../../_virtual/index.es.js";
4
+ import { Banner as s } from "../../data-display/banner/Banner.es.js";
5
+ import { MODES as t, OPEN_DURATION_MS as x } from "../../../constants/layout.es.js";
6
6
  import { useScrollToTop as h } from "../../../hooks/useScrollToTop.es.js";
7
7
  import { Helmet as v } from "../../layout/Helmet.es.js";
8
8
  const M = ({
9
- title: l,
10
- children: s,
9
+ title: n,
10
+ children: c,
11
11
  noPadding: d,
12
12
  className: u,
13
13
  noBanner: a,
@@ -15,32 +15,37 @@ const M = ({
15
15
  mode: i,
16
16
  displayId: e
17
17
  }) => {
18
- const r = i === t.EDIT || i === t.FOCUS_EDIT ? "edit" : i === t.COMPARISON ? "compare" : null, f = x(() => r === "edit" && e && !a || r === "compare", [r, e, a]);
19
- return h(), /* @__PURE__ */ n(b, { children: [
20
- l ? /* @__PURE__ */ o(v, { title: l }) : null,
21
- /* @__PURE__ */ n(
18
+ const r = i === t.EDIT || i === t.FOCUS_EDIT ? "edit" : i === t.COMPARISON ? "compare" : null, f = g(() => r === "edit" && e && !a || r === "compare", [r, e, a]);
19
+ return h(), /* @__PURE__ */ l(b, { children: [
20
+ n ? /* @__PURE__ */ o(v, { title: n }) : null,
21
+ /* @__PURE__ */ l(
22
22
  "div",
23
23
  {
24
24
  style: {
25
25
  marginLeft: "var(--sidebar-ml, 0px)"
26
26
  },
27
- className: c(
27
+ className: m(
28
28
  " relative h-[calc(100vh-56px)] overflow-y-auto flex flex-col bg-primary-800 dark:bg-black-800",
29
- `ease-in-out duration-${g}`,
29
+ // Scope the transition to margin-left (the sidebar push). Without an explicit
30
+ // transition-property, `duration-*` falls back to CSS's default `all`, which
31
+ // also animates background-color over 500ms — that made the rounded-tl corner
32
+ // flash a mismatched triangle on theme toggle. The background now flips with
33
+ // the `dark` class and is handled by the view transition.
34
+ `transition-[margin-left] ease-in-out duration-${x}`,
30
35
  u
31
36
  ),
32
37
  children: [
33
- r === "edit" && e && !a ? /* @__PURE__ */ o(m, { status: "warning", children: `You're currently editing ${e || ""}` }) : r === "compare" ? /* @__PURE__ */ o(m, { status: "success", children: "You are now in Comparison Mode" }) : null,
38
+ r === "edit" && e && !a ? /* @__PURE__ */ o(s, { status: "warning", children: `You're currently editing ${e || ""}` }) : r === "compare" ? /* @__PURE__ */ o(s, { status: "success", children: "You are now in Comparison Mode" }) : null,
34
39
  /* @__PURE__ */ o(
35
40
  "div",
36
41
  {
37
- className: c(
42
+ className: m(
38
43
  `flex-1 overflow-y-auto overflow-x-hidden bg-gray-50 dark:bg-black-700 ${p ? "hide-scrollbar" : ""}`,
39
44
  d ? "p-0" : "p-base",
40
45
  f ? "rounded-tl-none" : "!rounded-tl-xl"
41
46
  ),
42
47
  id: "app-body-container",
43
- children: s
48
+ children: c
44
49
  }
45
50
  )
46
51
  ]
@@ -1 +1 @@
1
- {"version":3,"file":"CardMain.es.js","sources":["../../../../src/components/cards/card-main/CardMain.tsx"],"sourcesContent":["import type { FC, ReactNode } from 'react';\nimport { useMemo } from 'react';\nimport cn from 'classnames';\nimport { Banner } from '../../data-display/banner/Banner';\nimport { MODES, OPEN_DURATION_MS } from '../../../constants/layout';\nimport { useScrollToTop } from '../../../hooks/useScrollToTop';\nimport { Helmet } from '../../layout';\n\nexport type CardMainProps = {\n title?: string;\n children: ReactNode;\n noPadding?: boolean;\n className?: string;\n noHeight?: boolean;\n noBanner?: boolean;\n noScrollbar?: boolean;\n /** Current mode - can be 'edit', 'focusEdit', 'comparison' */\n mode?: string | null;\n /** Display ID to show in banner */\n displayId?: string | null;\n /** Whether the main sidebar is expanded */\n isMainSideBarOpen?: boolean;\n};\n\n/**\n * CardMain component for main content areas with optional edit/comparison banners\n *\n * @example\n * ```tsx\n * <CardMain title=\"Page Title\" mode=\"edit\" displayId=\"DOC-001\">\n * <div>Page content</div>\n * </CardMain>\n * ```\n */\nexport const CardMain: FC<CardMainProps> = ({\n title,\n children,\n noPadding,\n className,\n noBanner,\n noScrollbar,\n mode,\n displayId,\n}) => {\n const currentMode = mode === MODES.EDIT || mode === MODES.FOCUS_EDIT ? 'edit' : mode === MODES.COMPARISON ? 'compare' : null;\n\n const isBannerVisible = useMemo(() => {\n return (currentMode === 'edit' && displayId && !noBanner) || currentMode === 'compare';\n }, [currentMode, displayId, noBanner]);\n\n\n useScrollToTop()\n return (\n <>\n {!!title ? <Helmet title={title} /> : null}\n <div\n style={{\n marginLeft: 'var(--sidebar-ml, 0px)'\n }}\n className={cn(\n ` relative h-[calc(100vh-56px)] overflow-y-auto flex flex-col bg-primary-800 dark:bg-black-800`,\n `ease-in-out duration-${OPEN_DURATION_MS}`,\n className,\n )}\n >\n {currentMode === 'edit' && displayId && !noBanner ? (\n <Banner status='warning'>{`You're currently editing ${displayId || ''}`}</Banner>\n ) : currentMode === 'compare' ? (\n <Banner status='success'>{`You are now in Comparison Mode`}</Banner>\n ) : null}\n\n <div\n className={cn(\n `flex-1 overflow-y-auto overflow-x-hidden bg-gray-50 dark:bg-black-700 ${noScrollbar ? 'hide-scrollbar' : ''}`,\n noPadding ? 'p-0' : 'p-base',\n isBannerVisible ? 'rounded-tl-none' : '!rounded-tl-xl',\n )}\n id='app-body-container'\n >\n {children}\n </div>\n </div>\n </>\n );\n};\n\nCardMain.displayName = 'CardMain';\n\n\n\n"],"names":["CardMain","title","children","noPadding","className","noBanner","noScrollbar","mode","displayId","currentMode","MODES","isBannerVisible","useMemo","useScrollToTop","jsxs","Fragment","jsx","Helmet","cn","OPEN_DURATION_MS","Banner"],"mappings":";;;;;;;AAkCO,MAAMA,IAA8B,CAAC;AAAA,EAC1C,OAAAC;AAAA,EACA,UAAAC;AAAA,EACA,WAAAC;AAAA,EACA,WAAAC;AAAA,EACA,UAAAC;AAAA,EACA,aAAAC;AAAA,EACA,MAAAC;AAAA,EACA,WAAAC;AACF,MAAM;AACJ,QAAMC,IAAcF,MAASG,EAAM,QAAQH,MAASG,EAAM,aAAa,SAASH,MAASG,EAAM,aAAa,YAAY,MAElHC,IAAkBC,EAAQ,MACtBH,MAAgB,UAAUD,KAAa,CAACH,KAAaI,MAAgB,WAC5E,CAACA,GAAaD,GAAWH,CAAQ,CAAC;AAGrC,SAAAQ,EAAA,GAEE,gBAAAC,EAAAC,GAAA,EACG,UAAA;AAAA,IAAEd,IAAQ,gBAAAe,EAACC,GAAA,EAAO,OAAAhB,GAAc,IAAK;AAAA,IACtC,gBAAAa;AAAA,MAAC;AAAA,MAAA;AAAA,QACD,OAAO;AAAA,UACL,YAAY;AAAA,QAAA;AAAA,QAEZ,WAAWI;AAAA,UACT;AAAA,UACA,wBAAwBC,CAAgB;AAAA,UACxCf;AAAA,QAAA;AAAA,QAGD,UAAA;AAAA,UAAAK,MAAgB,UAAUD,KAAa,CAACH,sBACtCe,GAAA,EAAO,QAAO,WAAW,UAAA,4BAA4BZ,KAAa,EAAE,GAAA,CAAG,IACtEC,MAAgB,YAClB,gBAAAO,EAACI,KAAO,QAAO,WAAW,4CAAiC,IACzD;AAAA,UAEJ,gBAAAJ;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,WAAWE;AAAA,gBACT,yEAAyEZ,IAAc,mBAAmB,EAAE;AAAA,gBAC5GH,IAAY,QAAQ;AAAA,gBACpBQ,IAAkB,oBAAoB;AAAA,cAAA;AAAA,cAExC,IAAG;AAAA,cAEF,UAAAT;AAAA,YAAA;AAAA,UAAA;AAAA,QACH;AAAA,MAAA;AAAA,IAAA;AAAA,EACF,GACF;AAEJ;AAEAF,EAAS,cAAc;"}
1
+ {"version":3,"file":"CardMain.es.js","sources":["../../../../src/components/cards/card-main/CardMain.tsx"],"sourcesContent":["import type { FC, ReactNode } from 'react';\nimport { useMemo } from 'react';\nimport cn from 'classnames';\nimport { Banner } from '../../data-display/banner/Banner';\nimport { MODES, OPEN_DURATION_MS } from '../../../constants/layout';\nimport { useScrollToTop } from '../../../hooks/useScrollToTop';\nimport { Helmet } from '../../layout';\n\nexport type CardMainProps = {\n title?: string;\n children: ReactNode;\n noPadding?: boolean;\n className?: string;\n noHeight?: boolean;\n noBanner?: boolean;\n noScrollbar?: boolean;\n /** Current mode - can be 'edit', 'focusEdit', 'comparison' */\n mode?: string | null;\n /** Display ID to show in banner */\n displayId?: string | null;\n /** Whether the main sidebar is expanded */\n isMainSideBarOpen?: boolean;\n};\n\n/**\n * CardMain component for main content areas with optional edit/comparison banners\n *\n * @example\n * ```tsx\n * <CardMain title=\"Page Title\" mode=\"edit\" displayId=\"DOC-001\">\n * <div>Page content</div>\n * </CardMain>\n * ```\n */\nexport const CardMain: FC<CardMainProps> = ({\n title,\n children,\n noPadding,\n className,\n noBanner,\n noScrollbar,\n mode,\n displayId,\n}) => {\n const currentMode = mode === MODES.EDIT || mode === MODES.FOCUS_EDIT ? 'edit' : mode === MODES.COMPARISON ? 'compare' : null;\n\n const isBannerVisible = useMemo(() => {\n return (currentMode === 'edit' && displayId && !noBanner) || currentMode === 'compare';\n }, [currentMode, displayId, noBanner]);\n\n\n useScrollToTop()\n return (\n <>\n {!!title ? <Helmet title={title} /> : null}\n <div\n style={{\n marginLeft: 'var(--sidebar-ml, 0px)'\n }}\n className={cn(\n ` relative h-[calc(100vh-56px)] overflow-y-auto flex flex-col bg-primary-800 dark:bg-black-800`,\n // Scope the transition to margin-left (the sidebar push). Without an explicit\n // transition-property, `duration-*` falls back to CSS's default `all`, which\n // also animates background-color over 500ms — that made the rounded-tl corner\n // flash a mismatched triangle on theme toggle. The background now flips with\n // the `dark` class and is handled by the view transition.\n `transition-[margin-left] ease-in-out duration-${OPEN_DURATION_MS}`,\n className,\n )}\n >\n {currentMode === 'edit' && displayId && !noBanner ? (\n <Banner status='warning'>{`You're currently editing ${displayId || ''}`}</Banner>\n ) : currentMode === 'compare' ? (\n <Banner status='success'>{`You are now in Comparison Mode`}</Banner>\n ) : null}\n\n <div\n className={cn(\n `flex-1 overflow-y-auto overflow-x-hidden bg-gray-50 dark:bg-black-700 ${noScrollbar ? 'hide-scrollbar' : ''}`,\n noPadding ? 'p-0' : 'p-base',\n isBannerVisible ? 'rounded-tl-none' : '!rounded-tl-xl',\n )}\n id='app-body-container'\n >\n {children}\n </div>\n </div>\n </>\n );\n};\n\nCardMain.displayName = 'CardMain';\n\n\n\n"],"names":["CardMain","title","children","noPadding","className","noBanner","noScrollbar","mode","displayId","currentMode","MODES","isBannerVisible","useMemo","useScrollToTop","jsxs","Fragment","jsx","Helmet","cn","OPEN_DURATION_MS","Banner"],"mappings":";;;;;;;AAkCO,MAAMA,IAA8B,CAAC;AAAA,EAC1C,OAAAC;AAAA,EACA,UAAAC;AAAA,EACA,WAAAC;AAAA,EACA,WAAAC;AAAA,EACA,UAAAC;AAAA,EACA,aAAAC;AAAA,EACA,MAAAC;AAAA,EACA,WAAAC;AACF,MAAM;AACJ,QAAMC,IAAcF,MAASG,EAAM,QAAQH,MAASG,EAAM,aAAa,SAASH,MAASG,EAAM,aAAa,YAAY,MAElHC,IAAkBC,EAAQ,MACtBH,MAAgB,UAAUD,KAAa,CAACH,KAAaI,MAAgB,WAC5E,CAACA,GAAaD,GAAWH,CAAQ,CAAC;AAGrC,SAAAQ,EAAA,GAEE,gBAAAC,EAAAC,GAAA,EACG,UAAA;AAAA,IAAEd,IAAQ,gBAAAe,EAACC,GAAA,EAAO,OAAAhB,GAAc,IAAK;AAAA,IACtC,gBAAAa;AAAA,MAAC;AAAA,MAAA;AAAA,QACD,OAAO;AAAA,UACL,YAAY;AAAA,QAAA;AAAA,QAEZ,WAAWI;AAAA,UACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,UAMA,iDAAiDC,CAAgB;AAAA,UACjEf;AAAA,QAAA;AAAA,QAGD,UAAA;AAAA,UAAAK,MAAgB,UAAUD,KAAa,CAACH,sBACtCe,GAAA,EAAO,QAAO,WAAW,UAAA,4BAA4BZ,KAAa,EAAE,GAAA,CAAG,IACtEC,MAAgB,YAClB,gBAAAO,EAACI,KAAO,QAAO,WAAW,4CAAiC,IACzD;AAAA,UAEJ,gBAAAJ;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,WAAWE;AAAA,gBACT,yEAAyEZ,IAAc,mBAAmB,EAAE;AAAA,gBAC5GH,IAAY,QAAQ;AAAA,gBACpBQ,IAAkB,oBAAoB;AAAA,cAAA;AAAA,cAExC,IAAG;AAAA,cAEF,UAAAT;AAAA,YAAA;AAAA,UAAA;AAAA,QACH;AAAA,MAAA;AAAA,IAAA;AAAA,EACF,GACF;AAEJ;AAEAF,EAAS,cAAc;"}
@@ -3,5 +3,5 @@
3
3
  `),e=e.split(`
4
4
  `).map(n=>n.trimEnd()).join(`
5
5
  `),e=e.replace(/\n+$/,"")+`
6
- `),navigator?.clipboard?.writeText(e).then(()=>{}).catch(n=>{const r=n;A.toast.error(r?.message||L.systemMessages.copyFailure("Python Code"),{toastId:L.systemMessages.copyFailure("Python Code")})})}catch(e){const n=e;A.toast.error(n?.message||L.systemMessages.copyFailure("Python Code"),{toastId:L.systemMessages.copyFailure("Python Code")})}else if(i==="json")try{const e=JSON.parse(o),n=JSON.stringify(e,null,4);navigator?.clipboard?.writeText(n)}catch(e){const n=e;A.toast.error(n?.message||L.systemMessages.copyFailure("JSON Code"),{toastId:L.systemMessages.copyFailure("JSON Code")})}else navigator?.clipboard?.writeText(o)},ee=e=>e==="python"?{type:"text/x-python",extension:"py"}:e==="json"?{type:"application/json",extension:"json"}:{type:"text/plain",extension:"txt"},te=(e,n)=>e.replace(/[<>:"/\\|?*\x00-\x1f]/g,"_").replace(/\.{2,}/g,".").replace(/^\.+|\.+$/g,"").trim()||n,Ie=()=>{try{const e=new Blob([o],{type:ee(i)?.type}),n=URL.createObjectURL(e),r=document.createElement("a");r.href=n;const c=ee(i)?.extension||"txt",a=te(c,"txt");r.download=te(`code_${Date.now()}.${a}`,`code_${Date.now()}.${a}`),document.body.appendChild(r),r.click(),document.body.removeChild(r),URL.revokeObjectURL(n)}catch(e){const n=e;A.toast.error(n?.message||L.systemMessages.copyFailure("Code download"),{toastId:L.systemMessages.copyFailure("Code download")})}};return t.jsx(oe.FullScreen,{handle:S,className:"h-full",children:t.jsxs("div",{className:qe.cn("relative border border-neutral-200 dark:border-neutral-700 rounded-lg h-full overflow-hidden",he),id:"code-editor-container-with-json-grid",children:[t.jsxs("div",{className:B("px-3 py-2 flex items-center bg-neutral-50 dark:bg-neutral-800","border-b border-neutral-200 dark:border-neutral-700",Y?"justify-between":"justify-end"),children:[Y&&J?t.jsx(Je.Toggle,{isChecked:N==="Grid",onChange:e=>Me(e?"Grid":"JSON"),statusText:"",hideStatus:!0,withIcon:!0,tooltip:N==="JSON"?"Grid view":"Code view",icon:{checkedIcon:t.jsx(re.GridOnIcon,{fontSize:6,className:"cursor-pointer !block text-primary-600 dark:text-neutral-300"}),uncheckedIcon:t.jsx(re.CodeIcon,{fontSize:10,className:"cursor-pointer !block text-neutral-700 dark:text-neutral-400"})}}):null,t.jsxs("div",{className:"flex items-center gap-0.5",children:[xe?.({editor:F.current,value:o,onChange:R,language:i,isEditMode:O,activeTab:N}),N==="Grid"&&O&&J&&t.jsx("span",{className:"flex items-center justify-center border-r border-neutral-200 dark:border-neutral-700 mr-1.5 pr-1.5",children:t.jsx(k,{title:"Add key",children:t.jsx("button",{type:"button",id:"btn-code-editor-json-grid-up",onClick:()=>X(!0),className:B("p-0.5 rounded-md flex items-center justify-center","hover:bg-primary-100 hover:dark:bg-neutral-800 text-primary-600 dark:text-neutral-100"),children:t.jsx(Ae,{fontSize:16})})})}),N==="Grid"?t.jsxs(t.Fragment,{children:[t.jsx(k,{title:"Collapse all",children:t.jsx("button",{type:"button",id:"btn-code-editor-json-grid-up",onClick:()=>P(!1),className:z,children:t.jsx(_e,{fontSize:16})})}),t.jsx(k,{title:"Expand all",children:t.jsx("button",{type:"button",id:"btn-code-editor-json-grid-down",onClick:()=>P(!0),className:z,children:t.jsx($e,{fontSize:16})})})]}):null,N==="JSON"&&J?t.jsx(k,{title:"Format",children:t.jsx("button",{type:"button",id:"btn-code-editor-format-code",onClick:Z,className:z,children:t.jsx(Ke,{fontSize:14})})}):null,ie&&N==="JSON"&&J?t.jsx(k,{title:q==="vs"?"Dark mode":"Light mode",children:t.jsx("button",{type:"button",id:"btn-code-editor-with-theme",onClick:()=>je(q==="vs"?"vs-dark":"vs"),className:z,children:q==="vs"?t.jsx(Ve,{fontSize:14}):t.jsx(Ge,{fontSize:14})})}):null,(i==="python"||i==="json")&&ce?t.jsx(k,{title:"Copy",children:t.jsx("button",{type:"button",id:"btn-code-editor-copy-code",onClick:Ee,className:z,children:t.jsx(Be,{fontSize:14})})}):null,(i==="python"||i==="json")&&le?t.jsx(k,{title:"Download",children:t.jsx("button",{type:"button",id:"btn-code-editor-download-code",onClick:Ie,className:z,children:t.jsx(De,{fontSize:14})})}):null,se?t.jsx(k,{title:"Fullscreen",children:t.jsx("button",{onClick:ke,type:"button",id:"btn-code-editor-fullscreen",className:z,children:t.jsx(Pe,{fontSize:14})})}):null]})]}),N==="Grid"&&i==="json"?t.jsx("div",{children:t.jsx(He.JsonGridViewer,{isFullScreen:S?.active,allExpanded:ve,toggleAll:()=>P(e=>!e),isEditMode:!!O,isDarkMode:ye==="dark",style:{height:S?.active?"100vh":$},value:o,onChange:R,setIsAddKeyModalOpen:X,isAddKeyModalOpen:Le})}):t.jsx(Re.default,{height:S?.active?"100vh":$,language:i,value:o,onChange:Fe,theme:q,onMount:Se,options:{fontSize:16,folding:!0,fontFamily:"Menlo, Monaco, 'Courier New', monospace",fontLigatures:!0,readOnly:!O}})]})})};exports.CodeEditor=Ue;
6
+ `),navigator?.clipboard?.writeText(e).then(()=>{}).catch(n=>{const r=n;A.toast.error(r?.message||L.systemMessages.copyFailure("Python Code"),{toastId:L.systemMessages.copyFailure("Python Code")})})}catch(e){const n=e;A.toast.error(n?.message||L.systemMessages.copyFailure("Python Code"),{toastId:L.systemMessages.copyFailure("Python Code")})}else if(i==="json")try{const e=JSON.parse(o),n=JSON.stringify(e,null,4);navigator?.clipboard?.writeText(n)}catch(e){const n=e;A.toast.error(n?.message||L.systemMessages.copyFailure("JSON Code"),{toastId:L.systemMessages.copyFailure("JSON Code")})}else navigator?.clipboard?.writeText(o)},ee=e=>e==="python"?{type:"text/x-python",extension:"py"}:e==="json"?{type:"application/json",extension:"json"}:{type:"text/plain",extension:"txt"},te=(e,n)=>e.replace(/[<>:"/\\|?*\x00-\x1f]/g,"_").replace(/\.{2,}/g,".").replace(/^\.+|\.+$/g,"").trim()||n,Ie=()=>{try{const e=new Blob([o],{type:ee(i)?.type}),n=URL.createObjectURL(e),r=document.createElement("a");r.href=n;const c=ee(i)?.extension||"txt",a=te(c,"txt");r.download=te(`code_${Date.now()}.${a}`,`code_${Date.now()}.${a}`),document.body.appendChild(r),r.click(),document.body.removeChild(r),URL.revokeObjectURL(n)}catch(e){const n=e;A.toast.error(n?.message||L.systemMessages.copyFailure("Code download"),{toastId:L.systemMessages.copyFailure("Code download")})}};return t.jsx(oe.FullScreen,{handle:S,className:"h-full",children:t.jsxs("div",{className:qe.cn("relative border border-neutral-200 dark:border-neutral-700 rounded-lg h-full overflow-hidden",he),id:"code-editor-container-with-json-grid",children:[t.jsxs("div",{className:B("px-3 py-2 flex items-center bg-neutral-50 dark:bg-neutral-800","border-b border-neutral-200 dark:border-neutral-700",Y?"justify-between":"justify-end"),children:[Y&&J?t.jsx(Je.Toggle,{isChecked:N==="Grid",onChange:e=>Me(e?"Grid":"JSON"),statusText:"",hideStatus:!0,withIcon:!0,tooltip:N==="JSON"?"Grid view":"Code view",icon:{checkedIcon:t.jsx(re.GridOnIcon,{className:"cursor-pointer !block text-primary-600 dark:text-neutral-300 h-2xs w-2xs lg:h-xs lg:w-xs"}),uncheckedIcon:t.jsx(re.CodeIcon,{className:"cursor-pointer !block text-neutral-700 dark:text-neutral-400 h-2xs w-2xs lg:h-xs lg:w-xs"})}}):null,t.jsxs("div",{className:"flex items-center gap-0.5",children:[xe?.({editor:F.current,value:o,onChange:R,language:i,isEditMode:O,activeTab:N}),N==="Grid"&&O&&J&&t.jsx("span",{className:"flex items-center justify-center border-r border-neutral-200 dark:border-neutral-700 mr-1.5 pr-1.5",children:t.jsx(k,{title:"Add key",children:t.jsx("button",{type:"button",id:"btn-code-editor-json-grid-up",onClick:()=>X(!0),className:B("p-0.5 rounded-md flex items-center justify-center","hover:bg-primary-100 hover:dark:bg-neutral-800 text-primary-600 dark:text-neutral-100"),children:t.jsx(Ae,{fontSize:16})})})}),N==="Grid"?t.jsxs(t.Fragment,{children:[t.jsx(k,{title:"Collapse all",children:t.jsx("button",{type:"button",id:"btn-code-editor-json-grid-up",onClick:()=>P(!1),className:z,children:t.jsx(_e,{fontSize:16})})}),t.jsx(k,{title:"Expand all",children:t.jsx("button",{type:"button",id:"btn-code-editor-json-grid-down",onClick:()=>P(!0),className:z,children:t.jsx($e,{fontSize:16})})})]}):null,N==="JSON"&&J?t.jsx(k,{title:"Format",children:t.jsx("button",{type:"button",id:"btn-code-editor-format-code",onClick:Z,className:z,children:t.jsx(Ke,{fontSize:14})})}):null,ie&&N==="JSON"&&J?t.jsx(k,{title:q==="vs"?"Dark mode":"Light mode",children:t.jsx("button",{type:"button",id:"btn-code-editor-with-theme",onClick:()=>je(q==="vs"?"vs-dark":"vs"),className:z,children:q==="vs"?t.jsx(Ve,{fontSize:14}):t.jsx(Ge,{fontSize:14})})}):null,(i==="python"||i==="json")&&ce?t.jsx(k,{title:"Copy",children:t.jsx("button",{type:"button",id:"btn-code-editor-copy-code",onClick:Ee,className:z,children:t.jsx(Be,{fontSize:14})})}):null,(i==="python"||i==="json")&&le?t.jsx(k,{title:"Download",children:t.jsx("button",{type:"button",id:"btn-code-editor-download-code",onClick:Ie,className:z,children:t.jsx(De,{fontSize:14})})}):null,se?t.jsx(k,{title:"Fullscreen",children:t.jsx("button",{onClick:ke,type:"button",id:"btn-code-editor-fullscreen",className:z,children:t.jsx(Pe,{fontSize:14})})}):null]})]}),N==="Grid"&&i==="json"?t.jsx("div",{children:t.jsx(He.JsonGridViewer,{isFullScreen:S?.active,allExpanded:ve,toggleAll:()=>P(e=>!e),isEditMode:!!O,isDarkMode:ye==="dark",style:{height:S?.active?"100vh":$},value:o,onChange:R,setIsAddKeyModalOpen:X,isAddKeyModalOpen:Le})}):t.jsx(Re.default,{height:S?.active?"100vh":$,language:i,value:o,onChange:Fe,theme:q,onMount:Se,options:{fontSize:16,folding:!0,fontFamily:"Menlo, Monaco, 'Courier New', monospace",fontLigatures:!0,readOnly:!O}})]})})};exports.CodeEditor=Ue;
7
7
  //# sourceMappingURL=CodeEditor.cjs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"CodeEditor.cjs.js","sources":["../../../../src/components/data-display/code-editor/CodeEditor.tsx"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport Editor, { type OnMount } from '@monaco-editor/react';\nimport classNames from 'classnames';\nimport { type FC, useCallback, useEffect, useRef, useState } from 'react';\nimport { FullScreen, useFullScreenHandle } from 'react-full-screen';\nimport { toast } from 'react-toastify';\nimport { useMonaco } from '../../../hooks/useMonaco';\nimport { usePythonSyntax } from '../../../hooks/usePythonSyntax';\nimport { type CodeEditorProps } from '../../../types';\nimport { systemMessages } from '../../../utils/messageConstants';\nimport { JsonGrid } from './JsonGrid';\nimport Tooltip from '../../tooltip/Tooltip';\nimport { Toggle } from '../../forms/toggle/Toggle';\nimport { cn } from '../../../lib/utils';\nimport { CodeIcon, GridOnIcon } from '../../icon';\n\n// Icon class styling (matching web portal)\nconst iconClass = classNames(\n 'text-neutral-600 cursor-pointer hover:text-neutral-800',\n 'dark:text-neutral-300 dark:hover:text-neutral-50'\n);\n\n// Material Icons converted to SVG components (matching web portal icons)\nconst AddIcon = ({ fontSize }: { fontSize: number }) => (\n <svg width={fontSize} height={fontSize} viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z\" />\n </svg>\n);\n\nconst ContentPasteRoundedIcon = ({ fontSize }: { fontSize: number }) => (\n <svg width={fontSize} height={fontSize} viewBox=\"0 0 24 24\" fill=\"currentColor\" className={iconClass}>\n <path d=\"M19 2h-4.18C14.4.84 13.3 0 12 0S9.6.84 9.18 2H5c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-7 0c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm7 18H5V4h2v3h10V4h2v16z\" />\n </svg>\n);\n\nconst DarkModeOutlinedIcon = ({ fontSize }: { fontSize: number }) => (\n <svg width={fontSize} height={fontSize} viewBox=\"0 0 24 24\" fill=\"currentColor\" className={iconClass}>\n <path d=\"M9.5 2c-1.82 0-3.53.5-5 1.35 2.99 1.73 5 4.95 5 8.65s-2.01 6.92-5 8.65c1.47.85 3.18 1.35 5 1.35 5.52 0 10-4.48 10-10S15.02 2 9.5 2z\" />\n </svg>\n);\n\nconst FileDownloadRoundedIcon = ({ fontSize }: { fontSize: number }) => (\n <svg width={fontSize} height={fontSize} viewBox=\"0 0 24 24\" fill=\"currentColor\" className={iconClass}>\n <path d=\"M18 15v3H6v-3H4v3c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2v-3h-2zm-1-4-5 5-5-5h3V4h4v7h3z\" />\n </svg>\n);\n\nconst FullscreenRoundedIcon = ({ fontSize }: { fontSize: number }) => (\n <svg width={fontSize} height={fontSize} viewBox=\"0 0 24 24\" fill=\"currentColor\" className={iconClass}>\n <path d=\"M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z\" />\n </svg>\n);\n\nconst KeyboardDoubleArrowDownIcon = ({ fontSize }: { fontSize: number }) => (\n <svg width={fontSize} height={fontSize} viewBox=\"0 0 24 24\" fill=\"currentColor\" className={iconClass}>\n <path d=\"M18 6.41 16.59 5 12 9.58 7.41 5 6 6.41l6 6z\" />\n <path d=\"m18 13-1.41-1.41L12 16.17l-4.59-4.58L6 13l6 6z\" />\n </svg>\n);\n\nconst KeyboardDoubleArrowUpIcon = ({ fontSize }: { fontSize: number }) => (\n <svg width={fontSize} height={fontSize} viewBox=\"0 0 24 24\" fill=\"currentColor\" className={iconClass}>\n <path d=\"M6 17.59 7.41 19 12 14.42 16.59 19 18 17.59l-6-6z\" />\n <path d=\"m6 11 1.41 1.41L12 7.83l4.59 4.58L18 11l-6-6z\" />\n </svg>\n);\n\nconst LightModeOutlinedIcon = ({ fontSize }: { fontSize: number }) => (\n <svg width={fontSize} height={fontSize} viewBox=\"0 0 24 24\" fill=\"currentColor\" className={iconClass}>\n <path d=\"M12 9c1.65 0 3 1.35 3 3s-1.35 3-3 3-3-1.35-3-3 1.35-3 3-3m0-2c-2.76 0-5 2.24-5 5s2.24 5 5 5 5-2.24 5-5-2.24-5-5-5zM2 13h2c.55 0 1-.45 1-1s-.45-1-1-1H2c-.55 0-1 .45-1 1s.45 1 1 1zm18 0h2c.55 0 1-.45 1-1s-.45-1-1-1h-2c-.55 0-1 .45-1 1s.45 1 1 1zM11 2v2c0 .55.45 1 1 1s1-.45 1-1V2c0-.55-.45-1-1-1s-1 .45-1 1zm0 18v2c0 .55.45 1 1 1s1-.45 1-1v-2c0-.55-.45-1-1-1s-1 .45-1 1zM5.99 4.58c-.39-.39-1.03-.39-1.41 0-.39.39-.39 1.03 0 1.41l1.06 1.06c.39.39 1.03.39 1.41 0s.39-1.03 0-1.41L5.99 4.58zm12.37 12.37c-.39-.39-1.03-.39-1.41 0-.39.39-.39 1.03 0 1.41l1.06 1.06c.39.39 1.03.39 1.41 0 .39-.39.39-1.03 0-1.41l-1.06-1.06zm1.06-10.96c.39-.39.39-1.03 0-1.41-.39-.39-1.03-.39-1.41 0l-1.06 1.06c-.39.39-.39 1.03 0 1.41s1.03.39 1.41 0l1.06-1.06zM7.05 18.36c.39-.39.39-1.03 0-1.41-.39-.39-1.03-.39-1.41 0l-1.06 1.06c-.39.39-.39 1.03 0 1.41s1.03.39 1.41 0l1.06-1.06z\" />\n </svg>\n);\n\nconst SubjectOutlinedIcon = ({ fontSize }: { fontSize: number }) => (\n <svg width={fontSize} height={fontSize} viewBox=\"0 0 24 24\" fill=\"currentColor\" className={iconClass}>\n <path d=\"M14 17H4v2h10v-2zm6-8H4v2h16V9zM4 15h16v-2H4v2zM4 5v2h16V5H4z\" />\n </svg>\n);\n\ntype TTabKey = 'JSON' | 'Grid';\n\nexport const CodeEditor: FC<CodeEditorProps> = ({\n value,\n onChange = () => false,\n withFullScreen = true,\n withTheme = true,\n isEditMode = false,\n height = \"55vh\",\n language = \"json\",\n monacoEditor,\n isShowCopy = true,\n isShowDownload = true,\n setIsDisableSave,\n withJsonGrid = true,\n editorTheme: externalEditorTheme,\n setEditorTheme: externalSetEditorTheme,\n theme: externalTheme,\n className,\n enableAutoFormatting = true,\n renderToolbarActions,\n onBlockClick,\n focusBlock,\n focusBlockTopLevelOnly = false,\n}) => {\n const editorRef = useRef<any>(null);\n\n // Internal theme state (used when not provided by parent)\n const [internalEditorTheme, setInternalEditorTheme] = useState<\n \"vs\" | \"vs-dark\"\n >(\"vs\");\n const [internalTheme, setInternalTheme] = useState<\"light\" | \"dark\">(\"light\");\n\n // Use external theme if provided, otherwise use internal\n const editorTheme = externalEditorTheme ?? internalEditorTheme;\n const theme = externalTheme ?? internalTheme;\n const setEditorTheme =\n externalSetEditorTheme ??\n ((newTheme: \"vs\" | \"vs-dark\") => {\n setInternalEditorTheme(newTheme);\n setInternalTheme(newTheme === \"vs-dark\" ? \"dark\" : \"light\");\n });\n\n const [allExpanded, setAllExpanded] = useState<boolean>(false);\n const [currentEditorModel, setCurrentEditorModel] = useState<any>(null);\n const monacoInstance = useMonaco();\n\n // Use provided monacoEditor prop or fall back to our managed instance\n const activeMonacoEditor = monacoEditor || monacoInstance;\n\n const {\n handleFormatCode: handleFormatPythonCode,\n pythonError,\n pythonLoading,\n } = usePythonSyntax({\n code: value,\n setCode: onChange,\n currentEditorModel,\n monacoEditor: activeMonacoEditor,\n enable: isEditMode === true && language === \"python\",\n });\n\n const fullScreenHandle = useFullScreenHandle();\n const [activeTab, setActiveTab] = useState<TTabKey>(\"JSON\");\n const [isAddKeyModalOpen, setIsAddKeyModalOpen] = useState(false);\n const isLanguageJson = language === \"json\";\n\n const toggleFocusMode = () => {\n if (fullScreenHandle?.active) {\n fullScreenHandle.exit();\n } else {\n fullScreenHandle.enter();\n }\n };\n\n const onBlockClickRef = useRef(onBlockClick);\n onBlockClickRef.current = onBlockClick;\n\n const detectBlock = useCallback(\n async (editor: any, lineNumber: number, column: number) => {\n if (!onBlockClickRef.current) return;\n\n const model = editor.getModel();\n if (!model) return;\n\n const getTextForRange = (startLine: number, endLine: number) =>\n model.getValueInRange({\n startLineNumber: startLine,\n startColumn: 1,\n endLineNumber: endLine,\n endColumn: model.getLineMaxColumn(endLine),\n });\n\n const emitBlock = (\n startLine: number,\n endLine: number,\n text: string,\n kind?: string,\n parentBlock?: { startLine: number; endLine: number; text: string; kind?: string }\n ) => {\n onBlockClickRef.current!({\n startLine,\n endLine,\n text,\n kind,\n cursorLine: lineNumber,\n cursorColumn: column,\n parentBlock,\n });\n };\n\n try {\n const foldingContrib = editor.getContribution(\n \"editor.contrib.folding\"\n );\n if (foldingContrib) {\n const foldingModel = await (foldingContrib as any).getFoldingModel();\n if (foldingModel?.regions) {\n const regions = foldingModel.regions;\n const totalLines = model.getLineCount();\n\n // Collect all folding ranges that contain the cursor line\n const containingRanges: {\n start: number;\n end: number;\n size: number;\n kind?: string;\n }[] = [];\n\n for (let i = 0; i < regions.length; i++) {\n const start = regions.getStartLineNumber(i);\n const foldEnd = regions.getEndLineNumber(i);\n const end = Math.min(foldEnd + 1, totalLines);\n const size = end - start;\n\n if (lineNumber >= start && lineNumber <= end) {\n const rawKind = regions.getType(i);\n const kind =\n rawKind === 1\n ? \"comment\"\n : rawKind === 2\n ? \"imports\"\n : rawKind === 3\n ? \"region\"\n : undefined;\n containingRanges.push({ start, end, size, kind });\n }\n }\n\n if (containingRanges.length > 0) {\n // Sort by size: smallest first (innermost) → largest last (outermost)\n containingRanges.sort((a, b) => a.size - b.size);\n\n const innermost = containingRanges[0];\n const text = getTextForRange(innermost.start, innermost.end);\n\n // Find the outermost block that isn't the root document range.\n // Walk from largest to smallest, skip any range that starts at\n // line 1 and ends at the last line (that's the root `{}`).\n let outermost: typeof containingRanges[number] | undefined;\n for (let j = containingRanges.length - 1; j > 0; j--) {\n const r = containingRanges[j];\n const isRoot = r.start <= 1 && r.end >= totalLines;\n if (!isRoot) {\n outermost = r;\n break;\n }\n }\n\n const parentBlock =\n outermost && outermost !== innermost\n ? {\n startLine: outermost.start,\n endLine: outermost.end,\n text: getTextForRange(outermost.start, outermost.end),\n kind: outermost.kind,\n }\n : undefined;\n\n emitBlock(innermost.start, innermost.end, text, innermost.kind, parentBlock);\n return;\n }\n }\n }\n\n // Bracket matching fallback — no parent detection available\n const position = { lineNumber, column };\n const brackets = model.bracketPairs?.findEnclosingBrackets?.(position);\n\n if (brackets && brackets.length === 2) {\n const [openRange, closeRange] = brackets;\n const startLine = openRange.startLineNumber;\n const endLine = closeRange.endLineNumber;\n const text = getTextForRange(startLine, endLine);\n emitBlock(startLine, endLine, text);\n return;\n }\n\n // Full document fallback\n const totalLines = model.getLineCount();\n const text = model.getValue();\n emitBlock(1, totalLines, text);\n } catch {\n // Editor not ready — ignore silently\n }\n },\n []\n );\n\n // Navigate to a block when focusBlock changes\n useEffect(() => {\n if (!focusBlock || !editorRef.current) return;\n\n const editor = editorRef.current;\n const model = editor.getModel();\n if (!model) return;\n\n const allMatches = model.findMatches(\n focusBlock,\n true,\n false,\n true,\n null,\n false\n );\n\n if (allMatches.length === 0) return;\n\n let match = allMatches[0];\n\n if (focusBlockTopLevelOnly && allMatches.length > 1) {\n // A top-level key in formatted JSON has minimal leading whitespace\n // (one indent level). Find the match closest to column 1.\n let bestCol = Infinity;\n for (const m of allMatches) {\n const lineContent = model.getLineContent(m.range.startLineNumber);\n const leadingSpaces = lineContent.length - lineContent.trimStart().length;\n if (leadingSpaces < bestCol) {\n bestCol = leadingSpaces;\n match = m;\n }\n }\n }\n\n const matchLine = match.range.startLineNumber;\n const matchCol = match.range.startColumn;\n\n // Move cursor to the match with smooth scroll\n editor.setPosition({ lineNumber: matchLine, column: matchCol });\n editor.revealLineInCenter(matchLine, 1);\n\n // Find the enclosing block and highlight it\n const findAndHighlightBlock = async () => {\n try {\n // Try folding ranges first\n const foldingContrib = editor.getContribution(\n \"editor.contrib.folding\"\n );\n if (foldingContrib) {\n const foldingModel = await (foldingContrib as any).getFoldingModel();\n if (foldingModel?.regions) {\n const regions = foldingModel.regions;\n let bestStart = -1;\n let bestEnd = -1;\n let bestSize = Infinity;\n\n for (let i = 0; i < regions.length; i++) {\n const start = regions.getStartLineNumber(i);\n const foldEnd = regions.getEndLineNumber(i);\n const end = Math.min(foldEnd + 1, model.getLineCount());\n const size = end - start;\n\n if (\n matchLine >= start &&\n matchLine <= end &&\n size < bestSize\n ) {\n bestStart = start;\n bestEnd = end;\n bestSize = size;\n }\n }\n\n if (bestStart !== -1) {\n editor.setSelection({\n startLineNumber: bestStart,\n startColumn: 1,\n endLineNumber: bestEnd,\n endColumn: model.getLineMaxColumn(bestEnd),\n });\n editor.revealRangeInCenter({\n startLineNumber: bestStart,\n startColumn: 1,\n endLineNumber: bestEnd,\n endColumn: model.getLineMaxColumn(bestEnd),\n }, 1);\n return;\n }\n }\n }\n\n // Fall back to bracket matching\n const position = { lineNumber: matchLine, column: matchCol };\n const brackets =\n model.bracketPairs?.findEnclosingBrackets?.(position);\n\n if (brackets && brackets.length === 2) {\n const [openRange, closeRange] = brackets;\n editor.setSelection({\n startLineNumber: openRange.startLineNumber,\n startColumn: 1,\n endLineNumber: closeRange.endLineNumber,\n endColumn: model.getLineMaxColumn(closeRange.endLineNumber),\n });\n editor.revealRangeInCenter({\n startLineNumber: openRange.startLineNumber,\n startColumn: 1,\n endLineNumber: closeRange.endLineNumber,\n endColumn: model.getLineMaxColumn(closeRange.endLineNumber),\n }, 1);\n return;\n }\n\n // Last resort — just highlight the matched text\n editor.setSelection(match.range);\n } catch {\n // Folding model not ready — just highlight the match\n editor.setSelection(match.range);\n }\n };\n\n // Small delay to let folding model compute after content may have changed\n requestAnimationFrame(() => {\n findAndHighlightBlock();\n });\n }, [focusBlock, focusBlockTopLevelOnly]);\n\n const handleEditorDidMount: OnMount = (editor) => {\n editorRef.current = editor;\n\n const initializeEditor = () => {\n try {\n if (language === \"python\") {\n const model = editor.getModel();\n if (model) {\n setCurrentEditorModel(model);\n }\n }\n\n if (language === \"json\" && enableAutoFormatting) {\n requestAnimationFrame(() => {\n handleFormatCode();\n });\n }\n } catch (error) {\n console.warn(\"Failed to initialize editor:\", error);\n }\n };\n\n if (editor.getModel()) {\n initializeEditor();\n } else {\n const disposable = editor.onDidChangeModel(() => {\n initializeEditor();\n disposable.dispose();\n });\n }\n\n // Detect block on mouse click — use onMouseDown + small delay so cursor\n // position is settled before we read it\n if (onBlockClickRef.current) {\n editor.onMouseDown(() => {\n requestAnimationFrame(() => {\n const pos = editor.getPosition();\n if (pos) {\n detectBlock(editor, pos.lineNumber, pos.column);\n }\n });\n });\n }\n };\n\n const handleFormatJsonCode = () => {\n try {\n const parsedJson = JSON.parse(value);\n const formattedJson = JSON.stringify(parsedJson, null, 4);\n onChange(formattedJson);\n\n // Also update the editor model if it exists\n if (currentEditorModel && activeMonacoEditor) {\n activeMonacoEditor.editor.setModelMarkers(\n currentEditorModel,\n \"json\",\n []\n );\n }\n } catch (error) {\n // Display error visually instead of logging to console\n if (currentEditorModel && activeMonacoEditor) {\n const errorMessage =\n error instanceof Error ? error.message : \"Invalid JSON\";\n try {\n activeMonacoEditor.editor.setModelMarkers(\n currentEditorModel,\n \"json\",\n [\n {\n startLineNumber: 1,\n startColumn: 1,\n endLineNumber: 1,\n endColumn: 1,\n message: `Cannot format: ${errorMessage}`,\n severity: activeMonacoEditor.MarkerSeverity.Error,\n },\n ]\n );\n } catch (markerError) {\n console.warn(\"Failed to set JSON error markers:\", markerError);\n }\n }\n }\n };\n\n const handleFormatCode = () => {\n if (language === \"python\") {\n handleFormatPythonCode();\n return;\n }\n\n if (language === \"json\") {\n handleFormatJsonCode();\n return;\n }\n\n if (editorRef.current) {\n try {\n const formatAction = editorRef.current.getAction(\n \"editor.action.formatDocument\"\n );\n if (formatAction) {\n formatAction.run();\n }\n } catch (error) {\n console.warn(\"Failed to format document:\", error);\n }\n }\n };\n\n const handleChange = (newValue: string | undefined) => {\n if (typeof newValue === \"string\") {\n onChange(newValue);\n }\n };\n\n useEffect(() => {\n if (setIsDisableSave) {\n setIsDisableSave(pythonError || pythonLoading);\n }\n }, [pythonError, pythonLoading, setIsDisableSave]);\n\n // Don't render the editor until Monaco is ready (unless we have a provided instance)\n if (!monacoEditor && !monacoInstance) {\n return (\n <div className=\"flex items-center justify-center p-8 border border-neutral-200 dark:border-neutral-700 rounded-lg\">\n <div className=\"text-neutral-600 dark:text-neutral-400\">\n Loading editor...\n </div>\n </div>\n );\n }\n\n const hoverClass = classNames(\n \"hover:bg-neutral-300 hover:dark:bg-neutral-700 p-0.5 rounded-md flex items-center justify-center\"\n );\n\n const handleCopyCode = () => {\n if (language === \"python\") {\n try {\n let formattedCode = value;\n if (formattedCode) {\n formattedCode = formattedCode\n .replace(/\\r\\n/g, \"\\n\")\n .replace(/\\r/g, \"\\n\");\n formattedCode = formattedCode\n .split(\"\\n\")\n .map((line) => line.trimEnd())\n .join(\"\\n\");\n formattedCode = formattedCode.replace(/\\n+$/, \"\") + \"\\n\";\n }\n\n navigator?.clipboard\n ?.writeText(formattedCode)\n .then(() => {\n // show success toast (kept silent as in web portal)\n })\n .catch((_error: unknown) => {\n const error = _error as Error;\n toast.error(\n error?.message || systemMessages.copyFailure(\"Python Code\"),\n {\n toastId: systemMessages.copyFailure(\"Python Code\"),\n }\n );\n });\n } catch (_error: unknown) {\n const error = _error as Error;\n toast.error(\n error?.message || systemMessages.copyFailure(\"Python Code\"),\n {\n toastId: systemMessages.copyFailure(\"Python Code\"),\n }\n );\n }\n } else if (language === \"json\") {\n try {\n const parsedJson = JSON.parse(value);\n const formattedJson = JSON.stringify(parsedJson, null, 4);\n navigator?.clipboard?.writeText(formattedJson);\n } catch (_error: unknown) {\n const error = _error as Error;\n toast.error(error?.message || systemMessages.copyFailure(\"JSON Code\"), {\n toastId: systemMessages.copyFailure(\"JSON Code\"),\n });\n }\n } else {\n navigator?.clipboard?.writeText(value);\n }\n };\n\n const getConfig = (code: string) => {\n if (code === \"python\") {\n return {\n type: \"text/x-python\",\n extension: \"py\",\n };\n }\n if (code === \"json\") {\n return {\n type: \"application/json\",\n extension: \"json\",\n };\n }\n return {\n type: \"text/plain\",\n extension: \"txt\",\n };\n };\n\n // Sanitize filename utility (matching web portal implementation)\n const sanitizeFilename = (filename: string, fallback: string): string => {\n // Remove or replace potentially dangerous characters\n const sanitized = filename\n .replace(/[<>:\"/\\\\|?*\\x00-\\x1f]/g, \"_\") // Replace illegal chars\n .replace(/\\.{2,}/g, \".\") // Replace multiple dots\n .replace(/^\\.+|\\.+$/g, \"\") // Remove leading/trailing dots\n .trim();\n\n return sanitized || fallback;\n };\n\n const handleDownloadCode = () => {\n try {\n const blob = new Blob([value], { type: getConfig(language)?.type });\n const url = URL.createObjectURL(blob);\n const anchor = document.createElement(\"a\");\n anchor.href = url;\n const extension = getConfig(language)?.extension || \"txt\";\n const sanitizedExtension = sanitizeFilename(extension, \"txt\");\n anchor.download = sanitizeFilename(\n `code_${Date.now()}.${sanitizedExtension}`,\n `code_${Date.now()}.${sanitizedExtension}`\n );\n document.body.appendChild(anchor);\n anchor.click();\n document.body.removeChild(anchor);\n URL.revokeObjectURL(url);\n } catch (_error: unknown) {\n const error = _error as Error;\n toast.error(\n error?.message || systemMessages.copyFailure(\"Code download\"),\n {\n toastId: systemMessages.copyFailure(\"Code download\"),\n }\n );\n }\n };\n\n return (\n <FullScreen handle={fullScreenHandle} className=\"h-full\">\n <div\n className={cn(\n \"relative border border-neutral-200 dark:border-neutral-700 rounded-lg h-full overflow-hidden\",\n className\n )}\n id=\"code-editor-container-with-json-grid\"\n >\n <div\n className={classNames(\n `px-3 py-2 flex items-center bg-neutral-50 dark:bg-neutral-800`,\n // withJsonGrid\n // ? \"border-none\"\n // : \"border-b border-neutral-200 dark:border-neutral-700\",\n \"border-b border-neutral-200 dark:border-neutral-700\",\n isLanguageJson ? \"justify-between\" : \"justify-end\"\n )}\n >\n {isLanguageJson && withJsonGrid ? (\n <Toggle\n isChecked={activeTab === \"Grid\"}\n onChange={(checked) => setActiveTab(checked ? \"Grid\" : \"JSON\")}\n statusText=''\n hideStatus\n withIcon\n tooltip={activeTab === \"JSON\" ? \"Grid view\" : \"Code view\"}\n icon={{\n checkedIcon: <GridOnIcon fontSize={6} className=\"cursor-pointer !block text-primary-600 dark:text-neutral-300\" />,\n uncheckedIcon: <CodeIcon fontSize={10} className=\"cursor-pointer !block text-neutral-700 dark:text-neutral-400\" />,\n }}\n />\n ) : null}\n <div className=\"flex items-center gap-0.5\">\n {renderToolbarActions?.({\n editor: editorRef.current,\n value,\n onChange,\n language,\n isEditMode,\n activeTab,\n })}\n {activeTab === \"Grid\" && isEditMode && withJsonGrid && (\n <span className=\"flex items-center justify-center border-r border-neutral-200 dark:border-neutral-700 mr-1.5 pr-1.5\">\n <Tooltip title=\"Add key\">\n <button\n type='button'\n id=\"btn-code-editor-json-grid-up\"\n onClick={() => setIsAddKeyModalOpen(true)}\n className={classNames(\n \"p-0.5 rounded-md flex items-center justify-center\",\n \"hover:bg-primary-100 hover:dark:bg-neutral-800 text-primary-600 dark:text-neutral-100\"\n )}\n >\n <AddIcon fontSize={16} />\n </button>\n </Tooltip>\n </span>\n )}\n {activeTab === \"Grid\" ? (\n <>\n <Tooltip title=\"Collapse all\">\n <button\n type='button'\n id=\"btn-code-editor-json-grid-up\"\n onClick={() => setAllExpanded(false)}\n className={hoverClass}\n >\n <KeyboardDoubleArrowUpIcon fontSize={16} />\n </button>\n </Tooltip>\n\n <Tooltip title=\"Expand all\">\n <button\n type='button'\n id=\"btn-code-editor-json-grid-down\"\n onClick={() => setAllExpanded(true)}\n className={hoverClass}\n >\n <KeyboardDoubleArrowDownIcon fontSize={16} />\n </button>\n </Tooltip>\n </>\n ) : null}\n {activeTab === \"JSON\" && withJsonGrid ? (\n <Tooltip title=\"Format\">\n <button\n type='button'\n id=\"btn-code-editor-format-code\"\n onClick={handleFormatCode}\n className={hoverClass}\n >\n <SubjectOutlinedIcon fontSize={14} />\n </button>\n </Tooltip>\n ) : null}\n {withTheme && activeTab === \"JSON\" && withJsonGrid ? (\n <Tooltip\n title={editorTheme === \"vs\" ? \"Dark mode\" : \"Light mode\"}\n >\n <button\n type='button'\n id=\"btn-code-editor-with-theme\"\n onClick={() =>\n setEditorTheme(editorTheme === \"vs\" ? \"vs-dark\" : \"vs\")\n }\n className={hoverClass}\n >\n {editorTheme === \"vs\" ? (\n <DarkModeOutlinedIcon fontSize={14} />\n ) : (\n <LightModeOutlinedIcon fontSize={14} />\n )}\n </button>\n </Tooltip>\n ) : null}\n {(language === \"python\" || language === \"json\") && isShowCopy ? (\n <Tooltip title=\"Copy\">\n <button\n type='button'\n id=\"btn-code-editor-copy-code\"\n onClick={handleCopyCode}\n className={hoverClass}\n >\n <ContentPasteRoundedIcon fontSize={14} />\n </button>\n </Tooltip>\n ) : null}\n {(language === \"python\" || language === \"json\") &&\n isShowDownload ? (\n <Tooltip title=\"Download\">\n <button\n type='button'\n id=\"btn-code-editor-download-code\"\n onClick={handleDownloadCode}\n className={hoverClass}\n >\n <FileDownloadRoundedIcon fontSize={14} />\n </button>\n </Tooltip>\n ) : null}\n {withFullScreen ? (\n <Tooltip title=\"Fullscreen\">\n <button\n onClick={toggleFocusMode}\n type='button'\n id=\"btn-code-editor-fullscreen\"\n className={hoverClass}\n >\n <FullscreenRoundedIcon fontSize={14} />\n </button>\n </Tooltip>\n ) : null}\n </div>\n </div>\n\n {activeTab === \"Grid\" && language === \"json\" ? (\n <div>\n <JsonGrid\n isFullScreen={fullScreenHandle?.active}\n allExpanded={allExpanded}\n toggleAll={() => setAllExpanded((prev) => !prev)}\n isEditMode={Boolean(isEditMode)}\n isDarkMode={theme === \"dark\"}\n style={{\n height: fullScreenHandle?.active ? \"100vh\" : height,\n }}\n value={value}\n onChange={onChange}\n setIsAddKeyModalOpen={setIsAddKeyModalOpen}\n isAddKeyModalOpen={isAddKeyModalOpen}\n />\n </div>\n ) : (\n <Editor\n height={fullScreenHandle?.active ? \"100vh\" : height}\n language={language}\n value={value}\n onChange={handleChange}\n theme={editorTheme}\n onMount={handleEditorDidMount}\n options={{\n fontSize: 16,\n folding: true,\n fontFamily: \"Menlo, Monaco, 'Courier New', monospace\",\n fontLigatures: true,\n readOnly: !isEditMode,\n }}\n />\n )}\n </div>\n </FullScreen>\n );\n};\n"],"names":["iconClass","classNames","AddIcon","fontSize","jsx","ContentPasteRoundedIcon","DarkModeOutlinedIcon","FileDownloadRoundedIcon","FullscreenRoundedIcon","KeyboardDoubleArrowDownIcon","KeyboardDoubleArrowUpIcon","LightModeOutlinedIcon","SubjectOutlinedIcon","CodeEditor","value","onChange","withFullScreen","withTheme","isEditMode","height","language","monacoEditor","isShowCopy","isShowDownload","setIsDisableSave","withJsonGrid","externalEditorTheme","externalSetEditorTheme","externalTheme","className","enableAutoFormatting","renderToolbarActions","onBlockClick","focusBlock","focusBlockTopLevelOnly","editorRef","useRef","internalEditorTheme","setInternalEditorTheme","useState","internalTheme","setInternalTheme","editorTheme","theme","setEditorTheme","newTheme","allExpanded","setAllExpanded","currentEditorModel","setCurrentEditorModel","monacoInstance","useMonaco","activeMonacoEditor","handleFormatPythonCode","pythonError","pythonLoading","usePythonSyntax","fullScreenHandle","useFullScreenHandle","activeTab","setActiveTab","isAddKeyModalOpen","setIsAddKeyModalOpen","isLanguageJson","toggleFocusMode","onBlockClickRef","detectBlock","useCallback","editor","lineNumber","column","model","getTextForRange","startLine","endLine","emitBlock","text","kind","parentBlock","foldingContrib","foldingModel","regions","totalLines","containingRanges","i","start","foldEnd","end","size","rawKind","a","b","innermost","outermost","j","r","position","brackets","openRange","closeRange","useEffect","allMatches","match","bestCol","m","lineContent","leadingSpaces","matchLine","matchCol","findAndHighlightBlock","bestStart","bestEnd","bestSize","handleEditorDidMount","initializeEditor","handleFormatCode","error","disposable","pos","handleFormatJsonCode","parsedJson","formattedJson","errorMessage","markerError","formatAction","handleChange","newValue","hoverClass","handleCopyCode","formattedCode","line","_error","toast","systemMessages","getConfig","code","sanitizeFilename","filename","fallback","handleDownloadCode","blob","url","anchor","extension","sanitizedExtension","FullScreen","jsxs","cn","Toggle","checked","GridOnIcon","CodeIcon","Tooltip","Fragment","JsonGrid","prev","Editor"],"mappings":"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"}
1
+ {"version":3,"file":"CodeEditor.cjs.js","sources":["../../../../src/components/data-display/code-editor/CodeEditor.tsx"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport Editor, { type OnMount } from '@monaco-editor/react';\nimport classNames from 'classnames';\nimport { type FC, useCallback, useEffect, useRef, useState } from 'react';\nimport { FullScreen, useFullScreenHandle } from 'react-full-screen';\nimport { toast } from 'react-toastify';\nimport { useMonaco } from '../../../hooks/useMonaco';\nimport { usePythonSyntax } from '../../../hooks/usePythonSyntax';\nimport { type CodeEditorProps } from '../../../types';\nimport { systemMessages } from '../../../utils/messageConstants';\nimport { JsonGrid } from './JsonGrid';\nimport Tooltip from '../../tooltip/Tooltip';\nimport { Toggle } from '../../forms/toggle/Toggle';\nimport { cn } from '../../../lib/utils';\nimport { CodeIcon, GridOnIcon } from '../../icon';\n\n// Icon class styling (matching web portal)\nconst iconClass = classNames(\n 'text-neutral-600 cursor-pointer hover:text-neutral-800',\n 'dark:text-neutral-300 dark:hover:text-neutral-50'\n);\n\n// Material Icons converted to SVG components (matching web portal icons)\nconst AddIcon = ({ fontSize }: { fontSize: number }) => (\n <svg width={fontSize} height={fontSize} viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z\" />\n </svg>\n);\n\nconst ContentPasteRoundedIcon = ({ fontSize }: { fontSize: number }) => (\n <svg width={fontSize} height={fontSize} viewBox=\"0 0 24 24\" fill=\"currentColor\" className={iconClass}>\n <path d=\"M19 2h-4.18C14.4.84 13.3 0 12 0S9.6.84 9.18 2H5c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-7 0c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm7 18H5V4h2v3h10V4h2v16z\" />\n </svg>\n);\n\nconst DarkModeOutlinedIcon = ({ fontSize }: { fontSize: number }) => (\n <svg width={fontSize} height={fontSize} viewBox=\"0 0 24 24\" fill=\"currentColor\" className={iconClass}>\n <path d=\"M9.5 2c-1.82 0-3.53.5-5 1.35 2.99 1.73 5 4.95 5 8.65s-2.01 6.92-5 8.65c1.47.85 3.18 1.35 5 1.35 5.52 0 10-4.48 10-10S15.02 2 9.5 2z\" />\n </svg>\n);\n\nconst FileDownloadRoundedIcon = ({ fontSize }: { fontSize: number }) => (\n <svg width={fontSize} height={fontSize} viewBox=\"0 0 24 24\" fill=\"currentColor\" className={iconClass}>\n <path d=\"M18 15v3H6v-3H4v3c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2v-3h-2zm-1-4-5 5-5-5h3V4h4v7h3z\" />\n </svg>\n);\n\nconst FullscreenRoundedIcon = ({ fontSize }: { fontSize: number }) => (\n <svg width={fontSize} height={fontSize} viewBox=\"0 0 24 24\" fill=\"currentColor\" className={iconClass}>\n <path d=\"M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z\" />\n </svg>\n);\n\nconst KeyboardDoubleArrowDownIcon = ({ fontSize }: { fontSize: number }) => (\n <svg width={fontSize} height={fontSize} viewBox=\"0 0 24 24\" fill=\"currentColor\" className={iconClass}>\n <path d=\"M18 6.41 16.59 5 12 9.58 7.41 5 6 6.41l6 6z\" />\n <path d=\"m18 13-1.41-1.41L12 16.17l-4.59-4.58L6 13l6 6z\" />\n </svg>\n);\n\nconst KeyboardDoubleArrowUpIcon = ({ fontSize }: { fontSize: number }) => (\n <svg width={fontSize} height={fontSize} viewBox=\"0 0 24 24\" fill=\"currentColor\" className={iconClass}>\n <path d=\"M6 17.59 7.41 19 12 14.42 16.59 19 18 17.59l-6-6z\" />\n <path d=\"m6 11 1.41 1.41L12 7.83l4.59 4.58L18 11l-6-6z\" />\n </svg>\n);\n\nconst LightModeOutlinedIcon = ({ fontSize }: { fontSize: number }) => (\n <svg width={fontSize} height={fontSize} viewBox=\"0 0 24 24\" fill=\"currentColor\" className={iconClass}>\n <path d=\"M12 9c1.65 0 3 1.35 3 3s-1.35 3-3 3-3-1.35-3-3 1.35-3 3-3m0-2c-2.76 0-5 2.24-5 5s2.24 5 5 5 5-2.24 5-5-2.24-5-5-5zM2 13h2c.55 0 1-.45 1-1s-.45-1-1-1H2c-.55 0-1 .45-1 1s.45 1 1 1zm18 0h2c.55 0 1-.45 1-1s-.45-1-1-1h-2c-.55 0-1 .45-1 1s.45 1 1 1zM11 2v2c0 .55.45 1 1 1s1-.45 1-1V2c0-.55-.45-1-1-1s-1 .45-1 1zm0 18v2c0 .55.45 1 1 1s1-.45 1-1v-2c0-.55-.45-1-1-1s-1 .45-1 1zM5.99 4.58c-.39-.39-1.03-.39-1.41 0-.39.39-.39 1.03 0 1.41l1.06 1.06c.39.39 1.03.39 1.41 0s.39-1.03 0-1.41L5.99 4.58zm12.37 12.37c-.39-.39-1.03-.39-1.41 0-.39.39-.39 1.03 0 1.41l1.06 1.06c.39.39 1.03.39 1.41 0 .39-.39.39-1.03 0-1.41l-1.06-1.06zm1.06-10.96c.39-.39.39-1.03 0-1.41-.39-.39-1.03-.39-1.41 0l-1.06 1.06c-.39.39-.39 1.03 0 1.41s1.03.39 1.41 0l1.06-1.06zM7.05 18.36c.39-.39.39-1.03 0-1.41-.39-.39-1.03-.39-1.41 0l-1.06 1.06c-.39.39-.39 1.03 0 1.41s1.03.39 1.41 0l1.06-1.06z\" />\n </svg>\n);\n\nconst SubjectOutlinedIcon = ({ fontSize }: { fontSize: number }) => (\n <svg width={fontSize} height={fontSize} viewBox=\"0 0 24 24\" fill=\"currentColor\" className={iconClass}>\n <path d=\"M14 17H4v2h10v-2zm6-8H4v2h16V9zM4 15h16v-2H4v2zM4 5v2h16V5H4z\" />\n </svg>\n);\n\ntype TTabKey = 'JSON' | 'Grid';\n\nexport const CodeEditor: FC<CodeEditorProps> = ({\n value,\n onChange = () => false,\n withFullScreen = true,\n withTheme = true,\n isEditMode = false,\n height = \"55vh\",\n language = \"json\",\n monacoEditor,\n isShowCopy = true,\n isShowDownload = true,\n setIsDisableSave,\n withJsonGrid = true,\n editorTheme: externalEditorTheme,\n setEditorTheme: externalSetEditorTheme,\n theme: externalTheme,\n className,\n enableAutoFormatting = true,\n renderToolbarActions,\n onBlockClick,\n focusBlock,\n focusBlockTopLevelOnly = false,\n}) => {\n const editorRef = useRef<any>(null);\n\n // Internal theme state (used when not provided by parent)\n const [internalEditorTheme, setInternalEditorTheme] = useState<\n \"vs\" | \"vs-dark\"\n >(\"vs\");\n const [internalTheme, setInternalTheme] = useState<\"light\" | \"dark\">(\"light\");\n\n // Use external theme if provided, otherwise use internal\n const editorTheme = externalEditorTheme ?? internalEditorTheme;\n const theme = externalTheme ?? internalTheme;\n const setEditorTheme =\n externalSetEditorTheme ??\n ((newTheme: \"vs\" | \"vs-dark\") => {\n setInternalEditorTheme(newTheme);\n setInternalTheme(newTheme === \"vs-dark\" ? \"dark\" : \"light\");\n });\n\n const [allExpanded, setAllExpanded] = useState<boolean>(false);\n const [currentEditorModel, setCurrentEditorModel] = useState<any>(null);\n const monacoInstance = useMonaco();\n\n // Use provided monacoEditor prop or fall back to our managed instance\n const activeMonacoEditor = monacoEditor || monacoInstance;\n\n const {\n handleFormatCode: handleFormatPythonCode,\n pythonError,\n pythonLoading,\n } = usePythonSyntax({\n code: value,\n setCode: onChange,\n currentEditorModel,\n monacoEditor: activeMonacoEditor,\n enable: isEditMode === true && language === \"python\",\n });\n\n const fullScreenHandle = useFullScreenHandle();\n const [activeTab, setActiveTab] = useState<TTabKey>(\"JSON\");\n const [isAddKeyModalOpen, setIsAddKeyModalOpen] = useState(false);\n const isLanguageJson = language === \"json\";\n\n const toggleFocusMode = () => {\n if (fullScreenHandle?.active) {\n fullScreenHandle.exit();\n } else {\n fullScreenHandle.enter();\n }\n };\n\n const onBlockClickRef = useRef(onBlockClick);\n onBlockClickRef.current = onBlockClick;\n\n const detectBlock = useCallback(\n async (editor: any, lineNumber: number, column: number) => {\n if (!onBlockClickRef.current) return;\n\n const model = editor.getModel();\n if (!model) return;\n\n const getTextForRange = (startLine: number, endLine: number) =>\n model.getValueInRange({\n startLineNumber: startLine,\n startColumn: 1,\n endLineNumber: endLine,\n endColumn: model.getLineMaxColumn(endLine),\n });\n\n const emitBlock = (\n startLine: number,\n endLine: number,\n text: string,\n kind?: string,\n parentBlock?: { startLine: number; endLine: number; text: string; kind?: string }\n ) => {\n onBlockClickRef.current!({\n startLine,\n endLine,\n text,\n kind,\n cursorLine: lineNumber,\n cursorColumn: column,\n parentBlock,\n });\n };\n\n try {\n const foldingContrib = editor.getContribution(\n \"editor.contrib.folding\"\n );\n if (foldingContrib) {\n const foldingModel = await (foldingContrib as any).getFoldingModel();\n if (foldingModel?.regions) {\n const regions = foldingModel.regions;\n const totalLines = model.getLineCount();\n\n // Collect all folding ranges that contain the cursor line\n const containingRanges: {\n start: number;\n end: number;\n size: number;\n kind?: string;\n }[] = [];\n\n for (let i = 0; i < regions.length; i++) {\n const start = regions.getStartLineNumber(i);\n const foldEnd = regions.getEndLineNumber(i);\n const end = Math.min(foldEnd + 1, totalLines);\n const size = end - start;\n\n if (lineNumber >= start && lineNumber <= end) {\n const rawKind = regions.getType(i);\n const kind =\n rawKind === 1\n ? \"comment\"\n : rawKind === 2\n ? \"imports\"\n : rawKind === 3\n ? \"region\"\n : undefined;\n containingRanges.push({ start, end, size, kind });\n }\n }\n\n if (containingRanges.length > 0) {\n // Sort by size: smallest first (innermost) → largest last (outermost)\n containingRanges.sort((a, b) => a.size - b.size);\n\n const innermost = containingRanges[0];\n const text = getTextForRange(innermost.start, innermost.end);\n\n // Find the outermost block that isn't the root document range.\n // Walk from largest to smallest, skip any range that starts at\n // line 1 and ends at the last line (that's the root `{}`).\n let outermost: typeof containingRanges[number] | undefined;\n for (let j = containingRanges.length - 1; j > 0; j--) {\n const r = containingRanges[j];\n const isRoot = r.start <= 1 && r.end >= totalLines;\n if (!isRoot) {\n outermost = r;\n break;\n }\n }\n\n const parentBlock =\n outermost && outermost !== innermost\n ? {\n startLine: outermost.start,\n endLine: outermost.end,\n text: getTextForRange(outermost.start, outermost.end),\n kind: outermost.kind,\n }\n : undefined;\n\n emitBlock(innermost.start, innermost.end, text, innermost.kind, parentBlock);\n return;\n }\n }\n }\n\n // Bracket matching fallback — no parent detection available\n const position = { lineNumber, column };\n const brackets = model.bracketPairs?.findEnclosingBrackets?.(position);\n\n if (brackets && brackets.length === 2) {\n const [openRange, closeRange] = brackets;\n const startLine = openRange.startLineNumber;\n const endLine = closeRange.endLineNumber;\n const text = getTextForRange(startLine, endLine);\n emitBlock(startLine, endLine, text);\n return;\n }\n\n // Full document fallback\n const totalLines = model.getLineCount();\n const text = model.getValue();\n emitBlock(1, totalLines, text);\n } catch {\n // Editor not ready — ignore silently\n }\n },\n []\n );\n\n // Navigate to a block when focusBlock changes\n useEffect(() => {\n if (!focusBlock || !editorRef.current) return;\n\n const editor = editorRef.current;\n const model = editor.getModel();\n if (!model) return;\n\n const allMatches = model.findMatches(\n focusBlock,\n true,\n false,\n true,\n null,\n false\n );\n\n if (allMatches.length === 0) return;\n\n let match = allMatches[0];\n\n if (focusBlockTopLevelOnly && allMatches.length > 1) {\n // A top-level key in formatted JSON has minimal leading whitespace\n // (one indent level). Find the match closest to column 1.\n let bestCol = Infinity;\n for (const m of allMatches) {\n const lineContent = model.getLineContent(m.range.startLineNumber);\n const leadingSpaces = lineContent.length - lineContent.trimStart().length;\n if (leadingSpaces < bestCol) {\n bestCol = leadingSpaces;\n match = m;\n }\n }\n }\n\n const matchLine = match.range.startLineNumber;\n const matchCol = match.range.startColumn;\n\n // Move cursor to the match with smooth scroll\n editor.setPosition({ lineNumber: matchLine, column: matchCol });\n editor.revealLineInCenter(matchLine, 1);\n\n // Find the enclosing block and highlight it\n const findAndHighlightBlock = async () => {\n try {\n // Try folding ranges first\n const foldingContrib = editor.getContribution(\n \"editor.contrib.folding\"\n );\n if (foldingContrib) {\n const foldingModel = await (foldingContrib as any).getFoldingModel();\n if (foldingModel?.regions) {\n const regions = foldingModel.regions;\n let bestStart = -1;\n let bestEnd = -1;\n let bestSize = Infinity;\n\n for (let i = 0; i < regions.length; i++) {\n const start = regions.getStartLineNumber(i);\n const foldEnd = regions.getEndLineNumber(i);\n const end = Math.min(foldEnd + 1, model.getLineCount());\n const size = end - start;\n\n if (\n matchLine >= start &&\n matchLine <= end &&\n size < bestSize\n ) {\n bestStart = start;\n bestEnd = end;\n bestSize = size;\n }\n }\n\n if (bestStart !== -1) {\n editor.setSelection({\n startLineNumber: bestStart,\n startColumn: 1,\n endLineNumber: bestEnd,\n endColumn: model.getLineMaxColumn(bestEnd),\n });\n editor.revealRangeInCenter({\n startLineNumber: bestStart,\n startColumn: 1,\n endLineNumber: bestEnd,\n endColumn: model.getLineMaxColumn(bestEnd),\n }, 1);\n return;\n }\n }\n }\n\n // Fall back to bracket matching\n const position = { lineNumber: matchLine, column: matchCol };\n const brackets =\n model.bracketPairs?.findEnclosingBrackets?.(position);\n\n if (brackets && brackets.length === 2) {\n const [openRange, closeRange] = brackets;\n editor.setSelection({\n startLineNumber: openRange.startLineNumber,\n startColumn: 1,\n endLineNumber: closeRange.endLineNumber,\n endColumn: model.getLineMaxColumn(closeRange.endLineNumber),\n });\n editor.revealRangeInCenter({\n startLineNumber: openRange.startLineNumber,\n startColumn: 1,\n endLineNumber: closeRange.endLineNumber,\n endColumn: model.getLineMaxColumn(closeRange.endLineNumber),\n }, 1);\n return;\n }\n\n // Last resort — just highlight the matched text\n editor.setSelection(match.range);\n } catch {\n // Folding model not ready — just highlight the match\n editor.setSelection(match.range);\n }\n };\n\n // Small delay to let folding model compute after content may have changed\n requestAnimationFrame(() => {\n findAndHighlightBlock();\n });\n }, [focusBlock, focusBlockTopLevelOnly]);\n\n const handleEditorDidMount: OnMount = (editor) => {\n editorRef.current = editor;\n\n const initializeEditor = () => {\n try {\n if (language === \"python\") {\n const model = editor.getModel();\n if (model) {\n setCurrentEditorModel(model);\n }\n }\n\n if (language === \"json\" && enableAutoFormatting) {\n requestAnimationFrame(() => {\n handleFormatCode();\n });\n }\n } catch (error) {\n console.warn(\"Failed to initialize editor:\", error);\n }\n };\n\n if (editor.getModel()) {\n initializeEditor();\n } else {\n const disposable = editor.onDidChangeModel(() => {\n initializeEditor();\n disposable.dispose();\n });\n }\n\n // Detect block on mouse click — use onMouseDown + small delay so cursor\n // position is settled before we read it\n if (onBlockClickRef.current) {\n editor.onMouseDown(() => {\n requestAnimationFrame(() => {\n const pos = editor.getPosition();\n if (pos) {\n detectBlock(editor, pos.lineNumber, pos.column);\n }\n });\n });\n }\n };\n\n const handleFormatJsonCode = () => {\n try {\n const parsedJson = JSON.parse(value);\n const formattedJson = JSON.stringify(parsedJson, null, 4);\n onChange(formattedJson);\n\n // Also update the editor model if it exists\n if (currentEditorModel && activeMonacoEditor) {\n activeMonacoEditor.editor.setModelMarkers(\n currentEditorModel,\n \"json\",\n []\n );\n }\n } catch (error) {\n // Display error visually instead of logging to console\n if (currentEditorModel && activeMonacoEditor) {\n const errorMessage =\n error instanceof Error ? error.message : \"Invalid JSON\";\n try {\n activeMonacoEditor.editor.setModelMarkers(\n currentEditorModel,\n \"json\",\n [\n {\n startLineNumber: 1,\n startColumn: 1,\n endLineNumber: 1,\n endColumn: 1,\n message: `Cannot format: ${errorMessage}`,\n severity: activeMonacoEditor.MarkerSeverity.Error,\n },\n ]\n );\n } catch (markerError) {\n console.warn(\"Failed to set JSON error markers:\", markerError);\n }\n }\n }\n };\n\n const handleFormatCode = () => {\n if (language === \"python\") {\n handleFormatPythonCode();\n return;\n }\n\n if (language === \"json\") {\n handleFormatJsonCode();\n return;\n }\n\n if (editorRef.current) {\n try {\n const formatAction = editorRef.current.getAction(\n \"editor.action.formatDocument\"\n );\n if (formatAction) {\n formatAction.run();\n }\n } catch (error) {\n console.warn(\"Failed to format document:\", error);\n }\n }\n };\n\n const handleChange = (newValue: string | undefined) => {\n if (typeof newValue === \"string\") {\n onChange(newValue);\n }\n };\n\n useEffect(() => {\n if (setIsDisableSave) {\n setIsDisableSave(pythonError || pythonLoading);\n }\n }, [pythonError, pythonLoading, setIsDisableSave]);\n\n // Don't render the editor until Monaco is ready (unless we have a provided instance)\n if (!monacoEditor && !monacoInstance) {\n return (\n <div className=\"flex items-center justify-center p-8 border border-neutral-200 dark:border-neutral-700 rounded-lg\">\n <div className=\"text-neutral-600 dark:text-neutral-400\">\n Loading editor...\n </div>\n </div>\n );\n }\n\n const hoverClass = classNames(\n \"hover:bg-neutral-300 hover:dark:bg-neutral-700 p-0.5 rounded-md flex items-center justify-center\"\n );\n\n const handleCopyCode = () => {\n if (language === \"python\") {\n try {\n let formattedCode = value;\n if (formattedCode) {\n formattedCode = formattedCode\n .replace(/\\r\\n/g, \"\\n\")\n .replace(/\\r/g, \"\\n\");\n formattedCode = formattedCode\n .split(\"\\n\")\n .map((line) => line.trimEnd())\n .join(\"\\n\");\n formattedCode = formattedCode.replace(/\\n+$/, \"\") + \"\\n\";\n }\n\n navigator?.clipboard\n ?.writeText(formattedCode)\n .then(() => {\n // show success toast (kept silent as in web portal)\n })\n .catch((_error: unknown) => {\n const error = _error as Error;\n toast.error(\n error?.message || systemMessages.copyFailure(\"Python Code\"),\n {\n toastId: systemMessages.copyFailure(\"Python Code\"),\n }\n );\n });\n } catch (_error: unknown) {\n const error = _error as Error;\n toast.error(\n error?.message || systemMessages.copyFailure(\"Python Code\"),\n {\n toastId: systemMessages.copyFailure(\"Python Code\"),\n }\n );\n }\n } else if (language === \"json\") {\n try {\n const parsedJson = JSON.parse(value);\n const formattedJson = JSON.stringify(parsedJson, null, 4);\n navigator?.clipboard?.writeText(formattedJson);\n } catch (_error: unknown) {\n const error = _error as Error;\n toast.error(error?.message || systemMessages.copyFailure(\"JSON Code\"), {\n toastId: systemMessages.copyFailure(\"JSON Code\"),\n });\n }\n } else {\n navigator?.clipboard?.writeText(value);\n }\n };\n\n const getConfig = (code: string) => {\n if (code === \"python\") {\n return {\n type: \"text/x-python\",\n extension: \"py\",\n };\n }\n if (code === \"json\") {\n return {\n type: \"application/json\",\n extension: \"json\",\n };\n }\n return {\n type: \"text/plain\",\n extension: \"txt\",\n };\n };\n\n // Sanitize filename utility (matching web portal implementation)\n const sanitizeFilename = (filename: string, fallback: string): string => {\n // Remove or replace potentially dangerous characters\n const sanitized = filename\n .replace(/[<>:\"/\\\\|?*\\x00-\\x1f]/g, \"_\") // Replace illegal chars\n .replace(/\\.{2,}/g, \".\") // Replace multiple dots\n .replace(/^\\.+|\\.+$/g, \"\") // Remove leading/trailing dots\n .trim();\n\n return sanitized || fallback;\n };\n\n const handleDownloadCode = () => {\n try {\n const blob = new Blob([value], { type: getConfig(language)?.type });\n const url = URL.createObjectURL(blob);\n const anchor = document.createElement(\"a\");\n anchor.href = url;\n const extension = getConfig(language)?.extension || \"txt\";\n const sanitizedExtension = sanitizeFilename(extension, \"txt\");\n anchor.download = sanitizeFilename(\n `code_${Date.now()}.${sanitizedExtension}`,\n `code_${Date.now()}.${sanitizedExtension}`\n );\n document.body.appendChild(anchor);\n anchor.click();\n document.body.removeChild(anchor);\n URL.revokeObjectURL(url);\n } catch (_error: unknown) {\n const error = _error as Error;\n toast.error(\n error?.message || systemMessages.copyFailure(\"Code download\"),\n {\n toastId: systemMessages.copyFailure(\"Code download\"),\n }\n );\n }\n };\n\n return (\n <FullScreen handle={fullScreenHandle} className=\"h-full\">\n <div\n className={cn(\n \"relative border border-neutral-200 dark:border-neutral-700 rounded-lg h-full overflow-hidden\",\n className\n )}\n id=\"code-editor-container-with-json-grid\"\n >\n <div\n className={classNames(\n `px-3 py-2 flex items-center bg-neutral-50 dark:bg-neutral-800`,\n // withJsonGrid\n // ? \"border-none\"\n // : \"border-b border-neutral-200 dark:border-neutral-700\",\n \"border-b border-neutral-200 dark:border-neutral-700\",\n isLanguageJson ? \"justify-between\" : \"justify-end\"\n )}\n >\n {isLanguageJson && withJsonGrid ? (\n <Toggle\n isChecked={activeTab === \"Grid\"}\n onChange={(checked) => setActiveTab(checked ? \"Grid\" : \"JSON\")}\n statusText=''\n hideStatus\n withIcon\n tooltip={activeTab === \"JSON\" ? \"Grid view\" : \"Code view\"}\n icon={{\n checkedIcon: <GridOnIcon className=\"cursor-pointer !block text-primary-600 dark:text-neutral-300 h-2xs w-2xs lg:h-xs lg:w-xs\" />,\n uncheckedIcon: <CodeIcon className=\"cursor-pointer !block text-neutral-700 dark:text-neutral-400 h-2xs w-2xs lg:h-xs lg:w-xs\" />,\n }}\n />\n ) : null}\n <div className=\"flex items-center gap-0.5\">\n {renderToolbarActions?.({\n editor: editorRef.current,\n value,\n onChange,\n language,\n isEditMode,\n activeTab,\n })}\n {activeTab === \"Grid\" && isEditMode && withJsonGrid && (\n <span className=\"flex items-center justify-center border-r border-neutral-200 dark:border-neutral-700 mr-1.5 pr-1.5\">\n <Tooltip title=\"Add key\">\n <button\n type='button'\n id=\"btn-code-editor-json-grid-up\"\n onClick={() => setIsAddKeyModalOpen(true)}\n className={classNames(\n \"p-0.5 rounded-md flex items-center justify-center\",\n \"hover:bg-primary-100 hover:dark:bg-neutral-800 text-primary-600 dark:text-neutral-100\"\n )}\n >\n <AddIcon fontSize={16} />\n </button>\n </Tooltip>\n </span>\n )}\n {activeTab === \"Grid\" ? (\n <>\n <Tooltip title=\"Collapse all\">\n <button\n type='button'\n id=\"btn-code-editor-json-grid-up\"\n onClick={() => setAllExpanded(false)}\n className={hoverClass}\n >\n <KeyboardDoubleArrowUpIcon fontSize={16} />\n </button>\n </Tooltip>\n\n <Tooltip title=\"Expand all\">\n <button\n type='button'\n id=\"btn-code-editor-json-grid-down\"\n onClick={() => setAllExpanded(true)}\n className={hoverClass}\n >\n <KeyboardDoubleArrowDownIcon fontSize={16} />\n </button>\n </Tooltip>\n </>\n ) : null}\n {activeTab === \"JSON\" && withJsonGrid ? (\n <Tooltip title=\"Format\">\n <button\n type='button'\n id=\"btn-code-editor-format-code\"\n onClick={handleFormatCode}\n className={hoverClass}\n >\n <SubjectOutlinedIcon fontSize={14} />\n </button>\n </Tooltip>\n ) : null}\n {withTheme && activeTab === \"JSON\" && withJsonGrid ? (\n <Tooltip\n title={editorTheme === \"vs\" ? \"Dark mode\" : \"Light mode\"}\n >\n <button\n type='button'\n id=\"btn-code-editor-with-theme\"\n onClick={() =>\n setEditorTheme(editorTheme === \"vs\" ? \"vs-dark\" : \"vs\")\n }\n className={hoverClass}\n >\n {editorTheme === \"vs\" ? (\n <DarkModeOutlinedIcon fontSize={14} />\n ) : (\n <LightModeOutlinedIcon fontSize={14} />\n )}\n </button>\n </Tooltip>\n ) : null}\n {(language === \"python\" || language === \"json\") && isShowCopy ? (\n <Tooltip title=\"Copy\">\n <button\n type='button'\n id=\"btn-code-editor-copy-code\"\n onClick={handleCopyCode}\n className={hoverClass}\n >\n <ContentPasteRoundedIcon fontSize={14} />\n </button>\n </Tooltip>\n ) : null}\n {(language === \"python\" || language === \"json\") &&\n isShowDownload ? (\n <Tooltip title=\"Download\">\n <button\n type='button'\n id=\"btn-code-editor-download-code\"\n onClick={handleDownloadCode}\n className={hoverClass}\n >\n <FileDownloadRoundedIcon fontSize={14} />\n </button>\n </Tooltip>\n ) : null}\n {withFullScreen ? (\n <Tooltip title=\"Fullscreen\">\n <button\n onClick={toggleFocusMode}\n type='button'\n id=\"btn-code-editor-fullscreen\"\n className={hoverClass}\n >\n <FullscreenRoundedIcon fontSize={14} />\n </button>\n </Tooltip>\n ) : null}\n </div>\n </div>\n\n {activeTab === \"Grid\" && language === \"json\" ? (\n <div>\n <JsonGrid\n isFullScreen={fullScreenHandle?.active}\n allExpanded={allExpanded}\n toggleAll={() => setAllExpanded((prev) => !prev)}\n isEditMode={Boolean(isEditMode)}\n isDarkMode={theme === \"dark\"}\n style={{\n height: fullScreenHandle?.active ? \"100vh\" : height,\n }}\n value={value}\n onChange={onChange}\n setIsAddKeyModalOpen={setIsAddKeyModalOpen}\n isAddKeyModalOpen={isAddKeyModalOpen}\n />\n </div>\n ) : (\n <Editor\n height={fullScreenHandle?.active ? \"100vh\" : height}\n language={language}\n value={value}\n onChange={handleChange}\n theme={editorTheme}\n onMount={handleEditorDidMount}\n options={{\n fontSize: 16,\n folding: true,\n fontFamily: \"Menlo, Monaco, 'Courier New', monospace\",\n fontLigatures: true,\n readOnly: !isEditMode,\n }}\n />\n )}\n </div>\n </FullScreen>\n );\n};\n"],"names":["iconClass","classNames","AddIcon","fontSize","jsx","ContentPasteRoundedIcon","DarkModeOutlinedIcon","FileDownloadRoundedIcon","FullscreenRoundedIcon","KeyboardDoubleArrowDownIcon","KeyboardDoubleArrowUpIcon","LightModeOutlinedIcon","SubjectOutlinedIcon","CodeEditor","value","onChange","withFullScreen","withTheme","isEditMode","height","language","monacoEditor","isShowCopy","isShowDownload","setIsDisableSave","withJsonGrid","externalEditorTheme","externalSetEditorTheme","externalTheme","className","enableAutoFormatting","renderToolbarActions","onBlockClick","focusBlock","focusBlockTopLevelOnly","editorRef","useRef","internalEditorTheme","setInternalEditorTheme","useState","internalTheme","setInternalTheme","editorTheme","theme","setEditorTheme","newTheme","allExpanded","setAllExpanded","currentEditorModel","setCurrentEditorModel","monacoInstance","useMonaco","activeMonacoEditor","handleFormatPythonCode","pythonError","pythonLoading","usePythonSyntax","fullScreenHandle","useFullScreenHandle","activeTab","setActiveTab","isAddKeyModalOpen","setIsAddKeyModalOpen","isLanguageJson","toggleFocusMode","onBlockClickRef","detectBlock","useCallback","editor","lineNumber","column","model","getTextForRange","startLine","endLine","emitBlock","text","kind","parentBlock","foldingContrib","foldingModel","regions","totalLines","containingRanges","i","start","foldEnd","end","size","rawKind","a","b","innermost","outermost","j","r","position","brackets","openRange","closeRange","useEffect","allMatches","match","bestCol","m","lineContent","leadingSpaces","matchLine","matchCol","findAndHighlightBlock","bestStart","bestEnd","bestSize","handleEditorDidMount","initializeEditor","handleFormatCode","error","disposable","pos","handleFormatJsonCode","parsedJson","formattedJson","errorMessage","markerError","formatAction","handleChange","newValue","hoverClass","handleCopyCode","formattedCode","line","_error","toast","systemMessages","getConfig","code","sanitizeFilename","filename","fallback","handleDownloadCode","blob","url","anchor","extension","sanitizedExtension","FullScreen","jsxs","cn","Toggle","checked","GridOnIcon","CodeIcon","Tooltip","Fragment","JsonGrid","prev","Editor"],"mappings":"0rBAiBMA,EAAYC,EAChB,yDACA,kDACF,EAGMC,GAAU,CAAC,CAAE,SAAAC,KACjBC,EAAAA,IAAC,OAAI,MAAOD,EAAU,OAAQA,EAAU,QAAQ,YAAY,KAAK,eAC/D,eAAC,OAAA,CAAK,EAAE,sCAAsC,EAChD,EAGIE,GAA0B,CAAC,CAAE,SAAAF,CAAA,IACjCC,MAAC,MAAA,CAAI,MAAOD,EAAU,OAAQA,EAAU,QAAQ,YAAY,KAAK,eAAe,UAAWH,EACzF,SAAAI,MAAC,OAAA,CAAK,EAAE,mMAAA,CAAoM,CAAA,CAC9M,EAGIE,GAAuB,CAAC,CAAE,SAAAH,CAAA,IAC9BC,MAAC,MAAA,CAAI,MAAOD,EAAU,OAAQA,EAAU,QAAQ,YAAY,KAAK,eAAe,UAAWH,EACzF,SAAAI,MAAC,OAAA,CAAK,EAAE,qIAAA,CAAsI,CAAA,CAChJ,EAGIG,GAA0B,CAAC,CAAE,SAAAJ,CAAA,IACjCC,MAAC,MAAA,CAAI,MAAOD,EAAU,OAAQA,EAAU,QAAQ,YAAY,KAAK,eAAe,UAAWH,EACzF,SAAAI,MAAC,OAAA,CAAK,EAAE,kFAAA,CAAmF,CAAA,CAC7F,EAGII,GAAwB,CAAC,CAAE,SAAAL,CAAA,IAC/BC,MAAC,MAAA,CAAI,MAAOD,EAAU,OAAQA,EAAU,QAAQ,YAAY,KAAK,eAAe,UAAWH,EACzF,SAAAI,MAAC,OAAA,CAAK,EAAE,gFAAA,CAAiF,CAAA,CAC3F,EAGIK,GAA8B,CAAC,CAAE,SAAAN,CAAA,WACpC,MAAA,CAAI,MAAOA,EAAU,OAAQA,EAAU,QAAQ,YAAY,KAAK,eAAe,UAAWH,EACzF,SAAA,CAAAI,EAAAA,IAAC,OAAA,CAAK,EAAE,6CAAA,CAA8C,EACtDA,EAAAA,IAAC,OAAA,CAAK,EAAE,gDAAA,CAAiD,CAAA,EAC3D,EAGIM,GAA4B,CAAC,CAAE,SAAAP,CAAA,WAClC,MAAA,CAAI,MAAOA,EAAU,OAAQA,EAAU,QAAQ,YAAY,KAAK,eAAe,UAAWH,EACzF,SAAA,CAAAI,EAAAA,IAAC,OAAA,CAAK,EAAE,mDAAA,CAAoD,EAC5DA,EAAAA,IAAC,OAAA,CAAK,EAAE,+CAAA,CAAgD,CAAA,EAC1D,EAGIO,GAAwB,CAAC,CAAE,SAAAR,CAAA,IAC/BC,MAAC,MAAA,CAAI,MAAOD,EAAU,OAAQA,EAAU,QAAQ,YAAY,KAAK,eAAe,UAAWH,EACzF,SAAAI,MAAC,OAAA,CAAK,EAAE,o1BAAA,CAAq1B,CAAA,CAC/1B,EAGIQ,GAAsB,CAAC,CAAE,SAAAT,CAAA,IAC7BC,MAAC,MAAA,CAAI,MAAOD,EAAU,OAAQA,EAAU,QAAQ,YAAY,KAAK,eAAe,UAAWH,EACzF,SAAAI,MAAC,OAAA,CAAK,EAAE,+DAAA,CAAgE,CAAA,CAC1E,EAKWS,GAAkC,CAAC,CAC9C,MAAAC,EACA,SAAAC,EAAW,IAAM,GACjB,eAAAC,GAAiB,GACjB,UAAAC,GAAY,GACZ,WAAAC,EAAa,GACb,OAAAC,EAAS,OACT,SAAAC,EAAW,OACX,aAAAC,EACA,WAAAC,GAAa,GACb,eAAAC,GAAiB,GACjB,iBAAAC,EACA,aAAAC,EAAe,GACf,YAAaC,GACb,eAAgBC,GAChB,MAAOC,GACP,UAAAC,GACA,qBAAAC,GAAuB,GACvB,qBAAAC,GACA,aAAAC,EACA,WAAAC,EACA,uBAAAC,EAAyB,EAC3B,IAAM,CACJ,MAAMC,EAAYC,EAAAA,OAAY,IAAI,EAG5B,CAACC,GAAqBC,EAAsB,EAAIC,EAAAA,SAEpD,IAAI,EACA,CAACC,GAAeC,EAAgB,EAAIF,EAAAA,SAA2B,OAAO,EAGtEG,EAAchB,IAAuBW,GACrCM,GAAQf,IAAiBY,GACzBI,GACJjB,KACEkB,GAA+B,CAC/BP,GAAuBO,CAAQ,EAC/BJ,GAAiBI,IAAa,UAAY,OAAS,OAAO,CAC5D,GAEI,CAACC,GAAaC,CAAc,EAAIR,EAAAA,SAAkB,EAAK,EACvD,CAACS,EAAoBC,EAAqB,EAAIV,EAAAA,SAAc,IAAI,EAChEW,EAAiBC,GAAAA,UAAA,EAGjBC,EAAqB/B,GAAgB6B,EAErC,CACJ,iBAAkBG,GAClB,YAAAC,EACA,cAAAC,CAAA,EACEC,mBAAgB,CAClB,KAAM1C,EACN,QAASC,EACT,mBAAAiC,EACA,aAAcI,EACd,OAAQlC,IAAe,IAAQE,IAAa,QAAA,CAC7C,EAEKqC,EAAmBC,GAAAA,oBAAA,EACnB,CAACC,EAAWC,EAAY,EAAIrB,EAAAA,SAAkB,MAAM,EACpD,CAACsB,GAAmBC,CAAoB,EAAIvB,EAAAA,SAAS,EAAK,EAC1DwB,EAAiB3C,IAAa,OAE9B4C,GAAkB,IAAM,CACxBP,GAAkB,OACpBA,EAAiB,KAAA,EAEjBA,EAAiB,MAAA,CAErB,EAEMQ,EAAkB7B,EAAAA,OAAOJ,CAAY,EAC3CiC,EAAgB,QAAUjC,EAE1B,MAAMkC,GAAcC,EAAAA,YAClB,MAAOC,EAAaC,EAAoBC,IAAmB,CACzD,GAAI,CAACL,EAAgB,QAAS,OAE9B,MAAMM,EAAQH,EAAO,SAAA,EACrB,GAAI,CAACG,EAAO,OAEZ,MAAMC,EAAkB,CAACC,EAAmBC,IAC1CH,EAAM,gBAAgB,CACpB,gBAAiBE,EACjB,YAAa,EACb,cAAeC,EACf,UAAWH,EAAM,iBAAiBG,CAAO,CAAA,CAC1C,EAEGC,EAAY,CAChBF,EACAC,EACAE,EACAC,EACAC,IACG,CACHb,EAAgB,QAAS,CACvB,UAAAQ,EACA,QAAAC,EACA,KAAAE,EACA,KAAAC,EACA,WAAYR,EACZ,aAAcC,EACd,YAAAQ,CAAA,CACD,CACH,EAEA,GAAI,CACF,MAAMC,EAAiBX,EAAO,gBAC5B,wBAAA,EAEF,GAAIW,EAAgB,CAClB,MAAMC,EAAe,MAAOD,EAAuB,gBAAA,EACnD,GAAIC,GAAc,QAAS,CACzB,MAAMC,EAAUD,EAAa,QACvBE,EAAaX,EAAM,aAAA,EAGnBY,EAKA,CAAA,EAEN,QAASC,EAAI,EAAGA,EAAIH,EAAQ,OAAQG,IAAK,CACvC,MAAMC,EAAQJ,EAAQ,mBAAmBG,CAAC,EACpCE,EAAUL,EAAQ,iBAAiBG,CAAC,EACpCG,EAAM,KAAK,IAAID,EAAU,EAAGJ,CAAU,EACtCM,EAAOD,EAAMF,EAEnB,GAAIhB,GAAcgB,GAAShB,GAAckB,EAAK,CAC5C,MAAME,EAAUR,EAAQ,QAAQG,CAAC,EAC3BP,GACJY,IAAY,EACR,UACAA,IAAY,EACV,UACAA,IAAY,EACV,SACA,OACVN,EAAiB,KAAK,CAAE,MAAAE,EAAO,IAAAE,EAAK,KAAAC,EAAM,KAAAX,GAAM,CAClD,CACF,CAEA,GAAIM,EAAiB,OAAS,EAAG,CAE/BA,EAAiB,KAAK,CAACO,EAAGC,IAAMD,EAAE,KAAOC,EAAE,IAAI,EAE/C,MAAMC,EAAYT,EAAiB,CAAC,EAC9BP,EAAOJ,EAAgBoB,EAAU,MAAOA,EAAU,GAAG,EAK3D,IAAIC,EACJ,QAASC,EAAIX,EAAiB,OAAS,EAAGW,EAAI,EAAGA,IAAK,CACpD,MAAMC,EAAIZ,EAAiBW,CAAC,EAE5B,GAAI,EADWC,EAAE,OAAS,GAAKA,EAAE,KAAOb,GAC3B,CACXW,EAAYE,EACZ,KACF,CACF,CAEA,MAAMjB,EACJe,GAAaA,IAAcD,EACvB,CACE,UAAWC,EAAU,MACrB,QAASA,EAAU,IACnB,KAAMrB,EAAgBqB,EAAU,MAAOA,EAAU,GAAG,EACpD,KAAMA,EAAU,IAAA,EAElB,OAENlB,EAAUiB,EAAU,MAAOA,EAAU,IAAKhB,EAAMgB,EAAU,KAAMd,CAAW,EAC3E,MACF,CACF,CACF,CAGA,MAAMkB,EAAW,CAAE,WAAA3B,EAAY,OAAAC,CAAA,EACzB2B,EAAW1B,EAAM,cAAc,wBAAwByB,CAAQ,EAErE,GAAIC,GAAYA,EAAS,SAAW,EAAG,CACrC,KAAM,CAACC,EAAWC,CAAU,EAAIF,EAC1BxB,EAAYyB,EAAU,gBACtBxB,EAAUyB,EAAW,cACrBvB,EAAOJ,EAAgBC,EAAWC,CAAO,EAC/CC,EAAUF,EAAWC,EAASE,CAAI,EAClC,MACF,CAGA,MAAMM,EAAaX,EAAM,aAAA,EACnBK,EAAOL,EAAM,SAAA,EACnBI,EAAU,EAAGO,EAAYN,CAAI,CAC/B,MAAQ,CAER,CACF,EACA,CAAA,CAAC,EAIHwB,EAAAA,UAAU,IAAM,CACd,GAAI,CAACnE,GAAc,CAACE,EAAU,QAAS,OAEvC,MAAMiC,EAASjC,EAAU,QACnBoC,EAAQH,EAAO,SAAA,EACrB,GAAI,CAACG,EAAO,OAEZ,MAAM8B,EAAa9B,EAAM,YACvBtC,EACA,GACA,GACA,GACA,KACA,EAAA,EAGF,GAAIoE,EAAW,SAAW,EAAG,OAE7B,IAAIC,EAAQD,EAAW,CAAC,EAExB,GAAInE,GAA0BmE,EAAW,OAAS,EAAG,CAGnD,IAAIE,EAAU,IACd,UAAWC,KAAKH,EAAY,CAC1B,MAAMI,EAAclC,EAAM,eAAeiC,EAAE,MAAM,eAAe,EAC1DE,EAAgBD,EAAY,OAASA,EAAY,YAAY,OAC/DC,EAAgBH,IAClBA,EAAUG,EACVJ,EAAQE,EAEZ,CACF,CAEA,MAAMG,EAAYL,EAAM,MAAM,gBACxBM,EAAWN,EAAM,MAAM,YAG7BlC,EAAO,YAAY,CAAE,WAAYuC,EAAW,OAAQC,EAAU,EAC9DxC,EAAO,mBAAmBuC,EAAW,CAAC,EAGtC,MAAME,EAAwB,SAAY,CACxC,GAAI,CAEF,MAAM9B,EAAiBX,EAAO,gBAC5B,wBAAA,EAEF,GAAIW,EAAgB,CAClB,MAAMC,EAAe,MAAOD,EAAuB,gBAAA,EACnD,GAAIC,GAAc,QAAS,CACzB,MAAMC,EAAUD,EAAa,QAC7B,IAAI8B,EAAY,GACZC,EAAU,GACVC,EAAW,IAEf,QAAS5B,EAAI,EAAGA,EAAIH,EAAQ,OAAQG,IAAK,CACvC,MAAMC,EAAQJ,EAAQ,mBAAmBG,CAAC,EACpCE,EAAUL,EAAQ,iBAAiBG,CAAC,EACpCG,EAAM,KAAK,IAAID,EAAU,EAAGf,EAAM,cAAc,EAChDiB,EAAOD,EAAMF,EAGjBsB,GAAatB,GACbsB,GAAapB,GACbC,EAAOwB,IAEPF,EAAYzB,EACZ0B,EAAUxB,EACVyB,EAAWxB,EAEf,CAEA,GAAIsB,IAAc,GAAI,CACpB1C,EAAO,aAAa,CAClB,gBAAiB0C,EACjB,YAAa,EACb,cAAeC,EACf,UAAWxC,EAAM,iBAAiBwC,CAAO,CAAA,CAC1C,EACD3C,EAAO,oBAAoB,CACzB,gBAAiB0C,EACjB,YAAa,EACb,cAAeC,EACf,UAAWxC,EAAM,iBAAiBwC,CAAO,CAAA,EACxC,CAAC,EACJ,MACF,CACF,CACF,CAGA,MAAMf,EAAW,CAAE,WAAYW,EAAW,OAAQC,CAAA,EAC5CX,EACJ1B,EAAM,cAAc,wBAAwByB,CAAQ,EAEtD,GAAIC,GAAYA,EAAS,SAAW,EAAG,CACrC,KAAM,CAACC,EAAWC,CAAU,EAAIF,EAChC7B,EAAO,aAAa,CAClB,gBAAiB8B,EAAU,gBAC3B,YAAa,EACb,cAAeC,EAAW,cAC1B,UAAW5B,EAAM,iBAAiB4B,EAAW,aAAa,CAAA,CAC3D,EACD/B,EAAO,oBAAoB,CACzB,gBAAiB8B,EAAU,gBAC3B,YAAa,EACb,cAAeC,EAAW,cAC1B,UAAW5B,EAAM,iBAAiB4B,EAAW,aAAa,CAAA,EACzD,CAAC,EACJ,MACF,CAGA/B,EAAO,aAAakC,EAAM,KAAK,CACjC,MAAQ,CAENlC,EAAO,aAAakC,EAAM,KAAK,CACjC,CACF,EAGA,sBAAsB,IAAM,CAC1BO,EAAA,CACF,CAAC,CACH,EAAG,CAAC5E,EAAYC,CAAsB,CAAC,EAEvC,MAAM+E,GAAiC7C,GAAW,CAChDjC,EAAU,QAAUiC,EAEpB,MAAM8C,EAAmB,IAAM,CAC7B,GAAI,CACF,GAAI9F,IAAa,SAAU,CACzB,MAAMmD,EAAQH,EAAO,SAAA,EACjBG,GACFtB,GAAsBsB,CAAK,CAE/B,CAEInD,IAAa,QAAUU,IACzB,sBAAsB,IAAM,CAC1BqF,EAAA,CACF,CAAC,CAEL,OAASC,EAAO,CACd,QAAQ,KAAK,+BAAgCA,CAAK,CACpD,CACF,EAEA,GAAIhD,EAAO,WACT8C,EAAA,MACK,CACL,MAAMG,EAAajD,EAAO,iBAAiB,IAAM,CAC/C8C,EAAA,EACAG,EAAW,QAAA,CACb,CAAC,CACH,CAIIpD,EAAgB,SAClBG,EAAO,YAAY,IAAM,CACvB,sBAAsB,IAAM,CAC1B,MAAMkD,EAAMlD,EAAO,YAAA,EACfkD,GACFpD,GAAYE,EAAQkD,EAAI,WAAYA,EAAI,MAAM,CAElD,CAAC,CACH,CAAC,CAEL,EAEMC,GAAuB,IAAM,CACjC,GAAI,CACF,MAAMC,EAAa,KAAK,MAAM1G,CAAK,EAC7B2G,EAAgB,KAAK,UAAUD,EAAY,KAAM,CAAC,EACxDzG,EAAS0G,CAAa,EAGlBzE,GAAsBI,GACxBA,EAAmB,OAAO,gBACxBJ,EACA,OACA,CAAA,CAAC,CAGP,OAASoE,EAAO,CAEd,GAAIpE,GAAsBI,EAAoB,CAC5C,MAAMsE,EACJN,aAAiB,MAAQA,EAAM,QAAU,eAC3C,GAAI,CACFhE,EAAmB,OAAO,gBACxBJ,EACA,OACA,CACE,CACE,gBAAiB,EACjB,YAAa,EACb,cAAe,EACf,UAAW,EACX,QAAS,kBAAkB0E,CAAY,GACvC,SAAUtE,EAAmB,eAAe,KAAA,CAC9C,CACF,CAEJ,OAASuE,EAAa,CACpB,QAAQ,KAAK,oCAAqCA,CAAW,CAC/D,CACF,CACF,CACF,EAEMR,EAAmB,IAAM,CAC7B,GAAI/F,IAAa,SAAU,CACzBiC,GAAA,EACA,MACF,CAEA,GAAIjC,IAAa,OAAQ,CACvBmG,GAAA,EACA,MACF,CAEA,GAAIpF,EAAU,QACZ,GAAI,CACF,MAAMyF,EAAezF,EAAU,QAAQ,UACrC,8BAAA,EAEEyF,GACFA,EAAa,IAAA,CAEjB,OAASR,EAAO,CACd,QAAQ,KAAK,6BAA8BA,CAAK,CAClD,CAEJ,EAEMS,GAAgBC,GAAiC,CACjD,OAAOA,GAAa,UACtB/G,EAAS+G,CAAQ,CAErB,EASA,GAPA1B,EAAAA,UAAU,IAAM,CACV5E,GACFA,EAAiB8B,GAAeC,CAAa,CAEjD,EAAG,CAACD,EAAaC,EAAe/B,CAAgB,CAAC,EAG7C,CAACH,GAAgB,CAAC6B,EACpB,OACE9C,EAAAA,IAAC,OAAI,UAAU,oGACb,eAAC,MAAA,CAAI,UAAU,yCAAyC,SAAA,mBAAA,CAExD,CAAA,CACF,EAIJ,MAAM2H,EAAa9H,EACjB,kGAAA,EAGI+H,GAAiB,IAAM,CAC3B,GAAI5G,IAAa,SACf,GAAI,CACF,IAAI6G,EAAgBnH,EAChBmH,IACFA,EAAgBA,EACb,QAAQ,QAAS;AAAA,CAAI,EACrB,QAAQ,MAAO;AAAA,CAAI,EACtBA,EAAgBA,EACb,MAAM;AAAA,CAAI,EACV,IAAKC,GAASA,EAAK,QAAA,CAAS,EAC5B,KAAK;AAAA,CAAI,EACZD,EAAgBA,EAAc,QAAQ,OAAQ,EAAE,EAAI;AAAA,GAGtD,WAAW,WACP,UAAUA,CAAa,EACxB,KAAK,IAAM,CAEZ,CAAC,EACA,MAAOE,GAAoB,CAC1B,MAAMf,EAAQe,EACdC,EAAAA,MAAM,MACJhB,GAAO,SAAWiB,iBAAe,YAAY,aAAa,EAC1D,CACE,QAASA,EAAAA,eAAe,YAAY,aAAa,CAAA,CACnD,CAEJ,CAAC,CACL,OAASF,EAAiB,CACxB,MAAMf,EAAQe,EACdC,EAAAA,MAAM,MACJhB,GAAO,SAAWiB,iBAAe,YAAY,aAAa,EAC1D,CACE,QAASA,EAAAA,eAAe,YAAY,aAAa,CAAA,CACnD,CAEJ,SACSjH,IAAa,OACtB,GAAI,CACF,MAAMoG,EAAa,KAAK,MAAM1G,CAAK,EAC7B2G,EAAgB,KAAK,UAAUD,EAAY,KAAM,CAAC,EACxD,WAAW,WAAW,UAAUC,CAAa,CAC/C,OAASU,EAAiB,CACxB,MAAMf,EAAQe,EACdC,EAAAA,MAAM,MAAMhB,GAAO,SAAWiB,EAAAA,eAAe,YAAY,WAAW,EAAG,CACrE,QAASA,EAAAA,eAAe,YAAY,WAAW,CAAA,CAChD,CACH,MAEA,WAAW,WAAW,UAAUvH,CAAK,CAEzC,EAEMwH,GAAaC,GACbA,IAAS,SACJ,CACL,KAAM,gBACN,UAAW,IAAA,EAGXA,IAAS,OACJ,CACL,KAAM,mBACN,UAAW,MAAA,EAGR,CACL,KAAM,aACN,UAAW,KAAA,EAKTC,GAAmB,CAACC,EAAkBC,IAExBD,EACf,QAAQ,yBAA0B,GAAG,EACrC,QAAQ,UAAW,GAAG,EACtB,QAAQ,aAAc,EAAE,EACxB,KAAA,GAEiBC,EAGhBC,GAAqB,IAAM,CAC/B,GAAI,CACF,MAAMC,EAAO,IAAI,KAAK,CAAC9H,CAAK,EAAG,CAAE,KAAMwH,GAAUlH,CAAQ,GAAG,KAAM,EAC5DyH,EAAM,IAAI,gBAAgBD,CAAI,EAC9BE,EAAS,SAAS,cAAc,GAAG,EACzCA,EAAO,KAAOD,EACd,MAAME,EAAYT,GAAUlH,CAAQ,GAAG,WAAa,MAC9C4H,EAAqBR,GAAiBO,EAAW,KAAK,EAC5DD,EAAO,SAAWN,GAChB,QAAQ,KAAK,IAAA,CAAK,IAAIQ,CAAkB,GACxC,QAAQ,KAAK,IAAA,CAAK,IAAIA,CAAkB,EAAA,EAE1C,SAAS,KAAK,YAAYF,CAAM,EAChCA,EAAO,MAAA,EACP,SAAS,KAAK,YAAYA,CAAM,EAChC,IAAI,gBAAgBD,CAAG,CACzB,OAASV,EAAiB,CACxB,MAAMf,EAAQe,EACdC,EAAAA,MAAM,MACJhB,GAAO,SAAWiB,iBAAe,YAAY,eAAe,EAC5D,CACE,QAASA,EAAAA,eAAe,YAAY,eAAe,CAAA,CACrD,CAEJ,CACF,EAEA,OACEjI,EAAAA,IAAC6I,GAAAA,WAAA,CAAW,OAAQxF,EAAkB,UAAU,SAC9C,SAAAyF,EAAAA,KAAC,MAAA,CACC,UAAWC,GAAAA,GACT,+FACAtH,EAAA,EAEF,GAAG,uCAEH,SAAA,CAAAqH,EAAAA,KAAC,MAAA,CACC,UAAWjJ,EACT,gEAIA,sDACA8D,EAAiB,kBAAoB,aAAA,EAGtC,SAAA,CAAAA,GAAkBtC,EACjBrB,EAAAA,IAACgJ,GAAAA,OAAA,CACC,UAAWzF,IAAc,OACzB,SAAW0F,GAAYzF,GAAayF,EAAU,OAAS,MAAM,EAC7D,WAAW,GACX,WAAU,GACV,SAAQ,GACR,QAAS1F,IAAc,OAAS,YAAc,YAC9C,KAAM,CACJ,YAAavD,EAAAA,IAACkJ,GAAAA,WAAA,CAAW,UAAU,0FAAA,CAA2F,EAC9H,cAAelJ,EAAAA,IAACmJ,GAAAA,SAAA,CAAS,UAAU,0FAAA,CAA2F,CAAA,CAChI,CAAA,EAEA,KACJL,EAAAA,KAAC,MAAA,CAAI,UAAU,4BACZ,SAAA,CAAAnH,KAAuB,CACtB,OAAQI,EAAU,QAClB,MAAArB,EACA,SAAAC,EACA,SAAAK,EACA,WAAAF,EACA,UAAAyC,CAAA,CACD,EACAA,IAAc,QAAUzC,GAAcO,GACrCrB,EAAAA,IAAC,OAAA,CAAK,UAAU,qGACd,SAAAA,EAAAA,IAACoJ,EAAA,CAAQ,MAAM,UACb,SAAApJ,EAAAA,IAAC,SAAA,CACC,KAAK,SACL,GAAG,+BACH,QAAS,IAAM0D,EAAqB,EAAI,EACxC,UAAW7D,EACT,oDACA,uFAAA,EAGF,SAAAG,EAAAA,IAACF,GAAA,CAAQ,SAAU,EAAA,CAAI,CAAA,CAAA,EAE3B,CAAA,CACF,EAEDyD,IAAc,OACbuF,EAAAA,KAAAO,EAAAA,SAAA,CACE,SAAA,CAAArJ,EAAAA,IAACoJ,EAAA,CAAQ,MAAM,eACb,SAAApJ,EAAAA,IAAC,SAAA,CACC,KAAK,SACL,GAAG,+BACH,QAAS,IAAM2C,EAAe,EAAK,EACnC,UAAWgF,EAEX,SAAA3H,EAAAA,IAACM,GAAA,CAA0B,SAAU,EAAA,CAAI,CAAA,CAAA,EAE7C,EAEAN,EAAAA,IAACoJ,EAAA,CAAQ,MAAM,aACb,SAAApJ,EAAAA,IAAC,SAAA,CACC,KAAK,SACL,GAAG,iCACH,QAAS,IAAM2C,EAAe,EAAI,EAClC,UAAWgF,EAEX,SAAA3H,EAAAA,IAACK,GAAA,CAA4B,SAAU,EAAA,CAAI,CAAA,CAAA,CAC7C,CACF,CAAA,CAAA,CACF,EACE,KACHkD,IAAc,QAAUlC,EACvBrB,EAAAA,IAACoJ,EAAA,CAAQ,MAAM,SACb,SAAApJ,EAAAA,IAAC,SAAA,CACC,KAAK,SACL,GAAG,8BACH,QAAS+G,EACT,UAAWY,EAEX,SAAA3H,EAAAA,IAACQ,GAAA,CAAoB,SAAU,EAAA,CAAI,CAAA,CAAA,EAEvC,EACE,KACHK,IAAa0C,IAAc,QAAUlC,EACpCrB,EAAAA,IAACoJ,EAAA,CACC,MAAO9G,IAAgB,KAAO,YAAc,aAE5C,SAAAtC,EAAAA,IAAC,SAAA,CACC,KAAK,SACL,GAAG,6BACH,QAAS,IACPwC,GAAeF,IAAgB,KAAO,UAAY,IAAI,EAExD,UAAWqF,EAEV,SAAArF,IAAgB,KACftC,EAAAA,IAACE,GAAA,CAAqB,SAAU,GAAI,EAEpCF,EAAAA,IAACO,GAAA,CAAsB,SAAU,EAAA,CAAI,CAAA,CAAA,CAEzC,CAAA,EAEA,MACFS,IAAa,UAAYA,IAAa,SAAWE,GACjDlB,MAACoJ,EAAA,CAAQ,MAAM,OACb,SAAApJ,EAAAA,IAAC,SAAA,CACC,KAAK,SACL,GAAG,4BACH,QAAS4H,GACT,UAAWD,EAEX,SAAA3H,EAAAA,IAACC,GAAA,CAAwB,SAAU,EAAA,CAAI,CAAA,CAAA,EAE3C,EACE,MACFe,IAAa,UAAYA,IAAa,SACtCG,GACAnB,MAACoJ,EAAA,CAAQ,MAAM,WACb,SAAApJ,EAAAA,IAAC,SAAA,CACC,KAAK,SACL,GAAG,gCACH,QAASuI,GACT,UAAWZ,EAEX,SAAA3H,EAAAA,IAACG,GAAA,CAAwB,SAAU,EAAA,CAAI,CAAA,CAAA,EAE3C,EACE,KACHS,GACCZ,EAAAA,IAACoJ,EAAA,CAAQ,MAAM,aACb,SAAApJ,EAAAA,IAAC,SAAA,CACC,QAAS4D,GACT,KAAK,SACL,GAAG,6BACH,UAAW+D,EAEX,SAAA3H,EAAAA,IAACI,GAAA,CAAsB,SAAU,EAAA,CAAI,CAAA,CAAA,EAEzC,EACE,IAAA,CAAA,CACN,CAAA,CAAA,CAAA,EAGDmD,IAAc,QAAUvC,IAAa,aACnC,MAAA,CACC,SAAAhB,EAAAA,IAACsJ,GAAAA,eAAA,CACC,aAAcjG,GAAkB,OAChC,YAAAX,GACA,UAAW,IAAMC,EAAgB4G,GAAS,CAACA,CAAI,EAC/C,WAAY,EAAQzI,EACpB,WAAYyB,KAAU,OACtB,MAAO,CACL,OAAQc,GAAkB,OAAS,QAAUtC,CAAA,EAE/C,MAAAL,EACA,SAAAC,EACA,qBAAA+C,EACA,kBAAAD,EAAA,CAAA,EAEJ,EAEAzD,EAAAA,IAACwJ,GAAAA,QAAA,CACC,OAAQnG,GAAkB,OAAS,QAAUtC,EAC7C,SAAAC,EACA,MAAAN,EACA,SAAU+G,GACV,MAAOnF,EACP,QAASuE,GACT,QAAS,CACP,SAAU,GACV,QAAS,GACT,WAAY,0CACZ,cAAe,GACf,SAAU,CAAC/F,CAAA,CACb,CAAA,CACF,CAAA,CAAA,EAGN,CAEJ"}