From f537f1eab9de81d650a12de46efcb4698446d408 Mon Sep 17 00:00:00 2001 From: nikita Date: Sat, 4 Apr 2026 04:59:42 +0300 Subject: [PATCH] feat: IDE --- README.md | 1 - frontend/package.json | 5 + .../routing/helper/protected.route.tsx | 8 +- .../src/app/providers/routing/routing.tsx | 106 ++- frontend/src/modules/ide/IDE.tsx | 191 ++++ .../src/modules/ide/components/CodeEditor.tsx | 89 ++ .../modules/ide/components/ContextMenu.tsx | 99 ++ .../modules/ide/components/FileExplorer.tsx | 318 +++++++ .../modules/ide/components/FileTreeItem.tsx | 169 ++++ .../modules/ide/components/InputDialog.tsx | 119 +++ .../src/modules/ide/components/StatusBar.tsx | 44 + .../src/modules/ide/components/TabBar.tsx | 196 ++++ .../src/modules/ide/components/TitleBar.tsx | 55 ++ frontend/src/modules/ide/components/index.ts | 8 + frontend/src/modules/ide/helpers/fileTree.ts | 174 ++++ frontend/src/modules/ide/index.ts | 3 + frontend/src/modules/ide/store/useIDEStore.ts | 385 ++++++++ frontend/src/modules/ide/types.ts | 24 + frontend/src/pages/ide.page.tsx | 9 + frontend/yarn.lock | 896 +++++++++++++++++- 20 files changed, 2884 insertions(+), 15 deletions(-) delete mode 100644 README.md create mode 100644 frontend/src/modules/ide/IDE.tsx create mode 100644 frontend/src/modules/ide/components/CodeEditor.tsx create mode 100644 frontend/src/modules/ide/components/ContextMenu.tsx create mode 100644 frontend/src/modules/ide/components/FileExplorer.tsx create mode 100644 frontend/src/modules/ide/components/FileTreeItem.tsx create mode 100644 frontend/src/modules/ide/components/InputDialog.tsx create mode 100644 frontend/src/modules/ide/components/StatusBar.tsx create mode 100644 frontend/src/modules/ide/components/TabBar.tsx create mode 100644 frontend/src/modules/ide/components/TitleBar.tsx create mode 100644 frontend/src/modules/ide/components/index.ts create mode 100644 frontend/src/modules/ide/helpers/fileTree.ts create mode 100644 frontend/src/modules/ide/index.ts create mode 100644 frontend/src/modules/ide/store/useIDEStore.ts create mode 100644 frontend/src/modules/ide/types.ts create mode 100644 frontend/src/pages/ide.page.tsx diff --git a/README.md b/README.md deleted file mode 100644 index fa77674..0000000 --- a/README.md +++ /dev/null @@ -1 +0,0 @@ -# HellreigN \ No newline at end of file diff --git a/frontend/package.json b/frontend/package.json index 4aecc80..74ee85f 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -11,19 +11,24 @@ }, "dependencies": { "@codemirror/lang-sql": "^6.10.0", + "@monaco-editor/react": "^4.7.0", "@tailwindcss/vite": "^4.2.2", "@uiw/react-codemirror": "^4.25.8", "axios": "^1.13.6", + "file-surf": "^1.0.3", "framer-motion": "^12.38.0", + "monaco-languageclient": "^10.7.0", "primeicons": "^7.0.0", "primereact": "^10.9.7", "react": "^19.2.4", "react-dom": "^19.2.4", + "react-force-graph-2d": "^1.29.1", "react-icons": "^5.6.0", "react-router-dom": "^7.13.1", "recharts": "^3.8.0", "tailwind": "^4.0.0", "tailwindcss": "^4.2.2", + "vscode-ws-jsonrpc": "^3.5.0", "zustand": "^5.0.12" }, "devDependencies": { diff --git a/frontend/src/app/providers/routing/helper/protected.route.tsx b/frontend/src/app/providers/routing/helper/protected.route.tsx index 8ce4d9c..8eb41a6 100644 --- a/frontend/src/app/providers/routing/helper/protected.route.tsx +++ b/frontend/src/app/providers/routing/helper/protected.route.tsx @@ -1,12 +1,12 @@ -import { useAuthStore } from "@/store/auth/auth.store"; +import { useAuthStore } from "@/modules/auth/store/useAuthStore"; import { Navigate } from "react-router-dom"; export const ProtectedRoute = ({ children }: { children: React.ReactNode }) => { const { isAuthenticated } = useAuthStore(); - if (!isAuthenticated) { - return ; - } + // if (!isAuthenticated) { + // return ; + // } return <>{children}; }; diff --git a/frontend/src/app/providers/routing/routing.tsx b/frontend/src/app/providers/routing/routing.tsx index 65d1d3b..131f5f6 100644 --- a/frontend/src/app/providers/routing/routing.tsx +++ b/frontend/src/app/providers/routing/routing.tsx @@ -2,10 +2,105 @@ import { Suspense } from "react"; import { Routes as ReactRoutes, Route, Navigate } from "react-router-dom"; import { HomePage } from "@/pages/home.page"; import { ThemesPage } from "@/pages/themes.page"; +import { TestPage } from "@/pages/test.page"; +import { Test2Page, type GraphData } from "@/pages/test2.page"; import { AuthPage } from "@/pages/auth.page"; import { RegisterPage } from "@/pages/register.page"; -import { AddAgentsPage } from "@/pages/add-agents.page"; import { DefaultLayout } from "@/shared/layouts/DefaultLayout"; +import { AddAgentsPage } from "@/pages/add-agents.page"; +import { IDEPage } from "@/pages/ide.page"; + +export const mockGraphData: GraphData = { + nodes: [ + { + id: "api-gateway", + name: "API Gateway", + type: "service", + val: 12, + description: "Входная точка API", + }, + { + id: "auth-service", + name: "Auth Service", + type: "service", + val: 12, + description: "Аутентификация", + }, + { + id: "db-service", + name: "Database", + type: "service", + val: 12, + description: "Хранилище данных", + }, + { + id: "redis-service", + name: "Redis", + type: "service", + val: 12, + description: "Кэширование", + }, + { + id: "queue-service", + name: "Message Queue", + type: "service", + val: 12, + description: "Очередь сообщений", + }, + { + id: "user-agent", + name: "User Agent", + type: "agent", + val: 8, + description: "Обработка пользователей", + }, + { + id: "payment-agent", + name: "Payment Agent", + type: "agent", + val: 8, + description: "Платежи", + }, + { + id: "notification-agent", + name: "Notification Agent", + type: "agent", + val: 8, + description: "Уведомления", + }, + { + id: "analytics-agent", + name: "Analytics Agent", + type: "agent", + val: 8, + description: "Аналитика", + }, + { + id: "report-agent", + name: "Report Agent", + type: "agent", + val: 8, + description: "Отчеты", + }, + ], + links: [ + { source: "user-agent", target: "api-gateway", type: "uses" }, + { source: "user-agent", target: "auth-service", type: "uses" }, + { source: "user-agent", target: "db-service", type: "uses" }, + { source: "payment-agent", target: "api-gateway", type: "uses" }, + { source: "payment-agent", target: "auth-service", type: "uses" }, + { source: "payment-agent", target: "queue-service", type: "uses" }, + { source: "notification-agent", target: "redis-service", type: "uses" }, + { source: "notification-agent", target: "queue-service", type: "uses" }, + { source: "analytics-agent", target: "db-service", type: "uses" }, + { source: "report-agent", target: "db-service", type: "uses" }, + { source: "report-agent", target: "redis-service", type: "uses" }, + { source: "api-gateway", target: "auth-service", type: "depends_on" }, + { source: "auth-service", target: "db-service", type: "depends_on" }, + { source: "api-gateway", target: "queue-service", type: "depends_on" }, + { source: "queue-service", target: "redis-service", type: "depends_on" }, + ], +}; export const Routing = () => { return ( @@ -17,19 +112,20 @@ export const Routing = () => { } > - {/* Публичные маршруты */} } /> } /> - {/* Защищённые маршруты с Layout */} }> } /> } /> } /> - } /> - } /> + } /> + } /> + + } /> + } /> diff --git a/frontend/src/modules/ide/IDE.tsx b/frontend/src/modules/ide/IDE.tsx new file mode 100644 index 0000000..7e0dd30 --- /dev/null +++ b/frontend/src/modules/ide/IDE.tsx @@ -0,0 +1,191 @@ +import React, { useEffect } from "react"; +import { MdAdd } from "react-icons/md"; +import { GoTrash } from "react-icons/go"; +import { + useIDEStore, + initialFiles as defaultInitialFiles, +} from "./store/useIDEStore"; +import type { FileNode } from "./types"; +import { + FileExplorer, + TabBar, + CodeEditor, + TitleBar, + StatusBar, +} from "./components"; + +interface IDEProps { + initialFiles?: FileNode; +} + +export const IDE: React.FC = ({ + initialFiles: externalFiles, +}: IDEProps = {}) => { + const files = useIDEStore((state) => state.files); + const openFiles = useIDEStore((state) => state.openFiles); + const activeFile = useIDEStore((state) => state.activeFile); + const createNewProject = useIDEStore((state) => state.createNewProject); + const selectFile = useIDEStore((state) => state.selectFile); + const updateFileContent = useIDEStore((state) => state.updateFileContent); + const closeFile = useIDEStore((state) => state.closeFile); + const closeAllFiles = useIDEStore((state) => state.closeAllFiles); + const closeOtherFiles = useIDEStore((state) => state.closeOtherFiles); + const initialize = useIDEStore((state) => state.initialize); + const isInitialized = useIDEStore((state) => state.isInitialized); + + // Инициализация файлов + useEffect(() => { + if (!isInitialized) { + const filesToInit = externalFiles || defaultInitialFiles; + initialize(filesToInit); + } + }, [isInitialized, externalFiles, initialize]); + + // Если проект не открыт + if (!files) { + return ( +
+ +
+
+
+ +
+
+ No project open +
+
+ Create a new project to get started +
+ +
+
+ +
+ ); + } + + return ( +
+
+ + {activeFile ? `${activeFile.name} - ` : ""} + {files.name} + +
+
+
+ +
+
+ + +
+
+ +
+ ); +}; + +export default IDE; diff --git a/frontend/src/modules/ide/components/CodeEditor.tsx b/frontend/src/modules/ide/components/CodeEditor.tsx new file mode 100644 index 0000000..4b50be5 --- /dev/null +++ b/frontend/src/modules/ide/components/CodeEditor.tsx @@ -0,0 +1,89 @@ +import React from "react"; +import Editor from "@monaco-editor/react"; +import { FiFolder } from "react-icons/fi"; +import { getLanguage } from "../helpers/fileTree"; + +interface CodeEditorProps { + filePath: string; + content: string; + onChange: (content: string) => void; +} + +export const CodeEditor: React.FC = ({ + filePath, + content, + onChange, +}) => { + return ( +
+
+ {filePath ? ( + onChange(value || "")} + theme="vs-dark" + options={{ + minimap: { enabled: false }, + fontSize: 14, + fontFamily: "'Cascadia Code', 'Fira Code', monospace", + tabSize: 4, + wordWrap: "on", + lineNumbers: "on", + automaticLayout: true, + renderWhitespace: "selection", + smoothScrolling: true, + }} + /> + ) : ( +
+
+
+ +
+
+ Welcome to Web VS Code +
+
+ Right-click on a folder to create files +
+
+ Or right-click anywhere in the explorer +
+
+
+ )} +
+
+ ); +}; diff --git a/frontend/src/modules/ide/components/ContextMenu.tsx b/frontend/src/modules/ide/components/ContextMenu.tsx new file mode 100644 index 0000000..d07cb43 --- /dev/null +++ b/frontend/src/modules/ide/components/ContextMenu.tsx @@ -0,0 +1,99 @@ +import React, { useEffect } from "react"; +import { FiFile, FiFolder, FiEdit3, FiTrash2 } from "react-icons/fi"; + +const MenuItem: React.FC<{ + onClick: () => void; + danger?: boolean; + children: React.ReactNode; +}> = ({ onClick, danger, children }) => ( +
{ + e.currentTarget.style.backgroundColor = "#2a2d2e"; + }} + onMouseLeave={(e) => { + e.currentTarget.style.backgroundColor = "transparent"; + }} + > + {children} +
+); + +interface ContextMenuProps { + x: number; + y: number; + onClose: () => void; + onNewFile: () => void; + onNewFolder: () => void; + onRename: () => void; + onDelete: () => void; + hasNode: boolean; +} + +export const ContextMenu: React.FC = ({ + x, + y, + onClose, + onNewFile, + onNewFolder, + onRename, + onDelete, + hasNode, +}) => { + useEffect(() => { + const handleClick = () => onClose(); + document.addEventListener("click", handleClick); + return () => document.removeEventListener("click", handleClick); + }, [onClose]); + + return ( +
+ + New File + + + New Folder + + {hasNode && ( + <> +
+ + Rename + + + Delete + + + )} +
+ ); +}; diff --git a/frontend/src/modules/ide/components/FileExplorer.tsx b/frontend/src/modules/ide/components/FileExplorer.tsx new file mode 100644 index 0000000..38f537d --- /dev/null +++ b/frontend/src/modules/ide/components/FileExplorer.tsx @@ -0,0 +1,318 @@ +import React, { useEffect, useState } from "react"; +import { FiSearch, FiFile, FiFolder, FiMinus } from "react-icons/fi"; +import { GoKebabHorizontal } from "react-icons/go"; +import { MdClose, MdAdd } from "react-icons/md"; +import { FileTreeItem } from "./FileTreeItem"; +import { ContextMenu } from "./ContextMenu"; +import { InputDialog } from "./InputDialog"; +import { filterTree, collectPathsToExpand } from "../helpers/fileTree"; +import { useIDEStore } from "../store/useIDEStore"; +import type { FileNode } from "../types"; + +interface FileExplorerProps { + files: FileNode; + onDeleteRoot: () => void; +} + +export const FileExplorer: React.FC = ({ + files, + onDeleteRoot, +}) => { + const store = useIDEStore(); + const [showSearch, setShowSearch] = useState(false); + + const handleEmptyContextMenu = (e: React.MouseEvent) => { + e.preventDefault(); + e.stopPropagation(); + store.setContextMenu({ x: e.clientX, y: e.clientY, node: null }); + }; + + const handleNodeContextMenu = (e: React.MouseEvent, node: FileNode) => { + e.preventDefault(); + e.stopPropagation(); + store.setContextMenu({ x: e.clientX, y: e.clientY, node }); + }; + + const filteredFiles = store.searchQuery + ? filterTree(files, store.searchQuery) + : files; + + useEffect(() => { + if (store.searchQuery && files) { + const pathsToExpand = collectPathsToExpand(files, store.searchQuery); + if (pathsToExpand.size > 0) { + store.autoExpandPaths(pathsToExpand); + } + } + }, [store.searchQuery, files, store.autoExpandPaths]); + + return ( +
+
+ + EXPLORER + +
+ + + +
+
+ +
+ + + {files.name} + +
+ + {showSearch && ( +
+
+ + store.setSearchQuery(e.target.value)} + placeholder="Search..." + autoFocus + style={{ + flex: 1, + padding: "5px 6px", + backgroundColor: "transparent", + border: "none", + color: "#cccccc", + fontSize: "12px", + outline: "none", + }} + /> + {store.searchQuery && ( + + )} +
+
+ )} + +
+ {filteredFiles ? ( + + ) : ( +
+ No results found +
+ )} +
+ + {store.contextMenu && ( + store.setContextMenu(null)} + onNewFile={() => { + store.setDialog({ + type: "newFile", + node: store.contextMenu?.node || null, + }); + store.setContextMenu(null); + }} + onNewFolder={() => { + store.setDialog({ + type: "newFolder", + node: store.contextMenu?.node || null, + }); + store.setContextMenu(null); + }} + onRename={() => { + store.setDialog({ + type: "rename", + node: store.contextMenu?.node || null, + }); + store.setContextMenu(null); + }} + onDelete={() => { + if (store.contextMenu?.node) { + store.handleDeleteNode(store.contextMenu.node); + } + store.setContextMenu(null); + }} + hasNode={!!store.contextMenu.node} + /> + )} + + {store.dialog && ( + store.setDialog(null)} + /> + )} +
+ ); +}; diff --git a/frontend/src/modules/ide/components/FileTreeItem.tsx b/frontend/src/modules/ide/components/FileTreeItem.tsx new file mode 100644 index 0000000..05c7039 --- /dev/null +++ b/frontend/src/modules/ide/components/FileTreeItem.tsx @@ -0,0 +1,169 @@ +import React, { useState } from "react"; +import { FiChevronRight, FiChevronDown, FiTrash2 } from "react-icons/fi"; +import { GoFile } from "react-icons/go"; +import type { FileNode } from "../types"; + +interface FileTreeItemProps { + node: FileNode; + level: number; + onFileSelect: (node: FileNode) => void; + selectedFile: string | null; + onContextMenu: (e: React.MouseEvent, node: FileNode) => void; + expandedFolders: Set; + onToggleFolder: (path: string) => void; + onDelete: (node: FileNode) => void; + isRoot?: boolean; + searchQuery?: string; +} + +export const FileTreeItem: React.FC = ({ + node, + level, + onFileSelect, + selectedFile, + onContextMenu, + expandedFolders, + onToggleFolder, + onDelete, + isRoot, + searchQuery, +}) => { + const isFolder = node.type === "folder"; + const isSelected = selectedFile === node.path && !isFolder; + const isExpanded = expandedFolders.has(node.path || node.name); + const [hovered, setHovered] = useState(false); + + const handleClick = () => { + if (isFolder) { + onToggleFolder(node.path || node.name); + } else { + onFileSelect(node); + } + }; + + const handleDelete = (e: React.MouseEvent) => { + e.stopPropagation(); + onDelete(node); + }; + + const highlightText = (text: string, query: string) => { + if (!query) return text; + const idx = text.toLowerCase().indexOf(query.toLowerCase()); + if (idx === -1) return text; + return ( + <> + {text.slice(0, idx)} + + {text.slice(idx, idx + query.length)} + + {text.slice(idx + query.length)} + + ); + }; + + return ( +
+
onContextMenu(e, node)} + onMouseEnter={() => setHovered(true)} + onMouseLeave={() => setHovered(false)} + style={{ + paddingLeft: isRoot ? "8px" : `${level * 16 + 8}px`, + paddingTop: "4px", + paddingBottom: "4px", + cursor: "pointer", + display: "flex", + alignItems: "center", + gap: "6px", + backgroundColor: isSelected ? "#094771" : "transparent", + color: isSelected ? "#fff" : "#cccccc", + fontSize: "13px", + transition: "background-color 0.1s", + userSelect: "none", + minHeight: "28px", + }} + > + + {isFolder ? ( + isExpanded ? ( + + ) : ( + + ) + ) : ( + + )} + + + {searchQuery ? highlightText(node.name, searchQuery) : node.name} + + {hovered && !isRoot && ( + + )} +
+ {isFolder && isExpanded && node.children && ( +
+ {node.children.map((child, idx) => ( + + ))} +
+ )} +
+ ); +}; diff --git a/frontend/src/modules/ide/components/InputDialog.tsx b/frontend/src/modules/ide/components/InputDialog.tsx new file mode 100644 index 0000000..38270e9 --- /dev/null +++ b/frontend/src/modules/ide/components/InputDialog.tsx @@ -0,0 +1,119 @@ +import React, { useState, useRef, useEffect } from "react"; + +interface InputDialogProps { + title: string; + initialValue?: string; + onConfirm: (value: string) => void; + onCancel: () => void; +} + +export const InputDialog: React.FC = ({ + title, + initialValue = "", + onConfirm, + onCancel, +}) => { + const [value, setValue] = useState(initialValue); + const inputRef = useRef(null); + + useEffect(() => { + inputRef.current?.focus(); + inputRef.current?.select(); + }, []); + + return ( +
+
e.stopPropagation()} + > +

+ {title} +

+

+ Enter a new name +

+ setValue(e.target.value)} + onKeyDown={(e) => + e.key === "Enter" && value.trim() && onConfirm(value.trim()) + } + style={{ + width: "100%", + padding: "10px", + backgroundColor: "#3c3c3c", + border: "1px solid #3e3e42", + borderRadius: "6px", + color: "#ccc", + fontSize: "14px", + marginBottom: "20px", + outline: "none", + }} + /> +
+ + +
+
+
+ ); +}; diff --git a/frontend/src/modules/ide/components/StatusBar.tsx b/frontend/src/modules/ide/components/StatusBar.tsx new file mode 100644 index 0000000..257cd45 --- /dev/null +++ b/frontend/src/modules/ide/components/StatusBar.tsx @@ -0,0 +1,44 @@ +import React from "react"; +import { FiGitBranch, FiCheckCircle, FiAlertCircle } from "react-icons/fi"; +import type { FileNode } from "../types"; + +interface StatusBarProps { + activeFile: FileNode | null; +} + +export const StatusBar: React.FC = ({ activeFile }) => { + return ( +
+
+ + main + + + 0 0 + +
+
+ {activeFile && ( + + Ln 1, Col 1 | Spaces: 4 | UTF-8 |{" "} + {activeFile.path?.split(".").pop()?.toUpperCase() || "TXT"} + + )} + Web VS Code +
+
+ ); +}; diff --git a/frontend/src/modules/ide/components/TabBar.tsx b/frontend/src/modules/ide/components/TabBar.tsx new file mode 100644 index 0000000..797332e --- /dev/null +++ b/frontend/src/modules/ide/components/TabBar.tsx @@ -0,0 +1,196 @@ +import React, { useState } from "react"; +import { GoFile } from "react-icons/go"; +import { MdClose } from "react-icons/md"; +import type { FileNode } from "../types"; + +interface TabBarProps { + openFiles: FileNode[]; + activeFile: FileNode | null; + onSelectFile: (file: FileNode) => void; + onCloseFile: (file: FileNode) => void; + onCloseAll: () => void; + onCloseOthers: (file: FileNode) => void; +} + +export const TabBar: React.FC = ({ + openFiles, + activeFile, + onSelectFile, + onCloseFile, + onCloseAll, + onCloseOthers, +}) => { + const [showContextMenu, setShowContextMenu] = useState<{ + x: number; + y: number; + file: FileNode; + } | null>(null); + + const handleContextMenu = (e: React.MouseEvent, file: FileNode) => { + e.preventDefault(); + setShowContextMenu({ x: e.clientX, y: e.clientY, file }); + }; + + return ( + <> +
+
+ +
+ {openFiles.map((file) => ( +
onSelectFile(file)} + onContextMenu={(e) => handleContextMenu(e, file)} + style={{ + display: "flex", + alignItems: "center", + padding: "8px 16px", + backgroundColor: + activeFile?.path === file.path ? "#1e1e1e" : "#2d2d30", + color: activeFile?.path === file.path ? "#fff" : "#cccccc", + borderRight: "1px solid #3e3e42", + cursor: "pointer", + fontSize: "13px", + gap: "10px", + whiteSpace: "nowrap", + transition: "all 0.1s", + borderTop: + activeFile?.path === file.path + ? "2px solid #0e639c" + : "2px solid transparent", + }} + > + + {file.name} + +
+ ))} +
+ {showContextMenu && ( +
+
{ + onCloseOthers(showContextMenu.file); + setShowContextMenu(null); + }} + style={{ + padding: "8px 16px", + cursor: "pointer", + color: "#cccccc", + fontSize: "13px", + }} + onMouseEnter={(e) => { + e.currentTarget.style.backgroundColor = "#2a2d2e"; + }} + onMouseLeave={(e) => { + e.currentTarget.style.backgroundColor = "transparent"; + }} + > + Close Others +
+
{ + onCloseAll(); + setShowContextMenu(null); + }} + style={{ + padding: "8px 16px", + cursor: "pointer", + color: "#cccccc", + fontSize: "13px", + }} + onMouseEnter={(e) => { + e.currentTarget.style.backgroundColor = "#2a2d2e"; + }} + onMouseLeave={(e) => { + e.currentTarget.style.backgroundColor = "transparent"; + }} + > + Close All +
+
+ )} + + ); +}; diff --git a/frontend/src/modules/ide/components/TitleBar.tsx b/frontend/src/modules/ide/components/TitleBar.tsx new file mode 100644 index 0000000..99fae56 --- /dev/null +++ b/frontend/src/modules/ide/components/TitleBar.tsx @@ -0,0 +1,55 @@ +import React from "react"; +import { FiGitBranch, FiCheckCircle } from "react-icons/fi"; + +export const TitleBar: React.FC = () => { + return ( +
+
+
+
+
+
+
+ + Web VS Code + +
+
+ + main + +
+
+ ); +}; diff --git a/frontend/src/modules/ide/components/index.ts b/frontend/src/modules/ide/components/index.ts new file mode 100644 index 0000000..95f10f9 --- /dev/null +++ b/frontend/src/modules/ide/components/index.ts @@ -0,0 +1,8 @@ +export { ContextMenu } from "./ContextMenu"; +export { InputDialog } from "./InputDialog"; +export { FileTreeItem } from "./FileTreeItem"; +export { FileExplorer } from "./FileExplorer"; +export { TabBar } from "./TabBar"; +export { CodeEditor } from "./CodeEditor"; +export { TitleBar } from "./TitleBar"; +export { StatusBar } from "./StatusBar"; diff --git a/frontend/src/modules/ide/helpers/fileTree.ts b/frontend/src/modules/ide/helpers/fileTree.ts new file mode 100644 index 0000000..22f60be --- /dev/null +++ b/frontend/src/modules/ide/helpers/fileTree.ts @@ -0,0 +1,174 @@ +import type { FileNode } from "../types"; + +export const addPaths = (node: FileNode, parentPath: string = ""): FileNode => { + const currentPath = parentPath ? `${parentPath}/${node.name}` : node.name; + const newNode = { ...node, path: currentPath }; + if (newNode.children) { + newNode.children = newNode.children.map((child) => + addPaths(child, currentPath), + ); + } + return newNode; +}; + +export const getAllFolderPaths = (node: FileNode): string[] => { + let paths: string[] = []; + if (node.type === "folder") { + paths.push(node.path || node.name); + if (node.children) { + node.children.forEach((child) => { + paths = [...paths, ...getAllFolderPaths(child)]; + }); + } + } + return paths; +}; + +export const findNode = (node: FileNode, path: string): FileNode | null => { + if (node.path === path) return node; + if (node.children) { + for (const child of node.children) { + const found = findNode(child, path); + if (found) return found; + } + } + return null; +}; + +export const deleteNode = (node: FileNode, path: string): FileNode | null => { + if (node.path === path) return null; + + if (node.children) { + const filtered = node.children.filter((child) => child.path !== path); + const mapped = filtered + .map((child) => deleteNode(child, path)) + .filter((child): child is FileNode => child !== null); + return { ...node, children: mapped }; + } + return node; +}; + +export const addNode = ( + node: FileNode, + parentPath: string, + newNode: FileNode, +): FileNode => { + if (node.path === parentPath) { + const newPath = addPaths(newNode, node.path); + return { ...node, children: [...(node.children || []), newPath] }; + } + if (node.children) { + return { + ...node, + children: node.children.map((child) => + addNode(child, parentPath, newNode), + ), + }; + } + return node; +}; + +export const renameNode = ( + node: FileNode, + oldPath: string, + newName: string, +): FileNode | null => { + if (node.path === oldPath) { + const pathParts = node.path?.split("/") || []; + pathParts[pathParts.length - 1] = newName; + const newPath = pathParts.join("/"); + const renamedNode = { ...node, name: newName, path: newPath }; + + if (renamedNode.children) { + renamedNode.children = renamedNode.children.map((child) => { + const oldChildPath = child.path || ""; + const newChildPath = oldChildPath.replace(oldPath, newPath); + return ( + renameNode( + child, + oldChildPath, + newChildPath.split("/").pop() || "", + ) || child + ); + }); + } + return renamedNode; + } + + if (node.children) { + return { + ...node, + children: node.children.map( + (child) => renameNode(child, oldPath, newName) || child, + ), + }; + } + return node; +}; + +export const filterTree = (node: FileNode, query: string): FileNode | null => { + if (!query) return node; + const lowerQuery = query.toLowerCase(); + + if (node.type === "file") { + if (node.name.toLowerCase().includes(lowerQuery)) return node; + return null; + } + + if (node.children) { + const filteredChildren = node.children + .map((child) => filterTree(child, query)) + .filter((child): child is FileNode => child !== null); + + if (filteredChildren.length > 0) { + return { ...node, children: filteredChildren }; + } + } + + if (node.name.toLowerCase().includes(lowerQuery)) return node; + return null; +}; + +export const collectPathsToExpand = ( + node: FileNode, + query: string, +): Set => { + const paths = new Set(); + if (!query) return paths; + + const lowerQuery = query.toLowerCase(); + + const search = (n: FileNode, currentPath: string) => { + if (n.name.toLowerCase().includes(lowerQuery)) { + const pathParts = currentPath.split("/"); + for (let i = 1; i < pathParts.length; i++) { + paths.add(pathParts.slice(0, i).join("/")); + } + } + if (n.children) { + n.children.forEach((child) => { + const childPath = child.path || `${currentPath}/${child.name}`; + search(child, childPath); + }); + } + }; + + search(node, node.path || node.name); + return paths; +}; + +export const getLanguage = (path: string) => { + const ext = path.split(".").pop(); + const map: Record = { + py: "python", + js: "javascript", + ts: "typescript", + jsx: "javascript", + tsx: "typescript", + json: "json", + md: "markdown", + css: "css", + html: "html", + }; + return map[ext || ""] || "plaintext"; +}; diff --git a/frontend/src/modules/ide/index.ts b/frontend/src/modules/ide/index.ts new file mode 100644 index 0000000..caeba36 --- /dev/null +++ b/frontend/src/modules/ide/index.ts @@ -0,0 +1,3 @@ +export { IDE } from "./IDE"; +export { useIDEStore, initialFiles } from "./store/useIDEStore"; +export type { FileNode } from "./types"; diff --git a/frontend/src/modules/ide/store/useIDEStore.ts b/frontend/src/modules/ide/store/useIDEStore.ts new file mode 100644 index 0000000..39fe5b9 --- /dev/null +++ b/frontend/src/modules/ide/store/useIDEStore.ts @@ -0,0 +1,385 @@ +import { create } from "zustand"; +import type { FileNode } from "../types"; +import { + addPaths, + getAllFolderPaths, + findNode, + deleteNode, + addNode, + renameNode, +} from "../helpers/fileTree"; + +export const initialFiles: FileNode = { + name: "my-project", + type: "folder", + children: [ + { + name: "src", + type: "folder", + children: [ + { + name: "main.py", + type: "file", + content: + 'print("Hello, World!")\n\ndef main():\n print("Welcome!")\n\nif __name__ == "__main__":\n main()', + }, + { + name: "utils.py", + type: "file", + content: "def helper():\n return 42", + }, + ], + }, + { + name: "README.md", + type: "file", + content: "# My Project\n\nWelcome!", + }, + ], +}; + +interface IDEState { + // Файловая система + files: FileNode | null; + openFiles: FileNode[]; + activeFile: FileNode | null; + expandedFolders: Set; + searchQuery: string; + showSearch: boolean; + isInitialized: boolean; + + // Диалоги и контекстные меню + contextMenu: { x: number; y: number; node: FileNode | null } | null; + dialog: { + type: "newFile" | "newFolder" | "rename"; + node: FileNode | null; + } | null; + tabContextMenu: { x: number; y: number; file: FileNode } | null; + + // Действия с файлами + selectFile: (node: FileNode) => void; + updateFileContent: (content: string) => void; + closeFile: (file: FileNode) => void; + closeAllFiles: () => void; + closeOtherFiles: (file: FileNode) => void; + + // Действия с деревом + refreshFiles: (newFiles: FileNode | null, newFile?: FileNode) => void; + toggleFolder: (path: string) => void; + expandAllFolders: () => void; + collapseAllFolders: () => void; + autoExpandPaths: (paths: Set) => void; + deleteRoot: () => void; + createNewProject: () => void; + + // Поиск + setSearchQuery: (query: string) => void; + toggleSearch: () => void; + + // Контекстные меню и диалоги + setContextMenu: ( + menu: { x: number; y: number; node: FileNode | null } | null, + ) => void; + setDialog: ( + dialog: { + type: "newFile" | "newFolder" | "rename"; + node: FileNode | null; + } | null, + ) => void; + setTabContextMenu: ( + menu: { x: number; y: number; file: FileNode } | null, + ) => void; + + // Инициализация + initialize: (initialFiles: FileNode) => void; + + // Диалог подтверждения + handleDialogConfirm: (value: string) => void; + handleDeleteNode: (node: FileNode) => void; +} + +export const useIDEStore = create((set, get) => ({ + // Начальное состояние + files: null, + openFiles: [], + activeFile: null, + expandedFolders: new Set(), + searchQuery: "", + showSearch: false, + isInitialized: false, + + contextMenu: null, + dialog: null, + tabContextMenu: null, + + // Инициализация + initialize: (initialFiles: FileNode) => { + const filesWithPaths = addPaths(initialFiles); + set({ + files: filesWithPaths, + expandedFolders: new Set([filesWithPaths.path || filesWithPaths.name]), + isInitialized: true, + }); + }, + + // Выбор файла + selectFile: (node: FileNode) => { + if (node.type === "file") { + const { openFiles } = get(); + if (!openFiles.find((f) => f.path === node.path)) { + set((state) => ({ openFiles: [...state.openFiles, node] })); + } + set({ activeFile: node }); + } + }, + + // Обновление содержимого файла + updateFileContent: (content: string) => { + const { activeFile } = get(); + if (activeFile) { + const updatedFile = { ...activeFile, content }; + set({ activeFile: updatedFile }); + set((state) => ({ + openFiles: state.openFiles.map((f) => + f.path === activeFile.path ? updatedFile : f, + ), + })); + } + }, + + // Закрытие файла + closeFile: (file: FileNode) => { + const { openFiles, activeFile } = get(); + const newOpenFiles = openFiles.filter((f) => f.path !== file.path); + set({ openFiles: newOpenFiles }); + + if (activeFile?.path === file.path) { + set({ activeFile: newOpenFiles[newOpenFiles.length - 1] || null }); + } + }, + + // Закрыть все файлы + closeAllFiles: () => { + set({ openFiles: [], activeFile: null }); + }, + + // Закрыть другие файлы + closeOtherFiles: (file: FileNode) => { + set({ openFiles: [file], activeFile: file }); + }, + + // Обновить файловую систему + refreshFiles: (newFiles: FileNode | null, newFile?: FileNode) => { + const { openFiles, activeFile, selectFile } = get(); + + set({ files: newFiles }); + + if (!newFiles) { + set({ openFiles: [], activeFile: null }); + return; + } + + const updatedOpenFiles = openFiles + .map((f) => { + const found = findNode(newFiles, f.path || ""); + return found && found.type === "file" ? found : null; + }) + .filter((f): f is FileNode => f !== null); + + set({ openFiles: updatedOpenFiles }); + + if (newFile) { + selectFile(newFile); + } else if (activeFile) { + const stillExists = findNode(newFiles, activeFile.path || ""); + if (!stillExists) { + set({ + activeFile: updatedOpenFiles[updatedOpenFiles.length - 1] || null, + }); + } else if (stillExists.type === "file") { + set({ activeFile: stillExists }); + } + } + }, + + // Переключить папку + toggleFolder: (path: string) => { + set((state) => { + const newSet = new Set(state.expandedFolders); + if (newSet.has(path)) { + newSet.delete(path); + } else { + newSet.add(path); + } + return { expandedFolders: newSet }; + }); + }, + + // Раскрыть все папки + expandAllFolders: () => { + const { files } = get(); + if (files) { + set({ expandedFolders: new Set(getAllFolderPaths(files)) }); + } + }, + + // Свернуть все папки + collapseAllFolders: () => { + set({ expandedFolders: new Set() }); + }, + + // Автоматически раскрыть пути + autoExpandPaths: (paths: Set) => { + set((state) => ({ + expandedFolders: new Set([...state.expandedFolders, ...paths]), + })); + }, + + // Удалить корень + deleteRoot: () => { + set({ + files: null, + openFiles: [], + activeFile: null, + expandedFolders: new Set(), + }); + }, + + // Создать новый проект + createNewProject: () => { + const newProject = addPaths(initialFiles); + set({ + files: newProject, + expandedFolders: new Set([newProject.path || newProject.name]), + searchQuery: "", + }); + }, + + // Поиск + setSearchQuery: (query: string) => { + set({ searchQuery: query }); + }, + + toggleSearch: () => { + set((state) => ({ showSearch: !state.showSearch })); + }, + + // Контекстные меню и диалоги + setContextMenu: (menu) => set({ contextMenu: menu }), + setDialog: (dialog) => set({ dialog: dialog }), + setTabContextMenu: (menu) => set({ tabContextMenu: menu }), + + // Подтверждение диалога + handleDialogConfirm: (value: string) => { + const { dialog, files, refreshFiles, toggleFolder, autoExpandPaths } = + get(); + if (!dialog) return; + + if (dialog.type === "rename" && dialog.node) { + const parentPath = + dialog.node.path?.split("/").slice(0, -1).join("/") || ""; + const parentNode = parentPath ? findNode(files!, parentPath) : files; + if ( + parentNode?.children?.some( + (c) => + c.name.toLowerCase() === value.toLowerCase() && + c.path !== dialog.node?.path, + ) + ) { + alert(`"${value}" already exists.`); + return; + } + const newFiles = renameNode( + files!, + dialog.node.path || dialog.node.name, + value, + ); + if (newFiles) { + refreshFiles(newFiles); + } + set({ dialog: null }); + return; + } + + let parentPath: string; + + if (!dialog.node) { + parentPath = files!.path || files!.name; + } else if (dialog.node.type === "folder") { + parentPath = dialog.node.path || dialog.node.name; + } else { + const pathParts = (dialog.node.path || dialog.node.name).split("/"); + pathParts.pop(); + parentPath = pathParts.join("/") || files!.path || files!.name; + } + + const parentNode = findNode(files!, parentPath); + if ( + parentNode?.children?.some( + (c) => c.name.toLowerCase() === value.toLowerCase(), + ) + ) { + alert(`"${value}" already exists in this folder.`); + set({ dialog: null }); + return; + } + + let newFiles: FileNode | null = null; + let createdNode: FileNode | null = null; + + if (dialog.type === "newFile") { + createdNode = { name: value, type: "file", content: "" }; + newFiles = addNode(files!, parentPath, createdNode); + } else if (dialog.type === "newFolder") { + createdNode = { name: value, type: "folder", children: [] }; + newFiles = addNode(files!, parentPath, createdNode); + } + + if (newFiles) { + const allParentPaths: string[] = []; + let current = parentPath; + while (current) { + allParentPaths.push(current); + const parts = current.split("/"); + parts.pop(); + current = parts.join("/"); + } + allParentPaths.forEach((p) => { + if (!get().expandedFolders.has(p)) { + toggleFolder(p); + } + }); + autoExpandPaths(new Set(allParentPaths)); + + if (createdNode && createdNode.type === "file") { + const findAndOpen = (node: FileNode, name: string): FileNode | null => { + if (node.name === name && node.type === "file") return node; + if (node.children) { + for (const child of node.children) { + const found = findAndOpen(child, name); + if (found) return found; + } + } + return null; + }; + const openedFile = findAndOpen(newFiles, value); + refreshFiles(newFiles, openedFile || undefined); + } else { + refreshFiles(newFiles); + } + } + set({ dialog: null }); + }, + + // Удаление узла + handleDeleteNode: (node: FileNode) => { + const { files, refreshFiles } = get(); + const isRootNode = node.path === files?.path; + if (isRootNode) { + get().deleteRoot(); + } else if (window.confirm(`Delete "${node.name}"?`)) { + const newFiles = deleteNode(files!, node.path || node.name); + if (newFiles) refreshFiles(newFiles); + } + }, +})); diff --git a/frontend/src/modules/ide/types.ts b/frontend/src/modules/ide/types.ts new file mode 100644 index 0000000..1744b5e --- /dev/null +++ b/frontend/src/modules/ide/types.ts @@ -0,0 +1,24 @@ +export interface FileNode { + name: string; + type: "file" | "folder"; + content?: string; + children?: FileNode[]; + path?: string; +} + +export interface ContextMenuState { + x: number; + y: number; + node: FileNode | null; +} + +export interface DialogState { + type: "newFile" | "newFolder" | "rename"; + node: FileNode | null; +} + +export interface TabContextMenuState { + x: number; + y: number; + file: FileNode; +} diff --git a/frontend/src/pages/ide.page.tsx b/frontend/src/pages/ide.page.tsx new file mode 100644 index 0000000..218d1ef --- /dev/null +++ b/frontend/src/pages/ide.page.tsx @@ -0,0 +1,9 @@ +import { IDE } from "../modules/ide"; + +export const IDEPage = () => { + return ( +
+ +
+ ); +}; diff --git a/frontend/yarn.lock b/frontend/yarn.lock index 225e87c..24295b2 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -256,6 +256,332 @@ style-mod "^4.1.0" w3c-keyname "^2.2.4" +<<<<<<< Updated upstream +======= +"@codingame/monaco-vscode-api@^25.1.2", "@codingame/monaco-vscode-api@25.1.2": + version "25.1.2" + resolved "https://registry.npmjs.org/@codingame/monaco-vscode-api/-/monaco-vscode-api-25.1.2.tgz" + integrity sha512-K04QcQA+Zb0KXucBAK/BGCT5dldiwIqdUbBQq7yuLvBLbof3cP1WSUuxasMHGYwM0MWyzIAsDtyAYMS7is8ZuA== + dependencies: + "@codingame/monaco-vscode-base-service-override" "25.1.2" + "@codingame/monaco-vscode-environment-service-override" "25.1.2" + "@codingame/monaco-vscode-extensions-service-override" "25.1.2" + "@codingame/monaco-vscode-files-service-override" "25.1.2" + "@codingame/monaco-vscode-host-service-override" "25.1.2" + "@codingame/monaco-vscode-layout-service-override" "25.1.2" + "@codingame/monaco-vscode-quickaccess-service-override" "25.1.2" + "@vscode/iconv-lite-umd" "0.7.1" + dompurify "3.3.1" + jschardet "3.1.4" + marked "14.0.0" + +"@codingame/monaco-vscode-base-service-override@25.1.2": + version "25.1.2" + resolved "https://registry.npmjs.org/@codingame/monaco-vscode-base-service-override/-/monaco-vscode-base-service-override-25.1.2.tgz" + integrity sha512-OwYs6h1ATUAeMmX+Q1c8esTG7GLMqniBs+fLEr1/9b/ciY485ArKo5UvrUxVPDtRNy/7F06vRW9IUCq9iKP14w== + dependencies: + "@codingame/monaco-vscode-api" "25.1.2" + +"@codingame/monaco-vscode-bulk-edit-service-override@25.1.2": + version "25.1.2" + resolved "https://registry.npmjs.org/@codingame/monaco-vscode-bulk-edit-service-override/-/monaco-vscode-bulk-edit-service-override-25.1.2.tgz" + integrity sha512-+EfSzjiFakCf0IIJKPZrHVGioq5N8GBsp51bXuKBR5J/B58cUaJY0Dc12PNTSpgAusAGOppUIOSBqUk4F/7IaQ== + dependencies: + "@codingame/monaco-vscode-api" "25.1.2" + +"@codingame/monaco-vscode-configuration-service-override@^25.1.2": + version "25.1.2" + resolved "https://registry.npmjs.org/@codingame/monaco-vscode-configuration-service-override/-/monaco-vscode-configuration-service-override-25.1.2.tgz" + integrity sha512-oeoZ3WtM42zHA1IWHrx9UGEfE+TixE+G8Bl9M9bjgFj1EROnkB5yOfELwRYPo4WOEtcK1C5nvIvWIj/hL9MaLg== + dependencies: + "@codingame/monaco-vscode-api" "25.1.2" + "@codingame/monaco-vscode-files-service-override" "25.1.2" + +"@codingame/monaco-vscode-editor-api@^25.1.2": + version "25.1.2" + resolved "https://registry.npmjs.org/@codingame/monaco-vscode-editor-api/-/monaco-vscode-editor-api-25.1.2.tgz" + integrity sha512-dVXoBLRN8vyFHsLY6iYISaNetZ3ispXLut0qL+jvN0e0CEFkUv1F/3EAE7myptrJSS/N1AptrRIxATT3lwFP+Q== + dependencies: + "@codingame/monaco-vscode-api" "25.1.2" + +"@codingame/monaco-vscode-editor-service-override@^25.1.2": + version "25.1.2" + resolved "https://registry.npmjs.org/@codingame/monaco-vscode-editor-service-override/-/monaco-vscode-editor-service-override-25.1.2.tgz" + integrity sha512-EadvDCyWdgxOPmaIvbcVVDNjTUYuKdjYWwKbPbbcTs9t4z1/DjdE7mV3ZdT6aGh5m6zkEEUOi143l27Y5eRt+Q== + dependencies: + "@codingame/monaco-vscode-api" "25.1.2" + +"@codingame/monaco-vscode-environment-service-override@25.1.2": + version "25.1.2" + resolved "https://registry.npmjs.org/@codingame/monaco-vscode-environment-service-override/-/monaco-vscode-environment-service-override-25.1.2.tgz" + integrity sha512-8GoD3lk0CN0dIMZOrZNS/i8RCaF1YSQ6nmrf+rqneOSHG9S382EnsZZD69d4+i7JnoeyttO7Kr9KH8WOhRV6OA== + dependencies: + "@codingame/monaco-vscode-api" "25.1.2" + +"@codingame/monaco-vscode-extension-api@^25.1.2": + version "25.1.2" + resolved "https://registry.npmjs.org/@codingame/monaco-vscode-extension-api/-/monaco-vscode-extension-api-25.1.2.tgz" + integrity sha512-SJW/YOhjo+9MXEyzMwQMUWdJVR3Llc6pTq5JQqs6Y30v73gTrpLqtzbd9FNdCuQR8S6bUk5ScH8GL4QrVuL5FA== + dependencies: + "@codingame/monaco-vscode-api" "25.1.2" + "@codingame/monaco-vscode-extensions-service-override" "25.1.2" + +"@codingame/monaco-vscode-extensions-service-override@^25.1.2", "@codingame/monaco-vscode-extensions-service-override@25.1.2": + version "25.1.2" + resolved "https://registry.npmjs.org/@codingame/monaco-vscode-extensions-service-override/-/monaco-vscode-extensions-service-override-25.1.2.tgz" + integrity sha512-rTTZW2biPxcg+JumhVf2L+38C5ptvNNxiJlwz39VfXFEh6qOHtAsIMy7vIXa0uGg5/y8DNp0SnOQJP/RKhLYZA== + dependencies: + "@codingame/monaco-vscode-api" "25.1.2" + "@codingame/monaco-vscode-files-service-override" "25.1.2" + +"@codingame/monaco-vscode-files-service-override@25.1.2": + version "25.1.2" + resolved "https://registry.npmjs.org/@codingame/monaco-vscode-files-service-override/-/monaco-vscode-files-service-override-25.1.2.tgz" + integrity sha512-TenLLAFIwY7keZFF8e3beUn7OVfnNINR5Noi4PVrjeeTcy6FuNH6Jghdul2JwpRAkvyJLdFMvomE2jlT6F03jQ== + dependencies: + "@codingame/monaco-vscode-api" "25.1.2" + +"@codingame/monaco-vscode-host-service-override@25.1.2": + version "25.1.2" + resolved "https://registry.npmjs.org/@codingame/monaco-vscode-host-service-override/-/monaco-vscode-host-service-override-25.1.2.tgz" + integrity sha512-lgaalpA9CUQW7i0bBwgBOK0DQNDvOo3QO3p6Rz6yVsHpgA4iMqq2d11dBDUKvuQSwIHPRu8CMHCqhQk/BQN/YA== + dependencies: + "@codingame/monaco-vscode-api" "25.1.2" + +"@codingame/monaco-vscode-keybindings-service-override@25.1.2": + version "25.1.2" + resolved "https://registry.npmjs.org/@codingame/monaco-vscode-keybindings-service-override/-/monaco-vscode-keybindings-service-override-25.1.2.tgz" + integrity sha512-cp/gGyTvCTAzCYnQm0HJykXJRB0Huz8Lvq60lj5LutgWcb8S3w6dOB2Houm8dHoeUm/jOko8SQNIP8hzWN92Zw== + dependencies: + "@codingame/monaco-vscode-api" "25.1.2" + "@codingame/monaco-vscode-files-service-override" "25.1.2" + +"@codingame/monaco-vscode-language-pack-cs@^25.1.2": + version "25.1.2" + resolved "https://registry.npmjs.org/@codingame/monaco-vscode-language-pack-cs/-/monaco-vscode-language-pack-cs-25.1.2.tgz" + integrity sha512-v0cB2uAOCwj135aGIf0arGV+DNW32lbWh04bv8ctTxcWRt1Pr2kTQ1pjfE8ynKgxabPfAk8E25/CerKSYOmZ+A== + dependencies: + "@codingame/monaco-vscode-api" "25.1.2" + +"@codingame/monaco-vscode-language-pack-de@^25.1.2": + version "25.1.2" + resolved "https://registry.npmjs.org/@codingame/monaco-vscode-language-pack-de/-/monaco-vscode-language-pack-de-25.1.2.tgz" + integrity sha512-xA3WOt1w5jlAOnyx4PBwx+qV3vx8C8/zie29qjYbgJMxGKDkb0HfpuKUwywDA2uUMI2wJZS+PnNG00zPDoLIrw== + dependencies: + "@codingame/monaco-vscode-api" "25.1.2" + +"@codingame/monaco-vscode-language-pack-es@^25.1.2": + version "25.1.2" + resolved "https://registry.npmjs.org/@codingame/monaco-vscode-language-pack-es/-/monaco-vscode-language-pack-es-25.1.2.tgz" + integrity sha512-1/upuO9lRJilZ3sRr0QLTpz55KYRaBWDe8wtPvghOFYOHyWgW8A4VhUQxa6L9SJgY1JkypUAm0U8WcMX2G4LnQ== + dependencies: + "@codingame/monaco-vscode-api" "25.1.2" + +"@codingame/monaco-vscode-language-pack-fr@^25.1.2": + version "25.1.2" + resolved "https://registry.npmjs.org/@codingame/monaco-vscode-language-pack-fr/-/monaco-vscode-language-pack-fr-25.1.2.tgz" + integrity sha512-iq+xx+tv1QIMmFD0eBhFRMF4xMAsVf/HyA1WogqBofteCWeAvRE9HUjZ5JzHz7jXBPe3dLP1LOM0r0GrJZs4fQ== + dependencies: + "@codingame/monaco-vscode-api" "25.1.2" + +"@codingame/monaco-vscode-language-pack-it@^25.1.2": + version "25.1.2" + resolved "https://registry.npmjs.org/@codingame/monaco-vscode-language-pack-it/-/monaco-vscode-language-pack-it-25.1.2.tgz" + integrity sha512-FajWCML9OR8ppLnJ0mcg+sFHEhYJl8zhb3/DHnd+pNysw8dLfetXoSWjaPnwPPpwiQgkNN1UsToZHOU9czVifQ== + dependencies: + "@codingame/monaco-vscode-api" "25.1.2" + +"@codingame/monaco-vscode-language-pack-ja@^25.1.2": + version "25.1.2" + resolved "https://registry.npmjs.org/@codingame/monaco-vscode-language-pack-ja/-/monaco-vscode-language-pack-ja-25.1.2.tgz" + integrity sha512-NwKh0BnPgUrJkxsm0X6vY4ftnd9DjxkcnQqK+bohta6UOzm09J1EjZ6QD42fjWngxrp/xiegtrYQ9NA2q6VpoA== + dependencies: + "@codingame/monaco-vscode-api" "25.1.2" + +"@codingame/monaco-vscode-language-pack-ko@^25.1.2": + version "25.1.2" + resolved "https://registry.npmjs.org/@codingame/monaco-vscode-language-pack-ko/-/monaco-vscode-language-pack-ko-25.1.2.tgz" + integrity sha512-fvaisgfcg8YaAwnyPcGmQDLwkwqzamLQUyx9HmnwDpXw0YANzd058Kwn6bz+Vfn9MjwuMNT0nllD0qQMnpdyew== + dependencies: + "@codingame/monaco-vscode-api" "25.1.2" + +"@codingame/monaco-vscode-language-pack-pl@^25.1.2": + version "25.1.2" + resolved "https://registry.npmjs.org/@codingame/monaco-vscode-language-pack-pl/-/monaco-vscode-language-pack-pl-25.1.2.tgz" + integrity sha512-9hDRyzFJkDia5rO9QE262JgxwP/cnalFisLFo7FQcw57ZhqzqXIdQIuwcKaHuAgzeQ6W2+A3KOLfTr3m7VZrXw== + dependencies: + "@codingame/monaco-vscode-api" "25.1.2" + +"@codingame/monaco-vscode-language-pack-pt-br@^25.1.2": + version "25.1.2" + resolved "https://registry.npmjs.org/@codingame/monaco-vscode-language-pack-pt-br/-/monaco-vscode-language-pack-pt-br-25.1.2.tgz" + integrity sha512-7fFnqOTAJGb5RuJ4uwh9sh0JmXALuHPGOl7iL9rZkcgIuVP5y6wVDUDXq5qjiRTNSFDs7Bzh463Ir5m5D6mJbA== + dependencies: + "@codingame/monaco-vscode-api" "25.1.2" + +"@codingame/monaco-vscode-language-pack-qps-ploc@^25.1.2": + version "25.1.2" + resolved "https://registry.npmjs.org/@codingame/monaco-vscode-language-pack-qps-ploc/-/monaco-vscode-language-pack-qps-ploc-25.1.2.tgz" + integrity sha512-IFjoqrSuPtIFWb+KlPT6PFWKszzNX+TCD9drgCV6AigvBO/xfGL3QwHB68l/DLbmDbohOz4Xdkutv20wuENAeA== + dependencies: + "@codingame/monaco-vscode-api" "25.1.2" + +"@codingame/monaco-vscode-language-pack-ru@^25.1.2": + version "25.1.2" + resolved "https://registry.npmjs.org/@codingame/monaco-vscode-language-pack-ru/-/monaco-vscode-language-pack-ru-25.1.2.tgz" + integrity sha512-0uDAeXO+GllKUPhJzP893rlDhlFV1IwCu/515rBdcyegt48iGm/xAgj26V90hNz8hmB6EuM/7d8MFeklbiIpYA== + dependencies: + "@codingame/monaco-vscode-api" "25.1.2" + +"@codingame/monaco-vscode-language-pack-tr@^25.1.2": + version "25.1.2" + resolved "https://registry.npmjs.org/@codingame/monaco-vscode-language-pack-tr/-/monaco-vscode-language-pack-tr-25.1.2.tgz" + integrity sha512-MJhHxDyJEiuVLQ9+jb8MnnN9lsbJOjJjMswVCeJ7v/Q/msAhq25QYUfn0DbOIzESJE1f7crffRb5e38XP8sYWA== + dependencies: + "@codingame/monaco-vscode-api" "25.1.2" + +"@codingame/monaco-vscode-language-pack-zh-hans@^25.1.2": + version "25.1.2" + resolved "https://registry.npmjs.org/@codingame/monaco-vscode-language-pack-zh-hans/-/monaco-vscode-language-pack-zh-hans-25.1.2.tgz" + integrity sha512-c7MMrhnSLb59NxpAa8nVy9aIbxy4gVYrCpDMq8W380LOaXTYb7nueTrw8QJ5QbJBNi2P2KZoGkn2BlONuBtJJg== + dependencies: + "@codingame/monaco-vscode-api" "25.1.2" + +"@codingame/monaco-vscode-language-pack-zh-hant@^25.1.2": + version "25.1.2" + resolved "https://registry.npmjs.org/@codingame/monaco-vscode-language-pack-zh-hant/-/monaco-vscode-language-pack-zh-hant-25.1.2.tgz" + integrity sha512-ARedFTM6JCluoPLJqkBcTJaQFdJNcN86OX6B8/NMApIPrnSIAfanMndpyilt8XjzUG6IH22cypR+DAlEjf48cA== + dependencies: + "@codingame/monaco-vscode-api" "25.1.2" + +"@codingame/monaco-vscode-languages-service-override@^25.1.2": + version "25.1.2" + resolved "https://registry.npmjs.org/@codingame/monaco-vscode-languages-service-override/-/monaco-vscode-languages-service-override-25.1.2.tgz" + integrity sha512-ipuS1V3NgXDkNrj0vBcgMBFnqo+19HVsZjjFGfPFH3x0uptP9aiWWK42wtDK3Qbu4teSjHL7WnSLrmw94rplWw== + dependencies: + "@codingame/monaco-vscode-api" "25.1.2" + "@codingame/monaco-vscode-files-service-override" "25.1.2" + +"@codingame/monaco-vscode-layout-service-override@25.1.2": + version "25.1.2" + resolved "https://registry.npmjs.org/@codingame/monaco-vscode-layout-service-override/-/monaco-vscode-layout-service-override-25.1.2.tgz" + integrity sha512-SxBGcMK3RgkGtUn7ZDl7dCoyNW0CWFQ/bfSRYUY06A0IA4JNS5jq1lhof57d0WXewm+5l8w1Spr/vMsfx1c9ig== + dependencies: + "@codingame/monaco-vscode-api" "25.1.2" + +"@codingame/monaco-vscode-localization-service-override@^25.1.2": + version "25.1.2" + resolved "https://registry.npmjs.org/@codingame/monaco-vscode-localization-service-override/-/monaco-vscode-localization-service-override-25.1.2.tgz" + integrity sha512-QLj62A8XDOIQW3KjsZlNxs+sfsNNHYxWMjQMwZu/y2Vw3IIHGly2Lpn4t4SFbeaBHJQJy4i5s7NpzlbF9MbEzQ== + dependencies: + "@codingame/monaco-vscode-api" "25.1.2" + +"@codingame/monaco-vscode-log-service-override@^25.1.2": + version "25.1.2" + resolved "https://registry.npmjs.org/@codingame/monaco-vscode-log-service-override/-/monaco-vscode-log-service-override-25.1.2.tgz" + integrity sha512-OoileAUtPAJ0j3RW31DFSxtOipy0EcFq+iIXEdGvoRlsQPZJ3o9ayjf1JvCXpxUjJ3QkmvQVhXsWNUFREjEFLg== + dependencies: + "@codingame/monaco-vscode-api" "25.1.2" + "@codingame/monaco-vscode-environment-service-override" "25.1.2" + +"@codingame/monaco-vscode-model-service-override@^25.1.2": + version "25.1.2" + resolved "https://registry.npmjs.org/@codingame/monaco-vscode-model-service-override/-/monaco-vscode-model-service-override-25.1.2.tgz" + integrity sha512-MGz/eV1CxibLvnl6WzK6idUHJCXJOVepJvKM6Trkv5050vRe+f/o1TjCiG8PaznAypYqZvnwkTG0B7/OTizCpQ== + dependencies: + "@codingame/monaco-vscode-api" "25.1.2" + +"@codingame/monaco-vscode-monarch-service-override@^25.1.2": + version "25.1.2" + resolved "https://registry.npmjs.org/@codingame/monaco-vscode-monarch-service-override/-/monaco-vscode-monarch-service-override-25.1.2.tgz" + integrity sha512-akyNHOJQRS7YHyk6kf0Encnkt+shlR+bIB84UJRUHFgSeF8s5gkDkQuFJph0YeUDWJWat+yBLUSZx2nHomdbHQ== + dependencies: + "@codingame/monaco-vscode-api" "25.1.2" + +"@codingame/monaco-vscode-quickaccess-service-override@25.1.2": + version "25.1.2" + resolved "https://registry.npmjs.org/@codingame/monaco-vscode-quickaccess-service-override/-/monaco-vscode-quickaccess-service-override-25.1.2.tgz" + integrity sha512-7IIrXnwHiF3w9d9p9kspEUz/LCibMLUztmRpGdZQfFtWBJw043q7rk8V1O42KdXr1hVg9IR5vfffwjy9nbiiUg== + dependencies: + "@codingame/monaco-vscode-api" "25.1.2" + +"@codingame/monaco-vscode-textmate-service-override@^25.1.2": + version "25.1.2" + resolved "https://registry.npmjs.org/@codingame/monaco-vscode-textmate-service-override/-/monaco-vscode-textmate-service-override-25.1.2.tgz" + integrity sha512-AL0FtSQBW+1vtoXYQvUqB2hfWojpK73Kq/n6KuNXxjLF/XBJ5FpeeZDfrBfwhWPPoHuBTsaFUCQy4L8xQgbVlA== + dependencies: + "@codingame/monaco-vscode-api" "25.1.2" + "@codingame/monaco-vscode-files-service-override" "25.1.2" + +"@codingame/monaco-vscode-theme-defaults-default-extension@^25.1.2": + version "25.1.2" + resolved "https://registry.npmjs.org/@codingame/monaco-vscode-theme-defaults-default-extension/-/monaco-vscode-theme-defaults-default-extension-25.1.2.tgz" + integrity sha512-0vTMFiC89YSDSmjFckuQBUKwRuFNtsILNO3k0PBiSLN/MW+VDItjJpiVLXC42+rUWlGgY2lYxOneGVa5slCV1w== + dependencies: + "@codingame/monaco-vscode-api" "25.1.2" + +"@codingame/monaco-vscode-theme-service-override@^25.1.2": + version "25.1.2" + resolved "https://registry.npmjs.org/@codingame/monaco-vscode-theme-service-override/-/monaco-vscode-theme-service-override-25.1.2.tgz" + integrity sha512-hsTwl6YYTiheFuQMmCmiEGLIdIdgYaf8Z85XWyxe6YgPtDaYGnp0fGSOXKA9/bf0JtuynzoLKtUUfDupK/A7Tw== + dependencies: + "@codingame/monaco-vscode-api" "25.1.2" + "@codingame/monaco-vscode-files-service-override" "25.1.2" + +"@codingame/monaco-vscode-view-banner-service-override@25.1.2": + version "25.1.2" + resolved "https://registry.npmjs.org/@codingame/monaco-vscode-view-banner-service-override/-/monaco-vscode-view-banner-service-override-25.1.2.tgz" + integrity sha512-zhujHd1PQ6rRXsC2OQGrx/282G2v3lpPFl9heDFGKzpdj5119SgcW+B9p/MwJ1qF3LJpuRRgefNiQtqC/KT1eA== + dependencies: + "@codingame/monaco-vscode-api" "25.1.2" + +"@codingame/monaco-vscode-view-common-service-override@25.1.2": + version "25.1.2" + resolved "https://registry.npmjs.org/@codingame/monaco-vscode-view-common-service-override/-/monaco-vscode-view-common-service-override-25.1.2.tgz" + integrity sha512-4Po/YaHUvVf4VmhVCZmM2lc/flOptiWSM140bIRNpMcfH0VwihYg15CcDeu1Oc+6DaauzsG3u59GtEvlMmJ9Zw== + dependencies: + "@codingame/monaco-vscode-api" "25.1.2" + "@codingame/monaco-vscode-bulk-edit-service-override" "25.1.2" + +"@codingame/monaco-vscode-view-status-bar-service-override@25.1.2": + version "25.1.2" + resolved "https://registry.npmjs.org/@codingame/monaco-vscode-view-status-bar-service-override/-/monaco-vscode-view-status-bar-service-override-25.1.2.tgz" + integrity sha512-Jp9ytLaWZ6evabTPtG3Mu3dFx+7WTIPz69BsGpl9PnU0kiSWUqQhPSob0Jz7E2qmMj0ZcNv2Wqvm6bMBu5OyrA== + dependencies: + "@codingame/monaco-vscode-api" "25.1.2" + +"@codingame/monaco-vscode-view-title-bar-service-override@25.1.2": + version "25.1.2" + resolved "https://registry.npmjs.org/@codingame/monaco-vscode-view-title-bar-service-override/-/monaco-vscode-view-title-bar-service-override-25.1.2.tgz" + integrity sha512-NVYtTAFR35NV/Fx7tSlbASicvpAjK5A14fmxF7/LJJN8ZmzhA/P3Y+UzhqOQl6/VcPV4pAMU0Z7Sicgwbn37dw== + dependencies: + "@codingame/monaco-vscode-api" "25.1.2" + +"@codingame/monaco-vscode-views-service-override@^25.1.2": + version "25.1.2" + resolved "https://registry.npmjs.org/@codingame/monaco-vscode-views-service-override/-/monaco-vscode-views-service-override-25.1.2.tgz" + integrity sha512-LfzlztsvobdP5L5EvJ/rqSEgy5fEVmrkMqRteuhEtNGd4hnmdBoX8W7BNMBPff6d4NfCK74pGHJF57RyT4Iixg== + dependencies: + "@codingame/monaco-vscode-api" "25.1.2" + "@codingame/monaco-vscode-keybindings-service-override" "25.1.2" + "@codingame/monaco-vscode-layout-service-override" "25.1.2" + "@codingame/monaco-vscode-quickaccess-service-override" "25.1.2" + "@codingame/monaco-vscode-view-common-service-override" "25.1.2" + +"@codingame/monaco-vscode-workbench-service-override@^25.1.2": + version "25.1.2" + resolved "https://registry.npmjs.org/@codingame/monaco-vscode-workbench-service-override/-/monaco-vscode-workbench-service-override-25.1.2.tgz" + integrity sha512-2LMHr+na03FhOAaXpIGmamq9hf7e4wt2kULn8NqNZRd3i+0v1tx/TSSjGhsA5EkrNrFD7CMSoXayBq8tgpCq/A== + dependencies: + "@codingame/monaco-vscode-api" "25.1.2" + "@codingame/monaco-vscode-keybindings-service-override" "25.1.2" + "@codingame/monaco-vscode-quickaccess-service-override" "25.1.2" + "@codingame/monaco-vscode-view-banner-service-override" "25.1.2" + "@codingame/monaco-vscode-view-common-service-override" "25.1.2" + "@codingame/monaco-vscode-view-status-bar-service-override" "25.1.2" + "@codingame/monaco-vscode-view-title-bar-service-override" "25.1.2" + +>>>>>>> Stashed changes "@eslint-community/eslint-utils@^4.8.0", "@eslint-community/eslint-utils@^4.9.1": version "4.9.1" resolved "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz" @@ -405,11 +731,158 @@ resolved "https://registry.npmjs.org/@marijn/find-cluster-break/-/find-cluster-break-1.0.2.tgz" integrity sha512-l0h88YhZFyKdXIFNfSWpyjStDjGHwZ/U7iobcK1cQQD8sejsONdQtTVU+1wVN1PBw40PiiHB1vA5S7VTfQiP9g== +<<<<<<< Updated upstream +======= +"@monaco-editor/loader@^1.5.0": + version "1.7.0" + resolved "https://registry.npmjs.org/@monaco-editor/loader/-/loader-1.7.0.tgz" + integrity sha512-gIwR1HrJrrx+vfyOhYmCZ0/JcWqG5kbfG7+d3f/C1LXk2EvzAbHSg3MQ5lO2sMlo9izoAZ04shohfKLVT6crVA== + dependencies: + state-local "^1.0.6" + +"@monaco-editor/react@^4.6.0", "@monaco-editor/react@^4.7.0": + version "4.7.0" + resolved "https://registry.npmjs.org/@monaco-editor/react/-/react-4.7.0.tgz" + integrity sha512-cyzXQCtO47ydzxpQtCGSQGOC8Gk3ZUeBXFAxD+CWXYFo5OqZyZUonFl0DwUlTyAfRHntBfw2p3w4s9R6oe1eCA== + dependencies: + "@monaco-editor/loader" "^1.5.0" + +>>>>>>> Stashed changes "@oxc-project/types@=0.122.0": version "0.122.0" resolved "https://registry.npmjs.org/@oxc-project/types/-/types-0.122.0.tgz" integrity sha512-oLAl5kBpV4w69UtFZ9xqcmTi+GENWOcPF7FCrczTiBbmC0ibXxCwyvZGbO39rCVEuLGAZM84DH0pUIyyv/YJzA== +"@radix-ui/primitive@1.1.3": + version "1.1.3" + resolved "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.3.tgz" + integrity sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg== + +"@radix-ui/react-collection@1.1.7": + version "1.1.7" + resolved "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.7.tgz" + integrity sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw== + dependencies: + "@radix-ui/react-compose-refs" "1.1.2" + "@radix-ui/react-context" "1.1.2" + "@radix-ui/react-primitive" "2.1.3" + "@radix-ui/react-slot" "1.2.3" + +"@radix-ui/react-compose-refs@1.1.2": + version "1.1.2" + resolved "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz" + integrity sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg== + +"@radix-ui/react-context@1.1.2": + version "1.1.2" + resolved "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.2.tgz" + integrity sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA== + +"@radix-ui/react-dismissable-layer@1.1.11": + version "1.1.11" + resolved "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.11.tgz" + integrity sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg== + dependencies: + "@radix-ui/primitive" "1.1.3" + "@radix-ui/react-compose-refs" "1.1.2" + "@radix-ui/react-primitive" "2.1.3" + "@radix-ui/react-use-callback-ref" "1.1.1" + "@radix-ui/react-use-escape-keydown" "1.1.1" + +"@radix-ui/react-portal@1.1.9": + version "1.1.9" + resolved "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.9.tgz" + integrity sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ== + dependencies: + "@radix-ui/react-primitive" "2.1.3" + "@radix-ui/react-use-layout-effect" "1.1.1" + +"@radix-ui/react-presence@1.1.5": + version "1.1.5" + resolved "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.5.tgz" + integrity sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ== + dependencies: + "@radix-ui/react-compose-refs" "1.1.2" + "@radix-ui/react-use-layout-effect" "1.1.1" + +"@radix-ui/react-primitive@2.1.3": + version "2.1.3" + resolved "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz" + integrity sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ== + dependencies: + "@radix-ui/react-slot" "1.2.3" + +"@radix-ui/react-slot@^1.1.0": + version "1.2.4" + resolved "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.4.tgz" + integrity sha512-Jl+bCv8HxKnlTLVrcDE8zTMJ09R9/ukw4qBs/oZClOfoQk/cOTbDn+NceXfV7j09YPVQUryJPHurafcSg6EVKA== + dependencies: + "@radix-ui/react-compose-refs" "1.1.2" + +"@radix-ui/react-slot@1.2.3": + version "1.2.3" + resolved "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz" + integrity sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A== + dependencies: + "@radix-ui/react-compose-refs" "1.1.2" + +"@radix-ui/react-toast@^1.2.1": + version "1.2.15" + resolved "https://registry.npmjs.org/@radix-ui/react-toast/-/react-toast-1.2.15.tgz" + integrity sha512-3OSz3TacUWy4WtOXV38DggwxoqJK4+eDkNMl5Z/MJZaoUPaP4/9lf81xXMe1I2ReTAptverZUpbPY4wWwWyL5g== + dependencies: + "@radix-ui/primitive" "1.1.3" + "@radix-ui/react-collection" "1.1.7" + "@radix-ui/react-compose-refs" "1.1.2" + "@radix-ui/react-context" "1.1.2" + "@radix-ui/react-dismissable-layer" "1.1.11" + "@radix-ui/react-portal" "1.1.9" + "@radix-ui/react-presence" "1.1.5" + "@radix-ui/react-primitive" "2.1.3" + "@radix-ui/react-use-callback-ref" "1.1.1" + "@radix-ui/react-use-controllable-state" "1.2.2" + "@radix-ui/react-use-layout-effect" "1.1.1" + "@radix-ui/react-visually-hidden" "1.2.3" + +"@radix-ui/react-use-callback-ref@1.1.1": + version "1.1.1" + resolved "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.1.tgz" + integrity sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg== + +"@radix-ui/react-use-controllable-state@1.2.2": + version "1.2.2" + resolved "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.2.tgz" + integrity sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg== + dependencies: + "@radix-ui/react-use-effect-event" "0.0.2" + "@radix-ui/react-use-layout-effect" "1.1.1" + +"@radix-ui/react-use-effect-event@0.0.2": + version "0.0.2" + resolved "https://registry.npmjs.org/@radix-ui/react-use-effect-event/-/react-use-effect-event-0.0.2.tgz" + integrity sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA== + dependencies: + "@radix-ui/react-use-layout-effect" "1.1.1" + +"@radix-ui/react-use-escape-keydown@1.1.1": + version "1.1.1" + resolved "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.1.tgz" + integrity sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g== + dependencies: + "@radix-ui/react-use-callback-ref" "1.1.1" + +"@radix-ui/react-use-layout-effect@1.1.1": + version "1.1.1" + resolved "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.1.tgz" + integrity sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ== + +"@radix-ui/react-visually-hidden@1.2.3": + version "1.2.3" + resolved "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.2.3.tgz" + integrity sha512-pzJq12tEaaIhqjbzpCuv/OypJY/BPavOofm+dbab+MHLajy277+1lLm6JFcGgF5eskJ6mquGirhXY2GD/8u8Ug== + dependencies: + "@radix-ui/react-primitive" "2.1.3" + "@reduxjs/toolkit@^1.9.0 || 2.x.x": version "2.11.2" resolved "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.11.2.tgz" @@ -492,6 +965,11 @@ "@tailwindcss/oxide" "4.2.2" tailwindcss "4.2.2" +"@tweenjs/tween.js@18 - 25": + version "25.0.0" + resolved "https://registry.npmjs.org/@tweenjs/tween.js/-/tween.js-25.0.0.tgz" + integrity sha512-XKLA6syeBUaPzx4j3qwMqzzq+V4uo72BnlbOjmuljLrRqdsd3qnzvZZoxvMHZ23ndsRS4aufU6JOZYpCbU6T1A== + "@tybys/wasm-util@^0.10.1": version "0.10.1" resolved "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz" @@ -567,7 +1045,7 @@ dependencies: undici-types "~7.16.0" -"@types/react-dom@^19.2.3": +"@types/react-dom@*", "@types/react-dom@^19.2.3": version "19.2.3" resolved "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz" integrity sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ== @@ -584,6 +1062,11 @@ dependencies: csstype "^3.2.2" +"@types/trusted-types@^2.0.7": + version "2.0.7" + resolved "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz" + integrity sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw== + "@types/use-sync-external-store@^0.0.6": version "0.0.6" resolved "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.6.tgz" @@ -717,6 +1200,11 @@ dependencies: "@rolldown/pluginutils" "1.0.0-rc.7" +"@vscode/iconv-lite-umd@0.7.1": + version "0.7.1" + resolved "https://registry.npmjs.org/@vscode/iconv-lite-umd/-/iconv-lite-umd-0.7.1.tgz" + integrity sha512-tK6k0DXFHW7q5+GGuGZO+phpAqpxO4WXl+BLc/8/uOk3RsM2ssAL3CQUQDb1TGfwltjsauhN6S4ghYZzs4sPFw== + accepts@~1.3.5: version "1.3.8" resolved "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz" @@ -725,6 +1213,11 @@ accepts@~1.3.5: mime-types "~2.1.34" negotiator "0.6.3" +accessor-fn@1: + version "1.5.3" + resolved "https://registry.npmjs.org/accessor-fn/-/accessor-fn-1.5.3.tgz" + integrity sha512-rkAofCwe/FvYFUlMB0v0gWmhqtfAtV1IUkdPbfhTUyYniu5LrC0A0UJkTH0Jv3S8SvwkmfuAlY+mQIJATdocMA== + acorn-jsx@^5.3.2: version "5.3.2" resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz" @@ -903,6 +1396,11 @@ basic-auth@~2.0.0: dependencies: safe-buffer "5.1.2" +"bezier-js@3 - 6": + version "6.1.4" + resolved "https://registry.npmjs.org/bezier-js/-/bezier-js-6.1.4.tgz" + integrity sha512-PA0FW9ZpcHbojUCMu28z9Vg/fNkwTj5YhusSAjHHDfHDGLxJ6YUKrAN2vk1fP2MMOxVw4Oko16FMlRGVBGqLKg== + bitsyntax@~0.0.4: version "0.0.4" resolved "https://registry.npmjs.org/bitsyntax/-/bitsyntax-0.0.4.tgz" @@ -939,6 +1437,13 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" +brace-expansion@^2.0.1: + version "2.0.3" + resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.3.tgz" + integrity sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA== + dependencies: + balanced-match "^1.0.0" + brace-expansion@^5.0.5: version "5.0.5" resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz" @@ -1008,6 +1513,16 @@ caniuse-lite@^1.0.30001782: resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001784.tgz" integrity sha512-WU346nBTklUV9YfUl60fqRbU5ZqyXlqvo1SgigE1OAXK5bFL8LL9q1K7aap3N739l4BvNqnkm3YrGHiY9sfUQw== +<<<<<<< Updated upstream +======= +canvas-color-tracker@^1.3: + version "1.3.2" + resolved "https://registry.npmjs.org/canvas-color-tracker/-/canvas-color-tracker-1.3.2.tgz" + integrity sha512-ryQkDX26yJ3CXzb3hxUVNlg1NKE4REc5crLBq661Nxzr8TNd236SaEf2ffYLXyI5tSABSeguHLqcVq4vf9L3Zg== + dependencies: + tinycolor2 "^1.6.0" + +>>>>>>> Stashed changes chalk@^4.0.0: version "4.1.2" resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" @@ -1025,6 +1540,16 @@ chalk@2.4.1: escape-string-regexp "^1.0.5" supports-color "^5.3.0" +<<<<<<< Updated upstream +======= +class-variance-authority@^0.7.1: + version "0.7.1" + resolved "https://registry.npmjs.org/class-variance-authority/-/class-variance-authority-0.7.1.tgz" + integrity sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg== + dependencies: + clsx "^2.1.1" + +>>>>>>> Stashed changes clsx@^2.1.1: version "2.1.1" resolved "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz" @@ -1194,41 +1719,99 @@ csstype@^3.0.2, csstype@^3.2.2: resolved "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz" integrity sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ== +<<<<<<< Updated upstream d3-array@^3.1.6, "d3-array@2 - 3", "d3-array@2.10.0 - 3": +======= +d3-array@^3.1.6, "d3-array@1 - 3", "d3-array@2 - 3", "d3-array@2.10.0 - 3": +>>>>>>> Stashed changes version "3.2.4" resolved "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz" integrity sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg== dependencies: internmap "1 - 2" +d3-binarytree@1: + version "1.0.2" + resolved "https://registry.npmjs.org/d3-binarytree/-/d3-binarytree-1.0.2.tgz" + integrity sha512-cElUNH+sHu95L04m92pG73t2MEJXKu+GeKUN1TJkFsu93E5W8E9Sc3kHEGJKgenGvj19m6upSn2EunvMgMD2Yw== + "d3-color@1 - 3": version "3.1.0" resolved "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz" integrity sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA== -d3-ease@^3.0.1: +"d3-dispatch@1 - 3": version "3.0.1" +<<<<<<< Updated upstream +======= + resolved "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz" + integrity sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg== + +"d3-drag@2 - 3": + version "3.0.0" + resolved "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz" + integrity sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg== + dependencies: + d3-dispatch "1 - 3" + d3-selection "3" + +d3-ease@^3.0.1, "d3-ease@1 - 3": + version "3.0.1" +>>>>>>> Stashed changes resolved "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz" integrity sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w== +"d3-force-3d@2 - 3": + version "3.0.6" + resolved "https://registry.npmjs.org/d3-force-3d/-/d3-force-3d-3.0.6.tgz" + integrity sha512-4tsKHUPLOVkyfEffZo1v6sFHvGFwAIIjt/W8IThbp08DYAsXZck+2pSHEG5W1+gQgEvFLdZkYvmJAbRM2EzMnA== + dependencies: + d3-binarytree "1" + d3-dispatch "1 - 3" + d3-octree "1" + d3-quadtree "1 - 3" + d3-timer "1 - 3" + "d3-format@1 - 3": version "3.1.2" resolved "https://registry.npmjs.org/d3-format/-/d3-format-3.1.2.tgz" integrity sha512-AJDdYOdnyRDV5b6ArilzCPPwc1ejkHcoyFarqlPqT7zRYjhavcT3uSrqcMvsgh2CgoPbK3RCwyHaVyxYcP2Arg== +<<<<<<< Updated upstream d3-interpolate@^3.0.1, "d3-interpolate@1.2.0 - 3": +======= +d3-interpolate@^3.0.1, "d3-interpolate@1 - 3", "d3-interpolate@1.2.0 - 3": +>>>>>>> Stashed changes version "3.0.1" resolved "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz" integrity sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g== dependencies: d3-color "1 - 3" +d3-octree@1: + version "1.1.0" + resolved "https://registry.npmjs.org/d3-octree/-/d3-octree-1.1.0.tgz" + integrity sha512-F8gPlqpP+HwRPMO/8uOu5wjH110+6q4cgJvgJT6vlpy3BEaDIKlTZrgHKZSp/i1InRpVfh4puY/kvL6MxK930A== + d3-path@^3.1.0: version "3.1.0" resolved "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz" integrity sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ== -d3-scale@^4.0.2: +"d3-quadtree@1 - 3": + version "3.0.1" + resolved "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-3.0.1.tgz" + integrity sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw== + +"d3-scale-chromatic@1 - 3": + version "3.1.0" + resolved "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz" + integrity sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ== + dependencies: + d3-color "1 - 3" + d3-interpolate "1 - 3" + +d3-scale@^4.0.2, "d3-scale@1 - 4": version "4.0.2" resolved "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz" integrity sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ== @@ -1239,6 +1822,11 @@ d3-scale@^4.0.2: d3-time "2.1.1 - 3" d3-time-format "2 - 4" +"d3-selection@2 - 3", d3-selection@3: + version "3.0.0" + resolved "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz" + integrity sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ== + d3-shape@^3.1.0: version "3.2.0" resolved "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz" @@ -1260,11 +1848,33 @@ d3-time@^3.0.0, "d3-time@1 - 3", "d3-time@2.1.1 - 3": dependencies: d3-array "2 - 3" -d3-timer@^3.0.1: +d3-timer@^3.0.1, "d3-timer@1 - 3": version "3.0.1" resolved "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz" integrity sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA== +"d3-transition@2 - 3": + version "3.0.1" + resolved "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz" + integrity sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w== + dependencies: + d3-color "1 - 3" + d3-dispatch "1 - 3" + d3-ease "1 - 3" + d3-interpolate "1 - 3" + d3-timer "1 - 3" + +"d3-zoom@2 - 3": + version "3.0.0" + resolved "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz" + integrity sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw== + dependencies: + d3-dispatch "1 - 3" + d3-drag "2 - 3" + d3-interpolate "1 - 3" + d3-selection "2 - 3" + d3-transition "2 - 3" + data-view-buffer@^1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz" @@ -1371,6 +1981,20 @@ dom-helpers@^5.0.1: "@babel/runtime" "^7.8.7" csstype "^3.0.2" +dompurify@3.2.7: + version "3.2.7" + resolved "https://registry.npmjs.org/dompurify/-/dompurify-3.2.7.tgz" + integrity sha512-WhL/YuveyGXJaerVlMYGWhvQswa7myDG17P7Vu65EWC05o8vfeNbvNf4d/BOvH99+ZW+LlQsc1GDKMa1vNK6dw== + optionalDependencies: + "@types/trusted-types" "^2.0.7" + +dompurify@3.3.1: + version "3.3.1" + resolved "https://registry.npmjs.org/dompurify/-/dompurify-3.3.1.tgz" + integrity sha512-qkdCKzLNtrgPFP1Vo+98FRzJnBRGe4ffyCea9IwHB1fyxPOeNTHpLKYGd4Uk9xvNoH0ZoOjwZxNptyMwqrId1Q== + optionalDependencies: + "@types/trusted-types" "^2.0.7" + draht@1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/draht/-/draht-1.0.1.tgz" @@ -1738,6 +2362,22 @@ file-entry-cache@^8.0.0: dependencies: flat-cache "^4.0.0" +file-surf@^1.0.3: + version "1.0.3" + resolved "https://registry.npmjs.org/file-surf/-/file-surf-1.0.3.tgz" + integrity sha512-XdNCxUASI/teXZ22/e4eDtPWhqqzDSWkkd0TFdqH3y8KUdSCpleZtId5XAahDxvdJdQDoWrpe8+SQiVb9yD5OQ== + dependencies: + "@monaco-editor/react" "^4.6.0" + "@radix-ui/react-slot" "^1.1.0" + "@radix-ui/react-toast" "^1.2.1" + class-variance-authority "^0.7.1" + clsx "^2.1.1" + lucide-react "^0.462.0" + monaco-editor "^0.45.0" + sonner "^1.5.0" + tailwind-merge "^2.5.2" + tailwindcss-animate "^1.0.7" + finalhandler@1.1.1: version "1.1.1" resolved "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz" @@ -1797,6 +2437,15 @@ flatted@^3.2.9: resolved "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz" integrity sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA== +float-tooltip@^1.7: + version "1.7.5" + resolved "https://registry.npmjs.org/float-tooltip/-/float-tooltip-1.7.5.tgz" + integrity sha512-/kXzuDnnBqyyWyhDMH7+PfP8J/oXiAavGzcRxASOMRHFuReDtofizLLJsf7nnDLAfEaMW4pVWaXrAjtnglpEkg== + dependencies: + d3-selection "2 - 3" + kapsule "^1.16" + preact "10" + follow-redirects@^1.15.11: version "1.15.11" resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz" @@ -1809,6 +2458,27 @@ for-each@^0.3.3, for-each@^0.3.5: dependencies: is-callable "^1.2.7" +force-graph@^1.51: + version "1.51.2" + resolved "https://registry.npmjs.org/force-graph/-/force-graph-1.51.2.tgz" + integrity sha512-zZNdMqx8qIQGurgnbgYIUsdXxSfvhfRSIdncsKGv/twUOZpwCsk9hPHmdjdcme1+epATgb41G0rkIGHJ0Wydng== + dependencies: + "@tweenjs/tween.js" "18 - 25" + accessor-fn "1" + bezier-js "3 - 6" + canvas-color-tracker "^1.3" + d3-array "1 - 3" + d3-drag "2 - 3" + d3-force-3d "2 - 3" + d3-scale "1 - 4" + d3-scale-chromatic "1 - 3" + d3-selection "2 - 3" + d3-zoom "2 - 3" + float-tooltip "^1.7" + index-array-by "1" + kapsule "^1.16" + lodash-es "4" + form-data@^4.0.5: version "4.0.5" resolved "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz" @@ -2067,6 +2737,14 @@ imurmurhash@^0.1.4: resolved "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz" integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== +<<<<<<< Updated upstream +======= +index-array-by@1: + version "1.4.2" + resolved "https://registry.npmjs.org/index-array-by/-/index-array-by-1.4.2.tgz" + integrity sha512-SP23P27OUKzXWEC/TOyWlwLviofQkCSCKONnc62eItjp69yCZZPqDQtr3Pw5gJDnPeUMqExmKydNZaJO0FU9pw== + +>>>>>>> Stashed changes inherits@^2.0.3, inherits@~2.0.1: version "2.0.4" resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" @@ -2292,6 +2970,14 @@ isexe@^2.0.0: resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== +<<<<<<< Updated upstream +======= +jerrypick@^1.1.1: + version "1.1.2" + resolved "https://registry.npmjs.org/jerrypick/-/jerrypick-1.1.2.tgz" + integrity sha512-YKnxXEekXKzhpf7CLYA0A+oDP8V0OhICNCr5lv96FvSsDEmrb0GKM776JgQvHTMjr7DTTPEVv/1Ciaw0uEWzBA== + +>>>>>>> Stashed changes jiti@*, jiti@^2.6.1, jiti@>=1.21.0: version "2.6.1" resolved "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz" @@ -2309,6 +2995,11 @@ js-yaml@^4.1.1: dependencies: argparse "^2.0.1" +jschardet@3.1.4: + version "3.1.4" + resolved "https://registry.npmjs.org/jschardet/-/jschardet-3.1.4.tgz" + integrity sha512-/kmVISmrwVwtyYU40iQUOp3SUPk2dhNCMsZBQX0R1/jZ8maaXJ/oZIzUOiyOqcgtLnETFKYChbJ5iDC/eWmFHg== + jsesc@^3.0.2: version "3.1.0" resolved "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz" @@ -2374,6 +3065,13 @@ jws@^3.2.1: jwa "^1.4.2" safe-buffer "^5.0.1" +kapsule@^1.16: + version "1.16.3" + resolved "https://registry.npmjs.org/kapsule/-/kapsule-1.16.3.tgz" + integrity sha512-4+5mNNf4vZDSwPhKprKwz3330iisPrb08JyMgbsdFrimBCKNHecua/WBwvVg3n7vwx0C1ARjfhwIpbrbd9n5wg== + dependencies: + lodash-es "4" + keyv@^4.5.4: version "4.5.4" resolved "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz" @@ -2428,6 +3126,11 @@ locate-path@^6.0.0: dependencies: p-locate "^5.0.0" +lodash-es@4: + version "4.18.1" + resolved "https://registry.npmjs.org/lodash-es/-/lodash-es-4.18.1.tgz" + integrity sha512-J8xewKD/Gk22OZbhpOVSwcs60zhd95ESDwezOFuA3/099925PdHJ7OFHNTGtajL3AlZkykD32HykiMo+BIBI8A== + lodash.includes@^4.3.0: version "4.3.0" resolved "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz" @@ -2492,6 +3195,11 @@ lru-cache@^5.1.1: dependencies: yallist "^3.0.2" +lucide-react@^0.462.0: + version "0.462.0" + resolved "https://registry.npmjs.org/lucide-react/-/lucide-react-0.462.0.tgz" + integrity sha512-NTL7EbAao9IFtuSivSZgrAh4fZd09Lr+6MTkqIxuHaH2nnYiYIzXPo06cOxHg9wKLdj6LL8TByG4qpePqwgx/g== + lusca@1.6.1: version "1.6.1" resolved "https://registry.npmjs.org/lusca/-/lusca-1.6.1.tgz" @@ -2506,6 +3214,11 @@ magic-string@^0.30.21: dependencies: "@jridgewell/sourcemap-codec" "^1.5.5" +marked@14.0.0: + version "14.0.0" + resolved "https://registry.npmjs.org/marked/-/marked-14.0.0.tgz" + integrity sha512-uIj4+faQ+MgHgwUW1l2PsPglZLOLOT1uErt06dAPtx2kjteLAkbsd/0FiYg/MGS+i7ZKLb7w2WClxHkzOOuryQ== + math-intrinsics@^1.1.0: version "1.1.0" resolved "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz" @@ -2562,11 +3275,71 @@ minimatch@^3.1.5: dependencies: brace-expansion "^1.1.7" +minimatch@^5.1.0: + version "5.1.9" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-5.1.9.tgz" + integrity sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw== + dependencies: + brace-expansion "^2.0.1" + moment@2.22.2: version "2.22.2" resolved "https://registry.npmjs.org/moment/-/moment-2.22.2.tgz" integrity sha512-LRvkBHaJGnrcWvqsElsOhHCzj8mU39wLx5pQ0pc6s153GynCTsPdGdqsVNKAQD9sKnWj11iF7TZx9fpLwdD3fw== +monaco-editor@^0.45.0: + version "0.45.0" + resolved "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.45.0.tgz" + integrity sha512-mjv1G1ZzfEE3k9HZN0dQ2olMdwIfaeAAjFiwNprLfYNRSz7ctv9XuCT7gPtBGrMUeV1/iZzYKj17Khu1hxoHOA== + +"monaco-editor@>= 0.25.0 < 1": + version "0.55.1" + resolved "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.55.1.tgz" + integrity sha512-jz4x+TJNFHwHtwuV9vA9rMujcZRb0CEilTEwG2rRSpe/A7Jdkuj8xPKttCgOh+v/lkHy7HsZ64oj+q3xoAFl9A== + dependencies: + dompurify "3.2.7" + marked "14.0.0" + +monaco-languageclient@^10.7.0: + version "10.7.0" + resolved "https://registry.npmjs.org/monaco-languageclient/-/monaco-languageclient-10.7.0.tgz" + integrity sha512-oA5cOFixkF4bspVL2zMSn48LvlNR/Cu3vJ8MCVam3PdjobSULGgHtOASuZIi3FgWK42X1z8/6hrG0LCjvNu1Hw== + dependencies: + "@codingame/monaco-vscode-api" "^25.1.2" + "@codingame/monaco-vscode-configuration-service-override" "^25.1.2" + "@codingame/monaco-vscode-editor-api" "^25.1.2" + "@codingame/monaco-vscode-editor-service-override" "^25.1.2" + "@codingame/monaco-vscode-extension-api" "^25.1.2" + "@codingame/monaco-vscode-extensions-service-override" "^25.1.2" + "@codingame/monaco-vscode-language-pack-cs" "^25.1.2" + "@codingame/monaco-vscode-language-pack-de" "^25.1.2" + "@codingame/monaco-vscode-language-pack-es" "^25.1.2" + "@codingame/monaco-vscode-language-pack-fr" "^25.1.2" + "@codingame/monaco-vscode-language-pack-it" "^25.1.2" + "@codingame/monaco-vscode-language-pack-ja" "^25.1.2" + "@codingame/monaco-vscode-language-pack-ko" "^25.1.2" + "@codingame/monaco-vscode-language-pack-pl" "^25.1.2" + "@codingame/monaco-vscode-language-pack-pt-br" "^25.1.2" + "@codingame/monaco-vscode-language-pack-qps-ploc" "^25.1.2" + "@codingame/monaco-vscode-language-pack-ru" "^25.1.2" + "@codingame/monaco-vscode-language-pack-tr" "^25.1.2" + "@codingame/monaco-vscode-language-pack-zh-hans" "^25.1.2" + "@codingame/monaco-vscode-language-pack-zh-hant" "^25.1.2" + "@codingame/monaco-vscode-languages-service-override" "^25.1.2" + "@codingame/monaco-vscode-localization-service-override" "^25.1.2" + "@codingame/monaco-vscode-log-service-override" "^25.1.2" + "@codingame/monaco-vscode-model-service-override" "^25.1.2" + "@codingame/monaco-vscode-monarch-service-override" "^25.1.2" + "@codingame/monaco-vscode-textmate-service-override" "^25.1.2" + "@codingame/monaco-vscode-theme-defaults-default-extension" "^25.1.2" + "@codingame/monaco-vscode-theme-service-override" "^25.1.2" + "@codingame/monaco-vscode-views-service-override" "^25.1.2" + "@codingame/monaco-vscode-workbench-service-override" "^25.1.2" + vscode "npm:@codingame/monaco-vscode-extension-api@^25.1.2" + vscode-languageclient "~9.0.1" + vscode-languageserver-protocol "~3.17.5" + vscode-ws-jsonrpc "~3.5.0" + morgan@1.9.1: version "1.9.1" resolved "https://registry.npmjs.org/morgan/-/morgan-1.9.1.tgz" @@ -2785,6 +3558,11 @@ postcss@^8.5.8: picocolors "^1.1.1" source-map-js "^1.2.1" +preact@10: + version "10.29.1" + resolved "https://registry.npmjs.org/preact/-/preact-10.29.1.tgz" + integrity sha512-gQCLc/vWroE8lIpleXtdJhTFDogTdZG9AjMUpVkDf2iTCNwYNWA+u16dL41TqUDJO4gm2IgrcMv3uTpjd4Pwmg== + prelude-ls@^1.2.1: version "1.2.1" resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz" @@ -2810,7 +3588,7 @@ processenv@1.1.0: dependencies: babel-runtime "6.26.0" -prop-types@^15.6.2: +prop-types@^15.6.2, prop-types@15: version "15.8.1" resolved "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz" integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== @@ -2857,13 +3635,26 @@ raw-body@2.3.3: iconv-lite "0.4.23" unpipe "1.0.0" +<<<<<<< Updated upstream "react-dom@^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom@^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom@^18.0.0 || ^19.0.0", react-dom@^19.2.4, react-dom@>=16.6.0, react-dom@>=17.0.0, react-dom@>=18: +======= +"react-dom@^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom@^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom@^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom@^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom@^18.0.0 || ^19.0.0", "react-dom@^18.0.0 || ^19.0.0 || ^19.0.0-rc", "react-dom@^18.3.1 || ^19.0.0", react-dom@^19.2.4, react-dom@>=16.6.0, react-dom@>=17.0.0, react-dom@>=18: +>>>>>>> Stashed changes version "19.2.4" resolved "https://registry.npmjs.org/react-dom/-/react-dom-19.2.4.tgz" integrity sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ== dependencies: scheduler "^0.27.0" +react-force-graph-2d@^1.29.1: + version "1.29.1" + resolved "https://registry.npmjs.org/react-force-graph-2d/-/react-force-graph-2d-1.29.1.tgz" + integrity sha512-1Rl/1Z3xy2iTHKj6a0jRXGyiI86xUti81K+jBQZ+Oe46csaMikp47L5AjrzA9hY9fNGD63X8ffrqnvaORukCuQ== + dependencies: + force-graph "^1.51" + prop-types "15" + react-kapsule "^2.5" + react-icons@^5.6.0: version "5.6.0" resolved "https://registry.npmjs.org/react-icons/-/react-icons-5.6.0.tgz" @@ -2874,6 +3665,16 @@ react-is@^16.13.1, "react-is@^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0": resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== +<<<<<<< Updated upstream +======= +react-kapsule@^2.5: + version "2.5.7" + resolved "https://registry.npmjs.org/react-kapsule/-/react-kapsule-2.5.7.tgz" + integrity sha512-kifAF4ZPD77qZKc4CKLmozq6GY1sBzPEJTIJb0wWFK6HsePJatK3jXplZn2eeAt3x67CDozgi7/rO8fNQ/AL7A== + dependencies: + jerrypick "^1.1.1" + +>>>>>>> Stashed changes "react-redux@^7.2.1 || ^8.1.3 || ^9.0.0", "react-redux@8.x.x || 9.x.x": version "9.2.0" resolved "https://registry.npmjs.org/react-redux/-/react-redux-9.2.0.tgz" @@ -2907,7 +3708,11 @@ react-transition-group@^4.4.1: loose-envify "^1.4.0" prop-types "^15.6.2" +<<<<<<< Updated upstream react@*, "react@^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react@^16.9.0 || ^17.0.0 || ^18 || ^19", "react@^17.0.0 || ^18.0.0 || ^19.0.0", "react@^18.0 || ^19", "react@^18.0.0 || ^19.0.0", react@^19.2.4, react@>=16.6.0, react@>=17.0.0, react@>=18, react@>=18.0.0: +======= +react@*, "react@^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0-rc", "react@^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react@^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react@^16.9.0 || ^17.0.0 || ^18 || ^19", "react@^17.0.0 || ^18.0.0 || ^19.0.0", "react@^18.0 || ^19", "react@^18.0.0 || ^19.0.0", "react@^18.0.0 || ^19.0.0 || ^19.0.0-rc", "react@^18.3.1 || ^19.0.0", react@^19.2.4, react@>=16.13.1, react@>=16.6.0, react@>=17.0.0, react@>=18, react@>=18.0.0: +>>>>>>> Stashed changes version "19.2.4" resolved "https://registry.npmjs.org/react/-/react-19.2.4.tgz" integrity sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ== @@ -3091,6 +3896,11 @@ semver@^6.3.1: resolved "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== +semver@^7.3.7: + version "7.7.4" + resolved "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz" + integrity sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA== + semver@^7.7.3: version "7.7.4" resolved "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz" @@ -3223,6 +4033,11 @@ side-channel@^1.1.0: side-channel-map "^1.0.1" side-channel-weakmap "^1.0.2" +sonner@^1.5.0: + version "1.7.4" + resolved "https://registry.npmjs.org/sonner/-/sonner-1.7.4.tgz" + integrity sha512-DIS8z4PfJRbIyfVFDVnK9rO3eYDtse4Omcm6bt0oEr5/jtLgysmjuBl1frJ9E/EQZrFmKx2A8m/s5s9CRXIzhw== + source-map-js@^1.2.1: version "1.2.1" resolved "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz" @@ -3240,6 +4055,11 @@ stack-trace@0.0.10: resolved "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz" integrity sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg== +state-local@^1.0.6: + version "1.0.7" + resolved "https://registry.npmjs.org/state-local/-/state-local-1.0.7.tgz" + integrity sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w== + "statuses@>= 1.4.0 < 2": version "1.5.0" resolved "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz" @@ -3342,6 +4162,11 @@ supports-color@^7.1.0: dependencies: has-flag "^4.0.0" +tailwind-merge@^2.5.2: + version "2.6.1" + resolved "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.6.1.tgz" + integrity sha512-Oo6tHdpZsGpkKG88HJ8RR1rg/RdnEkQEfMoEk2x1XRI3F1AxeU+ijRXpiVUF4UbLfcxxRGw6TbUINKYdWVsQTQ== + tailwind@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/tailwind/-/tailwind-4.0.0.tgz" @@ -3375,7 +4200,16 @@ tailwind@^4.0.0: uuidv4 "3.0.1" ws "6.2.0" +<<<<<<< Updated upstream tailwindcss@^4.2.2, tailwindcss@4.2.2: +======= +tailwindcss-animate@^1.0.7: + version "1.0.7" + resolved "https://registry.npmjs.org/tailwindcss-animate/-/tailwindcss-animate-1.0.7.tgz" + integrity sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA== + +tailwindcss@^4.2.2, "tailwindcss@>=3.0.0 || insiders", tailwindcss@4.2.2: +>>>>>>> Stashed changes version "4.2.2" resolved "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.2.2.tgz" integrity sha512-KWBIxs1Xb6NoLdMVqhbhgwZf2PGBpPEiwOqgI4pFIYbNTfBXiKYyWoTsXgBQ9WFg/OlhnvHaY+AEpW7wSmFo2Q== @@ -3395,6 +4229,11 @@ tiny-invariant@^1.3.3: resolved "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz" integrity sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg== +tinycolor2@^1.6.0: + version "1.6.0" + resolved "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.6.0.tgz" + integrity sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw== + tinyglobby@^0.2.15: version "0.2.15" resolved "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz" @@ -3619,6 +4458,53 @@ victory-vendor@^37.0.2: optionalDependencies: fsevents "~2.3.3" +vscode-jsonrpc@~8.2.1: + version "8.2.1" + resolved "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.2.1.tgz" + integrity sha512-kdjOSJ2lLIn7r1rtrMbbNCHjyMPfRnowdKjBQ+mGq6NAW5QY2bEZC/khaC5OR8svbbjvLEaIXkOq45e2X9BIbQ== + +vscode-jsonrpc@8.2.0: + version "8.2.0" + resolved "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0.tgz" + integrity sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA== + +vscode-languageclient@~9.0.1: + version "9.0.1" + resolved "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-9.0.1.tgz" + integrity sha512-JZiimVdvimEuHh5olxhxkht09m3JzUGwggb5eRUkzzJhZ2KjCN0nh55VfiED9oez9DyF8/fz1g1iBV3h+0Z2EA== + dependencies: + minimatch "^5.1.0" + semver "^7.3.7" + vscode-languageserver-protocol "3.17.5" + +vscode-languageserver-protocol@~3.17.5, vscode-languageserver-protocol@3.17.5: + version "3.17.5" + resolved "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.5.tgz" + integrity sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg== + dependencies: + vscode-jsonrpc "8.2.0" + vscode-languageserver-types "3.17.5" + +vscode-languageserver-types@3.17.5: + version "3.17.5" + resolved "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.5.tgz" + integrity sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg== + +vscode-ws-jsonrpc@^3.5.0, vscode-ws-jsonrpc@~3.5.0: + version "3.5.0" + resolved "https://registry.npmjs.org/vscode-ws-jsonrpc/-/vscode-ws-jsonrpc-3.5.0.tgz" + integrity sha512-13ZDy7Od4AfEPK2HIfY3DtyRi4FVsvFql1yobVJrpIoHOKGGJpIjVvIJpMxkrHzCZzWlYlg+WEu2hrYkCTvM0Q== + dependencies: + vscode-jsonrpc "~8.2.1" + +"vscode@npm:@codingame/monaco-vscode-extension-api@^25.1.2": + version "25.1.2" + resolved "https://registry.npmjs.org/@codingame/monaco-vscode-extension-api/-/monaco-vscode-extension-api-25.1.2.tgz" + integrity sha512-SJW/YOhjo+9MXEyzMwQMUWdJVR3Llc6pTq5JQqs6Y30v73gTrpLqtzbd9FNdCuQR8S6bUk5ScH8GL4QrVuL5FA== + dependencies: + "@codingame/monaco-vscode-api" "25.1.2" + "@codingame/monaco-vscode-extensions-service-override" "25.1.2" + w3c-keyname@^2.2.4: version "2.2.8" resolved "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz"