@web-noise/core 0.0.12-fix3 → 0.0.12-fix4

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 +1 @@
1
- {"mappings":"IY+LG,EC3KA,C,Q,O,C,C,Q,C,K,mB,A,Q,M,iB,A,Q,a,C,C,Y,C,C,W,C,C,e,C,C,U,C,K,O,A,Q,gB,C,K,W,A,Q,W,C,C,c,C,C,iB,C,K,gB,A,Q,Y,C,C,a,C,K,gB,A,O,Q,A,Q,U,C,K,iB,A,O,kB,A,Q,qB,C,C,W,C,C,oB,C,C,oB,C,C,U,C,K,W,A,Q,U,C,K,S,A,Q,qB,C,C,e,C,K,kB,A,Q,W,C,C,S,C,C,U,C,K,e,A,Q,gB,C,K,c,A,O,0B,A,Q,Q,C,C,Q,C,K,iB,A,O,yC,A,O,kB,A,O,Y,A,O,iB,A,Q,gB,C,C,e,C,C,4B,C,K,gB,A,O,c,A,O,mB,A,O,kC,A,O,gB,A,O,gB,A,O,qB,A,O,oC,A,O,Q,A,Q,wB,C,K,c,A,Q,M,W,A,O,4B,A,Q,iB,C,K,e,C,S,E,C,C,C,C,C,C,C,E,O,c,C,E,E,C,I,E,I,E,W,C,E,a,C,C,E,C,IJZS,EAAA,E,E,C,E,E,E,Q,I,G,E,E,U,I,I,E,E,a,I,I,E,E,Q,I,I,E,E,gB,I,I,E,E,a,I,I,E,E,c,I,I,E,E,S,I,I,E,E,S,I,I,E,E,S,I,I,E,E,e,I,I,E,E,iB,I,I,E,E,mB,I,I,E,E,qB,I,I,E,E,Y,I,I,E,E,c,I,I,E,E,iB,I,INDZ,IAAM,EAAa,AAAA,EAAO,GAAqB,CAA/C;;WAEa,EAAA,CAAC,CAAA,MAAE,CAAK,CAAE,GAAK,EAAM,MAAM,CAAC,KAAK,CAAjC;;;;;cAKG,EAAA,CAAC,CAAA,MAAE,CAAK,CAAE,GAAK,EAAM,MAAM,CAAC,UAAU,CAAtC;;;;AAIf,CAAA,CAEK,EAAa,AAAA,EAAO,GAAqB,CAA/C;cACgB,EAAA,CAAC,CAAA,MAAE,CAAK,CAAE,GAAK,EAAM,MAAM,CAAC,UAAU,CAAtC;8BACgB,EAAA,CAAC,CAAA,MAAE,CAAK,CAAE,GAAK,EAAM,MAAM,CAAC,UAAU,CAAtC;;;;;;AAM/B,CAAA,CAEK,EAAc,AAAA,EAAO,EAA4B,CAAvD;;;;;AAKC,CAAA,CAOY,EAAQ,CAAC,CAAA,SAAE,CAAQ,CAAA,QAAE,CAAO,CAAE,GAAG,EAAmB,IAC/D,IAAM,ECvCC,AAAA,IDqDP,OAZ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","sources":["<anon>","packages/core/components.ts","packages/core/src/components/index.ts","packages/core/src/components/Modal.tsx","packages/core/src/hooks/useTheme.ts","packages/core/src/components/Checker.tsx","packages/core/index.ts","packages/core/src/components/App.tsx","packages/core/src/store/index.ts","packages/core/src/constants.ts","packages/core/src/helpers/generateNodeId.ts","packages/core/src/store/nodesStore.ts","packages/core/src/store/history/index.ts","packages/core/src/store/audioPatch/index.ts","packages/core/src/store/audioPatch/compareGraphs.ts","packages/core/src/store/projectStore.ts","packages/core/src/helpers/projectFile.ts","packages/core/src/styles.ts","packages/core/src/theme.ts","packages/core/src/components/Editor/index.tsx","packages/core/src/components/contextMenu/EdgeContextMenu.tsx","packages/core/src/components/contextMenu/styles.tsx","packages/core/src/components/contextMenu/EditorContextMenu.tsx","packages/core/src/components/AddNode/index.tsx","packages/core/src/components/AddNode/Filters.tsx","packages/core/src/components/AddNode/Plugins.tsx","packages/core/src/components/UploadPatch.tsx","packages/core/src/components/UploadProject.tsx","packages/core/src/components/UploadAudio.tsx","packages/core/src/lib/index.ts","packages/core/src/lib/hooks/useWorker.ts","packages/core/src/lib/hooks/useMessageChannel.ts","packages/core/src/lib/helpers.ts","packages/core/src/components/contextMenu/NodeContextMenu.tsx","packages/core/src/components/ControlPanel/index.tsx","packages/core/src/components/ControlPanel/ControlPanelItem.tsx","packages/core/src/hooks/useAudioNode.ts","packages/core/src/hooks/useNode.ts","packages/core/src/components/ControlPanel/styles.tsx","packages/core/src/components/Node/index.tsx","packages/core/src/components/EditableLabel.tsx","packages/core/src/components/NodeInfoModal.tsx","packages/core/src/components/Help/index.tsx","packages/core/src/components/Help/HelpModal.tsx","node_modules/@parcel/runtime-js/lib/bundles/runtime-0b4bd901285c62b5.js","packages/core/src/components/ResumeContext.tsx","packages/core/src/components/ToggleMinimap.tsx","packages/core/src/components/Wire.tsx","packages/core/src/components/RadioGroup.tsx","packages/core/src/components/Input.tsx","packages/core/src/components/DropdownInput.tsx","packages/core/src/components/ColorInput.tsx","packages/core/src/components/NumberInput.tsx","packages/core/src/components/Button.tsx","packages/core/src/components/Select.tsx","packages/core/src/components/Slider.tsx","packages/core/src/components/SplineEditor.tsx","packages/core/src/components/NodeConfig.tsx"],"sourcesContent":["import {jsx as $qQ8Y1$jsx, jsxs as $qQ8Y1$jsxs, Fragment as $qQ8Y1$Fragment} from \"react/jsx-runtime\";\nimport $qQ8Y1$emotionstyled from \"@emotion/styled\";\nimport {useEffect as $qQ8Y1$useEffect, useState as $qQ8Y1$useState, version as $qQ8Y1$version, useMemo as $qQ8Y1$useMemo, useCallback as $qQ8Y1$useCallback, useRef as $qQ8Y1$useRef} from \"react\";\nimport {createPortal as $qQ8Y1$createPortal} from \"react-dom\";\nimport {MdClose as $qQ8Y1$MdClose, MdDragHandle as $qQ8Y1$MdDragHandle, MdSettings as $qQ8Y1$MdSettings, MdInfoOutline as $qQ8Y1$MdInfoOutline} from \"react-icons/md\";\nimport {useTheme as $qQ8Y1$useTheme, withTheme as $qQ8Y1$withTheme, ThemeProvider as $qQ8Y1$ThemeProvider, Global as $qQ8Y1$Global, css as $qQ8Y1$css} from \"@emotion/react\";\nimport {nanoid as $qQ8Y1$nanoid} from \"nanoid\";\nimport {FaPlus as $qQ8Y1$FaPlus} from \"react-icons/fa6\";\nimport {registerFetcher as $qQ8Y1$registerFetcher} from \"@web-noise/fetch\";\nimport $qQ8Y1$reactflow, {getConnectedEdges as $qQ8Y1$getConnectedEdges, addEdge as $qQ8Y1$addEdge, applyNodeChanges as $qQ8Y1$applyNodeChanges, applyEdgeChanges as $qQ8Y1$applyEdgeChanges, useOnViewportChange as $qQ8Y1$useOnViewportChange, Background as $qQ8Y1$Background, BackgroundVariant as $qQ8Y1$BackgroundVariant, MiniMap as $qQ8Y1$MiniMap, Controls as $qQ8Y1$Controls, ReactFlowProvider as $qQ8Y1$ReactFlowProvider, useReactFlow as $qQ8Y1$useReactFlow, Position as $qQ8Y1$Position, Handle as $qQ8Y1$Handle, ControlButton as $qQ8Y1$ControlButton, getBezierPath as $qQ8Y1$getBezierPath} from \"reactflow\";\nimport {create as $qQ8Y1$create} from \"zustand\";\nimport {setAudioNodeTypes as $qQ8Y1$setAudioNodeTypes, createPatch as $qQ8Y1$createPatch} from \"@web-noise/patch\";\nimport {reverse as $qQ8Y1$reverse, patch as $qQ8Y1$patch, create as $qQ8Y1$create1} from \"jsondiffpatch\";\nimport {injectGlobal as $qQ8Y1$injectGlobal} from \"@emotion/css\";\nimport \"reactflow/dist/style.css\";\nimport {useContextMenu as $qQ8Y1$useContextMenu, Item as $qQ8Y1$Item, Menu as $qQ8Y1$Menu, Separator as $qQ8Y1$Separator} from \"react-contexify\";\nimport \"react-contexify/dist/ReactContexify.css\";\nimport $qQ8Y1$jsfiledownload from \"js-file-download\";\nimport $qQ8Y1$hotkeysjs from \"hotkeys-js\";\nimport {FileDrop as $qQ8Y1$FileDrop} from \"react-file-drop\";\nimport {FaFileUpload as $qQ8Y1$FaFileUpload, FaQuestion as $qQ8Y1$FaQuestion, FaVolumeOff as $qQ8Y1$FaVolumeOff, FaMap as $qQ8Y1$FaMap, FaRegMap as $qQ8Y1$FaRegMap, FaRegArrowAltCircleRight as $qQ8Y1$FaRegArrowAltCircleRight} from \"react-icons/fa\";\nimport {Resizable as $qQ8Y1$Resizable} from \"re-resizable\";\nimport $qQ8Y1$reactgridlayout from \"react-grid-layout\";\nimport \"react-grid-layout/css/styles.css\";\nimport {AiFillLock as $qQ8Y1$AiFillLock, AiFillUnlock as $qQ8Y1$AiFillUnlock} from \"react-icons/ai\";\nimport {RxDashboard as $qQ8Y1$RxDashboard} from \"react-icons/rx\";\nimport $qQ8Y1$reactmoderndrawer from \"react-modern-drawer\";\nimport \"react-modern-drawer/dist/index.css\";\nimport {marked as $qQ8Y1$marked} from \"marked\";\nimport {useThrottledCallback as $qQ8Y1$useThrottledCallback} from \"use-debounce\";\nimport $qQ8Y1$rcslider from \"rc-slider\";\nimport \"rc-slider/assets/index.css\";\nimport {CanvasSpliner as $qQ8Y1$CanvasSpliner} from \"CanvasSpliner\";\n\n\nfunction $parcel$export(e, n, v, s) {\n Object.defineProperty(e, n, {get: v, set: s, enumerable: true, configurable: true});\n}\n\nfunction $parcel$interopDefault(a) {\n return a && a.__esModule ? a.default : a;\n}\nvar $d6863d1593a90046$exports = {};\n\n$parcel$export($d6863d1593a90046$exports, \"Modal\", () => $6c9029bae1fda307$export$2b77a92f1a5ad772);\n$parcel$export($d6863d1593a90046$exports, \"Checker\", () => $22dd0cb4a70b40fd$export$8ecd240bc8faaeeb);\n$parcel$export($d6863d1593a90046$exports, \"RadioGroup\", () => $03fc2a9d056cdbb9$export$a98f0dcb43a68a25);\n$parcel$export($d6863d1593a90046$exports, \"Input\", () => $f2626dfcf20c9281$export$f5b8910cec6cf069);\n$parcel$export($d6863d1593a90046$exports, \"DropdownInput\", () => $9f4596934c8f0841$export$7a40489edcbfb3a1);\n$parcel$export($d6863d1593a90046$exports, \"ColorInput\", () => $e1bb97faa82daf8d$export$5a1d7ca0a925d9c2);\n$parcel$export($d6863d1593a90046$exports, \"NumberInput\", () => $9746117513cdf0c6$export$6bf0cd3a219bbade);\n$parcel$export($d6863d1593a90046$exports, \"Button\", () => $fd88f4b57ca7d92f$export$353f5b6fc5456de1);\n$parcel$export($d6863d1593a90046$exports, \"Select\", () => $6af7bd545fe585cb$export$ef9b1a59e592288f);\n$parcel$export($d6863d1593a90046$exports, \"Slider\", () => $b36c9ac3a0f9fc74$export$472062a354075cee);\n$parcel$export($d6863d1593a90046$exports, \"SplineEditor\", () => $03443e7f1f47da42$export$2bf7c2638a145e5c);\n$parcel$export($d6863d1593a90046$exports, \"ConfigRowLabel\", () => $9d9e44a3523295ca$export$555ece15b74b7abc);\n$parcel$export($d6863d1593a90046$exports, \"ConfigRowControl\", () => $9d9e44a3523295ca$export$ef9ca7b440c0032c);\n$parcel$export($d6863d1593a90046$exports, \"ConfigRowSeparator\", () => $9d9e44a3523295ca$export$bd1dc14d6df7044e);\n$parcel$export($d6863d1593a90046$exports, \"ConfigRow\", () => $9d9e44a3523295ca$export$d56900fc3755b916);\n$parcel$export($d6863d1593a90046$exports, \"ConfigPanel\", () => $9d9e44a3523295ca$export$aac584ace4a7b830);\n$parcel$export($d6863d1593a90046$exports, \"ConfigRowInner\", () => $9d9e44a3523295ca$export$edaba703bd8b8dfa);\n\n\n\n\n\n\nconst $aa2521e46fde4290$var$useTheme = ()=>{\n return (0, $qQ8Y1$useTheme)();\n};\nvar $aa2521e46fde4290$export$2e2bcd8739ae039 = $aa2521e46fde4290$var$useTheme;\n\n\nconst $6c9029bae1fda307$var$ModalOuter = (0, $qQ8Y1$emotionstyled).div`\n position: fixed;\n z-index: ${({ theme: theme })=>theme.zIndex.modal};\n width: 100%;\n height: 100%;\n top: 0;\n left: 0;\n background: ${({ theme: theme })=>theme.colors.elevation3}cc;\n display: flex;\n align-items: center;\n justify-content: center;\n`;\nconst $6c9029bae1fda307$var$ModalInner = (0, $qQ8Y1$emotionstyled).div`\n background: ${({ theme: theme })=>theme.colors.elevation2};\n box-shadow: 1px 1px 1px 1px ${({ theme: theme })=>theme.colors.elevation1};\n color: white;\n width: 70%;\n height: 80%;\n overflow-y: scroll;\n position: relative;\n`;\nconst $6c9029bae1fda307$var$ModalCloser = (0, $qQ8Y1$emotionstyled)((0, $qQ8Y1$MdClose))`\n position: absolute;\n top: 0.2rem;\n right: 0.2rem;\n cursor: pointer;\n`;\nconst $6c9029bae1fda307$export$2b77a92f1a5ad772 = ({ children: children, onClose: onClose, ...props })=>{\n const theme = (0, $aa2521e46fde4290$export$2e2bcd8739ae039)();\n (0, $qQ8Y1$useEffect)(()=>{\n const escHandler = (event)=>{\n if (event.key === \"Escape\") onClose?.();\n };\n document.addEventListener(\"keydown\", escHandler);\n return ()=>{\n document.removeEventListener(\"keydown\", escHandler);\n };\n }, [\n onClose\n ]);\n return /*#__PURE__*/ (0, $qQ8Y1$createPortal)((0, $qQ8Y1$jsx)($6c9029bae1fda307$var$ModalOuter, {\n theme: theme,\n onClick: onClose,\n children: (0, $qQ8Y1$jsxs)($6c9029bae1fda307$var$ModalInner, {\n ...props,\n onClick: (e)=>{\n e.stopPropagation();\n },\n theme: theme,\n children: [\n children,\n (0, $qQ8Y1$jsx)($6c9029bae1fda307$var$ModalCloser, {\n theme: theme,\n onClick: onClose\n })\n ]\n })\n }), document.body);\n};\nvar $6c9029bae1fda307$export$2e2bcd8739ae039 = $6c9029bae1fda307$export$2b77a92f1a5ad772;\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nconst $cfbf5bba42d581f6$export$956b3cf15d7c363 = \"web-noise-drag-handle\";\nconst $cfbf5bba42d581f6$export$21d634b1d5d9bee3 = `.${$cfbf5bba42d581f6$export$956b3cf15d7c363}`;\nconst $cfbf5bba42d581f6$export$9f05d3e6ade4c09e = {\n rowHeight: 10,\n cols: 4\n};\nvar $cfbf5bba42d581f6$export$b0b7b95ee465c83c;\n(function(PortType) {\n PortType[\"Gate\"] = \"gate\";\n PortType[\"Number\"] = \"number\";\n PortType[\"Audio\"] = \"audio\";\n PortType[\"Any\"] = \"any\";\n})($cfbf5bba42d581f6$export$b0b7b95ee465c83c || ($cfbf5bba42d581f6$export$b0b7b95ee465c83c = {}));\n\n\nconst $bc626fd1435da0c4$var$generateNodeId = (node)=>{\n const random = +new Date() + Math.floor(Math.random() * 1000);\n if (!node?.type) return random.toString();\n return `${node.type}-${random}`;\n};\nvar $bc626fd1435da0c4$export$2e2bcd8739ae039 = $bc626fd1435da0c4$var$generateNodeId;\n\n\n\n\nconst $7f6466bb2c846f7d$var$nodesStateCreator = (set, get)=>({\n nodes: [],\n edges: [],\n onNodesChange: (changes)=>{\n set(({ nodes: nodes })=>({\n nodes: (0, $qQ8Y1$applyNodeChanges)(changes, nodes).map((node)=>({\n dragHandle: (0, $cfbf5bba42d581f6$export$21d634b1d5d9bee3),\n ...node\n }))\n }));\n },\n onEdgesChange: (changes)=>{\n set(({ edges: edges })=>({\n edges: (0, $qQ8Y1$applyEdgeChanges)(changes, edges)\n }));\n },\n onConnect: (connection)=>{\n set(({ edges: edges })=>({\n edges: (0, $qQ8Y1$addEdge)(connection, edges)\n }));\n },\n addNode: (node)=>{\n set(({ nodes: nodes })=>({\n nodes: nodes.concat(node)\n }));\n },\n setNodes: (nodes)=>{\n set({\n nodes: nodes\n });\n },\n setEdges: (edges)=>{\n set({\n edges: edges\n });\n },\n setNodesAndEdges: ({ nodes: nodes, edges: edges })=>{\n set({\n nodes: nodes,\n edges: edges\n });\n },\n getNodesAndEdges: ()=>{\n const { nodes: nodes, edges: edges } = get();\n return {\n nodes: nodes,\n edges: edges\n };\n },\n clearElements: ()=>{\n set({\n nodes: [],\n edges: []\n });\n },\n getNode: (id)=>{\n const { nodes: nodes } = get();\n const node = nodes.find((node)=>node.id === id);\n return node || null;\n },\n updateNodeData: (id, data)=>{\n set(({ nodes: nodes })=>{\n return {\n nodes: nodes.map((node)=>{\n if (node.id === id) return {\n ...node,\n data: {\n ...node.data,\n ...data\n }\n };\n return node;\n })\n };\n });\n },\n nodeTypes: {},\n setNodeTypes: (nodeTypes)=>set({\n nodeTypes: nodeTypes\n })\n });\nvar $7f6466bb2c846f7d$export$2e2bcd8739ae039 = $7f6466bb2c846f7d$var$nodesStateCreator;\n\n\n\nconst $cde61d7f4dc8a447$var$cloneObject = (input)=>{\n return JSON.parse(JSON.stringify(input));\n};\nconst $cde61d7f4dc8a447$export$b1b92d12d1c2ae0e = (set, get)=>({\n history: {\n maxHistoryLength: 5,\n buffer: [],\n pointer: 0,\n skipCollect: false,\n push: (changes)=>{\n const { history: history } = get();\n const { maxHistoryLength: maxHistoryLength, skipCollect: skipCollect } = history;\n if (skipCollect) {\n set({\n history: {\n ...history,\n skipCollect: false\n }\n });\n return;\n }\n set(({ history: history })=>{\n if (!history) return {};\n const { buffer: buffer, pointer: pointer } = history;\n const newBuffer = buffer.slice(Math.max(pointer - maxHistoryLength + 1, 0), pointer);\n return {\n history: {\n ...history,\n buffer: [\n ...newBuffer,\n changes\n ],\n pointer: Math.min(pointer + 1, maxHistoryLength)\n }\n };\n });\n },\n back: ()=>{\n const { nodes: nodes, edges: edges, controlPanel: controlPanel, history: history } = get();\n const { buffer: buffer, pointer: pointer } = history;\n const patchData = buffer[pointer - 1];\n if (!patchData) return;\n const reversedPatchData = $qQ8Y1$reverse(patchData);\n if (!reversedPatchData) return;\n const updates = $cde61d7f4dc8a447$var$cloneObject({\n nodes: nodes,\n edges: edges,\n controlPanel: controlPanel\n });\n const patch = $qQ8Y1$patch(updates, reversedPatchData);\n set({\n ...patch,\n history: {\n ...history,\n pointer: pointer - 1,\n skipCollect: true\n }\n });\n },\n forward: ()=>{\n const { nodes: nodes, edges: edges, controlPanel: controlPanel, history: history } = get();\n const { buffer: buffer, pointer: pointer } = history;\n const patchData = buffer[pointer];\n if (!patchData) return;\n const updates = $cde61d7f4dc8a447$var$cloneObject({\n nodes: nodes,\n edges: edges,\n controlPanel: controlPanel\n });\n const patch = $qQ8Y1$patch(updates, patchData);\n set({\n ...patch,\n history: {\n ...history,\n pointer: pointer + 1,\n skipCollect: true\n }\n });\n },\n // @TODO: remove this method and store history per file\n clear: ()=>{\n const { history: history } = get();\n set({\n history: {\n ...history,\n buffer: [],\n pointer: 0,\n skipCollect: true\n }\n });\n }\n }\n });\nconst $cde61d7f4dc8a447$var$COLLECT_CHANGES_DEBOUNCE_TIME = 500;\nconst $cde61d7f4dc8a447$export$4e64751394766316 = (set, get)=>{\n const jsondiffpatchInstance = $qQ8Y1$create1({\n propertyFilter: (name, context)=>{\n //@TODO: rework this function, find better solution\n if (context.parent?.parent?.childName === \"controlPanel\") return true;\n if (// @ts-ignore\n [\n \"data\",\n \"position\",\n \"controlPanel\"\n ].includes(context.parent?.childName)) return true;\n return [\n \"controlPanel\",\n \"size\",\n \"edges\",\n \"nodes\",\n \"data\",\n \"label\",\n \"config\",\n \"values\",\n \"position\",\n \"x\",\n \"y\"\n ].includes(name);\n }\n });\n let oldState = get();\n let timer;\n return (state, prevState)=>{\n if (state.currentFileIndex !== prevState.currentFileIndex) get().history.clear();\n clearTimeout(timer);\n if (!oldState) oldState = prevState;\n timer = setTimeout(()=>{\n const changes = jsondiffpatchInstance.diff(oldState, state);\n oldState = null;\n if (changes) get().history.push(changes);\n }, $cde61d7f4dc8a447$var$COLLECT_CHANGES_DEBOUNCE_TIME);\n };\n};\nconst $cde61d7f4dc8a447$var$history = (config)=>(set, get, api)=>{\n const collectChanges = $cde61d7f4dc8a447$export$4e64751394766316(set, get);\n api.subscribe(collectChanges);\n return config((...args)=>set(...args), get, api);\n };\nvar $cde61d7f4dc8a447$export$2e2bcd8739ae039 = $cde61d7f4dc8a447$var$history;\n\n\n\nconst $adad5cc6758973b9$export$e364ea0c1dfb25e5 = (left, right)=>{\n const setLeft = new Set(left.map((item)=>item.id));\n const setRight = new Set(right.map((item)=>item.id));\n const added = right.filter((item)=>!setLeft.has(item.id));\n const removed = left.filter((item)=>!setRight.has(item.id));\n return {\n added: added,\n removed: removed\n };\n};\n\n\nconst $cdfdbc6478cadc33$export$62647b40ff8aed70 = (set, get)=>({\n patch: (0, $qQ8Y1$createPatch)(),\n nodesState: {}\n });\nconst $cdfdbc6478cadc33$var$audioPatch = (config)=>(set, get, api)=>{\n api.subscribe(async (state, prevState)=>{});\n const promises = new Set();\n let currentState = {\n ...get(),\n nodes: [],\n edges: []\n };\n return config(async (...args)=>{\n const oldState = get();\n const [storeChanges] = args;\n //@ts-ignore\n const newState = {\n ...currentState,\n ...typeof storeChanges === \"function\" ? storeChanges({\n ...currentState\n }) : storeChanges\n };\n const nodeChanges = (0, $adad5cc6758973b9$export$e364ea0c1dfb25e5)(currentState.nodes, newState.nodes);\n const edgeChanges = (0, $adad5cc6758973b9$export$e364ea0c1dfb25e5)(currentState.edges, newState.edges);\n //@ts-ignore\n currentState = newState;\n const newNodes = nodeChanges.added;\n const newEdges = edgeChanges.added;\n const removedEdges = edgeChanges.removed;\n const removedNodes = nodeChanges.removed;\n const { patch: patch } = oldState;\n if (newNodes.length) {\n const promise = patch.registerAudioNodes(//@ts-ignore\n newNodes);\n promises.add(promise);\n await promise;\n promises.delete(promise);\n }\n if (!(newEdges.length || removedEdges.length || removedNodes.length)) {\n set(...args);\n return;\n }\n if (promises.size) try {\n await Promise.all([\n ...promises.values()\n ]);\n } catch (e) {\n console.log(\"some error\", e);\n }\n if (newEdges.length) patch.registerAudioConnections(//@ts-ignore\n newEdges);\n if (removedEdges.length) //@ts-ignore\n patch.unregisterAudioConnections(removedEdges);\n if (removedNodes.length) //@ts-ignore\n patch.unregisterAudioNodes(removedNodes);\n set(...args);\n }, get, api);\n };\nvar $cdfdbc6478cadc33$export$2e2bcd8739ae039 = $cdfdbc6478cadc33$var$audioPatch;\n\n\nconst $474db3030f688e41$export$e698b79c63b74136 = (file)=>!(\"type\" in file) || file.type === \"patch\";\nconst $474db3030f688e41$export$31c2336f657dc59f = (file)=>file.type === \"audio\";\n\n\nconst $0afc2f6b9c39abc8$var$projectStateCreator = (set, get)=>({\n project: {\n files: []\n },\n setProject (project) {\n set({\n project: project,\n currentFileIndex: 0\n });\n },\n getProject () {\n return get().project;\n },\n pullEditorChanges () {\n const { getEditorState: getEditorState, currentFileIndex: currentFileIndex, updateFileContent: updateFileContent, project: project } = get();\n const currentFile = project.files[currentFileIndex];\n if ((0, $474db3030f688e41$export$31c2336f657dc59f)(currentFile)) return;\n updateFileContent(currentFileIndex, {\n ...currentFile,\n file: getEditorState()\n });\n },\n syncEditorWithCurrentFile: ()=>{\n const { currentFileIndex: currentFileIndex, setEditorState: setEditorState, project: project } = get();\n const currentFile = project.files[currentFileIndex];\n if (currentFile.type === \"audio\") {\n console.log(\"audio file. skipping\");\n return;\n }\n setEditorState(currentFile.file);\n },\n currentFileIndex: 0,\n setCurrentFileIndex (newFileIndex) {\n const { currentFileIndex: currentFileIndex } = get();\n if (newFileIndex === currentFileIndex) return;\n set({\n currentFileIndex: newFileIndex\n });\n },\n updateFileContent (index, file) {\n const { project: project } = get();\n set({\n project: {\n ...project,\n files: project.files.map((f, i)=>{\n if (i === index) return {\n // @TODO check again if merging is really needed here\n ...f,\n ...file\n };\n return f;\n })\n }\n });\n },\n updateFileName (index, fileName) {\n const { project: project } = get();\n set({\n project: {\n ...project,\n files: project.files.map((f, i)=>{\n if (i === index) return {\n ...f,\n name: fileName\n };\n return f;\n })\n }\n });\n },\n addFile (file) {\n const { project: project } = get();\n const files = [\n ...project.files,\n file\n ];\n set({\n project: {\n ...project,\n files: files\n }\n });\n },\n deleteFile: (fileIndex)=>{\n const { project: project, currentFileIndex: currentFileIndex } = get();\n set({\n project: {\n ...project,\n files: project.files.filter((_, index)=>fileIndex !== index)\n }\n });\n if (fileIndex <= currentFileIndex) set({\n currentFileIndex: currentFileIndex - 1\n });\n }\n });\nvar $0afc2f6b9c39abc8$export$2e2bcd8739ae039 = $0afc2f6b9c39abc8$var$projectStateCreator;\n\n\nconst $e44921bed281a717$export$34c5bc865219488e = (...args)=>{\n const [set, get] = args;\n return {\n ...(0, $7f6466bb2c846f7d$export$2e2bcd8739ae039)(...args),\n ...(0, $cde61d7f4dc8a447$export$b1b92d12d1c2ae0e)(...args),\n ...(0, $cdfdbc6478cadc33$export$62647b40ff8aed70)(...args),\n ...(0, $0afc2f6b9c39abc8$export$2e2bcd8739ae039)(...args),\n setGraph: async ({ nodes: nodes, edges: edges })=>{\n const { patch: patch, createNodes: createNodes, createEdges: createEdges, setNodesAndEdges: setNodesAndEdges, nodes: activeNodes, edges: activeEdges } = get();\n setNodesAndEdges({\n nodes: [],\n edges: []\n });\n await createNodes(nodes);\n createEdges(edges);\n },\n clearGraph: ()=>{\n const { setGraph: setGraph } = get();\n setGraph({\n nodes: [],\n edges: []\n });\n },\n createNodes: async (nodes)=>{\n const { createNode: createNode } = get();\n await Promise.all(nodes.map((node)=>createNode(node)));\n },\n createNode: (nodeData)=>{\n const { addNode: addNode, nodesConfiguration: nodesConfiguration } = get();\n const { type: type, id: id, data: data } = nodeData;\n if (typeof type === \"undefined\") throw new Error(`node type is not defined for node: ${id}`);\n const node = {\n ...nodeData,\n data: {\n ...data,\n config: {\n ...nodesConfiguration[type]?.defaultConfig,\n ...data?.config\n }\n }\n };\n addNode(node);\n },\n removeNode: (node)=>get().removeNodes([\n node\n ]),\n removeNodes: (nodes)=>{\n const { edges: edges, nodes: currentNodes, onNodesDelete: onNodesDelete, removeEdges: removeEdges, removeNodesFromControlPanel: removeNodesFromControlPanel } = get();\n const parentNodeIds = nodes.map(({ id: id })=>id);\n const children = currentNodes.filter(({ parentNode: parentNode })=>parentNode && parentNodeIds.includes(parentNode));\n const resultingNodes = [\n ...nodes,\n ...children\n ];\n removeNodesFromControlPanel(resultingNodes);\n const connectedEdges = (0, $qQ8Y1$getConnectedEdges)(resultingNodes, edges);\n removeEdges(connectedEdges);\n onNodesDelete(resultingNodes);\n const nodeIds = resultingNodes.map(({ id: id })=>id);\n set({\n nodes: currentNodes.filter(({ id: id })=>!nodeIds.includes(id))\n });\n },\n removeEdges: (edges)=>{\n const { edges: currentEdges, onEdgesDelete: onEdgesDelete } = get();\n const edgeIds = edges.map(({ id: id })=>id);\n onEdgesDelete(edges);\n set({\n edges: currentEdges.filter(({ id: id })=>!edgeIds.includes(id))\n });\n },\n createEdges: (newEdges)=>{\n const { patch: patch, edges: edges, setEdges: setEdges } = get();\n setEdges(newEdges);\n },\n onConnect: async (connection)=>{\n const { edges: edges, createEdges: createEdges } = get();\n const newEdges = (0, $qQ8Y1$addEdge)(connection, edges);\n createEdges(newEdges);\n },\n onEdgesDelete: (edges)=>{\n const { patch: patch } = get();\n },\n onNodesDelete: async (nodes)=>{\n const { removeNodesFromControlPanel: removeNodesFromControlPanel, patch: patch } = get();\n removeNodesFromControlPanel(nodes);\n },\n plugins: [],\n setPlugins: async (plugins)=>{\n const { setNodeTypes: setNodeTypes } = get();\n set({\n plugins: plugins\n });\n const nodesConf = plugins.reduce((acc, plugin)=>{\n return {\n ...acc,\n ...plugin.components.reduce((subAcc, item)=>({\n ...subAcc,\n [item.type]: item\n }), {})\n };\n }, {});\n const nodeTypes = Object.keys(nodesConf).reduce((acc, type)=>{\n return {\n ...acc,\n [type]: nodesConf[type].node\n };\n }, {});\n const audioNodeTypes = Object.keys(nodesConf).reduce((acc, type)=>{\n return {\n ...acc,\n [type]: nodesConf[type].audioNode\n };\n }, {});\n (0, $qQ8Y1$setAudioNodeTypes)(audioNodeTypes);\n setNodeTypes(nodeTypes);\n set(({ nodesConfiguration: nodesConfiguration })=>({\n nodesConfiguration: {\n ...nodesConfiguration,\n ...nodesConf\n }\n }));\n },\n nodesConfiguration: {},\n config: {\n showMinimap: false\n },\n setConfig: (changes)=>{\n set(({ config: config })=>({\n config: {\n ...config,\n ...changes\n }\n }));\n },\n getEditorState: ()=>{\n const { getNodesAndEdges: getNodesAndEdges, controlPanel: controlPanel, viewport: viewport } = get();\n return {\n ...getNodesAndEdges(),\n controlPanel: controlPanel,\n viewport: viewport\n };\n },\n setEditorState: async ({ nodes: nodes, edges: edges, controlPanel: controlPanel, viewport: viewport })=>{\n const { setGraph: setGraph } = get();\n await setGraph({\n nodes: nodes,\n edges: edges\n });\n // @TODO: remove this line once audio patch initialisation is reworked\n await new Promise((r)=>setTimeout(r, 1000));\n set({\n controlPanel: controlPanel,\n viewport: viewport\n });\n },\n isHelpShown: false,\n toggleHelp: ()=>{\n const { isHelpShown: showHelp } = get();\n set({\n isHelpShown: !showHelp\n });\n },\n copyBuffer: {\n nodes: [],\n edges: []\n },\n copy: (elements)=>{\n set({\n copyBuffer: elements\n });\n },\n copySelectedItems: ()=>{\n const { nodes: currentNodes, edges: currentEdges, copy: copy } = get();\n const nodes = currentNodes.filter(({ selected: selected })=>selected);\n const edges = currentEdges.filter(({ selected: selected })=>selected);\n if (!nodes.length) return;\n copy({\n nodes: nodes,\n edges: edges\n });\n },\n pasteBuffer: (x = 0, y = 0)=>{\n const { copyBuffer: copyBuffer, createNodes: createNodes, setEdges: setEdges, nodes: nodes, edges: edges } = get();\n const { nodes: nodesToCopy, edges: edgesToCopy } = copyBuffer;\n if (!nodesToCopy.length) return;\n set({\n nodes: nodes.map((node)=>({\n ...node,\n selected: false\n }))\n });\n const topLeftNode = nodesToCopy.reduce((acc, node)=>{\n if (!acc) return node;\n if (node.position.x < acc.position.x && node.position.y < acc.position.y) return node;\n return acc;\n });\n const xDelta = topLeftNode.position.x - x;\n const yDelta = topLeftNode.position.y - y;\n const { nodes: newNodes, mapping: mapping } = nodesToCopy.reduce((acc, node)=>{\n const newNodeId = (0, $bc626fd1435da0c4$export$2e2bcd8739ae039)(node);\n return {\n nodes: [\n ...acc.nodes,\n {\n ...node,\n id: newNodeId,\n position: {\n x: node.position.x - xDelta,\n y: node.position.y - yDelta\n },\n selected: true\n }\n ],\n mapping: {\n ...acc.mapping,\n [node.id]: newNodeId\n }\n };\n }, {\n nodes: [],\n mapping: {}\n });\n createNodes(newNodes);\n const newEdges = edgesToCopy.map((edge)=>{\n const source = mapping[edge.source] || edge.source;\n const target = mapping[edge.target] || edge.target;\n return {\n ...edge,\n id: edge.id.replace(edge.source, source).replace(edge.target, target),\n source: source,\n target: target,\n selected: true\n };\n });\n setEdges([\n ...edges.map((edge)=>({\n ...edge,\n selected: false\n })),\n ...newEdges\n ]);\n },\n getControlPanelNode: (node)=>{\n const { nodesConfiguration: nodesConfiguration } = get();\n const { type: type } = node;\n if (!type) return null;\n const controlPanelNode = nodesConfiguration[type]?.controlPanelNode;\n if (!controlPanelNode) {\n console.error(`could not find node for type ${type}`);\n return null;\n }\n return controlPanelNode;\n },\n controlPanel: {\n show: true,\n nodes: [],\n size: {\n width: 200,\n height: 100\n }\n },\n showControlPanel: ()=>set(({ controlPanel: controlPanel })=>({\n controlPanel: {\n ...controlPanel,\n show: true\n }\n })),\n hideControlPanel: ()=>set(({ controlPanel: controlPanel })=>({\n controlPanel: {\n ...controlPanel,\n show: false\n }\n })),\n addNodeToControlPanel: (node)=>{\n const { nodesConfiguration: nodesConfiguration } = get();\n const defaultConfig = node.type ? nodesConfiguration[node.type]?.defaultConfig : {};\n const { height: height } = defaultConfig?.size || {};\n const newNode = {\n id: node.id,\n ...height ? {\n height: height / (0, $cfbf5bba42d581f6$export$9f05d3e6ade4c09e).rowHeight\n } : {}\n };\n set(({ controlPanel: controlPanel })=>({\n controlPanel: {\n ...controlPanel,\n nodes: [\n ...controlPanel.nodes,\n newNode\n ]\n }\n }));\n },\n removeNodeFromControlPanel: (node)=>get().removeNodesFromControlPanel([\n node\n ]),\n removeNodesFromControlPanel: (nodes)=>{\n const nodeIds = nodes.map(({ id: id })=>id);\n set(({ controlPanel: controlPanel })=>{\n const nodes = controlPanel.nodes.filter(({ id: id })=>!nodeIds.includes(id));\n return {\n controlPanel: {\n ...controlPanel,\n nodes: nodes\n }\n };\n });\n },\n setControlPanelNodes: (nodes)=>{\n set(({ controlPanel: controlPanel })=>{\n return {\n controlPanel: {\n ...controlPanel,\n nodes: nodes\n }\n };\n });\n },\n setControlPanelSize: (size)=>{\n set(({ controlPanel: controlPanel })=>{\n return {\n controlPanel: {\n ...controlPanel,\n size: size\n }\n };\n });\n },\n viewport: {\n x: 0,\n y: 0,\n zoom: 1\n },\n setViewport: (viewport)=>set({\n viewport: viewport\n })\n };\n};\nconst $e44921bed281a717$var$useStore = (0, $qQ8Y1$create)((0, $cdfdbc6478cadc33$export$2e2bcd8739ae039)((0, $cde61d7f4dc8a447$export$2e2bcd8739ae039)($e44921bed281a717$export$34c5bc865219488e)));\nvar $e44921bed281a717$export$2e2bcd8739ae039 = $e44921bed281a717$var$useStore;\n\n\n\nconst $9302338e8a0de440$var$LEVA_COLOR_ACCENT2_BLUE = \"#007bff\";\nconst $9302338e8a0de440$var$COLOR_GREEN_PRIMARY = \"#14df42\";\nconst $9302338e8a0de440$var$COLOR_WHITE_PRIMARY = \"#ffffff\";\nconst $9302338e8a0de440$var$colors = {\n elevation1: \"#292d39\",\n elevation2: \"#181c20\",\n elevation3: \"#373c4b\",\n accent1: \"#0066dc\",\n accent2: $9302338e8a0de440$var$LEVA_COLOR_ACCENT2_BLUE,\n accent3: \"#3c93ff\",\n highlight1: \"#535760\",\n highlight2: \"#8c92a4\",\n highlight3: \"#fefefe\",\n vivid1: $9302338e8a0de440$var$COLOR_GREEN_PRIMARY,\n whitePrimary: $9302338e8a0de440$var$COLOR_WHITE_PRIMARY,\n error: \"#db5353\"\n};\nconst $9302338e8a0de440$var$zIndex = {\n modal: 9998,\n controlPanel: 9999,\n resumeContextLayout: 10003\n};\nconst $9302338e8a0de440$var$theme = {\n colors: $9302338e8a0de440$var$colors,\n zIndex: $9302338e8a0de440$var$zIndex\n};\nvar $9302338e8a0de440$export$2e2bcd8739ae039 = $9302338e8a0de440$var$theme;\n\n\n(0, $qQ8Y1$injectGlobal)`\n .react-flow {\n .react-flow__pane {\n /* background: rgb(106 106 106); */\n /* background: \"white\"; */\n // background: #292d39;\n background: ${(0, $9302338e8a0de440$export$2e2bcd8739ae039).colors.elevation3};\n }\n\n .react-flow__background {\n /* background: #efefef; */\n stroke: white;\n }\n\n .react-flow__node-default {\n background: #292d39;\n color: white;\n border: none;\n /* background: transparent; */\n }\n\n .react-flow__node {\n padding: 0;\n width: auto;\n }\n\n .react-flow__edge-path {\n stroke: ${(0, $9302338e8a0de440$export$2e2bcd8739ae039).colors.accent2};\n }\n\n .react-flow__node.selected {\n border: 1px solid ${(0, $9302338e8a0de440$export$2e2bcd8739ae039).colors.accent2};\n box-shadow: 0 0 0 0.5px #${(0, $9302338e8a0de440$export$2e2bcd8739ae039).colors.accent2};\n }\n\n .react-flow__node-default.selected, .react-flow__node-default.selected:hover {\n box-shadow: 0 0 0 0.5px #${(0, $9302338e8a0de440$export$2e2bcd8739ae039).colors.accent2};\n }\n\n /* .react-flow__minimap-mask {\n fill: ${(0, $9302338e8a0de440$export$2e2bcd8739ae039).colors.elevation1}\n }\n\n .react-flow__minimap-node {\n fill:${(0, $9302338e8a0de440$export$2e2bcd8739ae039).colors.accent2}\n } */\n }\n\n`;\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nconst $d9641ef26ee1064b$export$ef9839ae55b8ba40 = (0, $qQ8Y1$emotionstyled)((0, $qQ8Y1$Item))``;\nconst $d9641ef26ee1064b$export$98eff9c5659394e3 = (0, $qQ8Y1$emotionstyled)((0, $qQ8Y1$Menu))`\n background: ${({ colors: colors })=>colors.elevation2};\n padding: 0;\n border-radius: 0;\n\n .react-contexify__item__content {\n color: ${({ colors: colors })=>colors.whitePrimary};\n }\n\n .react-contexify__separator {\n background-color: ${({ colors: colors })=>colors.elevation1};\n margin: 0;\n }\n`;\n\n\nconst $7ba264c3aa450939$export$d4cd258d01c03112 = \"editor-edge-menu\";\nconst $7ba264c3aa450939$export$8b2e4a15453bac1e = ()=>{\n const { show: show } = (0, $qQ8Y1$useContextMenu)({\n id: $7ba264c3aa450939$export$d4cd258d01c03112\n });\n const onContextMenu = (0, $qQ8Y1$useCallback)((event, edge)=>{\n event.stopPropagation();\n show(event, {\n props: {\n edge: edge\n }\n });\n }, [\n show\n ]);\n return {\n onContextMenu: onContextMenu\n };\n};\nconst $7ba264c3aa450939$var$EdgeContextMenu = ()=>{\n const theme = (0, $aa2521e46fde4290$export$2e2bcd8739ae039)();\n const removeEdges = (0, $e44921bed281a717$export$2e2bcd8739ae039)((store)=>store.removeEdges);\n return (0, $qQ8Y1$jsx)((0, $qQ8Y1$Fragment), {\n children: (0, $qQ8Y1$jsx)((0, $d9641ef26ee1064b$export$98eff9c5659394e3), {\n id: $7ba264c3aa450939$export$d4cd258d01c03112,\n animation: false,\n colors: theme.colors,\n children: (0, $qQ8Y1$jsx)((0, $d9641ef26ee1064b$export$ef9839ae55b8ba40), {\n onClick: (event)=>removeEdges([\n event.props.edge\n ]),\n children: \"Delete Edge (DEL)\"\n })\n })\n });\n};\nvar $7ba264c3aa450939$export$2e2bcd8739ae039 = $7ba264c3aa450939$var$EdgeContextMenu;\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nconst $8841b806cf9536cc$var$PluginsWrapper = (0, $qQ8Y1$withTheme)((0, $qQ8Y1$emotionstyled).div`\n width: 100%;\n`);\nconst $8841b806cf9536cc$var$PluginWrapper = (0, $qQ8Y1$withTheme)((0, $qQ8Y1$emotionstyled).div`\n padding: 1rem;\n display: flex;\n flex-direction: column;\n gap: 1rem;\n`);\nconst $8841b806cf9536cc$var$NodesList = (0, $qQ8Y1$withTheme)((0, $qQ8Y1$emotionstyled).ul`\n list-style: none;\n margin: 0;\n padding: 0;\n padding-bottom: 10px;\n columns: 2;\n\n li {\n display: flex;\n flex-direction: column;\n gap: 8px;\n padding: 4px;\n overflow: hidden;\n border: 1px solid ${({ theme: theme })=>theme.colors.elevation3};\n border-radius: 4px;\n margin-bottom: 0.5rem;\n &:hover {\n border-color: ${({ theme: theme })=>theme.colors.accent2};\n cursor: pointer;\n }\n }\n`);\nconst $8841b806cf9536cc$var$NodeTitle = (0, $qQ8Y1$withTheme)((0, $qQ8Y1$emotionstyled).div`\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n`);\nconst $8841b806cf9536cc$var$NodeDescription = (0, $qQ8Y1$withTheme)((0, $qQ8Y1$emotionstyled).div`\n color: ${({ theme: theme })=>theme.colors.highlight2};\n font-size: 12px;\n`);\nconst $8841b806cf9536cc$export$48f6b48a42d49a36 = (0, $qQ8Y1$withTheme)((0, $qQ8Y1$emotionstyled).div`\n display: flex;\n gap: 0.2rem;\n flex-wrap: wrap;\n`);\nconst $8841b806cf9536cc$export$7129a6e2db131a76 = (0, $qQ8Y1$withTheme)((0, $qQ8Y1$emotionstyled).span`\n cursor: pointer;\n font-size: 10px;\n background: ${({ theme: theme, isActive: isActive })=>isActive ? theme.colors.highlight1 : theme.colors.elevation3};\n border-radius: 2px;\n padding: 0.1rem 0.2rem;\n border: 1px solid;\n border-color: ${({ theme: theme })=>theme.colors.elevation2};\n &:hover {\n border-color: ${({ theme: theme })=>theme.colors.accent2};\n }\n`);\nconst $8841b806cf9536cc$var$PluginHeader = (0, $qQ8Y1$withTheme)((0, $qQ8Y1$emotionstyled).div``);\nconst $8841b806cf9536cc$var$PluginTitle = (0, $qQ8Y1$withTheme)((0, $qQ8Y1$emotionstyled).div`\n font-size: 1.1rem;\n padding: 0.25rem 0;\n color: ${({ theme: theme })=>theme.colors.highlight3};\n`);\nconst $8841b806cf9536cc$var$PluginDescription = (0, $qQ8Y1$withTheme)((0, $qQ8Y1$emotionstyled).div`\n color: ${({ theme: theme })=>theme.colors.highlight2};\n font-size: 12px;\n`);\nconst $8841b806cf9536cc$var$Plugins = ({ onComponentClick: onComponentClick, filters: { plugin: plugin, search: search = \"\", tags: tags }, onTagClick: onTagClick })=>{\n const plugins = (0, $e44921bed281a717$export$2e2bcd8739ae039)(({ plugins: plugins })=>plugins);\n const pluginsGroup = (0, $qQ8Y1$useMemo)(()=>{\n if (!plugin) return plugins;\n return plugins.filter(({ name: name })=>name === plugin);\n }, [\n plugins,\n plugin\n ]);\n const filteredPlugins = (0, $qQ8Y1$useMemo)(()=>{\n if (!search && !tags?.length) return pluginsGroup;\n const filteredByTags = pluginsGroup.map((plugin)=>({\n ...plugin,\n components: tags?.length ? plugin.components.filter((component)=>tags?.every((tag)=>component.tags?.includes(tag))) : plugin.components\n }));\n return filteredByTags.map((plugin)=>({\n ...plugin,\n components: plugin.components.filter(({ type: type, name: name })=>type.toLocaleLowerCase().includes(search.toLocaleLowerCase()) || name?.toLocaleLowerCase().includes(search.toLocaleLowerCase()))\n }));\n }, [\n pluginsGroup,\n search,\n tags\n ]);\n return (0, $qQ8Y1$jsx)($8841b806cf9536cc$var$PluginsWrapper, {\n children: filteredPlugins.map(({ name: name, description: description, components: components }, index)=>{\n if (!components.length) return null;\n return (0, $qQ8Y1$jsxs)($8841b806cf9536cc$var$PluginWrapper, {\n children: [\n (0, $qQ8Y1$jsxs)($8841b806cf9536cc$var$PluginHeader, {\n children: [\n (0, $qQ8Y1$jsx)($8841b806cf9536cc$var$PluginTitle, {\n children: name\n }),\n (0, $qQ8Y1$jsx)($8841b806cf9536cc$var$PluginDescription, {\n children: description\n })\n ]\n }),\n (0, $qQ8Y1$jsx)($8841b806cf9536cc$var$NodesList, {\n children: components.sort((a, b)=>a.type.toLowerCase() > b.type.toLowerCase() ? 1 : -1).map((component, idx)=>(0, $qQ8Y1$jsxs)(\"li\", {\n onClick: ()=>onComponentClick(component),\n children: [\n (0, $qQ8Y1$jsx)($8841b806cf9536cc$var$NodeTitle, {\n children: component.name || component.type\n }),\n component.description && (0, $qQ8Y1$jsx)($8841b806cf9536cc$var$NodeDescription, {\n children: component.description\n }),\n (0, $qQ8Y1$jsx)($8841b806cf9536cc$export$48f6b48a42d49a36, {\n children: component.tags?.map((tag, tagIdx)=>(0, $qQ8Y1$jsx)($8841b806cf9536cc$export$7129a6e2db131a76, {\n isActive: tags?.includes(tag),\n onClickCapture: (event)=>{\n event.stopPropagation();\n onTagClick(tag);\n },\n children: tag\n }, tagIdx))\n })\n ]\n }, idx))\n })\n ]\n }, index);\n })\n });\n};\nvar $8841b806cf9536cc$export$2e2bcd8739ae039 = $8841b806cf9536cc$var$Plugins;\n\n\nconst $45ab526683615339$var$InputWrapper = (0, $qQ8Y1$emotionstyled).div`\n display: flex;\n position: relative;\n`;\nconst $45ab526683615339$var$InputInner = (0, $qQ8Y1$emotionstyled).input`\n padding-right: 2rem;\n padding-left: 0.3rem;\n width: 100%;\n appearance: textfield;\n font-size: inherit;\n background: none;\n border: none;\n color: var(--leva-colors-highlight1);\n font-family: var(--leva-fonts-mono);\n cursor: inherit;\n text-overflow: ellipsis;\n outline: none;\n appearance: textfield;\n cursor: auto;\n background-color: ${({ theme: theme })=>theme.colors.elevation3};\n border-radius: 0.1rem;\n height: 2rem;\n color: ${({ theme: theme })=>theme.colors.highlight2};\n\n &:focus,\n &:hover {\n box-shadow: 0 0 0 var(--leva-borderWidths-focus)\n ${({ theme: theme })=>theme.colors.accent2};\n color: ${({ theme: theme })=>theme.colors.whitePrimary};\n }\n &::-webkit-inner-spin-button,\n &::-webkit-outer-spin-button {\n -webkit-appearance: none;\n margin-right: 1rem;\n }\n`;\nconst $45ab526683615339$var$FiltersWrapper = (0, $qQ8Y1$emotionstyled).div`\n display: flex;\n flex-direction: column;\n padding: 0.6rem;\n gap: 0.6rem;\n border-right: 1px solid ${({ theme: theme })=>theme.colors.elevation3};\n min-width: 14rem;\n`;\nconst $45ab526683615339$var$PluginName = (0, $qQ8Y1$emotionstyled).label`\n user-select: none;\n input {\n display: none;\n }\n input:checked + span {\n color: ${({ theme: theme })=>theme.colors.accent2};\n }\n &:hover {\n color: ${({ theme: theme })=>theme.colors.accent3};\n cursor: pointer;\n }\n`;\nconst $45ab526683615339$var$StyledPluginTag = (0, $qQ8Y1$withTheme)((0, $qQ8Y1$emotionstyled)((0, $8841b806cf9536cc$export$7129a6e2db131a76))`\n font-size: 12px;\n padding: 0.2rem 0.4rem;\n &:hover {\n }\n &::after {\n content: \"×\";\n margin-left: 0.4rem;\n }\n`);\nconst $45ab526683615339$var$Filters = ({ onChange: onChange, value: value })=>{\n const theme = (0, $aa2521e46fde4290$export$2e2bcd8739ae039)();\n const plugins = (0, $e44921bed281a717$export$2e2bcd8739ae039)(({ plugins: plugins })=>plugins);\n const inputRef = (0, $qQ8Y1$useRef)(null);\n (0, $qQ8Y1$useEffect)(()=>{\n if (!inputRef.current) return;\n inputRef.current.focus();\n }, [\n inputRef\n ]);\n return (0, $qQ8Y1$jsxs)($45ab526683615339$var$FiltersWrapper, {\n theme: theme,\n children: [\n (0, $qQ8Y1$jsx)($45ab526683615339$var$InputWrapper, {\n children: (0, $qQ8Y1$jsx)($45ab526683615339$var$InputInner, {\n ref: inputRef,\n theme: theme,\n value: value.search || \"\",\n placeholder: \"search...\",\n onChange: (event)=>onChange({\n ...value,\n search: event.target.value\n })\n })\n }),\n (0, $qQ8Y1$jsx)((0, $8841b806cf9536cc$export$48f6b48a42d49a36), {\n children: value.tags?.map((tag, index)=>(0, $qQ8Y1$jsx)($45ab526683615339$var$StyledPluginTag, {\n isActive: true,\n onClick: ()=>{\n const newTags = value.tags?.filter((t)=>t !== tag) || [];\n onChange({\n ...value,\n tags: newTags\n });\n },\n children: tag\n }, index))\n }),\n plugins.map(({ name: name, components: components }, index)=>{\n if (!name) return null;\n return (0, $qQ8Y1$jsxs)($45ab526683615339$var$PluginName, {\n theme: theme,\n children: [\n (0, $qQ8Y1$jsx)(\"input\", {\n type: \"checkbox\",\n name: \"plugin\",\n value: name,\n checked: name === value.plugin,\n onChange: ()=>{\n onChange({\n ...value,\n plugin: name === value.plugin ? null : name\n });\n }\n }),\n (0, $qQ8Y1$jsx)(\"span\", {\n children: name\n })\n ]\n }, index);\n })\n ]\n });\n};\nvar $45ab526683615339$export$2e2bcd8739ae039 = $45ab526683615339$var$Filters;\n\n\n\nconst $85c5b305f5fa024d$var$AddNodeWrapper = (0, $qQ8Y1$emotionstyled).div`\n height: 100%;\n width: 100%;\n display: flex;\n gap: 1rem;\n`;\nconst $85c5b305f5fa024d$var$PluginsPanel = (0, $qQ8Y1$emotionstyled).div`\n flex-grow: 1;\n height: 100%;\n overflow-y: scroll;\n`;\nconst $85c5b305f5fa024d$var$AddNode = ({ isOpen: isOpen, closeMenu: closeMenu, mousePosition: mousePosition })=>{\n const theme = (0, $aa2521e46fde4290$export$2e2bcd8739ae039)();\n const { screenToFlowPosition: screenToFlowPosition } = (0, $qQ8Y1$useReactFlow)();\n const { createNode: createNode } = (0, $e44921bed281a717$export$2e2bcd8739ae039)(({ createNode: createNode })=>({\n createNode: createNode\n }));\n const [filtersState, setFiltersState] = (0, $qQ8Y1$useState)({});\n const onComponentClick = (0, $qQ8Y1$useCallback)(({ type: type })=>{\n const { x: x, y: y } = screenToFlowPosition(mousePosition);\n const newNode = {\n //@TODO: generate node id in `createNode` function\n id: `${type}-${+new Date()}`,\n type: type,\n data: {\n label: type\n },\n position: {\n x: x,\n y: y\n },\n targetPosition: (0, $qQ8Y1$Position).Left,\n sourcePosition: (0, $qQ8Y1$Position).Right\n };\n createNode(newNode);\n closeMenu();\n }, [\n mousePosition,\n screenToFlowPosition,\n createNode,\n closeMenu,\n mousePosition\n ]);\n return isOpen ? (0, $qQ8Y1$jsx)((0, $6c9029bae1fda307$export$2e2bcd8739ae039), {\n onClose: ()=>{\n closeMenu();\n setFiltersState({});\n },\n children: (0, $qQ8Y1$jsxs)($85c5b305f5fa024d$var$AddNodeWrapper, {\n theme: theme,\n children: [\n (0, $qQ8Y1$jsx)((0, $45ab526683615339$export$2e2bcd8739ae039), {\n onChange: setFiltersState,\n value: filtersState\n }),\n (0, $qQ8Y1$jsx)($85c5b305f5fa024d$var$PluginsPanel, {\n theme: theme,\n children: (0, $qQ8Y1$jsx)((0, $8841b806cf9536cc$export$2e2bcd8739ae039), {\n filters: filtersState,\n onTagClick: (tag)=>{\n setFiltersState((state)=>({\n ...state,\n tags: state.tags?.includes(tag) ? state.tags.filter((t)=>t !== tag) : [\n ...state.tags || [],\n tag\n ]\n }));\n },\n onComponentClick: (component)=>{\n onComponentClick(component);\n setFiltersState({});\n }\n })\n })\n ]\n })\n }) : null;\n};\nvar $85c5b305f5fa024d$export$2e2bcd8739ae039 = $85c5b305f5fa024d$var$AddNode;\n\n\n\n\n\n\n\n\n\n\nconst $743f973aa6df694f$var$UploadPatchWrapper = (0, $qQ8Y1$emotionstyled).div`\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n width: 100%;\n\n .drop-zone-wrapper {\n width: 80%;\n height: 80%;\n }\n\n .drop-zone {\n height: 100%;\n width: 100%;\n border-style: dashed;\n border-width: 2px;\n border-color: ${({ theme: theme })=>theme.colors.highlight2};\n opacity: 0.5;\n cursor: pointer;\n }\n\n .drop-zone:hover,\n .drop-zone-drag-over {\n opacity: 1;\n }\n`;\nconst $743f973aa6df694f$var$DropZoneInner = (0, $qQ8Y1$emotionstyled).div`\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: center;\n height: 100%;\n width: 100%;\n`;\nconst $743f973aa6df694f$var$FileUploadIcon = (0, $qQ8Y1$emotionstyled)((0, $qQ8Y1$FaFileUpload))`\n width: 100%;\n height: 8rem;\n`;\nconst $743f973aa6df694f$var$FileUploadMessage = (0, $qQ8Y1$emotionstyled).div`\n font-size: 2rem;\n`;\nconst $743f973aa6df694f$var$UploadPatch = ({ isOpen: isOpen, closeMenu: closeMenu })=>{\n const theme = (0, $aa2521e46fde4290$export$2e2bcd8739ae039)();\n const setGraph = (0, $e44921bed281a717$export$2e2bcd8739ae039)(({ setGraph: setGraph })=>setGraph);\n const setEditorState = (0, $e44921bed281a717$export$2e2bcd8739ae039)((store)=>store.setEditorState);\n const fileInputRef = (0, $qQ8Y1$useRef)(null);\n const uploadFile = (0, $qQ8Y1$useCallback)((files)=>{\n const [file] = files || [];\n file.text().then(JSON.parse).then((editorState)=>{\n setEditorState(editorState);\n closeMenu();\n }).catch(console.error);\n }, [\n setGraph,\n closeMenu\n ]);\n const onTargetClick = ()=>{\n fileInputRef.current?.click();\n };\n return isOpen ? (0, $qQ8Y1$jsx)((0, $6c9029bae1fda307$export$2e2bcd8739ae039), {\n onClose: closeMenu,\n children: (0, $qQ8Y1$jsxs)($743f973aa6df694f$var$UploadPatchWrapper, {\n theme: theme,\n children: [\n (0, $qQ8Y1$jsx)(\"input\", {\n onChange: ({ target: { files: files } })=>uploadFile(files),\n ref: fileInputRef,\n type: \"file\",\n className: \"hidden\",\n style: {\n display: \"none\"\n },\n accept: \".json\"\n }),\n (0, $qQ8Y1$jsx)((0, $qQ8Y1$FileDrop), {\n className: \"drop-zone-wrapper\",\n targetClassName: \"drop-zone\",\n draggingOverTargetClassName: \"drop-zone-drag-over\",\n onTargetClick: onTargetClick,\n onDrop: (files)=>uploadFile(files),\n children: (0, $qQ8Y1$jsxs)($743f973aa6df694f$var$DropZoneInner, {\n theme: theme,\n children: [\n (0, $qQ8Y1$jsx)($743f973aa6df694f$var$FileUploadIcon, {}),\n (0, $qQ8Y1$jsx)($743f973aa6df694f$var$FileUploadMessage, {\n children: \"click or drop file here\"\n })\n ]\n })\n })\n ]\n })\n }) : null;\n};\nvar $743f973aa6df694f$export$2e2bcd8739ae039 = $743f973aa6df694f$var$UploadPatch;\n\n\n\n\n\n\n\n\n\n\nconst $af4ce549f5935079$var$UploadProjectWrapper = (0, $qQ8Y1$emotionstyled).div`\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n width: 100%;\n\n .drop-zone-wrapper {\n width: 80%;\n height: 80%;\n }\n\n .drop-zone {\n height: 100%;\n width: 100%;\n border-style: dashed;\n border-width: 2px;\n border-color: ${({ theme: theme })=>theme.colors.highlight2};\n opacity: 0.5;\n cursor: pointer;\n }\n\n .drop-zone:hover,\n .drop-zone-drag-over {\n opacity: 1;\n }\n`;\nconst $af4ce549f5935079$var$DropZoneInner = (0, $qQ8Y1$emotionstyled).div`\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: center;\n height: 100%;\n width: 100%;\n`;\nconst $af4ce549f5935079$var$FileUploadIcon = (0, $qQ8Y1$emotionstyled)((0, $qQ8Y1$FaFileUpload))`\n width: 100%;\n height: 8rem;\n`;\nconst $af4ce549f5935079$var$FileUploadMessage = (0, $qQ8Y1$emotionstyled).div`\n font-size: 2rem;\n`;\n// @TODO: unify with upload file\nconst $af4ce549f5935079$var$UploadProject = ({ isOpen: isOpen, closeMenu: closeMenu })=>{\n const theme = (0, $aa2521e46fde4290$export$2e2bcd8739ae039)();\n const setProject = (0, $e44921bed281a717$export$2e2bcd8739ae039)((store)=>store.setProject);\n const fileInputRef = (0, $qQ8Y1$useRef)(null);\n const uploadFile = (0, $qQ8Y1$useCallback)((files)=>{\n const [file] = files || [];\n file.text().then(JSON.parse).then((projectState)=>{\n setProject(projectState);\n closeMenu();\n }).catch(console.error);\n }, [\n setProject,\n closeMenu\n ]);\n const onTargetClick = ()=>{\n fileInputRef.current?.click();\n };\n return isOpen ? (0, $qQ8Y1$jsx)((0, $6c9029bae1fda307$export$2e2bcd8739ae039), {\n onClose: closeMenu,\n children: (0, $qQ8Y1$jsxs)($af4ce549f5935079$var$UploadProjectWrapper, {\n theme: theme,\n children: [\n (0, $qQ8Y1$jsx)(\"input\", {\n onChange: ({ target: { files: files } })=>uploadFile(files),\n ref: fileInputRef,\n type: \"file\",\n className: \"hidden\",\n style: {\n display: \"none\"\n },\n accept: \".json\"\n }),\n (0, $qQ8Y1$jsx)((0, $qQ8Y1$FileDrop), {\n className: \"drop-zone-wrapper\",\n targetClassName: \"drop-zone\",\n draggingOverTargetClassName: \"drop-zone-drag-over\",\n onTargetClick: onTargetClick,\n onDrop: (files)=>uploadFile(files),\n children: (0, $qQ8Y1$jsxs)($af4ce549f5935079$var$DropZoneInner, {\n theme: theme,\n children: [\n (0, $qQ8Y1$jsx)($af4ce549f5935079$var$FileUploadIcon, {}),\n (0, $qQ8Y1$jsx)($af4ce549f5935079$var$FileUploadMessage, {\n children: \"click or drop file here\"\n })\n ]\n })\n })\n ]\n })\n }) : null;\n};\nvar $af4ce549f5935079$export$2e2bcd8739ae039 = $af4ce549f5935079$var$UploadProject;\n\n\n\n\n\n\n\n\n\n\n\n\nconst $85cc84537fca2305$export$3a5757a785a34769 = (url)=>{\n const [worker, setWorker] = (0, $qQ8Y1$useState)(null);\n (0, $qQ8Y1$useEffect)(()=>{\n const newWorker = new Worker(url);\n setWorker(newWorker);\n return ()=>{\n newWorker?.terminate();\n setWorker(null);\n };\n }, []);\n return worker;\n};\nvar $85cc84537fca2305$export$2e2bcd8739ae039 = $85cc84537fca2305$export$3a5757a785a34769;\n\n\n\nconsole.log(888888, `React version: ${(0, $qQ8Y1$version)}`);\nconst $54f40e8606290db9$export$1e86115ead375efc = ()=>{\n const [channel, setChannel] = (0, $qQ8Y1$useState)(null);\n (0, $qQ8Y1$useEffect)(()=>{\n const newChannel = new MessageChannel();\n newChannel.port2.start();\n setChannel(newChannel);\n return ()=>{\n setChannel(null);\n newChannel.port2.close();\n };\n }, []);\n return channel;\n};\nvar $54f40e8606290db9$export$2e2bcd8739ae039 = $54f40e8606290db9$export$1e86115ead375efc;\n\n\nconst $9322aabb88fc4cc3$export$cd440e094f060920 = (param, value, audioContext)=>{\n if (typeof value === \"undefined\") return;\n param.setValueAtTime(value, audioContext.currentTime);\n};\nconst $9322aabb88fc4cc3$export$25df2e315be8e003 = (file)=>{\n return new Promise((resolve, reject)=>{\n const reader = new FileReader();\n reader.readAsDataURL(file);\n reader.onload = ()=>resolve(reader.result?.toString() || \"\");\n reader.onerror = (error)=>reject(error);\n });\n};\n\n\n\n\nconst $679f609277b7a9cd$var$UploadAudioWrapper = (0, $qQ8Y1$emotionstyled).div`\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n width: 100%;\n\n .drop-zone-wrapper {\n width: 80%;\n height: 80%;\n }\n\n .drop-zone {\n height: 100%;\n width: 100%;\n border-style: dashed;\n border-width: 2px;\n border-color: ${({ theme: theme })=>theme.colors.highlight2};\n opacity: 0.5;\n cursor: pointer;\n }\n\n .drop-zone:hover,\n .drop-zone-drag-over {\n opacity: 1;\n }\n`;\nconst $679f609277b7a9cd$var$DropZoneInner = (0, $qQ8Y1$emotionstyled).div`\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: center;\n height: 100%;\n width: 100%;\n`;\nconst $679f609277b7a9cd$var$FileUploadIcon = (0, $qQ8Y1$emotionstyled)((0, $qQ8Y1$FaFileUpload))`\n width: 100%;\n height: 8rem;\n`;\nconst $679f609277b7a9cd$var$FileUploadMessage = (0, $qQ8Y1$emotionstyled).div`\n font-size: 2rem;\n`;\nconst $679f609277b7a9cd$var$UploadAudio = ({ isOpen: isOpen, closeMenu: closeMenu })=>{\n const theme = (0, $aa2521e46fde4290$export$2e2bcd8739ae039)();\n const setGraph = (0, $e44921bed281a717$export$2e2bcd8739ae039)(({ setGraph: setGraph })=>setGraph);\n const setEditorState = (0, $e44921bed281a717$export$2e2bcd8739ae039)((store)=>store.setEditorState);\n const addFile = (0, $e44921bed281a717$export$2e2bcd8739ae039)((store)=>store.addFile);\n const fileInputRef = (0, $qQ8Y1$useRef)(null);\n const uploadFile = (0, $qQ8Y1$useCallback)(async (files)=>{\n const [file] = files || [];\n const base64 = await (0, $9322aabb88fc4cc3$export$25df2e315be8e003)(file);\n addFile({\n type: \"audio\",\n // @TODO: use nanoid here\n id: `audio-file-${+new Date()}`,\n name: file.name,\n file: base64\n });\n closeMenu();\n }, [\n addFile,\n closeMenu\n ]);\n const onTargetClick = ()=>{\n fileInputRef.current?.click();\n };\n return isOpen ? (0, $qQ8Y1$jsx)((0, $6c9029bae1fda307$export$2e2bcd8739ae039), {\n onClose: closeMenu,\n children: (0, $qQ8Y1$jsxs)($679f609277b7a9cd$var$UploadAudioWrapper, {\n theme: theme,\n children: [\n (0, $qQ8Y1$jsx)(\"input\", {\n onChange: ({ target: { files: files } })=>uploadFile(files),\n ref: fileInputRef,\n type: \"file\",\n className: \"hidden\",\n style: {\n display: \"none\"\n },\n accept: \".wav,.mp3,.ogg\"\n }),\n (0, $qQ8Y1$jsx)((0, $qQ8Y1$FileDrop), {\n className: \"drop-zone-wrapper\",\n targetClassName: \"drop-zone\",\n draggingOverTargetClassName: \"drop-zone-drag-over\",\n onTargetClick: onTargetClick,\n onDrop: (files)=>uploadFile(files),\n children: (0, $qQ8Y1$jsxs)($679f609277b7a9cd$var$DropZoneInner, {\n theme: theme,\n children: [\n (0, $qQ8Y1$jsx)($679f609277b7a9cd$var$FileUploadIcon, {}),\n (0, $qQ8Y1$jsx)($679f609277b7a9cd$var$FileUploadMessage, {\n children: \"click or drop file here\"\n })\n ]\n })\n })\n ]\n })\n }) : null;\n};\nvar $679f609277b7a9cd$export$2e2bcd8739ae039 = $679f609277b7a9cd$var$UploadAudio;\n\n\nconst $8827576290cfe6c8$export$d4cd258d01c03112 = \"editor-menu\";\nconst $8827576290cfe6c8$export$59ce2a6808e35a29 = ()=>{\n const { show: show } = (0, $qQ8Y1$useContextMenu)({\n id: $8827576290cfe6c8$export$d4cd258d01c03112\n });\n return {\n onContextMenu: show\n };\n};\nconst $8827576290cfe6c8$var$EditorContextMenu = ({ editorContextMenu: editorContextMenu = [] })=>{\n const theme = (0, $aa2521e46fde4290$export$2e2bcd8739ae039)();\n const [mousePosition, setMousePosition] = (0, $qQ8Y1$useState)({\n x: 0,\n y: 0\n });\n const [showAddNode, setShowAddNode] = (0, $qQ8Y1$useState)(false);\n const [showUploadPatch, setShowUploadPatch] = (0, $qQ8Y1$useState)(false);\n const [showUploadProject, setShowUploadProject] = (0, $qQ8Y1$useState)(false);\n const [showUploadAudio, setShowUploadAudio] = (0, $qQ8Y1$useState)(false);\n const addNodeHandler = (0, $qQ8Y1$useCallback)((x, y)=>{\n setMousePosition({\n x: x,\n y: y\n });\n setShowAddNode(true);\n }, [\n setShowAddNode\n ]);\n const pasteBuffer = (0, $e44921bed281a717$export$2e2bcd8739ae039)((store)=>store.pasteBuffer);\n const { screenToFlowPosition: screenToFlowPosition } = (0, $qQ8Y1$useReactFlow)();\n const pasteBufferHandler = (0, $qQ8Y1$useCallback)((mousePosition)=>{\n const { x: x, y: y } = screenToFlowPosition(mousePosition);\n pasteBuffer(x, y);\n }, [\n setShowAddNode,\n screenToFlowPosition\n ]);\n const clearGraph = (0, $e44921bed281a717$export$2e2bcd8739ae039)(({ clearGraph: clearGraph })=>clearGraph);\n const getEditorState = (0, $e44921bed281a717$export$2e2bcd8739ae039)((store)=>store.getEditorState);\n const getProject = (0, $e44921bed281a717$export$2e2bcd8739ae039)((store)=>store.getProject);\n const deleteAllHandler = (0, $qQ8Y1$useCallback)(()=>{\n clearGraph();\n }, [\n clearGraph\n ]);\n const toggleHelp = (0, $e44921bed281a717$export$2e2bcd8739ae039)((store)=>store.toggleHelp);\n const historyBack = (0, $e44921bed281a717$export$2e2bcd8739ae039)((store)=>store.history.back);\n const historyForward = (0, $e44921bed281a717$export$2e2bcd8739ae039)((store)=>store.history.forward);\n const historyPointer = (0, $e44921bed281a717$export$2e2bcd8739ae039)((store)=>store.history.pointer);\n const historyBuffer = (0, $e44921bed281a717$export$2e2bcd8739ae039)((store)=>store.history.buffer);\n const copySelectedItems = (0, $e44921bed281a717$export$2e2bcd8739ae039)((store)=>store.copySelectedItems);\n const nodes = (0, $e44921bed281a717$export$2e2bcd8739ae039)((store)=>store.nodes);\n const selectedNodes = (0, $qQ8Y1$useMemo)(()=>nodes.filter(({ selected: selected })=>selected), [\n nodes\n ]);\n const currentCopyBuffer = (0, $e44921bed281a717$export$2e2bcd8739ae039)((store)=>store.copyBuffer);\n const reactFlowInstance = (0, $qQ8Y1$useReactFlow)();\n const downloadPatchHandler = (0, $qQ8Y1$useCallback)(()=>{\n const fileName = \"web-noise-patch.json\";\n const editorState = getEditorState();\n const data = {\n ...editorState\n };\n (0, $qQ8Y1$jsfiledownload)(JSON.stringify(data, null, 2), fileName);\n }, [\n getEditorState,\n reactFlowInstance\n ]);\n const downloadProjectHandler = (0, $qQ8Y1$useCallback)(()=>{\n const fileName = \"web-noise-project.json\";\n const projectState = getProject();\n const data = {\n ...projectState\n };\n (0, $qQ8Y1$jsfiledownload)(JSON.stringify(data, null, 2), fileName);\n }, [\n getEditorState,\n reactFlowInstance\n ]);\n (0, $qQ8Y1$useEffect)(()=>{\n (0, $qQ8Y1$hotkeysjs)(\"command+shift+a\", ()=>{\n addNodeHandler(200, 50);\n return false;\n });\n //@TODO: find more elegant way to handle ?\n (0, $qQ8Y1$hotkeysjs)(\"shift+/\", ()=>{\n toggleHelp();\n return false;\n });\n (0, $qQ8Y1$hotkeysjs)(\"command+z\", ()=>{\n historyBack();\n return false;\n });\n (0, $qQ8Y1$hotkeysjs)(\"command+shift+z\", ()=>{\n historyForward();\n return false;\n });\n (0, $qQ8Y1$hotkeysjs)(\"command+c\", ()=>{\n copySelectedItems();\n return false;\n });\n (0, $qQ8Y1$hotkeysjs)(\"command+v\", ()=>{\n pasteBufferHandler({\n x: 200,\n y: 50\n });\n return false;\n });\n return ()=>{\n (0, $qQ8Y1$hotkeysjs).unbind();\n };\n }, [\n addNodeHandler,\n pasteBufferHandler\n ]);\n return (0, $qQ8Y1$jsxs)((0, $qQ8Y1$Fragment), {\n children: [\n (0, $qQ8Y1$jsx)((0, $85c5b305f5fa024d$export$2e2bcd8739ae039), {\n isOpen: showAddNode,\n closeMenu: ()=>setShowAddNode(false),\n mousePosition: mousePosition\n }),\n (0, $qQ8Y1$jsx)((0, $743f973aa6df694f$export$2e2bcd8739ae039), {\n isOpen: showUploadPatch,\n closeMenu: ()=>setShowUploadPatch(false)\n }),\n (0, $qQ8Y1$jsx)((0, $af4ce549f5935079$export$2e2bcd8739ae039), {\n isOpen: showUploadProject,\n closeMenu: ()=>setShowUploadProject(false)\n }),\n (0, $qQ8Y1$jsx)((0, $679f609277b7a9cd$export$2e2bcd8739ae039), {\n isOpen: showUploadAudio,\n closeMenu: ()=>setShowUploadAudio(false)\n }),\n (0, $qQ8Y1$jsxs)((0, $d9641ef26ee1064b$export$98eff9c5659394e3), {\n id: $8827576290cfe6c8$export$d4cd258d01c03112,\n animation: false,\n colors: theme.colors,\n children: [\n (0, $qQ8Y1$jsx)((0, $d9641ef26ee1064b$export$ef9839ae55b8ba40), {\n onClick: ({ triggerEvent: { clientX: clientX, clientY: clientY } })=>addNodeHandler(clientX, clientY),\n children: \"Add Node (\\u2318+\\u21E7+A)\"\n }),\n (0, $qQ8Y1$jsx)((0, $qQ8Y1$Separator), {}),\n (0, $qQ8Y1$jsx)((0, $d9641ef26ee1064b$export$ef9839ae55b8ba40), {\n onClick: deleteAllHandler,\n children: \"Delete All\"\n }),\n (0, $qQ8Y1$jsx)((0, $qQ8Y1$Separator), {}),\n (0, $qQ8Y1$jsx)((0, $d9641ef26ee1064b$export$ef9839ae55b8ba40), {\n onClick: downloadPatchHandler,\n children: \"Download patch\"\n }),\n (0, $qQ8Y1$jsx)((0, $d9641ef26ee1064b$export$ef9839ae55b8ba40), {\n onClick: ()=>setShowUploadPatch(true),\n children: \"Upload patch\"\n }),\n (0, $qQ8Y1$jsx)((0, $qQ8Y1$Separator), {}),\n (0, $qQ8Y1$jsx)((0, $d9641ef26ee1064b$export$ef9839ae55b8ba40), {\n onClick: downloadProjectHandler,\n children: \"Download project\"\n }),\n (0, $qQ8Y1$jsx)((0, $d9641ef26ee1064b$export$ef9839ae55b8ba40), {\n onClick: ()=>setShowUploadProject(true),\n children: \"Upload project\"\n }),\n (0, $qQ8Y1$jsx)((0, $qQ8Y1$Separator), {}),\n (0, $qQ8Y1$jsx)((0, $d9641ef26ee1064b$export$ef9839ae55b8ba40), {\n onClick: ()=>setShowUploadAudio(true),\n children: \"Upload Audio File\"\n }),\n (0, $qQ8Y1$jsx)((0, $qQ8Y1$Separator), {}),\n (0, $qQ8Y1$jsx)((0, $d9641ef26ee1064b$export$ef9839ae55b8ba40), {\n disabled: historyPointer === 0,\n onClick: historyBack,\n children: \"Undo (\\u2318+z)\"\n }),\n (0, $qQ8Y1$jsx)((0, $d9641ef26ee1064b$export$ef9839ae55b8ba40), {\n disabled: historyPointer === historyBuffer.length,\n onClick: historyForward,\n children: \"Redo (\\u2318+\\u21E7+Z)\"\n }),\n (0, $qQ8Y1$jsx)((0, $qQ8Y1$Separator), {}),\n (0, $qQ8Y1$jsx)((0, $d9641ef26ee1064b$export$ef9839ae55b8ba40), {\n disabled: !selectedNodes.length,\n onClick: copySelectedItems,\n children: \"Copy Selected (\\u2318+c)\"\n }),\n (0, $qQ8Y1$jsx)((0, $d9641ef26ee1064b$export$ef9839ae55b8ba40), {\n disabled: !currentCopyBuffer.nodes.length,\n onClick: ({ triggerEvent: { clientX: x, clientY: y } })=>pasteBufferHandler({\n x: x,\n y: y\n }),\n children: \"Paste (\\u2318+v)\"\n }),\n (0, $qQ8Y1$jsx)((0, $qQ8Y1$Separator), {}),\n editorContextMenu.map((item, index)=>(0, $qQ8Y1$jsx)((0, $d9641ef26ee1064b$export$ef9839ae55b8ba40), {\n children: item\n }, index)),\n (0, $qQ8Y1$jsx)((0, $qQ8Y1$Separator), {}),\n (0, $qQ8Y1$jsx)((0, $d9641ef26ee1064b$export$ef9839ae55b8ba40), {\n onClick: toggleHelp,\n children: \"Help (\\u21E7+?)\"\n })\n ]\n })\n ]\n });\n};\nvar $8827576290cfe6c8$export$2e2bcd8739ae039 = $8827576290cfe6c8$var$EditorContextMenu;\n\n\n\n\n\n\n\n\n\nconst $3d16dc6c2f6416d3$export$d4cd258d01c03112 = \"editor-node-menu\";\nconst $3d16dc6c2f6416d3$export$cbbbfb9fb15f3780 = ()=>{\n const { show: show } = (0, $qQ8Y1$useContextMenu)({\n id: $3d16dc6c2f6416d3$export$d4cd258d01c03112\n });\n const onContextMenu = (0, $qQ8Y1$useCallback)((event, node)=>{\n event.stopPropagation();\n show(event, {\n props: {\n node: node\n }\n });\n }, []);\n return {\n onContextMenu: onContextMenu\n };\n};\nconst $3d16dc6c2f6416d3$var$NodeContextMenu = (args)=>{\n const theme = (0, $aa2521e46fde4290$export$2e2bcd8739ae039)();\n const removeNodes = (0, $e44921bed281a717$export$2e2bcd8739ae039)((store)=>store.removeNodes);\n const addNodeToControlPanel = (0, $e44921bed281a717$export$2e2bcd8739ae039)((store)=>store.addNodeToControlPanel);\n const removeNodeFromControlPanel = (0, $e44921bed281a717$export$2e2bcd8739ae039)((store)=>store.removeNodeFromControlPanel);\n const copy = (0, $e44921bed281a717$export$2e2bcd8739ae039)((store)=>store.copy);\n const nodesConfiguration = (0, $e44921bed281a717$export$2e2bcd8739ae039)((store)=>store.nodesConfiguration);\n const controlPanelNodes = (0, $e44921bed281a717$export$2e2bcd8739ae039)((store)=>store.controlPanel.nodes);\n const isOnControlPanel = (0, $qQ8Y1$useCallback)(({ props: props })=>{\n if (!props?.node.type) return false;\n return !!controlPanelNodes.find(({ id: id })=>id === props.node.id);\n }, [\n controlPanelNodes\n ]);\n const hasControlPanelNode = (0, $qQ8Y1$useCallback)(({ props: props })=>{\n if (!props?.node.type) return false;\n const nodeConfiguration = nodesConfiguration[props.node.type];\n return !!nodeConfiguration?.controlPanelNode;\n }, [\n nodesConfiguration\n ]);\n return (0, $qQ8Y1$jsx)((0, $qQ8Y1$Fragment), {\n children: (0, $qQ8Y1$jsxs)((0, $d9641ef26ee1064b$export$98eff9c5659394e3), {\n id: $3d16dc6c2f6416d3$export$d4cd258d01c03112,\n animation: false,\n colors: theme.colors,\n children: [\n (0, $qQ8Y1$jsx)((0, $d9641ef26ee1064b$export$ef9839ae55b8ba40), {\n onClick: (event)=>removeNodes([\n event.props.node\n ]),\n children: \"Delete Node (DEL)\"\n }),\n (0, $qQ8Y1$jsx)((0, $d9641ef26ee1064b$export$ef9839ae55b8ba40), {\n hidden: (...args)=>!hasControlPanelNode(...args) || isOnControlPanel(...args),\n onClick: (event)=>addNodeToControlPanel(event.props.node),\n children: \"Add To Control Panel\"\n }),\n (0, $qQ8Y1$jsx)((0, $d9641ef26ee1064b$export$ef9839ae55b8ba40), {\n hidden: (...args)=>!hasControlPanelNode(...args) || !isOnControlPanel(...args),\n onClick: (event)=>removeNodeFromControlPanel(event.props.node),\n children: \"Remove From Control Panel\"\n }),\n (0, $qQ8Y1$jsx)((0, $d9641ef26ee1064b$export$ef9839ae55b8ba40), {\n onClick: (event)=>copy({\n nodes: [\n event.props.node\n ],\n edges: []\n }),\n children: \"Copy (\\u2318+c)\"\n })\n ]\n })\n });\n};\nvar $3d16dc6c2f6416d3$export$2e2bcd8739ae039 = $3d16dc6c2f6416d3$var$NodeContextMenu;\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nconst $acc48893b410c429$var$useAudioNode = (id)=>{\n const patch = (0, $e44921bed281a717$export$2e2bcd8739ae039)(({ patch: patch })=>patch);\n return patch.audioNodes.get(id);\n};\nvar $acc48893b410c429$export$2e2bcd8739ae039 = $acc48893b410c429$var$useAudioNode;\n\n\n\n\nconst $712d0a8959c2f3aa$var$useNode = (id)=>{\n const updateNodeData = (0, $e44921bed281a717$export$2e2bcd8739ae039)(({ updateNodeData: updateNodeData })=>updateNodeData);\n const updateNodeValues = (0, $qQ8Y1$useCallback)((values)=>updateNodeData(id, {\n values: values\n }), [\n id,\n updateNodeData\n ]);\n const updateNodeConfig = (0, $qQ8Y1$useCallback)((config)=>updateNodeData(id, {\n config: config\n }), [\n id,\n updateNodeData\n ]);\n const updateNodeLabel = (0, $qQ8Y1$useCallback)((label)=>updateNodeData(id, {\n label: label\n }), [\n id,\n updateNodeData\n ]);\n return {\n updateNodeValues: updateNodeValues,\n updateNodeConfig: updateNodeConfig,\n updateNodeLabel: updateNodeLabel\n };\n};\nvar $712d0a8959c2f3aa$export$2e2bcd8739ae039 = $712d0a8959c2f3aa$var$useNode;\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nconst $a2cf3f549395b7f1$export$5abe11f802ebd1f2 = (0, $qQ8Y1$emotionstyled).input`\n width: 100%;\n background: none;\n border: none;\n text-align: center;\n color: var(--leva-colors-highlight1);\n font-family: var(--leva-fonts-mono);\n font-size: var(--leva-fontSizes-root);\n cursor: inherit;\n text-overflow: ellipsis;\n outline: none;\n\n &:focus {\n box-shadow: 0 0 0 green var(--leva-colors-accent2);\n }\n &:focus-within {\n box-shadow: 0 0 0 green var(--leva-colors-accent2);\n }\n &:focus-vissible {\n box-shadow: 0 0 0 green var(--leva-colors-accent2);\n }\n &:not([readonly]):focus {\n color: #fff;\n appearance: none;\n cursor: auto;\n background-color: var(--leva-colors-elevation2);\n padding: 0.3rem;\n border-radius: 0.2rem;\n }\n`;\nconst $a2cf3f549395b7f1$var$EditableLabel = ({ onChange: onChange, value: value = \"\", className: className })=>{\n const labelInputRef = (0, $qQ8Y1$useRef)(null);\n const [labelEditMode, setLabelEditMode] = (0, $qQ8Y1$useState)(false);\n const editNodeLabel = (0, $qQ8Y1$useCallback)((event)=>{\n //@ts-ignore\n event.target?.select();\n setLabelEditMode(true);\n }, [\n setLabelEditMode\n ]);\n const exitEditMode = (0, $qQ8Y1$useCallback)(()=>{\n window.getSelection()?.collapseToEnd();\n setLabelEditMode(false);\n }, [\n setLabelEditMode\n ]);\n const saveNodeLabel = (0, $qQ8Y1$useCallback)(()=>{\n exitEditMode();\n if (labelInputRef.current) onChange(labelInputRef.current.value);\n }, [\n labelInputRef,\n exitEditMode,\n onChange\n ]);\n const cancelNodeLabelEdit = (0, $qQ8Y1$useCallback)(()=>{\n exitEditMode();\n if (labelInputRef.current && value) labelInputRef.current.value = value;\n }, [\n labelInputRef,\n exitEditMode,\n value\n ]);\n (0, $qQ8Y1$useEffect)(()=>{\n if (!labelInputRef.current) return;\n labelInputRef.current.value = value;\n }, [\n value,\n labelInputRef\n ]);\n return (0, $qQ8Y1$jsx)($a2cf3f549395b7f1$export$5abe11f802ebd1f2, {\n ref: labelInputRef,\n type: \"text\",\n readOnly: !labelEditMode,\n onDoubleClick: (event)=>editNodeLabel(event),\n onBlur: saveNodeLabel,\n onKeyDown: (event)=>{\n switch(event.key){\n case \"Escape\":\n cancelNodeLabelEdit();\n break;\n case \"Enter\":\n saveNodeLabel();\n break;\n }\n },\n className: className\n });\n};\nvar $a2cf3f549395b7f1$export$2e2bcd8739ae039 = $a2cf3f549395b7f1$var$EditableLabel;\n\n\n\n\n\n\n\n\n\nconst $c49c7ecc2471f2b1$var$NodeInfoWrapper = (0, $qQ8Y1$withTheme)((0, $qQ8Y1$emotionstyled).div`\n height: 100%;\n width: 100%;\n overflow: scroll;\n padding: 0.6rem;\n box-sizing: border-box;\n\n hr {\n border: none;\n border-bottom: 1px solid ${({ theme: theme })=>theme.colors.elevation3};\n }\n\n code {\n background-color: ${({ theme: theme })=>theme.colors.elevation3};\n color: ${({ theme: theme })=>theme.colors.highlight3};\n font-family:\n source-code-pro, Menlo, Monaco, Consolas, \"Courier New\", monospace;\n }\n\n pre {\n background-color: ${({ theme: theme })=>theme.colors.elevation3};\n padding: 0.2rem 0.3rem;\n border-radius: 1px;\n }\n\n a {\n color: ${({ theme: theme })=>theme.colors.accent1};\n }\n`);\nconst $c49c7ecc2471f2b1$var$useNodeManifest = (type)=>{\n const data = (0, $e44921bed281a717$export$2e2bcd8739ae039)((store)=>store.nodesConfiguration[type]);\n return data;\n};\nconst $c49c7ecc2471f2b1$var$NodeInfoModal = ({ isOpen: isOpen, onClose: onClose, type: nodeType, node: node })=>{\n const { info: info, portsDescription: portsDescription } = $c49c7ecc2471f2b1$var$useNodeManifest(nodeType);\n const portsInfo = (0, $qQ8Y1$useMemo)(()=>{\n const parts = [];\n const inputPorts = node.inputs;\n if (inputPorts) {\n parts.push(`## Inputs`);\n for(const portName in inputPorts){\n const port = inputPorts[portName];\n parts.push(`### *${portName}*`);\n const description = portsDescription?.inputs?.[portName];\n if (description) parts.push(description);\n if (Array.isArray(port.type)) parts.push(`**Types**: \\`${port.type.join(\", \")}\\``);\n else parts.push(`**Type**: \\`${port.type || \"unknown\"}\\``);\n if (port.range) parts.push(`**Range**: \\`[${port.range[0]}, ${port.range[1]}]\\``);\n if (port.defaultValue !== undefined) parts.push(`**Default**: \\`${port.defaultValue}\\``);\n }\n }\n const outputPorts = node.outputs;\n if (outputPorts) {\n parts.push(`## Outputs`);\n for(const portName in outputPorts){\n const port = outputPorts[portName];\n parts.push(`### *${portName}*`);\n const description = portsDescription?.outputs?.[portName];\n if (description) parts.push(description);\n if (Array.isArray(port.type)) parts.push(`**Types**: \\`${port.type.join(\", \")}\\``);\n else parts.push(`**Type**: \\`${port.type || \"unknown\"}\\``);\n if (port.range) parts.push(`**Range**: \\`[${port.range[0]}, ${port.range[1]}]\\``);\n if (port.defaultValue !== undefined) parts.push(`**Default**: \\`${port.defaultValue}\\``);\n }\n }\n return parts.join(\"\\n\\n\");\n }, [\n node,\n portsDescription\n ]);\n const combinedInfo = (info || \"\") + \"\\n\\n\" + portsInfo;\n return isOpen ? (0, $qQ8Y1$jsx)((0, $6c9029bae1fda307$export$2e2bcd8739ae039), {\n onClose: onClose,\n children: (0, $qQ8Y1$jsx)($c49c7ecc2471f2b1$var$NodeInfoWrapper, {\n dangerouslySetInnerHTML: {\n __html: (0, $qQ8Y1$marked)(combinedInfo || \"\")\n }\n })\n }) : null;\n};\nvar $c49c7ecc2471f2b1$export$2e2bcd8739ae039 = $c49c7ecc2471f2b1$var$NodeInfoModal;\n\n\nconst $ff9a1ac4f0decadf$var$NodeWrapper = (0, $qQ8Y1$emotionstyled).div`\n background-color: var(--leva-colors-elevation1);\n`;\nconst $ff9a1ac4f0decadf$var$NodeLoaderWrapper = (0, $qQ8Y1$emotionstyled)($ff9a1ac4f0decadf$var$NodeWrapper)`\n padding: 2rem 5rem;\n`;\nconst $ff9a1ac4f0decadf$var$NodeErrorWrapper = (0, $qQ8Y1$emotionstyled)($ff9a1ac4f0decadf$var$NodeWrapper)`\n padding: 1rem 2rem;\n`;\nconst $ff9a1ac4f0decadf$var$SettingsIconWrapper = (0, $qQ8Y1$emotionstyled)((0, $qQ8Y1$MdSettings))`\n font-size: 1.2rem;\n opacity: 0.4;\n width: 1rem;\n &:hover {\n opacity: 1;\n cursor: pointer;\n }\n`;\nconst $ff9a1ac4f0decadf$var$InfoIconWrapper = (0, $qQ8Y1$emotionstyled)((0, $qQ8Y1$MdInfoOutline))`\n font-size: 1.2rem;\n opacity: 0.4;\n width: 1rem;\n &:hover {\n opacity: 1;\n cursor: pointer;\n }\n`;\nconst $ff9a1ac4f0decadf$var$Section = (0, $qQ8Y1$emotionstyled).div`\n position: relative;\n font-family: var(--leva-fonts-mono);\n font-size: var(--leva-fontSizes-root);\n background-color: var(--leva-colors-elevation1);\n`;\nconst $ff9a1ac4f0decadf$export$1bdb8f2d1fe25c22 = (0, $qQ8Y1$emotionstyled)($ff9a1ac4f0decadf$var$Section)`\n display: flex;\n height: var(--leva-sizes-titleBarHeight);\n touch-action: none;\n align-items: center;\n justify-content: center;\n flex: 1 1 0%;\n color: var(--leva-colors-highlight1);\n padding: 0 0.4rem;\n gap: 0.3rem;\n`;\nconst $ff9a1ac4f0decadf$export$bfd3bd1fa283e3c6 = (0, $qQ8Y1$emotionstyled)($ff9a1ac4f0decadf$var$Section)(({ theme: theme })=>`\n display: grid;\n grid-template-areas: \"inputs outputs\";\n background: ${theme.colors.elevation2};\n border-bottom: 1px solid ${theme.colors.elevation1};\n color: ${theme.colors.highlight3};\n font-size: 0.6rem;\n`);\nconst $ff9a1ac4f0decadf$export$f1afba0ff9ea1277 = (0, $qQ8Y1$emotionstyled).div`\n grid-area: inputs;\n text-align: left;\n`;\nconst $ff9a1ac4f0decadf$export$af4f9b41fc32ed9e = (0, $qQ8Y1$emotionstyled).div`\n grid-area: outputs;\n text-align: right;\n`;\nconst $ff9a1ac4f0decadf$export$a2d375858cc72119 = (0, $qQ8Y1$emotionstyled).div`\n position: relative;\n padding: 5px 10px;\n`;\nconst $ff9a1ac4f0decadf$var$portColors = {\n [(0, $cfbf5bba42d581f6$export$b0b7b95ee465c83c).Audio]: \"#4ade80\",\n [(0, $cfbf5bba42d581f6$export$b0b7b95ee465c83c).Gate]: \"#c084fc\",\n [(0, $cfbf5bba42d581f6$export$b0b7b95ee465c83c).Number]: \"#38bdf8\",\n [(0, $cfbf5bba42d581f6$export$b0b7b95ee465c83c).Any]: \"#ffffff\"\n};\nconst $ff9a1ac4f0decadf$var$StyledHandle = (0, $qQ8Y1$withTheme)((0, $qQ8Y1$emotionstyled)((0, $qQ8Y1$Handle), {\n shouldForwardProp: (prop)=>prop !== \"portType\"\n})`\n --port-color: ${(props)=>{\n if (!props.portType) return props.theme.colors.highlight2;\n if (Array.isArray(props.portType)) {\n const colors = props.portType.map((type)=>$ff9a1ac4f0decadf$var$portColors[type]);\n return `linear-gradient(0.25turn, ${colors.join(\", \")});`;\n } else return $ff9a1ac4f0decadf$var$portColors[props.portType];\n}};\n border-color: var(--port-color);\n background: var(--port-color);\n box-shadow: 0px 0px 0px 1px ${({ theme: theme })=>theme.colors.elevation2} inset;\n`);\nconst $ff9a1ac4f0decadf$var$StyledInputHandle = (0, $qQ8Y1$withTheme)((0, $qQ8Y1$emotionstyled)($ff9a1ac4f0decadf$var$StyledHandle)`\n left: -3px;\n`);\nconst $ff9a1ac4f0decadf$export$9ea0feffc20ee81 = ({ ...props })=>(0, $qQ8Y1$jsx)($ff9a1ac4f0decadf$var$StyledInputHandle, {\n ...props,\n type: \"target\",\n position: (0, $qQ8Y1$Position).Left\n });\nconst $ff9a1ac4f0decadf$export$222539e2a2fac4e0 = (0, $qQ8Y1$withTheme)((0, $qQ8Y1$emotionstyled)($ff9a1ac4f0decadf$var$StyledHandle)`\n right: -3px;\n`);\nconst $ff9a1ac4f0decadf$export$496e5e1ee1696f64 = (props)=>(0, $qQ8Y1$jsx)($ff9a1ac4f0decadf$export$222539e2a2fac4e0, {\n ...props,\n type: \"source\",\n position: (0, $qQ8Y1$Position).Right\n });\nconst $ff9a1ac4f0decadf$export$7e0b3af1e60a3273 = ({ className: className, ...props })=>(0, $qQ8Y1$jsx)($ff9a1ac4f0decadf$export$1bdb8f2d1fe25c22, {\n ...props,\n className: [\n className,\n (0, $cfbf5bba42d581f6$export$956b3cf15d7c363)\n ].join(\" \")\n });\nconst $ff9a1ac4f0decadf$var$useNodeManifest = (type)=>{\n const data = (0, $e44921bed281a717$export$2e2bcd8739ae039)((store)=>store.nodesConfiguration[type]);\n return data;\n};\nconst $ff9a1ac4f0decadf$var$useConfigNode = (type)=>{\n const { configNode: ConfigNode } = $ff9a1ac4f0decadf$var$useNodeManifest(type);\n return {\n ConfigNode: ConfigNode\n };\n};\nconst $ff9a1ac4f0decadf$export$361064385d50ec44 = (props)=>{\n const { id: id, children: children, selected: selected, ...rest } = props;\n const theme = (0, $aa2521e46fde4290$export$2e2bcd8739ae039)();\n const getNode = (0, $e44921bed281a717$export$2e2bcd8739ae039)(({ getNode: getNode })=>getNode);\n const nodesConfiguration = (0, $e44921bed281a717$export$2e2bcd8739ae039)((store)=>store.nodesConfiguration);\n const [isInfoModalShown, setIsInfoModalShown] = (0, $qQ8Y1$useState)(false);\n const { info: info } = $ff9a1ac4f0decadf$var$useNodeManifest(props.type);\n const isResizeable = (0, $qQ8Y1$useMemo)(()=>nodesConfiguration[props.type].resizable ?? false, [\n nodesConfiguration,\n props.type\n ]);\n const { updateNodeLabel: updateNodeLabel, updateNodeConfig: updateNodeConfig } = (0, $712d0a8959c2f3aa$export$2e2bcd8739ae039)(id);\n const { data: data } = getNode(id) || {};\n const audioNode = (0, $acc48893b410c429$export$2e2bcd8739ae039)(id);\n const { ConfigNode: ConfigNode } = $ff9a1ac4f0decadf$var$useConfigNode(rest.type);\n const [configMode, setShowConfigMode] = (0, $qQ8Y1$useState)(false);\n if (!audioNode) return (0, $qQ8Y1$jsx)($ff9a1ac4f0decadf$var$NodeLoaderWrapper, {\n className: (0, $cfbf5bba42d581f6$export$956b3cf15d7c363),\n children: \"can't find audio node\"\n });\n if (audioNode.loading) return (0, $qQ8Y1$jsx)($ff9a1ac4f0decadf$var$NodeLoaderWrapper, {\n className: (0, $cfbf5bba42d581f6$export$956b3cf15d7c363),\n children: \"loading\"\n });\n if (audioNode.error) return (0, $qQ8Y1$jsxs)($ff9a1ac4f0decadf$var$NodeErrorWrapper, {\n className: (0, $cfbf5bba42d581f6$export$956b3cf15d7c363),\n children: [\n \"error: \",\n audioNode.error.toString()\n ]\n });\n if (!audioNode.node) return (0, $qQ8Y1$jsx)($ff9a1ac4f0decadf$var$NodeLoaderWrapper, {\n className: (0, $cfbf5bba42d581f6$export$956b3cf15d7c363),\n children: \"can't find audio node\"\n });\n const size = data?.config?.size;\n const { node: { inputs: inputs, outputs: outputs } } = audioNode;\n return (0, $qQ8Y1$jsxs)($ff9a1ac4f0decadf$var$NodeWrapper, {\n children: [\n (0, $qQ8Y1$jsxs)($ff9a1ac4f0decadf$export$7e0b3af1e60a3273, {\n children: [\n info && (0, $qQ8Y1$jsx)($ff9a1ac4f0decadf$var$InfoIconWrapper, {\n onClickCapture: ()=>setIsInfoModalShown(true)\n }),\n (0, $qQ8Y1$jsx)((0, $a2cf3f549395b7f1$export$2e2bcd8739ae039), {\n value: data?.label ?? \"No Name\",\n onChange: updateNodeLabel\n }),\n ConfigNode && (0, $qQ8Y1$jsx)($ff9a1ac4f0decadf$var$SettingsIconWrapper, {\n onClickCapture: ()=>setShowConfigMode((isShown)=>!isShown)\n })\n ]\n }),\n (0, $qQ8Y1$jsxs)($ff9a1ac4f0decadf$export$bfd3bd1fa283e3c6, {\n theme: theme,\n children: [\n (0, $qQ8Y1$jsx)($ff9a1ac4f0decadf$export$f1afba0ff9ea1277, {\n children: inputs ? Object.keys(inputs).map((key, index)=>(0, $qQ8Y1$jsxs)($ff9a1ac4f0decadf$export$a2d375858cc72119, {\n children: [\n (0, $qQ8Y1$jsx)($ff9a1ac4f0decadf$export$9ea0feffc20ee81, {\n id: key,\n portType: inputs[key].type\n }),\n (0, $qQ8Y1$jsx)(\"span\", {\n children: key\n })\n ]\n }, index)) : null\n }),\n (0, $qQ8Y1$jsx)($ff9a1ac4f0decadf$export$af4f9b41fc32ed9e, {\n children: outputs ? Object.keys(outputs).map((key, index)=>(0, $qQ8Y1$jsxs)($ff9a1ac4f0decadf$export$a2d375858cc72119, {\n children: [\n (0, $qQ8Y1$jsx)($ff9a1ac4f0decadf$export$496e5e1ee1696f64, {\n id: key,\n portType: outputs[key].type\n }),\n (0, $qQ8Y1$jsx)(\"span\", {\n children: key\n })\n ]\n }, index)) : null\n })\n ]\n }),\n ConfigNode && configMode && selected ? (0, $qQ8Y1$jsx)(ConfigNode, {\n ...props\n }) : isResizeable ? (0, $qQ8Y1$jsx)((0, $qQ8Y1$Resizable), {\n size: size,\n minWidth: 180,\n minHeight: 30,\n enable: {\n bottom: true,\n bottomRight: true,\n right: true\n },\n onResizeStop: (e, direction, ref, d)=>{\n const newSize = size ? {\n width: size.width + d.width,\n height: size.height + d.height\n } : ref.getBoundingClientRect();\n updateNodeConfig({\n ...data?.config,\n size: newSize\n });\n },\n children: children\n }) : children,\n (0, $qQ8Y1$jsx)((0, $c49c7ecc2471f2b1$export$2e2bcd8739ae039), {\n isOpen: isInfoModalShown,\n type: props.type,\n onClose: ()=>setIsInfoModalShown(false),\n node: audioNode.node\n })\n ]\n });\n};\n\n\nconst $4d70bd882ba90559$export$86de09faaa70680d = (0, $qQ8Y1$emotionstyled).div`\n width: 100%;\n padding: 0.4rem 0;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n`;\nconst $4d70bd882ba90559$export$548ca3bae446ddc2 = (0, $qQ8Y1$emotionstyled)((0, $ff9a1ac4f0decadf$export$7e0b3af1e60a3273))`\n display: flex;\n gap: 0.1rem;\n padding: 0 0.4rem;\n justify-content: start;\n font-size: 0.6rem;\n height: auto;\n min-width: 0;\n`;\nconst $4d70bd882ba90559$export$9fb15e3cc717240 = (0, $qQ8Y1$emotionstyled).div`\n display: flex;\n align-items: center;\n height: 70%;\n width: auto;\n gap: 0.4rem;\n`;\nconst $4d70bd882ba90559$export$be58b4326e23250f = (0, $qQ8Y1$emotionstyled).span`\n width: auto;\n height: 100%;\n cursor: pointer;\n svg {\n width: auto;\n height: 100%;\n }\n &:hover {\n color: ${({ theme: theme })=>theme.colors.highlight2};\n cursor: pointer;\n }\n`;\n\n\nconst $ac708c82d4748923$var$ControlPanelNodeWrapper = (0, $qQ8Y1$emotionstyled).div`\n height: 100%;\n display: grid;\n grid-template-rows: auto 1fr;\n`;\nconst $ac708c82d4748923$var$PanelNode = (props)=>{\n const { node: node } = props;\n const getControlPanelNode = (0, $e44921bed281a717$export$2e2bcd8739ae039)((store)=>store.getControlPanelNode);\n const ControlPanelNode = (0, $qQ8Y1$useMemo)(()=>getControlPanelNode(node), [\n node\n ]);\n if (!ControlPanelNode) return null;\n return (0, $qQ8Y1$jsx)(ControlPanelNode, {\n ...props\n });\n};\nconst $ac708c82d4748923$var$ControlPanelItem = (props)=>{\n const { node: node, showControls: showControls, onDelete: onDelete } = props;\n const theme = (0, $aa2521e46fde4290$export$2e2bcd8739ae039)();\n const { id: id } = node;\n const { node: audioNode } = (0, $acc48893b410c429$export$2e2bcd8739ae039)(id) || {};\n const { updateNodeValues: updateNodeValues } = (0, $712d0a8959c2f3aa$export$2e2bcd8739ae039)(id);\n return (0, $qQ8Y1$jsxs)($ac708c82d4748923$var$ControlPanelNodeWrapper, {\n theme: theme,\n children: [\n (0, $qQ8Y1$jsxs)((0, $4d70bd882ba90559$export$548ca3bae446ddc2), {\n theme: theme,\n children: [\n (0, $qQ8Y1$jsx)((0, $4d70bd882ba90559$export$86de09faaa70680d), {\n children: node.data.label\n }),\n showControls && (0, $qQ8Y1$jsxs)((0, $4d70bd882ba90559$export$9fb15e3cc717240), {\n children: [\n (0, $qQ8Y1$jsx)((0, $4d70bd882ba90559$export$be58b4326e23250f), {\n theme: theme,\n children: (0, $qQ8Y1$jsx)((0, $qQ8Y1$MdDragHandle), {\n className: \"grid-item-handle\"\n })\n }),\n (0, $qQ8Y1$jsx)((0, $4d70bd882ba90559$export$be58b4326e23250f), {\n theme: theme,\n children: (0, $qQ8Y1$jsx)((0, $qQ8Y1$MdClose), {\n onClick: ()=>onDelete(node)\n })\n })\n ]\n })\n ]\n }),\n (0, $qQ8Y1$jsx)($ac708c82d4748923$var$PanelNode, {\n node: node,\n audioNode: audioNode,\n updateNodeValues: updateNodeValues\n })\n ]\n });\n};\nvar $ac708c82d4748923$export$2e2bcd8739ae039 = $ac708c82d4748923$var$ControlPanelItem;\n\n\n\nconst $1c4c5bb8d78eb6a9$var$ControlPanelIconWrapper = (0, $qQ8Y1$emotionstyled).div`\n position: fixed;\n z-index: 5;\n box-shadow: 0px 1px 2px ${({ theme: theme })=>theme.colors.elevation2};\n left: 1rem;\n top: 4rem;\n width: 2rem;\n height: 2rem;\n border-radius: 50%;\n overflow: hidden;\n display: flex;\n align-items: center;\n justify-content: center;\n background: ${({ theme: theme })=>theme.colors.elevation1};\n color: ${({ theme: theme })=>theme.colors.highlight1};\n\n :hover {\n color: ${({ theme: theme })=>theme.colors.highlight2};\n cursor: pointer;\n }\n`;\nconst $1c4c5bb8d78eb6a9$var$ControlPanelIconsBar = (0, $qQ8Y1$emotionstyled)((0, $4d70bd882ba90559$export$9fb15e3cc717240))`\n height: 80%;\n`;\nconst $1c4c5bb8d78eb6a9$var$CloseIconWrapper = (0, $qQ8Y1$emotionstyled)((0, $4d70bd882ba90559$export$be58b4326e23250f))`\n font-size: 1rem;\n display: flex;\n align-items: center;\n`;\nconst $1c4c5bb8d78eb6a9$var$ControlPanelHeader = (0, $qQ8Y1$emotionstyled)((0, $4d70bd882ba90559$export$548ca3bae446ddc2))`\n grid-template-columns: 1fr auto;\n border-bottom: 1px solid ${({ theme: theme })=>theme.colors.elevation3};\n font-size: 0.7rem;\n`;\nconst $1c4c5bb8d78eb6a9$var$ControlPanelTitle = (0, $qQ8Y1$emotionstyled)((0, $4d70bd882ba90559$export$86de09faaa70680d))`\n text-align: center;\n`;\nconst $1c4c5bb8d78eb6a9$var$ControlPanelWrapper = (0, $qQ8Y1$emotionstyled).div`\n height: 100%;\n width: 100%;\n padding: 0.3rem 0.4rem;\n box-sizing: border-box;\n`;\nconst $1c4c5bb8d78eb6a9$var$ControlPanelBody = (0, $qQ8Y1$emotionstyled).div`\n height: auto;\n padding: 0;\n max-height: 95vh;\n overflow-y: scroll;\n border: 1px solid ${({ theme: theme })=>theme.colors.elevation3};\n`;\nconst $1c4c5bb8d78eb6a9$var$ControlPanelSettings = (0, $qQ8Y1$emotionstyled).div`\n padding: 1rem 0;\n font-family: var(--leva-fonts-mono);\n font-size: 0.8rem;\n`;\nconst $1c4c5bb8d78eb6a9$var$LockGridWrapper = (0, $qQ8Y1$emotionstyled).div`\n display: flex;\n align-items: center;\n gap: 0.5rem;\n cursor: pointer;\n color: ${({ theme: theme })=>theme.colors.highlight1};\n &:hover {\n color: ${({ theme: theme })=>theme.colors.highlight2};\n }\n`;\nconst $1c4c5bb8d78eb6a9$var$GridResizeHandle = (0, $qQ8Y1$emotionstyled).div`\n position: absolute;\n height: 1rem;\n top: 0;\n bottom: 0;\n margin: auto;\n left: 0.5rem;\n border-right: 1px solid ${({ theme: theme })=>theme.colors.whitePrimary};\n`;\nconst $1c4c5bb8d78eb6a9$var$ControlPanelItemWrapper = (0, $qQ8Y1$emotionstyled).div`\n box-sizing: border-box;\n overflow: hidden;\n .react-resizable-handle:after {\n border-color: ${({ theme: theme })=>theme.colors.whitePrimary};\n border-width: 1px;\n }\n`;\nconst $1c4c5bb8d78eb6a9$var$ControlPanel = ()=>{\n const theme = (0, $aa2521e46fde4290$export$2e2bcd8739ae039)();\n const nodeRef = (0, $qQ8Y1$useRef)(null);\n const nodes = (0, $e44921bed281a717$export$2e2bcd8739ae039)((store)=>store.nodes);\n const { show: show, nodes: controlPanelNodes, size: size } = (0, $e44921bed281a717$export$2e2bcd8739ae039)((store)=>store.controlPanel);\n const { width: width = 200, height: height } = size;\n const filteredNodes = (0, $qQ8Y1$useMemo)(()=>{\n const nodeIds = controlPanelNodes.map(({ id: id })=>id);\n return nodes.filter(({ id: id })=>nodeIds.includes(id));\n }, [\n nodes,\n controlPanelNodes\n ]);\n const showControlPanel = (0, $e44921bed281a717$export$2e2bcd8739ae039)((store)=>store.showControlPanel);\n const hideControlPanel = (0, $e44921bed281a717$export$2e2bcd8739ae039)((store)=>store.hideControlPanel);\n const setControlPanelNodes = (0, $e44921bed281a717$export$2e2bcd8739ae039)((store)=>store.setControlPanelNodes);\n const setControlPanelSize = (0, $e44921bed281a717$export$2e2bcd8739ae039)((store)=>store.setControlPanelSize);\n const removeNodeFromControlPanel = (0, $e44921bed281a717$export$2e2bcd8739ae039)((store)=>store.removeNodeFromControlPanel);\n const [isGridLocked, setGridLocked] = (0, $qQ8Y1$useState)(true);\n const layout = (0, $qQ8Y1$useMemo)(()=>{\n const fallbackY = controlPanelNodes.reduce((acc, { height: height = (0, $cfbf5bba42d581f6$export$9f05d3e6ade4c09e).rowHeight, x: x, y: y = 0 })=>{\n const Y = y + height;\n return Y > acc ? Y : acc;\n }, 0);\n return controlPanelNodes.map(({ id: i, width: width, height: height, x: x, y: y })=>{\n return {\n i: i,\n w: width || (0, $cfbf5bba42d581f6$export$9f05d3e6ade4c09e).cols,\n h: height || 6,\n x: x ?? 0,\n y: y ?? fallbackY\n };\n });\n }, [\n controlPanelNodes\n ]);\n if (!filteredNodes.length) return null;\n return (0, $qQ8Y1$jsxs)((0, $qQ8Y1$Fragment), {\n children: [\n (0, $qQ8Y1$jsx)($1c4c5bb8d78eb6a9$var$ControlPanelIconWrapper, {\n theme: theme,\n ref: nodeRef,\n onClick: showControlPanel,\n children: (0, $qQ8Y1$jsx)((0, $qQ8Y1$RxDashboard), {})\n }),\n (0, $qQ8Y1$jsxs)((0, $qQ8Y1$reactmoderndrawer), {\n open: show,\n onClose: hideControlPanel,\n direction: \"left\",\n className: \"\",\n size: \"auto\",\n enableOverlay: false,\n style: {\n background: theme.colors.elevation1,\n position: \"absolute\"\n },\n children: [\n (0, $qQ8Y1$jsxs)($1c4c5bb8d78eb6a9$var$ControlPanelHeader, {\n theme: theme,\n children: [\n (0, $qQ8Y1$jsx)($1c4c5bb8d78eb6a9$var$ControlPanelTitle, {\n children: \"Control Panel\"\n }),\n (0, $qQ8Y1$jsx)($1c4c5bb8d78eb6a9$var$ControlPanelIconsBar, {\n children: (0, $qQ8Y1$jsx)($1c4c5bb8d78eb6a9$var$CloseIconWrapper, {\n onClick: hideControlPanel,\n theme: theme,\n children: (0, $qQ8Y1$jsx)((0, $qQ8Y1$MdClose), {})\n })\n })\n ]\n }),\n (0, $qQ8Y1$jsxs)($1c4c5bb8d78eb6a9$var$ControlPanelWrapper, {\n children: [\n (0, $qQ8Y1$jsx)($1c4c5bb8d78eb6a9$var$ControlPanelSettings, {\n children: isGridLocked ? (0, $qQ8Y1$jsxs)($1c4c5bb8d78eb6a9$var$LockGridWrapper, {\n theme: theme,\n onClick: ()=>setGridLocked(false),\n children: [\n (0, $qQ8Y1$jsx)((0, $qQ8Y1$AiFillLock), {}),\n \"Unlock grid\"\n ]\n }) : (0, $qQ8Y1$jsxs)($1c4c5bb8d78eb6a9$var$LockGridWrapper, {\n theme: theme,\n onClick: ()=>setGridLocked(true),\n children: [\n (0, $qQ8Y1$jsx)((0, $qQ8Y1$AiFillUnlock), {}),\n \"Lock grid\"\n ]\n })\n }),\n (0, $qQ8Y1$jsx)((0, $qQ8Y1$Resizable), {\n enable: {\n top: false,\n right: !isGridLocked,\n bottom: false,\n left: false,\n topRight: false,\n bottomRight: false,\n bottomLeft: false,\n topLeft: false\n },\n handleComponent: {\n right: (0, $qQ8Y1$jsx)($1c4c5bb8d78eb6a9$var$GridResizeHandle, {\n theme: theme\n })\n },\n minWidth: 120,\n size: {\n width: width,\n height: \"auto\"\n },\n onResizeStop: (e, direction, ref, d)=>{\n setControlPanelSize({\n width: width + d.width,\n height: height + d.height\n });\n },\n children: (0, $qQ8Y1$jsx)($1c4c5bb8d78eb6a9$var$ControlPanelBody, {\n theme: theme,\n children: (0, $qQ8Y1$jsx)((0, $qQ8Y1$reactgridlayout), {\n layout: layout,\n className: \"layout\",\n cols: (0, $cfbf5bba42d581f6$export$9f05d3e6ade4c09e).cols,\n rowHeight: (0, $cfbf5bba42d581f6$export$9f05d3e6ade4c09e).rowHeight,\n width: width,\n margin: [\n 0,\n 0\n ],\n isResizable: !isGridLocked,\n draggableHandle: \".grid-item-handle\",\n onLayoutChange: (nodes)=>{\n requestAnimationFrame(()=>{\n setControlPanelNodes(nodes.map(({ i: i, w: w, h: h, x: x, y: y })=>({\n id: i,\n width: w,\n height: h,\n x: x,\n y: y\n })));\n });\n },\n children: filteredNodes.map((node)=>{\n return (0, $qQ8Y1$jsx)($1c4c5bb8d78eb6a9$var$ControlPanelItemWrapper, {\n theme: theme,\n children: (0, $qQ8Y1$jsx)((0, $ac708c82d4748923$export$2e2bcd8739ae039), {\n node: node,\n showControls: !isGridLocked,\n onDelete: removeNodeFromControlPanel\n })\n }, node.id);\n })\n })\n })\n })\n ]\n })\n ]\n })\n ]\n });\n};\nvar $1c4c5bb8d78eb6a9$export$2e2bcd8739ae039 = $1c4c5bb8d78eb6a9$var$ControlPanel;\n\n\n\n\n\n\n\n\n\n\n\n\nvar $fddbb316f10bd69c$exports = {};\n$fddbb316f10bd69c$exports = \"# Quick start\\n\\n## Add node\\n - Mouse right click\\n - Select **'Add Node'** from context menu\\n\\n ### &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;or\\n\\n - Press `CMD+SHIFT+A`\\n\\n<br/>\\n\\n## Connect nodes\\n - Mouse left click and hold on source port\\n - Drop on target port\\n\\n<br/>\\n\\n## Delete Node or Connection\\n - Mouse right click on node/connection\\n - Select **'Delete Node'**/**'Delete Connection'** from context menu\\n\\n ### &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;or\\n\\n - Mouse left click on node/connection, then press `Backspace`\\n\\n<br/>\\n\\n\\n## Move node\\n - Drag and Drop\\n\\n<br/>\\n\\n## Upload file\\n - Drag and drop audio or patch files onto the application\\n - Uploaded file appears as a new tab in the tabs bar at the top\\n - Click on the tab to view or edit the file\\n\\n\\n\";\n\n\nconst $c4aeaed06c94e6bd$var$MdPreview = (0, $qQ8Y1$withTheme)((0, $qQ8Y1$emotionstyled).div`\n font-family: var(--leva-fonts-mono);\n font-size: 0.7rem;\n box-sizing: border-box;\n height: 100%;\n width: 100%;\n overflow: scroll;\n color: ${({ theme: theme })=>theme.colors.whitePrimary};\n padding: 0 0.5rem;\n\n code {\n color: ${({ theme: theme })=>theme.colors.accent3};\n filter: hue-rotate(180deg);\n }\n`);\nconst $c4aeaed06c94e6bd$var$ModalContent = (0, $qQ8Y1$withTheme)((0, $qQ8Y1$emotionstyled).div`\n padding: 1rem;\n height: 100%;\n width: 100%;\n box-sizing: border-box;\n overflow: hidden;\n`);\nconst $c4aeaed06c94e6bd$var$HelpModal = ()=>{\n const isHelpShown = (0, $e44921bed281a717$export$2e2bcd8739ae039)((store)=>store.isHelpShown);\n const toggleHelp = (0, $e44921bed281a717$export$2e2bcd8739ae039)((store)=>store.toggleHelp);\n if (!isHelpShown) return null;\n return (0, $qQ8Y1$jsx)((0, $6c9029bae1fda307$export$2e2bcd8739ae039), {\n onClose: ()=>{\n toggleHelp();\n },\n children: (0, $qQ8Y1$jsx)($c4aeaed06c94e6bd$var$ModalContent, {\n children: (0, $qQ8Y1$jsx)($c4aeaed06c94e6bd$var$MdPreview, {\n dangerouslySetInnerHTML: {\n __html: (0, $qQ8Y1$marked)((0, (/*@__PURE__*/$parcel$interopDefault($fddbb316f10bd69c$exports))))\n },\n onWheelCapture: (event)=>event.stopPropagation()\n })\n })\n });\n};\nvar $c4aeaed06c94e6bd$export$2e2bcd8739ae039 = $c4aeaed06c94e6bd$var$HelpModal;\n\n\nconst $aaf6e15ae0d6178d$export$78bddedbcf2939ac = ()=>{\n const toggleHelp = (0, $e44921bed281a717$export$2e2bcd8739ae039)((store)=>store.toggleHelp);\n return (0, $qQ8Y1$jsx)((0, $qQ8Y1$Fragment), {\n children: (0, $qQ8Y1$jsx)((0, $qQ8Y1$ControlButton), {\n onClick: toggleHelp,\n children: (0, $qQ8Y1$jsx)((0, $qQ8Y1$FaQuestion), {})\n })\n });\n};\n\n\n\n\n\n\n\n\nconst $5f56149382e8930d$var$Layout = (0, $qQ8Y1$emotionstyled).div`\n position: fixed;\n z-index: ${({ theme: theme })=>theme.zIndex.resumeContextLayout};\n width: 100%;\n height: 100%;\n top: 0;\n left: 0;\n background: rgb(24 28 32 / 90%);\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: center;\n color: ${({ theme: theme })=>theme.colors.whitePrimary};\n cursor: pointer;\n`;\nconst $5f56149382e8930d$var$Row = (0, $qQ8Y1$emotionstyled).div`\n display: flex;\n width: 100%;\n align-items: center;\n justify-content: center;\n`;\nconst $5f56149382e8930d$var$Message = (0, $qQ8Y1$emotionstyled).div`\n font-family: var(--leva-fonts-mono);\n font-size: 2rem;\n`;\nconst $5f56149382e8930d$var$Icon = (0, $qQ8Y1$emotionstyled)((0, $qQ8Y1$FaVolumeOff))`\n width: 7rem;\n height: 7rem;\n`;\nconst $5f56149382e8930d$var$ResumeContext = ()=>{\n const theme = (0, $aa2521e46fde4290$export$2e2bcd8739ae039)();\n const patch = (0, $e44921bed281a717$export$2e2bcd8739ae039)(({ patch: patch })=>patch);\n const audioContext = patch.audioContext;\n const [isContextResumed, setIsContextResumed] = (0, $qQ8Y1$useState)(audioContext.state === \"running\");\n if (isContextResumed) return null;\n return (0, $qQ8Y1$jsxs)($5f56149382e8930d$var$Layout, {\n theme: theme,\n onClick: ()=>{\n audioContext.resume();\n setIsContextResumed(true);\n },\n children: [\n (0, $qQ8Y1$jsx)($5f56149382e8930d$var$Row, {\n children: (0, $qQ8Y1$jsx)($5f56149382e8930d$var$Message, {\n theme: theme,\n children: \"Click anywhere to resume audio context\"\n })\n }),\n (0, $qQ8Y1$jsx)($5f56149382e8930d$var$Row, {\n children: (0, $qQ8Y1$jsx)($5f56149382e8930d$var$Icon, {})\n })\n ]\n });\n};\nvar $5f56149382e8930d$export$2e2bcd8739ae039 = $5f56149382e8930d$var$ResumeContext;\n\n\n\n\n\n\nconst $728d3535906a11ab$var$ToggleMinimap = ()=>{\n const setConfig = (0, $e44921bed281a717$export$2e2bcd8739ae039)(({ setConfig: setConfig })=>setConfig);\n const { showMinimap: showMinimap } = (0, $e44921bed281a717$export$2e2bcd8739ae039)(({ config: config })=>config);\n return (0, $qQ8Y1$jsx)((0, $qQ8Y1$ControlButton), {\n onClick: ()=>setConfig({\n showMinimap: !showMinimap\n }),\n children: showMinimap ? (0, $qQ8Y1$jsx)((0, $qQ8Y1$FaMap), {}) : (0, $qQ8Y1$jsx)((0, $qQ8Y1$FaRegMap), {})\n });\n};\nvar $728d3535906a11ab$export$2e2bcd8739ae039 = $728d3535906a11ab$var$ToggleMinimap;\n\n\n\n\n\n\n\nconst $bdef559cce331667$var$Wire = ({ id: id, sourceX: sourceX, sourceY: sourceY, targetX: targetX, targetY: targetY, sourcePosition: sourcePosition, targetPosition: targetPosition, style: style = {}, data: data, markerStart: markerStart, markerEnd: markerEnd, source: source, target: target, sourceHandleId: sourceHandleId, targetHandleId: targetHandleId, selected: selected })=>{\n const theme = (0, $aa2521e46fde4290$export$2e2bcd8739ae039)();\n const getNode = (0, $e44921bed281a717$export$2e2bcd8739ae039)(({ getNode: getNode })=>getNode);\n const sourceNode = getNode(source);\n const targetNode = getNode(target);\n const isConnectedToSelected = sourceNode?.selected || targetNode?.selected;\n (0, $qQ8Y1$useEffect)(()=>{\n if (!sourceHandleId || !targetHandleId) return;\n console.log(`connected ${source} to ${target}`);\n return ()=>{\n console.log(`disconnected ${source} from ${target}`);\n };\n }, [\n source,\n sourceHandleId,\n target,\n targetHandleId\n ]);\n const [edgePath] = (0, $qQ8Y1$getBezierPath)({\n targetX: targetX,\n targetY: targetY,\n targetPosition: targetPosition,\n sourceX: sourceX,\n sourceY: sourceY,\n sourcePosition: sourcePosition\n });\n return (0, $qQ8Y1$jsxs)((0, $qQ8Y1$Fragment), {\n children: [\n (0, $qQ8Y1$jsx)(\"path\", {\n id: id,\n style: {\n ...style,\n stroke: selected ? theme.colors.accent2 : isConnectedToSelected ? theme.colors.highlight3 : theme.colors.highlight2\n },\n className: \"react-flow__edge-path Wire\",\n d: edgePath,\n markerEnd: markerEnd\n }),\n (0, $qQ8Y1$jsx)(\"path\", {\n style: {\n ...style,\n strokeWidth: 8,\n color: \"transparent\",\n opacity: 0,\n cursor: \"pointer\"\n },\n d: edgePath,\n markerEnd: markerEnd\n })\n ]\n });\n};\nvar $bdef559cce331667$export$2e2bcd8739ae039 = $bdef559cce331667$var$Wire;\n\n\nconsole.log(99999, `React version: ${(0, $qQ8Y1$version)}`);\nconst $83a57bff646cb127$var$onNodeDragStop = (_event, node)=>console.log(\"drag stop\", node);\nconst $83a57bff646cb127$var$onNodeClick = (_event, element)=>console.log(\"click\", element);\nconst $83a57bff646cb127$var$snapGrid = [\n 20,\n 20\n];\nconst $83a57bff646cb127$export$72cb76f559fbafcf = ({ editorState: editorState, plugins: plugins = [], editorContextMenu: editorContextMenu = [], onChange: onChange = ()=>{}, ...props })=>{\n const edgeTypes = (0, $qQ8Y1$useMemo)(()=>({\n wire: (0, $bdef559cce331667$export$2e2bcd8739ae039)\n }), []);\n const { nodes: nodes, edges: edges, controlPanel: controlPanel, onNodesChange: onNodesChange, onNodesDelete: onNodesDelete, onEdgesChange: onEdgesChange, onEdgesDelete: onEdgesDelete, onConnect: onConnect, setPlugins: setPlugins, setViewport: setViewport, viewport: viewport } = (0, $e44921bed281a717$export$2e2bcd8739ae039)();\n const editorConfig = (0, $e44921bed281a717$export$2e2bcd8739ae039)(({ config: config })=>config);\n const nodeTypes = (0, $e44921bed281a717$export$2e2bcd8739ae039)(({ nodeTypes: nodeTypes })=>nodeTypes);\n (0, $qQ8Y1$useEffect)(()=>{\n setPlugins(plugins);\n }, [\n plugins\n ]);\n const [reactflowInstance, setReactflowInstance] = (0, $qQ8Y1$useState)(null);\n (0, $qQ8Y1$useEffect)(()=>{\n if (!reactflowInstance) return;\n onChange({\n nodes: nodes,\n edges: edges,\n controlPanel: controlPanel,\n viewport: viewport\n });\n }, [\n nodes,\n edges,\n controlPanel,\n viewport\n ]);\n const onInit = (0, $qQ8Y1$useCallback)((rfi)=>{\n if (!reactflowInstance) {\n setReactflowInstance(rfi);\n console.log(\"flow loaded:\", rfi);\n }\n }, [\n reactflowInstance\n ]);\n const { onContextMenu: onEditorContextMenu } = (0, $8827576290cfe6c8$export$59ce2a6808e35a29)();\n const { onContextMenu: onNodeContextMenu } = (0, $3d16dc6c2f6416d3$export$cbbbfb9fb15f3780)();\n const { onContextMenu: onEdgeContextMenu } = (0, $7ba264c3aa450939$export$8b2e4a15453bac1e)();\n (0, $qQ8Y1$useEffect)(()=>{\n if (!viewport) return;\n reactflowInstance?.setViewport(viewport);\n }, [\n viewport,\n reactflowInstance\n ]);\n (0, $qQ8Y1$useOnViewportChange)({\n onEnd: setViewport\n });\n return (0, $qQ8Y1$jsxs)((0, $qQ8Y1$reactflow), {\n nodes: nodes,\n edges: edges,\n onNodesChange: onNodesChange,\n onNodesDelete: onNodesDelete,\n onEdgesChange: onEdgesChange,\n onConnect: onConnect,\n onNodeDragStop: $83a57bff646cb127$var$onNodeDragStop,\n onEdgesDelete: onEdgesDelete,\n onInit: onInit,\n onNodeClick: $83a57bff646cb127$var$onNodeClick,\n onContextMenu: onEditorContextMenu,\n onNodeContextMenu: onNodeContextMenu,\n onEdgeContextMenu: onEdgeContextMenu,\n nodeTypes: nodeTypes,\n edgeTypes: edgeTypes,\n snapGrid: $83a57bff646cb127$var$snapGrid,\n defaultViewport: editorState?.viewport,\n defaultEdgeOptions: {\n type: \"wire\"\n },\n snapToGrid: true,\n fitView: true,\n disableKeyboardA11y: true,\n children: [\n (0, $qQ8Y1$jsx)((0, $qQ8Y1$Background), {\n variant: (0, $qQ8Y1$BackgroundVariant).Dots,\n gap: 12\n }),\n editorConfig.showMinimap ? (0, $qQ8Y1$jsx)((0, $qQ8Y1$MiniMap), {}) : null,\n (0, $qQ8Y1$jsxs)((0, $qQ8Y1$Controls), {\n style: {\n right: \"1rem\",\n left: \"initial\",\n bottom: \"40%\",\n top: \"initial\"\n },\n showInteractive: false,\n children: [\n (0, $qQ8Y1$jsx)((0, $728d3535906a11ab$export$2e2bcd8739ae039), {}),\n (0, $qQ8Y1$jsx)((0, $aaf6e15ae0d6178d$export$78bddedbcf2939ac), {})\n ]\n }),\n (0, $qQ8Y1$jsx)((0, $5f56149382e8930d$export$2e2bcd8739ae039), {}),\n (0, $qQ8Y1$jsx)((0, $1c4c5bb8d78eb6a9$export$2e2bcd8739ae039), {}),\n (0, $qQ8Y1$jsx)((0, $c4aeaed06c94e6bd$export$2e2bcd8739ae039), {}),\n (0, $qQ8Y1$jsx)((0, $8827576290cfe6c8$export$2e2bcd8739ae039), {\n editorContextMenu: editorContextMenu\n }),\n (0, $qQ8Y1$jsx)((0, $3d16dc6c2f6416d3$export$2e2bcd8739ae039), {}),\n (0, $qQ8Y1$jsx)((0, $7ba264c3aa450939$export$2e2bcd8739ae039), {})\n ]\n });\n};\nconst $83a57bff646cb127$export$7cda8d932e2f33c0 = (props)=>(0, $qQ8Y1$jsx)((0, $qQ8Y1$ReactFlowProvider), {\n children: (0, $qQ8Y1$jsx)($83a57bff646cb127$export$72cb76f559fbafcf, {\n ...props\n })\n });\nvar $83a57bff646cb127$export$2e2bcd8739ae039 = $83a57bff646cb127$export$7cda8d932e2f33c0;\n\n\n\n\n\nconst $82ed00a03393ac16$export$d31000d36961d6c2 = {\n nodes: [],\n edges: [],\n controlPanel: {\n nodes: [],\n show: false,\n size: {\n width: 200,\n height: 100\n }\n },\n viewport: {\n x: 0,\n y: 0,\n zoom: 1.5\n }\n};\nconst $82ed00a03393ac16$export$6cd5d5c1dae69a36 = (0, $qQ8Y1$withTheme)((0, $qQ8Y1$emotionstyled).div`\n display: flex;\n flex-direction: column;\n height: 100%;\n width: 100%;\n`);\nconst $82ed00a03393ac16$export$6bc5189622b1f4ec = (0, $qQ8Y1$withTheme)((0, $qQ8Y1$emotionstyled).div`\n position: fixed;\n height: 100%;\n width: 100%;\n background: rgba(0, 0, 0, 0.7);\n color: white;\n display: flex;\n justify-content: center;\n align-items: center;\n font-size: 2rem;\n`);\nconst $82ed00a03393ac16$export$8d546ef2006cd0a2 = (0, $qQ8Y1$withTheme)((0, $qQ8Y1$emotionstyled).div`\n height: 100%;\n width: 100%;\n display: flex;\n position: relative;\n`);\nconst $82ed00a03393ac16$export$10efbd348f877f87 = (0, $qQ8Y1$withTheme)((0, $qQ8Y1$emotionstyled).div`\n display: flex;\n flex: 1;\n align-items: center;\n justify-content: center;\n background: ${({ theme: theme })=>theme.colors.elevation3};\n`);\nconst $82ed00a03393ac16$export$8c347812506d5ac9 = (0, $qQ8Y1$withTheme)((0, $qQ8Y1$emotionstyled).div`\n background: ${({ theme: theme })=>theme.colors.elevation2};\n opacity: 0.7;\n position: absolute;\n width: 100%;\n height: 100%;\n left: 0;\n top: 0;\n z-index: 1;\n font-family: var(--leva-fonts-mono);\n color: ${({ theme: theme })=>theme.colors.whitePrimary};\n display: ${({ show: show })=>show ? \"flex\" : \"none\"};\n align-items: center;\n justify-content: center;\n font-size: 6rem;\n`);\nconst $82ed00a03393ac16$export$b38a2fd24b22fb35 = (props)=>{\n const pullEditorChanges = (0, $e44921bed281a717$export$2e2bcd8739ae039)((store)=>store.pullEditorChanges);\n const currentFileIndex = (0, $e44921bed281a717$export$2e2bcd8739ae039)((store)=>store.currentFileIndex);\n const [showLoader, setShowLoader] = (0, $qQ8Y1$useState)(true);\n (0, $qQ8Y1$useEffect)(()=>{\n setShowLoader(true);\n setTimeout(()=>{\n setShowLoader(false);\n }, 1600);\n }, [\n currentFileIndex\n ]);\n const { file: file } = props;\n if (!file) return null;\n if (file.type === \"audio\") return (0, $qQ8Y1$jsx)($82ed00a03393ac16$export$10efbd348f877f87, {\n children: (0, $qQ8Y1$jsx)(\"audio\", {\n src: file.file,\n controls: true\n })\n });\n return (0, $qQ8Y1$jsxs)((0, $qQ8Y1$Fragment), {\n children: [\n (0, $qQ8Y1$jsx)((0, $83a57bff646cb127$export$7cda8d932e2f33c0), {\n ...props,\n onChange: (state)=>{\n pullEditorChanges();\n },\n editorState: file.file || $82ed00a03393ac16$export$d31000d36961d6c2\n }),\n (0, $qQ8Y1$jsx)($82ed00a03393ac16$export$8c347812506d5ac9, {\n show: showLoader,\n children: \"Loading...\"\n })\n ]\n });\n};\nconst $82ed00a03393ac16$export$2206531ad8592d57 = (0, $qQ8Y1$withTheme)((0, $qQ8Y1$emotionstyled).div`\n height: 2rem;\n display: flex;\n align-items: center;\n background: ${({ theme: theme })=>theme.colors.elevation2};\n`);\nconst $82ed00a03393ac16$export$3e41faf802a29e71 = (0, $qQ8Y1$withTheme)((0, $qQ8Y1$emotionstyled).div`\n display: flex;\n align-items: center;\n cursor: pointer;\n height: 100%;\n box-sizing: border-box;\n padding: 0.3rem 0.4rem;\n\n border-right: 1px solid ${({ theme: theme })=>theme.colors.elevation1};\n\n input {\n color: ${({ theme: theme, active: active })=>active ? theme.colors.whitePrimary : theme.colors.highlight1};\n\n &:not([readonly]):focus {\n background-color: ${({ theme: theme })=>theme.colors.elevation1};\n }\n }\n`);\nconst $82ed00a03393ac16$export$61e5b3c7bace77b8 = (0, $qQ8Y1$withTheme)((0, $qQ8Y1$emotionstyled).div`\n display: flex;\n align-items: center;\n height: 100%;\n padding: 0 0.5rem;\n cursor: pointer;\n\n color: ${({ theme: theme })=>theme.colors.highlight1};\n &:hover {\n color: ${({ theme: theme })=>theme.colors.whitePrimary};\n }\n`);\nconst $82ed00a03393ac16$export$3aef34186a092045 = (0, $qQ8Y1$withTheme)((0, $qQ8Y1$emotionstyled)((0, $qQ8Y1$FaPlus))`\n height: 40%;\n width: auto;\n`);\nconst $82ed00a03393ac16$export$cae179f078f4b4a4 = (0, $qQ8Y1$withTheme)((0, $qQ8Y1$emotionstyled)((0, $qQ8Y1$MdClose))`\n height: 70%;\n width: auto;\n cursor: pointer;\n color: ${({ theme: theme })=>theme.colors.highlight1};\n &:hover {\n color: ${({ theme: theme })=>theme.colors.whitePrimary};\n }\n`);\nconst $82ed00a03393ac16$var$generateId = ()=>{\n return (0, $qQ8Y1$nanoid)();\n};\nconst $82ed00a03393ac16$var$generateEmptyFile = ()=>({\n file: $82ed00a03393ac16$export$d31000d36961d6c2,\n name: \"Unnamed\",\n type: \"patch\",\n id: $82ed00a03393ac16$var$generateId()\n });\nconst $82ed00a03393ac16$export$86fbec116b87613f = ({ ...props })=>{\n const { projectState: projectState, theme: theme } = props;\n const currentFileIndex = (0, $e44921bed281a717$export$2e2bcd8739ae039)((store)=>store.currentFileIndex);\n const currentFile = (0, $e44921bed281a717$export$2e2bcd8739ae039)((store)=>store.project.files[store.currentFileIndex]);\n const setCurrentFileIndex = (0, $e44921bed281a717$export$2e2bcd8739ae039)((store)=>store.setCurrentFileIndex);\n const project = (0, $e44921bed281a717$export$2e2bcd8739ae039)((store)=>store.project);\n const setProject = (0, $e44921bed281a717$export$2e2bcd8739ae039)((store)=>store.setProject);\n const getProject = (0, $e44921bed281a717$export$2e2bcd8739ae039)((store)=>store.getProject);\n const updateFileName = (0, $e44921bed281a717$export$2e2bcd8739ae039)((store)=>store.updateFileName);\n const addFile = (0, $e44921bed281a717$export$2e2bcd8739ae039)((store)=>store.addFile);\n const deleteFile = (0, $e44921bed281a717$export$2e2bcd8739ae039)((store)=>store.deleteFile);\n const syncEditorWithCurrentFile = (0, $e44921bed281a717$export$2e2bcd8739ae039)((store)=>store.syncEditorWithCurrentFile);\n const setEditorState = (0, $e44921bed281a717$export$2e2bcd8739ae039)((store)=>store.setEditorState);\n const pullEditorChanges = (0, $e44921bed281a717$export$2e2bcd8739ae039)((store)=>store.pullEditorChanges);\n const [isDragging, setIsDragging] = (0, $qQ8Y1$useState)(false);\n const handleDragLeave = (e)=>{\n e.preventDefault();\n e.stopPropagation();\n setIsDragging(false);\n };\n const handleDragOver = (e)=>{\n e.preventDefault();\n e.stopPropagation();\n setIsDragging(true);\n };\n const handleDrop = (e)=>{\n e.preventDefault();\n e.stopPropagation();\n setIsDragging(false);\n const files = Array.from(e.dataTransfer.files);\n files.forEach(async (file)=>{\n if (file.type === \"application/json\") {\n const fileData = JSON.parse(await file.text());\n if (fileData.files && fileData.files.length) {\n if (!window.confirm(\"This action will replace your current project. Continue?\")) return;\n setProject(fileData);\n setCurrentFileIndex(0);\n syncEditorWithCurrentFile();\n return;\n }\n const emptyFile = $82ed00a03393ac16$var$generateEmptyFile();\n const newGraphState = {\n ...emptyFile,\n file: {\n ...fileData,\n controlPanel: {\n ...$82ed00a03393ac16$export$d31000d36961d6c2.controlPanel,\n ...fileData.controlPanel\n }\n },\n name: file.name\n };\n addFile(newGraphState, file.name);\n return;\n }\n if (file.type.match(/^audio\\//)) {\n const base64 = await (0, $9322aabb88fc4cc3$export$25df2e315be8e003)(file);\n addFile({\n type: \"audio\",\n // @TODO: use nanoid here\n id: `audio-file-${+new Date()}`,\n name: file.name,\n file: base64\n });\n return;\n }\n console.error(\"Unsupported file type\", file);\n });\n };\n (0, $qQ8Y1$useEffect)(()=>{\n setProject(projectState || {\n files: [\n $82ed00a03393ac16$var$generateEmptyFile()\n ]\n });\n const file = projectState?.files[0];\n file?.file && file?.type !== \"audio\" && setEditorState(file.file);\n }, [\n projectState\n ]);\n // EXPERIMENTAL CODE\n (0, $qQ8Y1$useEffect)(()=>{\n const fetcher = async (...args)=>{\n const request = new Request(...args);\n const files = getProject().files;\n const index = request.url.replace(\"project://\", \"\");\n const file = files.find(({ id: id })=>id === index);\n if (!file) return new Response(`File not found: ${request.url}`, {\n status: 404\n });\n if ((0, $474db3030f688e41$export$e698b79c63b74136)(file)) return new Response(JSON.stringify(file.file ?? null));\n if ((0, $474db3030f688e41$export$31c2336f657dc59f)(file)) return fetch(file.file);\n return new Response(null);\n };\n (0, $qQ8Y1$registerFetcher)(\"project://*\", fetcher);\n return ()=>{\n //unregister here\n };\n }, [\n getProject\n ]);\n (0, $qQ8Y1$useEffect)(()=>{\n syncEditorWithCurrentFile();\n }, [\n currentFileIndex,\n syncEditorWithCurrentFile\n ]);\n return (0, $qQ8Y1$jsxs)((0, $qQ8Y1$ThemeProvider), {\n theme: theme || (0, $9302338e8a0de440$export$2e2bcd8739ae039),\n children: [\n (0, $qQ8Y1$jsx)((0, $qQ8Y1$Global), {\n styles: (0, $qQ8Y1$css)`\n :root {\n --leva-colors-elevation1: #292d39;\n --leva-colors-elevation2: #181c20;\n --leva-colors-elevation3: #373c4b;\n --leva-colors-accent1: #0066dc;\n --leva-colors-accent2: #007bff;\n --leva-colors-accent3: #3c93ff;\n --leva-colors-highlight1: #535760;\n --leva-colors-highlight2: #8c92a4;\n --leva-colors-highlight3: #fefefe;\n --leva-colors-vivid1: #ffcc00;\n --leva-colors-folderWidgetColor: var(--leva-colors-highlight2);\n --leva-colors-folderTextColor: var(--leva-colors-highlight3);\n --leva-colors-toolTipBackground: var(--leva-colors-highlight3);\n --leva-colors-toolTipText: var(--leva-colors-elevation2);\n --leva-radii-xs: 2px;\n --leva-radii-sm: 3px;\n --leva-radii-lg: 10px;\n --leva-space-xs: 3px;\n --leva-space-sm: 6px;\n --leva-space-md: 10px;\n --leva-space-rowGap: 7px;\n --leva-space-colGap: 7px;\n --leva-fonts-mono:\n ui-monospace, SFMono-Regular, Menlo, \"Roboto Mono\", monospace;\n --leva-fonts-sans: system-ui, sans-serif;\n --leva-fontSizes-root: 11px;\n --leva-fontSizes-toolTip: var(--leva-fontSizes-root);\n --leva-sizes-rootWidth: 280px;\n --leva-sizes-controlWidth: 160px;\n --leva-sizes-numberInputMinWidth: 38px;\n --leva-sizes-scrubberWidth: 8px;\n --leva-sizes-scrubberHeight: 16px;\n --leva-sizes-rowHeight: 24px;\n --leva-sizes-folderTitleHeight: 20px;\n --leva-sizes-checkboxSize: 16px;\n --leva-sizes-joystickWidth: 100px;\n --leva-sizes-joystickHeight: 100px;\n --leva-sizes-colorPickerWidth: var(--leva-sizes-controlWidth);\n --leva-sizes-colorPickerHeight: 100px;\n --leva-sizes-imagePreviewWidth: var(--leva-sizes-controlWidth);\n --leva-sizes-imagePreviewHeight: 100px;\n --leva-sizes-monitorHeight: 60px;\n --leva-sizes-titleBarHeight: 39px;\n --leva-shadows-level1: 0 0 9px 0 #00000088;\n --leva-shadows-level2: 0 4px 14px #00000033;\n --leva-borderWidths-root: 0px;\n --leva-borderWidths-input: 1px;\n --leva-borderWidths-focus: 1px;\n --leva-borderWidths-hover: 1px;\n --leva-borderWidths-active: 1px;\n --leva-borderWidths-folder: 1px;\n --leva-fontWeights-label: normal;\n --leva-fontWeights-folder: normal;\n --leva-fontWeights-button: normal;\n }\n `\n }),\n (0, $qQ8Y1$jsxs)($82ed00a03393ac16$export$6cd5d5c1dae69a36, {\n onDragOver: handleDragOver,\n onDragLeave: handleDragLeave,\n onDrop: handleDrop,\n children: [\n (0, $qQ8Y1$jsxs)($82ed00a03393ac16$export$2206531ad8592d57, {\n children: [\n project.files.map((file, index)=>(0, $qQ8Y1$jsxs)($82ed00a03393ac16$export$3e41faf802a29e71, {\n onClick: ()=>{\n setCurrentFileIndex(index);\n },\n active: index === currentFileIndex,\n children: [\n (0, $qQ8Y1$jsx)((0, $a2cf3f549395b7f1$export$2e2bcd8739ae039), {\n onChange: (val)=>updateFileName(index, val),\n value: file.name || \"Unnamed\"\n }),\n (0, $qQ8Y1$jsx)($82ed00a03393ac16$export$cae179f078f4b4a4, {\n onClick: (event)=>{\n event.stopPropagation();\n if (!window.confirm(\"Do you really want to delete this file?\")) return;\n deleteFile(index);\n }\n })\n ]\n }, index)),\n (0, $qQ8Y1$jsx)($82ed00a03393ac16$export$61e5b3c7bace77b8, {\n onClick: ()=>{\n addFile($82ed00a03393ac16$var$generateEmptyFile());\n setCurrentFileIndex(project.files.length);\n },\n children: (0, $qQ8Y1$jsx)($82ed00a03393ac16$export$3aef34186a092045, {})\n })\n ]\n }),\n (0, $qQ8Y1$jsx)($82ed00a03393ac16$export$8d546ef2006cd0a2, {\n children: (0, $qQ8Y1$jsx)($82ed00a03393ac16$export$b38a2fd24b22fb35, {\n file: currentFile,\n ...props\n })\n }),\n isDragging && (0, $qQ8Y1$jsx)($82ed00a03393ac16$export$6bc5189622b1f4ec, {\n children: \"Drop file(s) to upload to the project\"\n })\n ]\n })\n ]\n });\n};\nvar $82ed00a03393ac16$export$2e2bcd8739ae039 = $82ed00a03393ac16$export$86fbec116b87613f;\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nconst $22dd0cb4a70b40fd$var$CheckerBox = (0, $qQ8Y1$emotionstyled).div`\n display: flex;\n align-items: center;\n justify-content: center;\n width: 0.6rem;\n height: 0.6rem;\n background: ${({ theme: theme })=>theme.colors.whitePrimary};\n border: 1px solid ${({ theme: theme })=>theme.colors.highlight1};\n &::after {\n content: \"\";\n background: ${({ theme: theme })=>theme.colors.accent1};\n }\n`;\nconst $22dd0cb4a70b40fd$var$CheckerLabel = (0, $qQ8Y1$emotionstyled).div``;\nconst $22dd0cb4a70b40fd$var$CheckerSubtitle = (0, $qQ8Y1$emotionstyled).div`\n font-size: 0.4rem;\n color: ${({ theme: theme })=>theme.colors.highlight1};\n`;\nconst $22dd0cb4a70b40fd$var$CheckedInner = (0, $qQ8Y1$emotionstyled).label`\n display: flex;\n cursor: pointer;\n gap: 0.4rem;\n line-height: 0.7rem;\n input {\n display: none;\n }\n input[type=\"radio\"] ~ .checker-box {\n border-radius: 50%;\n &::after {\n border-radius: 50%;\n }\n }\n input:checked ~ .checker-box:after {\n width: 70%;\n height: 70%;\n }\n`;\nconst $22dd0cb4a70b40fd$export$8ecd240bc8faaeeb = ({ label: label, subtitle: subtitle, name: name, type: type = \"checkbox\", onChange: onChange, checked: checked = false })=>{\n const theme = (0, $aa2521e46fde4290$export$2e2bcd8739ae039)();\n return (0, $qQ8Y1$jsxs)($22dd0cb4a70b40fd$var$CheckedInner, {\n children: [\n (0, $qQ8Y1$jsx)(\"input\", {\n type: type,\n name: name,\n checked: checked,\n onChange: ({ target: target })=>onChange?.(target.checked)\n }),\n (0, $qQ8Y1$jsx)($22dd0cb4a70b40fd$var$CheckerBox, {\n className: \"checker-box\",\n theme: theme\n }),\n (0, $qQ8Y1$jsxs)(\"div\", {\n children: [\n (0, $qQ8Y1$jsx)($22dd0cb4a70b40fd$var$CheckerLabel, {\n children: label\n }),\n subtitle ? (0, $qQ8Y1$jsx)($22dd0cb4a70b40fd$var$CheckerSubtitle, {\n theme: theme,\n children: subtitle\n }) : null\n ]\n })\n ]\n });\n};\nvar $22dd0cb4a70b40fd$export$2e2bcd8739ae039 = $22dd0cb4a70b40fd$export$8ecd240bc8faaeeb;\n\n\n\n\n\n\nconst $03fc2a9d056cdbb9$var$RadioGroupWrapper = (0, $qQ8Y1$emotionstyled).div`\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n font-family: var(--leva-fonts-mono);\n font-size: 0.7rem;\n color: ${({ theme: theme })=>theme.colors.highlight2};\n padding: 0.5rem;\n`;\nconst $03fc2a9d056cdbb9$export$a98f0dcb43a68a25 = ({ options: options, value: value, onChange: onChange })=>{\n const theme = (0, $aa2521e46fde4290$export$2e2bcd8739ae039)();\n return (0, $qQ8Y1$jsx)($03fc2a9d056cdbb9$var$RadioGroupWrapper, {\n theme: theme,\n children: options.map(({ value: optionValue, label: label, subtitle: subtitle }, index)=>(0, $qQ8Y1$jsx)((0, $22dd0cb4a70b40fd$export$2e2bcd8739ae039), {\n value: value,\n type: \"radio\",\n label: label,\n subtitle: subtitle,\n onChange: ()=>onChange(optionValue),\n checked: optionValue === value\n }, index))\n });\n};\nvar $03fc2a9d056cdbb9$export$2e2bcd8739ae039 = $03fc2a9d056cdbb9$export$a98f0dcb43a68a25;\n\n\n\n\n\nconst $f2626dfcf20c9281$export$fb9f58ebe9de6283 = (0, $qQ8Y1$emotionstyled).div`\n display: flex;\n position: relative;\n`;\nconst $f2626dfcf20c9281$export$42e20bb2ce90003b = (0, $qQ8Y1$withTheme)((0, $qQ8Y1$emotionstyled).input`\n padding-right: 2rem;\n padding-left: 0.3rem;\n padding-top: 0;\n padding-bottom: 0;\n width: 100%;\n appearance: textfield;\n font-size: inherit;\n background: none;\n border: none;\n color: var(--leva-colors-highlight1);\n font-family: var(--leva-fonts-mono);\n cursor: inherit;\n text-overflow: ellipsis;\n outline: none;\n appearance: textfield;\n cursor: auto;\n background-color: var(--leva-colors-elevation3);\n border-radius: 0.2rem;\n height: 1.5rem;\n color: var(--leva-colors-highlight2);\n\n &:focus,\n &:hover {\n box-shadow: 0 0 0 var(--leva-borderWidths-focus) var(--leva-colors-accent2);\n color: ${({ theme: theme })=>theme.colors.whitePrimary};\n }\n &::-webkit-inner-spin-button,\n &::-webkit-outer-spin-button {\n -webkit-appearance: none;\n margin-right: 1rem;\n }\n`);\nconst $f2626dfcf20c9281$export$f5b8910cec6cf069 = ({ type: type, value: value, placeholder: placeholder, onChange: onChange = ()=>{}, inputProps: inputProps, ...props })=>{\n return (0, $qQ8Y1$jsx)($f2626dfcf20c9281$export$fb9f58ebe9de6283, {\n ...props,\n children: (0, $qQ8Y1$jsx)($f2626dfcf20c9281$export$42e20bb2ce90003b, {\n type: type,\n value: value,\n placeholder: placeholder,\n onKeyDownCapture: (event)=>{\n event.stopPropagation();\n },\n onChange: (event)=>{\n onChange(event.target.value);\n },\n ...inputProps\n })\n });\n};\nvar $f2626dfcf20c9281$export$2e2bcd8739ae039 = $f2626dfcf20c9281$export$f5b8910cec6cf069;\n\n\n\n\n\n\n\n\nconst $9f4596934c8f0841$var$InputButton = (0, $qQ8Y1$withTheme)((0, $qQ8Y1$emotionstyled).button`\n position: absolute;\n right: 0;\n height: 100%;\n outline: none;\n background: none;\n border: none;\n color: ${({ theme: theme })=>theme.colors.highlight1};\n cursor: pointer;\n display: flex;\n align-items: center;\n z-index: 2;\n &:hover {\n color: ${({ theme: theme })=>theme.colors.highlight2};\n }\n &:active {\n color: ${({ theme: theme })=>theme.colors.highlight3};\n }\n`);\nconst $9f4596934c8f0841$var$DropdownContainer = (0, $qQ8Y1$emotionstyled).div`\n position: relative;\n width: 100%;\n`;\nconst $9f4596934c8f0841$var$DropdownList = (0, $qQ8Y1$withTheme)((0, $qQ8Y1$emotionstyled).div`\n position: absolute;\n top: calc(100% + 2px);\n left: 0;\n right: 0;\n max-height: 200px;\n overflow-y: auto;\n background-color: ${({ theme: theme })=>theme.colors.elevation2};\n border: 1px solid ${({ theme: theme })=>theme.colors.elevation3};\n border-radius: 0.2rem;\n box-shadow: 0 4px 6px rgba(0, 0, 0, 0.3);\n z-index: 1000;\n display: ${({ isOpen: isOpen })=>isOpen ? \"block\" : \"none\"};\n\n &::-webkit-scrollbar {\n width: 8px;\n }\n\n &::-webkit-scrollbar-track {\n background: ${({ theme: theme })=>theme.colors.elevation1};\n }\n\n &::-webkit-scrollbar-thumb {\n background: ${({ theme: theme })=>theme.colors.elevation3};\n border-radius: 4px;\n }\n\n &::-webkit-scrollbar-thumb:hover {\n background: ${({ theme: theme })=>theme.colors.highlight1};\n }\n`);\nconst $9f4596934c8f0841$var$DropdownItem = (0, $qQ8Y1$withTheme)((0, $qQ8Y1$emotionstyled).div`\n padding: 0.4rem 0.5rem;\n cursor: pointer;\n color: ${({ theme: theme })=>theme.colors.highlight1};\n background-color: ${({ theme: theme, isHighlighted: isHighlighted })=>isHighlighted ? theme.colors.elevation3 : \"transparent\"};\n font-family: var(--leva-fonts-mono);\n font-size: 0.9em;\n\n &:hover {\n background-color: ${({ theme: theme })=>theme.colors.elevation3};\n color: ${({ theme: theme })=>theme.colors.highlight2};\n }\n`);\nconst $9f4596934c8f0841$var$DropdownItemValue = (0, $qQ8Y1$emotionstyled).div`\n font-size: 0.85em;\n opacity: 0.7;\n margin-top: 2px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n`;\nconst $9f4596934c8f0841$var$DropdownItemLabel = (0, $qQ8Y1$emotionstyled).div`\n font-size: 1em;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n`;\nconst $9f4596934c8f0841$export$7a40489edcbfb3a1 = ({ value: value = \"\", placeholder: placeholder = \"\", onSubmit: onSubmit = ()=>{}, options: options = [], ...props })=>{\n const [currentValue, setCurrentValue] = (0, $qQ8Y1$useState)(value);\n const [isOpen, setIsOpen] = (0, $qQ8Y1$useState)(false);\n const [highlightedIndex, setHighlightedIndex] = (0, $qQ8Y1$useState)(-1);\n const inputRef = (0, $qQ8Y1$useRef)(null);\n const dropdownRef = (0, $qQ8Y1$useRef)(null);\n const filteredOptions = options.filter((option)=>currentValue === \"\" || option.value.toLowerCase().includes(currentValue.toLowerCase()) || option.label?.toLowerCase().includes(currentValue.toLowerCase()));\n const applyCurrentValue = (0, $qQ8Y1$useCallback)(()=>{\n onSubmit(currentValue);\n setIsOpen(false);\n setHighlightedIndex(-1);\n }, [\n currentValue,\n onSubmit\n ]);\n const selectOption = (0, $qQ8Y1$useCallback)((option)=>{\n setCurrentValue(option.value);\n onSubmit(option.value);\n setIsOpen(false);\n setHighlightedIndex(-1);\n }, [\n onSubmit\n ]);\n const handleKeyDown = (0, $qQ8Y1$useCallback)((event)=>{\n switch(event.key){\n case \"Escape\":\n setIsOpen(false);\n setHighlightedIndex(-1);\n break;\n case \"Enter\":\n if (isOpen && highlightedIndex >= 0 && filteredOptions[highlightedIndex]) {\n event.preventDefault();\n selectOption(filteredOptions[highlightedIndex]);\n } else applyCurrentValue();\n break;\n case \"ArrowDown\":\n event.preventDefault();\n if (!isOpen) {\n setIsOpen(true);\n setHighlightedIndex(0);\n } else setHighlightedIndex((prev)=>prev < filteredOptions.length - 1 ? prev + 1 : prev);\n break;\n case \"ArrowUp\":\n event.preventDefault();\n if (isOpen) setHighlightedIndex((prev)=>prev > 0 ? prev - 1 : prev);\n break;\n }\n }, [\n applyCurrentValue,\n isOpen,\n highlightedIndex,\n filteredOptions,\n selectOption\n ]);\n const handleInputChange = (value)=>{\n setCurrentValue(value);\n setIsOpen(true);\n setHighlightedIndex(-1);\n };\n const handleFocus = ()=>{\n if (options.length > 0) setIsOpen(true);\n };\n const handleBlur = ()=>{\n // Use setTimeout to allow click events on dropdown items to fire first\n setTimeout(()=>{\n setIsOpen(false);\n setHighlightedIndex(-1);\n }, 200);\n };\n // Handle clicking outside\n (0, $qQ8Y1$useEffect)(()=>{\n const handleClickOutside = (event)=>{\n if (dropdownRef.current && !dropdownRef.current.contains(event.target) && inputRef.current && !inputRef.current.contains(event.target)) {\n setIsOpen(false);\n setHighlightedIndex(-1);\n }\n };\n document.addEventListener(\"mousedown\", handleClickOutside);\n return ()=>{\n document.removeEventListener(\"mousedown\", handleClickOutside);\n };\n }, []);\n // Scroll highlighted item into view\n (0, $qQ8Y1$useEffect)(()=>{\n if (highlightedIndex >= 0 && dropdownRef.current) {\n const highlightedElement = dropdownRef.current.children[highlightedIndex];\n if (highlightedElement) highlightedElement.scrollIntoView({\n block: \"nearest\",\n behavior: \"smooth\"\n });\n }\n }, [\n highlightedIndex\n ]);\n return (0, $qQ8Y1$jsxs)($9f4596934c8f0841$var$DropdownContainer, {\n children: [\n (0, $qQ8Y1$jsxs)((0, $f2626dfcf20c9281$export$fb9f58ebe9de6283), {\n children: [\n (0, $qQ8Y1$jsx)((0, $f2626dfcf20c9281$export$42e20bb2ce90003b), {\n ...props,\n ref: inputRef,\n value: currentValue,\n placeholder: placeholder,\n onKeyDown: handleKeyDown,\n onChange: (event)=>handleInputChange(event.target.value),\n onFocus: handleFocus,\n onBlur: handleBlur,\n autoComplete: \"off\"\n }),\n (0, $qQ8Y1$jsx)($9f4596934c8f0841$var$InputButton, {\n onClick: applyCurrentValue,\n children: (0, $qQ8Y1$jsx)((0, $qQ8Y1$FaRegArrowAltCircleRight), {})\n })\n ]\n }),\n options.length > 0 && (0, $qQ8Y1$jsx)($9f4596934c8f0841$var$DropdownList, {\n ref: dropdownRef,\n isOpen: isOpen && filteredOptions.length > 0,\n children: filteredOptions.map((option, index)=>(0, $qQ8Y1$jsxs)($9f4596934c8f0841$var$DropdownItem, {\n isHighlighted: index === highlightedIndex,\n onClick: ()=>selectOption(option),\n onMouseEnter: ()=>setHighlightedIndex(index),\n children: [\n (0, $qQ8Y1$jsx)($9f4596934c8f0841$var$DropdownItemLabel, {\n children: option.label || option.value\n }),\n option.value && (0, $qQ8Y1$jsx)($9f4596934c8f0841$var$DropdownItemValue, {\n children: option.value\n })\n ]\n }, option.value + index))\n })\n ]\n });\n};\nvar $9f4596934c8f0841$export$2e2bcd8739ae039 = $9f4596934c8f0841$export$7a40489edcbfb3a1;\n\n\n\n\n\nconst $e1bb97faa82daf8d$var$StyledInputWrapper = (0, $qQ8Y1$emotionstyled)((0, $f2626dfcf20c9281$export$fb9f58ebe9de6283))`\n gap: 0.5rem;\n`;\nconst $e1bb97faa82daf8d$var$StyledInputInner = (0, $qQ8Y1$emotionstyled)((0, $f2626dfcf20c9281$export$42e20bb2ce90003b))`\n padding: 0;\n aspect-ratio: 1 / 1;\n width: auto;\n cursor: pointer;\n &::-webkit-color-swatch-wrapper {\n padding: 0;\n }\n &::-webkit-color-swatch {\n border-radius: 0.2rem;\n border: none;\n }\n`;\nconst $e1bb97faa82daf8d$export$5a1d7ca0a925d9c2 = ({ value: value, onChange: onChange = ()=>{}, ...props })=>{\n return (0, $qQ8Y1$jsxs)($e1bb97faa82daf8d$var$StyledInputWrapper, {\n ...props,\n children: [\n (0, $qQ8Y1$jsx)($e1bb97faa82daf8d$var$StyledInputInner, {\n type: \"color\",\n value: value,\n onChange: (event)=>{\n onChange(event.target.value);\n }\n }),\n (0, $qQ8Y1$jsx)((0, $f2626dfcf20c9281$export$42e20bb2ce90003b), {\n value: value,\n onChange: (event)=>{\n onChange(event.target.value);\n }\n })\n ]\n });\n};\nvar $e1bb97faa82daf8d$export$2e2bcd8739ae039 = $e1bb97faa82daf8d$export$5a1d7ca0a925d9c2;\n\n\n\n\n\n\nconst $9746117513cdf0c6$var$SampleInput = (0, $qQ8Y1$emotionstyled).span`\n position: relative;\n &:after {\n content: \"↕\";\n position: absolute;\n top: -1px;\n right: 0;\n height: 100%;\n display: flex;\n align-items: center;\n font-size: 1.2em;\n color: var(--leva-colors-highlight1);\n }\n`;\nconst $9746117513cdf0c6$var$SampleInputInner = (0, $qQ8Y1$emotionstyled).input`\n width: 100%;\n appearance: textfield;\n font-size: inherit;\n background: none;\n border: none;\n text-align: right;\n color: var(--leva-colors-highlight1);\n font-family: var(--leva-fonts-mono);\n cursor: inherit;\n text-overflow: ellipsis;\n outline: none;\n appearance: textfield;\n cursor: auto;\n background-color: var(--leva-colors-elevation3);\n border-radius: 0.2rem;\n height: 1.5rem;\n color: var(--leva-colors-highlight2);\n\n &:focus,\n &:hover {\n box-shadow: 0 0 0 var(--leva-borderWidths-focus) var(--leva-colors-accent2);\n }\n &::-webkit-inner-spin-button,\n &::-webkit-outer-spin-button {\n -webkit-appearance: none;\n margin-right: 1rem;\n }\n`;\nconst $9746117513cdf0c6$export$6bf0cd3a219bbade = ({ max: max = Infinity, min: min = -Infinity, value: value, step: step = 1, onChange: onChange = ()=>{}, placeholder: placeholder, ...props })=>{\n const inputRef = (0, $qQ8Y1$useRef)(null);\n const startChangedHandler = (0, $qQ8Y1$useThrottledCallback)((event)=>{\n if (typeof value === \"undefined\") return;\n //@TODO: come up with more logical factor calculation\n const factor = max < 10 ? 5 : max / 100;\n const st = +(value + Math.round(event.deltaY / factor) * step).toFixed(2);\n if (st < min || st > max) return;\n onChange(st);\n }, 100);\n (0, $qQ8Y1$useEffect)(()=>{\n if (!inputRef.current) return;\n inputRef.current.addEventListener(\"wheel\", (event)=>{\n event.preventDefault();\n event.stopPropagation();\n startChangedHandler(event);\n });\n inputRef.current.onchange = (event)=>{\n const value = event.target.value;\n onChange(+value);\n };\n }, [\n inputRef.current,\n onChange\n ]);\n (0, $qQ8Y1$useEffect)(()=>{\n if (typeof value === \"undefined\") return;\n inputRef.current && (inputRef.current.value = value.toString());\n }, [\n inputRef.current,\n value\n ]);\n return (0, $qQ8Y1$jsx)($9746117513cdf0c6$var$SampleInput, {\n ...props,\n children: (0, $qQ8Y1$jsx)($9746117513cdf0c6$var$SampleInputInner, {\n ref: inputRef,\n type: \"number\",\n step: step,\n min: min,\n max: max,\n placeholder: placeholder\n })\n });\n};\nvar $9746117513cdf0c6$export$2e2bcd8739ae039 = $9746117513cdf0c6$export$6bf0cd3a219bbade;\n\n\n\nconst $fd88f4b57ca7d92f$export$353f5b6fc5456de1 = (0, $qQ8Y1$emotionstyled).button`\n display: flex;\n align-items: center;\n justify-content: center;\n outline: none;\n font-size: inherit;\n font-family: inherit;\n border: none;\n appearance: none;\n font-weight: var(--leva-fontWeights-button);\n height: var(--leva-sizes-rowHeight);\n border-radius: var(--leva-radii-sm);\n background-color: ${({ theme: theme })=>theme.colors.elevation1};\n color: ${({ theme: theme })=>theme.colors.highlight3};\n background-color: ${({ theme: theme })=>theme.colors.accent2};\n cursor: pointer;\n font-family: var(--leva-fonts-mono);\n font-size: var(--leva-fontSizes-root);\n\n &:hover {\n box-shadow: inset 0 0 0 var(--leva-borderWidths-hover)\n ${({ theme: theme })=>theme.colors.accent3};\n }\n\n &:active {\n box-shadow: inset 0 0 0 var(--leva-borderWidths-active)\n ${({ theme: theme })=>theme.colors.accent3};\n background-color: ${({ theme: theme })=>theme.colors.accent1};\n }\n`;\nvar $fd88f4b57ca7d92f$export$2e2bcd8739ae039 = $fd88f4b57ca7d92f$export$353f5b6fc5456de1;\n\n\n\n\n\nconst $6af7bd545fe585cb$var$SelectWrapper = (0, $qQ8Y1$withTheme)((0, $qQ8Y1$emotionstyled).div`\n display: flex;\n align-items: center;\n position: relative;\n\n select {\n appearance: none;\n border: none;\n outline: none;\n width: 100%;\n font-weight: var(--leva-fontWeights-button);\n padding: 0.3rem 0.5rem;\n padding-right: 1rem;\n border-radius: var(--leva-radii-sm);\n background-color: ${({ theme: theme })=>theme.colors.elevation1};\n color: ${({ theme: theme })=>theme.colors.highlight3};\n cursor: pointer;\n font-family: var(--leva-fonts-mono);\n font-size: var(--leva-fontSizes-root);\n\n &:hover {\n box-shadow: inset 0 0 0 var(--leva-borderWidths-hover)\n ${({ theme: theme })=>theme.colors.accent3};\n }\n\n &:active {\n box-shadow: inset 0 0 0 var(--leva-borderWidths-active)\n ${({ theme: theme })=>theme.colors.accent3};\n background-color: ${({ theme: theme })=>theme.colors.accent1};\n }\n }\n\n &::after {\n position: absolute;\n right: 0.3rem;\n content: \"\";\n width: 0.5em;\n height: 0.3em;\n background-color: ${({ theme: theme })=>theme.colors.highlight3};\n clip-path: polygon(100% 0%, 0 0%, 50% 100%);\n }\n`);\nconst $6af7bd545fe585cb$export$ef9b1a59e592288f = ({ options: options, placeholder: placeholder, value: value, onChange: onChange, ...props })=>{\n return (0, $qQ8Y1$jsx)($6af7bd545fe585cb$var$SelectWrapper, {\n ...props,\n children: (0, $qQ8Y1$jsxs)(\"select\", {\n value: value || \"\",\n onChange: (event)=>onChange?.(event.target.value),\n children: [\n placeholder && (0, $qQ8Y1$jsx)(\"option\", {\n value: \"\",\n disabled: true,\n children: placeholder\n }),\n options.map(({ value: value, label: label })=>(0, $qQ8Y1$jsx)(\"option\", {\n value: value,\n children: label\n }, value + label))\n ]\n })\n });\n};\nvar $6af7bd545fe585cb$export$2e2bcd8739ae039 = $6af7bd545fe585cb$export$ef9b1a59e592288f;\n\n\n\n\n\nconst $b36c9ac3a0f9fc74$export$472062a354075cee = (0, $qQ8Y1$emotionstyled)((0, $qQ8Y1$rcslider))`\n padding: 0;\n cursor: pointer;\n position: relative;\n\n &:hover {\n filter: brightness(125%);\n }\n\n .rc-slider-dot {\n border-radius: 0;\n box-shadow: none;\n margin: 0;\n border: none;\n background: ${({ theme: theme })=>theme.colors.highlight2};\n }\n\n &.rc-slider-horizontal .rc-slider-dot {\n width: 1px;\n height: 0.25rem;\n bottom: -6px;\n }\n\n &.rc-slider-vertical .rc-slider-dot {\n width: 0.25rem;\n height: 1px;\n left: 3px;\n }\n\n .rc-slider-rail {\n background: ${({ theme: theme })=>theme.colors.elevation1};\n }\n\n .rc-slider-track {\n background: ${({ theme: theme, color: color })=>color || theme.colors.accent2};\n }\n\n .rc-slider-handle {\n border-radius: 0.125rem;\n background: ${({ theme: theme, color: color })=>color || theme.colors.accent2};\n opacity: 1;\n cursor: pointer;\n border: none;\n &:hover {\n filter: brightness(110%);\n }\n }\n\n .rc-slider-handle,\n .rc-slider-handle.rc-slider-handle-dragging {\n box-shadow: 0 0 0 2px ${({ theme: theme })=>theme.colors.elevation2};\n }\n\n &:before {\n content: \"\";\n position: absolute;\n background: transparent;\n }\n\n &.rc-slider-horizontal {\n height: 2px;\n\n .rc-slider-rail,\n .rc-slider-track,\n .rc-slider-step {\n height: 100%;\n }\n\n .rc-slider-handle {\n width: 0.5rem;\n height: 1rem;\n bottom: -7px;\n }\n\n .rc-slider-handle-dragging {\n cursor: ew-resize;\n }\n\n &:before {\n width: 100%;\n height: 1rem;\n top: -7px;\n }\n }\n\n &.rc-slider-vertical {\n width: 2px;\n\n .rc-slider-rail,\n .rc-slider-track,\n .rc-slider-step {\n width: 100%;\n }\n\n .rc-slider-track {\n left: 0;\n }\n\n .rc-slider-handle {\n width: 1rem;\n height: 0.5rem;\n right: -7px;\n }\n\n .rc-slider-handle-dragging {\n cursor: ns-resize;\n }\n\n &:before {\n height: 100%;\n width: 1rem;\n right: -7px;\n }\n }\n\n &.rc-slider-horizontal .rc-slider-mark {\n top: 1rem;\n }\n\n &.rc-slider-vertical .rc-slider-mark {\n left: 1rem;\n }\n\n .rc-slider-mark-text {\n font-size: 0.4rem;\n }\n`;\nvar $b36c9ac3a0f9fc74$export$2e2bcd8739ae039 = $b36c9ac3a0f9fc74$export$472062a354075cee;\n\n\n\n\n\n\n\nclass $03443e7f1f47da42$var$Spliner extends (0, $qQ8Y1$CanvasSpliner) {\n _updateMousePosition(evt) {\n const rect = this._canvas?.getBoundingClientRect();\n const scaleX = this._canvas.width / rect.width;\n const scaleY = this._canvas.height / rect.height;\n this._mouse = {\n x: (evt.clientX - rect.left) * scaleX,\n y: this._height - (evt.clientY - rect.top) * scaleY\n };\n }\n getPoints() {\n const xFactor = 1 / this._width;\n const yFactor = 1 / this._height;\n return this._pointCollection._points.map(({ x: x, y: y })=>({\n x: x * xFactor,\n y: y * yFactor\n }));\n }\n removeAll() {\n const length = this._pointCollection.getNumberOfPoints();\n for(let i = length; i > 0; i--)this._pointCollection.remove(i - 1);\n }\n update(points) {\n this.removeAll();\n const xFactor = this._width;\n const yFactor = this._height;\n points.forEach(({ x: x, y: y })=>{\n this._pointCollection.add({\n x: x * xFactor,\n y: y * yFactor\n });\n });\n this.draw();\n }\n off(eventName, handler) {\n // @TODO: implement unsibscribe\n }\n}\nconst $03443e7f1f47da42$var$WaveShaperInner = (0, $qQ8Y1$emotionstyled).div`\n height: 100%;\n width: 100%;\n position: relative;\n canvas {\n border: none !important;\n position: absolute;\n left: 0;\n right: 0;\n height: 100%;\n width: 100%;\n }\n`;\nconst $03443e7f1f47da42$export$2bf7c2638a145e5c = ({ onChange: onChange, onMove: onMove, points: points, type: type = \"monotonic\", textColor: textColor = \"red\", curveColor: curveColor = (0, $9302338e8a0de440$export$2e2bcd8739ae039).colors.accent2, gridStep: gridStep = 0.25, gridColor: gridColor = (0, $9302338e8a0de440$export$2e2bcd8739ae039).colors.elevation2, controlPointRadius: controlPointRadius = 14, controlPointColor: controlPointColor = (0, $9302338e8a0de440$export$2e2bcd8739ae039).colors.vivid1 })=>{\n const ref = (0, $qQ8Y1$useRef)(null);\n const [spliner, setSpliner] = (0, $qQ8Y1$useState)();\n const handlePointsChange = (0, $qQ8Y1$useCallback)((csObj)=>{\n const points = csObj.getPoints();\n onChange?.(points);\n }, [\n onChange\n ]);\n const handlePointMove = (0, $qQ8Y1$useCallback)((csObj)=>{\n const points = csObj.getPoints();\n onMove?.(points);\n }, [\n onMove\n ]);\n (0, $qQ8Y1$useEffect)(()=>spliner?.update(points), [\n spliner,\n points\n ]);\n (0, $qQ8Y1$useEffect)(()=>spliner?.setSplineType(type), [\n spliner,\n type\n ]);\n (0, $qQ8Y1$useEffect)(()=>spliner?.setGridStep(gridStep), [\n spliner,\n gridStep\n ]);\n (0, $qQ8Y1$useEffect)(()=>spliner?.setGridColor(gridColor), [\n spliner,\n gridColor\n ]);\n (0, $qQ8Y1$useEffect)(()=>spliner?.setControlPointRadius(controlPointRadius), [\n spliner,\n controlPointRadius\n ]);\n (0, $qQ8Y1$useEffect)(()=>spliner?.setTextColor(textColor), [\n spliner,\n textColor\n ]);\n (0, $qQ8Y1$useEffect)(()=>{\n spliner?.setCurveColor(\"idle\", curveColor);\n // spliner?.setCurveColor(\"moving\", \"yellow\");\n }, [\n spliner,\n curveColor\n ]);\n (0, $qQ8Y1$useEffect)(()=>{\n spliner?.setControlPointColor(\"idle\", controlPointColor);\n // spliner?.setControlPointColor(\"hovered\", \"blue\");\n // spliner?.setControlPointColor(\"grabbed\", \"black\");\n }, [\n spliner,\n controlPointColor\n ]);\n (0, $qQ8Y1$useEffect)(()=>{\n if (!spliner) return;\n spliner.setCurveThickness(4);\n spliner.on(\"movePoint\", handlePointMove);\n spliner.on(\"releasePoint\", handlePointsChange);\n spliner.on(\"pointAdded\", handlePointsChange);\n spliner.on(\"pointRemoved\", handlePointsChange);\n spliner.draw();\n return ()=>{\n spliner.off(\"movePoint\", handlePointMove);\n spliner.off(\"releasePoint\", handlePointsChange);\n spliner.off(\"pointAdded\", handlePointsChange);\n spliner.off(\"pointRemoved\", handlePointsChange);\n };\n }, [\n spliner,\n handlePointsChange,\n handlePointMove\n ]);\n (0, $qQ8Y1$useEffect)(()=>{\n if (!ref.current) return;\n const cs = new $03443e7f1f47da42$var$Spliner(ref.current, 1024, 1024);\n setSpliner(cs);\n }, [\n ref\n ]);\n return (0, $qQ8Y1$jsx)($03443e7f1f47da42$var$WaveShaperInner, {\n ref: ref\n });\n};\nvar $03443e7f1f47da42$export$2e2bcd8739ae039 = $03443e7f1f47da42$export$2bf7c2638a145e5c;\n\n\n\nconst $9d9e44a3523295ca$export$555ece15b74b7abc = (0, $qQ8Y1$emotionstyled).div``;\nconst $9d9e44a3523295ca$export$ef9ca7b440c0032c = (0, $qQ8Y1$emotionstyled).div`\n font-family: var(--leva-fonts-mono);\n font-size: 0.7rem;\n color: ${({ theme: theme })=>theme.colors.whitePrimary};\n`;\nconst $9d9e44a3523295ca$export$bd1dc14d6df7044e = (0, $qQ8Y1$emotionstyled).div`\n border-bottom: 1px solid ${({ theme: theme })=>theme.colors.elevation1};\n`;\nconst $9d9e44a3523295ca$export$d56900fc3755b916 = (0, $qQ8Y1$emotionstyled).div`\n padding: 0.2rem 0.4rem;\n font-size: 0.7rem;\n color: ${({ theme: theme })=>theme.colors.highlight2};\n position: relative;\n display: grid;\n align-items: center;\n grid-template-rows: minmax(1.5rem, max-content);\n grid-template-columns: ${({ oneLineLabels: oneLineLabels })=>oneLineLabels ? \"1fr\" : \"auto 10rem\"};\n row-gap: 0.1rem;\n column-gap: 0.4rem;\n`;\nconst $9d9e44a3523295ca$export$aac584ace4a7b830 = (0, $qQ8Y1$emotionstyled).div`\n display: flex;\n flex-direction: column;\n gap: 0.4rem;\n background: ${({ theme: theme })=>theme.colors.elevation2};\n padding: 0.4rem 0.1rem;\n`;\nconst $9d9e44a3523295ca$export$edaba703bd8b8dfa = (0, $qQ8Y1$emotionstyled).div``;\n\n\n\n\n\n\nexport {$6c9029bae1fda307$export$2b77a92f1a5ad772 as Modal, $22dd0cb4a70b40fd$export$8ecd240bc8faaeeb as Checker, $03fc2a9d056cdbb9$export$a98f0dcb43a68a25 as RadioGroup, $f2626dfcf20c9281$export$f5b8910cec6cf069 as Input, $9f4596934c8f0841$export$7a40489edcbfb3a1 as DropdownInput, $e1bb97faa82daf8d$export$5a1d7ca0a925d9c2 as ColorInput, $9746117513cdf0c6$export$6bf0cd3a219bbade as NumberInput, $fd88f4b57ca7d92f$export$353f5b6fc5456de1 as Button, $6af7bd545fe585cb$export$ef9b1a59e592288f as Select, $b36c9ac3a0f9fc74$export$472062a354075cee as Slider, $03443e7f1f47da42$export$2bf7c2638a145e5c as SplineEditor, $9d9e44a3523295ca$export$555ece15b74b7abc as ConfigRowLabel, $9d9e44a3523295ca$export$ef9ca7b440c0032c as ConfigRowControl, $9d9e44a3523295ca$export$bd1dc14d6df7044e as ConfigRowSeparator, $9d9e44a3523295ca$export$d56900fc3755b916 as ConfigRow, $9d9e44a3523295ca$export$aac584ace4a7b830 as ConfigPanel, $9d9e44a3523295ca$export$edaba703bd8b8dfa as ConfigRowInner};\n//# sourceMappingURL=components.js.map\n","export * from './src/components';\n","export { Modal } from \"./Modal\";\nexport { Checker } from \"./Checker\";\nexport { RadioGroup } from \"./RadioGroup\";\nexport { Input } from \"./Input\";\nexport { DropdownInput } from \"./DropdownInput\";\nexport { ColorInput } from \"./ColorInput\";\nexport { NumberInput } from \"./NumberInput\";\nexport { Button } from \"./Button\";\nexport { Select } from \"./Select\";\nexport { Slider } from \"./Slider\";\nexport { SplineEditor } from \"./SplineEditor\";\nexport {\n ConfigRowLabel,\n ConfigRowControl,\n ConfigRowSeparator,\n ConfigRow,\n ConfigPanel,\n ConfigRowInner,\n} from \"./NodeConfig\";\n","import styled from \"@emotion/styled\";\nimport { type ReactNode, useEffect } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { MdClose as CloseIcon } from \"react-icons/md\";\nimport useTheme from \"../hooks/useTheme\";\nimport { Theme } from \"../theme\";\n\nconst ModalOuter = styled.div<{ theme: Theme }>`\n position: fixed;\n z-index: ${({ theme }) => theme.zIndex.modal};\n width: 100%;\n height: 100%;\n top: 0;\n left: 0;\n background: ${({ theme }) => theme.colors.elevation3}cc;\n display: flex;\n align-items: center;\n justify-content: center;\n`;\n\nconst ModalInner = styled.div<{ theme: Theme }>`\n background: ${({ theme }) => theme.colors.elevation2};\n box-shadow: 1px 1px 1px 1px ${({ theme }) => theme.colors.elevation1};\n color: white;\n width: 70%;\n height: 80%;\n overflow-y: scroll;\n position: relative;\n`;\n\nconst ModalCloser = styled(CloseIcon)<{ theme: Theme }>`\n position: absolute;\n top: 0.2rem;\n right: 0.2rem;\n cursor: pointer;\n`;\n\ninterface ModalProps {\n onClose?: () => void;\n children: ReactNode;\n}\n\nexport const Modal = ({ children, onClose, ...props }: ModalProps) => {\n const theme = useTheme();\n\n useEffect(() => {\n const escHandler = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") {\n onClose?.();\n }\n };\n document.addEventListener(\"keydown\", escHandler);\n return () => {\n document.removeEventListener(\"keydown\", escHandler);\n };\n }, [onClose]);\n\n return createPortal(\n <ModalOuter theme={theme} onClick={onClose}>\n <ModalInner\n {...props}\n onClick={(e) => {\n e.stopPropagation();\n }}\n theme={theme}\n >\n {children}\n <ModalCloser theme={theme} onClick={onClose} />\n </ModalInner>\n </ModalOuter>,\n document.body,\n );\n};\n\nexport default Modal;\n","import { useTheme as useEmotionTheme } from \"@emotion/react\";\nimport type { Theme } from '../theme';\n\nconst useTheme = () => {\n return useEmotionTheme() as Theme;\n}\n\nexport default useTheme;\n","import styled from \"@emotion/styled\";\nimport { type Theme, useTheme } from \"../../../core\";\n\nconst CheckerBox = styled.div<{ theme: Theme }>`\n display: flex;\n align-items: center;\n justify-content: center;\n width: 0.6rem;\n height: 0.6rem;\n background: ${({ theme }) => theme.colors.whitePrimary};\n border: 1px solid ${({ theme }) => theme.colors.highlight1};\n &::after {\n content: \"\";\n background: ${({ theme }) => theme.colors.accent1};\n }\n`;\nconst CheckerLabel = styled.div``;\n\nconst CheckerSubtitle = styled.div<{ theme: Theme }>`\n font-size: 0.4rem;\n color: ${({ theme }) => theme.colors.highlight1};\n`;\n\nconst CheckedInner = styled.label`\n display: flex;\n cursor: pointer;\n gap: 0.4rem;\n line-height: 0.7rem;\n input {\n display: none;\n }\n input[type=\"radio\"] ~ .checker-box {\n border-radius: 50%;\n &::after {\n border-radius: 50%;\n }\n }\n input:checked ~ .checker-box:after {\n width: 70%;\n height: 70%;\n }\n`;\n\nexport interface CheckerItem {\n label: string;\n subtitle?: string;\n value: string | number | boolean | null;\n}\n\ninterface CheckerProps extends CheckerItem {\n name?: string;\n type?: \"radio\" | \"checkbox\";\n onChange?: (checked: boolean) => void;\n checked?: boolean;\n}\n\nexport const Checker = ({\n label,\n subtitle,\n name,\n type = \"checkbox\",\n onChange,\n checked = false,\n}: CheckerProps) => {\n const theme = useTheme();\n\n return (\n <CheckedInner>\n <input\n type={type}\n name={name}\n checked={checked}\n onChange={({ target }) => onChange?.(target.checked)}\n />\n <CheckerBox className=\"checker-box\" theme={theme} />\n <div>\n <CheckerLabel>{label}</CheckerLabel>\n {subtitle ? (\n <CheckerSubtitle theme={theme}>{subtitle}</CheckerSubtitle>\n ) : null}\n </div>\n </CheckedInner>\n );\n};\n\nexport default Checker;\n","export { default as Editor, EDITOR_DEFAULTS } from \"./src/components/App\";\nexport { default as Wire } from \"./src/components/Wire\";\nexport {\n WNNode,\n TitleBar,\n type WNNodeProps,\n PortsPanel,\n OutputPorts,\n OutputHandle,\n InputPorts,\n InputHandle,\n Port,\n} from \"./src/components/Node\";\nexport { default as Modal } from \"./src/components/Modal\";\nexport { default as EditableLabel } from \"./src/components/EditableLabel\";\nexport { default as useAudioNode } from \"./src/hooks/useAudioNode\";\nexport { default as useNode } from \"./src/hooks/useNode\";\nexport { default as useTheme } from \"./src/hooks/useTheme\";\nexport { default as useStore } from \"./src/store\";\nexport { default as theme } from \"./src/theme\";\nexport { isAudio, isPatch } from \"./src/helpers/projectFile\";\n\nexport { PortType } from \"./src/constants\";\n\nexport type {\n WNAudioNode,\n CreateWNAudioNode,\n ControlPanelNodeProps,\n PluginConfig,\n PluginComponent,\n ControlPanelNode,\n WNNodeData,\n WNNode as TWNNode,\n InputPort,\n OutputPort,\n EditorState,\n Project,\n WNEdge as TWNEdge,\n EditorStoreState,\n} from \"./src/types\";\n\nexport type { Theme } from \"./src/theme\";\n","import { css, Global, ThemeProvider, withTheme } from \"@emotion/react\";\nimport styled from \"@emotion/styled\";\nimport { nanoid } from \"nanoid\";\nimport { ComponentProps, ReactNode, useEffect, useMemo, useState } from \"react\";\nimport { FaPlus as IconAdd } from \"react-icons/fa6\";\nimport { MdClose } from \"react-icons/md\";\nimport { registerFetcher } from \"@web-noise/fetch\";\nimport useStore from \"../store\";\nimport \"../styles\";\nimport defaultTheme, { Theme } from \"../theme\";\nimport type {\n EditorFile,\n EditorState,\n PluginConfig,\n Project,\n ProjectFile,\n} from \"../types\";\nimport { Editor } from \"./Editor\";\nimport EditableLabel from \"./EditableLabel\";\nimport { isAudio, isPatch } from \"../helpers/projectFile\";\nimport { fileToBase64 } from \"../lib\";\n\n// @TODO: move default state to editor\nexport const EDITOR_DEFAULTS = {\n nodes: [],\n edges: [],\n controlPanel: {\n nodes: [],\n show: false,\n size: {\n width: 200,\n height: 100,\n },\n },\n viewport: { x: 0, y: 0, zoom: 1.5 },\n};\n\nexport const AppWrapper = withTheme(styled.div<{ theme: Theme }>`\n display: flex;\n flex-direction: column;\n height: 100%;\n width: 100%;\n`);\n\nexport const FileUploadLayout = withTheme(styled.div<{ theme: Theme }>`\n position: fixed;\n height: 100%;\n width: 100%;\n background: rgba(0, 0, 0, 0.7);\n color: white;\n display: flex;\n justify-content: center;\n align-items: center;\n font-size: 2rem;\n`);\n\nexport const EditorContainerWrapper = withTheme(styled.div<{ theme: Theme }>`\n height: 100%;\n width: 100%;\n display: flex;\n position: relative;\n`);\n\nexport const AudioTabWrapper = withTheme(styled.div<{ theme: Theme }>`\n display: flex;\n flex: 1;\n align-items: center;\n justify-content: center;\n background: ${({ theme }) => theme.colors.elevation3};\n`);\n\nexport const EditorLoadingOverlay = withTheme(styled.div<{\n theme: Theme;\n show: boolean;\n}>`\n background: ${({ theme }) => theme.colors.elevation2};\n opacity: 0.7;\n position: absolute;\n width: 100%;\n height: 100%;\n left: 0;\n top: 0;\n z-index: 1;\n font-family: var(--leva-fonts-mono);\n color: ${({ theme }) => theme.colors.whitePrimary};\n display: ${({ show }) => (show ? \"flex\" : \"none\")};\n align-items: center;\n justify-content: center;\n font-size: 6rem;\n`);\n\ntype EditorContainerProps = AppProps & {\n file: ProjectFile;\n};\n\nexport const EditorContainer = (props: EditorContainerProps) => {\n const pullEditorChanges = useStore((store) => store.pullEditorChanges);\n const currentFileIndex = useStore((store) => store.currentFileIndex);\n\n const [showLoader, setShowLoader] = useState(true);\n\n useEffect(() => {\n setShowLoader(true);\n setTimeout(() => {\n setShowLoader(false);\n }, 1600);\n }, [currentFileIndex]);\n\n const { file } = props;\n if (!file) return null;\n\n if (file.type === \"audio\") {\n return (\n <AudioTabWrapper>\n <audio src={file.file} controls />\n </AudioTabWrapper>\n );\n }\n\n return (\n <>\n <Editor\n {...props}\n onChange={(state) => {\n pullEditorChanges();\n }}\n editorState={(file as EditorFile).file || EDITOR_DEFAULTS}\n />\n\n <EditorLoadingOverlay show={showLoader}>Loading...</EditorLoadingOverlay>\n </>\n );\n};\n\nexport const TabsContainer = withTheme(styled.div<{ theme: Theme }>`\n height: 2rem;\n display: flex;\n align-items: center;\n background: ${({ theme }) => theme.colors.elevation2};\n`);\n\nexport const Tab = withTheme(styled.div<{ theme: Theme; active?: boolean }>`\n display: flex;\n align-items: center;\n cursor: pointer;\n height: 100%;\n box-sizing: border-box;\n padding: 0.3rem 0.4rem;\n\n border-right: 1px solid ${({ theme }) => theme.colors.elevation1};\n\n input {\n color: ${({ theme, active }) =>\n active ? theme.colors.whitePrimary : theme.colors.highlight1};\n\n &:not([readonly]):focus {\n background-color: ${({ theme }) => theme.colors.elevation1};\n }\n }\n`);\n\nexport const TabIconWrapper = withTheme(styled.div<{ theme: Theme }>`\n display: flex;\n align-items: center;\n height: 100%;\n padding: 0 0.5rem;\n cursor: pointer;\n\n color: ${({ theme }) => theme.colors.highlight1};\n &:hover {\n color: ${({ theme }) => theme.colors.whitePrimary};\n }\n`);\n\nexport const AddFileIcon = withTheme(styled(IconAdd)<{ theme: Theme }>`\n height: 40%;\n width: auto;\n`);\n\nexport const CloseIcon = withTheme(styled(MdClose)<{ theme: Theme }>`\n height: 70%;\n width: auto;\n cursor: pointer;\n color: ${({ theme }) => theme.colors.highlight1};\n &:hover {\n color: ${({ theme }) => theme.colors.whitePrimary};\n }\n`);\n\nconst generateId = (): string => {\n return nanoid();\n};\n\nconst generateEmptyFile = (): ProjectFile => ({\n file: EDITOR_DEFAULTS,\n name: \"Unnamed\",\n type: \"patch\",\n id: generateId(),\n});\n\ninterface AppProps {\n projectState?: Project;\n plugins?: Array<PluginConfig>;\n editorContextMenu?: Array<ReactNode>;\n onChange?: ({ nodes, edges, controlPanel }: EditorState) => void;\n theme?: Theme;\n}\n\nexport const App = ({ ...props }: AppProps) => {\n const { projectState, theme } = props;\n const currentFileIndex = useStore((store) => store.currentFileIndex);\n const currentFile = useStore(\n (store) => store.project.files[store.currentFileIndex],\n );\n const setCurrentFileIndex = useStore((store) => store.setCurrentFileIndex);\n\n const project = useStore((store) => store.project);\n const setProject = useStore((store) => store.setProject);\n const getProject = useStore((store) => store.getProject);\n const updateFileName = useStore((store) => store.updateFileName);\n\n const addFile = useStore((store) => store.addFile);\n const deleteFile = useStore((store) => store.deleteFile);\n const syncEditorWithCurrentFile = useStore(\n (store) => store.syncEditorWithCurrentFile,\n );\n\n const setEditorState = useStore((store) => store.setEditorState);\n const pullEditorChanges = useStore((store) => store.pullEditorChanges);\n\n const [isDragging, setIsDragging] = useState(false);\n\n const handleDragLeave = (e: React.DragEvent<HTMLDivElement>) => {\n e.preventDefault();\n e.stopPropagation();\n setIsDragging(false);\n };\n\n const handleDragOver = (e: React.DragEvent<HTMLDivElement>) => {\n e.preventDefault();\n e.stopPropagation();\n setIsDragging(true);\n };\n\n const handleDrop = (e: React.DragEvent<HTMLDivElement>) => {\n e.preventDefault();\n e.stopPropagation();\n\n setIsDragging(false);\n\n const files = Array.from(e.dataTransfer.files);\n files.forEach(async (file) => {\n if (file.type === \"application/json\") {\n const fileData = JSON.parse(await file.text());\n if (fileData.files && fileData.files.length) {\n if (\n !window.confirm(\n \"This action will replace your current project. Continue?\",\n )\n ) {\n return;\n }\n setProject(fileData);\n setCurrentFileIndex(0);\n syncEditorWithCurrentFile();\n return;\n }\n const emptyFile = generateEmptyFile();\n const newGraphState = {\n ...emptyFile,\n file: {\n ...fileData,\n controlPanel: {\n ...EDITOR_DEFAULTS.controlPanel,\n ...fileData.controlPanel,\n },\n },\n name: file.name,\n };\n addFile(newGraphState, file.name);\n return;\n }\n if (file.type.match(/^audio\\//)) {\n const base64 = await fileToBase64(file);\n addFile({\n type: \"audio\",\n // @TODO: use nanoid here\n id: `audio-file-${+new Date()}`,\n name: file.name,\n file: base64,\n });\n return;\n }\n console.error(\"Unsupported file type\", file);\n });\n };\n\n useEffect(() => {\n setProject(\n projectState || {\n files: [generateEmptyFile()],\n },\n );\n const file = projectState?.files[0];\n file?.file && file?.type !== \"audio\" && setEditorState(file.file);\n }, [projectState]);\n\n // EXPERIMENTAL CODE\n useEffect(() => {\n const fetcher: typeof fetch = async (...args) => {\n const request = new Request(...args);\n const files = getProject().files;\n const index = request.url.replace(\"project://\", \"\");\n const file = files.find(({ id }) => id === index);\n\n if (!file) {\n return new Response(`File not found: ${request.url}`, { status: 404 });\n }\n\n if (isPatch(file)) {\n return new Response(JSON.stringify(file.file ?? null));\n }\n\n if (isAudio(file)) {\n return fetch(file.file);\n }\n\n return new Response(null);\n };\n registerFetcher(\"project://*\", fetcher);\n return () => {\n //unregister here\n };\n }, [getProject]);\n\n useEffect(() => {\n syncEditorWithCurrentFile();\n }, [currentFileIndex, syncEditorWithCurrentFile]);\n\n return (\n <ThemeProvider theme={theme || defaultTheme}>\n <Global\n styles={css`\n :root {\n --leva-colors-elevation1: #292d39;\n --leva-colors-elevation2: #181c20;\n --leva-colors-elevation3: #373c4b;\n --leva-colors-accent1: #0066dc;\n --leva-colors-accent2: #007bff;\n --leva-colors-accent3: #3c93ff;\n --leva-colors-highlight1: #535760;\n --leva-colors-highlight2: #8c92a4;\n --leva-colors-highlight3: #fefefe;\n --leva-colors-vivid1: #ffcc00;\n --leva-colors-folderWidgetColor: var(--leva-colors-highlight2);\n --leva-colors-folderTextColor: var(--leva-colors-highlight3);\n --leva-colors-toolTipBackground: var(--leva-colors-highlight3);\n --leva-colors-toolTipText: var(--leva-colors-elevation2);\n --leva-radii-xs: 2px;\n --leva-radii-sm: 3px;\n --leva-radii-lg: 10px;\n --leva-space-xs: 3px;\n --leva-space-sm: 6px;\n --leva-space-md: 10px;\n --leva-space-rowGap: 7px;\n --leva-space-colGap: 7px;\n --leva-fonts-mono:\n ui-monospace, SFMono-Regular, Menlo, \"Roboto Mono\", monospace;\n --leva-fonts-sans: system-ui, sans-serif;\n --leva-fontSizes-root: 11px;\n --leva-fontSizes-toolTip: var(--leva-fontSizes-root);\n --leva-sizes-rootWidth: 280px;\n --leva-sizes-controlWidth: 160px;\n --leva-sizes-numberInputMinWidth: 38px;\n --leva-sizes-scrubberWidth: 8px;\n --leva-sizes-scrubberHeight: 16px;\n --leva-sizes-rowHeight: 24px;\n --leva-sizes-folderTitleHeight: 20px;\n --leva-sizes-checkboxSize: 16px;\n --leva-sizes-joystickWidth: 100px;\n --leva-sizes-joystickHeight: 100px;\n --leva-sizes-colorPickerWidth: var(--leva-sizes-controlWidth);\n --leva-sizes-colorPickerHeight: 100px;\n --leva-sizes-imagePreviewWidth: var(--leva-sizes-controlWidth);\n --leva-sizes-imagePreviewHeight: 100px;\n --leva-sizes-monitorHeight: 60px;\n --leva-sizes-titleBarHeight: 39px;\n --leva-shadows-level1: 0 0 9px 0 #00000088;\n --leva-shadows-level2: 0 4px 14px #00000033;\n --leva-borderWidths-root: 0px;\n --leva-borderWidths-input: 1px;\n --leva-borderWidths-focus: 1px;\n --leva-borderWidths-hover: 1px;\n --leva-borderWidths-active: 1px;\n --leva-borderWidths-folder: 1px;\n --leva-fontWeights-label: normal;\n --leva-fontWeights-folder: normal;\n --leva-fontWeights-button: normal;\n }\n `}\n />\n <AppWrapper\n onDragOver={handleDragOver}\n onDragLeave={handleDragLeave}\n onDrop={handleDrop}\n >\n <TabsContainer>\n {project.files.map((file, index) => (\n <Tab\n onClick={() => {\n setCurrentFileIndex(index);\n }}\n key={index}\n active={index === currentFileIndex}\n >\n <EditableLabel\n onChange={(val) => updateFileName(index, val)}\n value={file.name || \"Unnamed\"}\n />\n <CloseIcon\n onClick={(event) => {\n event.stopPropagation();\n if (\n !window.confirm(\"Do you really want to delete this file?\")\n ) {\n return;\n }\n deleteFile(index);\n }}\n />\n </Tab>\n ))}\n <TabIconWrapper\n onClick={() => {\n addFile(generateEmptyFile());\n setCurrentFileIndex(project.files.length);\n }}\n >\n <AddFileIcon />\n </TabIconWrapper>\n </TabsContainer>\n <EditorContainerWrapper>\n <EditorContainer file={currentFile!} {...props} />\n </EditorContainerWrapper>\n {isDragging && (\n <FileUploadLayout>\n Drop file(s) to upload to the project\n </FileUploadLayout>\n )}\n </AppWrapper>\n </ThemeProvider>\n );\n};\n\nexport default App;\n","import {\n addEdge,\n getConnectedEdges,\n NodeTypes,\n OnConnect,\n Viewport,\n} from \"reactflow\";\nimport { create, StateCreator } from \"zustand\";\nimport { setAudioNodeTypes, AudioNodeTypes } from \"@web-noise/patch\";\nimport { CONTROL_PANEL_GRID_CONFIG } from \"../constants\";\nimport generateNodeId from \"../helpers/generateNodeId\";\nimport {\n ControlPanelNode,\n ControlPanelNodes,\n PluginComponent,\n PluginConfig,\n WNEdge,\n WNNode,\n GraphState,\n EditorState,\n ControlPanelState,\n EditorStoreState,\n} from \"../types\";\nimport nodesStateCreator, { NodesState } from \"./nodesStore\";\nimport history, { historyStateCreator, HistoryState } from \"./history\";\nimport audioPatch, {\n AudioPatchState,\n audioPatchStateCreator,\n} from \"./audioPatch\";\nimport projectStateCreator, { ProjectState } from \"./projectStore\";\n\nexport type { AudioNodeTypes, NodesState, GraphState };\n\ninterface EditorConfig {\n showMinimap: boolean;\n}\n\ntype NodesConfiguration = Record<string, PluginComponent>;\n\nexport type StoreState = NodesState &\n HistoryState &\n ProjectState &\n AudioPatchState & {\n setGraph: (elements: { nodes: WNNode[]; edges: WNEdge[] }) => Promise<void>;\n clearGraph: () => void;\n createNode: (node: WNNode) => void;\n createNodes: (node: WNNode[]) => Promise<void>;\n removeNode: (node: WNNode) => void;\n removeNodes: (nodes: WNNode[]) => void;\n removeEdges: (nodes: WNEdge[]) => void;\n onConnect: OnConnect;\n createEdges: (edge: WNEdge[]) => void;\n onEdgesDelete: (edges: WNEdge[]) => void;\n onNodesDelete: (nodes: WNNode[]) => Promise<void>;\n plugins: Array<PluginConfig>;\n setPlugins: (plugins: Array<PluginConfig>) => void;\n nodesConfiguration: NodesConfiguration;\n config: EditorConfig;\n setConfig: (config: Partial<EditorConfig>) => void;\n getEditorState: () => EditorState;\n setEditorState: (state: EditorState) => Promise<void>;\n isHelpShown: boolean;\n toggleHelp: () => void;\n copyBuffer: { nodes: WNNode[]; edges: WNEdge[] };\n copy: (elements: { nodes: WNNode[]; edges: WNEdge[] }) => void;\n copySelectedItems: () => void;\n pasteBuffer: (x: number, y: number) => void;\n /* move to control panel store */\n getControlPanelNode: (node: WNNode) => ControlPanelNode | null;\n controlPanel: ControlPanelState;\n setControlPanelNodes: (nodes: ControlPanelNodes) => void;\n showControlPanel: () => void;\n hideControlPanel: () => void;\n setControlPanelSize: (width: { width: number; height: number }) => void;\n addNodeToControlPanel: (node: WNNode) => void;\n removeNodeFromControlPanel: (node: WNNode) => void;\n removeNodesFromControlPanel: (nodes: WNNode[]) => void;\n /* / move to control panel store */\n viewport: Viewport;\n setViewport: (viewport: Viewport) => void;\n };\n\nexport const stateCreator: StateCreator<StoreState> = (...args) => {\n const [set, get] = args;\n return {\n ...nodesStateCreator(...args),\n ...historyStateCreator(...args),\n ...audioPatchStateCreator(...args),\n ...projectStateCreator(...args),\n\n setGraph: async ({ nodes, edges }) => {\n const {\n patch,\n createNodes,\n createEdges,\n setNodesAndEdges,\n nodes: activeNodes,\n edges: activeEdges,\n } = get();\n setNodesAndEdges({ nodes: [], edges: [] });\n\n await createNodes(nodes);\n createEdges(edges);\n },\n clearGraph: () => {\n const { setGraph } = get();\n setGraph({ nodes: [], edges: [] });\n },\n createNodes: async (nodes) => {\n const { createNode } = get();\n await Promise.all(nodes.map((node) => createNode(node)));\n },\n createNode: (nodeData) => {\n const { addNode, nodesConfiguration } = get();\n\n const { type, id, data } = nodeData;\n\n if (typeof type === \"undefined\") {\n throw new Error(`node type is not defined for node: ${id}`);\n }\n\n const node = {\n ...nodeData,\n data: {\n ...data,\n config: {\n ...nodesConfiguration[type]?.defaultConfig,\n ...data?.config,\n },\n },\n };\n\n addNode(node);\n },\n removeNode: (node) => get().removeNodes([node]),\n removeNodes: (nodes) => {\n const {\n edges,\n nodes: currentNodes,\n onNodesDelete,\n removeEdges,\n removeNodesFromControlPanel,\n } = get();\n const parentNodeIds = nodes.map(({ id }) => id);\n const children = currentNodes.filter(\n ({ parentNode }) => parentNode && parentNodeIds.includes(parentNode),\n );\n const resultingNodes = [...nodes, ...children];\n removeNodesFromControlPanel(resultingNodes);\n const connectedEdges = getConnectedEdges(resultingNodes, edges);\n removeEdges(connectedEdges);\n onNodesDelete(resultingNodes);\n const nodeIds = resultingNodes.map(({ id }) => id);\n set({\n nodes: currentNodes.filter(({ id }) => !nodeIds.includes(id)),\n });\n },\n removeEdges: (edges) => {\n const { edges: currentEdges, onEdgesDelete } = get();\n const edgeIds = edges.map(({ id }) => id);\n onEdgesDelete(edges);\n set({\n edges: currentEdges.filter(({ id }) => !edgeIds.includes(id)),\n });\n },\n createEdges: (newEdges) => {\n const { patch, edges, setEdges } = get();\n setEdges(newEdges);\n },\n onConnect: async (connection) => {\n const { edges, createEdges } = get();\n const newEdges = addEdge(connection, edges);\n createEdges(newEdges);\n },\n onEdgesDelete: (edges) => {\n const { patch } = get();\n },\n onNodesDelete: async (nodes) => {\n const { removeNodesFromControlPanel, patch } = get();\n removeNodesFromControlPanel(nodes);\n },\n plugins: [],\n setPlugins: async (plugins) => {\n const { setNodeTypes } = get();\n set({ plugins });\n\n const nodesConf: NodesConfiguration = plugins.reduce((acc, plugin) => {\n return {\n ...acc,\n ...plugin.components.reduce(\n (subAcc, item) => ({\n ...subAcc,\n [item.type]: item,\n }),\n {},\n ),\n };\n }, {});\n\n const nodeTypes: NodeTypes = Object.keys(nodesConf).reduce(\n (acc, type) => {\n return {\n ...acc,\n [type]: nodesConf[type].node,\n };\n },\n {},\n );\n\n const audioNodeTypes: AudioNodeTypes = Object.keys(nodesConf).reduce(\n (acc, type) => {\n return {\n ...acc,\n [type]: nodesConf[type].audioNode,\n };\n },\n {},\n );\n\n setAudioNodeTypes(audioNodeTypes);\n setNodeTypes(nodeTypes);\n\n set(({ nodesConfiguration }) => ({\n nodesConfiguration: { ...nodesConfiguration, ...nodesConf },\n }));\n },\n nodesConfiguration: {},\n config: { showMinimap: false },\n setConfig: (changes) => {\n set(({ config }) => ({ config: { ...config, ...changes } }));\n },\n getEditorState: () => {\n const { getNodesAndEdges, controlPanel, viewport } = get();\n return {\n ...getNodesAndEdges(),\n controlPanel,\n viewport,\n };\n },\n setEditorState: async ({ nodes, edges, controlPanel, viewport }) => {\n const { setGraph } = get();\n await setGraph({ nodes, edges });\n // @TODO: remove this line once audio patch initialisation is reworked\n await new Promise((r) => setTimeout(r, 1000));\n set({\n controlPanel,\n viewport,\n });\n },\n isHelpShown: false,\n toggleHelp: () => {\n const { isHelpShown: showHelp } = get();\n set({ isHelpShown: !showHelp });\n },\n copyBuffer: { nodes: [], edges: [] },\n copy: (elements) => {\n set({ copyBuffer: elements });\n },\n copySelectedItems: () => {\n const { nodes: currentNodes, edges: currentEdges, copy } = get();\n const nodes = currentNodes.filter(({ selected }) => selected);\n const edges = currentEdges.filter(({ selected }) => selected);\n if (!nodes.length) {\n return;\n }\n copy({ nodes, edges });\n },\n pasteBuffer: (x = 0, y = 0) => {\n const { copyBuffer, createNodes, setEdges, nodes, edges } = get();\n const { nodes: nodesToCopy, edges: edgesToCopy } = copyBuffer;\n\n if (!nodesToCopy.length) {\n return;\n }\n\n set({\n nodes: nodes.map((node) => ({ ...node, selected: false })),\n });\n\n const topLeftNode = nodesToCopy.reduce((acc, node) => {\n if (!acc) {\n return node;\n }\n if (\n node.position.x < acc.position.x &&\n node.position.y < acc.position.y\n ) {\n return node;\n }\n return acc;\n });\n\n const xDelta = topLeftNode.position.x - x;\n const yDelta = topLeftNode.position.y - y;\n\n const { nodes: newNodes, mapping } = nodesToCopy.reduce(\n (acc, node) => {\n const newNodeId = generateNodeId(node);\n return {\n nodes: [\n ...acc.nodes,\n {\n ...node,\n id: newNodeId,\n position: {\n x: node.position.x - xDelta,\n y: node.position.y - yDelta,\n },\n selected: true,\n },\n ],\n mapping: {\n ...acc.mapping,\n [node.id]: newNodeId,\n },\n };\n },\n { nodes: [], mapping: {} } as {\n nodes: Array<WNNode>;\n mapping: Record<WNNode[\"id\"], WNNode[\"id\"]>;\n },\n );\n createNodes(newNodes);\n\n const newEdges = edgesToCopy.map((edge) => {\n const source = mapping[edge.source] || edge.source;\n const target = mapping[edge.target] || edge.target;\n return {\n ...edge,\n id: edge.id.replace(edge.source, source).replace(edge.target, target),\n source,\n target,\n selected: true,\n };\n });\n setEdges([\n ...edges.map((edge) => ({ ...edge, selected: false })),\n ...newEdges,\n ]);\n },\n getControlPanelNode: (node) => {\n const { nodesConfiguration } = get();\n const { type } = node;\n if (!type) {\n return null;\n }\n const controlPanelNode = nodesConfiguration[type]?.controlPanelNode;\n if (!controlPanelNode) {\n console.error(`could not find node for type ${type}`);\n return null;\n }\n return controlPanelNode;\n },\n controlPanel: {\n show: true,\n nodes: [],\n size: {\n width: 200,\n height: 100,\n },\n },\n showControlPanel: () =>\n set(({ controlPanel }) => ({\n controlPanel: { ...controlPanel, show: true },\n })),\n hideControlPanel: () =>\n set(({ controlPanel }) => ({\n controlPanel: { ...controlPanel, show: false },\n })),\n addNodeToControlPanel: (node) => {\n const { nodesConfiguration } = get();\n const defaultConfig = node.type\n ? nodesConfiguration[node.type]?.defaultConfig\n : {};\n const { height } = defaultConfig?.size || {};\n const newNode = {\n id: node.id,\n ...(height\n ? { height: height / CONTROL_PANEL_GRID_CONFIG.rowHeight }\n : {}),\n };\n set(({ controlPanel }) => ({\n controlPanel: {\n ...controlPanel,\n nodes: [...controlPanel.nodes, newNode],\n },\n }));\n },\n removeNodeFromControlPanel: (node) =>\n get().removeNodesFromControlPanel([node]),\n removeNodesFromControlPanel: (nodes) => {\n const nodeIds = nodes.map(({ id }) => id);\n set(({ controlPanel }) => {\n const nodes = controlPanel.nodes.filter(\n ({ id }) => !nodeIds.includes(id),\n );\n return {\n controlPanel: {\n ...controlPanel,\n nodes,\n },\n };\n });\n },\n setControlPanelNodes: (nodes) => {\n set(({ controlPanel }) => {\n return {\n controlPanel: {\n ...controlPanel,\n nodes,\n },\n };\n });\n },\n setControlPanelSize: (size) => {\n set(({ controlPanel }) => {\n return {\n controlPanel: {\n ...controlPanel,\n size,\n },\n };\n });\n },\n\n viewport: { x: 0, y: 0, zoom: 1 },\n setViewport: (viewport) => set({ viewport }),\n };\n};\n\nconst useStore = create<StoreState>(audioPatch(history(stateCreator)));\n\nexport default useStore;\n","export const DRAG_HANDLE_CLASS = \"web-noise-drag-handle\";\nexport const DRAG_HANDLE_SELECTOR = `.${DRAG_HANDLE_CLASS}`;\n\nexport const CONTROL_PANEL_GRID_CONFIG = {\n rowHeight: 10,\n cols: 4,\n};\n\nexport enum PortType {\n Gate = \"gate\",\n Number = \"number\",\n Audio = \"audio\",\n Any = \"any\",\n}\n","import { WNNode } from \"../types\";\n\nconst generateNodeId = (node?: Partial<WNNode>): WNNode[\"id\"] => {\n const random = +new Date() + Math.floor(Math.random() * 1000);\n if (!node?.type) {\n return random.toString();\n }\n return `${node.type}-${random}`;\n};\n\nexport default generateNodeId;\n","import {\n addEdge,\n applyEdgeChanges,\n applyNodeChanges,\n OnConnect,\n OnEdgesChange,\n OnNodesChange,\n NodeTypes,\n} from \"reactflow\";\nimport { StateCreator } from \"zustand\";\nimport { DRAG_HANDLE_SELECTOR } from \"../constants\";\nimport type { WNNode, WNNodeData, WNEdge, GraphState } from \"../types\";\n\n//@TODO: rename to NodesStore\nexport interface NodesState {\n nodes: WNNode[];\n edges: WNEdge[];\n onNodesChange: OnNodesChange;\n onEdgesChange: OnEdgesChange;\n onConnect: OnConnect;\n addNode: (node: WNNode) => void;\n setNodes: (nodes: WNNode[]) => void;\n setEdges: (edges: WNEdge[]) => void;\n setNodesAndEdges: (elements: GraphState) => void;\n getNodesAndEdges: () => GraphState;\n clearElements: () => void;\n getNode: (id: string) => WNNode | null;\n updateNodeData: (id: string, data: Partial<WNNodeData>) => void;\n nodeTypes: NodeTypes;\n setNodeTypes: (nodeTypes: NodeTypes) => void;\n}\n\nconst nodesStateCreator: StateCreator<NodesState> = (set, get) => ({\n nodes: [],\n edges: [],\n onNodesChange: (changes) => {\n set(({ nodes }) => ({\n nodes: applyNodeChanges(changes, nodes).map((node) => ({\n dragHandle: DRAG_HANDLE_SELECTOR,\n ...node,\n })),\n }));\n },\n onEdgesChange: (changes) => {\n set(({ edges }) => ({\n edges: applyEdgeChanges(changes, edges),\n }));\n },\n onConnect: (connection) => {\n set(({ edges }) => ({\n edges: addEdge(connection, edges),\n }));\n },\n addNode: (node) => {\n set(({ nodes }) => ({\n nodes: nodes.concat(node),\n }));\n },\n setNodes: (nodes) => {\n set({\n nodes,\n });\n },\n setEdges: (edges) => {\n set({\n edges,\n });\n },\n setNodesAndEdges: ({ nodes, edges }) => {\n set({\n nodes,\n edges,\n });\n },\n getNodesAndEdges: () => {\n const { nodes, edges } = get();\n return { nodes, edges };\n },\n clearElements: () => {\n set({\n nodes: [],\n edges: [],\n });\n },\n getNode: (id) => {\n const { nodes } = get();\n const node = nodes.find((node) => node.id === id);\n return node || null;\n },\n updateNodeData: (id, data) => {\n set(({ nodes }) => {\n return {\n nodes: nodes.map((node) => {\n if (node.id === id) {\n return {\n ...node,\n data: {\n ...node.data,\n ...data,\n },\n };\n }\n\n return node;\n }),\n };\n });\n },\n nodeTypes: {},\n setNodeTypes: (nodeTypes) => set({ nodeTypes }),\n});\n\nexport default nodesStateCreator;\n","import type { StateCreator } from \"zustand\";\nimport type { StoreState } from \"../\";\nimport * as jsondiffpatch from \"jsondiffpatch\";\nimport type { Delta, FilterContext } from \"jsondiffpatch\";\n\nexport interface HistoryState {\n history: {\n maxHistoryLength: number;\n buffer: Array<Delta>;\n pointer: number;\n skipCollect: boolean;\n push: (changes: Delta) => void;\n back: () => void;\n forward: () => void;\n clear: () => void;\n };\n}\n\nconst cloneObject = <T = unknown>(input: T): T => {\n return JSON.parse(JSON.stringify(input));\n};\n\nexport const historyStateCreator: StateCreator<HistoryState> = (set, get) => ({\n history: {\n maxHistoryLength: 5,\n buffer: [],\n pointer: 0,\n skipCollect: false,\n push: (changes: Delta) => {\n const { history } = get();\n const { maxHistoryLength, skipCollect } = history;\n\n if (skipCollect) {\n set({\n history: {\n ...history,\n skipCollect: false,\n },\n });\n return;\n }\n\n set(({ history }) => {\n if (!history) {\n return {};\n }\n const { buffer, pointer } = history;\n\n const newBuffer = buffer.slice(\n Math.max(pointer - maxHistoryLength + 1, 0),\n pointer,\n );\n\n return {\n history: {\n ...history,\n buffer: [...newBuffer, changes],\n pointer: Math.min(pointer + 1, maxHistoryLength),\n },\n };\n });\n },\n back: () => {\n const { nodes, edges, controlPanel, history } = get() as StoreState;\n const { buffer, pointer } = history;\n\n const patchData = buffer[pointer - 1];\n if (!patchData) {\n return;\n }\n\n const reversedPatchData = jsondiffpatch.reverse(patchData);\n if (!reversedPatchData) {\n return;\n }\n\n const updates = cloneObject({\n nodes,\n edges,\n controlPanel,\n });\n\n const patch = jsondiffpatch.patch(updates, reversedPatchData);\n\n set({\n ...patch,\n history: {\n ...history,\n pointer: pointer - 1,\n skipCollect: true,\n },\n });\n },\n forward: () => {\n const { nodes, edges, controlPanel, history } = get() as StoreState;\n const { buffer, pointer } = history;\n\n const patchData = buffer[pointer];\n if (!patchData) {\n return;\n }\n\n const updates = cloneObject({\n nodes,\n edges,\n controlPanel,\n });\n\n const patch = jsondiffpatch.patch(updates, patchData);\n\n set({\n ...patch,\n history: {\n ...history,\n pointer: pointer + 1,\n skipCollect: true,\n },\n });\n },\n // @TODO: remove this method and store history per file\n clear: () => {\n const { history } = get();\n set({\n history: {\n ...history,\n buffer: [],\n pointer: 0,\n skipCollect: true,\n },\n });\n },\n },\n});\n\nconst COLLECT_CHANGES_DEBOUNCE_TIME = 500;\n\nexport const createChangesCollector = (set: any, get: () => StoreState) => {\n const jsondiffpatchInstance = jsondiffpatch.create({\n propertyFilter: (name: string, context: FilterContext) => {\n //@TODO: rework this function, find better solution\n if (context.parent?.parent?.childName === \"controlPanel\") {\n return true;\n }\n if (\n // @ts-ignore\n [\"data\", \"position\", \"controlPanel\"].includes(context.parent?.childName)\n ) {\n return true;\n }\n return [\n \"controlPanel\",\n \"size\",\n \"edges\",\n\n \"nodes\",\n \"data\",\n \"label\",\n \"config\",\n \"values\",\n\n \"position\",\n \"x\",\n \"y\",\n ].includes(name);\n },\n });\n let oldState: StoreState | null = get();\n let timer: any;\n\n return (state: StoreState, prevState: StoreState) => {\n if (state.currentFileIndex !== prevState.currentFileIndex) {\n get().history.clear();\n }\n clearTimeout(timer);\n if (!oldState) {\n oldState = prevState;\n }\n timer = setTimeout(() => {\n const changes = jsondiffpatchInstance.diff(oldState, state);\n oldState = null;\n\n if (changes) {\n get().history.push(changes);\n }\n }, COLLECT_CHANGES_DEBOUNCE_TIME);\n };\n};\n\ntype StoreStateCreator = StateCreator<StoreState>;\n\nconst history =\n (config: StoreStateCreator): StoreStateCreator =>\n (set, get, api) => {\n const collectChanges = createChangesCollector(set, get);\n api.subscribe(collectChanges);\n return config((...args) => set(...args), get, api);\n };\n\nexport default history;\n","import { createPatch, Patch } from \"@web-noise/patch\";\nimport type { StateCreator } from \"zustand\";\nimport type { StoreState } from \"../\";\nimport { compareGraphs } from \"./compareGraphs\";\n\ntype StoreStateCreator = StateCreator<StoreState>;\nexport interface AudioPatchState {\n patch: Patch;\n nodesState: Record<string, any>;\n}\n\nexport const audioPatchStateCreator: StateCreator<AudioPatchState> = (\n set,\n get,\n) => ({\n patch: createPatch(),\n nodesState: {},\n});\n\nconst audioPatch =\n (config: StoreStateCreator): StoreStateCreator =>\n (set, get, api) => {\n api.subscribe(async (state, prevState) => {});\n\n const promises = new Set<Promise<unknown>>();\n\n let currentState = {\n ...get(),\n nodes: [],\n edges: [],\n };\n\n return config(\n async (...args) => {\n const oldState = get();\n const [storeChanges] = args;\n\n //@ts-ignore\n const newState = {\n ...currentState,\n ...(typeof storeChanges === \"function\"\n ? storeChanges({ ...currentState })\n : storeChanges),\n };\n\n const nodeChanges = compareGraphs(currentState.nodes, newState.nodes);\n const edgeChanges = compareGraphs(currentState.edges, newState.edges);\n\n //@ts-ignore\n currentState = newState;\n\n const newNodes = nodeChanges.added;\n const newEdges = edgeChanges.added;\n const removedEdges = edgeChanges.removed;\n const removedNodes = nodeChanges.removed;\n\n const { patch } = oldState;\n\n if (newNodes.length) {\n const promise = patch.registerAudioNodes(\n //@ts-ignore\n newNodes,\n );\n promises.add(promise);\n await promise;\n promises.delete(promise);\n }\n\n if (!(newEdges.length || removedEdges.length || removedNodes.length)) {\n set(...args);\n return;\n }\n\n if (promises.size) {\n try {\n await Promise.all([...promises.values()]);\n } catch (e) {\n console.log(\"some error\", e);\n }\n }\n\n if (newEdges.length) {\n patch.registerAudioConnections(\n //@ts-ignore\n newEdges,\n );\n }\n\n if (removedEdges.length) {\n //@ts-ignore\n patch.unregisterAudioConnections(removedEdges);\n }\n\n if (removedNodes.length) {\n //@ts-ignore\n patch.unregisterAudioNodes(removedNodes);\n }\n\n set(...args);\n },\n get,\n api,\n );\n };\n\nexport default audioPatch;\n","import { WNEdge, WNNode } from \"../../types\";\n\nexport type GraphItems = Array<WNNode | WNEdge>;\n\nexport interface GraphComparisonResult {\n added: GraphItems;\n removed: GraphItems;\n}\n\nexport const compareGraphs = (\n left: GraphItems,\n right: GraphItems,\n): GraphComparisonResult => {\n const setLeft = new Set(left.map((item) => item.id));\n const setRight = new Set(right.map((item) => item.id));\n\n const added = right.filter((item) => !setLeft.has(item.id));\n const removed = left.filter((item) => !setRight.has(item.id));\n\n return { added, removed };\n};\n","import { StateCreator } from \"zustand\";\nimport type { EditorState, Project, ProjectFile } from \"../types\";\nimport type { StoreState } from \"./\";\nimport { isAudio } from \"../helpers/projectFile\";\n\nexport interface ProjectState {\n project: Project;\n setProject: (project: Project) => void;\n getProject: () => Project;\n\n pullEditorChanges: () => void;\n syncEditorWithCurrentFile: () => void;\n\n //@TODO: move inside project\n currentFileIndex: number;\n setCurrentFileIndex: (index: number) => void;\n\n updateFileContent: (fileIndex: number, file: ProjectFile) => void;\n updateFileName: (fileIndex: number, fileName: string) => void;\n addFile: (file: ProjectFile, name?: string) => void;\n deleteFile: (fileIndex: number) => void;\n}\n\nconst projectStateCreator: StateCreator<ProjectState> = (set, get) => ({\n project: { files: [] },\n setProject(project) {\n set({ project, currentFileIndex: 0 });\n },\n getProject() {\n return get().project;\n },\n\n pullEditorChanges() {\n const { getEditorState, currentFileIndex, updateFileContent, project } =\n get() as StoreState;\n const currentFile = project.files[currentFileIndex];\n if (isAudio(currentFile)) {\n return;\n }\n updateFileContent(currentFileIndex, {\n ...currentFile,\n file: getEditorState(),\n });\n },\n\n syncEditorWithCurrentFile: () => {\n const { currentFileIndex, setEditorState, project } = get() as StoreState;\n const currentFile = project.files[currentFileIndex];\n if (currentFile.type === \"audio\") {\n console.log(\"audio file. skipping\");\n return;\n }\n setEditorState(currentFile.file);\n },\n\n currentFileIndex: 0,\n setCurrentFileIndex(newFileIndex) {\n const { currentFileIndex } = get();\n if (newFileIndex === currentFileIndex) {\n return;\n }\n set({ currentFileIndex: newFileIndex });\n },\n\n updateFileContent(index, file) {\n const { project } = get();\n set({\n project: {\n ...project,\n files: project.files.map((f, i) => {\n if (i === index) {\n return {\n // @TODO check again if merging is really needed here\n ...f,\n ...file,\n };\n }\n return f;\n }),\n },\n });\n },\n updateFileName(index, fileName) {\n const { project } = get();\n set({\n project: {\n ...project,\n files: project.files.map((f, i) => {\n if (i === index) {\n return {\n ...f,\n name: fileName,\n };\n }\n return f;\n }),\n },\n });\n },\n addFile(file) {\n const { project } = get();\n const files = [...project.files, file];\n set({\n project: {\n ...project,\n files,\n },\n });\n },\n deleteFile: (fileIndex) => {\n const { project, currentFileIndex } = get();\n\n set({\n project: {\n ...project,\n files: project.files.filter((_, index) => fileIndex !== index),\n },\n });\n\n if (fileIndex <= currentFileIndex) {\n set({ currentFileIndex: currentFileIndex - 1 });\n }\n },\n});\n\nexport default projectStateCreator;\n","import type { AudioFile, EditorFile, ProjectFile } from \"../types\";\n\nexport const isPatch = (file: ProjectFile): file is EditorFile =>\n !(\"type\" in file) || file.type === \"patch\";\n\nexport const isAudio = (file: ProjectFile): file is AudioFile =>\n file.type === \"audio\";\n","import { injectGlobal } from \"@emotion/css\";\nimport theme from \"./theme\";\n\ninjectGlobal`\n .react-flow {\n .react-flow__pane {\n /* background: rgb(106 106 106); */\n /* background: \"white\"; */\n // background: #292d39;\n background: ${theme.colors.elevation3};\n }\n\n .react-flow__background {\n /* background: #efefef; */\n stroke: white;\n }\n\n .react-flow__node-default {\n background: #292d39;\n color: white;\n border: none;\n /* background: transparent; */\n }\n\n .react-flow__node {\n padding: 0;\n width: auto;\n }\n\n .react-flow__edge-path {\n stroke: ${theme.colors.accent2};\n }\n\n .react-flow__node.selected {\n border: 1px solid ${theme.colors.accent2};\n box-shadow: 0 0 0 0.5px #${theme.colors.accent2};\n }\n\n .react-flow__node-default.selected, .react-flow__node-default.selected:hover {\n box-shadow: 0 0 0 0.5px #${theme.colors.accent2};\n }\n\n /* .react-flow__minimap-mask {\n fill: ${theme.colors.elevation1}\n }\n\n .react-flow__minimap-node {\n fill:${theme.colors.accent2}\n } */\n }\n\n`;\n","const LEVA_COLOR_ACCENT2_BLUE = \"#007bff\";\nconst COLOR_GREEN_PRIMARY = \"#14df42\";\nconst COLOR_WHITE_PRIMARY = \"#ffffff\";\n\nconst colors = <const>{\n elevation1: \"#292d39\", // bg color of the root panel (main title bar)\n elevation2: \"#181c20\", // bg color of the rows (main panel color)\n elevation3: \"#373c4b\", // bg color of the inputs\n accent1: \"#0066dc\",\n accent2: LEVA_COLOR_ACCENT2_BLUE,\n accent3: \"#3c93ff\",\n highlight1: \"#535760\",\n highlight2: \"#8c92a4\",\n highlight3: \"#fefefe\",\n vivid1: COLOR_GREEN_PRIMARY,\n whitePrimary: COLOR_WHITE_PRIMARY,\n error: \"#db5353\",\n};\n\nconst zIndex = <const>{\n modal: 9998,\n controlPanel: 9999,\n resumeContextLayout: 10003,\n};\n\nconst theme = {\n colors,\n zIndex,\n};\n\nexport type Theme = typeof theme;\n\nexport default theme;\n","import {\n type ReactNode,\n useCallback,\n useEffect,\n useMemo,\n useState,\n version,\n} from \"react\";\nimport ReactFlow, {\n Background,\n BackgroundVariant,\n Controls,\n MiniMap,\n ReactFlowInstance,\n ReactFlowProvider,\n useOnViewportChange,\n} from \"reactflow\";\nimport \"reactflow/dist/style.css\";\nimport useStore from \"../../store\";\nimport type { EditorState, PluginConfig } from \"../../types\";\nimport EdgeContextMenu, {\n useEdgeContextMenu,\n} from \"../contextMenu/EdgeContextMenu\";\nimport EditorContextMenu, {\n useEditorContextMenu,\n} from \"../contextMenu/EditorContextMenu\";\nimport NodeContextMenu, {\n useNodeContextMenu,\n} from \"../contextMenu/NodeContextMenu\";\nimport ControlPanel from \"../ControlPanel\";\nimport { HelpButton, HelpModal } from \"../Help\";\nimport ResumeContext from \"../ResumeContext\";\nimport ToggleMinimap from \"../ToggleMinimap\";\nimport Wire from \"../Wire\";\n\nconsole.log(99999, `React version: ${version}`);\n\nconst onNodeDragStop = (_event: any, node: any) =>\n console.log(\"drag stop\", node);\nconst onNodeClick = (_event: any, element: any) =>\n console.log(\"click\", element);\n\nconst snapGrid: [number, number] = [20, 20];\n\ninterface EditorProps {\n editorState?: EditorState;\n plugins?: Array<PluginConfig>;\n editorContextMenu?: Array<ReactNode>;\n onChange?: ({ nodes, edges, controlPanel }: EditorState) => void;\n}\n\nexport const EditorPane = ({\n editorState,\n plugins = [],\n editorContextMenu = [],\n onChange = () => {},\n ...props\n}: EditorProps) => {\n const edgeTypes = useMemo(\n () => ({\n wire: Wire,\n }),\n [],\n );\n\n const {\n nodes,\n edges,\n controlPanel,\n onNodesChange,\n onNodesDelete,\n onEdgesChange,\n onEdgesDelete,\n onConnect,\n setPlugins,\n setViewport,\n viewport,\n } = useStore();\n\n const editorConfig = useStore(({ config }) => config);\n\n const nodeTypes = useStore(({ nodeTypes }) => nodeTypes);\n\n useEffect(() => {\n setPlugins(plugins);\n }, [plugins]);\n\n const [reactflowInstance, setReactflowInstance] =\n useState<ReactFlowInstance | null>(null);\n\n useEffect(() => {\n if (!reactflowInstance) {\n return;\n }\n onChange({\n nodes,\n edges,\n controlPanel,\n viewport,\n });\n }, [nodes, edges, controlPanel, viewport]);\n\n const onInit = useCallback(\n (rfi: ReactFlowInstance) => {\n if (!reactflowInstance) {\n setReactflowInstance(rfi);\n console.log(\"flow loaded:\", rfi);\n }\n },\n [reactflowInstance],\n );\n\n const { onContextMenu: onEditorContextMenu } = useEditorContextMenu();\n const { onContextMenu: onNodeContextMenu } = useNodeContextMenu();\n const { onContextMenu: onEdgeContextMenu } = useEdgeContextMenu();\n\n useEffect(() => {\n if (!viewport) {\n return;\n }\n reactflowInstance?.setViewport(viewport);\n }, [viewport, reactflowInstance]);\n\n useOnViewportChange({\n onEnd: setViewport,\n });\n\n return (\n <ReactFlow\n nodes={nodes}\n edges={edges}\n onNodesChange={onNodesChange}\n onNodesDelete={onNodesDelete}\n onEdgesChange={onEdgesChange}\n onConnect={onConnect}\n onNodeDragStop={onNodeDragStop}\n onEdgesDelete={onEdgesDelete}\n onInit={onInit}\n onNodeClick={onNodeClick}\n onContextMenu={onEditorContextMenu}\n onNodeContextMenu={onNodeContextMenu}\n onEdgeContextMenu={onEdgeContextMenu}\n nodeTypes={nodeTypes}\n edgeTypes={edgeTypes}\n snapGrid={snapGrid}\n defaultViewport={editorState?.viewport}\n defaultEdgeOptions={{ type: \"wire\" }}\n snapToGrid\n fitView\n disableKeyboardA11y\n >\n <Background variant={BackgroundVariant.Dots} gap={12} />\n {editorConfig.showMinimap ? <MiniMap /> : null}\n\n <Controls\n style={{\n right: \"1rem\",\n left: \"initial\",\n bottom: \"40%\",\n top: \"initial\",\n }}\n showInteractive={false}\n >\n <ToggleMinimap />\n <HelpButton />\n </Controls>\n\n <ResumeContext />\n <ControlPanel />\n <HelpModal />\n <EditorContextMenu editorContextMenu={editorContextMenu} />\n <NodeContextMenu />\n <EdgeContextMenu />\n </ReactFlow>\n );\n};\n\nexport const Editor = (props: EditorProps) => (\n <ReactFlowProvider>\n <EditorPane {...props} />\n </ReactFlowProvider>\n);\n\nexport default Editor;\n","import { useCallback } from \"react\";\nimport { useContextMenu } from \"react-contexify\";\nimport \"react-contexify/dist/ReactContexify.css\";\nimport useTheme from \"../../hooks/useTheme\";\nimport useStore from \"../../store\";\nimport { ItemWrapper, MenuWrapper } from \"./styles\";\n\nexport const MENU_ID = \"editor-edge-menu\";\n\nexport const useEdgeContextMenu = () => {\n const { show } = useContextMenu({\n id: MENU_ID,\n });\n\n const onContextMenu = useCallback(\n (event: React.MouseEvent<Element, MouseEvent>, edge: unknown) => {\n event.stopPropagation();\n show(event, { props: { edge } });\n },\n [show],\n );\n\n return { onContextMenu };\n};\n\nconst EdgeContextMenu = () => {\n const theme = useTheme();\n\n const removeEdges = useStore((store) => store.removeEdges);\n\n return (\n <>\n <MenuWrapper id={MENU_ID} animation={false} colors={theme.colors}>\n <ItemWrapper onClick={(event) => removeEdges([event.props.edge])}>\n Delete Edge (DEL)\n </ItemWrapper>\n </MenuWrapper>\n </>\n );\n};\n\nexport default EdgeContextMenu;\n","import styled from \"@emotion/styled\";\nimport { Item, Menu } from \"react-contexify\";\nimport \"react-contexify/dist/ReactContexify.css\";\nimport { Theme } from \"../../theme\";\n\n\nexport const ItemWrapper = styled(Item)``;\n\nexport const MenuWrapper = styled(Menu)<{ colors: Theme[\"colors\"] }>`\n background: ${({ colors }) => colors.elevation2};\n padding: 0;\n border-radius: 0;\n\n .react-contexify__item__content {\n color: ${({ colors }) => colors.whitePrimary};\n }\n\n .react-contexify__separator {\n background-color: ${({ colors }) => colors.elevation1};\n margin: 0;\n }\n`;\n","import downloadFile from \"js-file-download\";\nimport {\n type ReactNode,\n useCallback,\n useEffect,\n useMemo,\n useState,\n} from \"react\";\nimport { Separator, useContextMenu } from \"react-contexify\";\nimport \"react-contexify/dist/ReactContexify.css\";\nimport { useReactFlow, type XYPosition } from \"reactflow\";\nimport hotkeys from \"hotkeys-js\";\nimport useTheme from \"../../hooks/useTheme\";\nimport useStore from \"../../store\";\nimport AddNode from \"../AddNode\";\nimport UploadPatch from \"../UploadPatch\";\nimport UploadProject from \"../UploadProject\";\nimport { ItemWrapper, MenuWrapper } from \"./styles\";\nimport UploadAudio from \"../UploadAudio\";\n\ntype MousePosition = {\n x: number;\n y: number;\n};\n\nexport const MENU_ID = \"editor-menu\";\n\nexport const useEditorContextMenu = () => {\n const { show } = useContextMenu({\n id: MENU_ID,\n });\n\n return { onContextMenu: show };\n};\n\nconst EditorContextMenu = ({\n editorContextMenu = [],\n}: {\n editorContextMenu?: Array<ReactNode>;\n}) => {\n const theme = useTheme();\n\n const [mousePosition, setMousePosition] = useState<MousePosition>({\n x: 0,\n y: 0,\n });\n const [showAddNode, setShowAddNode] = useState(false);\n const [showUploadPatch, setShowUploadPatch] = useState(false);\n const [showUploadProject, setShowUploadProject] = useState(false);\n const [showUploadAudio, setShowUploadAudio] = useState(false);\n\n const addNodeHandler = useCallback(\n (x: number, y: number) => {\n setMousePosition({ x, y });\n setShowAddNode(true);\n },\n [setShowAddNode],\n );\n\n const pasteBuffer = useStore((store) => store.pasteBuffer);\n const { screenToFlowPosition } = useReactFlow();\n const pasteBufferHandler = useCallback(\n (mousePosition: XYPosition) => {\n const { x, y } = screenToFlowPosition(mousePosition);\n pasteBuffer(x, y);\n },\n [setShowAddNode, screenToFlowPosition],\n );\n\n const clearGraph = useStore(({ clearGraph }) => clearGraph);\n\n const getEditorState = useStore((store) => store.getEditorState);\n const getProject = useStore((store) => store.getProject);\n\n const deleteAllHandler = useCallback(() => {\n clearGraph();\n }, [clearGraph]);\n\n const toggleHelp = useStore((store) => store.toggleHelp);\n\n const historyBack = useStore((store) => store.history.back);\n const historyForward = useStore((store) => store.history.forward);\n const historyPointer = useStore((store) => store.history.pointer);\n const historyBuffer = useStore((store) => store.history.buffer);\n\n const copySelectedItems = useStore((store) => store.copySelectedItems);\n const nodes = useStore((store) => store.nodes);\n const selectedNodes = useMemo(\n () => nodes.filter(({ selected }) => selected),\n [nodes],\n );\n const currentCopyBuffer = useStore((store) => store.copyBuffer);\n\n const reactFlowInstance = useReactFlow();\n\n const downloadPatchHandler = useCallback(() => {\n const fileName = \"web-noise-patch.json\";\n const editorState = getEditorState();\n const data = {\n ...editorState,\n };\n downloadFile(JSON.stringify(data, null, 2), fileName);\n }, [getEditorState, reactFlowInstance]);\n\n const downloadProjectHandler = useCallback(() => {\n const fileName = \"web-noise-project.json\";\n const projectState = getProject();\n const data = {\n ...projectState,\n };\n downloadFile(JSON.stringify(data, null, 2), fileName);\n }, [getEditorState, reactFlowInstance]);\n\n useEffect(() => {\n hotkeys(\"command+shift+a\", () => {\n addNodeHandler(200, 50);\n return false;\n });\n //@TODO: find more elegant way to handle ?\n hotkeys(\"shift+/\", () => {\n toggleHelp();\n return false;\n });\n hotkeys(\"command+z\", () => {\n historyBack();\n return false;\n });\n hotkeys(\"command+shift+z\", () => {\n historyForward();\n return false;\n });\n hotkeys(\"command+c\", () => {\n copySelectedItems();\n return false;\n });\n hotkeys(\"command+v\", () => {\n pasteBufferHandler({ x: 200, y: 50 });\n return false;\n });\n return () => {\n hotkeys.unbind();\n };\n }, [addNodeHandler, pasteBufferHandler]);\n\n return (\n <>\n <AddNode\n isOpen={showAddNode}\n closeMenu={() => setShowAddNode(false)}\n mousePosition={mousePosition}\n />\n <UploadPatch\n isOpen={showUploadPatch}\n closeMenu={() => setShowUploadPatch(false)}\n />\n <UploadProject\n isOpen={showUploadProject}\n closeMenu={() => setShowUploadProject(false)}\n />\n <UploadAudio\n isOpen={showUploadAudio}\n closeMenu={() => setShowUploadAudio(false)}\n />\n <MenuWrapper id={MENU_ID} animation={false} colors={theme.colors}>\n <ItemWrapper\n onClick={({ triggerEvent: { clientX, clientY } }) =>\n addNodeHandler(clientX, clientY)\n }\n >\n Add Node (⌘+⇧+A)\n </ItemWrapper>\n <Separator />\n <ItemWrapper onClick={deleteAllHandler}>Delete All</ItemWrapper>\n <Separator />\n <ItemWrapper onClick={downloadPatchHandler}>Download patch</ItemWrapper>\n <ItemWrapper onClick={() => setShowUploadPatch(true)}>\n Upload patch\n </ItemWrapper>\n <Separator />\n <ItemWrapper onClick={downloadProjectHandler}>\n Download project\n </ItemWrapper>\n <ItemWrapper onClick={() => setShowUploadProject(true)}>\n Upload project\n </ItemWrapper>\n <Separator />\n <ItemWrapper onClick={() => setShowUploadAudio(true)}>\n Upload Audio File\n </ItemWrapper>\n <Separator />\n <ItemWrapper disabled={historyPointer === 0} onClick={historyBack}>\n Undo (⌘+z)\n </ItemWrapper>\n <ItemWrapper\n disabled={historyPointer === historyBuffer.length}\n onClick={historyForward}\n >\n Redo (⌘+⇧+Z)\n </ItemWrapper>\n <Separator />\n <ItemWrapper\n disabled={!selectedNodes.length}\n onClick={copySelectedItems}\n >\n Copy Selected (⌘+c)\n </ItemWrapper>\n <ItemWrapper\n disabled={!currentCopyBuffer.nodes.length}\n onClick={({ triggerEvent: { clientX: x, clientY: y } }) =>\n pasteBufferHandler({ x, y })\n }\n >\n Paste (⌘+v)\n </ItemWrapper>\n <Separator />\n {editorContextMenu.map((item, index) => (\n <ItemWrapper key={index}>{item}</ItemWrapper>\n ))}\n <Separator />\n <ItemWrapper onClick={toggleHelp}>Help (⇧+?)</ItemWrapper>\n </MenuWrapper>\n </>\n );\n};\n\nexport default EditorContextMenu;\n","import styled from \"@emotion/styled\";\nimport { MouseEvent, useCallback, useState } from \"react\";\nimport { Position, useReactFlow } from \"reactflow\";\nimport useTheme from \"../../hooks/useTheme\";\nimport useStore from \"../../store\";\nimport { Theme } from \"../../theme\";\nimport { PluginComponent } from \"../../types\";\nimport Modal from \"../Modal\";\nimport Filters, { FiltersState } from \"./Filters\";\nimport Plugins from \"./Plugins\";\n\ninterface AddNodeProps {\n isOpen: boolean;\n closeMenu: () => void;\n mousePosition: MousePosition;\n}\n\ntype MousePosition = {\n x: number;\n y: number;\n};\n\nconst AddNodeWrapper = styled.div<{ theme: Theme }>`\n height: 100%;\n width: 100%;\n display: flex;\n gap: 1rem;\n`;\n\nconst PluginsPanel = styled.div<{ theme: Theme }>`\n flex-grow: 1;\n height: 100%;\n overflow-y: scroll;\n`;\n\nconst AddNode = ({ isOpen, closeMenu, mousePosition }: AddNodeProps) => {\n const theme = useTheme();\n const { screenToFlowPosition } = useReactFlow();\n\n const { createNode } = useStore(({ createNode }) => ({\n createNode,\n }));\n\n const [filtersState, setFiltersState] = useState<FiltersState>({});\n\n const onComponentClick = useCallback(\n ({ type }: PluginComponent) => {\n const { x, y } = screenToFlowPosition(mousePosition);\n const newNode = {\n //@TODO: generate node id in `createNode` function\n id: `${type}-${+new Date()}`,\n type,\n data: { label: type },\n position: {\n x,\n y,\n },\n targetPosition: Position.Left,\n sourcePosition: Position.Right,\n };\n createNode(newNode);\n closeMenu();\n },\n [mousePosition, screenToFlowPosition, createNode, closeMenu, mousePosition],\n );\n\n return isOpen ? (\n <Modal\n onClose={() => {\n closeMenu();\n setFiltersState({});\n }}\n >\n <AddNodeWrapper theme={theme}>\n <Filters onChange={setFiltersState} value={filtersState} />\n <PluginsPanel theme={theme}>\n <Plugins\n filters={filtersState}\n onTagClick={(tag) => {\n setFiltersState((state) => ({\n ...state,\n tags: state.tags?.includes(tag)\n ? state.tags.filter((t) => t !== tag)\n : [...(state.tags || []), tag],\n }));\n }}\n onComponentClick={(component) => {\n onComponentClick(component);\n setFiltersState({});\n }}\n />\n </PluginsPanel>\n </AddNodeWrapper>\n </Modal>\n ) : null;\n};\n\nexport default AddNode;\n","import styled from \"@emotion/styled\";\nimport { withTheme } from \"@emotion/react\";\nimport { useEffect, useRef } from \"react\";\nimport useTheme from \"../../hooks/useTheme\";\nimport useStore from \"../../store\";\nimport { Theme } from \"../../theme\";\nimport { PluginTag, TagsList } from \"./Plugins\";\n\nconst InputWrapper = styled.div`\n display: flex;\n position: relative;\n`;\n\nconst InputInner = styled.input<{ theme: Theme }>`\n padding-right: 2rem;\n padding-left: 0.3rem;\n width: 100%;\n appearance: textfield;\n font-size: inherit;\n background: none;\n border: none;\n color: var(--leva-colors-highlight1);\n font-family: var(--leva-fonts-mono);\n cursor: inherit;\n text-overflow: ellipsis;\n outline: none;\n appearance: textfield;\n cursor: auto;\n background-color: ${({ theme }) => theme.colors.elevation3};\n border-radius: 0.1rem;\n height: 2rem;\n color: ${({ theme }) => theme.colors.highlight2};\n\n &:focus,\n &:hover {\n box-shadow: 0 0 0 var(--leva-borderWidths-focus)\n ${({ theme }) => theme.colors.accent2};\n color: ${({ theme }) => theme.colors.whitePrimary};\n }\n &::-webkit-inner-spin-button,\n &::-webkit-outer-spin-button {\n -webkit-appearance: none;\n margin-right: 1rem;\n }\n`;\n\nconst FiltersWrapper = styled.div<{ theme: Theme }>`\n display: flex;\n flex-direction: column;\n padding: 0.6rem;\n gap: 0.6rem;\n border-right: 1px solid ${({ theme }) => theme.colors.elevation3};\n min-width: 14rem;\n`;\n\nconst PluginName = styled.label<{ theme: Theme }>`\n user-select: none;\n input {\n display: none;\n }\n input:checked + span {\n color: ${({ theme }) => theme.colors.accent2};\n }\n &:hover {\n color: ${({ theme }) => theme.colors.accent3};\n cursor: pointer;\n }\n`;\n\nconst StyledPluginTag = withTheme(styled(PluginTag)<{ theme: Theme }>`\n font-size: 12px;\n padding: 0.2rem 0.4rem;\n &:hover {\n }\n &::after {\n content: \"×\";\n margin-left: 0.4rem;\n }\n`);\n\nexport interface FiltersState {\n search?: string;\n plugin?: string | null;\n tags?: string[];\n}\n\ninterface FiltersProps {\n value: FiltersState;\n onChange: (filters: FiltersState) => void;\n}\n\nconst Filters = ({ onChange, value }: FiltersProps) => {\n const theme = useTheme();\n const plugins = useStore(({ plugins }) => plugins);\n\n const inputRef = useRef<HTMLInputElement>(null);\n\n useEffect(() => {\n if (!inputRef.current) {\n return;\n }\n inputRef.current.focus();\n }, [inputRef]);\n\n return (\n <FiltersWrapper theme={theme}>\n <InputWrapper>\n <InputInner\n ref={inputRef}\n theme={theme}\n value={value.search || \"\"}\n placeholder=\"search...\"\n onChange={(event) =>\n onChange({ ...value, search: event.target.value })\n }\n />\n </InputWrapper>\n <TagsList>\n {value.tags?.map((tag, index) => (\n <StyledPluginTag\n key={index}\n isActive\n onClick={() => {\n const newTags = value.tags?.filter((t) => t !== tag) || [];\n onChange({ ...value, tags: newTags });\n }}\n >\n {tag}\n </StyledPluginTag>\n ))}\n </TagsList>\n {plugins.map(({ name, components }, index) => {\n if (!name) {\n return null;\n }\n return (\n <PluginName theme={theme} key={index}>\n <input\n type=\"checkbox\"\n name=\"plugin\"\n value={name}\n checked={name === value.plugin}\n onChange={() => {\n onChange({\n ...value,\n plugin: name === value.plugin ? null : name,\n });\n }}\n />\n <span>{name}</span>\n </PluginName>\n );\n })}\n </FiltersWrapper>\n );\n};\n\nexport default Filters;\n","import styled from \"@emotion/styled\";\nimport { useMemo } from \"react\";\nimport useStore from \"../../store\";\nimport { Theme } from \"../../theme\";\nimport { PluginComponent } from \"../../types\";\nimport { FiltersState } from \"./Filters\";\nimport { withTheme } from \"@emotion/react\";\n\nconst PluginsWrapper = withTheme(styled.div<{ theme: Theme }>`\n width: 100%;\n`);\n\nconst PluginWrapper = withTheme(styled.div<{ theme: Theme }>`\n padding: 1rem;\n display: flex;\n flex-direction: column;\n gap: 1rem;\n`);\n\nconst NodesList = withTheme(styled.ul<{ theme: Theme }>`\n list-style: none;\n margin: 0;\n padding: 0;\n padding-bottom: 10px;\n columns: 2;\n\n li {\n display: flex;\n flex-direction: column;\n gap: 8px;\n padding: 4px;\n overflow: hidden;\n border: 1px solid ${({ theme }) => theme.colors.elevation3};\n border-radius: 4px;\n margin-bottom: 0.5rem;\n &:hover {\n border-color: ${({ theme }) => theme.colors.accent2};\n cursor: pointer;\n }\n }\n`);\n\nconst NodeTitle = withTheme(styled.div<{ theme: Theme }>`\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n`);\n\nconst NodeDescription = withTheme(styled.div<{ theme: Theme }>`\n color: ${({ theme }) => theme.colors.highlight2};\n font-size: 12px;\n`);\n\nexport const TagsList = withTheme(styled.div<{ theme: Theme }>`\n display: flex;\n gap: 0.2rem;\n flex-wrap: wrap;\n`);\n\nexport const PluginTag = withTheme(styled.span<{\n theme: Theme;\n isActive?: boolean;\n}>`\n cursor: pointer;\n font-size: 10px;\n background: ${({ theme, isActive }) =>\n isActive ? theme.colors.highlight1 : theme.colors.elevation3};\n border-radius: 2px;\n padding: 0.1rem 0.2rem;\n border: 1px solid;\n border-color: ${({ theme }) => theme.colors.elevation2};\n &:hover {\n border-color: ${({ theme }) => theme.colors.accent2};\n }\n`);\n\nconst PluginHeader = withTheme(styled.div<{ theme: Theme }>``);\n\nconst PluginTitle = withTheme(styled.div<{ theme: Theme }>`\n font-size: 1.1rem;\n padding: 0.25rem 0;\n color: ${({ theme }) => theme.colors.highlight3};\n`);\n\nconst PluginDescription = withTheme(styled.div<{ theme: Theme }>`\n color: ${({ theme }) => theme.colors.highlight2};\n font-size: 12px;\n`);\n\ninterface PluginsProps {\n filters: FiltersState;\n onComponentClick: (component: PluginComponent) => void;\n onTagClick: (tag: string) => void;\n}\n\nconst Plugins = ({\n onComponentClick,\n filters: { plugin, search = \"\", tags },\n onTagClick,\n}: PluginsProps) => {\n const plugins = useStore(({ plugins }) => plugins);\n\n const pluginsGroup = useMemo(() => {\n if (!plugin) {\n return plugins;\n }\n return plugins.filter(({ name }) => name === plugin);\n }, [plugins, plugin]);\n\n const filteredPlugins = useMemo(() => {\n if (!search && !tags?.length) {\n return pluginsGroup;\n }\n const filteredByTags = pluginsGroup.map((plugin) => ({\n ...plugin,\n components: tags?.length\n ? plugin.components.filter((component) =>\n tags?.every((tag) => component.tags?.includes(tag)),\n )\n : plugin.components,\n }));\n return filteredByTags.map((plugin) => ({\n ...plugin,\n components: plugin.components.filter(\n ({ type, name }) =>\n type.toLocaleLowerCase().includes(search.toLocaleLowerCase()) ||\n name?.toLocaleLowerCase().includes(search.toLocaleLowerCase()),\n ),\n }));\n }, [pluginsGroup, search, tags]);\n\n return (\n <PluginsWrapper>\n {filteredPlugins.map(({ name, description, components }, index) => {\n if (!components.length) {\n return null;\n }\n return (\n <PluginWrapper key={index}>\n <PluginHeader>\n <PluginTitle>{name}</PluginTitle>\n <PluginDescription>{description}</PluginDescription>\n </PluginHeader>\n <NodesList>\n {components\n .sort((a, b) =>\n a.type.toLowerCase() > b.type.toLowerCase() ? 1 : -1,\n )\n .map((component, idx) => (\n <li onClick={() => onComponentClick(component)} key={idx}>\n <NodeTitle>{component.name || component.type}</NodeTitle>\n {component.description && (\n <NodeDescription>{component.description}</NodeDescription>\n )}\n <TagsList>\n {component.tags?.map((tag, tagIdx) => (\n <PluginTag\n isActive={tags?.includes(tag)}\n onClickCapture={(event) => {\n event.stopPropagation();\n onTagClick(tag);\n }}\n key={tagIdx}\n >\n {tag}\n </PluginTag>\n ))}\n </TagsList>\n </li>\n ))}\n </NodesList>\n </PluginWrapper>\n );\n })}\n </PluginsWrapper>\n );\n};\n\nexport default Plugins;\n","import styled from \"@emotion/styled\";\nimport { MouseEvent, useCallback, useState, useRef, ChangeEvent } from \"react\";\nimport { FileDrop } from \"react-file-drop\";\nimport { FaFileUpload } from \"react-icons/fa\";\nimport useTheme from \"../hooks/useTheme\";\nimport useStore from \"../store\";\nimport { Theme } from \"../theme\";\nimport Modal from \"./Modal\";\n\ninterface UploadPatchProps {\n isOpen: boolean;\n closeMenu: () => void;\n}\n\nconst UploadPatchWrapper = styled.div<{ theme: Theme }>`\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n width: 100%;\n\n .drop-zone-wrapper {\n width: 80%;\n height: 80%;\n }\n\n .drop-zone {\n height: 100%;\n width: 100%;\n border-style: dashed;\n border-width: 2px;\n border-color: ${({ theme }) => theme.colors.highlight2};\n opacity: 0.5;\n cursor: pointer;\n }\n\n .drop-zone:hover,\n .drop-zone-drag-over {\n opacity: 1;\n }\n`;\n\nconst DropZoneInner = styled.div<{ theme: Theme }>`\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: center;\n height: 100%;\n width: 100%;\n`;\n\nconst FileUploadIcon = styled(FaFileUpload)`\n width: 100%;\n height: 8rem;\n`;\n\nconst FileUploadMessage = styled.div`\n font-size: 2rem;\n`;\n\nconst UploadPatch = ({ isOpen, closeMenu }: UploadPatchProps) => {\n const theme = useTheme();\n\n const setGraph = useStore(({ setGraph }) => setGraph);\n const setEditorState = useStore((store) => store.setEditorState);\n\n const fileInputRef = useRef<HTMLInputElement>(null);\n\n const uploadFile = useCallback(\n (files: FileList | null) => {\n const [file] = files || [];\n file\n .text()\n .then(JSON.parse)\n .then((editorState) => {\n setEditorState(editorState);\n closeMenu();\n })\n .catch(console.error);\n },\n [setGraph, closeMenu],\n );\n\n const onTargetClick = () => {\n fileInputRef.current?.click();\n };\n\n return isOpen ? (\n <Modal onClose={closeMenu}>\n <UploadPatchWrapper theme={theme}>\n <input\n onChange={({ target: { files } }) => uploadFile(files)}\n ref={fileInputRef}\n type=\"file\"\n className=\"hidden\"\n style={{ display: \"none\" }}\n accept=\".json\"\n />\n <FileDrop\n className=\"drop-zone-wrapper\"\n targetClassName=\"drop-zone\"\n draggingOverTargetClassName=\"drop-zone-drag-over\"\n onTargetClick={onTargetClick}\n onDrop={(files) => uploadFile(files)}\n >\n <DropZoneInner theme={theme}>\n <FileUploadIcon />\n <FileUploadMessage>click or drop file here</FileUploadMessage>\n </DropZoneInner>\n </FileDrop>\n </UploadPatchWrapper>\n </Modal>\n ) : null;\n};\n\nexport default UploadPatch;\n","import styled from \"@emotion/styled\";\nimport { useCallback, useRef } from \"react\";\nimport { FileDrop } from \"react-file-drop\";\nimport { FaFileUpload } from \"react-icons/fa\";\nimport useTheme from \"../hooks/useTheme\";\nimport useStore from \"../store\";\nimport { Theme } from \"../theme\";\nimport Modal from \"./Modal\";\n\ninterface UploadProjectProps {\n isOpen: boolean;\n closeMenu: () => void;\n}\n\nconst UploadProjectWrapper = styled.div<{ theme: Theme }>`\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n width: 100%;\n\n .drop-zone-wrapper {\n width: 80%;\n height: 80%;\n }\n\n .drop-zone {\n height: 100%;\n width: 100%;\n border-style: dashed;\n border-width: 2px;\n border-color: ${({ theme }) => theme.colors.highlight2};\n opacity: 0.5;\n cursor: pointer;\n }\n\n .drop-zone:hover,\n .drop-zone-drag-over {\n opacity: 1;\n }\n`;\n\nconst DropZoneInner = styled.div<{ theme: Theme }>`\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: center;\n height: 100%;\n width: 100%;\n`;\n\nconst FileUploadIcon = styled(FaFileUpload)`\n width: 100%;\n height: 8rem;\n`;\n\nconst FileUploadMessage = styled.div`\n font-size: 2rem;\n`;\n\n// @TODO: unify with upload file\nconst UploadProject = ({ isOpen, closeMenu }: UploadProjectProps) => {\n const theme = useTheme();\n\n const setProject = useStore((store) => store.setProject);\n\n const fileInputRef = useRef<HTMLInputElement>(null);\n\n const uploadFile = useCallback(\n (files: FileList | null) => {\n const [file] = files || [];\n file\n .text()\n .then(JSON.parse)\n .then((projectState) => {\n setProject(projectState);\n closeMenu();\n })\n .catch(console.error);\n },\n [setProject, closeMenu],\n );\n\n const onTargetClick = () => {\n fileInputRef.current?.click();\n };\n\n return isOpen ? (\n <Modal onClose={closeMenu}>\n <UploadProjectWrapper theme={theme}>\n <input\n onChange={({ target: { files } }) => uploadFile(files)}\n ref={fileInputRef}\n type=\"file\"\n className=\"hidden\"\n style={{ display: \"none\" }}\n accept=\".json\"\n />\n <FileDrop\n className=\"drop-zone-wrapper\"\n targetClassName=\"drop-zone\"\n draggingOverTargetClassName=\"drop-zone-drag-over\"\n onTargetClick={onTargetClick}\n onDrop={(files) => uploadFile(files)}\n >\n <DropZoneInner theme={theme}>\n <FileUploadIcon />\n <FileUploadMessage>click or drop file here</FileUploadMessage>\n </DropZoneInner>\n </FileDrop>\n </UploadProjectWrapper>\n </Modal>\n ) : null;\n};\n\nexport default UploadProject;\n","import styled from \"@emotion/styled\";\nimport { MouseEvent, useCallback, useState, useRef, ChangeEvent } from \"react\";\nimport { FileDrop } from \"react-file-drop\";\nimport { FaFileUpload } from \"react-icons/fa\";\nimport useTheme from \"../hooks/useTheme\";\nimport useStore from \"../store\";\nimport { Theme } from \"../theme\";\nimport Modal from \"./Modal\";\nimport { fileToBase64 } from \"../lib\";\n\ninterface UploadAudioProps {\n isOpen: boolean;\n closeMenu: () => void;\n}\n\nconst UploadAudioWrapper = styled.div<{ theme: Theme }>`\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n width: 100%;\n\n .drop-zone-wrapper {\n width: 80%;\n height: 80%;\n }\n\n .drop-zone {\n height: 100%;\n width: 100%;\n border-style: dashed;\n border-width: 2px;\n border-color: ${({ theme }) => theme.colors.highlight2};\n opacity: 0.5;\n cursor: pointer;\n }\n\n .drop-zone:hover,\n .drop-zone-drag-over {\n opacity: 1;\n }\n`;\n\nconst DropZoneInner = styled.div<{ theme: Theme }>`\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: center;\n height: 100%;\n width: 100%;\n`;\n\nconst FileUploadIcon = styled(FaFileUpload)`\n width: 100%;\n height: 8rem;\n`;\n\nconst FileUploadMessage = styled.div`\n font-size: 2rem;\n`;\n\nconst UploadAudio = ({ isOpen, closeMenu }: UploadAudioProps) => {\n const theme = useTheme();\n\n const setGraph = useStore(({ setGraph }) => setGraph);\n const setEditorState = useStore((store) => store.setEditorState);\n const addFile = useStore((store) => store.addFile);\n\n const fileInputRef = useRef<HTMLInputElement>(null);\n\n const uploadFile = useCallback(\n async (files: FileList | null) => {\n const [file] = files || [];\n const base64 = await fileToBase64(file);\n addFile({\n type: \"audio\",\n // @TODO: use nanoid here\n id: `audio-file-${+new Date()}`,\n name: file.name,\n file: base64,\n });\n closeMenu();\n },\n [addFile, closeMenu],\n );\n\n const onTargetClick = () => {\n fileInputRef.current?.click();\n };\n\n return isOpen ? (\n <Modal onClose={closeMenu}>\n <UploadAudioWrapper theme={theme}>\n <input\n onChange={({ target: { files } }) => uploadFile(files)}\n ref={fileInputRef}\n type=\"file\"\n className=\"hidden\"\n style={{ display: \"none\" }}\n accept=\".wav,.mp3,.ogg\"\n />\n <FileDrop\n className=\"drop-zone-wrapper\"\n targetClassName=\"drop-zone\"\n draggingOverTargetClassName=\"drop-zone-drag-over\"\n onTargetClick={onTargetClick}\n onDrop={(files) => uploadFile(files)}\n >\n <DropZoneInner theme={theme}>\n <FileUploadIcon />\n <FileUploadMessage>click or drop file here</FileUploadMessage>\n </DropZoneInner>\n </FileDrop>\n </UploadAudioWrapper>\n </Modal>\n ) : null;\n};\n\nexport default UploadAudio;\n","export { useWorker } from \"./hooks/useWorker\";\nexport { useMessageChannel } from \"./hooks/useMessageChannel\";\nexport * from \"./helpers\";\n","import { useEffect, useState } from \"react\";\n\nexport const useWorker = (url: string | URL) => {\n const [worker, setWorker] = useState<Worker | null>(null);\n\n useEffect(() => {\n const newWorker = new Worker(url);\n setWorker(newWorker);\n return () => {\n newWorker?.terminate();\n setWorker(null);\n };\n }, []);\n\n return worker;\n};\n\nexport default useWorker;\n","import { useEffect, useState, version } from \"react\";\n\nconsole.log(888888, `React version: ${version}`);\n\nexport const useMessageChannel = () => {\n const [channel, setChannel] = useState<MessageChannel | null>(null);\n useEffect(() => {\n const newChannel = new MessageChannel();\n newChannel.port2.start();\n setChannel(newChannel);\n return () => {\n setChannel(null);\n newChannel.port2.close();\n };\n }, []);\n return channel;\n};\n\nexport default useMessageChannel;\n","export const setParameterValue = (\n param: AudioParam,\n value: number | undefined,\n audioContext: AudioContext,\n): void => {\n if (typeof value === \"undefined\") {\n return;\n }\n param.setValueAtTime(value, audioContext.currentTime);\n};\n\nexport const fileToBase64 = (file: File): Promise<string> => {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.readAsDataURL(file);\n reader.onload = () => resolve(reader.result?.toString() || \"\");\n reader.onerror = (error) => reject(error);\n });\n};\n","import { useCallback } from \"react\";\nimport { useContextMenu, PredicateParams } from \"react-contexify\";\nimport \"react-contexify/dist/ReactContexify.css\";\nimport { WNNode } from \"../../types\";\nimport useTheme from \"../../hooks/useTheme\";\nimport useStore from \"../../store\";\nimport { ItemWrapper, MenuWrapper } from \"./styles\";\n\nexport const MENU_ID = \"editor-node-menu\";\n\nexport const useNodeContextMenu = () => {\n const { show } = useContextMenu({\n id: MENU_ID,\n });\n\n const onContextMenu = useCallback(\n (event: React.MouseEvent<Element, MouseEvent>, node: unknown) => {\n event.stopPropagation();\n show(event, { props: { node } });\n },\n [],\n );\n\n return { onContextMenu };\n};\n\nconst NodeContextMenu = (args: unknown) => {\n const theme = useTheme();\n\n const removeNodes = useStore((store) => store.removeNodes);\n const addNodeToControlPanel = useStore(\n (store) => store.addNodeToControlPanel,\n );\n const removeNodeFromControlPanel = useStore(\n (store) => store.removeNodeFromControlPanel,\n );\n const copy = useStore((store) => store.copy);\n const nodesConfiguration = useStore((store) => store.nodesConfiguration);\n const controlPanelNodes = useStore((store) => store.controlPanel.nodes);\n\n const isOnControlPanel = useCallback(\n ({ props }: PredicateParams<{ node: WNNode }>) => {\n if (!props?.node.type) {\n return false;\n }\n return !!controlPanelNodes.find(({ id }) => id === props.node.id);\n },\n [controlPanelNodes],\n );\n\n const hasControlPanelNode = useCallback(\n ({ props }: PredicateParams<{ node: WNNode }>) => {\n if (!props?.node.type) {\n return false;\n }\n const nodeConfiguration = nodesConfiguration[props.node.type];\n return !!nodeConfiguration?.controlPanelNode;\n },\n [nodesConfiguration],\n );\n\n return (\n <>\n <MenuWrapper id={MENU_ID} animation={false} colors={theme.colors}>\n <ItemWrapper onClick={(event) => removeNodes([event.props.node])}>\n Delete Node (DEL)\n </ItemWrapper>\n <ItemWrapper\n hidden={(...args) =>\n !hasControlPanelNode(...args) || isOnControlPanel(...args)\n }\n onClick={(event) => addNodeToControlPanel(event.props.node)}\n >\n Add To Control Panel\n </ItemWrapper>\n <ItemWrapper\n hidden={(...args) =>\n !hasControlPanelNode(...args) || !isOnControlPanel(...args)\n }\n onClick={(event) => removeNodeFromControlPanel(event.props.node)}\n >\n Remove From Control Panel\n </ItemWrapper>\n <ItemWrapper\n onClick={(event) => copy({ nodes: [event.props.node], edges: [] })}\n >\n Copy (⌘+c)\n </ItemWrapper>\n </MenuWrapper>\n </>\n );\n};\n\nexport default NodeContextMenu;\n","import styled from \"@emotion/styled\";\nimport { Resizable } from \"re-resizable\";\nimport { useMemo, useRef, useState } from \"react\";\nimport GridLayout from \"react-grid-layout\";\nimport \"react-grid-layout/css/styles.css\";\nimport {\n AiFillLock as LockIcon,\n AiFillUnlock as UnlockIcon,\n} from \"react-icons/ai\";\nimport { MdClose as CloseIcon } from \"react-icons/md\";\nimport { RxDashboard as ControlPanelIcon } from \"react-icons/rx\";\nimport Drawer from \"react-modern-drawer\";\nimport \"react-modern-drawer/dist/index.css\";\nimport { CONTROL_PANEL_GRID_CONFIG } from \"../../constants\";\nimport useTheme from \"../../hooks/useTheme\";\nimport useStore from \"../../store\";\nimport { Theme } from \"../../theme\";\nimport ControlPanelItem from \"./ControlPanelItem\";\nimport { IconsBar, IconWrapper, PanelTitle, TitleBarWrapper } from \"./styles\";\n\nconst ControlPanelIconWrapper = styled.div<{ theme: Theme }>`\n position: fixed;\n z-index: 5;\n box-shadow: 0px 1px 2px ${({ theme }) => theme.colors.elevation2};\n left: 1rem;\n top: 4rem;\n width: 2rem;\n height: 2rem;\n border-radius: 50%;\n overflow: hidden;\n display: flex;\n align-items: center;\n justify-content: center;\n background: ${({ theme }) => theme.colors.elevation1};\n color: ${({ theme }) => theme.colors.highlight1};\n\n :hover {\n color: ${({ theme }) => theme.colors.highlight2};\n cursor: pointer;\n }\n`;\n\nconst ControlPanelIconsBar = styled(IconsBar)`\n height: 80%;\n`;\n\nconst CloseIconWrapper = styled(IconWrapper)`\n font-size: 1rem;\n display: flex;\n align-items: center;\n`;\n\nconst ControlPanelHeader = styled(TitleBarWrapper)<{ theme: Theme }>`\n grid-template-columns: 1fr auto;\n border-bottom: 1px solid ${({ theme }) => theme.colors.elevation3};\n font-size: 0.7rem;\n`;\n\nconst ControlPanelTitle = styled(PanelTitle)`\n text-align: center;\n`;\n\nconst ControlPanelWrapper = styled.div`\n height: 100%;\n width: 100%;\n padding: 0.3rem 0.4rem;\n box-sizing: border-box;\n`;\n\nconst ControlPanelBody = styled.div<{ theme: Theme }>`\n height: auto;\n padding: 0;\n max-height: 95vh;\n overflow-y: scroll;\n border: 1px solid ${({ theme }) => theme.colors.elevation3};\n`;\n\nconst ControlPanelSettings = styled.div`\n padding: 1rem 0;\n font-family: var(--leva-fonts-mono);\n font-size: 0.8rem;\n`;\n\nconst LockGridWrapper = styled.div<{ theme: Theme }>`\n display: flex;\n align-items: center;\n gap: 0.5rem;\n cursor: pointer;\n color: ${({ theme }) => theme.colors.highlight1};\n &:hover {\n color: ${({ theme }) => theme.colors.highlight2};\n }\n`;\n\nconst GridResizeHandle = styled.div<{ theme: Theme }>`\n position: absolute;\n height: 1rem;\n top: 0;\n bottom: 0;\n margin: auto;\n left: 0.5rem;\n border-right: 1px solid ${({ theme }) => theme.colors.whitePrimary};\n`;\n\nconst ControlPanelItemWrapper = styled.div<{ theme: Theme }>`\n box-sizing: border-box;\n overflow: hidden;\n .react-resizable-handle:after {\n border-color: ${({ theme }) => theme.colors.whitePrimary};\n border-width: 1px;\n }\n`;\n\nconst ControlPanel = () => {\n const theme = useTheme();\n const nodeRef = useRef(null);\n const nodes = useStore((store) => store.nodes);\n const {\n show,\n nodes: controlPanelNodes,\n size,\n } = useStore((store) => store.controlPanel);\n\n const { width = 200, height } = size;\n\n const filteredNodes = useMemo(() => {\n const nodeIds = controlPanelNodes.map(({ id }) => id);\n return nodes.filter(({ id }) => nodeIds.includes(id));\n }, [nodes, controlPanelNodes]);\n\n const showControlPanel = useStore((store) => store.showControlPanel);\n const hideControlPanel = useStore((store) => store.hideControlPanel);\n const setControlPanelNodes = useStore((store) => store.setControlPanelNodes);\n const setControlPanelSize = useStore((store) => store.setControlPanelSize);\n const removeNodeFromControlPanel = useStore(\n (store) => store.removeNodeFromControlPanel,\n );\n\n const [isGridLocked, setGridLocked] = useState(true);\n\n const layout = useMemo(() => {\n const fallbackY = controlPanelNodes.reduce(\n (acc, { height = CONTROL_PANEL_GRID_CONFIG.rowHeight, x, y = 0 }) => {\n const Y = y + height;\n return Y > acc ? Y : acc;\n },\n 0,\n );\n return controlPanelNodes.map(({ id: i, width, height, x, y }) => {\n return {\n i,\n w: width || CONTROL_PANEL_GRID_CONFIG.cols,\n h: height || 6,\n x: x ?? 0,\n y: y ?? fallbackY,\n };\n });\n }, [controlPanelNodes]);\n\n if (!filteredNodes.length) {\n return null;\n }\n\n return (\n <>\n <ControlPanelIconWrapper\n theme={theme}\n ref={nodeRef}\n onClick={showControlPanel}\n >\n <ControlPanelIcon />\n </ControlPanelIconWrapper>\n <Drawer\n open={show}\n onClose={hideControlPanel}\n direction=\"left\"\n className=\"\"\n size=\"auto\"\n enableOverlay={false}\n style={{\n background: theme.colors.elevation1,\n position: \"absolute\",\n }}\n >\n <ControlPanelHeader theme={theme}>\n <ControlPanelTitle>Control Panel</ControlPanelTitle>\n <ControlPanelIconsBar>\n <CloseIconWrapper onClick={hideControlPanel} theme={theme}>\n <CloseIcon />\n </CloseIconWrapper>\n </ControlPanelIconsBar>\n </ControlPanelHeader>\n\n <ControlPanelWrapper>\n <ControlPanelSettings>\n {isGridLocked ? (\n <LockGridWrapper\n theme={theme}\n onClick={() => setGridLocked(false)}\n >\n <LockIcon />\n Unlock grid\n </LockGridWrapper>\n ) : (\n <LockGridWrapper\n theme={theme}\n onClick={() => setGridLocked(true)}\n >\n <UnlockIcon />\n Lock grid\n </LockGridWrapper>\n )}\n </ControlPanelSettings>\n <Resizable\n enable={{\n top: false,\n right: !isGridLocked,\n bottom: false,\n left: false,\n topRight: false,\n bottomRight: false,\n bottomLeft: false,\n topLeft: false,\n }}\n handleComponent={{\n right: <GridResizeHandle theme={theme} />,\n }}\n minWidth={120}\n size={{ width, height: \"auto\" }}\n onResizeStop={(e, direction, ref, d) => {\n setControlPanelSize({\n width: width + d.width,\n height: height + d.height,\n });\n }}\n >\n <ControlPanelBody theme={theme}>\n {/* @ts-ignore */}\n <GridLayout\n layout={layout}\n className=\"layout\"\n cols={CONTROL_PANEL_GRID_CONFIG.cols}\n rowHeight={CONTROL_PANEL_GRID_CONFIG.rowHeight}\n width={width}\n margin={[0, 0]}\n isResizable={!isGridLocked}\n draggableHandle=\".grid-item-handle\"\n onLayoutChange={(nodes) => {\n requestAnimationFrame(() => {\n setControlPanelNodes(\n nodes.map(({ i, w, h, x, y }) => ({\n id: i,\n width: w,\n height: h,\n x,\n y,\n })),\n );\n });\n }}\n >\n {filteredNodes.map((node) => {\n return (\n <ControlPanelItemWrapper key={node.id} theme={theme}>\n <ControlPanelItem\n node={node}\n showControls={!isGridLocked}\n onDelete={removeNodeFromControlPanel}\n />\n </ControlPanelItemWrapper>\n );\n })}\n </GridLayout>\n </ControlPanelBody>\n </Resizable>\n </ControlPanelWrapper>\n </Drawer>\n </>\n );\n};\n\nexport default ControlPanel;\n","import { useMemo } from \"react\";\n\nimport styled from \"@emotion/styled\";\nimport \"react-grid-layout/css/styles.css\";\nimport { MdDragHandle as DragIcon } from \"react-icons/md\";\nimport { MdClose as CloseIcon } from \"react-icons/md\";\nimport useAudioNode from \"../../hooks/useAudioNode\";\nimport useNode from \"../../hooks/useNode\";\nimport useTheme from \"../../hooks/useTheme\";\nimport useStore from \"../../store\";\nimport { Theme } from \"../../theme\";\nimport { WNNode, ControlPanelNodeProps } from \"../../types\";\nimport { IconsBar, IconWrapper, PanelTitle, TitleBarWrapper } from \"./styles\";\n\nconst ControlPanelNodeWrapper = styled.div<{ theme: Theme }>`\n height: 100%;\n display: grid;\n grid-template-rows: auto 1fr;\n`;\n\nconst PanelNode = (props: ControlPanelNodeProps) => {\n const { node } = props;\n\n const getControlPanelNode = useStore((store) => store.getControlPanelNode);\n\n const ControlPanelNode = useMemo(() => getControlPanelNode(node), [node]);\n\n if (!ControlPanelNode) {\n return null;\n }\n\n return <ControlPanelNode {...props} />;\n};\n\ninterface ControlPanelItemProps {\n node: WNNode;\n showControls: boolean;\n onDelete: (node: WNNode) => void;\n}\n\nconst ControlPanelItem = (props: ControlPanelItemProps) => {\n const { node, showControls, onDelete } = props;\n const theme = useTheme();\n\n const { id } = node;\n const { node: audioNode } = useAudioNode(id) || {};\n const { updateNodeValues } = useNode(id);\n\n return (\n <ControlPanelNodeWrapper theme={theme}>\n <TitleBarWrapper theme={theme}>\n <PanelTitle>{node.data.label}</PanelTitle>\n {showControls && (\n <IconsBar>\n <IconWrapper theme={theme}>\n <DragIcon className=\"grid-item-handle\" />\n </IconWrapper>\n <IconWrapper theme={theme}>\n <CloseIcon onClick={() => onDelete(node)} />\n </IconWrapper>\n </IconsBar>\n )}\n </TitleBarWrapper>\n <PanelNode\n node={node}\n audioNode={audioNode}\n updateNodeValues={updateNodeValues}\n />\n </ControlPanelNodeWrapper>\n );\n};\n\nexport default ControlPanelItem;\n","import { AudioNodeState } from \"@web-noise/patch\";\nimport useStore from \"../store\";\nimport type { WNAudioNode } from \"../types\";\n\nconst useAudioNode = <T = WNAudioNode>(id: string) => {\n const patch = useStore(({ patch }) => patch);\n return patch.audioNodes.get(id) as AudioNodeState<T> | undefined;\n};\n\nexport default useAudioNode;\n","import { useCallback } from \"react\";\nimport useStore from \"../store\";\nimport { WNNodeData } from \"../types\";\n\nconst useNode = (id: string) => {\n const updateNodeData = useStore(({ updateNodeData }) => updateNodeData);\n\n const updateNodeValues = useCallback(\n (values: WNNodeData[\"values\"]) => updateNodeData(id, { values }),\n [id, updateNodeData]\n );\n const updateNodeConfig = useCallback(\n (config: WNNodeData[\"config\"]) => updateNodeData(id, { config }),\n [id, updateNodeData]\n );\n const updateNodeLabel = useCallback(\n (label: string) => updateNodeData(id, { label }),\n [id, updateNodeData]\n );\n\n return {\n updateNodeValues,\n updateNodeConfig,\n updateNodeLabel,\n };\n};\n\nexport default useNode;\n","import styled from \"@emotion/styled\";\nimport \"react-grid-layout/css/styles.css\";\nimport { Theme } from \"../../theme\";\nimport { TitleBar } from \"../Node\";\n\nexport const PanelTitle = styled.div`\n width: 100%;\n padding: 0.4rem 0;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n`;\n\nexport const TitleBarWrapper = styled(TitleBar)<{ theme: Theme }>`\n display: flex;\n gap: 0.1rem;\n padding: 0 0.4rem;\n justify-content: start;\n font-size: 0.6rem;\n height: auto;\n min-width: 0;\n`;\n\nexport const IconsBar = styled.div`\n display: flex;\n align-items: center;\n height: 70%;\n width: auto;\n gap: 0.4rem;\n`;\n\nexport const IconWrapper = styled.span<{ theme: Theme }>`\n width: auto;\n height: 100%;\n cursor: pointer;\n svg {\n width: auto;\n height: 100%;\n }\n &:hover {\n color: ${({ theme }) => theme.colors.highlight2};\n cursor: pointer;\n }\n`;\n","import styled from \"@emotion/styled\";\nimport { withTheme } from \"@emotion/react\";\nimport { Resizable } from \"re-resizable\";\nimport { ComponentProps, useMemo, useState } from \"react\";\nimport {\n MdSettings as SettingsIcon,\n MdInfoOutline as InfoIcon,\n} from \"react-icons/md\";\nimport { Handle, HandleProps, NodeProps, Position } from \"reactflow\";\nimport { DRAG_HANDLE_CLASS, PortType } from \"../../constants\";\nimport useAudioNode from \"../../hooks/useAudioNode\";\nimport useNode from \"../../hooks/useNode\";\nimport useTheme from \"../../hooks/useTheme\";\nimport useStore from \"../../store\";\nimport { Theme } from \"../../theme\";\nimport { AudioPort, WNNodeData } from \"../../types\";\nimport EditableLabel from \"../EditableLabel\";\nimport NodeInfoModal from \"../NodeInfoModal\";\n\nconst NodeWrapper = styled.div`\n background-color: var(--leva-colors-elevation1);\n`;\n\nconst NodeLoaderWrapper = styled(NodeWrapper)`\n padding: 2rem 5rem;\n`;\n\nconst NodeErrorWrapper = styled(NodeWrapper)`\n padding: 1rem 2rem;\n`;\n\nconst SettingsIconWrapper = styled(SettingsIcon)`\n font-size: 1.2rem;\n opacity: 0.4;\n width: 1rem;\n &:hover {\n opacity: 1;\n cursor: pointer;\n }\n`;\n\nconst InfoIconWrapper = styled(InfoIcon)`\n font-size: 1.2rem;\n opacity: 0.4;\n width: 1rem;\n &:hover {\n opacity: 1;\n cursor: pointer;\n }\n`;\n\nconst Section = styled.div`\n position: relative;\n font-family: var(--leva-fonts-mono);\n font-size: var(--leva-fontSizes-root);\n background-color: var(--leva-colors-elevation1);\n`;\n\nexport const TitleBarInner = styled(Section)`\n display: flex;\n height: var(--leva-sizes-titleBarHeight);\n touch-action: none;\n align-items: center;\n justify-content: center;\n flex: 1 1 0%;\n color: var(--leva-colors-highlight1);\n padding: 0 0.4rem;\n gap: 0.3rem;\n`;\n\nexport const PortsPanel = styled(Section)<{ theme: Theme }>(\n ({ theme }) => `\n display: grid;\n grid-template-areas: \"inputs outputs\";\n background: ${theme.colors.elevation2};\n border-bottom: 1px solid ${theme.colors.elevation1};\n color: ${theme.colors.highlight3};\n font-size: 0.6rem;\n`,\n);\n\nexport const InputPorts = styled.div`\n grid-area: inputs;\n text-align: left;\n`;\n\nexport const OutputPorts = styled.div`\n grid-area: outputs;\n text-align: right;\n`;\n\nexport const Port = styled.div`\n position: relative;\n padding: 5px 10px;\n`;\n\nconst portColors = {\n [PortType.Audio]: \"#4ade80\", // vibrant green\n [PortType.Gate]: \"#c084fc\", // rich purple\n [PortType.Number]: \"#38bdf8\", // bright blue\n [PortType.Any]: \"#ffffff\", // white\n};\n\nconst StyledHandle = withTheme(styled(Handle, {\n shouldForwardProp: (prop) => prop !== \"portType\",\n})<{ portType?: AudioPort[\"type\"]; theme: Theme }>`\n --port-color: ${(props) => {\n if (!props.portType) return props.theme.colors.highlight2;\n if (Array.isArray(props.portType)) {\n const colors = props.portType.map((type) => portColors[type]);\n return `linear-gradient(0.25turn, ${colors.join(\", \")});`;\n } else {\n return portColors[props.portType];\n }\n }};\n border-color: var(--port-color);\n background: var(--port-color);\n box-shadow: 0px 0px 0px 1px ${({ theme }) => theme.colors.elevation2} inset;\n`);\n\nconst StyledInputHandle = withTheme(styled(StyledHandle)`\n left: -3px;\n`);\n\nexport const InputHandle = ({\n ...props\n}: Partial<HandleProps & ComponentProps<typeof StyledInputHandle>>) => (\n <StyledInputHandle {...props} type=\"target\" position={Position.Left} />\n);\n\nexport const StyledOutputHandle = withTheme(styled(StyledHandle)`\n right: -3px;\n`);\n\nexport const OutputHandle = (\n props: Partial<HandleProps & ComponentProps<typeof StyledOutputHandle>>,\n) => <StyledOutputHandle {...props} type=\"source\" position={Position.Right} />;\n\nexport type WNNodeProps<T = Record<string, unknown>> = NodeProps<\n T & WNNodeData\n>;\n\nexport interface TitleBarProps {\n className?: string;\n [key: string]: unknown;\n}\n\nexport const TitleBar = ({ className, ...props }: TitleBarProps) => (\n <TitleBarInner\n {...props}\n className={[className, DRAG_HANDLE_CLASS].join(\" \")}\n />\n);\n\nexport interface WNNodeParameters extends NodeProps {\n children?: any;\n}\n\nconst useNodeManifest = (type: string) => {\n const data = useStore((store) => store.nodesConfiguration[type]);\n\n return data;\n};\n\nconst useConfigNode = (type: string) => {\n const { configNode: ConfigNode } = useNodeManifest(type);\n\n return {\n ConfigNode,\n };\n};\n\nexport const WNNode = (props: WNNodeParameters) => {\n const { id, children, selected, ...rest } = props;\n const theme = useTheme();\n const getNode = useStore(({ getNode }) => getNode);\n const nodesConfiguration = useStore((store) => store.nodesConfiguration);\n\n const [isInfoModalShown, setIsInfoModalShown] = useState(false);\n\n const { info } = useNodeManifest(props.type);\n\n const isResizeable = useMemo(\n () => nodesConfiguration[props.type].resizable ?? false,\n [nodesConfiguration, props.type],\n );\n\n const { updateNodeLabel, updateNodeConfig } = useNode(id);\n const { data } = getNode(id) || {};\n const audioNode = useAudioNode(id);\n const { ConfigNode } = useConfigNode(rest.type);\n\n const [configMode, setShowConfigMode] = useState(false);\n\n if (!audioNode) {\n return (\n <NodeLoaderWrapper className={DRAG_HANDLE_CLASS}>\n can't find audio node\n </NodeLoaderWrapper>\n );\n }\n\n if (audioNode.loading) {\n return (\n <NodeLoaderWrapper className={DRAG_HANDLE_CLASS}>\n loading\n </NodeLoaderWrapper>\n );\n }\n\n if (audioNode.error) {\n return (\n <NodeErrorWrapper className={DRAG_HANDLE_CLASS}>\n error: {audioNode.error.toString()}\n </NodeErrorWrapper>\n );\n }\n\n if (!audioNode.node) {\n return (\n <NodeLoaderWrapper className={DRAG_HANDLE_CLASS}>\n can't find audio node\n </NodeLoaderWrapper>\n );\n }\n\n const size = data?.config?.size as\n | { width: number; height: number }\n | undefined;\n\n const {\n node: { inputs, outputs },\n } = audioNode;\n\n return (\n <NodeWrapper>\n <TitleBar>\n {info && (\n <InfoIconWrapper onClickCapture={() => setIsInfoModalShown(true)} />\n )}\n <EditableLabel\n value={data?.label ?? \"No Name\"}\n onChange={updateNodeLabel}\n />\n {ConfigNode && (\n <SettingsIconWrapper\n onClickCapture={() => setShowConfigMode((isShown) => !isShown)}\n />\n )}\n </TitleBar>\n <PortsPanel theme={theme}>\n <InputPorts>\n {inputs\n ? Object.keys(inputs).map((key, index) => (\n <Port key={index}>\n <InputHandle id={key} portType={inputs[key].type} />\n <span>{key}</span>\n </Port>\n ))\n : null}\n </InputPorts>\n <OutputPorts>\n {outputs\n ? Object.keys(outputs).map((key, index) => (\n <Port key={index}>\n <OutputHandle id={key} portType={outputs[key].type} />\n <span>{key}</span>\n </Port>\n ))\n : null}\n </OutputPorts>\n </PortsPanel>\n {ConfigNode && configMode && selected ? (\n <ConfigNode {...props} />\n ) : isResizeable ? (\n <Resizable\n size={size}\n minWidth={180}\n minHeight={30}\n enable={{\n bottom: true,\n bottomRight: true,\n right: true,\n }}\n onResizeStop={(e, direction, ref, d) => {\n const newSize = size\n ? {\n width: size.width + d.width,\n height: size.height + d.height,\n }\n : ref.getBoundingClientRect();\n updateNodeConfig({\n ...data?.config,\n size: newSize,\n });\n }}\n >\n {children}\n </Resizable>\n ) : (\n children\n )}\n <NodeInfoModal\n isOpen={isInfoModalShown}\n type={props.type}\n onClose={() => setIsInfoModalShown(false)}\n node={audioNode.node}\n />\n </NodeWrapper>\n );\n};\n","import styled from \"@emotion/styled\";\nimport React, { useCallback, useEffect, useRef, useState } from \"react\";\n\nexport const TitleBarLabel = styled.input`\n width: 100%;\n background: none;\n border: none;\n text-align: center;\n color: var(--leva-colors-highlight1);\n font-family: var(--leva-fonts-mono);\n font-size: var(--leva-fontSizes-root);\n cursor: inherit;\n text-overflow: ellipsis;\n outline: none;\n\n &:focus {\n box-shadow: 0 0 0 green var(--leva-colors-accent2);\n }\n &:focus-within {\n box-shadow: 0 0 0 green var(--leva-colors-accent2);\n }\n &:focus-vissible {\n box-shadow: 0 0 0 green var(--leva-colors-accent2);\n }\n &:not([readonly]):focus {\n color: #fff;\n appearance: none;\n cursor: auto;\n background-color: var(--leva-colors-elevation2);\n padding: 0.3rem;\n border-radius: 0.2rem;\n }\n`;\n\ninterface EditableLabelProps {\n onChange: (value: string) => void;\n value?: string;\n className?: string;\n}\n\nconst EditableLabel = ({\n onChange,\n value = \"\",\n className,\n}: EditableLabelProps) => {\n const labelInputRef = useRef<HTMLInputElement>(null);\n\n const [labelEditMode, setLabelEditMode] = useState(false);\n const editNodeLabel = useCallback(\n (event: React.MouseEvent) => {\n //@ts-ignore\n event.target?.select();\n setLabelEditMode(true);\n },\n [setLabelEditMode],\n );\n\n const exitEditMode = useCallback(() => {\n window.getSelection()?.collapseToEnd();\n setLabelEditMode(false);\n }, [setLabelEditMode]);\n\n const saveNodeLabel = useCallback(() => {\n exitEditMode();\n if (labelInputRef.current) {\n onChange(labelInputRef.current.value);\n }\n }, [labelInputRef, exitEditMode, onChange]);\n\n const cancelNodeLabelEdit = useCallback(() => {\n exitEditMode();\n if (labelInputRef.current && value) {\n labelInputRef.current.value = value;\n }\n }, [labelInputRef, exitEditMode, value]);\n\n useEffect(() => {\n if (!labelInputRef.current) {\n return;\n }\n labelInputRef.current.value = value;\n }, [value, labelInputRef]);\n\n return (\n <TitleBarLabel\n ref={labelInputRef}\n type=\"text\"\n readOnly={!labelEditMode}\n onDoubleClick={(event) => editNodeLabel(event)}\n onBlur={saveNodeLabel}\n onKeyDown={(event) => {\n switch (event.key) {\n case \"Escape\":\n cancelNodeLabelEdit();\n break;\n case \"Enter\":\n saveNodeLabel();\n break;\n }\n }}\n className={className}\n />\n );\n};\n\nexport default EditableLabel;\n","import styled from \"@emotion/styled\";\nimport Modal from \"./Modal\";\nimport { marked } from \"marked\";\nimport useStore from \"../store\";\nimport { withTheme } from \"@emotion/react\";\nimport { useMemo } from \"react\";\nimport { WNAudioNode } from \"../types\";\nimport { Theme } from \"../theme\";\n\ninterface NodeInfoModalProps {\n isOpen: boolean;\n onClose: () => void;\n type: string;\n node: WNAudioNode;\n}\n\nconst NodeInfoWrapper = withTheme(styled.div<{ theme: Theme }>`\n height: 100%;\n width: 100%;\n overflow: scroll;\n padding: 0.6rem;\n box-sizing: border-box;\n\n hr {\n border: none;\n border-bottom: 1px solid ${({ theme }) => theme.colors.elevation3};\n }\n\n code {\n background-color: ${({ theme }) => theme.colors.elevation3};\n color: ${({ theme }) => theme.colors.highlight3};\n font-family:\n source-code-pro, Menlo, Monaco, Consolas, \"Courier New\", monospace;\n }\n\n pre {\n background-color: ${({ theme }) => theme.colors.elevation3};\n padding: 0.2rem 0.3rem;\n border-radius: 1px;\n }\n\n a {\n color: ${({ theme }) => theme.colors.accent1};\n }\n`);\n\nconst useNodeManifest = (type: string) => {\n const data = useStore((store) => store.nodesConfiguration[type]);\n return data;\n};\n\nconst NodeInfoModal = ({\n isOpen,\n onClose,\n type: nodeType,\n node,\n}: NodeInfoModalProps) => {\n const { info, portsDescription } = useNodeManifest(nodeType);\n\n const portsInfo = useMemo(() => {\n const parts: string[] = [];\n\n const inputPorts = node.inputs;\n if (inputPorts) {\n parts.push(`## Inputs`);\n for (const portName in inputPorts) {\n const port = inputPorts[portName];\n parts.push(`### *${portName}*`);\n\n const description = portsDescription?.inputs?.[portName];\n\n if (description) {\n parts.push(description);\n }\n\n if (Array.isArray(port.type)) {\n parts.push(`**Types**: \\`${port.type.join(\", \")}\\``);\n } else {\n parts.push(`**Type**: \\`${port.type || \"unknown\"}\\``);\n }\n\n if (port.range) {\n parts.push(`**Range**: \\`[${port.range[0]}, ${port.range[1]}]\\``);\n }\n\n if (port.defaultValue !== undefined) {\n parts.push(`**Default**: \\`${port.defaultValue}\\``);\n }\n }\n }\n\n const outputPorts = node.outputs;\n if (outputPorts) {\n parts.push(`## Outputs`);\n for (const portName in outputPorts) {\n const port = outputPorts[portName];\n parts.push(`### *${portName}*`);\n\n const description = portsDescription?.outputs?.[portName];\n\n if (description) {\n parts.push(description);\n }\n\n if (Array.isArray(port.type)) {\n parts.push(`**Types**: \\`${port.type.join(\", \")}\\``);\n } else {\n parts.push(`**Type**: \\`${port.type || \"unknown\"}\\``);\n }\n\n if (port.range) {\n parts.push(`**Range**: \\`[${port.range[0]}, ${port.range[1]}]\\``);\n }\n\n if (port.defaultValue !== undefined) {\n parts.push(`**Default**: \\`${port.defaultValue}\\``);\n }\n }\n }\n return parts.join(\"\\n\\n\");\n }, [node, portsDescription]);\n\n const combinedInfo = (info || \"\") + \"\\n\\n\" + portsInfo;\n\n return isOpen ? (\n <Modal onClose={onClose}>\n <NodeInfoWrapper\n dangerouslySetInnerHTML={{ __html: marked(combinedInfo || \"\") }}\n />\n </Modal>\n ) : null;\n};\n\nexport default NodeInfoModal;\n","import { FaQuestion } from \"react-icons/fa\";\nimport { ControlButton } from \"reactflow\";\nimport useStore from \"../../store\";\nimport HelpModal from './HelpModal';\n\n\nconst HelpButton = () => {\n const toggleHelp = useStore((store) => store.toggleHelp);\n\n return (\n <>\n <ControlButton onClick={toggleHelp}>\n <FaQuestion />\n </ControlButton>\n </>\n );\n};\n\nexport { HelpModal, HelpButton };\n\n","import { withTheme } from \"@emotion/react\";\nimport styled from \"@emotion/styled\";\n// @ts-ignore\nimport { marked } from \"marked\";\nimport useStore from \"../../store\";\nimport { Theme } from \"../../theme\";\nimport Modal from \"../Modal\";\n\n//@ts-ignore\nimport HELP from \"bundle-text:./HELP.md\";\n\nconst MdPreview = withTheme(styled.div<{ theme: Theme }>`\n font-family: var(--leva-fonts-mono);\n font-size: 0.7rem;\n box-sizing: border-box;\n height: 100%;\n width: 100%;\n overflow: scroll;\n color: ${({ theme }) => theme.colors.whitePrimary};\n padding: 0 0.5rem;\n\n code {\n color: ${({ theme }) => theme.colors.accent3};\n filter: hue-rotate(180deg);\n }\n`);\n\nconst ModalContent = withTheme(styled.div<{ theme: Theme }>`\n padding: 1rem;\n height: 100%;\n width: 100%;\n box-sizing: border-box;\n overflow: hidden;\n`);\n\nconst HelpModal = () => {\n const isHelpShown = useStore((store) => store.isHelpShown);\n const toggleHelp = useStore((store) => store.toggleHelp);\n\n if (!isHelpShown) {\n return null;\n }\n\n return (\n <Modal\n onClose={() => {\n toggleHelp();\n }}\n >\n <ModalContent>\n <MdPreview\n dangerouslySetInnerHTML={{ __html: marked(HELP) }}\n onWheelCapture={(event) => event.stopPropagation()}\n ></MdPreview>\n </ModalContent>\n </Modal>\n );\n};\n\nexport default HelpModal;\n","module.exports = \"05630c010f8da328\";","import styled from \"@emotion/styled\";\nimport { useState } from \"react\";\nimport { FaVolumeOff as IconUnmute } from \"react-icons/fa\";\nimport useStore from \"../store\";\nimport useTheme from \"../hooks/useTheme\";\nimport { Theme } from \"../theme\";\n\n\nconst Layout = styled.div<{ theme: Theme }>`\n position: fixed;\n z-index: ${({ theme }) => theme.zIndex.resumeContextLayout};\n width: 100%;\n height: 100%;\n top: 0;\n left: 0;\n background: rgb(24 28 32 / 90%);\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: center;\n color: ${({ theme }) => theme.colors.whitePrimary};\n cursor: pointer;\n`;\n\nconst Row = styled.div`\n display: flex;\n width: 100%;\n align-items: center;\n justify-content: center;\n`;\n\nconst Message = styled.div<{ theme: Theme }>`\n font-family: var(--leva-fonts-mono);\n font-size: 2rem;\n`;\n\nconst Icon = styled(IconUnmute)`\n width: 7rem;\n height: 7rem;\n`;\n\nconst ResumeContext = () => {\n const theme = useTheme();\n const patch = useStore(({ patch }) => patch);\n const audioContext = patch.audioContext;\n const [isContextResumed, setIsContextResumed] = useState<boolean>(\n audioContext.state === \"running\",\n );\n\n if (isContextResumed) {\n return null;\n }\n\n return (\n <Layout\n theme={theme}\n onClick={() => {\n audioContext.resume();\n setIsContextResumed(true);\n }}\n >\n <Row>\n <Message theme={theme}>Click anywhere to resume audio context</Message>\n </Row>\n <Row>\n <Icon />\n </Row>\n </Layout>\n );\n};\n\nexport default ResumeContext;\n","import { FaMap, FaRegMap } from \"react-icons/fa\";\nimport { ControlButton } from \"reactflow\";\nimport useStore from \"../store\";\n\nconst ToggleMinimap = () => {\n const setConfig = useStore(({ setConfig }) => setConfig);\n const { showMinimap } = useStore(({ config }) => config);\n\n return (\n <ControlButton onClick={() => setConfig({ showMinimap: !showMinimap })}>\n {showMinimap ? <FaMap /> : <FaRegMap />}\n </ControlButton>\n );\n};\n\nexport default ToggleMinimap;\n","import { useEffect, useMemo } from \"react\";\nimport { EdgeProps, getBezierPath, getConnectedEdges } from \"reactflow\";\nimport useTheme from \"../hooks/useTheme\";\nimport useStore from \"../store\";\n\nconst Wire = ({\n id,\n sourceX,\n sourceY,\n targetX,\n targetY,\n sourcePosition,\n targetPosition,\n style = {},\n data,\n markerStart,\n markerEnd,\n source,\n target,\n sourceHandleId,\n targetHandleId,\n selected,\n}: EdgeProps) => {\n const theme = useTheme();\n const getNode = useStore(({ getNode }) => getNode);\n const sourceNode = getNode(source);\n const targetNode = getNode(target);\n const isConnectedToSelected = sourceNode?.selected || targetNode?.selected;\n useEffect(() => {\n if (!sourceHandleId || !targetHandleId) {\n return;\n }\n console.log(`connected ${source} to ${target}`);\n return () => {\n console.log(`disconnected ${source} from ${target}`);\n };\n }, [source, sourceHandleId, target, targetHandleId]);\n\n const [edgePath] = getBezierPath({\n targetX,\n targetY,\n targetPosition,\n sourceX,\n sourceY,\n sourcePosition,\n });\n\n return (\n <>\n <path\n id={id}\n style={{\n ...style,\n stroke: selected\n ? theme.colors.accent2\n : isConnectedToSelected\n ? theme.colors.highlight3\n : theme.colors.highlight2,\n }}\n className=\"react-flow__edge-path Wire\"\n d={edgePath}\n markerEnd={markerEnd}\n />\n <path\n style={{\n ...style,\n strokeWidth: 8,\n color: \"transparent\",\n opacity: 0,\n cursor: \"pointer\",\n }}\n d={edgePath}\n markerEnd={markerEnd}\n />\n </>\n );\n};\n\nexport default Wire;\n","import Checker, { CheckerItem } from \"./Checker\";\nimport styled from \"@emotion/styled\";\nimport { type Theme, useTheme } from \"../../\";\n\nconst RadioGroupWrapper = styled.div<{ theme: Theme }>`\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n font-family: var(--leva-fonts-mono);\n font-size: 0.7rem;\n color: ${({ theme }) => theme.colors.highlight2};\n padding: 0.5rem;\n`;\n\nexport const RadioGroup = ({\n options,\n value,\n onChange,\n}: {\n options: Array<CheckerItem>;\n value: CheckerItem[\"value\"];\n onChange: (value: CheckerItem[\"value\"]) => void;\n}) => {\n const theme = useTheme();\n return (\n <RadioGroupWrapper theme={theme}>\n {options.map(({ value: optionValue, label, subtitle }, index) => (\n <Checker\n key={index}\n value={value}\n type=\"radio\"\n label={label}\n subtitle={subtitle}\n onChange={() => onChange(optionValue)}\n checked={optionValue === value}\n />\n ))}\n </RadioGroupWrapper>\n );\n};\n\nexport default RadioGroup;\n","import { withTheme } from \"@emotion/react\";\nimport styled from \"@emotion/styled\";\nimport { HTMLProps } from \"react\";\nimport { type Theme } from \"../../\";\n\nexport const InputWrapper = styled.div`\n display: flex;\n position: relative;\n`;\n\nexport const InputInner = withTheme(styled.input<{ theme: Theme }>`\n padding-right: 2rem;\n padding-left: 0.3rem;\n padding-top: 0;\n padding-bottom: 0;\n width: 100%;\n appearance: textfield;\n font-size: inherit;\n background: none;\n border: none;\n color: var(--leva-colors-highlight1);\n font-family: var(--leva-fonts-mono);\n cursor: inherit;\n text-overflow: ellipsis;\n outline: none;\n appearance: textfield;\n cursor: auto;\n background-color: var(--leva-colors-elevation3);\n border-radius: 0.2rem;\n height: 1.5rem;\n color: var(--leva-colors-highlight2);\n\n &:focus,\n &:hover {\n box-shadow: 0 0 0 var(--leva-borderWidths-focus) var(--leva-colors-accent2);\n color: ${({ theme }) => theme.colors.whitePrimary};\n }\n &::-webkit-inner-spin-button,\n &::-webkit-outer-spin-button {\n -webkit-appearance: none;\n margin-right: 1rem;\n }\n`);\n\nexport interface InputProps {\n value?: string;\n placeholder?: string;\n onChange?: (value: string) => void;\n type?: string;\n inputProps?: Omit<HTMLProps<HTMLInputElement>, \"as\">;\n}\n\nexport const Input = ({\n type,\n value,\n placeholder,\n onChange = () => {},\n inputProps,\n ...props\n}: InputProps) => {\n return (\n <InputWrapper {...props}>\n <InputInner\n type={type}\n value={value}\n placeholder={placeholder}\n onKeyDownCapture={(event) => {\n event.stopPropagation();\n }}\n onChange={(event) => {\n onChange(event.target.value);\n }}\n {...inputProps}\n />\n </InputWrapper>\n );\n};\n\nexport default Input;\n","import styled from \"@emotion/styled\";\nimport { withTheme } from \"@emotion/react\";\nimport {\n KeyboardEventHandler,\n useCallback,\n useState,\n useRef,\n useEffect,\n} from \"react\";\nimport { FaRegArrowAltCircleRight as SetUrlIcon } from \"react-icons/fa\";\nimport type { Theme } from \"@web-noise/core\";\nimport { InputInner, InputWrapper } from \"./Input\";\n\nconst InputButton = withTheme(styled.button<{ theme: Theme }>`\n position: absolute;\n right: 0;\n height: 100%;\n outline: none;\n background: none;\n border: none;\n color: ${({ theme }) => theme.colors.highlight1};\n cursor: pointer;\n display: flex;\n align-items: center;\n z-index: 2;\n &:hover {\n color: ${({ theme }) => theme.colors.highlight2};\n }\n &:active {\n color: ${({ theme }) => theme.colors.highlight3};\n }\n`);\n\nconst DropdownContainer = styled.div`\n position: relative;\n width: 100%;\n`;\n\nconst DropdownList = withTheme(styled.div<{ theme: Theme; isOpen: boolean }>`\n position: absolute;\n top: calc(100% + 2px);\n left: 0;\n right: 0;\n max-height: 200px;\n overflow-y: auto;\n background-color: ${({ theme }) => theme.colors.elevation2};\n border: 1px solid ${({ theme }) => theme.colors.elevation3};\n border-radius: 0.2rem;\n box-shadow: 0 4px 6px rgba(0, 0, 0, 0.3);\n z-index: 1000;\n display: ${({ isOpen }) => (isOpen ? \"block\" : \"none\")};\n\n &::-webkit-scrollbar {\n width: 8px;\n }\n\n &::-webkit-scrollbar-track {\n background: ${({ theme }) => theme.colors.elevation1};\n }\n\n &::-webkit-scrollbar-thumb {\n background: ${({ theme }) => theme.colors.elevation3};\n border-radius: 4px;\n }\n\n &::-webkit-scrollbar-thumb:hover {\n background: ${({ theme }) => theme.colors.highlight1};\n }\n`);\n\nconst DropdownItem = withTheme(styled.div<{\n theme: Theme;\n isHighlighted: boolean;\n}>`\n padding: 0.4rem 0.5rem;\n cursor: pointer;\n color: ${({ theme }) => theme.colors.highlight1};\n background-color: ${({ theme, isHighlighted }) =>\n isHighlighted ? theme.colors.elevation3 : \"transparent\"};\n font-family: var(--leva-fonts-mono);\n font-size: 0.9em;\n\n &:hover {\n background-color: ${({ theme }) => theme.colors.elevation3};\n color: ${({ theme }) => theme.colors.highlight2};\n }\n`);\n\nconst DropdownItemValue = styled.div`\n font-size: 0.85em;\n opacity: 0.7;\n margin-top: 2px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n`;\n\nconst DropdownItemLabel = styled.div`\n font-size: 1em;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n`;\n\ninterface InputOption {\n value: string;\n label?: string;\n}\n\ninterface SubmitInputProps {\n value?: string;\n placeholder?: string;\n onSubmit?: (value: string) => void;\n options?: Array<InputOption>;\n}\n\nexport const DropdownInput = ({\n value = \"\",\n placeholder = \"\",\n onSubmit = () => {},\n options = [],\n ...props\n}: SubmitInputProps) => {\n const [currentValue, setCurrentValue] = useState<string>(value);\n const [isOpen, setIsOpen] = useState(false);\n const [highlightedIndex, setHighlightedIndex] = useState(-1);\n const inputRef = useRef<HTMLInputElement>(null);\n const dropdownRef = useRef<HTMLDivElement>(null);\n\n const filteredOptions = options.filter(\n (option) =>\n currentValue === \"\" ||\n option.value.toLowerCase().includes(currentValue.toLowerCase()) ||\n option.label?.toLowerCase().includes(currentValue.toLowerCase()),\n );\n\n const applyCurrentValue = useCallback(() => {\n onSubmit(currentValue);\n setIsOpen(false);\n setHighlightedIndex(-1);\n }, [currentValue, onSubmit]);\n\n const selectOption = useCallback(\n (option: InputOption) => {\n setCurrentValue(option.value);\n onSubmit(option.value);\n setIsOpen(false);\n setHighlightedIndex(-1);\n },\n [onSubmit],\n );\n\n const handleKeyDown: KeyboardEventHandler = useCallback(\n (event) => {\n switch (event.key) {\n case \"Escape\":\n setIsOpen(false);\n setHighlightedIndex(-1);\n break;\n case \"Enter\":\n if (\n isOpen &&\n highlightedIndex >= 0 &&\n filteredOptions[highlightedIndex]\n ) {\n event.preventDefault();\n selectOption(filteredOptions[highlightedIndex]);\n } else {\n applyCurrentValue();\n }\n break;\n case \"ArrowDown\":\n event.preventDefault();\n if (!isOpen) {\n setIsOpen(true);\n setHighlightedIndex(0);\n } else {\n setHighlightedIndex((prev) =>\n prev < filteredOptions.length - 1 ? prev + 1 : prev,\n );\n }\n break;\n case \"ArrowUp\":\n event.preventDefault();\n if (isOpen) {\n setHighlightedIndex((prev) => (prev > 0 ? prev - 1 : prev));\n }\n break;\n }\n },\n [\n applyCurrentValue,\n isOpen,\n highlightedIndex,\n filteredOptions,\n selectOption,\n ],\n );\n\n const handleInputChange = (value: string) => {\n setCurrentValue(value);\n setIsOpen(true);\n setHighlightedIndex(-1);\n };\n\n const handleFocus = () => {\n if (options.length > 0) {\n setIsOpen(true);\n }\n };\n\n const handleBlur = () => {\n // Use setTimeout to allow click events on dropdown items to fire first\n setTimeout(() => {\n setIsOpen(false);\n setHighlightedIndex(-1);\n }, 200);\n };\n\n // Handle clicking outside\n useEffect(() => {\n const handleClickOutside = (event: MouseEvent) => {\n if (\n dropdownRef.current &&\n !dropdownRef.current.contains(event.target as Node) &&\n inputRef.current &&\n !inputRef.current.contains(event.target as Node)\n ) {\n setIsOpen(false);\n setHighlightedIndex(-1);\n }\n };\n\n document.addEventListener(\"mousedown\", handleClickOutside);\n return () => {\n document.removeEventListener(\"mousedown\", handleClickOutside);\n };\n }, []);\n\n // Scroll highlighted item into view\n useEffect(() => {\n if (highlightedIndex >= 0 && dropdownRef.current) {\n const highlightedElement = dropdownRef.current.children[\n highlightedIndex\n ] as HTMLElement;\n if (highlightedElement) {\n highlightedElement.scrollIntoView({\n block: \"nearest\",\n behavior: \"smooth\",\n });\n }\n }\n }, [highlightedIndex]);\n\n return (\n <DropdownContainer>\n <InputWrapper>\n <InputInner\n {...props}\n ref={inputRef}\n value={currentValue}\n placeholder={placeholder}\n onKeyDown={handleKeyDown}\n onChange={(event) => handleInputChange(event.target.value)}\n onFocus={handleFocus}\n onBlur={handleBlur}\n autoComplete=\"off\"\n />\n\n <InputButton onClick={applyCurrentValue}>\n <SetUrlIcon />\n </InputButton>\n </InputWrapper>\n\n {options.length > 0 && (\n <DropdownList\n ref={dropdownRef}\n isOpen={isOpen && filteredOptions.length > 0}\n >\n {filteredOptions.map((option, index) => (\n <DropdownItem\n key={option.value + index}\n isHighlighted={index === highlightedIndex}\n onClick={() => selectOption(option)}\n onMouseEnter={() => setHighlightedIndex(index)}\n >\n <DropdownItemLabel>\n {option.label || option.value}\n </DropdownItemLabel>\n {option.value && (\n <DropdownItemValue>{option.value}</DropdownItemValue>\n )}\n </DropdownItem>\n ))}\n </DropdownList>\n )}\n </DropdownContainer>\n );\n};\n\nexport default DropdownInput;\n","import styled from \"@emotion/styled\";\nimport Input, { InputProps, InputInner, InputWrapper } from \"./Input\";\n\nconst StyledInputWrapper = styled(InputWrapper)`\n gap: 0.5rem;\n`;\n\nconst StyledInputInner = styled(InputInner)`\n padding: 0;\n aspect-ratio: 1 / 1;\n width: auto;\n cursor: pointer;\n &::-webkit-color-swatch-wrapper {\n padding: 0;\n }\n &::-webkit-color-swatch {\n border-radius: 0.2rem;\n border: none;\n }\n`;\n\nexport interface ColorInputProps {\n value?: string;\n onChange?: (value: string) => void;\n}\n\nexport const ColorInput = ({\n value,\n onChange = () => {},\n ...props\n}: ColorInputProps) => {\n return (\n <StyledInputWrapper {...props}>\n <StyledInputInner\n type=\"color\"\n value={value}\n onChange={(event) => {\n onChange(event.target.value);\n }}\n />\n <InputInner\n value={value}\n onChange={(event) => {\n onChange(event.target.value);\n }}\n />\n </StyledInputWrapper>\n );\n};\n\nexport default ColorInput;\n","import styled from \"@emotion/styled\";\nimport { useEffect, useRef } from \"react\";\n// @ts-ignore\nimport { useThrottledCallback } from \"use-debounce\";\n\nconst SampleInput = styled.span`\n position: relative;\n &:after {\n content: \"↕\";\n position: absolute;\n top: -1px;\n right: 0;\n height: 100%;\n display: flex;\n align-items: center;\n font-size: 1.2em;\n color: var(--leva-colors-highlight1);\n }\n`;\n\nconst SampleInputInner = styled.input`\n width: 100%;\n appearance: textfield;\n font-size: inherit;\n background: none;\n border: none;\n text-align: right;\n color: var(--leva-colors-highlight1);\n font-family: var(--leva-fonts-mono);\n cursor: inherit;\n text-overflow: ellipsis;\n outline: none;\n appearance: textfield;\n cursor: auto;\n background-color: var(--leva-colors-elevation3);\n border-radius: 0.2rem;\n height: 1.5rem;\n color: var(--leva-colors-highlight2);\n\n &:focus,\n &:hover {\n box-shadow: 0 0 0 var(--leva-borderWidths-focus) var(--leva-colors-accent2);\n }\n &::-webkit-inner-spin-button,\n &::-webkit-outer-spin-button {\n -webkit-appearance: none;\n margin-right: 1rem;\n }\n`;\n\ninterface NumberInputProps {\n max?: number;\n min?: number;\n value?: number;\n step?: number;\n onChange?: (value: number) => void;\n placeholder?: string;\n}\n\nexport const NumberInput = ({\n max = Infinity,\n min = -Infinity,\n value,\n step = 1,\n onChange = () => {},\n placeholder,\n ...props\n}: NumberInputProps) => {\n const inputRef = useRef<HTMLInputElement>(null);\n\n const startChangedHandler = useThrottledCallback(\n (event: Pick<WheelEvent, \"deltaY\">) => {\n if (typeof value === \"undefined\") {\n return;\n }\n //@TODO: come up with more logical factor calculation\n const factor = max < 10 ? 5 : max / 100;\n const st = +(value + Math.round(event.deltaY / factor) * step).toFixed(2);\n if (st < min || st > max) {\n return;\n }\n onChange(st);\n },\n 100,\n );\n\n useEffect(() => {\n if (!inputRef.current) {\n return;\n }\n\n inputRef.current.addEventListener(\"wheel\", (event) => {\n event.preventDefault();\n event.stopPropagation();\n startChangedHandler(event);\n });\n\n inputRef.current.onchange = (event) => {\n const value = (event.target as HTMLInputElement).value;\n onChange(+value);\n };\n }, [inputRef.current, onChange]);\n\n useEffect(() => {\n if (typeof value === \"undefined\") {\n return;\n }\n inputRef.current && (inputRef.current.value = value.toString());\n }, [inputRef.current, value]);\n\n return (\n <SampleInput {...props}>\n <SampleInputInner\n ref={inputRef}\n type=\"number\"\n step={step}\n min={min}\n max={max}\n placeholder={placeholder}\n />\n </SampleInput>\n );\n};\n\nexport default NumberInput;\n","import styled from \"@emotion/styled\";\nimport { type Theme } from \"../theme\";\n\nexport const Button = styled.button<{ theme: Theme }>`\n display: flex;\n align-items: center;\n justify-content: center;\n outline: none;\n font-size: inherit;\n font-family: inherit;\n border: none;\n appearance: none;\n font-weight: var(--leva-fontWeights-button);\n height: var(--leva-sizes-rowHeight);\n border-radius: var(--leva-radii-sm);\n background-color: ${({ theme }) => theme.colors.elevation1};\n color: ${({ theme }) => theme.colors.highlight3};\n background-color: ${({ theme }) => theme.colors.accent2};\n cursor: pointer;\n font-family: var(--leva-fonts-mono);\n font-size: var(--leva-fontSizes-root);\n\n &:hover {\n box-shadow: inset 0 0 0 var(--leva-borderWidths-hover)\n ${({ theme }) => theme.colors.accent3};\n }\n\n &:active {\n box-shadow: inset 0 0 0 var(--leva-borderWidths-active)\n ${({ theme }) => theme.colors.accent3};\n background-color: ${({ theme }) => theme.colors.accent1};\n }\n`;\n\nexport default Button;\n","import { withTheme } from \"@emotion/react\";\nimport styled from \"@emotion/styled\";\nimport { Theme } from \"../theme\";\n\nconst SelectWrapper = withTheme(styled.div<{ theme: Theme }>`\n display: flex;\n align-items: center;\n position: relative;\n\n select {\n appearance: none;\n border: none;\n outline: none;\n width: 100%;\n font-weight: var(--leva-fontWeights-button);\n padding: 0.3rem 0.5rem;\n padding-right: 1rem;\n border-radius: var(--leva-radii-sm);\n background-color: ${({ theme }) => theme.colors.elevation1};\n color: ${({ theme }) => theme.colors.highlight3};\n cursor: pointer;\n font-family: var(--leva-fonts-mono);\n font-size: var(--leva-fontSizes-root);\n\n &:hover {\n box-shadow: inset 0 0 0 var(--leva-borderWidths-hover)\n ${({ theme }) => theme.colors.accent3};\n }\n\n &:active {\n box-shadow: inset 0 0 0 var(--leva-borderWidths-active)\n ${({ theme }) => theme.colors.accent3};\n background-color: ${({ theme }) => theme.colors.accent1};\n }\n }\n\n &::after {\n position: absolute;\n right: 0.3rem;\n content: \"\";\n width: 0.5em;\n height: 0.3em;\n background-color: ${({ theme }) => theme.colors.highlight3};\n clip-path: polygon(100% 0%, 0 0%, 50% 100%);\n }\n`);\n\ninterface SelectOption {\n value: string;\n label?: string;\n}\n\ninterface SelectProps {\n options: Array<SelectOption>;\n value?: SelectOption[\"value\"];\n placeholder?: string;\n onChange?: (value: SelectOption[\"value\"]) => void;\n}\n\nexport const Select = ({\n options,\n placeholder,\n value,\n onChange,\n ...props\n}: SelectProps) => {\n return (\n <SelectWrapper {...props}>\n <select\n value={value || \"\"}\n onChange={(event) => onChange?.(event.target.value)}\n >\n {placeholder && (\n <option value=\"\" disabled>\n {placeholder}\n </option>\n )}\n {options.map(({ value, label }) => (\n <option key={value + label} value={value}>\n {label}\n </option>\n ))}\n </select>\n </SelectWrapper>\n );\n};\n\nexport default Select;\n","import styled from \"@emotion/styled\";\nimport RCSlider from \"rc-slider\";\nimport \"rc-slider/assets/index.css\";\nimport { type Theme } from \"../theme\";\n\nexport const Slider = styled(RCSlider)<{ theme: Theme; color?: string }>`\n padding: 0;\n cursor: pointer;\n position: relative;\n\n &:hover {\n filter: brightness(125%);\n }\n\n .rc-slider-dot {\n border-radius: 0;\n box-shadow: none;\n margin: 0;\n border: none;\n background: ${({ theme }) => theme.colors.highlight2};\n }\n\n &.rc-slider-horizontal .rc-slider-dot {\n width: 1px;\n height: 0.25rem;\n bottom: -6px;\n }\n\n &.rc-slider-vertical .rc-slider-dot {\n width: 0.25rem;\n height: 1px;\n left: 3px;\n }\n\n .rc-slider-rail {\n background: ${({ theme }) => theme.colors.elevation1};\n }\n\n .rc-slider-track {\n background: ${({ theme, color }) => color || theme.colors.accent2};\n }\n\n .rc-slider-handle {\n border-radius: 0.125rem;\n background: ${({ theme, color }) => color || theme.colors.accent2};\n opacity: 1;\n cursor: pointer;\n border: none;\n &:hover {\n filter: brightness(110%);\n }\n }\n\n .rc-slider-handle,\n .rc-slider-handle.rc-slider-handle-dragging {\n box-shadow: 0 0 0 2px ${({ theme }) => theme.colors.elevation2};\n }\n\n &:before {\n content: \"\";\n position: absolute;\n background: transparent;\n }\n\n &.rc-slider-horizontal {\n height: 2px;\n\n .rc-slider-rail,\n .rc-slider-track,\n .rc-slider-step {\n height: 100%;\n }\n\n .rc-slider-handle {\n width: 0.5rem;\n height: 1rem;\n bottom: -7px;\n }\n\n .rc-slider-handle-dragging {\n cursor: ew-resize;\n }\n\n &:before {\n width: 100%;\n height: 1rem;\n top: -7px;\n }\n }\n\n &.rc-slider-vertical {\n width: 2px;\n\n .rc-slider-rail,\n .rc-slider-track,\n .rc-slider-step {\n width: 100%;\n }\n\n .rc-slider-track {\n left: 0;\n }\n\n .rc-slider-handle {\n width: 1rem;\n height: 0.5rem;\n right: -7px;\n }\n\n .rc-slider-handle-dragging {\n cursor: ns-resize;\n }\n\n &:before {\n height: 100%;\n width: 1rem;\n right: -7px;\n }\n }\n\n &.rc-slider-horizontal .rc-slider-mark {\n top: 1rem;\n }\n\n &.rc-slider-vertical .rc-slider-mark {\n left: 1rem;\n }\n\n .rc-slider-mark-text {\n font-size: 0.4rem;\n }\n`;\n\nexport default Slider;\n","// @ts-nocheck\nimport { useCallback, useEffect, useRef, useState } from \"react\";\n//@ts-ignore\nimport { CanvasSpliner } from \"CanvasSpliner\";\nimport styled from \"@emotion/styled\";\nimport { theme } from \"../../\";\n\nexport interface SplinePoint {\n x: number;\n y: number;\n}\n\nexport type SplineType = \"monotonic\" | \"natural\";\n\nexport type SplinePoints = Array<SplinePoint>;\n\nclass Spliner extends CanvasSpliner {\n _updateMousePosition(evt: MouseEvent) {\n const rect = this._canvas?.getBoundingClientRect();\n\n const scaleX = this._canvas.width / rect.width;\n const scaleY = this._canvas.height / rect.height;\n\n this._mouse = {\n x: (evt.clientX - rect.left) * scaleX,\n y: this._height - (evt.clientY - rect.top) * scaleY,\n };\n }\n\n getPoints() {\n const xFactor = 1 / this._width;\n const yFactor = 1 / this._height;\n return this._pointCollection._points.map(({ x, y }) => ({\n x: x * xFactor,\n y: y * yFactor,\n }));\n }\n\n removeAll() {\n const length = this._pointCollection.getNumberOfPoints();\n for (let i = length; i > 0; i--) {\n this._pointCollection.remove(i - 1);\n }\n }\n\n update(points: Array<{ x: number; y: number }>) {\n this.removeAll();\n\n const xFactor = this._width;\n const yFactor = this._height;\n points.forEach(({ x, y }) => {\n this._pointCollection.add({ x: x * xFactor, y: y * yFactor });\n });\n\n this.draw();\n }\n\n off(eventName: string, handler: (csObj: Spliner) => void) {\n // @TODO: implement unsibscribe\n }\n}\n\nconst WaveShaperInner = styled.div`\n height: 100%;\n width: 100%;\n position: relative;\n canvas {\n border: none !important;\n position: absolute;\n left: 0;\n right: 0;\n height: 100%;\n width: 100%;\n }\n`;\n\nexport interface SplineEditorProps {\n points: Array<{ x: number; y: number }>;\n type?: SplineType;\n textColor?: string;\n curveColor?: string;\n gridStep?: number;\n gridColor?: string;\n controlPointRadius?: number;\n controlPointColor?: string;\n onChange?: (points: SplinePoints) => void;\n onMove?: (points: SplinePoints) => void;\n}\n\nexport const SplineEditor = ({\n onChange,\n onMove,\n points,\n type = \"monotonic\",\n textColor = \"red\",\n curveColor = theme.colors.accent2,\n gridStep = 0.25,\n gridColor = theme.colors.elevation2,\n controlPointRadius = 14,\n controlPointColor = theme.colors.vivid1,\n}: SplineEditorProps) => {\n const ref = useRef<HTMLDivElement | null>(null);\n const [spliner, setSpliner] = useState<Spliner>();\n\n const handlePointsChange = useCallback(\n (csObj: Spliner) => {\n const points: SplinePoints = csObj.getPoints();\n onChange?.(points);\n },\n [onChange],\n );\n\n const handlePointMove = useCallback(\n (csObj: Spliner) => {\n const points: SplinePoints = csObj.getPoints();\n onMove?.(points);\n },\n [onMove],\n );\n\n useEffect(() => spliner?.update(points), [spliner, points]);\n\n useEffect(() => spliner?.setSplineType(type), [spliner, type]);\n useEffect(() => spliner?.setGridStep(gridStep), [spliner, gridStep]);\n useEffect(() => spliner?.setGridColor(gridColor), [spliner, gridColor]);\n useEffect(\n () => spliner?.setControlPointRadius(controlPointRadius),\n [spliner, controlPointRadius],\n );\n useEffect(() => spliner?.setTextColor(textColor), [spliner, textColor]);\n useEffect(() => {\n spliner?.setCurveColor(\"idle\", curveColor);\n // spliner?.setCurveColor(\"moving\", \"yellow\");\n }, [spliner, curveColor]);\n useEffect(() => {\n spliner?.setControlPointColor(\"idle\", controlPointColor);\n // spliner?.setControlPointColor(\"hovered\", \"blue\");\n // spliner?.setControlPointColor(\"grabbed\", \"black\");\n }, [spliner, controlPointColor]);\n\n useEffect(() => {\n if (!spliner) {\n return;\n }\n\n spliner.setCurveThickness(4);\n\n spliner.on(\"movePoint\", handlePointMove);\n spliner.on(\"releasePoint\", handlePointsChange);\n spliner.on(\"pointAdded\", handlePointsChange);\n spliner.on(\"pointRemoved\", handlePointsChange);\n\n spliner.draw();\n\n return () => {\n spliner.off(\"movePoint\", handlePointMove);\n spliner.off(\"releasePoint\", handlePointsChange);\n spliner.off(\"pointAdded\", handlePointsChange);\n spliner.off(\"pointRemoved\", handlePointsChange);\n };\n }, [spliner, handlePointsChange, handlePointMove]);\n\n useEffect(() => {\n if (!ref.current) {\n return;\n }\n\n const cs = new Spliner(ref.current, 1024, 1024);\n setSpliner(cs);\n }, [ref]);\n\n return <WaveShaperInner ref={ref} />;\n};\n\nexport default SplineEditor;\n","import styled from \"@emotion/styled\";\nimport { Theme } from \"../theme\";\n\nexport const ConfigRowLabel = styled.div``;\n\nexport const ConfigRowControl = styled.div<{ theme: Theme }>`\n font-family: var(--leva-fonts-mono);\n font-size: 0.7rem;\n color: ${({ theme }) => theme.colors.whitePrimary};\n`;\n\nexport const ConfigRowSeparator = styled.div<{ theme: Theme }>`\n border-bottom: 1px solid ${({ theme }) => theme.colors.elevation1};\n`;\n\nexport const ConfigRow = styled.div<{ theme: Theme; oneLineLabels?: boolean }>`\n padding: 0.2rem 0.4rem;\n font-size: 0.7rem;\n color: ${({ theme }) => theme.colors.highlight2};\n position: relative;\n display: grid;\n align-items: center;\n grid-template-rows: minmax(1.5rem, max-content);\n grid-template-columns: ${({ oneLineLabels }) =>\n oneLineLabels ? \"1fr\" : \"auto 10rem\"};\n row-gap: 0.1rem;\n column-gap: 0.4rem;\n`;\n\nexport const ConfigPanel = styled.div<{ theme: Theme }>`\n display: flex;\n flex-direction: column;\n gap: 0.4rem;\n background: ${({ theme }) => theme.colors.elevation2};\n padding: 0.4rem 0.1rem;\n`;\n\nexport const ConfigRowInner = styled.div<{ theme: Theme }>``;\n"],"names":["config","jsx","$qQ8Y1$jsx","jsxs","$qQ8Y1$jsxs","$qQ8Y1$emotionstyled","useEffect","$qQ8Y1$useEffect","useState","$qQ8Y1$useState","version","$qQ8Y1$version","useCallback","$qQ8Y1$useCallback","useRef","$qQ8Y1$useRef","createPortal","$qQ8Y1$createPortal","MdClose","$qQ8Y1$MdClose","MdSettings","$qQ8Y1$MdSettings","MdInfoOutline","$qQ8Y1$MdInfoOutline","useTheme","$qQ8Y1$useTheme","withTheme","$qQ8Y1$withTheme","FaPlus","$qQ8Y1$FaPlus","getConnectedEdges","$qQ8Y1$getConnectedEdges","addEdge","$qQ8Y1$addEdge","applyNodeChanges","$qQ8Y1$applyNodeChanges","applyEdgeChanges","$qQ8Y1$applyEdgeChanges","Handle","$qQ8Y1$Handle","create","$qQ8Y1$create","setAudioNodeTypes","$qQ8Y1$setAudioNodeTypes","createPatch","$qQ8Y1$createPatch","reverse","$qQ8Y1$reverse","patch","$qQ8Y1$patch","$qQ8Y1$create1","injectGlobal","$qQ8Y1$injectGlobal","Item","$qQ8Y1$Item","Menu","$qQ8Y1$Menu","FaFileUpload","$qQ8Y1$FaFileUpload","FaVolumeOff","$qQ8Y1$FaVolumeOff","FaRegArrowAltCircleRight","$qQ8Y1$FaRegArrowAltCircleRight","useThrottledCallback","$qQ8Y1$useThrottledCallback","$qQ8Y1$rcslider","CanvasSpliner","$qQ8Y1$CanvasSpliner","$parcel$export","e","n","v","s","Object","defineProperty","get","set","enumerable","configurable","PortType","$cfbf5bba42d581f6$export$b0b7b95ee465c83c","$d6863d1593a90046$exports","$6c9029bae1fda307$export$2b77a92f1a5ad772","$22dd0cb4a70b40fd$export$8ecd240bc8faaeeb","$03fc2a9d056cdbb9$export$a98f0dcb43a68a25","$f2626dfcf20c9281$export$f5b8910cec6cf069","$9f4596934c8f0841$export$7a40489edcbfb3a1","$e1bb97faa82daf8d$export$5a1d7ca0a925d9c2","$9746117513cdf0c6$export$6bf0cd3a219bbade","$fd88f4b57ca7d92f$export$353f5b6fc5456de1","$6af7bd545fe585cb$export$ef9b1a59e592288f","$b36c9ac3a0f9fc74$export$472062a354075cee","$03443e7f1f47da42$export$2bf7c2638a145e5c","$9d9e44a3523295ca$export$555ece15b74b7abc","$9d9e44a3523295ca$export$ef9ca7b440c0032c","$9d9e44a3523295ca$export$bd1dc14d6df7044e","$9d9e44a3523295ca$export$d56900fc3755b916","$9d9e44a3523295ca$export$aac584ace4a7b830","$9d9e44a3523295ca$export$edaba703bd8b8dfa","$6c9029bae1fda307$var$ModalOuter","div","theme","zIndex","modal","colors","elevation3","$6c9029bae1fda307$var$ModalInner","elevation2","elevation1","$6c9029bae1fda307$var$ModalCloser","children","onClose","props","escHandler","event","key","document","addEventListener","removeEventListener","onClick","stopPropagation","body","$cfbf5bba42d581f6$export$956b3cf15d7c363","$cfbf5bba42d581f6$export$21d634b1d5d9bee3","$cde61d7f4dc8a447$var$cloneObject","input","JSON","parse","stringify","$adad5cc6758973b9$export$e364ea0c1dfb25e5","left","right","setLeft","Set","map","item","id","setRight","added","filter","has","removed","args","nodes","edges","onNodesChange","changes","node","dragHandle","onEdgesChange","onConnect","connection","addNode","concat","setNodes","setEdges","setNodesAndEdges","getNodesAndEdges","clearElements","getNode","find","updateNodeData","data","nodeTypes","setNodeTypes","history","maxHistoryLength","buffer","pointer","skipCollect","push","newBuffer","slice","Math","max","min","back","controlPanel","patchData","reversedPatchData","forward","clear","nodesState","project","files","setProject","currentFileIndex","getProject","pullEditorChanges","getEditorState","updateFileContent","currentFile","file","type","syncEditorWithCurrentFile","setEditorState","console","log","setCurrentFileIndex","newFileIndex","index","f","i","updateFileName","fileName","name","addFile","deleteFile","fileIndex","_","setGraph","createNodes","createEdges","activeNodes","activeEdges","clearGraph","createNode","Promise","all","nodeData","nodesConfiguration","Error","defaultConfig","removeNode","removeNodes","currentNodes","onNodesDelete","removeEdges","removeNodesFromControlPanel","parentNodeIds","resultingNodes","parentNode","includes","nodeIds","currentEdges","onEdgesDelete","edgeIds","newEdges","plugins","setPlugins","nodesConf","reduce","acc","plugin","components","subAcc","keys","audioNode","showMinimap","setConfig","viewport","r","setTimeout","isHelpShown","toggleHelp","showHelp","copyBuffer","copy","elements","copySelectedItems","selected","length","pasteBuffer","x","y","nodesToCopy","edgesToCopy","topLeftNode","position","xDelta","yDelta","newNodes","mapping","random","newNodeId","Date","floor","toString","edge","source","target","replace","getControlPanelNode","controlPanelNode","error","show","size","width","height","showControlPanel","hideControlPanel","addNodeToControlPanel","newNode","removeNodeFromControlPanel","setControlPanelNodes","setControlPanelSize","zoom","setViewport","api","timer","jsondiffpatchInstance","oldState","collectChanges","propertyFilter","context","parent","childName","state","prevState","clearTimeout","diff","subscribe","promises","currentState","storeChanges","newState","nodeChanges","edgeChanges","removedEdges","removedNodes","promise","registerAudioNodes","add","delete","values","registerAudioConnections","unregisterAudioConnections","unregisterAudioNodes","whitePrimary","ul","accent2","highlight2","$8841b806cf9536cc$export$7129a6e2db131a76","span","isActive","highlight1","highlight3","label","accent3","accent1","$ff9a1ac4f0decadf$var$NodeWrapper","$ff9a1ac4f0decadf$var$Section","$ff9a1ac4f0decadf$export$1bdb8f2d1fe25c22","$ff9a1ac4f0decadf$var$portColors","Audio","Gate","Number","Any","$ff9a1ac4f0decadf$var$StyledHandle","shouldForwardProp","prop","portType","Array","isArray","join","$4d70bd882ba90559$export$86de09faaa70680d","$4d70bd882ba90559$export$548ca3bae446ddc2","className","$4d70bd882ba90559$export$9fb15e3cc717240","$4d70bd882ba90559$export$be58b4326e23250f","resumeContextLayout","active","$22dd0cb4a70b40fd$var$CheckerBox","$22dd0cb4a70b40fd$var$CheckerLabel","$22dd0cb4a70b40fd$var$CheckerSubtitle","$22dd0cb4a70b40fd$var$CheckedInner","subtitle","onChange","checked","$03fc2a9d056cdbb9$var$RadioGroupWrapper","options","value","optionValue","$f2626dfcf20c9281$export$fb9f58ebe9de6283","$f2626dfcf20c9281$export$42e20bb2ce90003b","placeholder","inputProps","onKeyDownCapture","$9f4596934c8f0841$var$InputButton","button","$9f4596934c8f0841$var$DropdownContainer","$9f4596934c8f0841$var$DropdownList","isOpen","$9f4596934c8f0841$var$DropdownItem","isHighlighted","$9f4596934c8f0841$var$DropdownItemValue","$9f4596934c8f0841$var$DropdownItemLabel","onSubmit","currentValue","setCurrentValue","setIsOpen","highlightedIndex","setHighlightedIndex","inputRef","dropdownRef","filteredOptions","option","toLowerCase","applyCurrentValue","selectOption","handleKeyDown","preventDefault","prev","handleClickOutside","current","contains","highlightedElement","scrollIntoView","block","behavior","ref","onKeyDown","onFocus","onBlur","autoComplete","onMouseEnter","$e1bb97faa82daf8d$var$StyledInputWrapper","$e1bb97faa82daf8d$var$StyledInputInner","$9746117513cdf0c6$var$SampleInput","$9746117513cdf0c6$var$SampleInputInner","Infinity","step","startChangedHandler","factor","st","round","deltaY","toFixed","onchange","$6af7bd545fe585cb$var$SelectWrapper","disabled","color","$03443e7f1f47da42$var$Spliner","_updateMousePosition","evt","rect","_canvas","getBoundingClientRect","scaleX","scaleY","_mouse","clientX","_height","clientY","top","getPoints","xFactor","_width","yFactor","_pointCollection","_points","removeAll","getNumberOfPoints","remove","update","points","forEach","draw","off","eventName","handler","$03443e7f1f47da42$var$WaveShaperInner","onMove","textColor","curveColor","gridStep","gridColor","controlPointRadius","controlPointColor","spliner","setSpliner","handlePointsChange","csObj","handlePointMove","setSplineType","setGridStep","setGridColor","setControlPointRadius","setTextColor","setCurveColor","setControlPointColor","setCurveThickness","on","oneLineLabels","Modal","Checker","RadioGroup","Input","DropdownInput","ColorInput","NumberInput","Button","Select","Slider","SplineEditor","ConfigRowLabel","ConfigRowControl","ConfigRowSeparator","ConfigRow","ConfigPanel","ConfigRowInner"],"version":3,"file":"components.js.map"}
1
+ {"mappings":"IY+LG,EC3KA,C,Q,O,C,C,Q,C,K,mB,A,Q,M,iB,A,Q,a,C,C,Y,C,C,W,C,C,e,C,C,U,C,K,O,A,Q,gB,C,K,W,A,Q,W,C,C,c,C,C,iB,C,K,gB,A,Q,Y,C,C,a,C,K,gB,A,O,Q,A,Q,U,C,K,iB,A,O,kB,A,Q,qB,C,C,W,C,C,oB,C,C,oB,C,C,U,C,K,W,A,Q,U,C,K,S,A,Q,qB,C,C,e,C,K,kB,A,Q,W,C,C,S,C,C,U,C,K,e,A,Q,gB,C,K,c,A,O,0B,A,Q,Q,C,C,Q,C,K,iB,A,O,yC,A,O,kB,A,O,Y,A,O,iB,A,Q,gB,C,C,e,C,C,4B,C,K,gB,A,O,c,A,O,mB,A,O,kC,A,O,gB,A,O,gB,A,O,qB,A,O,oC,A,O,Q,A,Q,wB,C,K,c,A,Q,M,W,A,O,4B,A,Q,iB,C,K,e,C,S,E,C,C,C,C,C,C,C,E,O,c,C,E,E,C,I,E,I,E,W,C,E,a,C,C,E,C,IJZS,EAAA,E,E,C,E,E,E,Q,I,G,E,E,U,I,I,E,E,a,I,I,E,E,Q,I,I,E,E,gB,I,I,E,E,a,I,I,E,E,c,I,I,E,E,S,I,I,E,E,S,I,I,E,E,S,I,I,E,E,e,I,I,E,E,iB,I,I,E,E,mB,I,I,E,E,qB,I,I,E,E,Y,I,I,E,E,c,I,I,E,E,iB,I,INDZ,IAAM,EAAa,AAAA,EAAO,GAAqB,CAA/C;;WAEa,EAAA,CAAC,CAAA,MAAE,CAAK,CAAE,GAAK,EAAM,MAAM,CAAC,KAAK,CAAjC;;;;;cAKG,EAAA,CAAC,CAAA,MAAE,CAAK,CAAE,GAAK,EAAM,MAAM,CAAC,UAAU,CAAtC;;;;AAIf,CAAA,CAEK,EAAa,AAAA,EAAO,GAAqB,CAA/C;cACgB,EAAA,CAAC,CAAA,MAAE,CAAK,CAAE,GAAK,EAAM,MAAM,CAAC,UAAU,CAAtC;8BACgB,EAAA,CAAC,CAAA,MAAE,CAAK,CAAE,GAAK,EAAM,MAAM,CAAC,UAAU,CAAtC;;;;;;AAM/B,CAAA,CAEK,EAAc,AAAA,EAAO,EAA4B,CAAvD;;;;;AAKC,CAAA,CAOY,EAAQ,CAAC,CAAA,SAAE,CAAQ,CAAA,QAAE,CAAO,CAAE,GAAG,EAAmB,IAC/D,IAAM,ECvCC,AAAA,IDqDP,OAZ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","sources":["<anon>","packages/core/components.ts","packages/core/src/components/index.ts","packages/core/src/components/Modal.tsx","packages/core/src/hooks/useTheme.ts","packages/core/src/components/Checker.tsx","packages/core/index.ts","packages/core/src/components/App.tsx","packages/core/src/store/index.ts","packages/core/src/constants.ts","packages/core/src/helpers/generateNodeId.ts","packages/core/src/store/nodesStore.ts","packages/core/src/store/history/index.ts","packages/core/src/store/audioPatch/index.ts","packages/core/src/store/audioPatch/compareGraphs.ts","packages/core/src/store/projectStore.ts","packages/core/src/helpers/projectFile.ts","packages/core/src/styles.ts","packages/core/src/theme.ts","packages/core/src/components/Editor/index.tsx","packages/core/src/components/contextMenu/EdgeContextMenu.tsx","packages/core/src/components/contextMenu/styles.tsx","packages/core/src/components/contextMenu/EditorContextMenu.tsx","packages/core/src/components/AddNode/index.tsx","packages/core/src/components/AddNode/Filters.tsx","packages/core/src/components/AddNode/Plugins.tsx","packages/core/src/components/UploadPatch.tsx","packages/core/src/components/UploadProject.tsx","packages/core/src/components/UploadAudio.tsx","packages/core/src/lib/index.ts","packages/core/src/lib/hooks/useWorker.ts","packages/core/src/lib/hooks/useMessageChannel.ts","packages/core/src/lib/helpers.ts","packages/core/src/components/contextMenu/NodeContextMenu.tsx","packages/core/src/components/ControlPanel/index.tsx","packages/core/src/components/ControlPanel/ControlPanelItem.tsx","packages/core/src/hooks/useAudioNode.ts","packages/core/src/hooks/useNode.ts","packages/core/src/components/ControlPanel/styles.tsx","packages/core/src/components/Node/index.tsx","packages/core/src/components/EditableLabel.tsx","packages/core/src/components/NodeInfoModal.tsx","packages/core/src/components/Help/index.tsx","packages/core/src/components/Help/HelpModal.tsx","node_modules/@parcel/runtime-js/lib/bundles/runtime-75fdea8dd6c01287.js","packages/core/src/components/ResumeContext.tsx","packages/core/src/components/ToggleMinimap.tsx","packages/core/src/components/Wire.tsx","packages/core/src/components/RadioGroup.tsx","packages/core/src/components/Input.tsx","packages/core/src/components/DropdownInput.tsx","packages/core/src/components/ColorInput.tsx","packages/core/src/components/NumberInput.tsx","packages/core/src/components/Button.tsx","packages/core/src/components/Select.tsx","packages/core/src/components/Slider.tsx","packages/core/src/components/SplineEditor.tsx","packages/core/src/components/NodeConfig.tsx"],"sourcesContent":["import {jsx as $7gk4U$jsx, jsxs as $7gk4U$jsxs, Fragment as $7gk4U$Fragment} from \"react/jsx-runtime\";\nimport $7gk4U$emotionstyled from \"@emotion/styled\";\nimport {useEffect as $7gk4U$useEffect, useState as $7gk4U$useState, version as $7gk4U$version, useMemo as $7gk4U$useMemo, useCallback as $7gk4U$useCallback, useRef as $7gk4U$useRef} from \"react\";\nimport {createPortal as $7gk4U$createPortal} from \"react-dom\";\nimport {MdClose as $7gk4U$MdClose, MdDragHandle as $7gk4U$MdDragHandle, MdSettings as $7gk4U$MdSettings, MdInfoOutline as $7gk4U$MdInfoOutline} from \"react-icons/md\";\nimport {useTheme as $7gk4U$useTheme, withTheme as $7gk4U$withTheme, ThemeProvider as $7gk4U$ThemeProvider, Global as $7gk4U$Global, css as $7gk4U$css} from \"@emotion/react\";\nimport {nanoid as $7gk4U$nanoid} from \"nanoid\";\nimport {FaPlus as $7gk4U$FaPlus} from \"react-icons/fa6\";\nimport {registerFetcher as $7gk4U$registerFetcher} from \"@web-noise/fetch\";\nimport $7gk4U$reactflow, {getConnectedEdges as $7gk4U$getConnectedEdges, addEdge as $7gk4U$addEdge, applyNodeChanges as $7gk4U$applyNodeChanges, applyEdgeChanges as $7gk4U$applyEdgeChanges, useOnViewportChange as $7gk4U$useOnViewportChange, Background as $7gk4U$Background, BackgroundVariant as $7gk4U$BackgroundVariant, MiniMap as $7gk4U$MiniMap, Controls as $7gk4U$Controls, ReactFlowProvider as $7gk4U$ReactFlowProvider, useReactFlow as $7gk4U$useReactFlow, Position as $7gk4U$Position, Handle as $7gk4U$Handle, ControlButton as $7gk4U$ControlButton, getBezierPath as $7gk4U$getBezierPath} from \"reactflow\";\nimport {create as $7gk4U$create} from \"zustand\";\nimport {setAudioNodeTypes as $7gk4U$setAudioNodeTypes, createPatch as $7gk4U$createPatch} from \"@web-noise/patch\";\nimport {reverse as $7gk4U$reverse, patch as $7gk4U$patch, create as $7gk4U$create1} from \"jsondiffpatch\";\nimport {injectGlobal as $7gk4U$injectGlobal} from \"@emotion/css\";\nimport \"reactflow/dist/style.css\";\nimport {useContextMenu as $7gk4U$useContextMenu, Item as $7gk4U$Item, Menu as $7gk4U$Menu, Separator as $7gk4U$Separator} from \"react-contexify\";\nimport \"react-contexify/dist/ReactContexify.css\";\nimport $7gk4U$jsfiledownload from \"js-file-download\";\nimport $7gk4U$hotkeysjs from \"hotkeys-js\";\nimport {FileDrop as $7gk4U$FileDrop} from \"react-file-drop\";\nimport {FaFileUpload as $7gk4U$FaFileUpload, FaQuestion as $7gk4U$FaQuestion, FaVolumeOff as $7gk4U$FaVolumeOff, FaMap as $7gk4U$FaMap, FaRegMap as $7gk4U$FaRegMap, FaRegArrowAltCircleRight as $7gk4U$FaRegArrowAltCircleRight} from \"react-icons/fa\";\nimport {Resizable as $7gk4U$Resizable} from \"re-resizable\";\nimport $7gk4U$reactgridlayout from \"react-grid-layout\";\nimport \"react-grid-layout/css/styles.css\";\nimport {AiFillLock as $7gk4U$AiFillLock, AiFillUnlock as $7gk4U$AiFillUnlock} from \"react-icons/ai\";\nimport {RxDashboard as $7gk4U$RxDashboard} from \"react-icons/rx\";\nimport $7gk4U$reactmoderndrawer from \"react-modern-drawer\";\nimport \"react-modern-drawer/dist/index.css\";\nimport {marked as $7gk4U$marked} from \"marked\";\nimport {useThrottledCallback as $7gk4U$useThrottledCallback} from \"use-debounce\";\nimport $7gk4U$rcslider from \"rc-slider\";\nimport \"rc-slider/assets/index.css\";\nimport {CanvasSpliner as $7gk4U$CanvasSpliner} from \"CanvasSpliner\";\n\n\nfunction $parcel$export(e, n, v, s) {\n Object.defineProperty(e, n, {get: v, set: s, enumerable: true, configurable: true});\n}\n\nfunction $parcel$exportWildcard(dest, source) {\n Object.keys(source).forEach(function(key) {\n if (key === 'default' || key === '__esModule' || Object.prototype.hasOwnProperty.call(dest, key)) {\n return;\n }\n\n Object.defineProperty(dest, key, {\n enumerable: true,\n get: function get() {\n return source[key];\n }\n });\n });\n\n return dest;\n}\n\nfunction $parcel$interopDefault(a) {\n return a && a.__esModule ? a.default : a;\n}\nvar $ee9ef7c1261ede87$exports = {};\n\n$parcel$export($ee9ef7c1261ede87$exports, \"Modal\", () => $4001d24decbb98f7$export$2b77a92f1a5ad772);\n$parcel$export($ee9ef7c1261ede87$exports, \"Checker\", () => $0cdf21d270160c43$export$8ecd240bc8faaeeb);\n$parcel$export($ee9ef7c1261ede87$exports, \"RadioGroup\", () => $fee4ec5a9782241c$export$a98f0dcb43a68a25);\n$parcel$export($ee9ef7c1261ede87$exports, \"Input\", () => $4866e5bff8d594b9$export$f5b8910cec6cf069);\n$parcel$export($ee9ef7c1261ede87$exports, \"DropdownInput\", () => $eadb9fa465de5e7c$export$7a40489edcbfb3a1);\n$parcel$export($ee9ef7c1261ede87$exports, \"ColorInput\", () => $8d9f8f4bde3307d1$export$5a1d7ca0a925d9c2);\n$parcel$export($ee9ef7c1261ede87$exports, \"NumberInput\", () => $f537c5f3d37e7de0$export$6bf0cd3a219bbade);\n$parcel$export($ee9ef7c1261ede87$exports, \"Button\", () => $44b7e15e1a9af68f$export$353f5b6fc5456de1);\n$parcel$export($ee9ef7c1261ede87$exports, \"Select\", () => $6cd47b275e936c4f$export$ef9b1a59e592288f);\n$parcel$export($ee9ef7c1261ede87$exports, \"Slider\", () => $145c4d4c74f0de83$export$472062a354075cee);\n$parcel$export($ee9ef7c1261ede87$exports, \"SplineEditor\", () => $2c0e5b77732bcbe8$export$2bf7c2638a145e5c);\n$parcel$export($ee9ef7c1261ede87$exports, \"ConfigRowLabel\", () => $149f0c1aa7846f5b$export$555ece15b74b7abc);\n$parcel$export($ee9ef7c1261ede87$exports, \"ConfigRowControl\", () => $149f0c1aa7846f5b$export$ef9ca7b440c0032c);\n$parcel$export($ee9ef7c1261ede87$exports, \"ConfigRowSeparator\", () => $149f0c1aa7846f5b$export$bd1dc14d6df7044e);\n$parcel$export($ee9ef7c1261ede87$exports, \"ConfigRow\", () => $149f0c1aa7846f5b$export$d56900fc3755b916);\n$parcel$export($ee9ef7c1261ede87$exports, \"ConfigPanel\", () => $149f0c1aa7846f5b$export$aac584ace4a7b830);\n$parcel$export($ee9ef7c1261ede87$exports, \"ConfigRowInner\", () => $149f0c1aa7846f5b$export$edaba703bd8b8dfa);\n\n\n\n\n\n\nconst $abd71d53b289d0e8$var$useTheme = ()=>{\n return (0, $7gk4U$useTheme)();\n};\nvar $abd71d53b289d0e8$export$2e2bcd8739ae039 = $abd71d53b289d0e8$var$useTheme;\n\n\nconst $4001d24decbb98f7$var$ModalOuter = (0, $7gk4U$emotionstyled).div`\n position: fixed;\n z-index: ${({ theme: theme })=>theme.zIndex.modal};\n width: 100%;\n height: 100%;\n top: 0;\n left: 0;\n background: ${({ theme: theme })=>theme.colors.elevation3}cc;\n display: flex;\n align-items: center;\n justify-content: center;\n`;\nconst $4001d24decbb98f7$var$ModalInner = (0, $7gk4U$emotionstyled).div`\n background: ${({ theme: theme })=>theme.colors.elevation2};\n box-shadow: 1px 1px 1px 1px ${({ theme: theme })=>theme.colors.elevation1};\n color: white;\n width: 70%;\n height: 80%;\n overflow-y: scroll;\n position: relative;\n`;\nconst $4001d24decbb98f7$var$ModalCloser = (0, $7gk4U$emotionstyled)((0, $7gk4U$MdClose))`\n position: absolute;\n top: 0.2rem;\n right: 0.2rem;\n cursor: pointer;\n`;\nconst $4001d24decbb98f7$export$2b77a92f1a5ad772 = ({ children: children, onClose: onClose, ...props })=>{\n const theme = (0, $abd71d53b289d0e8$export$2e2bcd8739ae039)();\n (0, $7gk4U$useEffect)(()=>{\n const escHandler = (event)=>{\n if (event.key === \"Escape\") onClose?.();\n };\n document.addEventListener(\"keydown\", escHandler);\n return ()=>{\n document.removeEventListener(\"keydown\", escHandler);\n };\n }, [\n onClose\n ]);\n return /*#__PURE__*/ (0, $7gk4U$createPortal)((0, $7gk4U$jsx)($4001d24decbb98f7$var$ModalOuter, {\n theme: theme,\n onClick: onClose,\n children: (0, $7gk4U$jsxs)($4001d24decbb98f7$var$ModalInner, {\n ...props,\n onClick: (e)=>{\n e.stopPropagation();\n },\n theme: theme,\n children: [\n children,\n (0, $7gk4U$jsx)($4001d24decbb98f7$var$ModalCloser, {\n theme: theme,\n onClick: onClose\n })\n ]\n })\n }), document.body);\n};\nvar $4001d24decbb98f7$export$2e2bcd8739ae039 = $4001d24decbb98f7$export$2b77a92f1a5ad772;\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nvar $fcabc075f2eebe7f$exports = {};\n\n$parcel$export($fcabc075f2eebe7f$exports, \"DRAG_HANDLE_CLASS\", () => $fcabc075f2eebe7f$export$956b3cf15d7c363);\n$parcel$export($fcabc075f2eebe7f$exports, \"DRAG_HANDLE_SELECTOR\", () => $fcabc075f2eebe7f$export$21d634b1d5d9bee3);\n$parcel$export($fcabc075f2eebe7f$exports, \"CONTROL_PANEL_GRID_CONFIG\", () => $fcabc075f2eebe7f$export$9f05d3e6ade4c09e);\n$parcel$export($fcabc075f2eebe7f$exports, \"PortType\", () => $fcabc075f2eebe7f$export$b0b7b95ee465c83c);\nconst $fcabc075f2eebe7f$export$956b3cf15d7c363 = \"web-noise-drag-handle\";\nconst $fcabc075f2eebe7f$export$21d634b1d5d9bee3 = `.${$fcabc075f2eebe7f$export$956b3cf15d7c363}`;\nconst $fcabc075f2eebe7f$export$9f05d3e6ade4c09e = {\n rowHeight: 10,\n cols: 4\n};\nvar $fcabc075f2eebe7f$export$b0b7b95ee465c83c;\n(function(PortType) {\n PortType[\"Gate\"] = \"gate\";\n PortType[\"Number\"] = \"number\";\n PortType[\"Audio\"] = \"audio\";\n PortType[\"Any\"] = \"any\";\n})($fcabc075f2eebe7f$export$b0b7b95ee465c83c || ($fcabc075f2eebe7f$export$b0b7b95ee465c83c = {}));\n\n\nconst $84015eb9c9ad0a38$var$generateNodeId = (node)=>{\n const random = +new Date() + Math.floor(Math.random() * 1000);\n if (!node?.type) return random.toString();\n return `${node.type}-${random}`;\n};\nvar $84015eb9c9ad0a38$export$2e2bcd8739ae039 = $84015eb9c9ad0a38$var$generateNodeId;\n\n\n\n\nconst $119cb341fc1425fb$var$nodesStateCreator = (set, get)=>({\n nodes: [],\n edges: [],\n onNodesChange: (changes)=>{\n set(({ nodes: nodes })=>({\n nodes: (0, $7gk4U$applyNodeChanges)(changes, nodes).map((node)=>({\n dragHandle: (0, $fcabc075f2eebe7f$export$21d634b1d5d9bee3),\n ...node\n }))\n }));\n },\n onEdgesChange: (changes)=>{\n set(({ edges: edges })=>({\n edges: (0, $7gk4U$applyEdgeChanges)(changes, edges)\n }));\n },\n onConnect: (connection)=>{\n set(({ edges: edges })=>({\n edges: (0, $7gk4U$addEdge)(connection, edges)\n }));\n },\n addNode: (node)=>{\n set(({ nodes: nodes })=>({\n nodes: nodes.concat(node)\n }));\n },\n setNodes: (nodes)=>{\n set({\n nodes: nodes\n });\n },\n setEdges: (edges)=>{\n set({\n edges: edges\n });\n },\n setNodesAndEdges: ({ nodes: nodes, edges: edges })=>{\n set({\n nodes: nodes,\n edges: edges\n });\n },\n getNodesAndEdges: ()=>{\n const { nodes: nodes, edges: edges } = get();\n return {\n nodes: nodes,\n edges: edges\n };\n },\n clearElements: ()=>{\n set({\n nodes: [],\n edges: []\n });\n },\n getNode: (id)=>{\n const { nodes: nodes } = get();\n const node = nodes.find((node)=>node.id === id);\n return node || null;\n },\n updateNodeData: (id, data)=>{\n set(({ nodes: nodes })=>{\n return {\n nodes: nodes.map((node)=>{\n if (node.id === id) return {\n ...node,\n data: {\n ...node.data,\n ...data\n }\n };\n return node;\n })\n };\n });\n },\n nodeTypes: {},\n setNodeTypes: (nodeTypes)=>set({\n nodeTypes: nodeTypes\n })\n });\nvar $119cb341fc1425fb$export$2e2bcd8739ae039 = $119cb341fc1425fb$var$nodesStateCreator;\n\n\n\nconst $e85a74fe7877b330$var$cloneObject = (input)=>{\n return JSON.parse(JSON.stringify(input));\n};\nconst $e85a74fe7877b330$export$b1b92d12d1c2ae0e = (set, get)=>({\n history: {\n maxHistoryLength: 5,\n buffer: [],\n pointer: 0,\n skipCollect: false,\n push: (changes)=>{\n const { history: history } = get();\n const { maxHistoryLength: maxHistoryLength, skipCollect: skipCollect } = history;\n if (skipCollect) {\n set({\n history: {\n ...history,\n skipCollect: false\n }\n });\n return;\n }\n set(({ history: history })=>{\n if (!history) return {};\n const { buffer: buffer, pointer: pointer } = history;\n const newBuffer = buffer.slice(Math.max(pointer - maxHistoryLength + 1, 0), pointer);\n return {\n history: {\n ...history,\n buffer: [\n ...newBuffer,\n changes\n ],\n pointer: Math.min(pointer + 1, maxHistoryLength)\n }\n };\n });\n },\n back: ()=>{\n const { nodes: nodes, edges: edges, controlPanel: controlPanel, history: history } = get();\n const { buffer: buffer, pointer: pointer } = history;\n const patchData = buffer[pointer - 1];\n if (!patchData) return;\n const reversedPatchData = $7gk4U$reverse(patchData);\n if (!reversedPatchData) return;\n const updates = $e85a74fe7877b330$var$cloneObject({\n nodes: nodes,\n edges: edges,\n controlPanel: controlPanel\n });\n const patch = $7gk4U$patch(updates, reversedPatchData);\n set({\n ...patch,\n history: {\n ...history,\n pointer: pointer - 1,\n skipCollect: true\n }\n });\n },\n forward: ()=>{\n const { nodes: nodes, edges: edges, controlPanel: controlPanel, history: history } = get();\n const { buffer: buffer, pointer: pointer } = history;\n const patchData = buffer[pointer];\n if (!patchData) return;\n const updates = $e85a74fe7877b330$var$cloneObject({\n nodes: nodes,\n edges: edges,\n controlPanel: controlPanel\n });\n const patch = $7gk4U$patch(updates, patchData);\n set({\n ...patch,\n history: {\n ...history,\n pointer: pointer + 1,\n skipCollect: true\n }\n });\n },\n // @TODO: remove this method and store history per file\n clear: ()=>{\n const { history: history } = get();\n set({\n history: {\n ...history,\n buffer: [],\n pointer: 0,\n skipCollect: true\n }\n });\n }\n }\n });\nconst $e85a74fe7877b330$var$COLLECT_CHANGES_DEBOUNCE_TIME = 500;\nconst $e85a74fe7877b330$export$4e64751394766316 = (set, get)=>{\n const jsondiffpatchInstance = $7gk4U$create1({\n propertyFilter: (name, context)=>{\n //@TODO: rework this function, find better solution\n if (context.parent?.parent?.childName === \"controlPanel\") return true;\n if (// @ts-ignore\n [\n \"data\",\n \"position\",\n \"controlPanel\"\n ].includes(context.parent?.childName)) return true;\n return [\n \"controlPanel\",\n \"size\",\n \"edges\",\n \"nodes\",\n \"data\",\n \"label\",\n \"config\",\n \"values\",\n \"position\",\n \"x\",\n \"y\"\n ].includes(name);\n }\n });\n let oldState = get();\n let timer;\n return (state, prevState)=>{\n if (state.currentFileIndex !== prevState.currentFileIndex) get().history.clear();\n clearTimeout(timer);\n if (!oldState) oldState = prevState;\n timer = setTimeout(()=>{\n const changes = jsondiffpatchInstance.diff(oldState, state);\n oldState = null;\n if (changes) get().history.push(changes);\n }, $e85a74fe7877b330$var$COLLECT_CHANGES_DEBOUNCE_TIME);\n };\n};\nconst $e85a74fe7877b330$var$history = (config)=>(set, get, api)=>{\n const collectChanges = $e85a74fe7877b330$export$4e64751394766316(set, get);\n api.subscribe(collectChanges);\n return config((...args)=>set(...args), get, api);\n };\nvar $e85a74fe7877b330$export$2e2bcd8739ae039 = $e85a74fe7877b330$var$history;\n\n\n\nconst $6afd48ce6460068b$export$e364ea0c1dfb25e5 = (left, right)=>{\n const setLeft = new Set(left.map((item)=>item.id));\n const setRight = new Set(right.map((item)=>item.id));\n const added = right.filter((item)=>!setLeft.has(item.id));\n const removed = left.filter((item)=>!setRight.has(item.id));\n return {\n added: added,\n removed: removed\n };\n};\n\n\nconst $050de61b7535b152$export$62647b40ff8aed70 = (set, get)=>({\n patch: (0, $7gk4U$createPatch)(),\n nodesState: {}\n });\nconst $050de61b7535b152$var$audioPatch = (config)=>(set, get, api)=>{\n api.subscribe(async (state, prevState)=>{});\n const promises = new Set();\n let currentState = {\n ...get(),\n nodes: [],\n edges: []\n };\n return config(async (...args)=>{\n const oldState = get();\n const [storeChanges] = args;\n //@ts-ignore\n const newState = {\n ...currentState,\n ...typeof storeChanges === \"function\" ? storeChanges({\n ...currentState\n }) : storeChanges\n };\n const nodeChanges = (0, $6afd48ce6460068b$export$e364ea0c1dfb25e5)(currentState.nodes, newState.nodes);\n const edgeChanges = (0, $6afd48ce6460068b$export$e364ea0c1dfb25e5)(currentState.edges, newState.edges);\n //@ts-ignore\n currentState = newState;\n const newNodes = nodeChanges.added;\n const newEdges = edgeChanges.added;\n const removedEdges = edgeChanges.removed;\n const removedNodes = nodeChanges.removed;\n const { patch: patch } = oldState;\n if (newNodes.length) {\n const promise = patch.registerAudioNodes(//@ts-ignore\n newNodes);\n promises.add(promise);\n await promise;\n promises.delete(promise);\n }\n if (!(newEdges.length || removedEdges.length || removedNodes.length)) {\n set(...args);\n return;\n }\n if (promises.size) try {\n await Promise.all([\n ...promises.values()\n ]);\n } catch (e) {\n console.log(\"some error\", e);\n }\n if (newEdges.length) patch.registerAudioConnections(//@ts-ignore\n newEdges);\n if (removedEdges.length) //@ts-ignore\n patch.unregisterAudioConnections(removedEdges);\n if (removedNodes.length) //@ts-ignore\n patch.unregisterAudioNodes(removedNodes);\n set(...args);\n }, get, api);\n };\nvar $050de61b7535b152$export$2e2bcd8739ae039 = $050de61b7535b152$var$audioPatch;\n\n\nconst $c5ef937e71d3327e$export$e698b79c63b74136 = (file)=>!(\"type\" in file) || file.type === \"patch\";\nconst $c5ef937e71d3327e$export$31c2336f657dc59f = (file)=>file.type === \"audio\";\n\n\nconst $fc415f1d12d2f04e$var$projectStateCreator = (set, get)=>({\n project: {\n files: []\n },\n setProject (project) {\n set({\n project: project,\n currentFileIndex: 0\n });\n },\n getProject () {\n return get().project;\n },\n pullEditorChanges () {\n const { getEditorState: getEditorState, currentFileIndex: currentFileIndex, updateFileContent: updateFileContent, project: project } = get();\n const currentFile = project.files[currentFileIndex];\n if ((0, $c5ef937e71d3327e$export$31c2336f657dc59f)(currentFile)) return;\n updateFileContent(currentFileIndex, {\n ...currentFile,\n file: getEditorState()\n });\n },\n syncEditorWithCurrentFile: ()=>{\n const { currentFileIndex: currentFileIndex, setEditorState: setEditorState, project: project } = get();\n const currentFile = project.files[currentFileIndex];\n if (currentFile.type === \"audio\") {\n console.log(\"audio file. skipping\");\n return;\n }\n setEditorState(currentFile.file);\n },\n currentFileIndex: 0,\n setCurrentFileIndex (newFileIndex) {\n const { currentFileIndex: currentFileIndex } = get();\n if (newFileIndex === currentFileIndex) return;\n set({\n currentFileIndex: newFileIndex\n });\n },\n updateFileContent (index, file) {\n const { project: project } = get();\n set({\n project: {\n ...project,\n files: project.files.map((f, i)=>{\n if (i === index) return {\n // @TODO check again if merging is really needed here\n ...f,\n ...file\n };\n return f;\n })\n }\n });\n },\n updateFileName (index, fileName) {\n const { project: project } = get();\n set({\n project: {\n ...project,\n files: project.files.map((f, i)=>{\n if (i === index) return {\n ...f,\n name: fileName\n };\n return f;\n })\n }\n });\n },\n addFile (file) {\n const { project: project } = get();\n const files = [\n ...project.files,\n file\n ];\n set({\n project: {\n ...project,\n files: files\n }\n });\n },\n deleteFile: (fileIndex)=>{\n const { project: project, currentFileIndex: currentFileIndex } = get();\n set({\n project: {\n ...project,\n files: project.files.filter((_, index)=>fileIndex !== index)\n }\n });\n if (fileIndex <= currentFileIndex) set({\n currentFileIndex: currentFileIndex - 1\n });\n }\n });\nvar $fc415f1d12d2f04e$export$2e2bcd8739ae039 = $fc415f1d12d2f04e$var$projectStateCreator;\n\n\nconst $5b293d93bfa5f38a$export$34c5bc865219488e = (...args)=>{\n const [set, get] = args;\n return {\n ...(0, $119cb341fc1425fb$export$2e2bcd8739ae039)(...args),\n ...(0, $e85a74fe7877b330$export$b1b92d12d1c2ae0e)(...args),\n ...(0, $050de61b7535b152$export$62647b40ff8aed70)(...args),\n ...(0, $fc415f1d12d2f04e$export$2e2bcd8739ae039)(...args),\n setGraph: async ({ nodes: nodes, edges: edges })=>{\n const { patch: patch, createNodes: createNodes, createEdges: createEdges, setNodesAndEdges: setNodesAndEdges, nodes: activeNodes, edges: activeEdges } = get();\n setNodesAndEdges({\n nodes: [],\n edges: []\n });\n await createNodes(nodes);\n createEdges(edges);\n },\n clearGraph: ()=>{\n const { setGraph: setGraph } = get();\n setGraph({\n nodes: [],\n edges: []\n });\n },\n createNodes: async (nodes)=>{\n const { createNode: createNode } = get();\n await Promise.all(nodes.map((node)=>createNode(node)));\n },\n createNode: (nodeData)=>{\n const { addNode: addNode, nodesConfiguration: nodesConfiguration } = get();\n const { type: type, id: id, data: data } = nodeData;\n if (typeof type === \"undefined\") throw new Error(`node type is not defined for node: ${id}`);\n const node = {\n ...nodeData,\n data: {\n ...data,\n config: {\n ...nodesConfiguration[type]?.defaultConfig,\n ...data?.config\n }\n }\n };\n addNode(node);\n },\n removeNode: (node)=>get().removeNodes([\n node\n ]),\n removeNodes: (nodes)=>{\n const { edges: edges, nodes: currentNodes, onNodesDelete: onNodesDelete, removeEdges: removeEdges, removeNodesFromControlPanel: removeNodesFromControlPanel } = get();\n const parentNodeIds = nodes.map(({ id: id })=>id);\n const children = currentNodes.filter(({ parentNode: parentNode })=>parentNode && parentNodeIds.includes(parentNode));\n const resultingNodes = [\n ...nodes,\n ...children\n ];\n removeNodesFromControlPanel(resultingNodes);\n const connectedEdges = (0, $7gk4U$getConnectedEdges)(resultingNodes, edges);\n removeEdges(connectedEdges);\n onNodesDelete(resultingNodes);\n const nodeIds = resultingNodes.map(({ id: id })=>id);\n set({\n nodes: currentNodes.filter(({ id: id })=>!nodeIds.includes(id))\n });\n },\n removeEdges: (edges)=>{\n const { edges: currentEdges, onEdgesDelete: onEdgesDelete } = get();\n const edgeIds = edges.map(({ id: id })=>id);\n onEdgesDelete(edges);\n set({\n edges: currentEdges.filter(({ id: id })=>!edgeIds.includes(id))\n });\n },\n createEdges: (newEdges)=>{\n const { patch: patch, edges: edges, setEdges: setEdges } = get();\n setEdges(newEdges);\n },\n onConnect: async (connection)=>{\n const { edges: edges, createEdges: createEdges } = get();\n const newEdges = (0, $7gk4U$addEdge)(connection, edges);\n createEdges(newEdges);\n },\n onEdgesDelete: (edges)=>{\n const { patch: patch } = get();\n },\n onNodesDelete: async (nodes)=>{\n const { removeNodesFromControlPanel: removeNodesFromControlPanel, patch: patch } = get();\n removeNodesFromControlPanel(nodes);\n },\n plugins: [],\n setPlugins: async (plugins)=>{\n const { setNodeTypes: setNodeTypes } = get();\n set({\n plugins: plugins\n });\n const nodesConf = plugins.reduce((acc, plugin)=>{\n return {\n ...acc,\n ...plugin.components.reduce((subAcc, item)=>({\n ...subAcc,\n [item.type]: item\n }), {})\n };\n }, {});\n const nodeTypes = Object.keys(nodesConf).reduce((acc, type)=>{\n return {\n ...acc,\n [type]: nodesConf[type].node\n };\n }, {});\n const audioNodeTypes = Object.keys(nodesConf).reduce((acc, type)=>{\n return {\n ...acc,\n [type]: nodesConf[type].audioNode\n };\n }, {});\n (0, $7gk4U$setAudioNodeTypes)(audioNodeTypes);\n setNodeTypes(nodeTypes);\n set(({ nodesConfiguration: nodesConfiguration })=>({\n nodesConfiguration: {\n ...nodesConfiguration,\n ...nodesConf\n }\n }));\n },\n nodesConfiguration: {},\n config: {\n showMinimap: false\n },\n setConfig: (changes)=>{\n set(({ config: config })=>({\n config: {\n ...config,\n ...changes\n }\n }));\n },\n getEditorState: ()=>{\n const { getNodesAndEdges: getNodesAndEdges, controlPanel: controlPanel, viewport: viewport } = get();\n return {\n ...getNodesAndEdges(),\n controlPanel: controlPanel,\n viewport: viewport\n };\n },\n setEditorState: async ({ nodes: nodes, edges: edges, controlPanel: controlPanel, viewport: viewport })=>{\n const { setGraph: setGraph } = get();\n await setGraph({\n nodes: nodes,\n edges: edges\n });\n // @TODO: remove this line once audio patch initialisation is reworked\n await new Promise((r)=>setTimeout(r, 1000));\n set({\n controlPanel: controlPanel,\n viewport: viewport\n });\n },\n isHelpShown: false,\n toggleHelp: ()=>{\n const { isHelpShown: showHelp } = get();\n set({\n isHelpShown: !showHelp\n });\n },\n copyBuffer: {\n nodes: [],\n edges: []\n },\n copy: (elements)=>{\n set({\n copyBuffer: elements\n });\n },\n copySelectedItems: ()=>{\n const { nodes: currentNodes, edges: currentEdges, copy: copy } = get();\n const nodes = currentNodes.filter(({ selected: selected })=>selected);\n const edges = currentEdges.filter(({ selected: selected })=>selected);\n if (!nodes.length) return;\n copy({\n nodes: nodes,\n edges: edges\n });\n },\n pasteBuffer: (x = 0, y = 0)=>{\n const { copyBuffer: copyBuffer, createNodes: createNodes, setEdges: setEdges, nodes: nodes, edges: edges } = get();\n const { nodes: nodesToCopy, edges: edgesToCopy } = copyBuffer;\n if (!nodesToCopy.length) return;\n set({\n nodes: nodes.map((node)=>({\n ...node,\n selected: false\n }))\n });\n const topLeftNode = nodesToCopy.reduce((acc, node)=>{\n if (!acc) return node;\n if (node.position.x < acc.position.x && node.position.y < acc.position.y) return node;\n return acc;\n });\n const xDelta = topLeftNode.position.x - x;\n const yDelta = topLeftNode.position.y - y;\n const { nodes: newNodes, mapping: mapping } = nodesToCopy.reduce((acc, node)=>{\n const newNodeId = (0, $84015eb9c9ad0a38$export$2e2bcd8739ae039)(node);\n return {\n nodes: [\n ...acc.nodes,\n {\n ...node,\n id: newNodeId,\n position: {\n x: node.position.x - xDelta,\n y: node.position.y - yDelta\n },\n selected: true\n }\n ],\n mapping: {\n ...acc.mapping,\n [node.id]: newNodeId\n }\n };\n }, {\n nodes: [],\n mapping: {}\n });\n createNodes(newNodes);\n const newEdges = edgesToCopy.map((edge)=>{\n const source = mapping[edge.source] || edge.source;\n const target = mapping[edge.target] || edge.target;\n return {\n ...edge,\n id: edge.id.replace(edge.source, source).replace(edge.target, target),\n source: source,\n target: target,\n selected: true\n };\n });\n setEdges([\n ...edges.map((edge)=>({\n ...edge,\n selected: false\n })),\n ...newEdges\n ]);\n },\n getControlPanelNode: (node)=>{\n const { nodesConfiguration: nodesConfiguration } = get();\n const { type: type } = node;\n if (!type) return null;\n const controlPanelNode = nodesConfiguration[type]?.controlPanelNode;\n if (!controlPanelNode) {\n console.error(`could not find node for type ${type}`);\n return null;\n }\n return controlPanelNode;\n },\n controlPanel: {\n show: true,\n nodes: [],\n size: {\n width: 200,\n height: 100\n }\n },\n showControlPanel: ()=>set(({ controlPanel: controlPanel })=>({\n controlPanel: {\n ...controlPanel,\n show: true\n }\n })),\n hideControlPanel: ()=>set(({ controlPanel: controlPanel })=>({\n controlPanel: {\n ...controlPanel,\n show: false\n }\n })),\n addNodeToControlPanel: (node)=>{\n const { nodesConfiguration: nodesConfiguration } = get();\n const defaultConfig = node.type ? nodesConfiguration[node.type]?.defaultConfig : {};\n const { height: height } = defaultConfig?.size || {};\n const newNode = {\n id: node.id,\n ...height ? {\n height: height / (0, $fcabc075f2eebe7f$export$9f05d3e6ade4c09e).rowHeight\n } : {}\n };\n set(({ controlPanel: controlPanel })=>({\n controlPanel: {\n ...controlPanel,\n nodes: [\n ...controlPanel.nodes,\n newNode\n ]\n }\n }));\n },\n removeNodeFromControlPanel: (node)=>get().removeNodesFromControlPanel([\n node\n ]),\n removeNodesFromControlPanel: (nodes)=>{\n const nodeIds = nodes.map(({ id: id })=>id);\n set(({ controlPanel: controlPanel })=>{\n const nodes = controlPanel.nodes.filter(({ id: id })=>!nodeIds.includes(id));\n return {\n controlPanel: {\n ...controlPanel,\n nodes: nodes\n }\n };\n });\n },\n setControlPanelNodes: (nodes)=>{\n set(({ controlPanel: controlPanel })=>{\n return {\n controlPanel: {\n ...controlPanel,\n nodes: nodes\n }\n };\n });\n },\n setControlPanelSize: (size)=>{\n set(({ controlPanel: controlPanel })=>{\n return {\n controlPanel: {\n ...controlPanel,\n size: size\n }\n };\n });\n },\n viewport: {\n x: 0,\n y: 0,\n zoom: 1\n },\n setViewport: (viewport)=>set({\n viewport: viewport\n })\n };\n};\nconst $5b293d93bfa5f38a$var$useStore = (0, $7gk4U$create)((0, $050de61b7535b152$export$2e2bcd8739ae039)((0, $e85a74fe7877b330$export$2e2bcd8739ae039)($5b293d93bfa5f38a$export$34c5bc865219488e)));\nvar $5b293d93bfa5f38a$export$2e2bcd8739ae039 = $5b293d93bfa5f38a$var$useStore;\n\n\n\nconst $d10a6381d028e3f6$var$LEVA_COLOR_ACCENT2_BLUE = \"#007bff\";\nconst $d10a6381d028e3f6$var$COLOR_GREEN_PRIMARY = \"#14df42\";\nconst $d10a6381d028e3f6$var$COLOR_WHITE_PRIMARY = \"#ffffff\";\nconst $d10a6381d028e3f6$var$colors = {\n elevation1: \"#292d39\",\n elevation2: \"#181c20\",\n elevation3: \"#373c4b\",\n accent1: \"#0066dc\",\n accent2: $d10a6381d028e3f6$var$LEVA_COLOR_ACCENT2_BLUE,\n accent3: \"#3c93ff\",\n highlight1: \"#535760\",\n highlight2: \"#8c92a4\",\n highlight3: \"#fefefe\",\n vivid1: $d10a6381d028e3f6$var$COLOR_GREEN_PRIMARY,\n whitePrimary: $d10a6381d028e3f6$var$COLOR_WHITE_PRIMARY,\n error: \"#db5353\"\n};\nconst $d10a6381d028e3f6$var$zIndex = {\n modal: 9998,\n controlPanel: 9999,\n resumeContextLayout: 10003\n};\nconst $d10a6381d028e3f6$var$theme = {\n colors: $d10a6381d028e3f6$var$colors,\n zIndex: $d10a6381d028e3f6$var$zIndex\n};\nvar $d10a6381d028e3f6$export$2e2bcd8739ae039 = $d10a6381d028e3f6$var$theme;\n\n\n(0, $7gk4U$injectGlobal)`\n .react-flow {\n .react-flow__pane {\n /* background: rgb(106 106 106); */\n /* background: \"white\"; */\n // background: #292d39;\n background: ${(0, $d10a6381d028e3f6$export$2e2bcd8739ae039).colors.elevation3};\n }\n\n .react-flow__background {\n /* background: #efefef; */\n stroke: white;\n }\n\n .react-flow__node-default {\n background: #292d39;\n color: white;\n border: none;\n /* background: transparent; */\n }\n\n .react-flow__node {\n padding: 0;\n width: auto;\n }\n\n .react-flow__edge-path {\n stroke: ${(0, $d10a6381d028e3f6$export$2e2bcd8739ae039).colors.accent2};\n }\n\n .react-flow__node.selected {\n border: 1px solid ${(0, $d10a6381d028e3f6$export$2e2bcd8739ae039).colors.accent2};\n box-shadow: 0 0 0 0.5px #${(0, $d10a6381d028e3f6$export$2e2bcd8739ae039).colors.accent2};\n }\n\n .react-flow__node-default.selected, .react-flow__node-default.selected:hover {\n box-shadow: 0 0 0 0.5px #${(0, $d10a6381d028e3f6$export$2e2bcd8739ae039).colors.accent2};\n }\n\n /* .react-flow__minimap-mask {\n fill: ${(0, $d10a6381d028e3f6$export$2e2bcd8739ae039).colors.elevation1}\n }\n\n .react-flow__minimap-node {\n fill:${(0, $d10a6381d028e3f6$export$2e2bcd8739ae039).colors.accent2}\n } */\n }\n\n`;\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nconst $3c9d01d27d4be45b$export$ef9839ae55b8ba40 = (0, $7gk4U$emotionstyled)((0, $7gk4U$Item))``;\nconst $3c9d01d27d4be45b$export$98eff9c5659394e3 = (0, $7gk4U$emotionstyled)((0, $7gk4U$Menu))`\n background: ${({ colors: colors })=>colors.elevation2};\n padding: 0;\n border-radius: 0;\n\n .react-contexify__item__content {\n color: ${({ colors: colors })=>colors.whitePrimary};\n }\n\n .react-contexify__separator {\n background-color: ${({ colors: colors })=>colors.elevation1};\n margin: 0;\n }\n`;\n\n\nconst $c1fe1ac7b33d0893$export$d4cd258d01c03112 = \"editor-edge-menu\";\nconst $c1fe1ac7b33d0893$export$8b2e4a15453bac1e = ()=>{\n const { show: show } = (0, $7gk4U$useContextMenu)({\n id: $c1fe1ac7b33d0893$export$d4cd258d01c03112\n });\n const onContextMenu = (0, $7gk4U$useCallback)((event, edge)=>{\n event.stopPropagation();\n show(event, {\n props: {\n edge: edge\n }\n });\n }, [\n show\n ]);\n return {\n onContextMenu: onContextMenu\n };\n};\nconst $c1fe1ac7b33d0893$var$EdgeContextMenu = ()=>{\n const theme = (0, $abd71d53b289d0e8$export$2e2bcd8739ae039)();\n const removeEdges = (0, $5b293d93bfa5f38a$export$2e2bcd8739ae039)((store)=>store.removeEdges);\n return (0, $7gk4U$jsx)((0, $7gk4U$Fragment), {\n children: (0, $7gk4U$jsx)((0, $3c9d01d27d4be45b$export$98eff9c5659394e3), {\n id: $c1fe1ac7b33d0893$export$d4cd258d01c03112,\n animation: false,\n colors: theme.colors,\n children: (0, $7gk4U$jsx)((0, $3c9d01d27d4be45b$export$ef9839ae55b8ba40), {\n onClick: (event)=>removeEdges([\n event.props.edge\n ]),\n children: \"Delete Edge (DEL)\"\n })\n })\n });\n};\nvar $c1fe1ac7b33d0893$export$2e2bcd8739ae039 = $c1fe1ac7b33d0893$var$EdgeContextMenu;\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nconst $7eef8b3405d9f479$var$PluginsWrapper = (0, $7gk4U$withTheme)((0, $7gk4U$emotionstyled).div`\n width: 100%;\n`);\nconst $7eef8b3405d9f479$var$PluginWrapper = (0, $7gk4U$withTheme)((0, $7gk4U$emotionstyled).div`\n padding: 1rem;\n display: flex;\n flex-direction: column;\n gap: 1rem;\n`);\nconst $7eef8b3405d9f479$var$NodesList = (0, $7gk4U$withTheme)((0, $7gk4U$emotionstyled).ul`\n list-style: none;\n margin: 0;\n padding: 0;\n padding-bottom: 10px;\n columns: 2;\n\n li {\n display: flex;\n flex-direction: column;\n gap: 8px;\n padding: 4px;\n overflow: hidden;\n border: 1px solid ${({ theme: theme })=>theme.colors.elevation3};\n border-radius: 4px;\n margin-bottom: 0.5rem;\n &:hover {\n border-color: ${({ theme: theme })=>theme.colors.accent2};\n cursor: pointer;\n }\n }\n`);\nconst $7eef8b3405d9f479$var$NodeTitle = (0, $7gk4U$withTheme)((0, $7gk4U$emotionstyled).div`\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n`);\nconst $7eef8b3405d9f479$var$NodeDescription = (0, $7gk4U$withTheme)((0, $7gk4U$emotionstyled).div`\n color: ${({ theme: theme })=>theme.colors.highlight2};\n font-size: 12px;\n`);\nconst $7eef8b3405d9f479$export$48f6b48a42d49a36 = (0, $7gk4U$withTheme)((0, $7gk4U$emotionstyled).div`\n display: flex;\n gap: 0.2rem;\n flex-wrap: wrap;\n`);\nconst $7eef8b3405d9f479$export$7129a6e2db131a76 = (0, $7gk4U$withTheme)((0, $7gk4U$emotionstyled).span`\n cursor: pointer;\n font-size: 10px;\n background: ${({ theme: theme, isActive: isActive })=>isActive ? theme.colors.highlight1 : theme.colors.elevation3};\n border-radius: 2px;\n padding: 0.1rem 0.2rem;\n border: 1px solid;\n border-color: ${({ theme: theme })=>theme.colors.elevation2};\n &:hover {\n border-color: ${({ theme: theme })=>theme.colors.accent2};\n }\n`);\nconst $7eef8b3405d9f479$var$PluginHeader = (0, $7gk4U$withTheme)((0, $7gk4U$emotionstyled).div``);\nconst $7eef8b3405d9f479$var$PluginTitle = (0, $7gk4U$withTheme)((0, $7gk4U$emotionstyled).div`\n font-size: 1.1rem;\n padding: 0.25rem 0;\n color: ${({ theme: theme })=>theme.colors.highlight3};\n`);\nconst $7eef8b3405d9f479$var$PluginDescription = (0, $7gk4U$withTheme)((0, $7gk4U$emotionstyled).div`\n color: ${({ theme: theme })=>theme.colors.highlight2};\n font-size: 12px;\n`);\nconst $7eef8b3405d9f479$var$Plugins = ({ onComponentClick: onComponentClick, filters: { plugin: plugin, search: search = \"\", tags: tags }, onTagClick: onTagClick })=>{\n const plugins = (0, $5b293d93bfa5f38a$export$2e2bcd8739ae039)(({ plugins: plugins })=>plugins);\n const pluginsGroup = (0, $7gk4U$useMemo)(()=>{\n if (!plugin) return plugins;\n return plugins.filter(({ name: name })=>name === plugin);\n }, [\n plugins,\n plugin\n ]);\n const filteredPlugins = (0, $7gk4U$useMemo)(()=>{\n if (!search && !tags?.length) return pluginsGroup;\n const filteredByTags = pluginsGroup.map((plugin)=>({\n ...plugin,\n components: tags?.length ? plugin.components.filter((component)=>tags?.every((tag)=>component.tags?.includes(tag))) : plugin.components\n }));\n return filteredByTags.map((plugin)=>({\n ...plugin,\n components: plugin.components.filter(({ type: type, name: name })=>type.toLocaleLowerCase().includes(search.toLocaleLowerCase()) || name?.toLocaleLowerCase().includes(search.toLocaleLowerCase()))\n }));\n }, [\n pluginsGroup,\n search,\n tags\n ]);\n return (0, $7gk4U$jsx)($7eef8b3405d9f479$var$PluginsWrapper, {\n children: filteredPlugins.map(({ name: name, description: description, components: components }, index)=>{\n if (!components.length) return null;\n return (0, $7gk4U$jsxs)($7eef8b3405d9f479$var$PluginWrapper, {\n children: [\n (0, $7gk4U$jsxs)($7eef8b3405d9f479$var$PluginHeader, {\n children: [\n (0, $7gk4U$jsx)($7eef8b3405d9f479$var$PluginTitle, {\n children: name\n }),\n (0, $7gk4U$jsx)($7eef8b3405d9f479$var$PluginDescription, {\n children: description\n })\n ]\n }),\n (0, $7gk4U$jsx)($7eef8b3405d9f479$var$NodesList, {\n children: components.sort((a, b)=>a.type.toLowerCase() > b.type.toLowerCase() ? 1 : -1).map((component, idx)=>(0, $7gk4U$jsxs)(\"li\", {\n onClick: ()=>onComponentClick(component),\n children: [\n (0, $7gk4U$jsx)($7eef8b3405d9f479$var$NodeTitle, {\n children: component.name || component.type\n }),\n component.description && (0, $7gk4U$jsx)($7eef8b3405d9f479$var$NodeDescription, {\n children: component.description\n }),\n (0, $7gk4U$jsx)($7eef8b3405d9f479$export$48f6b48a42d49a36, {\n children: component.tags?.map((tag, tagIdx)=>(0, $7gk4U$jsx)($7eef8b3405d9f479$export$7129a6e2db131a76, {\n isActive: tags?.includes(tag),\n onClickCapture: (event)=>{\n event.stopPropagation();\n onTagClick(tag);\n },\n children: tag\n }, tagIdx))\n })\n ]\n }, idx))\n })\n ]\n }, index);\n })\n });\n};\nvar $7eef8b3405d9f479$export$2e2bcd8739ae039 = $7eef8b3405d9f479$var$Plugins;\n\n\nconst $059d317a9f4bda14$var$InputWrapper = (0, $7gk4U$emotionstyled).div`\n display: flex;\n position: relative;\n`;\nconst $059d317a9f4bda14$var$InputInner = (0, $7gk4U$emotionstyled).input`\n padding-right: 2rem;\n padding-left: 0.3rem;\n width: 100%;\n appearance: textfield;\n font-size: inherit;\n background: none;\n border: none;\n color: var(--leva-colors-highlight1);\n font-family: var(--leva-fonts-mono);\n cursor: inherit;\n text-overflow: ellipsis;\n outline: none;\n appearance: textfield;\n cursor: auto;\n background-color: ${({ theme: theme })=>theme.colors.elevation3};\n border-radius: 0.1rem;\n height: 2rem;\n color: ${({ theme: theme })=>theme.colors.highlight2};\n\n &:focus,\n &:hover {\n box-shadow: 0 0 0 var(--leva-borderWidths-focus)\n ${({ theme: theme })=>theme.colors.accent2};\n color: ${({ theme: theme })=>theme.colors.whitePrimary};\n }\n &::-webkit-inner-spin-button,\n &::-webkit-outer-spin-button {\n -webkit-appearance: none;\n margin-right: 1rem;\n }\n`;\nconst $059d317a9f4bda14$var$FiltersWrapper = (0, $7gk4U$emotionstyled).div`\n display: flex;\n flex-direction: column;\n padding: 0.6rem;\n gap: 0.6rem;\n border-right: 1px solid ${({ theme: theme })=>theme.colors.elevation3};\n min-width: 14rem;\n`;\nconst $059d317a9f4bda14$var$PluginName = (0, $7gk4U$emotionstyled).label`\n user-select: none;\n input {\n display: none;\n }\n input:checked + span {\n color: ${({ theme: theme })=>theme.colors.accent2};\n }\n &:hover {\n color: ${({ theme: theme })=>theme.colors.accent3};\n cursor: pointer;\n }\n`;\nconst $059d317a9f4bda14$var$StyledPluginTag = (0, $7gk4U$withTheme)((0, $7gk4U$emotionstyled)((0, $7eef8b3405d9f479$export$7129a6e2db131a76))`\n font-size: 12px;\n padding: 0.2rem 0.4rem;\n &:hover {\n }\n &::after {\n content: \"×\";\n margin-left: 0.4rem;\n }\n`);\nconst $059d317a9f4bda14$var$Filters = ({ onChange: onChange, value: value })=>{\n const theme = (0, $abd71d53b289d0e8$export$2e2bcd8739ae039)();\n const plugins = (0, $5b293d93bfa5f38a$export$2e2bcd8739ae039)(({ plugins: plugins })=>plugins);\n const inputRef = (0, $7gk4U$useRef)(null);\n (0, $7gk4U$useEffect)(()=>{\n if (!inputRef.current) return;\n inputRef.current.focus();\n }, [\n inputRef\n ]);\n return (0, $7gk4U$jsxs)($059d317a9f4bda14$var$FiltersWrapper, {\n theme: theme,\n children: [\n (0, $7gk4U$jsx)($059d317a9f4bda14$var$InputWrapper, {\n children: (0, $7gk4U$jsx)($059d317a9f4bda14$var$InputInner, {\n ref: inputRef,\n theme: theme,\n value: value.search || \"\",\n placeholder: \"search...\",\n onChange: (event)=>onChange({\n ...value,\n search: event.target.value\n })\n })\n }),\n (0, $7gk4U$jsx)((0, $7eef8b3405d9f479$export$48f6b48a42d49a36), {\n children: value.tags?.map((tag, index)=>(0, $7gk4U$jsx)($059d317a9f4bda14$var$StyledPluginTag, {\n isActive: true,\n onClick: ()=>{\n const newTags = value.tags?.filter((t)=>t !== tag) || [];\n onChange({\n ...value,\n tags: newTags\n });\n },\n children: tag\n }, index))\n }),\n plugins.map(({ name: name, components: components }, index)=>{\n if (!name) return null;\n return (0, $7gk4U$jsxs)($059d317a9f4bda14$var$PluginName, {\n theme: theme,\n children: [\n (0, $7gk4U$jsx)(\"input\", {\n type: \"checkbox\",\n name: \"plugin\",\n value: name,\n checked: name === value.plugin,\n onChange: ()=>{\n onChange({\n ...value,\n plugin: name === value.plugin ? null : name\n });\n }\n }),\n (0, $7gk4U$jsx)(\"span\", {\n children: name\n })\n ]\n }, index);\n })\n ]\n });\n};\nvar $059d317a9f4bda14$export$2e2bcd8739ae039 = $059d317a9f4bda14$var$Filters;\n\n\n\nconst $40a10d78b6fcf12b$var$AddNodeWrapper = (0, $7gk4U$emotionstyled).div`\n height: 100%;\n width: 100%;\n display: flex;\n gap: 1rem;\n`;\nconst $40a10d78b6fcf12b$var$PluginsPanel = (0, $7gk4U$emotionstyled).div`\n flex-grow: 1;\n height: 100%;\n overflow-y: scroll;\n`;\nconst $40a10d78b6fcf12b$var$AddNode = ({ isOpen: isOpen, closeMenu: closeMenu, mousePosition: mousePosition })=>{\n const theme = (0, $abd71d53b289d0e8$export$2e2bcd8739ae039)();\n const { screenToFlowPosition: screenToFlowPosition } = (0, $7gk4U$useReactFlow)();\n const { createNode: createNode } = (0, $5b293d93bfa5f38a$export$2e2bcd8739ae039)(({ createNode: createNode })=>({\n createNode: createNode\n }));\n const [filtersState, setFiltersState] = (0, $7gk4U$useState)({});\n const onComponentClick = (0, $7gk4U$useCallback)(({ type: type })=>{\n const { x: x, y: y } = screenToFlowPosition(mousePosition);\n const newNode = {\n //@TODO: generate node id in `createNode` function\n id: `${type}-${+new Date()}`,\n type: type,\n data: {\n label: type\n },\n position: {\n x: x,\n y: y\n },\n targetPosition: (0, $7gk4U$Position).Left,\n sourcePosition: (0, $7gk4U$Position).Right\n };\n createNode(newNode);\n closeMenu();\n }, [\n mousePosition,\n screenToFlowPosition,\n createNode,\n closeMenu,\n mousePosition\n ]);\n return isOpen ? (0, $7gk4U$jsx)((0, $4001d24decbb98f7$export$2e2bcd8739ae039), {\n onClose: ()=>{\n closeMenu();\n setFiltersState({});\n },\n children: (0, $7gk4U$jsxs)($40a10d78b6fcf12b$var$AddNodeWrapper, {\n theme: theme,\n children: [\n (0, $7gk4U$jsx)((0, $059d317a9f4bda14$export$2e2bcd8739ae039), {\n onChange: setFiltersState,\n value: filtersState\n }),\n (0, $7gk4U$jsx)($40a10d78b6fcf12b$var$PluginsPanel, {\n theme: theme,\n children: (0, $7gk4U$jsx)((0, $7eef8b3405d9f479$export$2e2bcd8739ae039), {\n filters: filtersState,\n onTagClick: (tag)=>{\n setFiltersState((state)=>({\n ...state,\n tags: state.tags?.includes(tag) ? state.tags.filter((t)=>t !== tag) : [\n ...state.tags || [],\n tag\n ]\n }));\n },\n onComponentClick: (component)=>{\n onComponentClick(component);\n setFiltersState({});\n }\n })\n })\n ]\n })\n }) : null;\n};\nvar $40a10d78b6fcf12b$export$2e2bcd8739ae039 = $40a10d78b6fcf12b$var$AddNode;\n\n\n\n\n\n\n\n\n\n\nconst $d972aef931806fef$var$UploadPatchWrapper = (0, $7gk4U$emotionstyled).div`\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n width: 100%;\n\n .drop-zone-wrapper {\n width: 80%;\n height: 80%;\n }\n\n .drop-zone {\n height: 100%;\n width: 100%;\n border-style: dashed;\n border-width: 2px;\n border-color: ${({ theme: theme })=>theme.colors.highlight2};\n opacity: 0.5;\n cursor: pointer;\n }\n\n .drop-zone:hover,\n .drop-zone-drag-over {\n opacity: 1;\n }\n`;\nconst $d972aef931806fef$var$DropZoneInner = (0, $7gk4U$emotionstyled).div`\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: center;\n height: 100%;\n width: 100%;\n`;\nconst $d972aef931806fef$var$FileUploadIcon = (0, $7gk4U$emotionstyled)((0, $7gk4U$FaFileUpload))`\n width: 100%;\n height: 8rem;\n`;\nconst $d972aef931806fef$var$FileUploadMessage = (0, $7gk4U$emotionstyled).div`\n font-size: 2rem;\n`;\nconst $d972aef931806fef$var$UploadPatch = ({ isOpen: isOpen, closeMenu: closeMenu })=>{\n const theme = (0, $abd71d53b289d0e8$export$2e2bcd8739ae039)();\n const setGraph = (0, $5b293d93bfa5f38a$export$2e2bcd8739ae039)(({ setGraph: setGraph })=>setGraph);\n const setEditorState = (0, $5b293d93bfa5f38a$export$2e2bcd8739ae039)((store)=>store.setEditorState);\n const fileInputRef = (0, $7gk4U$useRef)(null);\n const uploadFile = (0, $7gk4U$useCallback)((files)=>{\n const [file] = files || [];\n file.text().then(JSON.parse).then((editorState)=>{\n setEditorState(editorState);\n closeMenu();\n }).catch(console.error);\n }, [\n setGraph,\n closeMenu\n ]);\n const onTargetClick = ()=>{\n fileInputRef.current?.click();\n };\n return isOpen ? (0, $7gk4U$jsx)((0, $4001d24decbb98f7$export$2e2bcd8739ae039), {\n onClose: closeMenu,\n children: (0, $7gk4U$jsxs)($d972aef931806fef$var$UploadPatchWrapper, {\n theme: theme,\n children: [\n (0, $7gk4U$jsx)(\"input\", {\n onChange: ({ target: { files: files } })=>uploadFile(files),\n ref: fileInputRef,\n type: \"file\",\n className: \"hidden\",\n style: {\n display: \"none\"\n },\n accept: \".json\"\n }),\n (0, $7gk4U$jsx)((0, $7gk4U$FileDrop), {\n className: \"drop-zone-wrapper\",\n targetClassName: \"drop-zone\",\n draggingOverTargetClassName: \"drop-zone-drag-over\",\n onTargetClick: onTargetClick,\n onDrop: (files)=>uploadFile(files),\n children: (0, $7gk4U$jsxs)($d972aef931806fef$var$DropZoneInner, {\n theme: theme,\n children: [\n (0, $7gk4U$jsx)($d972aef931806fef$var$FileUploadIcon, {}),\n (0, $7gk4U$jsx)($d972aef931806fef$var$FileUploadMessage, {\n children: \"click or drop file here\"\n })\n ]\n })\n })\n ]\n })\n }) : null;\n};\nvar $d972aef931806fef$export$2e2bcd8739ae039 = $d972aef931806fef$var$UploadPatch;\n\n\n\n\n\n\n\n\n\n\nconst $6ca12aedd96d72f9$var$UploadProjectWrapper = (0, $7gk4U$emotionstyled).div`\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n width: 100%;\n\n .drop-zone-wrapper {\n width: 80%;\n height: 80%;\n }\n\n .drop-zone {\n height: 100%;\n width: 100%;\n border-style: dashed;\n border-width: 2px;\n border-color: ${({ theme: theme })=>theme.colors.highlight2};\n opacity: 0.5;\n cursor: pointer;\n }\n\n .drop-zone:hover,\n .drop-zone-drag-over {\n opacity: 1;\n }\n`;\nconst $6ca12aedd96d72f9$var$DropZoneInner = (0, $7gk4U$emotionstyled).div`\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: center;\n height: 100%;\n width: 100%;\n`;\nconst $6ca12aedd96d72f9$var$FileUploadIcon = (0, $7gk4U$emotionstyled)((0, $7gk4U$FaFileUpload))`\n width: 100%;\n height: 8rem;\n`;\nconst $6ca12aedd96d72f9$var$FileUploadMessage = (0, $7gk4U$emotionstyled).div`\n font-size: 2rem;\n`;\n// @TODO: unify with upload file\nconst $6ca12aedd96d72f9$var$UploadProject = ({ isOpen: isOpen, closeMenu: closeMenu })=>{\n const theme = (0, $abd71d53b289d0e8$export$2e2bcd8739ae039)();\n const setProject = (0, $5b293d93bfa5f38a$export$2e2bcd8739ae039)((store)=>store.setProject);\n const fileInputRef = (0, $7gk4U$useRef)(null);\n const uploadFile = (0, $7gk4U$useCallback)((files)=>{\n const [file] = files || [];\n file.text().then(JSON.parse).then((projectState)=>{\n setProject(projectState);\n closeMenu();\n }).catch(console.error);\n }, [\n setProject,\n closeMenu\n ]);\n const onTargetClick = ()=>{\n fileInputRef.current?.click();\n };\n return isOpen ? (0, $7gk4U$jsx)((0, $4001d24decbb98f7$export$2e2bcd8739ae039), {\n onClose: closeMenu,\n children: (0, $7gk4U$jsxs)($6ca12aedd96d72f9$var$UploadProjectWrapper, {\n theme: theme,\n children: [\n (0, $7gk4U$jsx)(\"input\", {\n onChange: ({ target: { files: files } })=>uploadFile(files),\n ref: fileInputRef,\n type: \"file\",\n className: \"hidden\",\n style: {\n display: \"none\"\n },\n accept: \".json\"\n }),\n (0, $7gk4U$jsx)((0, $7gk4U$FileDrop), {\n className: \"drop-zone-wrapper\",\n targetClassName: \"drop-zone\",\n draggingOverTargetClassName: \"drop-zone-drag-over\",\n onTargetClick: onTargetClick,\n onDrop: (files)=>uploadFile(files),\n children: (0, $7gk4U$jsxs)($6ca12aedd96d72f9$var$DropZoneInner, {\n theme: theme,\n children: [\n (0, $7gk4U$jsx)($6ca12aedd96d72f9$var$FileUploadIcon, {}),\n (0, $7gk4U$jsx)($6ca12aedd96d72f9$var$FileUploadMessage, {\n children: \"click or drop file here\"\n })\n ]\n })\n })\n ]\n })\n }) : null;\n};\nvar $6ca12aedd96d72f9$export$2e2bcd8739ae039 = $6ca12aedd96d72f9$var$UploadProject;\n\n\n\n\n\n\n\n\n\n\n\nvar $4bd7a7548349db5f$exports = {};\n\n$parcel$export($4bd7a7548349db5f$exports, \"useWorker\", () => $925e30e6078450bc$export$3a5757a785a34769);\n$parcel$export($4bd7a7548349db5f$exports, \"useMessageChannel\", () => $e0ee9b956b7c064a$export$1e86115ead375efc);\n\nconst $925e30e6078450bc$export$3a5757a785a34769 = (url)=>{\n const [worker, setWorker] = (0, $7gk4U$useState)(null);\n (0, $7gk4U$useEffect)(()=>{\n const newWorker = new Worker(url);\n setWorker(newWorker);\n return ()=>{\n newWorker?.terminate();\n setWorker(null);\n };\n }, []);\n return worker;\n};\nvar $925e30e6078450bc$export$2e2bcd8739ae039 = $925e30e6078450bc$export$3a5757a785a34769;\n\n\n\nconsole.log(888888, `React version: ${(0, $7gk4U$version)}`);\nconst $e0ee9b956b7c064a$export$1e86115ead375efc = ()=>{\n const [channel, setChannel] = (0, $7gk4U$useState)(null);\n (0, $7gk4U$useEffect)(()=>{\n const newChannel = new MessageChannel();\n newChannel.port2.start();\n setChannel(newChannel);\n return ()=>{\n setChannel(null);\n newChannel.port2.close();\n };\n }, []);\n return channel;\n};\nvar $e0ee9b956b7c064a$export$2e2bcd8739ae039 = $e0ee9b956b7c064a$export$1e86115ead375efc;\n\n\nvar $380e1488605d504c$exports = {};\n\n$parcel$export($380e1488605d504c$exports, \"setParameterValue\", () => $380e1488605d504c$export$cd440e094f060920);\n$parcel$export($380e1488605d504c$exports, \"fileToBase64\", () => $380e1488605d504c$export$25df2e315be8e003);\nconst $380e1488605d504c$export$cd440e094f060920 = (param, value, audioContext)=>{\n if (typeof value === \"undefined\") return;\n param.setValueAtTime(value, audioContext.currentTime);\n};\nconst $380e1488605d504c$export$25df2e315be8e003 = (file)=>{\n return new Promise((resolve, reject)=>{\n const reader = new FileReader();\n reader.readAsDataURL(file);\n reader.onload = ()=>resolve(reader.result?.toString() || \"\");\n reader.onerror = (error)=>reject(error);\n });\n};\n\n\n$parcel$exportWildcard($4bd7a7548349db5f$exports, $380e1488605d504c$exports);\n\n\nconst $7202e5658c6247ad$var$UploadAudioWrapper = (0, $7gk4U$emotionstyled).div`\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n width: 100%;\n\n .drop-zone-wrapper {\n width: 80%;\n height: 80%;\n }\n\n .drop-zone {\n height: 100%;\n width: 100%;\n border-style: dashed;\n border-width: 2px;\n border-color: ${({ theme: theme })=>theme.colors.highlight2};\n opacity: 0.5;\n cursor: pointer;\n }\n\n .drop-zone:hover,\n .drop-zone-drag-over {\n opacity: 1;\n }\n`;\nconst $7202e5658c6247ad$var$DropZoneInner = (0, $7gk4U$emotionstyled).div`\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: center;\n height: 100%;\n width: 100%;\n`;\nconst $7202e5658c6247ad$var$FileUploadIcon = (0, $7gk4U$emotionstyled)((0, $7gk4U$FaFileUpload))`\n width: 100%;\n height: 8rem;\n`;\nconst $7202e5658c6247ad$var$FileUploadMessage = (0, $7gk4U$emotionstyled).div`\n font-size: 2rem;\n`;\nconst $7202e5658c6247ad$var$UploadAudio = ({ isOpen: isOpen, closeMenu: closeMenu })=>{\n const theme = (0, $abd71d53b289d0e8$export$2e2bcd8739ae039)();\n const setGraph = (0, $5b293d93bfa5f38a$export$2e2bcd8739ae039)(({ setGraph: setGraph })=>setGraph);\n const setEditorState = (0, $5b293d93bfa5f38a$export$2e2bcd8739ae039)((store)=>store.setEditorState);\n const addFile = (0, $5b293d93bfa5f38a$export$2e2bcd8739ae039)((store)=>store.addFile);\n const fileInputRef = (0, $7gk4U$useRef)(null);\n const uploadFile = (0, $7gk4U$useCallback)(async (files)=>{\n const [file] = files || [];\n const base64 = await (0, $380e1488605d504c$export$25df2e315be8e003)(file);\n addFile({\n type: \"audio\",\n // @TODO: use nanoid here\n id: `audio-file-${+new Date()}`,\n name: file.name,\n file: base64\n });\n closeMenu();\n }, [\n addFile,\n closeMenu\n ]);\n const onTargetClick = ()=>{\n fileInputRef.current?.click();\n };\n return isOpen ? (0, $7gk4U$jsx)((0, $4001d24decbb98f7$export$2e2bcd8739ae039), {\n onClose: closeMenu,\n children: (0, $7gk4U$jsxs)($7202e5658c6247ad$var$UploadAudioWrapper, {\n theme: theme,\n children: [\n (0, $7gk4U$jsx)(\"input\", {\n onChange: ({ target: { files: files } })=>uploadFile(files),\n ref: fileInputRef,\n type: \"file\",\n className: \"hidden\",\n style: {\n display: \"none\"\n },\n accept: \".wav,.mp3,.ogg\"\n }),\n (0, $7gk4U$jsx)((0, $7gk4U$FileDrop), {\n className: \"drop-zone-wrapper\",\n targetClassName: \"drop-zone\",\n draggingOverTargetClassName: \"drop-zone-drag-over\",\n onTargetClick: onTargetClick,\n onDrop: (files)=>uploadFile(files),\n children: (0, $7gk4U$jsxs)($7202e5658c6247ad$var$DropZoneInner, {\n theme: theme,\n children: [\n (0, $7gk4U$jsx)($7202e5658c6247ad$var$FileUploadIcon, {}),\n (0, $7gk4U$jsx)($7202e5658c6247ad$var$FileUploadMessage, {\n children: \"click or drop file here\"\n })\n ]\n })\n })\n ]\n })\n }) : null;\n};\nvar $7202e5658c6247ad$export$2e2bcd8739ae039 = $7202e5658c6247ad$var$UploadAudio;\n\n\nconst $cc36fc9d90ce018d$export$d4cd258d01c03112 = \"editor-menu\";\nconst $cc36fc9d90ce018d$export$59ce2a6808e35a29 = ()=>{\n const { show: show } = (0, $7gk4U$useContextMenu)({\n id: $cc36fc9d90ce018d$export$d4cd258d01c03112\n });\n return {\n onContextMenu: show\n };\n};\nconst $cc36fc9d90ce018d$var$EditorContextMenu = ({ editorContextMenu: editorContextMenu = [] })=>{\n const theme = (0, $abd71d53b289d0e8$export$2e2bcd8739ae039)();\n const [mousePosition, setMousePosition] = (0, $7gk4U$useState)({\n x: 0,\n y: 0\n });\n const [showAddNode, setShowAddNode] = (0, $7gk4U$useState)(false);\n const [showUploadPatch, setShowUploadPatch] = (0, $7gk4U$useState)(false);\n const [showUploadProject, setShowUploadProject] = (0, $7gk4U$useState)(false);\n const [showUploadAudio, setShowUploadAudio] = (0, $7gk4U$useState)(false);\n const addNodeHandler = (0, $7gk4U$useCallback)((x, y)=>{\n setMousePosition({\n x: x,\n y: y\n });\n setShowAddNode(true);\n }, [\n setShowAddNode\n ]);\n const pasteBuffer = (0, $5b293d93bfa5f38a$export$2e2bcd8739ae039)((store)=>store.pasteBuffer);\n const { screenToFlowPosition: screenToFlowPosition } = (0, $7gk4U$useReactFlow)();\n const pasteBufferHandler = (0, $7gk4U$useCallback)((mousePosition)=>{\n const { x: x, y: y } = screenToFlowPosition(mousePosition);\n pasteBuffer(x, y);\n }, [\n setShowAddNode,\n screenToFlowPosition\n ]);\n const clearGraph = (0, $5b293d93bfa5f38a$export$2e2bcd8739ae039)(({ clearGraph: clearGraph })=>clearGraph);\n const getEditorState = (0, $5b293d93bfa5f38a$export$2e2bcd8739ae039)((store)=>store.getEditorState);\n const getProject = (0, $5b293d93bfa5f38a$export$2e2bcd8739ae039)((store)=>store.getProject);\n const deleteAllHandler = (0, $7gk4U$useCallback)(()=>{\n clearGraph();\n }, [\n clearGraph\n ]);\n const toggleHelp = (0, $5b293d93bfa5f38a$export$2e2bcd8739ae039)((store)=>store.toggleHelp);\n const historyBack = (0, $5b293d93bfa5f38a$export$2e2bcd8739ae039)((store)=>store.history.back);\n const historyForward = (0, $5b293d93bfa5f38a$export$2e2bcd8739ae039)((store)=>store.history.forward);\n const historyPointer = (0, $5b293d93bfa5f38a$export$2e2bcd8739ae039)((store)=>store.history.pointer);\n const historyBuffer = (0, $5b293d93bfa5f38a$export$2e2bcd8739ae039)((store)=>store.history.buffer);\n const copySelectedItems = (0, $5b293d93bfa5f38a$export$2e2bcd8739ae039)((store)=>store.copySelectedItems);\n const nodes = (0, $5b293d93bfa5f38a$export$2e2bcd8739ae039)((store)=>store.nodes);\n const selectedNodes = (0, $7gk4U$useMemo)(()=>nodes.filter(({ selected: selected })=>selected), [\n nodes\n ]);\n const currentCopyBuffer = (0, $5b293d93bfa5f38a$export$2e2bcd8739ae039)((store)=>store.copyBuffer);\n const reactFlowInstance = (0, $7gk4U$useReactFlow)();\n const downloadPatchHandler = (0, $7gk4U$useCallback)(()=>{\n const fileName = \"web-noise-patch.json\";\n const editorState = getEditorState();\n const data = {\n ...editorState\n };\n (0, $7gk4U$jsfiledownload)(JSON.stringify(data, null, 2), fileName);\n }, [\n getEditorState,\n reactFlowInstance\n ]);\n const downloadProjectHandler = (0, $7gk4U$useCallback)(()=>{\n const fileName = \"web-noise-project.json\";\n const projectState = getProject();\n const data = {\n ...projectState\n };\n (0, $7gk4U$jsfiledownload)(JSON.stringify(data, null, 2), fileName);\n }, [\n getEditorState,\n reactFlowInstance\n ]);\n (0, $7gk4U$useEffect)(()=>{\n (0, $7gk4U$hotkeysjs)(\"command+shift+a\", ()=>{\n addNodeHandler(200, 50);\n return false;\n });\n //@TODO: find more elegant way to handle ?\n (0, $7gk4U$hotkeysjs)(\"shift+/\", ()=>{\n toggleHelp();\n return false;\n });\n (0, $7gk4U$hotkeysjs)(\"command+z\", ()=>{\n historyBack();\n return false;\n });\n (0, $7gk4U$hotkeysjs)(\"command+shift+z\", ()=>{\n historyForward();\n return false;\n });\n (0, $7gk4U$hotkeysjs)(\"command+c\", ()=>{\n copySelectedItems();\n return false;\n });\n (0, $7gk4U$hotkeysjs)(\"command+v\", ()=>{\n pasteBufferHandler({\n x: 200,\n y: 50\n });\n return false;\n });\n return ()=>{\n (0, $7gk4U$hotkeysjs).unbind();\n };\n }, [\n addNodeHandler,\n pasteBufferHandler\n ]);\n return (0, $7gk4U$jsxs)((0, $7gk4U$Fragment), {\n children: [\n (0, $7gk4U$jsx)((0, $40a10d78b6fcf12b$export$2e2bcd8739ae039), {\n isOpen: showAddNode,\n closeMenu: ()=>setShowAddNode(false),\n mousePosition: mousePosition\n }),\n (0, $7gk4U$jsx)((0, $d972aef931806fef$export$2e2bcd8739ae039), {\n isOpen: showUploadPatch,\n closeMenu: ()=>setShowUploadPatch(false)\n }),\n (0, $7gk4U$jsx)((0, $6ca12aedd96d72f9$export$2e2bcd8739ae039), {\n isOpen: showUploadProject,\n closeMenu: ()=>setShowUploadProject(false)\n }),\n (0, $7gk4U$jsx)((0, $7202e5658c6247ad$export$2e2bcd8739ae039), {\n isOpen: showUploadAudio,\n closeMenu: ()=>setShowUploadAudio(false)\n }),\n (0, $7gk4U$jsxs)((0, $3c9d01d27d4be45b$export$98eff9c5659394e3), {\n id: $cc36fc9d90ce018d$export$d4cd258d01c03112,\n animation: false,\n colors: theme.colors,\n children: [\n (0, $7gk4U$jsx)((0, $3c9d01d27d4be45b$export$ef9839ae55b8ba40), {\n onClick: ({ triggerEvent: { clientX: clientX, clientY: clientY } })=>addNodeHandler(clientX, clientY),\n children: \"Add Node (\\u2318+\\u21E7+A)\"\n }),\n (0, $7gk4U$jsx)((0, $7gk4U$Separator), {}),\n (0, $7gk4U$jsx)((0, $3c9d01d27d4be45b$export$ef9839ae55b8ba40), {\n onClick: deleteAllHandler,\n children: \"Delete All\"\n }),\n (0, $7gk4U$jsx)((0, $7gk4U$Separator), {}),\n (0, $7gk4U$jsx)((0, $3c9d01d27d4be45b$export$ef9839ae55b8ba40), {\n onClick: downloadPatchHandler,\n children: \"Download patch\"\n }),\n (0, $7gk4U$jsx)((0, $3c9d01d27d4be45b$export$ef9839ae55b8ba40), {\n onClick: ()=>setShowUploadPatch(true),\n children: \"Upload patch\"\n }),\n (0, $7gk4U$jsx)((0, $7gk4U$Separator), {}),\n (0, $7gk4U$jsx)((0, $3c9d01d27d4be45b$export$ef9839ae55b8ba40), {\n onClick: downloadProjectHandler,\n children: \"Download project\"\n }),\n (0, $7gk4U$jsx)((0, $3c9d01d27d4be45b$export$ef9839ae55b8ba40), {\n onClick: ()=>setShowUploadProject(true),\n children: \"Upload project\"\n }),\n (0, $7gk4U$jsx)((0, $7gk4U$Separator), {}),\n (0, $7gk4U$jsx)((0, $3c9d01d27d4be45b$export$ef9839ae55b8ba40), {\n onClick: ()=>setShowUploadAudio(true),\n children: \"Upload Audio File\"\n }),\n (0, $7gk4U$jsx)((0, $7gk4U$Separator), {}),\n (0, $7gk4U$jsx)((0, $3c9d01d27d4be45b$export$ef9839ae55b8ba40), {\n disabled: historyPointer === 0,\n onClick: historyBack,\n children: \"Undo (\\u2318+z)\"\n }),\n (0, $7gk4U$jsx)((0, $3c9d01d27d4be45b$export$ef9839ae55b8ba40), {\n disabled: historyPointer === historyBuffer.length,\n onClick: historyForward,\n children: \"Redo (\\u2318+\\u21E7+Z)\"\n }),\n (0, $7gk4U$jsx)((0, $7gk4U$Separator), {}),\n (0, $7gk4U$jsx)((0, $3c9d01d27d4be45b$export$ef9839ae55b8ba40), {\n disabled: !selectedNodes.length,\n onClick: copySelectedItems,\n children: \"Copy Selected (\\u2318+c)\"\n }),\n (0, $7gk4U$jsx)((0, $3c9d01d27d4be45b$export$ef9839ae55b8ba40), {\n disabled: !currentCopyBuffer.nodes.length,\n onClick: ({ triggerEvent: { clientX: x, clientY: y } })=>pasteBufferHandler({\n x: x,\n y: y\n }),\n children: \"Paste (\\u2318+v)\"\n }),\n (0, $7gk4U$jsx)((0, $7gk4U$Separator), {}),\n editorContextMenu.map((item, index)=>(0, $7gk4U$jsx)((0, $3c9d01d27d4be45b$export$ef9839ae55b8ba40), {\n children: item\n }, index)),\n (0, $7gk4U$jsx)((0, $7gk4U$Separator), {}),\n (0, $7gk4U$jsx)((0, $3c9d01d27d4be45b$export$ef9839ae55b8ba40), {\n onClick: toggleHelp,\n children: \"Help (\\u21E7+?)\"\n })\n ]\n })\n ]\n });\n};\nvar $cc36fc9d90ce018d$export$2e2bcd8739ae039 = $cc36fc9d90ce018d$var$EditorContextMenu;\n\n\n\n\n\n\n\n\n\nconst $2deaca6d9e341a8a$export$d4cd258d01c03112 = \"editor-node-menu\";\nconst $2deaca6d9e341a8a$export$cbbbfb9fb15f3780 = ()=>{\n const { show: show } = (0, $7gk4U$useContextMenu)({\n id: $2deaca6d9e341a8a$export$d4cd258d01c03112\n });\n const onContextMenu = (0, $7gk4U$useCallback)((event, node)=>{\n event.stopPropagation();\n show(event, {\n props: {\n node: node\n }\n });\n }, []);\n return {\n onContextMenu: onContextMenu\n };\n};\nconst $2deaca6d9e341a8a$var$NodeContextMenu = (args)=>{\n const theme = (0, $abd71d53b289d0e8$export$2e2bcd8739ae039)();\n const removeNodes = (0, $5b293d93bfa5f38a$export$2e2bcd8739ae039)((store)=>store.removeNodes);\n const addNodeToControlPanel = (0, $5b293d93bfa5f38a$export$2e2bcd8739ae039)((store)=>store.addNodeToControlPanel);\n const removeNodeFromControlPanel = (0, $5b293d93bfa5f38a$export$2e2bcd8739ae039)((store)=>store.removeNodeFromControlPanel);\n const copy = (0, $5b293d93bfa5f38a$export$2e2bcd8739ae039)((store)=>store.copy);\n const nodesConfiguration = (0, $5b293d93bfa5f38a$export$2e2bcd8739ae039)((store)=>store.nodesConfiguration);\n const controlPanelNodes = (0, $5b293d93bfa5f38a$export$2e2bcd8739ae039)((store)=>store.controlPanel.nodes);\n const isOnControlPanel = (0, $7gk4U$useCallback)(({ props: props })=>{\n if (!props?.node.type) return false;\n return !!controlPanelNodes.find(({ id: id })=>id === props.node.id);\n }, [\n controlPanelNodes\n ]);\n const hasControlPanelNode = (0, $7gk4U$useCallback)(({ props: props })=>{\n if (!props?.node.type) return false;\n const nodeConfiguration = nodesConfiguration[props.node.type];\n return !!nodeConfiguration?.controlPanelNode;\n }, [\n nodesConfiguration\n ]);\n return (0, $7gk4U$jsx)((0, $7gk4U$Fragment), {\n children: (0, $7gk4U$jsxs)((0, $3c9d01d27d4be45b$export$98eff9c5659394e3), {\n id: $2deaca6d9e341a8a$export$d4cd258d01c03112,\n animation: false,\n colors: theme.colors,\n children: [\n (0, $7gk4U$jsx)((0, $3c9d01d27d4be45b$export$ef9839ae55b8ba40), {\n onClick: (event)=>removeNodes([\n event.props.node\n ]),\n children: \"Delete Node (DEL)\"\n }),\n (0, $7gk4U$jsx)((0, $3c9d01d27d4be45b$export$ef9839ae55b8ba40), {\n hidden: (...args)=>!hasControlPanelNode(...args) || isOnControlPanel(...args),\n onClick: (event)=>addNodeToControlPanel(event.props.node),\n children: \"Add To Control Panel\"\n }),\n (0, $7gk4U$jsx)((0, $3c9d01d27d4be45b$export$ef9839ae55b8ba40), {\n hidden: (...args)=>!hasControlPanelNode(...args) || !isOnControlPanel(...args),\n onClick: (event)=>removeNodeFromControlPanel(event.props.node),\n children: \"Remove From Control Panel\"\n }),\n (0, $7gk4U$jsx)((0, $3c9d01d27d4be45b$export$ef9839ae55b8ba40), {\n onClick: (event)=>copy({\n nodes: [\n event.props.node\n ],\n edges: []\n }),\n children: \"Copy (\\u2318+c)\"\n })\n ]\n })\n });\n};\nvar $2deaca6d9e341a8a$export$2e2bcd8739ae039 = $2deaca6d9e341a8a$var$NodeContextMenu;\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nconst $116798c46fe901a8$var$useAudioNode = (id)=>{\n const patch = (0, $5b293d93bfa5f38a$export$2e2bcd8739ae039)(({ patch: patch })=>patch);\n return patch.audioNodes.get(id);\n};\nvar $116798c46fe901a8$export$2e2bcd8739ae039 = $116798c46fe901a8$var$useAudioNode;\n\n\n\n\nconst $4ac8d6fa24cea4dc$var$useNode = (id)=>{\n const updateNodeData = (0, $5b293d93bfa5f38a$export$2e2bcd8739ae039)(({ updateNodeData: updateNodeData })=>updateNodeData);\n const updateNodeValues = (0, $7gk4U$useCallback)((values)=>updateNodeData(id, {\n values: values\n }), [\n id,\n updateNodeData\n ]);\n const updateNodeConfig = (0, $7gk4U$useCallback)((config)=>updateNodeData(id, {\n config: config\n }), [\n id,\n updateNodeData\n ]);\n const updateNodeLabel = (0, $7gk4U$useCallback)((label)=>updateNodeData(id, {\n label: label\n }), [\n id,\n updateNodeData\n ]);\n return {\n updateNodeValues: updateNodeValues,\n updateNodeConfig: updateNodeConfig,\n updateNodeLabel: updateNodeLabel\n };\n};\nvar $4ac8d6fa24cea4dc$export$2e2bcd8739ae039 = $4ac8d6fa24cea4dc$var$useNode;\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nconst $7a796029b1c3cc22$export$5abe11f802ebd1f2 = (0, $7gk4U$emotionstyled).input`\n width: 100%;\n background: none;\n border: none;\n text-align: center;\n color: var(--leva-colors-highlight1);\n font-family: var(--leva-fonts-mono);\n font-size: var(--leva-fontSizes-root);\n cursor: inherit;\n text-overflow: ellipsis;\n outline: none;\n\n &:focus {\n box-shadow: 0 0 0 green var(--leva-colors-accent2);\n }\n &:focus-within {\n box-shadow: 0 0 0 green var(--leva-colors-accent2);\n }\n &:focus-vissible {\n box-shadow: 0 0 0 green var(--leva-colors-accent2);\n }\n &:not([readonly]):focus {\n color: #fff;\n appearance: none;\n cursor: auto;\n background-color: var(--leva-colors-elevation2);\n padding: 0.3rem;\n border-radius: 0.2rem;\n }\n`;\nconst $7a796029b1c3cc22$var$EditableLabel = ({ onChange: onChange, value: value = \"\", className: className })=>{\n const labelInputRef = (0, $7gk4U$useRef)(null);\n const [labelEditMode, setLabelEditMode] = (0, $7gk4U$useState)(false);\n const editNodeLabel = (0, $7gk4U$useCallback)((event)=>{\n //@ts-ignore\n event.target?.select();\n setLabelEditMode(true);\n }, [\n setLabelEditMode\n ]);\n const exitEditMode = (0, $7gk4U$useCallback)(()=>{\n window.getSelection()?.collapseToEnd();\n setLabelEditMode(false);\n }, [\n setLabelEditMode\n ]);\n const saveNodeLabel = (0, $7gk4U$useCallback)(()=>{\n exitEditMode();\n if (labelInputRef.current) onChange(labelInputRef.current.value);\n }, [\n labelInputRef,\n exitEditMode,\n onChange\n ]);\n const cancelNodeLabelEdit = (0, $7gk4U$useCallback)(()=>{\n exitEditMode();\n if (labelInputRef.current && value) labelInputRef.current.value = value;\n }, [\n labelInputRef,\n exitEditMode,\n value\n ]);\n (0, $7gk4U$useEffect)(()=>{\n if (!labelInputRef.current) return;\n labelInputRef.current.value = value;\n }, [\n value,\n labelInputRef\n ]);\n return (0, $7gk4U$jsx)($7a796029b1c3cc22$export$5abe11f802ebd1f2, {\n ref: labelInputRef,\n type: \"text\",\n readOnly: !labelEditMode,\n onDoubleClick: (event)=>editNodeLabel(event),\n onBlur: saveNodeLabel,\n onKeyDown: (event)=>{\n switch(event.key){\n case \"Escape\":\n cancelNodeLabelEdit();\n break;\n case \"Enter\":\n saveNodeLabel();\n break;\n }\n },\n className: className\n });\n};\nvar $7a796029b1c3cc22$export$2e2bcd8739ae039 = $7a796029b1c3cc22$var$EditableLabel;\n\n\n\n\n\n\n\n\n\nconst $54aa58cab5d483cd$var$NodeInfoWrapper = (0, $7gk4U$withTheme)((0, $7gk4U$emotionstyled).div`\n height: 100%;\n width: 100%;\n overflow: scroll;\n padding: 0.6rem;\n box-sizing: border-box;\n\n hr {\n border: none;\n border-bottom: 1px solid ${({ theme: theme })=>theme.colors.elevation3};\n }\n\n code {\n background-color: ${({ theme: theme })=>theme.colors.elevation3};\n color: ${({ theme: theme })=>theme.colors.highlight3};\n font-family:\n source-code-pro, Menlo, Monaco, Consolas, \"Courier New\", monospace;\n }\n\n pre {\n background-color: ${({ theme: theme })=>theme.colors.elevation3};\n padding: 0.2rem 0.3rem;\n border-radius: 1px;\n }\n\n a {\n color: ${({ theme: theme })=>theme.colors.accent1};\n }\n`);\nconst $54aa58cab5d483cd$var$useNodeManifest = (type)=>{\n const data = (0, $5b293d93bfa5f38a$export$2e2bcd8739ae039)((store)=>store.nodesConfiguration[type]);\n return data;\n};\nconst $54aa58cab5d483cd$var$NodeInfoModal = ({ isOpen: isOpen, onClose: onClose, type: nodeType, node: node })=>{\n const { info: info, portsDescription: portsDescription } = $54aa58cab5d483cd$var$useNodeManifest(nodeType);\n const portsInfo = (0, $7gk4U$useMemo)(()=>{\n const parts = [];\n const inputPorts = node.inputs;\n if (inputPorts) {\n parts.push(`## Inputs`);\n for(const portName in inputPorts){\n const port = inputPorts[portName];\n parts.push(`### *${portName}*`);\n const description = portsDescription?.inputs?.[portName];\n if (description) parts.push(description);\n if (Array.isArray(port.type)) parts.push(`**Types**: \\`${port.type.join(\", \")}\\``);\n else parts.push(`**Type**: \\`${port.type || \"unknown\"}\\``);\n if (port.range) parts.push(`**Range**: \\`[${port.range[0]}, ${port.range[1]}]\\``);\n if (port.defaultValue !== undefined) parts.push(`**Default**: \\`${port.defaultValue}\\``);\n }\n }\n const outputPorts = node.outputs;\n if (outputPorts) {\n parts.push(`## Outputs`);\n for(const portName in outputPorts){\n const port = outputPorts[portName];\n parts.push(`### *${portName}*`);\n const description = portsDescription?.outputs?.[portName];\n if (description) parts.push(description);\n if (Array.isArray(port.type)) parts.push(`**Types**: \\`${port.type.join(\", \")}\\``);\n else parts.push(`**Type**: \\`${port.type || \"unknown\"}\\``);\n if (port.range) parts.push(`**Range**: \\`[${port.range[0]}, ${port.range[1]}]\\``);\n if (port.defaultValue !== undefined) parts.push(`**Default**: \\`${port.defaultValue}\\``);\n }\n }\n return parts.join(\"\\n\\n\");\n }, [\n node,\n portsDescription\n ]);\n const combinedInfo = (info || \"\") + \"\\n\\n\" + portsInfo;\n return isOpen ? (0, $7gk4U$jsx)((0, $4001d24decbb98f7$export$2e2bcd8739ae039), {\n onClose: onClose,\n children: (0, $7gk4U$jsx)($54aa58cab5d483cd$var$NodeInfoWrapper, {\n dangerouslySetInnerHTML: {\n __html: (0, $7gk4U$marked)(combinedInfo || \"\")\n }\n })\n }) : null;\n};\nvar $54aa58cab5d483cd$export$2e2bcd8739ae039 = $54aa58cab5d483cd$var$NodeInfoModal;\n\n\nconst $8ac710fa6e4a22e6$var$NodeWrapper = (0, $7gk4U$emotionstyled).div`\n background-color: var(--leva-colors-elevation1);\n`;\nconst $8ac710fa6e4a22e6$var$NodeLoaderWrapper = (0, $7gk4U$emotionstyled)($8ac710fa6e4a22e6$var$NodeWrapper)`\n padding: 2rem 5rem;\n`;\nconst $8ac710fa6e4a22e6$var$NodeErrorWrapper = (0, $7gk4U$emotionstyled)($8ac710fa6e4a22e6$var$NodeWrapper)`\n padding: 1rem 2rem;\n`;\nconst $8ac710fa6e4a22e6$var$SettingsIconWrapper = (0, $7gk4U$emotionstyled)((0, $7gk4U$MdSettings))`\n font-size: 1.2rem;\n opacity: 0.4;\n width: 1rem;\n &:hover {\n opacity: 1;\n cursor: pointer;\n }\n`;\nconst $8ac710fa6e4a22e6$var$InfoIconWrapper = (0, $7gk4U$emotionstyled)((0, $7gk4U$MdInfoOutline))`\n font-size: 1.2rem;\n opacity: 0.4;\n width: 1rem;\n &:hover {\n opacity: 1;\n cursor: pointer;\n }\n`;\nconst $8ac710fa6e4a22e6$var$Section = (0, $7gk4U$emotionstyled).div`\n position: relative;\n font-family: var(--leva-fonts-mono);\n font-size: var(--leva-fontSizes-root);\n background-color: var(--leva-colors-elevation1);\n`;\nconst $8ac710fa6e4a22e6$export$1bdb8f2d1fe25c22 = (0, $7gk4U$emotionstyled)($8ac710fa6e4a22e6$var$Section)`\n display: flex;\n height: var(--leva-sizes-titleBarHeight);\n touch-action: none;\n align-items: center;\n justify-content: center;\n flex: 1 1 0%;\n color: var(--leva-colors-highlight1);\n padding: 0 0.4rem;\n gap: 0.3rem;\n`;\nconst $8ac710fa6e4a22e6$export$bfd3bd1fa283e3c6 = (0, $7gk4U$emotionstyled)($8ac710fa6e4a22e6$var$Section)(({ theme: theme })=>`\n display: grid;\n grid-template-areas: \"inputs outputs\";\n background: ${theme.colors.elevation2};\n border-bottom: 1px solid ${theme.colors.elevation1};\n color: ${theme.colors.highlight3};\n font-size: 0.6rem;\n`);\nconst $8ac710fa6e4a22e6$export$f1afba0ff9ea1277 = (0, $7gk4U$emotionstyled).div`\n grid-area: inputs;\n text-align: left;\n`;\nconst $8ac710fa6e4a22e6$export$af4f9b41fc32ed9e = (0, $7gk4U$emotionstyled).div`\n grid-area: outputs;\n text-align: right;\n`;\nconst $8ac710fa6e4a22e6$export$a2d375858cc72119 = (0, $7gk4U$emotionstyled).div`\n position: relative;\n padding: 5px 10px;\n`;\nconst $8ac710fa6e4a22e6$var$portColors = {\n [(0, $fcabc075f2eebe7f$export$b0b7b95ee465c83c).Audio]: \"#4ade80\",\n [(0, $fcabc075f2eebe7f$export$b0b7b95ee465c83c).Gate]: \"#c084fc\",\n [(0, $fcabc075f2eebe7f$export$b0b7b95ee465c83c).Number]: \"#38bdf8\",\n [(0, $fcabc075f2eebe7f$export$b0b7b95ee465c83c).Any]: \"#ffffff\"\n};\nconst $8ac710fa6e4a22e6$var$StyledHandle = (0, $7gk4U$withTheme)((0, $7gk4U$emotionstyled)((0, $7gk4U$Handle), {\n shouldForwardProp: (prop)=>prop !== \"portType\"\n})`\n --port-color: ${(props)=>{\n if (!props.portType) return props.theme.colors.highlight2;\n if (Array.isArray(props.portType)) {\n const colors = props.portType.map((type)=>$8ac710fa6e4a22e6$var$portColors[type]);\n return `linear-gradient(0.25turn, ${colors.join(\", \")});`;\n } else return $8ac710fa6e4a22e6$var$portColors[props.portType];\n}};\n border-color: var(--port-color);\n background: var(--port-color);\n box-shadow: 0px 0px 0px 1px ${({ theme: theme })=>theme.colors.elevation2} inset;\n`);\nconst $8ac710fa6e4a22e6$var$StyledInputHandle = (0, $7gk4U$withTheme)((0, $7gk4U$emotionstyled)($8ac710fa6e4a22e6$var$StyledHandle)`\n left: -3px;\n`);\nconst $8ac710fa6e4a22e6$export$9ea0feffc20ee81 = ({ ...props })=>(0, $7gk4U$jsx)($8ac710fa6e4a22e6$var$StyledInputHandle, {\n ...props,\n type: \"target\",\n position: (0, $7gk4U$Position).Left\n });\nconst $8ac710fa6e4a22e6$export$222539e2a2fac4e0 = (0, $7gk4U$withTheme)((0, $7gk4U$emotionstyled)($8ac710fa6e4a22e6$var$StyledHandle)`\n right: -3px;\n`);\nconst $8ac710fa6e4a22e6$export$496e5e1ee1696f64 = (props)=>(0, $7gk4U$jsx)($8ac710fa6e4a22e6$export$222539e2a2fac4e0, {\n ...props,\n type: \"source\",\n position: (0, $7gk4U$Position).Right\n });\nconst $8ac710fa6e4a22e6$export$7e0b3af1e60a3273 = ({ className: className, ...props })=>(0, $7gk4U$jsx)($8ac710fa6e4a22e6$export$1bdb8f2d1fe25c22, {\n ...props,\n className: [\n className,\n (0, $fcabc075f2eebe7f$export$956b3cf15d7c363)\n ].join(\" \")\n });\nconst $8ac710fa6e4a22e6$var$useNodeManifest = (type)=>{\n const data = (0, $5b293d93bfa5f38a$export$2e2bcd8739ae039)((store)=>store.nodesConfiguration[type]);\n return data;\n};\nconst $8ac710fa6e4a22e6$var$useConfigNode = (type)=>{\n const { configNode: ConfigNode } = $8ac710fa6e4a22e6$var$useNodeManifest(type);\n return {\n ConfigNode: ConfigNode\n };\n};\nconst $8ac710fa6e4a22e6$export$361064385d50ec44 = (props)=>{\n const { id: id, children: children, selected: selected, ...rest } = props;\n const theme = (0, $abd71d53b289d0e8$export$2e2bcd8739ae039)();\n const getNode = (0, $5b293d93bfa5f38a$export$2e2bcd8739ae039)(({ getNode: getNode })=>getNode);\n const nodesConfiguration = (0, $5b293d93bfa5f38a$export$2e2bcd8739ae039)((store)=>store.nodesConfiguration);\n const [isInfoModalShown, setIsInfoModalShown] = (0, $7gk4U$useState)(false);\n const { info: info } = $8ac710fa6e4a22e6$var$useNodeManifest(props.type);\n const isResizeable = (0, $7gk4U$useMemo)(()=>nodesConfiguration[props.type].resizable ?? false, [\n nodesConfiguration,\n props.type\n ]);\n const { updateNodeLabel: updateNodeLabel, updateNodeConfig: updateNodeConfig } = (0, $4ac8d6fa24cea4dc$export$2e2bcd8739ae039)(id);\n const { data: data } = getNode(id) || {};\n const audioNode = (0, $116798c46fe901a8$export$2e2bcd8739ae039)(id);\n const { ConfigNode: ConfigNode } = $8ac710fa6e4a22e6$var$useConfigNode(rest.type);\n const [configMode, setShowConfigMode] = (0, $7gk4U$useState)(false);\n if (!audioNode) return (0, $7gk4U$jsx)($8ac710fa6e4a22e6$var$NodeLoaderWrapper, {\n className: (0, $fcabc075f2eebe7f$export$956b3cf15d7c363),\n children: \"can't find audio node\"\n });\n if (audioNode.loading) return (0, $7gk4U$jsx)($8ac710fa6e4a22e6$var$NodeLoaderWrapper, {\n className: (0, $fcabc075f2eebe7f$export$956b3cf15d7c363),\n children: \"loading\"\n });\n if (audioNode.error) return (0, $7gk4U$jsxs)($8ac710fa6e4a22e6$var$NodeErrorWrapper, {\n className: (0, $fcabc075f2eebe7f$export$956b3cf15d7c363),\n children: [\n \"error: \",\n audioNode.error.toString()\n ]\n });\n if (!audioNode.node) return (0, $7gk4U$jsx)($8ac710fa6e4a22e6$var$NodeLoaderWrapper, {\n className: (0, $fcabc075f2eebe7f$export$956b3cf15d7c363),\n children: \"can't find audio node\"\n });\n const size = data?.config?.size;\n const { node: { inputs: inputs, outputs: outputs } } = audioNode;\n return (0, $7gk4U$jsxs)($8ac710fa6e4a22e6$var$NodeWrapper, {\n children: [\n (0, $7gk4U$jsxs)($8ac710fa6e4a22e6$export$7e0b3af1e60a3273, {\n children: [\n info && (0, $7gk4U$jsx)($8ac710fa6e4a22e6$var$InfoIconWrapper, {\n onClickCapture: ()=>setIsInfoModalShown(true)\n }),\n (0, $7gk4U$jsx)((0, $7a796029b1c3cc22$export$2e2bcd8739ae039), {\n value: data?.label ?? \"No Name\",\n onChange: updateNodeLabel\n }),\n ConfigNode && (0, $7gk4U$jsx)($8ac710fa6e4a22e6$var$SettingsIconWrapper, {\n onClickCapture: ()=>setShowConfigMode((isShown)=>!isShown)\n })\n ]\n }),\n (0, $7gk4U$jsxs)($8ac710fa6e4a22e6$export$bfd3bd1fa283e3c6, {\n theme: theme,\n children: [\n (0, $7gk4U$jsx)($8ac710fa6e4a22e6$export$f1afba0ff9ea1277, {\n children: inputs ? Object.keys(inputs).map((key, index)=>(0, $7gk4U$jsxs)($8ac710fa6e4a22e6$export$a2d375858cc72119, {\n children: [\n (0, $7gk4U$jsx)($8ac710fa6e4a22e6$export$9ea0feffc20ee81, {\n id: key,\n portType: inputs[key].type\n }),\n (0, $7gk4U$jsx)(\"span\", {\n children: key\n })\n ]\n }, index)) : null\n }),\n (0, $7gk4U$jsx)($8ac710fa6e4a22e6$export$af4f9b41fc32ed9e, {\n children: outputs ? Object.keys(outputs).map((key, index)=>(0, $7gk4U$jsxs)($8ac710fa6e4a22e6$export$a2d375858cc72119, {\n children: [\n (0, $7gk4U$jsx)($8ac710fa6e4a22e6$export$496e5e1ee1696f64, {\n id: key,\n portType: outputs[key].type\n }),\n (0, $7gk4U$jsx)(\"span\", {\n children: key\n })\n ]\n }, index)) : null\n })\n ]\n }),\n ConfigNode && configMode && selected ? (0, $7gk4U$jsx)(ConfigNode, {\n ...props\n }) : isResizeable ? (0, $7gk4U$jsx)((0, $7gk4U$Resizable), {\n size: size,\n minWidth: 180,\n minHeight: 30,\n enable: {\n bottom: true,\n bottomRight: true,\n right: true\n },\n onResizeStop: (e, direction, ref, d)=>{\n const newSize = size ? {\n width: size.width + d.width,\n height: size.height + d.height\n } : ref.getBoundingClientRect();\n updateNodeConfig({\n ...data?.config,\n size: newSize\n });\n },\n children: children\n }) : children,\n (0, $7gk4U$jsx)((0, $54aa58cab5d483cd$export$2e2bcd8739ae039), {\n isOpen: isInfoModalShown,\n type: props.type,\n onClose: ()=>setIsInfoModalShown(false),\n node: audioNode.node\n })\n ]\n });\n};\n\n\nconst $6645e9588375d2aa$export$86de09faaa70680d = (0, $7gk4U$emotionstyled).div`\n width: 100%;\n padding: 0.4rem 0;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n`;\nconst $6645e9588375d2aa$export$548ca3bae446ddc2 = (0, $7gk4U$emotionstyled)((0, $8ac710fa6e4a22e6$export$7e0b3af1e60a3273))`\n display: flex;\n gap: 0.1rem;\n padding: 0 0.4rem;\n justify-content: start;\n font-size: 0.6rem;\n height: auto;\n min-width: 0;\n`;\nconst $6645e9588375d2aa$export$9fb15e3cc717240 = (0, $7gk4U$emotionstyled).div`\n display: flex;\n align-items: center;\n height: 70%;\n width: auto;\n gap: 0.4rem;\n`;\nconst $6645e9588375d2aa$export$be58b4326e23250f = (0, $7gk4U$emotionstyled).span`\n width: auto;\n height: 100%;\n cursor: pointer;\n svg {\n width: auto;\n height: 100%;\n }\n &:hover {\n color: ${({ theme: theme })=>theme.colors.highlight2};\n cursor: pointer;\n }\n`;\n\n\nconst $4e1e3f967fa555cc$var$ControlPanelNodeWrapper = (0, $7gk4U$emotionstyled).div`\n height: 100%;\n display: grid;\n grid-template-rows: auto 1fr;\n`;\nconst $4e1e3f967fa555cc$var$PanelNode = (props)=>{\n const { node: node } = props;\n const getControlPanelNode = (0, $5b293d93bfa5f38a$export$2e2bcd8739ae039)((store)=>store.getControlPanelNode);\n const ControlPanelNode = (0, $7gk4U$useMemo)(()=>getControlPanelNode(node), [\n node\n ]);\n if (!ControlPanelNode) return null;\n return (0, $7gk4U$jsx)(ControlPanelNode, {\n ...props\n });\n};\nconst $4e1e3f967fa555cc$var$ControlPanelItem = (props)=>{\n const { node: node, showControls: showControls, onDelete: onDelete } = props;\n const theme = (0, $abd71d53b289d0e8$export$2e2bcd8739ae039)();\n const { id: id } = node;\n const { node: audioNode } = (0, $116798c46fe901a8$export$2e2bcd8739ae039)(id) || {};\n const { updateNodeValues: updateNodeValues } = (0, $4ac8d6fa24cea4dc$export$2e2bcd8739ae039)(id);\n return (0, $7gk4U$jsxs)($4e1e3f967fa555cc$var$ControlPanelNodeWrapper, {\n theme: theme,\n children: [\n (0, $7gk4U$jsxs)((0, $6645e9588375d2aa$export$548ca3bae446ddc2), {\n theme: theme,\n children: [\n (0, $7gk4U$jsx)((0, $6645e9588375d2aa$export$86de09faaa70680d), {\n children: node.data.label\n }),\n showControls && (0, $7gk4U$jsxs)((0, $6645e9588375d2aa$export$9fb15e3cc717240), {\n children: [\n (0, $7gk4U$jsx)((0, $6645e9588375d2aa$export$be58b4326e23250f), {\n theme: theme,\n children: (0, $7gk4U$jsx)((0, $7gk4U$MdDragHandle), {\n className: \"grid-item-handle\"\n })\n }),\n (0, $7gk4U$jsx)((0, $6645e9588375d2aa$export$be58b4326e23250f), {\n theme: theme,\n children: (0, $7gk4U$jsx)((0, $7gk4U$MdClose), {\n onClick: ()=>onDelete(node)\n })\n })\n ]\n })\n ]\n }),\n (0, $7gk4U$jsx)($4e1e3f967fa555cc$var$PanelNode, {\n node: node,\n audioNode: audioNode,\n updateNodeValues: updateNodeValues\n })\n ]\n });\n};\nvar $4e1e3f967fa555cc$export$2e2bcd8739ae039 = $4e1e3f967fa555cc$var$ControlPanelItem;\n\n\n\nconst $3bd5bd72a0abfb9c$var$ControlPanelIconWrapper = (0, $7gk4U$emotionstyled).div`\n position: fixed;\n z-index: 5;\n box-shadow: 0px 1px 2px ${({ theme: theme })=>theme.colors.elevation2};\n left: 1rem;\n top: 4rem;\n width: 2rem;\n height: 2rem;\n border-radius: 50%;\n overflow: hidden;\n display: flex;\n align-items: center;\n justify-content: center;\n background: ${({ theme: theme })=>theme.colors.elevation1};\n color: ${({ theme: theme })=>theme.colors.highlight1};\n\n :hover {\n color: ${({ theme: theme })=>theme.colors.highlight2};\n cursor: pointer;\n }\n`;\nconst $3bd5bd72a0abfb9c$var$ControlPanelIconsBar = (0, $7gk4U$emotionstyled)((0, $6645e9588375d2aa$export$9fb15e3cc717240))`\n height: 80%;\n`;\nconst $3bd5bd72a0abfb9c$var$CloseIconWrapper = (0, $7gk4U$emotionstyled)((0, $6645e9588375d2aa$export$be58b4326e23250f))`\n font-size: 1rem;\n display: flex;\n align-items: center;\n`;\nconst $3bd5bd72a0abfb9c$var$ControlPanelHeader = (0, $7gk4U$emotionstyled)((0, $6645e9588375d2aa$export$548ca3bae446ddc2))`\n grid-template-columns: 1fr auto;\n border-bottom: 1px solid ${({ theme: theme })=>theme.colors.elevation3};\n font-size: 0.7rem;\n`;\nconst $3bd5bd72a0abfb9c$var$ControlPanelTitle = (0, $7gk4U$emotionstyled)((0, $6645e9588375d2aa$export$86de09faaa70680d))`\n text-align: center;\n`;\nconst $3bd5bd72a0abfb9c$var$ControlPanelWrapper = (0, $7gk4U$emotionstyled).div`\n height: 100%;\n width: 100%;\n padding: 0.3rem 0.4rem;\n box-sizing: border-box;\n`;\nconst $3bd5bd72a0abfb9c$var$ControlPanelBody = (0, $7gk4U$emotionstyled).div`\n height: auto;\n padding: 0;\n max-height: 95vh;\n overflow-y: scroll;\n border: 1px solid ${({ theme: theme })=>theme.colors.elevation3};\n`;\nconst $3bd5bd72a0abfb9c$var$ControlPanelSettings = (0, $7gk4U$emotionstyled).div`\n padding: 1rem 0;\n font-family: var(--leva-fonts-mono);\n font-size: 0.8rem;\n`;\nconst $3bd5bd72a0abfb9c$var$LockGridWrapper = (0, $7gk4U$emotionstyled).div`\n display: flex;\n align-items: center;\n gap: 0.5rem;\n cursor: pointer;\n color: ${({ theme: theme })=>theme.colors.highlight1};\n &:hover {\n color: ${({ theme: theme })=>theme.colors.highlight2};\n }\n`;\nconst $3bd5bd72a0abfb9c$var$GridResizeHandle = (0, $7gk4U$emotionstyled).div`\n position: absolute;\n height: 1rem;\n top: 0;\n bottom: 0;\n margin: auto;\n left: 0.5rem;\n border-right: 1px solid ${({ theme: theme })=>theme.colors.whitePrimary};\n`;\nconst $3bd5bd72a0abfb9c$var$ControlPanelItemWrapper = (0, $7gk4U$emotionstyled).div`\n box-sizing: border-box;\n overflow: hidden;\n .react-resizable-handle:after {\n border-color: ${({ theme: theme })=>theme.colors.whitePrimary};\n border-width: 1px;\n }\n`;\nconst $3bd5bd72a0abfb9c$var$ControlPanel = ()=>{\n const theme = (0, $abd71d53b289d0e8$export$2e2bcd8739ae039)();\n const nodeRef = (0, $7gk4U$useRef)(null);\n const nodes = (0, $5b293d93bfa5f38a$export$2e2bcd8739ae039)((store)=>store.nodes);\n const { show: show, nodes: controlPanelNodes, size: size } = (0, $5b293d93bfa5f38a$export$2e2bcd8739ae039)((store)=>store.controlPanel);\n const { width: width = 200, height: height } = size;\n const filteredNodes = (0, $7gk4U$useMemo)(()=>{\n const nodeIds = controlPanelNodes.map(({ id: id })=>id);\n return nodes.filter(({ id: id })=>nodeIds.includes(id));\n }, [\n nodes,\n controlPanelNodes\n ]);\n const showControlPanel = (0, $5b293d93bfa5f38a$export$2e2bcd8739ae039)((store)=>store.showControlPanel);\n const hideControlPanel = (0, $5b293d93bfa5f38a$export$2e2bcd8739ae039)((store)=>store.hideControlPanel);\n const setControlPanelNodes = (0, $5b293d93bfa5f38a$export$2e2bcd8739ae039)((store)=>store.setControlPanelNodes);\n const setControlPanelSize = (0, $5b293d93bfa5f38a$export$2e2bcd8739ae039)((store)=>store.setControlPanelSize);\n const removeNodeFromControlPanel = (0, $5b293d93bfa5f38a$export$2e2bcd8739ae039)((store)=>store.removeNodeFromControlPanel);\n const [isGridLocked, setGridLocked] = (0, $7gk4U$useState)(true);\n const layout = (0, $7gk4U$useMemo)(()=>{\n const fallbackY = controlPanelNodes.reduce((acc, { height: height = (0, $fcabc075f2eebe7f$export$9f05d3e6ade4c09e).rowHeight, x: x, y: y = 0 })=>{\n const Y = y + height;\n return Y > acc ? Y : acc;\n }, 0);\n return controlPanelNodes.map(({ id: i, width: width, height: height, x: x, y: y })=>{\n return {\n i: i,\n w: width || (0, $fcabc075f2eebe7f$export$9f05d3e6ade4c09e).cols,\n h: height || 6,\n x: x ?? 0,\n y: y ?? fallbackY\n };\n });\n }, [\n controlPanelNodes\n ]);\n if (!filteredNodes.length) return null;\n return (0, $7gk4U$jsxs)((0, $7gk4U$Fragment), {\n children: [\n (0, $7gk4U$jsx)($3bd5bd72a0abfb9c$var$ControlPanelIconWrapper, {\n theme: theme,\n ref: nodeRef,\n onClick: showControlPanel,\n children: (0, $7gk4U$jsx)((0, $7gk4U$RxDashboard), {})\n }),\n (0, $7gk4U$jsxs)((0, $7gk4U$reactmoderndrawer), {\n open: show,\n onClose: hideControlPanel,\n direction: \"left\",\n className: \"\",\n size: \"auto\",\n enableOverlay: false,\n style: {\n background: theme.colors.elevation1,\n position: \"absolute\"\n },\n children: [\n (0, $7gk4U$jsxs)($3bd5bd72a0abfb9c$var$ControlPanelHeader, {\n theme: theme,\n children: [\n (0, $7gk4U$jsx)($3bd5bd72a0abfb9c$var$ControlPanelTitle, {\n children: \"Control Panel\"\n }),\n (0, $7gk4U$jsx)($3bd5bd72a0abfb9c$var$ControlPanelIconsBar, {\n children: (0, $7gk4U$jsx)($3bd5bd72a0abfb9c$var$CloseIconWrapper, {\n onClick: hideControlPanel,\n theme: theme,\n children: (0, $7gk4U$jsx)((0, $7gk4U$MdClose), {})\n })\n })\n ]\n }),\n (0, $7gk4U$jsxs)($3bd5bd72a0abfb9c$var$ControlPanelWrapper, {\n children: [\n (0, $7gk4U$jsx)($3bd5bd72a0abfb9c$var$ControlPanelSettings, {\n children: isGridLocked ? (0, $7gk4U$jsxs)($3bd5bd72a0abfb9c$var$LockGridWrapper, {\n theme: theme,\n onClick: ()=>setGridLocked(false),\n children: [\n (0, $7gk4U$jsx)((0, $7gk4U$AiFillLock), {}),\n \"Unlock grid\"\n ]\n }) : (0, $7gk4U$jsxs)($3bd5bd72a0abfb9c$var$LockGridWrapper, {\n theme: theme,\n onClick: ()=>setGridLocked(true),\n children: [\n (0, $7gk4U$jsx)((0, $7gk4U$AiFillUnlock), {}),\n \"Lock grid\"\n ]\n })\n }),\n (0, $7gk4U$jsx)((0, $7gk4U$Resizable), {\n enable: {\n top: false,\n right: !isGridLocked,\n bottom: false,\n left: false,\n topRight: false,\n bottomRight: false,\n bottomLeft: false,\n topLeft: false\n },\n handleComponent: {\n right: (0, $7gk4U$jsx)($3bd5bd72a0abfb9c$var$GridResizeHandle, {\n theme: theme\n })\n },\n minWidth: 120,\n size: {\n width: width,\n height: \"auto\"\n },\n onResizeStop: (e, direction, ref, d)=>{\n setControlPanelSize({\n width: width + d.width,\n height: height + d.height\n });\n },\n children: (0, $7gk4U$jsx)($3bd5bd72a0abfb9c$var$ControlPanelBody, {\n theme: theme,\n children: (0, $7gk4U$jsx)((0, $7gk4U$reactgridlayout), {\n layout: layout,\n className: \"layout\",\n cols: (0, $fcabc075f2eebe7f$export$9f05d3e6ade4c09e).cols,\n rowHeight: (0, $fcabc075f2eebe7f$export$9f05d3e6ade4c09e).rowHeight,\n width: width,\n margin: [\n 0,\n 0\n ],\n isResizable: !isGridLocked,\n draggableHandle: \".grid-item-handle\",\n onLayoutChange: (nodes)=>{\n requestAnimationFrame(()=>{\n setControlPanelNodes(nodes.map(({ i: i, w: w, h: h, x: x, y: y })=>({\n id: i,\n width: w,\n height: h,\n x: x,\n y: y\n })));\n });\n },\n children: filteredNodes.map((node)=>{\n return (0, $7gk4U$jsx)($3bd5bd72a0abfb9c$var$ControlPanelItemWrapper, {\n theme: theme,\n children: (0, $7gk4U$jsx)((0, $4e1e3f967fa555cc$export$2e2bcd8739ae039), {\n node: node,\n showControls: !isGridLocked,\n onDelete: removeNodeFromControlPanel\n })\n }, node.id);\n })\n })\n })\n })\n ]\n })\n ]\n })\n ]\n });\n};\nvar $3bd5bd72a0abfb9c$export$2e2bcd8739ae039 = $3bd5bd72a0abfb9c$var$ControlPanel;\n\n\n\n\n\n\n\n\n\n\n\n\nvar $dc393226df3f5796$exports = {};\n$dc393226df3f5796$exports = \"# Quick start\\n\\n## Add node\\n - Mouse right click\\n - Select **'Add Node'** from context menu\\n\\n ### &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;or\\n\\n - Press `CMD+SHIFT+A`\\n\\n<br/>\\n\\n## Connect nodes\\n - Mouse left click and hold on source port\\n - Drop on target port\\n\\n<br/>\\n\\n## Delete Node or Connection\\n - Mouse right click on node/connection\\n - Select **'Delete Node'**/**'Delete Connection'** from context menu\\n\\n ### &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;or\\n\\n - Mouse left click on node/connection, then press `Backspace`\\n\\n<br/>\\n\\n\\n## Move node\\n - Drag and Drop\\n\\n<br/>\\n\\n## Upload file\\n - Drag and drop audio or patch files onto the application\\n - Uploaded file appears as a new tab in the tabs bar at the top\\n - Click on the tab to view or edit the file\\n\\n\\n\";\n\n\nconst $7d01d6ae325614d7$var$MdPreview = (0, $7gk4U$withTheme)((0, $7gk4U$emotionstyled).div`\n font-family: var(--leva-fonts-mono);\n font-size: 0.7rem;\n box-sizing: border-box;\n height: 100%;\n width: 100%;\n overflow: scroll;\n color: ${({ theme: theme })=>theme.colors.whitePrimary};\n padding: 0 0.5rem;\n\n code {\n color: ${({ theme: theme })=>theme.colors.accent3};\n filter: hue-rotate(180deg);\n }\n`);\nconst $7d01d6ae325614d7$var$ModalContent = (0, $7gk4U$withTheme)((0, $7gk4U$emotionstyled).div`\n padding: 1rem;\n height: 100%;\n width: 100%;\n box-sizing: border-box;\n overflow: hidden;\n`);\nconst $7d01d6ae325614d7$var$HelpModal = ()=>{\n const isHelpShown = (0, $5b293d93bfa5f38a$export$2e2bcd8739ae039)((store)=>store.isHelpShown);\n const toggleHelp = (0, $5b293d93bfa5f38a$export$2e2bcd8739ae039)((store)=>store.toggleHelp);\n if (!isHelpShown) return null;\n return (0, $7gk4U$jsx)((0, $4001d24decbb98f7$export$2e2bcd8739ae039), {\n onClose: ()=>{\n toggleHelp();\n },\n children: (0, $7gk4U$jsx)($7d01d6ae325614d7$var$ModalContent, {\n children: (0, $7gk4U$jsx)($7d01d6ae325614d7$var$MdPreview, {\n dangerouslySetInnerHTML: {\n __html: (0, $7gk4U$marked)((0, (/*@__PURE__*/$parcel$interopDefault($dc393226df3f5796$exports))))\n },\n onWheelCapture: (event)=>event.stopPropagation()\n })\n })\n });\n};\nvar $7d01d6ae325614d7$export$2e2bcd8739ae039 = $7d01d6ae325614d7$var$HelpModal;\n\n\nconst $4a7daf9e5da05d43$export$78bddedbcf2939ac = ()=>{\n const toggleHelp = (0, $5b293d93bfa5f38a$export$2e2bcd8739ae039)((store)=>store.toggleHelp);\n return (0, $7gk4U$jsx)((0, $7gk4U$Fragment), {\n children: (0, $7gk4U$jsx)((0, $7gk4U$ControlButton), {\n onClick: toggleHelp,\n children: (0, $7gk4U$jsx)((0, $7gk4U$FaQuestion), {})\n })\n });\n};\n\n\n\n\n\n\n\n\nconst $937b14f51e42c15a$var$Layout = (0, $7gk4U$emotionstyled).div`\n position: fixed;\n z-index: ${({ theme: theme })=>theme.zIndex.resumeContextLayout};\n width: 100%;\n height: 100%;\n top: 0;\n left: 0;\n background: rgb(24 28 32 / 90%);\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: center;\n color: ${({ theme: theme })=>theme.colors.whitePrimary};\n cursor: pointer;\n`;\nconst $937b14f51e42c15a$var$Row = (0, $7gk4U$emotionstyled).div`\n display: flex;\n width: 100%;\n align-items: center;\n justify-content: center;\n`;\nconst $937b14f51e42c15a$var$Message = (0, $7gk4U$emotionstyled).div`\n font-family: var(--leva-fonts-mono);\n font-size: 2rem;\n`;\nconst $937b14f51e42c15a$var$Icon = (0, $7gk4U$emotionstyled)((0, $7gk4U$FaVolumeOff))`\n width: 7rem;\n height: 7rem;\n`;\nconst $937b14f51e42c15a$var$ResumeContext = ()=>{\n const theme = (0, $abd71d53b289d0e8$export$2e2bcd8739ae039)();\n const patch = (0, $5b293d93bfa5f38a$export$2e2bcd8739ae039)(({ patch: patch })=>patch);\n const audioContext = patch.audioContext;\n const [isContextResumed, setIsContextResumed] = (0, $7gk4U$useState)(audioContext.state === \"running\");\n if (isContextResumed) return null;\n return (0, $7gk4U$jsxs)($937b14f51e42c15a$var$Layout, {\n theme: theme,\n onClick: ()=>{\n audioContext.resume();\n setIsContextResumed(true);\n },\n children: [\n (0, $7gk4U$jsx)($937b14f51e42c15a$var$Row, {\n children: (0, $7gk4U$jsx)($937b14f51e42c15a$var$Message, {\n theme: theme,\n children: \"Click anywhere to resume audio context\"\n })\n }),\n (0, $7gk4U$jsx)($937b14f51e42c15a$var$Row, {\n children: (0, $7gk4U$jsx)($937b14f51e42c15a$var$Icon, {})\n })\n ]\n });\n};\nvar $937b14f51e42c15a$export$2e2bcd8739ae039 = $937b14f51e42c15a$var$ResumeContext;\n\n\n\n\n\n\nconst $1b015292e5f83a97$var$ToggleMinimap = ()=>{\n const setConfig = (0, $5b293d93bfa5f38a$export$2e2bcd8739ae039)(({ setConfig: setConfig })=>setConfig);\n const { showMinimap: showMinimap } = (0, $5b293d93bfa5f38a$export$2e2bcd8739ae039)(({ config: config })=>config);\n return (0, $7gk4U$jsx)((0, $7gk4U$ControlButton), {\n onClick: ()=>setConfig({\n showMinimap: !showMinimap\n }),\n children: showMinimap ? (0, $7gk4U$jsx)((0, $7gk4U$FaMap), {}) : (0, $7gk4U$jsx)((0, $7gk4U$FaRegMap), {})\n });\n};\nvar $1b015292e5f83a97$export$2e2bcd8739ae039 = $1b015292e5f83a97$var$ToggleMinimap;\n\n\n\n\n\n\n\nconst $54592d2965d12a35$var$Wire = ({ id: id, sourceX: sourceX, sourceY: sourceY, targetX: targetX, targetY: targetY, sourcePosition: sourcePosition, targetPosition: targetPosition, style: style = {}, data: data, markerStart: markerStart, markerEnd: markerEnd, source: source, target: target, sourceHandleId: sourceHandleId, targetHandleId: targetHandleId, selected: selected })=>{\n const theme = (0, $abd71d53b289d0e8$export$2e2bcd8739ae039)();\n const getNode = (0, $5b293d93bfa5f38a$export$2e2bcd8739ae039)(({ getNode: getNode })=>getNode);\n const sourceNode = getNode(source);\n const targetNode = getNode(target);\n const isConnectedToSelected = sourceNode?.selected || targetNode?.selected;\n (0, $7gk4U$useEffect)(()=>{\n if (!sourceHandleId || !targetHandleId) return;\n console.log(`connected ${source} to ${target}`);\n return ()=>{\n console.log(`disconnected ${source} from ${target}`);\n };\n }, [\n source,\n sourceHandleId,\n target,\n targetHandleId\n ]);\n const [edgePath] = (0, $7gk4U$getBezierPath)({\n targetX: targetX,\n targetY: targetY,\n targetPosition: targetPosition,\n sourceX: sourceX,\n sourceY: sourceY,\n sourcePosition: sourcePosition\n });\n return (0, $7gk4U$jsxs)((0, $7gk4U$Fragment), {\n children: [\n (0, $7gk4U$jsx)(\"path\", {\n id: id,\n style: {\n ...style,\n stroke: selected ? theme.colors.accent2 : isConnectedToSelected ? theme.colors.highlight3 : theme.colors.highlight2\n },\n className: \"react-flow__edge-path Wire\",\n d: edgePath,\n markerEnd: markerEnd\n }),\n (0, $7gk4U$jsx)(\"path\", {\n style: {\n ...style,\n strokeWidth: 8,\n color: \"transparent\",\n opacity: 0,\n cursor: \"pointer\"\n },\n d: edgePath,\n markerEnd: markerEnd\n })\n ]\n });\n};\nvar $54592d2965d12a35$export$2e2bcd8739ae039 = $54592d2965d12a35$var$Wire;\n\n\nconsole.log(99999, `React version: ${(0, $7gk4U$version)}`);\nconst $a8a186009a201622$var$onNodeDragStop = (_event, node)=>console.log(\"drag stop\", node);\nconst $a8a186009a201622$var$onNodeClick = (_event, element)=>console.log(\"click\", element);\nconst $a8a186009a201622$var$snapGrid = [\n 20,\n 20\n];\nconst $a8a186009a201622$export$72cb76f559fbafcf = ({ editorState: editorState, plugins: plugins = [], editorContextMenu: editorContextMenu = [], onChange: onChange = ()=>{}, ...props })=>{\n const edgeTypes = (0, $7gk4U$useMemo)(()=>({\n wire: (0, $54592d2965d12a35$export$2e2bcd8739ae039)\n }), []);\n const { nodes: nodes, edges: edges, controlPanel: controlPanel, onNodesChange: onNodesChange, onNodesDelete: onNodesDelete, onEdgesChange: onEdgesChange, onEdgesDelete: onEdgesDelete, onConnect: onConnect, setPlugins: setPlugins, setViewport: setViewport, viewport: viewport } = (0, $5b293d93bfa5f38a$export$2e2bcd8739ae039)();\n const editorConfig = (0, $5b293d93bfa5f38a$export$2e2bcd8739ae039)(({ config: config })=>config);\n const nodeTypes = (0, $5b293d93bfa5f38a$export$2e2bcd8739ae039)(({ nodeTypes: nodeTypes })=>nodeTypes);\n (0, $7gk4U$useEffect)(()=>{\n setPlugins(plugins);\n }, [\n plugins\n ]);\n const [reactflowInstance, setReactflowInstance] = (0, $7gk4U$useState)(null);\n (0, $7gk4U$useEffect)(()=>{\n if (!reactflowInstance) return;\n onChange({\n nodes: nodes,\n edges: edges,\n controlPanel: controlPanel,\n viewport: viewport\n });\n }, [\n nodes,\n edges,\n controlPanel,\n viewport\n ]);\n const onInit = (0, $7gk4U$useCallback)((rfi)=>{\n if (!reactflowInstance) {\n setReactflowInstance(rfi);\n console.log(\"flow loaded:\", rfi);\n }\n }, [\n reactflowInstance\n ]);\n const { onContextMenu: onEditorContextMenu } = (0, $cc36fc9d90ce018d$export$59ce2a6808e35a29)();\n const { onContextMenu: onNodeContextMenu } = (0, $2deaca6d9e341a8a$export$cbbbfb9fb15f3780)();\n const { onContextMenu: onEdgeContextMenu } = (0, $c1fe1ac7b33d0893$export$8b2e4a15453bac1e)();\n (0, $7gk4U$useEffect)(()=>{\n if (!viewport) return;\n reactflowInstance?.setViewport(viewport);\n }, [\n viewport,\n reactflowInstance\n ]);\n (0, $7gk4U$useOnViewportChange)({\n onEnd: setViewport\n });\n return (0, $7gk4U$jsxs)((0, $7gk4U$reactflow), {\n nodes: nodes,\n edges: edges,\n onNodesChange: onNodesChange,\n onNodesDelete: onNodesDelete,\n onEdgesChange: onEdgesChange,\n onConnect: onConnect,\n onNodeDragStop: $a8a186009a201622$var$onNodeDragStop,\n onEdgesDelete: onEdgesDelete,\n onInit: onInit,\n onNodeClick: $a8a186009a201622$var$onNodeClick,\n onContextMenu: onEditorContextMenu,\n onNodeContextMenu: onNodeContextMenu,\n onEdgeContextMenu: onEdgeContextMenu,\n nodeTypes: nodeTypes,\n edgeTypes: edgeTypes,\n snapGrid: $a8a186009a201622$var$snapGrid,\n defaultViewport: editorState?.viewport,\n defaultEdgeOptions: {\n type: \"wire\"\n },\n snapToGrid: true,\n fitView: true,\n disableKeyboardA11y: true,\n children: [\n (0, $7gk4U$jsx)((0, $7gk4U$Background), {\n variant: (0, $7gk4U$BackgroundVariant).Dots,\n gap: 12\n }),\n editorConfig.showMinimap ? (0, $7gk4U$jsx)((0, $7gk4U$MiniMap), {}) : null,\n (0, $7gk4U$jsxs)((0, $7gk4U$Controls), {\n style: {\n right: \"1rem\",\n left: \"initial\",\n bottom: \"40%\",\n top: \"initial\"\n },\n showInteractive: false,\n children: [\n (0, $7gk4U$jsx)((0, $1b015292e5f83a97$export$2e2bcd8739ae039), {}),\n (0, $7gk4U$jsx)((0, $4a7daf9e5da05d43$export$78bddedbcf2939ac), {})\n ]\n }),\n (0, $7gk4U$jsx)((0, $937b14f51e42c15a$export$2e2bcd8739ae039), {}),\n (0, $7gk4U$jsx)((0, $3bd5bd72a0abfb9c$export$2e2bcd8739ae039), {}),\n (0, $7gk4U$jsx)((0, $7d01d6ae325614d7$export$2e2bcd8739ae039), {}),\n (0, $7gk4U$jsx)((0, $cc36fc9d90ce018d$export$2e2bcd8739ae039), {\n editorContextMenu: editorContextMenu\n }),\n (0, $7gk4U$jsx)((0, $2deaca6d9e341a8a$export$2e2bcd8739ae039), {}),\n (0, $7gk4U$jsx)((0, $c1fe1ac7b33d0893$export$2e2bcd8739ae039), {})\n ]\n });\n};\nconst $a8a186009a201622$export$7cda8d932e2f33c0 = (props)=>(0, $7gk4U$jsx)((0, $7gk4U$ReactFlowProvider), {\n children: (0, $7gk4U$jsx)($a8a186009a201622$export$72cb76f559fbafcf, {\n ...props\n })\n });\nvar $a8a186009a201622$export$2e2bcd8739ae039 = $a8a186009a201622$export$7cda8d932e2f33c0;\n\n\n\n\n\nconst $6a18468019a13869$export$d31000d36961d6c2 = {\n nodes: [],\n edges: [],\n controlPanel: {\n nodes: [],\n show: false,\n size: {\n width: 200,\n height: 100\n }\n },\n viewport: {\n x: 0,\n y: 0,\n zoom: 1.5\n }\n};\nconst $6a18468019a13869$export$6cd5d5c1dae69a36 = (0, $7gk4U$withTheme)((0, $7gk4U$emotionstyled).div`\n display: flex;\n flex-direction: column;\n height: 100%;\n width: 100%;\n`);\nconst $6a18468019a13869$export$6bc5189622b1f4ec = (0, $7gk4U$withTheme)((0, $7gk4U$emotionstyled).div`\n position: fixed;\n height: 100%;\n width: 100%;\n background: rgba(0, 0, 0, 0.7);\n color: white;\n display: flex;\n justify-content: center;\n align-items: center;\n font-size: 2rem;\n`);\nconst $6a18468019a13869$export$8d546ef2006cd0a2 = (0, $7gk4U$withTheme)((0, $7gk4U$emotionstyled).div`\n height: 100%;\n width: 100%;\n display: flex;\n position: relative;\n`);\nconst $6a18468019a13869$export$10efbd348f877f87 = (0, $7gk4U$withTheme)((0, $7gk4U$emotionstyled).div`\n display: flex;\n flex: 1;\n align-items: center;\n justify-content: center;\n background: ${({ theme: theme })=>theme.colors.elevation3};\n`);\nconst $6a18468019a13869$export$8c347812506d5ac9 = (0, $7gk4U$withTheme)((0, $7gk4U$emotionstyled).div`\n background: ${({ theme: theme })=>theme.colors.elevation2};\n opacity: 0.7;\n position: absolute;\n width: 100%;\n height: 100%;\n left: 0;\n top: 0;\n z-index: 1;\n font-family: var(--leva-fonts-mono);\n color: ${({ theme: theme })=>theme.colors.whitePrimary};\n display: ${({ show: show })=>show ? \"flex\" : \"none\"};\n align-items: center;\n justify-content: center;\n font-size: 6rem;\n`);\nconst $6a18468019a13869$export$b38a2fd24b22fb35 = (props)=>{\n const pullEditorChanges = (0, $5b293d93bfa5f38a$export$2e2bcd8739ae039)((store)=>store.pullEditorChanges);\n const currentFileIndex = (0, $5b293d93bfa5f38a$export$2e2bcd8739ae039)((store)=>store.currentFileIndex);\n const [showLoader, setShowLoader] = (0, $7gk4U$useState)(true);\n (0, $7gk4U$useEffect)(()=>{\n setShowLoader(true);\n setTimeout(()=>{\n setShowLoader(false);\n }, 1600);\n }, [\n currentFileIndex\n ]);\n const { file: file } = props;\n if (!file) return null;\n if (file.type === \"audio\") return (0, $7gk4U$jsx)($6a18468019a13869$export$10efbd348f877f87, {\n children: (0, $7gk4U$jsx)(\"audio\", {\n src: file.file,\n controls: true\n })\n });\n return (0, $7gk4U$jsxs)((0, $7gk4U$Fragment), {\n children: [\n (0, $7gk4U$jsx)((0, $a8a186009a201622$export$7cda8d932e2f33c0), {\n ...props,\n onChange: (state)=>{\n pullEditorChanges();\n },\n editorState: file.file || $6a18468019a13869$export$d31000d36961d6c2\n }),\n (0, $7gk4U$jsx)($6a18468019a13869$export$8c347812506d5ac9, {\n show: showLoader,\n children: \"Loading...\"\n })\n ]\n });\n};\nconst $6a18468019a13869$export$2206531ad8592d57 = (0, $7gk4U$withTheme)((0, $7gk4U$emotionstyled).div`\n height: 2rem;\n display: flex;\n align-items: center;\n background: ${({ theme: theme })=>theme.colors.elevation2};\n`);\nconst $6a18468019a13869$export$3e41faf802a29e71 = (0, $7gk4U$withTheme)((0, $7gk4U$emotionstyled).div`\n display: flex;\n align-items: center;\n cursor: pointer;\n height: 100%;\n box-sizing: border-box;\n padding: 0.3rem 0.4rem;\n\n border-right: 1px solid ${({ theme: theme })=>theme.colors.elevation1};\n\n input {\n color: ${({ theme: theme, active: active })=>active ? theme.colors.whitePrimary : theme.colors.highlight1};\n\n &:not([readonly]):focus {\n background-color: ${({ theme: theme })=>theme.colors.elevation1};\n }\n }\n`);\nconst $6a18468019a13869$export$61e5b3c7bace77b8 = (0, $7gk4U$withTheme)((0, $7gk4U$emotionstyled).div`\n display: flex;\n align-items: center;\n height: 100%;\n padding: 0 0.5rem;\n cursor: pointer;\n\n color: ${({ theme: theme })=>theme.colors.highlight1};\n &:hover {\n color: ${({ theme: theme })=>theme.colors.whitePrimary};\n }\n`);\nconst $6a18468019a13869$export$3aef34186a092045 = (0, $7gk4U$withTheme)((0, $7gk4U$emotionstyled)((0, $7gk4U$FaPlus))`\n height: 40%;\n width: auto;\n`);\nconst $6a18468019a13869$export$cae179f078f4b4a4 = (0, $7gk4U$withTheme)((0, $7gk4U$emotionstyled)((0, $7gk4U$MdClose))`\n height: 70%;\n width: auto;\n cursor: pointer;\n color: ${({ theme: theme })=>theme.colors.highlight1};\n &:hover {\n color: ${({ theme: theme })=>theme.colors.whitePrimary};\n }\n`);\nconst $6a18468019a13869$var$generateId = ()=>{\n return (0, $7gk4U$nanoid)();\n};\nconst $6a18468019a13869$var$generateEmptyFile = ()=>({\n file: $6a18468019a13869$export$d31000d36961d6c2,\n name: \"Unnamed\",\n type: \"patch\",\n id: $6a18468019a13869$var$generateId()\n });\nconst $6a18468019a13869$export$86fbec116b87613f = ({ ...props })=>{\n const { projectState: projectState, theme: theme } = props;\n const currentFileIndex = (0, $5b293d93bfa5f38a$export$2e2bcd8739ae039)((store)=>store.currentFileIndex);\n const currentFile = (0, $5b293d93bfa5f38a$export$2e2bcd8739ae039)((store)=>store.project.files[store.currentFileIndex]);\n const setCurrentFileIndex = (0, $5b293d93bfa5f38a$export$2e2bcd8739ae039)((store)=>store.setCurrentFileIndex);\n const project = (0, $5b293d93bfa5f38a$export$2e2bcd8739ae039)((store)=>store.project);\n const setProject = (0, $5b293d93bfa5f38a$export$2e2bcd8739ae039)((store)=>store.setProject);\n const getProject = (0, $5b293d93bfa5f38a$export$2e2bcd8739ae039)((store)=>store.getProject);\n const updateFileName = (0, $5b293d93bfa5f38a$export$2e2bcd8739ae039)((store)=>store.updateFileName);\n const addFile = (0, $5b293d93bfa5f38a$export$2e2bcd8739ae039)((store)=>store.addFile);\n const deleteFile = (0, $5b293d93bfa5f38a$export$2e2bcd8739ae039)((store)=>store.deleteFile);\n const syncEditorWithCurrentFile = (0, $5b293d93bfa5f38a$export$2e2bcd8739ae039)((store)=>store.syncEditorWithCurrentFile);\n const setEditorState = (0, $5b293d93bfa5f38a$export$2e2bcd8739ae039)((store)=>store.setEditorState);\n const pullEditorChanges = (0, $5b293d93bfa5f38a$export$2e2bcd8739ae039)((store)=>store.pullEditorChanges);\n const [isDragging, setIsDragging] = (0, $7gk4U$useState)(false);\n const handleDragLeave = (e)=>{\n e.preventDefault();\n e.stopPropagation();\n setIsDragging(false);\n };\n const handleDragOver = (e)=>{\n e.preventDefault();\n e.stopPropagation();\n setIsDragging(true);\n };\n const handleDrop = (e)=>{\n e.preventDefault();\n e.stopPropagation();\n setIsDragging(false);\n const files = Array.from(e.dataTransfer.files);\n files.forEach(async (file)=>{\n if (file.type === \"application/json\") {\n const fileData = JSON.parse(await file.text());\n if (fileData.files && fileData.files.length) {\n if (!window.confirm(\"This action will replace your current project. Continue?\")) return;\n setProject(fileData);\n setCurrentFileIndex(0);\n syncEditorWithCurrentFile();\n return;\n }\n const emptyFile = $6a18468019a13869$var$generateEmptyFile();\n const newGraphState = {\n ...emptyFile,\n file: {\n ...fileData,\n controlPanel: {\n ...$6a18468019a13869$export$d31000d36961d6c2.controlPanel,\n ...fileData.controlPanel\n }\n },\n name: file.name\n };\n addFile(newGraphState, file.name);\n return;\n }\n if (file.type.match(/^audio\\//)) {\n const base64 = await (0, $380e1488605d504c$export$25df2e315be8e003)(file);\n addFile({\n type: \"audio\",\n // @TODO: use nanoid here\n id: `audio-file-${+new Date()}`,\n name: file.name,\n file: base64\n });\n return;\n }\n console.error(\"Unsupported file type\", file);\n });\n };\n (0, $7gk4U$useEffect)(()=>{\n setProject(projectState || {\n files: [\n $6a18468019a13869$var$generateEmptyFile()\n ]\n });\n const file = projectState?.files[0];\n file?.file && file?.type !== \"audio\" && setEditorState(file.file);\n }, [\n projectState\n ]);\n // EXPERIMENTAL CODE\n (0, $7gk4U$useEffect)(()=>{\n const fetcher = async (...args)=>{\n const request = new Request(...args);\n const files = getProject().files;\n const index = request.url.replace(\"project://\", \"\");\n const file = files.find(({ id: id })=>id === index);\n if (!file) return new Response(`File not found: ${request.url}`, {\n status: 404\n });\n if ((0, $c5ef937e71d3327e$export$e698b79c63b74136)(file)) return new Response(JSON.stringify(file.file ?? null));\n if ((0, $c5ef937e71d3327e$export$31c2336f657dc59f)(file)) return fetch(file.file);\n return new Response(null);\n };\n (0, $7gk4U$registerFetcher)(\"project://*\", fetcher);\n return ()=>{\n //unregister here\n };\n }, [\n getProject\n ]);\n (0, $7gk4U$useEffect)(()=>{\n syncEditorWithCurrentFile();\n }, [\n currentFileIndex,\n syncEditorWithCurrentFile\n ]);\n return (0, $7gk4U$jsxs)((0, $7gk4U$ThemeProvider), {\n theme: theme || (0, $d10a6381d028e3f6$export$2e2bcd8739ae039),\n children: [\n (0, $7gk4U$jsx)((0, $7gk4U$Global), {\n styles: (0, $7gk4U$css)`\n :root {\n --leva-colors-elevation1: #292d39;\n --leva-colors-elevation2: #181c20;\n --leva-colors-elevation3: #373c4b;\n --leva-colors-accent1: #0066dc;\n --leva-colors-accent2: #007bff;\n --leva-colors-accent3: #3c93ff;\n --leva-colors-highlight1: #535760;\n --leva-colors-highlight2: #8c92a4;\n --leva-colors-highlight3: #fefefe;\n --leva-colors-vivid1: #ffcc00;\n --leva-colors-folderWidgetColor: var(--leva-colors-highlight2);\n --leva-colors-folderTextColor: var(--leva-colors-highlight3);\n --leva-colors-toolTipBackground: var(--leva-colors-highlight3);\n --leva-colors-toolTipText: var(--leva-colors-elevation2);\n --leva-radii-xs: 2px;\n --leva-radii-sm: 3px;\n --leva-radii-lg: 10px;\n --leva-space-xs: 3px;\n --leva-space-sm: 6px;\n --leva-space-md: 10px;\n --leva-space-rowGap: 7px;\n --leva-space-colGap: 7px;\n --leva-fonts-mono:\n ui-monospace, SFMono-Regular, Menlo, \"Roboto Mono\", monospace;\n --leva-fonts-sans: system-ui, sans-serif;\n --leva-fontSizes-root: 11px;\n --leva-fontSizes-toolTip: var(--leva-fontSizes-root);\n --leva-sizes-rootWidth: 280px;\n --leva-sizes-controlWidth: 160px;\n --leva-sizes-numberInputMinWidth: 38px;\n --leva-sizes-scrubberWidth: 8px;\n --leva-sizes-scrubberHeight: 16px;\n --leva-sizes-rowHeight: 24px;\n --leva-sizes-folderTitleHeight: 20px;\n --leva-sizes-checkboxSize: 16px;\n --leva-sizes-joystickWidth: 100px;\n --leva-sizes-joystickHeight: 100px;\n --leva-sizes-colorPickerWidth: var(--leva-sizes-controlWidth);\n --leva-sizes-colorPickerHeight: 100px;\n --leva-sizes-imagePreviewWidth: var(--leva-sizes-controlWidth);\n --leva-sizes-imagePreviewHeight: 100px;\n --leva-sizes-monitorHeight: 60px;\n --leva-sizes-titleBarHeight: 39px;\n --leva-shadows-level1: 0 0 9px 0 #00000088;\n --leva-shadows-level2: 0 4px 14px #00000033;\n --leva-borderWidths-root: 0px;\n --leva-borderWidths-input: 1px;\n --leva-borderWidths-focus: 1px;\n --leva-borderWidths-hover: 1px;\n --leva-borderWidths-active: 1px;\n --leva-borderWidths-folder: 1px;\n --leva-fontWeights-label: normal;\n --leva-fontWeights-folder: normal;\n --leva-fontWeights-button: normal;\n }\n `\n }),\n (0, $7gk4U$jsxs)($6a18468019a13869$export$6cd5d5c1dae69a36, {\n onDragOver: handleDragOver,\n onDragLeave: handleDragLeave,\n onDrop: handleDrop,\n children: [\n (0, $7gk4U$jsxs)($6a18468019a13869$export$2206531ad8592d57, {\n children: [\n project.files.map((file, index)=>(0, $7gk4U$jsxs)($6a18468019a13869$export$3e41faf802a29e71, {\n onClick: ()=>{\n setCurrentFileIndex(index);\n },\n active: index === currentFileIndex,\n children: [\n (0, $7gk4U$jsx)((0, $7a796029b1c3cc22$export$2e2bcd8739ae039), {\n onChange: (val)=>updateFileName(index, val),\n value: file.name || \"Unnamed\"\n }),\n (0, $7gk4U$jsx)($6a18468019a13869$export$cae179f078f4b4a4, {\n onClick: (event)=>{\n event.stopPropagation();\n if (!window.confirm(\"Do you really want to delete this file?\")) return;\n deleteFile(index);\n }\n })\n ]\n }, index)),\n (0, $7gk4U$jsx)($6a18468019a13869$export$61e5b3c7bace77b8, {\n onClick: ()=>{\n addFile($6a18468019a13869$var$generateEmptyFile());\n setCurrentFileIndex(project.files.length);\n },\n children: (0, $7gk4U$jsx)($6a18468019a13869$export$3aef34186a092045, {})\n })\n ]\n }),\n (0, $7gk4U$jsx)($6a18468019a13869$export$8d546ef2006cd0a2, {\n children: (0, $7gk4U$jsx)($6a18468019a13869$export$b38a2fd24b22fb35, {\n file: currentFile,\n ...props\n })\n }),\n isDragging && (0, $7gk4U$jsx)($6a18468019a13869$export$6bc5189622b1f4ec, {\n children: \"Drop file(s) to upload to the project\"\n })\n ]\n })\n ]\n });\n};\nvar $6a18468019a13869$export$2e2bcd8739ae039 = $6a18468019a13869$export$86fbec116b87613f;\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nconst $0cdf21d270160c43$var$CheckerBox = (0, $7gk4U$emotionstyled).div`\n display: flex;\n align-items: center;\n justify-content: center;\n width: 0.6rem;\n height: 0.6rem;\n background: ${({ theme: theme })=>theme.colors.whitePrimary};\n border: 1px solid ${({ theme: theme })=>theme.colors.highlight1};\n &::after {\n content: \"\";\n background: ${({ theme: theme })=>theme.colors.accent1};\n }\n`;\nconst $0cdf21d270160c43$var$CheckerLabel = (0, $7gk4U$emotionstyled).div``;\nconst $0cdf21d270160c43$var$CheckerSubtitle = (0, $7gk4U$emotionstyled).div`\n font-size: 0.4rem;\n color: ${({ theme: theme })=>theme.colors.highlight1};\n`;\nconst $0cdf21d270160c43$var$CheckedInner = (0, $7gk4U$emotionstyled).label`\n display: flex;\n cursor: pointer;\n gap: 0.4rem;\n line-height: 0.7rem;\n input {\n display: none;\n }\n input[type=\"radio\"] ~ .checker-box {\n border-radius: 50%;\n &::after {\n border-radius: 50%;\n }\n }\n input:checked ~ .checker-box:after {\n width: 70%;\n height: 70%;\n }\n`;\nconst $0cdf21d270160c43$export$8ecd240bc8faaeeb = ({ label: label, subtitle: subtitle, name: name, type: type = \"checkbox\", onChange: onChange, checked: checked = false })=>{\n const theme = (0, $abd71d53b289d0e8$export$2e2bcd8739ae039)();\n return (0, $7gk4U$jsxs)($0cdf21d270160c43$var$CheckedInner, {\n children: [\n (0, $7gk4U$jsx)(\"input\", {\n type: type,\n name: name,\n checked: checked,\n onChange: ({ target: target })=>onChange?.(target.checked)\n }),\n (0, $7gk4U$jsx)($0cdf21d270160c43$var$CheckerBox, {\n className: \"checker-box\",\n theme: theme\n }),\n (0, $7gk4U$jsxs)(\"div\", {\n children: [\n (0, $7gk4U$jsx)($0cdf21d270160c43$var$CheckerLabel, {\n children: label\n }),\n subtitle ? (0, $7gk4U$jsx)($0cdf21d270160c43$var$CheckerSubtitle, {\n theme: theme,\n children: subtitle\n }) : null\n ]\n })\n ]\n });\n};\nvar $0cdf21d270160c43$export$2e2bcd8739ae039 = $0cdf21d270160c43$export$8ecd240bc8faaeeb;\n\n\n\n\n\n\nconst $fee4ec5a9782241c$var$RadioGroupWrapper = (0, $7gk4U$emotionstyled).div`\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n font-family: var(--leva-fonts-mono);\n font-size: 0.7rem;\n color: ${({ theme: theme })=>theme.colors.highlight2};\n padding: 0.5rem;\n`;\nconst $fee4ec5a9782241c$export$a98f0dcb43a68a25 = ({ options: options, value: value, onChange: onChange })=>{\n const theme = (0, $abd71d53b289d0e8$export$2e2bcd8739ae039)();\n return (0, $7gk4U$jsx)($fee4ec5a9782241c$var$RadioGroupWrapper, {\n theme: theme,\n children: options.map(({ value: optionValue, label: label, subtitle: subtitle }, index)=>(0, $7gk4U$jsx)((0, $0cdf21d270160c43$export$2e2bcd8739ae039), {\n value: value,\n type: \"radio\",\n label: label,\n subtitle: subtitle,\n onChange: ()=>onChange(optionValue),\n checked: optionValue === value\n }, index))\n });\n};\nvar $fee4ec5a9782241c$export$2e2bcd8739ae039 = $fee4ec5a9782241c$export$a98f0dcb43a68a25;\n\n\n\n\n\nconst $4866e5bff8d594b9$export$fb9f58ebe9de6283 = (0, $7gk4U$emotionstyled).div`\n display: flex;\n position: relative;\n`;\nconst $4866e5bff8d594b9$export$42e20bb2ce90003b = (0, $7gk4U$withTheme)((0, $7gk4U$emotionstyled).input`\n padding-right: 2rem;\n padding-left: 0.3rem;\n padding-top: 0;\n padding-bottom: 0;\n width: 100%;\n appearance: textfield;\n font-size: inherit;\n background: none;\n border: none;\n color: var(--leva-colors-highlight1);\n font-family: var(--leva-fonts-mono);\n cursor: inherit;\n text-overflow: ellipsis;\n outline: none;\n appearance: textfield;\n cursor: auto;\n background-color: var(--leva-colors-elevation3);\n border-radius: 0.2rem;\n height: 1.5rem;\n color: var(--leva-colors-highlight2);\n\n &:focus,\n &:hover {\n box-shadow: 0 0 0 var(--leva-borderWidths-focus) var(--leva-colors-accent2);\n color: ${({ theme: theme })=>theme.colors.whitePrimary};\n }\n &::-webkit-inner-spin-button,\n &::-webkit-outer-spin-button {\n -webkit-appearance: none;\n margin-right: 1rem;\n }\n`);\nconst $4866e5bff8d594b9$export$f5b8910cec6cf069 = ({ type: type, value: value, placeholder: placeholder, onChange: onChange = ()=>{}, inputProps: inputProps, ...props })=>{\n return (0, $7gk4U$jsx)($4866e5bff8d594b9$export$fb9f58ebe9de6283, {\n ...props,\n children: (0, $7gk4U$jsx)($4866e5bff8d594b9$export$42e20bb2ce90003b, {\n type: type,\n value: value,\n placeholder: placeholder,\n onKeyDownCapture: (event)=>{\n event.stopPropagation();\n },\n onChange: (event)=>{\n onChange(event.target.value);\n },\n ...inputProps\n })\n });\n};\nvar $4866e5bff8d594b9$export$2e2bcd8739ae039 = $4866e5bff8d594b9$export$f5b8910cec6cf069;\n\n\n\n\n\n\n\n\nconst $eadb9fa465de5e7c$var$InputButton = (0, $7gk4U$withTheme)((0, $7gk4U$emotionstyled).button`\n position: absolute;\n right: 0;\n height: 100%;\n outline: none;\n background: none;\n border: none;\n color: ${({ theme: theme })=>theme.colors.highlight1};\n cursor: pointer;\n display: flex;\n align-items: center;\n z-index: 2;\n &:hover {\n color: ${({ theme: theme })=>theme.colors.highlight2};\n }\n &:active {\n color: ${({ theme: theme })=>theme.colors.highlight3};\n }\n`);\nconst $eadb9fa465de5e7c$var$DropdownContainer = (0, $7gk4U$emotionstyled).div`\n position: relative;\n width: 100%;\n`;\nconst $eadb9fa465de5e7c$var$DropdownList = (0, $7gk4U$withTheme)((0, $7gk4U$emotionstyled).div`\n position: absolute;\n top: calc(100% + 2px);\n left: 0;\n right: 0;\n max-height: 200px;\n overflow-y: auto;\n background-color: ${({ theme: theme })=>theme.colors.elevation2};\n border: 1px solid ${({ theme: theme })=>theme.colors.elevation3};\n border-radius: 0.2rem;\n box-shadow: 0 4px 6px rgba(0, 0, 0, 0.3);\n z-index: 1000;\n display: ${({ isOpen: isOpen })=>isOpen ? \"block\" : \"none\"};\n\n &::-webkit-scrollbar {\n width: 8px;\n }\n\n &::-webkit-scrollbar-track {\n background: ${({ theme: theme })=>theme.colors.elevation1};\n }\n\n &::-webkit-scrollbar-thumb {\n background: ${({ theme: theme })=>theme.colors.elevation3};\n border-radius: 4px;\n }\n\n &::-webkit-scrollbar-thumb:hover {\n background: ${({ theme: theme })=>theme.colors.highlight1};\n }\n`);\nconst $eadb9fa465de5e7c$var$DropdownItem = (0, $7gk4U$withTheme)((0, $7gk4U$emotionstyled).div`\n padding: 0.4rem 0.5rem;\n cursor: pointer;\n color: ${({ theme: theme })=>theme.colors.highlight1};\n background-color: ${({ theme: theme, isHighlighted: isHighlighted })=>isHighlighted ? theme.colors.elevation3 : \"transparent\"};\n font-family: var(--leva-fonts-mono);\n font-size: 0.9em;\n\n &:hover {\n background-color: ${({ theme: theme })=>theme.colors.elevation3};\n color: ${({ theme: theme })=>theme.colors.highlight2};\n }\n`);\nconst $eadb9fa465de5e7c$var$DropdownItemValue = (0, $7gk4U$emotionstyled).div`\n font-size: 0.85em;\n opacity: 0.7;\n margin-top: 2px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n`;\nconst $eadb9fa465de5e7c$var$DropdownItemLabel = (0, $7gk4U$emotionstyled).div`\n font-size: 1em;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n`;\nconst $eadb9fa465de5e7c$export$7a40489edcbfb3a1 = ({ value: value = \"\", placeholder: placeholder = \"\", onSubmit: onSubmit = ()=>{}, options: options = [], ...props })=>{\n const [currentValue, setCurrentValue] = (0, $7gk4U$useState)(value);\n const [isOpen, setIsOpen] = (0, $7gk4U$useState)(false);\n const [highlightedIndex, setHighlightedIndex] = (0, $7gk4U$useState)(-1);\n const inputRef = (0, $7gk4U$useRef)(null);\n const dropdownRef = (0, $7gk4U$useRef)(null);\n const filteredOptions = options.filter((option)=>currentValue === \"\" || option.value.toLowerCase().includes(currentValue.toLowerCase()) || option.label?.toLowerCase().includes(currentValue.toLowerCase()));\n const applyCurrentValue = (0, $7gk4U$useCallback)(()=>{\n onSubmit(currentValue);\n setIsOpen(false);\n setHighlightedIndex(-1);\n }, [\n currentValue,\n onSubmit\n ]);\n const selectOption = (0, $7gk4U$useCallback)((option)=>{\n setCurrentValue(option.value);\n onSubmit(option.value);\n setIsOpen(false);\n setHighlightedIndex(-1);\n }, [\n onSubmit\n ]);\n const handleKeyDown = (0, $7gk4U$useCallback)((event)=>{\n switch(event.key){\n case \"Escape\":\n setIsOpen(false);\n setHighlightedIndex(-1);\n break;\n case \"Enter\":\n if (isOpen && highlightedIndex >= 0 && filteredOptions[highlightedIndex]) {\n event.preventDefault();\n selectOption(filteredOptions[highlightedIndex]);\n } else applyCurrentValue();\n break;\n case \"ArrowDown\":\n event.preventDefault();\n if (!isOpen) {\n setIsOpen(true);\n setHighlightedIndex(0);\n } else setHighlightedIndex((prev)=>prev < filteredOptions.length - 1 ? prev + 1 : prev);\n break;\n case \"ArrowUp\":\n event.preventDefault();\n if (isOpen) setHighlightedIndex((prev)=>prev > 0 ? prev - 1 : prev);\n break;\n }\n }, [\n applyCurrentValue,\n isOpen,\n highlightedIndex,\n filteredOptions,\n selectOption\n ]);\n const handleInputChange = (value)=>{\n setCurrentValue(value);\n setIsOpen(true);\n setHighlightedIndex(-1);\n };\n const handleFocus = ()=>{\n if (options.length > 0) setIsOpen(true);\n };\n const handleBlur = ()=>{\n // Use setTimeout to allow click events on dropdown items to fire first\n setTimeout(()=>{\n setIsOpen(false);\n setHighlightedIndex(-1);\n }, 200);\n };\n // Handle clicking outside\n (0, $7gk4U$useEffect)(()=>{\n const handleClickOutside = (event)=>{\n if (dropdownRef.current && !dropdownRef.current.contains(event.target) && inputRef.current && !inputRef.current.contains(event.target)) {\n setIsOpen(false);\n setHighlightedIndex(-1);\n }\n };\n document.addEventListener(\"mousedown\", handleClickOutside);\n return ()=>{\n document.removeEventListener(\"mousedown\", handleClickOutside);\n };\n }, []);\n // Scroll highlighted item into view\n (0, $7gk4U$useEffect)(()=>{\n if (highlightedIndex >= 0 && dropdownRef.current) {\n const highlightedElement = dropdownRef.current.children[highlightedIndex];\n if (highlightedElement) highlightedElement.scrollIntoView({\n block: \"nearest\",\n behavior: \"smooth\"\n });\n }\n }, [\n highlightedIndex\n ]);\n return (0, $7gk4U$jsxs)($eadb9fa465de5e7c$var$DropdownContainer, {\n children: [\n (0, $7gk4U$jsxs)((0, $4866e5bff8d594b9$export$fb9f58ebe9de6283), {\n children: [\n (0, $7gk4U$jsx)((0, $4866e5bff8d594b9$export$42e20bb2ce90003b), {\n ...props,\n ref: inputRef,\n value: currentValue,\n placeholder: placeholder,\n onKeyDown: handleKeyDown,\n onChange: (event)=>handleInputChange(event.target.value),\n onFocus: handleFocus,\n onBlur: handleBlur,\n autoComplete: \"off\"\n }),\n (0, $7gk4U$jsx)($eadb9fa465de5e7c$var$InputButton, {\n onClick: applyCurrentValue,\n children: (0, $7gk4U$jsx)((0, $7gk4U$FaRegArrowAltCircleRight), {})\n })\n ]\n }),\n options.length > 0 && (0, $7gk4U$jsx)($eadb9fa465de5e7c$var$DropdownList, {\n ref: dropdownRef,\n isOpen: isOpen && filteredOptions.length > 0,\n children: filteredOptions.map((option, index)=>(0, $7gk4U$jsxs)($eadb9fa465de5e7c$var$DropdownItem, {\n isHighlighted: index === highlightedIndex,\n onClick: ()=>selectOption(option),\n onMouseEnter: ()=>setHighlightedIndex(index),\n children: [\n (0, $7gk4U$jsx)($eadb9fa465de5e7c$var$DropdownItemLabel, {\n children: option.label || option.value\n }),\n option.value && (0, $7gk4U$jsx)($eadb9fa465de5e7c$var$DropdownItemValue, {\n children: option.value\n })\n ]\n }, option.value + index))\n })\n ]\n });\n};\nvar $eadb9fa465de5e7c$export$2e2bcd8739ae039 = $eadb9fa465de5e7c$export$7a40489edcbfb3a1;\n\n\n\n\n\nconst $8d9f8f4bde3307d1$var$StyledInputWrapper = (0, $7gk4U$emotionstyled)((0, $4866e5bff8d594b9$export$fb9f58ebe9de6283))`\n gap: 0.5rem;\n`;\nconst $8d9f8f4bde3307d1$var$StyledInputInner = (0, $7gk4U$emotionstyled)((0, $4866e5bff8d594b9$export$42e20bb2ce90003b))`\n padding: 0;\n aspect-ratio: 1 / 1;\n width: auto;\n cursor: pointer;\n &::-webkit-color-swatch-wrapper {\n padding: 0;\n }\n &::-webkit-color-swatch {\n border-radius: 0.2rem;\n border: none;\n }\n`;\nconst $8d9f8f4bde3307d1$export$5a1d7ca0a925d9c2 = ({ value: value, onChange: onChange = ()=>{}, ...props })=>{\n return (0, $7gk4U$jsxs)($8d9f8f4bde3307d1$var$StyledInputWrapper, {\n ...props,\n children: [\n (0, $7gk4U$jsx)($8d9f8f4bde3307d1$var$StyledInputInner, {\n type: \"color\",\n value: value,\n onChange: (event)=>{\n onChange(event.target.value);\n }\n }),\n (0, $7gk4U$jsx)((0, $4866e5bff8d594b9$export$42e20bb2ce90003b), {\n value: value,\n onChange: (event)=>{\n onChange(event.target.value);\n }\n })\n ]\n });\n};\nvar $8d9f8f4bde3307d1$export$2e2bcd8739ae039 = $8d9f8f4bde3307d1$export$5a1d7ca0a925d9c2;\n\n\n\n\n\n\nconst $f537c5f3d37e7de0$var$SampleInput = (0, $7gk4U$emotionstyled).span`\n position: relative;\n &:after {\n content: \"↕\";\n position: absolute;\n top: -1px;\n right: 0;\n height: 100%;\n display: flex;\n align-items: center;\n font-size: 1.2em;\n color: var(--leva-colors-highlight1);\n }\n`;\nconst $f537c5f3d37e7de0$var$SampleInputInner = (0, $7gk4U$emotionstyled).input`\n width: 100%;\n appearance: textfield;\n font-size: inherit;\n background: none;\n border: none;\n text-align: right;\n color: var(--leva-colors-highlight1);\n font-family: var(--leva-fonts-mono);\n cursor: inherit;\n text-overflow: ellipsis;\n outline: none;\n appearance: textfield;\n cursor: auto;\n background-color: var(--leva-colors-elevation3);\n border-radius: 0.2rem;\n height: 1.5rem;\n color: var(--leva-colors-highlight2);\n\n &:focus,\n &:hover {\n box-shadow: 0 0 0 var(--leva-borderWidths-focus) var(--leva-colors-accent2);\n }\n &::-webkit-inner-spin-button,\n &::-webkit-outer-spin-button {\n -webkit-appearance: none;\n margin-right: 1rem;\n }\n`;\nconst $f537c5f3d37e7de0$export$6bf0cd3a219bbade = ({ max: max = Infinity, min: min = -Infinity, value: value, step: step = 1, onChange: onChange = ()=>{}, placeholder: placeholder, ...props })=>{\n const inputRef = (0, $7gk4U$useRef)(null);\n const startChangedHandler = (0, $7gk4U$useThrottledCallback)((event)=>{\n if (typeof value === \"undefined\") return;\n //@TODO: come up with more logical factor calculation\n const factor = max < 10 ? 5 : max / 100;\n const st = +(value + Math.round(event.deltaY / factor) * step).toFixed(2);\n if (st < min || st > max) return;\n onChange(st);\n }, 100);\n (0, $7gk4U$useEffect)(()=>{\n if (!inputRef.current) return;\n inputRef.current.addEventListener(\"wheel\", (event)=>{\n event.preventDefault();\n event.stopPropagation();\n startChangedHandler(event);\n });\n inputRef.current.onchange = (event)=>{\n const value = event.target.value;\n onChange(+value);\n };\n }, [\n inputRef.current,\n onChange\n ]);\n (0, $7gk4U$useEffect)(()=>{\n if (typeof value === \"undefined\") return;\n inputRef.current && (inputRef.current.value = value.toString());\n }, [\n inputRef.current,\n value\n ]);\n return (0, $7gk4U$jsx)($f537c5f3d37e7de0$var$SampleInput, {\n ...props,\n children: (0, $7gk4U$jsx)($f537c5f3d37e7de0$var$SampleInputInner, {\n ref: inputRef,\n type: \"number\",\n step: step,\n min: min,\n max: max,\n placeholder: placeholder\n })\n });\n};\nvar $f537c5f3d37e7de0$export$2e2bcd8739ae039 = $f537c5f3d37e7de0$export$6bf0cd3a219bbade;\n\n\n\nconst $44b7e15e1a9af68f$export$353f5b6fc5456de1 = (0, $7gk4U$emotionstyled).button`\n display: flex;\n align-items: center;\n justify-content: center;\n outline: none;\n font-size: inherit;\n font-family: inherit;\n border: none;\n appearance: none;\n font-weight: var(--leva-fontWeights-button);\n height: var(--leva-sizes-rowHeight);\n border-radius: var(--leva-radii-sm);\n background-color: ${({ theme: theme })=>theme.colors.elevation1};\n color: ${({ theme: theme })=>theme.colors.highlight3};\n background-color: ${({ theme: theme })=>theme.colors.accent2};\n cursor: pointer;\n font-family: var(--leva-fonts-mono);\n font-size: var(--leva-fontSizes-root);\n\n &:hover {\n box-shadow: inset 0 0 0 var(--leva-borderWidths-hover)\n ${({ theme: theme })=>theme.colors.accent3};\n }\n\n &:active {\n box-shadow: inset 0 0 0 var(--leva-borderWidths-active)\n ${({ theme: theme })=>theme.colors.accent3};\n background-color: ${({ theme: theme })=>theme.colors.accent1};\n }\n`;\nvar $44b7e15e1a9af68f$export$2e2bcd8739ae039 = $44b7e15e1a9af68f$export$353f5b6fc5456de1;\n\n\n\n\n\nconst $6cd47b275e936c4f$var$SelectWrapper = (0, $7gk4U$withTheme)((0, $7gk4U$emotionstyled).div`\n display: flex;\n align-items: center;\n position: relative;\n\n select {\n appearance: none;\n border: none;\n outline: none;\n width: 100%;\n font-weight: var(--leva-fontWeights-button);\n padding: 0.3rem 0.5rem;\n padding-right: 1rem;\n border-radius: var(--leva-radii-sm);\n background-color: ${({ theme: theme })=>theme.colors.elevation1};\n color: ${({ theme: theme })=>theme.colors.highlight3};\n cursor: pointer;\n font-family: var(--leva-fonts-mono);\n font-size: var(--leva-fontSizes-root);\n\n &:hover {\n box-shadow: inset 0 0 0 var(--leva-borderWidths-hover)\n ${({ theme: theme })=>theme.colors.accent3};\n }\n\n &:active {\n box-shadow: inset 0 0 0 var(--leva-borderWidths-active)\n ${({ theme: theme })=>theme.colors.accent3};\n background-color: ${({ theme: theme })=>theme.colors.accent1};\n }\n }\n\n &::after {\n position: absolute;\n right: 0.3rem;\n content: \"\";\n width: 0.5em;\n height: 0.3em;\n background-color: ${({ theme: theme })=>theme.colors.highlight3};\n clip-path: polygon(100% 0%, 0 0%, 50% 100%);\n }\n`);\nconst $6cd47b275e936c4f$export$ef9b1a59e592288f = ({ options: options, placeholder: placeholder, value: value, onChange: onChange, ...props })=>{\n return (0, $7gk4U$jsx)($6cd47b275e936c4f$var$SelectWrapper, {\n ...props,\n children: (0, $7gk4U$jsxs)(\"select\", {\n value: value || \"\",\n onChange: (event)=>onChange?.(event.target.value),\n children: [\n placeholder && (0, $7gk4U$jsx)(\"option\", {\n value: \"\",\n disabled: true,\n children: placeholder\n }),\n options.map(({ value: value, label: label })=>(0, $7gk4U$jsx)(\"option\", {\n value: value,\n children: label\n }, value + label))\n ]\n })\n });\n};\nvar $6cd47b275e936c4f$export$2e2bcd8739ae039 = $6cd47b275e936c4f$export$ef9b1a59e592288f;\n\n\n\n\n\nconst $145c4d4c74f0de83$export$472062a354075cee = (0, $7gk4U$emotionstyled)((0, $7gk4U$rcslider))`\n padding: 0;\n cursor: pointer;\n position: relative;\n\n &:hover {\n filter: brightness(125%);\n }\n\n .rc-slider-dot {\n border-radius: 0;\n box-shadow: none;\n margin: 0;\n border: none;\n background: ${({ theme: theme })=>theme.colors.highlight2};\n }\n\n &.rc-slider-horizontal .rc-slider-dot {\n width: 1px;\n height: 0.25rem;\n bottom: -6px;\n }\n\n &.rc-slider-vertical .rc-slider-dot {\n width: 0.25rem;\n height: 1px;\n left: 3px;\n }\n\n .rc-slider-rail {\n background: ${({ theme: theme })=>theme.colors.elevation1};\n }\n\n .rc-slider-track {\n background: ${({ theme: theme, color: color })=>color || theme.colors.accent2};\n }\n\n .rc-slider-handle {\n border-radius: 0.125rem;\n background: ${({ theme: theme, color: color })=>color || theme.colors.accent2};\n opacity: 1;\n cursor: pointer;\n border: none;\n &:hover {\n filter: brightness(110%);\n }\n }\n\n .rc-slider-handle,\n .rc-slider-handle.rc-slider-handle-dragging {\n box-shadow: 0 0 0 2px ${({ theme: theme })=>theme.colors.elevation2};\n }\n\n &:before {\n content: \"\";\n position: absolute;\n background: transparent;\n }\n\n &.rc-slider-horizontal {\n height: 2px;\n\n .rc-slider-rail,\n .rc-slider-track,\n .rc-slider-step {\n height: 100%;\n }\n\n .rc-slider-handle {\n width: 0.5rem;\n height: 1rem;\n bottom: -7px;\n }\n\n .rc-slider-handle-dragging {\n cursor: ew-resize;\n }\n\n &:before {\n width: 100%;\n height: 1rem;\n top: -7px;\n }\n }\n\n &.rc-slider-vertical {\n width: 2px;\n\n .rc-slider-rail,\n .rc-slider-track,\n .rc-slider-step {\n width: 100%;\n }\n\n .rc-slider-track {\n left: 0;\n }\n\n .rc-slider-handle {\n width: 1rem;\n height: 0.5rem;\n right: -7px;\n }\n\n .rc-slider-handle-dragging {\n cursor: ns-resize;\n }\n\n &:before {\n height: 100%;\n width: 1rem;\n right: -7px;\n }\n }\n\n &.rc-slider-horizontal .rc-slider-mark {\n top: 1rem;\n }\n\n &.rc-slider-vertical .rc-slider-mark {\n left: 1rem;\n }\n\n .rc-slider-mark-text {\n font-size: 0.4rem;\n }\n`;\nvar $145c4d4c74f0de83$export$2e2bcd8739ae039 = $145c4d4c74f0de83$export$472062a354075cee;\n\n\n\n\n\n\n\nclass $2c0e5b77732bcbe8$var$Spliner extends (0, $7gk4U$CanvasSpliner) {\n _updateMousePosition(evt) {\n const rect = this._canvas?.getBoundingClientRect();\n const scaleX = this._canvas.width / rect.width;\n const scaleY = this._canvas.height / rect.height;\n this._mouse = {\n x: (evt.clientX - rect.left) * scaleX,\n y: this._height - (evt.clientY - rect.top) * scaleY\n };\n }\n getPoints() {\n const xFactor = 1 / this._width;\n const yFactor = 1 / this._height;\n return this._pointCollection._points.map(({ x: x, y: y })=>({\n x: x * xFactor,\n y: y * yFactor\n }));\n }\n removeAll() {\n const length = this._pointCollection.getNumberOfPoints();\n for(let i = length; i > 0; i--)this._pointCollection.remove(i - 1);\n }\n update(points) {\n this.removeAll();\n const xFactor = this._width;\n const yFactor = this._height;\n points.forEach(({ x: x, y: y })=>{\n this._pointCollection.add({\n x: x * xFactor,\n y: y * yFactor\n });\n });\n this.draw();\n }\n off(eventName, handler) {\n // @TODO: implement unsibscribe\n }\n}\nconst $2c0e5b77732bcbe8$var$WaveShaperInner = (0, $7gk4U$emotionstyled).div`\n height: 100%;\n width: 100%;\n position: relative;\n canvas {\n border: none !important;\n position: absolute;\n left: 0;\n right: 0;\n height: 100%;\n width: 100%;\n }\n`;\nconst $2c0e5b77732bcbe8$export$2bf7c2638a145e5c = ({ onChange: onChange, onMove: onMove, points: points, type: type = \"monotonic\", textColor: textColor = \"red\", curveColor: curveColor = (0, $d10a6381d028e3f6$export$2e2bcd8739ae039).colors.accent2, gridStep: gridStep = 0.25, gridColor: gridColor = (0, $d10a6381d028e3f6$export$2e2bcd8739ae039).colors.elevation2, controlPointRadius: controlPointRadius = 14, controlPointColor: controlPointColor = (0, $d10a6381d028e3f6$export$2e2bcd8739ae039).colors.vivid1 })=>{\n const ref = (0, $7gk4U$useRef)(null);\n const [spliner, setSpliner] = (0, $7gk4U$useState)();\n const handlePointsChange = (0, $7gk4U$useCallback)((csObj)=>{\n const points = csObj.getPoints();\n onChange?.(points);\n }, [\n onChange\n ]);\n const handlePointMove = (0, $7gk4U$useCallback)((csObj)=>{\n const points = csObj.getPoints();\n onMove?.(points);\n }, [\n onMove\n ]);\n (0, $7gk4U$useEffect)(()=>spliner?.update(points), [\n spliner,\n points\n ]);\n (0, $7gk4U$useEffect)(()=>spliner?.setSplineType(type), [\n spliner,\n type\n ]);\n (0, $7gk4U$useEffect)(()=>spliner?.setGridStep(gridStep), [\n spliner,\n gridStep\n ]);\n (0, $7gk4U$useEffect)(()=>spliner?.setGridColor(gridColor), [\n spliner,\n gridColor\n ]);\n (0, $7gk4U$useEffect)(()=>spliner?.setControlPointRadius(controlPointRadius), [\n spliner,\n controlPointRadius\n ]);\n (0, $7gk4U$useEffect)(()=>spliner?.setTextColor(textColor), [\n spliner,\n textColor\n ]);\n (0, $7gk4U$useEffect)(()=>{\n spliner?.setCurveColor(\"idle\", curveColor);\n // spliner?.setCurveColor(\"moving\", \"yellow\");\n }, [\n spliner,\n curveColor\n ]);\n (0, $7gk4U$useEffect)(()=>{\n spliner?.setControlPointColor(\"idle\", controlPointColor);\n // spliner?.setControlPointColor(\"hovered\", \"blue\");\n // spliner?.setControlPointColor(\"grabbed\", \"black\");\n }, [\n spliner,\n controlPointColor\n ]);\n (0, $7gk4U$useEffect)(()=>{\n if (!spliner) return;\n spliner.setCurveThickness(4);\n spliner.on(\"movePoint\", handlePointMove);\n spliner.on(\"releasePoint\", handlePointsChange);\n spliner.on(\"pointAdded\", handlePointsChange);\n spliner.on(\"pointRemoved\", handlePointsChange);\n spliner.draw();\n return ()=>{\n spliner.off(\"movePoint\", handlePointMove);\n spliner.off(\"releasePoint\", handlePointsChange);\n spliner.off(\"pointAdded\", handlePointsChange);\n spliner.off(\"pointRemoved\", handlePointsChange);\n };\n }, [\n spliner,\n handlePointsChange,\n handlePointMove\n ]);\n (0, $7gk4U$useEffect)(()=>{\n if (!ref.current) return;\n const cs = new $2c0e5b77732bcbe8$var$Spliner(ref.current, 1024, 1024);\n setSpliner(cs);\n }, [\n ref\n ]);\n return (0, $7gk4U$jsx)($2c0e5b77732bcbe8$var$WaveShaperInner, {\n ref: ref\n });\n};\nvar $2c0e5b77732bcbe8$export$2e2bcd8739ae039 = $2c0e5b77732bcbe8$export$2bf7c2638a145e5c;\n\n\n\nconst $149f0c1aa7846f5b$export$555ece15b74b7abc = (0, $7gk4U$emotionstyled).div``;\nconst $149f0c1aa7846f5b$export$ef9ca7b440c0032c = (0, $7gk4U$emotionstyled).div`\n font-family: var(--leva-fonts-mono);\n font-size: 0.7rem;\n color: ${({ theme: theme })=>theme.colors.whitePrimary};\n`;\nconst $149f0c1aa7846f5b$export$bd1dc14d6df7044e = (0, $7gk4U$emotionstyled).div`\n border-bottom: 1px solid ${({ theme: theme })=>theme.colors.elevation1};\n`;\nconst $149f0c1aa7846f5b$export$d56900fc3755b916 = (0, $7gk4U$emotionstyled).div`\n padding: 0.2rem 0.4rem;\n font-size: 0.7rem;\n color: ${({ theme: theme })=>theme.colors.highlight2};\n position: relative;\n display: grid;\n align-items: center;\n grid-template-rows: minmax(1.5rem, max-content);\n grid-template-columns: ${({ oneLineLabels: oneLineLabels })=>oneLineLabels ? \"1fr\" : \"auto 10rem\"};\n row-gap: 0.1rem;\n column-gap: 0.4rem;\n`;\nconst $149f0c1aa7846f5b$export$aac584ace4a7b830 = (0, $7gk4U$emotionstyled).div`\n display: flex;\n flex-direction: column;\n gap: 0.4rem;\n background: ${({ theme: theme })=>theme.colors.elevation2};\n padding: 0.4rem 0.1rem;\n`;\nconst $149f0c1aa7846f5b$export$edaba703bd8b8dfa = (0, $7gk4U$emotionstyled).div``;\n\n\n\n\n\n\nexport {$4001d24decbb98f7$export$2b77a92f1a5ad772 as Modal, $0cdf21d270160c43$export$8ecd240bc8faaeeb as Checker, $fee4ec5a9782241c$export$a98f0dcb43a68a25 as RadioGroup, $4866e5bff8d594b9$export$f5b8910cec6cf069 as Input, $eadb9fa465de5e7c$export$7a40489edcbfb3a1 as DropdownInput, $8d9f8f4bde3307d1$export$5a1d7ca0a925d9c2 as ColorInput, $f537c5f3d37e7de0$export$6bf0cd3a219bbade as NumberInput, $44b7e15e1a9af68f$export$353f5b6fc5456de1 as Button, $6cd47b275e936c4f$export$ef9b1a59e592288f as Select, $145c4d4c74f0de83$export$472062a354075cee as Slider, $2c0e5b77732bcbe8$export$2bf7c2638a145e5c as SplineEditor, $149f0c1aa7846f5b$export$555ece15b74b7abc as ConfigRowLabel, $149f0c1aa7846f5b$export$ef9ca7b440c0032c as ConfigRowControl, $149f0c1aa7846f5b$export$bd1dc14d6df7044e as ConfigRowSeparator, $149f0c1aa7846f5b$export$d56900fc3755b916 as ConfigRow, $149f0c1aa7846f5b$export$aac584ace4a7b830 as ConfigPanel, $149f0c1aa7846f5b$export$edaba703bd8b8dfa as ConfigRowInner};\n//# sourceMappingURL=components.js.map\n","export * from './src/components';\n","export { Modal } from \"./Modal\";\nexport { Checker } from \"./Checker\";\nexport { RadioGroup } from \"./RadioGroup\";\nexport { Input } from \"./Input\";\nexport { DropdownInput } from \"./DropdownInput\";\nexport { ColorInput } from \"./ColorInput\";\nexport { NumberInput } from \"./NumberInput\";\nexport { Button } from \"./Button\";\nexport { Select } from \"./Select\";\nexport { Slider } from \"./Slider\";\nexport { SplineEditor } from \"./SplineEditor\";\nexport {\n ConfigRowLabel,\n ConfigRowControl,\n ConfigRowSeparator,\n ConfigRow,\n ConfigPanel,\n ConfigRowInner,\n} from \"./NodeConfig\";\n","import styled from \"@emotion/styled\";\nimport { type ReactNode, useEffect } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { MdClose as CloseIcon } from \"react-icons/md\";\nimport useTheme from \"../hooks/useTheme\";\nimport { Theme } from \"../theme\";\n\nconst ModalOuter = styled.div<{ theme: Theme }>`\n position: fixed;\n z-index: ${({ theme }) => theme.zIndex.modal};\n width: 100%;\n height: 100%;\n top: 0;\n left: 0;\n background: ${({ theme }) => theme.colors.elevation3}cc;\n display: flex;\n align-items: center;\n justify-content: center;\n`;\n\nconst ModalInner = styled.div<{ theme: Theme }>`\n background: ${({ theme }) => theme.colors.elevation2};\n box-shadow: 1px 1px 1px 1px ${({ theme }) => theme.colors.elevation1};\n color: white;\n width: 70%;\n height: 80%;\n overflow-y: scroll;\n position: relative;\n`;\n\nconst ModalCloser = styled(CloseIcon)<{ theme: Theme }>`\n position: absolute;\n top: 0.2rem;\n right: 0.2rem;\n cursor: pointer;\n`;\n\ninterface ModalProps {\n onClose?: () => void;\n children: ReactNode;\n}\n\nexport const Modal = ({ children, onClose, ...props }: ModalProps) => {\n const theme = useTheme();\n\n useEffect(() => {\n const escHandler = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") {\n onClose?.();\n }\n };\n document.addEventListener(\"keydown\", escHandler);\n return () => {\n document.removeEventListener(\"keydown\", escHandler);\n };\n }, [onClose]);\n\n return createPortal(\n <ModalOuter theme={theme} onClick={onClose}>\n <ModalInner\n {...props}\n onClick={(e) => {\n e.stopPropagation();\n }}\n theme={theme}\n >\n {children}\n <ModalCloser theme={theme} onClick={onClose} />\n </ModalInner>\n </ModalOuter>,\n document.body,\n );\n};\n\nexport default Modal;\n","import { useTheme as useEmotionTheme } from \"@emotion/react\";\nimport type { Theme } from '../theme';\n\nconst useTheme = () => {\n return useEmotionTheme() as Theme;\n}\n\nexport default useTheme;\n","import styled from \"@emotion/styled\";\nimport { type Theme, useTheme } from \"../../../core\";\n\nconst CheckerBox = styled.div<{ theme: Theme }>`\n display: flex;\n align-items: center;\n justify-content: center;\n width: 0.6rem;\n height: 0.6rem;\n background: ${({ theme }) => theme.colors.whitePrimary};\n border: 1px solid ${({ theme }) => theme.colors.highlight1};\n &::after {\n content: \"\";\n background: ${({ theme }) => theme.colors.accent1};\n }\n`;\nconst CheckerLabel = styled.div``;\n\nconst CheckerSubtitle = styled.div<{ theme: Theme }>`\n font-size: 0.4rem;\n color: ${({ theme }) => theme.colors.highlight1};\n`;\n\nconst CheckedInner = styled.label`\n display: flex;\n cursor: pointer;\n gap: 0.4rem;\n line-height: 0.7rem;\n input {\n display: none;\n }\n input[type=\"radio\"] ~ .checker-box {\n border-radius: 50%;\n &::after {\n border-radius: 50%;\n }\n }\n input:checked ~ .checker-box:after {\n width: 70%;\n height: 70%;\n }\n`;\n\nexport interface CheckerItem {\n label: string;\n subtitle?: string;\n value: string | number | boolean | null;\n}\n\ninterface CheckerProps extends CheckerItem {\n name?: string;\n type?: \"radio\" | \"checkbox\";\n onChange?: (checked: boolean) => void;\n checked?: boolean;\n}\n\nexport const Checker = ({\n label,\n subtitle,\n name,\n type = \"checkbox\",\n onChange,\n checked = false,\n}: CheckerProps) => {\n const theme = useTheme();\n\n return (\n <CheckedInner>\n <input\n type={type}\n name={name}\n checked={checked}\n onChange={({ target }) => onChange?.(target.checked)}\n />\n <CheckerBox className=\"checker-box\" theme={theme} />\n <div>\n <CheckerLabel>{label}</CheckerLabel>\n {subtitle ? (\n <CheckerSubtitle theme={theme}>{subtitle}</CheckerSubtitle>\n ) : null}\n </div>\n </CheckedInner>\n );\n};\n\nexport default Checker;\n","export { default as Editor, EDITOR_DEFAULTS } from \"./src/components/App\";\nexport { default as Wire } from \"./src/components/Wire\";\nexport {\n WNNode,\n TitleBar,\n type WNNodeProps,\n PortsPanel,\n OutputPorts,\n OutputHandle,\n InputPorts,\n InputHandle,\n Port,\n} from \"./src/components/Node\";\nexport { default as Modal } from \"./src/components/Modal\";\nexport { default as EditableLabel } from \"./src/components/EditableLabel\";\nexport { default as useAudioNode } from \"./src/hooks/useAudioNode\";\nexport { default as useNode } from \"./src/hooks/useNode\";\nexport { default as useTheme } from \"./src/hooks/useTheme\";\nexport { default as useStore } from \"./src/store\";\nexport { default as theme } from \"./src/theme\";\nexport { isAudio, isPatch } from \"./src/helpers/projectFile\";\n\nexport { PortType } from \"./src/constants\";\n\nexport type {\n WNAudioNode,\n CreateWNAudioNode,\n ControlPanelNodeProps,\n PluginConfig,\n PluginComponent,\n ControlPanelNode,\n WNNodeData,\n WNNode as TWNNode,\n InputPort,\n OutputPort,\n EditorState,\n Project,\n WNEdge as TWNEdge,\n EditorStoreState,\n} from \"./src/types\";\n\nexport type { Theme } from \"./src/theme\";\n","import { css, Global, ThemeProvider, withTheme } from \"@emotion/react\";\nimport styled from \"@emotion/styled\";\nimport { nanoid } from \"nanoid\";\nimport { ComponentProps, ReactNode, useEffect, useMemo, useState } from \"react\";\nimport { FaPlus as IconAdd } from \"react-icons/fa6\";\nimport { MdClose } from \"react-icons/md\";\nimport { registerFetcher } from \"@web-noise/fetch\";\nimport useStore from \"../store\";\nimport \"../styles\";\nimport defaultTheme, { Theme } from \"../theme\";\nimport type {\n EditorFile,\n EditorState,\n PluginConfig,\n Project,\n ProjectFile,\n} from \"../types\";\nimport { Editor } from \"./Editor\";\nimport EditableLabel from \"./EditableLabel\";\nimport { isAudio, isPatch } from \"../helpers/projectFile\";\nimport { fileToBase64 } from \"../lib\";\n\n// @TODO: move default state to editor\nexport const EDITOR_DEFAULTS = {\n nodes: [],\n edges: [],\n controlPanel: {\n nodes: [],\n show: false,\n size: {\n width: 200,\n height: 100,\n },\n },\n viewport: { x: 0, y: 0, zoom: 1.5 },\n};\n\nexport const AppWrapper = withTheme(styled.div<{ theme: Theme }>`\n display: flex;\n flex-direction: column;\n height: 100%;\n width: 100%;\n`);\n\nexport const FileUploadLayout = withTheme(styled.div<{ theme: Theme }>`\n position: fixed;\n height: 100%;\n width: 100%;\n background: rgba(0, 0, 0, 0.7);\n color: white;\n display: flex;\n justify-content: center;\n align-items: center;\n font-size: 2rem;\n`);\n\nexport const EditorContainerWrapper = withTheme(styled.div<{ theme: Theme }>`\n height: 100%;\n width: 100%;\n display: flex;\n position: relative;\n`);\n\nexport const AudioTabWrapper = withTheme(styled.div<{ theme: Theme }>`\n display: flex;\n flex: 1;\n align-items: center;\n justify-content: center;\n background: ${({ theme }) => theme.colors.elevation3};\n`);\n\nexport const EditorLoadingOverlay = withTheme(styled.div<{\n theme: Theme;\n show: boolean;\n}>`\n background: ${({ theme }) => theme.colors.elevation2};\n opacity: 0.7;\n position: absolute;\n width: 100%;\n height: 100%;\n left: 0;\n top: 0;\n z-index: 1;\n font-family: var(--leva-fonts-mono);\n color: ${({ theme }) => theme.colors.whitePrimary};\n display: ${({ show }) => (show ? \"flex\" : \"none\")};\n align-items: center;\n justify-content: center;\n font-size: 6rem;\n`);\n\ntype EditorContainerProps = AppProps & {\n file: ProjectFile;\n};\n\nexport const EditorContainer = (props: EditorContainerProps) => {\n const pullEditorChanges = useStore((store) => store.pullEditorChanges);\n const currentFileIndex = useStore((store) => store.currentFileIndex);\n\n const [showLoader, setShowLoader] = useState(true);\n\n useEffect(() => {\n setShowLoader(true);\n setTimeout(() => {\n setShowLoader(false);\n }, 1600);\n }, [currentFileIndex]);\n\n const { file } = props;\n if (!file) return null;\n\n if (file.type === \"audio\") {\n return (\n <AudioTabWrapper>\n <audio src={file.file} controls />\n </AudioTabWrapper>\n );\n }\n\n return (\n <>\n <Editor\n {...props}\n onChange={(state) => {\n pullEditorChanges();\n }}\n editorState={(file as EditorFile).file || EDITOR_DEFAULTS}\n />\n\n <EditorLoadingOverlay show={showLoader}>Loading...</EditorLoadingOverlay>\n </>\n );\n};\n\nexport const TabsContainer = withTheme(styled.div<{ theme: Theme }>`\n height: 2rem;\n display: flex;\n align-items: center;\n background: ${({ theme }) => theme.colors.elevation2};\n`);\n\nexport const Tab = withTheme(styled.div<{ theme: Theme; active?: boolean }>`\n display: flex;\n align-items: center;\n cursor: pointer;\n height: 100%;\n box-sizing: border-box;\n padding: 0.3rem 0.4rem;\n\n border-right: 1px solid ${({ theme }) => theme.colors.elevation1};\n\n input {\n color: ${({ theme, active }) =>\n active ? theme.colors.whitePrimary : theme.colors.highlight1};\n\n &:not([readonly]):focus {\n background-color: ${({ theme }) => theme.colors.elevation1};\n }\n }\n`);\n\nexport const TabIconWrapper = withTheme(styled.div<{ theme: Theme }>`\n display: flex;\n align-items: center;\n height: 100%;\n padding: 0 0.5rem;\n cursor: pointer;\n\n color: ${({ theme }) => theme.colors.highlight1};\n &:hover {\n color: ${({ theme }) => theme.colors.whitePrimary};\n }\n`);\n\nexport const AddFileIcon = withTheme(styled(IconAdd)<{ theme: Theme }>`\n height: 40%;\n width: auto;\n`);\n\nexport const CloseIcon = withTheme(styled(MdClose)<{ theme: Theme }>`\n height: 70%;\n width: auto;\n cursor: pointer;\n color: ${({ theme }) => theme.colors.highlight1};\n &:hover {\n color: ${({ theme }) => theme.colors.whitePrimary};\n }\n`);\n\nconst generateId = (): string => {\n return nanoid();\n};\n\nconst generateEmptyFile = (): ProjectFile => ({\n file: EDITOR_DEFAULTS,\n name: \"Unnamed\",\n type: \"patch\",\n id: generateId(),\n});\n\ninterface AppProps {\n projectState?: Project;\n plugins?: Array<PluginConfig>;\n editorContextMenu?: Array<ReactNode>;\n onChange?: ({ nodes, edges, controlPanel }: EditorState) => void;\n theme?: Theme;\n}\n\nexport const App = ({ ...props }: AppProps) => {\n const { projectState, theme } = props;\n const currentFileIndex = useStore((store) => store.currentFileIndex);\n const currentFile = useStore(\n (store) => store.project.files[store.currentFileIndex],\n );\n const setCurrentFileIndex = useStore((store) => store.setCurrentFileIndex);\n\n const project = useStore((store) => store.project);\n const setProject = useStore((store) => store.setProject);\n const getProject = useStore((store) => store.getProject);\n const updateFileName = useStore((store) => store.updateFileName);\n\n const addFile = useStore((store) => store.addFile);\n const deleteFile = useStore((store) => store.deleteFile);\n const syncEditorWithCurrentFile = useStore(\n (store) => store.syncEditorWithCurrentFile,\n );\n\n const setEditorState = useStore((store) => store.setEditorState);\n const pullEditorChanges = useStore((store) => store.pullEditorChanges);\n\n const [isDragging, setIsDragging] = useState(false);\n\n const handleDragLeave = (e: React.DragEvent<HTMLDivElement>) => {\n e.preventDefault();\n e.stopPropagation();\n setIsDragging(false);\n };\n\n const handleDragOver = (e: React.DragEvent<HTMLDivElement>) => {\n e.preventDefault();\n e.stopPropagation();\n setIsDragging(true);\n };\n\n const handleDrop = (e: React.DragEvent<HTMLDivElement>) => {\n e.preventDefault();\n e.stopPropagation();\n\n setIsDragging(false);\n\n const files = Array.from(e.dataTransfer.files);\n files.forEach(async (file) => {\n if (file.type === \"application/json\") {\n const fileData = JSON.parse(await file.text());\n if (fileData.files && fileData.files.length) {\n if (\n !window.confirm(\n \"This action will replace your current project. Continue?\",\n )\n ) {\n return;\n }\n setProject(fileData);\n setCurrentFileIndex(0);\n syncEditorWithCurrentFile();\n return;\n }\n const emptyFile = generateEmptyFile();\n const newGraphState = {\n ...emptyFile,\n file: {\n ...fileData,\n controlPanel: {\n ...EDITOR_DEFAULTS.controlPanel,\n ...fileData.controlPanel,\n },\n },\n name: file.name,\n };\n addFile(newGraphState, file.name);\n return;\n }\n if (file.type.match(/^audio\\//)) {\n const base64 = await fileToBase64(file);\n addFile({\n type: \"audio\",\n // @TODO: use nanoid here\n id: `audio-file-${+new Date()}`,\n name: file.name,\n file: base64,\n });\n return;\n }\n console.error(\"Unsupported file type\", file);\n });\n };\n\n useEffect(() => {\n setProject(\n projectState || {\n files: [generateEmptyFile()],\n },\n );\n const file = projectState?.files[0];\n file?.file && file?.type !== \"audio\" && setEditorState(file.file);\n }, [projectState]);\n\n // EXPERIMENTAL CODE\n useEffect(() => {\n const fetcher: typeof fetch = async (...args) => {\n const request = new Request(...args);\n const files = getProject().files;\n const index = request.url.replace(\"project://\", \"\");\n const file = files.find(({ id }) => id === index);\n\n if (!file) {\n return new Response(`File not found: ${request.url}`, { status: 404 });\n }\n\n if (isPatch(file)) {\n return new Response(JSON.stringify(file.file ?? null));\n }\n\n if (isAudio(file)) {\n return fetch(file.file);\n }\n\n return new Response(null);\n };\n registerFetcher(\"project://*\", fetcher);\n return () => {\n //unregister here\n };\n }, [getProject]);\n\n useEffect(() => {\n syncEditorWithCurrentFile();\n }, [currentFileIndex, syncEditorWithCurrentFile]);\n\n return (\n <ThemeProvider theme={theme || defaultTheme}>\n <Global\n styles={css`\n :root {\n --leva-colors-elevation1: #292d39;\n --leva-colors-elevation2: #181c20;\n --leva-colors-elevation3: #373c4b;\n --leva-colors-accent1: #0066dc;\n --leva-colors-accent2: #007bff;\n --leva-colors-accent3: #3c93ff;\n --leva-colors-highlight1: #535760;\n --leva-colors-highlight2: #8c92a4;\n --leva-colors-highlight3: #fefefe;\n --leva-colors-vivid1: #ffcc00;\n --leva-colors-folderWidgetColor: var(--leva-colors-highlight2);\n --leva-colors-folderTextColor: var(--leva-colors-highlight3);\n --leva-colors-toolTipBackground: var(--leva-colors-highlight3);\n --leva-colors-toolTipText: var(--leva-colors-elevation2);\n --leva-radii-xs: 2px;\n --leva-radii-sm: 3px;\n --leva-radii-lg: 10px;\n --leva-space-xs: 3px;\n --leva-space-sm: 6px;\n --leva-space-md: 10px;\n --leva-space-rowGap: 7px;\n --leva-space-colGap: 7px;\n --leva-fonts-mono:\n ui-monospace, SFMono-Regular, Menlo, \"Roboto Mono\", monospace;\n --leva-fonts-sans: system-ui, sans-serif;\n --leva-fontSizes-root: 11px;\n --leva-fontSizes-toolTip: var(--leva-fontSizes-root);\n --leva-sizes-rootWidth: 280px;\n --leva-sizes-controlWidth: 160px;\n --leva-sizes-numberInputMinWidth: 38px;\n --leva-sizes-scrubberWidth: 8px;\n --leva-sizes-scrubberHeight: 16px;\n --leva-sizes-rowHeight: 24px;\n --leva-sizes-folderTitleHeight: 20px;\n --leva-sizes-checkboxSize: 16px;\n --leva-sizes-joystickWidth: 100px;\n --leva-sizes-joystickHeight: 100px;\n --leva-sizes-colorPickerWidth: var(--leva-sizes-controlWidth);\n --leva-sizes-colorPickerHeight: 100px;\n --leva-sizes-imagePreviewWidth: var(--leva-sizes-controlWidth);\n --leva-sizes-imagePreviewHeight: 100px;\n --leva-sizes-monitorHeight: 60px;\n --leva-sizes-titleBarHeight: 39px;\n --leva-shadows-level1: 0 0 9px 0 #00000088;\n --leva-shadows-level2: 0 4px 14px #00000033;\n --leva-borderWidths-root: 0px;\n --leva-borderWidths-input: 1px;\n --leva-borderWidths-focus: 1px;\n --leva-borderWidths-hover: 1px;\n --leva-borderWidths-active: 1px;\n --leva-borderWidths-folder: 1px;\n --leva-fontWeights-label: normal;\n --leva-fontWeights-folder: normal;\n --leva-fontWeights-button: normal;\n }\n `}\n />\n <AppWrapper\n onDragOver={handleDragOver}\n onDragLeave={handleDragLeave}\n onDrop={handleDrop}\n >\n <TabsContainer>\n {project.files.map((file, index) => (\n <Tab\n onClick={() => {\n setCurrentFileIndex(index);\n }}\n key={index}\n active={index === currentFileIndex}\n >\n <EditableLabel\n onChange={(val) => updateFileName(index, val)}\n value={file.name || \"Unnamed\"}\n />\n <CloseIcon\n onClick={(event) => {\n event.stopPropagation();\n if (\n !window.confirm(\"Do you really want to delete this file?\")\n ) {\n return;\n }\n deleteFile(index);\n }}\n />\n </Tab>\n ))}\n <TabIconWrapper\n onClick={() => {\n addFile(generateEmptyFile());\n setCurrentFileIndex(project.files.length);\n }}\n >\n <AddFileIcon />\n </TabIconWrapper>\n </TabsContainer>\n <EditorContainerWrapper>\n <EditorContainer file={currentFile!} {...props} />\n </EditorContainerWrapper>\n {isDragging && (\n <FileUploadLayout>\n Drop file(s) to upload to the project\n </FileUploadLayout>\n )}\n </AppWrapper>\n </ThemeProvider>\n );\n};\n\nexport default App;\n","import {\n addEdge,\n getConnectedEdges,\n NodeTypes,\n OnConnect,\n Viewport,\n} from \"reactflow\";\nimport { create, StateCreator } from \"zustand\";\nimport { setAudioNodeTypes, AudioNodeTypes } from \"@web-noise/patch\";\nimport { CONTROL_PANEL_GRID_CONFIG } from \"../constants\";\nimport generateNodeId from \"../helpers/generateNodeId\";\nimport {\n ControlPanelNode,\n ControlPanelNodes,\n PluginComponent,\n PluginConfig,\n WNEdge,\n WNNode,\n GraphState,\n EditorState,\n ControlPanelState,\n EditorStoreState,\n} from \"../types\";\nimport nodesStateCreator, { NodesState } from \"./nodesStore\";\nimport history, { historyStateCreator, HistoryState } from \"./history\";\nimport audioPatch, {\n AudioPatchState,\n audioPatchStateCreator,\n} from \"./audioPatch\";\nimport projectStateCreator, { ProjectState } from \"./projectStore\";\n\nexport type { AudioNodeTypes, NodesState, GraphState };\n\ninterface EditorConfig {\n showMinimap: boolean;\n}\n\ntype NodesConfiguration = Record<string, PluginComponent>;\n\nexport type StoreState = NodesState &\n HistoryState &\n ProjectState &\n AudioPatchState & {\n setGraph: (elements: { nodes: WNNode[]; edges: WNEdge[] }) => Promise<void>;\n clearGraph: () => void;\n createNode: (node: WNNode) => void;\n createNodes: (node: WNNode[]) => Promise<void>;\n removeNode: (node: WNNode) => void;\n removeNodes: (nodes: WNNode[]) => void;\n removeEdges: (nodes: WNEdge[]) => void;\n onConnect: OnConnect;\n createEdges: (edge: WNEdge[]) => void;\n onEdgesDelete: (edges: WNEdge[]) => void;\n onNodesDelete: (nodes: WNNode[]) => Promise<void>;\n plugins: Array<PluginConfig>;\n setPlugins: (plugins: Array<PluginConfig>) => void;\n nodesConfiguration: NodesConfiguration;\n config: EditorConfig;\n setConfig: (config: Partial<EditorConfig>) => void;\n getEditorState: () => EditorState;\n setEditorState: (state: EditorState) => Promise<void>;\n isHelpShown: boolean;\n toggleHelp: () => void;\n copyBuffer: { nodes: WNNode[]; edges: WNEdge[] };\n copy: (elements: { nodes: WNNode[]; edges: WNEdge[] }) => void;\n copySelectedItems: () => void;\n pasteBuffer: (x: number, y: number) => void;\n /* move to control panel store */\n getControlPanelNode: (node: WNNode) => ControlPanelNode | null;\n controlPanel: ControlPanelState;\n setControlPanelNodes: (nodes: ControlPanelNodes) => void;\n showControlPanel: () => void;\n hideControlPanel: () => void;\n setControlPanelSize: (width: { width: number; height: number }) => void;\n addNodeToControlPanel: (node: WNNode) => void;\n removeNodeFromControlPanel: (node: WNNode) => void;\n removeNodesFromControlPanel: (nodes: WNNode[]) => void;\n /* / move to control panel store */\n viewport: Viewport;\n setViewport: (viewport: Viewport) => void;\n };\n\nexport const stateCreator: StateCreator<StoreState> = (...args) => {\n const [set, get] = args;\n return {\n ...nodesStateCreator(...args),\n ...historyStateCreator(...args),\n ...audioPatchStateCreator(...args),\n ...projectStateCreator(...args),\n\n setGraph: async ({ nodes, edges }) => {\n const {\n patch,\n createNodes,\n createEdges,\n setNodesAndEdges,\n nodes: activeNodes,\n edges: activeEdges,\n } = get();\n setNodesAndEdges({ nodes: [], edges: [] });\n\n await createNodes(nodes);\n createEdges(edges);\n },\n clearGraph: () => {\n const { setGraph } = get();\n setGraph({ nodes: [], edges: [] });\n },\n createNodes: async (nodes) => {\n const { createNode } = get();\n await Promise.all(nodes.map((node) => createNode(node)));\n },\n createNode: (nodeData) => {\n const { addNode, nodesConfiguration } = get();\n\n const { type, id, data } = nodeData;\n\n if (typeof type === \"undefined\") {\n throw new Error(`node type is not defined for node: ${id}`);\n }\n\n const node = {\n ...nodeData,\n data: {\n ...data,\n config: {\n ...nodesConfiguration[type]?.defaultConfig,\n ...data?.config,\n },\n },\n };\n\n addNode(node);\n },\n removeNode: (node) => get().removeNodes([node]),\n removeNodes: (nodes) => {\n const {\n edges,\n nodes: currentNodes,\n onNodesDelete,\n removeEdges,\n removeNodesFromControlPanel,\n } = get();\n const parentNodeIds = nodes.map(({ id }) => id);\n const children = currentNodes.filter(\n ({ parentNode }) => parentNode && parentNodeIds.includes(parentNode),\n );\n const resultingNodes = [...nodes, ...children];\n removeNodesFromControlPanel(resultingNodes);\n const connectedEdges = getConnectedEdges(resultingNodes, edges);\n removeEdges(connectedEdges);\n onNodesDelete(resultingNodes);\n const nodeIds = resultingNodes.map(({ id }) => id);\n set({\n nodes: currentNodes.filter(({ id }) => !nodeIds.includes(id)),\n });\n },\n removeEdges: (edges) => {\n const { edges: currentEdges, onEdgesDelete } = get();\n const edgeIds = edges.map(({ id }) => id);\n onEdgesDelete(edges);\n set({\n edges: currentEdges.filter(({ id }) => !edgeIds.includes(id)),\n });\n },\n createEdges: (newEdges) => {\n const { patch, edges, setEdges } = get();\n setEdges(newEdges);\n },\n onConnect: async (connection) => {\n const { edges, createEdges } = get();\n const newEdges = addEdge(connection, edges);\n createEdges(newEdges);\n },\n onEdgesDelete: (edges) => {\n const { patch } = get();\n },\n onNodesDelete: async (nodes) => {\n const { removeNodesFromControlPanel, patch } = get();\n removeNodesFromControlPanel(nodes);\n },\n plugins: [],\n setPlugins: async (plugins) => {\n const { setNodeTypes } = get();\n set({ plugins });\n\n const nodesConf: NodesConfiguration = plugins.reduce((acc, plugin) => {\n return {\n ...acc,\n ...plugin.components.reduce(\n (subAcc, item) => ({\n ...subAcc,\n [item.type]: item,\n }),\n {},\n ),\n };\n }, {});\n\n const nodeTypes: NodeTypes = Object.keys(nodesConf).reduce(\n (acc, type) => {\n return {\n ...acc,\n [type]: nodesConf[type].node,\n };\n },\n {},\n );\n\n const audioNodeTypes: AudioNodeTypes = Object.keys(nodesConf).reduce(\n (acc, type) => {\n return {\n ...acc,\n [type]: nodesConf[type].audioNode,\n };\n },\n {},\n );\n\n setAudioNodeTypes(audioNodeTypes);\n setNodeTypes(nodeTypes);\n\n set(({ nodesConfiguration }) => ({\n nodesConfiguration: { ...nodesConfiguration, ...nodesConf },\n }));\n },\n nodesConfiguration: {},\n config: { showMinimap: false },\n setConfig: (changes) => {\n set(({ config }) => ({ config: { ...config, ...changes } }));\n },\n getEditorState: () => {\n const { getNodesAndEdges, controlPanel, viewport } = get();\n return {\n ...getNodesAndEdges(),\n controlPanel,\n viewport,\n };\n },\n setEditorState: async ({ nodes, edges, controlPanel, viewport }) => {\n const { setGraph } = get();\n await setGraph({ nodes, edges });\n // @TODO: remove this line once audio patch initialisation is reworked\n await new Promise((r) => setTimeout(r, 1000));\n set({\n controlPanel,\n viewport,\n });\n },\n isHelpShown: false,\n toggleHelp: () => {\n const { isHelpShown: showHelp } = get();\n set({ isHelpShown: !showHelp });\n },\n copyBuffer: { nodes: [], edges: [] },\n copy: (elements) => {\n set({ copyBuffer: elements });\n },\n copySelectedItems: () => {\n const { nodes: currentNodes, edges: currentEdges, copy } = get();\n const nodes = currentNodes.filter(({ selected }) => selected);\n const edges = currentEdges.filter(({ selected }) => selected);\n if (!nodes.length) {\n return;\n }\n copy({ nodes, edges });\n },\n pasteBuffer: (x = 0, y = 0) => {\n const { copyBuffer, createNodes, setEdges, nodes, edges } = get();\n const { nodes: nodesToCopy, edges: edgesToCopy } = copyBuffer;\n\n if (!nodesToCopy.length) {\n return;\n }\n\n set({\n nodes: nodes.map((node) => ({ ...node, selected: false })),\n });\n\n const topLeftNode = nodesToCopy.reduce((acc, node) => {\n if (!acc) {\n return node;\n }\n if (\n node.position.x < acc.position.x &&\n node.position.y < acc.position.y\n ) {\n return node;\n }\n return acc;\n });\n\n const xDelta = topLeftNode.position.x - x;\n const yDelta = topLeftNode.position.y - y;\n\n const { nodes: newNodes, mapping } = nodesToCopy.reduce(\n (acc, node) => {\n const newNodeId = generateNodeId(node);\n return {\n nodes: [\n ...acc.nodes,\n {\n ...node,\n id: newNodeId,\n position: {\n x: node.position.x - xDelta,\n y: node.position.y - yDelta,\n },\n selected: true,\n },\n ],\n mapping: {\n ...acc.mapping,\n [node.id]: newNodeId,\n },\n };\n },\n { nodes: [], mapping: {} } as {\n nodes: Array<WNNode>;\n mapping: Record<WNNode[\"id\"], WNNode[\"id\"]>;\n },\n );\n createNodes(newNodes);\n\n const newEdges = edgesToCopy.map((edge) => {\n const source = mapping[edge.source] || edge.source;\n const target = mapping[edge.target] || edge.target;\n return {\n ...edge,\n id: edge.id.replace(edge.source, source).replace(edge.target, target),\n source,\n target,\n selected: true,\n };\n });\n setEdges([\n ...edges.map((edge) => ({ ...edge, selected: false })),\n ...newEdges,\n ]);\n },\n getControlPanelNode: (node) => {\n const { nodesConfiguration } = get();\n const { type } = node;\n if (!type) {\n return null;\n }\n const controlPanelNode = nodesConfiguration[type]?.controlPanelNode;\n if (!controlPanelNode) {\n console.error(`could not find node for type ${type}`);\n return null;\n }\n return controlPanelNode;\n },\n controlPanel: {\n show: true,\n nodes: [],\n size: {\n width: 200,\n height: 100,\n },\n },\n showControlPanel: () =>\n set(({ controlPanel }) => ({\n controlPanel: { ...controlPanel, show: true },\n })),\n hideControlPanel: () =>\n set(({ controlPanel }) => ({\n controlPanel: { ...controlPanel, show: false },\n })),\n addNodeToControlPanel: (node) => {\n const { nodesConfiguration } = get();\n const defaultConfig = node.type\n ? nodesConfiguration[node.type]?.defaultConfig\n : {};\n const { height } = defaultConfig?.size || {};\n const newNode = {\n id: node.id,\n ...(height\n ? { height: height / CONTROL_PANEL_GRID_CONFIG.rowHeight }\n : {}),\n };\n set(({ controlPanel }) => ({\n controlPanel: {\n ...controlPanel,\n nodes: [...controlPanel.nodes, newNode],\n },\n }));\n },\n removeNodeFromControlPanel: (node) =>\n get().removeNodesFromControlPanel([node]),\n removeNodesFromControlPanel: (nodes) => {\n const nodeIds = nodes.map(({ id }) => id);\n set(({ controlPanel }) => {\n const nodes = controlPanel.nodes.filter(\n ({ id }) => !nodeIds.includes(id),\n );\n return {\n controlPanel: {\n ...controlPanel,\n nodes,\n },\n };\n });\n },\n setControlPanelNodes: (nodes) => {\n set(({ controlPanel }) => {\n return {\n controlPanel: {\n ...controlPanel,\n nodes,\n },\n };\n });\n },\n setControlPanelSize: (size) => {\n set(({ controlPanel }) => {\n return {\n controlPanel: {\n ...controlPanel,\n size,\n },\n };\n });\n },\n\n viewport: { x: 0, y: 0, zoom: 1 },\n setViewport: (viewport) => set({ viewport }),\n };\n};\n\nconst useStore = create<StoreState>(audioPatch(history(stateCreator)));\n\nexport default useStore;\n","export const DRAG_HANDLE_CLASS = \"web-noise-drag-handle\";\nexport const DRAG_HANDLE_SELECTOR = `.${DRAG_HANDLE_CLASS}`;\n\nexport const CONTROL_PANEL_GRID_CONFIG = {\n rowHeight: 10,\n cols: 4,\n};\n\nexport enum PortType {\n Gate = \"gate\",\n Number = \"number\",\n Audio = \"audio\",\n Any = \"any\",\n}\n","import { WNNode } from \"../types\";\n\nconst generateNodeId = (node?: Partial<WNNode>): WNNode[\"id\"] => {\n const random = +new Date() + Math.floor(Math.random() * 1000);\n if (!node?.type) {\n return random.toString();\n }\n return `${node.type}-${random}`;\n};\n\nexport default generateNodeId;\n","import {\n addEdge,\n applyEdgeChanges,\n applyNodeChanges,\n OnConnect,\n OnEdgesChange,\n OnNodesChange,\n NodeTypes,\n} from \"reactflow\";\nimport { StateCreator } from \"zustand\";\nimport { DRAG_HANDLE_SELECTOR } from \"../constants\";\nimport type { WNNode, WNNodeData, WNEdge, GraphState } from \"../types\";\n\n//@TODO: rename to NodesStore\nexport interface NodesState {\n nodes: WNNode[];\n edges: WNEdge[];\n onNodesChange: OnNodesChange;\n onEdgesChange: OnEdgesChange;\n onConnect: OnConnect;\n addNode: (node: WNNode) => void;\n setNodes: (nodes: WNNode[]) => void;\n setEdges: (edges: WNEdge[]) => void;\n setNodesAndEdges: (elements: GraphState) => void;\n getNodesAndEdges: () => GraphState;\n clearElements: () => void;\n getNode: (id: string) => WNNode | null;\n updateNodeData: (id: string, data: Partial<WNNodeData>) => void;\n nodeTypes: NodeTypes;\n setNodeTypes: (nodeTypes: NodeTypes) => void;\n}\n\nconst nodesStateCreator: StateCreator<NodesState> = (set, get) => ({\n nodes: [],\n edges: [],\n onNodesChange: (changes) => {\n set(({ nodes }) => ({\n nodes: applyNodeChanges(changes, nodes).map((node) => ({\n dragHandle: DRAG_HANDLE_SELECTOR,\n ...node,\n })),\n }));\n },\n onEdgesChange: (changes) => {\n set(({ edges }) => ({\n edges: applyEdgeChanges(changes, edges),\n }));\n },\n onConnect: (connection) => {\n set(({ edges }) => ({\n edges: addEdge(connection, edges),\n }));\n },\n addNode: (node) => {\n set(({ nodes }) => ({\n nodes: nodes.concat(node),\n }));\n },\n setNodes: (nodes) => {\n set({\n nodes,\n });\n },\n setEdges: (edges) => {\n set({\n edges,\n });\n },\n setNodesAndEdges: ({ nodes, edges }) => {\n set({\n nodes,\n edges,\n });\n },\n getNodesAndEdges: () => {\n const { nodes, edges } = get();\n return { nodes, edges };\n },\n clearElements: () => {\n set({\n nodes: [],\n edges: [],\n });\n },\n getNode: (id) => {\n const { nodes } = get();\n const node = nodes.find((node) => node.id === id);\n return node || null;\n },\n updateNodeData: (id, data) => {\n set(({ nodes }) => {\n return {\n nodes: nodes.map((node) => {\n if (node.id === id) {\n return {\n ...node,\n data: {\n ...node.data,\n ...data,\n },\n };\n }\n\n return node;\n }),\n };\n });\n },\n nodeTypes: {},\n setNodeTypes: (nodeTypes) => set({ nodeTypes }),\n});\n\nexport default nodesStateCreator;\n","import type { StateCreator } from \"zustand\";\nimport type { StoreState } from \"../\";\nimport * as jsondiffpatch from \"jsondiffpatch\";\nimport type { Delta, FilterContext } from \"jsondiffpatch\";\n\nexport interface HistoryState {\n history: {\n maxHistoryLength: number;\n buffer: Array<Delta>;\n pointer: number;\n skipCollect: boolean;\n push: (changes: Delta) => void;\n back: () => void;\n forward: () => void;\n clear: () => void;\n };\n}\n\nconst cloneObject = <T = unknown>(input: T): T => {\n return JSON.parse(JSON.stringify(input));\n};\n\nexport const historyStateCreator: StateCreator<HistoryState> = (set, get) => ({\n history: {\n maxHistoryLength: 5,\n buffer: [],\n pointer: 0,\n skipCollect: false,\n push: (changes: Delta) => {\n const { history } = get();\n const { maxHistoryLength, skipCollect } = history;\n\n if (skipCollect) {\n set({\n history: {\n ...history,\n skipCollect: false,\n },\n });\n return;\n }\n\n set(({ history }) => {\n if (!history) {\n return {};\n }\n const { buffer, pointer } = history;\n\n const newBuffer = buffer.slice(\n Math.max(pointer - maxHistoryLength + 1, 0),\n pointer,\n );\n\n return {\n history: {\n ...history,\n buffer: [...newBuffer, changes],\n pointer: Math.min(pointer + 1, maxHistoryLength),\n },\n };\n });\n },\n back: () => {\n const { nodes, edges, controlPanel, history } = get() as StoreState;\n const { buffer, pointer } = history;\n\n const patchData = buffer[pointer - 1];\n if (!patchData) {\n return;\n }\n\n const reversedPatchData = jsondiffpatch.reverse(patchData);\n if (!reversedPatchData) {\n return;\n }\n\n const updates = cloneObject({\n nodes,\n edges,\n controlPanel,\n });\n\n const patch = jsondiffpatch.patch(updates, reversedPatchData);\n\n set({\n ...patch,\n history: {\n ...history,\n pointer: pointer - 1,\n skipCollect: true,\n },\n });\n },\n forward: () => {\n const { nodes, edges, controlPanel, history } = get() as StoreState;\n const { buffer, pointer } = history;\n\n const patchData = buffer[pointer];\n if (!patchData) {\n return;\n }\n\n const updates = cloneObject({\n nodes,\n edges,\n controlPanel,\n });\n\n const patch = jsondiffpatch.patch(updates, patchData);\n\n set({\n ...patch,\n history: {\n ...history,\n pointer: pointer + 1,\n skipCollect: true,\n },\n });\n },\n // @TODO: remove this method and store history per file\n clear: () => {\n const { history } = get();\n set({\n history: {\n ...history,\n buffer: [],\n pointer: 0,\n skipCollect: true,\n },\n });\n },\n },\n});\n\nconst COLLECT_CHANGES_DEBOUNCE_TIME = 500;\n\nexport const createChangesCollector = (set: any, get: () => StoreState) => {\n const jsondiffpatchInstance = jsondiffpatch.create({\n propertyFilter: (name: string, context: FilterContext) => {\n //@TODO: rework this function, find better solution\n if (context.parent?.parent?.childName === \"controlPanel\") {\n return true;\n }\n if (\n // @ts-ignore\n [\"data\", \"position\", \"controlPanel\"].includes(context.parent?.childName)\n ) {\n return true;\n }\n return [\n \"controlPanel\",\n \"size\",\n \"edges\",\n\n \"nodes\",\n \"data\",\n \"label\",\n \"config\",\n \"values\",\n\n \"position\",\n \"x\",\n \"y\",\n ].includes(name);\n },\n });\n let oldState: StoreState | null = get();\n let timer: any;\n\n return (state: StoreState, prevState: StoreState) => {\n if (state.currentFileIndex !== prevState.currentFileIndex) {\n get().history.clear();\n }\n clearTimeout(timer);\n if (!oldState) {\n oldState = prevState;\n }\n timer = setTimeout(() => {\n const changes = jsondiffpatchInstance.diff(oldState, state);\n oldState = null;\n\n if (changes) {\n get().history.push(changes);\n }\n }, COLLECT_CHANGES_DEBOUNCE_TIME);\n };\n};\n\ntype StoreStateCreator = StateCreator<StoreState>;\n\nconst history =\n (config: StoreStateCreator): StoreStateCreator =>\n (set, get, api) => {\n const collectChanges = createChangesCollector(set, get);\n api.subscribe(collectChanges);\n return config((...args) => set(...args), get, api);\n };\n\nexport default history;\n","import { createPatch, Patch } from \"@web-noise/patch\";\nimport type { StateCreator } from \"zustand\";\nimport type { StoreState } from \"../\";\nimport { compareGraphs } from \"./compareGraphs\";\n\ntype StoreStateCreator = StateCreator<StoreState>;\nexport interface AudioPatchState {\n patch: Patch;\n nodesState: Record<string, any>;\n}\n\nexport const audioPatchStateCreator: StateCreator<AudioPatchState> = (\n set,\n get,\n) => ({\n patch: createPatch(),\n nodesState: {},\n});\n\nconst audioPatch =\n (config: StoreStateCreator): StoreStateCreator =>\n (set, get, api) => {\n api.subscribe(async (state, prevState) => {});\n\n const promises = new Set<Promise<unknown>>();\n\n let currentState = {\n ...get(),\n nodes: [],\n edges: [],\n };\n\n return config(\n async (...args) => {\n const oldState = get();\n const [storeChanges] = args;\n\n //@ts-ignore\n const newState = {\n ...currentState,\n ...(typeof storeChanges === \"function\"\n ? storeChanges({ ...currentState })\n : storeChanges),\n };\n\n const nodeChanges = compareGraphs(currentState.nodes, newState.nodes);\n const edgeChanges = compareGraphs(currentState.edges, newState.edges);\n\n //@ts-ignore\n currentState = newState;\n\n const newNodes = nodeChanges.added;\n const newEdges = edgeChanges.added;\n const removedEdges = edgeChanges.removed;\n const removedNodes = nodeChanges.removed;\n\n const { patch } = oldState;\n\n if (newNodes.length) {\n const promise = patch.registerAudioNodes(\n //@ts-ignore\n newNodes,\n );\n promises.add(promise);\n await promise;\n promises.delete(promise);\n }\n\n if (!(newEdges.length || removedEdges.length || removedNodes.length)) {\n set(...args);\n return;\n }\n\n if (promises.size) {\n try {\n await Promise.all([...promises.values()]);\n } catch (e) {\n console.log(\"some error\", e);\n }\n }\n\n if (newEdges.length) {\n patch.registerAudioConnections(\n //@ts-ignore\n newEdges,\n );\n }\n\n if (removedEdges.length) {\n //@ts-ignore\n patch.unregisterAudioConnections(removedEdges);\n }\n\n if (removedNodes.length) {\n //@ts-ignore\n patch.unregisterAudioNodes(removedNodes);\n }\n\n set(...args);\n },\n get,\n api,\n );\n };\n\nexport default audioPatch;\n","import { WNEdge, WNNode } from \"../../types\";\n\nexport type GraphItems = Array<WNNode | WNEdge>;\n\nexport interface GraphComparisonResult {\n added: GraphItems;\n removed: GraphItems;\n}\n\nexport const compareGraphs = (\n left: GraphItems,\n right: GraphItems,\n): GraphComparisonResult => {\n const setLeft = new Set(left.map((item) => item.id));\n const setRight = new Set(right.map((item) => item.id));\n\n const added = right.filter((item) => !setLeft.has(item.id));\n const removed = left.filter((item) => !setRight.has(item.id));\n\n return { added, removed };\n};\n","import { StateCreator } from \"zustand\";\nimport type { EditorState, Project, ProjectFile } from \"../types\";\nimport type { StoreState } from \"./\";\nimport { isAudio } from \"../helpers/projectFile\";\n\nexport interface ProjectState {\n project: Project;\n setProject: (project: Project) => void;\n getProject: () => Project;\n\n pullEditorChanges: () => void;\n syncEditorWithCurrentFile: () => void;\n\n //@TODO: move inside project\n currentFileIndex: number;\n setCurrentFileIndex: (index: number) => void;\n\n updateFileContent: (fileIndex: number, file: ProjectFile) => void;\n updateFileName: (fileIndex: number, fileName: string) => void;\n addFile: (file: ProjectFile, name?: string) => void;\n deleteFile: (fileIndex: number) => void;\n}\n\nconst projectStateCreator: StateCreator<ProjectState> = (set, get) => ({\n project: { files: [] },\n setProject(project) {\n set({ project, currentFileIndex: 0 });\n },\n getProject() {\n return get().project;\n },\n\n pullEditorChanges() {\n const { getEditorState, currentFileIndex, updateFileContent, project } =\n get() as StoreState;\n const currentFile = project.files[currentFileIndex];\n if (isAudio(currentFile)) {\n return;\n }\n updateFileContent(currentFileIndex, {\n ...currentFile,\n file: getEditorState(),\n });\n },\n\n syncEditorWithCurrentFile: () => {\n const { currentFileIndex, setEditorState, project } = get() as StoreState;\n const currentFile = project.files[currentFileIndex];\n if (currentFile.type === \"audio\") {\n console.log(\"audio file. skipping\");\n return;\n }\n setEditorState(currentFile.file);\n },\n\n currentFileIndex: 0,\n setCurrentFileIndex(newFileIndex) {\n const { currentFileIndex } = get();\n if (newFileIndex === currentFileIndex) {\n return;\n }\n set({ currentFileIndex: newFileIndex });\n },\n\n updateFileContent(index, file) {\n const { project } = get();\n set({\n project: {\n ...project,\n files: project.files.map((f, i) => {\n if (i === index) {\n return {\n // @TODO check again if merging is really needed here\n ...f,\n ...file,\n };\n }\n return f;\n }),\n },\n });\n },\n updateFileName(index, fileName) {\n const { project } = get();\n set({\n project: {\n ...project,\n files: project.files.map((f, i) => {\n if (i === index) {\n return {\n ...f,\n name: fileName,\n };\n }\n return f;\n }),\n },\n });\n },\n addFile(file) {\n const { project } = get();\n const files = [...project.files, file];\n set({\n project: {\n ...project,\n files,\n },\n });\n },\n deleteFile: (fileIndex) => {\n const { project, currentFileIndex } = get();\n\n set({\n project: {\n ...project,\n files: project.files.filter((_, index) => fileIndex !== index),\n },\n });\n\n if (fileIndex <= currentFileIndex) {\n set({ currentFileIndex: currentFileIndex - 1 });\n }\n },\n});\n\nexport default projectStateCreator;\n","import type { AudioFile, EditorFile, ProjectFile } from \"../types\";\n\nexport const isPatch = (file: ProjectFile): file is EditorFile =>\n !(\"type\" in file) || file.type === \"patch\";\n\nexport const isAudio = (file: ProjectFile): file is AudioFile =>\n file.type === \"audio\";\n","import { injectGlobal } from \"@emotion/css\";\nimport theme from \"./theme\";\n\ninjectGlobal`\n .react-flow {\n .react-flow__pane {\n /* background: rgb(106 106 106); */\n /* background: \"white\"; */\n // background: #292d39;\n background: ${theme.colors.elevation3};\n }\n\n .react-flow__background {\n /* background: #efefef; */\n stroke: white;\n }\n\n .react-flow__node-default {\n background: #292d39;\n color: white;\n border: none;\n /* background: transparent; */\n }\n\n .react-flow__node {\n padding: 0;\n width: auto;\n }\n\n .react-flow__edge-path {\n stroke: ${theme.colors.accent2};\n }\n\n .react-flow__node.selected {\n border: 1px solid ${theme.colors.accent2};\n box-shadow: 0 0 0 0.5px #${theme.colors.accent2};\n }\n\n .react-flow__node-default.selected, .react-flow__node-default.selected:hover {\n box-shadow: 0 0 0 0.5px #${theme.colors.accent2};\n }\n\n /* .react-flow__minimap-mask {\n fill: ${theme.colors.elevation1}\n }\n\n .react-flow__minimap-node {\n fill:${theme.colors.accent2}\n } */\n }\n\n`;\n","const LEVA_COLOR_ACCENT2_BLUE = \"#007bff\";\nconst COLOR_GREEN_PRIMARY = \"#14df42\";\nconst COLOR_WHITE_PRIMARY = \"#ffffff\";\n\nconst colors = <const>{\n elevation1: \"#292d39\", // bg color of the root panel (main title bar)\n elevation2: \"#181c20\", // bg color of the rows (main panel color)\n elevation3: \"#373c4b\", // bg color of the inputs\n accent1: \"#0066dc\",\n accent2: LEVA_COLOR_ACCENT2_BLUE,\n accent3: \"#3c93ff\",\n highlight1: \"#535760\",\n highlight2: \"#8c92a4\",\n highlight3: \"#fefefe\",\n vivid1: COLOR_GREEN_PRIMARY,\n whitePrimary: COLOR_WHITE_PRIMARY,\n error: \"#db5353\",\n};\n\nconst zIndex = <const>{\n modal: 9998,\n controlPanel: 9999,\n resumeContextLayout: 10003,\n};\n\nconst theme = {\n colors,\n zIndex,\n};\n\nexport type Theme = typeof theme;\n\nexport default theme;\n","import {\n type ReactNode,\n useCallback,\n useEffect,\n useMemo,\n useState,\n version,\n} from \"react\";\nimport ReactFlow, {\n Background,\n BackgroundVariant,\n Controls,\n MiniMap,\n ReactFlowInstance,\n ReactFlowProvider,\n useOnViewportChange,\n} from \"reactflow\";\nimport \"reactflow/dist/style.css\";\nimport useStore from \"../../store\";\nimport type { EditorState, PluginConfig } from \"../../types\";\nimport EdgeContextMenu, {\n useEdgeContextMenu,\n} from \"../contextMenu/EdgeContextMenu\";\nimport EditorContextMenu, {\n useEditorContextMenu,\n} from \"../contextMenu/EditorContextMenu\";\nimport NodeContextMenu, {\n useNodeContextMenu,\n} from \"../contextMenu/NodeContextMenu\";\nimport ControlPanel from \"../ControlPanel\";\nimport { HelpButton, HelpModal } from \"../Help\";\nimport ResumeContext from \"../ResumeContext\";\nimport ToggleMinimap from \"../ToggleMinimap\";\nimport Wire from \"../Wire\";\n\nconsole.log(99999, `React version: ${version}`);\n\nconst onNodeDragStop = (_event: any, node: any) =>\n console.log(\"drag stop\", node);\nconst onNodeClick = (_event: any, element: any) =>\n console.log(\"click\", element);\n\nconst snapGrid: [number, number] = [20, 20];\n\ninterface EditorProps {\n editorState?: EditorState;\n plugins?: Array<PluginConfig>;\n editorContextMenu?: Array<ReactNode>;\n onChange?: ({ nodes, edges, controlPanel }: EditorState) => void;\n}\n\nexport const EditorPane = ({\n editorState,\n plugins = [],\n editorContextMenu = [],\n onChange = () => {},\n ...props\n}: EditorProps) => {\n const edgeTypes = useMemo(\n () => ({\n wire: Wire,\n }),\n [],\n );\n\n const {\n nodes,\n edges,\n controlPanel,\n onNodesChange,\n onNodesDelete,\n onEdgesChange,\n onEdgesDelete,\n onConnect,\n setPlugins,\n setViewport,\n viewport,\n } = useStore();\n\n const editorConfig = useStore(({ config }) => config);\n\n const nodeTypes = useStore(({ nodeTypes }) => nodeTypes);\n\n useEffect(() => {\n setPlugins(plugins);\n }, [plugins]);\n\n const [reactflowInstance, setReactflowInstance] =\n useState<ReactFlowInstance | null>(null);\n\n useEffect(() => {\n if (!reactflowInstance) {\n return;\n }\n onChange({\n nodes,\n edges,\n controlPanel,\n viewport,\n });\n }, [nodes, edges, controlPanel, viewport]);\n\n const onInit = useCallback(\n (rfi: ReactFlowInstance) => {\n if (!reactflowInstance) {\n setReactflowInstance(rfi);\n console.log(\"flow loaded:\", rfi);\n }\n },\n [reactflowInstance],\n );\n\n const { onContextMenu: onEditorContextMenu } = useEditorContextMenu();\n const { onContextMenu: onNodeContextMenu } = useNodeContextMenu();\n const { onContextMenu: onEdgeContextMenu } = useEdgeContextMenu();\n\n useEffect(() => {\n if (!viewport) {\n return;\n }\n reactflowInstance?.setViewport(viewport);\n }, [viewport, reactflowInstance]);\n\n useOnViewportChange({\n onEnd: setViewport,\n });\n\n return (\n <ReactFlow\n nodes={nodes}\n edges={edges}\n onNodesChange={onNodesChange}\n onNodesDelete={onNodesDelete}\n onEdgesChange={onEdgesChange}\n onConnect={onConnect}\n onNodeDragStop={onNodeDragStop}\n onEdgesDelete={onEdgesDelete}\n onInit={onInit}\n onNodeClick={onNodeClick}\n onContextMenu={onEditorContextMenu}\n onNodeContextMenu={onNodeContextMenu}\n onEdgeContextMenu={onEdgeContextMenu}\n nodeTypes={nodeTypes}\n edgeTypes={edgeTypes}\n snapGrid={snapGrid}\n defaultViewport={editorState?.viewport}\n defaultEdgeOptions={{ type: \"wire\" }}\n snapToGrid\n fitView\n disableKeyboardA11y\n >\n <Background variant={BackgroundVariant.Dots} gap={12} />\n {editorConfig.showMinimap ? <MiniMap /> : null}\n\n <Controls\n style={{\n right: \"1rem\",\n left: \"initial\",\n bottom: \"40%\",\n top: \"initial\",\n }}\n showInteractive={false}\n >\n <ToggleMinimap />\n <HelpButton />\n </Controls>\n\n <ResumeContext />\n <ControlPanel />\n <HelpModal />\n <EditorContextMenu editorContextMenu={editorContextMenu} />\n <NodeContextMenu />\n <EdgeContextMenu />\n </ReactFlow>\n );\n};\n\nexport const Editor = (props: EditorProps) => (\n <ReactFlowProvider>\n <EditorPane {...props} />\n </ReactFlowProvider>\n);\n\nexport default Editor;\n","import { useCallback } from \"react\";\nimport { useContextMenu } from \"react-contexify\";\nimport \"react-contexify/dist/ReactContexify.css\";\nimport useTheme from \"../../hooks/useTheme\";\nimport useStore from \"../../store\";\nimport { ItemWrapper, MenuWrapper } from \"./styles\";\n\nexport const MENU_ID = \"editor-edge-menu\";\n\nexport const useEdgeContextMenu = () => {\n const { show } = useContextMenu({\n id: MENU_ID,\n });\n\n const onContextMenu = useCallback(\n (event: React.MouseEvent<Element, MouseEvent>, edge: unknown) => {\n event.stopPropagation();\n show(event, { props: { edge } });\n },\n [show],\n );\n\n return { onContextMenu };\n};\n\nconst EdgeContextMenu = () => {\n const theme = useTheme();\n\n const removeEdges = useStore((store) => store.removeEdges);\n\n return (\n <>\n <MenuWrapper id={MENU_ID} animation={false} colors={theme.colors}>\n <ItemWrapper onClick={(event) => removeEdges([event.props.edge])}>\n Delete Edge (DEL)\n </ItemWrapper>\n </MenuWrapper>\n </>\n );\n};\n\nexport default EdgeContextMenu;\n","import styled from \"@emotion/styled\";\nimport { Item, Menu } from \"react-contexify\";\nimport \"react-contexify/dist/ReactContexify.css\";\nimport { Theme } from \"../../theme\";\n\n\nexport const ItemWrapper = styled(Item)``;\n\nexport const MenuWrapper = styled(Menu)<{ colors: Theme[\"colors\"] }>`\n background: ${({ colors }) => colors.elevation2};\n padding: 0;\n border-radius: 0;\n\n .react-contexify__item__content {\n color: ${({ colors }) => colors.whitePrimary};\n }\n\n .react-contexify__separator {\n background-color: ${({ colors }) => colors.elevation1};\n margin: 0;\n }\n`;\n","import downloadFile from \"js-file-download\";\nimport {\n type ReactNode,\n useCallback,\n useEffect,\n useMemo,\n useState,\n} from \"react\";\nimport { Separator, useContextMenu } from \"react-contexify\";\nimport \"react-contexify/dist/ReactContexify.css\";\nimport { useReactFlow, type XYPosition } from \"reactflow\";\nimport hotkeys from \"hotkeys-js\";\nimport useTheme from \"../../hooks/useTheme\";\nimport useStore from \"../../store\";\nimport AddNode from \"../AddNode\";\nimport UploadPatch from \"../UploadPatch\";\nimport UploadProject from \"../UploadProject\";\nimport { ItemWrapper, MenuWrapper } from \"./styles\";\nimport UploadAudio from \"../UploadAudio\";\n\ntype MousePosition = {\n x: number;\n y: number;\n};\n\nexport const MENU_ID = \"editor-menu\";\n\nexport const useEditorContextMenu = () => {\n const { show } = useContextMenu({\n id: MENU_ID,\n });\n\n return { onContextMenu: show };\n};\n\nconst EditorContextMenu = ({\n editorContextMenu = [],\n}: {\n editorContextMenu?: Array<ReactNode>;\n}) => {\n const theme = useTheme();\n\n const [mousePosition, setMousePosition] = useState<MousePosition>({\n x: 0,\n y: 0,\n });\n const [showAddNode, setShowAddNode] = useState(false);\n const [showUploadPatch, setShowUploadPatch] = useState(false);\n const [showUploadProject, setShowUploadProject] = useState(false);\n const [showUploadAudio, setShowUploadAudio] = useState(false);\n\n const addNodeHandler = useCallback(\n (x: number, y: number) => {\n setMousePosition({ x, y });\n setShowAddNode(true);\n },\n [setShowAddNode],\n );\n\n const pasteBuffer = useStore((store) => store.pasteBuffer);\n const { screenToFlowPosition } = useReactFlow();\n const pasteBufferHandler = useCallback(\n (mousePosition: XYPosition) => {\n const { x, y } = screenToFlowPosition(mousePosition);\n pasteBuffer(x, y);\n },\n [setShowAddNode, screenToFlowPosition],\n );\n\n const clearGraph = useStore(({ clearGraph }) => clearGraph);\n\n const getEditorState = useStore((store) => store.getEditorState);\n const getProject = useStore((store) => store.getProject);\n\n const deleteAllHandler = useCallback(() => {\n clearGraph();\n }, [clearGraph]);\n\n const toggleHelp = useStore((store) => store.toggleHelp);\n\n const historyBack = useStore((store) => store.history.back);\n const historyForward = useStore((store) => store.history.forward);\n const historyPointer = useStore((store) => store.history.pointer);\n const historyBuffer = useStore((store) => store.history.buffer);\n\n const copySelectedItems = useStore((store) => store.copySelectedItems);\n const nodes = useStore((store) => store.nodes);\n const selectedNodes = useMemo(\n () => nodes.filter(({ selected }) => selected),\n [nodes],\n );\n const currentCopyBuffer = useStore((store) => store.copyBuffer);\n\n const reactFlowInstance = useReactFlow();\n\n const downloadPatchHandler = useCallback(() => {\n const fileName = \"web-noise-patch.json\";\n const editorState = getEditorState();\n const data = {\n ...editorState,\n };\n downloadFile(JSON.stringify(data, null, 2), fileName);\n }, [getEditorState, reactFlowInstance]);\n\n const downloadProjectHandler = useCallback(() => {\n const fileName = \"web-noise-project.json\";\n const projectState = getProject();\n const data = {\n ...projectState,\n };\n downloadFile(JSON.stringify(data, null, 2), fileName);\n }, [getEditorState, reactFlowInstance]);\n\n useEffect(() => {\n hotkeys(\"command+shift+a\", () => {\n addNodeHandler(200, 50);\n return false;\n });\n //@TODO: find more elegant way to handle ?\n hotkeys(\"shift+/\", () => {\n toggleHelp();\n return false;\n });\n hotkeys(\"command+z\", () => {\n historyBack();\n return false;\n });\n hotkeys(\"command+shift+z\", () => {\n historyForward();\n return false;\n });\n hotkeys(\"command+c\", () => {\n copySelectedItems();\n return false;\n });\n hotkeys(\"command+v\", () => {\n pasteBufferHandler({ x: 200, y: 50 });\n return false;\n });\n return () => {\n hotkeys.unbind();\n };\n }, [addNodeHandler, pasteBufferHandler]);\n\n return (\n <>\n <AddNode\n isOpen={showAddNode}\n closeMenu={() => setShowAddNode(false)}\n mousePosition={mousePosition}\n />\n <UploadPatch\n isOpen={showUploadPatch}\n closeMenu={() => setShowUploadPatch(false)}\n />\n <UploadProject\n isOpen={showUploadProject}\n closeMenu={() => setShowUploadProject(false)}\n />\n <UploadAudio\n isOpen={showUploadAudio}\n closeMenu={() => setShowUploadAudio(false)}\n />\n <MenuWrapper id={MENU_ID} animation={false} colors={theme.colors}>\n <ItemWrapper\n onClick={({ triggerEvent: { clientX, clientY } }) =>\n addNodeHandler(clientX, clientY)\n }\n >\n Add Node (⌘+⇧+A)\n </ItemWrapper>\n <Separator />\n <ItemWrapper onClick={deleteAllHandler}>Delete All</ItemWrapper>\n <Separator />\n <ItemWrapper onClick={downloadPatchHandler}>Download patch</ItemWrapper>\n <ItemWrapper onClick={() => setShowUploadPatch(true)}>\n Upload patch\n </ItemWrapper>\n <Separator />\n <ItemWrapper onClick={downloadProjectHandler}>\n Download project\n </ItemWrapper>\n <ItemWrapper onClick={() => setShowUploadProject(true)}>\n Upload project\n </ItemWrapper>\n <Separator />\n <ItemWrapper onClick={() => setShowUploadAudio(true)}>\n Upload Audio File\n </ItemWrapper>\n <Separator />\n <ItemWrapper disabled={historyPointer === 0} onClick={historyBack}>\n Undo (⌘+z)\n </ItemWrapper>\n <ItemWrapper\n disabled={historyPointer === historyBuffer.length}\n onClick={historyForward}\n >\n Redo (⌘+⇧+Z)\n </ItemWrapper>\n <Separator />\n <ItemWrapper\n disabled={!selectedNodes.length}\n onClick={copySelectedItems}\n >\n Copy Selected (⌘+c)\n </ItemWrapper>\n <ItemWrapper\n disabled={!currentCopyBuffer.nodes.length}\n onClick={({ triggerEvent: { clientX: x, clientY: y } }) =>\n pasteBufferHandler({ x, y })\n }\n >\n Paste (⌘+v)\n </ItemWrapper>\n <Separator />\n {editorContextMenu.map((item, index) => (\n <ItemWrapper key={index}>{item}</ItemWrapper>\n ))}\n <Separator />\n <ItemWrapper onClick={toggleHelp}>Help (⇧+?)</ItemWrapper>\n </MenuWrapper>\n </>\n );\n};\n\nexport default EditorContextMenu;\n","import styled from \"@emotion/styled\";\nimport { MouseEvent, useCallback, useState } from \"react\";\nimport { Position, useReactFlow } from \"reactflow\";\nimport useTheme from \"../../hooks/useTheme\";\nimport useStore from \"../../store\";\nimport { Theme } from \"../../theme\";\nimport { PluginComponent } from \"../../types\";\nimport Modal from \"../Modal\";\nimport Filters, { FiltersState } from \"./Filters\";\nimport Plugins from \"./Plugins\";\n\ninterface AddNodeProps {\n isOpen: boolean;\n closeMenu: () => void;\n mousePosition: MousePosition;\n}\n\ntype MousePosition = {\n x: number;\n y: number;\n};\n\nconst AddNodeWrapper = styled.div<{ theme: Theme }>`\n height: 100%;\n width: 100%;\n display: flex;\n gap: 1rem;\n`;\n\nconst PluginsPanel = styled.div<{ theme: Theme }>`\n flex-grow: 1;\n height: 100%;\n overflow-y: scroll;\n`;\n\nconst AddNode = ({ isOpen, closeMenu, mousePosition }: AddNodeProps) => {\n const theme = useTheme();\n const { screenToFlowPosition } = useReactFlow();\n\n const { createNode } = useStore(({ createNode }) => ({\n createNode,\n }));\n\n const [filtersState, setFiltersState] = useState<FiltersState>({});\n\n const onComponentClick = useCallback(\n ({ type }: PluginComponent) => {\n const { x, y } = screenToFlowPosition(mousePosition);\n const newNode = {\n //@TODO: generate node id in `createNode` function\n id: `${type}-${+new Date()}`,\n type,\n data: { label: type },\n position: {\n x,\n y,\n },\n targetPosition: Position.Left,\n sourcePosition: Position.Right,\n };\n createNode(newNode);\n closeMenu();\n },\n [mousePosition, screenToFlowPosition, createNode, closeMenu, mousePosition],\n );\n\n return isOpen ? (\n <Modal\n onClose={() => {\n closeMenu();\n setFiltersState({});\n }}\n >\n <AddNodeWrapper theme={theme}>\n <Filters onChange={setFiltersState} value={filtersState} />\n <PluginsPanel theme={theme}>\n <Plugins\n filters={filtersState}\n onTagClick={(tag) => {\n setFiltersState((state) => ({\n ...state,\n tags: state.tags?.includes(tag)\n ? state.tags.filter((t) => t !== tag)\n : [...(state.tags || []), tag],\n }));\n }}\n onComponentClick={(component) => {\n onComponentClick(component);\n setFiltersState({});\n }}\n />\n </PluginsPanel>\n </AddNodeWrapper>\n </Modal>\n ) : null;\n};\n\nexport default AddNode;\n","import styled from \"@emotion/styled\";\nimport { withTheme } from \"@emotion/react\";\nimport { useEffect, useRef } from \"react\";\nimport useTheme from \"../../hooks/useTheme\";\nimport useStore from \"../../store\";\nimport { Theme } from \"../../theme\";\nimport { PluginTag, TagsList } from \"./Plugins\";\n\nconst InputWrapper = styled.div`\n display: flex;\n position: relative;\n`;\n\nconst InputInner = styled.input<{ theme: Theme }>`\n padding-right: 2rem;\n padding-left: 0.3rem;\n width: 100%;\n appearance: textfield;\n font-size: inherit;\n background: none;\n border: none;\n color: var(--leva-colors-highlight1);\n font-family: var(--leva-fonts-mono);\n cursor: inherit;\n text-overflow: ellipsis;\n outline: none;\n appearance: textfield;\n cursor: auto;\n background-color: ${({ theme }) => theme.colors.elevation3};\n border-radius: 0.1rem;\n height: 2rem;\n color: ${({ theme }) => theme.colors.highlight2};\n\n &:focus,\n &:hover {\n box-shadow: 0 0 0 var(--leva-borderWidths-focus)\n ${({ theme }) => theme.colors.accent2};\n color: ${({ theme }) => theme.colors.whitePrimary};\n }\n &::-webkit-inner-spin-button,\n &::-webkit-outer-spin-button {\n -webkit-appearance: none;\n margin-right: 1rem;\n }\n`;\n\nconst FiltersWrapper = styled.div<{ theme: Theme }>`\n display: flex;\n flex-direction: column;\n padding: 0.6rem;\n gap: 0.6rem;\n border-right: 1px solid ${({ theme }) => theme.colors.elevation3};\n min-width: 14rem;\n`;\n\nconst PluginName = styled.label<{ theme: Theme }>`\n user-select: none;\n input {\n display: none;\n }\n input:checked + span {\n color: ${({ theme }) => theme.colors.accent2};\n }\n &:hover {\n color: ${({ theme }) => theme.colors.accent3};\n cursor: pointer;\n }\n`;\n\nconst StyledPluginTag = withTheme(styled(PluginTag)<{ theme: Theme }>`\n font-size: 12px;\n padding: 0.2rem 0.4rem;\n &:hover {\n }\n &::after {\n content: \"×\";\n margin-left: 0.4rem;\n }\n`);\n\nexport interface FiltersState {\n search?: string;\n plugin?: string | null;\n tags?: string[];\n}\n\ninterface FiltersProps {\n value: FiltersState;\n onChange: (filters: FiltersState) => void;\n}\n\nconst Filters = ({ onChange, value }: FiltersProps) => {\n const theme = useTheme();\n const plugins = useStore(({ plugins }) => plugins);\n\n const inputRef = useRef<HTMLInputElement>(null);\n\n useEffect(() => {\n if (!inputRef.current) {\n return;\n }\n inputRef.current.focus();\n }, [inputRef]);\n\n return (\n <FiltersWrapper theme={theme}>\n <InputWrapper>\n <InputInner\n ref={inputRef}\n theme={theme}\n value={value.search || \"\"}\n placeholder=\"search...\"\n onChange={(event) =>\n onChange({ ...value, search: event.target.value })\n }\n />\n </InputWrapper>\n <TagsList>\n {value.tags?.map((tag, index) => (\n <StyledPluginTag\n key={index}\n isActive\n onClick={() => {\n const newTags = value.tags?.filter((t) => t !== tag) || [];\n onChange({ ...value, tags: newTags });\n }}\n >\n {tag}\n </StyledPluginTag>\n ))}\n </TagsList>\n {plugins.map(({ name, components }, index) => {\n if (!name) {\n return null;\n }\n return (\n <PluginName theme={theme} key={index}>\n <input\n type=\"checkbox\"\n name=\"plugin\"\n value={name}\n checked={name === value.plugin}\n onChange={() => {\n onChange({\n ...value,\n plugin: name === value.plugin ? null : name,\n });\n }}\n />\n <span>{name}</span>\n </PluginName>\n );\n })}\n </FiltersWrapper>\n );\n};\n\nexport default Filters;\n","import styled from \"@emotion/styled\";\nimport { useMemo } from \"react\";\nimport useStore from \"../../store\";\nimport { Theme } from \"../../theme\";\nimport { PluginComponent } from \"../../types\";\nimport { FiltersState } from \"./Filters\";\nimport { withTheme } from \"@emotion/react\";\n\nconst PluginsWrapper = withTheme(styled.div<{ theme: Theme }>`\n width: 100%;\n`);\n\nconst PluginWrapper = withTheme(styled.div<{ theme: Theme }>`\n padding: 1rem;\n display: flex;\n flex-direction: column;\n gap: 1rem;\n`);\n\nconst NodesList = withTheme(styled.ul<{ theme: Theme }>`\n list-style: none;\n margin: 0;\n padding: 0;\n padding-bottom: 10px;\n columns: 2;\n\n li {\n display: flex;\n flex-direction: column;\n gap: 8px;\n padding: 4px;\n overflow: hidden;\n border: 1px solid ${({ theme }) => theme.colors.elevation3};\n border-radius: 4px;\n margin-bottom: 0.5rem;\n &:hover {\n border-color: ${({ theme }) => theme.colors.accent2};\n cursor: pointer;\n }\n }\n`);\n\nconst NodeTitle = withTheme(styled.div<{ theme: Theme }>`\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n`);\n\nconst NodeDescription = withTheme(styled.div<{ theme: Theme }>`\n color: ${({ theme }) => theme.colors.highlight2};\n font-size: 12px;\n`);\n\nexport const TagsList = withTheme(styled.div<{ theme: Theme }>`\n display: flex;\n gap: 0.2rem;\n flex-wrap: wrap;\n`);\n\nexport const PluginTag = withTheme(styled.span<{\n theme: Theme;\n isActive?: boolean;\n}>`\n cursor: pointer;\n font-size: 10px;\n background: ${({ theme, isActive }) =>\n isActive ? theme.colors.highlight1 : theme.colors.elevation3};\n border-radius: 2px;\n padding: 0.1rem 0.2rem;\n border: 1px solid;\n border-color: ${({ theme }) => theme.colors.elevation2};\n &:hover {\n border-color: ${({ theme }) => theme.colors.accent2};\n }\n`);\n\nconst PluginHeader = withTheme(styled.div<{ theme: Theme }>``);\n\nconst PluginTitle = withTheme(styled.div<{ theme: Theme }>`\n font-size: 1.1rem;\n padding: 0.25rem 0;\n color: ${({ theme }) => theme.colors.highlight3};\n`);\n\nconst PluginDescription = withTheme(styled.div<{ theme: Theme }>`\n color: ${({ theme }) => theme.colors.highlight2};\n font-size: 12px;\n`);\n\ninterface PluginsProps {\n filters: FiltersState;\n onComponentClick: (component: PluginComponent) => void;\n onTagClick: (tag: string) => void;\n}\n\nconst Plugins = ({\n onComponentClick,\n filters: { plugin, search = \"\", tags },\n onTagClick,\n}: PluginsProps) => {\n const plugins = useStore(({ plugins }) => plugins);\n\n const pluginsGroup = useMemo(() => {\n if (!plugin) {\n return plugins;\n }\n return plugins.filter(({ name }) => name === plugin);\n }, [plugins, plugin]);\n\n const filteredPlugins = useMemo(() => {\n if (!search && !tags?.length) {\n return pluginsGroup;\n }\n const filteredByTags = pluginsGroup.map((plugin) => ({\n ...plugin,\n components: tags?.length\n ? plugin.components.filter((component) =>\n tags?.every((tag) => component.tags?.includes(tag)),\n )\n : plugin.components,\n }));\n return filteredByTags.map((plugin) => ({\n ...plugin,\n components: plugin.components.filter(\n ({ type, name }) =>\n type.toLocaleLowerCase().includes(search.toLocaleLowerCase()) ||\n name?.toLocaleLowerCase().includes(search.toLocaleLowerCase()),\n ),\n }));\n }, [pluginsGroup, search, tags]);\n\n return (\n <PluginsWrapper>\n {filteredPlugins.map(({ name, description, components }, index) => {\n if (!components.length) {\n return null;\n }\n return (\n <PluginWrapper key={index}>\n <PluginHeader>\n <PluginTitle>{name}</PluginTitle>\n <PluginDescription>{description}</PluginDescription>\n </PluginHeader>\n <NodesList>\n {components\n .sort((a, b) =>\n a.type.toLowerCase() > b.type.toLowerCase() ? 1 : -1,\n )\n .map((component, idx) => (\n <li onClick={() => onComponentClick(component)} key={idx}>\n <NodeTitle>{component.name || component.type}</NodeTitle>\n {component.description && (\n <NodeDescription>{component.description}</NodeDescription>\n )}\n <TagsList>\n {component.tags?.map((tag, tagIdx) => (\n <PluginTag\n isActive={tags?.includes(tag)}\n onClickCapture={(event) => {\n event.stopPropagation();\n onTagClick(tag);\n }}\n key={tagIdx}\n >\n {tag}\n </PluginTag>\n ))}\n </TagsList>\n </li>\n ))}\n </NodesList>\n </PluginWrapper>\n );\n })}\n </PluginsWrapper>\n );\n};\n\nexport default Plugins;\n","import styled from \"@emotion/styled\";\nimport { MouseEvent, useCallback, useState, useRef, ChangeEvent } from \"react\";\nimport { FileDrop } from \"react-file-drop\";\nimport { FaFileUpload } from \"react-icons/fa\";\nimport useTheme from \"../hooks/useTheme\";\nimport useStore from \"../store\";\nimport { Theme } from \"../theme\";\nimport Modal from \"./Modal\";\n\ninterface UploadPatchProps {\n isOpen: boolean;\n closeMenu: () => void;\n}\n\nconst UploadPatchWrapper = styled.div<{ theme: Theme }>`\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n width: 100%;\n\n .drop-zone-wrapper {\n width: 80%;\n height: 80%;\n }\n\n .drop-zone {\n height: 100%;\n width: 100%;\n border-style: dashed;\n border-width: 2px;\n border-color: ${({ theme }) => theme.colors.highlight2};\n opacity: 0.5;\n cursor: pointer;\n }\n\n .drop-zone:hover,\n .drop-zone-drag-over {\n opacity: 1;\n }\n`;\n\nconst DropZoneInner = styled.div<{ theme: Theme }>`\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: center;\n height: 100%;\n width: 100%;\n`;\n\nconst FileUploadIcon = styled(FaFileUpload)`\n width: 100%;\n height: 8rem;\n`;\n\nconst FileUploadMessage = styled.div`\n font-size: 2rem;\n`;\n\nconst UploadPatch = ({ isOpen, closeMenu }: UploadPatchProps) => {\n const theme = useTheme();\n\n const setGraph = useStore(({ setGraph }) => setGraph);\n const setEditorState = useStore((store) => store.setEditorState);\n\n const fileInputRef = useRef<HTMLInputElement>(null);\n\n const uploadFile = useCallback(\n (files: FileList | null) => {\n const [file] = files || [];\n file\n .text()\n .then(JSON.parse)\n .then((editorState) => {\n setEditorState(editorState);\n closeMenu();\n })\n .catch(console.error);\n },\n [setGraph, closeMenu],\n );\n\n const onTargetClick = () => {\n fileInputRef.current?.click();\n };\n\n return isOpen ? (\n <Modal onClose={closeMenu}>\n <UploadPatchWrapper theme={theme}>\n <input\n onChange={({ target: { files } }) => uploadFile(files)}\n ref={fileInputRef}\n type=\"file\"\n className=\"hidden\"\n style={{ display: \"none\" }}\n accept=\".json\"\n />\n <FileDrop\n className=\"drop-zone-wrapper\"\n targetClassName=\"drop-zone\"\n draggingOverTargetClassName=\"drop-zone-drag-over\"\n onTargetClick={onTargetClick}\n onDrop={(files) => uploadFile(files)}\n >\n <DropZoneInner theme={theme}>\n <FileUploadIcon />\n <FileUploadMessage>click or drop file here</FileUploadMessage>\n </DropZoneInner>\n </FileDrop>\n </UploadPatchWrapper>\n </Modal>\n ) : null;\n};\n\nexport default UploadPatch;\n","import styled from \"@emotion/styled\";\nimport { useCallback, useRef } from \"react\";\nimport { FileDrop } from \"react-file-drop\";\nimport { FaFileUpload } from \"react-icons/fa\";\nimport useTheme from \"../hooks/useTheme\";\nimport useStore from \"../store\";\nimport { Theme } from \"../theme\";\nimport Modal from \"./Modal\";\n\ninterface UploadProjectProps {\n isOpen: boolean;\n closeMenu: () => void;\n}\n\nconst UploadProjectWrapper = styled.div<{ theme: Theme }>`\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n width: 100%;\n\n .drop-zone-wrapper {\n width: 80%;\n height: 80%;\n }\n\n .drop-zone {\n height: 100%;\n width: 100%;\n border-style: dashed;\n border-width: 2px;\n border-color: ${({ theme }) => theme.colors.highlight2};\n opacity: 0.5;\n cursor: pointer;\n }\n\n .drop-zone:hover,\n .drop-zone-drag-over {\n opacity: 1;\n }\n`;\n\nconst DropZoneInner = styled.div<{ theme: Theme }>`\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: center;\n height: 100%;\n width: 100%;\n`;\n\nconst FileUploadIcon = styled(FaFileUpload)`\n width: 100%;\n height: 8rem;\n`;\n\nconst FileUploadMessage = styled.div`\n font-size: 2rem;\n`;\n\n// @TODO: unify with upload file\nconst UploadProject = ({ isOpen, closeMenu }: UploadProjectProps) => {\n const theme = useTheme();\n\n const setProject = useStore((store) => store.setProject);\n\n const fileInputRef = useRef<HTMLInputElement>(null);\n\n const uploadFile = useCallback(\n (files: FileList | null) => {\n const [file] = files || [];\n file\n .text()\n .then(JSON.parse)\n .then((projectState) => {\n setProject(projectState);\n closeMenu();\n })\n .catch(console.error);\n },\n [setProject, closeMenu],\n );\n\n const onTargetClick = () => {\n fileInputRef.current?.click();\n };\n\n return isOpen ? (\n <Modal onClose={closeMenu}>\n <UploadProjectWrapper theme={theme}>\n <input\n onChange={({ target: { files } }) => uploadFile(files)}\n ref={fileInputRef}\n type=\"file\"\n className=\"hidden\"\n style={{ display: \"none\" }}\n accept=\".json\"\n />\n <FileDrop\n className=\"drop-zone-wrapper\"\n targetClassName=\"drop-zone\"\n draggingOverTargetClassName=\"drop-zone-drag-over\"\n onTargetClick={onTargetClick}\n onDrop={(files) => uploadFile(files)}\n >\n <DropZoneInner theme={theme}>\n <FileUploadIcon />\n <FileUploadMessage>click or drop file here</FileUploadMessage>\n </DropZoneInner>\n </FileDrop>\n </UploadProjectWrapper>\n </Modal>\n ) : null;\n};\n\nexport default UploadProject;\n","import styled from \"@emotion/styled\";\nimport { MouseEvent, useCallback, useState, useRef, ChangeEvent } from \"react\";\nimport { FileDrop } from \"react-file-drop\";\nimport { FaFileUpload } from \"react-icons/fa\";\nimport useTheme from \"../hooks/useTheme\";\nimport useStore from \"../store\";\nimport { Theme } from \"../theme\";\nimport Modal from \"./Modal\";\nimport { fileToBase64 } from \"../lib\";\n\ninterface UploadAudioProps {\n isOpen: boolean;\n closeMenu: () => void;\n}\n\nconst UploadAudioWrapper = styled.div<{ theme: Theme }>`\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n width: 100%;\n\n .drop-zone-wrapper {\n width: 80%;\n height: 80%;\n }\n\n .drop-zone {\n height: 100%;\n width: 100%;\n border-style: dashed;\n border-width: 2px;\n border-color: ${({ theme }) => theme.colors.highlight2};\n opacity: 0.5;\n cursor: pointer;\n }\n\n .drop-zone:hover,\n .drop-zone-drag-over {\n opacity: 1;\n }\n`;\n\nconst DropZoneInner = styled.div<{ theme: Theme }>`\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: center;\n height: 100%;\n width: 100%;\n`;\n\nconst FileUploadIcon = styled(FaFileUpload)`\n width: 100%;\n height: 8rem;\n`;\n\nconst FileUploadMessage = styled.div`\n font-size: 2rem;\n`;\n\nconst UploadAudio = ({ isOpen, closeMenu }: UploadAudioProps) => {\n const theme = useTheme();\n\n const setGraph = useStore(({ setGraph }) => setGraph);\n const setEditorState = useStore((store) => store.setEditorState);\n const addFile = useStore((store) => store.addFile);\n\n const fileInputRef = useRef<HTMLInputElement>(null);\n\n const uploadFile = useCallback(\n async (files: FileList | null) => {\n const [file] = files || [];\n const base64 = await fileToBase64(file);\n addFile({\n type: \"audio\",\n // @TODO: use nanoid here\n id: `audio-file-${+new Date()}`,\n name: file.name,\n file: base64,\n });\n closeMenu();\n },\n [addFile, closeMenu],\n );\n\n const onTargetClick = () => {\n fileInputRef.current?.click();\n };\n\n return isOpen ? (\n <Modal onClose={closeMenu}>\n <UploadAudioWrapper theme={theme}>\n <input\n onChange={({ target: { files } }) => uploadFile(files)}\n ref={fileInputRef}\n type=\"file\"\n className=\"hidden\"\n style={{ display: \"none\" }}\n accept=\".wav,.mp3,.ogg\"\n />\n <FileDrop\n className=\"drop-zone-wrapper\"\n targetClassName=\"drop-zone\"\n draggingOverTargetClassName=\"drop-zone-drag-over\"\n onTargetClick={onTargetClick}\n onDrop={(files) => uploadFile(files)}\n >\n <DropZoneInner theme={theme}>\n <FileUploadIcon />\n <FileUploadMessage>click or drop file here</FileUploadMessage>\n </DropZoneInner>\n </FileDrop>\n </UploadAudioWrapper>\n </Modal>\n ) : null;\n};\n\nexport default UploadAudio;\n","export { useWorker } from \"./hooks/useWorker\";\nexport { useMessageChannel } from \"./hooks/useMessageChannel\";\nexport * from \"./helpers\";\n","import { useEffect, useState } from \"react\";\n\nexport const useWorker = (url: string | URL) => {\n const [worker, setWorker] = useState<Worker | null>(null);\n\n useEffect(() => {\n const newWorker = new Worker(url);\n setWorker(newWorker);\n return () => {\n newWorker?.terminate();\n setWorker(null);\n };\n }, []);\n\n return worker;\n};\n\nexport default useWorker;\n","import { useEffect, useState, version } from \"react\";\n\nconsole.log(888888, `React version: ${version}`);\n\nexport const useMessageChannel = () => {\n const [channel, setChannel] = useState<MessageChannel | null>(null);\n useEffect(() => {\n const newChannel = new MessageChannel();\n newChannel.port2.start();\n setChannel(newChannel);\n return () => {\n setChannel(null);\n newChannel.port2.close();\n };\n }, []);\n return channel;\n};\n\nexport default useMessageChannel;\n","export const setParameterValue = (\n param: AudioParam,\n value: number | undefined,\n audioContext: AudioContext,\n): void => {\n if (typeof value === \"undefined\") {\n return;\n }\n param.setValueAtTime(value, audioContext.currentTime);\n};\n\nexport const fileToBase64 = (file: File): Promise<string> => {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.readAsDataURL(file);\n reader.onload = () => resolve(reader.result?.toString() || \"\");\n reader.onerror = (error) => reject(error);\n });\n};\n","import { useCallback } from \"react\";\nimport { useContextMenu, PredicateParams } from \"react-contexify\";\nimport \"react-contexify/dist/ReactContexify.css\";\nimport { WNNode } from \"../../types\";\nimport useTheme from \"../../hooks/useTheme\";\nimport useStore from \"../../store\";\nimport { ItemWrapper, MenuWrapper } from \"./styles\";\n\nexport const MENU_ID = \"editor-node-menu\";\n\nexport const useNodeContextMenu = () => {\n const { show } = useContextMenu({\n id: MENU_ID,\n });\n\n const onContextMenu = useCallback(\n (event: React.MouseEvent<Element, MouseEvent>, node: unknown) => {\n event.stopPropagation();\n show(event, { props: { node } });\n },\n [],\n );\n\n return { onContextMenu };\n};\n\nconst NodeContextMenu = (args: unknown) => {\n const theme = useTheme();\n\n const removeNodes = useStore((store) => store.removeNodes);\n const addNodeToControlPanel = useStore(\n (store) => store.addNodeToControlPanel,\n );\n const removeNodeFromControlPanel = useStore(\n (store) => store.removeNodeFromControlPanel,\n );\n const copy = useStore((store) => store.copy);\n const nodesConfiguration = useStore((store) => store.nodesConfiguration);\n const controlPanelNodes = useStore((store) => store.controlPanel.nodes);\n\n const isOnControlPanel = useCallback(\n ({ props }: PredicateParams<{ node: WNNode }>) => {\n if (!props?.node.type) {\n return false;\n }\n return !!controlPanelNodes.find(({ id }) => id === props.node.id);\n },\n [controlPanelNodes],\n );\n\n const hasControlPanelNode = useCallback(\n ({ props }: PredicateParams<{ node: WNNode }>) => {\n if (!props?.node.type) {\n return false;\n }\n const nodeConfiguration = nodesConfiguration[props.node.type];\n return !!nodeConfiguration?.controlPanelNode;\n },\n [nodesConfiguration],\n );\n\n return (\n <>\n <MenuWrapper id={MENU_ID} animation={false} colors={theme.colors}>\n <ItemWrapper onClick={(event) => removeNodes([event.props.node])}>\n Delete Node (DEL)\n </ItemWrapper>\n <ItemWrapper\n hidden={(...args) =>\n !hasControlPanelNode(...args) || isOnControlPanel(...args)\n }\n onClick={(event) => addNodeToControlPanel(event.props.node)}\n >\n Add To Control Panel\n </ItemWrapper>\n <ItemWrapper\n hidden={(...args) =>\n !hasControlPanelNode(...args) || !isOnControlPanel(...args)\n }\n onClick={(event) => removeNodeFromControlPanel(event.props.node)}\n >\n Remove From Control Panel\n </ItemWrapper>\n <ItemWrapper\n onClick={(event) => copy({ nodes: [event.props.node], edges: [] })}\n >\n Copy (⌘+c)\n </ItemWrapper>\n </MenuWrapper>\n </>\n );\n};\n\nexport default NodeContextMenu;\n","import styled from \"@emotion/styled\";\nimport { Resizable } from \"re-resizable\";\nimport { useMemo, useRef, useState } from \"react\";\nimport GridLayout from \"react-grid-layout\";\nimport \"react-grid-layout/css/styles.css\";\nimport {\n AiFillLock as LockIcon,\n AiFillUnlock as UnlockIcon,\n} from \"react-icons/ai\";\nimport { MdClose as CloseIcon } from \"react-icons/md\";\nimport { RxDashboard as ControlPanelIcon } from \"react-icons/rx\";\nimport Drawer from \"react-modern-drawer\";\nimport \"react-modern-drawer/dist/index.css\";\nimport { CONTROL_PANEL_GRID_CONFIG } from \"../../constants\";\nimport useTheme from \"../../hooks/useTheme\";\nimport useStore from \"../../store\";\nimport { Theme } from \"../../theme\";\nimport ControlPanelItem from \"./ControlPanelItem\";\nimport { IconsBar, IconWrapper, PanelTitle, TitleBarWrapper } from \"./styles\";\n\nconst ControlPanelIconWrapper = styled.div<{ theme: Theme }>`\n position: fixed;\n z-index: 5;\n box-shadow: 0px 1px 2px ${({ theme }) => theme.colors.elevation2};\n left: 1rem;\n top: 4rem;\n width: 2rem;\n height: 2rem;\n border-radius: 50%;\n overflow: hidden;\n display: flex;\n align-items: center;\n justify-content: center;\n background: ${({ theme }) => theme.colors.elevation1};\n color: ${({ theme }) => theme.colors.highlight1};\n\n :hover {\n color: ${({ theme }) => theme.colors.highlight2};\n cursor: pointer;\n }\n`;\n\nconst ControlPanelIconsBar = styled(IconsBar)`\n height: 80%;\n`;\n\nconst CloseIconWrapper = styled(IconWrapper)`\n font-size: 1rem;\n display: flex;\n align-items: center;\n`;\n\nconst ControlPanelHeader = styled(TitleBarWrapper)<{ theme: Theme }>`\n grid-template-columns: 1fr auto;\n border-bottom: 1px solid ${({ theme }) => theme.colors.elevation3};\n font-size: 0.7rem;\n`;\n\nconst ControlPanelTitle = styled(PanelTitle)`\n text-align: center;\n`;\n\nconst ControlPanelWrapper = styled.div`\n height: 100%;\n width: 100%;\n padding: 0.3rem 0.4rem;\n box-sizing: border-box;\n`;\n\nconst ControlPanelBody = styled.div<{ theme: Theme }>`\n height: auto;\n padding: 0;\n max-height: 95vh;\n overflow-y: scroll;\n border: 1px solid ${({ theme }) => theme.colors.elevation3};\n`;\n\nconst ControlPanelSettings = styled.div`\n padding: 1rem 0;\n font-family: var(--leva-fonts-mono);\n font-size: 0.8rem;\n`;\n\nconst LockGridWrapper = styled.div<{ theme: Theme }>`\n display: flex;\n align-items: center;\n gap: 0.5rem;\n cursor: pointer;\n color: ${({ theme }) => theme.colors.highlight1};\n &:hover {\n color: ${({ theme }) => theme.colors.highlight2};\n }\n`;\n\nconst GridResizeHandle = styled.div<{ theme: Theme }>`\n position: absolute;\n height: 1rem;\n top: 0;\n bottom: 0;\n margin: auto;\n left: 0.5rem;\n border-right: 1px solid ${({ theme }) => theme.colors.whitePrimary};\n`;\n\nconst ControlPanelItemWrapper = styled.div<{ theme: Theme }>`\n box-sizing: border-box;\n overflow: hidden;\n .react-resizable-handle:after {\n border-color: ${({ theme }) => theme.colors.whitePrimary};\n border-width: 1px;\n }\n`;\n\nconst ControlPanel = () => {\n const theme = useTheme();\n const nodeRef = useRef(null);\n const nodes = useStore((store) => store.nodes);\n const {\n show,\n nodes: controlPanelNodes,\n size,\n } = useStore((store) => store.controlPanel);\n\n const { width = 200, height } = size;\n\n const filteredNodes = useMemo(() => {\n const nodeIds = controlPanelNodes.map(({ id }) => id);\n return nodes.filter(({ id }) => nodeIds.includes(id));\n }, [nodes, controlPanelNodes]);\n\n const showControlPanel = useStore((store) => store.showControlPanel);\n const hideControlPanel = useStore((store) => store.hideControlPanel);\n const setControlPanelNodes = useStore((store) => store.setControlPanelNodes);\n const setControlPanelSize = useStore((store) => store.setControlPanelSize);\n const removeNodeFromControlPanel = useStore(\n (store) => store.removeNodeFromControlPanel,\n );\n\n const [isGridLocked, setGridLocked] = useState(true);\n\n const layout = useMemo(() => {\n const fallbackY = controlPanelNodes.reduce(\n (acc, { height = CONTROL_PANEL_GRID_CONFIG.rowHeight, x, y = 0 }) => {\n const Y = y + height;\n return Y > acc ? Y : acc;\n },\n 0,\n );\n return controlPanelNodes.map(({ id: i, width, height, x, y }) => {\n return {\n i,\n w: width || CONTROL_PANEL_GRID_CONFIG.cols,\n h: height || 6,\n x: x ?? 0,\n y: y ?? fallbackY,\n };\n });\n }, [controlPanelNodes]);\n\n if (!filteredNodes.length) {\n return null;\n }\n\n return (\n <>\n <ControlPanelIconWrapper\n theme={theme}\n ref={nodeRef}\n onClick={showControlPanel}\n >\n <ControlPanelIcon />\n </ControlPanelIconWrapper>\n <Drawer\n open={show}\n onClose={hideControlPanel}\n direction=\"left\"\n className=\"\"\n size=\"auto\"\n enableOverlay={false}\n style={{\n background: theme.colors.elevation1,\n position: \"absolute\",\n }}\n >\n <ControlPanelHeader theme={theme}>\n <ControlPanelTitle>Control Panel</ControlPanelTitle>\n <ControlPanelIconsBar>\n <CloseIconWrapper onClick={hideControlPanel} theme={theme}>\n <CloseIcon />\n </CloseIconWrapper>\n </ControlPanelIconsBar>\n </ControlPanelHeader>\n\n <ControlPanelWrapper>\n <ControlPanelSettings>\n {isGridLocked ? (\n <LockGridWrapper\n theme={theme}\n onClick={() => setGridLocked(false)}\n >\n <LockIcon />\n Unlock grid\n </LockGridWrapper>\n ) : (\n <LockGridWrapper\n theme={theme}\n onClick={() => setGridLocked(true)}\n >\n <UnlockIcon />\n Lock grid\n </LockGridWrapper>\n )}\n </ControlPanelSettings>\n <Resizable\n enable={{\n top: false,\n right: !isGridLocked,\n bottom: false,\n left: false,\n topRight: false,\n bottomRight: false,\n bottomLeft: false,\n topLeft: false,\n }}\n handleComponent={{\n right: <GridResizeHandle theme={theme} />,\n }}\n minWidth={120}\n size={{ width, height: \"auto\" }}\n onResizeStop={(e, direction, ref, d) => {\n setControlPanelSize({\n width: width + d.width,\n height: height + d.height,\n });\n }}\n >\n <ControlPanelBody theme={theme}>\n {/* @ts-ignore */}\n <GridLayout\n layout={layout}\n className=\"layout\"\n cols={CONTROL_PANEL_GRID_CONFIG.cols}\n rowHeight={CONTROL_PANEL_GRID_CONFIG.rowHeight}\n width={width}\n margin={[0, 0]}\n isResizable={!isGridLocked}\n draggableHandle=\".grid-item-handle\"\n onLayoutChange={(nodes) => {\n requestAnimationFrame(() => {\n setControlPanelNodes(\n nodes.map(({ i, w, h, x, y }) => ({\n id: i,\n width: w,\n height: h,\n x,\n y,\n })),\n );\n });\n }}\n >\n {filteredNodes.map((node) => {\n return (\n <ControlPanelItemWrapper key={node.id} theme={theme}>\n <ControlPanelItem\n node={node}\n showControls={!isGridLocked}\n onDelete={removeNodeFromControlPanel}\n />\n </ControlPanelItemWrapper>\n );\n })}\n </GridLayout>\n </ControlPanelBody>\n </Resizable>\n </ControlPanelWrapper>\n </Drawer>\n </>\n );\n};\n\nexport default ControlPanel;\n","import { useMemo } from \"react\";\n\nimport styled from \"@emotion/styled\";\nimport \"react-grid-layout/css/styles.css\";\nimport { MdDragHandle as DragIcon } from \"react-icons/md\";\nimport { MdClose as CloseIcon } from \"react-icons/md\";\nimport useAudioNode from \"../../hooks/useAudioNode\";\nimport useNode from \"../../hooks/useNode\";\nimport useTheme from \"../../hooks/useTheme\";\nimport useStore from \"../../store\";\nimport { Theme } from \"../../theme\";\nimport { WNNode, ControlPanelNodeProps } from \"../../types\";\nimport { IconsBar, IconWrapper, PanelTitle, TitleBarWrapper } from \"./styles\";\n\nconst ControlPanelNodeWrapper = styled.div<{ theme: Theme }>`\n height: 100%;\n display: grid;\n grid-template-rows: auto 1fr;\n`;\n\nconst PanelNode = (props: ControlPanelNodeProps) => {\n const { node } = props;\n\n const getControlPanelNode = useStore((store) => store.getControlPanelNode);\n\n const ControlPanelNode = useMemo(() => getControlPanelNode(node), [node]);\n\n if (!ControlPanelNode) {\n return null;\n }\n\n return <ControlPanelNode {...props} />;\n};\n\ninterface ControlPanelItemProps {\n node: WNNode;\n showControls: boolean;\n onDelete: (node: WNNode) => void;\n}\n\nconst ControlPanelItem = (props: ControlPanelItemProps) => {\n const { node, showControls, onDelete } = props;\n const theme = useTheme();\n\n const { id } = node;\n const { node: audioNode } = useAudioNode(id) || {};\n const { updateNodeValues } = useNode(id);\n\n return (\n <ControlPanelNodeWrapper theme={theme}>\n <TitleBarWrapper theme={theme}>\n <PanelTitle>{node.data.label}</PanelTitle>\n {showControls && (\n <IconsBar>\n <IconWrapper theme={theme}>\n <DragIcon className=\"grid-item-handle\" />\n </IconWrapper>\n <IconWrapper theme={theme}>\n <CloseIcon onClick={() => onDelete(node)} />\n </IconWrapper>\n </IconsBar>\n )}\n </TitleBarWrapper>\n <PanelNode\n node={node}\n audioNode={audioNode}\n updateNodeValues={updateNodeValues}\n />\n </ControlPanelNodeWrapper>\n );\n};\n\nexport default ControlPanelItem;\n","import { AudioNodeState } from \"@web-noise/patch\";\nimport useStore from \"../store\";\nimport type { WNAudioNode } from \"../types\";\n\nconst useAudioNode = <T = WNAudioNode>(id: string) => {\n const patch = useStore(({ patch }) => patch);\n return patch.audioNodes.get(id) as AudioNodeState<T> | undefined;\n};\n\nexport default useAudioNode;\n","import { useCallback } from \"react\";\nimport useStore from \"../store\";\nimport { WNNodeData } from \"../types\";\n\nconst useNode = (id: string) => {\n const updateNodeData = useStore(({ updateNodeData }) => updateNodeData);\n\n const updateNodeValues = useCallback(\n (values: WNNodeData[\"values\"]) => updateNodeData(id, { values }),\n [id, updateNodeData]\n );\n const updateNodeConfig = useCallback(\n (config: WNNodeData[\"config\"]) => updateNodeData(id, { config }),\n [id, updateNodeData]\n );\n const updateNodeLabel = useCallback(\n (label: string) => updateNodeData(id, { label }),\n [id, updateNodeData]\n );\n\n return {\n updateNodeValues,\n updateNodeConfig,\n updateNodeLabel,\n };\n};\n\nexport default useNode;\n","import styled from \"@emotion/styled\";\nimport \"react-grid-layout/css/styles.css\";\nimport { Theme } from \"../../theme\";\nimport { TitleBar } from \"../Node\";\n\nexport const PanelTitle = styled.div`\n width: 100%;\n padding: 0.4rem 0;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n`;\n\nexport const TitleBarWrapper = styled(TitleBar)<{ theme: Theme }>`\n display: flex;\n gap: 0.1rem;\n padding: 0 0.4rem;\n justify-content: start;\n font-size: 0.6rem;\n height: auto;\n min-width: 0;\n`;\n\nexport const IconsBar = styled.div`\n display: flex;\n align-items: center;\n height: 70%;\n width: auto;\n gap: 0.4rem;\n`;\n\nexport const IconWrapper = styled.span<{ theme: Theme }>`\n width: auto;\n height: 100%;\n cursor: pointer;\n svg {\n width: auto;\n height: 100%;\n }\n &:hover {\n color: ${({ theme }) => theme.colors.highlight2};\n cursor: pointer;\n }\n`;\n","import styled from \"@emotion/styled\";\nimport { withTheme } from \"@emotion/react\";\nimport { Resizable } from \"re-resizable\";\nimport { ComponentProps, useMemo, useState } from \"react\";\nimport {\n MdSettings as SettingsIcon,\n MdInfoOutline as InfoIcon,\n} from \"react-icons/md\";\nimport { Handle, HandleProps, NodeProps, Position } from \"reactflow\";\nimport { DRAG_HANDLE_CLASS, PortType } from \"../../constants\";\nimport useAudioNode from \"../../hooks/useAudioNode\";\nimport useNode from \"../../hooks/useNode\";\nimport useTheme from \"../../hooks/useTheme\";\nimport useStore from \"../../store\";\nimport { Theme } from \"../../theme\";\nimport { AudioPort, WNNodeData } from \"../../types\";\nimport EditableLabel from \"../EditableLabel\";\nimport NodeInfoModal from \"../NodeInfoModal\";\n\nconst NodeWrapper = styled.div`\n background-color: var(--leva-colors-elevation1);\n`;\n\nconst NodeLoaderWrapper = styled(NodeWrapper)`\n padding: 2rem 5rem;\n`;\n\nconst NodeErrorWrapper = styled(NodeWrapper)`\n padding: 1rem 2rem;\n`;\n\nconst SettingsIconWrapper = styled(SettingsIcon)`\n font-size: 1.2rem;\n opacity: 0.4;\n width: 1rem;\n &:hover {\n opacity: 1;\n cursor: pointer;\n }\n`;\n\nconst InfoIconWrapper = styled(InfoIcon)`\n font-size: 1.2rem;\n opacity: 0.4;\n width: 1rem;\n &:hover {\n opacity: 1;\n cursor: pointer;\n }\n`;\n\nconst Section = styled.div`\n position: relative;\n font-family: var(--leva-fonts-mono);\n font-size: var(--leva-fontSizes-root);\n background-color: var(--leva-colors-elevation1);\n`;\n\nexport const TitleBarInner = styled(Section)`\n display: flex;\n height: var(--leva-sizes-titleBarHeight);\n touch-action: none;\n align-items: center;\n justify-content: center;\n flex: 1 1 0%;\n color: var(--leva-colors-highlight1);\n padding: 0 0.4rem;\n gap: 0.3rem;\n`;\n\nexport const PortsPanel = styled(Section)<{ theme: Theme }>(\n ({ theme }) => `\n display: grid;\n grid-template-areas: \"inputs outputs\";\n background: ${theme.colors.elevation2};\n border-bottom: 1px solid ${theme.colors.elevation1};\n color: ${theme.colors.highlight3};\n font-size: 0.6rem;\n`,\n);\n\nexport const InputPorts = styled.div`\n grid-area: inputs;\n text-align: left;\n`;\n\nexport const OutputPorts = styled.div`\n grid-area: outputs;\n text-align: right;\n`;\n\nexport const Port = styled.div`\n position: relative;\n padding: 5px 10px;\n`;\n\nconst portColors = {\n [PortType.Audio]: \"#4ade80\", // vibrant green\n [PortType.Gate]: \"#c084fc\", // rich purple\n [PortType.Number]: \"#38bdf8\", // bright blue\n [PortType.Any]: \"#ffffff\", // white\n};\n\nconst StyledHandle = withTheme(styled(Handle, {\n shouldForwardProp: (prop) => prop !== \"portType\",\n})<{ portType?: AudioPort[\"type\"]; theme: Theme }>`\n --port-color: ${(props) => {\n if (!props.portType) return props.theme.colors.highlight2;\n if (Array.isArray(props.portType)) {\n const colors = props.portType.map((type) => portColors[type]);\n return `linear-gradient(0.25turn, ${colors.join(\", \")});`;\n } else {\n return portColors[props.portType];\n }\n }};\n border-color: var(--port-color);\n background: var(--port-color);\n box-shadow: 0px 0px 0px 1px ${({ theme }) => theme.colors.elevation2} inset;\n`);\n\nconst StyledInputHandle = withTheme(styled(StyledHandle)`\n left: -3px;\n`);\n\nexport const InputHandle = ({\n ...props\n}: Partial<HandleProps & ComponentProps<typeof StyledInputHandle>>) => (\n <StyledInputHandle {...props} type=\"target\" position={Position.Left} />\n);\n\nexport const StyledOutputHandle = withTheme(styled(StyledHandle)`\n right: -3px;\n`);\n\nexport const OutputHandle = (\n props: Partial<HandleProps & ComponentProps<typeof StyledOutputHandle>>,\n) => <StyledOutputHandle {...props} type=\"source\" position={Position.Right} />;\n\nexport type WNNodeProps<T = Record<string, unknown>> = NodeProps<\n T & WNNodeData\n>;\n\nexport interface TitleBarProps {\n className?: string;\n [key: string]: unknown;\n}\n\nexport const TitleBar = ({ className, ...props }: TitleBarProps) => (\n <TitleBarInner\n {...props}\n className={[className, DRAG_HANDLE_CLASS].join(\" \")}\n />\n);\n\nexport interface WNNodeParameters extends NodeProps {\n children?: any;\n}\n\nconst useNodeManifest = (type: string) => {\n const data = useStore((store) => store.nodesConfiguration[type]);\n\n return data;\n};\n\nconst useConfigNode = (type: string) => {\n const { configNode: ConfigNode } = useNodeManifest(type);\n\n return {\n ConfigNode,\n };\n};\n\nexport const WNNode = (props: WNNodeParameters) => {\n const { id, children, selected, ...rest } = props;\n const theme = useTheme();\n const getNode = useStore(({ getNode }) => getNode);\n const nodesConfiguration = useStore((store) => store.nodesConfiguration);\n\n const [isInfoModalShown, setIsInfoModalShown] = useState(false);\n\n const { info } = useNodeManifest(props.type);\n\n const isResizeable = useMemo(\n () => nodesConfiguration[props.type].resizable ?? false,\n [nodesConfiguration, props.type],\n );\n\n const { updateNodeLabel, updateNodeConfig } = useNode(id);\n const { data } = getNode(id) || {};\n const audioNode = useAudioNode(id);\n const { ConfigNode } = useConfigNode(rest.type);\n\n const [configMode, setShowConfigMode] = useState(false);\n\n if (!audioNode) {\n return (\n <NodeLoaderWrapper className={DRAG_HANDLE_CLASS}>\n can't find audio node\n </NodeLoaderWrapper>\n );\n }\n\n if (audioNode.loading) {\n return (\n <NodeLoaderWrapper className={DRAG_HANDLE_CLASS}>\n loading\n </NodeLoaderWrapper>\n );\n }\n\n if (audioNode.error) {\n return (\n <NodeErrorWrapper className={DRAG_HANDLE_CLASS}>\n error: {audioNode.error.toString()}\n </NodeErrorWrapper>\n );\n }\n\n if (!audioNode.node) {\n return (\n <NodeLoaderWrapper className={DRAG_HANDLE_CLASS}>\n can't find audio node\n </NodeLoaderWrapper>\n );\n }\n\n const size = data?.config?.size as\n | { width: number; height: number }\n | undefined;\n\n const {\n node: { inputs, outputs },\n } = audioNode;\n\n return (\n <NodeWrapper>\n <TitleBar>\n {info && (\n <InfoIconWrapper onClickCapture={() => setIsInfoModalShown(true)} />\n )}\n <EditableLabel\n value={data?.label ?? \"No Name\"}\n onChange={updateNodeLabel}\n />\n {ConfigNode && (\n <SettingsIconWrapper\n onClickCapture={() => setShowConfigMode((isShown) => !isShown)}\n />\n )}\n </TitleBar>\n <PortsPanel theme={theme}>\n <InputPorts>\n {inputs\n ? Object.keys(inputs).map((key, index) => (\n <Port key={index}>\n <InputHandle id={key} portType={inputs[key].type} />\n <span>{key}</span>\n </Port>\n ))\n : null}\n </InputPorts>\n <OutputPorts>\n {outputs\n ? Object.keys(outputs).map((key, index) => (\n <Port key={index}>\n <OutputHandle id={key} portType={outputs[key].type} />\n <span>{key}</span>\n </Port>\n ))\n : null}\n </OutputPorts>\n </PortsPanel>\n {ConfigNode && configMode && selected ? (\n <ConfigNode {...props} />\n ) : isResizeable ? (\n <Resizable\n size={size}\n minWidth={180}\n minHeight={30}\n enable={{\n bottom: true,\n bottomRight: true,\n right: true,\n }}\n onResizeStop={(e, direction, ref, d) => {\n const newSize = size\n ? {\n width: size.width + d.width,\n height: size.height + d.height,\n }\n : ref.getBoundingClientRect();\n updateNodeConfig({\n ...data?.config,\n size: newSize,\n });\n }}\n >\n {children}\n </Resizable>\n ) : (\n children\n )}\n <NodeInfoModal\n isOpen={isInfoModalShown}\n type={props.type}\n onClose={() => setIsInfoModalShown(false)}\n node={audioNode.node}\n />\n </NodeWrapper>\n );\n};\n","import styled from \"@emotion/styled\";\nimport React, { useCallback, useEffect, useRef, useState } from \"react\";\n\nexport const TitleBarLabel = styled.input`\n width: 100%;\n background: none;\n border: none;\n text-align: center;\n color: var(--leva-colors-highlight1);\n font-family: var(--leva-fonts-mono);\n font-size: var(--leva-fontSizes-root);\n cursor: inherit;\n text-overflow: ellipsis;\n outline: none;\n\n &:focus {\n box-shadow: 0 0 0 green var(--leva-colors-accent2);\n }\n &:focus-within {\n box-shadow: 0 0 0 green var(--leva-colors-accent2);\n }\n &:focus-vissible {\n box-shadow: 0 0 0 green var(--leva-colors-accent2);\n }\n &:not([readonly]):focus {\n color: #fff;\n appearance: none;\n cursor: auto;\n background-color: var(--leva-colors-elevation2);\n padding: 0.3rem;\n border-radius: 0.2rem;\n }\n`;\n\ninterface EditableLabelProps {\n onChange: (value: string) => void;\n value?: string;\n className?: string;\n}\n\nconst EditableLabel = ({\n onChange,\n value = \"\",\n className,\n}: EditableLabelProps) => {\n const labelInputRef = useRef<HTMLInputElement>(null);\n\n const [labelEditMode, setLabelEditMode] = useState(false);\n const editNodeLabel = useCallback(\n (event: React.MouseEvent) => {\n //@ts-ignore\n event.target?.select();\n setLabelEditMode(true);\n },\n [setLabelEditMode],\n );\n\n const exitEditMode = useCallback(() => {\n window.getSelection()?.collapseToEnd();\n setLabelEditMode(false);\n }, [setLabelEditMode]);\n\n const saveNodeLabel = useCallback(() => {\n exitEditMode();\n if (labelInputRef.current) {\n onChange(labelInputRef.current.value);\n }\n }, [labelInputRef, exitEditMode, onChange]);\n\n const cancelNodeLabelEdit = useCallback(() => {\n exitEditMode();\n if (labelInputRef.current && value) {\n labelInputRef.current.value = value;\n }\n }, [labelInputRef, exitEditMode, value]);\n\n useEffect(() => {\n if (!labelInputRef.current) {\n return;\n }\n labelInputRef.current.value = value;\n }, [value, labelInputRef]);\n\n return (\n <TitleBarLabel\n ref={labelInputRef}\n type=\"text\"\n readOnly={!labelEditMode}\n onDoubleClick={(event) => editNodeLabel(event)}\n onBlur={saveNodeLabel}\n onKeyDown={(event) => {\n switch (event.key) {\n case \"Escape\":\n cancelNodeLabelEdit();\n break;\n case \"Enter\":\n saveNodeLabel();\n break;\n }\n }}\n className={className}\n />\n );\n};\n\nexport default EditableLabel;\n","import styled from \"@emotion/styled\";\nimport Modal from \"./Modal\";\nimport { marked } from \"marked\";\nimport useStore from \"../store\";\nimport { withTheme } from \"@emotion/react\";\nimport { useMemo } from \"react\";\nimport { WNAudioNode } from \"../types\";\nimport { Theme } from \"../theme\";\n\ninterface NodeInfoModalProps {\n isOpen: boolean;\n onClose: () => void;\n type: string;\n node: WNAudioNode;\n}\n\nconst NodeInfoWrapper = withTheme(styled.div<{ theme: Theme }>`\n height: 100%;\n width: 100%;\n overflow: scroll;\n padding: 0.6rem;\n box-sizing: border-box;\n\n hr {\n border: none;\n border-bottom: 1px solid ${({ theme }) => theme.colors.elevation3};\n }\n\n code {\n background-color: ${({ theme }) => theme.colors.elevation3};\n color: ${({ theme }) => theme.colors.highlight3};\n font-family:\n source-code-pro, Menlo, Monaco, Consolas, \"Courier New\", monospace;\n }\n\n pre {\n background-color: ${({ theme }) => theme.colors.elevation3};\n padding: 0.2rem 0.3rem;\n border-radius: 1px;\n }\n\n a {\n color: ${({ theme }) => theme.colors.accent1};\n }\n`);\n\nconst useNodeManifest = (type: string) => {\n const data = useStore((store) => store.nodesConfiguration[type]);\n return data;\n};\n\nconst NodeInfoModal = ({\n isOpen,\n onClose,\n type: nodeType,\n node,\n}: NodeInfoModalProps) => {\n const { info, portsDescription } = useNodeManifest(nodeType);\n\n const portsInfo = useMemo(() => {\n const parts: string[] = [];\n\n const inputPorts = node.inputs;\n if (inputPorts) {\n parts.push(`## Inputs`);\n for (const portName in inputPorts) {\n const port = inputPorts[portName];\n parts.push(`### *${portName}*`);\n\n const description = portsDescription?.inputs?.[portName];\n\n if (description) {\n parts.push(description);\n }\n\n if (Array.isArray(port.type)) {\n parts.push(`**Types**: \\`${port.type.join(\", \")}\\``);\n } else {\n parts.push(`**Type**: \\`${port.type || \"unknown\"}\\``);\n }\n\n if (port.range) {\n parts.push(`**Range**: \\`[${port.range[0]}, ${port.range[1]}]\\``);\n }\n\n if (port.defaultValue !== undefined) {\n parts.push(`**Default**: \\`${port.defaultValue}\\``);\n }\n }\n }\n\n const outputPorts = node.outputs;\n if (outputPorts) {\n parts.push(`## Outputs`);\n for (const portName in outputPorts) {\n const port = outputPorts[portName];\n parts.push(`### *${portName}*`);\n\n const description = portsDescription?.outputs?.[portName];\n\n if (description) {\n parts.push(description);\n }\n\n if (Array.isArray(port.type)) {\n parts.push(`**Types**: \\`${port.type.join(\", \")}\\``);\n } else {\n parts.push(`**Type**: \\`${port.type || \"unknown\"}\\``);\n }\n\n if (port.range) {\n parts.push(`**Range**: \\`[${port.range[0]}, ${port.range[1]}]\\``);\n }\n\n if (port.defaultValue !== undefined) {\n parts.push(`**Default**: \\`${port.defaultValue}\\``);\n }\n }\n }\n return parts.join(\"\\n\\n\");\n }, [node, portsDescription]);\n\n const combinedInfo = (info || \"\") + \"\\n\\n\" + portsInfo;\n\n return isOpen ? (\n <Modal onClose={onClose}>\n <NodeInfoWrapper\n dangerouslySetInnerHTML={{ __html: marked(combinedInfo || \"\") }}\n />\n </Modal>\n ) : null;\n};\n\nexport default NodeInfoModal;\n","import { FaQuestion } from \"react-icons/fa\";\nimport { ControlButton } from \"reactflow\";\nimport useStore from \"../../store\";\nimport HelpModal from './HelpModal';\n\n\nconst HelpButton = () => {\n const toggleHelp = useStore((store) => store.toggleHelp);\n\n return (\n <>\n <ControlButton onClick={toggleHelp}>\n <FaQuestion />\n </ControlButton>\n </>\n );\n};\n\nexport { HelpModal, HelpButton };\n\n","import { withTheme } from \"@emotion/react\";\nimport styled from \"@emotion/styled\";\n// @ts-ignore\nimport { marked } from \"marked\";\nimport useStore from \"../../store\";\nimport { Theme } from \"../../theme\";\nimport Modal from \"../Modal\";\n\n//@ts-ignore\nimport HELP from \"bundle-text:./HELP.md\";\n\nconst MdPreview = withTheme(styled.div<{ theme: Theme }>`\n font-family: var(--leva-fonts-mono);\n font-size: 0.7rem;\n box-sizing: border-box;\n height: 100%;\n width: 100%;\n overflow: scroll;\n color: ${({ theme }) => theme.colors.whitePrimary};\n padding: 0 0.5rem;\n\n code {\n color: ${({ theme }) => theme.colors.accent3};\n filter: hue-rotate(180deg);\n }\n`);\n\nconst ModalContent = withTheme(styled.div<{ theme: Theme }>`\n padding: 1rem;\n height: 100%;\n width: 100%;\n box-sizing: border-box;\n overflow: hidden;\n`);\n\nconst HelpModal = () => {\n const isHelpShown = useStore((store) => store.isHelpShown);\n const toggleHelp = useStore((store) => store.toggleHelp);\n\n if (!isHelpShown) {\n return null;\n }\n\n return (\n <Modal\n onClose={() => {\n toggleHelp();\n }}\n >\n <ModalContent>\n <MdPreview\n dangerouslySetInnerHTML={{ __html: marked(HELP) }}\n onWheelCapture={(event) => event.stopPropagation()}\n ></MdPreview>\n </ModalContent>\n </Modal>\n );\n};\n\nexport default HelpModal;\n","module.exports = \"e0644016fb7e7c32\";","import styled from \"@emotion/styled\";\nimport { useState } from \"react\";\nimport { FaVolumeOff as IconUnmute } from \"react-icons/fa\";\nimport useStore from \"../store\";\nimport useTheme from \"../hooks/useTheme\";\nimport { Theme } from \"../theme\";\n\n\nconst Layout = styled.div<{ theme: Theme }>`\n position: fixed;\n z-index: ${({ theme }) => theme.zIndex.resumeContextLayout};\n width: 100%;\n height: 100%;\n top: 0;\n left: 0;\n background: rgb(24 28 32 / 90%);\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: center;\n color: ${({ theme }) => theme.colors.whitePrimary};\n cursor: pointer;\n`;\n\nconst Row = styled.div`\n display: flex;\n width: 100%;\n align-items: center;\n justify-content: center;\n`;\n\nconst Message = styled.div<{ theme: Theme }>`\n font-family: var(--leva-fonts-mono);\n font-size: 2rem;\n`;\n\nconst Icon = styled(IconUnmute)`\n width: 7rem;\n height: 7rem;\n`;\n\nconst ResumeContext = () => {\n const theme = useTheme();\n const patch = useStore(({ patch }) => patch);\n const audioContext = patch.audioContext;\n const [isContextResumed, setIsContextResumed] = useState<boolean>(\n audioContext.state === \"running\",\n );\n\n if (isContextResumed) {\n return null;\n }\n\n return (\n <Layout\n theme={theme}\n onClick={() => {\n audioContext.resume();\n setIsContextResumed(true);\n }}\n >\n <Row>\n <Message theme={theme}>Click anywhere to resume audio context</Message>\n </Row>\n <Row>\n <Icon />\n </Row>\n </Layout>\n );\n};\n\nexport default ResumeContext;\n","import { FaMap, FaRegMap } from \"react-icons/fa\";\nimport { ControlButton } from \"reactflow\";\nimport useStore from \"../store\";\n\nconst ToggleMinimap = () => {\n const setConfig = useStore(({ setConfig }) => setConfig);\n const { showMinimap } = useStore(({ config }) => config);\n\n return (\n <ControlButton onClick={() => setConfig({ showMinimap: !showMinimap })}>\n {showMinimap ? <FaMap /> : <FaRegMap />}\n </ControlButton>\n );\n};\n\nexport default ToggleMinimap;\n","import { useEffect, useMemo } from \"react\";\nimport { EdgeProps, getBezierPath, getConnectedEdges } from \"reactflow\";\nimport useTheme from \"../hooks/useTheme\";\nimport useStore from \"../store\";\n\nconst Wire = ({\n id,\n sourceX,\n sourceY,\n targetX,\n targetY,\n sourcePosition,\n targetPosition,\n style = {},\n data,\n markerStart,\n markerEnd,\n source,\n target,\n sourceHandleId,\n targetHandleId,\n selected,\n}: EdgeProps) => {\n const theme = useTheme();\n const getNode = useStore(({ getNode }) => getNode);\n const sourceNode = getNode(source);\n const targetNode = getNode(target);\n const isConnectedToSelected = sourceNode?.selected || targetNode?.selected;\n useEffect(() => {\n if (!sourceHandleId || !targetHandleId) {\n return;\n }\n console.log(`connected ${source} to ${target}`);\n return () => {\n console.log(`disconnected ${source} from ${target}`);\n };\n }, [source, sourceHandleId, target, targetHandleId]);\n\n const [edgePath] = getBezierPath({\n targetX,\n targetY,\n targetPosition,\n sourceX,\n sourceY,\n sourcePosition,\n });\n\n return (\n <>\n <path\n id={id}\n style={{\n ...style,\n stroke: selected\n ? theme.colors.accent2\n : isConnectedToSelected\n ? theme.colors.highlight3\n : theme.colors.highlight2,\n }}\n className=\"react-flow__edge-path Wire\"\n d={edgePath}\n markerEnd={markerEnd}\n />\n <path\n style={{\n ...style,\n strokeWidth: 8,\n color: \"transparent\",\n opacity: 0,\n cursor: \"pointer\",\n }}\n d={edgePath}\n markerEnd={markerEnd}\n />\n </>\n );\n};\n\nexport default Wire;\n","import Checker, { CheckerItem } from \"./Checker\";\nimport styled from \"@emotion/styled\";\nimport { type Theme, useTheme } from \"../../\";\n\nconst RadioGroupWrapper = styled.div<{ theme: Theme }>`\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n font-family: var(--leva-fonts-mono);\n font-size: 0.7rem;\n color: ${({ theme }) => theme.colors.highlight2};\n padding: 0.5rem;\n`;\n\nexport const RadioGroup = ({\n options,\n value,\n onChange,\n}: {\n options: Array<CheckerItem>;\n value: CheckerItem[\"value\"];\n onChange: (value: CheckerItem[\"value\"]) => void;\n}) => {\n const theme = useTheme();\n return (\n <RadioGroupWrapper theme={theme}>\n {options.map(({ value: optionValue, label, subtitle }, index) => (\n <Checker\n key={index}\n value={value}\n type=\"radio\"\n label={label}\n subtitle={subtitle}\n onChange={() => onChange(optionValue)}\n checked={optionValue === value}\n />\n ))}\n </RadioGroupWrapper>\n );\n};\n\nexport default RadioGroup;\n","import { withTheme } from \"@emotion/react\";\nimport styled from \"@emotion/styled\";\nimport { HTMLProps } from \"react\";\nimport { type Theme } from \"../../\";\n\nexport const InputWrapper = styled.div`\n display: flex;\n position: relative;\n`;\n\nexport const InputInner = withTheme(styled.input<{ theme: Theme }>`\n padding-right: 2rem;\n padding-left: 0.3rem;\n padding-top: 0;\n padding-bottom: 0;\n width: 100%;\n appearance: textfield;\n font-size: inherit;\n background: none;\n border: none;\n color: var(--leva-colors-highlight1);\n font-family: var(--leva-fonts-mono);\n cursor: inherit;\n text-overflow: ellipsis;\n outline: none;\n appearance: textfield;\n cursor: auto;\n background-color: var(--leva-colors-elevation3);\n border-radius: 0.2rem;\n height: 1.5rem;\n color: var(--leva-colors-highlight2);\n\n &:focus,\n &:hover {\n box-shadow: 0 0 0 var(--leva-borderWidths-focus) var(--leva-colors-accent2);\n color: ${({ theme }) => theme.colors.whitePrimary};\n }\n &::-webkit-inner-spin-button,\n &::-webkit-outer-spin-button {\n -webkit-appearance: none;\n margin-right: 1rem;\n }\n`);\n\nexport interface InputProps {\n value?: string;\n placeholder?: string;\n onChange?: (value: string) => void;\n type?: string;\n inputProps?: Omit<HTMLProps<HTMLInputElement>, \"as\">;\n}\n\nexport const Input = ({\n type,\n value,\n placeholder,\n onChange = () => {},\n inputProps,\n ...props\n}: InputProps) => {\n return (\n <InputWrapper {...props}>\n <InputInner\n type={type}\n value={value}\n placeholder={placeholder}\n onKeyDownCapture={(event) => {\n event.stopPropagation();\n }}\n onChange={(event) => {\n onChange(event.target.value);\n }}\n {...inputProps}\n />\n </InputWrapper>\n );\n};\n\nexport default Input;\n","import styled from \"@emotion/styled\";\nimport { withTheme } from \"@emotion/react\";\nimport {\n KeyboardEventHandler,\n useCallback,\n useState,\n useRef,\n useEffect,\n} from \"react\";\nimport { FaRegArrowAltCircleRight as SetUrlIcon } from \"react-icons/fa\";\nimport type { Theme } from \"@web-noise/core\";\nimport { InputInner, InputWrapper } from \"./Input\";\n\nconst InputButton = withTheme(styled.button<{ theme: Theme }>`\n position: absolute;\n right: 0;\n height: 100%;\n outline: none;\n background: none;\n border: none;\n color: ${({ theme }) => theme.colors.highlight1};\n cursor: pointer;\n display: flex;\n align-items: center;\n z-index: 2;\n &:hover {\n color: ${({ theme }) => theme.colors.highlight2};\n }\n &:active {\n color: ${({ theme }) => theme.colors.highlight3};\n }\n`);\n\nconst DropdownContainer = styled.div`\n position: relative;\n width: 100%;\n`;\n\nconst DropdownList = withTheme(styled.div<{ theme: Theme; isOpen: boolean }>`\n position: absolute;\n top: calc(100% + 2px);\n left: 0;\n right: 0;\n max-height: 200px;\n overflow-y: auto;\n background-color: ${({ theme }) => theme.colors.elevation2};\n border: 1px solid ${({ theme }) => theme.colors.elevation3};\n border-radius: 0.2rem;\n box-shadow: 0 4px 6px rgba(0, 0, 0, 0.3);\n z-index: 1000;\n display: ${({ isOpen }) => (isOpen ? \"block\" : \"none\")};\n\n &::-webkit-scrollbar {\n width: 8px;\n }\n\n &::-webkit-scrollbar-track {\n background: ${({ theme }) => theme.colors.elevation1};\n }\n\n &::-webkit-scrollbar-thumb {\n background: ${({ theme }) => theme.colors.elevation3};\n border-radius: 4px;\n }\n\n &::-webkit-scrollbar-thumb:hover {\n background: ${({ theme }) => theme.colors.highlight1};\n }\n`);\n\nconst DropdownItem = withTheme(styled.div<{\n theme: Theme;\n isHighlighted: boolean;\n}>`\n padding: 0.4rem 0.5rem;\n cursor: pointer;\n color: ${({ theme }) => theme.colors.highlight1};\n background-color: ${({ theme, isHighlighted }) =>\n isHighlighted ? theme.colors.elevation3 : \"transparent\"};\n font-family: var(--leva-fonts-mono);\n font-size: 0.9em;\n\n &:hover {\n background-color: ${({ theme }) => theme.colors.elevation3};\n color: ${({ theme }) => theme.colors.highlight2};\n }\n`);\n\nconst DropdownItemValue = styled.div`\n font-size: 0.85em;\n opacity: 0.7;\n margin-top: 2px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n`;\n\nconst DropdownItemLabel = styled.div`\n font-size: 1em;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n`;\n\ninterface InputOption {\n value: string;\n label?: string;\n}\n\ninterface SubmitInputProps {\n value?: string;\n placeholder?: string;\n onSubmit?: (value: string) => void;\n options?: Array<InputOption>;\n}\n\nexport const DropdownInput = ({\n value = \"\",\n placeholder = \"\",\n onSubmit = () => {},\n options = [],\n ...props\n}: SubmitInputProps) => {\n const [currentValue, setCurrentValue] = useState<string>(value);\n const [isOpen, setIsOpen] = useState(false);\n const [highlightedIndex, setHighlightedIndex] = useState(-1);\n const inputRef = useRef<HTMLInputElement>(null);\n const dropdownRef = useRef<HTMLDivElement>(null);\n\n const filteredOptions = options.filter(\n (option) =>\n currentValue === \"\" ||\n option.value.toLowerCase().includes(currentValue.toLowerCase()) ||\n option.label?.toLowerCase().includes(currentValue.toLowerCase()),\n );\n\n const applyCurrentValue = useCallback(() => {\n onSubmit(currentValue);\n setIsOpen(false);\n setHighlightedIndex(-1);\n }, [currentValue, onSubmit]);\n\n const selectOption = useCallback(\n (option: InputOption) => {\n setCurrentValue(option.value);\n onSubmit(option.value);\n setIsOpen(false);\n setHighlightedIndex(-1);\n },\n [onSubmit],\n );\n\n const handleKeyDown: KeyboardEventHandler = useCallback(\n (event) => {\n switch (event.key) {\n case \"Escape\":\n setIsOpen(false);\n setHighlightedIndex(-1);\n break;\n case \"Enter\":\n if (\n isOpen &&\n highlightedIndex >= 0 &&\n filteredOptions[highlightedIndex]\n ) {\n event.preventDefault();\n selectOption(filteredOptions[highlightedIndex]);\n } else {\n applyCurrentValue();\n }\n break;\n case \"ArrowDown\":\n event.preventDefault();\n if (!isOpen) {\n setIsOpen(true);\n setHighlightedIndex(0);\n } else {\n setHighlightedIndex((prev) =>\n prev < filteredOptions.length - 1 ? prev + 1 : prev,\n );\n }\n break;\n case \"ArrowUp\":\n event.preventDefault();\n if (isOpen) {\n setHighlightedIndex((prev) => (prev > 0 ? prev - 1 : prev));\n }\n break;\n }\n },\n [\n applyCurrentValue,\n isOpen,\n highlightedIndex,\n filteredOptions,\n selectOption,\n ],\n );\n\n const handleInputChange = (value: string) => {\n setCurrentValue(value);\n setIsOpen(true);\n setHighlightedIndex(-1);\n };\n\n const handleFocus = () => {\n if (options.length > 0) {\n setIsOpen(true);\n }\n };\n\n const handleBlur = () => {\n // Use setTimeout to allow click events on dropdown items to fire first\n setTimeout(() => {\n setIsOpen(false);\n setHighlightedIndex(-1);\n }, 200);\n };\n\n // Handle clicking outside\n useEffect(() => {\n const handleClickOutside = (event: MouseEvent) => {\n if (\n dropdownRef.current &&\n !dropdownRef.current.contains(event.target as Node) &&\n inputRef.current &&\n !inputRef.current.contains(event.target as Node)\n ) {\n setIsOpen(false);\n setHighlightedIndex(-1);\n }\n };\n\n document.addEventListener(\"mousedown\", handleClickOutside);\n return () => {\n document.removeEventListener(\"mousedown\", handleClickOutside);\n };\n }, []);\n\n // Scroll highlighted item into view\n useEffect(() => {\n if (highlightedIndex >= 0 && dropdownRef.current) {\n const highlightedElement = dropdownRef.current.children[\n highlightedIndex\n ] as HTMLElement;\n if (highlightedElement) {\n highlightedElement.scrollIntoView({\n block: \"nearest\",\n behavior: \"smooth\",\n });\n }\n }\n }, [highlightedIndex]);\n\n return (\n <DropdownContainer>\n <InputWrapper>\n <InputInner\n {...props}\n ref={inputRef}\n value={currentValue}\n placeholder={placeholder}\n onKeyDown={handleKeyDown}\n onChange={(event) => handleInputChange(event.target.value)}\n onFocus={handleFocus}\n onBlur={handleBlur}\n autoComplete=\"off\"\n />\n\n <InputButton onClick={applyCurrentValue}>\n <SetUrlIcon />\n </InputButton>\n </InputWrapper>\n\n {options.length > 0 && (\n <DropdownList\n ref={dropdownRef}\n isOpen={isOpen && filteredOptions.length > 0}\n >\n {filteredOptions.map((option, index) => (\n <DropdownItem\n key={option.value + index}\n isHighlighted={index === highlightedIndex}\n onClick={() => selectOption(option)}\n onMouseEnter={() => setHighlightedIndex(index)}\n >\n <DropdownItemLabel>\n {option.label || option.value}\n </DropdownItemLabel>\n {option.value && (\n <DropdownItemValue>{option.value}</DropdownItemValue>\n )}\n </DropdownItem>\n ))}\n </DropdownList>\n )}\n </DropdownContainer>\n );\n};\n\nexport default DropdownInput;\n","import styled from \"@emotion/styled\";\nimport Input, { InputProps, InputInner, InputWrapper } from \"./Input\";\n\nconst StyledInputWrapper = styled(InputWrapper)`\n gap: 0.5rem;\n`;\n\nconst StyledInputInner = styled(InputInner)`\n padding: 0;\n aspect-ratio: 1 / 1;\n width: auto;\n cursor: pointer;\n &::-webkit-color-swatch-wrapper {\n padding: 0;\n }\n &::-webkit-color-swatch {\n border-radius: 0.2rem;\n border: none;\n }\n`;\n\nexport interface ColorInputProps {\n value?: string;\n onChange?: (value: string) => void;\n}\n\nexport const ColorInput = ({\n value,\n onChange = () => {},\n ...props\n}: ColorInputProps) => {\n return (\n <StyledInputWrapper {...props}>\n <StyledInputInner\n type=\"color\"\n value={value}\n onChange={(event) => {\n onChange(event.target.value);\n }}\n />\n <InputInner\n value={value}\n onChange={(event) => {\n onChange(event.target.value);\n }}\n />\n </StyledInputWrapper>\n );\n};\n\nexport default ColorInput;\n","import styled from \"@emotion/styled\";\nimport { useEffect, useRef } from \"react\";\n// @ts-ignore\nimport { useThrottledCallback } from \"use-debounce\";\n\nconst SampleInput = styled.span`\n position: relative;\n &:after {\n content: \"↕\";\n position: absolute;\n top: -1px;\n right: 0;\n height: 100%;\n display: flex;\n align-items: center;\n font-size: 1.2em;\n color: var(--leva-colors-highlight1);\n }\n`;\n\nconst SampleInputInner = styled.input`\n width: 100%;\n appearance: textfield;\n font-size: inherit;\n background: none;\n border: none;\n text-align: right;\n color: var(--leva-colors-highlight1);\n font-family: var(--leva-fonts-mono);\n cursor: inherit;\n text-overflow: ellipsis;\n outline: none;\n appearance: textfield;\n cursor: auto;\n background-color: var(--leva-colors-elevation3);\n border-radius: 0.2rem;\n height: 1.5rem;\n color: var(--leva-colors-highlight2);\n\n &:focus,\n &:hover {\n box-shadow: 0 0 0 var(--leva-borderWidths-focus) var(--leva-colors-accent2);\n }\n &::-webkit-inner-spin-button,\n &::-webkit-outer-spin-button {\n -webkit-appearance: none;\n margin-right: 1rem;\n }\n`;\n\ninterface NumberInputProps {\n max?: number;\n min?: number;\n value?: number;\n step?: number;\n onChange?: (value: number) => void;\n placeholder?: string;\n}\n\nexport const NumberInput = ({\n max = Infinity,\n min = -Infinity,\n value,\n step = 1,\n onChange = () => {},\n placeholder,\n ...props\n}: NumberInputProps) => {\n const inputRef = useRef<HTMLInputElement>(null);\n\n const startChangedHandler = useThrottledCallback(\n (event: Pick<WheelEvent, \"deltaY\">) => {\n if (typeof value === \"undefined\") {\n return;\n }\n //@TODO: come up with more logical factor calculation\n const factor = max < 10 ? 5 : max / 100;\n const st = +(value + Math.round(event.deltaY / factor) * step).toFixed(2);\n if (st < min || st > max) {\n return;\n }\n onChange(st);\n },\n 100,\n );\n\n useEffect(() => {\n if (!inputRef.current) {\n return;\n }\n\n inputRef.current.addEventListener(\"wheel\", (event) => {\n event.preventDefault();\n event.stopPropagation();\n startChangedHandler(event);\n });\n\n inputRef.current.onchange = (event) => {\n const value = (event.target as HTMLInputElement).value;\n onChange(+value);\n };\n }, [inputRef.current, onChange]);\n\n useEffect(() => {\n if (typeof value === \"undefined\") {\n return;\n }\n inputRef.current && (inputRef.current.value = value.toString());\n }, [inputRef.current, value]);\n\n return (\n <SampleInput {...props}>\n <SampleInputInner\n ref={inputRef}\n type=\"number\"\n step={step}\n min={min}\n max={max}\n placeholder={placeholder}\n />\n </SampleInput>\n );\n};\n\nexport default NumberInput;\n","import styled from \"@emotion/styled\";\nimport { type Theme } from \"../theme\";\n\nexport const Button = styled.button<{ theme: Theme }>`\n display: flex;\n align-items: center;\n justify-content: center;\n outline: none;\n font-size: inherit;\n font-family: inherit;\n border: none;\n appearance: none;\n font-weight: var(--leva-fontWeights-button);\n height: var(--leva-sizes-rowHeight);\n border-radius: var(--leva-radii-sm);\n background-color: ${({ theme }) => theme.colors.elevation1};\n color: ${({ theme }) => theme.colors.highlight3};\n background-color: ${({ theme }) => theme.colors.accent2};\n cursor: pointer;\n font-family: var(--leva-fonts-mono);\n font-size: var(--leva-fontSizes-root);\n\n &:hover {\n box-shadow: inset 0 0 0 var(--leva-borderWidths-hover)\n ${({ theme }) => theme.colors.accent3};\n }\n\n &:active {\n box-shadow: inset 0 0 0 var(--leva-borderWidths-active)\n ${({ theme }) => theme.colors.accent3};\n background-color: ${({ theme }) => theme.colors.accent1};\n }\n`;\n\nexport default Button;\n","import { withTheme } from \"@emotion/react\";\nimport styled from \"@emotion/styled\";\nimport { Theme } from \"../theme\";\n\nconst SelectWrapper = withTheme(styled.div<{ theme: Theme }>`\n display: flex;\n align-items: center;\n position: relative;\n\n select {\n appearance: none;\n border: none;\n outline: none;\n width: 100%;\n font-weight: var(--leva-fontWeights-button);\n padding: 0.3rem 0.5rem;\n padding-right: 1rem;\n border-radius: var(--leva-radii-sm);\n background-color: ${({ theme }) => theme.colors.elevation1};\n color: ${({ theme }) => theme.colors.highlight3};\n cursor: pointer;\n font-family: var(--leva-fonts-mono);\n font-size: var(--leva-fontSizes-root);\n\n &:hover {\n box-shadow: inset 0 0 0 var(--leva-borderWidths-hover)\n ${({ theme }) => theme.colors.accent3};\n }\n\n &:active {\n box-shadow: inset 0 0 0 var(--leva-borderWidths-active)\n ${({ theme }) => theme.colors.accent3};\n background-color: ${({ theme }) => theme.colors.accent1};\n }\n }\n\n &::after {\n position: absolute;\n right: 0.3rem;\n content: \"\";\n width: 0.5em;\n height: 0.3em;\n background-color: ${({ theme }) => theme.colors.highlight3};\n clip-path: polygon(100% 0%, 0 0%, 50% 100%);\n }\n`);\n\ninterface SelectOption {\n value: string;\n label?: string;\n}\n\ninterface SelectProps {\n options: Array<SelectOption>;\n value?: SelectOption[\"value\"];\n placeholder?: string;\n onChange?: (value: SelectOption[\"value\"]) => void;\n}\n\nexport const Select = ({\n options,\n placeholder,\n value,\n onChange,\n ...props\n}: SelectProps) => {\n return (\n <SelectWrapper {...props}>\n <select\n value={value || \"\"}\n onChange={(event) => onChange?.(event.target.value)}\n >\n {placeholder && (\n <option value=\"\" disabled>\n {placeholder}\n </option>\n )}\n {options.map(({ value, label }) => (\n <option key={value + label} value={value}>\n {label}\n </option>\n ))}\n </select>\n </SelectWrapper>\n );\n};\n\nexport default Select;\n","import styled from \"@emotion/styled\";\nimport RCSlider from \"rc-slider\";\nimport \"rc-slider/assets/index.css\";\nimport { type Theme } from \"../theme\";\n\nexport const Slider = styled(RCSlider)<{ theme: Theme; color?: string }>`\n padding: 0;\n cursor: pointer;\n position: relative;\n\n &:hover {\n filter: brightness(125%);\n }\n\n .rc-slider-dot {\n border-radius: 0;\n box-shadow: none;\n margin: 0;\n border: none;\n background: ${({ theme }) => theme.colors.highlight2};\n }\n\n &.rc-slider-horizontal .rc-slider-dot {\n width: 1px;\n height: 0.25rem;\n bottom: -6px;\n }\n\n &.rc-slider-vertical .rc-slider-dot {\n width: 0.25rem;\n height: 1px;\n left: 3px;\n }\n\n .rc-slider-rail {\n background: ${({ theme }) => theme.colors.elevation1};\n }\n\n .rc-slider-track {\n background: ${({ theme, color }) => color || theme.colors.accent2};\n }\n\n .rc-slider-handle {\n border-radius: 0.125rem;\n background: ${({ theme, color }) => color || theme.colors.accent2};\n opacity: 1;\n cursor: pointer;\n border: none;\n &:hover {\n filter: brightness(110%);\n }\n }\n\n .rc-slider-handle,\n .rc-slider-handle.rc-slider-handle-dragging {\n box-shadow: 0 0 0 2px ${({ theme }) => theme.colors.elevation2};\n }\n\n &:before {\n content: \"\";\n position: absolute;\n background: transparent;\n }\n\n &.rc-slider-horizontal {\n height: 2px;\n\n .rc-slider-rail,\n .rc-slider-track,\n .rc-slider-step {\n height: 100%;\n }\n\n .rc-slider-handle {\n width: 0.5rem;\n height: 1rem;\n bottom: -7px;\n }\n\n .rc-slider-handle-dragging {\n cursor: ew-resize;\n }\n\n &:before {\n width: 100%;\n height: 1rem;\n top: -7px;\n }\n }\n\n &.rc-slider-vertical {\n width: 2px;\n\n .rc-slider-rail,\n .rc-slider-track,\n .rc-slider-step {\n width: 100%;\n }\n\n .rc-slider-track {\n left: 0;\n }\n\n .rc-slider-handle {\n width: 1rem;\n height: 0.5rem;\n right: -7px;\n }\n\n .rc-slider-handle-dragging {\n cursor: ns-resize;\n }\n\n &:before {\n height: 100%;\n width: 1rem;\n right: -7px;\n }\n }\n\n &.rc-slider-horizontal .rc-slider-mark {\n top: 1rem;\n }\n\n &.rc-slider-vertical .rc-slider-mark {\n left: 1rem;\n }\n\n .rc-slider-mark-text {\n font-size: 0.4rem;\n }\n`;\n\nexport default Slider;\n","// @ts-nocheck\nimport { useCallback, useEffect, useRef, useState } from \"react\";\n//@ts-ignore\nimport { CanvasSpliner } from \"CanvasSpliner\";\nimport styled from \"@emotion/styled\";\nimport { theme } from \"../../\";\n\nexport interface SplinePoint {\n x: number;\n y: number;\n}\n\nexport type SplineType = \"monotonic\" | \"natural\";\n\nexport type SplinePoints = Array<SplinePoint>;\n\nclass Spliner extends CanvasSpliner {\n _updateMousePosition(evt: MouseEvent) {\n const rect = this._canvas?.getBoundingClientRect();\n\n const scaleX = this._canvas.width / rect.width;\n const scaleY = this._canvas.height / rect.height;\n\n this._mouse = {\n x: (evt.clientX - rect.left) * scaleX,\n y: this._height - (evt.clientY - rect.top) * scaleY,\n };\n }\n\n getPoints() {\n const xFactor = 1 / this._width;\n const yFactor = 1 / this._height;\n return this._pointCollection._points.map(({ x, y }) => ({\n x: x * xFactor,\n y: y * yFactor,\n }));\n }\n\n removeAll() {\n const length = this._pointCollection.getNumberOfPoints();\n for (let i = length; i > 0; i--) {\n this._pointCollection.remove(i - 1);\n }\n }\n\n update(points: Array<{ x: number; y: number }>) {\n this.removeAll();\n\n const xFactor = this._width;\n const yFactor = this._height;\n points.forEach(({ x, y }) => {\n this._pointCollection.add({ x: x * xFactor, y: y * yFactor });\n });\n\n this.draw();\n }\n\n off(eventName: string, handler: (csObj: Spliner) => void) {\n // @TODO: implement unsibscribe\n }\n}\n\nconst WaveShaperInner = styled.div`\n height: 100%;\n width: 100%;\n position: relative;\n canvas {\n border: none !important;\n position: absolute;\n left: 0;\n right: 0;\n height: 100%;\n width: 100%;\n }\n`;\n\nexport interface SplineEditorProps {\n points: Array<{ x: number; y: number }>;\n type?: SplineType;\n textColor?: string;\n curveColor?: string;\n gridStep?: number;\n gridColor?: string;\n controlPointRadius?: number;\n controlPointColor?: string;\n onChange?: (points: SplinePoints) => void;\n onMove?: (points: SplinePoints) => void;\n}\n\nexport const SplineEditor = ({\n onChange,\n onMove,\n points,\n type = \"monotonic\",\n textColor = \"red\",\n curveColor = theme.colors.accent2,\n gridStep = 0.25,\n gridColor = theme.colors.elevation2,\n controlPointRadius = 14,\n controlPointColor = theme.colors.vivid1,\n}: SplineEditorProps) => {\n const ref = useRef<HTMLDivElement | null>(null);\n const [spliner, setSpliner] = useState<Spliner>();\n\n const handlePointsChange = useCallback(\n (csObj: Spliner) => {\n const points: SplinePoints = csObj.getPoints();\n onChange?.(points);\n },\n [onChange],\n );\n\n const handlePointMove = useCallback(\n (csObj: Spliner) => {\n const points: SplinePoints = csObj.getPoints();\n onMove?.(points);\n },\n [onMove],\n );\n\n useEffect(() => spliner?.update(points), [spliner, points]);\n\n useEffect(() => spliner?.setSplineType(type), [spliner, type]);\n useEffect(() => spliner?.setGridStep(gridStep), [spliner, gridStep]);\n useEffect(() => spliner?.setGridColor(gridColor), [spliner, gridColor]);\n useEffect(\n () => spliner?.setControlPointRadius(controlPointRadius),\n [spliner, controlPointRadius],\n );\n useEffect(() => spliner?.setTextColor(textColor), [spliner, textColor]);\n useEffect(() => {\n spliner?.setCurveColor(\"idle\", curveColor);\n // spliner?.setCurveColor(\"moving\", \"yellow\");\n }, [spliner, curveColor]);\n useEffect(() => {\n spliner?.setControlPointColor(\"idle\", controlPointColor);\n // spliner?.setControlPointColor(\"hovered\", \"blue\");\n // spliner?.setControlPointColor(\"grabbed\", \"black\");\n }, [spliner, controlPointColor]);\n\n useEffect(() => {\n if (!spliner) {\n return;\n }\n\n spliner.setCurveThickness(4);\n\n spliner.on(\"movePoint\", handlePointMove);\n spliner.on(\"releasePoint\", handlePointsChange);\n spliner.on(\"pointAdded\", handlePointsChange);\n spliner.on(\"pointRemoved\", handlePointsChange);\n\n spliner.draw();\n\n return () => {\n spliner.off(\"movePoint\", handlePointMove);\n spliner.off(\"releasePoint\", handlePointsChange);\n spliner.off(\"pointAdded\", handlePointsChange);\n spliner.off(\"pointRemoved\", handlePointsChange);\n };\n }, [spliner, handlePointsChange, handlePointMove]);\n\n useEffect(() => {\n if (!ref.current) {\n return;\n }\n\n const cs = new Spliner(ref.current, 1024, 1024);\n setSpliner(cs);\n }, [ref]);\n\n return <WaveShaperInner ref={ref} />;\n};\n\nexport default SplineEditor;\n","import styled from \"@emotion/styled\";\nimport { Theme } from \"../theme\";\n\nexport const ConfigRowLabel = styled.div``;\n\nexport const ConfigRowControl = styled.div<{ theme: Theme }>`\n font-family: var(--leva-fonts-mono);\n font-size: 0.7rem;\n color: ${({ theme }) => theme.colors.whitePrimary};\n`;\n\nexport const ConfigRowSeparator = styled.div<{ theme: Theme }>`\n border-bottom: 1px solid ${({ theme }) => theme.colors.elevation1};\n`;\n\nexport const ConfigRow = styled.div<{ theme: Theme; oneLineLabels?: boolean }>`\n padding: 0.2rem 0.4rem;\n font-size: 0.7rem;\n color: ${({ theme }) => theme.colors.highlight2};\n position: relative;\n display: grid;\n align-items: center;\n grid-template-rows: minmax(1.5rem, max-content);\n grid-template-columns: ${({ oneLineLabels }) =>\n oneLineLabels ? \"1fr\" : \"auto 10rem\"};\n row-gap: 0.1rem;\n column-gap: 0.4rem;\n`;\n\nexport const ConfigPanel = styled.div<{ theme: Theme }>`\n display: flex;\n flex-direction: column;\n gap: 0.4rem;\n background: ${({ theme }) => theme.colors.elevation2};\n padding: 0.4rem 0.1rem;\n`;\n\nexport const ConfigRowInner = styled.div<{ theme: Theme }>``;\n"],"names":["config","jsx","$7gk4U$jsx","jsxs","$7gk4U$jsxs","$7gk4U$emotionstyled","useEffect","$7gk4U$useEffect","useState","$7gk4U$useState","version","$7gk4U$version","useCallback","$7gk4U$useCallback","useRef","$7gk4U$useRef","createPortal","$7gk4U$createPortal","MdClose","$7gk4U$MdClose","MdSettings","$7gk4U$MdSettings","MdInfoOutline","$7gk4U$MdInfoOutline","useTheme","$7gk4U$useTheme","withTheme","$7gk4U$withTheme","FaPlus","$7gk4U$FaPlus","getConnectedEdges","$7gk4U$getConnectedEdges","addEdge","$7gk4U$addEdge","applyNodeChanges","$7gk4U$applyNodeChanges","applyEdgeChanges","$7gk4U$applyEdgeChanges","Handle","$7gk4U$Handle","create","$7gk4U$create","setAudioNodeTypes","$7gk4U$setAudioNodeTypes","createPatch","$7gk4U$createPatch","reverse","$7gk4U$reverse","patch","$7gk4U$patch","$7gk4U$create1","injectGlobal","$7gk4U$injectGlobal","Item","$7gk4U$Item","Menu","$7gk4U$Menu","FaFileUpload","$7gk4U$FaFileUpload","FaVolumeOff","$7gk4U$FaVolumeOff","FaRegArrowAltCircleRight","$7gk4U$FaRegArrowAltCircleRight","useThrottledCallback","$7gk4U$useThrottledCallback","$7gk4U$rcslider","CanvasSpliner","$7gk4U$CanvasSpliner","$parcel$export","e","n","v","s","Object","defineProperty","get","set","enumerable","configurable","PortType","$fcabc075f2eebe7f$export$b0b7b95ee465c83c","$ee9ef7c1261ede87$exports","$4001d24decbb98f7$export$2b77a92f1a5ad772","$0cdf21d270160c43$export$8ecd240bc8faaeeb","$fee4ec5a9782241c$export$a98f0dcb43a68a25","$4866e5bff8d594b9$export$f5b8910cec6cf069","$eadb9fa465de5e7c$export$7a40489edcbfb3a1","$8d9f8f4bde3307d1$export$5a1d7ca0a925d9c2","$f537c5f3d37e7de0$export$6bf0cd3a219bbade","$44b7e15e1a9af68f$export$353f5b6fc5456de1","$6cd47b275e936c4f$export$ef9b1a59e592288f","$145c4d4c74f0de83$export$472062a354075cee","$2c0e5b77732bcbe8$export$2bf7c2638a145e5c","$149f0c1aa7846f5b$export$555ece15b74b7abc","$149f0c1aa7846f5b$export$ef9ca7b440c0032c","$149f0c1aa7846f5b$export$bd1dc14d6df7044e","$149f0c1aa7846f5b$export$d56900fc3755b916","$149f0c1aa7846f5b$export$aac584ace4a7b830","$149f0c1aa7846f5b$export$edaba703bd8b8dfa","$4001d24decbb98f7$var$ModalOuter","div","theme","zIndex","modal","colors","elevation3","$4001d24decbb98f7$var$ModalInner","elevation2","elevation1","$4001d24decbb98f7$var$ModalCloser","children","onClose","props","escHandler","event","key","document","addEventListener","removeEventListener","onClick","stopPropagation","body","$fcabc075f2eebe7f$exports","$fcabc075f2eebe7f$export$956b3cf15d7c363","$fcabc075f2eebe7f$export$21d634b1d5d9bee3","$fcabc075f2eebe7f$export$9f05d3e6ade4c09e","rowHeight","cols","$e85a74fe7877b330$var$cloneObject","input","JSON","parse","stringify","$6afd48ce6460068b$export$e364ea0c1dfb25e5","left","right","setLeft","Set","map","item","id","setRight","added","filter","has","removed","args","nodes","edges","onNodesChange","changes","node","dragHandle","onEdgesChange","onConnect","connection","addNode","concat","setNodes","setEdges","setNodesAndEdges","getNodesAndEdges","clearElements","getNode","find","updateNodeData","data","nodeTypes","setNodeTypes","history","maxHistoryLength","buffer","pointer","skipCollect","push","newBuffer","slice","Math","max","min","back","controlPanel","patchData","reversedPatchData","forward","clear","nodesState","project","files","setProject","currentFileIndex","getProject","pullEditorChanges","getEditorState","updateFileContent","currentFile","file","type","syncEditorWithCurrentFile","setEditorState","console","log","setCurrentFileIndex","newFileIndex","index","f","i","updateFileName","fileName","name","addFile","deleteFile","fileIndex","_","setGraph","createNodes","createEdges","activeNodes","activeEdges","clearGraph","createNode","Promise","all","nodeData","nodesConfiguration","Error","defaultConfig","removeNode","removeNodes","currentNodes","onNodesDelete","removeEdges","removeNodesFromControlPanel","parentNodeIds","resultingNodes","parentNode","includes","nodeIds","currentEdges","onEdgesDelete","edgeIds","newEdges","plugins","setPlugins","nodesConf","reduce","acc","plugin","components","subAcc","keys","audioNode","showMinimap","setConfig","viewport","r","setTimeout","isHelpShown","toggleHelp","showHelp","copyBuffer","copy","elements","copySelectedItems","selected","length","pasteBuffer","x","y","nodesToCopy","edgesToCopy","topLeftNode","position","xDelta","yDelta","newNodes","mapping","random","newNodeId","Date","floor","toString","edge","source","target","replace","getControlPanelNode","controlPanelNode","error","show","size","width","height","showControlPanel","hideControlPanel","addNodeToControlPanel","newNode","removeNodeFromControlPanel","setControlPanelNodes","setControlPanelSize","zoom","setViewport","api","timer","jsondiffpatchInstance","oldState","collectChanges","propertyFilter","context","parent","childName","state","prevState","clearTimeout","diff","subscribe","promises","currentState","storeChanges","newState","nodeChanges","edgeChanges","removedEdges","removedNodes","promise","registerAudioNodes","add","delete","values","registerAudioConnections","unregisterAudioConnections","unregisterAudioNodes","whitePrimary","ul","accent2","highlight2","$7eef8b3405d9f479$export$7129a6e2db131a76","span","isActive","highlight1","highlight3","label","accent3","$4bd7a7548349db5f$exports","$925e30e6078450bc$export$3a5757a785a34769","$e0ee9b956b7c064a$export$1e86115ead375efc","url","worker","setWorker","newWorker","Worker","terminate","channel","setChannel","newChannel","MessageChannel","port2","start","close","$380e1488605d504c$exports","$380e1488605d504c$export$cd440e094f060920","$380e1488605d504c$export$25df2e315be8e003","param","value","audioContext","setValueAtTime","currentTime","resolve","reject","reader","FileReader","readAsDataURL","onload","result","onerror","forEach","prototype","hasOwnProperty","call","accent1","$8ac710fa6e4a22e6$var$NodeWrapper","$8ac710fa6e4a22e6$var$Section","$8ac710fa6e4a22e6$export$1bdb8f2d1fe25c22","$8ac710fa6e4a22e6$var$portColors","Audio","Gate","Number","Any","$8ac710fa6e4a22e6$var$StyledHandle","shouldForwardProp","prop","portType","Array","isArray","join","$6645e9588375d2aa$export$86de09faaa70680d","$6645e9588375d2aa$export$548ca3bae446ddc2","className","$6645e9588375d2aa$export$9fb15e3cc717240","$6645e9588375d2aa$export$be58b4326e23250f","resumeContextLayout","active","$0cdf21d270160c43$var$CheckerBox","$0cdf21d270160c43$var$CheckerLabel","$0cdf21d270160c43$var$CheckerSubtitle","$0cdf21d270160c43$var$CheckedInner","subtitle","onChange","checked","$fee4ec5a9782241c$var$RadioGroupWrapper","options","optionValue","$4866e5bff8d594b9$export$fb9f58ebe9de6283","$4866e5bff8d594b9$export$42e20bb2ce90003b","placeholder","inputProps","onKeyDownCapture","$eadb9fa465de5e7c$var$InputButton","button","$eadb9fa465de5e7c$var$DropdownContainer","$eadb9fa465de5e7c$var$DropdownList","isOpen","$eadb9fa465de5e7c$var$DropdownItem","isHighlighted","$eadb9fa465de5e7c$var$DropdownItemValue","$eadb9fa465de5e7c$var$DropdownItemLabel","onSubmit","currentValue","setCurrentValue","setIsOpen","highlightedIndex","setHighlightedIndex","inputRef","dropdownRef","filteredOptions","option","toLowerCase","applyCurrentValue","selectOption","handleKeyDown","preventDefault","prev","handleClickOutside","current","contains","highlightedElement","scrollIntoView","block","behavior","ref","onKeyDown","onFocus","onBlur","autoComplete","onMouseEnter","$8d9f8f4bde3307d1$var$StyledInputWrapper","$8d9f8f4bde3307d1$var$StyledInputInner","$f537c5f3d37e7de0$var$SampleInput","$f537c5f3d37e7de0$var$SampleInputInner","Infinity","step","startChangedHandler","factor","st","round","deltaY","toFixed","onchange","$6cd47b275e936c4f$var$SelectWrapper","disabled","color","$2c0e5b77732bcbe8$var$Spliner","_updateMousePosition","evt","rect","_canvas","getBoundingClientRect","scaleX","scaleY","_mouse","clientX","_height","clientY","top","getPoints","xFactor","_width","yFactor","_pointCollection","_points","removeAll","getNumberOfPoints","remove","update","points","draw","off","eventName","handler","$2c0e5b77732bcbe8$var$WaveShaperInner","onMove","textColor","curveColor","gridStep","gridColor","controlPointRadius","controlPointColor","spliner","setSpliner","handlePointsChange","csObj","handlePointMove","setSplineType","setGridStep","setGridColor","setControlPointRadius","setTextColor","setCurveColor","setControlPointColor","setCurveThickness","on","oneLineLabels","Modal","Checker","RadioGroup","Input","DropdownInput","ColorInput","NumberInput","Button","Select","Slider","SplineEditor","ConfigRowLabel","ConfigRowControl","ConfigRowSeparator","ConfigRow","ConfigPanel","ConfigRowInner"],"version":3,"file":"components.js.map"}