{/* Graph */}
-
+ {viewMode === "graph" ? (
+
+ ) : (
+
+ )}
{/* Right Toggle Button */}
diff --git a/hindsight-control-plane/src/components/graph-3d.tsx b/hindsight-control-plane/src/components/graph-3d.tsx
new file mode 100644
index 00000000..bdb60a1c
--- /dev/null
+++ b/hindsight-control-plane/src/components/graph-3d.tsx
@@ -0,0 +1,469 @@
+"use client";
+
+import { useRef, useEffect, useState, useMemo, useCallback } from "react";
+import dynamic from "next/dynamic";
+import { GraphNode, GraphLink, GraphData } from "./graph-2d";
+import { Button } from "@/components/ui/button";
+import { RotateCcw, ZoomIn, ZoomOut, Maximize2, Minimize2 } from "lucide-react";
+
+// Dynamic import to avoid SSR issues with WebGL
+// Load react-force-graph-3d which will handle Three.js internally
+const ForceGraph3D = dynamic(
+ () => {
+ // Ensure we're in browser environment
+ if (typeof window === "undefined") {
+ return Promise.resolve(null);
+ }
+
+ // Import react-force-graph-3d - it handles Three.js internally
+ return import("react-force-graph-3d")
+ .then((mod) => {
+ const Component = mod.default || mod;
+ // Verify Three.js is available
+ if (!Component) {
+ throw new Error("Failed to load react-force-graph-3d");
+ }
+ return Component;
+ })
+ .catch((error) => {
+ console.error("Error loading 3D graph library:", error);
+ throw error;
+ });
+ },
+ {
+ ssr: false,
+ loading: () => (
+
+
+
+
Loading 3D graph...
+
+
+ ),
+ }
+) as any;
+
+// Hook to detect dark mode
+function useIsDarkMode() {
+ const [isDark, setIsDark] = useState(false);
+
+ useEffect(() => {
+ const checkDark = () => {
+ setIsDark(document.documentElement.classList.contains("dark"));
+ };
+
+ checkDark();
+
+ // Watch for theme changes
+ const observer = new MutationObserver(checkDark);
+ observer.observe(document.documentElement, { attributes: true, attributeFilter: ["class"] });
+
+ return () => observer.disconnect();
+ }, []);
+
+ return isDark;
+}
+
+// ============================================================================
+// Types & Interfaces
+// ============================================================================
+
+export interface Graph3DProps {
+ data: GraphData;
+ height?: number;
+ showLabels?: boolean;
+ onNodeClick?: (node: GraphNode) => void;
+ onNodeHover?: (node: GraphNode | null) => void;
+ nodeColorFn?: (node: GraphNode) => string;
+ nodeSizeFn?: (node: GraphNode) => number;
+ linkColorFn?: (link: GraphLink) => string;
+ linkWidthFn?: (link: GraphLink) => number;
+ maxNodes?: number;
+}
+
+// ============================================================================
+// Default Values
+// ============================================================================
+
+const BRAND_PRIMARY = "#0074d9";
+const DEFAULT_NODE_COLOR = BRAND_PRIMARY;
+const DEFAULT_LINK_COLOR = BRAND_PRIMARY;
+const DEFAULT_LINK_WIDTH = 1;
+const DEFAULT_NODE_SIZE = 4;
+
+// ============================================================================
+// Component
+// ============================================================================
+
+export function Graph3D({
+ data,
+ height = 600,
+ showLabels = true,
+ onNodeClick,
+ onNodeHover,
+ nodeColorFn,
+ nodeSizeFn,
+ linkColorFn,
+ linkWidthFn,
+ maxNodes,
+}: Graph3DProps) {
+ const fgRef = useRef
(null);
+ const [isMounted, setIsMounted] = useState(false);
+ const [isLibraryReady, setIsLibraryReady] = useState(false);
+ const hasCenteredRef = useRef(false); // Track if we've centered once
+ const [hoveredNode, setHoveredNode] = useState(null);
+ const [hoveredNodePos, setHoveredNodePos] = useState<{ x: number; y: number } | null>(null);
+ const [mousePos, setMousePos] = useState<{ x: number; y: number } | null>(null);
+ const [cameraPosition, setCameraPosition] = useState({ x: 0, y: 0, z: 0 });
+ const isDarkMode = useIsDarkMode();
+
+ // Ensure Three.js and library are ready before rendering
+ useEffect(() => {
+ if (!isMounted) return;
+
+ const checkLibrary = async () => {
+ try {
+ // Import Three.js first to ensure it's available
+ const three = await import("three");
+ // Verify Three.js is properly loaded
+ if (three && three.VERTEX_SHADER) {
+ // Small delay to ensure everything is initialized
+ setTimeout(() => {
+ setIsLibraryReady(true);
+ }, 100);
+ } else {
+ console.warn("Three.js not properly initialized");
+ setIsLibraryReady(true); // Still try to render
+ }
+ } catch (error) {
+ console.error("Error loading Three.js:", error);
+ setIsLibraryReady(true); // Still try to render
+ }
+ };
+
+ checkLibrary();
+ }, [isMounted]);
+
+ // Use refs to store callbacks to prevent re-renders
+ const onNodeClickRef = useRef(onNodeClick);
+ const onNodeHoverRef = useRef(onNodeHover);
+ const nodeColorFnRef = useRef(nodeColorFn);
+ const linkColorFnRef = useRef(linkColorFn);
+ const nodeSizeFnRef = useRef(nodeSizeFn);
+ const linkWidthFnRef = useRef(linkWidthFn);
+
+ onNodeClickRef.current = onNodeClick;
+ onNodeHoverRef.current = onNodeHover;
+ nodeColorFnRef.current = nodeColorFn;
+ linkColorFnRef.current = linkColorFn;
+ nodeSizeFnRef.current = nodeSizeFn;
+ linkWidthFnRef.current = linkWidthFn;
+
+ // Transform and limit data
+ const graphData = useMemo(() => {
+ let nodes = [...data.nodes];
+
+ // Limit nodes if needed
+ if (maxNodes && nodes.length > maxNodes) {
+ nodes = nodes.slice(0, maxNodes);
+ }
+
+ // Show ALL links between visible nodes
+ const nodeIds = new Set(nodes.map((n) => n.id));
+ const links = data.links.filter((l) => nodeIds.has(l.source) && nodeIds.has(l.target));
+
+ return { nodes, links };
+ }, [data, maxNodes]);
+
+ // Track mounting state
+ useEffect(() => {
+ setIsMounted(true);
+ return () => setIsMounted(false);
+ }, []);
+
+ // Calculate node connections for dynamic sizing
+ const nodeConnections = useMemo(() => {
+ const connections = new Map();
+ graphData.links.forEach((link) => {
+ connections.set(link.source, (connections.get(link.source) || 0) + 1);
+ connections.set(link.target, (connections.get(link.target) || 0) + 1);
+ });
+ return connections;
+ }, [graphData.links]);
+
+ // Prepare graph data for 3D force graph
+ const graphData3D = useMemo(() => {
+ const nodes = graphData.nodes.map((node) => {
+ const connections = nodeConnections.get(node.id) || 0;
+ const size = nodeSizeFnRef.current
+ ? nodeSizeFnRef.current(node)
+ : node.size || Math.max(3, Math.min(10, DEFAULT_NODE_SIZE + connections * 0.6));
+
+ return {
+ id: node.id,
+ name: showLabels ? node.label || node.id.substring(0, 8) : "",
+ color: nodeColorFnRef.current
+ ? nodeColorFnRef.current(node)
+ : node.color || DEFAULT_NODE_COLOR,
+ val: size,
+ originalNode: node,
+ };
+ });
+
+ const links = graphData.links.map((link) => ({
+ source: link.source,
+ target: link.target,
+ color: linkColorFnRef.current
+ ? linkColorFnRef.current(link)
+ : link.color || DEFAULT_LINK_COLOR,
+ width: linkWidthFnRef.current
+ ? linkWidthFnRef.current(link)
+ : link.width || DEFAULT_LINK_WIDTH,
+ originalLink: link,
+ }));
+
+ return { nodes, links };
+ }, [graphData, showLabels, nodeConnections]);
+
+ // Handle node click
+ const handleNodeClick = useCallback(
+ (node: any) => {
+ const originalNode = node.originalNode as GraphNode;
+ if (onNodeClickRef.current && originalNode) {
+ onNodeClickRef.current(originalNode);
+ }
+ },
+ []
+ );
+
+ // Handle node hover with mouse position tracking
+ const handleNodeHover = useCallback(
+ (node: any, prevNode: any) => {
+ if (node) {
+ const originalNode = node.originalNode as GraphNode;
+ setHoveredNode(originalNode);
+ // Use mouse position for tooltip if available, otherwise center
+ if (mousePos) {
+ setHoveredNodePos(mousePos);
+ } else {
+ setHoveredNodePos({ x: window.innerWidth / 2, y: window.innerHeight / 2 });
+ }
+ if (onNodeHoverRef.current && originalNode) {
+ onNodeHoverRef.current(originalNode);
+ }
+ } else {
+ setHoveredNode(null);
+ setHoveredNodePos(null);
+ if (onNodeHoverRef.current) {
+ onNodeHoverRef.current(null);
+ }
+ }
+ },
+ [mousePos]
+ );
+
+ // Track mouse position for tooltip
+ useEffect(() => {
+ const handleMouseMove = (e: MouseEvent) => {
+ setMousePos({ x: e.clientX, y: e.clientY });
+ };
+
+ window.addEventListener("mousemove", handleMouseMove);
+ return () => window.removeEventListener("mousemove", handleMouseMove);
+ }, []);
+
+ // Handle link hover
+ const handleLinkHover = useCallback((link: any) => {
+ // Optional: Add link hover tooltip if needed
+ }, []);
+
+ // Control functions
+ const handleResetCamera = useCallback(() => {
+ if (fgRef.current) {
+ fgRef.current.cameraPosition({ x: 0, y: 0, z: 1000 });
+ fgRef.current.zoomToFit(400);
+ }
+ }, []);
+
+ const handleZoomIn = useCallback(() => {
+ if (fgRef.current) {
+ const distance = fgRef.current.cameraDistance();
+ fgRef.current.cameraPosition({ z: Math.max(100, distance * 0.7) });
+ }
+ }, []);
+
+ const handleZoomOut = useCallback(() => {
+ if (fgRef.current) {
+ const distance = fgRef.current.cameraDistance();
+ fgRef.current.cameraPosition({ z: Math.min(3000, distance * 1.4) });
+ }
+ }, []);
+
+ const handleFitView = useCallback(() => {
+ if (fgRef.current) {
+ fgRef.current.zoomToFit(400);
+ }
+ }, []);
+
+ // Center graph on first load - using onEngineStop (proven method)
+ // No separate loading state needed - graph renders immediately
+
+ if (!isMounted) {
+ return (
+
+
+
+
Loading 3D graph...
+
+
+ );
+ }
+
+
+ return (
+
+ {isMounted && isLibraryReady && ForceGraph3D && graphData3D.nodes.length > 0 && (
+
{
+ const originalNode = node.originalNode as GraphNode;
+ return showLabels
+ ? originalNode?.label || node.name || originalNode?.id || node.id || ""
+ : "";
+ }}
+ nodeColor={(node: { color?: string }) => node.color || DEFAULT_NODE_COLOR}
+ nodeVal={(node: { val?: number }) => node.val || DEFAULT_NODE_SIZE}
+ linkColor={(link: { color?: string }) => link.color || DEFAULT_LINK_COLOR}
+ linkWidth={(link: { width?: number }) => link.width || DEFAULT_LINK_WIDTH}
+ linkDirectionalArrowLength={8}
+ linkDirectionalArrowRelPos={1}
+ linkCurvature={0.25}
+ linkOpacity={isDarkMode ? 0.6 : 0.5}
+ nodeOpacity={0.9}
+ onNodeClick={handleNodeClick}
+ onNodeHover={handleNodeHover}
+ onLinkHover={handleLinkHover}
+ backgroundColor={isDarkMode ? "#0f1419" : "#f8fafc"}
+ showNavInfo={false}
+ cooldownTicks={100}
+ warmupTicks={60}
+ onEngineStop={() => {
+ // Auto-center on first engine stop (proven method)
+ if (fgRef.current && !hasCenteredRef.current) {
+ try {
+ fgRef.current.cameraPosition({ x: 0, y: 0, z: 1000 });
+ fgRef.current.zoomToFit(400);
+ hasCenteredRef.current = true;
+ } catch (error) {
+ // Silently fail
+ hasCenteredRef.current = true;
+ }
+ }
+ }}
+ onCameraChange={(camera: any) => {
+ if (camera) {
+ setCameraPosition({
+ x: camera.x || 0,
+ y: camera.y || 0,
+ z: camera.z || 0,
+ });
+ }
+ }}
+ />
+ )}
+
+ {/* Node hover tooltip */}
+ {hoveredNode && hoveredNodePos && (
+
+
+
{hoveredNode.label || hoveredNode.id}
+ {hoveredNode.metadata?.text && (
+
+ {hoveredNode.metadata.text}
+
+ )}
+
+
+ )}
+
+ {/* Control buttons */}
+
+
+
+
+
+
+
+ {/* Empty state */}
+ {graphData.nodes.length === 0 && (
+
+
+
No memories to display
+
+
+ )}
+
+ {/* Controls hint */}
+
+
Controls
+
+
🖱️ Drag to rotate • Scroll to zoom
+
👆 Click node to view details
+
🔘 Use buttons to reset/zoom
+
+
+
+ );
+}
diff --git a/package-lock.json b/package-lock.json
index a0257db2..3ebf24ab 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -167,6 +167,7 @@
"react": "^19.2.0",
"react-chrono": "^2.9.1",
"react-dom": "^19.2.0",
+ "react-force-graph-3d": "^1.25.4",
"react-markdown": "^10.1.0",
"react18-json-view": "^0.2.9",
"recharts": "^3.5.1",
@@ -446,6 +447,7 @@
"resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.46.2.tgz",
"integrity": "sha512-ZsOJqu4HOG5BlvIFnMU0YKjQ9ZI6r3C31dg2jk5kMWPSdhJpYL9xa5hEe7aieE+707dXeMI4ej3diy6mXdZpgA==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"@algolia/client-common": "5.46.2",
"@algolia/requester-browser-xhr": "5.46.2",
@@ -2640,6 +2642,7 @@
}
],
"license": "MIT",
+ "peer": true,
"engines": {
"node": ">=18"
},
@@ -2662,6 +2665,7 @@
}
],
"license": "MIT",
+ "peer": true,
"engines": {
"node": ">=18"
}
@@ -2771,6 +2775,7 @@
"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz",
"integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"cssesc": "^3.0.0",
"util-deprecate": "^1.0.2"
@@ -3192,6 +3197,7 @@
"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz",
"integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"cssesc": "^3.0.0",
"util-deprecate": "^1.0.2"
@@ -4177,6 +4183,7 @@
"resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-docs/-/plugin-content-docs-3.9.2.tgz",
"integrity": "sha512-C5wZsGuKTY8jEYsqdxhhFOe1ZDjH0uIYJ9T/jebHwkyxqnr4wW0jTkB72OMqNjsoQRcb0JN3PcSeTwFlVgzCZg==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"@docusaurus/core": "3.9.2",
"@docusaurus/logger": "3.9.2",
@@ -4445,6 +4452,7 @@
"resolved": "https://registry.npmjs.org/@docusaurus/theme-common/-/theme-common-3.9.2.tgz",
"integrity": "sha512-6c4DAbR6n6nPbnZhY2V3tzpnKnGL+6aOsLvFL26VRqhlczli9eWG0VDUNoCQEPnGwDMhPS42UhSAnz5pThm5Ag==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"@docusaurus/mdx-loader": "3.9.2",
"@docusaurus/module-type-aliases": "3.9.2",
@@ -4588,6 +4596,7 @@
"resolved": "https://registry.npmjs.org/@docusaurus/utils/-/utils-3.9.2.tgz",
"integrity": "sha512-lBSBiRruFurFKXr5Hbsl2thmGweAPmddhF3jb99U4EMDA5L+e5Y1rAkOS07Nvrup7HUMBDrCV45meaxZnt28nQ==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"@docusaurus/logger": "3.9.2",
"@docusaurus/types": "3.9.2",
@@ -6193,6 +6202,7 @@
"resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-3.1.1.tgz",
"integrity": "sha512-f++rKLQgUVYDAtECQ6fn/is15GkEH9+nZPM3MS0RcxVqoTfawHvDlSCH7JbMhAM6uJ32v3eXLvLmLvjGu7PTQw==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"@types/mdx": "^2.0.0"
},
@@ -6687,6 +6697,7 @@
"resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz",
"integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==",
"license": "Apache-2.0",
+ "peer": true,
"engines": {
"node": ">=8.0.0"
}
@@ -8192,6 +8203,7 @@
"resolved": "https://registry.npmjs.org/@svgr/core/-/core-8.1.0.tgz",
"integrity": "sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"@babel/core": "^7.21.3",
"@svgr/babel-preset": "8.1.0",
@@ -8610,6 +8622,12 @@
"node": ">=10.13.0"
}
},
+ "node_modules/@tweenjs/tween.js": {
+ "version": "25.0.0",
+ "resolved": "https://registry.npmjs.org/@tweenjs/tween.js/-/tween.js-25.0.0.tgz",
+ "integrity": "sha512-XKLA6syeBUaPzx4j3qwMqzzq+V4uo72BnlbOjmuljLrRqdsd3qnzvZZoxvMHZ23ndsRS4aufU6JOZYpCbU6T1A==",
+ "license": "MIT"
+ },
"node_modules/@tybys/wasm-util": {
"version": "0.10.1",
"resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz",
@@ -9209,6 +9227,7 @@
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.7.tgz",
"integrity": "sha512-MWtvHrGZLFttgeEj28VXHxpmwYbor/ATPYbBfSFZEIRK0ecCFLl2Qo55z52Hss+UV9CRN7trSeq1zbgx7YDWWg==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"csstype": "^3.2.2"
}
@@ -9218,6 +9237,7 @@
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz",
"integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==",
"license": "MIT",
+ "peer": true,
"peerDependencies": {
"@types/react": "^19.2.0"
}
@@ -9415,6 +9435,7 @@
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.52.0.tgz",
"integrity": "sha512-iIACsx8pxRnguSYhHiMn2PvhvfpopO9FXHyn1mG5txZIsAaB6F0KwbFnUQN3KCiG3Jcuad/Cao2FAs1Wp7vAyg==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"@typescript-eslint/scope-manager": "8.52.0",
"@typescript-eslint/types": "8.52.0",
@@ -10047,6 +10068,22 @@
"integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==",
"license": "Apache-2.0"
},
+ "node_modules/3d-force-graph": {
+ "version": "1.79.0",
+ "resolved": "https://registry.npmjs.org/3d-force-graph/-/3d-force-graph-1.79.0.tgz",
+ "integrity": "sha512-0RUNcfiH12f93loY/iS4wShzhXzdLLN4futvFnintF7eP30DjX+nAdLDAGOZwSflhijQyVwnGtpczNjFrDLUzQ==",
+ "license": "MIT",
+ "dependencies": {
+ "accessor-fn": "1",
+ "kapsule": "^1.16",
+ "three": ">=0.118 <1",
+ "three-forcegraph": "1",
+ "three-render-objects": "^1.35"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
"node_modules/accepts": {
"version": "1.3.8",
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
@@ -10090,11 +10127,21 @@
"node": ">= 0.6"
}
},
+ "node_modules/accessor-fn": {
+ "version": "1.5.3",
+ "resolved": "https://registry.npmjs.org/accessor-fn/-/accessor-fn-1.5.3.tgz",
+ "integrity": "sha512-rkAofCwe/FvYFUlMB0v0gWmhqtfAtV1IUkdPbfhTUyYniu5LrC0A0UJkTH0Jv3S8SvwkmfuAlY+mQIJATdocMA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ }
+ },
"node_modules/acorn": {
"version": "8.15.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
"license": "MIT",
+ "peer": true,
"bin": {
"acorn": "bin/acorn"
},
@@ -10189,6 +10236,7 @@
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0",
@@ -10253,6 +10301,7 @@
"resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-5.46.2.tgz",
"integrity": "sha512-qqAXW9QvKf2tTyhpDA4qXv1IfBwD2eduSW6tUEBFIfCeE9gn9HQ9I5+MaKoenRuHrzk5sQoNh1/iof8mY7uD6Q==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"@algolia/abtesting": "1.12.2",
"@algolia/client-abtesting": "5.46.2",
@@ -11084,6 +11133,7 @@
}
],
"license": "MIT",
+ "peer": true,
"dependencies": {
"baseline-browser-mapping": "^2.9.0",
"caniuse-lite": "^1.0.30001759",
@@ -12143,6 +12193,7 @@
"integrity": "sha512-c3Q2VVkGAUyupsjRnaNX6u8Dq2vAdzm9iuPj5FW0fRxzlxgq9Q39MDq10IvmQSpLgHQNyQzQmOo6bgGHmH3NNg==",
"hasInstallScript": true,
"license": "MIT",
+ "peer": true,
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/core-js"
@@ -12389,6 +12440,7 @@
"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz",
"integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"cssesc": "^3.0.0",
"util-deprecate": "^1.0.2"
@@ -12725,6 +12777,7 @@
"resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.33.1.tgz",
"integrity": "sha512-iJc4TwyANnOGR1OmWhsS9ayRS3s+XQ185FmuHObThD+5AeJCakAAbWv8KimMTt08xCCLNgneQwFp+JRJOr9qGQ==",
"license": "MIT",
+ "peer": true,
"engines": {
"node": ">=0.10"
}
@@ -12830,6 +12883,12 @@
"node": ">=12"
}
},
+ "node_modules/d3-binarytree": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/d3-binarytree/-/d3-binarytree-1.0.2.tgz",
+ "integrity": "sha512-cElUNH+sHu95L04m92pG73t2MEJXKu+GeKUN1TJkFsu93E5W8E9Sc3kHEGJKgenGvj19m6upSn2EunvMgMD2Yw==",
+ "license": "MIT"
+ },
"node_modules/d3-brush": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-3.0.0.tgz",
@@ -12982,6 +13041,22 @@
"node": ">=12"
}
},
+ "node_modules/d3-force-3d": {
+ "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==",
+ "license": "MIT",
+ "dependencies": {
+ "d3-binarytree": "1",
+ "d3-dispatch": "1 - 3",
+ "d3-octree": "1",
+ "d3-quadtree": "1 - 3",
+ "d3-timer": "1 - 3"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
"node_modules/d3-format": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz",
@@ -13024,6 +13099,12 @@
"node": ">=12"
}
},
+ "node_modules/d3-octree": {
+ "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==",
+ "license": "MIT"
+ },
"node_modules/d3-path": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz",
@@ -13134,6 +13215,7 @@
"resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz",
"integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==",
"license": "ISC",
+ "peer": true,
"engines": {
"node": ">=12"
}
@@ -13234,6 +13316,18 @@
"integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==",
"license": "BSD-2-Clause"
},
+ "node_modules/data-bind-mapper": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/data-bind-mapper/-/data-bind-mapper-1.0.3.tgz",
+ "integrity": "sha512-QmU3lyEnbENQPo0M1F9BMu4s6cqNNp8iJA+b/HP2sSb7pf3dxwF3+EP1eO69rwBfH9kFJ1apmzrtogAmVt2/Xw==",
+ "license": "MIT",
+ "dependencies": {
+ "accessor-fn": "1"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
"node_modules/data-view-buffer": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz",
@@ -14215,6 +14309,7 @@
"resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.2.tgz",
"integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.8.0",
"@eslint-community/regexpp": "^4.12.1",
@@ -14392,6 +14487,7 @@
"resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.32.0.tgz",
"integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"@rtsao/scc": "^1.1.0",
"array-includes": "^3.1.9",
@@ -15287,6 +15383,20 @@
"integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==",
"license": "ISC"
},
+ "node_modules/float-tooltip": {
+ "version": "1.7.5",
+ "resolved": "https://registry.npmjs.org/float-tooltip/-/float-tooltip-1.7.5.tgz",
+ "integrity": "sha512-/kXzuDnnBqyyWyhDMH7+PfP8J/oXiAavGzcRxASOMRHFuReDtofizLLJsf7nnDLAfEaMW4pVWaXrAjtnglpEkg==",
+ "license": "MIT",
+ "dependencies": {
+ "d3-selection": "2 - 3",
+ "kapsule": "^1.16",
+ "preact": "10"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
"node_modules/focus-visible": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/focus-visible/-/focus-visible-5.2.1.tgz",
@@ -17596,12 +17706,22 @@
"node": ">= 0.4"
}
},
+ "node_modules/jerrypick": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/jerrypick/-/jerrypick-1.1.2.tgz",
+ "integrity": "sha512-YKnxXEekXKzhpf7CLYA0A+oDP8V0OhICNCr5lv96FvSsDEmrb0GKM776JgQvHTMjr7DTTPEVv/1Ciaw0uEWzBA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ }
+ },
"node_modules/jest": {
"version": "29.7.0",
"resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz",
"integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"@jest/core": "^29.7.0",
"@jest/types": "^29.6.3",
@@ -18168,6 +18288,7 @@
"resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz",
"integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==",
"license": "MIT",
+ "peer": true,
"bin": {
"jiti": "bin/jiti.js"
}
@@ -18302,6 +18423,18 @@
"node": ">=4.0"
}
},
+ "node_modules/kapsule": {
+ "version": "1.16.3",
+ "resolved": "https://registry.npmjs.org/kapsule/-/kapsule-1.16.3.tgz",
+ "integrity": "sha512-4+5mNNf4vZDSwPhKprKwz3330iisPrb08JyMgbsdFrimBCKNHecua/WBwvVg3n7vwx0C1ARjfhwIpbrbd9n5wg==",
+ "license": "MIT",
+ "dependencies": {
+ "lodash-es": "4"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
"node_modules/katex": {
"version": "0.16.27",
"resolved": "https://registry.npmjs.org/katex/-/katex-0.16.27.tgz",
@@ -21399,6 +21532,7 @@
"resolved": "https://registry.npmjs.org/mobx/-/mobx-6.15.0.tgz",
"integrity": "sha512-UczzB+0nnwGotYSgllfARAqWCJ5e/skuV2K/l+Zyck/H6pJIhLXuBnz+6vn2i211o7DtbE78HQtsYEKICHGI+g==",
"license": "MIT",
+ "peer": true,
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/mobx"
@@ -21617,6 +21751,44 @@
"node": "^10 || ^12 || >=14"
}
},
+ "node_modules/ngraph.events": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/ngraph.events/-/ngraph.events-1.4.0.tgz",
+ "integrity": "sha512-NeDGI4DSyjBNBRtA86222JoYietsmCXbs8CEB0dZ51Xeh4lhVl1y3wpWLumczvnha8sFQIW4E0vvVWwgmX2mGw==",
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/ngraph.forcelayout": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/ngraph.forcelayout/-/ngraph.forcelayout-3.3.1.tgz",
+ "integrity": "sha512-MKBuEh1wujyQHFTW57y5vd/uuEOK0XfXYxm3lC7kktjJLRdt/KEKEknyOlc6tjXflqBKEuYBBcu7Ax5VY+S6aw==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "ngraph.events": "^1.0.0",
+ "ngraph.merge": "^1.0.0",
+ "ngraph.random": "^1.0.0"
+ }
+ },
+ "node_modules/ngraph.graph": {
+ "version": "20.1.1",
+ "resolved": "https://registry.npmjs.org/ngraph.graph/-/ngraph.graph-20.1.1.tgz",
+ "integrity": "sha512-KNtZWYzYe7SMOuG3vvROznU+fkPmL5cGYFsWjqt+Ob1uF5xZz5EjomtsNOZEIwVuD37/zokeEqNK1ghY4/fhDg==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "ngraph.events": "^1.4.0"
+ }
+ },
+ "node_modules/ngraph.merge": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/ngraph.merge/-/ngraph.merge-1.0.0.tgz",
+ "integrity": "sha512-5J8YjGITUJeapsomtTALYsw7rFveYkM+lBj3QiYZ79EymQcuri65Nw3knQtFxQBU1r5iOaVRXrSwMENUPK62Vg==",
+ "license": "MIT"
+ },
+ "node_modules/ngraph.random": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/ngraph.random/-/ngraph.random-1.2.0.tgz",
+ "integrity": "sha512-4EUeAGbB2HWX9njd6bP6tciN6ByJfoaAvmVL9QTaZSeXrW46eNGA9GajiXiPBbvFqxUWFkEbyo6x5qsACUuVfA==",
+ "license": "BSD-3-Clause"
+ },
"node_modules/no-case": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz",
@@ -22708,6 +22880,7 @@
}
],
"license": "MIT",
+ "peer": true,
"dependencies": {
"nanoid": "^3.3.11",
"picocolors": "^1.1.1",
@@ -23611,6 +23784,7 @@
"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz",
"integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"cssesc": "^3.0.0",
"util-deprecate": "^1.0.2"
@@ -24174,6 +24348,16 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/preact": {
+ "version": "10.28.2",
+ "resolved": "https://registry.npmjs.org/preact/-/preact-10.28.2.tgz",
+ "integrity": "sha512-lbteaWGzGHdlIuiJ0l2Jq454m6kcpI1zNje6d8MlGAFlYvP2GO4ibnat7P74Esfz4sPTdM6UxtTwh/d3pwM9JA==",
+ "license": "MIT",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/preact"
+ }
+ },
"node_modules/prelude-ls": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
@@ -24575,6 +24759,7 @@
"resolved": "https://registry.npmjs.org/react/-/react-19.2.3.tgz",
"integrity": "sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA==",
"license": "MIT",
+ "peer": true,
"engines": {
"node": ">=0.10.0"
}
@@ -24603,6 +24788,7 @@
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.3.tgz",
"integrity": "sha512-yELu4WmLPw5Mr/lmeEpox5rw3RETacE++JgHqQzd2dg+YbJuat3jH4ingc+WPZhxaoFzdv9y33G+F7Nl5O0GBg==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"scheduler": "^0.27.0"
},
@@ -24616,6 +24802,23 @@
"integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==",
"license": "MIT"
},
+ "node_modules/react-force-graph-3d": {
+ "version": "1.29.0",
+ "resolved": "https://registry.npmjs.org/react-force-graph-3d/-/react-force-graph-3d-1.29.0.tgz",
+ "integrity": "sha512-YCD4W+SA9oeK7mMXZ9pXAGSbDZ3+6IYxv8nPZcqqYeiP1nqZIB/cbMveD3S2bH9EqsGrUMW5qFXjAm5topSblw==",
+ "license": "MIT",
+ "dependencies": {
+ "3d-force-graph": "^1.79",
+ "prop-types": "15",
+ "react-kapsule": "^2.5"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "peerDependencies": {
+ "react": "*"
+ }
+ },
"node_modules/react-helmet-async": {
"name": "@slorber/react-helmet-async",
"version": "1.3.0",
@@ -24653,12 +24856,28 @@
"react": "^18.0.0 || ^19.0.0"
}
},
+ "node_modules/react-kapsule": {
+ "version": "2.5.7",
+ "resolved": "https://registry.npmjs.org/react-kapsule/-/react-kapsule-2.5.7.tgz",
+ "integrity": "sha512-kifAF4ZPD77qZKc4CKLmozq6GY1sBzPEJTIJb0wWFK6HsePJatK3jXplZn2eeAt3x67CDozgi7/rO8fNQ/AL7A==",
+ "license": "MIT",
+ "dependencies": {
+ "jerrypick": "^1.1.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "peerDependencies": {
+ "react": ">=16.13.1"
+ }
+ },
"node_modules/react-loadable": {
"name": "@docusaurus/react-loadable",
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/@docusaurus/react-loadable/-/react-loadable-6.0.0.tgz",
"integrity": "sha512-YMMxTUQV/QFSnbgrP3tjDzLHRg7vsbMn8e9HAa8o/1iXoiomo48b7sk/kkmWEuWNDPJVlKSJRB6Y2fHqdJk+SQ==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"@types/react": "*"
},
@@ -24714,6 +24933,7 @@
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.2.0.tgz",
"integrity": "sha512-ROY9fvHhwOD9ySfrF0wmvu//bKCQ6AeZZq1nJNtbDC+kk5DuSuNX/n6YWYF/SYy7bSba4D4FSz8DJeKY/S/r+g==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"@types/use-sync-external-store": "^0.0.6",
"use-sync-external-store": "^1.4.0"
@@ -24784,6 +25004,7 @@
"resolved": "https://registry.npmjs.org/react-router/-/react-router-5.3.4.tgz",
"integrity": "sha512-Ys9K+ppnJah3QuaRiLxk+jDWOR1MekYQrlytiXxC1RyfbdsZkS5pvKAzCCr031xHixZwpnsYNT5xysdFHQaYsA==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"@babel/runtime": "^7.12.13",
"history": "^4.9.0",
@@ -25091,7 +25312,8 @@
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz",
"integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==",
- "license": "MIT"
+ "license": "MIT",
+ "peer": true
},
"node_modules/redux-thunk": {
"version": "3.1.0",
@@ -25873,6 +26095,7 @@
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
"integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"fast-deep-equal": "^3.1.3",
"fast-uri": "^3.0.1",
@@ -26981,6 +27204,7 @@
"resolved": "https://registry.npmjs.org/styled-components/-/styled-components-6.2.0.tgz",
"integrity": "sha512-ryFCkETE++8jlrBmC+BoGPUN96ld1/Yp0s7t5bcXDobrs4XoXroY1tN+JbFi09hV6a5h3MzbcVi8/BGDP0eCgQ==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"@emotion/is-prop-valid": "1.2.2",
"@emotion/unitless": "0.8.1",
@@ -27201,7 +27425,8 @@
"version": "4.1.18",
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.18.tgz",
"integrity": "sha512-4+Z+0yiYyEtUVCScyfHCxOYP06L5Ne+JiHhY2IjR2KWMIWhJOYZKLSGZaP5HkZ8+bY0cxfzwDE5uOmzFXyIwxw==",
- "license": "MIT"
+ "license": "MIT",
+ "peer": true
},
"node_modules/tailwindcss-animate": {
"version": "1.0.7",
@@ -27366,7 +27591,51 @@
"version": "0.182.0",
"resolved": "https://registry.npmjs.org/three/-/three-0.182.0.tgz",
"integrity": "sha512-GbHabT+Irv+ihI1/f5kIIsZ+Ef9Sl5A1Y7imvS5RQjWgtTPfPnZ43JmlYI7NtCRDK9zir20lQpfg8/9Yd02OvQ==",
- "license": "MIT"
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/three-forcegraph": {
+ "version": "1.43.0",
+ "resolved": "https://registry.npmjs.org/three-forcegraph/-/three-forcegraph-1.43.0.tgz",
+ "integrity": "sha512-1AqLmTCjjjwcuccObG96fCxiRnNJjCLdA5Mozl7XK+ROwTJ6QEJPo2XJ6uxWeuAmPE7ukMhgv4lj28oZSfE4wg==",
+ "license": "MIT",
+ "dependencies": {
+ "accessor-fn": "1",
+ "d3-array": "1 - 3",
+ "d3-force-3d": "2 - 3",
+ "d3-scale": "1 - 4",
+ "d3-scale-chromatic": "1 - 3",
+ "data-bind-mapper": "1",
+ "kapsule": "^1.16",
+ "ngraph.forcelayout": "3",
+ "ngraph.graph": "20",
+ "tinycolor2": "1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "peerDependencies": {
+ "three": ">=0.118.3"
+ }
+ },
+ "node_modules/three-render-objects": {
+ "version": "1.40.4",
+ "resolved": "https://registry.npmjs.org/three-render-objects/-/three-render-objects-1.40.4.tgz",
+ "integrity": "sha512-Ukpu1pei3L5r809izvjsZxwuRcYLiyn6Uvy3lZ9bpMTdvj3i6PeX6w++/hs2ZS3KnEzGjb6YvTvh4UQuwHTDJg==",
+ "license": "MIT",
+ "dependencies": {
+ "@tweenjs/tween.js": "18 - 25",
+ "accessor-fn": "1",
+ "float-tooltip": "^1.7",
+ "kapsule": "^1.16",
+ "polished": "4"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "peerDependencies": {
+ "three": ">=0.168"
+ }
},
"node_modules/throttleit": {
"version": "2.1.0",
@@ -27398,6 +27667,12 @@
"integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==",
"license": "MIT"
},
+ "node_modules/tinycolor2": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.6.0.tgz",
+ "integrity": "sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==",
+ "license": "MIT"
+ },
"node_modules/tinyexec": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.2.tgz",
@@ -27445,6 +27720,7 @@
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
"license": "MIT",
+ "peer": true,
"engines": {
"node": ">=12"
},
@@ -27670,7 +27946,8 @@
"version": "2.8.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
- "license": "0BSD"
+ "license": "0BSD",
+ "peer": true
},
"node_modules/type-check": {
"version": "0.4.0",
@@ -27828,6 +28105,7 @@
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
"license": "Apache-2.0",
+ "peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
@@ -28616,6 +28894,7 @@
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.104.1.tgz",
"integrity": "sha512-Qphch25abbMNtekmEGJmeRUhLDbe+QfiWTiqpKYkpCOWY64v9eyl+KRRLmqOFA2AvKPpc9DC6+u2n76tQLBoaA==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"@types/eslint-scope": "^3.7.7",
"@types/estree": "^1.0.8",
@@ -29514,6 +29793,7 @@
"resolved": "https://registry.npmjs.org/zod/-/zod-4.3.5.tgz",
"integrity": "sha512-k7Nwx6vuWx1IJ9Bjuf4Zt1PEllcwe7cls3VNzm4CQ1/hgtFUK2bRNG3rvnpPUhFjmqJKAKtjV576KnUkHocg/g==",
"license": "MIT",
+ "peer": true,
"funding": {
"url": "https://github.com/sponsors/colinhacks"
}